25 lines
168 KiB
JavaScript
25 lines
168 KiB
JavaScript
"use strict";
|
||
/*
|
||
* ATTENTION: An "eval-source-map" devtool has been used.
|
||
* This devtool is neither made for production nor for readable output files.
|
||
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
|
||
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
|
||
* or disable the default devtool with "devtool: false".
|
||
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
|
||
*/
|
||
exports.id = "vendor-chunks/linkifyjs";
|
||
exports.ids = ["vendor-chunks/linkifyjs"];
|
||
exports.modules = {
|
||
|
||
/***/ "(ssr)/./node_modules/linkifyjs/dist/linkify.mjs":
|
||
/*!*************************************************!*\
|
||
!*** ./node_modules/linkifyjs/dist/linkify.mjs ***!
|
||
\*************************************************/
|
||
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {
|
||
|
||
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ MultiToken: () => (/* binding */ MultiToken),\n/* harmony export */ Options: () => (/* binding */ Options),\n/* harmony export */ State: () => (/* binding */ State),\n/* harmony export */ createTokenClass: () => (/* binding */ createTokenClass),\n/* harmony export */ find: () => (/* binding */ find),\n/* harmony export */ init: () => (/* binding */ init),\n/* harmony export */ multi: () => (/* binding */ multi),\n/* harmony export */ options: () => (/* binding */ options),\n/* harmony export */ regexp: () => (/* binding */ regexp),\n/* harmony export */ registerCustomProtocol: () => (/* binding */ registerCustomProtocol),\n/* harmony export */ registerPlugin: () => (/* binding */ registerPlugin),\n/* harmony export */ registerTokenPlugin: () => (/* binding */ registerTokenPlugin),\n/* harmony export */ reset: () => (/* binding */ reset),\n/* harmony export */ stringToArray: () => (/* binding */ stringToArray),\n/* harmony export */ test: () => (/* binding */ test),\n/* harmony export */ text: () => (/* binding */ multi),\n/* harmony export */ tokenize: () => (/* binding */ tokenize)\n/* harmony export */ });\n// THIS FILE IS AUTOMATICALLY GENERATED DO NOT EDIT DIRECTLY\n// See update-tlds.js for encoding/decoding format\n// https://data.iana.org/TLD/tlds-alpha-by-domain.txt\nconst encodedTlds = 'aaa1rp3bb0ott3vie4c1le2ogado5udhabi7c0ademy5centure6ountant0s9o1tor4d0s1ult4e0g1ro2tna4f0l1rica5g0akhan5ency5i0g1rbus3force5tel5kdn3l0ibaba4pay4lfinanz6state5y2sace3tom5m0azon4ericanexpress7family11x2fam3ica3sterdam8nalytics7droid5quan4z2o0l2partments8p0le4q0uarelle8r0ab1mco4chi3my2pa2t0e3s0da2ia2sociates9t0hleta5torney7u0ction5di0ble3o3spost5thor3o0s4w0s2x0a2z0ure5ba0by2idu3namex4d1k2r0celona5laycard4s5efoot5gains6seball5ketball8uhaus5yern5b0c1t1va3cg1n2d1e0ats2uty4er2rlin4st0buy5t2f1g1h0arti5i0ble3d1ke2ng0o3o1z2j1lack0friday9ockbuster8g1omberg7ue3m0s1w2n0pparibas9o0ats3ehringer8fa2m1nd2o0k0ing5sch2tik2on4t1utique6x2r0adesco6idgestone9oadway5ker3ther5ussels7s1t1uild0ers6siness6y1zz3v1w1y1z0h3ca0b1fe2l0l1vinklein9m0era3p2non3petown5ital0one8r0avan4ds2e0er0s4s2sa1e1h1ino4t0ering5holic7ba1n1re3c1d1enter4o1rn3f0a1d2g1h0anel2nel4rity4se2t2eap3intai5ristmas6ome4urch5i0priani6rcle4sco3tadel4i0c2y3k1l0aims4eaning6ick2nic1que6othing5ud3ub0med6m1n1o0ach3des3ffee4llege4ogne5m0mbank4unity6pany2re3uter5sec4ndos3struction8ulting7tact3ractors9oking4l1p2rsica5untry4pon0s4rses6pa2r0edit0card4union9icket5own3s1uise0s6u0isinella9v1w1x1y0mru3ou3z2dad1nce3ta1e1ing3sun4y2clk3ds2e0al0er2s3gree4livery5l1oitte5ta3mocrat6ntal2ist5si0gn4v2hl2iamonds6et2gital5rect0ory7scount3ver5h2y2j1k1m1np2o0cs1tor4g1mains5t1wnload7rive4tv2ubai3nlop4pont4rban5vag2r2z2earth3t2c0o2deka3u0cation8e1g1mail3erck5nergy4gineer0ing9terprises10pson4quipment8r0icsson6ni3s0q1tate5t1u0rovision8s2vents5xchange6pert3osed4ress5traspace10fage2il1rwinds6th3mily4n0s2rm0ers5shion4t3edex3edback6rrari3ero6i0delity5o2lm2nal1nce1ial7re0stone6mdale6sh0ing5t0ness6j1k1lickr3ghts4r2orist4wers5y2m1o0o0d1tball6rd1ex2sale4um3undation8x2r0ee1senius7l1ogans4ntier7tr2ujitsu5n0d2rniture7tbol5yi3ga0l0lery3o1up4me0s3p1rden4y2b0iz3d0n2e0a1nt0ing5orge5f1g0ee3h1i0ft0s3ves2ing5l0ass3e1obal2o4m0ail3bh2o1x2n1odaddy5ld0point6f2o0dyear5g0le4p1t1v2p1q1r0ainger5phics5tis4een3ipe3ocery4up4s1t1u0cci3ge2ide2tars5ru3w1y2hair2mburg5ngout5us3bo2dfc0bank7ealth0care8lp1sinki6re1mes5iphop4samitsu7tachi5v2k0t2m1n1ockey4ldings5iday5medepot5goods5s0ense7nda3rse3spital5t0ing5t0els3mail5use3w2r1sbc3t1u0ghes5yatt3undai7ibm2cbc2e1u2d1e0ee3fm2kano4l1m0amat4db2mo0bilien9n0c1dustries8finiti5o2g1k1stitute6urance4e4t0ernational10uit4vestments10o1piranga7q1r0ish4s0maili5t0anbul7t0au2v3jaguar4va3cb2e0ep2tzt3welry6io2ll2m0p2nj2o0bs1urg4t1y2p0morgan6rs3uegos4niper7kaufen5ddi3e0rryhotels6properties14fh2g1h1i0a1ds2m1ndle4tchen5wi3m1n1oeln3matsu5sher5p0mg2n2r0d1ed3uokgroup8w1y0oto4z2la0caixa5mborghini8er3nd0rover6xess5salle5t0ino3robe5w0yer5b1c1ds2ease3clerc5frak4gal2o2xus4gbt3i0dl2fe0insurance9style7ghting6ke2lly3mited4o2ncoln4k2ve1ing5k1lc1p2oan0s3cker3us3l1ndon4tte1o3ve3pl0financial11r1s1t0d0a3u0ndbeck6xe1ury5v1y2ma0drid4if1son4keup4n0agement7go3p1rket0ing3s4riott5shalls7ttel5ba2c0kinsey7d1e0d0ia3et2lbourne7me1orial6n0u2rckmsd7g1h1iami3crosoft7l1ni1t2t0subishi9k1l0b1s2m0a2n1o0bi0le4da2e1i1m1nash3ey2ster5rmon3tgage6scow4to0rcycles9v0ie4p1q1r1s0d2t0n1r2u0seum3ic4v1w1x1y1z2na0b1goya4me2vy3ba2c1e0c1t0bank4flix4work5ustar5w0s2xt0direct7us4f0l2g0o2hk2i0co2ke1on3nja3ssan1y5l1o0kia3rton4w0ruz3tv4p1r0a1w2tt2u1yc2z2obi1server7ffice5kinawa6layan0group9lo3m0ega4ne1g1l0ine5oo2pen3racle3nge4g0anic5igins6saka4tsuka4t2vh3pa0ge2nasonic7ris2s1tners4s1y3y2ccw3e0t2f0izer5g1h0armacy6d1ilips5one2to0graphy6s4ysio5ics1tet2ures6d1n0g1k2oneer5zza4k1l0ace2y0station9umbing5s3m1n0c2ohl2ker3litie5rn2st3r0axi3ess3ime3o0d0uctions8f1gressive8mo2perties3y5tection8u0dential9s1t1ub2w0c2y2qa1pon3uebec3st5racing4dio4e0ad1lestate6tor2y4cipes5d0stone5umbrella9hab3ise0n3t2liance6n0t0als5pair3ort3ublican8st0aurant8view0s5xroth6ich0ardli6oh3l1o1p2o0cks3deo3gers4om3s0vp3u0gby3hr2n2w0e2yukyu6sa0arland6fe0ty4kura4le1on3msclub4ung5ndvik0coromant12ofi4p1rl2s1ve2xo3b0i1s2c0b1haeffler7midt4olarships8ol3ule3warz5ience5ot3d1e0arch3t2cure1ity6ek2lect4ner3rvices6ven3w1x0y3fr2g1h0angrila6rp3ell3ia1ksha5oes2p0ping5uji3w3i0lk2na1gles5te3j1k0i0n2y0pe4l0ing4m0art3ile4n0cf3o0ccer3ial4ftbank4ware6hu2lar2utions7ng1y2y2pa0ce3ort2t3r0l2s1t0ada2ples4r1tebank4farm7c0group6ockholm6rage3e3ream4udio2y3yle4u0cks3pplies3y2ort5rf1gery5zuki5v1watch4iss4x1y0dney4stems6z2tab1ipei4lk2obao4rget4tamotors6r2too4x0i3c0i2d0k2eam2ch0nology8l1masek5nnis4va3f1g1h0d1eater2re6iaa2ckets5enda4ps2res2ol4j0maxx4x2k0maxx5l1m0all4n1o0day3kyo3ols3p1ray3shiba5tal3urs3wn2yota3s3r0ade1ing4ining5vel0ers0insurance16ust3v2t1ube2i1nes3shu4v0s2w1z2ua1bank3s2g1k1nicom3versity8o2ol2ps2s1y1z2va0cations7na1guard7c1e0gas3ntures6risign5mögensberater2ung14sicherung10t2g1i0ajes4deo3g1king4llas4n1p1rgin4sa1ion4va1o3laanderen9n1odka3lvo3te1ing3o2yage5u2wales2mart4ter4ng0gou5tch0es6eather0channel12bcam3er2site5d0ding5ibo2r3f1hoswho6ien2ki2lliamhill9n0dows4e1ners6me2olterskluwer11odside6rk0s2ld3w2s1tc1f3xbox3erox4ihuan4n2xx2yz3yachts4hoo3maxun5ndex5e1odobashi7ga2kohama6u0tube6t1un3za0ppos4ra3ero3ip2m1one3uerich6w2';\n// Internationalized domain names containing non-ASCII\nconst encodedUtlds = 'ελ1υ2бг1ел3дети4ею2католик6ом3мкд2он1сква6онлайн5рг3рус2ф2сайт3рб3укр3қаз3հայ3ישראל5קום3ابوظبي5رامكو5لاردن4بحرين5جزائر5سعودية6عليان5مغرب5مارات5یران5بارت2زار4يتك3ھارت5تونس4سودان3رية5شبكة4عراق2ب2مان4فلسطين6قطر3كاثوليك6وم3مصر2ليسيا5وريتانيا7قع4همراه5پاکستان7ڀارت4कॉम3नेट3भारत0म्3ोत5संगठन5বাংলা5ভারত2ৰত4ਭਾਰਤ4ભારત4ଭାରତ4இந்தியா6லங்கை6சிங்கப்பூர்11భారత్5ಭಾರತ4ഭാരതം5ලංකා4คอม3ไทย3ລາວ3გე2みんな3アマゾン4クラウド4グーグル4コム2ストア3セール3ファッション6ポイント4世界2中信1国1國1文网3亚马逊3企业2佛山2信息2健康2八卦2公司1益2台湾1灣2商城1店1标2嘉里0大酒店5在线2大拿2天主教3娱乐2家電2广东2微博2慈善2我爱你3手机2招聘2政务1府2新加坡2闻2时尚2書籍2机构2淡马锡3游戏2澳門2点看2移动2组织机构4网址1店1站1络2联通2谷歌2购物2通販2集团2電訊盈科4飞利浦3食品2餐厅2香格里拉3港2닷넷1컴2삼성2한국2';\n\n/**\n * Finite State Machine generation utilities\n */\n\n/**\n * @template T\n * @typedef {{ [group: string]: T[] }} Collections\n */\n\n/**\n * @typedef {{ [group: string]: true }} Flags\n */\n\n// Keys in scanner Collections instances\nconst numeric = 'numeric';\nconst ascii = 'ascii';\nconst alpha = 'alpha';\nconst asciinumeric = 'asciinumeric';\nconst alphanumeric = 'alphanumeric';\nconst domain = 'domain';\nconst emoji = 'emoji';\nconst scheme = 'scheme';\nconst slashscheme = 'slashscheme';\nconst whitespace = 'whitespace';\n\n/**\n * @template T\n * @param {string} name\n * @param {Collections<T>} groups to register in\n * @returns {T[]} Current list of tokens in the given collection\n */\nfunction registerGroup(name, groups) {\n if (!(name in groups)) {\n groups[name] = [];\n }\n return groups[name];\n}\n\n/**\n * @template T\n * @param {T} t token to add\n * @param {Collections<T>} groups\n * @param {Flags} flags\n */\nfunction addToGroups(t, flags, groups) {\n if (flags[numeric]) {\n flags[asciinumeric] = true;\n flags[alphanumeric] = true;\n }\n if (flags[ascii]) {\n flags[asciinumeric] = true;\n flags[alpha] = true;\n }\n if (flags[asciinumeric]) {\n flags[alphanumeric] = true;\n }\n if (flags[alpha]) {\n flags[alphanumeric] = true;\n }\n if (flags[alphanumeric]) {\n flags[domain] = true;\n }\n if (flags[emoji]) {\n flags[domain] = true;\n }\n for (const k in flags) {\n const group = registerGroup(k, groups);\n if (group.indexOf(t) < 0) {\n group.push(t);\n }\n }\n}\n\n/**\n * @template T\n * @param {T} t token to check\n * @param {Collections<T>} groups\n * @returns {Flags} group flags that contain this token\n */\nfunction flagsForToken(t, groups) {\n const result = {};\n for (const c in groups) {\n if (groups[c].indexOf(t) >= 0) {\n result[c] = true;\n }\n }\n return result;\n}\n\n/**\n * @template T\n * @typedef {null | T } Transition\n */\n\n/**\n * Define a basic state machine state. j is the list of character transitions,\n * jr is the list of regex-match transitions, jd is the default state to\n * transition to t is the accepting token type, if any. If this is the terminal\n * state, then it does not emit a token.\n *\n * The template type T represents the type of the token this state accepts. This\n * should be a string (such as of the token exports in `text.js`) or a\n * MultiToken subclass (from `multi.js`)\n *\n * @template T\n * @param {T} [token] Token that this state emits\n */\nfunction State(token = null) {\n // this.n = null; // DEBUG: State name\n /** @type {{ [input: string]: State<T> }} j */\n this.j = {}; // IMPLEMENTATION 1\n // this.j = []; // IMPLEMENTATION 2\n /** @type {[RegExp, State<T>][]} jr */\n this.jr = [];\n /** @type {?State<T>} jd */\n this.jd = null;\n /** @type {?T} t */\n this.t = token;\n}\n\n/**\n * Scanner token groups\n * @type Collections<string>\n */\nState.groups = {};\nState.prototype = {\n accepts() {\n return !!this.t;\n },\n /**\n * Follow an existing transition from the given input to the next state.\n * Does not mutate.\n * @param {string} input character or token type to transition on\n * @returns {?State<T>} the next state, if any\n */\n go(input) {\n const state = this;\n const nextState = state.j[input];\n if (nextState) {\n return nextState;\n }\n for (let i = 0; i < state.jr.length; i++) {\n const regex = state.jr[i][0];\n const nextState = state.jr[i][1]; // note: might be empty to prevent default jump\n if (nextState && regex.test(input)) {\n return nextState;\n }\n }\n // Nowhere left to jump! Return default, if any\n return state.jd;\n },\n /**\n * Whether the state has a transition for the given input. Set the second\n * argument to true to only look for an exact match (and not a default or\n * regular-expression-based transition)\n * @param {string} input\n * @param {boolean} exactOnly\n */\n has(input, exactOnly = false) {\n return exactOnly ? input in this.j : !!this.go(input);\n },\n /**\n * Short for \"transition all\"; create a transition from the array of items\n * in the given list to the same final resulting state.\n * @param {string | string[]} inputs Group of inputs to transition on\n * @param {Transition<T> | State<T>} [next] Transition options\n * @param {Flags} [flags] Collections flags to add token to\n * @param {Collections<T>} [groups] Master list of token groups\n */\n ta(inputs, next, flags, groups) {\n for (let i = 0; i < inputs.length; i++) {\n this.tt(inputs[i], next, flags, groups);\n }\n },\n /**\n * Short for \"take regexp transition\"; defines a transition for this state\n * when it encounters a token which matches the given regular expression\n * @param {RegExp} regexp Regular expression transition (populate first)\n * @param {T | State<T>} [next] Transition options\n * @param {Flags} [flags] Collections flags to add token to\n * @param {Collections<T>} [groups] Master list of token groups\n * @returns {State<T>} taken after the given input\n */\n tr(regexp, next, flags, groups) {\n groups = groups || State.groups;\n let nextState;\n if (next && next.j) {\n nextState = next;\n } else {\n // Token with maybe token groups\n nextState = new State(next);\n if (flags && groups) {\n addToGroups(next, flags, groups);\n }\n }\n this.jr.push([regexp, nextState]);\n return nextState;\n },\n /**\n * Short for \"take transitions\", will take as many sequential transitions as\n * the length of the given input and returns the\n * resulting final state.\n * @param {string | string[]} input\n * @param {T | State<T>} [next] Transition options\n * @param {Flags} [flags] Collections flags to add token to\n * @param {Collections<T>} [groups] Master list of token groups\n * @returns {State<T>} taken after the given input\n */\n ts(input, next, flags, groups) {\n let state = this;\n const len = input.length;\n if (!len) {\n return state;\n }\n for (let i = 0; i < len - 1; i++) {\n state = state.tt(input[i]);\n }\n return state.tt(input[len - 1], next, flags, groups);\n },\n /**\n * Short for \"take transition\", this is a method for building/working with\n * state machines.\n *\n * If a state already exists for the given input, returns it.\n *\n * If a token is specified, that state will emit that token when reached by\n * the linkify engine.\n *\n * If no state exists, it will be initialized with some default transitions\n * that resemble existing default transitions.\n *\n * If a state is given for the second argument, that state will be\n * transitioned to on the given input regardless of what that input\n * previously did.\n *\n * Specify a token group flags to define groups that this token belongs to.\n * The token will be added to corresponding entires in the given groups\n * object.\n *\n * @param {string} input character, token type to transition on\n * @param {T | State<T>} [next] Transition options\n * @param {Flags} [flags] Collections flags to add token to\n * @param {Collections<T>} [groups] Master list of groups\n * @returns {State<T>} taken after the given input\n */\n tt(input, next, flags, groups) {\n groups = groups || State.groups;\n const state = this;\n\n // Check if existing state given, just a basic transition\n if (next && next.j) {\n state.j[input] = next;\n return next;\n }\n const t = next;\n\n // Take the transition with the usual default mechanisms and use that as\n // a template for creating the next state\n let nextState,\n templateState = state.go(input);\n if (templateState) {\n nextState = new State();\n Object.assign(nextState.j, templateState.j);\n nextState.jr.push.apply(nextState.jr, templateState.jr);\n nextState.jd = templateState.jd;\n nextState.t = templateState.t;\n } else {\n nextState = new State();\n }\n if (t) {\n // Ensure newly token is in the same groups as the old token\n if (groups) {\n if (nextState.t && typeof nextState.t === 'string') {\n const allFlags = Object.assign(flagsForToken(nextState.t, groups), flags);\n addToGroups(t, allFlags, groups);\n } else if (flags) {\n addToGroups(t, flags, groups);\n }\n }\n nextState.t = t; // overwrite anything that was previously there\n }\n state.j[input] = nextState;\n return nextState;\n }\n};\n\n// Helper functions to improve minification (not exported outside linkifyjs module)\n\n/**\n * @template T\n * @param {State<T>} state\n * @param {string | string[]} input\n * @param {Flags} [flags]\n * @param {Collections<T>} [groups]\n */\nconst ta = (state, input, next, flags, groups) => state.ta(input, next, flags, groups);\n\n/**\n * @template T\n * @param {State<T>} state\n * @param {RegExp} regexp\n * @param {T | State<T>} [next]\n * @param {Flags} [flags]\n * @param {Collections<T>} [groups]\n */\nconst tr = (state, regexp, next, flags, groups) => state.tr(regexp, next, flags, groups);\n\n/**\n * @template T\n * @param {State<T>} state\n * @param {string | string[]} input\n * @param {T | State<T>} [next]\n * @param {Flags} [flags]\n * @param {Collections<T>} [groups]\n */\nconst ts = (state, input, next, flags, groups) => state.ts(input, next, flags, groups);\n\n/**\n * @template T\n * @param {State<T>} state\n * @param {string} input\n * @param {T | State<T>} [next]\n * @param {Collections<T>} [groups]\n * @param {Flags} [flags]\n */\nconst tt = (state, input, next, flags, groups) => state.tt(input, next, flags, groups);\n\n/******************************************************************************\nText Tokens\nIdentifiers for token outputs from the regexp scanner\n******************************************************************************/\n\n// A valid web domain token\nconst WORD = 'WORD'; // only contains a-z\nconst UWORD = 'UWORD'; // contains letters other than a-z, used for IDN\nconst ASCIINUMERICAL = 'ASCIINUMERICAL'; // contains a-z, 0-9\nconst ALPHANUMERICAL = 'ALPHANUMERICAL'; // contains numbers and letters other than a-z, used for IDN\n\n// Special case of word\nconst LOCALHOST = 'LOCALHOST';\n\n// Valid top-level domain, special case of WORD (see tlds.js)\nconst TLD = 'TLD';\n\n// Valid IDN TLD, special case of UWORD (see tlds.js)\nconst UTLD = 'UTLD';\n\n// The scheme portion of a web URI protocol. Supported types include: `mailto`,\n// `file`, and user-defined custom protocols. Limited to schemes that contain\n// only letters\nconst SCHEME = 'SCHEME';\n\n// Similar to SCHEME, except makes distinction for schemes that must always be\n// followed by `://`, not just `:`. Supported types include `http`, `https`,\n// `ftp`, `ftps`\nconst SLASH_SCHEME = 'SLASH_SCHEME';\n\n// Any sequence of digits 0-9\nconst NUM = 'NUM';\n\n// Any number of consecutive whitespace characters that are not newline\nconst WS = 'WS';\n\n// New line (unix style)\nconst NL = 'NL'; // \\n\n\n// Opening/closing bracket classes\n// TODO: Rename OPEN -> LEFT and CLOSE -> RIGHT in v5 to fit with Unicode names\n// Also rename angle brackes to LESSTHAN and GREATER THAN\nconst OPENBRACE = 'OPENBRACE'; // {\nconst CLOSEBRACE = 'CLOSEBRACE'; // }\nconst OPENBRACKET = 'OPENBRACKET'; // [\nconst CLOSEBRACKET = 'CLOSEBRACKET'; // ]\nconst OPENPAREN = 'OPENPAREN'; // (\nconst CLOSEPAREN = 'CLOSEPAREN'; // )\nconst OPENANGLEBRACKET = 'OPENANGLEBRACKET'; // <\nconst CLOSEANGLEBRACKET = 'CLOSEANGLEBRACKET'; // >\nconst FULLWIDTHLEFTPAREN = 'FULLWIDTHLEFTPAREN'; // (\nconst FULLWIDTHRIGHTPAREN = 'FULLWIDTHRIGHTPAREN'; // )\nconst LEFTCORNERBRACKET = 'LEFTCORNERBRACKET'; // 「\nconst RIGHTCORNERBRACKET = 'RIGHTCORNERBRACKET'; // 」\nconst LEFTWHITECORNERBRACKET = 'LEFTWHITECORNERBRACKET'; // 『\nconst RIGHTWHITECORNERBRACKET = 'RIGHTWHITECORNERBRACKET'; // 』\nconst FULLWIDTHLESSTHAN = 'FULLWIDTHLESSTHAN'; // <\nconst FULLWIDTHGREATERTHAN = 'FULLWIDTHGREATERTHAN'; // >\n\n// Various symbols\nconst AMPERSAND = 'AMPERSAND'; // &\nconst APOSTROPHE = 'APOSTROPHE'; // '\nconst ASTERISK = 'ASTERISK'; // *\nconst AT = 'AT'; // @\nconst BACKSLASH = 'BACKSLASH'; // \\\nconst BACKTICK = 'BACKTICK'; // `\nconst CARET = 'CARET'; // ^\nconst COLON = 'COLON'; // :\nconst COMMA = 'COMMA'; // ,\nconst DOLLAR = 'DOLLAR'; // $\nconst DOT = 'DOT'; // .\nconst EQUALS = 'EQUALS'; // =\nconst EXCLAMATION = 'EXCLAMATION'; // !\nconst HYPHEN = 'HYPHEN'; // -\nconst PERCENT = 'PERCENT'; // %\nconst PIPE = 'PIPE'; // |\nconst PLUS = 'PLUS'; // +\nconst POUND = 'POUND'; // #\nconst QUERY = 'QUERY'; // ?\nconst QUOTE = 'QUOTE'; // \"\nconst FULLWIDTHMIDDLEDOT = 'FULLWIDTHMIDDLEDOT'; // ・\n\nconst SEMI = 'SEMI'; // ;\nconst SLASH = 'SLASH'; // /\nconst TILDE = 'TILDE'; // ~\nconst UNDERSCORE = 'UNDERSCORE'; // _\n\n// Emoji symbol\nconst EMOJI$1 = 'EMOJI';\n\n// Default token - anything that is not one of the above\nconst SYM = 'SYM';\n\nvar tk = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tALPHANUMERICAL: ALPHANUMERICAL,\n\tAMPERSAND: AMPERSAND,\n\tAPOSTROPHE: APOSTROPHE,\n\tASCIINUMERICAL: ASCIINUMERICAL,\n\tASTERISK: ASTERISK,\n\tAT: AT,\n\tBACKSLASH: BACKSLASH,\n\tBACKTICK: BACKTICK,\n\tCARET: CARET,\n\tCLOSEANGLEBRACKET: CLOSEANGLEBRACKET,\n\tCLOSEBRACE: CLOSEBRACE,\n\tCLOSEBRACKET: CLOSEBRACKET,\n\tCLOSEPAREN: CLOSEPAREN,\n\tCOLON: COLON,\n\tCOMMA: COMMA,\n\tDOLLAR: DOLLAR,\n\tDOT: DOT,\n\tEMOJI: EMOJI$1,\n\tEQUALS: EQUALS,\n\tEXCLAMATION: EXCLAMATION,\n\tFULLWIDTHGREATERTHAN: FULLWIDTHGREATERTHAN,\n\tFULLWIDTHLEFTPAREN: FULLWIDTHLEFTPAREN,\n\tFULLWIDTHLESSTHAN: FULLWIDTHLESSTHAN,\n\tFULLWIDTHMIDDLEDOT: FULLWIDTHMIDDLEDOT,\n\tFULLWIDTHRIGHTPAREN: FULLWIDTHRIGHTPAREN,\n\tHYPHEN: HYPHEN,\n\tLEFTCORNERBRACKET: LEFTCORNERBRACKET,\n\tLEFTWHITECORNERBRACKET: LEFTWHITECORNERBRACKET,\n\tLOCALHOST: LOCALHOST,\n\tNL: NL,\n\tNUM: NUM,\n\tOPENANGLEBRACKET: OPENANGLEBRACKET,\n\tOPENBRACE: OPENBRACE,\n\tOPENBRACKET: OPENBRACKET,\n\tOPENPAREN: OPENPAREN,\n\tPERCENT: PERCENT,\n\tPIPE: PIPE,\n\tPLUS: PLUS,\n\tPOUND: POUND,\n\tQUERY: QUERY,\n\tQUOTE: QUOTE,\n\tRIGHTCORNERBRACKET: RIGHTCORNERBRACKET,\n\tRIGHTWHITECORNERBRACKET: RIGHTWHITECORNERBRACKET,\n\tSCHEME: SCHEME,\n\tSEMI: SEMI,\n\tSLASH: SLASH,\n\tSLASH_SCHEME: SLASH_SCHEME,\n\tSYM: SYM,\n\tTILDE: TILDE,\n\tTLD: TLD,\n\tUNDERSCORE: UNDERSCORE,\n\tUTLD: UTLD,\n\tUWORD: UWORD,\n\tWORD: WORD,\n\tWS: WS\n});\n\n// Note that these two Unicode ones expand into a really big one with Babel\nconst ASCII_LETTER = /[a-z]/;\nconst LETTER = /\\p{L}/u; // Any Unicode character with letter data type\nconst EMOJI = /\\p{Emoji}/u; // Any Unicode emoji character\nconst EMOJI_VARIATION$1 = /\\ufe0f/;\nconst DIGIT = /\\d/;\nconst SPACE = /\\s/;\n\nvar regexp = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tASCII_LETTER: ASCII_LETTER,\n\tDIGIT: DIGIT,\n\tEMOJI: EMOJI,\n\tEMOJI_VARIATION: EMOJI_VARIATION$1,\n\tLETTER: LETTER,\n\tSPACE: SPACE\n});\n\n/**\n\tThe scanner provides an interface that takes a string of text as input, and\n\toutputs an array of tokens instances that can be used for easy URL parsing.\n*/\n\nconst CR = '\\r'; // carriage-return character\nconst LF = '\\n'; // line-feed character\nconst EMOJI_VARIATION = '\\ufe0f'; // Variation selector, follows heart and others\nconst EMOJI_JOINER = '\\u200d'; // zero-width joiner\nconst OBJECT_REPLACEMENT = '\\ufffc'; // whitespace placeholder that sometimes appears in rich text editors\n\nlet tlds = null,\n utlds = null; // don't change so only have to be computed once\n\n/**\n * Scanner output token:\n * - `t` is the token name (e.g., 'NUM', 'EMOJI', 'TLD')\n * - `v` is the value of the token (e.g., '123', '❤️', 'com')\n * - `s` is the start index of the token in the original string\n * - `e` is the end index of the token in the original string\n * @typedef {{t: string, v: string, s: number, e: number}} Token\n */\n\n/**\n * @template T\n * @typedef {{ [collection: string]: T[] }} Collections\n */\n\n/**\n * Initialize the scanner character-based state machine for the given start\n * state\n * @param {[string, boolean][]} customSchemes List of custom schemes, where each\n * item is a length-2 tuple with the first element set to the string scheme, and\n * the second element set to `true` if the `://` after the scheme is optional\n */\nfunction init$2(customSchemes = []) {\n // Frequently used states (name argument removed during minification)\n /** @type Collections<string> */\n const groups = {}; // of tokens\n State.groups = groups;\n /** @type State<string> */\n const Start = new State();\n if (tlds == null) {\n tlds = decodeTlds(encodedTlds);\n }\n if (utlds == null) {\n utlds = decodeTlds(encodedUtlds);\n }\n\n // States for special URL symbols that accept immediately after start\n tt(Start, \"'\", APOSTROPHE);\n tt(Start, '{', OPENBRACE);\n tt(Start, '}', CLOSEBRACE);\n tt(Start, '[', OPENBRACKET);\n tt(Start, ']', CLOSEBRACKET);\n tt(Start, '(', OPENPAREN);\n tt(Start, ')', CLOSEPAREN);\n tt(Start, '<', OPENANGLEBRACKET);\n tt(Start, '>', CLOSEANGLEBRACKET);\n tt(Start, '(', FULLWIDTHLEFTPAREN);\n tt(Start, ')', FULLWIDTHRIGHTPAREN);\n tt(Start, '「', LEFTCORNERBRACKET);\n tt(Start, '」', RIGHTCORNERBRACKET);\n tt(Start, '『', LEFTWHITECORNERBRACKET);\n tt(Start, '』', RIGHTWHITECORNERBRACKET);\n tt(Start, '<', FULLWIDTHLESSTHAN);\n tt(Start, '>', FULLWIDTHGREATERTHAN);\n tt(Start, '&', AMPERSAND);\n tt(Start, '*', ASTERISK);\n tt(Start, '@', AT);\n tt(Start, '`', BACKTICK);\n tt(Start, '^', CARET);\n tt(Start, ':', COLON);\n tt(Start, ',', COMMA);\n tt(Start, '$', DOLLAR);\n tt(Start, '.', DOT);\n tt(Start, '=', EQUALS);\n tt(Start, '!', EXCLAMATION);\n tt(Start, '-', HYPHEN);\n tt(Start, '%', PERCENT);\n tt(Start, '|', PIPE);\n tt(Start, '+', PLUS);\n tt(Start, '#', POUND);\n tt(Start, '?', QUERY);\n tt(Start, '\"', QUOTE);\n tt(Start, '/', SLASH);\n tt(Start, ';', SEMI);\n tt(Start, '~', TILDE);\n tt(Start, '_', UNDERSCORE);\n tt(Start, '\\\\', BACKSLASH);\n tt(Start, '・', FULLWIDTHMIDDLEDOT);\n const Num = tr(Start, DIGIT, NUM, {\n [numeric]: true\n });\n tr(Num, DIGIT, Num);\n const Asciinumeric = tr(Num, ASCII_LETTER, ASCIINUMERICAL, {\n [asciinumeric]: true\n });\n const Alphanumeric = tr(Num, LETTER, ALPHANUMERICAL, {\n [alphanumeric]: true\n });\n\n // State which emits a word token\n const Word = tr(Start, ASCII_LETTER, WORD, {\n [ascii]: true\n });\n tr(Word, DIGIT, Asciinumeric);\n tr(Word, ASCII_LETTER, Word);\n tr(Asciinumeric, DIGIT, Asciinumeric);\n tr(Asciinumeric, ASCII_LETTER, Asciinumeric);\n\n // Same as previous, but specific to non-fsm.ascii alphabet words\n const UWord = tr(Start, LETTER, UWORD, {\n [alpha]: true\n });\n tr(UWord, ASCII_LETTER); // Non-accepting\n tr(UWord, DIGIT, Alphanumeric);\n tr(UWord, LETTER, UWord);\n tr(Alphanumeric, DIGIT, Alphanumeric);\n tr(Alphanumeric, ASCII_LETTER); // Non-accepting\n tr(Alphanumeric, LETTER, Alphanumeric); // Non-accepting\n\n // Whitespace jumps\n // Tokens of only non-newline whitespace are arbitrarily long\n // If any whitespace except newline, more whitespace!\n const Nl = tt(Start, LF, NL, {\n [whitespace]: true\n });\n const Cr = tt(Start, CR, WS, {\n [whitespace]: true\n });\n const Ws = tr(Start, SPACE, WS, {\n [whitespace]: true\n });\n tt(Start, OBJECT_REPLACEMENT, Ws);\n tt(Cr, LF, Nl); // \\r\\n\n tt(Cr, OBJECT_REPLACEMENT, Ws);\n tr(Cr, SPACE, Ws);\n tt(Ws, CR); // non-accepting state to avoid mixing whitespaces\n tt(Ws, LF); // non-accepting state to avoid mixing whitespaces\n tr(Ws, SPACE, Ws);\n tt(Ws, OBJECT_REPLACEMENT, Ws);\n\n // Emoji tokens. They are not grouped by the scanner except in cases where a\n // zero-width joiner is present\n const Emoji = tr(Start, EMOJI, EMOJI$1, {\n [emoji]: true\n });\n tt(Emoji, '#'); // no transition, emoji regex seems to match #\n tr(Emoji, EMOJI, Emoji);\n tt(Emoji, EMOJI_VARIATION, Emoji);\n // tt(Start, EMOJI_VARIATION, Emoji); // This one is sketchy\n\n const EmojiJoiner = tt(Emoji, EMOJI_JOINER);\n tt(EmojiJoiner, '#');\n tr(EmojiJoiner, EMOJI, Emoji);\n // tt(EmojiJoiner, EMOJI_VARIATION, Emoji); // also sketchy\n\n // Generates states for top-level domains\n // Note that this is most accurate when tlds are in alphabetical order\n const wordjr = [[ASCII_LETTER, Word], [DIGIT, Asciinumeric]];\n const uwordjr = [[ASCII_LETTER, null], [LETTER, UWord], [DIGIT, Alphanumeric]];\n for (let i = 0; i < tlds.length; i++) {\n fastts(Start, tlds[i], TLD, WORD, wordjr);\n }\n for (let i = 0; i < utlds.length; i++) {\n fastts(Start, utlds[i], UTLD, UWORD, uwordjr);\n }\n addToGroups(TLD, {\n tld: true,\n ascii: true\n }, groups);\n addToGroups(UTLD, {\n utld: true,\n alpha: true\n }, groups);\n\n // Collect the states generated by different protocols. NOTE: If any new TLDs\n // get added that are also protocols, set the token to be the same as the\n // protocol to ensure parsing works as expected.\n fastts(Start, 'file', SCHEME, WORD, wordjr);\n fastts(Start, 'mailto', SCHEME, WORD, wordjr);\n fastts(Start, 'http', SLASH_SCHEME, WORD, wordjr);\n fastts(Start, 'https', SLASH_SCHEME, WORD, wordjr);\n fastts(Start, 'ftp', SLASH_SCHEME, WORD, wordjr);\n fastts(Start, 'ftps', SLASH_SCHEME, WORD, wordjr);\n addToGroups(SCHEME, {\n scheme: true,\n ascii: true\n }, groups);\n addToGroups(SLASH_SCHEME, {\n slashscheme: true,\n ascii: true\n }, groups);\n\n // Register custom schemes. Assumes each scheme is asciinumeric with hyphens\n customSchemes = customSchemes.sort((a, b) => a[0] > b[0] ? 1 : -1);\n for (let i = 0; i < customSchemes.length; i++) {\n const sch = customSchemes[i][0];\n const optionalSlashSlash = customSchemes[i][1];\n const flags = optionalSlashSlash ? {\n [scheme]: true\n } : {\n [slashscheme]: true\n };\n if (sch.indexOf('-') >= 0) {\n flags[domain] = true;\n } else if (!ASCII_LETTER.test(sch)) {\n flags[numeric] = true; // numbers only\n } else if (DIGIT.test(sch)) {\n flags[asciinumeric] = true;\n } else {\n flags[ascii] = true;\n }\n ts(Start, sch, sch, flags);\n }\n\n // Localhost token\n ts(Start, 'localhost', LOCALHOST, {\n ascii: true\n });\n\n // Set default transition for start state (some symbol)\n Start.jd = new State(SYM);\n return {\n start: Start,\n tokens: Object.assign({\n groups\n }, tk)\n };\n}\n\n/**\n\tGiven a string, returns an array of TOKEN instances representing the\n\tcomposition of that string.\n\n\t@method run\n\t@param {State<string>} start scanner starting state\n\t@param {string} str input string to scan\n\t@return {Token[]} list of tokens, each with a type and value\n*/\nfunction run$1(start, str) {\n // State machine is not case sensitive, so input is tokenized in lowercased\n // form (still returns regular case). Uses selective `toLowerCase` because\n // lowercasing the entire string causes the length and character position to\n // vary in some non-English strings with V8-based runtimes.\n const iterable = stringToArray(str.replace(/[A-Z]/g, c => c.toLowerCase()));\n const charCount = iterable.length; // <= len if there are emojis, etc\n const tokens = []; // return value\n\n // cursor through the string itself, accounting for characters that have\n // width with length 2 such as emojis\n let cursor = 0;\n\n // Cursor through the array-representation of the string\n let charCursor = 0;\n\n // Tokenize the string\n while (charCursor < charCount) {\n let state = start;\n let nextState = null;\n let tokenLength = 0;\n let latestAccepting = null;\n let sinceAccepts = -1;\n let charsSinceAccepts = -1;\n while (charCursor < charCount && (nextState = state.go(iterable[charCursor]))) {\n state = nextState;\n\n // Keep track of the latest accepting state\n if (state.accepts()) {\n sinceAccepts = 0;\n charsSinceAccepts = 0;\n latestAccepting = state;\n } else if (sinceAccepts >= 0) {\n sinceAccepts += iterable[charCursor].length;\n charsSinceAccepts++;\n }\n tokenLength += iterable[charCursor].length;\n cursor += iterable[charCursor].length;\n charCursor++;\n }\n\n // Roll back to the latest accepting state\n cursor -= sinceAccepts;\n charCursor -= charsSinceAccepts;\n tokenLength -= sinceAccepts;\n\n // No more jumps, just make a new token from the last accepting one\n tokens.push({\n t: latestAccepting.t,\n // token type/name\n v: str.slice(cursor - tokenLength, cursor),\n // string value\n s: cursor - tokenLength,\n // start index\n e: cursor // end index (excluding)\n });\n }\n return tokens;\n}\n\n/**\n * Convert a String to an Array of characters, taking into account that some\n * characters like emojis take up two string indexes.\n *\n * Adapted from core-js (MIT license)\n * https://github.com/zloirock/core-js/blob/2d69cf5f99ab3ea3463c395df81e5a15b68f49d9/packages/core-js/internals/string-multibyte.js\n *\n * @function stringToArray\n * @param {string} str\n * @returns {string[]}\n */\nfunction stringToArray(str) {\n const result = [];\n const len = str.length;\n let index = 0;\n while (index < len) {\n let first = str.charCodeAt(index);\n let second;\n let char = first < 0xd800 || first > 0xdbff || index + 1 === len || (second = str.charCodeAt(index + 1)) < 0xdc00 || second > 0xdfff ? str[index] // single character\n : str.slice(index, index + 2); // two-index characters\n result.push(char);\n index += char.length;\n }\n return result;\n}\n\n/**\n * Fast version of ts function for when transition defaults are well known\n * @param {State<string>} state\n * @param {string} input\n * @param {string} t\n * @param {string} defaultt\n * @param {[RegExp, State<string>][]} jr\n * @returns {State<string>}\n */\nfunction fastts(state, input, t, defaultt, jr) {\n let next;\n const len = input.length;\n for (let i = 0; i < len - 1; i++) {\n const char = input[i];\n if (state.j[char]) {\n next = state.j[char];\n } else {\n next = new State(defaultt);\n next.jr = jr.slice();\n state.j[char] = next;\n }\n state = next;\n }\n next = new State(t);\n next.jr = jr.slice();\n state.j[input[len - 1]] = next;\n return next;\n}\n\n/**\n * Converts a string of Top-Level Domain names encoded in update-tlds.js back\n * into a list of strings.\n * @param {str} encoded encoded TLDs string\n * @returns {str[]} original TLDs list\n */\nfunction decodeTlds(encoded) {\n const words = [];\n const stack = [];\n let i = 0;\n let digits = '0123456789';\n while (i < encoded.length) {\n let popDigitCount = 0;\n while (digits.indexOf(encoded[i + popDigitCount]) >= 0) {\n popDigitCount++; // encountered some digits, have to pop to go one level up trie\n }\n if (popDigitCount > 0) {\n words.push(stack.join('')); // whatever preceded the pop digits must be a word\n for (let popCount = parseInt(encoded.substring(i, i + popDigitCount), 10); popCount > 0; popCount--) {\n stack.pop();\n }\n i += popDigitCount;\n } else {\n stack.push(encoded[i]); // drop down a level into the trie\n i++;\n }\n }\n return words;\n}\n\n/**\n * An object where each key is a valid DOM Event Name such as `click` or `focus`\n * and each value is an event handler function.\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/Element#events\n * @typedef {?{ [event: string]: Function }} EventListeners\n */\n\n/**\n * All formatted properties required to render a link, including `tagName`,\n * `attributes`, `content` and `eventListeners`.\n * @typedef {{ tagName: any, attributes: {[attr: string]: any}, content: string,\n * eventListeners: EventListeners }} IntermediateRepresentation\n */\n\n/**\n * Specify either an object described by the template type `O` or a function.\n *\n * The function takes a string value (usually the link's href attribute), the\n * link type (`'url'`, `'hashtag`', etc.) and an internal token representation\n * of the link. It should return an object of the template type `O`\n * @template O\n * @typedef {O | ((value: string, type: string, token: MultiToken) => O)} OptObj\n */\n\n/**\n * Specify either a function described by template type `F` or an object.\n *\n * Each key in the object should be a link type (`'url'`, `'hashtag`', etc.). Each\n * value should be a function with template type `F` that is called when the\n * corresponding link type is encountered.\n * @template F\n * @typedef {F | { [type: string]: F}} OptFn\n */\n\n/**\n * Specify either a value with template type `V`, a function that returns `V` or\n * an object where each value resolves to `V`.\n *\n * The function takes a string value (usually the link's href attribute), the\n * link type (`'url'`, `'hashtag`', etc.) and an internal token representation\n * of the link. It should return an object of the template type `V`\n *\n * For the object, each key should be a link type (`'url'`, `'hashtag`', etc.).\n * Each value should either have type `V` or a function that returns V. This\n * function similarly takes a string value and a token.\n *\n * Example valid types for `Opt<string>`:\n *\n * ```js\n * 'hello'\n * (value, type, token) => 'world'\n * { url: 'hello', email: (value, token) => 'world'}\n * ```\n * @template V\n * @typedef {V | ((value: string, type: string, token: MultiToken) => V) | { [type: string]: V | ((value: string, token: MultiToken) => V) }} Opt\n */\n\n/**\n * See available options: https://linkify.js.org/docs/options.html\n * @typedef {{\n * \tdefaultProtocol?: string,\n * events?: OptObj<EventListeners>,\n * \tformat?: Opt<string>,\n * \tformatHref?: Opt<string>,\n * \tnl2br?: boolean,\n * \ttagName?: Opt<any>,\n * \ttarget?: Opt<string>,\n * \trel?: Opt<string>,\n * \tvalidate?: Opt<boolean>,\n * \ttruncate?: Opt<number>,\n * \tclassName?: Opt<string>,\n * \tattributes?: OptObj<({ [attr: string]: any })>,\n * ignoreTags?: string[],\n * \trender?: OptFn<((ir: IntermediateRepresentation) => any)>\n * }} Opts\n */\n\n/**\n * @type Required<Opts>\n */\nconst defaults = {\n defaultProtocol: 'http',\n events: null,\n format: noop,\n formatHref: noop,\n nl2br: false,\n tagName: 'a',\n target: null,\n rel: null,\n validate: true,\n truncate: Infinity,\n className: null,\n attributes: null,\n ignoreTags: [],\n render: null\n};\n\n/**\n * Utility class for linkify interfaces to apply specified\n * {@link Opts formatting and rendering options}.\n *\n * @param {Opts | Options} [opts] Option value overrides.\n * @param {(ir: IntermediateRepresentation) => any} [defaultRender] (For\n * internal use) default render function that determines how to generate an\n * HTML element based on a link token's derived tagName, attributes and HTML.\n * Similar to render option\n */\nfunction Options(opts, defaultRender = null) {\n let o = Object.assign({}, defaults);\n if (opts) {\n o = Object.assign(o, opts instanceof Options ? opts.o : opts);\n }\n\n // Ensure all ignored tags are uppercase\n const ignoredTags = o.ignoreTags;\n const uppercaseIgnoredTags = [];\n for (let i = 0; i < ignoredTags.length; i++) {\n uppercaseIgnoredTags.push(ignoredTags[i].toUpperCase());\n }\n /** @protected */\n this.o = o;\n if (defaultRender) {\n this.defaultRender = defaultRender;\n }\n this.ignoreTags = uppercaseIgnoredTags;\n}\nOptions.prototype = {\n o: defaults,\n /**\n * @type string[]\n */\n ignoreTags: [],\n /**\n * @param {IntermediateRepresentation} ir\n * @returns {any}\n */\n defaultRender(ir) {\n return ir;\n },\n /**\n * Returns true or false based on whether a token should be displayed as a\n * link based on the user options.\n * @param {MultiToken} token\n * @returns {boolean}\n */\n check(token) {\n return this.get('validate', token.toString(), token);\n },\n // Private methods\n\n /**\n * Resolve an option's value based on the value of the option and the given\n * params. If operator and token are specified and the target option is\n * callable, automatically calls the function with the given argument.\n * @template {keyof Opts} K\n * @param {K} key Name of option to use\n * @param {string} [operator] will be passed to the target option if it's a\n * function. If not specified, RAW function value gets returned\n * @param {MultiToken} [token] The token from linkify.tokenize\n * @returns {Opts[K] | any}\n */\n get(key, operator, token) {\n const isCallable = operator != null;\n let option = this.o[key];\n if (!option) {\n return option;\n }\n if (typeof option === 'object') {\n option = token.t in option ? option[token.t] : defaults[key];\n if (typeof option === 'function' && isCallable) {\n option = option(operator, token);\n }\n } else if (typeof option === 'function' && isCallable) {\n option = option(operator, token.t, token);\n }\n return option;\n },\n /**\n * @template {keyof Opts} L\n * @param {L} key Name of options object to use\n * @param {string} [operator]\n * @param {MultiToken} [token]\n * @returns {Opts[L] | any}\n */\n getObj(key, operator, token) {\n let obj = this.o[key];\n if (typeof obj === 'function' && operator != null) {\n obj = obj(operator, token.t, token);\n }\n return obj;\n },\n /**\n * Convert the given token to a rendered element that may be added to the\n * calling-interface's DOM\n * @param {MultiToken} token Token to render to an HTML element\n * @returns {any} Render result; e.g., HTML string, DOM element, React\n * Component, etc.\n */\n render(token) {\n const ir = token.render(this); // intermediate representation\n const renderFn = this.get('render', null, token) || this.defaultRender;\n return renderFn(ir, token.t, token);\n }\n};\nfunction noop(val) {\n return val;\n}\n\nvar options = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tOptions: Options,\n\tdefaults: defaults\n});\n\n/******************************************************************************\n\tMulti-Tokens\n\tTokens composed of arrays of TextTokens\n******************************************************************************/\n\n/**\n * @param {string} value\n * @param {Token[]} tokens\n */\nfunction MultiToken(value, tokens) {\n this.t = 'token';\n this.v = value;\n this.tk = tokens;\n}\n\n/**\n * Abstract class used for manufacturing tokens of text tokens. That is rather\n * than the value for a token being a small string of text, it's value an array\n * of text tokens.\n *\n * Used for grouping together URLs, emails, hashtags, and other potential\n * creations.\n * @class MultiToken\n * @property {string} t\n * @property {string} v\n * @property {Token[]} tk\n * @abstract\n */\nMultiToken.prototype = {\n isLink: false,\n /**\n * Return the string this token represents.\n * @return {string}\n */\n toString() {\n return this.v;\n },\n /**\n * What should the value for this token be in the `href` HTML attribute?\n * Returns the `.toString` value by default.\n * @param {string} [scheme]\n * @return {string}\n */\n toHref(scheme) {\n return this.toString();\n },\n /**\n * @param {Options} options Formatting options\n * @returns {string}\n */\n toFormattedString(options) {\n const val = this.toString();\n const truncate = options.get('truncate', val, this);\n const formatted = options.get('format', val, this);\n return truncate && formatted.length > truncate ? formatted.substring(0, truncate) + '…' : formatted;\n },\n /**\n *\n * @param {Options} options\n * @returns {string}\n */\n toFormattedHref(options) {\n return options.get('formatHref', this.toHref(options.get('defaultProtocol')), this);\n },\n /**\n * The start index of this token in the original input string\n * @returns {number}\n */\n startIndex() {\n return this.tk[0].s;\n },\n /**\n * The end index of this token in the original input string (up to this\n * index but not including it)\n * @returns {number}\n */\n endIndex() {\n return this.tk[this.tk.length - 1].e;\n },\n /**\n \tReturns an object of relevant values for this token, which includes keys\n \t* type - Kind of token ('url', 'email', etc.)\n \t* value - Original text\n \t* href - The value that should be added to the anchor tag's href\n \t\tattribute\n \t\t@method toObject\n \t@param {string} [protocol] `'http'` by default\n */\n toObject(protocol = defaults.defaultProtocol) {\n return {\n type: this.t,\n value: this.toString(),\n isLink: this.isLink,\n href: this.toHref(protocol),\n start: this.startIndex(),\n end: this.endIndex()\n };\n },\n /**\n *\n * @param {Options} options Formatting option\n */\n toFormattedObject(options) {\n return {\n type: this.t,\n value: this.toFormattedString(options),\n isLink: this.isLink,\n href: this.toFormattedHref(options),\n start: this.startIndex(),\n end: this.endIndex()\n };\n },\n /**\n * Whether this token should be rendered as a link according to the given options\n * @param {Options} options\n * @returns {boolean}\n */\n validate(options) {\n return options.get('validate', this.toString(), this);\n },\n /**\n * Return an object that represents how this link should be rendered.\n * @param {Options} options Formattinng options\n */\n render(options) {\n const token = this;\n const href = this.toHref(options.get('defaultProtocol'));\n const formattedHref = options.get('formatHref', href, this);\n const tagName = options.get('tagName', href, token);\n const content = this.toFormattedString(options);\n const attributes = {};\n const className = options.get('className', href, token);\n const target = options.get('target', href, token);\n const rel = options.get('rel', href, token);\n const attrs = options.getObj('attributes', href, token);\n const eventListeners = options.getObj('events', href, token);\n attributes.href = formattedHref;\n if (className) {\n attributes.class = className;\n }\n if (target) {\n attributes.target = target;\n }\n if (rel) {\n attributes.rel = rel;\n }\n if (attrs) {\n Object.assign(attributes, attrs);\n }\n return {\n tagName,\n attributes,\n content,\n eventListeners\n };\n }\n};\n\n/**\n * Create a new token that can be emitted by the parser state machine\n * @param {string} type readable type of the token\n * @param {object} props properties to assign or override, including isLink = true or false\n * @returns {new (value: string, tokens: Token[]) => MultiToken} new token class\n */\nfunction createTokenClass(type, props) {\n class Token extends MultiToken {\n constructor(value, tokens) {\n super(value, tokens);\n this.t = type;\n }\n }\n for (const p in props) {\n Token.prototype[p] = props[p];\n }\n Token.t = type;\n return Token;\n}\n\n/**\n\tRepresents a list of tokens making up a valid email address\n*/\nconst Email = createTokenClass('email', {\n isLink: true,\n toHref() {\n return 'mailto:' + this.toString();\n }\n});\n\n/**\n\tRepresents some plain text\n*/\nconst Text = createTokenClass('text');\n\n/**\n\tMulti-linebreak token - represents a line break\n\t@class Nl\n*/\nconst Nl = createTokenClass('nl');\n\n/**\n\tRepresents a list of text tokens making up a valid URL\n\t@class Url\n*/\nconst Url = createTokenClass('url', {\n isLink: true,\n /**\n \tLowercases relevant parts of the domain and adds the protocol if\n \trequired. Note that this will not escape unsafe HTML characters in the\n \tURL.\n \t\t@param {string} [scheme] default scheme (e.g., 'https')\n \t@return {string} the full href\n */\n toHref(scheme = defaults.defaultProtocol) {\n // Check if already has a prefix scheme\n return this.hasProtocol() ? this.v : `${scheme}://${this.v}`;\n },\n /**\n * Check whether this URL token has a protocol\n * @return {boolean}\n */\n hasProtocol() {\n const tokens = this.tk;\n return tokens.length >= 2 && tokens[0].t !== LOCALHOST && tokens[1].t === COLON;\n }\n});\n\nvar multi = /*#__PURE__*/Object.freeze({\n\t__proto__: null,\n\tBase: MultiToken,\n\tEmail: Email,\n\tMultiToken: MultiToken,\n\tNl: Nl,\n\tText: Text,\n\tUrl: Url,\n\tcreateTokenClass: createTokenClass\n});\n\n/**\n\tNot exactly parser, more like the second-stage scanner (although we can\n\ttheoretically hotswap the code here with a real parser in the future... but\n\tfor a little URL-finding utility abstract syntax trees may be a little\n\toverkill).\n\n\tURL format: http://en.wikipedia.org/wiki/URI_scheme\n\tEmail format: http://en.wikipedia.org/wiki/EmailAddress (links to RFC in\n\treference)\n\n\t@module linkify\n\t@submodule parser\n\t@main run\n*/\n\nconst makeState = arg => new State(arg);\n\n/**\n * Generate the parser multi token-based state machine\n * @param {{ groups: Collections<string> }} tokens\n */\nfunction init$1({\n groups\n}) {\n // Types of characters the URL can definitely end in\n const qsAccepting = groups.domain.concat([AMPERSAND, ASTERISK, AT, BACKSLASH, BACKTICK, CARET, DOLLAR, EQUALS, HYPHEN, NUM, PERCENT, PIPE, PLUS, POUND, SLASH, SYM, TILDE, UNDERSCORE]);\n\n // Types of tokens that can follow a URL and be part of the query string\n // but cannot be the very last characters\n // Characters that cannot appear in the URL at all should be excluded\n const qsNonAccepting = [APOSTROPHE, COLON, COMMA, DOT, EXCLAMATION, PERCENT, QUERY, QUOTE, SEMI, OPENANGLEBRACKET, CLOSEANGLEBRACKET, OPENBRACE, CLOSEBRACE, CLOSEBRACKET, OPENBRACKET, OPENPAREN, CLOSEPAREN, FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN, LEFTCORNERBRACKET, RIGHTCORNERBRACKET, LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET, FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN];\n\n // For addresses without the mailto prefix\n // Tokens allowed in the localpart of the email\n const localpartAccepting = [AMPERSAND, APOSTROPHE, ASTERISK, BACKSLASH, BACKTICK, CARET, DOLLAR, EQUALS, HYPHEN, OPENBRACE, CLOSEBRACE, PERCENT, PIPE, PLUS, POUND, QUERY, SLASH, SYM, TILDE, UNDERSCORE];\n\n // The universal starting state.\n /**\n * @type State<Token>\n */\n const Start = makeState();\n const Localpart = tt(Start, TILDE); // Local part of the email address\n ta(Localpart, localpartAccepting, Localpart);\n ta(Localpart, groups.domain, Localpart);\n const Domain = makeState(),\n Scheme = makeState(),\n SlashScheme = makeState();\n ta(Start, groups.domain, Domain); // parsed string ends with a potential domain name (A)\n ta(Start, groups.scheme, Scheme); // e.g., 'mailto'\n ta(Start, groups.slashscheme, SlashScheme); // e.g., 'http'\n\n ta(Domain, localpartAccepting, Localpart);\n ta(Domain, groups.domain, Domain);\n const LocalpartAt = tt(Domain, AT); // Local part of the email address plus @\n\n tt(Localpart, AT, LocalpartAt); // close to an email address now\n\n // Local part of an email address can be e.g. 'http' or 'mailto'\n tt(Scheme, AT, LocalpartAt);\n tt(SlashScheme, AT, LocalpartAt);\n const LocalpartDot = tt(Localpart, DOT); // Local part of the email address plus '.' (localpart cannot end in .)\n ta(LocalpartDot, localpartAccepting, Localpart);\n ta(LocalpartDot, groups.domain, Localpart);\n const EmailDomain = makeState();\n ta(LocalpartAt, groups.domain, EmailDomain); // parsed string starts with local email info + @ with a potential domain name\n ta(EmailDomain, groups.domain, EmailDomain);\n const EmailDomainDot = tt(EmailDomain, DOT); // domain followed by DOT\n ta(EmailDomainDot, groups.domain, EmailDomain);\n const Email$1 = makeState(Email); // Possible email address (could have more tlds)\n ta(EmailDomainDot, groups.tld, Email$1);\n ta(EmailDomainDot, groups.utld, Email$1);\n tt(LocalpartAt, LOCALHOST, Email$1);\n\n // Hyphen can jump back to a domain name\n const EmailDomainHyphen = tt(EmailDomain, HYPHEN); // parsed string starts with local email info + @ with a potential domain name\n tt(EmailDomainHyphen, HYPHEN, EmailDomainHyphen);\n ta(EmailDomainHyphen, groups.domain, EmailDomain);\n ta(Email$1, groups.domain, EmailDomain);\n tt(Email$1, DOT, EmailDomainDot);\n tt(Email$1, HYPHEN, EmailDomainHyphen);\n\n // Final possible email states\n const EmailColon = tt(Email$1, COLON); // URL followed by colon (potential port number here)\n /*const EmailColonPort = */\n ta(EmailColon, groups.numeric, Email); // URL followed by colon and port number\n\n // Account for dots and hyphens. Hyphens are usually parts of domain names\n // (but not TLDs)\n const DomainHyphen = tt(Domain, HYPHEN); // domain followed by hyphen\n const DomainDot = tt(Domain, DOT); // domain followed by DOT\n tt(DomainHyphen, HYPHEN, DomainHyphen);\n ta(DomainHyphen, groups.domain, Domain);\n ta(DomainDot, localpartAccepting, Localpart);\n ta(DomainDot, groups.domain, Domain);\n const DomainDotTld = makeState(Url); // Simplest possible URL with no query string\n ta(DomainDot, groups.tld, DomainDotTld);\n ta(DomainDot, groups.utld, DomainDotTld);\n ta(DomainDotTld, groups.domain, Domain);\n ta(DomainDotTld, localpartAccepting, Localpart);\n tt(DomainDotTld, DOT, DomainDot);\n tt(DomainDotTld, HYPHEN, DomainHyphen);\n tt(DomainDotTld, AT, LocalpartAt);\n const DomainDotTldColon = tt(DomainDotTld, COLON); // URL followed by colon (potential port number here)\n const DomainDotTldColonPort = makeState(Url); // TLD followed by a port number\n ta(DomainDotTldColon, groups.numeric, DomainDotTldColonPort);\n\n // Long URL with optional port and maybe query string\n const Url$1 = makeState(Url);\n\n // URL with extra symbols at the end, followed by an opening bracket\n const UrlNonaccept = makeState(); // URL followed by some symbols (will not be part of the final URL)\n\n // Query strings\n ta(Url$1, qsAccepting, Url$1);\n ta(Url$1, qsNonAccepting, UrlNonaccept);\n ta(UrlNonaccept, qsAccepting, Url$1);\n ta(UrlNonaccept, qsNonAccepting, UrlNonaccept);\n\n // Become real URLs after `SLASH` or `COLON NUM SLASH`\n // Here works with or without scheme:// prefix\n tt(DomainDotTld, SLASH, Url$1);\n tt(DomainDotTldColonPort, SLASH, Url$1);\n\n // Note that domains that begin with schemes are treated slighly differently\n const SchemeColon = tt(Scheme, COLON); // e.g., 'mailto:'\n const SlashSchemeColon = tt(SlashScheme, COLON); // e.g., 'http:'\n const SlashSchemeColonSlash = tt(SlashSchemeColon, SLASH); // e.g., 'http:/'\n\n const UriPrefix = tt(SlashSchemeColonSlash, SLASH); // e.g., 'http://'\n\n // Scheme states can transition to domain states\n ta(Scheme, groups.domain, Domain);\n tt(Scheme, DOT, DomainDot);\n tt(Scheme, HYPHEN, DomainHyphen);\n ta(SlashScheme, groups.domain, Domain);\n tt(SlashScheme, DOT, DomainDot);\n tt(SlashScheme, HYPHEN, DomainHyphen);\n\n // Force URL with scheme prefix followed by anything sane\n ta(SchemeColon, groups.domain, Url$1);\n tt(SchemeColon, SLASH, Url$1);\n tt(SchemeColon, QUERY, Url$1);\n ta(UriPrefix, groups.domain, Url$1);\n ta(UriPrefix, qsAccepting, Url$1);\n tt(UriPrefix, SLASH, Url$1);\n const bracketPairs = [[OPENBRACE, CLOSEBRACE],\n // {}\n [OPENBRACKET, CLOSEBRACKET],\n // []\n [OPENPAREN, CLOSEPAREN],\n // ()\n [OPENANGLEBRACKET, CLOSEANGLEBRACKET],\n // <>\n [FULLWIDTHLEFTPAREN, FULLWIDTHRIGHTPAREN],\n // ()\n [LEFTCORNERBRACKET, RIGHTCORNERBRACKET],\n // 「」\n [LEFTWHITECORNERBRACKET, RIGHTWHITECORNERBRACKET],\n // 『』\n [FULLWIDTHLESSTHAN, FULLWIDTHGREATERTHAN] // <>\n ];\n for (let i = 0; i < bracketPairs.length; i++) {\n const [OPEN, CLOSE] = bracketPairs[i];\n const UrlOpen = tt(Url$1, OPEN); // URL followed by open bracket\n\n // Continue not accepting for open brackets\n tt(UrlNonaccept, OPEN, UrlOpen);\n\n // Closing bracket component. This character WILL be included in the URL\n tt(UrlOpen, CLOSE, Url$1);\n\n // URL that beings with an opening bracket, followed by a symbols.\n // Note that the final state can still be `UrlOpen` (if the URL has a\n // single opening bracket for some reason).\n const UrlOpenQ = makeState(Url);\n ta(UrlOpen, qsAccepting, UrlOpenQ);\n const UrlOpenSyms = makeState(); // UrlOpen followed by some symbols it cannot end it\n ta(UrlOpen, qsNonAccepting);\n\n // URL that begins with an opening bracket, followed by some symbols\n ta(UrlOpenQ, qsAccepting, UrlOpenQ);\n ta(UrlOpenQ, qsNonAccepting, UrlOpenSyms);\n ta(UrlOpenSyms, qsAccepting, UrlOpenQ);\n ta(UrlOpenSyms, qsNonAccepting, UrlOpenSyms);\n\n // Close brace/bracket to become regular URL\n tt(UrlOpenQ, CLOSE, Url$1);\n tt(UrlOpenSyms, CLOSE, Url$1);\n }\n tt(Start, LOCALHOST, DomainDotTld); // localhost is a valid URL state\n tt(Start, NL, Nl); // single new line\n\n return {\n start: Start,\n tokens: tk\n };\n}\n\n/**\n * Run the parser state machine on a list of scanned string-based tokens to\n * create a list of multi tokens, each of which represents a URL, email address,\n * plain text, etc.\n *\n * @param {State<MultiToken>} start parser start state\n * @param {string} input the original input used to generate the given tokens\n * @param {Token[]} tokens list of scanned tokens\n * @returns {MultiToken[]}\n */\nfunction run(start, input, tokens) {\n let len = tokens.length;\n let cursor = 0;\n let multis = [];\n let textTokens = [];\n while (cursor < len) {\n let state = start;\n let secondState = null;\n let nextState = null;\n let multiLength = 0;\n let latestAccepting = null;\n let sinceAccepts = -1;\n while (cursor < len && !(secondState = state.go(tokens[cursor].t))) {\n // Starting tokens with nowhere to jump to.\n // Consider these to be just plain text\n textTokens.push(tokens[cursor++]);\n }\n while (cursor < len && (nextState = secondState || state.go(tokens[cursor].t))) {\n // Get the next state\n secondState = null;\n state = nextState;\n\n // Keep track of the latest accepting state\n if (state.accepts()) {\n sinceAccepts = 0;\n latestAccepting = state;\n } else if (sinceAccepts >= 0) {\n sinceAccepts++;\n }\n cursor++;\n multiLength++;\n }\n if (sinceAccepts < 0) {\n // No accepting state was found, part of a regular text token add\n // the first text token to the text tokens array and try again from\n // the next\n cursor -= multiLength;\n if (cursor < len) {\n textTokens.push(tokens[cursor]);\n cursor++;\n }\n } else {\n // Accepting state!\n // First close off the textTokens (if available)\n if (textTokens.length > 0) {\n multis.push(initMultiToken(Text, input, textTokens));\n textTokens = [];\n }\n\n // Roll back to the latest accepting state\n cursor -= sinceAccepts;\n multiLength -= sinceAccepts;\n\n // Create a new multitoken\n const Multi = latestAccepting.t;\n const subtokens = tokens.slice(cursor - multiLength, cursor);\n multis.push(initMultiToken(Multi, input, subtokens));\n }\n }\n\n // Finally close off the textTokens (if available)\n if (textTokens.length > 0) {\n multis.push(initMultiToken(Text, input, textTokens));\n }\n return multis;\n}\n\n/**\n * Utility function for instantiating a new multitoken with all the relevant\n * fields during parsing.\n * @param {new (value: string, tokens: Token[]) => MultiToken} Multi class to instantiate\n * @param {string} input original input string\n * @param {Token[]} tokens consecutive tokens scanned from input string\n * @returns {MultiToken}\n */\nfunction initMultiToken(Multi, input, tokens) {\n const startIdx = tokens[0].s;\n const endIdx = tokens[tokens.length - 1].e;\n const value = input.slice(startIdx, endIdx);\n return new Multi(value, tokens);\n}\n\nconst warn = typeof console !== 'undefined' && console && console.warn || (() => {});\nconst warnAdvice = 'until manual call of linkify.init(). Register all schemes and plugins before invoking linkify the first time.';\n\n// Side-effect initialization state\nconst INIT = {\n scanner: null,\n parser: null,\n tokenQueue: [],\n pluginQueue: [],\n customSchemes: [],\n initialized: false\n};\n\n/**\n * @typedef {{\n * \tstart: State<string>,\n * \ttokens: { groups: Collections<string> } & typeof tk\n * }} ScannerInit\n */\n\n/**\n * @typedef {{\n * \tstart: State<MultiToken>,\n * \ttokens: typeof multi\n * }} ParserInit\n */\n\n/**\n * @typedef {(arg: { scanner: ScannerInit }) => void} TokenPlugin\n */\n\n/**\n * @typedef {(arg: { scanner: ScannerInit, parser: ParserInit }) => void} Plugin\n */\n\n/**\n * De-register all plugins and reset the internal state-machine. Used for\n * testing; not required in practice.\n * @private\n */\nfunction reset() {\n State.groups = {};\n INIT.scanner = null;\n INIT.parser = null;\n INIT.tokenQueue = [];\n INIT.pluginQueue = [];\n INIT.customSchemes = [];\n INIT.initialized = false;\n return INIT;\n}\n\n/**\n * Register a token plugin to allow the scanner to recognize additional token\n * types before the parser state machine is constructed from the results.\n * @param {string} name of plugin to register\n * @param {TokenPlugin} plugin function that accepts the scanner state machine\n * and available scanner tokens and collections and extends the state machine to\n * recognize additional tokens or groups.\n */\nfunction registerTokenPlugin(name, plugin) {\n if (typeof plugin !== 'function') {\n throw new Error(`linkifyjs: Invalid token plugin ${plugin} (expects function)`);\n }\n for (let i = 0; i < INIT.tokenQueue.length; i++) {\n if (name === INIT.tokenQueue[i][0]) {\n warn(`linkifyjs: token plugin \"${name}\" already registered - will be overwritten`);\n INIT.tokenQueue[i] = [name, plugin];\n return;\n }\n }\n INIT.tokenQueue.push([name, plugin]);\n if (INIT.initialized) {\n warn(`linkifyjs: already initialized - will not register token plugin \"${name}\" ${warnAdvice}`);\n }\n}\n\n/**\n * Register a linkify plugin\n * @param {string} name of plugin to register\n * @param {Plugin} plugin function that accepts the parser state machine and\n * extends the parser to recognize additional link types\n */\nfunction registerPlugin(name, plugin) {\n if (typeof plugin !== 'function') {\n throw new Error(`linkifyjs: Invalid plugin ${plugin} (expects function)`);\n }\n for (let i = 0; i < INIT.pluginQueue.length; i++) {\n if (name === INIT.pluginQueue[i][0]) {\n warn(`linkifyjs: plugin \"${name}\" already registered - will be overwritten`);\n INIT.pluginQueue[i] = [name, plugin];\n return;\n }\n }\n INIT.pluginQueue.push([name, plugin]);\n if (INIT.initialized) {\n warn(`linkifyjs: already initialized - will not register plugin \"${name}\" ${warnAdvice}`);\n }\n}\n\n/**\n * Detect URLs with the following additional protocol. Anything with format\n * \"protocol://...\" will be considered a link. If `optionalSlashSlash` is set to\n * `true`, anything with format \"protocol:...\" will be considered a link.\n * @param {string} scheme\n * @param {boolean} [optionalSlashSlash]\n */\nfunction registerCustomProtocol(scheme, optionalSlashSlash = false) {\n if (INIT.initialized) {\n warn(`linkifyjs: already initialized - will not register custom scheme \"${scheme}\" ${warnAdvice}`);\n }\n if (!/^[0-9a-z]+(-[0-9a-z]+)*$/.test(scheme)) {\n throw new Error(`linkifyjs: incorrect scheme format.\n1. Must only contain digits, lowercase ASCII letters or \"-\"\n2. Cannot start or end with \"-\"\n3. \"-\" cannot repeat`);\n }\n INIT.customSchemes.push([scheme, optionalSlashSlash]);\n}\n\n/**\n * Initialize the linkify state machine. Called automatically the first time\n * linkify is called on a string, but may be called manually as well.\n */\nfunction init() {\n // Initialize scanner state machine and plugins\n INIT.scanner = init$2(INIT.customSchemes);\n for (let i = 0; i < INIT.tokenQueue.length; i++) {\n INIT.tokenQueue[i][1]({\n scanner: INIT.scanner\n });\n }\n\n // Initialize parser state machine and plugins\n INIT.parser = init$1(INIT.scanner.tokens);\n for (let i = 0; i < INIT.pluginQueue.length; i++) {\n INIT.pluginQueue[i][1]({\n scanner: INIT.scanner,\n parser: INIT.parser\n });\n }\n INIT.initialized = true;\n return INIT;\n}\n\n/**\n * Parse a string into tokens that represent linkable and non-linkable sub-components\n * @param {string} str\n * @return {MultiToken[]} tokens\n */\nfunction tokenize(str) {\n if (!INIT.initialized) {\n init();\n }\n return run(INIT.parser.start, str, run$1(INIT.scanner.start, str));\n}\ntokenize.scan = run$1; // for testing\n\n/**\n * Find a list of linkable items in the given string.\n * @param {string} str string to find links in\n * @param {string | Opts} [type] either formatting options or specific type of\n * links to find, e.g., 'url' or 'email'\n * @param {Opts} [opts] formatting options for final output. Cannot be specified\n * if opts already provided in `type` argument\n */\nfunction find(str, type = null, opts = null) {\n if (type && typeof type === 'object') {\n if (opts) {\n throw Error(`linkifyjs: Invalid link type ${type}; must be a string`);\n }\n opts = type;\n type = null;\n }\n const options = new Options(opts);\n const tokens = tokenize(str);\n const filtered = [];\n for (let i = 0; i < tokens.length; i++) {\n const token = tokens[i];\n if (token.isLink && (!type || token.t === type) && options.check(token)) {\n filtered.push(token.toFormattedObject(options));\n }\n }\n return filtered;\n}\n\n/**\n * Is the given string valid linkable text of some sort. Note that this does not\n * trim the text for you.\n *\n * Optionally pass in a second `type` param, which is the type of link to test\n * for.\n *\n * For example,\n *\n * linkify.test(str, 'email');\n *\n * Returns `true` if str is a valid email.\n * @param {string} str string to test for links\n * @param {string} [type] optional specific link type to look for\n * @returns boolean true/false\n */\nfunction test(str, type = null) {\n const tokens = tokenize(str);\n return tokens.length === 1 && tokens[0].isLink && (!type || tokens[0].t === type);\n}\n\n\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiKHNzcikvLi9ub2RlX21vZHVsZXMvbGlua2lmeWpzL2Rpc3QvbGlua2lmeS5tanMiLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxlQUFlLHdCQUF3QjtBQUN2Qzs7QUFFQTtBQUNBLGVBQWUseUJBQXlCO0FBQ3hDOztBQUVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixXQUFXLGdCQUFnQjtBQUMzQixhQUFhLEtBQUs7QUFDbEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFdBQVcsR0FBRztBQUNkLFdBQVcsZ0JBQWdCO0FBQzNCLFdBQVcsT0FBTztBQUNsQjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQUVBO0FBQ0E7QUFDQSxXQUFXLEdBQUc7QUFDZCxXQUFXLGdCQUFnQjtBQUMzQixhQUFhLE9BQU87QUFDcEI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLGFBQWEsV0FBVztBQUN4Qjs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EsV0FBVyxHQUFHO0FBQ2Q7QUFDQTtBQUNBLG9CQUFvQjtBQUNwQixlQUFlLDZCQUE2QjtBQUM1QyxlQUFlO0FBQ2Ysa0JBQWtCO0FBQ2xCLGFBQWEsc0JBQXNCO0FBQ25DO0FBQ0EsYUFBYSxXQUFXO0FBQ3hCO0FBQ0EsYUFBYSxJ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O0FBQ0E7QUFDQTtBQUNBLHVCQUF1Qjs7QUFFdkI7QUFDQTtBQUNBLFdBQVcsUUFBUTtBQUNuQixXQUFXLGVBQWU7QUFDMUI7QUFDQSxXQUFXLE1BQU07QUFDakI7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLGtEQUFrRCxPQUFPO0FBQ3pEO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0Esa0JBQWtCLG1CQUFtQjtBQUNyQztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxXQUFXLFFBQVE7QUFDbkIsV0FBVyxRQUFRO0FBQ25CO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUFFOE0iLCJzb3VyY2VzIjpbIkU6XFxHSVRcXG12cFxcbmFzaGVsLWZyb250ZW5kXFxub2RlX21vZHVsZXNcXGxpbmtpZnlqc1xcZGlzdFxcbGlua2lmeS5tanMiXSwic291cmNlc0NvbnRlbnQiOlsiLy8gVEhJUyBGSUxFIElTIEFVVE9NQVRJQ0FMTFkgR0VORVJBVEVEIERPIE5PVCBFRElUIERJUkVDVExZXG4vLyBTZWUgdXBkYXRlLXRsZHMuanMgZm9yIGVuY29kaW5nL2RlY29kaW5nIGZvcm1hdFxuLy8gaHR0cHM6Ly9kYXRhLmlhbmEub3JnL1RMRC90bGRzLWFscGhhLWJ5LWRvbWFpbi50eHRcbmNvbnN0IGVuY29kZWRUbGRzID0gJ2FhYTFycDNiYjBvdHQzdmllNGMxbGUyb2dhZG81dWRoYWJpN2MwYWRlbXk1Y2VudHVyZTZvdW50YW50MHM5bzF0b3I0ZDBzMXVsdDRlMGcxcm8ydG5hNGYwbDFyaWNhNWcwYWtoYW41ZW5jeTVpMGcxcmJ1czNmb3JjZTV0ZWw1a2RuM2wwaWJhYmE0cGF5NGxmaW5hbno2c3RhdGU1eTJzYWNlM3RvbTVtMGF6b240ZXJpY2FuZXhwcmVzczdmYW1pbHkxMXgyZmFtM2ljYTNzdGVyZGFtOG5hbHl0aWNzN2Ryb2lkNXF1YW40ejJvMGwycGFydG1lbnRzOHAwbGU0cTB1YXJlbGxlOHIwYWIxbWNvNGNoaTNteTJwYTJ0MGUzczBkYTJpYTJzb2NpYXRlczl0MGhsZXRhNXRvcm5leTd1MGN0aW9uNWRpMGJsZTNvM3Nwb3N0NXRob3IzbzBzNHcwczJ4MGEyejB1cmU1YmEwYnkyaWR1M25hbWV4NGQxazJyMGNlbG9uYTVsYXljYXJkNHM1ZWZvb3Q1Z2FpbnM2c2ViYWxsNWtldGJhbGw4dWhhdXM1eWVybjViMGMxdDF2YTNjZzFuMmQxZTBhdHMydXR5NGVyMnJsaW40c3QwYnV5NXQyZjFnMWgwYXJ0aTVpMGJsZTNkMWtlMm5nMG8zbzF6MmoxbGFjazBmcmlkYXk5b2NrYnVzdGVyOGcxb21iZXJnN3VlM20wczF3Mm4wcHBhcmliYXM5bzBhdHMzZWhyaW5nZXI4ZmEybTFuZDJvMGswaW5nNXNjaDJ0aWsyb240dDF1dGlxdWU2eDJyMGFkZXNjbzZpZGdlc3RvbmU5b2Fkd2F5NWtlcjN0aGVyNXVzc2VsczdzMXQxdWlsZDBlcnM2c2luZXNzNnkxenozdjF3MXkxejBoM2NhMGIxZmUybDBsMXZpbmtsZWluOW0wZXJhM3Aybm9uM3BldG93bjVpdGFsMG9uZThyMGF2YW40ZHMyZTBlcjBzNHMyc2ExZTFoMWlubzR0MGVyaW5nNWhvbGljN2JhMW4xcmUzYzFkMWVudGVyNG8xcm4zZjBhMWQyZzFoMGFuZWwybmVsNHJpdHk0c2UydDJlYXAzaW50YWk1cmlzdG1hczZvbWU0dXJjaDVpMHByaWFuaTZyY2xlNHNjbzN0YWRlbDRpMGMyeTNrMWwwYWltczRlYW5pbmc2aWNrMm5pYzFxdWU2b3RoaW5nNXVkM3ViMG1lZDZtMW4xbzBhY2gzZGVzM2ZmZWU0bGxlZ2U0b2duZTVtMG1iYW5rNHVuaXR5NnBhbnkycmUzdXRlcjVzZWM0bmRvczNzdHJ1Y3Rpb244dWx0aW5nN3RhY3QzcmFjdG9yczlva2luZzRsMXAycnNpY2E1dW50cnk0cG9uMHM0cnNlczZwYTJyMGVkaXQwY2FyZDR1bmlvbjlpY2tldDVvd24zczF1aXNlMHM2dTBpc2luZWxsYTl2MXcxeDF5MG1ydTNvdTN6MmRhZDFuY2UzdGExZTFpbmczc3VuNHkyY2xrM2RzMmUwYWwwZXIyczNncmVlNGxpdmVyeTVsMW9pdHRlNXRhM21vY3JhdDZudGFsMmlzdDVzaTBnbjR2MmhsMmlhbW9uZHM2ZXQyZ2l0YWw1cmVjdDBvcnk3c2NvdW50M3ZlcjVoMnkyajFrMW0xbnAybzBjczF0b3I0ZzFtYWluczV0MXdubG9hZDdyaXZlNHR2MnViYWkzbmxvcDRwb250NHJiYW41dmFnMnIyejJlYXJ0aDN0MmMwbzJkZWthM3UwY2F0aW9uOGUxZzFtYWlsM2VyY2s1bmVyZ3k0Z2luZWVyMGluZzl0ZXJwcmlzZXMxMHBzb240cXVpcG1lbnQ4cjBpY3Nzb242bmkzczBxMXRhdGU1dDF1MHJvdmlzaW9uOHMydmVudHM1eGNoYW5nZTZwZXJ0M29zZWQ0cmVzczV0cmFzcGFjZTEwZmFnZTJpbDFyd2luZHM2dGgzbWlseTRuMHMycm0wZXJzNXNoaW9uNHQzZWRleDNlZGJhY2s2cnJhcmkzZXJvNmkwZGVsaXR5NW8ybG0ybmFsMW5jZTFpYWw3cmUwc3RvbmU2bWRhbGU2c2gwaW5nNXQwbmVzczZqMWsxbGlja3IzZ2h0czRyMm9yaXN0NHdlcnM1eTJtMW8wbzBkMXRiYWxsNnJkMWV4MnNhbGU0dW0zdW5kYXRpb244eDJyMGVlMXNlbml1czdsMW9nYW5zNG50aWVyN3RyMnVqaXRzdTVuMGQycm5pdHVyZTd0Ym9sNXlpM2dhMGwwbGVyeTNvMXVwNG1lMHMzcDFyZGVuNHkyYjBpejNkMG4yZTBhMW50MGluZzVvcmdlNWYxZzBlZTNoMWkwZnQwczN2ZXMyaW5nNWwwYXNzM2Uxb2JhbDJvNG0wYWlsM2JoMm8xeDJuMW9kYWRkeTVsZDBwb2ludDZmMm8wZHllYXI1ZzBsZTRwMXQxdjJwMXExcjBhaW5nZXI1cGhpY3M1dGlzNGVlbjNpcGUzb2Nlcnk0dXA0czF0MXUwY2NpM2dlMmlkZTJ0YXJzNXJ1M3cxeTJoYWlyMm1idXJnNW5nb3V0NXVzM2JvMmRmYzBiYW5rN2VhbHRoMGNhcmU4bHAxc2lua2k2cmUxbWVzNWlwaG9wNHNhbWl0c3U3dGFjaGk1djJrMHQybTFuMW9ja2V5NGxkaW5nczVpZGF5NW1lZGVwb3Q1Z29vZHM1czBlbnNlN25kYTNyc2Uzc3BpdGFsNXQwaW5nNXQwZWxzM21haWw1dXNlM3cycjFzYmMzdDF1MGdoZXM1eWF0dDN1bmRhaTdpYm0yY2JjMmUxdTJkMWUwZWUzZm0ya2FubzRsMW0wYW1hdDRkYjJtbzBiaWxpZW45bjBjMWR1c3RyaWVzOGZpbml0aTVvMmcxazFzdGl0dXRlNnVyYW5jZTRlNHQwZXJuYXRpb25hbDEwdWl0NHZlc3RtZW50czEwbzFwaXJhbmdhN3ExcjBpc2g0czBtYWlsaTV0MGFuYnVsN3QwYXUydjNqYWd1YXI0dmEzY2IyZTBlcDJ0enQzd2Vscnk2aW8ybGwybTBwMm5qMm8wYnMxdXJnNHQxeTJwMG1vcmdhbjZyczN1ZWdvczRuaXBlcjdrYXVmZW41ZGRpM2UwcnJ5aG90ZWxzNnByb3BlcnRpZXMxNGZoMmcxaDFpMGExZHMybTFuZGxlNHRjaGVuNXdpM20xbjFvZWxuM21hdHN1NXNoZXI1cDBtZzJuMnIwZDFlZDN1b2tncm91cDh3MXkwb3RvNHoybGEwY2FpeGE1bWJvcmdoaW5pOGVyM25kMHJvdmVyNnhlc3M1c2FsbGU1dDBpbm8zcm9iZTV3MHllcjViMWMxZHMyZWFzZTNjbGVyYzVmcmFrNGdhbDJvMnh1czRnYnQzaTBkbDJmZTBpbnN1cmFuY2U5c3R5bGU3Z2h0aW5nNmtlMmxseTNtaXRlZDRvMm5jb2xuNGsydmUxaW5nNWsxbGMxcDJvYW4wczNja2VyM3VzM2wxbmRvbjR0dGUxbzN2ZTNwbDBmaW5hbmNpYWwxMXIxczF0MGQwYTN1MG5kYmVjazZ4ZTF1cnk1djF5Mm1hMGRyaWQ0aWYxc29uNGtldXA0bjBhZ2VtZW50N2dvM3AxcmtldDBpbmczczRyaW90dDVzaGFsbHM3dHRlbDViYTJjMGtpbnNleTdkMWUwZDBpYTNldDJsYm91cm5lN21lMW9yaWFsNm4wdTJyY2ttc2Q3ZzFoMWlhbWkzY3Jvc29mdDdsMW5pMXQydDBzdWJpc2hpOWsxbDBiMXMybTBhMm4xbzBiaTBsZTRkYTJlMWkxbTFuYXNoM2V5MnN0ZXI1cm1vbjN0Z2FnZTZzY293NHRvMHJjeWNsZXM5djBpZTRwMXExcjFzMGQydDBuMXIydTBzZXVtM2ljNHYxdzF4MXkxejJuYTBiMWdveWE0bWUydnkzYmEyYzFlMGMxdDBiYW5rNGZsaXg0d29yazV1c3RhcjV3MHMyeHQwZGlyZWN0N3VzNGYwbDJnMG8yaGsyaTBjbzJrZTFvbjNuamEzc3NhbjF5NWwxbzBraWEzcnRvbjR3MHJ1ejN0djRwMXIwYTF3MnR0MnUxeWMyejJvYmkxc2VydmVyN2ZmaWNlNWtpbmF3YTZsYXlhbjBncm91cDlsbzNtMGVnYTRuZTFnMWwwaW5lNW9vMnBlbjNyYWNsZTNuZ2U0ZzBhbmljNWlnaW5zNnNha2E0dHN1a2E0dDJ2aDNwYTBnZTJuYXNvbmljN3JpczJzMXRuZXJzNHMxeTN5MmNjdzNlMHQyZjBpemVyNWcxaDBhcm1hY3k2ZDFpbGlwczVvbmUydG8wZ3JhcGh5NnM0eXNpbzVpY3MxdGV0MnVyZXM2ZDFuMGcxazJvbmVlcjV6emE0azFsMGFjZTJ5MHN0YXRpb245dW1iaW5nNXMzbTFuMGMyb2hsMmtlcjNsaXRpZTVybjJzdDNyMGF4aTNlc3MzaW1lM28wZDB1Y3Rpb25zOGYxZ3Jlc3NpdmU4bW8ycGVydGllczN5NXRlY3Rpb244dTBkZW50aWFsOXMxdDF1YjJ3MGMyeTJxYTFwb24zdWViZWMzc3Q1cmFjaW5nNGRpbzRlMGFkMWxlc3RhdGU2dG9yMnk0Y2lwZXM1ZDBzdG9uZTV1bWJyZWxsYTloYWIzaXNlMG4zdDJsaWFuY2U2bjB0MGFsczVwYWlyM29ydDN1YmxpY2FuOHN0MGF1cmFudDh2aWV3MHM1eHJvdGg2aWNoMGFyZGxpNm9oM2wxbzFwMm8wY2tzM2RlbzNnZXJzNG9tM3MwdnAzdTBnYnkzaHIybjJ3MGUyeXVreXU2c2EwYXJsYW5kNmZlMHR5NGt1cmE0bGUxb24zbXNjbHViNHVuZzVuZHZpazBjb3JvbWFudDEyb2ZpNHAxcmwyczF2ZTJ4bzNiMGkxczJjMGIxaGFlZmZsZXI3bWlkdDRvbGFyc2hpcHM4b2wzdWxlM3dhcno1aWVuY2U1b3QzZDFlMGFyY2gzdDJjdXJlMWl0eTZlazJsZWN0NG5lcjNydmljZXM2dmVuM3cxeDB5M2ZyMmcxaDBhbmdyaWxhNnJwM2VsbDNpYTFrc2hhNW9lczJwMHBpbmc1dWppM3czaTBsazJuYTFnbGVzNXRlM2oxazBpMG4yeTBwZTRsMGluZzRtMGFydDNpbGU0bjBjZjNvMGNjZXIzaWFsNGZ0YmFuazR3YXJlNmh1MmxhcjJ1dGlvbnM3bmcxeTJ5MnBhMGNlM29ydDJ0M3IwbDJzMXQwYWRhMnBsZXM0cjF0ZWJhbms0ZmFybTdjMGdyb3VwNm9ja2hvbG02cmFnZTNlM3JlYW00dWRpbzJ5M3lsZTR1MGNrczNwcGxpZXMzeTJvcnQ1cmYxZ2VyeTV6dWtpNXYxd2F0Y2g0aXNzNHgxeTBkbmV5NHN0ZW1zNnoydGFiMWlwZWk0bGsyb2JhbzRyZ2V0NHRhbW90b3JzNnIydG9vNHgwaTNjMGkyZDBrMmVhbTJjaDBub2xvZ3k4bDFtYXNlazVubmlzNHZhM2YxZzFoMGQxZWF0ZXIycmU2aWFhMmNrZXRzNWVuZGE0cHMycmVzMm9sNGowbWF4eDR4MmswbWF4eDVsMW0wYWxsNG4xbzBkYXkza3lvM29sczNwMXJheTNzaGliYTV0YWwzdXJzM3duMnlvdGEzczNyMGFkZTFpbmc0aW5pbmc1dmVsMGVyczBpbnN1cmFuY2UxNnVzdDN2MnQxdWJlMmkxbmVzM3NodTR2MHMydzF6MnVhMWJhbmszczJnMWsxbmljb20zdmVyc2l0eThvMm9sMnBzMnMxeTF6MnZhMGNhdGlvbnM3bmExZ3VhcmQ3YzFlMGdhczNudHVyZXM2cmlzaWduNW3DtmdlbnNiZXJhdGVyMnVuZzE0c2ljaGVydW5nMTB0MmcxaTBhamVzNGRlbzNnMWtpbmc0bGxhczRuMXAxcmdpbjRzYTFpb240dmExbzNsYWFuZGVyZW45bjFvZGthM2x2bzN0ZTFpbmczbzJ5YWdlNXUyd2FsZXMybWFydDR0ZXI0bmcwZ291NXRjaDBlczZlYXRoZXIwY2hhbm5lbDEyYmNhbTNlcjJzaXRlNWQwZGluZzVpYm8ycjNmMWhvc3dobzZpZW4ya2kybGxpYW1oaWxsOW4wZG93czRlMW5lcnM2bWUyb2x0ZXJza2x1d2VyMTFvZHNpZGU2cmswczJsZDN3MnMxdGMxZjN4Ym94M2Vyb3g0aWh1YW40bjJ4eDJ5ejN5YWNodHM0aG9vM21heHVuNW5kZXg1ZTFvZG9iYXNoaTdnYTJrb2hhbWE2dTB0dWJlNnQxdW4zemEwcHBvczRyYTNlcm8zaXAybTFvbmUzdWVyaWNoNncyJztcbi8vIEludGVybmF0aW9uYWxpemVkIGRvbWFpbiBuYW1lcyBjb250YWluaW5nIG5vbi1BU0NJSVxuY29uc3QgZW5jb2RlZFV0bGRzID0gJ861zrsxz4Uy0LHQszHQtdC7M9C00LXRgtC4NNC10Y4y0LrQsNGC0L7Qu9C40Lo20L7QvDPQvNC60LQy0L7QvTHRgdC60LLQsDbQvtC90LvQsNC50L010YDQszPRgNGD0YEy0YQy0YHQsNC50YIz0YDQsTPRg9C60YAz0pvQsNC3M9Ww1aHVtTPXmdep16jXkNecNden15XXnTPYp9io2YjYuNio2Yo12LHYp9mF2YPZiDXZhNin2LHYr9mGNNio2K3YsdmK2YY12KzYstin2KbYsTXYs9i52YjYr9mK2Kk22LnZhNmK2KfZhjXZhdi62LHYqDXZhdin2LHYp9iqNduM2LHYp9mGNdio2KfYsdiqMtiy2KfYsTTZitiq2YMz2r7Yp9ix2Ko12KrZiNmG2LM02LPZiNiv2KfZhjPYsdmK2Kk12LTYqNmD2Kk02LnYsdin2YIy2Kgy2YXYp9mGNNmB2YTYs9i32YrZhjbZgti32LEz2YPYp9ir2YjZhNmK2YM22YjZhTPZhdi12LEy2YTZitiz2YrYpzXZiNix2YrYqtin2YbZitinN9mC2Lk02YfZhdix2KfZhzXZvtin2qnYs9iq2KfZhjfagNin2LHYqjTgpJXgpYngpK4z4KSo4KWH4KSfM+CkreCkvuCksOCkpDDgpK7gpY0z4KWL4KSkNeCkuOCkguCkl+CkoOCkqDXgpqzgpr7gpoLgprLgpr414Kat4Ka+4Kaw4KakMuCnsOCmpDTgqK3gqL7gqLDgqKQ04Kqt4Kq+4Kqw4KqkNOCsreCsvuCssOCspDTgrofgrqjgr43grqTgrr/grq/grr424K6y4K6Z4K+N4K6V4K+INuCumuCuv+CumeCvjeCuleCuquCvjeCuquCvguCusOCvjTEx4LCt4LC+4LCw4LCk4LGNNeCyreCyvuCysOCypDTgtK3gtL7gtLDgtKTgtII14La94LaC4Laa4LePNOC4hOC4reC4oTPguYTguJfguKIz4Lql4Lqy4LqnM+GDkuGDlDLjgb/jgpPjgaoz44Ki44Oe44K+44OzNOOCr+ODqeOCpuODiTTjgrDjg7zjgrDjg6s044Kz44OgMuOCueODiOOCojPjgrvjg7zjg6sz44OV44Kh44OD44K344On44OzNuODneOCpOODs+ODiDTkuJbnlYwy5Lit5L+hMeWbvTHlnIsx5paH572RM+S6mumprOmAijPkvIHkuJoy5L2b5bGxMuS/oeaBrzLlgaXlurcy5YWr5Y2mMuWFrOWPuDHnm4oy5Y+w5rm+MeeBozLllYbln44x5bqXMeaghzLlmInph4ww5aSn6YWS5bqXNeWcqOe6vzLlpKfmi78y5aSp5Li75pWZM+WoseS5kDLlrrbpm7sy5bm/5LicMuW+ruWNmjLmhYjlloQy5oiR54ix5L2gM+aJi+acujLmi5vogZgy5pS/5YqhMeW6nDLmlrDliqDlnaEy6Ze7MuaXtuWwmjLmm7jnsY0y5py65p6EMua3oemprOmUoTPmuLjmiI8y5r6z6ZaAMueCueecizLnp7vliqgy57uE57uH5py65p6ENOe9keWdgDHlupcx56uZMee7nDLogZTpgJoy6LC35q2MMui0reeJqTLpgJrosqky6ZuG5ZuiMumbu+ioiuebiOenkTTpo57liKnmtaYz6aOf5ZOBMumkkOWOhTLpppnmoLzph4zmi4kz5rivMuuLt+uEtzHsu7Qy7IK87ISxMu2VnOq1rTInO1xuXG4vKipcbiAqIEZpbml0ZSBTdGF0ZSBNYWNoaW5lIGdlbmVyYXRpb24gdXRpbGl0aWVzXG4gKi9cblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHR5cGVkZWYge3sgW2dyb3VwOiBzdHJpbmddOiBUW10gfX0gQ29sbGVjdGlvbnNcbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHt7IFtncm91cDogc3RyaW5nXTogdHJ1ZSB9fSBGbGFnc1xuICovXG5cbi8vIEtleXMgaW4gc2Nhbm5lciBDb2xsZWN0aW9ucyBpbnN0YW5jZXNcbmNvbnN0IG51bWVyaWMgPSAnbnVtZXJpYyc7XG5jb25zdCBhc2NpaSA9ICdhc2NpaSc7XG5jb25zdCBhbHBoYSA9ICdhbHBoYSc7XG5jb25zdCBhc2NpaW51bWVyaWMgPSAnYXNjaWludW1lcmljJztcbmNvbnN0IGFscGhhbnVtZXJpYyA9ICdhbHBoYW51bWVyaWMnO1xuY29uc3QgZG9tYWluID0gJ2RvbWFpbic7XG5jb25zdCBlbW9qaSA9ICdlbW9qaSc7XG5jb25zdCBzY2hlbWUgPSAnc2NoZW1lJztcbmNvbnN0IHNsYXNoc2NoZW1lID0gJ3NsYXNoc2NoZW1lJztcbmNvbnN0IHdoaXRlc3BhY2UgPSAnd2hpdGVzcGFjZSc7XG5cbi8qKlxuICogQHRlbXBsYXRlIFRcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lXG4gKiBAcGFyYW0ge0NvbGxlY3Rpb25zPFQ+fSBncm91cHMgdG8gcmVnaXN0ZXIgaW5cbiAqIEByZXR1cm5zIHtUW119IEN1cnJlbnQgbGlzdCBvZiB0b2tlbnMgaW4gdGhlIGdpdmVuIGNvbGxlY3Rpb25cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJHcm91cChuYW1lLCBncm91cHMpIHtcbiAgaWYgKCEobmFtZSBpbiBncm91cHMpKSB7XG4gICAgZ3JvdXBzW25hbWVdID0gW107XG4gIH1cbiAgcmV0dXJuIGdyb3Vwc1tuYW1lXTtcbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtUfSB0IHRva2VuIHRvIGFkZFxuICogQHBhcmFtIHtDb2xsZWN0aW9uczxUPn0gZ3JvdXBzXG4gKiBAcGFyYW0ge0ZsYWdzfSBmbGFnc1xuICovXG5mdW5jdGlvbiBhZGRUb0dyb3Vwcyh0LCBmbGFncywgZ3JvdXBzKSB7XG4gIGlmIChmbGFnc1tudW1lcmljXSkge1xuICAgIGZsYWdzW2FzY2lpbnVtZXJpY10gPSB0cnVlO1xuICAgIGZsYWdzW2FscGhhbnVtZXJpY10gPSB0cnVlO1xuICB9XG4gIGlmIChmbGFnc1thc2NpaV0pIHtcbiAgICBmbGFnc1thc2NpaW51bWVyaWNdID0gdHJ1ZTtcbiAgICBmbGFnc1thbHBoYV0gPSB0cnVlO1xuICB9XG4gIGlmIChmbGFnc1thc2NpaW51bWVyaWNdKSB7XG4gICAgZmxhZ3NbYWxwaGFudW1lcmljXSA9IHRydWU7XG4gIH1cbiAgaWYgKGZsYWdzW2FscGhhXSkge1xuICAgIGZsYWdzW2FscGhhbnVtZXJpY10gPSB0cnVlO1xuICB9XG4gIGlmIChmbGFnc1thbHBoYW51bWVyaWNdKSB7XG4gICAgZmxhZ3NbZG9tYWluXSA9IHRydWU7XG4gIH1cbiAgaWYgKGZsYWdzW2Vtb2ppXSkge1xuICAgIGZsYWdzW2RvbWFpbl0gPSB0cnVlO1xuICB9XG4gIGZvciAoY29uc3QgayBpbiBmbGFncykge1xuICAgIGNvbnN0IGdyb3VwID0gcmVnaXN0ZXJHcm91cChrLCBncm91cHMpO1xuICAgIGlmIChncm91cC5pbmRleE9mKHQpIDwgMCkge1xuICAgICAgZ3JvdXAucHVzaCh0KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtUfSB0IHRva2VuIHRvIGNoZWNrXG4gKiBAcGFyYW0ge0NvbGxlY3Rpb25zPFQ+fSBncm91cHNcbiAqIEByZXR1cm5zIHtGbGFnc30gZ3JvdXAgZmxhZ3MgdGhhdCBjb250YWluIHRoaXMgdG9rZW5cbiAqL1xuZnVuY3Rpb24gZmxhZ3NGb3JUb2tlbih0LCBncm91cHMpIHtcbiAgY29uc3QgcmVzdWx0ID0ge307XG4gIGZvciAoY29uc3QgYyBpbiBncm91cHMpIHtcbiAgICBpZiAoZ3JvdXBzW2NdLmluZGV4T2YodCkgPj0gMCkge1xuICAgICAgcmVzdWx0W2NdID0gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHR5cGVkZWYge251bGwgfCBUIH0gVHJhbnNpdGlvblxuICovXG5cbi8qKlxuICogRGVmaW5lIGEgYmFzaWMgc3RhdGUgbWFjaGluZSBzdGF0ZS4gaiBpcyB0aGUgbGlzdCBvZiBjaGFyYWN0ZXIgdHJhbnNpdGlvbnMsXG4gKiBqciBpcyB0aGUgbGlzdCBvZiByZWdleC1tYXRjaCB0cmFuc2l0aW9ucywgamQgaXMgdGhlIGRlZmF1bHQgc3RhdGUgdG9cbiAqIHRyYW5zaXRpb24gdG8gdCBpcyB0aGUgYWNjZXB0aW5nIHRva2VuIHR5cGUsIGlmIGFueS4gSWYgdGhpcyBpcyB0aGUgdGVybWluYWxcbiAqIHN0YXRlLCB0aGVuIGl0IGRvZXMgbm90IGVtaXQgYSB0b2tlbi5cbiAqXG4gKiBUaGUgdGVtcGxhdGUgdHlwZSBUIHJlcHJlc2VudHMgdGhlIHR5cGUgb2YgdGhlIHRva2VuIHRoaXMgc3RhdGUgYWNjZXB0cy4gVGhpc1xuICogc2hvdWxkIGJlIGEgc3RyaW5nIChzdWNoIGFzIG9mIHRoZSB0b2tlbiBleHBvcnRzIGluIGB0ZXh0LmpzYCkgb3IgYVxuICogTXVsdGlUb2tlbiBzdWJjbGFzcyAoZnJvbSBgbXVsdGkuanNgKVxuICpcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge1R9IFt0b2tlbl0gVG9rZW4gdGhhdCB0aGlzIHN0YXRlIGVtaXRzXG4gKi9cbmZ1bmN0aW9uIFN0YXRlKHRva2VuID0gbnVsbCkge1xuICAvLyB0aGlzLm4gPSBudWxsOyAvLyBERUJVRzogU3RhdGUgbmFtZVxuICAvKiogQHR5cGUge3sgW2lucHV0OiBzdHJpbmddOiBTdGF0ZTxUPiB9fSBqICovXG4gIHRoaXMuaiA9IHt9OyAvLyBJTVBMRU1FTlRBVElPTiAxXG4gIC8vIHRoaXMuaiA9IFtdOyAvLyBJTVBMRU1FTlRBVElPTiAyXG4gIC8qKiBAdHlwZSB7W1JlZ0V4cCwgU3RhdGU8VD5dW119IGpyICovXG4gIHRoaXMuanIgPSBbXTtcbiAgLyoqIEB0eXBlIHs/U3RhdGU8VD59IGpkICovXG4gIHRoaXMuamQgPSBudWxsO1xuICAvKiogQHR5cGUgez9UfSB0ICovXG4gIHRoaXMudCA9IHRva2VuO1xufVxuXG4vKipcbiAqIFNjYW5uZXIgdG9rZW4gZ3JvdXBzXG4gKiBAdHlwZSBDb2xsZWN0aW9uczxzdHJpbmc+XG4gKi9cblN0YXRlLmdyb3VwcyA9IHt9O1xuU3RhdGUucHJvdG90eXBlID0ge1xuICBhY2NlcHRzKCkge1xuICAgIHJldHVybiAhIXRoaXMudDtcbiAgfSxcbiAgLyoqXG4gICAqIEZvbGxvdyBhbiBleGlzdGluZyB0cmFuc2l0aW9uIGZyb20gdGhlIGdpdmVuIGlucHV0IHRvIHRoZSBuZXh0IHN0YXRlLlxuICAgKiBEb2VzIG5vdCBtdXRhdGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dCBjaGFyYWN0ZXIgb3IgdG9rZW4gdHlwZSB0byB0cmFuc2l0aW9uIG9uXG4gICAqIEByZXR1cm5zIHs/U3RhdGU8VD59IHRoZSBuZXh0IHN0YXRlLCBpZiBhbnlcbiAgICovXG4gIGdvKGlucHV0KSB7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzO1xuICAgIGNvbnN0IG5leHRTdGF0ZSA9IHN0YXRlLmpbaW5wdXRdO1xuICAgIGlmIChuZXh0U3RhdGUpIHtcbiAgICAgIHJldHVybiBuZXh0U3RhdGU7XG4gICAgfVxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgc3RhdGUuanIubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHJlZ2V4ID0gc3RhdGUuanJbaV1bMF07XG4gICAgICBjb25zdCBuZXh0U3RhdGUgPSBzdGF0ZS5qcltpXVsxXTsgLy8gbm90ZTogbWlnaHQgYmUgZW1wdHkgdG8gcHJldmVudCBkZWZhdWx0IGp1bXBcbiAgICAgIGlmIChuZXh0U3RhdGUgJiYgcmVnZXgudGVzdChpbnB1dCkpIHtcbiAgICAgICAgcmV0dXJuIG5leHRTdGF0ZTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gTm93aGVyZSBsZWZ0IHRvIGp1bXAhIFJldHVybiBkZWZhdWx0LCBpZiBhbnlcbiAgICByZXR1cm4gc3RhdGUuamQ7XG4gIH0sXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBzdGF0ZSBoYXMgYSB0cmFuc2l0aW9uIGZvciB0aGUgZ2l2ZW4gaW5wdXQuIFNldCB0aGUgc2Vjb25kXG4gICAqIGFyZ3VtZW50IHRvIHRydWUgdG8gb25seSBsb29rIGZvciBhbiBleGFjdCBtYXRjaCAoYW5kIG5vdCBhIGRlZmF1bHQgb3JcbiAgICogcmVndWxhci1leHByZXNzaW9uLWJhc2VkIHRyYW5zaXRpb24pXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dFxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IGV4YWN0T25seVxuICAgKi9cbiAgaGFzKGlucHV0LCBleGFjdE9ubHkgPSBmYWxzZSkge1xuICAgIHJldHVybiBleGFjdE9ubHkgPyBpbnB1dCBpbiB0aGlzLmogOiAhIXRoaXMuZ28oaW5wdXQpO1xuICB9LFxuICAvKipcbiAgICogU2hvcnQgZm9yIFwidHJhbnNpdGlvbiBhbGxcIjsgY3JlYXRlIGEgdHJhbnNpdGlvbiBmcm9tIHRoZSBhcnJheSBvZiBpdGVtc1xuICAgKiBpbiB0aGUgZ2l2ZW4gbGlzdCB0byB0aGUgc2FtZSBmaW5hbCByZXN1bHRpbmcgc3RhdGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgc3RyaW5nW119IGlucHV0cyBHcm91cCBvZiBpbnB1dHMgdG8gdHJhbnNpdGlvbiBvblxuICAgKiBAcGFyYW0ge1RyYW5zaXRpb248VD4gfCBTdGF0ZTxUPn0gW25leHRdIFRyYW5zaXRpb24gb3B0aW9uc1xuICAgKiBAcGFyYW0ge0ZsYWdzfSBbZmxhZ3NdIENvbGxlY3Rpb25zIGZsYWdzIHRvIGFkZCB0b2tlbiB0b1xuICAgKiBAcGFyYW0ge0NvbGxlY3Rpb25zPFQ+fSBbZ3JvdXBzXSBNYXN0ZXIgbGlzdCBvZiB0b2tlbiBncm91cHNcbiAgICovXG4gIHRhKGlucHV0cywgbmV4dCwgZmxhZ3MsIGdyb3Vwcykge1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB0aGlzLnR0KGlucHV0c1tpXSwgbmV4dCwgZmxhZ3MsIGdyb3Vwcyk7XG4gICAgfVxuICB9LFxuICAvKipcbiAgICogU2hvcnQgZm9yIFwidGFrZSByZWdleHAgdHJhbnNpdGlvblwiOyBkZWZpbmVzIGEgdHJhbnNpdGlvbiBmb3IgdGhpcyBzdGF0ZVxuICAgKiB3aGVuIGl0IGVuY291bnRlcnMgYSB0b2tlbiB3aGljaCBtYXRjaGVzIHRoZSBnaXZlbiByZWd1bGFyIGV4cHJlc3Npb25cbiAgICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cCBSZWd1bGFyIGV4cHJlc3Npb24gdHJhbnNpdGlvbiAocG9wdWxhdGUgZmlyc3QpXG4gICAqIEBwYXJhbSB7VCB8IFN0YXRlPFQ+fSBbbmV4dF0gVHJhbnNpdGlvbiBvcHRpb25zXG4gICAqIEBwYXJhbSB7RmxhZ3N9IFtmbGFnc10gQ29sbGVjdGlvbnMgZmxhZ3MgdG8gYWRkIHRva2VuIHRvXG4gICAqIEBwYXJhbSB7Q29sbGVjdGlvbnM8VD59IFtncm91cHNdIE1hc3RlciBsaXN0IG9mIHRva2VuIGdyb3Vwc1xuICAgKiBAcmV0dXJucyB7U3RhdGU8VD59IHRha2VuIGFmdGVyIHRoZSBnaXZlbiBpbnB1dFxuICAgKi9cbiAgdHIocmVnZXhwLCBuZXh0LCBmbGFncywgZ3JvdXBzKSB7XG4gICAgZ3JvdXBzID0gZ3JvdXBzIHx8IFN0YXRlLmdyb3VwcztcbiAgICBsZXQgbmV4dFN0YXRlO1xuICAgIGlmIChuZXh0ICYmIG5leHQuaikge1xuICAgICAgbmV4dFN0YXRlID0gbmV4dDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gVG9rZW4gd2l0aCBtYXliZSB0b2tlbiBncm91cHNcbiAgICAgIG5leHRTdGF0ZSA9IG5ldyBTdGF0ZShuZXh0KTtcbiAgICAgIGlmIChmbGFncyAmJiBncm91cHMpIHtcbiAgICAgICAgYWRkVG9Hcm91cHMobmV4dCwgZmxhZ3MsIGdyb3Vwcyk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuanIucHVzaChbcmVnZXhwLCBuZXh0U3RhdGVdKTtcbiAgICByZXR1cm4gbmV4dFN0YXRlO1xuICB9LFxuICAvKipcbiAgICogU2hvcnQgZm9yIFwidGFrZSB0cmFuc2l0aW9uc1wiLCB3aWxsIHRha2UgYXMgbWFueSBzZXF1ZW50aWFsIHRyYW5zaXRpb25zIGFzXG4gICAqIHRoZSBsZW5ndGggb2YgdGhlIGdpdmVuIGlucHV0IGFuZCByZXR1cm5zIHRoZVxuICAgKiByZXN1bHRpbmcgZmluYWwgc3RhdGUuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgc3RyaW5nW119IGlucHV0XG4gICAqIEBwYXJhbSB7VCB8IFN0YXRlPFQ+fSBbbmV4dF0gVHJhbnNpdGlvbiBvcHRpb25zXG4gICAqIEBwYXJhbSB7RmxhZ3N9IFtmbGFnc10gQ29sbGVjdGlvbnMgZmxhZ3MgdG8gYWRkIHRva2VuIHRvXG4gICAqIEBwYXJhbSB7Q29sbGVjdGlvbnM8VD59IFtncm91cHNdIE1hc3RlciBsaXN0IG9mIHRva2VuIGdyb3Vwc1xuICAgKiBAcmV0dXJucyB7U3RhdGU8VD59IHRha2VuIGFmdGVyIHRoZSBnaXZlbiBpbnB1dFxuICAgKi9cbiAgdHMoaW5wdXQsIG5leHQsIGZsYWdzLCBncm91cHMpIHtcbiAgICBsZXQgc3RhdGUgPSB0aGlzO1xuICAgIGNvbnN0IGxlbiA9IGlucHV0Lmxlbmd0aDtcbiAgICBpZiAoIWxlbikge1xuICAgICAgcmV0dXJuIHN0YXRlO1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbiAtIDE7IGkrKykge1xuICAgICAgc3RhdGUgPSBzdGF0ZS50dChpbnB1dFtpXSk7XG4gICAgfVxuICAgIHJldHVybiBzdGF0ZS50dChpbnB1dFtsZW4gLSAxXSwgbmV4dCwgZmxhZ3MsIGdyb3Vwcyk7XG4gIH0sXG4gIC8qKlxuICAgKiBTaG9ydCBmb3IgXCJ0YWtlIHRyYW5zaXRpb25cIiwgdGhpcyBpcyBhIG1ldGhvZCBmb3IgYnVpbGRpbmcvd29ya2luZyB3aXRoXG4gICAqIHN0YXRlIG1hY2hpbmVzLlxuICAgKlxuICAgKiBJZiBhIHN0YXRlIGFscmVhZHkgZXhpc3RzIGZvciB0aGUgZ2l2ZW4gaW5wdXQsIHJldHVybnMgaXQuXG4gICAqXG4gICAqIElmIGEgdG9rZW4gaXMgc3BlY2lmaWVkLCB0aGF0IHN0YXRlIHdpbGwgZW1pdCB0aGF0IHRva2VuIHdoZW4gcmVhY2hlZCBieVxuICAgKiB0aGUgbGlua2lmeSBlbmdpbmUuXG4gICAqXG4gICAqIElmIG5vIHN0YXRlIGV4aXN0cywgaXQgd2lsbCBiZSBpbml0aWFsaXplZCB3aXRoIHNvbWUgZGVmYXVsdCB0cmFuc2l0aW9uc1xuICAgKiB0aGF0IHJlc2VtYmxlIGV4aXN0aW5nIGRlZmF1bHQgdHJhbnNpdGlvbnMuXG4gICAqXG4gICAqIElmIGEgc3RhdGUgaXMgZ2l2ZW4gZm9yIHRoZSBzZWNvbmQgYXJndW1lbnQsIHRoYXQgc3RhdGUgd2lsbCBiZVxuICAgKiB0cmFuc2l0aW9uZWQgdG8gb24gdGhlIGdpdmVuIGlucHV0IHJlZ2FyZGxlc3Mgb2Ygd2hhdCB0aGF0IGlucHV0XG4gICAqIHByZXZpb3VzbHkgZGlkLlxuICAgKlxuICAgKiBTcGVjaWZ5IGEgdG9rZW4gZ3JvdXAgZmxhZ3MgdG8gZGVmaW5lIGdyb3VwcyB0aGF0IHRoaXMgdG9rZW4gYmVsb25ncyB0by5cbiAgICogVGhlIHRva2VuIHdpbGwgYmUgYWRkZWQgdG8gY29ycmVzcG9uZGluZyBlbnRpcmVzIGluIHRoZSBnaXZlbiBncm91cHNcbiAgICogb2JqZWN0LlxuICAgKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgY2hhcmFjdGVyLCB0b2tlbiB0eXBlIHRvIHRyYW5zaXRpb24gb25cbiAgICogQHBhcmFtIHtUIHwgU3RhdGU8VD59IFtuZXh0XSBUcmFuc2l0aW9uIG9wdGlvbnNcbiAgICogQHBhcmFtIHtGbGFnc30gW2ZsYWdzXSBDb2xsZWN0aW9ucyBmbGFncyB0byBhZGQgdG9rZW4gdG9cbiAgICogQHBhcmFtIHtDb2xsZWN0aW9uczxUPn0gW2dyb3Vwc10gTWFzdGVyIGxpc3Qgb2YgZ3JvdXBzXG4gICAqIEByZXR1cm5zIHtTdGF0ZTxUPn0gdGFrZW4gYWZ0ZXIgdGhlIGdpdmVuIGlucHV0XG4gICAqL1xuICB0dChpbnB1dCwgbmV4dCwgZmxhZ3MsIGdyb3Vwcykge1xuICAgIGdyb3VwcyA9IGdyb3VwcyB8fCBTdGF0ZS5ncm91cHM7XG4gICAgY29uc3Qgc3RhdGUgPSB0aGlzO1xuXG4gICAgLy8gQ2hlY2sgaWYgZXhpc3Rpbmcgc3RhdGUgZ2l2ZW4sIGp1c3QgYSBiYXNpYyB0cmFuc2l0aW9uXG4gICAgaWYgKG5leHQgJiYgbmV4dC5qKSB7XG4gICAgICBzdGF0ZS5qW2lucHV0XSA9IG5leHQ7XG4gICAgICByZXR1cm4gbmV4dDtcbiAgICB9XG4gICAgY29uc3QgdCA9IG5leHQ7XG5cbiAgICAvLyBUYWtlIHRoZSB0cmFuc2l0aW9uIHdpdGggdGhlIHVzdWFsIGRlZmF1bHQgbWVjaGFuaXNtcyBhbmQgdXNlIHRoYXQgYXNcbiAgICAvLyBhIHRlbXBsYXRlIGZvciBjcmVhdGluZyB0aGUgbmV4dCBzdGF0ZVxuICAgIGxldCBuZXh0U3RhdGUsXG4gICAgICB0ZW1wbGF0ZVN0YXRlID0gc3RhdGUuZ28oaW5wdXQpO1xuICAgIGlmICh0ZW1wbGF0ZVN0YXRlKSB7XG4gICAgICBuZXh0U3RhdGUgPSBuZXcgU3RhdGUoKTtcbiAgICAgIE9iamVjdC5hc3NpZ24obmV4dFN0YXRlLmosIHRlbXBsYXRlU3RhdGUuaik7XG4gICAgICBuZXh0U3RhdGUuanIucHVzaC5hcHBseShuZXh0U3RhdGUuanIsIHRlbXBsYXRlU3RhdGUuanIpO1xuICAgICAgbmV4dFN0YXRlLmpkID0gdGVtcGxhdGVTdGF0ZS5qZDtcbiAgICAgIG5leHRTdGF0ZS50ID0gdGVtcGxhdGVTdGF0ZS50O1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0U3RhdGUgPSBuZXcgU3RhdGUoKTtcbiAgICB9XG4gICAgaWYgKHQpIHtcbiAgICAgIC8vIEVuc3VyZSBuZXdseSB0b2tlbiBpcyBpbiB0aGUgc2FtZSBncm91cHMgYXMgdGhlIG9sZCB0b2tlblxuICAgICAgaWYgKGdyb3Vwcykge1xuICAgICAgICBpZiAobmV4dFN0YXRlLnQgJiYgdHlwZW9mIG5leHRTdGF0ZS50ID09PSAnc3RyaW5nJykge1xuICAgICAgICAgIGNvbnN0IGFsbEZsYWdzID0gT2JqZWN0LmFzc2lnbihmbGFnc0ZvclRva2VuKG5leHRTdGF0ZS50LCBncm91cHMpLCBmbGFncyk7XG4gICAgICAgICAgYWRkVG9Hcm91cHModCwgYWxsRmxhZ3MsIGdyb3Vwcyk7XG4gICAgICAgIH0gZWxzZSBpZiAoZmxhZ3MpIHtcbiAgICAgICAgICBhZGRUb0dyb3Vwcyh0LCBmbGFncywgZ3JvdXBzKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgbmV4dFN0YXRlLnQgPSB0OyAvLyBvdmVyd3JpdGUgYW55dGhpbmcgdGhhdCB3YXMgcHJldmlvdXNseSB0aGVyZVxuICAgIH1cbiAgICBzdGF0ZS5qW2lucHV0XSA9IG5leHRTdGF0ZTtcbiAgICByZXR1cm4gbmV4dFN0YXRlO1xuICB9XG59O1xuXG4vLyBIZWxwZXIgZnVuY3Rpb25zIHRvIGltcHJvdmUgbWluaWZpY2F0aW9uIChub3QgZXhwb3J0ZWQgb3V0c2lkZSBsaW5raWZ5anMgbW9kdWxlKVxuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge1N0YXRlPFQ+fSBzdGF0ZVxuICogQHBhcmFtIHtzdHJpbmcgfCBzdHJpbmdbXX0gaW5wdXRcbiAqIEBwYXJhbSB7RmxhZ3N9IFtmbGFnc11cbiAqIEBwYXJhbSB7Q29sbGVjdGlvbnM8VD59IFtncm91cHNdXG4gKi9cbmNvbnN0IHRhID0gKHN0YXRlLCBpbnB1dCwgbmV4dCwgZmxhZ3MsIGdyb3VwcykgPT4gc3RhdGUudGEoaW5wdXQsIG5leHQsIGZsYWdzLCBncm91cHMpO1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAcGFyYW0ge1N0YXRlPFQ+fSBzdGF0ZVxuICogQHBhcmFtIHtSZWdFeHB9IHJlZ2V4cFxuICogQHBhcmFtIHtUIHwgU3RhdGU8VD59IFtuZXh0XVxuICogQHBhcmFtIHtGbGFnc30gW2ZsYWdzXVxuICogQHBhcmFtIHtDb2xsZWN0aW9uczxUPn0gW2dyb3Vwc11cbiAqL1xuY29uc3QgdHIgPSAoc3RhdGUsIHJlZ2V4cCwgbmV4dCwgZmxhZ3MsIGdyb3VwcykgPT4gc3RhdGUudHIocmVnZXhwLCBuZXh0LCBmbGFncywgZ3JvdXBzKTtcblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtTdGF0ZTxUPn0gc3RhdGVcbiAqIEBwYXJhbSB7c3RyaW5nIHwgc3RyaW5nW119IGlucHV0XG4gKiBAcGFyYW0ge1QgfCBTdGF0ZTxUPn0gW25leHRdXG4gKiBAcGFyYW0ge0ZsYWdzfSBbZmxhZ3NdXG4gKiBAcGFyYW0ge0NvbGxlY3Rpb25zPFQ+fSBbZ3JvdXBzXVxuICovXG5jb25zdCB0cyA9IChzdGF0ZSwgaW5wdXQsIG5leHQsIGZsYWdzLCBncm91cHMpID0+IHN0YXRlLnRzKGlucHV0LCBuZXh0LCBmbGFncywgZ3JvdXBzKTtcblxuLyoqXG4gKiBAdGVtcGxhdGUgVFxuICogQHBhcmFtIHtTdGF0ZTxUPn0gc3RhdGVcbiAqIEBwYXJhbSB7c3RyaW5nfSBpbnB1dFxuICogQHBhcmFtIHtUIHwgU3RhdGU8VD59IFtuZXh0XVxuICogQHBhcmFtIHtDb2xsZWN0aW9uczxUPn0gW2dyb3Vwc11cbiAqIEBwYXJhbSB7RmxhZ3N9IFtmbGFnc11cbiAqL1xuY29uc3QgdHQgPSAoc3RhdGUsIGlucHV0LCBuZXh0LCBmbGFncywgZ3JvdXBzKSA9PiBzdGF0ZS50dChpbnB1dCwgbmV4dCwgZmxhZ3MsIGdyb3Vwcyk7XG5cbi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKipcblRleHQgVG9rZW5zXG5JZGVudGlmaWVycyBmb3IgdG9rZW4gb3V0cHV0cyBmcm9tIHRoZSByZWdleHAgc2Nhbm5lclxuKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG4vLyBBIHZhbGlkIHdlYiBkb21haW4gdG9rZW5cbmNvbnN0IFdPUkQgPSAnV09SRCc7IC8vIG9ubHkgY29udGFpbnMgYS16XG5jb25zdCBVV09SRCA9ICdVV09SRCc7IC8vIGNvbnRhaW5zIGxldHRlcnMgb3RoZXIgdGhhbiBhLXosIHVzZWQgZm9yIElETlxuY29uc3QgQVNDSUlOVU1FUklDQUwgPSAnQVNDSUlOVU1FUklDQUwnOyAvLyBjb250YWlucyBhLXosIDAtOVxuY29uc3QgQUxQSEFOVU1FUklDQUwgPSAnQUxQSEFOVU1FUklDQUwnOyAvLyBjb250YWlucyBudW1iZXJzIGFuZCBsZXR0ZXJzIG90aGVyIHRoYW4gYS16LCB1c2VkIGZvciBJRE5cblxuLy8gU3BlY2lhbCBjYXNlIG9mIHdvcmRcbmNvbnN0IExPQ0FMSE9TVCA9ICdMT0NBTEhPU1QnO1xuXG4vLyBWYWxpZCB0b3AtbGV2ZWwgZG9tYWluLCBzcGVjaWFsIGNhc2Ugb2YgV09SRCAoc2VlIHRsZHMuanMpXG5jb25zdCBUTEQgPSAnVExEJztcblxuLy8gVmFsaWQgSUROIFRMRCwgc3BlY2lhbCBjYXNlIG9mIFVXT1JEIChzZWUgdGxkcy5qcylcbmNvbnN0IFVUTEQgPSAnVVRMRCc7XG5cbi8vIFRoZSBzY2hlbWUgcG9ydGlvbiBvZiBhIHdlYiBVUkkgcHJvdG9jb2wuIFN1cHBvcnRlZCB0eXBlcyBpbmNsdWRlOiBgbWFpbHRvYCxcbi8vIGBmaWxlYCwgYW5kIHVzZXItZGVmaW5lZCBjdXN0b20gcHJvdG9jb2xzLiBMaW1pdGVkIHRvIHNjaGVtZXMgdGhhdCBjb250YWluXG4vLyBvbmx5IGxldHRlcnNcbmNvbnN0IFNDSEVNRSA9ICdTQ0hFTUUnO1xuXG4vLyBTaW1pbGFyIHRvIFNDSEVNRSwgZXhjZXB0IG1ha2VzIGRpc3RpbmN0aW9uIGZvciBzY2hlbWVzIHRoYXQgbXVzdCBhbHdheXMgYmVcbi8vIGZvbGxvd2VkIGJ5IGA6Ly9gLCBub3QganVzdCBgOmAuIFN1cHBvcnRlZCB0eXBlcyBpbmNsdWRlIGBodHRwYCwgYGh0dHBzYCxcbi8vIGBmdHBgLCBgZnRwc2BcbmNvbnN0IFNMQVNIX1NDSEVNRSA9ICdTTEFTSF9TQ0hFTUUnO1xuXG4vLyBBbnkgc2VxdWVuY2Ugb2YgZGlnaXRzIDAtOVxuY29uc3QgTlVNID0gJ05VTSc7XG5cbi8vIEFueSBudW1iZXIgb2YgY29uc2VjdXRpdmUgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzIHRoYXQgYXJlIG5vdCBuZXdsaW5lXG5jb25zdCBXUyA9ICdXUyc7XG5cbi8vIE5ldyBsaW5lICh1bml4IHN0eWxlKVxuY29uc3QgTkwgPSAnTkwnOyAvLyBcXG5cblxuLy8gT3BlbmluZy9jbG9zaW5nIGJyYWNrZXQgY2xhc3Nlc1xuLy8gVE9ETzogUmVuYW1lIE9QRU4gLT4gTEVGVCBhbmQgQ0xPU0UgLT4gUklHSFQgaW4gdjUgdG8gZml0IHdpdGggVW5pY29kZSBuYW1lc1xuLy8gQWxzbyByZW5hbWUgYW5nbGUgYnJhY2tlcyB0byBMRVNTVEhBTiBhbmQgR1JFQVRFUiBUSEFOXG5jb25zdCBPUEVOQlJBQ0UgPSAnT1BFTkJSQUNFJzsgLy8ge1xuY29uc3QgQ0xPU0VCUkFDRSA9ICdDTE9TRUJSQUNFJzsgLy8gfVxuY29uc3QgT1BFTkJSQUNLRVQgPSAnT1BFTkJSQUNLRVQnOyAvLyBbXG5jb25zdCBDTE9TRUJSQUNLRVQgPSAnQ0xPU0VCUkFDS0VUJzsgLy8gXVxuY29uc3QgT1BFTlBBUkVOID0gJ09QRU5QQVJFTic7IC8vIChcbmNvbnN0IENMT1NFUEFSRU4gPSAnQ0xPU0VQQVJFTic7IC8vIClcbmNvbnN0IE9QRU5BTkdMRUJSQUNLRVQgPSAnT1BFTkFOR0xFQlJBQ0tFVCc7IC8vIDxcbmNvbnN0IENMT1NFQU5HTEVCUkFDS0VUID0gJ0NMT1NFQU5HTEVCUkFDS0VUJzsgLy8gPlxuY29uc3QgRlVMTFdJRFRITEVGVFBBUkVOID0gJ0ZVTExXSURUSExFRlRQQVJFTic7IC8vIO+8iFxuY29uc3QgRlVMTFdJRFRIUklHSFRQQVJFTiA9ICdGVUxMV0lEVEhSSUdIVFBBUkVOJzsgLy8g77yJXG5jb25zdCBMRUZUQ09STkVSQlJBQ0tFVCA9ICdMRUZUQ09STkVSQlJBQ0tFVCc7IC8vIOOAjFxuY29uc3QgUklHSFRDT1JORVJCUkFDS0VUID0gJ1JJR0hUQ09STkVSQlJBQ0tFVCc7IC8vIOOAjVxuY29uc3QgTEVGVFdISVRFQ09STkVSQlJBQ0tFVCA9ICdMRUZUV0hJVEVDT1JORVJCUkFDS0VUJzsgLy8g44COXG5jb25zdCBSSUdIVFdISVRFQ09STkVSQlJBQ0tFVCA9ICdSSUdIVFdISVRFQ09STkVSQlJBQ0tFVCc7IC8vIOOAj1xuY29uc3QgRlVMTFdJRFRITEVTU1RIQU4gPSAnRlVMTFdJRFRITEVTU1RIQU4nOyAvLyDvvJxcbmNvbnN0IEZVTExXSURUSEdSRUFURVJUSEFOID0gJ0ZVTExXSURUSEdSRUFURVJUSEFOJzsgLy8g77yeXG5cbi8vIFZhcmlvdXMgc3ltYm9sc1xuY29uc3QgQU1QRVJTQU5EID0gJ0FNUEVSU0FORCc7IC8vICZcbmNvbnN0IEFQT1NUUk9QSEUgPSAnQVBPU1RST1BIRSc7IC8vICdcbmNvbnN0IEFTVEVSSVNLID0gJ0FTVEVSSVNLJzsgLy8gKlxuY29uc3QgQVQgPSAnQVQnOyAvLyBAXG5jb25zdCBCQUNLU0xBU0ggPSAnQkFDS1NMQVNIJzsgLy8gXFxcbmNvbnN0IEJBQ0tUSUNLID0gJ0JBQ0tUSUNLJzsgLy8gYFxuY29uc3QgQ0FSRVQgPSAnQ0FSRVQnOyAvLyBeXG5jb25zdCBDT0xPTiA9ICdDT0xPTic7IC8vIDpcbmNvbnN0IENPTU1BID0gJ0NPTU1BJzsgLy8gLFxuY29uc3QgRE9MTEFSID0gJ0RPTExBUic7IC8vICRcbmNvbnN0IERPVCA9ICdET1QnOyAvLyAuXG5jb25zdCBFUVVBTFMgPSAnRVFVQUxTJzsgLy8gPVxuY29uc3QgRVhDTEFNQVRJT04gPSAnRVhDTEFNQVRJT04nOyAvLyAhXG5jb25zdCBIWVBIRU4gPSAnSFlQSEVOJzsgLy8gLVxuY29uc3QgUEVSQ0VOVCA9ICdQRVJDRU5UJzsgLy8gJVxuY29uc3QgUElQRSA9ICdQSVBFJzsgLy8gfFxuY29uc3QgUExVUyA9ICdQTFVTJzsgLy8gK1xuY29uc3QgUE9VTkQgPSAnUE9VTkQnOyAvLyAjXG5jb25zdCBRVUVSWSA9ICdRVUVSWSc7IC8vID9cbmNvbnN0IFFVT1RFID0gJ1FVT1RFJzsgLy8gXCJcbmNvbnN0IEZVTExXSURUSE1JRERMRURPVCA9ICdGVUxMV0lEVEhNSURETEVET1QnOyAvLyDjg7tcblxuY29uc3QgU0VNSSA9ICdTRU1JJzsgLy8gO1xuY29uc3QgU0xBU0ggPSAnU0xBU0gnOyAvLyAvXG5jb25zdCBUSUxERSA9ICdUSUxERSc7IC8vIH5cbmNvbnN0IFVOREVSU0NPUkUgPSAnVU5ERVJTQ09SRSc7IC8vIF9cblxuLy8gRW1vamkgc3ltYm9sXG5jb25zdCBFTU9KSSQxID0gJ0VNT0pJJztcblxuLy8gRGVmYXVsdCB0b2tlbiAtIGFueXRoaW5nIHRoYXQgaXMgbm90IG9uZSBvZiB0aGUgYWJvdmVcbmNvbnN0IFNZTSA9ICdTWU0nO1xuXG52YXIgdGsgPSAvKiNfX1BVUkVfXyovT2JqZWN0LmZyZWV6ZSh7XG5cdF9fcHJvdG9fXzogbnVsbCxcblx0QUxQSEFOVU1FUklDQUw6IEFMUEhBTlVNRVJJQ0FMLFxuXHRBTVBFUlNBTkQ6IEFNUEVSU0FORCxcblx0QVBPU1RST1BIRTogQVBPU1RST1BIRSxcblx0QVNDSUlOVU1FUklDQUw6IEFTQ0lJTlVNRVJJQ0FMLFxuXHRBU1RFUklTSzogQVNURVJJU0ssXG5cdEFUOiBBVCxcblx0QkFDS1NMQVNIOiBCQUNLU0xBU0gsXG5cdEJBQ0tUSUNLOiBCQUNLVElDSyxcblx0Q0FSRVQ6IENBUkVULFxuXHRDTE9TRUFOR0xFQlJBQ0tFVDogQ0xPU0VBTkdMRUJSQUNLRVQsXG5cdENMT1NFQlJBQ0U6IENMT1NFQlJBQ0UsXG5cdENMT1NFQlJBQ0tFVDogQ0xPU0VCUkFDS0VULFxuXHRDTE9TRVBBUkVOOiBDTE9TRVBBUkVOLFxuXHRDT0xPTjogQ09MT04sXG5cdENPTU1BOiBDT01NQSxcblx0RE9MTEFSOiBET0xMQVIsXG5cdERPVDogRE9ULFxuXHRFTU9KSTogRU1PSkkkMSxcblx0RVFVQUxTOiBFUVVBTFMsXG5cdEVYQ0xBTUFUSU9OOiBFWENMQU1BVElPTixcblx0RlVMTFdJRFRIR1JFQVRFUlRIQU46IEZVTExXSURUSEdSRUFURVJUSEFOLFxuXHRGVUxMV0lEVEhMRUZUUEFSRU46IEZVTExXSURUSExFRlRQQVJFTixcblx0RlVMTFdJRFRITEVTU1RIQU46IEZVTExXSURUSExFU1NUSEFOLFxuXHRGVUxMV0lEVEhNSURETEVET1Q6IEZVTExXSURUSE1JRERMRURPVCxcblx0RlVMTFdJRFRIUklHSFRQQVJFTjogRlVMTFdJRFRIUklHSFRQQVJFTixcblx0SFlQSEVOOiBIWVBIRU4sXG5cdExFRlRDT1JORVJCUkFDS0VUOiBMRUZUQ09STkVSQlJBQ0tFVCxcblx0TEVGVFdISVRFQ09STkVSQlJBQ0tFVDogTEVGVFdISVRFQ09STkVSQlJBQ0tFVCxcblx0TE9DQUxIT1NUOiBMT0NBTEhPU1QsXG5cdE5MOiBOTCxcblx0TlVNOiBOVU0sXG5cdE9QRU5BTkdMRUJSQUNLRVQ6IE9QRU5BTkdMRUJSQUNLRVQsXG5cdE9QRU5CUkFDRTogT1BFTkJSQUNFLFxuXHRPUEVOQlJBQ0tFVDogT1BFTkJSQUNLRVQsXG5cdE9QRU5QQVJFTjogT1BFTlBBUkVOLFxuXHRQRVJDRU5UOiBQRVJDRU5ULFxuXHRQSVBFOiBQSVBFLFxuXHRQTFVTOiBQTFVTLFxuXHRQT1VORDogUE9VTkQsXG5cdFFVRVJZOiBRVUVSWSxcblx0UVVPVEU6IFFVT1RFLFxuXHRSSUdIVENPUk5FUkJSQUNLRVQ6IFJJR0hUQ09STkVSQlJBQ0tFVCxcblx0UklHSFRXSElURUNPUk5FUkJSQUNLRVQ6IFJJR0hUV0hJVEVDT1JORVJCUkFDS0VULFxuXHRTQ0hFTUU6IFNDSEVNRSxcblx0U0VNSTogU0VNSSxcblx0U0xBU0g6IFNMQVNILFxuXHRTTEFTSF9TQ0hFTUU6IFNMQVNIX1NDSEVNRSxcblx0U1lNOiBTWU0sXG5cdFRJTERFOiBUSUxERSxcblx0VExEOiBUTEQsXG5cdFVOREVSU0NPUkU6IFVOREVSU0NPUkUsXG5cdFVUTEQ6IFVUTEQsXG5cdFVXT1JEOiBVV09SRCxcblx0V09SRDogV09SRCxcblx0V1M6IFdTXG59KTtcblxuLy8gTm90ZSB0aGF0IHRoZXNlIHR3byBVbmljb2RlIG9uZXMgZXhwYW5kIGludG8gYSByZWFsbHkgYmlnIG9uZSB3aXRoIEJhYmVsXG5jb25zdCBBU0NJSV9MRVRURVIgPSAvW2Etel0vO1xuY29uc3QgTEVUVEVSID0gL1xccHtMfS91OyAvLyBBbnkgVW5pY29kZSBjaGFyYWN0ZXIgd2l0aCBsZXR0ZXIgZGF0YSB0eXBlXG5jb25zdCBFTU9KSSA9IC9cXHB7RW1vaml9L3U7IC8vIEFueSBVbmljb2RlIGVtb2ppIGNoYXJhY3RlclxuY29uc3QgRU1PSklfVkFSSUFUSU9OJDEgPSAvXFx1ZmUwZi87XG5jb25zdCBESUdJVCA9IC9cXGQvO1xuY29uc3QgU1BBQ0UgPSAvXFxzLztcblxudmFyIHJlZ2V4cCA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcblx0X19wcm90b19fOiBudWxsLFxuXHRBU0NJSV9MRVRURVI6IEFTQ0lJX0xFVFRFUixcblx0RElHSVQ6IERJR0lULFxuXHRFTU9KSTogRU1PSkksXG5cdEVNT0pJX1ZBUklBVElPTjogRU1PSklfVkFSSUFUSU9OJDEsXG5cdExFVFRFUjogTEVUVEVSLFxuXHRTUEFDRTogU1BBQ0Vcbn0pO1xuXG4vKipcblx0VGhlIHNjYW5uZXIgcHJvdmlkZXMgYW4gaW50ZXJmYWNlIHRoYXQgdGFrZXMgYSBzdHJpbmcgb2YgdGV4dCBhcyBpbnB1dCwgYW5kXG5cdG91dHB1dHMgYW4gYXJyYXkgb2YgdG9rZW5zIGluc3RhbmNlcyB0aGF0IGNhbiBiZSB1c2VkIGZvciBlYXN5IFVSTCBwYXJzaW5nLlxuKi9cblxuY29uc3QgQ1IgPSAnXFxyJzsgLy8gY2FycmlhZ2UtcmV0dXJuIGNoYXJhY3RlclxuY29uc3QgTEYgPSAnXFxuJzsgLy8gbGluZS1mZWVkIGNoYXJhY3RlclxuY29uc3QgRU1PSklfVkFSSUFUSU9OID0gJ1xcdWZlMGYnOyAvLyBWYXJpYXRpb24gc2VsZWN0b3IsIGZvbGxvd3MgaGVhcnQgYW5kIG90aGVyc1xuY29uc3QgRU1PSklfSk9JTkVSID0gJ1xcdTIwMGQnOyAvLyB6ZXJvLXdpZHRoIGpvaW5lclxuY29uc3QgT0JKRUNUX1JFUExBQ0VNRU5UID0gJ1xcdWZmZmMnOyAvLyB3aGl0ZXNwYWNlIHBsYWNlaG9sZGVyIHRoYXQgc29tZXRpbWVzIGFwcGVhcnMgaW4gcmljaCB0ZXh0IGVkaXRvcnNcblxubGV0IHRsZHMgPSBudWxsLFxuICB1dGxkcyA9IG51bGw7IC8vIGRvbid0IGNoYW5nZSBzbyBvbmx5IGhhdmUgdG8gYmUgY29tcHV0ZWQgb25jZVxuXG4vKipcbiAqIFNjYW5uZXIgb3V0cHV0IHRva2VuOlxuICogLSBgdGAgaXMgdGhlIHRva2VuIG5hbWUgKGUuZy4sICdOVU0nLCAnRU1PSkknLCAnVExEJylcbiAqIC0gYHZgIGlzIHRoZSB2YWx1ZSBvZiB0aGUgdG9rZW4gKGUuZy4sICcxMjMnLCAn4p2k77iPJywgJ2NvbScpXG4gKiAtIGBzYCBpcyB0aGUgc3RhcnQgaW5kZXggb2YgdGhlIHRva2VuIGluIHRoZSBvcmlnaW5hbCBzdHJpbmdcbiAqIC0gYGVgIGlzIHRoZSBlbmQgaW5kZXggb2YgdGhlIHRva2VuIGluIHRoZSBvcmlnaW5hbCBzdHJpbmdcbiAqIEB0eXBlZGVmIHt7dDogc3RyaW5nLCB2OiBzdHJpbmcsIHM6IG51bWJlciwgZTogbnVtYmVyfX0gVG9rZW5cbiAqL1xuXG4vKipcbiAqIEB0ZW1wbGF0ZSBUXG4gKiBAdHlwZWRlZiB7eyBbY29sbGVjdGlvbjogc3RyaW5nXTogVFtdIH19IENvbGxlY3Rpb25zXG4gKi9cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBzY2FubmVyIGNoYXJhY3Rlci1iYXNlZCBzdGF0ZSBtYWNoaW5lIGZvciB0aGUgZ2l2ZW4gc3RhcnRcbiAqIHN0YXRlXG4gKiBAcGFyYW0ge1tzdHJpbmcsIGJvb2xlYW5dW119IGN1c3RvbVNjaGVtZXMgTGlzdCBvZiBjdXN0b20gc2NoZW1lcywgd2hlcmUgZWFjaFxuICogaXRlbSBpcyBhIGxlbmd0aC0yIHR1cGxlIHdpdGggdGhlIGZpcnN0IGVsZW1lbnQgc2V0IHRvIHRoZSBzdHJpbmcgc2NoZW1lLCBhbmRcbiAqIHRoZSBzZWNvbmQgZWxlbWVudCBzZXQgdG8gYHRydWVgIGlmIHRoZSBgOi8vYCBhZnRlciB0aGUgc2NoZW1lIGlzIG9wdGlvbmFsXG4gKi9cbmZ1bmN0aW9uIGluaXQkMihjdXN0b21TY2hlbWVzID0gW10pIHtcbiAgLy8gRnJlcXVlbnRseSB1c2VkIHN0YXRlcyAobmFtZSBhcmd1bWVudCByZW1vdmVkIGR1cmluZyBtaW5pZmljYXRpb24pXG4gIC8qKiBAdHlwZSBDb2xsZWN0aW9uczxzdHJpbmc+ICovXG4gIGNvbnN0IGdyb3VwcyA9IHt9OyAvLyBvZiB0b2tlbnNcbiAgU3RhdGUuZ3JvdXBzID0gZ3JvdXBzO1xuICAvKiogQHR5cGUgU3RhdGU8c3RyaW5nPiAqL1xuICBjb25zdCBTdGFydCA9IG5ldyBTdGF0ZSgpO1xuICBpZiAodGxkcyA9PSBudWxsKSB7XG4gICAgdGxkcyA9IGRlY29kZVRsZHMoZW5jb2RlZFRsZHMpO1xuICB9XG4gIGlmICh1dGxkcyA9PSBudWxsKSB7XG4gICAgdXRsZHMgPSBkZWNvZGVUbGRzKGVuY29kZWRVdGxkcyk7XG4gIH1cblxuICAvLyBTdGF0ZXMgZm9yIHNwZWNpYWwgVVJMIHN5bWJvbHMgdGhhdCBhY2NlcHQgaW1tZWRpYXRlbHkgYWZ0ZXIgc3RhcnRcbiAgdHQoU3RhcnQsIFwiJ1wiLCBBUE9TVFJPUEhFKTtcbiAgdHQoU3RhcnQsICd7JywgT1BFTkJSQUNFKTtcbiAgdHQoU3RhcnQsICd9JywgQ0xPU0VCUkFDRSk7XG4gIHR0KFN0YXJ0LCAnWycsIE9QRU5CUkFDS0VUKTtcbiAgdHQoU3RhcnQsICddJywgQ0xPU0VCUkFDS0VUKTtcbiAgdHQoU3RhcnQsICcoJywgT1BFTlBBUkVOKTtcbiAgdHQoU3RhcnQsICcpJywgQ0xPU0VQQVJFTik7XG4gIHR0KFN0YXJ0LCAnPCcsIE9QRU5BTkdMRUJSQUNLRVQpO1xuICB0dChTdGFydCwgJz4nLCBDTE9TRUFOR0xFQlJBQ0tFVCk7XG4gIHR0KFN0YXJ0LCAn77yIJywgRlVMTFdJRFRITEVGVFBBUkVOKTtcbiAgdHQoU3RhcnQsICfvvIknLCBGVUxMV0lEVEhSSUdIVFBBUkVOKTtcbiAgdHQoU3RhcnQsICfjgIwnLCBMRUZUQ09STkVSQlJBQ0tFVCk7XG4gIHR0KFN0YXJ0LCAn44CNJywgUklHSFRDT1JORVJCUkFDS0VUKTtcbiAgdHQoU3RhcnQsICfjgI4nLCBMRUZUV0hJVEVDT1JORVJCUkFDS0VUKTtcbiAgdHQoU3RhcnQsICfjgI8nLCBSSUdIVFdISVRFQ09STkVSQlJBQ0tFVCk7XG4gIHR0KFN0YXJ0LCAn77ycJywgRlVMTFdJRFRITEVTU1RIQU4pO1xuICB0dChTdGFydCwgJ++8nicsIEZVTExXSURUSEdSRUFURVJUSEFOKTtcbiAgdHQoU3RhcnQsICcmJywgQU1QRVJTQU5EKTtcbiAgdHQoU3RhcnQsICcqJywgQVNURVJJU0spO1xuICB0dChTdGFydCwgJ0AnLCBBVCk7XG4gIHR0KFN0YXJ0LCAnYCcsIEJBQ0tUSUNLKTtcbiAgdHQoU3RhcnQsICdeJywgQ0FSRVQpO1xuICB0dChTdGFydCwgJzonLCBDT0xPTik7XG4gIHR0KFN0YXJ0LCAnLCcsIENPTU1BKTtcbiAgdHQoU3RhcnQsICckJywgRE9MTEFSKTtcbiAgdHQoU3RhcnQsICcuJywgRE9UKTtcbiAgdHQoU3RhcnQsICc9JywgRVFVQUxTKTtcbiAgdHQoU3RhcnQsICchJywgRVhDTEFNQVRJT04pO1xuICB0dChTdGFydCwgJy0nLCBIWVBIRU4pO1xuICB0dChTdGFydCwgJyUnLCBQRVJDRU5UKTtcbiAgdHQoU3RhcnQsICd8JywgUElQRSk7XG4gIHR0KFN0YXJ0LCAnKycsIFBMVVMpO1xuICB0dChTdGFydCwgJyMnLCBQT1VORCk7XG4gIHR0KFN0YXJ0LCAnPycsIFFVRVJZKTtcbiAgdHQoU3RhcnQsICdcIicsIFFVT1RFKTtcbiAgdHQoU3RhcnQsICcvJywgU0xBU0gpO1xuICB0dChTdGFydCwgJzsnLCBTRU1JKTtcbiAgdHQoU3RhcnQsICd+JywgVElMREUpO1xuICB0dChTdGFydCwgJ18nLCBVTkRFUlNDT1JFKTtcbiAgdHQoU3RhcnQsICdcXFxcJywgQkFDS1NMQVNIKTtcbiAgdHQoU3RhcnQsICfjg7snLCBGVUxMV0lEVEhNSURETEVET1QpO1xuICBjb25zdCBOdW0gPSB0cihTdGFydCwgRElHSVQsIE5VTSwge1xuICAgIFtudW1lcmljXTogdHJ1ZVxuICB9KTtcbiAgdHIoTnVtLCBESUdJVCwgTnVtKTtcbiAgY29uc3QgQXNjaWludW1lcmljID0gdHIoTnVtLCBBU0NJSV9MRVRURVIsIEFTQ0lJTlVNRVJJQ0FMLCB7XG4gICAgW2FzY2lpbnVtZXJpY106IHRydWVcbiAgfSk7XG4gIGNvbnN0IEFscGhhbnVtZXJpYyA9IHRyKE51bSwgTEVUVEVSLCBBTFBIQU5VTUVSSUNBTCwge1xuICAgIFthbHBoYW51bWVyaWNdOiB0cnVlXG4gIH0pO1xuXG4gIC8vIFN0YXRlIHdoaWNoIGVtaXRzIGEgd29yZCB0b2tlblxuICBjb25zdCBXb3JkID0gdHIoU3RhcnQsIEFTQ0lJX0xFVFRFUiwgV09SRCwge1xuICAgIFthc2NpaV06IHRydWVcbiAgfSk7XG4gIHRyKFdvcmQsIERJR0lULCBBc2NpaW51bWVyaWMpO1xuICB0cihXb3JkLCBBU0NJSV9MRVRURVIsIFdvcmQpO1xuICB0cihBc2NpaW51bWVyaWMsIERJR0lULCBBc2NpaW51bWVyaWMpO1xuICB0cihBc2NpaW51bWVyaWMsIEFTQ0lJX0xFVFRFUiwgQXNjaWludW1lcmljKTtcblxuICAvLyBTYW1lIGFzIHByZXZpb3VzLCBidXQgc3BlY2lmaWMgdG8gbm9uLWZzbS5hc2NpaSBhbHBoYWJldCB3b3Jkc1xuICBjb25zdCBVV29yZCA9IHRyKFN0YXJ0LCBMRVRURVIsIFVXT1JELCB7XG4gICAgW2FscGhhXTogdHJ1ZVxuICB9KTtcbiAgdHIoVVdvcmQsIEFTQ0lJX0xFVFRFUik7IC8vIE5vbi1hY2NlcHRpbmdcbiAgdHIoVVdvcmQsIERJR0lULCBBbHBoYW51bWVyaWMpO1xuICB0cihVV29yZCwgTEVUVEVSLCBVV29yZCk7XG4gIHRyKEFscGhhbnVtZXJpYywgRElHSVQsIEFscGhhbnVtZXJpYyk7XG4gIHRyKEFscGhhbnVtZXJpYywgQVNDSUlfTEVUVEVSKTsgLy8gTm9uLWFjY2VwdGluZ1xuICB0cihBbHBoYW51bWVyaWMsIExFVFRFUiwgQWxwaGFudW1lcmljKTsgLy8gTm9uLWFjY2VwdGluZ1xuXG4gIC8vIFdoaXRlc3BhY2UganVtcHNcbiAgLy8gVG9rZW5zIG9mIG9ubHkgbm9uLW5ld2xpbmUgd2hpdGVzcGFjZSBhcmUgYXJiaXRyYXJpbHkgbG9uZ1xuICAvLyBJZiBhbnkgd2hpdGVzcGFjZSBleGNlcHQgbmV3bGluZSwgbW9yZSB3aGl0ZXNwYWNlIVxuICBjb25zdCBObCA9IHR0KFN0YXJ0LCBMRiwgTkwsIHtcbiAgICBbd2hpdGVzcGFjZV06IHRydWVcbiAgfSk7XG4gIGNvbnN0IENyID0gdHQoU3RhcnQsIENSLCBXUywge1xuICAgIFt3aGl0ZXNwYWNlXTogdHJ1ZVxuICB9KTtcbiAgY29uc3QgV3MgPSB0cihTdGFydCwgU1BBQ0UsIFdTLCB7XG4gICAgW3doaXRlc3BhY2VdOiB0cnVlXG4gIH0pO1xuICB0dChTdGFydCwgT0JKRUNUX1JFUExBQ0VNRU5ULCBXcyk7XG4gIHR0KENyLCBMRiwgTmwpOyAvLyBcXHJcXG5cbiAgdHQoQ3IsIE9CSkVDVF9SRVBMQUNFTUVOVCwgV3MpO1xuICB0cihDciwgU1BBQ0UsIFdzKTtcbiAgdHQoV3MsIENSKTsgLy8gbm9uLWFjY2VwdGluZyBzdGF0ZSB0byBhdm9pZCBtaXhpbmcgd2hpdGVzcGFjZXNcbiAgdHQoV3MsIExGKTsgLy8gbm9uLWFjY2VwdGluZyBzdGF0ZSB0byBhdm9pZCBtaXhpbmcgd2hpdGVzcGFjZXNcbiAgdHIoV3MsIFNQQUNFLCBXcyk7XG4gIHR0KFdzLCBPQkpFQ1RfUkVQTEFDRU1FTlQsIFdzKTtcblxuICAvLyBFbW9qaSB0b2tlbnMuIFRoZXkgYXJlIG5vdCBncm91cGVkIGJ5IHRoZSBzY2FubmVyIGV4Y2VwdCBpbiBjYXNlcyB3aGVyZSBhXG4gIC8vIHplcm8td2lkdGggam9pbmVyIGlzIHByZXNlbnRcbiAgY29uc3QgRW1vamkgPSB0cihTdGFydCwgRU1PSkksIEVNT0pJJDEsIHtcbiAgICBbZW1vamldOiB0cnVlXG4gIH0pO1xuICB0dChFbW9qaSwgJyMnKTsgLy8gbm8gdHJhbnNpdGlvbiwgZW1vamkgcmVnZXggc2VlbXMgdG8gbWF0Y2ggI1xuICB0cihFbW9qaSwgRU1PSkksIEVtb2ppKTtcbiAgdHQoRW1vamksIEVNT0pJX1ZBUklBVElPTiwgRW1vamkpO1xuICAvLyB0dChTdGFydCwgRU1PSklfVkFSSUFUSU9OLCBFbW9qaSk7IC8vIFRoaXMgb25lIGlzIHNrZXRjaHlcblxuICBjb25zdCBFbW9qaUpvaW5lciA9IHR0KEVtb2ppLCBFTU9KSV9KT0lORVIpO1xuICB0dChFbW9qaUpvaW5lciwgJyMnKTtcbiAgdHIoRW1vamlKb2luZXIsIEVNT0pJLCBFbW9qaSk7XG4gIC8vIHR0KEVtb2ppSm9pbmVyLCBFTU9KSV9WQVJJQVRJT04sIEVtb2ppKTsgLy8gYWxzbyBza2V0Y2h5XG5cbiAgLy8gR2VuZXJhdGVzIHN0YXRlcyBmb3IgdG9wLWxldmVsIGRvbWFpbnNcbiAgLy8gTm90ZSB0aGF0IHRoaXMgaXMgbW9zdCBhY2N1cmF0ZSB3aGVuIHRsZHMgYXJlIGluIGFscGhhYmV0aWNhbCBvcmRlclxuICBjb25zdCB3b3JkanIgPSBbW0FTQ0lJX0xFVFRFUiwgV29yZF0sIFtESUdJVCwgQXNjaWludW1lcmljXV07XG4gIGNvbnN0IHV3b3JkanIgPSBbW0FTQ0lJX0xFVFRFUiwgbnVsbF0sIFtMRVRURVIsIFVXb3JkXSwgW0RJR0lULCBBbHBoYW51bWVyaWNdXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB0bGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgZmFzdHRzKFN0YXJ0LCB0bGRzW2ldLCBUTEQsIFdPUkQsIHdvcmRqcik7XG4gIH1cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB1dGxkcy5sZW5ndGg7IGkrKykge1xuICAgIGZhc3R0cyhTdGFydCwgdXRsZHNbaV0sIFVUTEQsIFVXT1JELCB1d29yZGpyKTtcbiAgfVxuICBhZGRUb0dyb3VwcyhUTEQsIHtcbiAgICB0bGQ6IHRydWUsXG4gICAgYXNjaWk6IHRydWVcbiAgfSwgZ3JvdXBzKTtcbiAgYWRkVG9Hcm91cHMoVVRMRCwge1xuICAgIHV0bGQ6IHRydWUsXG4gICAgYWxwaGE6IHRydWVcbiAgfSwgZ3JvdXBzKTtcblxuICAvLyBDb2xsZWN0IHRoZSBzdGF0ZXMgZ2VuZXJhdGVkIGJ5IGRpZmZlcmVudCBwcm90b2NvbHMuIE5PVEU6IElmIGFueSBuZXcgVExEc1xuICAvLyBnZXQgYWRkZWQgdGhhdCBhcmUgYWxzbyBwcm90b2NvbHMsIHNldCB0aGUgdG9rZW4gdG8gYmUgdGhlIHNhbWUgYXMgdGhlXG4gIC8vIHByb3RvY29sIHRvIGVuc3VyZSBwYXJzaW5nIHdvcmtzIGFzIGV4cGVjdGVkLlxuICBmYXN0dHMoU3RhcnQsICdmaWxlJywgU0NIRU1FLCBXT1JELCB3b3JkanIpO1xuICBmYXN0dHMoU3RhcnQsICdtYWlsdG8nLCBTQ0hFTUUsIFdPUkQsIHdvcmRqcik7XG4gIGZhc3R0cyhTdGFydCwgJ2h0dHAnLCBTTEFTSF9TQ0hFTUUsIFdPUkQsIHdvcmRqcik7XG4gIGZhc3R0cyhTdGFydCwgJ2h0dHBzJywgU0xBU0hfU0NIRU1FLCBXT1JELCB3b3JkanIpO1xuICBmYXN0dHMoU3RhcnQsICdmdHAnLCBTTEFTSF9TQ0hFTUUsIFdPUkQsIHdvcmRqcik7XG4gIGZhc3R0cyhTdGFydCwgJ2Z0cHMnLCBTTEFTSF9TQ0hFTUUsIFdPUkQsIHdvcmRqcik7XG4gIGFkZFRvR3JvdXBzKFNDSEVNRSwge1xuICAgIHNjaGVtZTogdHJ1ZSxcbiAgICBhc2NpaTogdHJ1ZVxuICB9LCBncm91cHMpO1xuICBhZGRUb0dyb3VwcyhTTEFTSF9TQ0hFTUUsIHtcbiAgICBzbGFzaHNjaGVtZTogdHJ1ZSxcbiAgICBhc2NpaTogdHJ1ZVxuICB9LCBncm91cHMpO1xuXG4gIC8vIFJlZ2lzdGVyIGN1c3RvbSBzY2hlbWVzLiBBc3N1bWVzIGVhY2ggc2NoZW1lIGlzIGFzY2lpbnVtZXJpYyB3aXRoIGh5cGhlbnNcbiAgY3VzdG9tU2NoZW1lcyA9IGN1c3RvbVNjaGVtZXMuc29ydCgoYSwgYikgPT4gYVswXSA+IGJbMF0gPyAxIDogLTEpO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGN1c3RvbVNjaGVtZXMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCBzY2ggPSBjdXN0b21TY2hlbWVzW2ldWzBdO1xuICAgIGNvbnN0IG9wdGlvbmFsU2xhc2hTbGFzaCA9IGN1c3RvbVNjaGVtZXNbaV1bMV07XG4gICAgY29uc3QgZmxhZ3MgPSBvcHRpb25hbFNsYXNoU2xhc2ggPyB7XG4gICAgICBbc2NoZW1lXTogdHJ1ZVxuICAgIH0gOiB7XG4gICAgICBbc2xhc2hzY2hlbWVdOiB0cnVlXG4gICAgfTtcbiAgICBpZiAoc2NoLmluZGV4T2YoJy0nKSA+PSAwKSB7XG4gICAgICBmbGFnc1tkb21haW5dID0gdHJ1ZTtcbiAgICB9IGVsc2UgaWYgKCFBU0NJSV9MRVRURVIudGVzdChzY2gpKSB7XG4gICAgICBmbGFnc1tudW1lcmljXSA9IHRydWU7IC8vIG51bWJlcnMgb25seVxuICAgIH0gZWxzZSBpZiAoRElHSVQudGVzdChzY2gpKSB7XG4gICAgICBmbGFnc1thc2NpaW51bWVyaWNdID0gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhZ3NbYXNjaWldID0gdHJ1ZTtcbiAgICB9XG4gICAgdHMoU3RhcnQsIHNjaCwgc2NoLCBmbGFncyk7XG4gIH1cblxuICAvLyBMb2NhbGhvc3QgdG9rZW5cbiAgdHMoU3RhcnQsICdsb2NhbGhvc3QnLCBMT0NBTEhPU1QsIHtcbiAgICBhc2NpaTogdHJ1ZVxuICB9KTtcblxuICAvLyBTZXQgZGVmYXVsdCB0cmFuc2l0aW9uIGZvciBzdGFydCBzdGF0ZSAoc29tZSBzeW1ib2wpXG4gIFN0YXJ0LmpkID0gbmV3IFN0YXRlKFNZTSk7XG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IFN0YXJ0LFxuICAgIHRva2VuczogT2JqZWN0LmFzc2lnbih7XG4gICAgICBncm91cHNcbiAgICB9LCB0aylcbiAgfTtcbn1cblxuLyoqXG5cdEdpdmVuIGEgc3RyaW5nLCByZXR1cm5zIGFuIGFycmF5IG9mIFRPS0VOIGluc3RhbmNlcyByZXByZXNlbnRpbmcgdGhlXG5cdGNvbXBvc2l0aW9uIG9mIHRoYXQgc3RyaW5nLlxuXG5cdEBtZXRob2QgcnVuXG5cdEBwYXJhbSB7U3RhdGU8c3RyaW5nPn0gc3RhcnQgc2Nhbm5lciBzdGFydGluZyBzdGF0ZVxuXHRAcGFyYW0ge3N0cmluZ30gc3RyIGlucHV0IHN0cmluZyB0byBzY2FuXG5cdEByZXR1cm4ge1Rva2VuW119IGxpc3Qgb2YgdG9rZW5zLCBlYWNoIHdpdGggYSB0eXBlIGFuZCB2YWx1ZVxuKi9cbmZ1bmN0aW9uIHJ1biQxKHN0YXJ0LCBzdHIpIHtcbiAgLy8gU3RhdGUgbWFjaGluZSBpcyBub3QgY2FzZSBzZW5zaXRpdmUsIHNvIGlucHV0IGlzIHRva2VuaXplZCBpbiBsb3dlcmNhc2VkXG4gIC8vIGZvcm0gKHN0aWxsIHJldHVybnMgcmVndWxhciBjYXNlKS4gVXNlcyBzZWxlY3RpdmUgYHRvTG93ZXJDYXNlYCBiZWNhdXNlXG4gIC8vIGxvd2VyY2FzaW5nIHRoZSBlbnRpcmUgc3RyaW5nIGNhdXNlcyB0aGUgbGVuZ3RoIGFuZCBjaGFyYWN0ZXIgcG9zaXRpb24gdG9cbiAgLy8gdmFyeSBpbiBzb21lIG5vbi1FbmdsaXNoIHN0cmluZ3Mgd2l0aCBWOC1iYXNlZCBydW50aW1lcy5cbiAgY29uc3QgaXRlcmFibGUgPSBzdHJpbmdUb0FycmF5KHN0ci5yZXBsYWNlKC9bQS1aXS9nLCBjID0+IGMudG9Mb3dlckNhc2UoKSkpO1xuICBjb25zdCBjaGFyQ291bnQgPSBpdGVyYWJsZS5sZW5ndGg7IC8vIDw9IGxlbiBpZiB0aGVyZSBhcmUgZW1vamlzLCBldGNcbiAgY29uc3QgdG9rZW5zID0gW107IC8vIHJldHVybiB2YWx1ZVxuXG4gIC8vIGN1cnNvciB0aHJvdWdoIHRoZSBzdHJpbmcgaXRzZWxmLCBhY2NvdW50aW5nIGZvciBjaGFyYWN0ZXJzIHRoYXQgaGF2ZVxuICAvLyB3aWR0aCB3aXRoIGxlbmd0aCAyIHN1Y2ggYXMgZW1vamlzXG4gIGxldCBjdXJzb3IgPSAwO1xuXG4gIC8vIEN1cnNvciB0aHJvdWdoIHRoZSBhcnJheS1yZXByZXNlbnRhdGlvbiBvZiB0aGUgc3RyaW5nXG4gIGxldCBjaGFyQ3Vyc29yID0gMDtcblxuICAvLyBUb2tlbml6ZSB0aGUgc3RyaW5nXG4gIHdoaWxlIChjaGFyQ3Vyc29yIDwgY2hhckNvdW50KSB7XG4gICAgbGV0IHN0YXRlID0gc3RhcnQ7XG4gICAgbGV0IG5leHRTdGF0ZSA9IG51bGw7XG4gICAgbGV0IHRva2VuTGVuZ3RoID0gMDtcbiAgICBsZXQgbGF0ZXN0QWNjZXB0aW5nID0gbnVsbDtcbiAgICBsZXQgc2luY2VBY2NlcHRzID0gLTE7XG4gICAgbGV0IGNoYXJzU2luY2VBY2NlcHRzID0gLTE7XG4gICAgd2hpbGUgKGNoYXJDdXJzb3IgPCBjaGFyQ291bnQgJiYgKG5leHRTdGF0ZSA9IHN0YXRlLmdvKGl0ZXJhYmxlW2NoYXJDdXJzb3JdKSkpIHtcbiAgICAgIHN0YXRlID0gbmV4dFN0YXRlO1xuXG4gICAgICAvLyBLZWVwIHRyYWNrIG9mIHRoZSBsYXRlc3QgYWNjZXB0aW5nIHN0YXRlXG4gICAgICBpZiAoc3RhdGUuYWNjZXB0cygpKSB7XG4gICAgICAgIHNpbmNlQWNjZXB0cyA9IDA7XG4gICAgICAgIGNoYXJzU2luY2VBY2NlcHRzID0gMDtcbiAgICAgICAgbGF0ZXN0QWNjZXB0aW5nID0gc3RhdGU7XG4gICAgICB9IGVsc2UgaWYgKHNpbmNlQWNjZXB0cyA+PSAwKSB7XG4gICAgICAgIHNpbmNlQWNjZXB0cyArPSBpdGVyYWJsZVtjaGFyQ3Vyc29yXS5sZW5ndGg7XG4gICAgICAgIGNoYXJzU2luY2VBY2NlcHRzKys7XG4gICAgICB9XG4gICAgICB0b2tlbkxlbmd0aCArPSBpdGVyYWJsZVtjaGFyQ3Vyc29yXS5sZW5ndGg7XG4gICAgICBjdXJzb3IgKz0gaXRlcmFibGVbY2hhckN1cnNvcl0ubGVuZ3RoO1xuICAgICAgY2hhckN1cnNvcisrO1xuICAgIH1cblxuICAgIC8vIFJvbGwgYmFjayB0byB0aGUgbGF0ZXN0IGFjY2VwdGluZyBzdGF0ZVxuICAgIGN1cnNvciAtPSBzaW5jZUFjY2VwdHM7XG4gICAgY2hhckN1cnNvciAtPSBjaGFyc1NpbmNlQWNjZXB0cztcbiAgICB0b2tlbkxlbmd0aCAtPSBzaW5jZUFjY2VwdHM7XG5cbiAgICAvLyBObyBtb3JlIGp1bXBzLCBqdXN0IG1ha2UgYSBuZXcgdG9rZW4gZnJvbSB0aGUgbGFzdCBhY2NlcHRpbmcgb25lXG4gICAgdG9rZW5zLnB1c2goe1xuICAgICAgdDogbGF0ZXN0QWNjZXB0aW5nLnQsXG4gICAgICAvLyB0b2tlbiB0eXBlL25hbWVcbiAgICAgIHY6IHN0ci5zbGljZShjdXJzb3IgLSB0b2tlbkxlbmd0aCwgY3Vyc29yKSxcbiAgICAgIC8vIHN0cmluZyB2YWx1ZVxuICAgICAgczogY3Vyc29yIC0gdG9rZW5MZW5ndGgsXG4gICAgICAvLyBzdGFydCBpbmRleFxuICAgICAgZTogY3Vyc29yIC8vIGVuZCBpbmRleCAoZXhjbHVkaW5nKVxuICAgIH0pO1xuICB9XG4gIHJldHVybiB0b2tlbnM7XG59XG5cbi8qKlxuICogQ29udmVydCBhIFN0cmluZyB0byBhbiBBcnJheSBvZiBjaGFyYWN0ZXJzLCB0YWtpbmcgaW50byBhY2NvdW50IHRoYXQgc29tZVxuICogY2hhcmFjdGVycyBsaWtlIGVtb2ppcyB0YWtlIHVwIHR3byBzdHJpbmcgaW5kZXhlcy5cbiAqXG4gKiBBZGFwdGVkIGZyb20gY29yZS1qcyAoTUlUIGxpY2Vuc2UpXG4gKiBodHRwczovL2dpdGh1Yi5jb20vemxvaXJvY2svY29yZS1qcy9ibG9iLzJkNjljZjVmOTlhYjNlYTM0NjNjMzk1ZGY4MWU1YTE1YjY4ZjQ5ZDkvcGFja2FnZXMvY29yZS1qcy9pbnRlcm5hbHMvc3RyaW5nLW11bHRpYnl0ZS5qc1xuICpcbiAqIEBmdW5jdGlvbiBzdHJpbmdUb0FycmF5XG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gKiBAcmV0dXJucyB7c3RyaW5nW119XG4gKi9cbmZ1bmN0aW9uIHN0cmluZ1RvQXJyYXkoc3RyKSB7XG4gIGNvbnN0IHJlc3VsdCA9IFtdO1xuICBjb25zdCBsZW4gPSBzdHIubGVuZ3RoO1xuICBsZXQgaW5kZXggPSAwO1xuICB3aGlsZSAoaW5kZXggPCBsZW4pIHtcbiAgICBsZXQgZmlyc3QgPSBzdHIuY2hhckNvZGVBdChpbmRleCk7XG4gICAgbGV0IHNlY29uZDtcbiAgICBsZXQgY2hhciA9IGZpcnN0IDwgMHhkODAwIHx8IGZpcnN0ID4gMHhkYmZmIHx8IGluZGV4ICsgMSA9PT0gbGVuIHx8IChzZWNvbmQgPSBzdHIuY2hhckNvZGVBdChpbmRleCArIDEpKSA8IDB4ZGMwMCB8fCBzZWNvbmQgPiAweGRmZmYgPyBzdHJbaW5kZXhdIC8vIHNpbmdsZSBjaGFyYWN0ZXJcbiAgICA6IHN0ci5zbGljZShpbmRleCwgaW5kZXggKyAyKTsgLy8gdHdvLWluZGV4IGNoYXJhY3RlcnNcbiAgICByZXN1bHQucHVzaChjaGFyKTtcbiAgICBpbmRleCArPSBjaGFyLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG4vKipcbiAqIEZhc3QgdmVyc2lvbiBvZiB0cyBmdW5jdGlvbiBmb3Igd2hlbiB0cmFuc2l0aW9uIGRlZmF1bHRzIGFyZSB3ZWxsIGtub3duXG4gKiBAcGFyYW0ge1N0YXRlPHN0cmluZz59IHN0YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXRcbiAqIEBwYXJhbSB7c3RyaW5nfSB0XG4gKiBAcGFyYW0ge3N0cmluZ30gZGVmYXVsdHRcbiAqIEBwYXJhbSB7W1JlZ0V4cCwgU3RhdGU8c3RyaW5nPl1bXX0ganJcbiAqIEByZXR1cm5zIHtTdGF0ZTxzdHJpbmc+fVxuICovXG5mdW5jdGlvbiBmYXN0dHMoc3RhdGUsIGlucHV0LCB0LCBkZWZhdWx0dCwganIpIHtcbiAgbGV0IG5leHQ7XG4gIGNvbnN0IGxlbiA9IGlucHV0Lmxlbmd0aDtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBsZW4gLSAxOyBpKyspIHtcbiAgICBjb25zdCBjaGFyID0gaW5wdXRbaV07XG4gICAgaWYgKHN0YXRlLmpbY2hhcl0pIHtcbiAgICAgIG5leHQgPSBzdGF0ZS5qW2NoYXJdO1xuICAgIH0gZWxzZSB7XG4gICAgICBuZXh0ID0gbmV3IFN0YXRlKGRlZmF1bHR0KTtcbiAgICAgIG5leHQuanIgPSBqci5zbGljZSgpO1xuICAgICAgc3RhdGUualtjaGFyXSA9IG5leHQ7XG4gICAgfVxuICAgIHN0YXRlID0gbmV4dDtcbiAgfVxuICBuZXh0ID0gbmV3IFN0YXRlKHQpO1xuICBuZXh0LmpyID0ganIuc2xpY2UoKTtcbiAgc3RhdGUualtpbnB1dFtsZW4gLSAxXV0gPSBuZXh0O1xuICByZXR1cm4gbmV4dDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIHN0cmluZyBvZiBUb3AtTGV2ZWwgRG9tYWluIG5hbWVzIGVuY29kZWQgaW4gdXBkYXRlLXRsZHMuanMgYmFja1xuICogaW50byBhIGxpc3Qgb2Ygc3RyaW5ncy5cbiAqIEBwYXJhbSB7c3RyfSBlbmNvZGVkIGVuY29kZWQgVExEcyBzdHJpbmdcbiAqIEByZXR1cm5zIHtzdHJbXX0gb3JpZ2luYWwgVExEcyBsaXN0XG4gKi9cbmZ1bmN0aW9uIGRlY29kZVRsZHMoZW5jb2RlZCkge1xuICBjb25zdCB3b3JkcyA9IFtdO1xuICBjb25zdCBzdGFjayA9IFtdO1xuICBsZXQgaSA9IDA7XG4gIGxldCBkaWdpdHMgPSAnMDEyMzQ1Njc4OSc7XG4gIHdoaWxlIChpIDwgZW5jb2RlZC5sZW5ndGgpIHtcbiAgICBsZXQgcG9wRGlnaXRDb3VudCA9IDA7XG4gICAgd2hpbGUgKGRpZ2l0cy5pbmRleE9mKGVuY29kZWRbaSArIHBvcERpZ2l0Q291bnRdKSA+PSAwKSB7XG4gICAgICBwb3BEaWdpdENvdW50Kys7IC8vIGVuY291bnRlcmVkIHNvbWUgZGlnaXRzLCBoYXZlIHRvIHBvcCB0byBnbyBvbmUgbGV2ZWwgdXAgdHJpZVxuICAgIH1cbiAgICBpZiAocG9wRGlnaXRDb3VudCA+IDApIHtcbiAgICAgIHdvcmRzLnB1c2goc3RhY2suam9pbignJykpOyAvLyB3aGF0ZXZlciBwcmVjZWRlZCB0aGUgcG9wIGRpZ2l0cyBtdXN0IGJlIGEgd29yZFxuICAgICAgZm9yIChsZXQgcG9wQ291bnQgPSBwYXJzZUludChlbmNvZGVkLnN1YnN0cmluZyhpLCBpICsgcG9wRGlnaXRDb3VudCksIDEwKTsgcG9wQ291bnQgPiAwOyBwb3BDb3VudC0tKSB7XG4gICAgICAgIHN0YWNrLnBvcCgpO1xuICAgICAgfVxuICAgICAgaSArPSBwb3BEaWdpdENvdW50O1xuICAgIH0gZWxzZSB7XG4gICAgICBzdGFjay5wdXNoKGVuY29kZWRbaV0pOyAvLyBkcm9wIGRvd24gYSBsZXZlbCBpbnRvIHRoZSB0cmllXG4gICAgICBpKys7XG4gICAgfVxuICB9XG4gIHJldHVybiB3b3Jkcztcbn1cblxuLyoqXG4gKiBBbiBvYmplY3Qgd2hlcmUgZWFjaCBrZXkgaXMgYSB2YWxpZCBET00gRXZlbnQgTmFtZSBzdWNoIGFzIGBjbGlja2Agb3IgYGZvY3VzYFxuICogYW5kIGVhY2ggdmFsdWUgaXMgYW4gZXZlbnQgaGFuZGxlciBmdW5jdGlvbi5cbiAqXG4gKiBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvRWxlbWVudCNldmVudHNcbiAqIEB0eXBlZGVmIHs/eyBbZXZlbnQ6IHN0cmluZ106IEZ1bmN0aW9uIH19IEV2ZW50TGlzdGVuZXJzXG4gKi9cblxuLyoqXG4gKiBBbGwgZm9ybWF0dGVkIHByb3BlcnRpZXMgcmVxdWlyZWQgdG8gcmVuZGVyIGEgbGluaywgaW5jbHVkaW5nIGB0YWdOYW1lYCxcbiAqIGBhdHRyaWJ1dGVzYCwgYGNvbnRlbnRgIGFuZCBgZXZlbnRMaXN0ZW5lcnNgLlxuICogQHR5cGVkZWYge3sgdGFnTmFtZTogYW55LCBhdHRyaWJ1dGVzOiB7W2F0dHI6IHN0cmluZ106IGFueX0sIGNvbnRlbnQ6IHN0cmluZyxcbiAqIGV2ZW50TGlzdGVuZXJzOiBFdmVudExpc3RlbmVycyB9fSBJbnRlcm1lZGlhdGVSZXByZXNlbnRhdGlvblxuICovXG5cbi8qKlxuICogU3BlY2lmeSBlaXRoZXIgYW4gb2JqZWN0IGRlc2NyaWJlZCBieSB0aGUgdGVtcGxhdGUgdHlwZSBgT2Agb3IgYSBmdW5jdGlvbi5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gdGFrZXMgYSBzdHJpbmcgdmFsdWUgKHVzdWFsbHkgdGhlIGxpbmsncyBocmVmIGF0dHJpYnV0ZSksIHRoZVxuICogbGluayB0eXBlIChgJ3VybCdgLCBgJ2hhc2h0YWdgJywgZXRjLikgYW5kIGFuIGludGVybmFsIHRva2VuIHJlcHJlc2VudGF0aW9uXG4gKiBvZiB0aGUgbGluay4gSXQgc2hvdWxkIHJldHVybiBhbiBvYmplY3Qgb2YgdGhlIHRlbXBsYXRlIHR5cGUgYE9gXG4gKiBAdGVtcGxhdGUgT1xuICogQHR5cGVkZWYge08gfCAoKHZhbHVlOiBzdHJpbmcsIHR5cGU6IHN0cmluZywgdG9rZW46IE11bHRpVG9rZW4pID0+IE8pfSBPcHRPYmpcbiAqL1xuXG4vKipcbiAqIFNwZWNpZnkgZWl0aGVyIGEgZnVuY3Rpb24gZGVzY3JpYmVkIGJ5IHRlbXBsYXRlIHR5cGUgYEZgIG9yIGFuIG9iamVjdC5cbiAqXG4gKiBFYWNoIGtleSBpbiB0aGUgb2JqZWN0IHNob3VsZCBiZSBhIGxpbmsgdHlwZSAoYCd1cmwnYCwgYCdoYXNodGFnYCcsIGV0Yy4pLiBFYWNoXG4gKiB2YWx1ZSBzaG91bGQgYmUgYSBmdW5jdGlvbiB3aXRoIHRlbXBsYXRlIHR5cGUgYEZgIHRoYXQgaXMgY2FsbGVkIHdoZW4gdGhlXG4gKiBjb3JyZXNwb25kaW5nIGxpbmsgdHlwZSBpcyBlbmNvdW50ZXJlZC5cbiAqIEB0ZW1wbGF0ZSBGXG4gKiBAdHlwZWRlZiB7RiB8IHsgW3R5cGU6IHN0cmluZ106IEZ9fSBPcHRGblxuICovXG5cbi8qKlxuICogU3BlY2lmeSBlaXRoZXIgYSB2YWx1ZSB3aXRoIHRlbXBsYXRlIHR5cGUgYFZgLCBhIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBgVmAgb3JcbiAqIGFuIG9iamVjdCB3aGVyZSBlYWNoIHZhbHVlIHJlc29sdmVzIHRvIGBWYC5cbiAqXG4gKiBUaGUgZnVuY3Rpb24gdGFrZXMgYSBzdHJpbmcgdmFsdWUgKHVzdWFsbHkgdGhlIGxpbmsncyBocmVmIGF0dHJpYnV0ZSksIHRoZVxuICogbGluayB0eXBlIChgJ3VybCdgLCBgJ2hhc2h0YWdgJywgZXRjLikgYW5kIGFuIGludGVybmFsIHRva2VuIHJlcHJlc2VudGF0aW9uXG4gKiBvZiB0aGUgbGluay4gSXQgc2hvdWxkIHJldHVybiBhbiBvYmplY3Qgb2YgdGhlIHRlbXBsYXRlIHR5cGUgYFZgXG4gKlxuICogRm9yIHRoZSBvYmplY3QsIGVhY2gga2V5IHNob3VsZCBiZSBhIGxpbmsgdHlwZSAoYCd1cmwnYCwgYCdoYXNodGFnYCcsIGV0Yy4pLlxuICogRWFjaCB2YWx1ZSBzaG91bGQgZWl0aGVyIGhhdmUgdHlwZSBgVmAgb3IgYSBmdW5jdGlvbiB0aGF0IHJldHVybnMgVi4gVGhpc1xuICogZnVuY3Rpb24gc2ltaWxhcmx5IHRha2VzIGEgc3RyaW5nIHZhbHVlIGFuZCBhIHRva2VuLlxuICpcbiAqIEV4YW1wbGUgdmFsaWQgdHlwZXMgZm9yIGBPcHQ8c3RyaW5nPmA6XG4gKlxuICogYGBganNcbiAqICdoZWxsbydcbiAqICh2YWx1ZSwgdHlwZSwgdG9rZW4pID0+ICd3b3JsZCdcbiAqIHsgdXJsOiAnaGVsbG8nLCBlbWFpbDogKHZhbHVlLCB0b2tlbikgPT4gJ3dvcmxkJ31cbiAqIGBgYFxuICogQHRlbXBsYXRlIFZcbiAqIEB0eXBlZGVmIHtWIHwgKCh2YWx1ZTogc3RyaW5nLCB0eXBlOiBzdHJpbmcsIHRva2VuOiBNdWx0aVRva2VuKSA9PiBWKSB8IHsgW3R5cGU6IHN0cmluZ106IFYgfCAoKHZhbHVlOiBzdHJpbmcsIHRva2VuOiBNdWx0aVRva2VuKSA9PiBWKSB9fSBPcHRcbiAqL1xuXG4vKipcbiAqIFNlZSBhdmFpbGFibGUgb3B0aW9uczogaHR0cHM6Ly9saW5raWZ5LmpzLm9yZy9kb2NzL29wdGlvbnMuaHRtbFxuICogQHR5cGVkZWYge3tcbiAqIFx0ZGVmYXVsdFByb3RvY29sPzogc3RyaW5nLFxuICogIGV2ZW50cz86IE9wdE9iajxFdmVudExpc3RlbmVycz4sXG4gKiBcdGZvcm1hdD86IE9wdDxzdHJpbmc+LFxuICogXHRmb3JtYXRIcmVmPzogT3B0PHN0cmluZz4sXG4gKiBcdG5sMmJyPzogYm9vbGVhbixcbiAqIFx0dGFnTmFtZT86IE9wdDxhbnk+LFxuICogXHR0YXJnZXQ/OiBPcHQ8c3RyaW5nPixcbiAqIFx0cmVsPzogT3B0PHN0cmluZz4sXG4gKiBcdHZhbGlkYXRlPzogT3B0PGJvb2xlYW4+LFxuICogXHR0cnVuY2F0ZT86IE9wdDxudW1iZXI+LFxuICogXHRjbGFzc05hbWU/OiBPcHQ8c3RyaW5nPixcbiAqIFx0YXR0cmlidXRlcz86IE9wdE9iajwoeyBbYXR0cjogc3RyaW5nXTogYW55IH0pPixcbiAqICBpZ25vcmVUYWdzPzogc3RyaW5nW10sXG4gKiBcdHJlbmRlcj86IE9wdEZuPCgoaXI6IEludGVybWVkaWF0ZVJlcHJlc2VudGF0aW9uKSA9PiBhbnkpPlxuICogfX0gT3B0c1xuICovXG5cbi8qKlxuICogQHR5cGUgUmVxdWlyZWQ8T3B0cz5cbiAqL1xuY29uc3QgZGVmYXVsdHMgPSB7XG4gIGRlZmF1bHRQcm90b2NvbDogJ2h0dHAnLFxuICBldmVudHM6IG51bGwsXG4gIGZvcm1hdDogbm9vcCxcbiAgZm9ybWF0SHJlZjogbm9vcCxcbiAgbmwyYnI6IGZhbHNlLFxuICB0YWdOYW1lOiAnYScsXG4gIHRhcmdldDogbnVsbCxcbiAgcmVsOiBudWxsLFxuICB2YWxpZGF0ZTogdHJ1ZSxcbiAgdHJ1bmNhdGU6IEluZmluaXR5LFxuICBjbGFzc05hbWU6IG51bGwsXG4gIGF0dHJpYnV0ZXM6IG51bGwsXG4gIGlnbm9yZVRhZ3M6IFtdLFxuICByZW5kZXI6IG51bGxcbn07XG5cbi8qKlxuICogVXRpbGl0eSBjbGFzcyBmb3IgbGlua2lmeSBpbnRlcmZhY2VzIHRvIGFwcGx5IHNwZWNpZmllZFxuICoge0BsaW5rIE9wdHMgZm9ybWF0dGluZyBhbmQgcmVuZGVyaW5nIG9wdGlvbnN9LlxuICpcbiAqIEBwYXJhbSB7T3B0cyB8IE9wdGlvbnN9IFtvcHRzXSBPcHRpb24gdmFsdWUgb3ZlcnJpZGVzLlxuICogQHBhcmFtIHsoaXI6IEludGVybWVkaWF0ZVJlcHJlc2VudGF0aW9uKSA9PiBhbnl9IFtkZWZhdWx0UmVuZGVyXSAoRm9yXG4gKiAgIGludGVybmFsIHVzZSkgZGVmYXVsdCByZW5kZXIgZnVuY3Rpb24gdGhhdCBkZXRlcm1pbmVzIGhvdyB0byBnZW5lcmF0ZSBhblxuICogICBIVE1MIGVsZW1lbnQgYmFzZWQgb24gYSBsaW5rIHRva2VuJ3MgZGVyaXZlZCB0YWdOYW1lLCBhdHRyaWJ1dGVzIGFuZCBIVE1MLlxuICogICBTaW1pbGFyIHRvIHJlbmRlciBvcHRpb25cbiAqL1xuZnVuY3Rpb24gT3B0aW9ucyhvcHRzLCBkZWZhdWx0UmVuZGVyID0gbnVsbCkge1xuICBsZXQgbyA9IE9iamVjdC5hc3NpZ24oe30sIGRlZmF1bHRzKTtcbiAgaWYgKG9wdHMpIHtcbiAgICBvID0gT2JqZWN0LmFzc2lnbihvLCBvcHRzIGluc3RhbmNlb2YgT3B0aW9ucyA/IG9wdHMubyA6IG9wdHMpO1xuICB9XG5cbiAgLy8gRW5zdXJlIGFsbCBpZ25vcmVkIHRhZ3MgYXJlIHVwcGVyY2FzZVxuICBjb25zdCBpZ25vcmVkVGFncyA9IG8uaWdub3JlVGFncztcbiAgY29uc3QgdXBwZXJjYXNlSWdub3JlZFRhZ3MgPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBpZ25vcmVkVGFncy5sZW5ndGg7IGkrKykge1xuICAgIHVwcGVyY2FzZUlnbm9yZWRUYWdzLnB1c2goaWdub3JlZFRhZ3NbaV0udG9VcHBlckNhc2UoKSk7XG4gIH1cbiAgLyoqIEBwcm90ZWN0ZWQgKi9cbiAgdGhpcy5vID0gbztcbiAgaWYgKGRlZmF1bHRSZW5kZXIpIHtcbiAgICB0aGlzLmRlZmF1bHRSZW5kZXIgPSBkZWZhdWx0UmVuZGVyO1xuICB9XG4gIHRoaXMuaWdub3JlVGFncyA9IHVwcGVyY2FzZUlnbm9yZWRUYWdzO1xufVxuT3B0aW9ucy5wcm90b3R5cGUgPSB7XG4gIG86IGRlZmF1bHRzLFxuICAvKipcbiAgICogQHR5cGUgc3RyaW5nW11cbiAgICovXG4gIGlnbm9yZVRhZ3M6IFtdLFxuICAvKipcbiAgICogQHBhcmFtIHtJbnRlcm1lZGlhdGVSZXByZXNlbnRhdGlvbn0gaXJcbiAgICogQHJldHVybnMge2FueX1cbiAgICovXG4gIGRlZmF1bHRSZW5kZXIoaXIpIHtcbiAgICByZXR1cm4gaXI7XG4gIH0sXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRydWUgb3IgZmFsc2UgYmFzZWQgb24gd2hldGhlciBhIHRva2VuIHNob3VsZCBiZSBkaXNwbGF5ZWQgYXMgYVxuICAgKiBsaW5rIGJhc2VkIG9uIHRoZSB1c2VyIG9wdGlvbnMuXG4gICAqIEBwYXJhbSB7TXVsdGlUb2tlbn0gdG9rZW5cbiAgICogQHJldHVybnMge2Jvb2xlYW59XG4gICAqL1xuICBjaGVjayh0b2tlbikge1xuICAgIHJldHVybiB0aGlzLmdldCgndmFsaWRhdGUnLCB0b2tlbi50b1N0cmluZygpLCB0b2tlbik7XG4gIH0sXG4gIC8vIFByaXZhdGUgbWV0aG9kc1xuXG4gIC8qKlxuICAgKiBSZXNvbHZlIGFuIG9wdGlvbidzIHZhbHVlIGJhc2VkIG9uIHRoZSB2YWx1ZSBvZiB0aGUgb3B0aW9uIGFuZCB0aGUgZ2l2ZW5cbiAgICogcGFyYW1zLiBJZiBvcGVyYXRvciBhbmQgdG9rZW4gYXJlIHNwZWNpZmllZCBhbmQgdGhlIHRhcmdldCBvcHRpb24gaXNcbiAgICogY2FsbGFibGUsIGF1dG9tYXRpY2FsbHkgY2FsbHMgdGhlIGZ1bmN0aW9uIHdpdGggdGhlIGdpdmVuIGFyZ3VtZW50LlxuICAgKiBAdGVtcGxhdGUge2tleW9mIE9wdHN9IEtcbiAgICogQHBhcmFtIHtLfSBrZXkgTmFtZSBvZiBvcHRpb24gdG8gdXNlXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbb3BlcmF0b3JdIHdpbGwgYmUgcGFzc2VkIHRvIHRoZSB0YXJnZXQgb3B0aW9uIGlmIGl0J3MgYVxuICAgKiBmdW5jdGlvbi4gSWYgbm90IHNwZWNpZmllZCwgUkFXIGZ1bmN0aW9uIHZhbHVlIGdldHMgcmV0dXJuZWRcbiAgICogQHBhcmFtIHtNdWx0aVRva2VufSBbdG9rZW5dIFRoZSB0b2tlbiBmcm9tIGxpbmtpZnkudG9rZW5pemVcbiAgICogQHJldHVybnMge09wdHNbS10gfCBhbnl9XG4gICAqL1xuICBnZXQoa2V5LCBvcGVyYXRvciwgdG9rZW4pIHtcbiAgICBjb25zdCBpc0NhbGxhYmxlID0gb3BlcmF0b3IgIT0gbnVsbDtcbiAgICBsZXQgb3B0aW9uID0gdGhpcy5vW2tleV07XG4gICAgaWYgKCFvcHRpb24pIHtcbiAgICAgIHJldHVybiBvcHRpb247XG4gICAgfVxuICAgIGlmICh0eXBlb2Ygb3B0aW9uID09PSAnb2JqZWN0Jykge1xuICAgICAgb3B0aW9uID0gdG9rZW4udCBpbiBvcHRpb24gPyBvcHRpb25bdG9rZW4udF0gOiBkZWZhdWx0c1trZXldO1xuICAgICAgaWYgKHR5cGVvZiBvcHRpb24gPT09ICdmdW5jdGlvbicgJiYgaXNDYWxsYWJsZSkge1xuICAgICAgICBvcHRpb24gPSBvcHRpb24ob3BlcmF0b3IsIHRva2VuKTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBvcHRpb24gPT09ICdmdW5jdGlvbicgJiYgaXNDYWxsYWJsZSkge1xuICAgICAgb3B0aW9uID0gb3B0aW9uKG9wZXJhdG9yLCB0b2tlbi50LCB0b2tlbik7XG4gICAgfVxuICAgIHJldHVybiBvcHRpb247XG4gIH0sXG4gIC8qKlxuICAgKiBAdGVtcGxhdGUge2tleW9mIE9wdHN9IExcbiAgICogQHBhcmFtIHtMfSBrZXkgTmFtZSBvZiBvcHRpb25zIG9iamVjdCB0byB1c2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtvcGVyYXRvcl1cbiAgICogQHBhcmFtIHtNdWx0aVRva2VufSBbdG9rZW5dXG4gICAqIEByZXR1cm5zIHtPcHRzW0xdIHwgYW55fVxuICAgKi9cbiAgZ2V0T2JqKGtleSwgb3BlcmF0b3IsIHRva2VuKSB7XG4gICAgbGV0IG9iaiA9IHRoaXMub1trZXldO1xuICAgIGlmICh0eXBlb2Ygb2JqID09PSAnZnVuY3Rpb24nICYmIG9wZXJhdG9yICE9IG51bGwpIHtcbiAgICAgIG9iaiA9IG9iaihvcGVyYXRvciwgdG9rZW4udCwgdG9rZW4pO1xuICAgIH1cbiAgICByZXR1cm4gb2JqO1xuICB9LFxuICAvKipcbiAgICogQ29udmVydCB0aGUgZ2l2ZW4gdG9rZW4gdG8gYSByZW5kZXJlZCBlbGVtZW50IHRoYXQgbWF5IGJlIGFkZGVkIHRvIHRoZVxuICAgKiBjYWxsaW5nLWludGVyZmFjZSdzIERPTVxuICAgKiBAcGFyYW0ge011bHRpVG9rZW59IHRva2VuIFRva2VuIHRvIHJlbmRlciB0byBhbiBIVE1MIGVsZW1lbnRcbiAgICogQHJldHVybnMge2FueX0gUmVuZGVyIHJlc3VsdDsgZS5nLiwgSFRNTCBzdHJpbmcsIERPTSBlbGVtZW50LCBSZWFjdFxuICAgKiAgIENvbXBvbmVudCwgZXRjLlxuICAgKi9cbiAgcmVuZGVyKHRva2VuKSB7XG4gICAgY29uc3QgaXIgPSB0b2tlbi5yZW5kZXIodGhpcyk7IC8vIGludGVybWVkaWF0ZSByZXByZXNlbnRhdGlvblxuICAgIGNvbnN0IHJlbmRlckZuID0gdGhpcy5nZXQoJ3JlbmRlcicsIG51bGwsIHRva2VuKSB8fCB0aGlzLmRlZmF1bHRSZW5kZXI7XG4gICAgcmV0dXJuIHJlbmRlckZuKGlyLCB0b2tlbi50LCB0b2tlbik7XG4gIH1cbn07XG5mdW5jdGlvbiBub29wKHZhbCkge1xuICByZXR1cm4gdmFsO1xufVxuXG52YXIgb3B0aW9ucyA9IC8qI19fUFVSRV9fKi9PYmplY3QuZnJlZXplKHtcblx0X19wcm90b19fOiBudWxsLFxuXHRPcHRpb25zOiBPcHRpb25zLFxuXHRkZWZhdWx0czogZGVmYXVsdHNcbn0pO1xuXG4vKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG5cdE11bHRpLVRva2Vuc1xuXHRUb2tlbnMgY29tcG9zZWQgb2YgYXJyYXlzIG9mIFRleHRUb2tlbnNcbioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi9cblxuLyoqXG4gKiBAcGFyYW0ge3N0cmluZ30gdmFsdWVcbiAqIEBwYXJhbSB7VG9rZW5bXX0gdG9rZW5zXG4gKi9cbmZ1bmN0aW9uIE11bHRpVG9rZW4odmFsdWUsIHRva2Vucykge1xuICB0aGlzLnQgPSAndG9rZW4nO1xuICB0aGlzLnYgPSB2YWx1ZTtcbiAgdGhpcy50ayA9IHRva2Vucztcbn1cblxuLyoqXG4gKiBBYnN0cmFjdCBjbGFzcyB1c2VkIGZvciBtYW51ZmFjdHVyaW5nIHRva2VucyBvZiB0ZXh0IHRva2Vucy4gVGhhdCBpcyByYXRoZXJcbiAqIHRoYW4gdGhlIHZhbHVlIGZvciBhIHRva2VuIGJlaW5nIGEgc21hbGwgc3RyaW5nIG9mIHRleHQsIGl0J3MgdmFsdWUgYW4gYXJyYXlcbiAqIG9mIHRleHQgdG9rZW5zLlxuICpcbiAqIFVzZWQgZm9yIGdyb3VwaW5nIHRvZ2V0aGVyIFVSTHMsIGVtYWlscywgaGFzaHRhZ3MsIGFuZCBvdGhlciBwb3RlbnRpYWxcbiAqIGNyZWF0aW9ucy5cbiAqIEBjbGFzcyBNdWx0aVRva2VuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gdFxuICogQHByb3BlcnR5IHtzdHJpbmd9IHZcbiAqIEBwcm9wZXJ0eSB7VG9rZW5bXX0gdGtcbiAqIEBhYnN0cmFjdFxuICovXG5NdWx0aVRva2VuLnByb3RvdHlwZSA9IHtcbiAgaXNMaW5rOiBmYWxzZSxcbiAgLyoqXG4gICAqIFJldHVybiB0aGUgc3RyaW5nIHRoaXMgdG9rZW4gcmVwcmVzZW50cy5cbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIHRoaXMudjtcbiAgfSxcbiAgLyoqXG4gICAqIFdoYXQgc2hvdWxkIHRoZSB2YWx1ZSBmb3IgdGhpcyB0b2tlbiBiZSBpbiB0aGUgYGhyZWZgIEhUTUwgYXR0cmlidXRlP1xuICAgKiBSZXR1cm5zIHRoZSBgLnRvU3RyaW5nYCB2YWx1ZSBieSBkZWZhdWx0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW3NjaGVtZV1cbiAgICogQHJldHVybiB7c3RyaW5nfVxuICAgKi9cbiAgdG9IcmVmKHNjaGVtZSkge1xuICAgIHJldHVybiB0aGlzLnRvU3RyaW5nKCk7XG4gIH0sXG4gIC8qKlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgRm9ybWF0dGluZyBvcHRpb25zXG4gICAqIEByZXR1cm5zIHtzdHJpbmd9XG4gICAqL1xuICB0b0Zvcm1hdHRlZFN0cmluZyhvcHRpb25zKSB7XG4gICAgY29uc3QgdmFsID0gdGhpcy50b1N0cmluZygpO1xuICAgIGNvbnN0IHRydW5jYXRlID0gb3B0aW9ucy5nZXQoJ3RydW5jYXRlJywgdmFsLCB0aGlzKTtcbiAgICBjb25zdCBmb3JtYXR0ZWQgPSBvcHRpb25zLmdldCgnZm9ybWF0JywgdmFsLCB0aGlzKTtcbiAgICByZXR1cm4gdHJ1bmNhdGUgJiYgZm9ybWF0dGVkLmxlbmd0aCA+IHRydW5jYXRlID8gZm9ybWF0dGVkLnN1YnN0cmluZygwLCB0cnVuY2F0ZSkgKyAn4oCmJyA6IGZvcm1hdHRlZDtcbiAgfSxcbiAgLyoqXG4gICAqXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9uc1xuICAgKiBAcmV0dXJucyB7c3RyaW5nfVxuICAgKi9cbiAgdG9Gb3JtYXR0ZWRIcmVmKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gb3B0aW9ucy5nZXQoJ2Zvcm1hdEhyZWYnLCB0aGlzLnRvSHJlZihvcHRpb25zLmdldCgnZGVmYXVsdFByb3RvY29sJykpLCB0aGlzKTtcbiAgfSxcbiAgLyoqXG4gICAqIFRoZSBzdGFydCBpbmRleCBvZiB0aGlzIHRva2VuIGluIHRoZSBvcmlnaW5hbCBpbnB1dCBzdHJpbmdcbiAgICogQHJldHVybnMge251bWJlcn1cbiAgICovXG4gIHN0YXJ0SW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMudGtbMF0ucztcbiAgfSxcbiAgLyoqXG4gICAqIFRoZSBlbmQgaW5kZXggb2YgdGhpcyB0b2tlbiBpbiB0aGUgb3JpZ2luYWwgaW5wdXQgc3RyaW5nICh1cCB0byB0aGlzXG4gICAqIGluZGV4IGJ1dCBub3QgaW5jbHVkaW5nIGl0KVxuICAgKiBAcmV0dXJucyB7bnVtYmVyfVxuICAgKi9cbiAgZW5kSW5kZXgoKSB7XG4gICAgcmV0dXJuIHRoaXMudGtbdGhpcy50ay5sZW5ndGggLSAxXS5lO1xuICB9LFxuICAvKipcbiAgXHRSZXR1cm5zIGFuIG9iamVjdCAgb2YgcmVsZXZhbnQgdmFsdWVzIGZvciB0aGlzIHRva2VuLCB3aGljaCBpbmNsdWRlcyBrZXlzXG4gIFx0KiB0eXBlIC0gS2luZCBvZiB0b2tlbiAoJ3VybCcsICdlbWFpbCcsIGV0Yy4pXG4gIFx0KiB2YWx1ZSAtIE9yaWdpbmFsIHRleHRcbiAgXHQqIGhyZWYgLSBUaGUgdmFsdWUgdGhhdCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIGFuY2hvciB0YWcncyBocmVmXG4gIFx0XHRhdHRyaWJ1dGVcbiAgXHRcdEBtZXRob2QgdG9PYmplY3RcbiAgXHRAcGFyYW0ge3N0cmluZ30gW3Byb3RvY29sXSBgJ2h0dHAnYCBieSBkZWZhdWx0XG4gICovXG4gIHRvT2JqZWN0KHByb3RvY29sID0gZGVmYXVsdHMuZGVmYXVsdFByb3RvY29sKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHRoaXMudCxcbiAgICAgIHZhbHVlOiB0aGlzLnRvU3RyaW5nKCksXG4gICAgICBpc0xpbms6IHRoaXMuaXNMaW5rLFxuICAgICAgaHJlZjogdGhpcy50b0hyZWYocHJvdG9jb2wpLFxuICAgICAgc3RhcnQ6IHRoaXMuc3RhcnRJbmRleCgpLFxuICAgICAgZW5kOiB0aGlzLmVuZEluZGV4KClcbiAgICB9O1xuICB9LFxuICAvKipcbiAgICpcbiAgICogQHBhcmFtIHtPcHRpb25zfSBvcHRpb25zIEZvcm1hdHRpbmcgb3B0aW9uXG4gICAqL1xuICB0b0Zvcm1hdHRlZE9iamVjdChvcHRpb25zKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IHRoaXMudCxcbiAgICAgIHZhbHVlOiB0aGlzLnRvRm9ybWF0dGVkU3RyaW5nKG9wdGlvbnMpLFxuICAgICAgaXNMaW5rOiB0aGlzLmlzTGluayxcbiAgICAgIGhyZWY6IHRoaXMudG9Gb3JtYXR0ZWRIcmVmKG9wdGlvbnMpLFxuICAgICAgc3RhcnQ6IHRoaXMuc3RhcnRJbmRleCgpLFxuICAgICAgZW5kOiB0aGlzLmVuZEluZGV4KClcbiAgICB9O1xuICB9LFxuICAvKipcbiAgICogV2hldGhlciB0aGlzIHRva2VuIHNob3VsZCBiZSByZW5kZXJlZCBhcyBhIGxpbmsgYWNjb3JkaW5nIHRvIHRoZSBnaXZlbiBvcHRpb25zXG4gICAqIEBwYXJhbSB7T3B0aW9uc30gb3B0aW9uc1xuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn1cbiAgICovXG4gIHZhbGlkYXRlKG9wdGlvbnMpIHtcbiAgICByZXR1cm4gb3B0aW9ucy5nZXQoJ3ZhbGlkYXRlJywgdGhpcy50b1N0cmluZygpLCB0aGlzKTtcbiAgfSxcbiAgLyoqXG4gICAqIFJldHVybiBhbiBvYmplY3QgdGhhdCByZXByZXNlbnRzIGhvdyB0aGlzIGxpbmsgc2hvdWxkIGJlIHJlbmRlcmVkLlxuICAgKiBAcGFyYW0ge09wdGlvbnN9IG9wdGlvbnMgRm9ybWF0dGlubmcgb3B0aW9uc1xuICAgKi9cbiAgcmVuZGVyKG9wdGlvbnMpIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXM7XG4gICAgY29uc3QgaHJlZiA9IHRoaXMudG9IcmVmKG9wdGlvbnMuZ2V0KCdkZWZhdWx0UHJvdG9jb2wnKSk7XG4gICAgY29uc3QgZm9ybWF0dGVkSHJlZiA9IG9wdGlvbnMuZ2V0KCdmb3JtYXRIcmVmJywgaHJlZiwgdGhpcyk7XG4gICAgY29uc3QgdGFnTmFtZSA9IG9wdGlvbnMuZ2V0KCd0YWdOYW1lJywgaHJlZiwgdG9rZW4pO1xuICAgIGNvbnN0IGNvbnRlbnQgPSB0aGlzLnRvRm9ybWF0dGVkU3RyaW5nKG9wdGlvbnMpO1xuICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSB7fTtcbiAgICBjb25zdCBjbGFzc05hbWUgPSBvcHRpb25zLmdldCgnY2xhc3NOYW1lJywgaHJlZiwgdG9rZW4pO1xuICAgIGNvbnN0IHRhcmdldCA9IG9wdGlvbnMuZ2V0KCd0YXJnZXQnLCBocmVmLCB0b2tlbik7XG4gICAgY29uc3QgcmVsID0gb3B0aW9ucy5nZXQoJ3JlbCcsIGhyZWYsIHRva2VuKTtcbiAgICBjb25zdCBhdHRycyA9IG9wdGlvbnMuZ2V0T2JqKCdhdHRyaWJ1dGVzJywgaHJlZiwgdG9rZW4pO1xuICAgIGNvbnN0IGV2ZW50TGlzdGVuZXJzID0gb3B0aW9ucy5nZXRPYmooJ2V2ZW50cycsIGhyZWYsIHRva2VuKTtcbiAgICBhdHRyaWJ1dGVzLmhyZWYgPSBmb3JtYXR0ZWRIcmVmO1xuICAgIGlmIChjbGFzc05hbWUpIHtcbiAgICAgIGF0dHJpYnV0ZXMuY2xhc3MgPSBjbGFzc05hbWU7XG4gICAgfVxuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgIGF0dHJpYnV0ZXMudGFyZ2V0ID0gdGFyZ2V0O1xuICAgIH1cbiAgICBpZiAocmVsKSB7XG4gICAgICBhdHRyaWJ1dGVzLnJlbCA9IHJlbDtcbiAgICB9XG4gICAgaWYgKGF0dHJzKSB7XG4gICAgICBPYmplY3QuYXNzaWduKGF0dHJpYnV0ZXMsIGF0dHJzKTtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIHRhZ05hbWUsXG4gICAgICBhdHRyaWJ1dGVzLFxuICAgICAgY29udGVudCxcbiAgICAgIGV2ZW50TGlzdGVuZXJzXG4gICAgfTtcbiAgfVxufTtcblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgdG9rZW4gdGhhdCBjYW4gYmUgZW1pdHRlZCBieSB0aGUgcGFyc2VyIHN0YXRlIG1hY2hpbmVcbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIHJlYWRhYmxlIHR5cGUgb2YgdGhlIHRva2VuXG4gKiBAcGFyYW0ge29iamVjdH0gcHJvcHMgcHJvcGVydGllcyB0byBhc3NpZ24gb3Igb3ZlcnJpZGUsIGluY2x1ZGluZyBpc0xpbmsgPSB0cnVlIG9yIGZhbHNlXG4gKiBAcmV0dXJucyB7bmV3ICh2YWx1ZTogc3RyaW5nLCB0b2tlbnM6IFRva2VuW10pID0+IE11bHRpVG9rZW59IG5ldyB0b2tlbiBjbGFzc1xuICovXG5mdW5jdGlvbiBjcmVhdGVUb2tlbkNsYXNzKHR5cGUsIHByb3BzKSB7XG4gIGNsYXNzIFRva2VuIGV4dGVuZHMgTXVsdGlUb2tlbiB7XG4gICAgY29uc3RydWN0b3IodmFsdWUsIHRva2Vucykge1xuICAgICAgc3VwZXIodmFsdWUsIHRva2Vucyk7XG4gICAgICB0aGlzLnQgPSB0eXBlO1xuICAgIH1cbiAgfVxuICBmb3IgKGNvbnN0IHAgaW4gcHJvcHMpIHtcbiAgICBUb2tlbi5wcm90b3R5cGVbcF0gPSBwcm9wc1twXTtcbiAgfVxuICBUb2tlbi50ID0gdHlwZTtcbiAgcmV0dXJuIFRva2VuO1xufVxuXG4vKipcblx0UmVwcmVzZW50cyBhIGxpc3Qgb2YgdG9rZW5zIG1ha2luZyB1cCBhIHZhbGlkIGVtYWlsIGFkZHJlc3NcbiovXG5jb25zdCBFbWFpbCA9IGNyZWF0ZVRva2VuQ2xhc3MoJ2VtYWlsJywge1xuICBpc0xpbms6IHRydWUsXG4gIHRvSHJlZigpIHtcbiAgICByZXR1cm4gJ21haWx0bzonICsgdGhpcy50b1N0cmluZygpO1xuICB9XG59KTtcblxuLyoqXG5cdFJlcHJlc2VudHMgc29tZSBwbGFpbiB0ZXh0XG4qL1xuY29uc3QgVGV4dCA9IGNyZWF0ZVRva2VuQ2xhc3MoJ3RleHQnKTtcblxuLyoqXG5cdE11bHRpLWxpbmVicmVhayB0b2tlbiAtIHJlcHJlc2VudHMgYSBsaW5lIGJyZWFrXG5cdEBjbGFzcyBObFxuKi9cbmNvbnN0IE5sID0gY3JlYXRlVG9rZW5DbGFzcygnbmwnKTtcblxuLyoqXG5cdFJlcHJlc2VudHMgYSBsaXN0IG9mIHRleHQgdG9rZW5zIG1ha2luZyB1cCBhIHZhbGlkIFVSTFxuXHRAY2xhc3MgVXJsXG4qL1xuY29uc3QgVXJsID0gY3JlYXRlVG9rZW5DbGFzcygndXJsJywge1xuICBpc0xpbms6IHRydWUsXG4gIC8qKlxuICBcdExvd2VyY2FzZXMgcmVsZXZhbnQgcGFydHMgb2YgdGhlIGRvbWFpbiBhbmQgYWRkcyB0aGUgcHJvdG9jb2wgaWZcbiAgXHRyZXF1aXJlZC4gTm90ZSB0aGF0IHRoaXMgd2lsbCBub3QgZXNjYXBlIHVuc2FmZSBIVE1MIGNoYXJhY3RlcnMgaW4gdGhlXG4gIFx0VVJMLlxuICBcdFx0QHBhcmFtIHtzdHJpbmd9IFtzY2hlbWVdIGRlZmF1bHQgc2NoZW1lIChlLmcuLCAnaHR0cHMnKVxuICBcdEByZXR1cm4ge3N0cmluZ30gdGhlIGZ1bGwgaHJlZlxuICAqL1xuICB0b0hyZWYoc2NoZW1lID0gZGVmYXVsdHMuZGVmYXVsdFByb3RvY29sKSB7XG4gICAgLy8gQ2hlY2sgaWYgYWxyZWFkeSBoYXMgYSBwcmVmaXggc2NoZW1lXG4gICAgcmV0dXJuIHRoaXMuaGFzUHJvdG9jb2woKSA/IHRoaXMudiA6IGAke3NjaGVtZX06Ly8ke3RoaXMudn1gO1xuICB9LFxuICAvKipcbiAgICogQ2hlY2sgd2hldGhlciB0aGlzIFVSTCB0b2tlbiBoYXMgYSBwcm90b2NvbFxuICAgKiBAcmV0dXJuIHtib29sZWFufVxuICAgKi9cbiAgaGFzUHJvdG9jb2woKSB7XG4gICAgY29uc3QgdG9rZW5zID0gdGhpcy50aztcbiAgICByZXR1cm4gdG9rZW5zLmxlbmd0aCA+PSAyICYmIHRva2Vuc1swXS50ICE9PSBMT0NBTEhPU1QgJiYgdG9rZW5zWzFdLnQgPT09IENPTE9OO1xuICB9XG59KTtcblxudmFyIG11bHRpID0gLyojX19QVVJFX18qL09iamVjdC5mcmVlemUoe1xuXHRfX3Byb3RvX186IG51bGwsXG5cdEJhc2U6IE11bHRpVG9rZW4sXG5cdEVtYWlsOiBFbWFpbCxcblx0TXVsdGlUb2tlbjogTXVsdGlUb2tlbixcblx0Tmw6IE5sLFxuXHRUZXh0OiBUZXh0LFxuXHRVcmw6IFVybCxcblx0Y3JlYXRlVG9rZW5DbGFzczogY3JlYXRlVG9rZW5DbGFzc1xufSk7XG5cbi8qKlxuXHROb3QgZXhhY3RseSBwYXJzZXIsIG1vcmUgbGlrZSB0aGUgc2Vjb25kLXN0YWdlIHNjYW5uZXIgKGFsdGhvdWdoIHdlIGNhblxuXHR0aGVvcmV0aWNhbGx5IGhvdHN3YXAgdGhlIGNvZGUgaGVyZSB3aXRoIGEgcmVhbCBwYXJzZXIgaW4gdGhlIGZ1dHVyZS4uLiBidXRcblx0Zm9yIGEgbGl0dGxlIFVSTC1maW5kaW5nIHV0aWxpdHkgYWJzdHJhY3Qgc3ludGF4IHRyZWVzIG1heSBiZSBhIGxpdHRsZVxuXHRvdmVya2lsbCkuXG5cblx0VVJMIGZvcm1hdDogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9VUklfc2NoZW1lXG5cdEVtYWlsIGZvcm1hdDogaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9FbWFpbEFkZHJlc3MgKGxpbmtzIHRvIFJGQyBpblxuXHRyZWZlcmVuY2UpXG5cblx0QG1vZHVsZSBsaW5raWZ5XG5cdEBzdWJtb2R1bGUgcGFyc2VyXG5cdEBtYWluIHJ1blxuKi9cblxuY29uc3QgbWFrZVN0YXRlID0gYXJnID0+IG5ldyBTdGF0ZShhcmcpO1xuXG4vKipcbiAqIEdlbmVyYXRlIHRoZSBwYXJzZXIgbXVsdGkgdG9rZW4tYmFzZWQgc3RhdGUgbWFjaGluZVxuICogQHBhcmFtIHt7IGdyb3VwczogQ29sbGVjdGlvbnM8c3RyaW5nPiB9fSB0b2tlbnNcbiAqL1xuZnVuY3Rpb24gaW5pdCQxKHtcbiAgZ3JvdXBzXG59KSB7XG4gIC8vIFR5cGVzIG9mIGNoYXJhY3RlcnMgdGhlIFVSTCBjYW4gZGVmaW5pdGVseSBlbmQgaW5cbiAgY29uc3QgcXNBY2NlcHRpbmcgPSBncm91cHMuZG9tYWluLmNvbmNhdChbQU1QRVJTQU5ELCBBU1RFUklTSywgQVQsIEJBQ0tTTEFTSCwgQkFDS1RJQ0ssIENBUkVULCBET0xMQVIsIEVRVUFMUywgSFlQSEVOLCBOVU0sIFBFUkNFTlQsIFBJUEUsIFBMVVMsIFBPVU5ELCBTTEFTSCwgU1lNLCBUSUxERSwgVU5ERVJTQ09SRV0pO1xuXG4gIC8vIFR5cGVzIG9mIHRva2VucyB0aGF0IGNhbiBmb2xsb3cgYSBVUkwgYW5kIGJlIHBhcnQgb2YgdGhlIHF1ZXJ5IHN0cmluZ1xuICAvLyBidXQgY2Fubm90IGJlIHRoZSB2ZXJ5IGxhc3QgY2hhcmFjdGVyc1xuICAvLyBDaGFyYWN0ZXJzIHRoYXQgY2Fubm90IGFwcGVhciBpbiB0aGUgVVJMIGF0IGFsbCBzaG91bGQgYmUgZXhjbHVkZWRcbiAgY29uc3QgcXNOb25BY2NlcHRpbmcgPSBbQVBPU1RST1BIRSwgQ09MT04sIENPTU1BLCBET1QsIEVYQ0xBTUFUSU9OLCBQRVJDRU5ULCBRVUVSWSwgUVVPVEUsIFNFTUksIE9QRU5BTkdMRUJSQUNLRVQsIENMT1NFQU5HTEVCUkFDS0VULCBPUEVOQlJBQ0UsIENMT1NFQlJBQ0UsIENMT1NFQlJBQ0tFVCwgT1BFTkJSQUNLRVQsIE9QRU5QQVJFTiwgQ0xPU0VQQVJFTiwgRlVMTFdJRFRITEVGVFBBUkVOLCBGVUxMV0lEVEhSSUdIVFBBUkVOLCBMRUZUQ09STkVSQlJBQ0tFVCwgUklHSFRDT1JORVJCUkFDS0VULCBMRUZUV0hJVEVDT1JORVJCUkFDS0VULCBSSUdIVFdISVRFQ09STkVSQlJBQ0tFVCwgRlVMTFdJRFRITEVTU1RIQU4sIEZVTExXSURUSEdSRUFURVJUSEFOXTtcblxuICAvLyBGb3IgYWRkcmVzc2VzIHdpdGhvdXQgdGhlIG1haWx0byBwcmVmaXhcbiAgLy8gVG9rZW5zIGFsbG93ZWQgaW4gdGhlIGxvY2FscGFydCBvZiB0aGUgZW1haWxcbiAgY29uc3QgbG9jYWxwYXJ0QWNjZXB0aW5nID0gW0FNUEVSU0FORCwgQVBPU1RST1BIRSwgQVNURVJJU0ssIEJBQ0tTTEFTSCwgQkFDS1RJQ0ssIENBUkVULCBET0xMQVIsIEVRVUFMUywgSFlQSEVOLCBPUEVOQlJBQ0UsIENMT1NFQlJBQ0UsIFBFUkNFTlQsIFBJUEUsIFBMVVMsIFBPVU5ELCBRVUVSWSwgU0xBU0gsIFNZTSwgVElMREUsIFVOREVSU0NPUkVdO1xuXG4gIC8vIFRoZSB1bml2ZXJzYWwgc3RhcnRpbmcgc3RhdGUuXG4gIC8qKlxuICAgKiBAdHlwZSBTdGF0ZTxUb2tlbj5cbiAgICovXG4gIGNvbnN0IFN0YXJ0ID0gbWFrZVN0YXRlKCk7XG4gIGNvbnN0IExvY2FscGFydCA9IHR0KFN0YXJ0LCBUSUxERSk7IC8vIExvY2FsIHBhcnQgb2YgdGhlIGVtYWlsIGFkZHJlc3NcbiAgdGEoTG9jYWxwYXJ0LCBsb2NhbHBhcnRBY2NlcHRpbmcsIExvY2FscGFydCk7XG4gIHRhKExvY2FscGFydCwgZ3JvdXBzLmRvbWFpbiwgTG9jYWxwYXJ0KTtcbiAgY29uc3QgRG9tYWluID0gbWFrZVN0YXRlKCksXG4gICAgU2NoZW1lID0gbWFrZVN0YXRlKCksXG4gICAgU2xhc2hTY2hlbWUgPSBtYWtlU3RhdGUoKTtcbiAgdGEoU3RhcnQsIGdyb3Vwcy5kb21haW4sIERvbWFpbik7IC8vIHBhcnNlZCBzdHJpbmcgZW5kcyB3aXRoIGEgcG90ZW50aWFsIGRvbWFpbiBuYW1lIChBKVxuICB0YShTdGFydCwgZ3JvdXBzLnNjaGVtZSwgU2NoZW1lKTsgLy8gZS5nLiwgJ21haWx0bydcbiAgdGEoU3RhcnQsIGdyb3Vwcy5zbGFzaHNjaGVtZSwgU2xhc2hTY2hlbWUpOyAvLyBlLmcuLCAnaHR0cCdcblxuICB0YShEb21haW4sIGxvY2FscGFydEFjY2VwdGluZywgTG9jYWxwYXJ0KTtcbiAgdGEoRG9tYWluLCBncm91cHMuZG9tYWluLCBEb21haW4pO1xuICBjb25zdCBMb2NhbHBhcnRBdCA9IHR0KERvbWFpbiwgQVQpOyAvLyBMb2NhbCBwYXJ0IG9mIHRoZSBlbWFpbCBhZGRyZXNzIHBsdXMgQFxuXG4gIHR0KExvY2FscGFydCwgQVQsIExvY2FscGFydEF0KTsgLy8gY2xvc2UgdG8gYW4gZW1haWwgYWRkcmVzcyBub3dcblxuICAvLyBMb2NhbCBwYXJ0IG9mIGFuIGVtYWlsIGFkZHJlc3MgY2FuIGJlIGUuZy4gJ2h0dHAnIG9yICdtYWlsdG8nXG4gIHR0KFNjaGVtZSwgQVQsIExvY2FscGFydEF0KTtcbiAgdHQoU2xhc2hTY2hlbWUsIEFULCBMb2NhbHBhcnRBdCk7XG4gIGNvbnN0IExvY2FscGFydERvdCA9IHR0KExvY2FscGFydCwgRE9UKTsgLy8gTG9jYWwgcGFydCBvZiB0aGUgZW1haWwgYWRkcmVzcyBwbHVzICcuJyAobG9jYWxwYXJ0IGNhbm5vdCBlbmQgaW4gLilcbiAgdGEoTG9jYWxwYXJ0RG90LCBsb2NhbHBhcnRBY2NlcHRpbmcsIExvY2FscGFydCk7XG4gIHRhKExvY2FscGFydERvdCwgZ3JvdXBzLmRvbWFpbiwgTG9jYWxwYXJ0KTtcbiAgY29uc3QgRW1haWxEb21haW4gPSBtYWtlU3RhdGUoKTtcbiAgdGEoTG9jYWxwYXJ0QXQsIGdyb3Vwcy5kb21haW4sIEVtYWlsRG9tYWluKTsgLy8gcGFyc2VkIHN0cmluZyBzdGFydHMgd2l0aCBsb2NhbCBlbWFpbCBpbmZvICsgQCB3aXRoIGEgcG90ZW50aWFsIGRvbWFpbiBuYW1lXG4gIHRhKEVtYWlsRG9tYWluLCBncm91cHMuZG9tYWluLCBFbWFpbERvbWFpbik7XG4gIGNvbnN0IEVtYWlsRG9tYWluRG90ID0gdHQoRW1haWxEb21haW4sIERPVCk7IC8vIGRvbWFpbiBmb2xsb3dlZCBieSBET1RcbiAgdGEoRW1haWxEb21haW5Eb3QsIGdyb3Vwcy5kb21haW4sIEVtYWlsRG9tYWluKTtcbiAgY29uc3QgRW1haWwkMSA9IG1ha2VTdGF0ZShFbWFpbCk7IC8vIFBvc3NpYmxlIGVtYWlsIGFkZHJlc3MgKGNvdWxkIGhhdmUgbW9yZSB0bGRzKVxuICB0YShFbWFpbERvbWFpbkRvdCwgZ3JvdXBzLnRsZCwgRW1haWwkMSk7XG4gIHRhKEVtYWlsRG9tYWluRG90LCBncm91cHMudXRsZCwgRW1haWwkMSk7XG4gIHR0KExvY2FscGFydEF0LCBMT0NBTEhPU1QsIEVtYWlsJDEpO1xuXG4gIC8vIEh5cGhlbiBjYW4ganVtcCBiYWNrIHRvIGEgZG9tYWluIG5hbWVcbiAgY29uc3QgRW1haWxEb21haW5IeXBoZW4gPSB0dChFbWFpbERvbWFpbiwgSFlQSEVOKTsgLy8gcGFyc2VkIHN0cmluZyBzdGFydHMgd2l0aCBsb2NhbCBlbWFpbCBpbmZvICsgQCB3aXRoIGEgcG90ZW50aWFsIGRvbWFpbiBuYW1lXG4gIHR0KEVtYWlsRG9tYWluSHlwaGVuLCBIWVBIRU4sIEVtYWlsRG9tYWluSHlwaGVuKTtcbiAgdGEoRW1haWxEb21haW5IeXBoZW4sIGdyb3Vwcy5kb21haW4sIEVtYWlsRG9tYWluKTtcbiAgdGEoRW1haWwkMSwgZ3JvdXBzLmRvbWFpbiwgRW1haWxEb21haW4pO1xuICB0dChFbWFpbCQxLCBET1QsIEVtYWlsRG9tYWluRG90KTtcbiAgdHQoRW1haWwkMSwgSFlQSEVOLCBFbWFpbERvbWFpbkh5cGhlbik7XG5cbiAgLy8gRmluYWwgcG9zc2libGUgZW1haWwgc3RhdGVzXG4gIGNvbnN0IEVtYWlsQ29sb24gPSB0dChFbWFpbCQxLCBDT0xPTik7IC8vIFVSTCBmb2xsb3dlZCBieSBjb2xvbiAocG90ZW50aWFsIHBvcnQgbnVtYmVyIGhlcmUpXG4gIC8qY29uc3QgRW1haWxDb2xvblBvcnQgPSAqL1xuICB0YShFbWFpbENvbG9uLCBncm91cHMubnVtZXJpYywgRW1haWwpOyAvLyBVUkwgZm9sbG93ZWQgYnkgY29sb24gYW5kIHBvcnQgbnVtYmVyXG5cbiAgLy8gQWNjb3VudCBmb3IgZG90cyBhbmQgaHlwaGVucy4gSHlwaGVucyBhcmUgdXN1YWxseSBwYXJ0cyBvZiBkb21haW4gbmFtZXNcbiAgLy8gKGJ1dCBub3QgVExEcylcbiAgY29uc3QgRG9tYWluSHlwaGVuID0gdHQoRG9tYWluLCBIWVBIRU4pOyAvLyBkb21haW4gZm9sbG93ZWQgYnkgaHlwaGVuXG4gIGNvbnN0IERvbWFpbkRvdCA9IHR0KERvbWFpbiwgRE9UKTsgLy8gZG9tYWluIGZvbGxvd2VkIGJ5IERPVFxuICB0dChEb21haW5IeXBoZW4sIEhZUEhFTiwgRG9tYWluSHlwaGVuKTtcbiAgdGEoRG9tYWluSHlwaGVuLCBncm91cHMuZG9tYWluLCBEb21haW4pO1xuICB0YShEb21haW5Eb3QsIGxvY2FscGFydEFjY2VwdGluZywgTG9jYWxwYXJ0KTtcbiAgdGEoRG9tYWluRG90LCBncm91cHMuZG9tYWluLCBEb21haW4pO1xuICBjb25zdCBEb21haW5Eb3RUbGQgPSBtYWtlU3RhdGUoVXJsKTsgLy8gU2ltcGxlc3QgcG9zc2libGUgVVJMIHdpdGggbm8gcXVlcnkgc3RyaW5nXG4gIHRhKERvbWFpbkRvdCwgZ3JvdXBzLnRsZCwgRG9tYWluRG90VGxkKTtcbiAgdGEoRG9tYWluRG90LCBncm91cHMudXRsZCwgRG9tYWluRG90VGxkKTtcbiAgdGEoRG9tYWluRG90VGxkLCBncm91cHMuZG9tYWluLCBEb21haW4pO1xuICB0YShEb21haW5Eb3RUbGQsIGxvY2FscGFydEFjY2VwdGluZywgTG9jYWxwYXJ0KTtcbiAgdHQoRG9tYWluRG90VGxkLCBET1QsIERvbWFpbkRvdCk7XG4gIHR0KERvbWFpbkRvdFRsZCwgSFlQSEVOLCBEb21haW5IeXBoZW4pO1xuICB0dChEb21haW5Eb3RUbGQsIEFULCBMb2NhbHBhcnRBdCk7XG4gIGNvbnN0IERvbWFpbkRvdFRsZENvbG9uID0gdHQoRG9tYWluRG90VGxkLCBDT0xPTik7IC8vIFVSTCBmb2xsb3dlZCBieSBjb2xvbiAocG90ZW50aWFsIHBvcnQgbnVtYmVyIGhlcmUpXG4gIGNvbnN0IERvbWFpbkRvdFRsZENvbG9uUG9ydCA9IG1ha2VTdGF0ZShVcmwpOyAvLyBUTEQgZm9sbG93ZWQgYnkgYSBwb3J0IG51bWJlclxuICB0YShEb21haW5Eb3RUbGRDb2xvbiwgZ3JvdXBzLm51bWVyaWMsIERvbWFpbkRvdFRsZENvbG9uUG9ydCk7XG5cbiAgLy8gTG9uZyBVUkwgd2l0aCBvcHRpb25hbCBwb3J0IGFuZCBtYXliZSBxdWVyeSBzdHJpbmdcbiAgY29uc3QgVXJsJDEgPSBtYWtlU3RhdGUoVXJsKTtcblxuICAvLyBVUkwgd2l0aCBleHRyYSBzeW1ib2xzIGF0IHRoZSBlbmQsIGZvbGxvd2VkIGJ5IGFuIG9wZW5pbmcgYnJhY2tldFxuICBjb25zdCBVcmxOb25hY2NlcHQgPSBtYWtlU3RhdGUoKTsgLy8gVVJMIGZvbGxvd2VkIGJ5IHNvbWUgc3ltYm9scyAod2lsbCBub3QgYmUgcGFydCBvZiB0aGUgZmluYWwgVVJMKVxuXG4gIC8vIFF1ZXJ5IHN0cmluZ3NcbiAgdGEoVXJsJDEsIHFzQWNjZXB0aW5nLCBVcmwkMSk7XG4gIHRhKFVybCQxLCBxc05vbkFjY2VwdGluZywgVXJsTm9uYWNjZXB0KTtcbiAgdGEoVXJsTm9uYWNjZXB0LCBxc0FjY2VwdGluZywgVXJsJDEpO1xuICB0YShVcmxOb25hY2NlcHQsIHFzTm9uQWNjZXB0aW5nLCBVcmxOb25hY2NlcHQpO1xuXG4gIC8vIEJlY29tZSByZWFsIFVSTHMgYWZ0ZXIgYFNMQVNIYCBvciBgQ09MT04gTlVNIFNMQVNIYFxuICAvLyBIZXJlIHdvcmtzIHdpdGggb3Igd2l0aG91dCBzY2hlbWU6Ly8gcHJlZml4XG4gIHR0KERvbWFpbkRvdFRsZCwgU0xBU0gsIFVybCQxKTtcbiAgdHQoRG9tYWluRG90VGxkQ29sb25Qb3J0LCBTTEFTSCwgVXJsJDEpO1xuXG4gIC8vIE5vdGUgdGhhdCBkb21haW5zIHRoYXQgYmVnaW4gd2l0aCBzY2hlbWVzIGFyZSB0cmVhdGVkIHNsaWdobHkgZGlmZmVyZW50bHlcbiAgY29uc3QgU2NoZW1lQ29sb24gPSB0dChTY2hlbWUsIENPTE9OKTsgLy8gZS5nLiwgJ21haWx0bzonXG4gIGNvbnN0IFNsYXNoU2NoZW1lQ29sb24gPSB0dChTbGFzaFNjaGVtZSwgQ09MT04pOyAvLyBlLmcuLCAnaHR0cDonXG4gIGNvbnN0IFNsYXNoU2NoZW1lQ29sb25TbGFzaCA9IHR0KFNsYXNoU2NoZW1lQ29sb24sIFNMQVNIKTsgLy8gZS5nLiwgJ2h0dHA6LydcblxuICBjb25zdCBVcmlQcmVmaXggPSB0dChTbGFzaFNjaGVtZUNvbG9uU2xhc2gsIFNMQVNIKTsgLy8gZS5nLiwgJ2h0dHA6Ly8nXG5cbiAgLy8gU2NoZW1lIHN0YXRlcyBjYW4gdHJhbnNpdGlvbiB0byBkb21haW4gc3RhdGVzXG4gIHRhKFNjaGVtZSwgZ3JvdXBzLmRvbWFpbiwgRG9tYWluKTtcbiAgdHQoU2NoZW1lLCBET1QsIERvbWFpbkRvdCk7XG4gIHR0KFNjaGVtZSwgSFlQSEVOLCBEb21haW5IeXBoZW4pO1xuICB0YShTbGFzaFNjaGVtZSwgZ3JvdXBzLmRvbWFpbiwgRG9tYWluKTtcbiAgdHQoU2xhc2hTY2hlbWUsIERPVCwgRG9tYWluRG90KTtcbiAgdHQoU2xhc2hTY2hlbWUsIEhZUEhFTiwgRG9tYWluSHlwaGVuKTtcblxuICAvLyBGb3JjZSBVUkwgd2l0aCBzY2hlbWUgcHJlZml4IGZvbGxvd2VkIGJ5IGFueXRoaW5nIHNhbmVcbiAgdGEoU2NoZW1lQ29sb24sIGdyb3Vwcy5kb21haW4sIFVybCQxKTtcbiAgdHQoU2NoZW1lQ29sb24sIFNMQVNILCBVcmwkMSk7XG4gIHR0KFNjaGVtZUNvbG9uLCBRVUVSWSwgVXJsJDEpO1xuICB0YShVcmlQcmVmaXgsIGdyb3Vwcy5kb21haW4sIFVybCQxKTtcbiAgdGEoVXJpUHJlZml4LCBxc0FjY2VwdGluZywgVXJsJDEpO1xuICB0dChVcmlQcmVmaXgsIFNMQVNILCBVcmwkMSk7XG4gIGNvbnN0IGJyYWNrZXRQYWlycyA9IFtbT1BFTkJSQUNFLCBDTE9TRUJSQUNFXSxcbiAgLy8ge31cbiAgW09QRU5CUkFDS0VULCBDTE9TRUJSQUNLRVRdLFxuICAvLyBbXVxuICBbT1BFTlBBUkVOLCBDTE9TRVBBUkVOXSxcbiAgLy8gKClcbiAgW09QRU5BTkdMRUJSQUNLRVQsIENMT1NFQU5HTEVCUkFDS0VUXSxcbiAgLy8gPD5cbiAgW0ZVTExXSURUSExFRlRQQVJFTiwgRlVMTFdJRFRIUklHSFRQQVJFTl0sXG4gIC8vIO+8iO+8iVxuICBbTEVGVENPUk5FUkJSQUNLRVQsIFJJR0hUQ09STkVSQlJBQ0tFVF0sXG4gIC8vIOOAjOOAjVxuICBbTEVGVFdISVRFQ09STkVSQlJBQ0tFVCwgUklHSFRXSElURUNPUk5FUkJSQUNLRVRdLFxuICAvLyDjgI7jgI9cbiAgW0ZVTExXSURUSExFU1NUSEFOLCBGVUxMV0lEVEhHUkVBVEVSVEhBTl0gLy8g77yc77yeXG4gIF07XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYnJhY2tldFBhaXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgW09QRU4sIENMT1NFXSA9IGJyYWNrZXRQYWlyc1tpXTtcbiAgICBjb25zdCBVcmxPcGVuID0gdHQoVXJsJDEsIE9QRU4pOyAvLyBVUkwgZm9sbG93ZWQgYnkgb3BlbiBicmFja2V0XG5cbiAgICAvLyBDb250aW51ZSBub3QgYWNjZXB0aW5nIGZvciBvcGVuIGJyYWNrZXRzXG4gICAgdHQoVXJsTm9uYWNjZXB0LCBPUEVOLCBVcmxPcGVuKTtcblxuICAgIC8vIENsb3NpbmcgYnJhY2tldCBjb21wb25lbnQuIFRoaXMgY2hhcmFjdGVyIFdJTEwgYmUgaW5jbHVkZWQgaW4gdGhlIFVSTFxuICAgIHR0KFVybE9wZW4sIENMT1NFLCBVcmwkMSk7XG5cbiAgICAvLyBVUkwgdGhhdCBiZWluZ3Mgd2l0aCBhbiBvcGVuaW5nIGJyYWNrZXQsIGZvbGxvd2VkIGJ5IGEgc3ltYm9scy5cbiAgICAvLyBOb3RlIHRoYXQgdGhlIGZpbmFsIHN0YXRlIGNhbiBzdGlsbCBiZSBgVXJsT3BlbmAgKGlmIHRoZSBVUkwgaGFzIGFcbiAgICAvLyBzaW5nbGUgb3BlbmluZyBicmFja2V0IGZvciBzb21lIHJlYXNvbikuXG4gICAgY29uc3QgVXJsT3BlblEgPSBtYWtlU3RhdGUoVXJsKTtcbiAgICB0YShVcmxPcGVuLCBxc0FjY2VwdGluZywgVXJsT3BlblEpO1xuICAgIGNvbnN0IFVybE9wZW5TeW1zID0gbWFrZVN0YXRlKCk7IC8vIFVybE9wZW4gZm9sbG93ZWQgYnkgc29tZSBzeW1ib2xzIGl0IGNhbm5vdCBlbmQgaXRcbiAgICB0YShVcmxPcGVuLCBxc05vbkFjY2VwdGluZyk7XG5cbiAgICAvLyBVUkwgdGhhdCBiZWdpbnMgd2l0aCBhbiBvcGVuaW5nIGJyYWNrZXQsIGZvbGxvd2VkIGJ5IHNvbWUgc3ltYm9sc1xuICAgIHRhKFVybE9wZW5RLCBxc0FjY2VwdGluZywgVXJsT3BlblEpO1xuICAgIHRhKFVybE9wZW5RLCBxc05vbkFjY2VwdGluZywgVXJsT3BlblN5bXMpO1xuICAgIHRhKFVybE9wZW5TeW1zLCBxc0FjY2VwdGluZywgVXJsT3BlblEpO1xuICAgIHRhKFVybE9wZW5TeW1zLCBxc05vbkFjY2VwdGluZywgVXJsT3BlblN5bXMpO1xuXG4gICAgLy8gQ2xvc2UgYnJhY2UvYnJhY2tldCB0byBiZWNvbWUgcmVndWxhciBVUkxcbiAgICB0dChVcmxPcGVuUSwgQ0xPU0UsIFVybCQxKTtcbiAgICB0dChVcmxPcGVuU3ltcywgQ0xPU0UsIFVybCQxKTtcbiAgfVxuICB0dChTdGFydCwgTE9DQUxIT1NULCBEb21haW5Eb3RUbGQpOyAvLyBsb2NhbGhvc3QgaXMgYSB2YWxpZCBVUkwgc3RhdGVcbiAgdHQoU3RhcnQsIE5MLCBObCk7IC8vIHNpbmdsZSBuZXcgbGluZVxuXG4gIHJldHVybiB7XG4gICAgc3RhcnQ6IFN0YXJ0LFxuICAgIHRva2VuczogdGtcbiAgfTtcbn1cblxuLyoqXG4gKiBSdW4gdGhlIHBhcnNlciBzdGF0ZSBtYWNoaW5lIG9uIGEgbGlzdCBvZiBzY2FubmVkIHN0cmluZy1iYXNlZCB0b2tlbnMgdG9cbiAqIGNyZWF0ZSBhIGxpc3Qgb2YgbXVsdGkgdG9rZW5zLCBlYWNoIG9mIHdoaWNoIHJlcHJlc2VudHMgYSBVUkwsIGVtYWlsIGFkZHJlc3MsXG4gKiBwbGFpbiB0ZXh0LCBldGMuXG4gKlxuICogQHBhcmFtIHtTdGF0ZTxNdWx0aVRva2VuPn0gc3RhcnQgcGFyc2VyIHN0YXJ0IHN0YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgdGhlIG9yaWdpbmFsIGlucHV0IHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGdpdmVuIHRva2Vuc1xuICogQHBhcmFtIHtUb2tlbltdfSB0b2tlbnMgbGlzdCBvZiBzY2FubmVkIHRva2Vuc1xuICogQHJldHVybnMge011bHRpVG9rZW5bXX1cbiAqL1xuZnVuY3Rpb24gcnVuKHN0YXJ0LCBpbnB1dCwgdG9rZW5zKSB7XG4gIGxldCBsZW4gPSB0b2tlbnMubGVuZ3RoO1xuICBsZXQgY3Vyc29yID0gMDtcbiAgbGV0IG11bHRpcyA9IFtdO1xuICBsZXQgdGV4dFRva2VucyA9IFtdO1xuICB3aGlsZSAoY3Vyc29yIDwgbGVuKSB7XG4gICAgbGV0IHN0YXRlID0gc3RhcnQ7XG4gICAgbGV0IHNlY29uZFN0YXRlID0gbnVsbDtcbiAgICBsZXQgbmV4dFN0YXRlID0gbnVsbDtcbiAgICBsZXQgbXVsdGlMZW5ndGggPSAwO1xuICAgIGxldCBsYXRlc3RBY2NlcHRpbmcgPSBudWxsO1xuICAgIGxldCBzaW5jZUFjY2VwdHMgPSAtMTtcbiAgICB3aGlsZSAoY3Vyc29yIDwgbGVuICYmICEoc2Vjb25kU3RhdGUgPSBzdGF0ZS5nbyh0b2tlbnNbY3Vyc29yXS50KSkpIHtcbiAgICAgIC8vIFN0YXJ0aW5nIHRva2VucyB3aXRoIG5vd2hlcmUgdG8ganVtcCB0by5cbiAgICAgIC8vIENvbnNpZGVyIHRoZXNlIHRvIGJlIGp1c3QgcGxhaW4gdGV4dFxuICAgICAgdGV4dFRva2Vucy5wdXNoKHRva2Vuc1tjdXJzb3IrK10pO1xuICAgIH1cbiAgICB3aGlsZSAoY3Vyc29yIDwgbGVuICYmIChuZXh0U3RhdGUgPSBzZWNvbmRTdGF0ZSB8fCBzdGF0ZS5nbyh0b2tlbnNbY3Vyc29yXS50KSkpIHtcbiAgICAgIC8vIEdldCB0aGUgbmV4dCBzdGF0ZVxuICAgICAgc2Vjb25kU3RhdGUgPSBudWxsO1xuICAgICAgc3RhdGUgPSBuZXh0U3RhdGU7XG5cbiAgICAgIC8vIEtlZXAgdHJhY2sgb2YgdGhlIGxhdGVzdCBhY2NlcHRpbmcgc3RhdGVcbiAgICAgIGlmIChzdGF0ZS5hY2NlcHRzKCkpIHtcbiAgICAgICAgc2luY2VBY2NlcHRzID0gMDtcbiAgICAgICAgbGF0ZXN0QWNjZXB0aW5nID0gc3RhdGU7XG4gICAgICB9IGVsc2UgaWYgKHNpbmNlQWNjZXB0cyA+PSAwKSB7XG4gICAgICAgIHNpbmNlQWNjZXB0cysrO1xuICAgICAgfVxuICAgICAgY3Vyc29yKys7XG4gICAgICBtdWx0aUxlbmd0aCsrO1xuICAgIH1cbiAgICBpZiAoc2luY2VBY2NlcHRzIDwgMCkge1xuICAgICAgLy8gTm8gYWNjZXB0aW5nIHN0YXRlIHdhcyBmb3VuZCwgcGFydCBvZiBhIHJlZ3VsYXIgdGV4dCB0b2tlbiBhZGRcbiAgICAgIC8vIHRoZSBmaXJzdCB0ZXh0IHRva2VuIHRvIHRoZSB0ZXh0IHRva2VucyBhcnJheSBhbmQgdHJ5IGFnYWluIGZyb21cbiAgICAgIC8vIHRoZSBuZXh0XG4gICAgICBjdXJzb3IgLT0gbXVsdGlMZW5ndGg7XG4gICAgICBpZiAoY3Vyc29yIDwgbGVuKSB7XG4gICAgICAgIHRleHRUb2tlbnMucHVzaCh0b2tlbnNbY3Vyc29yXSk7XG4gICAgICAgIGN1cnNvcisrO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICAvLyBBY2NlcHRpbmcgc3RhdGUhXG4gICAgICAvLyBGaXJzdCBjbG9zZSBvZmYgdGhlIHRleHRUb2tlbnMgKGlmIGF2YWlsYWJsZSlcbiAgICAgIGlmICh0ZXh0VG9rZW5zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbXVsdGlzLnB1c2goaW5pdE11bHRpVG9rZW4oVGV4dCwgaW5wdXQsIHRleHRUb2tlbnMpKTtcbiAgICAgICAgdGV4dFRva2VucyA9IFtdO1xuICAgICAgfVxuXG4gICAgICAvLyBSb2xsIGJhY2sgdG8gdGhlIGxhdGVzdCBhY2NlcHRpbmcgc3RhdGVcbiAgICAgIGN1cnNvciAtPSBzaW5jZUFjY2VwdHM7XG4gICAgICBtdWx0aUxlbmd0aCAtPSBzaW5jZUFjY2VwdHM7XG5cbiAgICAgIC8vIENyZWF0ZSBhIG5ldyBtdWx0aXRva2VuXG4gICAgICBjb25zdCBNdWx0aSA9IGxhdGVzdEFjY2VwdGluZy50O1xuICAgICAgY29uc3Qgc3VidG9rZW5zID0gdG9rZW5zLnNsaWNlKGN1cnNvciAtIG11bHRpTGVuZ3RoLCBjdXJzb3IpO1xuICAgICAgbXVsdGlzLnB1c2goaW5pdE11bHRpVG9rZW4oTXVsdGksIGlucHV0LCBzdWJ0b2tlbnMpKTtcbiAgICB9XG4gIH1cblxuICAvLyBGaW5hbGx5IGNsb3NlIG9mZiB0aGUgdGV4dFRva2VucyAoaWYgYXZhaWxhYmxlKVxuICBpZiAodGV4dFRva2Vucy5sZW5ndGggPiAwKSB7XG4gICAgbXVsdGlzLnB1c2goaW5pdE11bHRpVG9rZW4oVGV4dCwgaW5wdXQsIHRleHRUb2tlbnMpKTtcbiAgfVxuICByZXR1cm4gbXVsdGlzO1xufVxuXG4vKipcbiAqIFV0aWxpdHkgZnVuY3Rpb24gZm9yIGluc3RhbnRpYXRpbmcgYSBuZXcgbXVsdGl0b2tlbiB3aXRoIGFsbCB0aGUgcmVsZXZhbnRcbiAqIGZpZWxkcyBkdXJpbmcgcGFyc2luZy5cbiAqIEBwYXJhbSB7bmV3ICh2YWx1ZTogc3RyaW5nLCB0b2tlbnM6IFRva2VuW10pID0+IE11bHRpVG9rZW59IE11bHRpIGNsYXNzIHRvIGluc3RhbnRpYXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gaW5wdXQgb3JpZ2luYWwgaW5wdXQgc3RyaW5nXG4gKiBAcGFyYW0ge1Rva2VuW119IHRva2VucyBjb25zZWN1dGl2ZSB0b2tlbnMgc2Nhbm5lZCBmcm9tIGlucHV0IHN0cmluZ1xuICogQHJldHVybnMge011bHRpVG9rZW59XG4gKi9cbmZ1bmN0aW9uIGluaXRNdWx0aVRva2VuKE11bHRpLCBpbnB1dCwgdG9rZW5zKSB7XG4gIGNvbnN0IHN0YXJ0SWR4ID0gdG9rZW5zWzBdLnM7XG4gIGNvbnN0IGVuZElkeCA9IHRva2Vuc1t0b2tlbnMubGVuZ3RoIC0gMV0uZTtcbiAgY29uc3QgdmFsdWUgPSBpbnB1dC5zbGljZShzdGFydElkeCwgZW5kSWR4KTtcbiAgcmV0dXJuIG5ldyBNdWx0aSh2YWx1ZSwgdG9rZW5zKTtcbn1cblxuY29uc3Qgd2FybiA9IHR5cGVvZiBjb25zb2xlICE9PSAndW5kZWZpbmVkJyAmJiBjb25zb2xlICYmIGNvbnNvbGUud2FybiB8fCAoKCkgPT4ge30pO1xuY29uc3Qgd2FybkFkdmljZSA9ICd1bnRpbCBtYW51YWwgY2FsbCBvZiBsaW5raWZ5LmluaXQoKS4gUmVnaXN0ZXIgYWxsIHNjaGVtZXMgYW5kIHBsdWdpbnMgYmVmb3JlIGludm9raW5nIGxpbmtpZnkgdGhlIGZpcnN0IHRpbWUuJztcblxuLy8gU2lkZS1lZmZlY3QgaW5pdGlhbGl6YXRpb24gc3RhdGVcbmNvbnN0IElOSVQgPSB7XG4gIHNjYW5uZXI6IG51bGwsXG4gIHBhcnNlcjogbnVsbCxcbiAgdG9rZW5RdWV1ZTogW10sXG4gIHBsdWdpblF1ZXVlOiBbXSxcbiAgY3VzdG9tU2NoZW1lczogW10sXG4gIGluaXRpYWxpemVkOiBmYWxzZVxufTtcblxuLyoqXG4gKiBAdHlwZWRlZiB7e1xuICogXHRzdGFydDogU3RhdGU8c3RyaW5nPixcbiAqIFx0dG9rZW5zOiB7IGdyb3VwczogQ29sbGVjdGlvbnM8c3RyaW5nPiB9ICYgdHlwZW9mIHRrXG4gKiB9fSBTY2FubmVySW5pdFxuICovXG5cbi8qKlxuICogQHR5cGVkZWYge3tcbiAqIFx0c3RhcnQ6IFN0YXRlPE11bHRpVG9rZW4+LFxuICogXHR0b2tlbnM6IHR5cGVvZiBtdWx0aVxuICogfX0gUGFyc2VySW5pdFxuICovXG5cbi8qKlxuICogQHR5cGVkZWYgeyhhcmc6IHsgc2Nhbm5lcjogU2Nhbm5lckluaXQgfSkgPT4gdm9pZH0gVG9rZW5QbHVnaW5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHsoYXJnOiB7IHNjYW5uZXI6IFNjYW5uZXJJbml0LCBwYXJzZXI6IFBhcnNlckluaXQgfSkgPT4gdm9pZH0gUGx1Z2luXG4gKi9cblxuLyoqXG4gKiBEZS1yZWdpc3RlciBhbGwgcGx1Z2lucyBhbmQgcmVzZXQgdGhlIGludGVybmFsIHN0YXRlLW1hY2hpbmUuIFVzZWQgZm9yXG4gKiB0ZXN0aW5nOyBub3QgcmVxdWlyZWQgaW4gcHJhY3RpY2UuXG4gKiBAcHJpdmF0ZVxuICovXG5mdW5jdGlvbiByZXNldCgpIHtcbiAgU3RhdGUuZ3JvdXBzID0ge307XG4gIElOSVQuc2Nhbm5lciA9IG51bGw7XG4gIElOSVQucGFyc2VyID0gbnVsbDtcbiAgSU5JVC50b2tlblF1ZXVlID0gW107XG4gIElOSVQucGx1Z2luUXVldWUgPSBbXTtcbiAgSU5JVC5jdXN0b21TY2hlbWVzID0gW107XG4gIElOSVQuaW5pdGlhbGl6ZWQgPSBmYWxzZTtcbiAgcmV0dXJuIElOSVQ7XG59XG5cbi8qKlxuICogUmVnaXN0ZXIgYSB0b2tlbiBwbHVnaW4gdG8gYWxsb3cgdGhlIHNjYW5uZXIgdG8gcmVjb2duaXplIGFkZGl0aW9uYWwgdG9rZW5cbiAqIHR5cGVzIGJlZm9yZSB0aGUgcGFyc2VyIHN0YXRlIG1hY2hpbmUgaXMgY29uc3RydWN0ZWQgZnJvbSB0aGUgcmVzdWx0cy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIG9mIHBsdWdpbiB0byByZWdpc3RlclxuICogQHBhcmFtIHtUb2tlblBsdWdpbn0gcGx1Z2luIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyB0aGUgc2Nhbm5lciBzdGF0ZSBtYWNoaW5lXG4gKiBhbmQgYXZhaWxhYmxlIHNjYW5uZXIgdG9rZW5zIGFuZCBjb2xsZWN0aW9ucyBhbmQgZXh0ZW5kcyB0aGUgc3RhdGUgbWFjaGluZSB0b1xuICogcmVjb2duaXplIGFkZGl0aW9uYWwgdG9rZW5zIG9yIGdyb3Vwcy5cbiAqL1xuZnVuY3Rpb24gcmVnaXN0ZXJUb2tlblBsdWdpbihuYW1lLCBwbHVnaW4pIHtcbiAgaWYgKHR5cGVvZiBwbHVnaW4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGxpbmtpZnlqczogSW52YWxpZCB0b2tlbiBwbHVnaW4gJHtwbHVnaW59IChleHBlY3RzIGZ1bmN0aW9uKWApO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgSU5JVC50b2tlblF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKG5hbWUgPT09IElOSVQudG9rZW5RdWV1ZVtpXVswXSkge1xuICAgICAgd2FybihgbGlua2lmeWpzOiB0b2tlbiBwbHVnaW4gXCIke25hbWV9XCIgYWxyZWFkeSByZWdpc3RlcmVkIC0gd2lsbCBiZSBvdmVyd3JpdHRlbmApO1xuICAgICAgSU5JVC50b2tlblF1ZXVlW2ldID0gW25hbWUsIHBsdWdpbl07XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG4gIElOSVQudG9rZW5RdWV1ZS5wdXNoKFtuYW1lLCBwbHVnaW5dKTtcbiAgaWYgKElOSVQuaW5pdGlhbGl6ZWQpIHtcbiAgICB3YXJuKGBsaW5raWZ5anM6IGFscmVhZHkgaW5pdGlhbGl6ZWQgLSB3aWxsIG5vdCByZWdpc3RlciB0b2tlbiBwbHVnaW4gXCIke25hbWV9XCIgJHt3YXJuQWR2aWNlfWApO1xuICB9XG59XG5cbi8qKlxuICogUmVnaXN0ZXIgYSBsaW5raWZ5IHBsdWdpblxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgb2YgcGx1Z2luIHRvIHJlZ2lzdGVyXG4gKiBAcGFyYW0ge1BsdWdpbn0gcGx1Z2luIGZ1bmN0aW9uIHRoYXQgYWNjZXB0cyB0aGUgcGFyc2VyIHN0YXRlIG1hY2hpbmUgYW5kXG4gKiBleHRlbmRzIHRoZSBwYXJzZXIgdG8gcmVjb2duaXplIGFkZGl0aW9uYWwgbGluayB0eXBlc1xuICovXG5mdW5jdGlvbiByZWdpc3RlclBsdWdpbihuYW1lLCBwbHVnaW4pIHtcbiAgaWYgKHR5cGVvZiBwbHVnaW4gIT09ICdmdW5jdGlvbicpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGxpbmtpZnlqczogSW52YWxpZCBwbHVnaW4gJHtwbHVnaW59IChleHBlY3RzIGZ1bmN0aW9uKWApO1xuICB9XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgSU5JVC5wbHVnaW5RdWV1ZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChuYW1lID09PSBJTklULnBsdWdpblF1ZXVlW2ldWzBdKSB7XG4gICAgICB3YXJuKGBsaW5raWZ5anM6IHBsdWdpbiBcIiR7bmFtZX1cIiBhbHJlYWR5IHJlZ2lzdGVyZWQgLSB3aWxsIGJlIG92ZXJ3cml0dGVuYCk7XG4gICAgICBJTklULnBsdWdpblF1ZXVlW2ldID0gW25hbWUsIHBsdWdpbl07XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG4gIElOSVQucGx1Z2luUXVldWUucHVzaChbbmFtZSwgcGx1Z2luXSk7XG4gIGlmIChJTklULmluaXRpYWxpemVkKSB7XG4gICAgd2FybihgbGlua2lmeWpzOiBhbHJlYWR5IGluaXRpYWxpemVkIC0gd2lsbCBub3QgcmVnaXN0ZXIgcGx1Z2luIFwiJHtuYW1lfVwiICR7d2FybkFkdmljZX1gKTtcbiAgfVxufVxuXG4vKipcbiAqIERldGVjdCBVUkxzIHdpdGggdGhlIGZvbGxvd2luZyBhZGRpdGlvbmFsIHByb3RvY29sLiBBbnl0aGluZyB3aXRoIGZvcm1hdFxuICogXCJwcm90b2NvbDovLy4uLlwiIHdpbGwgYmUgY29uc2lkZXJlZCBhIGxpbmsuIElmIGBvcHRpb25hbFNsYXNoU2xhc2hgIGlzIHNldCB0b1xuICogYHRydWVgLCBhbnl0aGluZyB3aXRoIGZvcm1hdCBcInByb3RvY29sOi4uLlwiIHdpbGwgYmUgY29uc2lkZXJlZCBhIGxpbmsuXG4gKiBAcGFyYW0ge3N0cmluZ30gc2NoZW1lXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25hbFNsYXNoU2xhc2hdXG4gKi9cbmZ1bmN0aW9uIHJlZ2lzdGVyQ3VzdG9tUHJvdG9jb2woc2NoZW1lLCBvcHRpb25hbFNsYXNoU2xhc2ggPSBmYWxzZSkge1xuICBpZiAoSU5JVC5pbml0aWFsaXplZCkge1xuICAgIHdhcm4oYGxpbmtpZnlqczogYWxyZWFkeSBpbml0aWFsaXplZCAtIHdpbGwgbm90IHJlZ2lzdGVyIGN1c3RvbSBzY2hlbWUgXCIke3NjaGVtZX1cIiAke3dhcm5BZHZpY2V9YCk7XG4gIH1cbiAgaWYgKCEvXlswLTlhLXpdKygtWzAtOWEtel0rKSokLy50ZXN0KHNjaGVtZSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYGxpbmtpZnlqczogaW5jb3JyZWN0IHNjaGVtZSBmb3JtYXQuXG4xLiBNdXN0IG9ubHkgY29udGFpbiBkaWdpdHMsIGxvd2VyY2FzZSBBU0NJSSBsZXR0ZXJzIG9yIFwiLVwiXG4yLiBDYW5ub3Qgc3RhcnQgb3IgZW5kIHdpdGggXCItXCJcbjMuIFwiLVwiIGNhbm5vdCByZXBlYXRgKTtcbiAgfVxuICBJTklULmN1c3RvbVNjaGVtZXMucHVzaChbc2NoZW1lLCBvcHRpb25hbFNsYXNoU2xhc2hdKTtcbn1cblxuLyoqXG4gKiBJbml0aWFsaXplIHRoZSBsaW5raWZ5IHN0YXRlIG1hY2hpbmUuIENhbGxlZCBhdXRvbWF0aWNhbGx5IHRoZSBmaXJzdCB0aW1lXG4gKiBsaW5raWZ5IGlzIGNhbGxlZCBvbiBhIHN0cmluZywgYnV0IG1heSBiZSBjYWxsZWQgbWFudWFsbHkgYXMgd2VsbC5cbiAqL1xuZnVuY3Rpb24gaW5pdCgpIHtcbiAgLy8gSW5pdGlhbGl6ZSBzY2FubmVyIHN0YXRlIG1hY2hpbmUgYW5kIHBsdWdpbnNcbiAgSU5JVC5zY2FubmVyID0gaW5pdCQyKElOSVQuY3VzdG9tU2NoZW1lcyk7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgSU5JVC50b2tlblF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgSU5JVC50b2tlblF1ZXVlW2ldWzFdKHtcbiAgICAgIHNjYW5uZXI6IElOSVQuc2Nhbm5lclxuICAgIH0pO1xuICB9XG5cbiAgLy8gSW5pdGlhbGl6ZSBwYXJzZXIgc3RhdGUgbWFjaGluZSBhbmQgcGx1Z2luc1xuICBJTklULnBhcnNlciA9IGluaXQkMShJTklULnNjYW5uZXIudG9rZW5zKTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBJTklULnBsdWdpblF1ZXVlLmxlbmd0aDsgaSsrKSB7XG4gICAgSU5JVC5wbHVnaW5RdWV1ZVtpXVsxXSh7XG4gICAgICBzY2FubmVyOiBJTklULnNjYW5uZXIsXG4gICAgICBwYXJzZXI6IElOSVQucGFyc2VyXG4gICAgfSk7XG4gIH1cbiAgSU5JVC5pbml0aWFsaXplZCA9IHRydWU7XG4gIHJldHVybiBJTklUO1xufVxuXG4vKipcbiAqIFBhcnNlIGEgc3RyaW5nIGludG8gdG9rZW5zIHRoYXQgcmVwcmVzZW50IGxpbmthYmxlIGFuZCBub24tbGlua2FibGUgc3ViLWNvbXBvbmVudHNcbiAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAqIEByZXR1cm4ge011bHRpVG9rZW5bXX0gdG9rZW5zXG4gKi9cbmZ1bmN0aW9uIHRva2VuaXplKHN0cikge1xuICBpZiAoIUlOSVQuaW5pdGlhbGl6ZWQpIHtcbiAgICBpbml0KCk7XG4gIH1cbiAgcmV0dXJuIHJ1bihJTklULnBhcnNlci5zdGFydCwgc3RyLCBydW4kMShJTklULnNjYW5uZXIuc3RhcnQsIHN0cikpO1xufVxudG9rZW5pemUuc2NhbiA9IHJ1biQxOyAvLyBmb3IgdGVzdGluZ1xuXG4vKipcbiAqIEZpbmQgYSBsaXN0IG9mIGxpbmthYmxlIGl0ZW1zIGluIHRoZSBnaXZlbiBzdHJpbmcuXG4gKiBAcGFyYW0ge3N0cmluZ30gc3RyIHN0cmluZyB0byBmaW5kIGxpbmtzIGluXG4gKiBAcGFyYW0ge3N0cmluZyB8IE9wdHN9IFt0eXBlXSBlaXRoZXIgZm9ybWF0dGluZyBvcHRpb25zIG9yIHNwZWNpZmljIHR5cGUgb2ZcbiAqIGxpbmtzIHRvIGZpbmQsIGUuZy4sICd1cmwnIG9yICdlbWFpbCdcbiAqIEBwYXJhbSB7T3B0c30gW29wdHNdIGZvcm1hdHRpbmcgb3B0aW9ucyBmb3IgZmluYWwgb3V0cHV0LiBDYW5ub3QgYmUgc3BlY2lmaWVkXG4gKiBpZiBvcHRzIGFscmVhZHkgcHJvdmlkZWQgaW4gYHR5cGVgIGFyZ3VtZW50XG4gKi9cbmZ1bmN0aW9uIGZpbmQoc3RyLCB0eXBlID0gbnVsbCwgb3B0cyA9IG51bGwpIHtcbiAgaWYgKHR5cGUgJiYgdHlwZW9mIHR5cGUgPT09ICdvYmplY3QnKSB7XG4gICAgaWYgKG9wdHMpIHtcbiAgICAgIHRocm93IEVycm9yKGBsaW5raWZ5anM6IEludmFsaWQgbGluayB0eXBlICR7dHlwZX07IG11c3QgYmUgYSBzdHJpbmdgKTtcbiAgICB9XG4gICAgb3B0cyA9IHR5cGU7XG4gICAgdHlwZSA9IG51bGw7XG4gIH1cbiAgY29uc3Qgb3B0aW9ucyA9IG5ldyBPcHRpb25zKG9wdHMpO1xuICBjb25zdCB0b2tlbnMgPSB0b2tlbml6ZShzdHIpO1xuICBjb25zdCBmaWx0ZXJlZCA9IFtdO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IHRva2Vucy5sZW5ndGg7IGkrKykge1xuICAgIGNvbnN0IHRva2VuID0gdG9rZW5zW2ldO1xuICAgIGlmICh0b2tlbi5pc0xpbmsgJiYgKCF0eXBlIHx8IHRva2VuLnQgPT09IHR5cGUpICYmIG9wdGlvbnMuY2hlY2sodG9rZW4pKSB7XG4gICAgICBmaWx0ZXJlZC5wdXNoKHRva2VuLnRvRm9ybWF0dGVkT2JqZWN0KG9wdGlvbnMpKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZpbHRlcmVkO1xufVxuXG4vKipcbiAqIElzIHRoZSBnaXZlbiBzdHJpbmcgdmFsaWQgbGlua2FibGUgdGV4dCBvZiBzb21lIHNvcnQuIE5vdGUgdGhhdCB0aGlzIGRvZXMgbm90XG4gKiB0cmltIHRoZSB0ZXh0IGZvciB5b3UuXG4gKlxuICogT3B0aW9uYWxseSBwYXNzIGluIGEgc2Vjb25kIGB0eXBlYCBwYXJhbSwgd2hpY2ggaXMgdGhlIHR5cGUgb2YgbGluayB0byB0ZXN0XG4gKiBmb3IuXG4gKlxuICogRm9yIGV4YW1wbGUsXG4gKlxuICogICAgIGxpbmtpZnkudGVzdChzdHIsICdlbWFpbCcpO1xuICpcbiAqIFJldHVybnMgYHRydWVgIGlmIHN0ciBpcyBhIHZhbGlkIGVtYWlsLlxuICogQHBhcmFtIHtzdHJpbmd9IHN0ciBzdHJpbmcgdG8gdGVzdCBmb3IgbGlua3NcbiAqIEBwYXJhbSB7c3RyaW5nfSBbdHlwZV0gb3B0aW9uYWwgc3BlY2lmaWMgbGluayB0eXBlIHRvIGxvb2sgZm9yXG4gKiBAcmV0dXJucyBib29sZWFuIHRydWUvZmFsc2VcbiAqL1xuZnVuY3Rpb24gdGVzdChzdHIsIHR5cGUgPSBudWxsKSB7XG4gIGNvbnN0IHRva2VucyA9IHRva2VuaXplKHN0cik7XG4gIHJldHVybiB0b2tlbnMubGVuZ3RoID09PSAxICYmIHRva2Vuc1swXS5pc0xpbmsgJiYgKCF0eXBlIHx8IHRva2Vuc1swXS50ID09PSB0eXBlKTtcbn1cblxuZXhwb3J0IHsgTXVsdGlUb2tlbiwgT3B0aW9ucywgU3RhdGUsIGNyZWF0ZVRva2VuQ2xhc3MsIGZpbmQsIGluaXQsIG11bHRpLCBvcHRpb25zLCByZWdleHAsIHJlZ2lzdGVyQ3VzdG9tUHJvdG9jb2wsIHJlZ2lzdGVyUGx1Z2luLCByZWdpc3RlclRva2VuUGx1Z2luLCByZXNldCwgc3RyaW5nVG9BcnJheSwgdGVzdCwgbXVsdGkgYXMgdGV4dCwgdG9rZW5pemUgfTtcbiJdLCJuYW1lcyI6W10sImlnbm9yZUxpc3QiOlswXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///(ssr)/./node_modules/linkifyjs/dist/linkify.mjs\n");
|
||
|
||
/***/ })
|
||
|
||
};
|
||
; |