@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/deno.lock CHANGED
@@ -1,112 +1,32 @@
1
1
  {
2
- "version": "4",
2
+ "version": "5",
3
3
  "specifiers": {
4
- "jsr:@libs/logger@2": "2.1.4",
5
- "jsr:@libs/run@2": "2.0.5",
6
- "jsr:@libs/testing@3": "3.0.0",
7
- "jsr:@libs/typing@2": "2.9.0",
8
- "jsr:@libs/typing@3": "3.0.0",
9
- "jsr:@std/assert@1": "1.0.6",
10
- "jsr:@std/assert@^1.0.6": "1.0.6",
11
- "jsr:@std/async@1": "1.0.5",
12
- "jsr:@std/bytes@^1.0.2": "1.0.2",
13
- "jsr:@std/expect@1": "1.0.4",
14
- "jsr:@std/fmt@1": "1.0.2",
15
- "jsr:@std/fs@1": "1.0.4",
16
- "jsr:@std/html@1": "1.0.3",
17
- "jsr:@std/http@1": "1.0.7",
18
- "jsr:@std/internal@^1.0.4": "1.0.4",
19
- "jsr:@std/path@1": "1.0.6",
20
- "jsr:@std/streams@1": "1.0.6",
21
- "npm:highlight.js@11": "11.10.0"
4
+ "jsr:@std/internal@^1.0.14": "1.0.14",
5
+ "jsr:@std/path@^1.1.4": "1.1.6",
6
+ "jsr:@std/xml@~0.1.3": "0.1.3"
22
7
  },
23
8
  "jsr": {
24
- "@libs/logger@2.1.4": {
25
- "integrity": "47d100412f9c16b5752d670d7fb182a2dce2cda26a72896e0f69d3a2de35fa1f"
9
+ "@std/internal@1.0.14": {
10
+ "integrity": "291516b3d4c35024d6ffbc0a9df5bf4c64116e05b50012cf846710152d2ffdf7"
26
11
  },
27
- "@libs/run@2.0.5": {
28
- "integrity": "6da09b6d9458a7f8134a113f7a70186742e6f759423a60f7037ca1001bbf1b78",
12
+ "@std/path@1.1.6": {
13
+ "integrity": "c68485c2a4dfbb5ae3cc74fae4e8c4e5d874cf8a8ed12927917235c758b46cbe",
29
14
  "dependencies": [
30
- "jsr:@libs/logger",
31
- "jsr:@libs/typing@2",
32
- "jsr:@std/async",
33
- "jsr:@std/streams"
34
- ]
35
- },
36
- "@libs/testing@3.0.0": {
37
- "integrity": "514547988fadac36890692ccafc932546d9e27680df1b736dd7674ad2e7c9625",
38
- "dependencies": [
39
- "jsr:@libs/run",
40
- "jsr:@libs/typing@2",
41
- "jsr:@std/assert@1",
42
- "jsr:@std/expect",
43
- "jsr:@std/fmt",
44
- "jsr:@std/html",
45
- "jsr:@std/http",
46
- "npm:highlight.js"
47
- ]
48
- },
49
- "@libs/typing@2.9.0": {
50
- "integrity": "ddf35ea652b807cd9b19b4f3f163fb5d76d57299053753fbd01ba8b02d9306ad"
51
- },
52
- "@libs/typing@3.0.0": {
53
- "integrity": "f84ffbbdcbb6a02e6a527911b1399dc79f6ad213aec4ad0a86c95df4b353738f"
54
- },
55
- "@std/assert@1.0.6": {
56
- "integrity": "1904c05806a25d94fe791d6d883b685c9e2dcd60e4f9fc30f4fc5cf010c72207",
57
- "dependencies": [
58
- "jsr:@std/internal"
59
- ]
60
- },
61
- "@std/async@1.0.5": {
62
- "integrity": "31d68214bfbb31bd4c6022401d484e3964147c76c9220098baa703a39b6c2da6"
63
- },
64
- "@std/bytes@1.0.2": {
65
- "integrity": "fbdee322bbd8c599a6af186a1603b3355e59a5fb1baa139f8f4c3c9a1b3e3d57"
66
- },
67
- "@std/expect@1.0.4": {
68
- "integrity": "97f68a445a9de0d9670200d2b7a19a7505a01b2cb390a983ba8d97d90ce30c4f",
69
- "dependencies": [
70
- "jsr:@std/assert@^1.0.6",
71
15
  "jsr:@std/internal"
72
16
  ]
73
17
  },
74
- "@std/fmt@1.0.2": {
75
- "integrity": "87e9dfcdd3ca7c066e0c3c657c1f987c82888eb8103a3a3baa62684ffeb0f7a7"
76
- },
77
- "@std/fs@1.0.4": {
78
- "integrity": "2907d32d8d1d9e540588fd5fe0ec21ee638134bd51df327ad4e443aaef07123c"
79
- },
80
- "@std/html@1.0.3": {
81
- "integrity": "7a0ac35e050431fb49d44e61c8b8aac1ebd55937e0dc9ec6409aa4bab39a7988"
82
- },
83
- "@std/http@1.0.7": {
84
- "integrity": "9b904fc256678a5c9759f1a53a24a3fdcc59d83dc62099bb472683b6f819194c"
85
- },
86
- "@std/internal@1.0.4": {
87
- "integrity": "62e8e4911527e5e4f307741a795c0b0a9e6958d0b3790716ae71ce085f755422"
88
- },
89
- "@std/path@1.0.6": {
90
- "integrity": "ab2c55f902b380cf28e0eec501b4906e4c1960d13f00e11cfbcd21de15f18fed"
91
- },
92
- "@std/streams@1.0.6": {
93
- "integrity": "022ed94e380d06b4d91c49eb70241b7289ab78b8c2b4c4bbb7eb265e4997c25c",
94
- "dependencies": [
95
- "jsr:@std/bytes"
96
- ]
97
- }
98
- },
99
- "npm": {
100
- "highlight.js@11.10.0": {
101
- "integrity": "sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ=="
18
+ "@std/xml@0.1.3": {
19
+ "integrity": "afb7750d09f9f521046b27119d0e63f7aaad6eeb3d74e5f41fc04a9958014811"
102
20
  }
103
21
  },
104
22
  "workspace": {
105
23
  "dependencies": [
106
- "jsr:@libs/testing@3",
107
- "jsr:@libs/typing@3",
108
- "jsr:@std/fs@1",
109
- "jsr:@std/path@1"
110
- ]
24
+ "jsr:@std/path@^1.1.4"
25
+ ],
26
+ "packageJson": {
27
+ "dependencies": [
28
+ "npm:@jsr/std__path@^1.1.4"
29
+ ]
30
+ }
111
31
  }
112
32
  }
package/mod.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./parse.js";
2
+ export * from "./stringify.js";
3
+ export type * from "./_types.js";
package/mod.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./parse.js";
2
+ export * from "./stringify.js";
3
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMveG1sL21vZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgKiBmcm9tIFwiLi9wYXJzZS5qc1wiXG5leHBvcnQgKiBmcm9tIFwiLi9zdHJpbmdpZnkuanNcIlxuZXhwb3J0IHR5cGUgKiBmcm9tIFwiLi9fdHlwZXMuanNcIlxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLGNBQWMsYUFBWTtBQUMxQixjQUFjLGlCQUFnQiJ9
package/package.json CHANGED
@@ -1,28 +1,32 @@
1
1
  {
2
2
  "name": "@lowlighter/xml",
3
- "version": "6.0.0",
3
+ "version": "8.0.0",
4
4
  "type": "module",
5
- "scripts": {},
6
- "dependencies": {},
7
- "devDependencies": {},
8
- "description": "XML parser/stringifier with no dependencies.",
9
- "keywords": [
10
- "xml",
11
- "parser",
12
- "stringifier",
13
- "esm"
14
- ],
15
- "license": "MIT",
16
- "author": "lowlighter (Simon Lecoq)",
17
- "homepage": "https://github.com/lowlighter/libs",
18
- "repository": {
19
- "type": "git",
20
- "url": "git+https://github.com/lowlighter/libs.git"
21
- },
22
- "funding": "https://github.com/sponsors/lowlighter",
5
+ "main": "./mod.js",
6
+ "types": "./mod.d.ts",
23
7
  "exports": {
24
- ".": "./mod.mjs",
25
- "./parse": "./parse.mjs",
26
- "./stringify": "./stringify.mjs"
8
+ ".": {
9
+ "types": "./mod.d.ts",
10
+ "import": "./mod.js",
11
+ "default": "./mod.js"
12
+ },
13
+ "./parse": {
14
+ "types": "./parse.d.ts",
15
+ "import": "./parse.js",
16
+ "default": "./parse.js"
17
+ },
18
+ "./stringify": {
19
+ "types": "./stringify.d.ts",
20
+ "import": "./stringify.js",
21
+ "default": "./stringify.js"
22
+ },
23
+ "./wasm/parse": {
24
+ "types": "./wasm/parse.d.ts",
25
+ "import": "./wasm/parse.js",
26
+ "default": "./wasm/parse.js"
27
+ }
28
+ },
29
+ "dependencies": {
30
+ "@jsr/std__xml": "^0.1.3"
27
31
  }
28
- }
32
+ }
package/parse.d.ts ADDED
@@ -0,0 +1,81 @@
1
+ import { type CleanOptions, type FlattenOptions, type ReviveOptions } from "./_parser.js";
2
+ import type { 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
+ *
14
+ * > Note: `html` mode is currently not supported, use the WASM backend (`@libs/xml/wasm/parse`) instead.
15
+ * > Tracking issue: https://github.com/denoland/std/issues/7212
16
+ */ mode?: "xml";
17
+ };
18
+ /**
19
+ * Parse a XML string into an object.
20
+ *
21
+ * Output (cleaning, flattening, reviving, etc.) can be customized using the {@link ParseOptions} parameter.
22
+ *
23
+ * 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):
24
+ * - General properties
25
+ * - `readonly ["~name"]: string`: tag name
26
+ * - `readonly ["~parent"]: Nullable<XmlNode>`: parent node
27
+ * - `["#text"]?: string`: text content
28
+ * - Node properties
29
+ * - `readonly ["~children"]: Array<XmlNode|XmlText>`: node children
30
+ * - `readonly ["#comments"]?: Array<string>`: node comments
31
+ * - `readonly ["#text"]?: string`: concatenated children text content, this property becomes enumerable if at least one non-empty text node is present
32
+ * - XML document properties
33
+ * - `["#doctype"]?: XmlNode`: XML doctype
34
+ * - `["#instructions"]?: { [key:string]: Arrayable<XmlNode> }`: XML processing instructions
35
+ *
36
+ * Attributes are prefixed with an arobase (`@`).
37
+ *
38
+ * ```ts
39
+ * console.log(parse(
40
+ * `
41
+ * <root>
42
+ * <!-- This is a comment -->
43
+ * <text>hello</text>
44
+ * <array>world</array>
45
+ * <array>monde</array>
46
+ * <array>世界</array>
47
+ * <array>🌏</array>
48
+ * <number>42</number>
49
+ * <boolean>true</boolean>
50
+ * <complex attribute="value">content</complex>
51
+ * </root>
52
+ * `))
53
+ * ```
54
+ */ export declare function parse(content: string, options?: ParseOptions): XmlDocument;
55
+ /**
56
+ * Parse a XML string into an object.
57
+ *
58
+ * Output (cleaning, flattening, reviving, etc.) can be customized using the {@link ParseOptions} parameter.
59
+ *
60
+ * 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):
61
+ * - General properties
62
+ * - `readonly ["~name"]: string`: tag name
63
+ * - `readonly ["~parent"]: Nullable<XmlNode>`: parent node
64
+ * - `["#text"]?: string`: text content
65
+ * - Node properties
66
+ * - `readonly ["~children"]: Array<XmlNode|XmlText>`: node children
67
+ * - `readonly ["#comments"]?: Array<string>`: node comments
68
+ * - `readonly ["#text"]?: string`: concatenated children text content, this property becomes enumerable if at least one non-empty text node is present
69
+ * - XML document properties
70
+ * - `["#doctype"]?: XmlNode`: XML doctype
71
+ * - `["#instructions"]?: { [key:string]: Arrayable<XmlNode> }`: XML processing instructions
72
+ *
73
+ * Attributes are prefixed with an arobase (`@`).
74
+ *
75
+ * ```ts
76
+ * import { fromFileUrl } from "@std/path"
77
+ *
78
+ * const file = await Deno.open(fromFileUrl(import.meta.resolve("./bench/assets/small.xml")))
79
+ * console.log(await parse(file.readable))
80
+ * ```
81
+ */ export declare function parse(content: ReadableStream<Uint8Array>, options?: ParseOptions): Promise<XmlDocument>;
package/parse.js ADDED
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Parse a XML string into an object.
3
+ * @module
4
+ */ // Imports
5
+ import { parse as std_parse } from "@std/xml/parse";
6
+ import { parseXmlStreamFromBytes } from "@std/xml/parse-stream";
7
+ import { finalize, xml_doctype, xml_element, xml_instruction, xml_node, xml_text } from "./_parser.js";
8
+ export function parse(content, options) {
9
+ if (typeof content !== "string") return parse_stream(content, options);
10
+ const xml = xml_node("~xml");
11
+ content = content.replace(/^\s+/, "");
12
+ // @std sync parser only exposes a DOM tree of {declaration, root}
13
+ // and is missing DOCTYPE and processing instructions (they are discarded)
14
+ // Prescan the content to recover them first
15
+ content = prescan(content, xml);
16
+ const doc = std_parse(content, {
17
+ disallowDoctype: false
18
+ });
19
+ // XML declaration
20
+ if (doc.declaration) {
21
+ if (doc.declaration.version) xml["@version"] = doc.declaration.version;
22
+ if (doc.declaration.encoding) xml["@encoding"] = doc.declaration.encoding;
23
+ if (doc.declaration.standalone) xml["@standalone"] = doc.declaration.standalone;
24
+ }
25
+ build(doc.root, xml);
26
+ return finalize(xml, options);
27
+ }
28
+ /**
29
+ * Parse a XML stream into an object.
30
+ * @std streaming parser events are mapped to the same document structure as the string version,
31
+ * and unlike the sync DOM they natively expose the doctype and processing instructions.
32
+ */ async function parse_stream(content, options) {
33
+ const xml = xml_node("~xml");
34
+ const stack = [
35
+ xml
36
+ ];
37
+ await parseXmlStreamFromBytes(content, {
38
+ // XML declaration
39
+ onDeclaration (version, encoding, standalone) {
40
+ if (version) xml["@version"] = version;
41
+ if (encoding) xml["@encoding"] = encoding;
42
+ if (standalone) xml["@standalone"] = standalone;
43
+ },
44
+ // XML doctype (only the name and public/system identifiers are exposed by @std events)
45
+ onDoctype (name, publicId, systemId) {
46
+ const doctype = xml_node("~doctype", {
47
+ parent: xml
48
+ });
49
+ [
50
+ name,
51
+ publicId,
52
+ systemId
53
+ ].filter((value)=>value !== undefined).forEach((value)=>doctype[`@${value}`] = "");
54
+ xml["#doctype"] = doctype;
55
+ },
56
+ // XML processing instruction
57
+ onProcessingInstruction (target, instruction) {
58
+ xml_instruction(xml, target, instruction.trim());
59
+ },
60
+ // XML tag opened
61
+ onStartElement (name, _colon, _uri, attributes, selfClosing) {
62
+ const node = xml_element(name, stack.at(-1));
63
+ for(let i = 0; i < attributes.count; i++)node[`@${attributes.getName(i)}`] = attributes.getValue(i);
64
+ if (!selfClosing) stack.push(node);
65
+ },
66
+ // XML tag closed
67
+ onEndElement () {
68
+ stack.pop();
69
+ },
70
+ // Text
71
+ onText (text) {
72
+ xml_text(text, {
73
+ type: "~text",
74
+ parent: stack.at(-1)
75
+ });
76
+ },
77
+ // CDATA
78
+ onCData (text) {
79
+ xml_text(text, {
80
+ type: "~cdata",
81
+ parent: stack.at(-1)
82
+ });
83
+ },
84
+ // Comment
85
+ onComment (text) {
86
+ xml_text(text, {
87
+ type: "~comment",
88
+ parent: stack.at(-1)
89
+ });
90
+ }
91
+ }, {
92
+ disallowDoctype: false
93
+ });
94
+ return finalize(xml, options);
95
+ }
96
+ /** Recover `#doctype` and `#instructions`. */ function prescan(content, xml) {
97
+ // Prolog: skip whitespace/comments, collect instructions and doctype until the root element opens
98
+ let i = 0;
99
+ prolog: while(i < content.length){
100
+ switch(true){
101
+ case /\s/.test(content[i]):
102
+ {
103
+ i++;
104
+ continue;
105
+ }
106
+ case content.startsWith("<!--", i):
107
+ {
108
+ const end = content.indexOf("-->", i + 4);
109
+ if (end < 0) break prolog;
110
+ i = end + 3;
111
+ continue;
112
+ }
113
+ case content.startsWith("<?", i):
114
+ {
115
+ const end = content.indexOf("?>", i + 2);
116
+ if (end < 0) break prolog;
117
+ const raw = content.slice(i + 2, end);
118
+ i = end + 2;
119
+ const target = raw.match(/^\S+/)?.[0] ?? "";
120
+ // The <?xml?> declaration is already handled through std's DOM
121
+ if (target !== "xml") xml_instruction(xml, target, raw.slice(target.length).trim());
122
+ continue;
123
+ }
124
+ case content.startsWith("<!DOCTYPE", i):
125
+ {
126
+ // Find the closing ">", skipping quoted literals and the internal subset "[...]"
127
+ let j = i + 9;
128
+ doctype: while(j < content.length){
129
+ switch(content[j]){
130
+ case '"':
131
+ case "'":
132
+ {
133
+ const quote = content.indexOf(content[j], j + 1);
134
+ if (quote < 0) break doctype;
135
+ j = quote + 1;
136
+ break;
137
+ }
138
+ case "[":
139
+ {
140
+ const bracket = content.indexOf("]", j + 1);
141
+ if (bracket < 0) break doctype;
142
+ j = bracket + 1;
143
+ break;
144
+ }
145
+ case ">":
146
+ break doctype;
147
+ default:
148
+ j++;
149
+ }
150
+ }
151
+ xml["#doctype"] = Object.assign(xml_node("~doctype", {
152
+ parent: xml
153
+ }), xml_doctype(content.slice(i + 9, j).trim()));
154
+ const end = Math.min(j + 1, content.length);
155
+ content = `${content.slice(0, i)}${" ".repeat(end - i)}${content.slice(end)}`;
156
+ i = end;
157
+ continue;
158
+ }
159
+ default:
160
+ break prolog;
161
+ }
162
+ }
163
+ // Epilog: only comments and instructions may follow the root element, scan them backwards
164
+ const instructions = [];
165
+ let tail = content.trimEnd();
166
+ epilog: while(true){
167
+ switch(true){
168
+ case tail.endsWith("-->"):
169
+ {
170
+ const start = tail.lastIndexOf("<!--");
171
+ if (start < 0) break epilog;
172
+ tail = tail.slice(0, start).trimEnd();
173
+ continue;
174
+ }
175
+ case tail.endsWith("?>"):
176
+ {
177
+ const start = tail.lastIndexOf("<?");
178
+ if (start < 0) break epilog;
179
+ const raw = tail.slice(start + 2, -2);
180
+ const target = raw.match(/^\S+/)?.[0] ?? "";
181
+ instructions.unshift([
182
+ target,
183
+ raw.slice(target.length).trim()
184
+ ]);
185
+ tail = tail.slice(0, start).trimEnd();
186
+ continue;
187
+ }
188
+ default:
189
+ break epilog;
190
+ }
191
+ }
192
+ instructions.forEach(([target, raw])=>xml_instruction(xml, target, raw));
193
+ return content;
194
+ }
195
+ /** Walk a std DOM element into the ergonomic ~children/@attr/#text structure. */ function build(element, parent) {
196
+ // Attach under the enumerable key with array-grouping
197
+ const node = xml_element(element.name.raw, parent);
198
+ // Attributes
199
+ for (const [name, value] of Object.entries(element.attributes))node[`@${name}`] = value;
200
+ // Children
201
+ for (const child of element.children){
202
+ switch(child.type){
203
+ case "element":
204
+ build(child, node);
205
+ break;
206
+ case "text":
207
+ xml_text(child.text, {
208
+ type: "~text",
209
+ parent: node
210
+ });
211
+ break;
212
+ case "cdata":
213
+ xml_text(child.text, {
214
+ type: "~cdata",
215
+ parent: node
216
+ });
217
+ break;
218
+ case "comment":
219
+ xml_text(child.text, {
220
+ type: "~comment",
221
+ parent: node
222
+ });
223
+ break;
224
+ }
225
+ }
226
+ }
227
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImZpbGU6Ly8vaG9tZS9ydW5uZXIvd29yay9saWJzL2xpYnMvQGxpYnMveG1sL3BhcnNlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogUGFyc2UgYSBYTUwgc3RyaW5nIGludG8gYW4gb2JqZWN0LlxuICogQG1vZHVsZVxuICovXG5cbi8vIEltcG9ydHNcbmltcG9ydCB7IHBhcnNlIGFzIHN0ZF9wYXJzZSB9IGZyb20gXCJAc3RkL3htbC9wYXJzZVwiXG5pbXBvcnQgeyBwYXJzZVhtbFN0cmVhbUZyb21CeXRlcyB9IGZyb20gXCJAc3RkL3htbC9wYXJzZS1zdHJlYW1cIlxuaW1wb3J0IHR5cGUgeyBYbWxEb2N1bWVudCBhcyBTdGREb2N1bWVudCwgWG1sRWxlbWVudCBhcyBTdGRFbGVtZW50LCBYbWxOb2RlIGFzIFN0ZE5vZGUgfSBmcm9tIFwiQHN0ZC94bWwvdHlwZXNcIlxuaW1wb3J0IHsgdHlwZSBDbGVhbk9wdGlvbnMsIGZpbmFsaXplLCB0eXBlIEZsYXR0ZW5PcHRpb25zLCB0eXBlIFJldml2ZU9wdGlvbnMsIHhtbF9kb2N0eXBlLCB4bWxfZWxlbWVudCwgeG1sX2luc3RydWN0aW9uLCB4bWxfbm9kZSwgeG1sX3RleHQgfSBmcm9tIFwiLi9fcGFyc2VyLmpzXCJcbmltcG9ydCB0eXBlIHsgWG1sRG9jdW1lbnQsIFhtbE5vZGUgfSBmcm9tIFwiLi9fdHlwZXMuanNcIlxuZXhwb3J0IHR5cGUgKiBmcm9tIFwiLi9fdHlwZXMuanNcIlxuZXhwb3J0IHR5cGUgeyBDbGVhbk9wdGlvbnMsIEZsYXR0ZW5PcHRpb25zLCBSZXZpdmVPcHRpb25zLCBSZXZpdmVyIH0gZnJvbSBcIi4vX3BhcnNlci5qc1wiXG5cbi8qKiBYTUwgcGFyc2VyIG9wdGlvbnMuICovXG5leHBvcnQgdHlwZSBQYXJzZU9wdGlvbnMgPSB7XG4gIC8qKiBSZW1vdmUgZWxlbWVudHMgZnJvbSByZXN1bHQuICovXG4gIGNsZWFuPzogQ2xlYW5PcHRpb25zXG4gIC8qKiBGbGF0dGVuIHJlc3VsdCBkZXBlbmRpbmcgb24gbm9kZSBjb250ZW50LiAqL1xuICBmbGF0dGVuPzogRmxhdHRlbk9wdGlvbnNcbiAgLyoqIFJldml2ZSByZXN1bHQuICovXG4gIHJldml2ZT86IFJldml2ZU9wdGlvbnNcbiAgLyoqXG4gICAqIFBhcnNpbmcgbW9kZS5cbiAgICogVXNpbmcgYGh0bWxgIGlzIG1vcmUgcGVybWlzc2l2ZSBhbmQgd2lsbCBub3QgdGhyb3cgb24gc29tZSBpbnZhbGlkIFhNTCBzeW50YXguXG4gICAqIE1haW5seSB1bnF1b3RlZCBhdHRyaWJ1dGVzIHdpbGwgYmUgc3VwcG9ydGVkIGFuZCBub3QgcHJvcGVybHkgY2xvc2VkIHRhZ3Mgd2lsbCBiZSBhY2NlcHRlZC5cbiAgICpcbiAgICogPiBOb3RlOiBgaHRtbGAgbW9kZSBpcyBjdXJyZW50bHkgbm90IHN1cHBvcnRlZCwgdXNlIHRoZSBXQVNNIGJhY2tlbmQgKGBAbGlicy94bWwvd2FzbS9wYXJzZWApIGluc3RlYWQuXG4gICAqID4gVHJhY2tpbmcgaXNzdWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9kZW5vbGFuZC9zdGQvaXNzdWVzLzcyMTJcbiAgICovXG4gIG1vZGU/OiBcInhtbFwiXG59XG5cbi8qKlxuICogUGFyc2UgYSBYTUwgc3RyaW5nIGludG8gYW4gb2JqZWN0LlxuICpcbiAqIE91dHB1dCAoY2xlYW5pbmcsIGZsYXR0ZW5pbmcsIHJldml2aW5nLCBldGMuKSBjYW4gYmUgY3VzdG9taXplZCB1c2luZyB0aGUge0BsaW5rIFBhcnNlT3B0aW9uc30gcGFyYW1ldGVyLlxuICpcbiAqIFVubGVzcyBmbGF0dGVuZWQsIG91dHB1dCBub2RlcyB3aWxsIGNvbnRhaW4gdGhlIGZvbGxvd2luZyBub24tZW51bWVyYWJsZSBwcm9wZXJ0aWVzICh3aGljaCBtZWFuIHRoZXkncmUgbm90IFwidmlzaWJsZVwiIHdoZW4gaXRlcmF0aW5nIG92ZXIsIGJ1dCBhcmUgc3RpbGwgZXhwbGljaXRlbHkgYWNjZXNzaWJsZSk6XG4gKiAtIEdlbmVyYWwgcHJvcGVydGllc1xuICogICAtIGByZWFkb25seSBbXCJ+bmFtZVwiXTogc3RyaW5nYDogdGFnIG5hbWVcbiAqICAgLSBgcmVhZG9ubHkgW1wifnBhcmVudFwiXTogTnVsbGFibGU8WG1sTm9kZT5gOiBwYXJlbnQgbm9kZVxuICogICAtIGBbXCIjdGV4dFwiXT86IHN0cmluZ2A6IHRleHQgY29udGVudFxuICogLSBOb2RlIHByb3BlcnRpZXNcbiAqICAgLSBgcmVhZG9ubHkgW1wifmNoaWxkcmVuXCJdOiBBcnJheTxYbWxOb2RlfFhtbFRleHQ+YDogbm9kZSBjaGlsZHJlblxuICogICAtIGByZWFkb25seSBbXCIjY29tbWVudHNcIl0/OiBBcnJheTxzdHJpbmc+YDogbm9kZSBjb21tZW50c1xuICogICAtIGByZWFkb25seSBbXCIjdGV4dFwiXT86IHN0cmluZ2A6IGNvbmNhdGVuYXRlZCBjaGlsZHJlbiB0ZXh0IGNvbnRlbnQsIHRoaXMgcHJvcGVydHkgYmVjb21lcyBlbnVtZXJhYmxlIGlmIGF0IGxlYXN0IG9uZSBub24tZW1wdHkgdGV4dCBub2RlIGlzIHByZXNlbnRcbiAqIC0gWE1MIGRvY3VtZW50IHByb3BlcnRpZXNcbiAqICAtIGBbXCIjZG9jdHlwZVwiXT86IFhtbE5vZGVgOiBYTUwgZG9jdHlwZVxuICogIC0gYFtcIiNpbnN0cnVjdGlvbnNcIl0/OiB7IFtrZXk6c3RyaW5nXTogQXJyYXlhYmxlPFhtbE5vZGU+IH1gOiBYTUwgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnNcbiAqXG4gKiBBdHRyaWJ1dGVzIGFyZSBwcmVmaXhlZCB3aXRoIGFuIGFyb2Jhc2UgKGBAYCkuXG4gKlxuICogYGBgdHNcbiAqIGNvbnNvbGUubG9nKHBhcnNlKFxuICogYFxuICogICA8cm9vdD5cbiAqICAgICA8IS0tIFRoaXMgaXMgYSBjb21tZW50IC0tPlxuICogICAgIDx0ZXh0PmhlbGxvPC90ZXh0PlxuICogICAgIDxhcnJheT53b3JsZDwvYXJyYXk+XG4gKiAgICAgPGFycmF5Pm1vbmRlPC9hcnJheT5cbiAqICAgICA8YXJyYXk+5LiW55WMPC9hcnJheT5cbiAqICAgICA8YXJyYXk+8J+MjzwvYXJyYXk+XG4gKiAgICAgPG51bWJlcj40MjwvbnVtYmVyPlxuICogICAgIDxib29sZWFuPnRydWU8L2Jvb2xlYW4+XG4gKiAgICAgPGNvbXBsZXggYXR0cmlidXRlPVwidmFsdWVcIj5jb250ZW50PC9jb21wbGV4PlxuICogICA8L3Jvb3Q+XG4gKiBgKSlcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2UoY29udGVudDogc3RyaW5nLCBvcHRpb25zPzogUGFyc2VPcHRpb25zKTogWG1sRG9jdW1lbnRcblxuLyoqXG4gKiBQYXJzZSBhIFhNTCBzdHJpbmcgaW50byBhbiBvYmplY3QuXG4gKlxuICogT3V0cHV0IChjbGVhbmluZywgZmxhdHRlbmluZywgcmV2aXZpbmcsIGV0Yy4pIGNhbiBiZSBjdXN0b21pemVkIHVzaW5nIHRoZSB7QGxpbmsgUGFyc2VPcHRpb25zfSBwYXJhbWV0ZXIuXG4gKlxuICogVW5sZXNzIGZsYXR0ZW5lZCwgb3V0cHV0IG5vZGVzIHdpbGwgY29udGFpbiB0aGUgZm9sbG93aW5nIG5vbi1lbnVtZXJhYmxlIHByb3BlcnRpZXMgKHdoaWNoIG1lYW4gdGhleSdyZSBub3QgXCJ2aXNpYmxlXCIgd2hlbiBpdGVyYXRpbmcgb3ZlciwgYnV0IGFyZSBzdGlsbCBleHBsaWNpdGVseSBhY2Nlc3NpYmxlKTpcbiAqIC0gR2VuZXJhbCBwcm9wZXJ0aWVzXG4gKiAgIC0gYHJlYWRvbmx5IFtcIn5uYW1lXCJdOiBzdHJpbmdgOiB0YWcgbmFtZVxuICogICAtIGByZWFkb25seSBbXCJ+cGFyZW50XCJdOiBOdWxsYWJsZTxYbWxOb2RlPmA6IHBhcmVudCBub2RlXG4gKiAgIC0gYFtcIiN0ZXh0XCJdPzogc3RyaW5nYDogdGV4dCBjb250ZW50XG4gKiAtIE5vZGUgcHJvcGVydGllc1xuICogICAtIGByZWFkb25seSBbXCJ+Y2hpbGRyZW5cIl06IEFycmF5PFhtbE5vZGV8WG1sVGV4dD5gOiBub2RlIGNoaWxkcmVuXG4gKiAgIC0gYHJlYWRvbmx5IFtcIiNjb21tZW50c1wiXT86IEFycmF5PHN0cmluZz5gOiBub2RlIGNvbW1lbnRzXG4gKiAgIC0gYHJlYWRvbmx5IFtcIiN0ZXh0XCJdPzogc3RyaW5nYDogY29uY2F0ZW5hdGVkIGNoaWxkcmVuIHRleHQgY29udGVudCwgdGhpcyBwcm9wZXJ0eSBiZWNvbWVzIGVudW1lcmFibGUgaWYgYXQgbGVhc3Qgb25lIG5vbi1lbXB0eSB0ZXh0IG5vZGUgaXMgcHJlc2VudFxuICogLSBYTUwgZG9jdW1lbnQgcHJvcGVydGllc1xuICogIC0gYFtcIiNkb2N0eXBlXCJdPzogWG1sTm9kZWA6IFhNTCBkb2N0eXBlXG4gKiAgLSBgW1wiI2luc3RydWN0aW9uc1wiXT86IHsgW2tleTpzdHJpbmddOiBBcnJheWFibGU8WG1sTm9kZT4gfWA6IFhNTCBwcm9jZXNzaW5nIGluc3RydWN0aW9uc1xuICpcbiAqIEF0dHJpYnV0ZXMgYXJlIHByZWZpeGVkIHdpdGggYW4gYXJvYmFzZSAoYEBgKS5cbiAqXG4gKiBgYGB0c1xuICogaW1wb3J0IHsgZnJvbUZpbGVVcmwgfSBmcm9tIFwiQHN0ZC9wYXRoXCJcbiAqXG4gKiBjb25zdCBmaWxlID0gYXdhaXQgRGVuby5vcGVuKGZyb21GaWxlVXJsKGltcG9ydC5tZXRhLnJlc29sdmUoXCIuL2JlbmNoL2Fzc2V0cy9zbWFsbC54bWxcIikpKVxuICogY29uc29sZS5sb2coYXdhaXQgcGFyc2UoZmlsZS5yZWFkYWJsZSkpXG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBhcnNlKGNvbnRlbnQ6IFJlYWRhYmxlU3RyZWFtPFVpbnQ4QXJyYXk+LCBvcHRpb25zPzogUGFyc2VPcHRpb25zKTogUHJvbWlzZTxYbWxEb2N1bWVudD5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZShjb250ZW50OiBzdHJpbmcgfCBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5Piwgb3B0aW9ucz86IFBhcnNlT3B0aW9ucyk6IFhtbERvY3VtZW50IHwgUHJvbWlzZTxYbWxEb2N1bWVudD4ge1xuICBpZiAodHlwZW9mIGNvbnRlbnQgIT09IFwic3RyaW5nXCIpXG4gICAgcmV0dXJuIHBhcnNlX3N0cmVhbShjb250ZW50LCBvcHRpb25zKVxuICBjb25zdCB4bWwgPSB4bWxfbm9kZShcIn54bWxcIikgYXMgWG1sRG9jdW1lbnRcbiAgY29udGVudCA9IGNvbnRlbnQucmVwbGFjZSgvXlxccysvLCBcIlwiKVxuICAvLyBAc3RkIHN5bmMgcGFyc2VyIG9ubHkgZXhwb3NlcyBhIERPTSB0cmVlIG9mIHtkZWNsYXJhdGlvbiwgcm9vdH1cbiAgLy8gYW5kIGlzIG1pc3NpbmcgRE9DVFlQRSBhbmQgcHJvY2Vzc2luZyBpbnN0cnVjdGlvbnMgKHRoZXkgYXJlIGRpc2NhcmRlZClcbiAgLy8gUHJlc2NhbiB0aGUgY29udGVudCB0byByZWNvdmVyIHRoZW0gZmlyc3RcbiAgY29udGVudCA9IHByZXNjYW4oY29udGVudCwgeG1sKVxuICBjb25zdCBkb2M6IFN0ZERvY3VtZW50ID0gc3RkX3BhcnNlKGNvbnRlbnQsIHsgZGlzYWxsb3dEb2N0eXBlOiBmYWxzZSB9KVxuXG4gIC8vIFhNTCBkZWNsYXJhdGlvblxuICBpZiAoZG9jLmRlY2xhcmF0aW9uKSB7XG4gICAgaWYgKGRvYy5kZWNsYXJhdGlvbi52ZXJzaW9uKVxuICAgICAgeG1sW1wiQHZlcnNpb25cIl0gPSBkb2MuZGVjbGFyYXRpb24udmVyc2lvbiBhcyB0eXBlb2YgeG1sW1wiQHZlcnNpb25cIl1cbiAgICBpZiAoZG9jLmRlY2xhcmF0aW9uLmVuY29kaW5nKVxuICAgICAgeG1sW1wiQGVuY29kaW5nXCJdID0gZG9jLmRlY2xhcmF0aW9uLmVuY29kaW5nXG4gICAgaWYgKGRvYy5kZWNsYXJhdGlvbi5zdGFuZGFsb25lKVxuICAgICAgeG1sW1wiQHN0YW5kYWxvbmVcIl0gPSBkb2MuZGVjbGFyYXRpb24uc3RhbmRhbG9uZVxuICB9XG5cbiAgYnVpbGQoZG9jLnJvb3QsIHhtbClcblxuICByZXR1cm4gZmluYWxpemUoeG1sLCBvcHRpb25zKVxufVxuXG4vKipcbiAqIFBhcnNlIGEgWE1MIHN0cmVhbSBpbnRvIGFuIG9iamVjdC5cbiAqIEBzdGQgc3RyZWFtaW5nIHBhcnNlciBldmVudHMgYXJlIG1hcHBlZCB0byB0aGUgc2FtZSBkb2N1bWVudCBzdHJ1Y3R1cmUgYXMgdGhlIHN0cmluZyB2ZXJzaW9uLFxuICogYW5kIHVubGlrZSB0aGUgc3luYyBET00gdGhleSBuYXRpdmVseSBleHBvc2UgdGhlIGRvY3R5cGUgYW5kIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb25zLlxuICovXG5hc3luYyBmdW5jdGlvbiBwYXJzZV9zdHJlYW0oY29udGVudDogUmVhZGFibGVTdHJlYW08VWludDhBcnJheT4sIG9wdGlvbnM/OiBQYXJzZU9wdGlvbnMpOiBQcm9taXNlPFhtbERvY3VtZW50PiB7XG4gIGNvbnN0IHhtbCA9IHhtbF9ub2RlKFwifnhtbFwiKSBhcyBYbWxEb2N1bWVudFxuICBjb25zdCBzdGFjayA9IFt4bWxdIGFzIEFycmF5PFhtbE5vZGU+XG4gIGF3YWl0IHBhcnNlWG1sU3RyZWFtRnJvbUJ5dGVzKGNvbnRlbnQsIHtcbiAgICAvLyBYTUwgZGVjbGFyYXRpb25cbiAgICBvbkRlY2xhcmF0aW9uKHZlcnNpb24sIGVuY29kaW5nLCBzdGFuZGFsb25lKSB7XG4gICAgICBpZiAodmVyc2lvbilcbiAgICAgICAgeG1sW1wiQHZlcnNpb25cIl0gPSB2ZXJzaW9uIGFzIFhtbERvY3VtZW50W1wiQHZlcnNpb25cIl1cbiAgICAgIGlmIChlbmNvZGluZylcbiAgICAgICAgeG1sW1wiQGVuY29kaW5nXCJdID0gZW5jb2RpbmdcbiAgICAgIGlmIChzdGFuZGFsb25lKVxuICAgICAgICB4bWxbXCJAc3RhbmRhbG9uZVwiXSA9IHN0YW5kYWxvbmVcbiAgICB9LFxuICAgIC8vIFhNTCBkb2N0eXBlIChvbmx5IHRoZSBuYW1lIGFuZCBwdWJsaWMvc3lzdGVtIGlkZW50aWZpZXJzIGFyZSBleHBvc2VkIGJ5IEBzdGQgZXZlbnRzKVxuICAgIG9uRG9jdHlwZShuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpIHtcbiAgICAgIGNvbnN0IGRvY3R5cGUgPSB4bWxfbm9kZShcIn5kb2N0eXBlXCIsIHsgcGFyZW50OiB4bWwgfSlcbiAgICAgIDtbbmFtZSwgcHVibGljSWQsIHN5c3RlbUlkXS5maWx0ZXIoKHZhbHVlKSA9PiB2YWx1ZSAhPT0gdW5kZWZpbmVkKS5mb3JFYWNoKCh2YWx1ZSkgPT4gZG9jdHlwZVtgQCR7dmFsdWV9YF0gPSBcIlwiKVxuICAgICAgeG1sW1wiI2RvY3R5cGVcIl0gPSBkb2N0eXBlXG4gICAgfSxcbiAgICAvLyBYTUwgcHJvY2Vzc2luZyBpbnN0cnVjdGlvblxuICAgIG9uUHJvY2Vzc2luZ0luc3RydWN0aW9uKHRhcmdldCwgaW5zdHJ1Y3Rpb24pIHtcbiAgICAgIHhtbF9pbnN0cnVjdGlvbih4bWwsIHRhcmdldCwgaW5zdHJ1Y3Rpb24udHJpbSgpKVxuICAgIH0sXG4gICAgLy8gWE1MIHRhZyBvcGVuZWRcbiAgICBvblN0YXJ0RWxlbWVudChuYW1lLCBfY29sb24sIF91cmksIGF0dHJpYnV0ZXMsIHNlbGZDbG9zaW5nKSB7XG4gICAgICBjb25zdCBub2RlID0geG1sX2VsZW1lbnQobmFtZSwgc3RhY2suYXQoLTEpISlcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0cmlidXRlcy5jb3VudDsgaSsrKVxuICAgICAgICBub2RlW2BAJHthdHRyaWJ1dGVzLmdldE5hbWUoaSl9YF0gPSBhdHRyaWJ1dGVzLmdldFZhbHVlKGkpXG4gICAgICBpZiAoIXNlbGZDbG9zaW5nKVxuICAgICAgICBzdGFjay5wdXNoKG5vZGUpXG4gICAgfSxcbiAgICAvLyBYTUwgdGFnIGNsb3NlZFxuICAgIG9uRW5kRWxlbWVudCgpIHtcbiAgICAgIHN0YWNrLnBvcCgpXG4gICAgfSxcbiAgICAvLyBUZXh0XG4gICAgb25UZXh0KHRleHQpIHtcbiAgICAgIHhtbF90ZXh0KHRleHQsIHsgdHlwZTogXCJ+dGV4dFwiLCBwYXJlbnQ6IHN0YWNrLmF0KC0xKSEgfSlcbiAgICB9LFxuICAgIC8vIENEQVRBXG4gICAgb25DRGF0YSh0ZXh0KSB7XG4gICAgICB4bWxfdGV4dCh0ZXh0LCB7IHR5cGU6IFwifmNkYXRhXCIsIHBhcmVudDogc3RhY2suYXQoLTEpISB9KVxuICAgIH0sXG4gICAgLy8gQ29tbWVudFxuICAgIG9uQ29tbWVudCh0ZXh0KSB7XG4gICAgICB4bWxfdGV4dCh0ZXh0LCB7IHR5cGU6IFwifmNvbW1lbnRcIiwgcGFyZW50OiBzdGFjay5hdCgtMSkhIH0pXG4gICAgfSxcbiAgfSwgeyBkaXNhbGxvd0RvY3R5cGU6IGZhbHNlIH0pXG4gIHJldHVybiBmaW5hbGl6ZSh4bWwsIG9wdGlvbnMpXG59XG5cbi8qKiBSZWNvdmVyIGAjZG9jdHlwZWAgYW5kIGAjaW5zdHJ1Y3Rpb25zYC4gKi9cbmZ1bmN0aW9uIHByZXNjYW4oY29udGVudDogc3RyaW5nLCB4bWw6IFhtbERvY3VtZW50KTogc3RyaW5nIHtcbiAgLy8gUHJvbG9nOiBza2lwIHdoaXRlc3BhY2UvY29tbWVudHMsIGNvbGxlY3QgaW5zdHJ1Y3Rpb25zIGFuZCBkb2N0eXBlIHVudGlsIHRoZSByb290IGVsZW1lbnQgb3BlbnNcbiAgbGV0IGkgPSAwXG4gIHByb2xvZzogd2hpbGUgKGkgPCBjb250ZW50Lmxlbmd0aCkge1xuICAgIHN3aXRjaCAodHJ1ZSkge1xuICAgICAgY2FzZSAvXFxzLy50ZXN0KGNvbnRlbnRbaV0pOiB7XG4gICAgICAgIGkrK1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuICAgICAgY2FzZSBjb250ZW50LnN0YXJ0c1dpdGgoXCI8IS0tXCIsIGkpOiB7XG4gICAgICAgIGNvbnN0IGVuZCA9IGNvbnRlbnQuaW5kZXhPZihcIi0tPlwiLCBpICsgNClcbiAgICAgICAgaWYgKGVuZCA8IDApXG4gICAgICAgICAgYnJlYWsgcHJvbG9nXG4gICAgICAgIGkgPSBlbmQgKyAzXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBjYXNlIGNvbnRlbnQuc3RhcnRzV2l0aChcIjw/XCIsIGkpOiB7XG4gICAgICAgIGNvbnN0IGVuZCA9IGNvbnRlbnQuaW5kZXhPZihcIj8+XCIsIGkgKyAyKVxuICAgICAgICBpZiAoZW5kIDwgMClcbiAgICAgICAgICBicmVhayBwcm9sb2dcbiAgICAgICAgY29uc3QgcmF3ID0gY29udGVudC5zbGljZShpICsgMiwgZW5kKVxuICAgICAgICBpID0gZW5kICsgMlxuICAgICAgICBjb25zdCB0YXJnZXQgPSByYXcubWF0Y2goL15cXFMrLyk/LlswXSA/PyBcIlwiXG4gICAgICAgIC8vIFRoZSA8P3htbD8+IGRlY2xhcmF0aW9uIGlzIGFscmVhZHkgaGFuZGxlZCB0aHJvdWdoIHN0ZCdzIERPTVxuICAgICAgICBpZiAodGFyZ2V0ICE9PSBcInhtbFwiKVxuICAgICAgICAgIHhtbF9pbnN0cnVjdGlvbih4bWwsIHRhcmdldCwgcmF3LnNsaWNlKHRhcmdldC5sZW5ndGgpLnRyaW0oKSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGNhc2UgY29udGVudC5zdGFydHNXaXRoKFwiPCFET0NUWVBFXCIsIGkpOiB7XG4gICAgICAgIC8vIEZpbmQgdGhlIGNsb3NpbmcgXCI+XCIsIHNraXBwaW5nIHF1b3RlZCBsaXRlcmFscyBhbmQgdGhlIGludGVybmFsIHN1YnNldCBcIlsuLi5dXCJcbiAgICAgICAgbGV0IGogPSBpICsgOVxuICAgICAgICBkb2N0eXBlOiB3aGlsZSAoaiA8IGNvbnRlbnQubGVuZ3RoKSB7XG4gICAgICAgICAgc3dpdGNoIChjb250ZW50W2pdKSB7XG4gICAgICAgICAgICBjYXNlICdcIic6XG4gICAgICAgICAgICBjYXNlIFwiJ1wiOiB7XG4gICAgICAgICAgICAgIGNvbnN0IHF1b3RlID0gY29udGVudC5pbmRleE9mKGNvbnRlbnRbal0sIGogKyAxKVxuICAgICAgICAgICAgICBpZiAocXVvdGUgPCAwKVxuICAgICAgICAgICAgICAgIGJyZWFrIGRvY3R5cGVcbiAgICAgICAgICAgICAgaiA9IHF1b3RlICsgMVxuICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FzZSBcIltcIjoge1xuICAgICAgICAgICAgICBjb25zdCBicmFja2V0ID0gY29udGVudC5pbmRleE9mKFwiXVwiLCBqICsgMSlcbiAgICAgICAgICAgICAgaWYgKGJyYWNrZXQgPCAwKVxuICAgICAgICAgICAgICAgIGJyZWFrIGRvY3R5cGVcbiAgICAgICAgICAgICAgaiA9IGJyYWNrZXQgKyAxXG4gICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjYXNlIFwiPlwiOlxuICAgICAgICAgICAgICBicmVhayBkb2N0eXBlXG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICBqKytcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgeG1sW1wiI2RvY3R5cGVcIl0gPSBPYmplY3QuYXNzaWduKHhtbF9ub2RlKFwifmRvY3R5cGVcIiwgeyBwYXJlbnQ6IHhtbCB9KSwgeG1sX2RvY3R5cGUoY29udGVudC5zbGljZShpICsgOSwgaikudHJpbSgpKSlcbiAgICAgICAgY29uc3QgZW5kID0gTWF0aC5taW4oaiArIDEsIGNvbnRlbnQubGVuZ3RoKVxuICAgICAgICBjb250ZW50ID0gYCR7Y29udGVudC5zbGljZSgwLCBpKX0ke1wiIFwiLnJlcGVhdChlbmQgLSBpKX0ke2NvbnRlbnQuc2xpY2UoZW5kKX1gXG4gICAgICAgIGkgPSBlbmRcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrIHByb2xvZ1xuICAgIH1cbiAgfVxuICAvLyBFcGlsb2c6IG9ubHkgY29tbWVudHMgYW5kIGluc3RydWN0aW9ucyBtYXkgZm9sbG93IHRoZSByb290IGVsZW1lbnQsIHNjYW4gdGhlbSBiYWNrd2FyZHNcbiAgY29uc3QgaW5zdHJ1Y3Rpb25zID0gW10gYXMgQXJyYXk8W3N0cmluZywgc3RyaW5nXT5cbiAgbGV0IHRhaWwgPSBjb250ZW50LnRyaW1FbmQoKVxuICBlcGlsb2c6IHdoaWxlICh0cnVlKSB7XG4gICAgc3dpdGNoICh0cnVlKSB7XG4gICAgICBjYXNlIHRhaWwuZW5kc1dpdGgoXCItLT5cIik6IHtcbiAgICAgICAgY29uc3Qgc3RhcnQgPSB0YWlsLmxhc3RJbmRleE9mKFwiPCEtLVwiKVxuICAgICAgICBpZiAoc3RhcnQgPCAwKVxuICAgICAgICAgIGJyZWFrIGVwaWxvZ1xuICAgICAgICB0YWlsID0gdGFpbC5zbGljZSgwLCBzdGFydCkudHJpbUVuZCgpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG4gICAgICBjYXNlIHRhaWwuZW5kc1dpdGgoXCI/PlwiKToge1xuICAgICAgICBjb25zdCBzdGFydCA9IHRhaWwubGFzdEluZGV4T2YoXCI8P1wiKVxuICAgICAgICBpZiAoc3RhcnQgPCAwKVxuICAgICAgICAgIGJyZWFrIGVwaWxvZ1xuICAgICAgICBjb25zdCByYXcgPSB0YWlsLnNsaWNlKHN0YXJ0ICsgMiwgLTIpXG4gICAgICAgIGNvbnN0IHRhcmdldCA9IHJhdy5tYXRjaCgvXlxcUysvKT8uWzBdID8/IFwiXCJcbiAgICAgICAgaW5zdHJ1Y3Rpb25zLnVuc2hpZnQoW3RhcmdldCwgcmF3LnNsaWNlKHRhcmdldC5sZW5ndGgpLnRyaW0oKV0pXG4gICAgICAgIHRhaWwgPSB0YWlsLnNsaWNlKDAsIHN0YXJ0KS50cmltRW5kKClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrIGVwaWxvZ1xuICAgIH1cbiAgfVxuICBpbnN0cnVjdGlvbnMuZm9yRWFjaCgoW3RhcmdldCwgcmF3XSkgPT4geG1sX2luc3RydWN0aW9uKHhtbCwgdGFyZ2V0LCByYXcpKVxuICByZXR1cm4gY29udGVudFxufVxuXG4vKiogV2FsayBhIHN0ZCBET00gZWxlbWVudCBpbnRvIHRoZSBlcmdvbm9taWMgfmNoaWxkcmVuL0BhdHRyLyN0ZXh0IHN0cnVjdHVyZS4gKi9cbmZ1bmN0aW9uIGJ1aWxkKGVsZW1lbnQ6IFN0ZEVsZW1lbnQsIHBhcmVudDogWG1sTm9kZSk6IHZvaWQge1xuICAvLyBBdHRhY2ggdW5kZXIgdGhlIGVudW1lcmFibGUga2V5IHdpdGggYXJyYXktZ3JvdXBpbmdcbiAgY29uc3Qgbm9kZSA9IHhtbF9lbGVtZW50KGVsZW1lbnQubmFtZS5yYXcsIHBhcmVudClcbiAgLy8gQXR0cmlidXRlc1xuICBmb3IgKGNvbnN0IFtuYW1lLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoZWxlbWVudC5hdHRyaWJ1dGVzKSlcbiAgICBub2RlW2BAJHtuYW1lfWBdID0gdmFsdWVcbiAgLy8gQ2hpbGRyZW5cbiAgZm9yIChjb25zdCBjaGlsZCBvZiBlbGVtZW50LmNoaWxkcmVuIGFzIFJlYWRvbmx5QXJyYXk8U3RkTm9kZT4pIHtcbiAgICBzd2l0Y2ggKGNoaWxkLnR5cGUpIHtcbiAgICAgIGNhc2UgXCJlbGVtZW50XCI6XG4gICAgICAgIGJ1aWxkKGNoaWxkLCBub2RlKVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSBcInRleHRcIjpcbiAgICAgICAgeG1sX3RleHQoY2hpbGQudGV4dCwgeyB0eXBlOiBcIn50ZXh0XCIsIHBhcmVudDogbm9kZSB9KVxuICAgICAgICBicmVha1xuICAgICAgY2FzZSBcImNkYXRhXCI6XG4gICAgICAgIHhtbF90ZXh0KGNoaWxkLnRleHQsIHsgdHlwZTogXCJ+Y2RhdGFcIiwgcGFyZW50OiBub2RlIH0pXG4gICAgICAgIGJyZWFrXG4gICAgICBjYXNlIFwiY29tbWVudFwiOlxuICAgICAgICB4bWxfdGV4dChjaGlsZC50ZXh0LCB7IHR5cGU6IFwifmNvbW1lbnRcIiwgcGFyZW50OiBub2RlIH0pXG4gICAgICAgIGJyZWFrXG4gICAgfVxuICB9XG59XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7OztDQUdDLEdBRUQsVUFBVTtBQUNWLFNBQVMsU0FBUyxTQUFTLFFBQVEsaUJBQWdCO0FBQ25ELFNBQVMsdUJBQXVCLFFBQVEsd0JBQXVCO0FBRS9ELFNBQTRC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
package/stringify.d.ts ADDED
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Stringify an XML document object into a XML string.
3
+ * @module
4
+ */ import type { Nullable, Stringifyable, XmlNode, XmlText } from "./_types.js";
5
+ export type * from "./_types.js";
6
+ /** XML stringifier options. */ export type StringifyOptions = {
7
+ /** Format options. */ format?: FormatOptions;
8
+ /** Replace options. */ replace?: ReplaceOptions;
9
+ };
10
+ /** XML stringifier {@linkcode StringifyOptions}`.format` */ export type FormatOptions = {
11
+ /**
12
+ * Indent string (defaults to `" "`).
13
+ * Set to empty string to disable indentation and enable minification.
14
+ */ indent?: string;
15
+ /** Break text node if its length is greater than this value (defaults to `128`). */ breakline?: number;
16
+ };
17
+ /** XML stringifier {@linkcode StringifyOptions}`.replace` */ export type ReplaceOptions = {
18
+ /**
19
+ * Force escape all XML entities.
20
+ * By default, only the ones that would break the XML structure are escaped.
21
+ */ entities?: boolean;
22
+ /**
23
+ * Custom replacer (this is applied after other revivals).
24
+ * When it is applied on an attribute, `key` and `value` will be given.
25
+ * When it is applied on a node, both `key` and `value` will be `null`.
26
+ * Return `undefined` to delete either the attribute or the tag.
27
+ */ custom?: Replacer;
28
+ };
29
+ /**
30
+ * Custom XML stringifier replacer.
31
+ * It can be used to change the way some nodes are stringified.
32
+ */ export type Replacer = (args: {
33
+ name: string;
34
+ key: Nullable<string>;
35
+ value: Nullable<string>;
36
+ node: Readonly<XmlNode>;
37
+ }) => unknown;
38
+ /**
39
+ * Stringify an {@link XmlDocument} object into a XML string.
40
+ *
41
+ * Output can be customized using the {@link options} parameter.
42
+ *
43
+ * ```ts
44
+ * import { stringify } from "./stringify.ts"
45
+ *
46
+ * console.log(stringify({
47
+ * "@version": "1.0",
48
+ * "@standalone": "yes",
49
+ * root: {
50
+ * text: "hello",
51
+ * array: ["world", "monde", "世界", "🌏"],
52
+ * number: 42,
53
+ * boolean: true,
54
+ * complex: {
55
+ * "@attribute": "value",
56
+ * "#text": "content",
57
+ * },
58
+ * }
59
+ * }))
60
+ * ```
61
+ */ export declare function stringify(document: Stringifyable, options?: StringifyOptions): string;
62
+ /**
63
+ * Helper to create a CDATA node.
64
+ *
65
+ * ```ts
66
+ * import { stringify, cdata } from "./stringify.ts"
67
+ * stringify({ string: cdata(`hello <world>`) })
68
+ * // <string><![CDATA[hello <world>]]></string>
69
+ * ```
70
+ */ export declare function cdata(text: string): Omit<XmlText, "~parent">;
71
+ /**
72
+ * Helper to create a comment node.
73
+ *
74
+ * ```ts
75
+ * import { stringify, comment } from "./stringify.ts"
76
+ * stringify({ string: comment(`hello world`) })
77
+ * // <string><!--hello world--></string>
78
+ * ```
79
+ */ export declare function comment(text: string): Omit<XmlText, "~parent">;