@githolon/dsl 0.105.23 → 0.105.24
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/dart/CHANGELOG.md +9 -0
- package/dart/lib/src/runner/node-entry.mjs +4461 -267
- package/dart/lib/src/runner/offline-install.mjs +4337 -115
- package/dart/lib/src/test_harness.dart +316 -235
- package/dart/lib/src/webview_bridge.dart +1478 -1087
- package/dart/pubspec.lock +1 -1
- package/dart/pubspec.yaml +2 -2
- package/dart_types/CHANGELOG.md +5 -0
- package/dart_types/lib/src/errors.dart +78 -58
- package/dart_types/pubspec.yaml +1 -1
- package/package.json +1 -1
- package/runtime/generated-application-host.js +4235 -102
- package/src/codegen_dart_client.ts +7 -10
- package/src/codegen_ts.ts +3 -6
- package/src/compat_manifest.ts +6 -7
- package/src/compile_package_main.ts +9 -11
- package/src/index.ts +9 -11
- package/src/kernel_capabilities.ts +79 -237
|
@@ -6,7 +6,7 @@ var __export = (target, all) => {
|
|
|
6
6
|
};
|
|
7
7
|
|
|
8
8
|
// <define:__NOMOS_KERNEL_RELEASE__>
|
|
9
|
-
var define_NOMOS_KERNEL_RELEASE_default = {
|
|
9
|
+
var define_NOMOS_KERNEL_RELEASE_default = { contracts: { "nomos.kernel.v1": "1.0.0" } };
|
|
10
10
|
|
|
11
11
|
// runner/offline-install.ts
|
|
12
12
|
import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync } from "node:fs";
|
|
@@ -19,15 +19,4159 @@ import { fileURLToPath } from "node:url";
|
|
|
19
19
|
import { statSync, renameSync, writeFileSync, mkdirSync, readFileSync } from "node:fs";
|
|
20
20
|
import { createHash } from "node:crypto";
|
|
21
21
|
import { join } from "node:path";
|
|
22
|
+
|
|
23
|
+
// ../../node_modules/fast-xml-parser/src/util.js
|
|
24
|
+
var nameStartChar = ":A-Za-z_\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02FF\\u0370-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD";
|
|
25
|
+
var nameChar = nameStartChar + "\\-.\\d\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
|
|
26
|
+
var nameRegexp = "[" + nameStartChar + "][" + nameChar + "]*";
|
|
27
|
+
var regexName = new RegExp("^" + nameRegexp + "$");
|
|
28
|
+
function getAllMatches(string, regex) {
|
|
29
|
+
const matches = [];
|
|
30
|
+
let match = regex.exec(string);
|
|
31
|
+
while (match) {
|
|
32
|
+
const allmatches = [];
|
|
33
|
+
allmatches.startIndex = regex.lastIndex - match[0].length;
|
|
34
|
+
const len = match.length;
|
|
35
|
+
for (let index = 0; index < len; index++) {
|
|
36
|
+
allmatches.push(match[index]);
|
|
37
|
+
}
|
|
38
|
+
matches.push(allmatches);
|
|
39
|
+
match = regex.exec(string);
|
|
40
|
+
}
|
|
41
|
+
return matches;
|
|
42
|
+
}
|
|
43
|
+
var isName = function(string) {
|
|
44
|
+
const match = regexName.exec(string);
|
|
45
|
+
return !(match === null || typeof match === "undefined");
|
|
46
|
+
};
|
|
47
|
+
function isExist(v) {
|
|
48
|
+
return typeof v !== "undefined";
|
|
49
|
+
}
|
|
50
|
+
var DANGEROUS_PROPERTY_NAMES = [
|
|
51
|
+
// '__proto__',
|
|
52
|
+
// 'constructor',
|
|
53
|
+
// 'prototype',
|
|
54
|
+
"hasOwnProperty",
|
|
55
|
+
"toString",
|
|
56
|
+
"valueOf",
|
|
57
|
+
"__defineGetter__",
|
|
58
|
+
"__defineSetter__",
|
|
59
|
+
"__lookupGetter__",
|
|
60
|
+
"__lookupSetter__"
|
|
61
|
+
];
|
|
62
|
+
var criticalProperties = ["__proto__", "constructor", "prototype"];
|
|
63
|
+
|
|
64
|
+
// ../../node_modules/fast-xml-parser/src/validator.js
|
|
65
|
+
var defaultOptions = {
|
|
66
|
+
allowBooleanAttributes: false,
|
|
67
|
+
//A tag can have attributes without any value
|
|
68
|
+
unpairedTags: []
|
|
69
|
+
};
|
|
70
|
+
function validate(xmlData, options) {
|
|
71
|
+
options = Object.assign({}, defaultOptions, options);
|
|
72
|
+
const tags = [];
|
|
73
|
+
let tagFound = false;
|
|
74
|
+
let reachedRoot = false;
|
|
75
|
+
if (xmlData[0] === "\uFEFF") {
|
|
76
|
+
xmlData = xmlData.substr(1);
|
|
77
|
+
}
|
|
78
|
+
for (let i = 0; i < xmlData.length; i++) {
|
|
79
|
+
if (xmlData[i] === "<" && xmlData[i + 1] === "?") {
|
|
80
|
+
i += 2;
|
|
81
|
+
i = readPI(xmlData, i);
|
|
82
|
+
if (i.err) return i;
|
|
83
|
+
} else if (xmlData[i] === "<") {
|
|
84
|
+
let tagStartPos = i;
|
|
85
|
+
i++;
|
|
86
|
+
if (xmlData[i] === "!") {
|
|
87
|
+
i = readCommentAndCDATA(xmlData, i);
|
|
88
|
+
continue;
|
|
89
|
+
} else {
|
|
90
|
+
let closingTag = false;
|
|
91
|
+
if (xmlData[i] === "/") {
|
|
92
|
+
closingTag = true;
|
|
93
|
+
i++;
|
|
94
|
+
}
|
|
95
|
+
let tagName = "";
|
|
96
|
+
for (; i < xmlData.length && xmlData[i] !== ">" && xmlData[i] !== " " && xmlData[i] !== " " && xmlData[i] !== "\n" && xmlData[i] !== "\r"; i++) {
|
|
97
|
+
tagName += xmlData[i];
|
|
98
|
+
}
|
|
99
|
+
tagName = tagName.trim();
|
|
100
|
+
if (tagName[tagName.length - 1] === "/") {
|
|
101
|
+
tagName = tagName.substring(0, tagName.length - 1);
|
|
102
|
+
i--;
|
|
103
|
+
}
|
|
104
|
+
if (!validateTagName(tagName)) {
|
|
105
|
+
let msg;
|
|
106
|
+
if (tagName.trim().length === 0) {
|
|
107
|
+
msg = "Invalid space after '<'.";
|
|
108
|
+
} else {
|
|
109
|
+
msg = "Tag '" + tagName + "' is an invalid name.";
|
|
110
|
+
}
|
|
111
|
+
return getErrorObject("InvalidTag", msg, getLineNumberForPosition(xmlData, i));
|
|
112
|
+
}
|
|
113
|
+
const result = readAttributeStr(xmlData, i);
|
|
114
|
+
if (result === false) {
|
|
115
|
+
return getErrorObject("InvalidAttr", "Attributes for '" + tagName + "' have open quote.", getLineNumberForPosition(xmlData, i));
|
|
116
|
+
}
|
|
117
|
+
let attrStr = result.value;
|
|
118
|
+
i = result.index;
|
|
119
|
+
if (attrStr[attrStr.length - 1] === "/") {
|
|
120
|
+
const attrStrStart = i - attrStr.length;
|
|
121
|
+
attrStr = attrStr.substring(0, attrStr.length - 1);
|
|
122
|
+
const isValid = validateAttributeString(attrStr, options);
|
|
123
|
+
if (isValid === true) {
|
|
124
|
+
tagFound = true;
|
|
125
|
+
} else {
|
|
126
|
+
return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, attrStrStart + isValid.err.line));
|
|
127
|
+
}
|
|
128
|
+
} else if (closingTag) {
|
|
129
|
+
if (!result.tagClosed) {
|
|
130
|
+
return getErrorObject("InvalidTag", "Closing tag '" + tagName + "' doesn't have proper closing.", getLineNumberForPosition(xmlData, i));
|
|
131
|
+
} else if (attrStr.trim().length > 0) {
|
|
132
|
+
return getErrorObject("InvalidTag", "Closing tag '" + tagName + "' can't have attributes or invalid starting.", getLineNumberForPosition(xmlData, tagStartPos));
|
|
133
|
+
} else if (tags.length === 0) {
|
|
134
|
+
return getErrorObject("InvalidTag", "Closing tag '" + tagName + "' has not been opened.", getLineNumberForPosition(xmlData, tagStartPos));
|
|
135
|
+
} else {
|
|
136
|
+
const otg = tags.pop();
|
|
137
|
+
if (tagName !== otg.tagName) {
|
|
138
|
+
let openPos = getLineNumberForPosition(xmlData, otg.tagStartPos);
|
|
139
|
+
return getErrorObject(
|
|
140
|
+
"InvalidTag",
|
|
141
|
+
"Expected closing tag '" + otg.tagName + "' (opened in line " + openPos.line + ", col " + openPos.col + ") instead of closing tag '" + tagName + "'.",
|
|
142
|
+
getLineNumberForPosition(xmlData, tagStartPos)
|
|
143
|
+
);
|
|
144
|
+
}
|
|
145
|
+
if (tags.length == 0) {
|
|
146
|
+
reachedRoot = true;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
} else {
|
|
150
|
+
const isValid = validateAttributeString(attrStr, options);
|
|
151
|
+
if (isValid !== true) {
|
|
152
|
+
return getErrorObject(isValid.err.code, isValid.err.msg, getLineNumberForPosition(xmlData, i - attrStr.length + isValid.err.line));
|
|
153
|
+
}
|
|
154
|
+
if (reachedRoot === true) {
|
|
155
|
+
return getErrorObject("InvalidXml", "Multiple possible root nodes found.", getLineNumberForPosition(xmlData, i));
|
|
156
|
+
} else if (options.unpairedTags.indexOf(tagName) !== -1) {
|
|
157
|
+
} else {
|
|
158
|
+
tags.push({ tagName, tagStartPos });
|
|
159
|
+
}
|
|
160
|
+
tagFound = true;
|
|
161
|
+
}
|
|
162
|
+
for (i++; i < xmlData.length; i++) {
|
|
163
|
+
if (xmlData[i] === "<") {
|
|
164
|
+
if (xmlData[i + 1] === "!") {
|
|
165
|
+
i++;
|
|
166
|
+
i = readCommentAndCDATA(xmlData, i);
|
|
167
|
+
continue;
|
|
168
|
+
} else if (xmlData[i + 1] === "?") {
|
|
169
|
+
i = readPI(xmlData, ++i);
|
|
170
|
+
if (i.err) return i;
|
|
171
|
+
} else {
|
|
172
|
+
break;
|
|
173
|
+
}
|
|
174
|
+
} else if (xmlData[i] === "&") {
|
|
175
|
+
const afterAmp = validateAmpersand(xmlData, i);
|
|
176
|
+
if (afterAmp == -1)
|
|
177
|
+
return getErrorObject("InvalidChar", "char '&' is not expected.", getLineNumberForPosition(xmlData, i));
|
|
178
|
+
i = afterAmp;
|
|
179
|
+
} else {
|
|
180
|
+
if (reachedRoot === true && !isWhiteSpace(xmlData[i])) {
|
|
181
|
+
return getErrorObject("InvalidXml", "Extra text at the end", getLineNumberForPosition(xmlData, i));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
if (xmlData[i] === "<") {
|
|
186
|
+
i--;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
} else {
|
|
190
|
+
if (isWhiteSpace(xmlData[i])) {
|
|
191
|
+
continue;
|
|
192
|
+
}
|
|
193
|
+
return getErrorObject("InvalidChar", "char '" + xmlData[i] + "' is not expected.", getLineNumberForPosition(xmlData, i));
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
if (!tagFound) {
|
|
197
|
+
return getErrorObject("InvalidXml", "Start tag expected.", 1);
|
|
198
|
+
} else if (tags.length == 1) {
|
|
199
|
+
return getErrorObject("InvalidTag", "Unclosed tag '" + tags[0].tagName + "'.", getLineNumberForPosition(xmlData, tags[0].tagStartPos));
|
|
200
|
+
} else if (tags.length > 0) {
|
|
201
|
+
return getErrorObject("InvalidXml", "Invalid '" + JSON.stringify(tags.map((t) => t.tagName), null, 4).replace(/\r?\n/g, "") + "' found.", { line: 1, col: 1 });
|
|
202
|
+
}
|
|
203
|
+
return true;
|
|
204
|
+
}
|
|
205
|
+
function isWhiteSpace(char) {
|
|
206
|
+
return char === " " || char === " " || char === "\n" || char === "\r";
|
|
207
|
+
}
|
|
208
|
+
function readPI(xmlData, i) {
|
|
209
|
+
const start = i;
|
|
210
|
+
for (; i < xmlData.length; i++) {
|
|
211
|
+
if (xmlData[i] == "?" || xmlData[i] == " ") {
|
|
212
|
+
const tagname = xmlData.substr(start, i - start);
|
|
213
|
+
if (i > 5 && tagname === "xml") {
|
|
214
|
+
return getErrorObject("InvalidXml", "XML declaration allowed only at the start of the document.", getLineNumberForPosition(xmlData, i));
|
|
215
|
+
} else if (xmlData[i] == "?" && xmlData[i + 1] == ">") {
|
|
216
|
+
i++;
|
|
217
|
+
break;
|
|
218
|
+
} else {
|
|
219
|
+
continue;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
return i;
|
|
224
|
+
}
|
|
225
|
+
function readCommentAndCDATA(xmlData, i) {
|
|
226
|
+
if (xmlData.length > i + 5 && xmlData[i + 1] === "-" && xmlData[i + 2] === "-") {
|
|
227
|
+
for (i += 3; i < xmlData.length; i++) {
|
|
228
|
+
if (xmlData[i] === "-" && xmlData[i + 1] === "-" && xmlData[i + 2] === ">") {
|
|
229
|
+
i += 2;
|
|
230
|
+
break;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
} else if (xmlData.length > i + 8 && xmlData[i + 1] === "D" && xmlData[i + 2] === "O" && xmlData[i + 3] === "C" && xmlData[i + 4] === "T" && xmlData[i + 5] === "Y" && xmlData[i + 6] === "P" && xmlData[i + 7] === "E") {
|
|
234
|
+
let angleBracketsCount = 1;
|
|
235
|
+
for (i += 8; i < xmlData.length; i++) {
|
|
236
|
+
if (xmlData[i] === "<") {
|
|
237
|
+
angleBracketsCount++;
|
|
238
|
+
} else if (xmlData[i] === ">") {
|
|
239
|
+
angleBracketsCount--;
|
|
240
|
+
if (angleBracketsCount === 0) {
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
} else if (xmlData.length > i + 9 && xmlData[i + 1] === "[" && xmlData[i + 2] === "C" && xmlData[i + 3] === "D" && xmlData[i + 4] === "A" && xmlData[i + 5] === "T" && xmlData[i + 6] === "A" && xmlData[i + 7] === "[") {
|
|
246
|
+
for (i += 8; i < xmlData.length; i++) {
|
|
247
|
+
if (xmlData[i] === "]" && xmlData[i + 1] === "]" && xmlData[i + 2] === ">") {
|
|
248
|
+
i += 2;
|
|
249
|
+
break;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return i;
|
|
254
|
+
}
|
|
255
|
+
var doubleQuote = '"';
|
|
256
|
+
var singleQuote = "'";
|
|
257
|
+
function readAttributeStr(xmlData, i) {
|
|
258
|
+
let attrStr = "";
|
|
259
|
+
let startChar = "";
|
|
260
|
+
let tagClosed = false;
|
|
261
|
+
for (; i < xmlData.length; i++) {
|
|
262
|
+
if (xmlData[i] === doubleQuote || xmlData[i] === singleQuote) {
|
|
263
|
+
if (startChar === "") {
|
|
264
|
+
startChar = xmlData[i];
|
|
265
|
+
} else if (startChar !== xmlData[i]) {
|
|
266
|
+
} else {
|
|
267
|
+
startChar = "";
|
|
268
|
+
}
|
|
269
|
+
} else if (xmlData[i] === ">") {
|
|
270
|
+
if (startChar === "") {
|
|
271
|
+
tagClosed = true;
|
|
272
|
+
break;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
attrStr += xmlData[i];
|
|
276
|
+
}
|
|
277
|
+
if (startChar !== "") {
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
value: attrStr,
|
|
282
|
+
index: i,
|
|
283
|
+
tagClosed
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
var validAttrStrRegxp = new RegExp(`(\\s*)([^\\s=]+)(\\s*=)?(\\s*(['"])(([\\s\\S])*?)\\5)?`, "g");
|
|
287
|
+
function validateAttributeString(attrStr, options) {
|
|
288
|
+
const matches = getAllMatches(attrStr, validAttrStrRegxp);
|
|
289
|
+
const attrNames = {};
|
|
290
|
+
for (let i = 0; i < matches.length; i++) {
|
|
291
|
+
if (matches[i][1].length === 0) {
|
|
292
|
+
return getErrorObject("InvalidAttr", "Attribute '" + matches[i][2] + "' has no space in starting.", getPositionFromMatch(matches[i]));
|
|
293
|
+
} else if (matches[i][3] !== void 0 && matches[i][4] === void 0) {
|
|
294
|
+
return getErrorObject("InvalidAttr", "Attribute '" + matches[i][2] + "' is without value.", getPositionFromMatch(matches[i]));
|
|
295
|
+
} else if (matches[i][3] === void 0 && !options.allowBooleanAttributes) {
|
|
296
|
+
return getErrorObject("InvalidAttr", "boolean attribute '" + matches[i][2] + "' is not allowed.", getPositionFromMatch(matches[i]));
|
|
297
|
+
}
|
|
298
|
+
const attrName = matches[i][2];
|
|
299
|
+
if (!validateAttrName(attrName)) {
|
|
300
|
+
return getErrorObject("InvalidAttr", "Attribute '" + attrName + "' is an invalid name.", getPositionFromMatch(matches[i]));
|
|
301
|
+
}
|
|
302
|
+
if (!Object.prototype.hasOwnProperty.call(attrNames, attrName)) {
|
|
303
|
+
attrNames[attrName] = 1;
|
|
304
|
+
} else {
|
|
305
|
+
return getErrorObject("InvalidAttr", "Attribute '" + attrName + "' is repeated.", getPositionFromMatch(matches[i]));
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
function validateNumberAmpersand(xmlData, i) {
|
|
311
|
+
let re = /\d/;
|
|
312
|
+
if (xmlData[i] === "x") {
|
|
313
|
+
i++;
|
|
314
|
+
re = /[\da-fA-F]/;
|
|
315
|
+
}
|
|
316
|
+
for (; i < xmlData.length; i++) {
|
|
317
|
+
if (xmlData[i] === ";")
|
|
318
|
+
return i;
|
|
319
|
+
if (!xmlData[i].match(re))
|
|
320
|
+
break;
|
|
321
|
+
}
|
|
322
|
+
return -1;
|
|
323
|
+
}
|
|
324
|
+
function validateAmpersand(xmlData, i) {
|
|
325
|
+
i++;
|
|
326
|
+
if (xmlData[i] === ";")
|
|
327
|
+
return -1;
|
|
328
|
+
if (xmlData[i] === "#") {
|
|
329
|
+
i++;
|
|
330
|
+
return validateNumberAmpersand(xmlData, i);
|
|
331
|
+
}
|
|
332
|
+
let count2 = 0;
|
|
333
|
+
for (; i < xmlData.length; i++, count2++) {
|
|
334
|
+
if (xmlData[i].match(/\w/) && count2 < 20)
|
|
335
|
+
continue;
|
|
336
|
+
if (xmlData[i] === ";")
|
|
337
|
+
break;
|
|
338
|
+
return -1;
|
|
339
|
+
}
|
|
340
|
+
return i;
|
|
341
|
+
}
|
|
342
|
+
function getErrorObject(code, message, lineNumber) {
|
|
343
|
+
return {
|
|
344
|
+
err: {
|
|
345
|
+
code,
|
|
346
|
+
msg: message,
|
|
347
|
+
line: lineNumber.line || lineNumber,
|
|
348
|
+
col: lineNumber.col
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
function validateAttrName(attrName) {
|
|
353
|
+
return isName(attrName);
|
|
354
|
+
}
|
|
355
|
+
function validateTagName(tagname) {
|
|
356
|
+
return isName(tagname);
|
|
357
|
+
}
|
|
358
|
+
function getLineNumberForPosition(xmlData, index) {
|
|
359
|
+
const lines = xmlData.substring(0, index).split(/\r?\n/);
|
|
360
|
+
return {
|
|
361
|
+
line: lines.length,
|
|
362
|
+
// column number is last line's length + 1, because column numbering starts at 1:
|
|
363
|
+
col: lines[lines.length - 1].length + 1
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
function getPositionFromMatch(match) {
|
|
367
|
+
return match.startIndex + match[1].length;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
// ../../node_modules/@nodable/entities/src/entities.js
|
|
371
|
+
var CURRENCY = {
|
|
372
|
+
cent: "\xA2",
|
|
373
|
+
pound: "\xA3",
|
|
374
|
+
curren: "\xA4",
|
|
375
|
+
yen: "\xA5",
|
|
376
|
+
euro: "\u20AC",
|
|
377
|
+
dollar: "$",
|
|
378
|
+
fnof: "\u0192",
|
|
379
|
+
inr: "\u20B9",
|
|
380
|
+
af: "\u060B",
|
|
381
|
+
birr: "\u1265\u122D",
|
|
382
|
+
peso: "\u20B1",
|
|
383
|
+
rub: "\u20BD",
|
|
384
|
+
won: "\u20A9",
|
|
385
|
+
yuan: "\xA5",
|
|
386
|
+
cedil: "\xB8"
|
|
387
|
+
};
|
|
388
|
+
var XML = {
|
|
389
|
+
amp: "&",
|
|
390
|
+
apos: "'",
|
|
391
|
+
gt: ">",
|
|
392
|
+
lt: "<",
|
|
393
|
+
quot: '"'
|
|
394
|
+
};
|
|
395
|
+
var COMMON_HTML = {
|
|
396
|
+
nbsp: "\xA0",
|
|
397
|
+
copy: "\xA9",
|
|
398
|
+
reg: "\xAE",
|
|
399
|
+
trade: "\u2122",
|
|
400
|
+
mdash: "\u2014",
|
|
401
|
+
ndash: "\u2013",
|
|
402
|
+
hellip: "\u2026",
|
|
403
|
+
laquo: "\xAB",
|
|
404
|
+
raquo: "\xBB",
|
|
405
|
+
lsquo: "\u2018",
|
|
406
|
+
rsquo: "\u2019",
|
|
407
|
+
ldquo: "\u201C",
|
|
408
|
+
rdquo: "\u201D",
|
|
409
|
+
bull: "\u2022",
|
|
410
|
+
para: "\xB6",
|
|
411
|
+
sect: "\xA7",
|
|
412
|
+
deg: "\xB0",
|
|
413
|
+
frac12: "\xBD",
|
|
414
|
+
frac14: "\xBC",
|
|
415
|
+
frac34: "\xBE"
|
|
416
|
+
};
|
|
417
|
+
|
|
418
|
+
// ../../node_modules/@nodable/entities/src/EntityDecoder.js
|
|
419
|
+
var ENTITY_ACTION = Object.freeze({
|
|
420
|
+
/** Resolve and expand the entity normally. */
|
|
421
|
+
ALLOW: "allow",
|
|
422
|
+
/** Silently skip this entity — it will not be registered. */
|
|
423
|
+
BLOCK: "block",
|
|
424
|
+
/** Throw an error, aborting entity registration entirely. */
|
|
425
|
+
THROW: "throw"
|
|
426
|
+
});
|
|
427
|
+
var SPECIAL_CHARS = new Set("!?\\\\/[]$%{}^&*()<>|+");
|
|
428
|
+
function validateEntityName(name) {
|
|
429
|
+
if (name[0] === "#") {
|
|
430
|
+
throw new Error(`[EntityReplacer] Invalid character '#' in entity name: "${name}"`);
|
|
431
|
+
}
|
|
432
|
+
for (const ch of name) {
|
|
433
|
+
if (SPECIAL_CHARS.has(ch)) {
|
|
434
|
+
throw new Error(`[EntityReplacer] Invalid character '${ch}' in entity name: "${name}"`);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
return name;
|
|
438
|
+
}
|
|
439
|
+
function mergeEntityMaps(...maps) {
|
|
440
|
+
const out = /* @__PURE__ */ Object.create(null);
|
|
441
|
+
for (const map of maps) {
|
|
442
|
+
if (!map) continue;
|
|
443
|
+
for (const key of Object.keys(map)) {
|
|
444
|
+
const raw = map[key];
|
|
445
|
+
if (typeof raw === "string") {
|
|
446
|
+
out[key] = raw;
|
|
447
|
+
} else if (raw && typeof raw === "object" && raw.val !== void 0) {
|
|
448
|
+
const val = raw.val;
|
|
449
|
+
if (typeof val === "string") {
|
|
450
|
+
out[key] = val;
|
|
451
|
+
}
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return out;
|
|
456
|
+
}
|
|
457
|
+
var LIMIT_TIER_EXTERNAL = "external";
|
|
458
|
+
var LIMIT_TIER_BASE = "base";
|
|
459
|
+
var LIMIT_TIER_ALL = "all";
|
|
460
|
+
function parseLimitTiers(raw) {
|
|
461
|
+
if (!raw || raw === LIMIT_TIER_EXTERNAL) return /* @__PURE__ */ new Set([LIMIT_TIER_EXTERNAL]);
|
|
462
|
+
if (raw === LIMIT_TIER_ALL) return /* @__PURE__ */ new Set([LIMIT_TIER_ALL]);
|
|
463
|
+
if (raw === LIMIT_TIER_BASE) return /* @__PURE__ */ new Set([LIMIT_TIER_BASE]);
|
|
464
|
+
if (Array.isArray(raw)) return new Set(raw);
|
|
465
|
+
return /* @__PURE__ */ new Set([LIMIT_TIER_EXTERNAL]);
|
|
466
|
+
}
|
|
467
|
+
var NCR_LEVEL = Object.freeze({ allow: 0, leave: 1, remove: 2, throw: 3 });
|
|
468
|
+
var XML10_ALLOWED_C0 = /* @__PURE__ */ new Set([9, 10, 13]);
|
|
469
|
+
function parseNCRConfig(ncr) {
|
|
470
|
+
if (!ncr) {
|
|
471
|
+
return { xmlVersion: 1, onLevel: NCR_LEVEL.allow, nullLevel: NCR_LEVEL.remove };
|
|
472
|
+
}
|
|
473
|
+
const xmlVersion = ncr.xmlVersion === 1.1 ? 1.1 : 1;
|
|
474
|
+
const onLevel = NCR_LEVEL[ncr.onNCR] ?? NCR_LEVEL.allow;
|
|
475
|
+
const nullLevel = NCR_LEVEL[ncr.nullNCR] ?? NCR_LEVEL.remove;
|
|
476
|
+
const clampedNull = Math.max(nullLevel, NCR_LEVEL.remove);
|
|
477
|
+
return { xmlVersion, onLevel, nullLevel: clampedNull };
|
|
478
|
+
}
|
|
479
|
+
var EntityDecoder = class {
|
|
480
|
+
/**
|
|
481
|
+
* @param {object} [options]
|
|
482
|
+
* @param {object|null} [options.namedEntities] — extra named entities merged into base map
|
|
483
|
+
* @param {object} [options.limit] — security limits
|
|
484
|
+
* @param {number} [options.limit.maxTotalExpansions=0] — 0 = unlimited
|
|
485
|
+
* @param {number} [options.limit.maxExpandedLength=0] — 0 = unlimited
|
|
486
|
+
* @param {'external'|'base'|'all'|string[]} [options.limit.applyLimitsTo='external']
|
|
487
|
+
* Which entity tiers count against the security limits:
|
|
488
|
+
* - 'external' (default) — only input/runtime + persistent external entities
|
|
489
|
+
* - 'base' — only DEFAULT_XML_ENTITIES + namedEntities
|
|
490
|
+
* - 'all' — every entity regardless of tier
|
|
491
|
+
* - string[] — explicit combination, e.g. ['external', 'base']
|
|
492
|
+
* @param {((resolved: string, original: string) => string)|null} [options.postCheck=null]
|
|
493
|
+
* @param {string[]} [options.remove=[]] — entity names (e.g. ['nbsp', '#13']) to delete (replace with empty string)
|
|
494
|
+
* @param {string[]} [options.leave=[]] — entity names to keep as literal (unchanged in output)
|
|
495
|
+
* @param {object} [options.ncr] — Numeric Character Reference controls
|
|
496
|
+
* @param {1.0|1.1} [options.ncr.xmlVersion=1.0]
|
|
497
|
+
* XML version governing which codepoint ranges are restricted:
|
|
498
|
+
* - 1.0 — C0 controls U+0001–U+001F (except U+0009/000A/000D) are prohibited
|
|
499
|
+
* - 1.1 — C0 controls are allowed when written as NCRs; C1 (U+007F–U+009F) decoded as-is
|
|
500
|
+
* @param {'allow'|'leave'|'remove'|'throw'} [options.ncr.onNCR='allow']
|
|
501
|
+
* Base action for numeric references. Severity order: allow < leave < remove < throw.
|
|
502
|
+
* For codepoint ranges that carry a minimum level (surrogates → remove, XML 1.0 C0 → remove),
|
|
503
|
+
* the effective action is max(onNCR, rangeMinimum).
|
|
504
|
+
* @param {'remove'|'throw'} [options.ncr.nullNCR='remove']
|
|
505
|
+
* Action for U+0000 (null). 'allow' and 'leave' are clamped to 'remove' since null is never safe.
|
|
506
|
+
* @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} [options.onExternalEntity=null]
|
|
507
|
+
* Hook called when an external entity is registered via `setExternalEntities()` or
|
|
508
|
+
* `addExternalEntity()`. Return `ENTITY_ACTION.ALLOW` to accept the entity,
|
|
509
|
+
* `ENTITY_ACTION.BLOCK` to silently skip it, or `ENTITY_ACTION.THROW` to abort with an error.
|
|
510
|
+
* @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} [options.onInputEntity=null]
|
|
511
|
+
* Hook called when an input entity is registered via `addInputEntities()`. Return
|
|
512
|
+
* `ENTITY_ACTION.ALLOW` to accept, `ENTITY_ACTION.BLOCK` to silently skip, or
|
|
513
|
+
* `ENTITY_ACTION.THROW` to abort with an error.
|
|
514
|
+
*/
|
|
515
|
+
constructor(options = {}) {
|
|
516
|
+
this._limit = options.limit || {};
|
|
517
|
+
this._maxTotalExpansions = this._limit.maxTotalExpansions || 0;
|
|
518
|
+
this._maxExpandedLength = this._limit.maxExpandedLength || 0;
|
|
519
|
+
this._postCheck = typeof options.postCheck === "function" ? options.postCheck : (r) => r;
|
|
520
|
+
this._limitTiers = parseLimitTiers(this._limit.applyLimitsTo ?? LIMIT_TIER_EXTERNAL);
|
|
521
|
+
this._numericAllowed = options.numericAllowed ?? true;
|
|
522
|
+
this._baseMap = mergeEntityMaps(XML, options.namedEntities || null);
|
|
523
|
+
this._externalMap = /* @__PURE__ */ Object.create(null);
|
|
524
|
+
this._inputMap = /* @__PURE__ */ Object.create(null);
|
|
525
|
+
this._totalExpansions = 0;
|
|
526
|
+
this._expandedLength = 0;
|
|
527
|
+
this._removeSet = new Set(options.remove && Array.isArray(options.remove) ? options.remove : []);
|
|
528
|
+
this._leaveSet = new Set(options.leave && Array.isArray(options.leave) ? options.leave : []);
|
|
529
|
+
const ncrCfg = parseNCRConfig(options.ncr);
|
|
530
|
+
this._ncrXmlVersion = ncrCfg.xmlVersion;
|
|
531
|
+
this._ncrOnLevel = ncrCfg.onLevel;
|
|
532
|
+
this._ncrNullLevel = ncrCfg.nullLevel;
|
|
533
|
+
this._onExternalEntity = typeof options.onExternalEntity === "function" ? options.onExternalEntity : null;
|
|
534
|
+
this._onInputEntity = typeof options.onInputEntity === "function" ? options.onInputEntity : null;
|
|
535
|
+
}
|
|
536
|
+
// -------------------------------------------------------------------------
|
|
537
|
+
// Private: registration hook dispatch
|
|
538
|
+
// -------------------------------------------------------------------------
|
|
539
|
+
/**
|
|
540
|
+
* Invoke a registration hook for a single entity name/value pair.
|
|
541
|
+
* Returns true when the entity should be accepted, false when it should be
|
|
542
|
+
* silently skipped (BLOCK), and throws when the hook returns THROW.
|
|
543
|
+
*
|
|
544
|
+
* @param {((name: string, value: string) => 'allow'|'block'|'throw')|null} hook
|
|
545
|
+
* @param {string} name
|
|
546
|
+
* @param {string} value
|
|
547
|
+
* @param {string} context — used in error messages ('external' | 'input')
|
|
548
|
+
* @returns {boolean} true = accept, false = skip
|
|
549
|
+
*/
|
|
550
|
+
_applyRegistrationHook(hook, name, value, context) {
|
|
551
|
+
if (!hook) return true;
|
|
552
|
+
const action = hook(name, value);
|
|
553
|
+
if (action === ENTITY_ACTION.BLOCK) return false;
|
|
554
|
+
if (action === ENTITY_ACTION.THROW) {
|
|
555
|
+
throw new Error(
|
|
556
|
+
`[EntityDecoder] Registration of ${context} entity "&${name};" was rejected by hook`
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
return true;
|
|
560
|
+
}
|
|
561
|
+
// -------------------------------------------------------------------------
|
|
562
|
+
// Persistent external entity registration
|
|
563
|
+
// -------------------------------------------------------------------------
|
|
564
|
+
/**
|
|
565
|
+
* Replace the full set of persistent external entities.
|
|
566
|
+
* All keys are validated — throws on invalid characters.
|
|
567
|
+
* If `onExternalEntity` is set, it is called once per entry; entries that
|
|
568
|
+
* return `ENTITY_ACTION.BLOCK` are silently omitted, `ENTITY_ACTION.THROW`
|
|
569
|
+
* aborts the whole call.
|
|
570
|
+
* @param {Record<string, string | { regex?: RegExp, val: string }>} map
|
|
571
|
+
*/
|
|
572
|
+
setExternalEntities(map) {
|
|
573
|
+
if (map) {
|
|
574
|
+
for (const key of Object.keys(map)) {
|
|
575
|
+
validateEntityName(key);
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
if (!this._onExternalEntity) {
|
|
579
|
+
this._externalMap = mergeEntityMaps(map);
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
const flat = mergeEntityMaps(map);
|
|
583
|
+
const filtered = /* @__PURE__ */ Object.create(null);
|
|
584
|
+
for (const [name, value] of Object.entries(flat)) {
|
|
585
|
+
if (this._applyRegistrationHook(this._onExternalEntity, name, value, "external")) {
|
|
586
|
+
filtered[name] = value;
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
this._externalMap = filtered;
|
|
590
|
+
}
|
|
591
|
+
/**
|
|
592
|
+
* Add a single persistent external entity.
|
|
593
|
+
* If `onExternalEntity` is set it is called before the entity is stored;
|
|
594
|
+
* `ENTITY_ACTION.BLOCK` silently skips storage, `ENTITY_ACTION.THROW` raises.
|
|
595
|
+
* @param {string} key
|
|
596
|
+
* @param {string} value
|
|
597
|
+
*/
|
|
598
|
+
addExternalEntity(key, value) {
|
|
599
|
+
validateEntityName(key);
|
|
600
|
+
if (typeof value === "string" && value.indexOf("&") === -1) {
|
|
601
|
+
if (this._applyRegistrationHook(this._onExternalEntity, key, value, "external")) {
|
|
602
|
+
this._externalMap[key] = value;
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
}
|
|
606
|
+
// -------------------------------------------------------------------------
|
|
607
|
+
// Input / runtime entity registration (per document)
|
|
608
|
+
// -------------------------------------------------------------------------
|
|
609
|
+
/**
|
|
610
|
+
* Inject DOCTYPE entities for the current document.
|
|
611
|
+
* Also resets per-document expansion counters.
|
|
612
|
+
* If `onInputEntity` is set it is called once per entry; entries returning
|
|
613
|
+
* `ENTITY_ACTION.BLOCK` are silently omitted, `ENTITY_ACTION.THROW` aborts.
|
|
614
|
+
* @param {Record<string, string | { regx?: RegExp, regex?: RegExp, val: string }>} map
|
|
615
|
+
*/
|
|
616
|
+
addInputEntities(map) {
|
|
617
|
+
this._totalExpansions = 0;
|
|
618
|
+
this._expandedLength = 0;
|
|
619
|
+
if (!this._onInputEntity) {
|
|
620
|
+
this._inputMap = mergeEntityMaps(map);
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
const flat = mergeEntityMaps(map);
|
|
624
|
+
const filtered = /* @__PURE__ */ Object.create(null);
|
|
625
|
+
for (const [name, value] of Object.entries(flat)) {
|
|
626
|
+
if (this._applyRegistrationHook(this._onInputEntity, name, value, "input")) {
|
|
627
|
+
filtered[name] = value;
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
this._inputMap = filtered;
|
|
631
|
+
}
|
|
632
|
+
// -------------------------------------------------------------------------
|
|
633
|
+
// Per-document reset
|
|
634
|
+
// -------------------------------------------------------------------------
|
|
635
|
+
/**
|
|
636
|
+
* Wipe input/runtime entities and reset counters.
|
|
637
|
+
* Call this before processing each new document.
|
|
638
|
+
* @returns {this}
|
|
639
|
+
*/
|
|
640
|
+
reset() {
|
|
641
|
+
this._inputMap = /* @__PURE__ */ Object.create(null);
|
|
642
|
+
this._totalExpansions = 0;
|
|
643
|
+
this._expandedLength = 0;
|
|
644
|
+
return this;
|
|
645
|
+
}
|
|
646
|
+
// -------------------------------------------------------------------------
|
|
647
|
+
// XML version (can be set after construction, e.g. once parser reads <?xml?>)
|
|
648
|
+
// -------------------------------------------------------------------------
|
|
649
|
+
/**
|
|
650
|
+
* Update the XML version used for NCR classification.
|
|
651
|
+
* Call this as soon as the document's `<?xml version="...">` declaration is parsed.
|
|
652
|
+
* @param {1.0|1.1|number} version
|
|
653
|
+
*/
|
|
654
|
+
setXmlVersion(version) {
|
|
655
|
+
this._ncrXmlVersion = version === 1.1 ? 1.1 : 1;
|
|
656
|
+
}
|
|
657
|
+
// -------------------------------------------------------------------------
|
|
658
|
+
// Primary API
|
|
659
|
+
// -------------------------------------------------------------------------
|
|
660
|
+
/**
|
|
661
|
+
* Replace all entity references in `str` in a single pass.
|
|
662
|
+
*
|
|
663
|
+
* @param {string} str
|
|
664
|
+
* @returns {string}
|
|
665
|
+
*/
|
|
666
|
+
decode(str) {
|
|
667
|
+
if (typeof str !== "string" || str.length === 0) return str;
|
|
668
|
+
if (str.indexOf("&") === -1) return str;
|
|
669
|
+
const original = str;
|
|
670
|
+
const chunks = [];
|
|
671
|
+
const len = str.length;
|
|
672
|
+
let last = 0;
|
|
673
|
+
let i = 0;
|
|
674
|
+
const limitExpansions = this._maxTotalExpansions > 0;
|
|
675
|
+
const limitLength = this._maxExpandedLength > 0;
|
|
676
|
+
const checkLimits = limitExpansions || limitLength;
|
|
677
|
+
while (i < len) {
|
|
678
|
+
if (str.charCodeAt(i) !== 38) {
|
|
679
|
+
i++;
|
|
680
|
+
continue;
|
|
681
|
+
}
|
|
682
|
+
let j = i + 1;
|
|
683
|
+
while (j < len && str.charCodeAt(j) !== 59 && j - i <= 32) j++;
|
|
684
|
+
if (j >= len || str.charCodeAt(j) !== 59) {
|
|
685
|
+
i++;
|
|
686
|
+
continue;
|
|
687
|
+
}
|
|
688
|
+
const token = str.slice(i + 1, j);
|
|
689
|
+
if (token.length === 0) {
|
|
690
|
+
i++;
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
let replacement;
|
|
694
|
+
let tier;
|
|
695
|
+
if (this._removeSet.has(token)) {
|
|
696
|
+
replacement = "";
|
|
697
|
+
if (tier === void 0) {
|
|
698
|
+
tier = LIMIT_TIER_EXTERNAL;
|
|
699
|
+
}
|
|
700
|
+
} else if (this._leaveSet.has(token)) {
|
|
701
|
+
i++;
|
|
702
|
+
continue;
|
|
703
|
+
} else if (token.charCodeAt(0) === 35) {
|
|
704
|
+
const ncrResult = this._resolveNCR(token);
|
|
705
|
+
if (ncrResult === void 0) {
|
|
706
|
+
i++;
|
|
707
|
+
continue;
|
|
708
|
+
}
|
|
709
|
+
replacement = ncrResult;
|
|
710
|
+
tier = LIMIT_TIER_BASE;
|
|
711
|
+
} else {
|
|
712
|
+
const resolved = this._resolveName(token);
|
|
713
|
+
replacement = resolved?.value;
|
|
714
|
+
tier = resolved?.tier;
|
|
715
|
+
}
|
|
716
|
+
if (replacement === void 0) {
|
|
717
|
+
i++;
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
if (i > last) chunks.push(str.slice(last, i));
|
|
721
|
+
chunks.push(replacement);
|
|
722
|
+
last = j + 1;
|
|
723
|
+
i = last;
|
|
724
|
+
if (checkLimits && this._tierCounts(tier)) {
|
|
725
|
+
if (limitExpansions) {
|
|
726
|
+
this._totalExpansions++;
|
|
727
|
+
if (this._totalExpansions > this._maxTotalExpansions) {
|
|
728
|
+
throw new Error(
|
|
729
|
+
`[EntityReplacer] Entity expansion count limit exceeded: ${this._totalExpansions} > ${this._maxTotalExpansions}`
|
|
730
|
+
);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
if (limitLength) {
|
|
734
|
+
const delta = replacement.length - (token.length + 2);
|
|
735
|
+
if (delta > 0) {
|
|
736
|
+
this._expandedLength += delta;
|
|
737
|
+
if (this._expandedLength > this._maxExpandedLength) {
|
|
738
|
+
throw new Error(
|
|
739
|
+
`[EntityReplacer] Expanded content length limit exceeded: ${this._expandedLength} > ${this._maxExpandedLength}`
|
|
740
|
+
);
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
}
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
if (last < len) chunks.push(str.slice(last));
|
|
747
|
+
const result = chunks.length === 0 ? str : chunks.join("");
|
|
748
|
+
return this._postCheck(result, original);
|
|
749
|
+
}
|
|
750
|
+
// -------------------------------------------------------------------------
|
|
751
|
+
// Private: limit tier check
|
|
752
|
+
// -------------------------------------------------------------------------
|
|
753
|
+
/**
|
|
754
|
+
* Returns true if a resolved entity of the given tier should count
|
|
755
|
+
* against the expansion/length limits.
|
|
756
|
+
* @param {string} tier — LIMIT_TIER_EXTERNAL | LIMIT_TIER_BASE
|
|
757
|
+
* @returns {boolean}
|
|
758
|
+
*/
|
|
759
|
+
_tierCounts(tier) {
|
|
760
|
+
if (this._limitTiers.has(LIMIT_TIER_ALL)) return true;
|
|
761
|
+
return this._limitTiers.has(tier);
|
|
762
|
+
}
|
|
763
|
+
// -------------------------------------------------------------------------
|
|
764
|
+
// Private: entity resolution
|
|
765
|
+
// -------------------------------------------------------------------------
|
|
766
|
+
/**
|
|
767
|
+
* Resolve a named entity token (without & and ;).
|
|
768
|
+
* Priority: inputMap > externalMap > baseMap
|
|
769
|
+
* Returns the resolved value tagged with its limit tier.
|
|
770
|
+
*
|
|
771
|
+
* @param {string} name
|
|
772
|
+
* @returns {{ value: string, tier: string }|undefined}
|
|
773
|
+
*/
|
|
774
|
+
_resolveName(name) {
|
|
775
|
+
if (name in this._inputMap) return { value: this._inputMap[name], tier: LIMIT_TIER_EXTERNAL };
|
|
776
|
+
if (name in this._externalMap) return { value: this._externalMap[name], tier: LIMIT_TIER_EXTERNAL };
|
|
777
|
+
if (name in this._baseMap) return { value: this._baseMap[name], tier: LIMIT_TIER_BASE };
|
|
778
|
+
return void 0;
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Classify a codepoint and return the minimum action level that must be applied.
|
|
782
|
+
* Returns -1 when no minimum is imposed (normal allow path).
|
|
783
|
+
*
|
|
784
|
+
* Ranges checked (in priority order):
|
|
785
|
+
* 1. U+0000 — null, governed by nullNCR (always ≥ remove)
|
|
786
|
+
* 2. U+D800–U+DFFF — surrogates, always prohibited (min: remove)
|
|
787
|
+
* 3. U+0001–U+001F \ {0x09,0x0A,0x0D} — XML 1.0 restricted C0 (min: remove)
|
|
788
|
+
* (skipped in XML 1.1 — C0 controls are allowed when written as NCRs)
|
|
789
|
+
*
|
|
790
|
+
* @param {number} cp — codepoint
|
|
791
|
+
* @returns {number} — minimum NCR_LEVEL value, or -1 for no restriction
|
|
792
|
+
*/
|
|
793
|
+
_classifyNCR(cp) {
|
|
794
|
+
if (cp === 0) return this._ncrNullLevel;
|
|
795
|
+
if (cp >= 55296 && cp <= 57343) return NCR_LEVEL.remove;
|
|
796
|
+
if (this._ncrXmlVersion === 1) {
|
|
797
|
+
if (cp >= 1 && cp <= 31 && !XML10_ALLOWED_C0.has(cp)) return NCR_LEVEL.remove;
|
|
798
|
+
}
|
|
799
|
+
return -1;
|
|
800
|
+
}
|
|
801
|
+
/**
|
|
802
|
+
* Execute a resolved NCR action.
|
|
803
|
+
*
|
|
804
|
+
* @param {number} action — NCR_LEVEL value
|
|
805
|
+
* @param {string} token — raw token (e.g. '#38') for error messages
|
|
806
|
+
* @param {number} cp — codepoint, used only for error messages
|
|
807
|
+
* @returns {string|undefined}
|
|
808
|
+
* - decoded character string → 'allow'
|
|
809
|
+
* - '' → 'remove'
|
|
810
|
+
* - undefined → 'leave' (caller must skip past '&' only)
|
|
811
|
+
* - throws Error → 'throw'
|
|
812
|
+
*/
|
|
813
|
+
_applyNCRAction(action, token, cp) {
|
|
814
|
+
switch (action) {
|
|
815
|
+
case NCR_LEVEL.allow:
|
|
816
|
+
return String.fromCodePoint(cp);
|
|
817
|
+
case NCR_LEVEL.remove:
|
|
818
|
+
return "";
|
|
819
|
+
case NCR_LEVEL.leave:
|
|
820
|
+
return void 0;
|
|
821
|
+
// signal: keep literal
|
|
822
|
+
case NCR_LEVEL.throw:
|
|
823
|
+
throw new Error(
|
|
824
|
+
`[EntityDecoder] Prohibited numeric character reference &${token}; (U+${cp.toString(16).toUpperCase().padStart(4, "0")})`
|
|
825
|
+
);
|
|
826
|
+
default:
|
|
827
|
+
return String.fromCodePoint(cp);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
/**
|
|
831
|
+
* Full NCR resolution pipeline for a numeric token.
|
|
832
|
+
*
|
|
833
|
+
* Steps:
|
|
834
|
+
* 1. Parse the codepoint (decimal or hex).
|
|
835
|
+
* 2. Validate the raw codepoint range (NaN, <0, >0x10FFFF).
|
|
836
|
+
* 3. If numericAllowed is false and no minimum restriction applies → leave as-is.
|
|
837
|
+
* 4. Classify the codepoint to find the minimum required action level.
|
|
838
|
+
* 5. Resolve effective action = max(onNCR, minimum).
|
|
839
|
+
* 6. Apply and return.
|
|
840
|
+
*
|
|
841
|
+
* @param {string} token — e.g. '#38', '#x26', '#X26'
|
|
842
|
+
* @returns {string|undefined}
|
|
843
|
+
* - string (incl. '') — replacement ('' = remove)
|
|
844
|
+
* - undefined — leave original &token; as-is
|
|
845
|
+
*/
|
|
846
|
+
_resolveNCR(token) {
|
|
847
|
+
const second = token.charCodeAt(1);
|
|
848
|
+
let cp;
|
|
849
|
+
if (second === 120 || second === 88) {
|
|
850
|
+
cp = parseInt(token.slice(2), 16);
|
|
851
|
+
} else {
|
|
852
|
+
cp = parseInt(token.slice(1), 10);
|
|
853
|
+
}
|
|
854
|
+
if (Number.isNaN(cp) || cp < 0 || cp > 1114111) return void 0;
|
|
855
|
+
const minimum = this._classifyNCR(cp);
|
|
856
|
+
if (!this._numericAllowed && minimum < NCR_LEVEL.remove) return void 0;
|
|
857
|
+
const effective = minimum === -1 ? this._ncrOnLevel : Math.max(this._ncrOnLevel, minimum);
|
|
858
|
+
return this._applyNCRAction(effective, token, cp);
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
|
|
862
|
+
// ../../node_modules/fast-xml-parser/src/xmlparser/OptionsBuilder.js
|
|
863
|
+
var defaultOnDangerousProperty = (name) => {
|
|
864
|
+
if (DANGEROUS_PROPERTY_NAMES.includes(name)) {
|
|
865
|
+
return "__" + name;
|
|
866
|
+
}
|
|
867
|
+
return name;
|
|
868
|
+
};
|
|
869
|
+
var defaultOptions2 = {
|
|
870
|
+
preserveOrder: false,
|
|
871
|
+
attributeNamePrefix: "@_",
|
|
872
|
+
attributesGroupName: false,
|
|
873
|
+
textNodeName: "#text",
|
|
874
|
+
ignoreAttributes: true,
|
|
875
|
+
removeNSPrefix: false,
|
|
876
|
+
// remove NS from tag name or attribute name if true
|
|
877
|
+
allowBooleanAttributes: false,
|
|
878
|
+
//a tag can have attributes without any value
|
|
879
|
+
//ignoreRootElement : false,
|
|
880
|
+
parseTagValue: true,
|
|
881
|
+
parseAttributeValue: false,
|
|
882
|
+
trimValues: true,
|
|
883
|
+
//Trim string values of tag and attributes
|
|
884
|
+
cdataPropName: false,
|
|
885
|
+
numberParseOptions: {
|
|
886
|
+
hex: true,
|
|
887
|
+
leadingZeros: true,
|
|
888
|
+
eNotation: true,
|
|
889
|
+
unicode: false
|
|
890
|
+
},
|
|
891
|
+
tagValueProcessor: function(tagName, val) {
|
|
892
|
+
return val;
|
|
893
|
+
},
|
|
894
|
+
attributeValueProcessor: function(attrName, val) {
|
|
895
|
+
return val;
|
|
896
|
+
},
|
|
897
|
+
stopNodes: [],
|
|
898
|
+
//nested tags will not be parsed even for errors
|
|
899
|
+
alwaysCreateTextNode: false,
|
|
900
|
+
isArray: () => false,
|
|
901
|
+
commentPropName: false,
|
|
902
|
+
unpairedTags: [],
|
|
903
|
+
processEntities: true,
|
|
904
|
+
htmlEntities: false,
|
|
905
|
+
entityDecoder: null,
|
|
906
|
+
ignoreDeclaration: false,
|
|
907
|
+
ignorePiTags: false,
|
|
908
|
+
transformTagName: false,
|
|
909
|
+
transformAttributeName: false,
|
|
910
|
+
updateTag: function(tagName, jPath, attrs) {
|
|
911
|
+
return tagName;
|
|
912
|
+
},
|
|
913
|
+
// skipEmptyListItem: false
|
|
914
|
+
captureMetaData: false,
|
|
915
|
+
maxNestedTags: 100,
|
|
916
|
+
strictReservedNames: true,
|
|
917
|
+
jPath: true,
|
|
918
|
+
// if true, pass jPath string to callbacks; if false, pass matcher instance
|
|
919
|
+
onDangerousProperty: defaultOnDangerousProperty
|
|
920
|
+
};
|
|
921
|
+
function validatePropertyName(propertyName, optionName) {
|
|
922
|
+
if (typeof propertyName !== "string") {
|
|
923
|
+
return;
|
|
924
|
+
}
|
|
925
|
+
const normalized = propertyName.toLowerCase();
|
|
926
|
+
if (DANGEROUS_PROPERTY_NAMES.some((dangerous) => normalized === dangerous.toLowerCase())) {
|
|
927
|
+
throw new Error(
|
|
928
|
+
`[SECURITY] Invalid ${optionName}: "${propertyName}" is a reserved JavaScript keyword that could cause prototype pollution`
|
|
929
|
+
);
|
|
930
|
+
}
|
|
931
|
+
if (criticalProperties.some((dangerous) => normalized === dangerous.toLowerCase())) {
|
|
932
|
+
throw new Error(
|
|
933
|
+
`[SECURITY] Invalid ${optionName}: "${propertyName}" is a reserved JavaScript keyword that could cause prototype pollution`
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
function normalizeProcessEntities(value, htmlEntities) {
|
|
938
|
+
if (typeof value === "boolean") {
|
|
939
|
+
return {
|
|
940
|
+
enabled: value,
|
|
941
|
+
// true or false
|
|
942
|
+
maxEntitySize: 1e4,
|
|
943
|
+
maxExpansionDepth: 1e4,
|
|
944
|
+
maxTotalExpansions: Infinity,
|
|
945
|
+
maxExpandedLength: 1e5,
|
|
946
|
+
maxEntityCount: 1e3,
|
|
947
|
+
allowedTags: null,
|
|
948
|
+
tagFilter: null,
|
|
949
|
+
appliesTo: "all"
|
|
950
|
+
};
|
|
951
|
+
}
|
|
952
|
+
if (typeof value === "object" && value !== null) {
|
|
953
|
+
return {
|
|
954
|
+
enabled: value.enabled !== false,
|
|
955
|
+
maxEntitySize: Math.max(1, value.maxEntitySize ?? 1e4),
|
|
956
|
+
maxExpansionDepth: Math.max(1, value.maxExpansionDepth ?? 1e4),
|
|
957
|
+
maxTotalExpansions: Math.max(1, value.maxTotalExpansions ?? Infinity),
|
|
958
|
+
maxExpandedLength: Math.max(1, value.maxExpandedLength ?? 1e5),
|
|
959
|
+
maxEntityCount: Math.max(1, value.maxEntityCount ?? 1e3),
|
|
960
|
+
allowedTags: value.allowedTags ?? null,
|
|
961
|
+
tagFilter: value.tagFilter ?? null,
|
|
962
|
+
appliesTo: value.appliesTo ?? "all"
|
|
963
|
+
};
|
|
964
|
+
}
|
|
965
|
+
return normalizeProcessEntities(true);
|
|
966
|
+
}
|
|
967
|
+
var buildOptions = function(options) {
|
|
968
|
+
const built = Object.assign({}, defaultOptions2, options);
|
|
969
|
+
const propertyNameOptions = [
|
|
970
|
+
{ value: built.attributeNamePrefix, name: "attributeNamePrefix" },
|
|
971
|
+
{ value: built.attributesGroupName, name: "attributesGroupName" },
|
|
972
|
+
{ value: built.textNodeName, name: "textNodeName" },
|
|
973
|
+
{ value: built.cdataPropName, name: "cdataPropName" },
|
|
974
|
+
{ value: built.commentPropName, name: "commentPropName" }
|
|
975
|
+
];
|
|
976
|
+
for (const { value, name } of propertyNameOptions) {
|
|
977
|
+
if (value) {
|
|
978
|
+
validatePropertyName(value, name);
|
|
979
|
+
}
|
|
980
|
+
}
|
|
981
|
+
if (built.onDangerousProperty === null) {
|
|
982
|
+
built.onDangerousProperty = defaultOnDangerousProperty;
|
|
983
|
+
}
|
|
984
|
+
built.processEntities = normalizeProcessEntities(built.processEntities, built.htmlEntities);
|
|
985
|
+
built.unpairedTagsSet = new Set(built.unpairedTags);
|
|
986
|
+
if (built.stopNodes && Array.isArray(built.stopNodes)) {
|
|
987
|
+
built.stopNodes = built.stopNodes.map((node) => {
|
|
988
|
+
if (typeof node === "string" && node.startsWith("*.")) {
|
|
989
|
+
return ".." + node.substring(2);
|
|
990
|
+
}
|
|
991
|
+
return node;
|
|
992
|
+
});
|
|
993
|
+
}
|
|
994
|
+
return built;
|
|
995
|
+
};
|
|
996
|
+
|
|
997
|
+
// ../../node_modules/fast-xml-parser/src/xmlparser/xmlNode.js
|
|
998
|
+
var METADATA_SYMBOL;
|
|
999
|
+
if (typeof Symbol !== "function") {
|
|
1000
|
+
METADATA_SYMBOL = "@@xmlMetadata";
|
|
1001
|
+
} else {
|
|
1002
|
+
METADATA_SYMBOL = Symbol("XML Node Metadata");
|
|
1003
|
+
}
|
|
1004
|
+
var XmlNode = class {
|
|
1005
|
+
constructor(tagname) {
|
|
1006
|
+
this.tagname = tagname;
|
|
1007
|
+
this.child = [];
|
|
1008
|
+
this[":@"] = /* @__PURE__ */ Object.create(null);
|
|
1009
|
+
}
|
|
1010
|
+
add(key, val) {
|
|
1011
|
+
if (key === "__proto__") key = "#__proto__";
|
|
1012
|
+
this.child.push({ [key]: val });
|
|
1013
|
+
}
|
|
1014
|
+
addChild(node, startIndex) {
|
|
1015
|
+
if (node.tagname === "__proto__") node.tagname = "#__proto__";
|
|
1016
|
+
if (node[":@"] && Object.keys(node[":@"]).length > 0) {
|
|
1017
|
+
this.child.push({ [node.tagname]: node.child, [":@"]: node[":@"] });
|
|
1018
|
+
} else {
|
|
1019
|
+
this.child.push({ [node.tagname]: node.child });
|
|
1020
|
+
}
|
|
1021
|
+
if (startIndex !== void 0) {
|
|
1022
|
+
this.child[this.child.length - 1][METADATA_SYMBOL] = { startIndex };
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
/** symbol used for metadata */
|
|
1026
|
+
static getMetaDataSymbol() {
|
|
1027
|
+
return METADATA_SYMBOL;
|
|
1028
|
+
}
|
|
1029
|
+
};
|
|
1030
|
+
|
|
1031
|
+
// ../../node_modules/xml-naming/src/index.js
|
|
1032
|
+
var nameStartChar10 = ":A-Za-z_\xC0-\xD6\xD8-\xF6\xF8-\u02FF\u0370-\u037D\u037F-\u0486\u0488-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD";
|
|
1033
|
+
var nameChar10 = nameStartChar10 + "\\-\\.\\d\xB7\u0300-\u036F\u203F-\u2040";
|
|
1034
|
+
var nameStartChar11 = ":A-Za-z_\xC0-\u02FF\u0370-\u037D\u037F-\u0486\u0488-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\u{10000}-\u{EFFFF}";
|
|
1035
|
+
var nameChar11 = nameStartChar11 + "\\-\\.\\d\xB7\u0300-\u036F\u0487\u203F-\u2040";
|
|
1036
|
+
var buildRegexes = (startChar, char, flags = "") => {
|
|
1037
|
+
const ncStart = startChar.replace(":", "");
|
|
1038
|
+
const ncChar = char.replace(":", "");
|
|
1039
|
+
const ncNamePat = `[${ncStart}][${ncChar}]*`;
|
|
1040
|
+
return {
|
|
1041
|
+
name: new RegExp(`^[${startChar}][${char}]*$`, flags),
|
|
1042
|
+
ncName: new RegExp(`^${ncNamePat}$`, flags),
|
|
1043
|
+
qName: new RegExp(`^${ncNamePat}(?::${ncNamePat})?$`, flags),
|
|
1044
|
+
nmToken: new RegExp(`^[${char}]+$`, flags),
|
|
1045
|
+
nmTokens: new RegExp(`^[${char}]+(?:\\s+[${char}]+)*$`, flags)
|
|
1046
|
+
};
|
|
1047
|
+
};
|
|
1048
|
+
var regexes10 = buildRegexes(nameStartChar10, nameChar10);
|
|
1049
|
+
var regexes11 = buildRegexes(nameStartChar11, nameChar11, "u");
|
|
1050
|
+
var nameStartCharAscii = ":A-Za-z_";
|
|
1051
|
+
var nameCharAscii = nameStartCharAscii + "\\-\\.\\d";
|
|
1052
|
+
var regexesAscii = buildRegexes(nameStartCharAscii, nameCharAscii);
|
|
1053
|
+
var getRegexes = (xmlVersion = "1.0", asciiOnly = false) => {
|
|
1054
|
+
if (asciiOnly) return regexesAscii;
|
|
1055
|
+
return xmlVersion === "1.1" ? regexes11 : regexes10;
|
|
1056
|
+
};
|
|
1057
|
+
var qName = (str, { xmlVersion = "1.0", asciiOnly = false } = {}) => getRegexes(xmlVersion, asciiOnly).qName.test(str);
|
|
1058
|
+
|
|
1059
|
+
// ../../node_modules/fast-xml-parser/src/xmlparser/DocTypeReader.js
|
|
1060
|
+
var DocTypeReader = class {
|
|
1061
|
+
constructor(options, xmlVersion) {
|
|
1062
|
+
this.suppressValidationErr = !options;
|
|
1063
|
+
this.options = options;
|
|
1064
|
+
this.xmlVersion = xmlVersion || 1;
|
|
1065
|
+
}
|
|
1066
|
+
setXmlVersion(xmlVersion = 1) {
|
|
1067
|
+
this.xmlVersion = xmlVersion;
|
|
1068
|
+
}
|
|
1069
|
+
readDocType(xmlData, i) {
|
|
1070
|
+
const entities = /* @__PURE__ */ Object.create(null);
|
|
1071
|
+
let entityCount = 0;
|
|
1072
|
+
if (xmlData[i + 3] === "O" && xmlData[i + 4] === "C" && xmlData[i + 5] === "T" && xmlData[i + 6] === "Y" && xmlData[i + 7] === "P" && xmlData[i + 8] === "E") {
|
|
1073
|
+
i = i + 9;
|
|
1074
|
+
let angleBracketsCount = 1;
|
|
1075
|
+
let hasBody = false, comment = false;
|
|
1076
|
+
let exp = "";
|
|
1077
|
+
for (; i < xmlData.length; i++) {
|
|
1078
|
+
if (xmlData[i] === "<" && !comment) {
|
|
1079
|
+
if (hasBody && hasSeq(xmlData, "!ENTITY", i)) {
|
|
1080
|
+
i += 7;
|
|
1081
|
+
let entityName, val;
|
|
1082
|
+
[entityName, val, i] = this.readEntityExp(xmlData, i + 1, this.suppressValidationErr);
|
|
1083
|
+
if (val.indexOf("&") === -1) {
|
|
1084
|
+
if (this.options.enabled !== false && this.options.maxEntityCount != null && entityCount >= this.options.maxEntityCount) {
|
|
1085
|
+
throw new Error(
|
|
1086
|
+
`Entity count (${entityCount + 1}) exceeds maximum allowed (${this.options.maxEntityCount})`
|
|
1087
|
+
);
|
|
1088
|
+
}
|
|
1089
|
+
entities[entityName] = val;
|
|
1090
|
+
entityCount++;
|
|
1091
|
+
}
|
|
1092
|
+
} else if (hasBody && hasSeq(xmlData, "!ELEMENT", i)) {
|
|
1093
|
+
i += 8;
|
|
1094
|
+
const { index } = this.readElementExp(xmlData, i + 1);
|
|
1095
|
+
i = index;
|
|
1096
|
+
} else if (hasBody && hasSeq(xmlData, "!ATTLIST", i)) {
|
|
1097
|
+
i += 8;
|
|
1098
|
+
} else if (hasBody && hasSeq(xmlData, "!NOTATION", i)) {
|
|
1099
|
+
i += 9;
|
|
1100
|
+
const { index } = this.readNotationExp(xmlData, i + 1, this.suppressValidationErr);
|
|
1101
|
+
i = index;
|
|
1102
|
+
} else if (hasSeq(xmlData, "!--", i)) comment = true;
|
|
1103
|
+
else throw new Error(`Invalid DOCTYPE`);
|
|
1104
|
+
angleBracketsCount++;
|
|
1105
|
+
exp = "";
|
|
1106
|
+
} else if (xmlData[i] === ">") {
|
|
1107
|
+
if (comment) {
|
|
1108
|
+
if (xmlData[i - 1] === "-" && xmlData[i - 2] === "-") {
|
|
1109
|
+
comment = false;
|
|
1110
|
+
angleBracketsCount--;
|
|
1111
|
+
}
|
|
1112
|
+
} else {
|
|
1113
|
+
angleBracketsCount--;
|
|
1114
|
+
}
|
|
1115
|
+
if (angleBracketsCount === 0) {
|
|
1116
|
+
break;
|
|
1117
|
+
}
|
|
1118
|
+
} else if (xmlData[i] === "[") {
|
|
1119
|
+
hasBody = true;
|
|
1120
|
+
} else {
|
|
1121
|
+
exp += xmlData[i];
|
|
1122
|
+
}
|
|
1123
|
+
}
|
|
1124
|
+
if (angleBracketsCount !== 0) {
|
|
1125
|
+
throw new Error(`Unclosed DOCTYPE`);
|
|
1126
|
+
}
|
|
1127
|
+
} else {
|
|
1128
|
+
throw new Error(`Invalid Tag instead of DOCTYPE`);
|
|
1129
|
+
}
|
|
1130
|
+
return { entities, i };
|
|
1131
|
+
}
|
|
1132
|
+
readEntityExp(xmlData, i) {
|
|
1133
|
+
i = skipWhitespace(xmlData, i);
|
|
1134
|
+
const startIndex = i;
|
|
1135
|
+
while (i < xmlData.length && !/\s/.test(xmlData[i]) && xmlData[i] !== '"' && xmlData[i] !== "'") {
|
|
1136
|
+
i++;
|
|
1137
|
+
}
|
|
1138
|
+
let entityName = xmlData.substring(startIndex, i);
|
|
1139
|
+
validateEntityName2(entityName, { xmlVersion: this.xmlVersion });
|
|
1140
|
+
i = skipWhitespace(xmlData, i);
|
|
1141
|
+
if (!this.suppressValidationErr) {
|
|
1142
|
+
if (xmlData.substring(i, i + 6).toUpperCase() === "SYSTEM") {
|
|
1143
|
+
throw new Error("External entities are not supported");
|
|
1144
|
+
} else if (xmlData[i] === "%") {
|
|
1145
|
+
throw new Error("Parameter entities are not supported");
|
|
1146
|
+
}
|
|
1147
|
+
}
|
|
1148
|
+
let entityValue = "";
|
|
1149
|
+
[i, entityValue] = this.readIdentifierVal(xmlData, i, "entity");
|
|
1150
|
+
if (this.options.enabled !== false && this.options.maxEntitySize != null && entityValue.length > this.options.maxEntitySize) {
|
|
1151
|
+
throw new Error(
|
|
1152
|
+
`Entity "${entityName}" size (${entityValue.length}) exceeds maximum allowed size (${this.options.maxEntitySize})`
|
|
1153
|
+
);
|
|
1154
|
+
}
|
|
1155
|
+
i--;
|
|
1156
|
+
return [entityName, entityValue, i];
|
|
1157
|
+
}
|
|
1158
|
+
readNotationExp(xmlData, i) {
|
|
1159
|
+
i = skipWhitespace(xmlData, i);
|
|
1160
|
+
const startIndex = i;
|
|
1161
|
+
while (i < xmlData.length && !/\s/.test(xmlData[i])) {
|
|
1162
|
+
i++;
|
|
1163
|
+
}
|
|
1164
|
+
let notationName = xmlData.substring(startIndex, i);
|
|
1165
|
+
!this.suppressValidationErr && validateEntityName2(notationName, { xmlVersion: this.xmlVersion });
|
|
1166
|
+
i = skipWhitespace(xmlData, i);
|
|
1167
|
+
const identifierType = xmlData.substring(i, i + 6).toUpperCase();
|
|
1168
|
+
if (!this.suppressValidationErr && identifierType !== "SYSTEM" && identifierType !== "PUBLIC") {
|
|
1169
|
+
throw new Error(`Expected SYSTEM or PUBLIC, found "${identifierType}"`);
|
|
1170
|
+
}
|
|
1171
|
+
i += identifierType.length;
|
|
1172
|
+
i = skipWhitespace(xmlData, i);
|
|
1173
|
+
let publicIdentifier = null;
|
|
1174
|
+
let systemIdentifier = null;
|
|
1175
|
+
if (identifierType === "PUBLIC") {
|
|
1176
|
+
[i, publicIdentifier] = this.readIdentifierVal(xmlData, i, "publicIdentifier");
|
|
1177
|
+
i = skipWhitespace(xmlData, i);
|
|
1178
|
+
if (xmlData[i] === '"' || xmlData[i] === "'") {
|
|
1179
|
+
[i, systemIdentifier] = this.readIdentifierVal(xmlData, i, "systemIdentifier");
|
|
1180
|
+
}
|
|
1181
|
+
} else if (identifierType === "SYSTEM") {
|
|
1182
|
+
[i, systemIdentifier] = this.readIdentifierVal(xmlData, i, "systemIdentifier");
|
|
1183
|
+
if (!this.suppressValidationErr && !systemIdentifier) {
|
|
1184
|
+
throw new Error("Missing mandatory system identifier for SYSTEM notation");
|
|
1185
|
+
}
|
|
1186
|
+
}
|
|
1187
|
+
return { notationName, publicIdentifier, systemIdentifier, index: --i };
|
|
1188
|
+
}
|
|
1189
|
+
readIdentifierVal(xmlData, i, type) {
|
|
1190
|
+
let identifierVal = "";
|
|
1191
|
+
const startChar = xmlData[i];
|
|
1192
|
+
if (startChar !== '"' && startChar !== "'") {
|
|
1193
|
+
throw new Error(`Expected quoted string, found "${startChar}"`);
|
|
1194
|
+
}
|
|
1195
|
+
i++;
|
|
1196
|
+
const startIndex = i;
|
|
1197
|
+
while (i < xmlData.length && xmlData[i] !== startChar) {
|
|
1198
|
+
i++;
|
|
1199
|
+
}
|
|
1200
|
+
identifierVal = xmlData.substring(startIndex, i);
|
|
1201
|
+
if (xmlData[i] !== startChar) {
|
|
1202
|
+
throw new Error(`Unterminated ${type} value`);
|
|
1203
|
+
}
|
|
1204
|
+
i++;
|
|
1205
|
+
return [i, identifierVal];
|
|
1206
|
+
}
|
|
1207
|
+
readElementExp(xmlData, i) {
|
|
1208
|
+
i = skipWhitespace(xmlData, i);
|
|
1209
|
+
const startIndex = i;
|
|
1210
|
+
while (i < xmlData.length && !/\s/.test(xmlData[i])) {
|
|
1211
|
+
i++;
|
|
1212
|
+
}
|
|
1213
|
+
let elementName = xmlData.substring(startIndex, i);
|
|
1214
|
+
if (!this.suppressValidationErr && !qName(elementName, { xmlVersion: this.xmlVersion })) {
|
|
1215
|
+
throw new Error(`Invalid element name: "${elementName}"`);
|
|
1216
|
+
}
|
|
1217
|
+
i = skipWhitespace(xmlData, i);
|
|
1218
|
+
let contentModel = "";
|
|
1219
|
+
if (xmlData[i] === "E" && hasSeq(xmlData, "MPTY", i)) i += 4;
|
|
1220
|
+
else if (xmlData[i] === "A" && hasSeq(xmlData, "NY", i)) i += 2;
|
|
1221
|
+
else if (xmlData[i] === "(") {
|
|
1222
|
+
i++;
|
|
1223
|
+
const startIndex2 = i;
|
|
1224
|
+
while (i < xmlData.length && xmlData[i] !== ")") {
|
|
1225
|
+
i++;
|
|
1226
|
+
}
|
|
1227
|
+
contentModel = xmlData.substring(startIndex2, i);
|
|
1228
|
+
if (xmlData[i] !== ")") {
|
|
1229
|
+
throw new Error("Unterminated content model");
|
|
1230
|
+
}
|
|
1231
|
+
} else if (!this.suppressValidationErr) {
|
|
1232
|
+
throw new Error(`Invalid Element Expression, found "${xmlData[i]}"`);
|
|
1233
|
+
}
|
|
1234
|
+
return {
|
|
1235
|
+
elementName,
|
|
1236
|
+
contentModel: contentModel.trim(),
|
|
1237
|
+
index: i
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
readAttlistExp(xmlData, i) {
|
|
1241
|
+
i = skipWhitespace(xmlData, i);
|
|
1242
|
+
let startIndex = i;
|
|
1243
|
+
while (i < xmlData.length && !/\s/.test(xmlData[i])) {
|
|
1244
|
+
i++;
|
|
1245
|
+
}
|
|
1246
|
+
let elementName = xmlData.substring(startIndex, i);
|
|
1247
|
+
validateEntityName2(elementName, { xmlVersion: this.xmlVersion });
|
|
1248
|
+
i = skipWhitespace(xmlData, i);
|
|
1249
|
+
startIndex = i;
|
|
1250
|
+
while (i < xmlData.length && !/\s/.test(xmlData[i])) {
|
|
1251
|
+
i++;
|
|
1252
|
+
}
|
|
1253
|
+
let attributeName = xmlData.substring(startIndex, i);
|
|
1254
|
+
if (!validateEntityName2(attributeName, { xmlVersion: this.xmlVersion })) {
|
|
1255
|
+
throw new Error(`Invalid attribute name: "${attributeName}"`);
|
|
1256
|
+
}
|
|
1257
|
+
i = skipWhitespace(xmlData, i);
|
|
1258
|
+
let attributeType = "";
|
|
1259
|
+
if (xmlData.substring(i, i + 8).toUpperCase() === "NOTATION") {
|
|
1260
|
+
attributeType = "NOTATION";
|
|
1261
|
+
i += 8;
|
|
1262
|
+
i = skipWhitespace(xmlData, i);
|
|
1263
|
+
if (xmlData[i] !== "(") {
|
|
1264
|
+
throw new Error(`Expected '(', found "${xmlData[i]}"`);
|
|
1265
|
+
}
|
|
1266
|
+
i++;
|
|
1267
|
+
let allowedNotations = [];
|
|
1268
|
+
while (i < xmlData.length && xmlData[i] !== ")") {
|
|
1269
|
+
const startIndex2 = i;
|
|
1270
|
+
while (i < xmlData.length && xmlData[i] !== "|" && xmlData[i] !== ")") {
|
|
1271
|
+
i++;
|
|
1272
|
+
}
|
|
1273
|
+
let notation = xmlData.substring(startIndex2, i);
|
|
1274
|
+
notation = notation.trim();
|
|
1275
|
+
if (!validateEntityName2(notation, { xmlVersion: this.xmlVersion })) {
|
|
1276
|
+
throw new Error(`Invalid notation name: "${notation}"`);
|
|
1277
|
+
}
|
|
1278
|
+
allowedNotations.push(notation);
|
|
1279
|
+
if (xmlData[i] === "|") {
|
|
1280
|
+
i++;
|
|
1281
|
+
i = skipWhitespace(xmlData, i);
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
if (xmlData[i] !== ")") {
|
|
1285
|
+
throw new Error("Unterminated list of notations");
|
|
1286
|
+
}
|
|
1287
|
+
i++;
|
|
1288
|
+
attributeType += " (" + allowedNotations.join("|") + ")";
|
|
1289
|
+
} else {
|
|
1290
|
+
const startIndex2 = i;
|
|
1291
|
+
while (i < xmlData.length && !/\s/.test(xmlData[i])) {
|
|
1292
|
+
i++;
|
|
1293
|
+
}
|
|
1294
|
+
attributeType += xmlData.substring(startIndex2, i);
|
|
1295
|
+
const validTypes = ["CDATA", "ID", "IDREF", "IDREFS", "ENTITY", "ENTITIES", "NMTOKEN", "NMTOKENS"];
|
|
1296
|
+
if (!this.suppressValidationErr && !validTypes.includes(attributeType.toUpperCase())) {
|
|
1297
|
+
throw new Error(`Invalid attribute type: "${attributeType}"`);
|
|
1298
|
+
}
|
|
1299
|
+
}
|
|
1300
|
+
i = skipWhitespace(xmlData, i);
|
|
1301
|
+
let defaultValue = "";
|
|
1302
|
+
if (xmlData.substring(i, i + 8).toUpperCase() === "#REQUIRED") {
|
|
1303
|
+
defaultValue = "#REQUIRED";
|
|
1304
|
+
i += 8;
|
|
1305
|
+
} else if (xmlData.substring(i, i + 7).toUpperCase() === "#IMPLIED") {
|
|
1306
|
+
defaultValue = "#IMPLIED";
|
|
1307
|
+
i += 7;
|
|
1308
|
+
} else {
|
|
1309
|
+
[i, defaultValue] = this.readIdentifierVal(xmlData, i, "ATTLIST");
|
|
1310
|
+
}
|
|
1311
|
+
return {
|
|
1312
|
+
elementName,
|
|
1313
|
+
attributeName,
|
|
1314
|
+
attributeType,
|
|
1315
|
+
defaultValue,
|
|
1316
|
+
index: i
|
|
1317
|
+
};
|
|
1318
|
+
}
|
|
1319
|
+
};
|
|
1320
|
+
var skipWhitespace = (data, index) => {
|
|
1321
|
+
while (index < data.length && /\s/.test(data[index])) {
|
|
1322
|
+
index++;
|
|
1323
|
+
}
|
|
1324
|
+
return index;
|
|
1325
|
+
};
|
|
1326
|
+
function hasSeq(data, seq, i) {
|
|
1327
|
+
for (let j = 0; j < seq.length; j++) {
|
|
1328
|
+
if (seq[j] !== data[i + j + 1]) return false;
|
|
1329
|
+
}
|
|
1330
|
+
return true;
|
|
1331
|
+
}
|
|
1332
|
+
function validateEntityName2(name, xmlVersion) {
|
|
1333
|
+
if (qName(name, { xmlVersion }))
|
|
1334
|
+
return name;
|
|
1335
|
+
else
|
|
1336
|
+
throw new Error(`Invalid entity name ${name}`);
|
|
1337
|
+
}
|
|
1338
|
+
|
|
1339
|
+
// ../../node_modules/anynum/digitTable.js
|
|
1340
|
+
var SCRIPT_ZEROS = [
|
|
1341
|
+
// Basic Latin (ASCII) — included for completeness / pass-through
|
|
1342
|
+
48,
|
|
1343
|
+
// 0-9
|
|
1344
|
+
// Arabic scripts
|
|
1345
|
+
1632,
|
|
1346
|
+
// Arabic-Indic ٠١٢٣٤٥٦٧٨٩
|
|
1347
|
+
1776,
|
|
1348
|
+
// Extended Arabic-Indic (Urdu/Persian/Sindhi) ۰۱۲۳
|
|
1349
|
+
// Indic scripts
|
|
1350
|
+
2406,
|
|
1351
|
+
// Devanagari ०१२३४५६७८९
|
|
1352
|
+
2534,
|
|
1353
|
+
// Bengali ০১২৩৪৫৬৭৮৯
|
|
1354
|
+
2662,
|
|
1355
|
+
// Gurmukhi ੦੧੨੩੪੫੬੭੮੯
|
|
1356
|
+
2790,
|
|
1357
|
+
// Gujarati ૦૧૨૩૪૫૬૭૮૯
|
|
1358
|
+
2918,
|
|
1359
|
+
// Odia ୦୧୨୩୪୫୬୭୮୯
|
|
1360
|
+
3046,
|
|
1361
|
+
// Tamil ௦௧௨௩௪௫௬௭௮௯
|
|
1362
|
+
3174,
|
|
1363
|
+
// Telugu ౦౧౨౩౪౫౬౭౮౯
|
|
1364
|
+
3302,
|
|
1365
|
+
// Kannada ೦೧೨೩೪೫೬೭೮೯
|
|
1366
|
+
3430,
|
|
1367
|
+
// Malayalam ൦൧൨൩൪൫൬൭൮൯
|
|
1368
|
+
3558,
|
|
1369
|
+
// Sinhala Archaic ෦෧෨෩෪෫෬෭෮෯
|
|
1370
|
+
// Southeast Asian scripts
|
|
1371
|
+
3664,
|
|
1372
|
+
// Thai ๐๑๒๓๔๕๖๗๘๙
|
|
1373
|
+
3792,
|
|
1374
|
+
// Lao ໐໑໒໓໔໕໖໗໘໙
|
|
1375
|
+
3872,
|
|
1376
|
+
// Tibetan ༠༡༢༣༤༥༦༧༨༩
|
|
1377
|
+
4160,
|
|
1378
|
+
// Myanmar ၀၁၂၃၄၅၆၇၈၉
|
|
1379
|
+
4240,
|
|
1380
|
+
// Myanmar Shan ႐႑႒႓႔႕႖႗႘႙
|
|
1381
|
+
6112,
|
|
1382
|
+
// Khmer ០១២៣៤៥៦៧៨៩
|
|
1383
|
+
6160,
|
|
1384
|
+
// Mongolian ᠐᠑᠒᠓᠔᠕᠖᠗᠘᠙
|
|
1385
|
+
6470,
|
|
1386
|
+
// Limbu ᥆᥇᥈᥉᥊᥋᥌᥍᥎᥏
|
|
1387
|
+
6608,
|
|
1388
|
+
// New Tai Lue ᧐᧑᧒᧓᧔᧕᧖᧗᧘᧙
|
|
1389
|
+
6784,
|
|
1390
|
+
// Tai Tham Hora ᪀᪁᪂᪃᪄᪅᪆᪇᪈᪉
|
|
1391
|
+
6800,
|
|
1392
|
+
// Tai Tham Tham ᪐᪑᪒᪓᪔᪕᪖᪗᪘᪙
|
|
1393
|
+
6992,
|
|
1394
|
+
// Balinese ᭐᭑᭒᭓᭔᭕᭖᭗᭘᭙
|
|
1395
|
+
7088,
|
|
1396
|
+
// Sundanese ᮰᮱᮲᮳᮴᮵᮶᮷᮸᮹
|
|
1397
|
+
7232,
|
|
1398
|
+
// Lepcha ᱀᱁᱂᱃᱄᱅᱆᱇᱈᱉
|
|
1399
|
+
7248,
|
|
1400
|
+
// Ol Chiki ᱐᱑᱒᱓᱔᱕᱖᱗᱘᱙
|
|
1401
|
+
// Fullwidth (CJK context)
|
|
1402
|
+
65296,
|
|
1403
|
+
// Fullwidth 0123456789
|
|
1404
|
+
// Mathematical digit variants (Unicode math block)
|
|
1405
|
+
120782,
|
|
1406
|
+
// Mathematical Bold
|
|
1407
|
+
120792,
|
|
1408
|
+
// Mathematical Double-Struck
|
|
1409
|
+
120802,
|
|
1410
|
+
// Mathematical Sans-Serif
|
|
1411
|
+
120812,
|
|
1412
|
+
// Mathematical Sans-Serif Bold
|
|
1413
|
+
120822,
|
|
1414
|
+
// Mathematical Monospace
|
|
1415
|
+
// Other scripts
|
|
1416
|
+
66720,
|
|
1417
|
+
// Osmanya 𐒠𐒡𐒢𐒣𐒤𐒥𐒦𐒧𐒨𐒩
|
|
1418
|
+
68912,
|
|
1419
|
+
// Hanifi Rohingya 𐴰𐴱𐴲𐴳𐴴𐴵𐴶𐴷𐴸𐴹
|
|
1420
|
+
69734,
|
|
1421
|
+
// Brahmi 𑁦𑁧𑁨𑁩𑁪𑁫𑁬𑁭𑁮𑁯
|
|
1422
|
+
69872,
|
|
1423
|
+
// Sora Sompeng 𑃰𑃱𑃲𑃳𑃴𑃵𑃶𑃷𑃸𑃹
|
|
1424
|
+
69942,
|
|
1425
|
+
// Chakma 𑄶𑄷𑄸𑄹𑄺𑄻𑄼𑄽𑄾𑄿
|
|
1426
|
+
70096,
|
|
1427
|
+
// Sharada 𑇐𑇑𑇒𑇓𑇔𑇕𑇖𑇗𑇘𑇙
|
|
1428
|
+
70384,
|
|
1429
|
+
// Khudawadi 𑋰𑋱𑋲𑋳𑋴𑋵𑋶𑋷𑋸𑋹
|
|
1430
|
+
70736,
|
|
1431
|
+
// Newa 𑑐𑑑𑑒𑑓𑑔𑑕𑑖𑑗𑑘𑑙
|
|
1432
|
+
70864,
|
|
1433
|
+
// Tirhuta 𑓐𑓑𑓒𑓓𑓔𑓕𑓖𑓗𑓘𑓙
|
|
1434
|
+
71248,
|
|
1435
|
+
// Modi 𑙐𑙑𑙒𑙓𑙔𑙕𑙖𑙗𑙘𑙙
|
|
1436
|
+
71360,
|
|
1437
|
+
// Takri 𑛀𑛁𑛂𑛃𑛄𑛅𑛆𑛇𑛈𑛉
|
|
1438
|
+
71472,
|
|
1439
|
+
// Ahom 𑜰𑜱𑜲𑜳𑜴𑜵𑜶𑜷𑜸𑜹
|
|
1440
|
+
71904,
|
|
1441
|
+
// Warang Citi 𑣠𑣡𑣢𑣣𑣤𑣥𑣦𑣧𑣨𑣩
|
|
1442
|
+
72016,
|
|
1443
|
+
// Dives Akuru 𑥐𑥑𑥒𑥓𑥔𑥕𑥖𑥗𑥘𑥙
|
|
1444
|
+
72688,
|
|
1445
|
+
// Khitan Small Script
|
|
1446
|
+
72784,
|
|
1447
|
+
// Bhaiksuki 𑱐𑱑𑱒𑱓𑱔𑱕𑱖𑱗𑱘𑱙
|
|
1448
|
+
73040,
|
|
1449
|
+
// Masaram Gondi 𑵐𑵑𑵒𑵓𑵔𑵕𑵖𑵗𑵘𑵙
|
|
1450
|
+
73120,
|
|
1451
|
+
// Gunjala Gondi 𑶠𑶡𑶢𑶣𑶤𑶥𑶦𑶧𑶨𑶩
|
|
1452
|
+
73552,
|
|
1453
|
+
// Kawi 𑽐𑽑𑽒𑽓𑽔𑽕𑽖𑽗𑽘𑽙
|
|
1454
|
+
92768,
|
|
1455
|
+
// Mro 𖩠𖩡𖩢𖩣𖩤𖩥𖩦𖩧𖩨𖩩
|
|
1456
|
+
92864,
|
|
1457
|
+
// Tangsa 𖫀𖫁𖫂𖫃𖫄𖫅𖫆𖫇𖫈𖫉
|
|
1458
|
+
93008,
|
|
1459
|
+
// Pahawh Hmong 𖭐𖭑𖭒𖭓𖭔𖭕𖭖𖭗𖭘𖭙
|
|
1460
|
+
123200,
|
|
1461
|
+
// Nyiakeng Puachue Hmong 𞅀𞅁𞅂𞅃𞅄𞅅𞅆𞅇𞅈𞅉
|
|
1462
|
+
123632,
|
|
1463
|
+
// Wancho 𞋰𞋱𞋲𞋳𞋴𞋵𞋶𞋷𞋸𞋹
|
|
1464
|
+
124144,
|
|
1465
|
+
// Nag Mundari 𞓰𞓱𞓲𞓳𞓴𞓵𞓶𞓷𞓸𞓹
|
|
1466
|
+
125264,
|
|
1467
|
+
// Adlam 𞥐𞥑𞥒𞥓𞥔𞥕𞥖𞥗𞥘𞥙
|
|
1468
|
+
130032
|
|
1469
|
+
// Segmented digit symbols 🯰🯱🯲🯳🯴🯵🯶🯷🯸🯹
|
|
1470
|
+
];
|
|
1471
|
+
var NOT_DIGIT = 255;
|
|
1472
|
+
var HIGH_MAP = /* @__PURE__ */ new Map();
|
|
1473
|
+
var LOW_MAX = 65535;
|
|
1474
|
+
var LOW_MIN = 1632;
|
|
1475
|
+
var TABLE_OFFSET = LOW_MIN;
|
|
1476
|
+
var TABLE_SIZE = LOW_MAX - LOW_MIN + 1;
|
|
1477
|
+
var TABLE = new Uint8Array(TABLE_SIZE).fill(NOT_DIGIT);
|
|
1478
|
+
for (const zero of SCRIPT_ZEROS) {
|
|
1479
|
+
for (let d = 0; d < 10; d++) {
|
|
1480
|
+
const cp = zero + d;
|
|
1481
|
+
if (cp <= LOW_MAX) {
|
|
1482
|
+
TABLE[cp - TABLE_OFFSET] = d;
|
|
1483
|
+
} else {
|
|
1484
|
+
HIGH_MAP.set(cp, d);
|
|
1485
|
+
}
|
|
1486
|
+
}
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1489
|
+
// ../../node_modules/anynum/anynum.js
|
|
1490
|
+
var CHAR_0 = 48;
|
|
1491
|
+
var CHAR_9 = 57;
|
|
1492
|
+
var CHAR_MINUS = 45;
|
|
1493
|
+
var MINUS_SET = /* @__PURE__ */ new Set([8722, 65293, 65123]);
|
|
1494
|
+
function anynum(str) {
|
|
1495
|
+
if (typeof str !== "string") return str;
|
|
1496
|
+
const len = str.length;
|
|
1497
|
+
if (len === 0) return str;
|
|
1498
|
+
let firstHit = -1;
|
|
1499
|
+
for (let i = 0; i < len; i++) {
|
|
1500
|
+
const cc = str.charCodeAt(i);
|
|
1501
|
+
if (cc >= CHAR_0 && cc <= CHAR_9 || cc === CHAR_MINUS) continue;
|
|
1502
|
+
if (cc < TABLE_OFFSET) {
|
|
1503
|
+
if (MINUS_SET.has(cc)) {
|
|
1504
|
+
firstHit = i;
|
|
1505
|
+
break;
|
|
1506
|
+
}
|
|
1507
|
+
continue;
|
|
1508
|
+
}
|
|
1509
|
+
if (cc >= 55296 && cc <= 56319) {
|
|
1510
|
+
if (i + 1 < len) {
|
|
1511
|
+
const low = str.charCodeAt(i + 1);
|
|
1512
|
+
if (low >= 56320 && low <= 57343) {
|
|
1513
|
+
const cp = 65536 + (cc - 55296 << 10) + (low - 56320);
|
|
1514
|
+
if (HIGH_MAP.has(cp)) {
|
|
1515
|
+
firstHit = i;
|
|
1516
|
+
break;
|
|
1517
|
+
}
|
|
1518
|
+
}
|
|
1519
|
+
}
|
|
1520
|
+
continue;
|
|
1521
|
+
}
|
|
1522
|
+
if (TABLE[cc - TABLE_OFFSET] !== NOT_DIGIT || MINUS_SET.has(cc)) {
|
|
1523
|
+
firstHit = i;
|
|
1524
|
+
break;
|
|
1525
|
+
}
|
|
1526
|
+
}
|
|
1527
|
+
if (firstHit === -1) return str;
|
|
1528
|
+
const chars = [];
|
|
1529
|
+
if (firstHit > 0) chars.push(str.slice(0, firstHit));
|
|
1530
|
+
for (let i = firstHit; i < len; i++) {
|
|
1531
|
+
const cc = str.charCodeAt(i);
|
|
1532
|
+
if (cc >= CHAR_0 && cc <= CHAR_9 || cc === CHAR_MINUS) {
|
|
1533
|
+
chars.push(str[i]);
|
|
1534
|
+
continue;
|
|
1535
|
+
}
|
|
1536
|
+
if (cc < TABLE_OFFSET) {
|
|
1537
|
+
chars.push(MINUS_SET.has(cc) ? "-" : str[i]);
|
|
1538
|
+
continue;
|
|
1539
|
+
}
|
|
1540
|
+
if (cc >= 55296 && cc <= 56319) {
|
|
1541
|
+
if (i + 1 < len) {
|
|
1542
|
+
const low = str.charCodeAt(i + 1);
|
|
1543
|
+
if (low >= 56320 && low <= 57343) {
|
|
1544
|
+
const cp = 65536 + (cc - 55296 << 10) + (low - 56320);
|
|
1545
|
+
const d2 = HIGH_MAP.get(cp);
|
|
1546
|
+
if (d2 !== void 0) {
|
|
1547
|
+
chars.push(String.fromCharCode(d2 + 48));
|
|
1548
|
+
i++;
|
|
1549
|
+
continue;
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
}
|
|
1553
|
+
chars.push(str[i]);
|
|
1554
|
+
continue;
|
|
1555
|
+
}
|
|
1556
|
+
if (MINUS_SET.has(cc)) {
|
|
1557
|
+
chars.push("-");
|
|
1558
|
+
continue;
|
|
1559
|
+
}
|
|
1560
|
+
const d = TABLE[cc - TABLE_OFFSET];
|
|
1561
|
+
chars.push(d !== NOT_DIGIT ? String.fromCharCode(d + 48) : str[i]);
|
|
1562
|
+
}
|
|
1563
|
+
return chars.join("");
|
|
1564
|
+
}
|
|
1565
|
+
var anynum_default = anynum;
|
|
1566
|
+
|
|
1567
|
+
// ../../node_modules/strnum/strnum.js
|
|
1568
|
+
var hexRegex = /^[-+]?0x[a-fA-F0-9]+$/;
|
|
1569
|
+
var binRegex = /^0b[01]+$/;
|
|
1570
|
+
var octRegex = /^0o[0-7]+$/;
|
|
1571
|
+
var numRegex = /^([\-\+])?(0*)([0-9]*(\.[0-9]*)?)$/;
|
|
1572
|
+
var consider = {
|
|
1573
|
+
hex: true,
|
|
1574
|
+
binary: false,
|
|
1575
|
+
octal: false,
|
|
1576
|
+
leadingZeros: true,
|
|
1577
|
+
decimalPoint: ".",
|
|
1578
|
+
eNotation: true,
|
|
1579
|
+
//skipLike: /regex/,
|
|
1580
|
+
infinity: "original",
|
|
1581
|
+
// "null", "infinity" (Infinity type), "string" ("Infinity" (the string literal))
|
|
1582
|
+
unicode: false
|
|
1583
|
+
};
|
|
1584
|
+
function toNumber(str, options = {}) {
|
|
1585
|
+
options = Object.assign({}, consider, options);
|
|
1586
|
+
if (!str || typeof str !== "string") return str;
|
|
1587
|
+
let trimmedStr = str.trim();
|
|
1588
|
+
if (trimmedStr.length === 0) return str;
|
|
1589
|
+
else if (options.skipLike !== void 0 && options.skipLike.test(trimmedStr)) return str;
|
|
1590
|
+
else if (trimmedStr === "0") return 0;
|
|
1591
|
+
if (options.unicode) {
|
|
1592
|
+
trimmedStr = anynum_default(trimmedStr);
|
|
1593
|
+
if (trimmedStr === "0") return 0;
|
|
1594
|
+
}
|
|
1595
|
+
if (options.hex && hexRegex.test(trimmedStr)) {
|
|
1596
|
+
return parse_int(trimmedStr, 16);
|
|
1597
|
+
} else if (options.binary && binRegex.test(trimmedStr)) {
|
|
1598
|
+
return parse_int(trimmedStr, 2);
|
|
1599
|
+
} else if (options.octal && octRegex.test(trimmedStr)) {
|
|
1600
|
+
return parse_int(trimmedStr, 8);
|
|
1601
|
+
} else if (!isFinite(trimmedStr)) {
|
|
1602
|
+
return handleInfinity(str, Number(trimmedStr), options);
|
|
1603
|
+
} else if (trimmedStr.includes("e") || trimmedStr.includes("E")) {
|
|
1604
|
+
return resolveEnotation(str, trimmedStr, options);
|
|
1605
|
+
} else {
|
|
1606
|
+
const match = numRegex.exec(trimmedStr);
|
|
1607
|
+
if (match) {
|
|
1608
|
+
const sign = match[1] || "";
|
|
1609
|
+
const leadingZeros = match[2];
|
|
1610
|
+
let numTrimmedByZeros = trimZeros(match[3]);
|
|
1611
|
+
const decimalAdjacentToLeadingZeros = sign ? (
|
|
1612
|
+
// 0., -00., 000.
|
|
1613
|
+
str[leadingZeros.length + 1] === "."
|
|
1614
|
+
) : str[leadingZeros.length] === ".";
|
|
1615
|
+
if (!options.leadingZeros && (leadingZeros.length > 1 || leadingZeros.length === 1 && !decimalAdjacentToLeadingZeros)) {
|
|
1616
|
+
return str;
|
|
1617
|
+
} else {
|
|
1618
|
+
const num = Number(trimmedStr);
|
|
1619
|
+
const parsedStr = String(num);
|
|
1620
|
+
if (num === 0) return num;
|
|
1621
|
+
if (parsedStr.search(/[eE]/) !== -1) {
|
|
1622
|
+
if (options.eNotation) return num;
|
|
1623
|
+
else return str;
|
|
1624
|
+
} else if (trimmedStr.indexOf(".") !== -1) {
|
|
1625
|
+
if (parsedStr === "0") return num;
|
|
1626
|
+
else if (parsedStr === numTrimmedByZeros) return num;
|
|
1627
|
+
else if (parsedStr === `${sign}${numTrimmedByZeros}`) return num;
|
|
1628
|
+
else return str;
|
|
1629
|
+
}
|
|
1630
|
+
let n = leadingZeros ? numTrimmedByZeros : trimmedStr;
|
|
1631
|
+
if (leadingZeros) {
|
|
1632
|
+
return n === parsedStr || sign + n === parsedStr ? num : str;
|
|
1633
|
+
} else {
|
|
1634
|
+
return n === parsedStr || n === sign + parsedStr ? num : str;
|
|
1635
|
+
}
|
|
1636
|
+
}
|
|
1637
|
+
} else {
|
|
1638
|
+
return str;
|
|
1639
|
+
}
|
|
1640
|
+
}
|
|
1641
|
+
}
|
|
1642
|
+
var eNotationRegx = /^([-+])?(0*)(\d*(\.\d*)?[eE][-\+]?\d+)$/;
|
|
1643
|
+
function resolveEnotation(str, trimmedStr, options) {
|
|
1644
|
+
if (!options.eNotation) return str;
|
|
1645
|
+
const notation = trimmedStr.match(eNotationRegx);
|
|
1646
|
+
if (notation) {
|
|
1647
|
+
let sign = notation[1] || "";
|
|
1648
|
+
const eChar = notation[3].indexOf("e") === -1 ? "E" : "e";
|
|
1649
|
+
const leadingZeros = notation[2];
|
|
1650
|
+
const eAdjacentToLeadingZeros = sign ? (
|
|
1651
|
+
// 0E.
|
|
1652
|
+
str[leadingZeros.length + 1] === eChar
|
|
1653
|
+
) : str[leadingZeros.length] === eChar;
|
|
1654
|
+
if (leadingZeros.length > 1 && eAdjacentToLeadingZeros) return str;
|
|
1655
|
+
else if (leadingZeros.length === 1 && (notation[3].startsWith(`.${eChar}`) || notation[3][0] === eChar)) {
|
|
1656
|
+
return Number(trimmedStr);
|
|
1657
|
+
} else if (leadingZeros.length > 0) {
|
|
1658
|
+
if (options.leadingZeros && !eAdjacentToLeadingZeros) {
|
|
1659
|
+
trimmedStr = (notation[1] || "") + notation[3];
|
|
1660
|
+
return Number(trimmedStr);
|
|
1661
|
+
} else return str;
|
|
1662
|
+
} else {
|
|
1663
|
+
return Number(trimmedStr);
|
|
1664
|
+
}
|
|
1665
|
+
} else {
|
|
1666
|
+
return str;
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
function trimZeros(numStr) {
|
|
1670
|
+
if (numStr && numStr.indexOf(".") !== -1) {
|
|
1671
|
+
let end = numStr.length;
|
|
1672
|
+
while (end > 0 && numStr.charCodeAt(end - 1) === 48) end--;
|
|
1673
|
+
numStr = numStr.slice(0, end);
|
|
1674
|
+
if (numStr === ".") numStr = "0";
|
|
1675
|
+
else if (numStr[0] === ".") numStr = "0" + numStr;
|
|
1676
|
+
else if (numStr[numStr.length - 1] === ".") numStr = numStr.substring(0, numStr.length - 1);
|
|
1677
|
+
return numStr;
|
|
1678
|
+
}
|
|
1679
|
+
return numStr;
|
|
1680
|
+
}
|
|
1681
|
+
function parse_int(numStr, base) {
|
|
1682
|
+
const str = numStr.trim();
|
|
1683
|
+
if (base === 2 || base === 8) numStr = str.substring(2);
|
|
1684
|
+
if (parseInt) return parseInt(numStr, base);
|
|
1685
|
+
else if (Number.parseInt) return Number.parseInt(numStr, base);
|
|
1686
|
+
else if (window && window.parseInt) return window.parseInt(numStr, base);
|
|
1687
|
+
else throw new Error("parseInt, Number.parseInt, window.parseInt are not supported");
|
|
1688
|
+
}
|
|
1689
|
+
function handleInfinity(str, num, options) {
|
|
1690
|
+
const isPositive = num === Infinity;
|
|
1691
|
+
switch (options.infinity.toLowerCase()) {
|
|
1692
|
+
case "null":
|
|
1693
|
+
return null;
|
|
1694
|
+
case "infinity":
|
|
1695
|
+
return num;
|
|
1696
|
+
// Return Infinity or -Infinity
|
|
1697
|
+
case "string":
|
|
1698
|
+
return isPositive ? "Infinity" : "-Infinity";
|
|
1699
|
+
case "original":
|
|
1700
|
+
default:
|
|
1701
|
+
return str;
|
|
1702
|
+
}
|
|
1703
|
+
}
|
|
1704
|
+
|
|
1705
|
+
// ../../node_modules/fast-xml-parser/src/ignoreAttributes.js
|
|
1706
|
+
function getIgnoreAttributesFn(ignoreAttributes) {
|
|
1707
|
+
if (typeof ignoreAttributes === "function") {
|
|
1708
|
+
return ignoreAttributes;
|
|
1709
|
+
}
|
|
1710
|
+
if (Array.isArray(ignoreAttributes)) {
|
|
1711
|
+
return (attrName) => {
|
|
1712
|
+
for (const pattern of ignoreAttributes) {
|
|
1713
|
+
if (typeof pattern === "string" && attrName === pattern) {
|
|
1714
|
+
return true;
|
|
1715
|
+
}
|
|
1716
|
+
if (pattern instanceof RegExp && pattern.test(attrName)) {
|
|
1717
|
+
return true;
|
|
1718
|
+
}
|
|
1719
|
+
}
|
|
1720
|
+
};
|
|
1721
|
+
}
|
|
1722
|
+
return () => false;
|
|
1723
|
+
}
|
|
1724
|
+
|
|
1725
|
+
// ../../node_modules/path-expression-matcher/src/Expression.js
|
|
1726
|
+
var Expression = class {
|
|
1727
|
+
/**
|
|
1728
|
+
* Create a new Expression
|
|
1729
|
+
* @param {string} pattern - Pattern string (e.g., "root.users.user", "..user[id]")
|
|
1730
|
+
* @param {Object} options - Configuration options
|
|
1731
|
+
* @param {string} options.separator - Path separator (default: '.')
|
|
1732
|
+
*/
|
|
1733
|
+
constructor(pattern, options = {}, data) {
|
|
1734
|
+
this.pattern = pattern;
|
|
1735
|
+
this.separator = options.separator || ".";
|
|
1736
|
+
this.segments = this._parse(pattern);
|
|
1737
|
+
this.data = data;
|
|
1738
|
+
this._hasDeepWildcard = this.segments.some((seg) => seg.type === "deep-wildcard");
|
|
1739
|
+
this._hasAttributeCondition = this.segments.some((seg) => seg.attrName !== void 0);
|
|
1740
|
+
this._hasPositionSelector = this.segments.some((seg) => seg.position !== void 0);
|
|
1741
|
+
}
|
|
1742
|
+
/**
|
|
1743
|
+
* Parse pattern string into segments
|
|
1744
|
+
* @private
|
|
1745
|
+
* @param {string} pattern - Pattern to parse
|
|
1746
|
+
* @returns {Array} Array of segment objects
|
|
1747
|
+
*/
|
|
1748
|
+
_parse(pattern) {
|
|
1749
|
+
const segments = [];
|
|
1750
|
+
let i = 0;
|
|
1751
|
+
let currentPart = "";
|
|
1752
|
+
while (i < pattern.length) {
|
|
1753
|
+
if (pattern[i] === this.separator) {
|
|
1754
|
+
if (i + 1 < pattern.length && pattern[i + 1] === this.separator) {
|
|
1755
|
+
if (currentPart.trim()) {
|
|
1756
|
+
segments.push(this._parseSegment(currentPart.trim()));
|
|
1757
|
+
currentPart = "";
|
|
1758
|
+
}
|
|
1759
|
+
segments.push({ type: "deep-wildcard" });
|
|
1760
|
+
i += 2;
|
|
1761
|
+
} else {
|
|
1762
|
+
if (currentPart.trim()) {
|
|
1763
|
+
segments.push(this._parseSegment(currentPart.trim()));
|
|
1764
|
+
}
|
|
1765
|
+
currentPart = "";
|
|
1766
|
+
i++;
|
|
1767
|
+
}
|
|
1768
|
+
} else {
|
|
1769
|
+
currentPart += pattern[i];
|
|
1770
|
+
i++;
|
|
1771
|
+
}
|
|
1772
|
+
}
|
|
1773
|
+
if (currentPart.trim()) {
|
|
1774
|
+
segments.push(this._parseSegment(currentPart.trim()));
|
|
1775
|
+
}
|
|
1776
|
+
return segments;
|
|
1777
|
+
}
|
|
1778
|
+
/**
|
|
1779
|
+
* Parse a single segment
|
|
1780
|
+
* @private
|
|
1781
|
+
* @param {string} part - Segment string (e.g., "user", "ns::user", "user[id]", "ns::user:first")
|
|
1782
|
+
* @returns {Object} Segment object
|
|
1783
|
+
*/
|
|
1784
|
+
_parseSegment(part) {
|
|
1785
|
+
const segment = { type: "tag" };
|
|
1786
|
+
let bracketContent = null;
|
|
1787
|
+
let withoutBrackets = part;
|
|
1788
|
+
const bracketMatch = part.match(/^([^\[]+)(\[[^\]]*\])(.*)$/);
|
|
1789
|
+
if (bracketMatch) {
|
|
1790
|
+
withoutBrackets = bracketMatch[1] + bracketMatch[3];
|
|
1791
|
+
if (bracketMatch[2]) {
|
|
1792
|
+
const content = bracketMatch[2].slice(1, -1);
|
|
1793
|
+
if (content) {
|
|
1794
|
+
bracketContent = content;
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
let namespace = void 0;
|
|
1799
|
+
let tagAndPosition = withoutBrackets;
|
|
1800
|
+
if (withoutBrackets.includes("::")) {
|
|
1801
|
+
const nsIndex = withoutBrackets.indexOf("::");
|
|
1802
|
+
namespace = withoutBrackets.substring(0, nsIndex).trim();
|
|
1803
|
+
tagAndPosition = withoutBrackets.substring(nsIndex + 2).trim();
|
|
1804
|
+
if (!namespace) {
|
|
1805
|
+
throw new Error(`Invalid namespace in pattern: ${part}`);
|
|
1806
|
+
}
|
|
1807
|
+
}
|
|
1808
|
+
let tag = void 0;
|
|
1809
|
+
let positionMatch = null;
|
|
1810
|
+
if (tagAndPosition.includes(":")) {
|
|
1811
|
+
const colonIndex = tagAndPosition.lastIndexOf(":");
|
|
1812
|
+
const tagPart = tagAndPosition.substring(0, colonIndex).trim();
|
|
1813
|
+
const posPart = tagAndPosition.substring(colonIndex + 1).trim();
|
|
1814
|
+
const isPositionKeyword = ["first", "last", "odd", "even"].includes(posPart) || /^nth\(\d+\)$/.test(posPart);
|
|
1815
|
+
if (isPositionKeyword) {
|
|
1816
|
+
tag = tagPart;
|
|
1817
|
+
positionMatch = posPart;
|
|
1818
|
+
} else {
|
|
1819
|
+
tag = tagAndPosition;
|
|
1820
|
+
}
|
|
1821
|
+
} else {
|
|
1822
|
+
tag = tagAndPosition;
|
|
1823
|
+
}
|
|
1824
|
+
if (!tag) {
|
|
1825
|
+
throw new Error(`Invalid segment pattern: ${part}`);
|
|
1826
|
+
}
|
|
1827
|
+
segment.tag = tag;
|
|
1828
|
+
if (namespace) {
|
|
1829
|
+
segment.namespace = namespace;
|
|
1830
|
+
}
|
|
1831
|
+
if (bracketContent) {
|
|
1832
|
+
if (bracketContent.includes("=")) {
|
|
1833
|
+
const eqIndex = bracketContent.indexOf("=");
|
|
1834
|
+
segment.attrName = bracketContent.substring(0, eqIndex).trim();
|
|
1835
|
+
segment.attrValue = bracketContent.substring(eqIndex + 1).trim();
|
|
1836
|
+
} else {
|
|
1837
|
+
segment.attrName = bracketContent.trim();
|
|
1838
|
+
}
|
|
1839
|
+
}
|
|
1840
|
+
if (positionMatch) {
|
|
1841
|
+
const nthMatch = positionMatch.match(/^nth\((\d+)\)$/);
|
|
1842
|
+
if (nthMatch) {
|
|
1843
|
+
segment.position = "nth";
|
|
1844
|
+
segment.positionValue = parseInt(nthMatch[1], 10);
|
|
1845
|
+
} else {
|
|
1846
|
+
segment.position = positionMatch;
|
|
1847
|
+
}
|
|
1848
|
+
}
|
|
1849
|
+
return segment;
|
|
1850
|
+
}
|
|
1851
|
+
/**
|
|
1852
|
+
* Get the number of segments
|
|
1853
|
+
* @returns {number}
|
|
1854
|
+
*/
|
|
1855
|
+
get length() {
|
|
1856
|
+
return this.segments.length;
|
|
1857
|
+
}
|
|
1858
|
+
/**
|
|
1859
|
+
* Check if expression contains deep wildcard
|
|
1860
|
+
* @returns {boolean}
|
|
1861
|
+
*/
|
|
1862
|
+
hasDeepWildcard() {
|
|
1863
|
+
return this._hasDeepWildcard;
|
|
1864
|
+
}
|
|
1865
|
+
/**
|
|
1866
|
+
* Check if expression has attribute conditions
|
|
1867
|
+
* @returns {boolean}
|
|
1868
|
+
*/
|
|
1869
|
+
hasAttributeCondition() {
|
|
1870
|
+
return this._hasAttributeCondition;
|
|
1871
|
+
}
|
|
1872
|
+
/**
|
|
1873
|
+
* Check if expression has position selectors
|
|
1874
|
+
* @returns {boolean}
|
|
1875
|
+
*/
|
|
1876
|
+
hasPositionSelector() {
|
|
1877
|
+
return this._hasPositionSelector;
|
|
1878
|
+
}
|
|
1879
|
+
/**
|
|
1880
|
+
* Get string representation
|
|
1881
|
+
* @returns {string}
|
|
1882
|
+
*/
|
|
1883
|
+
toString() {
|
|
1884
|
+
return this.pattern;
|
|
1885
|
+
}
|
|
1886
|
+
};
|
|
1887
|
+
|
|
1888
|
+
// ../../node_modules/path-expression-matcher/src/ExpressionSet.js
|
|
1889
|
+
var ExpressionSet = class {
|
|
1890
|
+
constructor() {
|
|
1891
|
+
this._byDepthAndTag = /* @__PURE__ */ new Map();
|
|
1892
|
+
this._wildcardByDepth = /* @__PURE__ */ new Map();
|
|
1893
|
+
this._deepWildcards = [];
|
|
1894
|
+
this._deepByTerminalTag = /* @__PURE__ */ new Map();
|
|
1895
|
+
this._patterns = /* @__PURE__ */ new Set();
|
|
1896
|
+
this._sealed = false;
|
|
1897
|
+
}
|
|
1898
|
+
/**
|
|
1899
|
+
* Add an Expression to the set.
|
|
1900
|
+
* Duplicate patterns (same pattern string) are silently ignored.
|
|
1901
|
+
*
|
|
1902
|
+
* @param {import('./Expression.js').default} expression - A pre-constructed Expression instance
|
|
1903
|
+
* @returns {this} for chaining
|
|
1904
|
+
* @throws {TypeError} if called after seal()
|
|
1905
|
+
*
|
|
1906
|
+
* @example
|
|
1907
|
+
* set.add(new Expression('root.users.user'));
|
|
1908
|
+
* set.add(new Expression('..script'));
|
|
1909
|
+
*/
|
|
1910
|
+
add(expression) {
|
|
1911
|
+
if (this._sealed) {
|
|
1912
|
+
throw new TypeError(
|
|
1913
|
+
"ExpressionSet is sealed. Create a new ExpressionSet to add more expressions."
|
|
1914
|
+
);
|
|
1915
|
+
}
|
|
1916
|
+
if (this._patterns.has(expression.pattern)) return this;
|
|
1917
|
+
this._patterns.add(expression.pattern);
|
|
1918
|
+
if (expression.hasDeepWildcard()) {
|
|
1919
|
+
const lastSeg2 = expression.segments[expression.segments.length - 1];
|
|
1920
|
+
if (lastSeg2 && lastSeg2.type !== "deep-wildcard" && lastSeg2.tag !== "*") {
|
|
1921
|
+
const tag2 = lastSeg2.tag;
|
|
1922
|
+
if (!this._deepByTerminalTag.has(tag2)) this._deepByTerminalTag.set(tag2, []);
|
|
1923
|
+
this._deepByTerminalTag.get(tag2).push(expression);
|
|
1924
|
+
} else {
|
|
1925
|
+
this._deepWildcards.push(expression);
|
|
1926
|
+
}
|
|
1927
|
+
return this;
|
|
1928
|
+
}
|
|
1929
|
+
const depth = expression.length;
|
|
1930
|
+
const lastSeg = expression.segments[expression.segments.length - 1];
|
|
1931
|
+
const tag = lastSeg?.tag;
|
|
1932
|
+
if (!tag || tag === "*") {
|
|
1933
|
+
if (!this._wildcardByDepth.has(depth)) this._wildcardByDepth.set(depth, []);
|
|
1934
|
+
this._wildcardByDepth.get(depth).push(expression);
|
|
1935
|
+
} else {
|
|
1936
|
+
const key = `${depth}:${tag}`;
|
|
1937
|
+
if (!this._byDepthAndTag.has(key)) this._byDepthAndTag.set(key, []);
|
|
1938
|
+
this._byDepthAndTag.get(key).push(expression);
|
|
1939
|
+
}
|
|
1940
|
+
return this;
|
|
1941
|
+
}
|
|
1942
|
+
/**
|
|
1943
|
+
* Add multiple expressions at once.
|
|
1944
|
+
*
|
|
1945
|
+
* @param {import('./Expression.js').default[]} expressions - Array of Expression instances
|
|
1946
|
+
* @returns {this} for chaining
|
|
1947
|
+
*
|
|
1948
|
+
* @example
|
|
1949
|
+
* set.addAll([
|
|
1950
|
+
* new Expression('root.users.user'),
|
|
1951
|
+
* new Expression('root.config.setting'),
|
|
1952
|
+
* ]);
|
|
1953
|
+
*/
|
|
1954
|
+
addAll(expressions) {
|
|
1955
|
+
for (const expr of expressions) this.add(expr);
|
|
1956
|
+
return this;
|
|
1957
|
+
}
|
|
1958
|
+
/**
|
|
1959
|
+
* Check whether a pattern string is already present in the set.
|
|
1960
|
+
*
|
|
1961
|
+
* @param {import('./Expression.js').default} expression
|
|
1962
|
+
* @returns {boolean}
|
|
1963
|
+
*/
|
|
1964
|
+
has(expression) {
|
|
1965
|
+
return this._patterns.has(expression.pattern);
|
|
1966
|
+
}
|
|
1967
|
+
/**
|
|
1968
|
+
* Number of expressions in the set.
|
|
1969
|
+
* @type {number}
|
|
1970
|
+
*/
|
|
1971
|
+
get size() {
|
|
1972
|
+
return this._patterns.size;
|
|
1973
|
+
}
|
|
1974
|
+
/**
|
|
1975
|
+
* Seal the set against further modifications.
|
|
1976
|
+
* Useful to prevent accidental mutations after config is built.
|
|
1977
|
+
* Calling add() or addAll() on a sealed set throws a TypeError.
|
|
1978
|
+
*
|
|
1979
|
+
* @returns {this}
|
|
1980
|
+
*/
|
|
1981
|
+
seal() {
|
|
1982
|
+
this._sealed = true;
|
|
1983
|
+
return this;
|
|
1984
|
+
}
|
|
1985
|
+
/**
|
|
1986
|
+
* Whether the set has been sealed.
|
|
1987
|
+
* @type {boolean}
|
|
1988
|
+
*/
|
|
1989
|
+
get isSealed() {
|
|
1990
|
+
return this._sealed;
|
|
1991
|
+
}
|
|
1992
|
+
/**
|
|
1993
|
+
* Test whether the matcher's current path matches any expression in the set.
|
|
1994
|
+
*
|
|
1995
|
+
* Evaluation order (cheapest → most expensive):
|
|
1996
|
+
* 1. Exact depth + tag bucket — O(1) lookup, typically 0–2 expressions
|
|
1997
|
+
* 2. Depth-only wildcard bucket — O(1) lookup, rare
|
|
1998
|
+
* 3. Deep-wildcard list — always checked, but usually small
|
|
1999
|
+
*
|
|
2000
|
+
* @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)
|
|
2001
|
+
* @returns {boolean} true if any expression matches the current path
|
|
2002
|
+
*
|
|
2003
|
+
* @example
|
|
2004
|
+
* if (stopNodes.matchesAny(matcher)) {
|
|
2005
|
+
* // handle stop node
|
|
2006
|
+
* }
|
|
2007
|
+
*/
|
|
2008
|
+
matchesAny(matcher) {
|
|
2009
|
+
return this.findMatch(matcher) !== null;
|
|
2010
|
+
}
|
|
2011
|
+
/**
|
|
2012
|
+
* Find and return the first Expression that matches the matcher's current path.
|
|
2013
|
+
*
|
|
2014
|
+
* Uses the same evaluation order as matchesAny (cheapest → most expensive):
|
|
2015
|
+
* 1. Exact depth + tag bucket
|
|
2016
|
+
* 2. Depth-only wildcard bucket
|
|
2017
|
+
* 3. Deep-wildcard list
|
|
2018
|
+
*
|
|
2019
|
+
* @param {import('./Matcher.js').default} matcher - Matcher instance (or readOnly view)
|
|
2020
|
+
* @returns {import('./Expression.js').default | null} the first matching Expression, or null
|
|
2021
|
+
*
|
|
2022
|
+
* @example
|
|
2023
|
+
* const expr = stopNodes.findMatch(matcher);
|
|
2024
|
+
* if (expr) {
|
|
2025
|
+
* // access expr.config, expr.pattern, etc.
|
|
2026
|
+
* }
|
|
2027
|
+
*/
|
|
2028
|
+
findMatch(matcher) {
|
|
2029
|
+
const depth = matcher.getDepth();
|
|
2030
|
+
const tag = matcher.getCurrentTag();
|
|
2031
|
+
const exactKey = `${depth}:${tag}`;
|
|
2032
|
+
const exactBucket = this._byDepthAndTag.get(exactKey);
|
|
2033
|
+
if (exactBucket) {
|
|
2034
|
+
for (let i = 0; i < exactBucket.length; i++) {
|
|
2035
|
+
if (matcher.matches(exactBucket[i])) return exactBucket[i];
|
|
2036
|
+
}
|
|
2037
|
+
}
|
|
2038
|
+
const wildcardBucket = this._wildcardByDepth.get(depth);
|
|
2039
|
+
if (wildcardBucket) {
|
|
2040
|
+
for (let i = 0; i < wildcardBucket.length; i++) {
|
|
2041
|
+
if (matcher.matches(wildcardBucket[i])) return wildcardBucket[i];
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
const deepBucket = this._deepByTerminalTag.get(tag);
|
|
2045
|
+
if (deepBucket) {
|
|
2046
|
+
for (let i = 0; i < deepBucket.length; i++) {
|
|
2047
|
+
if (matcher.matches(deepBucket[i])) return deepBucket[i];
|
|
2048
|
+
}
|
|
2049
|
+
}
|
|
2050
|
+
for (let i = 0; i < this._deepWildcards.length; i++) {
|
|
2051
|
+
if (matcher.matches(this._deepWildcards[i])) return this._deepWildcards[i];
|
|
2052
|
+
}
|
|
2053
|
+
return null;
|
|
2054
|
+
}
|
|
2055
|
+
};
|
|
2056
|
+
|
|
2057
|
+
// ../../node_modules/path-expression-matcher/src/Matcher.js
|
|
2058
|
+
var MatcherView = class {
|
|
2059
|
+
/**
|
|
2060
|
+
* @param {Matcher} matcher - The parent Matcher instance to read from.
|
|
2061
|
+
*/
|
|
2062
|
+
constructor(matcher) {
|
|
2063
|
+
this._matcher = matcher;
|
|
2064
|
+
}
|
|
2065
|
+
/**
|
|
2066
|
+
* Get the path separator used by the parent matcher.
|
|
2067
|
+
* @returns {string}
|
|
2068
|
+
*/
|
|
2069
|
+
get separator() {
|
|
2070
|
+
return this._matcher.separator;
|
|
2071
|
+
}
|
|
2072
|
+
/**
|
|
2073
|
+
* Get current tag name.
|
|
2074
|
+
* @returns {string|undefined}
|
|
2075
|
+
*/
|
|
2076
|
+
getCurrentTag() {
|
|
2077
|
+
const path = this._matcher.path;
|
|
2078
|
+
return path.length > 0 ? path[path.length - 1].tag : void 0;
|
|
2079
|
+
}
|
|
2080
|
+
/**
|
|
2081
|
+
* Get current namespace.
|
|
2082
|
+
* @returns {string|undefined}
|
|
2083
|
+
*/
|
|
2084
|
+
getCurrentNamespace() {
|
|
2085
|
+
const path = this._matcher.path;
|
|
2086
|
+
return path.length > 0 ? path[path.length - 1].namespace : void 0;
|
|
2087
|
+
}
|
|
2088
|
+
/**
|
|
2089
|
+
* Get current node's attribute value.
|
|
2090
|
+
* @param {string} attrName
|
|
2091
|
+
* @returns {*}
|
|
2092
|
+
*/
|
|
2093
|
+
getAttrValue(attrName) {
|
|
2094
|
+
const path = this._matcher.path;
|
|
2095
|
+
if (path.length === 0) return void 0;
|
|
2096
|
+
return path[path.length - 1].values?.[attrName];
|
|
2097
|
+
}
|
|
2098
|
+
/**
|
|
2099
|
+
* Check if current node has an attribute.
|
|
2100
|
+
* @param {string} attrName
|
|
2101
|
+
* @returns {boolean}
|
|
2102
|
+
*/
|
|
2103
|
+
hasAttr(attrName) {
|
|
2104
|
+
const path = this._matcher.path;
|
|
2105
|
+
if (path.length === 0) return false;
|
|
2106
|
+
const current = path[path.length - 1];
|
|
2107
|
+
return current.values !== void 0 && attrName in current.values;
|
|
2108
|
+
}
|
|
2109
|
+
/**
|
|
2110
|
+
* Get the value of a "kept" attribute from the nearest ancestor (or
|
|
2111
|
+
* current node) that declared it via `push(tag, attrs, ns, { keep: [...] })`.
|
|
2112
|
+
* @param {string} attrName
|
|
2113
|
+
* @returns {*}
|
|
2114
|
+
*/
|
|
2115
|
+
getAnyParentAttr(attrName) {
|
|
2116
|
+
return this._matcher.getAnyParentAttr(attrName);
|
|
2117
|
+
}
|
|
2118
|
+
/**
|
|
2119
|
+
* Check whether any ancestor (or the current node) kept the given
|
|
2120
|
+
* attribute via `push(tag, attrs, ns, { keep: [...] })`.
|
|
2121
|
+
* @param {string} attrName
|
|
2122
|
+
* @returns {boolean}
|
|
2123
|
+
*/
|
|
2124
|
+
hasAnyParentAttr(attrName) {
|
|
2125
|
+
return this._matcher.hasAnyParentAttr(attrName);
|
|
2126
|
+
}
|
|
2127
|
+
/**
|
|
2128
|
+
* Get current node's sibling position (child index in parent).
|
|
2129
|
+
* @returns {number}
|
|
2130
|
+
*/
|
|
2131
|
+
getPosition() {
|
|
2132
|
+
const path = this._matcher.path;
|
|
2133
|
+
if (path.length === 0) return -1;
|
|
2134
|
+
return path[path.length - 1].position ?? 0;
|
|
2135
|
+
}
|
|
2136
|
+
/**
|
|
2137
|
+
* Get current node's repeat counter (occurrence count of this tag name).
|
|
2138
|
+
* @returns {number}
|
|
2139
|
+
*/
|
|
2140
|
+
getCounter() {
|
|
2141
|
+
const path = this._matcher.path;
|
|
2142
|
+
if (path.length === 0) return -1;
|
|
2143
|
+
return path[path.length - 1].counter ?? 0;
|
|
2144
|
+
}
|
|
2145
|
+
/**
|
|
2146
|
+
* Get current node's sibling index (alias for getPosition).
|
|
2147
|
+
* @returns {number}
|
|
2148
|
+
* @deprecated Use getPosition() or getCounter() instead
|
|
2149
|
+
*/
|
|
2150
|
+
getIndex() {
|
|
2151
|
+
return this.getPosition();
|
|
2152
|
+
}
|
|
2153
|
+
/**
|
|
2154
|
+
* Get current path depth.
|
|
2155
|
+
* @returns {number}
|
|
2156
|
+
*/
|
|
2157
|
+
getDepth() {
|
|
2158
|
+
return this._matcher.path.length;
|
|
2159
|
+
}
|
|
2160
|
+
/**
|
|
2161
|
+
* Get path as string.
|
|
2162
|
+
* @param {string} [separator] - Optional separator (uses default if not provided)
|
|
2163
|
+
* @param {boolean} [includeNamespace=true]
|
|
2164
|
+
* @returns {string}
|
|
2165
|
+
*/
|
|
2166
|
+
toString(separator, includeNamespace = true) {
|
|
2167
|
+
return this._matcher.toString(separator, includeNamespace);
|
|
2168
|
+
}
|
|
2169
|
+
/**
|
|
2170
|
+
* Get path as array of tag names.
|
|
2171
|
+
* @returns {string[]}
|
|
2172
|
+
*/
|
|
2173
|
+
toArray() {
|
|
2174
|
+
return this._matcher.path.map((n) => n.tag);
|
|
2175
|
+
}
|
|
2176
|
+
/**
|
|
2177
|
+
* Match current path against an Expression.
|
|
2178
|
+
* @param {Expression} expression
|
|
2179
|
+
* @returns {boolean}
|
|
2180
|
+
*/
|
|
2181
|
+
matches(expression) {
|
|
2182
|
+
return this._matcher.matches(expression);
|
|
2183
|
+
}
|
|
2184
|
+
/**
|
|
2185
|
+
* Match any expression in the given set against the current path.
|
|
2186
|
+
* @param {ExpressionSet} exprSet
|
|
2187
|
+
* @returns {boolean}
|
|
2188
|
+
*/
|
|
2189
|
+
matchesAny(exprSet) {
|
|
2190
|
+
return exprSet.matchesAny(this._matcher);
|
|
2191
|
+
}
|
|
2192
|
+
};
|
|
2193
|
+
var Matcher = class {
|
|
2194
|
+
/**
|
|
2195
|
+
* Create a new Matcher.
|
|
2196
|
+
* @param {Object} [options={}]
|
|
2197
|
+
* @param {string} [options.separator='.'] - Default path separator
|
|
2198
|
+
*/
|
|
2199
|
+
constructor(options = {}) {
|
|
2200
|
+
this.separator = options.separator || ".";
|
|
2201
|
+
this.path = [];
|
|
2202
|
+
this.siblingStacks = [];
|
|
2203
|
+
this._pathStringCache = null;
|
|
2204
|
+
this._view = new MatcherView(this);
|
|
2205
|
+
this._keptAttrs = [];
|
|
2206
|
+
}
|
|
2207
|
+
/**
|
|
2208
|
+
* Push a new tag onto the path.
|
|
2209
|
+
* @param {string} tagName
|
|
2210
|
+
* @param {Object|null} [attrValues=null]
|
|
2211
|
+
* @param {string|null} [namespace=null]
|
|
2212
|
+
* @param {Object|null} [options=null]
|
|
2213
|
+
* @param {string[]} [options.keep] - Names of attributes (from attrValues)
|
|
2214
|
+
*/
|
|
2215
|
+
push(tagName, attrValues = null, namespace = null, options = null) {
|
|
2216
|
+
this._pathStringCache = null;
|
|
2217
|
+
if (this.path.length > 0) {
|
|
2218
|
+
this.path[this.path.length - 1].values = void 0;
|
|
2219
|
+
}
|
|
2220
|
+
const currentLevel = this.path.length;
|
|
2221
|
+
let level = this.siblingStacks[currentLevel];
|
|
2222
|
+
if (!level) {
|
|
2223
|
+
level = { counts: /* @__PURE__ */ new Map(), total: 0 };
|
|
2224
|
+
this.siblingStacks[currentLevel] = level;
|
|
2225
|
+
}
|
|
2226
|
+
const siblingKey = namespace ? `${namespace}:${tagName}` : tagName;
|
|
2227
|
+
const counter = level.counts.get(siblingKey) || 0;
|
|
2228
|
+
const position = level.total;
|
|
2229
|
+
level.counts.set(siblingKey, counter + 1);
|
|
2230
|
+
level.total++;
|
|
2231
|
+
const node = {
|
|
2232
|
+
tag: tagName,
|
|
2233
|
+
position,
|
|
2234
|
+
counter
|
|
2235
|
+
};
|
|
2236
|
+
if (namespace !== null && namespace !== void 0) {
|
|
2237
|
+
node.namespace = namespace;
|
|
2238
|
+
}
|
|
2239
|
+
if (attrValues !== null && attrValues !== void 0) {
|
|
2240
|
+
node.values = attrValues;
|
|
2241
|
+
}
|
|
2242
|
+
this.path.push(node);
|
|
2243
|
+
const depth = this.path.length;
|
|
2244
|
+
const keep = options !== null ? options.keep : null;
|
|
2245
|
+
if (keep !== null && keep !== void 0 && keep.length > 0 && attrValues) {
|
|
2246
|
+
for (let i = 0; i < keep.length; i++) {
|
|
2247
|
+
const name = keep[i];
|
|
2248
|
+
if (attrValues[name] !== void 0) {
|
|
2249
|
+
this._keptAttrs.push({ depth, name, value: attrValues[name] });
|
|
2250
|
+
}
|
|
2251
|
+
}
|
|
2252
|
+
}
|
|
2253
|
+
}
|
|
2254
|
+
/**
|
|
2255
|
+
* Pop the last tag from the path.
|
|
2256
|
+
* @returns {Object|undefined} The popped node
|
|
2257
|
+
*/
|
|
2258
|
+
pop() {
|
|
2259
|
+
if (this.path.length === 0) return void 0;
|
|
2260
|
+
this._pathStringCache = null;
|
|
2261
|
+
const node = this.path.pop();
|
|
2262
|
+
if (this.siblingStacks.length > this.path.length + 1) {
|
|
2263
|
+
this.siblingStacks.length = this.path.length + 1;
|
|
2264
|
+
}
|
|
2265
|
+
const poppedDepth = this.path.length + 1;
|
|
2266
|
+
while (this._keptAttrs.length > 0 && this._keptAttrs[this._keptAttrs.length - 1].depth >= poppedDepth) {
|
|
2267
|
+
this._keptAttrs.pop();
|
|
2268
|
+
}
|
|
2269
|
+
return node;
|
|
2270
|
+
}
|
|
2271
|
+
/**
|
|
2272
|
+
* Update current node's attribute values.
|
|
2273
|
+
* Useful when attributes are parsed after push.
|
|
2274
|
+
* @param {Object} attrValues
|
|
2275
|
+
*/
|
|
2276
|
+
updateCurrent(attrValues) {
|
|
2277
|
+
if (this.path.length > 0) {
|
|
2278
|
+
const current = this.path[this.path.length - 1];
|
|
2279
|
+
if (attrValues !== null && attrValues !== void 0) {
|
|
2280
|
+
current.values = attrValues;
|
|
2281
|
+
}
|
|
2282
|
+
}
|
|
2283
|
+
}
|
|
2284
|
+
/**
|
|
2285
|
+
* Get current tag name.
|
|
2286
|
+
* @returns {string|undefined}
|
|
2287
|
+
*/
|
|
2288
|
+
getCurrentTag() {
|
|
2289
|
+
return this.path.length > 0 ? this.path[this.path.length - 1].tag : void 0;
|
|
2290
|
+
}
|
|
2291
|
+
/**
|
|
2292
|
+
* Get current namespace.
|
|
2293
|
+
* @returns {string|undefined}
|
|
2294
|
+
*/
|
|
2295
|
+
getCurrentNamespace() {
|
|
2296
|
+
return this.path.length > 0 ? this.path[this.path.length - 1].namespace : void 0;
|
|
2297
|
+
}
|
|
2298
|
+
/**
|
|
2299
|
+
* Get current node's attribute value.
|
|
2300
|
+
* @param {string} attrName
|
|
2301
|
+
* @returns {*}
|
|
2302
|
+
*/
|
|
2303
|
+
getAttrValue(attrName) {
|
|
2304
|
+
if (this.path.length === 0) return void 0;
|
|
2305
|
+
return this.path[this.path.length - 1].values?.[attrName];
|
|
2306
|
+
}
|
|
2307
|
+
/**
|
|
2308
|
+
* Check if current node has an attribute.
|
|
2309
|
+
* @param {string} attrName
|
|
2310
|
+
* @returns {boolean}
|
|
2311
|
+
*/
|
|
2312
|
+
hasAttr(attrName) {
|
|
2313
|
+
if (this.path.length === 0) return false;
|
|
2314
|
+
const current = this.path[this.path.length - 1];
|
|
2315
|
+
return current.values !== void 0 && attrName in current.values;
|
|
2316
|
+
}
|
|
2317
|
+
/**
|
|
2318
|
+
* Get the value of a "kept" attribute from the nearest ancestor (or
|
|
2319
|
+
* current node) that declared it via `push(tag, attrs, ns, { keep: [...] })`.
|
|
2320
|
+
* Unlike getAttrValue(), this works regardless of how deep the path has
|
|
2321
|
+
* gone since the attribute was pushed — but only for attribute names that
|
|
2322
|
+
* were explicitly marked with `keep` at push time. Cost is proportional to
|
|
2323
|
+
* the number of currently-kept attributes (typically 0-3), not path depth.
|
|
2324
|
+
* @param {string} attrName
|
|
2325
|
+
* @returns {*} the value, or undefined if no ancestor kept this attribute
|
|
2326
|
+
*/
|
|
2327
|
+
getAnyParentAttr(attrName) {
|
|
2328
|
+
const kept = this._keptAttrs;
|
|
2329
|
+
for (let i = kept.length - 1; i >= 0; i--) {
|
|
2330
|
+
if (kept[i].name === attrName) return kept[i].value;
|
|
2331
|
+
}
|
|
2332
|
+
return void 0;
|
|
2333
|
+
}
|
|
2334
|
+
/**
|
|
2335
|
+
* Check whether any ancestor (or the current node) kept the given
|
|
2336
|
+
* attribute via `push(tag, attrs, ns, { keep: [...] })`.
|
|
2337
|
+
* @param {string} attrName
|
|
2338
|
+
* @returns {boolean}
|
|
2339
|
+
*/
|
|
2340
|
+
hasAnyParentAttr(attrName) {
|
|
2341
|
+
const kept = this._keptAttrs;
|
|
2342
|
+
for (let i = kept.length - 1; i >= 0; i--) {
|
|
2343
|
+
if (kept[i].name === attrName) return true;
|
|
2344
|
+
}
|
|
2345
|
+
return false;
|
|
2346
|
+
}
|
|
2347
|
+
/**
|
|
2348
|
+
* Get current node's sibling position (child index in parent).
|
|
2349
|
+
* @returns {number}
|
|
2350
|
+
*/
|
|
2351
|
+
getPosition() {
|
|
2352
|
+
if (this.path.length === 0) return -1;
|
|
2353
|
+
return this.path[this.path.length - 1].position ?? 0;
|
|
2354
|
+
}
|
|
2355
|
+
/**
|
|
2356
|
+
* Get current node's repeat counter (occurrence count of this tag name).
|
|
2357
|
+
* @returns {number}
|
|
2358
|
+
*/
|
|
2359
|
+
getCounter() {
|
|
2360
|
+
if (this.path.length === 0) return -1;
|
|
2361
|
+
return this.path[this.path.length - 1].counter ?? 0;
|
|
2362
|
+
}
|
|
2363
|
+
/**
|
|
2364
|
+
* Get current node's sibling index (alias for getPosition).
|
|
2365
|
+
* @returns {number}
|
|
2366
|
+
* @deprecated Use getPosition() or getCounter() instead
|
|
2367
|
+
*/
|
|
2368
|
+
getIndex() {
|
|
2369
|
+
return this.getPosition();
|
|
2370
|
+
}
|
|
2371
|
+
/**
|
|
2372
|
+
* Get current path depth.
|
|
2373
|
+
* @returns {number}
|
|
2374
|
+
*/
|
|
2375
|
+
getDepth() {
|
|
2376
|
+
return this.path.length;
|
|
2377
|
+
}
|
|
2378
|
+
/**
|
|
2379
|
+
* Get path as string.
|
|
2380
|
+
* @param {string} [separator] - Optional separator (uses default if not provided)
|
|
2381
|
+
* @param {boolean} [includeNamespace=true]
|
|
2382
|
+
* @returns {string}
|
|
2383
|
+
*/
|
|
2384
|
+
toString(separator, includeNamespace = true) {
|
|
2385
|
+
const sep2 = separator || this.separator;
|
|
2386
|
+
const isDefault = sep2 === this.separator && includeNamespace === true;
|
|
2387
|
+
if (isDefault) {
|
|
2388
|
+
if (this._pathStringCache !== null) {
|
|
2389
|
+
return this._pathStringCache;
|
|
2390
|
+
}
|
|
2391
|
+
const result = this.path.map(
|
|
2392
|
+
(n) => n.namespace ? `${n.namespace}:${n.tag}` : n.tag
|
|
2393
|
+
).join(sep2);
|
|
2394
|
+
this._pathStringCache = result;
|
|
2395
|
+
return result;
|
|
2396
|
+
}
|
|
2397
|
+
return this.path.map(
|
|
2398
|
+
(n) => includeNamespace && n.namespace ? `${n.namespace}:${n.tag}` : n.tag
|
|
2399
|
+
).join(sep2);
|
|
2400
|
+
}
|
|
2401
|
+
/**
|
|
2402
|
+
* Get path as array of tag names.
|
|
2403
|
+
* @returns {string[]}
|
|
2404
|
+
*/
|
|
2405
|
+
toArray() {
|
|
2406
|
+
return this.path.map((n) => n.tag);
|
|
2407
|
+
}
|
|
2408
|
+
/**
|
|
2409
|
+
* Reset the path to empty.
|
|
2410
|
+
*/
|
|
2411
|
+
reset() {
|
|
2412
|
+
this._pathStringCache = null;
|
|
2413
|
+
this.path = [];
|
|
2414
|
+
this.siblingStacks = [];
|
|
2415
|
+
this._keptAttrs = [];
|
|
2416
|
+
}
|
|
2417
|
+
/**
|
|
2418
|
+
* Match current path against an Expression.
|
|
2419
|
+
* @param {Expression} expression
|
|
2420
|
+
* @returns {boolean}
|
|
2421
|
+
*/
|
|
2422
|
+
matches(expression) {
|
|
2423
|
+
const segments = expression.segments;
|
|
2424
|
+
if (segments.length === 0) {
|
|
2425
|
+
return false;
|
|
2426
|
+
}
|
|
2427
|
+
if (expression.hasDeepWildcard()) {
|
|
2428
|
+
return this._matchWithDeepWildcard(segments);
|
|
2429
|
+
}
|
|
2430
|
+
return this._matchSimple(segments);
|
|
2431
|
+
}
|
|
2432
|
+
/**
|
|
2433
|
+
* @private
|
|
2434
|
+
*/
|
|
2435
|
+
_matchSimple(segments) {
|
|
2436
|
+
if (this.path.length !== segments.length) {
|
|
2437
|
+
return false;
|
|
2438
|
+
}
|
|
2439
|
+
for (let i = 0; i < segments.length; i++) {
|
|
2440
|
+
if (!this._matchSegment(segments[i], this.path[i], i === this.path.length - 1)) {
|
|
2441
|
+
return false;
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
return true;
|
|
2445
|
+
}
|
|
2446
|
+
/**
|
|
2447
|
+
* @private
|
|
2448
|
+
*/
|
|
2449
|
+
_matchWithDeepWildcard(segments) {
|
|
2450
|
+
let pathIdx = this.path.length - 1;
|
|
2451
|
+
let segIdx = segments.length - 1;
|
|
2452
|
+
while (segIdx >= 0 && pathIdx >= 0) {
|
|
2453
|
+
const segment = segments[segIdx];
|
|
2454
|
+
if (segment.type === "deep-wildcard") {
|
|
2455
|
+
segIdx--;
|
|
2456
|
+
if (segIdx < 0) {
|
|
2457
|
+
return true;
|
|
2458
|
+
}
|
|
2459
|
+
const nextSeg = segments[segIdx];
|
|
2460
|
+
let found = false;
|
|
2461
|
+
for (let i = pathIdx; i >= 0; i--) {
|
|
2462
|
+
if (this._matchSegment(nextSeg, this.path[i], i === this.path.length - 1)) {
|
|
2463
|
+
pathIdx = i - 1;
|
|
2464
|
+
segIdx--;
|
|
2465
|
+
found = true;
|
|
2466
|
+
break;
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
if (!found) {
|
|
2470
|
+
return false;
|
|
2471
|
+
}
|
|
2472
|
+
} else {
|
|
2473
|
+
if (!this._matchSegment(segment, this.path[pathIdx], pathIdx === this.path.length - 1)) {
|
|
2474
|
+
return false;
|
|
2475
|
+
}
|
|
2476
|
+
pathIdx--;
|
|
2477
|
+
segIdx--;
|
|
2478
|
+
}
|
|
2479
|
+
}
|
|
2480
|
+
return segIdx < 0;
|
|
2481
|
+
}
|
|
2482
|
+
/**
|
|
2483
|
+
* @private
|
|
2484
|
+
*/
|
|
2485
|
+
_matchSegment(segment, node, isCurrentNode) {
|
|
2486
|
+
if (segment.tag !== "*" && segment.tag !== node.tag) {
|
|
2487
|
+
return false;
|
|
2488
|
+
}
|
|
2489
|
+
if (segment.namespace !== void 0) {
|
|
2490
|
+
if (segment.namespace !== "*" && segment.namespace !== node.namespace) {
|
|
2491
|
+
return false;
|
|
2492
|
+
}
|
|
2493
|
+
}
|
|
2494
|
+
if (segment.attrName !== void 0) {
|
|
2495
|
+
if (!isCurrentNode) {
|
|
2496
|
+
return false;
|
|
2497
|
+
}
|
|
2498
|
+
if (!node.values || !(segment.attrName in node.values)) {
|
|
2499
|
+
return false;
|
|
2500
|
+
}
|
|
2501
|
+
if (segment.attrValue !== void 0) {
|
|
2502
|
+
if (String(node.values[segment.attrName]) !== String(segment.attrValue)) {
|
|
2503
|
+
return false;
|
|
2504
|
+
}
|
|
2505
|
+
}
|
|
2506
|
+
}
|
|
2507
|
+
if (segment.position !== void 0) {
|
|
2508
|
+
if (!isCurrentNode) {
|
|
2509
|
+
return false;
|
|
2510
|
+
}
|
|
2511
|
+
const counter = node.counter ?? 0;
|
|
2512
|
+
if (segment.position === "first" && counter !== 0) {
|
|
2513
|
+
return false;
|
|
2514
|
+
} else if (segment.position === "odd" && counter % 2 !== 1) {
|
|
2515
|
+
return false;
|
|
2516
|
+
} else if (segment.position === "even" && counter % 2 !== 0) {
|
|
2517
|
+
return false;
|
|
2518
|
+
} else if (segment.position === "nth" && counter !== segment.positionValue) {
|
|
2519
|
+
return false;
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
return true;
|
|
2523
|
+
}
|
|
2524
|
+
/**
|
|
2525
|
+
* Match any expression in the given set against the current path.
|
|
2526
|
+
* @param {ExpressionSet} exprSet
|
|
2527
|
+
* @returns {boolean}
|
|
2528
|
+
*/
|
|
2529
|
+
matchesAny(exprSet) {
|
|
2530
|
+
return exprSet.matchesAny(this);
|
|
2531
|
+
}
|
|
2532
|
+
/**
|
|
2533
|
+
* Create a snapshot of current state.
|
|
2534
|
+
* @returns {Object}
|
|
2535
|
+
*/
|
|
2536
|
+
snapshot() {
|
|
2537
|
+
return {
|
|
2538
|
+
path: this.path.map((node) => ({ ...node })),
|
|
2539
|
+
siblingStacks: this.siblingStacks.map((level) => level ? { counts: new Map(level.counts), total: level.total } : level),
|
|
2540
|
+
keptAttrs: this._keptAttrs.map((entry) => ({ ...entry }))
|
|
2541
|
+
};
|
|
2542
|
+
}
|
|
2543
|
+
/**
|
|
2544
|
+
* Restore state from snapshot.
|
|
2545
|
+
* @param {Object} snapshot
|
|
2546
|
+
*/
|
|
2547
|
+
restore(snapshot2) {
|
|
2548
|
+
this._pathStringCache = null;
|
|
2549
|
+
this.path = snapshot2.path.map((node) => ({ ...node }));
|
|
2550
|
+
this.siblingStacks = snapshot2.siblingStacks.map((level) => level ? { counts: new Map(level.counts), total: level.total } : level);
|
|
2551
|
+
this._keptAttrs = (snapshot2.keptAttrs || []).map((entry) => ({ ...entry }));
|
|
2552
|
+
}
|
|
2553
|
+
/**
|
|
2554
|
+
* Return the read-only {@link MatcherView} for this matcher.
|
|
2555
|
+
*
|
|
2556
|
+
* The same instance is returned on every call — no allocation occurs.
|
|
2557
|
+
* It always reflects the current parser state and is safe to pass to
|
|
2558
|
+
* user callbacks without risk of accidental mutation.
|
|
2559
|
+
*
|
|
2560
|
+
* @returns {MatcherView}
|
|
2561
|
+
*
|
|
2562
|
+
* @example
|
|
2563
|
+
* const view = matcher.readOnly();
|
|
2564
|
+
* // pass view to callbacks — it stays in sync automatically
|
|
2565
|
+
* view.matches(expr); // ✓
|
|
2566
|
+
* view.getCurrentTag(); // ✓
|
|
2567
|
+
* // view.push(...) // ✗ method does not exist — caught by TypeScript
|
|
2568
|
+
*/
|
|
2569
|
+
readOnly() {
|
|
2570
|
+
return this._view;
|
|
2571
|
+
}
|
|
2572
|
+
};
|
|
2573
|
+
|
|
2574
|
+
// ../../node_modules/is-unsafe/src/contexts/html.js
|
|
2575
|
+
var HTML_PATTERNS = [
|
|
2576
|
+
{
|
|
2577
|
+
id: "html-script-open",
|
|
2578
|
+
description: "<script opening tag",
|
|
2579
|
+
pattern: /<script[\s>/]/i
|
|
2580
|
+
},
|
|
2581
|
+
{
|
|
2582
|
+
id: "html-script-close",
|
|
2583
|
+
description: "</script closing tag",
|
|
2584
|
+
pattern: /<\/script[\s>]/i
|
|
2585
|
+
},
|
|
2586
|
+
{
|
|
2587
|
+
id: "html-javascript-protocol",
|
|
2588
|
+
description: "javascript: URI scheme (with optional whitespace/encoding)",
|
|
2589
|
+
// Handles javascript:, j\u0061vascript:, and whitespace variants
|
|
2590
|
+
pattern: /j[\t\n\r ]*a[\t\n\r ]*v[\t\n\r ]*a[\t\n\r ]*s[\t\n\r ]*c[\t\n\r ]*r[\t\n\r ]*i[\t\n\r ]*p[\t\n\r ]*t[\t\n\r ]*:/i
|
|
2591
|
+
},
|
|
2592
|
+
{
|
|
2593
|
+
id: "html-vbscript-protocol",
|
|
2594
|
+
description: "vbscript: URI scheme",
|
|
2595
|
+
pattern: /vbscript[\t\n\r ]*:/i
|
|
2596
|
+
},
|
|
2597
|
+
{
|
|
2598
|
+
id: "html-data-html",
|
|
2599
|
+
description: "data:text/html URI \u2014 can execute scripts in browsers",
|
|
2600
|
+
pattern: /data[\t\n\r ]*:[\t\n\r ]*text\/html/i
|
|
2601
|
+
},
|
|
2602
|
+
{
|
|
2603
|
+
id: "html-data-xhtml",
|
|
2604
|
+
description: "data:application/xhtml+xml URI",
|
|
2605
|
+
pattern: /data[\t\n\r ]*:[\t\n\r ]*application\/xhtml/i
|
|
2606
|
+
},
|
|
2607
|
+
{
|
|
2608
|
+
id: "html-data-svg",
|
|
2609
|
+
description: "data:image/svg+xml URI \u2014 can execute scripts",
|
|
2610
|
+
pattern: /data[\t\n\r ]*:[\t\n\r ]*image\/svg\+xml/i
|
|
2611
|
+
},
|
|
2612
|
+
{
|
|
2613
|
+
id: "html-inline-event-handler",
|
|
2614
|
+
description: "Inline event handler attributes: onclick=, onerror=, onload=, etc.",
|
|
2615
|
+
// \bon ensures we match a word boundary so "phonetic=" is not caught
|
|
2616
|
+
pattern: /\bon\w{1,30}\s*=/i
|
|
2617
|
+
},
|
|
2618
|
+
{
|
|
2619
|
+
id: "html-entity-obfuscated-script",
|
|
2620
|
+
description: "HTML-entity-encoded <script (e.g. <script or <script)",
|
|
2621
|
+
// Entities include optional trailing semicolon: < or < (both valid in HTML5)
|
|
2622
|
+
pattern: /(?:�*3[Cc];?|�*60;?|<)\s*script/i
|
|
2623
|
+
},
|
|
2624
|
+
{
|
|
2625
|
+
id: "html-entity-obfuscated-javascript",
|
|
2626
|
+
description: 'HTML-entity-encoded javascript: (partial \u2014 catches common j or j for "j")',
|
|
2627
|
+
pattern: /(?:�*6[Aa];?|�*106;?)\s*(?:�*61;?|a)[\s\S]{0,80}script\s*:/i
|
|
2628
|
+
},
|
|
2629
|
+
{
|
|
2630
|
+
id: "html-style-expression",
|
|
2631
|
+
description: "CSS expression() \u2014 IE-era code execution in style attributes",
|
|
2632
|
+
pattern: /style[\s\S]{0,20}expression\s*\(/i
|
|
2633
|
+
},
|
|
2634
|
+
{
|
|
2635
|
+
id: "html-object-embed",
|
|
2636
|
+
description: "<object or <embed tags that can load active content",
|
|
2637
|
+
pattern: /<(?:object|embed)[\s>/]/i
|
|
2638
|
+
},
|
|
2639
|
+
{
|
|
2640
|
+
id: "html-base-tag",
|
|
2641
|
+
description: "<base href= \u2014 can hijack all relative URLs on a page",
|
|
2642
|
+
pattern: /<base[\s>]/i
|
|
2643
|
+
},
|
|
2644
|
+
{
|
|
2645
|
+
id: "html-meta-refresh",
|
|
2646
|
+
description: '<meta http-equiv="refresh" \u2014 can redirect users',
|
|
2647
|
+
pattern: /<meta[\s\S]{0,40}http-equiv[\s\S]{0,20}refresh/i
|
|
2648
|
+
},
|
|
2649
|
+
{
|
|
2650
|
+
id: "html-srcdoc",
|
|
2651
|
+
description: "srcdoc= attribute on iframes \u2014 embeds HTML that can run scripts",
|
|
2652
|
+
pattern: /srcdoc\s*=/i
|
|
2653
|
+
},
|
|
2654
|
+
{
|
|
2655
|
+
id: "html-iframe",
|
|
2656
|
+
description: "<iframe tag",
|
|
2657
|
+
pattern: /<iframe[\s>/]/i
|
|
2658
|
+
},
|
|
2659
|
+
{
|
|
2660
|
+
id: "html-form",
|
|
2661
|
+
description: "<form tag \u2014 can be used for phishing / credential harvesting injection",
|
|
2662
|
+
pattern: /<form[\s>/]/i
|
|
2663
|
+
}
|
|
2664
|
+
];
|
|
2665
|
+
var html_default = HTML_PATTERNS;
|
|
2666
|
+
|
|
2667
|
+
// ../../node_modules/is-unsafe/src/contexts/xml.js
|
|
2668
|
+
var XML_PATTERNS = [
|
|
2669
|
+
{
|
|
2670
|
+
id: "xml-cdata-injection",
|
|
2671
|
+
description: "CDATA section injection: <![CDATA[ breaks out of text node context",
|
|
2672
|
+
pattern: /<!\[CDATA\[/i
|
|
2673
|
+
},
|
|
2674
|
+
{
|
|
2675
|
+
id: "xml-cdata-close",
|
|
2676
|
+
description: "CDATA close sequence: ]]> can terminate an enclosing CDATA section",
|
|
2677
|
+
pattern: /\]\]>/
|
|
2678
|
+
},
|
|
2679
|
+
{
|
|
2680
|
+
id: "xml-processing-instruction",
|
|
2681
|
+
description: "XML processing instruction: <?xml-stylesheet or <?php etc.",
|
|
2682
|
+
pattern: /<\?(?:xml[\- ]|php|asp)/i
|
|
2683
|
+
},
|
|
2684
|
+
{
|
|
2685
|
+
id: "xml-doctype-injection",
|
|
2686
|
+
description: "DOCTYPE declaration embedded in content \u2014 can define entities",
|
|
2687
|
+
// Match <!DOCTYPE followed by end-of-string, whitespace, or [ (internal subset)
|
|
2688
|
+
pattern: /<!DOCTYPE(?:[\s[]|$)/i
|
|
2689
|
+
},
|
|
2690
|
+
{
|
|
2691
|
+
id: "xml-entity-system",
|
|
2692
|
+
description: "SYSTEM keyword \u2014 used in external entity declarations (XXE)",
|
|
2693
|
+
pattern: /\bSYSTEM\s+["']/i
|
|
2694
|
+
},
|
|
2695
|
+
{
|
|
2696
|
+
id: "xml-entity-public",
|
|
2697
|
+
description: "PUBLIC keyword \u2014 used in external entity declarations (XXE)",
|
|
2698
|
+
pattern: /\bPUBLIC\s+["']/i
|
|
2699
|
+
},
|
|
2700
|
+
{
|
|
2701
|
+
id: "xml-entity-declaration",
|
|
2702
|
+
description: "<!ENTITY declaration \u2014 defines entities, potential XXE or entity expansion",
|
|
2703
|
+
pattern: /<!ENTITY[\s%]/i
|
|
2704
|
+
},
|
|
2705
|
+
{
|
|
2706
|
+
id: "xml-billion-laughs",
|
|
2707
|
+
description: "Entity reference chaining / billion laughs: repeated &eX; style references",
|
|
2708
|
+
// Heuristic: 3+ consecutive entity refs suggests expansion attack
|
|
2709
|
+
pattern: /(?:&\w{1,20};){3,}/
|
|
2710
|
+
},
|
|
2711
|
+
{
|
|
2712
|
+
id: "xml-namespace-confusion",
|
|
2713
|
+
description: "xmlns: attribute injection \u2014 can redefine namespaces to confuse parsers",
|
|
2714
|
+
pattern: /\bxmlns\s*(?::\w{1,40})?\s*=/i
|
|
2715
|
+
},
|
|
2716
|
+
{
|
|
2717
|
+
id: "xml-comment-injection",
|
|
2718
|
+
description: "<!-- comment injection \u2014 can hide content from some parsers",
|
|
2719
|
+
pattern: /<!--/
|
|
2720
|
+
},
|
|
2721
|
+
{
|
|
2722
|
+
id: "xml-comment-close",
|
|
2723
|
+
description: "--> closes an enclosing XML comment",
|
|
2724
|
+
pattern: /-->/
|
|
2725
|
+
},
|
|
2726
|
+
{
|
|
2727
|
+
id: "xml-pi-close",
|
|
2728
|
+
description: "?> closes an enclosing processing instruction",
|
|
2729
|
+
pattern: /\?>/
|
|
2730
|
+
}
|
|
2731
|
+
];
|
|
2732
|
+
var xml_default = XML_PATTERNS;
|
|
2733
|
+
|
|
2734
|
+
// ../../node_modules/is-unsafe/src/contexts/svg.js
|
|
2735
|
+
var SVG_PATTERNS = [
|
|
2736
|
+
{
|
|
2737
|
+
id: "svg-script-element",
|
|
2738
|
+
description: "<script element inside SVG executes JavaScript",
|
|
2739
|
+
pattern: /<script[\s>/]/i
|
|
2740
|
+
},
|
|
2741
|
+
{
|
|
2742
|
+
id: "svg-xlink-href-javascript",
|
|
2743
|
+
description: "xlink:href with javascript: \u2014 classic SVG XSS via <a> or <use>",
|
|
2744
|
+
pattern: /xlink\s*:\s*href\s*=\s*["']?\s*javascript\s*:/i
|
|
2745
|
+
},
|
|
2746
|
+
{
|
|
2747
|
+
id: "svg-href-javascript",
|
|
2748
|
+
description: "href= with javascript: in SVG context (<a>, <animate>, etc.)",
|
|
2749
|
+
pattern: /href\s*=\s*["']?\s*javascript\s*:/i
|
|
2750
|
+
},
|
|
2751
|
+
{
|
|
2752
|
+
id: "svg-foreignobject",
|
|
2753
|
+
description: "<foreignObject embeds HTML inside SVG \u2014 can execute scripts",
|
|
2754
|
+
pattern: /<foreignObject[\s>/]/i
|
|
2755
|
+
},
|
|
2756
|
+
{
|
|
2757
|
+
id: "svg-use-external",
|
|
2758
|
+
description: "<use xlink:href or href pointing to external resource (non-fragment URL)",
|
|
2759
|
+
// Match <use with href= where the value starts with a non-# character (external URL)
|
|
2760
|
+
// [\"'][^#] catches quoted values not starting with #; [^\"'#\s>] catches unquoted
|
|
2761
|
+
pattern: /<use[\s\S]{0,60}(?:xlink\s*:\s*)?href\s*=\s*(?:["'][^#]|[^"'#\s>])/i
|
|
2762
|
+
},
|
|
2763
|
+
{
|
|
2764
|
+
id: "svg-animate-href",
|
|
2765
|
+
description: '<animate attributeName="href" \u2014 can dynamically change href to javascript:',
|
|
2766
|
+
pattern: /<animate[\s\S]{0,80}attributeName\s*=\s*["'][\s]*href["']/i
|
|
2767
|
+
},
|
|
2768
|
+
{
|
|
2769
|
+
id: "svg-animate-xlinkhref",
|
|
2770
|
+
description: '<animate attributeName="xlink:href"',
|
|
2771
|
+
pattern: /<animate[\s\S]{0,80}attributeName\s*=\s*["'][\s]*xlink\s*:\s*href["']/i
|
|
2772
|
+
},
|
|
2773
|
+
{
|
|
2774
|
+
id: "svg-set-javascript",
|
|
2775
|
+
description: '<set to="javascript:..." \u2014 sets an attribute to a javascript: URI',
|
|
2776
|
+
pattern: /<set[\s\S]{0,80}to\s*=\s*["']?\s*javascript\s*:/i
|
|
2777
|
+
},
|
|
2778
|
+
{
|
|
2779
|
+
id: "svg-event-handler",
|
|
2780
|
+
description: "SVG-specific event handler attributes: onload=, onerror=, onactivate=, etc.",
|
|
2781
|
+
pattern: /\bon(?:load|error|activate|begin|end|repeat|focus|blur|click|mouse\w{1,20}|key\w{1,20})\s*=/i
|
|
2782
|
+
},
|
|
2783
|
+
{
|
|
2784
|
+
id: "svg-handler-generic",
|
|
2785
|
+
description: "Generic on* handler catch-all for SVG attributes",
|
|
2786
|
+
pattern: /\bon\w{1,30}\s*=/i
|
|
2787
|
+
},
|
|
2788
|
+
{
|
|
2789
|
+
id: "svg-filter-feimage",
|
|
2790
|
+
description: "<feImage href= \u2014 filter primitive that can load external resources",
|
|
2791
|
+
pattern: /<feImage[\s\S]{0,80}(?:xlink\s*:\s*)?href\s*=/i
|
|
2792
|
+
},
|
|
2793
|
+
{
|
|
2794
|
+
id: "svg-image-external",
|
|
2795
|
+
description: "<image xlink:href with http/https or javascript protocol",
|
|
2796
|
+
pattern: /<image[\s\S]{0,80}(?:xlink\s*:\s*)?href\s*=\s*["']?\s*(?:https?|javascript)\s*:/i
|
|
2797
|
+
},
|
|
2798
|
+
{
|
|
2799
|
+
id: "svg-style-javascript",
|
|
2800
|
+
description: "style= attribute containing javascript: (e.g. background:url(javascript:...))",
|
|
2801
|
+
pattern: /style\s*=[\s\S]{0,60}javascript\s*:/i
|
|
2802
|
+
}
|
|
2803
|
+
];
|
|
2804
|
+
var svg_default = SVG_PATTERNS;
|
|
2805
|
+
|
|
2806
|
+
// ../../node_modules/is-unsafe/src/contexts/sql.js
|
|
2807
|
+
var SQL_PATTERNS = [
|
|
2808
|
+
{
|
|
2809
|
+
id: "sql-block-comment-open",
|
|
2810
|
+
description: "SQL block comment open: /* ... */ \u2014 unusual in legitimate user text",
|
|
2811
|
+
pattern: /\/\*/
|
|
2812
|
+
},
|
|
2813
|
+
{
|
|
2814
|
+
id: "sql-union-select",
|
|
2815
|
+
description: "UNION SELECT \u2014 most common SQL injection aggregation attack",
|
|
2816
|
+
pattern: /\bUNION\s{1,20}(?:ALL\s{1,20})?SELECT\b/i
|
|
2817
|
+
},
|
|
2818
|
+
{
|
|
2819
|
+
id: "sql-drop-table",
|
|
2820
|
+
description: "DROP TABLE \u2014 destructive DDL injection",
|
|
2821
|
+
pattern: /\bDROP\s{1,20}TABLE\b/i
|
|
2822
|
+
},
|
|
2823
|
+
{
|
|
2824
|
+
id: "sql-drop-database",
|
|
2825
|
+
description: "DROP DATABASE \u2014 destructive DDL injection",
|
|
2826
|
+
pattern: /\bDROP\s{1,20}DATABASE\b/i
|
|
2827
|
+
},
|
|
2828
|
+
{
|
|
2829
|
+
id: "sql-insert-into",
|
|
2830
|
+
description: "INSERT INTO \u2014 data injection",
|
|
2831
|
+
pattern: /\bINSERT\s{1,20}INTO\b/i
|
|
2832
|
+
},
|
|
2833
|
+
{
|
|
2834
|
+
id: "sql-delete-from",
|
|
2835
|
+
description: "DELETE FROM \u2014 data deletion injection",
|
|
2836
|
+
pattern: /\bDELETE\s{1,20}FROM\b/i
|
|
2837
|
+
},
|
|
2838
|
+
{
|
|
2839
|
+
id: "sql-update-set",
|
|
2840
|
+
description: "UPDATE ... SET \u2014 data modification injection",
|
|
2841
|
+
// Allows arbitrary content between UPDATE and SET (table name, alias, etc.)
|
|
2842
|
+
pattern: /\bUPDATE\b[\s\S]{1,60}\bSET\b/i
|
|
2843
|
+
},
|
|
2844
|
+
{
|
|
2845
|
+
id: "sql-exec-xp",
|
|
2846
|
+
description: "EXEC xp_ \u2014 MSSQL extended stored procedure execution",
|
|
2847
|
+
pattern: /\bEXEC(?:UTE)?\s{1,20}xp_/i
|
|
2848
|
+
},
|
|
2849
|
+
{
|
|
2850
|
+
id: "sql-tautology-string",
|
|
2851
|
+
description: `Classic string tautology: ' OR '1'='1 or " OR "1"="1"`,
|
|
2852
|
+
// Last quote is optional — injection may truncate it: ' OR '1'='1--
|
|
2853
|
+
pattern: /'\s{0,10}OR\s{0,10}'[^']{0,20}'\s*=\s*'[^']{0,20}/i
|
|
2854
|
+
},
|
|
2855
|
+
{
|
|
2856
|
+
id: "sql-tautology-numeric",
|
|
2857
|
+
description: "Numeric tautology: OR 1=1",
|
|
2858
|
+
pattern: /\bOR\s{1,10}1\s*=\s*1\b/i
|
|
2859
|
+
},
|
|
2860
|
+
{
|
|
2861
|
+
id: "sql-always-true-zero",
|
|
2862
|
+
description: "Numeric tautology: OR 0=0",
|
|
2863
|
+
pattern: /\bOR\s{1,10}0\s*=\s*0\b/i
|
|
2864
|
+
},
|
|
2865
|
+
{
|
|
2866
|
+
id: "sql-sleep-benchmark",
|
|
2867
|
+
description: "Time-based blind injection: SLEEP() or BENCHMARK()",
|
|
2868
|
+
pattern: /\b(?:SLEEP|BENCHMARK)\s*\(/i
|
|
2869
|
+
},
|
|
2870
|
+
{
|
|
2871
|
+
id: "sql-waitfor-delay",
|
|
2872
|
+
description: "MSSQL time-based blind injection: WAITFOR DELAY",
|
|
2873
|
+
pattern: /\bWAITFOR\s{1,20}DELAY\b/i
|
|
2874
|
+
},
|
|
2875
|
+
{
|
|
2876
|
+
id: "sql-char-function",
|
|
2877
|
+
description: "CHAR() function \u2014 used to obfuscate injected strings",
|
|
2878
|
+
pattern: /\bCHAR\s*\(\s*\d{1,3}/i
|
|
2879
|
+
},
|
|
2880
|
+
{
|
|
2881
|
+
id: "sql-information-schema",
|
|
2882
|
+
description: "INFORMATION_SCHEMA \u2014 reconnaissance query for table/column enumeration",
|
|
2883
|
+
pattern: /\bINFORMATION_SCHEMA\b/i
|
|
2884
|
+
}
|
|
2885
|
+
];
|
|
2886
|
+
var sql_default = SQL_PATTERNS;
|
|
2887
|
+
|
|
2888
|
+
// ../../node_modules/is-unsafe/src/contexts/shell.js
|
|
2889
|
+
var SHELL_PATTERNS = [
|
|
2890
|
+
{
|
|
2891
|
+
id: "shell-path-traversal-unix",
|
|
2892
|
+
description: "Unix path traversal: ../ \u2014 climbing the directory tree",
|
|
2893
|
+
pattern: /\.\.\//
|
|
2894
|
+
},
|
|
2895
|
+
{
|
|
2896
|
+
id: "shell-path-traversal-windows",
|
|
2897
|
+
description: "Windows path traversal: ..\\ \u2014 climbing the directory tree",
|
|
2898
|
+
pattern: /\.\.\\/
|
|
2899
|
+
},
|
|
2900
|
+
{
|
|
2901
|
+
id: "shell-path-traversal-encoded",
|
|
2902
|
+
description: "URL-encoded path traversal: %2e%2e or %2f variants",
|
|
2903
|
+
pattern: /%2e%2e|%2f\.\.|\.\.%2f/i
|
|
2904
|
+
},
|
|
2905
|
+
{
|
|
2906
|
+
id: "shell-null-byte",
|
|
2907
|
+
description: "Null byte injection: \\x00 or %00 \u2014 truncates strings in C-backed functions",
|
|
2908
|
+
pattern: /\x00|%00/
|
|
2909
|
+
},
|
|
2910
|
+
{
|
|
2911
|
+
id: "shell-semicolon",
|
|
2912
|
+
description: "Semicolon command separator: cmd1; cmd2",
|
|
2913
|
+
pattern: /;/
|
|
2914
|
+
},
|
|
2915
|
+
{
|
|
2916
|
+
id: "shell-pipe",
|
|
2917
|
+
description: "Pipe operator: cmd1 | cmd2",
|
|
2918
|
+
pattern: /\|/
|
|
2919
|
+
},
|
|
2920
|
+
{
|
|
2921
|
+
id: "shell-and-operator",
|
|
2922
|
+
description: "AND operator: cmd1 && cmd2",
|
|
2923
|
+
pattern: /&&/
|
|
2924
|
+
},
|
|
2925
|
+
{
|
|
2926
|
+
id: "shell-or-operator",
|
|
2927
|
+
description: "OR operator: cmd1 || cmd2",
|
|
2928
|
+
pattern: /\|\|/
|
|
2929
|
+
},
|
|
2930
|
+
{
|
|
2931
|
+
id: "shell-backtick",
|
|
2932
|
+
description: "Backtick command substitution: `cmd`",
|
|
2933
|
+
pattern: /`/
|
|
2934
|
+
},
|
|
2935
|
+
{
|
|
2936
|
+
id: "shell-dollar-paren",
|
|
2937
|
+
description: "Dollar-paren command substitution: $(cmd)",
|
|
2938
|
+
pattern: /\$\(/
|
|
2939
|
+
},
|
|
2940
|
+
{
|
|
2941
|
+
id: "shell-dollar-brace",
|
|
2942
|
+
description: "Dollar-brace variable expansion: ${var} \u2014 can be abused for injection",
|
|
2943
|
+
pattern: /\$\{/
|
|
2944
|
+
},
|
|
2945
|
+
{
|
|
2946
|
+
id: "shell-redirect-out",
|
|
2947
|
+
description: "Output redirection: cmd > file or cmd >> file",
|
|
2948
|
+
pattern: />{1,2}/
|
|
2949
|
+
},
|
|
2950
|
+
{
|
|
2951
|
+
id: "shell-redirect-in",
|
|
2952
|
+
description: "Input redirection: cmd < file",
|
|
2953
|
+
pattern: /</
|
|
2954
|
+
},
|
|
2955
|
+
{
|
|
2956
|
+
id: "shell-newline-injection",
|
|
2957
|
+
description: "Newline injection: \\n or \\r \u2014 can inject new shell commands",
|
|
2958
|
+
pattern: /[\n\r]/
|
|
2959
|
+
},
|
|
2960
|
+
{
|
|
2961
|
+
id: "shell-glob-star",
|
|
2962
|
+
description: "Glob expansion: * or ? \u2014 can expand to unintended files",
|
|
2963
|
+
// Only flag when combined with path separators to reduce false positives
|
|
2964
|
+
pattern: /[/\\][*?]/
|
|
2965
|
+
},
|
|
2966
|
+
{
|
|
2967
|
+
id: "shell-absolute-root",
|
|
2968
|
+
description: "Absolute root path injection: string starting with / or \\ (Windows UNC)",
|
|
2969
|
+
pattern: /^(?:\/|\\\\)/
|
|
2970
|
+
},
|
|
2971
|
+
{
|
|
2972
|
+
id: "shell-windows-drive",
|
|
2973
|
+
description: "Windows drive letter path injection: C:\\ or D:/",
|
|
2974
|
+
pattern: /^[a-zA-Z]:[/\\]/
|
|
2975
|
+
},
|
|
2976
|
+
{
|
|
2977
|
+
id: "shell-curl-wget",
|
|
2978
|
+
description: "curl/wget with URL or flags \u2014 can exfiltrate data or download payloads",
|
|
2979
|
+
// Require a URL scheme (http/https/ftp) or a flag (-) to reduce false positives
|
|
2980
|
+
// "curl is a tool" won't match; "curl http://..." or "curl -s ..." will
|
|
2981
|
+
pattern: /\b(?:curl|wget)\s+(?:https?:\/\/|ftp:\/\/|-)/i
|
|
2982
|
+
}
|
|
2983
|
+
];
|
|
2984
|
+
var shell_default = SHELL_PATTERNS;
|
|
2985
|
+
|
|
2986
|
+
// ../../node_modules/is-unsafe/src/contexts/redos.js
|
|
2987
|
+
var REDOS_PATTERNS = [
|
|
2988
|
+
{
|
|
2989
|
+
id: "redos-nested-quantifier-plus",
|
|
2990
|
+
description: "Nested + quantifier inside a group with outer quantifier: (a+)+, (.+b)*, etc.",
|
|
2991
|
+
// Matches any group containing a + quantifier, with an outer * or + — catches (a+)+, (.+b)*, etc.
|
|
2992
|
+
pattern: /\([^)]*\+[^)]*\)[+*]/
|
|
2993
|
+
},
|
|
2994
|
+
{
|
|
2995
|
+
id: "redos-nested-quantifier-star",
|
|
2996
|
+
description: "Nested * quantifier: (a*)* or (a*)+ \u2014 catastrophic backtracking",
|
|
2997
|
+
pattern: /\([^)]*\*[^)]*\)[*+]/
|
|
2998
|
+
},
|
|
2999
|
+
{
|
|
3000
|
+
id: "redos-nested-groups",
|
|
3001
|
+
description: "Doubly nested quantified groups: ((a+)+) \u2014 guaranteed catastrophic",
|
|
3002
|
+
pattern: /\(\([^)]{0,40}\)[+*]\)[+*]/
|
|
3003
|
+
},
|
|
3004
|
+
{
|
|
3005
|
+
id: "redos-alternation-overlap",
|
|
3006
|
+
description: "Overlapping alternation under quantifier: (a|a)+ \u2014 ambiguous NFA paths",
|
|
3007
|
+
// Detect repeated identical alternatives under a quantifier
|
|
3008
|
+
pattern: /\(([^|()]{1,20})\|(?:\1)(?:\|[^|()]{1,20}){0,5}\)[+*?]{1,2}/
|
|
3009
|
+
},
|
|
3010
|
+
{
|
|
3011
|
+
id: "redos-star-plus-concat",
|
|
3012
|
+
description: "(x*x)+ pattern \u2014 triggers super-linear backtracking",
|
|
3013
|
+
pattern: /\([^)]{0,10}\*[^)]{0,10}\)[+*]/
|
|
3014
|
+
},
|
|
3015
|
+
{
|
|
3016
|
+
id: "redos-dot-star-greedy",
|
|
3017
|
+
description: "(.*){n,} or (.+){n,} \u2014 repeated greedy dot quantifiers",
|
|
3018
|
+
pattern: /\(\.[*+]\)\{?\d/
|
|
3019
|
+
},
|
|
3020
|
+
{
|
|
3021
|
+
id: "redos-large-repetition",
|
|
3022
|
+
description: "Very large fixed or range repetition count {1000,} or {1000,n} \u2014 denial of service via backtracking",
|
|
3023
|
+
// Matches { followed by 4+ digits (≥1000), then optional ,digits }
|
|
3024
|
+
pattern: /\{\d{4,}(?:,\d*)?\}/
|
|
3025
|
+
},
|
|
3026
|
+
{
|
|
3027
|
+
id: "redos-catastrophic-alternation",
|
|
3028
|
+
description: "Long alternation with many similar branches \u2014 polynomial backtracking risk",
|
|
3029
|
+
// Heuristic: 10+ pipe-separated alternatives in a single group
|
|
3030
|
+
pattern: /\([^)]{0,200}(?:\|[^|)]{0,50}){9,}\)/
|
|
3031
|
+
}
|
|
3032
|
+
];
|
|
3033
|
+
var redos_default = REDOS_PATTERNS;
|
|
3034
|
+
|
|
3035
|
+
// ../../node_modules/is-unsafe/src/contexts/nosql.js
|
|
3036
|
+
var sep = `["'\\s]*:`;
|
|
3037
|
+
var NOSQL_PATTERNS = [
|
|
3038
|
+
// ─── MongoDB $ operator injection ────────────────────────────────────────
|
|
3039
|
+
{
|
|
3040
|
+
id: "nosql-where-operator",
|
|
3041
|
+
description: "$where \u2014 executes arbitrary JavaScript server-side in MongoDB",
|
|
3042
|
+
pattern: new RegExp(`\\$where${sep}`, "i")
|
|
3043
|
+
},
|
|
3044
|
+
{
|
|
3045
|
+
id: "nosql-ne-operator",
|
|
3046
|
+
description: '$ne \u2014 "not equal" operator used to bypass equality checks',
|
|
3047
|
+
pattern: new RegExp(`\\$ne${sep}`, "i")
|
|
3048
|
+
},
|
|
3049
|
+
{
|
|
3050
|
+
id: "nosql-gt-operator",
|
|
3051
|
+
description: '$gt \u2014 "greater than" used to bypass password/value checks',
|
|
3052
|
+
pattern: new RegExp(`\\$gte?${sep}`, "i")
|
|
3053
|
+
},
|
|
3054
|
+
{
|
|
3055
|
+
id: "nosql-lt-operator",
|
|
3056
|
+
description: '$lt / $lte \u2014 "less than" bypass variants',
|
|
3057
|
+
pattern: new RegExp(`\\$lte?${sep}`, "i")
|
|
3058
|
+
},
|
|
3059
|
+
{
|
|
3060
|
+
id: "nosql-regex-operator",
|
|
3061
|
+
description: "$regex \u2014 can be used to extract data character by character (blind injection)",
|
|
3062
|
+
pattern: new RegExp(`\\$regex${sep}`, "i")
|
|
3063
|
+
},
|
|
3064
|
+
{
|
|
3065
|
+
id: "nosql-or-operator",
|
|
3066
|
+
description: "$or \u2014 logical OR; used to create always-true conditions",
|
|
3067
|
+
pattern: new RegExp(`\\$or${sep}\\s*\\[`, "i")
|
|
3068
|
+
},
|
|
3069
|
+
{
|
|
3070
|
+
id: "nosql-and-operator",
|
|
3071
|
+
description: "$and \u2014 logical AND operator injection",
|
|
3072
|
+
pattern: new RegExp(`\\$and${sep}\\s*\\[`, "i")
|
|
3073
|
+
},
|
|
3074
|
+
{
|
|
3075
|
+
id: "nosql-nor-operator",
|
|
3076
|
+
description: "$nor \u2014 logical NOR operator injection",
|
|
3077
|
+
pattern: new RegExp(`\\$nor${sep}\\s*\\[`, "i")
|
|
3078
|
+
},
|
|
3079
|
+
{
|
|
3080
|
+
id: "nosql-exists-operator",
|
|
3081
|
+
description: "$exists \u2014 can enumerate fields to determine schema",
|
|
3082
|
+
pattern: new RegExp(`\\$exists${sep}`, "i")
|
|
3083
|
+
},
|
|
3084
|
+
{
|
|
3085
|
+
id: "nosql-in-operator",
|
|
3086
|
+
description: "$in \u2014 matches any value in a list; can enumerate values",
|
|
3087
|
+
pattern: new RegExp(`\\$in${sep}\\s*\\[`, "i")
|
|
3088
|
+
},
|
|
3089
|
+
{
|
|
3090
|
+
id: "nosql-expr-operator",
|
|
3091
|
+
description: "$expr \u2014 allows aggregation expressions in queries (MongoDB 3.6+)",
|
|
3092
|
+
pattern: new RegExp(`\\$expr${sep}`, "i")
|
|
3093
|
+
},
|
|
3094
|
+
{
|
|
3095
|
+
id: "nosql-function-operator",
|
|
3096
|
+
description: "$function \u2014 executes arbitrary JavaScript in MongoDB 4.4+",
|
|
3097
|
+
pattern: new RegExp(`\\$function${sep}`, "i")
|
|
3098
|
+
},
|
|
3099
|
+
{
|
|
3100
|
+
id: "nosql-accumulator-operator",
|
|
3101
|
+
description: "$accumulator \u2014 custom aggregation with arbitrary JS execution",
|
|
3102
|
+
pattern: new RegExp(`\\$accumulator${sep}`, "i")
|
|
3103
|
+
},
|
|
3104
|
+
// ─── Prototype pollution ─────────────────────────────────────────────────
|
|
3105
|
+
{
|
|
3106
|
+
id: "nosql-proto-pollution",
|
|
3107
|
+
description: "__proto__ \u2014 prototype pollution via object key injection",
|
|
3108
|
+
pattern: /__proto__/
|
|
3109
|
+
},
|
|
3110
|
+
{
|
|
3111
|
+
id: "nosql-constructor-prototype",
|
|
3112
|
+
description: "constructor.prototype \u2014 alternative prototype pollution vector (dot notation or JSON key)",
|
|
3113
|
+
// Matches dot-notation (obj.constructor.prototype) and JSON key adjacency
|
|
3114
|
+
// ("constructor": {"prototype": ...})
|
|
3115
|
+
pattern: /constructor[\s"':.,{\[]*prototype/i
|
|
3116
|
+
},
|
|
3117
|
+
{
|
|
3118
|
+
id: "nosql-proto-bracket",
|
|
3119
|
+
description: '["__proto__"] \u2014 bracket-notation prototype pollution',
|
|
3120
|
+
pattern: /\[["']__proto__["']\]/
|
|
3121
|
+
}
|
|
3122
|
+
];
|
|
3123
|
+
var nosql_default = NOSQL_PATTERNS;
|
|
3124
|
+
|
|
3125
|
+
// ../../node_modules/is-unsafe/src/contexts/log.js
|
|
3126
|
+
var LOG_PATTERNS = [
|
|
3127
|
+
// ─── CRLF / newline injection ─────────────────────────────────────────────
|
|
3128
|
+
{
|
|
3129
|
+
id: "log-crlf-injection",
|
|
3130
|
+
description: "CRLF injection: literal \\r or \\n embeds fake log lines",
|
|
3131
|
+
pattern: /[\r\n]/
|
|
3132
|
+
},
|
|
3133
|
+
{
|
|
3134
|
+
id: "log-url-encoded-crlf",
|
|
3135
|
+
description: "URL-encoded CRLF: %0d, %0a, %0D, %0A \u2014 decoded by some log parsers",
|
|
3136
|
+
pattern: /%0[dDaA]/
|
|
3137
|
+
},
|
|
3138
|
+
{
|
|
3139
|
+
id: "log-unicode-newline",
|
|
3140
|
+
description: "Unicode newline variants: U+2028 (line separator), U+2029 (paragraph separator)",
|
|
3141
|
+
pattern: /[\u2028\u2029]/
|
|
3142
|
+
},
|
|
3143
|
+
// ─── Log4Shell / JNDI injection (CVE-2021-44228) ─────────────────────────
|
|
3144
|
+
{
|
|
3145
|
+
id: "log-log4shell-jndi",
|
|
3146
|
+
description: "Log4Shell: ${jndi:...} triggers remote code execution in Apache Log4j",
|
|
3147
|
+
pattern: /\$\{jndi\s*:/i
|
|
3148
|
+
},
|
|
3149
|
+
{
|
|
3150
|
+
id: "log-log4shell-obfuscated",
|
|
3151
|
+
description: "Obfuscated Log4Shell: ${::-j}... lookup-bypass prefix used to evade WAF detection",
|
|
3152
|
+
// ${::- is the Log4j lookup-bypass escape sequence; presence alone is suspicious
|
|
3153
|
+
pattern: /\$\{::-/
|
|
3154
|
+
},
|
|
3155
|
+
{
|
|
3156
|
+
id: "log-log4j-lookup",
|
|
3157
|
+
description: "Log4j lookup syntax: ${env:...}, ${sys:...}, ${ctx:...} \u2014 data exfiltration",
|
|
3158
|
+
pattern: /\$\{(?:env|sys|ctx|main|map|sd|web|docker|k8s|spring)\s*:/i
|
|
3159
|
+
},
|
|
3160
|
+
// ─── Server-Side Template Injection (SSTI) in log messages ───────────────
|
|
3161
|
+
{
|
|
3162
|
+
id: "log-ssti-double-brace",
|
|
3163
|
+
description: "SSTI double-brace: {{expression}} \u2014 Jinja2, Twig, Handlebars, etc.",
|
|
3164
|
+
pattern: /\{\{[\s\S]{0,80}\}\}/
|
|
3165
|
+
},
|
|
3166
|
+
{
|
|
3167
|
+
id: "log-ssti-hash-brace",
|
|
3168
|
+
description: "SSTI hash-brace: #{expression} \u2014 Thymeleaf, Velocity, Ruby ERB",
|
|
3169
|
+
pattern: /#\{[\s\S]{0,80}\}/
|
|
3170
|
+
},
|
|
3171
|
+
{
|
|
3172
|
+
id: "log-ssti-dollar-brace",
|
|
3173
|
+
description: "SSTI/EL injection: ${expression with operators or method calls} \u2014 JSP EL, Freemarker, SpEL",
|
|
3174
|
+
// Require that the ${...} content looks like an expression, not a plain variable name.
|
|
3175
|
+
// Flags if the content contains: . ( * + operators, or known SSTI keywords.
|
|
3176
|
+
// This avoids flagging ${PATH}, ${HOME} etc. (plain shell variables).
|
|
3177
|
+
pattern: /\$\{[^}]*(?:\.|\(|\*|\+|\bclass\b|\bruntime\b|\bprocess\b|\bexec\b)[^}]{0,80}\}/i
|
|
3178
|
+
},
|
|
3179
|
+
{
|
|
3180
|
+
id: "log-ssti-percent-tag",
|
|
3181
|
+
description: "SSTI ERB/ASP tag: <%= expression %> \u2014 Ruby ERB, ASP",
|
|
3182
|
+
pattern: /<%=[\s\S]{0,80}%>/
|
|
3183
|
+
},
|
|
3184
|
+
// ─── Null byte ────────────────────────────────────────────────────────────
|
|
3185
|
+
{
|
|
3186
|
+
id: "log-null-byte",
|
|
3187
|
+
description: "Null byte: \\x00 or %00 \u2014 can truncate log entries in C-backed loggers",
|
|
3188
|
+
pattern: /\x00|%00/
|
|
3189
|
+
},
|
|
3190
|
+
// ─── ANSI escape injection ────────────────────────────────────────────────
|
|
3191
|
+
{
|
|
3192
|
+
id: "log-ansi-escape",
|
|
3193
|
+
description: "ANSI escape sequence: ESC[ \u2014 can manipulate terminal output when logs are tailed",
|
|
3194
|
+
pattern: /\x1b\[/
|
|
3195
|
+
}
|
|
3196
|
+
];
|
|
3197
|
+
var log_default = LOG_PATTERNS;
|
|
3198
|
+
|
|
3199
|
+
// ../../node_modules/is-unsafe/src/contexts/sql-strict.js
|
|
3200
|
+
var SQL_STRICT_EXTRA = [
|
|
3201
|
+
{
|
|
3202
|
+
id: "sql-line-comment",
|
|
3203
|
+
description: "SQL line comment: -- followed by whitespace or end of string",
|
|
3204
|
+
pattern: /--(?:\s|$)/
|
|
3205
|
+
},
|
|
3206
|
+
{
|
|
3207
|
+
id: "sql-stacked-query",
|
|
3208
|
+
description: "Stacked queries: semicolon immediately followed by a SQL keyword",
|
|
3209
|
+
pattern: /;\s{0,10}(?:SELECT|INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|EXEC)\b/i
|
|
3210
|
+
},
|
|
3211
|
+
{
|
|
3212
|
+
id: "sql-hex-encoding",
|
|
3213
|
+
description: "Hex-encoded string injection: 0x41414141 style (MySQL)",
|
|
3214
|
+
pattern: /\b0x[0-9a-f]{4,}/i
|
|
3215
|
+
}
|
|
3216
|
+
];
|
|
3217
|
+
var SQL_STRICT_PATTERNS = [...sql_default, ...SQL_STRICT_EXTRA];
|
|
3218
|
+
var sql_strict_default = SQL_STRICT_PATTERNS;
|
|
3219
|
+
|
|
3220
|
+
// ../../node_modules/is-unsafe/src/index.js
|
|
3221
|
+
html_default.label = "HTML";
|
|
3222
|
+
xml_default.label = "XML";
|
|
3223
|
+
svg_default.label = "SVG";
|
|
3224
|
+
sql_default.label = "SQL";
|
|
3225
|
+
sql_strict_default.label = "SQL-STRICT";
|
|
3226
|
+
shell_default.label = "SHELL";
|
|
3227
|
+
redos_default.label = "REDOS";
|
|
3228
|
+
nosql_default.label = "NOSQL";
|
|
3229
|
+
log_default.label = "LOG";
|
|
3230
|
+
var VALID_CONTEXTS = Object.freeze({
|
|
3231
|
+
HTML: html_default,
|
|
3232
|
+
XML: xml_default,
|
|
3233
|
+
SVG: svg_default,
|
|
3234
|
+
SQL: sql_default,
|
|
3235
|
+
"SQL-STRICT": sql_strict_default,
|
|
3236
|
+
SHELL: shell_default,
|
|
3237
|
+
REDOS: redos_default,
|
|
3238
|
+
NOSQL: nosql_default,
|
|
3239
|
+
LOG: log_default
|
|
3240
|
+
});
|
|
3241
|
+
function assertString(value) {
|
|
3242
|
+
if (typeof value !== "string") {
|
|
3243
|
+
throw new TypeError(
|
|
3244
|
+
`is-unsafe: first argument must be a string, got ${typeof value}`
|
|
3245
|
+
);
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
function assertContext(context) {
|
|
3249
|
+
if (context instanceof RegExp) return;
|
|
3250
|
+
if (Array.isArray(context)) {
|
|
3251
|
+
if (context.length === 0) {
|
|
3252
|
+
throw new TypeError("is-unsafe: context must not be an empty array");
|
|
3253
|
+
}
|
|
3254
|
+
if (Array.isArray(context[0])) {
|
|
3255
|
+
for (const list of context) {
|
|
3256
|
+
if (!Array.isArray(list) || list.length === 0) {
|
|
3257
|
+
throw new TypeError(
|
|
3258
|
+
"is-unsafe: each context in the array must be a non-empty pattern array (PatternList)"
|
|
3259
|
+
);
|
|
3260
|
+
}
|
|
3261
|
+
}
|
|
3262
|
+
}
|
|
3263
|
+
return;
|
|
3264
|
+
}
|
|
3265
|
+
throw new TypeError(
|
|
3266
|
+
`is-unsafe: second argument must be a PatternList (e.g. HTML), an array of PatternLists (e.g. [HTML, XML]), or a RegExp. Got: ${typeof context}`
|
|
3267
|
+
);
|
|
3268
|
+
}
|
|
3269
|
+
function normalise(context) {
|
|
3270
|
+
if (context instanceof RegExp) return { lists: null, regex: context };
|
|
3271
|
+
if (Array.isArray(context[0])) return { lists: context, regex: null };
|
|
3272
|
+
return { lists: [context], regex: null };
|
|
3273
|
+
}
|
|
3274
|
+
function matchList(value, list) {
|
|
3275
|
+
const label = list.label ?? "CUSTOM";
|
|
3276
|
+
for (const rule of list) {
|
|
3277
|
+
if (rule.pattern.test(value)) {
|
|
3278
|
+
return { context: label, id: rule.id, description: rule.description, pattern: rule.pattern };
|
|
3279
|
+
}
|
|
3280
|
+
}
|
|
3281
|
+
return null;
|
|
3282
|
+
}
|
|
3283
|
+
function isUnsafe(value, context) {
|
|
3284
|
+
assertString(value);
|
|
3285
|
+
assertContext(context);
|
|
3286
|
+
const { lists, regex } = normalise(context);
|
|
3287
|
+
if (regex) return regex.test(value);
|
|
3288
|
+
for (const list of lists) {
|
|
3289
|
+
if (matchList(value, list) !== null) return true;
|
|
3290
|
+
}
|
|
3291
|
+
return false;
|
|
3292
|
+
}
|
|
3293
|
+
|
|
3294
|
+
// ../../node_modules/fast-xml-parser/src/xmlparser/OrderedObjParser.js
|
|
3295
|
+
function extractRawAttributes(prefixedAttrs, options) {
|
|
3296
|
+
if (!prefixedAttrs) return {};
|
|
3297
|
+
const attrs = options.attributesGroupName ? prefixedAttrs[options.attributesGroupName] : prefixedAttrs;
|
|
3298
|
+
if (!attrs) return {};
|
|
3299
|
+
const rawAttrs = {};
|
|
3300
|
+
for (const key in attrs) {
|
|
3301
|
+
if (key.startsWith(options.attributeNamePrefix)) {
|
|
3302
|
+
const rawName = key.substring(options.attributeNamePrefix.length);
|
|
3303
|
+
rawAttrs[rawName] = attrs[key];
|
|
3304
|
+
} else {
|
|
3305
|
+
rawAttrs[key] = attrs[key];
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
return rawAttrs;
|
|
3309
|
+
}
|
|
3310
|
+
function extractNamespace(rawTagName) {
|
|
3311
|
+
if (!rawTagName || typeof rawTagName !== "string") return void 0;
|
|
3312
|
+
const colonIndex = rawTagName.indexOf(":");
|
|
3313
|
+
if (colonIndex !== -1 && colonIndex > 0) {
|
|
3314
|
+
const ns = rawTagName.substring(0, colonIndex);
|
|
3315
|
+
if (ns !== "xmlns") {
|
|
3316
|
+
return ns;
|
|
3317
|
+
}
|
|
3318
|
+
}
|
|
3319
|
+
return void 0;
|
|
3320
|
+
}
|
|
3321
|
+
var OrderedObjParser = class {
|
|
3322
|
+
constructor(options, externalEntities) {
|
|
3323
|
+
this.options = options;
|
|
3324
|
+
this.currentNode = null;
|
|
3325
|
+
this.tagsNodeStack = [];
|
|
3326
|
+
this.parseXml = parseXml;
|
|
3327
|
+
this.parseTextData = parseTextData;
|
|
3328
|
+
this.resolveNameSpace = resolveNameSpace;
|
|
3329
|
+
this.buildAttributesMap = buildAttributesMap;
|
|
3330
|
+
this.isItStopNode = isItStopNode;
|
|
3331
|
+
this.replaceEntitiesValue = replaceEntitiesValue;
|
|
3332
|
+
this.readStopNodeData = readStopNodeData;
|
|
3333
|
+
this.saveTextToParentTag = saveTextToParentTag;
|
|
3334
|
+
this.addChild = addChild;
|
|
3335
|
+
this.ignoreAttributesFn = getIgnoreAttributesFn(this.options.ignoreAttributes);
|
|
3336
|
+
this.entityExpansionCount = 0;
|
|
3337
|
+
this.currentExpandedLength = 0;
|
|
3338
|
+
this.doctypefound = false;
|
|
3339
|
+
let namedEntities = { ...XML };
|
|
3340
|
+
if (this.options.entityDecoder) {
|
|
3341
|
+
this.entityDecoder = this.options.entityDecoder;
|
|
3342
|
+
} else {
|
|
3343
|
+
if (typeof this.options.htmlEntities === "object") namedEntities = this.options.htmlEntities;
|
|
3344
|
+
else if (this.options.htmlEntities === true) namedEntities = { ...COMMON_HTML, ...CURRENCY };
|
|
3345
|
+
this.entityDecoder = new EntityDecoder({
|
|
3346
|
+
namedEntities: { ...namedEntities, ...externalEntities },
|
|
3347
|
+
numericAllowed: this.options.htmlEntities,
|
|
3348
|
+
limit: {
|
|
3349
|
+
maxTotalExpansions: this.options.processEntities.maxTotalExpansions,
|
|
3350
|
+
maxExpandedLength: this.options.processEntities.maxExpandedLength,
|
|
3351
|
+
applyLimitsTo: this.options.processEntities.appliesTo
|
|
3352
|
+
},
|
|
3353
|
+
// onExternalEntity: (name, value) => isUnsafe(value) ? 'block' : 'allow',
|
|
3354
|
+
onInputEntity: (name, value) => (
|
|
3355
|
+
//TODO: VALID_CONTEXTS.HTML should be set only if this.options.htmlEntities
|
|
3356
|
+
isUnsafe(value, [html_default, xml_default]) ? ENTITY_ACTION.BLOCK : ENTITY_ACTION.ALLOW
|
|
3357
|
+
)
|
|
3358
|
+
//postCheck: resolved => resolved
|
|
3359
|
+
});
|
|
3360
|
+
}
|
|
3361
|
+
this.matcher = new Matcher();
|
|
3362
|
+
this.readonlyMatcher = this.matcher.readOnly();
|
|
3363
|
+
this.isCurrentNodeStopNode = false;
|
|
3364
|
+
this.stopNodeExpressionsSet = new ExpressionSet();
|
|
3365
|
+
const stopNodesOpts = this.options.stopNodes;
|
|
3366
|
+
if (stopNodesOpts && stopNodesOpts.length > 0) {
|
|
3367
|
+
for (let i = 0; i < stopNodesOpts.length; i++) {
|
|
3368
|
+
const stopNodeExp = stopNodesOpts[i];
|
|
3369
|
+
if (typeof stopNodeExp === "string") {
|
|
3370
|
+
this.stopNodeExpressionsSet.add(new Expression(stopNodeExp));
|
|
3371
|
+
} else if (stopNodeExp instanceof Expression) {
|
|
3372
|
+
this.stopNodeExpressionsSet.add(stopNodeExp);
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
this.stopNodeExpressionsSet.seal();
|
|
3376
|
+
}
|
|
3377
|
+
}
|
|
3378
|
+
};
|
|
3379
|
+
function parseTextData(val, tagName, jPath, dontTrim, hasAttributes, isLeafNode, escapeEntities) {
|
|
3380
|
+
const options = this.options;
|
|
3381
|
+
if (val !== void 0) {
|
|
3382
|
+
if (options.trimValues && !dontTrim) {
|
|
3383
|
+
val = val.trim();
|
|
3384
|
+
}
|
|
3385
|
+
if (val.length > 0) {
|
|
3386
|
+
if (!escapeEntities) val = this.replaceEntitiesValue(val, tagName, jPath);
|
|
3387
|
+
const jPathOrMatcher = options.jPath ? jPath.toString() : jPath;
|
|
3388
|
+
const newval = options.tagValueProcessor(tagName, val, jPathOrMatcher, hasAttributes, isLeafNode);
|
|
3389
|
+
if (newval === null || newval === void 0) {
|
|
3390
|
+
return val;
|
|
3391
|
+
} else if (typeof newval !== typeof val || newval !== val) {
|
|
3392
|
+
return newval;
|
|
3393
|
+
} else if (options.trimValues) {
|
|
3394
|
+
return parseValue(val, options.parseTagValue, options.numberParseOptions);
|
|
3395
|
+
} else {
|
|
3396
|
+
const trimmedVal = val.trim();
|
|
3397
|
+
if (trimmedVal === val) {
|
|
3398
|
+
return parseValue(val, options.parseTagValue, options.numberParseOptions);
|
|
3399
|
+
} else {
|
|
3400
|
+
return val;
|
|
3401
|
+
}
|
|
3402
|
+
}
|
|
3403
|
+
}
|
|
3404
|
+
}
|
|
3405
|
+
}
|
|
3406
|
+
function resolveNameSpace(tagname) {
|
|
3407
|
+
if (this.options.removeNSPrefix) {
|
|
3408
|
+
const tags = tagname.split(":");
|
|
3409
|
+
const prefix = tagname.charAt(0) === "/" ? "/" : "";
|
|
3410
|
+
if (tags[0] === "xmlns") {
|
|
3411
|
+
return "";
|
|
3412
|
+
}
|
|
3413
|
+
if (tags.length === 2) {
|
|
3414
|
+
tagname = prefix + tags[1];
|
|
3415
|
+
}
|
|
3416
|
+
}
|
|
3417
|
+
return tagname;
|
|
3418
|
+
}
|
|
3419
|
+
var attrsRegx = new RegExp(`([^\\s=]+)\\s*(=\\s*(['"])([\\s\\S]*?)\\3)?`, "gm");
|
|
3420
|
+
function buildAttributesMap(attrStr, jPath, tagName, force = false) {
|
|
3421
|
+
const options = this.options;
|
|
3422
|
+
if (force === true || options.ignoreAttributes !== true && typeof attrStr === "string") {
|
|
3423
|
+
const matches = getAllMatches(attrStr, attrsRegx);
|
|
3424
|
+
const len = matches.length;
|
|
3425
|
+
const attrs = {};
|
|
3426
|
+
const processedVals = new Array(len);
|
|
3427
|
+
let hasRawAttrs = false;
|
|
3428
|
+
const rawAttrsForMatcher = {};
|
|
3429
|
+
for (let i = 0; i < len; i++) {
|
|
3430
|
+
const attrName = this.resolveNameSpace(matches[i][1]);
|
|
3431
|
+
const oldVal = matches[i][4];
|
|
3432
|
+
if (attrName.length && oldVal !== void 0) {
|
|
3433
|
+
let val = oldVal;
|
|
3434
|
+
if (options.trimValues) val = val.trim();
|
|
3435
|
+
val = this.replaceEntitiesValue(val, tagName, this.readonlyMatcher);
|
|
3436
|
+
processedVals[i] = val;
|
|
3437
|
+
rawAttrsForMatcher[attrName] = val;
|
|
3438
|
+
hasRawAttrs = true;
|
|
3439
|
+
}
|
|
3440
|
+
}
|
|
3441
|
+
if (hasRawAttrs && typeof jPath === "object" && jPath.updateCurrent) {
|
|
3442
|
+
jPath.updateCurrent(rawAttrsForMatcher);
|
|
3443
|
+
}
|
|
3444
|
+
const jPathStr = options.jPath ? jPath.toString() : this.readonlyMatcher;
|
|
3445
|
+
let hasAttrs = false;
|
|
3446
|
+
for (let i = 0; i < len; i++) {
|
|
3447
|
+
const attrName = this.resolveNameSpace(matches[i][1]);
|
|
3448
|
+
if (this.ignoreAttributesFn(attrName, jPathStr)) continue;
|
|
3449
|
+
let aName = options.attributeNamePrefix + attrName;
|
|
3450
|
+
if (attrName.length) {
|
|
3451
|
+
if (options.transformAttributeName) {
|
|
3452
|
+
aName = options.transformAttributeName(aName);
|
|
3453
|
+
}
|
|
3454
|
+
aName = sanitizeName(aName, options);
|
|
3455
|
+
if (matches[i][4] !== void 0) {
|
|
3456
|
+
const oldVal = processedVals[i];
|
|
3457
|
+
const newVal = options.attributeValueProcessor(attrName, oldVal, jPathStr);
|
|
3458
|
+
if (newVal === null || newVal === void 0) {
|
|
3459
|
+
attrs[aName] = oldVal;
|
|
3460
|
+
} else if (typeof newVal !== typeof oldVal || newVal !== oldVal) {
|
|
3461
|
+
attrs[aName] = newVal;
|
|
3462
|
+
} else {
|
|
3463
|
+
attrs[aName] = parseValue(oldVal, options.parseAttributeValue, options.numberParseOptions);
|
|
3464
|
+
}
|
|
3465
|
+
hasAttrs = true;
|
|
3466
|
+
} else if (options.allowBooleanAttributes) {
|
|
3467
|
+
attrs[aName] = true;
|
|
3468
|
+
hasAttrs = true;
|
|
3469
|
+
}
|
|
3470
|
+
}
|
|
3471
|
+
}
|
|
3472
|
+
if (!hasAttrs) return;
|
|
3473
|
+
if (options.attributesGroupName && !options.preserveOrder) {
|
|
3474
|
+
const attrCollection = {};
|
|
3475
|
+
attrCollection[options.attributesGroupName] = attrs;
|
|
3476
|
+
return attrCollection;
|
|
3477
|
+
}
|
|
3478
|
+
return attrs;
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3481
|
+
var parseXml = function(xmlData) {
|
|
3482
|
+
xmlData = xmlData.replace(/\r\n?/g, "\n");
|
|
3483
|
+
const xmlObj = new XmlNode("!xml");
|
|
3484
|
+
let currentNode = xmlObj;
|
|
3485
|
+
let textData = "";
|
|
3486
|
+
this.matcher.reset();
|
|
3487
|
+
this.entityDecoder.reset();
|
|
3488
|
+
this.entityExpansionCount = 0;
|
|
3489
|
+
this.currentExpandedLength = 0;
|
|
3490
|
+
this.doctypefound = false;
|
|
3491
|
+
const options = this.options;
|
|
3492
|
+
const docTypeReader = new DocTypeReader(options.processEntities);
|
|
3493
|
+
const xmlLen = xmlData.length;
|
|
3494
|
+
for (let i = 0; i < xmlLen; i++) {
|
|
3495
|
+
const ch = xmlData[i];
|
|
3496
|
+
if (ch === "<") {
|
|
3497
|
+
const c1 = xmlData.charCodeAt(i + 1);
|
|
3498
|
+
if (c1 === 47) {
|
|
3499
|
+
const closeIndex = findClosingIndex(xmlData, ">", i, "Closing Tag is not closed.");
|
|
3500
|
+
let tagName = xmlData.substring(i + 2, closeIndex).trim();
|
|
3501
|
+
if (options.removeNSPrefix) {
|
|
3502
|
+
const colonIndex = tagName.indexOf(":");
|
|
3503
|
+
if (colonIndex !== -1) {
|
|
3504
|
+
tagName = tagName.substr(colonIndex + 1);
|
|
3505
|
+
}
|
|
3506
|
+
}
|
|
3507
|
+
tagName = transformTagName(options.transformTagName, tagName, "", options).tagName;
|
|
3508
|
+
if (currentNode) {
|
|
3509
|
+
textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
|
|
3510
|
+
}
|
|
3511
|
+
const lastTagName = this.matcher.getCurrentTag();
|
|
3512
|
+
if (tagName && options.unpairedTagsSet.has(tagName)) {
|
|
3513
|
+
throw new Error(`Unpaired tag can not be used as closing tag: </${tagName}>`);
|
|
3514
|
+
}
|
|
3515
|
+
if (lastTagName && options.unpairedTagsSet.has(lastTagName)) {
|
|
3516
|
+
this.matcher.pop();
|
|
3517
|
+
this.tagsNodeStack.pop();
|
|
3518
|
+
}
|
|
3519
|
+
this.matcher.pop();
|
|
3520
|
+
this.isCurrentNodeStopNode = false;
|
|
3521
|
+
currentNode = this.tagsNodeStack.pop();
|
|
3522
|
+
textData = "";
|
|
3523
|
+
i = closeIndex;
|
|
3524
|
+
} else if (c1 === 63) {
|
|
3525
|
+
let tagData = readTagExp(xmlData, i, false, "?>");
|
|
3526
|
+
if (!tagData) throw new Error("Pi Tag is not closed.");
|
|
3527
|
+
textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
|
|
3528
|
+
const attsMap = this.buildAttributesMap(tagData.tagExp, this.matcher, tagData.tagName, true);
|
|
3529
|
+
if (attsMap) {
|
|
3530
|
+
const ver = attsMap[this.options.attributeNamePrefix + "version"];
|
|
3531
|
+
this.entityDecoder.setXmlVersion(Number(ver) || 1);
|
|
3532
|
+
docTypeReader.setXmlVersion(Number(ver) || 1);
|
|
3533
|
+
}
|
|
3534
|
+
if (options.ignoreDeclaration && tagData.tagName === "?xml" || options.ignorePiTags) {
|
|
3535
|
+
} else {
|
|
3536
|
+
const childNode = new XmlNode(tagData.tagName);
|
|
3537
|
+
childNode.add(options.textNodeName, "");
|
|
3538
|
+
if (tagData.tagName !== tagData.tagExp && tagData.attrExpPresent && options.ignoreAttributes !== true) {
|
|
3539
|
+
childNode[":@"] = attsMap;
|
|
3540
|
+
}
|
|
3541
|
+
this.addChild(currentNode, childNode, this.readonlyMatcher, i);
|
|
3542
|
+
}
|
|
3543
|
+
i = tagData.closeIndex + 1;
|
|
3544
|
+
} else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 45 && xmlData.charCodeAt(i + 3) === 45) {
|
|
3545
|
+
const endIndex = findClosingIndex(xmlData, "-->", i + 4, "Comment is not closed.");
|
|
3546
|
+
if (options.commentPropName) {
|
|
3547
|
+
const comment = xmlData.substring(i + 4, endIndex - 2);
|
|
3548
|
+
textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
|
|
3549
|
+
currentNode.add(options.commentPropName, [{ [options.textNodeName]: comment }]);
|
|
3550
|
+
}
|
|
3551
|
+
i = endIndex;
|
|
3552
|
+
} else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 68) {
|
|
3553
|
+
if (this.doctypefound) throw new Error("Multiple DOCTYPE declarations found.");
|
|
3554
|
+
this.doctypefound = true;
|
|
3555
|
+
const result = docTypeReader.readDocType(xmlData, i);
|
|
3556
|
+
this.entityDecoder.addInputEntities(result.entities);
|
|
3557
|
+
i = result.i;
|
|
3558
|
+
} else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 91) {
|
|
3559
|
+
const closeIndex = findClosingIndex(xmlData, "]]>", i, "CDATA is not closed.") - 2;
|
|
3560
|
+
const tagExp = xmlData.substring(i + 9, closeIndex);
|
|
3561
|
+
textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher);
|
|
3562
|
+
let val = this.parseTextData(tagExp, currentNode.tagname, this.readonlyMatcher, true, false, true, true);
|
|
3563
|
+
if (val == void 0) val = "";
|
|
3564
|
+
if (options.cdataPropName) {
|
|
3565
|
+
currentNode.add(options.cdataPropName, [{ [options.textNodeName]: tagExp }]);
|
|
3566
|
+
} else {
|
|
3567
|
+
currentNode.add(options.textNodeName, val);
|
|
3568
|
+
}
|
|
3569
|
+
i = closeIndex + 2;
|
|
3570
|
+
} else {
|
|
3571
|
+
let result = readTagExp(xmlData, i, options.removeNSPrefix);
|
|
3572
|
+
if (!result) {
|
|
3573
|
+
const context = xmlData.substring(Math.max(0, i - 50), Math.min(xmlLen, i + 50));
|
|
3574
|
+
throw new Error(`readTagExp returned undefined at position ${i}. Context: "${context}"`);
|
|
3575
|
+
}
|
|
3576
|
+
let tagName = result.tagName;
|
|
3577
|
+
const rawTagName = result.rawTagName;
|
|
3578
|
+
let tagExp = result.tagExp;
|
|
3579
|
+
let attrExpPresent = result.attrExpPresent;
|
|
3580
|
+
let closeIndex = result.closeIndex;
|
|
3581
|
+
({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));
|
|
3582
|
+
if (options.strictReservedNames && (tagName === options.commentPropName || tagName === options.cdataPropName || tagName === options.textNodeName || tagName === options.attributesGroupName)) {
|
|
3583
|
+
throw new Error(`Invalid tag name: ${tagName}`);
|
|
3584
|
+
}
|
|
3585
|
+
if (currentNode && textData) {
|
|
3586
|
+
if (currentNode.tagname !== "!xml") {
|
|
3587
|
+
textData = this.saveTextToParentTag(textData, currentNode, this.readonlyMatcher, false);
|
|
3588
|
+
}
|
|
3589
|
+
}
|
|
3590
|
+
const lastTag = currentNode;
|
|
3591
|
+
if (lastTag && options.unpairedTagsSet.has(lastTag.tagname)) {
|
|
3592
|
+
currentNode = this.tagsNodeStack.pop();
|
|
3593
|
+
this.matcher.pop();
|
|
3594
|
+
}
|
|
3595
|
+
let isSelfClosing = false;
|
|
3596
|
+
if (tagExp.length > 0 && tagExp.lastIndexOf("/") === tagExp.length - 1) {
|
|
3597
|
+
isSelfClosing = true;
|
|
3598
|
+
if (tagName[tagName.length - 1] === "/") {
|
|
3599
|
+
tagName = tagName.substr(0, tagName.length - 1);
|
|
3600
|
+
tagExp = tagName;
|
|
3601
|
+
} else {
|
|
3602
|
+
tagExp = tagExp.substr(0, tagExp.length - 1);
|
|
3603
|
+
}
|
|
3604
|
+
attrExpPresent = tagName !== tagExp;
|
|
3605
|
+
}
|
|
3606
|
+
let prefixedAttrs = null;
|
|
3607
|
+
let rawAttrs = {};
|
|
3608
|
+
let namespace = void 0;
|
|
3609
|
+
namespace = extractNamespace(rawTagName);
|
|
3610
|
+
if (tagName !== xmlObj.tagname) {
|
|
3611
|
+
this.matcher.push(tagName, {}, namespace);
|
|
3612
|
+
}
|
|
3613
|
+
if (tagName !== tagExp && attrExpPresent) {
|
|
3614
|
+
prefixedAttrs = this.buildAttributesMap(tagExp, this.matcher, tagName);
|
|
3615
|
+
if (prefixedAttrs) {
|
|
3616
|
+
rawAttrs = extractRawAttributes(prefixedAttrs, options);
|
|
3617
|
+
}
|
|
3618
|
+
}
|
|
3619
|
+
if (tagName !== xmlObj.tagname) {
|
|
3620
|
+
this.isCurrentNodeStopNode = this.isItStopNode();
|
|
3621
|
+
}
|
|
3622
|
+
const startIndex = i;
|
|
3623
|
+
if (this.isCurrentNodeStopNode) {
|
|
3624
|
+
let tagContent = "";
|
|
3625
|
+
if (isSelfClosing) {
|
|
3626
|
+
i = result.closeIndex;
|
|
3627
|
+
} else if (options.unpairedTagsSet.has(tagName)) {
|
|
3628
|
+
i = result.closeIndex;
|
|
3629
|
+
} else {
|
|
3630
|
+
const result2 = this.readStopNodeData(xmlData, rawTagName, closeIndex + 1);
|
|
3631
|
+
if (!result2) throw new Error(`Unexpected end of ${rawTagName}`);
|
|
3632
|
+
i = result2.i;
|
|
3633
|
+
tagContent = result2.tagContent;
|
|
3634
|
+
}
|
|
3635
|
+
const childNode = new XmlNode(tagName);
|
|
3636
|
+
if (prefixedAttrs) {
|
|
3637
|
+
childNode[":@"] = prefixedAttrs;
|
|
3638
|
+
}
|
|
3639
|
+
childNode.add(options.textNodeName, tagContent);
|
|
3640
|
+
this.matcher.pop();
|
|
3641
|
+
this.isCurrentNodeStopNode = false;
|
|
3642
|
+
this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
|
|
3643
|
+
} else {
|
|
3644
|
+
if (isSelfClosing) {
|
|
3645
|
+
({ tagName, tagExp } = transformTagName(options.transformTagName, tagName, tagExp, options));
|
|
3646
|
+
const childNode = new XmlNode(tagName);
|
|
3647
|
+
if (prefixedAttrs) {
|
|
3648
|
+
childNode[":@"] = prefixedAttrs;
|
|
3649
|
+
}
|
|
3650
|
+
this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
|
|
3651
|
+
this.matcher.pop();
|
|
3652
|
+
this.isCurrentNodeStopNode = false;
|
|
3653
|
+
} else if (options.unpairedTagsSet.has(tagName)) {
|
|
3654
|
+
const childNode = new XmlNode(tagName);
|
|
3655
|
+
if (prefixedAttrs) {
|
|
3656
|
+
childNode[":@"] = prefixedAttrs;
|
|
3657
|
+
}
|
|
3658
|
+
this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
|
|
3659
|
+
this.matcher.pop();
|
|
3660
|
+
this.isCurrentNodeStopNode = false;
|
|
3661
|
+
i = result.closeIndex;
|
|
3662
|
+
continue;
|
|
3663
|
+
} else {
|
|
3664
|
+
const childNode = new XmlNode(tagName);
|
|
3665
|
+
if (this.tagsNodeStack.length > options.maxNestedTags) {
|
|
3666
|
+
throw new Error("Maximum nested tags exceeded");
|
|
3667
|
+
}
|
|
3668
|
+
this.tagsNodeStack.push(currentNode);
|
|
3669
|
+
if (prefixedAttrs) {
|
|
3670
|
+
childNode[":@"] = prefixedAttrs;
|
|
3671
|
+
}
|
|
3672
|
+
this.addChild(currentNode, childNode, this.readonlyMatcher, startIndex);
|
|
3673
|
+
currentNode = childNode;
|
|
3674
|
+
}
|
|
3675
|
+
textData = "";
|
|
3676
|
+
i = closeIndex;
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3679
|
+
} else {
|
|
3680
|
+
textData += xmlData[i];
|
|
3681
|
+
}
|
|
3682
|
+
}
|
|
3683
|
+
return xmlObj.child;
|
|
3684
|
+
};
|
|
3685
|
+
function addChild(currentNode, childNode, matcher, startIndex) {
|
|
3686
|
+
if (!this.options.captureMetaData) startIndex = void 0;
|
|
3687
|
+
const jPathOrMatcher = this.options.jPath ? matcher.toString() : matcher;
|
|
3688
|
+
const result = this.options.updateTag(childNode.tagname, jPathOrMatcher, childNode[":@"]);
|
|
3689
|
+
if (result === false) {
|
|
3690
|
+
} else if (typeof result === "string") {
|
|
3691
|
+
childNode.tagname = result;
|
|
3692
|
+
currentNode.addChild(childNode, startIndex);
|
|
3693
|
+
} else {
|
|
3694
|
+
currentNode.addChild(childNode, startIndex);
|
|
3695
|
+
}
|
|
3696
|
+
}
|
|
3697
|
+
function replaceEntitiesValue(val, tagName, jPath) {
|
|
3698
|
+
const entityConfig = this.options.processEntities;
|
|
3699
|
+
if (!entityConfig || !entityConfig.enabled) {
|
|
3700
|
+
return val;
|
|
3701
|
+
}
|
|
3702
|
+
if (entityConfig.allowedTags) {
|
|
3703
|
+
const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
|
|
3704
|
+
const allowed = Array.isArray(entityConfig.allowedTags) ? entityConfig.allowedTags.includes(tagName) : entityConfig.allowedTags(tagName, jPathOrMatcher);
|
|
3705
|
+
if (!allowed) {
|
|
3706
|
+
return val;
|
|
3707
|
+
}
|
|
3708
|
+
}
|
|
3709
|
+
if (entityConfig.tagFilter) {
|
|
3710
|
+
const jPathOrMatcher = this.options.jPath ? jPath.toString() : jPath;
|
|
3711
|
+
if (!entityConfig.tagFilter(tagName, jPathOrMatcher)) {
|
|
3712
|
+
return val;
|
|
3713
|
+
}
|
|
3714
|
+
}
|
|
3715
|
+
return this.entityDecoder.decode(val);
|
|
3716
|
+
}
|
|
3717
|
+
function saveTextToParentTag(textData, parentNode, matcher, isLeafNode) {
|
|
3718
|
+
if (textData) {
|
|
3719
|
+
if (isLeafNode === void 0) isLeafNode = parentNode.child.length === 0;
|
|
3720
|
+
textData = this.parseTextData(
|
|
3721
|
+
textData,
|
|
3722
|
+
parentNode.tagname,
|
|
3723
|
+
matcher,
|
|
3724
|
+
false,
|
|
3725
|
+
parentNode[":@"] ? Object.keys(parentNode[":@"]).length !== 0 : false,
|
|
3726
|
+
isLeafNode
|
|
3727
|
+
);
|
|
3728
|
+
if (textData !== void 0 && textData !== "")
|
|
3729
|
+
parentNode.add(this.options.textNodeName, textData);
|
|
3730
|
+
textData = "";
|
|
3731
|
+
}
|
|
3732
|
+
return textData;
|
|
3733
|
+
}
|
|
3734
|
+
function isItStopNode() {
|
|
3735
|
+
if (this.stopNodeExpressionsSet.size === 0) return false;
|
|
3736
|
+
return this.matcher.matchesAny(this.stopNodeExpressionsSet);
|
|
3737
|
+
}
|
|
3738
|
+
function tagExpWithClosingIndex(xmlData, i, closingChar = ">") {
|
|
3739
|
+
let attrBoundary = 0;
|
|
3740
|
+
const len = xmlData.length;
|
|
3741
|
+
const closeCode0 = closingChar.charCodeAt(0);
|
|
3742
|
+
const closeCode1 = closingChar.length > 1 ? closingChar.charCodeAt(1) : -1;
|
|
3743
|
+
let result = "";
|
|
3744
|
+
let segmentStart = i;
|
|
3745
|
+
for (let index = i; index < len; index++) {
|
|
3746
|
+
const code = xmlData.charCodeAt(index);
|
|
3747
|
+
if (attrBoundary) {
|
|
3748
|
+
if (code === attrBoundary) attrBoundary = 0;
|
|
3749
|
+
} else if (code === 34 || code === 39) {
|
|
3750
|
+
attrBoundary = code;
|
|
3751
|
+
} else if (code === closeCode0) {
|
|
3752
|
+
if (closeCode1 !== -1) {
|
|
3753
|
+
if (xmlData.charCodeAt(index + 1) === closeCode1) {
|
|
3754
|
+
result += xmlData.substring(segmentStart, index);
|
|
3755
|
+
return { data: result, index };
|
|
3756
|
+
}
|
|
3757
|
+
} else {
|
|
3758
|
+
result += xmlData.substring(segmentStart, index);
|
|
3759
|
+
return { data: result, index };
|
|
3760
|
+
}
|
|
3761
|
+
} else if (code === 9 && !attrBoundary) {
|
|
3762
|
+
result += xmlData.substring(segmentStart, index) + " ";
|
|
3763
|
+
segmentStart = index + 1;
|
|
3764
|
+
}
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
function findClosingIndex(xmlData, str, i, errMsg) {
|
|
3768
|
+
const closingIndex = xmlData.indexOf(str, i);
|
|
3769
|
+
if (closingIndex === -1) {
|
|
3770
|
+
throw new Error(errMsg);
|
|
3771
|
+
} else {
|
|
3772
|
+
return closingIndex + str.length - 1;
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
function findClosingChar(xmlData, char, i, errMsg) {
|
|
3776
|
+
const closingIndex = xmlData.indexOf(char, i);
|
|
3777
|
+
if (closingIndex === -1) throw new Error(errMsg);
|
|
3778
|
+
return closingIndex;
|
|
3779
|
+
}
|
|
3780
|
+
function readTagExp(xmlData, i, removeNSPrefix, closingChar = ">") {
|
|
3781
|
+
const result = tagExpWithClosingIndex(xmlData, i + 1, closingChar);
|
|
3782
|
+
if (!result) return;
|
|
3783
|
+
let tagExp = result.data;
|
|
3784
|
+
const closeIndex = result.index;
|
|
3785
|
+
const separatorIndex = tagExp.search(/\s/);
|
|
3786
|
+
let tagName = tagExp;
|
|
3787
|
+
let attrExpPresent = true;
|
|
3788
|
+
if (separatorIndex !== -1) {
|
|
3789
|
+
tagName = tagExp.substring(0, separatorIndex);
|
|
3790
|
+
tagExp = tagExp.substring(separatorIndex + 1).trimStart();
|
|
3791
|
+
}
|
|
3792
|
+
const rawTagName = tagName;
|
|
3793
|
+
if (removeNSPrefix) {
|
|
3794
|
+
const colonIndex = tagName.indexOf(":");
|
|
3795
|
+
if (colonIndex !== -1) {
|
|
3796
|
+
tagName = tagName.substr(colonIndex + 1);
|
|
3797
|
+
attrExpPresent = tagName !== result.data.substr(colonIndex + 1);
|
|
3798
|
+
}
|
|
3799
|
+
}
|
|
3800
|
+
return {
|
|
3801
|
+
tagName,
|
|
3802
|
+
tagExp,
|
|
3803
|
+
closeIndex,
|
|
3804
|
+
attrExpPresent,
|
|
3805
|
+
rawTagName
|
|
3806
|
+
};
|
|
3807
|
+
}
|
|
3808
|
+
function readStopNodeData(xmlData, tagName, i) {
|
|
3809
|
+
const startIndex = i;
|
|
3810
|
+
let openTagCount = 1;
|
|
3811
|
+
const xmllen = xmlData.length;
|
|
3812
|
+
for (; i < xmllen; i++) {
|
|
3813
|
+
if (xmlData[i] === "<") {
|
|
3814
|
+
const c1 = xmlData.charCodeAt(i + 1);
|
|
3815
|
+
if (c1 === 47) {
|
|
3816
|
+
const closeIndex = findClosingChar(xmlData, ">", i, `${tagName} is not closed`);
|
|
3817
|
+
let closeTagName = xmlData.substring(i + 2, closeIndex).trim();
|
|
3818
|
+
if (closeTagName === tagName) {
|
|
3819
|
+
openTagCount--;
|
|
3820
|
+
if (openTagCount === 0) {
|
|
3821
|
+
return {
|
|
3822
|
+
tagContent: xmlData.substring(startIndex, i),
|
|
3823
|
+
i: closeIndex
|
|
3824
|
+
};
|
|
3825
|
+
}
|
|
3826
|
+
}
|
|
3827
|
+
i = closeIndex;
|
|
3828
|
+
} else if (c1 === 63) {
|
|
3829
|
+
const closeIndex = findClosingIndex(xmlData, "?>", i + 1, "StopNode is not closed.");
|
|
3830
|
+
i = closeIndex;
|
|
3831
|
+
} else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 45 && xmlData.charCodeAt(i + 3) === 45) {
|
|
3832
|
+
const closeIndex = findClosingIndex(xmlData, "-->", i + 3, "StopNode is not closed.");
|
|
3833
|
+
i = closeIndex;
|
|
3834
|
+
} else if (c1 === 33 && xmlData.charCodeAt(i + 2) === 91) {
|
|
3835
|
+
const closeIndex = findClosingIndex(xmlData, "]]>", i, "StopNode is not closed.") - 2;
|
|
3836
|
+
i = closeIndex;
|
|
3837
|
+
} else {
|
|
3838
|
+
const tagData = readTagExp(xmlData, i, false);
|
|
3839
|
+
if (tagData) {
|
|
3840
|
+
const openTagName = tagData && tagData.tagName;
|
|
3841
|
+
if (openTagName === tagName && tagData.tagExp[tagData.tagExp.length - 1] !== "/") {
|
|
3842
|
+
openTagCount++;
|
|
3843
|
+
}
|
|
3844
|
+
i = tagData.closeIndex;
|
|
3845
|
+
}
|
|
3846
|
+
}
|
|
3847
|
+
}
|
|
3848
|
+
}
|
|
3849
|
+
}
|
|
3850
|
+
function parseValue(val, shouldParse, options) {
|
|
3851
|
+
if (shouldParse && typeof val === "string") {
|
|
3852
|
+
const newval = val.trim();
|
|
3853
|
+
if (newval === "true") return true;
|
|
3854
|
+
else if (newval === "false") return false;
|
|
3855
|
+
else return toNumber(val, options);
|
|
3856
|
+
} else {
|
|
3857
|
+
if (isExist(val)) {
|
|
3858
|
+
return val;
|
|
3859
|
+
} else {
|
|
3860
|
+
return "";
|
|
3861
|
+
}
|
|
3862
|
+
}
|
|
3863
|
+
}
|
|
3864
|
+
function transformTagName(fn, tagName, tagExp, options) {
|
|
3865
|
+
if (fn) {
|
|
3866
|
+
const newTagName = fn(tagName);
|
|
3867
|
+
if (tagExp === tagName) {
|
|
3868
|
+
tagExp = newTagName;
|
|
3869
|
+
}
|
|
3870
|
+
tagName = newTagName;
|
|
3871
|
+
}
|
|
3872
|
+
tagName = sanitizeName(tagName, options);
|
|
3873
|
+
return { tagName, tagExp };
|
|
3874
|
+
}
|
|
3875
|
+
function sanitizeName(name, options) {
|
|
3876
|
+
if (criticalProperties.includes(name)) {
|
|
3877
|
+
throw new Error(`[SECURITY] Invalid name: "${name}" is a reserved JavaScript keyword that could cause prototype pollution`);
|
|
3878
|
+
} else if (DANGEROUS_PROPERTY_NAMES.includes(name)) {
|
|
3879
|
+
return options.onDangerousProperty(name);
|
|
3880
|
+
}
|
|
3881
|
+
return name;
|
|
3882
|
+
}
|
|
3883
|
+
|
|
3884
|
+
// ../../node_modules/fast-xml-parser/src/xmlparser/node2json.js
|
|
3885
|
+
var METADATA_SYMBOL2 = XmlNode.getMetaDataSymbol();
|
|
3886
|
+
function stripAttributePrefix(attrs, prefix) {
|
|
3887
|
+
if (!attrs || typeof attrs !== "object") return {};
|
|
3888
|
+
if (!prefix) return attrs;
|
|
3889
|
+
const rawAttrs = {};
|
|
3890
|
+
for (const key in attrs) {
|
|
3891
|
+
if (key.startsWith(prefix)) {
|
|
3892
|
+
const rawName = key.substring(prefix.length);
|
|
3893
|
+
rawAttrs[rawName] = attrs[key];
|
|
3894
|
+
} else {
|
|
3895
|
+
rawAttrs[key] = attrs[key];
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
3898
|
+
return rawAttrs;
|
|
3899
|
+
}
|
|
3900
|
+
function prettify(node, options, matcher, readonlyMatcher) {
|
|
3901
|
+
return compress(node, options, matcher, readonlyMatcher);
|
|
3902
|
+
}
|
|
3903
|
+
function compress(arr, options, matcher, readonlyMatcher) {
|
|
3904
|
+
let text;
|
|
3905
|
+
const compressedObj = {};
|
|
3906
|
+
for (let i = 0; i < arr.length; i++) {
|
|
3907
|
+
const tagObj = arr[i];
|
|
3908
|
+
const property = propName(tagObj);
|
|
3909
|
+
if (property !== void 0 && property !== options.textNodeName) {
|
|
3910
|
+
const rawAttrs = stripAttributePrefix(
|
|
3911
|
+
tagObj[":@"] || {},
|
|
3912
|
+
options.attributeNamePrefix
|
|
3913
|
+
);
|
|
3914
|
+
matcher.push(property, rawAttrs);
|
|
3915
|
+
}
|
|
3916
|
+
if (property === options.textNodeName) {
|
|
3917
|
+
if (text === void 0) text = tagObj[property];
|
|
3918
|
+
else text += "" + tagObj[property];
|
|
3919
|
+
} else if (property === void 0) {
|
|
3920
|
+
continue;
|
|
3921
|
+
} else if (tagObj[property]) {
|
|
3922
|
+
let val = compress(tagObj[property], options, matcher, readonlyMatcher);
|
|
3923
|
+
const isLeaf = isLeafTag(val, options);
|
|
3924
|
+
if (Object.keys(val).length === 0 && options.alwaysCreateTextNode) {
|
|
3925
|
+
val[options.textNodeName] = "";
|
|
3926
|
+
}
|
|
3927
|
+
if (tagObj[":@"]) {
|
|
3928
|
+
assignAttributes(val, tagObj[":@"], readonlyMatcher, options);
|
|
3929
|
+
} else if (Object.keys(val).length === 1 && val[options.textNodeName] !== void 0 && !options.alwaysCreateTextNode) {
|
|
3930
|
+
val = val[options.textNodeName];
|
|
3931
|
+
} else if (Object.keys(val).length === 0) {
|
|
3932
|
+
if (options.alwaysCreateTextNode) val[options.textNodeName] = "";
|
|
3933
|
+
else val = "";
|
|
3934
|
+
}
|
|
3935
|
+
if (tagObj[METADATA_SYMBOL2] !== void 0 && typeof val === "object" && val !== null) {
|
|
3936
|
+
val[METADATA_SYMBOL2] = tagObj[METADATA_SYMBOL2];
|
|
3937
|
+
}
|
|
3938
|
+
if (compressedObj[property] !== void 0 && Object.prototype.hasOwnProperty.call(compressedObj, property)) {
|
|
3939
|
+
if (!Array.isArray(compressedObj[property])) {
|
|
3940
|
+
compressedObj[property] = [compressedObj[property]];
|
|
3941
|
+
}
|
|
3942
|
+
compressedObj[property].push(val);
|
|
3943
|
+
} else {
|
|
3944
|
+
const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() : readonlyMatcher;
|
|
3945
|
+
if (options.isArray(property, jPathOrMatcher, isLeaf)) {
|
|
3946
|
+
compressedObj[property] = [val];
|
|
3947
|
+
} else {
|
|
3948
|
+
compressedObj[property] = val;
|
|
3949
|
+
}
|
|
3950
|
+
}
|
|
3951
|
+
if (property !== void 0 && property !== options.textNodeName) {
|
|
3952
|
+
matcher.pop();
|
|
3953
|
+
}
|
|
3954
|
+
}
|
|
3955
|
+
}
|
|
3956
|
+
if (typeof text === "string") {
|
|
3957
|
+
if (text.length > 0) compressedObj[options.textNodeName] = text;
|
|
3958
|
+
} else if (text !== void 0) compressedObj[options.textNodeName] = text;
|
|
3959
|
+
return compressedObj;
|
|
3960
|
+
}
|
|
3961
|
+
function propName(obj) {
|
|
3962
|
+
const keys = Object.keys(obj);
|
|
3963
|
+
for (let i = 0; i < keys.length; i++) {
|
|
3964
|
+
const key = keys[i];
|
|
3965
|
+
if (key !== ":@") return key;
|
|
3966
|
+
}
|
|
3967
|
+
}
|
|
3968
|
+
function assignAttributes(obj, attrMap, readonlyMatcher, options) {
|
|
3969
|
+
if (attrMap) {
|
|
3970
|
+
const keys = Object.keys(attrMap);
|
|
3971
|
+
const len = keys.length;
|
|
3972
|
+
for (let i = 0; i < len; i++) {
|
|
3973
|
+
const atrrName = keys[i];
|
|
3974
|
+
const rawAttrName = atrrName.startsWith(options.attributeNamePrefix) ? atrrName.substring(options.attributeNamePrefix.length) : atrrName;
|
|
3975
|
+
const jPathOrMatcher = options.jPath ? readonlyMatcher.toString() + "." + rawAttrName : readonlyMatcher;
|
|
3976
|
+
if (options.isArray(atrrName, jPathOrMatcher, true, true)) {
|
|
3977
|
+
obj[atrrName] = [attrMap[atrrName]];
|
|
3978
|
+
} else {
|
|
3979
|
+
obj[atrrName] = attrMap[atrrName];
|
|
3980
|
+
}
|
|
3981
|
+
}
|
|
3982
|
+
}
|
|
3983
|
+
}
|
|
3984
|
+
function isLeafTag(obj, options) {
|
|
3985
|
+
const { textNodeName } = options;
|
|
3986
|
+
const propCount = Object.keys(obj).length;
|
|
3987
|
+
if (propCount === 0) {
|
|
3988
|
+
return true;
|
|
3989
|
+
}
|
|
3990
|
+
if (propCount === 1 && (obj[textNodeName] || typeof obj[textNodeName] === "boolean" || obj[textNodeName] === 0)) {
|
|
3991
|
+
return true;
|
|
3992
|
+
}
|
|
3993
|
+
return false;
|
|
3994
|
+
}
|
|
3995
|
+
|
|
3996
|
+
// ../../node_modules/fast-xml-parser/src/xmlparser/XMLParser.js
|
|
3997
|
+
var XMLParser = class {
|
|
3998
|
+
constructor(options) {
|
|
3999
|
+
this.externalEntities = {};
|
|
4000
|
+
this.options = buildOptions(options);
|
|
4001
|
+
}
|
|
4002
|
+
/**
|
|
4003
|
+
* Parse XML dats to JS object
|
|
4004
|
+
* @param {string|Uint8Array} xmlData
|
|
4005
|
+
* @param {boolean|Object} validationOption
|
|
4006
|
+
*/
|
|
4007
|
+
parse(xmlData, validationOption) {
|
|
4008
|
+
if (typeof xmlData !== "string" && xmlData.toString) {
|
|
4009
|
+
xmlData = xmlData.toString();
|
|
4010
|
+
} else if (typeof xmlData !== "string") {
|
|
4011
|
+
throw new Error("XML data is accepted in String or Bytes[] form.");
|
|
4012
|
+
}
|
|
4013
|
+
if (validationOption) {
|
|
4014
|
+
if (validationOption === true) validationOption = {};
|
|
4015
|
+
const result = validate(xmlData, validationOption);
|
|
4016
|
+
if (result !== true) {
|
|
4017
|
+
throw Error(`${result.err.msg}:${result.err.line}:${result.err.col}`);
|
|
4018
|
+
}
|
|
4019
|
+
}
|
|
4020
|
+
const orderedObjParser = new OrderedObjParser(this.options, this.externalEntities);
|
|
4021
|
+
const orderedResult = orderedObjParser.parseXml(xmlData);
|
|
4022
|
+
if (this.options.preserveOrder || orderedResult === void 0) return orderedResult;
|
|
4023
|
+
else return prettify(orderedResult, this.options, orderedObjParser.matcher, orderedObjParser.readonlyMatcher);
|
|
4024
|
+
}
|
|
4025
|
+
/**
|
|
4026
|
+
* Add Entity which is not by default supported by this library
|
|
4027
|
+
* @param {string} key
|
|
4028
|
+
* @param {string} value
|
|
4029
|
+
*/
|
|
4030
|
+
addEntity(key, value) {
|
|
4031
|
+
if (value.indexOf("&") !== -1) {
|
|
4032
|
+
throw new Error("Entity value can't have '&'");
|
|
4033
|
+
} else if (key.indexOf("&") !== -1 || key.indexOf(";") !== -1) {
|
|
4034
|
+
throw new Error("An entity must be set without '&' and ';'. Eg. use '#xD' for '
'");
|
|
4035
|
+
} else if (value === "&") {
|
|
4036
|
+
throw new Error("An entity with value '&' is not permitted");
|
|
4037
|
+
} else {
|
|
4038
|
+
this.externalEntities[key] = value;
|
|
4039
|
+
}
|
|
4040
|
+
}
|
|
4041
|
+
/**
|
|
4042
|
+
* Returns a Symbol that can be used to access the metadata
|
|
4043
|
+
* property on a node.
|
|
4044
|
+
*
|
|
4045
|
+
* If Symbol is not available in the environment, an ordinary property is used
|
|
4046
|
+
* and the name of the property is here returned.
|
|
4047
|
+
*
|
|
4048
|
+
* The XMLMetaData property is only present when `captureMetaData`
|
|
4049
|
+
* is true in the options.
|
|
4050
|
+
*/
|
|
4051
|
+
static getMetaDataSymbol() {
|
|
4052
|
+
return XmlNode.getMetaDataSymbol();
|
|
4053
|
+
}
|
|
4054
|
+
};
|
|
4055
|
+
|
|
4056
|
+
// ../../runtime/osgi_repository.ts
|
|
4057
|
+
var SHA256 = /^[0-9a-f]{64}$/;
|
|
4058
|
+
var OSGI_VERSION = /^(0|[1-9][0-9]*)(?:\.(0|[1-9][0-9]*))?(?:\.(0|[1-9][0-9]*))?(?:\.([A-Za-z0-9_-]+))?$/;
|
|
4059
|
+
var parser = new XMLParser({
|
|
4060
|
+
ignoreAttributes: false,
|
|
4061
|
+
attributeNamePrefix: "",
|
|
4062
|
+
removeNSPrefix: true,
|
|
4063
|
+
isArray: (_name, path) => /\.(resource|capability|requirement|attribute|directive)$/.test(String(path)),
|
|
4064
|
+
parseAttributeValue: false,
|
|
4065
|
+
parseTagValue: false,
|
|
4066
|
+
processEntities: false,
|
|
4067
|
+
trimValues: false
|
|
4068
|
+
});
|
|
4069
|
+
function children(value) {
|
|
4070
|
+
return Array.isArray(value) ? value.filter((entry) => typeof entry === "object" && entry !== null) : [];
|
|
4071
|
+
}
|
|
4072
|
+
function attributes(capability) {
|
|
4073
|
+
const result = /* @__PURE__ */ new Map();
|
|
4074
|
+
for (const attribute of children(capability.attribute)) {
|
|
4075
|
+
const name = attribute.name;
|
|
4076
|
+
const value = attribute.value;
|
|
4077
|
+
const type = attribute.type;
|
|
4078
|
+
if (typeof name !== "string" || typeof value !== "string" || result.has(name)) {
|
|
4079
|
+
throw new Error("OSGi capability contains a malformed or duplicate attribute");
|
|
4080
|
+
}
|
|
4081
|
+
if (type !== void 0 && typeof type !== "string") {
|
|
4082
|
+
throw new Error(`OSGi attribute ${name} has a malformed type`);
|
|
4083
|
+
}
|
|
4084
|
+
result.set(name, { value, ...type === void 0 ? {} : { type } });
|
|
4085
|
+
}
|
|
4086
|
+
return result;
|
|
4087
|
+
}
|
|
4088
|
+
function capabilityByNamespace(capabilities, namespace) {
|
|
4089
|
+
const matches = capabilities.filter((capability) => capability.namespace === namespace);
|
|
4090
|
+
if (matches.length !== 1) {
|
|
4091
|
+
throw new Error(`OSGi resource needs exactly one ${namespace} capability`);
|
|
4092
|
+
}
|
|
4093
|
+
return matches[0];
|
|
4094
|
+
}
|
|
4095
|
+
function required(attributes2, name) {
|
|
4096
|
+
const value = attributes2.get(name)?.value;
|
|
4097
|
+
if (value === void 0 || value.length === 0) throw new Error(`OSGi capability has no ${name} attribute`);
|
|
4098
|
+
return value;
|
|
4099
|
+
}
|
|
4100
|
+
function parseOsgiRepository(xml) {
|
|
4101
|
+
const document = parser.parse(xml);
|
|
4102
|
+
const parsedRepository = document.repository;
|
|
4103
|
+
const repository = parsedRepository === "" ? {} : parsedRepository;
|
|
4104
|
+
if (typeof repository !== "object" || repository === null || Array.isArray(repository)) {
|
|
4105
|
+
throw new Error("document has no OSGi repository root");
|
|
4106
|
+
}
|
|
4107
|
+
const resources = children(repository.resource).map((resource) => {
|
|
4108
|
+
const capabilities = children(resource.capability);
|
|
4109
|
+
const identityAttributes = attributes(capabilityByNamespace(capabilities, "osgi.identity"));
|
|
4110
|
+
const contentAttributes = attributes(capabilityByNamespace(capabilities, "osgi.content"));
|
|
4111
|
+
const identity = required(identityAttributes, "osgi.identity");
|
|
4112
|
+
const identityType = required(identityAttributes, "type");
|
|
4113
|
+
const identityVersion = required(identityAttributes, "version");
|
|
4114
|
+
if (!OSGI_VERSION.test(identityVersion)) throw new Error(`invalid OSGi identity version ${identityVersion}`);
|
|
4115
|
+
const contentSha256 = required(contentAttributes, "osgi.content");
|
|
4116
|
+
if (!SHA256.test(contentSha256)) throw new Error("osgi.content is not a lowercase SHA-256");
|
|
4117
|
+
const contentUrl = required(contentAttributes, "url");
|
|
4118
|
+
const sizeText = required(contentAttributes, "size");
|
|
4119
|
+
const contentSize = Number(sizeText);
|
|
4120
|
+
if (!Number.isSafeInteger(contentSize) || contentSize < 1) throw new Error("osgi.content size is invalid");
|
|
4121
|
+
const contentMime = required(contentAttributes, "mime");
|
|
4122
|
+
const contracts = capabilities.filter((capability) => capability.namespace === "osgi.contract").map((capability) => {
|
|
4123
|
+
const values = attributes(capability);
|
|
4124
|
+
const name = required(values, "osgi.contract");
|
|
4125
|
+
const versions = required(values, "version").split(",");
|
|
4126
|
+
if (versions.length === 0 || versions.some((version) => !OSGI_VERSION.test(version))) {
|
|
4127
|
+
throw new Error(`OSGi contract ${name} has invalid versions`);
|
|
4128
|
+
}
|
|
4129
|
+
const descriptorSha256 = values.get("nomos.contract.descriptor.sha256")?.value;
|
|
4130
|
+
if (descriptorSha256 !== void 0 && !SHA256.test(descriptorSha256)) {
|
|
4131
|
+
throw new Error(`OSGi contract ${name} has an invalid descriptor digest`);
|
|
4132
|
+
}
|
|
4133
|
+
return { name, versions, ...descriptorSha256 === void 0 ? {} : { descriptorSha256 } };
|
|
4134
|
+
});
|
|
4135
|
+
if (contracts.length === 0) throw new Error(`OSGi resource ${identity} has no contracts`);
|
|
4136
|
+
return {
|
|
4137
|
+
identity,
|
|
4138
|
+
identityType,
|
|
4139
|
+
identityVersion,
|
|
4140
|
+
contentSha256,
|
|
4141
|
+
contentUrl,
|
|
4142
|
+
contentSize,
|
|
4143
|
+
contentMime,
|
|
4144
|
+
contracts
|
|
4145
|
+
};
|
|
4146
|
+
});
|
|
4147
|
+
if (resources.length === 0) throw new Error("OSGi repository contains no resources");
|
|
4148
|
+
return resources;
|
|
4149
|
+
}
|
|
4150
|
+
function requireSingleOsgiResource(xml) {
|
|
4151
|
+
const resources = parseOsgiRepository(xml);
|
|
4152
|
+
if (resources.length !== 1) throw new Error(`selected OSGi repository contains ${resources.length} resources`);
|
|
4153
|
+
return resources[0];
|
|
4154
|
+
}
|
|
4155
|
+
|
|
4156
|
+
// runner/runtime-refresh.ts
|
|
22
4157
|
var RUNTIME_FRESH_MS = 15 * 60 * 1e3;
|
|
4158
|
+
var NOMOS_KERNEL_REQUIREMENTS = Object.freeze([
|
|
4159
|
+
Object.freeze({ name: "nomos.kernel.v1", version: "1.0.0" })
|
|
4160
|
+
]);
|
|
4161
|
+
var PRODUCTION_REPOSITORY = "kernel.repository.xml";
|
|
4162
|
+
var TEST_MINT_REPOSITORY = "kernel-testmint.repository.xml";
|
|
23
4163
|
var _refreshedDirs = /* @__PURE__ */ new Set();
|
|
24
4164
|
function runtimeIsWarm(dir, freshMs = RUNTIME_FRESH_MS) {
|
|
25
4165
|
try {
|
|
26
|
-
const
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
4166
|
+
const mtimes = [
|
|
4167
|
+
"holon.wasm",
|
|
4168
|
+
"holon-testmint.wasm",
|
|
4169
|
+
PRODUCTION_REPOSITORY,
|
|
4170
|
+
TEST_MINT_REPOSITORY,
|
|
4171
|
+
"bootstrap.law.usdz",
|
|
4172
|
+
"nomos.law.usdz"
|
|
4173
|
+
].map((name) => statSync(join(dir, name)).mtimeMs);
|
|
4174
|
+
return Date.now() - Math.min(...mtimes) < freshMs;
|
|
31
4175
|
} catch {
|
|
32
4176
|
return false;
|
|
33
4177
|
}
|
|
@@ -38,63 +4182,126 @@ function atomicWrite(target, data) {
|
|
|
38
4182
|
renameSync(tmp, target);
|
|
39
4183
|
}
|
|
40
4184
|
var sha256 = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
41
|
-
function
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
4185
|
+
function satisfies(resource, requirements) {
|
|
4186
|
+
return requirements.every((requirement) => resource.contracts.some((contract) => contract.name === requirement.name && contract.versions.includes(requirement.version)));
|
|
4187
|
+
}
|
|
4188
|
+
function readSelectedResource(dir, repositoryFile, identityType) {
|
|
4189
|
+
const resource = requireSingleOsgiResource(readFileSync(join(dir, repositoryFile), "utf8"));
|
|
4190
|
+
if (resource.identityType !== identityType) {
|
|
4191
|
+
throw new Error(`${repositoryFile} selects ${resource.identityType}, expected ${identityType}`);
|
|
4192
|
+
}
|
|
4193
|
+
return resource;
|
|
4194
|
+
}
|
|
4195
|
+
function runtimeCompatibilityMismatch(dir, requirements = NOMOS_KERNEL_REQUIREMENTS) {
|
|
4196
|
+
for (const [label, repositoryFile, identityType, artifactFile] of [
|
|
4197
|
+
["production", PRODUCTION_REPOSITORY, "nomos.kernel.production", "holon.wasm"],
|
|
4198
|
+
["test-mint", TEST_MINT_REPOSITORY, "nomos.kernel.test-mint", "holon-testmint.wasm"]
|
|
4199
|
+
]) {
|
|
4200
|
+
try {
|
|
4201
|
+
const resource = readSelectedResource(dir, repositoryFile, identityType);
|
|
4202
|
+
if (!satisfies(resource, requirements)) {
|
|
4203
|
+
return `${label} OSGi resource does not satisfy this host's kernel contracts`;
|
|
4204
|
+
}
|
|
4205
|
+
if (resource.contentMime !== "application/wasm") {
|
|
4206
|
+
return `${label} OSGi resource declares ${resource.contentMime}, not application/wasm`;
|
|
4207
|
+
}
|
|
4208
|
+
const bytes = readFileSync(join(dir, artifactFile));
|
|
4209
|
+
if (bytes.byteLength !== resource.contentSize) {
|
|
4210
|
+
return `${label} kernel has ${bytes.byteLength} bytes; OSGi resource declares ${resource.contentSize}`;
|
|
4211
|
+
}
|
|
4212
|
+
const actual = sha256(bytes);
|
|
4213
|
+
if (actual !== resource.contentSha256) {
|
|
4214
|
+
return `${label} kernel ${actual.slice(0, 12)}\u2026 does not match OSGi content ${resource.contentSha256.slice(0, 12)}\u2026`;
|
|
4215
|
+
}
|
|
4216
|
+
} catch (error) {
|
|
4217
|
+
return `${label} runtime custody is incomplete (${error.message})`;
|
|
50
4218
|
}
|
|
51
|
-
return void 0;
|
|
52
|
-
} catch (error) {
|
|
53
|
-
return `runtime cache is incomplete (${error.message})`;
|
|
54
4219
|
}
|
|
4220
|
+
return void 0;
|
|
55
4221
|
}
|
|
56
|
-
async function
|
|
57
|
-
const
|
|
58
|
-
if (
|
|
59
|
-
const
|
|
60
|
-
|
|
4222
|
+
async function fetchSelectedResource(fetchImpl, repositoryUrl, identityType, requirements) {
|
|
4223
|
+
const response = await fetchImpl(repositoryUrl);
|
|
4224
|
+
if (!response.ok) throw new Error(`${repositoryUrl} \u2192 ${response.status}`);
|
|
4225
|
+
const xml = await response.text();
|
|
4226
|
+
const resource = requireSingleOsgiResource(xml);
|
|
4227
|
+
if (resource.identityType !== identityType) {
|
|
4228
|
+
throw new Error(`${repositoryUrl} selected ${resource.identityType}, expected ${identityType}`);
|
|
4229
|
+
}
|
|
4230
|
+
if (!satisfies(resource, requirements)) {
|
|
4231
|
+
throw new Error(`${repositoryUrl} selected a kernel incompatible with the host's OSGi contracts`);
|
|
4232
|
+
}
|
|
4233
|
+
if (resource.contentMime !== "application/wasm") {
|
|
4234
|
+
throw new Error(`${repositoryUrl} selected ${resource.contentMime}, not application/wasm`);
|
|
4235
|
+
}
|
|
4236
|
+
return { xml, resource };
|
|
4237
|
+
}
|
|
4238
|
+
async function fetchVerifiedBytes(fetchImpl, repositoryUrl, resource) {
|
|
4239
|
+
const artifactUrl = new URL(resource.contentUrl, repositoryUrl).toString();
|
|
4240
|
+
const response = await fetchImpl(artifactUrl);
|
|
4241
|
+
if (!response.ok) throw new Error(`${artifactUrl} \u2192 ${response.status}`);
|
|
4242
|
+
const bytes = new Uint8Array(await response.arrayBuffer());
|
|
4243
|
+
if (bytes.byteLength !== resource.contentSize) {
|
|
4244
|
+
throw new Error(`${artifactUrl} has ${bytes.byteLength} bytes; OSGi resource declares ${resource.contentSize}`);
|
|
4245
|
+
}
|
|
4246
|
+
const actual = sha256(bytes);
|
|
4247
|
+
if (actual !== resource.contentSha256) {
|
|
4248
|
+
throw new Error(`${artifactUrl} digest ${actual} does not match OSGi content ${resource.contentSha256}`);
|
|
4249
|
+
}
|
|
4250
|
+
return bytes;
|
|
4251
|
+
}
|
|
4252
|
+
async function refreshRuntimeDir(cloud, dir, {
|
|
4253
|
+
fetchImpl = globalThis.fetch,
|
|
4254
|
+
log: log2,
|
|
4255
|
+
mode,
|
|
4256
|
+
requirements = NOMOS_KERNEL_REQUIREMENTS
|
|
4257
|
+
} = {}) {
|
|
4258
|
+
const selectedMode = String(mode ?? process.env["NOMOS_RUNTIME_REFRESH"] ?? "auto").toLowerCase();
|
|
4259
|
+
if (selectedMode === "never") return false;
|
|
4260
|
+
const coherent = runtimeCompatibilityMismatch(dir, requirements) === void 0;
|
|
4261
|
+
if (selectedMode !== "always") {
|
|
61
4262
|
if (coherent && _refreshedDirs.has(dir)) return false;
|
|
62
4263
|
if (coherent && runtimeIsWarm(dir)) return false;
|
|
63
4264
|
}
|
|
4265
|
+
const base = cloud.replace(/\/+$/, "");
|
|
64
4266
|
try {
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
const
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
4267
|
+
const productionUrl = `${base}/v1/runtime/kernels/production.repository.xml`;
|
|
4268
|
+
const testMintUrl = `${base}/v1/runtime/kernels/test-mint.repository.xml`;
|
|
4269
|
+
const production = await fetchSelectedResource(
|
|
4270
|
+
fetchImpl,
|
|
4271
|
+
productionUrl,
|
|
4272
|
+
"nomos.kernel.production",
|
|
4273
|
+
requirements
|
|
4274
|
+
);
|
|
4275
|
+
const testMint = await fetchSelectedResource(
|
|
4276
|
+
fetchImpl,
|
|
4277
|
+
testMintUrl,
|
|
4278
|
+
"nomos.kernel.test-mint",
|
|
4279
|
+
requirements
|
|
4280
|
+
);
|
|
4281
|
+
const [productionBytes, testMintBytes, bootstrapResponse, nomosResponse] = await Promise.all([
|
|
4282
|
+
fetchVerifiedBytes(fetchImpl, productionUrl, production.resource),
|
|
4283
|
+
fetchVerifiedBytes(fetchImpl, testMintUrl, testMint.resource),
|
|
4284
|
+
fetchImpl(`${base}/v1/runtime/bootstrap.law.usdz`),
|
|
4285
|
+
fetchImpl(`${base}/v1/runtime/nomos.law.usdz`)
|
|
4286
|
+
]);
|
|
4287
|
+
if (!bootstrapResponse.ok) throw new Error(`bootstrap law \u2192 ${bootstrapResponse.status}`);
|
|
4288
|
+
if (!nomosResponse.ok) throw new Error(`Nomos law \u2192 ${nomosResponse.status}`);
|
|
4289
|
+
const [bootstrapBytes, nomosBytes] = await Promise.all([
|
|
4290
|
+
bootstrapResponse.arrayBuffer().then((bytes) => new Uint8Array(bytes)),
|
|
4291
|
+
nomosResponse.arrayBuffer().then((bytes) => new Uint8Array(bytes))
|
|
4292
|
+
]);
|
|
86
4293
|
mkdirSync(dir, { recursive: true });
|
|
87
|
-
atomicWrite(join(dir, "holon.wasm"),
|
|
88
|
-
atomicWrite(join(dir, "holon-testmint.wasm"),
|
|
4294
|
+
atomicWrite(join(dir, "holon.wasm"), productionBytes);
|
|
4295
|
+
atomicWrite(join(dir, "holon-testmint.wasm"), testMintBytes);
|
|
4296
|
+
atomicWrite(join(dir, PRODUCTION_REPOSITORY), production.xml);
|
|
4297
|
+
atomicWrite(join(dir, TEST_MINT_REPOSITORY), testMint.xml);
|
|
89
4298
|
atomicWrite(join(dir, "bootstrap.law.usdz"), bootstrapBytes);
|
|
90
4299
|
atomicWrite(join(dir, "nomos.law.usdz"), nomosBytes);
|
|
91
4300
|
_refreshedDirs.add(dir);
|
|
92
|
-
|
|
4301
|
+
log2?.(`offline-install: refreshed OSGi-selected runtime custody from the cloud \u2192 ${dir}`);
|
|
93
4302
|
return true;
|
|
94
4303
|
} catch (error) {
|
|
95
|
-
|
|
96
|
-
log2(`offline-install: release-pinned runtime refresh failed: ${error.message}`);
|
|
97
|
-
}
|
|
4304
|
+
log2?.(`offline-install: OSGi runtime refresh failed: ${error.message}`);
|
|
98
4305
|
return false;
|
|
99
4306
|
}
|
|
100
4307
|
}
|
|
@@ -169,7 +4376,7 @@ __export(engine_exports, {
|
|
|
169
4376
|
intentOfferSizeRefusal: () => intentOfferSizeRefusal,
|
|
170
4377
|
isDirty: () => isDirty,
|
|
171
4378
|
isWarranted: () => isWarranted,
|
|
172
|
-
|
|
4379
|
+
kernelResource: () => kernelResource,
|
|
173
4380
|
kgit: () => kgit,
|
|
174
4381
|
lawParity: () => lawParity,
|
|
175
4382
|
ledgerStats: () => ledgerStats,
|
|
@@ -1724,8 +5931,8 @@ function makeGitFs(preopen, mount, { File: File2, Directory: Directory2 }) {
|
|
|
1724
5931
|
var enc = new TextEncoder();
|
|
1725
5932
|
var dec = new TextDecoder();
|
|
1726
5933
|
function flatten(dir, prefix, out) {
|
|
1727
|
-
const
|
|
1728
|
-
for (const [name, inode] of
|
|
5934
|
+
const children2 = [...(dir.contents ?? /* @__PURE__ */ new Map()).entries()].sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0);
|
|
5935
|
+
for (const [name, inode] of children2) {
|
|
1729
5936
|
const path = prefix ? prefix + "/" + name : name;
|
|
1730
5937
|
if (inode.contents instanceof Map) {
|
|
1731
5938
|
out.push({ path, dir: true });
|
|
@@ -5541,57 +9748,57 @@ function writeTypeOfScalar(type) {
|
|
|
5541
9748
|
}
|
|
5542
9749
|
|
|
5543
9750
|
// src/_adapter/proto/nomos/kernel/v1/kernel_pb.js
|
|
5544
|
-
var file_nomos_kernel_v1_kernel = /* @__PURE__ */ fileDesc("Chxub21vcy9rZXJuZWwvdjEva2VybmVsLnByb3RvEg9ub21vcy5rZXJuZWwudjEimAMKC0NhbGxSZXF1ZXN0EhgKEHByb3RvY29sX3ZlcnNpb24YASABKA0SEgoKcmVxdWVzdF9pZBgCIAEoCRIsCgRvcGVuGAogASgLMhwubm9tb3Mua2VybmVsLnYxLk9wZW5SZXF1ZXN0SAASLgoFb2ZmZXIYCyABKAsyHS5ub21vcy5rZXJuZWwudjEuT2ZmZXJSZXF1ZXN0SAASLgoFcXVlcnkYDCABKAsyHS5ub21vcy5rZXJuZWwudjEuUXVlcnlSZXF1ZXN0SAASMAoGb3V0Ym94GA0gASgLMh4ubm9tb3Mua2VybmVsLnYxLk91dGJveFJlcXVlc3RIABIsCgRzeW5jGA4gASgLMhwubm9tb3Mua2VybmVsLnYxLlN5bmNSZXF1ZXN0SAASMgoHY3VzdG9keRgPIAEoCzIfLm5vbW9zLmtlcm5lbC52MS5DdXN0b2R5UmVxdWVzdEgAEiwKBHRlc3QYECABKAsyHC5ub21vcy5rZXJuZWwudjEuVGVzdFJlcXVlc3RIAEILCglvcGVyYXRpb24iywMKDENhbGxSZXNwb25zZRIYChBwcm90b2NvbF92ZXJzaW9uGAEgASgNEhIKCnJlcXVlc3RfaWQYAiABKAkSKwoHZmFpbHVyZRgKIAEoCzIYLm5vbW9zLmtlcm5lbC52MS5GYWlsdXJlSAASLQoEb3BlbhgLIAEoCzIdLm5vbW9zLmtlcm5lbC52MS5PcGVuUmVzcG9uc2VIABIvCgVvZmZlchgMIAEoCzIeLm5vbW9zLmtlcm5lbC52MS5PZmZlclJlc3BvbnNlSAASLwoFcXVlcnkYDSABKAsyHi5ub21vcy5rZXJuZWwudjEuUXVlcnlSZXNwb25zZUgAEjEKBm91dGJveBgOIAEoCzIfLm5vbW9zLmtlcm5lbC52MS5PdXRib3hSZXNwb25zZUgAEi0KBHN5bmMYDyABKAsyHS5ub21vcy5rZXJuZWwudjEuU3luY1Jlc3BvbnNlSAASMwoHY3VzdG9keRgQIAEoCzIgLm5vbW9zLmtlcm5lbC52MS5DdXN0b2R5UmVzcG9uc2VIABItCgR0ZXN0GBEgASgLMh0ubm9tb3Mua2VybmVsLnYxLlRlc3RSZXNwb25zZUgAQgkKB291dGNvbWUiVwoHRmFpbHVyZRIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSLQoHZGV0YWlscxgDIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdCI8CgxPcGVuUmVzcG9uc2USLAoGcmVzdWx0GAEgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0IsMCCg1PZmZlclJlc3BvbnNlEjIKCGFkbWl0dGVkGAEgASgLMh4ubm9tb3Mua2VybmVsLnYxLk9mZmVyQWRtaXR0ZWRIABIwCgdyZWZ1c2VkGAIgASgLMh0ubm9tb3Mua2VybmVsLnYxLk9mZmVyUmVmdXNlZEgAEjsKDWRlYWRfbGV0dGVyZWQYAyABKAsyIi5ub21vcy5rZXJuZWwudjEuT2ZmZXJEZWFkTGV0dGVyZWRIABI4CgtxdWFyYW50aW5lZBgEIAEoCzIhLm5vbW9zLmtlcm5lbC52MS5PZmZlclF1YXJhbnRpbmVkSAASSgoVYmxvY2tlZF9vbl9kZXBlbmRlbmN5GAUgASgLMikubm9tb3Mua2VybmVsLnYxLk9mZmVyQmxvY2tlZE9uRGVwZW5kZW5jeUgAQgkKB291dGNvbWUiPQoNT2ZmZXJBZG1pdHRlZBIsCgZyZXN1bHQYASABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3QilgEKDE9mZmVyUmVmdXNlZBIVCghvZmZlcl9pZBgBIAEoCUgAiAEBEi8KB3JlZnVzYWwYAiABKAsyHi5ub21vcy5rZXJuZWwudjEuS2VybmVsUmVmdXNhbBIxCgtkaWFnbm9zdGljcxgDIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdEILCglfb2ZmZXJfaWQiegoRT2ZmZXJEZWFkTGV0dGVyZWQSFQoIb2ZmZXJfaWQYASABKAlIAIgBARIOCgZyZWFzb24YAiABKAkSMQoLZGlhZ25vc3RpY3MYAyABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3RCCwoJX29mZmVyX2lkIq4BChBPZmZlclF1YXJhbnRpbmVkEhUKCG9mZmVyX2lkGAEgASgJSACIAQESGQoRYXV0aG9yZWRfbGF3X2hhc2gYAiABKAkSGAoQY3VycmVudF9sYXdfaGFzaBgDIAEoCRIOCgZyZWFzb24YBCABKAkSMQoLZGlhZ25vc3RpY3MYBSABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3RCCwoJX29mZmVyX2lkIoEBChhPZmZlckJsb2NrZWRPbkRlcGVuZGVuY3kSFQoIb2ZmZXJfaWQYASABKAlIAIgBARIOCgZkZXRhaWwYAiABKAkSMQoLZGlhZ25vc3RpY3MYAyABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3RCCwoJX29mZmVyX2lkIoEBCg1LZXJuZWxSZWZ1c2FsEjAKBGNvZGUYASABKA4yIi5ub21vcy5rZXJuZWwudjEuS2VybmVsUmVmdXNhbENvZGUSDwoHbWVzc2FnZRgCIAEoCRItCgdkZXRhaWxzGAMgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0Iu8CCg1RdWVyeVJlc3BvbnNlEiwKBXZhbHVlGAEgASgLMhsubm9tb3Mua2VybmVsLnYxLk5vbW9zVmFsdWVIABJBChBhcHBsaWNhdGlvbl9qc29uGAIgASgLMiUubm9tb3Mua2VybmVsLnYxLkFwcGxpY2F0aW9uSnNvblZhbHVlSAASSgoTYXV0aG9yaXphdGlvbl9jaGVjaxgKIAEoCzIrLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uQ2hlY2tSZXNwb25zZUgAEkwKFGF1dGhvcml6YXRpb25fZXhwYW5kGAsgASgLMiwubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25FeHBhbmRSZXNwb25zZUgAEkkKGHZlcmlmeV9jaGFpbl9kaWFnbm9zdGljcxgUIAEoCzInLm5vbW9zLmtlcm5lbC52MS5WZXJpZnlDaGFpbkRpYWdub3N0aWNzQggKBnJlc3VsdCLnAQoTVmVyaWZ5Q2hhaW5TdGVwU3BhbhINCgVpbmRleBgBIAEoBBISCgpjb21taXRfb2lkGAIgASgJEg4KBmRvbWFpbhgDIAEoCRIRCglkaXJlY3RpdmUYBCABKAkSEAoIdG90YWxfdXMYBSABKAQSNgoGcGhhc2VzGAYgASgLMiYubm9tb3Mua2VybmVsLnYxLlZlcmlmeUNoYWluU3RlcFBoYXNlcxJACg5lbmdpbmVfdGltaW5ncxgHIAMoCzIoLm5vbW9zLmtlcm5lbC52MS5WZXJpZnlDaGFpbkVuZ2luZVRpbWluZyKYAgoVVmVyaWZ5Q2hhaW5TdGVwUGhhc2VzEh4KFnJ1bnRpbWVfbGF3X3JlZnJlc2hfdXMYASABKAQSEwoLbWFuaWZlc3RfdXMYAiABKAQSGQoRbGF3X3Jlc29sdXRpb25fdXMYAyABKAQSHQoVbWFuYWdlZF90cmFuc2l0aW9uX3VzGAQgASgEEhQKDHByaW5jaXBhbF91cxgFIAEoBBIUCgxldm9sdXRpb25fdXMYBiABKAQSGgoSY29sb2NhdGVkX3JlYWRzX3VzGAcgASgEEiEKGXR5cGVkX2luc3RhbGxfdmVyaWZpZXJfdXMYCCABKAQSFAoMYWRtaXNzaW9uX3VzGAkgASgEEg8KB2ZvbGRfdXMYCiABKAQi2gUKFlZlcmlmeUNoYWluRGlhZ25vc3RpY3MSLgoEd2FsaxgBIAEoDjIgLm5vbW9zLmtlcm5lbC52MS5WZXJpZnlDaGFpbldhbGsSEAoIdG90YWxfdXMYAiABKAQSGwoTcmVmZXJlbmNlX2xvb2t1cF91cxgDIAEoBBIaChJyZXBvc2l0b3J5X29wZW5fdXMYBCABKAQSFQoNY2hhaW5fcmVhZF91cxgFIAEoBBIWCg5lbmdpbmVfaW5pdF91cxgGIAEoBBIYChB0aW1lbGluZV9yZWFkX3VzGAcgASgEEhgKEGxhd19oeWRyYXRpb25fdXMYCCABKAQSGwoTcmVjb3ZlcnlfcHJlc2Nhbl91cxgJIAEoBBIYChBmb2xkX2Zyb250aWVyX3VzGAogASgEEjMKBXN0ZXBzGAsgAygLMiQubm9tb3Mua2VybmVsLnYxLlZlcmlmeUNoYWluU3RlcFNwYW4SQAoOZW5naW5lX3RpbWluZ3MYDCADKAsyKC5ub21vcy5rZXJuZWwudjEuVmVyaWZ5Q2hhaW5FbmdpbmVUaW1pbmcSTQoVbGF3X2h5ZHJhdGlvbl90aW1pbmdzGA0gAygLMi4ubm9tb3Mua2VybmVsLnYxLlZlcmlmeUNoYWluTGF3SHlkcmF0aW9uVGltaW5nEhkKEWxhd19jbG9zdXJlX2NvdW50GA4gASgEEh4KFmxhd19jbG9zdXJlX2NhY2hlX2hpdHMYDyABKAQSIAoYbGF3X2Nsb3N1cmVfY2FjaGVfbWlzc2VzGBAgASgEEhIKCnN0ZXBfY291bnQYESABKAQSFQoNc3RlcF90b3RhbF91cxgSIAEoBBJBChFzdGVwX3BoYXNlX3RvdGFscxgTIAEoCzImLm5vbW9zLmtlcm5lbC52MS5WZXJpZnlDaGFpblN0ZXBQaGFzZXMSGgoSb21pdHRlZF9zdGVwX2NvdW50GBQgASgEIjoKF1ZlcmlmeUNoYWluRW5naW5lVGltaW5nEg0KBXBoYXNlGAEgASgJEhAKCHRvdGFsX3VzGAIgASgEIkAKHVZlcmlmeUNoYWluTGF3SHlkcmF0aW9uVGltaW5nEg0KBXBoYXNlGAEgASgJEhAKCHRvdGFsX3VzGAIgASgEIiQKFEFwcGxpY2F0aW9uSnNvblZhbHVlEgwKBHV0ZjgYASABKAwitgIKDU91dGJvdW5kT2ZmZXISCgoCaWQYASABKAkSEwoLZGVzdGluYXRpb24YAiABKAkSFAoMc2VhbGVkX29mZmVyGAMgASgMEhQKDGNvbnRlbnRfdHlwZRgEIAEoCRIYChBzb3VyY2Vfd29ya3NwYWNlGAUgASgJEhQKDGN1c3RvZHlfaGVhZBgGIAEoCRIXCg9jYXVzZWRfYnlfb2ZmZXIYByABKAkSGwoTc2NoZWR1bGVkX2F0X21pbGxpcxgIIAEoBBIaChJkZWFkbGluZV9hdF9taWxsaXMYCSABKAQSFAoMY3VzdG9keV9wYXRoGAogASgJEhMKC2N1c3RvZHlfb2lkGAsgASgJEhQKDGRlbGl2ZXJ5X3JlZhgMIAEoCRIVCg1vYmxpZ2F0aW9uX2lkGA0gASgJIngKDk91dGJveFJlc3BvbnNlEi4KBm9mZmVycxgBIAMoCzIeLm5vbW9zLmtlcm5lbC52MS5PdXRib3VuZE9mZmVyEh8KEm5leHRfZHVlX2F0X21pbGxpcxgCIAEoBEgAiAEBQhUKE19uZXh0X2R1ZV9hdF9taWxsaXMiPAoMU3luY1Jlc3BvbnNlEiwKBnJlc3VsdBgBIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdCJCCg9Xb3Jrc3BhY2VUYXJnZXQSDAoEcmVwbxgBIAEoCRIRCgl3b3Jrc3BhY2UYAiABKAkSDgoGYnJhbmNoGAMgASgJIk4KC09wZW5SZXF1ZXN0EjAKBnRhcmdldBgBIAEoCzIgLm5vbW9zLmtlcm5lbC52MS5Xb3Jrc3BhY2VUYXJnZXQSDQoFc3BhbnMYAiABKAgiYQoNRGlyZWN0aXZlQ2FsbBIOCgZkb21haW4YASABKAkSEQoJZGlyZWN0aXZlGAIgASgJEi0KB3BheWxvYWQYAyABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3QiwAIKEEF1dGhvcmluZ09wdGlvbnMSDQoFYWN0b3IYASABKAkSEgoKYXV0aF90b2tlbhgCIAEoDBIVCg1hdXRob3Jfc2VjcmV0GAMgASgMEh0KEHZhbGlkX2Zyb21fZXBvY2gYBCABKARIAIgBARIfChJwcmluY2lwYWxfdmVyaWZpZWQYBSABKAhIAYgBARILCgNybmcYBiADKAESGAoQZGVmZXJfcHJvamVjdGlvbhgHIAEoCBINCgVzcGFucxgIIAEoCBIPCgdkcnlfcnVuGAkgASgIEhAKCHNlcXVlbmNlGAogASgEEi0KBWNsb2NrGAsgASgLMh4ubm9tb3Mua2VybmVsLnYxLkNhcHR1cmVkQ2xvY2tCEwoRX3ZhbGlkX2Zyb21fZXBvY2hCFQoTX3ByaW5jaXBhbF92ZXJpZmllZCJKCg1DYXB0dXJlZENsb2NrEhcKD3BoeXNpY2FsX21pbGxpcxgBIAEoBBIPCgdsb2dpY2FsGAIgASgNEg8KB3JlcGxpY2EYAyABKAQiwwMKEEJpcnRoQ2VydGlmaWNhdGUSDQoFY2hpbGQYASABKAkSDwoHZm91bmRlchgCIAEoCRIQCgh2ZXJpZmllZBgDIAEoCBISCgpwYXJlbnRfa2V5GAQgASgMEhEKCXBhcmVudF9pZBgFIAEoCRINCgVlcG9jaBgGIAEoAxIRCglzaWduYXR1cmUYByABKAwSGQoMdmVyaWZpZWRfdmlhGAggASgJSACIAQESFgoJaWRwX3Rva2VuGAkgASgJSAGIAQESGwoOY2FwdHVyZWRfY2xvY2sYCiABKANIAogBARIhChRhdXRoX3Byb3ZpZGVyX2lzc3VlchgLIAEoCUgDiAEBEh8KEmF1dGhfcHJvdmlkZXJfandrcxgMIAEoCUgEiAEBEiMKFmF1dGhfcHJvdmlkZXJfYXVkaWVuY2UYDSABKAlIBYgBAUIPCg1fdmVyaWZpZWRfdmlhQgwKCl9pZHBfdG9rZW5CEQoPX2NhcHR1cmVkX2Nsb2NrQhcKFV9hdXRoX3Byb3ZpZGVyX2lzc3VlckIVChNfYXV0aF9wcm92aWRlcl9qd2tzQhkKF19hdXRoX3Byb3ZpZGVyX2F1ZGllbmNlIpwECgxPZmZlclJlcXVlc3QSMAoGdGFyZ2V0GAEgASgLMiAubm9tb3Mua2VybmVsLnYxLldvcmtzcGFjZVRhcmdldBIuCgRjYWxsGAIgASgLMh4ubm9tb3Mua2VybmVsLnYxLkRpcmVjdGl2ZUNhbGxIABIcChJzZWFsZWRfY2hhbmdlX3VzZGEYByABKAxIABI0CglhdXRob3JpbmcYAyABKAsyIS5ub21vcy5rZXJuZWwudjEuQXV0aG9yaW5nT3B0aW9ucxIQCghsYXdfdXNkehgEIAEoDBIzCgxhdHRlc3RhdGlvbnMYBSADKAsyHS5ub21vcy5rZXJuZWwudjEuQXR0ZXN0ZWRSZWFkEj0KEmNvbmZsaWN0X3NuYXBzaG90cxgGIAMoCzIhLm5vbW9zLmtlcm5lbC52MS5Db25mbGljdFNuYXBzaG90EhoKEmV4ZWN1dGlvbl9sYXdfdXNkehgIIAEoDBIgChNjb250cm9sbGVyX2xhd19oYXNoGAkgASgJSAGIAQESHQoQY2FuZGlkYXRlX2NvbW1pdBgKIAEoCUgCiAEBEjwKEWJpcnRoX2NlcnRpZmljYXRlGAsgASgLMiEubm9tb3Mua2VybmVsLnYxLkJpcnRoQ2VydGlmaWNhdGVCCAoGaW50ZW50QhYKFF9jb250cm9sbGVyX2xhd19oYXNoQhMKEV9jYW5kaWRhdGVfY29tbWl0IpMBCgxBdHRlc3RlZFJlYWQSEAoIcXVlcnlfaWQYASABKAkSLwoJYXJndW1lbnRzGAIgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0EisKBnJlc3VsdBgDIAEoCzIbLm5vbW9zLmtlcm5lbC52MS5Ob21vc1ZhbHVlEhMKC2F0dGVzdGF0aW9uGAQgASgMInUKEENvbmZsaWN0U25hcHNob3QSFgoOYWdncmVnYXRlX3R5cGUYASABKAkSFAoMYWdncmVnYXRlX2lkGAIgASgJEg0KBWZpZWxkGAMgASgJEhUKDXRhcmdldF9zY2hlbWEYBCABKAkSDQoFdG9rZW4YBSABKAki5QUKDFF1ZXJ5UmVxdWVzdBIwCgZ0YXJnZXQYASABKAsyIC5ub21vcy5rZXJuZWwudjEuV29ya3NwYWNlVGFyZ2V0EjIKCWF1dGhvcml0eRgCIAEoCzIfLm5vbW9zLmtlcm5lbC52MS5RdWVyeUF1dGhvcml0eRINCgVzcGFucxgDIAEoCBIqCgRyb3dzGAogASgLMhoubm9tb3Mua2VybmVsLnYxLlJvd3NRdWVyeUgAEioKBHBhZ2UYCyABKAsyGi5ub21vcy5rZXJuZWwudjEuUGFnZVF1ZXJ5SAASKwoFYnlfaWQYDCABKAsyGi5ub21vcy5rZXJuZWwudjEuQnlJZFF1ZXJ5SAASOQoMcmVzb2x2ZV9yZWZzGA0gASgLMiEubm9tb3Mua2VybmVsLnYxLlJlc29sdmVSZWZzUXVlcnlIABJFChJyZWZlcmVuY2VfdmVyc2lvbnMYDiABKAsyJy5ub21vcy5rZXJuZWwudjEuUmVmZXJlbmNlVmVyc2lvbnNRdWVyeUgAEiwKBWNvdW50GA8gASgLMhsubm9tb3Mua2VybmVsLnYxLlRhbGx5UXVlcnlIABIqCgNzdW0YECABKAsyGy5ub21vcy5rZXJuZWwudjEuVGFsbHlRdWVyeUgAEjAKB3NwYXRpYWwYESABKAsyHS5ub21vcy5rZXJuZWwudjEuU3BhdGlhbFF1ZXJ5SAASLAoFbmFtZWQYEiABKAsyGy5ub21vcy5rZXJuZWwudjEuTmFtZWRRdWVyeUgAEkkKE2F1dGhvcml6YXRpb25fY2hlY2sYEyABKAsyKi5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbkNoZWNrUmVxdWVzdEgAEksKFGF1dGhvcml6YXRpb25fZXhwYW5kGBQgASgLMisubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25FeHBhbmRSZXF1ZXN0SABCBwoFcXVlcnkikgEKDlF1ZXJ5QXV0aG9yaXR5EhcKD3ByaW5jaXBhbF9jbGFpbRgBIAEoCRISCgphdXRoX3Rva2VuGAIgASgMEhAKCG5vd191bml4GAMgASgEEhUKDWF1dGhvcl9zZWNyZXQYBCABKAwSKgoEa2V5cxgFIAMoCzIcLm5vbW9zLmtlcm5lbC52MS5JbmplY3RlZEtleSI4CgtJbmplY3RlZEtleRINCgVzY29wZRgBIAEoCRINCgVlcG9jaBgCIAEoBBILCgNrZXkYAyABKAwiWwoJUm93c1F1ZXJ5EgoKAmlkGAEgASgJEi8KCWFyZ3VtZW50cxgCIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdBIRCglwcmluY2lwYWwYAyABKAkieQoJUGFnZVF1ZXJ5EgoKAmlkGAEgASgJEi8KCWFyZ3VtZW50cxgCIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdBINCgVsaW1pdBgDIAEoDRINCgVhZnRlchgEIAEoCRIRCglwcmluY2lwYWwYBSABKAkiTAoJQnlJZFF1ZXJ5EhYKDmFnZ3JlZ2F0ZV90eXBlGAEgASgJEhQKDGFnZ3JlZ2F0ZV9pZBgCIAEoCRIRCglwcmluY2lwYWwYAyABKAkiXAoITm9tb3NSZWYSEQoJd29ya3NwYWNlGAEgASgJEhYKDmFnZ3JlZ2F0ZV90eXBlGAIgASgJEhQKDGFnZ3JlZ2F0ZV9pZBgDIAEoCRIPCgd2ZXJzaW9uGAQgASgJIk4KEFJlc29sdmVSZWZzUXVlcnkSJwoEcmVmcxgBIAMoCzIZLm5vbW9zLmtlcm5lbC52MS5Ob21vc1JlZhIRCglwcmluY2lwYWwYAiABKAkiTgoWUmVmZXJlbmNlVmVyc2lvbnNRdWVyeRI0CgRyZWZzGAEgAygLMiYubm9tb3Mua2VybmVsLnYxLlJlZmVyZW5jZVZlcnNpb25DaGVjayKEAQoVUmVmZXJlbmNlVmVyc2lvbkNoZWNrEikKBnBpbm5lZBgBIAEoCzIZLm5vbW9zLmtlcm5lbC52MS5Ob21vc1JlZhIpCgZzZXJpZXMYAiABKAsyGS5ub21vcy5rZXJuZWwudjEuTm9tb3NSZWYSFQoNY3VycmVudF9maWVsZBgDIAEoCSJcCgpUYWxseVF1ZXJ5EgoKAmlkGAEgASgJEi8KCWFyZ3VtZW50cxgCIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdBIRCglwcmluY2lwYWwYAyABKAkiXgoMU3BhdGlhbFF1ZXJ5EgoKAmlkGAEgASgJEi8KCWFyZ3VtZW50cxgCIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdBIRCglwcmluY2lwYWwYAyABKAkicQoKTmFtZWRRdWVyeRIyCglvcGVyYXRpb24YASABKA4yHy5ub21vcy5rZXJuZWwudjEuUXVlcnlPcGVyYXRpb24SLwoJYXJndW1lbnRzGAIgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0Ii8KE0F1dGhvcml6YXRpb25PYmplY3QSDAoEdHlwZRgBIAEoCRIKCgJpZBgCIAEoCSJUChRBdXRob3JpemF0aW9uU3ViamVjdBIMCgR0eXBlGAEgASgJEgoKAmlkGAIgASgJEhUKCHJlbGF0aW9uGAMgASgJSACIAQFCCwoJX3JlbGF0aW9uIpwBChhSZWxhdGlvbnNoaXBUdXBsZUFkZHJlc3MSNgoIcmVzb3VyY2UYASABKAsyJC5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbk9iamVjdBIQCghyZWxhdGlvbhgCIAEoCRI2CgdzdWJqZWN0GAMgASgLMiUubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25TdWJqZWN0IoEBChhBdXRob3JpemF0aW9uQ29uc2lzdGVuY3kSIwoZY3VycmVudF92ZXJpZmllZF9mcm9udGllchgBIAEoCEgAEhkKD2F0X2xlYXN0X2NvbW1pdBgCIAEoCUgAEhYKDGV4YWN0X2NvbW1pdBgDIAEoCUgAQg0KC3JlcXVpcmVtZW50ImYKHUF1dGhvcml6YXRpb25Db25kaXRpb25Db250ZXh0EhQKDGNvbmRpdGlvbl9pZBgBIAEoCRIvCglhcmd1bWVudHMYAiABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3Qi9wIKGUF1dGhvcml6YXRpb25DaGVja1JlcXVlc3QSNgoIcmVzb3VyY2UYASABKAsyJC5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbk9iamVjdBISCgpwZXJtaXNzaW9uGAIgASgJEjYKB3N1YmplY3QYAyABKAsyJS5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvblN1YmplY3QSPgoLY29uc2lzdGVuY3kYBCABKAsyKS5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbkNvbnNpc3RlbmN5Ej8KB2NvbnRleHQYBSADKAsyLi5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbkNvbmRpdGlvbkNvbnRleHQSIAoTZXhwZWN0ZWRfbW9kZWxfaGFzaBgGIAEoCUgAiAEBEhsKE2luY2x1ZGVfZXhwbGFuYXRpb24YByABKAhCFgoUX2V4cGVjdGVkX21vZGVsX2hhc2gi7QIKGkF1dGhvcml6YXRpb25FeHBhbmRSZXF1ZXN0EjYKCHJlc291cmNlGAEgASgLMiQubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25PYmplY3QSEgoKcGVybWlzc2lvbhgCIAEoCRI+Cgtjb25zaXN0ZW5jeRgDIAEoCzIpLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uQ29uc2lzdGVuY3kSPwoHY29udGV4dBgEIAMoCzIuLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uQ29uZGl0aW9uQ29udGV4dBIgChNleHBlY3RlZF9tb2RlbF9oYXNoGAUgASgJSACIAQESDQoFbGltaXQYBiABKA0SEgoFYWZ0ZXIYByABKAlIAYgBARIbChNpbmNsdWRlX2V4cGxhbmF0aW9uGAggASgIQhYKFF9leHBlY3RlZF9tb2RlbF9oYXNoQggKBl9hZnRlciK9AQoZUmVsYXRpb25zaGlwVHVwbGVFdmlkZW5jZRI4CgV0dXBsZRgBIAEoCzIpLm5vbW9zLmtlcm5lbC52MS5SZWxhdGlvbnNoaXBUdXBsZUFkZHJlc3MSEAoIdHVwbGVfaWQYAiABKAkSGgoSYXNzZXJ0aW9uX2V2ZW50X2lkGAMgASgJEiAKE3Jldm9jYXRpb25fZXZlbnRfaWQYBCABKAlIAIgBAUIWChRfcmV2b2NhdGlvbl9ldmVudF9pZCLhAwoYQXV0aG9yaXphdGlvbkV4cGxhbmF0aW9uEkYKCW9wZXJhdGlvbhgBIAEoDjIzLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uRXhwbGFuYXRpb24uT3BlcmF0aW9uEhAKCHJlbGF0aW9uGAIgASgJEg4KBnJlc3VsdBgDIAEoCBI8CghldmlkZW5jZRgEIAMoCzIqLm5vbW9zLmtlcm5lbC52MS5SZWxhdGlvbnNoaXBUdXBsZUV2aWRlbmNlEjsKCGNoaWxkcmVuGAUgAygLMikubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25FeHBsYW5hdGlvbiLfAQoJT3BlcmF0aW9uEhkKFU9QRVJBVElPTl9VTlNQRUNJRklFRBAAEhQKEE9QRVJBVElPTl9ESVJFQ1QQARIeChpPUEVSQVRJT05fQ09NUFVURURfVVNFUlNFVBACEh4KGk9QRVJBVElPTl9UVVBMRV9UT19VU0VSU0VUEAMSEwoPT1BFUkFUSU9OX1VOSU9OEAQSGgoWT1BFUkFUSU9OX0lOVEVSU0VDVElPThAFEhcKE09QRVJBVElPTl9FWENMVVNJT04QBhIXChNPUEVSQVRJT05fQ09ORElUSU9OEAcidwoaQXV0aG9yaXphdGlvbkRlY2lzaW9uQmFzaXMSIAoYYXV0aG9yaXphdGlvbl9tb2RlbF9oYXNoGAEgASgJEiEKGXJlbGF0aW9uc2hpcF9zdGF0ZV9jb21taXQYAiABKAkSFAoMY29udGV4dF9oYXNoGAMgASgMIr4BChpBdXRob3JpemF0aW9uQ2hlY2tSZXNwb25zZRIPCgdhbGxvd2VkGAEgASgIEjoKBWJhc2lzGAIgASgLMisubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25EZWNpc2lvbkJhc2lzEkMKC2V4cGxhbmF0aW9uGAMgASgLMikubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25FeHBsYW5hdGlvbkgAiAEBQg4KDF9leHBsYW5hdGlvbiKDAgobQXV0aG9yaXphdGlvbkV4cGFuZFJlc3BvbnNlEjcKCHN1YmplY3RzGAEgAygLMiUubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25TdWJqZWN0EjoKBWJhc2lzGAIgASgLMisubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25EZWNpc2lvbkJhc2lzEhEKBG5leHQYAyABKAlIAIgBARJDCgtleHBsYW5hdGlvbhgEIAEoCzIpLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uRXhwbGFuYXRpb25IAYgBAUIHCgVfbmV4dEIOCgxfZXhwbGFuYXRpb24icAoNT3V0Ym94UmVxdWVzdBIwCgZ0YXJnZXQYASABKAsyIC5ub21vcy5rZXJuZWwudjEuV29ya3NwYWNlVGFyZ2V0Ei0KBWNsb2NrGAIgASgLMh4ubm9tb3Mua2VybmVsLnYxLkNhcHR1cmVkQ2xvY2siYwoLU3luY1JlcXVlc3QSMAoGdGFyZ2V0GAEgASgLMiAubm9tb3Mua2VybmVsLnYxLldvcmtzcGFjZVRhcmdldBIRCglmcm9tX2Jhc2UYAiABKAkSDwoHdG9faGVhZBgDIAEoCSJTCgtUZXN0UmVxdWVzdBI3CghzZXRfcm9vdBgBIAEoCzIjLm5vbW9zLmtlcm5lbC52MS5TZXRUZXN0Um9vdFJlcXVlc3RIAEILCglvcGVyYXRpb24iKAoSU2V0VGVzdFJvb3RSZXF1ZXN0EhIKCnB1YmxpY19rZXkYASABKAwiPQoMVGVzdFJlc3BvbnNlEi0KBnJlc3VsdBgBIAEoCzIdLm5vbW9zLmtlcm5lbC52MS5BY2tub3dsZWRnZWQitgoKDkN1c3RvZHlSZXF1ZXN0EjcKCnBhY2tfZGVsdGEYCiABKAsyIS5ub21vcy5rZXJuZWwudjEuUGFja0RlbHRhUmVxdWVzdEgAEjcKCmFwcGx5X3BhY2sYCyABKAsyIS5ub21vcy5rZXJuZWwudjEuQXBwbHlQYWNrUmVxdWVzdEgAEjcKCnJlcG9fc3RhdHMYDCABKAsyIS5ub21vcy5rZXJuZWwudjEuUmVwb1N0YXRzUmVxdWVzdEgAEj0KDWludGVudHNfYWJvdmUYDSABKAsyJC5ub21vcy5rZXJuZWwudjEuSW50ZW50c0Fib3ZlUmVxdWVzdEgAEj8KDmluc3BlY3RfY2hhbmdlGA4gASgLMiUubm9tb3Mua2VybmVsLnYxLkluc3BlY3RDaGFuZ2VSZXF1ZXN0SAASTgoWZW5jb2RlX3JlZnVzYWxfdmVyZGljdBgPIAEoCzIsLm5vbW9zLmtlcm5lbC52MS5FbmNvZGVSZWZ1c2FsVmVyZGljdFJlcXVlc3RIABJQChdpbnNwZWN0X3JlZnVzYWxfdmVyZGljdBgQIAEoCzItLm5vbW9zLmtlcm5lbC52MS5JbnNwZWN0UmVmdXNhbFZlcmRpY3RSZXF1ZXN0SAASNQoJcmVhZF9ibG9iGBEgASgLMiAubm9tb3Mua2VybmVsLnYxLlJlYWRCbG9iUmVxdWVzdEgAEjkKC3Jlc29sdmVfcmVmGBIgASgLMiIubm9tb3Mua2VybmVsLnYxLlJlc29sdmVSZWZSZXF1ZXN0SAASNQoJbGlzdF9yZWZzGBMgASgLMiAubm9tb3Mua2VybmVsLnYxLkxpc3RSZWZzUmVxdWVzdEgAEjUKCXdyaXRlX3JlZhgUIAEoCzIgLm5vbW9zLmtlcm5lbC52MS5Xcml0ZVJlZlJlcXVlc3RIABI3CgpkZWxldGVfcmVmGBUgASgLMiEubm9tb3Mua2VybmVsLnYxLkRlbGV0ZVJlZlJlcXVlc3RIABJEChF3cml0ZV9tZXRhX2NvbW1pdBgWIAEoCzInLm5vbW9zLmtlcm5lbC52MS5Xcml0ZU1ldGFDb21taXRSZXF1ZXN0SAASQgoQbGF3X2Nsb3N1cmVfaW5mbxgXIAEoCzImLm5vbW9zLmtlcm5lbC52MS5MYXdDbG9zdXJlSW5mb1JlcXVlc3RIABJFChFjaGVja3BvaW50X2V4cG9ydBgYIAEoCzIoLm5vbW9zLmtlcm5lbC52MS5DaGVja3BvaW50RXhwb3J0UmVxdWVzdEgAEkUKEWNoZWNrcG9pbnRfaW1wb3J0GBkgASgLMigubm9tb3Mua2VybmVsLnYxLkNoZWNrcG9pbnRJbXBvcnRSZXF1ZXN0SAASQwoQY2FwYWNpdHlfcmVzZXJ2ZRgaIAEoCzInLm5vbW9zLmtlcm5lbC52MS5DYXBhY2l0eVJlc2VydmVSZXF1ZXN0SAASOwoMcmVzdG9yZV9tYWluGBsgASgLMiMubm9tb3Mua2VybmVsLnYxLlJlc3RvcmVNYWluUmVxdWVzdEgAEk4KFnJlc29sdmVfc3RhdGVfcG9zaXRpb24YHCABKAsyLC5ub21vcy5rZXJuZWwudjEuUmVzb2x2ZVN0YXRlUG9zaXRpb25SZXF1ZXN0SAASRwoScmVzaWRlbnRfZm9vdHByaW50GB0gASgLMikubm9tb3Mua2VybmVsLnYxLlJlc2lkZW50Rm9vdHByaW50UmVxdWVzdEgAQgsKCW9wZXJhdGlvbiIoChhSZXNpZGVudEZvb3RwcmludFJlcXVlc3QSDAoEZGVlcBgBIAEoCCKfAgoRUmVzaWRlbnRGb290cHJpbnQSEQoJd29ya3NwYWNlGAEgASgJEg4KBmJyYW5jaBgCIAEoCRIYChByZWFkX21vZGVsX2J5dGVzGAMgASgEEh0KFXJlYWRfbW9kZWxfcnVzdF9ieXRlcxgEIAEoBBIYChBmb2xkX3N0YXRlX2J5dGVzGAUgASgEEhMKC2ZvbGRfaW1hZ2VzGAYgASgNEh8KF3NoYXJlZF9hdHRyaWJ1dGVkX2J5dGVzGAcgASgEEhIKCmFnZ3JlZ2F0ZXMYCCABKAQSNgoKY29tcG9uZW50cxgJIAMoCzIiLm5vbW9zLmtlcm5lbC52MS5SZXNpZGVudENvbXBvbmVudBISCgpjb21wdXRlX3VzGAogASgEImkKEVJlc2lkZW50Q29tcG9uZW50EjQKBGtpbmQYASABKA4yJi5ub21vcy5rZXJuZWwudjEuUmVzaWRlbnRDb21wb25lbnRLaW5kEg0KBWJ5dGVzGAIgASgEEg8KB2NlaWxpbmcYAyABKAgiygEKGVJlc2lkZW50Rm9vdHByaW50UmVzcG9uc2USNQoJcmVzaWRlbnRzGAEgAygLMiIubm9tb3Mua2VybmVsLnYxLlJlc2lkZW50Rm9vdHByaW50EhwKFGFsbG9jYXRvcl9saXZlX2J5dGVzGAIgASgEEhgKEGF0dHJpYnV0ZWRfYnl0ZXMYAyABKAQSGQoRdW5hY2NvdW50ZWRfYnl0ZXMYBCABKAQSFQoNYWNjb3VudGluZ191cxgFIAEoBBIMCgRkZWVwGAYgASgIIpwBChBQYWNrRGVsdGFSZXF1ZXN0EgwKBHJlcG8YASABKAkSEQoEaGVhZBgCIAEoCUgAiAEBEhEKBGJhc2UYAyABKAlIAYgBARIOCgZicmFuY2gYBCABKAkSHQoQc3RhZ2VkX3BhY2tfZmlsZRgFIAEoCUgCiAEBQgcKBV9oZWFkQgcKBV9iYXNlQhMKEV9zdGFnZWRfcGFja19maWxlInIKEEFwcGx5UGFja1JlcXVlc3QSDAoEcmVwbxgBIAEoCRIOCgRwYWNrGAIgASgMSAASGgoQc3RhZ2VkX3BhY2tfZmlsZRgEIAEoCUgAEhEKBGhlYWQYAyABKAlIAYgBAUIICgZzb3VyY2VCBwoFX2hlYWQiIAoQUmVwb1N0YXRzUmVxdWVzdBIMCgRyZXBvGAEgASgJIqwBChNJbnRlbnRzQWJvdmVSZXF1ZXN0EgwKBHJlcG8YASABKAkSEQoEaGVhZBgCIAEoCUgAiAEBEhEKBGJhc2UYAyABKAlIAYgBARIOCgZicmFuY2gYBCABKAkSDQoFbGltaXQYBSABKAQSGAoQY29tcGxldGVfbG9naWNhbBgGIAEoCBIWCg5jb21wYWN0X3N0b3JlZBgHIAEoCEIHCgVfaGVhZEIHCgVfYmFzZSIrChRJbnNwZWN0Q2hhbmdlUmVxdWVzdBITCgtjaGFuZ2VfdXNkYRgBIAEoDCLfAQoOUmVmdXNhbFZlcmRpY3QSFQoIb2ZmZXJfaWQYASABKAlIAIgBARIQCgNvaWQYAiABKAlIAYgBARITCgZkb21haW4YAyABKAlIAogBARIZCgxkaXJlY3RpdmVfaWQYBCABKAlIA4gBARIUCgdzZXNzaW9uGAUgASgJSASIAQESEQoJcGFya2VkX2F0GAYgASgJEg4KBnJlYXNvbhgHIAEoCUILCglfb2ZmZXJfaWRCBgoEX29pZEIJCgdfZG9tYWluQg8KDV9kaXJlY3RpdmVfaWRCCgoIX3Nlc3Npb24iTwobRW5jb2RlUmVmdXNhbFZlcmRpY3RSZXF1ZXN0EjAKB3ZlcmRpY3QYASABKAsyHy5ub21vcy5rZXJuZWwudjEuUmVmdXNhbFZlcmRpY3QiNAocSW5zcGVjdFJlZnVzYWxWZXJkaWN0UmVxdWVzdBIUCgx2ZXJkaWN0X3VzZGEYASABKAwiOgoPUmVhZEJsb2JSZXF1ZXN0EgwKBHJlcG8YASABKAkSCwoDb2lkGAIgASgJEgwKBHBhdGgYAyABKAkiNAoRUmVzb2x2ZVJlZlJlcXVlc3QSDAoEcmVwbxgBIAEoCRIRCglyZWZlcmVuY2UYAiABKAkiLwoPTGlzdFJlZnNSZXF1ZXN0EgwKBHJlcG8YASABKAkSDgoGcHJlZml4GAIgASgJIkIKD1dyaXRlUmVmUmVxdWVzdBIMCgRyZXBvGAEgASgJEhEKCXJlZmVyZW5jZRgCIAEoCRIOCgZ0YXJnZXQYAyABKAkiMwoQRGVsZXRlUmVmUmVxdWVzdBIMCgRyZXBvGAEgASgJEhEKCXJlZmVyZW5jZRgCIAEoCSIpCghNZXRhRmlsZRIMCgRwYXRoGAEgASgJEg8KB2NvbnRlbnQYAiABKAwirgEKFldyaXRlTWV0YUNvbW1pdFJlcXVlc3QSDAoEcmVwbxgBIAEoCRIPCgdwYXJlbnRzGAIgAygJEigKBWZpbGVzGAMgAygLMhkubm9tb3Mua2VybmVsLnYxLk1ldGFGaWxlEg8KB21lc3NhZ2UYBCABKAkSFAoMdGltZV9zZWNvbmRzGAUgASgSEhYKCXJlZmVyZW5jZRgGIAEoCUgAiAEBQgwKCl9yZWZlcmVuY2UiZwoVTGF3Q2xvc3VyZUluZm9SZXF1ZXN0EhQKDGNsb3N1cmVfZmlsZRgBIAEoCRI4CgpjYXBhYmlsaXR5GAIgASgOMiQubm9tb3Mua2VybmVsLnYxLktlcm5lbExhd0NhcGFiaWxpdHkihwEKF0NoZWNrcG9pbnRFeHBvcnRSZXF1ZXN0EjAKBnRhcmdldBgBIAEoCzIgLm5vbW9zLmtlcm5lbC52MS5Xb3Jrc3BhY2VUYXJnZXQSIQoUc3RhZ2VkX2Zyb250aWVyX2ZpbGUYAiABKAlIAIgBAUIXChVfc3RhZ2VkX2Zyb250aWVyX2ZpbGUi6QEKF0NoZWNrcG9pbnRJbXBvcnRSZXF1ZXN0EjAKBnRhcmdldBgBIAEoCzIgLm5vbW9zLmtlcm5lbC52MS5Xb3Jrc3BhY2VUYXJnZXQSEgoIZnJvbnRpZXIYAiABKAxIABIeChRzdGFnZWRfZnJvbnRpZXJfZmlsZRgGIAEoCUgAEhMKBmN1cnNvchgDIAEoCUgBiAEBEhcKCnN0YXRlX3Jvb3QYBCABKAlIAogBARINCgVzcGFucxgFIAEoCEIRCg9mcm9udGllcl9zb3VyY2VCCQoHX2N1cnNvckINCgtfc3RhdGVfcm9vdCIxChZDYXBhY2l0eVJlc2VydmVSZXF1ZXN0EhcKD2FnZ3JlZ2F0ZV9jb3VudBgBIAEoBCJpChJSZXN0b3JlTWFpblJlcXVlc3QSMAoGdGFyZ2V0GAEgASgLMiAubm9tb3Mua2VybmVsLnYxLldvcmtzcGFjZVRhcmdldBIMCgRoZWFkGAIgASgJEhMKC2RpYWdub3N0aWNzGAMgASgIImkKG1Jlc29sdmVTdGF0ZVBvc2l0aW9uUmVxdWVzdBIMCgRyZXBvGAEgASgJEhEKCW1haW5faGVhZBgCIAEoCRIVCg1oaW50ZWRfY29tbWl0GAMgASgJEhIKCnN0YXRlX3Jvb3QYBCABKAkiwgoKD0N1c3RvZHlSZXNwb25zZRI4CgpwYWNrX2RlbHRhGAogASgLMiIubm9tb3Mua2VybmVsLnYxLlBhY2tEZWx0YVJlc3BvbnNlSAASOAoKYXBwbHlfcGFjaxgLIAEoCzIiLm5vbW9zLmtlcm5lbC52MS5BcHBseVBhY2tSZXNwb25zZUgAEjgKCnJlcG9fc3RhdHMYDCABKAsyIi5ub21vcy5rZXJuZWwudjEuUmVwb1N0YXRzUmVzcG9uc2VIABI+Cg1pbnRlbnRzX2Fib3ZlGA0gASgLMiUubm9tb3Mua2VybmVsLnYxLkludGVudHNBYm92ZVJlc3BvbnNlSAASQAoOaW5zcGVjdF9jaGFuZ2UYDiABKAsyJi5ub21vcy5rZXJuZWwudjEuSW5zcGVjdENoYW5nZVJlc3BvbnNlSAASTwoWZW5jb2RlX3JlZnVzYWxfdmVyZGljdBgPIAEoCzItLm5vbW9zLmtlcm5lbC52MS5FbmNvZGVSZWZ1c2FsVmVyZGljdFJlc3BvbnNlSAASUQoXaW5zcGVjdF9yZWZ1c2FsX3ZlcmRpY3QYECABKAsyLi5ub21vcy5rZXJuZWwudjEuSW5zcGVjdFJlZnVzYWxWZXJkaWN0UmVzcG9uc2VIABI2CglyZWFkX2Jsb2IYESABKAsyIS5ub21vcy5rZXJuZWwudjEuUmVhZEJsb2JSZXNwb25zZUgAEjoKC3Jlc29sdmVfcmVmGBIgASgLMiMubm9tb3Mua2VybmVsLnYxLlJlc29sdmVSZWZSZXNwb25zZUgAEjYKCWxpc3RfcmVmcxgTIAEoCzIhLm5vbW9zLmtlcm5lbC52MS5MaXN0UmVmc1Jlc3BvbnNlSAASMgoJd3JpdGVfcmVmGBQgASgLMh0ubm9tb3Mua2VybmVsLnYxLkFja25vd2xlZGdlZEgAEjMKCmRlbGV0ZV9yZWYYFSABKAsyHS5ub21vcy5rZXJuZWwudjEuQWNrbm93bGVkZ2VkSAASRQoRd3JpdGVfbWV0YV9jb21taXQYFiABKAsyKC5ub21vcy5rZXJuZWwudjEuV3JpdGVNZXRhQ29tbWl0UmVzcG9uc2VIABJDChBsYXdfY2xvc3VyZV9pbmZvGBcgASgLMicubm9tb3Mua2VybmVsLnYxLkxhd0Nsb3N1cmVJbmZvUmVzcG9uc2VIABJGChFjaGVja3BvaW50X2V4cG9ydBgYIAEoCzIpLm5vbW9zLmtlcm5lbC52MS5DaGVja3BvaW50RXhwb3J0UmVzcG9uc2VIABJGChFjaGVja3BvaW50X2ltcG9ydBgZIAEoCzIpLm5vbW9zLmtlcm5lbC52MS5DaGVja3BvaW50SW1wb3J0UmVzcG9uc2VIABJEChBjYXBhY2l0eV9yZXNlcnZlGBogASgLMigubm9tb3Mua2VybmVsLnYxLkNhcGFjaXR5UmVzZXJ2ZVJlc3BvbnNlSAASPAoMcmVzdG9yZV9tYWluGBsgASgLMiQubm9tb3Mua2VybmVsLnYxLlJlc3RvcmVNYWluUmVzcG9uc2VIABJPChZyZXNvbHZlX3N0YXRlX3Bvc2l0aW9uGBwgASgLMi0ubm9tb3Mua2VybmVsLnYxLlJlc29sdmVTdGF0ZVBvc2l0aW9uUmVzcG9uc2VIABJIChJyZXNpZGVudF9mb290cHJpbnQYHSABKAsyKi5ub21vcy5rZXJuZWwudjEuUmVzaWRlbnRGb290cHJpbnRSZXNwb25zZUgAQgsKCW9wZXJhdGlvbiIwChFQYWNrRGVsdGFSZXNwb25zZRIMCgRwYWNrGAEgASgMEg0KBWJ5dGVzGAIgASgEIjwKEUFwcGx5UGFja1Jlc3BvbnNlEhQKDG9iamVjdF9jb3VudBgBIAEoBBIRCglwYWNrX2hhc2gYAiABKAkipwEKEVJlcG9TdGF0c1Jlc3BvbnNlEhMKC3RvdGFsX2J5dGVzGAEgASgEEhQKDG9iamVjdF9ieXRlcxgCIAEoBBIVCg1sb29zZV9vYmplY3RzGAMgASgEEhMKC2xvb3NlX2J5dGVzGAQgASgEEhIKCnBhY2tfZmlsZXMYBSABKAQSEgoKcGFja19ieXRlcxgGIAEoBBITCgtpbmRleF9ieXRlcxgHIAEoBCLiAQoMSW50ZW50UmVjb3JkEgsKA29pZBgBIAEoCRIRCglpbnRlbnRfaWQYAiABKAkSDgoGZG9tYWluGAMgASgJEhEKCWRpcmVjdGl2ZRgEIAEoCRITCgtjaGFuZ2VfdXNkYRgFIAEoDBIuCghzZW1hbnRpYxgGIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdBJKChV0cmFuc3BvcnRfcmVxdWlyZW1lbnQYByABKA4yKy5ub21vcy5rZXJuZWwudjEuSW50ZW50VHJhbnNwb3J0UmVxdWlyZW1lbnQiRgoUSW50ZW50c0Fib3ZlUmVzcG9uc2USLgoHaW50ZW50cxgBIAMoCzIdLm5vbW9zLmtlcm5lbC52MS5JbnRlbnRSZWNvcmQiQgoTTm9taW5hbENhbGxJZGVudGl0eRITCgtkb21haW5fcGF0aBgBIAEoCRIWCg5kaXJlY3RpdmVfcGF0aBgCIAEoCSKIAQoYTGlmZWN5Y2xlSW5zdGFsbElkZW50aXR5Eh8KF3RhcmdldF9jbG9zdXJlX2lkZW50aXR5GAEgASgJEhQKDGluc3RhbGxlZF9ieRgCIAEoCRI1CgVwaGFzZRgDIAEoDjImLm5vbW9zLmtlcm5lbC52MS5MaWZlY3ljbGVJbnN0YWxsUGhhc2UiWgodV29ya3NwYWNlUmVzaWRlbmN5UmVxdWlyZW1lbnQSEQoJd29ya3NwYWNlGAEgASgJEhMKC3NvdXJjZV9oZWFkGAIgASgJEhEKCWZvbGRfcm9vdBgDIAEoCSK0AgoVSW5zcGVjdENoYW5nZVJlc3BvbnNlEi4KCHNlbWFudGljGAEgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0EhEKCWludGVudF9pZBgCIAEoCRIyCgRjYWxsGAMgASgLMiQubm9tb3Mua2VybmVsLnYxLk5vbWluYWxDYWxsSWRlbnRpdHkSEAoIYXV0aG9yZWQYBCABKAgSRAoRbGlmZWN5Y2xlX2luc3RhbGwYBSABKAsyKS5ub21vcy5rZXJuZWwudjEuTGlmZWN5Y2xlSW5zdGFsbElkZW50aXR5EkwKFHJlcXVpcmVkX3Jlc2lkZW5jaWVzGAYgAygLMi4ubm9tb3Mua2VybmVsLnYxLldvcmtzcGFjZVJlc2lkZW5jeVJlcXVpcmVtZW50IkwKHFJlc29sdmVTdGF0ZVBvc2l0aW9uUmVzcG9uc2USGgoNcmVzb2x2ZWRfaGVhZBgBIAEoCUgAiAEBQhAKDl9yZXNvbHZlZF9oZWFkIjQKHEVuY29kZVJlZnVzYWxWZXJkaWN0UmVzcG9uc2USFAoMdmVyZGljdF91c2RhGAEgASgMIlEKHUluc3BlY3RSZWZ1c2FsVmVyZGljdFJlc3BvbnNlEjAKB3ZlcmRpY3QYASABKAsyHy5ub21vcy5rZXJuZWwudjEuUmVmdXNhbFZlcmRpY3QiLwoQUmVhZEJsb2JSZXNwb25zZRINCgVmb3VuZBgBIAEoCBIMCgRibG9iGAIgASgMIi4KElJlc29sdmVSZWZSZXNwb25zZRIQCgNvaWQYASABKAlIAIgBAUIGCgRfb2lkIisKCVJlZlJlY29yZBIRCglyZWZlcmVuY2UYASABKAkSCwoDb2lkGAIgASgJIjwKEExpc3RSZWZzUmVzcG9uc2USKAoEcmVmcxgBIAMoCzIaLm5vbW9zLmtlcm5lbC52MS5SZWZSZWNvcmQiDgoMQWNrbm93bGVkZ2VkIiYKF1dyaXRlTWV0YUNvbW1pdFJlc3BvbnNlEgsKA29pZBgBIAEoCSKDAQoWTGF3Q2xvc3VyZUluZm9SZXNwb25zZRIQCghpZGVudGl0eRgBIAEoCRIZChFyb290X2xvZ2ljYWxfcGF0aBgCIAEoCRITCgthc3NldF9jb3VudBgDIAEoBBISCgpwcmltX2NvdW50GAQgASgEEhMKC2RvbWFpbl9rZXlzGAUgAygJIu8CChhDaGVja3BvaW50RXhwb3J0UmVzcG9uc2USDQoFZW1wdHkYASABKAgSEwoGY3Vyc29yGAIgASgJSACIAQESEAoIZnJvbnRpZXIYAyABKAwSFwoKc3RhdGVfcm9vdBgEIAEoCUgBiAEBEhIKCnN0YXRlX3RyZWUYBSABKAgSDgoGcGlubmVkGAYgASgIEhsKE3JlYWRfaW5kZXhfc25hcHNob3QYByABKAgSIwobcmVhZF9pbmRleF9zbmFwc2hvdF9wZW5kaW5nGAggASgIEiQKF3JlYWRfaW5kZXhfc3FsaXRlX2J5dGVzGAkgASgESAKIAQESJQoYcmVhZF9pbmRleF9jdXN0b2R5X2J5dGVzGAogASgESAOIAQFCCQoHX2N1cnNvckINCgtfc3RhdGVfcm9vdEIaChhfcmVhZF9pbmRleF9zcWxpdGVfYnl0ZXNCGwoZX3JlYWRfaW5kZXhfY3VzdG9keV9ieXRlcyKeAgoYQ2hlY2twb2ludEltcG9ydFJlc3BvbnNlEhAKCHJlc3RvcmVkGAEgASgIEhMKBnJlYXNvbhgCIAEoCUgAiAEBEhcKD2Zyb250aWVyX3NlZWRlZBgDIAEoCBIlCh1mcm9udGllcl92ZXJpZmljYXRpb25fcGVuZGluZxgEIAEoCBIXCg9hZ2dyZWdhdGVfY291bnQYBSABKAQSKwoFc3BhbnMYBiABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3QSEwoGY3Vyc29yGAcgASgJSAGIAQESEQoJcmVhZF9vbmx5GAggASgIEhcKD2xhenlfcmVhZF9pbmRleBgJIAEoCEIJCgdfcmVhc29uQgkKB19jdXJzb3IiSgoXQ2FwYWNpdHlSZXNlcnZlUmVzcG9uc2USFwoPYWdncmVnYXRlX2NvdW50GAEgASgEEhYKDnJlc2VydmVkX2J5dGVzGAIgASgEIvkCChBSZXN0b3JlTWFpblNwYW5zEhAKCHRvdGFsX3VzGAEgASgEEhoKEmxpdmVfcmVmX2xvb2t1cF91cxgCIAEoBBIYChB0YXJnZXRfZGVjb2RlX3VzGAMgASgEEiQKHGN1c3RvZHlfY29tcGxldGVuZXNzX3JlYWRfdXMYBCABKAQSGQoRcXVhcmFudGluZV9yZWZfdXMYBSABKAQSJQodY2hhaW5fc2lnbmF0dXJlX2xhd19yZXBsYXlfdXMYBiABKAQSGQoRdmVyZGljdF9kZWNvZGVfdXMYByABKAQSIwobcHJvbW90ZV9hbmRfY2xlYW51cF9yZWZzX3VzGAggASgEEhsKE2Zyb250aWVyX3JlYnVpbGRfdXMYCSABKAQSGQoRZnJvbnRpZXJfc3RvcmVfdXMYCiABKAQSPQoMdmVyaWZpY2F0aW9uGAsgASgLMicubm9tb3Mua2VybmVsLnYxLlZlcmlmeUNoYWluRGlhZ25vc3RpY3MipAEKE1Jlc3RvcmVNYWluUmVzcG9uc2USDAoEaGVhZBgBIAEoCRIQCgh2ZXJpZmllZBgCIAEoCBIMCgR3YWxrGAMgASgJEjAKBXNwYW5zGAQgASgLMiEubm9tb3Mua2VybmVsLnYxLlJlc3RvcmVNYWluU3BhbnMSLQoHdmVyZGljdBgFIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdCKbAgoKTm9tb3NWYWx1ZRIlCgRudWxsGAEgASgLMhUubm9tb3Mua2VybmVsLnYxLk51bGxIABIRCgdib29sZWFuGAIgASgISAASGAoOc2lnbmVkX2ludGVnZXIYAyABKBJIABIaChB1bnNpZ25lZF9pbnRlZ2VyGAQgASgESAASGAoOZmxvYXRpbmdfcG9pbnQYBSABKAFIABIOCgR0ZXh0GAYgASgJSAASDwoFYnl0ZXMYByABKAxIABIqCgRsaXN0GAggASgLMhoubm9tb3Mua2VybmVsLnYxLk5vbW9zTGlzdEgAEi4KBm9iamVjdBgJIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdEgAQgYKBGtpbmQiBgoETnVsbCI4CglOb21vc0xpc3QSKwoGdmFsdWVzGAEgAygLMhsubm9tb3Mua2VybmVsLnYxLk5vbW9zVmFsdWUikwEKC05vbW9zU3RydWN0EjgKBmZpZWxkcxgBIAMoCzIoLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdC5GaWVsZHNFbnRyeRpKCgtGaWVsZHNFbnRyeRILCgNrZXkYASABKAkSKgoFdmFsdWUYAiABKAsyGy5ub21vcy5rZXJuZWwudjEuTm9tb3NWYWx1ZToCOAEq6RIKEUtlcm5lbFJlZnVzYWxDb2RlEiMKH0tFUk5FTF9SRUZVU0FMX0NPREVfVU5TUEVDSUZJRUQQABIlCiFLRVJORUxfUkVGVVNBTF9DT0RFX0JBRF9TSUdOQVRVUkUQARIkCiBLRVJORUxfUkVGVVNBTF9DT0RFX1VOQVVUSE9SSVpFRBACEicKI0tFUk5FTF9SRUZVU0FMX0NPREVfUE9MSUNZX0RJU0FCTEVEEAMSKgomS0VSTkVMX1JFRlVTQUxfQ09ERV9VTkNFUlRJRklFRF9QT0xJQ1kQBBIjCh9LRVJORUxfUkVGVVNBTF9DT0RFX1JFRkVSRU5USUFMEAUSLworS0VSTkVMX1JFRlVTQUxfQ09ERV9QT0lOVF9TVEFURV9VTkFWQUlMQUJMRRAGEiQKIEtFUk5FTF9SRUZVU0FMX0NPREVfQ0FQX0VYQ0VFREVEEAcSLQopS0VSTkVMX1JFRlVTQUxfQ09ERV9DQVBfQ09VTlRfVU5BVkFJTEFCTEUQCBIpCiVLRVJORUxfUkVGVVNBTF9DT0RFX0VWSURFTkNFX1VOQkFDS0VEEAkSJgoiS0VSTkVMX1JFRlVTQUxfQ09ERV9PUlBIQU5fUkVDRUlQVBAKEjYKMktFUk5FTF9SRUZVU0FMX0NPREVfUkVDRUlQVF9PTl9URVJNSU5BTF9PQkxJR0FUSU9OEAsSIgoeS0VSTkVMX1JFRlVTQUxfQ09ERV9OT1RfTUlOVEVEEAwSKAokS0VSTkVMX1JFRlVTQUxfQ09ERV9ET01BSU5fTElGRUNZQ0xFEA0SKQolS0VSTkVMX1JFRlVTQUxfQ09ERV9UWVBFX1RBR19NSVNNQVRDSBAOEiwKKEtFUk5FTF9SRUZVU0FMX0NPREVfUkVUSVJFRF9SRUFEX1NVUkZBQ0UQDxIwCixLRVJORUxfUkVGVVNBTF9DT0RFX0NST1NTX1dPUktTUEFDRV9ERUNMSU5FRBAQEisKJ0tFUk5FTF9SRUZVU0FMX0NPREVfQUdHUkVHQVRFX0lOVkFSSUFOVBAREisKJ0tFUk5FTF9SRUZVU0FMX0NPREVfV09SS1NQQUNFX0lOVkFSSUFOVBASEi4KKktFUk5FTF9SRUZVU0FMX0NPREVfQ0FQVFVSRURfUkVBRF9DT05GTElDVBATEjIKLktFUk5FTF9SRUZVU0FMX0NPREVfQ09ORkxJQ1RfU05BUFNIT1RfUkVRVUlSRUQQFBI0CjBLRVJORUxfUkVGVVNBTF9DT0RFX0NPTkZMSUNUX1NOQVBTSE9UX1VOREVDTEFSRUQQFRIxCi1LRVJORUxfUkVGVVNBTF9DT0RFX0NPTkZMSUNUX1NOQVBTSE9UX0lOVkFMSUQQFhIvCitLRVJORUxfUkVGVVNBTF9DT0RFX0NPTkZMSUNUX1NOQVBTSE9UX1NUQUxFEBcSMAosS0VSTkVMX1JFRlVTQUxfQ09ERV9DQVBUVVJFRF9SRUFEX1VOREVDTEFSRUQQGBItCilLRVJORUxfUkVGVVNBTF9DT0RFX0NBUFRVUkVEX1JFQURfUFJJVkFURRAZEjAKLEtFUk5FTF9SRUZVU0FMX0NPREVfQVRURVNURURfUkVBRF9VTkRFQ0xBUkVEEBoSMwovS0VSTkVMX1JFRlVTQUxfQ09ERV9BVFRFU1RFRF9SRUFEX1VOVFJVU1RFRF9LRVkQGxI2CjJLRVJORUxfUkVGVVNBTF9DT0RFX0FUVEVTVEVEX1JFQURfVU5UUlVTVEVEX1NPVVJDRRAcEiwKKEtFUk5FTF9SRUZVU0FMX0NPREVfQVRURVNURURfUkVBRF9GT1JHRUQQHRIrCidLRVJORUxfUkVGVVNBTF9DT0RFX0FUVEVTVEVEX1JFQURfU1RBTEUQHhIuCipLRVJORUxfUkVGVVNBTF9DT0RFX0FUVEVTVEVEX1JFQURfT1ZFUlNJWkUQHxI3CjNLRVJORUxfUkVGVVNBTF9DT0RFX0FUVEVTVEVEX1JFQURfRElTSE9OT1JFRF9TT1VSQ0UQIBI1CjFLRVJORUxfUkVGVVNBTF9DT0RFX0VRVUlWT0NBVElPTl9FVklERU5DRV9JTlZBTElEECESMwovS0VSTkVMX1JFRlVTQUxfQ09ERV9BVFRFU1RBVElPTl9SRUNFSVBUX0lOVkFMSUQQIhIrCidLRVJORUxfUkVGVVNBTF9DT0RFX0tFWV9ST1NURVJfTUlTTUFUQ0gQIxIvCitLRVJORUxfUkVGVVNBTF9DT0RFX0tFWV9FUE9DSF9OT1RfTU9OT1RPTklDECQSKQolS0VSTkVMX1JFRlVTQUxfQ09ERV9XUklURV9FUE9DSF9TVEFMRRAlEi0KKUtFUk5FTF9SRUZVU0FMX0NPREVfRU5WRUxPUEVfU0lEX01JU01BVENIECYSMgouS0VSTkVMX1JFRlVTQUxfQ09ERV9SRVZPS0VEX01FTUJFUl9SRVNVUlJFQ1RFRBAnEigKJEtFUk5FTF9SRUZVU0FMX0NPREVfRk9SR0VEX1BSSU5DSVBBTBAoEigKJEtFUk5FTF9SRUZVU0FMX0NPREVfT1dORURfS0VZX0FOQ0hPUhApEiYKIktFUk5FTF9SRUZVU0FMX0NPREVfT1dORURfUkVDT1ZFUlkQKhIsCihLRVJORUxfUkVGVVNBTF9DT0RFX1NVUkZBQ0VEX0JBU0lTX0FIRUFEECsSMgouS0VSTkVMX1JFRlVTQUxfQ09ERV9TSUdORVJfRVBPQ0hfT1VUX09GX1dJTkRPVxAsEiYKIktFUk5FTF9SRUZVU0FMX0NPREVfRVZPTFZFX1JFRlVTRUQQLRIrCidLRVJORUxfUkVGVVNBTF9DT0RFX0FUVEVTVEFUSU9OX0lOVkFMSUQQLhItCilLRVJORUxfUkVGVVNBTF9DT0RFX1BBUkVOVF9ESURfTk9UX0FUVEVTVBAvEikKJUtFUk5FTF9SRUZVU0FMX0NPREVfQ0VSVF9DSEFJTl9CUk9LRU4QMBIqCiZLRVJORUxfUkVGVVNBTF9DT0RFX05PVF9ST09URURfQVRfUk9PVBAxEioKJktFUk5FTF9SRUZVU0FMX0NPREVfREVMRUdBVElPTl9JTlZBTElEEDISJQohS0VSTkVMX1JFRlVTQUxfQ09ERV9QTEFOX1JFSkVDVEVEEDMqigEKD1ZlcmlmeUNoYWluV2FsaxIhCh1WRVJJRllfQ0hBSU5fV0FMS19VTlNQRUNJRklFRBAAEhoKFlZFUklGWV9DSEFJTl9XQUxLX0ZVTEwQARIcChhWRVJJRllfQ0hBSU5fV0FMS19TVUZGSVgQAhIaChZWRVJJRllfQ0hBSU5fV0FMS19NRU1PEAMqhQwKDlF1ZXJ5T3BlcmF0aW9uEh8KG1FVRVJZX09QRVJBVElPTl9VTlNQRUNJRklFRBAAEhwKGFFVRVJZX09QRVJBVElPTl9FWFRSRU1VTRABEiUKIVFVRVJZX09QRVJBVElPTl9QRU5ESU5HX0NPTkZMSUNUUxACEiwKKFFVRVJZX09QRVJBVElPTl9QRU5ESU5HX0NPTkZMSUNUX1NVTU1BUlkQAxIgChxRVUVSWV9PUEVSQVRJT05fUkVBRF9QT1NUVVJFEAQSHwobUVVFUllfT1BFUkFUSU9OX0NVUlJFTlRfTEFXEAUSIwofUVVFUllfT1BFUkFUSU9OX0lOVEVSRkFDRV9PRkZFUhAGEicKI1FVRVJZX09QRVJBVElPTl9SRUxBVElPTl9HQVRFX09GRkVSEAcSHQoZUVVFUllfT1BFUkFUSU9OX1NDRU5FX0xBVxAIEiEKHVFVRVJZX09QRVJBVElPTl9JTlNUQUxMRURfTEFXEAkSHAoYUVVFUllfT1BFUkFUSU9OX0RFU0NSSUJFEAoSIAocUVVFUllfT1BFUkFUSU9OX0tFUk5FTF9TVEFNUBALEiMKH1FVRVJZX09QRVJBVElPTl9ERVZFTE9QRVJfU1BBTlMQDBIpCiVRVUVSWV9PUEVSQVRJT05fREVDTEFSRURfQ0FQQUJJTElUSUVTEA0SHQoZUVVFUllfT1BFUkFUSU9OX1JFQURJTkVTUxAOEiQKIFFVRVJZX09QRVJBVElPTl9QUk9KRUNUSU9OX1NUQVRTEA8SJQohUVVFUllfT1BFUkFUSU9OX01FTU9SWV9EUk9QX1BST0JFEBASGAoUUVVFUllfT1BFUkFUSU9OX1dBUk0QERIbChdRVUVSWV9PUEVSQVRJT05fUkVGUkVTSBASEiAKHFFVRVJZX09QRVJBVElPTl9WRVJJRllfQ0hBSU4QExIlCiFRVUVSWV9PUEVSQVRJT05fSElTVE9SWV9QUkVGTElHSFQQFBIZChVRVUVSWV9PUEVSQVRJT05fUk9VVEUQFRIYChRRVUVSWV9PUEVSQVRJT05fTUlOVBAWEiEKHVFVRVJZX09QRVJBVElPTl9DUllQVE9fS0VZR0VOEBcSJQohUVVFUllfT1BFUkFUSU9OX0NSWVBUT19TRUFMX0ZJRUxEEBgSLAooUVVFUllfT1BFUkFUSU9OX0NSWVBUT19CTElORF9JTkRFWF9UT0tFThAZEioKJlFVRVJZX09QRVJBVElPTl9DUllQVE9fT1dORURfU0NPUEVfS0VZEBoSLworUVVFUllfT1BFUkFUSU9OX0NSWVBUT19PV05FRF9ERVZJQ0VfUkVRVUVTVBAbEjEKLVFVRVJZX09QRVJBVElPTl9DUllQVE9fT1dORURfUFJFUEFSRV9BUFBST1ZBTBAcEjEKLVFVRVJZX09QRVJBVElPTl9DUllQVE9fT1dORURfUFJFUEFSRV9SRUNPVkVSWRAdEiMKH1FVRVJZX09QRVJBVElPTl9DUllQVE9fV1JBUF9LRVkQHhIlCiFRVUVSWV9PUEVSQVRJT05fQ1JZUFRPX1VOV1JBUF9LRVkQHxIhCh1RVUVSWV9PUEVSQVRJT05fQVVUSE9SX0tFWUdFThAgEiQKIFFVRVJZX09QRVJBVElPTl9BVFRFU1RBVElPTl9TSUdOECESIAocUVVFUllfT1BFUkFUSU9OX1JFQ0VJUFRfUEFUSBAiEh0KGVFVRVJZX09QRVJBVElPTl9DRVJUX1NJR04QIxIlCiFRVUVSWV9PUEVSQVRJT05fQklSVEhfVFJVU1RfU1RBVEUQJBIhCh1RVUVSWV9PUEVSQVRJT05fRVJBX0NFUlRfU0lHThAlEigKJFFVRVJZX09QRVJBVElPTl9ERUxFR0FUSU9OX0NFUlRfU0lHThAmEikKJVFVRVJZX09QRVJBVElPTl9DQU5PTklDQUxJWkVfRlJPTlRJRVIQJxIrCidRVUVSWV9PUEVSQVRJT05fQ0FOT05JQ0FMSVpFX1BST0pFQ1RJT04QKCrSAgoVUmVzaWRlbnRDb21wb25lbnRLaW5kEicKI1JFU0lERU5UX0NPTVBPTkVOVF9LSU5EX1VOU1BFQ0lGSUVEEAASJgoiUkVTSURFTlRfQ09NUE9ORU5UX0tJTkRfRk9MRF9TVEFURRABEi0KKVJFU0lERU5UX0NPTVBPTkVOVF9LSU5EX1JFQURfTU9ERUxfU1FMSVRFEAISLgoqUkVTSURFTlRfQ09NUE9ORU5UX0tJTkRfUkVBRF9NT0RFTF9JTkRFWEVTEAMSLQopUkVTSURFTlRfQ09NUE9ORU5UX0tJTkRfU0hBUkVEX0FUVFJJQlVURUQQBBIsCihSRVNJREVOVF9DT01QT05FTlRfS0lORF9XT1JLU1BBQ0VfQ0FDSEVTEAUSLAooUkVTSURFTlRfQ09NUE9ORU5UX0tJTkRfR0lUX09CSkVDVF9DQUNIRRAGKmwKE0tlcm5lbExhd0NhcGFiaWxpdHkSJQohS0VSTkVMX0xBV19DQVBBQklMSVRZX1VOU1BFQ0lGSUVEEAASLgoqS0VSTkVMX0xBV19DQVBBQklMSVRZX1NUQUdFX1pFUk9fQk9PVFNUUkFQEAEqqAEKGkludGVudFRyYW5zcG9ydFJlcXVpcmVtZW50EiwKKElOVEVOVF9UUkFOU1BPUlRfUkVRVUlSRU1FTlRfVU5TUEVDSUZJRUQQABIuCipJTlRFTlRfVFJBTlNQT1JUX1JFUVVJUkVNRU5UX1NFQUxFRF9DSEFOR0UQARIsCihJTlRFTlRfVFJBTlNQT1JUX1JFUVVJUkVNRU5UX0NPTU1JVF9UUkVFEAIqiQEKFUxpZmVjeWNsZUluc3RhbGxQaGFzZRInCiNMSUZFQ1lDTEVfSU5TVEFMTF9QSEFTRV9VTlNQRUNJRklFRBAAEiIKHkxJRkVDWUNMRV9JTlNUQUxMX1BIQVNFX0FDVElWRRABEiMKH0xJRkVDWUNMRV9JTlNUQUxMX1BIQVNFX1BFTkRJTkcQAjJZChJOb21vc0tlcm5lbFNlcnZpY2USQwoEQ2FsbBIcLm5vbW9zLmtlcm5lbC52MS5DYWxsUmVxdWVzdBodLm5vbW9zLmtlcm5lbC52MS5DYWxsUmVzcG9uc2ViBnByb3RvMw");
|
|
9751
|
+
var file_nomos_kernel_v1_kernel = /* @__PURE__ */ fileDesc("Chxub21vcy9rZXJuZWwvdjEva2VybmVsLnByb3RvEg9ub21vcy5rZXJuZWwudjEimAMKC0NhbGxSZXF1ZXN0EhgKEHByb3RvY29sX3ZlcnNpb24YASABKA0SEgoKcmVxdWVzdF9pZBgCIAEoCRIsCgRvcGVuGAogASgLMhwubm9tb3Mua2VybmVsLnYxLk9wZW5SZXF1ZXN0SAASLgoFb2ZmZXIYCyABKAsyHS5ub21vcy5rZXJuZWwudjEuT2ZmZXJSZXF1ZXN0SAASLgoFcXVlcnkYDCABKAsyHS5ub21vcy5rZXJuZWwudjEuUXVlcnlSZXF1ZXN0SAASMAoGb3V0Ym94GA0gASgLMh4ubm9tb3Mua2VybmVsLnYxLk91dGJveFJlcXVlc3RIABIsCgRzeW5jGA4gASgLMhwubm9tb3Mua2VybmVsLnYxLlN5bmNSZXF1ZXN0SAASMgoHY3VzdG9keRgPIAEoCzIfLm5vbW9zLmtlcm5lbC52MS5DdXN0b2R5UmVxdWVzdEgAEiwKBHRlc3QYECABKAsyHC5ub21vcy5rZXJuZWwudjEuVGVzdFJlcXVlc3RIAEILCglvcGVyYXRpb24iywMKDENhbGxSZXNwb25zZRIYChBwcm90b2NvbF92ZXJzaW9uGAEgASgNEhIKCnJlcXVlc3RfaWQYAiABKAkSKwoHZmFpbHVyZRgKIAEoCzIYLm5vbW9zLmtlcm5lbC52MS5GYWlsdXJlSAASLQoEb3BlbhgLIAEoCzIdLm5vbW9zLmtlcm5lbC52MS5PcGVuUmVzcG9uc2VIABIvCgVvZmZlchgMIAEoCzIeLm5vbW9zLmtlcm5lbC52MS5PZmZlclJlc3BvbnNlSAASLwoFcXVlcnkYDSABKAsyHi5ub21vcy5rZXJuZWwudjEuUXVlcnlSZXNwb25zZUgAEjEKBm91dGJveBgOIAEoCzIfLm5vbW9zLmtlcm5lbC52MS5PdXRib3hSZXNwb25zZUgAEi0KBHN5bmMYDyABKAsyHS5ub21vcy5rZXJuZWwudjEuU3luY1Jlc3BvbnNlSAASMwoHY3VzdG9keRgQIAEoCzIgLm5vbW9zLmtlcm5lbC52MS5DdXN0b2R5UmVzcG9uc2VIABItCgR0ZXN0GBEgASgLMh0ubm9tb3Mua2VybmVsLnYxLlRlc3RSZXNwb25zZUgAQgkKB291dGNvbWUiVwoHRmFpbHVyZRIMCgRjb2RlGAEgASgJEg8KB21lc3NhZ2UYAiABKAkSLQoHZGV0YWlscxgDIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdCI8CgxPcGVuUmVzcG9uc2USLAoGcmVzdWx0GAEgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0IsMCCg1PZmZlclJlc3BvbnNlEjIKCGFkbWl0dGVkGAEgASgLMh4ubm9tb3Mua2VybmVsLnYxLk9mZmVyQWRtaXR0ZWRIABIwCgdyZWZ1c2VkGAIgASgLMh0ubm9tb3Mua2VybmVsLnYxLk9mZmVyUmVmdXNlZEgAEjsKDWRlYWRfbGV0dGVyZWQYAyABKAsyIi5ub21vcy5rZXJuZWwudjEuT2ZmZXJEZWFkTGV0dGVyZWRIABI4CgtxdWFyYW50aW5lZBgEIAEoCzIhLm5vbW9zLmtlcm5lbC52MS5PZmZlclF1YXJhbnRpbmVkSAASSgoVYmxvY2tlZF9vbl9kZXBlbmRlbmN5GAUgASgLMikubm9tb3Mua2VybmVsLnYxLk9mZmVyQmxvY2tlZE9uRGVwZW5kZW5jeUgAQgkKB291dGNvbWUiPQoNT2ZmZXJBZG1pdHRlZBIsCgZyZXN1bHQYASABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3QilgEKDE9mZmVyUmVmdXNlZBIVCghvZmZlcl9pZBgBIAEoCUgAiAEBEi8KB3JlZnVzYWwYAiABKAsyHi5ub21vcy5rZXJuZWwudjEuS2VybmVsUmVmdXNhbBIxCgtkaWFnbm9zdGljcxgDIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdEILCglfb2ZmZXJfaWQiegoRT2ZmZXJEZWFkTGV0dGVyZWQSFQoIb2ZmZXJfaWQYASABKAlIAIgBARIOCgZyZWFzb24YAiABKAkSMQoLZGlhZ25vc3RpY3MYAyABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3RCCwoJX29mZmVyX2lkIq4BChBPZmZlclF1YXJhbnRpbmVkEhUKCG9mZmVyX2lkGAEgASgJSACIAQESGQoRYXV0aG9yZWRfbGF3X2hhc2gYAiABKAkSGAoQY3VycmVudF9sYXdfaGFzaBgDIAEoCRIOCgZyZWFzb24YBCABKAkSMQoLZGlhZ25vc3RpY3MYBSABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3RCCwoJX29mZmVyX2lkIoEBChhPZmZlckJsb2NrZWRPbkRlcGVuZGVuY3kSFQoIb2ZmZXJfaWQYASABKAlIAIgBARIOCgZkZXRhaWwYAiABKAkSMQoLZGlhZ25vc3RpY3MYAyABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3RCCwoJX29mZmVyX2lkIoEBCg1LZXJuZWxSZWZ1c2FsEjAKBGNvZGUYASABKA4yIi5ub21vcy5rZXJuZWwudjEuS2VybmVsUmVmdXNhbENvZGUSDwoHbWVzc2FnZRgCIAEoCRItCgdkZXRhaWxzGAMgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0Iq8DCg1RdWVyeVJlc3BvbnNlEiwKBXZhbHVlGAEgASgLMhsubm9tb3Mua2VybmVsLnYxLk5vbW9zVmFsdWVIABJBChBhcHBsaWNhdGlvbl9qc29uGAIgASgLMiUubm9tb3Mua2VybmVsLnYxLkFwcGxpY2F0aW9uSnNvblZhbHVlSAASSgoTYXV0aG9yaXphdGlvbl9jaGVjaxgKIAEoCzIrLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uQ2hlY2tSZXNwb25zZUgAEkwKFGF1dGhvcml6YXRpb25fZXhwYW5kGAsgASgLMiwubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25FeHBhbmRSZXNwb25zZUgAEj4KDW9zZ2lfcmVzb3VyY2UYDCABKAsyJS5ub21vcy5rZXJuZWwudjEuT3NnaVJlc291cmNlUmVzcG9uc2VIABJJChh2ZXJpZnlfY2hhaW5fZGlhZ25vc3RpY3MYFCABKAsyJy5ub21vcy5rZXJuZWwudjEuVmVyaWZ5Q2hhaW5EaWFnbm9zdGljc0IICgZyZXN1bHQiSAoNT3NnaUF0dHJpYnV0ZRIMCgRuYW1lGAEgASgJEg0KBXZhbHVlGAIgASgJEhEKBHR5cGUYAyABKAlIAIgBAUIHCgVfdHlwZSIsCg1Pc2dpRGlyZWN0aXZlEgwKBG5hbWUYASABKAkSDQoFdmFsdWUYAiABKAkiiwEKDk9zZ2lDYXBhYmlsaXR5EhEKCW5hbWVzcGFjZRgBIAEoCRIyCgphdHRyaWJ1dGVzGAIgAygLMh4ubm9tb3Mua2VybmVsLnYxLk9zZ2lBdHRyaWJ1dGUSMgoKZGlyZWN0aXZlcxgDIAMoCzIeLm5vbW9zLmtlcm5lbC52MS5Pc2dpRGlyZWN0aXZlIowBCg9Pc2dpUmVxdWlyZW1lbnQSEQoJbmFtZXNwYWNlGAEgASgJEjIKCmF0dHJpYnV0ZXMYAiADKAsyHi5ub21vcy5rZXJuZWwudjEuT3NnaUF0dHJpYnV0ZRIyCgpkaXJlY3RpdmVzGAMgAygLMh4ubm9tb3Mua2VybmVsLnYxLk9zZ2lEaXJlY3RpdmUimgEKFE9zZ2lSZXNvdXJjZVJlc3BvbnNlEhMKC3NvdXJjZV91c2RhGAEgASgMEjUKDGNhcGFiaWxpdGllcxgCIAMoCzIfLm5vbW9zLmtlcm5lbC52MS5Pc2dpQ2FwYWJpbGl0eRI2CgxyZXF1aXJlbWVudHMYAyADKAsyIC5ub21vcy5rZXJuZWwudjEuT3NnaVJlcXVpcmVtZW50IucBChNWZXJpZnlDaGFpblN0ZXBTcGFuEg0KBWluZGV4GAEgASgEEhIKCmNvbW1pdF9vaWQYAiABKAkSDgoGZG9tYWluGAMgASgJEhEKCWRpcmVjdGl2ZRgEIAEoCRIQCgh0b3RhbF91cxgFIAEoBBI2CgZwaGFzZXMYBiABKAsyJi5ub21vcy5rZXJuZWwudjEuVmVyaWZ5Q2hhaW5TdGVwUGhhc2VzEkAKDmVuZ2luZV90aW1pbmdzGAcgAygLMigubm9tb3Mua2VybmVsLnYxLlZlcmlmeUNoYWluRW5naW5lVGltaW5nIpgCChVWZXJpZnlDaGFpblN0ZXBQaGFzZXMSHgoWcnVudGltZV9sYXdfcmVmcmVzaF91cxgBIAEoBBITCgttYW5pZmVzdF91cxgCIAEoBBIZChFsYXdfcmVzb2x1dGlvbl91cxgDIAEoBBIdChVtYW5hZ2VkX3RyYW5zaXRpb25fdXMYBCABKAQSFAoMcHJpbmNpcGFsX3VzGAUgASgEEhQKDGV2b2x1dGlvbl91cxgGIAEoBBIaChJjb2xvY2F0ZWRfcmVhZHNfdXMYByABKAQSIQoZdHlwZWRfaW5zdGFsbF92ZXJpZmllcl91cxgIIAEoBBIUCgxhZG1pc3Npb25fdXMYCSABKAQSDwoHZm9sZF91cxgKIAEoBCLaBQoWVmVyaWZ5Q2hhaW5EaWFnbm9zdGljcxIuCgR3YWxrGAEgASgOMiAubm9tb3Mua2VybmVsLnYxLlZlcmlmeUNoYWluV2FsaxIQCgh0b3RhbF91cxgCIAEoBBIbChNyZWZlcmVuY2VfbG9va3VwX3VzGAMgASgEEhoKEnJlcG9zaXRvcnlfb3Blbl91cxgEIAEoBBIVCg1jaGFpbl9yZWFkX3VzGAUgASgEEhYKDmVuZ2luZV9pbml0X3VzGAYgASgEEhgKEHRpbWVsaW5lX3JlYWRfdXMYByABKAQSGAoQbGF3X2h5ZHJhdGlvbl91cxgIIAEoBBIbChNyZWNvdmVyeV9wcmVzY2FuX3VzGAkgASgEEhgKEGZvbGRfZnJvbnRpZXJfdXMYCiABKAQSMwoFc3RlcHMYCyADKAsyJC5ub21vcy5rZXJuZWwudjEuVmVyaWZ5Q2hhaW5TdGVwU3BhbhJACg5lbmdpbmVfdGltaW5ncxgMIAMoCzIoLm5vbW9zLmtlcm5lbC52MS5WZXJpZnlDaGFpbkVuZ2luZVRpbWluZxJNChVsYXdfaHlkcmF0aW9uX3RpbWluZ3MYDSADKAsyLi5ub21vcy5rZXJuZWwudjEuVmVyaWZ5Q2hhaW5MYXdIeWRyYXRpb25UaW1pbmcSGQoRbGF3X2Nsb3N1cmVfY291bnQYDiABKAQSHgoWbGF3X2Nsb3N1cmVfY2FjaGVfaGl0cxgPIAEoBBIgChhsYXdfY2xvc3VyZV9jYWNoZV9taXNzZXMYECABKAQSEgoKc3RlcF9jb3VudBgRIAEoBBIVCg1zdGVwX3RvdGFsX3VzGBIgASgEEkEKEXN0ZXBfcGhhc2VfdG90YWxzGBMgASgLMiYubm9tb3Mua2VybmVsLnYxLlZlcmlmeUNoYWluU3RlcFBoYXNlcxIaChJvbWl0dGVkX3N0ZXBfY291bnQYFCABKAQiOgoXVmVyaWZ5Q2hhaW5FbmdpbmVUaW1pbmcSDQoFcGhhc2UYASABKAkSEAoIdG90YWxfdXMYAiABKAQiQAodVmVyaWZ5Q2hhaW5MYXdIeWRyYXRpb25UaW1pbmcSDQoFcGhhc2UYASABKAkSEAoIdG90YWxfdXMYAiABKAQiJAoUQXBwbGljYXRpb25Kc29uVmFsdWUSDAoEdXRmOBgBIAEoDCK2AgoNT3V0Ym91bmRPZmZlchIKCgJpZBgBIAEoCRITCgtkZXN0aW5hdGlvbhgCIAEoCRIUCgxzZWFsZWRfb2ZmZXIYAyABKAwSFAoMY29udGVudF90eXBlGAQgASgJEhgKEHNvdXJjZV93b3Jrc3BhY2UYBSABKAkSFAoMY3VzdG9keV9oZWFkGAYgASgJEhcKD2NhdXNlZF9ieV9vZmZlchgHIAEoCRIbChNzY2hlZHVsZWRfYXRfbWlsbGlzGAggASgEEhoKEmRlYWRsaW5lX2F0X21pbGxpcxgJIAEoBBIUCgxjdXN0b2R5X3BhdGgYCiABKAkSEwoLY3VzdG9keV9vaWQYCyABKAkSFAoMZGVsaXZlcnlfcmVmGAwgASgJEhUKDW9ibGlnYXRpb25faWQYDSABKAkieAoOT3V0Ym94UmVzcG9uc2USLgoGb2ZmZXJzGAEgAygLMh4ubm9tb3Mua2VybmVsLnYxLk91dGJvdW5kT2ZmZXISHwoSbmV4dF9kdWVfYXRfbWlsbGlzGAIgASgESACIAQFCFQoTX25leHRfZHVlX2F0X21pbGxpcyI8CgxTeW5jUmVzcG9uc2USLAoGcmVzdWx0GAEgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0IkIKD1dvcmtzcGFjZVRhcmdldBIMCgRyZXBvGAEgASgJEhEKCXdvcmtzcGFjZRgCIAEoCRIOCgZicmFuY2gYAyABKAkiTgoLT3BlblJlcXVlc3QSMAoGdGFyZ2V0GAEgASgLMiAubm9tb3Mua2VybmVsLnYxLldvcmtzcGFjZVRhcmdldBINCgVzcGFucxgCIAEoCCJhCg1EaXJlY3RpdmVDYWxsEg4KBmRvbWFpbhgBIAEoCRIRCglkaXJlY3RpdmUYAiABKAkSLQoHcGF5bG9hZBgDIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdCLAAgoQQXV0aG9yaW5nT3B0aW9ucxINCgVhY3RvchgBIAEoCRISCgphdXRoX3Rva2VuGAIgASgMEhUKDWF1dGhvcl9zZWNyZXQYAyABKAwSHQoQdmFsaWRfZnJvbV9lcG9jaBgEIAEoBEgAiAEBEh8KEnByaW5jaXBhbF92ZXJpZmllZBgFIAEoCEgBiAEBEgsKA3JuZxgGIAMoARIYChBkZWZlcl9wcm9qZWN0aW9uGAcgASgIEg0KBXNwYW5zGAggASgIEg8KB2RyeV9ydW4YCSABKAgSEAoIc2VxdWVuY2UYCiABKAQSLQoFY2xvY2sYCyABKAsyHi5ub21vcy5rZXJuZWwudjEuQ2FwdHVyZWRDbG9ja0ITChFfdmFsaWRfZnJvbV9lcG9jaEIVChNfcHJpbmNpcGFsX3ZlcmlmaWVkIkoKDUNhcHR1cmVkQ2xvY2sSFwoPcGh5c2ljYWxfbWlsbGlzGAEgASgEEg8KB2xvZ2ljYWwYAiABKA0SDwoHcmVwbGljYRgDIAEoBCLDAwoQQmlydGhDZXJ0aWZpY2F0ZRINCgVjaGlsZBgBIAEoCRIPCgdmb3VuZGVyGAIgASgJEhAKCHZlcmlmaWVkGAMgASgIEhIKCnBhcmVudF9rZXkYBCABKAwSEQoJcGFyZW50X2lkGAUgASgJEg0KBWVwb2NoGAYgASgDEhEKCXNpZ25hdHVyZRgHIAEoDBIZCgx2ZXJpZmllZF92aWEYCCABKAlIAIgBARIWCglpZHBfdG9rZW4YCSABKAlIAYgBARIbCg5jYXB0dXJlZF9jbG9jaxgKIAEoA0gCiAEBEiEKFGF1dGhfcHJvdmlkZXJfaXNzdWVyGAsgASgJSAOIAQESHwoSYXV0aF9wcm92aWRlcl9qd2tzGAwgASgJSASIAQESIwoWYXV0aF9wcm92aWRlcl9hdWRpZW5jZRgNIAEoCUgFiAEBQg8KDV92ZXJpZmllZF92aWFCDAoKX2lkcF90b2tlbkIRCg9fY2FwdHVyZWRfY2xvY2tCFwoVX2F1dGhfcHJvdmlkZXJfaXNzdWVyQhUKE19hdXRoX3Byb3ZpZGVyX2p3a3NCGQoXX2F1dGhfcHJvdmlkZXJfYXVkaWVuY2UinAQKDE9mZmVyUmVxdWVzdBIwCgZ0YXJnZXQYASABKAsyIC5ub21vcy5rZXJuZWwudjEuV29ya3NwYWNlVGFyZ2V0Ei4KBGNhbGwYAiABKAsyHi5ub21vcy5rZXJuZWwudjEuRGlyZWN0aXZlQ2FsbEgAEhwKEnNlYWxlZF9jaGFuZ2VfdXNkYRgHIAEoDEgAEjQKCWF1dGhvcmluZxgDIAEoCzIhLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpbmdPcHRpb25zEhAKCGxhd191c2R6GAQgASgMEjMKDGF0dGVzdGF0aW9ucxgFIAMoCzIdLm5vbW9zLmtlcm5lbC52MS5BdHRlc3RlZFJlYWQSPQoSY29uZmxpY3Rfc25hcHNob3RzGAYgAygLMiEubm9tb3Mua2VybmVsLnYxLkNvbmZsaWN0U25hcHNob3QSGgoSZXhlY3V0aW9uX2xhd191c2R6GAggASgMEiAKE2NvbnRyb2xsZXJfbGF3X2hhc2gYCSABKAlIAYgBARIdChBjYW5kaWRhdGVfY29tbWl0GAogASgJSAKIAQESPAoRYmlydGhfY2VydGlmaWNhdGUYCyABKAsyIS5ub21vcy5rZXJuZWwudjEuQmlydGhDZXJ0aWZpY2F0ZUIICgZpbnRlbnRCFgoUX2NvbnRyb2xsZXJfbGF3X2hhc2hCEwoRX2NhbmRpZGF0ZV9jb21taXQikwEKDEF0dGVzdGVkUmVhZBIQCghxdWVyeV9pZBgBIAEoCRIvCglhcmd1bWVudHMYAiABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3QSKwoGcmVzdWx0GAMgASgLMhsubm9tb3Mua2VybmVsLnYxLk5vbW9zVmFsdWUSEwoLYXR0ZXN0YXRpb24YBCABKAwidQoQQ29uZmxpY3RTbmFwc2hvdBIWCg5hZ2dyZWdhdGVfdHlwZRgBIAEoCRIUCgxhZ2dyZWdhdGVfaWQYAiABKAkSDQoFZmllbGQYAyABKAkSFQoNdGFyZ2V0X3NjaGVtYRgEIAEoCRINCgV0b2tlbhgFIAEoCSLlBQoMUXVlcnlSZXF1ZXN0EjAKBnRhcmdldBgBIAEoCzIgLm5vbW9zLmtlcm5lbC52MS5Xb3Jrc3BhY2VUYXJnZXQSMgoJYXV0aG9yaXR5GAIgASgLMh8ubm9tb3Mua2VybmVsLnYxLlF1ZXJ5QXV0aG9yaXR5Eg0KBXNwYW5zGAMgASgIEioKBHJvd3MYCiABKAsyGi5ub21vcy5rZXJuZWwudjEuUm93c1F1ZXJ5SAASKgoEcGFnZRgLIAEoCzIaLm5vbW9zLmtlcm5lbC52MS5QYWdlUXVlcnlIABIrCgVieV9pZBgMIAEoCzIaLm5vbW9zLmtlcm5lbC52MS5CeUlkUXVlcnlIABI5CgxyZXNvbHZlX3JlZnMYDSABKAsyIS5ub21vcy5rZXJuZWwudjEuUmVzb2x2ZVJlZnNRdWVyeUgAEkUKEnJlZmVyZW5jZV92ZXJzaW9ucxgOIAEoCzInLm5vbW9zLmtlcm5lbC52MS5SZWZlcmVuY2VWZXJzaW9uc1F1ZXJ5SAASLAoFY291bnQYDyABKAsyGy5ub21vcy5rZXJuZWwudjEuVGFsbHlRdWVyeUgAEioKA3N1bRgQIAEoCzIbLm5vbW9zLmtlcm5lbC52MS5UYWxseVF1ZXJ5SAASMAoHc3BhdGlhbBgRIAEoCzIdLm5vbW9zLmtlcm5lbC52MS5TcGF0aWFsUXVlcnlIABIsCgVuYW1lZBgSIAEoCzIbLm5vbW9zLmtlcm5lbC52MS5OYW1lZFF1ZXJ5SAASSQoTYXV0aG9yaXphdGlvbl9jaGVjaxgTIAEoCzIqLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uQ2hlY2tSZXF1ZXN0SAASSwoUYXV0aG9yaXphdGlvbl9leHBhbmQYFCABKAsyKy5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbkV4cGFuZFJlcXVlc3RIAEIHCgVxdWVyeSKSAQoOUXVlcnlBdXRob3JpdHkSFwoPcHJpbmNpcGFsX2NsYWltGAEgASgJEhIKCmF1dGhfdG9rZW4YAiABKAwSEAoIbm93X3VuaXgYAyABKAQSFQoNYXV0aG9yX3NlY3JldBgEIAEoDBIqCgRrZXlzGAUgAygLMhwubm9tb3Mua2VybmVsLnYxLkluamVjdGVkS2V5IjgKC0luamVjdGVkS2V5Eg0KBXNjb3BlGAEgASgJEg0KBWVwb2NoGAIgASgEEgsKA2tleRgDIAEoDCJbCglSb3dzUXVlcnkSCgoCaWQYASABKAkSLwoJYXJndW1lbnRzGAIgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0EhEKCXByaW5jaXBhbBgDIAEoCSJ5CglQYWdlUXVlcnkSCgoCaWQYASABKAkSLwoJYXJndW1lbnRzGAIgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0Eg0KBWxpbWl0GAMgASgNEg0KBWFmdGVyGAQgASgJEhEKCXByaW5jaXBhbBgFIAEoCSJMCglCeUlkUXVlcnkSFgoOYWdncmVnYXRlX3R5cGUYASABKAkSFAoMYWdncmVnYXRlX2lkGAIgASgJEhEKCXByaW5jaXBhbBgDIAEoCSJcCghOb21vc1JlZhIRCgl3b3Jrc3BhY2UYASABKAkSFgoOYWdncmVnYXRlX3R5cGUYAiABKAkSFAoMYWdncmVnYXRlX2lkGAMgASgJEg8KB3ZlcnNpb24YBCABKAkiTgoQUmVzb2x2ZVJlZnNRdWVyeRInCgRyZWZzGAEgAygLMhkubm9tb3Mua2VybmVsLnYxLk5vbW9zUmVmEhEKCXByaW5jaXBhbBgCIAEoCSJOChZSZWZlcmVuY2VWZXJzaW9uc1F1ZXJ5EjQKBHJlZnMYASADKAsyJi5ub21vcy5rZXJuZWwudjEuUmVmZXJlbmNlVmVyc2lvbkNoZWNrIoQBChVSZWZlcmVuY2VWZXJzaW9uQ2hlY2sSKQoGcGlubmVkGAEgASgLMhkubm9tb3Mua2VybmVsLnYxLk5vbW9zUmVmEikKBnNlcmllcxgCIAEoCzIZLm5vbW9zLmtlcm5lbC52MS5Ob21vc1JlZhIVCg1jdXJyZW50X2ZpZWxkGAMgASgJIlwKClRhbGx5UXVlcnkSCgoCaWQYASABKAkSLwoJYXJndW1lbnRzGAIgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0EhEKCXByaW5jaXBhbBgDIAEoCSJeCgxTcGF0aWFsUXVlcnkSCgoCaWQYASABKAkSLwoJYXJndW1lbnRzGAIgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0EhEKCXByaW5jaXBhbBgDIAEoCSJxCgpOYW1lZFF1ZXJ5EjIKCW9wZXJhdGlvbhgBIAEoDjIfLm5vbW9zLmtlcm5lbC52MS5RdWVyeU9wZXJhdGlvbhIvCglhcmd1bWVudHMYAiABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3QiLwoTQXV0aG9yaXphdGlvbk9iamVjdBIMCgR0eXBlGAEgASgJEgoKAmlkGAIgASgJIlQKFEF1dGhvcml6YXRpb25TdWJqZWN0EgwKBHR5cGUYASABKAkSCgoCaWQYAiABKAkSFQoIcmVsYXRpb24YAyABKAlIAIgBAUILCglfcmVsYXRpb24inAEKGFJlbGF0aW9uc2hpcFR1cGxlQWRkcmVzcxI2CghyZXNvdXJjZRgBIAEoCzIkLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uT2JqZWN0EhAKCHJlbGF0aW9uGAIgASgJEjYKB3N1YmplY3QYAyABKAsyJS5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvblN1YmplY3QigQEKGEF1dGhvcml6YXRpb25Db25zaXN0ZW5jeRIjChljdXJyZW50X3ZlcmlmaWVkX2Zyb250aWVyGAEgASgISAASGQoPYXRfbGVhc3RfY29tbWl0GAIgASgJSAASFgoMZXhhY3RfY29tbWl0GAMgASgJSABCDQoLcmVxdWlyZW1lbnQiZgodQXV0aG9yaXphdGlvbkNvbmRpdGlvbkNvbnRleHQSFAoMY29uZGl0aW9uX2lkGAEgASgJEi8KCWFyZ3VtZW50cxgCIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdCL3AgoZQXV0aG9yaXphdGlvbkNoZWNrUmVxdWVzdBI2CghyZXNvdXJjZRgBIAEoCzIkLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uT2JqZWN0EhIKCnBlcm1pc3Npb24YAiABKAkSNgoHc3ViamVjdBgDIAEoCzIlLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uU3ViamVjdBI+Cgtjb25zaXN0ZW5jeRgEIAEoCzIpLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uQ29uc2lzdGVuY3kSPwoHY29udGV4dBgFIAMoCzIuLm5vbW9zLmtlcm5lbC52MS5BdXRob3JpemF0aW9uQ29uZGl0aW9uQ29udGV4dBIgChNleHBlY3RlZF9tb2RlbF9oYXNoGAYgASgJSACIAQESGwoTaW5jbHVkZV9leHBsYW5hdGlvbhgHIAEoCEIWChRfZXhwZWN0ZWRfbW9kZWxfaGFzaCLtAgoaQXV0aG9yaXphdGlvbkV4cGFuZFJlcXVlc3QSNgoIcmVzb3VyY2UYASABKAsyJC5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbk9iamVjdBISCgpwZXJtaXNzaW9uGAIgASgJEj4KC2NvbnNpc3RlbmN5GAMgASgLMikubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25Db25zaXN0ZW5jeRI/Cgdjb250ZXh0GAQgAygLMi4ubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25Db25kaXRpb25Db250ZXh0EiAKE2V4cGVjdGVkX21vZGVsX2hhc2gYBSABKAlIAIgBARINCgVsaW1pdBgGIAEoDRISCgVhZnRlchgHIAEoCUgBiAEBEhsKE2luY2x1ZGVfZXhwbGFuYXRpb24YCCABKAhCFgoUX2V4cGVjdGVkX21vZGVsX2hhc2hCCAoGX2FmdGVyIr0BChlSZWxhdGlvbnNoaXBUdXBsZUV2aWRlbmNlEjgKBXR1cGxlGAEgASgLMikubm9tb3Mua2VybmVsLnYxLlJlbGF0aW9uc2hpcFR1cGxlQWRkcmVzcxIQCgh0dXBsZV9pZBgCIAEoCRIaChJhc3NlcnRpb25fZXZlbnRfaWQYAyABKAkSIAoTcmV2b2NhdGlvbl9ldmVudF9pZBgEIAEoCUgAiAEBQhYKFF9yZXZvY2F0aW9uX2V2ZW50X2lkIuEDChhBdXRob3JpemF0aW9uRXhwbGFuYXRpb24SRgoJb3BlcmF0aW9uGAEgASgOMjMubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25FeHBsYW5hdGlvbi5PcGVyYXRpb24SEAoIcmVsYXRpb24YAiABKAkSDgoGcmVzdWx0GAMgASgIEjwKCGV2aWRlbmNlGAQgAygLMioubm9tb3Mua2VybmVsLnYxLlJlbGF0aW9uc2hpcFR1cGxlRXZpZGVuY2USOwoIY2hpbGRyZW4YBSADKAsyKS5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbkV4cGxhbmF0aW9uIt8BCglPcGVyYXRpb24SGQoVT1BFUkFUSU9OX1VOU1BFQ0lGSUVEEAASFAoQT1BFUkFUSU9OX0RJUkVDVBABEh4KGk9QRVJBVElPTl9DT01QVVRFRF9VU0VSU0VUEAISHgoaT1BFUkFUSU9OX1RVUExFX1RPX1VTRVJTRVQQAxITCg9PUEVSQVRJT05fVU5JT04QBBIaChZPUEVSQVRJT05fSU5URVJTRUNUSU9OEAUSFwoTT1BFUkFUSU9OX0VYQ0xVU0lPThAGEhcKE09QRVJBVElPTl9DT05ESVRJT04QByJ3ChpBdXRob3JpemF0aW9uRGVjaXNpb25CYXNpcxIgChhhdXRob3JpemF0aW9uX21vZGVsX2hhc2gYASABKAkSIQoZcmVsYXRpb25zaGlwX3N0YXRlX2NvbW1pdBgCIAEoCRIUCgxjb250ZXh0X2hhc2gYAyABKAwivgEKGkF1dGhvcml6YXRpb25DaGVja1Jlc3BvbnNlEg8KB2FsbG93ZWQYASABKAgSOgoFYmFzaXMYAiABKAsyKy5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbkRlY2lzaW9uQmFzaXMSQwoLZXhwbGFuYXRpb24YAyABKAsyKS5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbkV4cGxhbmF0aW9uSACIAQFCDgoMX2V4cGxhbmF0aW9uIoMCChtBdXRob3JpemF0aW9uRXhwYW5kUmVzcG9uc2USNwoIc3ViamVjdHMYASADKAsyJS5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvblN1YmplY3QSOgoFYmFzaXMYAiABKAsyKy5ub21vcy5rZXJuZWwudjEuQXV0aG9yaXphdGlvbkRlY2lzaW9uQmFzaXMSEQoEbmV4dBgDIAEoCUgAiAEBEkMKC2V4cGxhbmF0aW9uGAQgASgLMikubm9tb3Mua2VybmVsLnYxLkF1dGhvcml6YXRpb25FeHBsYW5hdGlvbkgBiAEBQgcKBV9uZXh0Qg4KDF9leHBsYW5hdGlvbiJwCg1PdXRib3hSZXF1ZXN0EjAKBnRhcmdldBgBIAEoCzIgLm5vbW9zLmtlcm5lbC52MS5Xb3Jrc3BhY2VUYXJnZXQSLQoFY2xvY2sYAiABKAsyHi5ub21vcy5rZXJuZWwudjEuQ2FwdHVyZWRDbG9jayJjCgtTeW5jUmVxdWVzdBIwCgZ0YXJnZXQYASABKAsyIC5ub21vcy5rZXJuZWwudjEuV29ya3NwYWNlVGFyZ2V0EhEKCWZyb21fYmFzZRgCIAEoCRIPCgd0b19oZWFkGAMgASgJIlMKC1Rlc3RSZXF1ZXN0EjcKCHNldF9yb290GAEgASgLMiMubm9tb3Mua2VybmVsLnYxLlNldFRlc3RSb290UmVxdWVzdEgAQgsKCW9wZXJhdGlvbiIoChJTZXRUZXN0Um9vdFJlcXVlc3QSEgoKcHVibGljX2tleRgBIAEoDCI9CgxUZXN0UmVzcG9uc2USLQoGcmVzdWx0GAEgASgLMh0ubm9tb3Mua2VybmVsLnYxLkFja25vd2xlZGdlZCK2CgoOQ3VzdG9keVJlcXVlc3QSNwoKcGFja19kZWx0YRgKIAEoCzIhLm5vbW9zLmtlcm5lbC52MS5QYWNrRGVsdGFSZXF1ZXN0SAASNwoKYXBwbHlfcGFjaxgLIAEoCzIhLm5vbW9zLmtlcm5lbC52MS5BcHBseVBhY2tSZXF1ZXN0SAASNwoKcmVwb19zdGF0cxgMIAEoCzIhLm5vbW9zLmtlcm5lbC52MS5SZXBvU3RhdHNSZXF1ZXN0SAASPQoNaW50ZW50c19hYm92ZRgNIAEoCzIkLm5vbW9zLmtlcm5lbC52MS5JbnRlbnRzQWJvdmVSZXF1ZXN0SAASPwoOaW5zcGVjdF9jaGFuZ2UYDiABKAsyJS5ub21vcy5rZXJuZWwudjEuSW5zcGVjdENoYW5nZVJlcXVlc3RIABJOChZlbmNvZGVfcmVmdXNhbF92ZXJkaWN0GA8gASgLMiwubm9tb3Mua2VybmVsLnYxLkVuY29kZVJlZnVzYWxWZXJkaWN0UmVxdWVzdEgAElAKF2luc3BlY3RfcmVmdXNhbF92ZXJkaWN0GBAgASgLMi0ubm9tb3Mua2VybmVsLnYxLkluc3BlY3RSZWZ1c2FsVmVyZGljdFJlcXVlc3RIABI1CglyZWFkX2Jsb2IYESABKAsyIC5ub21vcy5rZXJuZWwudjEuUmVhZEJsb2JSZXF1ZXN0SAASOQoLcmVzb2x2ZV9yZWYYEiABKAsyIi5ub21vcy5rZXJuZWwudjEuUmVzb2x2ZVJlZlJlcXVlc3RIABI1CglsaXN0X3JlZnMYEyABKAsyIC5ub21vcy5rZXJuZWwudjEuTGlzdFJlZnNSZXF1ZXN0SAASNQoJd3JpdGVfcmVmGBQgASgLMiAubm9tb3Mua2VybmVsLnYxLldyaXRlUmVmUmVxdWVzdEgAEjcKCmRlbGV0ZV9yZWYYFSABKAsyIS5ub21vcy5rZXJuZWwudjEuRGVsZXRlUmVmUmVxdWVzdEgAEkQKEXdyaXRlX21ldGFfY29tbWl0GBYgASgLMicubm9tb3Mua2VybmVsLnYxLldyaXRlTWV0YUNvbW1pdFJlcXVlc3RIABJCChBsYXdfY2xvc3VyZV9pbmZvGBcgASgLMiYubm9tb3Mua2VybmVsLnYxLkxhd0Nsb3N1cmVJbmZvUmVxdWVzdEgAEkUKEWNoZWNrcG9pbnRfZXhwb3J0GBggASgLMigubm9tb3Mua2VybmVsLnYxLkNoZWNrcG9pbnRFeHBvcnRSZXF1ZXN0SAASRQoRY2hlY2twb2ludF9pbXBvcnQYGSABKAsyKC5ub21vcy5rZXJuZWwudjEuQ2hlY2twb2ludEltcG9ydFJlcXVlc3RIABJDChBjYXBhY2l0eV9yZXNlcnZlGBogASgLMicubm9tb3Mua2VybmVsLnYxLkNhcGFjaXR5UmVzZXJ2ZVJlcXVlc3RIABI7CgxyZXN0b3JlX21haW4YGyABKAsyIy5ub21vcy5rZXJuZWwudjEuUmVzdG9yZU1haW5SZXF1ZXN0SAASTgoWcmVzb2x2ZV9zdGF0ZV9wb3NpdGlvbhgcIAEoCzIsLm5vbW9zLmtlcm5lbC52MS5SZXNvbHZlU3RhdGVQb3NpdGlvblJlcXVlc3RIABJHChJyZXNpZGVudF9mb290cHJpbnQYHSABKAsyKS5ub21vcy5rZXJuZWwudjEuUmVzaWRlbnRGb290cHJpbnRSZXF1ZXN0SABCCwoJb3BlcmF0aW9uIigKGFJlc2lkZW50Rm9vdHByaW50UmVxdWVzdBIMCgRkZWVwGAEgASgIIp8CChFSZXNpZGVudEZvb3RwcmludBIRCgl3b3Jrc3BhY2UYASABKAkSDgoGYnJhbmNoGAIgASgJEhgKEHJlYWRfbW9kZWxfYnl0ZXMYAyABKAQSHQoVcmVhZF9tb2RlbF9ydXN0X2J5dGVzGAQgASgEEhgKEGZvbGRfc3RhdGVfYnl0ZXMYBSABKAQSEwoLZm9sZF9pbWFnZXMYBiABKA0SHwoXc2hhcmVkX2F0dHJpYnV0ZWRfYnl0ZXMYByABKAQSEgoKYWdncmVnYXRlcxgIIAEoBBI2Cgpjb21wb25lbnRzGAkgAygLMiIubm9tb3Mua2VybmVsLnYxLlJlc2lkZW50Q29tcG9uZW50EhIKCmNvbXB1dGVfdXMYCiABKAQiaQoRUmVzaWRlbnRDb21wb25lbnQSNAoEa2luZBgBIAEoDjImLm5vbW9zLmtlcm5lbC52MS5SZXNpZGVudENvbXBvbmVudEtpbmQSDQoFYnl0ZXMYAiABKAQSDwoHY2VpbGluZxgDIAEoCCLKAQoZUmVzaWRlbnRGb290cHJpbnRSZXNwb25zZRI1CglyZXNpZGVudHMYASADKAsyIi5ub21vcy5rZXJuZWwudjEuUmVzaWRlbnRGb290cHJpbnQSHAoUYWxsb2NhdG9yX2xpdmVfYnl0ZXMYAiABKAQSGAoQYXR0cmlidXRlZF9ieXRlcxgDIAEoBBIZChF1bmFjY291bnRlZF9ieXRlcxgEIAEoBBIVCg1hY2NvdW50aW5nX3VzGAUgASgEEgwKBGRlZXAYBiABKAginAEKEFBhY2tEZWx0YVJlcXVlc3QSDAoEcmVwbxgBIAEoCRIRCgRoZWFkGAIgASgJSACIAQESEQoEYmFzZRgDIAEoCUgBiAEBEg4KBmJyYW5jaBgEIAEoCRIdChBzdGFnZWRfcGFja19maWxlGAUgASgJSAKIAQFCBwoFX2hlYWRCBwoFX2Jhc2VCEwoRX3N0YWdlZF9wYWNrX2ZpbGUicgoQQXBwbHlQYWNrUmVxdWVzdBIMCgRyZXBvGAEgASgJEg4KBHBhY2sYAiABKAxIABIaChBzdGFnZWRfcGFja19maWxlGAQgASgJSAASEQoEaGVhZBgDIAEoCUgBiAEBQggKBnNvdXJjZUIHCgVfaGVhZCIgChBSZXBvU3RhdHNSZXF1ZXN0EgwKBHJlcG8YASABKAkirAEKE0ludGVudHNBYm92ZVJlcXVlc3QSDAoEcmVwbxgBIAEoCRIRCgRoZWFkGAIgASgJSACIAQESEQoEYmFzZRgDIAEoCUgBiAEBEg4KBmJyYW5jaBgEIAEoCRINCgVsaW1pdBgFIAEoBBIYChBjb21wbGV0ZV9sb2dpY2FsGAYgASgIEhYKDmNvbXBhY3Rfc3RvcmVkGAcgASgIQgcKBV9oZWFkQgcKBV9iYXNlIisKFEluc3BlY3RDaGFuZ2VSZXF1ZXN0EhMKC2NoYW5nZV91c2RhGAEgASgMIt8BCg5SZWZ1c2FsVmVyZGljdBIVCghvZmZlcl9pZBgBIAEoCUgAiAEBEhAKA29pZBgCIAEoCUgBiAEBEhMKBmRvbWFpbhgDIAEoCUgCiAEBEhkKDGRpcmVjdGl2ZV9pZBgEIAEoCUgDiAEBEhQKB3Nlc3Npb24YBSABKAlIBIgBARIRCglwYXJrZWRfYXQYBiABKAkSDgoGcmVhc29uGAcgASgJQgsKCV9vZmZlcl9pZEIGCgRfb2lkQgkKB19kb21haW5CDwoNX2RpcmVjdGl2ZV9pZEIKCghfc2Vzc2lvbiJPChtFbmNvZGVSZWZ1c2FsVmVyZGljdFJlcXVlc3QSMAoHdmVyZGljdBgBIAEoCzIfLm5vbW9zLmtlcm5lbC52MS5SZWZ1c2FsVmVyZGljdCI0ChxJbnNwZWN0UmVmdXNhbFZlcmRpY3RSZXF1ZXN0EhQKDHZlcmRpY3RfdXNkYRgBIAEoDCI6Cg9SZWFkQmxvYlJlcXVlc3QSDAoEcmVwbxgBIAEoCRILCgNvaWQYAiABKAkSDAoEcGF0aBgDIAEoCSI0ChFSZXNvbHZlUmVmUmVxdWVzdBIMCgRyZXBvGAEgASgJEhEKCXJlZmVyZW5jZRgCIAEoCSIvCg9MaXN0UmVmc1JlcXVlc3QSDAoEcmVwbxgBIAEoCRIOCgZwcmVmaXgYAiABKAkiQgoPV3JpdGVSZWZSZXF1ZXN0EgwKBHJlcG8YASABKAkSEQoJcmVmZXJlbmNlGAIgASgJEg4KBnRhcmdldBgDIAEoCSIzChBEZWxldGVSZWZSZXF1ZXN0EgwKBHJlcG8YASABKAkSEQoJcmVmZXJlbmNlGAIgASgJIikKCE1ldGFGaWxlEgwKBHBhdGgYASABKAkSDwoHY29udGVudBgCIAEoDCKuAQoWV3JpdGVNZXRhQ29tbWl0UmVxdWVzdBIMCgRyZXBvGAEgASgJEg8KB3BhcmVudHMYAiADKAkSKAoFZmlsZXMYAyADKAsyGS5ub21vcy5rZXJuZWwudjEuTWV0YUZpbGUSDwoHbWVzc2FnZRgEIAEoCRIUCgx0aW1lX3NlY29uZHMYBSABKBISFgoJcmVmZXJlbmNlGAYgASgJSACIAQFCDAoKX3JlZmVyZW5jZSJnChVMYXdDbG9zdXJlSW5mb1JlcXVlc3QSFAoMY2xvc3VyZV9maWxlGAEgASgJEjgKCmNhcGFiaWxpdHkYAiABKA4yJC5ub21vcy5rZXJuZWwudjEuS2VybmVsTGF3Q2FwYWJpbGl0eSKHAQoXQ2hlY2twb2ludEV4cG9ydFJlcXVlc3QSMAoGdGFyZ2V0GAEgASgLMiAubm9tb3Mua2VybmVsLnYxLldvcmtzcGFjZVRhcmdldBIhChRzdGFnZWRfZnJvbnRpZXJfZmlsZRgCIAEoCUgAiAEBQhcKFV9zdGFnZWRfZnJvbnRpZXJfZmlsZSLpAQoXQ2hlY2twb2ludEltcG9ydFJlcXVlc3QSMAoGdGFyZ2V0GAEgASgLMiAubm9tb3Mua2VybmVsLnYxLldvcmtzcGFjZVRhcmdldBISCghmcm9udGllchgCIAEoDEgAEh4KFHN0YWdlZF9mcm9udGllcl9maWxlGAYgASgJSAASEwoGY3Vyc29yGAMgASgJSAGIAQESFwoKc3RhdGVfcm9vdBgEIAEoCUgCiAEBEg0KBXNwYW5zGAUgASgIQhEKD2Zyb250aWVyX3NvdXJjZUIJCgdfY3Vyc29yQg0KC19zdGF0ZV9yb290IjEKFkNhcGFjaXR5UmVzZXJ2ZVJlcXVlc3QSFwoPYWdncmVnYXRlX2NvdW50GAEgASgEImkKElJlc3RvcmVNYWluUmVxdWVzdBIwCgZ0YXJnZXQYASABKAsyIC5ub21vcy5rZXJuZWwudjEuV29ya3NwYWNlVGFyZ2V0EgwKBGhlYWQYAiABKAkSEwoLZGlhZ25vc3RpY3MYAyABKAgiaQobUmVzb2x2ZVN0YXRlUG9zaXRpb25SZXF1ZXN0EgwKBHJlcG8YASABKAkSEQoJbWFpbl9oZWFkGAIgASgJEhUKDWhpbnRlZF9jb21taXQYAyABKAkSEgoKc3RhdGVfcm9vdBgEIAEoCSLCCgoPQ3VzdG9keVJlc3BvbnNlEjgKCnBhY2tfZGVsdGEYCiABKAsyIi5ub21vcy5rZXJuZWwudjEuUGFja0RlbHRhUmVzcG9uc2VIABI4CgphcHBseV9wYWNrGAsgASgLMiIubm9tb3Mua2VybmVsLnYxLkFwcGx5UGFja1Jlc3BvbnNlSAASOAoKcmVwb19zdGF0cxgMIAEoCzIiLm5vbW9zLmtlcm5lbC52MS5SZXBvU3RhdHNSZXNwb25zZUgAEj4KDWludGVudHNfYWJvdmUYDSABKAsyJS5ub21vcy5rZXJuZWwudjEuSW50ZW50c0Fib3ZlUmVzcG9uc2VIABJACg5pbnNwZWN0X2NoYW5nZRgOIAEoCzImLm5vbW9zLmtlcm5lbC52MS5JbnNwZWN0Q2hhbmdlUmVzcG9uc2VIABJPChZlbmNvZGVfcmVmdXNhbF92ZXJkaWN0GA8gASgLMi0ubm9tb3Mua2VybmVsLnYxLkVuY29kZVJlZnVzYWxWZXJkaWN0UmVzcG9uc2VIABJRChdpbnNwZWN0X3JlZnVzYWxfdmVyZGljdBgQIAEoCzIuLm5vbW9zLmtlcm5lbC52MS5JbnNwZWN0UmVmdXNhbFZlcmRpY3RSZXNwb25zZUgAEjYKCXJlYWRfYmxvYhgRIAEoCzIhLm5vbW9zLmtlcm5lbC52MS5SZWFkQmxvYlJlc3BvbnNlSAASOgoLcmVzb2x2ZV9yZWYYEiABKAsyIy5ub21vcy5rZXJuZWwudjEuUmVzb2x2ZVJlZlJlc3BvbnNlSAASNgoJbGlzdF9yZWZzGBMgASgLMiEubm9tb3Mua2VybmVsLnYxLkxpc3RSZWZzUmVzcG9uc2VIABIyCgl3cml0ZV9yZWYYFCABKAsyHS5ub21vcy5rZXJuZWwudjEuQWNrbm93bGVkZ2VkSAASMwoKZGVsZXRlX3JlZhgVIAEoCzIdLm5vbW9zLmtlcm5lbC52MS5BY2tub3dsZWRnZWRIABJFChF3cml0ZV9tZXRhX2NvbW1pdBgWIAEoCzIoLm5vbW9zLmtlcm5lbC52MS5Xcml0ZU1ldGFDb21taXRSZXNwb25zZUgAEkMKEGxhd19jbG9zdXJlX2luZm8YFyABKAsyJy5ub21vcy5rZXJuZWwudjEuTGF3Q2xvc3VyZUluZm9SZXNwb25zZUgAEkYKEWNoZWNrcG9pbnRfZXhwb3J0GBggASgLMikubm9tb3Mua2VybmVsLnYxLkNoZWNrcG9pbnRFeHBvcnRSZXNwb25zZUgAEkYKEWNoZWNrcG9pbnRfaW1wb3J0GBkgASgLMikubm9tb3Mua2VybmVsLnYxLkNoZWNrcG9pbnRJbXBvcnRSZXNwb25zZUgAEkQKEGNhcGFjaXR5X3Jlc2VydmUYGiABKAsyKC5ub21vcy5rZXJuZWwudjEuQ2FwYWNpdHlSZXNlcnZlUmVzcG9uc2VIABI8CgxyZXN0b3JlX21haW4YGyABKAsyJC5ub21vcy5rZXJuZWwudjEuUmVzdG9yZU1haW5SZXNwb25zZUgAEk8KFnJlc29sdmVfc3RhdGVfcG9zaXRpb24YHCABKAsyLS5ub21vcy5rZXJuZWwudjEuUmVzb2x2ZVN0YXRlUG9zaXRpb25SZXNwb25zZUgAEkgKEnJlc2lkZW50X2Zvb3RwcmludBgdIAEoCzIqLm5vbW9zLmtlcm5lbC52MS5SZXNpZGVudEZvb3RwcmludFJlc3BvbnNlSABCCwoJb3BlcmF0aW9uIjAKEVBhY2tEZWx0YVJlc3BvbnNlEgwKBHBhY2sYASABKAwSDQoFYnl0ZXMYAiABKAQiPAoRQXBwbHlQYWNrUmVzcG9uc2USFAoMb2JqZWN0X2NvdW50GAEgASgEEhEKCXBhY2tfaGFzaBgCIAEoCSKnAQoRUmVwb1N0YXRzUmVzcG9uc2USEwoLdG90YWxfYnl0ZXMYASABKAQSFAoMb2JqZWN0X2J5dGVzGAIgASgEEhUKDWxvb3NlX29iamVjdHMYAyABKAQSEwoLbG9vc2VfYnl0ZXMYBCABKAQSEgoKcGFja19maWxlcxgFIAEoBBISCgpwYWNrX2J5dGVzGAYgASgEEhMKC2luZGV4X2J5dGVzGAcgASgEIuIBCgxJbnRlbnRSZWNvcmQSCwoDb2lkGAEgASgJEhEKCWludGVudF9pZBgCIAEoCRIOCgZkb21haW4YAyABKAkSEQoJZGlyZWN0aXZlGAQgASgJEhMKC2NoYW5nZV91c2RhGAUgASgMEi4KCHNlbWFudGljGAYgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0EkoKFXRyYW5zcG9ydF9yZXF1aXJlbWVudBgHIAEoDjIrLm5vbW9zLmtlcm5lbC52MS5JbnRlbnRUcmFuc3BvcnRSZXF1aXJlbWVudCJGChRJbnRlbnRzQWJvdmVSZXNwb25zZRIuCgdpbnRlbnRzGAEgAygLMh0ubm9tb3Mua2VybmVsLnYxLkludGVudFJlY29yZCJCChNOb21pbmFsQ2FsbElkZW50aXR5EhMKC2RvbWFpbl9wYXRoGAEgASgJEhYKDmRpcmVjdGl2ZV9wYXRoGAIgASgJIogBChhMaWZlY3ljbGVJbnN0YWxsSWRlbnRpdHkSHwoXdGFyZ2V0X2Nsb3N1cmVfaWRlbnRpdHkYASABKAkSFAoMaW5zdGFsbGVkX2J5GAIgASgJEjUKBXBoYXNlGAMgASgOMiYubm9tb3Mua2VybmVsLnYxLkxpZmVjeWNsZUluc3RhbGxQaGFzZSJaCh1Xb3Jrc3BhY2VSZXNpZGVuY3lSZXF1aXJlbWVudBIRCgl3b3Jrc3BhY2UYASABKAkSEwoLc291cmNlX2hlYWQYAiABKAkSEQoJZm9sZF9yb290GAMgASgJIrQCChVJbnNwZWN0Q2hhbmdlUmVzcG9uc2USLgoIc2VtYW50aWMYASABKAsyHC5ub21vcy5rZXJuZWwudjEuTm9tb3NTdHJ1Y3QSEQoJaW50ZW50X2lkGAIgASgJEjIKBGNhbGwYAyABKAsyJC5ub21vcy5rZXJuZWwudjEuTm9taW5hbENhbGxJZGVudGl0eRIQCghhdXRob3JlZBgEIAEoCBJEChFsaWZlY3ljbGVfaW5zdGFsbBgFIAEoCzIpLm5vbW9zLmtlcm5lbC52MS5MaWZlY3ljbGVJbnN0YWxsSWRlbnRpdHkSTAoUcmVxdWlyZWRfcmVzaWRlbmNpZXMYBiADKAsyLi5ub21vcy5rZXJuZWwudjEuV29ya3NwYWNlUmVzaWRlbmN5UmVxdWlyZW1lbnQiTAocUmVzb2x2ZVN0YXRlUG9zaXRpb25SZXNwb25zZRIaCg1yZXNvbHZlZF9oZWFkGAEgASgJSACIAQFCEAoOX3Jlc29sdmVkX2hlYWQiNAocRW5jb2RlUmVmdXNhbFZlcmRpY3RSZXNwb25zZRIUCgx2ZXJkaWN0X3VzZGEYASABKAwiUQodSW5zcGVjdFJlZnVzYWxWZXJkaWN0UmVzcG9uc2USMAoHdmVyZGljdBgBIAEoCzIfLm5vbW9zLmtlcm5lbC52MS5SZWZ1c2FsVmVyZGljdCIvChBSZWFkQmxvYlJlc3BvbnNlEg0KBWZvdW5kGAEgASgIEgwKBGJsb2IYAiABKAwiLgoSUmVzb2x2ZVJlZlJlc3BvbnNlEhAKA29pZBgBIAEoCUgAiAEBQgYKBF9vaWQiKwoJUmVmUmVjb3JkEhEKCXJlZmVyZW5jZRgBIAEoCRILCgNvaWQYAiABKAkiPAoQTGlzdFJlZnNSZXNwb25zZRIoCgRyZWZzGAEgAygLMhoubm9tb3Mua2VybmVsLnYxLlJlZlJlY29yZCIOCgxBY2tub3dsZWRnZWQiJgoXV3JpdGVNZXRhQ29tbWl0UmVzcG9uc2USCwoDb2lkGAEgASgJIoMBChZMYXdDbG9zdXJlSW5mb1Jlc3BvbnNlEhAKCGlkZW50aXR5GAEgASgJEhkKEXJvb3RfbG9naWNhbF9wYXRoGAIgASgJEhMKC2Fzc2V0X2NvdW50GAMgASgEEhIKCnByaW1fY291bnQYBCABKAQSEwoLZG9tYWluX2tleXMYBSADKAki7wIKGENoZWNrcG9pbnRFeHBvcnRSZXNwb25zZRINCgVlbXB0eRgBIAEoCBITCgZjdXJzb3IYAiABKAlIAIgBARIQCghmcm9udGllchgDIAEoDBIXCgpzdGF0ZV9yb290GAQgASgJSAGIAQESEgoKc3RhdGVfdHJlZRgFIAEoCBIOCgZwaW5uZWQYBiABKAgSGwoTcmVhZF9pbmRleF9zbmFwc2hvdBgHIAEoCBIjChtyZWFkX2luZGV4X3NuYXBzaG90X3BlbmRpbmcYCCABKAgSJAoXcmVhZF9pbmRleF9zcWxpdGVfYnl0ZXMYCSABKARIAogBARIlChhyZWFkX2luZGV4X2N1c3RvZHlfYnl0ZXMYCiABKARIA4gBAUIJCgdfY3Vyc29yQg0KC19zdGF0ZV9yb290QhoKGF9yZWFkX2luZGV4X3NxbGl0ZV9ieXRlc0IbChlfcmVhZF9pbmRleF9jdXN0b2R5X2J5dGVzIp4CChhDaGVja3BvaW50SW1wb3J0UmVzcG9uc2USEAoIcmVzdG9yZWQYASABKAgSEwoGcmVhc29uGAIgASgJSACIAQESFwoPZnJvbnRpZXJfc2VlZGVkGAMgASgIEiUKHWZyb250aWVyX3ZlcmlmaWNhdGlvbl9wZW5kaW5nGAQgASgIEhcKD2FnZ3JlZ2F0ZV9jb3VudBgFIAEoBBIrCgVzcGFucxgGIAEoCzIcLm5vbW9zLmtlcm5lbC52MS5Ob21vc1N0cnVjdBITCgZjdXJzb3IYByABKAlIAYgBARIRCglyZWFkX29ubHkYCCABKAgSFwoPbGF6eV9yZWFkX2luZGV4GAkgASgIQgkKB19yZWFzb25CCQoHX2N1cnNvciJKChdDYXBhY2l0eVJlc2VydmVSZXNwb25zZRIXCg9hZ2dyZWdhdGVfY291bnQYASABKAQSFgoOcmVzZXJ2ZWRfYnl0ZXMYAiABKAQi+QIKEFJlc3RvcmVNYWluU3BhbnMSEAoIdG90YWxfdXMYASABKAQSGgoSbGl2ZV9yZWZfbG9va3VwX3VzGAIgASgEEhgKEHRhcmdldF9kZWNvZGVfdXMYAyABKAQSJAocY3VzdG9keV9jb21wbGV0ZW5lc3NfcmVhZF91cxgEIAEoBBIZChFxdWFyYW50aW5lX3JlZl91cxgFIAEoBBIlCh1jaGFpbl9zaWduYXR1cmVfbGF3X3JlcGxheV91cxgGIAEoBBIZChF2ZXJkaWN0X2RlY29kZV91cxgHIAEoBBIjChtwcm9tb3RlX2FuZF9jbGVhbnVwX3JlZnNfdXMYCCABKAQSGwoTZnJvbnRpZXJfcmVidWlsZF91cxgJIAEoBBIZChFmcm9udGllcl9zdG9yZV91cxgKIAEoBBI9Cgx2ZXJpZmljYXRpb24YCyABKAsyJy5ub21vcy5rZXJuZWwudjEuVmVyaWZ5Q2hhaW5EaWFnbm9zdGljcyKkAQoTUmVzdG9yZU1haW5SZXNwb25zZRIMCgRoZWFkGAEgASgJEhAKCHZlcmlmaWVkGAIgASgIEgwKBHdhbGsYAyABKAkSMAoFc3BhbnMYBCABKAsyIS5ub21vcy5rZXJuZWwudjEuUmVzdG9yZU1haW5TcGFucxItCgd2ZXJkaWN0GAUgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0IpsCCgpOb21vc1ZhbHVlEiUKBG51bGwYASABKAsyFS5ub21vcy5rZXJuZWwudjEuTnVsbEgAEhEKB2Jvb2xlYW4YAiABKAhIABIYCg5zaWduZWRfaW50ZWdlchgDIAEoEkgAEhoKEHVuc2lnbmVkX2ludGVnZXIYBCABKARIABIYCg5mbG9hdGluZ19wb2ludBgFIAEoAUgAEg4KBHRleHQYBiABKAlIABIPCgVieXRlcxgHIAEoDEgAEioKBGxpc3QYCCABKAsyGi5ub21vcy5rZXJuZWwudjEuTm9tb3NMaXN0SAASLgoGb2JqZWN0GAkgASgLMhwubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0SABCBgoEa2luZCIGCgROdWxsIjgKCU5vbW9zTGlzdBIrCgZ2YWx1ZXMYASADKAsyGy5ub21vcy5rZXJuZWwudjEuTm9tb3NWYWx1ZSKTAQoLTm9tb3NTdHJ1Y3QSOAoGZmllbGRzGAEgAygLMigubm9tb3Mua2VybmVsLnYxLk5vbW9zU3RydWN0LkZpZWxkc0VudHJ5GkoKC0ZpZWxkc0VudHJ5EgsKA2tleRgBIAEoCRIqCgV2YWx1ZRgCIAEoCzIbLm5vbW9zLmtlcm5lbC52MS5Ob21vc1ZhbHVlOgI4ASrpEgoRS2VybmVsUmVmdXNhbENvZGUSIwofS0VSTkVMX1JFRlVTQUxfQ09ERV9VTlNQRUNJRklFRBAAEiUKIUtFUk5FTF9SRUZVU0FMX0NPREVfQkFEX1NJR05BVFVSRRABEiQKIEtFUk5FTF9SRUZVU0FMX0NPREVfVU5BVVRIT1JJWkVEEAISJwojS0VSTkVMX1JFRlVTQUxfQ09ERV9QT0xJQ1lfRElTQUJMRUQQAxIqCiZLRVJORUxfUkVGVVNBTF9DT0RFX1VOQ0VSVElGSUVEX1BPTElDWRAEEiMKH0tFUk5FTF9SRUZVU0FMX0NPREVfUkVGRVJFTlRJQUwQBRIvCitLRVJORUxfUkVGVVNBTF9DT0RFX1BPSU5UX1NUQVRFX1VOQVZBSUxBQkxFEAYSJAogS0VSTkVMX1JFRlVTQUxfQ09ERV9DQVBfRVhDRUVERUQQBxItCilLRVJORUxfUkVGVVNBTF9DT0RFX0NBUF9DT1VOVF9VTkFWQUlMQUJMRRAIEikKJUtFUk5FTF9SRUZVU0FMX0NPREVfRVZJREVOQ0VfVU5CQUNLRUQQCRImCiJLRVJORUxfUkVGVVNBTF9DT0RFX09SUEhBTl9SRUNFSVBUEAoSNgoyS0VSTkVMX1JFRlVTQUxfQ09ERV9SRUNFSVBUX09OX1RFUk1JTkFMX09CTElHQVRJT04QCxIiCh5LRVJORUxfUkVGVVNBTF9DT0RFX05PVF9NSU5URUQQDBIoCiRLRVJORUxfUkVGVVNBTF9DT0RFX0RPTUFJTl9MSUZFQ1lDTEUQDRIpCiVLRVJORUxfUkVGVVNBTF9DT0RFX1RZUEVfVEFHX01JU01BVENIEA4SLAooS0VSTkVMX1JFRlVTQUxfQ09ERV9SRVRJUkVEX1JFQURfU1VSRkFDRRAPEjAKLEtFUk5FTF9SRUZVU0FMX0NPREVfQ1JPU1NfV09SS1NQQUNFX0RFQ0xJTkVEEBASKwonS0VSTkVMX1JFRlVTQUxfQ09ERV9BR0dSRUdBVEVfSU5WQVJJQU5UEBESKwonS0VSTkVMX1JFRlVTQUxfQ09ERV9XT1JLU1BBQ0VfSU5WQVJJQU5UEBISLgoqS0VSTkVMX1JFRlVTQUxfQ09ERV9DQVBUVVJFRF9SRUFEX0NPTkZMSUNUEBMSMgouS0VSTkVMX1JFRlVTQUxfQ09ERV9DT05GTElDVF9TTkFQU0hPVF9SRVFVSVJFRBAUEjQKMEtFUk5FTF9SRUZVU0FMX0NPREVfQ09ORkxJQ1RfU05BUFNIT1RfVU5ERUNMQVJFRBAVEjEKLUtFUk5FTF9SRUZVU0FMX0NPREVfQ09ORkxJQ1RfU05BUFNIT1RfSU5WQUxJRBAWEi8KK0tFUk5FTF9SRUZVU0FMX0NPREVfQ09ORkxJQ1RfU05BUFNIT1RfU1RBTEUQFxIwCixLRVJORUxfUkVGVVNBTF9DT0RFX0NBUFRVUkVEX1JFQURfVU5ERUNMQVJFRBAYEi0KKUtFUk5FTF9SRUZVU0FMX0NPREVfQ0FQVFVSRURfUkVBRF9QUklWQVRFEBkSMAosS0VSTkVMX1JFRlVTQUxfQ09ERV9BVFRFU1RFRF9SRUFEX1VOREVDTEFSRUQQGhIzCi9LRVJORUxfUkVGVVNBTF9DT0RFX0FUVEVTVEVEX1JFQURfVU5UUlVTVEVEX0tFWRAbEjYKMktFUk5FTF9SRUZVU0FMX0NPREVfQVRURVNURURfUkVBRF9VTlRSVVNURURfU09VUkNFEBwSLAooS0VSTkVMX1JFRlVTQUxfQ09ERV9BVFRFU1RFRF9SRUFEX0ZPUkdFRBAdEisKJ0tFUk5FTF9SRUZVU0FMX0NPREVfQVRURVNURURfUkVBRF9TVEFMRRAeEi4KKktFUk5FTF9SRUZVU0FMX0NPREVfQVRURVNURURfUkVBRF9PVkVSU0laRRAfEjcKM0tFUk5FTF9SRUZVU0FMX0NPREVfQVRURVNURURfUkVBRF9ESVNIT05PUkVEX1NPVVJDRRAgEjUKMUtFUk5FTF9SRUZVU0FMX0NPREVfRVFVSVZPQ0FUSU9OX0VWSURFTkNFX0lOVkFMSUQQIRIzCi9LRVJORUxfUkVGVVNBTF9DT0RFX0FUVEVTVEFUSU9OX1JFQ0VJUFRfSU5WQUxJRBAiEisKJ0tFUk5FTF9SRUZVU0FMX0NPREVfS0VZX1JPU1RFUl9NSVNNQVRDSBAjEi8KK0tFUk5FTF9SRUZVU0FMX0NPREVfS0VZX0VQT0NIX05PVF9NT05PVE9OSUMQJBIpCiVLRVJORUxfUkVGVVNBTF9DT0RFX1dSSVRFX0VQT0NIX1NUQUxFECUSLQopS0VSTkVMX1JFRlVTQUxfQ09ERV9FTlZFTE9QRV9TSURfTUlTTUFUQ0gQJhIyCi5LRVJORUxfUkVGVVNBTF9DT0RFX1JFVk9LRURfTUVNQkVSX1JFU1VSUkVDVEVEECcSKAokS0VSTkVMX1JFRlVTQUxfQ09ERV9GT1JHRURfUFJJTkNJUEFMECgSKAokS0VSTkVMX1JFRlVTQUxfQ09ERV9PV05FRF9LRVlfQU5DSE9SECkSJgoiS0VSTkVMX1JFRlVTQUxfQ09ERV9PV05FRF9SRUNPVkVSWRAqEiwKKEtFUk5FTF9SRUZVU0FMX0NPREVfU1VSRkFDRURfQkFTSVNfQUhFQUQQKxIyCi5LRVJORUxfUkVGVVNBTF9DT0RFX1NJR05FUl9FUE9DSF9PVVRfT0ZfV0lORE9XECwSJgoiS0VSTkVMX1JFRlVTQUxfQ09ERV9FVk9MVkVfUkVGVVNFRBAtEisKJ0tFUk5FTF9SRUZVU0FMX0NPREVfQVRURVNUQVRJT05fSU5WQUxJRBAuEi0KKUtFUk5FTF9SRUZVU0FMX0NPREVfUEFSRU5UX0RJRF9OT1RfQVRURVNUEC8SKQolS0VSTkVMX1JFRlVTQUxfQ09ERV9DRVJUX0NIQUlOX0JST0tFThAwEioKJktFUk5FTF9SRUZVU0FMX0NPREVfTk9UX1JPT1RFRF9BVF9ST09UEDESKgomS0VSTkVMX1JFRlVTQUxfQ09ERV9ERUxFR0FUSU9OX0lOVkFMSUQQMhIlCiFLRVJORUxfUkVGVVNBTF9DT0RFX1BMQU5fUkVKRUNURUQQMyqKAQoPVmVyaWZ5Q2hhaW5XYWxrEiEKHVZFUklGWV9DSEFJTl9XQUxLX1VOU1BFQ0lGSUVEEAASGgoWVkVSSUZZX0NIQUlOX1dBTEtfRlVMTBABEhwKGFZFUklGWV9DSEFJTl9XQUxLX1NVRkZJWBACEhoKFlZFUklGWV9DSEFJTl9XQUxLX01FTU8QAyqIDAoOUXVlcnlPcGVyYXRpb24SHwobUVVFUllfT1BFUkFUSU9OX1VOU1BFQ0lGSUVEEAASHAoYUVVFUllfT1BFUkFUSU9OX0VYVFJFTVVNEAESJQohUVVFUllfT1BFUkFUSU9OX1BFTkRJTkdfQ09ORkxJQ1RTEAISLAooUVVFUllfT1BFUkFUSU9OX1BFTkRJTkdfQ09ORkxJQ1RfU1VNTUFSWRADEiAKHFFVRVJZX09QRVJBVElPTl9SRUFEX1BPU1RVUkUQBBIfChtRVUVSWV9PUEVSQVRJT05fQ1VSUkVOVF9MQVcQBRIjCh9RVUVSWV9PUEVSQVRJT05fSU5URVJGQUNFX09GRkVSEAYSJwojUVVFUllfT1BFUkFUSU9OX1JFTEFUSU9OX0dBVEVfT0ZGRVIQBxIdChlRVUVSWV9PUEVSQVRJT05fU0NFTkVfTEFXEAgSIQodUVVFUllfT1BFUkFUSU9OX0lOU1RBTExFRF9MQVcQCRIcChhRVUVSWV9PUEVSQVRJT05fREVTQ1JJQkUQChIjCh9RVUVSWV9PUEVSQVRJT05fS0VSTkVMX1JFU09VUkNFEAsSIwofUVVFUllfT1BFUkFUSU9OX0RFVkVMT1BFUl9TUEFOUxAMEikKJVFVRVJZX09QRVJBVElPTl9ERUNMQVJFRF9DQVBBQklMSVRJRVMQDRIdChlRVUVSWV9PUEVSQVRJT05fUkVBRElORVNTEA4SJAogUVVFUllfT1BFUkFUSU9OX1BST0pFQ1RJT05fU1RBVFMQDxIlCiFRVUVSWV9PUEVSQVRJT05fTUVNT1JZX0RST1BfUFJPQkUQEBIYChRRVUVSWV9PUEVSQVRJT05fV0FSTRAREhsKF1FVRVJZX09QRVJBVElPTl9SRUZSRVNIEBISIAocUVVFUllfT1BFUkFUSU9OX1ZFUklGWV9DSEFJThATEiUKIVFVRVJZX09QRVJBVElPTl9ISVNUT1JZX1BSRUZMSUdIVBAUEhkKFVFVRVJZX09QRVJBVElPTl9ST1VURRAVEhgKFFFVRVJZX09QRVJBVElPTl9NSU5UEBYSIQodUVVFUllfT1BFUkFUSU9OX0NSWVBUT19LRVlHRU4QFxIlCiFRVUVSWV9PUEVSQVRJT05fQ1JZUFRPX1NFQUxfRklFTEQQGBIsCihRVUVSWV9PUEVSQVRJT05fQ1JZUFRPX0JMSU5EX0lOREVYX1RPS0VOEBkSKgomUVVFUllfT1BFUkFUSU9OX0NSWVBUT19PV05FRF9TQ09QRV9LRVkQGhIvCitRVUVSWV9PUEVSQVRJT05fQ1JZUFRPX09XTkVEX0RFVklDRV9SRVFVRVNUEBsSMQotUVVFUllfT1BFUkFUSU9OX0NSWVBUT19PV05FRF9QUkVQQVJFX0FQUFJPVkFMEBwSMQotUVVFUllfT1BFUkFUSU9OX0NSWVBUT19PV05FRF9QUkVQQVJFX1JFQ09WRVJZEB0SIwofUVVFUllfT1BFUkFUSU9OX0NSWVBUT19XUkFQX0tFWRAeEiUKIVFVRVJZX09QRVJBVElPTl9DUllQVE9fVU5XUkFQX0tFWRAfEiEKHVFVRVJZX09QRVJBVElPTl9BVVRIT1JfS0VZR0VOECASJAogUVVFUllfT1BFUkFUSU9OX0FUVEVTVEFUSU9OX1NJR04QIRIgChxRVUVSWV9PUEVSQVRJT05fUkVDRUlQVF9QQVRIECISHQoZUVVFUllfT1BFUkFUSU9OX0NFUlRfU0lHThAjEiUKIVFVRVJZX09QRVJBVElPTl9CSVJUSF9UUlVTVF9TVEFURRAkEiEKHVFVRVJZX09QRVJBVElPTl9FUkFfQ0VSVF9TSUdOECUSKAokUVVFUllfT1BFUkFUSU9OX0RFTEVHQVRJT05fQ0VSVF9TSUdOECYSKQolUVVFUllfT1BFUkFUSU9OX0NBTk9OSUNBTElaRV9GUk9OVElFUhAnEisKJ1FVRVJZX09QRVJBVElPTl9DQU5PTklDQUxJWkVfUFJPSkVDVElPThAoKtICChVSZXNpZGVudENvbXBvbmVudEtpbmQSJwojUkVTSURFTlRfQ09NUE9ORU5UX0tJTkRfVU5TUEVDSUZJRUQQABImCiJSRVNJREVOVF9DT01QT05FTlRfS0lORF9GT0xEX1NUQVRFEAESLQopUkVTSURFTlRfQ09NUE9ORU5UX0tJTkRfUkVBRF9NT0RFTF9TUUxJVEUQAhIuCipSRVNJREVOVF9DT01QT05FTlRfS0lORF9SRUFEX01PREVMX0lOREVYRVMQAxItCilSRVNJREVOVF9DT01QT05FTlRfS0lORF9TSEFSRURfQVRUUklCVVRFRBAEEiwKKFJFU0lERU5UX0NPTVBPTkVOVF9LSU5EX1dPUktTUEFDRV9DQUNIRVMQBRIsCihSRVNJREVOVF9DT01QT05FTlRfS0lORF9HSVRfT0JKRUNUX0NBQ0hFEAYqbAoTS2VybmVsTGF3Q2FwYWJpbGl0eRIlCiFLRVJORUxfTEFXX0NBUEFCSUxJVFlfVU5TUEVDSUZJRUQQABIuCipLRVJORUxfTEFXX0NBUEFCSUxJVFlfU1RBR0VfWkVST19CT09UU1RSQVAQASqoAQoaSW50ZW50VHJhbnNwb3J0UmVxdWlyZW1lbnQSLAooSU5URU5UX1RSQU5TUE9SVF9SRVFVSVJFTUVOVF9VTlNQRUNJRklFRBAAEi4KKklOVEVOVF9UUkFOU1BPUlRfUkVRVUlSRU1FTlRfU0VBTEVEX0NIQU5HRRABEiwKKElOVEVOVF9UUkFOU1BPUlRfUkVRVUlSRU1FTlRfQ09NTUlUX1RSRUUQAiqJAQoVTGlmZWN5Y2xlSW5zdGFsbFBoYXNlEicKI0xJRkVDWUNMRV9JTlNUQUxMX1BIQVNFX1VOU1BFQ0lGSUVEEAASIgoeTElGRUNZQ0xFX0lOU1RBTExfUEhBU0VfQUNUSVZFEAESIwofTElGRUNZQ0xFX0lOU1RBTExfUEhBU0VfUEVORElORxACMlkKEk5vbW9zS2VybmVsU2VydmljZRJDCgRDYWxsEhwubm9tb3Mua2VybmVsLnYxLkNhbGxSZXF1ZXN0Gh0ubm9tb3Mua2VybmVsLnYxLkNhbGxSZXNwb25zZWIGcHJvdG8z");
|
|
5545
9752
|
var CallRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 0);
|
|
5546
9753
|
var CallResponseSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 1);
|
|
5547
|
-
var WorkspaceTargetSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5548
|
-
var DirectiveCallSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5549
|
-
var AuthoringOptionsSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5550
|
-
var CapturedClockSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5551
|
-
var BirthCertificateSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5552
|
-
var OfferRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5553
|
-
var QueryRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5554
|
-
var QueryAuthoritySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5555
|
-
var InjectedKeySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5556
|
-
var RowsQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5557
|
-
var PageQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5558
|
-
var ByIdQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5559
|
-
var TallyQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5560
|
-
var SpatialQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5561
|
-
var NamedQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5562
|
-
var AuthorizationObjectSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5563
|
-
var AuthorizationSubjectSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5564
|
-
var AuthorizationConsistencySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5565
|
-
var AuthorizationCheckRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5566
|
-
var AuthorizationExpandRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5567
|
-
var OutboxRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5568
|
-
var SyncRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5569
|
-
var TestRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5570
|
-
var SetTestRootRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5571
|
-
var CustodyRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5572
|
-
var ResidentFootprintRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5573
|
-
var PackDeltaRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5574
|
-
var ApplyPackRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5575
|
-
var RepoStatsRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5576
|
-
var IntentsAboveRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5577
|
-
var InspectChangeRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5578
|
-
var RefusalVerdictSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5579
|
-
var EncodeRefusalVerdictRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5580
|
-
var InspectRefusalVerdictRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5581
|
-
var ReadBlobRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5582
|
-
var ResolveRefRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5583
|
-
var ListRefsRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5584
|
-
var WriteRefRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5585
|
-
var DeleteRefRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5586
|
-
var WriteMetaCommitRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5587
|
-
var LawClosureInfoRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5588
|
-
var CheckpointExportRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5589
|
-
var CheckpointImportRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5590
|
-
var CapacityReserveRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5591
|
-
var RestoreMainRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5592
|
-
var ResolveStatePositionRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5593
|
-
var NomosValueSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
5594
|
-
var NomosStructSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel,
|
|
9754
|
+
var WorkspaceTargetSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 26);
|
|
9755
|
+
var DirectiveCallSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 28);
|
|
9756
|
+
var AuthoringOptionsSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 29);
|
|
9757
|
+
var CapturedClockSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 30);
|
|
9758
|
+
var BirthCertificateSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 31);
|
|
9759
|
+
var OfferRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 32);
|
|
9760
|
+
var QueryRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 35);
|
|
9761
|
+
var QueryAuthoritySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 36);
|
|
9762
|
+
var InjectedKeySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 37);
|
|
9763
|
+
var RowsQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 38);
|
|
9764
|
+
var PageQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 39);
|
|
9765
|
+
var ByIdQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 40);
|
|
9766
|
+
var TallyQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 45);
|
|
9767
|
+
var SpatialQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 46);
|
|
9768
|
+
var NamedQuerySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 47);
|
|
9769
|
+
var AuthorizationObjectSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 48);
|
|
9770
|
+
var AuthorizationSubjectSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 49);
|
|
9771
|
+
var AuthorizationConsistencySchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 51);
|
|
9772
|
+
var AuthorizationCheckRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 53);
|
|
9773
|
+
var AuthorizationExpandRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 54);
|
|
9774
|
+
var OutboxRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 60);
|
|
9775
|
+
var SyncRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 61);
|
|
9776
|
+
var TestRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 62);
|
|
9777
|
+
var SetTestRootRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 63);
|
|
9778
|
+
var CustodyRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 65);
|
|
9779
|
+
var ResidentFootprintRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 66);
|
|
9780
|
+
var PackDeltaRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 70);
|
|
9781
|
+
var ApplyPackRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 71);
|
|
9782
|
+
var RepoStatsRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 72);
|
|
9783
|
+
var IntentsAboveRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 73);
|
|
9784
|
+
var InspectChangeRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 74);
|
|
9785
|
+
var RefusalVerdictSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 75);
|
|
9786
|
+
var EncodeRefusalVerdictRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 76);
|
|
9787
|
+
var InspectRefusalVerdictRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 77);
|
|
9788
|
+
var ReadBlobRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 78);
|
|
9789
|
+
var ResolveRefRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 79);
|
|
9790
|
+
var ListRefsRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 80);
|
|
9791
|
+
var WriteRefRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 81);
|
|
9792
|
+
var DeleteRefRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 82);
|
|
9793
|
+
var WriteMetaCommitRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 84);
|
|
9794
|
+
var LawClosureInfoRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 85);
|
|
9795
|
+
var CheckpointExportRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 86);
|
|
9796
|
+
var CheckpointImportRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 87);
|
|
9797
|
+
var CapacityReserveRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 88);
|
|
9798
|
+
var RestoreMainRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 89);
|
|
9799
|
+
var ResolveStatePositionRequestSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 90);
|
|
9800
|
+
var NomosValueSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 116);
|
|
9801
|
+
var NomosStructSchema = /* @__PURE__ */ messageDesc(file_nomos_kernel_v1_kernel, 119);
|
|
5595
9802
|
var QueryOperationSchema = /* @__PURE__ */ enumDesc(file_nomos_kernel_v1_kernel, 2);
|
|
5596
9803
|
var QueryOperation = /* @__PURE__ */ tsEnum(QueryOperationSchema);
|
|
5597
9804
|
var KernelLawCapabilitySchema = /* @__PURE__ */ enumDesc(file_nomos_kernel_v1_kernel, 4);
|
|
@@ -7211,8 +11418,25 @@ function installedLaw(eng2, ws) {
|
|
|
7211
11418
|
function sceneLaw(eng2, ws) {
|
|
7212
11419
|
return namedQueryProto(eng2, ws, QueryOperation.SCENE_LAW);
|
|
7213
11420
|
}
|
|
7214
|
-
function
|
|
7215
|
-
|
|
11421
|
+
function kernelResource(eng2, ws) {
|
|
11422
|
+
const response = callProto(eng2.ex, {
|
|
11423
|
+
case: "query",
|
|
11424
|
+
value: create(QueryRequestSchema, {
|
|
11425
|
+
target: protoTarget(ws, BRANCH),
|
|
11426
|
+
query: {
|
|
11427
|
+
case: "named",
|
|
11428
|
+
value: create(NamedQuerySchema, {
|
|
11429
|
+
operation: QueryOperation.KERNEL_RESOURCE,
|
|
11430
|
+
arguments: protoStruct({})
|
|
11431
|
+
})
|
|
11432
|
+
}
|
|
11433
|
+
})
|
|
11434
|
+
}, eng2.STDERR);
|
|
11435
|
+
if (response.outcome.case !== "query" || response.outcome.value.result.case !== "osgiResource") {
|
|
11436
|
+
const actual = response.outcome.case === "query" ? response.outcome.value.result.case || "empty" : response.outcome.case || "empty";
|
|
11437
|
+
throw new Error(`kernel returned ${actual} for OSGi resource query`);
|
|
11438
|
+
}
|
|
11439
|
+
return response.outcome.value.result.value;
|
|
7216
11440
|
}
|
|
7217
11441
|
function declaredCapabilities(eng2, ws) {
|
|
7218
11442
|
const out = namedQueryProto(eng2, ws, QueryOperation.DECLARED_CAPABILITIES);
|
|
@@ -8105,10 +12329,10 @@ function packBornChildren(eng2, born) {
|
|
|
8105
12329
|
}
|
|
8106
12330
|
});
|
|
8107
12331
|
}
|
|
8108
|
-
function reconcileBornPacks(eng2,
|
|
12332
|
+
function reconcileBornPacks(eng2, children2) {
|
|
8109
12333
|
const born = [];
|
|
8110
12334
|
const missing = [];
|
|
8111
|
-
for (const child of Array.isArray(
|
|
12335
|
+
for (const child of Array.isArray(children2) ? children2 : []) {
|
|
8112
12336
|
if (typeof child !== "string" || !child) continue;
|
|
8113
12337
|
const head = kgit.resolveRef(eng2, gitdirOf(child), BRANCH);
|
|
8114
12338
|
if (!head || !/^[0-9a-f]{40}$/i.test(head)) {
|
|
@@ -9134,7 +13358,7 @@ function warmKernelCaches(eng2, opts = {}) {
|
|
|
9134
13358
|
|
|
9135
13359
|
// runner/offline-install.ts
|
|
9136
13360
|
var HERE = dirname(fileURLToPath(import.meta.url));
|
|
9137
|
-
var
|
|
13361
|
+
var KERNEL_REQUIREMENTS = typeof define_NOMOS_KERNEL_RELEASE_default === "undefined" ? [{ name: "nomos.kernel.v1", version: "1.0.0" }] : Object.entries(define_NOMOS_KERNEL_RELEASE_default.contracts).map(([name, version]) => ({ name, version }));
|
|
9138
13362
|
var engineModule = process.env["NOMOS_ADAPTER_ENGINE"] ? await import(process.env["NOMOS_ADAPTER_ENGINE"]) : engine_exports;
|
|
9139
13363
|
var treeModule = process.env["NOMOS_ADAPTER_TREE"] ? await import(process.env["NOMOS_ADAPTER_TREE"]) : { serializeTree };
|
|
9140
13364
|
var { createEngine: createEngine2, mountWorkspace: mountWorkspace2, author: author2, closureInstallPayload: closureInstallPayload2, authorKeygen: authorKeygen2, refreshProjection: refreshProjection2, currentLaw: currentLaw2, exportCheckpoint: exportCheckpoint2, stageLawClosure: stageLawClosure2 } = engineModule;
|
|
@@ -9159,15 +13383,13 @@ var STALE_RUNTIME_HINT = "your cached kernel runtime may be stale \u2014 rm -rf
|
|
|
9159
13383
|
var looksLikeStaleRuntime = (msg) => /\bbbox param\b|missing.*param|non-numeric|unknown (op|query op)|unsupported op|unexpected (field|key)|no such op/i.test(msg);
|
|
9160
13384
|
await refreshRuntimeDir(CLOUD, runtimeDir, {
|
|
9161
13385
|
log: (m) => process.stderr.write(m + "\n"),
|
|
9162
|
-
|
|
13386
|
+
requirements: KERNEL_REQUIREMENTS
|
|
9163
13387
|
});
|
|
9164
|
-
|
|
9165
|
-
|
|
9166
|
-
|
|
9167
|
-
|
|
9168
|
-
|
|
9169
|
-
);
|
|
9170
|
-
}
|
|
13388
|
+
var mismatch = runtimeCompatibilityMismatch(runtimeDir, KERNEL_REQUIREMENTS);
|
|
13389
|
+
if (mismatch !== void 0) {
|
|
13390
|
+
die(
|
|
13391
|
+
`runtime compatibility failed: ${mismatch}. The SDK will not run generated law without a provider-selected, digest-verified compatible kernel; reconnect once to ${CLOUD}, then retry.`
|
|
13392
|
+
);
|
|
9171
13393
|
}
|
|
9172
13394
|
var wasmFile = join2(runtimeDir, "holon-testmint.wasm");
|
|
9173
13395
|
var bootstrapFile = join2(runtimeDir, "bootstrap.law.usdz");
|