1 | /**
|
---|
2 | * @license
|
---|
3 | * Copyright Google LLC All Rights Reserved.
|
---|
4 | *
|
---|
5 | * Use of this source code is governed by an MIT-style license that can be
|
---|
6 | * found in the LICENSE file at https://angular.io/license
|
---|
7 | */
|
---|
8 | import { assembleBoundTextPlaceholders, getSeqNumberGenerator, updatePlaceholderMap, wrapI18nPlaceholder } from './util';
|
---|
9 | var TagType;
|
---|
10 | (function (TagType) {
|
---|
11 | TagType[TagType["ELEMENT"] = 0] = "ELEMENT";
|
---|
12 | TagType[TagType["TEMPLATE"] = 1] = "TEMPLATE";
|
---|
13 | })(TagType || (TagType = {}));
|
---|
14 | /**
|
---|
15 | * Generates an object that is used as a shared state between parent and all child contexts.
|
---|
16 | */
|
---|
17 | function setupRegistry() {
|
---|
18 | return { getUniqueId: getSeqNumberGenerator(), icus: new Map() };
|
---|
19 | }
|
---|
20 | /**
|
---|
21 | * I18nContext is a helper class which keeps track of all i18n-related aspects
|
---|
22 | * (accumulates placeholders, bindings, etc) between i18nStart and i18nEnd instructions.
|
---|
23 | *
|
---|
24 | * When we enter a nested template, the top-level context is being passed down
|
---|
25 | * to the nested component, which uses this context to generate a child instance
|
---|
26 | * of I18nContext class (to handle nested template) and at the end, reconciles it back
|
---|
27 | * with the parent context.
|
---|
28 | *
|
---|
29 | * @param index Instruction index of i18nStart, which initiates this context
|
---|
30 | * @param ref Reference to a translation const that represents the content if thus context
|
---|
31 | * @param level Nestng level defined for child contexts
|
---|
32 | * @param templateIndex Instruction index of a template which this context belongs to
|
---|
33 | * @param meta Meta information (id, meaning, description, etc) associated with this context
|
---|
34 | */
|
---|
35 | export class I18nContext {
|
---|
36 | constructor(index, ref, level = 0, templateIndex = null, meta, registry) {
|
---|
37 | this.index = index;
|
---|
38 | this.ref = ref;
|
---|
39 | this.level = level;
|
---|
40 | this.templateIndex = templateIndex;
|
---|
41 | this.meta = meta;
|
---|
42 | this.registry = registry;
|
---|
43 | this.bindings = new Set();
|
---|
44 | this.placeholders = new Map();
|
---|
45 | this.isEmitted = false;
|
---|
46 | this._unresolvedCtxCount = 0;
|
---|
47 | this._registry = registry || setupRegistry();
|
---|
48 | this.id = this._registry.getUniqueId();
|
---|
49 | }
|
---|
50 | appendTag(type, node, index, closed) {
|
---|
51 | if (node.isVoid && closed) {
|
---|
52 | return; // ignore "close" for void tags
|
---|
53 | }
|
---|
54 | const ph = node.isVoid || !closed ? node.startName : node.closeName;
|
---|
55 | const content = { type, index, ctx: this.id, isVoid: node.isVoid, closed };
|
---|
56 | updatePlaceholderMap(this.placeholders, ph, content);
|
---|
57 | }
|
---|
58 | get icus() {
|
---|
59 | return this._registry.icus;
|
---|
60 | }
|
---|
61 | get isRoot() {
|
---|
62 | return this.level === 0;
|
---|
63 | }
|
---|
64 | get isResolved() {
|
---|
65 | return this._unresolvedCtxCount === 0;
|
---|
66 | }
|
---|
67 | getSerializedPlaceholders() {
|
---|
68 | const result = new Map();
|
---|
69 | this.placeholders.forEach((values, key) => result.set(key, values.map(serializePlaceholderValue)));
|
---|
70 | return result;
|
---|
71 | }
|
---|
72 | // public API to accumulate i18n-related content
|
---|
73 | appendBinding(binding) {
|
---|
74 | this.bindings.add(binding);
|
---|
75 | }
|
---|
76 | appendIcu(name, ref) {
|
---|
77 | updatePlaceholderMap(this._registry.icus, name, ref);
|
---|
78 | }
|
---|
79 | appendBoundText(node) {
|
---|
80 | const phs = assembleBoundTextPlaceholders(node, this.bindings.size, this.id);
|
---|
81 | phs.forEach((values, key) => updatePlaceholderMap(this.placeholders, key, ...values));
|
---|
82 | }
|
---|
83 | appendTemplate(node, index) {
|
---|
84 | // add open and close tags at the same time,
|
---|
85 | // since we process nested templates separately
|
---|
86 | this.appendTag(TagType.TEMPLATE, node, index, false);
|
---|
87 | this.appendTag(TagType.TEMPLATE, node, index, true);
|
---|
88 | this._unresolvedCtxCount++;
|
---|
89 | }
|
---|
90 | appendElement(node, index, closed) {
|
---|
91 | this.appendTag(TagType.ELEMENT, node, index, closed);
|
---|
92 | }
|
---|
93 | appendProjection(node, index) {
|
---|
94 | // Add open and close tags at the same time, since `<ng-content>` has no content,
|
---|
95 | // so when we come across `<ng-content>` we can register both open and close tags.
|
---|
96 | // Note: runtime i18n logic doesn't distinguish `<ng-content>` tag placeholders and
|
---|
97 | // regular element tag placeholders, so we generate element placeholders for both types.
|
---|
98 | this.appendTag(TagType.ELEMENT, node, index, false);
|
---|
99 | this.appendTag(TagType.ELEMENT, node, index, true);
|
---|
100 | }
|
---|
101 | /**
|
---|
102 | * Generates an instance of a child context based on the root one,
|
---|
103 | * when we enter a nested template within I18n section.
|
---|
104 | *
|
---|
105 | * @param index Instruction index of corresponding i18nStart, which initiates this context
|
---|
106 | * @param templateIndex Instruction index of a template which this context belongs to
|
---|
107 | * @param meta Meta information (id, meaning, description, etc) associated with this context
|
---|
108 | *
|
---|
109 | * @returns I18nContext instance
|
---|
110 | */
|
---|
111 | forkChildContext(index, templateIndex, meta) {
|
---|
112 | return new I18nContext(index, this.ref, this.level + 1, templateIndex, meta, this._registry);
|
---|
113 | }
|
---|
114 | /**
|
---|
115 | * Reconciles child context into parent one once the end of the i18n block is reached (i18nEnd).
|
---|
116 | *
|
---|
117 | * @param context Child I18nContext instance to be reconciled with parent context.
|
---|
118 | */
|
---|
119 | reconcileChildContext(context) {
|
---|
120 | // set the right context id for open and close
|
---|
121 | // template tags, so we can use it as sub-block ids
|
---|
122 | ['start', 'close'].forEach((op) => {
|
---|
123 | const key = context.meta[`${op}Name`];
|
---|
124 | const phs = this.placeholders.get(key) || [];
|
---|
125 | const tag = phs.find(findTemplateFn(this.id, context.templateIndex));
|
---|
126 | if (tag) {
|
---|
127 | tag.ctx = context.id;
|
---|
128 | }
|
---|
129 | });
|
---|
130 | // reconcile placeholders
|
---|
131 | const childPhs = context.placeholders;
|
---|
132 | childPhs.forEach((values, key) => {
|
---|
133 | const phs = this.placeholders.get(key);
|
---|
134 | if (!phs) {
|
---|
135 | this.placeholders.set(key, values);
|
---|
136 | return;
|
---|
137 | }
|
---|
138 | // try to find matching template...
|
---|
139 | const tmplIdx = phs.findIndex(findTemplateFn(context.id, context.templateIndex));
|
---|
140 | if (tmplIdx >= 0) {
|
---|
141 | // ... if found - replace it with nested template content
|
---|
142 | const isCloseTag = key.startsWith('CLOSE');
|
---|
143 | const isTemplateTag = key.endsWith('NG-TEMPLATE');
|
---|
144 | if (isTemplateTag) {
|
---|
145 | // current template's content is placed before or after
|
---|
146 | // parent template tag, depending on the open/close atrribute
|
---|
147 | phs.splice(tmplIdx + (isCloseTag ? 0 : 1), 0, ...values);
|
---|
148 | }
|
---|
149 | else {
|
---|
150 | const idx = isCloseTag ? values.length - 1 : 0;
|
---|
151 | values[idx].tmpl = phs[tmplIdx];
|
---|
152 | phs.splice(tmplIdx, 1, ...values);
|
---|
153 | }
|
---|
154 | }
|
---|
155 | else {
|
---|
156 | // ... otherwise just append content to placeholder value
|
---|
157 | phs.push(...values);
|
---|
158 | }
|
---|
159 | this.placeholders.set(key, phs);
|
---|
160 | });
|
---|
161 | this._unresolvedCtxCount--;
|
---|
162 | }
|
---|
163 | }
|
---|
164 | //
|
---|
165 | // Helper methods
|
---|
166 | //
|
---|
167 | function wrap(symbol, index, contextId, closed) {
|
---|
168 | const state = closed ? '/' : '';
|
---|
169 | return wrapI18nPlaceholder(`${state}${symbol}${index}`, contextId);
|
---|
170 | }
|
---|
171 | function wrapTag(symbol, { index, ctx, isVoid }, closed) {
|
---|
172 | return isVoid ? wrap(symbol, index, ctx) + wrap(symbol, index, ctx, true) :
|
---|
173 | wrap(symbol, index, ctx, closed);
|
---|
174 | }
|
---|
175 | function findTemplateFn(ctx, templateIndex) {
|
---|
176 | return (token) => typeof token === 'object' && token.type === TagType.TEMPLATE &&
|
---|
177 | token.index === templateIndex && token.ctx === ctx;
|
---|
178 | }
|
---|
179 | function serializePlaceholderValue(value) {
|
---|
180 | const element = (data, closed) => wrapTag('#', data, closed);
|
---|
181 | const template = (data, closed) => wrapTag('*', data, closed);
|
---|
182 | const projection = (data, closed) => wrapTag('!', data, closed);
|
---|
183 | switch (value.type) {
|
---|
184 | case TagType.ELEMENT:
|
---|
185 | // close element tag
|
---|
186 | if (value.closed) {
|
---|
187 | return element(value, true) + (value.tmpl ? template(value.tmpl, true) : '');
|
---|
188 | }
|
---|
189 | // open element tag that also initiates a template
|
---|
190 | if (value.tmpl) {
|
---|
191 | return template(value.tmpl) + element(value) +
|
---|
192 | (value.isVoid ? template(value.tmpl, true) : '');
|
---|
193 | }
|
---|
194 | return element(value);
|
---|
195 | case TagType.TEMPLATE:
|
---|
196 | return template(value, value.closed);
|
---|
197 | default:
|
---|
198 | return value;
|
---|
199 | }
|
---|
200 | }
|
---|
201 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29udGV4dC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbXBpbGVyL3NyYy9yZW5kZXIzL3ZpZXcvaTE4bi9jb250ZXh0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQU1ILE9BQU8sRUFBQyw2QkFBNkIsRUFBRSxxQkFBcUIsRUFBRSxvQkFBb0IsRUFBRSxtQkFBbUIsRUFBQyxNQUFNLFFBQVEsQ0FBQztBQUV2SCxJQUFLLE9BR0o7QUFIRCxXQUFLLE9BQU87SUFDViwyQ0FBTyxDQUFBO0lBQ1AsNkNBQVEsQ0FBQTtBQUNWLENBQUMsRUFISSxPQUFPLEtBQVAsT0FBTyxRQUdYO0FBRUQ7O0dBRUc7QUFDSCxTQUFTLGFBQWE7SUFDcEIsT0FBTyxFQUFDLFdBQVcsRUFBRSxxQkFBcUIsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEdBQUcsRUFBaUIsRUFBQyxDQUFDO0FBQ2hGLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sT0FBTyxXQUFXO0lBU3RCLFlBQ2EsS0FBYSxFQUFXLEdBQWtCLEVBQVcsUUFBZ0IsQ0FBQyxFQUN0RSxnQkFBNkIsSUFBSSxFQUFXLElBQW1CLEVBQ2hFLFFBQWM7UUFGYixVQUFLLEdBQUwsS0FBSyxDQUFRO1FBQVcsUUFBRyxHQUFILEdBQUcsQ0FBZTtRQUFXLFVBQUssR0FBTCxLQUFLLENBQVk7UUFDdEUsa0JBQWEsR0FBYixhQUFhLENBQW9CO1FBQVcsU0FBSSxHQUFKLElBQUksQ0FBZTtRQUNoRSxhQUFRLEdBQVIsUUFBUSxDQUFNO1FBVm5CLGFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBTyxDQUFDO1FBQzFCLGlCQUFZLEdBQUcsSUFBSSxHQUFHLEVBQWlCLENBQUM7UUFDeEMsY0FBUyxHQUFZLEtBQUssQ0FBQztRQUcxQix3QkFBbUIsR0FBVyxDQUFDLENBQUM7UUFNdEMsSUFBSSxDQUFDLFNBQVMs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S0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO2FBQ3REO1lBQ0QsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFeEIsS0FBSyxPQUFPLENBQUMsUUFBUTtZQUNuQixPQUFPLFFBQVEsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRXZDO1lBQ0UsT0FBTyxLQUFLLENBQUM7S0FDaEI7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7QVNUfSBmcm9tICcuLi8uLi8uLi9leHByZXNzaW9uX3BhcnNlci9hc3QnO1xuaW1wb3J0ICogYXMgaTE4biBmcm9tICcuLi8uLi8uLi9pMThuL2kxOG5fYXN0JztcbmltcG9ydCAqIGFzIG8gZnJvbSAnLi4vLi4vLi4vb3V0cHV0L291dHB1dF9hc3QnO1xuXG5pbXBvcnQge2Fzc2VtYmxlQm91bmRUZXh0UGxhY2Vob2xkZXJzLCBnZXRTZXFOdW1iZXJHZW5lcmF0b3IsIHVwZGF0ZVBsYWNlaG9sZGVyTWFwLCB3cmFwSTE4blBsYWNlaG9sZGVyfSBmcm9tICcuL3V0aWwnO1xuXG5lbnVtIFRhZ1R5cGUge1xuICBFTEVNRU5ULFxuICBURU1QTEFURSxcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYW4gb2JqZWN0IHRoYXQgaXMgdXNlZCBhcyBhIHNoYXJlZCBzdGF0ZSBiZXR3ZWVuIHBhcmVudCBhbmQgYWxsIGNoaWxkIGNvbnRleHRzLlxuICovXG5mdW5jdGlvbiBzZXR1cFJlZ2lzdHJ5KCkge1xuICByZXR1cm4ge2dldFVuaXF1ZUlkOiBnZXRTZXFOdW1iZXJHZW5lcmF0b3IoKSwgaWN1czogbmV3IE1hcDxzdHJpbmcsIGFueVtdPigpfTtcbn1cblxuLyoqXG4gKiBJMThuQ29udGV4dCBpcyBhIGhlbHBlciBjbGFzcyB3aGljaCBrZWVwcyB0cmFjayBvZiBhbGwgaTE4bi1yZWxhdGVkIGFzcGVjdHNcbiAqIChhY2N1bXVsYXRlcyBwbGFjZWhvbGRlcnMsIGJpbmRpbmdzLCBldGMpIGJldHdlZW4gaTE4blN0YXJ0IGFuZCBpMThuRW5kIGluc3RydWN0aW9ucy5cbiAqXG4gKiBXaGVuIHdlIGVudGVyIGEgbmVzdGVkIHRlbXBsYXRlLCB0aGUgdG9wLWxldmVsIGNvbnRleHQgaXMgYmVpbmcgcGFzc2VkIGRvd25cbiAqIHRvIHRoZSBuZXN0ZWQgY29tcG9uZW50LCB3aGljaCB1c2VzIHRoaXMgY29udGV4dCB0byBnZW5lcmF0ZSBhIGNoaWxkIGluc3RhbmNlXG4gKiBvZiBJMThuQ29udGV4dCBjbGFzcyAodG8gaGFuZGxlIG5lc3RlZCB0ZW1wbGF0ZSkgYW5kIGF0IHRoZSBlbmQsIHJlY29uY2lsZXMgaXQgYmFja1xuICogd2l0aCB0aGUgcGFyZW50IGNvbnRleHQuXG4gKlxuICogQHBhcmFtIGluZGV4IEluc3RydWN0aW9uIGluZGV4IG9mIGkxOG5TdGFydCwgd2hpY2ggaW5pdGlhdGVzIHRoaXMgY29udGV4dFxuICogQHBhcmFtIHJlZiBSZWZlcmVuY2UgdG8gYSB0cmFuc2xhdGlvbiBjb25zdCB0aGF0IHJlcHJlc2VudHMgdGhlIGNvbnRlbnQgaWYgdGh1cyBjb250ZXh0XG4gKiBAcGFyYW0gbGV2ZWwgTmVzdG5nIGxldmVsIGRlZmluZWQgZm9yIGNoaWxkIGNvbnRleHRzXG4gKiBAcGFyYW0gdGVtcGxhdGVJbmRleCBJbnN0cnVjdGlvbiBpbmRleCBvZiBhIHRlbXBsYXRlIHdoaWNoIHRoaXMgY29udGV4dCBiZWxvbmdzIHRvXG4gKiBAcGFyYW0gbWV0YSBNZXRhIGluZm9ybWF0aW9uIChpZCwgbWVhbmluZywgZGVzY3JpcHRpb24sIGV0YykgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29udGV4dFxuICovXG5leHBvcnQgY2xhc3MgSTE4bkNvbnRleHQge1xuICBwdWJsaWMgcmVhZG9ubHkgaWQ6IG51bWJlcjtcbiAgcHVibGljIGJpbmRpbmdzID0gbmV3IFNldDxBU1Q+KCk7XG4gIHB1YmxpYyBwbGFjZWhvbGRlcnMgPSBuZXcgTWFwPHN0cmluZywgYW55W10+KCk7XG4gIHB1YmxpYyBpc0VtaXR0ZWQ6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBwcml2YXRlIF9yZWdpc3RyeSE6IGFueTtcbiAgcHJpdmF0ZSBfdW5yZXNvbHZlZEN0eENvdW50OiBudW1iZXIgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcmVhZG9ubHkgaW5kZXg6IG51bWJlciwgcmVhZG9ubHkgcmVmOiBvLlJlYWRWYXJFeHByLCByZWFkb25seSBsZXZlbDogbnVtYmVyID0gMCxcbiAgICAgIHJlYWRvbmx5IHRlbXBsYXRlSW5kZXg6IG51bWJlcnxudWxsID0gbnVsbCwgcmVhZG9ubHkgbWV0YTogaTE4bi5JMThuTWV0YSxcbiAgICAgIHByaXZhdGUgcmVnaXN0cnk/OiBhbnkpIHtcbiAgICB0aGlzLl9yZWdpc3RyeSA9IHJlZ2lzdHJ5IHx8IHNldHVwUmVnaXN0cnkoKTtcbiAgICB0aGlzLmlkID0gdGhpcy5fcmVnaXN0cnkuZ2V0VW5pcXVlSWQoKTtcbiAgfVxuXG4gIHByaXZhdGUgYXBwZW5kVGFnKHR5cGU6IFRhZ1R5cGUsIG5vZGU6IGkxOG4uVGFnUGxhY2Vob2xkZXIsIGluZGV4OiBudW1iZXIsIGNsb3NlZD86IGJvb2xlYW4pIHtcbiAgICBpZiAobm9kZS5pc1ZvaWQgJiYgY2xvc2VkKSB7XG4gICAgICByZXR1cm47ICAvLyBpZ25vcmUgXCJjbG9zZVwiIGZvciB2b2lkIHRhZ3NcbiAgICB9XG4gICAgY29uc3QgcGggPSBub2RlLmlzVm9pZCB8fCAhY2xvc2VkID8gbm9kZS5zdGFydE5hbWUgOiBub2RlLmNsb3NlTmFtZTtcbiAgICBjb25zdCBjb250ZW50ID0ge3R5cGUsIGluZGV4LCBjdHg6IHRoaXMuaWQsIGlzVm9pZDogbm9kZS5pc1ZvaWQsIGNsb3NlZH07XG4gICAgdXBkYXRlUGxhY2Vob2xkZXJNYXAodGhpcy5wbGFjZWhvbGRlcnMsIHBoLCBjb250ZW50KTtcbiAgfVxuXG4gIGdldCBpY3VzKCkge1xuICAgIHJldHVybiB0aGlzLl9yZWdpc3RyeS5pY3VzO1xuICB9XG4gIGdldCBpc1Jvb3QoKSB7XG4gICAgcmV0dXJuIHRoaXMubGV2ZWwgPT09IDA7XG4gIH1cbiAgZ2V0IGlzUmVzb2x2ZWQoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3VucmVzb2x2ZWRDdHhDb3VudCA9PT0gMDtcbiAgfVxuXG4gIGdldFNlcmlhbGl6ZWRQbGFjZWhvbGRlcnMoKSB7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IE1hcDxzdHJpbmcsIGFueVtdPigpO1xuICAgIHRoaXMucGxhY2Vob2xkZXJzLmZvckVhY2goXG4gICAgICAgICh2YWx1ZXMsIGtleSkgPT4gcmVzdWx0LnNldChrZXksIHZhbHVlcy5tYXAoc2VyaWFsaXplUGxhY2Vob2xkZXJWYWx1ZSkpKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gcHVibGljIEFQSSB0byBhY2N1bXVsYXRlIGkxOG4tcmVsYXRlZCBjb250ZW50XG4gIGFwcGVuZEJpbmRpbmcoYmluZGluZzogQVNUKSB7XG4gICAgdGhpcy5iaW5kaW5ncy5hZGQoYmluZGluZyk7XG4gIH1cbiAgYXBwZW5kSWN1KG5hbWU6IHN0cmluZywgcmVmOiBvLkV4cHJlc3Npb24pIHtcbiAgICB1cGRhdGVQbGFjZWhvbGRlck1hcCh0aGlzLl9yZWdpc3RyeS5pY3VzLCBuYW1lLCByZWYpO1xuICB9XG4gIGFwcGVuZEJvdW5kVGV4dChub2RlOiBpMThuLkkxOG5NZXRhKSB7XG4gICAgY29uc3QgcGhzID0gYXNzZW1ibGVCb3VuZFRleHRQbGFjZWhvbGRlcnMobm9kZSwgdGhpcy5iaW5kaW5ncy5zaXplLCB0aGlzLmlkKTtcbiAgICBwaHMuZm9yRWFjaCgodmFsdWVzLCBrZXkpID0+IHVwZGF0ZVBsYWNlaG9sZGVyTWFwKHRoaXMucGxhY2Vob2xkZXJzLCBrZXksIC4uLnZhbHVlcykpO1xuICB9XG4gIGFwcGVuZFRlbXBsYXRlKG5vZGU6IGkxOG4uSTE4bk1ldGEsIGluZGV4OiBudW1iZXIpIHtcbiAgICAvLyBhZGQgb3BlbiBhbmQgY2xvc2UgdGFncyBhdCB0aGUgc2FtZSB0aW1lLFxuICAgIC8vIHNpbmNlIHdlIHByb2Nlc3MgbmVzdGVkIHRlbXBsYXRlcyBzZXBhcmF0ZWx5XG4gICAgdGhpcy5hcHBlbmRUYWcoVGFnVHlwZS5URU1QTEFURSwgbm9kZSBhcyBpMThuLlRhZ1BsYWNlaG9sZGVyLCBpbmRleCwgZmFsc2UpO1xuICAgIHRoaXMuYXBwZW5kVGFnKFRhZ1R5cGUuVEVNUExBVEUsIG5vZGUgYXMgaTE4bi5UYWdQbGFjZWhvbGRlciwgaW5kZXgsIHRydWUpO1xuICAgIHRoaXMuX3VucmVzb2x2ZWRDdHhDb3VudCsrO1xuICB9XG4gIGFwcGVuZEVsZW1lbnQobm9kZTogaTE4bi5JMThuTWV0YSwgaW5kZXg6IG51bWJlciwgY2xvc2VkPzogYm9vbGVhbikge1xuICAgIHRoaXMuYXBwZW5kVGFnKFRhZ1R5cGUuRUxFTUVOVCwgbm9kZSBhcyBpMThuLlRhZ1BsYWNlaG9sZGVyLCBpbmRleCwgY2xvc2VkKTtcbiAgfVxuICBhcHBlbmRQcm9qZWN0aW9uKG5vZGU6IGkxOG4uSTE4bk1ldGEsIGluZGV4OiBudW1iZXIpIHtcbiAgICAvLyBBZGQgb3BlbiBhbmQgY2xvc2UgdGFncyBhdCB0aGUgc2FtZSB0aW1lLCBzaW5jZSBgPG5nLWNvbnRlbnQ+YCBoYXMgbm8gY29udGVudCxcbiAgICAvLyBzbyB3aGVuIHdlIGNvbWUgYWNyb3NzIGA8bmctY29udGVudD5gIHdlIGNhbiByZWdpc3RlciBib3RoIG9wZW4gYW5kIGNsb3NlIHRhZ3MuXG4gICAgLy8gTm90ZTogcnVudGltZSBpMThuIGxvZ2ljIGRvZXNuJ3QgZGlzdGluZ3Vpc2ggYDxuZy1jb250ZW50PmAgdGFnIHBsYWNlaG9sZGVycyBhbmRcbiAgICAvLyByZWd1bGFyIGVsZW1lbnQgdGFnIHBsYWNlaG9sZGVycywgc28gd2UgZ2VuZXJhdGUgZWxlbWVudCBwbGFjZWhvbGRlcnMgZm9yIGJvdGggdHlwZXMuXG4gICAgdGhpcy5hcHBlbmRUYWcoVGFnVHlwZS5FTEVNRU5ULCBub2RlIGFzIGkxOG4uVGFnUGxhY2Vob2xkZXIsIGluZGV4LCBmYWxzZSk7XG4gICAgdGhpcy5hcHBlbmRUYWcoVGFnVHlwZS5FTEVNRU5ULCBub2RlIGFzIGkxOG4uVGFnUGxhY2Vob2xkZXIsIGluZGV4LCB0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZW5lcmF0ZXMgYW4gaW5zdGFuY2Ugb2YgYSBjaGlsZCBjb250ZXh0IGJhc2VkIG9uIHRoZSByb290IG9uZSxcbiAgICogd2hlbiB3ZSBlbnRlciBhIG5lc3RlZCB0ZW1wbGF0ZSB3aXRoaW4gSTE4biBzZWN0aW9uLlxuICAgKlxuICAgKiBAcGFyYW0gaW5kZXggSW5zdHJ1Y3Rpb24gaW5kZXggb2YgY29ycmVzcG9uZGluZyBpMThuU3RhcnQsIHdoaWNoIGluaXRpYXRlcyB0aGlzIGNvbnRleHRcbiAgICogQHBhcmFtIHRlbXBsYXRlSW5kZXggSW5zdHJ1Y3Rpb24gaW5kZXggb2YgYSB0ZW1wbGF0ZSB3aGljaCB0aGlzIGNvbnRleHQgYmVsb25ncyB0b1xuICAgKiBAcGFyYW0gbWV0YSBNZXRhIGluZm9ybWF0aW9uIChpZCwgbWVhbmluZywgZGVzY3JpcHRpb24sIGV0YykgYXNzb2NpYXRlZCB3aXRoIHRoaXMgY29udGV4dFxuICAgKlxuICAgKiBAcmV0dXJucyBJMThuQ29udGV4dCBpbnN0YW5jZVxuICAgKi9cbiAgZm9ya0NoaWxkQ29udGV4dChpbmRleDogbnVtYmVyLCB0ZW1wbGF0ZUluZGV4OiBudW1iZXIsIG1ldGE6IGkxOG4uSTE4bk1ldGEpIHtcbiAgICByZXR1cm4gbmV3IEkxOG5Db250ZXh0KGluZGV4LCB0aGlzLnJlZiwgdGhpcy5sZXZlbCArIDEsIHRlbXBsYXRlSW5kZXgsIG1ldGEsIHRoaXMuX3JlZ2lzdHJ5KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvbmNpbGVzIGNoaWxkIGNvbnRleHQgaW50byBwYXJlbnQgb25lIG9uY2UgdGhlIGVuZCBvZiB0aGUgaTE4biBibG9jayBpcyByZWFjaGVkIChpMThuRW5kKS5cbiAgICpcbiAgICogQHBhcmFtIGNvbnRleHQgQ2hpbGQgSTE4bkNvbnRleHQgaW5zdGFuY2UgdG8gYmUgcmVjb25jaWxlZCB3aXRoIHBhcmVudCBjb250ZXh0LlxuICAgKi9cbiAgcmVjb25jaWxlQ2hpbGRDb250ZXh0KGNvbnRleHQ6IEkxOG5Db250ZXh0KSB7XG4gICAgLy8gc2V0IHRoZSByaWdodCBjb250ZXh0IGlkIGZvciBvcGVuIGFuZCBjbG9zZVxuICAgIC8vIHRlbXBsYXRlIHRhZ3MsIHNvIHdlIGNhbiB1c2UgaXQgYXMgc3ViLWJsb2NrIGlkc1xuICAgIFsnc3RhcnQnLCAnY2xvc2UnXS5mb3JFYWNoKChvcDogc3RyaW5nKSA9PiB7XG4gICAgICBjb25zdCBrZXkgPSAoY29udGV4dC5tZXRhIGFzIGFueSlbYCR7b3B9TmFtZWBdO1xuICAgICAgY29uc3QgcGhzID0gdGhpcy5wbGFjZWhvbGRlcnMuZ2V0KGtleSkgfHwgW107XG4gICAgICBjb25zdCB0YWcgPSBwaHMuZmluZChmaW5kVGVtcGxhdGVGbih0aGlzLmlkLCBjb250ZXh0LnRlbXBsYXRlSW5kZXgpKTtcbiAgICAgIGlmICh0YWcpIHtcbiAgICAgICAgdGFnLmN0eCA9IGNvbnRleHQuaWQ7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyByZWNvbmNpbGUgcGxhY2Vob2xkZXJzXG4gICAgY29uc3QgY2hpbGRQaHMgPSBjb250ZXh0LnBsYWNlaG9sZGVycztcbiAgICBjaGlsZFBocy5mb3JFYWNoKCh2YWx1ZXM6IGFueVtdLCBrZXk6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3QgcGhzID0gdGhpcy5wbGFjZWhvbGRlcnMuZ2V0KGtleSk7XG4gICAgICBpZiAoIXBocykge1xuICAgICAgICB0aGlzLnBsYWNlaG9sZGVycy5zZXQoa2V5LCB2YWx1ZXMpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyB0cnkgdG8gZmluZCBtYXRjaGluZyB0ZW1wbGF0ZS4uLlxuICAgICAgY29uc3QgdG1wbElkeCA9IHBocy5maW5kSW5kZXgoZmluZFRlbXBsYXRlRm4oY29udGV4dC5pZCwgY29udGV4dC50ZW1wbGF0ZUluZGV4KSk7XG4gICAgICBpZiAodG1wbElkeCA+PSAwKSB7XG4gICAgICAgIC8vIC4uLiBpZiBmb3VuZCAtIHJlcGxhY2UgaXQgd2l0aCBuZXN0ZWQgdGVtcGxhdGUgY29udGVudFxuICAgICAgICBjb25zdCBpc0Nsb3NlVGFnID0ga2V5LnN0YXJ0c1dpdGgoJ0NMT1NFJyk7XG4gICAgICAgIGNvbnN0IGlzVGVtcGxhdGVUYWcgPSBrZXkuZW5kc1dpdGgoJ05HLVRFTVBMQVRFJyk7XG4gICAgICAgIGlmIChpc1RlbXBsYXRlVGFnKSB7XG4gICAgICAgICAgLy8gY3VycmVudCB0ZW1wbGF0ZSdzIGNvbnRlbnQgaXMgcGxhY2VkIGJlZm9yZSBvciBhZnRlclxuICAgICAgICAgIC8vIHBhcmVudCB0ZW1wbGF0ZSB0YWcsIGRlcGVuZGluZyBvbiB0aGUgb3Blbi9jbG9zZSBhdHJyaWJ1dGVcbiAgICAgICAgICBwaHMuc3BsaWNlKHRtcGxJZHggKyAoaXNDbG9zZVRhZyA/IDAgOiAxKSwgMCwgLi4udmFsdWVzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBjb25zdCBpZHggPSBpc0Nsb3NlVGFnID8gdmFsdWVzLmxlbmd0aCAtIDEgOiAwO1xuICAgICAgICAgIHZhbHVlc1tpZHhdLnRtcGwgPSBwaHNbdG1wbElkeF07XG4gICAgICAgICAgcGhzLnNwbGljZSh0bXBsSWR4LCAxLCAuLi52YWx1ZXMpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyAuLi4gb3RoZXJ3aXNlIGp1c3QgYXBwZW5kIGNvbnRlbnQgdG8gcGxhY2Vob2xkZXIgdmFsdWVcbiAgICAgICAgcGhzLnB1c2goLi4udmFsdWVzKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucGxhY2Vob2xkZXJzLnNldChrZXksIHBocyk7XG4gICAgfSk7XG4gICAgdGhpcy5fdW5yZXNvbHZlZEN0eENvdW50LS07XG4gIH1cbn1cblxuLy9cbi8vIEhlbHBlciBtZXRob2RzXG4vL1xuXG5mdW5jdGlvbiB3cmFwKHN5bWJvbDogc3RyaW5nLCBpbmRleDogbnVtYmVyLCBjb250ZXh0SWQ6IG51bWJlciwgY2xvc2VkPzogYm9vbGVhbik6IHN0cmluZyB7XG4gIGNvbnN0IHN0YXRlID0gY2xvc2VkID8gJy8nIDogJyc7XG4gIHJldHVybiB3cmFwSTE4blBsYWNlaG9sZGVyKGAke3N0YXRlfSR7c3ltYm9sfSR7aW5kZXh9YCwgY29udGV4dElkKTtcbn1cblxuZnVuY3Rpb24gd3JhcFRhZyhzeW1ib2w6IHN0cmluZywge2luZGV4LCBjdHgsIGlzVm9pZH06IGFueSwgY2xvc2VkPzogYm9vbGVhbik6IHN0cmluZyB7XG4gIHJldHVybiBpc1ZvaWQgPyB3cmFwKHN5bWJvbCwgaW5kZXgsIGN0eCkgKyB3cmFwKHN5bWJvbCwgaW5kZXgsIGN0eCwgdHJ1ZSkgOlxuICAgICAgICAgICAgICAgICAgd3JhcChzeW1ib2wsIGluZGV4LCBjdHgsIGNsb3NlZCk7XG59XG5cbmZ1bmN0aW9uIGZpbmRUZW1wbGF0ZUZuKGN0eDogbnVtYmVyLCB0ZW1wbGF0ZUluZGV4OiBudW1iZXJ8bnVsbCkge1xuICByZXR1cm4gKHRva2VuOiBhbnkpID0+IHR5cGVvZiB0b2tlbiA9PT0gJ29iamVjdCcgJiYgdG9rZW4udHlwZSA9PT0gVGFnVHlwZS5URU1QTEFURSAmJlxuICAgICAgdG9rZW4uaW5kZXggPT09IHRlbXBsYXRlSW5kZXggJiYgdG9rZW4uY3R4ID09PSBjdHg7XG59XG5cbmZ1bmN0aW9uIHNlcmlhbGl6ZVBsYWNlaG9sZGVyVmFsdWUodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gIGNvbnN0IGVsZW1lbnQgPSAoZGF0YTogYW55LCBjbG9zZWQ/OiBib29sZWFuKSA9PiB3cmFwVGFnKCcjJywgZGF0YSwgY2xvc2VkKTtcbiAgY29uc3QgdGVtcGxhdGUgPSAoZGF0YTogYW55LCBjbG9zZWQ/OiBib29sZWFuKSA9PiB3cmFwVGFnKCcqJywgZGF0YSwgY2xvc2VkKTtcbiAgY29uc3QgcHJvamVjdGlvbiA9IChkYXRhOiBhbnksIGNsb3NlZD86IGJvb2xlYW4pID0+IHdyYXBUYWcoJyEnLCBkYXRhLCBjbG9zZWQpO1xuXG4gIHN3aXRjaCAodmFsdWUudHlwZSkge1xuICAgIGNhc2UgVGFnVHlwZS5FTEVNRU5UOlxuICAgICAgLy8gY2xvc2UgZWxlbWVudCB0YWdcbiAgICAgIGlmICh2YWx1ZS5jbG9zZWQpIHtcbiAgICAgICAgcmV0dXJuIGVsZW1lbnQodmFsdWUsIHRydWUpICsgKHZhbHVlLnRtcGwgPyB0ZW1wbGF0ZSh2YWx1ZS50bXBsLCB0cnVlKSA6ICcnKTtcbiAgICAgIH1cbiAgICAgIC8vIG9wZW4gZWxlbWVudCB0YWcgdGhhdCBhbHNvIGluaXRpYXRlcyBhIHRlbXBsYXRlXG4gICAgICBpZiAodmFsdWUudG1wbCkge1xuICAgICAgICByZXR1cm4gdGVtcGxhdGUodmFsdWUudG1wbCkgKyBlbGVtZW50KHZhbHVlKSArXG4gICAgICAgICAgICAodmFsdWUuaXNWb2lkID8gdGVtcGxhdGUodmFsdWUudG1wbCwgdHJ1ZSkgOiAnJyk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZWxlbWVudCh2YWx1ZSk7XG5cbiAgICBjYXNlIFRhZ1R5cGUuVEVNUExBVEU6XG4gICAgICByZXR1cm4gdGVtcGxhdGUodmFsdWUsIHZhbHVlLmNsb3NlZCk7XG5cbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIHZhbHVlO1xuICB9XG59XG4iXX0= |
---|