UNPKG

37.3 kBJavaScriptView Raw
1'use strict';
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.init = exports.DictOptimizer = void 0;
4const mod_1 = require("../mod");
5const DIRECTIONS_REGEXP = /^[東西南北东]+$/;
6/**
7 * 词典优化模块
8 *
9 * @author 老雷<leizongmin@gmail.com>
10 */
11class DictOptimizer extends mod_1.SubSModuleOptimizer {
12 constructor() {
13 super(...arguments);
14 this.name = 'DictOptimizer';
15 }
16 _cache() {
17 super._cache();
18 this._TABLE = this.segment.getDict('TABLE');
19 this._POSTAG = this.segment.POSTAG;
20 }
21 isMergeable(w1, w2, { POSTAG, TABLE, nw, i, nw_cache, nw_cache_exists, }) {
22 let bool;
23 let m;
24 /**
25 * 原始判斷模式
26 */
27 if (w1.p == w2.p) {
28 bool = true;
29 }
30 /**
31 * 不確定沒有BUG 但原始模式已經不合需求 因為單一項目多個詞性
32 */
33 else if (m = (w1.p & w2.p)) {
34 if (1 || m & POSTAG.D_N) {
35 bool = true;
36 }
37 }
38 /**
39 * 允許例如 幾 + %
40 */
41 else if (w1.p && typeof w2.p == 'undefined') {
42 bool = true;
43 }
44 else if (w1.p & POSTAG.D_D && w2.p & POSTAG.D_V) {
45 ({
46 nw_cache,
47 nw_cache_exists,
48 } = this._getWordCache(nw, nw_cache, nw_cache_exists));
49 let mw = nw_cache;
50 if (mw && (mw.p & POSTAG.D_D || mw.p & POSTAG.D_V)) {
51 bool = true;
52 }
53 }
54 return bool
55 && this._getWordCache(nw, nw_cache, nw_cache_exists).nw_cache_exists;
56 }
57 _getWordCache(nw, nw_cache, nw_cache_exists) {
58 if (typeof nw_cache_exists === 'undefined') {
59 const TABLE = this._TABLE;
60 nw_cache = nw_cache || TABLE[nw];
61 nw_cache_exists = !!nw_cache;
62 }
63 return {
64 nw,
65 nw_cache,
66 nw_cache_exists,
67 };
68 }
69 /**
70 * 词典优化
71 *
72 * @param {array} words 单词数组
73 * @param {bool} is_not_first 是否为管理器调用的
74 * @return {array}
75 */
76 doOptimize(words, is_not_first) {
77 //debug(words);
78 if (typeof is_not_first == 'undefined') {
79 is_not_first = false;
80 }
81 // 合并相邻的能组成一个单词的两个词
82 const TABLE = this._TABLE;
83 const POSTAG = this._POSTAG;
84 const self = this;
85 let i = 0;
86 let ie = words.length - 1;
87 while (i < ie) {
88 let w1 = words[i];
89 let w2 = words[i + 1];
90 //debug(w1.w + ', ' + w2.w);
91 // ==========================================
92 let nw = w1.w + w2.w;
93 let nw_cache;
94 let nw_cache_exists;
95 /**
96 * 形容词 + 助词 = 形容词,如: 不同 + 的 = 不同的
97 */
98 if (w1.w != '了'
99 && (w1.p & POSTAG.D_A)
100 && (w2.p & POSTAG.D_U)) {
101 let p = POSTAG.D_A;
102 let f;
103 ({
104 nw_cache,
105 nw_cache_exists,
106 } = self._getWordCache(nw, nw_cache, nw_cache_exists));
107 let mw = nw_cache;
108 if (!mw || (mw.p & POSTAG.D_A)) {
109 if (mw && (mw.p & POSTAG.D_A)) {
110 p = mw.p;
111 f = mw.f;
112 }
113 else if (w1.p & POSTAG.BAD) {
114 p = POSTAG.D_A + POSTAG.BAD;
115 }
116 this.sliceToken(words, i, 2, {
117 w: nw,
118 //p: ((nw in TABLE && TABLE[nw].p & POSTAG.D_A) ? TABLE[nw].p : POSTAG.D_A),
119 p,
120 f,
121 m: [w1, w2],
122 }, undefined, {
123 [this.name]: 1,
124 });
125 ie--;
126 continue;
127 }
128 }
129 /**
130 * 形容詞 + 名詞 = 名詞
131 */
132 if ((w1.p & POSTAG.D_A)
133 && (w2.p & POSTAG.D_N)) {
134 ({
135 nw_cache,
136 nw_cache_exists,
137 } = self._getWordCache(nw, nw_cache, nw_cache_exists));
138 if (nw_cache_exists) {
139 let mw = nw_cache;
140 if (mw.p & POSTAG.D_N) {
141 this.sliceToken(words, i, 2, {
142 w: nw,
143 p: mw.p,
144 f: mw.f,
145 m: [w1, w2],
146 }, undefined, {
147 [this.name]: 7,
148 });
149 ie--;
150 continue;
151 }
152 }
153 }
154 // 能组成一个新词的(词性必须相同)
155 if (this.isMergeable(w1, w2, {
156 nw,
157 POSTAG,
158 TABLE,
159 i,
160 nw_cache,
161 nw_cache_exists,
162 }))
163 //if (w1.p == w2.p && nw in TABLE)
164 {
165 ({
166 nw_cache,
167 nw_cache_exists,
168 } = self._getWordCache(nw, nw_cache, nw_cache_exists));
169 let mw = nw_cache;
170 this.sliceToken(words, i, 2, {
171 w: nw,
172 p: mw.p,
173 f: mw.f,
174 m: [w1, w2],
175 }, undefined, {
176 [this.name]: 2,
177 });
178 ie--;
179 continue;
180 }
181 // ============================================
182 // 数词组合
183 if ((w1.p & POSTAG.A_M)) {
184 //debug(w2.w + ' ' + (w2.p & POSTAG.A_M));
185 // 百分比数字 如 10%,或者下一个词也是数词,则合并
186 if ((w2.p & POSTAG.A_M
187 && !/^第/.test(w2.w)) || w2.w == '%' || w2.w == '%') {
188 this.sliceToken(words, i, 2, {
189 w: w1.w + w2.w,
190 p: POSTAG.A_M,
191 m: [w1, w2],
192 }, undefined, {
193 [this.name]: 3,
194 });
195 ie--;
196 continue;
197 }
198 // 数词 + 量词,合并。如: 100个
199 if ((w2.p & POSTAG.A_Q)) {
200 // 数量词
201 let p = POSTAG.D_MQ;
202 let nw = w1.w + w2.w;
203 ({
204 nw_cache,
205 nw_cache_exists,
206 } = self._getWordCache(nw, nw_cache, nw_cache_exists));
207 if (nw_cache) {
208 p = nw_cache.p | POSTAG.D_MQ;
209 }
210 else {
211 if (w2.p & POSTAG.D_T) {
212 p = p | POSTAG.D_T;
213 }
214 if (w2.p & POSTAG.D_N) {
215 p = p | POSTAG.D_N;
216 }
217 if (w2.p & POSTAG.D_V) {
218 p = p | POSTAG.D_V;
219 }
220 }
221 this.sliceToken(words, i, 2, {
222 w: nw,
223 p,
224 m: [w1, w2],
225 }, undefined, {
226 [this.name]: 4,
227 });
228 ie--;
229 continue;
230 }
231 // 带小数点的数字 ,如 “3 . 14”,或者 “十五点三”
232 // 数词 + "分之" + 数词,如“五十分之一”
233 let w3 = words[i + 2];
234 if (w3 && (w3.p & POSTAG.A_M)) {
235 if (w2.w == '.'
236 || w2.w == '点'
237 || w2.w == '點'
238 || w2.w == '分之') {
239 this.sliceToken(words, i, 3, {
240 w: w1.w + w2.w + w3.w,
241 p: POSTAG.A_M,
242 m: [w1, w2, w3],
243 }, undefined, {
244 [this.name]: 5,
245 });
246 ie -= 2;
247 continue;
248 }
249 /**
250 * 支援 `最多容納59,000個人,或5.9萬人,再多就不行了.這是環評的結論.`
251 */
252 if (w2.w == ',') {
253 let _r1 = /^[\d0-9]+$/;
254 let _r2 = /^(?:(?:[\d0-9]+)?(?:\.[\d0-9]+)|(?:[\d0-9]+))$/;
255 if (_r1.test(w1.w) && _r2.test(w3.w)) {
256 this.sliceToken(words, i, 3, {
257 w: w1.w + w2.w + w3.w,
258 p: POSTAG.A_M,
259 m: [w1, w2, w3],
260 }, undefined, {
261 [this.name]: 6,
262 });
263 ie -= 2;
264 continue;
265 }
266 }
267 }
268 }
269 // 修正 “十五点五八”问题
270 if ((w1.p & POSTAG.D_MQ) && ['點', '点'].includes(w1.w.substr(-1)) && w2.p & POSTAG.A_M) {
271 //debug(w1, w2);
272 let i2 = 2;
273 let w4w = '';
274 for (let j = i + i2; j < ie; j++) {
275 let w3 = words[j];
276 if ((w3.p & POSTAG.A_M) > 0) {
277 w4w += w3.w;
278 i2++;
279 }
280 else {
281 break;
282 }
283 }
284 this.sliceToken(words, i, i2, {
285 w: w1.w + w2.w + w4w,
286 p: POSTAG.D_MQ,
287 m: [w1, w2, w4w],
288 }, undefined, {
289 [this.name]: 6,
290 });
291 ie -= i2 - 1;
292 continue;
293 }
294 /**
295 * 合併 東南西北
296 */
297 if (DIRECTIONS_REGEXP.test(w1.w)) {
298 if (DIRECTIONS_REGEXP.test(w2.w)) {
299 ({
300 nw_cache,
301 nw_cache_exists,
302 } = self._getWordCache(nw, nw_cache, nw_cache_exists));
303 let mw = this.createToken({
304 p: POSTAG.D_F,
305 ...nw_cache,
306 w: nw,
307 m: [w1, w2],
308 });
309 mw.p = mw.p | POSTAG.D_F;
310 this.sliceToken(words, i, 2, mw, true, {
311 [this.name]: 8,
312 });
313 ie--;
314 continue;
315 }
316 }
317 // 移到下一个词
318 i++;
319 }
320 // 针对组合数字后无法识别新组合的数字问题,需要重新扫描一次
321 return is_not_first === true ? words : this.doOptimize(words, true);
322 }
323}
324exports.DictOptimizer = DictOptimizer;
325exports.init = DictOptimizer.init.bind(DictOptimizer);
326exports.default = DictOptimizer;
327//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGljdE9wdGltaXplci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIkRpY3RPcHRpbWl6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWSxDQUFDOzs7QUFFYixnQ0FBOEU7QUFROUUsTUFBTSxpQkFBaUIsR0FBRyxZQUFZLENBQUM7QUFFdkM7Ozs7R0FJRztBQUNILE1BQWEsYUFBYyxTQUFRLHlCQUFtQjtJQUF0RDs7UUFLQyxTQUFJLEdBQUcsZUFBZSxDQUFDO0lBcVp4QixDQUFDO0lBblpBLE1BQU07UUFFTCxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDZixJQUFJLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzVDLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7SUFDcEMsQ0FBQztJQUVELFdBQVcsQ0FBQyxFQUFTLEVBQUUsRUFBUyxFQUFFLEVBQ2pDLE1BQU0sRUFDTixLQUFLLEVBQ0wsRUFBRSxFQUNGLENBQUMsRUFDRCxRQUFRLEVBQ1IsZUFBZSxHQVFmO1FBRUEsSUFBSSxJQUFhLENBQUM7UUFDbEIsSUFBSSxDQUFTLENBQUM7UUFFZDs7V0FFRztRQUNILElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUNoQjtZQUNDLElBQUksR0FBRyxJQUFJLENBQUM7U0FDWjtRQUNEOztXQUVHO2FBQ0UsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFDMUI7WUFDQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDLEdBQUcsRUFDdkI7Z0JBQ0MsSUFBSSxHQUFHLElBQUksQ0FBQzthQUNaO1NBQ0Q7UUFDRDs7V0FFRzthQUNFLElBQUksRUFBRSxDQUFDLENBQUMsSUFBSSxPQUFPLEVBQUUsQ0FBQyxDQUFDLElB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LENBQXVDLENBQUM7QUFFakcsa0JBQWUsYUFBYSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiJ3VzZSBzdHJpY3QnO1xuXG5pbXBvcnQgeyBTdWJTTW9kdWxlLCBTdWJTTW9kdWxlT3B0aW1pemVyLCBJU3ViT3B0aW1pemVyQ3JlYXRlIH0gZnJvbSAnLi4vbW9kJztcbmltcG9ydCB7IFNlZ21lbnQsIElXb3JkLCBJRElDVCB9IGZyb20gJy4uL1NlZ21lbnQnO1xuLy8gQHRzLWlnbm9yZVxuaW1wb3J0IHsgVVN0cmluZyB9IGZyb20gJ3VuaS1zdHJpbmcnO1xuaW1wb3J0IElQT1NUQUcgZnJvbSAnLi4vUE9TVEFHJztcbmltcG9ydCB7IGRlYnVnLCBJV29yZERlYnVnIH0gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQgeyB6aFJlZ0V4cCB9IGZyb20gJ3JlZ2V4cC1jamsnO1xuXG5jb25zdCBESVJFQ1RJT05TX1JFR0VYUCA9IC9eW+adseilv+WNl+WMl+S4nF0rJC87XG5cbi8qKlxuICog6K+N5YW45LyY5YyW5qih5Z2XXG4gKlxuICogQGF1dGhvciDogIHpm7c8bGVpem9uZ21pbkBnbWFpbC5jb20+XG4gKi9cbmV4cG9ydCBjbGFzcyBEaWN0T3B0aW1pemVyIGV4dGVuZHMgU3ViU01vZHVsZU9wdGltaXplclxue1xuXG5cdHByb3RlY3RlZCBfVEFCTEU6IElESUNUPElXb3JkPjtcblxuXHRuYW1lID0gJ0RpY3RPcHRpbWl6ZXInO1xuXG5cdF9jYWNoZSgpXG5cdHtcblx0XHRzdXBlci5fY2FjaGUoKTtcblx0XHR0aGlzLl9UQUJMRSA9IHRoaXMuc2VnbWVudC5nZXREaWN0KCdUQUJMRScpO1xuXHRcdHRoaXMuX1BPU1RBRyA9IHRoaXMuc2VnbWVudC5QT1NUQUc7XG5cdH1cblxuXHRpc01lcmdlYWJsZSh3MTogSVdvcmQsIHcyOiBJV29yZCwge1xuXHRcdFBPU1RBRyxcblx0XHRUQUJMRSxcblx0XHRudyxcblx0XHRpLFxuXHRcdG53X2NhY2hlLFxuXHRcdG53X2NhY2hlX2V4aXN0cyxcblx0fToge1xuXHRcdFBPU1RBRzogdHlwZW9mIElQT1NUQUcsXG5cdFx0VEFCTEU6IElESUNULFxuXHRcdG53OiBzdHJpbmcsXG5cdFx0aTogbnVtYmVyLFxuXHRcdG53X2NhY2hlOiBJV29yZCxcblx0XHRud19jYWNoZV9leGlzdHM6IGJvb2xlYW4sXG5cdH0pOiBib29sZWFuXG5cdHtcblx0XHRsZXQgYm9vbDogYm9vbGVhbjtcblx0XHRsZXQgbTogbnVtYmVyO1xuXG5cdFx0LyoqXG5cdFx0ICog5Y6f5aeL5Yik5pa35qih5byPXG5cdFx0ICovXG5cdFx0aWYgKHcxLnAgPT0gdzIucClcblx0XHR7XG5cdFx0XHRib29sID0gdHJ1ZTtcblx0XHR9XG5cdFx0LyoqXG5cdFx0ICog5LiN56K65a6a5rKS5pyJQlVHIOS9huWOn+Wni+aooeW8j+W3sue2k+S4jeWQiOmcgOaxgiDlm6Dngrrllq7kuIDpoIXnm67lpJrlgIvoqZ7mgKdcblx0XHQgKi9cblx0XHRlbHNlIGlmIChtID0gKHcxLnAgJiB3Mi5wKSlcblx0XHR7XG5cdFx0XHRpZiAoMSB8fCBtICYgUE9TVEFHLkRfTilcblx0XHRcdHtcblx0XHRcdFx0Ym9vbCA9IHRydWU7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdC8qKlxuXHRcdCAqIOWFgeioseS+i+WmgiDlub4gKyDvvIVcblx0XHQgKi9cblx0XHRlbHNlIGlmICh3MS5wICYmIHR5cGVvZiB3Mi5wID09ICd1bmRlZmluZWQnKVxuXHRcdHtcblx0XHRcdGJvb2wgPSB0cnVlO1xuXHRcdH1cblx0XHRlbHNlIGlmICh3MS5wICYgUE9TVEFHLkRfRCAmJiB3Mi5wICYgUE9TVEFHLkRfVilcblx0XHR7XG5cdFx0XHQoe1xuXHRcdFx0XHRud19jYWNoZSxcblx0XHRcdFx0bndfY2FjaGVfZXhpc3RzLFxuXHRcdFx0fSA9IHRoaXMuX2dldFdvcmRDYWNoZShudywgbndfY2FjaGUsIG53X2NhY2hlX2V4aXN0cykpO1xuXG5cdFx0XHRsZXQgbXcgPSBud19jYWNoZTtcblxuXHRcdFx0aWYgKG13ICYmIChtdy5wICYgUE9TVEFHLkRfRCB8fCBtdy5wICYgUE9TVEFHLkRfVikpXG5cdFx0XHR7XG5cdFx0XHRcdGJvb2wgPSB0cnVlO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBib29sXG5cdFx0XHQmJiB0aGlzLl9nZXRXb3JkQ2FjaGUobncsIG53X2NhY2hlLCBud19jYWNoZV9leGlzdHMpLm53X2NhY2hlX2V4aXN0cztcblx0fVxuXG5cdF9nZXRXb3JkQ2FjaGUobnc6IHN0cmluZywgbndfY2FjaGU6IElXb3JkLCBud19jYWNoZV9leGlzdHM6IGJvb2xlYW4pXG5cdHtcblx0XHRpZiAodHlwZW9mIG53X2NhY2hlX2V4aXN0cyA9PT0gJ3VuZGVmaW5lZCcpXG5cdFx0e1xuXHRcdFx0Y29uc3QgVEFCTEUgPSB0aGlzLl9UQUJMRTtcblxuXHRcdFx0bndfY2FjaGUgPSBud19jYWNoZSB8fCBUQUJMRVtud107XG5cdFx0XHRud19jYWNoZV9leGlzdHMgPSAhIW53X2NhY2hlO1xuXHRcdH1cblxuXHRcdHJldHVybiB7XG5cdFx0XHRudyxcblx0XHRcdG53X2NhY2hlLFxuXHRcdFx0bndfY2FjaGVfZXhpc3RzLFxuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiDor43lhbjkvJjljJZcblx0ICpcblx0ICogQHBhcmFtIHthcnJheX0gd29yZHMg5Y2V6K+N5pWw57uEXG5cdCAqIEBwYXJhbSB7Ym9vbH0gaXNfbm90X2ZpcnN0IOaYr+WQpuS4uueuoeeQhuWZqOiwg+eUqOeahFxuXHQgKiBAcmV0dXJuIHthcnJheX1cblx0ICovXG5cdGRvT3B0aW1pemUod29yZHM6IElXb3JkW10sIGlzX25vdF9maXJzdDogYm9vbGVhbik6IElXb3JkW11cblx0e1xuXHRcdC8vZGVidWcod29yZHMpO1xuXHRcdGlmICh0eXBlb2YgaXNfbm90X2ZpcnN0ID09ICd1bmRlZmluZWQnKVxuXHRcdHtcblx0XHRcdGlzX25vdF9maXJzdCA9IGZhbHNlO1xuXHRcdH1cblx0XHQvLyDlkIjlubbnm7jpgrvnmoTog73nu4TmiJDkuIDkuKrljZXor43nmoTkuKTkuKror41cblx0XHRjb25zdCBUQUJMRSA9IHRoaXMuX1RBQkxFO1xuXHRcdGNvbnN0IFBPU1RBRyA9IHRoaXMuX1BPU1RBRztcblx0XHRjb25zdCBzZWxmID0gdGhpcztcblxuXHRcdGxldCBpID0gMDtcblx0XHRsZXQgaWUgPSB3b3Jkcy5sZW5ndGggLSAxO1xuXHRcdHdoaWxlIChpIDwgaWUpXG5cdFx0e1xuXHRcdFx0bGV0IHcxID0gd29yZHNbaV07XG5cdFx0XHRsZXQgdzIgPSB3b3Jkc1tpICsgMV07XG5cdFx0XHQvL2RlYnVnKHcxLncgKyAnLCAnICsgdzIudyk7XG5cblx0XHRcdC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXHRcdFx0bGV0IG53OiBzdHJpbmcgPSB3MS53ICsgdzIudztcblxuXHRcdFx0bGV0IG53X2NhY2hlOiBJV29yZDtcblx0XHRcdGxldCBud19jYWNoZV9leGlzdHM6IGJvb2xlYW47XG5cblx0XHRcdC8qKlxuXHRcdFx0ICog5b2i5a656K+NICsg5Yqp6K+NID0g5b2i5a656K+N77yM5aaC77yaIOS4jeWQjCArIOeahCA9IOS4jeWQjOeahFxuXHRcdFx0ICovXG5cdFx0XHRpZiAodzEudyAhPSAn5LqGJ1xuXHRcdFx0XHQmJiAodzEucCAmIFBPU1RBRy5EX0EpXG5cdFx0XHRcdCYmICh3Mi5wICYgUE9TVEFHLkRfVSlcblx0XHRcdClcblx0XHRcdHtcblx0XHRcdFx0bGV0IHAgPSBQT1NUQUcuRF9BO1xuXHRcdFx0XHRsZXQgZjogbnVtYmVyO1xuXG5cdFx0XHRcdCh7XG5cdFx0XHRcdFx0bndfY2FjaGUsXG5cdFx0XHRcdFx0bndfY2FjaGVfZXhpc3RzLFxuXHRcdFx0XHR9ID0gc2VsZi5fZ2V0V29yZENhY2hlKG53LCBud19jYWNoZSwgbndfY2FjaGVfZXhpc3RzKSk7XG5cblx0XHRcdFx0bGV0IG13ID0gbndfY2FjaGU7XG5cblx0XHRcdFx0aWYgKCFtdyB8fCAobXcucCAmIFBPU1RBRy5EX0EpKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0aWYgKG13ICYmIChtdy5wICYgUE9TVEFHLkRfQSkpXG5cdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0cCA9IG13LnA7XG5cdFx0XHRcdFx0XHRmID0gbXcuZjtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZSBpZiAodzEucCAmIFBPU1RBRy5CQUQpXG5cdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0cCA9IFBPU1RBRy5EX0EgKyBQT1NUQUcuQkFEO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdHRoaXMuc2xpY2VUb2tlbih3b3JkcywgaSwgMiwge1xuXHRcdFx0XHRcdFx0dzogbncsXG5cdFx0XHRcdFx0XHQvL3A6ICgobncgaW4gVEFCTEUgJiYgVEFCTEVbbnddLnAgJiBQT1NUQUcuRF9BKSA/IFRBQkxFW253XS5wIDogUE9TVEFHLkRfQSksXG5cdFx0XHRcdFx0XHRwLFxuXHRcdFx0XHRcdFx0Zixcblx0XHRcdFx0XHRcdG06IFt3MSwgdzJdLFxuXHRcdFx0XHRcdH0sIHVuZGVmaW5lZCwge1xuXHRcdFx0XHRcdFx0W3RoaXMubmFtZV06IDEsXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0aWUtLTtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvKipcblx0XHRcdCAqIOW9ouWuueipniArIOWQjeipniA9IOWQjeipnlxuXHRcdFx0ICovXG5cdFx0XHRpZiAoKHcxLnAgJiBQT1NUQUcuRF9BKVxuXHRcdFx0XHQmJiAodzIucCAmIFBPU1RBRy5EX04pXG5cdFx0XHQpXG5cdFx0XHR7XG5cdFx0XHRcdCh7XG5cdFx0XHRcdFx0bndfY2FjaGUsXG5cdFx0XHRcdFx0bndfY2FjaGVfZXhpc3RzLFxuXHRcdFx0XHR9ID0gc2VsZi5fZ2V0V29yZENhY2hlKG53LCBud19jYWNoZSwgbndfY2FjaGVfZXhpc3RzKSk7XG5cblx0XHRcdFx0aWYgKG53X2NhY2hlX2V4aXN0cylcblx0XHRcdFx0e1xuXHRcdFx0XHRcdGxldCBtdyA9IG53X2NhY2hlO1xuXG5cdFx0XHRcdFx0aWYgKG13LnAgJiBQT1NUQUcuRF9OKVxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdHRoaXMuc2xpY2VUb2tlbih3b3JkcywgaSwgMiwge1xuXHRcdFx0XHRcdFx0XHR3OiBudyxcblx0XHRcdFx0XHRcdFx0cDogbXcucCxcblx0XHRcdFx0XHRcdFx0ZjogbXcuZixcblx0XHRcdFx0XHRcdFx0bTogW3cxLCB3Ml0sXG5cdFx0XHRcdFx0XHR9LCB1bmRlZmluZWQsIHtcblx0XHRcdFx0XHRcdFx0W3RoaXMubmFtZV06IDcsXG5cdFx0XHRcdFx0XHR9KTtcblx0XHRcdFx0XHRcdGllLS07XG5cdFx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8g6IO957uE5oiQ5LiA5Liq5paw6K+N55qEKOivjeaAp+W/hemhu+ebuOWQjClcblxuXHRcdFx0aWYgKHRoaXMuaXNNZXJnZWFibGUodzEsIHcyLCB7XG5cdFx0XHRcdG53LFxuXHRcdFx0XHRQT1NUQUcsXG5cdFx0XHRcdFRBQkxFLFxuXHRcdFx0XHRpLFxuXHRcdFx0XHRud19jYWNoZSxcblx0XHRcdFx0bndfY2FjaGVfZXhpc3RzLFxuXHRcdFx0fSkpXG5cdFx0XHQvL2lmICh3MS5wID09IHcyLnAgJiYgbncgaW4gVEFCTEUpXG5cdFx0XHR7XG5cdFx0XHRcdCh7XG5cdFx0XHRcdFx0bndfY2FjaGUsXG5cdFx0XHRcdFx0bndfY2FjaGVfZXhpc3RzLFxuXHRcdFx0XHR9ID0gc2VsZi5fZ2V0V29yZENhY2hlKG53LCBud19jYWNoZSwgbndfY2FjaGVfZXhpc3RzKSk7XG5cblx0XHRcdFx0bGV0IG13ID0gbndfY2FjaGU7XG5cblx0XHRcdFx0dGhpcy5zbGljZVRva2VuKHdvcmRzLCBpLCAyLCB7XG5cdFx0XHRcdFx0dzogbncsXG5cdFx0XHRcdFx0cDogbXcucCxcblx0XHRcdFx0XHRmOiBtdy5mLFxuXHRcdFx0XHRcdG06IFt3MSwgdzJdLFxuXHRcdFx0XHR9LCB1bmRlZmluZWQsIHtcblx0XHRcdFx0XHRbdGhpcy5uYW1lXTogMixcblx0XHRcdFx0fSk7XG5cdFx0XHRcdGllLS07XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXHRcdFx0Ly8g5pWw6K+N57uE5ZCIXG5cdFx0XHRpZiAoKHcxLnAgJiBQT1NUQUcuQV9NKSlcblx0XHRcdHtcblx0XHRcdFx0Ly9kZWJ1Zyh3Mi53ICsgJyAnICsgKHcyLnAgJiBQT1NUQUcuQV9NKSk7XG5cdFx0XHRcdC8vIOeZvuWIhuavlOaVsOWtlyDlpoIgMTAl77yM5oiW6ICF5LiL5LiA5Liq6K+N5Lmf5piv5pWw6K+N77yM5YiZ5ZCI5bm2XG5cdFx0XHRcdGlmICgoXG5cdFx0XHRcdFx0dzIucCAmIFBPU1RBRy5BX01cblx0XHRcdFx0XHQmJiAhL17nrKwvLnRlc3QodzIudylcblx0XHRcdFx0KSB8fCB3Mi53ID09ICclJyB8fCB3Mi53ID09ICfvvIUnKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0dGhpcy5zbGljZVRva2VuKHdvcmRzLCBpLCAyLCB7XG5cdFx0XHRcdFx0XHR3OiB3MS53ICsgdzIudyxcblx0XHRcdFx0XHRcdHA6IFBPU1RBRy5BX00sXG5cdFx0XHRcdFx0XHRtOiBbdzEsIHcyXSxcblx0XHRcdFx0XHR9LCB1bmRlZmluZWQsIHtcblx0XHRcdFx0XHRcdFt0aGlzLm5hbWVdOiAzLFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdGllLS07XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0Ly8g5pWw6K+NICsg6YeP6K+N77yM5ZCI5bm244CC5aaC77yaIDEwMOS4qlxuXHRcdFx0XHRpZiAoKHcyLnAgJiBQT1NUQUcuQV9RKSlcblx0XHRcdFx0e1xuXHRcdFx0XHRcdC8vIOaVsOmHj+ivjVxuXHRcdFx0XHRcdGxldCBwID0gUE9TVEFHLkRfTVE7XG5cdFx0XHRcdFx0bGV0IG53OiBzdHJpbmcgPSB3MS53ICsgdzIudztcblxuXHRcdFx0XHRcdCh7XG5cdFx0XHRcdFx0XHRud19jYWNoZSxcblx0XHRcdFx0XHRcdG53X2NhY2hlX2V4aXN0cyxcblx0XHRcdFx0XHR9ID0gc2VsZi5fZ2V0V29yZENhY2hlKG53LCBud19jYWNoZSwgbndfY2FjaGVfZXhpc3RzKSk7XG5cblx0XHRcdFx0XHRpZiAobndfY2FjaGUpXG5cdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0cCA9IG53X2NhY2hlLnAgfCBQT1NUQUcuRF9NUTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZVxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdGlmICh3Mi5wICYgUE9TVEFHLkRfVClcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0cCA9IHAgfCBQT1NUQUcuRF9UO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKHcyLnAgJiBQT1NUQUcuRF9OKVxuXHRcdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0XHRwID0gcCB8IFBPU1RBRy5EX047XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRpZiAodzIucCAmIFBPU1RBRy5EX1YpXG5cdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdHAgPSBwIHwgUE9TVEFHLkRfVjtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHR0aGlzLnNsaWNlVG9rZW4od29yZHMsIGksIDIsIHtcblx0XHRcdFx0XHRcdHc6IG53LFxuXHRcdFx0XHRcdFx0cCxcblx0XHRcdFx0XHRcdG06IFt3MSwgdzJdLFxuXHRcdFx0XHRcdH0sIHVuZGVmaW5lZCwge1xuXHRcdFx0XHRcdFx0W3RoaXMubmFtZV06IDQsXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0aWUtLTtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXHRcdFx0XHQvLyDluKblsI/mlbDngrnnmoTmlbDlrZcg77yM5aaCIOKAnDMgLiAxNOKAne+8jOaIluiAhSDigJzljYHkupTngrnkuInigJ1cblx0XHRcdFx0Ly8g5pWw6K+NICsgXCLliIbkuYtcIiArIOaVsOivje+8jOWmguKAnOS6lOWNgeWIhuS5i+S4gOKAnVxuXHRcdFx0XHRsZXQgdzMgPSB3b3Jkc1tpICsgMl07XG5cdFx0XHRcdGlmICh3MyAmJiAodzMucCAmIFBPU1RBRy5BX00pKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0aWYgKHcyLncgPT0gJy4nXG5cdFx0XHRcdFx0XHR8fCB3Mi53ID09ICfngrknXG5cdFx0XHRcdFx0XHR8fCB3Mi53ID09ICfpu54nXG5cdFx0XHRcdFx0XHR8fCB3Mi53ID09ICfliIbkuYsnXG5cdFx0XHRcdFx0KVxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdHRoaXMuc2xpY2VUb2tlbih3b3JkcywgaSwgMywge1xuXHRcdFx0XHRcdFx0XHR3OiB3MS53ICsgdzIudyArIHczLncsXG5cdFx0XHRcdFx0XHRcdHA6IFBPU1RBRy5BX00sXG5cdFx0XHRcdFx0XHRcdG06IFt3MSwgdzIsIHczXSxcblx0XHRcdFx0XHRcdH0sIHVuZGVmaW5lZCwge1xuXHRcdFx0XHRcdFx0XHRbdGhpcy5uYW1lXTogNSxcblx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0aWUgLT0gMjtcblx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8qKlxuXHRcdFx0XHRcdCAqIOaUr+aPtCBg5pyA5aSa5a6557SNNTksMDAw5YCL5Lq6LOaIljUuOeiQrOS6uizlho3lpJrlsLHkuI3ooYzkuoYu6YCZ5piv55Kw6KmV55qE57WQ6KuWLmBcblx0XHRcdFx0XHQgKi9cblx0XHRcdFx0XHRpZiAodzIudyA9PSAnLCcpXG5cdFx0XHRcdFx0e1xuXHRcdFx0XHRcdFx0bGV0IF9yMSA9IC9eW1xcZO+8kC3vvJldKyQvO1xuXHRcdFx0XHRcdFx0bGV0IF9yMiA9IC9eKD86KD86W1xcZO+8kC3vvJldKyk/KD86XFwuW1xcZO+8kC3vvJldKyl8KD86W1xcZO+8kC3vvJldKykpJC87XG5cblx0XHRcdFx0XHRcdGlmIChfcjEudGVzdCh3MS53KSAmJiBfcjIudGVzdCh3My53KSlcblx0XHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdFx0dGhpcy5zbGljZVRva2VuKHdvcmRzLCBpLCAzLCB7XG5cdFx0XHRcdFx0XHRcdFx0dzogdzEudyArIHcyLncgKyB3My53LFxuXHRcdFx0XHRcdFx0XHRcdHA6IFBPU1RBRy5BX00sXG5cdFx0XHRcdFx0XHRcdFx0bTogW3cxLCB3MiwgdzNdLFxuXHRcdFx0XHRcdFx0XHR9LCB1bmRlZmluZWQsIHtcblx0XHRcdFx0XHRcdFx0XHRbdGhpcy5uYW1lXTogNixcblx0XHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRcdGllIC09IDI7XG5cdFx0XHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyDkv67mraMg4oCc5Y2B5LqU54K55LqU5YWr4oCd6Zeu6aKYXG5cdFx0XHRpZiAoKHcxLnAgJiBQT1NUQUcuRF9NUSkgJiYgWyfpu54nLCAn54K5J10uaW5jbHVkZXModzEudy5zdWJzdHIoLTEpKSAmJiB3Mi5wICYgUE9TVEFHLkFfTSlcblx0XHRcdHtcblx0XHRcdFx0Ly9kZWJ1Zyh3MSwgdzIpO1xuXHRcdFx0XHRsZXQgaTIgPSAyO1xuXHRcdFx0XHRsZXQgdzR3ID0gJyc7XG5cdFx0XHRcdGZvciAobGV0IGogPSBpICsgaTI7IGogPCBpZTsgaisrKVxuXHRcdFx0XHR7XG5cdFx0XHRcdFx0bGV0IHczID0gd29yZHNbal07XG5cdFx0XHRcdFx0aWYgKCh3My5wICYgUE9TVEFHLkFfTSkgPiAwKVxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdHc0dyArPSB3My53O1xuXHRcdFx0XHRcdFx0aTIrKztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0ZWxzZVxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLnNsaWNlVG9rZW4od29yZHMsIGksIGkyLCB7XG5cdFx0XHRcdFx0dzogdzEudyArIHcyLncgKyB3NHcsXG5cdFx0XHRcdFx0cDogUE9TVEFHLkRfTVEsIC8vIOaVsOmHj+ivjVxuXHRcdFx0XHRcdG06IFt3MSwgdzIsIHc0d10sXG5cdFx0XHRcdH0sIHVuZGVmaW5lZCwge1xuXHRcdFx0XHRcdFt0aGlzLm5hbWVdOiA2LFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0aWUgLT0gaTIgLSAxO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0LyoqXG5cdFx0XHQgKiDlkIjkvbUg5p2x5Y2X6KW/5YyXXG5cdFx0XHQgKi9cblx0XHRcdGlmIChESVJFQ1RJT05TX1JFR0VYUC50ZXN0KHcxLncpKVxuXHRcdFx0e1xuXHRcdFx0XHRpZiAoRElSRUNUSU9OU19SRUdFWFAudGVzdCh3Mi53KSlcblx0XHRcdFx0e1xuXHRcdFx0XHRcdCh7XG5cdFx0XHRcdFx0XHRud19jYWNoZSxcblx0XHRcdFx0XHRcdG53X2NhY2hlX2V4aXN0cyxcblx0XHRcdFx0XHR9ID0gc2VsZi5fZ2V0V29yZENhY2hlKG53LCBud19jYWNoZSwgbndfY2FjaGVfZXhpc3RzKSk7XG5cblx0XHRcdFx0XHRsZXQgbXc6IElXb3JkRGVidWcgPSB0aGlzLmNyZWF0ZVRva2VuKHtcblx0XHRcdFx0XHRcdHA6IFBPU1RBRy5EX0YsXG5cdFx0XHRcdFx0XHQuLi5ud19jYWNoZSxcblx0XHRcdFx0XHRcdHc6IG53LFxuXHRcdFx0XHRcdFx0bTogW3cxLCB3Ml0sXG5cdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHRtdy5wID0gbXcucCB8IFBPU1RBRy5EX0Y7XG5cblx0XHRcdFx0XHR0aGlzLnNsaWNlVG9rZW4od29yZHMsIGksIDIsIG13LCB0cnVlLCB7XG5cdFx0XHRcdFx0XHRbdGhpcy5uYW1lXTogOCxcblx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHRcdGllLS07XG5cdFx0XHRcdFx0Y29udGludWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXHRcdFx0Ly8g56e75Yiw5LiL5LiA5Liq6K+NXG5cdFx0XHRpKys7XG5cdFx0fVxuXG5cdFx0Ly8g6ZKI5a+557uE5ZCI5pWw5a2X5ZCO5peg5rOV6K+G5Yir5paw57uE5ZCI55qE5pWw5a2X6Zeu6aKY77yM6ZyA6KaB6YeN5paw5omr5o+P5LiA5qyhXG5cdFx0cmV0dXJuIGlzX25vdF9maXJzdCA9PT0gdHJ1ZSA/IHdvcmRzIDogdGhpcy5kb09wdGltaXplKHdvcmRzLCB0cnVlKTtcblx0fVxuXG59XG5cbmV4cG9ydCBjb25zdCBpbml0ID0gRGljdE9wdGltaXplci5pbml0LmJpbmQoRGljdE9wdGltaXplcikgYXMgSVN1Yk9wdGltaXplckNyZWF0ZTxEaWN0T3B0aW1pemVyPjtcblxuZXhwb3J0IGRlZmF1bHQgRGljdE9wdGltaXplcjtcbiJdfQ==
\No newline at end of file