velocious 1.0.569 → 1.0.571

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 (50) hide show
  1. package/README.md +56 -2
  2. package/build/configuration-types.js +17 -0
  3. package/build/configuration.js +70 -0
  4. package/build/database/drivers/base.js +82 -44
  5. package/build/database/operation-connection.js +11 -0
  6. package/build/database/operation.js +10 -0
  7. package/build/http-server/client/index.js +77 -4
  8. package/build/http-server/client/response-compression.js +224 -0
  9. package/build/http-server/client/response.js +57 -0
  10. package/build/http-server/websocket-events-host.js +91 -48
  11. package/build/src/configuration-types.d.ts +55 -0
  12. package/build/src/configuration-types.d.ts.map +1 -1
  13. package/build/src/configuration-types.js +16 -1
  14. package/build/src/configuration.d.ts +6 -0
  15. package/build/src/configuration.d.ts.map +1 -1
  16. package/build/src/configuration.js +61 -1
  17. package/build/src/database/drivers/base.d.ts +30 -3
  18. package/build/src/database/drivers/base.d.ts.map +1 -1
  19. package/build/src/database/drivers/base.js +78 -42
  20. package/build/src/database/operation-connection.d.ts +6 -0
  21. package/build/src/database/operation-connection.d.ts.map +1 -1
  22. package/build/src/database/operation-connection.js +10 -1
  23. package/build/src/database/operation.d.ts +8 -0
  24. package/build/src/database/operation.d.ts.map +1 -1
  25. package/build/src/database/operation.js +10 -1
  26. package/build/src/http-server/client/index.d.ts +17 -1
  27. package/build/src/http-server/client/index.d.ts.map +1 -1
  28. package/build/src/http-server/client/index.js +74 -5
  29. package/build/src/http-server/client/response-compression.d.ts +71 -0
  30. package/build/src/http-server/client/response-compression.d.ts.map +1 -0
  31. package/build/src/http-server/client/response-compression.js +197 -0
  32. package/build/src/http-server/client/response.d.ts +27 -0
  33. package/build/src/http-server/client/response.d.ts.map +1 -1
  34. package/build/src/http-server/client/response.js +49 -1
  35. package/build/src/http-server/websocket-events-host.d.ts +28 -11
  36. package/build/src/http-server/websocket-events-host.d.ts.map +1 -1
  37. package/build/src/http-server/websocket-events-host.js +84 -46
  38. package/build/tsconfig.tsbuildinfo +1 -1
  39. package/package.json +4 -3
  40. package/scripts/docker-run.sh +20 -0
  41. package/scripts/verify-docker-dev-environment.js +579 -0
  42. package/src/configuration-types.js +17 -0
  43. package/src/configuration.js +70 -0
  44. package/src/database/drivers/base.js +82 -44
  45. package/src/database/operation-connection.js +11 -0
  46. package/src/database/operation.js +10 -0
  47. package/src/http-server/client/index.js +77 -4
  48. package/src/http-server/client/response-compression.js +224 -0
  49. package/src/http-server/client/response.js +57 -0
  50. package/src/http-server/websocket-events-host.js +91 -48
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Runs parse accept encoding.
3
+ * @param {string} headerValue - Accept-Encoding header value.
4
+ * @returns {Map<string, number>} - Lowercased coding to q-value (0-1).
5
+ */
6
+ export function parseAcceptEncoding(headerValue: string): Map<string, number>;
7
+ /**
8
+ * Negotiates the content coding for a response from the Accept-Encoding header.
9
+ * Identity participates in the same quality comparison as the supported codings:
10
+ * a higher-q identity selects identity, and equal-q ties break in server order
11
+ * br, gzip, identity. Identity defaults to acceptable unless explicitly refused
12
+ * with `identity;q=0` or a `*;q=0` wildcard without a more specific identity
13
+ * entry, and an explicit coding entry beats the wildcard.
14
+ * @param {string | null | undefined} acceptEncoding - Accept-Encoding header value.
15
+ * @returns {{encoding: "br" | "gzip" | "identity", identityAcceptable: boolean} | {notAcceptable: true}} - Negotiated coding, or that no acceptable representation exists.
16
+ */
17
+ export function negotiateContentEncoding(acceptEncoding: string | null | undefined): {
18
+ encoding: "br" | "gzip" | "identity";
19
+ identityAcceptable: boolean;
20
+ } | {
21
+ notAcceptable: true;
22
+ };
23
+ /**
24
+ * Runs is compressible content type.
25
+ * @param {string} contentType - Content-Type header value.
26
+ * @returns {boolean} - Whether the media type is on the compressible allowlist.
27
+ */
28
+ export function isCompressibleContentType(contentType: string): boolean;
29
+ /**
30
+ * Merges Accept-Encoding into the response Vary header case-insensitively and
31
+ * without duplicates. An existing `Vary: *` already covers every request header
32
+ * and is preserved as-is.
33
+ * @param {import("./response.js").default} response - Response instance.
34
+ * @returns {void} - No return value.
35
+ */
36
+ export function addAcceptEncodingToVary(response: import("./response.js").default): void;
37
+ /**
38
+ * Negotiates and applies compression to a buffered response body immediately before
39
+ * framing. Only string/Uint8Array responses reach this point; sendFile responses and
40
+ * bodyless statuses are excluded by the caller. Transformation is skipped for
41
+ * Cache-Control no-transform, non-allowlisted or pre-compressed media types,
42
+ * server-sent events, partial (206) responses, requests with a Range header,
43
+ * credentialed requests (Authorization/Cookie headers), responses carrying
44
+ * credentials or validators (Set-Cookie/ETag/Digest/Content-Digest/Content-Range
45
+ * headers), and per-response opt-outs; a skipped
46
+ * transformation is still sent as identity when the client accepts identity, and
47
+ * answered "not-acceptable" when it does not. Responses that already carry an
48
+ * application-supplied Content-Encoding are passed through unchanged and never
49
+ * negotiate. When the client forbids every representation (identity and all
50
+ * supported codings), the outcome is "not-acceptable".
51
+ * @param {object} args - Options object.
52
+ * @param {Buffer} args.bodyBuffer - Buffered response body bytes (UTF-8 encoded for string bodies).
53
+ * @param {import("../../configuration-types.js").NormalizedHttpCompressionConfiguration} args.compression - Normalized compression configuration.
54
+ * @param {import("./request.js").default | import("./websocket-request.js").default} args.request - Request object.
55
+ * @param {import("./response.js").default} args.response - Response instance.
56
+ * @returns {Promise<{outcome: "identity"} | {outcome: "compressed", body: Buffer} | {outcome: "not-acceptable"}>} - Compression outcome.
57
+ */
58
+ export function applyResponseCompression({ bodyBuffer, compression, request, response }: {
59
+ bodyBuffer: Buffer;
60
+ compression: import("../../configuration-types.js").NormalizedHttpCompressionConfiguration;
61
+ request: import("./request.js").default | import("./websocket-request.js").default;
62
+ response: import("./response.js").default;
63
+ }): Promise<{
64
+ outcome: "identity";
65
+ } | {
66
+ outcome: "compressed";
67
+ body: Buffer;
68
+ } | {
69
+ outcome: "not-acceptable";
70
+ }>;
71
+ //# sourceMappingURL=response-compression.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"response-compression.d.ts","sourceRoot":"","sources":["../../../../src/http-server/client/response-compression.js"],"names":[],"mappings":"AA4BA;;;;GAIG;AACH,iDAHW,MAAM,GACJ,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA8B/B;AAED;;;;;;;;;GASG;AACH,yDAHW,MAAM,GAAG,IAAI,GAAG,SAAS,GACvB;IAAC,QAAQ,EAAE,IAAI,GAAG,MAAM,GAAG,UAAU,CAAC;IAAC,kBAAkB,EAAE,OAAO,CAAA;CAAC,GAAG;IAAC,aAAa,EAAE,IAAI,CAAA;CAAC,CAyBvG;AAED;;;;GAIG;AACH,uDAHW,MAAM,GACJ,OAAO,CAcnB;AAED;;;;;;GAMG;AACH,kDAHW,OAAO,eAAe,EAAE,OAAO,GAC7B,IAAI,CAmBhB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,yFANG;IAAqB,UAAU,EAAvB,MAAM;IAC8E,WAAW,EAA/F,OAAO,8BAA8B,EAAE,sCAAsC;IACG,OAAO,EAAvF,OAAO,cAAc,EAAE,OAAO,GAAG,OAAO,wBAAwB,EAAE,OAAO;IACnC,QAAQ,EAA9C,OAAO,eAAe,EAAE,OAAO;CACvC,GAAU,OAAO,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAC,GAAG;IAAC,OAAO,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAC,GAAG;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAC,CAAC,CA6DhH"}
@@ -0,0 +1,197 @@
1
+ // @ts-check
2
+ import zlib from "node:zlib";
3
+ import { promisify } from "node:util";
4
+ const brotliCompressAsync = promisify(zlib.brotliCompress);
5
+ const gzipAsync = promisify(zlib.gzip);
6
+ /**
7
+ * Exact media types (beyond the text/*, *+json, and *+xml families) that are worth compressing.
8
+ * Everything else — unknown binary types and commonly pre-compressed media such as images,
9
+ * video, and archives — is left untouched by the conservative allowlist.
10
+ * @type {Set<string>} */
11
+ const COMPRESSIBLE_EXACT_MEDIA_TYPES = new Set([
12
+ "application/ecmascript",
13
+ "application/javascript",
14
+ "application/json",
15
+ "application/x-javascript",
16
+ "application/xml",
17
+ "image/svg+xml"
18
+ ]);
19
+ /**
20
+ * RFC 9110 §12.4.2 qvalue grammar: `0` or `1` with at most three fractional
21
+ * digits, and only zeros after `1`.
22
+ * @type {RegExp} */
23
+ const QVALUE_PATTERN = /^(?:0(?:\.\d{1,3})?|1(?:\.0{1,3})?)$/u;
24
+ /**
25
+ * Runs parse accept encoding.
26
+ * @param {string} headerValue - Accept-Encoding header value.
27
+ * @returns {Map<string, number>} - Lowercased coding to q-value (0-1).
28
+ */
29
+ export function parseAcceptEncoding(headerValue) {
30
+ /** @type {Map<string, number>} */
31
+ const codings = new Map();
32
+ for (const part of headerValue.split(",")) {
33
+ const [codingToken, ...parameters] = part.split(";");
34
+ const coding = codingToken?.trim().toLowerCase();
35
+ if (!coding)
36
+ continue;
37
+ let q = 1;
38
+ for (const parameter of parameters) {
39
+ const [name, value] = parameter.split("=");
40
+ if (name?.trim().toLowerCase() != "q")
41
+ continue;
42
+ const qvalue = value?.trim() || "";
43
+ // A malformed q-value (e.g. `.5`, `01`, `1.001`, more than three fractional
44
+ // digits, or empty) is treated as "not acceptable" (q=0), per RFC 9110 §12.4.2.
45
+ q = QVALUE_PATTERN.test(qvalue) ? Number(qvalue) : 0;
46
+ }
47
+ codings.set(coding, q);
48
+ }
49
+ return codings;
50
+ }
51
+ /**
52
+ * Negotiates the content coding for a response from the Accept-Encoding header.
53
+ * Identity participates in the same quality comparison as the supported codings:
54
+ * a higher-q identity selects identity, and equal-q ties break in server order
55
+ * br, gzip, identity. Identity defaults to acceptable unless explicitly refused
56
+ * with `identity;q=0` or a `*;q=0` wildcard without a more specific identity
57
+ * entry, and an explicit coding entry beats the wildcard.
58
+ * @param {string | null | undefined} acceptEncoding - Accept-Encoding header value.
59
+ * @returns {{encoding: "br" | "gzip" | "identity", identityAcceptable: boolean} | {notAcceptable: true}} - Negotiated coding, or that no acceptable representation exists.
60
+ */
61
+ export function negotiateContentEncoding(acceptEncoding) {
62
+ if (acceptEncoding === undefined || acceptEncoding === null || acceptEncoding.trim() === "") {
63
+ return { encoding: "identity", identityAcceptable: true };
64
+ }
65
+ const codings = parseAcceptEncoding(acceptEncoding);
66
+ const wildcardQ = codings.get("*");
67
+ const identityQ = codings.get("identity") ?? wildcardQ ?? 1;
68
+ // Declared in server preference order; the stable sort keeps this order for ties.
69
+ /** @type {Array<{coding: "br" | "gzip" | "identity", q: number}>} */
70
+ const candidates = [
71
+ { coding: "br", q: codings.get("br") ?? wildcardQ ?? 0 },
72
+ { coding: "gzip", q: codings.get("gzip") ?? wildcardQ ?? 0 },
73
+ { coding: "identity", q: identityQ }
74
+ ];
75
+ const selected = candidates
76
+ .filter((candidate) => candidate.q > 0)
77
+ .sort((a, b) => b.q - a.q)[0];
78
+ if (!selected)
79
+ return { notAcceptable: true };
80
+ return { encoding: selected.coding, identityAcceptable: identityQ > 0 };
81
+ }
82
+ /**
83
+ * Runs is compressible content type.
84
+ * @param {string} contentType - Content-Type header value.
85
+ * @returns {boolean} - Whether the media type is on the compressible allowlist.
86
+ */
87
+ export function isCompressibleContentType(contentType) {
88
+ const mediaType = contentType.split(";")[0]?.trim().toLowerCase();
89
+ if (!mediaType)
90
+ return false;
91
+ // Server-sent events are long-lived streams; buffering them for compression
92
+ // would break delivery, so they are excluded before the textual allowlist.
93
+ if (mediaType == "text/event-stream")
94
+ return false;
95
+ if (mediaType.startsWith("text/"))
96
+ return true;
97
+ if (mediaType.endsWith("+json") || mediaType.endsWith("+xml"))
98
+ return true;
99
+ return COMPRESSIBLE_EXACT_MEDIA_TYPES.has(mediaType);
100
+ }
101
+ /**
102
+ * Merges Accept-Encoding into the response Vary header case-insensitively and
103
+ * without duplicates. An existing `Vary: *` already covers every request header
104
+ * and is preserved as-is.
105
+ * @param {import("./response.js").default} response - Response instance.
106
+ * @returns {void} - No return value.
107
+ */
108
+ export function addAcceptEncodingToVary(response) {
109
+ for (const headerKey in response.headers) {
110
+ if (headerKey.toLowerCase() != "vary")
111
+ continue;
112
+ const values = response.headers[headerKey];
113
+ const tokens = values.flatMap((value) => value.split(",").map((token) => token.trim().toLowerCase()));
114
+ if (tokens.includes("*") || tokens.includes("accept-encoding"))
115
+ return;
116
+ if (values.length > 0) {
117
+ values[0] = `${values[0]}, Accept-Encoding`;
118
+ }
119
+ return;
120
+ }
121
+ response.setHeader("Vary", "Accept-Encoding");
122
+ }
123
+ /**
124
+ * Negotiates and applies compression to a buffered response body immediately before
125
+ * framing. Only string/Uint8Array responses reach this point; sendFile responses and
126
+ * bodyless statuses are excluded by the caller. Transformation is skipped for
127
+ * Cache-Control no-transform, non-allowlisted or pre-compressed media types,
128
+ * server-sent events, partial (206) responses, requests with a Range header,
129
+ * credentialed requests (Authorization/Cookie headers), responses carrying
130
+ * credentials or validators (Set-Cookie/ETag/Digest/Content-Digest/Content-Range
131
+ * headers), and per-response opt-outs; a skipped
132
+ * transformation is still sent as identity when the client accepts identity, and
133
+ * answered "not-acceptable" when it does not. Responses that already carry an
134
+ * application-supplied Content-Encoding are passed through unchanged and never
135
+ * negotiate. When the client forbids every representation (identity and all
136
+ * supported codings), the outcome is "not-acceptable".
137
+ * @param {object} args - Options object.
138
+ * @param {Buffer} args.bodyBuffer - Buffered response body bytes (UTF-8 encoded for string bodies).
139
+ * @param {import("../../configuration-types.js").NormalizedHttpCompressionConfiguration} args.compression - Normalized compression configuration.
140
+ * @param {import("./request.js").default | import("./websocket-request.js").default} args.request - Request object.
141
+ * @param {import("./response.js").default} args.response - Response instance.
142
+ * @returns {Promise<{outcome: "identity"} | {outcome: "compressed", body: Buffer} | {outcome: "not-acceptable"}>} - Compression outcome.
143
+ */
144
+ export async function applyResponseCompression({ bodyBuffer, compression, request, response }) {
145
+ if (!compression.enabled)
146
+ return { outcome: "identity" };
147
+ // Application-supplied encodings stay application-owned: they are passed through
148
+ // unchanged and never take part in negotiation failure handling.
149
+ if (response.getHeader("Content-Encoding").length > 0)
150
+ return { outcome: "identity" };
151
+ const negotiated = negotiateContentEncoding(request.header("accept-encoding"));
152
+ if ("notAcceptable" in negotiated)
153
+ return { outcome: "not-acceptable" };
154
+ const cacheControlTokens = response.getHeader("Cache-Control")
155
+ .flatMap((value) => value.split(","))
156
+ .map((token) => token.trim().toLowerCase());
157
+ const contentType = response.getHeader("Content-Type")[0];
158
+ // Automatic security exclusions: credentialed requests (Authorization/Cookie) and
159
+ // responses carrying credentials (Set-Cookie) or representation validators
160
+ // (ETag/Digest/Content-Digest) are never transformed — compression could leak
161
+ // secret-bearing content through a compression oracle, and validators stay
162
+ // application-owned rather than being recomputed for encoded variants.
163
+ const transformable = !response.isCompressionDisabled() &&
164
+ response.getStatusCode() !== 206 &&
165
+ !request.header("range") &&
166
+ !request.header("authorization") &&
167
+ !request.header("cookie") &&
168
+ response.getHeader("Content-Range").length === 0 &&
169
+ response.getHeader("Set-Cookie").length === 0 &&
170
+ response.getHeader("ETag").length === 0 &&
171
+ response.getHeader("Digest").length === 0 &&
172
+ response.getHeader("Content-Digest").length === 0 &&
173
+ !cacheControlTokens.includes("no-transform") &&
174
+ contentType !== undefined &&
175
+ isCompressibleContentType(contentType);
176
+ if (!transformable) {
177
+ // A skipped transformation may still go out as identity when the client accepts
178
+ // identity; when identity is forbidden, no acceptable representation can be sent.
179
+ return negotiated.identityAcceptable ? { outcome: "identity" } : { outcome: "not-acceptable" };
180
+ }
181
+ // The representation now depends on the request's Accept-Encoding, even when this
182
+ // particular response ends up identity (missing header, higher-q identity, below threshold).
183
+ addAcceptEncodingToVary(response);
184
+ if (negotiated.encoding == "identity")
185
+ return { outcome: "identity" };
186
+ // Below the threshold the smaller identity representation is sent instead — but only
187
+ // when identity is acceptable; a client that forbids identity must never be forced
188
+ // onto an unacceptable representation by the size check.
189
+ if (bodyBuffer.length < compression.threshold && negotiated.identityAcceptable)
190
+ return { outcome: "identity" };
191
+ const body = negotiated.encoding == "br"
192
+ ? await brotliCompressAsync(bodyBuffer, { params: { [zlib.constants.BROTLI_PARAM_QUALITY]: compression.brotliQuality } })
193
+ : await gzipAsync(bodyBuffer, { level: compression.gzipLevel });
194
+ response.setHeader("Content-Encoding", negotiated.encoding);
195
+ return { body, outcome: "compressed" };
196
+ }
197
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzcG9uc2UtY29tcHJlc3Npb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaHR0cC1zZXJ2ZXIvY2xpZW50L3Jlc3BvbnNlLWNvbXByZXNzaW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLElBQUksTUFBTSxXQUFXLENBQUE7QUFDNUIsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUVuQyxNQUFNLG1CQUFtQixHQUFHLFNBQVMsQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLENBQUE7QUFDMUQsTUFBTSxTQUFTLEdBQUcsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQTtBQUV0Qzs7Ozt5QkFJeUI7QUFDekIsTUFBTSw4QkFBOEIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUM3Qyx3QkFBd0I7SUFDeEIsd0JBQXdCO0lBQ3hCLGtCQUFrQjtJQUNsQiwwQkFBMEI7SUFDMUIsaUJBQWlCO0lBQ2pCLGVBQWU7Q0FDaEIsQ0FBQyxDQUFBO0FBRUY7OztvQkFHb0I7QUFDcEIsTUFBTSxjQUFjLEdBQUcsdUNBQXVDLENBQUE7QUFFOUQ7Ozs7R0FJRztBQUNILE1BQU0sVUFBVSxtQkFBbUIsQ0FBQyxXQUFXO0lBQzdDLGtDQUFrQztJQUNsQyxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFBO0lBRXpCLEtBQUssTUFBTSxJQUFJLElBQUksV0FBVyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQzFDLE1BQU0sQ0FBQyxXQUFXLEVBQUUsR0FBRyxVQUFVLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQ3BELE1BQU0sTUFBTSxHQUFHLFdBQVcsRUFBRSxJQUFJLEVBQUUsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtRQUVoRCxJQUFJLENBQUMsTUFBTTtZQUFFLFNBQVE7UUFFckIsSUFBSSxDQUFD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U0FBUyxJQUFJLFVBQVUsQ0FBQyxrQkFBa0I7UUFBRSxPQUFPLEVBQUMsT0FBTyxFQUFFLFVBQVUsRUFBQyxDQUFBO0lBRTVHLE1BQU0sSUFBSSxHQUFHLFVBQVUsQ0FBQyxRQUFRLElBQUksSUFBSTtRQUN0QyxDQUFDLENBQUMsTUFBTSxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsRUFBQyxNQUFNLEVBQUUsRUFBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsb0JBQW9CLENBQUMsRUFBRSxXQUFXLENBQUMsYUFBYSxFQUFDLEVBQUMsQ0FBQztRQUNySCxDQUFDLENBQUMsTUFBTSxTQUFTLENBQUMsVUFBVSxFQUFFLEVBQUMsS0FBSyxFQUFFLFdBQVcsQ0FBQyxTQUFTLEVBQUMsQ0FBQyxDQUFBO0lBRS9ELFFBQVEsQ0FBQyxTQUFTLENBQUMsa0JBQWtCLEVBQUUsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBRTNELE9BQU8sRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBQyxDQUFBO0FBQ3RDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHpsaWIgZnJvbSBcIm5vZGU6emxpYlwiXG5pbXBvcnQge3Byb21pc2lmeX0gZnJvbSBcIm5vZGU6dXRpbFwiXG5cbmNvbnN0IGJyb3RsaUNvbXByZXNzQXN5bmMgPSBwcm9taXNpZnkoemxpYi5icm90bGlDb21wcmVzcylcbmNvbnN0IGd6aXBBc3luYyA9IHByb21pc2lmeSh6bGliLmd6aXApXG5cbi8qKlxuICogRXhhY3QgbWVkaWEgdHlwZXMgKGJleW9uZCB0aGUgdGV4dC8qLCAqK2pzb24sIGFuZCAqK3htbCBmYW1pbGllcykgdGhhdCBhcmUgd29ydGggY29tcHJlc3NpbmcuXG4gKiBFdmVyeXRoaW5nIGVsc2Ug4oCUIHVua25vd24gYmluYXJ5IHR5cGVzIGFuZCBjb21tb25seSBwcmUtY29tcHJlc3NlZCBtZWRpYSBzdWNoIGFzIGltYWdlcyxcbiAqIHZpZGVvLCBhbmQgYXJjaGl2ZXMg4oCUIGlzIGxlZnQgdW50b3VjaGVkIGJ5IHRoZSBjb25zZXJ2YXRpdmUgYWxsb3dsaXN0LlxuICogQHR5cGUge1NldDxzdHJpbmc+fSAqL1xuY29uc3QgQ09NUFJFU1NJQkxFX0VYQUNUX01FRElBX1RZUEVTID0gbmV3IFNldChbXG4gIFwiYXBwbGljYXRpb24vZWNtYXNjcmlwdFwiLFxuICBcImFwcGxpY2F0aW9uL2phdmFzY3JpcHRcIixcbiAgXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gIFwiYXBwbGljYXRpb24veC1qYXZhc2NyaXB0XCIsXG4gIFwiYXBwbGljYXRpb24veG1sXCIsXG4gIFwiaW1hZ2Uvc3ZnK3htbFwiXG5dKVxuXG4vKipcbiAqIFJGQyA5MTEwIMKnMTIuNC4yIHF2YWx1ZSBncmFtbWFyOiBgMGAgb3IgYDFgIHdpdGggYXQgbW9zdCB0aHJlZSBmcmFjdGlvbmFsXG4gKiBkaWdpdHMsIGFuZCBvbmx5IHplcm9zIGFmdGVyIGAxYC5cbiAqIEB0eXBlIHtSZWdFeHB9ICovXG5jb25zdCBRVkFMVUVfUEFUVEVSTiA9IC9eKD86MCg/OlxcLlxcZHsxLDN9KT98MSg/OlxcLjB7MSwzfSk/KSQvdVxuXG4vKipcbiAqIFJ1bnMgcGFyc2UgYWNjZXB0IGVuY29kaW5nLlxuICogQHBhcmFtIHtzdHJpbmd9IGhlYWRlclZhbHVlIC0gQWNjZXB0LUVuY29kaW5nIGhlYWRlciB2YWx1ZS5cbiAqIEByZXR1cm5zIHtNYXA8c3RyaW5nLCBudW1iZXI+fSAtIExvd2VyY2FzZWQgY29kaW5nIHRvIHEtdmFsdWUgKDAtMSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUFjY2VwdEVuY29kaW5nKGhlYWRlclZhbHVlKSB7XG4gIC8qKiBAdHlwZSB7TWFwPHN0cmluZywgbnVtYmVyPn0gKi9cbiAgY29uc3QgY29kaW5ncyA9IG5ldyBNYXAoKVxuXG4gIGZvciAoY29uc3QgcGFydCBvZiBoZWFkZXJWYWx1ZS5zcGxpdChcIixcIikpIHtcbiAgICBjb25zdCBbY29kaW5nVG9rZW4sIC4uLnBhcmFtZXRlcnNdID0gcGFydC5zcGxpdChcIjtcIilcbiAgICBjb25zdCBjb2RpbmcgPSBjb2RpbmdUb2tlbj8udHJpbSgpLnRvTG93ZXJDYXNlKClcblxuICAgIGlmICghY29kaW5nKSBjb250aW51ZVxuXG4gICAgbGV0IHEgPSAxXG5cbiAgICBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBwYXJhbWV0ZXJzKSB7XG4gICAgICBjb25zdCBbbmFtZSwgdmFsdWVdID0gcGFyYW1ldGVyLnNwbGl0KFwiPVwiKVxuXG4gICAgICBpZiAobmFtZT8udHJpbSgpLnRvTG93ZXJDYXNlKCkgIT0gXCJxXCIpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHF2YWx1ZSA9IHZhbHVlPy50cmltKCkgfHwgXCJcIlxuXG4gICAgICAvLyBBIG1hbGZvcm1lZCBxLXZhbHVlIChlLmcuIGAuNWAsIGAwMWAsIGAxLjAwMWAsIG1vcmUgdGhhbiB0aHJlZSBmcmFjdGlvbmFsXG4gICAgICAvLyBkaWdpdHMsIG9yIGVtcHR5KSBpcyB0cmVhdGVkIGFzIFwibm90IGFjY2VwdGFibGVcIiAocT0wKSwgcGVyIFJGQyA5MTEwIMKnMTIuNC4yLlxuICAgICAgcSA9IFFWQUxVRV9QQVRURVJOLnRlc3QocXZhbHVlKSA/IE51bWJlcihxdmFsdWUpIDogMFxuICAgIH1cblxuICAgIGNvZGluZ3Muc2V0KGNvZGluZywgcSlcbiAgfVxuXG4gIHJldHVybiBjb2RpbmdzXG59XG5cbi8qKlxuICogTmVnb3RpYXRlcyB0aGUgY29udGVudCBjb2RpbmcgZm9yIGEgcmVzcG9uc2UgZnJvbSB0aGUgQWNjZXB0LUVuY29kaW5nIGhlYWRlci5cbiAqIElkZW50aXR5IHBhcnRpY2lwYXRlcyBpbiB0aGUgc2FtZSBxdWFsaXR5IGNvbXBhcmlzb24gYXMgdGhlIHN1cHBvcnRlZCBjb2RpbmdzOlxuICogYSBoaWdoZXItcSBpZGVudGl0eSBzZWxlY3RzIGlkZW50aXR5LCBhbmQgZXF1YWwtcSB0aWVzIGJyZWFrIGluIHNlcnZlciBvcmRlclxuICogYnIsIGd6aXAsIGlkZW50aXR5LiBJZGVudGl0eSBkZWZhdWx0cyB0byBhY2NlcHRhYmxlIHVubGVzcyBleHBsaWNpdGx5IHJlZnVzZWRcbiAqIHdpdGggYGlkZW50aXR5O3E9MGAgb3IgYSBgKjtxPTBgIHdpbGRjYXJkIHdpdGhvdXQgYSBtb3JlIHNwZWNpZmljIGlkZW50aXR5XG4gKiBlbnRyeSwgYW5kIGFuIGV4cGxpY2l0IGNvZGluZyBlbnRyeSBiZWF0cyB0aGUgd2lsZGNhcmQuXG4gKiBAcGFyYW0ge3N0cmluZyB8IG51bGwgfCB1bmRlZmluZWR9IGFjY2VwdEVuY29kaW5nIC0gQWNjZXB0LUVuY29kaW5nIGhlYWRlciB2YWx1ZS5cbiAqIEByZXR1cm5zIHt7ZW5jb2Rpbmc6IFwiYnJcIiB8IFwiZ3ppcFwiIHwgXCJpZGVudGl0eVwiLCBpZGVudGl0eUFjY2VwdGFibGU6IGJvb2xlYW59IHwge25vdEFjY2VwdGFibGU6IHRydWV9fSAtIE5lZ290aWF0ZWQgY29kaW5nLCBvciB0aGF0IG5vIGFjY2VwdGFibGUgcmVwcmVzZW50YXRpb24gZXhpc3RzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbmVnb3RpYXRlQ29udGVudEVuY29kaW5nKGFjY2VwdEVuY29kaW5nKSB7XG4gIGlmIChhY2NlcHRFbmNvZGluZyA9PT0gdW5kZWZpbmVkIHx8IGFjY2VwdEVuY29kaW5nID09PSBudWxsIHx8IGFjY2VwdEVuY29kaW5nLnRyaW0oKSA9PT0gXCJcIikge1xuICAgIHJldHVybiB7ZW5jb2Rpbmc6IFwiaWRlbnRpdHlcIiwgaWRlbnRpdHlBY2NlcHRhYmxlOiB0cnVlfVxuICB9XG5cbiAgY29uc3QgY29kaW5ncyA9IHBhcnNlQWNjZXB0RW5jb2RpbmcoYWNjZXB0RW5jb2RpbmcpXG4gIGNvbnN0IHdpbGRjYXJkUSA9IGNvZGluZ3MuZ2V0KFwiKlwiKVxuICBjb25zdCBpZGVudGl0eVEgPSBjb2RpbmdzLmdldChcImlkZW50aXR5XCIpID8/IHdpbGRjYXJkUSA/PyAxXG5cbiAgLy8gRGVjbGFyZWQgaW4gc2VydmVyIHByZWZlcmVuY2Ugb3JkZXI7IHRoZSBzdGFibGUgc29ydCBrZWVwcyB0aGlzIG9yZGVyIGZvciB0aWVzLlxuICAvKiogQHR5cGUge0FycmF5PHtjb2Rpbmc6IFwiYnJcIiB8IFwiZ3ppcFwiIHwgXCJpZGVudGl0eVwiLCBxOiBudW1iZXJ9Pn0gKi9cbiAgY29uc3QgY2FuZGlkYXRlcyA9IFtcbiAgICB7Y29kaW5nOiBcImJyXCIsIHE6IGNvZGluZ3MuZ2V0KFwiYnJcIikgPz8gd2lsZGNhcmRRID8/IDB9LFxuICAgIHtjb2Rpbmc6IFwiZ3ppcFwiLCBxOiBjb2RpbmdzLmdldChcImd6aXBcIikgPz8gd2lsZGNhcmRRID8/IDB9LFxuICAgIHtjb2Rpbmc6IFwiaWRlbnRpdHlcIiwgcTogaWRlbnRpdHlRfVxuICBdXG4gIGNvbnN0IHNlbGVjdGVkID0gY2FuZGlkYXRlc1xuICAgIC5maWx0ZXIoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLnEgPiAwKVxuICAgIC5zb3J0KChhLCBiKSA9PiBiLnEgLSBhLnEpWzBdXG5cbiAgaWYgKCFzZWxlY3RlZCkgcmV0dXJuIHtub3RBY2NlcHRhYmxlOiB0cnVlfVxuXG4gIHJldHVybiB7ZW5jb2Rpbmc6IHNlbGVjdGVkLmNvZGluZywgaWRlbnRpdHlBY2NlcHRhYmxlOiBpZGVudGl0eVEgPiAwfVxufVxuXG4vKipcbiAqIFJ1bnMgaXMgY29tcHJlc3NpYmxlIGNvbnRlbnQgdHlwZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBjb250ZW50VHlwZSAtIENvbnRlbnQtVHlwZSBoZWFkZXIgdmFsdWUuXG4gKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBtZWRpYSB0eXBlIGlzIG9uIHRoZSBjb21wcmVzc2libGUgYWxsb3dsaXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb21wcmVzc2libGVDb250ZW50VHlwZShjb250ZW50VHlwZSkge1xuICBjb25zdCBtZWRpYVR5cGUgPSBjb250ZW50VHlwZS5zcGxpdChcIjtcIilbMF0/LnRyaW0oKS50b0xvd2VyQ2FzZSgpXG5cbiAgaWYgKCFtZWRpYVR5cGUpIHJldHVybiBmYWxzZVxuXG4gIC8vIFNlcnZlci1zZW50IGV2ZW50cyBhcmUgbG9uZy1saXZlZCBzdHJlYW1zOyBidWZmZXJpbmcgdGhlbSBmb3IgY29tcHJlc3Npb25cbiAgLy8gd291bGQgYnJlYWsgZGVsaXZlcnksIHNvIHRoZXkgYXJlIGV4Y2x1ZGVkIGJlZm9yZSB0aGUgdGV4dHVhbCBhbGxvd2xpc3QuXG4gIGlmIChtZWRpYVR5cGUgPT0gXCJ0ZXh0L2V2ZW50LXN0cmVhbVwiKSByZXR1cm4gZmFsc2VcbiAgaWYgKG1lZGlhVHlwZS5zdGFydHNXaXRoKFwidGV4dC9cIikpIHJldHVybiB0cnVlXG4gIGlmIChtZWRpYVR5cGUuZW5kc1dpdGgoXCIranNvblwiKSB8fCBtZWRpYVR5cGUuZW5kc1dpdGgoXCIreG1sXCIpKSByZXR1cm4gdHJ1ZVxuXG4gIHJldHVybiBDT01QUkVTU0lCTEVfRVhBQ1RfTUVESUFfVFlQRVMuaGFzKG1lZGlhVHlwZSlcbn1cblxuLyoqXG4gKiBNZXJnZXMgQWNjZXB0LUVuY29kaW5nIGludG8gdGhlIHJlc3BvbnNlIFZhcnkgaGVhZGVyIGNhc2UtaW5zZW5zaXRpdmVseSBhbmRcbiAqIHdpdGhvdXQgZHVwbGljYXRlcy4gQW4gZXhpc3RpbmcgYFZhcnk6ICpgIGFscmVhZHkgY292ZXJzIGV2ZXJ5IHJlcXVlc3QgaGVhZGVyXG4gKiBhbmQgaXMgcHJlc2VydmVkIGFzLWlzLlxuICogQHBhcmFtIHtpbXBvcnQoXCIuL3Jlc3BvbnNlLmpzXCIpLmRlZmF1bHR9IHJlc3BvbnNlIC0gUmVzcG9uc2UgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZGRBY2NlcHRFbmNvZGluZ1RvVmFyeShyZXNwb25zZSkge1xuICBmb3IgKGNvbnN0IGhlYWRlcktleSBpbiByZXNwb25zZS5oZWFkZXJzKSB7XG4gICAgaWYgKGhlYWRlcktleS50b0xvd2VyQ2FzZSgpICE9IFwidmFyeVwiKSBjb250aW51ZVxuXG4gICAgY29uc3QgdmFsdWVzID0gcmVzcG9uc2UuaGVhZGVyc1toZWFkZXJLZXldXG4gICAgY29uc3QgdG9rZW5zID0gdmFsdWVzLmZsYXRNYXAoKHZhbHVlKSA9PiB2YWx1ZS5zcGxpdChcIixcIikubWFwKCh0b2tlbikgPT4gdG9rZW4udHJpbSgpLnRvTG93ZXJDYXNlKCkpKVxuXG4gICAgaWYgKHRva2Vucy5pbmNsdWRlcyhcIipcIikgfHwgdG9rZW5zLmluY2x1ZGVzKFwiYWNjZXB0LWVuY29kaW5nXCIpKSByZXR1cm5cblxuICAgIGlmICh2YWx1ZXMubGVuZ3RoID4gMCkge1xuICAgICAgdmFsdWVzWzBdID0gYCR7dmFsdWVzWzBdfSwgQWNjZXB0LUVuY29kaW5nYFxuICAgIH1cblxuICAgIHJldHVyblxuICB9XG5cbiAgcmVzcG9uc2Uuc2V0SGVhZGVyKFwiVmFyeVwiLCBcIkFjY2VwdC1FbmNvZGluZ1wiKVxufVxuXG4vKipcbiAqIE5lZ290aWF0ZXMgYW5kIGFwcGxpZXMgY29tcHJlc3Npb24gdG8gYSBidWZmZXJlZCByZXNwb25zZSBib2R5IGltbWVkaWF0ZWx5IGJlZm9yZVxuICogZnJhbWluZy4gT25seSBzdHJpbmcvVWludDhBcnJheSByZXNwb25zZXMgcmVhY2ggdGhpcyBwb2ludDsgc2VuZEZpbGUgcmVzcG9uc2VzIGFuZFxuICogYm9keWxlc3Mgc3RhdHVzZXMgYXJlIGV4Y2x1ZGVkIGJ5IHRoZSBjYWxsZXIuIFRyYW5zZm9ybWF0aW9uIGlzIHNraXBwZWQgZm9yXG4gKiBDYWNoZS1Db250cm9sIG5vLXRyYW5zZm9ybSwgbm9uLWFsbG93bGlzdGVkIG9yIHByZS1jb21wcmVzc2VkIG1lZGlhIHR5cGVzLFxuICogc2VydmVyLXNlbnQgZXZlbnRzLCBwYXJ0aWFsICgyMDYpIHJlc3BvbnNlcywgcmVxdWVzdHMgd2l0aCBhIFJhbmdlIGhlYWRlcixcbiAqIGNyZWRlbnRpYWxlZCByZXF1ZXN0cyAoQXV0aG9yaXphdGlvbi9Db29raWUgaGVhZGVycyksIHJlc3BvbnNlcyBjYXJyeWluZ1xuICogY3JlZGVudGlhbHMgb3IgdmFsaWRhdG9ycyAoU2V0LUNvb2tpZS9FVGFnL0RpZ2VzdC9Db250ZW50LURpZ2VzdC9Db250ZW50LVJhbmdlXG4gKiBoZWFkZXJzKSwgYW5kIHBlci1yZXNwb25zZSBvcHQtb3V0czsgYSBza2lwcGVkXG4gKiB0cmFuc2Zvcm1hdGlvbiBpcyBzdGlsbCBzZW50IGFzIGlkZW50aXR5IHdoZW4gdGhlIGNsaWVudCBhY2NlcHRzIGlkZW50aXR5LCBhbmRcbiAqIGFuc3dlcmVkIFwibm90LWFjY2VwdGFibGVcIiB3aGVuIGl0IGRvZXMgbm90LiBSZXNwb25zZXMgdGhhdCBhbHJlYWR5IGNhcnJ5IGFuXG4gKiBhcHBsaWNhdGlvbi1zdXBwbGllZCBDb250ZW50LUVuY29kaW5nIGFyZSBwYXNzZWQgdGhyb3VnaCB1bmNoYW5nZWQgYW5kIG5ldmVyXG4gKiBuZWdvdGlhdGUuIFdoZW4gdGhlIGNsaWVudCBmb3JiaWRzIGV2ZXJ5IHJlcHJlc2VudGF0aW9uIChpZGVudGl0eSBhbmQgYWxsXG4gKiBzdXBwb3J0ZWQgY29kaW5ncyksIHRoZSBvdXRjb21lIGlzIFwibm90LWFjY2VwdGFibGVcIi5cbiAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gKiBAcGFyYW0ge0J1ZmZlcn0gYXJncy5ib2R5QnVmZmVyIC0gQnVmZmVyZWQgcmVzcG9uc2UgYm9keSBieXRlcyAoVVRGLTggZW5jb2RlZCBmb3Igc3RyaW5nIGJvZGllcykuXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuTm9ybWFsaXplZEh0dHBDb21wcmVzc2lvbkNvbmZpZ3VyYXRpb259IGFyZ3MuY29tcHJlc3Npb24gLSBOb3JtYWxpemVkIGNvbXByZXNzaW9uIGNvbmZpZ3VyYXRpb24uXG4gKiBAcGFyYW0ge2ltcG9ydChcIi4vcmVxdWVzdC5qc1wiKS5kZWZhdWx0IHwgaW1wb3J0KFwiLi93ZWJzb2NrZXQtcmVxdWVzdC5qc1wiKS5kZWZhdWx0fSBhcmdzLnJlcXVlc3QgLSBSZXF1ZXN0IG9iamVjdC5cbiAqIEBwYXJhbSB7aW1wb3J0KFwiLi9yZXNwb25zZS5qc1wiKS5kZWZhdWx0fSBhcmdzLnJlc3BvbnNlIC0gUmVzcG9uc2UgaW5zdGFuY2UuXG4gKiBAcmV0dXJucyB7UHJvbWlzZTx7b3V0Y29tZTogXCJpZGVudGl0eVwifSB8IHtvdXRjb21lOiBcImNvbXByZXNzZWRcIiwgYm9keTogQnVmZmVyfSB8IHtvdXRjb21lOiBcIm5vdC1hY2NlcHRhYmxlXCJ9Pn0gLSBDb21wcmVzc2lvbiBvdXRjb21lLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYXBwbHlSZXNwb25zZUNvbXByZXNzaW9uKHtib2R5QnVmZmVyLCBjb21wcmVzc2lvbiwgcmVxdWVzdCwgcmVzcG9uc2V9KSB7XG4gIGlmICghY29tcHJlc3Npb24uZW5hYmxlZCkgcmV0dXJuIHtvdXRjb21lOiBcImlkZW50aXR5XCJ9XG5cbiAgLy8gQXBwbGljYXRpb24tc3VwcGxpZWQgZW5jb2RpbmdzIHN0YXkgYXBwbGljYXRpb24tb3duZWQ6IHRoZXkgYXJlIHBhc3NlZCB0aHJvdWdoXG4gIC8vIHVuY2hhbmdlZCBhbmQgbmV2ZXIgdGFrZSBwYXJ0IGluIG5lZ290aWF0aW9uIGZhaWx1cmUgaGFuZGxpbmcuXG4gIGlmIChyZXNwb25zZS5nZXRIZWFkZXIoXCJDb250ZW50LUVuY29kaW5nXCIpLmxlbmd0aCA+IDApIHJldHVybiB7b3V0Y29tZTogXCJpZGVudGl0eVwifVxuXG4gIGNvbnN0IG5lZ290aWF0ZWQgPSBuZWdvdGlhdGVDb250ZW50RW5jb2RpbmcocmVxdWVzdC5oZWFkZXIoXCJhY2NlcHQtZW5jb2RpbmdcIikpXG5cbiAgaWYgKFwibm90QWNjZXB0YWJsZVwiIGluIG5lZ290aWF0ZWQpIHJldHVybiB7b3V0Y29tZTogXCJub3QtYWNjZXB0YWJsZVwifVxuXG4gIGNvbnN0IGNhY2hlQ29udHJvbFRva2VucyA9IHJlc3BvbnNlLmdldEhlYWRlcihcIkNhY2hlLUNvbnRyb2xcIilcbiAgICAuZmxhdE1hcCgodmFsdWUpID0+IHZhbHVlLnNwbGl0KFwiLFwiKSlcbiAgICAubWFwKCh0b2tlbikgPT4gdG9rZW4udHJpbSgpLnRvTG93ZXJDYXNlKCkpXG4gIGNvbnN0IGNvbnRlbnRUeXBlID0gcmVzcG9uc2UuZ2V0SGVhZGVyKFwiQ29udGVudC1UeXBlXCIpWzBdXG5cbiAgLy8gQXV0b21hdGljIHNlY3VyaXR5IGV4Y2x1c2lvbnM6IGNyZWRlbnRpYWxlZCByZXF1ZXN0cyAoQXV0aG9yaXphdGlvbi9Db29raWUpIGFuZFxuICAvLyByZXNwb25zZXMgY2FycnlpbmcgY3JlZGVudGlhbHMgKFNldC1Db29raWUpIG9yIHJlcHJlc2VudGF0aW9uIHZhbGlkYXRvcnNcbiAgLy8gKEVUYWcvRGlnZXN0L0NvbnRlbnQtRGlnZXN0KSBhcmUgbmV2ZXIgdHJhbnNmb3JtZWQg4oCUIGNvbXByZXNzaW9uIGNvdWxkIGxlYWtcbiAgLy8gc2VjcmV0LWJlYXJpbmcgY29udGVudCB0aHJvdWdoIGEgY29tcHJlc3Npb24gb3JhY2xlLCBhbmQgdmFsaWRhdG9ycyBzdGF5XG4gIC8vIGFwcGxpY2F0aW9uLW93bmVkIHJhdGhlciB0aGFuIGJlaW5nIHJlY29tcHV0ZWQgZm9yIGVuY29kZWQgdmFyaWFudHMuXG4gIGNvbnN0IHRyYW5zZm9ybWFibGUgPSAhcmVzcG9uc2UuaXNDb21wcmVzc2lvbkRpc2FibGVkKCkgJiZcbiAgICByZXNwb25zZS5nZXRTdGF0dXNDb2RlKCkgIT09IDIwNiAmJlxuICAgICFyZXF1ZXN0LmhlYWRlcihcInJhbmdlXCIpICYmXG4gICAgIXJlcXVlc3QuaGVhZGVyKFwiYXV0aG9yaXphdGlvblwiKSAmJlxuICAgICFyZXF1ZXN0LmhlYWRlcihcImNvb2tpZVwiKSAmJlxuICAgIHJlc3BvbnNlLmdldEhlYWRlcihcIkNvbnRlbnQtUmFuZ2VcIikubGVuZ3RoID09PSAwICYmXG4gICAgcmVzcG9uc2UuZ2V0SGVhZGVyKFwiU2V0LUNvb2tpZVwiKS5sZW5ndGggPT09IDAgJiZcbiAgICByZXNwb25zZS5nZXRIZWFkZXIoXCJFVGFnXCIpLmxlbmd0aCA9PT0gMCAmJlxuICAgIHJlc3BvbnNlLmdldEhlYWRlcihcIkRpZ2VzdFwiKS5sZW5ndGggPT09IDAgJiZcbiAgICByZXNwb25zZS5nZXRIZWFkZXIoXCJDb250ZW50LURpZ2VzdFwiKS5sZW5ndGggPT09IDAgJiZcbiAgICAhY2FjaGVDb250cm9sVG9rZW5zLmluY2x1ZGVzKFwibm8tdHJhbnNmb3JtXCIpICYmXG4gICAgY29udGVudFR5cGUgIT09IHVuZGVmaW5lZCAmJlxuICAgIGlzQ29tcHJlc3NpYmxlQ29udGVudFR5cGUoY29udGVudFR5cGUpXG5cbiAgaWYgKCF0cmFuc2Zvcm1hYmxlKSB7XG4gICAgLy8gQSBza2lwcGVkIHRyYW5zZm9ybWF0aW9uIG1heSBzdGlsbCBnbyBvdXQgYXMgaWRlbnRpdHkgd2hlbiB0aGUgY2xpZW50IGFjY2VwdHNcbiAgICAvLyBpZGVudGl0eTsgd2hlbiBpZGVudGl0eSBpcyBmb3JiaWRkZW4sIG5vIGFjY2VwdGFibGUgcmVwcmVzZW50YXRpb24gY2FuIGJlIHNlbnQuXG4gICAgcmV0dXJuIG5lZ290aWF0ZWQuaWRlbnRpdHlBY2NlcHRhYmxlID8ge291dGNvbWU6IFwiaWRlbnRpdHlcIn0gOiB7b3V0Y29tZTogXCJub3QtYWNjZXB0YWJsZVwifVxuICB9XG5cbiAgLy8gVGhlIHJlcHJlc2VudGF0aW9uIG5vdyBkZXBlbmRzIG9uIHRoZSByZXF1ZXN0J3MgQWNjZXB0LUVuY29kaW5nLCBldmVuIHdoZW4gdGhpc1xuICAvLyBwYXJ0aWN1bGFyIHJlc3BvbnNlIGVuZHMgdXAgaWRlbnRpdHkgKG1pc3NpbmcgaGVhZGVyLCBoaWdoZXItcSBpZGVudGl0eSwgYmVsb3cgdGhyZXNob2xkKS5cbiAgYWRkQWNjZXB0RW5jb2RpbmdUb1ZhcnkocmVzcG9uc2UpXG5cbiAgaWYgKG5lZ290aWF0ZWQuZW5jb2RpbmcgPT0gXCJpZGVudGl0eVwiKSByZXR1cm4ge291dGNvbWU6IFwiaWRlbnRpdHlcIn1cblxuICAvLyBCZWxvdyB0aGUgdGhyZXNob2xkIHRoZSBzbWFsbGVyIGlkZW50aXR5IHJlcHJlc2VudGF0aW9uIGlzIHNlbnQgaW5zdGVhZCDigJQgYnV0IG9ubHlcbiAgLy8gd2hlbiBpZGVudGl0eSBpcyBhY2NlcHRhYmxlOyBhIGNsaWVudCB0aGF0IGZvcmJpZHMgaWRlbnRpdHkgbXVzdCBuZXZlciBiZSBmb3JjZWRcbiAgLy8gb250byBhbiB1bmFjY2VwdGFibGUgcmVwcmVzZW50YXRpb24gYnkgdGhlIHNpemUgY2hlY2suXG4gIGlmIChib2R5QnVmZmVyLmxlbmd0aCA8IGNvbXByZXNzaW9uLnRocmVzaG9sZCAmJiBuZWdvdGlhdGVkLmlkZW50aXR5QWNjZXB0YWJsZSkgcmV0dXJuIHtvdXRjb21lOiBcImlkZW50aXR5XCJ9XG5cbiAgY29uc3QgYm9keSA9IG5lZ290aWF0ZWQuZW5jb2RpbmcgPT0gXCJiclwiXG4gICAgPyBhd2FpdCBicm90bGlDb21wcmVzc0FzeW5jKGJvZHlCdWZmZXIsIHtwYXJhbXM6IHtbemxpYi5jb25zdGFudHMuQlJPVExJX1BBUkFNX1FVQUxJVFldOiBjb21wcmVzc2lvbi5icm90bGlRdWFsaXR5fX0pXG4gICAgOiBhd2FpdCBnemlwQXN5bmMoYm9keUJ1ZmZlciwge2xldmVsOiBjb21wcmVzc2lvbi5nemlwTGV2ZWx9KVxuXG4gIHJlc3BvbnNlLnNldEhlYWRlcihcIkNvbnRlbnQtRW5jb2RpbmdcIiwgbmVnb3RpYXRlZC5lbmNvZGluZylcblxuICByZXR1cm4ge2JvZHksIG91dGNvbWU6IFwiY29tcHJlc3NlZFwifVxufVxuIl19
@@ -23,6 +23,10 @@ export default class VelociousHttpServerClientResponse {
23
23
  * Headers.
24
24
  * @type {Record<string, string[]>} */
25
25
  headers: Record<string, string[]>;
26
+ /**
27
+ * Whether compression has been disabled for this specific response.
28
+ * @type {boolean} */
29
+ compressionDisabled: boolean;
26
30
  configuration: import("../../configuration.js").default;
27
31
  _requestTimeoutMs: number | undefined;
28
32
  _requestTimeoutMsChangeHandler: ((timeoutSeconds: number | undefined) => void) | undefined;
@@ -40,6 +44,29 @@ export default class VelociousHttpServerClientResponse {
40
44
  * @returns {void} - No return value.
41
45
  */
42
46
  setHeader(key: string, value: string): void;
47
+ /**
48
+ * Returns every value set for a header, matched case-insensitively.
49
+ * @param {string} key - Header name.
50
+ * @returns {string[]} - Header values in insertion order.
51
+ */
52
+ getHeader(key: string): string[];
53
+ /**
54
+ * Removes every value set for a header, matched case-insensitively.
55
+ * @param {string} key - Header name.
56
+ * @returns {void} - No return value.
57
+ */
58
+ removeHeader(key: string): void;
59
+ /**
60
+ * Disables HTTP response compression for this specific response, even when the
61
+ * server is configured to compress buffered responses.
62
+ * @returns {void} - No return value.
63
+ */
64
+ disableCompression(): void;
65
+ /**
66
+ * Runs is compression disabled.
67
+ * @returns {boolean} - Whether compression has been disabled for this response.
68
+ */
69
+ isCompressionDisabled(): boolean;
43
70
  /**
44
71
  * Runs get body.
45
72
  * @returns {string | Uint8Array | null} - The body.
@@ -1 +1 @@
1
- {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../../src/http-server/client/response.js"],"names":[],"mappings":"AA+EA;IAqBE;;;;OAIG;IACH,+BAFG;QAAuD,aAAa,EAA5D,OAAO,wBAAwB,EAAE,OAAO;KAClD,EAKA;IA7BD;;4CAEwC;IACxC,MADU,MAAM,GAAG,UAAU,GAAG,IAAI,CACzB;IAEX;;+BAE2B;IAC3B,UADU,MAAM,GAAG,IAAI,CACR;IAEf;;oFAEgF;IAChF,gBADU,CAAC,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CACvD;IAErB;;0CAEsC;IACtC,SADU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CACtB;IAQV,wDAAkC;IAClC,sCAAkC;IAClC,kDAwJ0B,MAAM,GAAG,SAAS,KAAK,IAAI,cAxJN;IAGjD;;;;;OAKG;IACH,eAJW,MAAM,SACN,MAAM,GACJ,IAAI,CAQhB;IAED;;;;;OAKG;IACH,eAJW,MAAM,SACN,MAAM,GACJ,IAAI,CAIhB;IAED;;;OAGG;IACH,WAFa,MAAM,GAAG,UAAU,GAAG,IAAI,CAQtC;IAED;;;OAGG;IACH,iBAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,oBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,eAHW,MAAM,GAAG,UAAU,GACjB,IAAI,CAMhB;IAED;;;OAGG;IACH,eAFa,MAAM,GAAG,IAAI,CAIzB;IAED;;;OAGG;IACH,qBAFa,CAAC,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAI9E;IAED;;;;;OAKG;IACH,kBAJW,MAAM,eACN,CAAC,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAChE,IAAI,CAMhB;IAED;;;;OAIG;IACH,oBAHW,KAAK,GACH,IAAI,CAKhB;IAED;;;;;;;;OAQG;IACH,kBAHW,MAAM,GAAG,MAAM,GACb,IAAI,CAYhB;IAFC,+BAA+B;IAC/B,kCAAoE;IAGtE;;;OAGG;IACH,uBAFa,MAAM,GAAG,SAAS,CAI9B;IAED;;;;OAIG;IACH,oCAHW,MAAM,GAAG,SAAS,GAAG,IAAI,GACvB,IAAI,CAYhB;IAED;;;;OAIG;IACH,0CAHW,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,GAC1C,IAAI,CAIhB;CACF"}
1
+ {"version":3,"file":"response.d.ts","sourceRoot":"","sources":["../../../../src/http-server/client/response.js"],"names":[],"mappings":"AA+EA;IA0BE;;;;OAIG;IACH,+BAFG;QAAuD,aAAa,EAA5D,OAAO,wBAAwB,EAAE,OAAO;KAClD,EAKA;IAlCD;;4CAEwC;IACxC,MADU,MAAM,GAAG,UAAU,GAAG,IAAI,CACzB;IAEX;;+BAE2B;IAC3B,UADU,MAAM,GAAG,IAAI,CACR;IAEf;;oFAEgF;IAChF,gBADU,CAAC,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CACvD;IAErB;;0CAEsC;IACtC,SADU,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CACtB;IAEZ;;yBAEqB;IACrB,qBADU,OAAO,CACU;IAQzB,wDAAkC;IAClC,sCAAkC;IAClC,kDA4M0B,MAAM,GAAG,SAAS,KAAK,IAAI,cA5MN;IAGjD;;;;;OAKG;IACH,eAJW,MAAM,SACN,MAAM,GACJ,IAAI,CAQhB;IAED;;;;;OAKG;IACH,eAJW,MAAM,SACN,MAAM,GACJ,IAAI,CAIhB;IAED;;;;OAIG;IACH,eAHW,MAAM,GACJ,MAAM,EAAE,CAepB;IAED;;;;OAIG;IACH,kBAHW,MAAM,GACJ,IAAI,CAUhB;IAED;;;;OAIG;IACH,sBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,yBAFa,OAAO,CAInB;IAED;;;OAGG;IACH,WAFa,MAAM,GAAG,UAAU,GAAG,IAAI,CAQtC;IAED;;;OAGG;IACH,iBAFa,MAAM,CAIlB;IAED;;;OAGG;IACH,oBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,eAHW,MAAM,GAAG,UAAU,GACjB,IAAI,CAMhB;IAED;;;OAGG;IACH,eAFa,MAAM,GAAG,IAAI,CAIzB;IAED;;;OAGG;IACH,qBAFa,CAAC,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,CAI9E;IAED;;;;;OAKG;IACH,kBAJW,MAAM,eACN,CAAC,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,IAAI,GAChE,IAAI,CAMhB;IAED;;;;OAIG;IACH,oBAHW,KAAK,GACH,IAAI,CAKhB;IAED;;;;;;;;OAQG;IACH,kBAHW,MAAM,GAAG,MAAM,GACb,IAAI,CAYhB;IAFC,+BAA+B;IAC/B,kCAAoE;IAGtE;;;OAGG;IACH,uBAFa,MAAM,GAAG,SAAS,CAI9B;IAED;;;;OAIG;IACH,oCAHW,MAAM,GAAG,SAAS,GAAG,IAAI,GACvB,IAAI,CAYhB;IAED;;;;OAIG;IACH,0CAHW,CAAC,cAAc,EAAE,MAAM,GAAG,SAAS,KAAK,IAAI,GAC1C,IAAI,CAIhB;CACF"}
@@ -91,6 +91,10 @@ export default class VelociousHttpServerClientResponse {
91
91
  * Headers.
92
92
  * @type {Record<string, string[]>} */
93
93
  headers = {};
94
+ /**
95
+ * Whether compression has been disabled for this specific response.
96
+ * @type {boolean} */
97
+ compressionDisabled = false;
94
98
  /**
95
99
  * Runs constructor.
96
100
  * @param {object} args - Options object.
@@ -122,6 +126,50 @@ export default class VelociousHttpServerClientResponse {
122
126
  setHeader(key, value) {
123
127
  this.headers[key] = [value];
124
128
  }
129
+ /**
130
+ * Returns every value set for a header, matched case-insensitively.
131
+ * @param {string} key - Header name.
132
+ * @returns {string[]} - Header values in insertion order.
133
+ */
134
+ getHeader(key) {
135
+ const lowerCaseKey = key.toLowerCase();
136
+ /** @type {string[]} */
137
+ const values = [];
138
+ for (const headerKey in this.headers) {
139
+ if (headerKey.toLowerCase() == lowerCaseKey) {
140
+ values.push(...this.headers[headerKey]);
141
+ }
142
+ }
143
+ return values;
144
+ }
145
+ /**
146
+ * Removes every value set for a header, matched case-insensitively.
147
+ * @param {string} key - Header name.
148
+ * @returns {void} - No return value.
149
+ */
150
+ removeHeader(key) {
151
+ const lowerCaseKey = key.toLowerCase();
152
+ for (const headerKey in this.headers) {
153
+ if (headerKey.toLowerCase() == lowerCaseKey) {
154
+ delete this.headers[headerKey];
155
+ }
156
+ }
157
+ }
158
+ /**
159
+ * Disables HTTP response compression for this specific response, even when the
160
+ * server is configured to compress buffered responses.
161
+ * @returns {void} - No return value.
162
+ */
163
+ disableCompression() {
164
+ this.compressionDisabled = true;
165
+ }
166
+ /**
167
+ * Runs is compression disabled.
168
+ * @returns {boolean} - Whether compression has been disabled for this response.
169
+ */
170
+ isCompressionDisabled() {
171
+ return this.compressionDisabled;
172
+ }
125
173
  /**
126
174
  * Runs get body.
127
175
  * @returns {string | Uint8Array | null} - The body.
@@ -240,4 +288,4 @@ export default class VelociousHttpServerClientResponse {
240
288
  this._requestTimeoutMsChangeHandler = handler;
241
289
  }
242
290
  }
243
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzcG9uc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaHR0cC1zZXJ2ZXIvY2xpZW50L3Jlc3BvbnNlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWjs7b0NBRW9DO0FBQ3BDLE1BQU0sb0JBQW9CLEdBQUc7SUFDM0IsU0FBUyxFQUFFLEdBQUc7SUFDZCxXQUFXLEVBQUUsR0FBRztJQUNoQix1QkFBdUIsRUFBRSxHQUFHO0NBQzdCLENBQUE7QUFFRDs7b0NBRW9DO0FBQ3BDLE1BQU0sd0JBQXdCLEdBQUc7SUFDL0IsR0FBRyxFQUFFLFVBQVU7SUFDZixHQUFHLEVBQUUscUJBQXFCO0lBQzFCLEdBQUcsRUFBRSxZQUFZO0lBQ2pCLEdBQUcsRUFBRSxhQUFhO0lBQ2xCLEdBQUcsRUFBRSxJQUFJO0lBQ1QsR0FBRyxFQUFFLFNBQVM7SUFDZCxHQUFHLEVBQUUsVUFBVTtJQUNmLEdBQUcsRUFBRSwrQkFBK0I7SUFDcEMsR0FBRyxFQUFFLFlBQVk7SUFDakIsR0FBRyxFQUFFLGVBQWU7SUFDcEIsR0FBRyxFQUFFLGlCQUFpQjtJQUN0QixHQUFHLEVBQUUsY0FBYztJQUNuQixHQUFHLEVBQUUsa0JBQWtCO0lBQ3ZCLEdBQUcsRUFBRSxTQUFTO0lBQ2QsR0FBRyxFQUFFLGtCQUFrQjtJQUN2QixHQUFHLEVBQUUsbUJBQW1CO0lBQ3hCLEdBQUcsRUFBRSxPQUFPO0lBQ1osR0FBRyxFQUFFLFdBQVc7SUFDaEIsR0FBRyxFQUFFLGNBQWM7SUFDbkIsR0FBRyxFQUFFLFdBQVc7SUFDaEIsR0FBRyxFQUFFLG9CQUFvQjtJQUN6QixHQUFHLEVBQUUsb0JBQW9CO0lBQ3pCLEdBQUcsRUFBRSxhQUFhO0lBQ2xCLEdBQUcsRUFBRSxjQUFjO0lBQ25CLEdBQUcsRUFBRSxrQkFBa0I7SUFDdkIsR0FBRyxFQUFFLFdBQVc7SUFDaEIsR0FBRyxFQUFFLFdBQVc7SUFDaEIsR0FBRyxFQUFFLG9CQUFvQjtJQUN6QixHQUFHLEVBQUUsZ0JBQWdCO0lBQ3JCLEdBQUcsRUFBRSwrQkFBK0I7SUFDcEMsR0FBRyxFQUFFLGlCQUFpQjtJQUN0QixHQUFHLEVBQUUsVUFBVTtJQUNmLEdBQUcsRUFBRSxNQUFNO0lBQ1gsR0FBRyxFQUFFLGlCQUFpQjtJQUN0QixHQUFHLEVBQUUscUJBQXFCO0lBQzFCLEdBQUcsRUFBRSxtQkFBbUI7SUFDeEIsR0FBRyxFQUFFLGNBQWM7SUFDbkIsR0FBRyxFQUFFLHdCQUF3QjtJQUM3QixHQUFHLEVBQUUsdUJBQXVCO0lBQzVCLEdBQUcsRUFBRSxvQkFBb0I7SUFDekIsR0FBRyxFQUFFLGNBQWM7SUFDbkIsR0FBRyxFQUFFLHFCQUFxQjtJQUMxQixHQUFHLEVBQUUsc0JBQXNCO0lBQzNCLEdBQUcsRUFBRSxRQUFRO0lBQ2IsR0FBRyxFQUFFLG1CQUFtQjtJQUN4QixHQUFHLEVBQUUsV0FBVztJQUNoQixHQUFHLEVBQUUsa0JBQWtCO0lBQ3ZCLEdBQUcsRUFBRSx1QkFBdUI7SUFDNUIsR0FBRyxFQUFFLG1CQUFtQjtJQUN4QixHQUFHLEVBQUUsaUNBQWlDO0lBQ3RDLEdBQUcsRUFBRSwrQkFBK0I7SUFDcEMsR0FBRyxFQUFFLHVCQUF1QjtJQUM1QixHQUFHLEVBQUUsaUJBQWlCO0lBQ3RCLEdBQUcsRUFBRSxhQUFhO0lBQ2xCLEdBQUcsRUFBRSxxQkFBcUI7SUFDMUIsR0FBRyxFQUFFLGlCQUFpQjtJQUN0QixHQUFHLEVBQUUsNEJBQTRCO0lBQ2pDLEdBQUcsRUFBRSx5QkFBeUI7SUFDOUIsR0FBRyxFQUFFLHNCQUFzQjtJQUMzQixHQUFHLEVBQUUsZUFBZTtJQUNwQixHQUFHLEVBQUUsY0FBYztJQUNuQixHQUFHLEVBQUUsaUNBQWlDO0NBQ3ZDLENBQUE7QUFFRCxNQUFNLENBQUMsT0FBTyxPQUFPLGlDQUFpQztJQUNwRDs7NENBRXdDO0lBQ3hDLElBQUksR0FBRyxJQUFJLENBQUE7SUFFWDs7K0JBRTJCO0lBQzNCLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFFZjs7b0ZBRWdGO0lBQ2hGLGNBQWMsR0FBRyxJQUFJLENBQUE7SUFFckI7OzBDQUVzQztJQUN0QyxPQUFPLEdBQUcsRUFBRSxDQUFBO0lBRVo7Ozs7T0FJRztJQUNILFlBQVksRUFBQyxhQUFhLEVBQUM7UUFDekIsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUE7UUFDbEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLFNBQVMsQ0FBQTtRQUNsQyxJQUFJLENBQUMsOEJBQThCLEdBQUcsU0FBUyxDQUFBO0lBQ2pELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFNBQVMsQ0FBQyxHQUFHLEVBQUUsS0FBSztRQUNsQixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUE7UUFDeEIsQ0FBQztRQUVELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFNBQVMsQ0FBQyxHQUFHLEVBQUUsS0FBSztRQUNsQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDN0IsQ0FBQztJQUVEOzs7T0FHRztJQUNILE9BQU87UUFDTCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDNUIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFBO1FBQ2xCLENBQUM7UUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUE7SUFDekMsQ0FBQztJQUVEOzs7T0FHRztJQUNILGFBQWE7UUFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLElBQUksR0FBRyxDQUFBO0lBQy9CLENBQUM7SUFFRDs7O09BR0c7SUFDSCxnQkFBZ0I7UUFDZCxPQUFPLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFBO0lBQ25DLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLEtBQUs7UUFDWCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQTtRQUNwQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQTtRQUMxQixJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQTtJQUNuQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQTtJQUN0QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsaUJBQWlCO1FBQ2YsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFBO0lBQzVCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFdBQVcsQ0FBQyxJQUFJLEVBQUUsVUFBVSxHQUFHLElBQUk7UUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7UUFDcEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxVQUFVLENBQUE7UUFDaEMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7SUFDbEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxZQUFZLENBQUMsS0FBSztRQUNoQixJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSwyQkFBMkIsQ0FBQyxDQUFBO1FBQzNELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTyxPQUFPLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFBO0lBQ3BELENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILFNBQVMsQ0FBQyxNQUFNO1FBQ2QsTUFBTSxTQUFTLEdBQUcsb0JBQW9CLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFDdEQsTUFBTSxhQUFhLEdBQUcsU0FBUyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUVqRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsSUFBSSxhQUFhLEdBQUcsR0FBRyxJQUFJLGFBQWEsR0FBRyxHQUFHLEVBQUUsQ0FBQztZQUNuRixNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixNQUFNLEVBQUUsQ0FBQyxDQUFBO1FBQ2hELENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxHQUFHLGFBQWEsQ0FBQTtRQUMvQixJQUFJLENBQUMsYUFBYSxHQUFHLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxJQUFJLElBQUksQ0FBQTtJQUN0RSxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsbUJBQW1CO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFBO0lBQy9CLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsbUJBQW1CLENBQUMsY0FBYztRQUNoQyxJQUFJLE9BQU8sY0FBYyxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDMUUsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGNBQWMsQ0FBQTtRQUN6QyxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxTQUFTLENBQUE7UUFDcEMsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLDhCQUE4QixFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLDhCQUE4QixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1FBQzdELENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGdDQUFnQyxDQUFDLE9BQU87UUFDdEMsSUFBSSxDQUFDLDhCQUE4QixHQUFHLE9BQU8sQ0FBQTtJQUMvQyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuLyoqXG4gKiBOYW1lZCBzdGF0dXMgYWxpYXNlcy5cbiAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBudW1iZXI+fSAqL1xuY29uc3QgTkFNRURfU1RBVFVTX0FMSUFTRVMgPSB7XG4gIFwic3VjY2Vzc1wiOiAyMDAsXG4gIFwibm90LWZvdW5kXCI6IDQwNCxcbiAgXCJpbnRlcm5hbC1zZXJ2ZXItZXJyb3JcIjogNTAwXG59XG5cbi8qKlxuICogU3RhbmRhcmQgc3RhdHVzIG1lc3NhZ2VzLlxuICogQHR5cGUge1JlY29yZDxudW1iZXIsIHN0cmluZz59ICovXG5jb25zdCBTVEFOREFSRF9TVEFUVVNfTUVTU0FHRVMgPSB7XG4gIDEwMDogXCJDb250aW51ZVwiLFxuICAxMDE6IFwiU3dpdGNoaW5nIFByb3RvY29sc1wiLFxuICAxMDI6IFwiUHJvY2Vzc2luZ1wiLFxuICAxMDM6IFwiRWFybHkgSGludHNcIixcbiAgMjAwOiBcIk9LXCIsXG4gIDIwMTogXCJDcmVhdGVkXCIsXG4gIDIwMjogXCJBY2NlcHRlZFwiLFxuICAyMDM6IFwiTm9uLUF1dGhvcml0YXRpdmUgSW5mb3JtYXRpb25cIixcbiAgMjA0OiBcIk5vIENvbnRlbnRcIixcbiAgMjA1OiBcIlJlc2V0IENvbnRlbnRcIixcbiAgMjA2OiBcIlBhcnRpYWwgQ29udGVudFwiLFxuICAyMDc6IFwiTXVsdGktU3RhdHVzXCIsXG4gIDIwODogXCJBbHJlYWR5IFJlcG9ydGVkXCIsXG4gIDIyNjogXCJJTSBVc2VkXCIsXG4gIDMwMDogXCJNdWx0aXBsZSBDaG9pY2VzXCIsXG4gIDMwMTogXCJNb3ZlZCBQZXJtYW5lbnRseVwiLFxuICAzMDI6IFwiRm91bmRcIixcbiAgMzAzOiBcIlNlZSBPdGhlclwiLFxuICAzMDQ6IFwiTm90IE1vZGlmaWVkXCIsXG4gIDMwNTogXCJVc2UgUHJveHlcIixcbiAgMzA3OiBcIlRlbXBvcmFyeSBSZWRpcmVjdFwiLFxuICAzMDg6IFwiUGVybWFuZW50IFJlZGlyZWN0XCIsXG4gIDQwMDogXCJCYWQgUmVxdWVzdFwiLFxuICA0MDE6IFwiVW5hdXRob3JpemVkXCIsXG4gIDQwMjogXCJQYXltZW50IFJlcXVpcmVkXCIsXG4gIDQwMzogXCJGb3JiaWRkZW5cIixcbiAgNDA0OiBcIk5vdCBGb3VuZFwiLFxuICA0MDU6IFwiTWV0aG9kIE5vdCBBbGxvd2VkXCIsXG4gIDQwNjogXCJOb3QgQWNjZXB0YWJsZVwiLFxuICA0MDc6IFwiUHJveHkgQXV0aGVudGljYXRpb24gUmVxdWlyZWRcIixcbiAgNDA4OiBcIlJlcXVlc3QgVGltZW91dFwiLFxuICA0MDk6IFwiQ29uZmxpY3RcIixcbiAgNDEwOiBcIkdvbmVcIixcbiAgNDExOiBcIkxlbmd0aCBSZXF1aXJlZFwiLFxuICA0MTI6IFwiUHJlY29uZGl0aW9uIEZhaWxlZFwiLFxuICA0MTM6IFwiUGF5bG9hZCBUb28gTGFyZ2VcIixcbiAgNDE0OiBcIlVSSSBUb28gTG9uZ1wiLFxuICA0MTU6IFwiVW5zdXBwb3J0ZWQgTWVkaWEgVHlwZVwiLFxuICA0MTY6IFwiUmFuZ2UgTm90IFNhdGlzZmlhYmxlXCIsXG4gIDQxNzogXCJFeHBlY3RhdGlvbiBGYWlsZWRcIixcbiAgNDE4OiBcIkknbSBhIHRlYXBvdFwiLFxuICA0MjE6IFwiTWlzZGlyZWN0ZWQgUmVxdWVzdFwiLFxuICA0MjI6IFwiVW5wcm9jZXNzYWJsZSBFbnRpdHlcIixcbiAgNDIzOiBcIkxvY2tlZFwiLFxuICA0MjQ6IFwiRmFpbGVkIERlcGVuZGVuY3lcIixcbiAgNDI1OiBcIlRvbyBFYXJseVwiLFxuICA0MjY6IFwiVXBncmFkZSBSZXF1aXJlZFwiLFxuICA0Mjg6IFwiUHJlY29uZGl0aW9uIFJlcXVpcmVkXCIsXG4gIDQyOTogXCJUb28gTWFueSBSZXF1ZXN0c1wiLFxuICA0MzE6IFwiUmVxdWVzdCBIZWFkZXIgRmllbGRzIFRvbyBMYXJnZVwiLFxuICA0NTE6IFwiVW5hdmFpbGFibGUgRm9yIExlZ2FsIFJlYXNvbnNcIixcbiAgNTAwOiBcIkludGVybmFsIHNlcnZlciBlcnJvclwiLFxuICA1MDE6IFwiTm90IEltcGxlbWVudGVkXCIsXG4gIDUwMjogXCJCYWQgR2F0ZXdheVwiLFxuICA1MDM6IFwiU2VydmljZSBVbmF2YWlsYWJsZVwiLFxuICA1MDQ6IFwiR2F0ZXdheSBUaW1lb3V0XCIsXG4gIDUwNTogXCJIVFRQIFZlcnNpb24gTm90IFN1cHBvcnRlZFwiLFxuICA1MDY6IFwiVmFyaWFudCBBbHNvIE5lZ290aWF0ZXNcIixcbiAgNTA3OiBcIkluc3VmZmljaWVudCBTdG9yYWdlXCIsXG4gIDUwODogXCJMb29wIERldGVjdGVkXCIsXG4gIDUxMDogXCJOb3QgRXh0ZW5kZWRcIixcbiAgNTExOiBcIk5ldHdvcmsgQXV0aGVudGljYXRpb24gUmVxdWlyZWRcIlxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNIdHRwU2VydmVyQ2xpZW50UmVzcG9uc2Uge1xuICAvKipcbiAgICogQm9keS5cbiAgICogQHR5cGUge3N0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsfSAqL1xuICBib2R5ID0gbnVsbFxuXG4gIC8qKlxuICAgKiBGaWxlIHBhdGguXG4gICAqIEB0eXBlIHtzdHJpbmcgfCBudWxsfSAqL1xuICBmaWxlUGF0aCA9IG51bGxcblxuICAvKipcbiAgICogRmlsZSByZXNwb25zZSBjb21wbGV0aW9uIGNhbGxiYWNrLlxuICAgKiBAdHlwZSB7KChyZXN1bHQ6IFwiY29tcGxldGVkXCIgfCBcImFib3J0ZWRcIikgPT4gdm9pZCB8IFByb21pc2U8dm9pZD4pIHwgbnVsbH0gKi9cbiAgZmlsZU9uRmluaXNoZWQgPSBudWxsXG5cbiAgLyoqXG4gICAqIEhlYWRlcnMuXG4gICAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT59ICovXG4gIGhlYWRlcnMgPSB7fVxuXG4gIC8qKlxuICAgKiBSdW5zIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gYXJncy5jb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9ufSkge1xuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IGNvbmZpZ3VyYXRpb25cbiAgICB0aGlzLl9yZXF1ZXN0VGltZW91dE1zID0gdW5kZWZpbmVkXG4gICAgdGhpcy5fcmVxdWVzdFRpbWVvdXRNc0NoYW5nZUhhbmRsZXIgPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGFkZCBoZWFkZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBLZXkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSAtIFZhbHVlIHRvIHVzZS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgYWRkSGVhZGVyKGtleSwgdmFsdWUpIHtcbiAgICBpZiAoIShrZXkgaW4gdGhpcy5oZWFkZXJzKSkge1xuICAgICAgdGhpcy5oZWFkZXJzW2tleV0gPSBbXVxuICAgIH1cblxuICAgIHRoaXMuaGVhZGVyc1trZXldLnB1c2godmFsdWUpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzZXQgaGVhZGVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gS2V5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsdWUgLSBWYWx1ZSB0byB1c2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHNldEhlYWRlcihrZXksIHZhbHVlKSB7XG4gICAgdGhpcy5oZWFkZXJzW2tleV0gPSBbdmFsdWVdXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgYm9keS5cbiAgICogQHJldHVybnMge3N0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsfSAtIFRoZSBib2R5LlxuICAgKi9cbiAgZ2V0Qm9keSgpIHtcbiAgICBpZiAodGhpcy5ib2R5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB0aGlzLmJvZHlcbiAgICB9XG5cbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJObyBib2R5IGhhcyBiZWVuIHNldFwiKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IHN0YXR1cyBjb2RlLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIFRoZSBzdGF0dXMgY29kZS5cbiAgICovXG4gIGdldFN0YXR1c0NvZGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdHVzQ29kZSB8fCAyMDBcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBzdGF0dXMgbWVzc2FnZS5cbiAgICogQHJldHVybnMge3N0cmluZ30gLSBUaGUgc3RhdHVzIG1lc3NhZ2UuXG4gICAqL1xuICBnZXRTdGF0dXNNZXNzYWdlKCkge1xuICAgIHJldHVybiB0aGlzLnN0YXR1c01lc3NhZ2UgfHwgXCJPS1wiXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzZXQgYm9keS5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBVaW50OEFycmF5fSB2YWx1ZSAtIFZhbHVlIHRvIHVzZS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc2V0Qm9keSh2YWx1ZSkge1xuICAgIHRoaXMuZmlsZVBhdGggPSBudWxsXG4gICAgdGhpcy5maWxlT25GaW5pc2hlZCA9IG51bGxcbiAgICB0aGlzLmJvZHkgPSB2YWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IGZpbGUgcGF0aC5cbiAgICogQHJldHVybnMge3N0cmluZyB8IG51bGx9IC0gRmlsZSBwYXRoLlxuICAgKi9cbiAgZ2V0RmlsZVBhdGgoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmlsZVBhdGhcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBmaWxlIHJlc3BvbnNlIGNvbXBsZXRpb24gY2FsbGJhY2suXG4gICAqIEByZXR1cm5zIHsoKHJlc3VsdDogXCJjb21wbGV0ZWRcIiB8IFwiYWJvcnRlZFwiKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPikgfCBudWxsfSAtIEZpbGUgcmVzcG9uc2UgY29tcGxldGlvbiBjYWxsYmFjay5cbiAgICovXG4gIGdldEZpbGVPbkZpbmlzaGVkKCkge1xuICAgIHJldHVybiB0aGlzLmZpbGVPbkZpbmlzaGVkXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzZXQgZmlsZSBwYXRoLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcGF0aCAtIEZpbGUgcGF0aC5cbiAgICogQHBhcmFtIHsoKHJlc3VsdDogXCJjb21wbGV0ZWRcIiB8IFwiYWJvcnRlZFwiKSA9PiB2b2lkIHwgUHJvbWlzZTx2b2lkPikgfCBudWxsfSBbb25GaW5pc2hlZF0gLSBDb21wbGV0aW9uIGNhbGxiYWNrLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzZXRGaWxlUGF0aChwYXRoLCBvbkZpbmlzaGVkID0gbnVsbCkge1xuICAgIHRoaXMuZmlsZVBhdGggPSBwYXRoXG4gICAgdGhpcy5maWxlT25GaW5pc2hlZCA9IG9uRmluaXNoZWRcbiAgICB0aGlzLmJvZHkgPSBudWxsXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzZXQgZXJyb3IgYm9keS5cbiAgICogQHBhcmFtIHtFcnJvcn0gZXJyb3IgLSBFcnJvciBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc2V0RXJyb3JCb2R5KGVycm9yKSB7XG4gICAgdGhpcy5zZXRIZWFkZXIoXCJDb250ZW50LVR5cGVcIiwgXCJ0ZXh0L3BsYWluOyBjaGFyc2V0PVVURi04XCIpXG4gICAgdGhpcy5zZXRCb2R5KGAke2Vycm9yLm1lc3NhZ2V9XFxuXFxuJHtlcnJvci5zdGFja31gKVxuICB9XG5cbiAgLyoqXG4gICAqIEFjY2VwdHMgYSBudW1lcmljIEhUVFAgc3RhdHVzIGNvZGUgKGUuZy4gYDQyMmApIG9yIG9uZSBvZiB0aGVcbiAgICogbmFtZWQgYWxpYXNlcyAoYFwic3VjY2Vzc1wiYCwgYFwibm90LWZvdW5kXCJgLCBgXCJpbnRlcm5hbC1zZXJ2ZXItZXJyb3JcImApLlxuICAgKiBOdW1lcmljIGlucHV0cyBpbiB0aGUgc3RhbmRhcmQgMXh4LTV4eCByYW5nZSByZXNvbHZlIHRoZWlyIG93blxuICAgKiBzdGF0dXMgbWVzc2FnZXMgZnJvbSB0aGUgSUFOQSByZWdpc3RyeTsgYWxpYXNlcyBrZWVwIHRoZVxuICAgKiBiYWNrLWNvbXBhdGlibGUgY29kZSBtYXBwaW5nLlxuICAgKiBAcGFyYW0ge251bWJlciB8IHN0cmluZ30gc3RhdHVzIC0gU3RhdHVzLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzZXRTdGF0dXMoc3RhdHVzKSB7XG4gICAgY29uc3QgYWxpYXNDb2RlID0gTkFNRURfU1RBVFVTX0FMSUFTRVNbU3RyaW5nKHN0YXR1cyldXG4gICAgY29uc3QgbnVtZXJpY1N0YXR1cyA9IGFsaWFzQ29kZSA/PyBOdW1iZXIoc3RhdHVzKVxuXG4gICAgaWYgKCFOdW1iZXIuaXNJbnRlZ2VyKG51bWVyaWNTdGF0dXMpIHx8IG51bWVyaWNTdGF0dXMgPCAxMDAgfHwgbnVtZXJpY1N0YXR1cyA+IDU5OSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmhhbmRsZWQgc3RhdHVzOiAke3N0YXR1c31gKVxuICAgIH1cblxuICAgIHRoaXMuc3RhdHVzQ29kZSA9IG51bWVyaWNTdGF0dXNcbiAgICB0aGlzLnN0YXR1c01lc3NhZ2UgPSBTVEFOREFSRF9TVEFUVVNfTUVTU0FHRVNbbnVtZXJpY1N0YXR1c10gfHwgXCJPS1wiXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgcmVxdWVzdCB0aW1lb3V0IG1zLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyIHwgdW5kZWZpbmVkfSAtIFJlcXVlc3QgdGltZW91dCBpbiBzZWNvbmRzLlxuICAgKi9cbiAgZ2V0UmVxdWVzdFRpbWVvdXRNcygpIHtcbiAgICByZXR1cm4gdGhpcy5fcmVxdWVzdFRpbWVvdXRNc1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc2V0IHJlcXVlc3QgdGltZW91dCBtcy5cbiAgICogQHBhcmFtIHtudW1iZXIgfCB1bmRlZmluZWQgfCBudWxsfSB0aW1lb3V0U2Vjb25kcyAtIFRpbWVvdXQgaW4gc2Vjb25kcy5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc2V0UmVxdWVzdFRpbWVvdXRNcyh0aW1lb3V0U2Vjb25kcykge1xuICAgIGlmICh0eXBlb2YgdGltZW91dFNlY29uZHMgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHRpbWVvdXRTZWNvbmRzKSkge1xuICAgICAgdGhpcy5fcmVxdWVzdFRpbWVvdXRNcyA9IHRpbWVvdXRTZWNvbmRzXG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuX3JlcXVlc3RUaW1lb3V0TXMgPSB1bmRlZmluZWRcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcmVxdWVzdFRpbWVvdXRNc0NoYW5nZUhhbmRsZXIpIHtcbiAgICAgIHRoaXMuX3JlcXVlc3RUaW1lb3V0TXNDaGFuZ2VIYW5kbGVyKHRoaXMuX3JlcXVlc3RUaW1lb3V0TXMpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc2V0IHJlcXVlc3QgdGltZW91dCBtcyBjaGFuZ2UgaGFuZGxlci5cbiAgICogQHBhcmFtIHsodGltZW91dFNlY29uZHM6IG51bWJlciB8IHVuZGVmaW5lZCkgPT4gdm9pZH0gaGFuZGxlciAtIENoYW5nZSBoYW5kbGVyLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzZXRSZXF1ZXN0VGltZW91dE1zQ2hhbmdlSGFuZGxlcihoYW5kbGVyKSB7XG4gICAgdGhpcy5fcmVxdWVzdFRpbWVvdXRNc0NoYW5nZUhhbmRsZXIgPSBoYW5kbGVyXG4gIH1cbn1cbiJdfQ==
291
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzcG9uc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvaHR0cC1zZXJ2ZXIvY2xpZW50L3Jlc3BvbnNlLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWjs7b0NBRW9DO0FBQ3BDLE1BQU0sb0JBQW9CLEdBQUc7SUFDM0IsU0FBUyxFQUFFLEdBQUc7SUFDZCxXQUFXLEVBQUUsR0FBRztJQUNoQix1QkFBdUIsRUFBRSxHQUFHO0NBQzdCLENBQUE7QUFFRDs7b0NBRW9DO0FBQ3BDLE1BQU0sd0JBQXdCLEdBQUc7SUFDL0IsR0FBRyxFQUFFLFVBQVU7SUFDZixHQUFHLEVBQUUscUJBQXFCO0lBQzFCLEdBQUcsRUFBRSxZQUFZO0lBQ2pCLEdBQUcsRUFBRSxhQUFhO0lBQ2xCLEdBQUcsRUFBRSxJQUFJO0lBQ1QsR0FBRyxFQUFFLFNBQVM7SUFDZCxHQUFHLEVBQUUsVUFBVTtJQUNmLEdBQUcsRUFBRSwrQkFBK0I7SUFDcEMsR0FBRyxFQUFFLFlBQVk7SUFDakIsR0FBRyxFQUFFLGVBQWU7SUFDcEIsR0FBRyxFQUFFLGlCQUFpQjtJQUN0QixHQUFHLEVBQUUsY0FBYztJQUNuQixHQUFHLEVBQUUsa0JBQWtCO0lBQ3ZCLEdBQUcsRUFBRSxTQUFTO0lBQ2QsR0FBRyxFQUFFLGtCQUFrQjtJQUN2QixHQUFHLEVBQUUsbUJBQW1CO0lBQ3hCLEdBQUcsRUFBRSxPQUFPO0lBQ1osR0FBRyxFQUFFLFdBQVc7SUFDaEIsR0FBRyxFQUFFLGNBQWM7SUFDbkIsR0FBRyxFQUFFLFdBQVc7SUFDaEIsR0FBRyxFQUFFLG9CQUFvQjtJQUN6QixHQUFHLEVBQUUsb0JBQW9CO0lBQ3pCLEdBQUcsRUFBRSxhQUFhO0lBQ2xCLEdBQUcsRUFBRSxjQUFjO0lBQ25CLEdBQUcsRUFBRSxrQkFBa0I7SUFDdkIsR0FBRyxFQUFFLFdBQVc7SUFDaEIsR0FBRyxFQUFFLFdBQVc7SUFDaEIsR0FBRyxFQUFFLG9CQUFvQjtJQUN6QixHQUFHLEVBQUUsZ0JBQWdCO0lBQ3JCLEdBQUcsRUFBRSwrQkFBK0I7SUFDcEMsR0FBRyxFQUFFLGlCQUFpQjtJQUN0QixHQUFHLEVBQUUsVUFBVTtJQUNmLEdBQUcsRUFBRSxNQUFNO0lBQ1gsR0FBRyxFQUFFLGlCQUFpQjtJQUN0QixHQUFHLEVBQUUscUJBQXFCO0lBQzFCLEdBQUcsRUFBRSxtQkFBbUI7SUFDeEIsR0FBRyxFQUFFLGNBQWM7SUFDbkIsR0FBRyxFQUFFLHdCQUF3QjtJQUM3QixHQUFHLEVBQUUsdUJBQXVCO0lBQzVCLEdBQUcsRUFBRSxvQkFBb0I7SUFDekIsR0FBRyxFQUFFLGNBQWM7SUFDbkIsR0FBRyxFQUFFLHFCQUFxQjtJQUMxQixHQUFHLEVBQUUsc0JBQXNCO0lBQzNCLEdBQUcsRUFBRSxRQUFRO0lBQ2IsR0FBRyxFQUFFLG1CQUFtQjtJQUN4QixHQUFHLEVBQUUsV0FBVztJQUNoQixHQUFHLEVBQUUsa0JBQWtCO0lBQ3ZCLEdBQUcsRUFBRSx1QkFBdUI7SUFDNUIsR0FBRyxFQUFFLG1CQUFtQjtJQUN4QixHQUFHLEVBQUUsaUNBQWlDO0lBQ3RDLEdBQUcsRUFBRSwrQkFBK0I7SUFDcEMsR0FBRyxFQUFFLHVCQUF1QjtJQUM1QixHQUFHLEVBQUUsaUJBQWlCO0lBQ3RCLEdBQUcsRUFBRSxhQUFhO0lBQ2xCLEdBQUcsRUFBRSxxQkFBcUI7SUFDMUIsR0FBRyxFQUFFLGlCQUFpQjtJQUN0QixHQUFHLEVBQUUsNEJBQTRCO0lBQ2pDLEdBQUcsRUFBRSx5QkFBeUI7SUFDOUIsR0FBRyxFQUFFLHNCQUFzQjtJQUMzQixHQUFHLEVBQUUsZUFBZTtJQUNwQixHQUFHLEVBQUUsY0FBYztJQUNuQixHQUFHLEVBQUUsaUNBQWlDO0NBQ3ZDLENBQUE7QUFFRCxNQUFNLENBQUMsT0FBTyxPQUFPLGlDQUFpQztJQUNwRDs7NENBRXdDO0lBQ3hDLElBQUksR0FBRyxJQUFJLENBQUE7SUFFWDs7K0JBRTJCO0lBQzNCLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFFZjs7b0ZBRWdGO0lBQ2hGLGNBQWMsR0FBRyxJQUFJLENBQUE7SUFFckI7OzBDQUVzQztJQUN0QyxPQUFPLEdBQUcsRUFBRSxDQUFBO0lBRVo7O3lCQUVxQjtJQUNyQixtQkFBbUIsR0FBRyxLQUFLLENBQUE7SUFFM0I7Ozs7T0FJRztJQUNILFlBQVksRUFBQyxhQUFhLEVBQUM7UUFDekIsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUE7UUFDbEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLFNBQVMsQ0FBQTtRQUNsQyxJQUFJLENBQUMsOEJBQThCLEdBQUcsU0FBUyxDQUFBO0lBQ2pELENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFNBQVMsQ0FBQyxHQUFHLEVBQUUsS0FBSztRQUNsQixJQUFJLENBQUMsQ0FBQyxHQUFHLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDM0IsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUE7UUFDeEIsQ0FBQztRQUVELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFBO0lBQy9CLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFNBQVMsQ0FBQyxHQUFHLEVBQUUsS0FBSztRQUNsQixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUE7SUFDN0IsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxTQUFTLENBQUMsR0FBRztRQUNYLE1BQU0sWUFBWSxHQUFHLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQTtRQUV0Qyx1QkFBdUI7UUFDdkIsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFBO1FBRWpCLEtBQUssTUFBTSxTQUFTLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3JDLElBQUksU0FBUyxDQUFDLFdBQVcsRUFBRSxJQUFJLFlBQVksRUFBRSxDQUFDO2dCQUM1QyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFBO1lBQ3pDLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxNQUFNLENBQUE7SUFDZixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFlBQVksQ0FBQyxHQUFHO1FBQ2QsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDLFdBQVcsRUFBRSxDQUFBO1FBRXRDLEtBQUssTUFBTSxTQUFTLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3JDLElBQUksU0FBUyxDQUFDLFdBQVcsRUFBRSxJQUFJLFlBQVksRUFBRSxDQUFDO2dCQUM1QyxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUE7WUFDaEMsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGtCQUFrQjtRQUNoQixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFBO0lBQ2pDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxxQkFBcUI7UUFDbkIsT0FBTyxJQUFJLENBQUMsbUJBQW1CLENBQUE7SUFDakMsQ0FBQztJQUVEOzs7T0FHRztJQUNILE9BQU87UUFDTCxJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDNUIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFBO1FBQ2xCLENBQUM7UUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLHNCQUFzQixDQUFDLENBQUE7SUFDekMsQ0FBQztJQUVEOzs7T0FHRztJQUNILGFBQWE7UUFDWCxPQUFPLElBQUksQ0FBQyxVQUFVLElBQUksR0FBRyxDQUFBO0lBQy9CLENBQUM7SUFFRDs7O09BR0c7SUFDSCxnQkFBZ0I7UUFDZCxPQUFPLElBQUksQ0FBQyxhQUFhLElBQUksSUFBSSxDQUFBO0lBQ25DLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsT0FBTyxDQUFDLEtBQUs7UUFDWCxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQTtRQUNwQixJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQTtRQUMxQixJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQTtJQUNuQixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsV0FBVztRQUNULE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQTtJQUN0QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsaUJBQWlCO1FBQ2YsT0FBTyxJQUFJLENBQUMsY0FBYyxDQUFBO0lBQzVCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILFdBQVcsQ0FBQyxJQUFJLEVBQUUsVUFBVSxHQUFHLElBQUk7UUFDakMsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUE7UUFDcEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxVQUFVLENBQUE7UUFDaEMsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUE7SUFDbEIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxZQUFZLENBQUMsS0FBSztRQUNoQixJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsRUFBRSwyQkFBMkIsQ0FBQyxDQUFBO1FBQzNELElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxLQUFLLENBQUMsT0FBTyxPQUFPLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFBO0lBQ3BELENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNILFNBQVMsQ0FBQyxNQUFNO1FBQ2QsTUFBTSxTQUFTLEdBQUcsb0JBQW9CLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUE7UUFDdEQsTUFBTSxhQUFhLEdBQUcsU0FBUyxJQUFJLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtRQUVqRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxhQUFhLENBQUMsSUFBSSxhQUFhLEdBQUcsR0FBRyxJQUFJLGFBQWEsR0FBRyxHQUFHLEVBQUUsQ0FBQztZQUNuRixNQUFNLElBQUksS0FBSyxDQUFDLHFCQUFxQixNQUFNLEVBQUUsQ0FBQyxDQUFBO1FBQ2hELENBQUM7UUFFRCxJQUFJLENBQUMsVUFBVSxHQUFHLGFBQWEsQ0FBQTtRQUMvQixJQUFJLENBQUMsYUFBYSxHQUFHLHdCQUF3QixDQUFDLGFBQWEsQ0FBQyxJQUFJLElBQUksQ0FBQTtJQUN0RSxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsbUJBQW1CO1FBQ2pCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixDQUFBO0lBQy9CLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsbUJBQW1CLENBQUMsY0FBYztRQUNoQyxJQUFJLE9BQU8sY0FBYyxLQUFLLFFBQVEsSUFBSSxNQUFNLENBQUMsUUFBUSxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDMUUsSUFBSSxDQUFDLGlCQUFpQixHQUFHLGNBQWMsQ0FBQTtRQUN6QyxDQUFDO2FBQU0sQ0FBQztZQUNOLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxTQUFTLENBQUE7UUFDcEMsQ0FBQztRQUVELElBQUksSUFBSSxDQUFDLDhCQUE4QixFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLDhCQUE4QixDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFBO1FBQzdELENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGdDQUFnQyxDQUFDLE9BQU87UUFDdEMsSUFBSSxDQUFDLDhCQUE4QixHQUFHLE9BQU8sQ0FBQTtJQUMvQyxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuLyoqXG4gKiBOYW1lZCBzdGF0dXMgYWxpYXNlcy5cbiAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBudW1iZXI+fSAqL1xuY29uc3QgTkFNRURfU1RBVFVTX0FMSUFTRVMgPSB7XG4gIFwic3VjY2Vzc1wiOiAyMDAsXG4gIFwibm90LWZvdW5kXCI6IDQwNCxcbiAgXCJpbnRlcm5hbC1zZXJ2ZXItZXJyb3JcIjogNTAwXG59XG5cbi8qKlxuICogU3RhbmRhcmQgc3RhdHVzIG1lc3NhZ2VzLlxuICogQHR5cGUge1JlY29yZDxudW1iZXIsIHN0cmluZz59ICovXG5jb25zdCBTVEFOREFSRF9TVEFUVVNfTUVTU0FHRVMgPSB7XG4gIDEwMDogXCJDb250aW51ZVwiLFxuICAxMDE6IFwiU3dpdGNoaW5nIFByb3RvY29sc1wiLFxuICAxMDI6IFwiUHJvY2Vzc2luZ1wiLFxuICAxMDM6IFwiRWFybHkgSGludHNcIixcbiAgMjAwOiBcIk9LXCIsXG4gIDIwMTogXCJDcmVhdGVkXCIsXG4gIDIwMjogXCJBY2NlcHRlZFwiLFxuICAyMDM6IFwiTm9uLUF1dGhvcml0YXRpdmUgSW5mb3JtYXRpb25cIixcbiAgMjA0OiBcIk5vIENvbnRlbnRcIixcbiAgMjA1OiBcIlJlc2V0IENvbnRlbnRcIixcbiAgMjA2OiBcIlBhcnRpYWwgQ29udGVudFwiLFxuICAyMDc6IFwiTXVsdGktU3RhdHVzXCIsXG4gIDIwODogXCJBbHJlYWR5IFJlcG9ydGVkXCIsXG4gIDIyNjogXCJJTSBVc2VkXCIsXG4gIDMwMDogXCJNdWx0aXBsZSBDaG9pY2VzXCIsXG4gIDMwMTogXCJNb3ZlZCBQZXJtYW5lbnRseVwiLFxuICAzMDI6IFwiRm91bmRcIixcbiAgMzAzOiBcIlNlZSBPdGhlclwiLFxuICAzMDQ6IFwiTm90IE1vZGlmaWVkXCIsXG4gIDMwNTogXCJVc2UgUHJveHlcIixcbiAgMzA3OiBcIlRlbXBvcmFyeSBSZWRpcmVjdFwiLFxuICAzMDg6IFwiUGVybWFuZW50IFJlZGlyZWN0XCIsXG4gIDQwMDogXCJCYWQgUmVxdWVzdFwiLFxuICA0MDE6IFwiVW5hdXRob3JpemVkXCIsXG4gIDQwMjogXCJQYXltZW50IFJlcXVpcmVkXCIsXG4gIDQwMzogXCJGb3JiaWRkZW5cIixcbiAgNDA0OiBcIk5vdCBGb3VuZFwiLFxuICA0MDU6IFwiTWV0aG9kIE5vdCBBbGxvd2VkXCIsXG4gIDQwNjogXCJOb3QgQWNjZXB0YWJsZVwiLFxuICA0MDc6IFwiUHJveHkgQXV0aGVudGljYXRpb24gUmVxdWlyZWRcIixcbiAgNDA4OiBcIlJlcXVlc3QgVGltZW91dFwiLFxuICA0MDk6IFwiQ29uZmxpY3RcIixcbiAgNDEwOiBcIkdvbmVcIixcbiAgNDExOiBcIkxlbmd0aCBSZXF1aXJlZFwiLFxuICA0MTI6IFwiUHJlY29uZGl0aW9uIEZhaWxlZFwiLFxuICA0MTM6IFwiUGF5bG9hZCBUb28gTGFyZ2VcIixcbiAgNDE0OiBcIlVSSSBUb28gTG9uZ1wiLFxuICA0MTU6IFwiVW5zdXBwb3J0ZWQgTWVkaWEgVHlwZVwiLFxuICA0MTY6IFwiUmFuZ2UgTm90IFNhdGlzZmlhYmxlXCIsXG4gIDQxNzogXCJFeHBlY3RhdGlvbiBGYWlsZWRcIixcbiAgNDE4OiBcIkknbSBhIHRlYXBvdFwiLFxuICA0MjE6IFwiTWlzZGlyZWN0ZWQgUmVxdWVzdFwiLFxuICA0MjI6IFwiVW5wcm9jZXNzYWJsZSBFbnRpdHlcIixcbiAgNDIzOiBcIkxvY2tlZFwiLFxuICA0MjQ6IFwiRmFpbGVkIERlcGVuZGVuY3lcIixcbiAgNDI1OiBcIlRvbyBFYXJseVwiLFxuICA0MjY6IFwiVXBncmFkZSBSZXF1aXJlZFwiLFxuICA0Mjg6IFwiUHJlY29uZGl0aW9uIFJlcXVpcmVkXCIsXG4gIDQyOTogXCJUb28gTWFueSBSZXF1ZXN0c1wiLFxuICA0MzE6IFwiUmVxdWVzdCBIZWFkZXIgRmllbGRzIFRvbyBMYXJnZVwiLFxuICA0NTE6IFwiVW5hdmFpbGFibGUgRm9yIExlZ2FsIFJlYXNvbnNcIixcbiAgNTAwOiBcIkludGVybmFsIHNlcnZlciBlcnJvclwiLFxuICA1MDE6IFwiTm90IEltcGxlbWVudGVkXCIsXG4gIDUwMjogXCJCYWQgR2F0ZXdheVwiLFxuICA1MDM6IFwiU2VydmljZSBVbmF2YWlsYWJsZVwiLFxuICA1MDQ6IFwiR2F0ZXdheSBUaW1lb3V0XCIsXG4gIDUwNTogXCJIVFRQIFZlcnNpb24gTm90IFN1cHBvcnRlZFwiLFxuICA1MDY6IFwiVmFyaWFudCBBbHNvIE5lZ290aWF0ZXNcIixcbiAgNTA3OiBcIkluc3VmZmljaWVudCBTdG9yYWdlXCIsXG4gIDUwODogXCJMb29wIERldGVjdGVkXCIsXG4gIDUxMDogXCJOb3QgRXh0ZW5kZWRcIixcbiAgNTExOiBcIk5ldHdvcmsgQXV0aGVudGljYXRpb24gUmVxdWlyZWRcIlxufVxuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNIdHRwU2VydmVyQ2xpZW50UmVzcG9uc2Uge1xuICAvKipcbiAgICogQm9keS5cbiAgICogQHR5cGUge3N0cmluZyB8IFVpbnQ4QXJyYXkgfCBudWxsfSAqL1xuICBib2R5ID0gbnVsbFxuXG4gIC8qKlxuICAgKiBGaWxlIHBhdGguXG4gICAqIEB0eXBlIHtzdHJpbmcgfCBudWxsfSAqL1xuICBmaWxlUGF0aCA9IG51bGxcblxuICAvKipcbiAgICogRmlsZSByZXNwb25zZSBjb21wbGV0aW9uIGNhbGxiYWNrLlxuICAgKiBAdHlwZSB7KChyZXN1bHQ6IFwiY29tcGxldGVkXCIgfCBcImFib3J0ZWRcIikgPT4gdm9pZCB8IFByb21pc2U8dm9pZD4pIHwgbnVsbH0gKi9cbiAgZmlsZU9uRmluaXNoZWQgPSBudWxsXG5cbiAgLyoqXG4gICAqIEhlYWRlcnMuXG4gICAqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmdbXT59ICovXG4gIGhlYWRlcnMgPSB7fVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGNvbXByZXNzaW9uIGhhcyBiZWVuIGRpc2FibGVkIGZvciB0aGlzIHNwZWNpZmljIHJlc3BvbnNlLlxuICAgKiBAdHlwZSB7Ym9vbGVhbn0gKi9cbiAgY29tcHJlc3Npb25EaXNhYmxlZCA9IGZhbHNlXG5cbiAgLyoqXG4gICAqIFJ1bnMgY29uc3RydWN0b3IuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb259KSB7XG4gICAgdGhpcy5jb25maWd1cmF0aW9uID0gY29uZmlndXJhdGlvblxuICAgIHRoaXMuX3JlcXVlc3RUaW1lb3V0TXMgPSB1bmRlZmluZWRcbiAgICB0aGlzLl9yZXF1ZXN0VGltZW91dE1zQ2hhbmdlSGFuZGxlciA9IHVuZGVmaW5lZFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgYWRkIGhlYWRlci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGtleSAtIEtleS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gVmFsdWUgdG8gdXNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBhZGRIZWFkZXIoa2V5LCB2YWx1ZSkge1xuICAgIGlmICghKGtleSBpbiB0aGlzLmhlYWRlcnMpKSB7XG4gICAgICB0aGlzLmhlYWRlcnNba2V5XSA9IFtdXG4gICAgfVxuXG4gICAgdGhpcy5oZWFkZXJzW2tleV0ucHVzaCh2YWx1ZSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNldCBoZWFkZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBLZXkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2YWx1ZSAtIFZhbHVlIHRvIHVzZS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc2V0SGVhZGVyKGtleSwgdmFsdWUpIHtcbiAgICB0aGlzLmhlYWRlcnNba2V5XSA9IFt2YWx1ZV1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIGV2ZXJ5IHZhbHVlIHNldCBmb3IgYSBoZWFkZXIsIG1hdGNoZWQgY2FzZS1pbnNlbnNpdGl2ZWx5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gSGVhZGVyIG5hbWUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmdbXX0gLSBIZWFkZXIgdmFsdWVzIGluIGluc2VydGlvbiBvcmRlci5cbiAgICovXG4gIGdldEhlYWRlcihrZXkpIHtcbiAgICBjb25zdCBsb3dlckNhc2VLZXkgPSBrZXkudG9Mb3dlckNhc2UoKVxuXG4gICAgLyoqIEB0eXBlIHtzdHJpbmdbXX0gKi9cbiAgICBjb25zdCB2YWx1ZXMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBoZWFkZXJLZXkgaW4gdGhpcy5oZWFkZXJzKSB7XG4gICAgICBpZiAoaGVhZGVyS2V5LnRvTG93ZXJDYXNlKCkgPT0gbG93ZXJDYXNlS2V5KSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKC4uLnRoaXMuaGVhZGVyc1toZWFkZXJLZXldKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB2YWx1ZXNcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGV2ZXJ5IHZhbHVlIHNldCBmb3IgYSBoZWFkZXIsIG1hdGNoZWQgY2FzZS1pbnNlbnNpdGl2ZWx5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gSGVhZGVyIG5hbWUuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHJlbW92ZUhlYWRlcihrZXkpIHtcbiAgICBjb25zdCBsb3dlckNhc2VLZXkgPSBrZXkudG9Mb3dlckNhc2UoKVxuXG4gICAgZm9yIChjb25zdCBoZWFkZXJLZXkgaW4gdGhpcy5oZWFkZXJzKSB7XG4gICAgICBpZiAoaGVhZGVyS2V5LnRvTG93ZXJDYXNlKCkgPT0gbG93ZXJDYXNlS2V5KSB7XG4gICAgICAgIGRlbGV0ZSB0aGlzLmhlYWRlcnNbaGVhZGVyS2V5XVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBEaXNhYmxlcyBIVFRQIHJlc3BvbnNlIGNvbXByZXNzaW9uIGZvciB0aGlzIHNwZWNpZmljIHJlc3BvbnNlLCBldmVuIHdoZW4gdGhlXG4gICAqIHNlcnZlciBpcyBjb25maWd1cmVkIHRvIGNvbXByZXNzIGJ1ZmZlcmVkIHJlc3BvbnNlcy5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgZGlzYWJsZUNvbXByZXNzaW9uKCkge1xuICAgIHRoaXMuY29tcHJlc3Npb25EaXNhYmxlZCA9IHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGlzIGNvbXByZXNzaW9uIGRpc2FibGVkLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGNvbXByZXNzaW9uIGhhcyBiZWVuIGRpc2FibGVkIGZvciB0aGlzIHJlc3BvbnNlLlxuICAgKi9cbiAgaXNDb21wcmVzc2lvbkRpc2FibGVkKCkge1xuICAgIHJldHVybiB0aGlzLmNvbXByZXNzaW9uRGlzYWJsZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCBib2R5LlxuICAgKiBAcmV0dXJucyB7c3RyaW5nIHwgVWludDhBcnJheSB8IG51bGx9IC0gVGhlIGJvZHkuXG4gICAqL1xuICBnZXRCb2R5KCkge1xuICAgIGlmICh0aGlzLmJvZHkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0dXJuIHRoaXMuYm9keVxuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihcIk5vIGJvZHkgaGFzIGJlZW4gc2V0XCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgc3RhdHVzIGNvZGUuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gVGhlIHN0YXR1cyBjb2RlLlxuICAgKi9cbiAgZ2V0U3RhdHVzQ29kZSgpIHtcbiAgICByZXR1cm4gdGhpcy5zdGF0dXNDb2RlIHx8IDIwMFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZ2V0IHN0YXR1cyBtZXNzYWdlLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nfSAtIFRoZSBzdGF0dXMgbWVzc2FnZS5cbiAgICovXG4gIGdldFN0YXR1c01lc3NhZ2UoKSB7XG4gICAgcmV0dXJuIHRoaXMuc3RhdHVzTWVzc2FnZSB8fCBcIk9LXCJcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNldCBib2R5LlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFVpbnQ4QXJyYXl9IHZhbHVlIC0gVmFsdWUgdG8gdXNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzZXRCb2R5KHZhbHVlKSB7XG4gICAgdGhpcy5maWxlUGF0aCA9IG51bGxcbiAgICB0aGlzLmZpbGVPbkZpbmlzaGVkID0gbnVsbFxuICAgIHRoaXMuYm9keSA9IHZhbHVlXG4gIH1cblxuICAvKipcbiAgICogUnVucyBnZXQgZmlsZSBwYXRoLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nIHwgbnVsbH0gLSBGaWxlIHBhdGguXG4gICAqL1xuICBnZXRGaWxlUGF0aCgpIHtcbiAgICByZXR1cm4gdGhpcy5maWxlUGF0aFxuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGZpbGUgcmVzcG9uc2UgY29tcGxldGlvbiBjYWxsYmFjay5cbiAgICogQHJldHVybnMgeygocmVzdWx0OiBcImNvbXBsZXRlZFwiIHwgXCJhYm9ydGVkXCIpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+KSB8IG51bGx9IC0gRmlsZSByZXNwb25zZSBjb21wbGV0aW9uIGNhbGxiYWNrLlxuICAgKi9cbiAgZ2V0RmlsZU9uRmluaXNoZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuZmlsZU9uRmluaXNoZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNldCBmaWxlIHBhdGguXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIC0gRmlsZSBwYXRoLlxuICAgKiBAcGFyYW0geygocmVzdWx0OiBcImNvbXBsZXRlZFwiIHwgXCJhYm9ydGVkXCIpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+KSB8IG51bGx9IFtvbkZpbmlzaGVkXSAtIENvbXBsZXRpb24gY2FsbGJhY2suXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHNldEZpbGVQYXRoKHBhdGgsIG9uRmluaXNoZWQgPSBudWxsKSB7XG4gICAgdGhpcy5maWxlUGF0aCA9IHBhdGhcbiAgICB0aGlzLmZpbGVPbkZpbmlzaGVkID0gb25GaW5pc2hlZFxuICAgIHRoaXMuYm9keSA9IG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIHNldCBlcnJvciBib2R5LlxuICAgKiBAcGFyYW0ge0Vycm9yfSBlcnJvciAtIEVycm9yIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzZXRFcnJvckJvZHkoZXJyb3IpIHtcbiAgICB0aGlzLnNldEhlYWRlcihcIkNvbnRlbnQtVHlwZVwiLCBcInRleHQvcGxhaW47IGNoYXJzZXQ9VVRGLThcIilcbiAgICB0aGlzLnNldEJvZHkoYCR7ZXJyb3IubWVzc2FnZX1cXG5cXG4ke2Vycm9yLnN0YWNrfWApXG4gIH1cblxuICAvKipcbiAgICogQWNjZXB0cyBhIG51bWVyaWMgSFRUUCBzdGF0dXMgY29kZSAoZS5nLiBgNDIyYCkgb3Igb25lIG9mIHRoZVxuICAgKiBuYW1lZCBhbGlhc2VzIChgXCJzdWNjZXNzXCJgLCBgXCJub3QtZm91bmRcImAsIGBcImludGVybmFsLXNlcnZlci1lcnJvclwiYCkuXG4gICAqIE51bWVyaWMgaW5wdXRzIGluIHRoZSBzdGFuZGFyZCAxeHgtNXh4IHJhbmdlIHJlc29sdmUgdGhlaXIgb3duXG4gICAqIHN0YXR1cyBtZXNzYWdlcyBmcm9tIHRoZSBJQU5BIHJlZ2lzdHJ5OyBhbGlhc2VzIGtlZXAgdGhlXG4gICAqIGJhY2stY29tcGF0aWJsZSBjb2RlIG1hcHBpbmcuXG4gICAqIEBwYXJhbSB7bnVtYmVyIHwgc3RyaW5nfSBzdGF0dXMgLSBTdGF0dXMuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHNldFN0YXR1cyhzdGF0dXMpIHtcbiAgICBjb25zdCBhbGlhc0NvZGUgPSBOQU1FRF9TVEFUVVNfQUxJQVNFU1tTdHJpbmcoc3RhdHVzKV1cbiAgICBjb25zdCBudW1lcmljU3RhdHVzID0gYWxpYXNDb2RlID8/IE51bWJlcihzdGF0dXMpXG5cbiAgICBpZiAoIU51bWJlci5pc0ludGVnZXIobnVtZXJpY1N0YXR1cykgfHwgbnVtZXJpY1N0YXR1cyA8IDEwMCB8fCBudW1lcmljU3RhdHVzID4gNTk5KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVuaGFuZGxlZCBzdGF0dXM6ICR7c3RhdHVzfWApXG4gICAgfVxuXG4gICAgdGhpcy5zdGF0dXNDb2RlID0gbnVtZXJpY1N0YXR1c1xuICAgIHRoaXMuc3RhdHVzTWVzc2FnZSA9IFNUQU5EQVJEX1NUQVRVU19NRVNTQUdFU1tudW1lcmljU3RhdHVzXSB8fCBcIk9LXCJcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGdldCByZXF1ZXN0IHRpbWVvdXQgbXMuXG4gICAqIEByZXR1cm5zIHtudW1iZXIgfCB1bmRlZmluZWR9IC0gUmVxdWVzdCB0aW1lb3V0IGluIHNlY29uZHMuXG4gICAqL1xuICBnZXRSZXF1ZXN0VGltZW91dE1zKCkge1xuICAgIHJldHVybiB0aGlzLl9yZXF1ZXN0VGltZW91dE1zXG4gIH1cblxuICAvKipcbiAgICogUnVucyBzZXQgcmVxdWVzdCB0aW1lb3V0IG1zLlxuICAgKiBAcGFyYW0ge251bWJlciB8IHVuZGVmaW5lZCB8IG51bGx9IHRpbWVvdXRTZWNvbmRzIC0gVGltZW91dCBpbiBzZWNvbmRzLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzZXRSZXF1ZXN0VGltZW91dE1zKHRpbWVvdXRTZWNvbmRzKSB7XG4gICAgaWYgKHR5cGVvZiB0aW1lb3V0U2Vjb25kcyA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUodGltZW91dFNlY29uZHMpKSB7XG4gICAgICB0aGlzLl9yZXF1ZXN0VGltZW91dE1zID0gdGltZW91dFNlY29uZHNcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fcmVxdWVzdFRpbWVvdXRNcyA9IHVuZGVmaW5lZFxuICAgIH1cblxuICAgIGlmICh0aGlzLl9yZXF1ZXN0VGltZW91dE1zQ2hhbmdlSGFuZGxlcikge1xuICAgICAgdGhpcy5fcmVxdWVzdFRpbWVvdXRNc0NoYW5nZUhhbmRsZXIodGhpcy5fcmVxdWVzdFRpbWVvdXRNcylcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBzZXQgcmVxdWVzdCB0aW1lb3V0IG1zIGNoYW5nZSBoYW5kbGVyLlxuICAgKiBAcGFyYW0geyh0aW1lb3V0U2Vjb25kczogbnVtYmVyIHwgdW5kZWZpbmVkKSA9PiB2b2lkfSBoYW5kbGVyIC0gQ2hhbmdlIGhhbmRsZXIuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHNldFJlcXVlc3RUaW1lb3V0TXNDaGFuZ2VIYW5kbGVyKGhhbmRsZXIpIHtcbiAgICB0aGlzLl9yZXF1ZXN0VGltZW91dE1zQ2hhbmdlSGFuZGxlciA9IGhhbmRsZXJcbiAgfVxufVxuIl19
@@ -7,13 +7,21 @@ export class VelociousHttpServerWebsocketEventsHost {
7
7
  * Broadcast handlers grouped by the configuration that owns them.
8
8
  * @type {Map<import("../configuration.js").default, Set<import("./worker-handler/index.js").default>>} */
9
9
  broadcastHandlersByConfiguration: Map<import("../configuration.js").default, Set<import("./worker-handler/index.js").default>>;
10
- publishQueue: Promise<void>;
11
10
  /**
12
- * Returns a promise that resolves when all pending publish/broadcast
13
- * operations have completed (including event-log persistence). Useful
14
- * when a request handler needs to guarantee its broadcast is persisted
15
- * before responding — without this, the HTTP response can return before
16
- * the async event-log write finishes.
11
+ * Ordered publish tails keyed by channel. Each channel persists and
12
+ * dispatches behind its own tail so a slow channel cannot head-of-line
13
+ * block unrelated channels. A rejected tail stays in the map so the
14
+ * channel remains poisoned and observable.
15
+ * @type {Map<string, Promise<void>>} */
16
+ publishQueuesByChannel: Map<string, Promise<void>>;
17
+ /**
18
+ * Returns a promise that settles when every channel tail pending at call
19
+ * time has settled (including event-log persistence). Useful when a
20
+ * request handler needs to guarantee its broadcast is persisted before
21
+ * responding — without this, the HTTP response can return before the
22
+ * async event-log write finishes. This is a snapshot barrier: work
23
+ * enqueued after the snapshot is not awaited, and the first rejection in
24
+ * snapshot order is rethrown after every snapshotted tail has settled.
17
25
  * @returns {Promise<void>}
18
26
  */
19
27
  awaitPendingBroadcasts(): Promise<void>;
@@ -48,13 +56,22 @@ export class VelociousHttpServerWebsocketEventsHost {
48
56
  configuration: import("../configuration.js").default;
49
57
  }): void;
50
58
  /**
51
- * Runs queue publish.
52
- * @param {() => Promise<void>} callback - Publish work to run in order.
53
- * @param {string} errorMessage - Message logged when publish work fails.
54
- * @param {import("../configuration.js").default} [originatingConfiguration] - Configuration whose context owns the work.
59
+ * Queues publish work behind the channel's own ordered tail so only work
60
+ * for the same channel serializes — a slow or failed channel never
61
+ * head-of-line blocks unrelated channels.
62
+ * @param {object} args - Options object.
63
+ * @param {() => Promise<void>} args.callback - Publish work to run in channel order.
64
+ * @param {string} args.channel - Channel whose ordered tail the work chains onto.
65
+ * @param {string} args.errorMessage - Message logged when publish work fails.
66
+ * @param {import("../configuration.js").default} [args.originatingConfiguration] - Configuration whose context owns the work.
55
67
  * @returns {void}
56
68
  */
57
- _queuePublish(callback: () => Promise<void>, errorMessage: string, originatingConfiguration?: import("../configuration.js").default): void;
69
+ _queuePublish({ callback, channel, errorMessage, originatingConfiguration }: {
70
+ callback: () => Promise<void>;
71
+ channel: string;
72
+ errorMessage: string;
73
+ originatingConfiguration?: import("../configuration.js").default | undefined;
74
+ }): void;
58
75
  /**
59
76
  * Runs persist v2 event if needed.
60
77
  * @param {object} args - Options.
@@ -1 +1 @@
1
- {"version":3,"file":"websocket-events-host.d.ts","sourceRoot":"","sources":["../../../src/http-server/websocket-events-host.js"],"names":[],"mappings":"AAIA;IAEI;;kEAE8D;IAC9D,UADU,GAAG,CAAC,OAAO,2BAA2B,EAAE,OAAO,CAAC,CACjC;IACzB;;8GAE0G;IAC1G,kCADU,GAAG,CAAC,OAAO,qBAAqB,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,2BAA2B,EAAE,OAAO,CAAC,CAAC,CACrD;IACjD,4BAAqC;IAGvC;;;;;;;OAOG;IACH,0BAFa,OAAO,CAAC,IAAI,CAAC,CAIzB;IAED;;;;OAIG;IACH,kBAHW,OAAO,2BAA2B,EAAE,OAAO,GACzC,MAAM,IAAI,CAqBtB;IAED;;;;;OAKG;IACH,uBAJW,MAAM,GAAG,MAAM,eACf,OAAC,GACC,IAAI,CAqBhB;IAED;;;;;;;;;;OAUG;IACH,+DANG;QAAqB,OAAO,EAApB,MAAM;QACkB,eAAe,EAAvC,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC;QACT,IAAI,EAAZ,OAAC;QAC2C,aAAa,EAAzD,OAAO,qBAAqB,EAAE,OAAO;KAC7C,GAAU,IAAI,CA0BhB;IAED;;;;;;OAMG;IACH,wBALW,MAAM,OAAO,CAAC,IAAI,CAAC,gBACnB,MAAM,6BACN,OAAO,qBAAqB,EAAE,OAAO,GACnC,IAAI,CAkBhB;IAED;;;;;;;OAOG;IACH,0DALG;QAAgB,IAAI,EAAZ,OAAC;QACY,OAAO,EAApB,MAAM;QACsC,aAAa,EAAzD,OAAO,qBAAqB,EAAE,OAAO;KAC7C,GAAU,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,CAAC,CAI3D;IAED;;;;;;OAMG;IACH,4CAJG;QAAqB,OAAO,EAApB,MAAM;QACE,OAAO,EAAf,OAAC;KACT,GAAU,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,CAAC,CAI3D;IAED;;;;;;;OAOG;IACH,kEALG;QAAqB,OAAO,EAApB,MAAM;QACE,OAAO,EAAf,OAAC;QAC4C,aAAa;KAClE,GAAU,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,CAAC,CAmB3D;CACF;;AAED,0EAAwE"}
1
+ {"version":3,"file":"websocket-events-host.d.ts","sourceRoot":"","sources":["../../../src/http-server/websocket-events-host.js"],"names":[],"mappings":"AAIA;IAEI;;kEAE8D;IAC9D,UADU,GAAG,CAAC,OAAO,2BAA2B,EAAE,OAAO,CAAC,CACjC;IACzB;;8GAE0G;IAC1G,kCADU,GAAG,CAAC,OAAO,qBAAqB,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,2BAA2B,EAAE,OAAO,CAAC,CAAC,CACrD;IACjD;;;;;4CAKwC;IACxC,wBADU,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CACG;IAGzC;;;;;;;;;OASG;IACH,0BAFa,OAAO,CAAC,IAAI,CAAC,CASzB;IAED;;;;OAIG;IACH,kBAHW,OAAO,2BAA2B,EAAE,OAAO,GACzC,MAAM,IAAI,CAqBtB;IAED;;;;;OAKG;IACH,uBAJW,MAAM,GAAG,MAAM,eACf,OAAC,GACC,IAAI,CAyBhB;IAED;;;;;;;;;;OAUG;IACH,+DANG;QAAqB,OAAO,EAApB,MAAM;QACkB,eAAe,EAAvC,MAAM,CAAC,MAAM,EAAE,OAAC,CAAC;QACT,IAAI,EAAZ,OAAC;QAC2C,aAAa,EAAzD,OAAO,qBAAqB,EAAE,OAAO;KAC7C,GAAU,IAAI,CAgChB;IAED;;;;;;;;;;OAUG;IACH,6EANG;QAAkC,QAAQ,EAAlC,MAAM,OAAO,CAAC,IAAI,CAAC;QACN,OAAO,EAApB,MAAM;QACO,YAAY,EAAzB,MAAM;QACuC,wBAAwB;KAC7E,GAAU,IAAI,CAkChB;IAED;;;;;;;OAOG;IACH,0DALG;QAAgB,IAAI,EAAZ,OAAC;QACY,OAAO,EAApB,MAAM;QACsC,aAAa,EAAzD,OAAO,qBAAqB,EAAE,OAAO;KAC7C,GAAU,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,CAAC,CAI3D;IAED;;;;;;OAMG;IACH,4CAJG;QAAqB,OAAO,EAApB,MAAM;QACE,OAAO,EAAf,OAAC;KACT,GAAU,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,CAAC,CAI3D;IAED;;;;;;;OAOG;IACH,kEALG;QAAqB,OAAO,EAApB,MAAM;QACE,OAAO,EAAf,OAAC;QAC4C,aAAa;KAClE,GAAU,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAC,GAAG,IAAI,CAAC,CAmB3D;CACF;;AAED,0EAAwE"}