@lowlighter/xml 6.0.0 → 8.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +77 -22
- package/_parser.d.ts +45 -0
- package/_parser.js +266 -0
- package/_types.d.ts +29 -0
- package/_types.js +2 -0
- package/bench/assets/medium.xml +1 -1
- package/bench/assets/small.xml +1 -1
- package/bench/bench.ts +6 -2
- package/deno.lock +17 -97
- package/mod.d.ts +3 -0
- package/mod.js +3 -0
- package/package.json +27 -23
- package/parse.d.ts +81 -0
- package/parse.js +227 -0
- package/stringify.d.ts +79 -0
- package/stringify.js +263 -0
- package/wasm/parse.d.ts +77 -0
- package/wasm/parse.js +123 -0
- package/wasm/wasm_xml_parser.js +3 -0
- package/_types.ts +0 -49
- package/_types_test.ts +0 -1
- package/deno.jsonc +0 -98
- package/mod.mjs +0 -1
- package/mod.ts +0 -3
- package/mod_test.ts +0 -1
- package/parse.mjs +0 -1
- package/parse.ts +0 -442
- package/parse_test.ts +0 -1303
- package/stringify.mjs +0 -1
- package/stringify.ts +0 -287
- package/stringify_test.ts +0 -303
- package/wasm_xml_parser/Cargo.lock +0 -159
- package/wasm_xml_parser/Cargo.toml +0 -16
- package/wasm_xml_parser/src/lib.rs +0 -234
- package/wasm_xml_parser/wasm_xml_parser.js +0 -2
package/stringify.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stringify an XML document object into a XML string.
|
|
3
|
+
* @module
|
|
4
|
+
*/ // Imports
|
|
5
|
+
/** Internal symbol to store properties without erasing user-provided ones. */ const internal = Symbol("internal");
|
|
6
|
+
/**
|
|
7
|
+
* Stringify an {@link XmlDocument} object into a XML string.
|
|
8
|
+
*
|
|
9
|
+
* Output can be customized using the {@link options} parameter.
|
|
10
|
+
*
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { stringify } from "./stringify.ts"
|
|
13
|
+
*
|
|
14
|
+
* console.log(stringify({
|
|
15
|
+
* "@version": "1.0",
|
|
16
|
+
* "@standalone": "yes",
|
|
17
|
+
* root: {
|
|
18
|
+
* text: "hello",
|
|
19
|
+
* array: ["world", "monde", "世界", "🌏"],
|
|
20
|
+
* number: 42,
|
|
21
|
+
* boolean: true,
|
|
22
|
+
* complex: {
|
|
23
|
+
* "@attribute": "value",
|
|
24
|
+
* "#text": "content",
|
|
25
|
+
* },
|
|
26
|
+
* }
|
|
27
|
+
* }))
|
|
28
|
+
* ```
|
|
29
|
+
*/ export function stringify(document, options) {
|
|
30
|
+
options ??= {};
|
|
31
|
+
options.format ??= {};
|
|
32
|
+
options.format.indent ??= " ";
|
|
33
|
+
options.format.breakline ??= 128;
|
|
34
|
+
const _options = options;
|
|
35
|
+
let text = "";
|
|
36
|
+
document = clone(document);
|
|
37
|
+
// Add prolog
|
|
38
|
+
text += xml_prolog(document, _options);
|
|
39
|
+
// Add processing instructions
|
|
40
|
+
if (document["#instructions"]) {
|
|
41
|
+
for (const [name, nodes] of Object.entries(document["#instructions"])){
|
|
42
|
+
for (const node of [
|
|
43
|
+
nodes
|
|
44
|
+
].flat()){
|
|
45
|
+
if (!("~name" in node)) Object.defineProperties(node, {
|
|
46
|
+
["~name"]: {
|
|
47
|
+
enumerable: false,
|
|
48
|
+
writable: false,
|
|
49
|
+
value: name
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
text += xml_instruction(node, _options);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
// Add doctype
|
|
57
|
+
if (document["#doctype"]) text += xml_doctype(document["#doctype"], _options);
|
|
58
|
+
// Add root node
|
|
59
|
+
const [root, ...garbage] = xml_children(document, _options);
|
|
60
|
+
if (!root) throw new SyntaxError("No root node detected");
|
|
61
|
+
if (garbage.length) throw new SyntaxError("Multiple root node detected");
|
|
62
|
+
text += xml_node(root, {
|
|
63
|
+
..._options,
|
|
64
|
+
depth: 0
|
|
65
|
+
});
|
|
66
|
+
return text.trim();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Clone the provided user document so it {@linkcode stringify} can edit it in-place without affecting user.
|
|
70
|
+
*
|
|
71
|
+
* It copies all enumerable properties along non-enumerable one supported by `parse`
|
|
72
|
+
*/ function clone(document) {
|
|
73
|
+
const cloned = Array.isArray(document) ? [] : {};
|
|
74
|
+
for(const property in document)cloned[property] = document[property] !== null && [
|
|
75
|
+
"object",
|
|
76
|
+
"function"
|
|
77
|
+
].includes(typeof document[property]) ? clone(document[property]) : document[property];
|
|
78
|
+
[
|
|
79
|
+
"~name",
|
|
80
|
+
"~parent",
|
|
81
|
+
"#text",
|
|
82
|
+
"~children",
|
|
83
|
+
"#comments",
|
|
84
|
+
"#text",
|
|
85
|
+
"#doctype",
|
|
86
|
+
"#instructions",
|
|
87
|
+
internal
|
|
88
|
+
].forEach((property)=>{
|
|
89
|
+
if (property in document) Object.defineProperty(cloned, property, Object.getOwnPropertyDescriptor(document, property));
|
|
90
|
+
});
|
|
91
|
+
return cloned;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Helper to create a CDATA node.
|
|
95
|
+
*
|
|
96
|
+
* ```ts
|
|
97
|
+
* import { stringify, cdata } from "./stringify.ts"
|
|
98
|
+
* stringify({ string: cdata(`hello <world>`) })
|
|
99
|
+
* // <string><![CDATA[hello <world>]]></string>
|
|
100
|
+
* ```
|
|
101
|
+
*/ export function cdata(text) {
|
|
102
|
+
return {
|
|
103
|
+
"~name": "~cdata",
|
|
104
|
+
"#text": text
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Helper to create a comment node.
|
|
109
|
+
*
|
|
110
|
+
* ```ts
|
|
111
|
+
* import { stringify, comment } from "./stringify.ts"
|
|
112
|
+
* stringify({ string: comment(`hello world`) })
|
|
113
|
+
* // <string><!--hello world--></string>
|
|
114
|
+
* ```
|
|
115
|
+
*/ export function comment(text) {
|
|
116
|
+
return {
|
|
117
|
+
"~name": "~comment",
|
|
118
|
+
"#text": text
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
/** Create XML prolog. */ function xml_prolog(document, options) {
|
|
122
|
+
;
|
|
123
|
+
document["~name"] ??= "xml";
|
|
124
|
+
return xml_instruction(document, options);
|
|
125
|
+
}
|
|
126
|
+
/** Create XML instruction. */ function xml_instruction(node, { format: { indent } }) {
|
|
127
|
+
let text = "";
|
|
128
|
+
const attributes = xml_attributes(node, arguments[1]);
|
|
129
|
+
if (attributes.length) {
|
|
130
|
+
text += `<?${node["~name"].replace(/^~/, "")}`;
|
|
131
|
+
for (const [name, value] of attributes)text += ` ${name}="${value}"`;
|
|
132
|
+
text += `?>${indent ? "\n" : ""}`;
|
|
133
|
+
}
|
|
134
|
+
return text;
|
|
135
|
+
}
|
|
136
|
+
/** Create XML doctype. */ function xml_doctype(node, { format: { indent } }) {
|
|
137
|
+
let text = "";
|
|
138
|
+
const attributes = xml_attributes(node, arguments[1]);
|
|
139
|
+
const elements = xml_children(node, arguments[1]);
|
|
140
|
+
if (attributes.length + elements.length) {
|
|
141
|
+
text += `<!DOCTYPE`;
|
|
142
|
+
for (const [name] of attributes)text += ` ${!/^[A-Za-z0-9_]+$/.test(name) ? `"${name}"` : name}`;
|
|
143
|
+
if (elements.length) {
|
|
144
|
+
text += `${indent ? `\n${indent}` : " "}[${indent ? "\n" : ""}`;
|
|
145
|
+
for (const element of elements)text += `${indent}<!ELEMENT ${element["~name"]} (${element["#text"]})>${indent ? "\n" : ""}`;
|
|
146
|
+
text += `${indent ? indent : ""}]${indent ? "\n" : ""}`;
|
|
147
|
+
}
|
|
148
|
+
text += `>${indent ? "\n" : ""}`;
|
|
149
|
+
}
|
|
150
|
+
return text;
|
|
151
|
+
}
|
|
152
|
+
/** Create XML node. */ function xml_node(node, { format: { breakline = 0, indent = "" }, replace, depth = 0 }) {
|
|
153
|
+
if (replace?.custom) {
|
|
154
|
+
if (replace.custom({
|
|
155
|
+
name: node["~name"],
|
|
156
|
+
key: null,
|
|
157
|
+
value: null,
|
|
158
|
+
node
|
|
159
|
+
}) === undefined) return "";
|
|
160
|
+
}
|
|
161
|
+
let text = `${indent.repeat(depth)}<${node["~name"]}`;
|
|
162
|
+
const attributes = xml_attributes(node, arguments[1]);
|
|
163
|
+
const children = xml_children(node, arguments[1]);
|
|
164
|
+
const preserve = node["@xml:space"] === "preserve";
|
|
165
|
+
for (const [name, value] of attributes)text += ` ${name}="${value}"`;
|
|
166
|
+
if (children.length || "#text" in node && node["#text"].length) {
|
|
167
|
+
const inline = indent && !preserve && (children.length || node["#text"].length > breakline - indent.length * depth);
|
|
168
|
+
text += `>${indent && !preserve && children.length ? "\n" : ""}`;
|
|
169
|
+
if ("#text" in node) {
|
|
170
|
+
if (inline) text += `\n${indent.repeat(depth + 1)}`;
|
|
171
|
+
text += node["#text"];
|
|
172
|
+
if (inline) text += "\n";
|
|
173
|
+
}
|
|
174
|
+
for (const child of children)text += xml_node(child, {
|
|
175
|
+
...arguments[1],
|
|
176
|
+
depth: depth + 1
|
|
177
|
+
});
|
|
178
|
+
if (inline) text += indent.repeat(depth);
|
|
179
|
+
text += `</${node["~name"]}>${indent ? "\n" : ""}`;
|
|
180
|
+
} else {
|
|
181
|
+
text += `/>${indent ? "\n" : ""}`;
|
|
182
|
+
}
|
|
183
|
+
return text;
|
|
184
|
+
}
|
|
185
|
+
/** Extract children from node. */ function xml_children(node, options) {
|
|
186
|
+
const children = Object.keys(node).filter((key)=>/^[A-Za-z_]/.test(key)).flatMap((key)=>[
|
|
187
|
+
node[key]
|
|
188
|
+
].flat().map((value)=>{
|
|
189
|
+
switch(true){
|
|
190
|
+
case value === null:
|
|
191
|
+
return {
|
|
192
|
+
["~name"]: key,
|
|
193
|
+
["#text"]: ""
|
|
194
|
+
};
|
|
195
|
+
case typeof value === "object":
|
|
196
|
+
{
|
|
197
|
+
const child = {
|
|
198
|
+
...value,
|
|
199
|
+
["~name"]: key
|
|
200
|
+
};
|
|
201
|
+
if (value["~name"]?.startsWith("~")) child[internal] = value["~name"];
|
|
202
|
+
return child;
|
|
203
|
+
}
|
|
204
|
+
default:
|
|
205
|
+
return {
|
|
206
|
+
["~name"]: key,
|
|
207
|
+
["#text"]: `${value}`
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
})).map((node)=>{
|
|
211
|
+
if ("#text" in node) {
|
|
212
|
+
const cdata = node[internal] === "~cdata";
|
|
213
|
+
const comment = node[internal] === "~comment";
|
|
214
|
+
node["#text"] = replace(node, "#text", {
|
|
215
|
+
...options,
|
|
216
|
+
escape: cdata ? [] : [
|
|
217
|
+
"&",
|
|
218
|
+
"<",
|
|
219
|
+
">"
|
|
220
|
+
]
|
|
221
|
+
});
|
|
222
|
+
if (node["#text"] === undefined) delete node["#text"];
|
|
223
|
+
else node["#text"] = cdata ? `<![CDATA[${node["#text"]}]]>` : comment ? `<!--${node["#text"]}-->` : `${node["#text"]}`;
|
|
224
|
+
}
|
|
225
|
+
return node;
|
|
226
|
+
});
|
|
227
|
+
return children;
|
|
228
|
+
}
|
|
229
|
+
/** Extract attributes from node. */ function xml_attributes(node, options) {
|
|
230
|
+
return Object.entries(node).filter(([key])=>key.startsWith("@")).map(([key])=>[
|
|
231
|
+
key.slice(1),
|
|
232
|
+
replace(node, key, {
|
|
233
|
+
...options,
|
|
234
|
+
escape: [
|
|
235
|
+
"&",
|
|
236
|
+
'"',
|
|
237
|
+
"'"
|
|
238
|
+
]
|
|
239
|
+
})
|
|
240
|
+
]).filter(([_, value])=>value !== undefined);
|
|
241
|
+
}
|
|
242
|
+
/** Entities */ const entities = {
|
|
243
|
+
"&": "&",
|
|
244
|
+
'"': """,
|
|
245
|
+
"<": "<",
|
|
246
|
+
">": ">",
|
|
247
|
+
"'": "'"
|
|
248
|
+
};
|
|
249
|
+
/** Replace value. */ function replace(node, key, options) {
|
|
250
|
+
let value = `${node[key]}`;
|
|
251
|
+
if (options?.escape) {
|
|
252
|
+
if (options?.replace?.entities) options.escape = Object.keys(entities);
|
|
253
|
+
for (const char of options?.escape)value = `${value}`.replaceAll(char, entities[char]);
|
|
254
|
+
}
|
|
255
|
+
if (options?.replace?.custom) return options.replace.custom({
|
|
256
|
+
name: node["~name"],
|
|
257
|
+
key,
|
|
258
|
+
value,
|
|
259
|
+
node: node
|
|
260
|
+
});
|
|
261
|
+
return value;
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMveG1sL3N0cmluZ2lmeS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFN0cmluZ2lmeSBhbiBYTUwgZG9jdW1lbnQgb2JqZWN0IGludG8gYSBYTUwgc3RyaW5nLlxuICogQG1vZHVsZVxuICovXG5cbi8vIEltcG9ydHNcbmltcG9ydCB0eXBlIHsgTnVsbGFibGUsIFN0cmluZ2lmeWFibGUsIFhtbERvY3VtZW50LCBYbWxOb2RlLCBYbWxUZXh0IH0gZnJvbSBcIi4vX3R5cGVzLmpzXCJcbmV4cG9ydCB0eXBlICogZnJvbSBcIi4vX3R5cGVzLmpzXCJcblxuLyoqIFhNTCBzdHJpbmdpZmllciBvcHRpb25zLiAqL1xuZXhwb3J0IHR5cGUgU3RyaW5naWZ5T3B0aW9ucyA9IHtcbiAgLyoqIEZvcm1hdCBvcHRpb25zLiAqL1xuICBmb3JtYXQ/OiBGb3JtYXRPcHRpb25zXG4gIC8qKiBSZXBsYWNlIG9wdGlvbnMuICovXG4gIHJlcGxhY2U/OiBSZXBsYWNlT3B0aW9uc1xufVxuXG4vKiogWE1MIHN0cmluZ2lmaWVyIHtAbGlua2NvZGUgU3RyaW5naWZ5T3B0aW9uc31gLmZvcm1hdGAgKi9cbmV4cG9ydCB0eXBlIEZvcm1hdE9wdGlvbnMgPSB7XG4gIC8qKlxuICAgKiBJbmRlbnQgc3RyaW5nIChkZWZhdWx0cyB0byBgXCIgIFwiYCkuXG4gICAqIFNldCB0byBlbXB0eSBzdHJpbmcgdG8gZGlzYWJsZSBpbmRlbnRhdGlvbiBhbmQgZW5hYmxlIG1pbmlmaWNhdGlvbi5cbiAgICovXG4gIGluZGVudD86IHN0cmluZ1xuICAvKiogQnJlYWsgdGV4dCBub2RlIGlmIGl0cyBsZW5ndGggaXMgZ3JlYXRlciB0aGFuIHRoaXMgdmFsdWUgKGRlZmF1bHRzIHRvIGAxMjhgKS4gKi9cbiAgYnJlYWtsaW5lPzogbnVtYmVyXG59XG5cbi8qKiBYTUwgc3RyaW5naWZpZXIge0BsaW5rY29kZSBTdHJpbmdpZnlPcHRpb25zfWAucmVwbGFjZWAgKi9cbmV4cG9ydCB0eXBlIFJlcGxhY2VPcHRpb25zID0ge1xuICAvKipcbiAgICogRm9yY2UgZXNjYXBlIGFsbCBYTUwgZW50aXRpZXMuXG4gICAqIEJ5IGRlZmF1bHQsIG9ubHkgdGhlIG9uZXMgdGhhdCB3b3VsZCBicmVhayB0aGUgWE1MIHN0cnVjdHVyZSBhcmUgZXNjYXBlZC5cbiAgICovXG4gIGVudGl0aWVzPzogYm9vbGVhblxuICAvKipcbiAgICogQ3VzdG9tIHJlcGxhY2VyICh0aGlzIGlzIGFwcGxpZWQgYWZ0ZXIgb3RoZXIgcmV2aXZhbHMpLlxuICAgKiBXaGVuIGl0IGlzIGFwcGxpZWQgb24gYW4gYXR0cmlidXRlLCBga2V5YCBhbmQgYHZhbHVlYCB3aWxsIGJlIGdpdmVuLlxuICAgKiBXaGVuIGl0IGlzIGFwcGxpZWQgb24gYSBub2RlLCBib3RoIGBrZXlgIGFuZCBgdmFsdWVgIHdpbGwgYmUgYG51bGxgLlxuICAgKiBSZXR1cm4gYHVuZGVmaW5lZGAgdG8gZGVsZXRlIGVpdGhlciB0aGUgYXR0cmlidXRlIG9yIHRoZSB0YWcuXG4gICAqL1xuICBjdXN0b20/OiBSZXBsYWNlclxufVxuXG4vKipcbiAqIEN1c3RvbSBYTUwgc3RyaW5naWZpZXIgcmVwbGFjZXIuXG4gKiBJdCBjYW4gYmUgdXNlZCB0byBjaGFuZ2UgdGhlIHdheSBzb21lIG5vZGVzIGFyZSBzdHJpbmdpZmllZC5cbiAqL1xuZXhwb3J0IHR5cGUgUmVwbGFjZXIgPSAoYXJnczogeyBuYW1lOiBzdHJpbmc7IGtleTogTnVsbGFibGU8c3RyaW5nPjsgdmFsdWU6IE51bGxhYmxlPHN0cmluZz47IG5vZGU6IFJlYWRvbmx5PFhtbE5vZGU+IH0pID0+IHVua25vd25cblxuLyoqIFhNTCBzdHJpbmdpZmllciBvcHRpb25zICh3aXRoIG5vbi1udWxsYWJsZSBmb3JtYXQgb3B0aW9ucykuICovXG50eXBlIF9PcHRpb25zID0gU3RyaW5naWZ5T3B0aW9ucyAmIHsgZm9ybWF0OiBOb25OdWxsYWJsZTxTdHJpbmdpZnlPcHRpb25zW1wiZm9ybWF0XCJdPiB9XG5cbi8qKiBJbnRlcm5hbCBzeW1ib2wgdG8gc3RvcmUgcHJvcGVydGllcyB3aXRob3V0IGVyYXNpbmcgdXNlci1wcm92aWRlZCBvbmVzLiAqL1xuY29uc3QgaW50ZXJuYWwgPSBTeW1ib2woXCJpbnRlcm5hbFwiKVxuXG4vKipcbiAqIFN0cmluZ2lmeSBhbiB7QGxpbmsgWG1sRG9jdW1lbnR9IG9iamVjdCBpbnRvIGEgWE1MIHN0cmluZy5cbiAqXG4gKiBPdXRwdXQgY2FuIGJlIGN1c3RvbWl6ZWQgdXNpbmcgdGhlIHtAbGluayBvcHRpb25zfSBwYXJhbWV0ZXIuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IHN0cmluZ2lmeSB9IGZyb20gXCIuL3N0cmluZ2lmeS50c1wiXG4gKlxuICogY29uc29sZS5sb2coc3RyaW5naWZ5KHtcbiAqICAgXCJAdmVyc2lvblwiOiBcIjEuMFwiLFxuICogICBcIkBzdGFuZGFsb25lXCI6IFwieWVzXCIsXG4gKiAgIHJvb3Q6IHtcbiAqICAgICB0ZXh0OiBcImhlbGxvXCIsXG4gKiAgICAgYXJyYXk6IFtcIndvcmxkXCIsIFwibW9uZGVcIiwgXCLkuJbnlYxcIiwgXCLwn4yPXCJdLFxuICogICAgIG51bWJlcjogNDIsXG4gKiAgICAgYm9vbGVhbjogdHJ1ZSxcbiAqICAgICBjb21wbGV4OiB7XG4gKiAgICAgICBcIkBhdHRyaWJ1dGVcIjogXCJ2YWx1ZVwiLFxuICogICAgICAgXCIjdGV4dFwiOiBcImNvbnRlbnRcIixcbiAqICAgICB9LFxuICogICB9XG4gKiB9KSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RyaW5naWZ5KGRvY3VtZW50OiBTdHJpbmdpZnlhYmxlLCBvcHRpb25zPzogU3RyaW5naWZ5T3B0aW9ucyk6IHN0cmluZyB7XG4gIG9wdGlvbnMgPz89IHt9XG4gIG9wdGlvbnMuZm9ybWF0ID8/PSB7fVxuICBvcHRpb25zLmZvcm1hdC5pbmRlbnQgPz89IFwiICBcIlxuICBvcHRpb25zLmZvcm1hdC5icmVha2xpbmUgPz89IDEyOFxuICBjb25zdCBfb3B0aW9ucyA9IG9wdGlvbnMgYXMgX09wdGlvbnNcbiAgbGV0IHRleHQgPSBcIlwiXG4gIGRvY3VtZW50ID0gY2xvbmUoZG9jdW1lbnQpXG4gIC8vIEFkZCBwcm9sb2dcbiAgdGV4dCArPSB4bWxfcHJvbG9nKGRvY3VtZW50IGFzIFhtbERvY3VtZW50LCBfb3B0aW9ucylcbiAgLy8gQWRkIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zXG4gIGlmIChkb2N1bWVudFtcIiNpbnN0cnVjdGlvbnNcIl0pIHtcbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBub2Rlc10gb2YgT2JqZWN0LmVudHJpZXMoZG9jdW1lbnRbXCIjaW5zdHJ1Y3Rpb25zXCJdKSkge1xuICAgICAgZm9yIChjb25zdCBub2RlIG9mIFtub2Rlc10uZmxhdCgpKSB7XG4gICAgICAgIGlmICghKFwifm5hbWVcIiBpbiBub2RlKSlcbiAgICAgICAgICBPYmplY3QuZGVmaW5lUHJvcGVydGllcyhub2RlLCB7IFtcIn5uYW1lXCJdOiB7IGVudW1lcmFibGU6IGZhbHNlLCB3cml0YWJsZTogZmFsc2UsIHZhbHVlOiBuYW1lIH0gfSlcbiAgICAgICAgdGV4dCArPSB4bWxfaW5zdHJ1Y3Rpb24obm9kZSwgX29wdGlvbnMpXG4gICAgICB9XG4gICAgfVxuICB9XG4gIC8vIEFkZCBkb2N0eXBlXG4gIGlmIChkb2N1bWVudFtcIiNkb2N0eXBlXCJdKVxuICAgIHRleHQgKz0geG1sX2RvY3R5cGUoZG9jdW1lbnRbXCIjZG9jdHlwZVwiXSBhcyBYbWxOb2RlLCBfb3B0aW9ucylcblxuICAvLyBBZGQgcm9vdCBub2RlXG4gIGNvbnN0IFtyb290LCAuLi5nYXJiYWdlXSA9IHhtbF9jaGlsZHJlbihkb2N1bWVudCBhcyBYbWxEb2N1bWVudCwgX29wdGlvbnMpXG4gIGlmICghcm9vdClcbiAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJObyByb290IG5vZGUgZGV0ZWN0ZWRcIilcbiAgaWYgKGdhcmJhZ2UubGVuZ3RoKVxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihcIk11bHRpcGxlIHJvb3Qgbm9kZSBkZXRlY3RlZFwiKVxuICB0ZXh0ICs9IHhtbF9ub2RlKHJvb3QsIHsgLi4uX29wdGlvbnMsIGRlcHRoOiAwIH0pXG5cbiAgcmV0dXJuIHRleHQudHJpbSgpXG59XG5cbi8qKlxuICogQ2xvbmUgdGhlIHByb3ZpZGVkIHVzZXIgZG9jdW1lbnQgc28gaXQge0BsaW5rY29kZSBzdHJpbmdpZnl9IGNhbiBlZGl0IGl0IGluLXBsYWNlIHdpdGhvdXQgYWZmZWN0aW5nIHVzZXIuXG4gKlxuICogSXQgY29waWVzIGFsbCBlbnVtZXJhYmxlIHByb3BlcnRpZXMgYWxvbmcgbm9uLWVudW1lcmFibGUgb25lIHN1cHBvcnRlZCBieSBgcGFyc2VgXG4gKi9cbmZ1bmN0aW9uIGNsb25lKGRvY3VtZW50OiBSZWNvcmQ8UHJvcGVydHlLZXksIHVua25vd24+KSB7XG4gIGNvbnN0IGNsb25lZCA9IChBcnJheS5pc0FycmF5KGRvY3VtZW50KSA/IFtdIDoge30pIGFzIHR5cGVvZiBkb2N1bWVudFxuICBmb3IgKGNvbnN0IHByb3BlcnR5IGluIGRvY3VtZW50KVxuICAgIGNsb25lZFtwcm9wZXJ0eV0gPSAoKGRvY3VtZW50W3Byb3BlcnR5XSAhPT0gbnVsbCkgJiYgKFtcIm9iamVjdFwiLCBcImZ1bmN0aW9uXCJdLmluY2x1ZGVzKHR5cGVvZiBkb2N1bWVudFtwcm9wZXJ0eV0pKSkgPyBjbG9uZShkb2N1bWVudFtwcm9wZXJ0eV0gYXMgUmVjb3JkPFByb3BlcnR5S2V5LCB1bmtub3duPikgOiBkb2N1bWVudFtwcm9wZXJ0eV1cbiAgO1tcIn5uYW1lXCIsIFwifnBhcmVudFwiLCBcIiN0ZXh0XCIsIFwifmNoaWxkcmVuXCIsIFwiI2NvbW1lbnRzXCIsIFwiI3RleHRcIiwgXCIjZG9jdHlwZVwiLCBcIiNpbnN0cnVjdGlvbnNcIiwgaW50ZXJuYWxdLmZvckVhY2goKHByb3BlcnR5KSA9PiB7XG4gICAgaWYgKHByb3BlcnR5IGluIGRvY3VtZW50KVxuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KGNsb25lZCwgcHJvcGVydHksIE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IoZG9jdW1lbnQsIHByb3BlcnR5KSEpXG4gIH0pXG4gIHJldHVybiBjbG9uZWRcbn1cblxuLyoqXG4gKiBIZWxwZXIgdG8gY3JlYXRlIGEgQ0RBVEEgbm9kZS5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgc3RyaW5naWZ5LCBjZGF0YSB9IGZyb20gXCIuL3N0cmluZ2lmeS50c1wiXG4gKiBzdHJpbmdpZnkoeyBzdHJpbmc6IGNkYXRhKGBoZWxsbyA8d29ybGQ+YCkgfSlcbiAqIC8vIDxzdHJpbmc+PCFbQ0RBVEFbaGVsbG8gPHdvcmxkPl1dPjwvc3RyaW5nPlxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjZGF0YSh0ZXh0OiBzdHJpbmcpOiBPbWl0PFhtbFRleHQsIFwifnBhcmVudFwiPiB7XG4gIHJldHVybiB7XG4gICAgXCJ+bmFtZVwiOiBcIn5jZGF0YVwiLFxuICAgIFwiI3RleHRcIjogdGV4dCxcbiAgfVxufVxuXG4vKipcbiAqIEhlbHBlciB0byBjcmVhdGUgYSBjb21tZW50IG5vZGUuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IHN0cmluZ2lmeSwgY29tbWVudCB9IGZyb20gXCIuL3N0cmluZ2lmeS50c1wiXG4gKiBzdHJpbmdpZnkoeyBzdHJpbmc6IGNvbW1lbnQoYGhlbGxvIHdvcmxkYCkgfSlcbiAqIC8vIDxzdHJpbmc+PCEtLWhlbGxvIHdvcmxkLS0+PC9zdHJpbmc+XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbW1lbnQodGV4dDogc3RyaW5nKTogT21pdDxYbWxUZXh0LCBcIn5wYXJlbnRcIj4ge1xuICByZXR1cm4ge1xuICAgIFwifm5hbWVcIjogXCJ+Y29tbWVudFwiLFxuICAgIFwiI3RleHRcIjogdGV4dCxcbiAgfVxufVxuXG4vKiogQ3JlYXRlIFhNTCBwcm9sb2cuICovXG5mdW5jdGlvbiB4bWxfcHJvbG9nKGRvY3VtZW50OiBYbWxEb2N1bWVudCwgb3B0aW9uczogX09wdGlvbnMpOiBzdHJpbmcge1xuICA7KGRvY3VtZW50IGFzIFJlY29yZDxQcm9wZXJ0eUtleSwgdW5rbm93bj4pW1wifm5hbWVcIl0gPz89IFwieG1sXCJcbiAgcmV0dXJuIHhtbF9pbnN0cnVjdGlvbihkb2N1bWVudCwgb3B0aW9ucylcbn1cblxuLyoqIENyZWF0ZSBYTUwgaW5zdHJ1Y3Rpb24uICovXG5mdW5jdGlvbiB4bWxfaW5zdHJ1Y3Rpb24obm9kZTogWG1sTm9kZSwgeyBmb3JtYXQ6IHsgaW5kZW50IH0gfTogX09wdGlvbnMpOiBzdHJpbmcge1xuICBsZXQgdGV4dCA9IFwiXCJcbiAgY29uc3QgYXR0cmlidXRlcyA9IHhtbF9hdHRyaWJ1dGVzKG5vZGUgYXMgWG1sTm9kZSwgYXJndW1lbnRzWzFdKVxuICBpZiAoYXR0cmlidXRlcy5sZW5ndGgpIHtcbiAgICB0ZXh0ICs9IGA8PyR7bm9kZVtcIn5uYW1lXCJdLnJlcGxhY2UoL15+LywgXCJcIil9YFxuICAgIGZvciAoY29uc3QgW25hbWUsIHZhbHVlXSBvZiBhdHRyaWJ1dGVzKVxuICAgICAgdGV4dCArPSBgICR7bmFtZX09XCIke3ZhbHVlfVwiYFxuICAgIHRleHQgKz0gYD8+JHtpbmRlbnQgPyBcIlxcblwiIDogXCJcIn1gXG4gIH1cbiAgcmV0dXJuIHRleHRcbn1cblxuLyoqIENyZWF0ZSBYTUwgZG9jdHlwZS4gKi9cbmZ1bmN0aW9uIHhtbF9kb2N0eXBlKG5vZGU6IFhtbE5vZGUsIHsgZm9ybWF0OiB7IGluZGVudCB9IH06IF9PcHRpb25zKTogc3RyaW5nIHtcbiAgbGV0IHRleHQgPSBcIlwiXG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSB4bWxfYXR0cmlidXRlcyhub2RlLCBhcmd1bWVudHNbMV0pXG4gIGNvbnN0IGVsZW1lbnRzID0geG1sX2NoaWxkcmVuKG5vZGUsIGFyZ3VtZW50c1sxXSlcbiAgaWYgKGF0dHJpYnV0ZXMubGVuZ3RoICsgZWxlbWVudHMubGVuZ3RoKSB7XG4gICAgdGV4dCArPSBgPCFET0NUWVBFYFxuICAgIGZvciAoY29uc3QgW25hbWVdIG9mIGF0dHJpYnV0ZXMpXG4gICAgICB0ZXh0ICs9IGAgJHshL15bQS1aYS16MC05X10rJC8udGVzdChuYW1lKSA/IGBcIiR7bmFtZX1cImAgOiBuYW1lfWBcbiAgICBpZiAoZWxlbWVudHMubGVuZ3RoKSB7XG4gICAgICB0ZXh0ICs9IGAke2luZGVudCA/IGBcXG4ke2luZGVudH1gIDogXCIgXCJ9WyR7aW5kZW50ID8gXCJcXG5cIiA6IFwiXCJ9YFxuICAgICAgZm9yIChjb25zdCBlbGVtZW50IG9mIGVsZW1lbnRzKVxuICAgICAgICB0ZXh0ICs9IGAke2luZGVudH08IUVMRU1FTlQgJHtlbGVtZW50W1wifm5hbWVcIl19ICgke2VsZW1lbnRbXCIjdGV4dFwiXX0pPiR7aW5kZW50ID8gXCJcXG5cIiA6IFwiXCJ9YFxuICAgICAgdGV4dCArPSBgJHtpbmRlbnQgPyBpbmRlbnQgOiBcIlwifV0ke2luZGVudCA/IFwiXFxuXCIgOiBcIlwifWBcbiAgICB9XG4gICAgdGV4dCArPSBgPiR7aW5kZW50ID8gXCJcXG5cIiA6IFwiXCJ9YFxuICB9XG4gIHJldHVybiB0ZXh0XG59XG5cbi8qKiBDcmVhdGUgWE1MIG5vZGUuICovXG5mdW5jdGlvbiB4bWxfbm9kZShub2RlOiBYbWxOb2RlLCB7IGZvcm1hdDogeyBicmVha2xpbmUgPSAwLCBpbmRlbnQgPSBcIlwiIH0sIHJlcGxhY2UsIGRlcHRoID0gMCB9OiBfT3B0aW9ucyAmIHsgZGVwdGg/OiBudW1iZXIgfSk6IHN0cmluZyB7XG4gIGlmIChyZXBsYWNlPy5jdXN0b20pIHtcbiAgICBpZiAocmVwbGFjZS5jdXN0b20oeyBuYW1lOiBub2RlW1wifm5hbWVcIl0sIGtleTogbnVsbCwgdmFsdWU6IG51bGwsIG5vZGUgfSkgPT09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiBcIlwiXG4gIH1cbiAgbGV0IHRleHQgPSBgJHtpbmRlbnQucmVwZWF0KGRlcHRoKX08JHtub2RlW1wifm5hbWVcIl19YFxuICBjb25zdCBhdHRyaWJ1dGVzID0geG1sX2F0dHJpYnV0ZXMobm9kZSwgYXJndW1lbnRzWzFdKVxuICBjb25zdCBjaGlsZHJlbiA9IHhtbF9jaGlsZHJlbihub2RlLCBhcmd1bWVudHNbMV0pXG4gIGNvbnN0IHByZXNlcnZlID0gbm9kZVtcIkB4bWw6c3BhY2VcIl0gPT09IFwicHJlc2VydmVcIlxuICBmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZV0gb2YgYXR0cmlidXRlcylcbiAgICB0ZXh0ICs9IGAgJHtuYW1lfT1cIiR7dmFsdWV9XCJgXG4gIGlmICgoY2hpbGRyZW4ubGVuZ3RoKSB8fCAoKFwiI3RleHRcIiBpbiBub2RlKSAmJiAobm9kZVtcIiN0ZXh0XCJdLmxlbmd0aCkpKSB7XG4gICAgY29uc3QgaW5saW5lID0gaW5kZW50ICYmICghcHJlc2VydmUpICYmICgoY2hpbGRyZW4ubGVuZ3RoKSB8fCAobm9kZVtcIiN0ZXh0XCJdLmxlbmd0aCA+IGJyZWFrbGluZSAtIGluZGVudC5sZW5ndGggKiBkZXB0aCkpXG4gICAgdGV4dCArPSBgPiR7aW5kZW50ICYmICghcHJlc2VydmUpICYmIChjaGlsZHJlbi5sZW5ndGgpID8gXCJcXG5cIiA6IFwiXCJ9YFxuICAgIGlmIChcIiN0ZXh0XCIgaW4gbm9kZSkge1xuICAgICAgaWYgKGlubGluZSlcbiAgICAgICAgdGV4dCArPSBgXFxuJHtpbmRlbnQucmVwZWF0KGRlcHRoICsgMSl9YFxuICAgICAgdGV4dCArPSBub2RlW1wiI3RleHRcIl1cbiAgICAgIGlmIChpbmxpbmUpXG4gICAgICAgIHRleHQgKz0gXCJcXG5cIlxuICAgIH1cbiAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIGNoaWxkcmVuKVxuICAgICAgdGV4dCArPSB4bWxfbm9kZShjaGlsZCwgeyAuLi5hcmd1bWVudHNbMV0sIGRlcHRoOiBkZXB0aCArIDEgfSlcbiAgICBpZiAoaW5saW5lKVxuICAgICAgdGV4dCArPSBpbmRlbnQucmVwZWF0KGRlcHRoKVxuICAgIHRleHQgKz0gYDwvJHtub2RlW1wifm5hbWVcIl19PiR7aW5kZW50ID8gXCJcXG5cIiA6IFwiXCJ9YFxuICB9IGVsc2Uge1xuICAgIHRleHQgKz0gYC8+JHtpbmRlbnQgPyBcIlxcblwiIDogXCJcIn1gXG4gIH1cbiAgcmV0dXJuIHRleHRcbn1cblxuLyoqIEV4dHJhY3QgY2hpbGRyZW4gZnJvbSBub2RlLiAqL1xuZnVuY3Rpb24geG1sX2NoaWxkcmVuKG5vZGU6IFhtbE5vZGUsIG9wdGlvbnM6IFN0cmluZ2lmeU9wdGlvbnMpOiBBcnJheTxYbWxOb2RlPiB7XG4gIGNvbnN0IGNoaWxkcmVuID0gT2JqZWN0LmtleXMobm9kZSlcbiAgICAuZmlsdGVyKChrZXkpID0+IC9eW0EtWmEtel9dLy50ZXN0KGtleSkpXG4gICAgLmZsYXRNYXAoKGtleSkgPT5cbiAgICAgIFtub2RlIVtrZXldXS5mbGF0KCkubWFwKCh2YWx1ZSkgPT4ge1xuICAgICAgICBzd2l0Y2ggKHRydWUpIHtcbiAgICAgICAgICBjYXNlIHZhbHVlID09PSBudWxsOlxuICAgICAgICAgICAgcmV0dXJuICh7IFtcIn5uYW1lXCJdOiBrZXksIFtcIiN0ZXh0XCJdOiBcIlwiIH0pXG4gICAgICAgICAgY2FzZSB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCI6IHtcbiAgICAgICAgICAgIGNvbnN0IGNoaWxkID0geyAuLi52YWx1ZSBhcyBSZWNvcmQ8UHJvcGVydHlLZXksIHVua25vd24+LCBbXCJ+bmFtZVwiXToga2V5IH0gYXMgUmVjb3JkPFByb3BlcnR5S2V5LCB1bmtub3duPlxuICAgICAgICAgICAgaWYgKCgodmFsdWUgYXMgUmVjb3JkPFByb3BlcnR5S2V5LCB1bmtub3duPilbXCJ+bmFtZVwiXSBhcyBzdHJpbmcpPy5zdGFydHNXaXRoKFwiflwiKSlcbiAgICAgICAgICAgICAgY2hpbGRbaW50ZXJuYWxdID0gKHZhbHVlIGFzIFJlY29yZDxQcm9wZXJ0eUtleSwgdW5rbm93bj4pW1wifm5hbWVcIl1cbiAgICAgICAgICAgIHJldHVybiBjaGlsZFxuICAgICAgICAgIH1cbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuICh7IFtcIn5uYW1lXCJdOiBrZXksIFtcIiN0ZXh0XCJdOiBgJHt2YWx1ZX1gIH0pXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgKVxuICAgIC5tYXAoKG5vZGUpID0+IHtcbiAgICAgIGlmIChcIiN0ZXh0XCIgaW4gbm9kZSkge1xuICAgICAgICBjb25zdCBjZGF0YSA9IG5vZGVbaW50ZXJuYWxdID09PSBcIn5jZGF0YVwiXG4gICAgICAgIGNvbnN0IGNvbW1lbnQgPSBub2RlW2ludGVybmFsXSA9PT0gXCJ+Y29tbWVudFwiXG4gICAgICAgIG5vZGVbXCIjdGV4dFwiXSA9IHJlcGxhY2Uobm9kZSBhcyBYbWxOb2RlLCBcIiN0ZXh0XCIsIHsgLi4ub3B0aW9ucywgZXNjYXBlOiBjZGF0YSA/IFtdIDogW1wiJlwiLCBcIjxcIiwgXCI+XCJdIH0pIGFzIHN0cmluZ1xuICAgICAgICBpZiAobm9kZVtcIiN0ZXh0XCJdID09PSB1bmRlZmluZWQpXG4gICAgICAgICAgZGVsZXRlIG5vZGVbXCIjdGV4dFwiXVxuICAgICAgICBlbHNlXG4gICAgICAgICAgbm9kZVtcIiN0ZXh0XCJdID0gY2RhdGEgPyBgPCFbQ0RBVEFbJHtub2RlW1wiI3RleHRcIl19XV0+YCA6IGNvbW1lbnQgPyBgPCEtLSR7bm9kZVtcIiN0ZXh0XCJdfS0tPmAgOiBgJHtub2RlW1wiI3RleHRcIl19YFxuICAgICAgfVxuICAgICAgcmV0dXJuIG5vZGVcbiAgICB9KSBhcyBSZXR1cm5UeXBlPHR5cGVvZiB4bWxfY2hpbGRyZW4+XG4gIHJldHVybiBjaGlsZHJlblxufVxuXG4vKiogRXh0cmFjdCBhdHRyaWJ1dGVzIGZyb20gbm9kZS4gKi9cbmZ1bmN0aW9uIHhtbF9hdHRyaWJ1dGVzKG5vZGU6IFhtbE5vZGUsIG9wdGlvbnM6IFN0cmluZ2lmeU9wdGlvbnMpOiBBcnJheTxbc3RyaW5nLCBzdHJpbmddPiB7XG4gIHJldHVybiBPYmplY3QuZW50cmllcyhub2RlISlcbiAgICAuZmlsdGVyKChba2V5XSkgPT4ga2V5LnN0YXJ0c1dpdGgoXCJAXCIpKVxuICAgIC5tYXAoKFtrZXldKSA9PiBba2V5LnNsaWNlKDEpLCByZXBsYWNlKG5vZGUhLCBrZXksIHsgLi4ub3B0aW9ucywgZXNjYXBlOiBbXCImXCIsICdcIicsIFwiJ1wiXSB9KV0pXG4gICAgLmZpbHRlcigoW18sIHZhbHVlXSkgPT4gdmFsdWUgIT09IHVuZGVmaW5lZCkgYXMgUmV0dXJuVHlwZTx0eXBlb2YgeG1sX2F0dHJpYnV0ZXM+XG59XG5cbi8qKiBFbnRpdGllcyAqL1xuY29uc3QgZW50aXRpZXMgPSB7XG4gIFwiJlwiOiBcIiZhbXA7XCIsIC8vS2VlcCBmaXJzdFxuICAnXCInOiBcIiZxdW90O1wiLFxuICBcIjxcIjogXCImbHQ7XCIsXG4gIFwiPlwiOiBcIiZndDtcIixcbiAgXCInXCI6IFwiJmFwb3M7XCIsXG59IGFzIGNvbnN0XG5cbi8qKiBSZXBsYWNlIHZhbHVlLiAqL1xuZnVuY3Rpb24gcmVwbGFjZShub2RlOiBYbWxOb2RlIHwgWG1sVGV4dCwga2V5OiBzdHJpbmcsIG9wdGlvbnM6IFN0cmluZ2lmeU9wdGlvbnMgJiB7IGVzY2FwZT86IEFycmF5PGtleW9mIHR5cGVvZiBlbnRpdGllcz4gfSkge1xuICBsZXQgdmFsdWUgPSBgJHsobm9kZSBhcyBYbWxOb2RlKVtrZXldfWAgYXMgc3RyaW5nXG4gIGlmIChvcHRpb25zPy5lc2NhcGUpIHtcbiAgICBpZiAob3B0aW9ucz8ucmVwbGFjZT8uZW50aXRpZXMpXG4gICAgICBvcHRpb25zLmVzY2FwZSA9IE9iamVjdC5rZXlzKGVudGl0aWVzKSBhcyBBcnJheTxrZXlvZiB0eXBlb2YgZW50aXRpZXM+XG4gICAgZm9yIChjb25zdCBjaGFyIG9mIG9wdGlvbnM/LmVzY2FwZSlcbiAgICAgIHZhbHVlID0gYCR7dmFsdWV9YC5yZXBsYWNlQWxsKGNoYXIsIGVudGl0aWVzW2NoYXJdKVxuICB9XG4gIGlmIChvcHRpb25zPy5yZXBsYWNlPy5jdXN0b20pXG4gICAgcmV0dXJuIG9wdGlvbnMucmVwbGFjZS5jdXN0b20oeyBuYW1lOiBub2RlW1wifm5hbWVcIl0sIGtleSwgdmFsdWUsIG5vZGU6IG5vZGUgYXMgWG1sTm9kZSB9KVxuICByZXR1cm4gdmFsdWVcbn1cbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0NBR0MsR0FFRCxVQUFVO0FBZ0RWLDRFQUE0RSxHQUM1RSxNQUFNLFdBQVcsT0FBTztBQUV4Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Q0F1QkMsR0FDRCxPQUFPLFNBQVMsVUFBVSxRQUF1QixFQUFFLE9BQTBCO0VBQzNFLFlBQVksQ0FBQztFQUNiLFFBQVEsTUFBTSxLQUFLLENBQUM7RUFDcEIsUUFBUSxNQUFNLENBQUMsTUFBTSxLQUFLO0VBQzFCLFFBQVEsTUFBTSxDQUFDLFNBQVMsS0FBSztFQUM3QixNQUFNLFdBQVc7RUFDakIsSUFBSSxPQUFPO0VBQ1gsV0FBVyxNQUFNO0VBQ2pCLGFBQWE7RUFDYixRQUFRLFdBQVcsVUFBeUI7RUFDNUMsOEJBQThCO0VBQzlCLElBQUksUUFBUSxDQUFDLGdCQUFnQixFQUFFO0lBQzdCLEtBQUssTUFBTSxDQUFDLE1BQU0sTUFBTSxJQUFJLE9BQU8sT0FBTyxDQUFDLFFBQVEsQ0FBQyxnQkFBZ0IsRUFBRztNQUNyRSxLQUFLLE1BQU0sUUFBUTtRQUFDO09BQU0sQ0FBQyxJQUFJLEdBQUk7UUFDakMsSUFBSSxDQUFDLENBQUMsV0FBVyxJQUFJLEdBQ25CLE9BQU8sZ0JBQWdCLENBQUMsTUFBTTtVQUFFLENBQUMsUUFBUSxFQUFFO1lBQUUsWUFBWTtZQUFPLFVBQVU7WUFBTyxPQUFPO1VBQUs7UUFBRTtRQUNqRyxRQUFRLGdCQUFnQixNQUFNO01BQ2hDO0lBQ0Y7RUFDRjtFQUNBLGNBQWM7RUFDZCxJQUFJLFFBQVEsQ0FBQyxXQUFXLEVBQ3RCLFFBQVEsWUFBWSxRQUFRLENBQUMsV0FBVyxFQUFhO0VBRXZELGdCQUFnQjtFQUNoQixNQUFNLENBQUMsTUFB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
|
package/wasm/parse.d.ts
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type CleanOptions, type FlattenOptions, type ReviveOptions } from "../_parser.js";
|
|
2
|
+
import type { ReaderSync, XmlDocument } from "../_types.js";
|
|
3
|
+
export type * from "../_types.js";
|
|
4
|
+
export type { CleanOptions, FlattenOptions, ReviveOptions, Reviver } from "../_parser.js";
|
|
5
|
+
/** XML parser options. */ export type ParseOptions = {
|
|
6
|
+
/** Remove elements from result. */ clean?: CleanOptions;
|
|
7
|
+
/** Flatten result depending on node content. */ flatten?: FlattenOptions;
|
|
8
|
+
/** Revive result. */ revive?: ReviveOptions;
|
|
9
|
+
/**
|
|
10
|
+
* Parsing mode.
|
|
11
|
+
* Using `html` is more permissive and will not throw on some invalid XML syntax.
|
|
12
|
+
* Mainly unquoted attributes will be supported and not properly closed tags will be accepted.
|
|
13
|
+
*/ mode?: "xml" | "html";
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Parse a XML string into an object.
|
|
17
|
+
*
|
|
18
|
+
* Output (cleaning, flattening, reviving, etc.) can be customized using the {@link ParseOptions} parameter.
|
|
19
|
+
*
|
|
20
|
+
* Unless flattened, output nodes will contain the following non-enumerable properties (which mean they're not "visible" when iterating over, but are still explicitely accessible):
|
|
21
|
+
* - General properties
|
|
22
|
+
* - `readonly ["~name"]: string`: tag name
|
|
23
|
+
* - `readonly ["~parent"]: Nullable<XmlNode>`: parent node
|
|
24
|
+
* - `["#text"]?: string`: text content
|
|
25
|
+
* - Node properties
|
|
26
|
+
* - `readonly ["~children"]: Array<XmlNode|XmlText>`: node children
|
|
27
|
+
* - `readonly ["#comments"]?: Array<string>`: node comments
|
|
28
|
+
* - `readonly ["#text"]?: string`: concatenated children text content, this property becomes enumerable if at least one non-empty text node is present
|
|
29
|
+
* - XML document properties
|
|
30
|
+
* - `["#doctype"]?: XmlNode`: XML doctype
|
|
31
|
+
* - `["#instructions"]?: { [key:string]: Arrayable<XmlNode> }`: XML processing instructions
|
|
32
|
+
*
|
|
33
|
+
* Attributes are prefixed with an arobase (`@`).
|
|
34
|
+
*
|
|
35
|
+
* You can also pass an object that implements {@link ReaderSync} instead of a string.
|
|
36
|
+
*
|
|
37
|
+
* ```ts
|
|
38
|
+
* console.log(parse(
|
|
39
|
+
* `
|
|
40
|
+
* <root>
|
|
41
|
+
* <!-- This is a comment -->
|
|
42
|
+
* <text>hello</text>
|
|
43
|
+
* <array>world</array>
|
|
44
|
+
* <array>monde</array>
|
|
45
|
+
* <array>世界</array>
|
|
46
|
+
* <array>🌏</array>
|
|
47
|
+
* <number>42</number>
|
|
48
|
+
* <boolean>true</boolean>
|
|
49
|
+
* <complex attribute="value">content</complex>
|
|
50
|
+
* </root>
|
|
51
|
+
* `))
|
|
52
|
+
* ```
|
|
53
|
+
*/ export declare function parse(content: string, options?: ParseOptions): XmlDocument;
|
|
54
|
+
/**
|
|
55
|
+
* Parse a XML file into an object.
|
|
56
|
+
*
|
|
57
|
+
* Output (cleaning, flattening, reviving, etc.) can be customized using the {@link ParseOptions} parameter.
|
|
58
|
+
*
|
|
59
|
+
* ```ts
|
|
60
|
+
* import { fromFileUrl } from "@std/path"
|
|
61
|
+
*
|
|
62
|
+
* const file = await Deno.open(fromFileUrl(import.meta.resolve("../bench/assets/small.xml")))
|
|
63
|
+
* console.log(parse(file))
|
|
64
|
+
* ```
|
|
65
|
+
*/ export declare function parse(content: ReaderSync, options?: ParseOptions): XmlDocument;
|
|
66
|
+
/**
|
|
67
|
+
* Parse a XML stream into an object.
|
|
68
|
+
*
|
|
69
|
+
* Output (cleaning, flattening, reviving, etc.) can be customized using the {@link ParseOptions} parameter.
|
|
70
|
+
*
|
|
71
|
+
* ```ts
|
|
72
|
+
* import { fromFileUrl } from "@std/path"
|
|
73
|
+
*
|
|
74
|
+
* const file = await Deno.open(fromFileUrl(import.meta.resolve("../bench/assets/small.xml")))
|
|
75
|
+
* console.log(await parse(file.readable))
|
|
76
|
+
* ```
|
|
77
|
+
*/ export declare function parse(content: ReadableStream<Uint8Array>, options?: ParseOptions): Promise<XmlDocument>;
|
package/wasm/parse.js
ADDED
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse a XML string into an object (legacy WASM backend).
|
|
3
|
+
*
|
|
4
|
+
* This backend predates the {@link ../parse.ts} implementation based on `@std/xml` and is kept as an alternative,
|
|
5
|
+
* mainly because it additionally supports the more permissive `html` parsing mode.
|
|
6
|
+
* Both share the same options, output structure and types.
|
|
7
|
+
*
|
|
8
|
+
* @module
|
|
9
|
+
*/ // Imports
|
|
10
|
+
import { initSync, JsReader, source, Token, tokenize } from "./wasm_xml_parser.js";
|
|
11
|
+
import { finalize, xml_doctype, xml_element, xml_instruction, xml_node, xml_text } from "../_parser.js";
|
|
12
|
+
initSync(source());
|
|
13
|
+
export function parse(content, options) {
|
|
14
|
+
if (content instanceof ReadableStream) return new Response(content).bytes().then((bytes)=>parse_bytes(bytes, options));
|
|
15
|
+
return parse_bytes(content, options);
|
|
16
|
+
}
|
|
17
|
+
/** Tokenize a XML document with the WASM tokenizer and map the tokens to the same document structure as the std backend. */ function parse_bytes(content, options) {
|
|
18
|
+
const xml = xml_node("~xml");
|
|
19
|
+
const stack = [
|
|
20
|
+
xml
|
|
21
|
+
];
|
|
22
|
+
const tokens = [];
|
|
23
|
+
const states = [];
|
|
24
|
+
const flags = {
|
|
25
|
+
root: false
|
|
26
|
+
};
|
|
27
|
+
try {
|
|
28
|
+
const reader = content instanceof Uint8Array ? new JsReader(content) : new JsReader(new TextEncoder().encode(content), typeof content === "object" ? content : undefined);
|
|
29
|
+
tokenize(reader, tokens, states, options?.mode === "html");
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (states.at(-1)?.[0] === Token.StateParseAttribute) tokens.push([
|
|
32
|
+
Token.Error,
|
|
33
|
+
`Failed to parse attribute around position ${states.at(-1)[1]}`
|
|
34
|
+
]);
|
|
35
|
+
if (!states.length) throw new EvalError(`WASM XML parser crashed: ${error}`);
|
|
36
|
+
}
|
|
37
|
+
const errors = tokens.find(([token])=>token === Token.Error);
|
|
38
|
+
if (errors) throw new SyntaxError(`Malformed XML document: ${errors[1]}`);
|
|
39
|
+
for (const [token, name, value = name] of tokens){
|
|
40
|
+
switch(token){
|
|
41
|
+
// XML declaration
|
|
42
|
+
case Token.XMLDeclaration:
|
|
43
|
+
{
|
|
44
|
+
// https://www.w3.org/TR/REC-xml/#NT-VersionNum
|
|
45
|
+
const version = value.match(/version=(["'])(?<version>1\.\d+)(\1)/)?.groups?.version;
|
|
46
|
+
if (version) xml["@version"] = version;
|
|
47
|
+
// https://www.w3.org/TR/REC-xml/#NT-EncodingDecl
|
|
48
|
+
const encoding = value.match(/encoding=(["'])(?<encoding>[A-Za-z][-\w.]*)(\1)/)?.groups?.encoding;
|
|
49
|
+
if (encoding) xml["@encoding"] = encoding;
|
|
50
|
+
// https://www.w3.org/TR/REC-xml/#NT-SDDecl
|
|
51
|
+
const standalone = value.match(/standalone=(["'])(?<standalone>yes|no)(\1)/)?.groups?.standalone;
|
|
52
|
+
if (standalone) xml["@standalone"] = standalone;
|
|
53
|
+
break;
|
|
54
|
+
}
|
|
55
|
+
// XML Doctype definition
|
|
56
|
+
case Token.XMLDoctype:
|
|
57
|
+
{
|
|
58
|
+
xml["#doctype"] = Object.assign(xml_node("~doctype", {
|
|
59
|
+
parent: xml
|
|
60
|
+
}), xml_doctype(value));
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
// XML processing instruction
|
|
64
|
+
case Token.XMLInstruction:
|
|
65
|
+
{
|
|
66
|
+
const target = value.match(/^\S+/)?.[0] ?? "";
|
|
67
|
+
xml_instruction(xml, target, value.slice(target.length).trim());
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
// XML tag opened
|
|
71
|
+
case Token.TagOpen:
|
|
72
|
+
{
|
|
73
|
+
if (stack.length === 1) {
|
|
74
|
+
if (flags.root) throw new SyntaxError("Multiple root node detected");
|
|
75
|
+
flags.root = true;
|
|
76
|
+
}
|
|
77
|
+
stack.push(xml_element(name, stack.at(-1)));
|
|
78
|
+
break;
|
|
79
|
+
}
|
|
80
|
+
// XML tag closed
|
|
81
|
+
case Token.TagClose:
|
|
82
|
+
{
|
|
83
|
+
stack.pop();
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
// XML attribute
|
|
87
|
+
case Token.TagAttribute:
|
|
88
|
+
{
|
|
89
|
+
stack.at(-1)[`@${name}`] = value;
|
|
90
|
+
break;
|
|
91
|
+
}
|
|
92
|
+
// Text
|
|
93
|
+
case Token.Text:
|
|
94
|
+
{
|
|
95
|
+
xml_text(value, {
|
|
96
|
+
type: "~text",
|
|
97
|
+
parent: stack.at(-1)
|
|
98
|
+
});
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
// CDATA
|
|
102
|
+
case Token.CData:
|
|
103
|
+
{
|
|
104
|
+
xml_text(value, {
|
|
105
|
+
type: "~cdata",
|
|
106
|
+
parent: stack.at(-1)
|
|
107
|
+
});
|
|
108
|
+
break;
|
|
109
|
+
}
|
|
110
|
+
// Comment
|
|
111
|
+
case Token.Comment:
|
|
112
|
+
{
|
|
113
|
+
xml_text(value, {
|
|
114
|
+
type: "~comment",
|
|
115
|
+
parent: stack.at(-1)
|
|
116
|
+
});
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return finalize(xml, options);
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMveG1sL3dhc20vcGFyc2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBQYXJzZSBhIFhNTCBzdHJpbmcgaW50byBhbiBvYmplY3QgKGxlZ2FjeSBXQVNNIGJhY2tlbmQpLlxuICpcbiAqIFRoaXMgYmFja2VuZCBwcmVkYXRlcyB0aGUge0BsaW5rIC4uL3BhcnNlLnRzfSBpbXBsZW1lbnRhdGlvbiBiYXNlZCBvbiBgQHN0ZC94bWxgIGFuZCBpcyBrZXB0IGFzIGFuIGFsdGVybmF0aXZlLFxuICogbWFpbmx5IGJlY2F1c2UgaXQgYWRkaXRpb25hbGx5IHN1cHBvcnRzIHRoZSBtb3JlIHBlcm1pc3NpdmUgYGh0bWxgIHBhcnNpbmcgbW9kZS5cbiAqIEJvdGggc2hhcmUgdGhlIHNhbWUgb3B0aW9ucywgb3V0cHV0IHN0cnVjdHVyZSBhbmQgdHlwZXMuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbi8vIEltcG9ydHNcbmltcG9ydCB7IGluaXRTeW5jLCBKc1JlYWRlciwgc291cmNlLCBUb2tlbiwgdG9rZW5pemUgfSBmcm9tIFwiLi93YXNtX3htbF9wYXJzZXIuanNcIlxuaW1wb3J0IHsgdHlwZSBDbGVhbk9wdGlvbnMsIGZpbmFsaXplLCB0eXBlIEZsYXR0ZW5PcHRpb25zLCB0eXBlIFJldml2ZU9wdGlvbnMsIHhtbF9kb2N0eXBlLCB4bWxfZWxlbWVudCwgeG1sX2luc3RydWN0aW9uLCB4bWxfbm9kZSwgeG1sX3RleHQgfSBmcm9tIFwiLi4vX3BhcnNlci5qc1wiXG5pbXBvcnQgdHlwZSB7IFJlYWRlclN5bmMsIFhtbERvY3VtZW50LCBYbWxOb2RlIH0gZnJvbSBcIi4uL190eXBlcy5qc1wiXG5leHBvcnQgdHlwZSAqIGZyb20gXCIuLi9fdHlwZXMuanNcIlxuZXhwb3J0IHR5cGUgeyBDbGVhbk9wdGlvbnMsIEZsYXR0ZW5PcHRpb25zLCBSZXZpdmVPcHRpb25zLCBSZXZpdmVyIH0gZnJvbSBcIi4uL19wYXJzZXIuanNcIlxuaW5pdFN5bmMoc291cmNlKCkpXG5cbi8qKiBYTUwgcGFyc2VyIG9wdGlvbnMuICovXG5leHBvcnQgdHlwZSBQYXJzZU9wdGlvbnMgPSB7XG4gIC8qKiBSZW1vdmUgZWxlbWVudHMgZnJvbSByZXN1bHQuICovXG4gIGNsZWFuPzogQ2xlYW5PcHRpb25zXG4gIC8qKiBGbGF0dGVuIHJlc3VsdCBkZXBlbmRpbmcgb24gbm9kZSBjb250ZW50LiAqL1xuICBmbGF0dGVuPzogRmxhdHRlbk9wdGlvbnNcbiAgLyoqIFJldml2ZSByZXN1bHQuICovXG4gIHJldml2ZT86IFJldml2ZU9wdGlvbnNcbiAgLyoqXG4gICAqIFBhcnNpbmcgbW9kZS5cbiAgICogVXNpbmcgYGh0bWxgIGlzIG1vcmUgcGVybWlzc2l2ZSBhbmQgd2lsbCBub3QgdGhyb3cgb24gc29tZSBpbnZhbGlkIFhNTCBzeW50YXguXG4gICAqIE1haW5seSB1bnF1b3RlZCBhdHRyaWJ1dGVzIHdpbGwgYmUgc3VwcG9ydGVkIGFuZCBub3QgcHJvcGVybHkgY2xvc2VkIHRhZ3Mgd2lsbCBiZSBhY2NlcHRlZC5cbiAgICovXG4gIG1vZGU/OiBcInhtbFwiIHwgXCJodG1sXCJcbn1cblxuLyoqXG4gKiBQYXJzZSBhIFhNTCBzdHJpbmcgaW50byBhbiBvYmplY3QuXG4gKlxuICogT3V0cHV0IChjbGVhbmluZywgZmxhdHRlbmluZywgcmV2aXZpbmcsIGV0Yy4pIGNhbiBiZSBjdXN0b21pemVkIHVzaW5nIHRoZSB7QGxpbmsgUGFyc2VPcHRpb25zfSBwYXJhbWV0ZXIuXG4gKlxuICogVW5sZXNzIGZsYXR0ZW5lZCwgb3V0cHV0IG5vZGVzIHdpbGwgY29udGFpbiB0aGUgZm9sbG93aW5nIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgKHdoaWNoIG1lYW4gdGhleSdyZSBub3QgXCJ2aXNpYmxlXCIgd2hlbiBpdGVyYXRpbmcgb3ZlciwgYnV0IGFyZSBzdGlsbCBleHBsaWNpdGVseSBhY2Nlc3NpYmxlKTpcbiAqIC0gR2VuZXJhbCBwcm9wZXJ0aWVzXG4gKiAgIC0gYHJlYWRvbmx5IFtcIn5uYW1lXCJdOiBzdHJpbmdgOiB0YWcgbmFtZVxuICogICAtIGByZWFkb25seSBbXCJ+cGFyZW50XCJdOiBOdWxsYWJsZTxYbWxOb2RlPmA6IHBhcmVudCBub2RlXG4gKiAgIC0gYFtcIiN0ZXh0XCJdPzogc3RyaW5nYDogdGV4dCBjb250ZW50XG4gKiAtIE5vZGUgcHJvcGVydGllc1xuICogICAtIGByZWFkb25seSBbXCJ+Y2hpbGRyZW5cIl06IEFycmF5PFhtbE5vZGV8WG1sVGV4dD5gOiBub2RlIGNoaWxkcmVuXG4gKiAgIC0gYHJlYWRvbmx5IFtcIiNjb21tZW50c1wiXT86IEFycmF5PHN0cmluZz5gOiBub2RlIGNvbW1lbnRzXG4gKiAgIC0gYHJlYWRvbmx5IFtcIiN0ZXh0XCJdPzogc3RyaW5nYDogY29uY2F0ZW5hdGVkIGNoaWxkcmVuIHRleHQgY29udGVudCwgdGhpcyBwcm9wZXJ0eSBiZWNvbWVzIGVudW1lcmFibGUgaWYgYXQgbGVhc3Qgb25lIG5vbi1lbXB0eSB0ZXh0IG5vZGUgaXMgcHJlc2VudFxuICogLSBYTUwgZG9jdW1lbnQgcHJvcGVydGllc1xuICogIC0gYFtcIiNkb2N0eXBlXCJdPzogWG1sTm9kZWA6IFhNTCBkb2N0eXBlXG4gKiAgLSBgW1wiI2luc3RydWN0aW9uc1wiXT86IHsgW2tleTpzdHJpbmddOiBBcnJheWFibGU8WG1sTm9kZT4gfWA6IFhNTCBwcm9jZXNzaW5nIGluc3RydWN0aW9uc1xuICpcbiAqIEF0dHJpYnV0ZXMgYXJlIHByZWZpeGVkIHdpdGggYW4gYXJvYmFzZSAoYEBgKS5cbiAqXG4gKiBZb3UgY2FuIGFsc28gcGFzcyBhbiBvYmplY3QgdGhhdCBpbXBsZW1lbnRzIHtAbGluayBSZWFkZXJTeW5jfSBpbnN0ZWFkIG9mIGEgc3RyaW5nLlxuICpcbiAqIGBgYHRzXG4gKiBjb25zb2xlLmxvZyhwYXJzZShcbiAqIGBcbiAqICAgPHJvb3Q+XG4gKiAgICAgPCEtLSBUaGlzIGlzIGEgY29tbWVudCAtLT5cbiAqICAgICA8dGV4dD5oZWxsbzwvdGV4dD5cbiAqICAgICA8YXJyYXk+d29ybGQ8L2FycmF5PlxuICogICAgIDxhcnJheT5tb25kZTwvYXJyYXk+XG4gKiAgICAgPGFycmF5PuS4lueVjDwvYXJyYXk+XG4gKiAgICAgPGFycmF5PvCfjI88L2FycmF5PlxuICogICAgIDxudW1iZXI+NDI8L251bWJlcj5cbiAqICAgICA8Ym9vbGVhbj50cnVlPC9ib29sZWFuPlxuICogICAgIDxjb21wbGV4IGF0dHJpYnV0ZT1cInZhbHVlXCI+Y29udGVudDwvY29tcGxleD5cbiAqICAgPC9yb290PlxuICogYCkpXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlKGNvbnRlbnQ6IHN0cmluZywgb3B0aW9ucz86IFBhcnNlT3B0aW9ucyk6IFhtbERvY3VtZW50XG4vKipcbiAqIFBhcnNlIGEgWE1MIGZpbGUgaW50byBhbiBvYmplY3QuXG4gKlxuICogT3V0cHV0IChjbGVhbmluZywgZmxhdHRlbmluZywgcmV2aXZpbmcsIGV0Yy4pIGNhbiBiZSBjdXN0b21pemVkIHVzaW5nIHRoZSB7QGxpbmsgUGFyc2VPcHRpb25zfSBwYXJhbWV0ZXIuXG4gKlxuICogYGBgdHNcbiAqIGltcG9ydCB7IGZyb21GaWxlVXJsIH0gZnJvbSBcIkBzdGQvcGF0aFwiXG4gKlxuICogY29uc3QgZmlsZSA9IGF3YWl0IERlbm8ub3Blbihmcm9tRmlsZVVybChpbXBvcnQubWV0YS5yZXNvbHZlKFwiLi4vYmVuY2gvYXNzZXRzL3NtYWxsLnhtbFwiKSkpXG4gKiBjb25zb2xlLmxvZyhwYXJzZShmaWxlKSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2UoY29udGVudDogUmVhZGVyU3luYywgb3B0aW9ucz86IFBhcnNlT3B0aW9ucyk6IFhtbERvY3VtZW50XG4vKipcbiAqIFBhcnNlIGEgWE1MIHN0cmVhbSBpbnRvIGFuIG9iamVjdC5cbiAqXG4gKiBPdXRwdXQgKGNsZWFuaW5nLCBmbGF0dGVuaW5nLCByZXZpdmluZywgZXRjLikgY2FuIGJlIGN1c3RvbWl6ZWQgdXNpbmcgdGhlIHtAbGluayBQYXJzZU9wdGlvbnN9IHBhcmFtZXRlci5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgZnJvbUZpbGVVcmwgfSBmcm9tIFwiQHN0ZC9wYXRoXCJcbiAqXG4gKiBjb25zdCBmaWxlID0gYXdhaXQgRGVuby5vcGVuKGZyb21GaWxlVXJsKGltcG9ydC5tZXRhLnJlc29sdmUoXCIuLi9iZW5jaC9hc3NldHMvc21hbGwueG1sXCIpKSlcbiAqIGNvbnNvbGUubG9nKGF3YWl0IHBhcnNlKGZpbGUucmVhZGFibGUpKVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZShjb250ZW50OiBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5Piwgb3B0aW9ucz86IFBhcnNlT3B0aW9ucyk6IFByb21pc2U8WG1sRG9jdW1lbnQ+XG5leHBvcnQgZnVuY3Rpb24gcGFyc2UoY29udGVudDogc3RyaW5nIHwgUmVhZGVyU3luYyB8IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+LCBvcHRpb25zPzogUGFyc2VPcHRpb25zKSB7XG4gIGlmIChjb250ZW50IGluc3RhbmNlb2YgUmVhZGFibGVTdHJlYW0pXG4gICAgcmV0dXJuIG5ldyBSZXNwb25zZShjb250ZW50KS5ieXRlcygpLnRoZW4oKGJ5dGVzKSA9PiBwYXJzZV9ieXRlcyhieXRlcywgb3B0aW9ucykpXG4gIHJldHVybiBwYXJzZV9ieXRlcyhjb250ZW50LCBvcHRpb25zKVxufVxuXG4vKiogVG9rZW5pemUgYSBYTUwgZG9jdW1lbnQgd2l0aCB0aGUgV0FTTSB0b2tlbml6ZXIgYW5kIG1hcCB0aGUgdG9rZW5zIHRvIHRoZSBzYW1lIGRvY3VtZW50IHN0cnVjdHVyZSBhcyB0aGUgc3RkIGJhY2tlbmQuICovXG5mdW5jdGlvbiBwYXJzZV9ieXRlcyhjb250ZW50OiBzdHJpbmcgfCBSZWFkZXJTeW5jIHwgVWludDhBcnJheSwgb3B0aW9ucz86IFBhcnNlT3B0aW9ucyk6IFhtbERvY3VtZW50IHtcbiAgY29uc3QgeG1sID0geG1sX25vZGUoXCJ+eG1sXCIpIGFzIFhtbERvY3VtZW50XG4gIGNvbnN0IHN0YWNrID0gW3htbF0gYXMgQXJyYXk8WG1sTm9kZT5cbiAgY29uc3QgdG9rZW5zID0gW10gYXMgQXJyYXk8W251bWJlciwgc3RyaW5nLCBzdHJpbmc/XT5cbiAgY29uc3Qgc3RhdGVzID0gW10gYXMgQXJyYXk8W251bWJlciwgbnVtYmVyXT5cbiAgY29uc3QgZmxhZ3MgPSB7IHJvb3Q6IGZhbHNlIH1cbiAgdHJ5IHtcbiAgICBjb25zdCByZWFkZXIgPSBjb250ZW50IGluc3RhbmNlb2YgVWludDhBcnJheSA/IG5ldyBKc1JlYWRlcihjb250ZW50KSA6IG5ldyBKc1JlYWRlcihuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoY29udGVudCBhcyBzdHJpbmcpLCB0eXBlb2YgY29udGVudCA9PT0gXCJvYmplY3RcIiA/IGNvbnRlbnQgOiB1bmRlZmluZWQpXG4gICAgdG9rZW5pemUocmVhZGVyLCB0b2tlbnMsIHN0YXRlcywgb3B0aW9ucz8ubW9kZSA9PT0gXCJodG1sXCIpXG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKHN0YXRlcy5hdCgtMSk/LlswXSA9PT0gVG9rZW4uU3RhdGVQYXJzZUF0dHJpYnV0ZSlcbiAgICAgIHRva2Vucy5wdXNoKFtUb2tlbi5FcnJvciwgYEZhaWxlZCB0byBwYXJzZSBhdHRyaWJ1dGUgYXJvdW5kIHBvc2l0aW9uICR7c3RhdGVzLmF0KC0xKSFbMV19YF0pXG4gICAgaWYgKCFzdGF0ZXMubGVuZ3RoKVxuICAgICAgdGhyb3cgbmV3IEV2YWxFcnJvcihgV0FTTSBYTUwgcGFyc2VyIGNyYXNoZWQ6ICR7ZXJyb3J9YClcbiAgfVxuICBjb25zdCBlcnJvcnMgPSB0b2tlbnMuZmluZCgoW3Rva2VuXSkgPT4gdG9rZW4gPT09IFRva2VuLkVycm9yKVxuICBpZiAoZXJyb3JzKVxuICAgIHRocm93IG5ldyBTeW50YXhFcnJvcihgTWFsZm9ybWVkIFhNTCBkb2N1bWVudDogJHtlcnJvcnNbMV19YClcbiAgZm9yIChjb25zdCBbdG9rZW4sIG5hbWUsIHZhbHVlID0gbmFtZV0gb2YgdG9rZW5zKSB7XG4gICAgc3dpdGNoICh0b2tlbikge1xuICAgICAgLy8gWE1MIGRlY2xhcmF0aW9uXG4gICAgICBjYXNlIFRva2VuLlhNTERlY2xhcmF0aW9uOiB7XG4gICAgICAgIC8vIGh0dHBzOi8vd3d3LnczLm9yZy9UUi9SRUMteG1sLyNOVC1WZXJzaW9uTnVtXG4gICAgICAgIGNvbnN0IHZlcnNpb24gPSB2YWx1ZS5tYXRjaCgvdmVyc2lvbj0oW1wiJ10pKD88dmVyc2lvbj4xXFwuXFxkKykoXFwxKS8pPy5ncm91cHM/LnZlcnNpb25cbiAgICAgICAgaWYgKHZlcnNpb24pXG4gICAgICAgICAgeG1sW1wiQHZlcnNpb25cIl0gPSB2ZXJzaW9uIGFzIHR5cGVvZiB4bWxbXCJAdmVyc2lvblwiXVxuICAgICAgICAvLyBodHRwczovL3d3dy53My5vcmcvVFIvUkVDLXhtbC8jTlQtRW5jb2RpbmdEZWNsXG4gICAgICAgIGNvbnN0IGVuY29kaW5nID0gdmFsdWUubWF0Y2goL2VuY29kaW5nPShbXCInXSkoPzxlbmNvZGluZz5bQS1aYS16XVstXFx3Ll0qKShcXDEpLyk/Lmdyb3Vwcz8uZW5jb2RpbmdcbiAgICAgICAgaWYgKGVuY29kaW5nKVxuICAgICAgICAgIHhtbFtcIkBlbmNvZGluZ1wiXSA9IGVuY29kaW5nIGFzIHR5cGVvZiB4bWxbXCJAZW5jb2RpbmdcIl1cbiAgICAgICAgLy8gaHR0cHM6Ly93d3cudzMub3JnL1RSL1JFQy14bWwvI05ULVNERGVjbFxuICAgICAgICBjb25zdCBzdGFuZGFsb25lID0gdmFsdWUubWF0Y2goL3N0YW5kYWxvbmU9KFtcIiddKSg/PHN0YW5kYWxvbmU+eWVzfG5vKShcXDEpLyk/Lmdyb3Vwcz8uc3RhbmRhbG9uZVxuICAgICAgICBpZiAoc3RhbmRhbG9uZSlcbiAgICAgICAgICB4bWxbXCJAc3RhbmRhbG9uZVwiXSA9IHN0YW5kYWxvbmUgYXMgdHlwZW9mIHhtbFtcIkBzdGFuZGFsb25lXCJdXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICAvLyBYTUwgRG9jdHlwZSBkZWZpbml0aW9uXG4gICAgICBjYXNlIFRva2VuLlhNTERvY3R5cGU6IHtcbiAgICAgICAgeG1sW1wiI2RvY3R5cGVcIl0gPSBPYmplY3QuYXNzaWduKHhtbF9ub2RlKFwifmRvY3R5cGVcIiwgeyBwYXJlbnQ6IHhtbCB9KSwgeG1sX2RvY3R5cGUodmFsdWUpKVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgLy8gWE1MIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25cbiAgICAgIGNhc2UgVG9rZW4uWE1MSW5zdHJ1Y3Rpb246IHtcbiAgICAgICAgY29uc3QgdGFyZ2V0ID0gdmFsdWUubWF0Y2goL15cXFMrLyk/LlswXSA/PyBcIlwiXG4gICAgICAgIHhtbF9pbnN0cnVjdGlvbih4bWwsIHRhcmdldCwgdmFsdWUuc2xpY2UodGFyZ2V0Lmxlbmd0aCkudHJpbSgpKVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgLy8gWE1MIHRhZyBvcGVuZWRcbiAgICAgIGNhc2UgVG9rZW4uVGFnT3Blbjoge1xuICAgICAgICBpZiAoc3RhY2subGVuZ3RoID09PSAxKSB7XG4gICAgICAgICAgaWYgKGZsYWdzLnJvb3QpXG4gICAgICAgICAgICB0aHJvdyBuZXcgU3ludGF4RXJyb3IoXCJNdWx0aXBsZSByb290IG5vZGUgZGV0ZWN0ZWRcIilcbiAgICAgICAgICBmbGFncy5yb290ID0gdHJ1ZVxuICAgICAgICB9XG4gICAgICAgIHN0YWNrLnB1c2goeG1sX2VsZW1lbnQobmFtZSwgc3RhY2suYXQoLTEpISkpXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICAvLyBYTUwgdGFnIGNsb3NlZFxuICAgICAgY2FzZSBUb2tlbi5UYWdDbG9zZToge1xuICAgICAgICBzdGFjay5wb3AoKVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgLy8gWE1MIGF0dHJpYnV0ZVxuICAgICAgY2FzZSBUb2tlbi5UYWdBdHRyaWJ1dGU6IHtcbiAgICAgICAgc3RhY2suYXQoLTEpIVtgQCR7bmFtZX1gXSA9IHZhbHVlXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgICAvLyBUZXh0XG4gICAgICBjYXNlIFRva2VuLlRleHQ6IHtcbiAgICAgICAgeG1sX3RleHQodmFsdWUsIHsgdHlwZTogXCJ+dGV4dFwiLCBwYXJlbnQ6IHN0YWNrLmF0KC0xKSEgfSlcbiAgICAgICAgYnJlYWtcbiAgICAgIH1cbiAgICAgIC8vIENEQVRBXG4gICAgICBjYXNlIFRva2VuLkNEYXRhOiB7XG4gICAgICAgIHhtbF90ZXh0KHZhbHVlLCB7IHR5cGU6IFwifmNkYXRhXCIsIHBhcmVudDogc3RhY2suYXQoLTEpISB9KVxuICAgICAgICBicmVha1xuICAgICAgfVxuICAgICAgLy8gQ29tbWVudFxuICAgICAgY2FzZSBUb2tlbi5Db21tZW50OiB7XG4gICAgICAgIHhtbF90ZXh0KHZhbHVlLCB7IHR5cGU6IFwifmNvbW1lbnRcIiwgcGFyZW50OiBzdGFjay5hdCgtMSkhIH0pXG4gICAgICAgIGJyZWFrXG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBmaW5hbGl6ZSh4bWwsIG9wdGlvbnMpXG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7O0NBUUMsR0FFRCxVQUFVO0FBQ1YsU0FBUyxRQUFRLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsUUFBUSxRQUFRLHVCQUFzQjtBQUNsRixTQUE0QixRQUFRLEVBQTJDLFdBQVcsRUFBRSxXQUFXLEVBQUUsZUFBZSxFQUFFLFFBQVEsRUFBRSxRQUFRLFFBQVEsZ0JBQWU7QUFJbkssU0FBUztBQW9GVCxPQUFPLFNBQVMsTUFBTSxPQUF5RCxFQUFFLE9BQXNCO0VBQ3JHLElBQUksbUJBQW1CLGdCQUNyQixPQUFPLElBQUksU0FBUyxTQUFTLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxRQUFVLFlBQVks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
|