react-render-detective 0.1.0 → 0.1.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.
package/README.md CHANGED
@@ -11,10 +11,12 @@
11
11
  [Guide](docs/GUIDE.md) · [API](docs/API.md) · [Feasibility report](docs/FEASIBILITY.md) ·
12
12
  [Benchmarks](docs/BENCHMARKS.md)
13
13
 
14
- > **Status: 0.1.0, early release.** 74 tests pass on React 18 and 19, benchmarks and bundle budgets
15
- > are green, and the packed package is verified in a clean install for ESM, CJS and TypeScript
16
- > consumers. Not yet exercised: a real browser (all testing is jsdom) and Suspense / error-boundary
17
- > edges. Treat it as a preview issues welcome.
14
+ > **Status: 0.1.0, early release.** 76 tests pass on React 18 and 19; benchmarks and bundle budgets
15
+ > are green; the packed package is verified in a clean install for ESM, CJS and TypeScript
16
+ > consumers; and the demo dashboard has been driven end to end in Chrome, which found four real
17
+ > defects the jsdom suite had missed (see the [changelog](CHANGELOG.md)). Not yet exercised:
18
+ > Suspense and error-boundary edges, and any app that isn't the demo. Treat it as a preview —
19
+ > issues welcome.
18
20
 
19
21
  Not just:
20
22
 
@@ -221,8 +223,10 @@ Full API: [docs/API.md](docs/API.md).
221
223
  ## Safety
222
224
 
223
225
  - **Nothing leaves your machine.** No network calls, no telemetry, no analytics, no storage.
224
- - **Production-safe by default.** `detectDev()` defaults to *off* when it cannot tell.
225
- With `enabled: false` nothing is registered and no `<Profiler>` is mounted.
226
+ - **Off until you ask.** Importing the package registers nothing. `init()` is the switch, and it
227
+ turns diagnostics on unless it can positively see `NODE_ENV === "production"` guard the call so
228
+ your bundler removes it entirely. With `enabled: false` nothing is registered and no `<Profiler>`
229
+ is mounted.
226
230
  - **Fail-safe.** Every instrumentation path is wrapped: a throwing getter, an exploding subscriber
227
231
  or an un-inspectable prop degrades the diagnostic, never your app.
228
232
  - **Bounded.** Ring-buffered events, capped inspection depth/width, props released on unmount.
@@ -137,16 +137,20 @@ function formatInspected(node) {
137
137
  }
138
138
 
139
139
  // src/core/config.ts
140
- function detectDev() {
140
+ function detectProduction() {
141
141
  try {
142
142
  const env = typeof process !== "undefined" ? process?.env : void 0;
143
- if (env && env.NODE_ENV) return env.NODE_ENV !== "production";
143
+ if (env && env.NODE_ENV) return env.NODE_ENV === "production";
144
144
  } catch {
145
145
  }
146
146
  return false;
147
147
  }
148
+ function detectDev() {
149
+ return !detectProduction();
150
+ }
148
151
  var defaultConfig = {
149
- enabled: detectDev(),
152
+ // Off until `init()` is called, so importing the package costs nothing.
153
+ enabled: false,
150
154
  mode: "console",
151
155
  include: [],
152
156
  exclude: [],
@@ -594,9 +598,16 @@ var Detective = class {
594
598
  this.initialized = false;
595
599
  this.events = new RingBuffer(this.config.maxEvents);
596
600
  }
597
- /** Idempotent: repeated calls reconfigure, they never duplicate anything (§47). */
601
+ /**
602
+ * Idempotent: repeated calls reconfigure, they never duplicate anything (§47).
603
+ *
604
+ * Calling `init()` *is* the intent to turn diagnostics on, so `enabled`
605
+ * defaults to true unless a production build is positively detected. Guard
606
+ * the call itself for production safety — that is what the docs show, and it
607
+ * is what lets a bundler drop the whole thing.
608
+ */
598
609
  init(options = {}) {
599
- this.configure(options);
610
+ this.configure({ enabled: !detectProduction(), ...options });
600
611
  this.initialized = true;
601
612
  return this;
602
613
  }
@@ -656,8 +667,6 @@ var Detective = class {
656
667
  this.nodes.set(node.id, node);
657
668
  }
658
669
  detach(node) {
659
- node.prevProps = void 0;
660
- node.pendingProps = void 0;
661
670
  this.nodes.delete(node.id);
662
671
  }
663
672
  /** Hot path. Must stay allocation-free and O(1). */
@@ -1008,5 +1017,5 @@ function getDetective() {
1008
1017
  }
1009
1018
 
1010
1019
  export { Detective, RingBuffer, defaultConfig, detectDev, diagnose, diffProps, formatInspected, getDetective, inspect, isPlainObject, isReactElement, matches, mergeConfig, severityFor, shallowEqual, shouldInstrument, valueType };
1011
- //# sourceMappingURL=chunk-GRPJ4JAB.js.map
1012
- //# sourceMappingURL=chunk-GRPJ4JAB.js.map
1020
+ //# sourceMappingURL=chunk-27IWHWSM.js.map
1021
+ //# sourceMappingURL=chunk-27IWHWSM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/inspect.ts","../src/core/config.ts","../src/core/compare.ts","../src/core/diagnose.ts","../src/core/ringBuffer.ts","../src/core/store.ts"],"names":["take","keys","evidence"],"mappings":";AAEA,IAAM,aAAA,mBAAgB,MAAA,CAAO,GAAA,CAAI,eAAe,CAAA;AAChD,IAAM,0BAAA,mBAA6B,MAAA,CAAO,GAAA,CAAI,4BAA4B,CAAA;AAEnE,SAAS,eAAe,KAAA,EAAyB;AACtD,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,MAAM,OAAO,KAAA;AACxD,EAAA,MAAM,IAAK,KAAA,CAAgC,QAAA;AAC3C,EAAA,OAAO,CAAA,KAAM,iBAAiB,CAAA,KAAM,0BAAA;AACtC;AAEO,SAAS,cAAc,KAAA,EAAkD;AAC9E,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,MAAM,OAAO,KAAA;AACxD,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAO,KAAA;AACjC,EAAA,IAAI,cAAA,CAAe,KAAK,CAAA,EAAG,OAAO,KAAA;AAClC,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,cAAA,CAAe,KAAK,CAAA;AACzC,EAAA,OAAO,KAAA,KAAU,MAAA,CAAO,SAAA,IAAa,KAAA,KAAU,IAAA;AACjD;AAEO,SAAS,UAAU,KAAA,EAA+B;AACvD,EAAA,IAAI,KAAA,KAAU,MAAM,OAAO,MAAA;AAC3B,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG,OAAO,OAAA;AACjC,EAAA,IAAI,cAAA,CAAe,KAAK,CAAA,EAAG,OAAO,SAAA;AAClC,EAAA,MAAM,IAAI,OAAO,KAAA;AACjB,EAAA,IAAI,CAAA,KAAM,UAAU,OAAO,QAAA;AAC3B,EAAA,IAAI,CAAA,KAAM,YAAY,OAAO,UAAA;AAC7B,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,YAAY,KAAA,EAAwB;AAC3C,EAAA,MAAM,OAAQ,KAAA,CAA6B,IAAA;AAC3C,EAAA,IAAI,OAAO,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AACrC,EAAA,IAAI,OAAO,IAAA,KAAS,UAAA,SAAoB,IAAA,CAAiD,WAAA,IAAgB,KAA2B,IAAA,IAAQ,WAAA;AAC5I,EAAA,OAAO,SAAA;AACT;AAQO,SAAS,OAAA,CAAQ,OAAgB,MAAA,EAAqC;AAC3E,EAAA,MAAM,MAAA,GAAS,EAAE,KAAA,EAAO,MAAA,CAAO,kBAAA,EAAmB;AAClD,EAAA,IAAI;AACF,IAAA,OAAO,IAAA,CAAK,OAAO,MAAA,EAAQ,MAAA,EAAQ,OAAO,KAAA,kBAAO,IAAI,SAAiB,CAAA;AAAA,EACxE,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,CAAA,EAAG,WAAA,EAAa,IAAA,EAAM,mBAAA,EAAoB;AAAA,EACrD;AACF;AAEA,SAAS,IAAA,CACP,KAAA,EACA,MAAA,EACA,MAAA,EACA,OACA,IAAA,EACW;AACX,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG,OAAO,EAAE,CAAA,EAAG,WAAA,EAAa,MAAM,YAAA,EAAa;AAErE,EAAA,IAAI,KAAA,KAAU,MAAA,EAAW,OAAO,EAAE,GAAG,WAAA,EAAY;AACjD,EAAA,IAAI,UAAU,IAAA,EAAM,OAAO,EAAE,CAAA,EAAG,WAAA,EAAa,GAAG,IAAA,EAAK;AAErD,EAAA,MAAM,OAAO,OAAO,KAAA;AACpB,EAAA,IAAI,IAAA,KAAS,QAAA,EAAU,OAAO,MAAA,CAAO,MAAM,KAAK,CAAA,GAAI,EAAE,CAAA,EAAG,OAAM,GAAI,EAAE,CAAA,EAAG,WAAA,EAAa,GAAG,KAAA,EAAgB;AACxG,EAAA,IAAI,SAAS,SAAA,EAAW,OAAO,EAAE,CAAA,EAAG,WAAA,EAAa,GAAG,KAAA,EAAiB;AACrE,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,MAAM,CAAA,GAAI,KAAA;AACV,IAAA,OAAO;AAAA,MACL,CAAA,EAAG,WAAA;AAAA,MACH,GAAG,CAAA,CAAE,MAAA,GAAS,MAAA,CAAO,eAAA,GAAkB,GAAG,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,MAAA,CAAO,eAAe,CAAC,CAAA,QAAA,EAAM,EAAE,MAAA,GAAS,MAAA,CAAO,eAAe,CAAA,CAAA,CAAA,GAAM;AAAA,KAC3H;AAAA,EACF;AACA,EAAA,IAAI,IAAA,KAAS,UAAU,OAAO,EAAE,GAAG,QAAA,EAAU,CAAA,EAAG,MAAA,CAAO,KAAK,CAAA,EAAE;AAC9D,EAAA,IAAI,IAAA,KAAS,QAAA,EAAU,OAAO,EAAE,CAAA,EAAG,QAAA,EAAU,CAAA,EAAG,CAAA,EAAG,MAAA,CAAO,KAAK,CAAC,CAAA,CAAA,CAAA,EAAI;AACpE,EAAA,IAAI,SAAS,UAAA,EAAY;AACvB,IAAA,MAAM,EAAA,GAAK,KAAA;AACX,IAAA,OAAO,EAAE,GAAG,UAAA,EAAY,IAAA,EAAM,GAAG,WAAA,IAAe,EAAA,CAAG,QAAQ,WAAA,EAAY;AAAA,EACzE;AAEA,EAAA,MAAM,GAAA,GAAM,KAAA;AACZ,EAAA,IAAI,KAAK,GAAA,CAAI,GAAG,GAAG,OAAO,EAAE,GAAG,UAAA,EAAW;AAC1C,EAAA,IAAA,CAAK,IAAI,GAAG,CAAA;AAEZ,EAAA,IAAI,cAAA,CAAe,GAAG,CAAA,EAAG,OAAO,EAAE,GAAG,SAAA,EAAW,IAAA,EAAM,WAAA,CAAY,GAAG,CAAA,EAAE;AAEvE,EAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG;AACtB,IAAA,MAAM,SAAS,GAAA,CAAI,MAAA;AACnB,IAAA,IAAI,SAAS,CAAA,EAAG,OAAO,EAAE,CAAA,EAAG,SAAS,MAAA,EAAO;AAC5C,IAAA,MAAMA,KAAAA,GAAO,IAAA,CAAK,GAAA,CAAI,MAAA,EAAQ,OAAO,cAAc,CAAA;AACnD,IAAA,MAAM,QAAqB,EAAC;AAC5B,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAIA,KAAAA,EAAM,CAAA,EAAA,QAAW,IAAA,CAAK,IAAA,CAAK,GAAA,CAAI,CAAC,GAAG,MAAA,EAAQ,MAAA,EAAQ,KAAA,GAAQ,CAAA,EAAG,IAAI,CAAC,CAAA;AACvF,IAAA,OAAO,EAAE,CAAA,EAAG,OAAA,EAAS,QAAQ,KAAA,EAAO,SAAA,EAAWA,QAAO,MAAA,EAAO;AAAA,EAC/D;AAEA,EAAA,MAAM,IAAA,GAAO,UAAU,GAAG,CAAA;AAC1B,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAA,GAAO,MAAA,CAAO,KAAK,GAA8B,CAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAE,CAAA,EAAG,QAAA,EAAU,IAAA,EAAK;AAAA,EAC7B;AACA,EAAA,IAAI,SAAS,CAAA,EAAG;AACd,IAAA,OAAO,EAAE,CAAA,EAAG,QAAA,EAAU,IAAA,EAAM,MAAM,IAAA,CAAK,KAAA,CAAM,CAAA,EAAG,MAAA,CAAO,aAAa,CAAA,EAAG,SAAA,EAAW,IAAA,CAAK,MAAA,GAAS,OAAO,aAAA,EAAc;AAAA,EACvH;AACA,EAAA,MAAM,OAAO,IAAA,CAAK,GAAA,CAAI,IAAA,CAAK,MAAA,EAAQ,OAAO,aAAa,CAAA;AACvD,EAAA,MAAM,UAAqC,EAAC;AAC5C,EAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,EAAM,CAAA,EAAA,EAAK;AAC7B,IAAA,MAAM,CAAA,GAAI,KAAK,CAAC,CAAA;AAChB,IAAA,IAAI,CAAA;AACJ,IAAA,IAAI;AACF,MAAA,CAAA,GAAK,IAAgC,CAAC,CAAA;AAAA,IACxC,CAAA,CAAA,MAAQ;AAEN,MAAA,OAAA,CAAQ,CAAC,CAAA,GAAI,EAAE,CAAA,EAAG,WAAA,EAAa,MAAM,cAAA,EAAe;AACpD,MAAA;AAAA,IACF;AACA,IAAA,OAAA,CAAQ,CAAC,IAAI,IAAA,CAAK,CAAA,EAAG,QAAQ,MAAA,EAAQ,KAAA,GAAQ,GAAG,IAAI,CAAA;AAAA,EACtD;AACA,EAAA,OAAO,EAAE,GAAG,QAAA,EAAU,IAAA,EAAM,SAAS,SAAA,EAAW,IAAA,GAAO,KAAK,MAAA,EAAO;AACrE;AAEA,SAAS,UAAU,GAAA,EAAiC;AAClD,EAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,cAAA,CAAe,GAAG,CAAA;AACvC,EAAA,IAAI,KAAA,KAAU,MAAA,CAAO,SAAA,IAAa,KAAA,KAAU,MAAM,OAAO,MAAA;AACzD,EAAA,MAAM,IAAA,GAAO,OAAO,WAAA,EAAa,IAAA;AACjC,EAAA,OAAO,OAAO,IAAA,KAAS,QAAA,IAAY,IAAA,KAAS,WAAW,IAAA,GAAO,MAAA;AAChE;AAGO,SAAS,gBAAgB,IAAA,EAAqC;AACnE,EAAA,IAAI,CAAC,MAAM,OAAO,QAAA;AAClB,EAAA,QAAQ,KAAK,CAAA;AAAG,IACd,KAAK,WAAA;AACH,MAAA,OAAO,OAAO,IAAA,CAAK,CAAA,KAAM,QAAA,GAAW,IAAA,CAAK,SAAA,CAAU,IAAA,CAAK,CAAC,CAAA,GAAI,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA;AAAA,IAC5E,KAAK,WAAA;AACH,MAAA,OAAO,WAAA;AAAA,IACT,KAAK,KAAA;AACH,MAAA,OAAO,KAAA;AAAA,IACT,KAAK,QAAA;AAAA,IACL,KAAK,QAAA;AACH,MAAA,OAAO,IAAA,CAAK,CAAA;AAAA,IACd,KAAK,UAAA;AACH,MAAA,OAAO,CAAA,OAAA,EAAK,KAAK,IAAI,CAAA,EAAA,CAAA;AAAA,IACvB,KAAK,SAAA;AACH,MAAA,OAAO,CAAA,CAAA,EAAI,KAAK,IAAI,CAAA,GAAA,CAAA;AAAA,IACtB,KAAK,UAAA;AACH,MAAA,OAAO,YAAA;AAAA,IACT,KAAK,WAAA;AACH,MAAA,OAAO,CAAA,QAAA,EAAM,KAAK,IAAI,CAAA,CAAA,CAAA;AAAA,IACxB,KAAK,OAAA,EAAS;AACZ,MAAA,IAAI,CAAC,IAAA,CAAK,KAAA,EAAO,OAAO,CAAA,MAAA,EAAS,KAAK,MAAM,CAAA,CAAA,CAAA;AAC5C,MAAA,MAAM,OAAO,IAAA,CAAK,KAAA,CAAM,IAAI,eAAe,CAAA,CAAE,KAAK,IAAI,CAAA;AACtD,MAAA,OAAO,IAAI,IAAI,CAAA,EAAG,IAAA,CAAK,SAAA,GAAY,aAAQ,EAAE,CAAA,CAAA,CAAA;AAAA,IAC/C;AAAA,IACA,KAAK,QAAA,EAAU;AACb,MAAA,MAAM,SAAS,IAAA,CAAK,IAAA,GAAO,CAAA,EAAG,IAAA,CAAK,IAAI,CAAA,CAAA,CAAA,GAAM,EAAA;AAC7C,MAAA,IAAI,KAAK,OAAA,EAAS;AAChB,QAAA,MAAM,IAAA,GAAO,OAAO,OAAA,CAAQ,IAAA,CAAK,OAAO,CAAA,CACrC,GAAA,CAAI,CAAC,CAAC,CAAA,EAAG,CAAC,CAAA,KAAM,CAAA,EAAG,CAAC,CAAA,EAAA,EAAK,eAAA,CAAgB,CAAC,CAAC,CAAA,CAAE,CAAA,CAC7C,IAAA,CAAK,IAAI,CAAA;AACZ,QAAA,OAAO,CAAA,EAAG,MAAM,CAAA,EAAA,EAAK,IAAI,GAAG,IAAA,CAAK,SAAA,GAAY,aAAQ,EAAE,CAAA,EAAA,CAAA;AAAA,MACzD;AACA,MAAA,IAAI,IAAA,CAAK,IAAA,EAAM,OAAO,CAAA,EAAG,MAAM,CAAA,EAAA,EAAK,IAAA,CAAK,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA,EAAG,IAAA,CAAK,SAAA,GAAY,aAAQ,EAAE,CAAA,EAAA,CAAA;AACtF,MAAA,OAAO,GAAG,MAAM,CAAA,QAAA,CAAA;AAAA,IAClB;AAAA;AAEJ;;;ACvJO,SAAS,gBAAA,GAA4B;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,OAAO,OAAA,KAAY,WAAA,GAAc,SAAS,GAAA,GAAM,KAAA,CAAA;AAC5D,IAAA,IAAI,GAAA,IAAO,GAAA,CAAI,QAAA,EAAU,OAAO,IAAI,QAAA,KAAa,YAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AAAA,EAER;AACA,EAAA,OAAO,KAAA;AACT;AAGO,SAAS,SAAA,GAAqB;AACnC,EAAA,OAAO,CAAC,gBAAA,EAAiB;AAC3B;AAEO,IAAM,aAAA,GAAiC;AAAA;AAAA,EAE5C,OAAA,EAAS,KAAA;AAAA,EACT,IAAA,EAAM,SAAA;AAAA,EACN,SAAS,EAAC;AAAA,EACV,SAAS,EAAC;AAAA,EACV,YAAA,EAAc,CAAA;AAAA,EACd,SAAA,EAAW,GAAA;AAAA,EACX,mBAAA,EAAqB,EAAA;AAAA,EACrB,UAAA,EAAY,EAAE,OAAA,EAAS,CAAA,EAAG,MAAM,EAAA,EAAI,QAAA,EAAU,EAAA,EAAI,QAAA,EAAU,GAAA,EAAI;AAAA,EAChE,UAAA,EAAY;AAAA,IACV,KAAA,EAAO,CAAA;AAAA,IACP,aAAA,EAAe,EAAA;AAAA,IACf,cAAA,EAAgB,EAAA;AAAA,IAChB,eAAA,EAAiB,GAAA;AAAA,IACjB,kBAAA,EAAoB;AAAA,GACtB;AAAA,EACA,qBAAA,EAAuB;AACzB;AAEO,SAAS,WAAA,CAAY,IAAA,EAAuB,OAAA,GAA4B,EAAC,EAAoB;AAClG,EAAA,MAAM,EAAE,UAAA,EAAY,UAAA,EAAY,GAAG,MAAK,GAAI,OAAA;AAC5C,EAAA,MAAM,IAAA,GAAwB;AAAA,IAC5B,GAAG,IAAA;AAAA,IACH,GAAI,IAAA;AAAA,IACJ,YAAY,EAAE,GAAG,IAAA,CAAK,UAAA,EAAY,GAAG,UAAA,EAAW;AAAA,IAChD,YAAY,EAAE,GAAG,IAAA,CAAK,UAAA,EAAY,GAAG,UAAA;AAAW,GAClD;AACA,EAAA,IAAA,CAAK,YAAA,GAAe,KAAA,CAAM,IAAA,CAAK,YAAA,EAAc,GAAG,CAAC,CAAA;AACjD,EAAA,IAAA,CAAK,SAAA,GAAY,KAAK,GAAA,CAAI,CAAA,EAAG,KAAK,KAAA,CAAM,IAAA,CAAK,SAAS,CAAC,CAAA;AACvD,EAAA,IAAA,CAAK,UAAA,CAAW,KAAA,GAAQ,KAAA,CAAM,IAAA,CAAK,KAAA,CAAM,KAAK,UAAA,CAAW,KAAK,CAAA,EAAG,CAAA,EAAG,CAAC,CAAA;AACrE,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,KAAA,CAAM,CAAA,EAAW,EAAA,EAAY,EAAA,EAAoB;AACxD,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,KAAA,CAAM,CAAC,GAAG,OAAO,EAAA;AACrD,EAAA,OAAO,KAAK,GAAA,CAAI,EAAA,EAAI,KAAK,GAAA,CAAI,EAAA,EAAI,CAAC,CAAC,CAAA;AACrC;AAEO,SAAS,OAAA,CAAQ,MAAc,QAAA,EAA2C;AAC/E,EAAA,KAAA,MAAW,KAAK,QAAA,EAAU;AACxB,IAAA,IAAI,OAAO,MAAM,QAAA,GAAW,CAAA,KAAM,OAAO,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,IAAA;AAAA,EAChE;AACA,EAAA,OAAO,KAAA;AACT;AAGO,SAAS,gBAAA,CAAiB,MAAc,MAAA,EAAkC;AAC/E,EAAA,IAAI,OAAA,CAAQ,IAAA,EAAM,MAAA,CAAO,OAAO,GAAG,OAAO,KAAA;AAC1C,EAAA,IAAI,MAAA,CAAO,OAAA,CAAQ,MAAA,GAAS,CAAA,IAAK,CAAC,QAAQ,IAAA,EAAM,MAAA,CAAO,OAAO,CAAA,EAAG,OAAO,KAAA;AACxE,EAAA,OAAO,IAAA;AACT;;;ACvEA,IAAM,QAAiC,EAAC;AAEjC,SAAS,SAAA,CACd,QAAA,EACA,OAAA,EACA,MAAA,EACW;AACX,EAAA,MAAM,OAAO,QAAA,IAAY,KAAA;AACzB,EAAA,MAAM,OAAO,OAAA,IAAW,KAAA;AACxB,EAAA,MAAM,UAAwB,EAAC;AAC/B,EAAA,MAAM,YAAsB,EAAC;AAE7B,EAAA,MAAM,IAAA,uBAAW,GAAA,EAAY;AAC7B,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA;AAChC,EAAA,KAAA,MAAW,CAAA,IAAK,IAAA,EAAM,IAAA,CAAK,GAAA,CAAI,CAAC,CAAA;AAEhC,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,MAAM,UAAU,GAAA,IAAO,IAAA;AACvB,IAAA,MAAM,UAAU,GAAA,IAAO,IAAA;AACvB,IAAA,MAAM,CAAA,GAAI,KAAK,GAAG,CAAA;AAClB,IAAA,MAAM,CAAA,GAAI,KAAK,GAAG,CAAA;AAElB,IAAA,IAAI,WAAW,OAAA,IAAW,MAAA,CAAO,EAAA,CAAG,CAAA,EAAG,CAAC,CAAA,EAAG;AACzC,MAAA,SAAA,CAAU,KAAK,GAAG,CAAA;AAClB,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,GAAA,EAAK,IAAA,EAAM,SAAS,SAAA,EAAW,SAAA,CAAU,CAAC,CAAA,EAAG,OAAA,EAAS,IAAA,CAAK,CAAA,EAAG,MAAM,GAAG,CAAA;AACtF,MAAA;AAAA,IACF;AACA,IAAA,IAAI,CAAC,OAAA,EAAS;AACZ,MAAA,OAAA,CAAQ,IAAA,CAAK,EAAE,GAAA,EAAK,IAAA,EAAM,WAAW,SAAA,EAAW,SAAA,CAAU,CAAC,CAAA,EAAG,QAAA,EAAU,IAAA,CAAK,CAAA,EAAG,MAAM,GAAG,CAAA;AACzF,MAAA;AAAA,IACF;AACA,IAAA,OAAA,CAAQ,KAAK,cAAA,CAAe,GAAA,EAAK,CAAA,EAAG,CAAA,EAAG,MAAM,CAAC,CAAA;AAAA,EAChD;AAEA,EAAA,OAAO,EAAE,SAAS,SAAA,EAAU;AAC9B;AAEA,SAAS,cAAA,CAAe,GAAA,EAAa,CAAA,EAAY,CAAA,EAAY,MAAA,EAAqC;AAChG,EAAA,MAAM,IAAA,GAAO,UAAU,CAAC,CAAA;AACxB,EAAA,MAAM,IAAA,GAAmB;AAAA,IACvB,GAAA;AAAA,IACA,IAAA,EAAM,OAAA;AAAA,IACN,SAAA,EAAW,IAAA;AAAA,IACX,QAAA,EAAU,IAAA,CAAK,CAAA,EAAG,MAAM,CAAA;AAAA,IACxB,OAAA,EAAS,IAAA,CAAK,CAAA,EAAG,MAAM;AAAA,GACzB;AAEA,EAAA,IAAI,OAAO,CAAA,KAAM,UAAA,IAAc,OAAO,MAAM,UAAA,EAAY;AACtD,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,IAAA,IAAI,OAAO,qBAAA,EAAuB;AAChC,MAAA,IAAA,CAAK,WAAA,GAAc,UAAA,CAAW,CAAC,CAAA,KAAM,WAAW,CAAC,CAAA;AAAA,IACnD;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,MAAM,OAAA,GAAU,YAAA,CAAa,CAAA,EAAG,CAAA,EAAG,MAAM,CAAA;AACzC,EAAA,IAAI,YAAY,IAAA,EAAM;AACpB,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAAA,EACtB,CAAA,MAAA,IAAW,YAAY,KAAA,EAAO;AAC5B,IAAA,IAAA,CAAK,IAAA,GAAO,OAAA;AACZ,IAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AAAA,EACtB;AACA,EAAA,OAAO,IAAA;AACT;AAOO,SAAS,YAAA,CAAa,CAAA,EAAY,CAAA,EAAY,MAAA,EAAwC;AAC3F,EAAA,IAAI,MAAA,CAAO,EAAA,CAAG,CAAA,EAAG,CAAC,GAAG,OAAO,IAAA;AAC5B,EAAA,IAAI,OAAO,CAAA,KAAM,QAAA,IAAY,OAAO,CAAA,KAAM,YAAY,CAAA,KAAM,IAAA,IAAQ,CAAA,KAAM,IAAA,EAAM,OAAO,KAAA;AAEvF,EAAA,MAAM,EAAE,aAAA,EAAe,cAAA,EAAe,GAAI,MAAA,CAAO,UAAA;AAEjD,EAAA,IAAI,MAAM,OAAA,CAAQ,CAAC,KAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG;AACxC,IAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,IAAK,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA,EAAG,OAAO,KAAA;AACnD,IAAA,IAAI,CAAA,CAAE,MAAA,KAAW,CAAA,CAAE,MAAA,EAAQ,OAAO,KAAA;AAClC,IAAA,IAAI,CAAA,CAAE,MAAA,GAAS,cAAA,EAAgB,OAAO,MAAA;AACtC,IAAA,KAAA,IAAS,IAAI,CAAA,EAAG,CAAA,GAAI,CAAA,CAAE,MAAA,EAAQ,KAAK,IAAI,CAAC,MAAA,CAAO,EAAA,CAAG,EAAE,CAAC,CAAA,EAAG,EAAE,CAAC,CAAC,GAAG,OAAO,KAAA;AACtE,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,CAAA,YAAa,IAAA,IAAQ,CAAA,YAAa,IAAA,EAAM;AAC1C,IAAA,OAAO,CAAA,YAAa,QAAQ,CAAA,YAAa,IAAA,GAAO,EAAE,OAAA,EAAQ,KAAM,CAAA,CAAE,OAAA,EAAQ,GAAI,KAAA;AAAA,EAChF;AAEA,EAAA,IAAI,cAAA,CAAe,CAAC,CAAA,IAAK,cAAA,CAAe,CAAC,CAAA,EAAG;AAC1C,IAAA,MAAM,EAAA,GAAK,CAAA;AACX,IAAA,MAAM,EAAA,GAAK,CAAA;AACX,IAAA,IAAI,EAAA,CAAG,SAAS,EAAA,CAAG,IAAA,IAAQ,GAAG,GAAA,KAAQ,EAAA,CAAG,KAAK,OAAO,KAAA;AACrD,IAAA,OAAO,YAAA,CAAa,EAAA,CAAG,KAAA,EAAO,EAAA,CAAG,OAAO,MAAM,CAAA;AAAA,EAChD;AAEA,EAAA,IAAI,CAAC,cAAc,CAAC,CAAA,IAAK,CAAC,aAAA,CAAc,CAAC,GAAG,OAAO,MAAA;AAEnD,EAAA,MAAM,EAAA,GAAK,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA;AACxB,EAAA,MAAM,EAAA,GAAK,MAAA,CAAO,IAAA,CAAK,CAAC,CAAA;AACxB,EAAA,IAAI,EAAA,CAAG,MAAA,KAAW,EAAA,CAAG,MAAA,EAAQ,OAAO,KAAA;AACpC,EAAA,IAAI,EAAA,CAAG,MAAA,GAAS,aAAA,EAAe,OAAO,MAAA;AACtC,EAAA,KAAA,MAAW,KAAK,EAAA,EAAI;AAClB,IAAA,IAAI,CAAC,OAAO,SAAA,CAAU,cAAA,CAAe,KAAK,CAAA,EAAG,CAAC,GAAG,OAAO,KAAA;AACxD,IAAA,IAAI,CAAC,MAAA,CAAO,EAAA,CAAG,CAAA,CAAE,CAAC,GAAG,CAAA,CAAE,CAAC,CAAC,CAAA,EAAG,OAAO,KAAA;AAAA,EACrC;AACA,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,IAAA,CAAK,OAAgB,MAAA,EAAoC;AAChE,EAAA,OAAO,OAAA,CAAQ,KAAA,EAAO,MAAA,CAAO,UAAU,CAAA;AACzC;AAEA,SAAS,WAAW,EAAA,EAAqB;AACvC,EAAA,IAAI;AACF,IAAA,OAAO,QAAA,CAAS,SAAA,CAAU,QAAA,CAAS,IAAA,CAAK,EAAE,CAAA;AAAA,EAC5C,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,EAAA;AAAA,EACT;AACF;;;AC9FO,SAAS,WAAA,CAAY,UAAkB,CAAA,EAAsC;AAClF,EAAA,IAAI,QAAA,IAAY,CAAA,CAAE,QAAA,EAAU,OAAO,UAAA;AACnC,EAAA,IAAI,QAAA,IAAY,CAAA,CAAE,QAAA,EAAU,OAAO,WAAA;AACnC,EAAA,IAAI,QAAA,IAAY,CAAA,CAAE,IAAA,EAAM,OAAO,MAAA;AAC/B,EAAA,IAAI,QAAA,IAAY,CAAA,CAAE,OAAA,EAAS,OAAO,SAAA;AAClC,EAAA,OAAO,QAAA;AACT;AAMO,SAAS,QAAA,CAAS,OAAuB,UAAA,EAAmC;AACjF,EAAA,MAAM,QAAA,GAAW,WAAA,CAAY,KAAA,CAAM,YAAA,EAAc,UAAU,CAAA;AAC3D,EAAA,MAAM,CAAA,GAAI,SAAS,KAAK,CAAA;AACxB,EAAA,CAAA,CAAE,QAAA,GAAW,QAAA;AAEb,EAAA,IAAI,CAAC,MAAM,SAAA,EAAW;AACpB,IAAA,CAAA,CAAE,QAAA,CAAS,OAAA;AAAA,MACT;AAAA,KACF;AAAA,EACF,CAAA,MAAA,IAAW,KAAA,CAAM,QAAA,GAAW,CAAA,EAAG;AAC7B,IAAA,CAAA,CAAE,QAAA,CAAS,IAAA;AAAA,MACT,CAAA,oBAAA,EAAuB,MAAM,QAAQ,CAAA,4HAAA;AAAA,KACvC;AAAA,EACF;AAEA,EAAA,IAAI,QAAA,KAAa,UAAA,IAAc,QAAA,KAAa,WAAA,EAAa;AACvD,IAAA,CAAA,CAAE,QAAA,CAAS,IAAA,CAAK,CAAA,YAAA,EAAe,GAAA,CAAI,KAAA,CAAM,YAAY,CAAC,CAAA,kBAAA,EAAgB,UAAA,CAAW,QAAQ,CAAA,aAAA,CAAe,CAAA;AAAA,EAC1G;AACA,EAAA,OAAO,CAAA;AACT;AAEA,SAAS,SAAS,KAAA,EAAkC;AAClD,EAAA,MAAM,EAAE,YAAA,EAAc,cAAA,EAAgB,cAAA,EAAgB,aAAA,EAAe,YAAW,GAAI,KAAA;AAEpF,EAAA,IAAI,KAAA,CAAM,UAAU,OAAA,EAAS;AAC3B,IAAA,OAAO,IAAA,CAAK,OAAA,EAAS,MAAA,EAAQ,CAAA,EAAG,KAAA,CAAM,aAAa,CAAA,SAAA,CAAA,EAAa,CAAC,gCAAgC,CAAA,EAAG,KAAK,CAAA;AAAA,EAC3G;AAEA,EAAA,IAAI,KAAA,CAAM,YAAA,CAAa,MAAA,GAAS,CAAA,EAAG;AACjC,IAAA,MAAM,QAAQ,KAAA,CAAM,YAAA,CAAa,IAAI,CAAC,CAAA,KAAM,EAAE,IAAI,CAAA;AAClD,IAAA,MAAM,QAAA,GAAW,MAAM,YAAA,CAAa,GAAA;AAAA,MAClC,CAAC,CAAA,KAAM,CAAA,EAAA,EAAK,CAAA,CAAE,IAAI,CAAA,IAAA,EAAO,eAAA,CAAgB,CAAA,CAAE,QAAQ,CAAC,CAAA,QAAA,EAAM,eAAA,CAAgB,CAAA,CAAE,OAAO,CAAC,CAAA;AAAA,KACtF;AACA,IAAA,IAAI,YAAA,CAAa,SAAS,CAAA,EAAG;AAC3B,MAAA,QAAA,CAAS,IAAA,CAAK,CAAA,oBAAA,EAAuB,YAAA,CAAa,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,GAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA,IACnF;AACA,IAAA,OAAO,IAAA;AAAA,MACL,OAAA;AAAA,MACA,MAAA;AAAA,MACA,GAAG,KAAA,CAAM,aAAa,4CAA4C,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA;AAAA,MAClF,QAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,YAAA,CAAa,SAAS,CAAA,EAAG;AAC3B,IAAA,MAAM,aAAa,YAAA,CAAa,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,WAAW,CAAA;AACpE,IAAA,MAAM,gBAAgB,YAAA,CAAa,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAS,WAAW,CAAA;AAEvE,IAAA,IAAI,UAAA,CAAW,SAAS,CAAA,EAAG;AACzB,MAAA,MAAMC,QAAO,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,GAAG,CAAA;AACxC,MAAA,MAAMC,SAAAA,GAAW;AAAA,QACf,CAAA,+BAAA,EAAkCD,KAAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA;AAAA,QACjD,GAAG,UAAA,CAAW,GAAA,CAAI,QAAQ;AAAA,OAC5B;AACA,MAAA,IAAI,aAAA,CAAc,SAAS,CAAA,EAAG;AAC5B,QAAAC,SAAAA,CAAS,IAAA;AAAA,UACP,CAAA,qDAAA,EAAwD,aAAA,CAAc,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,GAAG,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA;AAAA,SACpG;AAAA,MACF;AACA,MAAA,OAAO,IAAA;AAAA,QACL,OAAA;AAAA,QACA,MAAA;AAAA,QACA,CAAA,EAAG,KAAA,CAAM,aAAa,CAAA,kBAAA,EAAqB,MAAA,CAAOD,KAAAA,CAAK,MAAA,EAAQ,MAAM,CAAC,CAAA,UAAA,EAAaA,KAAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA;AAAA,QAClGC,SAAAA;AAAA,QACA,KAAA;AAAA,QACA,cAAc,MAAA,GAAS,CAAA,GAAI,mBAAA,CAAoB,aAAA,EAAe,UAAU,CAAA,GAAI;AAAA,OAC9E;AAAA,IACF;AAGA,IAAA,MAAM,OAAO,aAAA,CAAc,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,GAAG,CAAA;AAC3C,IAAA,MAAM,QAAA,GAAW;AAAA,MACf,CAAA,EAAG,MAAA,CAAO,IAAA,CAAK,MAAA,EAAQ,MAAM,CAAC,CAAA,4BAAA,EAA+B,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA;AAAA,MAC5E,GAAG,aAAA,CAAc,GAAA,CAAI,QAAQ;AAAA,KAC/B;AACA,IAAA,IAAI,kBAAkB,UAAA,EAAY;AAChC,MAAA,QAAA,CAAS,IAAA,CAAK,CAAA,EAAG,UAAU,CAAA,8CAAA,EAAiD,IAAA,CAAK,MAAA,GAAS,CAAA,GAAI,cAAA,GAAiB,CAAA,EAAA,EAAK,IAAA,CAAK,CAAC,CAAC,IAAI,CAAA,CAAA,CAAG,CAAA;AAAA,IACpI;AACA,IAAA,MAAM,UAAA,GAAyB,aAAA,CAAc,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,YAAA,KAAiB,IAAA,IAAQ,CAAA,CAAE,SAAA,KAAc,UAAU,CAAA,GAC1G,QAAA,GACA,KAAA;AACJ,IAAA,OAAO,IAAA;AAAA,MACL,OAAA;AAAA,MACA,UAAA;AAAA,MACA,GAAG,KAAA,CAAM,aAAa,qBAAqB,IAAA,CAAK,IAAA,CAAK,IAAI,CAAC,CAAA,kDAAA,CAAA;AAAA,MAC1D,QAAA;AAAA,MACA,IAAA;AAAA,MACA,mBAAA,CAAoB,eAAe,UAAU;AAAA,KAC/C;AAAA,EACF;AAGA,EAAA,IAAI,KAAA,CAAM,qBAAqB,KAAA,EAAO;AAGpC,IAAA,IAAI,cAAA,CAAe,SAAS,CAAA,EAAG;AAC7B,MAAA,MAAM,CAAA,GAAI,eAAe,CAAC,CAAA;AAC1B,MAAA,MAAM,MAAA,GAAS,CAAA,CAAE,WAAA,CAAY,MAAA,GAAS,CAAA,GAAI,CAAA,UAAA,EAAa,CAAA,CAAE,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AACrF,MAAA,OAAO,IAAA;AAAA,QACL,SAAA;AAAA,QACA,QAAA;AAAA,QACA,GAAG,KAAA,CAAM,aAAa,mBAAmB,CAAA,CAAE,WAAW,+BAA+B,MAAM,CAAA,CAAA;AAAA,QAC3F;AAAA,UACE,2EAAA;AAAA,UACA,CAAA,gBAAA,EAAmB,EAAE,WAAW,CAAA,wBAAA,CAAA;AAAA,UAChC,CAAA,CAAE,gBACE,CAAA,EAAG,CAAA,CAAE,WAAW,CAAA,qEAAA,CAAA,GAChB,CAAA,EAAG,EAAE,WAAW,CAAA,oBAAA,CAAA;AAAA,UACpB;AAAA,SACF;AAAA,QACA,CAAA,CAAE,aAAA;AAAA,QACF,CAAA,CAAE,aAAA,GACE,CAAA,EAAG,CAAA,CAAE,WAAW,CAAA,yGAAA,CAAA,GAChB;AAAA,OACN;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,MACL,mBAAA;AAAA,MACA,KAAA,CAAM,mBAAmB,MAAA,GAAS,QAAA;AAAA,MAClC,CAAA,EAAG,MAAM,aAAa,CAAA,0FAAA,CAAA;AAAA,MACtB;AAAA,QACE,8DAAA;AAAA,QACA,KAAA,CAAM,mBACF,uGAAA,GACA,+HAAA;AAAA,QACJ;AAAA,OACF;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,IAAI,KAAA,CAAM,qBAAqB,IAAA,EAAM;AAEnC,IAAA,MAAM,QAAQ,cAAA,IAAkB,UAAA;AAChC,IAAA,OAAO,IAAA;AAAA,MACL,QAAA;AAAA,MACA,KAAA,IAAS,cAAA,CAAe,MAAA,KAAW,CAAA,GAAI,MAAA,GAAS,QAAA;AAAA,MAChD,CAAA,EAAG,MAAM,aAAa,CAAA,2EAAA,CAAA;AAAA,MACtB;AAAA,QACE,KAAA,GACI,CAAA,EAAG,UAAU,CAAA,4BAAA,CAAA,GACb,+IAAA;AAAA,QACJ,uCAAA;AAAA,QACA,cAAA,CAAe,MAAA,KAAW,CAAA,GACtB,4CAAA,GACA,mCAAmC,cAAA,CAAe,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,8EAAA;AAAA,OAC5F;AAAA,MACA,IAAA;AAAA,MACA,eAAe,KAAK;AAAA,KACtB;AAAA,EACF;AAGA,EAAA,IAAI,cAAA,EAAgB;AAClB,IAAA,MAAM,QAAA,GAAW;AAAA,MACf,CAAA,EAAG,cAAc,mCAAmC,CAAA,4BAAA,CAAA;AAAA,MACpD,uCAAA;AAAA,MACA,cAAA,CAAe,MAAA,KAAW,CAAA,GACtB,4CAAA,GACA,mCAAmC,cAAA,CAAe,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,WAAW,CAAA,CAAE,IAAA,CAAK,IAAI,CAAC,CAAA,qEAAA;AAAA,KAC5F;AACA,IAAA,OAAO,IAAA;AAAA,MACL,QAAA;AAAA,MACA,cAAA,CAAe,MAAA,KAAW,CAAA,GAAI,MAAA,GAAS,QAAA;AAAA,MACvC,CAAA,EAAG,MAAM,aAAa,CAAA,2EAAA,CAAA;AAAA,MACtB,QAAA;AAAA,MACA,IAAA;AAAA,MACA,eAAe,KAAK;AAAA,KACtB;AAAA,EACF;AAEA,EAAA,IAAI,cAAA,CAAe,SAAS,CAAA,EAAG;AAC7B,IAAA,MAAM,CAAA,GAAI,eAAe,CAAC,CAAA;AAC1B,IAAA,MAAM,MAAA,GAAS,CAAA,CAAE,WAAA,CAAY,MAAA,GAAS,CAAA,GAAI,CAAA,UAAA,EAAa,CAAA,CAAE,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA,CAAA,CAAA,GAAM,EAAA;AACrF,IAAA,OAAO,IAAA;AAAA,MACL,SAAA;AAAA,MACA,QAAA;AAAA,MACA,GAAG,KAAA,CAAM,aAAa,mBAAmB,CAAA,CAAE,WAAW,+BAA+B,MAAM,CAAA,CAAA;AAAA,MAC3F;AAAA,QACE,CAAA,qDAAA,CAAA;AAAA,QACA,CAAA,gBAAA,EAAmB,EAAE,WAAW,CAAA,wBAAA,CAAA;AAAA,QAChC,CAAA,CAAE,gBACE,CAAA,EAAG,CAAA,CAAE,WAAW,CAAA,qEAAA,CAAA,GAChB,CAAA,EAAG,EAAE,WAAW,CAAA,oBAAA,CAAA;AAAA,QACpB;AAAA,OACF;AAAA,MACA,CAAA,CAAE,aAAA;AAAA,MACF,CAAA,CAAE,aAAA,GACE,CAAA,EAAG,CAAA,CAAE,WAAW,CAAA,yGAAA,CAAA,GAChB;AAAA,KACN;AAAA,EACF;AAEA,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,OAAO,IAAA;AAAA,MACL,SAAA;AAAA,MACA,KAAA;AAAA,MACA,CAAA,2CAAA,EAA8C,MAAM,aAAa,CAAA,CAAA,CAAA;AAAA,MACjE;AAAA,QACE,qDAAA;AAAA,QACA,iGAAA;AAAA,QACA;AAAA,OACF;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AAAA,IACL,mBAAA;AAAA,IACA,QAAA;AAAA,IACA,CAAA,EAAG,MAAM,aAAa,CAAA,0FAAA,CAAA;AAAA,IACtB;AAAA,MACE,mCAAA;AAAA,MACA,qEAAA;AAAA,MACA,4CAAA;AAAA,MACA;AAAA,KACF;AAAA,IACA;AAAA,GACF;AACF;AAMA,SAAS,eAAe,KAAA,EAA+B;AACrD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,YAAA,IAAgB,CAAA,IAAK,MAAM,qBAAA,IAAyB,CAAA;AACxE,EAAA,OAAO,QACH,CAAA,cAAA,EAAiB,KAAA,CAAM,aAAa,CAAA,qEAAA,EAAwE,KAAA,CAAM,wBAAwB,CAAC,CAAA,QAAA,EAAQ,GAAA,CAAI,KAAA,CAAM,YAAY,CAAC,CAAA,sCAAA,CAAA,GAC1K,8CAA8C,GAAA,CAAI,KAAA,CAAM,YAAY,CAAC,CAAA,8CAAA,CAAA;AAC3E;AAEA,SAAS,mBAAA,CAAoB,SAAuB,UAAA,EAA6B;AAC/E,EAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,SAAA,KAAc,UAAU,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,GAAG,CAAA;AAC9E,EAAA,MAAM,OAAO,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,EAAE,SAAA,KAAc,QAAA,IAAY,CAAA,CAAE,SAAA,KAAc,OAAO,CAAA,CAAE,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,GAAG,CAAA;AACxG,EAAA,MAAM,KAAA,GAAQ,UAAA,GAAa,CAAA,IAAA,EAAO,UAAU,CAAA,CAAA,GAAK,EAAA;AACjD,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,IAAI,IAAI,MAAA,GAAS,CAAA,QAAS,IAAA,CAAK,CAAA,EAAG,KAAK,GAAG,CAAC,CAAA,CAAA,EAAI,MAAA,CAAO,IAAI,MAAA,EAAQ,IAAA,EAAM,KAAK,CAAC,CAAA,0BAAA,EAA6B,KAAK,CAAA,mEAAA,CAAgE,CAAA;AAChL,EAAA,IAAI,KAAK,MAAA,GAAS,CAAA,QAAS,IAAA,CAAK,CAAA,EAAG,KAAK,IAAI,CAAC,CAAA,CAAA,EAAI,MAAA,CAAO,KAAK,MAAA,EAAQ,IAAA,EAAM,KAAK,CAAC,CAAA,yBAAA,EAA4B,KAAK,CAAA,iEAAA,CAA8D,CAAA;AAChL,EAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,cAAc,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,CAAC,MAAM,CAAA,CAAE,GAAG,CAAC,CAAC,cAAc,KAAK,CAAA,kBAAA,CAAA;AAC/F,EAAA,OAAO,GAAG,UAAA,CAAW,KAAA,CAAM,IAAA,CAAK,IAAI,CAAC,CAAC,CAAA,CAAA,CAAA;AACxC;AAEA,SAAS,SAAS,CAAA,EAAuB;AACvC,EAAA,QAAQ,EAAE,IAAA;AAAM,IACd,KAAK,OAAA;AACH,MAAA,OAAO,CAAA,EAAA,EAAK,EAAE,GAAG,CAAA,aAAA,CAAA;AAAA,IACnB,KAAK,SAAA;AACH,MAAA,OAAO,CAAA,EAAA,EAAK,EAAE,GAAG,CAAA,eAAA,CAAA;AAAA,IACnB,KAAK,WAAA;AACH,MAAA,IAAI,CAAA,CAAE,cAAc,UAAA,EAAY;AAC9B,QAAA,OAAO,CAAA,CAAE,cACL,CAAA,EAAA,EAAK,CAAA,CAAE,GAAG,CAAA,4FAAA,CAAA,GACV,CAAA,EAAA,EAAK,EAAE,GAAG,CAAA,+BAAA,CAAA;AAAA,MAChB;AACA,MAAA,IAAI,CAAA,CAAE,iBAAiB,IAAA,EAAM,OAAO,KAAK,CAAA,CAAE,GAAG,CAAA,YAAA,EAAe,CAAA,CAAE,SAAS,CAAA,sCAAA,CAAA;AACxE,MAAA,OAAO,CAAA,EAAA,EAAK,EAAE,GAAG,CAAA,+EAAA,CAAA;AAAA,IACnB,KAAK,OAAA;AACH,MAAA,OAAO,CAAA,EAAA,EAAK,EAAE,GAAG,CAAA,iBAAA,CAAA;AAAA;AAEvB;AAEA,SAAS,KACP,MAAA,EACA,UAAA,EACA,OAAA,EACA,QAAA,EACA,sBACA,UAAA,EACW;AACX,EAAA,OAAO,EAAE,QAAQ,UAAA,EAAY,OAAA,EAAS,UAAU,oBAAA,EAAsB,UAAA,EAAY,UAAU,QAAA,EAAS;AACvG;AAEA,IAAM,MAAM,CAAC,EAAA,KAAuB,GAAG,EAAA,CAAG,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAA;AACpD,IAAM,IAAA,GAAO,CAAC,EAAA,KAAyB,EAAA,CAAG,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,EAAA,EAAK,CAAC,CAAA,EAAA,CAAI,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA;AAC1E,IAAM,UAAA,GAAa,CAAC,CAAA,KAAsB,CAAA,CAAE,MAAA,CAAO,CAAC,CAAA,CAAE,WAAA,EAAY,GAAI,CAAA,CAAE,KAAA,CAAM,CAAC,CAAA;AAC/E,SAAS,MAAA,CAAO,CAAA,EAAW,GAAA,EAAa,IAAA,EAAuB;AAC7D,EAAA,IAAI,GAAA,KAAQ,IAAA,EAAM,OAAO,CAAA,KAAM,IAAI,IAAA,GAAQ,IAAA;AAC3C,EAAA,OAAO,MAAM,CAAA,GAAI,CAAA,EAAG,GAAG,CAAA,CAAA,GAAK,GAAG,GAAG,CAAA,CAAA,CAAA;AACpC;;;AC1UO,IAAM,aAAN,MAAoB;AAAA,EAKzB,YAAY,QAAA,EAAkB;AAH9B,IAAA,IAAA,CAAQ,IAAA,GAAO,CAAA;AACf,IAAA,IAAA,CAAQ,KAAA,GAAQ,CAAA;AAGd,IAAA,IAAA,CAAK,QAAQ,IAAI,KAAA,CAAqB,KAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAC,CAAA;AAAA,EAC7D;AAAA,EAEA,KAAK,IAAA,EAAe;AAClB,IAAA,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,IAAI,CAAA,GAAI,IAAA;AACxB,IAAA,IAAA,CAAK,IAAA,GAAA,CAAQ,IAAA,CAAK,IAAA,GAAO,CAAA,IAAK,KAAK,KAAA,CAAM,MAAA;AACzC,IAAA,IAAI,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,QAAQ,IAAA,CAAK,KAAA,EAAA;AAAA,EAC3C;AAAA,EAEA,IAAI,IAAA,GAAe;AACjB,IAAA,OAAO,IAAA,CAAK,KAAA;AAAA,EACd;AAAA;AAAA,EAGA,OAAA,GAAe;AACb,IAAA,MAAM,MAAW,EAAC;AAClB,IAAA,MAAM,GAAA,GAAM,KAAK,KAAA,CAAM,MAAA;AACvB,IAAA,MAAM,KAAA,GAAA,CAAS,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,QAAQ,GAAA,IAAO,GAAA;AAC/C,IAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,IAAA,CAAK,OAAO,CAAA,EAAA,EAAK;AACnC,MAAA,MAAM,CAAA,GAAI,IAAA,CAAK,KAAA,CAAA,CAAO,KAAA,GAAQ,KAAK,GAAG,CAAA;AACtC,MAAA,IAAI,CAAA,KAAM,MAAA,EAAW,GAAA,CAAI,IAAA,CAAK,CAAC,CAAA;AAAA,IACjC;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,KAAA,CAAqB,IAAA,CAAK,MAAM,MAAM,CAAA;AACvD,IAAA,IAAA,CAAK,IAAA,GAAO,CAAA;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,CAAA;AAAA,EACf;AAAA,EAEA,OAAO,QAAA,EAAwB;AAC7B,IAAA,MAAM,QAAA,GAAW,KAAK,OAAA,EAAQ;AAC9B,IAAA,IAAA,CAAK,QAAQ,IAAI,KAAA,CAAqB,KAAK,GAAA,CAAI,CAAA,EAAG,QAAQ,CAAC,CAAA;AAC3D,IAAA,IAAA,CAAK,IAAA,GAAO,CAAA;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,CAAA;AACb,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,KAAA,CAAM,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,QAAA,CAAS,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,MAAM,CAAC,CAAA;AAC5E,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,EAAM,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA;AAAA,EACzC;AACF;;;AC7BA,IAAM,GAAA,GAAM,MACV,OAAO,WAAA,KAAgB,WAAA,IAAe,OAAO,WAAA,CAAY,GAAA,KAAQ,UAAA,GAAa,WAAA,CAAY,GAAA,EAAI,GAAI,KAAK,GAAA,EAAI;AAY7G,IAAM,cAAoC,EAAC;AAC3C,IAAM,eAAA,GAAkB,GAAA;AACxB,IAAM,cAAA,GAAiB,GAAA;AA2DvB,IAAM,eAAe,OAAqC;AAAA,EACxD,KAAA,EAAO,CAAA;AAAA,EACP,KAAA,EAAO,CAAA;AAAA,EACP,KAAA,EAAO,CAAA;AAAA,EACP,MAAA,EAAQ,CAAA;AAAA,EACR,OAAA,EAAS,CAAA;AAAA,EACT,mBAAA,EAAqB,CAAA;AAAA,EACrB,OAAA,EAAS;AACX,CAAA,CAAA;AAEO,IAAM,YAAN,MAAgB;AAAA,EAgBrB,WAAA,GAAc;AAfd,IAAA,IAAA,CAAA,MAAA,GAA0B,EAAE,GAAG,aAAA,EAAc;AAC7C,IAAA,IAAA,CAAQ,KAAA,uBAAY,GAAA,EAAwB;AAE5C,IAAA,IAAA,CAAQ,SAAA,uBAAgB,GAAA,EAAkC;AAC1D,IAAA,IAAA,CAAQ,UAA2B,EAAC;AACpC,IAAA,IAAA,CAAQ,iBAAgE,EAAC;AAEzE;AAAA,IAAA,IAAA,CAAQ,GAAA,GAAM,CAAA;AACd,IAAA,IAAA,CAAQ,cAAA,GAAiB,KAAA;AAEzB,IAAA,IAAA,CAAQ,MAAA,GAAS,CAAA;AAEjB;AAAA,IAAA,IAAA,CAAS,aAAA,uBAAoB,OAAA,EAAoB;AACjD,IAAA,IAAA,CAAQ,WAAA,GAAc,KAAA;AAGpB,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,UAAA,CAAwB,IAAA,CAAK,OAAO,SAAS,CAAA;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,IAAA,CAAK,OAAA,GAA4B,EAAC,EAAc;AAC9C,IAAA,IAAA,CAAK,SAAA,CAAU,EAAE,OAAA,EAAS,CAAC,kBAAiB,EAAG,GAAG,SAAS,CAAA;AAC3D,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,SAAA,CAAU,OAAA,GAA4B,EAAC,EAAS;AAC9C,IAAA,MAAM,WAAA,GAAc,KAAK,MAAA,CAAO,SAAA;AAChC,IAAA,IAAA,CAAK,MAAA,GAAS,WAAA,CAAY,IAAA,CAAK,MAAA,EAAQ,OAAO,CAAA;AAC9C,IAAA,IAAI,IAAA,CAAK,OAAO,SAAA,KAAc,WAAA,OAAkB,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA;AAAA,EACrF;AAAA,EAEA,IAAI,aAAA,GAAyB;AAC3B,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA,EAEA,IAAI,OAAA,GAAmB;AACrB,IAAA,OAAO,KAAK,MAAA,CAAO,OAAA;AAAA,EACrB;AAAA,EAEA,UAAU,QAAA,EAAoD;AAC5D,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC3B,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,IAChC,CAAA;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,UAAA,CAAW,MAAc,MAAA,EAAwD;AAC/E,IAAA,IAAI,CAAC,gBAAA,CAAiB,IAAA,EAAM,IAAA,CAAK,MAAM,GAAG,OAAO,MAAA;AACjD,IAAA,MAAM,OAAA,GAAU,KAAK,MAAA,CAAO,YAAA,IAAgB,KAAK,IAAA,CAAK,MAAA,EAAO,GAAI,IAAA,CAAK,MAAA,CAAO,YAAA;AAC7E,IAAA,MAAM,IAAA,GAAmB;AAAA,MACvB,EAAA,EAAI,CAAA,IAAA,EAAO,EAAE,IAAA,CAAK,MAAM,CAAA,CAAA;AAAA,MACxB,IAAA;AAAA,MACA,MAAA;AAAA,MACA,KAAA,EAAO,MAAA,GAAS,MAAA,CAAO,KAAA,GAAQ,CAAA,GAAI,CAAA;AAAA,MACnC,OAAA;AAAA,MACA,QAAA,EAAU,CAAA;AAAA,MACV,cAAc,EAAC;AAAA,MACf,UAAA,EAAY,KAAA;AAAA,MACZ,YAAA,EAAc,CAAA;AAAA,MACd,cAAA,EAAgB,EAAA;AAAA,MAChB,WAAW,EAAC;AAAA,MACZ,KAAA,EAAO;AAAA,QACL,WAAA,EAAa,CAAA;AAAA,QACb,UAAA,EAAY,CAAA;AAAA,QACZ,mBAAA,EAAqB,CAAA;AAAA,QACrB,UAAA,EAAY,CAAA;AAAA,QACZ,iBAAA,EAAmB,CAAA;AAAA,QACnB,eAAA,EAAiB,CAAA;AAAA,QACjB,WAAA,EAAa,CAAA;AAAA,QACb,2BAAA,EAA6B,CAAA;AAAA,QAC7B,SAAS,YAAA;AAAa;AACxB,KACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,OAAO,IAAA,EAAwB;AAC7B,IAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAA,CAAK,EAAA,EAAI,IAAI,CAAA;AAAA,EAC9B;AAAA,EAEA,OAAO,IAAA,EAAwB;AAa7B,IAAA,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAAA,EAC3B;AAAA;AAAA,EAGA,aAAA,CAAc,MAAkB,KAAA,EAAsC;AACpE,IAAA,IAAA,CAAK,QAAA,EAAA;AACL,IAAA,IAAA,CAAK,YAAA,GAAe,KAAA;AAAA,EACtB;AAAA,EAEA,iBAAA,CAAkB,MAAkB,MAAA,EAAkC;AACpE,IAAA,IAAI,KAAK,YAAA,CAAa,MAAA,GAAS,IAAI,IAAA,CAAK,YAAA,CAAa,KAAK,MAAM,CAAA;AAAA,EAClE;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,YAAA,CAAa,MAAkB,MAAA,EAA2B;AACxD,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK;AAAA,MAChB,GAAG,MAAA;AAAA,MACH,IAAA;AAAA,MACA,UAAU,IAAA,CAAK,QAAA;AAAA,MACf,OAAO,IAAA,CAAK,YAAA;AAAA,MACZ,OAAO,IAAA,CAAK,YAAA,CAAa,MAAA,GAAS,CAAA,GAAI,KAAK,YAAA,GAAe,WAAA;AAAA,MAC1D,GAAA,EAAK,EAAE,IAAA,CAAK;AAAA,KACb,CAAA;AACD,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAClB,IAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAChB,IAAA,IAAA,CAAK,YAAA,GAAe,MAAA;AACpB,IAAA,IAAI,KAAK,YAAA,CAAa,MAAA,GAAS,CAAA,EAAG,IAAA,CAAK,eAAe,EAAC;AACvD,IAAA,IAAA,CAAK,iBAAiB,MAAA,CAAO,UAAA;AAC7B,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA,EAEA,oBAAoB,MAAA,EAA6B;AAC/C,IAAA,IAAA,CAAK,cAAA,CAAe,KAAK,EAAE,MAAA,EAAQ,KAAK,EAAE,IAAA,CAAK,KAAK,CAAA;AACpD,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA;AAAA,EAIQ,aAAA,GAAsB;AAC5B,IAAA,IAAI,KAAK,cAAA,EAAgB;AACzB,IAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AACtB,IAAA,cAAA,CAAe,MAAM;AACnB,MAAA,IAAA,CAAK,cAAA,GAAiB,KAAA;AACtB,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,CAAC,CAAA;AACD,IAAA,IAAA,CAAK,aAAA,EAAc;AAAA,EACrB;AAAA,EAEQ,aAAA,GAAsB;AAC5B,IAAA,IAAI,IAAA,CAAK,gBAAgB,MAAA,EAAW;AACpC,IAAA,IAAA,CAAK,WAAA,GAAc,WAAW,MAAM;AAClC,MAAA,IAAA,CAAK,WAAA,GAAc,MAAA;AACnB,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,KAAA,EAAM;AAAA,MACb,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF,GAAG,cAAc,CAAA;AAEjB,IAAC,IAAA,CAAK,YAAuC,KAAA,IAAQ;AAAA,EACvD;AAAA;AAAA,EAGQ,KAAA,GAAc;AACpB,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,EAAO,EAAG;AACtC,MAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,QAAA,IAAA,CAAK,KAAA,CAAM,uBAAuB,IAAA,CAAK,QAAA;AACvC,QAAA,IAAA,CAAK,QAAA,GAAW,CAAA;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,MAAA,KAAW,CAAA,EAAG;AAC7B,MAAA,IAAA,CAAK,eAAe,MAAA,GAAS,CAAA;AAC7B,MAAA;AAAA,IACF;AACA,IAAA,MAAM,QAAQ,IAAA,CAAK,OAAA;AACnB,IAAA,IAAA,CAAK,UAAU,EAAC;AAChB,IAAA,MAAM,kBAAkB,IAAA,CAAK,cAAA;AAC7B,IAAA,IAAA,CAAK,iBAAiB,EAAC;AACvB,IAAA,MAAM,WAAW,IAAA,CAAK,aAAA;AAQtB,IAAA,IAAI,QAAA,GAAW,EAAA;AACf,IAAA,KAAA,IAAS,IAAI,KAAA,CAAM,MAAA,GAAS,CAAA,EAAG,CAAA,IAAK,GAAG,CAAA,EAAA,EAAK;AAC1C,MAAA,MAAM,GAAA,GAAM,MAAM,CAAC,CAAA;AACnB,MAAA,IAAI,GAAA,CAAI,UAAA,IAAc,CAAA,EAAG,QAAA,GAAW,GAAA,CAAI,UAAA;AAAA,WAAA,IAC/B,QAAA,IAAY,CAAA,EAAG,GAAA,CAAI,UAAA,GAAa,QAAA;AAAA,WACpC,GAAA,CAAI,aAAa,GAAA,EAAI;AAAA,IAC5B;AACA,IAAA,MAAM,WAA4B,eAAA,CAAgB,GAAA,CAAI,CAAC,EAAE,MAAA,EAAQ,KAAI,KAAM;AACzE,MAAA,IAAI,MAAA,CAAO,UAAA,IAAc,CAAA,EAAG,OAAO,MAAA;AACnC,MAAA,MAAM,YAAY,KAAA,CAAM,IAAA,CAAK,CAAC,CAAA,KAAM,CAAA,CAAE,MAAM,GAAG,CAAA;AAC/C,MAAA,OAAO,EAAE,GAAG,MAAA,EAAQ,UAAA,EAAY,YAAY,SAAA,CAAU,UAAA,GAAc,KAAA,CAAM,KAAA,CAAM,MAAA,GAAS,CAAC,CAAA,EAAG,UAAA,IAAc,KAAI,EAAG;AAAA,IACpH,CAAC,CAAA;AAID,IAAA,MAAM,aAAA,uBAAoB,GAAA,EAA6B;AACvD,IAAA,MAAM,cAAA,uBAAqB,GAAA,EAAwB;AACnD,IAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,MAAA,IAAI,GAAA,GAAM,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA;AAC1C,MAAA,IAAI,CAAC,KAAK,aAAA,CAAc,GAAA,CAAI,IAAI,UAAA,EAAa,GAAA,mBAAM,IAAI,GAAA,EAAM,CAAA;AAC7D,MAAA,GAAA,CAAI,GAAA,CAAI,IAAI,IAAI,CAAA;AAAA,IAClB;AACA,IAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,MAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,MAAA;AACxB,MAAA,IAAI,CAAC,MAAA,EAAQ;AACb,MAAA,IAAI,CAAC,cAAc,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA,EAAG,GAAA,CAAI,MAAM,CAAA,EAAG;AACrD,MAAA,cAAA,CAAe,GAAA,CAAI,SAAS,cAAA,CAAe,GAAA,CAAI,MAAM,CAAA,IAAK,CAAA,IAAK,IAAI,eAAe,CAAA;AAAA,IACpF;AAcA,IAAA,MAAM,gBAAA,uBAAuB,GAAA,EAAgB;AAC7C,IAAA,MAAM,yBAAA,uBAAgC,GAAA,EAAgB;AACtD,IAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,MAAA,MAAM,OAAA,GAAU,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA;AAChD,MAAA,IAAI,GAAA,CAAI,QAAA,GAAW,CAAA,IAAK,GAAA,CAAI,IAAA,CAAK,MAAA,IAAU,OAAA,EAAS,GAAA,CAAI,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA,EAAG;AACxE,QAAA,gBAAA,CAAiB,GAAA,CAAI,GAAA,CAAI,IAAA,CAAK,MAAM,CAAA;AAAA,MACtC;AACA,MAAA,KAAA,IAAS,IAAI,GAAA,CAAI,IAAA,CAAK,QAAQ,CAAA,EAAG,CAAA,GAAI,EAAE,MAAA,EAAQ;AAC7C,QAAA,IAAI,SAAS,GAAA,CAAI,CAAC,CAAA,EAAG,yBAAA,CAA0B,IAAI,CAAC,CAAA;AAAA,MACtD;AAAA,IACF;AAEA,IAAA,KAAA,MAAW,OAAO,KAAA,EAAO;AACvB,MAAA,IAAI,CAAC,GAAA,CAAI,IAAA,CAAK,OAAA,EAAS;AACvB,MAAA,MAAM,UACJ,GAAA,CAAI,QAAA,GAAW,CAAA,IACf,GAAA,CAAI,UAAU,OAAA,IACd,gBAAA,CAAiB,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA,IAC7B,CAAC,yBAAA,CAA0B,GAAA,CAAI,IAAI,IAAI,CAAA;AACzC,MAAA,IAAI,CAAC,OAAA,EAAS;AACd,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,IAAA;AAAA,UACH,IAAA,CAAK,UAAA,CAAW,GAAA,CAAI,IAAA,EAAM,GAAA,EAAK,aAAA,EAAe,cAAA,EAAgB,QAAA,EAAU,gBAAA,EAAkB,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,IAAI,CAAC;AAAA,SAClH;AAAA,MACF,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,WACN,IAAA,EACA,GAAA,EACA,eACA,cAAA,EACA,QAAA,EACA,kBACA,UAAA,EACa;AACb,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,IAAA,MAAM,cAAA,GAAiB,MAAA,GAAS,aAAA,CAAc,GAAA,CAAI,GAAA,CAAI,UAAU,CAAA,EAAG,GAAA,CAAI,MAAM,CAAA,KAAM,IAAA,GAAO,KAAA;AAI1F,IAAA,MAAM,gBAAA,GAAmB,UAAA,GAAa,MAAA,GAAY,GAAA,CAAI,QAAA,GAAW,CAAA;AACjE,IAAA,MAAM,OAAA,GAAU,IAAI,KAAA,KAAU,OAAA;AAC9B,IAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,KAAA,IAAS,IAAA,CAAK,aAAa,EAAC;AAC9C,IAAA,MAAM,EAAE,SAAS,SAAA,EAAU,GACzB,WAAW,gBAAA,KAAqB,KAAA,GAC5B,EAAE,OAAA,EAAS,EAAC,EAAG,WAAW,MAAA,CAAO,IAAA,CAAK,KAAK,CAAA,EAAE,GAC7C,UAAU,IAAA,CAAK,SAAA,EAAW,KAAA,EAAO,IAAA,CAAK,MAAM,CAAA;AAClD,IAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAEjB,IAAA,MAAM,SAAA,GAAY,cAAA,CAAe,GAAA,CAAI,IAAI,CAAA,IAAK,CAAA;AAC9C,IAAA,MAAM,eAAe,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,GAAA,CAAI,kBAAkB,SAAS,CAAA;AAChE,IAAA,MAAM,gBAAA,GAAmB,SAAS,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,UAAA,KAAe,IAAI,UAAU,CAAA;AAC/E,IAAA,MAAM,eAAe,GAAA,CAAI,KAAA;AAEzB,IAAA,IAAA,CAAK,YAAA,EAAA;AACL,IAAA,MAAM,SAAA,GAAY,QAAA;AAAA,MAChB;AAAA,QACE,eAAe,IAAA,CAAK,IAAA;AAAA,QACpB,OAAO,GAAA,CAAI,KAAA;AAAA,QACX,YAAY,MAAA,EAAQ,IAAA;AAAA,QACpB,cAAA;AAAA,QACA,eAAe,CAAC,MAAA;AAAA,QAChB,gBAAA;AAAA,QACA,gBAAA,EAAkB,gBAAA,CAAiB,GAAA,CAAI,IAAI,CAAA;AAAA,QAC3C,YAAA,EAAc,OAAA;AAAA,QACd,cAAA,EAAgB,gBAAA;AAAA,QAChB,YAAA;AAAA,QACA,UAAU,GAAA,CAAI,QAAA;AAAA,QACd,SAAA,EAAW,IAAA;AAAA,QACX,YAAA;AAAA,QACA,qBAAA,EAAuB,KAAK,KAAA,CAAM;AAAA,OACpC;AAAA,MACA,KAAK,MAAA,CAAO;AAAA,KACd;AAEA,IAAA,MAAM,aAAA,GAA+B;AAAA,MACnC,IAAI,IAAA,CAAK,EAAA;AAAA,MACT,MAAM,IAAA,CAAK,IAAA;AAAA,MACX,UAAU,MAAA,EAAQ,EAAA;AAAA,MAClB,OAAO,IAAA,CAAK;AAAA,KACd;AAEA,IAAA,MAAM,KAAA,GAAqB;AAAA,MACzB,IAAI,CAAA,EAAG,IAAA,CAAK,EAAE,CAAA,CAAA,EAAI,KAAK,YAAY,CAAA,CAAA;AAAA,MACnC,SAAA,EAAW,aAAA;AAAA,MACX,WAAW,GAAA,CAAI,SAAA;AAAA,MACf,cAAc,IAAA,CAAK,YAAA;AAAA,MACnB,OAAO,GAAA,CAAI,KAAA;AAAA,MACX,OAAA,EAAS;AAAA,QACP,iBAAiB,GAAA,CAAI,eAAA;AAAA,QACrB,cAAc,GAAA,CAAI,YAAA;AAAA,QAClB,YAAA;AAAA,QACA,2BAAA,EAA6B,SAAA;AAAA,QAC7B,YAAY,GAAA,CAAI,UAAA;AAAA,QAChB,WAAW,GAAA,CAAI;AAAA,OACjB;AAAA,MACA,YAAA,EAAc,OAAA;AAAA,MACd,cAAA,EAAgB,SAAA;AAAA,MAChB,QAAQ,MAAA,GAAS,EAAE,EAAA,EAAI,MAAA,CAAO,IAAI,IAAA,EAAM,MAAA,CAAO,IAAA,EAAM,QAAA,EAAU,OAAO,MAAA,EAAQ,EAAA,EAAI,KAAA,EAAO,MAAA,CAAO,OAAM,GAAI,MAAA;AAAA,MAC1G,cAAA;AAAA,MACA,gBAAgB,gBAAA,KAAqB,KAAA;AAAA,MACrC,cAAA,EAAgB,gBAAA;AAAA,MAChB,YAAA;AAAA,MACA,SAAA,EAAW,IAAA;AAAA,MACX,QAAA,EAAU,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAI,QAAQ,CAAA;AAAA,MAClC,SAAA,EAAW,IAAI,QAAA,GAAW,CAAA;AAAA,MAC1B;AAAA,KACF;AAEA,IAAA,IAAA,CAAK,WAAA,CAAY,MAAM,KAAK,CAAA;AAC5B,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEQ,WAAA,CAAY,MAAkB,KAAA,EAA0B;AAC9D,IAAA,MAAM,IAAI,IAAA,CAAK,KAAA;AACf,IAAA,CAAA,CAAE,WAAA,EAAA;AACF,IAAA,IAAI,KAAA,CAAM,KAAA,KAAU,OAAA,EAAS,CAAA,CAAE,UAAA,EAAA;AAC/B,IAAA,IAAI,KAAA,CAAM,WAAW,CAAA,CAAE,UAAA,EAAA;AACvB,IAAA,MAAM,CAAA,GAAI,MAAM,OAAA,CAAQ,YAAA;AACxB,IAAA,CAAA,CAAE,iBAAA,IAAqB,CAAA;AACvB,IAAA,IAAI,CAAA,GAAI,CAAA,CAAE,eAAA,EAAiB,CAAA,CAAE,eAAA,GAAkB,CAAA;AAC/C,IAAA,IAAI,CAAA,IAAK,IAAA,CAAK,MAAA,CAAO,mBAAA,EAAqB,CAAA,CAAE,WAAA,EAAA;AAC5C,IAAA,IAAI,KAAA,CAAM,SAAA,CAAU,oBAAA,EAAsB,CAAA,CAAE,2BAAA,EAAA;AAC5C,IAAA,CAAA,CAAE,OAAA,CAAQ,KAAA,CAAM,SAAA,CAAU,MAAM,CAAA,EAAA;AAChC,IAAA,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAA;AACrB,IAAA,IAAI,KAAK,SAAA,CAAU,MAAA,GAAS,eAAA,EAAiB,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,EACpE;AAAA,EAEQ,KAAK,KAAA,EAA0B;AACrC,IAAA,IAAA,CAAK,MAAA,CAAO,KAAK,KAAK,CAAA;AACtB,IAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,IAAA,CAAK,MAAA;AACzB,IAAA,IAAI,OAAA,EAAS;AACX,MAAA,IAAI;AACF,QAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,MACf,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,SAAA,EAAW;AACrC,MAAA,IAAI;AACF,QAAA,QAAA,CAAS,KAAK,CAAA;AAAA,MAChB,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAIA,SAAA,GAA2B;AACzB,IAAA,IAAA,CAAK,KAAA,EAAM;AACX,IAAA,OAAO,IAAA,CAAK,OAAO,OAAA,EAAQ;AAAA,EAC7B;AAAA,EAEA,kBAAkB,IAAA,EAAiC;AACjD,IAAA,IAAA,CAAK,KAAA,EAAM;AACX,IAAA,MAAM,MAAwB,EAAC;AAC/B,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,EAAO,EAAG;AACtC,MAAA,IAAI,IAAA,IAAQ,IAAA,CAAK,IAAA,KAAS,IAAA,EAAM;AAChC,MAAA,IAAI,KAAK,KAAA,CAAM,WAAA,KAAgB,KAAK,IAAA,CAAK,KAAA,CAAM,wBAAwB,CAAA,EAAG;AAC1E,MAAA,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,IAAI,CAAC,CAAA;AAAA,IACxB;AACA,IAAA,OAAO,GAAA;AAAA,EACT;AAAA,EAEA,QAAA,GAAqB;AACnB,IAAA,MAAM,GAAA,GAAM,KAAK,iBAAA,EAAkB;AACnC,IAAA,MAAM,MAAA,uBAAa,GAAA,EAA4B;AAC/C,IAAA,KAAA,MAAW,KAAK,GAAA,EAAK;AACnB,MAAA,MAAM,QAAA,GAAW,MAAA,CAAO,GAAA,CAAI,CAAA,CAAE,IAAI,CAAA;AAClC,MAAA,MAAA,CAAO,GAAA,CAAI,EAAE,IAAA,EAAM,QAAA,GAAW,WAAW,QAAA,EAAU,CAAC,IAAI,CAAC,CAAA;AAAA,IAC3D;AACA,IAAA,MAAM,MAAA,GAAS,CAAC,GAAG,MAAA,CAAO,QAAQ,CAAA;AAClC,IAAA,OAAO;AAAA,MACL,YAAY,MAAA,CAAO,MAAA;AAAA,MACnB,YAAA,EAAc,OAAO,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,WAAA,EAAa,CAAC,CAAA;AAAA,MAC1D,eAAA,EAAiB,OAAO,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,iBAAA,EAAmB,CAAC,CAAA;AAAA,MACnE,WAAA,EAAa,OAAO,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,WAAA,EAAa,CAAC,CAAA;AAAA,MACzD,2BAAA,EAA6B,OAAO,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,2BAAA,EAA6B,CAAC,CAAA;AAAA,MACzF,UAAA,EAAY,OAAO,MAAA,CAAO,CAAC,GAAG,CAAA,KAAM,CAAA,GAAI,CAAA,CAAE,UAAA,EAAY,CAAC,CAAA;AAAA,MACvD,SAAS,CAAC,GAAG,MAAM,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,kBAAkB,CAAA,CAAE,eAAe,CAAA,CAAE,KAAA,CAAM,GAAG,EAAE,CAAA;AAAA,MACtF,cAAc,CAAC,GAAG,MAAM,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,cAAc,CAAA,CAAE,WAAW,CAAA,CAAE,KAAA,CAAM,GAAG,EAAE,CAAA;AAAA,MACnF,eAAe,CAAC,GAAG,MAAM,CAAA,CAAE,KAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,oBAAoB,CAAA,CAAE,iBAAiB,CAAA,CAAE,KAAA,CAAM,GAAG,EAAE;AAAA,KAClG;AAAA,EACF;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,OAAO,KAAA,EAAM;AAClB,IAAA,IAAA,CAAK,QAAQ,MAAA,GAAS,CAAA;AACtB,IAAA,IAAA,CAAK,eAAe,MAAA,GAAS,CAAA;AAC7B,IAAA,KAAA,MAAW,IAAA,IAAQ,IAAA,CAAK,KAAA,CAAM,MAAA,EAAO,EAAG;AACtC,MAAA,IAAA,CAAK,KAAA,GAAQ;AAAA,QACX,WAAA,EAAa,CAAA;AAAA,QACb,UAAA,EAAY,CAAA;AAAA,QACZ,mBAAA,EAAqB,CAAA;AAAA,QACrB,UAAA,EAAY,CAAA;AAAA,QACZ,iBAAA,EAAmB,CAAA;AAAA,QACnB,eAAA,EAAiB,CAAA;AAAA,QACjB,WAAA,EAAa,CAAA;AAAA,QACb,2BAAA,EAA6B,CAAA;AAAA,QAC7B,SAAS,YAAA;AAAa,OACxB;AACA,MAAA,IAAA,CAAK,UAAU,MAAA,GAAS,CAAA;AACxB,MAAA,IAAA,CAAK,YAAA,GAAe,CAAA;AAAA,IACtB;AAAA,EACF;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,KAAA,EAAM;AACX,IAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AACjB,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,IAAA,IAAI,IAAA,CAAK,WAAA,KAAgB,MAAA,EAAW,YAAA,CAAa,KAAK,WAAW,CAAA;AACjE,IAAA,IAAA,CAAK,WAAA,GAAc,MAAA;AACnB,IAAA,IAAA,CAAK,MAAA,GAAS,EAAE,GAAG,aAAA,EAAc;AACjC,IAAA,IAAA,CAAK,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,MAAA,CAAO,SAAS,CAAA;AACxC,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AAAA,EACrB;AACF;AAEA,SAAS,UAAA,CAAW,QAAkB,CAAA,EAAmB;AACvD,EAAA,IAAI,MAAA,CAAO,MAAA,KAAW,CAAA,EAAG,OAAO,CAAA;AAChC,EAAA,MAAM,MAAM,IAAA,CAAK,GAAA,CAAI,MAAA,CAAO,MAAA,GAAS,GAAG,IAAA,CAAK,GAAA,CAAI,CAAA,EAAG,IAAA,CAAK,KAAM,CAAA,GAAI,GAAA,GAAO,OAAO,MAAM,CAAA,GAAI,CAAC,CAAC,CAAA;AAC7F,EAAA,OAAO,OAAO,GAAG,CAAA;AACnB;AAEA,SAAS,QAAQ,IAAA,EAAkC;AACjD,EAAA,MAAM,MAAA,GAAS,CAAC,GAAG,IAAA,CAAK,SAAS,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,GAAI,CAAC,CAAA;AACvD,EAAA,MAAM,IAAI,IAAA,CAAK,KAAA;AACf,EAAA,OAAO;AAAA,IACL,IAAI,IAAA,CAAK,EAAA;AAAA,IACT,MAAM,IAAA,CAAK,IAAA;AAAA,IACX,aAAa,CAAA,CAAE,WAAA;AAAA,IACf,YAAY,CAAA,CAAE,UAAA;AAAA,IACd,qBAAqB,CAAA,CAAE,mBAAA;AAAA,IACvB,YAAY,CAAA,CAAE,UAAA;AAAA,IACd,mBAAmB,CAAA,CAAE,iBAAA;AAAA,IACrB,qBAAqB,CAAA,CAAE,WAAA,GAAc,CAAA,CAAE,iBAAA,GAAoB,EAAE,WAAA,GAAc,CAAA;AAAA,IAC3E,kBAAA,EAAoB,UAAA,CAAW,MAAA,EAAQ,EAAE,CAAA;AAAA,IACzC,eAAA,EAAiB,UAAA,CAAW,MAAA,EAAQ,EAAE,CAAA;AAAA,IACtC,eAAA,EAAiB,UAAA,CAAW,MAAA,EAAQ,EAAE,CAAA;AAAA,IACtC,iBAAiB,CAAA,CAAE,eAAA;AAAA,IACnB,aAAa,CAAA,CAAE,WAAA;AAAA,IACf,6BAA6B,CAAA,CAAE,2BAAA;AAAA,IAC/B,OAAA,EAAS,EAAE,GAAG,CAAA,CAAE,OAAA;AAAQ,GAC1B;AACF;AAEA,SAAS,UAAA,CAAW,GAAmB,CAAA,EAAmC;AACxE,EAAA,MAAM,WAAA,GAAc,CAAA,CAAE,WAAA,GAAc,CAAA,CAAE,WAAA;AACtC,EAAA,MAAM,KAAA,GAAQ,CAAA,CAAE,iBAAA,GAAoB,CAAA,CAAE,iBAAA;AACtC,EAAA,MAAM,OAAA,GAAU,EAAE,GAAG,CAAA,CAAE,OAAA,EAAQ;AAC/B,EAAA,KAAA,MAAW,GAAA,IAAO,MAAA,CAAO,IAAA,CAAK,CAAA,CAAE,OAAO,CAAA,EAAqB,OAAA,CAAQ,GAAG,CAAA,IAAK,CAAA,CAAE,OAAA,CAAQ,GAAG,CAAA;AACzF,EAAA,OAAO;AAAA,IACL,IAAI,CAAA,CAAE,EAAA;AAAA,IACN,MAAM,CAAA,CAAE,IAAA;AAAA,IACR,WAAA;AAAA,IACA,UAAA,EAAY,CAAA,CAAE,UAAA,GAAa,CAAA,CAAE,UAAA;AAAA,IAC7B,mBAAA,EAAqB,CAAA,CAAE,mBAAA,GAAsB,CAAA,CAAE,mBAAA;AAAA,IAC/C,UAAA,EAAY,CAAA,CAAE,UAAA,GAAa,CAAA,CAAE,UAAA;AAAA,IAC7B,iBAAA,EAAmB,KAAA;AAAA,IACnB,mBAAA,EAAqB,WAAA,GAAc,KAAA,GAAQ,WAAA,GAAc,CAAA;AAAA,IACzD,oBAAoB,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,kBAAA,EAAoB,EAAE,kBAAkB,CAAA;AAAA,IACvE,iBAAiB,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,eAAA,EAAiB,EAAE,eAAe,CAAA;AAAA,IAC9D,iBAAiB,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,eAAA,EAAiB,EAAE,eAAe,CAAA;AAAA,IAC9D,iBAAiB,IAAA,CAAK,GAAA,CAAI,CAAA,CAAE,eAAA,EAAiB,EAAE,eAAe,CAAA;AAAA,IAC9D,WAAA,EAAa,CAAA,CAAE,WAAA,GAAc,CAAA,CAAE,WAAA;AAAA,IAC/B,2BAAA,EAA6B,CAAA,CAAE,2BAAA,GAA8B,CAAA,CAAE,2BAAA;AAAA,IAC/D;AAAA,GACF;AACF;AAQA,IAAM,GAAA,mBAAM,MAAA,CAAO,GAAA,CAAI,iCAAiC,CAAA;AAGjD,SAAS,YAAA,GAA0B;AACxC,EAAA,MAAM,CAAA,GAAI,UAAA;AACV,EAAA,IAAI,CAAC,EAAE,GAAG,CAAA,IAAK,GAAG,CAAA,GAAI,IAAI,SAAA,EAAU;AACpC,EAAA,OAAO,EAAE,GAAG,CAAA;AACd","file":"chunk-27IWHWSM.js","sourcesContent":["import type { Inspected, InspectionLimits, PropValueType } from \"./types.js\";\n\nconst REACT_ELEMENT = Symbol.for(\"react.element\");\nconst REACT_TRANSITIONAL_ELEMENT = Symbol.for(\"react.transitional.element\");\n\nexport function isReactElement(value: unknown): boolean {\n if (typeof value !== \"object\" || value === null) return false;\n const t = (value as { $$typeof?: symbol }).$$typeof;\n return t === REACT_ELEMENT || t === REACT_TRANSITIONAL_ELEMENT;\n}\n\nexport function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== \"object\" || value === null) return false;\n if (Array.isArray(value)) return false;\n if (isReactElement(value)) return false;\n const proto = Object.getPrototypeOf(value);\n return proto === Object.prototype || proto === null;\n}\n\nexport function valueType(value: unknown): PropValueType {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n if (isReactElement(value)) return \"element\";\n const t = typeof value;\n if (t === \"object\") return \"object\";\n if (t === \"function\") return \"function\";\n return t as PropValueType;\n}\n\nfunction elementName(value: unknown): string {\n const type = (value as { type?: unknown }).type;\n if (typeof type === \"string\") return type;\n if (typeof type === \"function\") return (type as { displayName?: string; name?: string }).displayName ?? (type as { name?: string }).name ?? \"Anonymous\";\n return \"Element\";\n}\n\n/**\n * Bounded, cycle-safe, non-retaining snapshot.\n *\n * Deliberately not `JSON.stringify`: that throws on cycles and BigInt, drops\n * `undefined`/functions/symbols, and has no size ceiling.\n */\nexport function inspect(value: unknown, limits: InspectionLimits): Inspected {\n const budget = { nodes: limits.maxSerializedNodes };\n try {\n return walk(value, limits, budget, limits.depth, new WeakSet<object>());\n } catch {\n return { t: \"truncated\", hint: \"inspection failed\" };\n }\n}\n\nfunction walk(\n value: unknown,\n limits: InspectionLimits,\n budget: { nodes: number },\n depth: number,\n seen: WeakSet<object>,\n): Inspected {\n if (budget.nodes-- <= 0) return { t: \"truncated\", hint: \"size limit\" };\n\n if (value === undefined) return { t: \"undefined\" };\n if (value === null) return { t: \"primitive\", v: null };\n\n const type = typeof value;\n if (type === \"number\") return Number.isNaN(value) ? { t: \"nan\" } : { t: \"primitive\", v: value as number };\n if (type === \"boolean\") return { t: \"primitive\", v: value as boolean };\n if (type === \"string\") {\n const s = value as string;\n return {\n t: \"primitive\",\n v: s.length > limits.maxStringLength ? `${s.slice(0, limits.maxStringLength)}…(+${s.length - limits.maxStringLength})` : s,\n };\n }\n if (type === \"symbol\") return { t: \"symbol\", v: String(value) };\n if (type === \"bigint\") return { t: \"bigint\", v: `${String(value)}n` };\n if (type === \"function\") {\n const fn = value as { displayName?: string; name?: string };\n return { t: \"function\", name: fn.displayName ?? fn.name ?? \"anonymous\" };\n }\n\n const obj = value as object;\n if (seen.has(obj)) return { t: \"circular\" };\n seen.add(obj);\n\n if (isReactElement(obj)) return { t: \"element\", name: elementName(obj) };\n\n if (Array.isArray(obj)) {\n const length = obj.length;\n if (depth <= 0) return { t: \"array\", length };\n const take = Math.min(length, limits.maxArrayLength);\n const items: Inspected[] = [];\n for (let i = 0; i < take; i++) items.push(walk(obj[i], limits, budget, depth - 1, seen));\n return { t: \"array\", length, items, truncated: take < length };\n }\n\n const ctor = objectTag(obj);\n let keys: string[];\n try {\n keys = Object.keys(obj as Record<string, unknown>);\n } catch {\n return { t: \"object\", ctor };\n }\n if (depth <= 0) {\n return { t: \"object\", ctor, keys: keys.slice(0, limits.maxObjectKeys), truncated: keys.length > limits.maxObjectKeys };\n }\n const take = Math.min(keys.length, limits.maxObjectKeys);\n const entries: Record<string, Inspected> = {};\n for (let i = 0; i < take; i++) {\n const k = keys[i] as string;\n let v: unknown;\n try {\n v = (obj as Record<string, unknown>)[k];\n } catch {\n // A throwing getter must never take down the app being debugged.\n entries[k] = { t: \"truncated\", hint: \"getter threw\" };\n continue;\n }\n entries[k] = walk(v, limits, budget, depth - 1, seen);\n }\n return { t: \"object\", ctor, entries, truncated: take < keys.length };\n}\n\nfunction objectTag(obj: object): string | undefined {\n const proto = Object.getPrototypeOf(obj);\n if (proto === Object.prototype || proto === null) return undefined;\n const name = proto?.constructor?.name;\n return typeof name === \"string\" && name !== \"Object\" ? name : undefined;\n}\n\n/** Single-line rendering for console output. */\nexport function formatInspected(node: Inspected | undefined): string {\n if (!node) return \"…\";\n switch (node.t) {\n case \"primitive\":\n return typeof node.v === \"string\" ? JSON.stringify(node.v) : String(node.v);\n case \"undefined\":\n return \"undefined\";\n case \"nan\":\n return \"NaN\";\n case \"symbol\":\n case \"bigint\":\n return node.v;\n case \"function\":\n return `ƒ ${node.name}()`;\n case \"element\":\n return `<${node.name} />`;\n case \"circular\":\n return \"[Circular]\";\n case \"truncated\":\n return `[… ${node.hint}]`;\n case \"array\": {\n if (!node.items) return `Array(${node.length})`;\n const body = node.items.map(formatInspected).join(\", \");\n return `[${body}${node.truncated ? \", …\" : \"\"}]`;\n }\n case \"object\": {\n const prefix = node.ctor ? `${node.ctor} ` : \"\";\n if (node.entries) {\n const body = Object.entries(node.entries)\n .map(([k, v]) => `${k}: ${formatInspected(v)}`)\n .join(\", \");\n return `${prefix}{ ${body}${node.truncated ? \", …\" : \"\"} }`;\n }\n if (node.keys) return `${prefix}{ ${node.keys.join(\", \")}${node.truncated ? \", …\" : \"\"} }`;\n return `${prefix}{…}`;\n }\n }\n}\n","import type { DetectiveConfig, DetectiveOptions } from \"./types.js\";\n\ndeclare const process: { env?: Record<string, string | undefined> } | undefined;\n\n/**\n * Positive production detection.\n *\n * Deliberately asymmetric: this returns `true` only when it can actually *see*\n * `NODE_ENV === \"production\"`. Anything else — including environments where\n * `process` does not exist at all, such as a Vite dev server in the browser —\n * is \"not known to be production\".\n *\n * The earlier version asked the opposite question (\"is this dev?\") and answered\n * `false` when it could not tell, which meant the documented Vite quick-start\n * turned the tool on and then silently recorded nothing.\n */\nexport function detectProduction(): boolean {\n try {\n const env = typeof process !== \"undefined\" ? process?.env : undefined;\n if (env && env.NODE_ENV) return env.NODE_ENV === \"production\";\n } catch {\n /* ignore */\n }\n return false;\n}\n\n/** @deprecated Use `detectProduction()`. Kept so existing imports keep working. */\nexport function detectDev(): boolean {\n return !detectProduction();\n}\n\nexport const defaultConfig: DetectiveConfig = {\n // Off until `init()` is called, so importing the package costs nothing.\n enabled: false,\n mode: \"console\",\n include: [],\n exclude: [],\n samplingRate: 1,\n maxEvents: 1000,\n slowRenderThreshold: 16,\n thresholds: { monitor: 5, slow: 16, verySlow: 50, critical: 100 },\n inspection: {\n depth: 1,\n maxObjectKeys: 20,\n maxArrayLength: 20,\n maxStringLength: 120,\n maxSerializedNodes: 200,\n },\n compareFunctionSource: false,\n};\n\nexport function mergeConfig(base: DetectiveConfig, options: DetectiveOptions = {}): DetectiveConfig {\n const { thresholds, inspection, ...rest } = options;\n const next: DetectiveConfig = {\n ...base,\n ...(rest as Partial<DetectiveConfig>),\n thresholds: { ...base.thresholds, ...thresholds },\n inspection: { ...base.inspection, ...inspection },\n };\n next.samplingRate = clamp(next.samplingRate, 0, 1);\n next.maxEvents = Math.max(1, Math.floor(next.maxEvents));\n next.inspection.depth = clamp(Math.floor(next.inspection.depth), 0, 6);\n return next;\n}\n\nfunction clamp(n: number, lo: number, hi: number): number {\n if (typeof n !== \"number\" || Number.isNaN(n)) return lo;\n return Math.min(hi, Math.max(lo, n));\n}\n\nexport function matches(name: string, patterns: Array<string | RegExp>): boolean {\n for (const p of patterns) {\n if (typeof p === \"string\" ? p === name : p.test(name)) return true;\n }\n return false;\n}\n\n/** Filter policy: exclude wins over include; empty include means \"everything\". */\nexport function shouldInstrument(name: string, config: DetectiveConfig): boolean {\n if (matches(name, config.exclude)) return false;\n if (config.include.length > 0 && !matches(name, config.include)) return false;\n return true;\n}\n","import { inspect, isPlainObject, isReactElement, valueType } from \"./inspect.js\";\nimport type { DetectiveConfig, Inspected, PropChange } from \"./types.js\";\n\nexport interface PropsDiff {\n changed: PropChange[];\n unchanged: string[];\n}\n\n/** Result of a bounded contents comparison. `undefined` = could not determine. */\ntype ShallowResult = boolean | undefined;\n\nconst EMPTY: Record<string, unknown> = {};\n\nexport function diffProps(\n previous: Record<string, unknown> | undefined,\n current: Record<string, unknown> | undefined,\n config: DetectiveConfig,\n): PropsDiff {\n const prev = previous ?? EMPTY;\n const next = current ?? EMPTY;\n const changed: PropChange[] = [];\n const unchanged: string[] = [];\n\n const keys = new Set<string>();\n for (const k in prev) keys.add(k);\n for (const k in next) keys.add(k);\n\n for (const key of keys) {\n const hadPrev = key in prev;\n const hasNext = key in next;\n const a = prev[key];\n const b = next[key];\n\n if (hadPrev && hasNext && Object.is(a, b)) {\n unchanged.push(key);\n continue;\n }\n if (!hadPrev) {\n changed.push({ key, kind: \"added\", valueType: valueType(b), current: snap(b, config) });\n continue;\n }\n if (!hasNext) {\n changed.push({ key, kind: \"removed\", valueType: valueType(a), previous: snap(a, config) });\n continue;\n }\n changed.push(describeChange(key, a, b, config));\n }\n\n return { changed, unchanged };\n}\n\nfunction describeChange(key: string, a: unknown, b: unknown, config: DetectiveConfig): PropChange {\n const type = valueType(b);\n const base: PropChange = {\n key,\n kind: \"value\",\n valueType: type,\n previous: snap(a, config),\n current: snap(b, config),\n };\n\n if (typeof a === \"function\" && typeof b === \"function\") {\n base.kind = \"reference\";\n if (config.compareFunctionSource) {\n base.sourceEqual = safeSource(a) === safeSource(b);\n }\n return base;\n }\n\n const shallow = shallowEqual(a, b, config);\n if (shallow === true) {\n base.kind = \"reference\";\n base.shallowEqual = true;\n } else if (shallow === false) {\n base.kind = \"value\";\n base.shallowEqual = false;\n }\n return base;\n}\n\n/**\n * Bounded shallow comparison. Returns `undefined` rather than guessing when the\n * values are too large or of a shape we cannot compare cheaply — the diagnostic\n * engine treats that as \"unknown\", never as \"equal\".\n */\nexport function shallowEqual(a: unknown, b: unknown, config: DetectiveConfig): ShallowResult {\n if (Object.is(a, b)) return true;\n if (typeof a !== \"object\" || typeof b !== \"object\" || a === null || b === null) return false;\n\n const { maxObjectKeys, maxArrayLength } = config.inspection;\n\n if (Array.isArray(a) || Array.isArray(b)) {\n if (!Array.isArray(a) || !Array.isArray(b)) return false;\n if (a.length !== b.length) return false;\n if (a.length > maxArrayLength) return undefined;\n for (let i = 0; i < a.length; i++) if (!Object.is(a[i], b[i])) return false;\n return true;\n }\n\n if (a instanceof Date || b instanceof Date) {\n return a instanceof Date && b instanceof Date ? a.getTime() === b.getTime() : false;\n }\n\n if (isReactElement(a) && isReactElement(b)) {\n const ea = a as { type: unknown; key: unknown; props: unknown };\n const eb = b as { type: unknown; key: unknown; props: unknown };\n if (ea.type !== eb.type || ea.key !== eb.key) return false;\n return shallowEqual(ea.props, eb.props, config);\n }\n\n if (!isPlainObject(a) || !isPlainObject(b)) return undefined;\n\n const ka = Object.keys(a);\n const kb = Object.keys(b);\n if (ka.length !== kb.length) return false;\n if (ka.length > maxObjectKeys) return undefined;\n for (const k of ka) {\n if (!Object.prototype.hasOwnProperty.call(b, k)) return false;\n if (!Object.is(a[k], b[k])) return false;\n }\n return true;\n}\n\nfunction snap(value: unknown, config: DetectiveConfig): Inspected {\n return inspect(value, config.inspection);\n}\n\nfunction safeSource(fn: unknown): string {\n try {\n return Function.prototype.toString.call(fn);\n } catch {\n return \"\";\n }\n}\n","import { formatInspected } from \"./inspect.js\";\nimport type {\n Confidence,\n ContextChange,\n TrackedStateChange,\n Diagnosis,\n PropChange,\n RenderPhase,\n Thresholds,\n} from \"./types.js\";\n\nexport interface DiagnosisInput {\n componentName: string;\n phase: RenderPhase;\n parentName?: string;\n /** Nearest instrumented ancestor re-rendered in this same commit. */\n parentRendered: boolean;\n /** True when we have no instrumented ancestor, so `parentRendered` is unknown. */\n parentUnknown: boolean;\n /**\n * Did something above re-evaluate this component's props?\n * `true` — the wrapper re-rendered, so the render came from above.\n * `false` — it did not, so the render started here or below.\n * `undefined` — hook mode, where the two cannot be told apart.\n */\n propsReevaluated: boolean | undefined;\n /** An instrumented child re-rendered from above, proving this component rendered. */\n selfRenderProven: boolean;\n changedProps: PropChange[];\n contextChanges: ContextChange[];\n /** Named state updates from `useTrackedState`. Empty unless opted in. */\n trackedState: TrackedStateChange[];\n selfDuration: number;\n attempts: number;\n committed: boolean;\n /** How many times this component already produced a \"no observable change\" render. */\n priorAvoidableRenders: number;\n}\n\nexport function severityFor(duration: number, t: Thresholds): Diagnosis[\"severity\"] {\n if (duration >= t.critical) return \"critical\";\n if (duration >= t.verySlow) return \"very-slow\";\n if (duration >= t.slow) return \"slow\";\n if (duration >= t.monitor) return \"monitor\";\n return \"normal\";\n}\n\n/**\n * Pure. No React, no globals, no I/O — so diagnostic correctness can be tested\n * directly (§70).\n */\nexport function diagnose(input: DiagnosisInput, thresholds: Thresholds): Diagnosis {\n const severity = severityFor(input.selfDuration, thresholds);\n const d = classify(input);\n d.severity = severity;\n\n if (!input.committed) {\n d.evidence.unshift(\n \"This render attempt was not committed — React discarded it (concurrent interruption or a development replay). It is excluded from statistics.\",\n );\n } else if (input.attempts > 1) {\n d.evidence.push(\n `Render function ran ${input.attempts}× for one commit — a development replay (StrictMode double-invoke or a discarded attempt). Not production behaviour.`,\n );\n }\n\n if (severity === \"critical\" || severity === \"very-slow\") {\n d.evidence.push(`Render cost ${fmt(input.selfDuration)} — above the ${thresholds.verySlow}ms threshold.`);\n }\n return d;\n}\n\nfunction classify(input: DiagnosisInput): Diagnosis {\n const { changedProps, contextChanges, parentRendered, parentUnknown, parentName } = input;\n\n if (input.phase === \"mount\") {\n return make(\"mount\", \"high\", `${input.componentName} mounted.`, [\"First render of this instance.\"], false);\n }\n\n if (input.trackedState.length > 0) {\n const names = input.trackedState.map((s) => s.name);\n const evidence = input.trackedState.map(\n (s) => `\\`${s.name}\\`: ${formatInspected(s.previous)} → ${formatInspected(s.current)}`,\n );\n if (changedProps.length > 0) {\n evidence.push(`Props also changed: ${changedProps.map((c) => c.key).join(\", \")}.`);\n }\n return make(\n \"state\",\n \"high\",\n `${input.componentName} rendered because its own state changed: ${names.join(\", \")}.`,\n evidence,\n false,\n );\n }\n\n if (changedProps.length > 0) {\n const meaningful = changedProps.filter((c) => c.kind !== \"reference\");\n const referenceOnly = changedProps.filter((c) => c.kind === \"reference\");\n\n if (meaningful.length > 0) {\n const keys = meaningful.map((c) => c.key);\n const evidence = [\n `Props changed with new values: ${keys.join(\", \")}.`,\n ...meaningful.map(describe),\n ];\n if (referenceOnly.length > 0) {\n evidence.push(\n `Also changed by reference only (contents identical): ${referenceOnly.map((c) => c.key).join(\", \")}.`,\n );\n }\n return make(\n \"props\",\n \"high\",\n `${input.componentName} rendered because ${plural(keys.length, \"prop\")} changed: ${keys.join(\", \")}.`,\n evidence,\n false,\n referenceOnly.length > 0 ? stabiliseSuggestion(referenceOnly, parentName) : undefined,\n );\n }\n\n // Every changed prop is a reference change with equal (or unknown) contents.\n const keys = referenceOnly.map((c) => c.key);\n const evidence = [\n `${plural(keys.length, \"prop\")} changed by reference only: ${keys.join(\", \")}.`,\n ...referenceOnly.map(describe),\n ];\n if (parentRendered && parentName) {\n evidence.push(`${parentName} re-rendered in the same commit and recreated ${keys.length > 1 ? \"these values\" : `\\`${keys[0]}\\``}.`);\n }\n const confidence: Confidence = referenceOnly.some((c) => c.shallowEqual === true || c.valueType === \"function\")\n ? \"medium\"\n : \"low\";\n return make(\n \"props\",\n confidence,\n `${input.componentName} rendered because ${keys.join(\", \")} changed by reference — the contents did not.`,\n evidence,\n true,\n stabiliseSuggestion(referenceOnly, parentName),\n );\n }\n\n // Nothing about the props changed.\n if (input.propsReevaluated === false) {\n // The wrapper never re-ran: no new props came from above, so the render\n // began at this component or below it.\n if (contextChanges.length > 0) {\n const c = contextChanges[0] as ContextChange;\n const detail = c.changedKeys.length > 0 ? ` Changed: ${c.changedKeys.join(\", \")}.` : \"\";\n return make(\n \"context\",\n \"medium\",\n `${input.componentName} rendered after ${c.contextName} updated in the same commit.${detail}`,\n [\n \"No new props came from above — the render started at this component.\",\n `Tracked context ${c.contextName} changed in this commit.`,\n c.referenceOnly\n ? `${c.contextName}'s value changed by reference only — its contents are identical.`\n : `${c.contextName}'s contents changed.`,\n \"React does not expose which contexts a component subscribes to, so this is correlation within one commit, not a recorded subscription.\",\n ],\n c.referenceOnly,\n c.referenceOnly\n ? `${c.contextName}'s provider recreates its value every render. Stabilise it with useMemo if consumers are doing real work.`\n : undefined,\n );\n }\n return make(\n \"state-or-external\",\n input.selfRenderProven ? \"high\" : \"medium\",\n `${input.componentName} rendered from inside itself — local state, a store subscription, or a forced update.`,\n [\n \"No new props came from above: the wrapper did not re-render.\",\n input.selfRenderProven\n ? \"An instrumented child re-rendered from above in this commit, which proves this component produced it.\"\n : \"No instrumented descendant rendered in this commit, so an uninstrumented descendant could in principle be the origin instead.\",\n \"React does not expose hook state without private internals, so the exact source is not observable. Use useTrackedState to name it.\",\n ],\n false,\n );\n }\n\n if (input.propsReevaluated === true) {\n // The wrapper re-rendered with identical props — pure propagation.\n const known = parentRendered && parentName;\n return make(\n \"parent\",\n known && contextChanges.length === 0 ? \"high\" : \"medium\",\n `${input.componentName} rendered because its parent rendered — its own inputs did not change.`,\n [\n known\n ? `${parentName} re-rendered in this commit.`\n : \"Something above re-rendered this component, but the nearest instrumented ancestor did not — an uninstrumented component sits in between.\",\n \"Every prop is identical by reference.\",\n contextChanges.length === 0\n ? \"No tracked context changed in this commit.\"\n : `A tracked context also changed (${contextChanges.map((c) => c.contextName).join(\", \")}) — but new props arrived from above, so propagation is the direct cause.`,\n ],\n true,\n memoSuggestion(input),\n );\n }\n\n // Hook mode: props and self-originated renders cannot be told apart.\n if (parentRendered) {\n const evidence = [\n `${parentName ?? \"The nearest instrumented ancestor\"} re-rendered in this commit.`,\n \"Every prop is identical by reference.\",\n contextChanges.length === 0\n ? \"No tracked context changed in this commit.\"\n : `A tracked context also changed (${contextChanges.map((c) => c.contextName).join(\", \")}) — if this component consumes it, that is an alternative cause.`,\n ];\n return make(\n \"parent\",\n contextChanges.length === 0 ? \"high\" : \"medium\",\n `${input.componentName} rendered because its parent rendered — its own inputs did not change.`,\n evidence,\n true,\n memoSuggestion(input),\n );\n }\n\n if (contextChanges.length > 0) {\n const c = contextChanges[0] as ContextChange;\n const detail = c.changedKeys.length > 0 ? ` Changed: ${c.changedKeys.join(\", \")}.` : \"\";\n return make(\n \"context\",\n \"medium\",\n `${input.componentName} rendered after ${c.contextName} updated in the same commit.${detail}`,\n [\n `Props are identical and the parent did not re-render.`,\n `Tracked context ${c.contextName} changed in this commit.`,\n c.referenceOnly\n ? `${c.contextName}'s value changed by reference only — its contents are identical.`\n : `${c.contextName}'s contents changed.`,\n \"React does not expose which contexts a component subscribes to, so this is correlation within one commit, not a recorded subscription.\",\n ],\n c.referenceOnly,\n c.referenceOnly\n ? `${c.contextName}'s provider recreates its value every render. Stabilise it with useMemo if consumers are doing real work.`\n : undefined,\n );\n }\n\n if (parentUnknown) {\n return make(\n \"unknown\",\n \"low\",\n `Cause could not be determined reliably for ${input.componentName}.`,\n [\n \"Props are identical and no tracked context changed.\",\n \"This component has no instrumented ancestor, so a parent-propagated render cannot be ruled out.\",\n \"Instrument the parent, or track the context it consumes, to narrow this down.\",\n ],\n false,\n );\n }\n\n return make(\n \"state-or-external\",\n \"medium\",\n `${input.componentName} rendered from inside itself — local state, a store subscription, or a forced update.`,\n [\n \"Props are identical by reference.\",\n \"The nearest instrumented ancestor did not re-render in this commit.\",\n \"No tracked context changed in this commit.\",\n \"React does not expose hook state without private internals, so the exact source is not observable. Use useTrackedState to name it.\",\n ],\n false,\n );\n}\n\n/**\n * Memoization is a trade, not a default. Only recommend measuring it when the\n * render actually costs something or the pattern has repeated (§50, §52).\n */\nfunction memoSuggestion(input: DiagnosisInput): string {\n const worth = input.selfDuration >= 1 || input.priorAvoidableRenders >= 5;\n return worth\n ? `Check whether ${input.componentName} benefits from React.memo(). It has re-rendered with identical props ${input.priorAvoidableRenders + 1}× at ${fmt(input.selfDuration)} each — measure before and after.`\n : `Props are identical, but this render costs ${fmt(input.selfDuration)}. Memoizing is unlikely to pay for itself yet.`;\n}\n\nfunction stabiliseSuggestion(changes: PropChange[], parentName?: string): string {\n const fns = changes.filter((c) => c.valueType === \"function\").map((c) => c.key);\n const objs = changes.filter((c) => c.valueType === \"object\" || c.valueType === \"array\").map((c) => c.key);\n const where = parentName ? ` in ${parentName}` : \"\";\n const parts: string[] = [];\n if (fns.length > 0) parts.push(`${list(fns)} ${plural(fns.length, \"is\", \"are\")} recreated on every render${where} — useCallback, or hoist it, if a memoized child depends on it`);\n if (objs.length > 0) parts.push(`${list(objs)} ${plural(objs.length, \"is\", \"are\")} a new object each render${where} — useMemo it, or pass the primitive fields you actually use`);\n if (parts.length === 0) return `Find where ${list(changes.map((c) => c.key))} is created${where} and stabilise it.`;\n return `${capitalize(parts.join(\"; \"))}.`;\n}\n\nfunction describe(c: PropChange): string {\n switch (c.kind) {\n case \"added\":\n return `\\`${c.key}\\` was added.`;\n case \"removed\":\n return `\\`${c.key}\\` was removed.`;\n case \"reference\":\n if (c.valueType === \"function\") {\n return c.sourceEqual\n ? `\\`${c.key}\\` is a new function with identical source — an inline closure recreated by the parent.`\n : `\\`${c.key}\\` is a new function reference.`;\n }\n if (c.shallowEqual === true) return `\\`${c.key}\\` is a new ${c.valueType} whose shallow contents are identical.`;\n return `\\`${c.key}\\` changed reference; contents were too large or too exotic to compare cheaply.`;\n case \"value\":\n return `\\`${c.key}\\` changed value.`;\n }\n}\n\nfunction make(\n reason: Diagnosis[\"reason\"],\n confidence: Confidence,\n summary: string,\n evidence: string[],\n potentiallyAvoidable: boolean,\n suggestion?: string,\n): Diagnosis {\n return { reason, confidence, summary, evidence, potentiallyAvoidable, suggestion, severity: \"normal\" };\n}\n\nconst fmt = (ms: number): string => `${ms.toFixed(1)}ms`;\nconst list = (xs: string[]): string => xs.map((x) => `\\`${x}\\``).join(\", \");\nconst capitalize = (s: string): string => s.charAt(0).toUpperCase() + s.slice(1);\nfunction plural(n: number, one: string, many?: string): string {\n if (one === \"is\") return n === 1 ? \"is\" : (many as string);\n return n === 1 ? `${one}` : `${one}s`;\n}\n","/** Fixed-capacity ring buffer. Bounded memory is a hard requirement (§26). */\nexport class RingBuffer<T> {\n private items: Array<T | undefined>;\n private head = 0;\n private count = 0;\n\n constructor(capacity: number) {\n this.items = new Array<T | undefined>(Math.max(1, capacity));\n }\n\n push(item: T): void {\n this.items[this.head] = item;\n this.head = (this.head + 1) % this.items.length;\n if (this.count < this.items.length) this.count++;\n }\n\n get size(): number {\n return this.count;\n }\n\n /** Oldest → newest. */\n toArray(): T[] {\n const out: T[] = [];\n const len = this.items.length;\n const start = (this.head - this.count + len) % len;\n for (let i = 0; i < this.count; i++) {\n const v = this.items[(start + i) % len];\n if (v !== undefined) out.push(v);\n }\n return out;\n }\n\n clear(): void {\n this.items = new Array<T | undefined>(this.items.length);\n this.head = 0;\n this.count = 0;\n }\n\n resize(capacity: number): void {\n const existing = this.toArray();\n this.items = new Array<T | undefined>(Math.max(1, capacity));\n this.head = 0;\n this.count = 0;\n const keep = existing.slice(Math.max(0, existing.length - this.items.length));\n for (const item of keep) this.push(item);\n }\n}\n","import { defaultConfig, detectProduction, mergeConfig, shouldInstrument } from \"./config.js\";\nimport { diffProps } from \"./compare.js\";\nimport { diagnose } from \"./diagnose.js\";\nimport { RingBuffer } from \"./ringBuffer.js\";\nimport type {\n AppStats,\n TrackedStateChange,\n ComponentInfo,\n ComponentStats,\n ContextChange,\n DetectiveConfig,\n DetectiveOptions,\n RenderEvent,\n RenderPhase,\n RenderReason,\n} from \"./types.js\";\n\nconst now = (): number =>\n typeof performance !== \"undefined\" && typeof performance.now === \"function\" ? performance.now() : Date.now();\n\n/** What an instrumentation site reports at commit time. */\nexport interface CommitInput {\n phase: RenderPhase;\n subtreeDuration: number;\n baseDuration: number;\n startTime: number;\n /** `-1` when there is no Profiler; the flush pass resolves it. */\n commitTime: number;\n}\n\nconst EMPTY_STATE: TrackedStateChange[] = [];\nconst DURATION_SAMPLE = 200;\nconst SWEEP_DELAY_MS = 250;\n\ninterface NodeRecord {\n id: string;\n name: string;\n /** Nearest instrumented ancestor, held directly so diagnosis never needs the registry. */\n parent?: NodeRecord;\n depth: number;\n sampled: boolean;\n /** Retained so the next render can be diffed. One props object per component. */\n prevProps?: Record<string, unknown>;\n pendingProps?: Record<string, unknown>;\n /** Render-function invocations not yet matched to a commit. */\n attempts: number;\n /** Named state updates reported by `useTrackedState`, consumed at the next commit. */\n pendingState: TrackedStateChange[];\n /** Set as soon as a commit is queued, so mount detection never waits on flush. */\n seenCommit: boolean;\n /**\n * `useId` of the first component to call `useTrackedState` under this node.\n * Later callers (descendants) cannot claim state attribution from it.\n */\n stateOwner?: string;\n renderNumber: number;\n lastCommitTime: number;\n durations: number[];\n stats: MutableStats;\n}\n\ninterface MutableStats {\n renderCount: number;\n mountCount: number;\n uncommittedAttempts: number;\n devReplays: number;\n totalSelfDuration: number;\n maxSelfDuration: number;\n slowRenders: number;\n potentiallyAvoidableRenders: number;\n reasons: Record<RenderReason, number>;\n}\n\ninterface PendingCommit {\n node: NodeRecord;\n phase: RenderPhase;\n subtreeDuration: number;\n baseDuration: number;\n startTime: number;\n commitTime: number;\n attempts: number;\n /**\n * Props and state are snapshotted **at commit time**, not at flush time.\n * Several commits can land before the deferred pass runs, and reading them\n * later would diff the wrong pair.\n */\n props: Record<string, unknown> | undefined;\n state: TrackedStateChange[];\n seq: number;\n}\n\nconst emptyReasons = (): Record<RenderReason, number> => ({\n mount: 0,\n props: 0,\n state: 0,\n parent: 0,\n context: 0,\n \"state-or-external\": 0,\n unknown: 0,\n});\n\nexport class Detective {\n config: DetectiveConfig = { ...defaultConfig };\n private nodes = new Map<string, NodeRecord>();\n private events: RingBuffer<RenderEvent>;\n private listeners = new Set<(event: RenderEvent) => void>();\n private pending: PendingCommit[] = [];\n private contextChanges: Array<{ change: ContextChange; seq: number }> = [];\n /** Orders renders and context updates so they can be matched without timers. */\n private seq = 0;\n private flushScheduled = false;\n private sweepHandle: ReturnType<typeof setTimeout> | undefined;\n private nextId = 0;\n /** Nodes created by `useRenderDiagnostics`, where props/state cannot be separated. */\n readonly hookModeNodes = new WeakSet<NodeRecord>();\n private initialized = false;\n\n constructor() {\n this.events = new RingBuffer<RenderEvent>(this.config.maxEvents);\n }\n\n /**\n * Idempotent: repeated calls reconfigure, they never duplicate anything (§47).\n *\n * Calling `init()` *is* the intent to turn diagnostics on, so `enabled`\n * defaults to true unless a production build is positively detected. Guard\n * the call itself for production safety — that is what the docs show, and it\n * is what lets a bundler drop the whole thing.\n */\n init(options: DetectiveOptions = {}): Detective {\n this.configure({ enabled: !detectProduction(), ...options });\n this.initialized = true;\n return this;\n }\n\n configure(options: DetectiveOptions = {}): void {\n const previousMax = this.config.maxEvents;\n this.config = mergeConfig(this.config, options);\n if (this.config.maxEvents !== previousMax) this.events.resize(this.config.maxEvents);\n }\n\n get isInitialized(): boolean {\n return this.initialized;\n }\n\n get enabled(): boolean {\n return this.config.enabled;\n }\n\n subscribe(listener: (event: RenderEvent) => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n // ---------------------------------------------------------------- registry\n\n /**\n * Creates a node without publishing it. StrictMode's double mount renders\n * discards one of the two, and only the surviving fiber's effect attaches —\n * so discarded nodes are simply garbage collected.\n */\n createNode(name: string, parent: NodeRecord | undefined): NodeRecord | undefined {\n if (!shouldInstrument(name, this.config)) return undefined;\n const sampled = this.config.samplingRate >= 1 || Math.random() < this.config.samplingRate;\n const node: NodeRecord = {\n id: `rrd_${++this.nextId}`,\n name,\n parent,\n depth: parent ? parent.depth + 1 : 0,\n sampled,\n attempts: 0,\n pendingState: [],\n seenCommit: false,\n renderNumber: 0,\n lastCommitTime: -1,\n durations: [],\n stats: {\n renderCount: 0,\n mountCount: 0,\n uncommittedAttempts: 0,\n devReplays: 0,\n totalSelfDuration: 0,\n maxSelfDuration: 0,\n slowRenders: 0,\n potentiallyAvoidableRenders: 0,\n reasons: emptyReasons(),\n },\n };\n return node;\n }\n\n attach(node: NodeRecord): void {\n this.nodes.set(node.id, node);\n }\n\n detach(node: NodeRecord): void {\n /*\n * Registry removal only — deliberately NOT clearing `prevProps`.\n *\n * StrictMode simulates an unmount/remount by running every effect's cleanup\n * and then the effect again. Wiping the previous props here made the first\n * real update after mount diff against `{}` and report every prop as newly\n * added — a confident, wrong diagnosis on the first update of every\n * component in a StrictMode app.\n *\n * Memory is bounded by dropping the node from the registry: after a genuine\n * unmount nothing references it, so it is collected along with its props.\n */\n this.nodes.delete(node.id);\n }\n\n /** Hot path. Must stay allocation-free and O(1). */\n recordAttempt(node: NodeRecord, props: Record<string, unknown>): void {\n node.attempts++;\n node.pendingProps = props;\n }\n\n recordStateChange(node: NodeRecord, change: TrackedStateChange): void {\n if (node.pendingState.length < 16) node.pendingState.push(change);\n }\n\n /**\n * Hot path. Called from Profiler#onRender; only enqueues.\n *\n * `attempts` is the number of times the *wrapper* rendered, i.e. how often\n * this component's props were re-evaluated from above. Zero means the render\n * originated at or below this component — the flush pass works out which.\n */\n recordCommit(node: NodeRecord, commit: CommitInput): void {\n this.pending.push({\n ...commit,\n node,\n attempts: node.attempts,\n props: node.pendingProps,\n state: node.pendingState.length > 0 ? node.pendingState : EMPTY_STATE,\n seq: ++this.seq,\n });\n node.seenCommit = true;\n node.attempts = 0;\n node.pendingProps = undefined;\n if (node.pendingState.length > 0) node.pendingState = [];\n node.lastCommitTime = commit.commitTime;\n this.scheduleFlush();\n }\n\n recordContextChange(change: ContextChange): void {\n this.contextChanges.push({ change, seq: ++this.seq });\n this.scheduleFlush();\n }\n\n // ------------------------------------------------------------ deferred work\n\n private scheduleFlush(): void {\n if (this.flushScheduled) return;\n this.flushScheduled = true;\n queueMicrotask(() => {\n this.flushScheduled = false;\n try {\n this.flush();\n } catch {\n /* diagnostics must never break the app (§46) */\n }\n });\n this.scheduleSweep();\n }\n\n private scheduleSweep(): void {\n if (this.sweepHandle !== undefined) return;\n this.sweepHandle = setTimeout(() => {\n this.sweepHandle = undefined;\n try {\n this.sweep();\n } catch {\n /* ignore */\n }\n }, SWEEP_DELAY_MS);\n // Never keep a Node process alive for diagnostics.\n (this.sweepHandle as { unref?: () => void }).unref?.();\n }\n\n /** Attempts that never reached a commit were abandoned or replayed. */\n private sweep(): void {\n for (const node of this.nodes.values()) {\n if (node.attempts > 0) {\n node.stats.uncommittedAttempts += node.attempts;\n node.attempts = 0;\n }\n }\n }\n\n /** Runs after the commit, off the render path. Whole batch is available here. */\n flush(): void {\n if (this.pending.length === 0) {\n this.contextChanges.length = 0;\n return;\n }\n const batch = this.pending;\n this.pending = [];\n const pendingContexts = this.contextChanges;\n this.contextChanges = [];\n const hookMode = this.hookModeNodes;\n\n /*\n * Hook-mode records and context updates are recorded *during* render, so\n * they belong to the next commit that lands after them. Matching on\n * sequence rather than wall-clock keeps that correct even when several\n * commits queue up before this deferred pass runs.\n */\n let nextReal = -1;\n for (let i = batch.length - 1; i >= 0; i--) {\n const rec = batch[i] as PendingCommit;\n if (rec.commitTime >= 0) nextReal = rec.commitTime;\n else if (nextReal >= 0) rec.commitTime = nextReal;\n else rec.commitTime = now();\n }\n const contexts: ContextChange[] = pendingContexts.map(({ change, seq }) => {\n if (change.commitTime >= 0) return change;\n const following = batch.find((r) => r.seq > seq);\n return { ...change, commitTime: following ? following.commitTime : (batch[batch.length - 1]?.commitTime ?? now()) };\n });\n\n // Which nodes rendered in each commit, and how much of a node's subtree\n // time belongs to instrumented descendants.\n const commitMembers = new Map<number, Set<NodeRecord>>();\n const descendantTime = new Map<NodeRecord, number>();\n for (const rec of batch) {\n let set = commitMembers.get(rec.commitTime);\n if (!set) commitMembers.set(rec.commitTime, (set = new Set()));\n set.add(rec.node);\n }\n for (const rec of batch) {\n const parent = rec.node.parent;\n if (!parent) continue;\n if (!commitMembers.get(rec.commitTime)?.has(parent)) continue;\n descendantTime.set(parent, (descendantTime.get(parent) ?? 0) + rec.subtreeDuration);\n }\n\n /*\n * A Profiler fires for every ancestor of the work, so a raw callback is not\n * proof that *this* component rendered. Two facts separate them:\n *\n * attempts > 0 the wrapper re-rendered, so something above re-rendered it.\n * attempts = 0 the work started at or below this component.\n *\n * For the second case, an instrumented child that itself re-rendered from\n * above is proof this component rendered (it produced that child). If some\n * deeper instrumented node fired instead, the origin is down there and this\n * callback is only propagation — counting it would inflate every ancestor.\n */\n const provenSelfRender = new Set<NodeRecord>();\n const hasInstrumentedDescendant = new Set<NodeRecord>();\n for (const rec of batch) {\n const members = commitMembers.get(rec.commitTime);\n if (rec.attempts > 0 && rec.node.parent && members?.has(rec.node.parent)) {\n provenSelfRender.add(rec.node.parent);\n }\n for (let a = rec.node.parent; a; a = a.parent) {\n if (members?.has(a)) hasInstrumentedDescendant.add(a);\n }\n }\n\n for (const rec of batch) {\n if (!rec.node.sampled) continue;\n const counted =\n rec.attempts > 0 ||\n rec.phase === \"mount\" ||\n provenSelfRender.has(rec.node) ||\n !hasInstrumentedDescendant.has(rec.node);\n if (!counted) continue;\n try {\n this.emit(\n this.buildEvent(rec.node, rec, commitMembers, descendantTime, contexts, provenSelfRender, hookMode.has(rec.node)),\n );\n } catch {\n /* one bad event must not lose the batch */\n }\n }\n }\n\n private buildEvent(\n node: NodeRecord,\n rec: PendingCommit,\n commitMembers: Map<number, Set<NodeRecord>>,\n descendantTime: Map<NodeRecord, number>,\n contexts: ContextChange[],\n provenSelfRender: Set<NodeRecord>,\n isHookMode: boolean,\n ): RenderEvent {\n const parent = node.parent;\n const parentRendered = parent ? commitMembers.get(rec.commitTime)?.has(parent) === true : false;\n\n // attempts === 0 means the wrapper never re-ran, so the props object is by\n // definition the same one as last time — there is nothing to diff.\n const propsReevaluated = isHookMode ? undefined : rec.attempts > 0;\n const isMount = rec.phase === \"mount\";\n const props = rec.props ?? node.prevProps ?? {};\n const { changed, unchanged } =\n isMount || propsReevaluated === false\n ? { changed: [], unchanged: Object.keys(props) }\n : diffProps(node.prevProps, props, this.config);\n node.prevProps = props;\n\n const accounted = descendantTime.get(node) ?? 0;\n const selfDuration = Math.max(0, rec.subtreeDuration - accounted);\n const relevantContexts = contexts.filter((c) => c.commitTime === rec.commitTime);\n const trackedState = rec.state;\n\n node.renderNumber++;\n const diagnosis = diagnose(\n {\n componentName: node.name,\n phase: rec.phase,\n parentName: parent?.name,\n parentRendered,\n parentUnknown: !parent,\n propsReevaluated,\n selfRenderProven: provenSelfRender.has(node),\n changedProps: changed,\n contextChanges: relevantContexts,\n selfDuration,\n attempts: rec.attempts,\n committed: true,\n trackedState,\n priorAvoidableRenders: node.stats.potentiallyAvoidableRenders,\n },\n this.config.thresholds,\n );\n\n const componentInfo: ComponentInfo = {\n id: node.id,\n name: node.name,\n parentId: parent?.id,\n depth: node.depth,\n };\n\n const event: RenderEvent = {\n id: `${node.id}#${node.renderNumber}`,\n component: componentInfo,\n timestamp: rec.startTime,\n renderNumber: node.renderNumber,\n phase: rec.phase,\n timings: {\n subtreeDuration: rec.subtreeDuration,\n baseDuration: rec.baseDuration,\n selfDuration,\n accountedDescendantDuration: accounted,\n commitTime: rec.commitTime,\n startTime: rec.startTime,\n },\n changedProps: changed,\n unchangedProps: unchanged,\n parent: parent ? { id: parent.id, name: parent.name, parentId: parent.parent?.id, depth: parent.depth } : undefined,\n parentRendered,\n selfOriginated: propsReevaluated === false,\n contextChanges: relevantContexts,\n trackedState,\n committed: true,\n attempts: Math.max(1, rec.attempts),\n devReplay: rec.attempts > 1,\n diagnosis,\n };\n\n this.updateStats(node, event);\n return event;\n }\n\n private updateStats(node: NodeRecord, event: RenderEvent): void {\n const s = node.stats;\n s.renderCount++;\n if (event.phase === \"mount\") s.mountCount++;\n if (event.devReplay) s.devReplays++;\n const d = event.timings.selfDuration;\n s.totalSelfDuration += d;\n if (d > s.maxSelfDuration) s.maxSelfDuration = d;\n if (d >= this.config.slowRenderThreshold) s.slowRenders++;\n if (event.diagnosis.potentiallyAvoidable) s.potentiallyAvoidableRenders++;\n s.reasons[event.diagnosis.reason]++;\n node.durations.push(d);\n if (node.durations.length > DURATION_SAMPLE) node.durations.shift();\n }\n\n private emit(event: RenderEvent): void {\n this.events.push(event);\n const { onEvent } = this.config;\n if (onEvent) {\n try {\n onEvent(event);\n } catch {\n /* ignore */\n }\n }\n for (const listener of this.listeners) {\n try {\n listener(event);\n } catch {\n /* ignore */\n }\n }\n }\n\n // -------------------------------------------------------------------- query\n\n getEvents(): RenderEvent[] {\n this.flush();\n return this.events.toArray();\n }\n\n getComponentStats(name?: string): ComponentStats[] {\n this.flush();\n const out: ComponentStats[] = [];\n for (const node of this.nodes.values()) {\n if (name && node.name !== name) continue;\n if (node.stats.renderCount === 0 && node.stats.uncommittedAttempts === 0) continue;\n out.push(toStats(node));\n }\n return out;\n }\n\n getStats(): AppStats {\n const all = this.getComponentStats();\n const byName = new Map<string, ComponentStats>();\n for (const s of all) {\n const existing = byName.get(s.name);\n byName.set(s.name, existing ? mergeStats(existing, s) : s);\n }\n const merged = [...byName.values()];\n return {\n components: merged.length,\n totalRenders: merged.reduce((a, s) => a + s.renderCount, 0),\n totalRenderTime: merged.reduce((a, s) => a + s.totalSelfDuration, 0),\n slowRenders: merged.reduce((a, s) => a + s.slowRenders, 0),\n potentiallyAvoidableRenders: merged.reduce((a, s) => a + s.potentiallyAvoidableRenders, 0),\n devReplays: merged.reduce((a, s) => a + s.devReplays, 0),\n slowest: [...merged].sort((a, b) => b.maxSelfDuration - a.maxSelfDuration).slice(0, 10),\n mostRendered: [...merged].sort((a, b) => b.renderCount - a.renderCount).slice(0, 10),\n mostExpensive: [...merged].sort((a, b) => b.totalSelfDuration - a.totalSelfDuration).slice(0, 10),\n };\n }\n\n clear(): void {\n this.events.clear();\n this.pending.length = 0;\n this.contextChanges.length = 0;\n for (const node of this.nodes.values()) {\n node.stats = {\n renderCount: 0,\n mountCount: 0,\n uncommittedAttempts: 0,\n devReplays: 0,\n totalSelfDuration: 0,\n maxSelfDuration: 0,\n slowRenders: 0,\n potentiallyAvoidableRenders: 0,\n reasons: emptyReasons(),\n };\n node.durations.length = 0;\n node.renderNumber = 0;\n }\n }\n\n /** Full teardown — used by tests and by HMR disposal. */\n reset(): void {\n this.clear();\n this.nodes.clear();\n this.listeners.clear();\n if (this.sweepHandle !== undefined) clearTimeout(this.sweepHandle);\n this.sweepHandle = undefined;\n this.config = { ...defaultConfig };\n this.events.resize(this.config.maxEvents);\n this.initialized = false;\n }\n}\n\nfunction percentile(sorted: number[], p: number): number {\n if (sorted.length === 0) return 0;\n const idx = Math.min(sorted.length - 1, Math.max(0, Math.ceil((p / 100) * sorted.length) - 1));\n return sorted[idx] as number;\n}\n\nfunction toStats(node: NodeRecord): ComponentStats {\n const sorted = [...node.durations].sort((a, b) => a - b);\n const s = node.stats;\n return {\n id: node.id,\n name: node.name,\n renderCount: s.renderCount,\n mountCount: s.mountCount,\n uncommittedAttempts: s.uncommittedAttempts,\n devReplays: s.devReplays,\n totalSelfDuration: s.totalSelfDuration,\n averageSelfDuration: s.renderCount ? s.totalSelfDuration / s.renderCount : 0,\n medianSelfDuration: percentile(sorted, 50),\n p95SelfDuration: percentile(sorted, 95),\n p99SelfDuration: percentile(sorted, 99),\n maxSelfDuration: s.maxSelfDuration,\n slowRenders: s.slowRenders,\n potentiallyAvoidableRenders: s.potentiallyAvoidableRenders,\n reasons: { ...s.reasons },\n };\n}\n\nfunction mergeStats(a: ComponentStats, b: ComponentStats): ComponentStats {\n const renderCount = a.renderCount + b.renderCount;\n const total = a.totalSelfDuration + b.totalSelfDuration;\n const reasons = { ...a.reasons };\n for (const key of Object.keys(b.reasons) as RenderReason[]) reasons[key] += b.reasons[key];\n return {\n id: a.id,\n name: a.name,\n renderCount,\n mountCount: a.mountCount + b.mountCount,\n uncommittedAttempts: a.uncommittedAttempts + b.uncommittedAttempts,\n devReplays: a.devReplays + b.devReplays,\n totalSelfDuration: total,\n averageSelfDuration: renderCount ? total / renderCount : 0,\n medianSelfDuration: Math.max(a.medianSelfDuration, b.medianSelfDuration),\n p95SelfDuration: Math.max(a.p95SelfDuration, b.p95SelfDuration),\n p99SelfDuration: Math.max(a.p99SelfDuration, b.p99SelfDuration),\n maxSelfDuration: Math.max(a.maxSelfDuration, b.maxSelfDuration),\n slowRenders: a.slowRenders + b.slowRenders,\n potentiallyAvoidableRenders: a.potentiallyAvoidableRenders + b.potentiallyAvoidableRenders,\n reasons,\n };\n}\n\nexport type { NodeRecord };\n\n/**\n * Singleton pinned to globalThis so Fast Refresh / duplicate module instances\n * share one detective instead of stacking three copies of the debugger (§47).\n */\nconst KEY = Symbol.for(\"react-render-detective.instance\");\ntype Global = typeof globalThis & { [KEY]?: Detective };\n\nexport function getDetective(): Detective {\n const g = globalThis as Global;\n if (!g[KEY]) g[KEY] = new Detective();\n return g[KEY] as Detective;\n}\n"]}
@@ -2,12 +2,16 @@
2
2
  function explainEvents(component, events) {
3
3
  const mine = events.filter((e) => e.component.name === component);
4
4
  if (mine.length === 0) return void 0;
5
+ const updates = mine.filter((e) => e.phase !== "mount");
6
+ const denominator = updates.length || mine.length;
5
7
  const reasonCounts = /* @__PURE__ */ new Map();
6
8
  const unstable = /* @__PURE__ */ new Map();
7
9
  let totalSelf = 0;
8
10
  let avoidable = 0;
9
11
  let avoidableTime = 0;
10
12
  let replays = 0;
13
+ let propsWithNewValues = 0;
14
+ let propsReferenceOnly = 0;
11
15
  for (const e of mine) {
12
16
  reasonCounts.set(e.diagnosis.reason, (reasonCounts.get(e.diagnosis.reason) ?? 0) + 1);
13
17
  totalSelf += e.timings.selfDuration;
@@ -16,6 +20,10 @@ function explainEvents(component, events) {
16
20
  avoidable++;
17
21
  avoidableTime += e.timings.selfDuration;
18
22
  }
23
+ if (e.diagnosis.reason === "props") {
24
+ if (e.changedProps.some((c) => c.kind !== "reference")) propsWithNewValues++;
25
+ else propsReferenceOnly++;
26
+ }
19
27
  for (const c of e.changedProps) {
20
28
  if (c.kind !== "reference") continue;
21
29
  const entry = unstable.get(c.key) ?? { count: 0, valueType: c.valueType };
@@ -24,33 +32,44 @@ function explainEvents(component, events) {
24
32
  }
25
33
  }
26
34
  const breakdown = [...reasonCounts.entries()].map(([reason, count]) => ({ reason, count, share: count / mine.length })).sort((a, b) => b.count - a.count);
27
- const unstableProps = [...unstable.entries()].map(([key, v]) => ({ key, count: v.count, share: v.count / mine.length, valueType: v.valueType })).sort((a, b) => b.count - a.count);
28
- const top = breakdown[0];
35
+ const unstableProps = [...unstable.entries()].map(([key, v]) => ({ key, count: v.count, share: v.count / denominator, valueType: v.valueType })).sort((a, b) => b.count - a.count);
36
+ const top = [...reasonCounts.entries()].filter(([reason]) => reason !== "mount").map(([reason, count]) => ({ reason, count, share: count / denominator })).sort((a, b) => b.count - a.count)[0];
29
37
  const topProp = unstableProps[0];
30
38
  const latest = mine[mine.length - 1];
31
39
  let headline;
32
40
  let nextStep;
33
41
  let confidence = "medium";
34
42
  if (topProp && topProp.share >= 0.5) {
35
- headline = `${pct(topProp.share)} of renders followed \`${topProp.key}\` changing by reference while its contents stayed the same.`;
36
- nextStep = `Find where \`${topProp.key}\` is created in ${latest.parent?.name ?? "the parent"} and stabilise it${topProp.valueType === "function" ? " (useCallback, or move it out of the component)" : " (useMemo, or pass the primitive fields you use)"}.`;
43
+ headline = `${pct(topProp.share)} of updates followed \`${topProp.key}\` changing by reference while its contents stayed the same.`;
44
+ const via = latest.parent?.name;
45
+ nextStep = `Trace \`${topProp.key}\` back from ${via ? `${via}, which passes it to ${component}` : component}, and stabilise it where it is created${topProp.valueType === "function" ? " (useCallback, or hoist it out of the component)" : " (useMemo, or pass the primitive fields you use)"}.`;
37
46
  confidence = "high";
38
47
  } else if (top && top.reason === "parent" && top.share >= 0.5) {
39
- headline = `${pct(top.share)} of renders were parent propagation with identical props.`;
48
+ headline = `${pct(top.share)} of updates were parent propagation with identical props.`;
40
49
  nextStep = `Measure ${component} with React.memo(). It is only worth it if ${fmt(totalSelf / mine.length)} per render matters here.`;
41
50
  confidence = "high";
42
51
  } else if (top && top.reason === "context") {
43
- headline = `${pct(top.share)} of renders followed a tracked context update.`;
52
+ headline = `${pct(top.share)} of updates followed a tracked context update.`;
44
53
  nextStep = "Check whether the provider's value is stable, and whether this component needs the whole context value.";
45
54
  confidence = "medium";
46
55
  } else if (top && (top.reason === "state" || top.reason === "state-or-external")) {
47
- headline = `${pct(top.share)} of renders came from inside the component \u2014 state or an external store.`;
56
+ headline = `${pct(top.share)} of updates came from inside the component \u2014 state or an external store.`;
48
57
  nextStep = top.reason === "state" ? "These are real state updates. Check whether every update needs to change state." : "Name the state with useTrackedState to see which value drives these renders.";
49
58
  confidence = top.reason === "state" ? "high" : "medium";
50
59
  } else if (top && top.reason === "props") {
51
- headline = `${pct(top.share)} of renders were driven by props with genuinely new values.`;
52
- nextStep = "These look like legitimate data changes. Look at render cost rather than render count.";
53
- confidence = "high";
60
+ if (propsReferenceOnly > propsWithNewValues) {
61
+ headline = `${pct(propsReferenceOnly / denominator)} of updates were prop changes where only the reference changed \u2014 the contents were identical.`;
62
+ nextStep = `Stabilise the props listed above in whichever component renders ${component}.`;
63
+ confidence = "high";
64
+ } else if (propsReferenceOnly > 0) {
65
+ headline = `${pct(propsWithNewValues / denominator)} of updates carried genuinely new prop values, and ${pct(propsReferenceOnly / denominator)} changed by reference only.`;
66
+ nextStep = "The reference-only ones are the avoidable half \u2014 start there.";
67
+ confidence = "high";
68
+ } else {
69
+ headline = `${pct(top.share)} of updates were driven by props with genuinely new values.`;
70
+ nextStep = "These look like legitimate data changes. Look at render cost rather than render count.";
71
+ confidence = "high";
72
+ }
54
73
  } else {
55
74
  headline = "Cause could not be determined reliably.";
56
75
  nextStep = "Instrument the parent, or track the context this component consumes, to narrow it down.";
@@ -59,6 +78,7 @@ function explainEvents(component, events) {
59
78
  return {
60
79
  component,
61
80
  renders: mine.length,
81
+ mounts: mine.length - updates.length,
62
82
  breakdown,
63
83
  unstableProps,
64
84
  averageSelfDuration: totalSelf / mine.length,
@@ -75,16 +95,16 @@ function formatExplanation(e) {
75
95
  const lines = [
76
96
  `${e.component}`,
77
97
  "",
78
- `${e.renders} recorded render${e.renders === 1 ? "" : "s"}`,
98
+ `${e.renders} recorded render${e.renders === 1 ? "" : "s"}${e.mounts > 0 ? ` (${e.mounts} mount${e.mounts === 1 ? "" : "s"})` : ""}`,
79
99
  "",
80
100
  "Why?",
81
101
  ` ${e.headline}`,
82
102
  "",
83
- "Breakdown",
103
+ "Breakdown (share of all renders)",
84
104
  ...e.breakdown.map((b) => ` ${b.reason.padEnd(18)} ${String(b.count).padStart(5)} ${pct(b.share)}`)
85
105
  ];
86
106
  if (e.unstableProps.length > 0) {
87
- lines.push("", "Reference-only prop changes");
107
+ lines.push("", "Reference-only prop changes (share of updates)");
88
108
  for (const p of e.unstableProps) {
89
109
  lines.push(` ${p.key.padEnd(18)} ${String(p.count).padStart(5)} ${pct(p.share)} (${p.valueType})`);
90
110
  }
@@ -109,5 +129,5 @@ var pct = (n) => `${Math.round(n * 100)}%`;
109
129
  var fmt = (ms) => `${ms.toFixed(1)}ms`;
110
130
 
111
131
  export { explainEvents, formatExplanation };
112
- //# sourceMappingURL=chunk-EGA344XG.js.map
113
- //# sourceMappingURL=chunk-EGA344XG.js.map
132
+ //# sourceMappingURL=chunk-D4G4D5AC.js.map
133
+ //# sourceMappingURL=chunk-D4G4D5AC.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/explain.ts"],"names":[],"mappings":";AAyBO,SAAS,aAAA,CAAc,WAAmB,MAAA,EAAgD;AAC/F,EAAA,MAAM,IAAA,GAAO,OAAO,MAAA,CAAO,CAAC,MAAM,CAAA,CAAE,SAAA,CAAU,SAAS,SAAS,CAAA;AAChE,EAAA,IAAI,IAAA,CAAK,MAAA,KAAW,CAAA,EAAG,OAAO,MAAA;AAS9B,EAAA,MAAM,UAAU,IAAA,CAAK,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,UAAU,OAAO,CAAA;AACtD,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,MAAA,IAAU,IAAA,CAAK,MAAA;AAE3C,EAAA,MAAM,YAAA,uBAAmB,GAAA,EAA0B;AACnD,EAAA,MAAM,QAAA,uBAAe,GAAA,EAAkD;AACvE,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,IAAI,SAAA,GAAY,CAAA;AAChB,EAAA,IAAI,aAAA,GAAgB,CAAA;AACpB,EAAA,IAAI,OAAA,GAAU,CAAA;AACd,EAAA,IAAI,kBAAA,GAAqB,CAAA;AACzB,EAAA,IAAI,kBAAA,GAAqB,CAAA;AAEzB,EAAA,KAAA,MAAW,KAAK,IAAA,EAAM;AACpB,IAAA,YAAA,CAAa,GAAA,CAAI,CAAA,CAAE,SAAA,CAAU,MAAA,EAAA,CAAS,YAAA,CAAa,GAAA,CAAI,CAAA,CAAE,SAAA,CAAU,MAAM,CAAA,IAAK,CAAA,IAAK,CAAC,CAAA;AACpF,IAAA,SAAA,IAAa,EAAE,OAAA,CAAQ,YAAA;AACvB,IAAA,IAAI,EAAE,SAAA,EAAW,OAAA,EAAA;AACjB,IAAA,IAAI,CAAA,CAAE,UAAU,oBAAA,EAAsB;AACpC,MAAA,SAAA,EAAA;AACA,MAAA,aAAA,IAAiB,EAAE,OAAA,CAAQ,YAAA;AAAA,IAC7B;AACA,IAAA,IAAI,CAAA,CAAE,SAAA,CAAU,MAAA,KAAW,OAAA,EAAS;AAClC,MAAA,IAAI,CAAA,CAAE,aAAa,IAAA,CAAK,CAAC,MAAM,CAAA,CAAE,IAAA,KAAS,WAAW,CAAA,EAAG,kBAAA,EAAA;AAAA,WACnD,kBAAA,EAAA;AAAA,IACP;AACA,IAAA,KAAA,MAAW,CAAA,IAAK,EAAE,YAAA,EAAc;AAC9B,MAAA,IAAI,CAAA,CAAE,SAAS,WAAA,EAAa;AAC5B,MAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,GAAG,CAAA,IAAK,EAAE,KAAA,EAAO,CAAA,EAAG,SAAA,EAAW,CAAA,CAAE,SAAA,EAAU;AACxE,MAAA,KAAA,CAAM,KAAA,EAAA;AACN,MAAA,QAAA,CAAS,GAAA,CAAI,CAAA,CAAE,GAAA,EAAK,KAAK,CAAA;AAAA,IAC3B;AAAA,EACF;AAEA,EAAA,MAAM,SAAA,GAAY,CAAC,GAAG,YAAA,CAAa,OAAA,EAAS,CAAA,CACzC,GAAA,CAAI,CAAC,CAAC,MAAA,EAAQ,KAAK,CAAA,MAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,KAAA,EAAO,KAAA,GAAQ,IAAA,CAAK,MAAA,EAAO,CAAE,CAAA,CACxE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AAEnC,EAAA,MAAM,aAAA,GAAgB,CAAC,GAAG,QAAA,CAAS,SAAS,CAAA,CACzC,GAAA,CAAI,CAAC,CAAC,GAAA,EAAK,CAAC,CAAA,MAAO,EAAE,KAAK,KAAA,EAAO,CAAA,CAAE,KAAA,EAAO,KAAA,EAAO,CAAA,CAAE,KAAA,GAAQ,WAAA,EAAa,SAAA,EAAW,EAAE,SAAA,EAAU,CAAE,CAAA,CACjG,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,KAAA,GAAQ,EAAE,KAAK,CAAA;AAGnC,EAAA,MAAM,MAAM,CAAC,GAAG,YAAA,CAAa,OAAA,EAAS,CAAA,CACnC,MAAA,CAAO,CAAC,CAAC,MAAM,CAAA,KAAM,MAAA,KAAW,OAAO,CAAA,CACvC,GAAA,CAAI,CAAC,CAAC,MAAA,EAAQ,KAAK,CAAA,MAAO,EAAE,MAAA,EAAQ,KAAA,EAAO,KAAA,EAAO,KAAA,GAAQ,aAAY,CAAE,CAAA,CACxE,IAAA,CAAK,CAAC,GAAG,CAAA,KAAM,CAAA,CAAE,QAAQ,CAAA,CAAE,KAAK,EAAE,CAAC,CAAA;AACtC,EAAA,MAAM,OAAA,GAAU,cAAc,CAAC,CAAA;AAC/B,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,IAAA,CAAK,MAAA,GAAS,CAAC,CAAA;AAEnC,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI,QAAA;AACJ,EAAA,IAAI,UAAA,GAAyB,QAAA;AAE7B,EAAA,IAAI,OAAA,IAAW,OAAA,CAAQ,KAAA,IAAS,GAAA,EAAK;AACnC,IAAA,QAAA,GAAW,GAAG,GAAA,CAAI,OAAA,CAAQ,KAAK,CAAC,CAAA,uBAAA,EAA0B,QAAQ,GAAG,CAAA,4DAAA,CAAA;AAGrE,IAAA,MAAM,GAAA,GAAM,OAAO,MAAA,EAAQ,IAAA;AAC3B,IAAA,QAAA,GACE,WAAW,OAAA,CAAQ,GAAG,CAAA,aAAA,EAAgB,GAAA,GAAM,GAAG,GAAG,CAAA,qBAAA,EAAwB,SAAS,CAAA,CAAA,GAAK,SAAS,CAAA,sCAAA,EAE/F,OAAA,CAAQ,SAAA,KAAc,UAAA,GAAa,qDAAqD,kDAC1F,CAAA,CAAA,CAAA;AACF,IAAA,UAAA,GAAa,MAAA;AAAA,EACf,WAAW,GAAA,IAAO,GAAA,CAAI,WAAW,QAAA,IAAY,GAAA,CAAI,SAAS,GAAA,EAAK;AAC7D,IAAA,QAAA,GAAW,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,KAAK,CAAC,CAAA,yDAAA,CAAA;AAC5B,IAAA,QAAA,GAAW,WAAW,SAAS,CAAA,2CAAA,EAA8C,IAAI,SAAA,GAAY,IAAA,CAAK,MAAM,CAAC,CAAA,yBAAA,CAAA;AACzG,IAAA,UAAA,GAAa,MAAA;AAAA,EACf,CAAA,MAAA,IAAW,GAAA,IAAO,GAAA,CAAI,MAAA,KAAW,SAAA,EAAW;AAC1C,IAAA,QAAA,GAAW,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,KAAK,CAAC,CAAA,8CAAA,CAAA;AAC5B,IAAA,QAAA,GAAW,yGAAA;AACX,IAAA,UAAA,GAAa,QAAA;AAAA,EACf,WAAW,GAAA,KAAQ,GAAA,CAAI,WAAW,OAAA,IAAW,GAAA,CAAI,WAAW,mBAAA,CAAA,EAAsB;AAChF,IAAA,QAAA,GAAW,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,KAAK,CAAC,CAAA,6EAAA,CAAA;AAC5B,IAAA,QAAA,GACE,GAAA,CAAI,MAAA,KAAW,OAAA,GACX,iFAAA,GACA,8EAAA;AACN,IAAA,UAAA,GAAa,GAAA,CAAI,MAAA,KAAW,OAAA,GAAU,MAAA,GAAS,QAAA;AAAA,EACjD,CAAA,MAAA,IAAW,GAAA,IAAO,GAAA,CAAI,MAAA,KAAW,OAAA,EAAS;AAExC,IAAA,IAAI,qBAAqB,kBAAA,EAAoB;AAC3C,MAAA,QAAA,GAAW,CAAA,EAAG,GAAA,CAAI,kBAAA,GAAqB,WAAW,CAAC,CAAA,kGAAA,CAAA;AACnD,MAAA,QAAA,GAAW,mEAAmE,SAAS,CAAA,CAAA,CAAA;AACvF,MAAA,UAAA,GAAa,MAAA;AAAA,IACf,CAAA,MAAA,IAAW,qBAAqB,CAAA,EAAG;AACjC,MAAA,QAAA,GACE,CAAA,EAAG,IAAI,kBAAA,GAAqB,WAAW,CAAC,CAAA,mDAAA,EACjC,GAAA,CAAI,kBAAA,GAAqB,WAAW,CAAC,CAAA,2BAAA,CAAA;AAC9C,MAAA,QAAA,GAAW,oEAAA;AACX,MAAA,UAAA,GAAa,MAAA;AAAA,IACf,CAAA,MAAO;AACL,MAAA,QAAA,GAAW,CAAA,EAAG,GAAA,CAAI,GAAA,CAAI,KAAK,CAAC,CAAA,2DAAA,CAAA;AAC5B,MAAA,QAAA,GAAW,wFAAA;AACX,MAAA,UAAA,GAAa,MAAA;AAAA,IACf;AAAA,EACF,CAAA,MAAO;AACL,IAAA,QAAA,GAAW,yCAAA;AACX,IAAA,QAAA,GAAW,yFAAA;AACX,IAAA,UAAA,GAAa,KAAA;AAAA,EACf;AAEA,EAAA,OAAO;AAAA,IACL,SAAA;AAAA,IACA,SAAS,IAAA,CAAK,MAAA;AAAA,IACd,MAAA,EAAQ,IAAA,CAAK,MAAA,GAAS,OAAA,CAAQ,MAAA;AAAA,IAC9B,SAAA;AAAA,IACA,aAAA;AAAA,IACA,mBAAA,EAAqB,YAAY,IAAA,CAAK,MAAA;AAAA,IACtC,iBAAA,EAAmB,SAAA;AAAA,IACnB,2BAAA,EAA6B,SAAA;AAAA,IAC7B,sBAAA,EAAwB,aAAA;AAAA,IACxB,UAAA,EAAY,OAAA;AAAA,IACZ,QAAA;AAAA,IACA,QAAA;AAAA,IACA;AAAA,GACF;AACF;AAEO,SAAS,kBAAkB,CAAA,EAAwB;AACxD,EAAA,MAAM,KAAA,GAAkB;AAAA,IACtB,CAAA,EAAG,EAAE,SAAS,CAAA,CAAA;AAAA,IACd,EAAA;AAAA,IACA,CAAA,EAAG,EAAE,OAAO,CAAA,gBAAA,EAAmB,EAAE,OAAA,KAAY,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,EAAG,CAAA,CAAE,SAAS,CAAA,GAAI,CAAA,EAAA,EAAK,CAAA,CAAE,MAAM,CAAA,MAAA,EAAS,CAAA,CAAE,WAAW,CAAA,GAAI,EAAA,GAAK,GAAG,CAAA,CAAA,CAAA,GAAM,EAAE,CAAA,CAAA;AAAA,IAClI,EAAA;AAAA,IACA,MAAA;AAAA,IACA,CAAA,EAAA,EAAK,EAAE,QAAQ,CAAA,CAAA;AAAA,IACf,EAAA;AAAA,IACA,kCAAA;AAAA,IACA,GAAG,CAAA,CAAE,SAAA,CAAU,GAAA,CAAI,CAAC,MAAM,CAAA,EAAA,EAAK,CAAA,CAAE,MAAA,CAAO,MAAA,CAAO,EAAE,CAAC,IAAI,MAAA,CAAO,CAAA,CAAE,KAAK,CAAA,CAAE,QAAA,CAAS,CAAC,CAAC,CAAA,EAAA,EAAK,GAAA,CAAI,CAAA,CAAE,KAAK,CAAC,CAAA,CAAE;AAAA,GACtG;AAEA,EAAA,IAAI,CAAA,CAAE,aAAA,CAAc,MAAA,GAAS,CAAA,EAAG;AAC9B,IAAA,KAAA,CAAM,IAAA,CAAK,IAAI,gDAAgD,CAAA;AAC/D,IAAA,KAAA,MAAW,CAAA,IAAK,EAAE,aAAA,EAAe;AAC/B,MAAA,KAAA,CAAM,IAAA,CAAK,KAAK,CAAA,CAAE,GAAA,CAAI,OAAO,EAAE,CAAC,CAAA,CAAA,EAAI,MAAA,CAAO,CAAA,CAAE,KAAK,EAAE,QAAA,CAAS,CAAC,CAAC,CAAA,EAAA,EAAK,GAAA,CAAI,CAAA,CAAE,KAAK,CAAC,CAAA,GAAA,EAAM,CAAA,CAAE,SAAS,CAAA,CAAA,CAAG,CAAA;AAAA,IACtG;AAAA,EACF;AAEA,EAAA,KAAA,CAAM,IAAA;AAAA,IACJ,EAAA;AAAA,IACA,MAAA;AAAA,IACA,CAAA,gBAAA,EAAmB,GAAA,CAAI,CAAA,CAAE,mBAAmB,CAAC,CAAA,CAAA;AAAA,IAC7C,CAAA,gBAAA,EAAmB,GAAA,CAAI,CAAA,CAAE,iBAAiB,CAAC,CAAA,CAAA;AAAA,IAC3C,4BAA4B,CAAA,CAAE,2BAA2B,gBAAgB,GAAA,CAAI,CAAA,CAAE,sBAAsB,CAAC,CAAA;AAAA,GACxG;AAEA,EAAA,IAAI,CAAA,CAAE,aAAa,CAAA,EAAG;AACpB,IAAA,KAAA,CAAM,IAAA;AAAA,MACJ,EAAA;AAAA,MACA,CAAA,EAAA,EAAK,EAAE,UAAU,CAAA,uHAAA;AAAA,KACnB;AAAA,EACF;AAEA,EAAA,KAAA,CAAM,IAAA,CAAK,EAAA,EAAI,WAAA,EAAa,CAAA,EAAA,EAAK,CAAA,CAAE,QAAQ,CAAA,CAAA,EAAI,EAAA,EAAI,CAAA,YAAA,EAAe,CAAA,CAAE,UAAU,CAAA,CAAE,CAAA;AAChF,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AACxB;AAEA,IAAM,GAAA,GAAM,CAAC,CAAA,KAAsB,CAAA,EAAG,KAAK,KAAA,CAAM,CAAA,GAAI,GAAG,CAAC,CAAA,CAAA,CAAA;AACzD,IAAM,MAAM,CAAC,EAAA,KAAuB,GAAG,EAAA,CAAG,OAAA,CAAQ,CAAC,CAAC,CAAA,EAAA,CAAA","file":"chunk-D4G4D5AC.js","sourcesContent":["import type { Confidence, RenderEvent, RenderReason } from \"./types.js\";\n\nexport interface Explanation {\n component: string;\n renders: number;\n /** Mounts are excluded from every share below — they cannot be optimised away. */\n mounts: number;\n /** Reason → share of renders, descending. */\n breakdown: Array<{ reason: RenderReason; count: number; share: number }>;\n /** Props that most often changed by reference only, descending. */\n unstableProps: Array<{ key: string; count: number; share: number; valueType: string }>;\n averageSelfDuration: number;\n totalSelfDuration: number;\n potentiallyAvoidableRenders: number;\n estimatedAvoidableTime: number;\n devReplays: number;\n headline: string;\n nextStep: string;\n confidence: Confidence;\n}\n\n/**\n * The flagship \"explain this render\" answer, aggregated across the recorded\n * history of one component. Pure — no React, no console.\n */\nexport function explainEvents(component: string, events: RenderEvent[]): Explanation | undefined {\n const mine = events.filter((e) => e.component.name === component);\n if (mine.length === 0) return undefined;\n\n /*\n * Shares are measured against *updates*, not against every recorded render.\n * Mounts happen once per instance and are not something you can optimise\n * away, so counting them in the denominator quietly deflates the share of\n * whatever is actually driving the re-renders — on a 20-row list, a prop\n * responsible for every single update reads as \"33%\".\n */\n const updates = mine.filter((e) => e.phase !== \"mount\");\n const denominator = updates.length || mine.length;\n\n const reasonCounts = new Map<RenderReason, number>();\n const unstable = new Map<string, { count: number; valueType: string }>();\n let totalSelf = 0;\n let avoidable = 0;\n let avoidableTime = 0;\n let replays = 0;\n let propsWithNewValues = 0;\n let propsReferenceOnly = 0;\n\n for (const e of mine) {\n reasonCounts.set(e.diagnosis.reason, (reasonCounts.get(e.diagnosis.reason) ?? 0) + 1);\n totalSelf += e.timings.selfDuration;\n if (e.devReplay) replays++;\n if (e.diagnosis.potentiallyAvoidable) {\n avoidable++;\n avoidableTime += e.timings.selfDuration;\n }\n if (e.diagnosis.reason === \"props\") {\n if (e.changedProps.some((c) => c.kind !== \"reference\")) propsWithNewValues++;\n else propsReferenceOnly++;\n }\n for (const c of e.changedProps) {\n if (c.kind !== \"reference\") continue;\n const entry = unstable.get(c.key) ?? { count: 0, valueType: c.valueType };\n entry.count++;\n unstable.set(c.key, entry);\n }\n }\n\n const breakdown = [...reasonCounts.entries()]\n .map(([reason, count]) => ({ reason, count, share: count / mine.length }))\n .sort((a, b) => b.count - a.count);\n\n const unstableProps = [...unstable.entries()]\n .map(([key, v]) => ({ key, count: v.count, share: v.count / denominator, valueType: v.valueType }))\n .sort((a, b) => b.count - a.count);\n\n // Ranked over updates, for the same reason the shares are.\n const top = [...reasonCounts.entries()]\n .filter(([reason]) => reason !== \"mount\")\n .map(([reason, count]) => ({ reason, count, share: count / denominator }))\n .sort((a, b) => b.count - a.count)[0];\n const topProp = unstableProps[0];\n const latest = mine[mine.length - 1] as RenderEvent;\n\n let headline: string;\n let nextStep: string;\n let confidence: Confidence = \"medium\";\n\n if (topProp && topProp.share >= 0.5) {\n headline = `${pct(topProp.share)} of updates followed \\`${topProp.key}\\` changing by reference while its contents stayed the same.`;\n // `parent` is the nearest instrumented ancestor — where the prop arrives\n // from, which is not necessarily where it is created. Say the former.\n const via = latest.parent?.name;\n nextStep =\n `Trace \\`${topProp.key}\\` back from ${via ? `${via}, which passes it to ${component}` : component}, ` +\n `and stabilise it where it is created${\n topProp.valueType === \"function\" ? \" (useCallback, or hoist it out of the component)\" : \" (useMemo, or pass the primitive fields you use)\"\n }.`;\n confidence = \"high\";\n } else if (top && top.reason === \"parent\" && top.share >= 0.5) {\n headline = `${pct(top.share)} of updates were parent propagation with identical props.`;\n nextStep = `Measure ${component} with React.memo(). It is only worth it if ${fmt(totalSelf / mine.length)} per render matters here.`;\n confidence = \"high\";\n } else if (top && top.reason === \"context\") {\n headline = `${pct(top.share)} of updates followed a tracked context update.`;\n nextStep = \"Check whether the provider's value is stable, and whether this component needs the whole context value.\";\n confidence = \"medium\";\n } else if (top && (top.reason === \"state\" || top.reason === \"state-or-external\")) {\n headline = `${pct(top.share)} of updates came from inside the component — state or an external store.`;\n nextStep =\n top.reason === \"state\"\n ? \"These are real state updates. Check whether every update needs to change state.\"\n : \"Name the state with useTrackedState to see which value drives these renders.\";\n confidence = top.reason === \"state\" ? \"high\" : \"medium\";\n } else if (top && top.reason === \"props\") {\n // Do not call a bucket \"new values\" without checking that it holds any.\n if (propsReferenceOnly > propsWithNewValues) {\n headline = `${pct(propsReferenceOnly / denominator)} of updates were prop changes where only the reference changed — the contents were identical.`;\n nextStep = `Stabilise the props listed above in whichever component renders ${component}.`;\n confidence = \"high\";\n } else if (propsReferenceOnly > 0) {\n headline =\n `${pct(propsWithNewValues / denominator)} of updates carried genuinely new prop values, ` +\n `and ${pct(propsReferenceOnly / denominator)} changed by reference only.`;\n nextStep = \"The reference-only ones are the avoidable half — start there.\";\n confidence = \"high\";\n } else {\n headline = `${pct(top.share)} of updates were driven by props with genuinely new values.`;\n nextStep = \"These look like legitimate data changes. Look at render cost rather than render count.\";\n confidence = \"high\";\n }\n } else {\n headline = \"Cause could not be determined reliably.\";\n nextStep = \"Instrument the parent, or track the context this component consumes, to narrow it down.\";\n confidence = \"low\";\n }\n\n return {\n component,\n renders: mine.length,\n mounts: mine.length - updates.length,\n breakdown,\n unstableProps,\n averageSelfDuration: totalSelf / mine.length,\n totalSelfDuration: totalSelf,\n potentiallyAvoidableRenders: avoidable,\n estimatedAvoidableTime: avoidableTime,\n devReplays: replays,\n headline,\n nextStep,\n confidence,\n };\n}\n\nexport function formatExplanation(e: Explanation): string {\n const lines: string[] = [\n `${e.component}`,\n \"\",\n `${e.renders} recorded render${e.renders === 1 ? \"\" : \"s\"}${e.mounts > 0 ? ` (${e.mounts} mount${e.mounts === 1 ? \"\" : \"s\"})` : \"\"}`,\n \"\",\n \"Why?\",\n ` ${e.headline}`,\n \"\",\n \"Breakdown (share of all renders)\",\n ...e.breakdown.map((b) => ` ${b.reason.padEnd(18)} ${String(b.count).padStart(5)} ${pct(b.share)}`),\n ];\n\n if (e.unstableProps.length > 0) {\n lines.push(\"\", \"Reference-only prop changes (share of updates)\");\n for (const p of e.unstableProps) {\n lines.push(` ${p.key.padEnd(18)} ${String(p.count).padStart(5)} ${pct(p.share)} (${p.valueType})`);\n }\n }\n\n lines.push(\n \"\",\n \"Cost\",\n ` average ${fmt(e.averageSelfDuration)}`,\n ` total ${fmt(e.totalSelfDuration)}`,\n ` potentially avoidable ${e.potentiallyAvoidableRenders} render(s), ~${fmt(e.estimatedAvoidableTime)}`,\n );\n\n if (e.devReplays > 0) {\n lines.push(\n \"\",\n ` ${e.devReplays} development replay(s) observed (StrictMode double-invoke or discarded attempts) — excluded from the counts above.`,\n );\n }\n\n lines.push(\"\", \"Next step\", ` ${e.nextStep}`, \"\", `Confidence: ${e.confidence}`);\n return lines.join(\"\\n\");\n}\n\nconst pct = (n: number): string => `${Math.round(n * 100)}%`;\nconst fmt = (ms: number): string => `${ms.toFixed(1)}ms`;\n"]}
@@ -139,16 +139,20 @@ function formatInspected(node) {
139
139
  }
140
140
 
141
141
  // src/core/config.ts
142
- function detectDev() {
142
+ function detectProduction() {
143
143
  try {
144
144
  const env = typeof process !== "undefined" ? process?.env : void 0;
145
- if (env && env.NODE_ENV) return env.NODE_ENV !== "production";
145
+ if (env && env.NODE_ENV) return env.NODE_ENV === "production";
146
146
  } catch {
147
147
  }
148
148
  return false;
149
149
  }
150
+ function detectDev() {
151
+ return !detectProduction();
152
+ }
150
153
  var defaultConfig = {
151
- enabled: detectDev(),
154
+ // Off until `init()` is called, so importing the package costs nothing.
155
+ enabled: false,
152
156
  mode: "console",
153
157
  include: [],
154
158
  exclude: [],
@@ -596,9 +600,16 @@ var Detective = class {
596
600
  this.initialized = false;
597
601
  this.events = new RingBuffer(this.config.maxEvents);
598
602
  }
599
- /** Idempotent: repeated calls reconfigure, they never duplicate anything (§47). */
603
+ /**
604
+ * Idempotent: repeated calls reconfigure, they never duplicate anything (§47).
605
+ *
606
+ * Calling `init()` *is* the intent to turn diagnostics on, so `enabled`
607
+ * defaults to true unless a production build is positively detected. Guard
608
+ * the call itself for production safety — that is what the docs show, and it
609
+ * is what lets a bundler drop the whole thing.
610
+ */
600
611
  init(options = {}) {
601
- this.configure(options);
612
+ this.configure({ enabled: !detectProduction(), ...options });
602
613
  this.initialized = true;
603
614
  return this;
604
615
  }
@@ -658,8 +669,6 @@ var Detective = class {
658
669
  this.nodes.set(node.id, node);
659
670
  }
660
671
  detach(node) {
661
- node.prevProps = void 0;
662
- node.pendingProps = void 0;
663
672
  this.nodes.delete(node.id);
664
673
  }
665
674
  /** Hot path. Must stay allocation-free and O(1). */
@@ -1026,5 +1035,5 @@ exports.severityFor = severityFor;
1026
1035
  exports.shallowEqual = shallowEqual;
1027
1036
  exports.shouldInstrument = shouldInstrument;
1028
1037
  exports.valueType = valueType;
1029
- //# sourceMappingURL=chunk-7FTXUOB6.cjs.map
1030
- //# sourceMappingURL=chunk-7FTXUOB6.cjs.map
1038
+ //# sourceMappingURL=chunk-SKLDIIL6.cjs.map
1039
+ //# sourceMappingURL=chunk-SKLDIIL6.cjs.map