ngx-atomic-i18n 0.1.0 → 0.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/ngx-atomic-i18n.mjs +19 -19
- package/fesm2022/ngx-atomic-i18n.mjs.map +1 -1
- package/package.json +8 -10
- package/types/ngx-atomic-i18n.d.ts +347 -0
- package/esm2022/lib/FIFO.model.mjs +0 -64
- package/esm2022/lib/translate.pipe.mjs +0 -18
- package/esm2022/lib/translate.provider.mjs +0 -121
- package/esm2022/lib/translate.token.mjs +0 -15
- package/esm2022/lib/translate.type.mjs +0 -10
- package/esm2022/lib/translate.util.mjs +0 -245
- package/esm2022/lib/translation-core.service.mjs +0 -312
- package/esm2022/lib/translation.directive.mjs +0 -35
- package/esm2022/lib/translation.loader.csr.mjs +0 -44
- package/esm2022/lib/translation.loader.ssr.mjs +0 -89
- package/esm2022/lib/translation.service.mjs +0 -165
- package/esm2022/ngx-atomic-i18n.mjs +0 -5
- package/esm2022/public-api.mjs +0 -15
- package/index.d.ts +0 -5
- package/lib/FIFO.model.d.ts +0 -21
- package/lib/translate.pipe.d.ts +0 -10
- package/lib/translate.provider.d.ts +0 -17
- package/lib/translate.token.d.ts +0 -15
- package/lib/translate.type.d.ts +0 -103
- package/lib/translate.util.d.ts +0 -28
- package/lib/translation-core.service.d.ts +0 -55
- package/lib/translation.directive.d.ts +0 -15
- package/lib/translation.loader.csr.d.ts +0 -10
- package/lib/translation.loader.ssr.d.ts +0 -17
- package/lib/translation.service.d.ts +0 -60
- package/public-api.d.ts +0 -11
|
@@ -1,245 +0,0 @@
|
|
|
1
|
-
import { effect, inject, Injector, runInInjectionContext } from "@angular/core";
|
|
2
|
-
import { Observable } from "rxjs";
|
|
3
|
-
/** Normalizes a language code against the configured supported languages. */
|
|
4
|
-
export function normalizeLangCode(lang, supportedLangs) {
|
|
5
|
-
if (!lang)
|
|
6
|
-
return null;
|
|
7
|
-
const variants = new Set();
|
|
8
|
-
variants.add(lang);
|
|
9
|
-
variants.add(lang.replace(/_/g, '-'));
|
|
10
|
-
variants.add(lang.replace(/-/g, '_'));
|
|
11
|
-
variants.add(lang.toLowerCase());
|
|
12
|
-
variants.add(lang.replace(/_/g, '-').toLowerCase());
|
|
13
|
-
for (const candidate of variants) {
|
|
14
|
-
const match = supportedLangs.find(supported => supported.toLowerCase() === candidate.toLowerCase());
|
|
15
|
-
if (match)
|
|
16
|
-
return match;
|
|
17
|
-
}
|
|
18
|
-
return null;
|
|
19
|
-
}
|
|
20
|
-
/** Determines the most appropriate language using the configured detection order. */
|
|
21
|
-
export function detectPreferredLang(config) {
|
|
22
|
-
const { supportedLangs, fallbackLang, langDetectionOrder } = config;
|
|
23
|
-
for (const source of langDetectionOrder) {
|
|
24
|
-
let lang;
|
|
25
|
-
switch (source) {
|
|
26
|
-
case 'url':
|
|
27
|
-
lang = typeof window !== 'undefined' ? window.location.pathname.split('/')[1] : null;
|
|
28
|
-
break;
|
|
29
|
-
case 'clientRequest':
|
|
30
|
-
lang = config.clientRequestLang ?? null;
|
|
31
|
-
break;
|
|
32
|
-
case 'localStorage':
|
|
33
|
-
lang = typeof window !== 'undefined' ? localStorage.getItem('lang') : null;
|
|
34
|
-
break;
|
|
35
|
-
case 'browser':
|
|
36
|
-
const langTag = globalThis?.navigator?.language ?? '';
|
|
37
|
-
lang = supportedLangs.find(s => langTag.startsWith(s)) ?? null;
|
|
38
|
-
break;
|
|
39
|
-
case 'customLang':
|
|
40
|
-
lang = typeof config.customLang === 'function' ? config.customLang() : config.customLang ?? null;
|
|
41
|
-
break;
|
|
42
|
-
case 'fallback':
|
|
43
|
-
lang = fallbackLang;
|
|
44
|
-
break;
|
|
45
|
-
}
|
|
46
|
-
const normalized = normalizeLangCode(lang, supportedLangs);
|
|
47
|
-
if (normalized) {
|
|
48
|
-
return normalized;
|
|
49
|
-
}
|
|
50
|
-
;
|
|
51
|
-
}
|
|
52
|
-
return normalizeLangCode(fallbackLang, supportedLangs) ?? fallbackLang;
|
|
53
|
-
}
|
|
54
|
-
/** Lightweight ICU parser that supports nested select/plural structures. */
|
|
55
|
-
export function parseICU(templateText, params) {
|
|
56
|
-
if (typeof params === 'object' ? !Object.keys(params).length : true)
|
|
57
|
-
return templateText;
|
|
58
|
-
const paramMap = {};
|
|
59
|
-
for (const [key, val] of Object.entries(params)) {
|
|
60
|
-
paramMap[key] = String(val);
|
|
61
|
-
}
|
|
62
|
-
function extractBlock(text, startIndex) {
|
|
63
|
-
let depth = 0;
|
|
64
|
-
let i = startIndex;
|
|
65
|
-
while (i < text.length) {
|
|
66
|
-
if (text[i] === '{') {
|
|
67
|
-
if (depth === 0)
|
|
68
|
-
startIndex = i;
|
|
69
|
-
depth++;
|
|
70
|
-
}
|
|
71
|
-
else if (text[i] === '}') {
|
|
72
|
-
depth--;
|
|
73
|
-
if (depth === 0)
|
|
74
|
-
return [text.slice(startIndex, i + 1), i + 1];
|
|
75
|
-
}
|
|
76
|
-
i++;
|
|
77
|
-
}
|
|
78
|
-
return [text.slice(startIndex), text.length];
|
|
79
|
-
}
|
|
80
|
-
function extractOptions(body) {
|
|
81
|
-
const options = {};
|
|
82
|
-
let i = 0;
|
|
83
|
-
while (i < body.length) {
|
|
84
|
-
while (body[i] === ' ')
|
|
85
|
-
i++;
|
|
86
|
-
let key = '';
|
|
87
|
-
while (i < body.length && body[i] !== '{' && body[i] !== ' ') {
|
|
88
|
-
key += body[i++];
|
|
89
|
-
}
|
|
90
|
-
while (i < body.length && body[i] === ' ')
|
|
91
|
-
i++;
|
|
92
|
-
if (body[i] !== '{') {
|
|
93
|
-
// Option must have a nested block; otherwise skip it.
|
|
94
|
-
i++;
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
const [block, next] = extractBlock(body, i);
|
|
98
|
-
options[key] = block.slice(1, -1);
|
|
99
|
-
i = next;
|
|
100
|
-
}
|
|
101
|
-
return options;
|
|
102
|
-
}
|
|
103
|
-
function resolveICU(text) {
|
|
104
|
-
text = text.replace(/\{\{(\w+)\}\}/g, (_, key) => paramMap[key] ?? '');
|
|
105
|
-
let result = '';
|
|
106
|
-
let cursor = 0;
|
|
107
|
-
while (cursor < text.length) {
|
|
108
|
-
const start = text.indexOf('{', cursor);
|
|
109
|
-
if (start === -1) {
|
|
110
|
-
result += text.slice(cursor);
|
|
111
|
-
break;
|
|
112
|
-
}
|
|
113
|
-
result += text.slice(cursor, start);
|
|
114
|
-
const [block, nextIndex] = extractBlock(text, start);
|
|
115
|
-
if (!block || block === '' || block === '{}') {
|
|
116
|
-
cursor = nextIndex;
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
const match = block.match(/^\{(\w+),\s*(plural|select),/);
|
|
120
|
-
if (!match) {
|
|
121
|
-
result += block;
|
|
122
|
-
cursor = nextIndex;
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
|
-
const [, varName, type] = match;
|
|
126
|
-
const rawVal = paramMap[varName] ?? '';
|
|
127
|
-
const numVal = Number(rawVal);
|
|
128
|
-
const body = block.slice(match[0].length, -1);
|
|
129
|
-
const options = extractOptions(body);
|
|
130
|
-
const selected = options[`=${rawVal}`] ||
|
|
131
|
-
(type === 'plural' && numVal === 1 && options['one']) ||
|
|
132
|
-
options[rawVal] ||
|
|
133
|
-
options['other'] ||
|
|
134
|
-
'';
|
|
135
|
-
if (!selected) {
|
|
136
|
-
result += block;
|
|
137
|
-
cursor = nextIndex;
|
|
138
|
-
continue;
|
|
139
|
-
}
|
|
140
|
-
let resolved = resolveICU(selected);
|
|
141
|
-
if (type === 'plural') {
|
|
142
|
-
resolved = resolved.replace(/#/g, rawVal);
|
|
143
|
-
}
|
|
144
|
-
resolved = resolved.replace(/{{(\w+)}}|\{(\w+)\}/g, (_, k1, k2) => {
|
|
145
|
-
const k = k1 || k2;
|
|
146
|
-
return paramMap[k] ?? '';
|
|
147
|
-
});
|
|
148
|
-
result += resolved;
|
|
149
|
-
cursor = nextIndex;
|
|
150
|
-
}
|
|
151
|
-
return result;
|
|
152
|
-
}
|
|
153
|
-
return resolveICU(templateText);
|
|
154
|
-
}
|
|
155
|
-
/** Flattens a nested translation object using dot notation keys. */
|
|
156
|
-
export function flattenTranslations(obj, prefix = '') {
|
|
157
|
-
const result = {};
|
|
158
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
159
|
-
const newKey = prefix ? `${prefix}.${key}` : key;
|
|
160
|
-
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
|
|
161
|
-
Object.assign(result, flattenTranslations(value, newKey));
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
result[newKey] = String(value);
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
return result;
|
|
168
|
-
}
|
|
169
|
-
/** Converts a signal to an observable while preserving injection context. */
|
|
170
|
-
export function toObservable(signal) {
|
|
171
|
-
const injector = inject(Injector);
|
|
172
|
-
return new Observable(subscribe => {
|
|
173
|
-
subscribe.next(signal());
|
|
174
|
-
const stop = runInInjectionContext(injector, () => effect(() => subscribe.next(signal()), { allowSignalWrites: true }));
|
|
175
|
-
return () => stop.destroy();
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
/** Deeply merges plain objects, replacing non-object values by assignment. */
|
|
179
|
-
export function deepMerge(target, source) {
|
|
180
|
-
const output = { ...target };
|
|
181
|
-
for (const key in source) {
|
|
182
|
-
const targetValue = target[key];
|
|
183
|
-
if (source.hasOwnProperty(key) &&
|
|
184
|
-
typeof source[key] === 'object' &&
|
|
185
|
-
source[key] !== null &&
|
|
186
|
-
!Array.isArray(source[key]) &&
|
|
187
|
-
typeof targetValue === 'object' &&
|
|
188
|
-
targetValue !== null &&
|
|
189
|
-
!Array.isArray(targetValue)) {
|
|
190
|
-
output[key] = deepMerge(targetValue, source[key]);
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
output[key] = source[key];
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return output;
|
|
197
|
-
}
|
|
198
|
-
/** Recursively retains only keys that are not already present in the existing object. */
|
|
199
|
-
export function filterNewKeysDeep(bundle, existing) {
|
|
200
|
-
const result = {};
|
|
201
|
-
for (const key in bundle) {
|
|
202
|
-
const existValue = existing[key];
|
|
203
|
-
if (typeof bundle[key] === 'object' &&
|
|
204
|
-
bundle[key] !== null &&
|
|
205
|
-
!Array.isArray(bundle[key]) &&
|
|
206
|
-
typeof existValue === 'object' &&
|
|
207
|
-
existValue !== null &&
|
|
208
|
-
!Array.isArray(existValue)) {
|
|
209
|
-
result[key] = filterNewKeysDeep(bundle[key], existValue);
|
|
210
|
-
}
|
|
211
|
-
else if (!(key in existing)) {
|
|
212
|
-
result[key] = bundle[key];
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
return result;
|
|
216
|
-
}
|
|
217
|
-
/** Safely reads a dotted path from a nested object. */
|
|
218
|
-
export function getNested(obj, path) {
|
|
219
|
-
return path.split('.').reduce((res, key) => res?.[key], obj);
|
|
220
|
-
}
|
|
221
|
-
/** Removes any leading slashes from path-like strings. */
|
|
222
|
-
export const stripLeadingSep = (s) => s.replace(/^[\\/]+/, '');
|
|
223
|
-
/** Normalises the path template configuration to an array form. */
|
|
224
|
-
export const tempToArray = (template) => Array.isArray(template) ? template : (template ? [template] : undefined);
|
|
225
|
-
/**
|
|
226
|
-
* Detect current build version from injected script names (CSR only).
|
|
227
|
-
* Matches filenames like: main.<hash>.js, runtime.<hash>.js, polyfills.<hash>.js
|
|
228
|
-
*/
|
|
229
|
-
export function detectBuildVersion() {
|
|
230
|
-
try {
|
|
231
|
-
if (typeof document === 'undefined' || !document?.scripts)
|
|
232
|
-
return null;
|
|
233
|
-
const regex = /\/(?:main|runtime|polyfills)\.([a-f0-9]{8,})\.[^\/]*\.js(?:\?|$)/i;
|
|
234
|
-
for (const s of Array.from(document.scripts)) {
|
|
235
|
-
const version = regex.exec(s.src);
|
|
236
|
-
if (version?.[1])
|
|
237
|
-
return version[1];
|
|
238
|
-
}
|
|
239
|
-
return null;
|
|
240
|
-
}
|
|
241
|
-
catch {
|
|
242
|
-
return null;
|
|
243
|
-
}
|
|
244
|
-
}
|
|
245
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnV0aWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtYXRvbWljLWkxOG4vc3JjL2xpYi90cmFuc2xhdGUudXRpbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sRUFBRSxRQUFRLEVBQUUscUJBQXFCLEVBQVUsTUFBTSxlQUFlLENBQUM7QUFFeEYsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUVsQyw2RUFBNkU7QUFDN0UsTUFBTSxVQUFVLGlCQUFpQixDQUMvQixJQUErQixFQUMvQixjQUF3QjtJQUV4QixJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQ3ZCLE1BQU0sUUFBUSxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7SUFDbkMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUNuQixRQUFRLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDdEMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQ3RDLFFBQVEsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUM7SUFDakMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxHQUFHLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxDQUFDO0lBQ3BELEtBQUssTUFBTSxTQUFTLElBQUksUUFBUSxFQUFFLENBQUM7UUFDakMsTUFBTSxLQUFLLEdBQUcsY0FBYyxDQUFDLElBQUksQ0FDL0IsU0FBUyxDQUFDLEVBQUUsQ0FBQyxTQUFTLENBQUMsV0FBVyxFQUFFLEtBQUssU0FBUyxDQUFDLFdBQVcsRUFBRSxD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QUFFLENBQUM7WUFDN0MsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBRSxDQUF1QixDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3pELElBQUksT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO2dCQUFFLE9BQU8sT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFBQyxNQUFNLENBQUM7UUFDUCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZWZmZWN0LCBpbmplY3QsIEluamVjdG9yLCBydW5JbkluamVjdGlvbkNvbnRleHQsIFNpZ25hbCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBEZWVwUGFydGlhbCwgUGF0aFRlbXBsYXRlLCBUcmFuc2xhdGlvbkNvbmZpZyB9IGZyb20gXCIuL3RyYW5zbGF0ZS50eXBlXCI7XG5pbXBvcnQgeyBPYnNlcnZhYmxlIH0gZnJvbSBcInJ4anNcIjtcblxuLyoqIE5vcm1hbGl6ZXMgYSBsYW5ndWFnZSBjb2RlIGFnYWluc3QgdGhlIGNvbmZpZ3VyZWQgc3VwcG9ydGVkIGxhbmd1YWdlcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVMYW5nQ29kZShcbiAgbGFuZzogc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCxcbiAgc3VwcG9ydGVkTGFuZ3M6IHN0cmluZ1tdXG4pOiBzdHJpbmcgfCBudWxsIHtcbiAgaWYgKCFsYW5nKSByZXR1cm4gbnVsbDtcbiAgY29uc3QgdmFyaWFudHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgdmFyaWFudHMuYWRkKGxhbmcpO1xuICB2YXJpYW50cy5hZGQobGFuZy5yZXBsYWNlKC9fL2csICctJykpO1xuICB2YXJpYW50cy5hZGQobGFuZy5yZXBsYWNlKC8tL2csICdfJykpO1xuICB2YXJpYW50cy5hZGQobGFuZy50b0xvd2VyQ2FzZSgpKTtcbiAgdmFyaWFudHMuYWRkKGxhbmcucmVwbGFjZSgvXy9nLCAnLScpLnRvTG93ZXJDYXNlKCkpO1xuICBmb3IgKGNvbnN0IGNhbmRpZGF0ZSBvZiB2YXJpYW50cykge1xuICAgIGNvbnN0IG1hdGNoID0gc3VwcG9ydGVkTGFuZ3MuZmluZChcbiAgICAgIHN1cHBvcnRlZCA9PiBzdXBwb3J0ZWQudG9Mb3dlckNhc2UoKSA9PT0gY2FuZGlkYXRlLnRvTG93ZXJDYXNlKClcbiAgICApO1xuICAgIGlmIChtYXRjaCkgcmV0dXJuIG1hdGNoO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKiogRGV0ZXJtaW5lcyB0aGUgbW9zdCBhcHByb3ByaWF0ZSBsYW5ndWFnZSB1c2luZyB0aGUgY29uZmlndXJlZCBkZXRlY3Rpb24gb3JkZXIuICovXG5leHBvcnQgZnVuY3Rpb24gZGV0ZWN0UHJlZmVycmVkTGFuZyhjb25maWc6IFRyYW5zbGF0aW9uQ29uZmlnKTogc3RyaW5nIHtcbiAgY29uc3QgeyBzdXBwb3J0ZWRMYW5ncywgZmFsbGJhY2tMYW5nLCBsYW5nRGV0ZWN0aW9uT3JkZXIgfSA9IGNvbmZpZztcbiAgZm9yIChjb25zdCBzb3VyY2Ugb2YgbGFuZ0RldGVjdGlvbk9yZGVyKSB7XG4gICAgbGV0IGxhbmc6IHN0cmluZyB8IG51bGw7XG4gICAgc3dpdGNoIChzb3VyY2UpIHtcbiAgICAgIGNhc2UgJ3VybCc6XG4gICAgICAgIGxhbmcgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZS5zcGxpdCgnLycpWzFdIDogbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdjbGllbnRSZXF1ZXN0JzpcbiAgICAgICAgbGFuZyA9IGNvbmZpZy5jbGllbnRSZXF1ZXN0TGFuZyA/PyBudWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2xvY2FsU3RvcmFnZSc6XG4gICAgICAgIGxhbmcgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IGxvY2FsU3RvcmFnZS5nZXRJdGVtKCdsYW5nJykgOiBudWxsO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2Jyb3dzZXInOlxuICAgICAgICBjb25zdCBsYW5nVGFnID0gKGdsb2JhbFRoaXMgYXMgYW55KT8ubmF2aWdhdG9yPy5sYW5ndWFnZSA/PyAnJztcbiAgICAgICAgbGFuZyA9IHN1cHBvcnRlZExhbmdzLmZpbmQocyA9PiBsYW5nVGFnLnN0YXJ0c1dpdGgocykpID8/IG51bGw7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnY3VzdG9tTGFuZyc6XG4gICAgICAgIGxhbmcgPSB0eXBlb2YgY29uZmlnLmN1c3RvbUxhbmcgPT09ICdmdW5jdGlvbicgPyBjb25maWcuY3VzdG9tTGFuZygpIDogY29uZmlnLmN1c3RvbUxhbmcgPz8gbnVsbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdmYWxsYmFjayc6XG4gICAgICAgIGxhbmcgPSBmYWxsYmFja0xhbmc7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb25zdCBub3JtYWxpemVkID0gbm9ybWFsaXplTGFuZ0NvZGUobGFuZywgc3VwcG9ydGVkTGFuZ3MpO1xuICAgIGlmIChub3JtYWxpemVkKSB7XG4gICAgICByZXR1cm4gbm9ybWFsaXplZDtcbiAgICB9O1xuICB9XG4gIHJldHVybiBub3JtYWxpemVMYW5nQ29kZShmYWxsYmFja0xhbmcsIHN1cHBvcnRlZExhbmdzKSA/PyBmYWxsYmFja0xhbmc7XG59XG5cbi8qKiBMaWdodHdlaWdodCBJQ1UgcGFyc2VyIHRoYXQgc3VwcG9ydHMgbmVzdGVkIHNlbGVjdC9wbHVyYWwgc3RydWN0dXJlcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUlDVSh0ZW1wbGF0ZVRleHQ6IHN0cmluZywgcGFyYW1zPzogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyPik6IHN0cmluZyB7XG4gIGlmICh0eXBlb2YgcGFyYW1zID09PSAnb2JqZWN0JyA/ICFPYmplY3Qua2V5cyhwYXJhbXMpLmxlbmd0aCA6IHRydWUpIHJldHVybiB0ZW1wbGF0ZVRleHQ7XG5cbiAgY29uc3QgcGFyYW1NYXA6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgZm9yIChjb25zdCBba2V5LCB2YWxdIG9mIE9iamVjdC5lbnRyaWVzKHBhcmFtcyEpKSB7XG4gICAgcGFyYW1NYXBba2V5XSA9IFN0cmluZyh2YWwpO1xuICB9XG5cbiAgZnVuY3Rpb24gZXh0cmFjdEJsb2NrKHRleHQ6IHN0cmluZywgc3RhcnRJbmRleDogbnVtYmVyKTogW3N0cmluZywgbnVtYmVyXSB7XG4gICAgbGV0IGRlcHRoID0gMDtcbiAgICBsZXQgaSA9IHN0YXJ0SW5kZXg7XG4gICAgd2hpbGUgKGkgPCB0ZXh0Lmxlbmd0aCkge1xuICAgICAgaWYgKHRleHRbaV0gPT09ICd7Jykge1xuICAgICAgICBpZiAoZGVwdGggPT09IDApIHN0YXJ0SW5kZXggPSBpO1xuICAgICAgICBkZXB0aCsrO1xuICAgICAgfSBlbHNlIGlmICh0ZXh0W2ldID09PSAnfScpIHtcbiAgICAgICAgZGVwdGgtLTtcbiAgICAgICAgaWYgKGRlcHRoID09PSAwKSByZXR1cm4gW3RleHQuc2xpY2Uoc3RhcnRJbmRleCwgaSArIDEpLCBpICsgMV07XG4gICAgICB9XG4gICAgICBpKys7XG4gICAgfVxuICAgIHJldHVybiBbdGV4dC5zbGljZShzdGFydEluZGV4KSwgdGV4dC5sZW5ndGhdO1xuICB9XG5cbiAgZnVuY3Rpb24gZXh0cmFjdE9wdGlvbnMoYm9keTogc3RyaW5nKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gICAgY29uc3Qgb3B0aW9uczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICAgIGxldCBpID0gMDtcbiAgICB3aGlsZSAoaSA8IGJvZHkubGVuZ3RoKSB7XG4gICAgICB3aGlsZSAoYm9keVtpXSA9PT0gJyAnKSBpKys7XG4gICAgICBsZXQga2V5ID0gJyc7XG4gICAgICB3aGlsZSAoaSA8IGJvZHkubGVuZ3RoICYmIGJvZHlbaV0gIT09ICd7JyAmJiBib2R5W2ldICE9PSAnICcpIHtcbiAgICAgICAga2V5ICs9IGJvZHlbaSsrXTtcbiAgICAgIH1cbiAgICAgIHdoaWxlIChpIDwgYm9keS5sZW5ndGggJiYgYm9keVtpXSA9PT0gJyAnKSBpKys7XG4gICAgICBpZiAoYm9keVtpXSAhPT0gJ3snKSB7XG4gICAgICAgIC8vIE9wdGlvbiBtdXN0IGhhdmUgYSBuZXN0ZWQgYmxvY2s7IG90aGVyd2lzZSBza2lwIGl0LlxuICAgICAgICBpKys7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgW2Jsb2NrLCBuZXh0XSA9IGV4dHJhY3RCbG9jayhib2R5LCBpKTtcbiAgICAgIG9wdGlvbnNba2V5XSA9IGJsb2NrLnNsaWNlKDEsIC0xKTtcbiAgICAgIGkgPSBuZXh0O1xuICAgIH1cbiAgICByZXR1cm4gb3B0aW9ucztcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc29sdmVJQ1UodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICB0ZXh0ID0gdGV4dC5yZXBsYWNlKC9cXHtcXHsoXFx3KylcXH1cXH0vZywgKF8sIGtleSkgPT4gcGFyYW1NYXBba2V5XSA/PyAnJyk7XG4gICAgbGV0IHJlc3VsdCA9ICcnO1xuICAgIGxldCBjdXJzb3IgPSAwO1xuXG4gICAgd2hpbGUgKGN1cnNvciA8IHRleHQubGVuZ3RoKSB7XG4gICAgICBjb25zdCBzdGFydCA9IHRleHQuaW5kZXhPZigneycsIGN1cnNvcik7XG4gICAgICBpZiAoc3RhcnQgPT09IC0xKSB7XG4gICAgICAgIHJlc3VsdCArPSB0ZXh0LnNsaWNlKGN1cnNvcik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICByZXN1bHQgKz0gdGV4dC5zbGljZShjdXJzb3IsIHN0YXJ0KTtcblxuICAgICAgY29uc3QgW2Jsb2NrLCBuZXh0SW5kZXhdID0gZXh0cmFjdEJsb2NrKHRleHQsIHN0YXJ0KTtcblxuICAgICAgaWYgKCFibG9jayB8fCBibG9jayA9PT0gJycgfHwgYmxvY2sgPT09ICd7fScpIHtcbiAgICAgICAgY3Vyc29yID0gbmV4dEluZGV4O1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbWF0Y2ggPSBibG9jay5tYXRjaCgvXlxceyhcXHcrKSxcXHMqKHBsdXJhbHxzZWxlY3QpLC8pO1xuICAgICAgaWYgKCFtYXRjaCkge1xuICAgICAgICByZXN1bHQgKz0gYmxvY2s7XG4gICAgICAgIGN1cnNvciA9IG5leHRJbmRleDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IFssIHZhck5hbWUsIHR5cGVdID0gbWF0Y2g7XG4gICAgICBjb25zdCByYXdWYWwgPSBwYXJhbU1hcFt2YXJOYW1lXSA/PyAnJztcbiAgICAgIGNvbnN0IG51bVZhbCA9IE51bWJlcihyYXdWYWwpO1xuICAgICAgY29uc3QgYm9keSA9IGJsb2NrLnNsaWNlKG1hdGNoWzBdLmxlbmd0aCwgLTEpO1xuICAgICAgY29uc3Qgb3B0aW9ucyA9IGV4dHJhY3RPcHRpb25zKGJvZHkpO1xuXG4gICAgICBjb25zdCBzZWxlY3RlZCA9XG4gICAgICAgIG9wdGlvbnNbYD0ke3Jhd1ZhbH1gXSB8fFxuICAgICAgICAodHlwZSA9PT0gJ3BsdXJhbCcgJiYgbnVtVmFsID09PSAxICYmIG9wdGlvbnNbJ29uZSddKSB8fFxuICAgICAgICBvcHRpb25zW3Jhd1ZhbF0gfHxcbiAgICAgICAgb3B0aW9uc1snb3RoZXInXSB8fFxuICAgICAgICAnJztcblxuICAgICAgaWYgKCFzZWxlY3RlZCkge1xuICAgICAgICByZXN1bHQgKz0gYmxvY2s7XG4gICAgICAgIGN1cnNvciA9IG5leHRJbmRleDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGxldCByZXNvbHZlZCA9IHJlc29sdmVJQ1Uoc2VsZWN0ZWQpO1xuXG4gICAgICBpZiAodHlwZSA9PT0gJ3BsdXJhbCcpIHtcbiAgICAgICAgcmVzb2x2ZWQgPSByZXNvbHZlZC5yZXBsYWNlKC8jL2csIHJhd1ZhbCk7XG4gICAgICB9XG5cbiAgICAgIHJlc29sdmVkID0gcmVzb2x2ZWQucmVwbGFjZSgve3soXFx3Kyl9fXxcXHsoXFx3KylcXH0vZywgKF8sIGsxLCBrMikgPT4ge1xuICAgICAgICBjb25zdCBrID0gazEgfHwgazI7XG4gICAgICAgIHJldHVybiBwYXJhbU1hcFtrXSA/PyAnJztcbiAgICAgIH0pO1xuXG4gICAgICByZXN1bHQgKz0gcmVzb2x2ZWQ7XG4gICAgICBjdXJzb3IgPSBuZXh0SW5kZXg7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHJldHVybiByZXNvbHZlSUNVKHRlbXBsYXRlVGV4dCk7XG59XG5cblxuXG4vKiogRmxhdHRlbnMgYSBuZXN0ZWQgdHJhbnNsYXRpb24gb2JqZWN0IHVzaW5nIGRvdCBub3RhdGlvbiBrZXlzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZsYXR0ZW5UcmFuc2xhdGlvbnMob2JqOiBhbnksIHByZWZpeCA9ICcnKTogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB7XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuICBmb3IgKGNvbnN0IFtrZXksIHZhbHVlXSBvZiBPYmplY3QuZW50cmllcyhvYmopKSB7XG4gICAgY29uc3QgbmV3S2V5ID0gcHJlZml4ID8gYCR7cHJlZml4fS4ke2tleX1gIDoga2V5O1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgICAgT2JqZWN0LmFzc2lnbihyZXN1bHQsIGZsYXR0ZW5UcmFuc2xhdGlvbnModmFsdWUsIG5ld0tleSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXN1bHRbbmV3S2V5XSA9IFN0cmluZyh2YWx1ZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiByZXN1bHQ7XG59XG5cblxuLyoqIENvbnZlcnRzIGEgc2lnbmFsIHRvIGFuIG9ic2VydmFibGUgd2hpbGUgcHJlc2VydmluZyBpbmplY3Rpb24gY29udGV4dC4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b09ic2VydmFibGU8VD4oc2lnbmFsOiBTaWduYWw8VD4pOiBPYnNlcnZhYmxlPFQ+IHtcbiAgY29uc3QgaW5qZWN0b3IgPSBpbmplY3QoSW5qZWN0b3IpO1xuICByZXR1cm4gbmV3IE9ic2VydmFibGUoc3Vic2NyaWJlID0+IHtcbiAgICBzdWJzY3JpYmUubmV4dChzaWduYWwoKSk7XG4gICAgY29uc3Qgc3RvcCA9IHJ1bkluSW5qZWN0aW9uQ29udGV4dChpbmplY3RvciwgKCkgPT4gZWZmZWN0KCgpID0+IHN1YnNjcmliZS5uZXh0KHNpZ25hbCgpKSwgeyBhbGxvd1NpZ25hbFdyaXRlczogdHJ1ZSB9KSk7XG4gICAgcmV0dXJuICgpID0+IHN0b3AuZGVzdHJveSgpO1xuICB9KTtcbn1cblxuXG4vKiogRGVlcGx5IG1lcmdlcyBwbGFpbiBvYmplY3RzLCByZXBsYWNpbmcgbm9uLW9iamVjdCB2YWx1ZXMgYnkgYXNzaWdubWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkZWVwTWVyZ2U8VCBleHRlbmRzIG9iamVjdCwgVSBleHRlbmRzIG9iamVjdD4odGFyZ2V0OiBULCBzb3VyY2U6IFUpOiBUICYgVSB7XG4gIGNvbnN0IG91dHB1dCA9IHsgLi4udGFyZ2V0IH0gYXMgVCAmIFU7XG4gIGZvciAoY29uc3Qga2V5IGluIHNvdXJjZSkge1xuICAgIGNvbnN0IHRhcmdldFZhbHVlID0gKHRhcmdldCBhcyBhbnkpW2tleV07XG4gICAgaWYgKFxuICAgICAgc291cmNlLmhhc093blByb3BlcnR5KGtleSkgJiZcbiAgICAgIHR5cGVvZiBzb3VyY2Vba2V5XSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHNvdXJjZVtrZXldICE9PSBudWxsICYmXG4gICAgICAhQXJyYXkuaXNBcnJheShzb3VyY2Vba2V5XSkgJiZcbiAgICAgIHR5cGVvZiB0YXJnZXRWYWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICAgIHRhcmdldFZhbHVlICE9PSBudWxsICYmXG4gICAgICAhQXJyYXkuaXNBcnJheSh0YXJnZXRWYWx1ZSlcbiAgICApIHtcbiAgICAgIG91dHB1dFtrZXldID0gZGVlcE1lcmdlKHRhcmdldFZhbHVlIGFzIGFueSwgc291cmNlW2tleV0gYXMgYW55KTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3V0cHV0W2tleV0gPSBzb3VyY2Vba2V5XSBhcyBhbnk7XG4gICAgfVxuICB9XG4gIHJldHVybiBvdXRwdXQ7XG59XG5cbi8qKiBSZWN1cnNpdmVseSByZXRhaW5zIG9ubHkga2V5cyB0aGF0IGFyZSBub3QgYWxyZWFkeSBwcmVzZW50IGluIHRoZSBleGlzdGluZyBvYmplY3QuICovXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyTmV3S2V5c0RlZXA8VCBleHRlbmRzIG9iamVjdCwgVSBleHRlbmRzIG9iamVjdD4oYnVuZGxlOiBULCBleGlzdGluZzogVSk6IERlZXBQYXJ0aWFsPFQ+IHtcbiAgY29uc3QgcmVzdWx0ID0ge30gYXMgUGFydGlhbDxUPjtcbiAgZm9yIChjb25zdCBrZXkgaW4gYnVuZGxlKSB7XG4gICAgY29uc3QgZXhpc3RWYWx1ZSA9IChleGlzdGluZyBhcyBhbnkpW2tleV07XG4gICAgaWYgKFxuICAgICAgdHlwZW9mIGJ1bmRsZVtrZXldID09PSAnb2JqZWN0JyAmJlxuICAgICAgYnVuZGxlW2tleV0gIT09IG51bGwgJiZcbiAgICAgICFBcnJheS5pc0FycmF5KGJ1bmRsZVtrZXldKSAmJlxuICAgICAgdHlwZW9mIGV4aXN0VmFsdWUgPT09ICdvYmplY3QnICYmXG4gICAgICBleGlzdFZhbHVlICE9PSBudWxsICYmXG4gICAgICAhQXJyYXkuaXNBcnJheShleGlzdFZhbHVlKVxuICAgICkge1xuICAgICAgcmVzdWx0W2tleV0gPSBmaWx0ZXJOZXdLZXlzRGVlcChidW5kbGVba2V5XSwgZXhpc3RWYWx1ZSkgYXMgYW55O1xuICAgIH0gZWxzZSBpZiAoIShrZXkgaW4gZXhpc3RpbmcpKSB7XG4gICAgICByZXN1bHRba2V5XSA9IGJ1bmRsZVtrZXldO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKiogU2FmZWx5IHJlYWRzIGEgZG90dGVkIHBhdGggZnJvbSBhIG5lc3RlZCBvYmplY3QuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmVzdGVkKG9iajogYW55LCBwYXRoOiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICByZXR1cm4gcGF0aC5zcGxpdCgnLicpLnJlZHVjZSgocmVzLCBrZXkpID0+IHJlcz8uW2tleV0sIG9iaik7XG59XG5cbi8qKiBSZW1vdmVzIGFueSBsZWFkaW5nIHNsYXNoZXMgZnJvbSBwYXRoLWxpa2Ugc3RyaW5ncy4gKi9cbmV4cG9ydCBjb25zdCBzdHJpcExlYWRpbmdTZXAgPSAoczogc3RyaW5nKSA9PiBzLnJlcGxhY2UoL15bXFxcXC9dKy8sICcnKTtcblxuLyoqIE5vcm1hbGlzZXMgdGhlIHBhdGggdGVtcGxhdGUgY29uZmlndXJhdGlvbiB0byBhbiBhcnJheSBmb3JtLiAqL1xuZXhwb3J0IGNvbnN0IHRlbXBUb0FycmF5ID0gKHRlbXBsYXRlOiBQYXRoVGVtcGxhdGUpID0+IEFycmF5LmlzQXJyYXkodGVtcGxhdGUpID8gdGVtcGxhdGUgOiAodGVtcGxhdGUgPyBbdGVtcGxhdGVdIDogdW5kZWZpbmVkKTtcblxuLyoqXG4gKiBEZXRlY3QgY3VycmVudCBidWlsZCB2ZXJzaW9uIGZyb20gaW5qZWN0ZWQgc2NyaXB0IG5hbWVzIChDU1Igb25seSkuXG4gKiBNYXRjaGVzIGZpbGVuYW1lcyBsaWtlOiBtYWluLjxoYXNoPi5qcywgcnVudGltZS48aGFzaD4uanMsIHBvbHlmaWxscy48aGFzaD4uanNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGRldGVjdEJ1aWxkVmVyc2lvbigpOiBzdHJpbmcgfCBudWxsIHtcbiAgdHJ5IHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJyB8fCAhZG9jdW1lbnQ/LnNjcmlwdHMpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHJlZ2V4ID0gL1xcLyg/Om1haW58cnVudGltZXxwb2x5ZmlsbHMpXFwuKFthLWYwLTldezgsfSlcXC5bXlxcL10qXFwuanMoPzpcXD98JCkvaTtcbiAgICBmb3IgKGNvbnN0IHMgb2YgQXJyYXkuZnJvbShkb2N1bWVudC5zY3JpcHRzKSkge1xuICAgICAgY29uc3QgdmVyc2lvbiA9IHJlZ2V4LmV4ZWMoKHMgYXMgSFRNTFNjcmlwdEVsZW1lbnQpLnNyYyk7XG4gICAgICBpZiAodmVyc2lvbj8uWzFdKSByZXR1cm4gdmVyc2lvblsxXTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH0gY2F0Y2gge1xuICAgIHJldHVybiBudWxsO1xuICB9XG59XG4iXX0=
|