{"version":3,"sources":["base.js"],"names":["initNotifications","fetchNotificationsCount","markNotificationsAsRead","initReactions","listenForNotificationsBellClick","initFilter","initPagination","initLoadMoreButton","setTimeout","document","getElementById","xmlhttp","locationAsArray","window","location","pathname","split","parsedLastParam","parseInt","length","replace","XMLHttpRequest","ActiveXObject","onreadystatechange","csrfToken","querySelector","content","Number","isInteger","open","setRequestHeader","send","checkUserLoggedIn","instantClick","InstantClick","removeExpiredKeys","preload","href","butts","getElementsByClassName","i","onclick","event","successCb","response","result","thisButt","classList","add","remove","preventDefault","sendHapticMessage","this","formData","FormData","append","dataset","reactableType","category","reactableId","getCsrfToken","then","sendFetch","status","json","showModalAfterError","element","action_ing","action_past","focus","notificationsLink","notificationsFilterSelect","changeNotifications","target","value","addEventListener","paginators","paginator","fetch","paginationPath","method","credentials","text","html","markup","trim","container","newNotifications","createElement","innerHTML","button","style","display","fetchNext","el","endpoint","insertCallback","indexParams","JSON","parse","params","urlParams","Object","keys","map","k","encodeURIComponent","join","indexOf","fetchUrl","nextPage","Date","now","entries","loadingElement","done","catch","err","console","log","insertNext","buildCallback","listId","newFollowersHTML","forEach","entry","elId","id","newHTML","followList","insertAdjacentHTML","fetching","buildFollowsHTML","follows","path","username","profile_image","name","buildTagsHTML","tag","antifollow","points","color","fetchNextFollowingPage","action","includes","fetchNextFollowersPage","buildVideoArticleHTML","videoArticle","cloudinary_video_url","title","video_duration_in_minutes","user","insertVideos","videoArticles","newVideosHTML","documentElement","scrollHeight","body","scrollTop","parentNode","frag","createRange","createContextualFragment","appendChild","fetchNextVideoPage","insertArticles","articles","newArticlesHTML","outerHTML","article","existingEl","parentElement","contains","buildArticleHTML","initializeReadingListIcons","newNode","articlePath","singleArticles","querySelectorAll","insertAfter","paginate","requiresApproval","searchHash","assign","per_page","page","tag_names","push","approved","homeEl","feed","class_name","sort_by","articlesSince","searchParams","URLSearchParams","key","Array","isArray","arrayValue","toString","headers","Accept","X-CSRF-Token","Content-Type","checkBlockedContentEvent","CustomEvent","dispatchEvent","fetchNextPageIfNearBottom","indexContainer","fetchCallback","scrollableElem","indexWhich","which","scrollY","checkIfNearBottomOfPage","search","setInterval","initScrolling","called","initializeAllTagEditButtons","tagEditButton","tagAdminButton","userData","admin","moderator_for_tags","archivedPosts","showArchivedPosts","posts","hideArchivedPosts","toggleArchivedPosts","e","link","match","initializeArchivedPostFilter","initializeArticleDate","addLocalizedDateTimeToElementsTitles","setReactionCount","reactionName","newCount","reactionClassList","reactionNumber","textContent","showUserReaction","animatedClass","reactionButton","setAttribute","hideUserReaction","hasUserReacted","getNumReactions","reactionEl","reactToArticle","articleId","reaction","toggleReaction","currentNum","createFormdata","userStatus","getAttribute","disabled","undefined","showLoginModal","setCollectionFunctionality","inbetweenLinks","inbetweenLinksLength","els","elsLength","j","className","requestReactionCounts","ajaxReq","readyState","DONE","article_reaction_counts","count","reactions","initializeArticleReactions","reactionButts","initializeBaseTracking","wait","addedGA","gaTrackingCode","gaTracking","waitingOnGA","s","o","g","r","a","m","q","arguments","l","getElementsByTagName","async","src","insertBefore","ga","create","clearInterval","fallbackActivityRecording","eventListening","trackCustomImpressions","tokenMeta","w","Math","max","clientWidth","innerWidth","h","clientHeight","innerHeight","screenW","screen","availWidth","screenH","availHeight","dataBody","user_language","navigator","language","referrer","user_agent","userAgent","viewport_size","screen_resolution","document_title","document_encoding","characterSet","document_path","stringify","registerNowButt","ArticleElement","isBot","test","windowBigEnough","stickyNav","sidebarHTMLVariant","html_variant_id","variantId","article_id","trackHTMLVariantTrial","successLinks","trackHtmlVariantSuccess","belowArticleHTMLVariant","randomNumber","floor","random","trackPageView","timeOnSiteCounter","timeOnSiteInterval","trackFifteenSecondsOnPage","displayAds","unit","trackAdImpression","removeEventListener","trackAdClick","token","adBox","display_ad_event","display_ad_id","context_type","clickedElement","closest","adClicked","initializeProfileImage","profile_image_90","addRelevantButtonsToArticle","articleContainer","buttonsInitialized","actions","published","authorId","clickToEditButton","pinnedArticleId","addRelevantButtonsToComments","settingsButts","butt","commentableUserId","userId","trusted","modButts","setCurrentUserToNavBar","userNavLink","initializeBaseUserData","removeExistingCSRF","csrfTokenMeta","csrfParamMeta","removeChild","fetchBaseData","responseText","newCsrfParamMeta","param","head","newCsrfTokenMeta","loaded","broadcast","creator","creatorOnboarding","creator_onboarding","browserStoreCache","initializeBodyData","broadcastData","camelizedBroadcastKey","string","toUpperCase","addCloseButtonClickHandle","localStorage","setItem","renderBroadcast","broadcastElement","data","banner_class","defaultClass","additionalClass","closeButton","initializeBroadcast","shouldHideBroadcast","frameElement","display_announcements","getItem","firstElementChild","toggle","initializeColorPicker","colorValueChange","field","nextElementSibling","previousElementSibling","from","picker","initializeCommentDate","getAndShowPreview","preview","editor","attachTwitterTimelineScript","script","processed_html","activateRunkitTags","payload","comment","body_markdown","handleCommentPreview","form","trigger","editorHeight","offsetHeight","minHeight","initializeCommentPreview","previewButton","initializeCommentsPage","toggleCodeOfConduct","commentableId","commentableType","hasRecentCommentActivity","commentableIdList","responseObj","allNodes","publicReactionCounts","public_reaction_counts","buttForComment","reactable_id","reactionsCountWrapper","reactionsLabelWrapper","I18n","t","toLowerCase","commentAuthorId","current_user","currentUserComment","userActionsEl","buttEl","commentId","reactionCount","reactionLabel","replyButts","parentId","waitingOnCSRF","commentWrapper","buildCommentFormHTML","handleCommentSubmit","listenForDetailsToggle","handleHiddenComments","codeOfConduct","checked_code_of_conduct","checkboxWrapper","textarea","height","blur","parentComment","commentParentId","commentable_id","commentable_type","parent_id","newComment","buildCommentHTML","docBody","checkbox","mainCommentsForm","handleFormClose","depth","replyTrigger","threadIndicator","iconSmallThread","actionsNode","nextSibling","commentInputs","input","comment_template","togglePreview","firstChild","newDiv","url","replaceWith","updateCommentsCount","handleFocus","handleButtonsActivation","area","handleSizeChange","Forem","initializeMentionAutocompleteTextArea","handleKeyUp","handleSubmit","click","handleBoldAndItalic","textArea","selection","substring","selectionStart","selectionEnd","surroundingStr","keyCode","KEY_CODE_B","replaceSelectedText","selectionStartWithOffset","setSelectionRange","handleLink","startOffset","endOffset","execCommand","setRangeText","handleKeyDown","Runtime","hasOSSpecificModifier","KEY_CODE_I","KEY_CODE_K","ENTER_KEY_CODE","oldHeight","buttons","validateField","handleChange","generateUploadFormdata","image","handleImageUpload","randomIdNumber","onchange","files","address","messageContainer","links","select","uploadedMessage","position","top","showRateLimitModal","responseBody","errorMessage","error","updateItemSummaryHtml","item","itemSummaryContent","usernames","number","itemUsername","detailItems","commentsCountDiv","commentsCountData","commentsCount","currentUser","commentableAuthorIds","coAuthorIds","coAuthorId","commentsContainer","commentableAuthorId","commentableCoAuthorIds","podCastEpisodeContainer","creatorId","collapseCommentsHiddenByCommentableUser","initializeCreditsPage","localizeTimeElements","year","month","day","hour","minute","second","selectNavigation","urlPrefix","initializeDashboardSort","initializeDateHelpers","initializeDrawerSliders","slideSidebar","on","feedFilterSelect","initializeHeroBannerClose","bannerWrapper","closeIcon","initializeLocalStorageRender","initializeSponsorshipVisibility","initializeOnboardingTaskCard","taskCard","createdAt","created_at","setDate","getDate","initializePWAFunctionality","matchMedia","matches","history","back","forward","reload","domain","protocol","host","initializePaymentPointers","userPointer","basePointer","meta","paymentPointer","initializePodcastPlayback","getById","getByClass","newAudioState","currentTime","playing","muted","volume","duration","updated","getTime","windowName","currentAudioState","currentState","audioExistAndIsPlaying","audio","recordExist","activeEpisode","spinPodcastRecord","customMessage","podcastPlaybackButton","changeStatusMessage","stopRotatingActivePodcastIfExist","findRecords","podcastPageRecords","podcastLiquidTagrecords","saveMediaState","state","newState","applyOnclickToPodcastBar","playPause","muteUnmute","goToTime","updateVolume","changePlaybackRate","terminatePodcastBar","podcastBarAlreadyExistAndPlayingTargetEpisode","episodeSlug","updateProgressListener","bufferValue","buffered","end","updateProgress","loadAudio","podcastMessage","load","loadAndPlayNewPodcast","findAndApplyOnclickToRecords","records","prototype","call","record","togglePodcastState","speed","parseFloat","playbackRate","rate","message","statusBox","startPodcastBar","pausePodcastBar","playAudio","Promise","resolve","reject","seconds","setPlaying","play","fetchMetadataString","episodeContainer","sendMetadataMessage","metadata","episodeName","podcastName","podcastImageUrl","startAudioPlayback","pauseAudioPlayback","pause","ahoyMessage","activePodcast","properties","episode","podcast","deviceType","ahoy","track","progress","buffer","time","firstDecimal","width","readableDuration","clientX","percent","sec","min","handlePodcastMessages","detail","namespace","initRuntime","isNativeIOS","isNativeAndroid","msg","ForemMobile","injectNativeMessage","initializeMedia","audioInitialized","audioContent","setReadingListButtonsState","addReadingListCountToHomePage","addHoverEffectToReadingListButtons","readingListButtons","highlightButton","buttonIdInt","reading_list_ids","reactToReadingListButtonClick","saveInitialized","readingListCount","renderOptimisticResult","properButtonFromEvent","buttonFormData","renderButtonState","renderNewSidebarCount","tagName","articlesList","readingListButtonMouseHandler","bind","isReadingListButtonHoverTarget","textReplacement","initializeSettings","settingsOrgSecret","timeNode","timeStamp","timeOptions","timestampToLocalDateTime","mobilePageSelector","sponsorClickHandler","details","listenForSponsorClick","partnerSeen","display_sponsors","formatDateTime","options","Intl","DateTimeFormat","format","convertUtcTime","utcTime","timeZoneName","convertUtcDate","utcDate","convertCalEvent","utc","weekday","updateLocalDateTime","elements","convertCallback","getUtcDateTime","local","initializeTimeFixer","datetime","initializeProfileInfoToggle","infoPanels","triggerWrapper","initializeProfileBadgesToggle","badgesWrapper","badges","badge","initializeVideoPlayback","getParameterByName","results","RegExp","exec","decodeURIComponent","timeToSeconds","hms","videoPlayerEvent","isPlaying","eventName","lastEvent","videoMetadata","initWebPlayer","waitingOnJWP","jwplayer","setup","file","video_source_url","mediaid","video_code","video_thumbnail_url","playbackRateControls","tracks","video_closed_caption_track_url","label","kind","default","seek","videoSource","requestFocus","videoMessage","handleVideoMessages","initializePlayer","playerElement","config_body_class","removeItem","cookieEnabled","slug","image_url","flareTag","currentTag","flare_tag","bg_color_hex","tagString","tagList","tag_list","cached_tag_list_array","filter","commentsDisplay","comments_count","commentsAriaLabelText","picUrl","profileUsername","reactionsCount","public_reactions_count","reactionsDisplay","reactionsText","main_image","forOrganization","organizationLogo","organizationClasses","organization","timeAgoInWords","published_at_int","timeAgo","oldTimeInSeconds","publishDate","readable_publish_date","published_timestamp","isArticle","previewCardContent","user_id","filterXSS","bodyTextSnippet","searchSnippetHTML","highlight","body_text","firstSnippetChar","startingEllipsis","readingTimeHTML","reading_time","saveButton","videoHTML","video_duration_string","navigationLink","authToken","commentCount","iconSmallOverflowHorizontal","iconCollapse","iconExpand","depthClass","detailsStartHTML","detailsEndHTML","commentHeader","commentFooter","commentAvatar","newly_created","profile_pic","react","reply","body_html","iconSmallComment","replyButton","num","iconSmallHeart","iconSmallHeartFilled","heart_ids","dynamicallyLoadScript","metaTag","Honeybadger","notify","Error","getCurrentPage","classString","getImageForLink","elem","imageUrl","$fetchedImageUrls","Image","referenceNode","timestamp","locale","timestampAttribute","localDateTime","timestampToLocalDateTimeLong","timestampToLocalDateTimeShort","currentYear","getFullYear","localStorageTest","preventDefaultAction","switchStatement","addTokenToBody","webkit","messageHandlers","haptic","postMessage","showModal","contentSelector","overlay","showUserAlertModal","confirm_text","buildModalDiv","modalId","timeframe","buildRateLimitText","errorResponse","modalDiv","getModal","wrapper","getModalHtml","side","direction","mainContent","secondsToHumanUnitAgo","times","scale","wholeUnits","formatter","humanTime","maxDisplayedAge","timeNow","diff","round","callInitializers","initializePage","waitingForDataLoad","runtime","currentContext","initializeBaseApp","init","client","[object Object]","currentMedium","currentOS","pwaButtons","windowsPlatforms","iosPlatforms","platform","nativeCheck","namespaceCheck","AndroidBridge","copyToClipboard","clipboard","writeText","KeyboardEvent","metaKey","ctrlKey","globalThis","n","u","require","f","code","exports","1","module","getDefaultWhiteList","onTag","onIgnoreTag","onTagAttr","onIgnoreTagAttr","escapeHtml","REGEXP_LT","REGEXP_GT","safeAttrValue","cssFilter","friendlyAttrValue","_","substr","REGEXP_DEFAULT_ON_TAG_ATTR_4","lastIndex","REGEXP_DEFAULT_ON_TAG_ATTR_7","REGEXP_DEFAULT_ON_TAG_ATTR_8","defaultCSSFilter","process","escapeAttrValue","escapeQuote","str","REGEXP_QUOTE","unescapeQuote","REGEXP_QUOTE_2","escapeHtmlEntities","REGEXP_ATTR_VALUE_1","String","fromCharCode","escapeDangerHtml5Entities","REGEXP_ATTR_VALUE_COLON","REGEXP_ATTR_VALUE_NEWLINE","clearNonPrintableCharacter","str2","len","charCodeAt","charAt","onIgnoreTagStripAll","StripTagBody","tags","next","isRemoveTag","isRemoveAllTag","removeList","posStart","isClosing","ret","rethtml","lastPos","pos","slice","stripCommentTag","STRIP_COMMENT_TAG_REGEXP","stripBlankChar","chars","char","c","FilterCSS","getDefaultCSSWhiteList","whiteList","./util","cssfilter","2","FilterXSS","DEFAULT","parser","./default","./parser","./xss","3","getTagName","parseTag","tagStart","quoteStart","currentPos","currentHtml","currentTagName","parseAttr","onAttr","addAttr","REGEXP_ATTR_NAME","retAttrs","tmpName","findNextEqual","findBeforeEqual","stripQuoteWrap","isQuoteWrapString","4","arr","fn","scope","5","isNull","obj","getAttrs","closing","shallowCopyObject","stripIgnoreTag","css","me","allowCommentTag","stripIgnoreTagBody","retHtml","sourcePosition","info","isWhite","attrs","whiteAttrList","attrsHtml","isWhiteAttr","6","onIgnoreAttr","parseStyle","source","check","opts","7","align-content","align-items","align-self","alignment-adjust","alignment-baseline","all","anchor-point","animation","animation-delay","animation-direction","animation-duration","animation-fill-mode","animation-iteration-count","animation-name","animation-play-state","animation-timing-function","azimuth","backface-visibility","background","background-attachment","background-clip","background-color","background-image","background-origin","background-position","background-repeat","background-size","baseline-shift","binding","bleed","bookmark-label","bookmark-level","bookmark-state","border","border-bottom","border-bottom-color","border-bottom-left-radius","border-bottom-right-radius","border-bottom-style","border-bottom-width","border-collapse","border-color","border-image","border-image-outset","border-image-repeat","border-image-slice","border-image-source","border-image-width","border-left","border-left-color","border-left-style","border-left-width","border-radius","border-right","border-right-color","border-right-style","border-right-width","border-spacing","border-style","border-top","border-top-color","border-top-left-radius","border-top-right-radius","border-top-style","border-top-width","border-width","bottom","box-decoration-break","box-shadow","box-sizing","box-snap","box-suppress","break-after","break-before","break-inside","caption-side","chains","clear","clip","clip-path","clip-rule","color-interpolation-filters","column-count","column-fill","column-gap","column-rule","column-rule-color","column-rule-style","column-rule-width","column-span","column-width","columns","contain","counter-increment","counter-reset","counter-set","crop","cue","cue-after","cue-before","cursor","display-inside","display-list","display-outside","dominant-baseline","elevation","empty-cells","flex","flex-basis","flex-direction","flex-flow","flex-grow","flex-shrink","flex-wrap","float","float-offset","flood-color","flood-opacity","flow-from","flow-into","font","font-family","font-feature-settings","font-kerning","font-language-override","font-size","font-size-adjust","font-stretch","font-style","font-synthesis","font-variant","font-variant-alternates","font-variant-caps","font-variant-east-asian","font-variant-ligatures","font-variant-numeric","font-variant-position","font-weight","grid","grid-area","grid-auto-columns","grid-auto-flow","grid-auto-rows","grid-column","grid-column-end","grid-column-start","grid-row","grid-row-end","grid-row-start","grid-template","grid-template-areas","grid-template-columns","grid-template-rows","hanging-punctuation","hyphens","icon","image-orientation","image-resolution","ime-mode","initial-letters","inline-box-align","justify-content","justify-items","justify-self","left","letter-spacing","lighting-color","line-box-contain","line-break","line-grid","line-height","line-snap","line-stacking","line-stacking-ruby","line-stacking-shift","line-stacking-strategy","list-style","list-style-image","list-style-position","list-style-type","margin","margin-bottom","margin-left","margin-right","margin-top","marker-offset","marker-side","marks","mask","mask-box","mask-box-outset","mask-box-repeat","mask-box-slice","mask-box-source","mask-box-width","mask-clip","mask-image","mask-origin","mask-position","mask-repeat","mask-size","mask-source-type","mask-type","max-height","max-lines","max-width","min-height","min-width","move-to","nav-down","nav-index","nav-left","nav-right","nav-up","object-fit","object-position","opacity","order","orphans","outline","outline-color","outline-offset","outline-style","outline-width","overflow","overflow-wrap","overflow-x","overflow-y","padding","padding-bottom","padding-left","padding-right","padding-top","page-break-after","page-break-before","page-break-inside","page-policy","pause-after","pause-before","perspective","perspective-origin","pitch","pitch-range","play-during","presentation-level","quotes","region-fragment","resize","rest","rest-after","rest-before","richness","right","rotation","rotation-point","ruby-align","ruby-merge","ruby-position","shape-image-threshold","shape-outside","shape-margin","size","speak","speak-as","speak-header","speak-numeral","speak-punctuation","speech-rate","stress","string-set","tab-size","table-layout","text-align","text-align-last","text-combine-upright","text-decoration","text-decoration-color","text-decoration-line","text-decoration-skip","text-decoration-style","text-emphasis","text-emphasis-color","text-emphasis-position","text-emphasis-style","text-height","text-indent","text-justify","text-orientation","text-overflow","text-shadow","text-space-collapse","text-transform","text-underline-position","text-wrap","transform","transform-origin","transform-style","transition","transition-delay","transition-duration","transition-property","transition-timing-function","unicode-bidi","vertical-align","visibility","voice-balance","voice-duration","voice-family","voice-pitch","voice-range","voice-rate","voice-stress","voice-volume","white-space","widows","will-change","word-break","word-spacing","word-wrap","wrap-flow","wrap-through","writing-mode","z-index","8","filterCSS","./css","9","addNewAttr","isParenthesisOpen","retCSS","trimRight","cssLength","10","global","factory","define","amd","self","_typeof","Symbol","iterator","constructor","sanitize","maxDepth","seen","seenObjects","canSerialize","hasOwnProperty","serialize","v","stringNameOfElement","concat","stringClassNames","attrName","attr","siblings","getSiblings","stringSelectorOfElement","parentName","stringTextOfElement","innerText","type","truncate","nativeFetch","isNative","sandbox","contentWindow","warn","func","parseURL","localURLPathname","parsed","parsedDocURL","URL","nodes","childNodes","node","builder","merge","obj1","obj2","obj3","newObject","new_obj","mergeErr","err1","err2","context","currentErrIs","currentErr","stack","isIgnored","patterns","some","p","encodeCookie","object","cookies","stackTrace","stacktrace","generateStackTrace","maxStackSize","generator","curr","callee","$1","caller","checkHandlers","handlers","handler","objectIsEmpty","objectIsExtensible","isExtensible","VERSION","NOTIFIER","version","installed","factoryCount","args","unshift","apply","debug","config","fallback","onErrorEnabled","notSingleton","onUnhandledRejectionEnabled","breadcrumbsEnabled","baseURL","request","apiKey","notice","buildPayload","x","onload","afterNotifyHandlers","afterNotify","statusText","exceedsMaxErrors","incrementErrorsCount","notifier","breadcrumbs","enabled","trail","class","backtrace","fingerprint","component","cgi_data","server","project_root","projectRoot","environment_name","environment","revision","generated","addBreadcrumb","stack_before_handlers","beforeNotifyHandlers","queue","wrap","___hb","onerror","preferCatch","force","_e","instrument","replacement","original","__hb_original","errorsSent","maxErrors","singleton","defaultProps","dom","network","navigation","atob","ErrorEvent","colno","extra","setContext","resetContext","configure","integrations","integration","beforeNotify","reset","resetMaxErrors","getVersion","toISOString","limit","selector","xhr","__hb_xhr","onreadystatechangeHandler","status_code","Request","recordUrlChange","to","lastHref","historyWrapper","inspectArray","level","Function","instrumentTimer","wrapOpts","delay","prop","listener","useCapture","wantsUntrusted","handleEvent","line","col","simulatedStack","onunhandledrejection","promiseRejectionEvent","reason","fileName","lineNumber","stackFallback","domReady","pop","attachEvent","root","toFixed","precision","decimalAdjust","isObject","isFunction","isSet","val","isString","isNumber","isBoolean","exp","isNaN","NaN","lazyEvaluate","dest","DATE","day_names","abbr_day_names","month_names","abbr_month_names","meridian","NUMBER_FORMAT","separator","delimiter","strip_insignificant_zeros","CURRENCY_FORMAT","sign_first","PERCENTAGE_FORMAT","SIZE_UNITS","DEFAULT_OPTIONS","defaultLocale","defaultSeparator","placeholder","fallbacks","translations","missingBehaviour","missingTranslationPrefix","initializeOptions","locales","get","list","localeParts","firstFallback","secondFallback","nullableFallbackLocale","pluralization","currentLocale","lookup","scopes","fullScope","getFullScope","shift","defaultValue","pluralizationLookupWithoutFallback","pluralizerKey","pluralizerKeys","pluralizer","pluralizationLookup","date","am","pm","prepareOptions","subject","createTranslationOptions","translationOptions","defaults","translate","translation","usedScope","optionsWithoutDefault","translationOption","interpolate","pluralize","missingTranslation","regex","nullPlaceholder","missingPlaceholder","p1","p2","toNumber","formattedNumber","negative","parts","abs","sign","toCurrency","localize","toPercentage","localizedValue","toTime","parseDate","convertedDate","fraction","UTC","setTime","$2","$3","$6","$4","$5","strftime","meridianOptions","weekDay","getDay","getMonth","getHours","hour12","secs","getSeconds","mins","getMinutes","offset","getTimezoneOffset","absOffsetHours","absOffsetMinutes","timezoneoffset","dateString","date_string","toHumanSize","kb","iterations","extend","visitsUrl","eventsUrl","isEmpty","canTrackNow","useBeacon","trackNow","canStringify","withCredentials","setCookie","ttl","Cookies","set","cookieDomain","getCookie","destroyCookie","setReady","callback","isReady","matchesSelector","mozMatchesSelector","msMatchesSelector","oMatchesSelector","webkitMatchesSelector","onEvent","matchedElement","documentReady","generateId","saveEventQueue","eventQueue","csrfParam","CSRFProtection","sendRequest","success","$","ajax","contentType","dataType","beforeSend","xhrFields","header","eventData","events","visit_token","visitor_token","trackEvent","ready","splice","trackEventNow","events_json","sendBeacon","presence","cleanObject","eventProperties","section","getClosestSection","hasAttribute","createVisit","visitId","getVisitId","visitorId","getVisitorId","trackVisits","visitDuration","visitorDuration","landing_page","screen_width","screen_height","js","visitParams","expires","toGMTString","cookie","escape","nameEQ","ca","unescape","startOnReady","Ahoy","jQuery","Zepto","getVisitToken","getVisitorToken","trackView","additionalProperties","propName","trackClicks","trackSubmits","trackChanges","start","$userAgent","removeHash","index","getLinkTarget","nodeName","isNotPreloadable","isPreloadable","$currentLocationWithoutHash","triggerPageEvent","eventType","arg1","arg2","arg3","returnValue","$eventsCallbacks","altered","changePage","newUrl","pageContentDiv","memberMenuButton","replaceChild","routeChangeTarget","pushState","hashIndex","hashElem","samePage","offsetParent","offsetTop","scrollTo","$isChromeForIOS","instantanize","setPreloadingAsHalted","$isPreloading","$isWaitingForCompletion","removeNoscriptTags","mousedownListener","$lastTouchTimestamp","mouseoverListener","mouseoutListener","$delayBeforePreload","$urlToPreload","$preloadTimer","touchstartListener","$preloadOnMousedown","focusListener","clickListener","clearTimeout","$xhr","abort","readystatechangeListener","processXHR","$url","$timing","getResponseHeader","doc","implementation","createHTMLDocument","alteredOnReceive","$fetchedBodies","elems","children","found","$trackedAssets","$mustRedirect","popstateListener","loc","$history","pageYOffset","isInitializing","originalElement","copyElement","scriptElementsInDOM","scriptElementsToCopy","attributes","option","internalUrl","getURLInfo","preloadingMode","supported","addRefreshBehavior","waitingOnPTR","PullToRefresh","mainElement","passive","onRefresh","receive","change","restore","honeybadgerKey","releaseFootprint","ignorePatterns"],"mappings":"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","sourceRoot":"/assets","sourcesContent":["/* global checkUserLoggedIn, instantClick, InstantClick, sendHapticMessage, showModalAfterError */\n\nfunction initNotifications() {\n fetchNotificationsCount();\n markNotificationsAsRead();\n initReactions();\n listenForNotificationsBellClick();\n initFilter();\n initPagination();\n initLoadMoreButton();\n}\n\nfunction markNotificationsAsRead() {\n setTimeout(function () {\n if (document.getElementById('notifications-container')) {\n var xmlhttp;\n var locationAsArray = window.location.pathname.split('/');\n // Use regex to ensure only numbers in the original string are converted to integers\n var parsedLastParam = parseInt(\n locationAsArray[locationAsArray.length - 1].replace(/[^0-9]/g, ''),\n 10,\n );\n\n if (window.XMLHttpRequest) {\n xmlhttp = new XMLHttpRequest();\n } else {\n xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');\n }\n xmlhttp.onreadystatechange = function () {};\n\n var csrfToken = document.querySelector(\"meta[name='csrf-token']\").content;\n\n if (Number.isInteger(parsedLastParam)) {\n xmlhttp.open(\n 'Post',\n '/notifications/reads?org_id=' + parsedLastParam,\n true,\n );\n } else {\n xmlhttp.open('Post', '/notifications/reads', true);\n }\n xmlhttp.setRequestHeader('X-CSRF-Token', csrfToken);\n xmlhttp.send();\n }\n }, 450);\n}\n\nfunction fetchNotificationsCount() {\n if (\n document.getElementById('notifications-container') == null \u0026\u0026\n checkUserLoggedIn()\n ) {\n // Prefetch notifications page\n if (instantClick) {\n InstantClick.removeExpiredKeys('force');\n setTimeout(function () {\n InstantClick.preload(\n document.getElementById('notifications-link').href,\n 'force',\n );\n }, 30);\n }\n }\n}\n\nfunction initReactions() {\n setTimeout(function () {\n if (document.getElementById('notifications-container')) {\n var butts = document.getElementsByClassName('reaction-button');\n\n for (var i = 0; i \u003c butts.length; i++) {\n var butt = butts[i];\n butt.onclick = function (event) {\n event.preventDefault();\n sendHapticMessage('medium');\n var thisButt = this;\n thisButt.classList.add('reacted');\n\n function successCb(response) {\n if (response.result === 'create') {\n thisButt.classList.add('reacted');\n } else {\n thisButt.classList.remove('reacted');\n }\n }\n\n var formData = new FormData();\n formData.append('reactable_type', thisButt.dataset.reactableType);\n formData.append('category', thisButt.dataset.category);\n formData.append('reactable_id', thisButt.dataset.reactableId);\n\n getCsrfToken()\n .then(sendFetch('reaction-creation', formData))\n .then(function (response) {\n if (response.status === 200) {\n response.json().then(successCb);\n } else {\n showModalAfterError({\n response,\n element: 'reaction',\n action_ing: 'updating',\n action_past: 'updated',\n });\n }\n });\n };\n }\n\n butts = document.getElementsByClassName('toggle-reply-form');\n\n for (let i = 0; i \u003c butts.length; i++) {\n const butt = butts[i];\n\n butt.onclick = function (event) {\n event.preventDefault();\n var thisButt = this;\n document\n .getElementById('comment-form-for-' + thisButt.dataset.reactableId)\n .classList.remove('hidden');\n thisButt.classList.add('hidden');\n thisButt.classList.remove('inline-flex');\n setTimeout(function () {\n document\n .getElementById(\n 'comment-textarea-for-' + thisButt.dataset.reactableId,\n )\n .focus();\n }, 30);\n };\n }\n }\n }, 180);\n}\n\nfunction listenForNotificationsBellClick() {\n var notificationsLink = document.getElementById('notifications-link');\n if (notificationsLink) {\n setTimeout(function () {\n notificationsLink.onclick = function () {\n document.getElementById('notifications-number').classList.add('hidden');\n };\n }, 180);\n }\n}\n\nfunction initFilter() {\n const notificationsFilterSelect = document.getElementById(\n 'notifications-filter__select',\n );\n const changeNotifications = (event) =\u003e {\n window.location.href = event.target.value;\n };\n if (notificationsFilterSelect) {\n notificationsFilterSelect.addEventListener('change', changeNotifications);\n }\n}\n\nfunction initPagination() {\n // paginators appear after each block of HTML notifications sent by the server\n const paginators = document.getElementsByClassName('notifications-paginator');\n if (paginators \u0026\u0026 paginators.length \u003e 0) {\n const paginator = paginators[paginators.length - 1];\n\n if (paginator) {\n window\n .fetch(paginator.dataset.paginationPath, {\n method: 'GET',\n credentials: 'same-origin',\n })\n .then(function (response) {\n if (response.status === 200) {\n response.text().then(function (html) {\n const markup = html.trim();\n\n if (markup) {\n const container = document.getElementById('articles-list');\n\n const newNotifications = document.createElement('div');\n newNotifications.innerHTML = markup;\n\n paginator.remove();\n container.append(newNotifications);\n\n initReactions();\n } else {\n // no more notifications to load, we hide the load more wrapper\n const button = document.getElementById('load-more-button');\n if (button) {\n button.style.display = 'none';\n }\n paginator.remove();\n }\n });\n }\n });\n }\n }\n}\n\nfunction initLoadMoreButton() {\n const button = document.getElementById('load-more-button');\n if (button) {\n button.addEventListener('click', initPagination);\n }\n};\n/* global insertAfter, insertArticles, buildArticleHTML, nextPage:writable, fetching:writable, done:writable, InstantClick */\n\nvar client;\n\nfunction fetchNext(el, endpoint, insertCallback) {\n var indexParams = JSON.parse(el.dataset.params);\n var urlParams = Object.keys(indexParams)\n .map(function handleMap(k) {\n return encodeURIComponent(k) + '=' + encodeURIComponent(indexParams[k]);\n })\n .join('\u0026');\n if (urlParams.indexOf('q=') \u003e -1) {\n return;\n }\n var fetchUrl = (\n endpoint +\n '?page=' +\n nextPage +\n '\u0026' +\n urlParams +\n '\u0026signature=' +\n parseInt(Date.now() / 400000, 10)\n ).replace('\u0026\u0026', '\u0026');\n window\n .fetch(fetchUrl)\n .then(function handleResponse(response) {\n response.json().then(function insertEntries(entries) {\n nextPage += 1;\n insertCallback(entries);\n if (entries.length === 0) {\n const loadingElement = document.getElementById('loading-articles');\n if (loadingElement) {\n loadingElement.style.display = 'none';\n }\n done = true;\n }\n });\n })\n .catch(function logError(err) {\n // eslint-disable-next-line no-console\n console.log(err);\n });\n}\n\nfunction insertNext(params, buildCallback) {\n return function insertEntries(entries = []) {\n var list = document.getElementById(params.listId || 'sublist');\n var newFollowersHTML = '';\n entries.forEach(function insertAnEntry(entry) {\n let existingEl = document.getElementById(\n (params.elId || 'element') + '-' + entry.id,\n );\n if (!existingEl) {\n var newHTML = buildCallback(entry);\n newFollowersHTML += newHTML;\n }\n });\n\n var followList = document.getElementById('following-wrapper');\n if (followList) {\n followList.insertAdjacentHTML('beforeend', newFollowersHTML);\n }\n if (nextPage \u003e 0) {\n fetching = false;\n }\n };\n}\n\nfunction buildFollowsHTML(follows) {\n return (\n '\u003cdiv class=\"crayons-card p-4 m:p-6 flex s:grid single-article\" id=\"follows-' +\n follows.id +\n '\"\u003e' +\n '\u003ca href=\"' +\n follows.path +\n '\" class=\"crayons-avatar crayons-avatar--2xl s:mb-2 s:mx-auto\"\u003e' +\n '\u003cimg alt=\"@' +\n follows.username +\n ' profile image\" class=\"crayons-avatar__image\" src=\"' +\n follows.profile_image +\n '\" /\u003e' +\n '\u003c/a\u003e' +\n '\u003cdiv class=\"pl-4 s:pl-0 self-center\"\u003e' +\n '\u003ch3 class=\"s:mb-1 p-0\"\u003e' +\n '\u003ca href=\"' +\n follows.path +\n '\"\u003e' +\n follows.name +\n '\u003c/a\u003e' +\n '\u003c/h3\u003e' +\n '\u003cp class=\"s:mb-4\"\u003e' +\n '\u003ca href=\"' +\n follows.path +\n '\" class=\"crayons-link crayons-link--secondary\"\u003e' +\n '@' +\n follows.username +\n '\u003c/a\u003e' +\n '\u003c/p\u003e' +\n '\u003c/div\u003e' +\n '\u003c/div\u003e'\n );\n}\n\nfunction buildTagsHTML(tag) {\n var antifollow = '';\n if (tag.points \u003c 0) {\n antifollow =\n '\u003cspan class=\"crayons-indicator crayons-indicator--critical crayons-indicator--outlined\" title=\"This tag has negative follow weight\"\u003eAnti-follow\u003c/span\u003e';\n }\n\n return `\u003cdiv class=\"crayons-card p-4 m:p-6 flex flex-col single-article\" id=\"follows-${tag.id}\" style=\"border: 1px solid ${tag.color}; box-shadow: 3px 3px 0 ${tag.color}\"\u003e\n \u003ch3 class=\"s:mb-1 p-0 fw-medium\"\u003e\n \u003ca href=\"/t/${tag.name}\" class=\"crayons-tag crayons-tag--l\"\u003e\n \u003cspan class=\"crayons-tag__prefix\"\u003e#\u003c/span\u003e${tag.name}\n \u003c/a\u003e\n ${antifollow}\n \u003c/h3\u003e\n \u003cp class=\"grid-cell__summary truncate-at-3\"\u003e\u003c/p\u003e\n \u003cinput name=\"follows[][id]\" id=\"follow_id_${tag.name}\" type=\"hidden\" form=\"follows_update_form\" value=\"${tag.id}\"\u003e\n \u003cinput step=\"any\" class=\"crayons-textfield flex-1 fs-s\" required=\"required\" type=\"number\" form=\"follows_update_form\" value=\"${tag.points}\" name=\"follows[][explicit_points]\" id=\"follow_points_${tag.name}\" aria-label=\"${tag.name} tag weight\"\u003e\n \u003c/div\u003e`;\n}\n\nfunction fetchNextFollowingPage(el) {\n var indexParams = JSON.parse(el.dataset.params);\n var action = indexParams.action;\n if (action.includes('users')) {\n fetchNext(\n el,\n '/followings/users',\n insertNext({ elId: 'follows' }, buildFollowsHTML),\n );\n } else if (action.includes('podcasts')) {\n fetchNext(\n el,\n '/followings/podcasts',\n insertNext({ elId: 'follows' }, buildFollowsHTML),\n );\n } else if (action.includes('organizations')) {\n fetchNext(\n el,\n '/followings/organizations',\n insertNext({ elId: 'follows' }, buildFollowsHTML),\n );\n } else {\n fetchNext(\n el,\n '/followings/tags',\n insertNext({ elId: 'follows' }, buildTagsHTML),\n );\n }\n}\n\nfunction fetchNextFollowersPage(el) {\n fetchNext(\n el,\n '/api/followers/users',\n insertNext({ elId: 'follows' }, buildFollowsHTML),\n );\n}\n\nfunction buildVideoArticleHTML(videoArticle) {\n return `\u003ca href=\"${videoArticle.path}\" id=\"video-article-${videoArticle.id}\" class=\"crayons-card media-card\"\u003e\n \u003cdiv class=\"media-card__artwork\"\u003e\n \u003cimg src=\"${videoArticle.cloudinary_video_url}\" class=\"w-100 object-cover block aspect-16-9 h-auto\" width=\"320\" height=\"180\" alt=\"${videoArticle.title}\"\u003e\n \u003cspan class=\"media-card__artwork__badge\"\u003e${videoArticle.video_duration_in_minutes}\u003c/span\u003e\n \u003c/div\u003e\n \u003cdiv class=\"media-card__content\"\u003e\n \u003ch2 class=\"fs-base mb-2 fw-medium\"\u003e${videoArticle.title}\u003c/h2\u003e\n \u003csmall class=\"fs-s\"\u003e\n ${videoArticle.user.name}\n \u003c/small\u003e\n \u003c/div\u003e\n \u003c/a\u003e`;\n}\n\nfunction insertVideos(videoArticles) {\n var list = document.getElementById('subvideos');\n var newVideosHTML = '';\n videoArticles.forEach(function insertAVideo(videoArticle) {\n var existingEl = document.getElementById(\n 'video-article-' + videoArticle.id,\n );\n if (!existingEl) {\n var newHTML = buildVideoArticleHTML(videoArticle);\n newVideosHTML += newHTML;\n }\n });\n\n var distanceFromBottom =\n document.documentElement.scrollHeight - document.body.scrollTop;\n\n var parentNode = document.querySelector('.js-video-collection');\n var frag = document.createRange().createContextualFragment(newVideosHTML);\n parentNode.appendChild(frag);\n\n if (nextPage \u003e 0) {\n fetching = false;\n }\n}\n\nfunction fetchNextVideoPage(el) {\n fetchNext(el, '/api/videos', insertVideos);\n}\n\nfunction insertArticles(articles) {\n var list = document.getElementById('substories');\n var newArticlesHTML = '';\n var el = document.getElementById('home-articles-object');\n if (el) {\n el.outerHTML = '';\n }\n articles.forEach(function insertAnArticle(article) {\n var existingEl = document.getElementById('article-link-' + article.id);\n if (\n ![\n '/',\n '/top/week',\n '/top/month',\n '/top/year',\n '/top/infinity',\n '/latest',\n ].includes(window.location.pathname) \u0026\u0026\n existingEl \u0026\u0026\n existingEl.parentElement \u0026\u0026\n existingEl.parentElement.classList.contains('crayons-story') \u0026\u0026\n !document.getElementById('video-player-' + article.id)\n ) {\n existingEl.parentElement.outerHTML = buildArticleHTML(article);\n } else if (!existingEl) {\n var newHTML = buildArticleHTML(article);\n newArticlesHTML += newHTML;\n initializeReadingListIcons();\n }\n });\n var distanceFromBottom =\n document.documentElement.scrollHeight - document.body.scrollTop;\n var newNode = document.createElement('div');\n newNode.classList.add('paged-stories');\n newNode.innerHTML = newArticlesHTML;\n\n newNode.addEventListener('click', (event) =\u003e {\n const { classList } = event.target;\n\n // This looks a little messy, but it's the only\n // way to make the entire card clickable.\n if (\n classList.contains('crayons-story') ||\n classList.contains('crayons-story__top') ||\n classList.contains('crayons-story__body') ||\n classList.contains('crayons-story__indention') ||\n classList.contains('crayons-story__title') ||\n classList.contains('crayons-story__tags') ||\n classList.contains('crayons-story__bottom')\n ) {\n let element = event.target;\n let { articlePath } = element.dataset;\n\n while (!articlePath) {\n articlePath = element.dataset.articlePath;\n element = element.parentElement;\n }\n\n InstantClick.preload(articlePath);\n InstantClick.display(articlePath);\n }\n });\n\n var singleArticles = document.querySelectorAll(\n '.single-article, .crayons-story',\n );\n var lastElement = singleArticles[singleArticles.length - 1];\n insertAfter(newNode, lastElement);\n if (nextPage \u003e 0) {\n fetching = false;\n }\n}\n\nfunction paginate(tag, params, requiresApproval) {\n const searchHash = Object.assign(\n { per_page: 15, page: nextPage },\n JSON.parse(params),\n );\n\n if (tag \u0026\u0026 tag.length \u003e 0) {\n searchHash.tag_names = searchHash.tag_names || [];\n searchHash.tag_names.push(tag);\n }\n searchHash.approved = requiresApproval === 'true' ? 'true' : '';\n\n var homeEl = document.getElementById('index-container');\n if (homeEl.dataset.feed === 'base-feed') {\n searchHash.class_name = 'Article';\n } else if (homeEl.dataset.feed === 'latest') {\n searchHash.class_name = 'Article';\n searchHash.sort_by = 'published_at';\n } else {\n searchHash.class_name = 'Article';\n searchHash['published_at[gte]'] = homeEl.dataset.articlesSince;\n searchHash.sort_by = 'public_reactions_count';\n }\n\n // Brute force copying code from a utility for quick fix\n const searchParams = new URLSearchParams();\n Object.keys(searchHash).forEach((key) =\u003e {\n const value = searchHash[key];\n if (Array.isArray(value)) {\n value.forEach((arrayValue) =\u003e {\n searchParams.append(`${key}[]`, arrayValue);\n });\n } else {\n searchParams.append(key, value);\n }\n });\n\n fetch(`/search/feed_content?${searchParams.toString()}`, {\n method: 'GET',\n headers: {\n Accept: 'application/json',\n 'X-CSRF-Token': window.csrfToken,\n 'Content-Type': 'application/json',\n },\n credentials: 'same-origin',\n })\n .then((response) =\u003e response.json())\n .then((content) =\u003e {\n nextPage += 1;\n insertArticles(content.result);\n const checkBlockedContentEvent = new CustomEvent('checkBlockedContent');\n window.dispatchEvent(checkBlockedContentEvent);\n initializeReadingListIcons();\n if (content.result.length === 0) {\n const loadingElement = document.getElementById('loading-articles');\n if (loadingElement) {\n loadingElement.style.display = 'none';\n }\n done = true;\n }\n });\n}\n\nfunction fetchNextPageIfNearBottom() {\n var indexContainer = document.getElementById('index-container');\n var elCheck = indexContainer \u0026\u0026 !document.getElementById('query-wrapper');\n if (!elCheck) {\n return;\n }\n\n var indexWhich = indexContainer.dataset.which;\n\n var fetchCallback;\n var scrollableElem;\n\n if (indexWhich === 'videos') {\n scrollableElem = document.getElementById('main-content');\n fetchCallback = function fetch() {\n fetchNextVideoPage(indexContainer);\n };\n } else if (indexWhich === 'followers') {\n scrollableElem = document.getElementById('user-dashboard');\n fetchCallback = function fetch() {\n fetchNextFollowersPage(indexContainer);\n };\n } else if (indexWhich === 'following') {\n scrollableElem = document.getElementById('user-dashboard');\n fetchCallback = function fetch() {\n fetchNextFollowingPage(indexContainer);\n };\n } else {\n scrollableElem =\n document.getElementById('main-content') ||\n document.getElementById('articles-list');\n\n fetchCallback = function fetch() {\n paginate(\n indexContainer.dataset.tag,\n indexContainer.dataset.params,\n indexContainer.dataset.requiresApproval,\n );\n };\n }\n\n if (\n !done \u0026\u0026\n !fetching \u0026\u0026\n window.scrollY \u003e scrollableElem.scrollHeight - 3700\n ) {\n fetching = true;\n fetchCallback();\n }\n}\n\nfunction checkIfNearBottomOfPage() {\n const loadingElement = document.getElementById('loading-articles');\n if (\n (document.getElementsByClassName('crayons-story').length \u003c 2 \u0026\u0026\n document.getElementsByClassName('single-article').length \u003c 2) ||\n window.location.search.indexOf('q=') \u003e -1\n ) {\n if (loadingElement) {\n loadingElement.style.display = 'none';\n }\n done = true;\n } else if (loadingElement) {\n loadingElement.style.display = 'block';\n }\n fetchNextPageIfNearBottom();\n setInterval(function handleInterval() {\n fetchNextPageIfNearBottom();\n }, 210);\n}\n\nfunction initScrolling() {\n var elCheck = document.getElementById('index-container');\n\n if (elCheck) {\n initScrolling.called = true;\n checkIfNearBottomOfPage();\n }\n};\n'use strict';\n\nfunction initializeAllTagEditButtons() {\n var tagEditButton = document.getElementById('tag-edit-button');\n var tagAdminButton = document.getElementById('tag-admin-button');\n var user = userData();\n if (user.admin \u0026\u0026 tagAdminButton) {\n tagAdminButton.style.display = 'inline-block';\n document.getElementById('tag-admin-button').style.display = 'inline-block';\n }\n if (\n user \u0026\u0026\n tagEditButton \u0026\u0026\n (user.moderator_for_tags.indexOf(tagEditButton.dataset.tag) \u003e -1 ||\n user.admin)\n ) {\n tagEditButton.style.display = 'inline-block';\n document.getElementById('tag-mod-button').style.display = 'inline-block';\n }\n};\n'use strict';\n\nfunction archivedPosts() {\n return document.getElementsByClassName('story-archived');\n}\n\nfunction showArchivedPosts() {\n var posts = archivedPosts();\n\n for (var i = 0; i \u003c posts.length; i += 1) {\n posts[i].classList.remove('hidden');\n }\n}\n\nfunction hideArchivedPosts() {\n var posts = archivedPosts();\n\n for (var i = 0; i \u003c posts.length; i += 1) {\n posts[i].classList.add('hidden');\n }\n}\n\nfunction toggleArchivedPosts(e) {\n e.preventDefault();\n var link = e.target;\n\n if (link.innerHTML.match(/Show/)) {\n link.innerHTML = 'Hide archived';\n showArchivedPosts();\n } else {\n link.innerHTML = 'Show archived';\n hideArchivedPosts();\n }\n}\n\nfunction initializeArchivedPostFilter() {\n var link = document.getElementById('toggleArchivedLink');\n if (link) {\n link.addEventListener('click', toggleArchivedPosts);\n }\n};\n/* Show article date/time according to user's locale */\n/* global addLocalizedDateTimeToElementsTitles */\n\nfunction initializeArticleDate() {\n var articlesDates = document.querySelectorAll(\n '.crayons-story time, article time, .single-other-article time',\n );\n\n addLocalizedDateTimeToElementsTitles(articlesDates, 'datetime');\n};\n/* global sendHapticMessage, showLoginModal, showModalAfterError */\n\n// Set reaction count to correct number\nfunction setReactionCount(reactionName, newCount) {\n var reactionClassList = document.getElementById(\n 'reaction-butt-' + reactionName,\n ).classList;\n var reactionNumber = document.getElementById(\n 'reaction-number-' + reactionName,\n );\n if (newCount \u003e 0) {\n reactionClassList.add('activated');\n reactionNumber.textContent = newCount;\n } else {\n reactionClassList.remove('activated');\n reactionNumber.textContent = '0';\n }\n}\n\nfunction showUserReaction(reactionName, animatedClass) {\n const reactionButton = document.getElementById(\n 'reaction-butt-' + reactionName,\n );\n reactionButton.classList.add('user-activated', animatedClass);\n reactionButton.setAttribute('aria-pressed', 'true');\n}\n\nfunction hideUserReaction(reactionName) {\n const reactionButton = document.getElementById(\n 'reaction-butt-' + reactionName,\n );\n reactionButton.classList.remove('user-activated', 'user-animated');\n reactionButton.setAttribute('aria-pressed', 'false');\n}\n\nfunction hasUserReacted(reactionName) {\n return document\n .getElementById('reaction-butt-' + reactionName)\n .classList.contains('user-activated');\n}\n\nfunction getNumReactions(reactionName) {\n const reactionEl = document.getElementById('reaction-number-' + reactionName);\n if (!reactionEl || reactionEl.textContent === '') {\n return 0;\n }\n\n return parseInt(reactionEl.textContent, 10);\n}\n\nfunction reactToArticle(articleId, reaction) {\n // Visually toggle the reaction\n function toggleReaction() {\n var currentNum = getNumReactions(reaction);\n if (hasUserReacted(reaction)) {\n hideUserReaction(reaction);\n setReactionCount(reaction, currentNum - 1);\n } else {\n showUserReaction(reaction, 'user-animated');\n setReactionCount(reaction, currentNum + 1);\n }\n }\n var userStatus = document.body.getAttribute('data-user-status');\n sendHapticMessage('medium');\n if (userStatus === 'logged-out') {\n showLoginModal();\n return;\n }\n toggleReaction();\n document.getElementById('reaction-butt-' + reaction).disabled = true;\n\n function createFormdata() {\n /*\n * What's not shown here is that \"authenticity_token\" is included in this formData.\n * The logic can be seen in sendFetch.js.\n */\n var formData = new FormData();\n formData.append('reactable_type', 'Article');\n formData.append('reactable_id', articleId);\n formData.append('category', reaction);\n return formData;\n }\n\n getCsrfToken()\n .then(sendFetch('reaction-creation', createFormdata()))\n .then((response) =\u003e {\n if (response.status === 200) {\n return response.json().then(() =\u003e {\n document.getElementById('reaction-butt-' + reaction).disabled = false;\n });\n } else {\n toggleReaction();\n document.getElementById('reaction-butt-' + reaction).disabled = false;\n showModalAfterError({\n response,\n element: 'reaction',\n action_ing: 'updating',\n action_past: 'updated',\n });\n return undefined;\n }\n })\n .catch((error) =\u003e {\n toggleReaction();\n document.getElementById('reaction-butt-' + reaction).disabled = false;\n });\n}\n\nfunction setCollectionFunctionality() {\n if (document.getElementById('collection-link-inbetween')) {\n var inbetweenLinks = document.getElementsByClassName(\n 'series-switcher__link--inbetween',\n );\n var inbetweenLinksLength = inbetweenLinks.length;\n for (var i = 0; i \u003c inbetweenLinks.length; i += 1) {\n inbetweenLinks[i].onclick = (e) =\u003e {\n e.preventDefault();\n var els = document.getElementsByClassName(\n 'series-switcher__link--hidden',\n );\n var elsLength = els.length;\n for (var j = 0; j \u003c elsLength; j += 1) {\n els[0].classList.remove('series-switcher__link--hidden');\n }\n for (var k = 0; k \u003c inbetweenLinksLength; k += 1) {\n inbetweenLinks[0].className = 'series-switcher__link--hidden';\n }\n };\n }\n }\n}\n\nfunction requestReactionCounts(articleId) {\n var ajaxReq;\n if (window.XMLHttpRequest) {\n ajaxReq = new XMLHttpRequest();\n } else {\n ajaxReq = new ActiveXObject('Microsoft.XMLHTTP');\n }\n ajaxReq.onreadystatechange = () =\u003e {\n if (ajaxReq.readyState === XMLHttpRequest.DONE) {\n var json = JSON.parse(ajaxReq.response);\n json.article_reaction_counts.forEach((reaction) =\u003e {\n setReactionCount(reaction.category, reaction.count);\n });\n json.reactions.forEach((reaction) =\u003e {\n if (document.getElementById('reaction-butt-' + reaction.category)) {\n showUserReaction(reaction.category, 'not-user-animated');\n }\n });\n }\n };\n ajaxReq.open('GET', '/reactions?article_id=' + articleId, true);\n ajaxReq.send();\n}\n\nfunction initializeArticleReactions() {\n setCollectionFunctionality();\n\n setTimeout(() =\u003e {\n var reactionButts = document.getElementsByClassName('crayons-reaction');\n\n // we wait for the article to appear,\n // we also check that reaction buttons are there as draft articles don't have them\n if (document.getElementById('article-body') \u0026\u0026 reactionButts.length \u003e 0) {\n var articleId = document.getElementById('article-body').dataset.articleId;\n\n requestReactionCounts(articleId);\n\n for (var i = 0; i \u003c reactionButts.length; i += 1) {\n reactionButts[i].onclick = function addReactionOnClick(e) {\n reactToArticle(articleId, this.dataset.category);\n };\n }\n }\n }, 3);\n};\nfunction initializeBaseTracking() {\n var wait = 0;\n var addedGA = false;\n var gaTrackingCode = document.body.dataset.gaTracking;\n var waitingOnGA = setInterval(function() {\n if (!addedGA) {\n (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){\n (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),\n m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)\n })(window,document,'script','//www.google-analytics.com/analytics.js','ga');\n }\n addedGA = true;\n wait++;\n if (window.ga \u0026\u0026 ga.create) {\n ga('create', gaTrackingCode, 'auto');\n ga('set', 'anonymizeIp', true);\n ga('send', 'pageview', location.pathname + location.search);\n clearInterval(waitingOnGA);\n }\n if (wait \u003e 85) {\n clearInterval(waitingOnGA);\n fallbackActivityRecording();\n }\n }, 25);\n eventListening();\n trackCustomImpressions();\n}\n\nfunction fallbackActivityRecording() {\n var tokenMeta = document.querySelector(\"meta[name='csrf-token']\")\n if (!tokenMeta) {\n return\n }\n var csrfToken = tokenMeta.getAttribute('content')\n var w = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);\n var h = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);\n var screenW = window.screen.availWidth;\n var screenH = window.screen.availHeight;\n var dataBody = {\n path: location.pathname + location.search,\n user_language: navigator.language,\n referrer: document.referrer,\n user_agent: navigator.userAgent,\n viewport_size: h + 'x' + w,\n screen_resolution: screenH + 'x' + screenW,\n document_title: document.title,\n document_encoding: document.characterSet,\n document_path: location.pathname + location.search,\n };\n window.fetch('/fallback_activity_recorder', {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'X-CSRF-Token': csrfToken,\n },\n body: JSON.stringify(dataBody),\n credentials: 'same-origin'\n });\n}\n\nfunction eventListening(){\n var registerNowButt = document.getElementById(\"cta-comment-register-now-link\");\n if (registerNowButt) {\n registerNowButt.onclick = function(){\n ga('send', 'event', 'click', 'register-now-click', null, null);\n }\n }\n}\n\nfunction trackCustomImpressions() {\n setTimeout(function(){\n var ArticleElement = document.getElementById('article-body') || document.getElementById('comment-article-indicator');\n var tokenMeta = document.querySelector(\"meta[name='csrf-token']\")\n var isBot = /bot|google|baidu|bing|msn|duckduckbot|teoma|slurp|yandex/i.test(navigator.userAgent) // is crawler\n var windowBigEnough = window.innerWidth \u003e 1023\n\n // Sidebar HTML variant tracking\n var stickyNav = document.getElementById('article-show-primary-sticky-nav');\n var sidebarHTMLVariant = document.getElementById('html-variant-article-show-sidebar');\n if (sidebarHTMLVariant \u0026\u0026 ArticleElement \u0026\u0026 tokenMeta \u0026\u0026 !isBot \u0026\u0026 windowBigEnough) {\n var dataBody = {\n html_variant_id: sidebarHTMLVariant.dataset.variantId,\n article_id: ArticleElement.dataset.articleId,\n };\n var csrfToken = tokenMeta.getAttribute('content');\n trackHTMLVariantTrial(dataBody, csrfToken)\n var successLinks = stickyNav.querySelectorAll('a,button'); //track all links and button clicks within nav\n for(var i = 0; i \u003c successLinks.length; i++)\n {\n successLinks[i].addEventListener('click', function() { trackHtmlVariantSuccess(dataBody, csrfToken) });\n }\n }\n\n // Below article HTML variant tracking\n var belowArticleHTMLVariant = document.getElementById('html-variant-article-show-below-article');\n if (belowArticleHTMLVariant \u0026\u0026 ArticleElement \u0026\u0026 tokenMeta \u0026\u0026 !isBot \u0026\u0026 windowBigEnough) {\n var dataBody = {\n html_variant_id: belowArticleHTMLVariant.dataset.variantId,\n article_id: ArticleElement.dataset.articleId,\n };\n var csrfToken = tokenMeta.getAttribute('content');\n trackHTMLVariantTrial(dataBody, csrfToken)\n var successLinks = belowArticleHTMLVariant.querySelectorAll('a,button'); //track all links and button clicks within nav\n for(var i = 0; i \u003c successLinks.length; i++)\n {\n successLinks[i].addEventListener('click', function() { trackHtmlVariantSuccess(dataBody, csrfToken) });\n }\n }\n\n // page view\n if (ArticleElement \u0026\u0026 tokenMeta \u0026\u0026 !isBot) {\n var randomNumber = Math.floor(Math.random() * 10); // 1 in 10; Only track 1 in 10 impressions\n if (!checkUserLoggedIn() \u0026\u0026 randomNumber != 1) {\n return;\n }\n var dataBody = {\n article_id: ArticleElement.dataset.articleId,\n referrer: document.referrer,\n user_agent: navigator.userAgent,\n };\n var csrfToken = tokenMeta.getAttribute('content');\n trackPageView(dataBody, csrfToken);\n var timeOnSiteCounter = 0;\n var timeOnSiteInterval = setInterval(function(){\n timeOnSiteCounter++\n var ArticleElement = document.getElementById('article-body') || document.getElementById('comment-article-indicator');\n if (ArticleElement \u0026\u0026 checkUserLoggedIn()) {\n trackFifteenSecondsOnPage(ArticleElement.dataset.articleId, csrfToken);\n } else {\n clearInterval(timeOnSiteInterval);\n }\n if ( timeOnSiteCounter \u003e 118 ) {\n clearInterval(timeOnSiteInterval);\n }\n }, 15000)\n }\n\n // display add\n var displayAds = document.querySelectorAll('[data-display-unit]');\n if (displayAds.length \u003e 0\n \u0026\u0026 tokenMeta\n \u0026\u0026 !isBot\n \u0026\u0026 windowBigEnough\n \u0026\u0026 checkUserLoggedIn()) {\n var csrfToken = tokenMeta.getAttribute('content');\n displayAds.forEach(unit =\u003e {\n trackAdImpression(csrfToken, unit);\n unit.removeEventListener('click', trackAdClick, false );\n unit.addEventListener('click', function(e) { trackAdClick(csrfToken, e.target) });\n });\n }\n }, 1800)\n}\n\nfunction trackHTMLVariantTrial(dataBody, csrfToken) {\n var randomNumber = Math.floor(Math.random() * 10); // 1 in 10; Only track 1 in 10 impressions\n if (randomNumber === 1) {\n window.fetch('/html_variant_trials', {\n method: 'POST',\n headers: {\n 'X-CSRF-Token': csrfToken,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(dataBody),\n credentials: 'same-origin',\n });\n }\n}\n\nfunction trackHtmlVariantSuccess(dataBody, csrfToken) {\n window.fetch('/html_variant_successes', {\n method: 'POST',\n headers: {\n 'X-CSRF-Token': csrfToken,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(dataBody),\n credentials: 'same-origin',\n })\n}\n\nfunction trackPageView(dataBody, csrfToken) {\n window.fetch('/page_views', {\n method: 'POST',\n headers: {\n 'X-CSRF-Token': csrfToken,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(dataBody),\n credentials: 'same-origin',\n })\n}\n\nfunction trackFifteenSecondsOnPage(articleId, csrfToken) {\n window.fetch('/page_views/' + articleId, {\n method: 'PATCH',\n headers: {\n 'X-CSRF-Token': csrfToken,\n 'Content-Type': 'application/json',\n },\n credentials: 'same-origin',\n })\n}\n\nfunction trackAdImpression(token, adBox) {\n var dataBody = {\n display_ad_event: {\n display_ad_id: adBox.dataset.id,\n context_type: \"home\",\n category: \"impression\",\n }\n }\n window.fetch('/display_ad_events', {\n method: 'POST',\n headers: {\n 'X-CSRF-Token': token,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(dataBody),\n credentials: 'same-origin',\n })\n}\n\nfunction trackAdClick(token, clickedElement) {\n var adBox = clickedElement.closest('[data-display-unit]');\n if (!adClicked) {\n var dataBody = {\n display_ad_event: {\n display_ad_id: adBox.dataset.id,\n context_type: \"home\",\n category: \"click\",\n }\n }\n window.fetch('/display_ad_events', {\n method: 'POST',\n headers: {\n 'X-CSRF-Token': token,\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify(dataBody),\n credentials: 'same-origin',\n })\n }\n adClicked = true;\n};\n/* global filterXSS */\nfunction initializeProfileImage(user) {\n if (!document.getElementById('comment-primary-user-profile--avatar')) return;\n document.getElementById('comment-primary-user-profile--avatar').src =\n user.profile_image_90;\n}\n\nfunction addRelevantButtonsToArticle(user) {\n var articleContainer = document.getElementById('article-show-container');\n\n if (\n articleContainer \u0026\u0026\n articleContainer.dataset.buttonsInitialized !== 'true'\n ) {\n let actions = [];\n const published = JSON.parse(articleContainer.dataset.published);\n\n if (parseInt(articleContainer.dataset.authorId, 10) === user.id) {\n actions.push(\n `\u003ca class=\"crayons-btn crayons-btn--s crayons-btn--ghost px-2\" href=\"${articleContainer.dataset.path}/edit\" rel=\"nofollow\"\u003eEdit\u003c/a\u003e`,\n );\n\n let clickToEditButton = document.getElementById('author-click-to-edit');\n if (clickToEditButton) {\n clickToEditButton.style.display = 'inline-block';\n }\n\n if (published === true) {\n actions.push(\n `\u003ca class=\"crayons-btn crayons-btn--s crayons-btn--ghost px-2\" href=\"${articleContainer.dataset.path}/manage\" rel=\"nofollow\"\u003eManage\u003c/a\u003e`,\n );\n }\n\n actions.push(\n `\u003ca class=\"crayons-btn crayons-btn--s crayons-btn--ghost px-2\" href=\"${articleContainer.dataset.path}/stats\" rel=\"nofollow\"\u003eStats\u003c/a\u003e`,\n );\n }\n\n const { articleId, pinnedArticleId } = articleContainer.dataset;\n\n // we hide the buttons for draft articles, for non admins and\n // if there's already a pinned post different from the current one\n if (user.admin) {\n actions.push(\n `\u003ca class=\"crayons-btn crayons-btn--s crayons-btn--ghost px-2\" href=\"/admin/content_manager/articles/${articleId}\" data-no-instant\u003eAdmin\u003c/a\u003e`,\n );\n }\n\n document.getElementById('action-space').innerHTML = actions.join('');\n articleContainer.dataset.buttonsInitialized = 'true';\n }\n}\n\nfunction addRelevantButtonsToComments(user) {\n if (document.getElementById('comments-container')) {\n // buttons are actually \u003cspan\u003e's\n var settingsButts = document.getElementsByClassName('comment-actions');\n\n for (let i = 0; i \u003c settingsButts.length; i += 1) {\n let butt = settingsButts[i];\n const { action, commentableUserId, userId } = butt.dataset;\n if (parseInt(userId, 10) === user.id \u0026\u0026 action === 'settings-button') {\n butt.innerHTML =\n '\u003ca href=\"' +\n butt.dataset.path +\n '\" rel=\"nofollow\" class=\"crayons-link crayons-link--block\" data-no-instant\u003eSettings\u003c/a\u003e';\n butt.classList.remove('hidden');\n butt.classList.add('block');\n }\n\n if (\n action === 'hide-button' \u0026\u0026\n parseInt(commentableUserId, 10) === user.id\n ) {\n butt.classList.remove('hidden');\n butt.classList.add('block');\n }\n }\n\n if (user.trusted) {\n var modButts = document.getElementsByClassName('mod-actions');\n for (let i = 0; i \u003c modButts.length; i += 1) {\n let butt = modButts[i];\n if (butt.classList.contains('mod-actions-comment-button')) {\n butt.innerHTML =\n '\u003ca href=\"' +\n butt.dataset.path +\n '\" rel=\"nofollow\" class=\"crayons-link crayons-link--block\"\u003eModerate\u003c/a\u003e';\n }\n butt.className = 'mod-actions';\n butt.classList.remove('hidden');\n butt.classList.add('block');\n }\n }\n }\n}\n\nfunction setCurrentUserToNavBar(user) {\n const userNavLink = document.getElementById('first-nav-link');\n userNavLink.href = `/${user.username}`;\n userNavLink.getElementsByTagName('span')[0].textContent = user.name;\n userNavLink.getElementsByTagName(\n 'small',\n )[0].textContent = `@${user.username}`;\n document.getElementById('nav-profile-image').src = user.profile_image_90;\n if (user.admin) {\n document\n .getElementsByClassName('js-header-menu-admin-link')[0]\n .classList.remove('hidden');\n }\n}\n\nfunction initializeBaseUserData() {\n const user = userData();\n setCurrentUserToNavBar(user);\n initializeProfileImage(user);\n addRelevantButtonsToArticle(user);\n addRelevantButtonsToComments(user);\n};\n/* global checkUserLoggedIn */\n\nfunction removeExistingCSRF() {\n var csrfTokenMeta = document.querySelector(\"meta[name='csrf-token']\");\n var csrfParamMeta = document.querySelector(\"meta[name='csrf-param']\");\n if (csrfTokenMeta \u0026\u0026 csrfParamMeta) {\n csrfTokenMeta.parentNode.removeChild(csrfTokenMeta);\n csrfParamMeta.parentNode.removeChild(csrfParamMeta);\n }\n}\n\nfunction fetchBaseData() {\n var xmlhttp;\n if (window.XMLHttpRequest) {\n xmlhttp = new XMLHttpRequest();\n } else {\n xmlhttp = new ActiveXObject('Microsoft.XMLHTTP');\n }\n xmlhttp.onreadystatechange = () =\u003e {\n if (xmlhttp.readyState === XMLHttpRequest.DONE) {\n // Assigning CSRF\n var json = JSON.parse(xmlhttp.responseText);\n if (json.token) {\n removeExistingCSRF();\n }\n var newCsrfParamMeta = document.createElement('meta');\n newCsrfParamMeta.name = 'csrf-param';\n newCsrfParamMeta.content = json.param;\n document.head.appendChild(newCsrfParamMeta);\n var newCsrfTokenMeta = document.createElement('meta');\n newCsrfTokenMeta.name = 'csrf-token';\n newCsrfTokenMeta.content = json.token;\n document.head.appendChild(newCsrfTokenMeta);\n document.body.dataset.loaded = 'true';\n\n // Assigning Broadcast\n if (json.broadcast) {\n document.body.dataset.broadcast = json.broadcast;\n }\n\n // Assigning User\n if (checkUserLoggedIn()) {\n document.body.dataset.user = json.user;\n document.body.dataset.creator = json.creator;\n document.body.dataset.creatorOnboarding = json.creator_onboarding;\n browserStoreCache('set', json.user);\n\n setTimeout(() =\u003e {\n if (typeof ga === 'function') {\n ga('set', 'userId', JSON.parse(json.user).id);\n }\n }, 400);\n } else {\n // Ensure user data is not exposed if no one is logged in\n delete document.body.dataset.user;\n delete document.body.dataset.creator;\n delete document.body.dataset.creatorOnboarding;\n browserStoreCache('remove');\n }\n }\n };\n\n xmlhttp.open('GET', '/async_info/base_data', true);\n xmlhttp.send();\n}\n\nfunction initializeBodyData() {\n fetchBaseData();\n};\n/* eslint-disable camelcase */\n/**\n * Parses the broadcast object on the document into JSON.\n *\n * @function broadcastData\n * @returns {Object} Returns an object of the parsed broadcast data.\n */\nfunction broadcastData() {\n const { broadcast = null } = document.body.dataset;\n\n return JSON.parse(broadcast);\n}\n\n/**\n * Parses the broadcast object on the document into JSON.\n *\n * @function camelizedBroadcastKey\n * @param {string} title The title of the broadcast.\n * @returns {string} Returns the camelized title appended with \"Seen\".\n */\nfunction camelizedBroadcastKey(title) {\n const camelizedTitle = title.replace(/\\W+(.)/g, (match, string) =\u003e {\n return string.toUpperCase();\n });\n\n return `${camelizedTitle}Seen`;\n}\n\n/**\n * A function that finds the close button and adds a click handler to it.\n * The click handler sets a key in local storage and removes the broadcast\n * element entirely from the DOM.\n *\n * @function addCloseButtonClickHandle\n * @param {string} title The title of the broadcast.\n */\nfunction addCloseButtonClickHandle(title) {\n var closeButton = document.getElementsByClassName(\n 'close-announcement-button',\n )[0];\n closeButton.onclick = (e) =\u003e {\n localStorage.setItem(camelizedBroadcastKey(title), true);\n document.getElementById('active-broadcast').remove();\n };\n}\n\n/**\n * A function to insert the broadcast's HTML into the `active-broadcast` element.\n * Determines what classes to add to the broadcast element,\n * and inserts a close button and adds a click handler to it.\n *\n * Adds a `.broadcast-visible` class to the broadcastElement to make it display.\n *\n * @function initializeBroadcast\n * @param {string} broadcastElement The HTML element for the broadcast, with a class of `.active-broadcast`.\n * @param {Object} data An object representing the parsed broadcast data.\n */\nfunction renderBroadcast(broadcastElement, data) {\n const { banner_class, html, title } = data;\n\n if (banner_class) {\n const [defaultClass, additionalClass] = banner_class.split(' ');\n if (additionalClass) {\n broadcastElement.classList.add(defaultClass, additionalClass);\n } else {\n broadcastElement.classList.add(defaultClass);\n }\n }\n\n const closeButton = `\u003cbutton class=\"close-announcement-button crayons-btn crayons-btn--icon-rounded crayons-btn--inverted crayons-btn--ghost\"\u003e\n \u003csvg class=\"crayons-icon\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003cpath d=\"M12 10.586l4.95-4.95 1.414 1.414-4.95 4.95 4.95 4.95-1.414 1.414-4.95-4.95-4.95 4.95-1.414-1.414 4.95-4.95-4.95-4.95L7.05 5.636l4.95 4.95z\" /\u003e\u003c/svg\u003e\n \u003c/button\u003e`;\n\n broadcastElement.insertAdjacentHTML(\n 'afterbegin',\n `\u003cdiv class='broadcast-data'\u003e${html}\u003c/div\u003e${closeButton}`,\n );\n addCloseButtonClickHandle(title);\n broadcastElement.classList.add('broadcast-visible');\n}\n\n/**\n * A function to determine if a broadcast should render.\n * Does not render a broadcast in an iframe, or on `/connect` and `/new` routes.\n * Does not render a broadcast if the current user has opted-out,\n * if the broadcast has already been inserted, or if the key for\n * the broadcast's title exists in localStorage.\n *\n * @function initializeBroadcast\n */\nfunction initializeBroadcast() {\n const shouldHideBroadcast = window.location.pathname.match(\n /^(?:\\/connect|\\/new)/,\n );\n\n // Iframes will attempt to re-render a broadcast, so we want to explicitly\n // avoid initializing one if we are within `window.frameElement`.\n if (window.frameElement || shouldHideBroadcast) {\n const broadcast = document.getElementById('active-broadcast');\n\n // Hide the broadcast if it exists and we are on a path where it should be hidden.\n if (broadcast) {\n broadcast.classList.remove('broadcast-visible');\n }\n return;\n }\n\n const user = userData();\n const data = broadcastData();\n\n if (user \u0026\u0026 !user.display_announcements) {\n return;\n }\n if (!data) {\n return;\n }\n\n const { title } = data;\n if (JSON.parse(localStorage.getItem(camelizedBroadcastKey(title))) === true) {\n return; // Do not render broadcast if previously dismissed by user.\n }\n\n const el = document.getElementById('active-broadcast');\n if (el.firstElementChild) {\n if (!el.classList.contains('broadcast-visible')) {\n // The articleForm may have hidden the broadcast when\n // it loaded, so we need to explicitly display it again.\n el.classList.toggle('broadcast-visible');\n }\n\n return; // Only append HTML once, on first render.\n }\n\n renderBroadcast(el, data);\n}\n/* eslint-enable camelcase */;\n'use strict';\n\nfunction initializeColorPicker() {\n var pickers = Array.from(document.getElementsByClassName('js-color-field'));\n\n function colorValueChange(e) {\n var field = e.target;\n var sibling = '';\n if (field.nextElementSibling) {\n sibling = field.nextElementSibling;\n } else {\n sibling = field.previousElementSibling;\n }\n\n sibling.value = field.value;\n }\n\n pickers.forEach(function (picker) {\n picker.addEventListener('change', colorValueChange);\n });\n};\n/* Show comment date/time according to user's locale */\n/* global addLocalizedDateTimeToElementsTitles */\n\n'use strict';\n\nfunction initializeCommentDate() {\n var commentsDates = document.querySelectorAll('.comment-date time');\n\n addLocalizedDateTimeToElementsTitles(commentsDates, 'datetime');\n};\n/* global activateRunkitTags */\n\nfunction getAndShowPreview(preview, editor) {\n function attachTwitterTimelineScript() {\n const script = document.createElement('script');\n script.src = 'https://platform.twitter.com/widgets.js';\n script.async = true;\n document.body.appendChild(script);\n return () =\u003e {\n document.body.removeChild(script);\n };\n }\n\n function successCb(body) {\n preview.innerHTML = body.processed_html; // eslint-disable-line no-param-reassign\n if (body.processed_html.includes('twitter-timeline')) {\n attachTwitterTimelineScript();\n }\n activateRunkitTags();\n }\n\n const payload = JSON.stringify({\n comment: {\n body_markdown: editor.value,\n },\n });\n getCsrfToken()\n .then(sendFetch('comment-preview', payload))\n .then((response) =\u003e {\n return response.json();\n })\n .then(successCb)\n .catch((err) =\u003e {\n console.log('error!'); // eslint-disable-line\n console.log(err); // eslint-disable-line no-console\n });\n}\n\nfunction handleCommentPreview(event) {\n event.preventDefault();\n const { form } = event.target;\n const editor = form.getElementsByClassName('comment-textarea')[0];\n const preview = form.getElementsByClassName('comment-form__preview')[0];\n const trigger = form.getElementsByClassName('preview-toggle')[0];\n\n if (editor.value !== '') {\n if (form.classList.contains('preview-open')) {\n form.classList.toggle('preview-open');\n trigger.innerHTML = 'Preview';\n } else {\n getAndShowPreview(preview, editor);\n const editorHeight = editor.offsetHeight + 43; // not ideal but prevents jumping screen\n preview.style.minHeight = `${editorHeight}px`;\n trigger.innerHTML = 'Continue editing';\n form.classList.toggle('preview-open');\n }\n }\n}\n\nfunction initializeCommentPreview() {\n const previewButton = document.getElementsByClassName('preview-toggle')[0];\n\n if (!previewButton) {\n return;\n }\n\n previewButton.addEventListener('click', handleCommentPreview);\n};\nvar iconSmallThread = `\u003csvg width=\"24\" height=\"24\" class=\"crayons-icon\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003cpath d=\"M17 13l-5 6-5-6h3.125c0-3.314 2.798-6 6.25-6 .17 0 .34.006.506.02-1.787.904-3.006 2.705-3.006 4.78V13H17z\" /\u003e\u003c/svg\u003e`;\n\n/**\n *\n * A function that triggers all the interactivity when a page with comments are loaded.\n * It calls sub-functions to define functionality for fetching async info, and attaching\n * event listeners related to rich UI interaction and form submission.\n *\n * When comment reaction data needs to be fetched and how we make those choices:\n * When no logged in user only need to fetch reaction numbers if there has been recent comment activity.\n * If no recent comments, we do not need the precision of fetching latest counts async. Static value is almost certainly good enough.\n * Always fetch when user is logged in because we need state of whether the user has reacted.\n *\n * @function initializeCommentsPage\n */\n\nfunction initializeCommentsPage() {\n if (document.getElementById('comments-container')) {\n toggleCodeOfConduct();\n var userStatus = document.body.getAttribute('data-user-status');\n var commentableId = document.getElementById('comments-container').dataset.commentableId;\n var commentableType = document.getElementById('comments-container').dataset.commentableType;\n var hasRecentCommentActivity = document.getElementById('comments-container').dataset.hasRecentCommentActivity;\n commentableIdList = commentableId.split(\",\");\n\n if (userStatus === 'logged-in' || hasRecentCommentActivity !== 'false') {\n var f = (function() {\n for (var i = 0; i \u003c commentableIdList.length; i++) {\n (function(i){\n var ajaxReq;\n if (window.XMLHttpRequest) {\n ajaxReq = new XMLHttpRequest();\n } else {\n ajaxReq = new ActiveXObject('Microsoft.XMLHTTP');\n }\n ajaxReq.onreadystatechange = function () {\n if (ajaxReq.readyState === XMLHttpRequest.DONE) {\n var responseObj = JSON.parse(ajaxReq.response);\n var reactions = responseObj.reactions;\n var allNodes = document.getElementsByClassName('single-comment-node');\n var publicReactionCounts = responseObj.public_reaction_counts;\n for (var i = 0; i \u003c reactions.length; i++) {\n var buttForComment = document.getElementById('button-for-comment-' + reactions[i].reactable_id);\n if (buttForComment) {\n buttForComment.classList.add('reacted');\n buttForComment.setAttribute('aria-pressed', 'true')\n }\n }\n for (var i = 0; i \u003c publicReactionCounts.length; i++) {\n var buttForComment = document.getElementById('button-for-comment-' + publicReactionCounts[i].id);\n if (buttForComment) {\n var reactionsCountWrapper = buttForComment.querySelector('.reactions-count');\n var reactionsLabelWrapper = buttForComment.querySelector('.reactions-label');\n if (publicReactionCounts[i].count \u003e 0) {\n\n if (publicReactionCounts[i].count \u003e 1) {\n reactionsLabelWrapper.innerHTML = `\u0026nbsp;${I18n.t('core.like').toLowerCase()}s`;\n } else {\n reactionsLabelWrapper.innerHTML = `\u0026nbsp;${I18n.t('core.like').toLowerCase()}`;\n }\n\n reactionsCountWrapper.id = 'reactions-count-' + publicReactionCounts[i].id;\n reactionsCountWrapper.innerHTML = publicReactionCounts[i].count;\n reactionsCountWrapper.classList.remove(\"hidden\");\n } else {\n reactionsCountWrapper.classList.add(\"hidden\");\n reactionsCountWrapper.innerHTML = '0';\n }\n\n if (!buttForComment.classList.contains(\"reacted\")) {\n buttForComment.setAttribute('aria-pressed', 'false')\n }\n }\n }\n\n for (var i = 0; i \u003c allNodes.length; i++) {\n if (allNodes[i].dataset.commentAuthorId == responseObj.current_user.id) {\n allNodes[i].dataset.currentUserComment = \"true\";\n var path = allNodes[i].dataset.path;\n var userActionsEl = allNodes[i].querySelector('.current-user-actions');\n var buttEl = document.getElementById('button-for-comment-' + allNodes[i].dataset.commentId);\n if (userActionsEl \u0026\u0026 buttEl) {\n userActionsEl.innerHTML = `\u003cli\u003e\u003ca href=\"${ path }/edit\" class=\"crayons-link crayons-link--block\" aria-label=\"Edit this comment\"\u003eEdit\u003c/a\u003e\u003c/li\u003e\n \u003cli\u003e\u003ca data-no-instant href=\"${ path }/delete_confirm\" class=\"edit-butt crayons-link crayons-link--block\" aria-label=\"Delete this comment\"\u003eDelete\u003c/a\u003e\u003c/li\u003e`\n userActionsEl.classList.remove('hidden');\n }\n }\n }\n }\n };\n\n ajaxReq.open(\"GET\", \"/reactions?commentable_id=\" + commentableIdList[i] + \"\u0026commentable_type=\" + commentableType, true);\n ajaxReq.send();\n })(i);\n }\n })();\n }\n\n var butts = document.getElementsByClassName('reaction-button');\n for (var i = 0; i \u003c butts.length; i++) {\n var butt = butts[i];\n butt.onclick = function (event) {\n var thisButt = this;\n event.preventDefault();\n sendHapticMessage('medium');\n var userStatus = document.body.getAttribute('data-user-status');\n if (userStatus === 'logged-out') {\n showLoginModal();\n return;\n }\n\n thisButt.classList.add('reacted');\n thisButt.disabled = true;\n\n function successCb(response) {\n var reactionCount = thisButt.querySelector('.reactions-count');\n var reactionLabel = thisButt.querySelector('.reactions-label');\n if (response.result === 'create') {\n thisButt.classList.add('reacted');\n thisButt.setAttribute('aria-pressed', 'true');\n if (reactionCount) {\n reactionCount.innerHTML = parseInt(reactionCount.innerHTML) + 1;\n reactionCount.classList.remove(\"hidden\");\n if(parseInt(reactionCount.innerHTML) == 1) {\n reactionLabel.innerHTML = \"\u0026nbsp;like\"\n } else if(parseInt(reactionCount.innerHTML) \u003e 1) {\n reactionLabel.innerHTML = \"\u0026nbsp;likes\"\n }\n }\n } else {\n thisButt.classList.remove('reacted');\n thisButt.setAttribute('aria-pressed', 'false');\n if (reactionCount) {\n reactionCount.innerHTML = parseInt(reactionCount.innerHTML) - 1;\n if(parseInt(reactionCount.innerHTML) == 0) {\n reactionCount.classList.add(\"hidden\");\n reactionLabel.innerHTML = \"Like\"\n }\n }\n }\n }\n var formData = new FormData();\n formData.append('reactable_type', 'Comment');\n formData.append('reactable_id', thisButt.dataset.commentId);\n getCsrfToken()\n .then(sendFetch('reaction-creation', formData))\n .then(function (response) {\n thisButt.disabled = false;\n if (response.status === 200) {\n response.json().then(successCb);\n } else {\n showModalAfterError({\n response,\n element: 'reaction',\n action_ing: 'making',\n action_past: 'made',\n });\n }\n });\n };\n }\n var replyButts = document.getElementsByClassName('toggle-reply-form');\n for (var i = 0; i \u003c replyButts.length; i++) {\n var butt = replyButts[i];\n butt.onclick = function (event) {\n event.preventDefault();\n if (event.target.classList.contains(\"thread-indication\")) {\n return false;\n } else {\n var userStatus = document.body.getAttribute('data-user-status');\n if (userStatus == 'logged-out') {\n showLoginModal();\n return;\n }\n var parentId = event.target.closest('.comment').dataset.commentId;\n var waitingOnCSRF = setInterval(function () {\n var metaTag = document.querySelector(\"meta[name='csrf-token']\");\n if (metaTag) {\n clearInterval(waitingOnCSRF);\n commentWrapper = event.target.closest('.comment__details');\n commentWrapper.classList.add(\"replying\");\n commentWrapper.innerHTML += buildCommentFormHTML(commentableId, commentableType, parentId);\n initializeCommentsPage();\n\n setTimeout(function () {\n commentWrapper.getElementsByTagName('textarea')[0].focus();\n }, 30);\n }\n }, 1);\n };\n return false;\n }\n }\n\n if (document.getElementById('new_comment')) {\n document.getElementById('new_comment').addEventListener('submit', handleCommentSubmit);\n }\n }\n listenForDetailsToggle();\n\n handleHiddenComments(commentableType);\n}\n\nfunction toggleCodeOfConduct() {\n var user = userData();\n if (!user) {\n return;\n }\n var codeOfConduct = user.checked_code_of_conduct\n var checkboxWrapper = document.getElementById('toggle-code-of-conduct-checkbox');\n if (checkboxWrapper \u0026\u0026 !codeOfConduct) {\n checkboxWrapper.innerHTML = '\u003cinput type=\"checkbox\" name=\"checked_code_of_conduct\" class=\"checkbox\" required/\u003e\\\n \u003clabel for=\"checked_code_of_conduct\"\u003eI\\'ve read the \u003ca href=\"/code-of-conduct\"\u003ecode of conduct\u003c/a\u003e\u003c/label\u003e'\n }\n}\n\nfunction handleCommentSubmit(event) {\n event.preventDefault();\n var form = event.target;\n form.classList.add('submitting');\n var textarea = form.getElementsByClassName('comment-textarea')[0];\n if (textarea) {\n textarea.style.height = null;\n textarea.blur();\n }\n var parentComment = document.getElementById(\"comment-node-\" + event.target.dataset.commentId);\n\n // as there can be multiple forms rendered in the comments, we need to use querySelector to find descendants\n var commentParentId = form.querySelector(\"#comment_parent_id\");\n var body = JSON.stringify({\n comment: {\n body_markdown: form.getElementsByTagName(\"textarea\")[0].value,\n commentable_id: form.querySelector(\"#comment_commentable_id\").value,\n commentable_type: form.querySelector(\"#comment_commentable_type\").value,\n parent_id: commentParentId ? commentParentId.value : null,\n }\n });\n\n getCsrfToken()\n .then(sendFetch('comment-creation', body))\n .then(function (response) {\n if (response.status === 200) {\n response.json().then(function (newComment) {\n var newNode = document.createElement('div');\n newNode.innerHTML = buildCommentHTML(newComment);\n var docBody = document.body\n\n var userData = JSON.parse(docBody.getAttribute('data-user'))\n userData.checked_code_of_conduct = true;\n\n docBody.dataset.user = JSON.stringify(userData);\n\n var checkbox = form.getElementsByClassName('code-of-conduct')[0]\n if (checkbox) {\n checkbox.innerHTML = \"\"\n }\n\n var mainCommentsForm = document.getElementById(\"new_comment\");\n if (parentComment) {\n handleFormClose(event);\n if (newComment.depth \u003e 3) {\n var replyTrigger = parentComment.getElementsByClassName(\"toggle-reply-form\")[0];\n var threadIndicator = `\u003cspan class=\"fs-s inline-flex items-center fs-italic color-base-50 pl-1\"\u003e${ iconSmallThread }Thread\u003c/span\u003e`;\n replyTrigger.classList.replace(\"inline-flex\", \"hidden\");\n replyTrigger.parentNode.innerHTML += threadIndicator;\n }\n var actionsNode = parentComment.getElementsByClassName(\"comment__inner\")[0];\n actionsNode.parentNode.insertBefore(newNode, actionsNode.nextSibling);\n }\n\n else if (mainCommentsForm) {\n var mainCommentsForm = document.getElementById(\"new_comment\");\n mainCommentsForm.classList.remove(\"submitting\");\n mainCommentsForm.classList.remove('preview-open');\n\n const commentInputs = [...form.getElementsByClassName(\"comment-textarea\")]\n commentInputs[0].closest('.comment-form').classList.remove('comment-form--initiated');\n\n // Clearing out all comment textboxes and resetting their height because\n // there is an additional one generated by the comment\n // mention auto-complete component\n commentInputs.forEach(input =\u003e {\n input.value = newComment.comment_template || \"\";\n input.style.height = null;\n });\n\n const preview = document.getElementById(\"preview-div\");\n const togglePreview = document.querySelector('.preview-toggle');\n preview.innerHTML = \"\";\n togglePreview.innerHTML = \"Preview\";\n const container = document.getElementById(\"comment-trees-container\");\n container.insertBefore(newNode, container.firstChild);\n }\n else if (document.getElementById(\"notifications-container\")) {\n var newDiv = document.createElement(\"span\")\n newDiv.innerHTML = '\u003cdiv class=\"crayons-notice align-center p-2 m-2 crayons-notice--success reply-sent-notice reply-sent-notice\" aria-live=\"polite\"\u003eReply sent — \u003ca href=\"' + newComment.url + '\"\u003eCheck it out\u003c/a\u003e\u003c/div\u003e'\n form.replaceWith(newDiv);\n }\n else {\n window.location.replace(newComment.url)\n }\n updateCommentsCount();\n initializeCommentsPage();\n initializeCommentDate();\n activateRunkitTags();\n })\n } else {\n form.classList.remove('submitting');\n showModalAfterError({\n response,\n element: 'comment',\n action_ing: 'posting',\n action_past: 'posted',\n });\n return false;\n }\n return false;\n });\n return false;\n}\n\nfunction handleFocus(event) {\n handleButtonsActivation(event);\n var userStatus = document.body.getAttribute('data-user-status');\n var area = event.target;\n if (userStatus == 'logged-out') {\n event.preventDefault();\n showLoginModal();\n area.blur();\n } else {\n var form = event.target.closest(\".comment-form\");\n if (form) {\n form.classList.add(\"comment-form--initiated\");\n }\n handleSizeChange(event);\n window.Forem.initializeMentionAutocompleteTextArea(area);\n }\n}\n\nfunction handleKeyUp(event) {\n handleSizeChange(event);\n handleButtonsActivation(event);\n}\n\n// Handler for when Ctrl+Enter OR Command+Enter is pressed\nfunction handleSubmit(event) {\n // Get user details and extract code of conduct \u0026 comment count\n var user = userData();\n if (!user) {\n return;\n }\n\n var codeOfConduct = user.checked_code_of_conduct;\n if (codeOfConduct \u0026\u0026 event.target.value.trim() !== '') {\n event.target.closest('form').querySelector('button[type=\"submit\"]').click();\n }\n}\n\n// Handler when Ctrl+B/I OR Command+B/I is pressed\nfunction handleBoldAndItalic(event) {\n var textArea = event.target;\n\n var selection = textArea.value.substring(textArea.selectionStart, textArea.selectionEnd);\n var selectionStart = textArea.selectionStart;\n var surroundingStr = event.keyCode === KEY_CODE_B ? \"**\" : \"_\";\n\n replaceSelectedText(textArea, `${surroundingStr}${selection}${surroundingStr}`);\n\n var selectionStartWithOffset = selectionStart + surroundingStr.length;\n textArea.setSelectionRange(selectionStartWithOffset, selectionStartWithOffset + selection.length);\n}\n\n// Handler when Ctrl+K OR Command+K is pressed\nfunction handleLink(event) {\n var textArea = event.target;\n\n var selection = textArea.value.substring(textArea.selectionStart, textArea.selectionEnd);\n var selectionStart = textArea.selectionStart;\n\n replaceSelectedText(textArea, `[${selection}](url)`);\n\n // start position + length of selection + [](\n var startOffset = selectionStart + selection.length + 3;\n\n // start offset + 'url'.length\n var endOffset = startOffset + 3;\n\n textArea.setSelectionRange(startOffset, endOffset);\n}\n\nfunction replaceSelectedText(textArea, text) {\n // Chrome and other modern browsers (except FF and IE 8,9,10,11)\n if (document.execCommand('insertText', false, text)) {\n }\n // Firefox (non-standard method)\n else if (typeof textArea.setRangeText === \"function\") {\n textArea.setRangeText(text);\n }\n\n /*\n Disabling IE 8-11 for now as there's no easy way to verify all this\n We can revisit this if it's really needed and find a jQuery plugin to use\n\n // IE 8-10\n else if(document.selection) {\n const ieRange = document.selection.createRange();\n ieRange.text = text;\n\n // Move cursor after the inserted text\n ieRange.collapse(false); // to the end\n ieRange.select();\n }\n else {\n // Does not support IE 11 yet\n }\n */\n}\n\nvar KEY_CODE_B = 66;\nvar KEY_CODE_I = 73;\nvar KEY_CODE_K = 75;\nvar ENTER_KEY_CODE = 13;\n\nfunction handleKeyDown(event) {\n if (Runtime.hasOSSpecificModifier(event)) {\n switch (event.keyCode) {\n case KEY_CODE_B:\n event.preventDefault();\n handleBoldAndItalic(event);\n break;\n case KEY_CODE_I:\n event.preventDefault();\n handleBoldAndItalic(event);\n break;\n case KEY_CODE_K:\n event.preventDefault();\n handleLink(event);\n break;\n case ENTER_KEY_CODE:\n event.preventDefault();\n handleSubmit(event);\n break;\n default:\n break;\n }\n }\n}\n\nfunction handleFormClose(event) {\n event.target.closest('.inner-comment').classList.remove(\"replying\");\n event.target.closest('.comment-form').remove();\n initializeCommentsPage();\n}\n\nfunction handleSizeChange(event) {\n var textarea = event.target;\n var oldHeight = parseInt(textarea.style.height.replace('px',''));\n textarea.style.height = textarea.scrollHeight + (textarea.scrollHeight \u003e oldHeight ? 15 : 0) + \"px\";\n}\n\nfunction handleButtonsActivation(event) {\n var textarea = event.target;\n var commentForm = textarea.closest('.comment-form');\n if (commentForm) {\n var buttons = textarea.closest('.comment-form').getElementsByClassName('js-btn-enable');\n Array.from(buttons).forEach(function(button) {\n button.disabled = textarea.value.length === 0;\n });\n };\n}\n\nfunction validateField(event) {\n // We only need to validate the textarea that is not the comment mention auto-complete component\n const textArea = event.target.form.querySelector('.comment-textarea:not([role=combobox])');\n\n if (textArea.value === '') {\n event.preventDefault();\n return;\n }\n}\n\nfunction handleChange(event) {\n handleButtonsActivation(event);\n}\n\nfunction generateUploadFormdata(image) {\n var token = document.querySelector(\"meta[name='csrf-token']\").content;\n var formData = new FormData();\n formData.append('authenticity_token', token);\n formData.append('image', image[0]);\n return formData;\n}\n\nfunction handleImageUpload(event, randomIdNumber) {\n var commentableId = document.getElementById('comments-container').dataset.commentableId;\n event.preventDefault();\n document.getElementById('image-upload-' + randomIdNumber).click();\n document.getElementById('image-upload-' + randomIdNumber).onchange = function (e) {\n var image = document.getElementById('image-upload-' + randomIdNumber).files;\n if (image.length \u003e 0) {\n document.getElementById(\"image-upload-file-label-\" + randomIdNumber).style.color = '#888888';\n document.getElementById(\"image-upload-file-label-\" + randomIdNumber).innerHTML = \"Uploading...\";\n document.getElementById(\"image-upload-submit-\" + randomIdNumber).value = \"uploading\";\n setTimeout(function () {\n document.getElementById(\"image-upload-submit-\" + randomIdNumber).click(function () { });\n }, 50)\n }\n }\n\n document.getElementById(\"image-upload-submit-\" + randomIdNumber).onclick = function (e) {\n e.preventDefault();\n var image = document.getElementById('image-upload-' + randomIdNumber).files;\n if (image.length \u003e 0) {\n getCsrfToken()\n .then(sendFetch(\"image-upload\", generateUploadFormdata(image)))\n .then(function (response) {\n if (response.status === 200) {\n response.json().then(\n function uploadImageCb(json) {\n var address = document.getElementById(\"uploaded-image-\" + randomIdNumber);\n var button = document.getElementById(\"image-upload-button-\" + randomIdNumber);\n var messageContainer = document.getElementById(\"image-upload-file-label-\" + randomIdNumber)\n // button.style.display = \"none\";\n messageContainer.style.display = \"none\";\n address.value = json.links[0];\n address.classList.remove(\"hidden\");;\n address.select();\n\n var uploadedMessage = 'Uploaded! Paste into editor';\n messageContainer.innerHTML = uploadedMessage;\n messageContainer.style.color = '#00c673';\n messageContainer.style.position = \"relative\";\n messageContainer.style.top = \"5px\";\n }\n );\n } else if (response.status === 429) {\n showRateLimitModal({\n response,\n element: 'image',\n action_ing: 'uploading',\n action_past: 'uploaded',\n });\n } else {\n response.json().then(function(responseBody) {\n var errorMessage = responseBody.error || 'Invalid file!';\n document.getElementById(\"image-upload-file-label-\" + randomIdNumber).innerHTML = errorMessage;\n document.getElementById(\"image-upload-file-label-\" + randomIdNumber).style.color = '#e05252';\n document.getElementById(\"image-upload-submit-\" + randomIdNumber).style.display = 'none';\n });\n }\n })\n .catch(function (err) {\n // there's currently no error handling\n })\n }\n }\n}\n\nfunction updateItemSummaryHtml(item) {\n var itemSummaryContent = item.getElementsByClassName(\"js-collapse-comment-content\")[0];\n var usernames = item.getElementsByClassName(\"js-comment-username\");\n var number = \"\";\n if (usernames.length \u003e 1) {\n number = \" + \" + (usernames.length - 1) + \" replies\"\n }\n var itemUsername = usernames[0].textContent + number\n if (item.open) {\n itemSummaryContent.innerHTML = \"\";\n } else {\n itemSummaryContent.innerHTML = itemUsername;\n }\n}\n\nfunction listenForDetailsToggle() {\n var detailItems = document.querySelectorAll(\".js-comment-wrapper\");\n for (var i = 0; i \u003c detailItems.length; i++) {\n detailItems[i].addEventListener(\"toggle\", event =\u003e {\n var item = event.target;\n updateItemSummaryHtml(item);\n });\n }\n}\n\n/**\n * Increment comment, stored in `.js-comments-count`, count by one.\n */\nfunction updateCommentsCount() {\n const commentsCountDiv = document.querySelector(\".js-comments-count\");\n\n // if there's nowhere to put the count return early.\n if(!commentsCountDiv) return;\n\n const commentsCountData = parseInt(commentsCountDiv.dataset.commentsCount, 10) + 1;\n commentsCountDiv.dataset.commentsCount = commentsCountData;\n commentsCountDiv.innerHTML = `(${commentsCountData})`\n}\n\nfunction handleHiddenComments(commentableType){\n const currentUser = userData();\n const commentableAuthorIds = [];\n let coAuthorIds = '';\n if(commentableType === \"Article\"){\n const articleContainer = document.querySelector('#article-show-container');\n if(articleContainer){\n if (articleContainer.dataset) {\n commentableAuthorIds.push(articleContainer.dataset.authorId);\n coAuthorIds = articleContainer.dataset.coAuthorIds;\n if(coAuthorIds){\n coAuthorIds.split(',').forEach(coAuthorId =\u003e {\n commentableAuthorIds.push(coAuthorId);\n });\n }\n }\n }\n else {\n const commentsContainer = document.querySelector('#comments-container');\n if(commentsContainer){\n if(commentsContainer.dataset) {\n commentableAuthorIds.push(commentsContainer.dataset.commentableAuthorId);\n coAuthorIds = commentsContainer.dataset.commentableCoAuthorIds;\n if(coAuthorIds){\n coAuthorIds.split(',').forEach(coAuthorId =\u003e {\n commentableAuthorIds.push(coAuthorId);\n });\n }\n }\n }\n }\n } else if(commentableType === \"PodcastEpisode\"){\n const podCastEpisodeContainer = document.querySelector('.podcast-episode-container');\n if(podCastEpisodeContainer){\n commentableAuthorIds.push(podCastEpisodeContainer.dataset.creatorId);\n }\n }\n if(currentUser \u0026\u0026 commentableAuthorIds.includes(currentUser.id.toString())){\n collapseCommentsHiddenByCommentableUser();\n }\n else {\n document.querySelectorAll('.element-hidden-by-commentable-user').forEach(element =\u003e {\n element.classList.add('hidden');\n })\n document.querySelectorAll('.comment-hidden-by-author-text').forEach(element =\u003e {\n element.classList.remove('hidden');\n })\n }\n}\n\nfunction collapseCommentsHiddenByCommentableUser() {\n document.querySelectorAll(\".js-comment-wrapper.details-comment-hidden-by-commentable-user\").forEach(item =\u003e {\n if (item.querySelectorAll('.comment-form').length === 0){\n item.open = false;\n updateItemSummaryHtml(item);\n }\n })\n};\n/* global localizeTimeElements */\n\n'use strict';\n\nfunction initializeCreditsPage() {\n const datetimes = document.querySelectorAll('.ledger time');\n\n localizeTimeElements(datetimes, {\n year: 'numeric',\n month: 'short',\n day: '2-digit',\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n });\n};\n/* global InstantClick */\n\n'use strict';\n\nfunction selectNavigation(select, urlPrefix) {\n const trigger = document.getElementById(select);\n\n if (trigger) {\n trigger.addEventListener('change', (event) =\u003e {\n let url = event.target.value;\n if (urlPrefix) {\n url = urlPrefix + url;\n }\n\n InstantClick.preload(url);\n InstantClick.display(url);\n });\n }\n}\n\nfunction initializeDashboardSort() {\n selectNavigation('dashboard_sort', '/dashboard?sort=');\n selectNavigation('dashboard_author');\n selectNavigation('mobile_nav_dashboard');\n};\n/* global localizeTimeElements */\n\n'use strict';\n\nfunction initializeDateHelpers() {\n // Date without year: Jul 12\n localizeTimeElements(document.querySelectorAll('time.date-no-year'), {\n month: 'short',\n day: 'numeric',\n });\n\n // Full date: Jul 12, 2020\n localizeTimeElements(document.querySelectorAll('time.date'), {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n};\n/* global InstantClick, slideSidebar */\n\nfunction initializeDrawerSliders() {\n if (document.getElementById('on-page-nav-controls')) {\n if (document.getElementById('sidebar-bg-left')) {\n document.getElementById('sidebar-bg-left').onclick = (_event) =\u003e {\n slideSidebar('left', 'outOfView');\n };\n }\n if (document.getElementById('sidebar-bg-right')) {\n document.getElementById('sidebar-bg-right').onclick = (_event) =\u003e {\n slideSidebar('right', 'outOfView');\n };\n }\n\n if (document.getElementById('on-page-nav-butt-left')) {\n document.getElementById('on-page-nav-butt-left').onclick = (_event) =\u003e {\n slideSidebar('left', 'intoView');\n };\n }\n if (document.getElementById('on-page-nav-butt-right')) {\n document.getElementById('on-page-nav-butt-right').onclick = (_event) =\u003e {\n slideSidebar('right', 'intoView');\n };\n }\n InstantClick.on('change', (_event) =\u003e {\n document.body.classList.remove('modal-open');\n slideSidebar('right', 'outOfView');\n slideSidebar('left', 'outOfView');\n });\n }\n\n const feedFilterSelect = document.getElementById('feed-filter-select');\n\n if (feedFilterSelect) {\n feedFilterSelect.addEventListener('change', (event) =\u003e {\n const url = event.target.value;\n\n InstantClick.preload(url);\n InstantClick.display(url);\n });\n }\n};\n'use strict';\n\nfunction initializeHeroBannerClose() {\n let bannerWrapper = document.getElementById('hero-html-wrapper');\n let closeIcon = document.getElementById('js-hero-banner__x');\n\n // Currently js-hero-banner__x button icon ID needs to be written into the abstract html\n // In the future this could be extracted so the implementer doesn't need to worry about it.\n\n if (bannerWrapper \u0026\u0026 closeIcon) {\n closeIcon.setAttribute('aria-label', 'Close campaign banner');\n closeIcon.addEventListener('click', () =\u003e {\n localStorage.setItem('exited_hero', bannerWrapper.dataset.name);\n bannerWrapper.style.display = 'none';\n });\n }\n};\nfunction initializeLocalStorageRender() {\n try {\n var userData = browserStoreCache('get');\n if (userData) {\n document.body.dataset.user = userData;\n initializeBaseUserData();\n initializeReadingListIcons();\n initializeSponsorshipVisibility();\n }\n } catch (err) {\n browserStoreCache('remove');\n }\n};\n/**\n * This script looks for the onboarding task card, which is hidden by default,\n * and displays it if the user is created less than a week ago and hasn't closed\n * the task card yet.\n */\n\nfunction initializeOnboardingTaskCard() {\n if (localStorage.getItem('task-card-closed') === 'yes') {\n return;\n }\n\n var taskCard = document.getElementsByClassName('onboarding-task-card')[0];\n const user = userData();\n if (taskCard == null || !user) {\n return; // Guard against a null/undefined taskCard, and no user data.\n }\n\n var createdAt = new Date(user.created_at);\n var now = new Date();\n var aWeekAgo = now.setDate(now.getDate() - 7);\n\n if (createdAt \u003e aWeekAgo) {\n taskCard.style.display = 'block';\n }\n};\n'use strict';\n\nfunction initializePWAFunctionality() {\n if (\n window.matchMedia('(display-mode: standalone)').matches ||\n window.frameElement\n ) {\n document\n .getElementById('pwa-nav-buttons')\n .classList.add('pwa-nav-buttons--showing');\n document.getElementById('app-back-button').onclick = (e) =\u003e {\n e.preventDefault();\n window.history.back();\n };\n document.getElementById('app-forward-button').onclick = (e) =\u003e {\n e.preventDefault();\n window.history.forward();\n };\n document.getElementById('app-refresh-button').onclick = (e) =\u003e {\n e.preventDefault();\n window.location.reload();\n };\n var isTouchDevice = /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|DEV-Native-ios/i.test(\n navigator.userAgent,\n );\n if (!isTouchDevice) {\n var domain = window.location.protocol + '//' + window.location.host;\n var links = document.getElementsByTagName('a');\n // eslint-disable-next-line no-plusplus\n for (var i = 0, max = links.length; i \u003c max; i++) {\n var a = links[i];\n if (a.href.indexOf(domain + '/') === 0 || a.href.indexOf('/') === 0) {\n // Is internal link. Do nothing right now.\n } else {\n a.setAttribute('target', '_blank');\n a.setAttribute('rel', 'noopener noreferrer');\n }\n }\n }\n }\n};\nfunction initializePaymentPointers() {\n var userPointer = document.getElementById('author-payment-pointer');\n var basePointer = document.getElementById('base-payment-pointer');\n var meta = document.querySelector(\"meta[name='monetization']\");\n\n if (userPointer \u0026\u0026 meta) {\n meta.content = userPointer.dataset.paymentPointer;\n } else if (basePointer) {\n meta.content = basePointer.dataset.paymentPointer;\n }\n};\n/**\n * This script hunts for podcast's \"Record\" for both the podcast_episode's\n * show page and an article page containing podcast liquid tag. It handles\n * playback and makes sure the record will spin when the podcast is currently\n * playing.\n *\n * The media is initialized (once) and the \"state\" is stored using localStorage.\n * When playback is the website's responsability it's run using the `audio` HTML\n * element. The iOS app uses a bridging strategy that sends messages using\n * webkit messageHandlers and receives incoming messages through the\n * `contentaudio` element, which allows for native audio playback.\n *\n * The high level functions are the following:\n * - spinPodcastRecord()\n * - findAndApplyOnclickToRecords()\n * - initializeMedia()\n * - currentAudioState()\n * - saveMediaState()\n *\n * The following are useful eslint disables for this file in particular. Because\n * of the way it's wrapped around its own function (own context) we don't have\n * the problem of using a method before it's defined:\n */\n\n/* global ahoy, Runtime */\n/* eslint no-use-before-define: 0 */\n/* eslint no-param-reassign: 0 */\n\nvar audioInitialized = false;\n\nfunction initializePodcastPlayback() {\n var deviceType = 'web';\n\n function getById(name) {\n return document.getElementById(name);\n }\n\n function getByClass(name) {\n return document.getElementsByClassName(name);\n }\n\n function newAudioState() {\n if (!window.name) {\n window.name = Math.random();\n }\n return {\n html: getById('audiocontent').innerHTML,\n currentTime: 0,\n playing: false,\n muted: false,\n volume: 1,\n duration: 1,\n updated: new Date().getTime(),\n windowName: window.name,\n };\n }\n\n function currentAudioState() {\n try {\n var currentState = JSON.parse(\n localStorage.getItem('media_playback_state_v2'),\n );\n if (!currentState || window.name !== currentState.windowName) {\n return newAudioState();\n }\n return currentState;\n } catch (e) {\n console.log(e); // eslint-disable-line no-console\n return newAudioState();\n }\n }\n\n function audioExistAndIsPlaying() {\n var audio = getById('audio');\n var currentState = currentAudioState();\n return audio \u0026\u0026 currentState.playing;\n }\n\n function recordExist() {\n return getById(`record-${window.activeEpisode}`);\n }\n\n function spinPodcastRecord(customMessage) {\n if (audioExistAndIsPlaying() \u0026\u0026 recordExist()) {\n var podcastPlaybackButton = getById(`record-${window.activeEpisode}`);\n podcastPlaybackButton.classList.add('playing');\n podcastPlaybackButton.setAttribute('aria-pressed', 'true');\n changeStatusMessage(customMessage);\n }\n }\n\n function stopRotatingActivePodcastIfExist() {\n if (window.activeEpisode \u0026\u0026 getById(`record-${window.activeEpisode}`)) {\n var podcastPlaybackButton = getById(`record-${window.activeEpisode}`);\n podcastPlaybackButton.classList.remove('playing');\n podcastPlaybackButton.setAttribute('aria-pressed', 'false');\n window.activeEpisode = undefined;\n }\n }\n\n function findRecords() {\n var podcastPageRecords = getByClass('record-wrapper');\n var podcastLiquidTagrecords = getByClass('podcastliquidtag__record');\n if (podcastPageRecords.length \u003e 0) {\n return podcastPageRecords;\n }\n return podcastLiquidTagrecords;\n }\n\n function saveMediaState(state) {\n var currentState = state || currentAudioState();\n var newState = newAudioState();\n newState.currentTime = currentState.currentTime;\n newState.playing = currentState.playing;\n newState.muted = currentState.muted;\n newState.volume = currentState.volume;\n newState.duration = currentState.duration;\n localStorage.setItem('media_playback_state_v2', JSON.stringify(newState));\n return newState;\n }\n\n function applyOnclickToPodcastBar(audio) {\n var currentState = currentAudioState();\n getById('barPlayPause').onclick = function () {\n playPause(audio);\n };\n getById('mutebutt').onclick = function () {\n muteUnmute(audio);\n };\n getById('volbutt').onclick = function () {\n muteUnmute(audio);\n };\n getById('bufferwrapper').onclick = function (e) {\n goToTime(e, audio);\n };\n getById('volumeslider').value = currentState.volume * 100;\n getById('volumeslider').onchange = function (e) {\n updateVolume(e, audio);\n };\n getById('speed').onclick = function () {\n changePlaybackRate(audio);\n };\n getById('closebutt').onclick = function () {\n terminatePodcastBar(audio);\n };\n }\n\n function podcastBarAlreadyExistAndPlayingTargetEpisode(episodeSlug) {\n return getById('audiocontent').innerHTML.indexOf(`${episodeSlug}`) !== -1;\n }\n\n function updateProgressListener(audio) {\n return function (e) {\n var bufferValue = 0;\n if (audio.currentTime \u003e 0) {\n var bufferEnd = audio.buffered.end(audio.buffered.length - 1);\n bufferValue = (bufferEnd / audio.duration) * 100;\n }\n updateProgress(audio.currentTime, audio.duration, bufferValue);\n };\n }\n\n function loadAudio(audio) {\n if (Runtime.podcastMessage) {\n Runtime.podcastMessage({\n action: 'load',\n url: audio.getElementsByTagName('source')[0].src,\n });\n } else {\n audio.load();\n }\n }\n\n function loadAndPlayNewPodcast(episodeSlug) {\n getById('audiocontent').innerHTML = getById(\n `hidden-audio-${episodeSlug}`,\n ).innerHTML;\n var audio = getById('audio');\n audio.addEventListener('timeupdate', updateProgressListener(audio), false);\n loadAudio(audio);\n playPause(audio);\n applyOnclickToPodcastBar(audio);\n }\n\n function findAndApplyOnclickToRecords() {\n var records = findRecords();\n Array.prototype.forEach.call(records, function (record) {\n var episodeSlug = record.getAttribute('data-episode');\n var podcastSlug = record.getAttribute('data-podcast');\n\n var togglePodcastState = function (e) {\n if (podcastBarAlreadyExistAndPlayingTargetEpisode(episodeSlug)) {\n var audio = getById('audio');\n if (audio) {\n playPause(audio);\n }\n } else {\n stopRotatingActivePodcastIfExist();\n loadAndPlayNewPodcast(episodeSlug);\n }\n };\n record.addEventListener('click', togglePodcastState);\n });\n }\n\n function changePlaybackRate(audio) {\n var currentState = currentAudioState();\n var el = getById('speed');\n var speed = parseFloat(el.getAttribute('data-speed'));\n if (speed === 2) {\n el.setAttribute('data-speed', 0.5);\n el.innerHTML = '0.5x';\n currentState.playbackRate = 0.5;\n } else {\n el.setAttribute('data-speed', speed + 0.5);\n el.innerHTML = speed + 0.5 + 'x';\n currentState.playbackRate = speed + 0.5;\n }\n saveMediaState(currentState);\n\n if (Runtime.podcastMessage) {\n Runtime.podcastMessage({\n action: 'rate',\n rate: currentState.playbackRate.toString(),\n });\n } else {\n audio.playbackRate = currentState.playbackRate;\n }\n }\n\n function changeStatusMessage(message) {\n var statusBox = getById(`status-message-${window.activeEpisode}`);\n if (statusBox) {\n if (message) {\n statusBox.classList.add('showing');\n statusBox.innerHTML = message;\n } else {\n statusBox.classList.remove('showing');\n }\n } else if (\n message === 'initializing...' \u0026\u0026\n getByClass('status-message')[0]\n ) {\n getByClass('status-message')[0].innerHTML = message;\n }\n }\n\n function startPodcastBar() {\n getById('barPlayPause').classList.add('playing');\n getById('progressBar').classList.add('playing');\n getById('animated-bars').classList.add('playing');\n }\n\n function pausePodcastBar() {\n getById('barPlayPause').classList.remove('playing');\n getById('animated-bars').classList.remove('playing');\n }\n\n function playAudio(audio) {\n return new Promise(function (resolve, reject) {\n var currentState = currentAudioState();\n if (Runtime.podcastMessage) {\n Runtime.podcastMessage({\n action: 'play',\n url: audio.getElementsByTagName('source')[0].src,\n seconds: currentState.currentTime.toString(),\n });\n setPlaying(true);\n resolve();\n } else {\n audio.currentTime = currentState.currentTime;\n audio\n .play()\n .then(function () {\n setPlaying(true);\n resolve();\n })\n .catch(function (error) {\n console.log(error); // eslint-disable-line no-console\n setPlaying(false);\n reject();\n });\n }\n });\n }\n\n function fetchMetadataString() {\n var episodeContainer = getByClass('podcast-episode-container')[0];\n if (episodeContainer === undefined) {\n episodeContainer = getByClass('podcastliquidtag')[0];\n }\n return episodeContainer.dataset.meta;\n }\n\n function sendMetadataMessage() {\n if (Runtime.podcastMessage) {\n try {\n var metadata = JSON.parse(fetchMetadataString());\n Runtime.podcastMessage({\n action: 'metadata',\n episodeName: metadata.episodeName,\n podcastName: metadata.podcastName,\n podcastImageUrl: metadata.podcastImageUrl,\n });\n } catch (e) {\n console.log('Unable to load Podcast Episode metadata', e); // eslint-disable-line no-console\n }\n }\n }\n\n function startAudioPlayback(audio) {\n sendMetadataMessage();\n\n playAudio(audio)\n .then(function () {\n spinPodcastRecord();\n startPodcastBar();\n })\n .catch(function (error) {\n playAudio(audio);\n setTimeout(function () {\n spinPodcastRecord('initializing...');\n startPodcastBar();\n }, 5);\n });\n }\n\n function pauseAudioPlayback(audio) {\n if (Runtime.podcastMessage) {\n Runtime.podcastMessage({ action: 'pause' });\n } else {\n audio.pause();\n }\n setPlaying(false);\n stopRotatingActivePodcastIfExist();\n pausePodcastBar();\n }\n\n function ahoyMessage(action) {\n window.activeEpisode = audio.getAttribute('data-episode');\n window.activePodcast = audio.getAttribute('data-podcast');\n\n var properties = {\n action: action,\n episode: window.activeEpisode,\n podcast: window.activePodcast,\n deviceType: deviceType,\n };\n ahoy.track('Podcast Player Streaming', properties);\n }\n\n function playPause(audio) {\n var currentState = currentAudioState();\n if (!currentState.playing) {\n ahoyMessage('play');\n changeStatusMessage('initializing...');\n startAudioPlayback(audio);\n } else {\n ahoyMessage('pause');\n pauseAudioPlayback(audio);\n changeStatusMessage(null);\n }\n }\n\n function muteUnmute(audio) {\n var currentState = currentAudioState();\n getById('mutebutt').classList.add(\n currentState.muted ? 'hidden' : 'showing',\n );\n getById('volumeindicator').classList.add(\n currentState.muted ? 'showing' : 'hidden',\n );\n getById('mutebutt').classList.remove(\n currentState.muted ? 'showing' : 'hidden',\n );\n getById('volumeindicator').classList.remove(\n currentState.muted ? 'hidden' : 'showing',\n );\n\n currentState.muted = !currentState.muted;\n if (Runtime.podcastMessage) {\n Runtime.podcastMessage({\n action: 'muted',\n muted: currentState.muted.toString(),\n });\n } else {\n audio.muted = currentState.muted;\n }\n saveMediaState(currentState);\n }\n\n function updateVolume(e, audio) {\n var currentState = currentAudioState();\n currentState.volume = e.target.value / 100;\n if (Runtime.podcastMessage) {\n Runtime.podcastMessage({ action: 'volume', volume: currentState.volume });\n } else {\n audio.volume = currentState.volume;\n }\n saveMediaState(currentState);\n }\n\n function updateProgress(currentTime, duration, bufferValue) {\n var progress = getById('progress');\n var buffer = getById('buffer');\n var time = getById('time');\n var value = 0;\n var firstDecimal = currentTime - Math.floor(currentTime);\n if (currentTime \u003e 0) {\n value = Math.floor((100.0 / duration) * currentTime);\n if (firstDecimal \u003c 0.4) {\n // Rewrite to mediaState storage every few beats.\n var currentState = currentAudioState();\n currentState.duration = duration;\n currentState.currentTime = currentTime;\n saveMediaState(currentState);\n }\n }\n if (progress \u0026\u0026 time \u0026\u0026 currentTime \u003e 0) {\n progress.style.width = value + '%';\n buffer.style.width = bufferValue + '%';\n time.innerHTML =\n readableDuration(currentTime) + ' / ' + readableDuration(duration);\n }\n }\n\n function goToTime(e, audio) {\n var currentState = currentAudioState();\n var progress = getById('progress');\n var time = getById('time');\n if (e.clientX \u003e 128) {\n var percent = (e.clientX - 128) / (window.innerWidth - 133);\n var duration = currentState.duration;\n currentState.currentTime = duration * percent; // jumps to 29th secs\n\n if (Runtime.podcastMessage) {\n Runtime.podcastMessage({\n action: 'seek',\n seconds: currentState.currentTime.toString(),\n });\n } else {\n audio.currentTime = currentState.currentTime;\n }\n\n time.innerHTML =\n readableDuration(currentState.currentTime) +\n ' / ' +\n readableDuration(currentState.duration);\n progress.style.width = percent * 100.0 + '%';\n }\n }\n\n function readableDuration(seconds) {\n var sec = Math.floor(seconds);\n var min = Math.floor(sec / 60);\n min = min \u003e= 10 ? min : '0' + min;\n sec = Math.floor(sec % 60);\n sec = sec \u003e= 10 ? sec : '0' + sec;\n return min + ':' + sec;\n }\n\n function terminatePodcastBar(audio) {\n audio.removeEventListener(\n 'timeupdate',\n updateProgressListener(audio),\n false,\n );\n getById('audiocontent').innerHTML = '';\n stopRotatingActivePodcastIfExist();\n saveMediaState(newAudioState());\n if (Runtime.podcastMessage) {\n Runtime.podcastMessage({ action: 'terminate' });\n }\n }\n\n function handlePodcastMessages(event) {\n const message = JSON.parse(event.detail);\n if (message.namespace !== 'podcast') {\n return;\n }\n\n var currentState = currentAudioState();\n switch (message.action) {\n case 'init':\n getById('time').innerHTML = 'initializing...';\n currentState.currentTime = 0;\n break;\n case 'tick':\n currentState.currentTime = message.currentTime;\n currentState.duration = message.duration;\n updateProgress(currentState.currentTime, currentState.duration, 100);\n break;\n default:\n console.log('Unrecognized message: ', message); // eslint-disable-line no-console\n }\n\n saveMediaState(currentState);\n }\n\n // When Runtime.podcastMessage is undefined we need to execute web logic\n function initRuntime() {\n if (Runtime.isNativeIOS('podcast')) {\n deviceType = 'iOS';\n } else if (Runtime.isNativeAndroid('podcastMessage')) {\n deviceType = 'Android';\n }\n\n if (deviceType !== 'web') {\n Runtime.podcastMessage = (msg) =\u003e {\n window.ForemMobile.injectNativeMessage('podcast', msg);\n };\n }\n }\n\n function initializeMedia() {\n var currentState = currentAudioState();\n document.getElementById('audiocontent').innerHTML = currentState.html;\n var audio = getById('audio');\n if (audio === undefined || audio === null) {\n audioInitialized = false;\n return;\n }\n if (Runtime.podcastMessage) {\n audio.currentTime = currentState.currentTime || 0;\n }\n loadAudio(audio);\n if (currentState.playing) {\n playAudio(audio).catch(function (error) {\n pausePodcastBar();\n });\n }\n setTimeout(function () {\n audio.addEventListener(\n 'timeupdate',\n updateProgressListener(audio),\n false,\n );\n document.addEventListener('ForemMobile', handlePodcastMessages);\n }, 500);\n applyOnclickToPodcastBar(audio);\n }\n\n function setPlaying(playing) {\n var currentState = currentAudioState();\n currentState.playing = playing;\n saveMediaState(currentState);\n }\n\n initRuntime();\n spinPodcastRecord();\n findAndApplyOnclickToRecords();\n if (!audioInitialized) {\n audioInitialized = true;\n initializeMedia();\n }\n var audio = getById('audio');\n var audioContent = getById('audiocontent');\n if (audio \u0026\u0026 audioContent \u0026\u0026 audioContent.innerHTML.length \u003c 25) {\n // audio not already loaded\n loadAudio(audio);\n }\n};\n/* eslint-disable no-use-before-define */\n/* eslint-disable no-undef */\n/* eslint-disable func-names */\n/* eslint-disable consistent-return */\n/* eslint-disable no-unused-vars */\n\nfunction initializeReadingListIcons() {\n setReadingListButtonsState();\n addReadingListCountToHomePage();\n addHoverEffectToReadingListButtons();\n}\n\n// set SAVE or SAVED articles buttons\nfunction setReadingListButtonsState() {\n var readingListButtons = document.querySelectorAll(\n '.bookmark-button:not([data-initial-feed])',\n );\n Array.from(readingListButtons).forEach(highlightButton);\n}\n\n// private\n\nfunction highlightButton(button) {\n var user = userData();\n var buttonIdInt = parseInt(button.dataset.reactableId, 10);\n if (user \u0026\u0026 user.reading_list_ids.indexOf(buttonIdInt) \u003e -1) {\n button.classList.add('selected');\n } else {\n button.classList.remove('selected');\n }\n button.addEventListener('click', reactToReadingListButtonClick);\n button.dataset.saveInitialized = true;\n}\n\nfunction addReadingListCountToHomePage() {\n var user = userData();\n var readingListCount;\n if (user \u0026\u0026 document.getElementById('reading-list-count')) {\n readingListCount =\n user.reading_list_ids.length \u003e 0 ? user.reading_list_ids.length : '';\n document.getElementById('reading-list-count').innerHTML = readingListCount;\n document.getElementById('reading-list-count').dataset.count =\n user.reading_list_ids.length;\n }\n}\n\nfunction reactToReadingListButtonClick(event) {\n var button;\n var userStatus;\n event.preventDefault();\n sendHapticMessage('medium');\n userStatus = document.body.getAttribute('data-user-status');\n if (userStatus === 'logged-out') {\n showLoginModal();\n return;\n }\n button = properButtonFromEvent(event);\n renderOptimisticResult(button);\n getCsrfToken()\n .then(sendFetch('reaction-creation', buttonFormData(button)))\n .then(function (response) {\n if (response.status === 200) {\n return response.json().then(function (json) {\n renderButtonState(button, json);\n renderNewSidebarCount(button, json);\n });\n } // else {\n // there's currently no errorCb.\n // }\n })\n .catch(function (error) {\n // there's currently no error handling.\n });\n}\n\nfunction renderButtonState(button, json) {\n if (json.result === 'create') {\n button.classList.add('selected');\n addHoverEffectToReadingListButtons(button);\n } else {\n button.classList.remove('selected');\n }\n}\n\nfunction renderNewSidebarCount(button, json) {\n var newCount;\n var count = document.getElementById('reading-list-count').dataset.count;\n count = parseInt(count, 10);\n if (json.result === 'create') {\n newCount = count + 1;\n } else if (count !== 0) {\n newCount = count - 1;\n }\n document.getElementById('reading-list-count').dataset.count = newCount;\n document.getElementById('reading-list-count').innerHTML =\n newCount \u003e 0 ? newCount : '';\n}\n\nfunction buttonFormData(button) {\n var formData = new FormData();\n formData.append('reactable_type', 'Article');\n formData.append('reactable_id', button.dataset.reactableId);\n formData.append('category', 'readinglist');\n return formData;\n}\n\nfunction renderOptimisticResult(button) {\n renderButtonState(button, { result: 'create' }); // optimistic create only for now\n}\n\nfunction properButtonFromEvent(event) {\n var properElement;\n if (event.target.tagName === 'BUTTON') {\n properElement = event.target;\n } else {\n properElement = event.target.parentElement;\n }\n return properElement;\n}\n\n/*\n Add the hover effect to reading list buttons.\n\n This function makes use of mouseover/mouseevent bubbling behaviors to attach\n only two event handlers to the articles container for performance reasons.\n*/\nfunction addHoverEffectToReadingListButtons() {\n var articlesList = document.getElementsByClassName('articles-list');\n Array.from(articlesList).forEach(function (container) {\n // we use `bind` so that the event handler will have the correct text in its\n // `this` local variable\n container.addEventListener(\n 'mouseover',\n readingListButtonMouseHandler.bind('Unsave'),\n );\n container.addEventListener(\n 'mouseout',\n readingListButtonMouseHandler.bind('Saved'),\n );\n });\n}\n\n/*\n Determines if the element is the target of the reading list button hover.\n*/\nfunction isReadingListButtonHoverTarget(element) {\n var classList = element.classList;\n\n return (\n (element.tagName === 'BUTTON' \u0026\u0026\n classList.contains('bookmark-button') \u0026\u0026\n classList.contains('selected')) ||\n (element.tagName === 'SPAN' \u0026\u0026 classList.contains('bm-success'))\n );\n}\n\nfunction readingListButtonMouseHandler(event) {\n var target = event.target;\n\n if (isReadingListButtonHoverTarget(target)) {\n event.preventDefault();\n\n var textReplacement = this; // `this` is the text to be replaced\n var textSpan;\n if (target.tagName === 'BUTTON') {\n textSpan = target.getElementsByClassName('bm-success')[0];\n } else {\n textSpan = target;\n }\n\n textSpan.innerHTML = textReplacement;\n }\n}\n\n/* eslint-enable no-use-before-define */\n/* eslint-enable no-undef */\n/* eslint-enable func-names */\n/* eslint-enable consistent-return */\n/* eslint-enable no-unused-vars */;\n/* global timestampToLocalDateTime InstantClick */\n\nfunction initializeSettings() {\n // highlights organization secret on click\n const settingsOrgSecret = document.getElementById('settings-org-secret');\n if (settingsOrgSecret) {\n settingsOrgSecret.addEventListener('click', (event) =\u003e {\n event.target.select();\n });\n }\n\n // shows RSS fetch time in local time\n let timeNode = document.getElementById('rss-fetch-time');\n if (timeNode) {\n var timeStamp = timeNode.getAttribute('datetime');\n var timeOptions = {\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n };\n\n timeNode.textContent = timestampToLocalDateTime(\n timeStamp,\n navigator.language,\n timeOptions,\n );\n }\n\n const mobilePageSelector = document.getElementById('mobile-page-selector');\n\n if (mobilePageSelector) {\n mobilePageSelector.addEventListener('change', (event) =\u003e {\n const url = event.target.value;\n\n InstantClick.preload(url);\n InstantClick.display(url);\n });\n }\n};\n/*\n * kept as a stand function so it can be loaded again without issue\n * see: https://github.com/thepracticaldev/dev.to/issues/6468\n */\nfunction sponsorClickHandler(event) {\n ga(\n 'send',\n 'event',\n 'click',\n 'click sponsor link',\n event.target.dataset.details,\n null,\n );\n}\n\nfunction listenForSponsorClick() {\n setTimeout(() =\u003e {\n if (window.ga) {\n var links = document.getElementsByClassName('partner-link');\n // eslint-disable-next-line no-plusplus\n for (var i = 0; i \u003c links.length; i++) {\n links[i].onclick = sponsorClickHandler;\n }\n }\n }, 400);\n}\n\nfunction initializeSponsorshipVisibility() {\n var el =\n document.getElementById('sponsorship-widget') ||\n document.getElementById('partner-content-display');\n var user = userData();\n if (el) {\n setTimeout(() =\u003e {\n if (window.ga) {\n if (document.querySelectorAll('[data-partner-seen]').length === 0) {\n ga(\n 'send',\n 'event',\n 'view',\n 'sponsor displayed on page',\n el.dataset.details,\n null,\n );\n el.dataset.partnerSeen = 'true';\n }\n }\n }, 400);\n }\n if (el \u0026\u0026 user \u0026\u0026 user.display_sponsors) {\n el.classList.remove('hidden');\n listenForSponsorClick();\n } else if (el \u0026\u0026 user) {\n el.classList.add('hidden');\n } else if (el) {\n el.classList.remove('hidden');\n listenForSponsorClick();\n }\n};\n'use strict';\n\nfunction formatDateTime(options, value) {\n return new Intl.DateTimeFormat('en-US', options).format(value);\n}\n\nfunction convertUtcTime(utcTime) {\n var time = new Date(utcTime);\n var options = {\n hour: 'numeric',\n minute: 'numeric',\n timeZoneName: 'short',\n };\n return formatDateTime(options, time);\n}\n\nfunction convertUtcDate(utcDate) {\n var date = new Date(utcDate);\n var options = {\n month: 'short',\n day: 'numeric',\n };\n return formatDateTime(options, date);\n}\n\nfunction convertCalEvent(utc) {\n var date = new Date(utc);\n var options = {\n weekday: 'long',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n };\n\n return formatDateTime(options, date);\n}\n\nfunction updateLocalDateTime(elements, convertCallback, getUtcDateTime) {\n var local;\n for (var i = 0; i \u003c elements.length; i += 1) {\n local = convertCallback(getUtcDateTime(elements[i]));\n // eslint-disable-next-line no-param-reassign\n elements[i].innerHTML = local;\n }\n}\n\nfunction initializeTimeFixer() {\n var utcTime = document.getElementsByClassName('utc-time');\n var utcDate = document.getElementsByClassName('utc-date');\n var utc = document.getElementsByClassName('utc');\n\n if (!utc) {\n return;\n }\n\n updateLocalDateTime(\n utcTime,\n convertUtcTime,\n (element) =\u003e element.dataset.datetime,\n );\n updateLocalDateTime(\n utcDate,\n convertUtcDate,\n (element) =\u003e element.dataset.datetime,\n );\n updateLocalDateTime(utc, convertCalEvent, (element) =\u003e element.innerHTML);\n};\n'use strict';\n\nfunction initializeProfileInfoToggle() {\n const infoPanels = document.getElementsByClassName('js-user-info')[0];\n const trigger = document.getElementsByClassName('js-user-info-trigger')[0];\n const triggerWrapper = document.getElementsByClassName(\n 'js-user-info-trigger-wrapper',\n )[0];\n\n if (trigger \u0026\u0026 infoPanels) {\n trigger.addEventListener('click', () =\u003e {\n triggerWrapper.classList.replace('block', 'hidden');\n infoPanels.classList.replace('hidden', 'grid');\n });\n }\n}\n\nfunction initializeProfileBadgesToggle() {\n const badgesWrapper = document.getElementsByClassName('js-profile-badges')[0];\n const trigger = document.getElementsByClassName(\n 'js-profile-badges-trigger',\n )[0];\n\n if (badgesWrapper \u0026\u0026 trigger) {\n const badges = badgesWrapper.querySelectorAll('.js-profile-badge.hidden');\n trigger.addEventListener('click', () =\u003e {\n badges.forEach((badge) =\u003e {\n badge.classList.remove('hidden');\n });\n\n trigger.classList.add('hidden');\n });\n }\n};\n/**\n * This script hunts for video tags and initializes the correct player\n * depending on the platform:\n * - web: jwplayer\n * - iOS/Android: Native player\n *\n * Once jwplayer is initialized there's no follow up actions to be taken.\n * Mobile Native players send back information into the DOM in order to\n * interact and update the UI, therefore a MutationObserver is registered.\n */\n\n/* eslint no-use-before-define: 0 */\n/* eslint no-param-reassign: 0 */\n/* eslint no-useless-escape: 0 */\n/* global jwplayer, ahoy, Runtime */\n\nfunction initializeVideoPlayback() {\n var currentTime = '0';\n var deviceType = 'web';\n var lastEvent = '';\n\n function getById(name) {\n return document.getElementById(name);\n }\n\n function getParameterByName(name, url) {\n if (!url) url = window.location.href;\n name = name.replace(/[\\[\\]]/g, '\\\\$\u0026');\n var regex = new RegExp('[?\u0026]' + name + '(=([^\u0026#]*)|\u0026|#|$)'),\n results = regex.exec(url);\n if (!results) return null;\n if (!results[2]) return '';\n return decodeURIComponent(results[2].replace(/\\+/g, ' '));\n }\n\n function timeToSeconds(hms) {\n var a;\n if (hms.length \u003c 3) {\n return hms;\n } else if (hms.length \u003c 6) {\n a = hms.split(':');\n return (hms = +a[0] * 60 + +a[1]);\n } else {\n a = hms.split(':');\n return (hms = +a[0] * 60 * 60 + +a[1] * 60 + +a[2]);\n }\n }\n\n function videoPlayerEvent(isPlaying) {\n // jwtplayer tends to send multiple 'play' actions. This check makes sure\n // we're not tracking repeated 'play' events for a single interaction.\n var eventName = isPlaying ? 'play' : 'pause';\n if (lastEvent === eventName) {\n return;\n }\n lastEvent = eventName;\n\n var metadata = videoMetadata(getById('video-player-source'));\n var properties = {\n article: metadata.id,\n deviceType: deviceType,\n action: eventName,\n };\n ahoy.track('Video Player Streaming', properties);\n }\n\n function initWebPlayer(seconds, metadata) {\n var waitingOnJWP = setInterval(function () {\n if (typeof jwplayer !== 'undefined') {\n clearInterval(waitingOnJWP);\n var playerInstance = jwplayer(`video-player-${metadata.id}`);\n playerInstance.setup({\n file: metadata.video_source_url,\n mediaid: metadata.video_code,\n image: metadata.video_thumbnail_url,\n playbackRateControls: true,\n tracks: [\n {\n file: metadata.video_closed_caption_track_url,\n label: 'English',\n kind: 'captions',\n default: false,\n },\n ],\n });\n if (seconds) {\n jwplayer().on('firstFrame', function () {\n jwplayer().seek(seconds);\n });\n jwplayer().on('play', function () {\n videoPlayerEvent(true);\n });\n jwplayer().on('pause', function () {\n videoPlayerEvent(false);\n });\n }\n }\n }, 2);\n }\n\n function videoMetadata(videoSource) {\n try {\n return JSON.parse(videoSource.dataset.meta);\n } catch (e) {\n console.log('Unable to load Podcast Episode metadata', e); // eslint-disable-line no-console\n }\n }\n\n function requestFocus() {\n var metadata = videoMetadata(videoSource);\n var playerElement = getById(`video-player-${metadata.id}`);\n\n getById('pause-butt').classList.add('active');\n getById('play-butt').classList.remove('active');\n\n Runtime.videoMessage({\n action: 'play',\n url: metadata.video_source_url,\n seconds: currentTime,\n });\n\n videoPlayerEvent(true);\n }\n\n function handleVideoMessages(event) {\n const message = JSON.parse(event.detail);\n if (message.namespace !== 'video') {\n return;\n }\n\n switch (message.action) {\n case 'play':\n getById('pause-butt').classList.add('active');\n getById('play-butt').classList.remove('active');\n videoPlayerEvent(true);\n break;\n case 'pause':\n getById('pause-butt').classList.remove('active');\n getById('play-butt').classList.add('active');\n videoPlayerEvent(false);\n break;\n case 'tick':\n currentTime = message.currentTime;\n break;\n default:\n console.log('Unrecognized message: ', message); // eslint-disable-line no-console\n }\n }\n\n function initializePlayer(videoSource) {\n var seconds = timeToSeconds(getParameterByName('t') || '0');\n var metadata = videoMetadata(videoSource);\n\n if (Runtime.isNativeIOS('video')) {\n deviceType = 'iOS';\n } else if (Runtime.isNativeAndroid('videoMessage')) {\n deviceType = 'Android';\n } else {\n // jwplayer is initialized and no further interaction is needed\n initWebPlayer(seconds, metadata);\n return;\n }\n\n Runtime.videoMessage = (msg) =\u003e {\n window.ForemMobile.injectNativeMessage('video', msg);\n };\n\n var playerElement = getById(`video-player-${metadata.id}`);\n playerElement.addEventListener('click', requestFocus);\n\n playerElement.classList.add('native');\n getById('play-butt').classList.add('active');\n\n document.addEventListener('ForemMobile', handleVideoMessages);\n\n currentTime = `${seconds}`;\n }\n\n // If an video player element is found initialize it\n var videoSource = getById('video-player-source');\n if (videoSource !== null) {\n initializePlayer(videoSource);\n }\n};\n/**\n * This class helps managing native feature support. Can easily be referenced\n * from anywhere in JavaScript with:\n *\n * if (Runtime.isNativeiOS('video')) { ... }\n *\n * if (Runtime.isNativeAndroid('podcastMessage')) { ... }\n */\nclass Runtime {\n /**\n * This function returns a string combining the current Medium and OS\n * that represents the current Context where the app is running.\n *\n * @returns {String} \"Medium-OS\", for example \"Browser-Android\"\n */\n static currentContext() {\n return `${Runtime.currentMedium()}-${Runtime.currentOS()}`;\n }\n\n /**\n * This function returns a string that represents the current Medium where\n * the app is currently running. The currently supported mediums are Browser,\n * ForemWebView and PWA.\n *\n * @returns {String} One of the supported Mediums or 'Unsupported'\n */\n static currentMedium() {\n const pwaButtons = document.getElementById('pwa-nav-buttons');\n if (/ForemWebView/i.test(navigator.userAgent)) {\n return 'ForemWebView';\n } else if (pwaButtons.classList.contains('pwa-nav-buttons--showing')) {\n return 'PWA';\n } else {\n return 'Browser';\n }\n }\n\n /**\n * This function returns a string that represents the current OS where the app\n * is currently running. The currently supported Operating Systems are\n * Windows, Linux, macOS, Android and iOS.\n *\n * @returns {String} One of the supported Operating Systems or 'Unsupported'\n */\n static currentOS() {\n const macosPlatforms = ['Macintosh', 'MacIntel', 'MacPPC', 'Mac68K'];\n const windowsPlatforms = ['Win32', 'Win64', 'Windows', 'WinCE'];\n const iosPlatforms = ['iPhone', 'iPad', 'iPod'];\n\n if (macosPlatforms.includes(window.navigator.platform)) {\n return 'macOS';\n } else if (iosPlatforms.includes(window.navigator.platform)) {\n return 'iOS';\n } else if (windowsPlatforms.includes(window.navigator.platform)) {\n return 'Windows';\n } else if (/Android/i.test(window.navigator.userAgent)) {\n return 'Android';\n } else if (/Linux/i.test(window.navigator.platform)) {\n return 'Linux';\n }\n\n return 'Unsupported';\n }\n\n /**\n * Checks the device for iOS (webkit) native feature support\n *\n * @function isNativeIOS\n * @param {string} namespace Specifies support for a specific feature\n * (i.e. video, podcast, etc)\n * @returns {boolean} true if current environment support native features\n */\n static isNativeIOS(namespace = null) {\n const nativeCheck =\n /DEV-Native-ios|ForemWebView/i.test(navigator.userAgent) \u0026\u0026\n window \u0026\u0026\n window.webkit \u0026\u0026\n window.webkit.messageHandlers;\n\n let namespaceCheck = true;\n if (nativeCheck \u0026\u0026 namespace) {\n namespaceCheck = window.webkit.messageHandlers[namespace] != undefined;\n }\n\n return nativeCheck \u0026\u0026 namespaceCheck;\n }\n\n /**\n * Checks the device for Android native feature support\n *\n * @function isNativeAndroid\n * @param {string} namespace Specifies support for a specific feature\n * (i.e. videoMessage, podcastMessage, etc)\n * @returns {boolean} true if current environment support native features\n */\n static isNativeAndroid(namespace = null) {\n const nativeCheck =\n /DEV-Native-android|ForemWebView/i.test(navigator.userAgent) \u0026\u0026\n typeof AndroidBridge !== 'undefined';\n\n let namespaceCheck = true;\n if (nativeCheck \u0026\u0026 namespace) {\n namespaceCheck = AndroidBridge[namespace] != undefined;\n }\n\n return nativeCheck \u0026\u0026 namespaceCheck;\n }\n\n /**\n * This function copies text to clipboard taking in consideration all\n * supported platforms.\n *\n * @param {string} text to be copied to the clipboard\n *\n * @returns {Promise} Resolves when succesful in copying to clipboard\n */\n static copyToClipboard(text) {\n return new Promise((resolve, reject) =\u003e {\n if (Runtime.isNativeAndroid('copyToClipboard')) {\n AndroidBridge.copyToClipboard(text);\n resolve();\n } else if (navigator.clipboard != null) {\n navigator.clipboard\n .writeText(text)\n .then(() =\u003e {\n resolve();\n })\n .catch((e) =\u003e {\n reject(e);\n });\n } else {\n reject('Unable to copy the text. Try reloading the page');\n }\n });\n }\n\n /**\n * Returns true if the supplied KeyboardEvent includes the OS-specific\n * modifier key. For example, the Cmd key on Apple platforms or the Ctrl key\n * on others.\n *\n * @param {KeyboardEvent} The event to check for the OS-specific modifier key\n *\n * @returns {Boolean} true if the event was fired with the OS-specific\n * modifier key, false otherwise. Also returns false if\n * the event is not a KeyboardEvent.\n */\n static hasOSSpecificModifier(event) {\n if (!(event instanceof KeyboardEvent)) {\n return false;\n }\n\n if (navigator.userAgent.indexOf('Mac OS X') \u003e= 0) {\n return event.metaKey;\n } else {\n return event.ctrlKey;\n }\n }\n\n /**\n * Returns a string representation of the expected modifier key for the current OS.\n * This allows us to display correct shortcut key hints to users in the UI, and set up correct shortcut key bindings.\n *\n * @returns {string} either 'cmd' if on macOS, or 'ctrl' otherwise\n */\n static getOSKeyboardModifierKeyString() {\n return Runtime.currentOS() === 'macOS' ? 'cmd' : 'ctrl';\n }\n};\n'use strict';\n\nfunction browserStoreCache(action, userData) {\n try {\n switch (action) {\n case 'set':\n localStorage.setItem('current_user', userData);\n localStorage.setItem(\n 'config_body_class',\n JSON.parse(userData).config_body_class,\n );\n break;\n case 'remove':\n localStorage.removeItem('current_user');\n break;\n default:\n return localStorage.getItem('current_user');\n }\n } catch (err) {\n if (navigator.cookieEnabled) {\n browserStoreCache('remove');\n }\n }\n return undefined;\n};\n/* global timeAgo, filterXSS */\n\n/* eslint-disable no-multi-str */\n\nfunction buildArticleHTML(article) {\n if (article \u0026\u0026 article.class_name === 'PodcastEpisode') {\n return `\u003carticle class=\"crayons-story crayons-podcast-episode mb-2\"\u003e\n \u003cdiv class=\"crayons-story__body flex flex-start\"\u003e\n \u003ca href=\"${article.podcast.slug}\" class=\"crayons-podcast-episode__cover\"\u003e\n \u003cimg src=\"${article.podcast.image_url}\" alt=\"${article.podcast.title}\" loading=\"lazy\" /\u003e\n \u003c/a\u003e\n \u003cdiv class=\"pt-2 flex-1\"\u003e\n \u003cp class=\"crayons-podcast-episode__author\"\u003e\n ${article.podcast.title}\n \u003c/p\u003e\n \u003ch2 class=\"crayons-podcast-episode__title crayons-story__title mb-0\"\u003e\n \u003ca href=\"${article.path}\" id=\"article-link-${article.id}\"\u003e\n ${article.podcast.title}\n \u003c/a\u003e\n \u003c/h2\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/article\u003e`;\n }\n\n if (article) {\n var container = document.getElementById('index-container');\n\n var flareTag = '';\n var currentTag = '';\n if (container) {\n currentTag = JSON.parse(container.dataset.params).tag;\n }\n if (article.flare_tag \u0026\u0026 currentTag !== article.flare_tag.name) {\n flareTag = `\u003ca href=\"/t/${article.flare_tag.name}\" \n class=\"crayons-tag crayons-tag--filled\" \n style=\"--tag-bg: ${article.flare_tag.bg_color_hex}1a; --tag-prefix: ${article.flare_tag.bg_color_hex}; --tag-bg-hover: ${article.flare_tag.bg_color_hex}1a; --tag-prefix-hover: ${article.flare_tag.bg_color_hex};\"\n \u003e\n \u003cspan class=\"crayons-tag__prefix\"\u003e#\u003c/span\u003e\n ${article.flare_tag.name}\n \u003c/a\u003e`;\n }\n\n var tagString = '';\n var tagList = article.tag_list || article.cached_tag_list_array || [];\n if (flareTag) {\n tagList = tagList.filter(function (tag) {\n return tag !== article.flare_tag.name;\n });\n tagString += flareTag;\n }\n if (tagList) {\n tagList.forEach(function buildTagString(t) {\n tagString =\n tagString +\n `\u003ca href=\"/t/${t}\" class=\"crayons-tag crayons-tag--monochrome\"\u003e\u003cspan class=\"crayons-tag__prefix\"\u003e#\u003c/span\u003e${t}\u003c/a\u003e\\n`;\n });\n }\n\n var commentsDisplay = '';\n var commentsCount = '0';\n if ((article.comments_count || '0') \u003e 0) {\n commentsCount = article.comments_count || '0';\n }\n\n var commentsAriaLabelText =\n ' aria-label=\"Comments for post ' +\n article.title +\n ' (' +\n commentsCount +\n ')\" ';\n\n if (article.class_name !== 'User') {\n commentsDisplay =\n '\u003ca href=\"' +\n article.path +\n '#comments\"' +\n commentsAriaLabelText +\n 'class=\"crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left \"\u003e\u003csvg class=\"crayons-icon\" width=\"24\" height=\"24\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003cpath d=\"M10.5 5h3a6 6 0 110 12v2.625c-3.75-1.5-9-3.75-9-8.625a6 6 0 016-6zM12 15.5h1.5a4.501 4.501 0 001.722-8.657A4.5 4.5 0 0013.5 6.5h-3A4.5 4.5 0 006 11c0 2.707 1.846 4.475 6 6.36V15.5z\"/\u003e\u003c/svg\u003e';\n if (commentsCount \u003e 0) {\n commentsDisplay +=\n commentsCount +\n '\u003cspan class=\"hidden s:inline\"\u003e\u0026nbsp;comments\u003c/span\u003e\u003c/a\u003e';\n } else {\n commentsDisplay +=\n '\u003cspan class=\"hidden s:inline\"\u003eAdd\u0026nbsp;Comment\u003c/span\u003e\u003c/a\u003e';\n }\n }\n\n var reactionsCount = article.public_reactions_count;\n var reactionsDisplay = '';\n var reactionsText = reactionsCount === 1 ? 'reaction' : 'reactions';\n\n if (article.class_name !== 'User' \u0026\u0026 reactionsCount \u003e 0) {\n reactionsDisplay =\n '\u003ca href=\"' +\n article.path +\n '\"' +\n commentsAriaLabelText +\n 'class=\"crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left\"\u003e\u003csvg class=\"crayons-icon\" width=\"24\" height=\"24\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003cpath d=\"M18.884 12.595l.01.011L12 19.5l-6.894-6.894.01-.01A4.875 4.875 0 0112 5.73a4.875 4.875 0 016.884 6.865zM6.431 7.037a3.375 3.375 0 000 4.773L12 17.38l5.569-5.569a3.375 3.375 0 10-4.773-4.773L9.613 10.22l-1.06-1.062 2.371-2.372a3.375 3.375 0 00-4.492.25v.001z\"/\u003e\u003c/svg\u003e' +\n reactionsCount +\n `\u003cspan class=\"hidden s:inline\"\u003e\u0026nbsp;${reactionsText}\u003c/span\u003e\u003c/a\u003e`;\n }\n\n var picUrl;\n var profileUsername;\n var userName;\n if (article.class_name === 'PodcastEpisode') {\n picUrl = article.main_image;\n profileUsername = article.slug;\n userName = article.title;\n } else {\n picUrl = article.user.profile_image_90;\n profileUsername = article.user.username;\n userName = article.user.name;\n }\n var orgHeadline = '';\n var forOrganization = '';\n var organizationLogo = '';\n var organizationClasses = 'crayons-avatar--l';\n\n if (\n article.organization \u0026\u0026\n !document.getElementById('organization-article-index')\n ) {\n organizationLogo =\n '\u003ca href=\"/' +\n article.organization.slug +\n '\" class=\"crayons-logo crayons-logo--l\"\u003e\u003cimg alt=\"' +\n article.organization.name +\n ' logo\" src=\"' +\n article.organization.profile_image_90 +\n '\" class=\"crayons-logo__image\" loading=\"lazy\"/\u003e\u003c/a\u003e';\n forOrganization =\n '\u003cspan\u003e\u003cspan class=\"crayons-story__tertiary fw-normal\"\u003e for \u003c/span\u003e\u003ca href=\"/' +\n article.organization.slug +\n '\" class=\"crayons-story__secondary fw-medium\"\u003e' +\n article.organization.name +\n '\u003c/a\u003e\u003c/span\u003e';\n organizationClasses =\n 'crayons-avatar--s absolute -right-2 -bottom-2 border-solid border-2 border-base-inverted';\n }\n\n var timeAgoInWords = '';\n if (article.published_at_int) {\n timeAgoInWords = timeAgo({ oldTimeInSeconds: article.published_at_int });\n }\n\n var publishDate = '';\n if (article.readable_publish_date) {\n if (article.published_timestamp) {\n publishDate =\n '\u003ctime datetime=\"' +\n article.published_timestamp +\n '\"\u003e' +\n article.readable_publish_date +\n ' ' +\n timeAgoInWords +\n '\u003c/time\u003e';\n } else {\n publishDate =\n '\u003ctime\u003e' +\n article.readable_publish_date +\n ' ' +\n timeAgoInWords +\n '\u003c/time\u003e';\n }\n }\n\n // We only show profile preview cards for Posts\n var isArticle = article.class_name === 'Article';\n\n var previewCardContent = `\n \u003cdiv id=\"story-author-preview-content-${article.id}\" class=\"profile-preview-card__content crayons-dropdown p-4\" data-repositioning-dropdown=\"true\" style=\"border-top: var(--su-7) solid var(--card-color);\" data-testid=\"profile-preview-card\"\u003e\n \u003cdiv class=\"gap-4 grid\"\u003e\n \u003cdiv class=\"-mt-4\"\u003e\n \u003ca href=\"/${profileUsername}\" class=\"flex\"\u003e\n \u003cspan class=\"crayons-avatar crayons-avatar--xl mr-2 shrink-0\"\u003e\n \u003cimg src=\"${picUrl}\" class=\"crayons-avatar__image\" alt=\"\" loading=\"lazy\" /\u003e\n \u003c/span\u003e\n \u003cspan class=\"crayons-link crayons-subtitle-2 mt-5\"\u003e${article.user.name}\u003c/span\u003e\n \u003c/a\u003e\n \u003c/div\u003e\n \u003cdiv class=\"print-hidden\"\u003e\n \u003cbutton class=\"crayons-btn follow-action-button whitespace-nowrap follow-user w-100\" data-info='{\"id\": ${article.user_id}, \"className\": \"User\", \"style\": \"full\", \"name\": \"${article.user.name}\"}'\u003eFollow\u003c/button\u003e\n \u003c/div\u003e\n \u003cdiv class=\"author-preview-metadata-container\" data-author-id=\"${article.user_id}\"\u003e\u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n `;\n\n var meta = `\n \u003cdiv class=\"crayons-story__meta\"\u003e\n \u003cdiv class=\"crayons-story__author-pic\"\u003e\n ${organizationLogo}\n \u003ca href=\"/${profileUsername}\" class=\"crayons-avatar ${organizationClasses}\"\u003e\n \u003cimg src=\"${picUrl}\" alt=\"${profileUsername} profile\" class=\"crayons-avatar__image\" loading=\"lazy\" /\u003e\n \u003c/a\u003e\n \u003c/div\u003e\n \u003cdiv\u003e\n \u003cdiv\u003e\n \u003ca href=\"/${profileUsername}\" class=\"crayons-story__secondary fw-medium ${\n isArticle ? 'm:hidden' : ''\n }\"\u003e${filterXSS(article.user.name)}\u003c/a\u003e\n ${\n isArticle\n ? `\u003cdiv class=\"profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block\"\u003e\u003cbutton id=\"story-author-preview-trigger-${article.id}\" aria-controls=\"story-author-preview-content-${article.id}\" class=\"profile-preview-card__trigger fs-s crayons-btn crayons-btn--ghost p-1 -ml-1 -my-2\" aria-label=\"${article.user.name} profile details\"\u003e${article.user.name}\u003c/button\u003e${previewCardContent}\u003c/div\u003e`\n : ''\n }\n ${forOrganization}\n \u003c/div\u003e\n \u003ca href=\"${\n article.path\n }\" class=\"crayons-story__tertiary fs-xs\"\u003e${publishDate}\u003c/a\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n `;\n\n var bodyTextSnippet = '';\n var searchSnippetHTML = '';\n if (article.highlight \u0026\u0026 article.highlight.body_text.length \u003e 0) {\n var firstSnippetChar = article.highlight.body_text[0];\n var startingEllipsis = '';\n if (firstSnippetChar.toLowerCase() !== firstSnippetChar.toUpperCase()) {\n startingEllipsis = '…';\n }\n bodyTextSnippet =\n startingEllipsis + article.highlight.body_text.join('...') + '…';\n if (bodyTextSnippet.length \u003e 0) {\n searchSnippetHTML =\n '\u003cdiv class=\"crayons-story__snippet mb-1\"\u003e' +\n bodyTextSnippet +\n '\u003c/div\u003e';\n }\n }\n\n var readingTimeHTML = '';\n if (article.class_name === 'Article') {\n // we have ` ... || null` for the case article.reading_time is undefined\n readingTimeHTML =\n '\u003csmall class=\"crayons-story__tertiary fs-xs mr-2\"\u003e' +\n ((article.reading_time || null) \u003c 1\n ? '1 min'\n : article.reading_time + ' min') +\n ' read\u003c/small\u003e';\n }\n\n var saveButton = '';\n if (article.class_name === 'Article') {\n saveButton =\n '\u003cbutton type=\"button\" id=\"article-save-button-' +\n article.id +\n '\" class=\"crayons-btn crayons-btn--secondary crayons-btn--s bookmark-button\" data-reactable-id=\"' +\n article.id +\n '\"\u003e\\\n \u003cspan class=\"bm-initial\"\u003eSave\u003c/span\u003e\\\n \u003cspan class=\"bm-success\"\u003eSaved\u003c/span\u003e\\\n \u003c/button\u003e';\n } else if (article.class_name === 'User') {\n saveButton = `\n \u003cbutton type=\"button\"\n class=\"crayons-btn crayons-btn--secondary crayons-btn--icon-left fs-s bookmark-button article-engagement-count engage-button follow-action-button follow-user\"\n data-info='{\"id\": ${article.id},\"className\":\"User\", \"name\": \"${article.user.name}\"}'\n data-follow-action-button\u003e\n \u0026nbsp;\n \u003c/button\u003e`;\n }\n\n var videoHTML = '';\n if (article.cloudinary_video_url) {\n videoHTML =\n '\u003ca href=\"' +\n article.path +\n '\" class=\"crayons-story__video\" style=\"background-image:url(' +\n article.cloudinary_video_url +\n ')\"\u003e\u003cdiv class=\"crayons-story__video__time\"\u003e' +\n (article.video_duration_string || article.video_duration_in_minutes) +\n '\u003c/div\u003e\u003c/a\u003e';\n }\n\n var navigationLink = `\n \u003ca\n href=\"${article.path}\"\n aria-labelledby=\"article-link-${article.id}\"\n class=\"crayons-story__hidden-navigation-link\"\n \u003e\n ${filterXSS(article.title)}\n \u003c/a\u003e\n `;\n\n return `\u003carticle class=\"crayons-story\"\n data-article-path=\"${article.path}\"\n id=\"article-${article.id}\"\n data-content-user-id=\"${article.user_id}\"\u003e\\\n ${navigationLink}\\\n \u003cdiv role=\"presentation\"\u003e\\\n ${videoHTML}\\\n \u003cdiv class=\"crayons-story__body\"\u003e\\\n \u003cdiv class=\"crayons-story__top\"\u003e\\\n ${meta}\n \u003c/div\u003e\\\n \u003cdiv class=\"crayons-story__indention\"\u003e\n \u003ch3 class=\"crayons-story__title\"\u003e\n \u003ca href=\"${article.path}\" id=\"article-link-${article.id}\"\u003e\n ${filterXSS(article.title)}\n \u003c/a\u003e\n \u003c/h3\u003e\\\n \u003cdiv class=\"crayons-story__tags\"\u003e\n ${tagString}\n \u003c/div\u003e\\\n ${searchSnippetHTML}\\\n \u003cdiv class=\"crayons-story__bottom\"\u003e\\\n \u003cdiv class=\"crayons-story__details\"\u003e\n ${reactionsDisplay} ${commentsDisplay}\n \u003c/div\u003e\\\n \u003cdiv class=\"crayons-story__save\"\u003e\\\n ${readingTimeHTML}\\\n ${saveButton}\n \u003c/div\u003e\\\n \u003c/div\u003e\\\n \u003c/div\u003e\\\n \u003c/div\u003e\\\n \u003c/div\u003e\\\n \u003c/article\u003e`;\n }\n\n return '';\n}\n\n/* eslint-enable no-multi-str */;\nfunction buildCommentFormHTML(commentableId, commentableType, parentId) {\n var authToken = document.querySelector(\"meta[name='csrf-token']\").getAttribute('content');\n var user = userData();\n var codeOfConductHTML = \"\"\n if (user \u0026\u0026 !user.codeOfConduct \u0026\u0026 user.commentCount \u003c 1){\n codeOfConductHTML = '\u003cdiv class=\"code-of-conduct sub-comment-code-of-conduct\" style=\"display:block\" id=\"toggle-code-of-conduct-checkbox\"\u003e\\\n \u003cinput class=\"checkbox\" type=\"checkbox\" name=\"checked_code_of_conduct\" required /\u003e\\\n \u003clabel for=\"checked_code_of_conduct\"\u003eI\\'ve read the \u003ca href=\"/code-of-conduct\"\u003ecode of conduct\u003c/a\u003e\u003c/label\u003e\\\n \u003c/div\u003e'\n }\n var randomIdNumber = Math.floor(Math.random() * 1991);\n\n return `\u003cform class=\"comment-form pt-4\" onsubmit=\"handleCommentSubmit.bind(this)(event)\" id=\"new-comment-${parentId}\" action=\"/comments\" accept-charset=\"UTF-8\" method=\"post\" data-comment-id=\"${parentId}\"\u003e\n \u003cinput name=\"utf8\" type=\"hidden\" value=\"\u0026#x2713;\" /\u003e\n \u003cinput type=\"hidden\" name=\"authenticity_token\" value=\"${authToken}\"\u003e\n \u003cinput value=\"${commentableId}\" type=\"hidden\" name=\"comment[commentable_id]\" id=\"comment_commentable_id\" /\u003e\n \u003cinput value=\"${commentableType}\" type=\"hidden\" name=\"comment[commentable_type]\" id=\"comment_commentable_type\" /\u003e\n \u003cinput value=\"${parentId}\" type=\"hidden\" name=\"comment[parent_id]\" id=\"comment_parent_id\" /\u003e\n \u003cdiv class=\"comment-form__inner\"\u003e\n \u003cdiv class=\"comment-form__field\"\u003e\n \u003ctextarea id=\"textarea-for-${parentId}\" class=\"crayons-textfield crayons-textfield--ghost comment-textarea\" name=\"comment[body_markdown]\" placeholder=\"Reply...\" aria-label=\"Reply to a comment...\" required=\"required\" onkeydown=\"handleKeyDown(event)\" onfocus=\"handleFocus(event)\" oninput=\"handleChange(event)\" onkeyup=\"handleKeyUp(event)\"\u003e\u003c/textarea\u003e\n \u003cdiv class=\"comment-form__toolbar\"\u003e\n \u003cdiv class=\"editor-image-upload\"\u003e\n \u003cinput type=\"file\" id=\"image-upload-${randomIdNumber}\" name=\"file\" accept=\"image/*\" style=\"display:none\"\u003e\n \u003cbutton type=\"button\" class=\"crayons-btn crayons-btn--s crayons-btn--icon-left crayons-btn--ghost-dimmed\" onclick=\"handleImageUpload(event, ${randomIdNumber})\" id=\"image-upload-button-${randomIdNumber}\"\u003e\n \u003csvg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\" class=\"crayons-icon\"\u003e\u003cpath d=\"M20 5H4v14l9.292-9.294a1 1 0 011.414 0L20 15.01V5zM2 3.993A1 1 0 012.992 3h18.016c.548 0 .992.445.992.993v16.014a1 1 0 01-.992.993H2.992A.993.993 0 012 20.007V3.993zM8 11a2 2 0 110-4 2 2 0 010 4z\"/\u003e\u003c/svg\u003e\n \u003cspan class=\"hidden s:inline-block\"\u003eUpload image\u003c/span\u003e\n \u003c/button\u003e\n \u003clabel class=\"image-upload-file-label\" id=\"image-upload-file-label-${randomIdNumber}\"\u003e\u003c/label\u003e\n \u003cinput type=\"submit\" id=\"image-upload-submit-${randomIdNumber}\" value=\"Upload\" style=\"display:none\"\u003e\n \u003cinput class=\"crayons-textfield fs-s w-auto uploaded-image hidden\" type=\"text\" id=\"uploaded-image-${randomIdNumber}\" /\u003e\n \u003c/div\u003e\n \u003cbutton type=\"button\" class=\"crayons-btn crayons-btn--s crayons-btn--icon-left crayons-btn--ghost-dimmed response-templates-button\" title=\"Use a response template\" data-has-listener=\"false\"\u003e\n \u003csvg width=\"24\" height=\"24\" class=\"crayons-icon\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003cpath d=\"M3 18.5V5a3 3 0 013-3h14a1 1 0 011 1v18a1 1 0 01-1 1H6.5A3.5 3.5 0 013 18.5zM19 20v-3H6.5a1.5 1.5 0 100 3H19zM10 4H6a1 1 0 00-1 1v10.337A3.485 3.485 0 016.5 15H19V4h-2v8l-3.5-2-3.5 2V4z\"/\u003e\u003c/svg\u003e\n \u003cspan class=\"hidden s:inline-block\"\u003eTemplates\u003c/span\u003e\n \u003c/button\u003e\n \u003ca href=\"/p/editor_guide\" class=\"crayons-btn crayons-btn--ghost-dimmed crayons-btn--icon crayons-btn--s ml-auto\" target=\"_blank\" rel=\"noopener\" title=\"Markdown Guide\"\u003e\n \u003csvg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" width=\"24\" height=\"24\" class=\"crayons-icon\"\u003e\u003cpath d=\"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 100-16 8 8 0 000 16zM11 7h2v2h-2V7zm0 4h2v6h-2v-6z\"/\u003e\u003c/svg\u003e\n \u003c/a\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003cdiv class=\"response-templates-container crayons-card crayons-card--secondary p-4 mb-4 fs-base comment-form__templates hidden\"\u003e\n \u003cheader\u003e\n \u003cbutton type=\"button\" class=\"personal-template-button active\" data-target-type=\"personal\" data-form-id=\"new_comment\"\u003ePersonal\u003c/button\u003e\n \u003cbutton type=\"button\" class=\"moderator-template-button hidden\" data-target-type=\"moderator\" data-form-id=\"new_comment\"\u003eModerator\u003c/button\u003e\n \u003c/header\u003e\n \u003cimg class=\"loading-img hidden\" src=\"/assets/loading-ellipsis-b714cf681fd66c853ff6f03dd161b77aa3c80e03cdc06f478b695f42770421e9.svg\" alt=\"loading\"\u003e\n \u003cdiv class=\"personal-responses-container\"\u003e\u003c/div\u003e\n \u003cdiv class=\"moderator-responses-container hidden\"\u003e\u003c/div\u003e\n \u003ca target=\"_blank\" rel=\"noopener nofollow\" href=\"/settings/response-templates\"\u003eCreate template\u003c/a\u003e\n \u003cp\u003eTemplates let you quickly answer FAQs or store snippets for re-use.\u003c/p\u003e\n \u003c/div\u003e\n \u003cdiv class=\"comment-form__preview text-styles text-styles--secondary\"\u003e\u003c/div\u003e\n \u003cdiv class=\"comment-form__buttons mb-4 whitespace-nowrap\"\u003e\n \u003cbutton type=\"submit\" class=\"crayons-btn comment-action-button mr-2 js-btn-enable\" name=\"submit\" disabled\u003eSubmit\u003c/button\u003e\n \u003cbutton type=\"button\" class=\"preview-toggle crayons-btn crayons-btn--secondary comment-action-button comment-action-preview mr-2 js-btn-enable\" onclick=\"handleCommentPreview(event)\" disabled\u003ePreview\u003c/button\u003e\n \u003cbutton type=\"button\" class=\"crayons-btn crayons-btn--ghost\" onclick=\"handleFormClose(event)\"\u003eDismiss\u003c/button\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/form\u003e`;\n};\nfunction buildCommentHTML(comment) {\n var iconSmallOverflowHorizontal = `\u003csvg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" class=\"crayons-icon pointer-events-none\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003cpath fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M8.25 12a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm5.25 0a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zm3.75 1.5a1.5 1.5 0 100-3 1.5 1.5 0 000 3z\" /\u003e\u003c/svg\u003e`;\n var iconCollapse = `\u003csvg width=\"24\" height=\"24\" class=\"crayons-icon expanded\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003cpath d=\"M12 10.6771L8 6.93529L8.99982 6L12 8.80653L15.0002 6L16 6.93529L12 10.6771ZM12 15.1935L8.99982 18L8 17.0647L12 13.3229L16 17.0647L15.0002 17.9993L12 15.1935Z\" /\u003e\u003c/svg\u003e`;\n var iconExpand = `\u003csvg width=\"24\" height=\"24\" class=\"crayons-icon collapsed\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\"\u003e\u003cpath d=\"M12 18L8 14.2287L8.99982 13.286L12 16.1147L15.0002 13.286L16 14.2287L12 18ZM12 7.88533L8.99982 10.714L8 9.77133L12 6L16 9.77133L15.0002 10.7133L12 7.88533Z\" /\u003e\u003c/svg\u003e`;\n\n var depthClass = \"\";\n var customClass = \"\";\n\n var detailsStartHTML = \"\";\n var detailsEndHTML = \"\";\n\n var commentHeader = \"\";\n var commentFooter = \"\";\n var commentAvatar = \"\";\n var commentBody = \"\";\n\n if ( comment.depth == 0 ) {\n depthClass += \"root \";\n } else {\n depthClass += \"child \"\n }\n\n if ( comment.depth \u003e 3 ) {\n depthClass += \"comment--too-deep \";\n }\n\n if (comment.newly_created) {\n customClass = \"comment-created-via-fetch\"\n }\n\n if (comment.depth \u003c 3) {\n detailsStartHTML = `\n \u003cdetails class=\"comment-wrapper comment-wrapper--deep-${ comment.depth } js-comment-wrapper\" open\u003e\n \u003csummary aria-label=\"Toggle this comment (and replies)\"\u003e\n \u003cspan class=\"inline-block align-middle ${ comment.depth \u003e 0 ? 'mx-0' : 'm:mx-1'}\"\u003e\n ${ iconCollapse }\n ${ iconExpand }\n \u003c/span\u003e\n \u003cspan class=\"js-collapse-comment-content inline-block align-middle\"\u003e\u003c/span\u003e\n \u003c/summary\u003e\n `;\n detailsEndHTML = `\u003c/details\u003e`;\n }\n\n commentAvatar = `\u003ca href=\"/${ comment.user.username }\" class=\"shrink-0 crayons-avatar ${ comment.depth == 0 ? 'm:crayons-avatar--l mt-4 m:mt-3' : 'mt-4' }\"\u003e\n \u003cimg class=\"crayons-avatar__image\" width=\"32\" height=\"32\" src=\"${ comment.user.profile_pic }\" alt=\"${ comment.user.username } profile\" /\u003e\n \u003c/a\u003e`;\n\n commentHeader = `\u003cdiv class=\"comment__header\" \u003e\n \u003ca href=\"/${ comment.user.username }\" class=\"crayons-link crayons-link--secondary flex items-center fw-medium m:hidden\"\u003e\n \u003cspan class=\"js-comment-username\"\u003e${ comment.user.name }\u003c/span\u003e\n \u003c/a\u003e\n \u003cdiv class=\"profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:block\"\u003e\n \u003cbutton id=\"comment-profile-preview-trigger-${comment.id}\" aria-controls=\"comment-profile-preview-content-${comment.id}\" class=\"profile-preview-card__trigger p-1 -my-1 -ml-1 crayons-btn crayons-btn--ghost\" aria-label=\"${comment.user.name} profile details\"\u003e${comment.user.name}\u003c/button\u003e\n \u003cspan data-js-comment-user-id=\"${comment.user.id}\" data-js-dropdown-content-id=\"comment-profile-preview-content-${comment.id}\" class=\"preview-card-placeholder\"\u003e\u003c/span\u003e\n \u003c/div\u003e\n \u003cspan class=\"color-base-30 px-2 m:pl-0\" role=\"presentation\"\u003e\u0026bull;\u003c/span\u003e\n\n \u003ca href=\"${ comment.url }\" class=\"comment-date crayons-link crayons-link--secondary fs-s\"\u003e\n \u003ctime datetime=\"${ comment.published_timestamp }\"\u003e\n ${ comment.readable_publish_date }\n \u003c/time\u003e\n \u003c/a\u003e\n\n \u003cdiv class=\"comment__dropdown\"\u003e\n \u003cbutton id=\"comment-dropdown-trigger-${comment.id}\" aria-controls=\"comment-dropdown-${comment.id}\" aria-expanded=\"false\" class=\"dropbtn comment__dropdown-trigger crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon\" aria-label=\"Toggle dropdown menu\" aria-haspopup=\"true\"\u003e\n ${ iconSmallOverflowHorizontal }\n \u003c/button\u003e\n \u003cdiv id=\"comment-dropdown-${comment.id}\" class=\"crayons-dropdown right-1 s:right-0 s:left-auto fs-base dropdown\"\u003e\n \u003cul class=\"m-0\"\u003e\n \u003cli\u003e\u003ca href=\"${ comment.url }\" class=\"crayons-link crayons-link--block permalink-copybtn\" aria-label=\"Copy link to ${ comment.user.name }'s comment\" data-no-instant\u003e${ I18n.t('core.copy_link') }\u003c/a\u003e\u003c/li\u003e\n \u003cli\u003e\u003ca href=\"${ comment.url }/settings\" class=\"crayons-link crayons-link--block\" aria-label=\"Go to ${ comment.user.name }'s comment settings\"\u003eSettings\u003c/a\u003e\u003c/li\u003e\n \u003cli\u003e\u003ca href=\"/report-abuse?url=${ comment.url }\" class=\"crayons-link crayons-link--block\" aria-label=\"Report ${ comment.user.name }'s comment as abusive or violating our code of conduct and/or terms and conditions\"\u003e${ I18n.t('core.report_abuse') }\u003c/a\u003e\u003c/li\u003e\n \u003cli class=\"${ comment.newly_created ? '' : 'hidden' }\"\u003e\u003ca href=\"${ comment.url }/edit\" class=\"crayons-link crayons-link--block\" rel=\"nofollow\" aria-label=\"Edit this comment\"\u003eEdit\u003c/a\u003e\u003c/li\u003e\n \u003cli class=\"${ comment.newly_created ? '' : 'hidden' }\"\u003e\u003ca data-no-instant=\"\" href=\"${ comment.url }/delete_confirm\" class=\"crayons-link crayons-link--block\" rel=\"nofollow\" aria-label=\"Delete this comment\"\u003eDelete\u003c/a\u003e\u003c/li\u003e\n \u003c/ul\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e`;\n\n commentFooter = `\u003cfooter class=\"comment__footer\"\u003e\n ${ react(comment) }\n ${ reply(comment) }\n \u003c/footer\u003e`;\n\n commentBody = `${ detailsStartHTML }\n \u003cdiv class=\"comment single-comment-node ${ depthClass } comment--deep-${ comment.depth }\" id=\"comment-node-${ comment.id }\" data-comment-id=\"${ comment.id }\" data-path=\"${ comment.url }\" data-comment-author-id=\"${ comment.user.id }\" data-current-user-comment=\"${ comment.newly_created }\" data-content-user-id=\"${ comment.user.id }\"\u003e\n \u003cdiv class=\"comment__inner\"\u003e\n ${ commentAvatar }\n \u003cdiv class=\"inner-comment comment__details\"\u003e\n \u003cdiv class=\"comment__content crayons-card\"\u003e\n ${ commentHeader }\n \u003cdiv class=\"comment__body text-styles text-styles--secondary body\"\u003e\n ${ comment.body_html }\n \u003c/div\u003e\n \u003c/div\u003e\n ${ commentFooter }\n \u003c/div\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n ${ detailsEndHTML }`;\n\n return commentBody;\n}\n\nfunction reply(comment) {\n var iconSmallComment = `\u003csvg width=\"24\" height=\"24\" xmlns=\"http://www.w3.org/2000/svg\" class=\"crayons-icon reaction-icon not-reacted\"\u003e\u003cpath d=\"M10.5 5h3a6 6 0 110 12v2.625c-3.75-1.5-9-3.75-9-8.625a6 6 0 016-6zM12 15.5h1.5a4.501 4.501 0 001.722-8.657A4.5 4.5 0 0013.5 6.5h-3A4.5 4.5 0 006 11c0 2.707 1.846 4.475 6 6.36V15.5z\"/\u003e\u003c/svg\u003e`;\n var replyButton = `\u003ca class=\"js actions crayons-btn crayons-btn--ghost crayons-btn--s crayons-btn--icon-left toggle-reply-form mr-1 inline-flex\"\n href=\"#${ comment.url }\"\n data-comment-id=\"${ comment.id }\"\n data-path=\"${ comment.url }\"\n rel=\"nofollow\"\u003e\n ${ iconSmallComment }\n \u003cspan class=\"hidden m:inline-block\"\u003eReply\u003c/span\u003e\n \u003c/a\u003e`;\n if (comment.newly_created) {\n return replyButton;\n }\n}\n\nfunction react(comment) {\n var reactedClass = \"\";\n var num = 1;\n var iconSmallHeart = `\u003csvg width=\"24\" height=\"24\" xmlns=\"http://www.w3.org/2000/svg\" class=\"crayons-icon reaction-icon not-reacted\"\u003e\u003cpath d=\"M18.884 12.595l.01.011L12 19.5l-6.894-6.894.01-.01A4.875 4.875 0 0112 5.73a4.875 4.875 0 016.884 6.865zM6.431 7.037a3.375 3.375 0 000 4.773L12 17.38l5.569-5.569a3.375 3.375 0 10-4.773-4.773L9.613 10.22l-1.06-1.062 2.371-2.372a3.375 3.375 0 00-4.492.25v.001z\"/\u003e\u003c/svg\u003e`;\n var iconSmallHeartFilled = `\u003csvg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" xmlns=\"http://www.w3.org/2000/svg\" class=\"crayons-icon reaction-icon--like reaction-icon reacted\"\u003e\u003cpath d=\"M5.116 12.595a4.875 4.875 0 015.56-7.68h-.002L7.493 8.098l1.06 1.061 3.181-3.182a4.875 4.875 0 016.895 6.894L12 19.5l-6.894-6.894.01-.01z\"/\u003e\u003c/svg\u003e`;\n\n if (!comment.newly_created \u0026\u0026 comment.heart_ids.indexOf(userData().id) \u003e -1) {\n reactedClass = \"reacted\"\n }\n\n if (!comment.newly_created) {\n num = comment.public_reactions_count;\n }\n\n var reactButton = `\u003cbutton class=\"crayons-btn crayons-btn--ghost crayons-btn--icon-left crayons-btn--s mr-1 reaction-like inline-flex reaction-button\" id=\"button-for-comment-${ comment.id }\" data-comment-id=\"${ comment.id }\"\u003e\n ${ iconSmallHeart }\n ${ iconSmallHeartFilled }\n \u003cspan class=\"reactions-count\" id=\"reactions-count-${ comment.id }\"\u003e${ num }\u003c/span\u003e\n \u003cspan class=\"reactions-label hidden m:inline-block\"\u003elike\u003c/span\u003e\n \u003c/button\u003e`;\n\n return reactButton;\n};\nfunction checkUserLoggedIn() {\n const body = document.body;\n if (!body) {\n return false;\n }\n\n return body.getAttribute('data-user-status') === 'logged-in';\n};\nfunction dynamicallyLoadScript(url) {\n if (document.querySelector(`script[src='${url}']`)) return;\n\n const script = document.createElement('script');\n script.src = url;\n\n document.head.appendChild(script);\n};\n/* global Honeybadger */\n\nfunction getCsrfToken() {\n var promise = new Promise(function callback(resolve, reject) {\n var i = 0;\n // eslint-disable-next-line consistent-return\n var waitingOnCSRF = setInterval(function waitOnCSRF() {\n var metaTag = document.querySelector(\"meta[name='csrf-token']\");\n i += 1;\n\n if (metaTag) {\n clearInterval(waitingOnCSRF);\n var authToken = metaTag.getAttribute('content');\n return resolve(authToken);\n }\n\n if (i === 1000) {\n clearInterval(waitingOnCSRF);\n Honeybadger.notify(\n 'Could not locate CSRF metatag ' +\n JSON.stringify(localStorage.current_user),\n );\n return reject(new Error('Could not locate CSRF meta tag on the page.'));\n }\n }, 5);\n });\n return promise;\n};\n'use strict';\n\nfunction getCurrentPage(classString) {\n return (\n document.querySelectorAll(\"[data-current-page='\" + classString + \"']\")\n .length \u003e 0\n );\n};\n'use strict';\n\nvar $fetchedImageUrls = [];\nfunction getImageForLink(elem) {\n var imageUrl = elem.getAttribute('data-preload-image');\n if (imageUrl \u0026\u0026 $fetchedImageUrls.indexOf(imageUrl) === -1) {\n var img = new Image();\n img.src = imageUrl;\n $fetchedImageUrls.push(imageUrl);\n }\n};\n'use strict';\n\nfunction insertAfter(newNode, referenceNode) {\n if (referenceNode \u0026\u0026 referenceNode.parentNode) {\n referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);\n }\n};\n'use strict';\n\n/* Local date/time utilities */\n\n/*\n Convert string timestamp to local time, using the given locale.\n\n timestamp should be something like '2019-05-03T16:02:50.908Z'\n locale can be `navigator.language` or a custom locale. defaults to 'default'\n options are `Intl.DateTimeFormat` options\n\n see \u003chttps://developer.mozilla.org//docs/Web/JavaScript/Reference/Global_Objects/DateTimeFormat\u003e\n for more information.\n*/\nfunction timestampToLocalDateTime(timestamp, locale, options) {\n if (!timestamp) {\n return '';\n }\n\n try {\n var time = new Date(timestamp);\n return new Intl.DateTimeFormat(locale || 'default', options).format(time);\n } catch (e) {\n return '';\n }\n}\n\nfunction addLocalizedDateTimeToElementsTitles(elements, timestampAttribute) {\n for (var i = 0; i \u003c elements.length; i += 1) {\n var element = elements[i];\n\n // get UTC timestamp set by the server\n var timestamp = element.getAttribute(timestampAttribute || 'datetime');\n\n if (timestamp) {\n // add a full datetime to the element title, visible on hover.\n // `navigator.language` is used to allow the date to be localized\n // according to the browser's locale\n // see \u003chttps://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/language\u003e\n var localDateTime = timestampToLocalDateTimeLong(timestamp);\n element.setAttribute('title', localDateTime);\n }\n }\n}\n\nfunction localizeTimeElements(elements, timeOptions) {\n for (let i = 0; i \u003c elements.length; i += 1) {\n const element = elements[i];\n\n const timestamp = element.getAttribute('datetime');\n if (timestamp) {\n const localDateTime = timestampToLocalDateTime(\n timestamp,\n navigator.language,\n timeOptions,\n );\n\n element.textContent = localDateTime;\n }\n }\n}\n\nfunction timestampToLocalDateTimeLong(timestamp) {\n // example: \"Wednesday, April 3, 2019, 2:55:14 PM\"\n\n return timestampToLocalDateTime(timestamp, navigator.language, {\n weekday: 'long',\n year: 'numeric',\n month: 'long',\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n second: 'numeric',\n });\n}\n\nfunction timestampToLocalDateTimeShort(timestamp) {\n // example: \"10 Dec 2018\" if it is not the current year\n // example: \"6 Sep\" if it is the current year\n\n if (timestamp) {\n const currentYear = new Date().getFullYear();\n const givenYear = new Date(timestamp).getFullYear();\n\n var timeOptions = {\n day: 'numeric',\n month: 'short',\n };\n\n if (givenYear !== currentYear) {\n timeOptions.year = 'numeric';\n }\n\n return timestampToLocalDateTime(timestamp, navigator.language, timeOptions);\n }\n\n return '';\n}\n\nif (typeof globalThis !== 'undefined') {\n globalThis.timestampToLocalDateTimeLong = timestampToLocalDateTimeLong; // eslint-disable-line no-undef\n globalThis.timestampToLocalDateTimeShort = timestampToLocalDateTimeShort; // eslint-disable-line no-undef\n};\n'use strict';\n\nfunction localStorageTest() {\n var test = 'devtolocalstoragetestforavaialbility';\n try {\n localStorage.setItem(test, test);\n localStorage.removeItem(test);\n return true;\n } catch (e) {\n return false;\n }\n};\n'use strict';\n\nfunction preventDefaultAction(event) {\n event.preventDefault();\n};\n'use strict';\n\nconst fetchCallback = ({ url, headers = {}, addTokenToBody = false, body }) =\u003e {\n return (csrfToken) =\u003e {\n if (addTokenToBody) {\n body.append('authenticity_token', csrfToken);\n }\n return window.fetch(url, {\n method: 'POST',\n headers: {\n 'X-CSRF-Token': csrfToken,\n ...headers,\n },\n body,\n credentials: 'same-origin',\n });\n };\n};\n\nfunction sendFetch(switchStatement, body) {\n switch (switchStatement) {\n case 'article-preview':\n return fetchCallback({\n url: '/articles/preview',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n body,\n });\n case 'reaction-creation':\n return fetchCallback({\n url: '/reactions',\n addTokenToBody: true,\n body,\n });\n case 'image-upload':\n return fetchCallback({\n url: '/image_uploads',\n addTokenToBody: true,\n body,\n });\n case 'follow-creation':\n return fetchCallback({\n url: '/follows',\n addTokenToBody: true,\n body,\n });\n case 'block-user':\n return fetchCallback({\n url: '/user_blocks',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/json',\n },\n addTokenToBody: false,\n body,\n });\n case 'comment-creation':\n return fetchCallback({\n url: '/comments',\n headers: {\n 'Content-Type': 'application/json',\n },\n body,\n });\n case 'comment-preview':\n return fetchCallback({\n url: '/comments/preview',\n headers: {\n 'Content-Type': 'application/json',\n },\n body,\n });\n default:\n console.log('A wrong switchStatement was used.'); // eslint-disable-line no-console\n break;\n }\n return true;\n};\n'use strict';\n\nfunction sendHapticMessage(message) {\n try {\n if (\n window \u0026\u0026\n window.webkit \u0026\u0026\n window.webkit.messageHandlers \u0026\u0026\n window.webkit.messageHandlers.haptic\n ) {\n window.webkit.messageHandlers.haptic.postMessage(message);\n }\n } catch (err) {\n console.log(err.message); // eslint-disable-line no-console\n }\n};\nfunction showLoginModal() {\n window.Forem.showModal({\n title: 'Log in to continue',\n contentSelector: '#global-signup-modal',\n overlay: true,\n });\n};\n/**\n * HTML ID for modal DOM node\n *\n * @private\n * @constant modalId *\n * @type {string}\n */\nconst modalId = 'user-alert-modal';\n\n/**\n * Displays a general purpose user alert modal with a title, body text, and confirmation button.\n *\n * @function showUserAlertModal\n * @param {string} title The title/heading text to be displayed\n * @param {string} text The body text to be displayed\n * @param {string} confirm_text Text of the confirmation button\n *\n * @example\n * showUserAlertModal('Warning', 'You must wait', 'OK', '/faq/why-must-i-wait', 'Why must I wait?');\n */\nfunction showUserAlertModal(title, text, confirm_text) {\n buildModalDiv(text, confirm_text);\n window.Forem.showModal({\n title,\n contentSelector: `#${modalId}`,\n overlay: true,\n });\n}\n/**\n * Displays a user rate limit alert modal letting the user know what they did that exceeded a rate limit,\n * and gives them links to explain why they must wait\n *\n * @function showRateLimitModal\n * @param {string} element Description of the element that throw the error\n * @param {string} action_ing The -ing form of the action taken by the user\n * @param {string} action_past The past tense of the action taken by the user\n * @param {string} timeframe Description of the time that we need to wait\n *\n * @example\n * showRateLimitModal('Made a comment', 'comment again')\n */\nfunction showRateLimitModal({\n element,\n action_ing,\n action_past,\n timeframe = 'a moment',\n}) {\n let rateLimitText = buildRateLimitText({\n element,\n action_ing,\n action_past,\n timeframe,\n });\n let rateLimitLink = '/faq';\n showUserAlertModal(\n `Wait ${timeframe}...`,\n rateLimitText,\n 'Got it',\n rateLimitLink,\n 'Why do I have to wait?',\n );\n}\n/**\n * Displays the corresponding modal after an error.\n *\n * @function showModalAfterError\n * @param {Object} response The response from the API\n * @param {string} element Description of the element that throw the error\n * @param {string} action_ing The -ing form of the action taken by the user\n * @param {string} action_past The past tense of the action taken by the user\n * @param {string} timeframe Description of the time that we need to wait\n *\n * @example\n * showModalAfterError(response, 'made a comment', 'making another comment', 'a moment');\n */\nfunction showModalAfterError({\n response,\n element,\n action_ing,\n action_past,\n timeframe = 'a moment',\n}) {\n response\n .json()\n .then(function parseError(errorResponse) {\n if (response.status === 429) {\n showRateLimitModal({ element, action_ing, action_past, timeframe });\n } else {\n showUserAlertModal(\n `Error ${action_ing} ${element}`,\n `Your ${element} could not be ${action_past} due to an error: ` +\n errorResponse.error,\n 'OK',\n );\n }\n })\n .catch(function parseError(error) {\n showUserAlertModal(\n `Error ${action_ing} ${element}`,\n `Your ${element} could not be ${action_past} due to a server error`,\n 'OK',\n );\n });\n}\n\n/**\n * HTML template for modal\n *\n * @private\n * @function getModalHtml\n *\n * @param {string} text The body text to be displayed\n * @param {string} confirm_text Text of the confirmation button\n *\n * @returns {string} HTML for the modal\n */\nconst getModalHtml = (text, confirm_text) =\u003e `\n \u003cdiv id=\"${modalId}\" hidden\u003e\n \u003cdiv class=\"flex flex-col\"\u003e\n \u003cp class=\"color-base-70\"\u003e\n ${text}\n \u003c/p\u003e\n \u003cbutton class=\"crayons-btn mt-4 ml-auto\" type=\"button\" onClick=\"window.Forem.closeModal()\"\u003e\n ${confirm_text}\n \u003c/button\u003e\n \u003c/div\u003e\n \u003c/div\u003e\n `;\n\n/**\n * Constructs wording for rate limit modals\n *\n * @private\n * @function buildRateLimitText\n *\n * @param {string} element Description of the element that throw the error\n * @param {string} action_ing The -ing form of the action taken by the user\n * @param {string} action_past The past tense of the action taken by the user\n * @param {string} timeframe Description of the time that we need to wait\n *\n * @returns {string} Formatted body text for a rate limit modal\n */\nfunction buildRateLimitText({ element, action_ing, action_past, timeframe }) {\n return `Since you recently ${action_past} a ${element}, you’ll need to wait ${timeframe} before ${action_ing} another ${element}.`;\n}\n\n/**\n * Checks for the alert modal, and if it's not present builds and inserts it in the DOM\n *\n * @private\n * @function buildModalDiv\n *\n * @param {string} text The body text to be displayed\n * @param {string} confirm_text Text of the confirmation button\n *\n * @returns {Element} DOM node of the inserted alert modal\n */\nfunction buildModalDiv(text, confirm_text) {\n let modalDiv = document.getElementById(modalId);\n if (!modalDiv) {\n modalDiv = getModal(text, confirm_text);\n document.body.appendChild(modalDiv);\n } else {\n modalDiv.outerHTML = getModal(text, confirm_text).outerHTML;\n }\n return modalDiv;\n}\n\n/**\n * Takes template HTML for a modal and creates a DOM node based on supplied arguments\n *\n * @private\n * @function getModal\n *\n * @param {string} text The body text to be displayed\n * @param {string} confirm_text Text of the confirmation button\n *\n * @returns {Element} DOM node of alert modal with formatted text\n */\nfunction getModal(text, confirm_text) {\n let wrapper = document.createElement('div');\n wrapper.innerHTML = getModalHtml(text, confirm_text);\n return wrapper;\n};\nfunction slideSidebar(side, direction) {\n if (!document.getElementById('sidebar-wrapper-' + side)) {\n return;\n }\n const mainContent =\n document.getElementById('main-content') ||\n document.getElementById('articles-list');\n if (direction === 'intoView') {\n mainContent.classList.add('modal-open');\n document.body.classList.add('modal-open');\n document\n .getElementById('sidebar-wrapper-' + side)\n .classList.add('swiped-in');\n mainContent.addEventListener('touchmove', preventDefaultAction, false);\n } else {\n mainContent.classList.remove('modal-open');\n document.body.classList.remove('modal-open');\n document\n .getElementById('sidebar-wrapper-' + side)\n .classList.remove('swiped-in');\n mainContent.removeEventListener('touchmove', preventDefaultAction, false);\n }\n};\n'use strict';\n\nfunction secondsToHumanUnitAgo(seconds) {\n const times = [\n ['second', 1],\n ['min', 60],\n ['hour', 60 * 60],\n ['day', 60 * 60 * 24],\n ['week', 60 * 60 * 24 * 7],\n ['month', 60 * 60 * 24 * 30],\n ['year', 60 * 60 * 24 * 365],\n ];\n\n if (seconds \u003c times[0][1]) return 'just now';\n\n let scale = 0;\n // If the amount of seconds is more than a minute, we change the scale to minutes\n // If the amount of seconds then is more than an hour, we change the scale to hours\n // This continues until the unit above our current scale is longer than `seconds`, or doesn't exist\n while (scale + 1 \u003c times.length \u0026\u0026 seconds \u003e= times[scale + 1][1]) scale += 1;\n\n const wholeUnits = Math.floor(seconds / times[scale][1]);\n const unitName = times[scale][0] + (wholeUnits === 1 ? '' : 's');\n\n return wholeUnits + ' ' + unitName + ' ago';\n}\n\n/**\n * Returns a given time in seconds as a human readable form, e.g. (5 min ago)\n *\n * @param {object} options\n * @param {number} options.oldTimeInSeconds\n * @param {function} [(humanTime) =\u003e\n `\u003cspan class=\"time-ago-indicator\"\u003e(${humanTime})\u003c/span\u003e`] options.formatter\n * @param {number} [60 * 60 * 24 - 1] options.maxDisplayedAge The maximum display age in seconds\n *\n * @returns {string} A formatted string in human readable form. Note that the default formatter returns a string with markup in it.\n */\nfunction timeAgo({\n oldTimeInSeconds,\n formatter = (humanTime) =\u003e\n `\u003cspan class=\"time-ago-indicator\"\u003e(${humanTime})\u003c/span\u003e`,\n maxDisplayedAge = 60 * 60 * 24 - 1,\n}) {\n const timeNow = new Date() / 1000;\n const diff = Math.round(timeNow - oldTimeInSeconds);\n\n if (diff \u003e maxDisplayedAge) return '';\n\n return formatter(secondsToHumanUnitAgo(diff));\n}\n\n// TODO: This is for Storybook/jest.\n// Longterm, this should be a utility function that can be imported.\n// For the time being, duplication of this function is being avoided.\nif (typeof globalThis !== 'undefined') {\n globalThis.timeAgo = timeAgo; // eslint-disable-line no-undef\n};\n'use strict';\n\nfunction userData() {\n const { user = null } = document.body.dataset;\n\n return JSON.parse(user);\n};\n(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"\u0026\u0026require;if(!u\u0026\u0026a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"\u0026\u0026require;for(var o=0;o\u003cr.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n/**\n * 默认配置\n *\n * @author 老雷\u003cleizongmin@gmail.com\u003e\n */\n\nvar FilterCSS = require('cssfilter').FilterCSS;\nvar getDefaultCSSWhiteList = require('cssfilter').getDefaultWhiteList;\nvar _ = require('./util');\n\n// 默认白名单\nfunction getDefaultWhiteList () {\n return {\n // // a: ['target', 'href', 'title'],\n // abbr: ['title'],\n // address: [],\n // area: ['shape', 'coords', 'href', 'alt'],\n // article: [],\n // aside: [],\n // audio: ['autoplay', 'controls', 'loop', 'preload', 'src'],\n // b: [],\n // bdi: ['dir'],\n // bdo: ['dir'],\n // big: [],\n // blockquote: ['cite'],\n // br: [],\n // caption: [],\n // center: [],\n // cite: [],\n // code: [],\n // col: ['align', 'valign', 'span', 'width'],\n // colgroup: ['align', 'valign', 'span', 'width'],\n // dd: [],\n // del: ['datetime'],\n // details: ['open'],\n // div: [],\n // dl: [],\n // dt: [],\n // em: [],\n // font: ['color', 'size', 'face'],\n // footer: [],\n // h1: [],\n // h2: [],\n // h3: [],\n // h4: [],\n // h5: [],\n // h6: [],\n // header: [],\n // hr: [],\n // i: [],\n // // img: ['src', 'alt', 'title', 'width', 'height'],\n // ins: ['datetime'],\n // li: [],\n // mark: [],\n // nav: [],\n // ol: [],\n // p: [],\n // pre: [],\n // s: [],\n // section:[],\n // small: [],\n // span: [],\n // sub: [],\n // sup: [],\n // strong: [],\n // table: ['width', 'border', 'align', 'valign'],\n // tbody: ['align', 'valign'],\n // td: ['width', 'rowspan', 'colspan', 'align', 'valign'],\n // tfoot: ['align', 'valign'],\n // th: ['width', 'rowspan', 'colspan', 'align', 'valign'],\n // thead: ['align', 'valign'],\n // tr: ['rowspan', 'align', 'valign'],\n // tt: [],\n // u: [],\n // ul: [],\n // video: ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width']\n };\n}\n\n// 默认CSS Filter\nvar defaultCSSFilter = new FilterCSS();\n\n/**\n * 匹配到标签时的处理方法\n *\n * @param {String} tag\n * @param {String} html\n * @param {Object} options\n * @return {String}\n */\nfunction onTag (tag, html, options) {\n // do nothing\n}\n\n/**\n * 匹配到不在白名单上的标签时的处理方法\n *\n * @param {String} tag\n * @param {String} html\n * @param {Object} options\n * @return {String}\n */\nfunction onIgnoreTag (tag, html, options) {\n // do nothing\n}\n\n/**\n * 匹配到标签属性时的处理方法\n *\n * @param {String} tag\n * @param {String} name\n * @param {String} value\n * @return {String}\n */\nfunction onTagAttr (tag, name, value) {\n // do nothing\n}\n\n/**\n * 匹配到不在白名单上的标签属性时的处理方法\n *\n * @param {String} tag\n * @param {String} name\n * @param {String} value\n * @return {String}\n */\nfunction onIgnoreTagAttr (tag, name, value) {\n // do nothing\n}\n\n/**\n * HTML转义\n *\n * @param {String} html\n */\nfunction escapeHtml (html) {\n return html.replace(REGEXP_LT, '\u0026lt;').replace(REGEXP_GT, '\u0026gt;');\n}\n\n/**\n * 安全的标签属性值\n *\n * @param {String} tag\n * @param {String} name\n * @param {String} value\n * @param {Object} cssFilter\n * @return {String}\n */\nfunction safeAttrValue (tag, name, value, cssFilter) {\n // 转换为友好的属性值,再做判断\n value = friendlyAttrValue(value);\n\n if (name === 'href' || name === 'src') {\n // 过滤 href 和 src 属性\n // 仅允许 http:// | https:// | mailto: | / | # 开头的地址\n value = _.trim(value);\n if (value === '#') return '#';\n if (!(value.substr(0, 7) === 'http://' ||\n value.substr(0, 8) === 'https://' ||\n value.substr(0, 7) === 'mailto:' ||\n value[0] === '#' ||\n value[0] === '/')) {\n return '';\n }\n } else if (name === 'background') {\n // 过滤 background 属性 (这个xss漏洞较老了,可能已经不适用)\n // javascript:\n REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0;\n if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) {\n return '';\n }\n } else if (name === 'style') {\n // /*注释*/\n /*REGEXP_DEFAULT_ON_TAG_ATTR_3.lastIndex = 0;\n if (REGEXP_DEFAULT_ON_TAG_ATTR_3.test(value)) {\n return '';\n }*/\n // expression()\n REGEXP_DEFAULT_ON_TAG_ATTR_7.lastIndex = 0;\n if (REGEXP_DEFAULT_ON_TAG_ATTR_7.test(value)) {\n return '';\n }\n // url()\n REGEXP_DEFAULT_ON_TAG_ATTR_8.lastIndex = 0;\n if (REGEXP_DEFAULT_ON_TAG_ATTR_8.test(value)) {\n REGEXP_DEFAULT_ON_TAG_ATTR_4.lastIndex = 0;\n if (REGEXP_DEFAULT_ON_TAG_ATTR_4.test(value)) {\n return '';\n }\n }\n if (cssFilter !== false) {\n cssFilter = cssFilter || defaultCSSFilter;\n value = cssFilter.process(value);\n }\n }\n\n // 输出时需要转义\u003c\u003e\"\n value = escapeAttrValue(value);\n return value;\n}\n\n// 正则表达式\nvar REGEXP_LT = /\u003c/g;\nvar REGEXP_GT = /\u003e/g;\nvar REGEXP_QUOTE = /\"/g;\nvar REGEXP_QUOTE_2 = /\u0026quot;/g;\nvar REGEXP_ATTR_VALUE_1 = /\u0026#([a-zA-Z0-9]*);?/img;\nvar REGEXP_ATTR_VALUE_COLON = /\u0026colon;?/img;\nvar REGEXP_ATTR_VALUE_NEWLINE = /\u0026newline;?/img;\nvar REGEXP_DEFAULT_ON_TAG_ATTR_3 = /\\/\\*|\\*\\//mg;\nvar REGEXP_DEFAULT_ON_TAG_ATTR_4 = /((j\\s*a\\s*v\\s*a|v\\s*b|l\\s*i\\s*v\\s*e)\\s*s\\s*c\\s*r\\s*i\\s*p\\s*t\\s*|m\\s*o\\s*c\\s*h\\s*a)\\:/ig;\nvar REGEXP_DEFAULT_ON_TAG_ATTR_5 = /^[\\s\"'`]*(d\\s*a\\s*t\\s*a\\s*)\\:/ig;\nvar REGEXP_DEFAULT_ON_TAG_ATTR_6 = /^[\\s\"'`]*(d\\s*a\\s*t\\s*a\\s*)\\:\\s*image\\//ig;\nvar REGEXP_DEFAULT_ON_TAG_ATTR_7 = /e\\s*x\\s*p\\s*r\\s*e\\s*s\\s*s\\s*i\\s*o\\s*n\\s*\\(.*/ig;\nvar REGEXP_DEFAULT_ON_TAG_ATTR_8 = /u\\s*r\\s*l\\s*\\(.*/ig;\n\n/**\n * 对双引号进行转义\n *\n * @param {String} str\n * @return {String} str\n */\nfunction escapeQuote (str) {\n return str.replace(REGEXP_QUOTE, '\u0026quot;');\n}\n\n/**\n * 对双引号进行转义\n *\n * @param {String} str\n * @return {String} str\n */\nfunction unescapeQuote (str) {\n return str.replace(REGEXP_QUOTE_2, '\"');\n}\n\n/**\n * 对html实体编码进行转义\n *\n * @param {String} str\n * @return {String}\n */\nfunction escapeHtmlEntities (str) {\n return str.replace(REGEXP_ATTR_VALUE_1, function replaceUnicode (str, code) {\n return (code[0] === 'x' || code[0] === 'X')\n ? String.fromCharCode(parseInt(code.substr(1), 16))\n : String.fromCharCode(parseInt(code, 10));\n });\n}\n\n/**\n * 对html5新增的危险实体编码进行转义\n *\n * @param {String} str\n * @return {String}\n */\nfunction escapeDangerHtml5Entities (str) {\n return str.replace(REGEXP_ATTR_VALUE_COLON, ':')\n .replace(REGEXP_ATTR_VALUE_NEWLINE, ' ');\n}\n\n/**\n * 清除不可见字符\n *\n * @param {String} str\n * @return {String}\n */\nfunction clearNonPrintableCharacter (str) {\n var str2 = '';\n for (var i = 0, len = str.length; i \u003c len; i++) {\n str2 += str.charCodeAt(i) \u003c 32 ? ' ' : str.charAt(i);\n }\n return _.trim(str2);\n}\n\n/**\n * 将标签的属性值转换成一般字符,便于分析\n *\n * @param {String} str\n * @return {String}\n */\nfunction friendlyAttrValue (str) {\n str = unescapeQuote(str); // 双引号\n str = escapeHtmlEntities(str); // 转换HTML实体编码\n str = escapeDangerHtml5Entities(str); // 转换危险的HTML5新增实体编码\n str = clearNonPrintableCharacter(str); // 清除不可见字符\n return str;\n}\n\n/**\n * 转义用于输出的标签属性值\n *\n * @param {String} str\n * @return {String}\n */\nfunction escapeAttrValue (str) {\n str = escapeQuote(str);\n str = escapeHtml(str);\n return str;\n}\n\n/**\n * 去掉不在白名单中的标签onIgnoreTag处理方法\n */\nfunction onIgnoreTagStripAll () {\n return '';\n}\n\n/**\n * 删除标签体\n *\n * @param {array} tags 要删除的标签列表\n * @param {function} next 对不在列表中的标签的处理函数,可选\n */\nfunction StripTagBody (tags, next) {\n if (typeof(next) !== 'function') {\n next = function () {};\n }\n\n var isRemoveAllTag = !Array.isArray(tags);\n function isRemoveTag (tag) {\n if (isRemoveAllTag) return true;\n return (_.indexOf(tags, tag) !== -1);\n }\n\n var removeList = []; // 要删除的位置范围列表\n var posStart = false; // 当前标签开始位置\n\n return {\n onIgnoreTag: function (tag, html, options) {\n if (isRemoveTag(tag)) {\n if (options.isClosing) {\n var ret = '[/removed]';\n var end = options.position + ret.length;\n removeList.push([posStart !== false ? posStart : options.position, end]);\n posStart = false;\n return ret;\n } else {\n if (!posStart) {\n posStart = options.position;\n }\n return '[removed]';\n }\n } else {\n return next(tag, html, options);\n }\n },\n remove: function (html) {\n var rethtml = '';\n var lastPos = 0;\n _.forEach(removeList, function (pos) {\n rethtml += html.slice(lastPos, pos[0]);\n lastPos = pos[1];\n });\n rethtml += html.slice(lastPos);\n return rethtml;\n }\n };\n}\n\n/**\n * 去除备注标签\n *\n * @param {String} html\n * @return {String}\n */\nfunction stripCommentTag (html) {\n return html.replace(STRIP_COMMENT_TAG_REGEXP, '');\n}\nvar STRIP_COMMENT_TAG_REGEXP = /\u003c!--[\\s\\S]*?--\u003e/g;\n\n/**\n * 去除不可见字符\n *\n * @param {String} html\n * @return {String}\n */\nfunction stripBlankChar (html) {\n var chars = html.split('');\n chars = chars.filter(function (char) {\n var c = char.charCodeAt(0);\n if (c === 127) return false;\n if (c \u003c= 31) {\n if (c === 10 || c === 13) return true;\n return false;\n }\n return true;\n });\n return chars.join('');\n}\n\n\nexports.whiteList = getDefaultWhiteList();\nexports.getDefaultWhiteList = getDefaultWhiteList;\nexports.onTag = onTag;\nexports.onIgnoreTag = onIgnoreTag;\nexports.onTagAttr = onTagAttr;\nexports.onIgnoreTagAttr = onIgnoreTagAttr;\nexports.safeAttrValue = safeAttrValue;\nexports.escapeHtml = escapeHtml;\nexports.escapeQuote = escapeQuote;\nexports.unescapeQuote = unescapeQuote;\nexports.escapeHtmlEntities = escapeHtmlEntities;\nexports.escapeDangerHtml5Entities = escapeDangerHtml5Entities;\nexports.clearNonPrintableCharacter = clearNonPrintableCharacter;\nexports.friendlyAttrValue = friendlyAttrValue;\nexports.escapeAttrValue = escapeAttrValue;\nexports.onIgnoreTagStripAll = onIgnoreTagStripAll;\nexports.StripTagBody = StripTagBody;\nexports.stripCommentTag = stripCommentTag;\nexports.stripBlankChar = stripBlankChar;\nexports.cssFilter = defaultCSSFilter;\nexports.getDefaultCSSWhiteList = getDefaultCSSWhiteList;\n\n},{\"./util\":4,\"cssfilter\":8}],2:[function(require,module,exports){\n/**\n * 模块入口\n *\n * @author 老雷\u003cleizongmin@gmail.com\u003e\n */\n\nvar DEFAULT = require('./default');\nvar parser = require('./parser');\nvar FilterXSS = require('./xss');\n\n\n/**\n * XSS过滤\n *\n * @param {String} html 要过滤的HTML代码\n * @param {Object} options 选项:whiteList, onTag, onTagAttr, onIgnoreTag, onIgnoreTagAttr, safeAttrValue, escapeHtml\n * @return {String}\n */\nfunction filterXSS (html, options) {\n var xss = new FilterXSS(options);\n return xss.process(html);\n}\n\n\n// 输出\nexports = module.exports = filterXSS;\nexports.FilterXSS = FilterXSS;\nfor (var i in DEFAULT) exports[i] = DEFAULT[i];\nfor (var i in parser) exports[i] = parser[i];\n\n\n// 在浏览器端使用\nif (typeof window !== 'undefined') {\n window.filterXSS = module.exports;\n}\n\n},{\"./default\":1,\"./parser\":3,\"./xss\":5}],3:[function(require,module,exports){\n/**\n * 简单 HTML Parser\n *\n * @author 老雷\u003cleizongmin@gmail.com\u003e\n */\n\nvar _ = require('./util');\n\n/**\n * 获取标签的名称\n *\n * @param {String} html 如:'\u003ca hef=\"#\"\u003e'\n * @return {String}\n */\nfunction getTagName (html) {\n var i = html.indexOf(' ');\n if (i === -1) {\n var tagName = html.slice(1, -1);\n } else {\n var tagName = html.slice(1, i + 1);\n }\n tagName = _.trim(tagName).toLowerCase();\n if (tagName.slice(0, 1) === '/') tagName = tagName.slice(1);\n if (tagName.slice(-1) === '/') tagName = tagName.slice(0, -1);\n return tagName;\n}\n\n/**\n * 是否为闭合标签\n *\n * @param {String} html 如:'\u003ca hef=\"#\"\u003e'\n * @return {Boolean}\n */\nfunction isClosing (html) {\n return (html.slice(0, 2) === '\u003c/');\n}\n\n/**\n * 分析HTML代码,调用相应的函数处理,返回处理后的HTML\n *\n * @param {String} html\n * @param {Function} onTag 处理标签的函数\n * 参数格式: function (sourcePosition, position, tag, html, isClosing)\n * @param {Function} escapeHtml 对HTML进行转义的函数\n * @return {String}\n */\nfunction parseTag (html, onTag, escapeHtml) {\n 'user strict';\n\n var rethtml = ''; // 待返回的HTML\n var lastPos = 0; // 上一个标签结束位置\n var tagStart = false; // 当前标签开始位置\n var quoteStart = false; // 引号开始位置\n var currentPos = 0; // 当前位置\n var len = html.length; // HTML长度\n var currentHtml = ''; // 当前标签的HTML代码\n var currentTagName = ''; // 当前标签的名称\n\n // 逐个分析字符\n for (currentPos = 0; currentPos \u003c len; currentPos++) {\n var c = html.charAt(currentPos);\n if (tagStart === false) {\n if (c === '\u003c') {\n tagStart = currentPos;\n continue;\n }\n } else {\n if (quoteStart === false) {\n if (c === '\u003c') {\n rethtml += escapeHtml(html.slice(lastPos, currentPos));\n tagStart = currentPos;\n lastPos = currentPos;\n continue;\n }\n if (c === '\u003e') {\n rethtml += escapeHtml(html.slice(lastPos, tagStart));\n currentHtml = html.slice(tagStart, currentPos + 1);\n currentTagName = getTagName(currentHtml);\n rethtml += onTag(tagStart,\n rethtml.length,\n currentTagName,\n currentHtml,\n isClosing(currentHtml));\n lastPos = currentPos + 1;\n tagStart = false;\n continue;\n }\n // HTML标签内的引号仅当前一个字符是等于号时才有效\n if ((c === '\"' || c === \"'\") \u0026\u0026 html.charAt(currentPos - 1) === '=') {\n quoteStart = c;\n continue;\n }\n } else {\n if (c === quoteStart) {\n quoteStart = false;\n continue;\n }\n }\n }\n }\n if (lastPos \u003c html.length) {\n rethtml += escapeHtml(html.substr(lastPos));\n }\n\n return rethtml;\n}\n\n// 不符合属性名称规则的正则表达式\nvar REGEXP_ATTR_NAME = /[^a-zA-Z0-9_:\\.\\-]/img;\n\n/**\n * 分析标签HTML代码,调用相应的函数处理,返回HTML\n *\n * @param {String} html 如标签'\u003ca href=\"#\" target=\"_blank\"\u003e' 则为 'href=\"#\" target=\"_blank\"'\n * @param {Function} onAttr 处理属性值的函数\n * 函数格式: function (name, value)\n * @return {String}\n */\nfunction parseAttr (html, onAttr) {\n 'user strict';\n\n var lastPos = 0; // 当前位置\n var retAttrs = []; // 待返回的属性列表\n var tmpName = false; // 临时属性名称\n var len = html.length; // HTML代码长度\n\n function addAttr (name, value) {\n name = _.trim(name);\n name = name.replace(REGEXP_ATTR_NAME, '').toLowerCase();\n if (name.length \u003c 1) return;\n var ret = onAttr(name, value || '');\n if (ret) retAttrs.push(ret);\n };\n\n // 逐个分析字符\n for (var i = 0; i \u003c len; i++) {\n var c = html.charAt(i);\n var v, j;\n if (tmpName === false \u0026\u0026 c === '=') {\n tmpName = html.slice(lastPos, i);\n lastPos = i + 1;\n continue;\n }\n if (tmpName !== false) {\n // HTML标签内的引号仅当前一个字符是等于号时才有效\n if (i === lastPos \u0026\u0026 (c === '\"' || c === \"'\") \u0026\u0026 html.charAt(i - 1) === '=') {\n j = html.indexOf(c, i + 1);\n if (j === -1) {\n break;\n } else {\n v = _.trim(html.slice(lastPos + 1, j));\n addAttr(tmpName, v);\n tmpName = false;\n i = j;\n lastPos = i + 1;\n continue;\n }\n }\n }\n if (c === ' ') {\n if (tmpName === false) {\n j = findNextEqual(html, i);\n if (j === -1) {\n v = _.trim(html.slice(lastPos, i));\n addAttr(v);\n tmpName = false;\n lastPos = i + 1;\n continue;\n } else {\n i = j - 1;\n continue;\n }\n } else {\n j = findBeforeEqual(html, i - 1);\n if (j === -1) {\n v = _.trim(html.slice(lastPos, i));\n v = stripQuoteWrap(v);\n addAttr(tmpName, v);\n tmpName = false;\n lastPos = i + 1;\n continue;\n } else {\n continue;\n }\n }\n }\n }\n\n if (lastPos \u003c html.length) {\n if (tmpName === false) {\n addAttr(html.slice(lastPos));\n } else {\n addAttr(tmpName, stripQuoteWrap(_.trim(html.slice(lastPos))));\n }\n }\n\n return _.trim(retAttrs.join(' '));\n}\n\nfunction findNextEqual (str, i) {\n for (; i \u003c str.length; i++) {\n var c = str[i];\n if (c === ' ') continue;\n if (c === '=') return i;\n return -1;\n }\n}\n\nfunction findBeforeEqual (str, i) {\n for (; i \u003e 0; i--) {\n var c = str[i];\n if (c === ' ') continue;\n if (c === '=') return i;\n return -1;\n }\n}\n\nfunction isQuoteWrapString (text) {\n if ((text[0] === '\"' \u0026\u0026 text[text.length - 1] === '\"') ||\n (text[0] === '\\'' \u0026\u0026 text[text.length - 1] === '\\'')) {\n return true;\n } else {\n return false;\n }\n};\n\nfunction stripQuoteWrap (text) {\n if (isQuoteWrapString(text)) {\n return text.substr(1, text.length - 2);\n } else {\n return text;\n }\n};\n\n\nexports.parseTag = parseTag;\nexports.parseAttr = parseAttr;\n\n},{\"./util\":4}],4:[function(require,module,exports){\nmodule.exports = {\n indexOf: function (arr, item) {\n var i, j;\n if (Array.prototype.indexOf) {\n return arr.indexOf(item);\n }\n for (i = 0, j = arr.length; i \u003c j; i++) {\n if (arr[i] === item) {\n return i;\n }\n }\n return -1;\n },\n forEach: function (arr, fn, scope) {\n var i, j;\n if (Array.prototype.forEach) {\n return arr.forEach(fn, scope);\n }\n for (i = 0, j = arr.length; i \u003c j; i++) {\n fn.call(scope, arr[i], i, arr);\n }\n },\n trim: function (str) {\n if (String.prototype.trim) {\n return str.trim();\n }\n return str.replace(/(^\\s*)|(\\s*$)/g, '');\n }\n};\n\n},{}],5:[function(require,module,exports){\n/**\n * 过滤XSS\n *\n * @author 老雷\u003cleizongmin@gmail.com\u003e\n */\n\nvar FilterCSS = require('cssfilter').FilterCSS;\nvar DEFAULT = require('./default');\nvar parser = require('./parser');\nvar parseTag = parser.parseTag;\nvar parseAttr = parser.parseAttr;\nvar _ = require('./util');\n\n\n/**\n * 返回值是否为空\n *\n * @param {Object} obj\n * @return {Boolean}\n */\nfunction isNull (obj) {\n return (obj === undefined || obj === null);\n}\n\n/**\n * 取标签内的属性列表字符串\n *\n * @param {String} html\n * @return {Object}\n * - {String} html\n * - {Boolean} closing\n */\nfunction getAttrs (html) {\n var i = html.indexOf(' ');\n if (i === -1) {\n return {\n html: '',\n closing: (html[html.length - 2] === '/')\n };\n }\n html = _.trim(html.slice(i + 1, -1));\n var isClosing = (html[html.length - 1] === '/');\n if (isClosing) html = _.trim(html.slice(0, -1));\n return {\n html: html,\n closing: isClosing\n };\n}\n\n/**\n * 浅拷贝对象\n *\n * @param {Object} obj\n * @return {Object}\n */\nfunction shallowCopyObject (obj) {\n var ret = {};\n for (var i in obj) {\n ret[i] = obj[i];\n }\n return ret;\n}\n\n/**\n * XSS过滤对象\n *\n * @param {Object} options\n * 选项:whiteList, onTag, onTagAttr, onIgnoreTag,\n * onIgnoreTagAttr, safeAttrValue, escapeHtml\n * stripIgnoreTagBody, allowCommentTag, stripBlankChar\n * css{whiteList, onAttr, onIgnoreAttr} css=false表示禁用cssfilter\n */\nfunction FilterXSS (options) {\n options = shallowCopyObject(options || {});\n\n if (options.stripIgnoreTag) {\n if (options.onIgnoreTag) {\n console.error('Notes: cannot use these two options \"stripIgnoreTag\" and \"onIgnoreTag\" at the same time');\n }\n options.onIgnoreTag = DEFAULT.onIgnoreTagStripAll;\n }\n\n options.whiteList = options.whiteList || DEFAULT.whiteList;\n options.onTag = options.onTag || DEFAULT.onTag;\n options.onTagAttr = options.onTagAttr || DEFAULT.onTagAttr;\n options.onIgnoreTag = options.onIgnoreTag || DEFAULT.onIgnoreTag;\n options.onIgnoreTagAttr = options.onIgnoreTagAttr || DEFAULT.onIgnoreTagAttr;\n options.safeAttrValue = options.safeAttrValue || DEFAULT.safeAttrValue;\n options.escapeHtml = options.escapeHtml || DEFAULT.escapeHtml;\n this.options = options;\n\n if (options.css === false) {\n this.cssFilter = false;\n } else {\n options.css = options.css || {};\n this.cssFilter = new FilterCSS(options.css);\n }\n}\n\n/**\n * 开始处理\n *\n * @param {String} html\n * @return {String}\n */\nFilterXSS.prototype.process = function (html) {\n // 兼容各种奇葩输入\n html = html || '';\n html = html.toString();\n if (!html) return '';\n\n var me = this;\n var options = me.options;\n var whiteList = options.whiteList;\n var onTag = options.onTag;\n var onIgnoreTag = options.onIgnoreTag;\n var onTagAttr = options.onTagAttr;\n var onIgnoreTagAttr = options.onIgnoreTagAttr;\n var safeAttrValue = options.safeAttrValue;\n var escapeHtml = options.escapeHtml;\n var cssFilter = me.cssFilter;\n\n // 是否清除不可见字符\n if (options.stripBlankChar) {\n html = DEFAULT.stripBlankChar(html);\n }\n\n // 是否禁止备注标签\n if (!options.allowCommentTag) {\n html = DEFAULT.stripCommentTag(html);\n }\n\n // 如果开启了stripIgnoreTagBody\n var stripIgnoreTagBody = false;\n if (options.stripIgnoreTagBody) {\n var stripIgnoreTagBody = DEFAULT.StripTagBody(options.stripIgnoreTagBody, onIgnoreTag);\n onIgnoreTag = stripIgnoreTagBody.onIgnoreTag;\n }\n\n var retHtml = parseTag(html, function (sourcePosition, position, tag, html, isClosing) {\n var info = {\n sourcePosition: sourcePosition,\n position: position,\n isClosing: isClosing,\n isWhite: (tag in whiteList)\n };\n\n // 调用onTag处理\n var ret = onTag(tag, html, info);\n if (!isNull(ret)) return ret;\n\n // 默认标签处理方法\n if (info.isWhite) {\n // 白名单标签,解析标签属性\n // 如果是闭合标签,则不需要解析属性\n if (info.isClosing) {\n return '\u003c/' + tag + '\u003e';\n }\n\n var attrs = getAttrs(html);\n var whiteAttrList = whiteList[tag];\n var attrsHtml = parseAttr(attrs.html, function (name, value) {\n\n // 调用onTagAttr处理\n var isWhiteAttr = (_.indexOf(whiteAttrList, name) !== -1);\n var ret = onTagAttr(tag, name, value, isWhiteAttr);\n if (!isNull(ret)) return ret;\n\n // 默认的属性处理方法\n if (isWhiteAttr) {\n // 白名单属性,调用safeAttrValue过滤属性值\n value = safeAttrValue(tag, name, value, cssFilter);\n if (value) {\n return name + '=\"' + value + '\"';\n } else {\n return name;\n }\n } else {\n // 非白名单属性,调用onIgnoreTagAttr处理\n var ret = onIgnoreTagAttr(tag, name, value, isWhiteAttr);\n if (!isNull(ret)) return ret;\n return;\n }\n });\n\n // 构造新的标签代码\n var html = '\u003c' + tag;\n if (attrsHtml) html += ' ' + attrsHtml;\n if (attrs.closing) html += ' /';\n html += '\u003e';\n return html;\n\n } else {\n // 非白名单标签,调用onIgnoreTag处理\n var ret = onIgnoreTag(tag, html, info);\n if (!isNull(ret)) return ret;\n return escapeHtml(html);\n }\n\n }, escapeHtml);\n\n // 如果开启了stripIgnoreTagBody,需要对结果再进行处理\n if (stripIgnoreTagBody) {\n retHtml = stripIgnoreTagBody.remove(retHtml);\n }\n\n return retHtml;\n};\n\n\nmodule.exports = FilterXSS;\n\n},{\"./default\":1,\"./parser\":3,\"./util\":4,\"cssfilter\":8}],6:[function(require,module,exports){\n/**\n * cssfilter\n *\n * @author 老雷\u003cleizongmin@gmail.com\u003e\n */\n\nvar DEFAULT = require('./default');\nvar parseStyle = require('./parser');\nvar _ = require('./util');\n\n\n/**\n * 返回值是否为空\n *\n * @param {Object} obj\n * @return {Boolean}\n */\nfunction isNull (obj) {\n return (obj === undefined || obj === null);\n}\n\n/**\n * 浅拷贝对象\n *\n * @param {Object} obj\n * @return {Object}\n */\nfunction shallowCopyObject (obj) {\n var ret = {};\n for (var i in obj) {\n ret[i] = obj[i];\n }\n return ret;\n}\n\n/**\n * 创建CSS过滤器\n *\n * @param {Object} options\n * - {Object} whiteList\n * - {Object} onAttr\n * - {Object} onIgnoreAttr\n */\nfunction FilterCSS (options) {\n options = shallowCopyObject(options || {});\n options.whiteList = options.whiteList || DEFAULT.whiteList;\n options.onAttr = options.onAttr || DEFAULT.onAttr;\n options.onIgnoreAttr = options.onIgnoreAttr || DEFAULT.onIgnoreAttr;\n this.options = options;\n}\n\nFilterCSS.prototype.process = function (css) {\n // 兼容各种奇葩输入\n css = css || '';\n css = css.toString();\n if (!css) return '';\n\n var me = this;\n var options = me.options;\n var whiteList = options.whiteList;\n var onAttr = options.onAttr;\n var onIgnoreAttr = options.onIgnoreAttr;\n\n var retCSS = parseStyle(css, function (sourcePosition, position, name, value, source) {\n\n var check = whiteList[name];\n var isWhite = false;\n if (check === true) isWhite = check;\n else if (typeof check === 'function') isWhite = check(value);\n else if (check instanceof RegExp) isWhite = check.test(value);\n if (isWhite !== true) isWhite = false;\n\n var opts = {\n position: position,\n sourcePosition: sourcePosition,\n source: source,\n isWhite: isWhite\n };\n\n if (isWhite) {\n\n var ret = onAttr(name, value, opts);\n if (isNull(ret)) {\n return name + ':' + value;\n } else {\n return ret;\n }\n\n } else {\n\n var ret = onIgnoreAttr(name, value, opts);\n if (!isNull(ret)) {\n return ret;\n }\n\n }\n });\n\n return retCSS;\n};\n\n\nmodule.exports = FilterCSS;\n\n},{\"./default\":7,\"./parser\":9,\"./util\":10}],7:[function(require,module,exports){\n/**\n * cssfilter\n *\n * @author 老雷\u003cleizongmin@gmail.com\u003e\n */\n\nfunction getDefaultWhiteList () {\n // 白名单值说明:\n // true: 允许该属性\n // Function: function (val) { } 返回true表示允许该属性,其他值均表示不允许\n // RegExp: regexp.test(val) 返回true表示允许该属性,其他值均表示不允许\n // 除上面列出的值外均表示不允许\n var whiteList = {};\n\n whiteList['align-content'] = false; // default: auto\n whiteList['align-items'] = false; // default: auto\n whiteList['align-self'] = false; // default: auto\n whiteList['alignment-adjust'] = false; // default: auto\n whiteList['alignment-baseline'] = false; // default: baseline\n whiteList['all'] = false; // default: depending on individual properties\n whiteList['anchor-point'] = false; // default: none\n whiteList['animation'] = false; // default: depending on individual properties\n whiteList['animation-delay'] = false; // default: 0\n whiteList['animation-direction'] = false; // default: normal\n whiteList['animation-duration'] = false; // default: 0\n whiteList['animation-fill-mode'] = false; // default: none\n whiteList['animation-iteration-count'] = false; // default: 1\n whiteList['animation-name'] = false; // default: none\n whiteList['animation-play-state'] = false; // default: running\n whiteList['animation-timing-function'] = false; // default: ease\n whiteList['azimuth'] = false; // default: center\n whiteList['backface-visibility'] = false; // default: visible\n whiteList['background'] = true; // default: depending on individual properties\n whiteList['background-attachment'] = true; // default: scroll\n whiteList['background-clip'] = true; // default: border-box\n whiteList['background-color'] = true; // default: transparent\n whiteList['background-image'] = true; // default: none\n whiteList['background-origin'] = true; // default: padding-box\n whiteList['background-position'] = true; // default: 0% 0%\n whiteList['background-repeat'] = true; // default: repeat\n whiteList['background-size'] = true; // default: auto\n whiteList['baseline-shift'] = false; // default: baseline\n whiteList['binding'] = false; // default: none\n whiteList['bleed'] = false; // default: 6pt\n whiteList['bookmark-label'] = false; // default: content()\n whiteList['bookmark-level'] = false; // default: none\n whiteList['bookmark-state'] = false; // default: open\n whiteList['border'] = true; // default: depending on individual properties\n whiteList['border-bottom'] = true; // default: depending on individual properties\n whiteList['border-bottom-color'] = true; // default: current color\n whiteList['border-bottom-left-radius'] = true; // default: 0\n whiteList['border-bottom-right-radius'] = true; // default: 0\n whiteList['border-bottom-style'] = true; // default: none\n whiteList['border-bottom-width'] = true; // default: medium\n whiteList['border-collapse'] = true; // default: separate\n whiteList['border-color'] = true; // default: depending on individual properties\n whiteList['border-image'] = true; // default: none\n whiteList['border-image-outset'] = true; // default: 0\n whiteList['border-image-repeat'] = true; // default: stretch\n whiteList['border-image-slice'] = true; // default: 100%\n whiteList['border-image-source'] = true; // default: none\n whiteList['border-image-width'] = true; // default: 1\n whiteList['border-left'] = true; // default: depending on individual properties\n whiteList['border-left-color'] = true; // default: current color\n whiteList['border-left-style'] = true; // default: none\n whiteList['border-left-width'] = true; // default: medium\n whiteList['border-radius'] = true; // default: 0\n whiteList['border-right'] = true; // default: depending on individual properties\n whiteList['border-right-color'] = true; // default: current color\n whiteList['border-right-style'] = true; // default: none\n whiteList['border-right-width'] = true; // default: medium\n whiteList['border-spacing'] = true; // default: 0\n whiteList['border-style'] = true; // default: depending on individual properties\n whiteList['border-top'] = true; // default: depending on individual properties\n whiteList['border-top-color'] = true; // default: current color\n whiteList['border-top-left-radius'] = true; // default: 0\n whiteList['border-top-right-radius'] = true; // default: 0\n whiteList['border-top-style'] = true; // default: none\n whiteList['border-top-width'] = true; // default: medium\n whiteList['border-width'] = true; // default: depending on individual properties\n whiteList['bottom'] = false; // default: auto\n whiteList['box-decoration-break'] = true; // default: slice\n whiteList['box-shadow'] = true; // default: none\n whiteList['box-sizing'] = true; // default: content-box\n whiteList['box-snap'] = true; // default: none\n whiteList['box-suppress'] = true; // default: show\n whiteList['break-after'] = true; // default: auto\n whiteList['break-before'] = true; // default: auto\n whiteList['break-inside'] = true; // default: auto\n whiteList['caption-side'] = false; // default: top\n whiteList['chains'] = false; // default: none\n whiteList['clear'] = true; // default: none\n whiteList['clip'] = false; // default: auto\n whiteList['clip-path'] = false; // default: none\n whiteList['clip-rule'] = false; // default: nonzero\n whiteList['color'] = true; // default: implementation dependent\n whiteList['color-interpolation-filters'] = true; // default: auto\n whiteList['column-count'] = false; // default: auto\n whiteList['column-fill'] = false; // default: balance\n whiteList['column-gap'] = false; // default: normal\n whiteList['column-rule'] = false; // default: depending on individual properties\n whiteList['column-rule-color'] = false; // default: current color\n whiteList['column-rule-style'] = false; // default: medium\n whiteList['column-rule-width'] = false; // default: medium\n whiteList['column-span'] = false; // default: none\n whiteList['column-width'] = false; // default: auto\n whiteList['columns'] = false; // default: depending on individual properties\n whiteList['contain'] = false; // default: none\n whiteList['content'] = false; // default: normal\n whiteList['counter-increment'] = false; // default: none\n whiteList['counter-reset'] = false; // default: none\n whiteList['counter-set'] = false; // default: none\n whiteList['crop'] = false; // default: auto\n whiteList['cue'] = false; // default: depending on individual properties\n whiteList['cue-after'] = false; // default: none\n whiteList['cue-before'] = false; // default: none\n whiteList['cursor'] = false; // default: auto\n whiteList['direction'] = false; // default: ltr\n whiteList['display'] = true; // default: depending on individual properties\n whiteList['display-inside'] = true; // default: auto\n whiteList['display-list'] = true; // default: none\n whiteList['display-outside'] = true; // default: inline-level\n whiteList['dominant-baseline'] = false; // default: auto\n whiteList['elevation'] = false; // default: level\n whiteList['empty-cells'] = false; // default: show\n whiteList['filter'] = false; // default: none\n whiteList['flex'] = false; // default: depending on individual properties\n whiteList['flex-basis'] = false; // default: auto\n whiteList['flex-direction'] = false; // default: row\n whiteList['flex-flow'] = false; // default: depending on individual properties\n whiteList['flex-grow'] = false; // default: 0\n whiteList['flex-shrink'] = false; // default: 1\n whiteList['flex-wrap'] = false; // default: nowrap\n whiteList['float'] = false; // default: none\n whiteList['float-offset'] = false; // default: 0 0\n whiteList['flood-color'] = false; // default: black\n whiteList['flood-opacity'] = false; // default: 1\n whiteList['flow-from'] = false; // default: none\n whiteList['flow-into'] = false; // default: none\n whiteList['font'] = true; // default: depending on individual properties\n whiteList['font-family'] = true; // default: implementation dependent\n whiteList['font-feature-settings'] = true; // default: normal\n whiteList['font-kerning'] = true; // default: auto\n whiteList['font-language-override'] = true; // default: normal\n whiteList['font-size'] = true; // default: medium\n whiteList['font-size-adjust'] = true; // default: none\n whiteList['font-stretch'] = true; // default: normal\n whiteList['font-style'] = true; // default: normal\n whiteList['font-synthesis'] = true; // default: weight style\n whiteList['font-variant'] = true; // default: normal\n whiteList['font-variant-alternates'] = true; // default: normal\n whiteList['font-variant-caps'] = true; // default: normal\n whiteList['font-variant-east-asian'] = true; // default: normal\n whiteList['font-variant-ligatures'] = true; // default: normal\n whiteList['font-variant-numeric'] = true; // default: normal\n whiteList['font-variant-position'] = true; // default: normal\n whiteList['font-weight'] = true; // default: normal\n whiteList['grid'] = false; // default: depending on individual properties\n whiteList['grid-area'] = false; // default: depending on individual properties\n whiteList['grid-auto-columns'] = false; // default: auto\n whiteList['grid-auto-flow'] = false; // default: none\n whiteList['grid-auto-rows'] = false; // default: auto\n whiteList['grid-column'] = false; // default: depending on individual properties\n whiteList['grid-column-end'] = false; // default: auto\n whiteList['grid-column-start'] = false; // default: auto\n whiteList['grid-row'] = false; // default: depending on individual properties\n whiteList['grid-row-end'] = false; // default: auto\n whiteList['grid-row-start'] = false; // default: auto\n whiteList['grid-template'] = false; // default: depending on individual properties\n whiteList['grid-template-areas'] = false; // default: none\n whiteList['grid-template-columns'] = false; // default: none\n whiteList['grid-template-rows'] = false; // default: none\n whiteList['hanging-punctuation'] = false; // default: none\n whiteList['height'] = true; // default: auto\n whiteList['hyphens'] = false; // default: manual\n whiteList['icon'] = false; // default: auto\n whiteList['image-orientation'] = false; // default: auto\n whiteList['image-resolution'] = false; // default: normal\n whiteList['ime-mode'] = false; // default: auto\n whiteList['initial-letters'] = false; // default: normal\n whiteList['inline-box-align'] = false; // default: last\n whiteList['justify-content'] = false; // default: auto\n whiteList['justify-items'] = false; // default: auto\n whiteList['justify-self'] = false; // default: auto\n whiteList['left'] = false; // default: auto\n whiteList['letter-spacing'] = true; // default: normal\n whiteList['lighting-color'] = true; // default: white\n whiteList['line-box-contain'] = false; // default: block inline replaced\n whiteList['line-break'] = false; // default: auto\n whiteList['line-grid'] = false; // default: match-parent\n whiteList['line-height'] = false; // default: normal\n whiteList['line-snap'] = false; // default: none\n whiteList['line-stacking'] = false; // default: depending on individual properties\n whiteList['line-stacking-ruby'] = false; // default: exclude-ruby\n whiteList['line-stacking-shift'] = false; // default: consider-shifts\n whiteList['line-stacking-strategy'] = false; // default: inline-line-height\n whiteList['list-style'] = true; // default: depending on individual properties\n whiteList['list-style-image'] = true; // default: none\n whiteList['list-style-position'] = true; // default: outside\n whiteList['list-style-type'] = true; // default: disc\n whiteList['margin'] = true; // default: depending on individual properties\n whiteList['margin-bottom'] = true; // default: 0\n whiteList['margin-left'] = true; // default: 0\n whiteList['margin-right'] = true; // default: 0\n whiteList['margin-top'] = true; // default: 0\n whiteList['marker-offset'] = false; // default: auto\n whiteList['marker-side'] = false; // default: list-item\n whiteList['marks'] = false; // default: none\n whiteList['mask'] = false; // default: border-box\n whiteList['mask-box'] = false; // default: see individual properties\n whiteList['mask-box-outset'] = false; // default: 0\n whiteList['mask-box-repeat'] = false; // default: stretch\n whiteList['mask-box-slice'] = false; // default: 0 fill\n whiteList['mask-box-source'] = false; // default: none\n whiteList['mask-box-width'] = false; // default: auto\n whiteList['mask-clip'] = false; // default: border-box\n whiteList['mask-image'] = false; // default: none\n whiteList['mask-origin'] = false; // default: border-box\n whiteList['mask-position'] = false; // default: center\n whiteList['mask-repeat'] = false; // default: no-repeat\n whiteList['mask-size'] = false; // default: border-box\n whiteList['mask-source-type'] = false; // default: auto\n whiteList['mask-type'] = false; // default: luminance\n whiteList['max-height'] = true; // default: none\n whiteList['max-lines'] = false; // default: none\n whiteList['max-width'] = true; // default: none\n whiteList['min-height'] = true; // default: 0\n whiteList['min-width'] = true; // default: 0\n whiteList['move-to'] = false; // default: normal\n whiteList['nav-down'] = false; // default: auto\n whiteList['nav-index'] = false; // default: auto\n whiteList['nav-left'] = false; // default: auto\n whiteList['nav-right'] = false; // default: auto\n whiteList['nav-up'] = false; // default: auto\n whiteList['object-fit'] = false; // default: fill\n whiteList['object-position'] = false; // default: 50% 50%\n whiteList['opacity'] = false; // default: 1\n whiteList['order'] = false; // default: 0\n whiteList['orphans'] = false; // default: 2\n whiteList['outline'] = false; // default: depending on individual properties\n whiteList['outline-color'] = false; // default: invert\n whiteList['outline-offset'] = false; // default: 0\n whiteList['outline-style'] = false; // default: none\n whiteList['outline-width'] = false; // default: medium\n whiteList['overflow'] = false; // default: depending on individual properties\n whiteList['overflow-wrap'] = false; // default: normal\n whiteList['overflow-x'] = false; // default: visible\n whiteList['overflow-y'] = false; // default: visible\n whiteList['padding'] = true; // default: depending on individual properties\n whiteList['padding-bottom'] = true; // default: 0\n whiteList['padding-left'] = true; // default: 0\n whiteList['padding-right'] = true; // default: 0\n whiteList['padding-top'] = true; // default: 0\n whiteList['page'] = false; // default: auto\n whiteList['page-break-after'] = false; // default: auto\n whiteList['page-break-before'] = false; // default: auto\n whiteList['page-break-inside'] = false; // default: auto\n whiteList['page-policy'] = false; // default: start\n whiteList['pause'] = false; // default: implementation dependent\n whiteList['pause-after'] = false; // default: implementation dependent\n whiteList['pause-before'] = false; // default: implementation dependent\n whiteList['perspective'] = false; // default: none\n whiteList['perspective-origin'] = false; // default: 50% 50%\n whiteList['pitch'] = false; // default: medium\n whiteList['pitch-range'] = false; // default: 50\n whiteList['play-during'] = false; // default: auto\n whiteList['position'] = false; // default: static\n whiteList['presentation-level'] = false; // default: 0\n whiteList['quotes'] = false; // default: text\n whiteList['region-fragment'] = false; // default: auto\n whiteList['resize'] = false; // default: none\n whiteList['rest'] = false; // default: depending on individual properties\n whiteList['rest-after'] = false; // default: none\n whiteList['rest-before'] = false; // default: none\n whiteList['richness'] = false; // default: 50\n whiteList['right'] = false; // default: auto\n whiteList['rotation'] = false; // default: 0\n whiteList['rotation-point'] = false; // default: 50% 50%\n whiteList['ruby-align'] = false; // default: auto\n whiteList['ruby-merge'] = false; // default: separate\n whiteList['ruby-position'] = false; // default: before\n whiteList['shape-image-threshold'] = false; // default: 0.0\n whiteList['shape-outside'] = false; // default: none\n whiteList['shape-margin'] = false; // default: 0\n whiteList['size'] = false; // default: auto\n whiteList['speak'] = false; // default: auto\n whiteList['speak-as'] = false; // default: normal\n whiteList['speak-header'] = false; // default: once\n whiteList['speak-numeral'] = false; // default: continuous\n whiteList['speak-punctuation'] = false; // default: none\n whiteList['speech-rate'] = false; // default: medium\n whiteList['stress'] = false; // default: 50\n whiteList['string-set'] = false; // default: none\n whiteList['tab-size'] = false; // default: 8\n whiteList['table-layout'] = false; // default: auto\n whiteList['text-align'] = true; // default: start\n whiteList['text-align-last'] = true; // default: auto\n whiteList['text-combine-upright'] = true; // default: none\n whiteList['text-decoration'] = true; // default: none\n whiteList['text-decoration-color'] = true; // default: currentColor\n whiteList['text-decoration-line'] = true; // default: none\n whiteList['text-decoration-skip'] = true; // default: objects\n whiteList['text-decoration-style'] = true; // default: solid\n whiteList['text-emphasis'] = true; // default: depending on individual properties\n whiteList['text-emphasis-color'] = true; // default: currentColor\n whiteList['text-emphasis-position'] = true; // default: over right\n whiteList['text-emphasis-style'] = true; // default: none\n whiteList['text-height'] = true; // default: auto\n whiteList['text-indent'] = true; // default: 0\n whiteList['text-justify'] = true; // default: auto\n whiteList['text-orientation'] = true; // default: mixed\n whiteList['text-overflow'] = true; // default: clip\n whiteList['text-shadow'] = true; // default: none\n whiteList['text-space-collapse'] = true; // default: collapse\n whiteList['text-transform'] = true; // default: none\n whiteList['text-underline-position'] = true; // default: auto\n whiteList['text-wrap'] = true; // default: normal\n whiteList['top'] = false; // default: auto\n whiteList['transform'] = false; // default: none\n whiteList['transform-origin'] = false; // default: 50% 50% 0\n whiteList['transform-style'] = false; // default: flat\n whiteList['transition'] = false; // default: depending on individual properties\n whiteList['transition-delay'] = false; // default: 0s\n whiteList['transition-duration'] = false; // default: 0s\n whiteList['transition-property'] = false; // default: all\n whiteList['transition-timing-function'] = false; // default: ease\n whiteList['unicode-bidi'] = false; // default: normal\n whiteList['vertical-align'] = false; // default: baseline\n whiteList['visibility'] = false; // default: visible\n whiteList['voice-balance'] = false; // default: center\n whiteList['voice-duration'] = false; // default: auto\n whiteList['voice-family'] = false; // default: implementation dependent\n whiteList['voice-pitch'] = false; // default: medium\n whiteList['voice-range'] = false; // default: medium\n whiteList['voice-rate'] = false; // default: normal\n whiteList['voice-stress'] = false; // default: normal\n whiteList['voice-volume'] = false; // default: medium\n whiteList['volume'] = false; // default: medium\n whiteList['white-space'] = false; // default: normal\n whiteList['widows'] = false; // default: 2\n whiteList['width'] = true; // default: auto\n whiteList['will-change'] = false; // default: auto\n whiteList['word-break'] = true; // default: normal\n whiteList['word-spacing'] = true; // default: normal\n whiteList['word-wrap'] = true; // default: normal\n whiteList['wrap-flow'] = false; // default: auto\n whiteList['wrap-through'] = false; // default: wrap\n whiteList['writing-mode'] = false; // default: horizontal-tb\n whiteList['z-index'] = false; // default: auto\n\n return whiteList;\n}\n\n\n/**\n * 匹配到白名单上的一个属性时\n *\n * @param {String} name\n * @param {String} value\n * @param {Object} options\n * @return {String}\n */\nfunction onAttr (name, value, options) {\n // do nothing\n}\n\n/**\n * 匹配到不在白名单上的一个属性时\n *\n * @param {String} name\n * @param {String} value\n * @param {Object} options\n * @return {String}\n */\nfunction onIgnoreAttr (name, value, options) {\n // do nothing\n}\n\n\nexports.whiteList = getDefaultWhiteList();\nexports.getDefaultWhiteList = getDefaultWhiteList;\nexports.onAttr = onAttr;\nexports.onIgnoreAttr = onIgnoreAttr;\n\n},{}],8:[function(require,module,exports){\n/**\n * cssfilter\n *\n * @author 老雷\u003cleizongmin@gmail.com\u003e\n */\n\nvar DEFAULT = require('./default');\nvar FilterCSS = require('./css');\n\n\n/**\n * XSS过滤\n *\n * @param {String} css 要过滤的CSS代码\n * @param {Object} options 选项:whiteList, onAttr, onIgnoreAttr\n * @return {String}\n */\nfunction filterCSS (html, options) {\n var xss = new FilterCSS(options);\n return xss.process(html);\n}\n\n\n// 输出\nexports = module.exports = filterCSS;\nexports.FilterCSS = FilterCSS;\nfor (var i in DEFAULT) exports[i] = DEFAULT[i];\n\n// 在浏览器端使用\nif (typeof window !== 'undefined') {\n window.filterCSS = module.exports;\n}\n\n},{\"./css\":6,\"./default\":7}],9:[function(require,module,exports){\n/**\n * cssfilter\n *\n * @author 老雷\u003cleizongmin@gmail.com\u003e\n */\n\nvar _ = require('./util');\n\n\n/**\n * 解析style\n *\n * @param {String} css\n * @param {Function} onAttr 处理属性的函数\n * 参数格式: function (sourcePosition, position, name, value, source)\n * @return {String}\n */\nfunction parseStyle (css, onAttr) {\n css = _.trimRight(css);\n if (css[css.length - 1] !== ';') css += ';';\n var cssLength = css.length;\n var isParenthesisOpen = false;\n var lastPos = 0;\n var i = 0;\n var retCSS = '';\n\n function addNewAttr () {\n // 如果没有正常的闭合圆括号,则直接忽略当前属性\n if (!isParenthesisOpen) {\n var source = _.trim(css.slice(lastPos, i));\n var j = source.indexOf(':');\n if (j !== -1) {\n var name = _.trim(source.slice(0, j));\n var value = _.trim(source.slice(j + 1));\n // 必须有属性名称\n if (name) {\n var ret = onAttr(lastPos, retCSS.length, name, value, source);\n if (ret) retCSS += ret + '; ';\n }\n }\n }\n lastPos = i + 1;\n }\n\n for (; i \u003c cssLength; i++) {\n var c = css[i];\n if (c === '/' \u0026\u0026 css[i + 1] === '*') {\n // 备注开始\n var j = css.indexOf('*/', i + 2);\n // 如果没有正常的备注结束,则后面的部分全部跳过\n if (j === -1) break;\n // 直接将当前位置调到备注结尾,并且初始化状态\n i = j + 1;\n lastPos = i + 1;\n isParenthesisOpen = false;\n } else if (c === '(') {\n isParenthesisOpen = true;\n } else if (c === ')') {\n isParenthesisOpen = false;\n } else if (c === ';') {\n if (isParenthesisOpen) {\n // 在圆括号里面,忽略\n } else {\n addNewAttr();\n }\n } else if (c === '\\n') {\n addNewAttr();\n }\n }\n\n return _.trim(retCSS);\n}\n\nmodule.exports = parseStyle;\n\n},{\"./util\":10}],10:[function(require,module,exports){\nmodule.exports = {\n indexOf: function (arr, item) {\n var i, j;\n if (Array.prototype.indexOf) {\n return arr.indexOf(item);\n }\n for (i = 0, j = arr.length; i \u003c j; i++) {\n if (arr[i] === item) {\n return i;\n }\n }\n return -1;\n },\n forEach: function (arr, fn, scope) {\n var i, j;\n if (Array.prototype.forEach) {\n return arr.forEach(fn, scope);\n }\n for (i = 0, j = arr.length; i \u003c j; i++) {\n fn.call(scope, arr[i], i, arr);\n }\n },\n trim: function (str) {\n if (String.prototype.trim) {\n return str.trim();\n }\n return str.replace(/(^\\s*)|(\\s*$)/g, '');\n },\n trimRight: function (str) {\n if (String.prototype.trimRight) {\n return str.trimRight();\n }\n return str.replace(/(\\s*$)/g, '');\n }\n};\n\n},{}]},{},[2]);\n/*\n global initializeLocalStorageRender, initializeBodyData,\n initializeAllTagEditButtons, initializeUserFollowButts,\n initializeBaseTracking, initializeCommentsPage,\n initializeArticleDate, initializeArticleReactions, initNotifications,\n initializeCommentDate, initializeSettings,\n initializeCommentPreview, initializeRuntimeBanner,\n initializeTimeFixer, initializeDashboardSort, initializePWAFunctionality,\n initializeArchivedPostFilter, initializeCreditsPage,\n initializeProfileInfoToggle, initializePodcastPlayback,\n initializeVideoPlayback, initializeDrawerSliders, initializeProfileBadgesToggle,\n initializeHeroBannerClose, initializeOnboardingTaskCard, initScrolling,\n nextPage:writable, fetching:writable, done:writable, adClicked:writable,\n initializePaymentPointers, initializeBroadcast, initializeDateHelpers,\n initializeColorPicker, Runtime\n*/\n\nfunction callInitializers() {\n initializeBaseTracking();\n initializePaymentPointers();\n initializeCommentsPage();\n initializeArticleDate();\n initializeArticleReactions();\n initNotifications();\n initializeCommentDate();\n initializeSettings();\n initializeCommentPreview();\n initializeTimeFixer();\n initializeDashboardSort();\n initializePWAFunctionality();\n initializeArchivedPostFilter();\n initializeCreditsPage();\n initializeProfileInfoToggle();\n initializeProfileBadgesToggle();\n initializeDrawerSliders();\n initializeHeroBannerClose();\n initializeOnboardingTaskCard();\n initializeDateHelpers();\n initializeColorPicker();\n}\n\nfunction initializePage() {\n initializeLocalStorageRender();\n initializeBodyData();\n\n var waitingForDataLoad = setInterval(function wait() {\n if (document.body.getAttribute('data-loaded') === 'true') {\n clearInterval(waitingForDataLoad);\n if (document.body.getAttribute('data-user-status') === 'logged-in') {\n initializeBaseUserData();\n initializeAllTagEditButtons();\n }\n initializeBroadcast();\n initializeReadingListIcons();\n initializeSponsorshipVisibility();\n if (document.getElementById('sidebar-additional')) {\n document.getElementById('sidebar-additional').classList.add('showing');\n }\n initializePodcastPlayback();\n initializeVideoPlayback();\n }\n }, 1);\n\n callInitializers();\n\n function freezeScrolling(event) {\n event.preventDefault();\n }\n\n nextPage = 0;\n fetching = false;\n done = false;\n adClicked = false;\n setTimeout(function undone() {\n done = false;\n }, 300);\n if (!initScrolling.called) {\n initScrolling();\n }\n\n // Initialize data-runtime context to the body data-attribute\n document.body.dataset.runtime = Runtime.currentContext();\n};\n(function (global, factory) {\n typeof exports === 'object' \u0026\u0026 typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' \u0026\u0026 define.amd ? define(factory) :\n (global = global || self, global.Honeybadger = factory());\n}(this, (function () { 'use strict';\n\n function _typeof(obj) {\n \"@babel/helpers - typeof\";\n\n if (typeof Symbol === \"function\" \u0026\u0026 typeof Symbol.iterator === \"symbol\") {\n _typeof = function (obj) {\n return typeof obj;\n };\n } else {\n _typeof = function (obj) {\n return obj \u0026\u0026 typeof Symbol === \"function\" \u0026\u0026 obj.constructor === Symbol \u0026\u0026 obj !== Symbol.prototype ? \"symbol\" : typeof obj;\n };\n }\n\n return _typeof(obj);\n }\n\n function sanitize(obj, maxDepth) {\n var seenObjects = [];\n\n function seen(obj) {\n if (!obj || _typeof(obj) !== 'object') {\n return false;\n }\n\n for (var i = 0; i \u003c seenObjects.length; i++) {\n var value = seenObjects[i];\n\n if (value === obj) {\n return true;\n }\n }\n\n seenObjects.push(obj);\n return false;\n }\n\n function canSerialize(obj) {\n // Functions are TMI and Symbols can't convert to strings.\n if (/function|symbol/.test(_typeof(obj))) {\n return false;\n }\n\n if (obj === null) {\n return false;\n }\n\n if (_typeof(obj) === 'object' \u0026\u0026 typeof obj.hasOwnProperty === 'undefined') {\n return false;\n }\n\n return true;\n }\n\n function serialize(obj, depth) {\n if (!depth) {\n depth = 0;\n }\n\n if (depth \u003e= maxDepth) {\n return '[DEPTH]';\n } // Inspect invalid types\n\n\n if (!canSerialize(obj)) {\n return Object.prototype.toString.call(obj);\n } // Halt circular references\n\n\n if (seen(obj)) {\n return '[RECURSION]';\n } // Serialize inside arrays\n\n\n if (Array.isArray(obj)) {\n return obj.map(function (o) {\n return serialize(o, depth + 1);\n });\n } // Serialize inside objects\n\n\n if (_typeof(obj) === 'object') {\n var ret = {};\n\n for (var k in obj) {\n var v = obj[k];\n\n if (Object.prototype.hasOwnProperty.call(obj, k) \u0026\u0026 k != null \u0026\u0026 v != null) {\n ret[k] = serialize(v, depth + 1);\n }\n }\n\n return ret;\n } // Return everything else untouched\n\n\n return obj;\n }\n\n return serialize(obj);\n }\n\n /**\n * Converts an HTMLElement into a human-readable string.\n * @param {!HTMLElement} element\n * @return {string}\n */\n function stringNameOfElement(element) {\n if (!element || !element.tagName) {\n return '';\n }\n\n var name = element.tagName.toLowerCase(); // Ignore the root \u003chtml\u003e element in selectors and events.\n\n if (name === 'html') {\n return '';\n }\n\n if (element.id) {\n name += \"#\".concat(element.id);\n }\n\n var stringClassNames = element.getAttribute('class');\n\n if (stringClassNames) {\n stringClassNames.split(/\\s+/).forEach(function (className) {\n name += \".\".concat(className);\n });\n }\n\n ['alt', 'name', 'title', 'type'].forEach(function (attrName) {\n var attr = element.getAttribute(attrName);\n\n if (attr) {\n name += \"[\".concat(attrName, \"=\\\"\").concat(attr, \"\\\"]\");\n }\n });\n var siblings = getSiblings(element);\n\n if (siblings.length \u003e 1) {\n name += \":nth-child(\".concat(Array.prototype.indexOf.call(siblings, element) + 1, \")\");\n }\n\n return name;\n }\n function stringSelectorOfElement(element) {\n var name = stringNameOfElement(element);\n\n if (element.parentNode \u0026\u0026 element.parentNode.tagName) {\n var parentName = stringSelectorOfElement(element.parentNode);\n\n if (parentName.length \u003e 0) {\n return \"\".concat(parentName, \" \u003e \").concat(name);\n }\n }\n\n return name;\n }\n function stringTextOfElement(element) {\n var text = element.textContent || element.innerText || '';\n\n if (!text \u0026\u0026 (element.type === 'submit' || element.type === 'button')) {\n text = element.value;\n }\n\n return truncate(text.trim(), 300);\n }\n function nativeFetch() {\n if (!window.fetch) {\n return false;\n }\n\n if (isNative(window.fetch)) {\n return true;\n } // If fetch isn't native, it may be wrapped by someone else. Try to get\n // a pristine function from an iframe.\n\n\n try {\n var sandbox = document.createElement('iframe');\n sandbox.style.display = 'none';\n document.head.appendChild(sandbox);\n var result = sandbox.contentWindow.fetch \u0026\u0026 isNative(sandbox.contentWindow.fetch);\n document.head.removeChild(sandbox);\n return result;\n } catch (err) {\n if (console \u0026\u0026 console.warn) {\n console.warn('failed to detect native fetch via iframe: ' + err);\n }\n }\n\n return false;\n }\n\n function isNative(func) {\n return func.toString().indexOf('native') !== -1;\n }\n\n function parseURL(url) {\n // Regexp: https://tools.ietf.org/html/rfc3986#appendix-B\n var match = url.match(/^(([^:/?#]+):)?(\\/\\/([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?$/) || {};\n return {\n protocol: match[2],\n host: match[4],\n pathname: match[5]\n };\n }\n function localURLPathname(url) {\n var parsed = parseURL(url);\n var parsedDocURL = parseURL(document.URL); // URL must be relative\n\n if (!parsed.host || !parsed.protocol) {\n return parsed.pathname;\n } // Same domain\n\n\n if (parsed.protocol === parsedDocURL.protocol \u0026\u0026 parsed.host === parsedDocURL.host) {\n return parsed.pathname;\n } // x-domain\n\n\n return \"\".concat(parsed.protocol, \"://\").concat(parsed.host).concat(parsed.pathname);\n } // Helpers\n\n function getSiblings(element) {\n try {\n var nodes = element.parentNode.childNodes;\n var siblings = [];\n Array.prototype.forEach.call(nodes, function (node) {\n if (node.tagName \u0026\u0026 node.tagName === element.tagName) {\n siblings.push(node);\n }\n });\n return siblings;\n } catch (e) {\n return [];\n }\n }\n\n function truncate(string, length) {\n if (string.length \u003e length) {\n string = string.substr(0, length) + '...';\n }\n\n return string;\n }\n\n function builder() {\n var VERSION = '2.3.0',\n NOTIFIER = {\n name: 'honeybadger-js',\n url: 'https://github.com/honeybadger-io/honeybadger-js',\n version: VERSION,\n language: 'javascript'\n }; // Used to control initial setup across clients.\n\n var loaded = false,\n installed = false,\n factoryCount = 0; // Used to prevent reporting duplicate errors across instances.\n\n var currentErr; // Utilities.\n\n function merge(obj1, obj2) {\n var obj3 = {};\n\n for (var k in obj1) {\n obj3[k] = obj1[k];\n }\n\n for (var k in obj2) {\n obj3[k] = obj2[k];\n }\n\n return obj3;\n } // Returns a new object with properties from other object.\n\n\n function newObject(obj) {\n if (_typeof(obj) !== 'object') {\n return {};\n }\n\n var new_obj = {};\n\n for (var k in obj) {\n new_obj[k] = obj[k];\n }\n\n return new_obj;\n }\n\n function mergeErr(err1, err2) {\n var ret = merge(err1, err2);\n\n if (err1.context \u0026\u0026 err2.context) {\n ret.context = merge(err1.context, err2.context);\n }\n\n return ret;\n }\n\n function currentErrIs(err) {\n if (!currentErr) {\n return false;\n }\n\n if (currentErr.name !== err.name) {\n return false;\n }\n\n if (currentErr.message !== err.message) {\n return false;\n }\n\n if (currentErr.stack !== err.stack) {\n return false;\n }\n\n return true;\n }\n\n function isIgnored(err, patterns) {\n if (!Array.isArray(patterns)) {\n return false;\n }\n\n return patterns.some(function (p) {\n return p.test(err.message);\n });\n }\n\n function encodeCookie(object) {\n if (_typeof(object) !== 'object') {\n return undefined;\n }\n\n var cookies = [];\n\n for (var k in object) {\n cookies.push(k + '=' + object[k]);\n }\n\n return cookies.join(';');\n }\n\n function stackTrace(err) {\n // From TraceKit: Opera 10 *destroys* its stacktrace property if you try to\n // access the stack property first.\n return err.stacktrace || err.stack || undefined;\n }\n\n function generateStackTrace(err) {\n var stack;\n var maxStackSize = 10;\n\n if (err \u0026\u0026 (stack = stackTrace(err))) {\n return {\n stack: stack,\n generator: undefined\n };\n }\n\n try {\n throw new Error('');\n } catch (e) {\n if (stack = stackTrace(e)) {\n return {\n stack: stack,\n generator: 'throw'\n };\n }\n }\n\n stack = ['\u003ccall-stack\u003e'];\n var curr = arguments.callee;\n\n while (curr \u0026\u0026 stack.length \u003c maxStackSize) {\n if (/function(?:\\s+([\\w$]+))+\\s*\\(/.test(curr.toString())) {\n stack.push(RegExp.$1 || '\u003canonymous\u003e');\n } else {\n stack.push('\u003canonymous\u003e');\n }\n\n try {\n curr = curr.caller;\n } catch (e) {\n break;\n }\n }\n\n return {\n stack: stack.join('\\n'),\n generator: 'walk'\n };\n }\n\n function checkHandlers(handlers, err, response) {\n var handler, i, len;\n\n for (i = 0, len = handlers.length; i \u003c len; i++) {\n handler = handlers[i];\n\n if (handler(err, response) === false) {\n return true;\n }\n }\n\n return false;\n }\n\n function objectIsEmpty(obj) {\n for (var k in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, k)) {\n return false;\n }\n }\n\n return true;\n }\n\n function objectIsExtensible(obj) {\n if (typeof Object.isExtensible !== 'function') {\n return true;\n }\n\n return Object.isExtensible(obj);\n } // Client factory.\n\n\n var factory = function factory(opts) {\n factoryCount += 1;\n var singleton = factoryCount === 1;\n var notSingleton = !singleton;\n var defaultProps = [];\n var queue = [];\n var self = {\n context: {},\n beforeNotifyHandlers: [],\n afterNotifyHandlers: [],\n breadcrumbs: [],\n errorsSent: 0,\n breadcrumbsEnabled: {\n dom: true,\n network: true,\n navigation: true,\n console: true\n }\n };\n\n if (_typeof(opts) === 'object') {\n for (var k in opts) {\n self[k] = opts[k];\n }\n }\n\n function log() {\n var console = window.console;\n\n if (console) {\n var args = Array.prototype.slice.call(arguments);\n args.unshift('[Honeybadger]');\n console.log.apply(console, args);\n }\n }\n\n function debug() {\n if (config('debug')) {\n return log.apply(this, arguments);\n }\n }\n\n function config(key, fallback) {\n var value = self[key];\n\n if (value === undefined) {\n value = self[key.toLowerCase()];\n }\n\n if (value === 'false') {\n value = false;\n }\n\n if (value !== undefined) {\n return value;\n }\n\n return fallback;\n }\n\n function onErrorEnabled() {\n if (notSingleton) {\n return false;\n }\n\n return config('onerror', true);\n }\n\n function onUnhandledRejectionEnabled() {\n if (notSingleton) {\n return false;\n }\n\n return config('onunhandledrejection', true);\n }\n\n function breadcrumbsEnabled(type) {\n if (self.breadcrumbsEnabled === true) {\n return true;\n }\n\n if (type) {\n return self.breadcrumbsEnabled[type] === true;\n }\n\n return self.breadcrumbsEnabled !== false;\n }\n\n function baseURL() {\n return 'http' + (config('ssl', true) \u0026\u0026 's' || '') + '://' + config('host', 'api.honeybadger.io');\n }\n\n function request(apiKey, notice) {\n try {\n var payload = buildPayload(notice);\n var x = new XMLHttpRequest();\n x.open('POST', baseURL() + '/v1/notices/js', config('async', true));\n x.setRequestHeader('X-API-Key', apiKey);\n x.setRequestHeader('Content-Type', 'application/json');\n x.setRequestHeader('Accept', 'text/json, application/json');\n x.send(JSON.stringify(sanitize(payload, config('max_depth', 8))));\n\n x.onload = function () {\n var handlers = Array.prototype.slice.call(self.afterNotifyHandlers);\n\n if (notice.afterNotify) {\n handlers.unshift(notice.afterNotify);\n }\n\n if (x.status !== 201) {\n checkHandlers(handlers, new Error(\"Bad HTTP response: \".concat(x.status)), notice);\n debug(\"Unable to send error report: \".concat(x.status, \": \").concat(x.statusText), x, notice);\n return;\n }\n\n checkHandlers(handlers, undefined, merge(notice, {\n id: JSON.parse(x.response).id\n }));\n debug('Error report sent', payload);\n };\n } catch (e) {\n checkHandlers(self.afterNotifyHandlers, e, notice);\n log('Unable to send error report: error while initializing request', e, notice);\n }\n }\n\n function send(notice) {\n currentErr = null;\n\n if (config('disabled', false)) {\n debug('Dropping notice: honeybadger.js is disabled', notice);\n return false;\n }\n\n var apiKey = config('apiKey', config('api_key'));\n\n if (!apiKey) {\n log('Unable to send error report: no API key has been configured');\n return false;\n }\n\n if (exceedsMaxErrors()) {\n debug('Dropping notice: max errors exceeded', notice);\n return false;\n }\n\n incrementErrorsCount();\n request(apiKey, notice);\n return true;\n }\n\n function buildPayload(err) {\n var data = {};\n\n if (err.userAgent) {\n data['HTTP_USER_AGENT'] = err.userAgent;\n }\n\n if (err.referrer) {\n data['HTTP_REFERER'] = err.referrer;\n }\n\n if (typeof err.cookies === 'string') {\n data['HTTP_COOKIE'] = err.cookies;\n } else if (_typeof(err.cookies) === 'object') {\n data['HTTP_COOKIE'] = encodeCookie(err.cookies);\n }\n\n return {\n 'notifier': NOTIFIER,\n 'breadcrumbs': {\n 'enabled': breadcrumbsEnabled(),\n 'trail': err.breadcrumbs\n },\n 'error': {\n 'class': err.name,\n 'message': err.message,\n 'backtrace': err.stack,\n 'generator': err.generator,\n 'fingerprint': err.fingerprint\n },\n 'request': {\n 'url': err.url,\n 'component': err.component,\n 'action': err.action,\n 'context': err.context,\n 'cgi_data': data,\n 'params': err.params\n },\n 'server': {\n 'project_root': err.projectRoot,\n 'environment_name': err.environment,\n 'revision': err.revision\n }\n };\n }\n\n function notify(err, generated) {\n if (!err) {\n err = {};\n }\n\n if (Object.prototype.toString.call(err) === '[object Error]') {\n var e = err;\n err = merge(err, {\n name: e.name,\n message: e.message,\n stack: stackTrace(e)\n });\n }\n\n if (!(_typeof(err) === 'object')) {\n var m = String(err);\n err = {\n message: m\n };\n }\n\n if (currentErrIs(err)) {\n // Skip the duplicate error.\n return false;\n } else if (currentErr \u0026\u0026 loaded) {\n // This is a different error, send the old one now.\n send(currentErr);\n }\n\n if (objectIsEmpty(err)) {\n return false;\n }\n\n var generator;\n\n if (generated) {\n err.stack = generated.stack;\n generator = generated.generator;\n }\n\n err = merge(err, {\n name: err.name || 'Error',\n context: merge(self.context, err.context),\n url: err.url || document.URL,\n projectRoot: err.projectRoot || err.project_root || config('projectRoot', config('project_root', window.location.protocol + '//' + window.location.host)),\n environment: err.environment || config('environment'),\n component: err.component || config('component'),\n action: err.action || config('action'),\n revision: err.revision || config('revision'),\n userAgent: err.userAgent || navigator.userAgent,\n referrer: err.referrer || document.referrer\n });\n self.addBreadcrumb('Honeybadger Notice', {\n category: 'notice',\n metadata: {\n message: err.message,\n name: err.name,\n stack: err.stack\n }\n });\n err.breadcrumbs = self.breadcrumbs.slice();\n var stack_before_handlers = err.stack;\n\n if (checkHandlers(self.beforeNotifyHandlers, err)) {\n return false;\n }\n\n if (err.stack != stack_before_handlers) {\n // Stack changed, so it's not generated.\n generator = undefined;\n }\n\n if (isIgnored(err, config('ignorePatterns'))) {\n return false;\n }\n\n err.generator = generator;\n currentErr = err;\n\n if (loaded) {\n debug('Deferring notice', err);\n window.setTimeout(function () {\n if (currentErrIs(err)) {\n send(err);\n }\n });\n } else {\n debug('Queuing notice', err);\n queue.push(err);\n }\n\n return err;\n }\n\n var preferCatch = true; // IE \u003c 10\n\n if (!window.atob) {\n preferCatch = false;\n } // See https://developer.mozilla.org/en-US/docs/Web/API/ErrorEvent\n\n\n if (window.ErrorEvent) {\n try {\n if (new window.ErrorEvent('').colno === 0) {\n preferCatch = false;\n }\n } catch (_e) {}\n } // wrap always returns the same function so that callbacks can be removed via\n // removeEventListener.\n\n\n function wrap(fn, opts) {\n if (!opts) {\n opts = {};\n }\n\n try {\n if (typeof fn !== 'function') {\n return fn;\n }\n\n if (!objectIsExtensible(fn)) {\n return fn;\n }\n\n if (!fn.___hb) {\n fn.___hb = function () {\n var onerror = onErrorEnabled(); // Don't catch if the browser is old or supports the new error\n // object and there is a window.onerror handler available instead.\n\n if (preferCatch \u0026\u0026 (onerror || opts.force) || opts.force \u0026\u0026 !onerror) {\n try {\n return fn.apply(this, arguments);\n } catch (err) {\n var generated = {\n stack: stackTrace(err)\n };\n self.addBreadcrumb(opts.component ? \"\".concat(opts.component, \": \").concat(err.name) : err.name, {\n category: 'error',\n metadata: {\n message: err.message,\n name: err.name,\n stack: generated.stack\n }\n });\n notify(err, generated);\n throw err;\n }\n } else {\n return fn.apply(this, arguments);\n }\n };\n }\n\n fn.___hb.___hb = fn.___hb;\n return fn.___hb;\n } catch (_e) {\n return fn;\n }\n } // Public API.\n\n\n self.notify = function (err, name, extra) {\n if (!err) {\n err = {};\n }\n\n if (Object.prototype.toString.call(err) === '[object Error]') {\n var e = err;\n err = merge(err, {\n name: e.name,\n message: e.message,\n stack: stackTrace(e)\n });\n }\n\n if (!(_typeof(err) === 'object')) {\n var m = String(err);\n err = {\n message: m\n };\n }\n\n if (name \u0026\u0026 !(_typeof(name) === 'object')) {\n var n = String(name);\n name = {\n name: n\n };\n }\n\n if (name) {\n err = mergeErr(err, name);\n }\n\n if (_typeof(extra) === 'object') {\n err = mergeErr(err, extra);\n }\n\n return notify(err, generateStackTrace(err));\n };\n\n self.wrap = function (func) {\n return wrap(func, {\n force: true\n });\n };\n\n self.setContext = function (context) {\n if (_typeof(context) === 'object') {\n self.context = merge(self.context, context);\n }\n\n return self;\n };\n\n self.resetContext = function (context) {\n if (_typeof(context) === 'object') {\n self.context = merge({}, context);\n } else {\n self.context = {};\n }\n\n return self;\n };\n\n self.configure = function (opts) {\n for (var k in opts) {\n self[k] = opts[k];\n }\n\n if (singleton \u0026\u0026 !installed) {\n installed = true;\n integrations.forEach(function (integration) {\n return integration();\n });\n }\n\n return self;\n };\n\n self.beforeNotify = function (handler) {\n self.beforeNotifyHandlers.push(handler);\n return self;\n };\n\n self.afterNotify = function (handler) {\n self.afterNotifyHandlers.push(handler);\n return self;\n };\n\n var indexOf = [].indexOf || function (item) {\n for (var i = 0, l = this.length; i \u003c l; i++) {\n if (i in this \u0026\u0026 this[i] === item) return i;\n }\n\n return -1;\n };\n\n self.reset = function () {\n self.context = {};\n self.beforeNotifyHandlers = [];\n self.breadcrumbs = [];\n\n for (var k in self) {\n if (indexOf.call(defaultProps, k) == -1) {\n self[k] = undefined;\n }\n }\n\n self.resetMaxErrors();\n return self;\n };\n\n self.resetMaxErrors = function () {\n return self.errorsSent = 0;\n };\n\n self.getVersion = function () {\n return VERSION;\n };\n\n self.addBreadcrumb = function (message, opts) {\n if (!breadcrumbsEnabled()) return;\n opts = opts || {};\n var metadata = newObject(opts.metadata);\n var category = opts.category || 'custom';\n var timestamp = new Date().toISOString();\n self.breadcrumbs.push({\n category: category,\n message: message,\n metadata: metadata,\n timestamp: timestamp\n });\n var limit = config('maxBreadcrumbs', 40);\n\n if (self.breadcrumbs.length \u003e limit) {\n self.breadcrumbs = self.breadcrumbs.slice(self.breadcrumbs.length - limit);\n }\n\n return self;\n };\n\n var integrations = []; // Install instrumentation.\n // This should happen once for the first factory call.\n\n function instrument(object, name, replacement) {\n if (notSingleton) {\n return;\n }\n\n if (!object || !name || !replacement || !(name in object)) {\n return;\n }\n\n var original = object[name];\n\n while (original \u0026\u0026 original.__hb_original) {\n original = original.__hb_original;\n }\n\n object[name] = replacement(original);\n object[name].__hb_original = original;\n } // Breadcrumbs: instrument click events\n\n\n integrations.push(function () {\n if (!breadcrumbsEnabled('dom')) {\n return;\n }\n\n window.addEventListener('click', function (event) {\n var message, selector, text;\n\n try {\n message = stringNameOfElement(event.target);\n selector = stringSelectorOfElement(event.target);\n text = stringTextOfElement(event.target);\n } catch (e) {\n message = 'UI Click';\n selector = '[unknown]';\n text = '[unknown]';\n } // There's nothing to display\n\n\n if (message.length === 0) {\n return;\n }\n self.addBreadcrumb(message, {\n category: 'ui.click',\n metadata: {\n selector: selector,\n text: text,\n event: event\n }\n });\n }, true);\n }); // Breadcrumbs: instrument XMLHttpRequest\n\n integrations.push(function () {\n if (!breadcrumbsEnabled('network')) {\n return;\n } // -- On xhr.open: capture initial metadata\n\n\n instrument(XMLHttpRequest.prototype, 'open', function (original) {\n return function () {\n var xhr = this;\n var url = arguments[1];\n var method = typeof arguments[0] === 'string' ? arguments[0].toUpperCase() : arguments[0];\n var message = \"\".concat(method, \" \").concat(localURLPathname(url));\n this.__hb_xhr = {\n type: 'xhr',\n method: method,\n url: url,\n message: message\n };\n\n if (typeof original === 'function') {\n original.apply(xhr, arguments);\n }\n };\n }); // -- On xhr.send: set up xhr.onreadystatechange to report breadcrumb\n\n instrument(XMLHttpRequest.prototype, 'send', function (original) {\n return function () {\n var xhr = this;\n\n function onreadystatechangeHandler() {\n if (xhr.readyState === 4) {\n var message;\n\n if (xhr.__hb_xhr) {\n xhr.__hb_xhr.status_code = xhr.status;\n message = xhr.__hb_xhr.message;\n delete xhr.__hb_xhr.message;\n }\n\n self.addBreadcrumb(message || 'XMLHttpRequest', {\n category: 'request',\n metadata: xhr.__hb_xhr\n });\n }\n }\n\n if ('onreadystatechange' in xhr \u0026\u0026 typeof xhr.onreadystatechange === 'function') {\n instrument(xhr, 'onreadystatechange', function (original) {\n return function () {\n onreadystatechangeHandler();\n\n if (typeof original === 'function') {\n original.apply(this, arguments);\n }\n };\n });\n } else {\n xhr.onreadystatechange = onreadystatechangeHandler;\n }\n\n if (typeof original === 'function') {\n original.apply(xhr, arguments);\n }\n };\n });\n }); // Breadcrumbs: instrument fetch\n\n integrations.push(function () {\n if (!breadcrumbsEnabled('network')) {\n return;\n }\n\n if (!nativeFetch()) {\n // Polyfills use XHR.\n return;\n }\n\n instrument(window, 'fetch', function (original) {\n return function () {\n var input = arguments[0];\n var method = 'GET';\n var url;\n\n if (typeof input === 'string') {\n url = input;\n } else if ('Request' in window \u0026\u0026 input instanceof Request) {\n url = input.url;\n\n if (input.method) {\n method = input.method;\n }\n } else {\n url = String(input);\n }\n\n if (arguments[1] \u0026\u0026 arguments[1].method) {\n method = arguments[1].method;\n }\n\n if (typeof method === 'string') {\n method = method.toUpperCase();\n }\n\n var message = \"\".concat(method, \" \").concat(localURLPathname(url));\n var metadata = {\n type: 'fetch',\n method: method,\n url: url\n };\n return original.apply(this, arguments).then(function (response) {\n metadata.status_code = response.status;\n self.addBreadcrumb(message, {\n category: 'request',\n metadata: metadata\n });\n return response;\n }).catch(function (error) {\n self.addBreadcrumb('fetch error', {\n category: 'error',\n metadata: metadata\n });\n throw error;\n });\n };\n });\n }); // Breadcrumbs: instrument navigation\n\n integrations.push(function () {\n if (!breadcrumbsEnabled('navigation')) {\n return;\n } // The last known href of the current page\n\n\n var lastHref = window.location.href;\n\n function recordUrlChange(from, to) {\n lastHref = to;\n self.addBreadcrumb('Page changed', {\n category: 'navigation',\n metadata: {\n from: from,\n to: to\n }\n });\n } // https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onpopstate\n\n\n instrument(window, 'onpopstate', function (original) {\n return function () {\n recordUrlChange(lastHref, window.location.href);\n\n if (original) {\n return original.apply(this, arguments);\n }\n };\n }); // https://developer.mozilla.org/en-US/docs/Web/API/History/pushState\n // https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState\n\n function historyWrapper(original) {\n return function () {\n var url = arguments.length \u003e 2 ? arguments[2] : undefined;\n\n if (url) {\n recordUrlChange(lastHref, String(url));\n }\n\n return original.apply(this, arguments);\n };\n }\n\n instrument(window.history, 'pushState', historyWrapper);\n instrument(window.history, 'replaceState', historyWrapper);\n }); // Breadcrumbs: instrument console\n\n integrations.push(function () {\n if (!breadcrumbsEnabled('console')) {\n return;\n }\n\n function inspectArray(obj) {\n if (!Array.isArray(obj)) {\n return '';\n }\n\n return obj.map(function (value) {\n try {\n return String(value);\n } catch (e) {\n return '[unknown]';\n }\n }).join(' ');\n }\n\n ['debug', 'info', 'warn', 'error', 'log'].forEach(function (level) {\n instrument(window.console, level, function (original) {\n return function () {\n var args = Array.prototype.slice.call(arguments);\n var message = inspectArray(args);\n var opts = {\n category: 'log',\n metadata: {\n level: level,\n arguments: sanitize(args, 3)\n }\n };\n self.addBreadcrumb(message, opts);\n\n if (typeof original === 'function') {\n Function.prototype.apply.call(original, window.console, arguments);\n }\n };\n });\n });\n }); // Wrap timers\n\n (function () {\n function instrumentTimer(wrapOpts) {\n return function (original) {\n // See https://developer.mozilla.org/en-US/docs/Web/API/WindowTimers/setTimeout\n return function (func, delay) {\n if (typeof func === 'function') {\n var args = Array.prototype.slice.call(arguments, 2);\n func = wrap(func, wrapOpts);\n return original(function () {\n func.apply(null, args);\n }, delay);\n } else {\n return original(func, delay);\n }\n };\n };\n }\n instrument(window, 'setTimeout', instrumentTimer({\n component: 'setTimeout'\n }));\n instrument(window, 'setInterval', instrumentTimer({\n component: 'setInterval'\n }));\n })(); // Wrap event listeners\n // Event targets borrowed from bugsnag-js:\n // See https://github.com/bugsnag/bugsnag-js/blob/d55af916a4d3c7757f979d887f9533fe1a04cc93/src/bugsnag.js#L542\n\n\n 'EventTarget Window Node ApplicationCache AudioTrackList ChannelMergerNode CryptoOperation EventSource FileReader HTMLUnknownElement IDBDatabase IDBRequest IDBTransaction KeyOperation MediaController MessagePort ModalWindow Notification SVGElementInstance Screen TextTrack TextTrackCue TextTrackList WebSocket WebSocketWorker Worker XMLHttpRequest XMLHttpRequestEventTarget XMLHttpRequestUpload'.replace(/\\w+/g, function (prop) {\n var prototype = window[prop] \u0026\u0026 window[prop].prototype;\n\n if (prototype \u0026\u0026 prototype.hasOwnProperty \u0026\u0026 prototype.hasOwnProperty('addEventListener')) {\n instrument(prototype, 'addEventListener', function (original) {\n var wrapOpts = {\n component: \"\".concat(prop, \".prototype.addEventListener\")\n }; // See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener\n\n return function (type, listener, useCapture, wantsUntrusted) {\n try {\n if (listener \u0026\u0026 listener.handleEvent != null) {\n listener.handleEvent = wrap(listener.handleEvent, wrapOpts);\n }\n } catch (e) {\n // Ignore 'Permission denied to access property \"handleEvent\"' errors.\n log(e);\n }\n\n return original.call(this, type, wrap(listener, wrapOpts), useCapture, wantsUntrusted);\n };\n });\n instrument(prototype, 'removeEventListener', function (original) {\n return function (type, listener, useCapture, wantsUntrusted) {\n original.call(this, type, listener, useCapture, wantsUntrusted);\n return original.call(this, type, wrap(listener), useCapture, wantsUntrusted);\n };\n });\n }\n }); // Wrap window.onerror\n\n instrument(window, 'onerror', function (original) {\n function onerror(msg, url, line, col, err) {\n debug('window.onerror callback invoked', arguments); // Skip if the error is already being sent.\n\n if (currentErr) {\n return;\n }\n\n if (!onErrorEnabled()) {\n return;\n }\n\n if (line === 0 \u0026\u0026 /Script error\\.?/.test(msg)) {\n // See https://developer.mozilla.org/en/docs/Web/API/GlobalEventHandlers/onerror#Notes\n log('Ignoring cross-domain script error: enable CORS to track these types of errors', arguments);\n return;\n } // Simulate v8 stack\n\n\n var simulatedStack = [msg, '\\n at ? (', url || 'unknown', ':', line || 0, ':', col || 0, ')'].join('');\n var generated;\n\n if (err) {\n generated = {\n stack: stackTrace(err)\n };\n\n if (!generated.stack) {\n generated = {\n stack: simulatedStack\n };\n }\n } else {\n // Important: leave `generated` undefined\n err = {\n name: 'window.onerror',\n message: msg,\n stack: simulatedStack\n };\n }\n\n self.addBreadcrumb(err.name === 'window.onerror' || !err.name ? 'window.onerror' : \"window.onerror: \".concat(err.name), {\n category: 'error',\n metadata: {\n message: err.message,\n name: err.name,\n stack: generated ? generated.stack : err.stack\n }\n });\n notify(err, generated);\n } // See https://developer.mozilla.org/en-US/docs/Web/API/GlobalEventHandlers/onerror\n\n\n return function (msg, url, line, col, err) {\n onerror(msg, url, line, col, err);\n\n if (typeof original === 'function' \u0026\u0026 config('_onerror_call_orig', true)) {\n return original.apply(this, arguments);\n }\n\n return false;\n };\n }); // Wrap window.onunhandledrejection\n\n instrument(window, 'onunhandledrejection', function (original) {\n // See https://developer.mozilla.org/en-US/docs/Web/API/Window/unhandledrejection_event\n function onunhandledrejection(promiseRejectionEvent) {\n debug('window.onunhandledrejection callback invoked', arguments); // Skip if the error is already being sent.\n\n if (currentErr) {\n return;\n }\n\n if (!onUnhandledRejectionEnabled()) {\n return;\n }\n\n var reason = promiseRejectionEvent.reason;\n\n if (reason instanceof Error) {\n // simulate v8 stack\n var fileName = reason.fileName || 'unknown';\n var lineNumber = reason.lineNumber || 0;\n var stackFallback = \"\".concat(reason.message, \"\\n at ? (\").concat(fileName, \":\").concat(lineNumber, \")\");\n var stack = stackTrace(reason) || stackFallback;\n var err = {\n name: reason.name,\n message: \"UnhandledPromiseRejectionWarning: \".concat(reason),\n stack: stack\n };\n self.addBreadcrumb(\"window.onunhandledrejection: \".concat(err.name), {\n category: 'error',\n metadata: err\n });\n notify(err);\n return;\n }\n\n var message = typeof reason === 'string' ? reason : JSON.stringify(reason);\n notify({\n name: 'window.onunhandledrejection',\n message: \"UnhandledPromiseRejectionWarning: \".concat(message)\n });\n }\n\n return function (promiseRejectionEvent) {\n onunhandledrejection(promiseRejectionEvent);\n\n if (typeof original === 'function') {\n original.apply(this, arguments);\n }\n };\n });\n\n function incrementErrorsCount() {\n return self.errorsSent++;\n }\n\n function exceedsMaxErrors() {\n var maxErrors = config('maxErrors');\n return maxErrors \u0026\u0026 self.errorsSent \u003e= maxErrors;\n } // Save original state for reset()\n\n\n for (var k in self) {\n defaultProps.push(k);\n } // Initialization.\n\n\n debug('Initializing honeybadger.js ' + VERSION); // See https://developer.mozilla.org/en-US/docs/Web/API/Document/readyState\n // https://www.w3.org/TR/html5/dom.html#dom-document-readystate\n // The 'loaded' state is for older versions of Safari.\n\n if (/complete|interactive|loaded/.test(document.readyState)) {\n loaded = true;\n debug('honeybadger.js ' + VERSION + ' ready');\n } else {\n debug('Installing ready handler');\n\n var domReady = function domReady() {\n loaded = true;\n debug('honeybadger.js ' + VERSION + ' ready');\n var notice;\n\n while (notice = queue.pop()) {\n send(notice);\n }\n };\n\n if (document.addEventListener) {\n document.addEventListener('DOMContentLoaded', domReady, true);\n } else {\n window.attachEvent('onload', domReady);\n }\n }\n\n return self;\n };\n\n return factory;\n }\n\n var factory = builder();\n var singleton = factory();\n singleton.factory = factory;\n\n return singleton;\n\n})));\n//# sourceMappingURL=honeybadger.js.map;\n// I18n.js\n// =======\n//\n// This small library provides the Rails I18n API on the Javascript.\n// You don't actually have to use Rails (or even Ruby) to use I18n.js.\n// Just make sure you export all translations in an object like this:\n//\n// I18n.translations.en = {\n// hello: \"Hello World\"\n// };\n//\n// See tests for specific formatting like numbers and dates.\n//\n\n// Using UMD pattern from\n// https://github.com/umdjs/umd#regular-module\n// `returnExports.js` version\n;(function (root, factory) {\n if (typeof define === 'function' \u0026\u0026 define.amd) {\n // AMD. Register as an anonymous module.\n define(\"i18n\", function(){ return factory(root);});\n } else if (typeof module === 'object' \u0026\u0026 module.exports) {\n // Node. Does not work with strict CommonJS, but\n // only CommonJS-like environments that support module.exports,\n // like Node.\n module.exports = factory(root);\n } else {\n // Browser globals (root is window)\n root.I18n = factory(root);\n }\n}(this, function(global) {\n \"use strict\";\n\n // Use previously defined object if exists in current scope\n var I18n = global \u0026\u0026 global.I18n || {};\n\n // Just cache the Array#slice function.\n var slice = Array.prototype.slice;\n\n // Apply number padding.\n var padding = function(number) {\n return (\"0\" + number.toString()).substr(-2);\n };\n\n // Improved toFixed number rounding function with support for unprecise floating points\n // JavaScript's standard toFixed function does not round certain numbers correctly (for example 0.105 with precision 2).\n var toFixed = function(number, precision) {\n return decimalAdjust('round', number, -precision).toFixed(precision);\n };\n\n // Is a given variable an object?\n // Borrowed from Underscore.js\n var isObject = function(obj) {\n var type = typeof obj;\n return type === 'function' || type === 'object'\n };\n\n var isFunction = function(func) {\n var type = typeof func;\n return type === 'function'\n };\n\n // Check if value is different than undefined and null;\n var isSet = function(value) {\n return typeof(value) !== 'undefined' \u0026\u0026 value !== null;\n };\n\n // Is a given value an array?\n // Borrowed from Underscore.js\n var isArray = function(val) {\n if (Array.isArray) {\n return Array.isArray(val);\n }\n return Object.prototype.toString.call(val) === '[object Array]';\n };\n\n var isString = function(val) {\n return typeof val === 'string' || Object.prototype.toString.call(val) === '[object String]';\n };\n\n var isNumber = function(val) {\n return typeof val === 'number' || Object.prototype.toString.call(val) === '[object Number]';\n };\n\n var isBoolean = function(val) {\n return val === true || val === false;\n };\n\n var isNull = function(val) {\n return val === null;\n };\n\n var decimalAdjust = function(type, value, exp) {\n // If the exp is undefined or zero...\n if (typeof exp === 'undefined' || +exp === 0) {\n return Math[type](value);\n }\n value = +value;\n exp = +exp;\n // If the value is not a number or the exp is not an integer...\n if (isNaN(value) || !(typeof exp === 'number' \u0026\u0026 exp % 1 === 0)) {\n return NaN;\n }\n // Shift\n value = value.toString().split('e');\n value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));\n // Shift back\n value = value.toString().split('e');\n return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));\n };\n\n var lazyEvaluate = function(message, scope) {\n if (isFunction(message)) {\n return message(scope);\n } else {\n return message;\n }\n };\n\n var merge = function (dest, obj) {\n var key, value;\n for (key in obj) if (obj.hasOwnProperty(key)) {\n value = obj[key];\n if (isString(value) || isNumber(value) || isBoolean(value) || isArray(value) || isNull(value)) {\n dest[key] = value;\n } else {\n if (dest[key] == null) dest[key] = {};\n merge(dest[key], value);\n }\n }\n return dest;\n };\n\n // Set default days/months translations.\n var DATE = {\n day_names: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"]\n , abbr_day_names: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"]\n , month_names: [null, \"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"]\n , abbr_month_names: [null, \"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"]\n , meridian: [\"AM\", \"PM\"]\n };\n\n // Set default number format.\n var NUMBER_FORMAT = {\n precision: 3\n , separator: \".\"\n , delimiter: \",\"\n , strip_insignificant_zeros: false\n };\n\n // Set default currency format.\n var CURRENCY_FORMAT = {\n unit: \"$\"\n , precision: 2\n , format: \"%u%n\"\n , sign_first: true\n , delimiter: \",\"\n , separator: \".\"\n };\n\n // Set default percentage format.\n var PERCENTAGE_FORMAT = {\n unit: \"%\"\n , precision: 3\n , format: \"%n%u\"\n , separator: \".\"\n , delimiter: \"\"\n };\n\n // Set default size units.\n var SIZE_UNITS = [null, \"kb\", \"mb\", \"gb\", \"tb\"];\n\n // Other default options\n var DEFAULT_OPTIONS = {\n // Set default locale. This locale will be used when fallback is enabled and\n // the translation doesn't exist in a particular locale.\n defaultLocale: \"en\"\n // Set the current locale to `en`.\n , locale: \"en\"\n // Set the translation key separator.\n , defaultSeparator: \".\"\n // Set the placeholder format. Accepts `{{placeholder}}` and `%{placeholder}`.\n , placeholder: /(?:\\{\\{|%\\{)(.*?)(?:\\}\\}?)/gm\n // Set if engine should fallback to the default locale when a translation\n // is missing.\n , fallbacks: false\n // Set the default translation object.\n , translations: {}\n // Set missing translation behavior. 'message' will display a message\n // that the translation is missing, 'guess' will try to guess the string\n , missingBehaviour: 'message'\n // if you use missingBehaviour with 'message', but want to know that the\n // string is actually missing for testing purposes, you can prefix the\n // guessed string by setting the value here. By default, no prefix!\n , missingTranslationPrefix: ''\n };\n\n // Set default locale. This locale will be used when fallback is enabled and\n // the translation doesn't exist in a particular locale.\n I18n.reset = function() {\n var key;\n for (key in DEFAULT_OPTIONS) {\n this[key] = DEFAULT_OPTIONS[key];\n }\n };\n\n // Much like `reset`, but only assign options if not already assigned\n I18n.initializeOptions = function() {\n var key;\n for (key in DEFAULT_OPTIONS) if (!isSet(this[key])) {\n this[key] = DEFAULT_OPTIONS[key];\n }\n };\n I18n.initializeOptions();\n\n // Return a list of all locales that must be tried before returning the\n // missing translation message. By default, this will consider the inline option,\n // current locale and fallback locale.\n //\n // I18n.locales.get(\"de-DE\");\n // // [\"de-DE\", \"de\", \"en\"]\n //\n // You can define custom rules for any locale. Just make sure you return a array\n // containing all locales.\n //\n // // Default the Wookie locale to English.\n // I18n.locales[\"wk\"] = function(locale) {\n // return [\"en\"];\n // };\n //\n I18n.locales = {};\n\n // Retrieve locales based on inline locale, current locale or default to\n // I18n's detection.\n I18n.locales.get = function(locale) {\n var result = this[locale] || this[I18n.locale] || this[\"default\"];\n\n if (isFunction(result)) {\n result = result(locale);\n }\n\n if (isArray(result) === false) {\n result = [result];\n }\n\n return result;\n };\n\n // The default locale list.\n I18n.locales[\"default\"] = function(locale) {\n var locales = []\n , list = []\n ;\n\n // Handle the inline locale option that can be provided to\n // the `I18n.t` options.\n if (locale) {\n locales.push(locale);\n }\n\n // Add the current locale to the list.\n if (!locale \u0026\u0026 I18n.locale) {\n locales.push(I18n.locale);\n }\n\n // Add the default locale if fallback strategy is enabled.\n if (I18n.fallbacks \u0026\u0026 I18n.defaultLocale) {\n locales.push(I18n.defaultLocale);\n }\n\n // Locale code format 1:\n // According to RFC4646 (http://www.ietf.org/rfc/rfc4646.txt)\n // language codes for Traditional Chinese should be `zh-Hant`\n //\n // But due to backward compatibility\n // We use older version of IETF language tag\n // @see http://www.w3.org/TR/html401/struct/dirlang.html\n // @see http://en.wikipedia.org/wiki/IETF_language_tag\n //\n // Format: `language-code = primary-code ( \"-\" subcode )*`\n //\n // primary-code uses ISO639-1\n // @see http://en.wikipedia.org/wiki/List_of_ISO_639-1_codes\n // @see http://www.iso.org/iso/home/standards/language_codes.htm\n //\n // subcode uses ISO 3166-1 alpha-2\n // @see http://en.wikipedia.org/wiki/ISO_3166\n // @see http://www.iso.org/iso/country_codes.htm\n //\n // @note\n // subcode can be in upper case or lower case\n // defining it in upper case is a convention only\n\n\n // Locale code format 2:\n // Format: `code = primary-code ( \"-\" region-code )*`\n // primary-code uses ISO 639-1\n // script-code uses ISO 15924\n // region-code uses ISO 3166-1 alpha-2\n // Example: zh-Hant-TW, en-HK, zh-Hant-CN\n //\n // It is similar to RFC4646 (or actually the same),\n // but seems to be limited to language, script, region\n\n // Compute each locale with its country code.\n // So this will return an array containing\n // `de-DE` and `de`\n // or\n // `zh-hans-tw`, `zh-hans`, `zh`\n // locales.\n locales.forEach(function(locale) {\n var localeParts = locale.split(\"-\");\n var firstFallback = null;\n var secondFallback = null;\n if (localeParts.length === 3) {\n firstFallback = [\n localeParts[0],\n localeParts[1]\n ].join(\"-\");\n secondFallback = localeParts[0];\n }\n else if (localeParts.length === 2) {\n firstFallback = localeParts[0];\n }\n\n if (list.indexOf(locale) === -1) {\n list.push(locale);\n }\n\n if (! I18n.fallbacks) {\n return;\n }\n\n [\n firstFallback,\n secondFallback\n ].forEach(function(nullableFallbackLocale) {\n // We don't want null values\n if (typeof nullableFallbackLocale === \"undefined\") { return; }\n if (nullableFallbackLocale === null) { return; }\n // We don't want duplicate values\n //\n // Comparing with `locale` first is faster than\n // checking whether value's presence in the list\n if (nullableFallbackLocale === locale) { return; }\n if (list.indexOf(nullableFallbackLocale) !== -1) { return; }\n\n list.push(nullableFallbackLocale);\n });\n });\n\n // No locales set? English it is.\n if (!locales.length) {\n locales.push(\"en\");\n }\n\n return list;\n };\n\n // Hold pluralization rules.\n I18n.pluralization = {};\n\n // Return the pluralizer for a specific locale.\n // If no specify locale is found, then I18n's default will be used.\n I18n.pluralization.get = function(locale) {\n return this[locale] || this[I18n.locale] || this[\"default\"];\n };\n\n // The default pluralizer rule.\n // It detects the `zero`, `one`, and `other` scopes.\n I18n.pluralization[\"default\"] = function(count) {\n switch (count) {\n case 0: return [\"zero\", \"other\"];\n case 1: return [\"one\"];\n default: return [\"other\"];\n }\n };\n\n // Return current locale. If no locale has been set, then\n // the current locale will be the default locale.\n I18n.currentLocale = function() {\n return this.locale || this.defaultLocale;\n };\n\n // Check if value is different than undefined and null;\n I18n.isSet = isSet;\n\n // Find and process the translation using the provided scope and options.\n // This is used internally by some functions and should not be used as an\n // public API.\n I18n.lookup = function(scope, options) {\n options = options || {};\n\n var locales = this.locales.get(options.locale).slice()\n , locale\n , scopes\n , fullScope\n , translations\n ;\n\n fullScope = this.getFullScope(scope, options);\n\n while (locales.length) {\n locale = locales.shift();\n scopes = fullScope.split(options.separator || this.defaultSeparator);\n translations = this.translations[locale];\n\n if (!translations) {\n continue;\n }\n while (scopes.length) {\n translations = translations[scopes.shift()];\n\n if (translations === undefined || translations === null) {\n break;\n }\n }\n\n if (translations !== undefined \u0026\u0026 translations !== null) {\n return translations;\n }\n }\n\n if (isSet(options.defaultValue)) {\n return lazyEvaluate(options.defaultValue, scope);\n }\n };\n\n // lookup pluralization rule key into translations\n I18n.pluralizationLookupWithoutFallback = function(count, locale, translations) {\n var pluralizer = this.pluralization.get(locale)\n , pluralizerKeys = pluralizer(count)\n , pluralizerKey\n , message;\n\n if (isObject(translations)) {\n while (pluralizerKeys.length) {\n pluralizerKey = pluralizerKeys.shift();\n if (isSet(translations[pluralizerKey])) {\n message = translations[pluralizerKey];\n break;\n }\n }\n }\n\n return message;\n };\n\n // Lookup dedicated to pluralization\n I18n.pluralizationLookup = function(count, scope, options) {\n options = options || {};\n var locales = this.locales.get(options.locale).slice()\n , locale\n , scopes\n , translations\n , message\n ;\n scope = this.getFullScope(scope, options);\n\n while (locales.length) {\n locale = locales.shift();\n scopes = scope.split(options.separator || this.defaultSeparator);\n translations = this.translations[locale];\n\n if (!translations) {\n continue;\n }\n\n while (scopes.length) {\n translations = translations[scopes.shift()];\n if (!isObject(translations)) {\n break;\n }\n if (scopes.length === 0) {\n message = this.pluralizationLookupWithoutFallback(count, locale, translations);\n }\n }\n if (typeof message !== \"undefined\" \u0026\u0026 message !== null) {\n break;\n }\n }\n\n if (typeof message === \"undefined\" || message === null) {\n if (isSet(options.defaultValue)) {\n if (isObject(options.defaultValue)) {\n message = this.pluralizationLookupWithoutFallback(count, options.locale, options.defaultValue);\n } else {\n message = options.defaultValue;\n }\n translations = options.defaultValue;\n }\n }\n\n return { message: message, translations: translations };\n };\n\n // Rails changed the way the meridian is stored.\n // It started with `date.meridian` returning an array,\n // then it switched to `time.am` and `time.pm`.\n // This function abstracts this difference and returns\n // the correct meridian or the default value when none is provided.\n I18n.meridian = function() {\n var time = this.lookup(\"time\");\n var date = this.lookup(\"date\");\n\n if (time \u0026\u0026 time.am \u0026\u0026 time.pm) {\n return [time.am, time.pm];\n } else if (date \u0026\u0026 date.meridian) {\n return date.meridian;\n } else {\n return DATE.meridian;\n }\n };\n\n // Merge serveral hash options, checking if value is set before\n // overwriting any value. The precedence is from left to right.\n //\n // I18n.prepareOptions({name: \"John Doe\"}, {name: \"Mary Doe\", role: \"user\"});\n // #=\u003e {name: \"John Doe\", role: \"user\"}\n //\n I18n.prepareOptions = function() {\n var args = slice.call(arguments)\n , options = {}\n , subject\n ;\n\n while (args.length) {\n subject = args.shift();\n\n if (typeof(subject) != \"object\") {\n continue;\n }\n\n for (var attr in subject) {\n if (!subject.hasOwnProperty(attr)) {\n continue;\n }\n\n if (isSet(options[attr])) {\n continue;\n }\n\n options[attr] = subject[attr];\n }\n }\n\n return options;\n };\n\n // Generate a list of translation options for default fallbacks.\n // `defaultValue` is also deleted from options as it is returned as part of\n // the translationOptions array.\n I18n.createTranslationOptions = function(scope, options) {\n var translationOptions = [{scope: scope}];\n\n // Defaults should be an array of hashes containing either\n // fallback scopes or messages\n if (isSet(options.defaults)) {\n translationOptions = translationOptions.concat(options.defaults);\n }\n\n // Maintain support for defaultValue. Since it is always a message\n // insert it in to the translation options as such.\n if (isSet(options.defaultValue)) {\n translationOptions.push({ message: options.defaultValue });\n }\n\n return translationOptions;\n };\n\n // Translate the given scope with the provided options.\n I18n.translate = function(scope, options) {\n options = options || {};\n\n var translationOptions = this.createTranslationOptions(scope, options);\n\n var translation;\n var usedScope = scope;\n\n var optionsWithoutDefault = this.prepareOptions(options)\n delete optionsWithoutDefault.defaultValue\n\n // Iterate through the translation options until a translation\n // or message is found.\n var translationFound =\n translationOptions.some(function(translationOption) {\n if (isSet(translationOption.scope)) {\n usedScope = translationOption.scope;\n translation = this.lookup(usedScope, optionsWithoutDefault);\n } else if (isSet(translationOption.message)) {\n translation = lazyEvaluate(translationOption.message, scope);\n }\n\n if (translation !== undefined \u0026\u0026 translation !== null) {\n return true;\n }\n }, this);\n\n if (!translationFound) {\n return this.missingTranslation(scope, options);\n }\n\n if (typeof(translation) === \"string\") {\n translation = this.interpolate(translation, options);\n } else if (isArray(translation)) {\n translation = translation.map(function(t) {\n return (typeof(t) === \"string\" ? this.interpolate(t, options) : t);\n }, this);\n } else if (isObject(translation) \u0026\u0026 isSet(options.count)) {\n translation = this.pluralize(options.count, usedScope, options);\n }\n\n return translation;\n };\n\n // This function interpolates the all variables in the given message.\n I18n.interpolate = function(message, options) {\n if (message == null) {\n return message;\n }\n\n options = options || {};\n var matches = message.match(this.placeholder)\n , placeholder\n , value\n , name\n , regex\n ;\n\n if (!matches) {\n return message;\n }\n\n while (matches.length) {\n placeholder = matches.shift();\n name = placeholder.replace(this.placeholder, \"$1\");\n\n if (isSet(options[name])) {\n value = options[name].toString().replace(/\\$/gm, \"_#$#_\");\n } else if (name in options) {\n value = this.nullPlaceholder(placeholder, message, options);\n } else {\n value = this.missingPlaceholder(placeholder, message, options);\n }\n\n regex = new RegExp(placeholder.replace(/{/gm, \"\\\\{\").replace(/}/gm, \"\\\\}\"));\n message = message.replace(regex, value);\n }\n\n return message.replace(/_#\\$#_/g, \"$\");\n };\n\n // Pluralize the given scope using the `count` value.\n // The pluralized translation may have other placeholders,\n // which will be retrieved from `options`.\n I18n.pluralize = function(count, scope, options) {\n options = this.prepareOptions({count: String(count)}, options)\n var pluralizer, result;\n\n result = this.pluralizationLookup(count, scope, options);\n if (typeof result.translations === \"undefined\" || result.translations == null) {\n return this.missingTranslation(scope, options);\n }\n\n if (typeof result.message !== \"undefined\" \u0026\u0026 result.message != null) {\n return this.interpolate(result.message, options);\n }\n else {\n pluralizer = this.pluralization.get(options.locale);\n return this.missingTranslation(scope + '.' + pluralizer(count)[0], options);\n }\n };\n\n // Return a missing translation message for the given parameters.\n I18n.missingTranslation = function(scope, options) {\n //guess intended string\n if(this.missingBehaviour === 'guess'){\n //get only the last portion of the scope\n var s = scope.split('.').slice(-1)[0];\n //replace underscore with space \u0026\u0026 camelcase with space and lowercase letter\n return (this.missingTranslationPrefix.length \u003e 0 ? this.missingTranslationPrefix : '') +\n s.replace(/_/g,' ').replace(/([a-z])([A-Z])/g,\n function(match, p1, p2) {return p1 + ' ' + p2.toLowerCase()} );\n }\n\n var localeForTranslation = (options != null \u0026\u0026 options.locale != null) ? options.locale : this.currentLocale();\n var fullScope = this.getFullScope(scope, options);\n var fullScopeWithLocale = [localeForTranslation, fullScope].join(options.separator || this.defaultSeparator);\n\n return '[missing \"' + fullScopeWithLocale + '\" translation]';\n };\n\n // Return a missing placeholder message for given parameters\n I18n.missingPlaceholder = function(placeholder, message, options) {\n return \"[missing \" + placeholder + \" value]\";\n };\n\n I18n.nullPlaceholder = function() {\n return I18n.missingPlaceholder.apply(I18n, arguments);\n };\n\n // Format number using localization rules.\n // The options will be retrieved from the `number.format` scope.\n // If this isn't present, then the following options will be used:\n //\n // - `precision`: `3`\n // - `separator`: `\".\"`\n // - `delimiter`: `\",\"`\n // - `strip_insignificant_zeros`: `false`\n //\n // You can also override these options by providing the `options` argument.\n //\n I18n.toNumber = function(number, options) {\n options = this.prepareOptions(\n options\n , this.lookup(\"number.format\")\n , NUMBER_FORMAT\n );\n\n var negative = number \u003c 0\n , string = toFixed(Math.abs(number), options.precision).toString()\n , parts = string.split(\".\")\n , precision\n , buffer = []\n , formattedNumber\n , format = options.format || \"%n\"\n , sign = negative ? \"-\" : \"\"\n ;\n\n number = parts[0];\n precision = parts[1];\n\n while (number.length \u003e 0) {\n buffer.unshift(number.substr(Math.max(0, number.length - 3), 3));\n number = number.substr(0, number.length -3);\n }\n\n formattedNumber = buffer.join(options.delimiter);\n\n if (options.strip_insignificant_zeros \u0026\u0026 precision) {\n precision = precision.replace(/0+$/, \"\");\n }\n\n if (options.precision \u003e 0 \u0026\u0026 precision) {\n formattedNumber += options.separator + precision;\n }\n\n if (options.sign_first) {\n format = \"%s\" + format;\n }\n else {\n format = format.replace(\"%n\", \"%s%n\");\n }\n\n formattedNumber = format\n .replace(\"%u\", options.unit)\n .replace(\"%n\", formattedNumber)\n .replace(\"%s\", sign)\n ;\n\n return formattedNumber;\n };\n\n // Format currency with localization rules.\n // The options will be retrieved from the `number.currency.format` and\n // `number.format` scopes, in that order.\n //\n // Any missing option will be retrieved from the `I18n.toNumber` defaults and\n // the following options:\n //\n // - `unit`: `\"$\"`\n // - `precision`: `2`\n // - `format`: `\"%u%n\"`\n // - `delimiter`: `\",\"`\n // - `separator`: `\".\"`\n //\n // You can also override these options by providing the `options` argument.\n //\n I18n.toCurrency = function(number, options) {\n options = this.prepareOptions(\n options\n , this.lookup(\"number.currency.format\", options)\n , this.lookup(\"number.format\", options)\n , CURRENCY_FORMAT\n );\n\n return this.toNumber(number, options);\n };\n\n // Localize several values.\n // You can provide the following scopes: `currency`, `number`, or `percentage`.\n // If you provide a scope that matches the `/^(date|time)/` regular expression\n // then the `value` will be converted by using the `I18n.toTime` function.\n //\n // It will default to the value's `toString` function.\n //\n I18n.localize = function(scope, value, options) {\n options || (options = {});\n\n switch (scope) {\n case \"currency\":\n return this.toCurrency(value, options);\n case \"number\":\n scope = this.lookup(\"number.format\", options);\n return this.toNumber(value, scope);\n case \"percentage\":\n return this.toPercentage(value, options);\n default:\n var localizedValue;\n\n if (scope.match(/^(date|time)/)) {\n localizedValue = this.toTime(scope, value, options);\n } else {\n localizedValue = value.toString();\n }\n\n return this.interpolate(localizedValue, options);\n }\n };\n\n // Parse a given `date` string into a JavaScript Date object.\n // This function is time zone aware.\n //\n // The following string formats are recognized:\n //\n // yyyy-mm-dd\n // yyyy-mm-dd[ T]hh:mm::ss\n // yyyy-mm-dd[ T]hh:mm::ss\n // yyyy-mm-dd[ T]hh:mm::ssZ\n // yyyy-mm-dd[ T]hh:mm::ss+0000\n // yyyy-mm-dd[ T]hh:mm::ss+00:00\n // yyyy-mm-dd[ T]hh:mm::ss.123Z\n //\n I18n.parseDate = function(date) {\n var matches, convertedDate, fraction;\n // A date input of `null` or `undefined` will be returned as-is\n if (date == null) {\n return date;\n }\n // we have a date, so just return it.\n if (typeof(date) === \"object\") {\n return date;\n }\n\n matches = date.toString().match(/(\\d{4})-(\\d{2})-(\\d{2})(?:[ T](\\d{2}):(\\d{2}):(\\d{2})([\\.,]\\d{1,3})?)?(Z|\\+00:?00)?/);\n\n if (matches) {\n for (var i = 1; i \u003c= 6; i++) {\n matches[i] = parseInt(matches[i], 10) || 0;\n }\n\n // month starts on 0\n matches[2] -= 1;\n\n fraction = matches[7] ? 1000 * (\"0\" + matches[7]) : null;\n\n if (matches[8]) {\n convertedDate = new Date(Date.UTC(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6], fraction));\n } else {\n convertedDate = new Date(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6], fraction);\n }\n } else if (typeof(date) == \"number\") {\n // UNIX timestamp\n convertedDate = new Date();\n convertedDate.setTime(date);\n } else if (date.match(/([A-Z][a-z]{2}) ([A-Z][a-z]{2}) (\\d+) (\\d+:\\d+:\\d+) ([+-]\\d+) (\\d+)/)) {\n // This format `Wed Jul 20 13:03:39 +0000 2011` is parsed by\n // webkit/firefox, but not by IE, so we must parse it manually.\n convertedDate = new Date();\n convertedDate.setTime(Date.parse([\n RegExp.$1, RegExp.$2, RegExp.$3, RegExp.$6, RegExp.$4, RegExp.$5\n ].join(\" \")));\n } else if (date.match(/\\d+ \\d+:\\d+:\\d+ [+-]\\d+ \\d+/)) {\n // a valid javascript format with timezone info\n convertedDate = new Date();\n convertedDate.setTime(Date.parse(date));\n } else {\n // an arbitrary javascript string\n convertedDate = new Date();\n convertedDate.setTime(Date.parse(date));\n }\n\n return convertedDate;\n };\n\n // Formats time according to the directives in the given format string.\n // The directives begins with a percent (%) character. Any text not listed as a\n // directive will be passed through to the output string.\n //\n // The accepted formats are:\n //\n // %a - The abbreviated weekday name (Sun)\n // %A - The full weekday name (Sunday)\n // %b - The abbreviated month name (Jan)\n // %B - The full month name (January)\n // %c - The preferred local date and time representation\n // %d - Day of the month (01..31)\n // %-d - Day of the month (1..31)\n // %H - Hour of the day, 24-hour clock (00..23)\n // %-H/%k - Hour of the day, 24-hour clock (0..23)\n // %I - Hour of the day, 12-hour clock (01..12)\n // %-I/%l - Hour of the day, 12-hour clock (1..12)\n // %m - Month of the year (01..12)\n // %-m - Month of the year (1..12)\n // %M - Minute of the hour (00..59)\n // %-M - Minute of the hour (0..59)\n // %p - Meridian indicator (AM or PM)\n // %P - Meridian indicator (am or pm)\n // %S - Second of the minute (00..60)\n // %-S - Second of the minute (0..60)\n // %w - Day of the week (Sunday is 0, 0..6)\n // %y - Year without a century (00..99)\n // %-y - Year without a century (0..99)\n // %Y - Year with century\n // %z/%Z - Timezone offset (+0545)\n //\n I18n.strftime = function(date, format, options) {\n var options = this.lookup(\"date\", options)\n , meridianOptions = I18n.meridian()\n ;\n\n if (!options) {\n options = {};\n }\n\n options = this.prepareOptions(options, DATE);\n\n if (isNaN(date.getTime())) {\n throw new Error('I18n.strftime() requires a valid date object, but received an invalid date.');\n }\n\n var weekDay = date.getDay()\n , day = date.getDate()\n , year = date.getFullYear()\n , month = date.getMonth() + 1\n , hour = date.getHours()\n , hour12 = hour\n , meridian = hour \u003e 11 ? 1 : 0\n , secs = date.getSeconds()\n , mins = date.getMinutes()\n , offset = date.getTimezoneOffset()\n , absOffsetHours = Math.floor(Math.abs(offset / 60))\n , absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60)\n , timezoneoffset = (offset \u003e 0 ? \"-\" : \"+\") +\n (absOffsetHours.toString().length \u003c 2 ? \"0\" + absOffsetHours : absOffsetHours) +\n (absOffsetMinutes.toString().length \u003c 2 ? \"0\" + absOffsetMinutes : absOffsetMinutes)\n ;\n\n if (hour12 \u003e 12) {\n hour12 = hour12 - 12;\n } else if (hour12 === 0) {\n hour12 = 12;\n }\n\n format = format.replace(\"%a\", options.abbr_day_names[weekDay]);\n format = format.replace(\"%A\", options.day_names[weekDay]);\n format = format.replace(\"%b\", options.abbr_month_names[month]);\n format = format.replace(\"%B\", options.month_names[month]);\n format = format.replace(\"%d\", padding(day));\n format = format.replace(\"%e\", day);\n format = format.replace(\"%-d\", day);\n format = format.replace(\"%H\", padding(hour));\n format = format.replace(\"%-H\", hour);\n format = format.replace(\"%k\", hour);\n format = format.replace(\"%I\", padding(hour12));\n format = format.replace(\"%-I\", hour12);\n format = format.replace(\"%l\", hour12);\n format = format.replace(\"%m\", padding(month));\n format = format.replace(\"%-m\", month);\n format = format.replace(\"%M\", padding(mins));\n format = format.replace(\"%-M\", mins);\n format = format.replace(\"%p\", meridianOptions[meridian]);\n format = format.replace(\"%P\", meridianOptions[meridian].toLowerCase());\n format = format.replace(\"%S\", padding(secs));\n format = format.replace(\"%-S\", secs);\n format = format.replace(\"%w\", weekDay);\n format = format.replace(\"%y\", padding(year));\n format = format.replace(\"%-y\", padding(year).replace(/^0+/, \"\"));\n format = format.replace(\"%Y\", year);\n format = format.replace(\"%z\", timezoneoffset);\n format = format.replace(\"%Z\", timezoneoffset);\n\n return format;\n };\n\n // Convert the given dateString into a formatted date.\n I18n.toTime = function(scope, dateString, options) {\n var date = this.parseDate(dateString)\n , format = this.lookup(scope, options)\n ;\n\n // A date input of `null` or `undefined` will be returned as-is\n if (date == null) {\n return date;\n }\n\n var date_string = date.toString()\n if (date_string.match(/invalid/i)) {\n return date_string;\n }\n\n if (!format) {\n return date_string;\n }\n\n return this.strftime(date, format, options);\n };\n\n // Convert a number into a formatted percentage value.\n I18n.toPercentage = function(number, options) {\n options = this.prepareOptions(\n options\n , this.lookup(\"number.percentage.format\", options)\n , this.lookup(\"number.format\", options)\n , PERCENTAGE_FORMAT\n );\n\n return this.toNumber(number, options);\n };\n\n // Convert a number into a readable size representation.\n I18n.toHumanSize = function(number, options) {\n var kb = 1024\n , size = number\n , iterations = 0\n , unit\n , precision\n , fullScope\n ;\n\n while (size \u003e= kb \u0026\u0026 iterations \u003c 4) {\n size = size / kb;\n iterations += 1;\n }\n\n if (iterations === 0) {\n fullScope = this.getFullScope(\"number.human.storage_units.units.byte\", options);\n unit = this.t(fullScope, {count: size});\n precision = 0;\n } else {\n fullScope = this.getFullScope(\"number.human.storage_units.units.\" + SIZE_UNITS[iterations], options);\n unit = this.t(fullScope);\n precision = (size - Math.floor(size) === 0) ? 0 : 1;\n }\n\n options = this.prepareOptions(\n options\n , {unit: unit, precision: precision, format: \"%n%u\", delimiter: \"\"}\n );\n\n return this.toNumber(size, options);\n };\n\n I18n.getFullScope = function(scope, options) {\n options = options || {};\n\n // Deal with the scope as an array.\n if (isArray(scope)) {\n scope = scope.join(options.separator || this.defaultSeparator);\n }\n\n // Deal with the scope option provided through the second argument.\n //\n // I18n.t('hello', {scope: 'greetings'});\n //\n if (options.scope) {\n scope = [options.scope, scope].join(options.separator || this.defaultSeparator);\n }\n\n return scope;\n };\n /**\n * Merge obj1 with obj2 (shallow merge), without modifying inputs\n * @param {Object} obj1\n * @param {Object} obj2\n * @returns {Object} Merged values of obj1 and obj2\n *\n * In order to support ES3, `Object.prototype.hasOwnProperty.call` is used\n * Idea is from:\n * https://stackoverflow.com/questions/8157700/object-has-no-hasownproperty-method-i-e-its-undefined-ie8\n */\n I18n.extend = function ( obj1, obj2 ) {\n if (typeof(obj1) === \"undefined\" \u0026\u0026 typeof(obj2) === \"undefined\") {\n return {};\n }\n return merge(obj1, obj2);\n };\n\n // Set aliases, so we can save some typing.\n I18n.t = I18n.translate.bind(I18n);\n I18n.l = I18n.localize.bind(I18n);\n I18n.p = I18n.pluralize.bind(I18n);\n\n return I18n;\n}));\n/*!\n * Ahoy.js\n * Simple, powerful JavaScript analytics\n * https://github.com/ankane/ahoy.js\n * v0.4.0\n * MIT License\n */\n\n(function (global, factory) {\n typeof exports === 'object' \u0026\u0026 typeof module !== 'undefined' ? module.exports = factory() :\n typeof define === 'function' \u0026\u0026 define.amd ? define(factory) :\n (global = global || self, global.ahoy = factory());\n}(this, (function () { 'use strict';\n\n // https://www.quirksmode.org/js/cookies.html\n\n var Cookies = {\n set: function (name, value, ttl, domain) {\n var expires = \"\";\n var cookieDomain = \"\";\n if (ttl) {\n var date = new Date();\n date.setTime(date.getTime() + (ttl * 60 * 1000));\n expires = \"; expires=\" + date.toGMTString();\n }\n if (domain) {\n cookieDomain = \"; domain=\" + domain;\n }\n document.cookie = name + \"=\" + escape(value) + expires + cookieDomain + \"; path=/; samesite=lax\";\n },\n get: function (name) {\n var i, c;\n var nameEQ = name + \"=\";\n var ca = document.cookie.split(';');\n for (i = 0; i \u003c ca.length; i++) {\n c = ca[i];\n while (c.charAt(0) === ' ') {\n c = c.substring(1, c.length);\n }\n if (c.indexOf(nameEQ) === 0) {\n return unescape(c.substring(nameEQ.length, c.length));\n }\n }\n return null;\n }\n };\n\n var config = {\n urlPrefix: \"\",\n visitsUrl: \"/ahoy/visits\",\n eventsUrl: \"/ahoy/events\",\n page: null,\n platform: \"Web\",\n useBeacon: true,\n startOnReady: true,\n trackVisits: true,\n cookies: true,\n cookieDomain: null,\n headers: {},\n visitParams: {},\n withCredentials: false,\n visitDuration: 4 * 60, // default 4 hours\n visitorDuration: 2 * 365 * 24 * 60 // default 2 years\n };\n\n var ahoy = window.ahoy || window.Ahoy || {};\n\n ahoy.configure = function (options) {\n for (var key in options) {\n if (options.hasOwnProperty(key)) {\n config[key] = options[key];\n }\n }\n };\n\n // legacy\n ahoy.configure(ahoy);\n\n var $ = window.jQuery || window.Zepto || window.$;\n var visitId, visitorId, track;\n var isReady = false;\n var queue = [];\n var canStringify = typeof(JSON) !== \"undefined\" \u0026\u0026 typeof(JSON.stringify) !== \"undefined\";\n var eventQueue = [];\n\n function visitsUrl() {\n return config.urlPrefix + config.visitsUrl;\n }\n\n function eventsUrl() {\n return config.urlPrefix + config.eventsUrl;\n }\n\n function isEmpty(obj) {\n return Object.keys(obj).length === 0;\n }\n\n function canTrackNow() {\n return (config.useBeacon || config.trackNow) \u0026\u0026 isEmpty(config.headers) \u0026\u0026 canStringify \u0026\u0026 typeof(window.navigator.sendBeacon) !== \"undefined\" \u0026\u0026 !config.withCredentials;\n }\n\n function serialize(object) {\n var data = new FormData();\n for (var key in object) {\n if (object.hasOwnProperty(key)) {\n data.append(key, object[key]);\n }\n }\n return data;\n }\n\n // cookies\n\n function setCookie(name, value, ttl) {\n Cookies.set(name, value, ttl, config.cookieDomain || config.domain);\n }\n\n function getCookie(name) {\n return Cookies.get(name);\n }\n\n function destroyCookie(name) {\n Cookies.set(name, \"\", -1);\n }\n\n function log(message) {\n if (getCookie(\"ahoy_debug\")) {\n window.console.log(message);\n }\n }\n\n function setReady() {\n var callback;\n while ((callback = queue.shift())) {\n callback();\n }\n isReady = true;\n }\n\n ahoy.ready = function (callback) {\n if (isReady) {\n callback();\n } else {\n queue.push(callback);\n }\n };\n\n function matchesSelector(element, selector) {\n var matches = element.matches ||\n element.matchesSelector ||\n element.mozMatchesSelector ||\n element.msMatchesSelector ||\n element.oMatchesSelector ||\n element.webkitMatchesSelector;\n\n if (matches) {\n if (matches.apply(element, [selector])) {\n return element;\n } else if (element.parentElement) {\n return matchesSelector(element.parentElement, selector);\n }\n return null;\n } else {\n log(\"Unable to match\");\n return null;\n }\n }\n\n function onEvent(eventName, selector, callback) {\n document.addEventListener(eventName, function (e) {\n var matchedElement = matchesSelector(e.target, selector);\n if (matchedElement) {\n callback.call(matchedElement, e);\n }\n });\n }\n\n // http://beeker.io/jquery-document-ready-equivalent-vanilla-javascript\n function documentReady(callback) {\n if (document.readyState === \"interactive\" || document.readyState === \"complete\") {\n setTimeout(callback, 0);\n } else {\n document.addEventListener(\"DOMContentLoaded\", callback);\n }\n }\n\n // https://stackoverflow.com/a/2117523/1177228\n function generateId() {\n return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {\n var r = Math.random()*16|0, v = c == 'x' ? r : (r\u00260x3|0x8);\n return v.toString(16);\n });\n }\n\n function saveEventQueue() {\n if (config.cookies \u0026\u0026 canStringify) {\n setCookie(\"ahoy_events\", JSON.stringify(eventQueue), 1);\n }\n }\n\n // from rails-ujs\n\n function csrfToken() {\n var meta = document.querySelector(\"meta[name=csrf-token]\");\n return meta \u0026\u0026 meta.content;\n }\n\n function csrfParam() {\n var meta = document.querySelector(\"meta[name=csrf-param]\");\n return meta \u0026\u0026 meta.content;\n }\n\n function CSRFProtection(xhr) {\n var token = csrfToken();\n if (token) { xhr.setRequestHeader(\"X-CSRF-Token\", token); }\n }\n\n function sendRequest(url, data, success) {\n if (canStringify) {\n if ($ \u0026\u0026 $.ajax) {\n $.ajax({\n type: \"POST\",\n url: url,\n data: JSON.stringify(data),\n contentType: \"application/json; charset=utf-8\",\n dataType: \"json\",\n beforeSend: CSRFProtection,\n success: success,\n headers: config.headers,\n xhrFields: {\n withCredentials: config.withCredentials\n }\n });\n } else {\n var xhr = new XMLHttpRequest();\n xhr.open(\"POST\", url, true);\n xhr.withCredentials = config.withCredentials;\n xhr.setRequestHeader(\"Content-Type\", \"application/json\");\n for (var header in config.headers) {\n if (config.headers.hasOwnProperty(header)) {\n xhr.setRequestHeader(header, config.headers[header]);\n }\n }\n xhr.onload = function() {\n if (xhr.status === 200) {\n success();\n }\n };\n CSRFProtection(xhr);\n xhr.send(JSON.stringify(data));\n }\n }\n }\n\n function eventData(event) {\n var data = {\n events: [event]\n };\n if (config.cookies) {\n data.visit_token = event.visit_token;\n data.visitor_token = event.visitor_token;\n }\n delete event.visit_token;\n delete event.visitor_token;\n return data;\n }\n\n function trackEvent(event) {\n ahoy.ready( function () {\n sendRequest(eventsUrl(), eventData(event), function() {\n // remove from queue\n for (var i = 0; i \u003c eventQueue.length; i++) {\n if (eventQueue[i].id == event.id) {\n eventQueue.splice(i, 1);\n break;\n }\n }\n saveEventQueue();\n });\n });\n }\n\n function trackEventNow(event) {\n ahoy.ready( function () {\n var data = eventData(event);\n var param = csrfParam();\n var token = csrfToken();\n if (param \u0026\u0026 token) { data[param] = token; }\n // stringify so we keep the type\n data.events_json = JSON.stringify(data.events);\n delete data.events;\n window.navigator.sendBeacon(eventsUrl(), serialize(data));\n });\n }\n\n function page() {\n return config.page || window.location.pathname;\n }\n\n function presence(str) {\n return (str \u0026\u0026 str.length \u003e 0) ? str : null;\n }\n\n function cleanObject(obj) {\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n if (obj[key] === null) {\n delete obj[key];\n }\n }\n }\n return obj;\n }\n\n function eventProperties() {\n return cleanObject({\n tag: this.tagName.toLowerCase(),\n id: presence(this.id),\n \"class\": presence(this.className),\n page: page(),\n section: getClosestSection(this)\n });\n }\n\n function getClosestSection(element) {\n for ( ; element \u0026\u0026 element !== document; element = element.parentNode) {\n if (element.hasAttribute('data-section')) {\n return element.getAttribute('data-section');\n }\n }\n\n return null;\n }\n\n function createVisit() {\n isReady = false;\n\n visitId = ahoy.getVisitId();\n visitorId = ahoy.getVisitorId();\n track = getCookie(\"ahoy_track\");\n\n if (config.cookies === false || config.trackVisits === false) {\n log(\"Visit tracking disabled\");\n setReady();\n } else if (visitId \u0026\u0026 visitorId \u0026\u0026 !track) {\n // TODO keep visit alive?\n log(\"Active visit\");\n setReady();\n } else {\n if (!visitId) {\n visitId = generateId();\n setCookie(\"ahoy_visit\", visitId, config.visitDuration);\n }\n\n // make sure cookies are enabled\n if (getCookie(\"ahoy_visit\")) {\n log(\"Visit started\");\n\n if (!visitorId) {\n visitorId = generateId();\n setCookie(\"ahoy_visitor\", visitorId, config.visitorDuration);\n }\n\n var data = {\n visit_token: visitId,\n visitor_token: visitorId,\n platform: config.platform,\n landing_page: window.location.href,\n screen_width: window.screen.width,\n screen_height: window.screen.height,\n js: true\n };\n\n // referrer\n if (document.referrer.length \u003e 0) {\n data.referrer = document.referrer;\n }\n\n for (var key in config.visitParams) {\n if (config.visitParams.hasOwnProperty(key)) {\n data[key] = config.visitParams[key];\n }\n }\n\n log(data);\n\n sendRequest(visitsUrl(), data, function () {\n // wait until successful to destroy\n destroyCookie(\"ahoy_track\");\n setReady();\n });\n } else {\n log(\"Cookies disabled\");\n setReady();\n }\n }\n }\n\n ahoy.getVisitId = ahoy.getVisitToken = function () {\n return getCookie(\"ahoy_visit\");\n };\n\n ahoy.getVisitorId = ahoy.getVisitorToken = function () {\n return getCookie(\"ahoy_visitor\");\n };\n\n ahoy.reset = function () {\n destroyCookie(\"ahoy_visit\");\n destroyCookie(\"ahoy_visitor\");\n destroyCookie(\"ahoy_events\");\n destroyCookie(\"ahoy_track\");\n return true;\n };\n\n ahoy.debug = function (enabled) {\n if (enabled === false) {\n destroyCookie(\"ahoy_debug\");\n } else {\n setCookie(\"ahoy_debug\", \"t\", 365 * 24 * 60); // 1 year\n }\n return true;\n };\n\n ahoy.track = function (name, properties) {\n // generate unique id\n var event = {\n name: name,\n properties: properties || {},\n time: (new Date()).getTime() / 1000.0,\n id: generateId(),\n js: true\n };\n\n ahoy.ready( function () {\n if (config.cookies \u0026\u0026 !ahoy.getVisitId()) {\n createVisit();\n }\n\n ahoy.ready( function () {\n log(event);\n\n event.visit_token = ahoy.getVisitId();\n event.visitor_token = ahoy.getVisitorId();\n\n if (canTrackNow()) {\n trackEventNow(event);\n } else {\n eventQueue.push(event);\n saveEventQueue();\n\n // wait in case navigating to reduce duplicate events\n setTimeout( function () {\n trackEvent(event);\n }, 1000);\n }\n });\n });\n\n return true;\n };\n\n ahoy.trackView = function (additionalProperties) {\n var properties = {\n url: window.location.href,\n title: document.title,\n page: page()\n };\n\n if (additionalProperties) {\n for(var propName in additionalProperties) {\n if (additionalProperties.hasOwnProperty(propName)) {\n properties[propName] = additionalProperties[propName];\n }\n }\n }\n ahoy.track(\"$view\", properties);\n };\n\n ahoy.trackClicks = function (selector) {\n if (selector === undefined) {\n throw new Error(\"Missing selector\");\n }\n onEvent(\"click\", selector, function (e) {\n var properties = eventProperties.call(this, e);\n properties.text = properties.tag == \"input\" ? this.value : (this.textContent || this.innerText || this.innerHTML).replace(/[\\s\\r\\n]+/g, \" \").trim();\n properties.href = this.href;\n ahoy.track(\"$click\", properties);\n });\n };\n\n ahoy.trackSubmits = function (selector) {\n if (selector === undefined) {\n throw new Error(\"Missing selector\");\n }\n onEvent(\"submit\", selector, function (e) {\n var properties = eventProperties.call(this, e);\n ahoy.track(\"$submit\", properties);\n });\n };\n\n ahoy.trackChanges = function (selector) {\n log(\"trackChanges is deprecated and will be removed in 0.5.0\");\n if (selector === undefined) {\n throw new Error(\"Missing selector\");\n }\n onEvent(\"change\", selector, function (e) {\n var properties = eventProperties.call(this, e);\n ahoy.track(\"$change\", properties);\n });\n };\n\n // push events from queue\n try {\n eventQueue = JSON.parse(getCookie(\"ahoy_events\") || \"[]\");\n } catch (e) {\n // do nothing\n }\n\n for (var i = 0; i \u003c eventQueue.length; i++) {\n trackEvent(eventQueue[i]);\n }\n\n ahoy.start = function () {\n createVisit();\n\n ahoy.start = function () {};\n };\n\n documentReady(function() {\n if (config.startOnReady) {\n ahoy.start();\n }\n });\n\n return ahoy;\n\n})));\n\n\n\n\n\n\n\n\n\nI18n.defaultLocale = 'en';\nI18n.locale = document.body.dataset.locale;\nI18n.translations = JSON.parse(document.getElementById('i18n-translations').dataset.translations);\nvar instantClick\n , InstantClick = instantClick = function(document, location, $userAgent) {\n // Internal variables\n var $isChromeForIOS = $userAgent.indexOf(' CriOS/') \u003e -1\n , $currentLocationWithoutHash\n , $urlToPreload\n , $preloadTimer\n , $lastTouchTimestamp\n\n // Preloading-related variables\n , $history = {}\n , $xhr\n , $url = false\n , $mustRedirect = false\n , $fetchedBodies = {}\n , $timing = {}\n , $isPreloading = false\n , $isWaitingForCompletion = false\n , $trackedAssets = []\n\n // Variables defined by public functions\n , $preloadOnMousedown\n , $delayBeforePreload\n , $eventsCallbacks = {\n fetch: [],\n receive: [],\n wait: [],\n change: [],\n restore: []\n }\n\n\n ////////// HELPERS //////////\n\n\n function removeHash(url) {\n var index = url.indexOf('#')\n if (index \u003c 0) {\n return url\n }\n return url.substr(0, index)\n }\n\n function getLinkTarget(target) {\n while (target \u0026\u0026 target.nodeName != 'A') {\n target = target.parentNode\n }\n return target\n }\n\n function isNotPreloadable(elem) {\n do {\n if (!elem.hasAttribute) { // Parent of \u003chtml\u003e\n break\n }\n if (elem.hasAttribute('data-instant')) {\n return false\n }\n if (elem.hasAttribute('data-no-instant')) {\n return true\n }\n }\n while (elem = elem.parentNode)\n return false\n }\n\n function isPreloadable(a) {\n var domain = location.protocol + '//' + location.host\n\n if (a.target // target=\"_blank\" etc.\n || a.hasAttribute('download')\n || a.href.indexOf(domain + '/') != 0 // Another domain, or no href attribute\n || (a.href.indexOf('#') \u003e -1\n \u0026\u0026 removeHash(a.href) == $currentLocationWithoutHash) // Anchor\n || isNotPreloadable(a)\n ) {\n return false\n }\n return true\n }\n\n function triggerPageEvent(eventType, arg1, arg2, arg3) {\n var returnValue = false\n for (var i = 0; i \u003c $eventsCallbacks[eventType].length; i++) {\n if (eventType == 'receive') {\n var altered = $eventsCallbacks[eventType][i](arg1, arg2, arg3)\n if (altered) {\n /* Update args for the next iteration of the loop. */\n if ('body' in altered) {\n arg2 = altered.body\n }\n if ('title' in altered) {\n arg3 = altered.title\n }\n\n returnValue = altered\n }\n }\n else {\n $eventsCallbacks[eventType][i](arg1, arg2, arg3)\n }\n }\n return returnValue\n }\n\n function changePage(title, body, newUrl, scrollY, pop) {\n var pageContentDiv = document.getElementById(\"page-content\");\n var memberMenuButton = document.getElementById(\"member-menu-button\")\n if (memberMenuButton) {\n memberMenuButton.classList.remove('showing')\n }\n document.body.replaceChild(body, pageContentDiv)\n\n var prog = document.getElementById(\"navigation-progress\");\n prog.classList.remove(\"showing\");\n\n if (newUrl) {\n const routeChangeTarget = document.getElementById('route-change-target');\n if(routeChangeTarget) {\n routeChangeTarget.focus();\n }\n document.getElementById('page-route-change').textContent = title;\n history.pushState(null, null, newUrl.replace(\"?samepage=true\",\"\").replace(\"\u0026samepage=true\",\"\"))\n\n var hashIndex = newUrl.indexOf('#'),\n hashElem = hashIndex \u003e -1 \u0026\u0026 (\n document.getElementById(newUrl.substr(hashIndex + 1)) ||\n document.querySelector(`[name=${newUrl.substr(hashIndex + 1)}].anchor`)\n ),\n offset = 0,\n samePage = newUrl.indexOf(\"samepage=true\") \u003e -1;\n\n if (hashElem) {\n while (hashElem.offsetParent) {\n offset += hashElem.offsetTop\n\n hashElem = hashElem.offsetParent\n }\n }\n if (!samePage){\n scrollTo(0, offset)\n }\n\n\n $currentLocationWithoutHash = removeHash(newUrl)\n }\n else {\n scrollTo(0, scrollY)\n }\n\n if ($isChromeForIOS \u0026\u0026 document.title == title) {\n /* Chrome for iOS:\n *\n * 1. Removes title on pushState, so the title needs to be set after.\n *\n * 2. Will not set the title if it's identical when trimmed, so\n * appending a space won't do; but a non-breaking space works.\n */\n document.title = title + String.fromCharCode(160)\n }\n else {\n document.title = title\n }\n\n instantanize()\n if (pop) {\n triggerPageEvent('restore')\n }\n else {\n triggerPageEvent('change', false)\n }\n }\n\n function setPreloadingAsHalted() {\n $isPreloading = false\n $isWaitingForCompletion = false\n }\n\n function removeNoscriptTags(html) {\n /* Must be done on text, not on a node's innerHTML, otherwise strange\n * things happen with implicitly closed elements (see the Noscript test).\n */\n return html.replace(/\u003cnoscript[\\s\\S]+?\u003c\\/noscript\u003e/gi, '')\n }\n\n\n ////////// EVENT LISTENERS //////////\n\n\n function mousedownListener(e) {\n if ($lastTouchTimestamp \u003e (+new Date - 500)) {\n return // Otherwise, click doesn't fire\n }\n\n var a = getLinkTarget(e.target)\n\n if (!a || !isPreloadable(a)) {\n return\n }\n\n preload(a.href)\n }\n\n function mouseoverListener(e) {\n if ($lastTouchTimestamp \u003e (+new Date - 500)) {\n return // Otherwise, click doesn't fire\n }\n\n var a = getLinkTarget(e.target)\n\n if (!a || !isPreloadable(a)) {\n return\n }\n\n a.addEventListener('mouseout', mouseoutListener)\n\n if (!$delayBeforePreload) {\n preload(a.href)\n }\n else {\n $urlToPreload = a.href\n $preloadTimer = setTimeout(preload, $delayBeforePreload)\n }\n getImageForLink(a);\n }\n\n function touchstartListener(e) {\n $lastTouchTimestamp = +new Date\n var a = getLinkTarget(e.target)\n\n if (!a || !isPreloadable(a)) {\n return\n }\n\n if ($preloadOnMousedown) {\n a.removeEventListener('mousedown', mousedownListener)\n }\n else {\n a.removeEventListener('mouseover', mouseoverListener)\n }\n preload(a.href);\n getImageForLink(a);\n }\n\n // If a link is focused, it is preloaded just like on mouseover.\n // It also covers the issue where a user needs to press \u003creturn\u003e\n // twice in order to follow a focused link.\n function focusListener(e) {\n var a = getLinkTarget(e.target)\n\n if (!a || !isPreloadable(a)) {\n return\n }\n\n if (!$delayBeforePreload) {\n preload(a.href)\n }\n else {\n $urlToPreload = a.href\n $preloadTimer = setTimeout(preload, $delayBeforePreload)\n }\n getImageForLink(a);\n }\n\n function clickListener(e) {\n try{\n var a = getLinkTarget(e.target)\n\n if (!a || !isPreloadable(a)) {\n return\n }\n\n if (e.which \u003e 1 || e.metaKey || e.ctrlKey) { // Opening in new tab\n return\n }\n display(a.href);\n e.preventDefault();\n }\n catch(err){\n console.log(err);\n }\n }\n\n function mouseoutListener() {\n if ($preloadTimer) {\n clearTimeout($preloadTimer)\n $preloadTimer = false\n return\n }\n\n if (!$isPreloading || $isWaitingForCompletion) {\n return\n }\n $xhr.abort()\n setPreloadingAsHalted()\n }\n\n function readystatechangeListener() {\n processXHR($xhr,$url);\n }\n\n function processXHR(xhr,url) {\n if (xhr.readyState \u003c 4) {\n return\n }\n if (xhr.status == 0) {\n /* Request aborted */\n return\n }\n\n $timing.ready = +new Date - $timing.start\n var pageContentDiv = document.getElementById(\"page-content\");\n if (pageContentDiv \u0026\u0026 xhr.status === 200 \u0026\u0026 xhr.getResponseHeader('Content-Type').match(/\\/(x|ht|xht)ml/)) {\n var doc = document.implementation.createHTMLDocument('');\n doc.documentElement.innerHTML = removeNoscriptTags(xhr.responseText)\n var title = doc.title\n var body = doc.getElementById(\"page-content\")\n var alteredOnReceive = triggerPageEvent('receive', url, body, title)\n if (alteredOnReceive) {\n if ('body' in alteredOnReceive) {\n body = alteredOnReceive.body\n }\n if ('title' in alteredOnReceive) {\n title = alteredOnReceive.title\n }\n }\n $fetchedBodies[url] = {body:body, title:title};\n var urlWithoutHash = removeHash(url)\n\n var elems = doc.head.children\n , found = 0\n , elem\n , data\n\n for (var i = 0; i \u003c elems.length; i++) {\n elem = elems[i]\n if (elem.hasAttribute('data-instant-track')) {\n data = elem.getAttribute('href') || elem.getAttribute('src') || elem.innerHTML\n for (var j = 0; j \u003c $trackedAssets.length; j++) {\n if ($trackedAssets[j] == data) {\n found++\n }\n }\n }\n }\n if (found != $trackedAssets.length) {\n $mustRedirect = true // Assets have changed\n }\n }\n else {\n $mustRedirect = true // Not an HTML document\n }\n\n if ($isWaitingForCompletion \u0026\u0026 $url === url) {\n $isWaitingForCompletion = false\n display($url)\n }\n }\n\n function popstateListener() {\n var loc = removeHash(location.href)\n if (loc == $currentLocationWithoutHash) {\n return\n }\n\n if (!(loc in $history)) {\n location.href = location.href\n return\n }\n $history[$currentLocationWithoutHash] = {\n body: document.getElementById(\"page-content\"),\n title: document.title,\n scrollY: pageYOffset\n }\n\n $currentLocationWithoutHash = loc\n changePage($history[loc].title, $history[loc].body, false, $history[loc].scrollY, true)\n }\n\n\n ////////// MAIN FUNCTIONS //////////\n\n\n function instantanize(isInitializing) {\n var docBody = document.body;\n if (docBody) {\n document.body.addEventListener('touchstart', touchstartListener, true)\n document.body.addEventListener('focus', focusListener, true)\n if ($preloadOnMousedown) {\n document.body.addEventListener('mousedown', mousedownListener, true)\n } else {\n document.body.addEventListener('mouseover', mouseoverListener, true)\n }\n document.body.addEventListener('click', clickListener, true)\n }\n\n if (!isInitializing) {\n var scriptElementsInDOM = document.body.getElementsByTagName('script')\n , scriptElementsToCopy = []\n , originalElement\n , copyElement\n , parentNode\n , nextSibling\n , i\n\n // `scriptElementsInDOM` will change during the copy of scripts if\n // a script add or delete script elements, so we need to put script\n // elements in an array to loop through them correctly.\n for (i = 0; i \u003c scriptElementsInDOM.length; i++) {\n scriptElementsToCopy.push(scriptElementsInDOM[i])\n }\n\n for (i = 0; i \u003c scriptElementsToCopy.length; i++) {\n originalElement = scriptElementsToCopy[i]\n if (!originalElement) { // Might have disappeared, see previous comment\n continue\n }\n if (originalElement.hasAttribute('data-no-instant')) {\n continue\n }\n\n copyElement = document.createElement('script')\n for (var j = 0; j \u003c originalElement.attributes.length; j++) {\n copyElement.setAttribute(originalElement.attributes[j].name, originalElement.attributes[j].value)\n }\n copyElement.textContent = originalElement.textContent\n\n parentNode = originalElement.parentNode\n nextSibling = originalElement.nextSibling\n parentNode.removeChild(originalElement)\n parentNode.insertBefore(copyElement, nextSibling)\n }\n }\n }\n\n function preload(url, option) {\n if (!$preloadOnMousedown\n \u0026\u0026 'display' in $timing\n \u0026\u0026 +new Date - ($timing.start + $timing.display) \u003c 100) {\n return\n }\n if ($preloadTimer) {\n clearTimeout($preloadTimer)\n $preloadTimer = false\n }\n\n if (!url) {\n url = $urlToPreload\n }\n\n if ($isPreloading \u0026\u0026 (url == $url || $isWaitingForCompletion)) {\n return\n }\n $isPreloading = true\n $isWaitingForCompletion = false\n\n $mustRedirect = false\n $timing = {\n start: +new Date\n }\n if (url.indexOf(\"?\") == -1) {\n var internalUrl = url+\"?i=i\"\n }\n else {\n var internalUrl = url+\"\u0026i=i\"\n }\n removeExpiredKeys()\n triggerPageEvent('fetch')\n if (!$fetchedBodies[url]){\n if (option === \"force\") {\n getURLInfo(url, function () {\n processXHR(this,url);\n })\n }\n else {\n $url = url\n $xhr.open('GET', internalUrl)\n $xhr.send()\n }\n }\n }\n\n function removeExpiredKeys(option) {\n if ( Object.keys($fetchedBodies).length \u003e 13 || option == \"force\" ) {\n $fetchedBodies = {};\n }\n\n }\n\n function getURLInfo(url, callback) {\n var xhr = new XMLHttpRequest();\n if (url.indexOf(\"?\") == -1) {\n var internalUrl = url+\"?i=i\"\n }\n else {\n var internalUrl = url+\"\u0026i=i\"\n }\n xhr.open (\n \"GET\",\n internalUrl,\n true\n );\n xhr.onreadystatechange = function() {\n if (xhr.readyState == 4) {\n // defensive check\n if (typeof callback == \"function\") {\n // apply() sets the meaning of \"this\" in the callback\n callback.apply(xhr);\n }\n }\n }\n // send the request *after* the event handler is defined\n xhr.send();\n }\n\n function display(url) {\n $url = url;\n if($fetchedBodies[url]){\n var body = $fetchedBodies[url]['body'];\n var title = $fetchedBodies[url]['title'];\n }\n else {\n var prog = document.getElementById(\"navigation-progress\");\n prog.classList.add(\"showing\");\n }\n\n if (!('display' in $timing)) {\n $timing.display = +new Date - $timing.start\n }\n if ($preloadTimer || !$isPreloading) {\n if ($preloadTimer \u0026\u0026 $url \u0026\u0026 $url != url) {\n location.href = url\n return\n }\n preload(url)\n triggerPageEvent('wait')\n $isWaitingForCompletion = true // Must be set *after* calling `preload`\n return\n }\n if ($isWaitingForCompletion) {\n /* The user clicked on a link while a page was preloading. Either on\n the same link or on another link. If it's the same link something\n might have gone wrong (or he could have double clicked, we don't\n handle that case), so we send him to the page without pjax.\n If it's another link, it hasn't been preloaded, so we redirect the\n user to it.\n */\n location.href = url\n return\n }\n if ($mustRedirect) {\n location.href = $url\n return\n }\n\n if (!body) {\n triggerPageEvent('wait')\n $isWaitingForCompletion = true\n return\n }\n $history[$currentLocationWithoutHash] = {\n body: document.getElementById(\"page-content\"),\n title: document.title,\n scrollY: pageYOffset\n }\n setPreloadingAsHalted()\n changePage(title, body, $url)\n }\n\n\n ////////// PUBLIC VARIABLE AND FUNCTIONS //////////\n\n var supported = 'pushState' in history\n \u0026\u0026 (!$userAgent.match('Android') || $userAgent.match('Chrome/') || $userAgent.match('Firefox/'))\n \u0026\u0026 location.protocol != \"file:\"\n\n /* The (sad) state of Android's AOSP browsers:\n\n 2.3.7: pushState appears to work correctly, but\n `doc.documentElement.innerHTML = body` is buggy.\n Update: InstantClick doesn't use that anymore, but it may\n fail where 3.0 do, this needs testing again.\n\n 3.0: pushState appears to work correctly (though the address bar is\n only updated on focus), but\n `document.documentElement.replaceChild(doc.body, document.body)`\n throws DOMException: WRONG_DOCUMENT_ERR.\n\n 4.0.2: Doesn't support pushState.\n\n 4.0.4,\n 4.1.1,\n 4.2,\n 4.3: Claims support for pushState, but doesn't update the address bar.\n\n 4.4: Works correctly. Claims to be 'Chrome/30.0.0.0'.\n\n All androids tested with Android SDK's Emulator.\n Version numbers are from the browser's user agent.\n\n Because of this mess, the only allowed browser on Android is Chrome.\n */\n\n function init(preloadingMode) {\n if ($currentLocationWithoutHash) {\n /* Already initialized */\n return\n }\n if (!supported) {\n triggerPageEvent('change', true)\n return\n }\n\n if (preloadingMode == 'mousedown') {\n $preloadOnMousedown = true\n }\n else if (typeof preloadingMode == 'number') {\n $delayBeforePreload = preloadingMode\n }\n $currentLocationWithoutHash = removeHash(location.href)\n $history[$currentLocationWithoutHash] = {\n body: document.getElementById(\"page-content\"),\n title: document.title,\n scrollY: pageYOffset\n }\n\n var elems = document.head.children\n , elem\n , data\n for (var i = 0; i \u003c elems.length; i++) {\n elem = elems[i]\n if (elem.hasAttribute('data-instant-track')) {\n data = elem.getAttribute('href') || elem.getAttribute('src') || elem.innerHTML\n /* We can't use just `elem.href` and `elem.src` because we can't\n retrieve `href`s and `src`s from the Ajax response.\n */\n $trackedAssets.push(data)\n }\n }\n\n $xhr = new XMLHttpRequest()\n $xhr.addEventListener('readystatechange', readystatechangeListener)\n\n instantanize(true)\n\n triggerPageEvent('change', true)\n\n addEventListener('popstate', popstateListener)\n addRefreshBehavior();\n }\n\n function on(eventType, callback) {\n $eventsCallbacks[eventType].push(callback)\n }\n\n function addRefreshBehavior(){\n if (!(\"ontouchstart\" in document.documentElement)) {\n return\n }\n\n var script = document.createElement('script');\n script.src = \"/assets/lib/pulltorefresh-9b56f74a421b6273bdafaa34b17521df12711be7191050b1193dfd958a99a81a.js\";\n document.head.appendChild(script);\n var waitingOnPTR = setInterval(function(){\n if (typeof PullToRefresh !== 'undefined') {\n var ptr = PullToRefresh.init({\n mainElement: 'body',\n passive: true,\n onRefresh: function(){\n window.location.reload();\n }\n });\n clearInterval(waitingOnPTR)\n }\n }, 1)\n }\n\n\n ////////////////////\n\n\n return {\n supported: supported,\n init: init,\n isPreloadable: isPreloadable,\n preload: preload,\n removeExpiredKeys: removeExpiredKeys,\n display: display,\n on: on\n }\n\n}(document, location, navigator.userAgent);\n\n\n// FUNCTIONAL CODE FOR PAGE\n\n function initializeBaseApp() {\n InstantClick.on('change', function() {\n initializePage();\n });\n InstantClick.init();\n }\n\n// INITIALIZE/ERROR HANDLING\n\n Honeybadger.configure({\n apiKey: document.body.dataset.honeybadgerKey,\n environment: \"production\",\n revision: document.body.dataset.releaseFootprint,\n ignorePatterns: [/ResizeObserver/i, /MetaMask/i],\n });\n\n// INITIALIZE AHOY TRACKING\n// Setting cookies to false matches what we do in ahoy's initializer.\n// Setting trackVisits to false prevents ahoy from creating a visit on the server-side.\n ahoy.configure({\n cookies: false,\n trackVisits: false\n });\n\n// Start BaseApp for Page\n initializeBaseApp();\n"]}