1 | ;
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.init = exports.ForeignTokenizer = void 0;
|
4 | /**
|
5 | * 外文字符、数字识别模块
|
6 | *
|
7 | * @author 老雷<leizongmin@gmail.com>
|
8 | */
|
9 | const mod_1 = require("../mod");
|
10 | const debug_1 = require("../util/debug");
|
11 | class 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 | }
|
262 | exports.ForeignTokenizer = ForeignTokenizer;
|
263 | exports.init = ForeignTokenizer.init.bind(ForeignTokenizer);
|
264 | exports.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 |