UNPKG

28.6 kBJavaScriptView Raw
1'use strict';
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.init = exports.ForeignTokenizer = void 0;
4/**
5 * 外文字符、数字识别模块
6 *
7 * @author 老雷<leizongmin@gmail.com>
8 */
9const mod_1 = require("../mod");
10const debug_1 = require("../util/debug");
11class ForeignTokenizer extends mod_1.SubSModuleTokenizer {
12 constructor() {
13 super(...arguments);
14 this.name = 'ForeignTokenizer';
15 }
16 _cache() {
17 super._cache();
18 this._TABLE = this.segment.getDict('TABLE');
19 let arr = [
20 /[\d0-9]+(?:,[\d0-9]+)?(?:\.[\d0-9]+)?/,
21 /[\w0-9A-Za-z\u0100-\u017F\u00A1-\u00FF]+/,
22 /[\u0600-\u06FF\u0750-\u077F]+/,
23 /[\u0400-\u04FF]+/,
24 // https://unicode-table.com/cn/blocks/greek-coptic/
25 /[\u0370-\u03FF]+/,
26 ];
27 this._REGEXP_SPLIT_1 = new RegExp('(' + _join([
28 /[\u4E00-\u9FFF]+/,
29 ].concat(arr)) + ')', 'iu');
30 this._REGEXP_SPLIT_2 = new RegExp('(' + _join(arr) + ')', 'iu');
31 function _join(arr) {
32 return arr.reduce(function (a, b) {
33 if (b instanceof RegExp) {
34 a.push(b.source);
35 }
36 else {
37 a.push(b);
38 }
39 return a;
40 }, []).join('|');
41 }
42 }
43 /**
44 * 对未识别的单词进行分词
45 *
46 * @param {array} words 单词数组
47 * @return {array}
48 */
49 split(words) {
50 //return this._splitUnknow(words, this.splitForeign);
51 return this._splitUnknow(words, this.splitForeign2);
52 /*
53 const POSTAG = this.segment.POSTAG;
54
55 let ret = [];
56 for (let i = 0, word; word = words[i]; i++)
57 {
58 if (word.p)
59 {
60 ret.push(word);
61 }
62 else
63 {
64 // 仅对未识别的词进行匹配
65 ret = ret.concat(this.splitForeign(word.w));
66 }
67 }
68 return ret;
69 */
70 }
71 /**
72 * 支援更多外文判定(但可能會降低效率)
73 *
74 * 並且避免誤切割 例如 latīna Русский
75 */
76 splitForeign2(text, cur) {
77 const POSTAG = this.segment.POSTAG;
78 const TABLE = this._TABLE;
79 //console.time('splitForeign2');
80 let ret = [];
81 let self = this;
82 let ls = text
83 .split(this._REGEXP_SPLIT_1);
84 for (let w of ls) {
85 if (w !== '') {
86 if (this._REGEXP_SPLIT_2.test(w)) {
87 let cw = TABLE[w];
88 if (cw) {
89 let nw = this.createRawToken({
90 w,
91 }, cw, {
92 [this.name]: 1,
93 });
94 ret.push(nw);
95 continue;
96 }
97 /**
98 * 當分詞不存在於字典中時
99 * 則再度分詞一次
100 */
101 let ls2 = w
102 .split(/([\d+0-9]+)/);
103 for (let w of ls2) {
104 if (w === '') {
105 continue;
106 }
107 let lasttype = 0;
108 let c = w.charCodeAt(0);
109 if (c >= 65296 && c <= 65370)
110 c -= 65248;
111 if (c >= 48 && c <= 57) {
112 lasttype = POSTAG.A_M;
113 } // 字母 lasttype = POSTAG.A_NX
114 else if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122)) {
115 lasttype = POSTAG.A_NX;
116 }
117 else {
118 lasttype = POSTAG.UNK;
119 }
120 if (lasttype === POSTAG.A_NX) {
121 let cw = TABLE[w];
122 if (cw) {
123 let nw = this.createRawToken({
124 w,
125 }, cw, {
126 [this.name]: 2,
127 });
128 ret.push(nw);
129 continue;
130 }
131 }
132 ret.push(self.debugToken({
133 w: w,
134 p: lasttype || undefined,
135 }, {
136 [self.name]: 3,
137 }, true));
138 }
139 }
140 else {
141 ret.push({
142 w,
143 });
144 }
145 }
146 }
147 //console.timeEnd('splitForeign2');
148 //console.log(ret);
149 return ret.length ? ret : undefined;
150 }
151 /**
152 * 匹配包含的英文字符和数字,并分割
153 *
154 * @param {string} text 文本
155 * @param {int} cur 开始位置
156 * @return {array} 返回格式 {w: '单词', c: 开始位置}
157 */
158 splitForeign(text, cur) {
159 const POSTAG = this.segment.POSTAG;
160 const TABLE = this._TABLE;
161 //console.time('splitForeign');
162 if (isNaN(cur))
163 cur = 0;
164 let ret = [];
165 // 取第一个字符的ASCII码
166 let lastcur = 0;
167 let lasttype = 0;
168 let c = text.charCodeAt(0);
169 // 全角数字或字母
170 if (c >= 65296 && c <= 65370)
171 c -= 65248;
172 // 数字 lasttype = POSTAG.A_M
173 if (c >= 48 && c <= 57) {
174 lasttype = POSTAG.A_M;
175 } // 字母 lasttype = POSTAG.A_NX
176 else if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122)) {
177 lasttype = POSTAG.A_NX;
178 }
179 else {
180 lasttype = POSTAG.UNK;
181 }
182 let i;
183 for (i = 1; i < text.length; i++) {
184 let c = text.charCodeAt(i);
185 // 全角数字或字母
186 if (c >= 65296 && c <= 65370)
187 c -= 65248;
188 // 数字 lasttype = POSTAG.A_M
189 if (c >= 48 && c <= 57) {
190 if (lasttype !== POSTAG.A_M) {
191 let nw = this.createForeignToken({
192 w: text.substr(lastcur, i - lastcur),
193 }, lasttype, {
194 [this.name]: 1,
195 });
196 //let nw = { w: text.substr(lastcur, i - lastcur) } as IWord;
197 //if (lasttype !== POSTAG.UNK) nw.p = lasttype;
198 ret.push(nw);
199 lastcur = i;
200 }
201 lasttype = POSTAG.A_M;
202 }
203 else if ((c >= 65 && c <= 90) || (c >= 97 && c <= 122)) {
204 // 字母 lasttype = POSTAG.A_NX
205 if (lasttype !== POSTAG.A_NX) {
206 //let nw = { w: text.substr(lastcur, i - lastcur) } as IWord;
207 let nw = this.createRawToken({
208 w: text.substr(lastcur, i - lastcur),
209 }, {
210 p: lasttype
211 }, {
212 [this.name]: 2,
213 });
214 //if (lasttype !== POSTAG.UNK) nw.p = lasttype;
215 ret.push(nw);
216 lastcur = i;
217 }
218 lasttype = POSTAG.A_NX;
219 }
220 else {
221 // 其他
222 if (lasttype !== POSTAG.UNK) {
223 let nw = this.createForeignToken({
224 w: text.substr(lastcur, i - lastcur),
225 p: lasttype
226 }, undefined, {
227 [this.name]: 3,
228 });
229 ret.push(nw);
230 lastcur = i;
231 }
232 lasttype = POSTAG.UNK;
233 }
234 }
235 // 剩余部分
236 //let nw = { w: text.substr(lastcur, i - lastcur) } as IWord;
237 let nw = this.createRawToken({
238 w: text.substr(lastcur, i - lastcur),
239 });
240 if (lasttype !== POSTAG.UNK)
241 nw.p = lasttype;
242 ret.push(nw);
243 //console.timeEnd('splitForeign');
244 //debug(ret);
245 return ret;
246 }
247 createForeignToken(word, lasttype, attr) {
248 let nw = this.createToken(word, true, attr);
249 let ow = this._TABLE[nw.w];
250 if (ow) {
251 debug_1.debugToken(nw, {
252 _source: ow,
253 });
254 nw.p = nw.p | ow.p;
255 }
256 if (lasttype && lasttype !== this._POSTAG.UNK) {
257 nw.p = lasttype | nw.p;
258 }
259 return nw;
260 }
261}
262exports.ForeignTokenizer = ForeignTokenizer;
263exports.init = ForeignTokenizer.init.bind(ForeignTokenizer);
264exports.default = ForeignTokenizer;
265//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRm9yZWlnblRva2VuaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIkZvcmVpZ25Ub2tlbml6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWSxDQUFDOzs7QUFFYjs7OztHQUlHO0FBQ0gsZ0NBQThFO0FBRTlFLHlDQUEyQztBQUszQyxNQUFhLGdCQUFpQixTQUFRLHlCQUFtQjtJQUF6RDs7UUFHQyxTQUFJLEdBQUcsa0JBQWtCLENBQUM7SUE0VTNCLENBQUM7SUFqVUEsTUFBTTtRQUVMLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNmLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUM7UUFFNUMsSUFBSSxHQUFHLEdBQUc7WUFDVCx1Q0FBdUM7WUFDdkMsMENBQTBDO1lBQzFDLCtCQUErQjtZQUMvQixrQkFBa0I7WUFDbEIsb0RBQW9EO1lBQ3BELGtCQUFrQjtTQUNsQixDQUFDO1FBRUYsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLE1BQU0sQ0FBQyxHQUFHLEdBQUUsS0FBSyxDQUFDO1lBQzVDLGtCQUFrQjtTQUNsQixDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxHQUFHLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUU1QixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksTUFBTSxDQUFDLEdBQUcsR0FBRSxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQUcsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBRS9ELFNBQVMsS0FBSyxDQUFDLEdBQTJCO1lBRXpDLE9BQU8sR0FBRyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO2dCQUUvQixJQUFJLENBQUMsWUFBWSxNQUFNLEVBQ3ZCO29CQUNDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2lCQUNqQjtxQkFFRDtvQkFDQyxDQUFDLENBQUMsSUFB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L1VELDRDQStVQztBQUVZLFFBQUEsSUFBSSxHQUFHLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQTBDLENBQUM7QUFFMUcsa0JBQWUsZ0JBQWdCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIndXNlIHN0cmljdCc7XG5cbi8qKlxuICog5aSW5paH5a2X56ym44CB5pWw5a2X6K+G5Yir5qih5Z2XXG4gKlxuICogQGF1dGhvciDogIHpm7c8bGVpem9uZ21pbkBnbWFpbC5jb20+XG4gKi9cbmltcG9ydCB7IFN1YlNNb2R1bGUsIFN1YlNNb2R1bGVUb2tlbml6ZXIsIElTdWJUb2tlbml6ZXJDcmVhdGUgfSBmcm9tICcuLi9tb2QnO1xuaW1wb3J0IHsgU2VnbWVudCwgSVdvcmQgfSBmcm9tICcuLi9TZWdtZW50JztcbmltcG9ydCB7IGRlYnVnVG9rZW4gfSBmcm9tICcuLi91dGlsL2RlYnVnJztcbmltcG9ydCBVU3RyaW5nIGZyb20gJ3VuaS1zdHJpbmcnO1xuaW1wb3J0IHsgZGVidWcgfSBmcm9tICcuLi91dGlsJztcbmltcG9ydCB7IElXb3JkRGVidWdJbmZvIH0gZnJvbSAnLi4vdXRpbC9pbmRleCc7XG5cbmV4cG9ydCBjbGFzcyBGb3JlaWduVG9rZW5pemVyIGV4dGVuZHMgU3ViU01vZHVsZVRva2VuaXplclxue1xuXG5cdG5hbWUgPSAnRm9yZWlnblRva2VuaXplcic7XG5cblx0LyoqXG5cdCAqIOWIhuipnueUqCjljIXlkKvkuK3mlocpXG5cdCAqL1xuXHRfUkVHRVhQX1NQTElUXzE6IFJlZ0V4cDtcblx0LyoqXG5cdCAqIOWIhuipnueUqCjkuI3ljIXlkKvkuK3mlofnmoTlhajoqZ7nrKblkIgpXG5cdCAqL1xuXHRfUkVHRVhQX1NQTElUXzI6IFJlZ0V4cDtcblxuXHRfY2FjaGUoKVxuXHR7XG5cdFx0c3VwZXIuX2NhY2hlKCk7XG5cdFx0dGhpcy5fVEFCTEUgPSB0aGlzLnNlZ21lbnQuZ2V0RGljdCgnVEFCTEUnKTtcblxuXHRcdGxldCBhcnIgPSBbXG5cdFx0XHQvW1xcZO+8kC3vvJldKyg/OixbXFxk77yQLe+8mV0rKT8oPzpcXC5bXFxk77yQLe+8mV0rKT8vLFxuXHRcdFx0L1tcXHfvvJAt77yZ77yhLe+8uu+9gS3vvZpcXHUwMTAwLVxcdTAxN0ZcXHUwMEExLVxcdTAwRkZdKy8sXG5cdFx0XHQvW1xcdTA2MDAtXFx1MDZGRlxcdTA3NTAtXFx1MDc3Rl0rLyxcblx0XHRcdC9bXFx1MDQwMC1cXHUwNEZGXSsvLFxuXHRcdFx0Ly8gaHR0cHM6Ly91bmljb2RlLXRhYmxlLmNvbS9jbi9ibG9ja3MvZ3JlZWstY29wdGljL1xuXHRcdFx0L1tcXHUwMzcwLVxcdTAzRkZdKy8sXG5cdFx0XTtcblxuXHRcdHRoaXMuX1JFR0VYUF9TUExJVF8xID0gbmV3IFJlZ0V4cCgnKCcgK19qb2luKFtcblx0XHRcdC9bXFx1NEUwMC1cXHU5RkZGXSsvLFxuXHRcdF0uY29uY2F0KGFycikpICsgJyknLCAnaXUnKTtcblxuXHRcdHRoaXMuX1JFR0VYUF9TUExJVF8yID0gbmV3IFJlZ0V4cCgnKCcgK19qb2luKGFycikgKyAnKScsICdpdScpO1xuXG5cdFx0ZnVuY3Rpb24gX2pvaW4oYXJyOiBBcnJheTxzdHJpbmcgfCBSZWdFeHA+KVxuXHRcdHtcblx0XHRcdHJldHVybiBhcnIucmVkdWNlKGZ1bmN0aW9uIChhLCBiKVxuXHRcdFx0e1xuXHRcdFx0XHRpZiAoYiBpbnN0YW5jZW9mIFJlZ0V4cClcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGEucHVzaChiLnNvdXJjZSk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxzZVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0YS5wdXNoKGIpO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIGE7XG5cdFx0XHR9LCBbXSkuam9pbignfCcpXG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIOWvueacquivhuWIq+eahOWNleivjei/m+ihjOWIhuivjVxuXHQgKlxuXHQgKiBAcGFyYW0ge2FycmF5fSB3b3JkcyDljZXor43mlbDnu4Rcblx0ICogQHJldHVybiB7YXJyYXl9XG5cdCAqL1xuXHRzcGxpdCh3b3JkczogSVdvcmRbXSk6IElXb3JkW11cblx0e1xuXHRcdC8vcmV0dXJuIHRoaXMuX3NwbGl0VW5rbm93KHdvcmRzLCB0aGlzLnNwbGl0Rm9yZWlnbik7XG5cdFx0cmV0dXJuIHRoaXMuX3NwbGl0VW5rbm93KHdvcmRzLCB0aGlzLnNwbGl0Rm9yZWlnbjIpO1xuXG5cdFx0Lypcblx0XHRjb25zdCBQT1NUQUcgPSB0aGlzLnNlZ21lbnQuUE9TVEFHO1xuXG5cdFx0bGV0IHJldCA9IFtdO1xuXHRcdGZvciAobGV0IGkgPSAwLCB3b3JkOyB3b3JkID0gd29yZHNbaV07IGkrKylcblx0XHR7XG5cdFx0XHRpZiAod29yZC5wKVxuXHRcdFx0e1xuXHRcdFx0XHRyZXQucHVzaCh3b3JkKTtcblx0XHRcdH1cblx0XHRcdGVsc2Vcblx0XHRcdHtcblx0XHRcdFx0Ly8g5LuF5a+55pyq6K+G5Yir55qE6K+N6L+b6KGM5Yy56YWNXG5cdFx0XHRcdHJldCA9IHJldC5jb25jYXQodGhpcy5zcGxpdEZvcmVpZ24od29yZC53KSk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiByZXQ7XG5cdFx0Ki9cblx0fVxuXG5cdC8qKlxuXHQgKiDmlK/mj7Tmm7TlpJrlpJbmlofliKTlrpoo5L2G5Y+v6IO95pyD6ZmN5L2O5pWI546HKVxuXHQgKlxuXHQgKiDkuKbkuJTpgb/lhY3oqqTliIflibIg5L6L5aaCIGxhdMSrbmEg0KDRg9GB0YHQutC40Llcblx0ICovXG5cdHNwbGl0Rm9yZWlnbjIodGV4dDogc3RyaW5nLCBjdXI/OiBudW1iZXIpOiBJV29yZFtdXG5cdHtcblx0XHRjb25zdCBQT1NUQUcgPSB0aGlzLnNlZ21lbnQuUE9TVEFHO1xuXHRcdGNvbnN0IFRBQkxFID0gdGhpcy5fVEFCTEU7XG5cblx0XHQvL2NvbnNvbGUudGltZSgnc3BsaXRGb3JlaWduMicpO1xuXG5cdFx0bGV0IHJldDogSVdvcmRbXSA9IFtdO1xuXHRcdGxldCBzZWxmID0gdGhpcztcblxuXHRcdGxldCBscyA9IHRleHRcblx0XHRcdC5zcGxpdCh0aGlzLl9SRUdFWFBfU1BMSVRfMSlcblx0XHQ7XG5cblx0XHRmb3IgKGxldCB3IG9mIGxzKVxuXHRcdHtcblx0XHRcdGlmICh3ICE9PSAnJylcblx0XHRcdHtcblx0XHRcdFx0aWYgKHRoaXMuX1JFR0VYUF9TUExJVF8yLnRlc3QodykpXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRsZXQgY3cgPSBUQUJMRVt3XTtcblxuXHRcdFx0XHRcdGlmIChjdylcblx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRsZXQgbncgPSB0aGlzLmNyZWF0ZVJhd1Rva2VuKHtcblx0XHRcdFx0XHRcdFx0dyxcblx0XHRcdFx0XHRcdH0sIGN3LCB7XG5cdFx0XHRcdFx0XHRcdFt0aGlzLm5hbWVdOiAxLFxuXHRcdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHRcdHJldC5wdXNoKG53KTtcblx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8qKlxuXHRcdFx0XHRcdCAqIOeVtuWIhuipnuS4jeWtmOWcqOaWvOWtl+WFuOS4reaZglxuXHRcdFx0XHRcdCAqIOWJh+WGjeW6puWIhuipnuS4gOasoVxuXHRcdFx0XHRcdCAqL1xuXHRcdFx0XHRcdGxldCBsczIgPSB3XG5cdFx0XHRcdFx0XHQuc3BsaXQoLyhbXFxkK++8kC3vvJldKykvKVxuXHRcdFx0XHRcdDtcblxuXHRcdFx0XHRcdGZvciAobGV0IHcgb2YgbHMyKVxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdGlmICh3ID09PSAnJylcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdGxldCBsYXN0dHlwZSA9IDA7XG5cblx0XHRcdFx0XHRcdGxldCBjID0gdy5jaGFyQ29kZUF0KDApO1xuXHRcdFx0XHRcdFx0aWYgKGMgPj0gNjUyOTYgJiYgYyA8PSA2NTM3MCkgYyAtPSA2NTI0ODtcblxuXHRcdFx0XHRcdFx0aWYgKGMgPj0gNDggJiYgYyA8PSA1Nylcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0bGFzdHR5cGUgPSBQT1NUQUcuQV9NO1xuXHRcdFx0XHRcdFx0fS8vIOWtl+avjSBsYXN0dHlwZSA9IFBPU1RBRy5BX05YXG5cdFx0XHRcdFx0XHRlbHNlIGlmICgoYyA+PSA2NSAmJiBjIDw9IDkwKSB8fCAoYyA+PSA5NyAmJiBjIDw9IDEyMikpXG5cdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdGxhc3R0eXBlID0gUE9TVEFHLkFfTlg7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRlbHNlXG5cdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdGxhc3R0eXBlID0gUE9TVEFHLlVOSztcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0aWYgKGxhc3R0eXBlID09PSBQT1NUQUcuQV9OWClcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0bGV0IGN3ID0gVEFCTEVbd107XG5cblx0XHRcdFx0XHRcdFx0aWYgKGN3KVxuXHRcdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdFx0bGV0IG53ID0gdGhpcy5jcmVhdGVSYXdUb2tlbih7XG5cdFx0XHRcdFx0XHRcdFx0XHR3LFxuXHRcdFx0XHRcdFx0XHRcdH0sIGN3LCB7XG5cdFx0XHRcdFx0XHRcdFx0XHRbdGhpcy5uYW1lXTogMixcblx0XHRcdFx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHRcdFx0XHRcdHJldC5wdXNoKG53KTtcblx0XHRcdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRyZXQucHVzaChzZWxmLmRlYnVnVG9rZW4oe1xuXHRcdFx0XHRcdFx0XHR3OiB3LFxuXHRcdFx0XHRcdFx0XHRwOiBsYXN0dHlwZSB8fCB1bmRlZmluZWQsXG5cdFx0XHRcdFx0XHR9LCB7XG5cdFx0XHRcdFx0XHRcdFtzZWxmLm5hbWVdOiAzLFxuXHRcdFx0XHRcdFx0fSwgdHJ1ZSkpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHRlbHNlXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRyZXQucHVzaCh7XG5cdFx0XHRcdFx0XHR3LFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly9jb25zb2xlLnRpbWVFbmQoJ3NwbGl0Rm9yZWlnbjInKTtcblxuXHRcdC8vY29uc29sZS5sb2cocmV0KTtcblxuXHRcdHJldHVybiByZXQubGVuZ3RoID8gcmV0IDogdW5kZWZpbmVkO1xuXHR9XG5cblx0LyoqXG5cdCAqIOWMuemFjeWMheWQq+eahOiLseaWh+Wtl+espuWSjOaVsOWtl++8jOW5tuWIhuWJslxuXHQgKlxuXHQgKiBAcGFyYW0ge3N0cmluZ30gdGV4dCDmlofmnKxcblx0ICogQHBhcmFtIHtpbnR9IGN1ciDlvIDlp4vkvY3nva5cblx0ICogQHJldHVybiB7YXJyYXl9ICDov5Tlm57moLzlvI8gICB7dzogJ+WNleivjScsIGM6IOW8gOWni+S9jee9rn1cblx0ICovXG5cdHNwbGl0Rm9yZWlnbih0ZXh0OiBzdHJpbmcsIGN1cj86IG51bWJlcik6IElXb3JkW11cblx0e1xuXHRcdGNvbnN0IFBPU1RBRyA9IHRoaXMuc2VnbWVudC5QT1NUQUc7XG5cdFx0Y29uc3QgVEFCTEUgPSB0aGlzLl9UQUJMRTtcblxuXHRcdC8vY29uc29sZS50aW1lKCdzcGxpdEZvcmVpZ24nKTtcblxuXHRcdGlmIChpc05hTihjdXIpKSBjdXIgPSAwO1xuXHRcdGxldCByZXQgPSBbXTtcblxuXHRcdC8vIOWPluesrOS4gOS4quWtl+espueahEFTQ0lJ56CBXG5cdFx0bGV0IGxhc3RjdXIgPSAwO1xuXHRcdGxldCBsYXN0dHlwZSA9IDA7XG5cdFx0bGV0IGMgPSB0ZXh0LmNoYXJDb2RlQXQoMCk7XG5cdFx0Ly8g5YWo6KeS5pWw5a2X5oiW5a2X5q+NXG5cdFx0aWYgKGMgPj0gNjUyOTYgJiYgYyA8PSA2NTM3MCkgYyAtPSA2NTI0ODtcblx0XHQvLyDmlbDlrZcgIGxhc3R0eXBlID0gUE9TVEFHLkFfTVxuXHRcdGlmIChjID49IDQ4ICYmIGMgPD0gNTcpXG5cdFx0e1xuXHRcdFx0bGFzdHR5cGUgPSBQT1NUQUcuQV9NO1xuXHRcdH0vLyDlrZfmr40gbGFzdHR5cGUgPSBQT1NUQUcuQV9OWFxuXHRcdGVsc2UgaWYgKChjID49IDY1ICYmIGMgPD0gOTApIHx8IChjID49IDk3ICYmIGMgPD0gMTIyKSlcblx0XHR7XG5cdFx0XHRsYXN0dHlwZSA9IFBPU1RBRy5BX05YO1xuXHRcdH1cblx0XHRlbHNlXG5cdFx0e1xuXHRcdFx0bGFzdHR5cGUgPSBQT1NUQUcuVU5LO1xuXHRcdH1cblxuXHRcdGxldCBpOiBudW1iZXI7XG5cblx0XHRmb3IgKGkgPSAxOyBpIDwgdGV4dC5sZW5ndGg7IGkrKylcblx0XHR7XG5cdFx0XHRsZXQgYyA9IHRleHQuY2hhckNvZGVBdChpKTtcblx0XHRcdC8vIOWFqOinkuaVsOWtl+aIluWtl+avjVxuXHRcdFx0aWYgKGMgPj0gNjUyOTYgJiYgYyA8PSA2NTM3MCkgYyAtPSA2NTI0ODtcblx0XHRcdC8vIOaVsOWtlyAgbGFzdHR5cGUgPSBQT1NUQUcuQV9NXG5cdFx0XHRpZiAoYyA+PSA0OCAmJiBjIDw9IDU3KVxuXHRcdFx0e1xuXHRcdFx0XHRpZiAobGFzdHR5cGUgIT09IFBPU1RBRy5BX00pXG5cdFx0XHRcdHtcblx0XHRcdFx0XHRsZXQgbncgPSB0aGlzLmNyZWF0ZUZvcmVpZ25Ub2tlbih7XG5cdFx0XHRcdFx0XHR3OiB0ZXh0LnN1YnN0cihsYXN0Y3VyLCBpIC0gbGFzdGN1ciksXG5cdFx0XHRcdFx0fSwgbGFzdHR5cGUsIHtcblx0XHRcdFx0XHRcdFt0aGlzLm5hbWVdOiAxLFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdC8vbGV0IG53ID0geyB3OiB0ZXh0LnN1YnN0cihsYXN0Y3VyLCBpIC0gbGFzdGN1cikgfSBhcyBJV29yZDtcblxuXHRcdFx0XHRcdC8vaWYgKGxhc3R0eXBlICE9PSBQT1NUQUcuVU5LKSBudy5wID0gbGFzdHR5cGU7XG5cdFx0XHRcdFx0cmV0LnB1c2gobncpO1xuXHRcdFx0XHRcdGxhc3RjdXIgPSBpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxhc3R0eXBlID0gUE9TVEFHLkFfTTtcblx0XHRcdH1cblx0XHRcdGVsc2UgaWYgKChjID49IDY1ICYmIGMgPD0gOTApIHx8IChjID49IDk3ICYmIGMgPD0gMTIyKSlcblx0XHRcdHtcblx0XHRcdFx0Ly8g5a2X5q+NIGxhc3R0eXBlID0gUE9TVEFHLkFfTlhcblx0XHRcdFx0aWYgKGxhc3R0eXBlICE9PSBQT1NUQUcuQV9OWClcblx0XHRcdFx0e1xuXHRcdFx0XHRcdC8vbGV0IG53ID0geyB3OiB0ZXh0LnN1YnN0cihsYXN0Y3VyLCBpIC0gbGFzdGN1cikgfSBhcyBJV29yZDtcblxuXHRcdFx0XHRcdGxldCBudyA9IHRoaXMuY3JlYXRlUmF3VG9rZW4oe1xuXHRcdFx0XHRcdFx0dzogdGV4dC5zdWJzdHIobGFzdGN1ciwgaSAtIGxhc3RjdXIpLFxuXHRcdFx0XHRcdH0sIHtcblx0XHRcdFx0XHRcdHA6IGxhc3R0eXBlXG5cdFx0XHRcdFx0fSwge1xuXHRcdFx0XHRcdFx0W3RoaXMubmFtZV06IDIsXG5cdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHQvL2lmIChsYXN0dHlwZSAhPT0gUE9TVEFHLlVOSykgbncucCA9IGxhc3R0eXBlO1xuXHRcdFx0XHRcdHJldC5wdXNoKG53KTtcblx0XHRcdFx0XHRsYXN0Y3VyID0gaTtcblx0XHRcdFx0fVxuXHRcdFx0XHRsYXN0dHlwZSA9IFBPU1RBRy5BX05YO1xuXHRcdFx0fVxuXHRcdFx0ZWxzZVxuXHRcdFx0e1xuXHRcdFx0XHQvLyDlhbbku5Zcblx0XHRcdFx0aWYgKGxhc3R0eXBlICE9PSBQT1NUQUcuVU5LKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0bGV0IG53ID0gdGhpcy5jcmVhdGVGb3JlaWduVG9rZW4oe1xuXHRcdFx0XHRcdFx0dzogdGV4dC5zdWJzdHIobGFzdGN1ciwgaSAtIGxhc3RjdXIpLFxuXHRcdFx0XHRcdFx0cDogbGFzdHR5cGVcblx0XHRcdFx0XHR9LCB1bmRlZmluZWQsIHtcblx0XHRcdFx0XHRcdFt0aGlzLm5hbWVdOiAzLFxuXHRcdFx0XHRcdH0pO1xuXG5cdFx0XHRcdFx0cmV0LnB1c2gobncpO1xuXHRcdFx0XHRcdGxhc3RjdXIgPSBpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGxhc3R0eXBlID0gUE9TVEFHLlVOSztcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8g5Ymp5L2Z6YOo5YiGXG5cdFx0Ly9sZXQgbncgPSB7IHc6IHRleHQuc3Vic3RyKGxhc3RjdXIsIGkgLSBsYXN0Y3VyKSB9IGFzIElXb3JkO1xuXG5cdFx0bGV0IG53ID0gdGhpcy5jcmVhdGVSYXdUb2tlbjxJV29yZD4oe1xuXHRcdFx0dzogdGV4dC5zdWJzdHIobGFzdGN1ciwgaSAtIGxhc3RjdXIpLFxuXHRcdH0pO1xuXG5cdFx0aWYgKGxhc3R0eXBlICE9PSBQT1NUQUcuVU5LKSBudy5wID0gbGFzdHR5cGU7XG5cdFx0cmV0LnB1c2gobncpO1xuXG5cdFx0Ly9jb25zb2xlLnRpbWVFbmQoJ3NwbGl0Rm9yZWlnbicpO1xuXG5cdFx0Ly9kZWJ1ZyhyZXQpO1xuXHRcdHJldHVybiByZXQ7XG5cdH1cblxuXHRjcmVhdGVGb3JlaWduVG9rZW4od29yZDogSVdvcmQsIGxhc3R0eXBlPzogbnVtYmVyLCBhdHRyPzogSVdvcmREZWJ1Z0luZm8pXG5cdHtcblx0XHRsZXQgbncgPSB0aGlzLmNyZWF0ZVRva2VuPElXb3JkPih3b3JkLCB0cnVlLCBhdHRyKTtcblxuXHRcdGxldCBvdyA9IHRoaXMuX1RBQkxFW253LnddO1xuXG5cdFx0aWYgKG93KVxuXHRcdHtcblx0XHRcdGRlYnVnVG9rZW4obncsIHtcblx0XHRcdFx0X3NvdXJjZTogb3csXG5cdFx0XHR9KTtcblxuXHRcdFx0bncucCA9IG53LnAgfCBvdy5wO1xuXHRcdH1cblxuXHRcdGlmIChsYXN0dHlwZSAmJiBsYXN0dHlwZSAhPT0gdGhpcy5fUE9TVEFHLlVOSylcblx0XHR7XG5cdFx0XHRudy5wID0gbGFzdHR5cGUgfCBudy5wO1xuXHRcdH1cblxuXHRcdHJldHVybiBudztcblx0fVxufVxuXG5leHBvcnQgY29uc3QgaW5pdCA9IEZvcmVpZ25Ub2tlbml6ZXIuaW5pdC5iaW5kKEZvcmVpZ25Ub2tlbml6ZXIpIGFzIElTdWJUb2tlbml6ZXJDcmVhdGU8Rm9yZWlnblRva2VuaXplcj47XG5cbmV4cG9ydCBkZWZhdWx0IEZvcmVpZ25Ub2tlbml6ZXI7XG5cbi8vZGVidWcoc3BsaXRGb3JlaWduKCdhZDIyMue7j+a1juaguOeulzEyM+mdnicpKTtcbiJdfQ==
\No newline at end of file