hotwire-native-dev-tools 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"hotwire-native-dev-tools.es.js","sources":["../src/assets/DevToolsStyling.css.js","../src/lib/DiagnosticsChecker.js","../src/utils/settings.js","../src/utils/utils.js","../src/assets/icons.js","../src/components/FloatingBubble.js","../src/components/BottomSheet.js","../src/lib/DevToolsState.js","../src/lib/NativeBridge.js","../src/DevTools.js","../src/index.js"],"sourcesContent":["// Ideally, we would use a dedicated CSS file, but I dind't find a good way to load the styles from a dedicated CSS file.\n// So we just use a function that returns the CSS content as a string.\n// For better syntax highlighting, you can set the language to CSS in the editor for this file.\nexport const cssContent = () => {\n return `\n :host {\n all: initial;\n font-family: system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\" !important;\n --font-size: 16px;\n font-size: var(--font-size) !important;\n }\n\n * {\n box-sizing: border-box;\n }\n\n p, span, h1, h2, h3, h4, h5, h6, div, a, button, input, label {\n font-size: inherit;\n }\n\n\n a {\n color: white;\n }\n\n h1, h2, h3, h4, h5, h6 {\n margin: 0;\n }\n\n button, label, .toggle-label {\n user-select: none;\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n }\n\n input {\n display: block;\n padding: 3px;\n box-sizing: border-box;\n border: 1px solid #ccc;\n border-radius: 4px;\n }\n\n input:focus {\n outline: none;\n }\n\n .btn-icon {\n background-color: transparent;\n border: none;\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.5em;\n height: 100%;\n }\n\n .btn-icon svg {\n width: 1rem;\n height: 1rem;\n fill: white;\n }\n\n /* Dropdown */\n .dropdown-content {\n display: none;\n position: absolute;\n z-index: 1000;\n background: white;\n border: 1px solid #ddd;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n min-width: 200px;\n max-width: 300px;\n opacity: 0;\n transform: scale(0.9);\n transition: opacity 0.2s, transform 0.2s;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .dropdown-content.dropdown-open {\n display: block;\n opacity: 1;\n transform: scale(1);\n pointer-events: auto;\n }\n\n .dropdown-content > * {\n padding: 12px;\n }\n\n .dropdown-content button,\n .dropdown-content label {\n color: black;\n width: 100%;\n margin: 0;\n border: none;\n display: flex;\n align-items: center;\n }\n\n .dropdown-content button:not(:first-child) {\n border-top: 1px solid #cecdcd;\n }\n\n .settings-dropdown {\n right: 0;\n top: 2rem;\n }\n\n /* Floating bubble */\n #floating-bubble {\n display: flex;\n background-color: hsl(0deg 0% 0% / 60%);\n border-radius: 50%;\n touch-action: none;\n user-select: none;\n z-index: 10000000;\n position: fixed;\n top: 10px;\n left: 10px;\n\n /* Remove tap highlight on iOS */\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n\n /* Keep width, height, and border in sync with bubbleSize in FloatingBubble.js */\n width: 4.75rem;\n height: 4.75rem;\n border: 0.3rem solid rgba(136, 136, 136, 0.5);\n }\n\n #floating-bubble svg {\n transform: scale(0.6);\n fill: #b1b1b1;\n }\n\n #floating-bubble .animation-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 1;\n }\n\n #floating-bubble .error-border {\n position: absolute;\n top: -30px;\n left: -30px;\n width: calc(100% + 60px);\n height: calc(100% + 60px);\n border-radius: 50%;\n }\n\n #floating-bubble .error-border circle {\n transform-origin: center;\n transform: rotate(-90deg);\n }\n\n #floating-bubble .error-border circle.animate {\n animation: error-border-progress 0.8s ease-out forwards;\n }\n\n #floating-bubble .animation-container.fade-out {\n animation: fade-out 0.4s ease-out forwards;\n }\n\n /*\n The \"stroke-dasharray\" defines the start of the animation\n The value is calculated by the formula: 2 * Math.PI * radius\n In this case: 2 * Math.PI * 90 = 565\n */\n @keyframes error-border-progress {\n from {\n stroke-dashoffset: 565;\n }\n to {\n stroke-dashoffset: 0;\n }\n }\n\n @keyframes fade-out {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n }\n\n /* Bottom Sheet */\n .bottom-sheet {\n position: fixed;\n bottom: 0;\n left: 0;\n width: 100%;\n max-height: 100%;\n display: flex;\n opacity: 0;\n pointer-events: none;\n align-items: center;\n flex-direction: column;\n justify-content: flex-end;\n transition: 0.1s linear;\n z-index: 10000001;\n }\n\n .bottom-sheet .sheet-overlay.active {\n position: fixed;\n top: 0;\n left: 0;\n z-index: -1;\n width: 100%;\n height: 100%;\n opacity: 0.2;\n background: #000;\n }\n\n .bottom-sheet .content {\n width: 100%;\n height: 40vh;\n position: relative;\n color: white;\n transform: translateY(100%);\n border-radius: 12px 12px 0 0;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.03);\n transition: 0.3s ease;\n overflow-y: hidden;\n }\n\n .bottom-sheet .log-entry {\n border-bottom: 1px solid #6c6c6c;\n white-space: collapse;\n }\n\n .bottom-sheet .log-entry-icon svg {\n width: 1rem;\n fill: white;\n }\n\n .bottom-sheet.show {\n opacity: 1;\n pointer-events: auto;\n }\n\n .bottom-sheet.show .content {\n transform: translateY(0%);\n }\n\n .bottom-sheet.dragging .content {\n transition: none;\n }\n .bottom-sheet.fullscreen .content {\n border-radius: 0;\n overflow-y: hidden;\n }\n\n .bottom-sheet .log-entry-message.warn {\n color: #f39c12;\n }\n\n .bottom-sheet .log-entry-message.error {\n color: #ED4E4C;\n }\n\n .bottom-sheet .tab-action-bars {\n /* Fixes a 1px gap that can appear between .tab-action-bar and .tablist on Android devices */\n margin-top: -1px;\n }\n\n .bottom-sheet .tab-action-bar {\n display: none;\n justify-content: space-between;\n background-color: rgb(49, 54, 63);\n padding: 0.5rem;\n padding-right: 1rem;\n padding-left: 1rem;\n }\n\n .bottom-sheet .tab-action-bar.active {\n display: flex;\n }\n\n .bottom-sheet .tab-action-bar button:active svg {\n fill: #6c6c6c;\n }\n\n .bottom-sheet .btn-clear-tab,\n .bottom-sheet .btn-reload-tab {\n margin-left: auto;\n }\n\n /* Bottom Sheet Tabs */\n .tablist {\n display: flex;\n overflow: hidden;\n background-color: #EEEEEE;\n }\n\n .tablist .tablink {\n color: black;\n background-color: inherit;\n width: 100%;\n border: none;\n outline: none;\n padding: 14px 16px;\n margin: 0;\n font-size: 0.8em;\n }\n\n .tablist .tablink.active {\n background-color: #31363f;\n color: white;\n }\n\n .tablist .tablink-settings {\n background-color: inherit;\n }\n\n .tab-contents {\n height: 100%;\n overflow: scroll;\n /* Fixes a 1px gap that can appear between .tab-action-bar and .tab-contents on Android devices */\n margin-top: -1px;\n }\n\n .outer-tab-content {\n display: none;\n border-top: none;\n height: 100%;\n overflow: scroll;\n background-color: hsl(0deg 0% 0% / 80%);\n backdrop-filter: blur(3px) saturate(100%);\n -webkit-backdrop-filter: blur(3px) saturate(100%);\n padding-bottom: 7em;\n }\n .outer-tab-content.active {\n display: block;\n }\n .inner-tab-content {\n padding: 1rem;\n overflow-x: auto;\n white-space: nowrap;\n }\n .single-tab-content .inner-tab-content {\n white-space: normal;\n }\n\n .tab-empty-content {\n display: flex;\n justify-content: center;\n flex-direction: column;\n align-items: center;\n padding: 1em;\n }\n\n .bottom-sheet .tablink-dropdown {\n background: inherit;\n border: none;\n outline: none;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.5em;\n width: 2rem;\n }\n\n .bottom-sheet .tablink-dropdown svg {\n width: 1rem;\n height: 1rem;\n fill: #121212;\n }\n\n .bottom-sheet .tablink-dropdown:active {\n background-color: #31363f;\n }\n .bottom-sheet .tablink-dropdown:active svg {\n fill: white;\n }\n\n /* Bottom Sheet Stack Visualization */\n .bottom-sheet .viewstack-card {\n border: 1px solid #ddd;\n border-radius: 8px;\n padding: 10px;\n margin: 10px 0;\n background: white;\n color: black;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n overflow: auto;\n }\n\n .bottom-sheet .viewstack-card.current-view {\n border: 2px solid #f1f208;\n }\n\n .bottom-sheet .tab-container {\n background: #EEEEEE;\n }\n\n .bottom-sheet .main-view {\n border-color: #4e6080;\n background: #31363F;\n }\n\n .bottom-sheet .hotwire-view {\n border-color: #6db1b5;\n background: #76ABAE;\n }\n\n .bottom-sheet .child-container {\n margin-left: 30px;\n position: relative;\n }\n\n .bottom-sheet .child-container::before {\n content: \"\";\n position: absolute;\n left: -15px;\n top: 0;\n bottom: 0;\n width: 2px;\n background: #ddd;\n }\n\n .bottom-sheet .view-title {\n display: flex;\n align-items: center;\n gap: 0.5em;\n\n font-weight: bold;\n color: white;\n margin-bottom: 5px;\n }\n\n .bottom-sheet .view-title-details {\n color: #efefef;\n font-size: 0.6em;\n }\n\n .bottom-sheet .tab-container .view-title-details {\n color: #6c6c6c;\n }\n\n .bottom-sheet .view-url {\n color: #000000;\n font-size: 0.9em;\n margin-top: 5px;\n word-break: break-all;\n }\n\n .bottom-sheet .non-identified-view {\n background: #EEEEEE;\n }\n .bottom-sheet .non-identified-view .view-title-details,\n .bottom-sheet .non-identified-view .view-title {\n color: #6c6c6c;\n }\n\n .bottom-sheet .viewstack-card pre {\n font-size: 0.8em;\n }\n\n /* Bottom Sheet Bridge Components */\n .bottom-sheet .bridge-components-collapse-btn {\n background: none;\n border: none;\n color: white;\n width: 100%;\n text-align: left;\n border-bottom: 1px solid #eee;\n padding: 0.5em 0em;\n font-size: 0.9em;\n }\n\n .tab-content-bridge-components {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n padding: 0.5em 0em;\n }\n\n .tab-content-bridge-components .bridge-component {\n position: relative;\n padding-left: 15px;\n }\n\n .tab-content-bridge-components .bridge-component::before {\n content: \"•\";\n color: #eee;\n font-size: 1.5em;\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n }\n .tab-content-bridge-components .bridge-component.connected::before {\n color: #5cff00\n }\n\n /* Collapsibles */\n .collapse-target {\n display: none;\n }\n\n .collapse-target.active {\n display: block;\n }\n\n .collapse:not(.no-chevron):after {\n content: '\\\\25BC';\n font-size: 13px;\n color: #777;\n float: right;\n margin-left: 5px;\n }\n\n .collapse:not(.no-chevron).active:after {\n content: \"\\\\25B2\";\n }\n\n /* Custom checkbox toggles */\n .toggle {\n display: inline-block;\n user-select: none;\n }\n\n .toggle-switch {\n display: inline-block;\n background: #ccc;\n border-radius: 16px;\n width: 29px;\n height: 16px;\n position: relative;\n vertical-align: middle;\n transition: background 0.15s;\n }\n .toggle-switch:before,\n .toggle-switch:after {\n content: \"\";\n }\n .toggle-switch:before {\n display: block;\n background: linear-gradient(to bottom, #fff 0%, #eee 100%);\n border-radius: 50%;\n width: 12px;\n height: 12px;\n position: absolute;\n top: 2px;\n left: 2px;\n transition: left 0.15s;\n }\n .toggle-checkbox:checked + .toggle-switch {\n background: #56c080;\n }\n .toggle-checkbox:checked + .toggle-switch:before {\n left: 15px;\n }\n\n .toggle-checkbox {\n position: absolute;\n visibility: hidden;\n }\n\n .toggle-label {\n position: relative;\n margin-left: 3px;\n top: 2px;\n }\n\n /* Utility classes */\n .d-none {\n display: none;\n }\n\n .text-center {\n text-align: center;\n }\n\n .text-ellipsis {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n }\n\n .break-word {\n word-break: break-word;\n }\n\n .d-flex {\n display: flex;\n }\n\n .flex-column {\n flex-direction: column;\n }\n\n .justify-content-between {\n justify-content: space-between;\n }\n\n .justify-content-end {\n justify-content: flex-end;\n }\n\n .align-items-center {\n align-items: center;\n }\n\n .flex-grow-1 {\n flex-grow: 1;\n }\n\n .border-bottom {\n border-bottom: 1px solid #c5c1c1;\n }\n\n .no-wrap {\n overflow: hidden;\n white-space: nowrap;\n }\n\n .white-space-collapse {\n white-space: collapse;\n }\n\n .overflow-auto {\n overflow: auto;\n }\n\n .mt-1 {\n margin-top: 0.25rem;\n }\n\n .mt-2 {\n margin-top: 0.5rem;\n }\n\n .mt-4 {\n margin-top: 1.5rem;\n }\n\n .ms-1 {\n margin-left: 0.25rem;\n }\n\n .mb-2 {\n margin-bottom: 0.5rem;\n }\n\n .mb-3 {\n margin-bottom: 1rem;\n }\n\n .mb-4 {\n margin-bottom: 1.5rem;\n }\n\n .gap-1 {\n gap: 0.25rem;\n }\n\n .gap-3 {\n gap: 1rem;\n }\n\n .pb-2 {\n padding-bottom: 0.5rem;\n }\n\n .pt-2 {\n padding-top: 0.5rem;\n }\n\n .w-100 {\n width: 100%;\n }\n\n .w-80 {\n width: 80%;\n }\n `\n}\n","export default class DiagnosticsChecker {\n constructor() {\n this.printedWarnings = []\n }\n\n printWarning = (message, once = true, ...extraArgs) => {\n if (once && this.printedWarnings.includes(message)) return\n\n console.warn(`DevTools: ${message}`, ...extraArgs)\n this.printedWarnings.push(message)\n }\n\n checkForWarnings = () => {\n this.#checkForTurboDrive()\n this.#checkForDuplicatedTurboFrames()\n this.#checkTurboPermanentElements()\n }\n\n #checkForTurboDrive = () => {\n if (!window.Turbo) {\n // Since it's possible that the DevTools are loaded before Turbo, we need to wait a bit to check if Turbo is loaded\n setTimeout(() => {\n if (!window.Turbo) {\n this.printWarning(\"Turbo is not detected. Hotwire Native will not work correctly without Turbo\")\n }\n }, 1000)\n } else if (window.Turbo?.session.drive === false) {\n setTimeout(() => {\n if (window.Turbo?.session.drive === false) {\n this.printWarning(\"Turbo Drive is disabled. Hotwire Native will not work correctly without Turbo Drive\")\n }\n }, 1000)\n }\n }\n\n #checkForDuplicatedTurboFrames = () => {\n const turboFramesIds = this.turboFrameIds\n const duplicatedIds = turboFramesIds.filter((id, index) => turboFramesIds.indexOf(id) !== index)\n\n duplicatedIds.forEach((id) => {\n this.printWarning(`Multiple Turbo Frames with the same ID '${id}' detected. This can cause unexpected behavior. Ensure that each Turbo Frame has a unique ID.`)\n })\n }\n\n #checkTurboPermanentElements = () => {\n const turboPermanentElements = document.querySelectorAll(\"[data-turbo-permanent]\")\n if (turboPermanentElements.length === 0) return\n\n turboPermanentElements.forEach((element) => {\n const id = element.id\n if (id === \"\") {\n const message = `Turbo Permanent Element detected without an ID. Turbo Permanent Elements must have a unique ID to work correctly.`\n this.printWarning(message, true, element)\n }\n\n const idIsDuplicated = id && document.querySelectorAll(`#${id}`).length > 1\n if (idIsDuplicated) {\n const message = `Turbo Permanent Element with ID '${id}' doesn't have a unique ID. Turbo Permanent Elements must have a unique ID to work correctly.`\n this.printWarning(message, true, element)\n }\n })\n }\n\n get turboFrameIds() {\n return Array.from(document.querySelectorAll(\"turbo-frame\")).map((turboFrame) => turboFrame.id)\n }\n}\n","export const getSettings = (key) => {\n let settings = JSON.parse(localStorage.getItem(\"hotwire-native-dev-tools\") || \"{}\")\n return settings[key]\n}\n\nexport const saveSettings = (key, value) => {\n let settings = JSON.parse(localStorage.getItem(\"hotwire-native-dev-tools\") || \"{}\")\n settings[key] = value\n\n localStorage.setItem(\"hotwire-native-dev-tools\", JSON.stringify(settings))\n}\n\nexport const resetSettings = () => {\n localStorage.removeItem(\"hotwire-native-dev-tools\")\n}\n\nexport const getConsoleFilterLevels = () => {\n const consoleFilterLevels = getSettings(\"consoleFilterLevels\") || {\n warn: true,\n error: true,\n debug: true,\n info: true,\n log: true,\n }\n\n return consoleFilterLevels\n}\n\nexport const saveConsoleFilterLevels = (key, value) => {\n const consoleFilterLevels = getConsoleFilterLevels()\n consoleFilterLevels[key] = value\n saveSettings(\"consoleFilterLevels\", consoleFilterLevels)\n return consoleFilterLevels\n}\n","export const debounce = (fn, delay) => {\n let timeoutId = null\n\n return (...args) => {\n const callback = () => fn.apply(this, args)\n clearTimeout(timeoutId)\n timeoutId = setTimeout(callback, delay)\n }\n}\n\nconst { userAgent } = window.navigator\nexport const isIosApp = /iOS/.test(userAgent)\nexport const isAndroidApp = /Android/.test(userAgent)\n\nexport const platform = () => {\n if (isIosApp) {\n return \"ios\"\n } else if (isAndroidApp) {\n return \"android\"\n }\n return \"unknown\"\n}\n\nexport const formattedPlatform = () => {\n switch (platform()) {\n case \"android\":\n return \"Android\"\n case \"ios\":\n return \"iOS\"\n default:\n return \"<unknown>\"\n }\n}\n","export const hotwireIcon = `\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 294 320\">\n <g transform=\"matrix(1,0,0,1,-28.38,-15.268)\">\n <g transform=\"matrix(1,0,0,1,-462.157,-144.417)\">\n <path d=\"M783.777,159.685L683.006,262.542L765.948,268.939L622.459,394.208L690.389,396.4L490.537,479.149L569.424,402.053L511.312,400.203L639.22,296.093L533.548,287.812L783.777,159.685Z\"/>\n </g>\n </g>\n </svg>\n`\n\nexport const arrowUp = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM385 215c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-71-71L280 392c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-214.1-71 71c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L239 103c9.4-9.4 24.6-9.4 33.9 0L385 215z\"/>\n </svg>\n`\n\nexport const arrowDown = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM127 297c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l71 71L232 120c0-13.3 10.7-24 24-24s24 10.7 24 24l0 214.1 71-71c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L273 409c-9.4 9.4-24.6 9.4-33.9 0L127 297z\"/>\n </svg>\n`\n\nexport const arrowLeft = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z\"/>\n </svg>\n`\n\nexport const trash = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M135.2 17.7L128 32 32 32C14.3 32 0 46.3 0 64S14.3 96 32 96l384 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-96 0-7.2-14.3C307.4 6.8 296.3 0 284.2 0L163.8 0c-12.1 0-23.2 6.8-28.6 17.7zM416 128L32 128 53.2 467c1.6 25.3 22.6 45 47.9 45l245.8 0c25.3 0 46.3-19.7 47.9-45L416 128z\"/>\n </svg>\n`\n\nexport const rotate = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M142.9 142.9c-17.5 17.5-30.1 38-37.8 59.8c-5.9 16.7-24.2 25.4-40.8 19.5s-25.4-24.2-19.5-40.8C55.6 150.7 73.2 122 97.6 97.6c87.2-87.2 228.3-87.5 315.8-1L455 55c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2l0 128c0 13.3-10.7 24-24 24l-8.4 0c0 0 0 0 0 0L344 224c-9.7 0-18.5-5.8-22.2-14.8s-1.7-19.3 5.2-26.2l41.1-41.1c-62.6-61.5-163.1-61.2-225.3 1zM16 312c0-13.3 10.7-24 24-24l7.6 0 .7 0L168 288c9.7 0 18.5 5.8 22.2 14.8s1.7 19.3-5.2 26.2l-41.1 41.1c62.6 61.5 163.1 61.2 225.3-1c17.5-17.5 30.1-38 37.8-59.8c5.9-16.7 24.2-25.4 40.8-19.5s25.4 24.2 19.5 40.8c-10.8 30.6-28.4 59.3-52.9 83.8c-87.2 87.2-228.3 87.5-315.8 1L57 457c-6.9 6.9-17.2 8.9-26.2 5.2S16 449.7 16 440l0-119.6 0-.7 0-7.6z\"/>\n </svg>\n`\n\nexport const questionMark = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM169.8 165.3c7.9-22.3 29.1-37.3 52.8-37.3l58.3 0c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L280 264.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24l0-13.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1l-58.3 0c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n`\n\nexport const search = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z\"/>\n </svg>\n`\n\nexport const filter = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M3.9 54.9C10.5 40.9 24.5 32 40 32l432 0c15.5 0 29.5 8.9 36.1 22.9s4.6 30.5-5.2 42.5L320 320.9 320 448c0 12.1-6.8 23.2-17.7 28.6s-23.8 4.3-33.5-3l-64-48c-8.1-6-12.8-15.5-12.8-25.6l0-79.1L9 97.3C-.7 85.4-2.8 68.8 3.9 54.9z\"/>\n </svg>\n`\n\nexport const threeDotsVertical = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 128 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z\"/>\n </svg>\n`\n","import { getSettings, saveSettings } from \"../utils/settings\"\nimport { debounce } from \"../utils/utils\"\nimport { hotwireIcon } from \"../assets/icons\"\n\nexport default class FloatingBubble {\n constructor(devTools) {\n this.devTools = devTools\n this.bubbleSize = 4.75 * 16 + 0.3 * 16 // 4.75rem + 0.3rem border\n this.minVisible = this.bubbleSize * 0.5 // Keep 50% of the bubble visible at all times\n this.currentlyDragging = false\n }\n\n render = debounce(() => {\n this.setPosition()\n this.createDragItem()\n this.setTranslate(this.initialX, this.initialY, this.dragItem)\n this.addEventListeners()\n }, 50)\n\n setPosition() {\n this.settingKey = window.innerWidth < window.innerHeight ? \"bubblePosPortrait\" : \"bubblePosLandscape\"\n\n // Get stored position or use default (bottom right corner)\n const defaultPos = { x: window.innerWidth - 100, y: window.innerHeight - 100 }\n const { x: startX, y: startY } = getSettings(this.settingKey) || defaultPos\n\n this.currentX = this.initialX = this.xOffset = startX\n this.currentY = this.initialY = this.yOffset = startY\n }\n\n createDragItem() {\n const existingBubble = this.devTools.shadowRoot?.getElementById(\"floating-bubble\")\n if (existingBubble) {\n this.dragItem = existingBubble\n return\n }\n\n this.dragItem = document.createElement(\"div\")\n this.dragItem.id = \"floating-bubble\"\n this.dragItem.innerHTML = hotwireIcon\n this.devTools.shadowRoot.appendChild(this.dragItem)\n }\n\n addEventListeners() {\n if (this.dragItem.hasEventListeners) return\n this.dragItem.addEventListener(\"click\", this.click.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchstart\", this.dragStart.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchend\", this.dragEnd.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchmove\", this.drag.bind(this), { passive: true })\n this.dragItem.hasEventListeners = true\n }\n\n click(event) {\n if (this.clickCallback) {\n this.clickCallback(event)\n }\n }\n\n animateErrorBorder = debounce(() => {\n if (!this.dragItem) return\n if (getSettings(\"errorAnimationEnabled\") === false) return\n\n let errorBorder = this.dragItem.querySelector(\".error-border\")\n let circleElement = this.dragItem.querySelector(\".error-border circle\")\n\n if (errorBorder) {\n errorBorder.remove()\n }\n\n const animationContainer = document.createElement(\"div\")\n animationContainer.className = \"animation-container\"\n animationContainer.innerHTML = `\n <svg viewBox=\"0 0 180 180\" xmlns=\"http://www.w3.org/2000/svg\" class=\"error-border\">\n <defs>\n <linearGradient id=\"errorGradient\" gradientTransform=\"rotate(45)\">\n <stop offset=\"0%\" stop-color=\"#e4241a\" />\n <stop offset=\"50%\" stop-color=\"#dd1f15\" />\n <stop offset=\"100%\" stop-color=\"#f6160a\" />\n </linearGradient>\n </defs>\n <circle cx=\"90\" cy=\"90\" r=\"90\" fill=\"none\" stroke=\"url(#errorGradient)\" stroke-width=\"21\"\n stroke-dasharray=\"565\" stroke-dashoffset=\"565\" stroke-linecap=\"round\" />\n </svg>\n `\n\n this.dragItem.appendChild(animationContainer)\n circleElement = this.dragItem.querySelector(\".error-border circle\")\n circleElement.classList.add(\"animate\")\n\n setTimeout(() => {\n animationContainer.classList.add(\"fade-out\")\n }, 1300) // Start fade-out after animation completes\n\n setTimeout(() => {\n if (animationContainer && animationContainer.parentNode) {\n animationContainer.remove()\n }\n }, 1800) // Remove after fade-out completes\n }, 100)\n\n onClick(callback) {\n this.clickCallback = callback\n }\n\n dragStart(event) {\n if (!event.target.closest(\"#floating-bubble\")) return\n this.currentlyDragging = true\n\n this.initialX = event.touches[0].clientX - this.xOffset\n this.initialY = event.touches[0].clientY - this.yOffset\n }\n\n dragEnd() {\n this.initialX = this.currentX\n this.initialY = this.currentY\n this.currentlyDragging = false\n\n saveSettings(this.settingKey, { x: this.currentX, y: this.currentY })\n }\n\n drag(event) {\n if (!this.currentlyDragging) return\n\n const touch = event.touches[0]\n const deltaX = touch.clientX - this.initialX\n const deltaY = touch.clientY - this.initialY\n\n // Constrain movement within screen bounds\n this.currentX = Math.max(-this.bubbleSize + this.minVisible, Math.min(deltaX, window.innerWidth - this.minVisible))\n this.currentY = Math.max(-this.bubbleSize + this.minVisible, Math.min(deltaY, window.innerHeight - this.minVisible))\n\n this.xOffset = this.currentX\n this.yOffset = this.currentY\n\n if (!this.animationFrame) {\n this.animationFrame = requestAnimationFrame(() => {\n this.setTranslate(this.currentX, this.currentY, this.dragItem)\n this.animationFrame = null\n })\n }\n }\n\n setTranslate(xPos, yPos, element) {\n element.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`\n }\n}\n","import * as Icons from \"../assets/icons\"\nimport { platform, formattedPlatform } from \"../utils/utils\"\nimport { saveSettings, getSettings, getConsoleFilterLevels, saveConsoleFilterLevels } from \"../utils/settings\"\n\n// WARNING: Be careful when console logging in this file, as it can cause an infinite loop\n// When you need to debug, use the `log` helper function like this:\n// this.log(\"message\")\n// or turn off the console proxy in DevTools.js\n\nexport default class BottomSheet {\n constructor(devTools) {\n this.devTools = devTools\n this.state = devTools.state.state\n this.sheetHeight = parseInt(getSettings(\"bottomSheetHeight\")) || 55\n }\n\n render() {\n this.createBottomSheet()\n this.sheetContent = this.bottomSheet.querySelector(\".content\")\n this.sheetOverlay = this.bottomSheet.querySelector(\".sheet-overlay\")\n this.addEventListeners()\n }\n\n update(newState) {\n this.state = newState\n this.checkNativeFeatures()\n this.renderConsoleLogs()\n this.renderBridgeComponents()\n this.renderBridgeLogs()\n this.renderEvents()\n this.renderNativeStack()\n }\n\n createBottomSheet() {\n const existingBottomSheet = this.devTools.shadowRoot?.querySelector(\".bottom-sheet\")\n if (existingBottomSheet) {\n this.bottomSheet = existingBottomSheet\n return\n }\n\n const activeTab = this.state.activeTab\n const consoleFilterLevels = getConsoleFilterLevels()\n const consoleSearch = this.state.consoleSearch\n this.bottomSheet = document.createElement(\"div\")\n this.bottomSheet.classList.add(\"bottom-sheet\")\n this.bottomSheet.innerHTML = `\n <div class=\"sheet-overlay ${getSettings(\"bottomSheetPinned\") === true ? \"\" : \"active\"}\"></div>\n <div class=\"content\">\n <div class=\"top-part\">\n <div class=\"tablist\">\n <button class=\"tablink ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\" data-tab-id=\"tab-bridge-components\">Bridge</button>\n <button class=\"tablink ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\" data-tab-id=\"tab-console-logs\">Console</button>\n <button class=\"tablink ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\" data-tab-id=\"tab-event-logs\">Events</button>\n <button class=\"tablink ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"} d-none\" data-tab-id=\"tab-native-stack\">Stack</button>\n <div class=\"tablink-settings dropdown d-flex\">\n <button class=\"dropdown-trigger tablink-dropdown\">${Icons.threeDotsVertical}</button>\n <div class=\"dropdown-content settings-dropdown\">\n <button class=\"btn-switch-to-single-tab-sheet\" data-tab-id=\"single-tab-settings\">Settings</button>\n <button class=\"pin-bottom-sheet\">Pin Bottom Sheet</button>\n </div>\n </div>\n </div>\n\n <div class=\"tab-action-bars\">\n <div class=\"tab-action-bar tab-bridge-components ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-clear-tab btn-clear-bridge-logs\">${Icons.trash}</button>\n </div>\n <div class=\"tab-action-bar d-flex flex-column tab-console-logs ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\">\n <div class=\"d-flex\">\n <button class=\"btn-icon btn-search-console\">${Icons.search}</button>\n <div class=\"dropdown\">\n <button class=\"dropdown-trigger btn-icon\">${Icons.filter}</button>\n <div class=\"dropdown-content console-filter-levels\">\n <label><input type=\"checkbox\" ${consoleFilterLevels.warn ? \"checked\" : \"\"} data-console-filter=\"warn\" /> Warnings</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.error ? \"checked\" : \"\"} data-console-filter=\"error\" /> Errors</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.debug ? \"checked\" : \"\"} data-console-filter=\"debug\" /> Debug</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.info ? \"checked\" : \"\"} data-console-filter=\"info\" /> Info</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.log ? \"checked\" : \"\"} data-console-filter=\"log\" /> Logs</label>\n </div>\n </div>\n <button class=\"btn-icon btn-clear-tab btn-clear-console-logs\">${Icons.trash}</button>\n </div>\n\n <div class=\"console-search mt-2 ${consoleSearch ? \"\" : \"d-none\"}\">\n <input type=\"search\" class=\"console-search-input\" value=\"${consoleSearch}\" placeholder=\"Search console logs\" />\n </div>\n </div>\n <div class=\"tab-action-bar tab-event-logs ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-clear-tab btn-clear-events\">${Icons.trash}</button>\n </div>\n <div class=\"tab-action-bar tab-native-stack ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-reload-tab btn-reload-stack\">${Icons.rotate}</button>\n </div>\n </div>\n </div>\n\n <div class=\"tab-contents\">\n <div id=\"tab-bridge-components\" class=\"outer-tab-content ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content\">\n <button class=\"collapse bridge-components-collapse-btn\" type=\"button\" data-collapse-target=\"bridge-components-collapse\">\n Registered Bridge Components: <span class=\"bridge-components-amount\">${this.state.supportedBridgeComponents.length}</span>\n </button>\n <div id=\"bridge-components-collapse\" class=\"collapse-target\">\n <div class=\"d-flex justify-content-between border-bottom\">\n <div class=\"tab-content-bridge-components flex-grow-1\"></div>\n <button class=\"btn-icon btn-help btn-switch-to-single-tab-sheet mt-1\" data-tab-id=\"single-tab-bridge-component-help\">${Icons.questionMark}</button>\n </div>\n </div>\n\n <div class=\"tab-content-bridge-logs\">\n </div>\n </div>\n </div>\n\n <div id=\"tab-console-logs\" class=\"outer-tab-content ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-console-logs\">\n </div>\n </div>\n\n <div id=\"tab-event-logs\" class=\"outer-tab-content ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-event-logs\">\n </div>\n </div>\n\n <div id=\"tab-native-stack\" class=\"outer-tab-content ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-native-stack\">\n </div>\n </div>\n\n <div id=\"single-tab-bridge-component-help\" class=\"single-tab-content outer-tab-content\">\n <div class=\"inner-tab-content\">\n <div class=\"d-flex align-items-center mb-3\">\n <button class=\"btn-icon btn-close-single-mode\">${Icons.arrowLeft}</button>\n <h3 class=\"ms-1\">Bridge Components</h3>\n </div>\n <p>This list shows all the bridge components that the ${formattedPlatform()} app supports. Components that are active on this page are marked with a green dot.</p>\n <h3 class=\"mt-4\">Why is my bridge component not on the list?</h3>\n <p class=\"mt-2\">Bridge components are automatically detected when they are registered in the native code. If your component is not on the list, make sure it is registered correctly.</p>\n ${this.registerBridgeComponentExample()}\n <p class\"mt-1\">For more information, check out the documentation:</p>\n <a href=\"${this.registerBridgeComponentHelpURL()}\">${this.registerBridgeComponentHelpURL()}</a>\n </div>\n </div>\n\n <div id=\"single-tab-settings\" class=\"single-tab-content outer-tab-content\">\n <div class=\"inner-tab-content\">\n <div class=\"d-flex align-items-center mb-3\">\n <button class=\"btn-icon btn-close-single-mode\">${Icons.arrowLeft}</button>\n <h3 class=\"ms-1\">Settings</h3>\n </div>\n <div class=\"mb-3\">\n <label for=\"bottom-sheet-height-setting\"> Bottom Sheet Height</label>\n <input type=\"range\" id=\"bottom-sheet-height-setting\" class=\"w-100\" min=\"10\" max=\"100\" value=\"${this.sheetHeight}\" step=\"1\" list=\"bottom-sheet-height-setting-markers\" />\n <datalist id=\"bottom-sheet-height-setting-markers\">\n <option value=\"55\"></option>\n </datalist>\n </div>\n <div class=\"mb-4\">\n <label for=\"font-size-setting\"> Font Size</label>\n <input type=\"range\" id=\"font-size-setting\" class=\"w-100\" min=\"8\" max=\"24\" value=\"${getSettings(\"fontSize\") || 16}\" step=\"1\" list=\"font-size-setting-markers\" />\n <datalist id=\"font-size-setting-markers\">\n <option value=\"16\"></option>\n </datalist>\n </div>\n <div class=\"mb-3\">\n <label class=\"toggle\">\n <input class=\"toggle-checkbox\" type=\"checkbox\" id=\"console-error-animation-setting\" ${getSettings(\"errorAnimationEnabled\") !== false ? \"checked\" : \"\"} />\n <div class=\"toggle-switch\"></div>\n <span class=\"toggle-label\">Console Error Animation</span>\n </label>\n </div>\n <div class=\"mb-3\">\n <label class=\"toggle\">\n <input class=\"toggle-checkbox\" type=\"checkbox\" id=\"auto-open-setting\" ${getSettings(\"autoOpen\") === true ? \"checked\" : \"\"} />\n <div class=\"toggle-switch\"></div>\n <span class=\"toggle-label\">Auto Open</span>\n </label>\n </div>\n </div>\n </div>\n </div>\n </div>\n `\n this.devTools.shadowRoot.appendChild(this.bottomSheet)\n }\n\n renderConsoleLogs() {\n const container = this.bottomSheet.querySelector(\".tab-content-console-logs\")\n const consoleFilterLevels = getConsoleFilterLevels()\n const consoleSearch = this.state.consoleSearch\n container.innerHTML = this.state.consoleLogs.length\n ? this.state.consoleLogs\n .filter((log) => consoleFilterLevels[log.type])\n .filter((log) => {\n if (!consoleSearch) return true\n return log.message.toLowerCase().includes(consoleSearch.toLowerCase())\n })\n .map((log) => this.consoleLogHTML(log.type, log.message, log.time))\n .join(\"\")\n : `<div class=\"tab-empty-content\"><span>No console logs yet</span></div>`\n }\n\n renderBridgeComponents() {\n const bridgeComponentsAmount = this.state.supportedBridgeComponents.length\n this.bottomSheet.querySelector(\".bridge-components-amount\").textContent = bridgeComponentsAmount\n\n const bridgeComponentIdentifiers = this.bridgeComponentIdentifiers\n const container = this.bottomSheet.querySelector(\".tab-content-bridge-components\")\n container.innerHTML = bridgeComponentsAmount\n ? this.state.supportedBridgeComponents.map((component) => `<div class=\"bridge-component ${bridgeComponentIdentifiers.includes(component) ? \"connected\" : \"\"}\">${component}</div>`).join(\"\")\n : `<div class=\"tab-empty-content d-flex flex-column text-center\"><span>${\"No bridge components found\"}</span></div>`\n }\n\n renderBridgeLogs() {\n const container = this.bottomSheet.querySelector(\".tab-content-bridge-logs\")\n container.innerHTML = this.state.bridgeLogs.length\n ? this.state.bridgeLogs.map((log) => this.bridgeLogHTML(log.direction, log.componentName, log.eventName, log.eventArgs, log.time)).join(\"\")\n : `<div class=\"tab-empty-content d-flex flex-column text-center\"><span>${\n this.state.bridgeIsConnected ? \"No bridge communication yet\" : \"Bridge is not connected <br><small>(Neither window.HotwireNative nor window.Strada is defined)</small>\"\n }</span></div>`\n }\n\n renderEvents() {\n const container = this.bottomSheet.querySelector(\".tab-content-event-logs\")\n container.innerHTML = this.state.eventLogs.length\n ? this.state.eventLogs.map((event) => this.eventMessageHTML(event.eventName, event.time)).join(\"\")\n : `<div class=\"tab-empty-content\"><span>No events captured yet</span></div>`\n }\n\n renderNativeStack() {\n const container = this.bottomSheet.querySelector(\".tab-content-native-stack\")\n container.innerHTML =\n `<div class=\"native-stack-wrapper\">` +\n (this.state.nativeStack.length ? this.state.nativeStack.map((view) => this.nativeViewStackHTML(view)).join(\"\") : `<div class=\"tab-empty-content\"><span>No native stack captured yet</span></div>`) +\n `</div>`\n }\n\n bridgeLogHTML(direction, componentName, eventName, eventArgs, time) {\n return `\n <div class=\"log-entry d-flex gap-3 pt-2 pb-2\">\n <div class=\"log-entry-icon d-flex justify-content-center align-items-center\">\n ${direction === \"send\" ? Icons.arrowDown : Icons.arrowUp}\n </div>\n <div class=\"w-100 overflow-auto\">\n <div class=\"d-flex justify-content-between\">\n <strong class=\"w-80 break-word\">${componentName}#${eventName}</strong>\n <small>${time}</small>\n </div>\n <div class=\"overflow-auto\">\n ${Object.entries(eventArgs)\n .map(([key, value]) => {\n const formattedValue = typeof value === \"object\" && value !== null ? JSON.stringify(value) : value\n return `<div class=\"white-space-collapse\">${key}: ${formattedValue}</div>`\n })\n .join(\"\")}\n </div>\n </div>\n </div>\n `\n }\n\n consoleLogHTML(type, message, time) {\n return `\n <div class=\"log-entry pt-2 pb-2\">\n <div class=\"w-100\">\n <div class=\"d-flex justify-content-end\">\n <small>${time}</small>\n </div>\n <div class=\"log-entry-message ${type}\">\n ${message}\n </div>\n </div>\n </div>\n `\n }\n\n eventMessageHTML(message, time) {\n return `\n <div class=\"log-entry pt-2 pb-2\">\n <div class=\"w-100\">\n <div class=\"d-flex justify-content-end\">\n <small>${time}</small>\n </div>\n <div class=\"log-entry-message\">\n ${message}\n </div>\n </div>\n </div>\n `\n }\n\n nativeViewStackHTML(view) {\n const isMainView = [\"UINavigationController\", \"NavigatorHost\"].includes(view.type)\n const isTabBar = view.type === \"UITabBarController\"\n const isHotwireView = [\"VisitableViewController\", \"HotwireWebFragment\", \"BackStackEntry\"].includes(view.type)\n const activeClass = view.url === this.currentUrl ? \"current-view\" : \"\"\n const wrapperClass = `viewstack-card ${activeClass} ${isMainView ? \"main-view\" : isHotwireView ? \"hotwire-view\" : isTabBar ? \"tab-container\" : \"non-identified-view\"}`\n const uniqueViewId = \"viewstack-\" + Math.random().toString(16).slice(2)\n\n const urlPath = view.url\n ? `<div class=\"view-url\">\n ${(() => {\n try {\n return new URL(view.url).pathname\n } catch (error) {\n return view.url\n }\n })()}\n </div>`\n : \"\"\n\n const pathConfigurationPropertiesJson = (() => {\n try {\n const props = view.pathConfigurationProperties\n return JSON.stringify(typeof props === \"string\" ? JSON.parse(props) : props, null, 2)\n } catch {\n return view.pathConfigurationProperties\n }\n })()\n const pathConfigurationProperties = pathConfigurationPropertiesJson ? `<pre class=\"view-path-configuration\">${pathConfigurationPropertiesJson}</pre>` : \"\"\n\n const childrenHTML = view.children?.length\n ? `<div class=\"child-container\">\n ${view.children.map((child) => this.nativeViewStackHTML(child)).join(\"\")}\n </div>`\n : \"\"\n\n return `\n <div>\n <div class=\"${wrapperClass} collapse no-chevron\" data-collapse-target=\"path-configuration-properties-${uniqueViewId}\">\n <div>\n <div class=\"view-title\">\n ${view.title == \"null\" ? \"\" : view.title}\n <div class=\"view-title-details\">${view.type}</div>\n </div>\n ${urlPath}\n </div>\n <div id=\"path-configuration-properties-${uniqueViewId}\" class=\"collapse-target\">\n ${pathConfigurationProperties}\n </div>\n </div>\n ${childrenHTML}\n </div>\n `\n }\n\n switchToSingleTabSheet(singleTabId) {\n // Hide the top part and all tabs\n this.sheetContent.querySelector(\".top-part\").classList.add(\"d-none\")\n this.devTools.shadowRoot.querySelectorAll(\".outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the single mode content\n this.devTools.shadowRoot.getElementById(singleTabId).classList.add(\"active\")\n }\n\n switchToMultiTabSheet() {\n this.sheetContent.querySelector(\".top-part\").classList.remove(\"d-none\")\n this.devTools.shadowRoot.querySelectorAll(\".outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the previous active tab\n this.devTools.shadowRoot.querySelectorAll(\".tablink, .outer-tab-content\").forEach((tab) => {\n if (tab.id == this.state.activeTab) {\n tab.classList.add(\"active\")\n }\n })\n }\n\n registerBridgeComponentExample() {\n switch (platform()) {\n case \"android\":\n return `\n<pre class=\"overflow-auto\">\n Hotwire.registerBridgeComponents(\n BridgeComponentFactory(\"my-component\", ::MyComponent)\n )\n</pre>\n`\n case \"ios\":\n return `\n<pre class=\"overflow-auto\">\n Hotwire.registerBridgeComponents([\n MyComponent.self\n ])\n</pre>`\n default:\n return \"\"\n }\n }\n\n registerBridgeComponentHelpURL() {\n switch (platform()) {\n case \"android\":\n return \"https://native.hotwired.dev/android/bridge-components\"\n case \"ios\":\n return \"https://native.hotwired.dev/ios/bridge-components\"\n default:\n return \"https://native.hotwired.dev\"\n }\n }\n\n checkNativeFeatures() {\n if (this.state.supportsNativeStackView) {\n this.bottomSheet.querySelector(\".tablink[data-tab-id='tab-native-stack']\").classList.remove(\"d-none\")\n }\n }\n\n addEventListeners() {\n if (this.bottomSheet.hasEventListeners) return\n\n // Click outside to close\n this.sheetOverlay.addEventListener(\"click\", () => {\n this.hideBottomSheet()\n this.switchToMultiTabSheet()\n })\n\n // Tab Click\n this.bottomSheet.querySelector(\".tablist\").addEventListener(\"click\", (event) => this.handleTabClick(event))\n\n // Action Buttons\n this.bottomSheet.querySelector(\".btn-clear-console-logs\").addEventListener(\"click\", () => {\n this.devTools.state.clearConsoleLogs()\n this.renderConsoleLogs()\n })\n this.bottomSheet.querySelector(\".btn-clear-bridge-logs\").addEventListener(\"click\", () => {\n this.devTools.state.clearBridgeLogs()\n this.renderBridgeLogs()\n })\n this.bottomSheet.querySelector(\".btn-clear-events\").addEventListener(\"click\", () => {\n this.devTools.state.clearEventLogs()\n this.renderEvents()\n })\n this.bottomSheet.querySelector(\".btn-reload-stack\").addEventListener(\"click\", () => {\n this.bottomSheet.querySelector(\".native-stack-wrapper\").style.opacity = 0.5\n this.devTools.refetchNativeStack()\n })\n\n // Switch to Single Tab Buttons\n this.bottomSheet.querySelectorAll(\".btn-switch-to-single-tab-sheet\").forEach((button) => {\n button.addEventListener(\"click\", (event) => {\n const singleTabId = event.target.closest(\"[data-tab-id]\").dataset.tabId\n if (!singleTabId) return\n this.switchToSingleTabSheet(singleTabId)\n })\n })\n\n // Close Single Tab Buttons\n this.bottomSheet.querySelectorAll(\".btn-close-single-mode\").forEach((button) => {\n button.addEventListener(\"click\", () => {\n this.switchToMultiTabSheet()\n })\n })\n\n // Dragging\n this.bottomSheet.querySelector(\".top-part\").addEventListener(\"touchstart\", this.dragStart.bind(this), { passive: true })\n this.bottomSheet.addEventListener(\"touchmove\", this.dragging.bind(this), { passive: true })\n this.bottomSheet.addEventListener(\"touchend\", this.dragStop.bind(this), { passive: true })\n\n // Filters\n this.bottomSheet.querySelector(\".console-filter-levels\").addEventListener(\"click\", ({ target }) => {\n const checkbox = target.closest(\"input[type='checkbox']\")\n if (!checkbox) return\n\n const filterType = checkbox.dataset.consoleFilter\n const isActive = checkbox.checked\n\n saveConsoleFilterLevels(filterType, isActive)\n this.renderConsoleLogs()\n })\n\n this.bottomSheet.querySelector(\".btn-search-console\").addEventListener(\"click\", () => {\n const searchInput = this.bottomSheet.querySelector(\".console-search\")\n searchInput.classList.toggle(\"d-none\")\n searchInput.querySelector(\"input\").focus()\n })\n\n this.bottomSheet.querySelector(\".console-search-input\").addEventListener(\"input\", (event) => {\n this.devTools.state.setConsoleSearchValue(event.target.value.toLowerCase())\n this.renderConsoleLogs()\n })\n\n // Settings\n this.bottomSheet.querySelector(\"#bottom-sheet-height-setting\").addEventListener(\"change\", (event) => {\n const value = event.target.value\n this.sheetHeight = parseInt(value)\n saveSettings(\"bottomSheetHeight\", value)\n this.updateSheetHeight(value)\n })\n\n this.bottomSheet.querySelector(\"#console-error-animation-setting\").addEventListener(\"change\", (event) => {\n saveSettings(\"errorAnimationEnabled\", event.target.checked)\n })\n\n this.bottomSheet.querySelector(\"#font-size-setting\").addEventListener(\"change\", (event) => {\n let value = event.target.value\n value = Math.max(8, Math.min(24, value))\n saveSettings(\"fontSize\", value)\n this.devTools.setCSSProperty(\"--font-size\", `${value}px`)\n })\n\n this.bottomSheet.querySelector(\"#auto-open-setting\").addEventListener(\"change\", (event) => {\n saveSettings(\"autoOpen\", event.target.checked)\n })\n\n this.bottomSheet.querySelector(\".pin-bottom-sheet\").addEventListener(\"click\", () => {\n const isPinned = getSettings(\"bottomSheetPinned\") === true\n saveSettings(\"bottomSheetPinned\", !isPinned)\n this.sheetOverlay.classList.toggle(\"active\")\n this.bottomSheet.querySelector(\".settings-dropdown\").classList.remove(\"dropdown-open\")\n })\n\n this.bottomSheet.addEventListener(\"click\", (event) => {\n // Handle collapsible elements\n const collapsible = event.target.closest(\".collapse\")\n if (collapsible && this.bottomSheet.contains(collapsible)) {\n const targetId = collapsible.getAttribute(\"data-collapse-target\")\n const targetElement = this.bottomSheet.querySelector(`#${targetId}`)\n if (targetElement) {\n const isActive = collapsible.classList.toggle(\"active\")\n targetElement.classList.toggle(\"active\", isActive)\n }\n return\n }\n\n // Handle dropdown triggers\n const trigger = event.target.closest(\".dropdown-trigger\")\n if (trigger) {\n event.preventDefault()\n this.toggleDropdown(trigger)\n return\n }\n\n // Close dropdowns when clicking outside\n const openDropdowns = this.bottomSheet.querySelectorAll(\".dropdown-content.dropdown-open\")\n openDropdowns.forEach((dropdown) => {\n const dropdownContainer = dropdown.closest(\".dropdown\")\n if (!dropdownContainer.contains(event.target)) {\n dropdown.classList.remove(\"dropdown-open\")\n }\n })\n })\n\n this.bottomSheet.hasEventListeners = true\n }\n\n toggleDropdown(triggerElement) {\n const dropdownContent = triggerElement.nextElementSibling || triggerElement.closest(\".dropdown\").querySelector(\".dropdown-content\")\n // Close other dropdowns first\n this.bottomSheet.querySelectorAll(\".dropdown-content.dropdown-open\").forEach((el) => {\n if (el !== dropdownContent) {\n el.classList.remove(\"dropdown-open\")\n }\n })\n dropdownContent.classList.toggle(\"dropdown-open\")\n }\n\n handleTabClick = (event) => {\n const clickedTab = event.target.closest(\".tablink\")\n if (!clickedTab) return\n\n const tabId = clickedTab.dataset.tabId\n this.devTools.state.setActiveTab(tabId)\n this.updateTabView(tabId)\n }\n\n updateTabView(tabId) {\n // Hide all Tabs\n this.devTools.shadowRoot.querySelectorAll(\".tablink, .outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Hide all Action Bars\n this.devTools.shadowRoot.querySelectorAll(\".tab-action-bar\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the clicked tab\n this.devTools.shadowRoot.querySelector(`[data-tab-id=\"${tabId}\"]`).classList.add(\"active\")\n this.devTools.shadowRoot.getElementById(tabId).classList.add(\"active\")\n\n // Show the action bar for the clicked tab\n this.devTools.shadowRoot.querySelector(`.tab-action-bar.${tabId}`).classList.add(\"active\")\n }\n\n showBottomSheet() {\n if (this.bottomSheet.classList.contains(\"show\")) return\n this.bottomSheet.classList.add(\"show\")\n this.originalOverflow = document.body.style.overflow\n document.body.style.overflow = \"hidden\"\n this.updateSheetHeight(this.sheetHeight)\n }\n\n updateSheetHeight(height) {\n this.sheetContent.style.height = `${height}vh`\n }\n\n hideBottomSheet() {\n this.bottomSheet.classList.remove(\"show\")\n document.body.style.overflow = this.originalOverflow\n }\n\n updateSheetHeight(height) {\n this.sheetContent.style.height = `${height}vh`\n this.bottomSheet.classList.toggle(\"fullscreen\", height === 100)\n }\n\n dragStart(event) {\n this.isDragging = true\n this.startY = event.pageY || event.touches?.[0].pageY\n this.startHeight = parseInt(this.sheetContent.style.height)\n this.bottomSheet.classList.add(\"dragging\")\n }\n\n dragging(event) {\n if (!this.isDragging) return\n const delta = this.startY - (event.pageY || event.touches?.[0].pageY)\n const newHeight = this.startHeight + (delta / window.innerHeight) * 100\n this.updateSheetHeight(newHeight)\n }\n\n dragStop() {\n this.isDragging = false\n this.bottomSheet.classList.remove(\"dragging\")\n const draggingThreshold = 10 // Defines how much the user needs to drag to trigger the hide/show\n const currentHeight = parseInt(this.sheetContent.style.height)\n\n const minThreshold = Math.max(0, this.sheetHeight - draggingThreshold)\n const maxThreshold = Math.min(100, this.sheetHeight + draggingThreshold)\n\n if (currentHeight < minThreshold) {\n this.hideBottomSheet()\n } else if (currentHeight > maxThreshold) {\n this.updateSheetHeight(100)\n } else {\n this.updateSheetHeight(this.sheetHeight)\n }\n }\n\n // Helper function to log messages, without causing a rerender of the bottom sheet\n // (Messages with a `HotwireDevTools` prefix will not be logged in the bottom sheet)\n log(message) {\n console.log(`HotwireDevTools: ${message}`)\n }\n\n // Get all the `static component = \"...\"` from the bridge components\n get bridgeComponentIdentifiers() {\n return window.Stimulus?.controllers.map((controller) => controller.component).filter((component) => component !== undefined) || []\n }\n\n get currentUrl() {\n return window.location.href\n }\n}\n","import { getSettings, saveSettings } from \"../utils/settings\"\n\nexport default class DevToolsState {\n constructor() {\n this.state = {\n consoleLogs: [],\n bridgeLogs: [],\n eventLogs: [],\n nativeStack: [],\n supportedBridgeComponents: [],\n bridgeIsConnected: false,\n supportsNativeStackView: false,\n consoleSearch: \"\",\n activeTab: getSettings(\"activeTab\") || \"tab-bridge-components\",\n }\n this.listeners = []\n }\n\n subscribe(listener) {\n this.listeners.push(listener)\n }\n\n notify() {\n this.listeners.forEach((listener) => listener(this.state))\n }\n\n addConsoleLog(type, message) {\n const log = { type, message, time: this.currentTime }\n this.state.consoleLogs.push(log)\n this.notify()\n }\n\n addBridgeLog(direction, componentName, eventName, eventArgs) {\n const log = { direction, componentName, eventName, eventArgs, time: this.currentTime }\n this.state.bridgeLogs.push(log)\n this.notify()\n }\n\n addEventLog(eventName) {\n const event = { eventName, time: this.currentTime }\n this.state.eventLogs.push(event)\n this.notify()\n }\n\n setNativeStack(stack) {\n this.state.nativeStack = stack\n this.notify()\n }\n\n setSupportsNativeStack(supports) {\n this.state.supportsNativeStackView = supports\n this.notify()\n }\n\n setBridgeIsConnected(isConnected) {\n this.state.bridgeIsConnected = isConnected\n this.notify()\n }\n\n setSupportedBridgeComponents(components) {\n this.state.supportedBridgeComponents = components\n this.notify()\n }\n\n clearConsoleLogs() {\n this.state.consoleLogs = []\n this.notify()\n }\n\n clearBridgeLogs() {\n this.state.bridgeLogs = []\n this.notify()\n }\n\n clearEventLogs() {\n this.state.eventLogs = []\n this.notify()\n }\n\n setActiveTab(tab) {\n this.state.activeTab = tab\n saveSettings(\"activeTab\", tab)\n }\n\n setConsoleSearchValue(value) {\n this.state.consoleSearch = value\n }\n\n get currentTime() {\n return new Date().toLocaleTimeString()\n }\n}\n","/*\nSimilar to the `BridgeComponent` class from the Hotwire Native Bridge,\nbut without requiring a bridge component HTML element or Stimulus controller.\n\nOriginally from: 37signals LLC\nhttps://github.com/hotwired/hotwire-native-bridge\n*/\nexport default class NativeBridge {\n bridgeIsConnected() {\n return !!(window.HotwireNative?.web || window.Strada?.web)\n }\n\n // Send a message to the native side\n send(event, data = {}, callback = null) {\n if (!this.bridgeIsConnected()) {\n return Promise.reject(\"Bridge is not connected\")\n }\n\n const messageData = {\n ...data,\n metadata: {\n url: window.location.href,\n },\n }\n\n return this.bridge.send({\n component: \"dev-tools\",\n event,\n data: messageData,\n callback,\n })\n }\n\n isComponentSupported(component) {\n if (!this.bridgeIsConnected()) {\n return false\n }\n return this.bridge.supportsComponent(component)\n }\n\n getSupportedComponents() {\n return document.documentElement.dataset.bridgeComponents?.split(\" \") || []\n }\n\n get bridge() {\n return window.HotwireNative?.web || window.Strada?.web\n }\n}\n","import { cssContent } from \"./assets/DevToolsStyling.css\"\nimport DiagnosticsChecker from \"./lib/DiagnosticsChecker\"\nimport FloatingBubble from \"./components/FloatingBubble\"\nimport BottomSheet from \"./components/BottomSheet\"\nimport DevToolsState from \"./lib/DevToolsState\"\nimport NativeBridge from \"./lib/NativeBridge\"\nimport { resetSettings } from \"./utils/settings\"\nimport { debounce } from \"./utils/utils\"\nimport { getSettings } from \"./utils/settings\"\n\nexport default class DevTools {\n constructor(options = {}) {\n this.options = {\n enabled: true,\n reset: false,\n ...options,\n }\n if (!this.options.enabled) return\n if (this.options.reset) resetSettings()\n\n this.state = new DevToolsState()\n this.bubble = new FloatingBubble(this)\n this.bottomSheet = new BottomSheet(this)\n this.nativeBridge = new NativeBridge(this)\n this.diagnosticsChecker = new DiagnosticsChecker()\n this.state.subscribe(this.update.bind(this))\n this.listenForTurboEvents()\n }\n\n // Setup gets called initially and on every turbo:load event, eg. when navigating to a new page\n setup() {\n if (!this.options.enabled) return\n this.setupShadowRoot()\n this.bubble.render()\n this.bottomSheet.render()\n\n // Add Console Proxy\n if (!this.originalConsole) {\n this.originalConsole = window.console\n this.addConsoleProxy()\n }\n\n // Add Bridge Proxy and call the native DevTools bridge component\n if (this.originalBridge) {\n // Bridge Proxy is already added\n this.callNativeBridgeComponent()\n } else if (window.HotwireNative || window.Strada) {\n // Bridge exists -> Add Bridge Proxy\n this.nativeBridgeGotConnected()\n } else {\n // Bridge does not exist yet -> Listen for the event\n document.addEventListener(\"web-bridge:ready\", () => {\n this.nativeBridgeGotConnected()\n })\n }\n\n // Add event listeners to the window\n this.addEventListeners()\n\n // Check for warnings\n this.diagnosticsChecker.checkForWarnings()\n\n this.bubble.onClick(() => {\n this.bottomSheet.showBottomSheet()\n this.nativeBridge.send(\"vibrate\")\n })\n\n if (getSettings(\"autoOpen\") === true) {\n this.bottomSheet.showBottomSheet()\n }\n }\n\n nativeBridgeGotConnected() {\n if (this.originalBridge) return\n\n this.originalBridge = window.HotwireNative?.web || window.Strada?.web\n this.addBridgeProxy()\n this.state.setBridgeIsConnected(true)\n this.callNativeBridgeComponent()\n this.updateSupportedBridgeComponents()\n this.startBridgeComponentObserver()\n }\n\n callNativeBridgeComponent() {\n if (this.nativeBridge.bridgeIsConnected()) {\n this.nativeBridge.send(\"connect\", {}, (message) => {\n // If this callback gets executed, it means the native counterpart\n // of the dev tools are installed and running.\n this.fetchNativeStack()\n })\n }\n }\n\n update = debounce((newState) => {\n this.bottomSheet.update(newState)\n }, 200)\n\n setupShadowRoot() {\n if (this.shadowContainer.shadowRoot) {\n this.shadowRoot = this.shadowContainer.shadowRoot\n this.injectCSSToShadowRoot()\n return\n }\n this.shadowRoot = this.shadowContainer.attachShadow({ mode: \"open\" })\n this.setCSSProperty(\"--font-size\", `${getSettings(\"fontSize\") || 16}px`)\n this.injectCSSToShadowRoot()\n }\n\n addBridgeProxy() {\n const createProxyHandler = () => ({\n get: (target, prop, receiver) => {\n const originalValue = Reflect.get(target, prop, receiver)\n\n // We are only interested in the send and receive methods\n if (typeof originalValue === \"function\" && (prop === \"send\" || prop === \"receive\")) {\n return (...args) => {\n this.interceptedBridgeMessage(prop, args)\n return originalValue.apply(target, args)\n }\n }\n\n // Forward all the other calls to the original bridge\n return typeof originalValue === \"function\" ? (...args) => originalValue.apply(target, args) : originalValue\n },\n })\n\n if (window.Strada) {\n window.Strada.web = new Proxy(this.originalBridge, createProxyHandler())\n }\n if (window.HotwireNative) {\n window.HotwireNative.web = new Proxy(this.originalBridge, createProxyHandler())\n }\n }\n\n addConsoleProxy() {\n window.console = new Proxy(this.originalConsole, {\n get: (target, prop, receiver) => {\n const originalValue = Reflect.get(target, prop, receiver)\n return (...args) => {\n this.interceptedConsoleMessage(prop, args)\n return originalValue?.apply(target, args)\n }\n },\n })\n }\n\n interceptedBridgeMessage(direction, args) {\n args.forEach((arg) => {\n const componentName = arg.component\n const eventName = arg.event\n const { metadata, ...eventArgs } = arg.data // Remove metadata from the args\n\n if (componentName !== \"dev-tools\") {\n // We don't want to log our own messages\n this.state.addBridgeLog(direction, componentName, eventName, eventArgs)\n }\n })\n }\n\n interceptedConsoleMessage(type, args) {\n const message = args\n .map((arg) => {\n if (arg instanceof Element) {\n const attrs = Array.from(arg.attributes)\n .map((attr) => `${attr.name}=\"${attr.value}\"`)\n .join(\" \")\n\n return `&lt;${arg.tagName.toLowerCase()}${attrs ? \" \" + attrs : \"\"}&gt;&lt;/${arg.tagName.toLowerCase()}&gt;`\n }\n if (typeof arg === \"object\") {\n try {\n return `<pre>${JSON.stringify(arg, null, 2)}</pre>`\n } catch {\n return `<pre>${arg}</pre>`\n }\n }\n // Escape HTML in string values\n const stringValue = arg.toString()\n return stringValue.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\").replace(/'/g, \"&#039;\")\n })\n .join(\" \")\n\n // Ignore messages from the dev tools itself\n // Otherwise we could end up in an infinite loop\n if (message.includes(\"hotwire-native-dev-tools\") || message.includes(\"HotwireDevTools\")) return\n\n this.state.addConsoleLog(type, message)\n if (type === \"error\") {\n this.bubble.animateErrorBorder()\n }\n }\n\n // Fetch the current stack from the native side\n // The debounce on this function is intentionally high,\n // to ensure the native side has enough time to set the ViewController / Fragment titles.\n // With a lower debounce, the view controller / fragment title would often be empty.\n fetchNativeStack = debounce(() => {\n this.nativeBridge.send(\"currentStackInfo\", {}, (message) => {\n this.state.setSupportsNativeStack(true)\n this.state.setNativeStack(message.data.stack)\n })\n }, 1000)\n\n refetchNativeStack() {\n this.nativeBridge.send(\"currentStackInfo\", {}, (message) => {\n this.state.setNativeStack(message.data.stack)\n })\n }\n\n injectCSSToShadowRoot = async () => {\n if (this.shadowRoot.querySelector(\"style\")) return\n\n const style = document.createElement(\"style\")\n style.textContent = cssContent()\n this.shadowRoot.appendChild(style)\n }\n\n addEventListeners() {\n if (this.hasEventListeners) return\n\n // Capture uncaught errors and unhandled promise rejections\n window.addEventListener(\"error\", (event) => {\n const { message, filename, lineno, colno } = event\n const formattedMessage = `${message} at ${filename}:${lineno}:${colno}`\n this.interceptedConsoleMessage(\"error\", [formattedMessage])\n })\n window.addEventListener(\"unhandledrejection\", (event) => {\n this.interceptedConsoleMessage(\"error\", [event.reason?.message])\n })\n\n // Observe screen size or orientation changes to reposition the bubble\n window.addEventListener(\n \"resize\",\n () => {\n this.bubble.render()\n },\n { passive: true }\n )\n\n this.hasEventListeners = true\n }\n\n listenForTurboEvents() {\n if (this.eventsRegistered) return\n\n const turboEvents = [\n \"turbo:click\",\n \"turbo:before-visit\",\n \"turbo:visit\",\n \"turbo:before-cache\",\n \"turbo:before-render\",\n \"turbo:render\",\n \"turbo:load\",\n \"turbo:morph\",\n \"turbo:before-morph-element\",\n \"turbo:before-morph-attribute\",\n \"turbo:morph-element\",\n \"turbo:submit-start\",\n \"turbo:submit-end\",\n \"turbo:before-frame-render\",\n \"turbo:frame-render\",\n \"turbo:frame-load\",\n \"turbo:frame-missing\",\n \"turbo:before-stream-render\",\n \"turbo:before-fetch-request\",\n \"turbo:before-fetch-response\",\n \"turbo:before-prefetch\",\n \"turbo:fetch-request-error\",\n ]\n\n turboEvents.forEach((eventName) => {\n window.addEventListener(\n eventName,\n (event) => {\n this.state.addEventLog(eventName)\n },\n { passive: true }\n )\n })\n\n this.eventsRegistered = true\n }\n\n startBridgeComponentObserver() {\n if (this.bridgeComponentObserver) return\n\n this.bridgeComponentObserver = new MutationObserver((mutationsList) => {\n for (const mutation of mutationsList) {\n if (mutation.type === \"attributes\" && mutation.attributeName === \"data-bridge-components\") {\n this.updateSupportedBridgeComponents()\n }\n }\n })\n\n this.bridgeComponentObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-bridge-components\"],\n })\n }\n\n updateSupportedBridgeComponents() {\n this.state.setSupportedBridgeComponents(this.nativeBridge.getSupportedComponents().sort())\n }\n\n getCSSProperty(propertyName) {\n const rootStyles = getComputedStyle(this.shadowContainer)\n return rootStyles.getPropertyValue(propertyName).trim()\n }\n\n setCSSProperty(propertyName, value) {\n this.shadowContainer.style.setProperty(propertyName, value)\n }\n\n get shadowContainer() {\n const existingShadowContainer = document.getElementById(\"hotwire-native-dev-tools-shadow-container\")\n if (existingShadowContainer) {\n return existingShadowContainer\n }\n const shadowContainer = document.createElement(\"div\")\n shadowContainer.id = \"hotwire-native-dev-tools-shadow-container\"\n shadowContainer.setAttribute(\"data-native-prevent-pull-to-refresh\", \"\")\n document.body.appendChild(shadowContainer)\n return shadowContainer\n }\n\n get currentTime() {\n return new Date().toLocaleTimeString()\n }\n}\n","import DevTools from \"./DevTools\"\n\nconst setupDevTools = (options = {}) => {\n const devTools = new DevTools(options)\n if (!devTools.options.enabled) return\n\n devTools.setup()\n\n document.addEventListener(\n \"turbo:load\",\n () => {\n devTools.setup()\n },\n { passive: true }\n )\n}\n\nexport { setupDevTools }\n"],"names":["cssContent","_checkForTurboDrive","_checkForDuplicatedTurboFrames","_checkTurboPermanentElements","DiagnosticsChecker","__publicField","message","once","extraArgs","__privateGet","__privateAdd","_a","turboFramesIds","id","index","turboPermanentElements","element","turboFrame","getSettings","key","saveSettings","value","settings","resetSettings","getConsoleFilterLevels","saveConsoleFilterLevels","consoleFilterLevels","debounce","fn","delay","timeoutId","args","callback","this","userAgent","isIosApp","isAndroidApp","platform","formattedPlatform","hotwireIcon","arrowUp","arrowDown","arrowLeft","trash","rotate","questionMark","search","filter","threeDotsVertical","FloatingBubble","devTools","errorBorder","circleElement","animationContainer","defaultPos","startX","startY","existingBubble","event","touch","deltaX","deltaY","xPos","yPos","BottomSheet","clickedTab","tabId","newState","existingBottomSheet","activeTab","consoleSearch","Icons.threeDotsVertical","Icons.trash","Icons.search","Icons.filter","Icons.rotate","Icons.questionMark","Icons.arrowLeft","container","log","bridgeComponentsAmount","bridgeComponentIdentifiers","component","view","direction","componentName","eventName","eventArgs","time","Icons.arrowDown","Icons.arrowUp","formattedValue","type","isMainView","isTabBar","isHotwireView","wrapperClass","uniqueViewId","urlPath","pathConfigurationPropertiesJson","props","pathConfigurationProperties","childrenHTML","child","singleTabId","tab","button","target","checkbox","filterType","isActive","searchInput","isPinned","collapsible","targetId","targetElement","trigger","dropdown","triggerElement","dropdownContent","el","height","delta","newHeight","draggingThreshold","currentHeight","minThreshold","maxThreshold","controller","DevToolsState","listener","stack","supports","isConnected","components","NativeBridge","_b","data","messageData","DevTools","options","style","createProxyHandler","prop","receiver","originalValue","arg","metadata","attrs","attr","filename","lineno","colno","formattedMessage","mutationsList","mutation","propertyName","existingShadowContainer","shadowContainer","setupDevTools"],"mappings":";;;;;;;AAGO,MAAMA,IAAa,MACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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"}
1
+ {"version":3,"file":"hotwire-native-dev-tools.es.js","sources":["../src/assets/DevToolsStyling.css.js","../src/lib/DiagnosticsChecker.js","../src/utils/settings.js","../src/utils/utils.js","../src/assets/icons.js","../src/components/FloatingBubble.js","../src/components/BottomSheet.js","../src/lib/DevToolsState.js","../src/lib/NativeBridge.js","../src/DevTools.js","../src/index.js"],"sourcesContent":["// Ideally, we would use a dedicated CSS file, but I dind't find a good way to load the styles from a dedicated CSS file.\n// So we just use a function that returns the CSS content as a string.\n// For better syntax highlighting, you can set the language to CSS in the editor for this file.\nexport const cssContent = () => {\n return `\n :host {\n all: initial;\n font-family: system-ui, \"Segoe UI\", Roboto, Helvetica, Arial, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", \"Segoe UI Symbol\" !important;\n --font-size: 16px;\n font-size: var(--font-size) !important;\n }\n\n * {\n box-sizing: border-box;\n }\n\n p, span, h1, h2, h3, h4, h5, h6, div, a, button, input, label {\n font-size: inherit;\n }\n\n\n a {\n color: white;\n }\n\n h1, h2, h3, h4, h5, h6 {\n margin: 0;\n }\n\n button, label, .toggle-label {\n user-select: none;\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n }\n\n input {\n display: block;\n padding: 3px;\n box-sizing: border-box;\n border: 1px solid #ccc;\n border-radius: 4px;\n }\n\n input:focus {\n outline: none;\n }\n\n .btn-icon {\n background-color: transparent;\n border: none;\n color: white;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.5em;\n height: 100%;\n }\n\n .btn-icon svg {\n width: 1rem;\n height: 1rem;\n fill: white;\n }\n\n /* Dropdown */\n .dropdown-content {\n display: none;\n position: absolute;\n z-index: 1000;\n background: white;\n border: 1px solid #ddd;\n box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);\n min-width: 200px;\n max-width: 300px;\n opacity: 0;\n transform: scale(0.9);\n transition: opacity 0.2s, transform 0.2s;\n user-select: none;\n -webkit-user-select: none;\n }\n\n .dropdown-content.dropdown-open {\n display: block;\n opacity: 1;\n transform: scale(1);\n pointer-events: auto;\n }\n\n .dropdown-content > * {\n padding: 12px;\n }\n\n .dropdown-content button,\n .dropdown-content label {\n color: black;\n width: 100%;\n margin: 0;\n border: none;\n display: flex;\n align-items: center;\n }\n\n .dropdown-content button:not(:first-child) {\n border-top: 1px solid #cecdcd;\n }\n\n .settings-dropdown {\n right: 0;\n top: 2rem;\n }\n\n /* Floating bubble */\n #floating-bubble {\n display: flex;\n background-color: hsl(0deg 0% 0% / 60%);\n border-radius: 50%;\n touch-action: none;\n user-select: none;\n z-index: 10000000;\n position: fixed;\n top: 10px;\n left: 10px;\n\n /* Remove tap highlight on iOS */\n -webkit-user-select: none;\n -webkit-tap-highlight-color: transparent;\n\n /* Keep width, height, and border in sync with bubbleSize in FloatingBubble.js */\n width: 4.75rem;\n height: 4.75rem;\n border: 0.3rem solid rgba(136, 136, 136, 0.5);\n }\n\n #floating-bubble svg {\n transform: scale(0.6);\n fill: #b1b1b1;\n }\n\n #floating-bubble .animation-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n pointer-events: none;\n z-index: 1;\n }\n\n #floating-bubble .error-border {\n position: absolute;\n top: -30px;\n left: -30px;\n width: calc(100% + 60px);\n height: calc(100% + 60px);\n border-radius: 50%;\n }\n\n #floating-bubble .error-border circle {\n transform-origin: center;\n transform: rotate(-90deg);\n }\n\n #floating-bubble .error-border circle.animate {\n animation: error-border-progress 0.8s ease-out forwards;\n }\n\n #floating-bubble .animation-container.fade-out {\n animation: fade-out 0.4s ease-out forwards;\n }\n\n /*\n The \"stroke-dasharray\" defines the start of the animation\n The value is calculated by the formula: 2 * Math.PI * radius\n In this case: 2 * Math.PI * 90 = 565\n */\n @keyframes error-border-progress {\n from {\n stroke-dashoffset: 565;\n }\n to {\n stroke-dashoffset: 0;\n }\n }\n\n @keyframes fade-out {\n from {\n opacity: 1;\n }\n to {\n opacity: 0;\n }\n }\n\n /* Bottom Sheet */\n .bottom-sheet {\n position: fixed;\n bottom: 0;\n left: 0;\n width: 100%;\n max-height: 100%;\n display: flex;\n opacity: 0;\n pointer-events: none;\n align-items: center;\n flex-direction: column;\n justify-content: flex-end;\n transition: 0.1s linear;\n z-index: 10000001;\n }\n\n .bottom-sheet .sheet-overlay.active {\n position: fixed;\n top: 0;\n left: 0;\n z-index: -1;\n width: 100%;\n height: 100%;\n opacity: 0.2;\n background: #000;\n }\n\n .bottom-sheet .content {\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 40vh;\n position: relative;\n color: white;\n transform: translateY(100%);\n border-radius: 12px 12px 0 0;\n box-shadow: 0 10px 20px rgba(0, 0, 0, 0.03);\n transition: 0.3s ease;\n overflow-y: hidden;\n }\n\n .bottom-sheet .log-entry {\n border-bottom: 1px solid #6c6c6c;\n white-space: collapse;\n }\n\n .bottom-sheet .log-entry-icon svg {\n width: 1rem;\n fill: white;\n }\n\n .bottom-sheet.show {\n opacity: 1;\n pointer-events: auto;\n }\n\n .bottom-sheet.show .content {\n transform: translateY(0%);\n }\n\n .bottom-sheet.dragging .content {\n transition: none;\n }\n .bottom-sheet.fullscreen .content {\n border-radius: 0;\n overflow-y: hidden;\n }\n\n .bottom-sheet .log-entry-message.warn {\n color: #f39c12;\n }\n\n .bottom-sheet .log-entry-message.error {\n color: #ED4E4C;\n }\n\n .bottom-sheet .tab-action-bars {\n /* Fixes a 1px gap that can appear between .tab-action-bar and .tablist on Android devices */\n margin-top: -1px;\n }\n\n .bottom-sheet .tab-action-bar {\n display: none;\n justify-content: space-between;\n background-color: rgb(49, 54, 63);\n padding: 0.5rem;\n padding-right: 1rem;\n padding-left: 1rem;\n }\n\n .bottom-sheet .tab-action-bar.active {\n display: flex;\n }\n\n .bottom-sheet .tab-action-bar button:active svg {\n fill: #6c6c6c;\n }\n\n .bottom-sheet .btn-clear-tab,\n .bottom-sheet .btn-reload-tab {\n margin-left: auto;\n }\n\n /* Bottom Sheet Tabs */\n .tablist {\n display: flex;\n overflow: hidden;\n background-color: #EEEEEE;\n }\n\n .tablist .tablink {\n color: black;\n background-color: inherit;\n width: 100%;\n border: none;\n outline: none;\n padding: 14px 16px;\n margin: 0;\n font-size: 0.8em;\n }\n\n .tablist .tablink.active {\n background-color: #31363f;\n color: white;\n }\n\n .tablist .tablink-settings {\n background-color: inherit;\n }\n\n .tab-contents {\n height: 100%;\n overflow: scroll;\n /* Fixes a 1px gap that can appear between .tab-action-bar and .tab-contents on Android devices */\n margin-top: -1px;\n }\n\n .outer-tab-content {\n display: none;\n border-top: none;\n height: 100%;\n overflow: scroll;\n background-color: hsl(0deg 0% 0% / 80%);\n backdrop-filter: blur(30px) saturate(250%);\n -webkit-backdrop-filter: blur(30px) saturate(250%);\n padding-bottom: 7em;\n }\n .outer-tab-content.active {\n display: block;\n }\n .inner-tab-content {\n padding: 1rem;\n overflow-x: auto;\n white-space: nowrap;\n }\n .single-tab-content .inner-tab-content {\n white-space: normal;\n }\n\n .info-card {\n border-radius: 5px;\n background: hsl(0deg 0% 0% / 20%);\n padding: 1em;\n margin-bottom: 1em;\n }\n\n .info-card-title {\n font-size: 1em;\n font-weight: 700;\n margin-bottom: 1em;\n display: flex;\n justify-content: space-between;\n }\n\n .info-card-hint {\n font-size: 0.8em;\n }\n\n .tab-empty-content {\n display: flex;\n justify-content: center;\n flex-direction: column;\n align-items: center;\n padding: 1em;\n }\n\n .bottom-sheet .tablink-dropdown {\n background: inherit;\n border: none;\n outline: none;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0.5em;\n width: 2rem;\n }\n\n .bottom-sheet .tablink-dropdown svg {\n width: 1rem;\n height: 1rem;\n fill: #121212;\n }\n\n .bottom-sheet .tablink-dropdown:active {\n background-color: #31363f;\n }\n .bottom-sheet .tablink-dropdown:active svg {\n fill: white;\n }\n\n /* Bottom Sheet Stack Visualization */\n .bottom-sheet .viewstack-card {\n border: 1px solid #ddd;\n border-radius: 8px;\n padding: 10px;\n margin: 10px 0;\n background: white;\n color: black;\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\n overflow: auto;\n }\n\n .bottom-sheet .viewstack-card.current-view {\n border: 2px solid #f1f208;\n }\n\n .bottom-sheet .tab-container {\n background: #EEEEEE;\n }\n\n .bottom-sheet .main-view {\n border-color: #4e6080;\n background: #31363F;\n }\n\n .bottom-sheet .hotwire-view {\n border-color: #6db1b5;\n background: #76ABAE;\n }\n\n .bottom-sheet .child-container {\n margin-left: 30px;\n position: relative;\n }\n\n .bottom-sheet .child-container::before {\n content: \"\";\n position: absolute;\n left: -15px;\n top: 0;\n bottom: 0;\n width: 2px;\n background: #ddd;\n }\n\n .bottom-sheet .view-title {\n display: flex;\n align-items: center;\n gap: 0.5em;\n\n font-weight: bold;\n color: white;\n margin-bottom: 5px;\n }\n\n .bottom-sheet .view-title-details {\n color: #efefef;\n font-size: 0.6em;\n }\n\n .bottom-sheet .tab-container .view-title-details {\n color: #6c6c6c;\n }\n\n .bottom-sheet .view-url {\n color: #000000;\n font-size: 0.9em;\n margin-top: 5px;\n word-break: break-all;\n }\n\n .bottom-sheet .non-identified-view {\n background: #EEEEEE;\n }\n .bottom-sheet .non-identified-view .view-title-details,\n .bottom-sheet .non-identified-view .view-title {\n color: #6c6c6c;\n }\n\n .bottom-sheet .viewstack-card pre {\n font-size: 0.8em;\n }\n\n /* Bottom Sheet Bridge Components */\n .bottom-sheet .bridge-components-collapse-btn {\n background: none;\n border: none;\n color: white;\n width: 100%;\n text-align: left;\n border-bottom: 1px solid #eee;\n padding: 0.5em 0em;\n font-size: 0.9em;\n }\n\n .tab-content-bridge-components {\n display: grid;\n grid-template-columns: 1fr 1fr;\n gap: 10px;\n padding: 0.5em 0em;\n }\n\n .tab-content-bridge-components .bridge-component {\n position: relative;\n padding-left: 15px;\n }\n\n .tab-content-bridge-components .bridge-component::before {\n content: \"•\";\n color: #eee;\n font-size: 1.5em;\n position: absolute;\n left: 0;\n top: 50%;\n transform: translateY(-50%);\n }\n .tab-content-bridge-components .bridge-component.connected::before {\n color: #5cff00\n }\n\n /* Collapsibles */\n .collapse-target {\n display: none;\n }\n\n .collapse-target.active {\n display: block;\n }\n\n .collapse:not(.no-chevron):after {\n content: '\\\\25BC';\n font-size: 13px;\n color: #777;\n float: right;\n margin-left: 5px;\n }\n\n .collapse:not(.no-chevron).active:after {\n content: \"\\\\25B2\";\n }\n\n /* Custom checkbox toggles */\n .toggle {\n display: inline-block;\n user-select: none;\n }\n\n .toggle-switch {\n display: inline-block;\n background: #ccc;\n border-radius: 16px;\n width: 29px;\n height: 16px;\n position: relative;\n vertical-align: middle;\n transition: background 0.15s;\n }\n .toggle-switch:before,\n .toggle-switch:after {\n content: \"\";\n }\n .toggle-switch:before {\n display: block;\n background: linear-gradient(to bottom, #fff 0%, #eee 100%);\n border-radius: 50%;\n width: 12px;\n height: 12px;\n position: absolute;\n top: 2px;\n left: 2px;\n transition: left 0.15s;\n }\n .toggle-checkbox:checked + .toggle-switch {\n background: #56c080;\n }\n .toggle-checkbox:checked + .toggle-switch:before {\n left: 15px;\n }\n\n .toggle-checkbox {\n position: absolute;\n visibility: hidden;\n }\n\n .toggle-label {\n position: relative;\n margin-left: 3px;\n top: 2px;\n }\n\n /* Utility classes */\n .d-none {\n display: none;\n }\n\n .text-center {\n text-align: center;\n }\n\n .text-ellipsis {\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n }\n\n .break-word {\n word-break: break-word;\n }\n\n .d-flex {\n display: flex;\n }\n\n .flex-column {\n flex-direction: column;\n }\n\n .justify-content-between {\n justify-content: space-between;\n }\n\n .justify-content-end {\n justify-content: flex-end;\n }\n\n .align-items-center {\n align-items: center;\n }\n\n .flex-grow-1 {\n flex-grow: 1;\n }\n\n .border-bottom {\n border-bottom: 1px solid #c5c1c1;\n }\n\n .no-wrap {\n overflow: hidden;\n white-space: nowrap;\n }\n\n .white-space-collapse {\n white-space: collapse;\n }\n\n .overflow-auto {\n overflow: auto;\n }\n\n .m-0 {\n margin: 0;\n }\n\n .mt-1 {\n margin-top: 0.25rem;\n }\n\n .mt-2 {\n margin-top: 0.5rem;\n }\n\n .mt-4 {\n margin-top: 1.5rem;\n }\n\n .ms-1 {\n margin-left: 0.25rem;\n }\n\n .mb-2 {\n margin-bottom: 0.5rem;\n }\n\n .mb-3 {\n margin-bottom: 1rem;\n }\n\n .mb-4 {\n margin-bottom: 1.5rem;\n }\n\n .gap-1 {\n gap: 0.25rem;\n }\n\n .gap-3 {\n gap: 1rem;\n }\n\n .pb-2 {\n padding-bottom: 0.5rem;\n }\n\n .pt-2 {\n padding-top: 0.5rem;\n }\n\n .w-100 {\n width: 100%;\n }\n\n .w-80 {\n width: 80%;\n }\n `\n}\n","export default class DiagnosticsChecker {\n constructor() {\n this.printedWarnings = []\n }\n\n printWarning = (message, once = true, ...extraArgs) => {\n if (once && this.printedWarnings.includes(message)) return\n\n console.warn(`DevTools: ${message}`, ...extraArgs)\n this.printedWarnings.push(message)\n }\n\n checkForWarnings = () => {\n this.#checkForTurboDrive()\n this.#checkForDuplicatedTurboFrames()\n this.#checkTurboPermanentElements()\n }\n\n #checkForTurboDrive = () => {\n if (!window.Turbo) {\n // Since it's possible that the DevTools are loaded before Turbo, we need to wait a bit to check if Turbo is loaded\n setTimeout(() => {\n if (!window.Turbo) {\n this.printWarning(\"Turbo is not detected. Hotwire Native will not work correctly without Turbo\")\n }\n }, 1000)\n } else if (window.Turbo?.session.drive === false) {\n setTimeout(() => {\n if (window.Turbo?.session.drive === false) {\n this.printWarning(\"Turbo Drive is disabled. Hotwire Native will not work correctly without Turbo Drive\")\n }\n }, 1000)\n }\n }\n\n #checkForDuplicatedTurboFrames = () => {\n const turboFramesIds = this.turboFrameIds\n const duplicatedIds = turboFramesIds.filter((id, index) => turboFramesIds.indexOf(id) !== index)\n\n duplicatedIds.forEach((id) => {\n this.printWarning(`Multiple Turbo Frames with the same ID '${id}' detected. This can cause unexpected behavior. Ensure that each Turbo Frame has a unique ID.`)\n })\n }\n\n #checkTurboPermanentElements = () => {\n const turboPermanentElements = document.querySelectorAll(\"[data-turbo-permanent]\")\n if (turboPermanentElements.length === 0) return\n\n turboPermanentElements.forEach((element) => {\n const id = element.id\n if (id === \"\") {\n const message = `Turbo Permanent Element detected without an ID. Turbo Permanent Elements must have a unique ID to work correctly.`\n this.printWarning(message, true, element)\n }\n\n const idIsDuplicated = id && document.querySelectorAll(`#${id}`).length > 1\n if (idIsDuplicated) {\n const message = `Turbo Permanent Element with ID '${id}' doesn't have a unique ID. Turbo Permanent Elements must have a unique ID to work correctly.`\n this.printWarning(message, true, element)\n }\n })\n }\n\n get turboFrameIds() {\n return Array.from(document.querySelectorAll(\"turbo-frame\")).map((turboFrame) => turboFrame.id)\n }\n}\n","export const getSettings = (key) => {\n let settings = JSON.parse(localStorage.getItem(\"hotwire-native-dev-tools\") || \"{}\")\n return settings[key]\n}\n\nexport const saveSettings = (key, value) => {\n let settings = JSON.parse(localStorage.getItem(\"hotwire-native-dev-tools\") || \"{}\")\n settings[key] = value\n\n localStorage.setItem(\"hotwire-native-dev-tools\", JSON.stringify(settings))\n}\n\nexport const resetSettings = () => {\n localStorage.removeItem(\"hotwire-native-dev-tools\")\n}\n\nexport const getConsoleFilterLevels = () => {\n const consoleFilterLevels = getSettings(\"consoleFilterLevels\") || {\n warn: true,\n error: true,\n debug: true,\n info: true,\n log: true,\n }\n\n return consoleFilterLevels\n}\n\nexport const saveConsoleFilterLevels = (key, value) => {\n const consoleFilterLevels = getConsoleFilterLevels()\n consoleFilterLevels[key] = value\n saveSettings(\"consoleFilterLevels\", consoleFilterLevels)\n return consoleFilterLevels\n}\n","export const debounce = (fn, delay) => {\n let timeoutId = null\n\n return (...args) => {\n const callback = () => fn.apply(this, args)\n clearTimeout(timeoutId)\n timeoutId = setTimeout(callback, delay)\n }\n}\n\nconst { userAgent } = window.navigator\nexport const isIosApp = /iOS/.test(userAgent)\nexport const isAndroidApp = /Android/.test(userAgent)\n\nexport const platform = () => {\n if (isIosApp) {\n return \"ios\"\n } else if (isAndroidApp) {\n return \"android\"\n }\n return \"unknown\"\n}\n\nexport const formattedPlatform = () => {\n switch (platform()) {\n case \"android\":\n return \"Android\"\n case \"ios\":\n return \"iOS\"\n default:\n return \"<unknown>\"\n }\n}\n\nexport const getMetaElement = (name) => {\n return document.querySelector(`meta[name=\"${name}\"]`)\n}\n\nexport const getMetaContent = (name) => {\n const element = getMetaElement(name)\n return element && element.content\n}\n","export const hotwireIcon = `\n <svg width=\"100%\" height=\"100%\" viewBox=\"0 0 294 320\">\n <g transform=\"matrix(1,0,0,1,-28.38,-15.268)\">\n <g transform=\"matrix(1,0,0,1,-462.157,-144.417)\">\n <path d=\"M783.777,159.685L683.006,262.542L765.948,268.939L622.459,394.208L690.389,396.4L490.537,479.149L569.424,402.053L511.312,400.203L639.22,296.093L533.548,287.812L783.777,159.685Z\"/>\n </g>\n </g>\n </svg>\n`\n\nexport const arrowUp = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM385 215c9.4 9.4 9.4 24.6 0 33.9s-24.6 9.4-33.9 0l-71-71L280 392c0 13.3-10.7 24-24 24s-24-10.7-24-24l0-214.1-71 71c-9.4 9.4-24.6 9.4-33.9 0s-9.4-24.6 0-33.9L239 103c9.4-9.4 24.6-9.4 33.9 0L385 215z\"/>\n </svg>\n`\n\nexport const arrowDown = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 0a256 256 0 1 0 0 512A256 256 0 1 0 256 0zM127 297c-9.4-9.4-9.4-24.6 0-33.9s24.6-9.4 33.9 0l71 71L232 120c0-13.3 10.7-24 24-24s24 10.7 24 24l0 214.1 71-71c9.4-9.4 24.6-9.4 33.9 0s9.4 24.6 0 33.9L273 409c-9.4 9.4-24.6 9.4-33.9 0L127 297z\"/>\n </svg>\n`\n\nexport const arrowLeft = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M9.4 233.4c-12.5 12.5-12.5 32.8 0 45.3l160 160c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L109.2 288 416 288c17.7 0 32-14.3 32-32s-14.3-32-32-32l-306.7 0L214.6 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0l-160 160z\"/>\n </svg>\n`\n\nexport const trash = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 448 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M135.2 17.7L128 32 32 32C14.3 32 0 46.3 0 64S14.3 96 32 96l384 0c17.7 0 32-14.3 32-32s-14.3-32-32-32l-96 0-7.2-14.3C307.4 6.8 296.3 0 284.2 0L163.8 0c-12.1 0-23.2 6.8-28.6 17.7zM416 128L32 128 53.2 467c1.6 25.3 22.6 45 47.9 45l245.8 0c25.3 0 46.3-19.7 47.9-45L416 128z\"/>\n </svg>\n`\n\nexport const rotate = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M142.9 142.9c-17.5 17.5-30.1 38-37.8 59.8c-5.9 16.7-24.2 25.4-40.8 19.5s-25.4-24.2-19.5-40.8C55.6 150.7 73.2 122 97.6 97.6c87.2-87.2 228.3-87.5 315.8-1L455 55c6.9-6.9 17.2-8.9 26.2-5.2s14.8 12.5 14.8 22.2l0 128c0 13.3-10.7 24-24 24l-8.4 0c0 0 0 0 0 0L344 224c-9.7 0-18.5-5.8-22.2-14.8s-1.7-19.3 5.2-26.2l41.1-41.1c-62.6-61.5-163.1-61.2-225.3 1zM16 312c0-13.3 10.7-24 24-24l7.6 0 .7 0L168 288c9.7 0 18.5 5.8 22.2 14.8s1.7 19.3-5.2 26.2l-41.1 41.1c62.6 61.5 163.1 61.2 225.3-1c17.5-17.5 30.1-38 37.8-59.8c5.9-16.7 24.2-25.4 40.8-19.5s25.4 24.2 19.5 40.8c-10.8 30.6-28.4 59.3-52.9 83.8c-87.2 87.2-228.3 87.5-315.8 1L57 457c-6.9 6.9-17.2 8.9-26.2 5.2S16 449.7 16 440l0-119.6 0-.7 0-7.6z\"/>\n </svg>\n`\n\nexport const questionMark = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M256 512A256 256 0 1 0 256 0a256 256 0 1 0 0 512zM169.8 165.3c7.9-22.3 29.1-37.3 52.8-37.3l58.3 0c34.9 0 63.1 28.3 63.1 63.1c0 22.6-12.1 43.5-31.7 54.8L280 264.4c-.2 13-10.9 23.6-24 23.6c-13.3 0-24-10.7-24-24l0-13.5c0-8.6 4.6-16.5 12.1-20.8l44.3-25.4c4.7-2.7 7.6-7.7 7.6-13.1c0-8.4-6.8-15.1-15.1-15.1l-58.3 0c-3.4 0-6.4 2.1-7.5 5.3l-.4 1.2c-4.4 12.5-18.2 19-30.6 14.6s-19-18.2-14.6-30.6l.4-1.2zM224 352a32 32 0 1 1 64 0 32 32 0 1 1 -64 0z\"/>\n </svg>\n`\n\nexport const search = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M416 208c0 45.9-14.9 88.3-40 122.7L502.6 457.4c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L330.7 376c-34.4 25.2-76.8 40-122.7 40C93.1 416 0 322.9 0 208S93.1 0 208 0S416 93.1 416 208zM208 352a144 144 0 1 0 0-288 144 144 0 1 0 0 288z\"/>\n </svg>\n`\n\nexport const filter = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M3.9 54.9C10.5 40.9 24.5 32 40 32l432 0c15.5 0 29.5 8.9 36.1 22.9s4.6 30.5-5.2 42.5L320 320.9 320 448c0 12.1-6.8 23.2-17.7 28.6s-23.8 4.3-33.5-3l-64-48c-8.1-6-12.8-15.5-12.8-25.6l0-79.1L9 97.3C-.7 85.4-2.8 68.8 3.9 54.9z\"/>\n </svg>\n`\n\nexport const threeDotsVertical = `\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 128 512\">\n <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->\n <path d=\"M64 360a56 56 0 1 0 0 112 56 56 0 1 0 0-112zm0-160a56 56 0 1 0 0 112 56 56 0 1 0 0-112zM120 96A56 56 0 1 0 8 96a56 56 0 1 0 112 0z\"/>\n </svg>\n`\n","import { getSettings, saveSettings } from \"../utils/settings\"\nimport { debounce } from \"../utils/utils\"\nimport { hotwireIcon } from \"../assets/icons\"\n\nexport default class FloatingBubble {\n constructor(devTools) {\n this.devTools = devTools\n this.bubbleSize = 4.75 * 16 + 0.3 * 16 // 4.75rem + 0.3rem border\n this.minVisible = this.bubbleSize * 0.5 // Keep 50% of the bubble visible at all times\n this.currentlyDragging = false\n }\n\n render = debounce(() => {\n this.setPosition()\n this.createDragItem()\n this.setTranslate(this.initialX, this.initialY, this.dragItem)\n this.addEventListeners()\n }, 50)\n\n setPosition() {\n this.settingKey = window.innerWidth < window.innerHeight ? \"bubblePosPortrait\" : \"bubblePosLandscape\"\n\n // Get stored position or use default (bottom right corner)\n const defaultPos = { x: window.innerWidth - 100, y: window.innerHeight - 100 }\n const { x: startX, y: startY } = getSettings(this.settingKey) || defaultPos\n\n this.currentX = this.initialX = this.xOffset = startX\n this.currentY = this.initialY = this.yOffset = startY\n }\n\n createDragItem() {\n const existingBubble = this.devTools.shadowRoot?.getElementById(\"floating-bubble\")\n if (existingBubble) {\n this.dragItem = existingBubble\n return\n }\n\n this.dragItem = document.createElement(\"div\")\n this.dragItem.id = \"floating-bubble\"\n this.dragItem.innerHTML = hotwireIcon\n this.devTools.shadowRoot.appendChild(this.dragItem)\n }\n\n addEventListeners() {\n if (this.dragItem.hasEventListeners) return\n this.dragItem.addEventListener(\"click\", this.click.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchstart\", this.dragStart.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchend\", this.dragEnd.bind(this), { passive: true })\n this.dragItem.addEventListener(\"touchmove\", this.drag.bind(this), { passive: true })\n this.dragItem.hasEventListeners = true\n }\n\n click(event) {\n if (this.clickCallback) {\n this.clickCallback(event)\n }\n }\n\n animateErrorBorder = debounce(() => {\n if (!this.dragItem) return\n if (getSettings(\"errorAnimationEnabled\") === false) return\n\n let errorBorder = this.dragItem.querySelector(\".error-border\")\n let circleElement = this.dragItem.querySelector(\".error-border circle\")\n\n if (errorBorder) {\n errorBorder.remove()\n }\n\n const animationContainer = document.createElement(\"div\")\n animationContainer.className = \"animation-container\"\n animationContainer.innerHTML = `\n <svg viewBox=\"0 0 180 180\" xmlns=\"http://www.w3.org/2000/svg\" class=\"error-border\">\n <defs>\n <linearGradient id=\"errorGradient\" gradientTransform=\"rotate(45)\">\n <stop offset=\"0%\" stop-color=\"#e4241a\" />\n <stop offset=\"50%\" stop-color=\"#dd1f15\" />\n <stop offset=\"100%\" stop-color=\"#f6160a\" />\n </linearGradient>\n </defs>\n <circle cx=\"90\" cy=\"90\" r=\"90\" fill=\"none\" stroke=\"url(#errorGradient)\" stroke-width=\"21\"\n stroke-dasharray=\"565\" stroke-dashoffset=\"565\" stroke-linecap=\"round\" />\n </svg>\n `\n\n this.dragItem.appendChild(animationContainer)\n circleElement = this.dragItem.querySelector(\".error-border circle\")\n circleElement.classList.add(\"animate\")\n\n setTimeout(() => {\n animationContainer.classList.add(\"fade-out\")\n }, 1300) // Start fade-out after animation completes\n\n setTimeout(() => {\n if (animationContainer && animationContainer.parentNode) {\n animationContainer.remove()\n }\n }, 1800) // Remove after fade-out completes\n }, 100)\n\n onClick(callback) {\n this.clickCallback = callback\n }\n\n dragStart(event) {\n if (!event.target.closest(\"#floating-bubble\")) return\n this.currentlyDragging = true\n\n this.initialX = event.touches[0].clientX - this.xOffset\n this.initialY = event.touches[0].clientY - this.yOffset\n }\n\n dragEnd() {\n this.initialX = this.currentX\n this.initialY = this.currentY\n this.currentlyDragging = false\n\n saveSettings(this.settingKey, { x: this.currentX, y: this.currentY })\n }\n\n drag(event) {\n if (!this.currentlyDragging) return\n\n const touch = event.touches[0]\n const deltaX = touch.clientX - this.initialX\n const deltaY = touch.clientY - this.initialY\n\n // Constrain movement within screen bounds\n this.currentX = Math.max(-this.bubbleSize + this.minVisible, Math.min(deltaX, window.innerWidth - this.minVisible))\n this.currentY = Math.max(-this.bubbleSize + this.minVisible, Math.min(deltaY, window.innerHeight - this.minVisible))\n\n this.xOffset = this.currentX\n this.yOffset = this.currentY\n\n if (!this.animationFrame) {\n this.animationFrame = requestAnimationFrame(() => {\n this.setTranslate(this.currentX, this.currentY, this.dragItem)\n this.animationFrame = null\n })\n }\n }\n\n setTranslate(xPos, yPos, element) {\n element.style.transform = `translate3d(${xPos}px, ${yPos}px, 0)`\n }\n}\n","import * as Icons from \"../assets/icons\"\nimport { platform, formattedPlatform, getMetaContent } from \"../utils/utils\"\nimport { saveSettings, getSettings, getConsoleFilterLevels, saveConsoleFilterLevels } from \"../utils/settings\"\n\n// WARNING: Be careful when console logging in this file, as it can cause an infinite loop\n// When you need to debug, use the `log` helper function like this:\n// this.log(\"message\")\n// or turn off the console proxy in DevTools.js\n\nexport default class BottomSheet {\n constructor(devTools) {\n this.devTools = devTools\n this.state = devTools.state.state\n this.sheetHeight = parseInt(getSettings(\"bottomSheetHeight\")) || 55\n }\n\n render() {\n this.createBottomSheet()\n this.sheetContent = this.bottomSheet.querySelector(\".content\")\n this.sheetOverlay = this.bottomSheet.querySelector(\".sheet-overlay\")\n this.addEventListeners()\n }\n\n // Called when the in-memory state changes,\n // such as when a new console or bridge log is captured.\n update(newState) {\n this.state = newState\n this.checkNativeFeatures()\n this.renderConsoleLogs()\n this.renderBridgeComponents()\n this.renderBridgeLogs()\n this.renderEvents()\n this.renderNativeStack()\n this.scrollToLatestLog(this.state.activeTab)\n this.state.shouldScrollToLatestLog = true\n }\n\n // Called when another native tab of the mobile app\n // updates devtools-related local storage.\n applySettingsFromStorage() {\n const settings = [\n { key: \"bottomSheetHeight\", setter: (value) => this.updateSheetHeight(value) },\n { key: \"activeTab\", setter: (value) => this.updateTabView(value) },\n { key: \"fontSize\", setter: (value) => this.updateFontSize(value) },\n { key: \"errorAnimationEnabled\", setter: (value) => this.updateErrorAnimation(value) },\n { key: \"autoOpen\", setter: (value) => this.updateAutoOpen(value) },\n ]\n settings.forEach(({ key, setter }) => {\n const storedValue = getSettings(key)\n if (storedValue !== undefined) setter(storedValue)\n })\n\n const storedConsoleFilterLevels = getConsoleFilterLevels()\n if (storedConsoleFilterLevels) {\n this.updateConsoleFilter(storedConsoleFilterLevels)\n }\n }\n\n createBottomSheet() {\n const existingBottomSheet = this.devTools.shadowRoot?.querySelector(\".bottom-sheet\")\n if (existingBottomSheet) {\n this.bottomSheet = existingBottomSheet\n return\n }\n\n const activeTab = this.state.activeTab\n const consoleFilterLevels = getConsoleFilterLevels()\n const consoleSearch = this.state.consoleSearch\n this.bottomSheet = document.createElement(\"div\")\n this.bottomSheet.classList.add(\"bottom-sheet\")\n this.bottomSheet.innerHTML = `\n <div class=\"sheet-overlay ${getSettings(\"bottomSheetPinned\") === true ? \"\" : \"active\"}\"></div>\n <div class=\"content\">\n <div class=\"top-part\">\n <div class=\"tablist\">\n <button class=\"tablink ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\" data-tab-id=\"tab-bridge-components\">Bridge</button>\n <button class=\"tablink ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\" data-tab-id=\"tab-console-logs\">Console</button>\n <button class=\"tablink ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\" data-tab-id=\"tab-event-logs\">Events</button>\n <button class=\"tablink ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"} d-none\" data-tab-id=\"tab-native-stack\">Stack</button>\n <div class=\"tablink-settings dropdown d-flex\">\n <button class=\"dropdown-trigger tablink-dropdown\">${Icons.threeDotsVertical}</button>\n <div class=\"dropdown-content settings-dropdown\">\n <button class=\"btn-switch-to-single-tab-sheet\" data-tab-id=\"single-tab-settings\">Settings</button>\n <button class=\"btn-switch-to-single-tab-sheet\" data-tab-id=\"single-tab-info\">Info</button>\n <button class=\"pin-bottom-sheet\">Pin Bottom Sheet</button>\n </div>\n </div>\n </div>\n\n <div class=\"tab-action-bars\">\n <div class=\"tab-action-bar tab-bridge-components ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-clear-tab btn-clear-bridge-logs\">${Icons.trash}</button>\n </div>\n <div class=\"tab-action-bar d-flex flex-column tab-console-logs ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\">\n <div class=\"d-flex\">\n <button class=\"btn-icon btn-search-console\">${Icons.search}</button>\n <div class=\"dropdown\">\n <button class=\"dropdown-trigger btn-icon\">${Icons.filter}</button>\n <div class=\"dropdown-content console-filter-levels\">\n <label><input type=\"checkbox\" ${consoleFilterLevels.warn ? \"checked\" : \"\"} data-console-filter=\"warn\" /> Warnings</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.error ? \"checked\" : \"\"} data-console-filter=\"error\" /> Errors</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.debug ? \"checked\" : \"\"} data-console-filter=\"debug\" /> Debug</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.info ? \"checked\" : \"\"} data-console-filter=\"info\" /> Info</label>\n <label><input type=\"checkbox\" ${consoleFilterLevels.log ? \"checked\" : \"\"} data-console-filter=\"log\" /> Logs</label>\n </div>\n </div>\n <button class=\"btn-icon btn-clear-tab btn-clear-console-logs\">${Icons.trash}</button>\n </div>\n\n <div class=\"console-search mt-2 ${consoleSearch ? \"\" : \"d-none\"}\">\n <input type=\"search\" class=\"console-search-input\" value=\"${consoleSearch}\" placeholder=\"Search console logs\" />\n </div>\n </div>\n <div class=\"tab-action-bar tab-event-logs ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-clear-tab btn-clear-events\">${Icons.trash}</button>\n </div>\n <div class=\"tab-action-bar tab-native-stack ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"}\">\n <button class=\"btn-icon btn-reload-tab btn-reload-stack\">${Icons.rotate}</button>\n </div>\n </div>\n </div>\n\n <div class=\"tab-contents\">\n <div id=\"tab-bridge-components\" class=\"outer-tab-content ${activeTab === \"tab-bridge-components\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content\">\n <button class=\"collapse bridge-components-collapse-btn\" type=\"button\" data-collapse-target=\"bridge-components-collapse\">\n Registered Bridge Components: <span class=\"bridge-components-amount\">${this.state.supportedBridgeComponents.length}</span>\n </button>\n <div id=\"bridge-components-collapse\" class=\"collapse-target\">\n <div class=\"d-flex justify-content-between border-bottom\">\n <div class=\"tab-content-bridge-components flex-grow-1\"></div>\n <button class=\"btn-icon btn-help btn-switch-to-single-tab-sheet mt-1\" data-tab-id=\"single-tab-bridge-component-help\">${Icons.questionMark}</button>\n </div>\n </div>\n\n <div class=\"tab-content-bridge-logs\">\n </div>\n </div>\n </div>\n\n <div id=\"tab-console-logs\" class=\"outer-tab-content ${activeTab === \"tab-console-logs\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-console-logs\">\n </div>\n </div>\n\n <div id=\"tab-event-logs\" class=\"outer-tab-content ${activeTab === \"tab-event-logs\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-event-logs\">\n </div>\n </div>\n\n <div id=\"tab-native-stack\" class=\"outer-tab-content ${activeTab === \"tab-native-stack\" ? \"active\" : \"\"}\">\n <div class=\"inner-tab-content tab-content-native-stack\">\n </div>\n </div>\n\n <div id=\"single-tab-bridge-component-help\" class=\"single-tab-content outer-tab-content\">\n <div class=\"inner-tab-content\">\n <div class=\"d-flex align-items-center mb-3\">\n <button class=\"btn-icon btn-close-single-mode\">${Icons.arrowLeft}</button>\n <h3 class=\"ms-1\">Bridge Components</h3>\n </div>\n <p>This list shows all the bridge components that the ${formattedPlatform()} app supports. Components that are active on this page are marked with a green dot.</p>\n <h3 class=\"mt-4\">Why is my bridge component not on the list?</h3>\n <p class=\"mt-2\">Bridge components are automatically detected when they are registered in the native code. If your component is not on the list, make sure it is registered correctly.</p>\n ${this.registerBridgeComponentExample()}\n <p class\"mt-1\">For more information, check out the documentation:</p>\n <a href=\"${this.registerBridgeComponentHelpURL()}\">${this.registerBridgeComponentHelpURL()}</a>\n </div>\n </div>\n\n <div id=\"single-tab-settings\" class=\"single-tab-content outer-tab-content\">\n <div class=\"inner-tab-content\">\n <div class=\"d-flex align-items-center mb-3\">\n <button class=\"btn-icon btn-close-single-mode\">${Icons.arrowLeft}</button>\n <h3 class=\"ms-1\">Settings</h3>\n </div>\n <div class=\"mb-3\">\n <label for=\"bottom-sheet-height-setting\"> Bottom Sheet Height</label>\n <input type=\"range\" id=\"bottom-sheet-height-setting\" class=\"w-100\" min=\"10\" max=\"100\" value=\"${this.sheetHeight}\" step=\"1\" list=\"bottom-sheet-height-setting-markers\" />\n <datalist id=\"bottom-sheet-height-setting-markers\">\n <option value=\"55\"></option>\n </datalist>\n </div>\n <div class=\"mb-4\">\n <label for=\"font-size-setting\"> Font Size</label>\n <input type=\"range\" id=\"font-size-setting\" class=\"w-100\" min=\"8\" max=\"24\" value=\"${getSettings(\"fontSize\") || 16}\" step=\"1\" list=\"font-size-setting-markers\" />\n <datalist id=\"font-size-setting-markers\">\n <option value=\"16\"></option>\n </datalist>\n </div>\n <div class=\"mb-3\">\n <label class=\"toggle\">\n <input class=\"toggle-checkbox\" type=\"checkbox\" id=\"console-error-animation-setting\" ${getSettings(\"errorAnimationEnabled\") !== false ? \"checked\" : \"\"} />\n <div class=\"toggle-switch\"></div>\n <span class=\"toggle-label\">Console Error Animation</span>\n </label>\n </div>\n <div class=\"mb-3\">\n <label class=\"toggle\">\n <input class=\"toggle-checkbox\" type=\"checkbox\" id=\"auto-open-setting\" ${getSettings(\"autoOpen\") === true ? \"checked\" : \"\"} />\n <div class=\"toggle-switch\"></div>\n <span class=\"toggle-label\">Auto Open</span>\n </label>\n </div>\n <div class=\"mb-3\">\n <label class=\"toggle\">\n <input class=\"toggle-checkbox\" type=\"checkbox\" id=\"scroll-to-latest-log-setting\" ${getSettings(\"scrollToLatestLog\") === true ? \"checked\" : \"\"} />\n <div class=\"toggle-switch\"></div>\n <span class=\"toggle-label\">Automatically Scroll to New Logs</span>\n </label>\n </div>\n </div>\n </div>\n\n <div id=\"single-tab-info\" class=\"single-tab-content outer-tab-content\">\n <div class=\"inner-tab-content\">\n <div class=\"d-flex align-items-center mb-3\">\n <button class=\"btn-icon btn-close-single-mode\">${Icons.arrowLeft}</button>\n <h3 class=\"ms-1\">Info</h3>\n </div>\n <div class=\"info-card\">\n <div class=\"info-card-title\">Current URL</div>\n <div class=\"current-url\">${this.currentUrl}</div>\n </div>\n <div class=\"info-card\">\n <div class=\"info-card-title\">User Agent</div>\n <div class=\"user-agent\">${navigator.userAgent}</div>\n </div>\n <div class=\"info-card\">\n <div class=\"info-card-title\"><pre class=\"m-0\">turbo-cache-control:</pre> <span>${getMetaContent(\"turbo-cache-control\") || \"-\"}</span></div>\n <div class=\"info-card-hint\"><strong>no-cache:</strong> always fetched from the network, even on restore</div>\n <div class=\"info-card-hint\"><strong>no-preview:</strong> skipped in preview, used only on restore</div>\n <div class=\"info-card-hint\"><strong>unset:</strong> shows cached preview if the cache is valid</div>\n </div>\n <div class=\"info-card\">\n <div class=\"info-card-title\"><pre class=\"m-0\">turbo-refresh-method:</pre> <span>${getMetaContent(\"turbo-refresh-method\") || \"-\"}</span></div>\n <div class=\"info-card-hint\"><strong>replace (default):</strong> replaces the entire &lt;body&gt; on revisit</div>\n <div class=\"info-card-hint\"><strong>morph:</strong> updates only changed DOM elements, preserving state</div>\n </div>\n <div class=\"info-card\">\n <div class=\"info-card-title\"><pre class=\"m-0\">turbo-visit-control:</pre> <span>${getMetaContent(\"turbo-visit-control\") || \"-\"}</span></div>\n <div class=\"info-card-hint\"><strong>reload:</strong> forces a full page reload</div>\n <div class=\"info-card-hint\"><strong>unset:</strong> allows Turbo to handle the visit normally</div>\n </div>\n </div>\n </div>\n </div>\n </div>\n `\n this.devTools.shadowRoot.appendChild(this.bottomSheet)\n }\n\n renderConsoleLogs() {\n const container = this.bottomSheet.querySelector(\".tab-content-console-logs\")\n const consoleFilterLevels = getConsoleFilterLevels()\n const consoleSearch = this.state.consoleSearch\n container.innerHTML = this.state.consoleLogs.length\n ? this.state.consoleLogs\n .filter((log) => consoleFilterLevels[log.type])\n .filter((log) => {\n if (!consoleSearch) return true\n return log.message.toLowerCase().includes(consoleSearch.toLowerCase())\n })\n .map((log) => this.consoleLogHTML(log.type, log.message, log.time))\n .join(\"\")\n : `<div class=\"tab-empty-content\"><span>No console logs yet</span></div>`\n }\n\n renderBridgeComponents() {\n const bridgeComponentsAmount = this.state.supportedBridgeComponents.length\n this.bottomSheet.querySelector(\".bridge-components-amount\").textContent = bridgeComponentsAmount\n\n const bridgeComponentIdentifiers = this.bridgeComponentIdentifiers\n const container = this.bottomSheet.querySelector(\".tab-content-bridge-components\")\n container.innerHTML = bridgeComponentsAmount\n ? this.state.supportedBridgeComponents.map((component) => `<div class=\"bridge-component ${bridgeComponentIdentifiers.includes(component) ? \"connected\" : \"\"}\">${component}</div>`).join(\"\")\n : `<div class=\"tab-empty-content d-flex flex-column text-center\"><span>${\"No bridge components found\"}</span></div>`\n }\n\n renderBridgeLogs() {\n const container = this.bottomSheet.querySelector(\".tab-content-bridge-logs\")\n container.innerHTML = this.state.bridgeLogs.length\n ? this.state.bridgeLogs.map((log) => this.bridgeLogHTML(log.direction, log.componentName, log.eventName, log.eventArgs, log.time)).join(\"\")\n : `<div class=\"tab-empty-content d-flex flex-column text-center\"><span>${\n this.state.bridgeIsConnected ? \"No bridge communication yet\" : \"Bridge is not connected <br><small>(Neither window.HotwireNative nor window.Strada is defined)</small>\"\n }</span></div>`\n }\n\n renderEvents() {\n const container = this.bottomSheet.querySelector(\".tab-content-event-logs\")\n container.innerHTML = this.state.eventLogs.length\n ? this.state.eventLogs.map((event) => this.eventMessageHTML(event.eventName, event.time)).join(\"\")\n : `<div class=\"tab-empty-content\"><span>No events captured yet</span></div>`\n }\n\n renderNativeStack() {\n const container = this.bottomSheet.querySelector(\".tab-content-native-stack\")\n container.innerHTML =\n `<div class=\"native-stack-wrapper\">` +\n (this.state.nativeStack.length ? this.state.nativeStack.map((view) => this.nativeViewStackHTML(view)).join(\"\") : `<div class=\"tab-empty-content\"><span>No native stack captured yet</span></div>`) +\n `</div>`\n }\n\n bridgeLogHTML(direction, componentName, eventName, eventArgs, time) {\n return `\n <div class=\"log-entry d-flex gap-3 pt-2 pb-2\">\n <div class=\"log-entry-icon d-flex justify-content-center align-items-center\">\n ${direction === \"send\" ? Icons.arrowDown : Icons.arrowUp}\n </div>\n <div class=\"w-100 overflow-auto\">\n <div class=\"d-flex justify-content-between\">\n <strong class=\"w-80 break-word\">${componentName}#${eventName}</strong>\n <small>${time}</small>\n </div>\n <div class=\"overflow-auto\">\n ${Object.entries(eventArgs)\n .map(([key, value]) => {\n const formattedValue = typeof value === \"object\" && value !== null ? JSON.stringify(value) : value\n return `<div class=\"white-space-collapse\">${key}: ${formattedValue}</div>`\n })\n .join(\"\")}\n </div>\n </div>\n </div>\n `\n }\n\n consoleLogHTML(type, message, time) {\n return `\n <div class=\"log-entry pt-2 pb-2\">\n <div class=\"w-100\">\n <div class=\"d-flex justify-content-end\">\n <small>${time}</small>\n </div>\n <div class=\"log-entry-message ${type}\">\n ${message}\n </div>\n </div>\n </div>\n `\n }\n\n eventMessageHTML(message, time) {\n return `\n <div class=\"log-entry pt-2 pb-2\">\n <div class=\"w-100\">\n <div class=\"d-flex justify-content-end\">\n <small>${time}</small>\n </div>\n <div class=\"log-entry-message\">\n ${message}\n </div>\n </div>\n </div>\n `\n }\n\n nativeViewStackHTML(view) {\n const removeTrailingSlash = (url) => {\n return url?.replace(/\\/+$/, \"\")\n }\n const isMainView = [\"UINavigationController\", \"NavigatorHost\"].includes(view.type)\n const isTabBar = view.type === \"UITabBarController\"\n const isHotwireView = [\"VisitableViewController\", \"HotwireWebFragment\", \"BackStackEntry\"].includes(view.type)\n const activeClass = removeTrailingSlash(view.url) === removeTrailingSlash(this.currentUrl) ? \"current-view\" : \"\"\n const wrapperClass = `viewstack-card ${activeClass} ${isMainView ? \"main-view\" : isHotwireView ? \"hotwire-view\" : isTabBar ? \"tab-container\" : \"non-identified-view\"}`\n const uniqueViewId = \"viewstack-\" + Math.random().toString(16).slice(2)\n\n const urlPath = view.url\n ? `<div class=\"view-url\">\n ${(() => {\n try {\n return new URL(view.url).pathname\n } catch (error) {\n return view.url\n }\n })()}\n </div>`\n : \"\"\n\n const pathConfigurationPropertiesJson = (() => {\n try {\n const props = view.pathConfigurationProperties\n return JSON.stringify(typeof props === \"string\" ? JSON.parse(props) : props, null, 2)\n } catch {\n return view.pathConfigurationProperties\n }\n })()\n const pathConfigurationProperties = pathConfigurationPropertiesJson ? `<pre class=\"view-path-configuration\">${pathConfigurationPropertiesJson}</pre>` : \"\"\n\n const childrenHTML = view.children?.length\n ? `<div class=\"child-container\">\n ${view.children.map((child) => this.nativeViewStackHTML(child)).join(\"\")}\n </div>`\n : \"\"\n\n return `\n <div>\n <div class=\"${wrapperClass} collapse no-chevron\" data-collapse-target=\"path-configuration-properties-${uniqueViewId}\">\n <div>\n <div class=\"view-title\">\n ${view.title == \"null\" ? \"\" : view.title}\n <div class=\"view-title-details\">${view.type}</div>\n </div>\n ${urlPath}\n </div>\n <div id=\"path-configuration-properties-${uniqueViewId}\" class=\"collapse-target\">\n ${pathConfigurationProperties}\n </div>\n </div>\n ${childrenHTML}\n </div>\n `\n }\n\n switchToSingleTabSheet(singleTabId) {\n // Hide the top part and all tabs\n this.sheetContent.querySelector(\".top-part\").classList.add(\"d-none\")\n this.devTools.shadowRoot.querySelectorAll(\".outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the single mode content\n this.devTools.shadowRoot.getElementById(singleTabId).classList.add(\"active\")\n }\n\n switchToMultiTabSheet() {\n this.sheetContent.querySelector(\".top-part\").classList.remove(\"d-none\")\n this.devTools.shadowRoot.querySelectorAll(\".outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the previous active tab\n this.devTools.shadowRoot.querySelectorAll(\".tablink, .outer-tab-content\").forEach((tab) => {\n if (tab.id == this.state.activeTab) {\n tab.classList.add(\"active\")\n }\n })\n }\n\n registerBridgeComponentExample() {\n switch (platform()) {\n case \"android\":\n return `\n<pre class=\"overflow-auto\">\n Hotwire.registerBridgeComponents(\n BridgeComponentFactory(\"my-component\", ::MyComponent)\n )\n</pre>\n`\n case \"ios\":\n return `\n<pre class=\"overflow-auto\">\n Hotwire.registerBridgeComponents([\n MyComponent.self\n ])\n</pre>`\n default:\n return \"\"\n }\n }\n\n registerBridgeComponentHelpURL() {\n switch (platform()) {\n case \"android\":\n return \"https://native.hotwired.dev/android/bridge-components\"\n case \"ios\":\n return \"https://native.hotwired.dev/ios/bridge-components\"\n default:\n return \"https://native.hotwired.dev\"\n }\n }\n\n checkNativeFeatures() {\n if (this.state.supportsNativeStackView) {\n this.bottomSheet.querySelector(\".tablink[data-tab-id='tab-native-stack']\").classList.remove(\"d-none\")\n }\n }\n\n addEventListeners() {\n if (this.bottomSheet.hasEventListeners) return\n\n // Click outside to close\n this.sheetOverlay.addEventListener(\"click\", () => {\n this.hideBottomSheet()\n this.switchToMultiTabSheet()\n })\n\n // Tab Click\n this.bottomSheet.querySelector(\".tablist\").addEventListener(\"click\", (event) => this.handleTabClick(event))\n\n // Action Buttons\n this.bottomSheet.querySelector(\".btn-clear-console-logs\").addEventListener(\"click\", () => {\n this.devTools.state.clearConsoleLogs()\n this.renderConsoleLogs()\n })\n this.bottomSheet.querySelector(\".btn-clear-bridge-logs\").addEventListener(\"click\", () => {\n this.devTools.state.clearBridgeLogs()\n this.renderBridgeLogs()\n })\n this.bottomSheet.querySelector(\".btn-clear-events\").addEventListener(\"click\", () => {\n this.devTools.state.clearEventLogs()\n this.renderEvents()\n })\n this.bottomSheet.querySelector(\".btn-reload-stack\").addEventListener(\"click\", () => {\n this.bottomSheet.querySelector(\".native-stack-wrapper\").style.opacity = 0.5\n this.devTools.refetchNativeStack()\n })\n\n // Switch to Single Tab Buttons\n this.bottomSheet.querySelectorAll(\".btn-switch-to-single-tab-sheet\").forEach((button) => {\n button.addEventListener(\"click\", (event) => {\n const singleTabId = event.target.closest(\"[data-tab-id]\").dataset.tabId\n if (!singleTabId) return\n this.switchToSingleTabSheet(singleTabId)\n })\n })\n\n // Close Single Tab Buttons\n this.bottomSheet.querySelectorAll(\".btn-close-single-mode\").forEach((button) => {\n button.addEventListener(\"click\", () => {\n this.switchToMultiTabSheet()\n })\n })\n\n // Dragging\n this.bottomSheet.querySelector(\".top-part\").addEventListener(\"touchstart\", this.dragStart.bind(this), { passive: true })\n this.bottomSheet.addEventListener(\"touchmove\", this.dragging.bind(this), { passive: true })\n this.bottomSheet.addEventListener(\"touchend\", this.dragStop.bind(this), { passive: true })\n\n // Filters\n this.bottomSheet.querySelector(\".console-filter-levels\").addEventListener(\"click\", ({ target }) => {\n const checkbox = target.closest(\"input[type='checkbox']\")\n if (!checkbox) return\n\n const filterType = checkbox.dataset.consoleFilter\n const isActive = checkbox.checked\n\n saveConsoleFilterLevels(filterType, isActive)\n this.renderConsoleLogs()\n })\n\n this.bottomSheet.querySelector(\".btn-search-console\").addEventListener(\"click\", () => {\n const searchInput = this.bottomSheet.querySelector(\".console-search\")\n searchInput.classList.toggle(\"d-none\")\n searchInput.querySelector(\"input\").focus()\n })\n\n this.bottomSheet.querySelector(\".console-search-input\").addEventListener(\"input\", (event) => {\n this.devTools.state.setConsoleSearchValue(event.target.value.toLowerCase())\n this.renderConsoleLogs()\n })\n\n // Settings\n this.bottomSheet.querySelector(\"#bottom-sheet-height-setting\").addEventListener(\"change\", (event) => {\n const value = event.target.value\n this.sheetHeight = parseInt(value)\n saveSettings(\"bottomSheetHeight\", value)\n this.updateSheetHeight(value)\n })\n\n this.bottomSheet.querySelector(\"#console-error-animation-setting\").addEventListener(\"change\", (event) => {\n saveSettings(\"errorAnimationEnabled\", event.target.checked)\n })\n\n this.bottomSheet.querySelector(\"#font-size-setting\").addEventListener(\"change\", (event) => {\n let value = event.target.value\n value = Math.max(8, Math.min(24, value))\n saveSettings(\"fontSize\", value)\n this.devTools.setCSSProperty(\"--font-size\", `${value}px`)\n })\n\n this.bottomSheet.querySelector(\"#auto-open-setting\").addEventListener(\"change\", (event) => {\n saveSettings(\"autoOpen\", event.target.checked)\n })\n\n this.bottomSheet.querySelector(\"#scroll-to-latest-log-setting\").addEventListener(\"change\", (event) => {\n saveSettings(\"scrollToLatestLog\", event.target.checked)\n })\n\n this.bottomSheet.querySelector(\".pin-bottom-sheet\").addEventListener(\"click\", () => {\n const isPinned = getSettings(\"bottomSheetPinned\") === true\n saveSettings(\"bottomSheetPinned\", !isPinned)\n this.sheetOverlay.classList.toggle(\"active\")\n this.bottomSheet.querySelector(\".settings-dropdown\").classList.remove(\"dropdown-open\")\n })\n\n this.bottomSheet.addEventListener(\"click\", (event) => {\n // Handle collapsible elements\n const collapsible = event.target.closest(\".collapse\")\n if (collapsible && this.bottomSheet.contains(collapsible)) {\n const targetId = collapsible.getAttribute(\"data-collapse-target\")\n const targetElement = this.bottomSheet.querySelector(`#${targetId}`)\n if (targetElement) {\n const isActive = collapsible.classList.toggle(\"active\")\n targetElement.classList.toggle(\"active\", isActive)\n }\n return\n }\n\n // Handle dropdown triggers\n const trigger = event.target.closest(\".dropdown-trigger\")\n if (trigger) {\n event.preventDefault()\n this.toggleDropdown(trigger)\n return\n }\n\n // Close dropdowns when clicking outside\n const openDropdowns = this.bottomSheet.querySelectorAll(\".dropdown-content.dropdown-open\")\n openDropdowns.forEach((dropdown) => {\n const dropdownContainer = dropdown.closest(\".dropdown\")\n if (!dropdownContainer.contains(event.target)) {\n dropdown.classList.remove(\"dropdown-open\")\n }\n })\n })\n\n this.bottomSheet.hasEventListeners = true\n }\n\n updateConsoleFilter(consoleFilterLevels) {\n this.bottomSheet.querySelectorAll(\".console-filter-levels input[type='checkbox']\").forEach((checkbox) => {\n const filterType = checkbox.dataset.consoleFilter\n const isActive = consoleFilterLevels[filterType]\n checkbox.checked = isActive\n })\n }\n\n toggleDropdown(triggerElement) {\n const dropdownContent = triggerElement.nextElementSibling || triggerElement.closest(\".dropdown\").querySelector(\".dropdown-content\")\n // Close other dropdowns first\n this.bottomSheet.querySelectorAll(\".dropdown-content.dropdown-open\").forEach((el) => {\n if (el !== dropdownContent) {\n el.classList.remove(\"dropdown-open\")\n }\n })\n dropdownContent.classList.toggle(\"dropdown-open\")\n }\n\n handleTabClick = (event) => {\n const clickedTab = event.target.closest(\".tablink\")\n if (!clickedTab) return\n\n const tabId = clickedTab.dataset.tabId\n this.devTools.state.setActiveTab(tabId)\n this.updateTabView(tabId)\n }\n\n updateTabView(tabId) {\n // Hide all Tabs\n this.devTools.shadowRoot.querySelectorAll(\".tablink, .outer-tab-content\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Hide all Action Bars\n this.devTools.shadowRoot.querySelectorAll(\".tab-action-bar\").forEach((tab) => tab.classList.remove(\"active\"))\n\n // Show the clicked tab\n this.devTools.shadowRoot.querySelector(`[data-tab-id=\"${tabId}\"]`).classList.add(\"active\")\n this.devTools.shadowRoot.getElementById(tabId).classList.add(\"active\")\n\n // Show the action bar for the clicked tab\n this.devTools.shadowRoot.querySelector(`.tab-action-bar.${tabId}`).classList.add(\"active\")\n\n // Scroll to the latest log in the clicked tab\n if (this.state.shouldScrollToLatestLog) {\n this.scrollToLatestLog(tabId)\n\n // Reset the flag to avoid scrolling on every tab switch without new logs\n this.state.shouldScrollToLatestLog = false\n }\n }\n\n scrollToLatestLog(tabId) {\n if (getSettings(\"scrollToLatestLog\") != true) return\n\n requestAnimationFrame(() => {\n const tabContainer = this.devTools.shadowRoot.getElementById(tabId)\n const latestLog = tabContainer?.querySelector(\".log-entry:last-child\")\n latestLog?.scrollIntoView({ behavior: \"instant\", block: \"center\" })\n })\n }\n\n showBottomSheet() {\n if (this.bottomSheet.classList.contains(\"show\")) return\n this.bottomSheet.classList.add(\"show\")\n this.originalOverflow = document.body.style.overflow\n document.body.style.overflow = \"hidden\"\n this.updateSheetHeight(this.sheetHeight)\n }\n\n hideBottomSheet() {\n this.bottomSheet.classList.remove(\"show\")\n document.body.style.overflow = this.originalOverflow\n }\n\n updateSheetHeight(height) {\n this.sheetContent.style.height = `${height}vh`\n this.bottomSheet.classList.toggle(\"fullscreen\", height === 100)\n }\n\n dragStart(event) {\n this.isDragging = true\n this.startY = event.pageY || event.touches?.[0].pageY\n this.startHeight = parseInt(this.sheetContent.style.height)\n this.bottomSheet.classList.add(\"dragging\")\n }\n\n dragging(event) {\n if (!this.isDragging) return\n const delta = this.startY - (event.pageY || event.touches?.[0].pageY)\n const newHeight = this.startHeight + (delta / window.innerHeight) * 100\n this.updateSheetHeight(newHeight)\n }\n\n dragStop() {\n this.isDragging = false\n this.bottomSheet.classList.remove(\"dragging\")\n const draggingThreshold = 10 // Defines how much the user needs to drag to trigger the hide/show\n const currentHeight = parseInt(this.sheetContent.style.height)\n\n const minThreshold = Math.max(0, this.sheetHeight - draggingThreshold)\n const maxThreshold = Math.min(100, this.sheetHeight + draggingThreshold)\n\n if (currentHeight < minThreshold) {\n this.hideBottomSheet()\n } else if (currentHeight > maxThreshold) {\n this.updateSheetHeight(100)\n } else {\n this.updateSheetHeight(this.sheetHeight)\n }\n }\n\n updateFontSize(value) {\n this.devTools.setCSSProperty(\"--font-size\", `${value}px`)\n this.bottomSheet.querySelector(\"#font-size-setting\").value = value\n }\n\n updateErrorAnimation(value) {\n this.bottomSheet.querySelector(\"#console-error-animation-setting\").checked = value\n }\n\n updateAutoOpen(value) {\n this.bottomSheet.querySelector(\"#auto-open-setting\").checked = value\n }\n\n // Helper function to log messages, without causing a rerender of the bottom sheet\n // (Messages with a `HotwireDevTools` prefix will not be logged in the bottom sheet)\n log(message) {\n console.log(`HotwireDevTools: ${message}`)\n }\n\n // Get all the `static component = \"...\"` from the bridge components\n get bridgeComponentIdentifiers() {\n return window.Stimulus?.controllers.map((controller) => controller.component).filter((component) => component !== undefined) || []\n }\n\n get currentUrl() {\n return window.location.href\n }\n}\n","import { getSettings, saveSettings } from \"../utils/settings\"\n\nexport default class DevToolsState {\n constructor() {\n this.state = {\n consoleLogs: [],\n bridgeLogs: [],\n eventLogs: [],\n nativeStack: [],\n supportedBridgeComponents: [],\n bridgeIsConnected: false,\n supportsNativeStackView: false,\n consoleSearch: \"\",\n activeTab: this.storedActiveTab,\n }\n this.listeners = []\n }\n\n subscribe(listener) {\n this.listeners.push(listener)\n }\n\n notify() {\n this.listeners.forEach((listener) => listener(this.state))\n }\n\n addConsoleLog(type, message) {\n const log = { type, message, time: this.currentTime }\n this.state.consoleLogs.push(log)\n this.notify()\n }\n\n addBridgeLog(direction, componentName, eventName, eventArgs) {\n const log = { direction, componentName, eventName, eventArgs, time: this.currentTime }\n this.state.bridgeLogs.push(log)\n this.notify()\n }\n\n addEventLog(eventName) {\n const event = { eventName, time: this.currentTime }\n this.state.eventLogs.push(event)\n this.notify()\n }\n\n setNativeStack(stack) {\n this.state.nativeStack = stack\n this.notify()\n }\n\n setSupportsNativeStack(supports) {\n this.state.supportsNativeStackView = supports\n this.notify()\n }\n\n setBridgeIsConnected(isConnected) {\n this.state.bridgeIsConnected = isConnected\n this.notify()\n }\n\n setSupportedBridgeComponents(components) {\n this.state.supportedBridgeComponents = components\n this.notify()\n }\n\n clearConsoleLogs() {\n this.state.consoleLogs = []\n this.notify()\n }\n\n clearBridgeLogs() {\n this.state.bridgeLogs = []\n this.notify()\n }\n\n clearEventLogs() {\n this.state.eventLogs = []\n this.notify()\n }\n\n setActiveTab(tab) {\n this.state.activeTab = tab\n saveSettings(\"activeTab\", tab)\n }\n\n setConsoleSearchValue(value) {\n this.state.consoleSearch = value\n }\n\n updateLocalStorageSettings() {\n this.state.activeTab = this.storedActiveTab\n }\n\n get currentTime() {\n return new Date().toLocaleTimeString()\n }\n\n get storedActiveTab() {\n return getSettings(\"activeTab\") || \"tab-bridge-components\"\n }\n}\n","/*\nSimilar to the `BridgeComponent` class from the Hotwire Native Bridge,\nbut without requiring a bridge component HTML element or Stimulus controller.\n\nOriginally from: 37signals LLC\nhttps://github.com/hotwired/hotwire-native-bridge\n*/\nexport default class NativeBridge {\n bridgeIsConnected() {\n return !!(window.HotwireNative?.web || window.Strada?.web)\n }\n\n // Send a message to the native side\n send(event, data = {}, callback = null) {\n if (!this.bridgeIsConnected()) {\n return Promise.reject(\"Bridge is not connected\")\n }\n\n const messageData = {\n ...data,\n metadata: {\n url: window.location.href,\n },\n }\n\n return this.bridge.send({\n component: \"dev-tools\",\n event,\n data: messageData,\n callback,\n })\n }\n\n isComponentSupported(component) {\n if (!this.bridgeIsConnected()) {\n return false\n }\n return this.bridge.supportsComponent(component)\n }\n\n getSupportedComponents() {\n return document.documentElement.dataset.bridgeComponents?.split(\" \") || []\n }\n\n get bridge() {\n return window.HotwireNative?.web || window.Strada?.web\n }\n}\n","import { cssContent } from \"./assets/DevToolsStyling.css\"\nimport DiagnosticsChecker from \"./lib/DiagnosticsChecker\"\nimport FloatingBubble from \"./components/FloatingBubble\"\nimport BottomSheet from \"./components/BottomSheet\"\nimport DevToolsState from \"./lib/DevToolsState\"\nimport NativeBridge from \"./lib/NativeBridge\"\nimport { resetSettings } from \"./utils/settings\"\nimport { debounce } from \"./utils/utils\"\nimport { getSettings } from \"./utils/settings\"\n\nexport default class DevTools {\n constructor(options = {}) {\n this.options = {\n enabled: true,\n reset: false,\n ...options,\n }\n if (!this.options.enabled) return\n if (this.options.reset) resetSettings()\n\n this.state = new DevToolsState()\n this.bubble = new FloatingBubble(this)\n this.bottomSheet = new BottomSheet(this)\n this.nativeBridge = new NativeBridge(this)\n this.diagnosticsChecker = new DiagnosticsChecker()\n this.state.subscribe(this.update.bind(this))\n this.listenForTurboEvents()\n }\n\n // Setup gets called initially and on every turbo:load event, eg. when navigating to a new page\n setup() {\n if (!this.options.enabled) return\n this.setupShadowRoot()\n this.bubble.render()\n this.bottomSheet.render()\n\n // Add Console Proxy\n if (!this.originalConsole) {\n this.originalConsole = window.console\n this.addConsoleProxy()\n }\n\n // Add Bridge Proxy and call the native DevTools bridge component\n if (this.originalBridge) {\n // Bridge Proxy is already added\n this.callNativeBridgeComponent()\n } else if (window.HotwireNative || window.Strada) {\n // Bridge exists -> Add Bridge Proxy\n this.nativeBridgeGotConnected()\n } else {\n // Bridge does not exist yet -> Listen for the event\n document.addEventListener(\"web-bridge:ready\", () => {\n this.nativeBridgeGotConnected()\n })\n }\n\n // Add event listeners to the window\n this.addEventListeners()\n\n // Check for warnings\n this.diagnosticsChecker.checkForWarnings()\n\n this.bubble.onClick(() => {\n this.bottomSheet.showBottomSheet()\n this.nativeBridge.send(\"vibrate\")\n })\n\n if (getSettings(\"autoOpen\") === true) {\n this.bottomSheet.showBottomSheet()\n }\n }\n\n nativeBridgeGotConnected() {\n if (this.originalBridge) return\n\n this.originalBridge = window.HotwireNative?.web || window.Strada?.web\n this.addBridgeProxy()\n this.state.setBridgeIsConnected(true)\n this.callNativeBridgeComponent()\n this.updateSupportedBridgeComponents()\n this.startBridgeComponentObserver()\n }\n\n callNativeBridgeComponent() {\n if (this.nativeBridge.bridgeIsConnected()) {\n this.nativeBridge.send(\"connect\", {}, (message) => {\n // If this callback gets executed, it means the native counterpart\n // of the dev tools are installed and running.\n this.fetchNativeStack()\n })\n }\n }\n\n update = debounce((newState) => {\n this.bottomSheet.update(newState)\n }, 200)\n\n setupShadowRoot() {\n if (this.shadowContainer.shadowRoot) {\n this.shadowRoot = this.shadowContainer.shadowRoot\n this.injectCSSToShadowRoot()\n return\n }\n this.shadowRoot = this.shadowContainer.attachShadow({ mode: \"open\" })\n this.setCSSProperty(\"--font-size\", `${getSettings(\"fontSize\") || 16}px`)\n this.injectCSSToShadowRoot()\n }\n\n addBridgeProxy() {\n const createProxyHandler = () => ({\n get: (target, prop, receiver) => {\n const originalValue = Reflect.get(target, prop, receiver)\n\n // We are only interested in the send and receive methods\n if (typeof originalValue === \"function\" && (prop === \"send\" || prop === \"receive\")) {\n return (...args) => {\n this.interceptedBridgeMessage(prop, args)\n return originalValue.apply(target, args)\n }\n }\n\n // Forward all the other calls to the original bridge\n return typeof originalValue === \"function\" ? (...args) => originalValue.apply(target, args) : originalValue\n },\n })\n\n if (window.Strada) {\n window.Strada.web = new Proxy(this.originalBridge, createProxyHandler())\n }\n if (window.HotwireNative) {\n window.HotwireNative.web = new Proxy(this.originalBridge, createProxyHandler())\n }\n }\n\n addConsoleProxy() {\n window.console = new Proxy(this.originalConsole, {\n get: (target, prop, receiver) => {\n const originalValue = Reflect.get(target, prop, receiver)\n return (...args) => {\n this.interceptedConsoleMessage(prop, args)\n return originalValue?.apply(target, args)\n }\n },\n })\n }\n\n interceptedBridgeMessage(direction, args) {\n args.forEach((arg) => {\n const componentName = arg.component\n const eventName = arg.event\n const { metadata, ...eventArgs } = arg.data // Remove metadata from the args\n\n if (componentName !== \"dev-tools\") {\n // We don't want to log our own messages\n this.state.addBridgeLog(direction, componentName, eventName, eventArgs)\n }\n })\n }\n\n interceptedConsoleMessage(type, args) {\n const message = args\n .map((arg) => {\n if (arg instanceof Element) {\n const attrs = Array.from(arg.attributes)\n .map((attr) => `${attr.name}=\"${attr.value}\"`)\n .join(\" \")\n\n return `&lt;${arg.tagName.toLowerCase()}${attrs ? \" \" + attrs : \"\"}&gt;&lt;/${arg.tagName.toLowerCase()}&gt;`\n }\n if (typeof arg === \"object\") {\n try {\n return `<pre>${JSON.stringify(arg, null, 2)}</pre>`\n } catch {\n return `<pre>${arg}</pre>`\n }\n }\n // Escape HTML in string values\n const stringValue = arg.toString()\n return stringValue.replace(/&/g, \"&amp;\").replace(/</g, \"&lt;\").replace(/>/g, \"&gt;\").replace(/\"/g, \"&quot;\").replace(/'/g, \"&#039;\")\n })\n .join(\" \")\n\n // Ignore messages from the dev tools itself\n // Otherwise we could end up in an infinite loop\n if (message.includes(\"hotwire-native-dev-tools\") || message.includes(\"HotwireDevTools\")) return\n\n this.state.addConsoleLog(type, message)\n if (type === \"error\") {\n this.bubble.animateErrorBorder()\n }\n }\n\n // Fetch the current stack from the native side\n // The debounce on this function is intentionally high,\n // to ensure the native side has enough time to set the ViewController / Fragment titles.\n // With a lower debounce, the view controller / fragment title would often be empty.\n fetchNativeStack = debounce(() => {\n this.nativeBridge.send(\"currentStackInfo\", {}, (message) => {\n this.state.setSupportsNativeStack(true)\n this.state.setNativeStack(message.data.stack)\n })\n }, 1000)\n\n refetchNativeStack() {\n this.nativeBridge.send(\"currentStackInfo\", {}, (message) => {\n this.state.setNativeStack(message.data.stack)\n })\n }\n\n injectCSSToShadowRoot = async () => {\n if (this.shadowRoot.querySelector(\"style\")) return\n\n const style = document.createElement(\"style\")\n style.textContent = cssContent()\n this.shadowRoot.appendChild(style)\n }\n\n addEventListeners() {\n if (this.hasEventListeners) return\n\n // Capture uncaught errors and unhandled promise rejections\n window.addEventListener(\"error\", (event) => {\n const { message, filename, lineno, colno } = event\n const formattedMessage = `${message} at ${filename}:${lineno}:${colno}`\n this.interceptedConsoleMessage(\"error\", [formattedMessage])\n })\n window.addEventListener(\"unhandledrejection\", (event) => {\n this.interceptedConsoleMessage(\"error\", [event.reason?.message])\n })\n\n // Observe screen size or orientation changes to reposition the bubble\n window.addEventListener(\n \"resize\",\n () => {\n this.bubble.render()\n },\n { passive: true }\n )\n\n // Listen for localStorage changes triggered by devtools in another (native) tab.\n // This keeps the devtools UI in sync across tabs.\n window.addEventListener(\"storage\", (event) => {\n if (event.key === \"hotwire-native-dev-tools\") {\n this.state.updateLocalStorageSettings()\n this.bubble.render()\n this.bottomSheet.update(this.state.state)\n this.bottomSheet.applySettingsFromStorage()\n }\n })\n\n this.hasEventListeners = true\n }\n\n listenForTurboEvents() {\n if (this.eventsRegistered) return\n\n const turboEvents = [\n \"turbo:click\",\n \"turbo:before-visit\",\n \"turbo:visit\",\n \"turbo:before-cache\",\n \"turbo:before-render\",\n \"turbo:render\",\n \"turbo:load\",\n \"turbo:morph\",\n \"turbo:before-morph-element\",\n \"turbo:before-morph-attribute\",\n \"turbo:morph-element\",\n \"turbo:submit-start\",\n \"turbo:submit-end\",\n \"turbo:before-frame-render\",\n \"turbo:frame-render\",\n \"turbo:frame-load\",\n \"turbo:frame-missing\",\n \"turbo:before-stream-render\",\n \"turbo:before-fetch-request\",\n \"turbo:before-fetch-response\",\n \"turbo:before-prefetch\",\n \"turbo:fetch-request-error\",\n ]\n\n turboEvents.forEach((eventName) => {\n window.addEventListener(\n eventName,\n (event) => {\n this.state.addEventLog(eventName)\n },\n { passive: true }\n )\n })\n\n this.eventsRegistered = true\n }\n\n startBridgeComponentObserver() {\n if (this.bridgeComponentObserver) return\n\n this.bridgeComponentObserver = new MutationObserver((mutationsList) => {\n for (const mutation of mutationsList) {\n if (mutation.type === \"attributes\" && mutation.attributeName === \"data-bridge-components\") {\n this.updateSupportedBridgeComponents()\n }\n }\n })\n\n this.bridgeComponentObserver.observe(document.documentElement, {\n attributes: true,\n attributeFilter: [\"data-bridge-components\"],\n })\n }\n\n updateSupportedBridgeComponents() {\n this.state.setSupportedBridgeComponents(this.nativeBridge.getSupportedComponents().sort())\n }\n\n getCSSProperty(propertyName) {\n const rootStyles = getComputedStyle(this.shadowContainer)\n return rootStyles.getPropertyValue(propertyName).trim()\n }\n\n setCSSProperty(propertyName, value) {\n this.shadowContainer.style.setProperty(propertyName, value)\n }\n\n get shadowContainer() {\n const existingShadowContainer = document.getElementById(\"hotwire-native-dev-tools-shadow-container\")\n if (existingShadowContainer) {\n return existingShadowContainer\n }\n const shadowContainer = document.createElement(\"div\")\n shadowContainer.id = \"hotwire-native-dev-tools-shadow-container\"\n shadowContainer.setAttribute(\"data-native-prevent-pull-to-refresh\", \"\")\n document.body.appendChild(shadowContainer)\n return shadowContainer\n }\n\n get currentTime() {\n return new Date().toLocaleTimeString()\n }\n}\n","import DevTools from \"./DevTools\"\n\nconst setupDevTools = (options = {}) => {\n const devTools = new DevTools(options)\n if (!devTools.options.enabled) return\n\n devTools.setup()\n\n document.addEventListener(\n \"turbo:load\",\n () => {\n devTools.setup()\n },\n { passive: true }\n )\n}\n\nexport { setupDevTools }\n"],"names":["cssContent","_checkForTurboDrive","_checkForDuplicatedTurboFrames","_checkTurboPermanentElements","DiagnosticsChecker","__publicField","message","once","extraArgs","__privateGet","__privateAdd","_a","turboFramesIds","id","index","turboPermanentElements","element","turboFrame","getSettings","key","saveSettings","value","settings","resetSettings","getConsoleFilterLevels","saveConsoleFilterLevels","consoleFilterLevels","debounce","fn","delay","timeoutId","args","callback","this","userAgent","isIosApp","isAndroidApp","platform","formattedPlatform","getMetaElement","name","getMetaContent","hotwireIcon","arrowUp","arrowDown","arrowLeft","trash","rotate","questionMark","search","filter","threeDotsVertical","FloatingBubble","devTools","errorBorder","circleElement","animationContainer","defaultPos","startX","startY","existingBubble","event","touch","deltaX","deltaY","xPos","yPos","BottomSheet","clickedTab","tabId","newState","setter","storedValue","storedConsoleFilterLevels","existingBottomSheet","activeTab","consoleSearch","Icons.threeDotsVertical","Icons.trash","Icons.search","Icons.filter","Icons.rotate","Icons.questionMark","Icons.arrowLeft","container","log","bridgeComponentsAmount","bridgeComponentIdentifiers","component","view","direction","componentName","eventName","eventArgs","time","Icons.arrowDown","Icons.arrowUp","formattedValue","type","removeTrailingSlash","url","isMainView","isTabBar","isHotwireView","wrapperClass","uniqueViewId","urlPath","pathConfigurationPropertiesJson","props","pathConfigurationProperties","childrenHTML","child","singleTabId","tab","button","target","checkbox","filterType","isActive","searchInput","isPinned","collapsible","targetId","targetElement","trigger","dropdown","triggerElement","dropdownContent","el","tabContainer","latestLog","height","delta","newHeight","draggingThreshold","currentHeight","minThreshold","maxThreshold","controller","DevToolsState","listener","stack","supports","isConnected","components","NativeBridge","_b","data","messageData","DevTools","options","style","createProxyHandler","prop","receiver","originalValue","arg","metadata","attrs","attr","filename","lineno","colno","formattedMessage","mutationsList","mutation","propertyName","existingShadowContainer","shadowContainer","setupDevTools"],"mappings":";;;;;;;AAGO,MAAMA,IAAa,MACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAJT,IAAAC,GAAAC,GAAAC;ACAe,MAAMC,EAAmB;AAAA,E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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hotwire-native-dev-tools",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Dev Tools for Hotwire Native",
5
5
  "main": "./dist/hotwire-native-dev-tools.es.js",
6
6
  "module": "./dist/hotwire-native-dev-tools.es.js",