hotwire-native-dev-tools 0.2.0 → 0.3.1

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,11 +1,4 @@
1
- var F = Object.defineProperty;
2
- var T = (i) => {
3
- throw TypeError(i);
4
- };
5
- var q = (i, t, e) => t in i ? F(i, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : i[t] = e;
6
- var d = (i, t, e) => q(i, typeof t != "symbol" ? t + "" : t, e), A = (i, t, e) => t.has(i) || T("Cannot " + e);
7
- var g = (i, t, e) => (A(i, t, "read from private field"), e ? e.call(i) : t.get(i)), p = (i, t, e) => t.has(i) ? T("Cannot add the same private member more than once") : t instanceof WeakSet ? t.add(i) : t.set(i, e);
8
- const M = () => `
1
+ const T = () => `
9
2
  :host {
10
3
  all: initial;
11
4
  font-family: system-ui, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol" !important;
@@ -65,6 +58,13 @@ const M = () => `
65
58
  fill: white;
66
59
  }
67
60
 
61
+ .icon--black svg {
62
+ fill: black;
63
+ }
64
+ .icon--muted svg {
65
+ fill: #6c6c6c;
66
+ }
67
+
68
68
  /* Dropdown */
69
69
  .dropdown-content {
70
70
  display: none;
@@ -103,10 +103,20 @@ const M = () => `
103
103
  align-items: center;
104
104
  }
105
105
 
106
- .dropdown-content button:not(:first-child) {
106
+ .dropdown-content .dropdown-btn-full-width:not(:first-child),
107
+ .dropdown-content .dropdown-entry:not(:first-child) {
107
108
  border-top: 1px solid #cecdcd;
108
109
  }
109
110
 
111
+ .dropdown--right .dropdown-content {
112
+ right: 1em;
113
+ }
114
+
115
+ .dropdown--scrollable .dropdown-content {
116
+ overflow-y: auto;
117
+ max-height: 100%;
118
+ }
119
+
110
120
  .settings-dropdown {
111
121
  right: 0;
112
122
  top: 2rem;
@@ -604,6 +614,10 @@ const M = () => `
604
614
  text-align: center;
605
615
  }
606
616
 
617
+ .text-muted {
618
+ color: #6c6c6c;
619
+ }
620
+
607
621
  .text-ellipsis {
608
622
  text-overflow: ellipsis;
609
623
  white-space: nowrap;
@@ -707,73 +721,73 @@ const M = () => `
707
721
  width: 100%;
708
722
  }
709
723
 
724
+ .w-auto {
725
+ width: auto !important;
726
+ }
727
+
710
728
  .w-80 {
711
729
  width: 80%;
712
730
  }
713
731
  `;
714
- var v, f, w;
715
- class H {
732
+ class B {
716
733
  constructor() {
717
- d(this, "printWarning", (t, e = !0, ...o) => {
718
- e && this.printedWarnings.includes(t) || (console.warn(`DevTools: ${t}`, ...o), this.printedWarnings.push(t));
719
- });
720
- d(this, "checkForWarnings", () => {
721
- g(this, v).call(this), g(this, f).call(this), g(this, w).call(this);
722
- });
723
- p(this, v, () => {
724
- var t;
725
- window.Turbo ? ((t = window.Turbo) == null ? void 0 : t.session.drive) === !1 && setTimeout(() => {
726
- var e;
727
- ((e = window.Turbo) == null ? void 0 : e.session.drive) === !1 && this.printWarning("Turbo Drive is disabled. Hotwire Native will not work correctly without Turbo Drive");
728
- }, 1e3) : setTimeout(() => {
729
- window.Turbo || this.printWarning("Turbo is not detected. Hotwire Native will not work correctly without Turbo");
730
- }, 1e3);
731
- });
732
- p(this, f, () => {
733
- const t = this.turboFrameIds;
734
- t.filter((o, s) => t.indexOf(o) !== s).forEach((o) => {
735
- this.printWarning(`Multiple Turbo Frames with the same ID '${o}' detected. This can cause unexpected behavior. Ensure that each Turbo Frame has a unique ID.`);
736
- });
737
- });
738
- p(this, w, () => {
739
- const t = document.querySelectorAll("[data-turbo-permanent]");
740
- t.length !== 0 && t.forEach((e) => {
741
- const o = e.id;
742
- if (o === "" && this.printWarning("Turbo Permanent Element detected without an ID. Turbo Permanent Elements must have a unique ID to work correctly.", !0, e), o && document.querySelectorAll(`#${o}`).length > 1) {
743
- const n = `Turbo Permanent Element with ID '${o}' doesn't have a unique ID. Turbo Permanent Elements must have a unique ID to work correctly.`;
744
- this.printWarning(n, !0, e);
745
- }
746
- });
747
- });
748
734
  this.printedWarnings = [];
749
735
  }
736
+ printWarning = (t, e = !0, ...o) => {
737
+ e && this.printedWarnings.includes(t) || (console.warn(`DevTools: ${t}`, ...o), this.printedWarnings.push(t));
738
+ };
739
+ checkForWarnings = () => {
740
+ this.#t(), this.#e();
741
+ };
742
+ #t = () => {
743
+ const t = this.turboFrameIds;
744
+ t.filter((o, s) => t.indexOf(o) !== s).forEach((o) => {
745
+ this.printWarning(`Multiple Turbo Frames with the same ID '${o}' detected. This can cause unexpected behavior. Ensure that each Turbo Frame has a unique ID.`);
746
+ });
747
+ };
748
+ #e = () => {
749
+ const t = document.querySelectorAll("[data-turbo-permanent]");
750
+ t.length !== 0 && t.forEach((e) => {
751
+ const o = e.id;
752
+ if (o === "" && this.printWarning("Turbo Permanent Element detected without an ID. Turbo Permanent Elements must have a unique ID to work correctly.", !0, e), o && document.querySelectorAll(`#${o}`).length > 1) {
753
+ const n = `Turbo Permanent Element with ID '${o}' doesn't have a unique ID. Turbo Permanent Elements must have a unique ID to work correctly.`;
754
+ this.printWarning(n, !0, e);
755
+ }
756
+ });
757
+ };
750
758
  get turboFrameIds() {
751
759
  return Array.from(document.querySelectorAll("turbo-frame")).map((t) => t.id);
752
760
  }
753
761
  }
754
- v = new WeakMap(), f = new WeakMap(), w = new WeakMap();
755
- const a = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") || "{}")[i], h = (i, t) => {
762
+ const c = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") || "{}")[i], l = (i, t) => {
756
763
  let e = JSON.parse(localStorage.getItem("hotwire-native-dev-tools") || "{}");
757
764
  e[i] = t, localStorage.setItem("hotwire-native-dev-tools", JSON.stringify(e));
758
- }, z = () => {
765
+ }, $ = () => {
759
766
  localStorage.removeItem("hotwire-native-dev-tools");
760
- }, u = () => a("consoleFilterLevels") || {
767
+ }, u = () => c("consoleFilterLevels") || {
761
768
  warn: !0,
762
769
  error: !0,
763
770
  debug: !0,
764
771
  info: !0,
765
772
  log: !0
766
- }, N = (i, t) => {
773
+ }, I = (i, t) => {
767
774
  const e = u();
768
- return e[i] = t, h("consoleFilterLevels", e), e;
769
- }, m = (i, t) => {
775
+ return e[i] = t, l("consoleFilterLevels", e), e;
776
+ }, m = () => c("consoleLogBlacklist") || [], F = (i) => {
777
+ i = i.trim();
778
+ const t = c("consoleLogBlacklist") || [];
779
+ return t.includes(i) || (t.push(i), l("consoleLogBlacklist", t)), t;
780
+ }, q = (i) => {
781
+ let t = c("consoleLogBlacklist") || [];
782
+ return t = t.filter((e) => e !== i), l("consoleLogBlacklist", t), t;
783
+ }, g = (i, t) => {
770
784
  let e = null;
771
785
  return (...o) => {
772
786
  const s = () => i.apply(void 0, o);
773
787
  clearTimeout(e), e = setTimeout(s, t);
774
788
  };
775
- }, { userAgent: E } = window.navigator, D = /iOS/.test(E), P = /Android/.test(E), L = () => D ? "ios" : P ? "android" : "unknown", O = () => {
776
- switch (L()) {
789
+ }, { userAgent: k } = window.navigator, L = /iOS/.test(k), M = /Android/.test(k), f = () => L ? "ios" : M ? "android" : "unknown", A = () => {
790
+ switch (f()) {
777
791
  case "android":
778
792
  return "Android";
779
793
  case "ios":
@@ -781,10 +795,13 @@ const a = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") ||
781
795
  default:
782
796
  return "<unknown>";
783
797
  }
784
- }, R = (i) => document.querySelector(`meta[name="${i}"]`), y = (i) => {
785
- const t = R(i);
798
+ }, H = (i) => document.querySelector(`meta[name="${i}"]`), v = (i) => {
799
+ const t = H(i);
786
800
  return t && t.content;
787
- }, j = `
801
+ }, y = (i) => {
802
+ const t = Array.from(i.attributes).map((e) => `${e.name}="${e.value}"`).join(" ");
803
+ return `&lt;${i.tagName.toLowerCase()}${t ? " " + t : ""}&gt;&lt;/${i.tagName.toLowerCase()}&gt;`;
804
+ }, z = `
788
805
  <svg width="100%" height="100%" viewBox="0 0 294 320">
789
806
  <g transform="matrix(1,0,0,1,-28.38,-15.268)">
790
807
  <g transform="matrix(1,0,0,1,-462.157,-144.417)">
@@ -792,95 +809,76 @@ const a = (i) => JSON.parse(localStorage.getItem("hotwire-native-dev-tools") ||
792
809
  </g>
793
810
  </g>
794
811
  </svg>
795
- `, V = `
812
+ `, N = `
796
813
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
797
814
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
798
815
  <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"/>
799
816
  </svg>
800
- `, Y = `
817
+ `, P = `
801
818
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
802
819
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
803
820
  <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"/>
804
821
  </svg>
805
- `, S = `
822
+ `, b = `
806
823
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
807
824
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
808
825
  <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"/>
809
826
  </svg>
810
- `, k = `
827
+ `, p = `
811
828
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
812
829
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
813
830
  <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"/>
814
831
  </svg>
815
- `, W = `
832
+ `, D = `
816
833
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
817
834
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
818
835
  <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"/>
819
836
  </svg>
820
- `, U = `
837
+ `, O = `
821
838
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
822
839
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
823
840
  <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"/>
824
841
  </svg>
825
- `, X = `
842
+ `, j = `
826
843
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
827
844
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
828
845
  <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"/>
829
846
  </svg>
830
- `, J = `
847
+ `, R = `
831
848
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
832
849
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
833
850
  <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"/>
834
851
  </svg>
835
- `, G = `
852
+ `, S = `
836
853
  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 128 512">
837
854
  <!--!Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
838
855
  <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"/>
839
856
  </svg>
857
+ `, V = `
858
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640">
859
+ <!--!Font Awesome Free 7.0.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.-->
860
+ <path d="M431.2 476.5L163.5 208.8C141.1 240.2 128 278.6 128 320C128 426 214 512 320 512C361.5 512 399.9 498.9 431.2 476.5zM476.5 431.2C498.9 399.8 512 361.4 512 320C512 214 426 128 320 128C278.5 128 240.1 141.1 208.8 163.5L476.5 431.2zM64 320C64 178.6 178.6 64 320 64C461.4 64 576 178.6 576 320C576 461.4 461.4 576 320 576C178.6 576 64 461.4 64 320z"/>
861
+ </svg>
840
862
  `;
841
- class K {
863
+ class Y {
842
864
  constructor(t) {
843
- d(this, "render", m(() => {
844
- this.setPosition(), this.createDragItem(), this.setTranslate(this.initialX, this.initialY, this.dragItem), this.addEventListeners();
845
- }, 50));
846
- d(this, "animateErrorBorder", m(() => {
847
- if (!this.dragItem || a("errorAnimationEnabled") === !1) return;
848
- let t = this.dragItem.querySelector(".error-border"), e = this.dragItem.querySelector(".error-border circle");
849
- t && t.remove();
850
- const o = document.createElement("div");
851
- o.className = "animation-container", o.innerHTML = `
852
- <svg viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg" class="error-border">
853
- <defs>
854
- <linearGradient id="errorGradient" gradientTransform="rotate(45)">
855
- <stop offset="0%" stop-color="#e4241a" />
856
- <stop offset="50%" stop-color="#dd1f15" />
857
- <stop offset="100%" stop-color="#f6160a" />
858
- </linearGradient>
859
- </defs>
860
- <circle cx="90" cy="90" r="90" fill="none" stroke="url(#errorGradient)" stroke-width="21"
861
- stroke-dasharray="565" stroke-dashoffset="565" stroke-linecap="round" />
862
- </svg>
863
- `, this.dragItem.appendChild(o), e = this.dragItem.querySelector(".error-border circle"), e.classList.add("animate"), setTimeout(() => {
864
- o.classList.add("fade-out");
865
- }, 1300), setTimeout(() => {
866
- o && o.parentNode && o.remove();
867
- }, 1800);
868
- }, 100));
869
865
  this.devTools = t, this.bubbleSize = 4.75 * 16 + 0.3 * 16, this.minVisible = this.bubbleSize * 0.5, this.currentlyDragging = !1;
870
866
  }
867
+ render = g(() => {
868
+ this.setPosition(), this.createDragItem(), this.setTranslate(this.initialX, this.initialY, this.dragItem), this.addEventListeners();
869
+ }, 50);
871
870
  setPosition() {
872
871
  this.settingKey = window.innerWidth < window.innerHeight ? "bubblePosPortrait" : "bubblePosLandscape";
873
- const t = { x: window.innerWidth - 100, y: window.innerHeight - 100 }, { x: e, y: o } = a(this.settingKey) || t;
872
+ const t = { x: window.innerWidth - 100, y: window.innerHeight - 100 }, { x: e, y: o } = c(this.settingKey) || t;
874
873
  this.currentX = this.initialX = this.xOffset = e, this.currentY = this.initialY = this.yOffset = o;
875
874
  }
876
875
  createDragItem() {
877
- var e;
878
- const t = (e = this.devTools.shadowRoot) == null ? void 0 : e.getElementById("floating-bubble");
876
+ const t = this.devTools.shadowRoot?.getElementById("floating-bubble");
879
877
  if (t) {
880
878
  this.dragItem = t;
881
879
  return;
882
880
  }
883
- this.dragItem = document.createElement("div"), this.dragItem.id = "floating-bubble", this.dragItem.innerHTML = j, this.devTools.shadowRoot.appendChild(this.dragItem);
881
+ this.dragItem = document.createElement("div"), this.dragItem.id = "floating-bubble", this.dragItem.innerHTML = z, this.devTools.shadowRoot.appendChild(this.dragItem);
884
882
  }
885
883
  addEventListeners() {
886
884
  this.dragItem.hasEventListeners || (this.dragItem.addEventListener("click", this.click.bind(this), { passive: !0 }), this.dragItem.addEventListener("touchstart", this.dragStart.bind(this), { passive: !0 }), this.dragItem.addEventListener("touchend", this.dragEnd.bind(this), { passive: !0 }), this.dragItem.addEventListener("touchmove", this.drag.bind(this), { passive: !0 }), this.dragItem.hasEventListeners = !0);
@@ -888,6 +886,29 @@ class K {
888
886
  click(t) {
889
887
  this.clickCallback && this.clickCallback(t);
890
888
  }
889
+ animateErrorBorder = g(() => {
890
+ if (!this.dragItem || c("errorAnimationEnabled") === !1) return;
891
+ let t = this.dragItem.querySelector(".error-border"), e = this.dragItem.querySelector(".error-border circle");
892
+ t && t.remove();
893
+ const o = document.createElement("div");
894
+ o.className = "animation-container", o.innerHTML = `
895
+ <svg viewBox="0 0 180 180" xmlns="http://www.w3.org/2000/svg" class="error-border">
896
+ <defs>
897
+ <linearGradient id="errorGradient" gradientTransform="rotate(45)">
898
+ <stop offset="0%" stop-color="#e4241a" />
899
+ <stop offset="50%" stop-color="#dd1f15" />
900
+ <stop offset="100%" stop-color="#f6160a" />
901
+ </linearGradient>
902
+ </defs>
903
+ <circle cx="90" cy="90" r="90" fill="none" stroke="url(#errorGradient)" stroke-width="21"
904
+ stroke-dasharray="565" stroke-dashoffset="565" stroke-linecap="round" />
905
+ </svg>
906
+ `, this.dragItem.appendChild(o), e = this.dragItem.querySelector(".error-border circle"), e.classList.add("animate"), setTimeout(() => {
907
+ o.classList.add("fade-out");
908
+ }, 1300), setTimeout(() => {
909
+ o && o.parentNode && o.remove();
910
+ }, 1800);
911
+ }, 100);
891
912
  onClick(t) {
892
913
  this.clickCallback = t;
893
914
  }
@@ -895,7 +916,7 @@ class K {
895
916
  t.target.closest("#floating-bubble") && (this.currentlyDragging = !0, this.initialX = t.touches[0].clientX - this.xOffset, this.initialY = t.touches[0].clientY - this.yOffset);
896
917
  }
897
918
  dragEnd() {
898
- this.initialX = this.currentX, this.initialY = this.currentY, this.currentlyDragging = !1, h(this.settingKey, { x: this.currentX, y: this.currentY });
919
+ this.initialX = this.currentX, this.initialY = this.currentY, this.currentlyDragging = !1, l(this.settingKey, { x: this.currentX, y: this.currentY });
899
920
  }
900
921
  drag(t) {
901
922
  if (!this.currentlyDragging) return;
@@ -908,15 +929,9 @@ class K {
908
929
  o.style.transform = `translate3d(${t}px, ${e}px, 0)`;
909
930
  }
910
931
  }
911
- class Z {
932
+ class U {
912
933
  constructor(t) {
913
- d(this, "handleTabClick", (t) => {
914
- const e = t.target.closest(".tablink");
915
- if (!e) return;
916
- const o = e.dataset.tabId;
917
- this.devTools.state.setActiveTab(o), this.updateTabView(o);
918
- });
919
- this.devTools = t, this.state = t.state.state, this.sheetHeight = parseInt(a("bottomSheetHeight")) || 55;
934
+ this.devTools = t, this.state = t.state.state, this.sheetHeight = parseInt(c("bottomSheetHeight")) || 55;
920
935
  }
921
936
  render() {
922
937
  this.createBottomSheet(), this.sheetContent = this.bottomSheet.querySelector(".content"), this.sheetOverlay = this.bottomSheet.querySelector(".sheet-overlay"), this.addEventListeners();
@@ -924,7 +939,7 @@ class Z {
924
939
  // Called when the in-memory state changes,
925
940
  // such as when a new console or bridge log is captured.
926
941
  update(t) {
927
- this.state = t, this.checkNativeFeatures(), this.renderConsoleLogs(), this.renderBridgeComponents(), this.renderBridgeLogs(), this.renderEvents(), this.renderNativeStack(), this.scrollToLatestLog(this.state.activeTab), this.state.shouldScrollToLatestLog = !0;
942
+ this.state = t, this.checkNativeFeatures(), this.renderConsoleLogs(), this.renderBridgeComponents(), this.renderBridgeLogs(), this.renderEvents(), this.renderNativeStack(), this.renderInfos(), this.scrollToLatestLog(this.state.activeTab), this.state.shouldScrollToLatestLog = !0;
928
943
  }
929
944
  // Called when another native tab of the mobile app
930
945
  // updates devtools-related local storage.
@@ -936,22 +951,21 @@ class Z {
936
951
  { key: "errorAnimationEnabled", setter: (o) => this.updateErrorAnimation(o) },
937
952
  { key: "autoOpen", setter: (o) => this.updateAutoOpen(o) }
938
953
  ].forEach(({ key: o, setter: s }) => {
939
- const n = a(o);
954
+ const n = c(o);
940
955
  n !== void 0 && s(n);
941
956
  });
942
957
  const e = u();
943
958
  e && this.updateConsoleFilter(e);
944
959
  }
945
960
  createBottomSheet() {
946
- var n;
947
- const t = (n = this.devTools.shadowRoot) == null ? void 0 : n.querySelector(".bottom-sheet");
961
+ const t = this.devTools.shadowRoot?.querySelector(".bottom-sheet");
948
962
  if (t) {
949
963
  this.bottomSheet = t;
950
964
  return;
951
965
  }
952
966
  const e = this.state.activeTab, o = u(), s = this.state.consoleSearch;
953
967
  this.bottomSheet = document.createElement("div"), this.bottomSheet.classList.add("bottom-sheet"), this.bottomSheet.innerHTML = `
954
- <div class="sheet-overlay ${a("bottomSheetPinned") === !0 ? "" : "active"}"></div>
968
+ <div class="sheet-overlay ${c("bottomSheetPinned") === !0 ? "" : "active"}"></div>
955
969
  <div class="content">
956
970
  <div class="top-part">
957
971
  <div class="tablist">
@@ -960,24 +974,25 @@ class Z {
960
974
  <button class="tablink ${e === "tab-event-logs" ? "active" : ""}" data-tab-id="tab-event-logs">Events</button>
961
975
  <button class="tablink ${e === "tab-native-stack" ? "active" : ""} d-none" data-tab-id="tab-native-stack">Stack</button>
962
976
  <div class="tablink-settings dropdown d-flex">
963
- <button class="dropdown-trigger tablink-dropdown">${G}</button>
977
+ <button class="dropdown-trigger tablink-dropdown">${S}</button>
964
978
  <div class="dropdown-content settings-dropdown">
965
- <button class="btn-switch-to-single-tab-sheet" data-tab-id="single-tab-settings">Settings</button>
966
- <button class="btn-switch-to-single-tab-sheet" data-tab-id="single-tab-info">Info</button>
967
- <button class="pin-bottom-sheet">Pin Bottom Sheet</button>
979
+ <button class="dropdown-btn-full-width btn-switch-to-single-tab-sheet" data-tab-id="single-tab-settings">Settings</button>
980
+ <button class="dropdown-btn-full-width btn-switch-to-single-tab-sheet" data-tab-id="single-tab-info">Info</button>
981
+ <button class="dropdown-btn-full-width btn-switch-to-single-tab-sheet d-none" data-tab-id="single-tab-path-configuration-check">PathConfiguration Check</button>
982
+ <button class="dropdown-btn-full-width pin-bottom-sheet">Pin Bottom Sheet</button>
968
983
  </div>
969
984
  </div>
970
985
  </div>
971
986
 
972
987
  <div class="tab-action-bars">
973
988
  <div class="tab-action-bar tab-bridge-components ${e === "tab-bridge-components" ? "active" : ""}">
974
- <button class="btn-icon btn-clear-tab btn-clear-bridge-logs">${k}</button>
989
+ <button class="btn-icon btn-clear-tab btn-clear-bridge-logs">${p}</button>
975
990
  </div>
976
991
  <div class="tab-action-bar d-flex flex-column tab-console-logs ${e === "tab-console-logs" ? "active" : ""}">
977
992
  <div class="d-flex">
978
- <button class="btn-icon btn-search-console">${X}</button>
993
+ <button class="btn-icon btn-search-console">${j}</button>
979
994
  <div class="dropdown">
980
- <button class="dropdown-trigger btn-icon">${J}</button>
995
+ <button class="dropdown-trigger btn-icon">${R}</button>
981
996
  <div class="dropdown-content console-filter-levels">
982
997
  <label><input type="checkbox" ${o.warn ? "checked" : ""} data-console-filter="warn" /> Warnings</label>
983
998
  <label><input type="checkbox" ${o.error ? "checked" : ""} data-console-filter="error" /> Errors</label>
@@ -986,7 +1001,12 @@ class Z {
986
1001
  <label><input type="checkbox" ${o.log ? "checked" : ""} data-console-filter="log" /> Logs</label>
987
1002
  </div>
988
1003
  </div>
989
- <button class="btn-icon btn-clear-tab btn-clear-console-logs">${k}</button>
1004
+ <div class="dropdown dropdown--scrollable">
1005
+ <button class="dropdown-trigger btn-icon">${V}</button>
1006
+ <div class="dropdown-content console-log-blacklist">
1007
+ </div>
1008
+ </div>
1009
+ <button class="btn-icon btn-clear-tab btn-clear-console-logs">${p}</button>
990
1010
  </div>
991
1011
 
992
1012
  <div class="console-search mt-2 ${s ? "" : "d-none"}">
@@ -994,10 +1014,10 @@ class Z {
994
1014
  </div>
995
1015
  </div>
996
1016
  <div class="tab-action-bar tab-event-logs ${e === "tab-event-logs" ? "active" : ""}">
997
- <button class="btn-icon btn-clear-tab btn-clear-events">${k}</button>
1017
+ <button class="btn-icon btn-clear-tab btn-clear-events">${p}</button>
998
1018
  </div>
999
1019
  <div class="tab-action-bar tab-native-stack ${e === "tab-native-stack" ? "active" : ""}">
1000
- <button class="btn-icon btn-reload-tab btn-reload-stack">${W}</button>
1020
+ <button class="btn-icon btn-reload-tab btn-reload-stack">${D}</button>
1001
1021
  </div>
1002
1022
  </div>
1003
1023
  </div>
@@ -1011,7 +1031,7 @@ class Z {
1011
1031
  <div id="bridge-components-collapse" class="collapse-target">
1012
1032
  <div class="d-flex justify-content-between border-bottom">
1013
1033
  <div class="tab-content-bridge-components flex-grow-1"></div>
1014
- <button class="btn-icon btn-help btn-switch-to-single-tab-sheet mt-1" data-tab-id="single-tab-bridge-component-help">${U}</button>
1034
+ <button class="btn-icon btn-help btn-switch-to-single-tab-sheet mt-1" data-tab-id="single-tab-bridge-component-help">${O}</button>
1015
1035
  </div>
1016
1036
  </div>
1017
1037
 
@@ -1038,10 +1058,10 @@ class Z {
1038
1058
  <div id="single-tab-bridge-component-help" class="single-tab-content outer-tab-content">
1039
1059
  <div class="inner-tab-content">
1040
1060
  <div class="d-flex align-items-center mb-3">
1041
- <button class="btn-icon btn-close-single-mode">${S}</button>
1061
+ <button class="btn-icon btn-close-single-mode">${b}</button>
1042
1062
  <h3 class="ms-1">Bridge Components</h3>
1043
1063
  </div>
1044
- <p>This list shows all the bridge components that the ${O()} app supports. Components that are active on this page are marked with a green dot.</p>
1064
+ <p>This list shows all the bridge components that the ${A()} app supports. Components that are active on this page are marked with a green dot.</p>
1045
1065
  <h3 class="mt-4">Why is my bridge component not on the list?</h3>
1046
1066
  <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>
1047
1067
  ${this.registerBridgeComponentExample()}
@@ -1053,7 +1073,7 @@ class Z {
1053
1073
  <div id="single-tab-settings" class="single-tab-content outer-tab-content">
1054
1074
  <div class="inner-tab-content">
1055
1075
  <div class="d-flex align-items-center mb-3">
1056
- <button class="btn-icon btn-close-single-mode">${S}</button>
1076
+ <button class="btn-icon btn-close-single-mode">${b}</button>
1057
1077
  <h3 class="ms-1">Settings</h3>
1058
1078
  </div>
1059
1079
  <div class="mb-3">
@@ -1065,28 +1085,28 @@ class Z {
1065
1085
  </div>
1066
1086
  <div class="mb-4">
1067
1087
  <label for="font-size-setting"> Font Size</label>
1068
- <input type="range" id="font-size-setting" class="w-100" min="8" max="24" value="${a("fontSize") || 16}" step="1" list="font-size-setting-markers" />
1088
+ <input type="range" id="font-size-setting" class="w-100" min="8" max="24" value="${c("fontSize") || 16}" step="1" list="font-size-setting-markers" />
1069
1089
  <datalist id="font-size-setting-markers">
1070
1090
  <option value="16"></option>
1071
1091
  </datalist>
1072
1092
  </div>
1073
1093
  <div class="mb-3">
1074
1094
  <label class="toggle">
1075
- <input class="toggle-checkbox" type="checkbox" id="console-error-animation-setting" ${a("errorAnimationEnabled") !== !1 ? "checked" : ""} />
1095
+ <input class="toggle-checkbox" type="checkbox" id="console-error-animation-setting" ${c("errorAnimationEnabled") !== !1 ? "checked" : ""} />
1076
1096
  <div class="toggle-switch"></div>
1077
1097
  <span class="toggle-label">Console Error Animation</span>
1078
1098
  </label>
1079
1099
  </div>
1080
1100
  <div class="mb-3">
1081
1101
  <label class="toggle">
1082
- <input class="toggle-checkbox" type="checkbox" id="auto-open-setting" ${a("autoOpen") === !0 ? "checked" : ""} />
1102
+ <input class="toggle-checkbox" type="checkbox" id="auto-open-setting" ${c("autoOpen") === !0 ? "checked" : ""} />
1083
1103
  <div class="toggle-switch"></div>
1084
1104
  <span class="toggle-label">Auto Open</span>
1085
1105
  </label>
1086
1106
  </div>
1087
1107
  <div class="mb-3">
1088
1108
  <label class="toggle">
1089
- <input class="toggle-checkbox" type="checkbox" id="scroll-to-latest-log-setting" ${a("scrollToLatestLog") === !0 ? "checked" : ""} />
1109
+ <input class="toggle-checkbox" type="checkbox" id="scroll-to-latest-log-setting" ${c("scrollToLatestLog") === !0 ? "checked" : ""} />
1090
1110
  <div class="toggle-switch"></div>
1091
1111
  <span class="toggle-label">Automatically Scroll to New Logs</span>
1092
1112
  </label>
@@ -1094,45 +1114,41 @@ class Z {
1094
1114
  </div>
1095
1115
  </div>
1096
1116
 
1097
- <div id="single-tab-info" class="single-tab-content outer-tab-content">
1117
+ <div id="single-tab-path-configuration-check" class="single-tab-content outer-tab-content">
1098
1118
  <div class="inner-tab-content">
1099
1119
  <div class="d-flex align-items-center mb-3">
1100
- <button class="btn-icon btn-close-single-mode">${S}</button>
1101
- <h3 class="ms-1">Info</h3>
1102
- </div>
1103
- <div class="info-card">
1104
- <div class="info-card-title">Current URL</div>
1105
- <div class="current-url">${this.currentUrl}</div>
1120
+ <button class="btn-icon btn-close-single-mode">${b}</button>
1121
+ <h3 class="ms-1">PathConfiguration Check</h3>
1106
1122
  </div>
1107
- <div class="info-card">
1108
- <div class="info-card-title">User Agent</div>
1109
- <div class="user-agent">${navigator.userAgent}</div>
1110
- </div>
1111
- <div class="info-card">
1112
- <div class="info-card-title"><pre class="m-0">turbo-cache-control:</pre> <span>${y("turbo-cache-control") || "-"}</span></div>
1113
- <div class="info-card-hint"><strong>no-cache:</strong> always fetched from the network, even on restore</div>
1114
- <div class="info-card-hint"><strong>no-preview:</strong> skipped in preview, used only on restore</div>
1115
- <div class="info-card-hint"><strong>unset:</strong> shows cached preview if the cache is valid</div>
1116
- </div>
1117
- <div class="info-card">
1118
- <div class="info-card-title"><pre class="m-0">turbo-refresh-method:</pre> <span>${y("turbo-refresh-method") || "-"}</span></div>
1119
- <div class="info-card-hint"><strong>replace (default):</strong> replaces the entire &lt;body&gt; on revisit</div>
1120
- <div class="info-card-hint"><strong>morph:</strong> updates only changed DOM elements, preserving state</div>
1123
+ <div class="mb-3">
1124
+ <label for="path-configuration-check-url">URL</label>
1125
+ <input id="path-configuration-check-url" class="w-100" value="/" />
1121
1126
  </div>
1122
- <div class="info-card">
1123
- <div class="info-card-title"><pre class="m-0">turbo-visit-control:</pre> <span>${y("turbo-visit-control") || "-"}</span></div>
1124
- <div class="info-card-hint"><strong>reload:</strong> forces a full page reload</div>
1125
- <div class="info-card-hint"><strong>unset:</strong> allows Turbo to handle the visit normally</div>
1127
+ <div id="path-configuration-check-properties-output" class="overflow-auto">
1126
1128
  </div>
1127
1129
  </div>
1128
1130
  </div>
1131
+
1132
+ <div id="single-tab-info" class="single-tab-content outer-tab-content">
1133
+ </div>
1129
1134
  </div>
1130
1135
  </div>
1131
1136
  `, this.devTools.shadowRoot.appendChild(this.bottomSheet);
1132
1137
  }
1133
1138
  renderConsoleLogs() {
1134
- const t = this.bottomSheet.querySelector(".tab-content-console-logs"), e = u(), o = this.state.consoleSearch;
1135
- t.innerHTML = this.state.consoleLogs.length ? this.state.consoleLogs.filter((s) => e[s.type]).filter((s) => o ? s.message.toLowerCase().includes(o.toLowerCase()) : !0).map((s) => this.consoleLogHTML(s.type, s.message, s.time)).join("") : '<div class="tab-empty-content"><span>No console logs yet</span></div>';
1139
+ const t = this.bottomSheet.querySelector(".tab-content-console-logs"), e = u(), o = m(), s = this.state.consoleSearch;
1140
+ t.innerHTML = this.state.consoleLogs.length ? this.state.consoleLogs.filter((n) => e[n.type]).filter((n) => s ? n.message.toLowerCase().includes(s.toLowerCase()) : !0).filter((n) => !o.includes(n.message.trim())).map((n) => this.consoleLogHTML(n.type, n.message, n.time)).join("") : '<div class="tab-empty-content"><span>No console logs yet</span></div>', this.renderConsoleBlacklist();
1141
+ }
1142
+ renderConsoleBlacklist() {
1143
+ this.bottomSheet.querySelector(".console-log-blacklist").innerHTML = m().length ? `
1144
+ ${m().map(
1145
+ (t) => `
1146
+ <div class="d-flex justify-content-between align-items-center dropdown-entry">
1147
+ <label class="console-log-blacklist-entry-text">${t}</label>
1148
+ <button class="btn-icon btn-remove-console-log-blacklist-entry icon--muted dropdown-content-action w-auto" data-entry="${t}">${p}</button>
1149
+ </div>
1150
+ `
1151
+ ).join("")}` : '<div class="text-center text-muted">No blacklisted logs</div>';
1136
1152
  }
1137
1153
  renderBridgeComponents() {
1138
1154
  const t = this.state.supportedBridgeComponents.length;
@@ -1152,11 +1168,61 @@ class Z {
1152
1168
  const t = this.bottomSheet.querySelector(".tab-content-native-stack");
1153
1169
  t.innerHTML = '<div class="native-stack-wrapper">' + (this.state.nativeStack.length ? this.state.nativeStack.map((e) => this.nativeViewStackHTML(e)).join("") : '<div class="tab-empty-content"><span>No native stack captured yet</span></div>') + "</div>";
1154
1170
  }
1171
+ renderInfos() {
1172
+ const t = `
1173
+ <div class="inner-tab-content">
1174
+ <div class="d-flex align-items-center mb-3">
1175
+ <button class="btn-icon btn-close-single-mode">${b}</button>
1176
+ <h3 class="ms-1">Info</h3>
1177
+ </div>
1178
+ <div class="info-card">
1179
+ <div class="info-card-title">Current URL</div>
1180
+ <div class="current-url">${this.currentUrl}</div>
1181
+ </div>
1182
+ <div class="info-card">
1183
+ <div class="info-card-title">User Agent</div>
1184
+ <div class="user-agent">${navigator.userAgent}</div>
1185
+ </div>
1186
+ <div class="info-card">
1187
+ <div class="info-card-title"><pre class="m-0">turbo-cache-control:</pre> <span>${v("turbo-cache-control") || "-"}</span></div>
1188
+ <div class="info-card-hint"><strong>no-cache:</strong> always fetched from the network, even on restore</div>
1189
+ <div class="info-card-hint"><strong>no-preview:</strong> skipped in preview, used only on restore</div>
1190
+ <div class="info-card-hint"><strong>unset:</strong> shows cached preview if the cache is valid</div>
1191
+ </div>
1192
+ <div class="info-card">
1193
+ <div class="info-card-title"><pre class="m-0">turbo-refresh-method:</pre> <span>${v("turbo-refresh-method") || "-"}</span></div>
1194
+ <div class="info-card-hint"><strong>replace (default):</strong> replaces the entire &lt;body&gt; on revisit</div>
1195
+ <div class="info-card-hint"><strong>morph:</strong> updates only changed DOM elements, preserving state</div>
1196
+ </div>
1197
+ <div class="info-card">
1198
+ <div class="info-card-title"><pre class="m-0">turbo-visit-control:</pre> <span>${v("turbo-visit-control") || "-"}</span></div>
1199
+ <div class="info-card-hint"><strong>reload:</strong> forces a full page reload</div>
1200
+ <div class="info-card-hint"><strong>unset:</strong> allows Turbo to handle the visit normally</div>
1201
+ </div>
1202
+ </div>
1203
+ `;
1204
+ this.bottomSheet.querySelector("#single-tab-info").innerHTML = t;
1205
+ }
1206
+ renderPathConfigurationCheck = g((t) => {
1207
+ const e = L ? t : `${window.location.origin}${t}`;
1208
+ this.devTools.nativeBridge.send("propertiesForUrl", { url: e }, (o) => {
1209
+ this.bottomSheet.querySelector("#path-configuration-check-properties-output").style.opacity = 1;
1210
+ const s = (() => {
1211
+ try {
1212
+ const r = o.data.properties;
1213
+ return JSON.stringify(typeof r == "string" ? JSON.parse(r) : r, null, 2);
1214
+ } catch {
1215
+ return o.data.properties;
1216
+ }
1217
+ })(), n = s ? `<pre class="view-path-configuration">${s}</pre>` : "", a = this.bottomSheet.querySelector("#path-configuration-check-properties-output");
1218
+ a.innerHTML = n;
1219
+ });
1220
+ }, 500);
1155
1221
  bridgeLogHTML(t, e, o, s, n) {
1156
1222
  return `
1157
1223
  <div class="log-entry d-flex gap-3 pt-2 pb-2">
1158
1224
  <div class="log-entry-icon d-flex justify-content-center align-items-center">
1159
- ${t === "send" ? Y : V}
1225
+ ${t === "send" ? P : N}
1160
1226
  </div>
1161
1227
  <div class="w-100 overflow-auto">
1162
1228
  <div class="d-flex justify-content-between">
@@ -1164,9 +1230,9 @@ class Z {
1164
1230
  <small>${n}</small>
1165
1231
  </div>
1166
1232
  <div class="overflow-auto">
1167
- ${Object.entries(s).map(([r, c]) => {
1168
- const b = typeof c == "object" && c !== null ? JSON.stringify(c) : c;
1169
- return `<div class="white-space-collapse">${r}: ${b}</div>`;
1233
+ ${Object.entries(s).map(([a, r]) => {
1234
+ const h = typeof r == "object" && r !== null ? JSON.stringify(r) : r;
1235
+ return `<div class="white-space-collapse">${a}: ${h}</div>`;
1170
1236
  }).join("")}
1171
1237
  </div>
1172
1238
  </div>
@@ -1180,8 +1246,17 @@ class Z {
1180
1246
  <div class="d-flex justify-content-end">
1181
1247
  <small>${o}</small>
1182
1248
  </div>
1183
- <div class="log-entry-message ${t}">
1184
- ${e}
1249
+ <div class="d-flex justify-content-between">
1250
+ <div class="log-entry-message ${t}">
1251
+ ${e}
1252
+ </div>
1253
+ <div class="dropdown dropdown--right">
1254
+ <button class="dropdown-trigger btn-icon">${S}</button>
1255
+ <div class="dropdown-content">
1256
+ <button class="dropdown-btn-full-width dropdown-content-action console-log-action-hide-console-log">Ignore this log</button>
1257
+ <button class="dropdown-btn-full-width dropdown-content-action console-log-action-copy-console-log">Copy log message</button>
1258
+ </div>
1259
+ </div>
1185
1260
  </div>
1186
1261
  </div>
1187
1262
  </div>
@@ -1202,8 +1277,7 @@ class Z {
1202
1277
  `;
1203
1278
  }
1204
1279
  nativeViewStackHTML(t) {
1205
- var C;
1206
- const e = (l) => l == null ? void 0 : l.replace(/\/+$/, ""), o = ["UINavigationController", "NavigatorHost"].includes(t.type), s = t.type === "UITabBarController", n = ["VisitableViewController", "HotwireWebFragment", "BackStackEntry"].includes(t.type), c = `viewstack-card ${e(t.url) === e(this.currentUrl) ? "current-view" : ""} ${o ? "main-view" : n ? "hotwire-view" : s ? "tab-container" : "non-identified-view"}`, b = "viewstack-" + Math.random().toString(16).slice(2), B = t.url ? `<div class="view-url">
1280
+ const e = (d) => d?.replace(/\/+$/, ""), o = ["UINavigationController", "NavigatorHost"].includes(t.type), s = t.type === "UITabBarController", n = ["VisitableViewController", "HotwireWebFragment", "BackStackEntry"].includes(t.type), r = `viewstack-card ${e(t.url) === e(this.currentUrl) ? "current-view" : ""} ${o ? "main-view" : n ? "hotwire-view" : s ? "tab-container" : "non-identified-view"}`, h = "viewstack-" + Math.random().toString(16).slice(2), x = t.url ? `<div class="view-url">
1207
1281
  ${(() => {
1208
1282
  try {
1209
1283
  return new URL(t.url).pathname;
@@ -1211,31 +1285,31 @@ class Z {
1211
1285
  return t.url;
1212
1286
  }
1213
1287
  })()}
1214
- </div>` : "", x = (() => {
1288
+ </div>` : "", w = (() => {
1215
1289
  try {
1216
- const l = t.pathConfigurationProperties;
1217
- return JSON.stringify(typeof l == "string" ? JSON.parse(l) : l, null, 2);
1290
+ const d = t.pathConfigurationProperties;
1291
+ return JSON.stringify(typeof d == "string" ? JSON.parse(d) : d, null, 2);
1218
1292
  } catch {
1219
1293
  return t.pathConfigurationProperties;
1220
1294
  }
1221
- })(), $ = x ? `<pre class="view-path-configuration">${x}</pre>` : "", I = (C = t.children) != null && C.length ? `<div class="child-container">
1222
- ${t.children.map((l) => this.nativeViewStackHTML(l)).join("")}
1295
+ })(), C = w ? `<pre class="view-path-configuration">${w}</pre>` : "", E = t.children?.length ? `<div class="child-container">
1296
+ ${t.children.map((d) => this.nativeViewStackHTML(d)).join("")}
1223
1297
  </div>` : "";
1224
1298
  return `
1225
1299
  <div>
1226
- <div class="${c} collapse no-chevron" data-collapse-target="path-configuration-properties-${b}">
1300
+ <div class="${r} collapse no-chevron" data-collapse-target="path-configuration-properties-${h}">
1227
1301
  <div>
1228
1302
  <div class="view-title">
1229
1303
  ${t.title == "null" ? "" : t.title}
1230
1304
  <div class="view-title-details">${t.type}</div>
1231
1305
  </div>
1232
- ${B}
1306
+ ${x}
1233
1307
  </div>
1234
- <div id="path-configuration-properties-${b}" class="collapse-target">
1235
- ${$}
1308
+ <div id="path-configuration-properties-${h}" class="collapse-target">
1309
+ ${C}
1236
1310
  </div>
1237
1311
  </div>
1238
- ${I}
1312
+ ${E}
1239
1313
  </div>
1240
1314
  `;
1241
1315
  }
@@ -1248,7 +1322,7 @@ class Z {
1248
1322
  });
1249
1323
  }
1250
1324
  registerBridgeComponentExample() {
1251
- switch (L()) {
1325
+ switch (f()) {
1252
1326
  case "android":
1253
1327
  return `
1254
1328
  <pre class="overflow-auto">
@@ -1269,7 +1343,7 @@ class Z {
1269
1343
  }
1270
1344
  }
1271
1345
  registerBridgeComponentHelpURL() {
1272
- switch (L()) {
1346
+ switch (f()) {
1273
1347
  case "android":
1274
1348
  return "https://native.hotwired.dev/android/bridge-components";
1275
1349
  case "ios":
@@ -1279,7 +1353,7 @@ class Z {
1279
1353
  }
1280
1354
  }
1281
1355
  checkNativeFeatures() {
1282
- this.state.supportsNativeStackView && this.bottomSheet.querySelector(".tablink[data-tab-id='tab-native-stack']").classList.remove("d-none");
1356
+ this.state.supportsNativeStackView && (this.bottomSheet.querySelector(".tablink[data-tab-id='tab-native-stack']").classList.remove("d-none"), this.bottomSheet.querySelector(".btn-switch-to-single-tab-sheet[data-tab-id='single-tab-path-configuration-check']").classList.remove("d-none"));
1283
1357
  }
1284
1358
  addEventListeners() {
1285
1359
  this.bottomSheet.hasEventListeners || (this.sheetOverlay.addEventListener("click", () => {
@@ -1295,17 +1369,13 @@ class Z {
1295
1369
  }), this.bottomSheet.querySelectorAll(".btn-switch-to-single-tab-sheet").forEach((t) => {
1296
1370
  t.addEventListener("click", (e) => {
1297
1371
  const o = e.target.closest("[data-tab-id]").dataset.tabId;
1298
- o && this.switchToSingleTabSheet(o);
1299
- });
1300
- }), this.bottomSheet.querySelectorAll(".btn-close-single-mode").forEach((t) => {
1301
- t.addEventListener("click", () => {
1302
- this.switchToMultiTabSheet();
1372
+ o && (o === "single-tab-path-configuration-check" && this.bottomSheet.querySelector("#path-configuration-check-url").value === "/" && this.renderPathConfigurationCheck("/"), o === "single-tab-info" && this.renderInfos(), this.switchToSingleTabSheet(o));
1303
1373
  });
1304
1374
  }), this.bottomSheet.querySelector(".top-part").addEventListener("touchstart", this.dragStart.bind(this), { passive: !0 }), this.bottomSheet.addEventListener("touchmove", this.dragging.bind(this), { passive: !0 }), this.bottomSheet.addEventListener("touchend", this.dragStop.bind(this), { passive: !0 }), this.bottomSheet.querySelector(".console-filter-levels").addEventListener("click", ({ target: t }) => {
1305
1375
  const e = t.closest("input[type='checkbox']");
1306
1376
  if (!e) return;
1307
1377
  const o = e.dataset.consoleFilter, s = e.checked;
1308
- N(o, s), this.renderConsoleLogs();
1378
+ I(o, s), this.renderConsoleLogs();
1309
1379
  }), this.bottomSheet.querySelector(".btn-search-console").addEventListener("click", () => {
1310
1380
  const t = this.bottomSheet.querySelector(".console-search");
1311
1381
  t.classList.toggle("d-none"), t.querySelector("input").focus();
@@ -1313,26 +1383,28 @@ class Z {
1313
1383
  this.devTools.state.setConsoleSearchValue(t.target.value.toLowerCase()), this.renderConsoleLogs();
1314
1384
  }), this.bottomSheet.querySelector("#bottom-sheet-height-setting").addEventListener("change", (t) => {
1315
1385
  const e = t.target.value;
1316
- this.sheetHeight = parseInt(e), h("bottomSheetHeight", e), this.updateSheetHeight(e);
1386
+ this.sheetHeight = parseInt(e), l("bottomSheetHeight", e), this.updateSheetHeight(e);
1317
1387
  }), this.bottomSheet.querySelector("#console-error-animation-setting").addEventListener("change", (t) => {
1318
- h("errorAnimationEnabled", t.target.checked);
1388
+ l("errorAnimationEnabled", t.target.checked);
1319
1389
  }), this.bottomSheet.querySelector("#font-size-setting").addEventListener("change", (t) => {
1320
1390
  let e = t.target.value;
1321
- e = Math.max(8, Math.min(24, e)), h("fontSize", e), this.devTools.setCSSProperty("--font-size", `${e}px`);
1391
+ e = Math.max(8, Math.min(24, e)), l("fontSize", e), this.devTools.setCSSProperty("--font-size", `${e}px`);
1322
1392
  }), this.bottomSheet.querySelector("#auto-open-setting").addEventListener("change", (t) => {
1323
- h("autoOpen", t.target.checked);
1393
+ l("autoOpen", t.target.checked);
1324
1394
  }), this.bottomSheet.querySelector("#scroll-to-latest-log-setting").addEventListener("change", (t) => {
1325
- h("scrollToLatestLog", t.target.checked);
1395
+ l("scrollToLatestLog", t.target.checked);
1326
1396
  }), this.bottomSheet.querySelector(".pin-bottom-sheet").addEventListener("click", () => {
1327
- const t = a("bottomSheetPinned") === !0;
1328
- h("bottomSheetPinned", !t), this.sheetOverlay.classList.toggle("active"), this.bottomSheet.querySelector(".settings-dropdown").classList.remove("dropdown-open");
1397
+ const t = c("bottomSheetPinned") === !0;
1398
+ l("bottomSheetPinned", !t), this.sheetOverlay.classList.toggle("active"), this.bottomSheet.querySelector(".settings-dropdown").classList.remove("dropdown-open");
1399
+ }), this.bottomSheet.querySelector("#path-configuration-check-url").addEventListener("input", (t) => {
1400
+ this.bottomSheet.querySelector("#path-configuration-check-properties-output").style.opacity = 0.5, this.renderPathConfigurationCheck(t.target.value);
1329
1401
  }), this.bottomSheet.addEventListener("click", (t) => {
1330
1402
  const e = t.target.closest(".collapse");
1331
1403
  if (e && this.bottomSheet.contains(e)) {
1332
- const n = e.getAttribute("data-collapse-target"), r = this.bottomSheet.querySelector(`#${n}`);
1404
+ const a = e.getAttribute("data-collapse-target"), r = this.bottomSheet.querySelector(`#${a}`);
1333
1405
  if (r) {
1334
- const c = e.classList.toggle("active");
1335
- r.classList.toggle("active", c);
1406
+ const h = e.classList.toggle("active");
1407
+ r.classList.toggle("active", h);
1336
1408
  }
1337
1409
  return;
1338
1410
  }
@@ -1341,11 +1413,22 @@ class Z {
1341
1413
  t.preventDefault(), this.toggleDropdown(o);
1342
1414
  return;
1343
1415
  }
1344
- this.bottomSheet.querySelectorAll(".dropdown-content.dropdown-open").forEach((n) => {
1345
- n.closest(".dropdown").contains(t.target) || n.classList.remove("dropdown-open");
1346
- });
1416
+ if (t.target.closest(".dropdown-content-action")) {
1417
+ this.handleDropdownActionClick(t);
1418
+ return;
1419
+ }
1420
+ if (t.target.closest(".btn-close-single-mode")) {
1421
+ this.switchToMultiTabSheet();
1422
+ return;
1423
+ }
1424
+ this.closeAllDropdowns(t);
1347
1425
  }), this.bottomSheet.hasEventListeners = !0);
1348
1426
  }
1427
+ closeAllDropdowns(t) {
1428
+ this.bottomSheet.querySelectorAll(".dropdown-content.dropdown-open").forEach((o) => {
1429
+ o.closest(".dropdown").contains(t.target) || o.classList.remove("dropdown-open");
1430
+ });
1431
+ }
1349
1432
  updateConsoleFilter(t) {
1350
1433
  this.bottomSheet.querySelectorAll(".console-filter-levels input[type='checkbox']").forEach((e) => {
1351
1434
  const o = e.dataset.consoleFilter, s = t[o];
@@ -1358,13 +1441,30 @@ class Z {
1358
1441
  o !== e && o.classList.remove("dropdown-open");
1359
1442
  }), e.classList.toggle("dropdown-open");
1360
1443
  }
1444
+ handleTabClick = (t) => {
1445
+ const e = t.target.closest(".tablink");
1446
+ if (!e) return;
1447
+ const o = e.dataset.tabId;
1448
+ this.devTools.state.setActiveTab(o), this.updateTabView(o);
1449
+ };
1450
+ handleDropdownActionClick = (t) => {
1451
+ const e = t.target.closest(".dropdown-content-action");
1452
+ if (e)
1453
+ if (e.classList.contains("console-log-action-hide-console-log"))
1454
+ F(e.closest(".log-entry").querySelector(".log-entry-message").textContent), this.renderConsoleLogs();
1455
+ else if (e.classList.contains("console-log-action-copy-console-log")) {
1456
+ const s = e.closest(".log-entry").querySelector(".log-entry-message").textContent;
1457
+ navigator.clipboard.writeText(s).then(() => {
1458
+ this.closeAllDropdowns(t);
1459
+ });
1460
+ } else e.classList.contains("btn-remove-console-log-blacklist-entry") && (q(e.dataset.entry.trim()), this.renderConsoleLogs());
1461
+ };
1361
1462
  updateTabView(t) {
1362
1463
  this.devTools.shadowRoot.querySelectorAll(".tablink, .outer-tab-content").forEach((e) => e.classList.remove("active")), this.devTools.shadowRoot.querySelectorAll(".tab-action-bar").forEach((e) => e.classList.remove("active")), this.devTools.shadowRoot.querySelector(`[data-tab-id="${t}"]`).classList.add("active"), this.devTools.shadowRoot.getElementById(t).classList.add("active"), this.devTools.shadowRoot.querySelector(`.tab-action-bar.${t}`).classList.add("active"), this.state.shouldScrollToLatestLog && (this.scrollToLatestLog(t), this.state.shouldScrollToLatestLog = !1);
1363
1464
  }
1364
1465
  scrollToLatestLog(t) {
1365
- a("scrollToLatestLog") == !0 && requestAnimationFrame(() => {
1366
- const e = this.devTools.shadowRoot.getElementById(t), o = e == null ? void 0 : e.querySelector(".log-entry:last-child");
1367
- o == null || o.scrollIntoView({ behavior: "instant", block: "center" });
1466
+ c("scrollToLatestLog") == !0 && requestAnimationFrame(() => {
1467
+ this.devTools.shadowRoot.getElementById(t)?.querySelector(".log-entry:last-child")?.scrollIntoView({ behavior: "instant", block: "center" });
1368
1468
  });
1369
1469
  }
1370
1470
  showBottomSheet() {
@@ -1377,13 +1477,11 @@ class Z {
1377
1477
  this.sheetContent.style.height = `${t}vh`, this.bottomSheet.classList.toggle("fullscreen", t === 100);
1378
1478
  }
1379
1479
  dragStart(t) {
1380
- var e;
1381
- this.isDragging = !0, this.startY = t.pageY || ((e = t.touches) == null ? void 0 : e[0].pageY), this.startHeight = parseInt(this.sheetContent.style.height), this.bottomSheet.classList.add("dragging");
1480
+ this.isDragging = !0, this.startY = t.pageY || t.touches?.[0].pageY, this.startHeight = parseInt(this.sheetContent.style.height), this.bottomSheet.classList.add("dragging");
1382
1481
  }
1383
1482
  dragging(t) {
1384
- var s;
1385
1483
  if (!this.isDragging) return;
1386
- const e = this.startY - (t.pageY || ((s = t.touches) == null ? void 0 : s[0].pageY)), o = this.startHeight + e / window.innerHeight * 100;
1484
+ const e = this.startY - (t.pageY || t.touches?.[0].pageY), o = this.startHeight + e / window.innerHeight * 100;
1387
1485
  this.updateSheetHeight(o);
1388
1486
  }
1389
1487
  dragStop() {
@@ -1407,14 +1505,13 @@ class Z {
1407
1505
  }
1408
1506
  // Get all the `static component = "..."` from the bridge components
1409
1507
  get bridgeComponentIdentifiers() {
1410
- var t;
1411
- return ((t = window.Stimulus) == null ? void 0 : t.controllers.map((e) => e.component).filter((e) => e !== void 0)) || [];
1508
+ return window.Stimulus?.controllers.map((t) => t.component).filter((t) => t !== void 0) || [];
1412
1509
  }
1413
1510
  get currentUrl() {
1414
1511
  return window.location.href;
1415
1512
  }
1416
1513
  }
1417
- class Q {
1514
+ class W {
1418
1515
  constructor() {
1419
1516
  this.state = {
1420
1517
  consoleLogs: [],
@@ -1468,7 +1565,7 @@ class Q {
1468
1565
  this.state.eventLogs = [], this.notify();
1469
1566
  }
1470
1567
  setActiveTab(t) {
1471
- this.state.activeTab = t, h("activeTab", t);
1568
+ this.state.activeTab = t, l("activeTab", t);
1472
1569
  }
1473
1570
  setConsoleSearchValue(t) {
1474
1571
  this.state.consoleSearch = t;
@@ -1480,13 +1577,12 @@ class Q {
1480
1577
  return (/* @__PURE__ */ new Date()).toLocaleTimeString();
1481
1578
  }
1482
1579
  get storedActiveTab() {
1483
- return a("activeTab") || "tab-bridge-components";
1580
+ return c("activeTab") || "tab-bridge-components";
1484
1581
  }
1485
1582
  }
1486
- class _ {
1583
+ class X {
1487
1584
  bridgeIsConnected() {
1488
- var t, e;
1489
- return !!((t = window.HotwireNative) != null && t.web || (e = window.Strada) != null && e.web);
1585
+ return !!(window.HotwireNative?.web || window.Strada?.web);
1490
1586
  }
1491
1587
  // Send a message to the native side
1492
1588
  send(t, e = {}, o = null) {
@@ -1509,38 +1605,19 @@ class _ {
1509
1605
  return this.bridgeIsConnected() ? this.bridge.supportsComponent(t) : !1;
1510
1606
  }
1511
1607
  getSupportedComponents() {
1512
- var t;
1513
- return ((t = document.documentElement.dataset.bridgeComponents) == null ? void 0 : t.split(" ")) || [];
1608
+ return document.documentElement.dataset.bridgeComponents?.split(" ") || [];
1514
1609
  }
1515
1610
  get bridge() {
1516
- var t, e;
1517
- return ((t = window.HotwireNative) == null ? void 0 : t.web) || ((e = window.Strada) == null ? void 0 : e.web);
1611
+ return window.HotwireNative?.web || window.Strada?.web;
1518
1612
  }
1519
1613
  }
1520
- class tt {
1614
+ class J {
1521
1615
  constructor(t = {}) {
1522
- d(this, "update", m((t) => {
1523
- this.bottomSheet.update(t);
1524
- }, 200));
1525
- // Fetch the current stack from the native side
1526
- // The debounce on this function is intentionally high,
1527
- // to ensure the native side has enough time to set the ViewController / Fragment titles.
1528
- // With a lower debounce, the view controller / fragment title would often be empty.
1529
- d(this, "fetchNativeStack", m(() => {
1530
- this.nativeBridge.send("currentStackInfo", {}, (t) => {
1531
- this.state.setSupportsNativeStack(!0), this.state.setNativeStack(t.data.stack);
1532
- });
1533
- }, 1e3));
1534
- d(this, "injectCSSToShadowRoot", async () => {
1535
- if (this.shadowRoot.querySelector("style")) return;
1536
- const t = document.createElement("style");
1537
- t.textContent = M(), this.shadowRoot.appendChild(t);
1538
- });
1539
1616
  this.options = {
1540
1617
  enabled: !0,
1541
1618
  reset: !1,
1542
1619
  ...t
1543
- }, this.options.enabled && (this.options.reset && z(), this.state = new Q(), this.bubble = new K(this), this.bottomSheet = new Z(this), this.nativeBridge = new _(this), this.diagnosticsChecker = new H(), this.state.subscribe(this.update.bind(this)), this.listenForTurboEvents());
1620
+ }, this.options.enabled && (this.options.reset && $(), this.state = new W(), this.bubble = new Y(this), this.bottomSheet = new U(this), this.nativeBridge = new X(this), this.diagnosticsChecker = new B(), this.state.subscribe(this.update.bind(this)), this.listenForTurboEvents());
1544
1621
  }
1545
1622
  // Setup gets called initially and on every turbo:load event, eg. when navigating to a new page
1546
1623
  setup() {
@@ -1548,29 +1625,31 @@ class tt {
1548
1625
  this.nativeBridgeGotConnected();
1549
1626
  }), this.addEventListeners(), this.diagnosticsChecker.checkForWarnings(), this.bubble.onClick(() => {
1550
1627
  this.bottomSheet.showBottomSheet(), this.nativeBridge.send("vibrate");
1551
- }), a("autoOpen") === !0 && this.bottomSheet.showBottomSheet());
1628
+ }), c("autoOpen") === !0 && this.bottomSheet.showBottomSheet());
1552
1629
  }
1553
1630
  nativeBridgeGotConnected() {
1554
- var t, e;
1555
- this.originalBridge || (this.originalBridge = ((t = window.HotwireNative) == null ? void 0 : t.web) || ((e = window.Strada) == null ? void 0 : e.web), this.addBridgeProxy(), this.state.setBridgeIsConnected(!0), this.callNativeBridgeComponent(), this.updateSupportedBridgeComponents(), this.startBridgeComponentObserver());
1631
+ this.originalBridge || (this.originalBridge = window.HotwireNative?.web || window.Strada?.web, this.addBridgeProxy(), this.state.setBridgeIsConnected(!0), this.callNativeBridgeComponent(), this.updateSupportedBridgeComponents(), this.startBridgeComponentObserver());
1556
1632
  }
1557
1633
  callNativeBridgeComponent() {
1558
1634
  this.nativeBridge.bridgeIsConnected() && this.nativeBridge.send("connect", {}, (t) => {
1559
1635
  this.fetchNativeStack();
1560
1636
  });
1561
1637
  }
1638
+ update = g((t) => {
1639
+ this.bottomSheet.update(t);
1640
+ }, 200);
1562
1641
  setupShadowRoot() {
1563
1642
  if (this.shadowContainer.shadowRoot) {
1564
1643
  this.shadowRoot = this.shadowContainer.shadowRoot, this.injectCSSToShadowRoot();
1565
1644
  return;
1566
1645
  }
1567
- this.shadowRoot = this.shadowContainer.attachShadow({ mode: "open" }), this.setCSSProperty("--font-size", `${a("fontSize") || 16}px`), this.injectCSSToShadowRoot();
1646
+ this.shadowRoot = this.shadowContainer.attachShadow({ mode: "open" }), this.setCSSProperty("--font-size", `${c("fontSize") || 16}px`), this.injectCSSToShadowRoot();
1568
1647
  }
1569
1648
  addBridgeProxy() {
1570
1649
  const t = () => ({
1571
1650
  get: (e, o, s) => {
1572
1651
  const n = Reflect.get(e, o, s);
1573
- return typeof n == "function" && (o === "send" || o === "receive") ? (...r) => (this.interceptedBridgeMessage(o, r), n.apply(e, r)) : typeof n == "function" ? (...r) => n.apply(e, r) : n;
1652
+ return typeof n == "function" && (o === "send" || o === "receive") ? (...a) => (this.interceptedBridgeMessage(o, a), n.apply(e, a)) : typeof n == "function" ? (...a) => n.apply(e, a) : n;
1574
1653
  }
1575
1654
  });
1576
1655
  window.Strada && (window.Strada.web = new Proxy(this.originalBridge, t())), window.HotwireNative && (window.HotwireNative.web = new Proxy(this.originalBridge, t()));
@@ -1579,44 +1658,65 @@ class tt {
1579
1658
  window.console = new Proxy(this.originalConsole, {
1580
1659
  get: (t, e, o) => {
1581
1660
  const s = Reflect.get(t, e, o);
1582
- return (...n) => (this.interceptedConsoleMessage(e, n), s == null ? void 0 : s.apply(t, n));
1661
+ return (...n) => (this.interceptedConsoleMessage(e, n), s?.apply(t, n));
1583
1662
  }
1584
1663
  });
1585
1664
  }
1586
1665
  interceptedBridgeMessage(t, e) {
1587
1666
  e.forEach((o) => {
1588
- const s = o.component, n = o.event, { metadata: r, ...c } = o.data;
1589
- s !== "dev-tools" && this.state.addBridgeLog(t, s, n, c);
1667
+ const s = o.component, n = o.event, { metadata: a, ...r } = o.data;
1668
+ s !== "dev-tools" && this.state.addBridgeLog(t, s, n, r);
1590
1669
  });
1591
1670
  }
1592
1671
  interceptedConsoleMessage(t, e) {
1593
1672
  const o = e.map((s) => {
1594
- if (s instanceof Element) {
1595
- const r = Array.from(s.attributes).map((c) => `${c.name}="${c.value}"`).join(" ");
1596
- return `&lt;${s.tagName.toLowerCase()}${r ? " " + r : ""}&gt;&lt;/${s.tagName.toLowerCase()}&gt;`;
1673
+ if (s instanceof Element)
1674
+ return y(s);
1675
+ if (s instanceof Error) {
1676
+ let a = `${s.name}: ${s.message}
1677
+ `;
1678
+ return s.stack && (a += `
1679
+ ${s.stack}`), `<pre>${a}</pre>`;
1597
1680
  }
1598
- if (typeof s == "object")
1681
+ if (typeof s == "object" && s !== null)
1599
1682
  try {
1600
- return `<pre>${JSON.stringify(s, null, 2)}</pre>`;
1683
+ return `<pre>${JSON.stringify(
1684
+ s,
1685
+ (a, r) => r === window ? "[Window Object]" : r instanceof HTMLElement ? y(r) : r,
1686
+ 2
1687
+ )}</pre>`;
1601
1688
  } catch {
1602
- return `<pre>${s}</pre>`;
1689
+ return `<pre>${s.toString()}</pre>`;
1603
1690
  }
1604
1691
  return s.toString().replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;");
1605
1692
  }).join(" ");
1606
- o.includes("hotwire-native-dev-tools") || o.includes("HotwireDevTools") || (this.state.addConsoleLog(t, o), t === "error" && this.bubble.animateErrorBorder());
1693
+ o.includes("hotwire-native-dev-tools") || o.includes("HotwireDevTools") || (this.state.addConsoleLog(t, o), t === "error" && (m().includes(o) || this.bubble.animateErrorBorder()));
1607
1694
  }
1695
+ // Fetch the current stack from the native side
1696
+ // The debounce on this function is intentionally high,
1697
+ // to ensure the native side has enough time to set the ViewController / Fragment titles.
1698
+ // With a lower debounce, the view controller / fragment title would often be empty.
1699
+ fetchNativeStack = g(() => {
1700
+ this.nativeBridge.send("currentStackInfo", {}, (t) => {
1701
+ this.state.setSupportsNativeStack(!0), this.state.setNativeStack(t.data.stack);
1702
+ });
1703
+ }, 1e3);
1608
1704
  refetchNativeStack() {
1609
1705
  this.nativeBridge.send("currentStackInfo", {}, (t) => {
1610
1706
  this.state.setNativeStack(t.data.stack);
1611
1707
  });
1612
1708
  }
1709
+ injectCSSToShadowRoot = async () => {
1710
+ if (this.shadowRoot.querySelector("style")) return;
1711
+ const t = document.createElement("style");
1712
+ t.textContent = T(), this.shadowRoot.appendChild(t);
1713
+ };
1613
1714
  addEventListeners() {
1614
1715
  this.hasEventListeners || (window.addEventListener("error", (t) => {
1615
- const { message: e, filename: o, lineno: s, colno: n } = t, r = `${e} at ${o}:${s}:${n}`;
1616
- this.interceptedConsoleMessage("error", [r]);
1716
+ const { message: e, filename: o, lineno: s, colno: n } = t, a = `${e} at ${o}:${s}:${n}`;
1717
+ this.interceptedConsoleMessage("error", [a]);
1617
1718
  }), window.addEventListener("unhandledrejection", (t) => {
1618
- var e;
1619
- this.interceptedConsoleMessage("error", [(e = t.reason) == null ? void 0 : e.message]);
1719
+ this.interceptedConsoleMessage("error", [t.reason?.message]);
1620
1720
  }), window.addEventListener(
1621
1721
  "resize",
1622
1722
  () => {
@@ -1691,8 +1791,8 @@ class tt {
1691
1791
  return (/* @__PURE__ */ new Date()).toLocaleTimeString();
1692
1792
  }
1693
1793
  }
1694
- const ot = (i = {}) => {
1695
- const t = new tt(i);
1794
+ const G = (i = {}) => {
1795
+ const t = new J(i);
1696
1796
  t.options.enabled && (t.setup(), document.addEventListener(
1697
1797
  "turbo:load",
1698
1798
  () => {
@@ -1702,6 +1802,6 @@ const ot = (i = {}) => {
1702
1802
  ));
1703
1803
  };
1704
1804
  export {
1705
- ot as setupDevTools
1805
+ G as setupDevTools
1706
1806
  };
1707
1807
  //# sourceMappingURL=hotwire-native-dev-tools.es.js.map