1 | ;
|
2 | var __assign = (this && this.__assign) || Object.assign || function(t) {
|
3 | for (var s, i = 1, n = arguments.length; i < n; i++) {
|
4 | s = arguments[i];
|
5 | for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
6 | t[p] = s[p];
|
7 | }
|
8 | return t;
|
9 | };
|
10 | var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
11 | return new (P || (P = Promise))(function (resolve, reject) {
|
12 | function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
13 | function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
14 | function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
|
15 | step((generator = generator.apply(thisArg, _arguments || [])).next());
|
16 | });
|
17 | };
|
18 | var __generator = (this && this.__generator) || function (thisArg, body) {
|
19 | var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
20 | return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
21 | function verb(n) { return function (v) { return step([n, v]); }; }
|
22 | function step(op) {
|
23 | if (f) throw new TypeError("Generator is already executing.");
|
24 | while (_) try {
|
25 | if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
26 | if (y = 0, t) op = [op[0] & 2, t.value];
|
27 | switch (op[0]) {
|
28 | case 0: case 1: t = op; break;
|
29 | case 4: _.label++; return { value: op[1], done: false };
|
30 | case 5: _.label++; y = op[1]; op = [0]; continue;
|
31 | case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
32 | default:
|
33 | if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
34 | if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
35 | if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
36 | if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
37 | if (t[2]) _.ops.pop();
|
38 | _.trys.pop(); continue;
|
39 | }
|
40 | op = body.call(thisArg, _);
|
41 | } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
42 | if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
43 | }
|
44 | };
|
45 | Object.defineProperty(exports, "__esModule", { value: true });
|
46 | require('source-map-support').install();
|
47 | require('tsconfig-paths').register();
|
48 | var init_1 = require("./init");
|
49 | var _ = require('lodash');
|
50 | // // 临时调试线上日志打印
|
51 | // //framework/index.ts(8,13): error TS2339: Property 'setLogLevel' does not exist on type 'Console'
|
52 | // exports.handler = async function (event, context, callback) {
|
53 | // // console.setLogLevel('error') 不能写在此会导致编译错误阿里云自己扩展的私有方法
|
54 | // console.log('xxxxx', 'yyyyy', 'zzzzzz')
|
55 | // console.error('xxxxx1', 'yyyyy1', 'zzzzzz1')
|
56 | // let out = '<html><body>zzzzzz</body></html>'
|
57 | // let htmlResponse = {
|
58 | // isBase64Encoded: true,
|
59 | // statusCode: 200,
|
60 | // headers: {
|
61 | // "Content-type": "text/html; charset=utf-8",
|
62 | // },
|
63 | // // base64 encode body so it can be safely returned as JSON value
|
64 | // body: new Buffer(out as string).toString('base64')
|
65 | // }
|
66 | // callback(null, htmlResponse)
|
67 | // }
|
68 | // 基于阿里云的函数计算统一入口的路由处理
|
69 | exports.handler = function (event, context, __callback__) {
|
70 | return __awaiter(this, void 0, void 0, function () {
|
71 | var callback, evt, jsonResponse, jsonResponse, urlBase, url, bIsNeedRedirect, domain, __cors__, __api__, __url__, __header__, param, out, _a, post, body, err_1, cookie, setCookie, htmlResponse, jsonResponse, err_2;
|
72 | return __generator(this, function (_b) {
|
73 | switch (_b.label) {
|
74 | case 0:
|
75 | // 重置请求上下文环境变量
|
76 | xreset();
|
77 | // xlog('请求的参数event',event)
|
78 | // xlog('请求的参数context',context)
|
79 | // TODO 增加对于定时器的功能模拟实现
|
80 | // 调试打印请求的输入和输出方便准确的定位调试线上的响应信息
|
81 | xlog('$$$$1111=>' + event.toString());
|
82 | callback = function (context, out) {
|
83 | xlog('$$$$=>', out.body ? Object.assign({}, out, { body: xbase64decode(out.body) }) : out);
|
84 | __callback__(context, out);
|
85 | };
|
86 | evt = JSON.parse(event.toString());
|
87 | // xlog('请求的参数evt',evt)
|
88 | // FIXME yg 定制 ----- 暂时
|
89 | if (/MP_verify_KEtrfArJjFUvBw93\.txt$/.test(evt.path)) {
|
90 | jsonResponse = {
|
91 | isBase64Encoded: false,
|
92 | statusCode: 200,
|
93 | headers: {
|
94 | "Content-type": "text/plain",
|
95 | },
|
96 | body: 'KEtrfArJjFUvBw93'
|
97 | };
|
98 | return [2 /*return*/, callback(null, jsonResponse)];
|
99 | }
|
100 | // FIXME 蜜豆游学 定制 ----- 暂时
|
101 | if (/MP_verify_fQngODKLLpay3tw5\.txt$/.test(evt.path)) {
|
102 | jsonResponse = {
|
103 | isBase64Encoded: false,
|
104 | statusCode: 200,
|
105 | headers: {
|
106 | "Content-type": "text/plain",
|
107 | },
|
108 | body: 'MP_verify_fQngODKLLpay3tw5'
|
109 | };
|
110 | return [2 /*return*/, callback(null, jsonResponse)];
|
111 | }
|
112 | // console.log('header中的参数:',evt['headers'])
|
113 | // console.log('header中的数据:',JSON.stringify(evt['headers']))
|
114 | // FIXME yg ====> 特殊路径处理
|
115 | if (evt.httpMethod && evt['headers']['CA-Host'] && /[a-zA-Z0-9-_.]*\.youngget\.com$/.test(evt['headers']['CA-Host']) && /^\/share\/[0-9a-zA-Z\/+=]{1,}$/.test(evt.path)) {
|
116 | urlBase = evt.path.split("/share/");
|
117 | url = xbase64decode(urlBase[urlBase.length - 1]);
|
118 | // console.log('查看解码之后的路径:',url)
|
119 | callback(null, {
|
120 | statusCode: 301,
|
121 | headers: {
|
122 | "Location": url,
|
123 | },
|
124 | });
|
125 | return [2 /*return*/];
|
126 | }
|
127 | // TODO 需要对于事件定时器进行统一的约定在应用层可扩展自定义相关定时器等事件类型
|
128 | if (evt['triggerName']) {
|
129 | // 对定时触发器的统一拦截处理
|
130 | switch (evt['triggerName']) {
|
131 | // FC线上容器的预热定时器预置到开发框架上统一集成支持
|
132 | case '__axjs-preheat-timer__':
|
133 | // // 获取请求参数的配置数据
|
134 | // try {
|
135 | // let payload = JSON.parse(evt['payload'])
|
136 | // xassert(payload['url'] && payload['timeout'])
|
137 | // await xpost(payload['url'], payload['param'], undefined, payload['timeout'])
|
138 | // } catch (err) {
|
139 | // // ignore error
|
140 | // xlog(JSON.stringify(xerror(err)).replace(/\r/g, '').replace(/\n/g, ''))
|
141 | // }
|
142 | break;
|
143 | }
|
144 | callback(null, {
|
145 | statusCode: 200,
|
146 | });
|
147 | return [2 /*return*/];
|
148 | }
|
149 | // else if (evt['path'] === '/__axjs-preheat-timer__') {
|
150 | // // 预热api网关的空请求心跳接口实现
|
151 | // return
|
152 | // }
|
153 | // FIXME 全站HTTPS开启将HTTP请求做重定向跳转以及主域名跳转(例如youngget.com跳转到www.youngget.com)
|
154 | // 由于api网关暂不支持在nginx上配置重定向跳转,需要在框架层面上做跳转配置支持此特性,解决部分老浏览器无法自动跳转问题。
|
155 | // 仅仅对根请求开放支持HTTP和HTTPS双重请求,以便于支持自动重定向跳转功能实现。
|
156 | if (evt.httpMethod == 'GET') {
|
157 | bIsNeedRedirect = false;
|
158 | domain = evt['headers']['CA-Host'];
|
159 | if (/^[0-9a-zA-Z_-]+\.[0-9a-zA-Z_-]+$/.test(domain)) {
|
160 | domain = 'www.' + domain; // 将一级域名强制跳转到www二级主域名上符合国际惯例约定俗成的规范标准化
|
161 | bIsNeedRedirect = true;
|
162 | }
|
163 | if (evt['headers']['X-Forwarded-Proto'] == 'http') {
|
164 | bIsNeedRedirect = true;
|
165 | }
|
166 | if (bIsNeedRedirect) {
|
167 | callback(null, {
|
168 | statusCode: 301,
|
169 | headers: {
|
170 | "Location": "https://" + domain + "/",
|
171 | },
|
172 | });
|
173 | return [2 /*return*/];
|
174 | }
|
175 | }
|
176 | // 根据API网关设置的环境常量参数正确配置线上版本的运行环境,取代AONE的本地、日常、预发、灰度等环境部署支持开发。
|
177 | // 全局变量仅仅用于放在整个应用生命周期变量
|
178 | global['__env__'] = _.get(evt, 'headers.__env__', 'prod');
|
179 | __cors__ = {};
|
180 | // FIXME yg定制需要生产环境下支付宝回调请求是跨域的需要支持options的跨域请求(临时放开限制,需要配置允许跨域的白名单列表在API网关上设置)
|
181 | // if (global['__env__'] !== 'prod' && global['__env__'] !== 'gray') {
|
182 | // // 非生产环境或灰度环境,需要禁用CORS功能禁止跨域访问增加安全性。
|
183 | // if (evt.headers.origin) {
|
184 | // // 获取源站动态允许请求跨域 (FIXME 需要进行安全限制对来源服务器网址合法性进行安全限制,本地开发调试全部放开请求)
|
185 | // __cors__['Access-Control-Allow-Origin'] = evt.headers.origin
|
186 | // // __cors__['Access-Control-Allow-Origin'] = '*' // 不能设置为任意值浏览器有安全限制
|
187 | // }
|
188 | // __cors__['Access-Control-Allow-Credentials'] = 'true'
|
189 | // __cors__['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept'
|
190 | // __cors__['Access-Control-Allow-Methods'] = 'POST, OPTIONS'
|
191 | // }
|
192 | if (evt.headers.origin) {
|
193 | // 获取源站动态允许请求跨域 (FIXME 需要进行安全限制对来源服务器网址合法性进行安全限制,本地开发调试全部放开请求)
|
194 | __cors__['Access-Control-Allow-Origin'] = evt.headers.origin;
|
195 | // __cors__['Access-Control-Allow-Origin'] = '*' // 不能设置为任意值浏览器有安全限制
|
196 | }
|
197 | __cors__['Access-Control-Allow-Credentials'] = 'true';
|
198 | __cors__['Access-Control-Allow-Headers'] = 'Origin, X-Requested-With, Content-Type, Accept';
|
199 | __cors__['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'; // 支持协议约定格式
|
200 | // 支持跨域的验证请求方法的合法性规避掉过滤掉不安全的请求。
|
201 | switch (evt.httpMethod) {
|
202 | case 'GET':
|
203 | case 'POST':
|
204 | break;
|
205 | case 'OPTIONS':
|
206 | // if (global['__env__'] == 'prod' || global['__env__'] == 'gray') {
|
207 | // // 生产和灰度环境下禁止跨域OPTIONS请求以便于增强安全性
|
208 | // callback(null, {
|
209 | // statusCode: 501,
|
210 | // })
|
211 | // } else {
|
212 | // // 非生产和灰度环境下才允许支持跨域OPTIONS请求
|
213 | // callback(null, {
|
214 | // statusCode: 200,
|
215 | // headers: {
|
216 | // ...__cors__,
|
217 | // },
|
218 | // })
|
219 | // }
|
220 | // FIXME yg定制需要生产环境下支付宝回调请求是跨域的需要支持options的跨域请求(临时放开限制,需要配置允许跨域的白名单列表在API网关上设置)
|
221 | callback(null, {
|
222 | statusCode: 200,
|
223 | headers: __assign({}, __cors__),
|
224 | });
|
225 | return [2 /*return*/];
|
226 | default:
|
227 | // 禁止任何的非法请求严格进行约定限制
|
228 | callback(null, {
|
229 | statusCode: 502,
|
230 | });
|
231 | return [2 /*return*/];
|
232 | }
|
233 | global['__evt__'] = event.toString(); // FIXME 需要设计上下文定义请求实例生命周期变量
|
234 | __api__ = _.get(evt, 'headers.__api__', evt.path) // 最终控制器与app子目录下的ts文件保持完全的一一映射关系。
|
235 | ;
|
236 | __url__ = evt['headers']['X-Forwarded-Proto'] + '://' + evt['headers']['CA-Host'] + evt['path'];
|
237 | __header__ = evt['headers'];
|
238 | param = Object.assign({ __api__: __api__, __url__: __url__, __header__: __header__ }, // header请求中的两个框架层面上的预定义参数 TODO 需要移除掉并非应用关心的内容
|
239 | evt.pathParameters || {}, // 路由重写参数 domain/[a]/[b]?xxx (可被GET参数覆盖)
|
240 | evt.queryParameters || {} // GET请求参数 domain/path?a=x&b=x
|
241 | );
|
242 | out = {};
|
243 | _a = evt.httpMethod;
|
244 | switch (_a) {
|
245 | case 'GET': return [3 /*break*/, 1];
|
246 | case 'POST': return [3 /*break*/, 2];
|
247 | }
|
248 | return [3 /*break*/, 6];
|
249 | case 1: return [3 /*break*/, 7];
|
250 | case 2:
|
251 | _b.trys.push([2, 3, , 5]);
|
252 | post = {};
|
253 | if (_.isString(evt.body)) {
|
254 | body = evt.body;
|
255 | if (evt.isBase64Encoded) {
|
256 | body = new Buffer(evt.body, 'base64').toString();
|
257 | }
|
258 | post = init_1.parse_post_param(evt['headers'], body);
|
259 | }
|
260 | param = Object.assign(param, post); // 用post参数覆盖掉get参数,用于灵活的设置请求参数兼容get和post两种方法方便开发调试。
|
261 | return [3 /*break*/, 5];
|
262 | case 3:
|
263 | err_1 = _b.sent();
|
264 | // xlog(err, evt.httpMethod, evt.body)
|
265 | return [4 /*yield*/, xwarn(err_1)
|
266 | // 400 Bad Request 客户端请求的语法错误,服务器无法理解
|
267 | ];
|
268 | case 4:
|
269 | // xlog(err, evt.httpMethod, evt.body)
|
270 | _b.sent();
|
271 | // 400 Bad Request 客户端请求的语法错误,服务器无法理解
|
272 | callback(null, {
|
273 | statusCode: 503,
|
274 | });
|
275 | return [2 /*return*/];
|
276 | case 5: return [3 /*break*/, 7];
|
277 | case 6:
|
278 | // xlog(evt.httpMethod, evt.body)
|
279 | // 400 Bad Request 客户端请求的语法错误,服务器无法理解
|
280 | callback(null, {
|
281 | statusCode: 504,
|
282 | });
|
283 | return [2 /*return*/];
|
284 | case 7:
|
285 | _b.trys.push([7, 9, , 11]);
|
286 | console.log('进入try');
|
287 | cookie = _.get(evt['headers'], 'Cookie', undefined);
|
288 | console.log('获取cookie信息', JSON.stringify(cookie));
|
289 | if (!cookie) {
|
290 | cookie = _.get(evt['headers'], 'cookie', '');
|
291 | }
|
292 | global['__request_cookies__'] = require('cookie').parse(cookie);
|
293 | console.log('赋值给__request_cookies__', global['__request_cookies__']);
|
294 | // 获取use-agent请求头部信息
|
295 | global['__user_agent__'] = evt['headers']['User-Agent'];
|
296 | console.log('赋值给__user_agent__', global['__user_agent__']);
|
297 | // 获取客户端的IP地址信息
|
298 | global['__client_ip__'] = evt['headers']['X-Real-IP'];
|
299 | console.log('赋值给__client_ip__', global['__client_ip__']);
|
300 | // TODO WEB请求需要对404页面以及ERROR页面进行兼容处理(在framework内部进行细节的错误判断在out中透传status的http的状态吗正确错误返回)
|
301 | // 404 Not Found 服务器无法根据客户端的请求找到资源(网页)。通过此代码,网站设计人员可设置"您所请求的资源无法找到"的个性页面
|
302 | // 403 Forbidden 服务器理解请求客户端的请求,但是拒绝执行此请求(权限验证处理错误)
|
303 | // console.log('查看框架是否又错')
|
304 | console.log('__api__是否出错', __api__);
|
305 | return [4 /*yield*/, init_1.request_process(__api__, param)];
|
306 | case 8:
|
307 | out = _b.sent();
|
308 | console.log('返回的out值', JSON.stringify(out));
|
309 | if (_.isEmpty(out)) {
|
310 | // 对于nowrap的情况做特殊容错处理
|
311 | out = undefined;
|
312 | }
|
313 | setCookie = { 'Set-Cookie': undefined };
|
314 | if (!_.isEmpty(global['__respond_cookies__'])) {
|
315 | setCookie['Set-Cookie'] = _.values(global['__respond_cookies__']);
|
316 | }
|
317 | // console.log('查看redirect_url的值',global['__redirect_url__'])
|
318 | if (global['__redirect_url__']) {
|
319 | // console.log('进入第一个选项')
|
320 | callback(null, {
|
321 | statusCode: 302,
|
322 | headers: __assign({ "Location": global['__redirect_url__'] }, setCookie),
|
323 | });
|
324 | global['__redirect_url__'] = undefined;
|
325 | }
|
326 | else if (_.isString(out)) {
|
327 | htmlResponse = {
|
328 | isBase64Encoded: true,
|
329 | statusCode: 200,
|
330 | headers: __assign({ "Content-type": "text/html; charset=utf-8" }, setCookie, __cors__),
|
331 | // base64 encode body so it can be safely returned as JSON value
|
332 | body: new Buffer(out).toString('base64')
|
333 | };
|
334 | callback(null, htmlResponse);
|
335 | }
|
336 | else {
|
337 | jsonResponse = {
|
338 | isBase64Encoded: true,
|
339 | statusCode: 200,
|
340 | headers: __assign({ "Content-type": "application/json" }, __cors__),
|
341 | // base64 encode body so it can be safely returned as JSON value
|
342 | body: new Buffer(out ? JSON.stringify(out) : '').toString('base64')
|
343 | };
|
344 | callback(null, jsonResponse);
|
345 | }
|
346 | return [3 /*break*/, 11];
|
347 | case 9:
|
348 | err_2 = _b.sent();
|
349 | // 通知框架自身实现逻辑的意外报错(框架自身不论何种情况都应该正常工作,一旦出现此问题大多数情况是框架自身问题或者流量引发的运维问题)
|
350 | return [4 /*yield*/, xwarn({
|
351 | __api__: __api__, __url__: __url__, param: param, message: err_2.message, stack: xstack(err_2)
|
352 | })
|
353 | // 500 Internal Server Error 服务器内部错误,无法完成请求
|
354 | ];
|
355 | case 10:
|
356 | // 通知框架自身实现逻辑的意外报错(框架自身不论何种情况都应该正常工作,一旦出现此问题大多数情况是框架自身问题或者流量引发的运维问题)
|
357 | _b.sent();
|
358 | // 500 Internal Server Error 服务器内部错误,无法完成请求
|
359 | callback(null, { statusCode: 505 });
|
360 | return [3 /*break*/, 11];
|
361 | case 11: return [2 /*return*/];
|
362 | }
|
363 | });
|
364 | });
|
365 | };
|
366 | // API参数的识别逻辑,为普通字符串路径定义与app下的ts文件路由完全一一对应,优先取HEADER中的定义,再取GET中的形参定义或者POST形参定义进行参数请求的覆盖处理。
|
367 | // PARAM请求的参数处理要求为BASE64编码化的JSON字符串。
|
368 | // "event": {
|
369 | // "body": "ewoJImFwaSI6ICIvYS9iL2MiLAoJInBhcmFtIjogImFzZGZhc2RmYXNkZiIKfQ==", => 对应于POST请求数据
|
370 | // "headers": {
|
371 | // "X-Ca-Api-Gateway": "B25CD51B-5815-4775-9EAB-6D481BC1AE17",
|
372 | // "__api__": "/web/mobile/test", =》 自定义转义PATH的路径信息对于SEO优化兼容处理(也可以在GET或POST请求中传递对应参数)
|
373 | // "X-Forwarded-For": "42.120.74.88",
|
374 | // "Content-Type": "application/json"
|
375 | // },
|
376 | // "httpMethod": "POST",
|
377 | // "isBase64Encoded": true,
|
378 | // "path": "/", =》 没有意义用于前端根据需要自己进行扩展别名映射处理,后端的控制器不以此为标准,可以对同一个控制器定义N个不同的路径标识。
|
379 | // "pathParameters": {},
|
380 | // "queryParameters": {} => 对应于GET请求数据
|
381 | // },
|
382 | // "query": {},
|
383 | // "context": {
|
384 | // "requestId": "B25CD51B-5815-4775-9EAB-6D481BC1AE17",
|
385 | // "credentials": {
|
386 | // "accessKeyId": "",
|
387 | // "accessKeySecret": "",
|
388 | // "securityToken": ""
|
389 | // },
|
390 | // "function": {
|
391 | // "name": "test",
|
392 | // "handler": "index.handler",
|
393 | // "memory": 128,
|
394 | // "timeout": 300
|
395 | // },
|
396 | // "services": {
|
397 | // "name": "alilang",
|
398 | // "logProject": "",
|
399 | // "logStore": ""
|
400 | // },
|
401 | // "region": "cn-shanghai",
|
402 | // "accountId": "1734066057689528"
|
403 | // }
|
404 | // }
|
405 | // 最新版本event的API网关的FC返回数据格式:
|
406 | // CA-Host请求域名、
|
407 | // X-Forwarded-Proto
|
408 | // "path": "/test", ==》》基本上可以拼接出__url__参数可以省略掉此冗余参数配置了。
|
409 | // ==》》借助route.map.ts文件的映射关系定义省略掉__api__配置进一步简化网关应用。
|
410 | // "httpMethod": "GET",
|
411 | // "isBase64Encoded": true,
|
412 | // "X-Forwarded-For": "42.120.74.103", // 客户端请求IP地址用户判定所属区域信息海外访问问题优化依赖点
|
413 | // "X-Real-IP": "42.120.74.103",
|
414 | // Cookie
|
415 | // User-Agent =>> PC站和M站自适应问题
|
416 | // Accept-Language =>> 浏览器客户端的语言类型自动适配多语言架构设计问题
|
417 | // let x = {
|
418 | // "body": "",
|
419 | // "headers": {
|
420 | // "X-Ca-Api-Gateway": "B276F77B-334E-4857-AE64-65BAFD419E2A",
|
421 | // "Cookie": "cna=r5snEzzOvA0CASp4Smdq+II/; UM_distinctid=162bcd61d9111cd-080e0f43e6b60d-33697b04-13c680-162bcd61d92c86; _tb_token_=H8U7BqixF3YVR3GnhMRz; NEW2_ACR_JSESSIONID=VM566F91-K5CP8QIVMQTSAH3C4H5X1-DRIHYJHJ-QE2; _new_cr_session0=1AbLByOMHeZe3G41KYd5WcPdC%2Fi8qvGHUBTK8Fbrfx8Soi%2BHELuxxA6jros7W%2FqC1YtebgB3auEF5lu1SCzUzTkt6v%2FiFeN%2FptbvBRziYEGXSEVhWnUlBR2tfpjrXMnIcfb2%2FwnGkH4vkeMIJ1Bvuw%3D%3D; emplId=149337; hrc_sidebar=open; traceId=7d4b16de-74bc-4eac-884b-54ca0354e4aa; SSO_LANG=ZH-CN; SSO_EMPID_HASH=9db1ed21402f7c36674b5e6e6de1fc68; animate_date=201864; aa=xxxxxxx; cn_1260001221_dplus=%7B%22distinct_id%22%3A%20%22162bcd61d9111cd-080e0f43e6b60d-33697b04-13c680-162bcd61d92c86%22%2C%22sp%22%3A%20%7B%22%24_sessionid%22%3A%200%2C%22%24_sessionTime%22%3A%201528086234%2C%22%24dp%22%3A%200%2C%22%24_sessionPVTime%22%3A%201528086234%7D%7D; isg=BDw8SonyS9utyn5fedYRe-uRDdzwNAD0-51BHha9_ScJ4dxrNkWw77KQxQmZqRi3",
|
422 | // "X-Forwarded-Proto": "https",
|
423 | // "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.181 Safari/537.36",
|
424 | // "__url__": "https://toufang.alibaba-inc.com/test",
|
425 | // "CA-Host": "toufang.alibaba-inc.com",
|
426 | // "Cache-Control": "max-age=0",
|
427 | // "upgrade-insecure-requests": "1",
|
428 | // "Accept-Language": "zh-CN,zh;q=0.9",
|
429 | // "__api__": "/web/test/test",
|
430 | // "Accept-Encoding": "gzip, deflate, br",
|
431 | // "X-Forwarded-For": "42.120.74.103",
|
432 | // "X-Real-IP": "42.120.74.103",
|
433 | // "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"
|
434 | // },
|
435 | // "httpMethod": "GET",
|
436 | // "isBase64Encoded": true,
|
437 | // "path": "/test",
|
438 | // "pathParameters": {},
|
439 | // "queryParameters": {}
|
440 | // }
|
441 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXgtY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiaW5kZXgtY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFBO0FBQ3ZDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFBO0FBRXBDLCtCQUF3RDtBQUV4RCxJQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDLENBQUE7QUFFM0IsZ0JBQWdCO0FBQ2hCLG9HQUFvRztBQUNwRyxnRUFBZ0U7QUFDaEUsK0RBQStEO0FBQy9ELDhDQUE4QztBQUM5QyxtREFBbUQ7QUFDbkQsbURBQW1EO0FBQ25ELDJCQUEyQjtBQUMzQixpQ0FBaUM7QUFDakMsMkJBQTJCO0FBQzNCLHFCQUFxQjtBQUNyQiwwREFBMEQ7QUFDMUQsYUFBYTtBQUNiLDJFQUEyRTtBQUMzRSw2REFBNkQ7QUFDN0QsUUFBUTtBQUNSLG1DQUFtQztBQUNuQyxJQUFJO0FBRUosc0JBQXNCO0FBQ3RCLE9BQU8sQ0FBQyxPQUFPLEdBQUcsVUFBZ0IsS0FBSyxFQUFFLE9BQU8sRUFBRSxZQUFZOzs7Ozs7b0JBQzFELGNBQWM7b0JBQ2QsTUFBTSxFQUFFLENBQUE7b0JBQ1IsMkJBQTJCO29CQUMzQiwrQkFBK0I7b0JBRy9CLHNCQUFzQjtvQkFFdEIsK0JBQStCO29CQUMvQixJQUFJLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFBO29CQUMvQixRQUFRLEdBQUcsVUFBQyxPQUFPLEVBQUUsR0FBRzt3QkFDMUIsSUFBSSxDQUFDLFFBQVEsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBQyxJQUFJLEVBQUUs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K0JBQStCO0FBQy9CLHVCQUF1QjtBQUN2Qiw0QkFBNEI7QUFDNUIsNEJBQTRCO0FBQzVCLElBQUkiLCJzb3VyY2VzQ29udGVudCI6WyJyZXF1aXJlKCdzb3VyY2UtbWFwLXN1cHBvcnQnKS5pbnN0YWxsKClcbnJlcXVpcmUoJ3RzY29uZmlnLXBhdGhzJykucmVnaXN0ZXIoKVxuXG5pbXBvcnQge3JlcXVlc3RfcHJvY2VzcywgcGFyc2VfcG9zdF9wYXJhbX0gZnJvbSAnLi9pbml0J1xuXG5jb25zdCBfID0gcmVxdWlyZSgnbG9kYXNoJylcblxuLy8gLy8g5Li05pe26LCD6K+V57q/5LiK5pel5b+X5omT5Y2wXG4vLyAvL2ZyYW1ld29yay9pbmRleC50cyg4LDEzKTogZXJyb3IgVFMyMzM5OiBQcm9wZXJ0eSAnc2V0TG9nTGV2ZWwnIGRvZXMgbm90IGV4aXN0IG9uIHR5cGUgJ0NvbnNvbGUnXG4vLyBleHBvcnRzLmhhbmRsZXIgPSBhc3luYyBmdW5jdGlvbiAoZXZlbnQsIGNvbnRleHQsIGNhbGxiYWNrKSB7XG4vLyAgICAgLy8gY29uc29sZS5zZXRMb2dMZXZlbCgnZXJyb3InKSDkuI3og73lhpnlnKjmraTkvJrlr7zoh7TnvJbor5HplJnor6/pmL/ph4zkupHoh6rlt7HmianlsZXnmoTnp4HmnInmlrnms5Vcbi8vICAgICBjb25zb2xlLmxvZygneHh4eHgnLCAneXl5eXknLCAnenp6enp6Jylcbi8vICAgICBjb25zb2xlLmVycm9yKCd4eHh4eDEnLCAneXl5eXkxJywgJ3p6enp6ejEnKVxuLy8gICAgIGxldCBvdXQgPSAnPGh0bWw+PGJvZHk+enp6enp6PC9ib2R5PjwvaHRtbD4nXG4vLyAgICAgbGV0IGh0bWxSZXNwb25zZSA9IHtcbi8vICAgICAgICAgaXNCYXNlNjRFbmNvZGVkOiB0cnVlLFxuLy8gICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4vLyAgICAgICAgIGhlYWRlcnM6IHtcbi8vICAgICAgICAgICAgIFwiQ29udGVudC10eXBlXCI6IFwidGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04XCIsXG4vLyAgICAgICAgIH0sXG4vLyAgICAgICAgIC8vIGJhc2U2NCBlbmNvZGUgYm9keSBzbyBpdCBjYW4gYmUgc2FmZWx5IHJldHVybmVkIGFzIEpTT04gdmFsdWVcbi8vICAgICAgICAgYm9keTogbmV3IEJ1ZmZlcihvdXQgYXMgc3RyaW5nKS50b1N0cmluZygnYmFzZTY0Jylcbi8vICAgICB9XG4vLyAgICAgY2FsbGJhY2sobnVsbCwgaHRtbFJlc3BvbnNlKVxuLy8gfVxuXG4vLyDln7rkuo7pmL/ph4zkupHnmoTlh73mlbDorqHnrpfnu5/kuIDlhaXlj6PnmoTot6/nlLHlpITnkIZcbmV4cG9ydHMuaGFuZGxlciA9IGFzeW5jIGZ1bmN0aW9uIChldmVudCwgY29udGV4dCwgX19jYWxsYmFja19fKSB7XG4gICAgLy8g6YeN572u6K+35rGC5LiK5LiL5paH546v5aKD5Y+Y6YePXG4gICAgeHJlc2V0KClcbiAgICAvLyB4bG9nKCfor7fmsYLnmoTlj4LmlbBldmVudCcsZXZlbnQpXG4gICAgLy8geGxvZygn6K+35rGC55qE5Y+C5pWwY29udGV4dCcsY29udGV4dClcblxuXG4gICAgLy8gVE9ETyDlop7liqDlr7nkuo7lrprml7blmajnmoTlip/og73mqKHmi5/lrp7njrBcblxuICAgIC8vIOiwg+ivleaJk+WNsOivt+axgueahOi+k+WFpeWSjOi+k+WHuuaWueS+v+WHhuehrueahOWumuS9jeiwg+ivlee6v+S4iueahOWTjeW6lOS/oeaBr1xuICAgIHhsb2coJyQkJCQxMTExPT4nICsgZXZlbnQudG9TdHJpbmcoKSlcbiAgICBjb25zdCBjYWxsYmFjayA9IChjb250ZXh0LCBvdXQpID0+IHtcbiAgICAgICAgeGxvZygnJCQkJD0+Jywgb3V0LmJvZHkgPyBPYmplY3QuYXNzaWduKHt9LCBvdXQsIHtib2R5OiB4YmFzZTY0ZGVjb2RlKG91dC5ib2R5KX0pIDogb3V0KVxuICAgICAgICBfX2NhbGxiYWNrX18oY29udGV4dCwgb3V0KVxuICAgIH1cblxuICAgIGxldCBldnQgPSBKU09OLnBhcnNlKGV2ZW50LnRvU3RyaW5nKCkpXG4gICAgLy8geGxvZygn6K+35rGC55qE5Y+C5pWwZXZ0JyxldnQpXG5cbiAgIC8vIEZJWE1FIHlnIOWumuWItiAgLS0tLS0g5pqC5pe2XG4gICAgaWYoL01QX3ZlcmlmeV9LRXRyZkFySmpGVXZCdzkzXFwudHh0JC8udGVzdChldnQucGF0aCkpe1xuICAgICAgICBsZXQganNvblJlc3BvbnNlID0ge1xuICAgICAgICAgICAgaXNCYXNlNjRFbmNvZGVkOiBmYWxzZSxcbiAgICAgICAgICAgIHN0YXR1c0NvZGU6IDIwMCxcbiAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICBcIkNvbnRlbnQtdHlwZVwiOiBcInRleHQvcGxhaW5cIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBib2R5OiAnS0V0cmZBckpqRlV2Qnc5MydcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY2FsbGJhY2sobnVsbCwganNvblJlc3BvbnNlKVxuICAgIH1cbiAgICAgLy8gRklYTUUg6Jyc6LGG5ri45a2mIOWumuWItiAgLS0tLS0g5pqC5pe2XG4gICAgIGlmKC9NUF92ZXJpZnlfZlFuZ09ES0xMcGF5M3R3NVxcLnR4dCQvLnRlc3QoZXZ0LnBhdGgpKXtcbiAgICAgICAgbGV0IGpzb25SZXNwb25zZSA9IHtcbiAgICAgICAgICAgIGlzQmFzZTY0RW5jb2RlZDogZmFsc2UsXG4gICAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgXCJDb250ZW50LXR5cGVcIjogXCJ0ZXh0L3BsYWluXCIsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAgYm9keTogJ01QX3ZlcmlmeV9mUW5nT0RLTExwYXkzdHc1J1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjYWxsYmFjayhudWxsLCBqc29uUmVzcG9uc2UpXG4gICAgfVxuICAgIC8vIGNvbnNvbGUubG9nKCdoZWFkZXLkuK3nmoTlj4LmlbDvvJonLGV2dFsnaGVhZGVycyddKVxuICAgIC8vIGNvbnNvbGUubG9nKCdoZWFkZXLkuK3nmoTmlbDmja46JyxKU09OLnN0cmluZ2lmeShldnRbJ2hlYWRlcnMnXSkpXG4gICAgLy8gRklYTUUgeWcgID09PT0+IOeJueauiui3r+W+hOWkhOeQhlxuICAgIGlmIChldnQuaHR0cE1ldGhvZCAmJiBldnRbJ2hlYWRlcnMnXVsnQ0EtSG9zdCddICYmIC9bYS16QS1aMC05LV8uXSpcXC55b3VuZ2dldFxcLmNvbSQvLnRlc3QoZXZ0WydoZWFkZXJzJ11bJ0NBLUhvc3QnXSkgJiYgL15cXC9zaGFyZVxcL1swLTlhLXpBLVpcXC8rPV17MSx9JC8udGVzdChldnQucGF0aCkpIHtcbiAgICAgICAgbGV0IHVybEJhc2UgPSBldnQucGF0aC5zcGxpdChcIi9zaGFyZS9cIilcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ+afpeeci+WIhuino+WIhuino+S5i+WQjueahOWcsOWdgCcsdXJsQmFzZSlcbiAgICAgICAgbGV0IHVybCA9IHhiYXNlNjRkZWNvZGUodXJsQmFzZVt1cmxCYXNlLmxlbmd0aCAtIDFdKVxuICAgICAgICAvLyBjb25zb2xlLmxvZygn5p+l55yL6Kej56CB5LmL5ZCO55qE6Lev5b6E77yaJyx1cmwpXG4gICAgICAgIGNhbGxiYWNrKG51bGwsIHtcbiAgICAgICAgICAgIHN0YXR1c0NvZGU6IDMwMSwgLy8g5rC45LmF6YeN5a6a5ZCRXG4gICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgXCJMb2NhdGlvblwiOiB1cmwsIC8vIOeJueauiui3r+W+hOWkhOeQhlxuICAgICAgICAgICAgfSxcbiAgICAgICAgfSlcbiAgICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgLy8gVE9ETyDpnIDopoHlr7nkuo7kuovku7blrprml7blmajov5vooYznu5/kuIDnmoTnuqblrprlnKjlupTnlKjlsYLlj6/mianlsZXoh6rlrprkuYnnm7jlhbPlrprml7blmajnrYnkuovku7bnsbvlnotcbiAgICBpZiAoZXZ0Wyd0cmlnZ2VyTmFtZSddKSB7XG4gICAgICAgIC8vIOWvueWumuaXtuinpuWPkeWZqOeahOe7n+S4gOaLpuaIquWkhOeQhlxuICAgICAgICBzd2l0Y2ggKGV2dFsndHJpZ2dlck5hbWUnXSkge1xuICAgICAgICAgICAgLy8gRkPnur/kuIrlrrnlmajnmoTpooTng63lrprml7blmajpooTnva7liLDlvIDlj5HmoYbmnrbkuIrnu5/kuIDpm4bmiJDmlK/mjIFcbiAgICAgICAgICAgIGNhc2UgJ19fYXhqcy1wcmVoZWF0LXRpbWVyX18nOlxuICAgICAgICAgICAgICAgIC8vIC8vIOiOt+WPluivt+axguWPguaVsOeahOmFjee9ruaVsOaNrlxuICAgICAgICAgICAgICAgIC8vIHRyeSB7XG4gICAgICAgICAgICAgICAgLy8gICAgIGxldCBwYXlsb2FkID0gSlNPTi5wYXJzZShldnRbJ3BheWxvYWQnXSlcbiAgICAgICAgICAgICAgICAvLyAgICAgeGFzc2VydChwYXlsb2FkWyd1cmwnXSAmJiBwYXlsb2FkWyd0aW1lb3V0J10pXG4gICAgICAgICAgICAgICAgLy8gICAgIGF3YWl0IHhwb3N0KHBheWxvYWRbJ3VybCddLCBwYXlsb2FkWydwYXJhbSddLCB1bmRlZmluZWQsIHBheWxvYWRbJ3RpbWVvdXQnXSlcbiAgICAgICAgICAgICAgICAvLyB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICAgICAgICAvLyAgICAgLy8gaWdub3JlIGVycm9yXG4gICAgICAgICAgICAgICAgLy8gICAgIHhsb2coSlNPTi5zdHJpbmdpZnkoeGVycm9yKGVycikpLnJlcGxhY2UoL1xcci9nLCAnJykucmVwbGFjZSgvXFxuL2csICcnKSlcbiAgICAgICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgfVxuICAgICAgICBjYWxsYmFjayhudWxsLCB7XG4gICAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgIH0pXG4gICAgICAgIHJldHVyblxuICAgIH1cbiAgICAvLyBlbHNlIGlmIChldnRbJ3BhdGgnXSA9PT0gJy9fX2F4anMtcHJlaGVhdC10aW1lcl9fJykge1xuICAgIC8vICAgICAvLyDpooTng61hcGnnvZHlhbPnmoTnqbror7fmsYLlv4Pot7PmjqXlj6Plrp7njrBcbiAgICAvLyAgICAgcmV0dXJuXG4gICAgLy8gfVxuXG4gICAgLy8gRklYTUUg5YWo56uZSFRUUFPlvIDlkK/lsIZIVFRQ6K+35rGC5YGa6YeN5a6a5ZCR6Lez6L2s5Lul5Y+K5Li75Z+f5ZCN6Lez6L2sKOS+i+WmgnlvdW5nZ2V0LmNvbei3s+i9rOWIsHd3dy55b3VuZ2dldC5jb20pXG4gICAgLy8g55Sx5LqOYXBp572R5YWz5pqC5LiN5pSv5oyB5ZyobmdpbnjkuIrphY3nva7ph43lrprlkJHot7PovazvvIzpnIDopoHlnKjmoYbmnrblsYLpnaLkuIrlgZrot7PovazphY3nva7mlK/mjIHmraTnibnmgKfvvIzop6PlhrPpg6jliIbogIHmtY/op4jlmajml6Dms5Xoh6rliqjot7Povazpl67popjjgIJcbiAgICAvLyDku4Xku4Xlr7nmoLnor7fmsYLlvIDmlL7mlK/mjIFIVFRQ5ZKMSFRUUFPlj4zph43or7fmsYLvvIzku6Xkvr/kuo7mlK/mjIHoh6rliqjph43lrprlkJHot7Povazlip/og73lrp7njrDjgIJcbiAgICBpZiAoZXZ0Lmh0dHBNZXRob2QgPT0gJ0dFVCcpIHtcbiAgICAgICAgbGV0IGJJc05lZWRSZWRpcmVjdCA9IGZhbHNlXG4gICAgICAgIGxldCBkb21haW4gPSBldnRbJ2hlYWRlcnMnXVsnQ0EtSG9zdCddXG4gICAgICAgIGlmICgvXlswLTlhLXpBLVpfLV0rXFwuWzAtOWEtekEtWl8tXSskLy50ZXN0KGRvbWFpbikpIHtcbiAgICAgICAgICAgIGRvbWFpbiA9ICd3d3cuJyArIGRvbWFpbiAvLyDlsIbkuIDnuqfln5/lkI3lvLrliLbot7PovazliLB3d3fkuoznuqfkuLvln5/lkI3kuIrnrKblkIjlm73pmYXmg6/kvovnuqblrprkv5fmiJDnmoTop4TojIPmoIflh4bljJZcbiAgICAgICAgICAgIGJJc05lZWRSZWRpcmVjdCA9IHRydWVcbiAgICAgICAgfVxuICAgICAgICBpZiAoZXZ0WydoZWFkZXJzJ11bJ1gtRm9yd2FyZGVkLVByb3RvJ10gPT0gJ2h0dHAnKSB7XG4gICAgICAgICAgICBiSXNOZWVkUmVkaXJlY3QgPSB0cnVlXG4gICAgICAgIH1cbiAgICAgICAgaWYgKGJJc05lZWRSZWRpcmVjdCkge1xuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwge1xuICAgICAgICAgICAgICAgIHN0YXR1c0NvZGU6IDMwMSwgLy8g5rC45LmF6YeN5a6a5ZCRXG4gICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICBcIkxvY2F0aW9uXCI6IGBodHRwczovLyR7ZG9tYWlufS9gLCAvLyDlhajpg6jph43lrprlkJHliLDpppbpobXkuI3mlK/mjIHpnZ7ms5XnvZHlnYBcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLy8g5qC55o2uQVBJ572R5YWz6K6+572u55qE546v5aKD5bi46YeP5Y+C5pWw5q2j56Gu6YWN572u57q/5LiK54mI5pys55qE6L+Q6KGM546v5aKD77yM5Y+W5LujQU9OReeahOacrOWcsOOAgeaXpeW4uOOAgemihOWPkeOAgeeBsOW6puetieeOr+Wig+mDqOe9suaUr+aMgeW8gOWPkeOAglxuICAgIC8vIOWFqOWxgOWPmOmHj+S7heS7heeUqOS6juaUvuWcqOaVtOS4quW6lOeUqOeUn+WRveWRqOacn+WPmOmHj1xuICAgIGdsb2JhbFsnX19lbnZfXyddID0gXy5nZXQoZXZ0LCAnaGVhZGVycy5fX2Vudl9fJywgJ3Byb2QnKVxuXG4gICAgY29uc3QgX19jb3JzX18gPSB7fVxuICAgIC8vIEZJWE1FIHln5a6a5Yi26ZyA6KaB55Sf5Lqn546v5aKD5LiL5pSv5LuY5a6d5Zue6LCD6K+35rGC5piv6Leo5Z+f55qE6ZyA6KaB5pSv5oyBb3B0aW9uc+eahOi3qOWfn+ivt+axgu+8iOS4tOaXtuaUvuW8gOmZkOWItu+8jOmcgOimgemFjee9ruWFgeiuuOi3qOWfn+eahOeZveWQjeWNleWIl+ihqOWcqEFQSee9keWFs+S4iuiuvue9ru+8iVxuICAgIC8vIGlmIChnbG9iYWxbJ19fZW52X18nXSAhPT0gJ3Byb2QnICYmIGdsb2JhbFsnX19lbnZfXyddICE9PSAnZ3JheScpIHtcbiAgICAvLyAgICAgLy8g6Z2e55Sf5Lqn546v5aKD5oiW54Gw5bqm546v5aKD77yM6ZyA6KaB56aB55SoQ09SU+WKn+iDveemgeatoui3qOWfn+iuv+mXruWinuWKoOWuieWFqOaAp+OAglxuICAgIC8vICAgICBpZiAoZXZ0LmhlYWRlcnMub3JpZ2luKSB7XG4gICAgLy8gICAgICAgICAvLyDojrflj5bmupDnq5nliqjmgIHlhYHorrjor7fmsYLot6jln58gKEZJWE1FIOmcgOimgei/m+ihjOWuieWFqOmZkOWItuWvueadpea6kOacjeWKoeWZqOe9keWdgOWQiOazleaAp+i/m+ihjOWuieWFqOmZkOWItu+8jOacrOWcsOW8gOWPkeiwg+ivleWFqOmDqOaUvuW8gOivt+axgilcbiAgICAvLyAgICAgICAgIF9fY29yc19fWydBY2Nlc3MtQ29udHJvbC1BbGxvdy1PcmlnaW4nXSA9IGV2dC5oZWFkZXJzLm9yaWdpblxuICAgIC8vICAgICAgICAgLy8gX19jb3JzX19bJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbiddID0gJyonIC8vIOS4jeiDveiuvue9ruS4uuS7u+aEj+WAvOa1j+iniOWZqOacieWuieWFqOmZkOWItlxuICAgIC8vICAgICB9XG4gICAgLy8gICAgIF9fY29yc19fWydBY2Nlc3MtQ29udHJvbC1BbGxvdy1DcmVkZW50aWFscyddID0gJ3RydWUnXG4gICAgLy8gICAgIF9fY29yc19fWydBY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzJ10gPSAnT3JpZ2luLCBYLVJlcXVlc3RlZC1XaXRoLCBDb250ZW50LVR5cGUsIEFjY2VwdCdcbiAgICAvLyAgICAgX19jb3JzX19bJ0FjY2Vzcy1Db250cm9sLUFsbG93LU1ldGhvZHMnXSA9ICdQT1NULCBPUFRJT05TJ1xuICAgIC8vIH1cbiAgICBpZiAoZXZ0LmhlYWRlcnMub3JpZ2luKSB7XG4gICAgICAgIC8vIOiOt+WPlua6kOermeWKqOaAgeWFgeiuuOivt+axgui3qOWfnyAoRklYTUUg6ZyA6KaB6L+b6KGM5a6J5YWo6ZmQ5Yi25a+55p2l5rqQ5pyN5Yqh5Zmo572R5Z2A5ZCI5rOV5oCn6L+b6KGM5a6J5YWo6ZmQ5Yi277yM5pys5Zyw5byA5Y+R6LCD6K+V5YWo6YOo5pS+5byA6K+35rGCKVxuICAgICAgICBfX2NvcnNfX1snQWNjZXNzLUNvbnRyb2wtQWxsb3ctT3JpZ2luJ10gPSBldnQuaGVhZGVycy5vcmlnaW5cbiAgICAgICAgLy8gX19jb3JzX19bJ0FjY2Vzcy1Db250cm9sLUFsbG93LU9yaWdpbiddID0gJyonIC8vIOS4jeiDveiuvue9ruS4uuS7u+aEj+WAvOa1j+iniOWZqOacieWuieWFqOmZkOWItlxuICAgIH1cbiAgICBfX2NvcnNfX1snQWNjZXNzLUNvbnRyb2wtQWxsb3ctQ3JlZGVudGlhbHMnXSA9ICd0cnVlJ1xuICAgIF9fY29yc19fWydBY2Nlc3MtQ29udHJvbC1BbGxvdy1IZWFkZXJzJ10gPSAnT3JpZ2luLCBYLVJlcXVlc3RlZC1XaXRoLCBDb250ZW50LVR5cGUsIEFjY2VwdCdcbiAgICBfX2NvcnNfX1snQWNjZXNzLUNvbnRyb2wtQWxsb3ctTWV0aG9kcyddID0gJ0dFVCwgUE9TVCwgT1BUSU9OUycgLy8g5pSv5oyB5Y2P6K6u57qm5a6a5qC85byPXG5cbiAgICAvLyDmlK/mjIHot6jln5/nmoTpqozor4Hor7fmsYLmlrnms5XnmoTlkIjms5XmgKfop4Tpgb/mjonov4fmu6TmjonkuI3lronlhajnmoTor7fmsYLjgIJcbiAgICBzd2l0Y2ggKGV2dC5odHRwTWV0aG9kKSB7XG4gICAgICAgIGNhc2UgJ0dFVCc6XG4gICAgICAgIGNhc2UgJ1BPU1QnOlxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnT1BUSU9OUyc6XG4gICAgICAgICAgICAvLyBpZiAoZ2xvYmFsWydfX2Vudl9fJ10gPT0gJ3Byb2QnIHx8IGdsb2JhbFsnX19lbnZfXyddID09ICdncmF5Jykge1xuICAgICAgICAgICAgLy8gICAgIC8vIOeUn+S6p+WSjOeBsOW6pueOr+Wig+S4i+emgeatoui3qOWfn09QVElPTlPor7fmsYLku6Xkvr/kuo7lop7lvLrlronlhajmgKdcbiAgICAgICAgICAgIC8vICAgICBjYWxsYmFjayhudWxsLCB7XG4gICAgICAgICAgICAvLyAgICAgICAgIHN0YXR1c0NvZGU6IDUwMSxcbiAgICAgICAgICAgIC8vICAgICB9KVxuICAgICAgICAgICAgLy8gfSBlbHNlIHtcbiAgICAgICAgICAgIC8vICAgICAvLyDpnZ7nlJ/kuqflkozngbDluqbnjq/looPkuIvmiY3lhYHorrjmlK/mjIHot6jln59PUFRJT05T6K+35rGCXG4gICAgICAgICAgICAvLyAgICAgY2FsbGJhY2sobnVsbCwge1xuICAgICAgICAgICAgLy8gICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgICAvLyAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgIC8vICAgICAgICAgICAgIC4uLl9fY29yc19fLFxuICAgICAgICAgICAgLy8gICAgICAgICB9LFxuICAgICAgICAgICAgLy8gICAgIH0pXG4gICAgICAgICAgICAvLyB9XG4gICAgICAgICAgICAvLyBGSVhNRSB5Z+WumuWItumcgOimgeeUn+S6p+eOr+Wig+S4i+aUr+S7mOWuneWbnuiwg+ivt+axguaYr+i3qOWfn+eahOmcgOimgeaUr+aMgW9wdGlvbnPnmoTot6jln5/or7fmsYLvvIjkuLTml7bmlL7lvIDpmZDliLbvvIzpnIDopoHphY3nva7lhYHorrjot6jln5/nmoTnmb3lkI3ljZXliJfooajlnKhBUEnnvZHlhbPkuIrorr7nva7vvIlcbiAgICAgICAgICAgIGNhbGxiYWNrKG51bGwsIHtcbiAgICAgICAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICAuLi5fX2NvcnNfXyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHJldHVyblxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgLy8g56aB5q2i5Lu75L2V55qE6Z2e5rOV6K+35rGC5Lil5qC86L+b6KGM57qm5a6a6ZmQ5Yi2XG4gICAgICAgICAgICBjYWxsYmFjayhudWxsLCB7XG4gICAgICAgICAgICAgICAgc3RhdHVzQ29kZTogNTAyLFxuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGdsb2JhbFsnX19ldnRfXyddID0gZXZlbnQudG9TdHJpbmcoKSAvLyBGSVhNRSDpnIDopoHorr7orqHkuIrkuIvmloflrprkuYnor7fmsYLlrp7kvovnlJ/lkb3lkajmnJ/lj5jph49cbiAgICAvLyB4bG9nKCfojrflj5blhajlsYDlj5jph49nbG9iYWxbXCJfX2V2dF9fXCJd55qE5YC877yaJyxnbG9iYWxbJ19fZXZ0X18nXSlcbiAgICAvLyDlhYjku6VIRUFFUuS4reeahF9fYXBpX1/lrZfmrrXov5vooYzor4bliKvvvIzlpoLmnpxIRUFERVLkuK3msqHmnInlrprkuYnlho3kvb/nlKhVUkzot6/lvoTlr7nlupTnmoRQQVRI6K+G5Yir77yM5Lul5q2k5pSv5oyBU0VP562J5YmN56uv6Lev5b6E6YeN5YaZ6Zeu6aKY44CCXG4gICAgbGV0IF9fYXBpX18gPSBfLmdldChldnQsICdoZWFkZXJzLl9fYXBpX18nLCBldnQucGF0aCkgLy8g5pyA57uI5o6n5Yi25Zmo5LiOYXBw5a2Q55uu5b2V5LiL55qEdHPmlofku7bkv53mjIHlrozlhajnmoTkuIDkuIDmmKDlsITlhbPns7vjgIJcbiAgICAvLyDmlLnov5vkuLrmoLnmja5BUEnnvZHlhbPnmoTnm7jlhbPlj4LmlbDoh6rliqjmi7zmjqXlh7rmnaXmraPnoa7nmoRVUkznvZHlnYDor7fmsYLot6/lvoRcbiAgICBsZXQgX191cmxfXyA9IGV2dFsnaGVhZGVycyddWydYLUZvcndhcmRlZC1Qcm90byddICsgJzovLycgKyBldnRbJ2hlYWRlcnMnXVsnQ0EtSG9zdCddICsgZXZ0WydwYXRoJ11cbiAgICAvLyDlsIblhajpg6jnmoRIRUFERVLkv6Hmga/pgI/kvKDliLDlupTnlKjkuK1cbiAgICAvLyBjb25zb2xlLmxvZyg4MzgzODM4MzgzODM4MzgpXG4gICAgLy8gY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkoZXZ0WydoZWFkZXJzJ10pKVxuICAgIGxldCBfX2hlYWRlcl9fID0gZXZ0WydoZWFkZXJzJ11cblxuICAgIGxldCBwYXJhbSA9IE9iamVjdC5hc3NpZ24oXG4gICAgICAgIHtfX2FwaV9fLCBfX3VybF9fLCBfX2hlYWRlcl9ffSwgLy8gaGVhZGVy6K+35rGC5Lit55qE5Lik5Liq5qGG5p625bGC6Z2i5LiK55qE6aKE5a6a5LmJ5Y+C5pWwIFRPRE8g6ZyA6KaB56e76Zmk5o6J5bm26Z2e5bqU55So5YWz5b+D55qE5YaF5a65XG4gICAgICAgIGV2dC5wYXRoUGFyYW1ldGVycyB8fCB7fSwgLy8g6Lev55Sx6YeN5YaZ5Y+C5pWwIGRvbWFpbi9bYV0vW2JdP3h4eCAo5Y+v6KKrR0VU5Y+C5pWw6KaG55uWKVxuICAgICAgICBldnQucXVlcnlQYXJhbWV0ZXJzIHx8IHt9IC8vIEdFVOivt+axguWPguaVsCBkb21haW4vcGF0aD9hPXgmYj14XG4gICAgKVxuICAgIGxldCBvdXQgPSB7fSBhcyBhbnlcblxuICAgIC8vIC8vIOadoeS7tuaXpeW/l+aJk+WNsOe6v+S4iuS4tOaXtumXrumimOaOkuafpeWkhOeQhu+8iFRPRE8g5aKe5Yqg5Lia5Yqh6YC76L6R5omp5bGV5rOo5YWl55qE6ZKp5a2Q5a6e546w77yJXG4gICAgLy8gbGV0IHhkZWJ1ZyA9IGFzeW5jICguLi5hcmdzKSA9PiB7XG4gICAgLy8gICAgIGlmICghXy5pbmNsdWRlcyhfX3VybF9fLCAneS5hbGliYWJhLWluYy5jb20nKSkge1xuICAgIC8vICAgICAgICAgcmV0dXJuXG4gICAgLy8gICAgIH1cbiAgICAvLyAgICAgYXdhaXQgeHdhcm4oLi4uYXJncylcbiAgICAvLyB9XG4gICAgLy8gZ2xvYmFsWyd4ZGVidWcnXSA9IHhkZWJ1ZyAvLyDlhajlsYDlj6/nlKhcbiAgICAvLyBhd2FpdCB4ZGVidWcoe3BhcmFtLCBldnR9KVxuXG4gICAgc3dpdGNoIChldnQuaHR0cE1ldGhvZCkge1xuICAgICAgICBjYXNlICdHRVQnOlxuICAgICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnUE9TVCc6XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIC8vIOmYv+mHjOS6kUFQSee9keWFs+eahFBPU1Tor7fmsYLlj4LmlbDmmK9KU09O5a2X56ym5Liy55qEQkFTRTY057yW56CB5omA5Lul6ZyA6KaB6L+b6KGM6L2s5LmJ5aSE55CGXG4gICAgICAgICAgICAgICAgbGV0IHBvc3QgPSB7fVxuICAgICAgICAgICAgICAgIGlmIChfLmlzU3RyaW5nKGV2dC5ib2R5KSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgYm9keSA9IGV2dC5ib2R5XG4gICAgICAgICAgICAgICAgICAgIGlmIChldnQuaXNCYXNlNjRFbmNvZGVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBib2R5ID0gbmV3IEJ1ZmZlcihldnQuYm9keSwgJ2Jhc2U2NCcpLnRvU3RyaW5nKClcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwb3N0ID0gcGFyc2VfcG9zdF9wYXJhbShldnRbJ2hlYWRlcnMnXSwgYm9keSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgcGFyYW0gPSBPYmplY3QuYXNzaWduKHBhcmFtLCBwb3N0KSAvLyDnlKhwb3N05Y+C5pWw6KaG55uW5o6JZ2V05Y+C5pWw77yM55So5LqO54G15rS755qE6K6+572u6K+35rGC5Y+C5pWw5YW85a65Z2V05ZKMcG9zdOS4pOenjeaWueazleaWueS+v+W8gOWPkeiwg+ivleOAglxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgICAgICAgICAgLy8geGxvZyhlcnIsIGV2dC5odHRwTWV0aG9kLCBldnQuYm9keSlcbiAgICAgICAgICAgICAgICBhd2FpdCB4d2FybihlcnIpXG4gICAgICAgICAgICAgICAgLy8gNDAwXHRCYWQgUmVxdWVzdFx05a6i5oi356uv6K+35rGC55qE6K+t5rOV6ZSZ6K+v77yM5pyN5Yqh5Zmo5peg5rOV55CG6KejXG4gICAgICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwge1xuICAgICAgICAgICAgICAgICAgICBzdGF0dXNDb2RlOiA1MDMsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICByZXR1cm5cbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGJyZWFrXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAvLyB4bG9nKGV2dC5odHRwTWV0aG9kLCBldnQuYm9keSlcbiAgICAgICAgICAgIC8vIDQwMFx0QmFkIFJlcXVlc3RcdOWuouaIt+err+ivt+axgueahOivreazlemUmeivr++8jOacjeWKoeWZqOaXoOazleeQhuino1xuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwge1xuICAgICAgICAgICAgICAgIHN0YXR1c0NvZGU6IDUwNCxcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0cnkge1xuICAgICAgICBjb25zb2xlLmxvZygn6L+b5YWldHJ5JylcbiAgICAgICAgLy8g6Kej5p6Q6K+35rGC5Lit55qEY29va2llc+aVsOaNruW5tui9rOaNouS4ukpTT07lr7nosaHlrZjlgqjliLDlhajlsYDlj5jph4/kuK3kvr/kuo7lkI7nu63lupTnlKh4Y29va2ll5o6l5Y+j5L2/55SoXG4gICAgICAgIGxldCBjb29raWUgPSBfLmdldChldnRbJ2hlYWRlcnMnXSwgJ0Nvb2tpZScsIHVuZGVmaW5lZClcbiAgICAgICAgY29uc29sZS5sb2coJ+iOt+WPlmNvb2tpZeS/oeaBrycsSlNPTi5zdHJpbmdpZnkoY29va2llKSlcbiAgICAgICAgaWYgKCFjb29raWUpIHtcbiAgICAgICAgICAgIGNvb2tpZSA9IF8uZ2V0KGV2dFsnaGVhZGVycyddLCAnY29va2llJywgJycpXG4gICAgICAgIH1cbiAgICAgICAgZ2xvYmFsWydfX3JlcXVlc3RfY29va2llc19fJ10gPSByZXF1aXJlKCdjb29raWUnKS5wYXJzZShjb29raWUpXG4gICAgICAgIGNvbnNvbGUubG9nKCfotYvlgLznu5lfX3JlcXVlc3RfY29va2llc19fJyxnbG9iYWxbJ19fcmVxdWVzdF9jb29raWVzX18nXSlcbiAgICAgICAgLy8g6I635Y+WdXNlLWFnZW506K+35rGC5aS06YOo5L+h5oGvXG4gICAgICAgIGdsb2JhbFsnX191c2VyX2FnZW50X18nXSA9IGV2dFsnaGVhZGVycyddWydVc2VyLUFnZW50J11cbiAgICAgICAgY29uc29sZS5sb2coJ+i1i+WAvOe7mV9fdXNlcl9hZ2VudF9fJyxnbG9iYWxbJ19fdXNlcl9hZ2VudF9fJ10pXG4gICAgICAgIC8vIOiOt+WPluWuouaIt+err+eahElQ5Zyw5Z2A5L+h5oGvXG4gICAgICAgIGdsb2JhbFsnX19jbGllbnRfaXBfXyddID0gZXZ0WydoZWFkZXJzJ11bJ1gtUmVhbC1JUCddXG4gICAgICAgIGNvbnNvbGUubG9nKCfotYvlgLznu5lfX2NsaWVudF9pcF9fJyxnbG9iYWxbJ19fY2xpZW50X2lwX18nXSlcblxuICAgICAgICAvLyBUT0RPIFdFQuivt+axgumcgOimgeWvuTQwNOmhtemdouS7peWPikVSUk9S6aG16Z2i6L+b6KGM5YW85a655aSE55CG77yI5ZyoZnJhbWV3b3Jr5YaF6YOo6L+b6KGM57uG6IqC55qE6ZSZ6K+v5Yik5pat5Zyob3V05Lit6YCP5Lygc3RhdHVz55qEaHR0cOeahOeKtuaAgeWQl+ato+ehrumUmeivr+i/lOWbnu+8iVxuICAgICAgICAvLyA0MDRcdE5vdCBGb3VuZCDmnI3liqHlmajml6Dms5XmoLnmja7lrqLmiLfnq6/nmoTor7fmsYLmib7liLDotYTmupDvvIjnvZHpobXvvInjgILpgJrov4fmraTku6PnoIHvvIznvZHnq5norr7orqHkurrlkZjlj6/orr7nva5cIuaCqOaJgOivt+axgueahOi1hOa6kOaXoOazleaJvuWIsFwi55qE5Liq5oCn6aG16Z2iXG4gICAgICAgIC8vIDQwM1x0Rm9yYmlkZGVuXHTmnI3liqHlmajnkIbop6Por7fmsYLlrqLmiLfnq6/nmoTor7fmsYLvvIzkvYbmmK/mi5Lnu53miafooYzmraTor7fmsYLvvIjmnYPpmZDpqozor4HlpITnkIbplJnor6/vvIlcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ+afpeeci+ahhuaetuaYr+WQpuWPiOmUmScpXG4gICAgICAgIGNvbnNvbGUubG9nKCdfX2FwaV9f5piv5ZCm5Ye66ZSZJyxfX2FwaV9fKVxuICAgICAgICBvdXQgPSBhd2FpdCByZXF1ZXN0X3Byb2Nlc3MoX19hcGlfXywgcGFyYW0pXG4gICAgICAgIFxuICAgICAgICBjb25zb2xlLmxvZygn6L+U5Zue55qEb3V05YC8JyxKU09OLnN0cmluZ2lmeShvdXQpKVxuICAgICAgICBpZiAoXy5pc0VtcHR5KG91dCkpIHtcbiAgICAgICAgICAgIC8vIOWvueS6jm5vd3JhcOeahOaDheWGteWBmueJueauiuWuuemUmeWkhOeQhlxuICAgICAgICAgICAgb3V0ID0gdW5kZWZpbmVkXG4gICAgICAgIH1cbiAgICAgICAgLy8gY29uc29sZS5sb2coJ+WHhuWkh+WkhOeQhmNvb2tpZXMnKVxuICAgICAgICAvLyDlpITnkIZyZXNwb25zZeeahGNvb2tpZXPorr7nva5cbiAgICAgICAgbGV0IHNldENvb2tpZSA9IHsnU2V0LUNvb2tpZSc6IHVuZGVmaW5lZH1cbiAgICAgICAgaWYgKCFfLmlzRW1wdHkoZ2xvYmFsWydfX3Jlc3BvbmRfY29va2llc19fJ10pKSB7XG4gICAgICAgICAgICBzZXRDb29raWVbJ1NldC1Db29raWUnXSA9IF8udmFsdWVzKGdsb2JhbFsnX19yZXNwb25kX2Nvb2tpZXNfXyddKVxuICAgICAgICB9XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCfmn6XnnItyZWRpcmVjdF91cmznmoTlgLwnLGdsb2JhbFsnX19yZWRpcmVjdF91cmxfXyddKVxuICAgICAgICBpZiAoZ2xvYmFsWydfX3JlZGlyZWN0X3VybF9fJ10pIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCfov5vlhaXnrKzkuIDkuKrpgInpobknKVxuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwge1xuICAgICAgICAgICAgICAgIHN0YXR1c0NvZGU6IDMwMixcbiAgICAgICAgICAgICAgICBoZWFkZXJzOiB7XG4gICAgICAgICAgICAgICAgICAgIFwiTG9jYXRpb25cIjogZ2xvYmFsWydfX3JlZGlyZWN0X3VybF9fJ10sXG4gICAgICAgICAgICAgICAgICAgIC4uLnNldENvb2tpZVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB9KVxuICAgICAgICAgICAgZ2xvYmFsWydfX3JlZGlyZWN0X3VybF9fJ10gPSB1bmRlZmluZWRcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChfLmlzU3RyaW5nKG91dCkpIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCfov5vlhaXnrKzkuozkuKrpgInpobknKVxuICAgICAgICAgICAgbGV0IGh0bWxSZXNwb25zZSA9IHtcbiAgICAgICAgICAgICAgICBpc0Jhc2U2NEVuY29kZWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgc3RhdHVzQ29kZTogMjAwLFxuICAgICAgICAgICAgICAgIGhlYWRlcnM6IHtcbiAgICAgICAgICAgICAgICAgICAgXCJDb250ZW50LXR5cGVcIjogXCJ0ZXh0L2h0bWw7IGNoYXJzZXQ9dXRmLThcIixcbiAgICAgICAgICAgICAgICAgICAgLi4uc2V0Q29va2llLFxuICAgICAgICAgICAgICAgICAgICAuLi5fX2NvcnNfXyxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIC8vIGJhc2U2NCBlbmNvZGUgYm9keSBzbyBpdCBjYW4gYmUgc2FmZWx5IHJldHVybmVkIGFzIEpTT04gdmFsdWVcbiAgICAgICAgICAgICAgICBib2R5OiBuZXcgQnVmZmVyKG91dCBhcyBzdHJpbmcpLnRvU3RyaW5nKCdiYXNlNjQnKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwgaHRtbFJlc3BvbnNlKVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ+i/m+WFpeesrOS4ieS4qumAiemhuScpXG4gICAgICAgICAgICBsZXQganNvblJlc3BvbnNlID0ge1xuICAgICAgICAgICAgICAgIGlzQmFzZTY0RW5jb2RlZDogdHJ1ZSxcbiAgICAgICAgICAgICAgICBzdGF0dXNDb2RlOiAyMDAsXG4gICAgICAgICAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgICAgICAgICAgICBcIkNvbnRlbnQtdHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgICAgICAgICAgICAgICAgLi4uX19jb3JzX18sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAvLyBiYXNlNjQgZW5jb2RlIGJvZHkgc28gaXQgY2FuIGJlIHNhZmVseSByZXR1cm5lZCBhcyBKU09OIHZhbHVlXG4gICAgICAgICAgICAgICAgYm9keTogbmV3IEJ1ZmZlcihvdXQgPyBKU09OLnN0cmluZ2lmeShvdXQpIDogJycpLnRvU3RyaW5nKCdiYXNlNjQnKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY2FsbGJhY2sobnVsbCwganNvblJlc3BvbnNlKVxuICAgICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAgIC8vIOmAmuefpeahhuaetuiHqui6q+WunueOsOmAu+i+keeahOaEj+WkluaKpemUme+8iOahhuaetuiHqui6q+S4jeiuuuS9leenjeaDheWGtemDveW6lOivpeato+W4uOW3peS9nO+8jOS4gOaXpuWHuueOsOatpOmXrumimOWkp+WkmuaVsOaDheWGteaYr+ahhuaetuiHqui6q+mXrumimOaIluiAhea1gemHj+W8leWPkeeahOi/kOe7tOmXrumimO+8iVxuICAgICAgICBhd2FpdCB4d2Fybih7XG4gICAgICAgICAgICBfX2FwaV9fLCBfX3VybF9fLCBwYXJhbSwgbWVzc2FnZTogZXJyLm1lc3NhZ2UsIHN0YWNrOiB4c3RhY2soZXJyKVxuICAgICAgICB9KVxuICAgICAgICAvLyA1MDBcdEludGVybmFsIFNlcnZlciBFcnJvclx05pyN5Yqh5Zmo5YaF6YOo6ZSZ6K+v77yM5peg5rOV5a6M5oiQ6K+35rGCXG4gICAgICAgIGNhbGxiYWNrKG51bGwsIHtzdGF0dXNDb2RlOiA1MDV9KVxuICAgIH1cbn1cblxuLy8gIEFQSeWPguaVsOeahOivhuWIq+mAu+i+ke+8jOS4uuaZrumAmuWtl+espuS4sui3r+W+hOWumuS5ieS4jmFwcOS4i+eahHRz5paH5Lu26Lev55Sx5a6M5YWo5LiA5LiA5a+55bqU77yM5LyY5YWI5Y+WSEVBREVS5Lit55qE5a6a5LmJ77yM5YaN5Y+WR0VU5Lit55qE5b2i5Y+C5a6a5LmJ5oiW6ICFUE9TVOW9ouWPguWumuS5iei/m+ihjOWPguaVsOivt+axgueahOimhuebluWkhOeQhuOAglxuLy8gIFBBUkFN6K+35rGC55qE5Y+C5pWw5aSE55CG6KaB5rGC5Li6QkFTRTY057yW56CB5YyW55qESlNPTuWtl+espuS4suOAglxuLy8gICAgIFwiZXZlbnRcIjoge1xuLy8gICAgICAgICBcImJvZHlcIjogXCJld29KSW1Gd2FTSTZJQ0l2WVM5aUwyTWlMQW9KSW5CaGNtRnRJam9nSW1GelpHWmhjMlJtWVhOa1ppSUtmUT09XCIsID0+IOWvueW6lOS6jlBPU1Tor7fmsYLmlbDmja5cbi8vICAgICAgICAgXCJoZWFkZXJzXCI6IHtcbi8vICAgICAgICAgICAgIFwiWC1DYS1BcGktR2F0ZXdheVwiOiBcIkIyNUNENTFCLTU4MTUtNDc3NS05RUFCLTZENDgxQkMxQUUxN1wiLFxuLy8gICAgICAgICAgICAgXCJfX2FwaV9fXCI6IFwiL3dlYi9tb2JpbGUvdGVzdFwiLCAgID3jgIsg6Ieq5a6a5LmJ6L2s5LmJUEFUSOeahOi3r+W+hOS/oeaBr+WvueS6jlNFT+S8mOWMluWFvOWuueWkhOeQhu+8iOS5n+WPr+S7peWcqEdFVOaIllBPU1Tor7fmsYLkuK3kvKDpgJLlr7nlupTlj4LmlbDvvIlcbi8vICAgICAgICAgICAgIFwiWC1Gb3J3YXJkZWQtRm9yXCI6IFwiNDIuMTIwLjc0Ljg4XCIsXG4vLyAgICAgICAgICAgICBcIkNvbnRlbnQtVHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIlxuLy8gICAgICAgICB9LFxuLy8gICAgICAgICBcImh0dHBNZXRob2RcIjogXCJQT1NUXCIsXG4vLyAgICAgICAgIFwiaXNCYXNlNjRFbmNvZGVkXCI6IHRydWUsXG4vLyAgICAgICAgIFwicGF0aFwiOiBcIi9cIiwgPeOAiyDmsqHmnInmhI/kuYnnlKjkuo7liY3nq6/moLnmja7pnIDopoHoh6rlt7Hov5vooYzmianlsZXliKvlkI3mmKDlsITlpITnkIbvvIzlkI7nq6/nmoTmjqfliLblmajkuI3ku6XmraTkuLrmoIflh4bvvIzlj6/ku6Xlr7nlkIzkuIDkuKrmjqfliLblmajlrprkuYlO5Liq5LiN5ZCM55qE6Lev5b6E5qCH6K+G44CCXG4vLyAgICAgICAgIFwicGF0aFBhcmFtZXRlcnNcIjoge30sXG4vLyAgICAgICAgIFwicXVlcnlQYXJhbWV0ZXJzXCI6IHt9ID0+IOWvueW6lOS6jkdFVOivt+axguaVsOaNrlxuLy8gICAgIH0sXG4vLyAgICAgXCJxdWVyeVwiOiB7fSxcbi8vICAgICBcImNvbnRleHRcIjoge1xuLy8gICAgICAgICBcInJlcXVlc3RJZFwiOiBcIkIyNUNENTFCLTU4MTUtNDc3NS05RUFCLTZENDgxQkMxQUUxN1wiLFxuLy8gICAgICAgICBcImNyZWRlbnRpYWxzXCI6IHtcbi8vICAgICAgICAgICAgIFwiYWNjZXNzS2V5SWRcIjogXCJcIixcbi8vICAgICAgICAgICAgIFwiYWNjZXNzS2V5U2VjcmV0XCI6IFwiXCIsXG4vLyAgICAgICAgICAgICBcInNlY3VyaXR5VG9rZW5cIjogXCJcIlxuLy8gICAgICAgICB9LFxuLy8gICAgICAgICBcImZ1bmN0aW9uXCI6IHtcbi8vICAgICAgICAgICAgIFwibmFtZVwiOiBcInRlc3RcIixcbi8vICAgICAgICAgICAgIFwiaGFuZGxlclwiOiBcImluZGV4LmhhbmRsZXJcIixcbi8vICAgICAgICAgICAgIFwibWVtb3J5XCI6IDEyOCxcbi8vICAgICAgICAgICAgIFwidGltZW91dFwiOiAzMDBcbi8vICAgICAgICAgfSxcbi8vICAgICAgICAgXCJzZXJ2aWNlc1wiOiB7XG4vLyAgICAgICAgICAgICBcIm5hbWVcIjogXCJhbGlsYW5nXCIsXG4vLyAgICAgICAgICAgICBcImxvZ1Byb2plY3RcIjogXCJcIixcbi8vICAgICAgICAgICAgIFwibG9nU3RvcmVcIjogXCJcIlxuLy8gICAgICAgICB9LFxuLy8gICAgICAgICBcInJlZ2lvblwiOiBcImNuLXNoYW5naGFpXCIsXG4vLyAgICAgICAgIFwiYWNjb3VudElkXCI6IFwiMTczNDA2NjA1NzY4OTUyOFwiXG4vLyAgICAgfVxuLy8gfVxuXG4vLyDmnIDmlrDniYjmnKxldmVudOeahEFQSee9keWFs+eahEZD6L+U5Zue5pWw5o2u5qC85byP77yaXG4vLyAgICAgIENBLUhvc3Tor7fmsYLln5/lkI3jgIFcbi8vICAgICAgWC1Gb3J3YXJkZWQtUHJvdG9cbi8vICAgICAgXCJwYXRoXCI6IFwiL3Rlc3RcIiwgPT3jgIvjgIvln7rmnKzkuIrlj6/ku6Xmi7zmjqXlh7pfX3VybF9f5Y+C5pWw5Y+v5Lul55yB55Wl5o6J5q2k5YaX5L2Z5Y+C5pWw6YWN572u5LqG44CCXG4vLyAgICAgICAgICAgICAgICAgICAgICAgPT3jgIvjgIvlgJ/liqlyb3V0ZS5tYXAudHPmlofku7bnmoTmmKDlsITlhbPns7vlrprkuYnnnIHnlaXmjolfX2FwaV9f6YWN572u6L+b5LiA5q2l566A5YyW572R5YWz5bqU55So44CCXG4vLyAgICAgIFwiaHR0cE1ldGhvZFwiOiBcIkdFVFwiLFxuLy8gICAgICBcImlzQmFzZTY0RW5jb2RlZFwiOiB0cnVlLFxuLy8gICAgICBcIlgtRm9yd2FyZGVkLUZvclwiOiBcIjQyLjEyMC43NC4xMDNcIiwgLy8g5a6i5oi356uv6K+35rGCSVDlnLDlnYDnlKjmiLfliKTlrprmiYDlsZ7ljLrln5/kv6Hmga/mtbflpJborr/pl67pl67popjkvJjljJbkvp3otZbngrlcbi8vICAgICAgXCJYLVJlYWwtSVBcIjogXCI0Mi4xMjAuNzQuMTAzXCIsXG4vLyAgICAgIENvb2tpZVxuLy8gICAgICBVc2VyLUFnZW50ICAgICAgID0+PiBQQ+ermeWSjE3nq5noh6rpgILlupTpl67pophcbi8vICAgICAgQWNjZXB0LUxhbmd1YWdlICA9Pj4g5rWP6KeI5Zmo5a6i5oi356uv55qE6K+t6KiA57G75Z6L6Ieq5Yqo6YCC6YWN5aSa6K+t6KiA5p625p6E6K6+6K6h6Zeu6aKYXG4vLyBsZXQgeCA9IHtcbi8vICAgICBcImJvZHlcIjogXCJcIixcbi8vICAgICBcImhlYWRlcnNcIjoge1xuLy8gICAgICAgICBcIlgtQ2EtQXBpLUdhdGV3YXlcIjogXCJCMjc2Rjc3Qi0zMzRFLTQ4NTctQUU2NC02NUJBRkQ0MTlFMkFcIixcbi8vICAgICAgICAgXCJDb29raWVcIjogXCJjbmE9cjVzbkV6ek92QTBDQVNwNFNtZHErSUkvOyBVTV9kaXN0aW5jdGlkPTE2MmJjZDYxZDkxMTFjZC0wODBlMGY0M2U2YjYwZC0zMzY5N2IwNC0xM2M2ODAtMTYyYmNkNjFkOTJjODY7IF90Yl90b2tlbl89SDhVN0JxaXhGM1lWUjNHbmhNUno7IE5FVzJfQUNSX0pTRVNTSU9OSUQ9Vk01NjZGOTEtSzVDUDhRSVZNUVRTQUgzQzRINVgxLURSSUhZSkhKLVFFMjsgX25ld19jcl9zZXNzaW9uMD0xQWJMQnlPTUhlWmUzRzQxS1lkNVdjUGRDJTJGaThxdkdIVUJUSzhGYnJmeDhTb2klMkJIRUx1eHhBNmpyb3M3VyUyRnFDMVl0ZWJnQjNhdUVGNWx1MVNDelV6VGt0NnYlMkZpRmVOJTJGcHRidkJSemlZRUdYU0VWaFduVWxCUjJ0ZnBqclhNbkljZmIyJTJGd25Ha0g0dmtlTUlKMUJ2dXclM0QlM0Q7IGVtcGxJZD0xNDkzMzc7IGhyY19zaWRlYmFyPW9wZW47IHRyYWNlSWQ9N2Q0YjE2ZGUtNzRiYy00ZWFjLTg4NGItNTRjYTAzNTRlNGFhOyBTU09fTEFORz1aSC1DTjsgU1NPX0VNUElEX0hBU0g9OWRiMWVkMjE0MDJmN2MzNjY3NGI1ZTZlNmRlMWZjNjg7IGFuaW1hdGVfZGF0ZT0yMDE4NjQ7IGFhPXh4eHh4eHg7IGNuXzEyNjAwMDEyMjFfZHBsdXM9JTdCJTIyZGlzdGluY3RfaWQlMjIlM0ElMjAlMjIxNjJiY2Q2MWQ5MTExY2QtMDgwZTBmNDNlNmI2MGQtMzM2OTdiMDQtMTNjNjgwLTE2MmJjZDYxZDkyYzg2JTIyJTJDJTIyc3AlMjIlM0ElMjAlN0IlMjIlMjRfc2Vzc2lvbmlkJTIyJTNBJTIwMCUyQyUyMiUyNF9zZXNzaW9uVGltZSUyMiUzQSUyMDE1MjgwODYyMzQlMkMlMjIlMjRkcCUyMiUzQSUyMDAlMkMlMjIlMjRfc2Vzc2lvblBWVGltZSUyMiUzQSUyMDE1MjgwODYyMzQlN0QlN0Q7IGlzZz1CRHc4U29ueVM5dXR5bjVmZWRZUmUtdVJEZHp3TkFEMC01MUJIaGE5X1NjSjRkeHJOa1d3NzdLUXhRbVpxUmkzXCIsXG4vLyAgICAgICAgIFwiWC1Gb3J3YXJkZWQtUHJvdG9cIjogXCJodHRwc1wiLFxuLy8gICAgICAgICBcIlVzZXItQWdlbnRcIjogXCJNb3ppbGxhLzUuMCAoTWFjaW50b3NoOyBJbnRlbCBNYWMgT1MgWCAxMF8xMl82KSBBcHBsZVdlYktpdC81MzcuMzYgKEtIVE1MLCBsaWtlIEdlY2tvKSBDaHJvbWUvNjYuMC4zMzU5LjE4MSBTYWZhcmkvNTM3LjM2XCIsXG4vLyAgICAgICAgIFwiX191cmxfX1wiOiBcImh0dHBzOi8vdG91ZmFuZy5hbGliYWJhLWluYy5jb20vdGVzdFwiLFxuLy8gICAgICAgICBcIkNBLUhvc3RcIjogXCJ0b3VmYW5nLmFsaWJhYmEtaW5jLmNvbVwiLFxuLy8gICAgICAgICBcIkNhY2hlLUNvbnRyb2xcIjogXCJtYXgtYWdlPTBcIixcbi8vICAgICAgICAgXCJ1cGdyYWRlLWluc2VjdXJlLXJlcXVlc3RzXCI6IFwiMVwiLFxuLy8gICAgICAgICBcIkFjY2VwdC1MYW5ndWFnZVwiOiBcInpoLUNOLHpoO3E9MC45XCIsXG4vLyAgICAgICAgIFwiX19hcGlfX1wiOiBcIi93ZWIvdGVzdC90ZXN0XCIsXG4vLyAgICAgICAgIFwiQWNjZXB0LUVuY29kaW5nXCI6IFwiZ3ppcCwgZGVmbGF0ZSwgYnJcIixcbi8vICAgICAgICAgXCJYLUZvcndhcmRlZC1Gb3JcIjogXCI0Mi4xMjAuNzQuMTAzXCIsXG4vLyAgICAgICAgIFwiWC1SZWFsLUlQXCI6IFwiNDIuMTIwLjc0LjEwM1wiLFxuLy8gICAgICAgICBcIkFjY2VwdFwiOiBcInRleHQvaHRtbCxhcHBsaWNhdGlvbi94aHRtbCt4bWwsYXBwbGljYXRpb24veG1sO3E9MC45LGltYWdlL3dlYnAsaW1hZ2UvYXBuZywqLyo7cT0wLjhcIlxuLy8gICAgIH0sXG4vLyAgICAgXCJodHRwTWV0aG9kXCI6IFwiR0VUXCIsXG4vLyAgICAgXCJpc0Jhc2U2NEVuY29kZWRcIjogdHJ1ZSxcbi8vICAgICBcInBhdGhcIjogXCIvdGVzdFwiLFxuLy8gICAgIFwicGF0aFBhcmFtZXRlcnNcIjoge30sXG4vLyAgICAgXCJxdWVyeVBhcmFtZXRlcnNcIjoge31cbi8vIH1cbiJdfQ== |
\ | No newline at end of file |