@libs-ui/components-preview-text-data 0.2.357-2 → 0.2.357-21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +327 -187
- package/editor/editor-completions.d.ts +8 -0
- package/editor/editor-forbidden.d.ts +8 -0
- package/editor/editor-height.d.ts +21 -0
- package/esm2022/editor/editor-completions.mjs +36 -0
- package/esm2022/editor/editor-forbidden.mjs +65 -0
- package/esm2022/editor/editor-height.mjs +136 -0
- package/esm2022/linters/js-linter.mjs +348 -0
- package/esm2022/linters/json-linter.mjs +14 -0
- package/esm2022/linters/linter-shared.mjs +8 -0
- package/esm2022/linters/python-linter.mjs +52 -0
- package/esm2022/linters/sql-linter.mjs +34 -0
- package/esm2022/preview-text-data.component.mjs +43 -319
- package/esm2022/preview-text-data.define.mjs +13 -1
- package/esm2022/preview-text-data.type.mjs +2 -0
- package/fesm2022/libs-ui-components-preview-text-data.mjs +733 -320
- package/fesm2022/libs-ui-components-preview-text-data.mjs.map +1 -1
- package/linters/js-linter.d.ts +45 -0
- package/linters/json-linter.d.ts +4 -0
- package/linters/linter-shared.d.ts +3 -0
- package/linters/python-linter.d.ts +4 -0
- package/linters/sql-linter.d.ts +4 -0
- package/package.json +9 -7
- package/preview-text-data.component.d.ts +20 -35
- package/preview-text-data.define.d.ts +12 -0
- package/preview-text-data.type.d.ts +33 -0
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import { get } from '@libs-ui/utils';
|
|
2
|
+
import { astSkipKeys, astTypeKeys, tsValueNodes } from '../preview-text-data.define';
|
|
3
|
+
import { getTokenBefore } from './linter-shared';
|
|
4
|
+
// Cache module-level (chia sẻ giữa các instance editor) — đều immutable, lazy-load 1 lần.
|
|
5
|
+
let babelParserModule;
|
|
6
|
+
let knownGlobalsSet;
|
|
7
|
+
/** Lazy-load + cache module @babel/parser (chỉ tải lần đầu khi lint JS/TS). */
|
|
8
|
+
const getBabelParser = async () => {
|
|
9
|
+
if (!babelParserModule) {
|
|
10
|
+
babelParserModule = await import('@babel/parser');
|
|
11
|
+
}
|
|
12
|
+
return babelParserModule;
|
|
13
|
+
};
|
|
14
|
+
/** Lazy-load + cache tập biến toàn cục JS/DOM hợp lệ từ package `globals` (JSON thuần, browser-safe). */
|
|
15
|
+
const getKnownGlobals = async () => {
|
|
16
|
+
if (!knownGlobalsSet) {
|
|
17
|
+
const globalsModule = (await import('globals'));
|
|
18
|
+
const globalsData = (globalsModule.default ?? globalsModule);
|
|
19
|
+
knownGlobalsSet = new Set([...Object.keys(globalsData['builtin'] ?? {}), ...Object.keys(globalsData['browser'] ?? {}), ...Object.keys(globalsData['es2021'] ?? {})]);
|
|
20
|
+
}
|
|
21
|
+
return knownGlobalsSet;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Parse code, trả về vừa danh sách lỗi cú pháp vừa AST (nếu parse sạch).
|
|
25
|
+
* `errorRecovery` gom nhiều lỗi vào `result.errors`; lỗi nặng vẫn `throw` → bắt thêm ở catch.
|
|
26
|
+
*/
|
|
27
|
+
export const parseJs = (parser, code) => {
|
|
28
|
+
try {
|
|
29
|
+
const result = parser.parse(code, {
|
|
30
|
+
sourceType: 'module',
|
|
31
|
+
errorRecovery: true,
|
|
32
|
+
plugins: ['typescript', 'jsx'],
|
|
33
|
+
allowReturnOutsideFunction: true,
|
|
34
|
+
allowAwaitOutsideFunction: true,
|
|
35
|
+
allowImportExportEverywhere: true,
|
|
36
|
+
allowSuperOutsideMethod: true,
|
|
37
|
+
allowNewTargetOutsideFunction: true,
|
|
38
|
+
allowUndeclaredExports: true,
|
|
39
|
+
});
|
|
40
|
+
return { errors: result.errors, ast: result };
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
const loc = get(error, 'loc');
|
|
44
|
+
const message = get(error, 'message') || 'JavaScript syntax error';
|
|
45
|
+
return { errors: [{ loc, message }] };
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
/** Giữ cho test/back-compat: chỉ lấy danh sách lỗi cú pháp. */
|
|
49
|
+
export const collectBabelErrors = (parser, code) => parseJs(parser, code).errors;
|
|
50
|
+
/**
|
|
51
|
+
* Quét text từng dòng, flag dấu "." cuối dòng (incomplete property access) tại ĐÚNG vị trí dấu chấm.
|
|
52
|
+
* Thu thập `taintedLines` (dòng có trailing dot) + `dotPositions` (offset dấu chấm để vá khi parse).
|
|
53
|
+
*/
|
|
54
|
+
export const collectTrailingDotDiagnostics = (doc, diagnostics, taintedLines, dotPositions) => {
|
|
55
|
+
for (let lineNumber = 1; lineNumber <= doc.lines; lineNumber++) {
|
|
56
|
+
const line = doc.line(lineNumber);
|
|
57
|
+
const trimmed = line.text.trimEnd();
|
|
58
|
+
const match = /(\w+)\.\s*$/.exec(trimmed);
|
|
59
|
+
if (!match) {
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
taintedLines.add(lineNumber);
|
|
63
|
+
const dotPosition = line.from + trimmed.lastIndexOf('.');
|
|
64
|
+
dotPositions.push(dotPosition);
|
|
65
|
+
diagnostics.push({ from: dotPosition, to: dotPosition + 1, severity: 'error', message: `Incomplete property access on "${match[1]}"` });
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
/** Thay các ký tự tại `positions` bằng space, giữ nguyên độ dài chuỗi (để offset không đổi). */
|
|
69
|
+
const replaceCharsWithSpace = (code, positions) => {
|
|
70
|
+
if (!positions.length) {
|
|
71
|
+
return code;
|
|
72
|
+
}
|
|
73
|
+
const chars = code.split('');
|
|
74
|
+
for (const position of positions) {
|
|
75
|
+
if (position >= 0 && position < chars.length) {
|
|
76
|
+
chars[position] = ' ';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return chars.join('');
|
|
80
|
+
};
|
|
81
|
+
/** VariableDeclaration ở `for(let i=0;...)` / `for..in` / `for..of` KHÔNG cần `;` cuối. */
|
|
82
|
+
const requiresSemicolon = (nodeType, parentType, keyInParent) => {
|
|
83
|
+
if (nodeType === 'VariableDeclaration') {
|
|
84
|
+
if (parentType === 'ForStatement' && keyInParent === 'init')
|
|
85
|
+
return false;
|
|
86
|
+
if ((parentType === 'ForInStatement' || parentType === 'ForOfStatement') && keyInParent === 'left')
|
|
87
|
+
return false;
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* Rule custom "require semicolon": câu lệnh (const/let/return/expression...) không kết thúc bằng `;` → báo lỗi.
|
|
93
|
+
* Dùng vị trí `node.end` của AST babel; bỏ qua dòng tainted (trailing dot) để không chồng lỗi.
|
|
94
|
+
*/
|
|
95
|
+
export const collectMissingSemicolonDiagnostics = (ast, code, diagnostics, taintedLines) => {
|
|
96
|
+
const semiNodes = new Set(['ExpressionStatement', 'VariableDeclaration', 'ReturnStatement', 'ThrowStatement', 'BreakStatement', 'ContinueStatement', 'DoWhileStatement', 'DebuggerStatement']);
|
|
97
|
+
const seen = new Set();
|
|
98
|
+
const lineOf = (offset) => code.slice(0, offset).split('\n').length;
|
|
99
|
+
const walk = (node, parentType, keyInParent) => {
|
|
100
|
+
if (Array.isArray(node)) {
|
|
101
|
+
for (const item of node)
|
|
102
|
+
walk(item, parentType, keyInParent);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (!node || typeof node !== 'object')
|
|
106
|
+
return;
|
|
107
|
+
const current = node;
|
|
108
|
+
if (typeof current.type !== 'string')
|
|
109
|
+
return;
|
|
110
|
+
if (semiNodes.has(current.type) && requiresSemicolon(current.type, parentType, keyInParent) && typeof current.end === 'number') {
|
|
111
|
+
const end = Math.min(current.end, code.length);
|
|
112
|
+
if (end > 0 && code.charAt(end - 1) !== ';' && !seen.has(end) && !taintedLines.has(lineOf(end - 1))) {
|
|
113
|
+
seen.add(end);
|
|
114
|
+
diagnostics.push({ from: end - 1, to: end, severity: 'error', message: 'Missing semicolon' });
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
for (const childKey of Object.keys(current)) {
|
|
118
|
+
if (astSkipKeys.has(childKey))
|
|
119
|
+
continue;
|
|
120
|
+
walk(current[childKey], current.type, childKey);
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
walk(ast.program ?? ast, '', '');
|
|
124
|
+
};
|
|
125
|
+
/** Chuẩn hóa message: thân thiện cho trailing dot + heuristic kiểu cũ cho "Unexpected token"; bỏ hậu tố "(line:col)". */
|
|
126
|
+
export const buildJsErrorMessage = (doc, from, rawMessage) => {
|
|
127
|
+
const charBefore = from > 0 ? doc.sliceString(from - 1, from) : '';
|
|
128
|
+
if (charBefore === '.') {
|
|
129
|
+
const owner = getTokenBefore(doc, from).replace(/\.$/, '');
|
|
130
|
+
return owner ? `Incomplete property access on "${owner}"` : 'Incomplete property access';
|
|
131
|
+
}
|
|
132
|
+
const cleaned = rawMessage.replace(/\s*\(\d+:\d+\)\s*$/, '').trim();
|
|
133
|
+
if (/missing semicolon/i.test(cleaned)) {
|
|
134
|
+
return 'Unexpected token — missing operator or separator between expressions';
|
|
135
|
+
}
|
|
136
|
+
if (/^unexpected token$/i.test(cleaned)) {
|
|
137
|
+
const prevToken = getTokenBefore(doc, from);
|
|
138
|
+
if (prevToken.endsWith('('))
|
|
139
|
+
return 'Missing closing ")"';
|
|
140
|
+
if (prevToken.endsWith('['))
|
|
141
|
+
return 'Missing closing "]"';
|
|
142
|
+
if (/^function$/i.test(prevToken))
|
|
143
|
+
return 'Expected function name or "("';
|
|
144
|
+
if (/^return$/i.test(prevToken))
|
|
145
|
+
return 'Invalid expression after "return"';
|
|
146
|
+
if (/^=>$/.test(prevToken))
|
|
147
|
+
return 'Expected function body after "=>"';
|
|
148
|
+
if (/^const$|^let$|^var$/i.test(prevToken))
|
|
149
|
+
return 'Expected variable name';
|
|
150
|
+
}
|
|
151
|
+
return `JavaScript syntax error: ${cleaned}`;
|
|
152
|
+
};
|
|
153
|
+
/** Lấy tên binding từ pattern (Identifier, destructuring object/array, default, rest). */
|
|
154
|
+
const collectPatternNames = (node, declared) => {
|
|
155
|
+
if (!node || typeof node.type !== 'string')
|
|
156
|
+
return;
|
|
157
|
+
switch (node.type) {
|
|
158
|
+
case 'Identifier':
|
|
159
|
+
if (node.name)
|
|
160
|
+
declared.add(node.name);
|
|
161
|
+
return;
|
|
162
|
+
case 'ObjectPattern':
|
|
163
|
+
if (node.properties)
|
|
164
|
+
for (const property of node.properties)
|
|
165
|
+
collectPatternNames(property.type === 'RestElement' ? property.argument : property.value, declared);
|
|
166
|
+
return;
|
|
167
|
+
case 'ArrayPattern':
|
|
168
|
+
if (node.elements)
|
|
169
|
+
for (const element of node.elements)
|
|
170
|
+
collectPatternNames(element, declared);
|
|
171
|
+
return;
|
|
172
|
+
case 'AssignmentPattern':
|
|
173
|
+
collectPatternNames(node.left, declared);
|
|
174
|
+
return;
|
|
175
|
+
case 'RestElement':
|
|
176
|
+
collectPatternNames(node.argument, declared);
|
|
177
|
+
return;
|
|
178
|
+
case 'TSParameterProperty':
|
|
179
|
+
collectPatternNames(node.parameter, declared);
|
|
180
|
+
return;
|
|
181
|
+
default:
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
/** Thu thập tên binding (biến/hàm/class/param/import/enum...) từ 1 node vào tập `declared`. */
|
|
186
|
+
const collectBindingNames = (node, declared) => {
|
|
187
|
+
switch (node.type) {
|
|
188
|
+
case 'VariableDeclarator':
|
|
189
|
+
collectPatternNames(node.id, declared);
|
|
190
|
+
return;
|
|
191
|
+
case 'FunctionDeclaration':
|
|
192
|
+
case 'FunctionExpression':
|
|
193
|
+
case 'ClassDeclaration':
|
|
194
|
+
case 'ClassExpression':
|
|
195
|
+
if (node.id?.name)
|
|
196
|
+
declared.add(node.id.name);
|
|
197
|
+
if (node.params)
|
|
198
|
+
for (const param of node.params)
|
|
199
|
+
collectPatternNames(param, declared);
|
|
200
|
+
return;
|
|
201
|
+
case 'ArrowFunctionExpression':
|
|
202
|
+
if (node.params)
|
|
203
|
+
for (const param of node.params)
|
|
204
|
+
collectPatternNames(param, declared);
|
|
205
|
+
return;
|
|
206
|
+
case 'CatchClause':
|
|
207
|
+
collectPatternNames(node.param, declared);
|
|
208
|
+
return;
|
|
209
|
+
case 'ImportDefaultSpecifier':
|
|
210
|
+
case 'ImportNamespaceSpecifier':
|
|
211
|
+
case 'ImportSpecifier':
|
|
212
|
+
if (node.local?.name)
|
|
213
|
+
declared.add(node.local.name);
|
|
214
|
+
return;
|
|
215
|
+
case 'TSEnumDeclaration':
|
|
216
|
+
case 'TSModuleDeclaration':
|
|
217
|
+
if (node.id?.name)
|
|
218
|
+
declared.add(node.id.name);
|
|
219
|
+
return;
|
|
220
|
+
default:
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
/** Xác định 1 Identifier có phải tham chiếu giá trị không (loại property access, key object, declaration id, label...). */
|
|
225
|
+
const isReferenceIdentifier = (parent, keyInParent) => {
|
|
226
|
+
if (!parent)
|
|
227
|
+
return true;
|
|
228
|
+
const parentType = parent.type;
|
|
229
|
+
if ((parentType === 'MemberExpression' || parentType === 'OptionalMemberExpression') && keyInParent === 'property' && !parent.computed)
|
|
230
|
+
return false;
|
|
231
|
+
if ((parentType === 'ObjectProperty' || parentType === 'ObjectMethod' || parentType === 'ClassMethod' || parentType === 'ClassProperty' || parentType === 'ClassPrivateProperty' || parentType === 'PropertyDefinition') && keyInParent === 'key' && !parent.computed)
|
|
232
|
+
return false;
|
|
233
|
+
if (keyInParent === 'label')
|
|
234
|
+
return false;
|
|
235
|
+
if (parentType === 'TSQualifiedName' && keyInParent === 'right')
|
|
236
|
+
return false;
|
|
237
|
+
if (parentType === 'VariableDeclarator' && keyInParent === 'id')
|
|
238
|
+
return false;
|
|
239
|
+
if ((parentType === 'FunctionDeclaration' || parentType === 'FunctionExpression' || parentType === 'ClassDeclaration' || parentType === 'ClassExpression') && keyInParent === 'id')
|
|
240
|
+
return false;
|
|
241
|
+
if (parentType === 'ImportSpecifier' || parentType === 'ImportDefaultSpecifier' || parentType === 'ImportNamespaceSpecifier' || parentType === 'ExportSpecifier')
|
|
242
|
+
return false;
|
|
243
|
+
if (parentType === 'MetaProperty')
|
|
244
|
+
return false;
|
|
245
|
+
if (parentType === 'TSEnumMember' && keyInParent === 'id')
|
|
246
|
+
return false;
|
|
247
|
+
return true;
|
|
248
|
+
};
|
|
249
|
+
/** Duyệt đệ quy AST: gom binding name vào `declared`, gom identifier tham chiếu vào `references`. */
|
|
250
|
+
const walkAstNode = (node, parent, keyInParent, inType, declared, references) => {
|
|
251
|
+
if (Array.isArray(node)) {
|
|
252
|
+
for (const item of node)
|
|
253
|
+
walkAstNode(item, parent, keyInParent, inType, declared, references);
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
if (!node || typeof node !== 'object')
|
|
257
|
+
return;
|
|
258
|
+
const current = node;
|
|
259
|
+
if (typeof current.type !== 'string')
|
|
260
|
+
return;
|
|
261
|
+
collectBindingNames(current, declared);
|
|
262
|
+
if (current.type === 'Identifier' && !inType && isReferenceIdentifier(parent, keyInParent)) {
|
|
263
|
+
const start = current.loc?.start;
|
|
264
|
+
if (current.name && start)
|
|
265
|
+
references.push({ name: current.name, line: start.line, column: start.column });
|
|
266
|
+
}
|
|
267
|
+
const opensType = inType || (current.type.startsWith('TS') && !tsValueNodes.has(current.type));
|
|
268
|
+
for (const childKey of Object.keys(current)) {
|
|
269
|
+
if (astSkipKeys.has(childKey))
|
|
270
|
+
continue;
|
|
271
|
+
const child = current[childKey];
|
|
272
|
+
const childOpensType = typeof child === 'object' && child !== null && typeof child.type === 'string' && child.type.startsWith('TS') && !tsValueNodes.has(child.type);
|
|
273
|
+
const childInType = opensType || astTypeKeys.has(childKey) || childOpensType;
|
|
274
|
+
walkAstNode(child, current, childKey, childInType, declared, references);
|
|
275
|
+
}
|
|
276
|
+
};
|
|
277
|
+
/**
|
|
278
|
+
* Pass ngữ nghĩa: báo biến CHƯA KHAI BÁO. Tự duyệt AST (object thuần) — KHÔNG dùng `@babel/traverse`
|
|
279
|
+
* (cần `process` của Node → crash browser). Hợp lệ = binding trong code + global JS/DOM + `completionLabels`.
|
|
280
|
+
*/
|
|
281
|
+
export const collectUndeclaredIdentifiers = async (ast, doc, completionLabels, taintedLines = new Set()) => {
|
|
282
|
+
const globalsSet = await getKnownGlobals();
|
|
283
|
+
const declared = new Set();
|
|
284
|
+
const references = [];
|
|
285
|
+
walkAstNode(ast, null, '', false, declared, references);
|
|
286
|
+
const diagnostics = [];
|
|
287
|
+
const seen = new Set();
|
|
288
|
+
for (const reference of references) {
|
|
289
|
+
const { name, line: startLine, column: startColumn } = reference;
|
|
290
|
+
if (declared.has(name) || globalsSet.has(name) || completionLabels.has(name))
|
|
291
|
+
continue;
|
|
292
|
+
if (taintedLines.has(startLine))
|
|
293
|
+
continue;
|
|
294
|
+
const dedupeKey = `${startLine}:${startColumn}:${name}`;
|
|
295
|
+
if (seen.has(dedupeKey))
|
|
296
|
+
continue;
|
|
297
|
+
seen.add(dedupeKey);
|
|
298
|
+
const line = doc.line(Math.min(Math.max(startLine, 1), doc.lines));
|
|
299
|
+
const from = Math.min(line.from + Math.max(startColumn, 0), doc.length);
|
|
300
|
+
const to = Math.min(from + name.length, doc.length);
|
|
301
|
+
diagnostics.push({ from, to: Math.max(from + 1, to), severity: 'error', message: `"${name}" is not defined` });
|
|
302
|
+
}
|
|
303
|
+
return diagnostics;
|
|
304
|
+
};
|
|
305
|
+
/**
|
|
306
|
+
* Toàn bộ pipeline validate JS/TS:
|
|
307
|
+
* - Pass 1: trailing dot (text) — flag đúng vị trí dấu `.` cuối dòng + đánh dấu dòng tainted.
|
|
308
|
+
* - Pass 2: lỗi cú pháp babel — bỏ lỗi trên dòng tainted (cascading).
|
|
309
|
+
* - Pass 3: rule cần AST (thiếu `;`, biến chưa khai báo). Trailing dot được "vá" (`.`→space) để babel
|
|
310
|
+
* vẫn parse được phần còn lại → rule vẫn chạy cho các dòng KHÁC.
|
|
311
|
+
*/
|
|
312
|
+
export const computeJsDiagnostics = async (doc, code, completionLabels) => {
|
|
313
|
+
const diagnostics = [];
|
|
314
|
+
if (code.trim() === '') {
|
|
315
|
+
return diagnostics;
|
|
316
|
+
}
|
|
317
|
+
const taintedLines = new Set();
|
|
318
|
+
const dotPositions = [];
|
|
319
|
+
collectTrailingDotDiagnostics(doc, diagnostics, taintedLines, dotPositions);
|
|
320
|
+
const parseCode = replaceCharsWithSpace(code, dotPositions);
|
|
321
|
+
const parser = await getBabelParser();
|
|
322
|
+
const { errors, ast } = parseJs(parser, parseCode);
|
|
323
|
+
const seen = new Set();
|
|
324
|
+
for (const error of errors) {
|
|
325
|
+
const location = error.loc;
|
|
326
|
+
if (!location)
|
|
327
|
+
continue;
|
|
328
|
+
const lineNumber = Math.min(Math.max(location.line, 1), doc.lines);
|
|
329
|
+
if (taintedLines.has(lineNumber))
|
|
330
|
+
continue;
|
|
331
|
+
const line = doc.line(lineNumber);
|
|
332
|
+
const errorPos = Math.min(line.from + Math.max(location.column, 0), doc.length);
|
|
333
|
+
const to = Math.min(errorPos + 1, doc.length);
|
|
334
|
+
const from = errorPos >= to && errorPos > 0 ? errorPos - 1 : errorPos;
|
|
335
|
+
const message = buildJsErrorMessage(doc, errorPos, error.message);
|
|
336
|
+
const dedupeKey = `${from}:${message}`;
|
|
337
|
+
if (seen.has(dedupeKey))
|
|
338
|
+
continue;
|
|
339
|
+
seen.add(dedupeKey);
|
|
340
|
+
diagnostics.push({ from, to: Math.max(from + 1, to), severity: 'error', message });
|
|
341
|
+
}
|
|
342
|
+
if (errors.length === 0 && ast) {
|
|
343
|
+
collectMissingSemicolonDiagnostics(ast, code, diagnostics, taintedLines);
|
|
344
|
+
diagnostics.push(...(await collectUndeclaredIdentifiers(ast, doc, completionLabels, taintedLines)));
|
|
345
|
+
}
|
|
346
|
+
return diagnostics;
|
|
347
|
+
};
|
|
348
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianMtbGludGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy11aS9jb21wb25lbnRzL3ByZXZpZXctdGV4dC1kYXRhL3NyYy9saW50ZXJzL2pzLWxpbnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFFQSxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDckMsT0FBTyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUUsWUFBWSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFckYsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBS2pELDBGQUEwRjtBQUMxRixJQUFJLGlCQUE2RCxDQUFDO0FBQ2xFLElBQUksZUFBd0MsQ0FBQztBQUU3QywrRUFBK0U7QUFDL0UsTUFBTSxjQUFjLEdBQUcsS0FBSyxJQUE2QyxFQUFFO0lBQ3pFLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1FBQ3ZCLGlCQUFpQixHQUFHLE1BQU0sTUFBTSxDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3BELENBQUM7SUFDRCxPQUFPLGlCQUFpQixDQUFDO0FBQzNCLENBQUMsQ0FBQztBQUVGLHlHQUF5RztBQUN6RyxNQUFNLGVBQWUsR0FBRyxLQUFLLElBQTBCLEVBQUU7SUFDdkQsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1FBQ3JCLE1BQU0sYUFBYSxHQUFHLENBQUMsTUFBTSxNQUFNLENBQUMsU0FBUyxDQUFDLENBQXFFLENBQUM7UUFDcEgsTUFBTSxXQUFXLEdBQUcsQ0FBQyxhQUFhLENBQUMsT0FBTyxJQUFJLGFBQWEsQ0FBNEMsQ0FBQztRQUN4RyxlQUFlLEdBQUcsSUFBSSxHQUFHLENBQVMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxD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QUFPLEVBQUUsQ0FBQztRQUN2QyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsU0FBUyxDQUFDO1lBQUUsU0FBUztRQUNsQyxJQUFJLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3BCLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxHQUFHLENBQUMsRUFBRSxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDLENBQUM7SUFDckYsQ0FBQztJQUVELElBQUksTUFBTSxDQUFDLE1BQU0sS0FBSyxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7UUFDL0Isa0NBQWtDLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxXQUFXLEVBQUUsWUFBWSxDQUFDLENBQUM7UUFDekUsV0FBVyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSw0QkFBNEIsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN0RyxDQUFDO0lBRUQsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlhZ25vc3RpYyB9IGZyb20gJ0Bjb2RlbWlycm9yL2xpbnQnO1xuaW1wb3J0IHsgVGV4dCB9IGZyb20gJ0Bjb2RlbWlycm9yL3N0YXRlJztcbmltcG9ydCB7IGdldCB9IGZyb20gJ0BsaWJzLXVpL3V0aWxzJztcbmltcG9ydCB7IGFzdFNraXBLZXlzLCBhc3RUeXBlS2V5cywgdHNWYWx1ZU5vZGVzIH0gZnJvbSAnLi4vcHJldmlldy10ZXh0LWRhdGEuZGVmaW5lJztcbmltcG9ydCB7IFRfQXN0Tm9kZSB9IGZyb20gJy4uL3ByZXZpZXctdGV4dC1kYXRhLnR5cGUnO1xuaW1wb3J0IHsgZ2V0VG9rZW5CZWZvcmUgfSBmcm9tICcuL2xpbnRlci1zaGFyZWQnO1xuXG50eXBlIFRfQmFiZWxFcnJvciA9IHsgbG9jPzogeyBsaW5lOiBudW1iZXI7IGNvbHVtbjogbnVtYmVyIH07IG1lc3NhZ2U6IHN0cmluZyB9O1xudHlwZSBUX0FzdFJlZmVyZW5jZSA9IHsgbmFtZTogc3RyaW5nOyBsaW5lOiBudW1iZXI7IGNvbHVtbjogbnVtYmVyIH07XG5cbi8vIENhY2hlIG1vZHVsZS1sZXZlbCAoY2hpYSBz4bq7IGdp4buvYSBjw6FjIGluc3RhbmNlIGVkaXRvcikg4oCUIMSR4buBdSBpbW11dGFibGUsIGxhenktbG9hZCAxIGzhuqduLlxubGV0IGJhYmVsUGFyc2VyTW9kdWxlOiB0eXBlb2YgaW1wb3J0KCdAYmFiZWwvcGFyc2VyJykgfCB1bmRlZmluZWQ7XG5sZXQga25vd25HbG9iYWxzU2V0OiBTZXQ8c3RyaW5nPiB8IHVuZGVmaW5lZDtcblxuLyoqIExhenktbG9hZCArIGNhY2hlIG1vZHVsZSBAYmFiZWwvcGFyc2VyIChjaOG7iSB04bqjaSBs4bqnbiDEkeG6p3Uga2hpIGxpbnQgSlMvVFMpLiAqL1xuY29uc3QgZ2V0QmFiZWxQYXJzZXIgPSBhc3luYyAoKTogUHJvbWlzZTx0eXBlb2YgaW1wb3J0KCdAYmFiZWwvcGFyc2VyJyk+ID0+IHtcbiAgaWYgKCFiYWJlbFBhcnNlck1vZHVsZSkge1xuICAgIGJhYmVsUGFyc2VyTW9kdWxlID0gYXdhaXQgaW1wb3J0KCdAYmFiZWwvcGFyc2VyJyk7XG4gIH1cbiAgcmV0dXJuIGJhYmVsUGFyc2VyTW9kdWxlO1xufTtcblxuLyoqIExhenktbG9hZCArIGNhY2hlIHThuq1wIGJp4bq/biB0b8OgbiBj4bulYyBKUy9ET00gaOG7o3AgbOG7hyB04burIHBhY2thZ2UgYGdsb2JhbHNgIChKU09OIHRodeG6p24sIGJyb3dzZXItc2FmZSkuICovXG5jb25zdCBnZXRLbm93bkdsb2JhbHMgPSBhc3luYyAoKTogUHJvbWlzZTxTZXQ8c3RyaW5nPj4gPT4ge1xuICBpZiAoIWtub3duR2xvYmFsc1NldCkge1xuICAgIGNvbnN0IGdsb2JhbHNNb2R1bGUgPSAoYXdhaXQgaW1wb3J0KCdnbG9iYWxzJykpIGFzIHVua25vd24gYXMgeyBkZWZhdWx0PzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgYm9vbGVhbj4+IH07XG4gICAgY29uc3QgZ2xvYmFsc0RhdGEgPSAoZ2xvYmFsc01vZHVsZS5kZWZhdWx0ID8/IGdsb2JhbHNNb2R1bGUpIGFzIFJlY29yZDxzdHJpbmcsIFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+PjtcbiAgICBrbm93bkdsb2JhbHNTZXQgPSBuZXcgU2V0PHN0cmluZz4oWy4uLk9iamVjdC5rZXlzKGdsb2JhbHNEYXRhWydidWlsdGluJ10gPz8ge30pLCAuLi5PYmplY3Qua2V5cyhnbG9iYWxzRGF0YVsnYnJvd3NlciddID8/IHt9KSwgLi4uT2JqZWN0LmtleXMoZ2xvYmFsc0RhdGFbJ2VzMjAyMSddID8/IHt9KV0pO1xuICB9XG4gIHJldHVybiBrbm93bkdsb2JhbHNTZXQ7XG59O1xuXG4vKipcbiAqIFBhcnNlIGNvZGUsIHRy4bqjIHbhu4EgduG7q2EgZGFuaCBzw6FjaCBs4buXaSBjw7ogcGjDoXAgduG7q2EgQVNUIChu4bq/dSBwYXJzZSBz4bqhY2gpLlxuICogYGVycm9yUmVjb3ZlcnlgIGdvbSBuaGnhu4F1IGzhu5dpIHbDoG8gYHJlc3VsdC5lcnJvcnNgOyBs4buXaSBu4bq3bmcgduG6q24gYHRocm93YCDihpIgYuG6r3QgdGjDqm0g4bufIGNhdGNoLlxuICovXG5leHBvcnQgY29uc3QgcGFyc2VKcyA9IChwYXJzZXI6IHR5cGVvZiBpbXBvcnQoJ0BiYWJlbC9wYXJzZXInKSwgY29kZTogc3RyaW5nKTogeyBlcnJvcnM6IFRfQmFiZWxFcnJvcltdOyBhc3Q/OiBvYmplY3QgfSA9PiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcmVzdWx0ID0gcGFyc2VyLnBhcnNlKGNvZGUsIHtcbiAgICAgIHNvdXJjZVR5cGU6ICdtb2R1bGUnLFxuICAgICAgZXJyb3JSZWNvdmVyeTogdHJ1ZSxcbiAgICAgIHBsdWdpbnM6IFsndHlwZXNjcmlwdCcsICdqc3gnXSxcbiAgICAgIGFsbG93UmV0dXJuT3V0c2lkZUZ1bmN0aW9uOiB0cnVlLFxuICAgICAgYWxsb3dBd2FpdE91dHNpZGVGdW5jdGlvbjogdHJ1ZSxcbiAgICAgIGFsbG93SW1wb3J0RXhwb3J0RXZlcnl3aGVyZTogdHJ1ZSxcbiAgICAgIGFsbG93U3VwZXJPdXRzaWRlTWV0aG9kOiB0cnVlLFxuICAgICAgYWxsb3dOZXdUYXJnZXRPdXRzaWRlRnVuY3Rpb246IHRydWUsXG4gICAgICBhbGxvd1VuZGVjbGFyZWRFeHBvcnRzOiB0cnVlLFxuICAgIH0pO1xuICAgIHJldHVybiB7IGVycm9yczogcmVzdWx0LmVycm9ycyBhcyBUX0JhYmVsRXJyb3JbXSwgYXN0OiByZXN1bHQgfTtcbiAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICBjb25zdCBsb2MgPSBnZXQoZXJyb3IsICdsb2MnKSBhcyB7IGxpbmU6IG51bWJlcjsgY29sdW1uOiBudW1iZXIgfSB8IHVuZGVmaW5lZDtcbiAgICBjb25zdCBtZXNzYWdlID0gKGdldChlcnJvciwgJ21lc3NhZ2UnKSBhcyBzdHJpbmcpIHx8ICdKYXZhU2NyaXB0IHN5bnRheCBlcnJvcic7XG4gICAgcmV0dXJuIHsgZXJyb3JzOiBbeyBsb2MsIG1lc3NhZ2UgfV0gfTtcbiAgfVxufTtcblxuLyoqIEdp4buvIGNobyB0ZXN0L2JhY2stY29tcGF0OiBjaOG7iSBs4bqleSBkYW5oIHPDoWNoIGzhu5dpIGPDuiBwaMOhcC4gKi9cbmV4cG9ydCBjb25zdCBjb2xsZWN0QmFiZWxFcnJvcnMgPSAocGFyc2VyOiB0eXBlb2YgaW1wb3J0KCdAYmFiZWwvcGFyc2VyJyksIGNvZGU6IHN0cmluZyk6IFRfQmFiZWxFcnJvcltdID0+IHBhcnNlSnMocGFyc2VyLCBjb2RlKS5lcnJvcnM7XG5cbi8qKlxuICogUXXDqXQgdGV4dCB04burbmcgZMOybmcsIGZsYWcgZOG6pXUgXCIuXCIgY3Xhu5FpIGTDsm5nIChpbmNvbXBsZXRlIHByb3BlcnR5IGFjY2VzcykgdOG6oWkgxJDDmk5HIHbhu4sgdHLDrSBk4bqldSBjaOG6pW0uXG4gKiBUaHUgdGjhuq1wIGB0YWludGVkTGluZXNgIChkw7JuZyBjw7MgdHJhaWxpbmcgZG90KSArIGBkb3RQb3NpdGlvbnNgIChvZmZzZXQgZOG6pXUgY2jhuqVtIMSR4buDIHbDoSBraGkgcGFyc2UpLlxuICovXG5leHBvcnQgY29uc3QgY29sbGVjdFRyYWlsaW5nRG90RGlhZ25vc3RpY3MgPSAoZG9jOiBUZXh0LCBkaWFnbm9zdGljczogRGlhZ25vc3RpY1tdLCB0YWludGVkTGluZXM6IFNldDxudW1iZXI+LCBkb3RQb3NpdGlvbnM6IG51bWJlcltdKTogdm9pZCA9PiB7XG4gIGZvciAobGV0IGxpbmVOdW1iZXIgPSAxOyBsaW5lTnVtYmVyIDw9IGRvYy5saW5lczsgbGluZU51bWJlcisrKSB7XG4gICAgY29uc3QgbGluZSA9IGRvYy5saW5lKGxpbmVOdW1iZXIpO1xuICAgIGNvbnN0IHRyaW1tZWQgPSBsaW5lLnRleHQudHJpbUVuZCgpO1xuICAgIGNvbnN0IG1hdGNoID0gLyhcXHcrKVxcLlxccyokLy5leGVjKHRyaW1tZWQpO1xuICAgIGlmICghbWF0Y2gpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICB0YWludGVkTGluZXMuYWRkKGxpbmVOdW1iZXIpO1xuICAgIGNvbnN0IGRvdFBvc2l0aW9uID0gbGluZS5mcm9tICsgdHJpbW1lZC5sYXN0SW5kZXhPZignLicpO1xuICAgIGRvdFBvc2l0aW9ucy5wdXNoKGRvdFBvc2l0aW9uKTtcbiAgICBkaWFnbm9zdGljcy5wdXNoKHsgZnJvbTogZG90UG9zaXRpb24sIHRvOiBkb3RQb3NpdGlvbiArIDEsIHNldmVyaXR5OiAnZXJyb3InLCBtZXNzYWdlOiBgSW5jb21wbGV0ZSBwcm9wZXJ0eSBhY2Nlc3Mgb24gXCIke21hdGNoWzFdfVwiYCB9KTtcbiAgfVxufTtcblxuLyoqIFRoYXkgY8OhYyBrw70gdOG7sSB04bqhaSBgcG9zaXRpb25zYCBi4bqxbmcgc3BhY2UsIGdp4buvIG5ndXnDqm4gxJHhu5kgZMOgaSBjaHXhu5dpICjEkeG7gyBvZmZzZXQga2jDtG5nIMSR4buVaSkuICovXG5jb25zdCByZXBsYWNlQ2hhcnNXaXRoU3BhY2UgPSAoY29kZTogc3RyaW5nLCBwb3NpdGlvbnM6IG51bWJlcltdKTogc3RyaW5nID0+IHtcbiAgaWYgKCFwb3NpdGlvbnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIGNvZGU7XG4gIH1cbiAgY29uc3QgY2hhcnMgPSBjb2RlLnNwbGl0KCcnKTtcbiAgZm9yIChjb25zdCBwb3NpdGlvbiBvZiBwb3NpdGlvbnMpIHtcbiAgICBpZiAocG9zaXRpb24gPj0gMCAmJiBwb3NpdGlvbiA8IGNoYXJzLmxlbmd0aCkge1xuICAgICAgY2hhcnNbcG9zaXRpb25dID0gJyAnO1xuICAgIH1cbiAgfVxuICByZXR1cm4gY2hhcnMuam9pbignJyk7XG59O1xuXG4vKiogVmFyaWFibGVEZWNsYXJhdGlvbiDhu58gYGZvcihsZXQgaT0wOy4uLilgIC8gYGZvci4uaW5gIC8gYGZvci4ub2ZgIEtIw5RORyBj4bqnbiBgO2AgY3Xhu5FpLiAqL1xuY29uc3QgcmVxdWlyZXNTZW1pY29sb24gPSAobm9kZVR5cGU6IHN0cmluZywgcGFyZW50VHlwZTogc3RyaW5nLCBrZXlJblBhcmVudDogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG4gIGlmIChub2RlVHlwZSA9PT0gJ1ZhcmlhYmxlRGVjbGFyYXRpb24nKSB7XG4gICAgaWYgKHBhcmVudFR5cGUgPT09ICdGb3JTdGF0ZW1lbnQnICYmIGtleUluUGFyZW50ID09PSAnaW5pdCcpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoKHBhcmVudFR5cGUgPT09ICdGb3JJblN0YXRlbWVudCcgfHwgcGFyZW50VHlwZSA9PT0gJ0Zvck9mU3RhdGVtZW50JykgJiYga2V5SW5QYXJlbnQgPT09ICdsZWZ0JykgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufTtcblxuLyoqXG4gKiBSdWxlIGN1c3RvbSBcInJlcXVpcmUgc2VtaWNvbG9uXCI6IGPDonUgbOG7h25oIChjb25zdC9sZXQvcmV0dXJuL2V4cHJlc3Npb24uLi4pIGtow7RuZyBr4bq/dCB0aMO6YyBi4bqxbmcgYDtgIOKGkiBiw6FvIGzhu5dpLlxuICogRMO5bmcgduG7iyB0csOtIGBub2RlLmVuZGAgY+G7p2EgQVNUIGJhYmVsOyBi4buPIHF1YSBkw7JuZyB0YWludGVkICh0cmFpbGluZyBkb3QpIMSR4buDIGtow7RuZyBjaOG7k25nIGzhu5dpLlxuICovXG5leHBvcnQgY29uc3QgY29sbGVjdE1pc3NpbmdTZW1pY29sb25EaWFnbm9zdGljcyA9IChhc3Q6IG9iamVjdCwgY29kZTogc3RyaW5nLCBkaWFnbm9zdGljczogRGlhZ25vc3RpY1tdLCB0YWludGVkTGluZXM6IFNldDxudW1iZXI+KTogdm9pZCA9PiB7XG4gIGNvbnN0IHNlbWlOb2RlcyA9IG5ldyBTZXQoWydFeHByZXNzaW9uU3RhdGVtZW50JywgJ1ZhcmlhYmxlRGVjbGFyYXRpb24nLCAnUmV0dXJuU3RhdGVtZW50JywgJ1Rocm93U3RhdGVtZW50JywgJ0JyZWFrU3RhdGVtZW50JywgJ0NvbnRpbnVlU3RhdGVtZW50JywgJ0RvV2hpbGVTdGF0ZW1lbnQnLCAnRGVidWdnZXJTdGF0ZW1lbnQnXSk7XG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0PG51bWJlcj4oKTtcbiAgY29uc3QgbGluZU9mID0gKG9mZnNldDogbnVtYmVyKSA9PiBjb2RlLnNsaWNlKDAsIG9mZnNldCkuc3BsaXQoJ1xcbicpLmxlbmd0aDtcbiAgY29uc3Qgd2FsayA9IChub2RlOiB1bmtub3duLCBwYXJlbnRUeXBlOiBzdHJpbmcsIGtleUluUGFyZW50OiBzdHJpbmcpOiB2b2lkID0+IHtcbiAgICBpZiAoQXJyYXkuaXNBcnJheShub2RlKSkge1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIG5vZGUpIHdhbGsoaXRlbSwgcGFyZW50VHlwZSwga2V5SW5QYXJlbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoIW5vZGUgfHwgdHlwZW9mIG5vZGUgIT09ICdvYmplY3QnKSByZXR1cm47XG4gICAgY29uc3QgY3VycmVudCA9IG5vZGUgYXMgVF9Bc3ROb2RlO1xuICAgIGlmICh0eXBlb2YgY3VycmVudC50eXBlICE9PSAnc3RyaW5nJykgcmV0dXJuO1xuXG4gICAgaWYgKHNlbWlOb2Rlcy5oYXMoY3VycmVudC50eXBlKSAmJiByZXF1aXJlc1NlbWljb2xvbihjdXJyZW50LnR5cGUsIHBhcmVudFR5cGUsIGtleUluUGFyZW50KSAmJiB0eXBlb2YgY3VycmVudC5lbmQgPT09ICdudW1iZXInKSB7XG4gICAgICBjb25zdCBlbmQgPSBNYXRoLm1pbihjdXJyZW50LmVuZCwgY29kZS5sZW5ndGgpO1xuICAgICAgaWYgKGVuZCA+IDAgJiYgY29kZS5jaGFyQXQoZW5kIC0gMSkgIT09ICc7JyAmJiAhc2Vlbi5oYXMoZW5kKSAmJiAhdGFpbnRlZExpbmVzLmhhcyhsaW5lT2YoZW5kIC0gMSkpKSB7XG4gICAgICAgIHNlZW4uYWRkKGVuZCk7XG4gICAgICAgIGRpYWdub3N0aWNzLnB1c2goeyBmcm9tOiBlbmQgLSAxLCB0bzogZW5kLCBzZXZlcml0eTogJ2Vycm9yJywgbWVzc2FnZTogJ01pc3Npbmcgc2VtaWNvbG9uJyB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNoaWxkS2V5IG9mIE9iamVjdC5rZXlzKGN1cnJlbnQpKSB7XG4gICAgICBpZiAoYXN0U2tpcEtleXMuaGFzKGNoaWxkS2V5KSkgY29udGludWU7XG4gICAgICB3YWxrKGN1cnJlbnRbY2hpbGRLZXldLCBjdXJyZW50LnR5cGUsIGNoaWxkS2V5KTtcbiAgICB9XG4gIH07XG4gIHdhbGsoKGFzdCBhcyB7IHByb2dyYW0/OiB1bmtub3duIH0pLnByb2dyYW0gPz8gYXN0LCAnJywgJycpO1xufTtcblxuLyoqIENodeG6qW4gaMOzYSBtZXNzYWdlOiB0aMOibiB0aGnhu4duIGNobyB0cmFpbGluZyBkb3QgKyBoZXVyaXN0aWMga2nhu4N1IGPFqSBjaG8gXCJVbmV4cGVjdGVkIHRva2VuXCI7IGLhu48gaOG6rXUgdOG7kSBcIihsaW5lOmNvbClcIi4gKi9cbmV4cG9ydCBjb25zdCBidWlsZEpzRXJyb3JNZXNzYWdlID0gKGRvYzogVGV4dCwgZnJvbTogbnVtYmVyLCByYXdNZXNzYWdlOiBzdHJpbmcpOiBzdHJpbmcgPT4ge1xuICBjb25zdCBjaGFyQmVmb3JlID0gZnJvbSA+IDAgPyBkb2Muc2xpY2VTdHJpbmcoZnJvbSAtIDEsIGZyb20pIDogJyc7XG4gIGlmIChjaGFyQmVmb3JlID09PSAnLicpIHtcbiAgICBjb25zdCBvd25lciA9IGdldFRva2VuQmVmb3JlKGRvYywgZnJvbSkucmVwbGFjZSgvXFwuJC8sICcnKTtcbiAgICByZXR1cm4gb3duZXIgPyBgSW5jb21wbGV0ZSBwcm9wZXJ0eSBhY2Nlc3Mgb24gXCIke293bmVyfVwiYCA6ICdJbmNvbXBsZXRlIHByb3BlcnR5IGFjY2Vzcyc7XG4gIH1cblxuICBjb25zdCBjbGVhbmVkID0gcmF3TWVzc2FnZS5yZXBsYWNlKC9cXHMqXFwoXFxkKzpcXGQrXFwpXFxzKiQvLCAnJykudHJpbSgpO1xuICBpZiAoL21pc3Npbmcgc2VtaWNvbG9uL2kudGVzdChjbGVhbmVkKSkge1xuICAgIHJldHVybiAnVW5leHBlY3RlZCB0b2tlbiDigJQgbWlzc2luZyBvcGVyYXRvciBvciBzZXBhcmF0b3IgYmV0d2VlbiBleHByZXNzaW9ucyc7XG4gIH1cbiAgaWYgKC9edW5leHBlY3RlZCB0b2tlbiQvaS50ZXN0KGNsZWFuZWQpKSB7XG4gICAgY29uc3QgcHJldlRva2VuID0gZ2V0VG9rZW5CZWZvcmUoZG9jLCBmcm9tKTtcbiAgICBpZiAocHJldlRva2VuLmVuZHNXaXRoKCcoJykpIHJldHVybiAnTWlzc2luZyBjbG9zaW5nIFwiKVwiJztcbiAgICBpZiAocHJldlRva2VuLmVuZHNXaXRoKCdbJykpIHJldHVybiAnTWlzc2luZyBjbG9zaW5nIFwiXVwiJztcbiAgICBpZiAoL15mdW5jdGlvbiQvaS50ZXN0KHByZXZUb2tlbikpIHJldHVybiAnRXhwZWN0ZWQgZnVuY3Rpb24gbmFtZSBvciBcIihcIic7XG4gICAgaWYgKC9ecmV0dXJuJC9pLnRlc3QocHJldlRva2VuKSkgcmV0dXJuICdJbnZhbGlkIGV4cHJlc3Npb24gYWZ0ZXIgXCJyZXR1cm5cIic7XG4gICAgaWYgKC9ePT4kLy50ZXN0KHByZXZUb2tlbikpIHJldHVybiAnRXhwZWN0ZWQgZnVuY3Rpb24gYm9keSBhZnRlciBcIj0+XCInO1xuICAgIGlmICgvXmNvbnN0JHxebGV0JHxedmFyJC9pLnRlc3QocHJldlRva2VuKSkgcmV0dXJuICdFeHBlY3RlZCB2YXJpYWJsZSBuYW1lJztcbiAgfVxuICByZXR1cm4gYEphdmFTY3JpcHQgc3ludGF4IGVycm9yOiAke2NsZWFuZWR9YDtcbn07XG5cbi8qKiBM4bqleSB0w6puIGJpbmRpbmcgdOG7qyBwYXR0ZXJuIChJZGVudGlmaWVyLCBkZXN0cnVjdHVyaW5nIG9iamVjdC9hcnJheSwgZGVmYXVsdCwgcmVzdCkuICovXG5jb25zdCBjb2xsZWN0UGF0dGVybk5hbWVzID0gKG5vZGU6IFRfQXN0Tm9kZSB8IG51bGwgfCB1bmRlZmluZWQsIGRlY2xhcmVkOiBTZXQ8c3RyaW5nPik6IHZvaWQgPT4ge1xuICBpZiAoIW5vZGUgfHwgdHlwZW9mIG5vZGUudHlwZSAhPT0gJ3N0cmluZycpIHJldHVybjtcbiAgc3dpdGNoIChub2RlLnR5cGUpIHtcbiAgICBjYXNlICdJZGVudGlmaWVyJzpcbiAgICAgIGlmIChub2RlLm5hbWUpIGRlY2xhcmVkLmFkZChub2RlLm5hbWUpO1xuICAgICAgcmV0dXJuO1xuICAgIGNhc2UgJ09iamVjdFBhdHRlcm4nOlxuICAgICAgaWYgKG5vZGUucHJvcGVydGllcykgZm9yIChjb25zdCBwcm9wZXJ0eSBvZiBub2RlLnByb3BlcnRpZXMpIGNvbGxlY3RQYXR0ZXJuTmFtZXMocHJvcGVydHkudHlwZSA9PT0gJ1Jlc3RFbGVtZW50JyA/IHByb3BlcnR5LmFyZ3VtZW50IDogcHJvcGVydHkudmFsdWUsIGRlY2xhcmVkKTtcbiAgICAgIHJldHVybjtcbiAgICBjYXNlICdBcnJheVBhdHRlcm4nOlxuICAgICAgaWYgKG5vZGUuZWxlbWVudHMpIGZvciAoY29uc3QgZWxlbWVudCBvZiBub2RlLmVsZW1lbnRzKSBjb2xsZWN0UGF0dGVybk5hbWVzKGVsZW1lbnQsIGRlY2xhcmVkKTtcbiAgICAgIHJldHVybjtcbiAgICBjYXNlICdBc3NpZ25tZW50UGF0dGVybic6XG4gICAgICBjb2xsZWN0UGF0dGVybk5hbWVzKG5vZGUubGVmdCwgZGVjbGFyZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIGNhc2UgJ1Jlc3RFbGVtZW50JzpcbiAgICAgIGNvbGxlY3RQYXR0ZXJuTmFtZXMobm9kZS5hcmd1bWVudCwgZGVjbGFyZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIGNhc2UgJ1RTUGFyYW1ldGVyUHJvcGVydHknOlxuICAgICAgY29sbGVjdFBhdHRlcm5OYW1lcyhub2RlLnBhcmFtZXRlciwgZGVjbGFyZWQpO1xuICAgICAgcmV0dXJuO1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm47XG4gIH1cbn07XG5cbi8qKiBUaHUgdGjhuq1wIHTDqm4gYmluZGluZyAoYmnhur9uL2jDoG0vY2xhc3MvcGFyYW0vaW1wb3J0L2VudW0uLi4pIHThu6sgMSBub2RlIHbDoG8gdOG6rXAgYGRlY2xhcmVkYC4gKi9cbmNvbnN0IGNvbGxlY3RCaW5kaW5nTmFtZXMgPSAobm9kZTogVF9Bc3ROb2RlLCBkZWNsYXJlZDogU2V0PHN0cmluZz4pOiB2b2lkID0+IHtcbiAgc3dpdGNoIChub2RlLnR5cGUpIHtcbiAgICBjYXNlICdWYXJpYWJsZURlY2xhcmF0b3InOlxuICAgICAgY29sbGVjdFBhdHRlcm5OYW1lcyhub2RlLmlkLCBkZWNsYXJlZCk7XG4gICAgICByZXR1cm47XG4gICAgY2FzZSAnRnVuY3Rpb25EZWNsYXJhdGlvbic6XG4gICAgY2FzZSAnRnVuY3Rpb25FeHByZXNzaW9uJzpcbiAgICBjYXNlICdDbGFzc0RlY2xhcmF0aW9uJzpcbiAgICBjYXNlICdDbGFzc0V4cHJlc3Npb24nOlxuICAgICAgaWYgKG5vZGUuaWQ/Lm5hbWUpIGRlY2xhcmVkLmFkZChub2RlLmlkLm5hbWUpO1xuICAgICAgaWYgKG5vZGUucGFyYW1zKSBmb3IgKGNvbnN0IHBhcmFtIG9mIG5vZGUucGFyYW1zKSBjb2xsZWN0UGF0dGVybk5hbWVzKHBhcmFtLCBkZWNsYXJlZCk7XG4gICAgICByZXR1cm47XG4gICAgY2FzZSAnQXJyb3dGdW5jdGlvbkV4cHJlc3Npb24nOlxuICAgICAgaWYgKG5vZGUucGFyYW1zKSBmb3IgKGNvbnN0IHBhcmFtIG9mIG5vZGUucGFyYW1zKSBjb2xsZWN0UGF0dGVybk5hbWVzKHBhcmFtLCBkZWNsYXJlZCk7XG4gICAgICByZXR1cm47XG4gICAgY2FzZSAnQ2F0Y2hDbGF1c2UnOlxuICAgICAgY29sbGVjdFBhdHRlcm5OYW1lcyhub2RlLnBhcmFtLCBkZWNsYXJlZCk7XG4gICAgICByZXR1cm47XG4gICAgY2FzZSAnSW1wb3J0RGVmYXVsdFNwZWNpZmllcic6XG4gICAgY2FzZSAnSW1wb3J0TmFtZXNwYWNlU3BlY2lmaWVyJzpcbiAgICBjYXNlICdJbXBvcnRTcGVjaWZpZXInOlxuICAgICAgaWYgKG5vZGUubG9jYWw/Lm5hbWUpIGRlY2xhcmVkLmFkZChub2RlLmxvY2FsLm5hbWUpO1xuICAgICAgcmV0dXJuO1xuICAgIGNhc2UgJ1RTRW51bURlY2xhcmF0aW9uJzpcbiAgICBjYXNlICdUU01vZHVsZURlY2xhcmF0aW9uJzpcbiAgICAgIGlmIChub2RlLmlkPy5uYW1lKSBkZWNsYXJlZC5hZGQobm9kZS5pZC5uYW1lKTtcbiAgICAgIHJldHVybjtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuO1xuICB9XG59O1xuXG4vKiogWMOhYyDEkeG7i25oIDEgSWRlbnRpZmllciBjw7MgcGjhuqNpIHRoYW0gY2hp4bq/dSBnacOhIHRy4buLIGtow7RuZyAobG/huqFpIHByb3BlcnR5IGFjY2Vzcywga2V5IG9iamVjdCwgZGVjbGFyYXRpb24gaWQsIGxhYmVsLi4uKS4gKi9cbmNvbnN0IGlzUmVmZXJlbmNlSWRlbnRpZmllciA9IChwYXJlbnQ6IFRfQXN0Tm9kZSB8IG51bGwsIGtleUluUGFyZW50OiBzdHJpbmcpOiBib29sZWFuID0+IHtcbiAgaWYgKCFwYXJlbnQpIHJldHVybiB0cnVlO1xuICBjb25zdCBwYXJlbnRUeXBlID0gcGFyZW50LnR5cGU7XG4gIGlmICgocGFyZW50VHlwZSA9PT0gJ01lbWJlckV4cHJlc3Npb24nIHx8IHBhcmVudFR5cGUgPT09ICdPcHRpb25hbE1lbWJlckV4cHJlc3Npb24nKSAmJiBrZXlJblBhcmVudCA9PT0gJ3Byb3BlcnR5JyAmJiAhcGFyZW50LmNvbXB1dGVkKSByZXR1cm4gZmFsc2U7XG4gIGlmICgocGFyZW50VHlwZSA9PT0gJ09iamVjdFByb3BlcnR5JyB8fCBwYXJlbnRUeXBlID09PSAnT2JqZWN0TWV0aG9kJyB8fCBwYXJlbnRUeXBlID09PSAnQ2xhc3NNZXRob2QnIHx8IHBhcmVudFR5cGUgPT09ICdDbGFzc1Byb3BlcnR5JyB8fCBwYXJlbnRUeXBlID09PSAnQ2xhc3NQcml2YXRlUHJvcGVydHknIHx8IHBhcmVudFR5cGUgPT09ICdQcm9wZXJ0eURlZmluaXRpb24nKSAmJiBrZXlJblBhcmVudCA9PT0gJ2tleScgJiYgIXBhcmVudC5jb21wdXRlZCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoa2V5SW5QYXJlbnQgPT09ICdsYWJlbCcpIHJldHVybiBmYWxzZTtcbiAgaWYgKHBhcmVudFR5cGUgPT09ICdUU1F1YWxpZmllZE5hbWUnICYmIGtleUluUGFyZW50ID09PSAncmlnaHQnKSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYXJlbnRUeXBlID09PSAnVmFyaWFibGVEZWNsYXJhdG9yJyAmJiBrZXlJblBhcmVudCA9PT0gJ2lkJykgcmV0dXJuIGZhbHNlO1xuICBpZiAoKHBhcmVudFR5cGUgPT09ICdGdW5jdGlvbkRlY2xhcmF0aW9uJyB8fCBwYXJlbnRUeXBlID09PSAnRnVuY3Rpb25FeHByZXNzaW9uJyB8fCBwYXJlbnRUeXBlID09PSAnQ2xhc3NEZWNsYXJhdGlvbicgfHwgcGFyZW50VHlwZSA9PT0gJ0NsYXNzRXhwcmVzc2lvbicpICYmIGtleUluUGFyZW50ID09PSAnaWQnKSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYXJlbnRUeXBlID09PSAnSW1wb3J0U3BlY2lmaWVyJyB8fCBwYXJlbnRUeXBlID09PSAnSW1wb3J0RGVmYXVsdFNwZWNpZmllcicgfHwgcGFyZW50VHlwZSA9PT0gJ0ltcG9ydE5hbWVzcGFjZVNwZWNpZmllcicgfHwgcGFyZW50VHlwZSA9PT0gJ0V4cG9ydFNwZWNpZmllcicpIHJldHVybiBmYWxzZTtcbiAgaWYgKHBhcmVudFR5cGUgPT09ICdNZXRhUHJvcGVydHknKSByZXR1cm4gZmFsc2U7XG4gIGlmIChwYXJlbnRUeXBlID09PSAnVFNFbnVtTWVtYmVyJyAmJiBrZXlJblBhcmVudCA9PT0gJ2lkJykgcmV0dXJuIGZhbHNlO1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbi8qKiBEdXnhu4d0IMSR4buHIHF1eSBBU1Q6IGdvbSBiaW5kaW5nIG5hbWUgdsOgbyBgZGVjbGFyZWRgLCBnb20gaWRlbnRpZmllciB0aGFtIGNoaeG6v3UgdsOgbyBgcmVmZXJlbmNlc2AuICovXG5jb25zdCB3YWxrQXN0Tm9kZSA9IChub2RlOiB1bmtub3duLCBwYXJlbnQ6IFRfQXN0Tm9kZSB8IG51bGwsIGtleUluUGFyZW50OiBzdHJpbmcsIGluVHlwZTogYm9vbGVhbiwgZGVjbGFyZWQ6IFNldDxzdHJpbmc+LCByZWZlcmVuY2VzOiBUX0FzdFJlZmVyZW5jZVtdKTogdm9pZCA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KG5vZGUpKSB7XG4gICAgZm9yIChjb25zdCBpdGVtIG9mIG5vZGUpIHdhbGtBc3ROb2RlKGl0ZW0sIHBhcmVudCwga2V5SW5QYXJlbnQsIGluVHlwZSwgZGVjbGFyZWQsIHJlZmVyZW5jZXMpO1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoIW5vZGUgfHwgdHlwZW9mIG5vZGUgIT09ICdvYmplY3QnKSByZXR1cm47XG4gIGNvbnN0IGN1cnJlbnQgPSBub2RlIGFzIFRfQXN0Tm9kZTtcbiAgaWYgKHR5cGVvZiBjdXJyZW50LnR5cGUgIT09ICdzdHJpbmcnKSByZXR1cm47XG5cbiAgY29sbGVjdEJpbmRpbmdOYW1lcyhjdXJyZW50LCBkZWNsYXJlZCk7XG5cbiAgaWYgKGN1cnJlbnQudHlwZSA9PT0gJ0lkZW50aWZpZXInICYmICFpblR5cGUgJiYgaXNSZWZlcmVuY2VJZGVudGlmaWVyKHBhcmVudCwga2V5SW5QYXJlbnQpKSB7XG4gICAgY29uc3Qgc3RhcnQgPSBjdXJyZW50LmxvYz8uc3RhcnQ7XG4gICAgaWYgKGN1cnJlbnQubmFtZSAmJiBzdGFydCkgcmVmZXJlbmNlcy5wdXNoKHsgbmFtZTogY3VycmVudC5uYW1lLCBsaW5lOiBzdGFydC5saW5lLCBjb2x1bW46IHN0YXJ0LmNvbHVtbiB9KTtcbiAgfVxuXG4gIGNvbnN0IG9wZW5zVHlwZSA9IGluVHlwZSB8fCAoY3VycmVudC50eXBlLnN0YXJ0c1dpdGgoJ1RTJykgJiYgIXRzVmFsdWVOb2Rlcy5oYXMoY3VycmVudC50eXBlKSk7XG4gIGZvciAoY29uc3QgY2hpbGRLZXkgb2YgT2JqZWN0LmtleXMoY3VycmVudCkpIHtcbiAgICBpZiAoYXN0U2tpcEtleXMuaGFzKGNoaWxkS2V5KSkgY29udGludWU7XG4gICAgY29uc3QgY2hpbGQgPSBjdXJyZW50W2NoaWxkS2V5XTtcbiAgICBjb25zdCBjaGlsZE9wZW5zVHlwZSA9IHR5cGVvZiBjaGlsZCA9PT0gJ29iamVjdCcgJiYgY2hpbGQgIT09IG51bGwgJiYgdHlwZW9mIChjaGlsZCBhcyBUX0FzdE5vZGUpLnR5cGUgPT09ICdzdHJpbmcnICYmIChjaGlsZCBhcyBUX0FzdE5vZGUpLnR5cGUuc3RhcnRzV2l0aCgnVFMnKSAmJiAhdHNWYWx1ZU5vZGVzLmhhcygoY2hpbGQgYXMgVF9Bc3ROb2RlKS50eXBlKTtcbiAgICBjb25zdCBjaGlsZEluVHlwZSA9IG9wZW5zVHlwZSB8fCBhc3RUeXBlS2V5cy5oYXMoY2hpbGRLZXkpIHx8IGNoaWxkT3BlbnNUeXBlO1xuICAgIHdhbGtBc3ROb2RlKGNoaWxkLCBjdXJyZW50LCBjaGlsZEtleSwgY2hpbGRJblR5cGUsIGRlY2xhcmVkLCByZWZlcmVuY2VzKTtcbiAgfVxufTtcblxuLyoqXG4gKiBQYXNzIG5n4buvIG5naMSpYTogYsOhbyBiaeG6v24gQ0jGr0EgS0hBSSBCw4FPLiBU4buxIGR1eeG7h3QgQVNUIChvYmplY3QgdGh14bqnbikg4oCUIEtIw5RORyBkw7luZyBgQGJhYmVsL3RyYXZlcnNlYFxuICogKGPhuqduIGBwcm9jZXNzYCBj4bunYSBOb2RlIOKGkiBjcmFzaCBicm93c2VyKS4gSOG7o3AgbOG7hyA9IGJpbmRpbmcgdHJvbmcgY29kZSArIGdsb2JhbCBKUy9ET00gKyBgY29tcGxldGlvbkxhYmVsc2AuXG4gKi9cbmV4cG9ydCBjb25zdCBjb2xsZWN0VW5kZWNsYXJlZElkZW50aWZpZXJzID0gYXN5bmMgKGFzdDogb2JqZWN0LCBkb2M6IFRleHQsIGNvbXBsZXRpb25MYWJlbHM6IFNldDxzdHJpbmc+LCB0YWludGVkTGluZXM6IFNldDxudW1iZXI+ID0gbmV3IFNldCgpKTogUHJvbWlzZTxEaWFnbm9zdGljW10+ID0+IHtcbiAgY29uc3QgZ2xvYmFsc1NldCA9IGF3YWl0IGdldEtub3duR2xvYmFscygpO1xuICBjb25zdCBkZWNsYXJlZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBjb25zdCByZWZlcmVuY2VzOiBUX0FzdFJlZmVyZW5jZVtdID0gW107XG5cbiAgd2Fsa0FzdE5vZGUoYXN0IGFzIFRfQXN0Tm9kZSwgbnVsbCwgJycsIGZhbHNlLCBkZWNsYXJlZCwgcmVmZXJlbmNlcyk7XG5cbiAgY29uc3QgZGlhZ25vc3RpY3M6IERpYWdub3N0aWNbXSA9IFtdO1xuICBjb25zdCBzZWVuID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGZvciAoY29uc3QgcmVmZXJlbmNlIG9mIHJlZmVyZW5jZXMpIHtcbiAgICBjb25zdCB7IG5hbWUsIGxpbmU6IHN0YXJ0TGluZSwgY29sdW1uOiBzdGFydENvbHVtbiB9ID0gcmVmZXJlbmNlO1xuICAgIGlmIChkZWNsYXJlZC5oYXMobmFtZSkgfHwgZ2xvYmFsc1NldC5oYXMobmFtZSkgfHwgY29tcGxldGlvbkxhYmVscy5oYXMobmFtZSkpIGNvbnRpbnVlO1xuICAgIGlmICh0YWludGVkTGluZXMuaGFzKHN0YXJ0TGluZSkpIGNvbnRpbnVlO1xuXG4gICAgY29uc3QgZGVkdXBlS2V5ID0gYCR7c3RhcnRMaW5lfToke3N0YXJ0Q29sdW1ufToke25hbWV9YDtcbiAgICBpZiAoc2Vlbi5oYXMoZGVkdXBlS2V5KSkgY29udGludWU7XG4gICAgc2Vlbi5hZGQoZGVkdXBlS2V5KTtcblxuICAgIGNvbnN0IGxpbmUgPSBkb2MubGluZShNYXRoLm1pbihNYXRoLm1heChzdGFydExpbmUsIDEpLCBkb2MubGluZXMpKTtcbiAgICBjb25zdCBmcm9tID0gTWF0aC5taW4obGluZS5mcm9tICsgTWF0aC5tYXgoc3RhcnRDb2x1bW4sIDApLCBkb2MubGVuZ3RoKTtcbiAgICBjb25zdCB0byA9IE1hdGgubWluKGZyb20gKyBuYW1lLmxlbmd0aCwgZG9jLmxlbmd0aCk7XG4gICAgZGlhZ25vc3RpY3MucHVzaCh7IGZyb20sIHRvOiBNYXRoLm1heChmcm9tICsgMSwgdG8pLCBzZXZlcml0eTogJ2Vycm9yJywgbWVzc2FnZTogYFwiJHtuYW1lfVwiIGlzIG5vdCBkZWZpbmVkYCB9KTtcbiAgfVxuICByZXR1cm4gZGlhZ25vc3RpY3M7XG59O1xuXG4vKipcbiAqIFRvw6BuIGLhu5kgcGlwZWxpbmUgdmFsaWRhdGUgSlMvVFM6XG4gKiAtIFBhc3MgMTogdHJhaWxpbmcgZG90ICh0ZXh0KSDigJQgZmxhZyDEkcO6bmcgduG7iyB0csOtIGThuqV1IGAuYCBjdeG7kWkgZMOybmcgKyDEkcOhbmggZOG6pXUgZMOybmcgdGFpbnRlZC5cbiAqIC0gUGFzcyAyOiBs4buXaSBjw7ogcGjDoXAgYmFiZWwg4oCUIGLhu48gbOG7l2kgdHLDqm4gZMOybmcgdGFpbnRlZCAoY2FzY2FkaW5nKS5cbiAqIC0gUGFzcyAzOiBydWxlIGPhuqduIEFTVCAodGhp4bq/dSBgO2AsIGJp4bq/biBjaMawYSBraGFpIGLDoW8pLiBUcmFpbGluZyBkb3QgxJHGsOG7o2MgXCJ2w6FcIiAoYC5g4oaSc3BhY2UpIMSR4buDIGJhYmVsXG4gKiAgIHbhuqtuIHBhcnNlIMSRxrDhu6NjIHBo4bqnbiBjw7JuIGzhuqFpIOKGkiBydWxlIHbhuqtuIGNo4bqheSBjaG8gY8OhYyBkw7JuZyBLSMOBQy5cbiAqL1xuZXhwb3J0IGNvbnN0IGNvbXB1dGVKc0RpYWdub3N0aWNzID0gYXN5bmMgKGRvYzogVGV4dCwgY29kZTogc3RyaW5nLCBjb21wbGV0aW9uTGFiZWxzOiBTZXQ8c3RyaW5nPik6IFByb21pc2U8RGlhZ25vc3RpY1tdPiA9PiB7XG4gIGNvbnN0IGRpYWdub3N0aWNzOiBEaWFnbm9zdGljW10gPSBbXTtcbiAgaWYgKGNvZGUudHJpbSgpID09PSAnJykge1xuICAgIHJldHVybiBkaWFnbm9zdGljcztcbiAgfVxuXG4gIGNvbnN0IHRhaW50ZWRMaW5lcyA9IG5ldyBTZXQ8bnVtYmVyPigpO1xuICBjb25zdCBkb3RQb3NpdGlvbnM6IG51bWJlcltdID0gW107XG4gIGNvbGxlY3RUcmFpbGluZ0RvdERpYWdub3N0aWNzKGRvYywgZGlhZ25vc3RpY3MsIHRhaW50ZWRMaW5lcywgZG90UG9zaXRpb25zKTtcblxuICBjb25zdCBwYXJzZUNvZGUgPSByZXBsYWNlQ2hhcnNXaXRoU3BhY2UoY29kZSwgZG90UG9zaXRpb25zKTtcbiAgY29uc3QgcGFyc2VyID0gYXdhaXQgZ2V0QmFiZWxQYXJzZXIoKTtcbiAgY29uc3QgeyBlcnJvcnMsIGFzdCB9ID0gcGFyc2VKcyhwYXJzZXIsIHBhcnNlQ29kZSk7XG4gIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgZm9yIChjb25zdCBlcnJvciBvZiBlcnJvcnMpIHtcbiAgICBjb25zdCBsb2NhdGlvbiA9IGVycm9yLmxvYztcbiAgICBpZiAoIWxvY2F0aW9uKSBjb250aW51ZTtcbiAgICBjb25zdCBsaW5lTnVtYmVyID0gTWF0aC5taW4oTWF0aC5tYXgobG9jYXRpb24ubGluZSwgMSksIGRvYy5saW5lcyk7XG4gICAgaWYgKHRhaW50ZWRMaW5lcy5oYXMobGluZU51bWJlcikpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGxpbmUgPSBkb2MubGluZShsaW5lTnVtYmVyKTtcbiAgICBjb25zdCBlcnJvclBvcyA9IE1hdGgubWluKGxpbmUuZnJvbSArIE1hdGgubWF4KGxvY2F0aW9uLmNvbHVtbiwgMCksIGRvYy5sZW5ndGgpO1xuICAgIGNvbnN0IHRvID0gTWF0aC5taW4oZXJyb3JQb3MgKyAxLCBkb2MubGVuZ3RoKTtcbiAgICBjb25zdCBmcm9tID0gZXJyb3JQb3MgPj0gdG8gJiYgZXJyb3JQb3MgPiAwID8gZXJyb3JQb3MgLSAxIDogZXJyb3JQb3M7XG4gICAgY29uc3QgbWVzc2FnZSA9IGJ1aWxkSnNFcnJvck1lc3NhZ2UoZG9jLCBlcnJvclBvcywgZXJyb3IubWVzc2FnZSk7XG4gICAgY29uc3QgZGVkdXBlS2V5ID0gYCR7ZnJvbX06JHttZXNzYWdlfWA7XG4gICAgaWYgKHNlZW4uaGFzKGRlZHVwZUtleSkpIGNvbnRpbnVlO1xuICAgIHNlZW4uYWRkKGRlZHVwZUtleSk7XG4gICAgZGlhZ25vc3RpY3MucHVzaCh7IGZyb20sIHRvOiBNYXRoLm1heChmcm9tICsgMSwgdG8pLCBzZXZlcml0eTogJ2Vycm9yJywgbWVzc2FnZSB9KTtcbiAgfVxuXG4gIGlmIChlcnJvcnMubGVuZ3RoID09PSAwICYmIGFzdCkge1xuICAgIGNvbGxlY3RNaXNzaW5nU2VtaWNvbG9uRGlhZ25vc3RpY3MoYXN0LCBjb2RlLCBkaWFnbm9zdGljcywgdGFpbnRlZExpbmVzKTtcbiAgICBkaWFnbm9zdGljcy5wdXNoKC4uLihhd2FpdCBjb2xsZWN0VW5kZWNsYXJlZElkZW50aWZpZXJzKGFzdCwgZG9jLCBjb21wbGV0aW9uTGFiZWxzLCB0YWludGVkTGluZXMpKSk7XG4gIH1cblxuICByZXR1cm4gZGlhZ25vc3RpY3M7XG59O1xuIl19
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { get } from '@libs-ui/utils';
|
|
2
|
+
/** Validate JSON bằng `JSON.parse`. Lỗi → 1 diagnostic phủ toàn bộ nội dung. */
|
|
3
|
+
export const computeJsonDiagnostics = (view) => {
|
|
4
|
+
const text = view.state.doc.toString();
|
|
5
|
+
const diagnostics = [];
|
|
6
|
+
try {
|
|
7
|
+
JSON.parse(text);
|
|
8
|
+
}
|
|
9
|
+
catch (error) {
|
|
10
|
+
diagnostics.push({ from: 0, to: text.length, severity: 'error', message: get(error, 'message', '') });
|
|
11
|
+
}
|
|
12
|
+
return diagnostics;
|
|
13
|
+
};
|
|
14
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1saW50ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzLXVpL2NvbXBvbmVudHMvcHJldmlldy10ZXh0LWRhdGEvc3JjL2xpbnRlcnMvanNvbi1saW50ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRXJDLGdGQUFnRjtBQUNoRixNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLElBQWdCLEVBQWdCLEVBQUU7SUFDdkUsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLENBQUM7SUFDdkMsTUFBTSxXQUFXLEdBQWlCLEVBQUUsQ0FBQztJQUNyQyxJQUFJLENBQUM7UUFDSCxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ25CLENBQUM7SUFBQyxPQUFPLEtBQWMsRUFBRSxDQUFDO1FBQ3hCLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLEdBQUcsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztJQUN4RyxDQUFDO0lBQ0QsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRGlhZ25vc3RpYyB9IGZyb20gJ0Bjb2RlbWlycm9yL2xpbnQnO1xuaW1wb3J0IHsgRWRpdG9yVmlldyB9IGZyb20gJ0Bjb2RlbWlycm9yL3ZpZXcnO1xuaW1wb3J0IHsgZ2V0IH0gZnJvbSAnQGxpYnMtdWkvdXRpbHMnO1xuXG4vKiogVmFsaWRhdGUgSlNPTiBi4bqxbmcgYEpTT04ucGFyc2VgLiBM4buXaSDihpIgMSBkaWFnbm9zdGljIHBo4bunIHRvw6BuIGLhu5kgbuG7mWkgZHVuZy4gKi9cbmV4cG9ydCBjb25zdCBjb21wdXRlSnNvbkRpYWdub3N0aWNzID0gKHZpZXc6IEVkaXRvclZpZXcpOiBEaWFnbm9zdGljW10gPT4ge1xuICBjb25zdCB0ZXh0ID0gdmlldy5zdGF0ZS5kb2MudG9TdHJpbmcoKTtcbiAgY29uc3QgZGlhZ25vc3RpY3M6IERpYWdub3N0aWNbXSA9IFtdO1xuICB0cnkge1xuICAgIEpTT04ucGFyc2UodGV4dCk7XG4gIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgZGlhZ25vc3RpY3MucHVzaCh7IGZyb206IDAsIHRvOiB0ZXh0Lmxlbmd0aCwgc2V2ZXJpdHk6ICdlcnJvcicsIG1lc3NhZ2U6IGdldChlcnJvciwgJ21lc3NhZ2UnLCAnJykgfSk7XG4gIH1cbiAgcmV0dXJuIGRpYWdub3N0aWNzO1xufTtcbiJdfQ==
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/** Lấy token (chuỗi không khoảng trắng) liền trước vị trí `pos` trong document. Dùng chung cho JS/SQL/Python. */
|
|
2
|
+
export const getTokenBefore = (doc, pos) => {
|
|
3
|
+
const start = Math.max(0, pos - 30);
|
|
4
|
+
const text = doc.sliceString(start, pos);
|
|
5
|
+
const match = /(\S+)\s*$/.exec(text);
|
|
6
|
+
return match?.[1] ?? '';
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGludGVyLXNoYXJlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9wcmV2aWV3LXRleHQtZGF0YS9zcmMvbGludGVycy9saW50ZXItc2hhcmVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUVBLGlIQUFpSDtBQUNqSCxNQUFNLENBQUMsTUFBTSxjQUFjLEdBQUcsQ0FBQyxHQUFTLEVBQUUsR0FBVyxFQUFVLEVBQUU7SUFDL0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsR0FBRyxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQ3BDLE1BQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sS0FBSyxHQUFHLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDckMsT0FBTyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUM7QUFDMUIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgVGV4dCB9IGZyb20gJ0Bjb2RlbWlycm9yL3N0YXRlJztcblxuLyoqIEzhuqV5IHRva2VuIChjaHXhu5dpIGtow7RuZyBraG/huqNuZyB0cuG6r25nKSBsaeG7gW4gdHLGsOG7m2MgduG7iyB0csOtIGBwb3NgIHRyb25nIGRvY3VtZW50LiBEw7luZyBjaHVuZyBjaG8gSlMvU1FML1B5dGhvbi4gKi9cbmV4cG9ydCBjb25zdCBnZXRUb2tlbkJlZm9yZSA9IChkb2M6IFRleHQsIHBvczogbnVtYmVyKTogc3RyaW5nID0+IHtcbiAgY29uc3Qgc3RhcnQgPSBNYXRoLm1heCgwLCBwb3MgLSAzMCk7XG4gIGNvbnN0IHRleHQgPSBkb2Muc2xpY2VTdHJpbmcoc3RhcnQsIHBvcyk7XG4gIGNvbnN0IG1hdGNoID0gLyhcXFMrKVxccyokLy5leGVjKHRleHQpO1xuICByZXR1cm4gbWF0Y2g/LlsxXSA/PyAnJztcbn07XG4iXX0=
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { syntaxTree } from '@codemirror/language';
|
|
2
|
+
import { getTokenBefore } from './linter-shared';
|
|
3
|
+
const buildPythonErrorMessage = (doc, node) => {
|
|
4
|
+
if (node.from !== node.to) {
|
|
5
|
+
const text = doc.sliceString(node.from, node.to).trim();
|
|
6
|
+
return `Python syntax error${text ? ` near "${text}"` : ''}`;
|
|
7
|
+
}
|
|
8
|
+
const prevToken = getTokenBefore(doc, node.from);
|
|
9
|
+
if (!prevToken)
|
|
10
|
+
return 'Python syntax error';
|
|
11
|
+
if (/^def$/i.test(prevToken))
|
|
12
|
+
return 'Expected function name after "def"';
|
|
13
|
+
if (/^class$/i.test(prevToken))
|
|
14
|
+
return 'Expected class name after "class"';
|
|
15
|
+
if (/^return$/i.test(prevToken))
|
|
16
|
+
return 'Invalid expression after "return"';
|
|
17
|
+
if (/^import$/i.test(prevToken))
|
|
18
|
+
return 'Expected module name after "import"';
|
|
19
|
+
if (/^from$/i.test(prevToken))
|
|
20
|
+
return 'Expected module name after "from"';
|
|
21
|
+
if (/^if$/i.test(prevToken))
|
|
22
|
+
return 'Expected condition after "if"';
|
|
23
|
+
if (/^elif$/i.test(prevToken))
|
|
24
|
+
return 'Expected condition after "elif"';
|
|
25
|
+
if (/^while$/i.test(prevToken))
|
|
26
|
+
return 'Expected condition after "while"';
|
|
27
|
+
if (/^for$/i.test(prevToken))
|
|
28
|
+
return 'Expected variable after "for"';
|
|
29
|
+
if (prevToken.endsWith('.'))
|
|
30
|
+
return `Incomplete attribute access on "${prevToken.slice(0, -1)}"`;
|
|
31
|
+
if (prevToken.endsWith('('))
|
|
32
|
+
return 'Missing closing ")"';
|
|
33
|
+
if (prevToken.endsWith('['))
|
|
34
|
+
return 'Missing closing "]"';
|
|
35
|
+
return `Python syntax error near "${prevToken}"`;
|
|
36
|
+
};
|
|
37
|
+
/** Phát hiện lỗi cú pháp Python từ error node của syntaxTree (Lezer) — cùng approach SQL. */
|
|
38
|
+
export const computePythonDiagnostics = (view) => {
|
|
39
|
+
const diagnostics = [];
|
|
40
|
+
const doc = view.state.doc;
|
|
41
|
+
syntaxTree(view.state).iterate({
|
|
42
|
+
enter: (node) => {
|
|
43
|
+
if (!node.type.isError)
|
|
44
|
+
return;
|
|
45
|
+
const from = Math.max(0, node.from - 1);
|
|
46
|
+
const to = node.from === node.to ? node.from + 1 : node.to;
|
|
47
|
+
diagnostics.push({ from, to: Math.min(to, doc.length), severity: 'error', message: buildPythonErrorMessage(doc, node) });
|
|
48
|
+
},
|
|
49
|
+
});
|
|
50
|
+
return diagnostics;
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHl0aG9uLWxpbnRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9wcmV2aWV3LXRleHQtZGF0YS9zcmMvbGludGVycy9weXRob24tbGludGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUtsRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFakQsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLEdBQVMsRUFBRSxJQUFtQixFQUFVLEVBQUU7SUFDekUsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUMxQixNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3hELE9BQU8sc0JBQXNCLElBQUksQ0FBQyxDQUFDLENBQUMsVUFBVSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUM7SUFDL0QsQ0FBQztJQUNELE1BQU0sU0FBUyxHQUFHLGNBQWMsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ2pELElBQUksQ0FBQyxTQUFTO1FBQUUsT0FBTyxxQkFBcUIsQ0FBQztJQUM3QyxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTyxvQ0FBb0MsQ0FBQztJQUMxRSxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTyxtQ0FBbUMsQ0FBQztJQUMzRSxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTyxtQ0FBbUMsQ0FBQztJQUM1RSxJQUFJLFdBQVcsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTyxxQ0FBcUMsQ0FBQztJQUM5RSxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTyxtQ0FBbUMsQ0FBQztJQUMxRSxJQUFJLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTywrQkFBK0IsQ0FBQztJQUNwRSxJQUFJLFNBQVMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTyxpQ0FBaUMsQ0FBQztJQUN4RSxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTyxrQ0FBa0MsQ0FBQztJQUMxRSxJQUFJLFFBQVEsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDO1FBQUUsT0FBTywrQkFBK0IsQ0FBQztJQUNyRSxJQUFJLFNBQVMsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDO1FBQUUsT0FBTyxtQ0FBbUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDO0lBQ2pHLElBQUksU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7UUFBRSxPQUFPLHFCQUFxQixDQUFDO0lBQzFELElBQUksU0FBUyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUM7UUFBRSxPQUFPLHFCQUFxQixDQUFDO0lBQzFELE9BQU8sNkJBQTZCLFNBQVMsR0FBRyxDQUFDO0FBQ25ELENBQUMsQ0FBQztBQUVGLDZGQUE2RjtBQUM3RixNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyxDQUFDLElBQWdCLEVBQWdCLEVBQUU7SUFDekUsTUFBTSxXQUFXLEdBQWlCLEVBQUUsQ0FBQztJQUNyQyxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQztJQUMzQixVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUM3QixLQUFLLEVBQUUsQ0FBQyxJQUFtQixFQUFFLEVBQUU7WUFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTztnQkFBRSxPQUFPO1lBQy9CLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDeEMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMzRCxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQUUsUUFBUSxFQUFFLE9BQU8sRUFBRSxPQUFPLEVBQUUsdUJBQXVCLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMzSCxDQUFDO0tBQ0YsQ0FBQyxDQUFDO0lBQ0gsT0FBTyxXQUFXLENBQUM7QUFDckIsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgc3ludGF4VHJlZSB9IGZyb20gJ0Bjb2RlbWlycm9yL2xhbmd1YWdlJztcbmltcG9ydCB7IERpYWdub3N0aWMgfSBmcm9tICdAY29kZW1pcnJvci9saW50JztcbmltcG9ydCB7IFRleHQgfSBmcm9tICdAY29kZW1pcnJvci9zdGF0ZSc7XG5pbXBvcnQgeyBFZGl0b3JWaWV3IH0gZnJvbSAnQGNvZGVtaXJyb3Ivdmlldyc7XG5pbXBvcnQgdHlwZSB7IFN5bnRheE5vZGVSZWYgfSBmcm9tICdAbGV6ZXIvY29tbW9uJztcbmltcG9ydCB7IGdldFRva2VuQmVmb3JlIH0gZnJvbSAnLi9saW50ZXItc2hhcmVkJztcblxuY29uc3QgYnVpbGRQeXRob25FcnJvck1lc3NhZ2UgPSAoZG9jOiBUZXh0LCBub2RlOiBTeW50YXhOb2RlUmVmKTogc3RyaW5nID0+IHtcbiAgaWYgKG5vZGUuZnJvbSAhPT0gbm9kZS50bykge1xuICAgIGNvbnN0IHRleHQgPSBkb2Muc2xpY2VTdHJpbmcobm9kZS5mcm9tLCBub2RlLnRvKS50cmltKCk7XG4gICAgcmV0dXJuIGBQeXRob24gc3ludGF4IGVycm9yJHt0ZXh0ID8gYCBuZWFyIFwiJHt0ZXh0fVwiYCA6ICcnfWA7XG4gIH1cbiAgY29uc3QgcHJldlRva2VuID0gZ2V0VG9rZW5CZWZvcmUoZG9jLCBub2RlLmZyb20pO1xuICBpZiAoIXByZXZUb2tlbikgcmV0dXJuICdQeXRob24gc3ludGF4IGVycm9yJztcbiAgaWYgKC9eZGVmJC9pLnRlc3QocHJldlRva2VuKSkgcmV0dXJuICdFeHBlY3RlZCBmdW5jdGlvbiBuYW1lIGFmdGVyIFwiZGVmXCInO1xuICBpZiAoL15jbGFzcyQvaS50ZXN0KHByZXZUb2tlbikpIHJldHVybiAnRXhwZWN0ZWQgY2xhc3MgbmFtZSBhZnRlciBcImNsYXNzXCInO1xuICBpZiAoL15yZXR1cm4kL2kudGVzdChwcmV2VG9rZW4pKSByZXR1cm4gJ0ludmFsaWQgZXhwcmVzc2lvbiBhZnRlciBcInJldHVyblwiJztcbiAgaWYgKC9eaW1wb3J0JC9pLnRlc3QocHJldlRva2VuKSkgcmV0dXJuICdFeHBlY3RlZCBtb2R1bGUgbmFtZSBhZnRlciBcImltcG9ydFwiJztcbiAgaWYgKC9eZnJvbSQvaS50ZXN0KHByZXZUb2tlbikpIHJldHVybiAnRXhwZWN0ZWQgbW9kdWxlIG5hbWUgYWZ0ZXIgXCJmcm9tXCInO1xuICBpZiAoL15pZiQvaS50ZXN0KHByZXZUb2tlbikpIHJldHVybiAnRXhwZWN0ZWQgY29uZGl0aW9uIGFmdGVyIFwiaWZcIic7XG4gIGlmICgvXmVsaWYkL2kudGVzdChwcmV2VG9rZW4pKSByZXR1cm4gJ0V4cGVjdGVkIGNvbmRpdGlvbiBhZnRlciBcImVsaWZcIic7XG4gIGlmICgvXndoaWxlJC9pLnRlc3QocHJldlRva2VuKSkgcmV0dXJuICdFeHBlY3RlZCBjb25kaXRpb24gYWZ0ZXIgXCJ3aGlsZVwiJztcbiAgaWYgKC9eZm9yJC9pLnRlc3QocHJldlRva2VuKSkgcmV0dXJuICdFeHBlY3RlZCB2YXJpYWJsZSBhZnRlciBcImZvclwiJztcbiAgaWYgKHByZXZUb2tlbi5lbmRzV2l0aCgnLicpKSByZXR1cm4gYEluY29tcGxldGUgYXR0cmlidXRlIGFjY2VzcyBvbiBcIiR7cHJldlRva2VuLnNsaWNlKDAsIC0xKX1cImA7XG4gIGlmIChwcmV2VG9rZW4uZW5kc1dpdGgoJygnKSkgcmV0dXJuICdNaXNzaW5nIGNsb3NpbmcgXCIpXCInO1xuICBpZiAocHJldlRva2VuLmVuZHNXaXRoKCdbJykpIHJldHVybiAnTWlzc2luZyBjbG9zaW5nIFwiXVwiJztcbiAgcmV0dXJuIGBQeXRob24gc3ludGF4IGVycm9yIG5lYXIgXCIke3ByZXZUb2tlbn1cImA7XG59O1xuXG4vKiogUGjDoXQgaGnhu4duIGzhu5dpIGPDuiBwaMOhcCBQeXRob24gdOG7qyBlcnJvciBub2RlIGPhu6dhIHN5bnRheFRyZWUgKExlemVyKSDigJQgY8O5bmcgYXBwcm9hY2ggU1FMLiAqL1xuZXhwb3J0IGNvbnN0IGNvbXB1dGVQeXRob25EaWFnbm9zdGljcyA9ICh2aWV3OiBFZGl0b3JWaWV3KTogRGlhZ25vc3RpY1tdID0+IHtcbiAgY29uc3QgZGlhZ25vc3RpY3M6IERpYWdub3N0aWNbXSA9IFtdO1xuICBjb25zdCBkb2MgPSB2aWV3LnN0YXRlLmRvYztcbiAgc3ludGF4VHJlZSh2aWV3LnN0YXRlKS5pdGVyYXRlKHtcbiAgICBlbnRlcjogKG5vZGU6IFN5bnRheE5vZGVSZWYpID0+IHtcbiAgICAgIGlmICghbm9kZS50eXBlLmlzRXJyb3IpIHJldHVybjtcbiAgICAgIGNvbnN0IGZyb20gPSBNYXRoLm1heCgwLCBub2RlLmZyb20gLSAxKTtcbiAgICAgIGNvbnN0IHRvID0gbm9kZS5mcm9tID09PSBub2RlLnRvID8gbm9kZS5mcm9tICsgMSA6IG5vZGUudG87XG4gICAgICBkaWFnbm9zdGljcy5wdXNoKHsgZnJvbSwgdG86IE1hdGgubWluKHRvLCBkb2MubGVuZ3RoKSwgc2V2ZXJpdHk6ICdlcnJvcicsIG1lc3NhZ2U6IGJ1aWxkUHl0aG9uRXJyb3JNZXNzYWdlKGRvYywgbm9kZSkgfSk7XG4gICAgfSxcbiAgfSk7XG4gIHJldHVybiBkaWFnbm9zdGljcztcbn07XG4iXX0=
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { syntaxTree } from '@codemirror/language';
|
|
2
|
+
import { getTokenBefore } from './linter-shared';
|
|
3
|
+
const buildSqlErrorMessage = (doc, node) => {
|
|
4
|
+
if (node.from !== node.to) {
|
|
5
|
+
const text = doc.sliceString(node.from, node.to);
|
|
6
|
+
return `SQL syntax error near "${text}"`;
|
|
7
|
+
}
|
|
8
|
+
const prevToken = getTokenBefore(doc, node.from);
|
|
9
|
+
if (!prevToken)
|
|
10
|
+
return 'SQL syntax error at beginning of statement';
|
|
11
|
+
if (/FROM$/i.test(prevToken))
|
|
12
|
+
return 'Expected table name after FROM';
|
|
13
|
+
if (/SELECT$/i.test(prevToken))
|
|
14
|
+
return 'Expected column list after SELECT';
|
|
15
|
+
if (/WHERE$/i.test(prevToken))
|
|
16
|
+
return 'Expected condition after WHERE';
|
|
17
|
+
if (prevToken.endsWith('('))
|
|
18
|
+
return 'Missing closing ")"';
|
|
19
|
+
return `Unexpected end of SQL after "${prevToken}"`;
|
|
20
|
+
};
|
|
21
|
+
/** Phát hiện lỗi cú pháp SQL từ error node của syntaxTree (Lezer). */
|
|
22
|
+
export const computeSqlDiagnostics = (view) => {
|
|
23
|
+
const diagnostics = [];
|
|
24
|
+
const doc = view.state.doc;
|
|
25
|
+
syntaxTree(view.state).iterate({
|
|
26
|
+
enter: (node) => {
|
|
27
|
+
if (!node.type.isError)
|
|
28
|
+
return;
|
|
29
|
+
diagnostics.push({ from: Math.max(0, node.from - 1), to: node.from, severity: 'error', message: buildSqlErrorMessage(doc, node) });
|
|
30
|
+
},
|
|
31
|
+
});
|
|
32
|
+
return diagnostics;
|
|
33
|
+
};
|
|
34
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3FsLWxpbnRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL2xpYnMtdWkvY29tcG9uZW50cy9wcmV2aWV3LXRleHQtZGF0YS9zcmMvbGludGVycy9zcWwtbGludGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUtsRCxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFakQsTUFBTSxvQkFBb0IsR0FBRyxDQUFDLEdBQVMsRUFBRSxJQUFtQixFQUFVLEVBQUU7SUFDdEUsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUMxQixNQUFNLElBQUksR0FBRyxHQUFHLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2pELE9BQU8sMEJBQTBCLElBQUksR0FBRyxDQUFDO0lBQzNDLENBQUM7SUFDRCxNQUFNLFNBQVMsR0FBRyxjQUFjLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNqRCxJQUFJLENBQUMsU0FBUztRQUFFLE9BQU8sNENBQTRDLENBQUM7SUFDcEUsSUFBSSxRQUFRLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUFFLE9BQU8sZ0NBQWdDLENBQUM7SUFDdEUsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUFFLE9BQU8sbUNBQW1DLENBQUM7SUFDM0UsSUFBSSxTQUFTLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUFFLE9BQU8sZ0NBQWdDLENBQUM7SUFDdkUsSUFBSSxTQUFTLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztRQUFFLE9BQU8scUJBQXFCLENBQUM7SUFDMUQsT0FBTyxnQ0FBZ0MsU0FBUyxHQUFHLENBQUM7QUFDdEQsQ0FBQyxDQUFDO0FBRUYsc0VBQXNFO0FBQ3RFLE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLENBQUMsSUFBZ0IsRUFBZ0IsRUFBRTtJQUN0RSxNQUFNLFdBQVcsR0FBaUIsRUFBRSxDQUFDO0lBQ3JDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDO0lBQzNCLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsT0FBTyxDQUFDO1FBQzdCLEtBQUssRUFBRSxDQUFDLElBQW1CLEVBQUUsRUFBRTtZQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPO2dCQUFFLE9BQU87WUFDL0IsV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsSUFBSSxHQUFHLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLG9CQUFvQixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDckksQ0FBQztLQUNGLENBQUMsQ0FBQztJQUNILE9BQU8sV0FBVyxDQUFDO0FBQ3JCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHN5bnRheFRyZWUgfSBmcm9tICdAY29kZW1pcnJvci9sYW5ndWFnZSc7XG5pbXBvcnQgeyBEaWFnbm9zdGljIH0gZnJvbSAnQGNvZGVtaXJyb3IvbGludCc7XG5pbXBvcnQgeyBUZXh0IH0gZnJvbSAnQGNvZGVtaXJyb3Ivc3RhdGUnO1xuaW1wb3J0IHsgRWRpdG9yVmlldyB9IGZyb20gJ0Bjb2RlbWlycm9yL3ZpZXcnO1xuaW1wb3J0IHR5cGUgeyBTeW50YXhOb2RlUmVmIH0gZnJvbSAnQGxlemVyL2NvbW1vbic7XG5pbXBvcnQgeyBnZXRUb2tlbkJlZm9yZSB9IGZyb20gJy4vbGludGVyLXNoYXJlZCc7XG5cbmNvbnN0IGJ1aWxkU3FsRXJyb3JNZXNzYWdlID0gKGRvYzogVGV4dCwgbm9kZTogU3ludGF4Tm9kZVJlZik6IHN0cmluZyA9PiB7XG4gIGlmIChub2RlLmZyb20gIT09IG5vZGUudG8pIHtcbiAgICBjb25zdCB0ZXh0ID0gZG9jLnNsaWNlU3RyaW5nKG5vZGUuZnJvbSwgbm9kZS50byk7XG4gICAgcmV0dXJuIGBTUUwgc3ludGF4IGVycm9yIG5lYXIgXCIke3RleHR9XCJgO1xuICB9XG4gIGNvbnN0IHByZXZUb2tlbiA9IGdldFRva2VuQmVmb3JlKGRvYywgbm9kZS5mcm9tKTtcbiAgaWYgKCFwcmV2VG9rZW4pIHJldHVybiAnU1FMIHN5bnRheCBlcnJvciBhdCBiZWdpbm5pbmcgb2Ygc3RhdGVtZW50JztcbiAgaWYgKC9GUk9NJC9pLnRlc3QocHJldlRva2VuKSkgcmV0dXJuICdFeHBlY3RlZCB0YWJsZSBuYW1lIGFmdGVyIEZST00nO1xuICBpZiAoL1NFTEVDVCQvaS50ZXN0KHByZXZUb2tlbikpIHJldHVybiAnRXhwZWN0ZWQgY29sdW1uIGxpc3QgYWZ0ZXIgU0VMRUNUJztcbiAgaWYgKC9XSEVSRSQvaS50ZXN0KHByZXZUb2tlbikpIHJldHVybiAnRXhwZWN0ZWQgY29uZGl0aW9uIGFmdGVyIFdIRVJFJztcbiAgaWYgKHByZXZUb2tlbi5lbmRzV2l0aCgnKCcpKSByZXR1cm4gJ01pc3NpbmcgY2xvc2luZyBcIilcIic7XG4gIHJldHVybiBgVW5leHBlY3RlZCBlbmQgb2YgU1FMIGFmdGVyIFwiJHtwcmV2VG9rZW59XCJgO1xufTtcblxuLyoqIFBow6F0IGhp4buHbiBs4buXaSBjw7ogcGjDoXAgU1FMIHThu6sgZXJyb3Igbm9kZSBj4bunYSBzeW50YXhUcmVlIChMZXplcikuICovXG5leHBvcnQgY29uc3QgY29tcHV0ZVNxbERpYWdub3N0aWNzID0gKHZpZXc6IEVkaXRvclZpZXcpOiBEaWFnbm9zdGljW10gPT4ge1xuICBjb25zdCBkaWFnbm9zdGljczogRGlhZ25vc3RpY1tdID0gW107XG4gIGNvbnN0IGRvYyA9IHZpZXcuc3RhdGUuZG9jO1xuICBzeW50YXhUcmVlKHZpZXcuc3RhdGUpLml0ZXJhdGUoe1xuICAgIGVudGVyOiAobm9kZTogU3ludGF4Tm9kZVJlZikgPT4ge1xuICAgICAgaWYgKCFub2RlLnR5cGUuaXNFcnJvcikgcmV0dXJuO1xuICAgICAgZGlhZ25vc3RpY3MucHVzaCh7IGZyb206IE1hdGgubWF4KDAsIG5vZGUuZnJvbSAtIDEpLCB0bzogbm9kZS5mcm9tLCBzZXZlcml0eTogJ2Vycm9yJywgbWVzc2FnZTogYnVpbGRTcWxFcnJvck1lc3NhZ2UoZG9jLCBub2RlKSB9KTtcbiAgICB9LFxuICB9KTtcbiAgcmV0dXJuIGRpYWdub3N0aWNzO1xufTtcbiJdfQ==
|