{"version":3,"sources":["webpack:///./app/javascript/topNavigation/utilities.js","webpack:///./app/javascript/utilities/waitOnBaseData.js","webpack:///./node_modules/focus-visible/dist/focus-visible.js","webpack:///./app/javascript/packs/base.jsx"],"names":["closeHeaderMenu","memberMenu","menuNavButton","setAttribute","classList","remove","dataset","clicked","firstItem","document","getElementById","initializeMemberMenu","memberTopMenu","navigator","userAgent","body","add","addEventListener","_event","contains","focus","focusFirstItem","activeElement","window","requestAnimationFrame","openHeaderMenu","test","e","key","querySelector","event","stopPropagation","target","closest","secondToLastNavLink","setTimeout","toggleBurgerMenu","leftNavState","showMoreMenu","nextElementSibling","getInstantClick","waitTime","Promise","resolve","reject","failTimer","clearInterval","timer","Error","setInterval","InstantClick","clearTimeout","initializeMobileMenu","menuTriggers","moreMenus","forEach","trigger","onclick","setCurrentPageIconLink","currentPage","pageEntries","filter","page","iconLink","blur","removeAttribute","waitOnBaseData","waitingForDataLoad","getAttribute","applyFocusVisiblePolyfill","scope","hadKeyboardEvent","hadFocusVisibleRecently","hadFocusVisibleRecentlyTimeout","inputTypesAllowlist","text","search","url","tel","email","password","number","date","month","week","time","datetime","isValidFocusTarget","el","nodeName","focusTriggersKeyboardModality","type","tagName","readOnly","isContentEditable","addFocusVisibleClass","removeFocusVisibleClass","hasAttribute","onKeyDown","metaKey","altKey","ctrlKey","onPointerDown","onFocus","onBlur","onVisibilityChange","visibilityState","addInitialPointerMoveListeners","onInitialPointerMove","removeInitialPointerMoveListeners","removeEventListener","toLowerCase","nodeType","Node","DOCUMENT_FRAGMENT_NODE","host","DOCUMENT_NODE","documentElement","CustomEvent","error","createEvent","initCustomEvent","dispatchEvent","factory","WINDOW_MODAL_ID","initializeNav","querySelectorAll","getElementsByClassName","Object","entries","Forem","preactImport","undefined","getPreactImport","this","mentionAutoCompleteImports","getMentionAutoCompleteImports","all","initializeMentionAutocompleteTextArea","originalTextArea","parentContainer","parentElement","id","MentionAutocompleteTextArea","fetchSearch","render","h","replaceElement","fetchSuggestions","username","modalImports","getModalImports","showModal","title","contentSelector","overlay","size","onOpen","Modal","currentModalContainer","createElement","appendChild","onClose","focusTrapSelector","dangerouslySetInnerHTML","__html","innerHTML","closeModal","CreatorSettingsController","LogoUploadController","application","Application","start","register","Honeybadger","notify","message","then","on","Runtime","currentMedium","module","ForemMobile","foremMobileNamespace","userSessionBroadcast","location","pathname","loadCreatorSettings"],"mappings":"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","file":"js/base-ee6fde369523271f60d7.chunk.js","sourcesContent":["function closeHeaderMenu(memberMenu, menuNavButton) {\n menuNavButton.setAttribute('aria-expanded', 'false');\n memberMenu.classList.remove('desktop', 'showing');\n delete memberMenu.dataset.clicked;\n}\n\nconst firstItem = document.getElementById('first-nav-link');\n\nfunction openHeaderMenu(memberMenu, menuNavButton) {\n menuNavButton.setAttribute('aria-expanded', 'true');\n memberMenu.classList.add('showing');\n\n if (!firstItem) {\n return;\n }\n\n // Focus on the first item in the menu\n (function focusFirstItem() {\n if (document.activeElement === firstItem) {\n // The first element has focus\n return;\n }\n\n firstItem.focus();\n // requestAnimationFrame is faster and more reliable than setTimeout\n // https://swizec.com/blog/how-to-wait-for-dom-elements-to-show-up-in-modern-browsers\n window.requestAnimationFrame(focusFirstItem);\n })();\n}\n\n/**\n * Determines whether or not a device is a touch device.\n *\n * @returns true if a touch device, otherwise false.\n */\nexport function isTouchDevice() {\n return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini|DEV-Native-ios/i.test(\n navigator.userAgent,\n );\n}\n\n/**\n * Initializes the member navigation menu events.\n *\n * @param {HTMLElement} memberTopMenu The member menu in the top navigation.\n * @param {HTMLElement} menuNavButton The button to activate the member navigation menu.\n */\nexport function initializeMemberMenu(memberTopMenu, menuNavButton) {\n // Typically using CSS for hovering for the menu is the way to go. But... since we use InstantClick for\n // loading pages, the top header navigation never changes in terms of the DOM references.\n // Because of this, we're using mouse events to mouseover/mouseout on the member's avatar\n // to attach styles to get it to show the menu so that this works on desktop and mobile.\n if (navigator.userAgent === 'DEV-Native-ios') {\n document.body.classList.add('dev-ios-native-body');\n }\n const { classList } = memberTopMenu;\n menuNavButton.addEventListener('click', (_event) => {\n if (classList.contains('showing') && memberTopMenu.dataset.clicked) {\n closeHeaderMenu(memberTopMenu, menuNavButton);\n menuNavButton.focus();\n } else {\n openHeaderMenu(memberTopMenu, menuNavButton);\n memberTopMenu.dataset.clicked = 'clicked';\n }\n });\n\n if (isTouchDevice()) {\n memberTopMenu.addEventListener('focus', (_event) => {\n menuNavButton.setAttribute('aria-expanded', 'true');\n });\n } else {\n memberTopMenu.addEventListener('keyup', (e) => {\n if (e.key === 'Escape' && classList.contains('showing')) {\n closeHeaderMenu(memberTopMenu, menuNavButton);\n menuNavButton.focus();\n }\n });\n }\n\n memberTopMenu\n .querySelector('.crayons-header__menu__dropdown')\n .addEventListener('click', (event) => {\n // There is a click event listener on the body and we do not want\n // this click to be caught by it\n event.stopPropagation();\n\n // Close the menu if the user clicked or touched on mobile a link in the menu.\n closeHeaderMenu(memberTopMenu, menuNavButton);\n menuNavButton.focus();\n });\n\n document.addEventListener('click', (event) => {\n if (event.target.closest('#member-menu-button') === menuNavButton) {\n // The menu navigation button manages it's own click event.\n return;\n }\n\n // Close the menu if the user clicked or touched on mobile a link in the menu.\n closeHeaderMenu(memberTopMenu, menuNavButton);\n });\n\n const secondToLastNavLink = document.getElementById('second-last-nav-link');\n\n document\n .getElementById('last-nav-link')\n .addEventListener('blur', (_event) => {\n // When we tab out of the last link in the member menu, close\n // the menu.\n setTimeout(() => {\n if (document.activeElement === secondToLastNavLink) {\n return;\n }\n\n closeHeaderMenu(memberTopMenu, menuNavButton);\n }, 10);\n });\n}\n\nfunction toggleBurgerMenu() {\n const { leftNavState = 'closed' } = document.body.dataset;\n document.body.dataset.leftNavState =\n leftNavState === 'open' ? 'closed' : 'open';\n}\n\nfunction showMoreMenu({ target }) {\n target.nextElementSibling.classList.remove('hidden');\n target.classList.add('hidden');\n}\n\n/**\n * Gets a reference to InstantClick\n *\n * @param {number} [waitTime=2000] The amount of time to wait\n * until giving up waiting for InstantClick to exist\n *\n * @returns {Promise} The global instance of InstantClick.\n */\nexport async function getInstantClick(waitTime = 2000) {\n return new Promise((resolve, reject) => {\n const failTimer = setTimeout(() => {\n clearInterval(timer);\n reject(new Error('Unable to resolve InstantClick'));\n }, waitTime);\n\n const timer = setInterval(() => {\n if (typeof InstantClick !== 'undefined') {\n clearTimeout(failTimer);\n clearInterval(timer);\n resolve(InstantClick);\n }\n });\n });\n}\n\n/**\n * Initializes the hamburger menu for mobile navigation\n *\n * @param {HTMLElement[]} menuTriggers\n * @param {HTMLElement[]} moreMenus\n */\nexport function initializeMobileMenu(menuTriggers, moreMenus) {\n menuTriggers.forEach((trigger) => {\n trigger.onclick = toggleBurgerMenu;\n });\n\n moreMenus.forEach((trigger) => {\n trigger.onclick = showMoreMenu;\n });\n}\n\n/**\n * Sets the icon link visually for the current page if the current page\n * is one of the main icon links of the top navigation.\n *\n * @param {string} currentPage\n * @param {[string, HTMLElement][]} pageEntries\n */\nexport function setCurrentPageIconLink(currentPage, pageEntries) {\n pageEntries\n // Filter out nulls (means the user is logged out so most icons are not in the logged out view)\n .filter(([, iconLink]) => iconLink)\n .forEach(([page, iconLink]) => {\n if (currentPage === page) {\n iconLink.blur();\n iconLink.setAttribute('aria-current', 'page');\n } else {\n iconLink.removeAttribute('aria-current');\n }\n });\n}\n","/**\n * A util function to wrap any code that needs to wait until the page has\n * initialized correctly before executing. This is generally the case for\n * packs/components that require `/app/assets/initializers` to execute first,\n * this way you're ensured that global functions/namespaces will be available\n * (i.e. the Runtime class).\n *\n * @returns {Promise} A chainable promise that will fulfill when the page has\n * loaded correctly and all initializers have run.\n */\nexport function waitOnBaseData() {\n return new Promise((resolve) => {\n const waitingForDataLoad = setInterval(() => {\n if (document.body.getAttribute('data-loaded') === 'true') {\n clearInterval(waitingForDataLoad);\n resolve();\n }\n }, 100);\n });\n}\n","(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory() :\n typeof define === 'function' && define.amd ? define(factory) :\n (factory());\n}(this, (function () { 'use strict';\n\n /**\n * Applies the :focus-visible polyfill at the given scope.\n * A scope in this case is either the top-level Document or a Shadow Root.\n *\n * @param {(Document|ShadowRoot)} scope\n * @see https://github.com/WICG/focus-visible\n */\n function applyFocusVisiblePolyfill(scope) {\n var hadKeyboardEvent = true;\n var hadFocusVisibleRecently = false;\n var hadFocusVisibleRecentlyTimeout = null;\n\n var inputTypesAllowlist = {\n text: true,\n search: true,\n url: true,\n tel: true,\n email: true,\n password: true,\n number: true,\n date: true,\n month: true,\n week: true,\n time: true,\n datetime: true,\n 'datetime-local': true\n };\n\n /**\n * Helper function for legacy browsers and iframes which sometimes focus\n * elements like document, body, and non-interactive SVG.\n * @param {Element} el\n */\n function isValidFocusTarget(el) {\n if (\n el &&\n el !== document &&\n el.nodeName !== 'HTML' &&\n el.nodeName !== 'BODY' &&\n 'classList' in el &&\n 'contains' in el.classList\n ) {\n return true;\n }\n return false;\n }\n\n /**\n * Computes whether the given element should automatically trigger the\n * `focus-visible` class being added, i.e. whether it should always match\n * `:focus-visible` when focused.\n * @param {Element} el\n * @return {boolean}\n */\n function focusTriggersKeyboardModality(el) {\n var type = el.type;\n var tagName = el.tagName;\n\n if (tagName === 'INPUT' && inputTypesAllowlist[type] && !el.readOnly) {\n return true;\n }\n\n if (tagName === 'TEXTAREA' && !el.readOnly) {\n return true;\n }\n\n if (el.isContentEditable) {\n return true;\n }\n\n return false;\n }\n\n /**\n * Add the `focus-visible` class to the given element if it was not added by\n * the author.\n * @param {Element} el\n */\n function addFocusVisibleClass(el) {\n if (el.classList.contains('focus-visible')) {\n return;\n }\n el.classList.add('focus-visible');\n el.setAttribute('data-focus-visible-added', '');\n }\n\n /**\n * Remove the `focus-visible` class from the given element if it was not\n * originally added by the author.\n * @param {Element} el\n */\n function removeFocusVisibleClass(el) {\n if (!el.hasAttribute('data-focus-visible-added')) {\n return;\n }\n el.classList.remove('focus-visible');\n el.removeAttribute('data-focus-visible-added');\n }\n\n /**\n * If the most recent user interaction was via the keyboard;\n * and the key press did not include a meta, alt/option, or control key;\n * then the modality is keyboard. Otherwise, the modality is not keyboard.\n * Apply `focus-visible` to any current active element and keep track\n * of our keyboard modality state with `hadKeyboardEvent`.\n * @param {KeyboardEvent} e\n */\n function onKeyDown(e) {\n if (e.metaKey || e.altKey || e.ctrlKey) {\n return;\n }\n\n if (isValidFocusTarget(scope.activeElement)) {\n addFocusVisibleClass(scope.activeElement);\n }\n\n hadKeyboardEvent = true;\n }\n\n /**\n * If at any point a user clicks with a pointing device, ensure that we change\n * the modality away from keyboard.\n * This avoids the situation where a user presses a key on an already focused\n * element, and then clicks on a different element, focusing it with a\n * pointing device, while we still think we're in keyboard modality.\n * @param {Event} e\n */\n function onPointerDown(e) {\n hadKeyboardEvent = false;\n }\n\n /**\n * On `focus`, add the `focus-visible` class to the target if:\n * - the target received focus as a result of keyboard navigation, or\n * - the event target is an element that will likely require interaction\n * via the keyboard (e.g. a text box)\n * @param {Event} e\n */\n function onFocus(e) {\n // Prevent IE from focusing the document or HTML element.\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (hadKeyboardEvent || focusTriggersKeyboardModality(e.target)) {\n addFocusVisibleClass(e.target);\n }\n }\n\n /**\n * On `blur`, remove the `focus-visible` class from the target.\n * @param {Event} e\n */\n function onBlur(e) {\n if (!isValidFocusTarget(e.target)) {\n return;\n }\n\n if (\n e.target.classList.contains('focus-visible') ||\n e.target.hasAttribute('data-focus-visible-added')\n ) {\n // To detect a tab/window switch, we look for a blur event followed\n // rapidly by a visibility change.\n // If we don't see a visibility change within 100ms, it's probably a\n // regular focus change.\n hadFocusVisibleRecently = true;\n window.clearTimeout(hadFocusVisibleRecentlyTimeout);\n hadFocusVisibleRecentlyTimeout = window.setTimeout(function() {\n hadFocusVisibleRecently = false;\n }, 100);\n removeFocusVisibleClass(e.target);\n }\n }\n\n /**\n * If the user changes tabs, keep track of whether or not the previously\n * focused element had .focus-visible.\n * @param {Event} e\n */\n function onVisibilityChange(e) {\n if (document.visibilityState === 'hidden') {\n // If the tab becomes active again, the browser will handle calling focus\n // on the element (Safari actually calls it twice).\n // If this tab change caused a blur on an element with focus-visible,\n // re-apply the class when the user switches back to the tab.\n if (hadFocusVisibleRecently) {\n hadKeyboardEvent = true;\n }\n addInitialPointerMoveListeners();\n }\n }\n\n /**\n * Add a group of listeners to detect usage of any pointing devices.\n * These listeners will be added when the polyfill first loads, and anytime\n * the window is blurred, so that they are active when the window regains\n * focus.\n */\n function addInitialPointerMoveListeners() {\n document.addEventListener('mousemove', onInitialPointerMove);\n document.addEventListener('mousedown', onInitialPointerMove);\n document.addEventListener('mouseup', onInitialPointerMove);\n document.addEventListener('pointermove', onInitialPointerMove);\n document.addEventListener('pointerdown', onInitialPointerMove);\n document.addEventListener('pointerup', onInitialPointerMove);\n document.addEventListener('touchmove', onInitialPointerMove);\n document.addEventListener('touchstart', onInitialPointerMove);\n document.addEventListener('touchend', onInitialPointerMove);\n }\n\n function removeInitialPointerMoveListeners() {\n document.removeEventListener('mousemove', onInitialPointerMove);\n document.removeEventListener('mousedown', onInitialPointerMove);\n document.removeEventListener('mouseup', onInitialPointerMove);\n document.removeEventListener('pointermove', onInitialPointerMove);\n document.removeEventListener('pointerdown', onInitialPointerMove);\n document.removeEventListener('pointerup', onInitialPointerMove);\n document.removeEventListener('touchmove', onInitialPointerMove);\n document.removeEventListener('touchstart', onInitialPointerMove);\n document.removeEventListener('touchend', onInitialPointerMove);\n }\n\n /**\n * When the polfyill first loads, assume the user is in keyboard modality.\n * If any event is received from a pointing device (e.g. mouse, pointer,\n * touch), turn off keyboard modality.\n * This accounts for situations where focus enters the page from the URL bar.\n * @param {Event} e\n */\n function onInitialPointerMove(e) {\n // Work around a Safari quirk that fires a mousemove on whenever the\n // window blurs, even if you're tabbing out of the page. ¯\\_(ツ)_/¯\n if (e.target.nodeName && e.target.nodeName.toLowerCase() === 'html') {\n return;\n }\n\n hadKeyboardEvent = false;\n removeInitialPointerMoveListeners();\n }\n\n // For some kinds of state, we are interested in changes at the global scope\n // only. For example, global pointer input, global key presses and global\n // visibility change should affect the state at every scope:\n document.addEventListener('keydown', onKeyDown, true);\n document.addEventListener('mousedown', onPointerDown, true);\n document.addEventListener('pointerdown', onPointerDown, true);\n document.addEventListener('touchstart', onPointerDown, true);\n document.addEventListener('visibilitychange', onVisibilityChange, true);\n\n addInitialPointerMoveListeners();\n\n // For focus and blur, we specifically care about state changes in the local\n // scope. This is because focus / blur events that originate from within a\n // shadow root are not re-dispatched from the host element if it was already\n // the active element in its own scope:\n scope.addEventListener('focus', onFocus, true);\n scope.addEventListener('blur', onBlur, true);\n\n // We detect that a node is a ShadowRoot by ensuring that it is a\n // DocumentFragment and also has a host property. This check covers native\n // implementation and polyfill implementation transparently. If we only cared\n // about the native implementation, we could just check if the scope was\n // an instance of a ShadowRoot.\n if (scope.nodeType === Node.DOCUMENT_FRAGMENT_NODE && scope.host) {\n // Since a ShadowRoot is a special kind of DocumentFragment, it does not\n // have a root element to add a class to. So, we add this attribute to the\n // host element instead:\n scope.host.setAttribute('data-js-focus-visible', '');\n } else if (scope.nodeType === Node.DOCUMENT_NODE) {\n document.documentElement.classList.add('js-focus-visible');\n document.documentElement.setAttribute('data-js-focus-visible', '');\n }\n }\n\n // It is important to wrap all references to global window and document in\n // these checks to support server-side rendering use cases\n // @see https://github.com/WICG/focus-visible/issues/199\n if (typeof window !== 'undefined' && typeof document !== 'undefined') {\n // Make the polyfill helper globally available. This can be used as a signal\n // to interested libraries that wish to coordinate with the polyfill for e.g.,\n // applying the polyfill to a shadow root:\n window.applyFocusVisiblePolyfill = applyFocusVisiblePolyfill;\n\n // Notify interested libraries of the polyfill's presence, in case the\n // polyfill was loaded lazily:\n var event;\n\n try {\n event = new CustomEvent('focus-visible-polyfill-ready');\n } catch (error) {\n // IE11 does not support using CustomEvent as a constructor directly:\n event = document.createEvent('CustomEvent');\n event.initCustomEvent('focus-visible-polyfill-ready', false, false, {});\n }\n\n window.dispatchEvent(event);\n }\n\n if (typeof document !== 'undefined') {\n // Apply the polyfill to the global document, so that no JavaScript\n // coordination is required to use the polyfill in the top-level document:\n applyFocusVisiblePolyfill(document);\n }\n\n})));\n","/* global Runtime */\nimport 'focus-visible';\nimport {\n initializeMobileMenu,\n setCurrentPageIconLink,\n initializeMemberMenu,\n} from '../topNavigation/utilities';\nimport { waitOnBaseData } from '../utilities/waitOnBaseData';\n\n// Unique ID applied to modals created using window.Forem.showModal\nconst WINDOW_MODAL_ID = 'window-modal';\n\n// Namespace for functions which need to be accessed in plain JS initializers\nwindow.Forem = {\n preactImport: undefined,\n getPreactImport() {\n if (!this.preactImport) {\n this.preactImport = import('preact');\n }\n return this.preactImport;\n },\n mentionAutoCompleteImports: undefined,\n getMentionAutoCompleteImports() {\n if (!this.mentionAutoCompleteImports) {\n this.mentionAutoCompleteImports = [\n import('@crayons/MentionAutocompleteTextArea'),\n import('@utilities/search'),\n this.getPreactImport(),\n ];\n }\n\n // We're still returning Promises, but if the they have already been imported\n // they will now be fulfilled instead of pending, i.e. a network request is no longer made.\n return Promise.all(this.mentionAutoCompleteImports);\n },\n initializeMentionAutocompleteTextArea: async (originalTextArea) => {\n const parentContainer = originalTextArea.parentElement;\n\n const alreadyInitialized = parentContainer.id === 'combobox-container';\n if (alreadyInitialized) {\n return;\n }\n\n const [{ MentionAutocompleteTextArea }, { fetchSearch }, { render, h }] =\n await window.Forem.getMentionAutoCompleteImports();\n\n render(\n fetchSearch('usernames', { username })}\n />,\n parentContainer,\n originalTextArea,\n );\n },\n modalImports: undefined,\n getModalImports() {\n if (!this.modalImports) {\n this.modalImports = [import('@crayons/Modal'), this.getPreactImport()];\n }\n return Promise.all(this.modalImports);\n },\n showModal: async ({\n title,\n contentSelector,\n overlay = false,\n size = 's',\n onOpen,\n }) => {\n const [{ Modal }, { render, h }] = await window.Forem.getModalImports();\n\n // Guard against two modals being opened at once\n let currentModalContainer = document.getElementById(WINDOW_MODAL_ID);\n if (currentModalContainer) {\n render(null, currentModalContainer);\n } else {\n currentModalContainer = document.createElement('div');\n currentModalContainer.setAttribute('id', WINDOW_MODAL_ID);\n document.body.appendChild(currentModalContainer);\n }\n\n render(\n {\n render(null, currentModalContainer);\n }}\n size={size}\n focusTrapSelector={`#${WINDOW_MODAL_ID}`}\n >\n \n ,\n currentModalContainer,\n );\n\n onOpen?.();\n },\n closeModal: async () => {\n const currentModalContainer = document.getElementById(WINDOW_MODAL_ID);\n if (currentModalContainer) {\n const { render } = await window.Forem.getPreactImport();\n render(null, currentModalContainer);\n }\n },\n};\n\nfunction getPageEntries() {\n return Object.entries({\n 'notifications-index': document.getElementById('notifications-link'),\n 'moderations-index': document.getElementById('moderation-link'),\n 'articles_search-index': document.getElementById('search-link'),\n });\n}\n\nfunction initializeNav() {\n const { currentPage } = document.getElementById('page-content').dataset;\n const menuTriggers = [\n ...document.querySelectorAll(\n '.js-hamburger-trigger, .hamburger a:not(.js-nav-more-trigger)',\n ),\n ];\n const moreMenus = [...document.getElementsByClassName('js-nav-more-trigger')];\n\n setCurrentPageIconLink(currentPage, getPageEntries());\n initializeMobileMenu(menuTriggers, moreMenus);\n}\n\nconst memberMenu = document.getElementById('crayons-header__menu');\nconst menuNavButton = document.getElementById('member-menu-button');\n\nif (memberMenu) {\n initializeMemberMenu(memberMenu, menuNavButton);\n}\n\n// Initialize when asset pipeline (sprockets) initializers have executed\nwaitOnBaseData()\n .then(() => {\n InstantClick.on('change', () => {\n initializeNav();\n });\n\n if (Runtime.currentMedium() === 'ForemWebView') {\n // Dynamic import of the namespace\n import('../mobile/foremMobile.js').then((module) => {\n // Load the namespace\n window.ForemMobile = module.foremMobileNamespace();\n // Run the first session\n window.ForemMobile.userSessionBroadcast();\n });\n }\n })\n .catch((error) => {\n Honeybadger.notify(error);\n });\n\ninitializeNav();\n\nasync function loadCreatorSettings() {\n try {\n const [\n { CreatorSettingsController },\n { LogoUploadController },\n { Application },\n ] = await Promise.all([\n import('@admin-controllers/creator_settings_controller'),\n import('@admin-controllers/logo_upload_controller'),\n import('@hotwired/stimulus'),\n ]);\n\n const application = Application.start();\n application.register('creator-settings', CreatorSettingsController);\n application.register('logo-upload', LogoUploadController);\n } catch (error) {\n Honeybadger.notify(\n `Error loading the creator settings controller: ${error.message}`,\n );\n }\n}\n\nif (document.location.pathname === '/admin/creator_settings/new') {\n loadCreatorSettings();\n}\n"],"sourceRoot":""}