@omujs/omu 0.9.42 → 0.9.47

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.
Files changed (154) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/package.json +1 -1
  3. package/src/api/dashboard/extension.ts +42 -42
  4. package/src/api/dashboard/handler.ts +1 -1
  5. package/src/api/registry/extension.ts +109 -23
  6. package/src/network/network.ts +5 -0
  7. package/src/omu.ts +1 -0
  8. package/src/serialize/bytebuffer.ts +8 -0
  9. package/src/version.ts +1 -1
  10. package/dist/dts/address.d.ts +0 -6
  11. package/dist/dts/api/asset/extension.d.ts +0 -25
  12. package/dist/dts/api/asset/index.d.ts +0 -2
  13. package/dist/dts/api/dashboard/extension.d.ts +0 -181
  14. package/dist/dts/api/dashboard/handler.d.ts +0 -22
  15. package/dist/dts/api/dashboard/index.d.ts +0 -3
  16. package/dist/dts/api/dashboard/packets.d.ts +0 -73
  17. package/dist/dts/api/endpoint/endpoint.d.ts +0 -32
  18. package/dist/dts/api/endpoint/extension.d.ts +0 -23
  19. package/dist/dts/api/endpoint/index.d.ts +0 -2
  20. package/dist/dts/api/endpoint/packets.d.ts +0 -51
  21. package/dist/dts/api/extension-registry.d.ts +0 -8
  22. package/dist/dts/api/extension.d.ts +0 -11
  23. package/dist/dts/api/http/extension.d.ts +0 -41
  24. package/dist/dts/api/http/http.d.ts +0 -36
  25. package/dist/dts/api/http/index.d.ts +0 -2
  26. package/dist/dts/api/http/websocket.d.ts +0 -123
  27. package/dist/dts/api/i18n/extension.d.ts +0 -19
  28. package/dist/dts/api/i18n/index.d.ts +0 -1
  29. package/dist/dts/api/index.d.ts +0 -2
  30. package/dist/dts/api/logger/extension.d.ts +0 -25
  31. package/dist/dts/api/logger/index.d.ts +0 -1
  32. package/dist/dts/api/logger/packets.d.ts +0 -18
  33. package/dist/dts/api/permission/extension.d.ts +0 -19
  34. package/dist/dts/api/permission/index.d.ts +0 -1
  35. package/dist/dts/api/permission/permission.d.ts +0 -25
  36. package/dist/dts/api/plugin/extension.d.ts +0 -43
  37. package/dist/dts/api/plugin/index.d.ts +0 -2
  38. package/dist/dts/api/plugin/package-info.d.ts +0 -84
  39. package/dist/dts/api/registry/extension.d.ts +0 -26
  40. package/dist/dts/api/registry/index.d.ts +0 -2
  41. package/dist/dts/api/registry/packets.d.ts +0 -20
  42. package/dist/dts/api/registry/registry.d.ts +0 -57
  43. package/dist/dts/api/server/extension.d.ts +0 -61
  44. package/dist/dts/api/server/index.d.ts +0 -1
  45. package/dist/dts/api/session/extension.d.ts +0 -52
  46. package/dist/dts/api/session/index.d.ts +0 -1
  47. package/dist/dts/api/signal/extension.d.ts +0 -22
  48. package/dist/dts/api/signal/index.d.ts +0 -1
  49. package/dist/dts/api/signal/packets.d.ts +0 -21
  50. package/dist/dts/api/signal/signal.d.ts +0 -33
  51. package/dist/dts/api/table/extension.d.ts +0 -29
  52. package/dist/dts/api/table/index.d.ts +0 -2
  53. package/dist/dts/api/table/packets.d.ts +0 -65
  54. package/dist/dts/api/table/table.d.ts +0 -76
  55. package/dist/dts/app.d.ts +0 -49
  56. package/dist/dts/const.d.ts +0 -2
  57. package/dist/dts/errors.d.ts +0 -36
  58. package/dist/dts/event/index.d.ts +0 -6
  59. package/dist/dts/helper.d.ts +0 -13
  60. package/dist/dts/identifier.d.ts +0 -51
  61. package/dist/dts/index.d.ts +0 -36
  62. package/dist/dts/localization/index.d.ts +0 -2
  63. package/dist/dts/localization/locale.d.ts +0 -735
  64. package/dist/dts/localization/localization.d.ts +0 -5
  65. package/dist/dts/lock.d.ts +0 -6
  66. package/dist/dts/network/connection.d.ts +0 -17
  67. package/dist/dts/network/encryption.d.ts +0 -38
  68. package/dist/dts/network/frame-transport.d.ts +0 -22
  69. package/dist/dts/network/index.d.ts +0 -5
  70. package/dist/dts/network/network.d.ts +0 -58
  71. package/dist/dts/network/packet/index.d.ts +0 -2
  72. package/dist/dts/network/packet/packet-types.d.ts +0 -84
  73. package/dist/dts/network/packet/packet.d.ts +0 -28
  74. package/dist/dts/network/websocket-transport.d.ts +0 -24
  75. package/dist/dts/omu.d.ts +0 -61
  76. package/dist/dts/result.d.ts +0 -41
  77. package/dist/dts/serialize/bytebuffer.d.ts +0 -71
  78. package/dist/dts/serialize/index.d.ts +0 -2
  79. package/dist/dts/serialize/serializer.d.ts +0 -38
  80. package/dist/dts/token.d.ts +0 -14
  81. package/dist/dts/version.d.ts +0 -2
  82. package/dist/esm/address.js +0 -4
  83. package/dist/esm/api/asset/extension.js +0 -905
  84. package/dist/esm/api/asset/index.js +0 -903
  85. package/dist/esm/api/dashboard/extension.js +0 -1355
  86. package/dist/esm/api/dashboard/handler.js +0 -4
  87. package/dist/esm/api/dashboard/index.js +0 -1354
  88. package/dist/esm/api/dashboard/packets.js +0 -413
  89. package/dist/esm/api/endpoint/endpoint.js +0 -383
  90. package/dist/esm/api/endpoint/extension.js +0 -1090
  91. package/dist/esm/api/endpoint/index.js +0 -383
  92. package/dist/esm/api/endpoint/packets.js +0 -793
  93. package/dist/esm/api/extension-registry.js +0 -23
  94. package/dist/esm/api/extension.js +0 -278
  95. package/dist/esm/api/http/extension.js +0 -1414
  96. package/dist/esm/api/http/http.js +0 -442
  97. package/dist/esm/api/http/index.js +0 -1413
  98. package/dist/esm/api/http/websocket.js +0 -220
  99. package/dist/esm/api/i18n/extension.js +0 -1270
  100. package/dist/esm/api/i18n/index.js +0 -1268
  101. package/dist/esm/api/index.js +0 -295
  102. package/dist/esm/api/logger/extension.js +0 -850
  103. package/dist/esm/api/logger/index.js +0 -846
  104. package/dist/esm/api/logger/packets.js +0 -667
  105. package/dist/esm/api/permission/extension.js +0 -535
  106. package/dist/esm/api/permission/index.js +0 -294
  107. package/dist/esm/api/permission/permission.js +0 -294
  108. package/dist/esm/api/plugin/extension.js +0 -531
  109. package/dist/esm/api/plugin/index.js +0 -529
  110. package/dist/esm/api/plugin/package-info.js +0 -4
  111. package/dist/esm/api/registry/extension.js +0 -1217
  112. package/dist/esm/api/registry/index.js +0 -1216
  113. package/dist/esm/api/registry/packets.js +0 -688
  114. package/dist/esm/api/registry/registry.js +0 -383
  115. package/dist/esm/api/server/extension.js +0 -2071
  116. package/dist/esm/api/server/index.js +0 -2049
  117. package/dist/esm/api/session/extension.js +0 -2166
  118. package/dist/esm/api/session/index.js +0 -2166
  119. package/dist/esm/api/signal/extension.js +0 -1025
  120. package/dist/esm/api/signal/index.js +0 -379
  121. package/dist/esm/api/signal/packets.js +0 -684
  122. package/dist/esm/api/signal/signal.js +0 -379
  123. package/dist/esm/api/table/extension.js +0 -1547
  124. package/dist/esm/api/table/index.js +0 -1546
  125. package/dist/esm/api/table/packets.js +0 -898
  126. package/dist/esm/api/table/table.js +0 -383
  127. package/dist/esm/app.js +0 -264
  128. package/dist/esm/const.js +0 -11
  129. package/dist/esm/errors.js +0 -548
  130. package/dist/esm/event/index.js +0 -22
  131. package/dist/esm/helper.js +0 -15
  132. package/dist/esm/identifier.js +0 -266
  133. package/dist/esm/index.js +0 -5111
  134. package/dist/esm/localization/index.js +0 -742
  135. package/dist/esm/localization/locale.js +0 -742
  136. package/dist/esm/localization/localization.js +0 -4
  137. package/dist/esm/lock.js +0 -46
  138. package/dist/esm/network/connection.js +0 -293
  139. package/dist/esm/network/encryption.js +0 -980
  140. package/dist/esm/network/frame-transport.js +0 -525
  141. package/dist/esm/network/index.js +0 -1617
  142. package/dist/esm/network/network.js +0 -1358
  143. package/dist/esm/network/packet/index.js +0 -485
  144. package/dist/esm/network/packet/packet-types.js +0 -486
  145. package/dist/esm/network/packet/packet.js +0 -126
  146. package/dist/esm/network/websocket-transport.js +0 -487
  147. package/dist/esm/omu.js +0 -4870
  148. package/dist/esm/result.js +0 -68
  149. package/dist/esm/serialize/bytebuffer.js +0 -378
  150. package/dist/esm/serialize/index.js +0 -465
  151. package/dist/esm/serialize/serializer.js +0 -97
  152. package/dist/esm/token.js +0 -42
  153. package/dist/esm/version.js +0 -11
  154. package/tsconfig.tsbuildinfo +0 -1
@@ -1,23 +0,0 @@
1
- // @bun
2
- // src/api/extension-registry.ts
3
- class ExtensionRegistry {
4
- omu;
5
- extensionMap = new Map;
6
- constructor(omu) {
7
- this.omu = omu;
8
- }
9
- register(type) {
10
- if (this.extensionMap.has(type.name)) {
11
- throw new Error(`Extension type ${type.name} already registered`);
12
- }
13
- const extension = type.create(this.omu);
14
- this.extensionMap.set(type.name, extension);
15
- return extension;
16
- }
17
- }
18
- export {
19
- ExtensionRegistry
20
- };
21
-
22
- //# debugId=1E840782605B06CE64756E2164756E21
23
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FwaS9leHRlbnNpb24tcmVnaXN0cnkudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiaW1wb3J0IHsgT211IH0gZnJvbSAnLi4vb211LmpzJztcbmltcG9ydCB0eXBlIHsgRXh0ZW5zaW9uLCBFeHRlbnNpb25UeXBlIH0gZnJvbSAnLi9leHRlbnNpb24uanMnO1xuXG5leHBvcnQgY2xhc3MgRXh0ZW5zaW9uUmVnaXN0cnkge1xuICAgIHByaXZhdGUgcmVhZG9ubHkgZXh0ZW5zaW9uTWFwOiBNYXA8c3RyaW5nLCBFeHRlbnNpb24+ID0gbmV3IE1hcCgpO1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSBvbXU6IE9tdSkge31cblxuICAgIHJlZ2lzdGVyPFQgZXh0ZW5kcyBFeHRlbnNpb24+KHR5cGU6IEV4dGVuc2lvblR5cGU8VD4pOiBUIHtcbiAgICAgICAgaWYgKHRoaXMuZXh0ZW5zaW9uTWFwLmhhcyh0eXBlLm5hbWUpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4dGVuc2lvbiB0eXBlICR7dHlwZS5uYW1lfSBhbHJlYWR5IHJlZ2lzdGVyZWRgKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBleHRlbnNpb24gPSB0eXBlLmNyZWF0ZSh0aGlzLm9tdSk7XG4gICAgICAgIHRoaXMuZXh0ZW5zaW9uTWFwLnNldCh0eXBlLm5hbWUsIGV4dGVuc2lvbik7XG4gICAgICAgIHJldHVybiBleHRlbnNpb247XG4gICAgfVxufVxuIgogIF0sCiAgIm1hcHBpbmdzIjogIjs7QUFHTyxNQUFNLGtCQUFrQjtBQUFBLEVBR0U7QUFBQSxFQUZaLGVBQXVDLElBQUk7QUFBQSxFQUU1RCxXQUFXLENBQWtCLEtBQVU7QUFBQSxJQUFWO0FBQUE7QUFBQSxFQUU3QixRQUE2QixDQUFDLE1BQTJCO0FBQUEsSUFDckQsSUFBSSxLQUFLLGFBQWEsSUFBSSxLQUFLLElBQUksR0FBRztBQUFBLE1BQ2xDLE1BQU0sSUFBSSxNQUFNLGtCQUFrQixLQUFLLHlCQUF5QjtBQUFBLElBQ3BFO0FBQUEsSUFDQSxNQUFNLFlBQVksS0FBSyxPQUFPLEtBQUssR0FBRztBQUFBLElBQ3RDLEtBQUssYUFBYSxJQUFJLEtBQUssTUFBTSxTQUFTO0FBQUEsSUFDMUMsT0FBTztBQUFBO0FBRWY7IiwKICAiZGVidWdJZCI6ICIxRTg0MDc4MjYwNUIwNkNFNjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==
@@ -1,278 +0,0 @@
1
- // @bun
2
- // src/app.ts
3
- class App {
4
- id;
5
- type;
6
- parentId;
7
- version;
8
- url;
9
- metadata;
10
- dependencies;
11
- constructor(id, options) {
12
- this.id = Identifier.from(id);
13
- this.parentId = Identifier.fromOptional(options.parentId);
14
- this.version = options.version;
15
- this.url = options.url;
16
- this.metadata = options.metadata;
17
- this.type = options.type ?? "app";
18
- this.dependencies = options.dependencies ?? {};
19
- }
20
- static deserialize(info) {
21
- const id = Identifier.fromKey(info.id);
22
- return new App(id, {
23
- parentId: Identifier.fromOptional(info.parent_id),
24
- version: info.version,
25
- url: info.url,
26
- type: info.type,
27
- metadata: info.metadata,
28
- dependencies: info.dependencies ?? {}
29
- });
30
- }
31
- static serialize(data) {
32
- return {
33
- id: data.id.key(),
34
- type: data.type,
35
- parent_id: data.parentId?.key(),
36
- version: data.version,
37
- url: data.url,
38
- metadata: data.metadata,
39
- dependencies: data.dependencies
40
- };
41
- }
42
- join(...paths) {
43
- return new App(this.id.join(...paths), {
44
- parentId: this.parentId,
45
- version: this.version,
46
- url: this.url,
47
- type: this.type,
48
- metadata: this.metadata,
49
- dependencies: this.dependencies
50
- });
51
- }
52
- }
53
-
54
- // src/identifier.ts
55
- var NAMESPACE_REGEX = /^(\.[^/:.]|[\w-])+$/;
56
- var NAME_REGEX = /^[^/:]+$/;
57
-
58
- class Identifier {
59
- namespace;
60
- path;
61
- constructor(namespace, ...path) {
62
- Identifier.validate(namespace, path);
63
- this.namespace = namespace;
64
- this.path = path;
65
- }
66
- static serialize(identifier) {
67
- return identifier.key();
68
- }
69
- static deserialize(json) {
70
- return Identifier.fromJson(json);
71
- }
72
- static from(id) {
73
- if (id instanceof Identifier) {
74
- return id;
75
- } else if (id instanceof App) {
76
- return id.id;
77
- } else if (typeof id === "string") {
78
- return Identifier.fromKey(id);
79
- } else {
80
- const idCasted = id;
81
- if (typeof idCasted.namespace === "string" && Array.isArray(idCasted.path) && idCasted.path.every((p) => typeof p === "string")) {
82
- return new Identifier(idCasted.namespace, ...idCasted.path);
83
- }
84
- const idWithId = id;
85
- if (typeof idWithId.id !== "undefined") {
86
- return Identifier.from(idWithId.id);
87
- }
88
- throw new Error(`Cannot convert to Identifier: ${id}`);
89
- }
90
- }
91
- static fromOptional(id) {
92
- if (id === undefined || id === null) {
93
- return;
94
- }
95
- return Identifier.from(id);
96
- }
97
- static validate(namespace, path) {
98
- if (!namespace) {
99
- throw new Error("Invalid namespace: Namespace cannot be empty");
100
- }
101
- if (path.length === 0) {
102
- throw new Error("Invalid path: Path must have at least one name");
103
- }
104
- if (!NAMESPACE_REGEX.test(namespace)) {
105
- throw new Error(`Invalid namespace: Namespace must match ${NAMESPACE_REGEX}`);
106
- }
107
- for (const name of path) {
108
- if (!NAME_REGEX.test(name)) {
109
- throw new Error(`Invalid path: Name must match ${NAME_REGEX} but got ${name}`);
110
- }
111
- }
112
- }
113
- static format(namespace, ...path) {
114
- Identifier.validate(namespace, path);
115
- return `${namespace}:${path.join("/")}`;
116
- }
117
- static fromKey(key) {
118
- const separator = key.indexOf(":");
119
- if (separator === -1) {
120
- throw new Error(`Invalid key: No separator found in ${key}`);
121
- }
122
- if (key.indexOf(":", separator + 1) !== -1) {
123
- throw new Error(`Invalid key: Multiple separators found in ${key}`);
124
- }
125
- const namespace = key.slice(0, separator);
126
- const path = key.slice(separator + 1);
127
- if (!namespace || !path) {
128
- throw new Error("Invalid key: Namespace and path cannot be empty");
129
- }
130
- return new Identifier(namespace, ...path.split("/"));
131
- }
132
- static fromUrl(url) {
133
- const parsedUrl = new URL(url);
134
- const namespace = Identifier.namespaceFromUrl(parsedUrl.href);
135
- const path = parsedUrl.pathname.slice(1).split("/");
136
- return new Identifier(namespace, ...path);
137
- }
138
- static namespaceFromUrl(url) {
139
- const parsed = new URL(url);
140
- return parsed.hostname.split(".").reverse().join(".");
141
- }
142
- get base() {
143
- return new Identifier(this.namespace, this.path[0]);
144
- }
145
- toJson() {
146
- return this.key();
147
- }
148
- static fromJson(json) {
149
- return Identifier.fromKey(json);
150
- }
151
- key() {
152
- return Identifier.format(this.namespace, ...this.path);
153
- }
154
- isEqual(other) {
155
- return this.key() === other.key();
156
- }
157
- isNamespaceEqual(other) {
158
- return this.namespace === other.namespace;
159
- }
160
- isSubpathOf(other) {
161
- if (this.namespace !== other.namespace) {
162
- return false;
163
- }
164
- if (this.path.length < other.path.length) {
165
- return false;
166
- }
167
- for (let i = 0;i < other.path.length; i++) {
168
- if (this.path[i] !== other.path[i]) {
169
- return false;
170
- }
171
- }
172
- return true;
173
- }
174
- join(...path) {
175
- return new Identifier(this.namespace, ...this.path, ...path);
176
- }
177
- }
178
-
179
- class IdentifierMap {
180
- map = new Map;
181
- constructor(entries) {
182
- if (!entries)
183
- return;
184
- for (const [id, value] of entries) {
185
- this.map.set(id.key(), value);
186
- }
187
- }
188
- get size() {
189
- return this.map.size;
190
- }
191
- set(identifier, value) {
192
- this.map.set(identifier.key(), value);
193
- }
194
- get(identifier) {
195
- return this.map.get(identifier.key());
196
- }
197
- has(identifier) {
198
- return this.map.has(identifier.key());
199
- }
200
- delete(identifier) {
201
- this.map.delete(identifier.key());
202
- }
203
- clear() {
204
- this.map.clear();
205
- }
206
- *keys() {
207
- for (const key of this.map.keys()) {
208
- yield Identifier.fromKey(key);
209
- }
210
- }
211
- values() {
212
- return this.map.values();
213
- }
214
- *entries() {
215
- for (const [key, value] of this.map.entries()) {
216
- yield [Identifier.fromKey(key), value];
217
- }
218
- }
219
- [Symbol.iterator]() {
220
- return this.entries();
221
- }
222
- }
223
-
224
- class IdentifierSet {
225
- set = new Set;
226
- get size() {
227
- return this.set.size;
228
- }
229
- add(identifier) {
230
- this.set.add(identifier.key());
231
- }
232
- has(identifier) {
233
- return this.set.has(identifier.key());
234
- }
235
- delete(identifier) {
236
- this.set.delete(identifier.key());
237
- }
238
- clear() {
239
- this.set.clear();
240
- }
241
- *keys() {
242
- for (const key of this.set.keys()) {
243
- yield Identifier.fromKey(key);
244
- }
245
- }
246
- values() {
247
- return this.keys();
248
- }
249
- *entries() {
250
- for (const key of this.set.keys()) {
251
- const identifier = Identifier.fromKey(key);
252
- yield [identifier, identifier];
253
- }
254
- }
255
- [Symbol.iterator]() {
256
- return this.entries();
257
- }
258
- }
259
-
260
- // src/api/extension.ts
261
- class ExtensionType extends Identifier {
262
- name;
263
- create;
264
- constructor(name, create) {
265
- super("ext", name);
266
- this.name = name;
267
- this.create = create;
268
- }
269
- key() {
270
- return new Identifier("ext", this.name).key();
271
- }
272
- }
273
- export {
274
- ExtensionType
275
- };
276
-
277
- //# debugId=B3226625378AEDB064756E2164756E21
278
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vc3JjL2FwcC50cyIsICIuLi8uLi9zcmMvaWRlbnRpZmllci50cyIsICIuLi8uLi9zcmMvYXBpL2V4dGVuc2lvbi50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsKICAgICJpbXBvcnQgeyBJZGVudGlmaWVyLCBJbnRvSWQgfSBmcm9tICcuL2lkZW50aWZpZXInO1xuaW1wb3J0IHR5cGUgeyBMb2NhbGUgfSBmcm9tICcuL2xvY2FsaXphdGlvbi9sb2NhbGUuanMnO1xuaW1wb3J0IHR5cGUgeyBMb2NhbGl6ZWRUZXh0IH0gZnJvbSAnLi9sb2NhbGl6YXRpb24vbG9jYWxpemF0aW9uLmpzJztcblxuZXhwb3J0IHR5cGUgQXBwTWV0YWRhdGEgPSB7XG4gICAgbG9jYWxlOiBMb2NhbGU7XG4gICAgbmFtZT86IExvY2FsaXplZFRleHQ7XG4gICAgaWNvbj86IExvY2FsaXplZFRleHQ7XG4gICAgZGVzY3JpcHRpb24/OiBMb2NhbGl6ZWRUZXh0O1xuICAgIGltYWdlPzogTG9jYWxpemVkVGV4dDtcbiAgICBzaXRlPzogTG9jYWxpemVkVGV4dDtcbiAgICByZXBvc2l0b3J5PzogTG9jYWxpemVkVGV4dDtcbiAgICBhdXRob3JzPzogTG9jYWxpemVkVGV4dDtcbiAgICBsaWNlbnNlPzogTG9jYWxpemVkVGV4dDtcbiAgICB0YWdzPzogc3RyaW5nW107XG59O1xuXG5leHBvcnQgdHlwZSBBcHBUeXBlID0gJ2FwcCcgfCAnc2VydmljZScgfCAncmVtb3RlJyB8ICdwbHVnaW4nIHwgJ2Rhc2hib2FyZCc7XG5cbmV4cG9ydCB0eXBlIERlcGVuZGVuY3lTcGVjaWZpZXIgPSB7XG4gICAgdmVyc2lvbjogc3RyaW5nO1xuICAgIGluZGV4Pzogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgQXBwSnNvbiA9IHtcbiAgICBpZDogc3RyaW5nO1xuICAgIHR5cGU6IEFwcFR5cGU7XG4gICAgcGFyZW50X2lkPzogc3RyaW5nO1xuICAgIHZlcnNpb24/OiBzdHJpbmc7XG4gICAgdXJsPzogc3RyaW5nO1xuICAgIG1ldGFkYXRhPzogQXBwTWV0YWRhdGE7XG4gICAgZGVwZW5kZW5jaWVzPzogUmVjb3JkPHN0cmluZywgRGVwZW5kZW5jeVNwZWNpZmllciB8IHN0cmluZz47XG59O1xuXG5leHBvcnQgY2xhc3MgQXBwIHtcbiAgICBwdWJsaWMgcmVhZG9ubHkgaWQ6IElkZW50aWZpZXI7XG4gICAgcHVibGljIHJlYWRvbmx5IHR5cGU6IEFwcFR5cGU7XG4gICAgcHVibGljIHJlYWRvbmx5IHBhcmVudElkPzogSWRlbnRpZmllcjtcbiAgICBwdWJsaWMgcmVhZG9ubHkgdmVyc2lvbj86IHN0cmluZztcbiAgICBwdWJsaWMgcmVhZG9ubHkgdXJsPzogc3RyaW5nO1xuICAgIHB1YmxpYyByZWFkb25seSBtZXRhZGF0YT86IEFwcE1ldGFkYXRhO1xuICAgIHB1YmxpYyByZWFkb25seSBkZXBlbmRlbmNpZXM6IFJlY29yZDxzdHJpbmcsIERlcGVuZGVuY3lTcGVjaWZpZXIgfCBzdHJpbmc+O1xuXG4gICAgY29uc3RydWN0b3IoaWQ6IEludG9JZCwgb3B0aW9uczoge1xuICAgICAgICB0eXBlPzogQXBwVHlwZTtcbiAgICAgICAgcGFyZW50SWQ/OiBJbnRvSWQ7XG4gICAgICAgIHZlcnNpb24/OiBzdHJpbmc7XG4gICAgICAgIHVybD86IHN0cmluZztcbiAgICAgICAgbWV0YWRhdGE/OiBBcHBNZXRhZGF0YTtcbiAgICAgICAgZGVwZW5kZW5jaWVzPzogUmVjb3JkPHN0cmluZywgRGVwZW5kZW5jeVNwZWNpZmllciB8IHN0cmluZz47XG4gICAgfSkge1xuICAgICAgICB0aGlzLmlkID0gSWRlbnRpZmllci5mcm9tKGlkKTtcbiAgICAgICAgdGhpcy5wYXJlbnRJZCA9IElkZW50aWZpZXIuZnJvbU9wdGlvbmFsKG9wdGlvbnMucGFyZW50SWQpO1xuICAgICAgICB0aGlzLnZlcnNpb24gPSBvcHRpb25zLnZlcnNpb247XG4gICAgICAgIHRoaXMudXJsID0gb3B0aW9ucy51cmw7XG4gICAgICAgIHRoaXMubWV0YWRhdGEgPSBvcHRpb25zLm1ldGFkYXRhO1xuICAgICAgICB0aGlzLnR5cGUgPSBvcHRpb25zLnR5cGUgPz8gJ2FwcCc7XG4gICAgICAgIHRoaXMuZGVwZW5kZW5jaWVzID0gb3B0aW9ucy5kZXBlbmRlbmNpZXMgPz8ge307XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBkZXNlcmlhbGl6ZShpbmZvOiBBcHBKc29uKTogQXBwIHtcbiAgICAgICAgY29uc3QgaWQgPSBJZGVudGlmaWVyLmZyb21LZXkoaW5mby5pZCk7XG4gICAgICAgIHJldHVybiBuZXcgQXBwKGlkLCB7XG4gICAgICAgICAgICBwYXJlbnRJZDogSWRlbnRpZmllci5mcm9tT3B0aW9uYWwoaW5mby5wYXJlbnRfaWQpLFxuICAgICAgICAgICAgdmVyc2lvbjogaW5mby52ZXJzaW9uLFxuICAgICAgICAgICAgdXJsOiBpbmZvLnVybCxcbiAgICAgICAgICAgIHR5cGU6IGluZm8udHlwZSxcbiAgICAgICAgICAgIG1ldGFkYXRhOiBpbmZvLm1ldGFkYXRhLFxuICAgICAgICAgICAgZGVwZW5kZW5jaWVzOiBpbmZvLmRlcGVuZGVuY2llcyA/PyB7fSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBzZXJpYWxpemUoZGF0YTogQXBwKTogQXBwSnNvbiB7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBpZDogZGF0YS5pZC5rZXkoKSxcbiAgICAgICAgICAgIHR5cGU6IGRhdGEudHlwZSxcbiAgICAgICAgICAgIHBhcmVudF9pZDogZGF0YS5wYXJlbnRJZD8ua2V5KCksXG4gICAgICAgICAgICB2ZXJzaW9uOiBkYXRhLnZlcnNpb24sXG4gICAgICAgICAgICB1cmw6IGRhdGEudXJsLFxuICAgICAgICAgICAgbWV0YWRhdGE6IGRhdGEubWV0YWRhdGEsXG4gICAgICAgICAgICBkZXBlbmRlbmNpZXM6IGRhdGEuZGVwZW5kZW5jaWVzLFxuICAgICAgICB9O1xuICAgIH1cblxuICAgIHB1YmxpYyBqb2luKC4uLnBhdGhzOiBzdHJpbmdbXSk6IEFwcCB7XG4gICAgICAgIHJldHVybiBuZXcgQXBwKHRoaXMuaWQuam9pbiguLi5wYXRocyksIHtcbiAgICAgICAgICAgIHBhcmVudElkOiB0aGlzLnBhcmVudElkLFxuICAgICAgICAgICAgdmVyc2lvbjogdGhpcy52ZXJzaW9uLFxuICAgICAgICAgICAgdXJsOiB0aGlzLnVybCxcbiAgICAgICAgICAgIHR5cGU6IHRoaXMudHlwZSxcbiAgICAgICAgICAgIG1ldGFkYXRhOiB0aGlzLm1ldGFkYXRhLFxuICAgICAgICAgICAgZGVwZW5kZW5jaWVzOiB0aGlzLmRlcGVuZGVuY2llcyxcbiAgICAgICAgfSk7XG4gICAgfVxufVxuIiwKICAgICJpbXBvcnQgdHlwZSB7IEV4dGVuc2lvblR5cGUgfSBmcm9tICcuL2FwaSc7XG5pbXBvcnQgeyBBcHAgfSBmcm9tICcuL2FwcCc7XG5cbmNvbnN0IE5BTUVTUEFDRV9SRUdFWCA9IC9eKFxcLlteLzouXXxbXFx3LV0pKyQvO1xuY29uc3QgTkFNRV9SRUdFWCA9IC9eW14vOl0rJC87XG5cbmV4cG9ydCB0eXBlIEludG9JZCA9IElkZW50aWZpZXIgfCBzdHJpbmcgfCBFeHRlbnNpb25UeXBlIHwgQXBwO1xuXG5leHBvcnQgY2xhc3MgSWRlbnRpZmllciB7XG4gICAgcHVibGljIHJlYWRvbmx5IG5hbWVzcGFjZTogc3RyaW5nO1xuICAgIHB1YmxpYyByZWFkb25seSBwYXRoOiBzdHJpbmdbXTtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBuYW1lc3BhY2U6IHN0cmluZyxcbiAgICAgICAgLi4ucGF0aDogc3RyaW5nW11cbiAgICApIHtcbiAgICAgICAgSWRlbnRpZmllci52YWxpZGF0ZShuYW1lc3BhY2UsIHBhdGgpO1xuICAgICAgICB0aGlzLm5hbWVzcGFjZSA9IG5hbWVzcGFjZTtcbiAgICAgICAgdGhpcy5wYXRoID0gcGF0aDtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIHNlcmlhbGl6ZShpZGVudGlmaWVyOiBJZGVudGlmaWVyKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIGlkZW50aWZpZXIua2V5KCk7XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBkZXNlcmlhbGl6ZShqc29uOiBzdHJpbmcpOiBJZGVudGlmaWVyIHtcbiAgICAgICAgcmV0dXJuIElkZW50aWZpZXIuZnJvbUpzb24oanNvbik7XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBmcm9tKGlkOiBJbnRvSWQpOiBJZGVudGlmaWVyIHtcbiAgICAgICAgaWYgKGlkIGluc3RhbmNlb2YgSWRlbnRpZmllcikge1xuICAgICAgICAgICAgcmV0dXJuIGlkO1xuICAgICAgICB9IGVsc2UgaWYgKGlkIGluc3RhbmNlb2YgQXBwKSB7XG4gICAgICAgICAgICByZXR1cm4gaWQuaWQ7XG4gICAgICAgIH0gZWxzZSBpZiAodHlwZW9mIGlkID09PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgcmV0dXJuIElkZW50aWZpZXIuZnJvbUtleShpZCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBUcnkgdG8gaW5mZXJcbiAgICAgICAgICAgIC8vIFZpdGUgZG9lcyBub3QgcHJlc2VydmUgY2xhc3MgaW5mb3JtYXRpb24gd2hlbiBpbXBvcnRpbmcgZnJvbSBkaWZmZXJlbnQgcGFja2FnZXNcbiAgICAgICAgICAgIGNvbnN0IGlkQ2FzdGVkID0gaWQgYXMgeyBuYW1lc3BhY2U6IHN0cmluZzsgcGF0aDogc3RyaW5nW10gfTtcbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICB0eXBlb2YgaWRDYXN0ZWQubmFtZXNwYWNlID09PSAnc3RyaW5nJyAmJlxuICAgICAgICAgICAgICAgIEFycmF5LmlzQXJyYXkoaWRDYXN0ZWQucGF0aCkgJiZcbiAgICAgICAgICAgICAgICBpZENhc3RlZC5wYXRoLmV2ZXJ5KChwKSA9PiB0eXBlb2YgcCA9PT0gJ3N0cmluZycpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IElkZW50aWZpZXIoaWRDYXN0ZWQubmFtZXNwYWNlLCAuLi5pZENhc3RlZC5wYXRoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGlkV2l0aElkID0gaWQgYXMgeyBpZDogSW50b0lkIHwgdW5kZWZpbmVkIH07XG4gICAgICAgICAgICBpZiAodHlwZW9mIGlkV2l0aElkLmlkICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgICAgICAgICAgIHJldHVybiBJZGVudGlmaWVyLmZyb20oaWRXaXRoSWQuaWQpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29udmVydCB0byBJZGVudGlmaWVyOiAke2lkfWApO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBmcm9tT3B0aW9uYWwoaWQ6IEludG9JZCB8IHVuZGVmaW5lZCB8IG51bGwpOiBJZGVudGlmaWVyIHwgdW5kZWZpbmVkIHtcbiAgICAgICAgaWYgKGlkID09PSB1bmRlZmluZWQgfHwgaWQgPT09IG51bGwpIHtcbiAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIElkZW50aWZpZXIuZnJvbShpZCk7XG4gICAgfVxuXG4gICAgc3RhdGljIHZhbGlkYXRlKG5hbWVzcGFjZTogc3RyaW5nLCBwYXRoOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgICAgICBpZiAoIW5hbWVzcGFjZSkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIG5hbWVzcGFjZTogTmFtZXNwYWNlIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwYXRoLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHBhdGg6IFBhdGggbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBuYW1lJyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFOQU1FU1BBQ0VfUkVHRVgudGVzdChuYW1lc3BhY2UpKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgbmFtZXNwYWNlOiBOYW1lc3BhY2UgbXVzdCBtYXRjaCAke05BTUVTUEFDRV9SRUdFWH1gKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IgKGNvbnN0IG5hbWUgb2YgcGF0aCkge1xuICAgICAgICAgICAgaWYgKCFOQU1FX1JFR0VYLnRlc3QobmFtZSkpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQgcGF0aDogTmFtZSBtdXN0IG1hdGNoICR7TkFNRV9SRUdFWH0gYnV0IGdvdCAke25hbWV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgZm9ybWF0KG5hbWVzcGFjZTogc3RyaW5nLCAuLi5wYXRoOiBzdHJpbmdbXSk6IHN0cmluZyB7XG4gICAgICAgIElkZW50aWZpZXIudmFsaWRhdGUobmFtZXNwYWNlLCBwYXRoKTtcbiAgICAgICAgcmV0dXJuIGAke25hbWVzcGFjZX06JHtwYXRoLmpvaW4oJy8nKX1gO1xuICAgIH1cblxuICAgIHN0YXRpYyBmcm9tS2V5KGtleTogc3RyaW5nKTogSWRlbnRpZmllciB7XG4gICAgICAgIGNvbnN0IHNlcGFyYXRvciA9IGtleS5pbmRleE9mKCc6Jyk7XG4gICAgICAgIGlmIChzZXBhcmF0b3IgPT09IC0xKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQga2V5OiBObyBzZXBhcmF0b3IgZm91bmQgaW4gJHtrZXl9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGtleS5pbmRleE9mKCc6Jywgc2VwYXJhdG9yICsgMSkgIT09IC0xKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludmFsaWQga2V5OiBNdWx0aXBsZSBzZXBhcmF0b3JzIGZvdW5kIGluICR7a2V5fWApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IG5hbWVzcGFjZSA9IGtleS5zbGljZSgwLCBzZXBhcmF0b3IpO1xuICAgICAgICBjb25zdCBwYXRoID0ga2V5LnNsaWNlKHNlcGFyYXRvciArIDEpO1xuICAgICAgICBpZiAoIW5hbWVzcGFjZSB8fCAhcGF0aCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIGtleTogTmFtZXNwYWNlIGFuZCBwYXRoIGNhbm5vdCBiZSBlbXB0eScpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBuZXcgSWRlbnRpZmllcihuYW1lc3BhY2UsIC4uLnBhdGguc3BsaXQoJy8nKSk7XG4gICAgfVxuXG4gICAgcHVibGljIHN0YXRpYyBmcm9tVXJsKHVybDogc3RyaW5nIHwgVVJMKTogSWRlbnRpZmllciB7XG4gICAgICAgIGNvbnN0IHBhcnNlZFVybCA9IG5ldyBVUkwodXJsKTtcbiAgICAgICAgY29uc3QgbmFtZXNwYWNlID0gSWRlbnRpZmllci5uYW1lc3BhY2VGcm9tVXJsKHBhcnNlZFVybC5ocmVmKTtcbiAgICAgICAgY29uc3QgcGF0aCA9IHBhcnNlZFVybC5wYXRobmFtZS5zbGljZSgxKS5zcGxpdCgnLycpO1xuICAgICAgICByZXR1cm4gbmV3IElkZW50aWZpZXIobmFtZXNwYWNlLCAuLi5wYXRoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc3RhdGljIG5hbWVzcGFjZUZyb21VcmwodXJsOiBzdHJpbmcgfCBVUkwpOiBzdHJpbmcge1xuICAgICAgICBjb25zdCBwYXJzZWQgPSBuZXcgVVJMKHVybCk7XG4gICAgICAgIHJldHVybiBwYXJzZWQuaG9zdG5hbWUuc3BsaXQoJy4nKS5yZXZlcnNlKCkuam9pbignLicpO1xuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgYmFzZSgpOiBJZGVudGlmaWVyIHtcbiAgICAgICAgcmV0dXJuIG5ldyBJZGVudGlmaWVyKHRoaXMubmFtZXNwYWNlLCB0aGlzLnBhdGhbMF0pO1xuICAgIH1cblxuICAgIHB1YmxpYyB0b0pzb24oKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIHRoaXMua2V5KCk7XG4gICAgfVxuXG4gICAgc3RhdGljIGZyb21Kc29uKGpzb246IHN0cmluZyk6IElkZW50aWZpZXIge1xuICAgICAgICByZXR1cm4gSWRlbnRpZmllci5mcm9tS2V5KGpzb24pO1xuICAgIH1cblxuICAgIHB1YmxpYyBrZXkoKTogc3RyaW5nIHtcbiAgICAgICAgcmV0dXJuIElkZW50aWZpZXIuZm9ybWF0KHRoaXMubmFtZXNwYWNlLCAuLi50aGlzLnBhdGgpO1xuICAgIH1cblxuICAgIHB1YmxpYyBpc0VxdWFsKG90aGVyOiBJZGVudGlmaWVyKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmtleSgpID09PSBvdGhlci5rZXkoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNOYW1lc3BhY2VFcXVhbChvdGhlcjogSWRlbnRpZmllcik6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gdGhpcy5uYW1lc3BhY2UgPT09IG90aGVyLm5hbWVzcGFjZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaXNTdWJwYXRoT2Yob3RoZXI6IElkZW50aWZpZXIpOiBib29sZWFuIHtcbiAgICAgICAgaWYgKHRoaXMubmFtZXNwYWNlICE9PSBvdGhlci5uYW1lc3BhY2UpIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAodGhpcy5wYXRoLmxlbmd0aCA8IG90aGVyLnBhdGgubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBvdGhlci5wYXRoLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5wYXRoW2ldICE9PSBvdGhlci5wYXRoW2ldKSB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHB1YmxpYyBqb2luKC4uLnBhdGg6IHN0cmluZ1tdKTogSWRlbnRpZmllciB7XG4gICAgICAgIHJldHVybiBuZXcgSWRlbnRpZmllcih0aGlzLm5hbWVzcGFjZSwgLi4udGhpcy5wYXRoLCAuLi5wYXRoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBJZGVudGlmaWVyTWFwPFQ+IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IG1hcDogTWFwPHN0cmluZywgVD4gPSBuZXcgTWFwKCk7XG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIGVudHJpZXM/OiBJdGVyYWJsZTxbSWRlbnRpZmllciwgVF0+LFxuICAgICkge1xuICAgICAgICBpZiAoIWVudHJpZXMpIHJldHVybjtcbiAgICAgICAgZm9yIChjb25zdCBbaWQsIHZhbHVlXSBvZiBlbnRyaWVzKSB7XG4gICAgICAgICAgICB0aGlzLm1hcC5zZXQoaWQua2V5KCksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBnZXQgc2l6ZSgpOiBudW1iZXIge1xuICAgICAgICByZXR1cm4gdGhpcy5tYXAuc2l6ZTtcbiAgICB9XG5cbiAgICBwdWJsaWMgc2V0KGlkZW50aWZpZXI6IElkZW50aWZpZXIsIHZhbHVlOiBUKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWFwLnNldChpZGVudGlmaWVyLmtleSgpLCB2YWx1ZSk7XG4gICAgfVxuXG4gICAgcHVibGljIGdldChpZGVudGlmaWVyOiBJZGVudGlmaWVyKTogVCB8IHVuZGVmaW5lZCB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5nZXQoaWRlbnRpZmllci5rZXkoKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGhhcyhpZGVudGlmaWVyOiBJZGVudGlmaWVyKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5oYXMoaWRlbnRpZmllci5rZXkoKSk7XG4gICAgfVxuXG4gICAgcHVibGljIGRlbGV0ZShpZGVudGlmaWVyOiBJZGVudGlmaWVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWFwLmRlbGV0ZShpZGVudGlmaWVyLmtleSgpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgY2xlYXIoKTogdm9pZCB7XG4gICAgICAgIHRoaXMubWFwLmNsZWFyKCk7XG4gICAgfVxuXG4gICAgcHVibGljICprZXlzKCk6IEl0ZXJhYmxlSXRlcmF0b3I8SWRlbnRpZmllcj4ge1xuICAgICAgICBmb3IgKGNvbnN0IGtleSBvZiB0aGlzLm1hcC5rZXlzKCkpIHtcbiAgICAgICAgICAgIHlpZWxkIElkZW50aWZpZXIuZnJvbUtleShrZXkpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIHZhbHVlcygpOiBJdGVyYWJsZUl0ZXJhdG9yPFQ+IHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLnZhbHVlcygpO1xuICAgIH1cblxuICAgIHB1YmxpYyAqZW50cmllcygpOiBJdGVyYWJsZUl0ZXJhdG9yPFtJZGVudGlmaWVyLCBUXT4ge1xuICAgICAgICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiB0aGlzLm1hcC5lbnRyaWVzKCkpIHtcbiAgICAgICAgICAgIHlpZWxkIFtJZGVudGlmaWVyLmZyb21LZXkoa2V5KSwgdmFsdWVdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIFtTeW1ib2wuaXRlcmF0b3JdKCk6IEl0ZXJhYmxlSXRlcmF0b3I8W0lkZW50aWZpZXIsIFRdPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmVudHJpZXMoKTtcbiAgICB9XG59XG5cbmV4cG9ydCBjbGFzcyBJZGVudGlmaWVyU2V0IHtcbiAgICBwcml2YXRlIHJlYWRvbmx5IHNldDogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG5cbiAgICBwdWJsaWMgZ2V0IHNpemUoKTogbnVtYmVyIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0LnNpemU7XG4gICAgfVxuXG4gICAgcHVibGljIGFkZChpZGVudGlmaWVyOiBJZGVudGlmaWVyKTogdm9pZCB7XG4gICAgICAgIHRoaXMuc2V0LmFkZChpZGVudGlmaWVyLmtleSgpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgaGFzKGlkZW50aWZpZXI6IElkZW50aWZpZXIpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuc2V0LmhhcyhpZGVudGlmaWVyLmtleSgpKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgZGVsZXRlKGlkZW50aWZpZXI6IElkZW50aWZpZXIpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXQuZGVsZXRlKGlkZW50aWZpZXIua2V5KCkpO1xuICAgIH1cblxuICAgIHB1YmxpYyBjbGVhcigpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5zZXQuY2xlYXIoKTtcbiAgICB9XG5cbiAgICBwdWJsaWMgKmtleXMoKTogSXRlcmFibGVJdGVyYXRvcjxJZGVudGlmaWVyPiB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHRoaXMuc2V0LmtleXMoKSkge1xuICAgICAgICAgICAgeWllbGQgSWRlbnRpZmllci5mcm9tS2V5KGtleSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgdmFsdWVzKCk6IEl0ZXJhYmxlSXRlcmF0b3I8SWRlbnRpZmllcj4ge1xuICAgICAgICByZXR1cm4gdGhpcy5rZXlzKCk7XG4gICAgfVxuXG4gICAgcHVibGljICplbnRyaWVzKCk6IEl0ZXJhYmxlSXRlcmF0b3I8W0lkZW50aWZpZXIsIElkZW50aWZpZXJdPiB7XG4gICAgICAgIGZvciAoY29uc3Qga2V5IG9mIHRoaXMuc2V0LmtleXMoKSkge1xuICAgICAgICAgICAgY29uc3QgaWRlbnRpZmllciA9IElkZW50aWZpZXIuZnJvbUtleShrZXkpO1xuICAgICAgICAgICAgeWllbGQgW2lkZW50aWZpZXIsIGlkZW50aWZpZXJdO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHVibGljIFtTeW1ib2wuaXRlcmF0b3JdKCk6IEl0ZXJhYmxlSXRlcmF0b3I8W0lkZW50aWZpZXIsIElkZW50aWZpZXJdPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmVudHJpZXMoKTtcbiAgICB9XG59XG4iLAogICAgImltcG9ydCB7IElkZW50aWZpZXIgfSBmcm9tICcuLi9pZGVudGlmaWVyJztcbmltcG9ydCB7IE9tdSB9IGZyb20gJy4uL29tdSc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgRXh0ZW5zaW9uIHtcbiAgICByZWFkb25seSB0eXBlOiBFeHRlbnNpb25UeXBlO1xufVxuXG5leHBvcnQgY2xhc3MgRXh0ZW5zaW9uVHlwZTxUIGV4dGVuZHMgRXh0ZW5zaW9uID0gRXh0ZW5zaW9uPiBleHRlbmRzIElkZW50aWZpZXIge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nLFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgY3JlYXRlOiAob211OiBPbXUpID0+IFQsXG4gICAgKSB7XG4gICAgICAgIHN1cGVyKCdleHQnLCBuYW1lKTtcbiAgICB9XG5cbiAgICBwdWJsaWMga2V5KCk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiBuZXcgSWRlbnRpZmllcignZXh0JywgdGhpcy5uYW1lKS5rZXkoKTtcbiAgICB9XG59XG4iCiAgXSwKICAibWFwcGluZ3MiOiAiOztBQWtDTyxNQUFNLElBQUk7QUFBQSxFQUNHO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFFaEIsV0FBVyxDQUFDLElBQVksU0FPckI7QUFBQSxJQUNDLEtBQUssS0FBSyxXQUFXLEtBQUssRUFBRTtBQUFBLElBQzVCLEtBQUssV0FBVyxXQUFXLGFBQWEsUUFBUSxRQUFRO0FBQUEsSUFDeEQsS0FBSyxVQUFVLFFBQVE7QUFBQSxJQUN2QixLQUFLLE1BQU0sUUFBUTtBQUFBLElBQ25CLEtBQUssV0FBVyxRQUFRO0FBQUEsSUFDeEIsS0FBSyxPQUFPLFFBQVEsUUFBUTtBQUFBLElBQzVCLEtBQUssZUFBZSxRQUFRLGdCQUFnQixDQUFDO0FBQUE7QUFBQSxTQUduQyxXQUFXLENBQUMsTUFBb0I7QUFBQSxJQUMxQyxN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QUF3QjtBQUFBLElBQ2pDLE9BQU8sS0FBSyxJQUFJLE9BQU87QUFBQTtBQUFBLEdBR25CLE9BQU8sR0FBc0M7QUFBQSxJQUNqRCxZQUFZLEtBQUssVUFBVSxLQUFLLElBQUksUUFBUSxHQUFHO0FBQUEsTUFDM0MsTUFBTSxDQUFDLFdBQVcsUUFBUSxHQUFHLEdBQUcsS0FBSztBQUFBLElBQ3pDO0FBQUE7QUFBQSxHQUdJLE9BQU8sU0FBUyxHQUFzQztBQUFBLElBQzFELE9BQU8sS0FBSyxRQUFRO0FBQUE7QUFFNUI7QUFBQTtBQUVPLE1BQU0sY0FBYztBQUFBLEVBQ04sTUFBbUIsSUFBSTtBQUFBLE1BRTdCLElBQUksR0FBVztBQUFBLElBQ3RCLE9BQU8sS0FBSyxJQUFJO0FBQUE7QUFBQSxFQUdiLEdBQUcsQ0FBQyxZQUE4QjtBQUFBLElBQ3JDLEtBQUssSUFBSSxJQUFJLFdBQVcsSUFBSSxDQUFDO0FBQUE7QUFBQSxFQUcxQixHQUFHLENBQUMsWUFBaUM7QUFBQSxJQUN4QyxPQUFPLEtBQUssSUFBSSxJQUFJLFdBQVcsSUFBSSxDQUFDO0FBQUE7QUFBQSxFQUdqQyxNQUFNLENBQUMsWUFBOEI7QUFBQSxJQUN4QyxLQUFLLElBQUksT0FBTyxXQUFXLElBQUksQ0FBQztBQUFBO0FBQUEsRUFHN0IsS0FBSyxHQUFTO0FBQUEsSUFDakIsS0FBSyxJQUFJLE1BQU07QUFBQTtBQUFBLEdBR1gsSUFBSSxHQUFpQztBQUFBLElBQ3pDLFdBQVcsT0FBTyxLQUFLLElBQUksS0FBSyxHQUFHO0FBQUEsTUFDL0IsTUFBTSxXQUFXLFFBQVEsR0FBRztBQUFBLElBQ2hDO0FBQUE7QUFBQSxFQUdHLE1BQU0sR0FBaUM7QUFBQSxJQUMxQyxPQUFPLEtBQUssS0FBSztBQUFBO0FBQUEsR0FHYixPQUFPLEdBQStDO0FBQUEsSUFDMUQsV0FBVyxPQUFPLEtBQUssSUFBSSxLQUFLLEdBQUc7QUFBQSxNQUMvQixNQUFNLGFBQWEsV0FBVyxRQUFRLEdBQUc7QUFBQSxNQUN6QyxNQUFNLENBQUMsWUFBWSxVQUFVO0FBQUEsSUFDakM7QUFBQTtBQUFBLEdBR0ksT0FBTyxTQUFTLEdBQStDO0FBQUEsSUFDbkUsT0FBTyxLQUFLLFFBQVE7QUFBQTtBQUU1Qjs7O0FDeFBPLE1BQU0sc0JBQXVELFdBQVc7QUFBQSxFQUV2RDtBQUFBLEVBQ0E7QUFBQSxFQUZwQixXQUFXLENBQ1MsTUFDQSxRQUNsQjtBQUFBLElBQ0UsTUFBTSxPQUFPLElBQUk7QUFBQSxJQUhEO0FBQUEsSUFDQTtBQUFBO0FBQUEsRUFLYixHQUFHLEdBQVc7QUFBQSxJQUNqQixPQUFPLElBQUksV0FBVyxPQUFPLEtBQUssSUFBSSxFQUFFLElBQUk7QUFBQTtBQUVwRDsiLAogICJkZWJ1Z0lkIjogIkIzMjI2NjI1Mzc4QUVEQjA2NDc1NkUyMTY0NzU2RTIxIiwKICAibmFtZXMiOiBbXQp9