├── .babelrc
├── .gitignore
├── .npmignore
├── LICENSE
├── README.md
├── browser
├── moha.js
└── moha.min.js
├── es5
├── browser.js
├── index.js
├── modules
│ └── pangu.js
├── stores
│ └── exps-dict.js
├── things
│ ├── big-news.js
│ ├── elder.js
│ └── life-exp.js
└── utils
│ ├── extend.js
│ └── upper-case-first.js
├── gulpfile.babel.js
├── package.json
├── src
└── scripts
│ ├── browser.js
│ ├── index.js
│ ├── modules
│ └── pangu.js
│ ├── stores
│ └── exps-dict.js
│ ├── things
│ ├── big-news.js
│ ├── elder.js
│ └── life-exp.js
│ └── utils
│ ├── extend.js
│ └── upper-case-first.js
└── test
└── index.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015"],
3 | "plugins": [
4 | "add-module-exports"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.log
2 | node_modules
3 |
4 | gh-pages
5 | .publish
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | /test
2 | /src/gh-pages
3 |
4 | .babelrc
5 |
6 | gulpfile.babel.js
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 IFELog
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## MoHa: First mo and then hahhhhhhhhhh [WIP]
2 |
3 |
4 |
5 | > `风声雨声读书声,谈笑风生`
6 | > `The sound of Wind, Rain and Reading, just talk and laugh`
7 | > `家事国事天下事,三件小事`
8 | > `The affairs of Family, Country and World, just 3 little things`
9 |
10 | ## Installtion
11 | ```
12 | npm i moha --save
13 | ```
14 |
15 | ## Features & Usage
16 |
17 | ### 1. Improving Life Experiences (Converter)
18 | ``` javascript
19 | import {lifeExp} from 'moha'
20 |
21 | let talks = '我是最好的。Great!'
22 | let exps = lifeExp(talks)
23 |
24 | console.log(exps) // Echo: 我是坠吼滴。Excited!
25 | ```
26 | > Here is the [Exps Dict](https://github.com/IFELog/MoHa/blob/master/src/scripts/stores/exps-dict.js) which would make you say `Wow, MoHa is excited!`.
27 |
28 | ### 2. Making Big News with HK Journalists (Page Translator)
29 | ``` javascript
30 | import {bigNews} from 'moha'
31 |
32 | bigNews() // Current page will be halangify
33 | ```
34 | ### 3. Talking with the Elder (Generator)
35 | - Todo: Imitate the elder and create an elder (Generator).
36 |
37 | ## How to Contribute?
38 | **The first and the most important thing** is to create a puppet account on GitHub to keep yourself safe in the real world. When someone knocks on your door and says "Open the door, check the water meter!", please don't trust the guy and directly reply "Water meter is outside the door!".
39 |
40 | ## Dependencies
41 | - [pangu.js](https://github.com/vinta/pangu.js) - 為什麼你們就是不能加個空格呢?
42 |
43 | ## References
44 | - [蛤蛤体生成器](http://dkwingsmt.github.io/haha/)
45 | - [把长者语言写进电脑](https://github.com/xiaq/halang/issues/1)
46 | - [恶俗古风自动生成器](http://www.jianshu.com/p/f893291674ca)
47 |
48 | ## License
49 | This work is licensed under the MIT license.
50 |
--------------------------------------------------------------------------------
/browser/moha.js:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 跟 Go 版差了一個 '
68 | // quote_cjk >> 跟 Go 版差了一個 '
69 | // fix_quote
70 | // fix_single_quote
71 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(["])/g, '$1 $2');
72 | newText = newText.replace(/(["])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2');
73 | newText = newText.replace(/(["'\(\[\{<\u201c]+)(\s*)(.+?)(\s*)(["'\)\]\}>\u201d]+)/g, '$1$3$5');
74 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])( )(')([A-Za-z])/g, '$1$3$4');
75 |
76 | // cjk_hash
77 | // hash_cjk
78 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(#(\S+))/g, '$1 $2');
79 | newText = newText.replace(/((\S+)#)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $3');
80 |
81 | // cjk_operator_ans
82 | // ans_operator_cjk
83 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\+\-\*\/=&\\|<>])([A-Za-z0-9])/g, '$1 $2 $3');
84 | newText = newText.replace(/([A-Za-z0-9])([\+\-\*\/=&\\|<>])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2 $3');
85 |
86 | // cjk_bracket_cjk
87 | // cjk_bracket
88 | // bracket_cjk
89 | // fix_bracket
90 | var oldText = newText;
91 | var tmpText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c]+(.*?)[\)\]\}>\u201d]+)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2 $4');
92 | newText = tmpText;
93 | if (oldText === tmpText) {
94 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c>])/g, '$1 $2');
95 | newText = newText.replace(/([\)\]\}>\u201d<])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2');
96 | }
97 | newText = newText.replace(/([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/g, '$1$3$5');
98 |
99 | // fix_symbol
100 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([~!:,\.\?\u2026])([A-Za-z0-9])/g, '$1$2 $3');
101 |
102 | // cjk_ans
103 | // ans_cjk
104 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([A-Za-z0-9`\$%\^&\*\-=\+\\\|/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])/g, '$1 $2');
105 | newText = newText.replace(/([A-Za-z0-9`~\$%\^&\*\-=\+\\\|/!;:,\.\?\u00a1-\u00ff\u2022\u2026\u2027\u2150-\u218f])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2');
106 |
107 | return newText;
108 | };
109 |
110 | module.exports = exports['default'];
111 |
112 | },{}],4:[function(require,module,exports){
113 | 'use strict';
114 |
115 | Object.defineProperty(exports, "__esModule", {
116 | value: true
117 | });
118 | var expsDict = {
119 | // Chinese => Chinese
120 | '最': '坠',
121 | '好的': '吼滴',
122 | '好啊': '吼哇',
123 | '着急': '拙计',
124 | '粉丝': '膜法师',
125 | '支持|赞同': '兹瓷',
126 | '批评|指责|责备': '批判',
127 | '招惹|冒犯|挑衅': '得罪',
128 | '差错|错误|过失': '偏差',
129 | '赚钱|获利': '闷声发大财',
130 | '印点|内定[^钦点]': '钦点',
131 | '经验(丰富|多)': '身经百战',
132 | '(过来|老)(司机|人)': '长者',
133 | '人生(哲学|哲理)': '人生经验',
134 | '(绝对|肯定)(啦|呀)': '当然啦',
135 | '知不知道|晓不晓得': '识得唔识得',
136 | '谈话|闲聊|聊天|交流': '谈笑风生',
137 | '(见识|阅历)(丰富|多|广)': '见得多了',
138 | '不予置评|拒绝(回答|评论)': '无可奉告',
139 | '(坠|很|相当|非常)快': '比香港记者还快',
140 | '(按|讲)(原则|准则|规则|道理)': '讲基本法',
141 | '胡说|乱说|信口胡言|瞎扯|瞎说|胡扯': '一派胡言',
142 | '制造舆论|哗众取宠|一本道|故弄玄虚|夸大其词': '搞个大新闻',
143 | '(到|去|游览)过(许|很)多(地方|城市|国家)': '哪一个国家我没有去过',
144 | '233(3*)': function _(find, $1) {
145 | var multiH = $1.replace(/3/g, 'h');
146 | return 'hhh' + multiH;
147 | },
148 | '(呵|哈|嘻*)': function _(find, $1) {
149 | var multiH = $1.replace(/./g, '蛤');
150 | return '' + multiH;
151 | },
152 |
153 | // Chinese => English
154 | '我很生气': 'I\'m angry',
155 | '天真(的^|了?)': ' naive',
156 | '(太|很|非常?)年轻(的^|了?)': 'too young',
157 | '(太|很|非常?)简单(的^|了?)': 'too simple',
158 | '有(些|的?)时(候?)': 'sometimes',
159 |
160 | // English => English
161 | "great": 'excited'
162 | };
163 |
164 | exports.default = expsDict;
165 | module.exports = exports['default'];
166 |
167 | },{}],5:[function(require,module,exports){
168 | 'use strict';
169 |
170 | Object.defineProperty(exports, "__esModule", {
171 | value: true
172 | });
173 |
174 | var _lifeExp = require('./life-exp');
175 |
176 | var _lifeExp2 = _interopRequireDefault(_lifeExp);
177 |
178 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
179 |
180 | // Working only in browsers :(
181 | var bigNews = function bigNews() {
182 | var $root = arguments.length <= 0 || arguments[0] === undefined ? document.querySelector('body') : arguments[0];
183 | var isIncludeTitle = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
184 |
185 |
186 | // Replace title
187 | if (isIncludeTitle) {
188 | document.title = (0, _lifeExp2.default)(document.title);
189 | }
190 |
191 | // Replace body or other DOM
192 | if ($root !== null) {
193 | DOMTraversal($root, function (node) {
194 | if (node.nodeType === 1) {
195 | // Element
196 | tranAttr(node, ['title', 'alt', 'placeholder']);
197 | } else if (node.nodeType === 3) {
198 | // Text
199 | // FIXME: Disable converting code to halang
200 | node.data = (0, _lifeExp2.default)(node.data, { isTrim: false });
201 | }
202 | });
203 | }
204 |
205 | return $root;
206 | };
207 |
208 | /* ==== Private Functions ==== */
209 | var DOMTraversal = function DOMTraversal(node, callback) {
210 | callback(node);
211 | node = node.firstChild;
212 | while (node) {
213 | DOMTraversal(node, callback);
214 | node = node.nextSibling;
215 | }
216 | };
217 |
218 | var tranAttr = function tranAttr(node, attr) {
219 | if (Array.isArray(attr)) {
220 | for (var i = 0; i < attr.length; i++) {
221 | tranAttr(node, attr[i]);
222 | }
223 | } else {
224 | var attrValue = node.getAttribute(attr);
225 | if (attrValue !== "" && attrValue !== null) {
226 | node.setAttribute(attr, (0, _lifeExp2.default)(attrValue, { isTrim: false }));
227 | }
228 | }
229 | };
230 |
231 | exports.default = bigNews;
232 | module.exports = exports['default'];
233 |
234 | },{"./life-exp":7}],6:[function(require,module,exports){
235 | "use strict";
236 |
237 | Object.defineProperty(exports, "__esModule", {
238 | value: true
239 | });
240 | var elder = function elder() {};
241 |
242 | exports.default = elder;
243 | module.exports = exports['default'];
244 |
245 | },{}],7:[function(require,module,exports){
246 | 'use strict';
247 |
248 | Object.defineProperty(exports, "__esModule", {
249 | value: true
250 | });
251 |
252 | var _pangu = require('../modules/pangu');
253 |
254 | var _pangu2 = _interopRequireDefault(_pangu);
255 |
256 | var _extend = require('../utils/extend');
257 |
258 | var _extend2 = _interopRequireDefault(_extend);
259 |
260 | var _upperCaseFirst = require('../utils/upper-case-first');
261 |
262 | var _upperCaseFirst2 = _interopRequireDefault(_upperCaseFirst);
263 |
264 | var _expsDict = require('../stores/exps-dict');
265 |
266 | var _expsDict2 = _interopRequireDefault(_expsDict);
267 |
268 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
269 |
270 | var lifeExp = function lifeExp(talks) {
271 | var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
272 |
273 | // Init exps
274 | var exps = talks;
275 |
276 | // Init options
277 | var defaultOptions = {
278 | isTrim: true,
279 | isWearGlasses: false
280 | };
281 | options = (0, _extend2.default)({}, defaultOptions, options);
282 |
283 | /* ==== Teaching ==== */
284 |
285 | // Replace text according to expsDict
286 | for (var pattern in _expsDict2.default) {
287 | exps = exps.replace(new RegExp(pattern, 'ig'), _expsDict2.default[pattern]);
288 | }
289 |
290 | // TODO: Wear glasses
291 | if (options.isWearGlasses) {}
292 |
293 | // Add space between Chinese and English characters
294 | exps = (0, _pangu2.default)(exps);
295 |
296 | // Remove leading and trailing excess spaces
297 | if (options.isTrim) {
298 | exps.trim();
299 | }
300 |
301 | // Upper case the first character of each sentence
302 | var endPunctuation = ['。', '!', '?', // Fullwidth
303 | '. ', '! ', '? ' // Halfwidth
304 | ];
305 | endPunctuation.forEach(function (mark) {
306 | exps = exps.split(mark).map(_upperCaseFirst2.default).join(mark);
307 | });
308 |
309 | return exps;
310 | };
311 |
312 | exports.default = lifeExp;
313 | module.exports = exports['default'];
314 |
315 | },{"../modules/pangu":3,"../stores/exps-dict":4,"../utils/extend":8,"../utils/upper-case-first":9}],8:[function(require,module,exports){
316 | "use strict";
317 |
318 | Object.defineProperty(exports, "__esModule", {
319 | value: true
320 | });
321 | var _arguments = arguments;
322 | var extend = function extend(dest) {
323 | var objs = [].slice.call(_arguments, 1);
324 |
325 | for (var i = 0, len = objs.length; i < len; i++) {
326 | var obj = objs[i];
327 | for (var prop in obj) {
328 | dest[prop] = obj[prop];
329 | }
330 | }
331 |
332 | return dest;
333 | };
334 |
335 | exports.default = extend;
336 | module.exports = exports['default'];
337 |
338 | },{}],9:[function(require,module,exports){
339 | 'use strict';
340 |
341 | Object.defineProperty(exports, "__esModule", {
342 | value: true
343 | });
344 |
345 | exports.default = function (str) {
346 | if (str == null) {
347 | return '';
348 | }
349 | return str.charAt(0).toUpperCase() + str.substr(1);
350 | };
351 |
352 | module.exports = exports['default'];
353 |
354 | },{}]},{},[1])
355 | //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvc2NyaXB0cy9icm93c2VyLmpzIiwic3JjL3NjcmlwdHMvaW5kZXguanMiLCJzcmMvc2NyaXB0cy9tb2R1bGVzL3Bhbmd1LmpzIiwic3JjL3NjcmlwdHMvc3RvcmVzL2V4cHMtZGljdC5qcyIsInNyYy9zY3JpcHRzL3RoaW5ncy9iaWctbmV3cy5qcyIsInNyYy9zY3JpcHRzL3RoaW5ncy9lbGRlci5qcyIsInNyYy9zY3JpcHRzL3RoaW5ncy9saWZlLWV4cC5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL2V4dGVuZC5qcyIsInNyYy9zY3JpcHRzL3V0aWxzL3VwcGVyLWNhc2UtZmlyc3QuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7QUNBQTs7Ozs7O0FBRUEsT0FBTyxJQUFQOzs7Ozs7Ozs7OztBQ0ZBOzs7O0FBQ0E7Ozs7QUFDQTs7Ozs7O2tCQUVlO0FBQ2IsNEJBRGE7QUFFYiw0QkFGYTtBQUdiLHdCQUhhOzs7Ozs7Ozs7OztrQkNKQSxVQUFDLElBQUQsRUFBVTtBQUN2QixNQUFJLFVBQVUsSUFBVjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFEbUIsU0FzQnZCLEdBQVUsUUFBUSxPQUFSLENBQWdCLGlJQUFoQixFQUFtSixPQUFuSixDQUFWLENBdEJ1QjtBQXVCdkIsWUFBVSxRQUFRLE9BQVIsQ0FBZ0IsaUlBQWhCLEVBQW1KLE9BQW5KLENBQVYsQ0F2QnVCO0FBd0J2QixZQUFVLFFBQVEsT0FBUixDQUFnQiwwREFBaEIsRUFBNEUsUUFBNUUsQ0FBVixDQXhCdUI7QUF5QnZCLFlBQVUsUUFBUSxPQUFSLENBQWdCLDRJQUFoQixFQUE4SixRQUE5SixDQUFWOzs7O0FBekJ1QixTQTZCdkIsR0FBVSxRQUFRLE9BQVIsQ0FBZ0Isb0lBQWhCLEVBQXNKLE9BQXRKLENBQVYsQ0E3QnVCO0FBOEJ2QixZQUFVLFFBQVEsT0FBUixDQUFnQixvSUFBaEIsRUFBc0osT0FBdEosQ0FB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QVMsR0FBNUMsRUFBaUQ7QUFDL0MsUUFBSSxNQUFNLEtBQUssQ0FBTCxDQUFOLENBRDJDO0FBRS9DLFNBQUssSUFBSSxJQUFKLElBQVksR0FBakIsRUFBc0I7QUFDcEIsV0FBSyxJQUFMLElBQWEsSUFBSSxJQUFKLENBQWIsQ0FEb0I7S0FBdEI7R0FGRjs7QUFPQSxTQUFPLElBQVAsQ0FWcUI7Q0FBVjs7a0JBYUU7Ozs7Ozs7Ozs7a0JDYkEsVUFBQyxHQUFELEVBQVM7QUFDdEIsTUFBSSxPQUFPLElBQVAsRUFBYTtBQUNmLFdBQU8sRUFBUCxDQURlO0dBQWpCO0FBR0EsU0FBTyxJQUFJLE1BQUosQ0FBVyxDQUFYLEVBQWMsV0FBZCxLQUE4QixJQUFJLE1BQUosQ0FBVyxDQUFYLENBQTlCLENBSmU7Q0FBVCIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCJpbXBvcnQgbW9oYSBmcm9tICcuL2luZGV4J1xuXG5nbG9iYWwubW9oYSA9IG1vaGFcbiIsImltcG9ydCBsaWZlRXhwIGZyb20gJy4vdGhpbmdzL2xpZmUtZXhwJ1xuaW1wb3J0IGJpZ05ld3MgZnJvbSAnLi90aGluZ3MvYmlnLW5ld3MnXG5pbXBvcnQgZWxkZXIgZnJvbSAnLi90aGluZ3MvZWxkZXInXG5cbmV4cG9ydCBkZWZhdWx0IHtcbiAgbGlmZUV4cCxcbiAgYmlnTmV3cyxcbiAgZWxkZXJcbn1cbiIsImV4cG9ydCBkZWZhdWx0ICh0ZXh0KSA9PiB7XG4gIGxldCBuZXdUZXh0ID0gdGV4dFxuXG4gIC8qXG4gIFxcdTJlODAtXFx1MmVmZiBDSksgUmFkaWNhbHMgU3VwcGxlbWVudFxuICBcXHUyZjAwLVxcdTJmZGYgS2FuZ3hpIFJhZGljYWxzXG4gIFxcdTMwNDAtXFx1MzA5ZiBIaXJhZ2FuYVxuICBcXHUzMGEwLVxcdTMwZmYgS2F0YWthbmFcbiAgXFx1MzEwMC1cXHUzMTJmIEJvcG9tb2ZvXG4gIFxcdTMyMDAtXFx1MzJmZiBFbmNsb3NlZCBDSksgTGV0dGVycyBhbmQgTW9udGhzXG4gIFxcdTM0MDAtXFx1NGRiZiBDSksgVW5pZmllZCBJZGVvZ3JhcGhzIEV4dGVuc2lvbiBBXG4gIFxcdTRlMDAtXFx1OWZmZiBDSksgVW5pZmllZCBJZGVvZ3JhcGhzXG4gIFxcdWY5MDAtXFx1ZmFmZiBDSksgQ29tcGF0aWJpbGl0eSBJZGVvZ3JhcGhzXG5cbiAgaHR0cDovL3VuaWNvZGUtdGFibGUuY29tL2VuL1xuICBodHRwczovL2dpdGh1Yi5jb20vdmludGEvcGFuZ3VcbiAgKi9cblxuICAvLyBjamtfcXVvdGUgPj4g6LefIEdvIOeJiOW3ruS6huS4gOWAiyAnXG4gIC8vIHF1b3RlX2NqayA+PiDot58gR28g54mI5beu5LqG5LiA5YCLICdcbiAgLy8gZml4X3F1b3RlXG4gIC8vIGZpeF9zaW5nbGVfcXVvdGVcbiAgbmV3VGV4dCA9IG5ld1RleHQucmVwbGFjZSgvKFtcXHUyZTgwLVxcdTJlZmZcXHUyZjAwLVxcdTJmZGZcXHUzMDQwLVxcdTMwOWZcXHUzMGEwLVxcdTMwZmZcXHUzMTAwLVxcdTMxMmZcXHUzMjAwLVxcdTMyZmZcXHUzNDAwLVxcdTRkYmZcXHU0ZTAwLVxcdTlmZmZcXHVmOTAwLVxcdWZhZmZdKShbXCJdKS9nLCAnJDEgJDInKVxuICBuZXdUZXh0ID0gbmV3VGV4dC5yZXBsYWNlKC8oW1wiXSkoW1xcdTJlODAtXFx1MmVmZlxcdTJmMDAtXFx1MmZkZlxcdTMwNDAtXFx1MzA5ZlxcdTMwYTAtXFx1MzBmZlxcdTMxMDAtXFx1MzEyZlxcdTMyMDAtXFx1MzJmZlxcdTM0MDAtXFx1NGRiZlxcdTRlMDAtXFx1OWZmZlxcdWY5MDAtXFx1ZmFmZl0pL2csICckMSAkMicpXG4gIG5ld1RleHQgPSBuZXdUZXh0LnJlcGxhY2UoLyhbXCInXFwoXFxbXFx7PFxcdTIwMWNdKykoXFxzKikoLis/KShcXHMqKShbXCInXFwpXFxdXFx9PlxcdTIwMWRdKykvZywgJyQxJDMkNScpXG4gIG5ld1RleHQgPSBuZXdUZXh0LnJlcGxhY2UoLyhbXFx1MmU4MC1cXHUyZWZmXFx1MmYwMC1cXHUyZmRmXFx1MzA0MC1cXHUzMDlmXFx1MzBhMC1cXHUzMGZmXFx1MzEwMC1cXHUzMTJmXFx1MzIwMC1cXHUzMmZmXFx1MzQwMC1cXHU0ZGJmXFx1NGUwMC1cXHU5ZmZmXFx1ZjkwMC1cXHVmYWZmXSkoICkoJykoW0EtWmEtel0pL2csICckMSQzJDQnKVxuXG4gIC8vIGNqa19oYXNoXG4gIC8vIGhhc2hfY2prXG4gIG5ld1RleHQgPSBuZXdUZXh0LnJlcGxhY2UoLyhbXFx1MmU4MC1cXHUyZWZmXFx1MmYwMC1cXHUyZmRmXFx1MzA0MC1cXHUzMDlmXFx1MzBhMC1cXHUzMGZmXFx1MzEwMC1cXHUzMTJmXFx1MzIwMC1cXHUzMmZmXFx1MzQwMC1cXHU0ZGJmXFx1NGUwMC1cXHU5ZmZmXFx1ZjkwMC1cXHVmYWZmXSkoIyhcXFMrKSkvZywgJyQxICQyJylcbiAgbmV3VGV4dCA9IG5ld1RleHQucmVwbGFjZSgvKChcXFMrKSMpKFtcXHUyZTgwLVxcdTJlZmZcXHUyZjAwLVxcdTJmZGZcXHUzMDQwLVxcdTMwOWZcXHUzMGEwLVxcdTMwZmZcXHUzMTAwLVxcdTMxMmZcXHUzMjAwLVxcdTMyZmZcXHUzNDAwLVxcdTRkYmZcXHU0ZTAwLVxcdTlmZmZcXHVmOTAwLVxcdWZhZmZdKS9nLCAnJDEgJDMnKVxuXG4gIC8vIGNqa19vcGVyYXRvcl9hbnNcbiAgLy8gYW5zX29wZXJhdG9yX2Nqa1xuICBuZXdUZXh0ID0gbmV3VGV4dC5yZXBsYWNlKC8oW1xcdTJlODAtXFx1MmVmZlxcdTJmMDAtXFx1MmZkZlxcdTMwNDAtXFx1MzA5ZlxcdTMwYTAtXFx1MzBmZlxcdTMxMDAtXFx1MzEyZlxcdTMyMDAtXFx1MzJmZlxcdTM0MDAtXFx1NGRiZlxcdTRlMDAtXFx1OWZmZlxcdWY5MDAtXFx1ZmFmZl0pKFtcXCtcXC1cXCpcXC89JlxcXFx8PD5dKShbQS1aYS16MC05XSkvZywgJyQxICQyICQzJylcbiAgbmV3VGV4dCA9IG5ld1RleHQucmVwbGFjZSgvKFtBLVphLXowLTldKShbXFwrXFwtXFwqXFwvPSZcXFxcfDw+XSkoW1xcdTJlODAtXFx1MmVmZlxcdTJmMDAtXFx1MmZkZlxcdTMwNDAtXFx1MzA5ZlxcdTMwYTAtXFx1MzBmZlxcdTMxMDAtXFx1MzEyZlxcdTMyMDAtXFx1MzJmZlxcdTM0MDAtXFx1NGRiZlxcdTRlMDAtXFx1OWZmZlxcdWY5MDAtXFx1ZmFmZl0pL2csICckMSAkMiAkMycpXG5cbiAgLy8gY2prX2JyYWNrZXRfY2prXG4gIC8vIGNqa19icmFja2V0XG4gIC8vIGJyYWNrZXRfY2prXG4gIC8vIGZpeF9icmFja2V0XG4gIGNvbnN0IG9sZFRleHQgPSBuZXdUZXh0XG4gIGNvbnN0IHRtcFRleHQgPSBuZXdUZXh0LnJlcGxhY2UoLyhbXFx1MmU4MC1cXHUyZWZmXFx1MmYwMC1cXHUyZmRmXFx1MzA0MC1cXHUzMDlmXFx1MzBhMC1cXHUzMGZmXFx1MzEwMC1cXHUzMTJmXFx1MzIwMC1cXHUzMmZmXFx1MzQwMC1cXHU0ZGJmXFx1NGUwMC1cXHU5ZmZmXFx1ZjkwMC1cXHVmYWZmXSkoW1xcKFxcW1xcezxcXHUyMDFjXSsoLio/KVtcXClcXF1cXH0+XFx1MjAxZF0rKShbXFx1MmU4MC1cXHUyZWZmXFx1MmYwMC1cXHUyZmRmXFx1MzA0MC1cXHUzMDlmXFx1MzBhMC1cXHUzMGZmXFx1MzEwMC1cXHUzMTJmXFx1MzIwMC1cXHUzMmZmXFx1MzQwMC1cXHU0ZGJmXFx1NGUwMC1cXHU5ZmZmXFx1ZjkwMC1cXHVmYWZmXSkvZywgJyQxICQyICQ0JylcbiAgbmV3VGV4dCA9IHRtcFRleHRcbiAgaWYgKG9sZFRleHQgPT09IHRtcFRleHQpIHtcbiAgICBuZXdUZXh0ID0gbmV3VGV4dC5yZXBsYWNlKC8oW1xcdTJlODAtXFx1MmVmZlxcdTJmMDAtXFx1MmZkZlxcdTMwNDAtXFx1MzA5ZlxcdTMwYTAtXFx1MzBmZlxcdTMxMDAtXFx1MzEyZlxcdTMyMDAtXFx1MzJmZlxcdTM0MDAtXFx1NGRiZlxcdTRlMDAtXFx1OWZmZlxcdWY5MDAtXFx1ZmFmZl0pKFtcXChcXFtcXHs8XFx1MjAxYz5dKS9nLCAnJDEgJDInKVxuICAgIG5ld1RleHQgPSBuZXdUZXh0LnJlcGxhY2UoLyhbXFwpXFxdXFx9PlxcdTIwMWQ8XSkoW1xcdTJlODAtXFx1MmVmZlxcdTJmMDAtXFx1MmZkZlxcdTMwNDAtXFx1MzA5ZlxcdTMwYTAtXFx1MzBmZlxcdTMxMDAtXFx1MzEyZlxcdTMyMDAtXFx1MzJmZlxcdTM0MDAtXFx1NGRiZlxcdTRlMDAtXFx1OWZmZlxcdWY5MDAtXFx1ZmFmZl0pL2csICckMSAkMicpXG4gIH1cbiAgbmV3VGV4dCA9IG5ld1RleHQucmVwbGFjZSgvKFtcXChcXFtcXHs8XFx1MjAxY10rKShcXHMqKSguKz8pKFxccyopKFtcXClcXF1cXH0+XFx1MjAxZF0rKS9nLCAnJDEkMyQ1JylcblxuICAvLyBmaXhfc3ltYm9sXG4gIG5ld1RleHQgPSBuZXdUZXh0LnJlcGxhY2UoLyhbXFx1MmU4MC1cXHUyZWZmXFx1MmYwMC1cXHUyZmRmXFx1MzA0MC1cXHUzMDlmXFx1MzBhMC1cXHUzMGZmXFx1MzEwMC1cXHUzMTJmXFx1MzIwMC1cXHUzMmZmXFx1MzQwMC1cXHU0ZGJmXFx1NGUwMC1cXHU5ZmZmXFx1ZjkwMC1cXHVmYWZmXSkoW34hOixcXC5cXD9cXHUyMDI2XSkoW0EtWmEtejAtOV0pL2csICckMSQyICQzJylcblxuICAvLyBjamtfYW5zXG4gIC8vIGFuc19jamtcbiAgbmV3VGV4dCA9IG5ld1RleHQucmVwbGFjZSgvKFtcXHUyZTgwLVxcdTJlZmZcXHUyZjAwLVxcdTJmZGZcXHUzMDQwLVxcdTMwOWZcXHUzMGEwLVxcdTMwZmZcXHUzMTAwLVxcdTMxMmZcXHUzMjAwLVxcdTMyZmZcXHUzNDAwLVxcdTRkYmZcXHU0ZTAwLVxcdTlmZmZcXHVmOTAwLVxcdWZhZmZdKShbQS1aYS16MC05YFxcJCVcXF4mXFwqXFwtPVxcK1xcXFxcXHwvQFxcdTAwYTEtXFx1MDBmZlxcdTIwMjJcXHUyMDI3XFx1MjE1MC1cXHUyMThmXSkvZywgJyQxICQyJylcbiAgbmV3VGV4dCA9IG5ld1RleHQucmVwbGFjZSgvKFtBLVphLXowLTlgflxcJCVcXF4mXFwqXFwtPVxcK1xcXFxcXHwvITs6LFxcLlxcP1xcdTAwYTEtXFx1MDBmZlxcdTIwMjJcXHUyMDI2XFx1MjAyN1xcdTIxNTAtXFx1MjE4Zl0pKFtcXHUyZTgwLVxcdTJlZmZcXHUyZjAwLVxcdTJmZGZcXHUzMDQwLVxcdTMwOWZcXHUzMGEwLVxcdTMwZmZcXHUzMTAwLVxcdTMxMmZcXHUzMjAwLVxcdTMyZmZcXHUzNDAwLVxcdTRkYmZcXHU0ZTAwLVxcdTlmZmZcXHVmOTAwLVxcdWZhZmZdKS9nLCAnJDEgJDInKVxuXG4gIHJldHVybiBuZXdUZXh0XG59XG4iLCJsZXQgZXhwc0RpY3QgPSB7XG4gIC8vIENoaW5lc2UgPT4gQ2hpbmVzZVxuICAn5pyAJzogJ+WdoCcsXG4gICflpb3nmoQnOiAn5ZC85ru0JyxcbiAgJ+WlveWViic6ICflkLzlk4cnLFxuICAn552A5oClJzogJ+aLmeiuoScsXG4gICfnsonkuJ0nOiAn6Iac5rOV5biIJyxcbiAgJ+aUr+aMgXzotZ7lkIwnOiAn5YW555O3JyxcbiAgJ+aJueivhHzmjIfotKN86LSj5aSHJzogJ+aJueWIpCcsXG4gICfmi5vmg7l85YaS54qvfOaMkeihhSc6ICflvpfnvaonLFxuICAn5beu6ZSZfOmUmeivr3zov4flpLEnOiAn5YGP5beuJyxcbiAgJ+i1mumSsXzojrfliKknOiAn6Ze35aOw5Y+R5aSn6LSiJyxcbiAgJ+WNsOeCuXzlhoXlrppbXumSpueCuV0nOiAn6ZKm54K5JyxcbiAgJ+e7j+mqjCjkuLDlr4x85aSaKSc6ICfouqvnu4/nmb7miJgnLFxuICAnKOi/h+adpXzogIEpKOWPuOacunzkuropJzogJ+mVv+iAhScsXG4gICfkurrnlJ8o5ZOy5a2mfOWTsueQhiknOiAn5Lq655Sf57uP6aqMJyxcbiAgJyjnu53lr7l86IKv5a6aKSjllaZ85ZGAKSc6ICflvZPnhLbllaYnLFxuICAn55+l5LiN55+l6YGT772c5pmT5LiN5pmT5b6XJzogJ+ivhuW+l+WUlOivhuW+lycsXG4gICfosIjor5186Zey6IGK772c6IGK5aSpfOS6pOa1gSc6ICfosIjnrJHpo47nlJ8nLFxuICAnKOingeivhnzpmIXljoYpKOS4sOWvjHzlpJp85bm/KSc6ICfop4HlvpflpJrkuoYnLFxuICAn5LiN5LqI572u6K+EfOaLkue7nSjlm57nrZR86K+E6K66KSc6ICfml6Dlj6/lpYnlkYonLFxuICAnKOWdoHzlvoh855u45b2TfOmdnuW4uCnlv6snOiAn5q+U6aaZ5riv6K6w6ICF6L+Y5b+rJyxcbiAgJyjmjIl86K6yKSjljp/liJl85YeG5YiZfOinhOWImXzpgZPnkIYpJzogJ+iusuWfuuacrOazlScsXG4gICfog6Hor7R85Lmx6K+0fOS/oeWPo+iDoeiogHznno7mia98556O6K+0fOiDoeaJryc6ICfkuIDmtL7og6HoqIAnLFxuICAn5Yi26YCg6IiG6K66fOWTl+S8l+WPluWuoHzkuIDmnKzpgZN85pWF5byE546E6JmafOWkuOWkp+WFtuivjSc6ICfmkJ7kuKrlpKfmlrDpl7snLFxuICAnKOWIsHzljrt85ri46KeIKei/hyjorrh85b6IKeWkmijlnLDmlrl85Z+O5biCfOWbveWutiknOiAn5ZOq5LiA5Liq5Zu95a625oiR5rKh5pyJ5Y676L+HJyxcbiAgJzIzMygzKiknOiAoZmluZCwgJDEpID0+IHtcbiAgICBsZXQgbXVsdGlIID0gJDEucmVwbGFjZSgvMy9nLCAnaCcpXG4gICAgcmV0dXJuIGBoaGgke211bHRpSH1gXG4gIH0sXG4gICco5ZG1fOWTiHzlmLsqKSc6IChmaW5kLCAkMSkgPT4ge1xuICAgIGxldCBtdWx0aUggPSAkMS5yZXBsYWNlKC8uL2csICfom6QnKVxuICAgIHJldHVybiBgJHttdWx0aUh9YFxuICB9LFxuXG4gIC8vIENoaW5lc2UgPT4gRW5nbGlzaFxuICAn5oiR5b6I55Sf5rCUJzogJ0lcXCdtIGFuZ3J5JyxcbiAgJ+WkqeecnyjnmoRefOS6hj8pJzogJyBuYWl2ZScsXG4gICco5aSqfOW+iHzpnZ7luLg/KeW5tOi9uyjnmoRefOS6hj8pJzogJ3RvbyB5b3VuZycsXG4gICco5aSqfOW+iHzpnZ7luLg/KeeugOWNlSjnmoRefOS6hj8pJzogJ3RvbyBzaW1wbGUnLFxuICAn5pyJKOS6m3znmoQ/KeaXtijlgJk/KSc6ICdzb21ldGltZXMnLFxuXG4gIC8vIEVuZ2xpc2ggPT4gRW5nbGlzaFxuICBcImdyZWF0XCI6ICdleGNpdGVkJ1xufVxuXG5leHBvcnQgZGVmYXVsdCBleHBzRGljdFxuIiwiaW1wb3J0IGxpZmVFeHAgZnJvbSAnLi9saWZlLWV4cCdcblxuLy8gV29ya2luZyBvbmx5IGluIGJyb3dzZXJzIDooXG5sZXQgYmlnTmV3cyA9ICgkcm9vdCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJ2JvZHknKSwgaXNJbmNsdWRlVGl0bGUgPSB0cnVlKSA9PiB7XG5cbiAgLy8gUmVwbGFjZSB0aXRsZVxuICBpZiAoaXNJbmNsdWRlVGl0bGUpIHtcbiAgICBkb2N1bWVudC50aXRsZSA9IGxpZmVFeHAoZG9jdW1lbnQudGl0bGUpXG4gIH1cblxuICAvLyBSZXBsYWNlIGJvZHkgb3Igb3RoZXIgRE9NXG4gIGlmICgkcm9vdCAhPT0gbnVsbCkge1xuICAgIERPTVRyYXZlcnNhbCgkcm9vdCwgKG5vZGUpID0+IHtcbiAgICAgIGlmKG5vZGUubm9kZVR5cGUgPT09IDEpIHsgLy8gRWxlbWVudFxuICAgICAgICB0cmFuQXR0cihub2RlLCBbJ3RpdGxlJywgJ2FsdCcsICdwbGFjZWhvbGRlciddKVxuICAgICAgfSBlbHNlIGlmIChub2RlLm5vZGVUeXBlID09PSAzKSB7IC8vIFRleHRcbiAgICAgICAgLy8gRklYTUU6IERpc2FibGUgY29udmVydGluZyBjb2RlIHRvIGhhbGFuZ1xuICAgICAgICBub2RlLmRhdGEgPSBsaWZlRXhwKG5vZGUuZGF0YSwge2lzVHJpbTogZmFsc2V9KVxuICAgICAgfVxuICAgIH0pXG4gIH1cblxuICByZXR1cm4gJHJvb3RcblxufVxuXG4vKiA9PT09IFByaXZhdGUgRnVuY3Rpb25zID09PT0gKi9cbmxldCBET01UcmF2ZXJzYWwgPSAobm9kZSwgY2FsbGJhY2spID0+IHtcbiAgY2FsbGJhY2sobm9kZSlcbiAgbm9kZSA9IG5vZGUuZmlyc3RDaGlsZFxuICB3aGlsZSAobm9kZSkge1xuICAgIERPTVRyYXZlcnNhbChub2RlLCBjYWxsYmFjaylcbiAgICBub2RlID0gbm9kZS5uZXh0U2libGluZ1xuICB9XG59XG5cbmxldCB0cmFuQXR0ciA9IChub2RlLCBhdHRyKSA9PiB7XG4gIGlmIChBcnJheS5pc0FycmF5KGF0dHIpKSB7XG4gICAgZm9yKGxldCBpID0gMDsgaSA8IGF0dHIubGVuZ3RoOyBpKyspIHtcbiAgICAgIHRyYW5BdHRyKG5vZGUsIGF0dHJbaV0pXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGxldCBhdHRyVmFsdWUgPSBub2RlLmdldEF0dHJpYnV0ZShhdHRyKVxuICAgIGlmIChhdHRyVmFsdWUgIT09IFwiXCIgJiYgYXR0clZhbHVlICE9PSBudWxsKSB7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZShhdHRyLCBsaWZlRXhwKGF0dHJWYWx1ZSwge2lzVHJpbTogZmFsc2V9KSlcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgYmlnTmV3c1xuIiwibGV0IGVsZGVyID0gKCkgPT4ge1xuXG59XG5cbmV4cG9ydCBkZWZhdWx0IGVsZGVyXG4iLCJpbXBvcnQgcGFuZ3UgZnJvbSAnLi4vbW9kdWxlcy9wYW5ndSdcbmltcG9ydCBleHRlbmQgZnJvbSAnLi4vdXRpbHMvZXh0ZW5kJ1xuaW1wb3J0IHVwcGVyQ2FzZUZpcnN0IGZyb20gJy4uL3V0aWxzL3VwcGVyLWNhc2UtZmlyc3QnXG5pbXBvcnQgZXhwc0RpY3QgZnJvbSAnLi4vc3RvcmVzL2V4cHMtZGljdCdcblxubGV0IGxpZmVFeHAgPSAodGFsa3MsIG9wdGlvbnMgPSB7fSkgPT4ge1xuICAvLyBJbml0IGV4cHNcbiAgbGV0IGV4cHMgPSB0YWxrc1xuXG4gIC8vIEluaXQgb3B0aW9uc1xuICBsZXQgZGVmYXVsdE9wdGlvbnMgPSB7XG4gICAgaXNUcmltOiB0cnVlLFxuICAgIGlzV2VhckdsYXNzZXM6IGZhbHNlXG4gIH1cbiAgb3B0aW9ucyA9IGV4dGVuZCh7fSwgZGVmYXVsdE9wdGlvbnMsIG9wdGlvbnMpXG5cbiAgLyogPT09PSBUZWFjaGluZyA9PT09ICovXG5cbiAgLy8gUmVwbGFjZSB0ZXh0IGFjY29yZGluZyB0byBleHBzRGljdFxuICBmb3IgKGxldCBwYXR0ZXJuIGluIGV4cHNEaWN0KSB7XG4gICAgZXhwcyA9IGV4cHMucmVwbGFjZShuZXcgUmVnRXhwKHBhdHRlcm4sICdpZycpLCBleHBzRGljdFtwYXR0ZXJuXSlcbiAgfVxuXG4gIC8vIFRPRE86IFdlYXIgZ2xhc3Nlc1xuICBpZiAob3B0aW9ucy5pc1dlYXJHbGFzc2VzKSB7XG5cbiAgfVxuXG4gIC8vIEFkZCBzcGFjZSBiZXR3ZWVuIENoaW5lc2UgYW5kIEVuZ2xpc2ggY2hhcmFjdGVyc1xuICBleHBzID0gcGFuZ3UoZXhwcylcblxuICAvLyBSZW1vdmUgbGVhZGluZyBhbmQgdHJhaWxpbmcgZXhjZXNzIHNwYWNlc1xuICBpZiAob3B0aW9ucy5pc1RyaW0pIHtcbiAgICBleHBzLnRyaW0oKVxuICB9XG5cbiAgLy8gVXBwZXIgY2FzZSB0aGUgZmlyc3QgY2hhcmFjdGVyIG9mIGVhY2ggc2VudGVuY2VcbiAgbGV0IGVuZFB1bmN0dWF0aW9uID0gW1xuICAgICfjgIInLCAn77yBJywgJ++8nycsIC8vIEZ1bGx3aWR0aFxuICAgICcuICcsICchICcsICc/ICcgLy8gSGFsZndpZHRoXG4gIF1cbiAgZW5kUHVuY3R1YXRpb24uZm9yRWFjaCgobWFyaykgPT4ge1xuICAgIGV4cHMgPSBleHBzLnNwbGl0KG1hcmspLm1hcCh1cHBlckNhc2VGaXJzdCkuam9pbihtYXJrKVxuICB9KVxuXG4gIHJldHVybiBleHBzXG59XG5cbmV4cG9ydCBkZWZhdWx0IGxpZmVFeHBcbiIsImxldCBleHRlbmQgPSAoZGVzdCkgPT4ge1xuICBsZXQgb2JqcyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuXG4gIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvYmpzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgbGV0IG9iaiA9IG9ianNbaV1cbiAgICBmb3IgKHZhciBwcm9wIGluIG9iaikge1xuICAgICAgZGVzdFtwcm9wXSA9IG9ialtwcm9wXVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkZXN0XG59XG5cbmV4cG9ydCBkZWZhdWx0IGV4dGVuZFxuIiwiZXhwb3J0IGRlZmF1bHQgKHN0cikgPT4ge1xuICBpZiAoc3RyID09IG51bGwpIHtcbiAgICByZXR1cm4gJydcbiAgfVxuICByZXR1cm4gc3RyLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3RyLnN1YnN0cigxKVxufVxuIl19
356 |
--------------------------------------------------------------------------------
/browser/moha.min.js:
--------------------------------------------------------------------------------
1 | !function u(f,e,t){function r(n,l){if(!e[n]){if(!f[n]){var i="function"==typeof require&&require;if(!l&&i)return i(n,!0);if(a)return a(n,!0);var d=new Error("Cannot find module '"+n+"'");throw d.code="MODULE_NOT_FOUND",d}var o=e[n]={exports:{}};f[n][0].call(o.exports,function(u){var e=f[n][1][u];return r(e?e:u)},o,o.exports,u,f,e,t)}return e[n].exports}for(var a="function"==typeof require&&require,n=0;n\u201d]+)/g,"$1$3$5"),f=f.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])( )(')([A-Za-z])/g,"$1$3$4"),f=f.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(#(\S+))/g,"$1 $2"),f=f.replace(/((\S+)#)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,"$1 $3"),f=f.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\+\-\*\/=&\\|<>])([A-Za-z0-9])/g,"$1 $2 $3"),f=f.replace(/([A-Za-z0-9])([\+\-\*\/=&\\|<>])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,"$1 $2 $3");var e=f,t=f.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c]+(.*?)[\)\]\}>\u201d]+)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,"$1 $2 $4");return f=t,e===t&&(f=f.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c>])/g,"$1 $2"),f=f.replace(/([\)\]\}>\u201d<])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,"$1 $2")),f=f.replace(/([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/g,"$1$3$5"),f=f.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([~!:,\.\?\u2026])([A-Za-z0-9])/g,"$1$2 $3"),f=f.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([A-Za-z0-9`\$%\^&\*\-=\+\\\|\/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])/g,"$1 $2"),f=f.replace(/([A-Za-z0-9`~\$%\^&\*\-=\+\\\|\/!;:,\.\?\u00a1-\u00ff\u2022\u2026\u2027\u2150-\u218f])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g,"$1 $2")},f.exports=e["default"]},{}],4:[function(u,f,e){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var t={"最":"坠","好的":"吼滴","好啊":"吼哇","着急":"拙计","粉丝":"膜法师","支持|赞同":"兹瓷","批评|指责|责备":"批判","招惹|冒犯|挑衅":"得罪","差错|错误|过失":"偏差","赚钱|获利":"闷声发大财","印点|内定[^钦点]":"钦点","经验(丰富|多)":"身经百战","(过来|老)(司机|人)":"长者","人生(哲学|哲理)":"人生经验","(绝对|肯定)(啦|呀)":"当然啦","知不知道|晓不晓得":"识得唔识得","谈话|闲聊|聊天|交流":"谈笑风生","(见识|阅历)(丰富|多|广)":"见得多了","不予置评|拒绝(回答|评论)":"无可奉告","(坠|很|相当|非常)快":"比香港记者还快","(按|讲)(原则|准则|规则|道理)":"讲基本法","胡说|乱说|信口胡言|瞎扯|瞎说|胡扯":"一派胡言","制造舆论|哗众取宠|一本道|故弄玄虚|夸大其词":"搞个大新闻","(到|去|游览)过(许|很)多(地方|城市|国家)":"哪一个国家我没有去过","233(3*)":function(u,f){var e=f.replace(/3/g,"h");return"hhh"+e},"(呵|哈|嘻*)":function(u,f){var e=f.replace(/./g,"蛤");return""+e},"我很生气":"I'm angry","天真(的^|了?)":" naive","(太|很|非常?)年轻(的^|了?)":"too young","(太|很|非常?)简单(的^|了?)":"too simple","有(些|的?)时(候?)":"sometimes",great:"excited"};e["default"]=t,f.exports=e["default"]},{}],5:[function(u,f,e){"use strict";function t(u){return u&&u.__esModule?u:{"default":u}}Object.defineProperty(e,"__esModule",{value:!0});var r=u("./life-exp"),a=t(r),n=function(){var u=arguments.length<=0||void 0===arguments[0]?document.querySelector("body"):arguments[0],f=arguments.length<=1||void 0===arguments[1]?!0:arguments[1];return f&&(document.title=(0,a["default"])(document.title)),null!==u&&l(u,function(u){1===u.nodeType?i(u,["title","alt","placeholder"]):3===u.nodeType&&(u.data=(0,a["default"])(u.data,{isTrim:!1}))}),u},l=function d(u,f){for(f(u),u=u.firstChild;u;)d(u,f),u=u.nextSibling},i=function o(u,f){if(Array.isArray(f))for(var e=0;ee;e++){var a=f[e];for(var n in a)u[n]=a[n]}return u};e["default"]=r,f.exports=e["default"]},{}],9:[function(u,f,e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e["default"]=function(u){return null==u?"":u.charAt(0).toUpperCase()+u.substr(1)},f.exports=e["default"]},{}]},{},[1]);
--------------------------------------------------------------------------------
/es5/browser.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | var _index = require('./index');
4 |
5 | var _index2 = _interopRequireDefault(_index);
6 |
7 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
8 |
9 | global.moha = _index2.default;
--------------------------------------------------------------------------------
/es5/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _lifeExp = require('./things/life-exp');
8 |
9 | var _lifeExp2 = _interopRequireDefault(_lifeExp);
10 |
11 | var _bigNews = require('./things/big-news');
12 |
13 | var _bigNews2 = _interopRequireDefault(_bigNews);
14 |
15 | var _elder = require('./things/elder');
16 |
17 | var _elder2 = _interopRequireDefault(_elder);
18 |
19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20 |
21 | exports.default = {
22 | lifeExp: _lifeExp2.default,
23 | bigNews: _bigNews2.default,
24 | elder: _elder2.default
25 | };
26 | module.exports = exports['default'];
--------------------------------------------------------------------------------
/es5/modules/pangu.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | exports.default = function (text) {
8 | var newText = text;
9 |
10 | /*
11 | \u2e80-\u2eff CJK Radicals Supplement
12 | \u2f00-\u2fdf Kangxi Radicals
13 | \u3040-\u309f Hiragana
14 | \u30a0-\u30ff Katakana
15 | \u3100-\u312f Bopomofo
16 | \u3200-\u32ff Enclosed CJK Letters and Months
17 | \u3400-\u4dbf CJK Unified Ideographs Extension A
18 | \u4e00-\u9fff CJK Unified Ideographs
19 | \uf900-\ufaff CJK Compatibility Ideographs
20 | http://unicode-table.com/en/
21 | https://github.com/vinta/pangu
22 | */
23 |
24 | // cjk_quote >> 跟 Go 版差了一個 '
25 | // quote_cjk >> 跟 Go 版差了一個 '
26 | // fix_quote
27 | // fix_single_quote
28 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(["])/g, '$1 $2');
29 | newText = newText.replace(/(["])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2');
30 | newText = newText.replace(/(["'\(\[\{<\u201c]+)(\s*)(.+?)(\s*)(["'\)\]\}>\u201d]+)/g, '$1$3$5');
31 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])( )(')([A-Za-z])/g, '$1$3$4');
32 |
33 | // cjk_hash
34 | // hash_cjk
35 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(#(\S+))/g, '$1 $2');
36 | newText = newText.replace(/((\S+)#)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $3');
37 |
38 | // cjk_operator_ans
39 | // ans_operator_cjk
40 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\+\-\*\/=&\\|<>])([A-Za-z0-9])/g, '$1 $2 $3');
41 | newText = newText.replace(/([A-Za-z0-9])([\+\-\*\/=&\\|<>])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2 $3');
42 |
43 | // cjk_bracket_cjk
44 | // cjk_bracket
45 | // bracket_cjk
46 | // fix_bracket
47 | var oldText = newText;
48 | var tmpText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c]+(.*?)[\)\]\}>\u201d]+)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2 $4');
49 | newText = tmpText;
50 | if (oldText === tmpText) {
51 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c>])/g, '$1 $2');
52 | newText = newText.replace(/([\)\]\}>\u201d<])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2');
53 | }
54 | newText = newText.replace(/([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/g, '$1$3$5');
55 |
56 | // fix_symbol
57 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([~!:,\.\?\u2026])([A-Za-z0-9])/g, '$1$2 $3');
58 |
59 | // cjk_ans
60 | // ans_cjk
61 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([A-Za-z0-9`\$%\^&\*\-=\+\\\|/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])/g, '$1 $2');
62 | newText = newText.replace(/([A-Za-z0-9`~\$%\^&\*\-=\+\\\|/!;:,\.\?\u00a1-\u00ff\u2022\u2026\u2027\u2150-\u218f])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2');
63 |
64 | return newText;
65 | };
66 |
67 | module.exports = exports['default'];
--------------------------------------------------------------------------------
/es5/stores/exps-dict.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | var expsDict = {
7 | // Chinese => Chinese
8 | '最': '坠',
9 | '好的': '吼滴',
10 | '好啊': '吼哇',
11 | '着急': '拙计',
12 | '粉丝': '膜法师',
13 | '支持|赞同': '兹瓷',
14 | '批评|指责|责备': '批判',
15 | '招惹|冒犯|挑衅': '得罪',
16 | '差错|错误|过失': '偏差',
17 | '赚钱|获利': '闷声发大财',
18 | '印点|内定[^钦点]': '钦点',
19 | '经验(丰富|多)': '身经百战',
20 | '(过来|老)(司机|人)': '长者',
21 | '人生(哲学|哲理)': '人生经验',
22 | '(绝对|肯定)(啦|呀)': '当然啦',
23 | '知不知道|晓不晓得': '识得唔识得',
24 | '谈话|闲聊|聊天|交流': '谈笑风生',
25 | '(见识|阅历)(丰富|多|广)': '见得多了',
26 | '不予置评|拒绝(回答|评论)': '无可奉告',
27 | '(坠|很|相当|非常)快': '比香港记者还快',
28 | '(按|讲)(原则|准则|规则|道理)': '讲基本法',
29 | '胡说|乱说|信口胡言|瞎扯|瞎说|胡扯': '一派胡言',
30 | '制造舆论|哗众取宠|一本道|故弄玄虚|夸大其词': '搞个大新闻',
31 | '(到|去|游览)过(许|很)多(地方|城市|国家)': '哪一个国家我没有去过',
32 | '233(3*)': function _(find, $1) {
33 | var multiH = $1.replace(/3/g, 'h');
34 | return 'hhh' + multiH;
35 | },
36 | '(呵|哈|嘻*)': function _(find, $1) {
37 | var multiH = $1.replace(/./g, '蛤');
38 | return '' + multiH;
39 | },
40 |
41 | // Chinese => English
42 | '我很生气': 'I\'m angry',
43 | '天真(的^|了?)': ' naive',
44 | '(太|很|非常?)年轻(的^|了?)': 'too young',
45 | '(太|很|非常?)简单(的^|了?)': 'too simple',
46 | '有(些|的?)时(候?)': 'sometimes',
47 |
48 | // English => English
49 | "great": 'excited'
50 | };
51 |
52 | exports.default = expsDict;
53 | module.exports = exports['default'];
--------------------------------------------------------------------------------
/es5/things/big-news.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _lifeExp = require('./life-exp');
8 |
9 | var _lifeExp2 = _interopRequireDefault(_lifeExp);
10 |
11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12 |
13 | // Working only in browsers :(
14 | var bigNews = function bigNews() {
15 | var $root = arguments.length <= 0 || arguments[0] === undefined ? document.querySelector('body') : arguments[0];
16 | var isIncludeTitle = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];
17 |
18 |
19 | // Replace title
20 | if (isIncludeTitle) {
21 | document.title = (0, _lifeExp2.default)(document.title);
22 | }
23 |
24 | // Replace body or other DOM
25 | if ($root !== null) {
26 | DOMTraversal($root, function (node) {
27 | if (node.nodeType === 1) {
28 | // Element
29 | tranAttr(node, ['title', 'alt', 'placeholder']);
30 | } else if (node.nodeType === 3) {
31 | // Text
32 | // FIXME: Disable converting code to halang
33 | node.data = (0, _lifeExp2.default)(node.data, { isTrim: false });
34 | }
35 | });
36 | }
37 |
38 | return $root;
39 | };
40 |
41 | /* ==== Private Functions ==== */
42 | var DOMTraversal = function DOMTraversal(node, callback) {
43 | callback(node);
44 | node = node.firstChild;
45 | while (node) {
46 | DOMTraversal(node, callback);
47 | node = node.nextSibling;
48 | }
49 | };
50 |
51 | var tranAttr = function tranAttr(node, attr) {
52 | if (Array.isArray(attr)) {
53 | for (var i = 0; i < attr.length; i++) {
54 | tranAttr(node, attr[i]);
55 | }
56 | } else {
57 | var attrValue = node.getAttribute(attr);
58 | if (attrValue !== "" && attrValue !== null) {
59 | node.setAttribute(attr, (0, _lifeExp2.default)(attrValue, { isTrim: false }));
60 | }
61 | }
62 | };
63 |
64 | exports.default = bigNews;
65 | module.exports = exports['default'];
--------------------------------------------------------------------------------
/es5/things/elder.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | var elder = function elder() {};
7 |
8 | exports.default = elder;
9 | module.exports = exports['default'];
--------------------------------------------------------------------------------
/es5/things/life-exp.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _pangu = require('../modules/pangu');
8 |
9 | var _pangu2 = _interopRequireDefault(_pangu);
10 |
11 | var _extend = require('../utils/extend');
12 |
13 | var _extend2 = _interopRequireDefault(_extend);
14 |
15 | var _upperCaseFirst = require('../utils/upper-case-first');
16 |
17 | var _upperCaseFirst2 = _interopRequireDefault(_upperCaseFirst);
18 |
19 | var _expsDict = require('../stores/exps-dict');
20 |
21 | var _expsDict2 = _interopRequireDefault(_expsDict);
22 |
23 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
24 |
25 | var lifeExp = function lifeExp(talks) {
26 | var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
27 |
28 | // Init exps
29 | var exps = talks;
30 |
31 | // Init options
32 | var defaultOptions = {
33 | isTrim: true,
34 | isWearGlasses: false
35 | };
36 | options = (0, _extend2.default)({}, defaultOptions, options);
37 |
38 | /* ==== Teaching ==== */
39 |
40 | // Replace text according to expsDict
41 | for (var pattern in _expsDict2.default) {
42 | exps = exps.replace(new RegExp(pattern, 'ig'), _expsDict2.default[pattern]);
43 | }
44 |
45 | // TODO: Wear glasses
46 | if (options.isWearGlasses) {}
47 |
48 | // Add space between Chinese and English characters
49 | exps = (0, _pangu2.default)(exps);
50 |
51 | // Remove leading and trailing excess spaces
52 | if (options.isTrim) {
53 | exps.trim();
54 | }
55 |
56 | // Upper case the first character of each sentence
57 | var endPunctuation = ['。', '!', '?', // Fullwidth
58 | '. ', '! ', '? ' // Halfwidth
59 | ];
60 | endPunctuation.forEach(function (mark) {
61 | exps = exps.split(mark).map(_upperCaseFirst2.default).join(mark);
62 | });
63 |
64 | return exps;
65 | };
66 |
67 | exports.default = lifeExp;
68 | module.exports = exports['default'];
--------------------------------------------------------------------------------
/es5/utils/extend.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | var _arguments = arguments;
7 | var extend = function extend(dest) {
8 | var objs = [].slice.call(_arguments, 1);
9 |
10 | for (var i = 0, len = objs.length; i < len; i++) {
11 | var obj = objs[i];
12 | for (var prop in obj) {
13 | dest[prop] = obj[prop];
14 | }
15 | }
16 |
17 | return dest;
18 | };
19 |
20 | exports.default = extend;
21 | module.exports = exports['default'];
--------------------------------------------------------------------------------
/es5/utils/upper-case-first.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | exports.default = function (str) {
8 | if (str == null) {
9 | return '';
10 | }
11 | return str.charAt(0).toUpperCase() + str.substr(1);
12 | };
13 |
14 | module.exports = exports['default'];
--------------------------------------------------------------------------------
/gulpfile.babel.js:
--------------------------------------------------------------------------------
1 | const argv = require('yargs').argv
2 | const browserify = require('browserify')
3 | const source = require('vinyl-source-stream')
4 |
5 | const gulp = require('gulp')
6 | const babel = require('gulp-babel')
7 | const jade = require('gulp-jade')
8 | const gutil = require('gulp-util')
9 | const stylus = require('gulp-stylus')
10 | const rename = require('gulp-rename')
11 | const uglify = require('gulp-uglify')
12 | const rimraf = require('gulp-rimraf')
13 | const sequence = require('gulp-sequence')
14 | const livereload = require('gulp-livereload')
15 |
16 | let isBuild = argv._[0] === 'build'
17 |
18 | // Global method
19 | function logError (err) {
20 | var stack = unescape(err.stack)
21 | delete err.stack
22 | if (err.stream != null) {
23 | delete err.stream
24 | }
25 | if (err.codeFrame != null) {
26 | delete err.codeFrame
27 | }
28 | gutil.log(err)
29 | gutil.log(stack)
30 | this.emit('end')
31 | }
32 |
33 | /* ==== Tasks ==== */
34 | gulp.task('clean', () =>
35 | gulp.src(['browser', 'es5', 'gh-pages'], {read: false})
36 | .pipe(rimraf({
37 | force: true
38 | }))
39 | )
40 |
41 | gulp.task('scripts', () =>
42 | gulp.src('src/scripts/**/*.js')
43 | .pipe(babel())
44 | .on('error', logError)
45 | .pipe(gulp.dest('es5'))
46 | )
47 |
48 | gulp.task('script-browser', () =>
49 | browserify({
50 | entries: 'src/scripts/browser.js',
51 | cache: {},
52 | packageCache: {},
53 | debug: !isBuild
54 | })
55 | .transform('babelify')
56 | .bundle()
57 | .on('error', logError)
58 | .pipe(source('moha.js'))
59 | .pipe(gulp.dest('browser'))
60 | )
61 |
62 | gulp.task('script-browser-min', () =>
63 | gulp.src('browser/moha.js')
64 | .pipe(uglify())
65 | .pipe(rename('moha.min.js'))
66 | .pipe(gulp.dest('browser'))
67 | )
68 |
69 | gulp.task('ghPages-index', () => null)
70 | gulp.task('ghPages-style', () => null)
71 | gulp.task('ghPages-script', () => null)
72 |
73 | // Watch & Serve
74 | gulp.task('watch', () => {
75 | livereload.listen(23333)
76 | gulp.watch('src/scripts/**/*.js', ['dev'])
77 | })
78 |
79 | gulp.task('serve', ['watch'], () => {
80 |
81 | })
82 |
83 | // Tasks sequence
84 | gulp.task('dev', (cb) => sequence('clean', ['scripts', 'script-browser'])(cb))
85 |
86 | gulp.task('ghPages', (cb) => sequence(['ghPages-index', 'ghPages-style', 'ghPages-script'])(cb))
87 |
88 | gulp.task('build', (cb) => sequence('dev', 'ghPages','script-browser-min')(cb))
89 |
90 | gulp.task('default', ['build'])
91 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "moha",
3 | "version": "0.0.1",
4 | "description": "Never too young, too simple but sometimes moha.",
5 | "license": "MIT",
6 | "author": "IFELog",
7 | "main": "es5/index.js",
8 | "scripts": {
9 | "test": "node test/index.js"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/IFELog/MoHa.git"
14 | },
15 | "dependencies": {
16 | "pangu": "^3.0.0"
17 | },
18 | "devDependencies": {
19 | "babel-plugin-add-module-exports": "^0.1.2",
20 | "babel-preset-es2015": "^6.6.0",
21 | "babelify": "^7.2.0",
22 | "browserify": "^13.0.0",
23 | "gulp": "^3.9.1",
24 | "gulp-babel": "^6.1.2",
25 | "gulp-jade": "^1.0.1",
26 | "gulp-livereload": "^3.8.0",
27 | "gulp-rename": "^1.2.2",
28 | "gulp-rimraf": "^0.2.0",
29 | "gulp-sequence": "^0.4.5",
30 | "gulp-stylus": "^2.0.2",
31 | "gulp-uglify": "^1.2.0",
32 | "gulp-util": "^3.0.6",
33 | "tape": "^4.5.1",
34 | "vinyl-source-stream": "^1.1.0",
35 | "yargs": "^3.19.0"
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/scripts/browser.js:
--------------------------------------------------------------------------------
1 | import moha from './index'
2 |
3 | global.moha = moha
4 |
--------------------------------------------------------------------------------
/src/scripts/index.js:
--------------------------------------------------------------------------------
1 | import lifeExp from './things/life-exp'
2 | import bigNews from './things/big-news'
3 | import elder from './things/elder'
4 |
5 | export default {
6 | lifeExp,
7 | bigNews,
8 | elder
9 | }
10 |
--------------------------------------------------------------------------------
/src/scripts/modules/pangu.js:
--------------------------------------------------------------------------------
1 | export default (text) => {
2 | let newText = text
3 |
4 | /*
5 | \u2e80-\u2eff CJK Radicals Supplement
6 | \u2f00-\u2fdf Kangxi Radicals
7 | \u3040-\u309f Hiragana
8 | \u30a0-\u30ff Katakana
9 | \u3100-\u312f Bopomofo
10 | \u3200-\u32ff Enclosed CJK Letters and Months
11 | \u3400-\u4dbf CJK Unified Ideographs Extension A
12 | \u4e00-\u9fff CJK Unified Ideographs
13 | \uf900-\ufaff CJK Compatibility Ideographs
14 |
15 | http://unicode-table.com/en/
16 | https://github.com/vinta/pangu
17 | */
18 |
19 | // cjk_quote >> 跟 Go 版差了一個 '
20 | // quote_cjk >> 跟 Go 版差了一個 '
21 | // fix_quote
22 | // fix_single_quote
23 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(["])/g, '$1 $2')
24 | newText = newText.replace(/(["])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2')
25 | newText = newText.replace(/(["'\(\[\{<\u201c]+)(\s*)(.+?)(\s*)(["'\)\]\}>\u201d]+)/g, '$1$3$5')
26 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])( )(')([A-Za-z])/g, '$1$3$4')
27 |
28 | // cjk_hash
29 | // hash_cjk
30 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])(#(\S+))/g, '$1 $2')
31 | newText = newText.replace(/((\S+)#)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $3')
32 |
33 | // cjk_operator_ans
34 | // ans_operator_cjk
35 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\+\-\*\/=&\\|<>])([A-Za-z0-9])/g, '$1 $2 $3')
36 | newText = newText.replace(/([A-Za-z0-9])([\+\-\*\/=&\\|<>])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2 $3')
37 |
38 | // cjk_bracket_cjk
39 | // cjk_bracket
40 | // bracket_cjk
41 | // fix_bracket
42 | const oldText = newText
43 | const tmpText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c]+(.*?)[\)\]\}>\u201d]+)([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2 $4')
44 | newText = tmpText
45 | if (oldText === tmpText) {
46 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([\(\[\{<\u201c>])/g, '$1 $2')
47 | newText = newText.replace(/([\)\]\}>\u201d<])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2')
48 | }
49 | newText = newText.replace(/([\(\[\{<\u201c]+)(\s*)(.+?)(\s*)([\)\]\}>\u201d]+)/g, '$1$3$5')
50 |
51 | // fix_symbol
52 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([~!:,\.\?\u2026])([A-Za-z0-9])/g, '$1$2 $3')
53 |
54 | // cjk_ans
55 | // ans_cjk
56 | newText = newText.replace(/([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])([A-Za-z0-9`\$%\^&\*\-=\+\\\|/@\u00a1-\u00ff\u2022\u2027\u2150-\u218f])/g, '$1 $2')
57 | newText = newText.replace(/([A-Za-z0-9`~\$%\^&\*\-=\+\\\|/!;:,\.\?\u00a1-\u00ff\u2022\u2026\u2027\u2150-\u218f])([\u2e80-\u2eff\u2f00-\u2fdf\u3040-\u309f\u30a0-\u30ff\u3100-\u312f\u3200-\u32ff\u3400-\u4dbf\u4e00-\u9fff\uf900-\ufaff])/g, '$1 $2')
58 |
59 | return newText
60 | }
61 |
--------------------------------------------------------------------------------
/src/scripts/stores/exps-dict.js:
--------------------------------------------------------------------------------
1 | let expsDict = {
2 | // Chinese => Chinese
3 | '最': '坠',
4 | '好的': '吼滴',
5 | '好啊': '吼哇',
6 | '着急': '拙计',
7 | '粉丝': '膜法师',
8 | '支持|赞同': '兹瓷',
9 | '批评|指责|责备': '批判',
10 | '招惹|冒犯|挑衅': '得罪',
11 | '差错|错误|过失': '偏差',
12 | '赚钱|获利': '闷声发大财',
13 | '印点|内定[^钦点]': '钦点',
14 | '经验(丰富|多)': '身经百战',
15 | '(过来|老)(司机|人)': '长者',
16 | '人生(哲学|哲理)': '人生经验',
17 | '(绝对|肯定)(啦|呀)': '当然啦',
18 | '知不知道|晓不晓得': '识得唔识得',
19 | '谈话|闲聊|聊天|交流': '谈笑风生',
20 | '(见识|阅历)(丰富|多|广)': '见得多了',
21 | '不予置评|拒绝(回答|评论)': '无可奉告',
22 | '(坠|很|相当|非常)快': '比香港记者还快',
23 | '(按|讲)(原则|准则|规则|道理)': '讲基本法',
24 | '胡说|乱说|信口胡言|瞎扯|瞎说|胡扯': '一派胡言',
25 | '制造舆论|哗众取宠|一本道|故弄玄虚|夸大其词': '搞个大新闻',
26 | '(到|去|游览)过(许|很)多(地方|城市|国家)': '哪一个国家我没有去过',
27 | '233(3*)': (find, $1) => {
28 | let multiH = $1.replace(/3/g, 'h')
29 | return `hhh${multiH}`
30 | },
31 | '(呵|哈|嘻*)': (find, $1) => {
32 | let multiH = $1.replace(/./g, '蛤')
33 | return `${multiH}`
34 | },
35 |
36 | // Chinese => English
37 | '我很生气': 'I\'m angry',
38 | '天真(的^|了?)': ' naive',
39 | '(太|很|非常?)年轻(的^|了?)': 'too young',
40 | '(太|很|非常?)简单(的^|了?)': 'too simple',
41 | '有(些|的?)时(候?)': 'sometimes',
42 |
43 | // English => English
44 | "great": 'excited'
45 | }
46 |
47 | export default expsDict
48 |
--------------------------------------------------------------------------------
/src/scripts/things/big-news.js:
--------------------------------------------------------------------------------
1 | import lifeExp from './life-exp'
2 |
3 | // Working only in browsers :(
4 | let bigNews = ($root = document.querySelector('body'), isIncludeTitle = true) => {
5 |
6 | // Replace title
7 | if (isIncludeTitle) {
8 | document.title = lifeExp(document.title)
9 | }
10 |
11 | // Replace body or other DOM
12 | if ($root !== null) {
13 | DOMTraversal($root, (node) => {
14 | if(node.nodeType === 1) { // Element
15 | tranAttr(node, ['title', 'alt', 'placeholder'])
16 | } else if (node.nodeType === 3) { // Text
17 | // FIXME: Disable converting code to halang
18 | node.data = lifeExp(node.data, {isTrim: false})
19 | }
20 | })
21 | }
22 |
23 | return $root
24 |
25 | }
26 |
27 | /* ==== Private Functions ==== */
28 | let DOMTraversal = (node, callback) => {
29 | callback(node)
30 | node = node.firstChild
31 | while (node) {
32 | DOMTraversal(node, callback)
33 | node = node.nextSibling
34 | }
35 | }
36 |
37 | let tranAttr = (node, attr) => {
38 | if (Array.isArray(attr)) {
39 | for(let i = 0; i < attr.length; i++) {
40 | tranAttr(node, attr[i])
41 | }
42 | } else {
43 | let attrValue = node.getAttribute(attr)
44 | if (attrValue !== "" && attrValue !== null) {
45 | node.setAttribute(attr, lifeExp(attrValue, {isTrim: false}))
46 | }
47 | }
48 | }
49 |
50 | export default bigNews
51 |
--------------------------------------------------------------------------------
/src/scripts/things/elder.js:
--------------------------------------------------------------------------------
1 | let elder = () => {
2 |
3 | }
4 |
5 | export default elder
6 |
--------------------------------------------------------------------------------
/src/scripts/things/life-exp.js:
--------------------------------------------------------------------------------
1 | import pangu from '../modules/pangu'
2 | import extend from '../utils/extend'
3 | import upperCaseFirst from '../utils/upper-case-first'
4 | import expsDict from '../stores/exps-dict'
5 |
6 | let lifeExp = (talks, options = {}) => {
7 | // Init exps
8 | let exps = talks
9 |
10 | // Init options
11 | let defaultOptions = {
12 | isTrim: true,
13 | isWearGlasses: false
14 | }
15 | options = extend({}, defaultOptions, options)
16 |
17 | /* ==== Teaching ==== */
18 |
19 | // Replace text according to expsDict
20 | for (let pattern in expsDict) {
21 | exps = exps.replace(new RegExp(pattern, 'ig'), expsDict[pattern])
22 | }
23 |
24 | // TODO: Wear glasses
25 | if (options.isWearGlasses) {
26 |
27 | }
28 |
29 | // Add space between Chinese and English characters
30 | exps = pangu(exps)
31 |
32 | // Remove leading and trailing excess spaces
33 | if (options.isTrim) {
34 | exps.trim()
35 | }
36 |
37 | // Upper case the first character of each sentence
38 | let endPunctuation = [
39 | '。', '!', '?', // Fullwidth
40 | '. ', '! ', '? ' // Halfwidth
41 | ]
42 | endPunctuation.forEach((mark) => {
43 | exps = exps.split(mark).map(upperCaseFirst).join(mark)
44 | })
45 |
46 | return exps
47 | }
48 |
49 | export default lifeExp
50 |
--------------------------------------------------------------------------------
/src/scripts/utils/extend.js:
--------------------------------------------------------------------------------
1 | let extend = (dest) => {
2 | let objs = [].slice.call(arguments, 1)
3 |
4 | for (var i = 0, len = objs.length; i < len; i++) {
5 | let obj = objs[i]
6 | for (var prop in obj) {
7 | dest[prop] = obj[prop]
8 | }
9 | }
10 |
11 | return dest
12 | }
13 |
14 | export default extend
15 |
--------------------------------------------------------------------------------
/src/scripts/utils/upper-case-first.js:
--------------------------------------------------------------------------------
1 | export default (str) => {
2 | if (str == null) {
3 | return ''
4 | }
5 | return str.charAt(0).toUpperCase() + str.substr(1)
6 | }
7 |
--------------------------------------------------------------------------------
/test/index.js:
--------------------------------------------------------------------------------
1 | var test = require('tape')
2 |
3 | var moha = require('../es5/')
4 |
5 | test('Improving Life Experiences', function(t) {
6 | t.plan(1)
7 |
8 | t.equal(moha.lifeExp('我是最好的'), '我是坠吼滴')
9 | })
10 |
--------------------------------------------------------------------------------