{"version":3,"sources":["common/module/realtime/Serum.RealtimeEventEmitter.js","common/module/realtime/Serum.SseEventEmitter.js","common/module/realtime/Serum.RealtimeUpdater.js","common/module/realtime/Serum.RelationalRealtimeWidget.js","common/module/realtime/Serum.RealtimeWidget.js","type/stream/Serum.RealtimeStream.js","common/module/media/Serum.MediaMetadata.js","type/compilation/CompilationStatus.js","type/compilation/Compilation.js","skin/newsroom/tinycon.js","skin/newsroom/Serum.Newsroom.js","realtime.js"],"names":["define","Pubsub","EventEmitter","onUpdate","id","version","data","publish","update","subscribeTo","unsubscribeFrom","RealtimeEventEmitter","$","module","SseEventEmitter","onPush","subscriberIds","includes","emitter","subscribesTo","length","index","indexOf","splice","eventSource","firstTimeConnection","close","window","EventSource","config","SSE_NOTIFIER_URL","onopen","onmessage","e","onerror","extend","Updater","setupTargetRemoval","$target","subscribe","topics","CONTENT_RELOAD","$container","closest","removeTarget","addTarget","attr","is","targets","push","filter","target","get","each","this","trigger","updater","Fragment","getContent","relationLimit","relationContext","parameters","join","ajax","CONTENT_ENDPOINT","RelationalRealtimeWidget","$widget","delegate","setRelationLimit","limit","getRelationLimit","parseInt","getRelationCount","relationCount","getRelations","setDefaultPerspective","perspective","defaultPerspective","onBeforeInsert","onAfterInsert","relations","widget","relationElements","map","$item","moveRelationTo","from","to","paused","$items","$from","$to","fromClasses","toClasses","before","indexOfRelation","relation","i","relationDifference","r1","r2","relationPerspective","relationTemplate","createRelation","widgetID","localref","size","relationSize","alignment","defaultAlignment","secondary","relationContentElement","find","relationContainer","insertRelationAt","context","$content","renderID","renderInContext","params","render","stripWhitespace","$relations","prependTo","$neighborElement","insertBefore","last","insertAfter","appendTo","removeRelations","offset","remove","slice","repaint","content","master","k","setTimeout","isPaused","pause","unpause","synchronize","done","event","stopPropagation","stopImmediatePropagation","on","RealtimeUpdater","RealtimeWidget","getRenderID","parent","destroy","off","Time","ScrollTrigger","moment","Waypoint","$element","options","onScroll","position","topOffset","top","reached","enter","exit","DID_SCROLL","RealtimeStream","$stream","onRealtimeInsertion","highestUnrederedInsertionIndex","stream","unrenderedInsertions","unrenderedInsertionCount","setupShortcutButton","animate","scrollTop","setupExpandableImages","document","toggleClass","CHANGE_IMAGES","imgEls","setupPagination","$button","TRACK_EVENT","category","action","addClass","removeClass","hide","show","onBeforeRealtimeDeletion","formatDate","today","time","daysBetween","diff","clone","startOf","subtract","isSame","day","format","charAt","toUpperCase","substring","formatDateStrings","now","html","onVisibilityStateChange","visible","streamHeaderIsVisible","setupVisibilityStateChange","setupEvents","CHECK_FOR_NRKNO_EMBED","$animated","maxHeight","opacity","hasClass","getJson","url","requestSettings","type","dataType","getLatestSeriesEpisodeId","PS_VIDEO_API_URL","PSAPI_SERIES_PATH","replace","then","getMediaData","METADATA_PATH","cache","Deferred","resolve","isSeries","episodeId","getAspectRatio","videoID","metaData","displayAspectRatio","getLiveStatus","liveStatus","isLive","streamingMode","playability","availability","live","transmissionInterval","startTime","MediaMetadata","v","REDMODE_BULLETIN_CUTOFF","fail","error","console","getHtml","REDMODE_TIME_CUTOFF","CompilationStatus","shouldSetupRealtimeUpdating","setupRealtimeUpdating","disableRealtimeUpdating","isDisabledBecauseAutoplay","flowWidget","setupRedmodeDetection","when","checkIfRecentOrRedmodeBulletins","hasRecentOrRedmodeBulletins","hasLiveVideo","video","Boolean","isInRedMode","always","styleLiveVideoStatus","checkIfShouldGoLarge","setupFlowChangeDetection","$flow","$parent","shouldGoLarge","videoId","checkIfPlugVideoShouldPlay","liveVideoIsOngoing","videoView","Array","isArray","ludoPlayers","entry","view","reduce","current","videoCanPlay","videoMustBeLive","player","mediaItem","passedLiveCheck","isPlayable","playVideo","set","play","log","hasLargeParent","hasVideoCanPlay","isAudio","Date","showRecentTeasers","ids","wrapper","parentNode","querySelector","compilationLink","href","forEach","placeholder","createElement","insertAdjacentElement","outerHTML","compilationID","deferred","timestamp","getTime","recentTeasers","teaser","created","deferredTeasers","apply","bulletinResponses","arguments","prototype","call","hasRedmodeBulletin","some","bulletinAjax","bulletinResponse","emphasis","setupLiveMediaStyling","videoType","parents","bootstrap","selector","elements","querySelectorAll","Compilation","setupStream","pageArticles","preventDefault","articleList","articlePagingSize","getRelationClasses","setupRelatedArticles","$articles","modelType","scrollToAnchor","toggleCollapsible","setupNavigation","label","text","one","setupStatus","status","Tinycon","currentFavicon","originalFavicon","faviconImage","canvas","r","Math","ceil","devicePixelRatio","defaults","width","height","font","color","background","fallback","crossOrigin","abbreviate","ua","agent","navigator","userAgent","toLowerCase","browser","ie","chrome","webkit","safari","mozilla","getFaviconTag","links","getElementsByTagName","len","getAttribute","match","removeFaviconTag","removeChild","getCurrentFavicon","tag","getCanvas","setFaviconTag","link","rel","appendChild","drawFavicon","getContext","updateTitle","src","onload","clearRect","drawImage","drawBubble","refreshFavicon","originalTitle","title","abbreviateNumber","left","bottom","right","radius","fillStyle","strokeStyle","lineWidth","beginPath","moveTo","quadraticCurveTo","lineTo","closePath","fill","stroke","textAlign","textBaseline","fillText","toDataURL","metricPrefixes","round","value","precision","Number","toFixed","setOptions","custom","colour","key","hasOwnProperty","setImage","setBubble","reset","amd","exports","isNewsroomPath","pathname","ENDS_WITH_SLASH","test","onStreamInsertionCountChange","count","StreamNotification","updateCount","setupNotifications","setupVisibilityHandling","property","isVisible","eventName","setupUnreadHandling","checkReadStatus","BulletinStateManager","itemIsSeen","isElementVisible","markItemAsSeen","isSupported","setupBulletinAuthorInjection","updateBulletinAuthors","BulletinAuthors","ready","$notification","detach","getAuthors","authors","authorsMap","authorBulletins","location","has","$bulletin","author","fetchAuthors","updateTimestamp","$authorsContainer","runningTimestamp","empty","$author","append","namespace","maxItems","element","rectangle","getBoundingClientRect","bottomEdgeVisible","innerHeight","seenItems","MAX_SEEN_ITEMS","shift","readItems","localStorage","getItem","NAMESPACE","JSON","parse","documentElement","storeAndTrimIfNeeded","iterations","setItem","stringify","domException","name","items","_isNewsroomPath"],"mappings":"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","file":"realtime.js","sourcesContent":["define('common/module/realtime/Serum.RealtimeEventEmitter',[\n 'common/js/lib/Serum.Pubsub'\n], function(Pubsub) {\n\n 'use strict';\n\n function EventEmitter() {\n\n function onUpdate(id, version, data) {\n Pubsub.publish('REALTIME_CONTENT_UPDATE', {\n id : id,\n version : version,\n update : data\n });\n }\n\n return {\n subscribeTo : function(id, version) {}, // eslint-disable-line no-unused-vars\n unsubscribeFrom : function(id) {}, // eslint-disable-line no-unused-vars\n\n onUpdate : onUpdate\n };\n }\n\n return EventEmitter;\n});\n","define('common/module/realtime/Serum.SseEventEmitter',[\n 'common/module/realtime/Serum.RealtimeEventEmitter',\n 'jquery',\n 'common/js/lib/Serum.Pubsub',\n 'module'\n], function(RealtimeEventEmitter, $, Pubsub, module) {\n\n 'use strict';\n\n function SseEventEmitter() {\n var emitter = new RealtimeEventEmitter();\n var subscriberIds = [];\n var timeoutId = null;\n var eventSource = null;\n var firstTimeConnection = false;\n\n function setupEventHandling() {\n if (eventSource !== null) {\n eventSource.close();\n }\n if (!window.EventSource) {\n return;\n }\n eventSource = new window.EventSource(module.config().SSE_NOTIFIER_URL);\n eventSource.onopen = function() {\n if (firstTimeConnection) {\n Pubsub.publish('REALTIME_RECONNECTION_SUCCESS');\n }\n\n firstTimeConnection = true;\n Pubsub.publish('REALTIME_CONNECTION_SUCCESS');\n };\n eventSource.onmessage = function(e) {\n onPush(e);\n };\n eventSource.onerror = function() {\n Pubsub.publish('REALTIME_CONNECTION_FAILURE');\n };\n\n }\n\n function onPush(data) {\n if (subscriberIds.includes(data.data)) {\n emitter.onUpdate(data.data, null, data);\n }\n }\n\n function subscribesTo(id) {\n return subscriberIds.includes(id);\n }\n\n function collectingIds() { // eslint-disable-line no-unused-vars\n return timeoutId !== null;\n }\n\n function subscribeTo(id) {\n // keep only one subscription per id\n if (subscribesTo(id)) {\n return;\n }\n\n subscriberIds[subscriberIds.length] = id;\n }\n\n function unsubscribeFrom(id, version) { // eslint-disable-line no-unused-vars\n var index = subscriberIds.indexOf(id);\n if (index !== -1) {\n subscriberIds.splice(index, 1);\n }\n }\n\n setupEventHandling();\n\n return $.extend(emitter, {\n subscribeTo : subscribeTo,\n unsubscribeFrom : unsubscribeFrom\n });\n\n }\n\n return SseEventEmitter\n\n});\n\n","define('common/module/realtime/Serum.RealtimeUpdater',[\n 'common/module/realtime/Serum.SseEventEmitter',\n 'common/js/lib/Serum.Pubsub',\n 'jquery'\n], function(EventEmitter, Pubsub, $) {\n 'use strict';\n\n var Updater = function() {\n var emitter = new EventEmitter();\n var targets = {};\n\n function setupTargetRemoval($target, id) {\n Pubsub.subscribe(Pubsub.topics.CONTENT_RELOAD, function($container) {\n if (!$target.closest($container).length) {\n return;\n }\n\n removeTarget(id, $target);\n });\n }\n\n function addTarget($target) {\n\n var id = $target.attr('data-id');\n var version = $target.attr('data-version');\n\n if (!$target.is(':visible')) {\n return;\n }\n\n targets[id] = targets[id] || $();\n targets[id].push($target);\n\n setupTargetRemoval($target, id);\n\n emitter.subscribeTo(id, version);\n }\n\n function removeTarget(id, $target) {\n targets[id] = targets[id].filter(function(target) {\n return target !== $target.get(0);\n });\n }\n\n function initialize() {\n\n Pubsub.subscribe('REALTIME_CONTENT_UPDATE', function(data) {\n\n targets[data.id].each(function() {\n $(this).trigger('realtimeupdate', data);\n });\n });\n }\n\n initialize();\n\n return {\n addTarget : addTarget,\n removeTarget : removeTarget\n };\n };\n\n Updater.get = (function() {\n var updater;\n\n return function() {\n if (!updater) {\n updater = new Updater();\n }\n\n return updater;\n };\n\n })();\n\n\n return Updater;\n});\n","define('common/module/realtime/Serum.RelationalRealtimeWidget',[\n 'jquery',\n 'common/module/asset/Serum.Asset.Fragment',\n 'common/js/lib/Serum.Pubsub'\n], function($, Fragment, Pubsub) {\n 'use strict';\n\n var CONTENT_ENDPOINT = '/serum/api/content/json/';\n\n function getContent(id, relationLimit, relationContext) {\n var parameters = [];\n parameters.push('v=2');\n\n if (relationLimit) {\n parameters.push('limit=' + relationLimit);\n }\n\n if (relationContext) {\n parameters.push('context=' + relationContext);\n }\n\n if (parameters.length) {\n parameters = '?' + parameters.join('&');\n } else {\n parameters = '';\n }\n\n return $.ajax(CONTENT_ENDPOINT + id + parameters);\n }\n\n function RelationalRealtimeWidget($widget, delegate) {\n\n var paused = false;\n var widgetID = $widget.attr('data-id');\n var defaultPerspective = 'RICH';\n var defaultAlignment = 'AUTO';\n var relationLimit = $widget.attr('data-relation-limit') || 35;\n var relationContext = $widget.attr('data-relation-context') || null;\n var relationSize = $widget.attr('data-relation-size') || 'AUTO';\n var relationCount;\n var widget;\n\n function setRelationLimit(limit) {\n relationLimit = limit;\n }\n\n function getRelationLimit() {\n return window.parseInt(relationLimit, 10);\n }\n\n function getRelationCount() {\n if (!relationCount) {\n getRelations();\n }\n\n return relationCount;\n }\n\n function setDefaultPerspective(perspective) {\n defaultPerspective = perspective;\n }\n\n /* extend these for special insertion behaviour */\n function onBeforeInsert() { }\n function onAfterInsert() { }\n\n /* returns a list of relation objects */\n function getRelations() {\n\n var relations = widget.relationElements().map(function() {\n var $item = $(this);\n var id = $item.attr('data-id');\n return {\n id : id,\n perspective : $item.attr('data-perspective') || 'BRIEF'\n };\n }).get();\n\n relationCount = relations.length;\n\n return relations;\n }\n\n /* moves a relation to the specified relation index in the DOM */\n function moveRelationTo(from, to) {\n\n if (paused) {\n return;\n }\n\n var $items = widget.relationElements();\n var $from = $($items.get(from));\n var $to = $($items.get(to));\n var fromClasses = $from.attr('class');\n var toClasses = $to.attr('class');\n\n $widget.trigger('beforerealtimereorder', $from, $to);\n\n $to.attr('class', fromClasses);\n $from.attr('class', toClasses);\n\n $($to).before($from);\n\n $widget.trigger('realtimereorder', $from, $to);\n }\n\n /* returns the index of a relation in the DOM, -1 if it does not exist */\n function indexOfRelation(relations, relation) {\n for (var i = 0; i < relations.length; i++) {\n if (relations[i].id === relation.id) {\n return i;\n }\n }\n return -1;\n }\n\n /* returns true if there is a difference between the specified relations, false otherwise */\n function relationDifference(r1, r2) { // eslint-disable-line no-unused-vars\n return false;\n\n /** not implemented\n\n if (r1.perspective == 'AUTO') {\n r1.perspective = 'RICH';\n }\n if (r2.perspective == 'AUTO') {\n r2.perspective = 'RICH';\n }\n\n return r1.perspective != r2.perspective;\n */\n }\n\n function relationPerspective(relation) {\n return (relation.perspective === 'AUTO' || !relation.perspective)\n ? defaultPerspective\n : relation.perspective;\n }\n\n /* returns a template for the wrapper used when inserting new relations */\n function relationTemplate() {\n return '
';\n }\n\n /* creates a jQuery object for a new relations to be inserted in the DOM */\n function createRelation(relation) {\n relation.perspective = defaultPerspective; //Makes messages follow perspective of parent\n var $item = $(widget.relationTemplate(relation))\n .attr('data-id', relation.id)\n .attr('data-reference-id', widgetID + '.' + relation.localref)\n .attr('data-perspective', relation.perspective || defaultPerspective)\n .attr('data-size', relation.size || relationSize)\n .attr('data-alignment', relation.alignment || defaultAlignment);\n if (relation.secondary) {\n $item.attr('data-secondary', relation.secondary);\n }\n return $item;\n }\n\n /* returns the content element of the specified relation */\n function relationContentElement($item) {\n return $item;\n }\n\n function relationElements() {\n return $widget.find('.relation');\n }\n\n function relationContainer() {\n return $widget.find('.relations');\n }\n\n /* render the specified relation object at the specified index */\n function insertRelationAt(relation, i) {\n\n $widget.trigger('realtimeinsertion', { relation : relation, index : i, context : relationContext });\n\n if (paused) {\n return;\n }\n\n var $item = createRelation(relation);\n\n var $content = widget.relationContentElement($item);\n widget.onBeforeInsert($content);\n\n var renderID = relation.id;\n if (widget.renderInContext) {\n renderID = widgetID + '.' + relation.localref;\n }\n\n var perspective = widget.relationPerspective(relation);\n var params = {};\n if (perspective) {\n params.perspective = perspective;\n }\n if (relation.secondary) {\n params.secondary = relation.secondary;\n }\n //Let widget settings override if relation size is AUTO\n if (relation.size === 'AUTO') {\n params.size = relationSize;\n }\n\n Fragment.render(renderID, $content, params, {\n stripWhitespace : false,\n onUpdate : function() {\n widget.onAfterInsert($content);\n $widget.trigger('afterrealtimeinsertion', $content);\n }\n });\n\n var $relations = widget.relationElements();\n if (i === 0) {\n $item.prependTo(widget.relationContainer());\n return;\n }\n\n var $neighborElement = $relations.get(i);\n if ($neighborElement) {\n $item.insertBefore($neighborElement);\n } else if ($relations.last().length) {\n $item.insertAfter($relations.last());\n } else {\n $item.appendTo(widget.relationContainer());\n }\n }\n\n function removeRelations(offset) {\n var $relations = widget.relationElements();\n\n $widget.trigger('beforerealtimedeletion', { offset : offset, relations : $relations });\n if (offset === -1) {\n $relations.remove();\n } else {\n $relations.slice(offset).remove();\n }\n\n $widget.trigger('realtimedeletion');\n }\n\n /* repain this relational widget with a master list */\n function repaint(content) {\n $widget.trigger('beforerealtimerepaint');\n\n var master = content.relations;\n var relations = null;\n\n if (master.length === 0) {\n removeRelations(-1);\n return;\n }\n\n $.each(master, function(i, relation) {\n relations = getRelations();\n\n var k = indexOfRelation(relations, relation);\n\n if (k === -1) {\n insertRelationAt(relation, i);\n\n } else if (k !== i) {\n moveRelationTo(k, i);\n }\n\n if (relationDifference(relations[i], relation)) {\n updateRelation(relation);\n }\n });\n\n if (relations !== null && master.length < relations.length) {\n setTimeout(function() {\n removeRelations(master.length);\n }, 1500);\n }\n\n $widget.trigger('realtimerepaint', { master : master });\n }\n\n function updateRelation(relation) { // eslint-disable-line no-unused-vars\n // TODO\n }\n\n function isPaused() {\n return paused;\n }\n\n function pause() {\n paused = true;\n }\n\n function unpause() {\n paused = false;\n synchronize();\n }\n\n function synchronize() {\n return getContent(widgetID, relationLimit, relationContext).done(repaint);\n }\n\n function onUpdate(event, data) {\n event.stopPropagation();\n event.stopImmediatePropagation();\n\n if (data.id !== widgetID) {\n return;\n }\n\n synchronize();\n }\n\n $widget.on('realtimeupdate', onUpdate);\n Pubsub.subscribe('REALTIME_RECONNECTION_SUCCESS', function() {\n setTimeout(synchronize, 1000);\n });\n\n widget = $.extend({\n relationTemplate : relationTemplate,\n relationContentElement : relationContentElement,\n relationElements : relationElements,\n relationContainer : relationContainer,\n relationPerspective : relationPerspective,\n\n moveRelationTo : moveRelationTo,\n insertRelationAt : insertRelationAt,\n getRelations : getRelations,\n\n onAfterInsert : onAfterInsert,\n onBeforeInsert : onBeforeInsert,\n removeRelations : removeRelations,\n\n synchronize : synchronize,\n\n isPaused : isPaused,\n pause : pause,\n unpause : unpause,\n\n setDefaultPerspective : setDefaultPerspective,\n\n getRelationLimit : getRelationLimit,\n setRelationLimit : setRelationLimit,\n getRelationCount : getRelationCount,\n\n renderInContext : true\n }, delegate);\n\n $widget.data('widget', widget);\n\n return widget;\n }\n\n return RelationalRealtimeWidget;\n});\n\n","define('common/module/realtime/Serum.RealtimeWidget',[\n 'common/module/realtime/Serum.RealtimeUpdater',\n 'common/module/asset/Serum.Asset.Fragment'\n], function(RealtimeUpdater, Fragment) {\n 'use strict';\n\n var updater = RealtimeUpdater.get();\n\n function RealtimeWidget($widget, perspective) {\n\n var id = $widget.attr('data-id');\n\n perspective = $widget.attr('data-perspective') || perspective || 'RICH';\n var secondary = $widget.attr('data-secondary');\n\n\n function getRenderID() {\n var $parent = $widget.parent();\n var referenceID = $parent.attr('data-reference-id');\n\n return referenceID || id;\n }\n\n function destroy() {\n updater.removeTarget(id, $widget);\n $widget.off('realtimeupdate', onUpdate);\n }\n\n function onUpdate(event, data) {\n if (data.id !== id) {\n return false;\n }\n\n event.stopPropagation();\n event.stopImmediatePropagation();\n\n var params = { perspective : perspective};\n if (secondary) {\n params.secondary = secondary;\n }\n\n Fragment.render(getRenderID(), $widget.parent(), params, {\n stripWhitespace : false\n });\n\n destroy();\n return false;\n }\n\n $widget.on('realtimeupdate', onUpdate);\n $widget.on('delete', destroy);\n\n return {\n destroy: destroy\n };\n }\n\n return RealtimeWidget;\n});\n","define('type/stream/Serum.RealtimeStream',[\n 'common/js/lib/Serum.Time',\n 'common/module/realtime/Serum.RelationalRealtimeWidget',\n 'common/js/lib/Serum.ScrollTrigger',\n 'common/js/lib/Serum.Pubsub',\n 'common/js/lib/Serum.Moment',\n 'jquery'\n], function(Time, RelationalRealtimeWidget, ScrollTrigger, Pubsub, moment, $) {\n 'use strict';\n\n /* convenience function for detecting scrolling past an element */\n function Waypoint($element, options) {\n // PUB-12817 - reduce ridiculous amounts of errors because of no null checking\n if (!$element.length) {\n return;\n }\n\n var reached = false;\n\n function onScroll(position) {\n var topOffset = $element.offset().top; //Must happen onScroll in case content above has changed height\n\n if (!reached && position.top > topOffset) {\n options.enter();\n reached = true;\n }\n\n if (reached && position.top < topOffset) {\n options.exit();\n reached = false;\n }\n }\n\n Pubsub.subscribe(Pubsub.topics.DID_SCROLL, onScroll);\n }\n\n\n /* stream decorator */\n function RealtimeStream($stream) {\n\n var unrenderedInsertions = 0;\n var highestUnrederedInsertionIndex = -1;\n var streamHeaderIsVisible = true;\n var relationPerspective = $stream.data('relationPerspective');\n\n var stream = new RelationalRealtimeWidget($stream, {\n onBeforeInsert : function($content) {\n $content.addClass('new');\n },\n\n onAfterInsert : function($content) {\n Pubsub.publish(Pubsub.topics.CHECK_FOR_NRKNO_EMBED);\n var $animated;\n\n if (relationPerspective === 'REFERENCE') {\n $animated = $content.find('> span');\n $animated.animate({ maxHeight : 40 }, function() {\n $animated.animate({ opacity : 0 }, function() {\n $animated.animate({ opacity : 1 });\n });\n });\n return;\n }\n\n $animated = $content.find('.bulletin > div');\n $animated.animate({ maxHeight: 700 }, 1000, function() {\n $animated.animate({ opacity: 1 }, 400, function() {\n $content.removeClass('new');\n $animated.attr('style', '');\n formatDateStrings($content.find('.bulletin-text time[datetime]'));\n });\n });\n },\n\n relationElements : function() {\n return $stream.find('.stream-item');\n },\n\n relationContainer : function() {\n return $stream.find($stream.hasClass('lean') ? '.stream-lean-content' : '.stream-content');\n },\n relationTemplate : function(relation) { // eslint-disable-line no-unused-vars\n return '';\n }\n });\n\n stream.setDefaultPerspective(relationPerspective);\n\n function onRealtimeInsertion(event, data) {\n var index = data.index;\n if (data.context !== 'items') {\n return;\n }\n\n if (index > highestUnrederedInsertionIndex && index < stream.getRelationCount()) {\n unrenderedInsertions++;\n Pubsub.publish('/stream/underedInsertionCountChange', {\n stream : $stream,\n unrenderedInsertionCount : unrenderedInsertions\n });\n highestUnrederedInsertionIndex = data.index;\n }\n }\n\n function setupShortcutButton() {\n $stream.on('click', '.stream-top-shortcut', function() {\n $('body, html').animate({ scrollTop: $stream.offset().top - 15 }, 800);\n });\n }\n\n function setupExpandableImages() {\n $(document).on('click', '.bulletin-attachment.image', function() {\n $(this).toggleClass('bulletin-attachment-expanded');\n setTimeout(function() {\n Pubsub.publish(Pubsub.topics.CHANGE_IMAGES, { imgEls : $(this) });\n }, 700);\n });\n }\n\n function setupPagination() {\n var $button = $stream.find('.stream-pagination-button');\n\n $stream.on('click', '.stream-pagination-button', function() {\n Pubsub.publish(Pubsub.topics.TRACK_EVENT, {\n category : 'Stream',\n action : 'Pagination click'\n });\n\n $button.addClass('is-busy');\n\n stream.setRelationLimit(stream.getRelationLimit() + 5);\n\n if (stream.isPaused()) {\n stream.unpause();\n $button.removeClass('is-busy');\n } else {\n stream.synchronize().done(function() {\n $button.removeClass('is-busy');\n });\n }\n });\n\n $stream.on('realtimerepaint', function(event, data) {\n //TODO: need some more data from backend here?\n //console.log(data.master.length, stream.getRelationLimit());\n if (data.master.length < stream.getRelationLimit()) {\n $stream.find('.stream-pagination-button').parent().hide();\n }else{\n $stream.find('.stream-pagination-button').parent().show();\n }\n });\n }\n\n function onBeforeRealtimeDeletion(e, data) { // eslint-disable-line no-unused-vars\n //TODO: remove this?\n }\n\n function formatDate(today, time) {\n var daysBetween = today.diff(time, 'days'),\n yesterday = today.clone().startOf('day').subtract(1, 'days');\n\n if(yesterday.isSame(time, 'day')) {\n return 'I går';\n }\n if(daysBetween < 5) {\n var day = time.format('dddd');\n return day.charAt(0).toUpperCase() + day.substring(1);\n }\n return undefined;\n }\n\n function formatDateStrings($items) {\n var today = moment(Time.now());\n $items.each(function() {\n var $item = $(this),\n time = moment($item.data('timestamp'));\n\n if(!today.isSame(time, 'day')) {\n $item.find('.bulletin-publish-clock').show();\n $item.find('.bulletin-publish-date').html(formatDate(today, time)).show();\n if(!today.isSame(time, 'year')) {\n $item.find('.bulletin-publish-year').show();\n }\n }\n });\n }\n\n function onVisibilityStateChange(data) {\n\n if (data.visible && stream.isPaused() && streamHeaderIsVisible) {\n stream.unpause();\n\n $stream.off('realtimeinsertion', onRealtimeInsertion);\n highestUnrederedInsertionIndex = -1;\n unrenderedInsertions = 0;\n\n Pubsub.publish('/stream/underedInsertionCountChange', {\n stream : $stream,\n unrenderedInsertionCount : unrenderedInsertions\n });\n } else if (!data.visible) {\n stream.pause();\n $stream.on('realtimeinsertion', onRealtimeInsertion);\n }\n }\n\n function setupVisibilityStateChange() {\n Pubsub.subscribe('VISIBILITY_DID_CHANGE_STATE', onVisibilityStateChange);\n }\n\n function setupEvents() {\n new Waypoint($stream.find('.stream-content'), { // eslint-disable-line no-new\n enter : function() {\n stream.pause();\n $stream.on('realtimeinsertion', onRealtimeInsertion);\n streamHeaderIsVisible = false;\n },\n exit : function() {\n streamHeaderIsVisible = true;\n stream.unpause();\n $stream.off('realtimeinsertion', onRealtimeInsertion);\n highestUnrederedInsertionIndex = -1;\n unrenderedInsertions = 0;\n\n Pubsub.publish('/stream/underedInsertionCountChange', {\n stream : $stream,\n unrenderedInsertionCount : unrenderedInsertions\n });\n }\n });\n\n setupShortcutButton();\n setupPagination();\n setupExpandableImages();\n formatDateStrings($stream.find('.stream-item .bulletin-text time[datetime]'));\n setupVisibilityStateChange();\n\n $stream.on('beforerealtimedeletion', onBeforeRealtimeDeletion);\n }\n\n (function initialize() {\n setupEvents();\n $stream.data('realtime-stream', stream);\n $stream.trigger('widget.initialized');\n })();\n\n return stream;\n }\n\n return RealtimeStream;\n\n});\n\n","define(\n 'common/module/media/Serum.MediaMetadata',['jquery', 'module'],\n function ($, module) {\n var PSAPI_SERIES_PATH = 'series/{seriesId}/latestOrNextEpisode/mediaelement';\n var METADATA_PATH = 'playback/metadata/';\n\n var cache = {};\n\n function getJson (url) {\n var requestSettings = {\n type: 'GET',\n url: url,\n dataType: 'json'\n };\n\n return $.ajax(requestSettings)\n }\n\n function getLatestSeriesEpisodeId (id) {\n var url = module.config().PS_VIDEO_API_URL + PSAPI_SERIES_PATH.replace('{seriesId}', id);\n return getJson(url)\n .then(function (data) {\n return data.id;\n });\n }\n\n function getMediaData (id) {\n var url = module.config().PS_VIDEO_API_URL + METADATA_PATH + id;\n\n if (cache[id]) {\n return $.Deferred()\n .resolve()\n .then(function () {\n return cache[id];\n });\n }\n\n return getJson(url)\n .then(function (data) {\n cache[id] = data;\n return data;\n });\n }\n\n function get (id, isSeries) {\n if (isSeries) {\n return getLatestSeriesEpisodeId(id)\n .then(function (episodeId) {\n return getMediaData(episodeId);\n })\n }\n\n return getMediaData(id);\n }\n\n function getAspectRatio (videoID, isSeries) {\n if (videoID) {\n return get(videoID, isSeries === true)\n .then(function (metaData) {\n return metaData.displayAspectRatio;\n });\n }\n\n return null;\n }\n\n function getLiveStatus (videoID, isSeries) {\n if (videoID) {\n return get(videoID, isSeries === true)\n .then(function (metaData) {\n var liveStatus = {};\n\n liveStatus.isLive = metaData.streamingMode === 'live' &&\n metaData.playability === 'playable';\n\n if (metaData.availability && metaData.availability.live && metaData.availability.live.transmissionInterval) {\n liveStatus.startTime = metaData.availability.live.transmissionInterval.from\n }\n\n return liveStatus;\n });\n }\n\n return {};\n }\n\n return {\n get: get,\n getLatestSeriesEpisodeId: getLatestSeriesEpisodeId,\n getLiveStatus: getLiveStatus,\n getAspectRatio: getAspectRatio\n }\n }\n);\n\n","define('type/compilation/CompilationStatus',[\n 'jquery',\n 'common/js/lib/Serum.Time',\n 'common/module/realtime/Serum.RealtimeUpdater',\n 'common/module/realtime/Serum.RealtimeWidget',\n 'common/module/media/Serum.MediaMetadata'\n], function($, Time, RealtimeUpdater, RealtimeWidget, MediaMetadata) {\n 'use strict';\n\n var REDMODE_TIME_CUTOFF = 3600000;\n var REDMODE_BULLETIN_CUTOFF = 3;\n\n function getContent(id) {\n return $.ajax('/serum/api/content/json/' + id, {\n data : {\n v : 2,\n limit : REDMODE_BULLETIN_CUTOFF,\n context : 'items'\n }\n }).fail(function(error){\n console.error(error); //eslint-disable-line no-console\n });\n }\n\n function getHtml(id, perspective) {\n return $.get('/serum/api/render/' + id + '?perspective=' + perspective)\n .fail(function(error){\n console.error(error); //eslint-disable-line no-console\n });\n }\n\n var CompilationStatus = function($element, shouldSetupRealtimeUpdating) {\n var id = $element.attr('data-id') || false,\n video = null,\n videoId = $element.attr('data-video-id') || false,\n widget = null,\n $parent = $element.parent('.compilation-reference'),\n $flow = $element.parents('.flow'),\n flowWidget = $flow.data('widget'),\n isDisabledBecauseAutoplay = false;\n\n function setupRealtimeUpdating() {\n RealtimeUpdater.get().addTarget($element);\n widget = new RealtimeWidget($element);\n }\n\n function disableRealtimeUpdating() {\n isDisabledBecauseAutoplay = true;\n\n // disable auto-update of this compilation\n if(widget) {\n widget.destroy();\n }\n\n // disable auto-update of parent flow\n if(flowWidget) {\n flowWidget.pause();\n }\n }\n\n function setupRedmodeDetection() {\n $.when(checkIfRecentOrRedmodeBulletins(id))\n .then(function(hasRecentOrRedmodeBulletins) {\n var hasLiveVideo = video && video.liveStatus && video.liveStatus.isLive;\n\n return Boolean(hasRecentOrRedmodeBulletins || hasLiveVideo);\n })\n .then(function (isInRedMode) {\n $element.toggleClass('emphasis-high', isInRedMode);\n $element.find('.compilation-status').attr('aria-hidden', !isInRedMode);\n })\n .always(function () {\n if (video && video.liveStatus) {\n styleLiveVideoStatus(video.liveStatus);\n }\n checkIfShouldGoLarge();\n });\n }\n\n function setupFlowChangeDetection() {\n $flow.on('realtimereorder', function(){\n checkIfShouldGoLarge();\n });\n }\n\n function checkIfShouldGoLarge() {\n if($flow.hasClass('newsroom-top-flow') && $parent.is(':first-child')) {\n var shouldGoLarge = Boolean($element.hasClass('emphasis-high') || videoId);\n\n $parent.toggleClass('go-large', shouldGoLarge);\n checkIfPlugVideoShouldPlay();\n }\n }\n\n function liveVideoIsOngoing (videoView) {\n if (!Array.isArray(window.ludoPlayers)) {\n return false; // should NEVER happen\n }\n\n return window.ludoPlayers.filter(function (entry) {\n return videoView === entry.view;\n }).reduce(function (current, entry) {\n return current === true ? true : entry.liveStatus && entry.liveStatus.isLive === true;\n }, false);\n }\n\n function videoCanPlay (videoMustBeLive) {\n if (!video || !video.player || !video.player.current()) {\n return false;\n }\n\n var mediaItem = video.player.current();\n var passedLiveCheck = videoMustBeLive ?\n mediaItem.isLive && liveVideoIsOngoing(video.view)\n : true;\n\n return mediaItem.isPlayable && passedLiveCheck;\n }\n\n function playVideo() {\n if (video && video.player) {\n video.player.set('mute', true); // player.mute() will not work, this does!\n // PUB-12453 temp workaround for a suspected race condition in Ludo player\n setTimeout(function () {\n video.player.play();\n }, 100);\n } else {\n console.log('playVideo() called, but video doesnt exist or have a player property'); //eslint-disable-line no-console\n }\n }\n\n\n function checkIfPlugVideoShouldPlay() {\n var hasLargeParent = $parent.hasClass('go-large');\n var hasVideoCanPlay = videoCanPlay(false);\n\n if(!isDisabledBecauseAutoplay && hasLargeParent && hasVideoCanPlay) {\n disableRealtimeUpdating();\n playVideo();\n }\n }\n\n function styleLiveVideoStatus (liveStatus, isAudio) {\n if (liveStatus.isLive || liveStatus.startTime) {\n $element.addClass('compilation-video-live');\n\n if (isAudio) {\n $element.addClass('compilation-audio-live');\n }\n\n if (liveStatus.startTime && new Date(liveStatus.startTime) > new Date()) {\n $element.addClass('compilation-media-pending');\n }\n }\n }\n\n function showRecentTeasers(ids) {\n var wrapper = $element[0].parentNode.querySelector('.compilation-aside-teasers');\n if (!wrapper) {\n return;\n }\n var compilationLink = $element[0].querySelector('a[data-id=\"' + id + '\"]').href;\n ids.forEach(function (id) {\n var placeholder = document.createElement('span');\n wrapper.insertAdjacentElement('beforeend', placeholder);\n getHtml(id, 'REFERENCE').then(function (html) {\n placeholder.outerHTML = html;\n // link to teaser in compilation, not standalone\n wrapper.querySelector('a[data-id=\"' + id + '\"]').href = compilationLink + '#' + id + '.' + id;\n });\n });\n }\n\n function checkIfRecentOrRedmodeBulletins(compilationID) {\n var deferred = $.Deferred();\n\n if (!compilationID) {\n deferred.resolve(false);\n return deferred;\n }\n\n getContent(compilationID).then(function(data) {\n if (data.relations.length === 0) {\n deferred.resolve(false);\n } else {\n var timestamp = Time.now().getTime() - REDMODE_TIME_CUTOFF;\n var recentTeasers = data.relations.filter(function (teaser) {\n return new Date(teaser.created).getTime() > timestamp;\n });\n\n showRecentTeasers(recentTeasers.map(function(teaser){\n return teaser.id;\n }));\n\n // If all teasers are within the cutoff, resolve true (a lot is happening, activate redmode)\n if (recentTeasers.length === data.relations.length) {\n deferred.resolve(true);\n } else {\n var deferredTeasers = recentTeasers.map(function (teaser) {\n return getContent(teaser.id);\n })\n // Check if any of the recent teasers have emphasis = HIGH\n $.when.apply(null, deferredTeasers).then(function () {\n // Make sure our arguments are an array\n var bulletinResponses = deferredTeasers.length === 1 ? [arguments] : Array.prototype.slice.call(arguments),\n hasRedmodeBulletin = bulletinResponses.some(function (bulletinAjax) {\n var bulletinResponse = bulletinAjax[0];\n return bulletinResponse && bulletinResponse.emphasis && bulletinResponse.emphasis === 'HIGH';\n });\n deferred.resolve(hasRedmodeBulletin);\n });\n }\n }\n });\n\n return deferred;\n }\n\n function setupLiveMediaStyling () {\n var videoType = null,\n isAudio = false;\n\n if (Boolean(videoId)) {\n videoType = $element.find('figure.video').attr('data-video-type');\n isAudio = $element.find('figure.video').attr('data-audio-as-video') === 'true';\n\n if (['DEFAULT', 'LATEST'].indexOf(videoType) > -1) {\n $.when(MediaMetadata.getLiveStatus(videoId, videoType === 'LATEST'))\n .then(function (liveStatus) {\n styleLiveVideoStatus(liveStatus, isAudio);\n })\n }\n }\n }\n\n (function initalize() {\n if(shouldSetupRealtimeUpdating) {\n setupRealtimeUpdating();\n }\n setupRedmodeDetection();\n setupFlowChangeDetection();\n setupLiveMediaStyling();\n })();\n\n return {\n update: function() {\n setupRedmodeDetection();\n }\n };\n };\n\n CompilationStatus.bootstrap = function(selector) {\n var i, elements;\n selector = selector || '.compilation.js-initialize';\n elements = document.querySelectorAll(selector);\n\n for (i = 0; i < elements.length; i++) {\n new CompilationStatus($(elements[i]).removeClass('js-initialize'), true); //eslint-disable-line no-new\n }\n };\n\n return CompilationStatus;\n\n});\n\n","define('type/compilation/Compilation',[\n 'jquery',\n 'common/module/realtime/Serum.RealtimeUpdater',\n 'common/module/realtime/Serum.RelationalRealtimeWidget',\n 'type/stream/Serum.RealtimeStream',\n 'type/compilation/CompilationStatus',\n 'common/js/lib/Serum.Pubsub'\n], function($, RealtimeUpdater, RelationalRealtimeWidget, RealtimeStream, CompilationStatus, Pubsub) {\n 'use strict';\n\n var Compilation = function($element) {\n var stream, // eslint-disable-line no-unused-vars\n articleList,\n articlePagingSize,\n status;\n\n\n function setupStream() {\n RealtimeUpdater.get().addTarget($element);\n stream = new RealtimeStream($element);\n }\n\n function pageArticles(e) {\n e.preventDefault();\n var $button = $(this).addClass('is-busy');\n\n articleList.setRelationLimit(articleList.getRelationLimit() + articlePagingSize);\n articleList.synchronize().done(function() {\n $button.removeClass('is-busy');\n });\n }\n\n function getRelationClasses() {\n return $('.compilation-articles-container .col.relation').last().attr('class');\n }\n\n function setupRelatedArticles() {\n var $articles = $('.compilation-articles');\n if (!$articles.length) {\n return;\n }\n\n RealtimeUpdater.get().addTarget($articles);\n\n articlePagingSize = parseInt($articles.data('pagingSize'), 10) || 5;\n\n articleList = new RelationalRealtimeWidget($articles, {\n relationContainer: function() {\n return $articles.find('.compilation-articles-container');\n },\n relationTemplate: function() {\n return '';\n },\n relationPerspective: function(relation) {\n return (relation.modelType === 'VideoReference') ? 'RICH' : 'LEAN';\n },\n onAfterInsert : function() {\n Pubsub.publish(Pubsub.topics.CHECK_FOR_NRKNO_EMBED);\n },\n renderInContext: false\n });\n\n articleList.setDefaultPerspective('LEAN');\n\n $articles.on('click', '.flow-page-forward', pageArticles);\n $articles.on('realtimerepaint', function(event, data) {\n if (data.master.length < articleList.getRelationLimit()) {\n $element.find('.flow-page-forward').parent().hide();\n } else {\n $element.find('.flow-page-forward').parent().show();\n }\n event.stopImmediatePropagation();\n //event.stopPropagation();\n });\n }\n\n function scrollToAnchor(e) {\n e.preventDefault();\n\n var href = $(this).attr('href');\n var $target = $(href);\n\n $('html, body').animate({\n scrollTop: $target.offset().top - 15\n }, 500);\n }\n\n function toggleCollapsible() {\n $(this).toggleClass('widget-collapsed');\n\n Pubsub.publish(Pubsub.topics.TRACK_EVENT, {\n category: 'Compilation',\n action: 'Expand description'\n });\n }\n\n function setupNavigation() {\n $element.on('click', '.compilation-navigation a', function() {\n Pubsub.publish(Pubsub.topics.TRACK_EVENT, {\n category: 'Compilation',\n action: 'Navigation click',\n label: $(this).text()\n });\n });\n $element.on('click', '.compilation-navigation a', scrollToAnchor);\n $element.one('click', '.widget-collapsible', toggleCollapsible);\n }\n\n function setupStatus() {\n status = new CompilationStatus($element, false);\n //TODO: er dette den beste eventen å lytte på?\n $element.on('realtimerepaint', function(event, data) { // eslint-disable-line no-unused-vars\n status.update();\n });\n }\n\n function initialize() {\n setupStream();\n setupRelatedArticles();\n setupNavigation();\n setupStatus();\n }\n\n initialize();\n\n };\n\n Compilation.bootstrap = function() {\n $('.compilation.rich.js-initialize').each(function() {\n new Compilation($(this).removeClass('js-initialize')); // eslint-disable-line no-new\n });\n };\n\n return Compilation;\n});\n\n","/*!\n * Tinycon - A small library for manipulating the Favicon\n * Tom Moor, http://tommoor.com\n * Copyright (c) 2015 Tom Moor\n * @license MIT Licensed\n */\n\n(function(){\n\n var Tinycon = {};\n var currentFavicon = null;\n var originalFavicon = null;\n var faviconImage = null;\n var canvas = null;\n var options = {};\n // Chrome browsers with nonstandard zoom report fractional devicePixelRatio.\n var r = Math.ceil(window.devicePixelRatio) || 1;\n var size = 16 * r;\n var defaults = {\n width: 7,\n height: 9,\n font: 10 * r + 'px arial',\n color: '#ffffff',\n background: '#F03D25',\n fallback: true,\n crossOrigin: true,\n abbreviate: true\n };\n\n var ua = (function () {\n var agent = navigator.userAgent.toLowerCase();\n // New function has access to 'agent' via closure\n return function (browser) {\n return agent.indexOf(browser) !== -1;\n };\n }());\n\n var browser = {\n ie: ua('trident'),\n chrome: ua('chrome'),\n webkit: ua('chrome') || ua('safari'),\n safari: ua('safari') && !ua('chrome'),\n mozilla: ua('mozilla') && !ua('chrome') && !ua('safari')\n };\n\n // private methods\n var getFaviconTag = function(){\n\n var links = document.getElementsByTagName('link');\n\n for(var i=0, len=links.length; i < len; i++) {\n if ((links[i].getAttribute('rel') || '').match(/\\bicon\\b/i)) {\n return links[i];\n }\n }\n\n return false;\n };\n\n var removeFaviconTag = function(){\n\n var links = document.getElementsByTagName('link');\n\n for(var i=0, len=links.length; i < len; i++) {\n var exists = (typeof(links[i]) !== 'undefined');\n if (exists && (links[i].getAttribute('rel') || '').match(/\\bicon\\b/i)) {\n links[i].parentNode.removeChild(links[i]);\n }\n }\n };\n\n var getCurrentFavicon = function(){\n\n if (!originalFavicon || !currentFavicon) {\n var tag = getFaviconTag();\n currentFavicon = tag ? tag.getAttribute('href') : '/favicon.ico';\n if (!originalFavicon) {\n originalFavicon = currentFavicon;\n }\n }\n\n return currentFavicon;\n };\n\n var getCanvas = function (){\n\n if (!canvas) {\n canvas = document.createElement(\"canvas\");\n canvas.width = size;\n canvas.height = size;\n }\n\n return canvas;\n };\n\n var setFaviconTag = function(url){\n if(url){\n removeFaviconTag();\n\n var link = document.createElement('link');\n link.type = 'image/x-icon';\n link.rel = 'icon';\n link.href = url;\n document.getElementsByTagName('head')[0].appendChild(link);\n }\n };\n\n var log = function(message){\n if (window.console) window.console.log(message);\n };\n\n var drawFavicon = function(label, color) {\n\n // fallback to updating the browser title if unsupported\n if (!getCanvas().getContext || browser.ie || browser.safari || options.fallback === 'force') {\n return updateTitle(label);\n }\n\n var context = getCanvas().getContext(\"2d\");\n var color = color || '#000000';\n var src = getCurrentFavicon();\n\n faviconImage = document.createElement('img');\n faviconImage.onload = function() {\n\n // clear canvas\n context.clearRect(0, 0, size, size);\n\n // draw the favicon\n context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, size, size);\n\n // draw bubble over the top\n if ((label + '').length > 0) drawBubble(context, label, color);\n\n // refresh tag in page\n refreshFavicon();\n };\n\n // allow cross origin resource requests if the image is not a data:uri\n // as detailed here: https://github.com/mrdoob/three.js/issues/1305\n if (!src.match(/^data/) && options.crossOrigin) {\n faviconImage.crossOrigin = 'anonymous';\n }\n\n faviconImage.src = src;\n };\n\n var updateTitle = function(label) {\n\n if (options.fallback) {\n // Grab the current title that we can prefix with the label\n var originalTitle = document.title;\n\n // Strip out the old label if there is one\n if (originalTitle[0] === '(') {\n originalTitle = originalTitle.slice(originalTitle.indexOf(' '));\n }\n\n if ((label + '').length > 0) {\n document.title = '(' + label + ') ' + originalTitle;\n } else {\n document.title = originalTitle;\n }\n }\n };\n\n var drawBubble = function(context, label, color) {\n\n // automatic abbreviation for long (>2 digits) numbers\n if (typeof label == 'number' && label > 99 && options.abbreviate) {\n label = abbreviateNumber(label);\n }\n\n // bubble needs to be larger for double digits\n var len = (label + '').length-1;\n\n var width = options.width * r + (6 * r * len),\n height = options.height * r;\n\n var top = size - height,\n left = size - width - r,\n bottom = 16 * r,\n right = 16 * r,\n radius = 2 * r;\n\n // webkit seems to render fonts lighter than firefox\n context.font = (browser.webkit ? 'bold ' : '') + options.font;\n context.fillStyle = options.background;\n context.strokeStyle = options.background;\n context.lineWidth = r;\n\n // bubble\n context.beginPath();\n context.moveTo(left + radius, top);\n context.quadraticCurveTo(left, top, left, top + radius);\n context.lineTo(left, bottom - radius);\n context.quadraticCurveTo(left, bottom, left + radius, bottom);\n context.lineTo(right - radius, bottom);\n context.quadraticCurveTo(right, bottom, right, bottom - radius);\n context.lineTo(right, top + radius);\n context.quadraticCurveTo(right, top, right - radius, top);\n context.closePath();\n context.fill();\n\n // bottom shadow\n context.beginPath();\n context.strokeStyle = \"rgba(0,0,0,0.3)\";\n context.moveTo(left + radius / 2.0, bottom);\n context.lineTo(right - radius / 2.0, bottom);\n context.stroke();\n\n // label\n context.fillStyle = options.color;\n context.textAlign = \"right\";\n context.textBaseline = \"top\";\n\n // unfortunately webkit/mozilla are a pixel different in text positioning\n context.fillText(label, r === 2 ? 29 : 15, browser.mozilla ? 7*r : 6*r);\n };\n\n var refreshFavicon = function(){\n // check support\n if (!getCanvas().getContext) return;\n\n setFaviconTag(getCanvas().toDataURL());\n };\n\n var abbreviateNumber = function(label) {\n var metricPrefixes = [\n ['G', 1000000000],\n ['M', 1000000],\n ['k', 1000]\n ];\n\n for(var i = 0; i < metricPrefixes.length; ++i) {\n if (label >= metricPrefixes[i][1]) {\n label = round(label / metricPrefixes[i][1]) + metricPrefixes[i][0];\n break;\n }\n }\n\n return label;\n };\n\n var round = function (value, precision) {\n var number = new Number(value);\n return number.toFixed(precision);\n };\n\n // public methods\n Tinycon.setOptions = function(custom){\n options = {};\n\n // account for deprecated UK English spelling\n if (custom.colour) {\n custom.color = custom.colour;\n }\n\n for(var key in defaults){\n options[key] = custom.hasOwnProperty(key) ? custom[key] : defaults[key];\n }\n return this;\n };\n\n Tinycon.setImage = function(url){\n currentFavicon = url;\n refreshFavicon();\n return this;\n };\n\n Tinycon.setBubble = function(label, color) {\n label = label || '';\n drawFavicon(label, color);\n return this;\n };\n\n Tinycon.reset = function(){\n currentFavicon = originalFavicon;\n setFaviconTag(originalFavicon);\n };\n\n Tinycon.setOptions(defaults);\n\n if(typeof define === 'function' && define.amd) {\n define('skin/newsroom/tinycon',Tinycon);\n } else if (typeof module !== 'undefined') {\n module.exports = Tinycon;\n } else {\n window.Tinycon = Tinycon;\n }\n\n})();\n","define('skin/newsroom/Serum.Newsroom',[\n 'jquery',\n 'common/js/lib/Serum.Pubsub',\n 'skin/newsroom/tinycon',\n 'common/module/asset/Serum.Asset.Fragment'\n], function($, Pubsub, Tinycon, Fragment) {\n 'use strict';\n\n // this function is redefined if visibiliy API is supported\n var isVisible = function() {\n return true;\n };\n\n var ENDS_WITH_SLASH = /\\/$/;\n\n function isNewsroomPath (pathname) {\n return ENDS_WITH_SLASH.test(pathname);\n }\n\n // show/hide/update notifications about incoming ab messages\n var StreamNotification = (function() {\n\n var NOTIFICATION_MARKUP =\n '