why-hydration 0.1.4 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/CHANGELOG.md +108 -1
  2. package/README.md +220 -33
  3. package/dist/{chunk-WQLUD25W.js → chunk-3OAI2ZHY.js} +375 -118
  4. package/dist/chunk-3OAI2ZHY.js.map +1 -0
  5. package/dist/{chunk-OGQEPU7G.cjs → chunk-DXPTZB3Z.cjs} +44 -2
  6. package/dist/chunk-DXPTZB3Z.cjs.map +1 -0
  7. package/dist/{chunk-DSO337ME.cjs → chunk-KX6G7I4Y.cjs} +384 -118
  8. package/dist/chunk-KX6G7I4Y.cjs.map +1 -0
  9. package/dist/chunk-MK3TYHKM.js +966 -0
  10. package/dist/chunk-MK3TYHKM.js.map +1 -0
  11. package/dist/chunk-R7IWOK5M.cjs +989 -0
  12. package/dist/chunk-R7IWOK5M.cjs.map +1 -0
  13. package/dist/{chunk-FV3PEJQE.js → chunk-XIM33ZGB.js} +44 -2
  14. package/dist/chunk-XIM33ZGB.js.map +1 -0
  15. package/dist/index.cjs +32 -24
  16. package/dist/index.d.cts +43 -5
  17. package/dist/index.d.ts +43 -5
  18. package/dist/index.js +2 -2
  19. package/dist/next/index.cjs +5 -5
  20. package/dist/next/index.d.cts +1 -1
  21. package/dist/next/index.d.ts +1 -1
  22. package/dist/next/index.js +3 -3
  23. package/dist/next/script.cjs +2 -2
  24. package/dist/next/script.js +1 -1
  25. package/dist/react.cjs +5 -5
  26. package/dist/react.d.cts +23 -3
  27. package/dist/react.d.ts +23 -3
  28. package/dist/react.js +3 -3
  29. package/dist/{types-6wTih14e.d.cts → types-C14vcpBO.d.cts} +9 -0
  30. package/dist/{types-6wTih14e.d.ts → types-C14vcpBO.d.ts} +9 -0
  31. package/package.json +1 -1
  32. package/dist/chunk-3KULWJ7A.js +0 -569
  33. package/dist/chunk-3KULWJ7A.js.map +0 -1
  34. package/dist/chunk-5CBGYE7A.cjs +0 -592
  35. package/dist/chunk-5CBGYE7A.cjs.map +0 -1
  36. package/dist/chunk-DSO337ME.cjs.map +0 -1
  37. package/dist/chunk-FV3PEJQE.js.map +0 -1
  38. package/dist/chunk-OGQEPU7G.cjs.map +0 -1
  39. package/dist/chunk-WQLUD25W.js.map +0 -1
@@ -0,0 +1,966 @@
1
+ import { isDev, ReportCollector, inspectRoot, reportFromMessage, isInternalComponent, formatConsoleArgs, isHydrationMessage, EN_MESSAGES, plainText, renderMessage, code, classDetail, param } from './chunk-3OAI2ZHY.js';
2
+ import { getServerHtmlForRoot, readSnapshot, DEFAULT_SNAPSHOT_SELECTORS } from './chunk-XIM33ZGB.js';
3
+ import * as React2 from 'react';
4
+
5
+ // src/react/console.ts
6
+ function installConsoleInterceptor(onMessage) {
7
+ if (typeof console === "undefined") return () => {
8
+ };
9
+ const original = console.error;
10
+ const patched = (...args) => {
11
+ try {
12
+ const message = formatConsoleArgs(args);
13
+ if (message && isHydrationMessage(message)) {
14
+ onMessage(message, args);
15
+ }
16
+ } catch {
17
+ }
18
+ original.apply(console, args);
19
+ };
20
+ console.error = patched;
21
+ return () => {
22
+ if (console.error === patched) {
23
+ console.error = original;
24
+ }
25
+ };
26
+ }
27
+ var BADGE = "color:#f59e0b;font-weight:bold";
28
+ var DIM = "color:#9ca3af";
29
+ function createConsoleReporter() {
30
+ const sink = (report) => {
31
+ const title = `%c\u2B21 why-hydration%c ${report.cause.category} \u2014 ${report.node.path}`;
32
+ console.group(title, BADGE, DIM);
33
+ console.log("%cServer:%c", "color:#fb7185", "", report.server ?? "(none)");
34
+ console.log("%cClient:%c", "color:#4ade80", "", report.client ?? "(none)");
35
+ if (report.component) {
36
+ console.log("%cComponent:%c", DIM, "", `<${report.component}>`);
37
+ }
38
+ if (report.location?.file) {
39
+ const loc = report.location.line ? `${report.location.file}:${report.location.line}` : report.location.file;
40
+ console.log("%cSource:%c", DIM, "", loc);
41
+ }
42
+ console.log("%cWhy:%c", DIM, "", report.cause.explanation);
43
+ console.log("%cFix:%c", "color:#86efac", "", report.cause.suggestion);
44
+ if (report.cause.docsUrl) {
45
+ console.log("%cDocs:%c", DIM, "", report.cause.docsUrl);
46
+ }
47
+ if (report.componentStack) {
48
+ console.log("%cComponent stack:%c", DIM, "", report.componentStack);
49
+ }
50
+ console.groupEnd();
51
+ };
52
+ return sink;
53
+ }
54
+
55
+ // src/react/capture.ts
56
+ var MAX_CAPTURED = 50;
57
+ var captured = /* @__PURE__ */ new Set();
58
+ var listeners = /* @__PURE__ */ new Set();
59
+ var uninstall = null;
60
+ function startCapture() {
61
+ if (uninstall || typeof window === "undefined") return;
62
+ uninstall = installConsoleInterceptor((message) => {
63
+ if (captured.has(message) || captured.size >= MAX_CAPTURED) return;
64
+ captured.add(message);
65
+ for (const listener of [...listeners]) listener(message);
66
+ });
67
+ }
68
+ function subscribeCapture(listener) {
69
+ startCapture();
70
+ listeners.add(listener);
71
+ for (const message of [...captured]) listener(message);
72
+ return () => {
73
+ if (!listeners.delete(listener)) return;
74
+ if (listeners.size === 0 && uninstall) {
75
+ uninstall();
76
+ uninstall = null;
77
+ }
78
+ };
79
+ }
80
+
81
+ // src/react/i18n.ts
82
+ var EN = {
83
+ dir: "ltr",
84
+ title: "Hydration mismatch",
85
+ dialogLabel: "Hydration mismatch diagnostics",
86
+ dismiss: "Dismiss",
87
+ dismissLabel: "Dismiss diagnostics overlay",
88
+ hintDismissLabel: "Dismiss hint",
89
+ server: "Server",
90
+ client: "Client",
91
+ fix: "Fix:",
92
+ learnMore: "Learn more \u2192",
93
+ none: "(none)",
94
+ empty: "(empty)",
95
+ fallbackCategory: "Mismatch",
96
+ categories: {
97
+ "non-deterministic-value": "Non-deterministic value",
98
+ "date-time": "Date / time",
99
+ "locale-format": "Locale formatting",
100
+ "browser-only-api": "Browser-only API",
101
+ "viewport-branching": "Viewport branching",
102
+ "invalid-html-nesting": "Invalid HTML nesting",
103
+ "whitespace-minification": "Whitespace / minification",
104
+ "third-party-dom-mutation": "Third-party DOM mutation",
105
+ "attribute-mismatch": "Attribute mismatch",
106
+ unknown: "Unknown"
107
+ },
108
+ messages: EN_MESSAGES,
109
+ hint: (count) => `\u2193 ${count} issues \u2014 scroll to see all`
110
+ };
111
+ var AR_MESSAGES = {
112
+ "non-deterministic-value": {
113
+ explanation: "\u0639\u0631\u0636 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644 \u0642\u064A\u0645\u062A\u064A\u0646 \u062A\u0628\u062F\u0648\u0627\u0646 \u0639\u0634\u0648\u0627\u0626\u064A\u062A\u064A\u0646 \u0648\u0645\u062E\u062A\u0644\u0641\u062A\u064A\u0646 (\u0645\u0639\u0631\u0651\u0641 \u0623\u0648 \u0631\u0645\u0632 \u0623\u0648 \u0646\u0627\u062A\u062C `Math.random()`). \u0623\u064A \u0634\u064A\u0621 \u063A\u064A\u0631 \u062D\u062A\u0645\u064A \u0623\u062B\u0646\u0627\u0621 \u0627\u0644\u0639\u0631\u0636 \u064A\u0646\u062A\u062C \u0642\u064A\u0645\u0629 \u0645\u062E\u062A\u0644\u0641\u0629 \u0639\u0644\u0649 \u0643\u0644 \u062C\u0627\u0646\u0628.",
114
+ suggestion: "\u0627\u0633\u062A\u062E\u062F\u0645 `useId()` \u0645\u0646 React \u0644\u0644\u0645\u0639\u0631\u0651\u0641\u0627\u062A. \u0623\u0645\u0627 \u0627\u0644\u0642\u064A\u0645 \u0627\u0644\u0639\u0634\u0648\u0627\u0626\u064A\u0629 \u0641\u0648\u0644\u0651\u062F\u0647\u0627 \u0628\u0639\u062F \u0627\u0644\u062A\u0631\u0643\u064A\u0628 (\u062F\u0627\u062E\u0644 `useEffect`) \u0623\u0648 \u0645\u0631\u0651\u0631\u0647\u0627 \u0645\u0646 \u0627\u0644\u062E\u0627\u062F\u0645 \u0644\u064A\u062A\u0641\u0642 \u0627\u0644\u0637\u0631\u0641\u0627\u0646. \u0644\u0627 \u062A\u0633\u062A\u062F\u0639\u0650 `Math.random()` \u0623\u0648 `crypto` \u0623\u062B\u0646\u0627\u0621 \u0627\u0644\u0639\u0631\u0636 \u0623\u0628\u062F\u064B\u0627."
115
+ },
116
+ "date-time": {
117
+ explanation: "\u0627\u0644\u0642\u064A\u0645\u062A\u0627\u0646 \u062A\u0627\u0631\u064A\u062E\u0627\u0646 \u0623\u0648 \u0648\u0642\u062A\u0627\u0646 \u064A\u062E\u062A\u0644\u0641\u0627\u0646 \u0628\u064A\u0646 \u0639\u0631\u0636 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0639\u0631\u0636 \u0627\u0644\u0639\u0645\u064A\u0644 \u2014 \u062A\u063A\u064A\u0651\u0631\u062A \u0627\u0644\u0633\u0627\u0639\u0629 (\u0623\u0648 \u0627\u062E\u062A\u0644\u0641\u062A \u0627\u0644\u0645\u0646\u0637\u0642\u0629 \u0627\u0644\u0632\u0645\u0646\u064A\u0629) \u0628\u064A\u0646 \u0627\u0644\u0628\u064A\u0626\u062A\u064A\u0646.",
118
+ suggestion: "\u0627\u0639\u0631\u0636 \u0627\u0644\u0648\u0642\u062A \u0627\u0644\u062D\u0627\u0644\u064A \u0628\u0639\u062F \u0627\u0644\u062A\u0631\u0643\u064A\u0628\u060C \u0623\u0648 \u0645\u0631\u0651\u0631 \u0637\u0627\u0628\u0639\u064B\u0627 \u0632\u0645\u0646\u064A\u064B\u0627 \u0648\u0627\u062D\u062F\u064B\u0627 \u0645\u0646 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0646\u0633\u0651\u0642\u0647 \u0628\u0627\u0644\u0637\u0631\u064A\u0642\u0629 \u0646\u0641\u0633\u0647\u0627 \u0639\u0644\u0649 \u0627\u0644\u062C\u0627\u0646\u0628\u064A\u0646. \u0648\u062D\u062F\u0651\u062F \u0645\u0646\u0637\u0642\u0629 \u0632\u0645\u0646\u064A\u0629 \u0635\u0631\u064A\u062D\u0629 \u0639\u0646\u062F \u0627\u0644\u062A\u0646\u0633\u064A\u0642."
119
+ },
120
+ "locale-format.bidi": {
121
+ explanation: "\u0627\u0644\u0642\u064A\u0645\u062A\u0627\u0646 \u0644\u0627 \u062A\u062E\u062A\u0644\u0641\u0627\u0646 \u0625\u0644\u0627 \u0628\u0639\u0644\u0627\u0645\u0627\u062A \u062A\u062D\u0643\u0645 \u062B\u0646\u0627\u0626\u064A\u0629 \u0627\u0644\u0627\u062A\u062C\u0627\u0647 \u063A\u064A\u0631 \u0645\u0631\u0626\u064A\u0629 (`LRM` \u0648`RLM` \u0648\u0639\u0644\u0627\u0645\u0627\u062A \u0627\u0644\u0639\u0632\u0644). \u062A\u0636\u064A\u0641 `Intl` \u0647\u0630\u0647 \u0627\u0644\u0639\u0644\u0627\u0645\u0627\u062A \u062D\u0648\u0644 \u0627\u0644\u0623\u0631\u0642\u0627\u0645 \u0648\u0627\u0644\u062A\u0648\u0627\u0631\u064A\u062E \u0641\u064A \u0627\u0644\u0644\u063A\u0627\u062A \u0627\u0644\u062A\u064A \u062A\u064F\u0643\u062A\u0628 \u0645\u0646 \u0627\u0644\u064A\u0645\u064A\u0646 \u0625\u0644\u0649 \u0627\u0644\u064A\u0633\u0627\u0631\u060C \u0648\u062A\u064F\u0635\u062F\u0631 \u0625\u0635\u062F\u0627\u0631\u0627\u062A ICU \u0627\u0644\u0645\u062E\u062A\u0644\u0641\u0629 \u2014 Node \u0645\u0642\u0627\u0628\u0644 \u0627\u0644\u0645\u062A\u0635\u0641\u062D \u2014 \u0639\u0644\u0627\u0645\u0627\u062A \u0645\u062E\u062A\u0644\u0641\u0629 \u0644\u0644\u0645\u062F\u062E\u0644 \u0646\u0641\u0633\u0647.",
122
+ suggestion: "\u0646\u0633\u0651\u0642 \u0627\u0644\u0642\u064A\u0645\u0629 \u0641\u064A \u0645\u0643\u0627\u0646 \u0648\u0627\u062D\u062F \u0648\u0645\u0631\u0651\u0631 \u0627\u0644\u0646\u0635 \u0627\u0644\u0646\u0627\u062A\u062C\u060C \u0623\u0648 \u062B\u0628\u0651\u062A \u0627\u0644\u0644\u063A\u0629 \u0648\u0627\u0644\u0645\u0646\u0637\u0642\u0629 \u0627\u0644\u0632\u0645\u0646\u064A\u0629 \u0646\u0641\u0633\u064A\u0647\u0645\u0627 \u0639\u0644\u0649 \u0627\u0644\u062C\u0627\u0646\u0628\u064A\u0646. \u0648\u0625\u0646 \u0643\u0627\u0646\u062A \u0627\u0644\u0639\u0644\u0627\u0645\u0627\u062A \u063A\u064A\u0631 \u0645\u0624\u0630\u064A\u0629 \u0641\u0623\u0636\u0641 `suppressHydrationWarning` \u0625\u0644\u0649 \u0627\u0644\u0639\u0646\u0635\u0631."
123
+ },
124
+ "locale-format.script": {
125
+ explanation: "\u0646\u064F\u0633\u0651\u0642\u062A \u0627\u0644\u0642\u064A\u0645\u0629 \u0646\u0641\u0633\u0647\u0627 \u0628\u0646\u0638\u0627\u0645\u064E\u064A \u0623\u0631\u0642\u0627\u0645 \u0645\u062E\u062A\u0644\u0641\u064A\u0646 (\u0623\u0631\u0642\u0627\u0645 \u0639\u0631\u0628\u064A\u0629 \u0645\u0634\u0631\u0642\u064A\u0629 `\u0660\u0661\u0662` \u0645\u0642\u0627\u0628\u0644 \u0623\u0631\u0642\u0627\u0645 \u0644\u0627\u062A\u064A\u0646\u064A\u0629 `012`). \u0627\u062E\u062A\u0627\u0631 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644 \u0625\u0639\u062F\u0627\u062F\u064A\u0646 \u0645\u062D\u0644\u064A\u064A\u0646 \u0645\u062E\u062A\u0644\u0641\u064A\u0646.",
126
+ suggestion: "\u0645\u0631\u0651\u0631 `locale` \u0635\u0631\u064A\u062D\u064B\u0627 (\u0648\u0645\u0646\u0637\u0642\u0629 \u0632\u0645\u0646\u064A\u0629) \u0625\u0644\u0649 `Intl.NumberFormat` \u0623\u0648 `toLocaleString` \u0639\u0644\u0649 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644 \u0645\u0639\u064B\u0627\u060C \u0623\u0648 \u0646\u0633\u0651\u0642 \u0627\u0644\u0642\u064A\u0645\u0629 \u0628\u0639\u062F \u0627\u0644\u062A\u0631\u0643\u064A\u0628 \u0644\u064A\u064F\u0633\u062A\u062E\u062F\u0645 \u0625\u0639\u062F\u0627\u062F \u0627\u0644\u0639\u0645\u064A\u0644 \u0648\u062D\u062F\u0647."
127
+ },
128
+ "locale-format.separators": {
129
+ explanation: "\u0646\u064F\u0633\u0651\u0642 \u0627\u0644\u0631\u0642\u0645 \u0646\u0641\u0633\u0647 \u0628\u0641\u0648\u0627\u0635\u0644 \u0622\u0644\u0627\u0641 \u0623\u0648 \u0641\u0648\u0627\u0635\u0644 \u0639\u0634\u0631\u064A\u0629 \u0645\u062E\u062A\u0644\u0641\u0629 \u0628\u064A\u0646 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644 (\u0645\u062B\u0644 `1,234.56` \u0645\u0642\u0627\u0628\u0644 `1.234,56`).",
130
+ suggestion: "\u0645\u0631\u0651\u0631 \u0625\u0639\u062F\u0627\u062F\u064B\u0627 \u0645\u062D\u0644\u064A\u064B\u0627 \u0635\u0631\u064A\u062D\u064B\u0627 \u0625\u0644\u0649 `Intl.NumberFormat` \u0623\u0648 `toLocaleString` \u0639\u0644\u0649 \u0627\u0644\u062C\u0627\u0646\u0628\u064A\u0646 \u0644\u062A\u062A\u0637\u0627\u0628\u0642 \u0627\u0644\u0641\u0648\u0627\u0635\u0644."
131
+ },
132
+ "locale-format.date-order": {
133
+ explanation: "\u0639\u064F\u0631\u0636 \u0627\u0644\u062A\u0627\u0631\u064A\u062E \u0646\u0641\u0633\u0647 \u0628\u062A\u0631\u062A\u064A\u0628 \u062D\u0642\u0648\u0644 \u0645\u062E\u062A\u0644\u0641 (`MM/DD` \u0645\u0642\u0627\u0628\u0644 `DD/MM`) \u0628\u064A\u0646 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644.",
134
+ suggestion: "\u0646\u0633\u0651\u0642 \u0627\u0644\u062A\u0648\u0627\u0631\u064A\u062E \u0628\u0625\u0639\u062F\u0627\u062F \u0645\u062D\u0644\u064A \u0648\u0645\u0646\u0637\u0642\u0629 \u0632\u0645\u0646\u064A\u0629 \u0635\u0631\u064A\u062D\u064A\u0646 \u0639\u0628\u0631 `Intl` \u0639\u0644\u0649 \u0627\u0644\u062C\u0627\u0646\u0628\u064A\u0646."
135
+ },
136
+ "browser-only-api": {
137
+ explanation: "\u0639\u0631\u0636 \u0627\u0644\u0639\u0645\u064A\u0644 \u0645\u062D\u062A\u0648\u0649 \u062A\u0631\u0643\u0647 \u0627\u0644\u062E\u0627\u062F\u0645 \u0641\u0627\u0631\u063A\u064B\u0627 \u2014 \u0648\u0647\u0630\u0647 \u0639\u0644\u0627\u0645\u0629 \u0639\u0644\u0649 \u0642\u0631\u0627\u0621\u0629 \u0648\u0627\u062C\u0647\u0629 \u0644\u0627 \u062A\u062A\u0648\u0641\u0631 \u0625\u0644\u0627 \u0641\u064A \u0627\u0644\u0645\u062A\u0635\u0641\u062D (`window` \u0623\u0648 `document` \u0623\u0648 `localStorage` \u0623\u0648 `navigator` \u0623\u0648 `matchMedia`) \u0623\u062B\u0646\u0627\u0621 \u0627\u0644\u0639\u0631\u0636.",
138
+ suggestion: "\u0627\u062C\u0639\u0644 \u0642\u0631\u0627\u0621\u0627\u062A \u0627\u0644\u0645\u062A\u0635\u0641\u062D \u0645\u0634\u0631\u0648\u0637\u0629 \u0628\u0639\u0644\u0627\u0645\u0629 \u062A\u0631\u0643\u064A\u0628 \u0623\u0648 \u0636\u0639\u0647\u0627 \u062F\u0627\u062E\u0644 `useEffect`\u060C \u0623\u0648 \u0627\u0633\u062A\u062E\u062F\u0645 `useSyncExternalStore` \u0645\u0639 \u0644\u0642\u0637\u0629 \u0644\u0644\u062E\u0627\u062F\u0645 \u0644\u064A\u0637\u0627\u0628\u0642 \u0623\u0648\u0644 \u0639\u0631\u0636 \u0639\u0644\u0649 \u0627\u0644\u0639\u0645\u064A\u0644 \u0645\u0627 \u0639\u0631\u0636\u0647 \u0627\u0644\u062E\u0627\u062F\u0645."
139
+ },
140
+ "viewport-branching": {
141
+ explanation: "\u0623\u064F\u0636\u064A\u0641\u062A \u0634\u062C\u0631\u0629 \u0641\u0631\u0639\u064A\u0629 \u0643\u0627\u0645\u0644\u0629 \u0623\u0648 \u062D\u064F\u0630\u0641\u062A \u0623\u0648 \u0627\u0633\u062A\u064F\u0628\u062F\u0644\u062A \u0628\u064A\u0646 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644 \u2014 \u063A\u0627\u0644\u0628\u064B\u0627 \u0628\u0633\u0628\u0628 \u0641\u062D\u0635 \u0641\u064A JavaScript \u0644\u0639\u0631\u0636 \u0627\u0644\u0634\u0627\u0634\u0629 \u064A\u0641\u0631\u0651\u0639 \u0627\u0644\u0634\u062C\u0631\u0629 \u0641\u064A \u0623\u0648\u0644 \u0639\u0631\u0636.",
142
+ suggestion: "\u0627\u0639\u0631\u0636 \u0627\u0644\u0641\u0631\u0639\u064A\u0646 \u0648\u0628\u062F\u0651\u0644 \u0628\u064A\u0646\u0647\u0645\u0627 \u0628\u0627\u0633\u062A\u0639\u0644\u0627\u0645\u0627\u062A \u0627\u0644\u0648\u0633\u0627\u0626\u0637 \u0641\u064A CSS \u0639\u0646\u062F \u0623\u0648\u0644 \u0631\u0633\u0645 \u0628\u062F\u0644 \u0627\u0644\u062A\u0641\u0631\u064A\u0639 \u0641\u064A JavaScript\u060C \u0623\u0648 \u0623\u062C\u0651\u0644 \u0627\u0644\u0641\u0631\u0639 \u0627\u0644\u0645\u0639\u062A\u0645\u062F \u0639\u0644\u0649 JavaScript \u0625\u0644\u0649 \u0645\u0627 \u0628\u0639\u062F \u0627\u0644\u062A\u0631\u0643\u064A\u0628."
143
+ },
144
+ "invalid-html-nesting": {
145
+ explanation: "\u0646\u064F\u0642\u0644\u062A \u0639\u0642\u062F\u0629 \u0623\u0648 \u0623\u064F\u062E\u0631\u062C\u062A \u0645\u0646 \u0645\u0643\u0627\u0646\u0647\u0627 \u0644\u0623\u0646 \u062A\u0631\u0645\u064A\u0632 HTML \u063A\u064A\u0631 \u0635\u0627\u0644\u062D (\u0645\u062B\u0644 `<div>` \u062F\u0627\u062E\u0644 `<p>`\u060C \u0623\u0648 `<a>` \u062F\u0627\u062E\u0644 `<a>`). \u064A\u064F\u0635\u0644\u062D \u0627\u0644\u0645\u062A\u0635\u0641\u062D DOM \u0627\u0644\u0642\u0627\u062F\u0645 \u0645\u0646 \u0627\u0644\u062E\u0627\u062F\u0645\u060C \u0641\u0644\u0627 \u064A\u0639\u0648\u062F \u0645\u0637\u0627\u0628\u0642\u064B\u0627 \u0644\u0645\u0627 \u064A\u062A\u0648\u0642\u0639\u0647 React.",
146
+ suggestion: "\u0635\u062D\u0651\u062D \u0635\u0644\u0627\u062D\u064A\u0629 \u0627\u0644\u062A\u0631\u0645\u064A\u0632: \u0644\u0627 \u064A\u0645\u0643\u0646 \u0648\u0636\u0639 \u0627\u0644\u0639\u0646\u0627\u0635\u0631 \u0627\u0644\u0643\u062A\u0644\u064A\u0629 \u062F\u0627\u062E\u0644 `<p>`\u060C \u0648\u0644\u0627 \u064A\u0645\u0643\u0646 \u062A\u062F\u0627\u062E\u0644 \u0627\u0644\u0631\u0648\u0627\u0628\u0637. \u0627\u0633\u062A\u0628\u062F\u0644 \u0627\u0644\u0639\u0646\u0635\u0631 \u0627\u0644\u0623\u0628 \u063A\u064A\u0631 \u0627\u0644\u0635\u0627\u0644\u062D \u0628\u0640 `<div>` \u0623\u0648 \u0623\u0639\u062F \u0647\u064A\u0643\u0644\u0629 \u0627\u0644\u0634\u062C\u0631\u0629."
147
+ },
148
+ "whitespace-minification": {
149
+ explanation: "\u0627\u0644\u0627\u062E\u062A\u0644\u0627\u0641 \u0641\u064A \u0627\u0644\u0645\u0633\u0627\u0641\u0627\u062A \u0627\u0644\u0628\u064A\u0636\u0627\u0621 \u0641\u0642\u0637 \u2014 \u0627\u0644\u0646\u0635 \u0645\u062A\u0637\u0627\u0628\u0642 \u0628\u0627\u0633\u062A\u062B\u0646\u0627\u0621 \u0627\u0644\u0645\u0633\u0627\u0641\u0627\u062A \u0648\u0627\u0644\u0623\u0633\u0637\u0631 \u0627\u0644\u062C\u062F\u064A\u062F\u0629. \u0639\u0644\u0649 \u0627\u0644\u0623\u0631\u062C\u062D \u0636\u063A\u0637 \u0645\u064F\u0635\u063A\u0651\u0631 HTML \u0627\u0644\u0645\u0633\u0627\u0641\u0627\u062A \u062D\u0648\u0644 \u062C\u0630\u0631 \u0627\u0644\u0640 Hydration \u0628\u0637\u0631\u064A\u0642\u0629 \u0645\u062E\u062A\u0644\u0641\u0629 \u0639\u0646 React.",
150
+ suggestion: "\u0631\u0627\u062C\u0639 \u0625\u0639\u062F\u0627\u062F\u0627\u062A \u0645\u064F\u0635\u063A\u0651\u0631 HTML (\u0645\u062B\u0644 `conservativeCollapse`) \u062D\u0648\u0644 \u062C\u0630\u0631 \u0627\u0644\u062A\u0637\u0628\u064A\u0642\u060C \u0623\u0648 \u062A\u062C\u0646\u0651\u0628 \u062A\u0635\u063A\u064A\u0631 \u0627\u0644\u0645\u0633\u0627\u0641\u0627\u062A \u062F\u0627\u062E\u0644 \u0627\u0644\u062A\u0631\u0645\u064A\u0632 \u0627\u0644\u0630\u064A \u064A\u0645\u0631 \u0628\u0627\u0644\u0640 Hydration."
151
+ },
152
+ "third-party-dom-mutation.extension-attribute": {
153
+ explanation: "\u062D\u0642\u0646 \u0627\u0645\u062A\u062F\u0627\u062F \u0645\u062A\u0635\u0641\u062D \u0623\u0648 \u0633\u0643\u0631\u0628\u062A \u062E\u0627\u0631\u062C\u064A (\u0645\u062B\u0644 Grammarly \u0623\u0648 ColorZilla) \u0627\u0644\u0633\u0645\u0629 `{attribute}` \u0642\u0628\u0644 \u0627\u0644\u0640 Hydration\u060C \u0641\u0644\u0645 \u064A\u0639\u062F DOM \u0639\u0644\u0649 \u0627\u0644\u0639\u0645\u064A\u0644 \u0645\u0637\u0627\u0628\u0642\u064B\u0627 \u0644\u0644\u062E\u0627\u062F\u0645.",
154
+ suggestion: "\u063A\u0627\u0644\u0628\u064B\u0627 \u0645\u0627 \u064A\u0643\u0648\u0646 \u0647\u0630\u0627 \u063A\u064A\u0631 \u0645\u0624\u0630\u064D. \u0623\u0636\u0641 `suppressHydrationWarning` \u0625\u0644\u0649 \u0627\u0644\u0639\u0646\u0635\u0631 \u0627\u0644\u0645\u062A\u0623\u062B\u0631\u060C \u0623\u0648 \u0623\u062C\u0651\u0644 \u062A\u0647\u064A\u0626\u0629 \u0627\u0644\u0633\u0643\u0631\u0628\u062A \u0627\u0644\u062E\u0627\u0631\u062C\u064A \u0625\u0644\u0649 \u0645\u0627 \u0628\u0639\u062F \u0627\u0644\u0640 Hydration."
155
+ },
156
+ "third-party-dom-mutation.root-attribute": {
157
+ explanation: "\u0638\u0647\u0631\u062A \u0633\u0645\u0629 (`{attribute}`) \u0639\u0644\u0649 \u0639\u0646\u0635\u0631 \u062C\u0630\u0631\u064A \u0644\u0645 \u064A\u0631\u0633\u0644\u0647\u0627 \u0627\u0644\u062E\u0627\u062F\u0645 \u0623\u0628\u062F\u064B\u0627 \u2014 \u0648\u0647\u064A \u0639\u0644\u0627\u0645\u0629 \u0645\u0645\u064A\u0632\u0629 \u0644\u0627\u0645\u062A\u062F\u0627\u062F \u0623\u0648 \u0633\u0643\u0631\u0628\u062A \u062E\u0627\u0631\u062C\u064A \u0645\u0628\u0643\u0631 \u064A\u0639\u062F\u0651\u0644 DOM.",
158
+ suggestion: "\u0623\u0636\u0641 `suppressHydrationWarning` \u0625\u0644\u0649 \u0627\u0644\u0639\u0646\u0635\u0631 \u0627\u0644\u062C\u0630\u0631\u064A\u060C \u0623\u0648 \u0623\u062C\u0651\u0644 \u0627\u0644\u0633\u0643\u0631\u0628\u062A \u0627\u0644\u062E\u0627\u0631\u062C\u064A \u0625\u0644\u0649 \u0645\u0627 \u0628\u0639\u062F \u0627\u0644\u0640 Hydration."
159
+ },
160
+ "third-party-dom-mutation.injected-node": {
161
+ explanation: (p) => [
162
+ "\u062D\u0642\u0646 \u0633\u0643\u0631\u0628\u062A \u062E\u0627\u0631\u062C\u064A \u0623\u0648 \u0627\u0645\u062A\u062F\u0627\u062F \u0645\u062A\u0635\u0641\u062D \u0627\u0644\u0639\u0646\u0635\u0631 ",
163
+ code(param(p, "tag")),
164
+ " (\u0625\u0639\u0644\u0627\u0646\u0627\u062A \u0623\u0648 \u0646\u0627\u0641\u0630\u0629 \u0645\u0648\u0627\u0641\u0642\u0629 \u0623\u0648 \u062A\u062D\u0644\u064A\u0644\u0627\u062A \u0623\u0648 \u0645\u062D\u0627\u062F\u062B\u0629) \u0628\u0639\u062F \u0639\u0631\u0636 \u0627\u0644\u062E\u0627\u062F\u0645. \u0644\u064A\u0633 \u0647\u0630\u0627 \u062C\u0632\u0621\u064B\u0627 \u0645\u0646 \u0627\u0644\u0640 Hydration \u0641\u064A \u062A\u0637\u0628\u064A\u0642\u0643\u060C \u0644\u0630\u0627 \u0641\u0647\u0648 \u063A\u0627\u0644\u0628\u064B\u0627 \u0636\u062C\u064A\u062C \u063A\u064A\u0631 \u0645\u0624\u0630\u064D."
165
+ ],
166
+ suggestion: '\u0625\u0646 \u062D\u0630\u0651\u0631 React \u0645\u0646\u0647 \u0641\u0623\u0636\u0641 `suppressHydrationWarning` \u0625\u0644\u0649 \u0623\u0642\u0631\u0628 \u063A\u0644\u0627\u0641 \u0639\u064F\u0631\u0636 \u0639\u0644\u0649 \u0627\u0644\u062E\u0627\u062F\u0645\u060C \u0623\u0648 \u062D\u0645\u0651\u0644 \u0627\u0644\u0633\u0643\u0631\u0628\u062A \u0627\u0644\u062E\u0627\u0631\u062C\u064A \u0628\u0639\u062F \u0627\u0644\u0640 Hydration (\u0645\u062B\u0644 `<Script strategy="afterInteractive">` \u0641\u064A Next.js).'
167
+ },
168
+ "attribute-mismatch.class": {
169
+ explanation: (p) => [
170
+ "\u062A\u062E\u062A\u0644\u0641 ",
171
+ code("class"),
172
+ " \u0628\u064A\u0646 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644",
173
+ ...classDetail(p, {
174
+ added: "\u0623\u064F\u0636\u064A\u0641 \u0639\u0644\u0649 \u0627\u0644\u0639\u0645\u064A\u0644: ",
175
+ removed: "\u0623\u064F\u0632\u064A\u0644 \u0639\u0644\u0649 \u0627\u0644\u0639\u0645\u064A\u0644: ",
176
+ listSeparator: "\u060C ",
177
+ partSeparator: "\u061B ",
178
+ open: " (",
179
+ close: ")"
180
+ }),
181
+ ". \u0637\u064F\u0628\u0651\u0642\u062A \u0641\u0626\u0629 CSS \u0628\u0634\u0643\u0644 \u0645\u0634\u0631\u0648\u0637 \u0639\u0644\u0649 \u0627\u0644\u0639\u0645\u064A\u0644 \u2014 \u063A\u0627\u0644\u0628\u064B\u0627 \u0628\u0633\u0628\u0628 \u0641\u062D\u0635 \u0644\u062D\u062C\u0645 \u0627\u0644\u0634\u0627\u0634\u0629 \u0623\u0648 \u0627\u0633\u062A\u0639\u0644\u0627\u0645 \u0648\u0633\u0627\u0626\u0637 \u0623\u0648 \u0633\u0645\u0629 (theme) \u0623\u0648 \u0639\u0644\u0627\u0645\u0629 \u0645\u064A\u0632\u0629 \u064A\u064F\u0646\u0641\u064E\u0651\u0630 \u0623\u062B\u0646\u0627\u0621 \u0623\u0648\u0644 \u0639\u0631\u0636."
182
+ ],
183
+ suggestion: "\u0627\u0639\u0631\u0636 \u0642\u064A\u0645\u0629 `className` \u0646\u0641\u0633\u0647\u0627 \u0639\u0644\u0649 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0641\u064A \u0623\u0648\u0644 \u0631\u0633\u0645 \u0639\u0644\u0649 \u0627\u0644\u0639\u0645\u064A\u0644. \u0627\u0646\u0642\u0644 \u0627\u0644\u0634\u0631\u0648\u0637 \u0627\u0644\u062E\u0627\u0635\u0629 \u0628\u0627\u0644\u0639\u0645\u064A\u0644 \u0625\u0644\u0649 `useEffect` \u0623\u0648 \u0639\u0644\u0627\u0645\u0629 \u062A\u0631\u0643\u064A\u0628\u060C \u0623\u0648 \u0646\u0641\u0651\u0630 \u0627\u0644\u062A\u063A\u064A\u064A\u0631 \u0627\u0644\u0628\u0635\u0631\u064A \u0628\u0627\u0633\u062A\u0639\u0644\u0627\u0645\u0627\u062A \u0627\u0644\u0648\u0633\u0627\u0626\u0637 \u0641\u064A CSS \u0628\u062F\u0644 \u062A\u0628\u062F\u064A\u0644 \u0627\u0644\u0641\u0626\u0629 \u0639\u0628\u0631 JavaScript."
184
+ },
185
+ "attribute-mismatch.style": {
186
+ explanation: "\u064A\u062E\u062A\u0644\u0641 `style` \u0627\u0644\u0645\u0636\u0645\u0651\u0646 \u0628\u064A\u0646 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644 \u2014 \u062D\u064F\u0633\u0628 \u0646\u0645\u0637 \u0645\u0636\u0645\u0651\u0646 \u0645\u0646 \u062D\u0627\u0644\u0629 \u062E\u0627\u0635\u0629 \u0628\u0627\u0644\u0639\u0645\u064A\u0644 (\u062D\u062C\u0645 \u0627\u0644\u0634\u0627\u0634\u0629 \u0623\u0648 \u0627\u0644\u0633\u0645\u0629 \u0623\u0648 \u0645\u0648\u0636\u0639 \u0627\u0644\u062A\u0645\u0631\u064A\u0631) \u0623\u062B\u0646\u0627\u0621 \u0627\u0644\u0639\u0631\u0636.",
187
+ suggestion: "\u0627\u062D\u0633\u0628 \u0627\u0644\u0646\u0645\u0637 \u0628\u0639\u062F \u0627\u0644\u062A\u0631\u0643\u064A\u0628 (`useEffect`) \u0644\u064A\u0637\u0627\u0628\u0642 \u0623\u0648\u0644 \u0639\u0631\u0636 \u0639\u0644\u0649 \u0627\u0644\u0639\u0645\u064A\u0644 \u0645\u0627 \u0639\u0631\u0636\u0647 \u0627\u0644\u062E\u0627\u062F\u0645\u060C \u0623\u0648 \u0627\u0646\u0642\u0644\u0647 \u0625\u0644\u0649 \u0641\u0626\u0629 CSS \u0623\u0648 \u0627\u0633\u062A\u0639\u0644\u0627\u0645 \u0648\u0633\u0627\u0626\u0637."
188
+ },
189
+ "attribute-mismatch.generic": {
190
+ explanation: "\u062A\u062E\u062A\u0644\u0641 \u0627\u0644\u0633\u0645\u0629 `{attribute}` \u0628\u064A\u0646 \u0627\u0644\u062E\u0627\u062F\u0645 (`{server}`) \u0648\u0627\u0644\u0639\u0645\u064A\u0644 (`{client}`) \u2014 \u0627\u0634\u062A\u064F\u0642\u0651\u062A \u0642\u064A\u0645\u062A\u0647\u0627 \u0645\u0646 \u0634\u064A\u0621 \u064A\u062E\u062A\u0644\u0641 \u0628\u064A\u0646 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0623\u0648\u0644 \u0639\u0631\u0636 \u0639\u0644\u0649 \u0627\u0644\u0639\u0645\u064A\u0644.",
191
+ suggestion: "\u0627\u062C\u0639\u0644 \u0642\u064A\u0645\u0629 \u0627\u0644\u0633\u0645\u0629 \u062D\u062A\u0645\u064A\u0629 \u0639\u0644\u0649 \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644\u060C \u0623\u0648 \u0639\u064A\u0651\u0646\u0647\u0627 \u0628\u0639\u062F \u0627\u0644\u062A\u0631\u0643\u064A\u0628 \u0644\u064A\u0637\u0627\u0628\u0642 \u0623\u0648\u0644 \u0639\u0631\u0636 \u0639\u0644\u0649 \u0627\u0644\u0639\u0645\u064A\u0644 HTML \u0627\u0644\u0642\u0627\u062F\u0645 \u0645\u0646 \u0627\u0644\u062E\u0627\u062F\u0645."
192
+ },
193
+ unknown: {
194
+ explanation: "\u0627\u0643\u062A\u064F\u0634\u0641 \u0639\u062F\u0645 \u062A\u0637\u0627\u0628\u0642 \u0641\u064A \u0627\u0644\u0640 Hydration \u0644\u0643\u0646 \u062A\u0639\u0630\u0651\u0631\u062A \u0645\u0637\u0627\u0628\u0642\u062A\u0647 \u0645\u0639 \u0633\u0628\u0628 \u0645\u0639\u0631\u0648\u0641. \u0627\u0641\u062D\u0635 \u0642\u064A\u0645\u062A\u064E\u064A \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644 \u0623\u0639\u0644\u0627\u0647.",
195
+ suggestion: "\u0642\u0627\u0631\u0646 \u0628\u064A\u0646 \u0642\u064A\u0645\u062A\u064E\u064A \u0627\u0644\u062E\u0627\u062F\u0645 \u0648\u0627\u0644\u0639\u0645\u064A\u0644. \u0645\u0646 \u0627\u0644\u0623\u0633\u0628\u0627\u0628 \u0627\u0644\u0634\u0627\u0626\u0639\u0629: \u0627\u0644\u0642\u064A\u0645 \u063A\u064A\u0631 \u0627\u0644\u062D\u062A\u0645\u064A\u0629\u060C \u0648\u0627\u0644\u062A\u0648\u0627\u0631\u064A\u062E \u0648\u0627\u0644\u0625\u0639\u062F\u0627\u062F\u0627\u062A \u0627\u0644\u0645\u062D\u0644\u064A\u0629\u060C \u0648\u0627\u0644\u0648\u0627\u062C\u0647\u0627\u062A \u0627\u0644\u062E\u0627\u0635\u0629 \u0628\u0627\u0644\u0645\u062A\u0635\u0641\u062D \u0627\u0644\u0645\u0633\u062A\u062E\u062F\u0645\u0629 \u0623\u062B\u0646\u0627\u0621 \u0627\u0644\u0639\u0631\u0636."
196
+ },
197
+ "unknown.no-location": {
198
+ explanation: "\u0623\u0628\u0644\u063A React \u0628\u0641\u0634\u0644 \u0627\u0644\u0640 Hydration \u062F\u0648\u0646 \u0623\u0646 \u064A\u062D\u062F\u062F \u0627\u0644\u0639\u0642\u062F\u0629 \u0627\u0644\u0645\u062E\u062A\u0644\u0641\u0629\u060C \u0648\u0644\u0645 \u064A\u062C\u062F \u0641\u062D\u0635 DOM \u0623\u064A \u0627\u062E\u062A\u0644\u0627\u0641 \u064A\u0645\u0643\u0646 \u0627\u0644\u0625\u0634\u0627\u0631\u0629 \u0625\u0644\u064A\u0647.",
199
+ suggestion: "\u062A\u0623\u0643\u062F \u0645\u0646 \u0648\u062C\u0648\u062F `<HydrationSnapshotScript>` (\u0623\u0648 \u0633\u0643\u0631\u0628\u062A \u0627\u0644\u0644\u0642\u0637\u0629 \u0627\u0644\u064A\u062F\u0648\u064A) \u062F\u0627\u062E\u0644 `<head>` \u0644\u064A\u062A\u0645\u0643\u0646 \u0641\u062D\u0635 DOM \u0645\u0646 \u062A\u062D\u062F\u064A\u062F \u0627\u0644\u0639\u0642\u062F\u0629\u060C \u0648\u0627\u0642\u0631\u0623 \u062A\u062D\u0630\u064A\u0631 React \u0627\u0644\u0643\u0627\u0645\u0644 \u0641\u064A \u0648\u062D\u062F\u0629 \u062A\u062D\u0643\u0645 \u0627\u0644\u0645\u062A\u0635\u0641\u062D."
200
+ }
201
+ };
202
+ var arPlural;
203
+ function arabicPlural(count) {
204
+ if (arPlural === void 0) {
205
+ arPlural = typeof Intl !== "undefined" && typeof Intl.PluralRules === "function" ? new Intl.PluralRules("ar") : null;
206
+ }
207
+ return arPlural?.select(count) ?? "other";
208
+ }
209
+ function arabicIssues(count) {
210
+ switch (arabicPlural(count)) {
211
+ case "zero":
212
+ return "\u0644\u0627 \u0645\u0634\u0643\u0644\u0627\u062A";
213
+ case "one":
214
+ return "\u0645\u0634\u0643\u0644\u0629 \u0648\u0627\u062D\u062F\u0629";
215
+ case "two":
216
+ return "\u0645\u0634\u0643\u0644\u062A\u0627\u0646";
217
+ case "few":
218
+ return `${count} \u0645\u0634\u0643\u0644\u0627\u062A`;
219
+ default:
220
+ return `${count} \u0645\u0634\u0643\u0644\u0629`;
221
+ }
222
+ }
223
+ var AR = {
224
+ dir: "rtl",
225
+ title: "\u0639\u062F\u0645 \u062A\u0637\u0627\u0628\u0642 \u0641\u064A \u0627\u0644\u0640 Hydration",
226
+ dialogLabel: "\u062A\u0634\u062E\u064A\u0635 \u0639\u062F\u0645 \u062A\u0637\u0627\u0628\u0642 \u0627\u0644\u0640 Hydration",
227
+ dismiss: "\u0625\u063A\u0644\u0627\u0642",
228
+ dismissLabel: "\u0625\u063A\u0644\u0627\u0642 \u0644\u0648\u062D\u0629 \u0627\u0644\u062A\u0634\u062E\u064A\u0635",
229
+ hintDismissLabel: "\u0625\u062E\u0641\u0627\u0621 \u0627\u0644\u062A\u0644\u0645\u064A\u062D",
230
+ server: "\u0627\u0644\u062E\u0627\u062F\u0645",
231
+ client: "\u0627\u0644\u0639\u0645\u064A\u0644",
232
+ fix: "\u0627\u0644\u062D\u0644:",
233
+ // The docs are only written in English, so say so rather than surprise.
234
+ learnMore: "\u0627\u0639\u0631\u0641 \u0627\u0644\u0645\u0632\u064A\u062F (\u0628\u0627\u0644\u0625\u0646\u062C\u0644\u064A\u0632\u064A\u0629) \u2190",
235
+ none: "(\u0644\u0627 \u0634\u064A\u0621)",
236
+ empty: "(\u0641\u0627\u0631\u063A)",
237
+ fallbackCategory: "\u0639\u062F\u0645 \u062A\u0637\u0627\u0628\u0642",
238
+ categories: {
239
+ "non-deterministic-value": "\u0642\u064A\u0645\u0629 \u063A\u064A\u0631 \u062D\u062A\u0645\u064A\u0629",
240
+ "date-time": "\u0627\u0644\u062A\u0627\u0631\u064A\u062E / \u0627\u0644\u0648\u0642\u062A",
241
+ "locale-format": "\u062A\u0646\u0633\u064A\u0642 \u0627\u0644\u0644\u063A\u0629 \u0648\u0627\u0644\u0645\u0646\u0637\u0642\u0629",
242
+ "browser-only-api": "\u0648\u0627\u062C\u0647\u0629 \u062E\u0627\u0635\u0629 \u0628\u0627\u0644\u0645\u062A\u0635\u0641\u062D",
243
+ "viewport-branching": "\u062A\u0641\u0631\u0651\u0639 \u062D\u0633\u0628 \u062D\u062C\u0645 \u0627\u0644\u0634\u0627\u0634\u0629",
244
+ "invalid-html-nesting": "\u062A\u062F\u0627\u062E\u0644 HTML \u063A\u064A\u0631 \u0635\u0627\u0644\u062D",
245
+ "whitespace-minification": "\u0627\u0644\u0645\u0633\u0627\u0641\u0627\u062A / \u0627\u0644\u062A\u0635\u063A\u064A\u0631",
246
+ "third-party-dom-mutation": "\u062A\u0639\u062F\u064A\u0644 DOM \u0645\u0646 \u0637\u0631\u0641 \u062E\u0627\u0631\u062C\u064A",
247
+ "attribute-mismatch": "\u0627\u062E\u062A\u0644\u0627\u0641 \u0641\u064A \u0627\u0644\u0633\u0645\u0629",
248
+ unknown: "\u063A\u064A\u0631 \u0645\u0639\u0631\u0648\u0641"
249
+ },
250
+ messages: AR_MESSAGES,
251
+ hint: (count) => `\u2193 ${arabicIssues(count)} \u2014 \u0645\u0631\u0651\u0631 \u0644\u0631\u0624\u064A\u0629 \u0627\u0644\u0643\u0644`
252
+ };
253
+ var OVERLAY_STRINGS = {
254
+ en: EN,
255
+ ar: AR
256
+ };
257
+ var ARABIC_LANG = /^(?:ar|arb|arz|ary|arq|aeb|apc|ajp|acm|afb|ars|acw|ayl|apd)(?:-|$)/i;
258
+ function resolveLocale(preference) {
259
+ if (preference === "en" || preference === "ar") return preference;
260
+ if (preference != null && preference !== "auto") return "en";
261
+ if (typeof document === "undefined") return "en";
262
+ const lang = document.documentElement.getAttribute("lang") ?? "";
263
+ return ARABIC_LANG.test(lang.trim()) ? "ar" : "en";
264
+ }
265
+
266
+ // src/react/overlay.ts
267
+ var CONTAINER_ID = "why-hydration-overlay";
268
+ var ARABIC_FACES = 'Tahoma, "Noto Sans Arabic", "Geeza Pro", "Segoe UI"';
269
+ var UI_FONT = `ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, ${ARABIC_FACES}, sans-serif`;
270
+ var MONO_FONT = "ui-monospace, SFMono-Regular, Menlo, Consolas, monospace";
271
+ var STYLES = `
272
+ :host {
273
+ all: initial;
274
+ /* The "all" shorthand deliberately excludes direction/unicode-bidi (CSS
275
+ spec), so these are set explicitly: the host page's own dir must never
276
+ leak in. The panel below then takes its direction from the overlay's
277
+ language, set inside this shadow root where no page style can reach it. */
278
+ direction: ltr;
279
+ unicode-bidi: isolate;
280
+ }
281
+ * { box-sizing: border-box; }
282
+ .wh-panel {
283
+ position: fixed;
284
+ z-index: 2147483647;
285
+ width: min(420px, calc(100vw - 32px));
286
+ max-height: min(70vh, 640px);
287
+ display: flex;
288
+ flex-direction: column;
289
+ font: 13px/1.5 ${UI_FONT};
290
+ color: #e5e7eb;
291
+ background: #0b0f17;
292
+ border: 1px solid #1f2937;
293
+ border-radius: 12px;
294
+ box-shadow: 0 12px 40px rgba(0,0,0,.5);
295
+ overflow: hidden;
296
+ text-align: start;
297
+ }
298
+ .wh-panel[dir="ltr"] { direction: ltr; }
299
+ /* Arabic reads poorly at Latin sizes, and letter-spacing or uppercasing breaks
300
+ the joining between its letters, so the right-to-left panel resets both. */
301
+ .wh-panel[dir="rtl"] { direction: rtl; font-size: 14px; line-height: 1.7; }
302
+ .wh-panel[dir="rtl"] .wh-side .wh-label { text-transform: none; letter-spacing: 0; font-size: 11px; }
303
+ .wh-bottom-right { bottom: 16px; right: 16px; }
304
+ .wh-bottom-left { bottom: 16px; left: 16px; }
305
+ .wh-top-right { top: 16px; right: 16px; }
306
+ .wh-top-left { top: 16px; left: 16px; }
307
+ .wh-header {
308
+ display: flex; align-items: center; gap: 8px;
309
+ padding: 10px 12px;
310
+ background: linear-gradient(180deg, #151b26, #0d1220);
311
+ border-bottom: 1px solid #1f2937;
312
+ }
313
+ .wh-dot { width: 8px; height: 8px; border-radius: 50%; background: #f59e0b; flex: none; }
314
+ .wh-title { font-weight: 600; color: #f3f4f6; }
315
+ .wh-count {
316
+ margin-inline-start: auto; font-size: 11px; color: #9ca3af;
317
+ background: #111827; border: 1px solid #1f2937; border-radius: 999px;
318
+ padding: 1px 8px;
319
+ }
320
+ .wh-btn {
321
+ appearance: none; border: 1px solid #1f2937; background: #111827;
322
+ color: #9ca3af; border-radius: 6px; cursor: pointer;
323
+ font: inherit; font-size: 12px; padding: 3px 8px;
324
+ }
325
+ .wh-btn:hover { color: #f3f4f6; border-color: #374151; }
326
+ .wh-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px; display: flex; flex-direction: column; gap: 8px; }
327
+ .wh-card { flex: 0 0 auto; border: 1px solid #1f2937; border-radius: 10px; background: #0f1521; overflow: hidden; }
328
+ .wh-card-head { display: flex; align-items: center; gap: 8px; padding: 8px 10px; }
329
+ .wh-cat { font-weight: 600; color: #fbbf24; font-size: 12px; }
330
+ .wh-conf { margin-inline-start: auto; font-size: 11px; color: #6b7280; unicode-bidi: isolate; }
331
+ .wh-body { padding: 0 10px 10px; }
332
+ .wh-where { font-size: 11px; color: #9ca3af; overflow-wrap: anywhere; margin-bottom: 4px; }
333
+ /* Selectors, component names, file paths and attribute names are code: they
334
+ stay left-to-right and isolated, or an RTL line mirrors their brackets and
335
+ reorders their segments. */
336
+ .wh-where code, .wh-comp, .wh-attr { unicode-bidi: isolate; font-family: ${MONO_FONT}; }
337
+ .wh-where code { color: #93c5fd; }
338
+ .wh-comp { color: #f3f4f6; font-weight: 600; }
339
+ .wh-attr { color: #c4b5fd; }
340
+ .wh-loc { font-size: 11px; color: #7dd3fc; overflow-wrap: anywhere; margin-bottom: 8px; font-family: ${MONO_FONT}; unicode-bidi: isolate; text-align: start; }
341
+ .wh-diff { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; margin-bottom: 8px; }
342
+ .wh-side { border-radius: 8px; padding: 6px 8px; font-size: 11px; min-width: 0; }
343
+ .wh-server { background: rgba(244,63,94,.08); border: 1px solid rgba(244,63,94,.35); }
344
+ .wh-client { background: rgba(34,197,94,.08); border: 1px solid rgba(34,197,94,.35); }
345
+ .wh-side .wh-label { display: block; font-size: 9px; text-transform: uppercase; letter-spacing: .04em; margin-bottom: 3px; }
346
+ .wh-server .wh-label { color: #fb7185; }
347
+ .wh-client .wh-label { color: #4ade80; }
348
+ /* A value is page data in any script. Each line takes its direction from its
349
+ own first strong character, so Arabic values read right-to-left with their
350
+ punctuation at the end even inside the English panel, and English values
351
+ stay left-to-right inside the Arabic one. Whitespace is preserved: a diff
352
+ viewer that collapses spaces hides whitespace-only mismatches. */
353
+ .wh-value {
354
+ display: block; unicode-bidi: plaintext; text-align: start;
355
+ white-space: pre-wrap; overflow-wrap: anywhere;
356
+ font-family: ${MONO_FONT};
357
+ }
358
+ .wh-value.wh-prose { font-family: ${UI_FONT}; font-size: 12px; }
359
+ .wh-empty-value { color: #6b7280; font-style: italic; font-family: ${UI_FONT}; }
360
+ .wh-invisible {
361
+ display: inline-block; margin: 0 1px; padding: 0 3px; border-radius: 3px;
362
+ font: 600 8px/1.6 ${MONO_FONT}; letter-spacing: .02em; vertical-align: 1px;
363
+ color: #fde68a; background: rgba(245,158,11,.18); border: 1px solid rgba(245,158,11,.45);
364
+ unicode-bidi: isolate; direction: ltr;
365
+ }
366
+ .wh-explain { color: #cbd5e1; margin-bottom: 8px; }
367
+ .wh-fix { color: #e5e7eb; background: #111827; border-inline-start: 3px solid #22c55e; border-radius: 4px; padding: 6px 8px; }
368
+ .wh-fix strong { color: #86efac; }
369
+ .wh-code {
370
+ font-family: ${MONO_FONT}; font-size: .92em; color: #e2e8f0;
371
+ background: rgba(148,163,184,.14); border-radius: 4px; padding: 0 3px;
372
+ unicode-bidi: isolate; overflow-wrap: anywhere;
373
+ }
374
+ .wh-param { unicode-bidi: isolate; color: #f8fafc; }
375
+ .wh-docs { display: inline-block; margin-top: 6px; color: #60a5fa; text-decoration: none; font-size: 11px; }
376
+ .wh-docs:hover { text-decoration: underline; }
377
+ .wh-hint {
378
+ display: none; align-items: center; gap: 8px;
379
+ padding: 7px 12px; font-size: 11px; color: #cbd5e1;
380
+ background: #0d1220; border-top: 1px solid #1f2937;
381
+ animation: wh-fade .2s ease;
382
+ }
383
+ .wh-hint.wh-show { display: flex; }
384
+ .wh-hint-text { flex: 1; }
385
+ .wh-hint-x {
386
+ appearance: none; border: 0; background: transparent; cursor: pointer;
387
+ color: #9ca3af; font-size: 14px; line-height: 1; padding: 2px 4px;
388
+ }
389
+ .wh-hint-x:hover { color: #f3f4f6; }
390
+ @keyframes wh-fade { from { opacity: 0 } to { opacity: 1 } }
391
+ @media (max-width: 420px) {
392
+ .wh-panel { width: auto; max-height: min(80vh, 640px); }
393
+ .wh-bottom-right, .wh-bottom-left { left: 8px; right: 8px; }
394
+ .wh-top-right, .wh-top-left { left: 8px; right: 8px; }
395
+ .wh-diff { grid-template-columns: 1fr; }
396
+ }
397
+ `;
398
+ function el(tag, className, text) {
399
+ const node = document.createElement(tag);
400
+ if (className) node.className = className;
401
+ if (text != null) node.textContent = text;
402
+ return node;
403
+ }
404
+ function shortenPath(file) {
405
+ const normalized = file.replace(/\\/g, "/");
406
+ const marker = normalized.match(/(?:^|\/)(?:src|app|pages|components)\//);
407
+ if (marker && marker.index != null) {
408
+ return normalized.slice(marker.index).replace(/^\//, "");
409
+ }
410
+ const parts = normalized.split("/");
411
+ return parts.slice(-2).join("/");
412
+ }
413
+ var INVISIBLE = {
414
+ "\u200B": "ZWSP",
415
+ "\u200E": "LRM",
416
+ "\u200F": "RLM",
417
+ "\u061C": "ALM",
418
+ "\u202A": "LRE",
419
+ "\u202B": "RLE",
420
+ "\u202C": "PDF",
421
+ "\u202D": "LRO",
422
+ "\u202E": "RLO",
423
+ "\u2066": "LRI",
424
+ "\u2067": "RLI",
425
+ "\u2068": "FSI",
426
+ "\u2069": "PDI",
427
+ "\uFEFF": "BOM"
428
+ };
429
+ var INVISIBLE_RE = /[\u200b\u200e\u200f\u061c\u202a-\u202e\u2066-\u2069\ufeff]/;
430
+ var INVISIBLE_SPLIT = /([\u200b\u200e\u200f\u061c\u202a-\u202e\u2066-\u2069\ufeff])/;
431
+ var RTL_SCRIPT = /[֐-ࣿיִ-﷿ﹰ-ﻼ]/;
432
+ function renderValue(value, strings) {
433
+ if (value == null || value === "") {
434
+ return el(
435
+ "span",
436
+ "wh-empty-value",
437
+ value === "" ? strings.empty : strings.none
438
+ );
439
+ }
440
+ const block = el("div", "wh-value");
441
+ block.dir = "auto";
442
+ if (RTL_SCRIPT.test(value)) block.classList.add("wh-prose");
443
+ if (!INVISIBLE_RE.test(value)) {
444
+ block.textContent = value;
445
+ return block;
446
+ }
447
+ for (const part of value.split(INVISIBLE_SPLIT)) {
448
+ if (!part) continue;
449
+ const name = INVISIBLE[part];
450
+ if (!name) {
451
+ block.append(part);
452
+ continue;
453
+ }
454
+ const badge = el("span", "wh-invisible", name);
455
+ const cp = part.codePointAt(0).toString(16).toUpperCase().padStart(4, "0");
456
+ badge.title = `U+${cp} ${name}`;
457
+ block.appendChild(badge);
458
+ }
459
+ return block;
460
+ }
461
+ function renderSegments(segments) {
462
+ const out = document.createDocumentFragment();
463
+ for (const s of segments) {
464
+ if (typeof s === "string") {
465
+ out.append(s);
466
+ } else if ("code" in s) {
467
+ const c = el("code", "wh-code", s.code);
468
+ c.dir = "auto";
469
+ out.appendChild(c);
470
+ } else {
471
+ const v = el("bdi", "wh-param", s.value);
472
+ out.appendChild(v);
473
+ }
474
+ }
475
+ return out;
476
+ }
477
+ function splitCode(text) {
478
+ return text.split("`").map((part, i) => i % 2 === 1 ? { code: part } : part).filter((s) => s !== "");
479
+ }
480
+ function causeText(cause, field, strings) {
481
+ const id = cause.messageId;
482
+ const params = cause.params ?? {};
483
+ if (id && Object.prototype.hasOwnProperty.call(EN_MESSAGES, id)) {
484
+ const english = plainText(renderMessage(EN_MESSAGES[id][field], params));
485
+ if (english === cause[field]) {
486
+ return {
487
+ segments: renderMessage(strings.messages[id][field], params),
488
+ translated: true
489
+ };
490
+ }
491
+ }
492
+ return { segments: splitCode(cause[field]), translated: false };
493
+ }
494
+ function renderCard(report, strings) {
495
+ const card = el("div", "wh-card");
496
+ const head = el("div", "wh-card-head");
497
+ head.appendChild(
498
+ el(
499
+ "span",
500
+ "wh-cat",
501
+ strings.categories[report.cause.category] ?? strings.fallbackCategory
502
+ )
503
+ );
504
+ const conf = el(
505
+ "span",
506
+ "wh-conf",
507
+ `${Math.round(report.cause.confidence * 100)}%`
508
+ );
509
+ conf.dir = "ltr";
510
+ head.appendChild(conf);
511
+ card.appendChild(head);
512
+ const body = el("div", "wh-body");
513
+ const where = el("div", "wh-where");
514
+ const name = report.component ?? report.node.tagName?.toLowerCase();
515
+ if (name) {
516
+ const comp = el(
517
+ "bdi",
518
+ report.component ? "wh-comp" : "wh-attr",
519
+ `<${name}>`
520
+ );
521
+ comp.dir = "ltr";
522
+ where.append(comp, " \xB7 ");
523
+ }
524
+ const path = el("code", void 0, report.node.path);
525
+ path.dir = "ltr";
526
+ where.appendChild(path);
527
+ if (report.node.attribute) {
528
+ const attr = el("bdi", "wh-attr", `@${report.node.attribute}`);
529
+ attr.dir = "ltr";
530
+ where.append(" \xB7 ", attr);
531
+ }
532
+ body.appendChild(where);
533
+ if (report.location?.file) {
534
+ const file = shortenPath(report.location.file);
535
+ const loc = el(
536
+ "div",
537
+ "wh-loc",
538
+ report.location.line ? `${file}:${report.location.line}` : file
539
+ );
540
+ loc.dir = "ltr";
541
+ body.appendChild(loc);
542
+ }
543
+ const diff = el("div", "wh-diff");
544
+ const server = el("div", "wh-side wh-server");
545
+ server.appendChild(el("span", "wh-label", strings.server));
546
+ server.appendChild(renderValue(report.server, strings));
547
+ const client = el("div", "wh-side wh-client");
548
+ client.appendChild(el("span", "wh-label", strings.client));
549
+ client.appendChild(renderValue(report.client, strings));
550
+ diff.appendChild(server);
551
+ diff.appendChild(client);
552
+ body.appendChild(diff);
553
+ const explanation = causeText(report.cause, "explanation", strings);
554
+ const explain = el("div", "wh-explain");
555
+ explain.dir = explanation.translated ? strings.dir : "auto";
556
+ explain.appendChild(renderSegments(explanation.segments));
557
+ body.appendChild(explain);
558
+ const suggestion = causeText(report.cause, "suggestion", strings);
559
+ const fix = el("div", "wh-fix");
560
+ fix.appendChild(el("strong", void 0, strings.fix));
561
+ fix.append(" ");
562
+ const fixText = el("span");
563
+ fixText.dir = suggestion.translated ? strings.dir : "auto";
564
+ fixText.appendChild(renderSegments(suggestion.segments));
565
+ fix.appendChild(fixText);
566
+ body.appendChild(fix);
567
+ if (report.cause.docsUrl && /^https?:\/\//i.test(report.cause.docsUrl)) {
568
+ const a = el("a", "wh-docs", strings.learnMore);
569
+ a.href = report.cause.docsUrl;
570
+ a.target = "_blank";
571
+ a.rel = "noreferrer noopener";
572
+ body.appendChild(a);
573
+ }
574
+ card.appendChild(body);
575
+ return card;
576
+ }
577
+ function createOverlay(options = {}) {
578
+ const position = options.position ?? "bottom-right";
579
+ let host = null;
580
+ let listEl = null;
581
+ let countEl = null;
582
+ let hintEl = null;
583
+ let hintTextEl = null;
584
+ let hintCheckTimer = null;
585
+ let hintDismissed = false;
586
+ let count = 0;
587
+ let strings = OVERLAY_STRINGS.en;
588
+ function ensureMounted() {
589
+ if (host) return;
590
+ document.getElementById(CONTAINER_ID)?.remove();
591
+ const locale = resolveLocale(options.locale);
592
+ strings = OVERLAY_STRINGS[locale];
593
+ host = document.createElement("div");
594
+ host.id = CONTAINER_ID;
595
+ host.setAttribute("data-why-hydration", "overlay");
596
+ host.setAttribute("aria-hidden", "false");
597
+ host.setAttribute("dir", strings.dir);
598
+ host.setAttribute("lang", locale);
599
+ const shadow = host.attachShadow({ mode: "open" });
600
+ const style = document.createElement("style");
601
+ style.textContent = STYLES;
602
+ shadow.appendChild(style);
603
+ const panel = el("div", `wh-panel wh-${position}`);
604
+ panel.setAttribute("dir", strings.dir);
605
+ panel.setAttribute("lang", locale);
606
+ panel.setAttribute("role", "dialog");
607
+ panel.setAttribute("aria-label", strings.dialogLabel);
608
+ const header = el("div", "wh-header");
609
+ header.appendChild(el("span", "wh-dot"));
610
+ header.appendChild(el("span", "wh-title", strings.title));
611
+ countEl = el("span", "wh-count", "0");
612
+ countEl.dir = "ltr";
613
+ header.appendChild(countEl);
614
+ const close = el("button", "wh-btn", strings.dismiss);
615
+ close.setAttribute("aria-label", strings.dismissLabel);
616
+ close.addEventListener("click", () => destroy());
617
+ header.appendChild(close);
618
+ panel.appendChild(header);
619
+ listEl = el("div", "wh-list");
620
+ panel.appendChild(listEl);
621
+ hintEl = el("div", "wh-hint");
622
+ hintTextEl = el("span", "wh-hint-text");
623
+ hintEl.appendChild(hintTextEl);
624
+ const hintX = el("button", "wh-hint-x", "\u2715");
625
+ hintX.setAttribute("aria-label", strings.hintDismissLabel);
626
+ hintX.addEventListener("click", () => dismissHint());
627
+ hintEl.appendChild(hintX);
628
+ panel.appendChild(hintEl);
629
+ shadow.appendChild(panel);
630
+ document.body.appendChild(host);
631
+ host.addEventListener("keydown", (e) => {
632
+ if (e.key === "Escape") destroy();
633
+ });
634
+ }
635
+ function dismissHint() {
636
+ hintDismissed = true;
637
+ hintEl?.classList.remove("wh-show");
638
+ }
639
+ function updateHint() {
640
+ if (!hintEl || !hintTextEl || hintDismissed) return;
641
+ hintTextEl.textContent = strings.hint(count);
642
+ if (count >= 4) hintEl.classList.add("wh-show");
643
+ }
644
+ function destroy() {
645
+ if (hintCheckTimer) clearTimeout(hintCheckTimer);
646
+ hintCheckTimer = null;
647
+ host?.remove();
648
+ host = null;
649
+ listEl = null;
650
+ countEl = null;
651
+ hintEl = null;
652
+ hintTextEl = null;
653
+ count = 0;
654
+ hintDismissed = false;
655
+ }
656
+ function push(report) {
657
+ ensureMounted();
658
+ count += 1;
659
+ if (countEl) countEl.textContent = String(count);
660
+ listEl?.appendChild(renderCard(report, strings));
661
+ if (hintCheckTimer) clearTimeout(hintCheckTimer);
662
+ hintCheckTimer = setTimeout(updateHint, 400);
663
+ }
664
+ return { push, destroy };
665
+ }
666
+
667
+ // src/react/fiber.ts
668
+ function getFiber(node) {
669
+ for (const key in node) {
670
+ if (key.startsWith("__reactFiber$") || key.startsWith("__reactInternalInstance$")) {
671
+ return node[key] ?? null;
672
+ }
673
+ }
674
+ return null;
675
+ }
676
+ function componentName(type) {
677
+ if (!type || typeof type === "string") return void 0;
678
+ if (typeof type === "function") {
679
+ const fn = type;
680
+ return fn.displayName || fn.name || void 0;
681
+ }
682
+ if (typeof type === "object") {
683
+ const obj = type;
684
+ if (obj.displayName) return obj.displayName;
685
+ if (obj.render) return obj.render.displayName || obj.render.name;
686
+ if (obj.type) return componentName(obj.type);
687
+ }
688
+ return void 0;
689
+ }
690
+ function resolveReactSource(node) {
691
+ if (!node) return {};
692
+ try {
693
+ let fiber = getFiber(node);
694
+ let component;
695
+ let location;
696
+ let hops = 0;
697
+ while (fiber && hops < 80) {
698
+ if (!component) {
699
+ const name = componentName(fiber.type);
700
+ if (name && !/^[a-z]/.test(name)) component = name;
701
+ }
702
+ if (!location && fiber._debugSource?.fileName) {
703
+ location = {
704
+ file: fiber._debugSource.fileName,
705
+ line: fiber._debugSource.lineNumber,
706
+ column: fiber._debugSource.columnNumber
707
+ };
708
+ }
709
+ if (component && location) break;
710
+ fiber = fiber.return ?? null;
711
+ hops += 1;
712
+ }
713
+ const result = {};
714
+ if (component) result.component = component;
715
+ if (location) result.location = location;
716
+ return result;
717
+ } catch {
718
+ return {};
719
+ }
720
+ }
721
+
722
+ // src/react/controller.ts
723
+ var INSPECT_FALLBACK_MS = 50;
724
+ function buildIgnore(ignore) {
725
+ if (!ignore || ignore.length === 0) return void 0;
726
+ return (divergence) => {
727
+ const node = divergence.element ?? null;
728
+ for (const rule of ignore) {
729
+ if (typeof rule === "function") {
730
+ if (node && rule(node)) return true;
731
+ } else if (node) {
732
+ try {
733
+ if (node.matches(rule) || node.closest(rule)) return true;
734
+ } catch {
735
+ }
736
+ }
737
+ }
738
+ return false;
739
+ };
740
+ }
741
+ var InspectorController = class {
742
+ constructor(options = {}) {
743
+ this.cleanups = [];
744
+ this.started = false;
745
+ this.pendingContext = {};
746
+ this.messages = /* @__PURE__ */ new Set();
747
+ this.warnedRoots = /* @__PURE__ */ new Set();
748
+ this.settlingTimers = [];
749
+ this.inspectScheduled = false;
750
+ this.inspectTimer = null;
751
+ this.onRecoverableError = (error, info) => {
752
+ if (!isDev) return;
753
+ const message = error instanceof Error ? error.message : String(error);
754
+ this.rememberMessage(message);
755
+ this.mergeContext({
756
+ componentStack: info?.componentStack,
757
+ component: firstComponentFromStack(info?.componentStack),
758
+ reactMessage: message
759
+ });
760
+ this.scheduleInspect();
761
+ };
762
+ this.options = options;
763
+ this.collector = new ReportCollector({
764
+ maxReports: options.maxReports,
765
+ extra: options.classify,
766
+ ignore: buildIgnore(options?.ignore)
767
+ });
768
+ }
769
+ start() {
770
+ if (this.started || !isDev || typeof window === "undefined") return;
771
+ this.started = true;
772
+ if (this.options.onReport) {
773
+ this.cleanups.push(this.collector.addSink(this.options.onReport));
774
+ }
775
+ this.cleanups.push(this.collector.addSink(createConsoleReporter()));
776
+ if (this.options.overlay !== false) {
777
+ const overlayOpts = typeof this.options.overlay === "object" ? this.options.overlay : {};
778
+ const handle = createOverlay(overlayOpts);
779
+ this.cleanups.push(
780
+ this.collector.addSink(handle.push, { replay: true }),
781
+ () => handle.destroy()
782
+ );
783
+ }
784
+ this.cleanups.push(
785
+ subscribeCapture((message) => {
786
+ this.rememberMessage(message);
787
+ this.mergeContext({ reactMessage: message });
788
+ this.scheduleInspect();
789
+ })
790
+ );
791
+ this.scheduleSettlingInspections();
792
+ }
793
+ // React applies client values to mismatched subtrees via a client re-render a
794
+ // few hundred ms after the initial hydration commit. We diff once per frame
795
+ // and then across this short "settling window" to catch that, deduped. This
796
+ // is a bounded, one-shot window — NOT a standing observer — so DOM changes
797
+ // from later app state are never mistaken for hydration mismatches.
798
+ scheduleSettlingInspections() {
799
+ this.scheduleInspect();
800
+ for (const delay of [80, 250, 700, 1500]) {
801
+ const timer = setTimeout(() => this.inspectAllRoots(), delay);
802
+ this.settlingTimers.push(timer);
803
+ }
804
+ }
805
+ rememberMessage(message) {
806
+ if (this.messages.size >= MAX_CAPTURED && !this.messages.has(message)) {
807
+ return;
808
+ }
809
+ this.messages.add(message);
810
+ }
811
+ mergeContext(ctx) {
812
+ this.pendingContext = {
813
+ componentStack: ctx.componentStack ?? this.pendingContext.componentStack,
814
+ component: ctx.component ?? this.pendingContext.component,
815
+ location: ctx.location ?? this.pendingContext.location,
816
+ reactMessage: ctx.reactMessage ?? this.pendingContext.reactMessage
817
+ };
818
+ }
819
+ domContext() {
820
+ return {
821
+ componentStack: this.pendingContext.componentStack,
822
+ component: this.pendingContext.component,
823
+ location: this.pendingContext.location
824
+ };
825
+ }
826
+ stop() {
827
+ for (const timer of this.settlingTimers.splice(0)) clearTimeout(timer);
828
+ this.clearScheduledInspect();
829
+ for (const cleanup of this.cleanups.splice(0)) cleanup();
830
+ this.started = false;
831
+ }
832
+ getReports() {
833
+ return this.collector.getReports();
834
+ }
835
+ inspectNow(context = {}) {
836
+ this.mergeContext(context);
837
+ this.inspectAllRoots();
838
+ }
839
+ inspectAllRoots() {
840
+ if (!this.started || typeof document === "undefined" || this.collector.isFull) {
841
+ return;
842
+ }
843
+ const configured = this.options.roots;
844
+ const selectors = configured ?? snapshotSelectors();
845
+ const context = this.domContext();
846
+ const seen = /* @__PURE__ */ new Set();
847
+ for (const selector of selectors) {
848
+ let root = null;
849
+ try {
850
+ root = document.querySelector(selector);
851
+ } catch {
852
+ this.warnRoot(selector, `"${selector}" is not a valid CSS selector.`);
853
+ continue;
854
+ }
855
+ if (!root || seen.has(root)) continue;
856
+ seen.add(root);
857
+ if (configured && getServerHtmlForRoot(root) == null) {
858
+ this.warnRoot(
859
+ selector,
860
+ `no server HTML was captured for "${selector}". Add it to the \`selectors\` prop of <HydrationSnapshotScript> so the server markup for that root is snapshotted.`
861
+ );
862
+ continue;
863
+ }
864
+ inspectRoot(
865
+ root,
866
+ this.collector,
867
+ context,
868
+ (divergence) => resolveReactSource(divergence.element ?? null)
869
+ );
870
+ }
871
+ for (const message of this.messages) {
872
+ reportFromMessage(message, this.collector, this.pendingContext, {
873
+ locationless: "skip"
874
+ });
875
+ }
876
+ const concrete = this.collector.getReports().some((r) => r.cause.messageId !== "unknown.no-location");
877
+ if (!concrete) {
878
+ for (const message of this.messages) {
879
+ reportFromMessage(message, this.collector, this.pendingContext, {
880
+ locationless: "only"
881
+ });
882
+ }
883
+ }
884
+ }
885
+ warnRoot(selector, detail) {
886
+ if (this.warnedRoots.has(selector)) return;
887
+ this.warnedRoots.add(selector);
888
+ console.warn(`[why-hydration] Skipping root: ${detail}`);
889
+ }
890
+ scheduleInspect() {
891
+ if (this.inspectScheduled) return;
892
+ this.inspectScheduled = true;
893
+ const run = () => {
894
+ if (!this.inspectScheduled) return;
895
+ this.clearScheduledInspect();
896
+ this.inspectAllRoots();
897
+ };
898
+ if (typeof requestAnimationFrame === "function") requestAnimationFrame(run);
899
+ this.inspectTimer = setTimeout(run, INSPECT_FALLBACK_MS);
900
+ }
901
+ clearScheduledInspect() {
902
+ this.inspectScheduled = false;
903
+ if (this.inspectTimer != null) {
904
+ clearTimeout(this.inspectTimer);
905
+ this.inspectTimer = null;
906
+ }
907
+ }
908
+ };
909
+ function snapshotSelectors() {
910
+ const snapshot = readSnapshot();
911
+ const keys = snapshot ? Object.keys(snapshot.roots) : [];
912
+ return keys.length > 0 ? keys : [...DEFAULT_SNAPSHOT_SELECTORS];
913
+ }
914
+ function firstComponentFromStack(stack) {
915
+ if (!stack) return void 0;
916
+ const frame = /(?:^|\n)\s*(?:at|in)\s+([A-Za-z0-9_$]+)/g;
917
+ for (const match of stack.matchAll(frame)) {
918
+ const name = match[1];
919
+ if (/^[A-Z]/.test(name) && !isInternalComponent(name)) return name;
920
+ }
921
+ return void 0;
922
+ }
923
+ function InspectorImpl(props) {
924
+ const { children, overlay, onReport, ignore, classify, maxReports } = props;
925
+ startCapture();
926
+ const optionsRef = React2.useRef({});
927
+ optionsRef.current = { overlay, onReport, ignore, classify, maxReports };
928
+ React2.useEffect(() => {
929
+ const controller = new InspectorController(optionsRef.current);
930
+ controller.start();
931
+ return () => controller.stop();
932
+ }, []);
933
+ return React2.createElement(React2.Fragment, null, children);
934
+ }
935
+
936
+ // src/react/index.tsx
937
+ function PassThrough(props) {
938
+ return React2.createElement(React2.Fragment, null, props.children);
939
+ }
940
+ var HydrationInspector = process.env.NODE_ENV !== "production" ? InspectorImpl : PassThrough;
941
+ function createHydrationInspector(options = {}) {
942
+ if (process.env.NODE_ENV === "production") {
943
+ return {
944
+ onRecoverableError: () => {
945
+ },
946
+ Provider: PassThrough
947
+ };
948
+ }
949
+ const controller = new InspectorController(options);
950
+ controller.start();
951
+ function Provider(props) {
952
+ React2.useEffect(() => {
953
+ controller.start();
954
+ return () => controller.stop();
955
+ }, []);
956
+ return React2.createElement(React2.Fragment, null, props.children);
957
+ }
958
+ return {
959
+ onRecoverableError: controller.onRecoverableError,
960
+ Provider
961
+ };
962
+ }
963
+
964
+ export { HydrationInspector, createHydrationInspector };
965
+ //# sourceMappingURL=chunk-MK3TYHKM.js.map
966
+ //# sourceMappingURL=chunk-MK3TYHKM.js.map