@ai-matrx/chat 0.4.9 → 0.4.12

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 (123) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/agents/components/context-items/bodies/ContextInputBody.js +1 -1
  3. package/dist/agents/components/context-items/bodies/GenericBody.js +1 -1
  4. package/dist/agents/components/conversation-actions/conversation-verbs.js +1 -1
  5. package/dist/agents/components/inputs/smart-input/RunSkillPicker.js +1 -1
  6. package/dist/agents/components/live-run/LiveRunDisplay.js +1 -1
  7. package/dist/agents/components/live-run/LiveRunProgress.js +1 -1
  8. package/dist/agents/components/live-run/RunSetDisplay.js +1 -1
  9. package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.js +2 -2
  10. package/dist/agents/components/messages-display/assistant/InPlaceAnswerEditor.js +1 -1
  11. package/dist/agents/components/messages-display/conversation-tools/find-in-conversation.js +1 -1
  12. package/dist/agents/components/messages-display/message-options/buildTaskSeedFromMessage.js +1 -1
  13. package/dist/agents/components/messages-display/user/AgentUserMessage.js +1 -1
  14. package/dist/agents/components/messages-display/user/FirstTurnVariables.js +1 -1
  15. package/dist/agents/components/run/AgentStatusIndicator.js +1 -1
  16. package/dist/agents/components/run/RunJobWorkingLine.js +1 -1
  17. package/dist/agents/components/shared/AgentNewRunButton.js +1 -1
  18. package/dist/agents/components/shared/AgentPlanningIndicator.js +1 -1
  19. package/dist/agents/conversation-export/conversation-transfer.js +1 -1
  20. package/dist/agents/conversation-export/document-markdown.js +1 -1
  21. package/dist/agents/hooks/useConversationRoutePromotion.js +1 -1
  22. package/dist/agents/hooks/useModelControls.js +1 -1
  23. package/dist/agents/redux/agent-definition/converters.js +1 -1
  24. package/dist/agents/redux/agent-definition/slice.js +1 -1
  25. package/dist/agents/redux/conversation-list/conversation-list.thunks.js +1 -1
  26. package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.js +1 -1
  27. package/dist/agents/redux/execution-system/instance-context/sync-canvas-item-context.thunk.js +1 -1
  28. package/dist/agents/redux/execution-system/thunks/process-stream.js +1 -1
  29. package/dist/agents/redux/execution-system/thunks/resolve-base-url.js +17 -0
  30. package/dist/agents/redux/execution-system/thunks/run-ai-stream.d.ts +7 -0
  31. package/dist/agents/redux/execution-system/thunks/run-ai-stream.js +13 -0
  32. package/dist/agents/redux/execution-system/thunks/run-headless-agent-json.js +14 -2
  33. package/dist/agents/redux/execution-system/utils/assemble-cx-content-blocks.js +1 -1
  34. package/dist/agents/redux/execution-system/utils/normalize-content-blocks.js +1 -1
  35. package/dist/agents/redux/execution-system/utils/output-contract-guard.js +1 -1
  36. package/dist/agents/redux/execution-system/utils/stream-block-accumulator.js +8 -8
  37. package/dist/agents/routing/confidential-routing.d.ts +52 -0
  38. package/dist/agents/routing/confidential-routing.js +38 -0
  39. package/dist/agents/utils/canvasItemContext.js +1 -1
  40. package/dist/canvas/workspace/ChatPanelTitleMenu.js +1 -1
  41. package/dist/canvas/workspace/useCanvasWorkspaceConversation.js +1 -1
  42. package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
  43. package/dist/cx-chat/components/core/ChatConversationClient.js +1 -1
  44. package/dist/cx-chat/components/messages/AssistantMessage.js +1 -1
  45. package/dist/cx-chat/hooks/useInstanceBootstrap.js +1 -1
  46. package/dist/cx-conversation/AssistantMessage.js +1 -1
  47. package/dist/host/configure.js +4 -1
  48. package/dist/host/contract.d.ts +14 -1
  49. package/dist/host/index.d.ts +1 -0
  50. package/dist/host/index.js +1 -0
  51. package/dist/mandates/llm-params.d.ts +1 -1
  52. package/dist/mandates/output-contract.js +1 -1
  53. package/dist/mandates/service.d.ts +1 -1
  54. package/dist/mandates/service.js +1 -1
  55. package/dist/mandates/test-run-core.js +1 -1
  56. package/dist/public-chat/components/PublicMessageOptionsMenu.js +1 -1
  57. package/dist/surfaces/services/surface-config.service.js +1 -1
  58. package/dist/tool-call-visualization/components/ToolCallBatch.js +1 -1
  59. package/dist/tool-call-visualization/components/ToolCallVisualization.js +1 -1
  60. package/dist/tool-call-visualization/renderers/agent-call/AgentCallInline.js +1 -1
  61. package/dist/tool-call-visualization/renderers/agent-call/CollabCallCard.js +1 -1
  62. package/dist/tool-call-visualization/renderers/agent-call/collab-subtitle.js +3 -3
  63. package/dist/tool-call-visualization/renderers/skill/SkillInline.js +1 -1
  64. package/dist/tool-call-visualization/result-fields/KeyValueGrid.js +1 -1
  65. package/dist/tool-call-visualization/result-fields/ResultValue.js +1 -1
  66. package/dist/tool-call-visualization/result-fields/shape.js +1 -1
  67. package/dist/tool-call-visualization/utils/cxToolCallToLifecycleEntry.js +2 -2
  68. package/dist/tool-call-visualization/utils/human-copy.js +3 -3
  69. package/dist/ui/mandates-storage/provision-shapes.d.ts +1 -1
  70. package/dist/ui/mandates-storage/provision-shapes.js +1 -1
  71. package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +1 -1
  72. package/dist/ui/treatment-shape.d.ts +1 -1
  73. package/dist/ui/treatment-shape.js +1 -1
  74. package/dist/voice-agent/relay/useVoiceRelaySession.js +1 -1
  75. package/package.json +26 -9
  76. package/dist/agents/hooks/useWarmAgent.d.ts +0 -8
  77. package/dist/agents/hooks/useWarmAgent.js +0 -25
  78. package/dist/agents/utils/artifactId.d.ts +0 -34
  79. package/dist/agents/utils/artifactId.js +0 -15
  80. package/dist/ui/ShimmerText.d.ts +0 -5
  81. package/dist/ui/ShimmerText.js +0 -21
  82. package/dist/ui/addressWithoutNavigating.d.ts +0 -68
  83. package/dist/ui/addressWithoutNavigating.js +0 -60
  84. package/dist/utils/content-ir/decision-answers-ids.d.ts +0 -3
  85. package/dist/utils/content-ir/decision-answers-ids.js +0 -6
  86. package/dist/utils/content-ir/envelope-parity.d.ts +0 -12
  87. package/dist/utils/content-ir/envelope-parity.js +0 -32
  88. package/dist/utils/content-ir/instance-title.d.ts +0 -26
  89. package/dist/utils/content-ir/instance-title.js +0 -39
  90. package/dist/utils/content-ir/kinds/kind-markdown-utils.d.ts +0 -84
  91. package/dist/utils/content-ir/kinds/kind-markdown-utils.js +0 -233
  92. package/dist/utils/content-ir/kinds/kind-value-markdown.d.ts +0 -5
  93. package/dist/utils/content-ir/kinds/kind-value-markdown.js +0 -17
  94. package/dist/utils/content-ir/legacy-quiz-envelope.d.ts +0 -3
  95. package/dist/utils/content-ir/legacy-quiz-envelope.js +0 -45
  96. package/dist/utils/content-ir/surfaces/embedded-kind-json.d.ts +0 -140
  97. package/dist/utils/content-ir/surfaces/embedded-kind-json.js +0 -527
  98. package/dist/utils/content-ir/surfaces/json-kind-signal.d.ts +0 -307
  99. package/dist/utils/content-ir/surfaces/json-kind-signal.js +0 -945
  100. package/dist/utils/content-ir/surfaces/kind-image-alt.d.ts +0 -27
  101. package/dist/utils/content-ir/surfaces/kind-image-alt.js +0 -117
  102. package/dist/utils/content-ir/surfaces/kind-one-line.d.ts +0 -67
  103. package/dist/utils/content-ir/surfaces/kind-one-line.js +0 -209
  104. package/dist/utils/content-ir/surfaces/kind-text-label.d.ts +0 -20
  105. package/dist/utils/content-ir/surfaces/kind-text-label.js +0 -50
  106. package/dist/utils/content-ir/surfaces/kind-text-to-markdown.d.ts +0 -47
  107. package/dist/utils/content-ir/surfaces/kind-text-to-markdown.js +0 -399
  108. package/dist/utils/content-ir/surfaces/markdown-escaped-kind.d.ts +0 -54
  109. package/dist/utils/content-ir/surfaces/markdown-escaped-kind.js +0 -128
  110. package/dist/utils/content-ir/surfaces/quoted-kind-lift.d.ts +0 -61
  111. package/dist/utils/content-ir/surfaces/quoted-kind-lift.js +0 -215
  112. package/dist/utils/inline-decision/decision-options.d.ts +0 -21
  113. package/dist/utils/inline-decision/decision-options.js +0 -32
  114. package/dist/utils/json.d.ts +0 -63
  115. package/dist/utils/json.js +0 -22
  116. package/dist/utils/markdown/plain-title.d.ts +0 -25
  117. package/dist/utils/markdown/plain-title.js +0 -51
  118. package/dist/utils/rendered-find.d.ts +0 -9
  119. package/dist/utils/rendered-find.js +0 -68
  120. package/dist/utils/rich-editor/core/caret-context.d.ts +0 -24
  121. package/dist/utils/rich-editor/core/caret-context.js +0 -73
  122. package/dist/utils/rich-editor/in-place/caret-handoff.d.ts +0 -3
  123. package/dist/utils/rich-editor/in-place/caret-handoff.js +0 -15
@@ -1,945 +0,0 @@
1
- import { fenceOpenerOf, findCodeRanges } from "@ai-matrx/content-ir/source";
2
- const UNDECIDED_LIMIT_CHARS = 2e3;
3
- const KIND_KEY_BODY = [..."__kind"].map((ch) => {
4
- const hex = ch.charCodeAt(0).toString(16).padStart(4, "0");
5
- const escaped = [...hex].map((d) => /[a-f]/.test(d) ? `[${d}${d.toUpperCase()}]` : d).join("");
6
- return `(?:${ch}|\\\\u${escaped})`;
7
- }).join("");
8
- const KIND_KEY = new RegExp(String.raw`(?<!\\)"${KIND_KEY_BODY}"\s*:`);
9
- const JSON5_KIND_KEY = /(?:^|[{,]\s*|\n\s*)(?:__kind|'__kind')\s*:/;
10
- const JSON5_KIND_SLUG = /(?:^|[{,]\s*|\n\s*)(?:__kind|'__kind'|"__kind")\s*:\s*("(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*')/;
11
- const MARKDOWN_KIND_KEY = /(?<!\\)"(?:\\_\\_|\\__|_\\_)kind"\s*:/;
12
- const ESCAPED_KIND_KEY = /\\+"__kind\\+"\s*:/;
13
- const ESCAPED_KIND_SLUG = /\\+"__kind\\+"\s*:\s*\\+"([A-Za-z0-9_.:-]+)\\+"/;
14
- const ALL_KIND_SPELLINGS = Object.freeze({
15
- markdown: true,
16
- escaped: true,
17
- python: true,
18
- smart: true,
19
- entity: true,
20
- js: true
21
- });
22
- const JSON_KIND_SPELLINGS = Object.freeze({ markdown: true });
23
- function hasJsonKindKey(source) {
24
- return hasKindKey(source, JSON_KIND_SPELLINGS);
25
- }
26
- function hasDetectionOnlyKindKey(source) {
27
- return !hasJsonKindKey(source) && (hasKindKey(source, ALL_KIND_SPELLINGS) || hasExoticKindKey(source));
28
- }
29
- const ZERO_WIDTH = /[\u200B-\u200D\u2060\uFEFF\u00AD]/g;
30
- const HAS_ZERO_WIDTH = /[\u200B-\u200D\u2060\uFEFF\u00AD]/;
31
- function withoutZeroWidth(text) {
32
- return HAS_ZERO_WIDTH.test(text) ? text.replace(ZERO_WIDTH, "") : text;
33
- }
34
- const PYTHON_KIND_KEY = /[{,]\s*'__kind'\s*:\s*['"]/;
35
- const PYTHON_KIND_SLUG = /[{,]\s*'__kind'\s*:\s*(?:'([A-Za-z0-9_.:-]+)'|"([A-Za-z0-9_.:-]+)")/;
36
- const SMART_DOUBLE = "\u201C\u201D\u201E\u201F\u2033";
37
- const SMART_SINGLE = "\u2018\u2019\u201A\u201B\u2032";
38
- const SMART_KIND_KEY = new RegExp(`[${SMART_DOUBLE}${SMART_SINGLE}]__kind[${SMART_DOUBLE}${SMART_SINGLE}"']\\s*:`);
39
- const ENTITY_QUOTE = "&(?:[qQ][uU][oO][tT]|[aA][pP][oO][sS]|#0*3[49]|#[xX]0*2[27]);";
40
- const ENTITY_KIND_KEY = new RegExp(`${ENTITY_QUOTE}__kind${ENTITY_QUOTE}\\s*:`);
41
- function isJson5Language(lang) {
42
- return (lang ?? "").trim().toLowerCase() === "json5";
43
- }
44
- function hasKindKey(source, options = {}) {
45
- const text = withoutZeroWidth(source);
46
- return KIND_KEY.test(text) || options.python === true && PYTHON_KIND_KEY.test(text) || options.json5 === true && JSON5_KIND_KEY.test(text) || options.markdown === true && MARKDOWN_KIND_KEY.test(text) || options.escaped === true && ESCAPED_KIND_KEY.test(text) || options.smart === true && SMART_KIND_KEY.test(text) || options.entity === true && ENTITY_KIND_KEY.test(text) || options.js === true && JS_KIND_KEY.test(text) || // Every realistic spelling COMBINED in one key (escaped + zero-width,
47
- // repr + zero-width, `"\__kind"`, `{\"\\_\\_kind\"…}` — L-1, round 9).
48
- options.escaped === true && options.python === true && options.smart === true && options.markdown === true && hasSpelledKey(source);
49
- }
50
- const JS_KIND_KEY = /[{,]\s*__kind\s*:\s*['"]/;
51
- function hasExoticKindKey(text) {
52
- if (!/kind|&#|&amp;|\uFF3F/i.test(text)) return false;
53
- let plain = text.replace(EXOTIC_INVISIBLE, "").replace(/\uFF02/g, '"').replace(/\uFF07/g, "'").replace(/\uFF3F/g, "_");
54
- for (let pass = 0; pass < 3 && plain.includes("&"); pass++) plain = plain.replace(LOOSE_ENTITY, looseEntity);
55
- return plain !== text && hasKindKey(plain, ALL_KIND_SPELLINGS);
56
- }
57
- const EXOTIC_INVISIBLE = /[\p{Cf}\u034F\u115F\u1160\u17B4\u17B5\u180E\u3164\uFFA0]/gu;
58
- const LOOSE_ENTITY = /&(#[xX][0-9a-fA-F]{1,8}|#\d{1,8}|[A-Za-z]{2,8});/g;
59
- const LOOSE_NAMED = { quot: '"', apos: "'", amp: "&", lt: "<", gt: ">", lowbar: "_" };
60
- function looseEntity(whole, body) {
61
- if (body.startsWith("#")) {
62
- const code = body[1] === "x" || body[1] === "X" ? Number.parseInt(body.slice(2), 16) : Number.parseInt(body.slice(1), 10);
63
- return Number.isFinite(code) && code > 0 && code < 1114112 ? String.fromCodePoint(code) : whole;
64
- }
65
- return LOOSE_NAMED[body.toLowerCase()] ?? whole;
66
- }
67
- function hasKindKeyAnySpelling(source) {
68
- return hasKindKey(source, ALL_KIND_SPELLINGS);
69
- }
70
- const KIND_SLUG = new RegExp(
71
- String.raw`(?<!\\)"${KIND_KEY_BODY}"\s*:\s*("(?:[^"\\]|\\.)*")`
72
- );
73
- const SLUG_TEXT = /^[A-Za-z0-9_.:-]+$/;
74
- function isKindSlug(value) {
75
- return typeof value === "string" && SLUG_TEXT.test(value);
76
- }
77
- function firstKindSlug(source, options = {}) {
78
- const text = withoutZeroWidth(source);
79
- let literal = KIND_SLUG.exec(text)?.[1];
80
- if (!literal && (options.json5 || options.js)) {
81
- const json5 = JSON5_KIND_SLUG.exec(text)?.[1];
82
- literal = json5?.startsWith("'") ? JSON.stringify(json5.slice(1, -1)) : json5;
83
- }
84
- if (!literal && options.escaped) {
85
- const escaped = ESCAPED_KIND_SLUG.exec(text)?.[1];
86
- if (escaped) return escaped;
87
- }
88
- if (!literal && options.python) {
89
- const python = PYTHON_KIND_SLUG.exec(text);
90
- if (python) return python[1] ?? python[2] ?? null;
91
- }
92
- if (!literal && (options.smart || options.entity || options.markdown)) {
93
- const canonical = normalizeKindSpellings(text);
94
- if (canonical !== text) return firstKindSlug(canonical, { ...options, smart: false, entity: false, markdown: false });
95
- }
96
- if (!literal) return null;
97
- let slug;
98
- try {
99
- slug = JSON.parse(literal);
100
- } catch {
101
- return null;
102
- }
103
- return typeof slug === "string" && SLUG_TEXT.test(slug) ? slug : null;
104
- }
105
- const PARTIAL_KIND_KEY_TAIL = /"__k(?:i(?:n(?:d(?:"\s*)?)?)?)?$/;
106
- function endsInPartialKindKey(text) {
107
- const tail = PARTIAL_KIND_KEY_TAIL.exec(text);
108
- if (!tail) return false;
109
- return isObjectKeyPosition(text, tail.index);
110
- }
111
- function isObjectKeyPosition(text, quoteAt) {
112
- const stack = [];
113
- let expectKey = false;
114
- let inString = false;
115
- let escaped = false;
116
- for (let i = 0; i < quoteAt; i++) {
117
- const ch = text[i];
118
- if (inString) {
119
- if (escaped) escaped = false;
120
- else if (ch === "\\") escaped = true;
121
- else if (ch === '"') inString = false;
122
- continue;
123
- }
124
- if (ch === '"') {
125
- inString = true;
126
- expectKey = false;
127
- } else if (ch === "{" || ch === "[") {
128
- stack.push(ch);
129
- expectKey = ch === "{";
130
- } else if (ch === "}" || ch === "]") {
131
- stack.pop();
132
- expectKey = false;
133
- } else if (ch === ",") {
134
- expectKey = stack[stack.length - 1] === "{";
135
- } else if (ch === ":") {
136
- expectKey = false;
137
- }
138
- }
139
- return !inString && expectKey;
140
- }
141
- function withoutLeadingJsonComments(text) {
142
- let i = 0;
143
- for (; ; ) {
144
- i = skipWs(text, i);
145
- if (text.startsWith("//", i)) {
146
- const end = text.indexOf("\n", i);
147
- if (end === -1) return "";
148
- i = end + 1;
149
- } else if (text.startsWith("/*", i)) {
150
- const end = text.indexOf("*/", i + 2);
151
- if (end === -1) return "";
152
- i = end + 2;
153
- } else {
154
- return i === 0 ? text : text.slice(i);
155
- }
156
- }
157
- }
158
- function jsonKindSignal(text, options = {}) {
159
- const source = withoutLeadingJsonComments(text ?? "");
160
- if (hasKindKey(source, options)) return "kind";
161
- let i = skipWs(source, 0);
162
- if (i >= source.length) return "undecided";
163
- if (source[i] === "[") {
164
- i = skipWs(source, i + 1);
165
- if (i >= source.length) return capped(source);
166
- if (source[i] !== "{") return notKindUnlessPartialKey(source);
167
- }
168
- if (source[i] !== "{") return notKindUnlessPartialKey(source);
169
- i = skipWs(source, i + 1);
170
- if (i >= source.length) return capped(source);
171
- if (source[i] !== '"') return notKindUnlessPartialKey(source);
172
- let j = i + 1;
173
- while (j < source.length) {
174
- const ch = source[j];
175
- if (ch === "\\") {
176
- j += 2;
177
- continue;
178
- }
179
- if (ch === '"') {
180
- return withoutZeroWidth(decodedKey(source.slice(i, j + 1))) === "__kind" ? "kind" : notKindUnlessPartialKey(source);
181
- }
182
- j++;
183
- }
184
- return capped(source);
185
- }
186
- function notKindUnlessPartialKey(source) {
187
- return endsInPartialKindKey(source) ? "undecided" : "not_kind";
188
- }
189
- function decodedKey(literal) {
190
- try {
191
- const key = JSON.parse(literal);
192
- return typeof key === "string" ? key : literal.slice(1, -1);
193
- } catch {
194
- return literal.slice(1, -1);
195
- }
196
- }
197
- function capped(source) {
198
- return source.length > UNDECIDED_LIMIT_CHARS ? "not_kind" : "undecided";
199
- }
200
- function skipWs(source, from) {
201
- let i = from;
202
- while (i < source.length && /\s/.test(source[i])) i++;
203
- return i;
204
- }
205
- function json5AsJson(text) {
206
- let out = "";
207
- let i = 0;
208
- while (i < text.length) {
209
- const ch = text[i];
210
- if (ch === '"' || ch === "'") {
211
- let j = i + 1;
212
- let body = "";
213
- while (j < text.length && text[j] !== ch) {
214
- if (text[j] === "\\") {
215
- body += text[j] + (text[j + 1] ?? "");
216
- j += 2;
217
- continue;
218
- }
219
- body += ch === "'" && text[j] === '"' ? '\\"' : text[j];
220
- j++;
221
- }
222
- out += `"${body}"`;
223
- i = j + 1;
224
- continue;
225
- }
226
- if (text.startsWith("//", i)) {
227
- const end = text.indexOf("\n", i);
228
- i = end === -1 ? text.length : end;
229
- continue;
230
- }
231
- if (text.startsWith("/*", i)) {
232
- const end = text.indexOf("*/", i + 2);
233
- i = end === -1 ? text.length : end + 2;
234
- continue;
235
- }
236
- const key = /^[A-Za-z_$][\w$]*(?=\s*:)/.exec(text.slice(i));
237
- if (key && /[{,]\s*$/.test(out)) {
238
- out += `"${key[0]}"`;
239
- i += key[0].length;
240
- continue;
241
- }
242
- out += ch;
243
- i++;
244
- }
245
- out = out.replace(/,(\s*[}\]])/g, "$1");
246
- try {
247
- JSON.parse(out);
248
- return out;
249
- } catch {
250
- return null;
251
- }
252
- }
253
- function pythonReprAsJson(text) {
254
- let out = "";
255
- let i = 0;
256
- while (i < text.length) {
257
- const ch = text[i];
258
- if (ch === "'" || ch === '"') {
259
- let j = i + 1;
260
- let body = "";
261
- while (j < text.length && text[j] !== ch) {
262
- if (text[j] === "\\") {
263
- const next = text[j + 1] ?? "";
264
- body += next === "'" ? "'" : `\\${next}`;
265
- j += 2;
266
- continue;
267
- }
268
- body += text[j] === '"' ? '\\"' : text[j];
269
- j++;
270
- }
271
- if (j >= text.length) return null;
272
- out += `"${body}"`;
273
- i = j + 1;
274
- continue;
275
- }
276
- const word = /^(?:True|False|None)\b/.exec(text.slice(i, i + 5));
277
- if (word) {
278
- out += word[0] === "True" ? "true" : word[0] === "False" ? "false" : "null";
279
- i += word[0].length;
280
- continue;
281
- }
282
- out += ch;
283
- i++;
284
- }
285
- try {
286
- JSON.parse(out);
287
- return out;
288
- } catch {
289
- return null;
290
- }
291
- }
292
- function hasPythonKindKey(text) {
293
- return PYTHON_KIND_KEY.test(withoutZeroWidth(text));
294
- }
295
- function pythonBalancedEnd(text, start) {
296
- let depth = 0;
297
- let quote = null;
298
- for (let i = start; i < text.length; i++) {
299
- const ch = text[i];
300
- if (quote) {
301
- if (ch === "\\") i++;
302
- else if (ch === quote) quote = null;
303
- continue;
304
- }
305
- if (ch === "'" || ch === '"') quote = ch;
306
- else if (ch === "{" || ch === "[") depth++;
307
- else if (ch === "}" || ch === "]") {
308
- depth--;
309
- if (depth === 0) return i + 1;
310
- }
311
- }
312
- return null;
313
- }
314
- function normalizeKindSpellings(source) {
315
- if (!mayHoldKindKey(source)) return source;
316
- if (/^[{[]/.test(source.trimStart())) {
317
- try {
318
- JSON.parse(source);
319
- return withoutZeroWidthInKeys(source);
320
- } catch {
321
- }
322
- }
323
- let out = "";
324
- let cursor = 0;
325
- for (const region of scanKindSpellingRegions(source)) {
326
- const rewritten = canonicalRegionText(source, region);
327
- if (rewritten === null) continue;
328
- out += source.slice(cursor, region.rewriteStart) + rewritten;
329
- cursor = region.rewriteEnd;
330
- }
331
- return cursor === 0 ? source : out + source.slice(cursor);
332
- }
333
- function canonicalRegionText(source, region) {
334
- if (region.family === "lifted") {
335
- if (region.markdown) return region.status === "broken" ? closedJson(region) ?? region.decoded : region.decoded;
336
- const key = source.slice(region.rewriteStart, region.rewriteEnd);
337
- return region.keyText === void 0 || key === region.keyText ? null : region.keyText;
338
- }
339
- if (region.status === "complete") {
340
- const json = regionJson(region);
341
- if (json !== null) return json;
342
- return region.family === "python" || region.family === "js" ? null : region.decoded;
343
- }
344
- if (region.status === "broken") return closedJson(region) ?? region.decoded;
345
- return region.family === "python" || region.family === "js" ? null : region.decoded;
346
- }
347
- const ZW = "[\\u200B-\\u200D\\u2060\\uFEFF\\u00AD]";
348
- const KEY_UNDERSCORE = String.raw`(?:\\*_|\\u005[fF]|&#0*95;|&#[xX]0*5[fF];|&lowbar;|&UnderBar;)`;
349
- const KEY_CORE = `${ZW}*${KEY_UNDERSCORE}${ZW}*${KEY_UNDERSCORE}${ZW}*k${ZW}*i${ZW}*n${ZW}*d${ZW}*`;
350
- const SMART_ANY = `[${SMART_DOUBLE}${SMART_SINGLE}]`;
351
- const SPELLED_KEY_SOURCE = [
352
- String.raw`(\\*)"(${KEY_CORE})\\*"\s*:`,
353
- String.raw`(?<=[{,]\s*)'(${KEY_CORE})'\s*:(?=\s*['"])`,
354
- `${SMART_ANY}(${KEY_CORE})[${SMART_DOUBLE}${SMART_SINGLE}"']\\s*:`,
355
- `${ENTITY_QUOTE}(${KEY_CORE})${ENTITY_QUOTE}\\s*:`,
356
- String.raw`(?<=[{,]\s*)(${KEY_CORE})\s*:(?=\s*['"])`
357
- ].join("|");
358
- const SPELLED_KEY = new RegExp(SPELLED_KEY_SOURCE);
359
- const SPELLED_KEY_G = new RegExp(SPELLED_KEY_SOURCE, "g");
360
- function hasSpelledKey(text) {
361
- return mayHoldKindKey(text) && SPELLED_KEY.test(text);
362
- }
363
- function mayHoldKindKey(text) {
364
- return text.includes("kind") || text.includes("_") && HAS_ZERO_WIDTH.test(text);
365
- }
366
- const MAX_REGIONS_PER_CALL = 2e3;
367
- const KEY_LOOKBEHIND = 64;
368
- function nextKindHit(text, from, zeroWidth) {
369
- if (!zeroWidth) return text.indexOf("kind", from);
370
- KIND_LETTERS_G.lastIndex = from;
371
- const m = KIND_LETTERS_G.exec(text);
372
- return m ? m.index : -1;
373
- }
374
- const KIND_LETTERS_G = new RegExp(`k${ZW}*i${ZW}*n${ZW}*d`, "g");
375
- function keyFamily(m) {
376
- if (m[3] !== void 0) return { family: "python", core: m[3], levels: 0 };
377
- if (m[4] !== void 0) return { family: "smart", core: m[4], levels: 0 };
378
- if (m[5] !== void 0) return { family: "entity", core: m[5], levels: 0 };
379
- if (m[6] !== void 0) return { family: "js", core: m[6], levels: 0 };
380
- const backslashes = m[1].length;
381
- const core = m[2];
382
- if (core.includes("&")) return { family: "entity", core, levels: 0 };
383
- if (backslashes > 0) {
384
- return { family: "escaped", core, levels: Math.min(4, Math.ceil(Math.log2(backslashes + 1))) };
385
- }
386
- const plain = core.replace(ZERO_WIDTH, "");
387
- if (plain === "__kind" || /^\\u005[fF]_kind$/.test(plain)) return { family: "lifted", core, levels: 0 };
388
- if (plain === "\\_\\_kind") return { family: "lifted", core, levels: 0 };
389
- return { family: "markdown", core, levels: 0 };
390
- }
391
- function scanKindSpellingRegions(text, options = {}) {
392
- const jsonOnly = options.families !== "all";
393
- const from = options.from ?? 0;
394
- const regions = [];
395
- if (!mayHoldKindKey(text)) return regions;
396
- const zeroWidth = HAS_ZERO_WIDTH.test(text);
397
- let quoted = null;
398
- const inQuoted = (at) => {
399
- quoted ??= quotedSourceRanges(text);
400
- let lo = 0;
401
- let hi = quoted.length - 1;
402
- while (lo <= hi) {
403
- const mid = lo + hi >> 1;
404
- const [a, b] = quoted[mid];
405
- if (at < a) hi = mid - 1;
406
- else if (at >= b) lo = mid + 1;
407
- else return true;
408
- }
409
- return false;
410
- };
411
- let cursor = from;
412
- let braceScan = from;
413
- let lastBrace = -1;
414
- let deadBraceFloor = from;
415
- const reach = { left: REACH_BUDGET_FACTOR * text.length + REACH_BUDGET_FLOOR };
416
- let hit = nextKindHit(text, from, zeroWidth);
417
- while (hit >= 0 && regions.length < MAX_REGIONS_PER_CALL) {
418
- const windowStart = Math.max(cursor, hit - KEY_LOOKBEHIND);
419
- const windowEnd = Math.min(text.length, hit + KEY_LOOKBEHIND);
420
- SPELLED_KEY_G.lastIndex = 0;
421
- const window = text.slice(windowStart, windowEnd);
422
- let m = null;
423
- for (let candidate = SPELLED_KEY_G.exec(window); candidate; candidate = SPELLED_KEY_G.exec(window)) {
424
- if (windowStart + candidate.index + candidate[0].length > hit) {
425
- m = candidate;
426
- break;
427
- }
428
- }
429
- if (!m) {
430
- hit = nextKindHit(text, hit + 1, zeroWidth);
431
- continue;
432
- }
433
- const keyAt = windowStart + m.index;
434
- const keyEnd = keyAt + m[0].length;
435
- const next = () => nextKindHit(text, keyEnd, zeroWidth);
436
- while (braceScan < keyAt) {
437
- if (text.charCodeAt(braceScan) === 123) lastBrace = braceScan;
438
- braceScan++;
439
- }
440
- const brace = lastBrace >= Math.max(cursor, deadBraceFloor) ? lastBrace : -1;
441
- if (brace < 0 || inQuoted(keyAt) || inQuoted(brace)) {
442
- hit = next();
443
- continue;
444
- }
445
- const { family, core, levels } = keyFamily(m);
446
- if (jsonOnly && family !== "lifted" && family !== "markdown") {
447
- hit = next();
448
- continue;
449
- }
450
- const markdown = /\\_/.test(core) || family === "escaped" && /\\{2}_/.test(core);
451
- const plan = decodePlan(family, levels, markdown);
452
- const region = boundRegion(text, brace, keyAt, plan, reach);
453
- if (!region) {
454
- deadBraceFloor = brace + 1;
455
- hit = next();
456
- continue;
457
- }
458
- if (family === "lifted" && !markdown) {
459
- regions.push({
460
- start: brace,
461
- end: region.end,
462
- rewriteStart: keyAt,
463
- rewriteEnd: keyEnd,
464
- keyText: m[0].replace(ZERO_WIDTH, ""),
465
- family,
466
- status: region.status,
467
- decoded: withoutZeroWidthInKeys(region.decoded),
468
- markdown: false
469
- });
470
- } else {
471
- regions.push({
472
- start: brace,
473
- end: region.end,
474
- rewriteStart: brace,
475
- rewriteEnd: region.end,
476
- family,
477
- status: region.status,
478
- decoded: withoutZeroWidthInKeys(region.decoded),
479
- markdown
480
- });
481
- }
482
- cursor = region.end;
483
- if (region.status === "prefix") break;
484
- hit = nextKindHit(text, cursor, zeroWidth);
485
- }
486
- return regions;
487
- }
488
- const ZW_KEY_IN_DECODED = new RegExp(`(["'])${ZW}*_${ZW}*_${ZW}*k${ZW}*i${ZW}*n${ZW}*d${ZW}*\\1(?=\\s*:)`, "g");
489
- function withoutZeroWidthInKeys(decoded) {
490
- return HAS_ZERO_WIDTH.test(decoded) ? decoded.replace(ZW_KEY_IN_DECODED, (key) => key.replace(ZERO_WIDTH, "")) : decoded;
491
- }
492
- function decodePlan(family, levels, markdown) {
493
- const steps = [];
494
- if (family === "entity") steps.push(entityStep);
495
- if (family === "smart") steps.push(smartStep);
496
- for (let level = 0; level < levels; level++) steps.push(escapeStep);
497
- if (markdown) steps.push(markdownStep);
498
- const grammar = family === "js" ? "js" : family === "python" || family === "smart" || family === "entity" ? "python" : "json";
499
- return { steps, grammar };
500
- }
501
- function decodeWith(raw, step) {
502
- let text = "";
503
- const map = [];
504
- for (let i = 0; i < raw.length; ) {
505
- const [out, consumed] = step(raw, i);
506
- for (let k = 0; k < out.length; k++) map.push(i);
507
- text += out;
508
- i += Math.max(1, consumed);
509
- }
510
- map.push(raw.length);
511
- return { text, map };
512
- }
513
- function decodeChain(raw, steps) {
514
- if (steps.length === 0) {
515
- const map = new Array(raw.length + 1);
516
- for (let i = 0; i <= raw.length; i++) map[i] = i;
517
- return { text: raw, map };
518
- }
519
- let current = decodeWith(raw, steps[0]);
520
- for (let s = 1; s < steps.length; s++) {
521
- const next = decodeWith(current.text, steps[s]);
522
- const prior = current.map;
523
- current = { text: next.text, map: next.map.map((at) => prior[at]) };
524
- }
525
- return current;
526
- }
527
- const ENTITY_STEP_RE = /^&(?:(quot|apos|amp|lt|gt|lowbar|UnderBar)|#(\d{1,6})|#[xX]([0-9a-fA-F]{1,6}));/i;
528
- const NAMED_ENTITIES = { quot: '"', apos: "'", amp: "&", lt: "<", gt: ">", lowbar: "_", underbar: "_" };
529
- const ESCAPE_CHARS = { '"': '"', "\\": "\\", "/": "/", n: "\n", t: " ", r: "\r", b: "", f: "" };
530
- const entityStep = (raw, i) => {
531
- if (raw[i] !== "&") return [raw[i], 1];
532
- const m = ENTITY_STEP_RE.exec(raw.slice(i, i + 12));
533
- if (!m) return ["&", 1];
534
- const ch = m[1] ? NAMED_ENTITIES[m[1].toLowerCase()] : String.fromCodePoint(Number.parseInt(m[2] ?? m[3], m[2] ? 10 : 16));
535
- return [ch, m[0].length];
536
- };
537
- const smartStep = (raw, i) => {
538
- const ch = raw[i];
539
- if (SMART_DOUBLE.includes(ch)) return ['"', 1];
540
- if (SMART_SINGLE.includes(ch)) return ["'", 1];
541
- return [ch, 1];
542
- };
543
- const escapeStep = (raw, i) => {
544
- if (raw[i] !== "\\") return [raw[i], 1];
545
- const next = raw[i + 1] ?? "";
546
- if (next in ESCAPE_CHARS) return [ESCAPE_CHARS[next], 2];
547
- if (next === "u" && /^[0-9a-fA-F]{4}$/.test(raw.slice(i + 2, i + 6))) return [raw.slice(i, i + 6), 6];
548
- return [raw.slice(i, i + 2), 2];
549
- };
550
- const markdownStep = (raw, i) => raw[i] === "\\" && raw[i + 1] === "_" ? ["_", 2] : [raw[i], 1];
551
- const FIRST_WINDOW = 128;
552
- const REACH_BUDGET_FACTOR = 4;
553
- const REACH_BUDGET_FLOOR = 65536;
554
- function boundRegion(text, brace, keyAt, plan, reach = { left: Number.POSITIVE_INFINITY }) {
555
- for (let width = FIRST_WINDOW; ; width *= 4) {
556
- const hi = Math.min(text.length, brace + width);
557
- const atEnd = hi === text.length;
558
- const decoded = decodeChain(text.slice(brace, hi), plan.steps);
559
- const keyDecoded = firstAtOrAfter(decoded.map, keyAt - brace);
560
- const verdict = kindGrammar(decoded.text, plan.grammar);
561
- if (verdict.status === "complete") {
562
- if (verdict.end <= keyDecoded) return null;
563
- return { end: brace + decoded.map[verdict.end], status: "complete", decoded: decoded.text.slice(0, verdict.end) };
564
- }
565
- if (verdict.status === "broken") {
566
- if (!atEnd && decoded.map[verdict.at] >= hi - brace - 16) continue;
567
- if (!verdict.prose) {
568
- const end = balancedEnd(decoded.text, plan.grammar !== "json");
569
- if (end === null && !atEnd) {
570
- const past = hi - brace - verdict.at;
571
- if (reach.left > past) {
572
- reach.left -= past;
573
- continue;
574
- }
575
- }
576
- if (end !== null && end > keyDecoded && lenientlyParses(decoded.text.slice(0, end), plan.grammar)) {
577
- return { end: brace + decoded.map[end], status: "complete", decoded: decoded.text.slice(0, end) };
578
- }
579
- }
580
- if (atEnd && ARRIVING_SPELLING_TAIL.test(text.slice(brace + decoded.map[verdict.at]))) {
581
- if (verdict.at <= keyDecoded) return null;
582
- return { end: text.length, status: "prefix", decoded: decoded.text };
583
- }
584
- if (verdict.cut <= keyDecoded) return null;
585
- return { end: brace + decoded.map[verdict.cut], status: "broken", decoded: decoded.text.slice(0, verdict.cut) };
586
- }
587
- if (!atEnd) continue;
588
- return { end: text.length, status: "prefix", decoded: decoded.text };
589
- }
590
- }
591
- const BARE_REGION_GRAMMAR_BUDGET = 16384;
592
- function bareRegionBreaksIntoProse(text, options = {}) {
593
- let region = text;
594
- if (region.length > BARE_REGION_GRAMMAR_BUDGET) {
595
- if (!options.firstBudget) return false;
596
- region = region.slice(0, BARE_REGION_GRAMMAR_BUDGET);
597
- }
598
- const start = region.search(/\S/);
599
- if (start < 0) return false;
600
- const verdict = kindGrammar(region, "json", start);
601
- return verdict.status === "broken" && verdict.prose;
602
- }
603
- function lenientlyParses(span, grammar) {
604
- const body = span.replace(/,(\s*[}\]])/g, "$1");
605
- if (grammar !== "json") return true;
606
- try {
607
- JSON.parse(body);
608
- return true;
609
- } catch {
610
- return false;
611
- }
612
- }
613
- function balancedEnd(text, singleQuotes) {
614
- let depth = 0;
615
- let quote = "";
616
- for (let i = 0; i < text.length; i++) {
617
- const ch = text[i];
618
- if (quote) {
619
- if (ch === "\\") i++;
620
- else if (ch === quote) quote = "";
621
- continue;
622
- }
623
- if (ch === '"' || singleQuotes && ch === "'") quote = ch;
624
- else if (ch === "{" || ch === "[") depth++;
625
- else if (ch === "}" || ch === "]") {
626
- depth--;
627
- if (depth === 0) return i + 1;
628
- }
629
- }
630
- return null;
631
- }
632
- function kindObjectProseBreak(text) {
633
- const key = text.search(LITERAL_KIND_KEY);
634
- if (key < 0) return null;
635
- const verdict = kindGrammar(text);
636
- return verdict.status === "broken" && verdict.prose && verdict.cut > key ? verdict.cut : null;
637
- }
638
- const LITERAL_KIND_KEY = new RegExp(String.raw`(?<!\\)"${KIND_KEY_BODY}"\s*:`);
639
- const ARRIVING_SPELLING_TAIL = /^(?:\\+"?|&#?[A-Za-z0-9]{0,6})$/;
640
- function firstAtOrAfter(map, raw) {
641
- let lo = 0;
642
- let hi = map.length - 1;
643
- while (lo < hi) {
644
- const mid = lo + hi >> 1;
645
- if (map[mid] < raw) lo = mid + 1;
646
- else hi = mid;
647
- }
648
- return lo;
649
- }
650
- function kindGrammar(s, dialect = "json", from = 0) {
651
- const closers = [];
652
- const singleQuotes = dialect !== "json";
653
- const bareKeys = dialect === "js";
654
- const trailingCommas = dialect !== "json";
655
- let expect = 0;
656
- let lastGood = from;
657
- const n = s.length;
658
- const broken = (at) => ({
659
- status: "broken",
660
- at,
661
- cut: lastGood,
662
- prose: !/^[{}[\]:,"'0-9.+-]$/.test(s[at] ?? "")
663
- });
664
- let i = from;
665
- while (i < n) {
666
- const c = s.charCodeAt(i);
667
- if (c === 32 || c === 9 || c === 10 || c === 13) {
668
- i++;
669
- continue;
670
- }
671
- if (expect === 4 || expect === 1 || expect === 2) {
672
- if (c === 125 || c === 93) {
673
- if (closers.length === 0 || closers[closers.length - 1] !== c) return broken(i);
674
- if (expect === 4 || trailingCommas || lastCharWasOpener(s, i)) {
675
- closers.pop();
676
- i++;
677
- lastGood = i;
678
- if (closers.length === 0) return { status: "complete", end: i };
679
- expect = 4;
680
- continue;
681
- }
682
- return broken(i);
683
- }
684
- if (expect === 4) {
685
- if (c !== 44) return broken(i);
686
- i++;
687
- lastGood = i;
688
- expect = closers[closers.length - 1] === 125 ? 2 : 1;
689
- continue;
690
- }
691
- }
692
- if (expect === 3) {
693
- if (c !== 58) return broken(i);
694
- i++;
695
- expect = 0;
696
- continue;
697
- }
698
- const keyPosition = expect === 2;
699
- if (c === 34 || singleQuotes && c === 39) {
700
- let j = i + 1;
701
- for (; ; ) {
702
- if (j >= n) return { status: "prefix" };
703
- const d = s.charCodeAt(j);
704
- if (d === 92) {
705
- j += 2;
706
- continue;
707
- }
708
- if (d === 10 || d === 13) return broken(j);
709
- if (d === c) break;
710
- j++;
711
- }
712
- i = j + 1;
713
- if (keyPosition) expect = 3;
714
- else {
715
- expect = 4;
716
- lastGood = i;
717
- }
718
- continue;
719
- }
720
- if (keyPosition) {
721
- if (!bareKeys || !isIdentStart(c)) return broken(i);
722
- let j = i + 1;
723
- while (j < n && isIdentPart(s.charCodeAt(j))) j++;
724
- if (j >= n) return { status: "prefix" };
725
- i = j;
726
- expect = 3;
727
- continue;
728
- }
729
- if (c === 123 || c === 91) {
730
- closers.push(c === 123 ? 125 : 93);
731
- i++;
732
- lastGood = i;
733
- expect = c === 123 ? 2 : 1;
734
- continue;
735
- }
736
- if (c === 45 || c >= 48 && c <= 57) {
737
- let j = i + 1;
738
- while (j < n && /[0-9eE.+-]/.test(s[j])) j++;
739
- if (j >= n) return { status: "prefix" };
740
- i = j;
741
- lastGood = i;
742
- expect = 4;
743
- continue;
744
- }
745
- if (isIdentStart(c)) {
746
- let j = i + 1;
747
- while (j < n && isIdentPart(s.charCodeAt(j))) j++;
748
- const word = s.slice(i, j);
749
- if (j >= n) return VALUE_WORDS[dialect].some((w) => w.startsWith(word)) ? { status: "prefix" } : broken(i);
750
- if (!VALUE_WORDS[dialect].includes(word)) return broken(i);
751
- i = j;
752
- lastGood = i;
753
- expect = 4;
754
- continue;
755
- }
756
- return broken(i);
757
- }
758
- return { status: "prefix" };
759
- }
760
- const VALUE_WORDS = {
761
- json: ["true", "false", "null"],
762
- python: ["True", "False", "None", "true", "false", "null"],
763
- js: ["true", "false", "null", "undefined", "NaN", "Infinity"]
764
- };
765
- function isIdentStart(c) {
766
- return c >= 65 && c <= 90 || c >= 97 && c <= 122 || c === 95 || c === 36;
767
- }
768
- function isIdentPart(c) {
769
- return isIdentStart(c) || c >= 48 && c <= 57;
770
- }
771
- function lastCharWasOpener(s, at) {
772
- for (let k = at - 1; k >= 0; k--) {
773
- const c = s.charCodeAt(k);
774
- if (c === 32 || c === 9 || c === 10 || c === 13) continue;
775
- return c === 123 || c === 91;
776
- }
777
- return false;
778
- }
779
- const JSON_ONLY_FAMILIES = /* @__PURE__ */ new Set(["lifted", "escaped", "markdown"]);
780
- function regionJson(region) {
781
- const text = region.decoded;
782
- if (region.family === "js") return json5AsJson(text);
783
- if (region.family !== "python") {
784
- try {
785
- JSON.parse(text);
786
- return text;
787
- } catch {
788
- }
789
- }
790
- return pythonReprAsJson(text);
791
- }
792
- function closedJson(region) {
793
- let body = region.decoded.replace(/\s+$/, "");
794
- body = body.replace(/,?\s*(?:"(?:[^"\\]|\\.)*"|'(?:[^'\\]|\\.)*'|[A-Za-z_$][\w$]*)\s*:\s*$/, "");
795
- body = body.replace(/,\s*$/, "");
796
- const closers = [];
797
- let quote = "";
798
- for (let i = 0; i < body.length; i++) {
799
- const ch = body[i];
800
- if (quote) {
801
- if (ch === "\\") i++;
802
- else if (ch === quote) quote = "";
803
- continue;
804
- }
805
- if (ch === '"' || ch === "'" && !JSON_ONLY_FAMILIES.has(region.family)) quote = ch;
806
- else if (ch === "{") closers.push("}");
807
- else if (ch === "[") closers.push("]");
808
- else if (ch === "}" || ch === "]") closers.pop();
809
- }
810
- if (quote) return null;
811
- return regionJson({ family: region.family, decoded: body + closers.reverse().join("") });
812
- }
813
- function valueCarriesKind(value) {
814
- return carriesKind(value, 0, /* @__PURE__ */ new Set());
815
- }
816
- const VALUE_SEARCH_DEPTH = 64;
817
- function carriesKind(value, depth, seen) {
818
- if (typeof value === "string") return textCarriesKind(value);
819
- if (value === null || typeof value !== "object") return false;
820
- if (depth > VALUE_SEARCH_DEPTH || seen.has(value)) return false;
821
- seen.add(value);
822
- if (Array.isArray(value)) {
823
- return value.some((item) => carriesKind(item, depth + 1, seen));
824
- }
825
- const record = value;
826
- if (typeof record.__kind === "string" && record.__kind.trim()) return true;
827
- for (const item of Object.values(record)) {
828
- if (carriesKind(item, depth + 1, seen)) return true;
829
- }
830
- return false;
831
- }
832
- function textCarriesKind(text) {
833
- if (isKindJsonText(text) || markdownCarriesKind(text)) return true;
834
- if (!mayHoldKindKey(text) || !/^[{[]/.test(text.trimStart())) return false;
835
- let parsed;
836
- try {
837
- parsed = JSON.parse(text);
838
- } catch {
839
- return false;
840
- }
841
- return typeof parsed === "object" && parsed !== null && valueCarriesKind(parsed);
842
- }
843
- function isKindJsonText(text) {
844
- const first = text.trimStart()[0];
845
- return (first === "{" || first === "[") && hasKindKey(text);
846
- }
847
- function rootKindSlug(value) {
848
- if (value === null || typeof value !== "object" || Array.isArray(value)) return null;
849
- const kind = value.__kind;
850
- return typeof kind === "string" && kind.trim() ? kind : null;
851
- }
852
- const JSON_FENCE_LANGS = /* @__PURE__ */ new Set(["", "json", "jsonc", "json5"]);
853
- function isJsonFenceLanguage(lang) {
854
- return JSON_FENCE_LANGS.has((lang ?? "").trim().toLowerCase());
855
- }
856
- function quotedSourceRanges(text) {
857
- const ranges = [];
858
- for (const range of findCodeRanges(text)) {
859
- if (range.kind === "span") {
860
- ranges.push([range.start, range.end]);
861
- continue;
862
- }
863
- const raw = text.slice(range.start, range.end);
864
- const newline = raw.indexOf("\n");
865
- const firstLine = (newline === -1 ? raw : raw.slice(0, newline)).replace(/^ {0,3}(?:> ?)*/, "");
866
- const opener = fenceOpenerOf(firstLine.trimStart());
867
- if (!opener || !isJsonFenceLanguage(opener.lang)) {
868
- ranges.push([range.start, range.end]);
869
- }
870
- }
871
- return ranges;
872
- }
873
- function isQuotedSourceXmlBlock(block) {
874
- return block.metadata?.genericXmlContainer !== true;
875
- }
876
- function frontMatterEnd(source) {
877
- const body = source.charCodeAt(0) === 65279 ? 1 : 0;
878
- const firstBreak = source.indexOf("\n", body);
879
- if (firstBreak < 0) return 0;
880
- const opener = source.slice(body, firstBreak).replace(/\r$/, "");
881
- if (opener !== "---" && opener !== "+++") return 0;
882
- for (let pos = firstBreak + 1; pos < source.length; ) {
883
- const next = source.indexOf("\n", pos);
884
- const end = next < 0 ? source.length : next;
885
- const line = source.slice(pos, end).replace(/\r$/, "");
886
- if (line === opener || opener === "---" && line === "...") return end;
887
- if (next < 0) break;
888
- pos = next + 1;
889
- }
890
- return 0;
891
- }
892
- function markdownCarriesKind(source) {
893
- const text = source.slice(frontMatterEnd(source));
894
- if (!hasKindKey(text, JSON_KIND_SPELLINGS)) return false;
895
- if (isKindJsonText(text)) return true;
896
- const quoted = quotedSourceRanges(text);
897
- if (quoted.length === 0) return true;
898
- let outside = "";
899
- let cursor = 0;
900
- for (const [start, end] of quoted) {
901
- if (start < cursor) continue;
902
- outside += text.slice(cursor, start) + " ";
903
- cursor = end;
904
- }
905
- outside += text.slice(cursor);
906
- return hasKindKey(outside, JSON_KIND_SPELLINGS);
907
- }
908
- export {
909
- ALL_KIND_SPELLINGS,
910
- BARE_REGION_GRAMMAR_BUDGET,
911
- JSON_KIND_SPELLINGS,
912
- bareRegionBreaksIntoProse,
913
- closedJson,
914
- endsInPartialKindKey,
915
- firstKindSlug,
916
- frontMatterEnd,
917
- hasDetectionOnlyKindKey,
918
- hasExoticKindKey,
919
- hasJsonKindKey,
920
- hasKindKey,
921
- hasKindKeyAnySpelling,
922
- hasPythonKindKey,
923
- isJson5Language,
924
- isJsonFenceLanguage,
925
- isKindJsonText,
926
- isKindSlug,
927
- isQuotedSourceXmlBlock,
928
- json5AsJson,
929
- jsonKindSignal,
930
- kindGrammar,
931
- kindObjectProseBreak,
932
- markdownCarriesKind,
933
- mayHoldKindKey,
934
- normalizeKindSpellings,
935
- pythonBalancedEnd,
936
- pythonReprAsJson,
937
- quotedSourceRanges,
938
- regionJson,
939
- rootKindSlug,
940
- scanKindSpellingRegions,
941
- textCarriesKind,
942
- valueCarriesKind,
943
- withoutLeadingJsonComments,
944
- withoutZeroWidth
945
- };