ngx-atomic-i18n 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/esm2022/lib/FIFO.model.mjs +64 -0
- package/esm2022/lib/translate.pipe.mjs +18 -0
- package/esm2022/lib/translate.provider.mjs +121 -0
- package/esm2022/lib/translate.token.mjs +15 -0
- package/esm2022/lib/translate.type.mjs +10 -0
- package/esm2022/lib/translate.util.mjs +245 -0
- package/esm2022/lib/translation-core.service.mjs +312 -0
- package/esm2022/lib/translation.directive.mjs +35 -0
- package/esm2022/lib/translation.loader.csr.mjs +44 -0
- package/esm2022/lib/translation.loader.ssr.mjs +89 -0
- package/esm2022/lib/translation.service.mjs +165 -0
- package/esm2022/ngx-atomic-i18n.mjs +5 -0
- package/esm2022/public-api.mjs +15 -0
- package/fesm2022/ngx-atomic-i18n.mjs +1099 -0
- package/fesm2022/ngx-atomic-i18n.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/FIFO.model.d.ts +21 -0
- package/lib/translate.pipe.d.ts +10 -0
- package/lib/translate.provider.d.ts +17 -0
- package/lib/translate.token.d.ts +15 -0
- package/lib/translate.type.d.ts +103 -0
- package/lib/translate.util.d.ts +28 -0
- package/lib/translation-core.service.d.ts +55 -0
- package/lib/translation.directive.d.ts +15 -0
- package/lib/translation.loader.csr.d.ts +10 -0
- package/lib/translation.loader.ssr.d.ts +17 -0
- package/lib/translation.service.d.ts +60 -0
- package/package.json +48 -0
- package/public-api.d.ts +11 -0
package/README.md
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# NgxComponentTranslate
|
|
2
|
+
|
|
3
|
+
This library was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.2.0.
|
|
4
|
+
|
|
5
|
+
## Code scaffolding
|
|
6
|
+
|
|
7
|
+
Run `ng generate component component-name --project ngx-atomic-i18n` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module --project ngx-atomic-i18n`.
|
|
8
|
+
> Note: Don't forget to add `--project ngx-atomic-i18n` or else it will be added to the default project in your `angular.json` file.
|
|
9
|
+
|
|
10
|
+
## Build
|
|
11
|
+
|
|
12
|
+
Run `ng build ngx-atomic-i18n` to build the project. The build artifacts will be stored in the `dist/` directory.
|
|
13
|
+
|
|
14
|
+
## Publishing
|
|
15
|
+
|
|
16
|
+
After building your library with `ng build ngx-atomic-i18n`, go to the dist folder `cd dist/ngx-atomic-i18n` and run `npm publish`.
|
|
17
|
+
|
|
18
|
+
## Running unit tests
|
|
19
|
+
|
|
20
|
+
Run `ng test ngx-atomic-i18n` to execute the unit tests via [Karma](https://karma-runner.github.io).
|
|
21
|
+
|
|
22
|
+
## Further help
|
|
23
|
+
|
|
24
|
+
To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.dev/tools/cli) page.
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/** Combined FIFO/LRU cache used to store compiled formatters. */
|
|
2
|
+
export class FIFOCache {
|
|
3
|
+
max;
|
|
4
|
+
map = new Map();
|
|
5
|
+
get size() {
|
|
6
|
+
return this.map.size;
|
|
7
|
+
}
|
|
8
|
+
constructor(max) {
|
|
9
|
+
this.max = max;
|
|
10
|
+
}
|
|
11
|
+
set(key, value) {
|
|
12
|
+
if (this.map.has(key)) {
|
|
13
|
+
this.map.delete(key);
|
|
14
|
+
}
|
|
15
|
+
this.map.set(key, value);
|
|
16
|
+
if (this.map.size > this.max) {
|
|
17
|
+
const first = this.map.keys().next().value;
|
|
18
|
+
if (first) {
|
|
19
|
+
this.map.delete(first);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
get(key) {
|
|
24
|
+
const val = this.map.get(key);
|
|
25
|
+
// Refresh recency on hit so frequently used entries stay resident.
|
|
26
|
+
if (val !== undefined) {
|
|
27
|
+
this.map.delete(key);
|
|
28
|
+
this.map.set(key, val);
|
|
29
|
+
}
|
|
30
|
+
return val;
|
|
31
|
+
}
|
|
32
|
+
has(key) {
|
|
33
|
+
return this.map.has(key);
|
|
34
|
+
}
|
|
35
|
+
delete(k) {
|
|
36
|
+
this.map.delete(k);
|
|
37
|
+
}
|
|
38
|
+
clear() {
|
|
39
|
+
this.map.clear();
|
|
40
|
+
}
|
|
41
|
+
/** Utility helper for controlled external iteration/manipulation. */
|
|
42
|
+
keys() {
|
|
43
|
+
return this.map.keys();
|
|
44
|
+
}
|
|
45
|
+
/** Iterates cached values without exposing the backing Map. */
|
|
46
|
+
forEach(cb) {
|
|
47
|
+
this.map.forEach((v, k) => cb(v, k));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Delete all entries that match the predicate.
|
|
51
|
+
* Returns the number of deleted entries.
|
|
52
|
+
*/
|
|
53
|
+
deleteWhere(predicate) {
|
|
54
|
+
let count = 0;
|
|
55
|
+
for (const [k, v] of this.map) {
|
|
56
|
+
if (predicate(k, v)) {
|
|
57
|
+
this.map.delete(k);
|
|
58
|
+
count++;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return count;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRklGTy5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1hdG9taWMtaTE4bi9zcmMvbGliL0ZJRk8ubW9kZWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsaUVBQWlFO0FBQ2pFLE1BQU0sT0FBTyxTQUFTO0lBS0U7SUFKWixHQUFHLEdBQUcsSUFBSSxHQUFHLEVBQVEsQ0FBQztJQUM5QixJQUFJLElBQUk7UUFDSixPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDO0lBQ3pCLENBQUM7SUFDRCxZQUFvQixHQUFXO1FBQVgsUUFBRyxHQUFILEdBQUcsQ0FBUTtJQUFJLENBQUM7SUFDcEMsR0FBRyxDQUFDLEdBQU0sRUFBRSxLQUFRO1FBQ2hCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QixDQUFDO1FBQ0QsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3pCLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1lBQzNCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDO1lBQzNDLElBQUksS0FBSyxFQUFFLENBQUM7Z0JBQ1IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDM0IsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBQ0QsR0FBRyxDQUFDLEdBQU07UUFDTixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM5QixtRUFBbUU7UUFDbkUsSUFBSSxHQUFHLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDcEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDckIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzNCLENBQUM7UUFDRCxPQUFPLEdBQUcsQ0FBQztJQUNmLENBQUM7SUFDRCxHQUFHLENBQUMsR0FBTTtRQUNOLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUNELE1BQU0sQ0FBQyxDQUFJO1FBQ1AsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQUNELEtBQUs7UUFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxxRUFBcUU7SUFDckUsSUFBSTtRQUNBLE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQsK0RBQStEO0lBQy9ELE9BQU8sQ0FBQyxFQUE4QjtRQUNsQyxJQUFJLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN6QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsV0FBVyxDQUFDLFNBQXdDO1FBQ2hELElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNkLEtBQUssTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDNUIsSUFBSSxTQUFTLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ2xCLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNuQixLQUFLLEVBQUUsQ0FBQztZQUNaLENBQUM7UUFDTCxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDakIsQ0FBQztDQUNKIiwic291cmNlc0NvbnRlbnQiOlsiLyoqIENvbWJpbmVkIEZJRk8vTFJVIGNhY2hlIHVzZWQgdG8gc3RvcmUgY29tcGlsZWQgZm9ybWF0dGVycy4gKi9cbmV4cG9ydCBjbGFzcyBGSUZPQ2FjaGU8SywgVj4ge1xuICAgIHByaXZhdGUgbWFwID0gbmV3IE1hcDxLLCBWPigpO1xuICAgIGdldCBzaXplKCk6IG51bWJlciB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5zaXplO1xuICAgIH1cbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIG1heDogbnVtYmVyKSB7IH1cbiAgICBzZXQoa2V5OiBLLCB2YWx1ZTogVik6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5tYXAuaGFzKGtleSkpIHtcbiAgICAgICAgICAgIHRoaXMubWFwLmRlbGV0ZShrZXkpO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubWFwLnNldChrZXksIHZhbHVlKTtcbiAgICAgICAgaWYgKHRoaXMubWFwLnNpemUgPiB0aGlzLm1heCkge1xuICAgICAgICAgICAgY29uc3QgZmlyc3QgPSB0aGlzLm1hcC5rZXlzKCkubmV4dCgpLnZhbHVlO1xuICAgICAgICAgICAgaWYgKGZpcnN0KSB7XG4gICAgICAgICAgICAgICAgdGhpcy5tYXAuZGVsZXRlKGZpcnN0KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbiAgICBnZXQoa2V5OiBLKTogViB8IHVuZGVmaW5lZCB7XG4gICAgICAgIGNvbnN0IHZhbCA9IHRoaXMubWFwLmdldChrZXkpO1xuICAgICAgICAvLyBSZWZyZXNoIHJlY2VuY3kgb24gaGl0IHNvIGZyZXF1ZW50bHkgdXNlZCBlbnRyaWVzIHN0YXkgcmVzaWRlbnQuXG4gICAgICAgIGlmICh2YWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgdGhpcy5tYXAuZGVsZXRlKGtleSk7XG4gICAgICAgICAgICB0aGlzLm1hcC5zZXQoa2V5LCB2YWwpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgfVxuICAgIGhhcyhrZXk6IEspOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMubWFwLmhhcyhrZXkpO1xuICAgIH1cbiAgICBkZWxldGUoazogSyk6IHZvaWQge1xuICAgICAgICB0aGlzLm1hcC5kZWxldGUoayk7XG4gICAgfVxuICAgIGNsZWFyKCk6IHZvaWQge1xuICAgICAgICB0aGlzLm1hcC5jbGVhcigpO1xuICAgIH1cblxuICAgIC8qKiBVdGlsaXR5IGhlbHBlciBmb3IgY29udHJvbGxlZCBleHRlcm5hbCBpdGVyYXRpb24vbWFuaXB1bGF0aW9uLiAqL1xuICAgIGtleXMoKTogSXRlcmFibGVJdGVyYXRvcjxLPiB7XG4gICAgICAgIHJldHVybiB0aGlzLm1hcC5rZXlzKCk7XG4gICAgfVxuXG4gICAgLyoqIEl0ZXJhdGVzIGNhY2hlZCB2YWx1ZXMgd2l0aG91dCBleHBvc2luZyB0aGUgYmFja2luZyBNYXAuICovXG4gICAgZm9yRWFjaChjYjogKHZhbHVlOiBWLCBrZXk6IEspID0+IHZvaWQpOiB2b2lkIHtcbiAgICAgICAgdGhpcy5tYXAuZm9yRWFjaCgodiwgaykgPT4gY2IodiwgaykpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlbGV0ZSBhbGwgZW50cmllcyB0aGF0IG1hdGNoIHRoZSBwcmVkaWNhdGUuXG4gICAgICogUmV0dXJucyB0aGUgbnVtYmVyIG9mIGRlbGV0ZWQgZW50cmllcy5cbiAgICAgKi9cbiAgICBkZWxldGVXaGVyZShwcmVkaWNhdGU6IChrZXk6IEssIHZhbHVlOiBWKSA9PiBib29sZWFuKTogbnVtYmVyIHtcbiAgICAgICAgbGV0IGNvdW50ID0gMDtcbiAgICAgICAgZm9yIChjb25zdCBbaywgdl0gb2YgdGhpcy5tYXApIHtcbiAgICAgICAgICAgIGlmIChwcmVkaWNhdGUoaywgdikpIHtcbiAgICAgICAgICAgICAgICB0aGlzLm1hcC5kZWxldGUoayk7XG4gICAgICAgICAgICAgICAgY291bnQrKztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY291bnQ7XG4gICAgfVxufVxuIl19
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { inject, Pipe } from "@angular/core";
|
|
2
|
+
import { TranslationService } from "./translation.service";
|
|
3
|
+
import * as i0 from "@angular/core";
|
|
4
|
+
/** Template helper that proxies lookups to `TranslationService.t`. */
|
|
5
|
+
export class TranslationPipe {
|
|
6
|
+
service = inject(TranslationService);
|
|
7
|
+
/** Formats the translation identified by `key` using the optional params. */
|
|
8
|
+
transform(key, params) {
|
|
9
|
+
return this.service.t(key, params);
|
|
10
|
+
}
|
|
11
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
12
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.2.13", ngImport: i0, type: TranslationPipe, isStandalone: true, name: "t", pure: false });
|
|
13
|
+
}
|
|
14
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TranslationPipe, decorators: [{
|
|
15
|
+
type: Pipe,
|
|
16
|
+
args: [{ name: 't', standalone: true, pure: false }]
|
|
17
|
+
}] });
|
|
18
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnBpcGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtYXRvbWljLWkxOG4vc3JjL2xpYi90cmFuc2xhdGUucGlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBaUIsTUFBTSxlQUFlLENBQUM7QUFFNUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sdUJBQXVCLENBQUM7O0FBRzNELHNFQUFzRTtBQUN0RSxNQUFNLE9BQU8sZUFBZTtJQUNULE9BQU8sR0FBRyxNQUFNLENBQUMsa0JBQWtCLENBQUMsQ0FBQztJQUN0RCw2RUFBNkU7SUFDN0UsU0FBUyxDQUFDLEdBQVcsRUFBRSxNQUFlO1FBQ3BDLE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQ3JDLENBQUM7d0dBTFUsZUFBZTtzR0FBZixlQUFlOzs0RkFBZixlQUFlO2tCQUYzQixJQUFJO21CQUFDLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBpbmplY3QsIFBpcGUsIFBpcGVUcmFuc2Zvcm0gfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuaW1wb3J0IHsgUGFyYW1zIH0gZnJvbSBcIi4vdHJhbnNsYXRlLnR5cGVcIjtcbmltcG9ydCB7IFRyYW5zbGF0aW9uU2VydmljZSB9IGZyb20gXCIuL3RyYW5zbGF0aW9uLnNlcnZpY2VcIjtcblxuQFBpcGUoeyBuYW1lOiAndCcsIHN0YW5kYWxvbmU6IHRydWUsIHB1cmU6IGZhbHNlIH0pXG4vKiogVGVtcGxhdGUgaGVscGVyIHRoYXQgcHJveGllcyBsb29rdXBzIHRvIGBUcmFuc2xhdGlvblNlcnZpY2UudGAuICovXG5leHBvcnQgY2xhc3MgVHJhbnNsYXRpb25QaXBlIGltcGxlbWVudHMgUGlwZVRyYW5zZm9ybSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc2VydmljZSA9IGluamVjdChUcmFuc2xhdGlvblNlcnZpY2UpO1xuICAvKiogRm9ybWF0cyB0aGUgdHJhbnNsYXRpb24gaWRlbnRpZmllZCBieSBga2V5YCB1c2luZyB0aGUgb3B0aW9uYWwgcGFyYW1zLiAqL1xuICB0cmFuc2Zvcm0oa2V5OiBzdHJpbmcsIHBhcmFtcz86IFBhcmFtcyk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMuc2VydmljZS50KGtleSwgcGFyYW1zKTtcbiAgfVxufVxuIl19
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { HttpClient } from "@angular/common/http";
|
|
2
|
+
import { APP_INITIALIZER, inject, isDevMode, PLATFORM_ID, TransferState, makeStateKey, Optional } from "@angular/core";
|
|
3
|
+
import { HttpTranslationLoader } from "./translation.loader.csr";
|
|
4
|
+
import { detectPreferredLang } from "./translate.util";
|
|
5
|
+
import { isPlatformServer } from "@angular/common";
|
|
6
|
+
import { TranslationService } from "./translation.service";
|
|
7
|
+
import { TempToken } from "./translate.type";
|
|
8
|
+
import { BUILD_VERSION, CLIENT_REQUEST_LANG, PAGE_TRANSLATION_ROOT, TRANSLATION_CONFIG, TRANSLATION_LOADER, TRANSLATION_NAMESPACE } from "./translate.token";
|
|
9
|
+
import { FsTranslationLoader } from "./translation.loader.ssr";
|
|
10
|
+
export const defaultConfig = {
|
|
11
|
+
supportedLangs: ['en'],
|
|
12
|
+
fallbackNamespace: 'common',
|
|
13
|
+
fallbackLang: '',
|
|
14
|
+
i18nRoots: ['i18n'],
|
|
15
|
+
pathTemplates: [`${TempToken.Root}/${TempToken.Namespace}/${TempToken.Lang}.json`],
|
|
16
|
+
enablePageFallback: false,
|
|
17
|
+
missingTranslationBehavior: 'show-key',
|
|
18
|
+
langDetectionOrder: ['url', 'clientRequest', 'localStorage', 'browser', 'customLang', 'fallback'],
|
|
19
|
+
clientRequestLang: null,
|
|
20
|
+
};
|
|
21
|
+
const CLIENT_REQUEST_LANG_STATE_KEY = makeStateKey('NGX_I18N_CLIENT_REQUEST_LANG');
|
|
22
|
+
function resolveClientRequestLang(platformId, transferState, providedLang) {
|
|
23
|
+
const stored = transferState?.get(CLIENT_REQUEST_LANG_STATE_KEY, null);
|
|
24
|
+
if (stored)
|
|
25
|
+
return stored;
|
|
26
|
+
const resolved = providedLang ?? null;
|
|
27
|
+
if (resolved && transferState && isPlatformServer(platformId)) {
|
|
28
|
+
transferState.set(CLIENT_REQUEST_LANG_STATE_KEY, resolved);
|
|
29
|
+
}
|
|
30
|
+
return resolved;
|
|
31
|
+
}
|
|
32
|
+
/** Bootstraps the entire translation infrastructure for an application. */
|
|
33
|
+
export function provideTranslationInit(userConfig) {
|
|
34
|
+
const debugEnabled = userConfig?.debug ?? isDevMode();
|
|
35
|
+
const baseConfig = { ...defaultConfig, ...(userConfig ?? {}), fallbackLang: defaultConfig.supportedLangs[0], debug: debugEnabled };
|
|
36
|
+
if (debugEnabled) {
|
|
37
|
+
console.info('[ngx-atomic-i18n] Debug logging is enabled.');
|
|
38
|
+
}
|
|
39
|
+
return [
|
|
40
|
+
{
|
|
41
|
+
provide: TRANSLATION_CONFIG,
|
|
42
|
+
useFactory: (platformId, transferState, clientRequestLang) => {
|
|
43
|
+
const requestLang = resolveClientRequestLang(platformId, transferState, clientRequestLang ?? baseConfig.clientRequestLang ?? null);
|
|
44
|
+
const finalConfig = { ...baseConfig, clientRequestLang: requestLang };
|
|
45
|
+
const preferredLang = detectPreferredLang(finalConfig);
|
|
46
|
+
return { ...finalConfig, customLang: preferredLang };
|
|
47
|
+
},
|
|
48
|
+
deps: [PLATFORM_ID, [new Optional(), TransferState], [new Optional(), CLIENT_REQUEST_LANG]],
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
provide: BUILD_VERSION,
|
|
52
|
+
useValue: userConfig?.buildVersion ?? null,
|
|
53
|
+
},
|
|
54
|
+
...provideTranslationLoader(baseConfig),
|
|
55
|
+
...provideTranslation(baseConfig.fallbackNamespace),
|
|
56
|
+
{
|
|
57
|
+
provide: APP_INITIALIZER,
|
|
58
|
+
useFactory: (ts) => {
|
|
59
|
+
return async () => {
|
|
60
|
+
const preload = baseConfig.preloadNamespaces;
|
|
61
|
+
if (preload?.length) {
|
|
62
|
+
await ts.preloadNamespaces(preload, ts.currentLang);
|
|
63
|
+
}
|
|
64
|
+
ts.setLang(ts.currentLang);
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
deps: [TranslationService],
|
|
68
|
+
multi: true,
|
|
69
|
+
},
|
|
70
|
+
];
|
|
71
|
+
}
|
|
72
|
+
/** Provides the component-scoped namespace injection for component-registered service.
|
|
73
|
+
* @param namespace The namespace owned by the component.
|
|
74
|
+
* @param isPage Whether the component is a top-level page (defaults to false).
|
|
75
|
+
*/
|
|
76
|
+
export function provideTranslation(namespace, isPage = false) {
|
|
77
|
+
return [
|
|
78
|
+
{
|
|
79
|
+
provide: TRANSLATION_NAMESPACE,
|
|
80
|
+
useValue: namespace,
|
|
81
|
+
},
|
|
82
|
+
TranslationService,
|
|
83
|
+
...(isPage ? [{
|
|
84
|
+
provide: PAGE_TRANSLATION_ROOT,
|
|
85
|
+
useValue: true,
|
|
86
|
+
}] : []),
|
|
87
|
+
];
|
|
88
|
+
}
|
|
89
|
+
/** Configures the runtime translation loader for CSR or SSR environments. */
|
|
90
|
+
export function provideTranslationLoader(config) {
|
|
91
|
+
return [
|
|
92
|
+
{
|
|
93
|
+
provide: TRANSLATION_LOADER,
|
|
94
|
+
useFactory: (platformId) => {
|
|
95
|
+
const options = config.loader ?? {};
|
|
96
|
+
const finalPathTemplates = config.pathTemplates ?? defaultConfig.pathTemplates;
|
|
97
|
+
const isSSR = options.forceMode === 'ssr' || (options.forceMode !== 'csr' && isPlatformServer(platformId));
|
|
98
|
+
if (isSSR) {
|
|
99
|
+
const nodeProcess = globalThis.process;
|
|
100
|
+
const baseDir = options.fsOptions?.baseDir ??
|
|
101
|
+
(typeof nodeProcess?.cwd === 'function' ? nodeProcess.cwd() : '');
|
|
102
|
+
const assetPath = options.fsOptions?.assetPath ?? (isDevMode() ? 'src/assets' : 'dist/browser/assets');
|
|
103
|
+
return options.ssrLoader?.()
|
|
104
|
+
?? new FsTranslationLoader({
|
|
105
|
+
baseDir,
|
|
106
|
+
assetPath,
|
|
107
|
+
resolvePaths: options.fsOptions?.resolvePaths,
|
|
108
|
+
fsModule: options.fsOptions?.fsModule
|
|
109
|
+
}, finalPathTemplates);
|
|
110
|
+
}
|
|
111
|
+
const http = inject(HttpClient);
|
|
112
|
+
return options.csrLoader?.(http)
|
|
113
|
+
?? new HttpTranslationLoader(http, {
|
|
114
|
+
baseUrl: options.httpOptions?.baseUrl ?? '/assets',
|
|
115
|
+
}, finalPathTemplates);
|
|
116
|
+
},
|
|
117
|
+
deps: [PLATFORM_ID],
|
|
118
|
+
}
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnByb3ZpZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWF0b21pYy1pMThuL3NyYy9saWIvdHJhbnNsYXRlLnByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNsRCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFZLGFBQWEsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2pJLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2pFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLGtCQUFrQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQ25ELE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQzNELE9BQU8sRUFBRSxTQUFTLEVBQWtFLE1BQU0sa0JBQWtCLENBQUM7QUFDN0csT0FBTyxFQUFFLGFBQWEsRUFBRSxtQkFBbUIsRUFBRSxxQkFBcUIsRUFBRSxrQkFBa0IsRUFBRSxrQkFBa0IsRUFBRSxxQkFBcUIsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzdKLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBUy9ELE1BQU0sQ0FBQyxNQUFNLGFBQWEsR0FBc0I7SUFDOUMsY0FBYyxFQUFFLENBQUMsSUFBSSxDQUFDO0lBQ3RCLGlCQUFpQixFQUFFLFFBQVE7SUFDM0IsWUFBWSxFQUFFLEVBQUU7SUFDaEIsU0FBUyxFQUFFLENBQUMsTUFBTSxDQUFDO0lBQ25CLGFBQWEsRUFBRSxDQUFDLEdBQUcsU0FBUyxDQUFDLElBQUksSUFBSSxTQUFTLENBQUMsU0FBUyxJQUFJLFNBQVMsQ0FBQyxJQUFJLE9B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TyxDQUFDLFNBQVMsRUFBRSxPQUFPO3dCQUMxQixDQUFDLE9BQU8sV0FBVyxFQUFFLEdBQUcsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7b0JBQ3BFLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxTQUFTLEVBQUUsU0FBUyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMscUJBQXFCLENBQUMsQ0FBQztvQkFDdkcsT0FBTyxPQUFPLENBQUMsU0FBUyxFQUFFLEVBQUU7MkJBQ3ZCLElBQUksbUJBQW1CLENBQUM7NEJBQ3pCLE9BQU87NEJBQ1AsU0FBUzs0QkFDVCxZQUFZLEVBQUUsT0FBTyxDQUFDLFNBQVMsRUFBRSxZQUFZOzRCQUM3QyxRQUFRLEVBQUUsT0FBTyxDQUFDLFNBQVMsRUFBRSxRQUFRO3lCQUN0QyxFQUFFLGtCQUFrQixDQUFDLENBQUM7Z0JBQzNCLENBQUM7Z0JBQ0QsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2dCQUNoQyxPQUFPLE9BQU8sQ0FBQyxTQUFTLEVBQUUsQ0FBQyxJQUFJLENBQUM7dUJBQzNCLElBQUkscUJBQXFCLENBQUMsSUFBSSxFQUFFO3dCQUNqQyxPQUFPLEVBQUUsT0FBTyxDQUFDLFdBQVcsRUFBRSxPQUFPLElBQUksU0FBUztxQkFDbkQsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1lBQzNCLENBQUM7WUFDRCxJQUFJLEVBQUUsQ0FBQyxXQUFXLENBQUM7U0FDcEI7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEh0dHBDbGllbnQgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uL2h0dHBcIjtcbmltcG9ydCB7IEFQUF9JTklUSUFMSVpFUiwgaW5qZWN0LCBpc0Rldk1vZGUsIFBMQVRGT1JNX0lELCBQcm92aWRlciwgVHJhbnNmZXJTdGF0ZSwgbWFrZVN0YXRlS2V5LCBPcHRpb25hbCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgeyBIdHRwVHJhbnNsYXRpb25Mb2FkZXIgfSBmcm9tIFwiLi90cmFuc2xhdGlvbi5sb2FkZXIuY3NyXCI7XG5pbXBvcnQgeyBkZXRlY3RQcmVmZXJyZWRMYW5nIH0gZnJvbSBcIi4vdHJhbnNsYXRlLnV0aWxcIjtcbmltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tIFwiQGFuZ3VsYXIvY29tbW9uXCI7XG5pbXBvcnQgeyBUcmFuc2xhdGlvblNlcnZpY2UgfSBmcm9tIFwiLi90cmFuc2xhdGlvbi5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBUZW1wVG9rZW4sIFRyYW5zbGF0aW9uQ29uZmlnLCBUcmFuc2xhdGlvbkxvYWRlciwgVHJhbnNsYXRpb25Mb2FkZXJPcHRpb25zIH0gZnJvbSBcIi4vdHJhbnNsYXRlLnR5cGVcIjtcbmltcG9ydCB7IEJVSUxEX1ZFUlNJT04sIENMSUVOVF9SRVFVRVNUX0xBTkcsIFBBR0VfVFJBTlNMQVRJT05fUk9PVCwgVFJBTlNMQVRJT05fQ09ORklHLCBUUkFOU0xBVElPTl9MT0FERVIsIFRSQU5TTEFUSU9OX05BTUVTUEFDRSB9IGZyb20gXCIuL3RyYW5zbGF0ZS50b2tlblwiO1xuaW1wb3J0IHsgRnNUcmFuc2xhdGlvbkxvYWRlciB9IGZyb20gXCIuL3RyYW5zbGF0aW9uLmxvYWRlci5zc3JcIjtcblxuZXhwb3J0IHR5cGUgUHJvdmlkZVRyYW5zbGF0aW9uSW5pdE9wdGlvbnMgPVxuICBQYXJ0aWFsPFRyYW5zbGF0aW9uQ29uZmlnPiAmIHtcbiAgICBsb2FkZXI/OiBUcmFuc2xhdGlvbkxvYWRlck9wdGlvbnM7XG4gICAgLyoqIE9wdGlvbmFsIGdsb2JhbCBidWlsZCB2ZXJzaW9uIGZvciBTU1IvQ1NSIHRvIGFsaWduIGNhY2hlcyAqL1xuICAgIGJ1aWxkVmVyc2lvbj86IHN0cmluZyB8IG51bGw7XG4gIH07XG5cbmV4cG9ydCBjb25zdCBkZWZhdWx0Q29uZmlnOiBUcmFuc2xhdGlvbkNvbmZpZyA9IHtcbiAgc3VwcG9ydGVkTGFuZ3M6IFsnZW4nXSxcbiAgZmFsbGJhY2tOYW1lc3BhY2U6ICdjb21tb24nLFxuICBmYWxsYmFja0xhbmc6ICcnLFxuICBpMThuUm9vdHM6IFsnaTE4biddLFxuICBwYXRoVGVtcGxhdGVzOiBbYCR7VGVtcFRva2VuLlJvb3R9LyR7VGVtcFRva2VuLk5hbWVzcGFjZX0vJHtUZW1wVG9rZW4uTGFuZ30uanNvbmBdLFxuICBlbmFibGVQYWdlRmFsbGJhY2s6IGZhbHNlLFxuICBtaXNzaW5nVHJhbnNsYXRpb25CZWhhdmlvcjogJ3Nob3cta2V5JyxcbiAgbGFuZ0RldGVjdGlvbk9yZGVyOiBbJ3VybCcsICdjbGllbnRSZXF1ZXN0JywgJ2xvY2FsU3RvcmFnZScsICdicm93c2VyJywgJ2N1c3RvbUxhbmcnLCAnZmFsbGJhY2snXSxcbiAgY2xpZW50UmVxdWVzdExhbmc6IG51bGwsXG59O1xuXG5jb25zdCBDTElFTlRfUkVRVUVTVF9MQU5HX1NUQVRFX0tFWSA9IG1ha2VTdGF0ZUtleTxzdHJpbmcgfCBudWxsPignTkdYX0kxOE5fQ0xJRU5UX1JFUVVFU1RfTEFORycpO1xuXG5mdW5jdGlvbiByZXNvbHZlQ2xpZW50UmVxdWVzdExhbmcoXG4gIHBsYXRmb3JtSWQ6IE9iamVjdCxcbiAgdHJhbnNmZXJTdGF0ZTogVHJhbnNmZXJTdGF0ZSB8IG51bGwgfCB1bmRlZmluZWQsXG4gIHByb3ZpZGVkTGFuZzogc3RyaW5nIHwgbnVsbFxuKTogc3RyaW5nIHwgbnVsbCB7XG4gIGNvbnN0IHN0b3JlZCA9IHRyYW5zZmVyU3RhdGU/LmdldChDTElFTlRfUkVRVUVTVF9MQU5HX1NUQVRFX0tFWSwgbnVsbCk7XG4gIGlmIChzdG9yZWQpIHJldHVybiBzdG9yZWQ7XG5cbiAgY29uc3QgcmVzb2x2ZWQgPSBwcm92aWRlZExhbmcgPz8gbnVsbDtcbiAgaWYgKHJlc29sdmVkICYmIHRyYW5zZmVyU3RhdGUgJiYgaXNQbGF0Zm9ybVNlcnZlcihwbGF0Zm9ybUlkKSkge1xuICAgIHRyYW5zZmVyU3RhdGUuc2V0KENMSUVOVF9SRVFVRVNUX0xBTkdfU1RBVEVfS0VZLCByZXNvbHZlZCk7XG4gIH1cbiAgcmV0dXJuIHJlc29sdmVkO1xufVxuLyoqIEJvb3RzdHJhcHMgdGhlIGVudGlyZSB0cmFuc2xhdGlvbiBpbmZyYXN0cnVjdHVyZSBmb3IgYW4gYXBwbGljYXRpb24uICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZVRyYW5zbGF0aW9uSW5pdCh1c2VyQ29uZmlnPzogUHJvdmlkZVRyYW5zbGF0aW9uSW5pdE9wdGlvbnMpOiBQcm92aWRlcltdIHtcbiAgY29uc3QgZGVidWdFbmFibGVkID0gdXNlckNvbmZpZz8uZGVidWcgPz8gaXNEZXZNb2RlKCk7XG4gIGNvbnN0IGJhc2VDb25maWcgPSB7IC4uLmRlZmF1bHRDb25maWcsIC4uLih1c2VyQ29uZmlnID8/IHt9KSwgZmFsbGJhY2tMYW5nOiBkZWZhdWx0Q29uZmlnLnN1cHBvcnRlZExhbmdzWzBdLCBkZWJ1ZzogZGVidWdFbmFibGVkIH0gYXMgVHJhbnNsYXRpb25Db25maWc7XG4gIGlmIChkZWJ1Z0VuYWJsZWQpIHtcbiAgICBjb25zb2xlLmluZm8oJ1tuZ3gtYXRvbWljLWkxOG5dIERlYnVnIGxvZ2dpbmcgaXMgZW5hYmxlZC4nKTtcbiAgfVxuICByZXR1cm4gW1xuICAgIHtcbiAgICAgIHByb3ZpZGU6IFRSQU5TTEFUSU9OX0NPTkZJRyxcbiAgICAgIHVzZUZhY3Rvcnk6IChwbGF0Zm9ybUlkOiBPYmplY3QsIHRyYW5zZmVyU3RhdGU6IFRyYW5zZmVyU3RhdGUgfCBudWxsIHwgdW5kZWZpbmVkLCBjbGllbnRSZXF1ZXN0TGFuZzogc3RyaW5nIHwgbnVsbCkgPT4ge1xuICAgICAgICBjb25zdCByZXF1ZXN0TGFuZyA9IHJlc29sdmVDbGllbnRSZXF1ZXN0TGFuZyhwbGF0Zm9ybUlkLCB0cmFuc2ZlclN0YXRlLCBjbGllbnRSZXF1ZXN0TGFuZyA/PyBiYXNlQ29uZmlnLmNsaWVudFJlcXVlc3RMYW5nID8/IG51bGwpO1xuICAgICAgICBjb25zdCBmaW5hbENvbmZpZyA9IHsgLi4uYmFzZUNvbmZpZywgY2xpZW50UmVxdWVzdExhbmc6IHJlcXVlc3RMYW5nIH0gYXMgVHJhbnNsYXRpb25Db25maWc7XG4gICAgICAgIGNvbnN0IHByZWZlcnJlZExhbmcgPSBkZXRlY3RQcmVmZXJyZWRMYW5nKGZpbmFsQ29uZmlnKTtcbiAgICAgICAgcmV0dXJuIHsgLi4uZmluYWxDb25maWcsIGN1c3RvbUxhbmc6IHByZWZlcnJlZExhbmcgfTtcbiAgICAgIH0sXG4gICAgICBkZXBzOiBbUExBVEZPUk1fSUQsIFtuZXcgT3B0aW9uYWwoKSwgVHJhbnNmZXJTdGF0ZV0sIFtuZXcgT3B0aW9uYWwoKSwgQ0xJRU5UX1JFUVVFU1RfTEFOR11dLFxuICAgIH0sXG4gICAge1xuICAgICAgcHJvdmlkZTogQlVJTERfVkVSU0lPTixcbiAgICAgIHVzZVZhbHVlOiB1c2VyQ29uZmlnPy5idWlsZFZlcnNpb24gPz8gbnVsbCxcbiAgICB9LFxuICAgIC4uLnByb3ZpZGVUcmFuc2xhdGlvbkxvYWRlcihiYXNlQ29uZmlnKSxcbiAgICAuLi5wcm92aWRlVHJhbnNsYXRpb24oYmFzZUNvbmZpZy5mYWxsYmFja05hbWVzcGFjZSksXG4gICAge1xuICAgICAgcHJvdmlkZTogQVBQX0lOSVRJQUxJWkVSLFxuICAgICAgdXNlRmFjdG9yeTogKHRzOiBUcmFuc2xhdGlvblNlcnZpY2UpID0+IHtcbiAgICAgICAgcmV0dXJuIGFzeW5jICgpID0+IHtcbiAgICAgICAgICBjb25zdCBwcmVsb2FkID0gYmFzZUNvbmZpZy5wcmVsb2FkTmFtZXNwYWNlcztcbiAgICAgICAgICBpZiAocHJlbG9hZD8ubGVuZ3RoKSB7XG4gICAgICAgICAgICBhd2FpdCB0cy5wcmVsb2FkTmFtZXNwYWNlcyhwcmVsb2FkLCB0cy5jdXJyZW50TGFuZyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRzLnNldExhbmcodHMuY3VycmVudExhbmcpO1xuICAgICAgICB9O1xuICAgICAgfSxcbiAgICAgIGRlcHM6IFtUcmFuc2xhdGlvblNlcnZpY2VdLFxuICAgICAgbXVsdGk6IHRydWUsXG4gICAgfSxcbiAgXTtcbn1cblxuXG4vKiogUHJvdmlkZXMgdGhlIGNvbXBvbmVudC1zY29wZWQgbmFtZXNwYWNlIGluamVjdGlvbiBmb3IgY29tcG9uZW50LXJlZ2lzdGVyZWQgc2VydmljZS5cbiAqIEBwYXJhbSBuYW1lc3BhY2UgVGhlIG5hbWVzcGFjZSBvd25lZCBieSB0aGUgY29tcG9uZW50LlxuICogQHBhcmFtIGlzUGFnZSBXaGV0aGVyIHRoZSBjb21wb25lbnQgaXMgYSB0b3AtbGV2ZWwgcGFnZSAoZGVmYXVsdHMgdG8gZmFsc2UpLlxuKi9cbmV4cG9ydCBmdW5jdGlvbiBwcm92aWRlVHJhbnNsYXRpb24obmFtZXNwYWNlOiBzdHJpbmcsIGlzUGFnZTogYm9vbGVhbiA9IGZhbHNlKTogUHJvdmlkZXJbXSB7XG4gIHJldHVybiBbXG4gICAge1xuICAgICAgcHJvdmlkZTogVFJBTlNMQVRJT05fTkFNRVNQQUNFLFxuICAgICAgdXNlVmFsdWU6IG5hbWVzcGFjZSxcbiAgICB9LFxuICAgIFRyYW5zbGF0aW9uU2VydmljZSxcbiAgICAuLi4oaXNQYWdlID8gW3tcbiAgICAgIHByb3ZpZGU6IFBBR0VfVFJBTlNMQVRJT05fUk9PVCxcbiAgICAgIHVzZVZhbHVlOiB0cnVlLFxuICAgIH1dIDogW10pLFxuICBdXG59XG5cbi8qKiBDb25maWd1cmVzIHRoZSBydW50aW1lIHRyYW5zbGF0aW9uIGxvYWRlciBmb3IgQ1NSIG9yIFNTUiBlbnZpcm9ubWVudHMuICovXG5leHBvcnQgZnVuY3Rpb24gcHJvdmlkZVRyYW5zbGF0aW9uTG9hZGVyKGNvbmZpZzogUHJvdmlkZVRyYW5zbGF0aW9uSW5pdE9wdGlvbnMpOiBQcm92aWRlcltdIHtcbiAgcmV0dXJuIFtcbiAgICB7XG4gICAgICBwcm92aWRlOiBUUkFOU0xBVElPTl9MT0FERVIsXG4gICAgICB1c2VGYWN0b3J5OiAocGxhdGZvcm1JZDogT2JqZWN0KTogVHJhbnNsYXRpb25Mb2FkZXIgPT4ge1xuICAgICAgICBjb25zdCBvcHRpb25zID0gY29uZmlnLmxvYWRlciA/PyB7fTtcbiAgICAgICAgY29uc3QgZmluYWxQYXRoVGVtcGxhdGVzID0gY29uZmlnLnBhdGhUZW1wbGF0ZXMgPz8gZGVmYXVsdENvbmZpZy5wYXRoVGVtcGxhdGVzO1xuICAgICAgICBjb25zdCBpc1NTUiA9IG9wdGlvbnMuZm9yY2VNb2RlID09PSAnc3NyJyB8fCAob3B0aW9ucy5mb3JjZU1vZGUgIT09ICdjc3InICYmIGlzUGxhdGZvcm1TZXJ2ZXIocGxhdGZvcm1JZCkpO1xuICAgICAgICBpZiAoaXNTU1IpIHtcbiAgICAgICAgICBjb25zdCBub2RlUHJvY2VzcyA9IChnbG9iYWxUaGlzIGFzIGFueSkucHJvY2VzcyBhcyB7IGN3ZD86ICgpID0+IHN0cmluZyB9IHwgdW5kZWZpbmVkO1xuICAgICAgICAgIGNvbnN0IGJhc2VEaXIgPVxuICAgICAgICAgICAgb3B0aW9ucy5mc09wdGlvbnM/LmJhc2VEaXIgPz9cbiAgICAgICAgICAgICh0eXBlb2Ygbm9kZVByb2Nlc3M/LmN3ZCA9PT0gJ2Z1bmN0aW9uJyA/IG5vZGVQcm9jZXNzLmN3ZCgpIDogJycpO1xuICAgICAgICAgIGNvbnN0IGFzc2V0UGF0aCA9IG9wdGlvbnMuZnNPcHRpb25zPy5hc3NldFBhdGggPz8gKGlzRGV2TW9kZSgpID8gJ3NyYy9hc3NldHMnIDogJ2Rpc3QvYnJvd3Nlci9hc3NldHMnKTtcbiAgICAgICAgICByZXR1cm4gb3B0aW9ucy5zc3JMb2FkZXI/LigpXG4gICAgICAgICAgICA/PyBuZXcgRnNUcmFuc2xhdGlvbkxvYWRlcih7XG4gICAgICAgICAgICAgIGJhc2VEaXIsXG4gICAgICAgICAgICAgIGFzc2V0UGF0aCxcbiAgICAgICAgICAgICAgcmVzb2x2ZVBhdGhzOiBvcHRpb25zLmZzT3B0aW9ucz8ucmVzb2x2ZVBhdGhzLFxuICAgICAgICAgICAgICBmc01vZHVsZTogb3B0aW9ucy5mc09wdGlvbnM/LmZzTW9kdWxlXG4gICAgICAgICAgICB9LCBmaW5hbFBhdGhUZW1wbGF0ZXMpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGh0dHAgPSBpbmplY3QoSHR0cENsaWVudCk7XG4gICAgICAgIHJldHVybiBvcHRpb25zLmNzckxvYWRlcj8uKGh0dHApXG4gICAgICAgICAgPz8gbmV3IEh0dHBUcmFuc2xhdGlvbkxvYWRlcihodHRwLCB7XG4gICAgICAgICAgICBiYXNlVXJsOiBvcHRpb25zLmh0dHBPcHRpb25zPy5iYXNlVXJsID8/ICcvYXNzZXRzJyxcbiAgICAgICAgICB9LCBmaW5hbFBhdGhUZW1wbGF0ZXMpO1xuICAgICAgfSxcbiAgICAgIGRlcHM6IFtQTEFURk9STV9JRF0sXG4gICAgfVxuICBdO1xufVxuIl19
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { InjectionToken } from "@angular/core";
|
|
2
|
+
/** Scoped namespace for translating a component tree (string or array). */
|
|
3
|
+
export const TRANSLATION_NAMESPACE = new InjectionToken('TRANSLATION_NAMESPACE');
|
|
4
|
+
/** Root configuration describing language support and loader behavior. */
|
|
5
|
+
export const TRANSLATION_CONFIG = new InjectionToken('TRANSLATION_CONFIG');
|
|
6
|
+
/** Factory used to retrieve translation JSON for a namespace/language tuple. */
|
|
7
|
+
export const TRANSLATION_LOADER = new InjectionToken('TRANSLATION_LOADER');
|
|
8
|
+
/** Optional build fingerprint appended to namespace cache keys. */
|
|
9
|
+
export const BUILD_VERSION = new InjectionToken('BUILD_VERSION');
|
|
10
|
+
/** Custom ICU formatter constructor injected by the host app when available. */
|
|
11
|
+
export const ICU_FORMATTER_TOKEN = new InjectionToken('ICU_FORMATTER_TOKEN');
|
|
12
|
+
export const PAGE_TRANSLATION_ROOT = new InjectionToken('PAGE_TRANSLATION_ROOT');
|
|
13
|
+
/** Per-request language captured during SSR and replayed on CSR. */
|
|
14
|
+
export const CLIENT_REQUEST_LANG = new InjectionToken('CLIENT_REQUEST_LANG');
|
|
15
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnRva2VuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vcHJvamVjdHMvbmd4LWF0b21pYy1pMThuL3NyYy9saWIvdHJhbnNsYXRlLnRva2VuLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFHL0MsMkVBQTJFO0FBQzNFLE1BQU0sQ0FBQyxNQUFNLHFCQUFxQixHQUFHLElBQUksY0FBYyxDQUFTLHVCQUF1QixDQUFDLENBQUM7QUFDekYsMEVBQTBFO0FBQzFFLE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLElBQUksY0FBYyxDQUFvQixvQkFBb0IsQ0FBQyxDQUFDO0FBQzlGLGdGQUFnRjtBQUNoRixNQUFNLENBQUMsTUFBTSxrQkFBa0IsR0FBRyxJQUFJLGNBQWMsQ0FBb0Isb0JBQW9CLENBQUMsQ0FBQztBQUM5RixtRUFBbUU7QUFDbkUsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUFHLElBQUksY0FBYyxDQUFnQixlQUFlLENBQUMsQ0FBQztBQUNoRixnRkFBZ0Y7QUFDaEYsTUFBTSxDQUFDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxjQUFjLENBQU0scUJBQXFCLENBQUMsQ0FBQztBQUVsRixNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLGNBQWMsQ0FBVSx1QkFBdUIsQ0FBQyxDQUFDO0FBQzFGLG9FQUFvRTtBQUNwRSxNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLGNBQWMsQ0FBZ0IscUJBQXFCLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEluamVjdGlvblRva2VuIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7IFRyYW5zbGF0aW9uQ29uZmlnLCBUcmFuc2xhdGlvbkxvYWRlciB9IGZyb20gXCIuL3RyYW5zbGF0ZS50eXBlXCI7XG5cbi8qKiBTY29wZWQgbmFtZXNwYWNlIGZvciB0cmFuc2xhdGluZyBhIGNvbXBvbmVudCB0cmVlIChzdHJpbmcgb3IgYXJyYXkpLiAqL1xuZXhwb3J0IGNvbnN0IFRSQU5TTEFUSU9OX05BTUVTUEFDRSA9IG5ldyBJbmplY3Rpb25Ub2tlbjxzdHJpbmc+KCdUUkFOU0xBVElPTl9OQU1FU1BBQ0UnKTtcbi8qKiBSb290IGNvbmZpZ3VyYXRpb24gZGVzY3JpYmluZyBsYW5ndWFnZSBzdXBwb3J0IGFuZCBsb2FkZXIgYmVoYXZpb3IuICovXG5leHBvcnQgY29uc3QgVFJBTlNMQVRJT05fQ09ORklHID0gbmV3IEluamVjdGlvblRva2VuPFRyYW5zbGF0aW9uQ29uZmlnPignVFJBTlNMQVRJT05fQ09ORklHJyk7XG4vKiogRmFjdG9yeSB1c2VkIHRvIHJldHJpZXZlIHRyYW5zbGF0aW9uIEpTT04gZm9yIGEgbmFtZXNwYWNlL2xhbmd1YWdlIHR1cGxlLiAqL1xuZXhwb3J0IGNvbnN0IFRSQU5TTEFUSU9OX0xPQURFUiA9IG5ldyBJbmplY3Rpb25Ub2tlbjxUcmFuc2xhdGlvbkxvYWRlcj4oJ1RSQU5TTEFUSU9OX0xPQURFUicpO1xuLyoqIE9wdGlvbmFsIGJ1aWxkIGZpbmdlcnByaW50IGFwcGVuZGVkIHRvIG5hbWVzcGFjZSBjYWNoZSBrZXlzLiAqL1xuZXhwb3J0IGNvbnN0IEJVSUxEX1ZFUlNJT04gPSBuZXcgSW5qZWN0aW9uVG9rZW48c3RyaW5nIHwgbnVsbD4oJ0JVSUxEX1ZFUlNJT04nKTtcbi8qKiBDdXN0b20gSUNVIGZvcm1hdHRlciBjb25zdHJ1Y3RvciBpbmplY3RlZCBieSB0aGUgaG9zdCBhcHAgd2hlbiBhdmFpbGFibGUuICovXG5leHBvcnQgY29uc3QgSUNVX0ZPUk1BVFRFUl9UT0tFTiA9IG5ldyBJbmplY3Rpb25Ub2tlbjxhbnk+KCdJQ1VfRk9STUFUVEVSX1RPS0VOJyk7XG5cbmV4cG9ydCBjb25zdCBQQUdFX1RSQU5TTEFUSU9OX1JPT1QgPSBuZXcgSW5qZWN0aW9uVG9rZW48Ym9vbGVhbj4oJ1BBR0VfVFJBTlNMQVRJT05fUk9PVCcpO1xuLyoqIFBlci1yZXF1ZXN0IGxhbmd1YWdlIGNhcHR1cmVkIGR1cmluZyBTU1IgYW5kIHJlcGxheWVkIG9uIENTUi4gKi9cbmV4cG9ydCBjb25zdCBDTElFTlRfUkVRVUVTVF9MQU5HID0gbmV3IEluamVjdGlvblRva2VuPHN0cmluZyB8IG51bGw+KCdDTElFTlRfUkVRVUVTVF9MQU5HJyk7XG4iXX0=
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export var TempToken;
|
|
2
|
+
(function (TempToken) {
|
|
3
|
+
/** Placeholder for the language code inside loader path templates. */
|
|
4
|
+
TempToken["Lang"] = "{{lang}}";
|
|
5
|
+
/** Placeholder for the namespace inside loader path templates. */
|
|
6
|
+
TempToken["Namespace"] = "{{namespace}}";
|
|
7
|
+
/** Placeholder for the root folder inside loader path templates. */
|
|
8
|
+
TempToken["Root"] = "{{root}}";
|
|
9
|
+
})(TempToken || (TempToken = {}));
|
|
10
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJhbnNsYXRlLnR5cGUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtYXRvbWljLWkxOG4vc3JjL2xpYi90cmFuc2xhdGUudHlwZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUF1R0EsTUFBTSxDQUFOLElBQVksU0FPWDtBQVBELFdBQVksU0FBUztJQUNuQixzRUFBc0U7SUFDdEUsOEJBQWlCLENBQUE7SUFDakIsa0VBQWtFO0lBQ2xFLHdDQUEyQixDQUFBO0lBQzNCLG9FQUFvRTtJQUNwRSw4QkFBaUIsQ0FBQTtBQUNuQixDQUFDLEVBUFcsU0FBUyxLQUFULFNBQVMsUUFPcEIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBIdHRwQ2xpZW50IH0gZnJvbSBcIkBhbmd1bGFyL2NvbW1vbi9odHRwXCI7XG5pbXBvcnQgeyBTaWduYWwgfSBmcm9tIFwiQGFuZ3VsYXIvY29yZVwiO1xuXG4vKiogR2xvYmFsIGNvbmZpZ3VyYXRpb24gY29udHJhY3QgdXNlZCBieSB0aGUgdHJhbnNsYXRpb24gc3lzdGVtLiAqL1xuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xhdGlvbkNvbmZpZyB7XG4gIHN1cHBvcnRlZExhbmdzOiBzdHJpbmdbXTtcbiAgZmFsbGJhY2tMYW5nOiBzdHJpbmc7XG4gIGkxOG5Sb290czogc3RyaW5nW107XG4gIHBhdGhUZW1wbGF0ZXM6IHN0cmluZ1tdIHwgc3RyaW5nO1xuICBmYWxsYmFja05hbWVzcGFjZTogc3RyaW5nO1xuICBsYW5nRGV0ZWN0aW9uT3JkZXI6ICgnbG9jYWxTdG9yYWdlJyB8ICd1cmwnIHwgJ2Jyb3dzZXInIHwgJ2N1c3RvbUxhbmcnIHwgJ2ZhbGxiYWNrJyB8ICdjbGllbnRSZXF1ZXN0JylbXTtcbiAgLyoqIEVuYWJsZSB2ZXJib3NlIGxvZ2dpbmcuIERlZmF1bHRzIHRvIHRydWUgaW4gZGV2IG1vZGUuICovXG4gIGRlYnVnPzogYm9vbGVhbjtcbiAgLyoqIEVuYWJsZSB1c2UgICovXG4gIGVuYWJsZVBhZ2VGYWxsYmFjazogYm9vbGVhbjtcbiAgcHJlbG9hZE5hbWVzcGFjZXM/OiBzdHJpbmdbXTtcbiAgY3VzdG9tTGFuZz86ICgoKSA9PiBzdHJpbmcpIHwgc3RyaW5nO1xuICAvKiogTGFuZ3VhZ2UgcGFzc2VkIGZyb20gU1NSIHJlcXVlc3QgYW5kIHJldXNlZCBvbiB0aGUgY2xpZW50LiAqL1xuICBjbGllbnRSZXF1ZXN0TGFuZz86IHN0cmluZyB8IG51bGw7XG4gIG1pc3NpbmdUcmFuc2xhdGlvbkJlaGF2aW9yPzogTWlzc2luZ1RyYW5zbGF0aW9uQmVoYXZpb3I7XG59XG5cbi8qKiBNZXRhZGF0YSBwYXNzZWQgaW50byBjb25zdW1lcnMgdG8gaW5kaWNhdGUgbmFtZXNwYWNlIHJlYWRpbmVzcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVHJhbnNsYXRpb25Db250ZXh0IHtcbiAgbmFtZXNwYWNlOiBzdHJpbmc7XG4gIHJlYWR5PzogU2lnbmFsPGJvb2xlYW4+O1xufVxuXG5leHBvcnQgdHlwZSBMYXp5TG9hZGVyID0gUmVjb3JkPExhbmcsICgpID0+IFByb21pc2U8VHJhbnNsYXRpb25zPj47XG5leHBvcnQgdHlwZSBQYXJhbXMgPSBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xuZXhwb3J0IHR5cGUgVHJhbnNsYXRpb25zID0gUmVjb3JkPHN0cmluZywgc3RyaW5nPjtcbmV4cG9ydCB0eXBlIExhbmcgPSBzdHJpbmc7XG4vKiogbGFuZzpuYW1lc3BhY2U6dmVyc2lvbiAqL1xuZXhwb3J0IHR5cGUgbnNLZXkgPSBzdHJpbmc7XG4vKipcbiAqIEhvdyB0aGUgdHJhbnNsYXRpb24gc3lzdGVtIHNob3VsZCBiZWhhdmUgd2hlbiBhIHRyYW5zbGF0aW9uIGtleSBpcyBtaXNzaW5nLlxuICpcbiAqIC0gJ3Nob3cta2V5JzogRGlzcGxheSB0aGUga2V5IGl0c2VsZiAoZS5nLiwgYCdtZW51LmFib3V0J2ApIGFzIGEgZmFsbGJhY2suXG4gKiAtICdlbXB0eSc6IFNob3cgYW4gZW1wdHkgc3RyaW5nLiBVc2UgdGhpcyBpZiB5b3UgcHJlZmVyIHVudHJhbnNsYXRlZCB0ZXh0IHRvIGRpc2FwcGVhciBzaWxlbnRseS5cbiAqIC0gJ3Rocm93JzogVGhyb3cgYSBydW50aW1lIGVycm9yLiBSZWNvbW1lbmRlZCBvbmx5IGR1cmluZyBkZXZlbG9wbWVudCBvciB0ZXN0aW5nOyB3aWxsIGJyZWFrIHRoZSBVSSBpZiBub3QgaGFuZGxlZC5cbiAqIC0gc3RyaW5nOiBBbnkgY3VzdG9tIHN0cmluZywgZS5nLiwgJy0tJywgJ2xvYWRpbmcuLi4nLCBldGMuXG4gKi9cbmV4cG9ydCB0eXBlIE1pc3NpbmdUcmFuc2xhdGlvbkJlaGF2aW9yID0gJ3Nob3cta2V5JyB8ICdlbXB0eScgfCAndGhyb3ctZXJyb3InO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYW5zbGF0aW9uTG9hZGVyIHtcbiAgLyoqXG4gICAqIEBwYXJhbSBpMThuUm9vdCAgTGlzdCBvZiBiYXNlIGZvbGRlcnMgdG8gbG9vayBmb3IgSlNPTiAob3JkZXJlZCBieSBwcmlvcml0eSlcbiAgICogQHBhcmFtIG5zICAgICAgICBOYW1lc3BhY2UsIGUuZy4gXCJob21lXCIgb3IgXCJhdXRoLWxvZ2luXCJcbiAgICogQHBhcmFtIGxhbmcgICAgICBMYW5ndWFnZSBjb2RlLCBlLmcuIFwiZW5cIiBvciBcInpoLUhhbnRcIlxuICAgKi9cbiAgbG9hZChpMThuUm9vdHM6IHN0cmluZ1tdLCBuYW1lc3BhY2U6IHN0cmluZywgbGFuZzogc3RyaW5nKTogUHJvbWlzZTxUcmFuc2xhdGlvbnM+O1xufVxuXG5leHBvcnQgdHlwZSBGb3JtYXRSZXN1bHQgPSB7IGZvcm1hdChwYXJhbXM6IFJlY29yZDxzdHJpbmcsIGFueT4pOiBzdHJpbmcgfVxuXG5leHBvcnQgdHlwZSBEZWVwUGFydGlhbDxUPiA9IHtcbiAgW0sgaW4ga2V5b2YgVF0/OiBUW0tdIGV4dGVuZHMgb2JqZWN0ID8gRGVlcFBhcnRpYWw8VFtLXT4gOiBUW0tdO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBGc01vZHVsZUxpa2Uge1xuICAvKiogTWluaW1hbCBzdWJzZXQgb2YgTm9kZSdzIGZzIEFQSSBuZWVkZWQgYnkgdGhlIFNTUiBsb2FkZXIuICovXG4gIHJlYWRGaWxlU3luYyhwYXRoOiBzdHJpbmcsIGVuY29kaW5nOiAndXRmOCcpOiBzdHJpbmc7XG4gIHN0YXRTeW5jKHBhdGg6IHN0cmluZyk6IGFueVxufVxuXG4vKiogT3B0aW9ucyB1c2VkIHRvIGN1c3RvbWlzZSB0aGUgU1NSIGZpbGUtc3lzdGVtIGxvYWRlci4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRnNMb2FkZXJPcHRpb25zIHtcbiAgLyoqICBvbmx5IGZvciBTU1IgLCBlLmcuIHByb2Nlc3MuY3dkKCkgKi9cbiAgYmFzZURpcj86IHN0cmluZztcbiAgLyoqIGUuZy4gJ3Byb2plY3RzL2FwcC9zcmMvYXNzZXRzJyAoZGV2KSBvciAnZGlzdC9hcHAvYnJvd3Nlci9hc3NldHMnICovXG4gIGFzc2V0UGF0aD86IHN0cmluZztcbiAgLyoqIEN1c3RvbSByZXNvbHZlciB0aGF0IHJldHVybnMgYW4gb3JkZXJlZCBsaXN0IG9mIGNhbmRpZGF0ZSBhYnNvbHV0ZSBwYXRocy4gKi9cbiAgcmVzb2x2ZVBhdGhzPzogKGN0eDoge1xuICAgIGJhc2VEaXI6IHN0cmluZztcbiAgICBhc3NldFBhdGg6IHN0cmluZztcbiAgICByb290OiBzdHJpbmc7XG4gICAgbGFuZzogc3RyaW5nO1xuICAgIG5hbWVzcGFjZTogc3RyaW5nO1xuICB9KSA9PiBzdHJpbmdbXTtcbiAgLyoqIEN1c3RvbSBmcyBtb2R1bGUgaW5zdGFuY2UgKHRha2VzIHByZWNlZGVuY2Ugb3ZlciBkeW5hbWljIGltcG9ydHMpLiAqL1xuICBmc01vZHVsZT86IEZzTW9kdWxlTGlrZTtcbiAgY2FjaGVNYXg/OiBudW1iZXI7XG59XG5cbi8qKiBPcHRpb25zIHVzZWQgdG8gY3VzdG9taXNlIHRoZSBIVFRQIGxvYWRlciBpbiBDU1IgZW52aXJvbm1lbnRzLiAqL1xuZXhwb3J0IGludGVyZmFjZSBIdHRwTG9hZGVyT3B0aW9ucyB7XG4gIC8qKiBkZWZhdWx0ICcvYXNzZXRzJyAqL1xuICBiYXNlVXJsPzogc3RyaW5nO1xufVxuXG4vKiogQWdncmVnYXRlIG9wdGlvbnMgZXhwb3NlZCB2aWEgYHByb3ZpZGVUcmFuc2xhdGlvbkluaXRgLiAqL1xuZXhwb3J0IGludGVyZmFjZSBUcmFuc2xhdGlvbkxvYWRlck9wdGlvbnMge1xuICBmb3JjZU1vZGU/OiAnc3NyJyB8ICdjc3InO1xuICBzc3JMb2FkZXI/OiAoKSA9PiBUcmFuc2xhdGlvbkxvYWRlcjsgICAgICAgICAgICAgICAgICAgIC8vIGN1c3RvbSBTU1IgbG9hZGVyXG4gIGNzckxvYWRlcj86IChodHRwOiBIdHRwQ2xpZW50KSA9PiBUcmFuc2xhdGlvbkxvYWRlcjsgICAgLy8gY3VzdG9tIENTUiBsb2FkZXJcbiAgZnNPcHRpb25zPzogRnNMb2FkZXJPcHRpb25zOyAgICAgICAgICAvL29wdGlvbnMgZm9yIEZzVHJhbnNsYXRpb25Mb2FkZXJcbiAgaHR0cE9wdGlvbnM/OiBIdHRwTG9hZGVyT3B0aW9uczsgICAgICAgICAvLyBvcHRpb25zIGZvciBIdHRwVHJhbnNsYXRpb25Mb2FkZXJcbn1cblxuZXhwb3J0IHR5cGUgQ2FjaGVFbnRyeSA9IHsgbXRpbWVNczogbnVtYmVyLCBkYXRhOiBUcmFuc2xhdGlvbnMgfTtcblxuZXhwb3J0IHR5cGUgUGF0aFRlbXBsYXRlID0gc3RyaW5nIHwgc3RyaW5nW10gfCB1bmRlZmluZWQ7XG5cbmV4cG9ydCBlbnVtIFRlbXBUb2tlbiB7XG4gIC8qKiBQbGFjZWhvbGRlciBmb3IgdGhlIGxhbmd1YWdlIGNvZGUgaW5zaWRlIGxvYWRlciBwYXRoIHRlbXBsYXRlcy4gKi9cbiAgTGFuZyA9ICd7e2xhbmd9fScsXG4gIC8qKiBQbGFjZWhvbGRlciBmb3IgdGhlIG5hbWVzcGFjZSBpbnNpZGUgbG9hZGVyIHBhdGggdGVtcGxhdGVzLiAqL1xuICBOYW1lc3BhY2UgPSAne3tuYW1lc3BhY2V9fScsXG4gIC8qKiBQbGFjZWhvbGRlciBmb3IgdGhlIHJvb3QgZm9sZGVyIGluc2lkZSBsb2FkZXIgcGF0aCB0ZW1wbGF0ZXMuICovXG4gIFJvb3QgPSAne3tyb290fX0nXG59XG4iXX0=
|
|
@@ -0,0 +1,245 @@
|
|
|
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=
|