{"version":3,"file":"js/853-e77cf8dff3168d813744.chunk.js","mappings":"4HAmBA,SAASA,EAAOC,EAASC,EAAWC,GAClC,MAAMC,EAAKC,SAASC,cAAcL,GASlC,OAPIC,IACFE,EAAGF,UAAYA,GAEbC,IACFC,EAAGD,UAAYA,GAGVC,CACT,CASA,SAASG,EAAkCH,GAClBA,EAAGI,cAAcC,iBAAiB,kBAE1CC,SAASC,IACtBA,EAAEC,MAAMC,QAAU,SAEtB,CAkBA,SAASC,EAA8BC,GACrC,OAAOA,EAAEC,WAAWC,SAAS,EAAG,IAClC,CAWA,SAASC,EACgBd,EACQe,GAE/B,MAAMC,GA5CC,QAAiB,QAAQC,GA6C1BC,EAAQH,EAAKG,MAEnB,GAAqB,IAAjBA,EAAMC,OAER,YADAhB,EAAWH,GAIb,GAAqB,IAAjBkB,EAAMC,QAAgBD,EAAM,GAAGD,KAAOD,EAExC,YADAb,EAAWH,GAIb,MAAMoB,EAzCR,SAA2CpB,EAAIkB,GAC7C,MAAMG,EAAiBrB,EAAGsB,aAAa,kBAEvC,GAAID,EAAgB,CAClB,MAAME,EAAWC,SAASH,EAAgB,IAC1C,OAAOH,EAAMO,MAAM,EAAGF,EACxB,CACE,OAAOL,CAEX,CAgCsBQ,CAClB1B,EACAkB,EAAMS,QAAQC,GAASA,EAAKX,KAAOD,KAGrCI,EAAYd,SAASsB,IACnB,MAAMC,EAAKjC,EAAO,KAAM,QAClBkC,EAAOlC,EAAO,MAAO,QACrBmC,EAAWnC,EAAO,OAAQ,GAlCpC,SAAmDoC,GACjD,MAAMC,EAAW,IAAIC,KAAKF,GACpBG,EAAWF,EAASG,cACpBC,EAAYJ,EAASK,WAAa,EAClCC,EAAUN,EAASO,UAEzB,MAAO,GAAG9B,EAAQ2B,MAAc3B,EAAQ6B,MAAYJ,GACtD,CA2BwCM,CAAWb,EAAKc,eAEpDZ,EAAKa,YAAYZ,GACjBF,EAAGc,YAAYb,GAEf,MAAMc,EAAWhD,EAAO,MAAO,YACzBiD,EAAYjD,EAAO,IAAK,GAAIgC,EAAKkB,OACvCD,EAAUE,KAAOnB,EAAKoB,IAEtBJ,EAASD,YAAYE,GACrBhB,EAAGc,YAAYC,GACf5C,EAAG2C,YAAYd,EAAG,GAEtB,CAgBE5B,SACGI,iBAAiB,4CACjBC,SAAS2C,KAhBdC,eAAgDlD,GAC9C,GAAuC,SAAnCA,EAAGsB,aAAa,eAClB,OAEAtB,EAAGmD,aAAa,cAAe,QAGjC,MAAMC,EAAOpD,EAAGsB,aAAa,aAG7BR,EAASd,QAFU,QAASoD,GAAMC,OAGpC,CAMMC,CAAUL,EAAQ,G,iBC5HjB,SAASM,IAThB,MAUE,OAAO,SAAAtD,SACJuD,cAAc,iCADV,IAEHlC,aAAa,UACnB,C,yBAwCA,Q,QAAe,UAAU,CACvBmC,MAAO,CAAEC,cAAe,CAX1B,SAAiCC,GAER,QAAnBA,EAAQC,QArBd,SAAyBZ,GAEvB,IAAKA,EAAIa,WAAW,QAClB,OAAO,EAGT,IAEE,OAAO,IAAIC,IAAId,GAAKe,WAAaC,OAAOC,SAASF,QACnD,CAAE,MAAOG,GAGP,OAAO,CACT,CACF,CASQC,CAAgBR,EAAQX,MAC1BW,EAAQS,QAAQC,IAAI,eAAgBd,IAG1C,K","sources":["webpack://endrun/./app/components/series_sidebar_component.js","webpack://endrun/./app/javascript/shared/http.js"],"sourcesContent":["// local\nimport http from '$shared/http.js';\nimport { getBootstrapData } from '$shared/utils.js';\n\n/**\n * @typedef {Object} Post\n * @property {number} id\n * @property {string} promo_photo\n * @property {string} published_at\n * @property {string} title\n * @property {string} url\n */\n\n/**\n * @param {string} tagName\n * @param {string} className\n * @param {string} innerText\n * @returns {Element}\n */\nfunction create(tagName, className, innerText) {\n const el = document.createElement(tagName);\n\n if (className) {\n el.className = className;\n }\n if (innerText) {\n el.innerText = innerText;\n }\n\n return el;\n}\n\n/**\n * @returns {number}\n */\nfunction getPostId() {\n return getBootstrapData('post').id;\n}\n\nfunction hideChrome(/** @type {Element} */ el) {\n const allHideIfEmpty = el.parentElement.querySelectorAll('.hide-if-empty');\n\n allHideIfEmpty.forEach((d) => {\n d.style.display = 'none';\n });\n}\n\n/**\n * @param {Element} el\n * @param {Post[]} posts\n * @returns {Post[]}\n */\nfunction slicePosts(/** @type {Element} */ el, posts) {\n const maxPostsString = el.getAttribute('data-max-posts');\n\n if (maxPostsString) {\n const maxPosts = parseInt(maxPostsString, 10);\n return posts.slice(0, maxPosts);\n } else {\n return posts;\n }\n}\n\nfunction zeroPad(/** @type {number} */ n) {\n return n.toString().padStart(2, '0');\n}\n\nfunction formatDate(/** @type {string | number} */ datestamp) {\n const thisDate = new Date(datestamp);\n const dateYear = thisDate.getFullYear();\n const dateMonth = thisDate.getMonth() + 1;\n const dateDay = thisDate.getDate();\n\n return `${zeroPad(dateMonth)}.${zeroPad(dateDay)}.${dateYear}`;\n}\n\nfunction template(\n /** @type {Element} */ el,\n /** @type {{posts: Post[]}} */ data\n) {\n const postId = getPostId();\n const posts = data.posts;\n\n if (posts.length === 0) {\n hideChrome(el);\n return;\n }\n\n if (posts.length === 1 && posts[0].id === postId) {\n hideChrome(el);\n return;\n }\n\n const slicedPosts = slicePosts(\n el,\n posts.filter((post) => post.id !== postId)\n );\n\n slicedPosts.forEach((post) => {\n const li = create('li', 'item');\n const date = create('div', 'date');\n const dateSpan = create('span', '', formatDate(post.published_at));\n\n date.appendChild(dateSpan);\n li.appendChild(date);\n\n const headline = create('div', 'headline');\n const headlineA = create('a', '', post.title);\n headlineA.href = post.url;\n\n headline.appendChild(headlineA);\n li.appendChild(headline);\n el.appendChild(li);\n });\n}\n\nasync function fetchData(/** @type {Element} */ el) {\n if (el.getAttribute('data-loaded') === 'true') {\n return;\n } else {\n el.setAttribute('data-loaded', 'true');\n }\n\n const path = el.getAttribute('data-path');\n const data = await http.get(path).json();\n\n template(el, data);\n}\n\nfunction setup() {\n document\n .querySelectorAll('[data-sidebar-v1],[data-sidebar-germany]')\n .forEach((element) => {\n fetchData(element);\n });\n}\n\nsetup();\n","// packages\nimport ky from 'ky';\n\n/**\n * Returns the CSRF token from the meta tag. This is injected by Rails using\n * the `csrf_meta_tags` helper.\n *\n * @returns {string}\n */\nexport function getCsrfToken() {\n return document\n .querySelector(\"meta[name='csrf-token']\")\n ?.getAttribute('content');\n}\n\n/**\n * Audits whether a given URL is on the same origin as the current page. We do\n * not want to send the CSRF token to different origins because sometimes third-party\n * services will throw errors if they receive a header they don't expect.\n *\n * @private\n * @param {string} url\n * @returns {boolean}\n */\nfunction isUrlSameOrigin(url) {\n // it is a relative URL so same origin\n if (!url.startsWith('http')) {\n return true;\n }\n\n try {\n // if the hostname matches, it's the same origin\n return new URL(url).hostname === window.location.hostname;\n } catch (_) {\n // if something goes wrong with the URL parsing we err on the side of\n // caution and assume it's the same origin\n return true;\n }\n}\n\n/**\n * @param {Request} request\n */\nfunction applyCsrfTokenToRequest(request) {\n // only need the CSRF token for non-GET requests\n if (request.method !== 'GET') {\n // send CSRF token only with same origin requests\n if (isUrlSameOrigin(request.url)) {\n request.headers.set('X-CSRF-Token', getCsrfToken());\n }\n }\n}\n\nexport default ky.create({\n hooks: { beforeRequest: [applyCsrfTokenToRequest] },\n});\n"],"names":["create","tagName","className","innerText","el","document","createElement","hideChrome","parentElement","querySelectorAll","forEach","d","style","display","zeroPad","n","toString","padStart","template","data","postId","id","posts","length","slicedPosts","maxPostsString","getAttribute","maxPosts","parseInt","slice","slicePosts","filter","post","li","date","dateSpan","datestamp","thisDate","Date","dateYear","getFullYear","dateMonth","getMonth","dateDay","getDate","formatDate","published_at","appendChild","headline","headlineA","title","href","url","element","async","setAttribute","path","json","fetchData","getCsrfToken","querySelector","hooks","beforeRequest","request","method","startsWith","URL","hostname","window","location","_","isUrlSameOrigin","headers","set"],"sourceRoot":""}