jamdesk 1.1.70 → 1.1.71
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/integration/validate.integration.test.js +21 -0
- package/dist/__tests__/integration/validate.integration.test.js.map +1 -1
- package/dist/__tests__/unit/extract-hooks.test.js +102 -1
- package/dist/__tests__/unit/extract-hooks.test.js.map +1 -1
- package/dist/__tests__/unit/mdx-validator.test.js +22 -0
- package/dist/__tests__/unit/mdx-validator.test.js.map +1 -1
- package/dist/__tests__/unit/migrate-mdx.test.js +121 -1
- package/dist/__tests__/unit/migrate-mdx.test.js.map +1 -1
- package/dist/__tests__/unit/relative-mdx-imports.test.d.ts +2 -0
- package/dist/__tests__/unit/relative-mdx-imports.test.d.ts.map +1 -0
- package/dist/__tests__/unit/relative-mdx-imports.test.js +452 -0
- package/dist/__tests__/unit/relative-mdx-imports.test.js.map +1 -0
- package/dist/__tests__/unit/relocate-snippets.test.d.ts +2 -0
- package/dist/__tests__/unit/relocate-snippets.test.d.ts.map +1 -0
- package/dist/__tests__/unit/relocate-snippets.test.js +542 -0
- package/dist/__tests__/unit/relocate-snippets.test.js.map +1 -0
- package/dist/__tests__/unit/run-build-script.test.js +23 -1
- package/dist/__tests__/unit/run-build-script.test.js.map +1 -1
- package/dist/__tests__/unit/warn-relative-imports.test.d.ts +2 -0
- package/dist/__tests__/unit/warn-relative-imports.test.d.ts.map +1 -0
- package/dist/__tests__/unit/warn-relative-imports.test.js +44 -0
- package/dist/__tests__/unit/warn-relative-imports.test.js.map +1 -0
- package/dist/commands/dev.d.ts.map +1 -1
- package/dist/commands/dev.js +16 -1
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/migrate/convert-mdx.d.ts +5 -1
- package/dist/commands/migrate/convert-mdx.d.ts.map +1 -1
- package/dist/commands/migrate/convert-mdx.js +19 -6
- package/dist/commands/migrate/convert-mdx.js.map +1 -1
- package/dist/commands/migrate/extract-hooks.d.ts +26 -0
- package/dist/commands/migrate/extract-hooks.d.ts.map +1 -1
- package/dist/commands/migrate/extract-hooks.js +71 -12
- package/dist/commands/migrate/extract-hooks.js.map +1 -1
- package/dist/commands/migrate/fix-mdx-syntax.d.ts +38 -0
- package/dist/commands/migrate/fix-mdx-syntax.d.ts.map +1 -0
- package/dist/commands/migrate/fix-mdx-syntax.js +80 -0
- package/dist/commands/migrate/fix-mdx-syntax.js.map +1 -0
- package/dist/commands/migrate/index.d.ts.map +1 -1
- package/dist/commands/migrate/index.js +165 -3
- package/dist/commands/migrate/index.js.map +1 -1
- package/dist/commands/migrate/relocate-snippets.d.ts +30 -0
- package/dist/commands/migrate/relocate-snippets.d.ts.map +1 -0
- package/dist/commands/migrate/relocate-snippets.js +357 -0
- package/dist/commands/migrate/relocate-snippets.js.map +1 -0
- package/dist/commands/validate.d.ts.map +1 -1
- package/dist/commands/validate.js +31 -1
- package/dist/commands/validate.js.map +1 -1
- package/dist/lib/mdx-syntax-fixes.d.ts +14 -0
- package/dist/lib/mdx-syntax-fixes.d.ts.map +1 -0
- package/dist/lib/mdx-syntax-fixes.js +38 -0
- package/dist/lib/mdx-syntax-fixes.js.map +1 -0
- package/dist/lib/mdx-validator.d.ts +11 -2
- package/dist/lib/mdx-validator.d.ts.map +1 -1
- package/dist/lib/mdx-validator.js +41 -4
- package/dist/lib/mdx-validator.js.map +1 -1
- package/dist/lib/relative-mdx-imports.d.ts +44 -0
- package/dist/lib/relative-mdx-imports.d.ts.map +1 -0
- package/dist/lib/relative-mdx-imports.js +145 -0
- package/dist/lib/relative-mdx-imports.js.map +1 -0
- package/dist/lib/run-build-script.d.ts.map +1 -1
- package/dist/lib/run-build-script.js +7 -0
- package/dist/lib/run-build-script.js.map +1 -1
- package/dist/lib/warn-relative-imports.d.ts +2 -0
- package/dist/lib/warn-relative-imports.d.ts.map +1 -0
- package/dist/lib/warn-relative-imports.js +29 -0
- package/dist/lib/warn-relative-imports.js.map +1 -0
- package/package.json +1 -1
- package/vendored/app/(unlock)/jd/unlock/page.tsx +32 -0
- package/vendored/app/[[...slug]]/page.tsx +63 -15
- package/vendored/components/navigation/SocialFooter.tsx +4 -18
- package/vendored/lib/branding-url.ts +9 -0
- package/vendored/lib/preprocess-mdx.ts +42 -0
- package/vendored/scripts/compile-snippets.cjs +50 -7
- package/vendored/workspace-package-lock.json +3 -3
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
// builder/cli/src/__tests__/unit/relative-mdx-imports.test.ts
|
|
2
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
3
|
+
import { mkdtemp, mkdir, writeFile, rm } from 'node:fs/promises';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { detectRelativeMdxImports, rewriteRelativeMdxImports, } from '../../lib/relative-mdx-imports.js';
|
|
7
|
+
describe('detectRelativeMdxImports', () => {
|
|
8
|
+
it('finds parent-relative MDX imports', () => {
|
|
9
|
+
const content = [
|
|
10
|
+
'---',
|
|
11
|
+
'title: x',
|
|
12
|
+
'---',
|
|
13
|
+
'import Foo from "../snippets/foo.mdx";',
|
|
14
|
+
'import Bar from "./bar.mdx";',
|
|
15
|
+
'',
|
|
16
|
+
'<Foo />',
|
|
17
|
+
].join('\n');
|
|
18
|
+
const matches = detectRelativeMdxImports(content);
|
|
19
|
+
expect(matches).toHaveLength(2);
|
|
20
|
+
expect(matches[0]).toMatchObject({ specifier: '../snippets/foo.mdx', line: 4 });
|
|
21
|
+
expect(matches[1]).toMatchObject({ specifier: './bar.mdx', line: 5 });
|
|
22
|
+
});
|
|
23
|
+
it('ignores root-relative MDX imports', () => {
|
|
24
|
+
const content = `import Foo from "/snippets/foo.mdx";`;
|
|
25
|
+
expect(detectRelativeMdxImports(content)).toEqual([]);
|
|
26
|
+
});
|
|
27
|
+
it('ignores non-MDX relative imports', () => {
|
|
28
|
+
const content = `import css from "../styles.css";\nimport Foo from "../foo.tsx";`;
|
|
29
|
+
expect(detectRelativeMdxImports(content)).toEqual([]);
|
|
30
|
+
});
|
|
31
|
+
it('handles single quotes, named imports, multiple per file', () => {
|
|
32
|
+
const content = [
|
|
33
|
+
`import { A, B } from '../snippets/a.mdx';`,
|
|
34
|
+
`import C from "../snippets/c.mdx";`,
|
|
35
|
+
].join('\n');
|
|
36
|
+
const matches = detectRelativeMdxImports(content);
|
|
37
|
+
expect(matches.map((m) => m.specifier)).toEqual([
|
|
38
|
+
'../snippets/a.mdx',
|
|
39
|
+
'../snippets/c.mdx',
|
|
40
|
+
]);
|
|
41
|
+
});
|
|
42
|
+
it('handles multi-line named imports', () => {
|
|
43
|
+
const content = [
|
|
44
|
+
'import {',
|
|
45
|
+
' Foo,',
|
|
46
|
+
' Bar,',
|
|
47
|
+
"} from '../snippets/components.mdx';",
|
|
48
|
+
].join('\n');
|
|
49
|
+
const matches = detectRelativeMdxImports(content);
|
|
50
|
+
expect(matches).toHaveLength(1);
|
|
51
|
+
expect(matches[0].specifier).toBe('../snippets/components.mdx');
|
|
52
|
+
// Line should be the line where the `import` keyword starts (1).
|
|
53
|
+
expect(matches[0].line).toBe(1);
|
|
54
|
+
});
|
|
55
|
+
it('ignores imports inside fenced code blocks (```)', () => {
|
|
56
|
+
// Real-world case from projects/mintlify/create/reusable-snippets.mdx:
|
|
57
|
+
// documentation pages show import syntax in code blocks; those are
|
|
58
|
+
// rendered as code, not executed, and must NOT be detected as imports.
|
|
59
|
+
const content = [
|
|
60
|
+
'# Docs',
|
|
61
|
+
'',
|
|
62
|
+
'```mdx',
|
|
63
|
+
'import Fake from "../snippets/fake.mdx";',
|
|
64
|
+
'```',
|
|
65
|
+
'',
|
|
66
|
+
'import Real from "../snippets/real.mdx";',
|
|
67
|
+
].join('\n');
|
|
68
|
+
const matches = detectRelativeMdxImports(content);
|
|
69
|
+
expect(matches).toHaveLength(1);
|
|
70
|
+
expect(matches[0].specifier).toBe('../snippets/real.mdx');
|
|
71
|
+
});
|
|
72
|
+
it('ignores imports inside tilde-fenced code blocks (~~~)', () => {
|
|
73
|
+
const content = [
|
|
74
|
+
'~~~mdx',
|
|
75
|
+
'import Fake from "../snippets/fake.mdx";',
|
|
76
|
+
'~~~',
|
|
77
|
+
'import Real from "../snippets/real.mdx";',
|
|
78
|
+
].join('\n');
|
|
79
|
+
const matches = detectRelativeMdxImports(content);
|
|
80
|
+
expect(matches.map((m) => m.specifier)).toEqual(['../snippets/real.mdx']);
|
|
81
|
+
});
|
|
82
|
+
it('ignores imports inside fenced blocks even with info strings and indentation', () => {
|
|
83
|
+
const content = [
|
|
84
|
+
'1. Step one',
|
|
85
|
+
'',
|
|
86
|
+
' ```mdx shared/example.mdx wrap',
|
|
87
|
+
' import Fake from "../snippets/fake.mdx";',
|
|
88
|
+
' ```',
|
|
89
|
+
'',
|
|
90
|
+
'import Real from "../snippets/real.mdx";',
|
|
91
|
+
].join('\n');
|
|
92
|
+
const matches = detectRelativeMdxImports(content);
|
|
93
|
+
expect(matches.map((m) => m.specifier)).toEqual(['../snippets/real.mdx']);
|
|
94
|
+
});
|
|
95
|
+
it('detects indented imports outside code blocks (real imports inside list items)', () => {
|
|
96
|
+
// Mintlify allows imports inline in MDX content. An indented import that
|
|
97
|
+
// is NOT inside a fence is still a real import. This exercises the
|
|
98
|
+
// distinction from the previous test.
|
|
99
|
+
const content = [
|
|
100
|
+
'1. Add the snippet:',
|
|
101
|
+
'',
|
|
102
|
+
' import Foo from "../snippets/foo.mdx";',
|
|
103
|
+
'',
|
|
104
|
+
' <Foo />',
|
|
105
|
+
].join('\n');
|
|
106
|
+
const matches = detectRelativeMdxImports(content);
|
|
107
|
+
expect(matches).toHaveLength(1);
|
|
108
|
+
expect(matches[0].specifier).toBe('../snippets/foo.mdx');
|
|
109
|
+
});
|
|
110
|
+
it('detects imports interleaved with markdown content', () => {
|
|
111
|
+
// Real-world: projects/mintlify/folder/relative-snippets-test.mdx has
|
|
112
|
+
// imports after frontmatter AND after markdown content (line 15+).
|
|
113
|
+
const content = [
|
|
114
|
+
'---',
|
|
115
|
+
'title: x',
|
|
116
|
+
'---',
|
|
117
|
+
'',
|
|
118
|
+
'# Heading',
|
|
119
|
+
'',
|
|
120
|
+
'Some prose paragraph.',
|
|
121
|
+
'',
|
|
122
|
+
'import Foo from "../snippets/foo.mdx";',
|
|
123
|
+
'',
|
|
124
|
+
'<Foo />',
|
|
125
|
+
].join('\n');
|
|
126
|
+
const matches = detectRelativeMdxImports(content);
|
|
127
|
+
expect(matches).toHaveLength(1);
|
|
128
|
+
expect(matches[0].line).toBe(9);
|
|
129
|
+
});
|
|
130
|
+
it('handles imports with no semicolon', () => {
|
|
131
|
+
const content = `import Foo from "../snippets/foo.mdx"\n<Foo />`;
|
|
132
|
+
const matches = detectRelativeMdxImports(content);
|
|
133
|
+
expect(matches).toHaveLength(1);
|
|
134
|
+
expect(matches[0].specifier).toBe('../snippets/foo.mdx');
|
|
135
|
+
});
|
|
136
|
+
it('handles type-only imports', () => {
|
|
137
|
+
const content = `import type { Foo } from "../snippets/foo.mdx";`;
|
|
138
|
+
const matches = detectRelativeMdxImports(content);
|
|
139
|
+
expect(matches).toHaveLength(1);
|
|
140
|
+
expect(matches[0].specifier).toBe('../snippets/foo.mdx');
|
|
141
|
+
});
|
|
142
|
+
it('handles CRLF line endings', () => {
|
|
143
|
+
const content = [
|
|
144
|
+
`import Foo from "../snippets/foo.mdx";`,
|
|
145
|
+
`import Bar from "../snippets/bar.mdx";`,
|
|
146
|
+
].join('\r\n');
|
|
147
|
+
const matches = detectRelativeMdxImports(content);
|
|
148
|
+
expect(matches).toHaveLength(2);
|
|
149
|
+
expect(matches.map((m) => m.specifier)).toEqual([
|
|
150
|
+
'../snippets/foo.mdx',
|
|
151
|
+
'../snippets/bar.mdx',
|
|
152
|
+
]);
|
|
153
|
+
});
|
|
154
|
+
it('returns empty array for empty content', () => {
|
|
155
|
+
expect(detectRelativeMdxImports('')).toEqual([]);
|
|
156
|
+
});
|
|
157
|
+
it('returns empty array for frontmatter-only file', () => {
|
|
158
|
+
const content = `---\ntitle: x\n---\n\n# Heading only`;
|
|
159
|
+
expect(detectRelativeMdxImports(content)).toEqual([]);
|
|
160
|
+
});
|
|
161
|
+
it('reports the correct line when prose contains the word "import"', () => {
|
|
162
|
+
// Regression: the previous regex's lazy `[\s\S]+?` bridge let `\bimport`
|
|
163
|
+
// anchor on the heading word, then span newlines to the real import on
|
|
164
|
+
// line 3 — reporting `line: 1` and producing wrong file:line warnings
|
|
165
|
+
// in `jamdesk validate` / `jamdesk dev`.
|
|
166
|
+
const content = [
|
|
167
|
+
'# How to import snippets',
|
|
168
|
+
'',
|
|
169
|
+
'import Real from "../snippets/real.mdx";',
|
|
170
|
+
].join('\n');
|
|
171
|
+
const matches = detectRelativeMdxImports(content);
|
|
172
|
+
expect(matches).toHaveLength(1);
|
|
173
|
+
expect(matches[0].line).toBe(3);
|
|
174
|
+
expect(matches[0].specifier).toBe('../snippets/real.mdx');
|
|
175
|
+
});
|
|
176
|
+
it('does not collapse adjacent imports when the first is non-parent-relative', () => {
|
|
177
|
+
// Regression: the lazy bridge previously absorbed the entire first import
|
|
178
|
+
// line when its specifier didn't end in .mdx (or wasn't parent-relative),
|
|
179
|
+
// making the second import look like it lived on line 1.
|
|
180
|
+
const content = [
|
|
181
|
+
'import A from "/abs/a.mdx";',
|
|
182
|
+
'import B from "../snippets/b.mdx";',
|
|
183
|
+
].join('\n');
|
|
184
|
+
const matches = detectRelativeMdxImports(content);
|
|
185
|
+
expect(matches).toHaveLength(1);
|
|
186
|
+
expect(matches[0].specifier).toBe('../snippets/b.mdx');
|
|
187
|
+
expect(matches[0].line).toBe(2);
|
|
188
|
+
});
|
|
189
|
+
it('ignores fenced code blocks indented inside numbered list items', () => {
|
|
190
|
+
// Regression: real Mintlify pattern in `create/reusable-snippets.mdx`
|
|
191
|
+
// where a `<CodeGroup>` / numbered-list step opens a fence at column 4+:
|
|
192
|
+
//
|
|
193
|
+
// 1. Step:
|
|
194
|
+
//
|
|
195
|
+
// ```mdx Relative import
|
|
196
|
+
// import Foo from "../shared/foo.mdx";
|
|
197
|
+
// ```
|
|
198
|
+
//
|
|
199
|
+
// The previous indent ceiling of `{0,3}` rejected the open, leaving the
|
|
200
|
+
// import inside as content and producing a false-positive match.
|
|
201
|
+
const content = [
|
|
202
|
+
'1. Step one:',
|
|
203
|
+
'',
|
|
204
|
+
' ```mdx Relative import',
|
|
205
|
+
' import MySnippet from "../shared/my-snippet.mdx";',
|
|
206
|
+
' ```',
|
|
207
|
+
].join('\n');
|
|
208
|
+
expect(detectRelativeMdxImports(content)).toEqual([]);
|
|
209
|
+
});
|
|
210
|
+
it('ignores side-effect imports (no binding)', () => {
|
|
211
|
+
// `import "../snippets/foo.mdx";` is syntactically valid but useless in
|
|
212
|
+
// MDX — you need a binding to render `<Foo />`. Lock in current behavior
|
|
213
|
+
// so a future regex tweak can't silently start matching them.
|
|
214
|
+
const content = `import "../snippets/foo.mdx";`;
|
|
215
|
+
expect(detectRelativeMdxImports(content)).toEqual([]);
|
|
216
|
+
});
|
|
217
|
+
});
|
|
218
|
+
describe('rewriteRelativeMdxImports', () => {
|
|
219
|
+
let projectRoot;
|
|
220
|
+
beforeEach(async () => {
|
|
221
|
+
projectRoot = await mkdtemp(path.join(tmpdir(), 'jd-mdx-rewrite-'));
|
|
222
|
+
await mkdir(path.join(projectRoot, 'snippets'), { recursive: true });
|
|
223
|
+
await writeFile(path.join(projectRoot, 'snippets/foo.mdx'), '# foo');
|
|
224
|
+
await mkdir(path.join(projectRoot, 'folder'), { recursive: true });
|
|
225
|
+
});
|
|
226
|
+
afterEach(async () => {
|
|
227
|
+
await rm(projectRoot, { recursive: true, force: true });
|
|
228
|
+
});
|
|
229
|
+
it('rewrites a parent-relative import that resolves under /snippets/', async () => {
|
|
230
|
+
const content = `import Foo from "../snippets/foo.mdx";\n<Foo />`;
|
|
231
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
232
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
233
|
+
expect(result.content).toBe(`import Foo from "/snippets/foo.mdx";\n<Foo />`);
|
|
234
|
+
expect(result.warnings).toEqual([]);
|
|
235
|
+
expect(result.rewrites).toHaveLength(1);
|
|
236
|
+
});
|
|
237
|
+
it('warns with a specific manual action when target is outside /snippets/', async () => {
|
|
238
|
+
await writeFile(path.join(projectRoot, 'folder/sibling.mdx'), '# sibling');
|
|
239
|
+
const content = `import S from "./sibling.mdx";`;
|
|
240
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
241
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
242
|
+
expect(result.content).toBe(content);
|
|
243
|
+
expect(result.warnings).toHaveLength(1);
|
|
244
|
+
// Warning should name the actual target file and the suggested snippet path
|
|
245
|
+
expect(result.warnings[0]).toContain('folder/sibling.mdx');
|
|
246
|
+
expect(result.warnings[0]).toContain('not under /snippets/');
|
|
247
|
+
expect(result.warnings[0]).toContain('/snippets/sibling.mdx');
|
|
248
|
+
expect(result.warnings[0]).toMatch(/inline its content/);
|
|
249
|
+
expect(result.rewrites).toEqual([]);
|
|
250
|
+
});
|
|
251
|
+
it('warns with actionable text when the target file does not exist anywhere', async () => {
|
|
252
|
+
// Specifier references ../snippets/ghost.mdx and there is no root snippet
|
|
253
|
+
// either — we cannot auto-rewrite. Warning should tell the user to create
|
|
254
|
+
// the snippet or remove the import.
|
|
255
|
+
const content = `import G from "../snippets/ghost.mdx";`;
|
|
256
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
257
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
258
|
+
expect(result.content).toBe(content);
|
|
259
|
+
expect(result.warnings).toHaveLength(1);
|
|
260
|
+
expect(result.warnings[0]).toContain('ghost.mdx');
|
|
261
|
+
expect(result.warnings[0]).toMatch(/target file doesn't exist/);
|
|
262
|
+
expect(result.warnings[0]).toMatch(/create the snippet or remove this import/);
|
|
263
|
+
});
|
|
264
|
+
it('rewrites ../snippets/X from a localized folder when X exists at the project root (Mintlify intent)', async () => {
|
|
265
|
+
// Real Mintlify projects have `import X from "../snippets/foo.mdx"` even
|
|
266
|
+
// in `zh/folder/page.mdx` — Mintlify resolves that to the root snippets
|
|
267
|
+
// dir regardless of the literal path. Migrate should follow that intent
|
|
268
|
+
// when `<root>/snippets/<basename>` exists.
|
|
269
|
+
await writeFile(path.join(projectRoot, 'snippets/foo.mdx'), '# foo');
|
|
270
|
+
await mkdir(path.join(projectRoot, 'zh/folder'), { recursive: true });
|
|
271
|
+
const content = `import Foo from "../snippets/foo.mdx";`;
|
|
272
|
+
const filePath = path.join(projectRoot, 'zh/folder/page.mdx');
|
|
273
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
274
|
+
expect(result.content).toBe(`import Foo from "/snippets/foo.mdx";`);
|
|
275
|
+
expect(result.rewrites).toEqual([{ from: '../snippets/foo.mdx', to: '/snippets/foo.mdx', line: 1 }]);
|
|
276
|
+
expect(result.warnings).toEqual([]);
|
|
277
|
+
});
|
|
278
|
+
it('rewrites ../../snippets/X from a deep localized path (Mintlify intent)', async () => {
|
|
279
|
+
await writeFile(path.join(projectRoot, 'snippets/bar.mdx'), '# bar');
|
|
280
|
+
await mkdir(path.join(projectRoot, 'es/folder/nested'), { recursive: true });
|
|
281
|
+
const content = `import Bar from "../../snippets/bar.mdx";`;
|
|
282
|
+
const filePath = path.join(projectRoot, 'es/folder/nested/page.mdx');
|
|
283
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
284
|
+
expect(result.content).toBe(`import Bar from "/snippets/bar.mdx";`);
|
|
285
|
+
expect(result.rewrites).toHaveLength(1);
|
|
286
|
+
expect(result.warnings).toEqual([]);
|
|
287
|
+
});
|
|
288
|
+
it('is idempotent on already-rewritten content', async () => {
|
|
289
|
+
const content = `import Foo from "/snippets/foo.mdx";`;
|
|
290
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
291
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
292
|
+
expect(result.content).toBe(content);
|
|
293
|
+
expect(result.rewrites).toEqual([]);
|
|
294
|
+
});
|
|
295
|
+
it('handles deep-relative paths', async () => {
|
|
296
|
+
await mkdir(path.join(projectRoot, 'folder/nested'), { recursive: true });
|
|
297
|
+
const content = `import F from "../../snippets/foo.mdx";`;
|
|
298
|
+
const filePath = path.join(projectRoot, 'folder/nested/page.mdx');
|
|
299
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
300
|
+
expect(result.content).toBe(`import F from "/snippets/foo.mdx";`);
|
|
301
|
+
expect(result.rewrites).toHaveLength(1);
|
|
302
|
+
});
|
|
303
|
+
it('rewrites a symlink in /snippets/ pointing outside (we trust the user-declared path)', async () => {
|
|
304
|
+
const { symlink } = await import('node:fs/promises');
|
|
305
|
+
await mkdir(path.join(projectRoot, 'shared'), { recursive: true });
|
|
306
|
+
await writeFile(path.join(projectRoot, 'shared/x.mdx'), '# x');
|
|
307
|
+
await symlink(path.join(projectRoot, 'shared/x.mdx'), path.join(projectRoot, 'snippets/aliased.mdx'));
|
|
308
|
+
const content = `import A from "../snippets/aliased.mdx";`;
|
|
309
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
310
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
311
|
+
expect(result.content).toBe(`import A from "/snippets/aliased.mdx";`);
|
|
312
|
+
expect(result.rewrites).toHaveLength(1);
|
|
313
|
+
});
|
|
314
|
+
it('rewrites multiple imports in one file, preserving each quote style', async () => {
|
|
315
|
+
await writeFile(path.join(projectRoot, 'snippets/a.mdx'), '# a');
|
|
316
|
+
await writeFile(path.join(projectRoot, 'snippets/b.mdx'), '# b');
|
|
317
|
+
const content = [
|
|
318
|
+
`import A from "../snippets/a.mdx";`,
|
|
319
|
+
`import B from '../snippets/b.mdx';`,
|
|
320
|
+
`<A />`,
|
|
321
|
+
`<B />`,
|
|
322
|
+
].join('\n');
|
|
323
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
324
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
325
|
+
expect(result.content).toContain(`import A from "/snippets/a.mdx";`);
|
|
326
|
+
expect(result.content).toContain(`import B from '/snippets/b.mdx';`);
|
|
327
|
+
expect(result.rewrites).toHaveLength(2);
|
|
328
|
+
});
|
|
329
|
+
it('handles mixed: some rewriteable + some warning + some missing', async () => {
|
|
330
|
+
await writeFile(path.join(projectRoot, 'snippets/exists.mdx'), '# x');
|
|
331
|
+
await writeFile(path.join(projectRoot, 'folder/sibling.mdx'), '# s');
|
|
332
|
+
const content = [
|
|
333
|
+
`import OK from "../snippets/exists.mdx";`,
|
|
334
|
+
`import S from "./sibling.mdx";`,
|
|
335
|
+
`import G from "../snippets/ghost.mdx";`,
|
|
336
|
+
].join('\n');
|
|
337
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
338
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
339
|
+
expect(result.content).toContain(`"/snippets/exists.mdx"`);
|
|
340
|
+
expect(result.content).toContain(`"./sibling.mdx"`);
|
|
341
|
+
expect(result.content).toContain(`"../snippets/ghost.mdx"`);
|
|
342
|
+
expect(result.rewrites).toHaveLength(1);
|
|
343
|
+
expect(result.warnings).toHaveLength(2);
|
|
344
|
+
expect(result.warnings.some((w) => /sibling\.mdx/.test(w))).toBe(true);
|
|
345
|
+
expect(result.warnings.some((w) => /ghost\.mdx/.test(w))).toBe(true);
|
|
346
|
+
});
|
|
347
|
+
it('rewrites imports inside subdirectories of /snippets/', async () => {
|
|
348
|
+
await mkdir(path.join(projectRoot, 'snippets/sub'), { recursive: true });
|
|
349
|
+
await writeFile(path.join(projectRoot, 'snippets/sub/foo.mdx'), '# foo');
|
|
350
|
+
const content = `import F from "../snippets/sub/foo.mdx";`;
|
|
351
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
352
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
353
|
+
expect(result.content).toBe(`import F from "/snippets/sub/foo.mdx";`);
|
|
354
|
+
});
|
|
355
|
+
it('warns on path traversal attempts that escape projectRoot', async () => {
|
|
356
|
+
const content = `import P from "../../../etc/passwd.mdx";`;
|
|
357
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
358
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
359
|
+
expect(result.content).toBe(content);
|
|
360
|
+
expect(result.rewrites).toEqual([]);
|
|
361
|
+
expect(result.warnings).toHaveLength(1);
|
|
362
|
+
});
|
|
363
|
+
it('does not rewrite imports inside fenced code blocks', async () => {
|
|
364
|
+
await writeFile(path.join(projectRoot, 'snippets/foo.mdx'), '# foo');
|
|
365
|
+
const content = [
|
|
366
|
+
'# Docs',
|
|
367
|
+
'',
|
|
368
|
+
'```mdx',
|
|
369
|
+
'import Doc from "../snippets/foo.mdx";',
|
|
370
|
+
'```',
|
|
371
|
+
].join('\n');
|
|
372
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
373
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
374
|
+
expect(result.content).toBe(content);
|
|
375
|
+
expect(result.rewrites).toEqual([]);
|
|
376
|
+
expect(result.warnings).toEqual([]);
|
|
377
|
+
});
|
|
378
|
+
it('handles multi-line named imports', async () => {
|
|
379
|
+
await writeFile(path.join(projectRoot, 'snippets/components.mdx'), '# c');
|
|
380
|
+
const content = [
|
|
381
|
+
'import {',
|
|
382
|
+
' Foo,',
|
|
383
|
+
' Bar,',
|
|
384
|
+
'} from "../snippets/components.mdx";',
|
|
385
|
+
].join('\n');
|
|
386
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
387
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
388
|
+
expect(result.content).toContain('"/snippets/components.mdx"');
|
|
389
|
+
expect(result.rewrites).toHaveLength(1);
|
|
390
|
+
expect(result.content.split('\n').length).toBe(content.split('\n').length);
|
|
391
|
+
});
|
|
392
|
+
it('resume-after-partial: rewrites a sibling import whose target was already moved to /snippets/', async () => {
|
|
393
|
+
// A previous relocate run moved folder/local.mdx → snippets/folder/local.mdx
|
|
394
|
+
// but didn't update this importer (e.g. user manually moved files, or a
|
|
395
|
+
// prior run aborted mid-flight). The rewriter should recover by probing
|
|
396
|
+
// the relocator's destination shape, not just emit "target file doesn't
|
|
397
|
+
// exist".
|
|
398
|
+
await mkdir(path.join(projectRoot, 'snippets/folder'), { recursive: true });
|
|
399
|
+
await writeFile(path.join(projectRoot, 'snippets/folder/local.mdx'), '# moved');
|
|
400
|
+
const content = `import L from "./local.mdx";\n<L />`;
|
|
401
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
402
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
403
|
+
expect(result.content).toBe(`import L from "/snippets/folder/local.mdx";\n<L />`);
|
|
404
|
+
expect(result.rewrites).toEqual([
|
|
405
|
+
{ from: './local.mdx', to: '/snippets/folder/local.mdx', line: 1 },
|
|
406
|
+
]);
|
|
407
|
+
expect(result.warnings).toEqual([]);
|
|
408
|
+
});
|
|
409
|
+
it('resume-after-partial: still warns when neither original nor moved location exists', async () => {
|
|
410
|
+
// No file at folder/ghost.mdx (origin), no file at snippets/folder/ghost.mdx
|
|
411
|
+
// (relocated dest), no file at snippets/ghost.mdx (Mintlify fallback).
|
|
412
|
+
// Rewriter should fall through to the actionable "doesn't exist" warning.
|
|
413
|
+
const content = `import G from "./ghost.mdx";`;
|
|
414
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
415
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
416
|
+
expect(result.rewrites).toEqual([]);
|
|
417
|
+
expect(result.warnings).toHaveLength(1);
|
|
418
|
+
expect(result.warnings[0]).toMatch(/target file doesn't exist/);
|
|
419
|
+
});
|
|
420
|
+
it('warns about a name collision when target is outside /snippets/ but suggested destination already exists', async () => {
|
|
421
|
+
// Both folder/share.mdx (the import target) AND snippets/share.mdx (the
|
|
422
|
+
// suggested destination) exist with different content — telling the
|
|
423
|
+
// user to "move folder/share.mdx → /snippets/share.mdx" would clobber.
|
|
424
|
+
// Warning should explicitly call out the conflict.
|
|
425
|
+
await writeFile(path.join(projectRoot, 'folder/share.mdx'), '# new content');
|
|
426
|
+
await writeFile(path.join(projectRoot, 'snippets/share.mdx'), '# existing different content');
|
|
427
|
+
const content = `import S from "./share.mdx";`;
|
|
428
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
429
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
430
|
+
expect(result.rewrites).toEqual([]);
|
|
431
|
+
expect(result.warnings).toHaveLength(1);
|
|
432
|
+
expect(result.warnings[0]).toContain('already exists with different content');
|
|
433
|
+
expect(result.warnings[0]).toMatch(/Rename one of the files or inline this import/);
|
|
434
|
+
// Must NOT emit the bare "Move the file to ..." advice — it would clobber.
|
|
435
|
+
expect(result.warnings[0]).not.toMatch(/^Move the file to /);
|
|
436
|
+
});
|
|
437
|
+
it('preserves $ in import paths verbatim (no String.replace backreference interpretation)', async () => {
|
|
438
|
+
// `$&`, `$'`, `$`+digit etc. are backreference patterns when passed as the
|
|
439
|
+
// replacement string to String.replace. Filenames containing `$` would
|
|
440
|
+
// silently corrupt the rewritten output if we forget to use a replacer
|
|
441
|
+
// function.
|
|
442
|
+
await writeFile(path.join(projectRoot, 'snippets/foo$bar.mdx'), '# dollarsign');
|
|
443
|
+
const content = `import F from "../snippets/foo$bar.mdx";`;
|
|
444
|
+
const filePath = path.join(projectRoot, 'folder/page.mdx');
|
|
445
|
+
const result = await rewriteRelativeMdxImports(content, filePath, projectRoot);
|
|
446
|
+
expect(result.content).toBe(`import F from "/snippets/foo$bar.mdx";`);
|
|
447
|
+
expect(result.rewrites).toEqual([
|
|
448
|
+
{ from: '../snippets/foo$bar.mdx', to: '/snippets/foo$bar.mdx', line: 1 },
|
|
449
|
+
]);
|
|
450
|
+
});
|
|
451
|
+
});
|
|
452
|
+
//# sourceMappingURL=relative-mdx-imports.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relative-mdx-imports.test.js","sourceRoot":"","sources":["../../../src/__tests__/unit/relative-mdx-imports.test.ts"],"names":[],"mappings":"AAAA,8DAA8D;AAC9D,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,mCAAmC,CAAC;AAE3C,QAAQ,CAAC,0BAA0B,EAAE,GAAG,EAAE;IACxC,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,OAAO,GAAG;YACd,KAAK;YACL,UAAU;YACV,KAAK;YACL,wCAAwC;YACxC,8BAA8B;YAC9B,EAAE;YACF,SAAS;SACV,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAEb,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAElD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,qBAAqB,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;QAChF,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,OAAO,GAAG,sCAAsC,CAAC;QACvD,MAAM,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,OAAO,GAAG,iEAAiE,CAAC;QAClF,MAAM,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,GAAG,EAAE;QACjE,MAAM,OAAO,GAAG;YACd,2CAA2C;YAC3C,oCAAoC;SACrC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,mBAAmB;YACnB,mBAAmB;SACpB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,GAAG,EAAE;QAC1C,MAAM,OAAO,GAAG;YACd,UAAU;YACV,QAAQ;YACR,QAAQ;YACR,sCAAsC;SACvC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;QAChE,iEAAiE;QACjE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iDAAiD,EAAE,GAAG,EAAE;QACzD,uEAAuE;QACvE,mEAAmE;QACnE,uEAAuE;QACvE,MAAM,OAAO,GAAG;YACd,QAAQ;YACR,EAAE;YACF,QAAQ;YACR,0CAA0C;YAC1C,KAAK;YACL,EAAE;YACF,0CAA0C;SAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uDAAuD,EAAE,GAAG,EAAE;QAC/D,MAAM,OAAO,GAAG;YACd,QAAQ;YACR,0CAA0C;YAC1C,KAAK;YACL,0CAA0C;SAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6EAA6E,EAAE,GAAG,EAAE;QACrF,MAAM,OAAO,GAAG;YACd,aAAa;YACb,EAAE;YACF,mCAAmC;YACnC,6CAA6C;YAC7C,QAAQ;YACR,EAAE;YACF,0CAA0C;SAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+EAA+E,EAAE,GAAG,EAAE;QACvF,yEAAyE;QACzE,mEAAmE;QACnE,sCAAsC;QACtC,MAAM,OAAO,GAAG;YACd,qBAAqB;YACrB,EAAE;YACF,2CAA2C;YAC3C,EAAE;YACF,YAAY;SACb,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mDAAmD,EAAE,GAAG,EAAE;QAC3D,sEAAsE;QACtE,mEAAmE;QACnE,MAAM,OAAO,GAAG;YACd,KAAK;YACL,UAAU;YACV,KAAK;YACL,EAAE;YACF,WAAW;YACX,EAAE;YACF,uBAAuB;YACvB,EAAE;YACF,wCAAwC;YACxC,EAAE;YACF,SAAS;SACV,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,GAAG,EAAE;QAC3C,MAAM,OAAO,GAAG,gDAAgD,CAAC;QACjE,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,OAAO,GAAG,iDAAiD,CAAC;QAClE,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,OAAO,GAAG;YACd,wCAAwC;YACxC,wCAAwC;SACzC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QACf,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9C,qBAAqB;YACrB,qBAAqB;SACtB,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,GAAG,EAAE;QAC/C,MAAM,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,OAAO,GAAG,sCAAsC,CAAC;QACvD,MAAM,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,yEAAyE;QACzE,uEAAuE;QACvE,sEAAsE;QACtE,yCAAyC;QACzC,MAAM,OAAO,GAAG;YACd,0BAA0B;YAC1B,EAAE;YACF,0CAA0C;SAC3C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,GAAG,EAAE;QAClF,0EAA0E;QAC1E,0EAA0E;QAC1E,yDAAyD;QACzD,MAAM,OAAO,GAAG;YACd,6BAA6B;YAC7B,oCAAoC;SACrC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,OAAO,GAAG,wBAAwB,CAAC,OAAO,CAAC,CAAC;QAClD,MAAM,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAChC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACvD,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gEAAgE,EAAE,GAAG,EAAE;QACxE,sEAAsE;QACtE,yEAAyE;QACzE,EAAE;QACF,eAAe;QACf,EAAE;QACF,iCAAiC;QACjC,+CAA+C;QAC/C,cAAc;QACd,EAAE;QACF,wEAAwE;QACxE,iEAAiE;QACjE,MAAM,OAAO,GAAG;YACd,cAAc;YACd,EAAE;YACF,4BAA4B;YAC5B,uDAAuD;YACvD,SAAS;SACV,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0CAA0C,EAAE,GAAG,EAAE;QAClD,wEAAwE;QACxE,yEAAyE;QACzE,8DAA8D;QAC9D,MAAM,OAAO,GAAG,+BAA+B,CAAC;QAChD,MAAM,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,2BAA2B,EAAE,GAAG,EAAE;IACzC,IAAI,WAAmB,CAAC;IAExB,UAAU,CAAC,KAAK,IAAI,EAAE;QACpB,WAAW,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;QACpE,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACrE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC,CAAC;QACrE,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,KAAK,IAAI,EAAE;QACnB,MAAM,EAAE,CAAC,WAAW,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,MAAM,OAAO,GAAG,iDAAiD,CAAC;QAClE,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,+CAA+C,CAAC,CAAC;QAC7E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,oBAAoB,CAAC,EAAE,WAAW,CAAC,CAAC;QAC3E,MAAM,OAAO,GAAG,gCAAgC,CAAC;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,4EAA4E;QAC5E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,oBAAoB,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,uBAAuB,CAAC,CAAC;QAC9D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;QACzD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yEAAyE,EAAE,KAAK,IAAI,EAAE;QACvF,0EAA0E;QAC1E,0EAA0E;QAC1E,oCAAoC;QACpC,MAAM,OAAO,GAAG,wCAAwC,CAAC;QACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;QAClD,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;QAChE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;IACjF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oGAAoG,EAAE,KAAK,IAAI,EAAE;QAClH,yEAAyE;QACzE,wEAAwE;QACxE,wEAAwE;QACxE,4CAA4C;QAC5C,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC,CAAC;QACrE,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtE,MAAM,OAAO,GAAG,wCAAwC,CAAC;QACzD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,oBAAoB,CAAC,CAAC;QAE9D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAE,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QACrG,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wEAAwE,EAAE,KAAK,IAAI,EAAE;QACtF,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC,CAAC;QACrE,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7E,MAAM,OAAO,GAAG,2CAA2C,CAAC;QAC5D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,2BAA2B,CAAC,CAAC;QAErE,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;QACpE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,4CAA4C,EAAE,KAAK,IAAI,EAAE;QAC1D,MAAM,OAAO,GAAG,sCAAsC,CAAC;QACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,eAAe,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG,yCAAyC,CAAC;QAC1D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,wBAAwB,CAAC,CAAC;QAElE,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;QAClE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qFAAqF,EAAE,KAAK,IAAI,EAAE;QACnG,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QACrD,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,KAAK,CAAC,CAAC;QAC/D,MAAM,OAAO,CACX,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EACtC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,sBAAsB,CAAC,CAC/C,CAAC;QACF,MAAM,OAAO,GAAG,0CAA0C,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACtE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oEAAoE,EAAE,KAAK,IAAI,EAAE;QAClF,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,EAAE,KAAK,CAAC,CAAC;QACjE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,gBAAgB,CAAC,EAAE,KAAK,CAAC,CAAC;QACjE,MAAM,OAAO,GAAG;YACd,oCAAoC;YACpC,oCAAoC;YACpC,OAAO;YACP,OAAO;SACR,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,kCAAkC,CAAC,CAAC;QACrE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+DAA+D,EAAE,KAAK,IAAI,EAAE;QAC7E,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC,EAAE,KAAK,CAAC,CAAC;QACtE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,oBAAoB,CAAC,EAAE,KAAK,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG;YACd,0CAA0C;YAC1C,gCAAgC;YAChC,wCAAwC;SACzC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QAC3D,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QACpD,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,yBAAyB,CAAC,CAAC;QAC5D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sDAAsD,EAAE,KAAK,IAAI,EAAE;QACpE,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,cAAc,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,sBAAsB,CAAC,EAAE,OAAO,CAAC,CAAC;QACzE,MAAM,OAAO,GAAG,0CAA0C,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0DAA0D,EAAE,KAAK,IAAI,EAAE;QACxE,MAAM,OAAO,GAAG,0CAA0C,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAC1C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oDAAoD,EAAE,KAAK,IAAI,EAAE;QAClE,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC,CAAC;QACrE,MAAM,OAAO,GAAG;YACd,QAAQ;YACR,EAAE;YACF,QAAQ;YACR,wCAAwC;YACxC,KAAK;SACN,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kCAAkC,EAAE,KAAK,IAAI,EAAE;QAChD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,yBAAyB,CAAC,EAAE,KAAK,CAAC,CAAC;QAC1E,MAAM,OAAO,GAAG;YACd,UAAU;YACV,QAAQ;YACR,QAAQ;YACR,sCAAsC;SACvC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACb,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC;QAC/D,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;IAC7E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8FAA8F,EAAE,KAAK,IAAI,EAAE;QAC5G,6EAA6E;QAC7E,wEAAwE;QACxE,wEAAwE;QACxE,wEAAwE;QACxE,UAAU;QACV,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC5E,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,2BAA2B,CAAC,EAAE,SAAS,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,qCAAqC,CAAC;QACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC;QAClF,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;YAC9B,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,4BAA4B,EAAE,IAAI,EAAE,CAAC,EAAE;SACnE,CAAC,CAAC;QACH,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mFAAmF,EAAE,KAAK,IAAI,EAAE;QACjG,6EAA6E;QAC7E,uEAAuE;QACvE,0EAA0E;QAC1E,MAAM,OAAO,GAAG,8BAA8B,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,2BAA2B,CAAC,CAAC;IAClE,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yGAAyG,EAAE,KAAK,IAAI,EAAE;QACvH,wEAAwE;QACxE,oEAAoE;QACpE,uEAAuE;QACvE,mDAAmD;QACnD,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,kBAAkB,CAAC,EAAE,eAAe,CAAC,CAAC;QAC7E,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,oBAAoB,CAAC,EAAE,8BAA8B,CAAC,CAAC;QAC9F,MAAM,OAAO,GAAG,8BAA8B,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACpC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,uCAAuC,CAAC,CAAC;QAC9E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,+CAA+C,CAAC,CAAC;QACpF,2EAA2E;QAC3E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uFAAuF,EAAE,KAAK,IAAI,EAAE;QACrG,2EAA2E;QAC3E,uEAAuE;QACvE,uEAAuE;QACvE,YAAY;QACZ,MAAM,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,sBAAsB,CAAC,EAAE,cAAc,CAAC,CAAC;QAChF,MAAM,OAAO,GAAG,0CAA0C,CAAC;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,iBAAiB,CAAC,CAAC;QAE3D,MAAM,MAAM,GAAG,MAAM,yBAAyB,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAE/E,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,wCAAwC,CAAC,CAAC;QACtE,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC;YAC9B,EAAE,IAAI,EAAE,yBAAyB,EAAE,EAAE,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAC,EAAE;SAC1E,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"relocate-snippets.test.d.ts","sourceRoot":"","sources":["../../../src/__tests__/unit/relocate-snippets.test.ts"],"names":[],"mappings":""}
|