mirror of
https://github.com/squidfunk/mkdocs-material.git
synced 2024-06-14 11:52:32 +03:00
1 line
298 KiB
Plaintext
1 line
298 KiB
Plaintext
{"version":3,"sources":["webpack:///webpack/bootstrap","webpack:///./src/assets/javascripts/browser/document/index.ts","webpack:///./src/assets/javascripts/browser/element/_/index.ts","webpack:///./src/assets/javascripts/browser/element/focus/index.ts","webpack:///./src/assets/javascripts/browser/element/offset/index.ts","webpack:///./src/assets/javascripts/browser/element/select/index.ts","webpack:///./src/assets/javascripts/browser/element/size/index.ts","webpack:///./src/assets/javascripts/browser/keyboard/index.ts","webpack:///./src/assets/javascripts/browser/location/_/index.ts","webpack:///./src/assets/javascripts/browser/location/base/index.ts","webpack:///./src/assets/javascripts/browser/location/hash/index.ts","webpack:///./src/assets/javascripts/browser/media/index.ts","webpack:///./src/assets/javascripts/browser/toggle/index.ts","webpack:///./src/assets/javascripts/browser/viewport/offset/index.ts","webpack:///./src/assets/javascripts/browser/viewport/size/index.ts","webpack:///./src/assets/javascripts/browser/viewport/_/index.ts","webpack:///./src/assets/javascripts/browser/worker/index.ts","webpack:///./src/assets/javascripts/utilities/config/index.ts","webpack:///./src/assets/javascripts/utilities/jsx/index.ts","webpack:///./src/assets/javascripts/utilities/rxjs/index.ts","webpack:///./src/assets/javascripts/utilities/string/index.ts","webpack:///./src/assets/javascripts/components/index.ts","webpack:///./src/assets/javascripts/integrations/clipboard/index.ts","webpack:///./src/assets/javascripts/integrations/dialog/index.ts","webpack:///./src/assets/javascripts/integrations/instant/index.ts","webpack:///./src/assets/javascripts/integrations/keyboard/index.ts","webpack:///./src/assets/javascripts/components/_/index.ts","webpack:///./src/assets/javascripts/components/toc/anchor/set/index.ts","webpack:///./src/assets/javascripts/components/shared/index.ts","webpack:///./src/assets/javascripts/templates/clipboard/index.tsx","webpack:///./src/assets/javascripts/templates/search/index.tsx","webpack:///./src/assets/javascripts/templates/source/index.tsx","webpack:///./src/assets/javascripts/templates/table/index.tsx","webpack:///./src/assets/javascripts/components/shared/sidebar/set/index.ts","webpack:///./src/assets/javascripts/components/toc/anchor/index.ts","webpack:///./src/assets/javascripts/integrations/search/query/transform/index.ts","webpack:///./src/assets/javascripts/integrations/search/_/index.ts","webpack:///./src/assets/javascripts/integrations/search/document/index.ts","webpack:///./src/assets/javascripts/integrations/search/highlighter/index.ts","webpack:///./src/assets/javascripts/integrations/search/query/_/index.ts","webpack:///./src/assets/javascripts/integrations/search/worker/message/index.ts","webpack:///./src/assets/javascripts/integrations/search/worker/_/index.ts","webpack:///./src/assets/javascripts/components/navigation/index.ts","webpack:///./src/assets/javascripts/components/shared/sidebar/index.ts","webpack:///./src/assets/javascripts/components/shared/sidebar/react/index.ts","webpack:///./src/assets/javascripts/components/toc/index.ts","webpack:///./src/assets/javascripts/components/toc/_/index.ts","webpack:///./src/assets/javascripts/components/toc/anchor/react/index.ts","webpack:///./src/assets/javascripts/components/search/_/index.ts","webpack:///./src/assets/javascripts/components/search/query/_/index.ts","webpack:///./src/assets/javascripts/components/search/query/react/index.ts","webpack:///./src/assets/javascripts/components/search/reset/_/index.ts","webpack:///./src/assets/javascripts/components/search/reset/react/index.ts","webpack:///./src/assets/javascripts/components/search/result/set/index.ts","webpack:///./src/assets/javascripts/components/search/result/react/index.ts","webpack:///./src/assets/javascripts/components/search/result/_/index.ts","webpack:///./src/assets/javascripts/components/header/_/index.ts","webpack:///./src/assets/javascripts/components/header/react/index.ts","webpack:///./src/assets/javascripts/components/header/set/index.ts","webpack:///./src/assets/javascripts/components/main/_/index.ts","webpack:///./src/assets/javascripts/components/main/react/index.ts","webpack:///./src/assets/javascripts/components/main/set/index.ts","webpack:///./src/assets/javascripts/components/tabs/_/index.ts","webpack:///./src/assets/javascripts/components/tabs/react/index.ts","webpack:///./src/assets/javascripts/components/tabs/set/index.ts","webpack:///./src/assets/javascripts/patches/scrollfix/index.ts","webpack:///./src/assets/javascripts/patches/source/index.ts","webpack:///./src/assets/javascripts/patches/source/github/index.ts","webpack:///./src/assets/javascripts/patches/source/gitlab/index.ts","webpack:///./src/assets/javascripts/index.ts","webpack:///./src/assets/javascripts/patches/code/index.ts","webpack:///./src/assets/javascripts/patches/details/index.ts","webpack:///./src/assets/javascripts/patches/script/index.ts","webpack:///./src/assets/javascripts/patches/table/index.ts"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","0","exports","module","l","m","c","d","name","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","p","jsonpArray","window","oldJsonpFunction","slice","watchDocument","document$","ReplaySubject","fromEvent","document","pipe","mapTo","subscribe","getElement","selector","node","querySelector","undefined","getElementOrThrow","el","ReferenceError","getActiveElement","activeElement","HTMLElement","getElements","Array","from","querySelectorAll","createElement","tagName","replaceElement","source","target","replaceWith","setElementFocus","focus","blur","watchElementFocus","merge","map","startWith","getElementOffset","x","scrollLeft","y","scrollTop","watchElementOffset","setElementSelection","HTMLInputElement","Error","select","entry$","Subject","observer$","defer","of","entries","entry","next","switchMap","resize","finalize","disconnect","shareReplay","bufferSize","refCount","watchElementSize","tap","observer","observe","filter","unobserve","contentRect","width","height","offsetWidth","offsetHeight","getElementSize","isSusceptibleToKeyboard","isContentEditable","watchKeyboard","ev","metaKey","ctrlKey","type","claim","preventDefault","stopPropagation","share","setLocation","url","location","href","isLocalLocation","ref","host","test","pathname","isAnchorLocation","hash","watchLocation","BehaviorSubject","URL","watchLocationBase","base","take","toString","replace","getLocationHash","substring","setLocationHash","addEventListener","click","watchLocationHash","watchMedia","query","media","matchMedia","matches","toggles","drawer","search","getToggle","checked","setToggle","watchToggle","getViewportOffset","Math","max","pageXOffset","pageYOffset","setViewportOffset","scrollTo","getViewportSize","innerWidth","innerHeight","watchViewport","combineLatest","passive","offset","size","watchViewportAt","header$","viewport$","size$","distinctUntilKeyChanged","offset$","offsetLeft","offsetTop","watchWorker","worker","tx$","rx$","pluck","throttle","leading","trailing","message","postMessage","switchMapTo","isConfig","config","features","createElementNS","setAttribute","setAttributeNS","appendChild","child","innerHTML","Node","isArray","h","attributes","keys","attr","children","cache","factory","sessionStorage","getItem","JSON","parse","value$","setItem","stringify","err","lang","translate","textContent","truncate","round","toFixed","len","charCodeAt","setupClipboard","dialog$","forEach","block","index","parent","parentElement","id","insertBefore","clipboard$","Observable","subscriber","on","clearSelection","setupDialog","duration","dialog","classList","add","text","body","container","observeOn","animationFrame","delay","removeAttribute","remove","noop","setupInstantLoading","urls","location$","history","scrollRestoration","favicon","state$","closest","includes","push$","pop$","state","distinctUntilChanged","prev","ajax$","skip","ajax","responseType","withCredentials","catchError","sample","pushState","dom","DOMParser","response","parseFromString","instant$","withLatestFrom","title","head","dispatchEvent","CustomEvent","debounceTime","replaceState","bufferCount","setupKeyboard","keyboard$","active","els","indexOf","components$","setupComponents","names","reduce","components","useComponent","setAnchorBlur","resetAnchorBlur","setAnchorActive","toggle","resetAnchorActive","css","renderClipboardButton","class","renderArticleDocument","teaser","terms","score","miss","list","tabIndex","xmlns","viewBox","renderSection","renderSearchResult","threshold","docs","findIndex","doc","article","best","more","renderSource","facts","fact","renderTable","table","setSidebarOffset","style","top","resetSidebarOffset","setSidebarHeight","resetSidebarHeight","defaultTransform","split","join","trim","pipeline","this","documents","Map","parents","Set","path","has","set","setupSearchDocumentMap","highlight","separator","RegExp","_","term","match","setupSearchHighlighter","lunr","tokenizer","use","multiLanguage","fns","a","b","difference","language","fn","searchPipeline","field","boost","Index","load","Query","QueryParser","clauses","parseSearchQuery","clause","presence","PROHIBITED","groups","results","matchData","startsWith","delete","getSearchQueryTerms","metadata","values","every","sort","console","warn","SearchMessageType","isSearchReadyMessage","READY","isSearchQueryMessage","QUERY","isSearchResultMessage","RESULT","setupSearchWorker","index$","base$","Worker","SETUP","mountNavigation","main$","screen$","screen","sidebar","watchSidebar","adjust","min","lock","applySidebar","mountTableOfContents","tablet$","tablet","sidebar$","anchors$","anchors","watchAnchorList","decodeURIComponent","adjust$","header","anchor","pop","applyAnchorList","mountSearch","query$","reset$","result$","status$","status","mountSearchQuery","options","focus$","watchSearchQuery","mountSearchReset","watchSearchReset","addToSearchResultList","applySearchResult","ready$","fetch$","meta","setSearchResultMeta","resetSearchResultMeta","thresholds","scan","scrollHeight","resetSearchResultList","mountSearchResult","identity","mountHeader","styles","getComputedStyle","position","sticky","watchHeader","type$","main","hx","zipWith","setHeaderTitleActive","resetHeaderTitleActive","applyHeaderType","mountMain","setHeaderShadow","resetHeaderShadow","border$","bottom","watchMain","complete","mountTabs","hidden","setTabsHidden","resetTabsHidden","applyTabs","isAppleDevice","navigator","userAgent","fetchSourceFacts","toLowerCase","user","repo","stargazers_count","forks_count","public_repos","fetchSourceFactsFromGitHub","project","encodeURIComponent","star_count","fetchSourceFactsFromGitLab","setScrollLock","resetScrollLock","parseInt","setupSearchIndex","initialize","SyntaxError","hash$","els$","scrollWidth","clientWidth","patchCodeBlocks","details","open","scrollIntoView","patchDetails","concatMap","script","src","onload","hasAttribute","patchSource","sentinel","patchTables","iif","patchScrollfix","navigation$","toc$","tabs$","search$","transform","protocol","sortBy","prop","charAt","visibility","documentElement"],"mappings":"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","file":"assets/javascripts/bundle.d5b17bb4.min.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t0: 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \tvar jsonpArray = window[\"webpackJsonp\"] = window[\"webpackJsonp\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// add entry module to deferred list\n \tdeferredModules.push([82,1]);\n \t// run deferred modules when ready\n \treturn checkDeferredModules();\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ReplaySubject, Subject, fromEvent } from \"rxjs\"\nimport { mapTo } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch document\n *\n * Documents must be implemented as subjects, so all downstream observables are\n * automatically updated when a new document is emitted. This enabled features\n * like instant loading.\n *\n * @return Document subject\n */\nexport function watchDocument(): Subject<Document> {\n const document$ = new ReplaySubject<Document>()\n fromEvent(document, \"DOMContentLoaded\")\n .pipe(\n mapTo(document)\n )\n .subscribe(document$)\n\n /* Return document */\n return document$\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve an element matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @return Element or nothing\n */\nexport function getElement<T extends HTMLElement>(\n selector: string, node: ParentNode = document\n): T | undefined {\n return node.querySelector<T>(selector) || undefined\n}\n\n/**\n * Retrieve an element matching a query selector or throw a reference error\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @return Element\n */\nexport function getElementOrThrow<T extends HTMLElement>(\n selector: string, node: ParentNode = document\n): T {\n const el = getElement<T>(selector, node)\n if (typeof el === \"undefined\")\n throw new ReferenceError(\n `Missing element: expected \"${selector}\" to be present`\n )\n return el\n}\n\n/**\n * Retrieve the currently active element\n *\n * @return Element or nothing\n */\nexport function getActiveElement(): HTMLElement | undefined {\n return document.activeElement instanceof HTMLElement\n ? document.activeElement\n : undefined\n}\n\n/**\n * Retrieve all elements matching the query selector\n *\n * @template T - Element type\n *\n * @param selector - Query selector\n * @param node - Node of reference\n *\n * @return Elements\n */\nexport function getElements<T extends HTMLElement>(\n selector: string, node: ParentNode = document\n): T[] {\n return Array.from(node.querySelectorAll<T>(selector))\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Create an element\n *\n * @template T - Tag name type\n *\n * @param tagName - Tag name\n *\n * @return Element\n */\nexport function createElement<T extends keyof HTMLElementTagNameMap>(\n tagName: T\n): HTMLElementTagNameMap[T] {\n return document.createElement(tagName)\n}\n\n/**\n * Replace an element with another element\n *\n * @param source - Source element\n * @param target - Target element\n */\nexport function replaceElement(\n source: HTMLElement, target: Node\n): void {\n source.replaceWith(target)\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent, merge } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\nimport { getActiveElement } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set element focus\n *\n * @param el - Element\n * @param value - Whether the element should be focused\n */\nexport function setElementFocus(\n el: HTMLElement, value: boolean = true\n): void {\n if (value)\n el.focus()\n else\n el.blur()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element focus\n *\n * @param el - Element\n *\n * @return Element focus observable\n */\nexport function watchElementFocus(\n el: HTMLElement\n): Observable<boolean> {\n return merge(\n fromEvent<FocusEvent>(el, \"focus\"),\n fromEvent<FocusEvent>(el, \"blur\")\n )\n .pipe(\n map(({ type }) => type === \"focus\"),\n startWith(el === getActiveElement())\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent, merge } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element offset\n *\n * @param el - Element\n *\n * @return Element offset\n */\nexport function getElementOffset(el: HTMLElement): ElementOffset {\n return {\n x: el.scrollLeft,\n y: el.scrollTop\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element offset\n *\n * @param el - Element\n *\n * @return Element offset observable\n */\nexport function watchElementOffset(\n el: HTMLElement\n): Observable<ElementOffset> {\n return merge(\n fromEvent(el, \"scroll\"),\n fromEvent(window, \"resize\")\n )\n .pipe(\n map(() => getElementOffset(el)),\n startWith(getElementOffset(el))\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set element text selection\n *\n * @param el - Element\n */\nexport function setElementSelection(\n el: HTMLElement\n): void {\n if (el instanceof HTMLInputElement)\n el.select()\n else\n throw new Error(\"Not implemented\")\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport ResizeObserver from \"resize-observer-polyfill\"\nimport {\n NEVER,\n Observable,\n Subject,\n defer,\n merge,\n of\n} from \"rxjs\"\nimport {\n filter,\n finalize,\n map,\n shareReplay,\n startWith,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Element offset\n */\nexport interface ElementSize {\n width: number /* Element width */\n height: number /* Element height */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Resize observer entry subject\n */\nconst entry$ = new Subject<ResizeObserverEntry>()\n\n/**\n * Resize observer observable\n *\n * This observable will create a `ResizeObserver` on the first subscription\n * and will automatically terminate it when there are no more subscribers.\n * It's quite important to centralize observation in a single `ResizeObserver`,\n * as the performance difference can be quite dramatic, as the link shows.\n *\n * @see https://bit.ly/3iIYfEm - Google Groups on performance\n */\nconst observer$ = defer(() => of(\n new ResizeObserver(entries => {\n for (const entry of entries)\n entry$.next(entry)\n })\n))\n .pipe(\n switchMap(resize => merge(of(resize), NEVER)\n .pipe(\n finalize(() => resize.disconnect())\n )\n ),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve element size\n *\n * @param el - Element\n *\n * @return Element size\n */\nexport function getElementSize(el: HTMLElement): ElementSize {\n return {\n width: el.offsetWidth,\n height: el.offsetHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch element size\n *\n * This function returns an observable that will subscribe to a single internal\n * instance of `ResizeObserver` upon subscription, and emit resize events until\n * termination. Note that this function should not be called with the same\n * element twice, as the first unsubscription will terminate observation.\n *\n * @param el - Element\n *\n * @return Element size observable\n */\nexport function watchElementSize(\n el: HTMLElement\n): Observable<ElementSize> {\n return observer$\n .pipe(\n tap(observer => observer.observe(el)),\n switchMap(observer => entry$\n .pipe(\n filter(({ target }) => target === el),\n finalize(() => observer.unobserve(el)),\n map(({ contentRect }) => ({\n width: contentRect.width,\n height: contentRect.height\n }))\n )\n ),\n startWith(getElementSize(el))\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent } from \"rxjs\"\nimport { filter, map, share } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Key\n */\nexport interface Key {\n type: string /* Key type */\n claim(): void /* Key claim */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether an element may receive keyboard input\n *\n * @param el - Element\n *\n * @return Test result\n */\nexport function isSusceptibleToKeyboard(el: HTMLElement): boolean {\n switch (el.tagName) {\n\n /* Form elements */\n case \"INPUT\":\n case \"SELECT\":\n case \"TEXTAREA\":\n return true\n\n /* Everything else */\n default:\n return el.isContentEditable\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch keyboard\n *\n * @return Keyboard observable\n */\nexport function watchKeyboard(): Observable<Key> {\n return fromEvent<KeyboardEvent>(window, \"keydown\")\n .pipe(\n filter(ev => !(ev.metaKey || ev.ctrlKey)),\n map(ev => ({\n type: ev.key,\n claim() {\n ev.preventDefault()\n ev.stopPropagation()\n }\n })),\n share()\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { BehaviorSubject, Subject } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location\n *\n * This function will return a `URL` object (and not `Location`) in order to\n * normalize typings across the application. Furthermore, locations need to be\n * tracked without setting them and `Location` is a singleton which represents\n * the current location.\n *\n * @return URL\n */\nexport function getLocation(): URL {\n return new URL(location.href)\n}\n\n/**\n * Set location\n *\n * @param url - URL to change to\n */\nexport function setLocation(url: URL): void {\n location.href = url.href\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Check whether a URL is a local link or a file (except `.html`)\n *\n * @param url - URL or HTML anchor element\n * @param ref - Reference URL\n *\n * @return Test result\n */\nexport function isLocalLocation(\n url: URL | HTMLAnchorElement,\n ref: URL | Location = location\n): boolean {\n return url.host === ref.host\n && /^(?:\\/[\\w-]+)*(?:\\/?|\\.html)$/i.test(url.pathname)\n}\n\n/**\n * Check whether a URL is an anchor link on the current page\n *\n * @param url - URL or HTML anchor element\n * @param ref - Reference URL\n *\n * @return Test result\n */\nexport function isAnchorLocation(\n url: URL | HTMLAnchorElement,\n ref: URL | Location = location\n): boolean {\n return url.pathname === ref.pathname\n && url.hash.length > 0\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location\n *\n * @return Location subject\n */\nexport function watchLocation(): Subject<URL> {\n return new BehaviorSubject<URL>(getLocation())\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable } from \"rxjs\"\nimport { map, shareReplay, take } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n location$: Observable<URL> /* Location observable */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location base\n *\n * @return Location base observable\n */\nexport function watchLocationBase(\n base: string, { location$ }: WatchOptions\n): Observable<string> {\n return location$\n .pipe(\n take(1),\n map(({ href }) => new URL(base, href)\n .toString()\n .replace(/\\/$/, \"\")\n ),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent } from \"rxjs\"\nimport { filter, map, share, startWith } from \"rxjs/operators\"\n\nimport { createElement } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve location hash\n *\n * @return Location hash\n */\nexport function getLocationHash(): string {\n return location.hash.substring(1)\n}\n\n/**\n * Set location hash\n *\n * Setting a new fragment identifier via `location.hash` will have no effect\n * if the value doesn't change. When a new fragment identifier is set, we want\n * the browser to target the respective element at all times, which is why we\n * use this dirty little trick.\n *\n * @param hash - Location hash\n */\nexport function setLocationHash(hash: string): void {\n const el = createElement(\"a\")\n el.href = hash\n el.addEventListener(\"click\", ev => ev.stopPropagation())\n el.click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch location hash\n *\n * @return Location hash observable\n */\nexport function watchLocationHash(): Observable<string> {\n return fromEvent<HashChangeEvent>(window, \"hashchange\")\n .pipe(\n map(getLocationHash),\n startWith(getLocationHash()),\n filter(hash => hash.length > 0),\n share()\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent } from \"rxjs\"\nimport { map, shareReplay, startWith } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch media query\n *\n * @param query - Media query\n *\n * @return Media observable\n */\nexport function watchMedia(query: string): Observable<boolean> {\n const media = matchMedia(query)\n return fromEvent<MediaQueryListEvent>(media, \"change\")\n .pipe(\n map(ev => ev.matches),\n startWith(media.matches),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\nimport { getElementOrThrow } from \"../element\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle\n */\nexport type Toggle =\n | \"drawer\" /* Toggle for drawer */\n | \"search\" /* Toggle for search */\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Toggle map\n */\nconst toggles: Record<Toggle, HTMLInputElement> = {\n drawer: getElementOrThrow(`[data-md-toggle=drawer]`),\n search: getElementOrThrow(`[data-md-toggle=search]`)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve the value of a toggle\n *\n * @param name - Toggle\n *\n * @return Toggle value\n */\nexport function getToggle(name: Toggle): boolean {\n return toggles[name].checked\n}\n\n/**\n * Set toggle\n *\n * Simulating a click event seems to be the most cross-browser compatible way\n * of changing the value while also emitting a `change` event. Before, Material\n * used `CustomEvent` to programmatically change the value of a toggle, but this\n * is a much simpler and cleaner solution which doesn't require a polyfill.\n *\n * @param name - Toggle\n * @param value - Toggle value\n */\nexport function setToggle(name: Toggle, value: boolean): void {\n if (toggles[name].checked !== value)\n toggles[name].click()\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch toggle\n *\n * @param name - Toggle\n *\n * @return Toggle value observable\n */\nexport function watchToggle(name: Toggle): Observable<boolean> {\n const el = toggles[name]\n return fromEvent(el, \"change\")\n .pipe(\n map(() => el.checked),\n startWith(el.checked)\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent, merge } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport offset\n */\nexport interface ViewportOffset {\n x: number /* Horizontal offset */\n y: number /* Vertical offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport offset\n *\n * On iOS Safari, viewport offset can be negative due to overflow scrolling.\n * As this may induce strange behaviors downstream, we'll just limit it to 0.\n *\n * @return Viewport offset\n */\nexport function getViewportOffset(): ViewportOffset {\n return {\n x: Math.max(0, pageXOffset),\n y: Math.max(0, pageYOffset)\n }\n}\n\n/**\n * Set viewport offset\n *\n * @param offset - Viewport offset\n */\nexport function setViewportOffset(\n { x, y }: Partial<ViewportOffset>\n): void {\n window.scrollTo(x || 0, y || 0)\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport offset\n *\n * @return Viewport offset observable\n */\nexport function watchViewportOffset(): Observable<ViewportOffset> {\n return merge(\n fromEvent(window, \"scroll\", { passive: true }),\n fromEvent(window, \"resize\", { passive: true })\n )\n .pipe(\n map(getViewportOffset),\n startWith(getViewportOffset())\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent } from \"rxjs\"\nimport { map, startWith } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport size\n */\nexport interface ViewportSize {\n width: number /* Viewport width */\n height: number /* Viewport height */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Retrieve viewport size\n *\n * @return Viewport size\n */\nexport function getViewportSize(): ViewportSize {\n return {\n width: innerWidth,\n height: innerHeight\n }\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport size\n *\n * @return Viewport size observable\n */\nexport function watchViewportSize(): Observable<ViewportSize> {\n return fromEvent(window, \"resize\", { passive: true })\n .pipe(\n map(getViewportSize),\n startWith(getViewportSize())\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, combineLatest } from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n map,\n shareReplay\n} from \"rxjs/operators\"\n\nimport { Header } from \"components\"\n\nimport {\n ViewportOffset,\n watchViewportOffset\n} from \"../offset\"\nimport {\n ViewportSize,\n watchViewportSize\n} from \"../size\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Viewport\n */\nexport interface Viewport {\n offset: ViewportOffset /* Viewport offset */\n size: ViewportSize /* Viewport size */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch at options\n */\ninterface WatchAtOptions {\n header$: Observable<Header> /* Header observable */\n viewport$: Observable<Viewport> /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch viewport\n *\n * @return Viewport observable\n */\nexport function watchViewport(): Observable<Viewport> {\n return combineLatest([\n watchViewportOffset(),\n watchViewportSize()\n ])\n .pipe(\n map(([offset, size]) => ({ offset, size })),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n}\n\n/**\n * Watch viewport relative to element\n *\n * @param el - Element\n * @param options - Options\n *\n * @return Viewport observable\n */\nexport function watchViewportAt(\n el: HTMLElement, { header$, viewport$ }: WatchAtOptions\n): Observable<Viewport> {\n const size$ = viewport$\n .pipe(\n distinctUntilKeyChanged(\"size\")\n )\n\n /* Compute element offset */\n const offset$ = combineLatest([size$, header$])\n .pipe(\n map((): ViewportOffset => ({\n x: el.offsetLeft,\n y: el.offsetTop\n }))\n )\n\n /* Compute relative viewport, return hot observable */\n return combineLatest([header$, viewport$, offset$])\n .pipe(\n map(([{ height }, { offset, size }, { x, y }]) => ({\n offset: {\n x: offset.x - x,\n y: offset.y - y + height\n },\n size\n }))\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, Subject, fromEvent } from \"rxjs\"\nimport {\n pluck,\n share,\n switchMapTo,\n tap,\n throttle\n} from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Worker message\n */\nexport interface WorkerMessage {\n type: unknown /* Message type */\n data?: unknown /* Message data */\n}\n\n/**\n * Worker handler\n *\n * @template T - Message type\n */\nexport interface WorkerHandler<\n T extends WorkerMessage\n> {\n tx$: Subject<T> /* Message transmission subject */\n rx$: Observable<T> /* Message receive observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n *\n * @template T - Worker message type\n */\ninterface WatchOptions<T extends WorkerMessage> {\n tx$: Observable<T> /* Message transmission observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch a web worker\n *\n * This function returns an observable that will send all values emitted by the\n * message observable to the web worker. Web worker communication is expected\n * to be bidirectional (request-response) and synchronous. Messages that are\n * emitted during a pending request are throttled, the last one is emitted.\n *\n * @param worker - Web worker\n * @param options - Options\n *\n * @return Worker message observable\n */\nexport function watchWorker<T extends WorkerMessage>(\n worker: Worker, { tx$ }: WatchOptions<T>\n): Observable<T> {\n\n /* Intercept messages from worker-like objects */\n const rx$ = fromEvent<MessageEvent>(worker, \"message\")\n .pipe<T>(\n pluck(\"data\")\n )\n\n /* Send and receive messages, return hot observable */\n return tx$\n .pipe(\n throttle(() => rx$, { leading: true, trailing: true }),\n tap(message => worker.postMessage(message)),\n switchMapTo(rx$),\n share()\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SearchIndex, SearchTransformFn } from \"integrations\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Feature flags\n */\nexport type Feature =\n | \"navigation.tabs\" /* Tabs navigation */\n | \"navigation.instant\" /* Instant loading */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Configuration\n */\nexport interface Config {\n base: string /* Base URL */\n features: Feature[] /* Feature flags */\n search: {\n worker: string /* Worker URL */\n index?: Promise<SearchIndex> /* Promise resolving with index */\n transform?: SearchTransformFn /* Transformation function */\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Ensure that the given value is a valid configuration\n *\n * We could use `jsonschema` or any other schema validation framework, but that\n * would just add more bloat to the bundle, so we'll keep it plain and simple.\n *\n * @param config - Configuration\n *\n * @return Test result\n */\nexport function isConfig(config: any): config is Config {\n return typeof config === \"object\"\n && typeof config.base === \"string\"\n && typeof config.features === \"object\"\n && typeof config.search === \"object\"\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n// tslint:disable no-null-keyword\n\nimport { JSX as JSXInternal } from \"preact\"\nimport { keys } from \"ramda\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * HTML and SVG attributes\n */\ntype Attributes =\n & JSXInternal.HTMLAttributes\n & JSXInternal.SVGAttributes\n & Record<string, any>\n\n/**\n * Child element\n */\ntype Child =\n | HTMLElement\n | SVGElement\n | Text\n | string\n | number\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create an element\n *\n * @param tagName - HTML or SVG tag\n *\n * @return Element\n */\nfunction createElement(tagName: string): HTMLElement | SVGElement {\n switch (tagName) {\n\n /* SVG elements */\n case \"svg\":\n case \"path\":\n return document.createElementNS(\"http://www.w3.org/2000/svg\", tagName)\n\n /* HTML elements */\n default:\n return document.createElement(tagName)\n }\n}\n\n/**\n * Set an attribute\n *\n * @param el - Element\n * @param name - Attribute name\n * @param value - Attribute value\n */\nfunction setAttribute(\n el: HTMLElement | SVGElement, name: string, value: string) {\n switch (name) {\n\n /* Attributes to be ignored */\n case \"xmlns\":\n break\n\n /* Attributes of SVG elements */\n case \"viewBox\":\n case \"d\":\n if (typeof value !== \"boolean\")\n el.setAttributeNS(null, name, value)\n else if (value)\n el.setAttributeNS(null, name, \"\")\n break\n\n /* Attributes of HTML elements */\n default:\n if (typeof value !== \"boolean\")\n el.setAttribute(name, value)\n else if (value)\n el.setAttribute(name, \"\")\n }\n}\n\n/**\n * Append a child node to an element\n *\n * @param el - Element\n * @param child - Child node(s)\n */\nfunction appendChild(\n el: HTMLElement | SVGElement, child: Child | Child[]\n): void {\n\n /* Handle primitive types (including raw HTML) */\n if (typeof child === \"string\" || typeof child === \"number\") {\n el.innerHTML += child.toString()\n\n /* Handle nodes */\n } else if (child instanceof Node) {\n el.appendChild(child)\n\n /* Handle nested children */\n } else if (Array.isArray(child)) {\n for (const node of child)\n appendChild(el, node)\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * JSX factory\n *\n * @param tagName - HTML or SVG tag\n * @param attributes - HTML attributes\n * @param children - Child elements\n *\n * @return Element\n */\nexport function h(\n tagName: string, attributes: Attributes | null, ...children: Child[]\n): HTMLElement | SVGElement {\n const el = createElement(tagName)\n\n /* Set attributes, if any */\n if (attributes)\n for (const attr of keys(attributes))\n setAttribute(el, attr, attributes[attr])\n\n /* Append child nodes */\n for (const child of children)\n appendChild(el, child)\n\n /* Return element */\n return el\n}\n\n/* ----------------------------------------------------------------------------\n * Namespace\n * ------------------------------------------------------------------------- */\n\nexport declare namespace h {\n namespace JSX {\n type Element = HTMLElement | SVGElement\n type IntrinsicElements = JSXInternal.IntrinsicElements\n }\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, defer, of } from \"rxjs\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Cache the last value emitted by an observable in session storage\n *\n * If the key is not found in session storage, the factory is executed and the\n * latest value emitted will automatically be persisted to sessions storage.\n * Note that the values emitted by the returned observable must be serializable\n * as `JSON`, or data will be lost.\n *\n * @template T - Value type\n *\n * @param key - Cache key\n * @param factory - Observable factory\n *\n * @return Value observable\n */\nexport function cache<T>(\n key: string, factory: () => Observable<T>\n): Observable<T> {\n return defer(() => {\n const data = sessionStorage.getItem(key)\n if (data) {\n return of(JSON.parse(data) as T)\n\n /* Retrieve value from observable factory and write to storage */\n } else {\n const value$ = factory()\n value$.subscribe(value => {\n try {\n sessionStorage.setItem(key, JSON.stringify(value))\n } catch (err) {\n /* Uncritical, just swallow */\n }\n })\n\n /* Return value */\n return value$\n }\n })\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { getElementOrThrow } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Translation keys\n */\ntype TranslateKey =\n | \"clipboard.copy\" /* Copy to clipboard */\n | \"clipboard.copied\" /* Copied to clipboard */\n | \"search.config.lang\" /* Search language */\n | \"search.config.pipeline\" /* Search pipeline */\n | \"search.config.separator\" /* Search separator */\n | \"search.result.placeholder\" /* Type to start searching */\n | \"search.result.none\" /* No matching documents */\n | \"search.result.one\" /* 1 matching document */\n | \"search.result.other\" /* # matching documents */\n | \"search.result.more.one\" /* 1 more on this page */\n | \"search.result.more.other\" /* # more on this page */\n | \"search.result.term.missing\" /* Missing */\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Translations\n */\nlet lang: Record<string, string>\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Translate the given key\n *\n * @param key - Key to be translated\n * @param value - Value to be replaced\n *\n * @return Translation\n */\nexport function translate(\n key: TranslateKey, value?: string | number\n): string {\n if (typeof lang === \"undefined\") {\n const el = getElementOrThrow(\"#__lang\")\n lang = JSON.parse(el.textContent!)\n }\n if (typeof lang[key] === \"undefined\") {\n throw new ReferenceError(`Invalid translation: ${key}`)\n }\n return typeof value !== \"undefined\"\n ? lang[key].replace(\"#\", value.toString())\n : lang[key]\n}\n\n/**\n * Truncate a string after the given number of characters\n *\n * This is not a very reasonable approach, since the summaries kind of suck.\n * It would be better to create something more intelligent, highlighting the\n * search occurrences and making a better summary out of it, but this note was\n * written three years ago, so who knows if we'll ever fix it.\n *\n * @param value - Value to be truncated\n * @param n - Number of characters\n *\n * @return Truncated value\n */\nexport function truncate(value: string, n: number): string {\n let i = n\n if (value.length > i) {\n while (value[i] !== \" \" && --i > 0); // tslint:disable-line\n return `${value.substring(0, i)}...`\n }\n return value\n}\n\n/**\n * Round a number for display with source facts\n *\n * This is a reverse engineered version of GitHub's weird rounding algorithm\n * for stars, forks and all other numbers. While all numbers below `1,000` are\n * returned as-is, bigger numbers are converted to fixed numbers:\n *\n * - `1,049` => `1k`\n * - `1,050` => `1.1k`\n * - `1,949` => `1.9k`\n * - `1,950` => `2k`\n *\n * @param value - Original value\n *\n * @return Rounded value\n */\nexport function round(value: number): string {\n if (value > 999) {\n const digits = +((value - 950) % 1000 > 99)\n return `${((value + 0.000001) / 1000).toFixed(digits)}k`\n } else {\n return value.toString()\n }\n}\n\n/**\n * Simple hash function\n *\n * @see https://bit.ly/2wsVjJ4 - Original source\n *\n * @param value - Value to be hashed\n *\n * @return Hash as 32bit integer\n */\nexport function hash(value: string): number {\n let h = 0\n for (let i = 0, len = value.length; i < len; i++) {\n h = ((h << 5) - h) + value.charCodeAt(i)\n h |= 0 // Convert to 32bit integer\n }\n return h\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nexport * from \"./_\"\nexport * from \"./header\"\nexport * from \"./main\"\nexport * from \"./navigation\"\nexport * from \"./search\"\nexport * from \"./shared\"\nexport * from \"./tabs\"\nexport * from \"./toc\"\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport * as ClipboardJS from \"clipboard\"\nimport { NEVER, Observable, Subject } from \"rxjs\"\nimport { mapTo, share, tap } from \"rxjs/operators\"\n\nimport { getElements } from \"browser\"\nimport { renderClipboardButton } from \"templates\"\nimport { translate } from \"utilities\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Observable<Document> /* Document observable */\n dialog$: Subject<string> /* Dialog subject */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up clipboard\n *\n * This function implements the Clipboard.js integration and injects a button\n * into all code blocks when the document changes.\n *\n * @param options - Options\n *\n * @return Clipboard observable\n */\nexport function setupClipboard(\n { document$, dialog$ }: SetupOptions\n): Observable<ClipboardJS.Event> {\n if (!ClipboardJS.isSupported())\n return NEVER\n\n /* Inject 'copy-to-clipboard' buttons */\n document$.subscribe(() => {\n const blocks = getElements(\"pre > code\")\n blocks.forEach((block, index) => {\n const parent = block.parentElement!\n parent.id = `__code_${index}`\n parent.insertBefore(renderClipboardButton(parent.id), block)\n })\n })\n\n /* Initialize clipboard */\n const clipboard$ = new Observable<ClipboardJS.Event>(subscriber => {\n new ClipboardJS(\".md-clipboard\").on(\"success\", ev => subscriber.next(ev))\n })\n .pipe(\n share()\n )\n\n /* Display notification for clipboard event */\n clipboard$\n .pipe(\n tap(ev => ev.clearSelection()),\n mapTo(translate(\"clipboard.copied\"))\n )\n .subscribe(dialog$)\n\n /* Return clipboard */\n return clipboard$\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Subject, animationFrameScheduler, noop, of } from \"rxjs\"\nimport {\n delay,\n map,\n observeOn,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\nimport { createElement } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n duration?: number /* Display duration (default: 2s) */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up dialog\n *\n * @param options - Options\n *\n * @return Dialog observable\n */\nexport function setupDialog(\n { duration }: SetupOptions = {}\n): Subject<string> {\n const dialog$ = new Subject<string>()\n\n /* Create dialog */\n const dialog = createElement(\"div\") // TODO: improve scoping\n dialog.classList.add(\"md-dialog\", \"md-typeset\")\n\n /* Display dialog */\n dialog$\n .pipe(\n switchMap(text => of(document.body) // useComponent(\"container\")\n .pipe(\n map(container => container.appendChild(dialog)),\n observeOn(animationFrameScheduler),\n delay(1), // Strangley it doesnt work when we push things to the new animation frame...\n tap(el => {\n el.innerHTML = text\n el.setAttribute(\"data-md-state\", \"open\")\n }),\n delay(duration || 2000),\n tap(el => el.removeAttribute(\"data-md-state\")),\n delay(400),\n tap(el => {\n el.innerHTML = \"\"\n el.remove()\n })\n )\n )\n )\n .subscribe(noop)\n\n /* Return dialog */\n return dialog$\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { NEVER, Observable, Subject, fromEvent, merge, of } from \"rxjs\"\nimport { ajax } from \"rxjs//ajax\"\nimport {\n bufferCount,\n catchError,\n debounceTime,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n filter,\n map,\n pluck,\n sample,\n share,\n skip,\n switchMap,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport {\n Viewport,\n ViewportOffset,\n getElement,\n isAnchorLocation,\n isLocalLocation,\n replaceElement,\n setLocation,\n setLocationHash,\n setToggle,\n setViewportOffset\n} from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * History state\n */\ninterface State {\n url: URL /* State URL */\n offset?: ViewportOffset /* State viewport offset */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n document$: Subject<Document> /* Document subject */\n location$: Subject<URL> /* Location subject */\n viewport$: Observable<Viewport> /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up instant loading\n *\n * When fetching, theoretically, we could use `responseType: \"document\"`, but\n * since all MkDocs links are relative, we need to make sure that the current\n * location matches the document we just loaded. Otherwise any relative links\n * in the document could use the old location.\n *\n * This is the reason why we need to synchronize history events and the process\n * of fetching the document for navigation changes (except `popstate` events):\n *\n * 1. Fetch document via `XMLHTTPRequest`\n * 2. Set new location via `history.pushState`\n * 3. Parse and emit fetched document\n *\n * For `popstate` events, we must not use `history.pushState`, or the forward\n * history will be irreversibly overwritten. In case the request fails, the\n * location change is dispatched regularly.\n *\n * @param options - Options\n */\nexport function setupInstantLoading(\n urls: string[], { document$, viewport$, location$ }: SetupOptions\n): void {\n\n /* Disable automatic scroll restoration */\n if (\"scrollRestoration\" in history)\n history.scrollRestoration = \"manual\"\n\n /* Hack: ensure that reloads restore viewport offset */\n fromEvent(window, \"beforeunload\")\n .subscribe(() => {\n history.scrollRestoration = \"auto\"\n })\n\n /* Hack: ensure absolute favicon link to omit 404s on document switch */\n const favicon = getElement<HTMLLinkElement>(`link[rel=\"shortcut icon\"]`)\n if (typeof favicon !== \"undefined\")\n favicon.href = favicon.href // tslint:disable-line no-self-assignment\n\n /* Intercept link clicks and convert to state change */\n const state$ = fromEvent<MouseEvent>(document.body, \"click\")\n .pipe(\n filter(ev => !(ev.metaKey || ev.ctrlKey)),\n switchMap(ev => {\n if (ev.target instanceof HTMLElement) {\n const el = ev.target.closest(\"a\")\n if (\n el && !el.target &&\n isLocalLocation(el) &&\n urls.includes(el.href)\n ) {\n if (!isAnchorLocation(el))\n ev.preventDefault()\n return of(el)\n }\n }\n return NEVER\n }),\n map(el => ({ url: new URL(el.href) })),\n share<State>()\n )\n\n /* Always close search on link click */\n state$.subscribe(() => {\n setToggle(\"search\", false)\n })\n\n /* Filter state changes to dispatch */\n const push$ = state$\n .pipe(\n filter(({ url }) => !isAnchorLocation(url)),\n share()\n )\n\n /* Intercept popstate events (history back and forward) */\n const pop$ = fromEvent<PopStateEvent>(window, \"popstate\")\n .pipe(\n filter(ev => ev.state !== null),\n map(ev => ({\n url: new URL(location.href),\n offset: ev.state\n })),\n share<State>()\n )\n\n /* Emit location change */\n merge(push$, pop$)\n .pipe(\n distinctUntilChanged((prev, next) => prev.url.href === next.url.href),\n pluck(\"url\")\n )\n .subscribe(location$)\n\n /* Fetch document on location change */\n const ajax$ = location$\n .pipe(\n distinctUntilKeyChanged(\"pathname\"),\n skip(1),\n switchMap(url => ajax({\n url: url.href,\n responseType: \"text\",\n withCredentials: true\n })\n .pipe(\n catchError(() => {\n setLocation(url)\n return NEVER\n })\n )\n ),\n share()\n )\n\n /* Set new location as soon as the document was fetched */\n push$\n .pipe(\n sample(ajax$)\n )\n .subscribe(({ url }) => {\n history.pushState({}, \"\", url.toString())\n })\n\n /* Parse and emit document */\n const dom = new DOMParser()\n ajax$\n .pipe(\n map(({ response }) => dom.parseFromString(response, \"text/html\"))\n )\n .subscribe(document$)\n\n /* Intercept instant loading */\n const instant$ = merge(push$, pop$)\n .pipe(\n sample(document$)\n )\n\n // TODO: this must be combined with search scroll restoration on mobile\n instant$.subscribe(({ url, offset }) => {\n if (url.hash && !offset) {\n setLocationHash(url.hash)\n } else {\n setViewportOffset(offset || { y: 0 })\n }\n })\n\n /* Replace document metadata */\n instant$\n .pipe(\n withLatestFrom(document$)\n )\n .subscribe(([, { title, head }]) => {\n document.title = title\n\n /* Replace meta tags */\n for (const selector of [\n `link[rel=\"canonical\"]`,\n `meta[name=\"author\"]`,\n `meta[name=\"description\"]`\n ]) {\n const next = getElement(selector, head)\n const prev = getElement(selector, document.head)\n if (\n typeof next !== \"undefined\" &&\n typeof prev !== \"undefined\"\n ) {\n replaceElement(prev, next)\n }\n }\n\n /* Finished, dispatch document switch event */\n document.dispatchEvent(new CustomEvent(\"DOMContentSwitch\"))\n })\n\n /* Debounce update of viewport offset */\n viewport$\n .pipe(\n debounceTime(250),\n distinctUntilKeyChanged(\"offset\")\n )\n .subscribe(({ offset }) => {\n history.replaceState(offset, \"\")\n })\n\n /* Set viewport offset from history */\n merge(state$, pop$)\n .pipe(\n bufferCount(2, 1),\n filter(([prev, next]) => {\n return prev.url.pathname === next.url.pathname\n && !isAnchorLocation(next.url)\n }),\n map(([, state]) => state)\n )\n .subscribe(({ offset }) => {\n setViewportOffset(offset || { y: 0 })\n })\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable } from \"rxjs\"\nimport {\n filter,\n map,\n share,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport {\n Key,\n getActiveElement,\n getElement,\n getElements,\n getToggle,\n isSusceptibleToKeyboard,\n setElementFocus,\n setElementSelection,\n setToggle,\n watchKeyboard\n} from \"browser\"\nimport { useComponent } from \"components\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Keyboard mode\n */\nexport type KeyboardMode =\n | \"global\" /* Global */\n | \"search\" /* Search is open */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Keyboard\n */\nexport interface Keyboard extends Key {\n mode: KeyboardMode /* Keyboard mode */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up keyboard\n *\n * This function will set up the keyboard handlers and ensure that keys are\n * correctly propagated. Currently there are two modes:\n *\n * - `global`: This mode is active when the search is closed. It is intended\n * to assign hotkeys to specific functions of the site. Currently the search,\n * previous and next page can be triggered.\n *\n * - `search`: This mode is active when the search is open. It maps certain\n * navigational keys to offer search results that can be entirely navigated\n * through keyboard input.\n *\n * The keyboard observable is returned and can be used to monitor the keyboard\n * in order toassign further hotkeys to custom functions.\n *\n * @return Keyboard observable\n */\nexport function setupKeyboard(): Observable<Keyboard> {\n const keyboard$ = watchKeyboard()\n .pipe(\n map<Key, Keyboard>(key => ({\n mode: getToggle(\"search\") ? \"search\" : \"global\",\n ...key\n })),\n filter(({ mode }) => {\n if (mode === \"global\") {\n const active = getActiveElement()\n if (typeof active !== \"undefined\")\n return !isSusceptibleToKeyboard(active)\n }\n return true\n }),\n share()\n )\n\n /* Set up search keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"search\"),\n withLatestFrom(\n useComponent(\"search-query\"),\n useComponent(\"search-result\")\n )\n )\n .subscribe(([key, query, result]) => {\n const active = getActiveElement()\n switch (key.type) {\n\n /* Enter: prevent form submission */\n case \"Enter\":\n if (active === query)\n key.claim()\n break\n\n /* Escape or Tab: close search */\n case \"Escape\":\n case \"Tab\":\n setToggle(\"search\", false)\n setElementFocus(query, false)\n break\n\n /* Vertical arrows: select previous or next search result */\n case \"ArrowUp\":\n case \"ArrowDown\":\n if (typeof active === \"undefined\") {\n setElementFocus(query)\n } else {\n const els = [query, ...getElements(\n \":not(details) > [href], summary, details[open] [href]\",\n result\n )]\n const i = Math.max(0, (\n Math.max(0, els.indexOf(active)) + els.length + (\n key.type === \"ArrowUp\" ? -1 : +1\n )\n ) % els.length)\n setElementFocus(els[i])\n }\n\n /* Prevent scrolling of page */\n key.claim()\n break\n\n /* All other keys: hand to search query */\n default:\n if (query !== getActiveElement())\n setElementFocus(query)\n }\n })\n\n /* Set up global keyboard handlers */\n keyboard$\n .pipe(\n filter(({ mode }) => mode === \"global\"),\n withLatestFrom(useComponent(\"search-query\"))\n )\n .subscribe(([key, query]) => {\n switch (key.type) {\n\n /* Open search and select query */\n case \"f\":\n case \"s\":\n case \"/\":\n setElementFocus(query)\n setElementSelection(query)\n key.claim()\n break\n\n /* Go to previous page */\n case \"p\":\n case \",\":\n const prev = getElement(\"[href][rel=prev]\")\n if (typeof prev !== \"undefined\")\n prev.click()\n break\n\n /* Go to next page */\n case \"n\":\n case \".\":\n const next = getElement(\"[href][rel=next]\")\n if (typeof next !== \"undefined\")\n next.click()\n break\n }\n })\n\n /* Return keyboard */\n return keyboard$\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { EMPTY, Observable, of } from \"rxjs\"\nimport {\n distinctUntilChanged,\n map,\n scan,\n shareReplay,\n switchMap\n} from \"rxjs/operators\"\n\nimport { getElement, replaceElement } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Component\n */\nexport type Component =\n | \"announce\" /* Announcement bar */\n | \"container\" /* Container */\n | \"header\" /* Header */\n | \"header-title\" /* Header title */\n | \"main\" /* Main area */\n | \"navigation\" /* Navigation */\n | \"search\" /* Search */\n | \"search-query\" /* Search input */\n | \"search-reset\" /* Search reset */\n | \"search-result\" /* Search results */\n | \"skip\" /* Skip link */\n | \"tabs\" /* Tabs */\n | \"toc\" /* Table of contents */\n\n/**\n * Component map\n */\nexport type ComponentMap = {\n [P in Component]?: HTMLElement\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n document$: Observable<Document> /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * Component map observable\n */\nlet components$: Observable<ComponentMap>\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up bindings to components with given names\n *\n * This function will maintain bindings to the elements identified by the given\n * names in-between document switches and update the elements in-place.\n *\n * @param names - Component names\n * @param options - Options\n */\nexport function setupComponents(\n names: Component[], { document$ }: WatchOptions\n): void {\n components$ = document$\n .pipe(\n\n /* Build component map */\n map(document => names.reduce<ComponentMap>((components, name) => {\n const el = getElement(`[data-md-component=${name}]`, document)\n return {\n ...components,\n ...typeof el !== \"undefined\" ? { [name]: el } : {}\n }\n }, {})),\n\n /* Re-compute component map on document switch */\n scan((prev, next) => {\n for (const name of names) {\n switch (name) {\n\n /* Top-level components: update */\n case \"announce\":\n case \"header-title\":\n case \"container\":\n case \"skip\":\n if (name in prev && typeof prev[name] !== \"undefined\") {\n replaceElement(prev[name]!, next[name]!)\n prev[name] = next[name]\n }\n break\n\n /* All other components: rebind */\n default:\n if (typeof next[name] !== \"undefined\")\n prev[name] = getElement(`[data-md-component=${name}]`)\n else\n delete prev[name]\n }\n }\n return prev\n }),\n\n /* Convert to hot observable */\n shareReplay({ bufferSize: 1, refCount: true })\n )\n}\n\n/**\n * Retrieve a component\n *\n * The returned observable will only re-emit if the element changed, i.e. if\n * it was replaced from a document which was switched to.\n *\n * @template T - Element type\n *\n * @param name - Component name\n *\n * @return Component observable\n */\nexport function useComponent<T extends HTMLInputElement>(\n name: \"search-query\"\n): Observable<T>\nexport function useComponent<T extends HTMLElement>(\n name: Component\n): Observable<T>\nexport function useComponent<T extends HTMLElement>(\n name: Component\n): Observable<T> {\n return components$\n .pipe(\n switchMap(components => (\n typeof components[name] !== \"undefined\"\n ? of(components[name] as T)\n : EMPTY\n )),\n distinctUntilChanged()\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set anchor blur\n *\n * @param el - Anchor element\n * @param value - Whether the anchor is blurred\n */\nexport function setAnchorBlur(\n el: HTMLElement, value: boolean\n): void {\n el.setAttribute(\"data-md-state\", value ? \"blur\" : \"\")\n}\n\n/**\n * Reset anchor blur\n *\n * @param el - Anchor element\n */\nexport function resetAnchorBlur(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Set anchor active\n *\n * @param el - Anchor element\n * @param value - Whether the anchor is active\n */\nexport function setAnchorActive(\n el: HTMLElement, value: boolean\n): void {\n el.classList.toggle(\"md-nav__link--active\", value)\n}\n\n/**\n * Reset anchor active\n *\n * @param el - Anchor element\n */\nexport function resetAnchorActive(\n el: HTMLElement\n): void {\n el.classList.remove(\"md-nav__link--active\")\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nexport * from \"./sidebar\"\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h, translate } from \"utilities\"\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * CSS classes\n */\nconst css = {\n container: \"md-clipboard md-icon\"\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a 'copy-to-clipboard' button\n *\n * @param id - Unique identifier\n *\n * @return Element\n */\nexport function renderClipboardButton(\n id: string\n) {\n return (\n <button\n class={css.container}\n title={translate(\"clipboard.copy\")}\n data-clipboard-target={`#${id} > code`}\n ></button>\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n SearchDocument,\n SearchMetadata,\n SearchResult\n} from \"integrations/search\"\nimport { h, translate, truncate } from \"utilities\"\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * CSS classes\n */\nconst css = {\n item: \"md-search-result__item\",\n link: \"md-search-result__link\",\n more: \"md-search-result__more\",\n article: \"md-search-result__article md-search-result__article--document\",\n section: \"md-search-result__article\",\n title: \"md-search-result__title\",\n teaser: \"md-search-result__teaser\",\n terms: \"md-search-result__terms\"\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Path of `content-copy` icon\n */\nconst path =\n \"M14,2H6A2,2 0 0,0 4,4V20A2,2 0 0,0 6,22H13C12.59,21.75 12.2,21.44 \" +\n \"11.86,21.1C11.53,20.77 11.25,20.4 11,20H6V4H13V9H18V10.18C18.71,10.34 \" +\n \"19.39,10.61 20,11V8L14,2M20.31,18.9C21.64,16.79 21,14 \" +\n \"18.91,12.68C16.8,11.35 14,12 12.69,14.08C11.35,16.19 12,18.97 \" +\n \"14.09,20.3C15.55,21.23 17.41,21.23 \" +\n \"18.88,20.32L22,23.39L23.39,22L20.31,18.9M16.5,19A2.5,2.5 0 0,1 \" +\n \"14,16.5A2.5,2.5 0 0,1 16.5,14A2.5,2.5 0 0,1 19,16.5A2.5,2.5 0 0,1 16.5,19Z\"\n\n/* ----------------------------------------------------------------------------\n * Helper function\n * ------------------------------------------------------------------------- */\n\n/**\n * Render an article document\n *\n * @param document - Article document\n * @param teaser - Whether to render the teaser\n *\n * @return Element\n */\nfunction renderArticleDocument(\n { location, title, text, terms, score }: SearchDocument & SearchMetadata,\n teaser: boolean\n) {\n const miss = Object.keys(terms)\n // tslint:disable-next-line: array-type\n .reduce<Array<Element | string>>((list, key) => [\n ...list, ...!terms[key] ? [<del>{key}</del>, \" \"] : []\n ], [])\n return (\n <a href={location.toString().replace(/%20/g, \"+\")} class={css.link} tabIndex={-1}>\n <article class={css.article} data-md-score={score.toFixed(2)}>\n <div class=\"md-search-result__icon md-icon\">\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\">\n <path d={path}></path>\n </svg>\n </div>\n <h1 class={css.title}>{title}</h1>\n {teaser && text.length > 0 &&\n <p class={css.teaser}>{truncate(text, 320)}</p>\n }\n {teaser && miss.length > 0 &&\n <p class={css.terms}>\n {translate(\"search.result.term.missing\")}: {...miss.slice(0, -1)}\n </p>\n }\n </article>\n </a>\n )\n}\n\n/**\n * Render a search document\n *\n * @param section - Search document\n *\n * @return Element\n */\nfunction renderSection(\n { location, title, text, terms, score }: SearchDocument & SearchMetadata\n) {\n const miss = Object.keys(terms)\n // tslint:disable-next-line: array-type\n .reduce<Array<Element | string>>((list, key) => [\n ...list, ...!terms[key] ? [<del>{key}</del>, \" \"] : []\n ], [])\n return (\n <a href={location.toString().replace(/%20/g, \"+\")} class={css.link} tabIndex={-1}>\n <article class={css.section} data-md-score={score.toFixed(2)}>\n <h1 class={css.title}>{title}</h1>\n {text.length > 0 &&\n <p class={css.teaser}>{truncate(text, 320)}</p>\n }\n {miss.length > 0 &&\n <p class={css.terms}>\n {translate(\"search.result.term.missing\")}: {...miss.slice(0, -1)}\n </p>\n }\n </article>\n </a>\n )\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a search result\n *\n * @param result - Search result\n *\n * @return Element\n */\nexport function renderSearchResult(\n result: SearchResult, threshold: number = Infinity\n) {\n const docs = [...result]\n\n /* Find and extract parent article */\n const parent = docs.findIndex(doc => !doc.location.includes(\"#\"))\n const [article] = docs.splice(parent, 1)\n\n /* Determine last index above threshold */\n let index = docs.findIndex(doc => doc.score < threshold)\n if (index === -1)\n index = docs.length\n\n /* Partition sections */\n const best = docs.slice(0, index)\n const more = docs.slice(index)\n\n /* Render children */\n const children = [\n renderArticleDocument(article, !parent && index === 0),\n ...best.map(renderSection),\n ...more.length ? [\n <details class={css.more}>\n <summary>\n {more.length > 0 && more.length === 1\n ? translate(\"search.result.more.one\")\n : translate(\"search.result.more.other\", more.length)\n }\n </summary>\n {...more.map(renderSection)}\n </details>\n ] : []\n ]\n\n /* Render search result */\n return (\n <li class={css.item}>\n {children}\n </li>\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SourceFacts } from \"patches/source\"\nimport { h } from \"utilities\"\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * CSS classes\n */\nconst css = {\n facts: \"md-source__facts\",\n fact: \"md-source__fact\"\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render source facts\n *\n * @param facts - Source facts\n *\n * @return Element\n */\nexport function renderSource(\n facts: SourceFacts\n) {\n const children = facts.map(fact => (\n <li class={css.fact}>{fact}</li>\n ))\n return (\n <ul class={css.facts}>\n {children}\n </ul>\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { h } from \"utilities\"\n\n/* ----------------------------------------------------------------------------\n * Data\n * ------------------------------------------------------------------------- */\n\n/**\n * CSS classes\n */\nconst css = {\n wrapper: \"md-typeset__scrollwrap\",\n table: \"md-typeset__table\"\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Render a table inside a wrapper to improve scrolling on mobile\n *\n * @param table - Table element\n *\n * @return Element\n */\nexport function renderTable(\n table: HTMLTableElement\n) {\n return (\n <div class={css.wrapper}>\n <div class={css.table}>\n {table}\n </div>\n </div>\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set sidebar offset\n *\n * @param el - Sidebar element\n * @param value - Sidebar offset\n */\nexport function setSidebarOffset(\n el: HTMLElement, value: number\n): void {\n el.style.top = `${value}px`\n}\n\n/**\n * Reset sidebar offset\n *\n * @param el - Sidebar element\n */\nexport function resetSidebarOffset(\n el: HTMLElement\n): void {\n el.style.top = \"\"\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Set sidebar height\n *\n * @param el - Sidebar element\n * @param value - Sidebar height\n */\nexport function setSidebarHeight(\n el: HTMLElement, value: number\n): void {\n el.style.height = `${value}px`\n}\n\n/**\n * Reset sidebar height\n *\n * @param el - Sidebar element\n */\nexport function resetSidebarHeight(\n el: HTMLElement\n): void {\n el.style.height = \"\"\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nexport * from \"./_\"\nexport * from \"./react\"\nexport * from \"./set\"\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search transformation function\n *\n * @param value - Query value\n *\n * @return Transformed query value\n */\nexport type SearchTransformFn = (value: string) => string\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Default transformation function\n *\n * 1. Search for terms in quotation marks and prepend a `+` modifier to denote\n * that the resulting document must contain all terms, converting the query\n * to an `AND` query (as opposed to the default `OR` behavior). While users\n * may expect terms enclosed in quotation marks to map to span queries, i.e.\n * for which order is important, `lunr` doesn't support them, so the best\n * we can do is to convert the terms to an `AND` query.\n *\n * 2. Replace control characters which are not located at the beginning of the\n * query or preceded by white space, or are not followed by a non-whitespace\n * character or are at the end of the query string. Furthermore, filter\n * unmatched quotation marks.\n *\n * 3. Trim excess whitespace from left and right.\n *\n * @param query - Query value\n *\n * @return Transformed query value\n */\nexport function defaultTransform(query: string): string {\n return query\n .split(/\"([^\"]+)\"/g) /* => 1 */\n .map((terms, index) => index & 1\n ? terms.replace(/^\\b|^(?![^\\x00-\\x7F]|$)|\\s+/g, \" +\")\n : terms\n )\n .join(\"\")\n .replace(/\"|(?:^|\\s+)[*+\\-:^~]+(?=\\s+|$)/g, \"\") /* => 2 */\n .trim() /* => 3 */\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n SearchDocument,\n SearchDocumentMap,\n setupSearchDocumentMap\n} from \"../document\"\nimport {\n SearchHighlightFactoryFn,\n setupSearchHighlighter\n} from \"../highlighter\"\nimport {\n SearchQueryTerms,\n getSearchQueryTerms,\n parseSearchQuery\n} from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index configuration\n */\nexport interface SearchIndexConfig {\n lang: string[] /* Search languages */\n separator: string /* Search separator */\n}\n\n/**\n * Search index document\n */\nexport interface SearchIndexDocument {\n location: string /* Document location */\n title: string /* Document title */\n text: string /* Document text */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search index pipeline function\n */\nexport type SearchIndexPipelineFn =\n | \"trimmer\" /* Trimmer */\n | \"stopWordFilter\" /* Stop word filter */\n | \"stemmer\" /* Stemmer */\n\n/**\n * Search index pipeline\n */\nexport type SearchIndexPipeline = SearchIndexPipelineFn[]\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search index\n *\n * This interfaces describes the format of the `search_index.json` file which\n * is automatically built by the MkDocs search plugin.\n */\nexport interface SearchIndex {\n config: SearchIndexConfig /* Search index configuration */\n docs: SearchIndexDocument[] /* Search index documents */\n index?: object | string /* Prebuilt or serialized index */\n pipeline?: SearchIndexPipeline /* Search index pipeline */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search metadata\n */\nexport interface SearchMetadata {\n score: number /* Score (relevance) */\n terms: SearchQueryTerms /* Search query terms */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search result\n */\nexport type SearchResult = Array<\n SearchDocument & SearchMetadata\n> // tslint:disable-line\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Compute the difference of two lists of strings\n *\n * @param a - 1st list of strings\n * @param b - 2nd list of strings\n *\n * @return Difference\n */\nfunction difference(a: string[], b: string[]): string[] {\n const [x, y] = [new Set(a), new Set(b)]\n return [\n ...new Set([...x].filter(value => !y.has(value)))\n ]\n}\n\n/* ----------------------------------------------------------------------------\n * Class\n * ------------------------------------------------------------------------- */\n\n/**\n * Search index\n *\n * Note that `lunr` is injected via Webpack, as it will otherwise also be\n * bundled in the application bundle.\n */\nexport class Search {\n\n /**\n * Search document mapping\n *\n * A mapping of URLs (including hash fragments) to the actual articles and\n * sections of the documentation. The search document mapping must be created\n * regardless of whether the index was prebuilt or not, as `lunr` itself will\n * only store the actual index.\n */\n protected documents: SearchDocumentMap\n\n /**\n * Search highlight factory function\n */\n protected highlight: SearchHighlightFactoryFn\n\n /**\n * The underlying `lunr` search index\n */\n protected index: lunr.Index\n\n /**\n * Create the search integration\n *\n * @param data - Search index\n */\n public constructor({ config, docs, pipeline, index }: SearchIndex) {\n this.documents = setupSearchDocumentMap(docs)\n this.highlight = setupSearchHighlighter(config)\n\n /* Set separator for tokenizer */\n lunr.tokenizer.separator = new RegExp(config.separator)\n\n /* If no index was given, create it */\n if (typeof index === \"undefined\") {\n this.index = lunr(function() {\n\n /* Set up multi-language support */\n if (config.lang.length === 1 && config.lang[0] !== \"en\") {\n this.use((lunr as any)[config.lang[0]])\n } else if (config.lang.length > 1) {\n this.use((lunr as any).multiLanguage(...config.lang))\n }\n\n /* Compute functions to be removed from the pipeline */\n const fns = difference([\n \"trimmer\", \"stopWordFilter\", \"stemmer\"\n ], pipeline!)\n\n /* Remove functions from the pipeline for registered languages */\n for (const lang of config.lang.map(language => (\n language === \"en\" ? lunr : (lunr as any)[language]\n ))) {\n for (const fn of fns) {\n this.pipeline.remove(lang[fn])\n this.searchPipeline.remove(lang[fn])\n }\n }\n\n /* Set up fields and reference */\n this.field(\"title\", { boost: 1000 })\n this.field(\"text\")\n this.ref(\"location\")\n\n /* Index documents */\n for (const doc of docs)\n this.add(doc)\n })\n\n /* Handle prebuilt or serialized index */\n } else {\n this.index = lunr.Index.load(\n typeof index === \"string\"\n ? JSON.parse(index)\n : index\n )\n }\n }\n\n /**\n * Search for matching documents\n *\n * The search index which MkDocs provides is divided up into articles, which\n * contain the whole content of the individual pages, and sections, which only\n * contain the contents of the subsections obtained by breaking the individual\n * pages up at `h1` ... `h6`. As there may be many sections on different pages\n * with identical titles (for example within this very project, e.g. \"Usage\"\n * or \"Installation\"), they need to be put into the context of the containing\n * page. For this reason, section results are grouped within their respective\n * articles which are the top-level results that are returned.\n *\n * @param query - Query value\n *\n * @return Search results\n */\n public search(query: string): SearchResult[] {\n if (query) {\n try {\n const highlight = this.highlight(query)\n\n /* Parse query to extract clauses for analysis */\n const clauses = parseSearchQuery(query)\n .filter(clause => (\n clause.presence !== lunr.Query.presence.PROHIBITED\n ))\n\n /* Perform search and post-process results */\n const groups = this.index.search(`${query}*`)\n\n /* Apply post-query boosts based on title and search query terms */\n .reduce<SearchResult>((results, { ref, score, matchData }) => {\n const document = this.documents.get(ref)\n if (typeof document !== \"undefined\") {\n const { location, title, text, parent } = document\n\n /* Compute and analyze search query terms */\n const terms = getSearchQueryTerms(\n clauses,\n Object.keys(matchData.metadata)\n )\n\n /* Highlight title and text and apply post-query boosts */\n const boost = +!parent + +Object.values(terms).every(t => t)\n results.push({\n location,\n title: highlight(title),\n text: highlight(text),\n score: score * (1 + boost),\n terms\n })\n }\n return results\n }, [])\n\n /* Sort search results again after applying boosts */\n .sort((a, b) => b.score - a.score)\n\n /* Group search results by page */\n .reduce((results, result) => {\n const document = this.documents.get(result.location)\n if (typeof document !== \"undefined\") {\n const ref = \"parent\" in document\n ? document.parent!.location\n : document.location\n results.set(ref, [...results.get(ref) || [], result])\n }\n return results\n }, new Map<string, SearchResult>())\n\n /* Expand grouped search results */\n return [...groups.values()]\n\n /* Log errors to console (for now) */\n } catch {\n // tslint:disable-next-line no-console\n console.warn(`Invalid query: ${query} – see https://bit.ly/2s3ChXG`)\n }\n }\n\n /* Return nothing in case of error or empty query */\n return []\n }\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport * as escapeHTML from \"escape-html\"\n\nimport { SearchIndexDocument } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search document\n */\nexport interface SearchDocument extends SearchIndexDocument {\n parent?: SearchIndexDocument /* Parent article */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search document mapping\n */\nexport type SearchDocumentMap = Map<string, SearchDocument>\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search document mapping\n *\n * @param docs - Search index documents\n *\n * @return Search document map\n */\nexport function setupSearchDocumentMap(\n docs: SearchIndexDocument[]\n): SearchDocumentMap {\n const documents = new Map<string, SearchDocument>()\n const parents = new Set<SearchDocument>()\n for (const doc of docs) {\n const [path, hash] = doc.location.split(\"#\")\n\n /* Extract location and title */\n const location = doc.location\n const title = doc.title\n\n /* Escape and cleanup text */\n const text = escapeHTML(doc.text)\n .replace(/\\s+(?=[,.:;!?])/g, \"\")\n .replace(/\\s+/g, \" \")\n\n /* Handle section */\n if (hash) {\n const parent = documents.get(path)!\n\n /* Ignore first section, override article */\n if (!parents.has(parent)) {\n parent.title = doc.title\n parent.text = text\n\n /* Remember that we processed the article */\n parents.add(parent)\n\n /* Add subsequent section */\n } else {\n documents.set(location, {\n location,\n title,\n text,\n parent\n })\n }\n\n /* Add article */\n } else {\n documents.set(location, {\n location,\n title,\n text\n })\n }\n }\n return documents\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SearchIndexConfig } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search highlight function\n *\n * @param value - Value\n *\n * @return Highlighted value\n */\nexport type SearchHighlightFn = (value: string) => string\n\n/**\n * Search highlight factory function\n *\n * @param query - Query value\n *\n * @return Search highlight function\n */\nexport type SearchHighlightFactoryFn = (query: string) => SearchHighlightFn\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Create a search highlighter\n *\n * @param config - Search index configuration\n *\n * @return Search highlight factory function\n */\nexport function setupSearchHighlighter(\n config: SearchIndexConfig\n): SearchHighlightFactoryFn {\n const separator = new RegExp(config.separator, \"img\")\n const highlight = (_: unknown, data: string, term: string) => {\n return `${data}<mark data-md-highlight>${term}</mark>`\n }\n\n /* Return factory function */\n return (query: string) => {\n query = query\n .replace(/[\\s*+\\-:~^]+/g, \" \")\n .trim()\n\n /* Create search term match expression */\n const match = new RegExp(`(^|${config.separator})(${\n query\n .replace(/[|\\\\{}()[\\]^$+*?.-]/g, \"\\\\$&\")\n .replace(separator, \"|\")\n })`, \"img\")\n\n /* Highlight string value */\n return value => value\n .replace(match, highlight)\n .replace(/<\\/mark>(\\s+)<mark[^>]*>/img, \"\\$1\")\n }\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search query clause\n */\nexport interface SearchQueryClause {\n presence: lunr.Query.presence /* Clause presence */\n term: string /* Clause term */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search query terms\n */\nexport type SearchQueryTerms = Record<string, boolean>\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Parse a search query for analysis\n *\n * @param value - Query value\n *\n * @return Search query clauses\n */\nexport function parseSearchQuery(\n value: string\n): SearchQueryClause[] {\n const query = new (lunr as any).Query([\"title\", \"text\"])\n const parser = new (lunr as any).QueryParser(value, query)\n\n /* Parse and return query clauses */\n parser.parse()\n return query.clauses\n}\n\n/**\n * Analyze the search query clauses in regard to the search terms found\n *\n * @param query - Search query clauses\n * @param terms - Search terms\n *\n * @return Search query terms\n */\nexport function getSearchQueryTerms(\n query: SearchQueryClause[], terms: string[]\n): SearchQueryTerms {\n const clauses = new Set<SearchQueryClause>(query)\n\n /* Match query clauses against terms */\n const result: SearchQueryTerms = {}\n for (let t = 0; t < terms.length; t++)\n for (const clause of clauses)\n if (terms[t].startsWith(clause.term)) {\n result[clause.term] = true\n clauses.delete(clause)\n }\n\n /* Annotate unmatched query clauses */\n for (const clause of clauses)\n result[clause.term] = false\n\n /* Return query terms */\n return result\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { SearchIndex, SearchResult } from \"../../_\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search message type\n */\nexport const enum SearchMessageType {\n SETUP, /* Search index setup */\n READY, /* Search index ready */\n QUERY, /* Search query */\n RESULT /* Search results */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * A message containing the data necessary to setup the search index\n */\nexport interface SearchSetupMessage {\n type: SearchMessageType.SETUP /* Message type */\n data: SearchIndex | string /* Message data */\n}\n\n/**\n * A message indicating the search index is ready\n */\nexport interface SearchReadyMessage {\n type: SearchMessageType.READY /* Message type */\n}\n\n/**\n * A message containing a search query\n */\nexport interface SearchQueryMessage {\n type: SearchMessageType.QUERY /* Message type */\n data: string /* Message data */\n}\n\n/**\n * A message containing results for a search query\n */\nexport interface SearchResultMessage {\n type: SearchMessageType.RESULT /* Message type */\n data: SearchResult[] /* Message data */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * A message exchanged with the search worker\n */\nexport type SearchMessage =\n | SearchSetupMessage\n | SearchReadyMessage\n | SearchQueryMessage\n | SearchResultMessage\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Type guard for search setup messages\n *\n * @param message - Search worker message\n *\n * @return Test result\n */\nexport function isSearchSetupMessage(\n message: SearchMessage\n): message is SearchSetupMessage {\n return message.type === SearchMessageType.SETUP\n}\n\n/**\n * Type guard for search ready messages\n *\n * @param message - Search worker message\n *\n * @return Test result\n */\nexport function isSearchReadyMessage(\n message: SearchMessage\n): message is SearchReadyMessage {\n return message.type === SearchMessageType.READY\n}\n\n/**\n * Type guard for search query messages\n *\n * @param message - Search worker message\n *\n * @return Test result\n */\nexport function isSearchQueryMessage(\n message: SearchMessage\n): message is SearchQueryMessage {\n return message.type === SearchMessageType.QUERY\n}\n\n/**\n * Type guard for search result messages\n *\n * @param message - Search worker message\n *\n * @return Test result\n */\nexport function isSearchResultMessage(\n message: SearchMessage\n): message is SearchResultMessage {\n return message.type === SearchMessageType.RESULT\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A RTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, Subject, asyncScheduler } from \"rxjs\"\nimport {\n map,\n observeOn,\n share,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport { WorkerHandler, watchWorker } from \"browser\"\n\nimport { SearchIndex } from \"../../_\"\nimport {\n SearchMessage,\n SearchMessageType,\n SearchSetupMessage,\n isSearchResultMessage\n} from \"../message\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Setup options\n */\ninterface SetupOptions {\n index$: Observable<SearchIndex> /* Search index observable */\n base$: Observable<string> /* Location base observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search web worker\n *\n * This function will create a web worker to set up and query the search index\n * which is done using `lunr`. The index must be passed as an observable to\n * enable hacks like _localsearch_ via search index embedding as JSON.\n *\n * @param url - Worker URL\n * @param options - Options\n *\n * @return Worker handler\n */\nexport function setupSearchWorker(\n url: string, { index$, base$ }: SetupOptions\n): WorkerHandler<SearchMessage> {\n const worker = new Worker(url)\n\n /* Create communication channels and resolve relative links */\n const tx$ = new Subject<SearchMessage>()\n const rx$ = watchWorker(worker, { tx$ })\n .pipe(\n withLatestFrom(base$),\n map(([message, base]) => {\n if (isSearchResultMessage(message)) {\n for (const result of message.data)\n for (const document of result)\n document.location = `${base}/${document.location}`\n }\n return message\n }),\n share()\n )\n\n /* Set up search index */\n index$\n .pipe(\n map<SearchIndex, SearchSetupMessage>(data => ({\n type: SearchMessageType.SETUP,\n data\n })),\n observeOn(asyncScheduler)\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Return worker handler */\n return { tx$, rx$ }\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, OperatorFunction, of, pipe } from \"rxjs\"\nimport { map, switchMap } from \"rxjs/operators\"\n\nimport { Viewport } from \"browser\"\n\nimport { Header } from \"../header\"\nimport { Main } from \"../main\"\nimport {\n Sidebar,\n applySidebar,\n watchSidebar\n} from \"../shared\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Navigation for [screen -]\n */\ninterface NavigationBelowScreen {} // tslint:disable-line\n\n/**\n * Navigation for [screen +]\n */\ninterface NavigationAboveScreen {\n sidebar: Sidebar /* Sidebar */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Navigation\n */\nexport type Navigation =\n | NavigationBelowScreen\n | NavigationAboveScreen\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n header$: Observable<Header> /* Header observable */\n main$: Observable<Main> /* Main area observable */\n viewport$: Observable<Viewport> /* Viewport observable */\n screen$: Observable<boolean> /* Screen media observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount navigation from source observable\n *\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountNavigation(\n { header$, main$, viewport$, screen$ }: MountOptions\n): OperatorFunction<HTMLElement, Navigation> {\n return pipe(\n switchMap(el => screen$\n .pipe(\n switchMap(screen => {\n\n /* [screen +]: Mount navigation in sidebar */\n if (screen) {\n return watchSidebar(el, { main$, viewport$ })\n .pipe(\n applySidebar(el, { header$ }),\n map(sidebar => ({ sidebar }))\n )\n\n /* [screen -]: Mount navigation in drawer */\n } else {\n return of({})\n }\n })\n )\n )\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nexport * from \"./_\"\nexport * from \"./react\"\nexport * from \"./set\"\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n MonoTypeOperatorFunction,\n Observable,\n animationFrameScheduler,\n combineLatest,\n pipe\n} from \"rxjs\"\nimport {\n distinctUntilChanged,\n finalize,\n map,\n observeOn,\n tap,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport { Viewport } from \"browser\"\n\nimport { Header } from \"../../../header\"\nimport { Main } from \"../../../main\"\nimport { Sidebar } from \"../_\"\nimport {\n resetSidebarHeight,\n resetSidebarOffset,\n setSidebarHeight,\n setSidebarOffset\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n main$: Observable<Main> /* Main area observable */\n viewport$: Observable<Viewport> /* Viewport observable */\n}\n\n/**\n * Apply options\n */\ninterface ApplyOptions {\n header$: Observable<Header> /* Header observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch sidebar\n *\n * This function returns an observable that computes the visual parameters of\n * the sidebar which depends on the vertical viewport offset, as well as the\n * height of the main area. When the page is scrolled beyond the header, the\n * sidebar is locked and fills the remaining space.\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @return Sidebar observable\n */\nexport function watchSidebar(\n el: HTMLElement, { main$, viewport$ }: WatchOptions\n): Observable<Sidebar> {\n const adjust = el.parentElement!.offsetTop\n - el.parentElement!.parentElement!.offsetTop\n\n /* Compute the sidebar's available height and if it should be locked */\n return combineLatest([main$, viewport$])\n .pipe(\n map(([{ offset, height }, { offset: { y } }]) => {\n height = height\n + Math.min(adjust, Math.max(0, y - offset))\n - adjust\n return {\n height,\n lock: y >= offset + adjust\n }\n }),\n distinctUntilChanged<Sidebar>((a, b) => {\n return a.height === b.height\n && a.lock === b.lock\n })\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Apply sidebar\n *\n * @param el - Sidebar element\n * @param options - Options\n *\n * @return Operator function\n */\nexport function applySidebar(\n el: HTMLElement, { header$ }: ApplyOptions\n): MonoTypeOperatorFunction<Sidebar> {\n return pipe(\n\n /* Defer repaint to next animation frame */\n observeOn(animationFrameScheduler),\n withLatestFrom(header$),\n tap(([{ height, lock }, { height: offset }]) => {\n setSidebarHeight(el, height)\n\n /* Set offset in locked state depending on header height */\n if (lock)\n setSidebarOffset(el, offset)\n else\n resetSidebarOffset(el)\n }),\n\n /* Re-map to sidebar */\n map(([sidebar]) => sidebar),\n\n /* Reset on complete or error */\n finalize(() => {\n resetSidebarOffset(el)\n resetSidebarHeight(el)\n })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nexport * from \"./_\"\nexport * from \"./anchor\"\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n OperatorFunction,\n combineLatest,\n of,\n pipe\n} from \"rxjs\"\nimport { map, switchMap } from \"rxjs/operators\"\n\nimport { Viewport, getElements } from \"browser\"\n\nimport { Header } from \"../../header\"\nimport { Main } from \"../../main\"\nimport {\n Sidebar,\n applySidebar,\n watchSidebar\n} from \"../../shared\"\nimport {\n AnchorList,\n applyAnchorList,\n watchAnchorList\n} from \"../anchor\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Table of contents for [tablet -]\n */\ninterface TableOfContentsBelowTablet {} // tslint:disable-line\n\n/**\n * Table of contents for [tablet +]\n */\ninterface TableOfContentsAboveTablet {\n sidebar: Sidebar /* Sidebar */\n anchors: AnchorList /* Anchor list */\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Table of contents\n */\nexport type TableOfContents =\n | TableOfContentsBelowTablet\n | TableOfContentsAboveTablet\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n header$: Observable<Header> /* Header observable */\n main$: Observable<Main> /* Main area observable */\n viewport$: Observable<Viewport> /* Viewport observable */\n tablet$: Observable<boolean> /* Tablet media observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount table of contents from source observable\n *\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountTableOfContents(\n { header$, main$, viewport$, tablet$ }: MountOptions\n): OperatorFunction<HTMLElement, TableOfContents> {\n return pipe(\n switchMap(el => tablet$\n .pipe(\n switchMap(tablet => {\n\n /* [tablet +]: Mount table of contents in sidebar */\n if (tablet) {\n const els = getElements<HTMLAnchorElement>(\".md-nav__link\", el)\n\n /* Watch and apply sidebar */\n const sidebar$ = watchSidebar(el, { main$, viewport$ })\n .pipe(\n applySidebar(el, { header$ })\n )\n\n /* Watch and apply anchor list (scroll spy) */\n const anchors$ = watchAnchorList(els, { header$, viewport$ })\n .pipe(\n applyAnchorList(els)\n )\n\n /* Combine into single hot observable */\n return combineLatest([sidebar$, anchors$])\n .pipe(\n map(([sidebar, anchors]) => ({ sidebar, anchors }))\n )\n\n /* [tablet -]: Unmount table of contents */\n } else {\n return of({})\n }\n })\n )\n )\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { reverse } from \"ramda\"\nimport {\n MonoTypeOperatorFunction,\n Observable,\n animationFrameScheduler,\n combineLatest,\n pipe\n} from \"rxjs\"\nimport {\n bufferCount,\n distinctUntilChanged,\n distinctUntilKeyChanged,\n finalize,\n map,\n observeOn,\n scan,\n startWith,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\nimport { Viewport, getElement, watchElementSize } from \"browser\"\n\nimport { Header } from \"../../../header\"\nimport { AnchorList } from \"../_\"\nimport {\n resetAnchorActive,\n resetAnchorBlur,\n setAnchorActive,\n setAnchorBlur\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n header$: Observable<Header> /* Header observable */\n viewport$: Observable<Viewport> /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch anchor list\n *\n * This is effectively a scroll-spy implementation which will account for the\n * fixed header and automatically re-calculate anchor offsets when the viewport\n * is resized. The returned observable will only emit if the anchor list needs\n * to be repainted.\n *\n * This implementation tracks an anchor element's entire path starting from its\n * level up to the top-most anchor element, e.g. `[h3, h2, h1]`. Although the\n * Material theme currently doesn't make use of this information, it enables\n * the styling of the entire hierarchy through customization.\n *\n * Note that the current anchor is the last item of the `prev` anchor list.\n *\n * @param els - Anchor elements\n * @param options - Options\n *\n * @return Anchor list observable\n */\nexport function watchAnchorList(\n els: HTMLAnchorElement[], { header$, viewport$ }: WatchOptions\n): Observable<AnchorList> {\n const table = new Map<HTMLAnchorElement, HTMLElement>()\n for (const el of els) {\n const id = decodeURIComponent(el.hash.substring(1))\n const target = getElement(`[id=\"${id}\"]`)\n if (typeof target !== \"undefined\")\n table.set(el, target)\n }\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n map(header => 18 + header.height)\n )\n\n /* Compute partition of previous and next anchors */\n const partition$ = watchElementSize(document.body)\n .pipe(\n distinctUntilKeyChanged(\"height\"),\n\n /* Build index to map anchor paths to vertical offsets */\n map(() => {\n let path: HTMLAnchorElement[] = []\n return [...table].reduce((index, [anchor, target]) => {\n while (path.length) {\n const last = table.get(path[path.length - 1])!\n if (last.tagName >= target.tagName) {\n path.pop()\n } else {\n break\n }\n }\n\n /* If the current anchor is hidden, continue with its parent */\n let offset = target.offsetTop\n while (!offset && target.parentElement) {\n target = target.parentElement\n offset = target.offsetTop\n }\n\n /* Map reversed anchor path to vertical offset */\n return index.set(\n reverse(path = [...path, anchor]),\n offset\n )\n }, new Map<HTMLAnchorElement[], number>())\n }),\n\n /* Re-compute partition when viewport offset changes */\n switchMap(index => combineLatest([adjust$, viewport$])\n .pipe(\n scan(([prev, next], [adjust, { offset: { y } }]) => {\n\n /* Look forward */\n while (next.length) {\n const [, offset] = next[0]\n if (offset - adjust < y) {\n prev = [...prev, next.shift()!]\n } else {\n break\n }\n }\n\n /* Look backward */\n while (prev.length) {\n const [, offset] = prev[prev.length - 1]\n if (offset - adjust >= y) {\n next = [prev.pop()!, ...next]\n } else {\n break\n }\n }\n\n /* Return partition */\n return [prev, next]\n }, [[], [...index]]),\n distinctUntilChanged((a, b) => {\n return a[0] === b[0]\n && a[1] === b[1]\n })\n )\n )\n )\n\n /* Compute and return anchor list migrations */\n return partition$\n .pipe(\n map(([prev, next]) => ({\n prev: prev.map(([path]) => path),\n next: next.map(([path]) => path)\n })),\n\n /* Extract anchor list migrations */\n startWith({ prev: [], next: [] }),\n bufferCount(2, 1),\n map(([a, b]) => {\n\n /* Moving down */\n if (a.prev.length < b.prev.length) {\n return {\n prev: b.prev.slice(Math.max(0, a.prev.length - 1), b.prev.length),\n next: []\n }\n\n /* Moving up */\n } else {\n return {\n prev: b.prev.slice(-1),\n next: b.next.slice(0, b.next.length - a.next.length)\n }\n }\n })\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Apply anchor list\n *\n * @param els - Anchor elements\n *\n * @return Operator function\n */\nexport function applyAnchorList(\n els: HTMLAnchorElement[]\n): MonoTypeOperatorFunction<AnchorList> {\n return pipe(\n\n /* Defer repaint to next animation frame */\n observeOn(animationFrameScheduler),\n tap(({ prev, next }) => {\n\n /* Look forward */\n for (const [el] of next) {\n resetAnchorActive(el)\n resetAnchorBlur(el)\n }\n\n /* Look backward */\n prev.forEach(([el], index) => {\n setAnchorActive(el, index === prev.length - 1)\n setAnchorBlur(el, true)\n })\n }),\n\n /* Reset on complete or error */\n finalize(() => {\n for (const el of els) {\n resetAnchorActive(el)\n resetAnchorBlur(el)\n }\n })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, OperatorFunction, combineLatest, pipe } from \"rxjs\"\nimport {\n filter,\n map,\n mapTo,\n sample,\n startWith,\n switchMap,\n take\n} from \"rxjs/operators\"\n\nimport { WorkerHandler } from \"browser\"\nimport {\n SearchMessage,\n SearchResult,\n isSearchQueryMessage,\n isSearchReadyMessage\n} from \"integrations/search\"\n\nimport { SearchQuery } from \"../query\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search status\n */\nexport type SearchStatus =\n | \"waiting\" /* Search waiting for initialization */\n | \"ready\" /* Search ready */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Search\n */\nexport interface Search {\n status: SearchStatus /* Search status */\n query: SearchQuery /* Search query */\n result: SearchResult[] /* Search result list */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable<SearchQuery> /* Search query observable */\n reset$: Observable<void> /* Search reset observable */\n result$: Observable<SearchResult[]> /* Search result observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search from source observable\n *\n * @param handler - Worker handler\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountSearch(\n { rx$, tx$ }: WorkerHandler<SearchMessage>,\n { query$, reset$, result$ }: MountOptions\n): OperatorFunction<HTMLElement, Search> {\n return pipe(\n switchMap(() => {\n\n /* Compute search status */\n const status$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n mapTo<SearchStatus>(\"ready\"),\n startWith(\"waiting\")\n ) as Observable<SearchStatus>\n\n /* Re-emit the latest query when search is ready */\n tx$\n .pipe(\n filter(isSearchQueryMessage),\n sample(status$),\n take(1)\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Combine into single observable */\n return combineLatest([status$, query$, result$, reset$])\n .pipe(\n map(([status, query, result]) => ({\n status,\n query,\n result\n }))\n )\n })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { OperatorFunction, pipe } from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n map,\n switchMap\n} from \"rxjs/operators\"\n\nimport { WorkerHandler, setToggle } from \"browser\"\nimport {\n SearchMessage,\n SearchMessageType,\n SearchQueryMessage,\n SearchTransformFn\n} from \"integrations\"\n\nimport { watchSearchQuery } from \"../react\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Search query\n */\nexport interface SearchQuery {\n value: string /* Query value */\n focus: boolean /* Query focus */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n transform?: SearchTransformFn /* Transformation function */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search query from source observable\n *\n * @param handler - Worker handler\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountSearchQuery(\n { tx$ }: WorkerHandler<SearchMessage>, options: MountOptions = {}\n): OperatorFunction<HTMLInputElement, SearchQuery> {\n return pipe(\n switchMap(el => {\n const query$ = watchSearchQuery(el, options)\n\n /* Subscribe worker to search query */\n query$\n .pipe(\n distinctUntilKeyChanged(\"value\"),\n map(({ value }): SearchQueryMessage => ({\n type: SearchMessageType.QUERY,\n data: value\n }))\n )\n .subscribe(tx$.next.bind(tx$))\n\n /* Toggle search on focus */\n query$\n .pipe(\n distinctUntilKeyChanged(\"focus\")\n )\n .subscribe(({ focus }) => {\n if (focus)\n setToggle(\"search\", focus)\n })\n\n /* Return search query */\n return query$\n })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, combineLatest, fromEvent, merge } from \"rxjs\"\nimport {\n delay,\n distinctUntilChanged,\n map,\n startWith\n} from \"rxjs/operators\"\n\nimport { watchElementFocus } from \"browser\"\nimport { SearchTransformFn, defaultTransform } from \"integrations\"\n\nimport { SearchQuery } from \"../_\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n transform?: SearchTransformFn /* Transformation function */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch search query\n *\n * Note that the focus event which triggers re-reading the current query value\n * is delayed by `1ms` so the input's empty state is allowed to propagate.\n *\n * @param el - Search query element\n * @param options - Options\n *\n * @return Search query observable\n */\nexport function watchSearchQuery(\n el: HTMLInputElement, { transform }: WatchOptions = {}\n): Observable<SearchQuery> {\n const fn = transform || defaultTransform\n\n /* Intercept keyboard events */\n const value$ = merge(\n fromEvent(el, \"keyup\"),\n fromEvent(el, \"focus\").pipe(delay(1))\n )\n .pipe(\n map(() => fn(el.value)),\n startWith(fn(el.value)),\n distinctUntilChanged()\n )\n\n /* Intercept focus events */\n const focus$ = watchElementFocus(el)\n\n /* Combine into single observable */\n return combineLatest([value$, focus$])\n .pipe(\n map(([value, focus]) => ({ value, focus }))\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { OperatorFunction, pipe } from \"rxjs\"\nimport {\n mapTo,\n startWith,\n switchMap,\n switchMapTo,\n tap\n} from \"rxjs/operators\"\n\nimport { setElementFocus } from \"browser\"\n\nimport { useComponent } from \"../../../_\"\nimport { watchSearchReset } from \"../react\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search reset from source observable\n *\n * @return Operator function\n */\nexport function mountSearchReset(): OperatorFunction<HTMLElement, void> {\n return pipe(\n switchMap(el => watchSearchReset(el)\n .pipe(\n switchMapTo(useComponent(\"search-query\")),\n tap(setElementFocus),\n mapTo(undefined)\n )\n ),\n startWith(undefined)\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, fromEvent } from \"rxjs\"\nimport { mapTo } from \"rxjs/operators\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch search reset\n *\n * @param el - Search reset element\n *\n * @return Search reset observable\n */\nexport function watchSearchReset(\n el: HTMLElement\n): Observable<void> {\n return fromEvent(el, \"click\")\n .pipe(\n mapTo(undefined)\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { translate } from \"utilities\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set number of search results\n *\n * @param el - Search result metadata element\n * @param value - Number of results\n */\nexport function setSearchResultMeta(\n el: HTMLElement, value: number\n): void {\n switch (value) {\n\n /* No results */\n case 0:\n el.textContent = translate(\"search.result.none\")\n break\n\n /* One result */\n case 1:\n el.textContent = translate(\"search.result.one\")\n break\n\n /* Multiple result */\n default:\n el.textContent = translate(\"search.result.other\", value)\n }\n}\n\n/**\n * Reset number of search results\n *\n * @param el - Search result metadata element\n */\nexport function resetSearchResultMeta(\n el: HTMLElement\n): void {\n el.textContent = translate(\"search.result.placeholder\")\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Add an element to the search result list\n *\n * @param el - Search result list element\n * @param child - Search result element\n */\nexport function addToSearchResultList(\n el: HTMLElement, child: Element\n): void {\n el.appendChild(child)\n}\n\n/**\n * Reset search result list\n *\n * @param el - Search result list element\n */\nexport function resetSearchResultList(\n el: HTMLElement\n): void {\n el.innerHTML = \"\"\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n MonoTypeOperatorFunction,\n Observable,\n animationFrameScheduler,\n pipe\n} from \"rxjs\"\nimport {\n finalize,\n map,\n mapTo,\n observeOn,\n scan,\n switchMap,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport { getElementOrThrow } from \"browser\"\nimport { SearchResult } from \"integrations/search\"\nimport { renderSearchResult } from \"templates\"\n\nimport { SearchQuery } from \"../../query\"\nimport {\n addToSearchResultList,\n resetSearchResultList,\n resetSearchResultMeta,\n setSearchResultMeta\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Apply options\n */\ninterface ApplyOptions {\n query$: Observable<SearchQuery> /* Search query observable */\n ready$: Observable<boolean> /* Search ready observable */\n fetch$: Observable<boolean> /* Result fetch observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Apply search results\n *\n * This function will perform a lazy rendering of the search results, depending\n * on the vertical offset of the search result container. When the scroll offset\n * reaches the bottom of the element, more results are fetched and rendered.\n *\n * @param el - Search result element\n * @param options - Options\n *\n * @return Operator function\n */\nexport function applySearchResult(\n el: HTMLElement, { query$, ready$, fetch$ }: ApplyOptions\n): MonoTypeOperatorFunction<SearchResult[]> {\n const list = getElementOrThrow(\".md-search-result__list\", el)\n const meta = getElementOrThrow(\".md-search-result__meta\", el)\n return pipe(\n\n /* Apply search result metadata */\n withLatestFrom(query$, ready$),\n map(([result, query]) => {\n if (query.value) {\n setSearchResultMeta(meta, result.length)\n } else {\n resetSearchResultMeta(meta)\n }\n return result\n }),\n\n /* Apply search result list */\n switchMap(result => {\n const thresholds = [...result.map(([best]) => best.score), 0]\n return fetch$\n .pipe(\n\n /* Defer repaint to next animation frame */\n observeOn(animationFrameScheduler),\n scan(index => {\n const container = el.parentElement!\n while (index < result.length) {\n addToSearchResultList(list, renderSearchResult(\n result[index++], thresholds[index]\n ))\n if (container.scrollHeight - container.offsetHeight > 16)\n break\n }\n return index\n }, 0),\n\n /* Re-map to search result */\n mapTo(result),\n\n /* Reset on complete or error */\n finalize(() => {\n resetSearchResultList(list)\n })\n )\n }\n )\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { identity } from \"ramda\"\nimport { Observable, OperatorFunction, pipe } from \"rxjs\"\nimport {\n distinctUntilChanged,\n filter,\n map,\n mapTo,\n pluck,\n startWith,\n switchMap\n} from \"rxjs/operators\"\n\nimport { WorkerHandler, watchElementOffset } from \"browser\"\nimport {\n SearchMessage,\n SearchResult,\n isSearchReadyMessage,\n isSearchResultMessage\n} from \"integrations\"\n\nimport { SearchQuery } from \"../../query\"\nimport { applySearchResult } from \"../react\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n query$: Observable<SearchQuery> /* Search query observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount search result from source observable\n *\n * @param handler - Worker handler\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountSearchResult(\n { rx$ }: WorkerHandler<SearchMessage>, { query$ }: MountOptions\n): OperatorFunction<HTMLElement, SearchResult[]> {\n return pipe(\n switchMap(el => {\n const container = el.parentElement!\n\n /* Compute if search is ready */\n const ready$ = rx$\n .pipe(\n filter(isSearchReadyMessage),\n mapTo(true)\n )\n\n /* Compute whether there are more search results to fetch */\n const fetch$ = watchElementOffset(container)\n .pipe(\n map(({ y }) => {\n return y >= container.scrollHeight - container.offsetHeight - 16\n }),\n distinctUntilChanged(),\n filter(identity)\n )\n\n /* Apply search results */\n return rx$\n .pipe(\n filter(isSearchResultMessage),\n pluck(\"data\"),\n applySearchResult(el, { query$, ready$, fetch$ }),\n startWith([])\n )\n })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, OperatorFunction, combineLatest, pipe } from \"rxjs\"\nimport {\n distinctUntilChanged,\n filter,\n map,\n startWith,\n switchMap,\n tap,\n zipWith\n} from \"rxjs/operators\"\n\nimport {\n Viewport,\n getElement,\n watchViewportAt\n} from \"browser\"\n\nimport { useComponent } from \"../../_\"\nimport {\n applyHeaderType,\n watchHeader\n} from \"../react\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Header type\n */\nexport type HeaderType =\n | \"site\" /* Header shows site title */\n | \"page\" /* Header shows page title */\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Header\n */\nexport interface Header {\n type: HeaderType /* Header type */\n sticky: boolean /* Header stickyness */\n height: number /* Header visible height */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n document$: Observable<Document> /* Document observable */\n viewport$: Observable<Viewport> /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount header from source observable\n *\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountHeader(\n { document$, viewport$ }: MountOptions\n): OperatorFunction<HTMLElement, Header> {\n return pipe(\n switchMap(el => {\n const header$ = watchHeader(el, { document$ })\n\n /* Compute whether the header should switch to page header */\n const type$ = useComponent(\"main\")\n .pipe(\n map(main => getElement(\"h1, h2, h3, h4, h5, h6\", main)!),\n filter(hx => typeof hx !== \"undefined\"),\n zipWith(useComponent(\"header-title\")),\n switchMap(([hx, title]) => watchViewportAt(hx, { header$, viewport$ })\n .pipe(\n map(({ offset: { y } }) => {\n return y >= hx.offsetHeight ? \"page\" : \"site\"\n }),\n distinctUntilChanged(),\n applyHeaderType(title)\n )\n ),\n startWith<HeaderType>(\"site\")\n )\n\n /* Combine into single observable */\n return combineLatest([header$, type$])\n .pipe(\n map(([header, type]): Header => ({ type, ...header }))\n )\n })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n MonoTypeOperatorFunction,\n Observable,\n animationFrameScheduler,\n of,\n pipe\n} from \"rxjs\"\nimport {\n distinctUntilChanged,\n finalize,\n map,\n observeOn,\n shareReplay,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\nimport { watchElementSize } from \"browser\"\n\nimport { Header, HeaderType } from \"../_\"\nimport {\n resetHeaderTitleActive,\n setHeaderTitleActive\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n document$: Observable<Document> /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch header\n *\n * @param el - Header element\n *\n * @return Header observable\n */\nexport function watchHeader(\n el: HTMLElement, { document$ }: WatchOptions\n): Observable<Omit<Header, \"type\">> {\n return document$\n .pipe(\n map(() => {\n const styles = getComputedStyle(el)\n return [\n \"sticky\", /* Modern browsers */\n \"-webkit-sticky\" /* Safari */\n ].includes(styles.position)\n }),\n distinctUntilChanged(),\n switchMap(sticky => {\n if (sticky) {\n return watchElementSize(el)\n .pipe(\n map(({ height }) => ({\n sticky: true,\n height\n }))\n )\n } else {\n return of({\n sticky: false,\n height: 0\n })\n }\n }),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Apply header title type\n *\n * @param el - Header title element\n *\n * @return Operator function\n */\nexport function applyHeaderType(\n el: HTMLElement\n): MonoTypeOperatorFunction<HeaderType> {\n return pipe(\n\n /* Defer repaint to next animation frame */\n observeOn(animationFrameScheduler),\n tap(type => {\n setHeaderTitleActive(el, type === \"page\")\n }),\n\n /* Reset on complete or error */\n finalize(() => {\n resetHeaderTitleActive(el)\n })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set header title active\n *\n * @param el - Header title element\n * @param value - Whether the title is shown\n */\nexport function setHeaderTitleActive(\n el: HTMLElement, value: boolean\n): void {\n el.setAttribute(\"data-md-state\", value ? \"active\" : \"\")\n}\n\n/**\n * Reset header title active\n *\n * @param el - Header title element\n */\nexport function resetHeaderTitleActive(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n Observable,\n OperatorFunction,\n Subject,\n noop,\n pipe\n} from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n finalize,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\nimport { Viewport } from \"browser\"\n\nimport { useComponent } from \"../../_\"\nimport { Header } from \"../../header\"\nimport {\n applyHeaderShadow,\n watchMain\n} from \"../react\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Main area\n */\nexport interface Main {\n offset: number /* Main area top offset */\n height: number /* Main area visible height */\n active: boolean /* Scrolled past top offset */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n header$: Observable<Header> /* Header observable */\n viewport$: Observable<Viewport> /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount main area from source observable\n *\n * The header must be connected to the main area observable outside of the\n * operator function, as the header will persist in-between document switches\n * while the main area is replaced. However, the header observable must be\n * passed to this function, so we connect both via a long-living subject.\n *\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountMain(\n { header$, viewport$ }: MountOptions\n): OperatorFunction<HTMLElement, Main> {\n const main$ = new Subject<Main>()\n\n /* Connect to main area observable via long-living subject */\n useComponent(\"header\")\n .pipe(\n switchMap(header => main$\n .pipe(\n distinctUntilKeyChanged(\"active\"),\n applyHeaderShadow(header)\n )\n )\n )\n .subscribe(noop)\n\n /* Return operator */\n return pipe(\n switchMap(el => watchMain(el, { header$, viewport$ })),\n tap(main => main$.next(main)),\n finalize(() => main$.complete())\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n MonoTypeOperatorFunction,\n Observable,\n animationFrameScheduler,\n combineLatest,\n pipe\n} from \"rxjs\"\nimport {\n distinctUntilChanged,\n distinctUntilKeyChanged,\n finalize,\n map,\n observeOn,\n pluck,\n switchMap,\n tap\n} from \"rxjs/operators\"\n\nimport { Viewport, watchElementSize } from \"browser\"\n\nimport { Header } from \"../../header\"\nimport { Main } from \"../_\"\nimport {\n resetHeaderShadow,\n setHeaderShadow\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch options\n */\ninterface WatchOptions {\n header$: Observable<Header> /* Header observable */\n viewport$: Observable<Viewport> /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Watch main area\n *\n * This function returns an observable that computes the visual parameters of\n * the main area which depends on the viewport vertical offset and height, as\n * well as the height of the header element, if the header is fixed.\n *\n * @param el - Main area element\n * @param options - Options\n *\n * @return Main area observable\n */\nexport function watchMain(\n el: HTMLElement, { header$, viewport$ }: WatchOptions\n): Observable<Main> {\n\n /* Compute necessary adjustment for header */\n const adjust$ = header$\n .pipe(\n pluck(\"height\"),\n distinctUntilChanged()\n )\n\n /* Compute the main area's top and bottom borders */\n const border$ = adjust$\n .pipe(\n switchMap(() => watchElementSize(el)\n .pipe(\n map(({ height }) => ({\n top: el.offsetTop,\n bottom: el.offsetTop + height\n })),\n distinctUntilKeyChanged(\"bottom\")\n )\n )\n )\n\n /* Compute the main area's offset, visible height and if we scrolled past */\n return combineLatest([adjust$, border$, viewport$])\n .pipe(\n map(([header, { top, bottom }, { offset: { y }, size: { height } }]) => {\n height = Math.max(0, height\n - Math.max(0, top - y, header)\n - Math.max(0, height + y - bottom)\n )\n return {\n offset: top - header,\n height,\n active: top - header <= y\n }\n }),\n distinctUntilChanged<Main>((a, b) => {\n return a.offset === b.offset\n && a.height === b.height\n && a.active === b.active\n })\n )\n}\n\n/* ------------------------------------------------------------------------- */\n\n/**\n * Apply header shadow\n *\n * @param el - Header element\n *\n * @return Operator function\n */\nexport function applyHeaderShadow(\n el: HTMLElement\n): MonoTypeOperatorFunction<Main> {\n return pipe(\n\n /* Defer repaint to next animation frame */\n observeOn(animationFrameScheduler),\n tap(({ active }) => {\n setHeaderShadow(el, active)\n }),\n\n /* Reset on complete or error */\n finalize(() => {\n resetHeaderShadow(el)\n })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set header shadow\n *\n * @param el - Header element\n * @param value - Whether the shadow is shown\n */\nexport function setHeaderShadow(\n el: HTMLElement, value: boolean\n): void {\n el.setAttribute(\"data-md-state\", value ? \"shadow\" : \"\")\n}\n\n/**\n * Reset header shadow\n *\n * @param el - Header element\n */\nexport function resetHeaderShadow(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, OperatorFunction, of, pipe } from \"rxjs\"\nimport {\n distinctUntilKeyChanged,\n map,\n switchMap\n} from \"rxjs/operators\"\n\nimport { Viewport, watchViewportAt } from \"browser\"\n\nimport { Header } from \"../../header\"\nimport { applyTabs } from \"../react\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Tabs\n */\nexport interface Tabs {\n hidden: boolean /* Whether the tabs are hidden */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n header$: Observable<Header> /* Header observable */\n viewport$: Observable<Viewport> /* Viewport observable */\n screen$: Observable<boolean> /* Media screen observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount tabs from source observable\n *\n * @param options - Options\n *\n * @return Operator function\n */\nexport function mountTabs(\n { header$, viewport$, screen$ }: MountOptions\n): OperatorFunction<HTMLElement, Tabs> {\n return pipe(\n switchMap(el => screen$\n .pipe(\n switchMap(screen => {\n\n /* [screen +]: Mount tabs above screen breakpoint */\n if (screen) {\n return watchViewportAt(el, { header$, viewport$ })\n .pipe(\n map(({ offset: { y } }) => ({ hidden: y >= 10 })),\n distinctUntilKeyChanged(\"hidden\"),\n applyTabs(el)\n )\n\n /* [screen -]: Unmount tabs below screen breakpoint */\n } else {\n return of({ hidden: true })\n }\n })\n )\n )\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport {\n MonoTypeOperatorFunction,\n animationFrameScheduler,\n pipe\n} from \"rxjs\"\nimport { finalize, observeOn, tap } from \"rxjs/operators\"\n\nimport { Tabs } from \"../_\"\nimport {\n resetTabsHidden,\n setTabsHidden\n} from \"../set\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Apply tabs\n *\n * @param el - Tabs element\n *\n * @return Operator function\n */\nexport function applyTabs(\n el: HTMLElement\n): MonoTypeOperatorFunction<Tabs> {\n return pipe(\n\n /* Defer repaint to next animation frame */\n observeOn(animationFrameScheduler),\n tap(({ hidden }) => {\n setTabsHidden(el, hidden)\n }),\n\n /* Reset on complete or error */\n finalize(() => {\n resetTabsHidden(el)\n })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set tabs hidden\n *\n * @param el - Tabs element\n * @param value - Whether the element is hidden\n */\nexport function setTabsHidden(\n el: HTMLElement, value: boolean\n): void {\n el.setAttribute(\"data-md-state\", value ? \"hidden\" : \"\")\n}\n\n/**\n * Reset tabs hidden\n *\n * @param el - Tabs element\n */\nexport function resetTabsHidden(\n el: HTMLElement\n): void {\n el.removeAttribute(\"data-md-state\")\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { NEVER, Observable, fromEvent, iif, merge } from \"rxjs\"\nimport { map, mapTo, shareReplay, switchMap } from \"rxjs/operators\"\n\nimport { getElements } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable<Document> /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Check whether the given device is an Apple device\n *\n * @return Test result\n */\nfunction isAppleDevice(): boolean {\n return /(iPad|iPhone|iPod)/.test(navigator.userAgent)\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all elements with `data-md-scrollfix` attributes\n *\n * This is a year-old patch which ensures that overflow scrolling works at the\n * top and bottom of containers on iOS by ensuring a `1px` scroll offset upon\n * the start of a touch event.\n *\n * @see https://bit.ly/2SCtAOO - Original source\n *\n * @param options - Options\n */\nexport function patchScrollfix(\n { document$ }: PatchOptions\n): void {\n const els$ = document$\n .pipe(\n map(() => getElements(\"[data-md-scrollfix]\")),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n\n /* Remove marker attribute, so we'll only add the fix once */\n els$.subscribe(els => {\n for (const el of els)\n el.removeAttribute(\"data-md-scrollfix\")\n })\n\n /* Patch overflow scrolling on touch start */\n iif(isAppleDevice, els$, NEVER)\n .pipe(\n switchMap(els => merge(...els.map(el => (\n fromEvent(el, \"touchstart\", { passive: true })\n .pipe(\n mapTo(el)\n )\n ))))\n )\n .subscribe(el => {\n const top = el.scrollTop\n\n /* We're at the top of the container */\n if (top === 0) {\n el.scrollTop = 1\n\n /* We're at the bottom of the container */\n } else if (top + el.offsetHeight === el.scrollHeight) {\n el.scrollTop = top - 1\n }\n })\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { NEVER, Observable } from \"rxjs\"\nimport { catchError, map, switchMap } from \"rxjs/operators\"\n\nimport { getElementOrThrow, getElements } from \"browser\"\nimport { renderSource } from \"templates\"\nimport { cache, hash } from \"utilities\"\n\nimport { fetchSourceFactsFromGitHub } from \"./github\"\nimport { fetchSourceFactsFromGitLab } from \"./gitlab\"\n\n/* ----------------------------------------------------------------------------\n * Types\n * ------------------------------------------------------------------------- */\n\n/**\n * Source facts\n */\nexport type SourceFacts = string[]\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable<Document> /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch source facts\n *\n * @param url - Source repository URL\n *\n * @return Source facts observable\n */\nfunction fetchSourceFacts(\n url: string\n): Observable<SourceFacts> {\n const [type] = url.match(/(git(?:hub|lab))/i) || []\n switch (type.toLowerCase()) {\n\n /* GitHub repository */\n case \"github\":\n const [, user, repo] = url.match(/^.+github\\.com\\/([^\\/]+)\\/?([^\\/]+)?/i)\n return fetchSourceFactsFromGitHub(user, repo)\n\n /* GitLab repository */\n case \"gitlab\":\n const [, base, slug] = url.match(/^.+?([^\\/]*gitlab[^\\/]+)\\/(.+?)\\/?$/i)\n return fetchSourceFactsFromGitLab(base, slug)\n\n /* Everything else */\n default:\n return NEVER\n }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch elements containing repository information\n *\n * This function will retrieve the URL from the repository link and try to\n * query data from integrated source code platforms like GitHub or GitLab.\n *\n * @param options - Options\n */\nexport function patchSource(\n { document$ }: PatchOptions\n): void {\n document$\n .pipe(\n map(() => getElementOrThrow<HTMLAnchorElement>(\".md-source[href]\")),\n switchMap(({ href }) => (\n cache(`${hash(href)}`, () => fetchSourceFacts(href))\n )),\n catchError(() => NEVER)\n )\n .subscribe(facts => {\n for (const el of getElements(\".md-source__repository\")) {\n if (!el.hasAttribute(\"data-md-state\")) {\n el.setAttribute(\"data-md-state\", \"done\")\n el.appendChild(renderSource(facts))\n }\n }\n })\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Repo, User } from \"github-types\"\nimport { Observable } from \"rxjs\"\nimport { ajax } from \"rxjs/ajax\"\nimport { filter, map, pluck } from \"rxjs/operators\"\n\nimport { round } from \"utilities\"\n\nimport { SourceFacts } from \"..\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitHub source facts\n *\n * @param user - GitHub user\n * @param repo - GitHub repository\n *\n * @return Source facts observable\n */\nexport function fetchSourceFactsFromGitHub(\n user: string, repo?: string\n): Observable<SourceFacts> {\n return ajax({\n url: typeof repo !== \"undefined\"\n ? `https://api.github.com/repos/${user}/${repo}`\n : `https://api.github.com/users/${user}`,\n responseType: \"json\"\n })\n .pipe(\n filter(({ status }) => status === 200),\n pluck(\"response\"),\n map(data => {\n\n /* GitHub repository */\n if (typeof repo !== \"undefined\") {\n const { stargazers_count, forks_count }: Repo = data\n return [\n `${round(stargazers_count || 0)} Stars`,\n `${round(forks_count || 0)} Forks`\n ]\n\n /* GitHub user/organization */\n } else {\n const { public_repos }: User = data\n return [\n `${round(public_repos || 0)} Repositories`\n ]\n }\n })\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { ProjectSchema } from \"gitlab\"\nimport { Observable } from \"rxjs\"\nimport { ajax } from \"rxjs/ajax\"\nimport { filter, map, pluck } from \"rxjs/operators\"\n\nimport { round } from \"utilities\"\n\nimport { SourceFacts } from \"..\"\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Fetch GitLab source facts\n *\n * @param base - GitLab base\n * @param project - GitLab project\n *\n * @return Source facts observable\n */\nexport function fetchSourceFactsFromGitLab(\n base: string, project: string\n): Observable<SourceFacts> {\n return ajax({\n url: `https://${base}/api/v4/projects/${encodeURIComponent(project)}`,\n responseType: \"json\"\n })\n .pipe(\n filter(({ status }) => status === 200),\n pluck(\"response\"),\n map(({ star_count, forks_count }: ProjectSchema) => ([\n `${round(star_count)} Stars`,\n `${round(forks_count)} Forks`\n ]))\n )\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\n// DISCLAIMER: this file is still WIP. There're some refactoring opportunities\n// which must be tackled after we gathered some feedback on v5.\n// tslint:disable\n\nimport \"focus-visible\"\n\nimport { sortBy, prop, values, identity } from \"ramda\"\nimport {\n merge,\n combineLatest,\n animationFrameScheduler,\n fromEvent,\n from,\n defer,\n of,\n NEVER\n} from \"rxjs\"\nimport { ajax } from \"rxjs/ajax\"\nimport {\n delay,\n switchMap,\n tap,\n filter,\n withLatestFrom,\n observeOn,\n take,\n shareReplay,\n pluck,\n catchError,\n map\n} from \"rxjs/operators\"\n\nimport {\n watchToggle,\n setToggle,\n getElements,\n watchMedia,\n watchDocument,\n watchLocation,\n watchLocationHash,\n watchViewport,\n isLocalLocation,\n setLocationHash,\n watchLocationBase\n} from \"browser\"\nimport {\n mountHeader,\n mountMain,\n mountNavigation,\n mountSearch,\n mountTableOfContents,\n mountTabs,\n useComponent,\n setupComponents,\n mountSearchQuery,\n mountSearchReset,\n mountSearchResult\n} from \"components\"\nimport {\n setupClipboard,\n setupDialog,\n setupKeyboard,\n setupInstantLoading,\n setupSearchWorker,\n SearchIndex, SearchIndexPipeline\n} from \"integrations\"\nimport {\n patchCodeBlocks,\n patchTables,\n patchDetails,\n patchScrollfix,\n patchSource,\n patchScripts\n} from \"patches\"\nimport { isConfig, translate } from \"utilities\"\n\n/* ------------------------------------------------------------------------- */\n\n/* Denote that JavaScript is available */\ndocument.documentElement.classList.remove(\"no-js\")\ndocument.documentElement.classList.add(\"js\")\n\n/* Test for iOS */\nif (navigator.userAgent.match(/(iPad|iPhone|iPod)/g))\n document.documentElement.classList.add(\"ios\")\n\n/**\n * Set scroll lock\n *\n * @param el - Scrollable element\n * @param value - Vertical offset\n */\nexport function setScrollLock(\n el: HTMLElement, value: number\n): void {\n el.setAttribute(\"data-md-state\", \"lock\")\n el.style.top = `-${value}px`\n}\n\n/**\n * Reset scroll lock\n *\n * @param el - Scrollable element\n */\nexport function resetScrollLock(\n el: HTMLElement\n): void {\n const value = -1 * parseInt(el.style.top, 10)\n el.removeAttribute(\"data-md-state\")\n el.style.top = \"\"\n if (value)\n window.scrollTo(0, value)\n}\n\n/* ----------------------------------------------------------------------------\n * Helper functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Set up search index\n *\n * @param data - Search index\n *\n * @return Search index\n */\nfunction setupSearchIndex( // Hack: move this outside here, temporarily...\n { config, docs, index }: SearchIndex\n): SearchIndex {\n\n /* Override default language with value from translation */\n if (config.lang.length === 1 && config.lang[0] === \"en\")\n config.lang = [translate(\"search.config.lang\")]\n\n /* Override default separator with value from translation */\n if (config.separator === \"[\\\\s\\\\-]+\")\n config.separator = translate(\"search.config.separator\")\n\n /* Set pipeline from translation */\n const pipeline = translate(\"search.config.pipeline\")\n .split(/\\s*,\\s*/)\n .filter(identity) as SearchIndexPipeline\n\n /* Return search index after defaulting */\n return { config, docs, index, pipeline }\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Initialize Material for MkDocs\n *\n * @param config - Configuration\n */\nexport function initialize(config: unknown) {\n if (!isConfig(config))\n throw new SyntaxError(`Invalid configuration: ${JSON.stringify(config)}`)\n\n /* Set up subjects */\n const document$ = watchDocument()\n const location$ = watchLocation()\n\n /* Set up user interface observables */\n const base$ = watchLocationBase(config.base, { location$ })\n const hash$ = watchLocationHash()\n const viewport$ = watchViewport()\n const tablet$ = watchMedia(\"(min-width: 960px)\")\n const screen$ = watchMedia(\"(min-width: 1220px)\")\n\n /* ----------------------------------------------------------------------- */\n\n /* Set up component bindings */\n setupComponents([\n \"announce\", /* Announcement bar */\n \"container\", /* Container */\n \"header\", /* Header */\n \"header-title\", /* Header title */\n \"main\", /* Main area */\n \"navigation\", /* Navigation */\n \"search\", /* Search */\n \"search-query\", /* Search input */\n \"search-reset\", /* Search reset */\n \"search-result\", /* Search results */\n \"skip\", /* Skip link */\n \"tabs\", /* Tabs */\n \"toc\" /* Table of contents */\n ], { document$ })\n\n const keyboard$ = setupKeyboard()\n\n // Hack: only make code blocks focusable on non-touch devices\n if (matchMedia(\"(hover)\").matches)\n patchCodeBlocks({ document$, viewport$ })\n patchDetails({ document$, hash$ })\n patchScripts({ document$ })\n patchSource({ document$ })\n patchTables({ document$ })\n\n /* Force 1px scroll offset to trigger overflow scrolling */\n patchScrollfix({ document$ })\n\n /* Set up clipboard and dialog */\n const dialog$ = setupDialog()\n const clipboard$ = setupClipboard({ document$, dialog$ })\n\n /* ----------------------------------------------------------------------- */\n\n /* Create header observable */\n const header$ = useComponent(\"header\")\n .pipe(\n mountHeader({ document$, viewport$ }),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n\n const main$ = useComponent(\"main\")\n .pipe(\n mountMain({ header$, viewport$ }),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n\n /* ----------------------------------------------------------------------- */\n\n const navigation$ = useComponent(\"navigation\")\n .pipe(\n mountNavigation({ header$, main$, viewport$, screen$ }),\n shareReplay({ bufferSize: 1, refCount: true }) // shareReplay because there might be late subscribers\n )\n\n const toc$ = useComponent(\"toc\")\n .pipe(\n mountTableOfContents({ header$, main$, viewport$, tablet$ }),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n\n const tabs$ = useComponent(\"tabs\")\n .pipe(\n mountTabs({ header$, viewport$, screen$ }),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n\n /* ----------------------------------------------------------------------- */\n\n /* Search worker - only if search is present */\n const worker$ = useComponent(\"search\")\n .pipe(\n switchMap(() => defer(() => {\n const index = config.search && config.search.index\n ? config.search.index\n : undefined\n\n /* Fetch index if it wasn't passed explicitly */\n const index$ = (\n typeof index !== \"undefined\"\n ? from(index)\n : base$\n .pipe(\n switchMap(base => ajax({\n url: `${base}/search/search_index.json`,\n responseType: \"json\",\n withCredentials: true\n })\n .pipe<SearchIndex>(\n pluck(\"response\")\n )\n )\n )\n )\n .pipe(\n map(setupSearchIndex),\n shareReplay(1)\n )\n\n return of(setupSearchWorker(config.search.worker, {\n base$, index$\n }))\n }))\n )\n\n /* ----------------------------------------------------------------------- */\n\n /* Mount search query */\n const search$ = worker$\n .pipe(\n switchMap(worker => {\n\n const query$ = useComponent(\"search-query\")\n .pipe(\n mountSearchQuery(worker, { transform: config.search.transform }),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n\n /* Mount search reset */\n const reset$ = useComponent(\"search-reset\")\n .pipe(\n mountSearchReset(),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n\n /* Mount search result */\n const result$ = useComponent(\"search-result\")\n .pipe(\n mountSearchResult(worker, { query$ }),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n\n return useComponent(\"search\")\n .pipe(\n mountSearch(worker, { query$, reset$, result$ }),\n )\n }),\n catchError(() => {\n useComponent(\"search\")\n .subscribe(el => el.hidden = true) // TODO: Hack\n return NEVER\n }),\n shareReplay({ bufferSize: 1, refCount: true })\n )\n\n /* ----------------------------------------------------------------------- */\n\n // // put into search...\n hash$\n .pipe(\n tap(() => setToggle(\"search\", false)),\n delay(125), // ensure that it runs after the body scroll reset...\n )\n .subscribe(hash => setLocationHash(`#${hash}`))\n\n // TODO: scroll restoration must be centralized\n combineLatest([\n watchToggle(\"search\"),\n tablet$,\n ])\n .pipe(\n withLatestFrom(viewport$),\n switchMap(([[toggle, tablet], { offset: { y }}]) => {\n const active = toggle && !tablet\n return document$\n .pipe(\n delay(active ? 400 : 100),\n observeOn(animationFrameScheduler),\n tap(({ body }) => active\n ? setScrollLock(body, y)\n : resetScrollLock(body)\n )\n )\n })\n )\n .subscribe()\n\n /* ----------------------------------------------------------------------- */\n\n /* Always close drawer on click */\n fromEvent<MouseEvent>(document.body, \"click\")\n .pipe(\n filter(ev => !(ev.metaKey || ev.ctrlKey)),\n filter(ev => {\n if (ev.target instanceof HTMLElement) {\n const el = ev.target.closest(\"a\") // TODO: abstract as link click?\n if (el && isLocalLocation(el)) {\n return true\n }\n }\n return false\n })\n )\n .subscribe(() => {\n setToggle(\"drawer\", false)\n })\n\n /* Enable instant loading, if not on file:// protocol */\n if (\n config.features.includes(\"navigation.instant\") &&\n location.protocol !== \"file:\"\n ) {\n\n /* Fetch sitemap and extract URL whitelist */\n base$\n .pipe(\n switchMap(base => ajax({\n url: `${base}/sitemap.xml`,\n responseType: \"document\",\n withCredentials: true\n })\n .pipe<Document>(\n pluck(\"response\")\n )\n ),\n withLatestFrom(base$),\n map(([document, base]) => {\n const urls = getElements(\"loc\", document)\n .map(node => node.textContent!)\n\n // Hack: This is a temporary fix to normalize instant loading lookup\n // on localhost and Netlify previews. If this approach proves to be\n // suitable, we'll refactor URL whitelisting anyway. We take the two\n // shortest URLs and determine the common prefix to isolate the\n // domain. If there're no two domains, we just leave it as-is, as\n // there isn't anything to be loaded anway.\n if (urls.length > 1) {\n const [a, b] = sortBy(prop(\"length\"), urls)\n\n /* Determine common prefix */\n let index = 0\n if (a === b)\n index = a.length\n else\n while (a.charAt(index) === b.charAt(index))\n index++\n\n /* Replace common prefix (i.e. base) with effective base */\n for (let i = 0; i < urls.length; i++)\n urls[i] = urls[i].replace(a.slice(0, index), `${base}/`)\n }\n return urls\n })\n )\n .subscribe(urls => {\n setupInstantLoading(urls, { document$, location$, viewport$ })\n })\n }\n\n /* ----------------------------------------------------------------------- */\n\n /* Unhide permalinks on first tab */\n keyboard$\n .pipe(\n filter(key => key.mode === \"global\" && key.type === \"Tab\"),\n take(1)\n )\n .subscribe(() => {\n for (const link of getElements(\".headerlink\"))\n link.style.visibility = \"visible\"\n })\n\n /* ----------------------------------------------------------------------- */\n\n const state = {\n\n /* Browser observables */\n document$,\n location$,\n viewport$,\n\n /* Component observables */\n header$,\n main$,\n navigation$,\n search$,\n tabs$,\n toc$,\n\n /* Integration observables */\n clipboard$,\n keyboard$,\n dialog$\n }\n\n /* Subscribe to all observables */\n merge(...values(state))\n .subscribe()\n return state\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable, combineLatest } from \"rxjs\"\nimport { distinctUntilKeyChanged, map } from \"rxjs/operators\"\n\nimport { Viewport, getElements } from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n document$: Observable<Document> /* Document observable */\n viewport$: Observable<Viewport> /* Viewport observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all `code` elements\n *\n * This function will make overflowing code blocks focusable via keyboard, so\n * they can be scrolled without a mouse.\n *\n * @param options - Options\n */\nexport function patchCodeBlocks(\n { document$, viewport$ }: MountOptions\n): void {\n const els$ = document$\n .pipe(\n map(() => getElements<HTMLTableElement>(\"pre > code\"))\n )\n\n /* Observe viewport size only */\n const size$ = viewport$\n .pipe(\n distinctUntilKeyChanged(\"size\")\n )\n\n /* Make overflowing elements focusable */\n combineLatest([els$, size$])\n .subscribe(([els]) => {\n for (const el of els) {\n if (el.scrollWidth > el.clientWidth)\n el.setAttribute(\"tabindex\", \"0\")\n else\n el.removeAttribute(\"tabindex\")\n }\n })\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { identity } from \"ramda\"\nimport { Observable, fromEvent, merge } from \"rxjs\"\nimport {\n filter,\n map,\n switchMapTo,\n tap\n} from \"rxjs/operators\"\n\nimport {\n getElement,\n getElements,\n watchMedia\n} from \"browser\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable<Document> /* Document observable */\n hash$: Observable<string> /* Location hash observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all `details` elements\n *\n * This function will ensure that all `details` tags are opened prior to\n * printing, so the whole content of the page is included, and on anchor jumps.\n *\n * @param options - Options\n */\nexport function patchDetails(\n { document$, hash$ }: PatchOptions\n): void {\n const els$ = document$\n .pipe(\n map(() => getElements<HTMLDetailsElement>(\"details\"))\n )\n\n /* Open all details before printing */\n merge(\n watchMedia(\"print\").pipe(filter(identity)), /* Webkit */\n fromEvent(window, \"beforeprint\") /* IE, FF */\n )\n .pipe(\n switchMapTo(els$)\n )\n .subscribe(els => {\n for (const el of els)\n el.setAttribute(\"open\", \"\")\n })\n\n /* Open parent details and fix anchor jump */\n hash$\n .pipe(\n map(id => getElement(`[id=\"${id}\"]`)!),\n filter(el => typeof el !== \"undefined\"),\n tap(el => {\n const details = el.closest(\"details\")\n if (details && !details.open)\n details.setAttribute(\"open\", \"\")\n })\n )\n .subscribe(el => el.scrollIntoView())\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { EMPTY, Observable, noop, of } from \"rxjs\"\nimport {\n concatMap,\n map,\n skip,\n switchMap,\n withLatestFrom\n} from \"rxjs/operators\"\n\nimport {\n createElement,\n getElements,\n replaceElement\n} from \"browser\"\nimport { useComponent } from \"components\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch options\n */\ninterface PatchOptions {\n document$: Observable<Document> /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all `script` elements\n *\n * This function must be run after a document switch, which means the first\n * emission must be ignored.\n *\n * @param options - Options\n */\nexport function patchScripts(\n { document$ }: PatchOptions\n): void {\n const els$ = document$\n .pipe(\n skip(1),\n withLatestFrom(useComponent(\"container\")),\n map(([, el]) => getElements<HTMLScriptElement>(\"script\", el))\n )\n\n /* Evaluate all scripts via replacement in order */\n els$\n .pipe(\n switchMap(els => of(...els)),\n concatMap(el => {\n const script = createElement(\"script\")\n if (el.src) {\n script.src = el.src\n replaceElement(el, script)\n\n /* Complete when script is loaded */\n return new Observable(observer => {\n script.onload = () => observer.complete()\n })\n\n /* Complete immediately */\n } else {\n script.textContent = el.textContent!\n replaceElement(el, script)\n return EMPTY\n }\n })\n )\n .subscribe(noop)\n}\n","/*\n * Copyright (c) 2016-2020 Martin Donath <martin.donath@squidfunk.com>\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\n\nimport { Observable } from \"rxjs\"\nimport { map } from \"rxjs/operators\"\n\nimport {\n createElement,\n getElements,\n replaceElement\n} from \"browser\"\nimport { renderTable } from \"templates\"\n\n/* ----------------------------------------------------------------------------\n * Helper types\n * ------------------------------------------------------------------------- */\n\n/**\n * Mount options\n */\ninterface MountOptions {\n document$: Observable<Document> /* Document observable */\n}\n\n/* ----------------------------------------------------------------------------\n * Functions\n * ------------------------------------------------------------------------- */\n\n/**\n * Patch all `table` elements\n *\n * This function will re-render all tables by wrapping them to improve overflow\n * scrolling on smaller screen sizes.\n *\n * @param options - Options\n */\nexport function patchTables(\n { document$ }: MountOptions\n): void {\n const sentinel = createElement(\"table\")\n document$\n .pipe(\n map(() => getElements<HTMLTableElement>(\"table:not([class])\"))\n )\n .subscribe(els => {\n for (const el of els) {\n replaceElement(el, sentinel)\n replaceElement(sentinel, renderTable(el))\n }\n })\n}\n"],"sourceRoot":""} |