From 9193d051759fd539ecd8d33d0a2427f71d5a4171 Mon Sep 17 00:00:00 2001 From: Andre Medeiros Date: Thu, 21 Aug 2014 23:17:38 +0300 Subject: [PATCH] Added examples: sum, any, delayWithSelector --- TODO | 3 +- dist/js/app.js | 17105 ++++++++++++++++++++++++- src/models/boolean-examples.coffee | 8 + src/models/math-examples.coffee | 8 + src/models/transform-examples.coffee | 22 +- 5 files changed, 17128 insertions(+), 18 deletions(-) diff --git a/TODO b/TODO index b3d0443..5db8380 100644 --- a/TODO +++ b/TODO @@ -41,7 +41,8 @@ DONE Remove the no-longer-needed loading indicator >>> v0.3.0 ## RC >>> v1.0.0 -TODO More trivial examples +DONE Added examples: sum, any, delayWithSelector +TODO Add more examples TODO Render each stream with a different regular polygon TODO Render also the stream completion time marker >>> v1.1.0 diff --git a/dist/js/app.js b/dist/js/app.js index c0f6ce3..ee2c887 100644 --- a/dist/js/app.js +++ b/dist/js/app.js @@ -1,5 +1,17100 @@ -!function t(e,n,r){function i(s,u){if(!n[s]){if(!e[s]){var c="function"==typeof require&&require;if(!u&&c)return c(s,!0);if(o)return o(s,!0);throw new Error("Cannot find module '"+s+"'")}var a=n[s]={exports:{}};e[s][0].call(a.exports,function(t){var n=e[s][1][t];return i(n?n:t)},a,a.exports,t,e,n,r)}return n[s].exports}for(var o="function"==typeof require&&require,s=0;st||isNaN(t))throw TypeError("n must be a positive number");return this._maxListeners=t,this},n.prototype.emit=function(t){var e,n,i,u,c,a;if(this._events||(this._events={}),"error"===t&&(!this._events.error||o(this._events.error)&&!this._events.error.length))throw e=arguments[1],e instanceof Error?e:TypeError('Uncaught, unspecified "error" event.');if(n=this._events[t],s(n))return!1;if(r(n))switch(arguments.length){case 1:n.call(this);break;case 2:n.call(this,arguments[1]);break;case 3:n.call(this,arguments[1],arguments[2]);break;default:for(i=arguments.length,u=new Array(i-1),c=1;i>c;c++)u[c-1]=arguments[c];n.apply(this,u)}else if(o(n)){for(i=arguments.length,u=new Array(i-1),c=1;i>c;c++)u[c-1]=arguments[c];for(a=n.slice(),i=a.length,c=0;i>c;c++)a[c].apply(this,u)}return!0},n.prototype.addListener=function(t,e){var i;if(!r(e))throw TypeError("listener must be a function");if(this._events||(this._events={}),this._events.newListener&&this.emit("newListener",t,r(e.listener)?e.listener:e),this._events[t]?o(this._events[t])?this._events[t].push(e):this._events[t]=[this._events[t],e]:this._events[t]=e,o(this._events[t])&&!this._events[t].warned){var i;i=s(this._maxListeners)?n.defaultMaxListeners:this._maxListeners,i&&i>0&&this._events[t].length>i&&(this._events[t].warned=!0,console.error("(node) warning: possible EventEmitter memory leak detected. %d listeners added. Use emitter.setMaxListeners() to increase limit.",this._events[t].length),"function"==typeof console.trace&&console.trace())}return this},n.prototype.on=n.prototype.addListener,n.prototype.once=function(t,e){function n(){this.removeListener(t,n),i||(i=!0,e.apply(this,arguments))}if(!r(e))throw TypeError("listener must be a function");var i=!1;return n.listener=e,this.on(t,n),this},n.prototype.removeListener=function(t,e){var n,i,s,u;if(!r(e))throw TypeError("listener must be a function");if(!this._events||!this._events[t])return this;if(n=this._events[t],s=n.length,i=-1,n===e||r(n.listener)&&n.listener===e)delete this._events[t],this._events.removeListener&&this.emit("removeListener",t,e);else if(o(n)){for(u=s;u-->0;)if(n[u]===e||n[u].listener&&n[u].listener===e){i=u;break}if(0>i)return this;1===n.length?(n.length=0,delete this._events[t]):n.splice(i,1),this._events.removeListener&&this.emit("removeListener",t,e)}return this},n.prototype.removeAllListeners=function(t){var e,n;if(!this._events)return this;if(!this._events.removeListener)return 0===arguments.length?this._events={}:this._events[t]&&delete this._events[t],this;if(0===arguments.length){for(e in this._events)"removeListener"!==e&&this.removeAllListeners(e);return this.removeAllListeners("removeListener"),this._events={},this}if(n=this._events[t],r(n))this.removeListener(t,n);else for(;n.length;)this.removeListener(t,n[n.length-1]);return delete this._events[t],this},n.prototype.listeners=function(t){var e;return e=this._events&&this._events[t]?r(this._events[t])?[this._events[t]]:this._events[t].slice():[]},n.listenerCount=function(t,e){var n;return n=t._events&&t._events[e]?r(t._events[e])?1:t._events[e].length:0}},{}],4:[function(t,e){function n(){function t(){function t(n){function l(t){var e=s(t,/([\.#]?[a-zA-Z0-9_:-]+)/);/^\.|#/.test(e[1])&&(a=document.createElement("div")),i(e,function(t){var e=t.substring(1,t.length);t&&(a?"."===t[0]?u(a).add(e):"#"===t[0]&&a.setAttribute("id",e):a=document.createElement(t))})}var f;if(null==n);else if("string"==typeof n)a?a.appendChild(f=document.createTextNode(n)):l(n);else if("number"==typeof n||"boolean"==typeof n||n instanceof Date||n instanceof RegExp)a.appendChild(f=document.createTextNode(n.toString()));else if(o(n))i(n,t);else if(r(n))a.appendChild(f=n);else if(n instanceof Text)a.appendChild(f=n);else if("object"==typeof n)for(var h in n)if("function"==typeof n[h])/^on\w+/.test(h)?a.addEventListener?(a.addEventListener(h.substring(2),n[h],!1),e.push(function(){a.removeEventListener(h.substring(2),n[h],!1)})):(a.attachEvent(h,n[h]),e.push(function(){a.detachEvent(h,n[h])})):(a[h]=n[h](),e.push(n[h](function(t){a[h]=t})));else if("style"===h)if("string"==typeof n[h])a.style.cssText=n[h];else for(var p in n[h])(function(t,r){"function"==typeof r?(a.style.setProperty(t,r()),e.push(r(function(e){a.style.setProperty(t,e)}))):a.style.setProperty(t,n[h][t])})(p,n[h][p]);else"data-"===h.substr(0,5)?c(a)[h.substr(5)]=n[h]:a[h]=n[h];else if("function"==typeof n){var d=n();a.appendChild(f=r(d)?d:document.createTextNode(d)),e.push(n(function(t){r(t)&&f.parentElement?(f.parentElement.replaceChild(t,f),f=t):f.textContent=t}))}return f}for(var n=[].slice.call(arguments),a=null;n.length;)t(n.shift());return a}var e=[];return t.cleanup=function(){for(var t=0;t>>0:o>>>0;(u=i.exec(e))&&(c=u.index+u[0].length,!(c>h&&(l.push(e.slice(h,u.index)),!r&&u.length>1&&u[0].replace(s,function(){for(var e=1;e1&&u.index=o)));)i.lastIndex===u.index&&i.lastIndex++;return h===e.length?(a||!i.test(""))&&l.push(""):l.push(e.slice(h)),l.length>o?l.slice(0,o):l}}()},{}],6:[function(t,e){function n(t){function e(t){var e=l();o(e,t)>-1||(e.push(t),f(e))}function n(t){var e=l(),n=o(e,t);-1!==n&&(e.splice(n,1),f(e))}function s(t){return o(l(),t)>-1}function u(t){return s(t)?(n(t),!1):(e(t),!0)}function c(){return t.className}function a(t){var e=l();return e[t]||null}function l(){var e=t.className;return r(e.split(" "),i)}function f(e){var n=e.length;t.className=e.join(" "),p.length=n;for(var r=0;r-1:void 0});return n.pop(),r.pop(),result}function h(t,e){return 1===t.length&&Array.isArray(t[e])?t[e]:Ve.call(t)}function p(t,e){for(var n=new Array(t),r=0;t>r;r++)n[r]=e();return n}function d(t,e){this.scheduler=t,this.disposable=e,this.isDisposed=!1}function v(t,e){return new ar(function(n){var r=new Qe,i=new Ze;return i.setDisposable(r),r.setDisposable(t.subscribe(n.onNext.bind(n),function(t){var r,o;try{o=e(t)}catch(s){return void n.onError(s)}le(o)&&(o=An(o)),r=new Qe,i.setDisposable(r),r.setDisposable(o.subscribe(n))},n.onCompleted.bind(n))),i})}function b(t,e){var n=this;return new ar(function(r){var i=0,o=t.length;return n.subscribe(function(n){if(o>i){var s,u=t[i++];try{s=e(n,u)}catch(c){return void r.onError(c)}r.onNext(s)}else r.onCompleted()},r.onError.bind(r),r.onCompleted.bind(r))})}function m(t){return this.map(function(e,n){var r=t(e,n);return le(r)?An(r):r}).concatAll()}function g(t){return this.select(function(e,n){var r=t(e,n);return le(r)?An(r):r}).mergeObservable()}function y(t,e,n){return new ar(function(r){var i=!1,o=null,s=[];return t.subscribe(function(t){var u,c;try{c=e(t)}catch(a){return void r.onError(a)}if(u=0,i)try{u=n(c,o)}catch(l){return void r.onError(l)}else i=!0,o=c;u>0&&(o=c,s=[]),u>=0&&s.push(t)},r.onError.bind(r),function(){r.onNext(s),r.onCompleted()})})}function w(t){if(0===t.length)throw new Error(fe);return t[0]}function x(t,e,n){return new ar(function(r){var i=0,o=e.length;return t.subscribe(function(t){var s=!1;try{o>i&&(s=n(t,e[i++]))}catch(u){return void r.onError(u)}s||(r.onNext(!1),r.onCompleted())},r.onError.bind(r),function(){r.onNext(i===o),r.onCompleted()})})}function E(t,e,n,r){if(0>e)throw new Error(he);return new ar(function(i){var o=e;return t.subscribe(function(t){0===o&&(i.onNext(t),i.onCompleted()),o--},i.onError.bind(i),function(){n?(i.onNext(r),i.onCompleted()):i.onError(new Error(he))})})}function C(t,e,n){return new ar(function(r){var i=n,o=!1;return t.subscribe(function(t){o?r.onError(new Error("Sequence contains more than one element")):(i=t,o=!0)},r.onError.bind(r),function(){o||e?(r.onNext(i),r.onCompleted()):r.onError(new Error(fe))})})}function N(t,e,n){return new ar(function(r){return t.subscribe(function(t){r.onNext(t),r.onCompleted()},r.onError.bind(r),function(){e?(r.onNext(n),r.onCompleted()):r.onError(new Error(fe))})})}function O(t,e,n){return new ar(function(r){var i=n,o=!1;return t.subscribe(function(t){i=t,o=!0},r.onError.bind(r),function(){o||e?(r.onNext(i),r.onCompleted()):r.onError(new Error(fe))})})}function k(e,n,r,i){return new ar(function(o){var s=0;return e.subscribe(function(t){var u;try{u=n.call(r,t,s,e)}catch(c){return void o.onError(c)}u?(o.onNext(i?s:t),o.onCompleted()):s++},o.onError.bind(o),function(){o.onNext(i?-1:t),o.onCompleted()})})}function S(t,e,n){if(t.addListener)return t.addListener(e,n),Ge(function(){t.removeListener(e,n)});if(t.addEventListener)return t.addEventListener(e,n,!1),Ge(function(){t.removeEventListener(e,n,!1)});throw new Error("No listener found")}function A(t,e,n){var r=new Fe;if("function"==typeof t.item&&"number"==typeof t.length)for(var i=0,o=t.length;o>i;i++)r.add(A(t.item(i),e,n));else t&&r.add(S(t,e,n));return r}function j(t,e,n){return new ar(function(r){function i(t,e){a[e]=t;var i;if(s[e]=!0,u||(u=s.every(ie))){try{i=n.apply(null,a)}catch(o){return void r.onError(o)}r.onNext(i)}else c&&r.onCompleted()}var o=2,s=[!1,!1],u=!1,c=!1,a=new Array(o);return new Fe(t.subscribe(function(t){i(t,0)},r.onError.bind(r),function(){c=!0,r.onCompleted()}),e.subscribe(function(t){i(t,1)},r.onError.bind(r)))})}function D(t){if(t&!1)return 2===t;for(var e=Math.sqrt(t),n=3;e>=n;){if(t%n===0)return!1;n+=2}return!0}function _(t){var e,n,r;for(e=0;e=t)return n;for(r=1|t;rn;n++){var i=t.charCodeAt(n);e=(e<<5)-e+i,e&=e}return e}function R(t){var e=668265261;return t=61^t^t>>>16,t+=t<<3,t^=t>>>4,t*=e,t^=t>>>15}function T(){return{key:null,value:null,next:0,hashCode:0}}function q(t,e){return t.groupJoin(this,e,function(){return Dn()},function(t,e){return e})}function P(t){var e=this;return new ar(function(n){var r=new hr,i=new Fe,o=new Ye(i);return n.onNext(Ue(r,o)),i.add(e.subscribe(function(t){r.onNext(t)},function(t){r.onError(t),n.onError(t)},function(){r.onCompleted(),n.onCompleted()})),i.add(t.subscribe(function(){r.onCompleted(),r=new hr,n.onNext(Ue(r,o))},function(t){r.onError(t),n.onError(t)},function(){r.onCompleted(),n.onCompleted()})),o})}function L(t){var e=this;return new ar(function(n){var r,i=new Ze,o=new Fe(i),s=new Ye(o),u=new hr;return n.onNext(Ue(u,s)),o.add(e.subscribe(function(t){u.onNext(t)},function(t){u.onError(t),n.onError(t)},function(){u.onCompleted(),n.onCompleted()})),r=function(){var e,o;try{o=t()}catch(c){return void n.onError(c)}e=new Qe,i.setDisposable(e),e.setDisposable(o.take(1).subscribe(re,function(t){u.onError(t),n.onError(t)},function(){u.onCompleted(),u=new hr,n.onNext(Ue(u,s)),r()}))},r(),s})}function V(e,n){return new bn(function(){return new vn(function(){return e()?{done:!1,value:n}:{done:!0,value:t}})})}function M(t){this.patterns=t}function z(t,e){this.expression=t,this.selector=e}function U(t,e,n){var r=t.get(e);if(!r){var i=new sr(e,n);return t.set(e,i),i}return r}function I(t,e,n){var r,i;for(this.joinObserverArray=t,this.onNext=e,this.onCompleted=n,this.joinObservers=new or,r=0;r0&&(s=n.now(),o+=r,s>=o&&(o=s+r)),e.onNext(i++),t(o)})})}function F(t,e){var n=rn(t);return new ar(function(t){return e.scheduleWithRelative(n,function(){t.onNext(0),t.onCompleted()})})}function $(t,e,n){return t===e?new ar(function(t){return n.schedulePeriodicWithState(0,e,function(e){return t.onNext(e),e+1})}):jn(function(){return H(n.now()+t,e,n)})}function J(t,e){var n=this;return new ar(function(r){var i,o=!1,s=new Ze,u=null,c=[],a=!1;return i=n.materialize().timestamp(e).subscribe(function(n){var i,l;"E"===n.value.kind?(c=[],c.push(n),u=n.value.exception,l=!a):(c.push({value:n.value,timestamp:n.timestamp+t}),l=!o,o=!0),l&&(null!==u?r.onError(u):(i=new Qe,s.setDisposable(i),i.setDisposable(e.scheduleRecursiveWithRelative(t,function(t){var n,i,s,l;if(null===u){a=!0;do s=null,c.length>0&&c[0].timestamp-e.now()<=0&&(s=c.shift().value),null!==s&&s.accept(r);while(null!==s);l=!1,i=0,c.length>0?(l=!0,i=Math.max(0,c[0].timestamp-e.now())):o=!1,n=u,a=!1,null!==n?r.onError(n):l&&t(i)}}))))}),new Fe(i,s)})}function G(t,e){var n=this;return jn(function(){var r=t-e.now();return J.call(n,r,e)})}function X(t,e){return new ar(function(n){function r(){s&&(s=!1,n.onNext(o)),i&&n.onCompleted()}var i,o,s;return new Fe(t.subscribe(function(t){s=!0,o=t},n.onError.bind(n),function(){i=!0}),e.subscribe(r,n.onError.bind(n),r))})}var K={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},Q=K[typeof window]&&window||this,Z=K[typeof n]&&n&&!n.nodeType&&n,Y=K[typeof e]&&e&&!e.nodeType&&e,te=Y&&Y.exports===Z&&Z,ee=K[typeof global]&&global;!ee||ee.global!==ee&&ee.window!==ee||(Q=ee);var ne={internals:{},config:{Promise:Q.Promise},helpers:{}},re=ne.helpers.noop=function(){},ie=ne.helpers.identity=function(t){return t},oe=(ne.helpers.pluck=function(t){return function(e){return e[t]}},ne.helpers.just=function(t){return function(){return t}},ne.helpers.defaultNow=Date.now),se=ne.helpers.defaultComparer=function(t,e){return Le(t,e)},ue=ne.helpers.defaultSubComparer=function(t,e){return t>e?1:e>t?-1:0},ce=ne.helpers.defaultKeySerializer=function(t){return t.toString()},ae=ne.helpers.defaultError=function(t){throw t},le=ne.helpers.isPromise=function(t){return!!t&&"function"==typeof t.then&&t.then!==ne.Observable.prototype.then},fe=(ne.helpers.asArray=function(){return Array.prototype.slice.call(arguments)},ne.helpers.not=function(t){return!t},"Sequence contains no elements."),he="Argument out of range",pe="Object has been disposed",de="object"==typeof Symbol&&Symbol.iterator||"_es6shim_iterator_";Q.Set&&"function"==typeof(new Q.Set)["@@iterator"]&&(de="@@iterator");var ve,be={done:!0,value:t},me="[object Arguments]",ge="[object Array]",ye="[object Boolean]",we="[object Date]",xe="[object Error]",Ee="[object Function]",Ce="[object Number]",Ne="[object Object]",Oe="[object RegExp]",ke="[object String]",Se=Object.prototype.toString,Ae=Object.prototype.hasOwnProperty,je=Se.call(arguments)==me,De=Error.prototype,_e=Object.prototype,We=_e.propertyIsEnumerable;try{ve=!(Se.call(document)==Ne&&!({toString:0}+""))}catch(Re){ve=!0}var Te=["constructor","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","toLocaleString","toString","valueOf"],qe={};qe[ge]=qe[we]=qe[Ce]={constructor:!0,toLocaleString:!0,toString:!0,valueOf:!0},qe[ye]=qe[ke]={constructor:!0,toString:!0,valueOf:!0},qe[xe]=qe[Ee]=qe[Oe]={constructor:!0,toString:!0},qe[Ne]={constructor:!0};var Pe={};!function(){var t=function(){this.x=1},e=[];t.prototype={valueOf:1,y:1};for(var n in new t)e.push(n);for(n in arguments);Pe.enumErrorProps=We.call(De,"message")||We.call(De,"name"),Pe.enumPrototypes=We.call(t,"prototype"),Pe.nonEnumArgs=0!=n,Pe.nonEnumShadows=!/valueOf/.test(e)}(1),je||(a=function(t){return t&&"object"==typeof t?Ae.call(t,"callee"):!1}),l(/x/)&&(l=function(t){return"function"==typeof t&&Se.call(t)==Ee});var Le=ne.internals.isEqual=function(t,e){return f(t,e,[],[])},Ve=Array.prototype.slice,Me=({}.hasOwnProperty,this.inherits=ne.internals.inherits=function(t,e){function n(){this.constructor=t}n.prototype=e.prototype,t.prototype=new n}),ze=ne.internals.addProperties=function(t){for(var e=Ve.call(arguments,1),n=0,r=e.length;r>n;n++){var i=e[n];for(var o in i)t[o]=i[o]}},Ue=ne.internals.addRef=function(t,e){return new ar(function(n){return new Fe(e.getDisposable(),t.subscribe(n))})},Ie=function(t,e){this.id=t,this.value=e};Ie.prototype.compareTo=function(t){var e=this.value.compareTo(t.value);return 0===e&&(e=this.id-t.id),e};var Be=ne.internals.PriorityQueue=function(t){this.items=new Array(t),this.length=0},He=Be.prototype;He.isHigherPriority=function(t,e){return this.items[t].compareTo(this.items[e])<0},He.percolate=function(t){if(!(t>=this.length||0>t)){var e=t-1>>1;if(!(0>e||e===t)&&this.isHigherPriority(t,e)){var n=this.items[t];this.items[t]=this.items[e],this.items[e]=n,this.percolate(e)}}},He.heapify=function(e){if(e===t&&(e=0),!(e>=this.length||0>e)){var n=2*e+1,r=2*e+2,i=e;if(ne;e++)t[e].dispose()}},$e.clear=function(){var t=this.disposables.slice(0);this.disposables=[],this.length=0;for(var e=0,n=t.length;n>e;e++)t[e].dispose()},$e.contains=function(t){return-1!==this.disposables.indexOf(t)},$e.toArray=function(){return this.disposables.slice(0)};var Je=ne.Disposable=function(t){this.isDisposed=!1,this.action=t||re};Je.prototype.dispose=function(){this.isDisposed||(this.action(),this.isDisposed=!0)};var Ge=Je.create=function(t){return new Je(t)},Xe=Je.empty={dispose:re},Ke=function(){function t(t){this.isSingle=t,this.isDisposed=!1,this.current=null}var e=t.prototype;return e.getDisposable=function(){return this.current},e.setDisposable=function(t){if(this.current&&this.isSingle)throw new Error("Disposable has already been assigned");var e,n=this.isDisposed;n||(e=this.current,this.current=t),e&&e.dispose(),n&&t&&t.dispose()},e.dispose=function(){var t;this.isDisposed||(this.isDisposed=!0,t=this.current,this.current=null),t&&t.dispose()},t}(),Qe=ne.SingleAssignmentDisposable=function(t){function e(){t.call(this,!0)}return Me(e,t),e}(Ke),Ze=ne.SerialDisposable=function(t){function e(){t.call(this,!1)}return Me(e,t),e}(Ke),Ye=ne.RefCountDisposable=function(){function t(t){this.disposable=t,this.disposable.count++,this.isInnerDisposed=!1}function e(t){this.underlyingDisposable=t,this.isDisposed=!1,this.isPrimaryDisposed=!1,this.count=0}return t.prototype.dispose=function(){this.disposable.isDisposed||this.isInnerDisposed||(this.isInnerDisposed=!0,this.disposable.count--,0===this.disposable.count&&this.disposable.isPrimaryDisposed&&(this.disposable.isDisposed=!0,this.disposable.underlyingDisposable.dispose()))},e.prototype.dispose=function(){this.isDisposed||this.isPrimaryDisposed||(this.isPrimaryDisposed=!0,0===this.count&&(this.isDisposed=!0,this.underlyingDisposable.dispose()))},e.prototype.getDisposable=function(){return this.isDisposed?Xe:new t(this)},e}();d.prototype.dispose=function(){var t=this;this.scheduler.schedule(function(){t.isDisposed||(t.isDisposed=!0,t.disposable.dispose())})};var tn=ne.internals.ScheduledItem=function(t,e,n,r,i){this.scheduler=t,this.state=e,this.action=n,this.dueTime=r,this.comparer=i||ue,this.disposable=new Qe};tn.prototype.invoke=function(){this.disposable.setDisposable(this.invokeCore())},tn.prototype.compareTo=function(t){return this.comparer(this.dueTime,t.dueTime)},tn.prototype.isCancelled=function(){return this.disposable.isDisposed},tn.prototype.invokeCore=function(){return this.action(this.scheduler,this.state)};var en,nn=ne.Scheduler=function(){function t(t,e,n,r){this.now=t,this._schedule=e,this._scheduleRelative=n,this._scheduleAbsolute=r}function e(t,e){var n=e.first,r=e.second,i=new Fe,o=function(e){r(e,function(e){var n=!1,r=!1,s=t.scheduleWithState(e,function(t,e){return n?i.remove(s):r=!0,o(e),Xe});r||(i.add(s),n=!0)})};return o(n),i}function n(t,e,n){var r=e.first,i=e.second,o=new Fe,s=function(e){i(e,function(e,r){var i=!1,u=!1,c=t[n].call(t,e,r,function(t,e){return i?o.remove(c):u=!0,s(e),Xe});u||(o.add(c),i=!0)})};return s(r),o}function r(t,e){return e(),Xe}var i=t.prototype;return i.catchException=i["catch"]=function(t){return new ln(this,t)},i.schedulePeriodic=function(t,e){return this.schedulePeriodicWithState(null,t,function(){e()})},i.schedulePeriodicWithState=function(t,e,n){var r=t,i=setInterval(function(){r=n(r)},e);return Ge(function(){clearInterval(i)})},i.schedule=function(t){return this._schedule(t,r)},i.scheduleWithState=function(t,e){return this._schedule(t,e)},i.scheduleWithRelative=function(t,e){return this._scheduleRelative(e,t,r)},i.scheduleWithRelativeAndState=function(t,e,n){return this._scheduleRelative(t,e,n)},i.scheduleWithAbsolute=function(t,e){return this._scheduleAbsolute(e,t,r)},i.scheduleWithAbsoluteAndState=function(t,e,n){return this._scheduleAbsolute(t,e,n)},i.scheduleRecursive=function(t){return this.scheduleRecursiveWithState(t,function(t,e){t(function(){e(t)})})},i.scheduleRecursiveWithState=function(t,n){return this.scheduleWithState({first:t,second:n},function(t,n){return e(t,n)})},i.scheduleRecursiveWithRelative=function(t,e){return this.scheduleRecursiveWithRelativeAndState(e,t,function(t,e){t(function(n){e(t,n)})})},i.scheduleRecursiveWithRelativeAndState=function(t,e,r){return this._scheduleRelative({first:t,second:r},e,function(t,e){return n(t,e,"scheduleWithRelativeAndState")})},i.scheduleRecursiveWithAbsolute=function(t,e){return this.scheduleRecursiveWithAbsoluteAndState(e,t,function(t,e){t(function(n){e(t,n)})})},i.scheduleRecursiveWithAbsoluteAndState=function(t,e,r){return this._scheduleAbsolute({first:t,second:r},e,function(t,e){return n(t,e,"scheduleWithAbsoluteAndState")})},t.now=oe,t.normalize=function(t){return 0>t&&(t=0),t},t}(),rn=nn.normalize,on=ne.internals.SchedulePeriodicRecursive=function(){function t(t,e){e(0,this._period);try{this._state=this._action(this._state)}catch(n){throw this._cancel.dispose(),n}}function e(t,e,n,r){this._scheduler=t,this._state=e,this._period=n,this._action=r}return e.prototype.start=function(){var e=new Qe;return this._cancel=e,e.setDisposable(this._scheduler.scheduleRecursiveWithRelativeAndState(0,this._period,t.bind(this))),e},e}(),sn=nn.immediate=function(){function t(t,e){return e(this,t)}function e(t,e,n){for(var r=rn(r);r-this.now()>0;);return n(this,t)}function n(t,e,n){return this.scheduleWithRelativeAndState(t,e-this.now(),n)}return new nn(oe,t,e,n)}(),un=nn.currentThread=function(){function t(t){for(var e;t.length>0;)if(e=t.dequeue(),!e.isCancelled()){for(;e.dueTime-nn.now()>0;);e.isCancelled()||e.invoke() -}}function e(t,e){return this.scheduleWithRelativeAndState(t,0,e)}function n(e,n,r){var o=this.now()+nn.normalize(n),s=new tn(this,e,r,o);if(i)i.enqueue(s);else{i=new Be(4),i.enqueue(s);try{t(i)}catch(u){throw u}finally{i=null}}return s.disposable}function r(t,e,n){return this.scheduleWithRelativeAndState(t,e-this.now(),n)}var i,o=new nn(oe,e,n,r);return o.scheduleRequired=function(){return null===i},o.ensureTrampoline=function(t){return null===i?this.schedule(t):t()},o}(),cn=re;!function(){function t(){if(!Q.postMessage||Q.importScripts)return!1;var t=!1,e=Q.onmessage;return Q.onmessage=function(){t=!0},Q.postMessage("","*"),Q.onmessage=e,t}function e(t){if("string"==typeof t.data&&t.data.substring(0,o.length)===o){var e=t.data.substring(o.length),n=s[e];n(),delete s[e]}}var n=RegExp("^"+String(Se).replace(/[.*+?^${}()|[\]\\]/g,"\\$&").replace(/toString| for [^\]]+/g,".*?")+"$"),r="function"==typeof(r=ee&&te&&ee.setImmediate)&&!n.test(r)&&r,i="function"==typeof(i=ee&&te&&ee.clearImmediate)&&!n.test(i)&&i;if("undefined"!=typeof process&&"[object process]"==={}.toString.call(process))en=process.nextTick;else if("function"==typeof r)en=r,cn=i;else if(t()){var o="ms.rx.schedule"+Math.random(),s={},u=0;Q.addEventListener?Q.addEventListener("message",e,!1):Q.attachEvent("onmessage",e,!1),en=function(t){var e=u++;s[e]=t,Q.postMessage(o+e,"*")}}else if(Q.MessageChannel){var c=new Q.MessageChannel,a={},l=0;c.port1.onmessage=function(t){var e=t.data,n=a[e];n(),delete a[e]},en=function(t){var e=l++;a[e]=t,c.port2.postMessage(e)}}else"document"in Q&&"onreadystatechange"in Q.document.createElement("script")?en=function(t){var e=Q.document.createElement("script");e.onreadystatechange=function(){t(),e.onreadystatechange=null,e.parentNode.removeChild(e),e=null},Q.document.documentElement.appendChild(e)}:(en=function(t){return setTimeout(t,0)},cn=clearTimeout)}();var an=nn.timeout=function(){function t(t,e){var n=this,r=new Qe,i=en(function(){r.isDisposed||r.setDisposable(e(n,t))});return new Fe(r,Ge(function(){cn(i)}))}function e(t,e,n){var r=this,i=nn.normalize(e);if(0===i)return r.scheduleWithState(t,n);var o=new Qe,s=setTimeout(function(){o.isDisposed||o.setDisposable(n(r,t))},i);return new Fe(o,Ge(function(){clearTimeout(s)}))}function n(t,e,n){return this.scheduleWithRelativeAndState(t,e-this.now(),n)}return new nn(oe,t,e,n)}(),ln=function(t){function e(){return this._scheduler.now()}function n(t,e){return this._scheduler.scheduleWithState(t,this._wrap(e))}function r(t,e,n){return this._scheduler.scheduleWithRelativeAndState(t,e,this._wrap(n))}function i(t,e,n){return this._scheduler.scheduleWithAbsoluteAndState(t,e,this._wrap(n))}function o(o,s){this._scheduler=o,this._handler=s,this._recursiveOriginal=null,this._recursiveWrapper=null,t.call(this,e,n,r,i)}return Me(o,t),o.prototype._clone=function(t){return new o(t,this._handler)},o.prototype._wrap=function(t){var e=this;return function(n,r){try{return t(e._getRecursiveWrapper(n),r)}catch(i){if(!e._handler(i))throw i;return Xe}}},o.prototype._getRecursiveWrapper=function(t){if(this._recursiveOriginal!==t){this._recursiveOriginal=t;var e=this._clone(t);e._recursiveOriginal=t,e._recursiveWrapper=e,this._recursiveWrapper=e}return this._recursiveWrapper},o.prototype.schedulePeriodicWithState=function(t,e,n){var r=this,i=!1,o=new Qe;return o.setDisposable(this._scheduler.schedulePeriodicWithState(t,e,function(t){if(i)return null;try{return n(t)}catch(e){if(i=!0,!r._handler(e))throw e;return o.dispose(),null}})),o},o}(nn),fn=ne.Notification=function(){function t(t,e){this.hasValue=null==e?!1:e,this.kind=t}var e=t.prototype;return e.accept=function(t,e,n){return 1===arguments.length&&"object"==typeof t?this._acceptObservable(t):this._accept(t,e,n)},e.toObservable=function(t){var e=this;return t||(t=sn),new ar(function(n){return t.schedule(function(){e._acceptObservable(n),"N"===e.kind&&n.onCompleted()})})},t}(),hn=fn.createOnNext=function(){function t(t){return t(this.value)}function e(t){return t.onNext(this.value)}function n(){return"OnNext("+this.value+")"}return function(r){var i=new fn("N",!0);return i.value=r,i._accept=t,i._acceptObservable=e,i.toString=n,i}}(),pn=fn.createOnError=function(){function t(t,e){return e(this.exception)}function e(t){return t.onError(this.exception)}function n(){return"OnError("+this.exception+")"}return function(r){var i=new fn("E");return i.exception=r,i._accept=t,i._acceptObservable=e,i.toString=n,i}}(),dn=fn.createOnCompleted=function(){function t(t,e,n){return n()}function e(t){return t.onCompleted()}function n(){return"OnCompleted()"}return function(){var r=new fn("C");return r._accept=t,r._acceptObservable=e,r.toString=n,r}}(),vn=ne.internals.Enumerator=function(t){this._next=t};vn.prototype.next=function(){return this._next()},vn.prototype[de]=function(){return this};var bn=ne.internals.Enumerable=function(t){this._iterator=t};bn.prototype[de]=function(){return this._iterator()},bn.prototype.concat=function(){var t=this;return new ar(function(e){var n;try{n=t[de]()}catch(r){return void e.onError()}var i,o=new Ze,s=sn.scheduleRecursive(function(t){var r;if(!i){try{r=n.next()}catch(s){return void e.onError(s)}if(r.done)return void e.onCompleted();var u=r.value;le(u)&&(u=An(u));var c=new Qe;o.setDisposable(c),c.setDisposable(u.subscribe(e.onNext.bind(e),e.onError.bind(e),function(){t()}))}});return new Fe(o,s,Ge(function(){i=!0}))})},bn.prototype.catchException=function(){var t=this;return new ar(function(e){var n;try{n=t[de]()}catch(r){return void e.onError()}var i,o,s=new Ze,u=sn.scheduleRecursive(function(t){if(!i){var r;try{r=n.next()}catch(u){return void e.onError(u)}if(r.done)return void(o?e.onError(o):e.onCompleted());var c=r.value;le(c)&&(c=An(c));var a=new Qe;s.setDisposable(a),a.setDisposable(c.subscribe(e.onNext.bind(e),function(e){o=e,t()},e.onCompleted.bind(e)))}});return new Fe(s,u,Ge(function(){i=!0}))})};var mn=bn.repeat=function(t,e){return null==e&&(e=-1),new bn(function(){var n=e;return new vn(function(){return 0===n?be:(n>0&&n--,{done:!1,value:t})})})},gn=bn.forEach=function(t,e,n){return e||(e=ie),new bn(function(){var r=-1;return new vn(function(){return++r0&&(t=!this.isAcquired,this.isAcquired=!0),t&&this.disposable.setDisposable(this.scheduler.scheduleRecursive(function(t){var n;if(!(e.queue.length>0))return void(e.isAcquired=!1);n=e.queue.shift();try{n()}catch(r){throw e.queue=[],e.hasFaulted=!0,r}t()}))},e.prototype.dispose=function(){t.prototype.dispose.call(this),this.disposable.dispose()},e}(En),kn=function(t){function e(){t.apply(this,arguments)}return Me(e,t),e.prototype.next=function(e){t.prototype.next.call(this,e),this.ensureActive()},e.prototype.error=function(e){t.prototype.error.call(this,e),this.ensureActive()},e.prototype.completed=function(){t.prototype.completed.call(this),this.ensureActive()},e}(On),Sn=ne.Observable=function(){function t(t){this._subscribe=t}return xn=t.prototype,xn.subscribe=xn.forEach=function(t,e,n){var r="object"==typeof t?t:wn(t,e,n);return this._subscribe(r)},t}();xn.observeOn=function(t){var e=this;return new ar(function(n){return e.subscribe(new kn(t,n))})},xn.subscribeOn=function(t){var e=this;return new ar(function(n){var r=new Qe,i=new Ze;return i.setDisposable(r),r.setDisposable(t.schedule(function(){i.setDisposable(new d(t,e.subscribe(n)))})),i})};var An=Sn.fromPromise=function(t){return new ar(function(e){return t.then(function(t){e.onNext(t),e.onCompleted()},function(t){e.onError(t)}),function(){t&&t.abort&&t.abort()}})};xn.toPromise=function(t){if(t||(t=ne.config.Promise),!t)throw new Error("Promise type not provided nor in Rx.config.Promise");var e=this;return new t(function(t,n){var r,i=!1;e.subscribe(function(t){r=t,i=!0},function(t){n(t)},function(){i&&t(r)})})},xn.toArray=function(){var t=this;return new ar(function(e){var n=[];return t.subscribe(n.push.bind(n),e.onError.bind(e),function(){e.onNext(n),e.onCompleted()})})},Sn.create=Sn.createWithDisposable=function(t){return new ar(t)};var jn=Sn.defer=function(t){return new ar(function(e){var n;try{n=t()}catch(r){return Tn(r).subscribe(e)}return le(n)&&(n=An(n)),n.subscribe(e)})},Dn=Sn.empty=function(t){return t||(t=sn),new ar(function(e){return t.schedule(function(){e.onCompleted()})})},_n=Sn.fromArray=function(t,e){return e||(e=un),new ar(function(n){var r=0,i=t.length;return e.scheduleRecursive(function(e){i>r?(n.onNext(t[r++]),e()):n.onCompleted()})})};Sn.fromIterable=function(t,e){return e||(e=un),new ar(function(n){var r;try{r=t[de]()}catch(i){return void n.onError(i)}return e.scheduleRecursive(function(t){var e;try{e=r.next()}catch(i){return void n.onError(i)}e.done?n.onCompleted():(n.onNext(e.value),t())})})},Sn.generate=function(t,e,n,r,i){return i||(i=un),new ar(function(o){var s=!0,u=t;return i.scheduleRecursive(function(t){var i,c;try{s?s=!1:u=n(u),i=e(u),i&&(c=r(u))}catch(a){return void o.onError(a)}i?(o.onNext(c),t()):o.onCompleted()})})},Sn.of=function(){for(var t=arguments.length,e=new Array(t),n=0;t>n;n++)e[n]=arguments[n];return _n(e)};var Wn=(Sn.ofWithScheduler=function(t){for(var e=arguments.length-1,n=new Array(e),r=0;e>r;r++)n[r]=arguments[r+1];return _n(n,t)},Sn.never=function(){return new ar(function(){return Xe})});Sn.range=function(t,e,n){return n||(n=un),new ar(function(r){return n.scheduleRecursiveWithState(0,function(n,i){e>n?(r.onNext(t+n),i(n+1)):r.onCompleted()})})},Sn.repeat=function(t,e,n){return n||(n=un),null==e&&(e=-1),Rn(t,n).repeat(e)};var Rn=Sn["return"]=Sn.returnValue=Sn.just=function(t,e){return e||(e=sn),new ar(function(n){return e.schedule(function(){n.onNext(t),n.onCompleted()})})},Tn=Sn["throw"]=Sn.throwException=function(t,e){return e||(e=sn),new ar(function(n){return e.schedule(function(){n.onError(t)})})};Sn.using=function(t,e){return new ar(function(n){var r,i,o=Xe;try{r=t(),r&&(o=r),i=e(r)}catch(s){return new Fe(Tn(s).subscribe(n),o)}return new Fe(i.subscribe(n),o)})},xn.amb=function(t){var e=this;return new ar(function(n){function r(){o||(o=s,a.dispose())}function i(){o||(o=u,c.dispose())}var o,s="L",u="R",c=new Qe,a=new Qe;return le(t)&&(t=An(t)),c.setDisposable(e.subscribe(function(t){r(),o===s&&n.onNext(t)},function(t){r(),o===s&&n.onError(t)},function(){r(),o===s&&n.onCompleted()})),a.setDisposable(t.subscribe(function(t){i(),o===u&&n.onNext(t)},function(t){i(),o===u&&n.onError(t)},function(){i(),o===u&&n.onCompleted()})),new Fe(c,a)})},Sn.amb=function(){function t(t,e){return t.amb(e)}for(var e=Wn(),n=h(arguments,0),r=0,i=n.length;i>r;r++)e=t(e,n[r]);return e},xn["catch"]=xn.catchException=function(t){return"function"==typeof t?v(this,t):qn([this,t])};var qn=Sn.catchException=Sn["catch"]=function(){var t=h(arguments,0);return gn(t).catchException()};xn.combineLatest=function(){var t=Ve.call(arguments);return Array.isArray(t[0])?t[0].unshift(this):t.unshift(this),Pn.apply(this,t)};var Pn=Sn.combineLatest=function(){var t=Ve.call(arguments),e=t.pop();return Array.isArray(t[0])&&(t=t[0]),new ar(function(n){function r(t){var r;if(u[t]=!0,c||(c=u.every(ie))){try{r=e.apply(null,l)}catch(i){return void n.onError(i)}n.onNext(r)}else a.filter(function(e,n){return n!==t}).every(ie)&&n.onCompleted()}function i(t){a[t]=!0,a.every(ie)&&n.onCompleted()}for(var o=function(){return!1},s=t.length,u=p(s,o),c=!1,a=p(s,o),l=new Array(s),f=new Array(s),h=0;s>h;h++)!function(e){var o=t[e],s=new Qe;le(o)&&(o=An(o)),s.setDisposable(o.subscribe(function(t){l[e]=t,r(e)},n.onError.bind(n),function(){i(e)})),f[e]=s}(h);return new Fe(f)})};xn.concat=function(){var t=Ve.call(arguments,0);return t.unshift(this),Ln.apply(this,t)};var Ln=Sn.concat=function(){var t=h(arguments,0);return gn(t).concat()};xn.concatObservable=xn.concatAll=function(){return this.merge(1)},xn.merge=function(t){if("number"!=typeof t)return Vn(this,t);var e=this;return new ar(function(n){var r=0,i=new Fe,o=!1,s=[],u=function(t){var e=new Qe;i.add(e),le(t)&&(t=An(t)),e.setDisposable(t.subscribe(n.onNext.bind(n),n.onError.bind(n),function(){var t;i.remove(e),s.length>0?(t=s.shift(),u(t)):(r--,o&&0===r&&n.onCompleted())}))};return i.add(e.subscribe(function(e){t>r?(r++,u(e)):s.push(e)},n.onError.bind(n),function(){o=!0,0===r&&n.onCompleted()})),i})};var Vn=Sn.merge=function(){var t,e;return arguments[0]?arguments[0].now?(t=arguments[0],e=Ve.call(arguments,1)):(t=sn,e=Ve.call(arguments,0)):(t=sn,e=Ve.call(arguments,1)),Array.isArray(e[0])&&(e=e[0]),_n(e,t).mergeObservable()};xn.mergeObservable=xn.mergeAll=function(){var t=this;return new ar(function(e){var n=new Fe,r=!1,i=new Qe;return n.add(i),i.setDisposable(t.subscribe(function(t){var i=new Qe;n.add(i),le(t)&&(t=An(t)),i.setDisposable(t.subscribe(function(t){e.onNext(t)},e.onError.bind(e),function(){n.remove(i),r&&1===n.length&&e.onCompleted()}))},e.onError.bind(e),function(){r=!0,1===n.length&&e.onCompleted()})),n})},xn.onErrorResumeNext=function(t){if(!t)throw new Error("Second observable is required");return Mn([this,t])};var Mn=Sn.onErrorResumeNext=function(){var t=h(arguments,0);return new ar(function(e){var n=0,r=new Ze,i=sn.scheduleRecursive(function(i){var o,s;n0})){try{o=u.map(function(t){return t.shift()}),i=n.apply(t,o)}catch(s){return void r.onError(s)}r.onNext(i)}else c.filter(function(t,n){return n!==e}).every(ie)&&r.onCompleted()}function o(t){c[t]=!0,c.every(function(t){return t})&&r.onCompleted()}for(var s=e.length,u=p(s,function(){return[]}),c=p(s,function(){return!1}),a=new Array(s),l=0;s>l;l++)!function(t){var n=e[t],s=new Qe;le(n)&&(n=An(n)),s.setDisposable(n.subscribe(function(e){u[t].push(e),i(t)},r.onError.bind(r),function(){o(t)})),a[t]=s}(l);return new Fe(a)})},Sn.zip=function(){var t=Ve.call(arguments,0),e=t.shift();return e.zip.apply(e,t)},Sn.zipArray=function(){var t=h(arguments,0);return new ar(function(e){function n(t){if(o.every(function(t){return t.length>0})){var n=o.map(function(t){return t.shift()});e.onNext(n)}else if(s.filter(function(e,n){return n!==t}).every(ie))return void e.onCompleted()}function r(t){return s[t]=!0,s.every(ie)?void e.onCompleted():void 0}for(var i=t.length,o=p(i,function(){return[]}),s=p(i,function(){return!1}),u=new Array(i),c=0;i>c;c++)!function(i){u[i]=new Qe,u[i].setDisposable(t[i].subscribe(function(t){o[i].push(t),n(i)},e.onError.bind(e),function(){r(i)}))}(c);var a=new Fe(u);return a.add(Ge(function(){for(var t=0,e=o.length;e>t;t++)o[t]=[]})),a})},xn.asObservable=function(){var t=this;return new ar(function(e){return t.subscribe(e)})},xn.bufferWithCount=function(t,e){return"number"!=typeof e&&(e=t),this.windowWithCount(t,e).selectMany(function(t){return t.toArray()}).where(function(t){return t.length>0})},xn.dematerialize=function(){var t=this;return new ar(function(e){return t.subscribe(function(t){return t.accept(e)},e.onError.bind(e),e.onCompleted.bind(e))})},xn.distinctUntilChanged=function(t,e){var n=this;return t||(t=ie),e||(e=se),new ar(function(r){var i,o=!1;return n.subscribe(function(n){var s,u=!1;try{s=t(n)}catch(c){return void r.onError(c)}if(o)try{u=e(i,s)}catch(c){return void r.onError(c)}o&&u||(o=!0,i=s,r.onNext(n))},r.onError.bind(r),r.onCompleted.bind(r))})},xn["do"]=xn.doAction=function(t,e,n){var r,i=this;return"function"==typeof t?r=t:(r=t.onNext.bind(t),e=t.onError.bind(t),n=t.onCompleted.bind(t)),new ar(function(t){return i.subscribe(function(e){try{r(e)}catch(n){t.onError(n)}t.onNext(e)},function(n){if(e){try{e(n)}catch(r){t.onError(r)}t.onError(n)}else t.onError(n)},function(){if(n){try{n()}catch(e){t.onError(e)}t.onCompleted()}else t.onCompleted()})})},xn["finally"]=xn.finallyAction=function(t){var e=this;return new ar(function(n){var r;try{r=e.subscribe(n)}catch(i){throw t(),i}return Ge(function(){try{r.dispose()}catch(e){throw e}finally{t()}})})},xn.ignoreElements=function(){var t=this;return new ar(function(e){return t.subscribe(re,e.onError.bind(e),e.onCompleted.bind(e))})},xn.materialize=function(){var t=this;return new ar(function(e){return t.subscribe(function(t){e.onNext(hn(t))},function(t){e.onNext(pn(t)),e.onCompleted()},function(){e.onNext(dn()),e.onCompleted()})})},xn.repeat=function(t){return mn(this,t).concat()},xn.retry=function(t){return mn(this,t).catchException()},xn.scan=function(){var t,e,n=!1,r=this;return 2===arguments.length?(n=!0,t=arguments[0],e=arguments[1]):e=arguments[0],new ar(function(i){var o,s,u;return r.subscribe(function(r){try{u||(u=!0),o?s=e(s,r):(s=n?e(t,r):r,o=!0)}catch(c){return void i.onError(c)}i.onNext(s)},i.onError.bind(i),function(){!u&&n&&i.onNext(t),i.onCompleted()})})},xn.skipLast=function(t){var e=this;return new ar(function(n){var r=[];return e.subscribe(function(e){r.push(e),r.length>t&&n.onNext(r.shift())},n.onError.bind(n),n.onCompleted.bind(n))})},xn.startWith=function(){var t,e,n=0;return arguments.length&&"now"in Object(arguments[0])?(e=arguments[0],n=1):e=sn,t=Ve.call(arguments,n),gn([_n(t,e),this]).concat()},xn.takeLast=function(t,e){return this.takeLastBuffer(t).selectMany(function(t){return _n(t,e)})},xn.takeLastBuffer=function(t){var e=this;return new ar(function(n){var r=[];return e.subscribe(function(e){r.push(e),r.length>t&&r.shift()},n.onError.bind(n),function(){n.onNext(r),n.onCompleted()})})},xn.windowWithCount=function(t,e){var n=this;if(0>=t)throw new Error(he);if(1===arguments.length&&(e=t),0>=e)throw new Error(he);return new ar(function(r){var i=new Qe,o=new Ye(i),s=0,u=[],c=function(){var t=new hr;u.push(t),r.onNext(Ue(t,o))};return c(),i.setDisposable(n.subscribe(function(n){for(var r,i=0,o=u.length;o>i;i++)u[i].onNext(n);var a=s-t+1;a>=0&&a%e===0&&(r=u.shift(),r.onCompleted()),s++,s%e===0&&c()},function(t){for(;u.length>0;)u.shift().onError(t);r.onError(t)},function(){for(;u.length>0;)u.shift().onCompleted();r.onCompleted()})),o})},xn.selectConcat=xn.concatMap=function(t,e){return e?this.concatMap(function(n,r){var i=t(n,r),o=le(i)?An(i):i;return o.map(function(t){return e(n,t,r)})}):"function"==typeof t?m.call(this,t):m.call(this,function(){return t})},xn.defaultIfEmpty=function(e){var n=this;return e===t&&(e=null),new ar(function(t){var r=!1;return n.subscribe(function(e){r=!0,t.onNext(e)},t.onError.bind(t),function(){r||t.onNext(e),t.onCompleted()})})},xn.distinct=function(t,e){var n=this;return t||(t=ie),e||(e=ce),new ar(function(r){var i={};return n.subscribe(function(n){var o,s,u,c=!1;try{o=t(n),s=e(o)}catch(a){return void r.onError(a)}for(u in i)if(s===u){c=!0;break}c||(i[s]=null,r.onNext(n))},r.onError.bind(r),r.onCompleted.bind(r))})},xn.groupBy=function(t,e,n){return this.groupByUntil(t,e,function(){return Wn()},n)},xn.groupByUntil=function(t,e,n,r){var i=this;return e||(e=ie),r||(r=ce),new ar(function(o){var s={},u=new Fe,c=new Ye(u);return u.add(i.subscribe(function(i){var a,l,f,h,p,d,v,b,m,g;try{d=t(i),v=r(d)}catch(y){for(g in s)s[g].onError(y);return void o.onError(y)}h=!1;try{m=s[v],m||(m=new hr,s[v]=m,h=!0)}catch(y){for(g in s)s[g].onError(y);return void o.onError(y)}if(h){p=new fr(d,m,c),l=new fr(d,m);try{a=n(l)}catch(y){for(g in s)s[g].onError(y);return void o.onError(y)}o.onNext(p),b=new Qe,u.add(b);var w=function(){v in s&&(delete s[v],m.onCompleted()),u.remove(b)};b.setDisposable(a.take(1).subscribe(re,function(t){for(g in s)s[g].onError(t);o.onError(t)},function(){w()}))}try{f=e(i)}catch(y){for(g in s)s[g].onError(y);return void o.onError(y)}m.onNext(f)},function(t){for(var e in s)s[e].onError(t);o.onError(t)},function(){for(var t in s)s[t].onCompleted();o.onCompleted()})),c})},xn.select=xn.map=function(t,e){var n=this;return new ar(function(r){var i=0;return n.subscribe(function(o){var s;try{s=t.call(e,o,i++,n)}catch(u){return void r.onError(u)}r.onNext(s)},r.onError.bind(r),r.onCompleted.bind(r))})},xn.pluck=function(t){return this.select(function(e){return e[t]})},xn.selectMany=xn.flatMap=function(t,e){return e?this.selectMany(function(n,r){var i=t(n,r),o=le(i)?An(i):i;return o.select(function(t){return e(n,t,r)})}):"function"==typeof t?g.call(this,t):g.call(this,function(){return t})},xn.selectSwitch=xn.flatMapLatest=xn.switchMap=function(t,e){return this.select(t,e).switchLatest()},xn.skip=function(t){if(0>t)throw new Error(he);var e=this;return new ar(function(n){var r=t;return e.subscribe(function(t){0>=r?n.onNext(t):r--},n.onError.bind(n),n.onCompleted.bind(n))})},xn.skipWhile=function(t,e){var n=this;return new ar(function(r){var i=0,o=!1;return n.subscribe(function(s){if(!o)try{o=!t.call(e,s,i++,n)}catch(u){return void r.onError(u)}o&&r.onNext(s)},r.onError.bind(r),r.onCompleted.bind(r))})},xn.take=function(t,e){if(0>t)throw new Error(he);if(0===t)return Dn(e);var n=this;return new ar(function(e){var r=t;return n.subscribe(function(t){r>0&&(r--,e.onNext(t),0===r&&e.onCompleted())},e.onError.bind(e),e.onCompleted.bind(e))})},xn.takeWhile=function(t,e){var n=this;return new ar(function(r){var i=0,o=!0;return n.subscribe(function(s){if(o){try{o=t.call(e,s,i++,n)}catch(u){return void r.onError(u)}o?r.onNext(s):r.onCompleted()}},r.onError.bind(r),r.onCompleted.bind(r))})},xn.where=xn.filter=function(t,e){var n=this;return new ar(function(r){var i=0;return n.subscribe(function(o){var s;try{s=t.call(e,o,i++,n)}catch(u){return void r.onError(u)}s&&r.onNext(o)},r.onError.bind(r),r.onCompleted.bind(r))})},xn.finalValue=function(){var t=this;return new ar(function(e){var n,r=!1;return t.subscribe(function(t){r=!0,n=t},e.onError.bind(e),function(){r?(e.onNext(n),e.onCompleted()):e.onError(new Error(fe))})})},xn.aggregate=function(){var t,e,n;return 2===arguments.length?(t=arguments[0],e=!0,n=arguments[1]):n=arguments[0],e?this.scan(t,n).startWith(t).finalValue():this.scan(n).finalValue()},xn.reduce=function(t){var e,n;return 2===arguments.length&&(n=!0,e=arguments[1]),n?this.scan(e,t).startWith(e).finalValue():this.scan(t).finalValue()},xn.some=xn.any=function(t,e){var n=this;return t?n.where(t,e).any():new ar(function(t){return n.subscribe(function(){t.onNext(!0),t.onCompleted()},t.onError.bind(t),function(){t.onNext(!1),t.onCompleted()})})},xn.isEmpty=function(){return this.any().select(function(t){return!t})},xn.every=xn.all=function(t,e){return this.where(function(e){return!t(e)},e).any().select(function(t){return!t})},xn.contains=function(t,e){return e||(e=se),this.where(function(n){return e(n,t)}).any()},xn.count=function(t,e){return t?this.where(t,e).count():this.aggregate(0,function(t){return t+1})},xn.sum=function(t,e){return t?this.select(t,e).sum():this.aggregate(0,function(t,e){return t+e})},xn.minBy=function(t,e){return e||(e=ue),y(this,t,function(t,n){return-1*e(t,n)})},xn.min=function(t){return this.minBy(ie,t).select(function(t){return w(t)})},xn.maxBy=function(t,e){return e||(e=ue),y(this,t,e)},xn.max=function(t){return this.maxBy(ie,t).select(function(t){return w(t)})},xn.average=function(t,e){return t?this.select(t,e).average():this.scan({sum:0,count:0},function(t,e){return{sum:t.sum+e,count:t.count+1}}).finalValue().select(function(t){if(0===t.count)throw new Error("The input sequence was empty");return t.sum/t.count})},xn.sequenceEqual=function(t,e){var n=this;return e||(e=se),Array.isArray(t)?x(n,t,e):new ar(function(r){var i=!1,o=!1,s=[],u=[],c=n.subscribe(function(t){var n,i;if(u.length>0){i=u.shift();try{n=e(i,t)}catch(c){return void r.onError(c)}n||(r.onNext(!1),r.onCompleted())}else o?(r.onNext(!1),r.onCompleted()):s.push(t)},r.onError.bind(r),function(){i=!0,0===s.length&&(u.length>0?(r.onNext(!1),r.onCompleted()):o&&(r.onNext(!0),r.onCompleted()))});le(t)&&(t=An(t));var a=t.subscribe(function(t){var n,o;if(s.length>0){o=s.shift();try{n=e(o,t)}catch(c){return void r.onError(c)}n||(r.onNext(!1),r.onCompleted())}else i?(r.onNext(!1),r.onCompleted()):u.push(t)},r.onError.bind(r),function(){o=!0,0===u.length&&(s.length>0?(r.onNext(!1),r.onCompleted()):i&&(r.onNext(!0),r.onCompleted()))});return new Fe(c,a)})},xn.elementAt=function(t){return E(this,t,!1)},xn.elementAtOrDefault=function(t,e){return E(this,t,!0,e)},xn.single=function(t,e){return t?this.where(t,e).single():C(this,!1)},xn.singleOrDefault=function(t,e,n){return t?this.where(t,n).singleOrDefault(null,e):C(this,!0,e)},xn.first=function(t,e){return t?this.where(t,e).first():N(this,!1)},xn.firstOrDefault=function(t,e){return t?this.where(t).firstOrDefault(null,e):N(this,!0,e)},xn.last=function(t,e){return t?this.where(t,e).last():O(this,!1)},xn.lastOrDefault=function(t,e,n){return t?this.where(t,n).lastOrDefault(null,e):O(this,!0,e)},xn.find=function(t,e){return k(this,t,e,!1)},xn.findIndex=function(t,e){return k(this,t,e,!0)},Sn.start=function(t,e,n){return zn(t,e,n)()};var zn=Sn.toAsync=function(t,e,n){return e||(e=an),function(){var r=arguments,i=new pr;return e.schedule(function(){var e;try{e=t.apply(n,r)}catch(o){return void i.onError(o)}i.onNext(e),i.onCompleted()}),i.asObservable()}};Sn.fromCallback=function(t,e,n,r){return e||(e=sn),function(){var i=Ve.call(arguments,0);return new ar(function(o){return e.schedule(function(){function e(t){var e=t;if(r)try{e=r(arguments)}catch(n){return void o.onError(n)}else 1===e.length&&(e=e[0]);o.onNext(e),o.onCompleted()}i.push(e),t.apply(n,i)})})}},Sn.fromNodeCallback=function(t,e,n,r){return e||(e=sn),function(){var i=Ve.call(arguments,0);return new ar(function(o){return e.schedule(function(){function e(t){if(t)return void o.onError(t);var e=Ve.call(arguments,1);if(r)try{e=r(e)}catch(n){return void o.onError(n)}else 1===e.length&&(e=e[0]);o.onNext(e),o.onCompleted()}i.push(e),t.apply(n,i)})})}};var Un=Q.angular&&angular.element?angular.element:Q.jQuery?Q.jQuery:Q.Zepto?Q.Zepto:null,In=!!Q.Ember&&"function"==typeof Q.Ember.addListener;Sn.fromEvent=function(t,e,n){if(In)return Bn(function(n){Ember.addListener(t,e,n)},function(n){Ember.removeListener(t,e,n)},n);if(Un){var r=Un(t);return Bn(function(t){r.on(e,t)},function(t){r.off(e,t)},n)}return new ar(function(r){return A(t,e,function(t){var e=t;if(n)try{e=n(arguments)}catch(i){return void r.onError(i)}r.onNext(e)})}).publish().refCount()};var Bn=Sn.fromEventPattern=function(t,e,n){return new ar(function(r){function i(t){var e=t;if(n)try{e=n(arguments)}catch(i){return void r.onError(i)}r.onNext(e)}var o=t(i);return Ge(function(){e&&e(i,o)})}).publish().refCount()};Sn.startAsync=function(t){var e;try{e=t()}catch(n){return Tn(n)}return An(e)};var Hn=function(t){function e(t){var e=this.source.publish(),n=e.subscribe(t),r=Xe,i=this.subject.distinctUntilChanged().subscribe(function(t){t?r=e.connect():(r.dispose(),r=Xe)});return new Fe(n,r,i)}function n(n,r){this.source=n,this.subject=r||new hr,this.isPaused=!0,t.call(this,e)}return Me(n,t),n.prototype.pause=function(){this.isPaused!==!0&&(this.isPaused=!0,this.subject.onNext(!1))},n.prototype.resume=function(){this.isPaused!==!1&&(this.isPaused=!1,this.subject.onNext(!0))},n}(Sn);xn.pausable=function(t){return new Hn(this,t)};var Fn=function(t){function e(t){var e=[],n=!0,r=j(this.source,this.subject.distinctUntilChanged(),function(t,e){return{data:t,shouldFire:e}}).subscribe(function(r){if(r.shouldFire&&n&&t.onNext(r.data),r.shouldFire&&!n){for(;e.length>0;)t.onNext(e.shift());n=!0}else r.shouldFire||n?!r.shouldFire&&n&&(n=!1):e.push(r.data)},function(n){for(;e.length>0;)t.onNext(e.shift());t.onError(n)},function(){for(;e.length>0;)t.onNext(e.shift());t.onCompleted()});return this.subject.onNext(!1),r}function n(n,r){this.source=n,this.subject=r||new hr,this.isPaused=!0,t.call(this,e)}return Me(n,t),n.prototype.pause=function(){this.isPaused!==!0&&(this.isPaused=!0,this.subject.onNext(!1))},n.prototype.resume=function(){this.isPaused!==!1&&(this.isPaused=!1,this.subject.onNext(!0))},n}(Sn);xn.pausableBuffered=function(t){return new Fn(this,t)},xn.controlled=function(t){return null==t&&(t=!0),new $n(this,t)};var $n=function(t){function e(t){return this.source.subscribe(t)}function n(n,r){t.call(this,e),this.subject=new Jn(r),this.source=n.multicast(this.subject).refCount()}return Me(n,t),n.prototype.request=function(t){return null==t&&(t=-1),this.subject.request(t)},n}(Sn),Jn=ne.ControlledSubject=function(t){function e(t){return this.subject.subscribe(t)}function n(n){null==n&&(n=!0),t.call(this,e),this.subject=new hr,this.enableQueue=n,this.queue=n?[]:null,this.requestedCount=0,this.requestedDisposable=Xe,this.error=null,this.hasFailed=!1,this.hasCompleted=!1,this.controlledDisposable=Xe -}return Me(n,t),ze(n.prototype,yn,{onCompleted:function(){r.call(this),this.hasCompleted=!0,this.enableQueue&&0!==this.queue.length||this.subject.onCompleted()},onError:function(t){r.call(this),this.hasFailed=!0,this.error=t,this.enableQueue&&0!==this.queue.length||this.subject.onError(t)},onNext:function(t){r.call(this);var e=!1;0===this.requestedCount?this.enableQueue&&this.queue.push(t):(-1!==this.requestedCount&&0===this.requestedCount--&&this.disposeCurrentRequest(),e=!0),e&&this.subject.onNext(t)},_processRequest:function(t){if(this.enableQueue){for(;this.queue.length>=t&&t>0;)this.subject.onNext(this.queue.shift()),t--;return 0!==this.queue.length?{numberOfItems:t,returnValue:!0}:{numberOfItems:t,returnValue:!1}}return this.hasFailed?(this.subject.onError(this.error),this.controlledDisposable.dispose(),this.controlledDisposable=Xe):this.hasCompleted&&(this.subject.onCompleted(),this.controlledDisposable.dispose(),this.controlledDisposable=Xe),{numberOfItems:t,returnValue:!1}},request:function(t){r.call(this),this.disposeCurrentRequest();var e=this,n=this._processRequest(t);return t=n.numberOfItems,n.returnValue?Xe:(this.requestedCount=t,this.requestedDisposable=Ge(function(){e.requestedCount=0}),this.requestedDisposable)},disposeCurrentRequest:function(){this.requestedDisposable.dispose(),this.requestedDisposable=Xe},dispose:function(){this.isDisposed=!0,this.error=null,this.subject.dispose(),this.requestedDisposable.dispose()}}),n}(Sn);xn.multicast=function(t,e){var n=this;return"function"==typeof t?new ar(function(r){var i=n.multicast(t());return new Fe(e(i).subscribe(r),i.connect())}):new Qn(n,t)},xn.publish=function(t){return t?this.multicast(function(){return new hr},t):this.multicast(new hr)},xn.share=function(){return this.publish(null).refCount()},xn.publishLast=function(t){return t?this.multicast(function(){return new pr},t):this.multicast(new pr)},xn.publishValue=function(t,e){return 2===arguments.length?this.multicast(function(){return new Xn(e)},t):this.multicast(new Xn(t))},xn.shareValue=function(t){return this.publishValue(t).refCount()},xn.replay=function(t,e,n,r){return t?this.multicast(function(){return new Kn(e,n,r)},t):this.multicast(new Kn(e,n,r))},xn.shareReplay=function(t,e,n){return this.replay(null,t,e,n).refCount()};var Gn=function(t,e){this.subject=t,this.observer=e};Gn.prototype.dispose=function(){if(!this.subject.isDisposed&&null!==this.observer){var t=this.subject.observers.indexOf(this.observer);this.subject.observers.splice(t,1),this.observer=null}};var Xn=ne.BehaviorSubject=function(t){function e(t){if(r.call(this),!this.isStopped)return this.observers.push(t),t.onNext(this.value),new Gn(this,t);var e=this.exception;return e?t.onError(e):t.onCompleted(),Xe}function n(n){t.call(this,e),this.value=n,this.observers=[],this.isDisposed=!1,this.isStopped=!1,this.exception=null}return Me(n,t),ze(n.prototype,yn,{hasObservers:function(){return this.observers.length>0},onCompleted:function(){if(r.call(this),!this.isStopped){var t=this.observers.slice(0);this.isStopped=!0;for(var e=0,n=t.length;n>e;e++)t[e].onCompleted();this.observers=[]}},onError:function(t){if(r.call(this),!this.isStopped){var e=this.observers.slice(0);this.isStopped=!0,this.exception=t;for(var n=0,i=e.length;i>n;n++)e[n].onError(t);this.observers=[]}},onNext:function(t){if(r.call(this),!this.isStopped){this.value=t;for(var e=this.observers.slice(0),n=0,i=e.length;i>n;n++)e[n].onNext(t)}},dispose:function(){this.isDisposed=!0,this.observers=null,this.value=null,this.exception=null}}),n}(Sn),Kn=ne.ReplaySubject=function(t){function e(t,e){this.subject=t,this.observer=e}function n(t){var n=new On(this.scheduler,t),i=new e(this,n);r.call(this),this._trim(this.scheduler.now()),this.observers.push(n);for(var o=this.q.length,s=0,u=this.q.length;u>s;s++)n.onNext(this.q[s].value);return this.hasError?(o++,n.onError(this.error)):this.isStopped&&(o++,n.onCompleted()),n.ensureActive(o),i}function i(e,r,i){this.bufferSize=null==e?Number.MAX_VALUE:e,this.windowSize=null==r?Number.MAX_VALUE:r,this.scheduler=i||un,this.q=[],this.observers=[],this.isStopped=!1,this.isDisposed=!1,this.hasError=!1,this.error=null,t.call(this,n)}return e.prototype.dispose=function(){if(this.observer.dispose(),!this.subject.isDisposed){var t=this.subject.observers.indexOf(this.observer);this.subject.observers.splice(t,1)}},Me(i,t),ze(i.prototype,yn,{hasObservers:function(){return this.observers.length>0},_trim:function(t){for(;this.q.length>this.bufferSize;)this.q.shift();for(;this.q.length>0&&t-this.q[0].interval>this.windowSize;)this.q.shift()},onNext:function(t){var e;if(r.call(this),!this.isStopped){var n=this.scheduler.now();this.q.push({interval:n,value:t}),this._trim(n);for(var i=this.observers.slice(0),o=0,s=i.length;s>o;o++)e=i[o],e.onNext(t),e.ensureActive()}},onError:function(t){var e;if(r.call(this),!this.isStopped){this.isStopped=!0,this.error=t,this.hasError=!0;var n=this.scheduler.now();this._trim(n);for(var i=this.observers.slice(0),o=0,s=i.length;s>o;o++)e=i[o],e.onError(t),e.ensureActive();this.observers=[]}},onCompleted:function(){var t;if(r.call(this),!this.isStopped){this.isStopped=!0;var e=this.scheduler.now();this._trim(e);for(var n=this.observers.slice(0),i=0,o=n.length;o>i;i++)t=n[i],t.onCompleted(),t.ensureActive();this.observers=[]}},dispose:function(){this.isDisposed=!0,this.observers=null}}),i}(Sn),Qn=ne.ConnectableObservable=function(t){function e(e,n){function r(t){return i.subject.subscribe(t)}var i={subject:n,source:e.asObservable(),hasSubscription:!1,subscription:null};this.connect=function(){return i.hasSubscription||(i.hasSubscription=!0,i.subscription=new Fe(i.source.subscribe(i.subject),Ge(function(){i.hasSubscription=!1}))),i.subscription},t.call(this,r)}return Me(e,t),e.prototype.connect=function(){return this.connect()},e.prototype.refCount=function(){var t=null,e=0,n=this;return new ar(function(r){var i,o;return e++,i=1===e,o=n.subscribe(r),i&&(t=n.connect()),Ge(function(){o.dispose(),e--,0===e&&t.dispose()})})},e}(Sn),Zn=[1,3,7,13,31,61,127,251,509,1021,2039,4093,8191,16381,32749,65521,131071,262139,524287,1048573,2097143,4194301,8388593,16777213,33554393,67108859,134217689,268435399,536870909,1073741789,2147483647],Yn="no such key",tr="duplicate key",er=function(){var t=0;return function(e){if(null==e)throw new Error(Yn);if("string"==typeof e)return W(e);if("number"==typeof e)return R(e);if("boolean"==typeof e)return e===!0?1:0;if(e instanceof Date)return e.getTime();if(e.getHashCode)return e.getHashCode();var n=17*t++;return e.getHashCode=function(){return n},n}}(),nr=function(t,e){if(0>t)throw new Error("out of range");t>0&&this._initialize(t),this.comparer=e||se,this.freeCount=0,this.size=0,this.freeList=-1};nr.prototype._initialize=function(t){var e,n=_(t);for(this.buckets=new Array(n),this.entries=new Array(n),e=0;n>e;e++)this.buckets[e]=-1,this.entries[e]=T();this.freeList=-1},nr.prototype.count=function(){return this.size},nr.prototype.add=function(t,e){return this._insert(t,e,!0)},nr.prototype._insert=function(t,e,n){this.buckets||this._initialize(0);for(var r,i=2147483647&er(t),o=i%this.buckets.length,s=this.buckets[o];s>=0;s=this.entries[s].next)if(this.entries[s].hashCode===i&&this.comparer(this.entries[s].key,t)){if(n)throw new Error(tr);return void(this.entries[s].value=e)}this.freeCount>0?(r=this.freeList,this.freeList=this.entries[r].next,--this.freeCount):(this.size===this.entries.length&&(this._resize(),o=i%this.buckets.length),r=this.size,++this.size),this.entries[r].hashCode=i,this.entries[r].next=this.buckets[o],this.entries[r].key=t,this.entries[r].value=e,this.buckets[o]=r},nr.prototype._resize=function(){var t=_(2*this.size),e=new Array(t);for(r=0;rr;++r)n[r]=T();for(var i=0;i=0;i=this.entries[i].next){if(this.entries[i].hashCode===e&&this.comparer(this.entries[i].key,t))return 0>r?this.buckets[n]=this.entries[i].next:this.entries[r].next=this.entries[i].next,this.entries[i].hashCode=-1,this.entries[i].next=this.freeList,this.entries[i].key=null,this.entries[i].value=null,this.freeList=i,++this.freeCount,!0;r=i}return!1},nr.prototype.clear=function(){var t,e;if(!(this.size<=0)){for(t=0,e=this.buckets.length;e>t;++t)this.buckets[t]=-1;for(t=0;t=0;n=this.entries[n].next)if(this.entries[n].hashCode===e&&this.comparer(this.entries[n].key,t))return n;return-1},nr.prototype.count=function(){return this.size-this.freeCount},nr.prototype.tryGetValue=function(e){var n=this._findEntry(e);return n>=0?this.entries[n].value:t},nr.prototype.getValues=function(){var t=0,e=[];if(this.entries)for(var n=0;n=0&&(e[t++]=this.entries[n].value);return e},nr.prototype.get=function(t){var e=this._findEntry(t);if(e>=0)return this.entries[e].value;throw new Error(Yn)},nr.prototype.set=function(t,e){this._insert(t,e,!1)},nr.prototype.containskey=function(t){return this._findEntry(t)>=0},xn.join=function(t,e,n,r){var i=this;return new ar(function(o){var s=new Fe,u=!1,c=0,a=new nr,l=!1,f=0,h=new nr;return s.add(i.subscribe(function(t){var n,i,l,f,p=c++,d=new Qe;a.add(p,t),s.add(d),i=function(){return a.remove(p)&&0===a.count()&&u&&o.onCompleted(),s.remove(d)};try{n=e(t)}catch(v){return void o.onError(v)}d.setDisposable(n.take(1).subscribe(re,o.onError.bind(o),function(){i()})),f=h.getValues();for(var b=0;bh;h++)d[h].onError(m);return void o.onError(m)}for(o.onNext(b),v=l.getValues(),h=0,p=v.length;p>h;h++)n.onNext(v[h]);var g=new Qe;u.add(g);var y,w=function(){a.remove(i)&&n.onCompleted(),u.remove(g)};try{y=e(t)}catch(m){for(d=a.getValues(),h=0,p=a.length;p>h;h++)d[h].onError(m);return void o.onError(m)}g.setDisposable(y.take(1).subscribe(s,function(t){for(d=a.getValues(),h=0,p=d.length;p>h;h++)d[h].onError(t);o.onError(t)},w))},function(t){for(var e=a.getValues(),n=0,r=e.length;r>n;n++)e[n].onError(t);o.onError(t)},o.onCompleted.bind(o))),u.add(t.subscribe(function(t){var e,r,i,c=h++;l.add(c,t);var f=new Qe;u.add(f);var p,d=function(){l.remove(c),u.remove(f)};try{p=n(t)}catch(v){for(e=a.getValues(),r=0,i=a.length;i>r;r++)e[r].onError(v);return void o.onError(v)}for(f.setDisposable(p.take(1).subscribe(s,function(t){for(e=a.getValues(),r=0,i=a.length;i>r;r++)e[r].onError(t);o.onError(t)},d)),e=a.getValues(),r=0,i=e.length;i>r;r++)e[r].onNext(t)},function(t){for(var e=a.getValues(),n=0,r=e.length;r>n;n++)e[n].onError(t);o.onError(t)})),c})},xn.buffer=function(){return this.window.apply(this,arguments).selectMany(function(t){return t.toArray()})},xn.window=function(t,e){return 1===arguments.length&&"function"!=typeof arguments[0]?P.call(this,t):"function"==typeof t?L.call(this,t):q.call(this,t,e)},xn.pairwise=function(){var t=this;return new ar(function(e){var n,r=!1;return t.subscribe(function(t){r?e.onNext([n,t]):r=!0,n=t},e.onError.bind(e),e.onCompleted.bind(e))})},xn.partition=function(t,e){var n=this.publish().refCount();return[n.filter(t,e),n.filter(function(n,r,i){return!t.call(e,n,r,i)})]},xn.letBind=xn.let=function(t){return t(this)},Sn["if"]=Sn.ifThen=function(t,e,n){return jn(function(){return n||(n=Dn()),le(e)&&(e=An(e)),le(n)&&(n=An(n)),"function"==typeof n.now&&(n=Dn(n)),t()?e:n})},Sn["for"]=Sn.forIn=function(t,e){return gn(t,e).concat()};var rr=Sn["while"]=Sn.whileDo=function(t,e){return le(e)&&(e=An(e)),V(t,e).concat()};xn.doWhile=function(t){return Ln([this,rr(t,this)])},Sn["case"]=Sn.switchCase=function(t,e,n){return jn(function(){n||(n=Dn()),"function"==typeof n.now&&(n=Dn(n));var r=e[t()];return le(r)&&(r=An(r)),r||n})},xn.expand=function(t,e){e||(e=sn);var n=this;return new ar(function(r){var i=[],o=new Ze,s=new Fe(o),u=0,c=!1,a=function(){var n=!1;i.length>0&&(n=!c,c=!0),n&&o.setDisposable(e.scheduleRecursive(function(e){var n;if(!(i.length>0))return void(c=!1);n=i.shift();var o=new Qe;s.add(o),o.setDisposable(n.subscribe(function(e){r.onNext(e);var n=null;try{n=t(e)}catch(o){r.onError(o)}i.push(n),u++,a()},r.onError.bind(r),function(){s.remove(o),u--,0===u&&r.onCompleted()})),e()}))};return i.push(n),u++,a(),s})},Sn.forkJoin=function(){var t=h(arguments,0);return new ar(function(e){var n=t.length;if(0===n)return e.onCompleted(),Xe;for(var r=new Fe,i=!1,o=new Array(n),s=new Array(n),u=new Array(n),c=0;n>c;c++)!function(c){var a=t[c];le(a)&&(a=An(a)),r.add(a.subscribe(function(t){i||(o[c]=!0,u[c]=t)},function(t){i=!0,e.onError(t),r.dispose()},function(){if(!i){if(!o[c])return void e.onCompleted();s[c]=!0;for(var t=0;n>t;t++)if(!s[t])return;i=!0,e.onNext(u),e.onCompleted()}}))}(c);return r})},xn.forkJoin=function(t,e){var n=this;return new ar(function(r){var i,o,s=!1,u=!1,c=!1,a=!1,l=new Qe,f=new Qe;return le(t)&&(t=An(t)),l.setDisposable(n.subscribe(function(t){c=!0,i=t},function(t){f.dispose(),r.onError(t)},function(){if(s=!0,u)if(c)if(a){var t;try{t=e(i,o)}catch(n){return void r.onError(n)}r.onNext(t),r.onCompleted()}else r.onCompleted();else r.onCompleted()})),f.setDisposable(t.subscribe(function(t){a=!0,o=t},function(t){l.dispose(),r.onError(t)},function(){if(u=!0,s)if(c)if(a){var t;try{t=e(i,o)}catch(n){return void r.onError(n)}r.onNext(t),r.onCompleted()}else r.onCompleted();else r.onCompleted()})),new Fe(l,f)})},xn.manySelect=function(t,e){e||(e=sn);var n=this;return jn(function(){var r;return n.select(function(t){var e=new ir(t);return r&&r.onNext(t),r=e,e}).doAction(re,function(t){r&&r.onError(t)},function(){r&&r.onCompleted()}).observeOn(e).select(function(e,n,r){return t(e,n,r)})})};var ir=function(t){function e(t){var e=this,n=new Fe;return n.add(un.schedule(function(){t.onNext(e.head),n.add(e.tail.mergeObservable().subscribe(t))})),n}function n(n){t.call(this,e),this.head=n,this.tail=new pr}return Me(n,t),ze(n.prototype,yn,{onCompleted:function(){this.onNext(Sn.empty())},onError:function(t){this.onNext(Sn.throwException(t))},onNext:function(t){this.tail.onNext(t),this.tail.onCompleted()}}),n}(Sn),or=function(){function t(){this.keys=[],this.values=[]}return t.prototype["delete"]=function(t){var e=this.keys.indexOf(t);return-1!==e&&(this.keys.splice(e,1),this.values.splice(e,1)),-1!==e},t.prototype.get=function(t,e){var n=this.keys.indexOf(t);return-1!==n?this.values[n]:e},t.prototype.set=function(t,e){var n=this.keys.indexOf(t);-1!==n&&(this.values[n]=e),this.values[this.keys.push(t)-1]=e},t.prototype.size=function(){return this.keys.length},t.prototype.has=function(t){return-1!==this.keys.indexOf(t)},t.prototype.getKeys=function(){return this.keys.slice(0)},t.prototype.getValues=function(){return this.values.slice(0)},t}();M.prototype.and=function(t){var e=this.patterns.slice(0);return e.push(t),new M(e)},M.prototype.then=function(t){return new z(this,t)},z.prototype.activate=function(t,e,n){for(var r=this,i=[],o=0,s=this.expression.patterns.length;s>o;o++)i.push(U(t,this.expression.patterns[o],e.onError.bind(e)));var u=new I(i,function(){var t;try{t=r.selector.apply(r,arguments)}catch(n){return void e.onError(n)}e.onNext(t)},function(){for(var t=0,e=i.length;e>t;t++)i[t].removeActivePlan(u);n(u)});for(o=0,s=i.length;s>o;o++)i[o].addActivePlan(u);return u},I.prototype.dequeue=function(){for(var t=this.joinObservers.getValues(),e=0,n=t.length;n>e;e++)t[e].queue.shift()},I.prototype.match=function(){var t,e,n,r,i,o=!0;for(e=0,n=this.joinObserverArray.length;n>e;e++)if(0===this.joinObserverArray[e].queue.length){o=!1;break}if(o){for(t=[],r=!1,e=0,n=this.joinObserverArray.length;n>e;e++)t.push(this.joinObserverArray[e].queue[0]),"C"===this.joinObserverArray[e].queue[0].kind&&(r=!0);if(r)this.onCompleted();else{for(this.dequeue(),i=[],e=0;en;n++)e[n].match()}},n.error=re,n.completed=re,n.addActivePlan=function(t){this.activePlans.push(t)},n.subscribe=function(){this.subscription.setDisposable(this.source.materialize().subscribe(this))},n.removeActivePlan=function(t){var e=this.activePlans.indexOf(t);this.activePlans.splice(e,1),0===this.activePlans.length&&this.dispose()},n.dispose=function(){t.prototype.dispose.call(this),this.isDisposed||(this.isDisposed=!0,this.subscription.dispose())},e}(En);xn.and=function(t){return new M([this,t])},xn.then=function(t){return new M([this]).then(t)},Sn.when=function(){var t=h(arguments,0);return new ar(function(e){var n,r,i,o,s,u,c=[],a=new or;u=wn(e.onNext.bind(e),function(t){for(var n=a.getValues(),r=0,i=n.length;i>r;r++)n[r].onError(t);e.onError(t)},e.onCompleted.bind(e));try{for(r=0,i=t.length;i>r;r++)c.push(t[r].activate(a,u,function(t){var e=c.indexOf(t);c.splice(e,1),0===c.length&&u.onCompleted()}))}catch(l){Tn(l).subscribe(e)}for(n=new Fe,s=a.getValues(),r=0,i=s.length;i>r;r++)o=s[r],o.subscribe(),n.add(o);return n})};var ur=Sn.interval=function(t,e){return e||(e=an),$(t,t,e)},cr=Sn.timer=function(e,n,r){var i;return r||(r=an),n!==t&&"number"==typeof n?i=n:n!==t&&"object"==typeof n&&(r=n),e instanceof Date&&i===t?B(e.getTime(),r):e instanceof Date&&i!==t?(i=n,H(e.getTime(),i,r)):i===t?F(e,r):$(e,i,r)};xn.delay=function(t,e){return e||(e=an),t instanceof Date?G.call(this,t.getTime(),e):J.call(this,t,e)},xn.throttle=function(t,e){e||(e=an);return this.throttleWithSelector(function(){return cr(t,e)})},xn.windowWithTime=function(e,n,r){var i,o=this;return n===t&&(i=e),r===t&&(r=an),"number"==typeof n?i=n:"object"==typeof n&&(i=e,r=n),new ar(function(t){function n(){var e=new Qe,o=!1,s=!1;f.setDisposable(e),a===c?(o=!0,s=!0):c>a?o=!0:s=!0;var p=o?a:c,d=p-h;h=p,o&&(a+=i),s&&(c+=i),e.setDisposable(r.scheduleWithRelative(d,function(){var e;s&&(e=new hr,l.push(e),t.onNext(Ue(e,u))),o&&(e=l.shift(),e.onCompleted()),n()}))}var s,u,c=i,a=e,l=[],f=new Ze,h=0;return s=new Fe(f),u=new Ye(s),l.push(new hr),t.onNext(Ue(l[0],u)),n(),s.add(o.subscribe(function(t){var e,n;for(e=0;e0&&o-i[0].interval>=t;)r.onNext(i.shift().value)},r.onError.bind(r),function(){for(var n=e.now();i.length>0&&n-i[0].interval>=t;)r.onNext(i.shift().value);r.onCompleted()})})},xn.takeLastWithTime=function(t,e,n){return this.takeLastBufferWithTime(t,e).selectMany(function(t){return _n(t,n)})},xn.takeLastBufferWithTime=function(t,e){var n=this;return e||(e=an),new ar(function(r){var i=[];return n.subscribe(function(n){var r=e.now();for(i.push({interval:r,value:n});i.length>0&&r-i[0].interval>=t;)i.shift()},r.onError.bind(r),function(){for(var n=e.now(),o=[];i.length>0;){var s=i.shift();n-s.interval<=t&&o.push(s.value)}r.onNext(o),r.onCompleted()})})},xn.takeWithTime=function(t,e){var n=this;return e||(e=an),new ar(function(r){var i=e.scheduleWithRelative(t,function(){r.onCompleted()});return new Fe(i,n.subscribe(r))})},xn.skipWithTime=function(t,e){var n=this;return e||(e=an),new ar(function(r){var i=!1,o=e.scheduleWithRelative(t,function(){i=!0}),s=n.subscribe(function(t){i&&r.onNext(t)},r.onError.bind(r),r.onCompleted.bind(r));return new Fe(o,s)})},xn.skipUntilWithTime=function(t,e){e||(e=an);var n=this,r=t instanceof Date?"scheduleWithAbsolute":"scheduleWithRelative";return new ar(function(i){var o=!1;return new Fe(e[r](t,function(){o=!0}),n.subscribe(function(t){o&&i.onNext(t)},i.onError.bind(i),i.onCompleted.bind(i)))})},xn.takeUntilWithTime=function(t,e){e||(e=an);var n=this,r=t instanceof Date?"scheduleWithAbsolute":"scheduleWithRelative";return new ar(function(i){return new Fe(e[r](t,function(){i.onCompleted()}),n.subscribe(i))})},xn.exclusive=function(){var t=this;return new ar(function(e){var n=!1,r=!1,i=new Qe,o=new Fe;return o.add(i),i.setDisposable(t.subscribe(function(t){if(!n){n=!0,le(t)&&(t=An(t));var i=new Qe;o.add(i),i.setDisposable(t.subscribe(e.onNext.bind(e),e.onError.bind(e),function(){o.remove(i),n=!1,r&&1===o.length&&e.onCompleted()}))}},e.onError.bind(e),function(){r=!0,n||1!==o.length||e.onCompleted()})),o})},xn.exclusiveMap=function(t,e){var n=this;return new ar(function(r){var i=0,o=!1,s=!0,u=new Qe,c=new Fe;return c.add(u),u.setDisposable(n.subscribe(function(n){o||(o=!0,innerSubscription=new Qe,c.add(innerSubscription),le(n)&&(n=An(n)),innerSubscription.setDisposable(n.subscribe(function(o){var s;try{s=t.call(e,o,i++,n)}catch(u){return void r.onError(u)}r.onNext(s)},r.onError.bind(r),function(){c.remove(innerSubscription),o=!1,s&&1===c.length&&r.onCompleted()})))},r.onError.bind(r),function(){s=!0,1!==c.length||o||r.onCompleted()})),c})},ne.VirtualTimeScheduler=function(t){function e(){throw new Error("Not implemented")}function n(){return this.toDateTimeOffset(this.clock)}function r(t,e){return this.scheduleAbsoluteWithState(t,this.clock,e)}function i(t,e,n){return this.scheduleRelativeWithState(t,this.toRelative(e),n)}function o(t,e,n){return this.scheduleRelativeWithState(t,this.toRelative(e-this.now()),n)}function s(t,e){return e(),Xe}function u(e,s){this.clock=e,this.comparer=s,this.isEnabled=!1,this.queue=new Be(1024),t.call(this,n,r,i,o)}Me(u,t);var c=u.prototype;return c.add=e,c.toDateTimeOffset=e,c.toRelative=e,c.schedulePeriodicWithState=function(t,e,n){var r=new on(this,t,e,n);return r.start()},c.scheduleRelativeWithState=function(t,e,n){var r=this.add(this.clock,e);return this.scheduleAbsoluteWithState(t,r,n)},c.scheduleRelative=function(t,e){return this.scheduleRelativeWithState(e,t,s)},c.start=function(){var t;if(!this.isEnabled){this.isEnabled=!0;do t=this.getNext(),null!==t?(this.comparer(t.dueTime,this.clock)>0&&(this.clock=t.dueTime),t.invoke()):this.isEnabled=!1;while(this.isEnabled)}},c.stop=function(){this.isEnabled=!1},c.advanceTo=function(t){var e,n=this.comparer(this.clock,t);if(this.comparer(this.clock,t)>0)throw new Error(he);if(0!==n&&!this.isEnabled){this.isEnabled=!0;do e=this.getNext(),null!==e&&this.comparer(e.dueTime,t)<=0?(this.comparer(e.dueTime,this.clock)>0&&(this.clock=e.dueTime),e.invoke()):this.isEnabled=!1;while(this.isEnabled);this.clock=t}},c.advanceBy=function(t){var e=this.add(this.clock,t),n=this.comparer(this.clock,e);if(n>0)throw new Error(he);0!==n&&this.advanceTo(e)},c.sleep=function(t){var e=this.add(this.clock,t);if(this.comparer(this.clock,e)>=0)throw new Error(he);this.clock=e},c.getNext=function(){for(var t;this.queue.length>0;){if(t=this.queue.peek(),!t.isCancelled())return t;this.queue.dequeue()}return null},c.scheduleAbsolute=function(t,e){return this.scheduleAbsoluteWithState(e,t,s)},c.scheduleAbsoluteWithState=function(t,e,n){var r=this,i=function(t,e){return r.queue.remove(o),n(t,e)},o=new tn(r,t,i,e,r.comparer);return r.queue.enqueue(o),o.disposable},u}(nn),ne.HistoricalScheduler=function(t){function e(e,n){var r=null==e?0:e,i=n||ue;t.call(this,r,i)}Me(e,t);var n=e.prototype;return n.add=function(t,e){return t+e},n.toDateTimeOffset=function(t){return new Date(t).getTime()},n.toRelative=function(t){return t},e}(ne.VirtualTimeScheduler);var ar=ne.AnonymousObservable=function(t){function e(t){return"undefined"==typeof t?t=Xe:"function"==typeof t&&(t=Ge(t)),t}function n(r){function i(t){var n=function(){try{i.setDisposable(e(r(i)))}catch(t){if(!i.fail(t))throw t}},i=new lr(t);return un.scheduleRequired()?un.schedule(n):n(),i}return this instanceof n?void t.call(this,i):new n(r)}return Me(n,t),n}(Sn),lr=function(t){function e(e){t.call(this),this.observer=e,this.m=new Qe}Me(e,t);var n=e.prototype;return n.next=function(t){var e=!1;try{this.observer.onNext(t),e=!0}catch(n){throw n}finally{e||this.dispose()}},n.error=function(t){try{this.observer.onError(t)}catch(e){throw e}finally{this.dispose()}},n.completed=function(){try{this.observer.onCompleted()}catch(t){throw t}finally{this.dispose()}},n.setDisposable=function(t){this.m.setDisposable(t)},n.getDisposable=function(){return this.m.getDisposable()},n.disposable=function(t){return arguments.length?this.getDisposable():setDisposable(t)},n.dispose=function(){t.prototype.dispose.call(this),this.m.dispose()},e}(En),fr=function(t){function e(t){return this.underlyingObservable.subscribe(t)}function n(n,r,i){t.call(this,e),this.key=n,this.underlyingObservable=i?new ar(function(t){return new Fe(i.getDisposable(),r.subscribe(t))}):r}return Me(n,t),n}(Sn),hr=ne.Subject=function(t){function e(t){return r.call(this),this.isStopped?this.exception?(t.onError(this.exception),Xe):(t.onCompleted(),Xe):(this.observers.push(t),new Gn(this,t))}function n(){t.call(this,e),this.isDisposed=!1,this.isStopped=!1,this.observers=[]}return Me(n,t),ze(n.prototype,yn,{hasObservers:function(){return this.observers.length>0},onCompleted:function(){if(r.call(this),!this.isStopped){var t=this.observers.slice(0);this.isStopped=!0;for(var e=0,n=t.length;n>e;e++)t[e].onCompleted();this.observers=[]}},onError:function(t){if(r.call(this),!this.isStopped){var e=this.observers.slice(0);this.isStopped=!0,this.exception=t;for(var n=0,i=e.length;i>n;n++)e[n].onError(t);this.observers=[]}},onNext:function(t){if(r.call(this),!this.isStopped)for(var e=this.observers.slice(0),n=0,i=e.length;i>n;n++)e[n].onNext(t)},dispose:function(){this.isDisposed=!0,this.observers=null}}),n.create=function(t,e){return new dr(t,e)},n}(Sn),pr=ne.AsyncSubject=function(t){function e(t){if(r.call(this),!this.isStopped)return this.observers.push(t),new Gn(this,t);var e=this.exception,n=this.hasValue,i=this.value;return e?t.onError(e):n?(t.onNext(i),t.onCompleted()):t.onCompleted(),Xe}function n(){t.call(this,e),this.isDisposed=!1,this.isStopped=!1,this.value=null,this.hasValue=!1,this.observers=[],this.exception=null}return Me(n,t),ze(n.prototype,yn,{hasObservers:function(){return r.call(this),this.observers.length>0},onCompleted:function(){var t,e,n;if(r.call(this),!this.isStopped){this.isStopped=!0;var i=this.observers.slice(0),o=this.value,s=this.hasValue;if(s)for(e=0,n=i.length;n>e;e++)t=i[e],t.onNext(o),t.onCompleted();else for(e=0,n=i.length;n>e;e++)i[e].onCompleted();this.observers=[]}},onError:function(t){if(r.call(this),!this.isStopped){var e=this.observers.slice(0); -this.isStopped=!0,this.exception=t;for(var n=0,i=e.length;i>n;n++)e[n].onError(t);this.observers=[]}},onNext:function(t){r.call(this),this.isStopped||(this.value=t,this.hasValue=!0)},dispose:function(){this.isDisposed=!0,this.observers=null,this.exception=null,this.value=null}}),n}(Sn),dr=function(t){function e(t){return this.observable.subscribe(t)}function n(n,r){t.call(this,e),this.observer=n,this.observable=r}return Me(n,t),ze(n.prototype,yn,{onCompleted:function(){this.observer.onCompleted()},onError:function(t){this.observer.onError(t)},onNext:function(t){this.observer.onNext(t)}}),n}(Sn);"function"==typeof define&&"object"==typeof define.amd&&define.amd?(Q.Rx=ne,define(function(){return ne})):Z&&Y?te?(Y.exports=ne).Rx=ne:Z.Rx=ne:Q.Rx=ne}).call(this)},{}],14:[function(t,e,n){(function(r){var i={"boolean":!1,"function":!0,object:!0,number:!1,string:!1,undefined:!1},o=i[typeof window]&&window||this,s=i[typeof n]&&n&&!n.nodeType&&n,u=i[typeof e]&&e&&!e.nodeType&&e,c=(u&&u.exports===s&&s,i[typeof global]&&global);!c||c.global!==c&&c.window!==c||(o=c),"function"==typeof define&&define.amd?define(["rx.virtualtime","exports"],function(t,e){return o.Rx=r(o,e,t),o.Rx}):"object"==typeof e&&e&&e.exports===s?e.exports=r(o,e.exports,t("./rx.all")):o.Rx=r(o,{},o.Rx)}).call(this,function(t,e,n){function r(t,e){return 1===t.length&&Array.isArray(t[e])?t[e]:d.call(t)}function i(t){this.predicate=t}function o(t){this.predicate=t}var s=n.Observer,u=n.Observable,c=n.Notification,a=n.VirtualTimeScheduler,l=n.Disposable,f=l.empty,h=l.create,p=n.CompositeDisposable,d=(n.SingleAssignmentDisposable,Array.prototype.slice),v=n.internals.inherits,b=n.internals.isEqual;i.prototype.equals=function(t){return t===this?!0:null==t?!1:"N"!==t.kind?!1:this.predicate(t.value)},o.prototype.equals=function(t){return t===this?!0:null==t?!1:"E"!==t.kind?!1:this.predicate(t.exception)};var m=n.ReactiveTest={created:100,subscribed:200,disposed:1e3,onNext:function(t,e){return"function"==typeof e?new g(t,new i(e)):new g(t,c.createOnNext(e))},onError:function(t,e){return"function"==typeof e?new g(t,new o(e)):new g(t,c.createOnError(e))},onCompleted:function(t){return new g(t,c.createOnCompleted())},subscribe:function(t,e){return new y(t,e)}},g=n.Recorded=function(t,e,n){this.time=t,this.value=e,this.comparer=n||b};g.prototype.equals=function(t){return this.time===t.time&&this.comparer(this.value,t.value)},g.prototype.toString=function(){return this.value.toString()+"@"+this.time};var y=n.Subscription=function(t,e){this.subscribe=t,this.unsubscribe=e||Number.MAX_VALUE};y.prototype.equals=function(t){return this.subscribe===t.subscribe&&this.unsubscribe===t.unsubscribe},y.prototype.toString=function(){return"("+this.subscribe+", "+this.unsubscribe===Number.MAX_VALUE?"Infinite":this.unsubscribe+")"};var w=n.MockDisposable=function(t){this.scheduler=t,this.disposes=[],this.disposes.push(this.scheduler.clock)};w.prototype.dispose=function(){this.disposes.push(this.scheduler.clock)};var x=function(t){function e(e){t.call(this),this.scheduler=e,this.messages=[]}v(e,t);var n=e.prototype;return n.onNext=function(t){this.messages.push(new g(this.scheduler.clock,c.createOnNext(t)))},n.onError=function(t){this.messages.push(new g(this.scheduler.clock,c.createOnError(t)))},n.onCompleted=function(){this.messages.push(new g(this.scheduler.clock,c.createOnCompleted()))},e}(s),E=function(t){function e(t){var e=this;this.observers.push(t),this.subscriptions.push(new y(this.scheduler.clock));var n=this.subscriptions.length-1;return h(function(){var r=e.observers.indexOf(t);e.observers.splice(r,1),e.subscriptions[n]=new y(e.subscriptions[n].subscribe,e.scheduler.clock)})}function n(n,r){t.call(this,e);var i,o,s=this;this.scheduler=n,this.messages=r,this.subscriptions=[],this.observers=[];for(var u=0,c=this.messages.length;c>u;u++)i=this.messages[u],o=i.value,function(t){n.scheduleAbsoluteWithState(null,i.time,function(){for(var e=s.observers.slice(0),n=0,r=e.length;r>n;n++)t.accept(e[n]);return f})}(o)}return v(n,t),n}(u),C=function(t){function e(t){var e,n,r=this;this.subscriptions.push(new y(this.scheduler.clock));for(var i=this.subscriptions.length-1,o=new p,s=0,u=this.messages.length;u>s;s++)e=this.messages[s],n=e.value,function(n){o.add(r.scheduler.scheduleRelativeWithState(null,e.time,function(){return n.accept(t),f}))}(n);return h(function(){r.subscriptions[i]=new y(r.subscriptions[i].subscribe,r.scheduler.clock),o.dispose()})}function n(n,r){t.call(this,e),this.scheduler=n,this.messages=r,this.subscriptions=[]}return v(n,t),n}(u);return n.TestScheduler=function(t){function e(t,e){return t>e?1:e>t?-1:0}function n(){t.call(this,0,e)}return v(n,t),n.prototype.scheduleAbsoluteWithState=function(e,n,r){return n<=this.clock&&(n=this.clock+1),t.prototype.scheduleAbsoluteWithState.call(this,e,n,r)},n.prototype.add=function(t,e){return t+e},n.prototype.toDateTimeOffset=function(t){return new Date(t).getTime()},n.prototype.toRelative=function(t){return t},n.prototype.startWithTiming=function(t,e,n,r){var i,o,s=this.createObserver();return this.scheduleAbsoluteWithState(null,e,function(){return i=t(),f}),this.scheduleAbsoluteWithState(null,n,function(){return o=i.subscribe(s),f}),this.scheduleAbsoluteWithState(null,r,function(){return o.dispose(),f}),this.start(),s},n.prototype.startWithDispose=function(t,e){return this.startWithTiming(t,m.created,m.subscribed,e)},n.prototype.startWithCreate=function(t){return this.startWithTiming(t,m.created,m.subscribed,m.disposed)},n.prototype.createHotObservable=function(){var t=r(arguments,0);return new E(this,t)},n.prototype.createColdObservable=function(){var t=r(arguments,0);return new C(this,t)},n.prototype.createObserver=function(){return new x(this)},n}(a),n})},{"./rx.all":13}],15:[function(t,e){var n=t("./dist/rx.all");t("./dist/rx.testing");var r=t("events").EventEmitter,i=n.Observable;n.Node={fromCallback:function(t,e,n,r){return i.fromCallback(t,e,n,r)},fromNodeCallback:function(t,e,n,r){return i.fromNodeCallback(t,e,n,r)},fromEvent:function(t,e,n){return i.fromEvent(t,e,n)},toEventEmitter:function(t,e,n){var i=new r;return n||(n=function(t){return t}),i.publish=function(){i.subscription=t.subscribe(function(t){i.emit(e,n(t))},function(t){i.emit("error",t)},function(){i.emit("end")})},i},fromStream:function(t){return i.create(function(e){function n(t){e.onNext(t)}function r(t){e.onError(t)}function i(){e.onCompleted()}return t.addListener("data",n),t.addListener("error",r),t.addListener("end",i),function(){t.removeListener("data",n),t.removeListener("error",r),t.removeListener("end",i)}}).publish().refCount()},writeToStream:function(t,e,n){return t.subscribe(function(t){e.write(String(t),n)},function(t){e.emit("error",t)},function(){!e._isStdio&&e.end()})}},e.exports=n},{"./dist/rx.all":13,"./dist/rx.testing":14,events:3}],16:[function(t,e){var n,r,i,o,s,u,c;r=t("rx"),n=t("rxmarbles/models/examples"),o=t("rxmarbles/controllers/selected-example"),s=t("rxmarbles/controllers/utils"),i=t("rxmarbles/views/sandbox"),u=new r.BehaviorSubject(null),o.stream.map(function(t){return t.inputs.map(s.prepareInputDiagram)}).subscribe(function(t){return u.onNext(t),!0}),c=i.getStreamOfArrayOfLiveInputDiagramStreams(),e.exports={initial$:u,continuous$:c}},{rx:15,"rxmarbles/controllers/selected-example":18,"rxmarbles/controllers/utils":19,"rxmarbles/models/examples":23,"rxmarbles/views/sandbox":32}],17:[function(t,e){var n,r,i,o,s,u,c,a=[].slice;o=t("rx"),u=t("rxmarbles/controllers/utils"),i=t("rxmarbles/controllers/input-diagrams"),s=t("rxmarbles/controllers/selected-example"),r=t("rxmarbles/models/examples"),n=100,c=i.continuous$.filter(function(t){return null!==t}).flatMapLatest(function(t){return o.Observable.combineLatest(t,function(){var t;return t=1<=arguments.length?a.call(arguments,0):[]})}).combineLatest(s.stream,function(t,e){var r,i,o,s,c,a;return i=n+1,a=u.makeScheduler(),o=function(){var e,n,o;for(o=[],e=0,n=t.length;n>e;e++)r=t[e],o.push(u.toVTStream(r,a,i));return o}(),c=e.apply(o,a),c=c.takeUntilWithTime(i,a),s=u.getDiagramPromise(c,a,i),a.start(),s}).mergeAll(),e.exports=c},{rx:15,"rxmarbles/controllers/input-diagrams":16,"rxmarbles/controllers/selected-example":18,"rxmarbles/controllers/utils":19,"rxmarbles/models/examples":23}],18:[function(t,e){var n,r,i,o,s,u;i=t("rx"),n=t("rxmarbles/models/examples"),r=t("rxmarbles/views/operators-menu"),u=window.location.hash.replace("#","")||"merge",s=r.getSelected$().startWith(u),o=s.map(function(t){var e;return e=n[t],e.key=t,e}),e.exports={stream:o}},{rx:15,"rxmarbles/models/examples":23,"rxmarbles/views/operators-menu":30}],19:[function(t,e){var n,r,i,o,s,u,c,a,l;n=t("rx"),s=function(){var t;return t=new n.VirtualTimeScheduler(0,function(t,e){return t>e?1:e>t?-1:0}),t.add=function(t,e){return t+e},t.toDateTimeOffset=function(t){return Math.floor(t)},t.toRelative=function(t){return t},t},r=function(t){var e,n;return e=877,n=0,"string"==typeof t?n=t.split("").map(function(t){return t.charCodeAt(0)}).reduce(function(t,e){return t+e}):"number"==typeof t&&(n=t*e),n},i=function(t){var e,n,i,o;return i=7,e=1046527,n=1e5,o=r(t.content),(t.time+o+i)*e%n},c=function(t){var e;return e={},e.time="undefined"==typeof t.time?t.t:t.time,e.content="undefined"==typeof t.content?t.d:t.content,e.id=null!=t.id?t.id:i(e),e},u=function(t){var e;return function(){var n,r,i;for(i=[],n=0,r=t.length;r>n;n++)e=t[n],i.push(c(e));return i}()},a=function(t){return t.map(u)},l=function(t,e,r){var i,o,s,u;for(o=[],s=0,u=t.length;u>s;s++)i=t[s],o.push(n.Observable.just(i,e).delay(i.t||i.time,e));return n.Observable.merge(o).takeUntilWithTime(r,e).publish().refCount()},o=function(t,e,i){var o;return o=new n.BehaviorSubject([]),t.observeOn(e).timestamp(e).map(function(t){return"object"!=typeof t.value&&(t.value={content:t.value,id:r(t.value)}),{time:t.timestamp/i*100,content:t.value.content,id:t.value.id}}).reduce(function(t,e){return t.push(e),t},[]).subscribe(function(t){return o.onNext(t),!0},function(){return console.warn("Error in the diagram promise stream"),0}),o.asObservable()},e.exports={makeScheduler:s,toVTStream:l,prepareInputDiagramStream:a,prepareInputDiagram:u,getDiagramPromise:o}},{rx:15}],20:[function(t,e){var n;n=t("rx"),e.exports={all:{label:"all(x => x < 10)",inputs:[[{t:5,d:1},{t:15,d:2},{t:25,d:3},{t:35,d:4},{t:65,d:5}]],apply:function(t){return t[0].all(function(t){return t.content<10})}},contains:{label:"contains(22)",inputs:[[{t:5,d:2},{t:15,d:30},{t:25,d:22},{t:35,d:5},{t:45,d:60},{t:55,d:1}]],apply:function(t){return t[0].contains({content:22},function(t,e){return t.content===e.content})}}}},{rx:15}],21:[function(t,e){var n;n=t("rx"),e.exports={combineLatest:{label:'combineLatest((x, y) => "" + x + y)',inputs:[[{t:0,d:1},{t:20,d:2},{t:65,d:3},{t:75,d:4},{t:92,d:5}],[{t:10,d:"A"},{t:25,d:"B"},{t:50,d:"C"},{t:57,d:"D"}]],apply:function(t){return n.Observable.combineLatest(t[0],t[1],function(t,e){return""+t.content+e.content})}},concat:{label:"concat",inputs:[[{t:0,d:1},{t:15,d:1},{t:50,d:1}],[{t:13,d:2},{t:30,d:2}]],apply:function(t){return n.Observable.concat(t)}},merge:{label:"merge",inputs:[[{t:0,d:20},{t:15,d:40},{t:30,d:60},{t:45,d:80},{t:60,d:100}],[{t:37,d:1},{t:68,d:1}]],apply:function(t){return n.Observable.merge(t)}},sample:{label:"sample",inputs:[[{t:0,d:1},{t:20,d:2},{t:40,d:3},{t:60,d:4},{t:80,d:5}],[{t:10,d:"A"},{t:25,d:"B"},{t:33,d:"C"},{t:70,d:"D"}]],apply:function(t){return t[0].sample(t[1])}},startWith:{label:"startWith(1)",inputs:[[{t:30,d:2},{t:40,d:3}]],apply:function(t,e){return t[0].startWith(e,1)}},zip:{label:"zip",inputs:[[{t:0,d:1},{t:20,d:2},{t:65,d:3},{t:75,d:4},{t:92,d:5}],[{t:10,d:"A"},{t:25,d:"B"},{t:50,d:"C"},{t:57,d:"D"}]],apply:function(t){return n.Observable.zip(t[0],t[1],function(t,e){return""+t.content+e.content})}}}},{rx:15}],22:[function(t,e){var n;n=t("rx"),e.exports={amb:{label:"amb",inputs:[[{t:10,d:20},{t:20,d:40},{t:30,d:60}],[{t:5,d:1},{t:15,d:2},{t:25,d:3}],[{t:20,d:0},{t:32,d:0},{t:44,d:0}]],apply:function(t){return n.Observable.amb(t)}}}},{rx:15}],23:[function(t,e){var n,r,i,o,s,u,c,a,l,f=[].slice,h={}.hasOwnProperty;n=t("rx"),l=t("rxmarbles/models/transform-examples"),o=t("rxmarbles/models/combine-examples"),u=t("rxmarbles/models/filter-examples"),c=t("rxmarbles/models/math-examples"),i=t("rxmarbles/models/boolean-examples"),s=t("rxmarbles/models/conditional-examples"),a=function(){var t,e,n,r,i,o,s;for(t=1<=arguments.length?f.call(arguments,0):[],r={},o=0,s=t.length;s>o;o++){n=t[o];for(e in n)h.call(n,e)&&(i=n[e],r[e]=n[e])}return r},r=function(t,e){var n,r;for(n in t)h.call(t,n)&&(r=t[n],t[n].category=e);return t},e.exports=a(r(l,"Transforming Operators"),r(o,"Combining Operators"),r(u,"Filtering Operators"),r(c,"Mathematical Operators"),r(i,"Boolean Operators"),r(s,"Conditional Operators"))},{rx:15,"rxmarbles/models/boolean-examples":20,"rxmarbles/models/combine-examples":21,"rxmarbles/models/conditional-examples":22,"rxmarbles/models/filter-examples":24,"rxmarbles/models/math-examples":25,"rxmarbles/models/transform-examples":26}],24:[function(t,e){var n;n=t("rx"),e.exports={distinct:{label:"distinct",inputs:[[{t:5,d:1},{t:20,d:2},{t:35,d:2},{t:60,d:1},{t:70,d:3}]],apply:function(t){return t[0].distinct(function(t){return t.content})}},distinctUntilChanged:{label:"distinctUntilChanged",inputs:[[{t:5,d:1},{t:20,d:2},{t:35,d:2},{t:60,d:1},{t:70,d:3}]],apply:function(t){return t[0].distinctUntilChanged(function(t){return t.content})}},elementAt:{label:"elementAt(2)",inputs:[[{t:30,d:1},{t:40,d:2},{t:65,d:3},{t:75,d:4}]],apply:function(t){return t[0].elementAt(2)}},filter:{label:"filter(x => x > 10)",inputs:[[{t:5,d:2},{t:15,d:30},{t:25,d:22},{t:35,d:5},{t:45,d:60},{t:55,d:1}]],apply:function(t){return t[0].filter(function(t){return t.content>10})}},find:{label:"find(x => x > 10)",inputs:[[{t:5,d:2},{t:15,d:30},{t:25,d:22},{t:35,d:5},{t:45,d:60},{t:55,d:1}]],apply:function(t){return t[0].find(function(t){return t.content>10})}},first:{label:"first",inputs:[[{t:30,d:1},{t:40,d:2},{t:65,d:3},{t:75,d:4}]],apply:function(t){return t[0].first()}},last:{label:"last",inputs:[[{t:30,d:1},{t:40,d:2},{t:65,d:3},{t:75,d:4}]],apply:function(t){return t[0].last()}},skip:{label:"skip(2)",inputs:[[{t:30,d:1},{t:40,d:2},{t:65,d:3},{t:75,d:4}]],apply:function(t){return t[0].skip(2)}},skipUntil:{label:"skipUntil",inputs:[[{t:0,d:1},{t:10,d:2},{t:20,d:3},{t:30,d:4},{t:40,d:5},{t:50,d:6},{t:60,d:7},{t:70,d:8},{t:80,d:9}],[{t:47,d:0},{t:73,d:0}]],apply:function(t){return t[0].skipUntil(t[1])}},take:{label:"take(2)",inputs:[[{t:30,d:1},{t:40,d:2},{t:65,d:3},{t:75,d:4}]],apply:function(t,e){return t[0].take(2,e)}},takeUntil:{label:"takeUntil",inputs:[[{t:0,d:1},{t:10,d:2},{t:20,d:3},{t:30,d:4},{t:40,d:5},{t:50,d:6},{t:60,d:7},{t:70,d:8},{t:80,d:9}],[{t:47,d:0},{t:73,d:0}]],apply:function(t){return t[0].takeUntil(t[1])}}}},{rx:15}],25:[function(t,e){var n;n=t("rx"),e.exports={aggregate:{label:"aggregate((x, y) => x + y)",inputs:[[{t:5,d:1},{t:15,d:2},{t:25,d:3},{t:35,d:4},{t:65,d:5}]],apply:function(t){return t[0].aggregate(function(t,e){return{content:t.content+e.content,time:t.time,id:t.id+e.id}})}},average:{label:"average",inputs:[[{t:5,d:1},{t:15,d:2},{t:30,d:2},{t:50,d:2},{t:65,d:5}]],apply:function(t){return t[0].average(function(t){return t.content})}},count:{label:"count(x => x > 10)",inputs:[[{t:5,d:2},{t:15,d:30},{t:25,d:22},{t:35,d:5},{t:45,d:60},{t:55,d:1}]],apply:function(t){return t[0].count(function(t){return t.content>10})}},max:{label:"max",inputs:[[{t:5,d:2},{t:15,d:30},{t:25,d:22},{t:35,d:5},{t:45,d:60},{t:55,d:1}]],apply:function(t){return t[0].max(function(t,e){return t.content>e.content?1:t.contente.content?1:t.content 10 * x)",inputs:[[{t:10,d:1},{t:20,d:2},{t:50,d:3}]],apply:function(t){return t[0].map(function(t){return{content:10*t.content,time:t.time,id:t.id}})}},scan:{label:"scan((x, y) => x + y)",inputs:[[{t:5,d:1},{t:15,d:2},{t:25,d:3},{t:35,d:4},{t:65,d:5}]],apply:function(t){return t[0].scan(function(t,e){return{content:t.content+e.content,time:t.time,id:t.id+e.id}})}},throttle:{label:"throttle",inputs:[[{t:0,d:1},{t:26,d:2},{t:34,d:3},{t:40,d:4},{t:45,d:5},{t:90,d:6}]],apply:function(t,e){return t[0].throttle(20,e)}}}},{rx:15}],27:[function(t,e){var n,r,i,o,s,u,c=[].slice;r=t("rx"),n=t("rxmarbles/views/marble"),i=function(){var t;return t=document.createElement("div"),t.className="arrow",t},o=function(){var t;return t=document.createElement("div"),t.className="arrow-head",t},s=function(t){var e,n,r,i;for(n=document.createElement("div"),n.className="marbles",r=0,i=t.length;i>r;r++)e=t[r],n.appendChild(e);return n},u=function(t){var e;return r.Observable.combineLatest(function(){var n,r,i;for(i=[],n=0,r=t.length;r>n;n++)e=t[n],i.push(e.dataStream);return i}(),function(){var t;return t=1<=arguments.length?c.call(arguments,0):[]})},e.exports={render:function(t){var e,r,c;return e=document.createElement("div"),e.className="diagram",e.appendChild(i()),e.appendChild(o()),c=function(){var e,i,o;for(o=[],e=0,i=t.length;i>e;e++)r=t[e],o.push(n.render(r,!0));return o}(),e.appendChild(s(c)),e.dataStream=u(c),e}}},{rx:15,"rxmarbles/views/marble":28}],28:[function(t,e){var n,r,i,o,s,u,c,a,l,f,h,p,d,v,b,m,g,y;r=t("rx"),b=t("virtual-hyperscript"),g=t("virtual-hyperscript/svg"),a="http://www.w3.org/2000/svg",n=4,c="0 0 1 1",o=.5,s=.5,u=.47,i="0.06px",p=function(t){return r.Observable.fromEvent(t,"mousedown").map(function(){var t,e,n;return e=r.Observable.fromEvent(document,"mousemove"),n=r.Observable.fromEvent(document,"mouseup"),t=e.map(function(t){return t.stopPropagation,t.preventDefault(),t.pageX}).windowWithCount(2,1).flatMap(function(t){return t.toArray()}).map(function(t){return t[1]-t[0]}),t.takeUntil(n)}).concatAll()},d=function(t,e){return p(t).scan(e,function(e,n){var r,i;i=1;try{i=100/t.parentElement.clientWidth}catch(o){r=o,console.warn(r)}return e+n*i}).map(function(t){return 0>t?0:t>100?100:t}).map(Math.round).startWith(e).distinctUntilChanged()},h=function(t){var e;return e=document.createElement("div"),e.className="marble-container",t&&(e.className+=" draggable"),e},f=function(t){var e,r,l;return r=t.id%n+1,l=document.createElementNS(a,"svg"),l.setAttribute("class","marble"),l.setAttribute("viewBox",c),e=document.createElementNS(a,"circle"),e.setAttribute("cx",o),e.setAttribute("cy",s),e.setAttribute("r",u),e.setAttribute("class","marble marble-color-"+r),e.setAttribute("stroke-width",i),l.appendChild(e),l},l=function(t){var e;return e=document.createElement("p"),e.className="marble-content",e.textContent=null!=t?t.content:void 0,e},v=function(t,e,n){return e?d(n,t.time):r.Observable.just(t.time)},y=function(t){var e,n,r;return e=t.id%4+1,r=""+t.time+"%",n=""+t.content,b("div.marble-container",{style:{left:r}},[g("svg",{attributes:{"class":"marble",viewBox:c}},[g("circle",{attributes:{"class":"marble marble-color-"+e,cx:o,cy:s,r:u,"stroke-width":i}})]),b("p.marble-content",{},n)])},m=function(t,e){var n,r;return null==e&&(e=!1),n=h(e),n.appendChild(f(t)),n.appendChild(l(t)),r=v(t,e,n),n.dataStream=r.map(function(e){return{time:e,content:t.content,id:t.id}}),r.subscribe(function(t){return n.style.left=t+"%",!0}),n},e.exports={render:m,virtualRender:y}},{rx:15,"virtual-hyperscript":59,"virtual-hyperscript/svg":87}],29:[function(t,e){var n,r;n=t("hyperscript"),r=function(t){var e;return e=t.length>20?{style:{"font-size":"1.5rem"}}:{},n("span.operator-box-label",e,t)},e.exports={render:function(t){return n("div.operator-box",[r(t.label)])}}},{hyperscript:4}],30:[function(t,e){var n,r,i,o,s,u,c,a,l,f,h,p={}.hasOwnProperty;s=t("hyperscript"),r=t("rx"),n=t("rxmarbles/models/examples"),h=new r.Subject,c=function(t){return s("li.category",""+t)},a=function(t){var e;return e=s("a",{href:"#"+t.key},t.key),r.Observable.fromEvent(e,"click").subscribe(function(){return h.onNext(t.key),!0}),s("li",[e])},l=function(t){var e;return function(){var n,r,i;for(i=[],n=0,r=t.length;r>n;n++)e=t[n],i.push(a(e));return i}()},u=function(t){var e,n,r;e={};for(n in t)p.call(t,n)&&(r=t[n],r.key=n,e.hasOwnProperty(r.category)?e[r.category].push(r):e[r.category]=[r]);return e},f=function(t){var e,n,r,i;i=[],n=u(t);for(r in n)p.call(n,r)&&(e=n[r],i.push(c(r)),i=i.concat(l(e)));return i.push(s("li.category","More")),i.push(s("li","Coming soon...")),i},o=function(){var t,e;return t=document.body,e=document.documentElement,Math.max(t.scrollHeight,t.offsetHeight,e.clientHeight,e.scrollHeight,e.offsetHeight)},i=function(t){return r.Observable.timer(1).subscribe(function(){var e;return e=o()-t.getBoundingClientRect().top,t.style.height=""+e+"px",!0})},e.exports={getSelected$:function(){return h},render:function(){var t;return t=s("ul.operators-menu",f(n)),i(t),t}}},{hyperscript:4,rx:15,"rxmarbles/models/examples":23}],31:[function(t,e){var n,r,i,o,s,u;r=t("rx"),o=t("virtual-hyperscript"),n=t("rxmarbles/views/marble"),i={createElement:t("virtual-dom/create-element"),diff:t("virtual-dom/diff"),patch:t("virtual-dom/patch")},u=function(t){var e;return o("div.marbles",function(){var r,i,o;for(o=[],r=0,i=t.length;i>r;r++)e=t[r],o.push(n.virtualRender(e));return o}())},s=function(t){var e;return null===t?o("div.diagram"):(e=[],e.push(o("div.arrow")),e.push(o("div.arrow-head")),e.push(u(t)),o("div.diagram",{},e))},e.exports={render:function(t){var e,n;return n=s(null),e=i.createElement(n),t.subscribe(function(t){var r,o;return r=s(t),o=i.diff(n,r),e=i.patch(e,o),n=r,!0}),e}}},{rx:15,"rxmarbles/views/marble":28,"virtual-dom/create-element":34,"virtual-dom/diff":35,"virtual-dom/patch":54,"virtual-hyperscript":59}],32:[function(t,e){var n,r,i,o,s,u,c,a,l,f;o=t("rx"),l=t("hyperscript"),n=t("rxmarbles/views/input-diagram"),r=t("rxmarbles/views/operator-box"),i=t("rxmarbles/views/output-diagram"),s=t("rxmarbles/views/utils"),f=new o.BehaviorSubject(null),u=function(){var e,r;return e=t("rxmarbles/controllers/input-diagrams"),r=s.renderObservableDOMElement(e.initial$.map(function(t){var e;return function(){var r,i,o;for(o=[],r=0,i=t.length;i>r;r++)e=t[r],o.push(n.render(e));return o}()}).doAction(function(t){var e;return f.onNext(function(){var n,r,i;for(i=[],n=0,r=t.length;r>n;n++)e=t[n],i.push(e.dataStream);return i}())}))},c=function(){var e;return e=t("rxmarbles/controllers/selected-example"),s.renderObservableDOMElement(e.stream.map(function(t){return r.render(t)}))},a=function(){var e;return e=t("rxmarbles/controllers/output-diagram"),i.render(e)},e.exports={getStreamOfArrayOfLiveInputDiagramStreams:function(){return f},render:function(){return l("div.sandbox",[u(),c(),a()])}}},{hyperscript:4,rx:15,"rxmarbles/controllers/input-diagrams":16,"rxmarbles/controllers/output-diagram":17,"rxmarbles/controllers/selected-example":18,"rxmarbles/views/input-diagram":27,"rxmarbles/views/operator-box":29,"rxmarbles/views/output-diagram":31,"rxmarbles/views/utils":33}],33:[function(t,e){e.exports={renderObservableDOMElement:function(t){var e;return e=document.createElement("div"),t.subscribe(function(t){var n,r,i;if(e.innerHTML="",Array.isArray(t))for(r=0,i=t.length;i>r;r++)n=t[r],e.appendChild(n);else t instanceof Element&&e.appendChild(t);return!0}),e}}},{}],34:[function(t,e){var n=t("vdom/create-element");e.exports=n},{"vdom/create-element":38}],35:[function(t,e){var n=t("vtree/diff");e.exports=n},{"vtree/diff":44}],36:[function(t,e){function n(t){return"object"==typeof t&&null!==t}e.exports=n},{}],37:[function(t,e){function n(t,e,n){for(var o in e){var c=e[o];void 0===c?r(t,e,n,o):u(c)?c.hook(t,o,n?n[o]:void 0):s(c)?i(t,e,n,o,c):void 0!==c&&(t[o]=c)}}function r(t,e,n,r){if(n){var i=n[r];if(!u(i))if("attributes"===r)for(var o in i)t.removeAttribute(o);else if("style"===r)for(var s in i)t.style[s]="";else t[r]="string"==typeof i?"":null}}function i(t,e,n,r,i){var u=n?n[r]:void 0;if("attributes"!==r){if(u&&s(u)&&o(u)!==o(i))return void(t[r]=i);s(t[r])||(t[r]={});var c="style"===r?"":void 0;for(var a in i){var l=i[a];t[r][a]=void 0===l?c:l}}else for(var f in i){var h=i[f];void 0===h?t.removeAttribute(f):t.setAttribute(f,h)}}function o(t){return Object.getPrototypeOf?Object.getPrototypeOf(t):t.__proto__?t.__proto__:t.constructor?t.constructor.prototype:void 0}var s=t("is-object"),u=t("vtree/is-vhook");e.exports=n},{"is-object":36,"vtree/is-vhook":47}],38:[function(t,e){function n(t,e){var a=e?e.document||r:r,l=e?e.warn:null;if(t=c(t).a,u(t))return t.init();if(s(t))return a.createTextNode(t.text);if(!o(t))return l&&l("Item is not a valid virtual dom node",t),null;var f=null===t.namespace?a.createElement(t.tagName):a.createElementNS(t.namespace,t.tagName),h=t.properties;i(f,h);for(var p=t.children,d=0;d=o;){if(r=(s+o)/2>>0,i=t[r],o===s)return i>=e&&n>=i;if(e>i)o=r+1;else{if(!(i>n))return!0;s=r-1}}return!1}function o(t,e){return t>e?1:-1}var s={};e.exports=n},{}],40:[function(t,e){var n="undefined"!=typeof global?global:"undefined"!=typeof window?window:{},r=t("min-document");if("undefined"!=typeof document)e.exports=document;else{var i=n["__GLOBAL_DOCUMENT_CACHE@4"];i||(i=n["__GLOBAL_DOCUMENT_CACHE@4"]=r),e.exports=i}},{"min-document":2}],41:[function(t,e){function n(t,e,n){var c=t.type,h=t.vNode,d=t.patch;switch(c){case p.REMOVE:return r(e,h);case p.INSERT:return i(e,d,n);case p.VTEXT:return o(e,h,d,n);case p.WIDGET:return s(e,h,d,n);case p.VNODE:return u(e,h,d,n);case p.ORDER:return a(e,d),e;case p.PROPS:return f(e,d,h.properties),e;case p.THUNK:return l(e,n.patch(e,d,n));default:return e}}function r(t,e){var n=t.parentNode;return n&&n.removeChild(t),c(t,e),null}function i(t,e,n){var r=d(e,n);return t&&t.appendChild(r),t}function o(t,e,n,r){var i;if(3===t.nodeType)t.replaceData(0,t.length,n.text),i=t;else{var o=t.parentNode;i=d(n,r),o&&o.replaceChild(i,t)}return c(t,e),i}function s(t,e,n,r){if(v(e,n))return n.update(e,t)||t;var i=t.parentNode,o=d(n,r);return i&&i.replaceChild(o,t),c(t,e),o}function u(t,e,n,r){var i=t.parentNode,o=d(n,r);return i&&i.replaceChild(o,t),c(t,e),o}function c(t,e){"function"==typeof e.destroy&&h(e)&&e.destroy(t)}function a(t,e){var n,r=[],i=t.childNodes,o=i.length,s=e.reverse;for(n=0;o>n;n++)r.push(t.childNodes[n]);var u,c,a,l=0;for(n=0;o>n;n++)u=e[n],void 0!==u&&u!==n&&(s[n]>n&&l++,c=r[u],a=i[n+l],c!==a&&t.insertBefore(c,a),n>u&&l--),n in e.removes&&l++}function l(t,e){return t&&e&&t!==e&&t.parentNode&&(console.log(t),t.parentNode.replaceChild(e,t)),e}var f=t("./apply-properties"),h=t("vtree/is-widget"),p=t("vtree/vpatch"),d=t("./create-element"),v=t("./update-widget");e.exports=n},{"./apply-properties":37,"./create-element":38,"./update-widget":43,"vtree/is-widget":50,"vtree/vpatch":52}],42:[function(t,e){function n(t,e){return r(t,e)}function r(t,e,n){var u=o(e);if(0===u.length)return t;var a=c(t,e.a,u),l=t.ownerDocument;n||(n={patch:r},l!==s&&(n.document=l));for(var f=0;fl?a:l,d=0;h>d;d++){var v=s[d],g=c[d];o+=1,v?g?r(v,g,n,o):v&&(n[o]=new b(b.REMOVE,v,null),u(v,n,o)):g&&(i=p(i,new b(b.INSERT,null,g))),m(v)&&v.count&&(o+=v.count)}return c.moves&&(i=p(i,new b(b.ORDER,t,c.moves))),i}function u(t,e,n){if(y(t))"function"==typeof t.destroy&&(e[n]=new b(b.REMOVE,t,null));else if(m(t)&&t.hasWidgets)for(var r=t.children,i=r.length,o=0;i>o;o++){var s=r[o];n+=1,u(s,e,n),m(s)&&s.count&&(n+=s.count)}}function c(t,e,r,i){var o=x(t,e),s=n(o.a,o.b);a(s)&&(r[i]=new b(b.THUNK,null,s))}function a(t){for(var e in t)if("a"!==e)return!0;return!1}function l(t,e,n){if(m(t)&&(t.hooks&&(e[n]=new b(b.PROPS,t.hooks,t.hooks)),t.descendantHooks))for(var r=t.children,i=r.length,o=0;i>o;o++){var s=r[o];n+=1,l(s,e,n),m(s)&&s.count&&(n+=s.count)}}function f(t,e){var n=h(e);if(!n)return e;var r=h(t);if(!r)return e;var i={},o={};for(var s in n)i[n[s]]=r[s];for(var s in r)o[r[s]]=n[s];for(var u=t.length,c=e.length,a=u>c?u:c,l=[],f=0,p=0,d=0,v={},b=v.removes={},m=v.reverse={},g=!1;a>f;){var y=o[p];if(void 0!==y)l[p]=e[y],y!==d&&(v[y]=d,m[d]=y,g=!0),d++;else if(p in o)l[p]=void 0,b[p]=d++,g=!0;else{for(;void 0!==i[f];)f++;if(a>f){var w=e[f];w&&(l[p]=w,f!==d&&(g=!0,v[f]=d,m[d]=f),d++),f++}}p++}return g&&(l.moves=v),l}function h(t){var e,n;for(e=0;e=0;r--)if(i[r]!=o[r])return!1;for(r=i.length-1;r>=0;r--)if(n=i[r],!u(t[n],e[n]))return!1;return!0}function l(t,e){return t&&e?"[object RegExp]"==Object.prototype.toString.call(e)?e.test(t):t instanceof e?!0:e.call({},t)===!0?!0:!1:!1}function f(t,e,n,r){var i;h.isString(n)&&(r=n,n=null);try{e()}catch(s){i=s}if(r=(n&&n.name?" ("+n.name+").":".")+(r?" "+r:"."),t&&!i&&o(i,n,"Missing expected exception"+r),!t&&l(i,n)&&o(i,n,"Got unwanted exception"+r),t&&i&&n&&!l(i,n)||!t&&i)throw i}var h=t("util/"),p=Array.prototype.slice,d=Object.prototype.hasOwnProperty,v=e.exports=s;v.AssertionError=function(t){this.name="AssertionError",this.actual=t.actual,this.expected=t.expected,this.operator=t.operator,t.message?(this.message=t.message,this.generatedMessage=!1):(this.message=i(this),this.generatedMessage=!0);var e=t.stackStartFunction||o;if(Error.captureStackTrace)Error.captureStackTrace(this,e);else{var n=new Error;if(n.stack){var r=n.stack,s=e.name,u=r.indexOf("\n"+s);if(u>=0){var c=r.indexOf("\n",u+1);r=r.substring(c+1)}this.stack=r}}},h.inherits(v.AssertionError,Error),v.fail=o,v.ok=s,v.equal=function(t,e,n){t!=e&&o(t,e,n,"==",v.equal)},v.notEqual=function(t,e,n){t==e&&o(t,e,n,"!=",v.notEqual)},v.deepEqual=function(t,e,n){u(t,e)||o(t,e,n,"deepEqual",v.deepEqual)},v.notDeepEqual=function(t,e,n){u(t,e)&&o(t,e,n,"notDeepEqual",v.notDeepEqual)},v.strictEqual=function(t,e,n){t!==e&&o(t,e,n,"===",v.strictEqual)},v.notStrictEqual=function(t,e,n){t===e&&o(t,e,n,"!==",v.notStrictEqual)},v.throws=function(){f.apply(this,[!0].concat(p.call(arguments)))},v.doesNotThrow=function(){f.apply(this,[!1].concat(p.call(arguments)))},v.ifError=function(t){if(t)throw t};var b=Object.keys||function(t){var e=[];for(var n in t)d.call(t,n)&&e.push(n);return e}},{"util/":68}],66:[function(t,e){e.exports="function"==typeof Object.create?function(t,e){t.super_=e,t.prototype=Object.create(e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}})}:function(t,e){t.super_=e;var n=function(){};n.prototype=e.prototype,t.prototype=new n,t.prototype.constructor=t}},{}],67:[function(t,e){e.exports=function(t){return t&&"object"==typeof t&&"function"==typeof t.copy&&"function"==typeof t.fill&&"function"==typeof t.readUInt8}},{}],68:[function(t,e,n){function r(t,e){var r={seen:[],stylize:o};return arguments.length>=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),d(e)?r.showHidden=e:e&&n._extend(r,e),w(r.showHidden)&&(r.showHidden=!1),w(r.depth)&&(r.depth=2),w(r.colors)&&(r.colors=!1),w(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=i),u(r,t,r.depth)}function i(t,e){var n=r.styles[e];return n?"["+r.colors[n][0]+"m"+t+"["+r.colors[n][1]+"m":t}function o(t){return t}function s(t){var e={};return t.forEach(function(t){e[t]=!0}),e}function u(t,e,r){if(t.customInspect&&e&&O(e.inspect)&&e.inspect!==n.inspect&&(!e.constructor||e.constructor.prototype!==e)){var i=e.inspect(r,t);return g(i)||(i=u(t,i,r)),i}var o=c(t,e);if(o)return o;var d=Object.keys(e),v=s(d);if(t.showHidden&&(d=Object.getOwnPropertyNames(e)),N(e)&&(d.indexOf("message")>=0||d.indexOf("description")>=0))return a(e);if(0===d.length){if(O(e)){var b=e.name?": "+e.name:"";return t.stylize("[Function"+b+"]","special")}if(x(e))return t.stylize(RegExp.prototype.toString.call(e),"regexp");if(C(e))return t.stylize(Date.prototype.toString.call(e),"date");if(N(e))return a(e)}var m="",y=!1,w=["{","}"];if(p(e)&&(y=!0,w=["[","]"]),O(e)){var E=e.name?": "+e.name:"";m=" [Function"+E+"]"}if(x(e)&&(m=" "+RegExp.prototype.toString.call(e)),C(e)&&(m=" "+Date.prototype.toUTCString.call(e)),N(e)&&(m=" "+a(e)),0===d.length&&(!y||0==e.length))return w[0]+m+w[1];if(0>r)return x(e)?t.stylize(RegExp.prototype.toString.call(e),"regexp"):t.stylize("[Object]","special");t.seen.push(e);var k;return k=y?l(t,e,r,v,d):d.map(function(n){return f(t,e,r,v,n,y)}),t.seen.pop(),h(k,m,w)}function c(t,e){if(w(e))return t.stylize("undefined","undefined");if(g(e)){var n="'"+JSON.stringify(e).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return t.stylize(n,"string")}return m(e)?t.stylize(""+e,"number"):d(e)?t.stylize(""+e,"boolean"):v(e)?t.stylize("null","null"):void 0}function a(t){return"["+Error.prototype.toString.call(t)+"]"}function l(t,e,n,r,i){for(var o=[],s=0,u=e.length;u>s;++s)o.push(D(e,String(s))?f(t,e,n,r,String(s),!0):"");return i.forEach(function(i){i.match(/^\d+$/)||o.push(f(t,e,n,r,i,!0))}),o}function f(t,e,n,r,i,o){var s,c,a;if(a=Object.getOwnPropertyDescriptor(e,i)||{value:e[i]},a.get?c=a.set?t.stylize("[Getter/Setter]","special"):t.stylize("[Getter]","special"):a.set&&(c=t.stylize("[Setter]","special")),D(r,i)||(s="["+i+"]"),c||(t.seen.indexOf(a.value)<0?(c=v(n)?u(t,a.value,null):u(t,a.value,n-1),c.indexOf("\n")>-1&&(c=o?c.split("\n").map(function(t){return" "+t}).join("\n").substr(2):"\n"+c.split("\n").map(function(t){return" "+t}).join("\n"))):c=t.stylize("[Circular]","special")),w(s)){if(o&&i.match(/^\d+$/))return c;s=JSON.stringify(""+i),s.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(s=s.substr(1,s.length-2),s=t.stylize(s,"name")):(s=s.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),s=t.stylize(s,"string"))}return s+": "+c}function h(t,e,n){var r=0,i=t.reduce(function(t,e){return r++,e.indexOf("\n")>=0&&r++,t+e.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(""===e?"":e+"\n ")+" "+t.join(",\n ")+" "+n[1]:n[0]+e+" "+t.join(", ")+" "+n[1]}function p(t){return Array.isArray(t)}function d(t){return"boolean"==typeof t}function v(t){return null===t}function b(t){return null==t}function m(t){return"number"==typeof t}function g(t){return"string"==typeof t}function y(t){return"symbol"==typeof t}function w(t){return void 0===t}function x(t){return E(t)&&"[object RegExp]"===S(t)}function E(t){return"object"==typeof t&&null!==t}function C(t){return E(t)&&"[object Date]"===S(t)}function N(t){return E(t)&&("[object Error]"===S(t)||t instanceof Error)}function O(t){return"function"==typeof t}function k(t){return null===t||"boolean"==typeof t||"number"==typeof t||"string"==typeof t||"symbol"==typeof t||"undefined"==typeof t}function S(t){return Object.prototype.toString.call(t)}function A(t){return 10>t?"0"+t.toString(10):t.toString(10)}function j(){var t=new Date,e=[A(t.getHours()),A(t.getMinutes()),A(t.getSeconds())].join(":");return[t.getDate(),T[t.getMonth()],e].join(" ")}function D(t,e){return Object.prototype.hasOwnProperty.call(t,e)}var _=/%[sdj%]/g;n.format=function(t){if(!g(t)){for(var e=[],n=0;n=o)return t;switch(t){case"%s":return String(i[n++]);case"%d":return Number(i[n++]);case"%j":try{return JSON.stringify(i[n++])}catch(e){return"[Circular]"}default:return t}}),u=i[n];o>n;u=i[++n])s+=v(u)||!E(u)?" "+u:" "+r(u);return s},n.deprecate=function(t,e){function r(){if(!i){if(process.throwDeprecation)throw new Error(e);process.traceDeprecation?console.trace(e):console.error(e),i=!0}return t.apply(this,arguments)}if(w(global.process))return function(){return n.deprecate(t,e).apply(this,arguments)};if(process.noDeprecation===!0)return t;var i=!1;return r};var W,R={};n.debuglog=function(t){if(w(W)&&(W=process.env.NODE_DEBUG||""),t=t.toUpperCase(),!R[t])if(new RegExp("\\b"+t+"\\b","i").test(W)){var e=process.pid;R[t]=function(){var r=n.format.apply(n,arguments);console.error("%s %d: %s",t,e,r)}}else R[t]=function(){};return R[t]},n.inspect=r,r.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},r.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},n.isArray=p,n.isBoolean=d,n.isNull=v,n.isNullOrUndefined=b,n.isNumber=m,n.isString=g,n.isSymbol=y,n.isUndefined=w,n.isRegExp=x,n.isObject=E,n.isDate=C,n.isError=N,n.isFunction=O,n.isPrimitive=k,n.isBuffer=t("./support/isBuffer");var T=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];n.log=function(){console.log("%s - %s",j(),n.format.apply(n,arguments))},n.inherits=t("inherits"),n._extend=function(t,e){if(!e||!E(e))return t;for(var n=Object.keys(e),r=n.length;r--;)t[n[r]]=e[n[r]];return t}},{"./support/isBuffer":67,inherits:66}],69:[function(t,e){function n(t){return t&&"object"==typeof t?s(t)?i(t,n):o(c(t),function(e,i){var o=r(i);return e[o]=n(t[i]),e},{}):t}function r(t){return t.replace(/[_.-](\w|$)/g,function(t,e){return e.toUpperCase()})}function i(t,e){if(t.map)return t.map(e);for(var n=[],r=0;r2?arguments[2]:null;if(u===+u)for(r=0;u>r;r++)null===c?e(s?t.charAt(r):t[r],r,t):e.call(c,s?t.charAt(r):t[r],r,t);else for(o in t)n.call(t,o)&&(null===c?e(t[o],o,t):e.call(c,t[o],o,t))}},{}],74:[function(t,e){e.exports=Object.keys||t("./shim")},{"./shim":76}],75:[function(t,e){var n=Object.prototype.toString;e.exports=function r(t){var e=n.call(t),r="[object Arguments]"===e;return r||(r="[object Array]"!==e&&null!==t&&"object"==typeof t&&"number"==typeof t.length&&t.length>=0&&"[object Function]"===n.call(t.callee)),r}},{}],76:[function(t,e){!function(){"use strict";var n,r=Object.prototype.hasOwnProperty,i=Object.prototype.toString,o=t("./foreach"),s=t("./isArguments"),u=!{toString:null}.propertyIsEnumerable("toString"),c=function(){}.propertyIsEnumerable("prototype"),a=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"];n=function(t){var e=null!==t&&"object"==typeof t,n="[object Function]"===i.call(t),l=s(t),f=[];if(!e&&!n&&!l)throw new TypeError("Object.keys called on a non-object");if(l)o(t,function(t){f.push(t)});else{var h,p=c&&n;for(h in t)p&&"prototype"===h||!r.call(t,h)||f.push(h)}if(u){var d=t.constructor,v=d&&d.prototype===t;o(a,function(e){v&&"constructor"===e||!r.call(t,e)||f.push(e)})}return f},e.exports=n}()},{"./foreach":73,"./isArguments":75}],77:[function(t,e){function n(t){function e(e){var r=new Error;Object.defineProperty(r,"type",{value:r.type,enumerable:!0,writable:!0,configurable:!0});var i=s({},t,e);return s(r,i),r.message=o(n,i),r}r(t,"args is required"),r(t.type,"args.type is required"),r(t.message,"args.message is required");var n=t.message;if(t.type&&!t.name){var u=i(t.type)+"Error";t.name=u[0].toUpperCase()+u.substr(1)}return e.type=t.type,e._name=t.name,e}var r=t("assert/"),i=t("camelize"),o=t("string-template"),s=t("xtend/mutable");e.exports=n},{"assert/":65,camelize:69,"string-template":70,"xtend/mutable":72}],78:[function(t,e){e.exports=t(46)},{}],79:[function(t,e){e.exports=t(47)},{}],80:[function(t,e){e.exports=t(48)},{"./version":83}],81:[function(t,e){e.exports=t(49)},{"./version":83}],82:[function(t,e){e.exports=t(50)},{}],83:[function(t,e){e.exports=t(51)},{}],84:[function(t,e){function n(t,e,n,r,a){this.tagName=t,this.properties=e||u,this.children=n||c,this.key=null!=r?String(r):void 0,this.namespace="string"==typeof a?a:null;var l,f=n&&n.length||0,h=0,p=!1,d=!1;for(var v in e)if(e.hasOwnProperty(v)){var b=e[v];s(b)&&(l||(l={}),l[v]=b)}for(var m=0;f>m;m++){var g=n[m];i(g)?(h+=g.count||0,!p&&g.hasWidgets&&(p=!0),d||!g.hooks&&!g.descendantHooks||(d=!0)):!p&&o(g)&&"function"==typeof g.destroy&&(p=!0)}this.count=f+h,this.hasWidgets=p,this.hooks=l,this.descendantHooks=d}var r=t("./version"),i=t("./is-vnode"),o=t("./is-widget"),s=t("./is-vhook");e.exports=n;var u={},c=[];n.prototype.version=r,n.prototype.type="VirtualNode"},{"./is-vhook":79,"./is-vnode":80,"./is-widget":82,"./version":83}],85:[function(t,e){function n(t){this.text=String(t)}var r=t("./version");e.exports=n,n.prototype.version=r,n.prototype.type="VirtualText"},{"./version":83}],86:[function(t,e){function n(t,e){if(!t)return"div";var n=!("id"in e),o=t.split(r),s=null;i.test(o[1])&&(s="div");var u,c,a,l;for(l=0;l + * @license MIT + */ + +var base64 = require('base64-js') +var ieee754 = require('ieee754') + +exports.Buffer = Buffer +exports.SlowBuffer = Buffer +exports.INSPECT_MAX_BYTES = 50 +Buffer.poolSize = 8192 + +/** + * If `Buffer._useTypedArrays`: + * === true Use Uint8Array implementation (fastest) + * === false Use Object implementation (compatible down to IE6) + */ +Buffer._useTypedArrays = (function () { + // Detect if browser supports Typed Arrays. Supported browsers are IE 10+, Firefox 4+, + // Chrome 7+, Safari 5.1+, Opera 11.6+, iOS 4.2+. If the browser does not support adding + // properties to `Uint8Array` instances, then that's the same as no `Uint8Array` support + // because we need to be able to add all the node Buffer API methods. This is an issue + // in Firefox 4-29. Now fixed: https://bugzilla.mozilla.org/show_bug.cgi?id=695438 + try { + var buf = new ArrayBuffer(0) + var arr = new Uint8Array(buf) + arr.foo = function () { return 42 } + return 42 === arr.foo() && + typeof arr.subarray === 'function' // Chrome 9-10 lack `subarray` + } catch (e) { + return false + } +})() + +/** + * Class: Buffer + * ============= + * + * The Buffer constructor returns instances of `Uint8Array` that are augmented + * with function properties for all the node `Buffer` API functions. We use + * `Uint8Array` so that square bracket notation works as expected -- it returns + * a single octet. + * + * By augmenting the instances, we can avoid modifying the `Uint8Array` + * prototype. + */ +function Buffer (subject, encoding, noZero) { + if (!(this instanceof Buffer)) + return new Buffer(subject, encoding, noZero) + + var type = typeof subject + + // Workaround: node's base64 implementation allows for non-padded strings + // while base64-js does not. + if (encoding === 'base64' && type === 'string') { + subject = stringtrim(subject) + while (subject.length % 4 !== 0) { + subject = subject + '=' + } + } + + // Find the length + var length + if (type === 'number') + length = coerce(subject) + else if (type === 'string') + length = Buffer.byteLength(subject, encoding) + else if (type === 'object') + length = coerce(subject.length) // assume that object is array-like + else + throw new Error('First argument needs to be a number, array or string.') + + var buf + if (Buffer._useTypedArrays) { + // Preferred: Return an augmented `Uint8Array` instance for best performance + buf = Buffer._augment(new Uint8Array(length)) + } else { + // Fallback: Return THIS instance of Buffer (created by `new`) + buf = this + buf.length = length + buf._isBuffer = true + } + + var i + if (Buffer._useTypedArrays && typeof subject.byteLength === 'number') { + // Speed optimization -- use set if we're copying from a typed array + buf._set(subject) + } else if (isArrayish(subject)) { + // Treat array-ish objects as a byte array + for (i = 0; i < length; i++) { + if (Buffer.isBuffer(subject)) + buf[i] = subject.readUInt8(i) + else + buf[i] = subject[i] + } + } else if (type === 'string') { + buf.write(subject, 0, encoding) + } else if (type === 'number' && !Buffer._useTypedArrays && !noZero) { + for (i = 0; i < length; i++) { + buf[i] = 0 + } + } + + return buf +} + +// STATIC METHODS +// ============== + +Buffer.isEncoding = function (encoding) { + switch (String(encoding).toLowerCase()) { + case 'hex': + case 'utf8': + case 'utf-8': + case 'ascii': + case 'binary': + case 'base64': + case 'raw': + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + return true + default: + return false + } +} + +Buffer.isBuffer = function (b) { + return !!(b !== null && b !== undefined && b._isBuffer) +} + +Buffer.byteLength = function (str, encoding) { + var ret + str = str + '' + switch (encoding || 'utf8') { + case 'hex': + ret = str.length / 2 + break + case 'utf8': + case 'utf-8': + ret = utf8ToBytes(str).length + break + case 'ascii': + case 'binary': + case 'raw': + ret = str.length + break + case 'base64': + ret = base64ToBytes(str).length + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = str.length * 2 + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.concat = function (list, totalLength) { + assert(isArray(list), 'Usage: Buffer.concat(list, [totalLength])\n' + + 'list should be an Array.') + + if (list.length === 0) { + return new Buffer(0) + } else if (list.length === 1) { + return list[0] + } + + var i + if (typeof totalLength !== 'number') { + totalLength = 0 + for (i = 0; i < list.length; i++) { + totalLength += list[i].length + } + } + + var buf = new Buffer(totalLength) + var pos = 0 + for (i = 0; i < list.length; i++) { + var item = list[i] + item.copy(buf, pos) + pos += item.length + } + return buf +} + +// BUFFER INSTANCE METHODS +// ======================= + +function _hexWrite (buf, string, offset, length) { + offset = Number(offset) || 0 + var remaining = buf.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + + // must be an even number of digits + var strLen = string.length + assert(strLen % 2 === 0, 'Invalid hex string') + + if (length > strLen / 2) { + length = strLen / 2 + } + for (var i = 0; i < length; i++) { + var byte = parseInt(string.substr(i * 2, 2), 16) + assert(!isNaN(byte), 'Invalid hex string') + buf[offset + i] = byte + } + Buffer._charsWritten = i * 2 + return i +} + +function _utf8Write (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(utf8ToBytes(string), buf, offset, length) + return charsWritten +} + +function _asciiWrite (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(asciiToBytes(string), buf, offset, length) + return charsWritten +} + +function _binaryWrite (buf, string, offset, length) { + return _asciiWrite(buf, string, offset, length) +} + +function _base64Write (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(base64ToBytes(string), buf, offset, length) + return charsWritten +} + +function _utf16leWrite (buf, string, offset, length) { + var charsWritten = Buffer._charsWritten = + blitBuffer(utf16leToBytes(string), buf, offset, length) + return charsWritten +} + +Buffer.prototype.write = function (string, offset, length, encoding) { + // Support both (string, offset, length, encoding) + // and the legacy (string, encoding, offset, length) + if (isFinite(offset)) { + if (!isFinite(length)) { + encoding = length + length = undefined + } + } else { // legacy + var swap = encoding + encoding = offset + offset = length + length = swap + } + + offset = Number(offset) || 0 + var remaining = this.length - offset + if (!length) { + length = remaining + } else { + length = Number(length) + if (length > remaining) { + length = remaining + } + } + encoding = String(encoding || 'utf8').toLowerCase() + + var ret + switch (encoding) { + case 'hex': + ret = _hexWrite(this, string, offset, length) + break + case 'utf8': + case 'utf-8': + ret = _utf8Write(this, string, offset, length) + break + case 'ascii': + ret = _asciiWrite(this, string, offset, length) + break + case 'binary': + ret = _binaryWrite(this, string, offset, length) + break + case 'base64': + ret = _base64Write(this, string, offset, length) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = _utf16leWrite(this, string, offset, length) + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.prototype.toString = function (encoding, start, end) { + var self = this + + encoding = String(encoding || 'utf8').toLowerCase() + start = Number(start) || 0 + end = (end !== undefined) + ? Number(end) + : end = self.length + + // Fastpath empty strings + if (end === start) + return '' + + var ret + switch (encoding) { + case 'hex': + ret = _hexSlice(self, start, end) + break + case 'utf8': + case 'utf-8': + ret = _utf8Slice(self, start, end) + break + case 'ascii': + ret = _asciiSlice(self, start, end) + break + case 'binary': + ret = _binarySlice(self, start, end) + break + case 'base64': + ret = _base64Slice(self, start, end) + break + case 'ucs2': + case 'ucs-2': + case 'utf16le': + case 'utf-16le': + ret = _utf16leSlice(self, start, end) + break + default: + throw new Error('Unknown encoding') + } + return ret +} + +Buffer.prototype.toJSON = function () { + return { + type: 'Buffer', + data: Array.prototype.slice.call(this._arr || this, 0) + } +} + +// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) +Buffer.prototype.copy = function (target, target_start, start, end) { + var source = this + + if (!start) start = 0 + if (!end && end !== 0) end = this.length + if (!target_start) target_start = 0 + + // Copy 0 bytes; we're done + if (end === start) return + if (target.length === 0 || source.length === 0) return + + // Fatal error conditions + assert(end >= start, 'sourceEnd < sourceStart') + assert(target_start >= 0 && target_start < target.length, + 'targetStart out of bounds') + assert(start >= 0 && start < source.length, 'sourceStart out of bounds') + assert(end >= 0 && end <= source.length, 'sourceEnd out of bounds') + + // Are we oob? + if (end > this.length) + end = this.length + if (target.length - target_start < end - start) + end = target.length - target_start + start + + var len = end - start + + if (len < 100 || !Buffer._useTypedArrays) { + for (var i = 0; i < len; i++) + target[i + target_start] = this[i + start] + } else { + target._set(this.subarray(start, start + len), target_start) + } +} + +function _base64Slice (buf, start, end) { + if (start === 0 && end === buf.length) { + return base64.fromByteArray(buf) + } else { + return base64.fromByteArray(buf.slice(start, end)) + } +} + +function _utf8Slice (buf, start, end) { + var res = '' + var tmp = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) { + if (buf[i] <= 0x7F) { + res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) + tmp = '' + } else { + tmp += '%' + buf[i].toString(16) + } + } + + return res + decodeUtf8Char(tmp) +} + +function _asciiSlice (buf, start, end) { + var ret = '' + end = Math.min(buf.length, end) + + for (var i = start; i < end; i++) + ret += String.fromCharCode(buf[i]) + return ret +} + +function _binarySlice (buf, start, end) { + return _asciiSlice(buf, start, end) +} + +function _hexSlice (buf, start, end) { + var len = buf.length + + if (!start || start < 0) start = 0 + if (!end || end < 0 || end > len) end = len + + var out = '' + for (var i = start; i < end; i++) { + out += toHex(buf[i]) + } + return out +} + +function _utf16leSlice (buf, start, end) { + var bytes = buf.slice(start, end) + var res = '' + for (var i = 0; i < bytes.length; i += 2) { + res += String.fromCharCode(bytes[i] + bytes[i+1] * 256) + } + return res +} + +Buffer.prototype.slice = function (start, end) { + var len = this.length + start = clamp(start, len, 0) + end = clamp(end, len, len) + + if (Buffer._useTypedArrays) { + return Buffer._augment(this.subarray(start, end)) + } else { + var sliceLen = end - start + var newBuf = new Buffer(sliceLen, undefined, true) + for (var i = 0; i < sliceLen; i++) { + newBuf[i] = this[i + start] + } + return newBuf + } +} + +// `get` will be removed in Node 0.13+ +Buffer.prototype.get = function (offset) { + console.log('.get() is deprecated. Access using array indexes instead.') + return this.readUInt8(offset) +} + +// `set` will be removed in Node 0.13+ +Buffer.prototype.set = function (v, offset) { + console.log('.set() is deprecated. Access using array indexes instead.') + return this.writeUInt8(v, offset) +} + +Buffer.prototype.readUInt8 = function (offset, noAssert) { + if (!noAssert) { + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'Trying to read beyond buffer length') + } + + if (offset >= this.length) + return + + return this[offset] +} + +function _readUInt16 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val + if (littleEndian) { + val = buf[offset] + if (offset + 1 < len) + val |= buf[offset + 1] << 8 + } else { + val = buf[offset] << 8 + if (offset + 1 < len) + val |= buf[offset + 1] + } + return val +} + +Buffer.prototype.readUInt16LE = function (offset, noAssert) { + return _readUInt16(this, offset, true, noAssert) +} + +Buffer.prototype.readUInt16BE = function (offset, noAssert) { + return _readUInt16(this, offset, false, noAssert) +} + +function _readUInt32 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val + if (littleEndian) { + if (offset + 2 < len) + val = buf[offset + 2] << 16 + if (offset + 1 < len) + val |= buf[offset + 1] << 8 + val |= buf[offset] + if (offset + 3 < len) + val = val + (buf[offset + 3] << 24 >>> 0) + } else { + if (offset + 1 < len) + val = buf[offset + 1] << 16 + if (offset + 2 < len) + val |= buf[offset + 2] << 8 + if (offset + 3 < len) + val |= buf[offset + 3] + val = val + (buf[offset] << 24 >>> 0) + } + return val +} + +Buffer.prototype.readUInt32LE = function (offset, noAssert) { + return _readUInt32(this, offset, true, noAssert) +} + +Buffer.prototype.readUInt32BE = function (offset, noAssert) { + return _readUInt32(this, offset, false, noAssert) +} + +Buffer.prototype.readInt8 = function (offset, noAssert) { + if (!noAssert) { + assert(offset !== undefined && offset !== null, + 'missing offset') + assert(offset < this.length, 'Trying to read beyond buffer length') + } + + if (offset >= this.length) + return + + var neg = this[offset] & 0x80 + if (neg) + return (0xff - this[offset] + 1) * -1 + else + return this[offset] +} + +function _readInt16 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val = _readUInt16(buf, offset, littleEndian, true) + var neg = val & 0x8000 + if (neg) + return (0xffff - val + 1) * -1 + else + return val +} + +Buffer.prototype.readInt16LE = function (offset, noAssert) { + return _readInt16(this, offset, true, noAssert) +} + +Buffer.prototype.readInt16BE = function (offset, noAssert) { + return _readInt16(this, offset, false, noAssert) +} + +function _readInt32 (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + var len = buf.length + if (offset >= len) + return + + var val = _readUInt32(buf, offset, littleEndian, true) + var neg = val & 0x80000000 + if (neg) + return (0xffffffff - val + 1) * -1 + else + return val +} + +Buffer.prototype.readInt32LE = function (offset, noAssert) { + return _readInt32(this, offset, true, noAssert) +} + +Buffer.prototype.readInt32BE = function (offset, noAssert) { + return _readInt32(this, offset, false, noAssert) +} + +function _readFloat (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset + 3 < buf.length, 'Trying to read beyond buffer length') + } + + return ieee754.read(buf, offset, littleEndian, 23, 4) +} + +Buffer.prototype.readFloatLE = function (offset, noAssert) { + return _readFloat(this, offset, true, noAssert) +} + +Buffer.prototype.readFloatBE = function (offset, noAssert) { + return _readFloat(this, offset, false, noAssert) +} + +function _readDouble (buf, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset + 7 < buf.length, 'Trying to read beyond buffer length') + } + + return ieee754.read(buf, offset, littleEndian, 52, 8) +} + +Buffer.prototype.readDoubleLE = function (offset, noAssert) { + return _readDouble(this, offset, true, noAssert) +} + +Buffer.prototype.readDoubleBE = function (offset, noAssert) { + return _readDouble(this, offset, false, noAssert) +} + +Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'trying to write beyond buffer length') + verifuint(value, 0xff) + } + + if (offset >= this.length) return + + this[offset] = value +} + +function _writeUInt16 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'trying to write beyond buffer length') + verifuint(value, 0xffff) + } + + var len = buf.length + if (offset >= len) + return + + for (var i = 0, j = Math.min(len - offset, 2); i < j; i++) { + buf[offset + i] = + (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> + (littleEndian ? i : 1 - i) * 8 + } +} + +Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { + _writeUInt16(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { + _writeUInt16(this, value, offset, false, noAssert) +} + +function _writeUInt32 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'trying to write beyond buffer length') + verifuint(value, 0xffffffff) + } + + var len = buf.length + if (offset >= len) + return + + for (var i = 0, j = Math.min(len - offset, 4); i < j; i++) { + buf[offset + i] = + (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff + } +} + +Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { + _writeUInt32(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { + _writeUInt32(this, value, offset, false, noAssert) +} + +Buffer.prototype.writeInt8 = function (value, offset, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset < this.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7f, -0x80) + } + + if (offset >= this.length) + return + + if (value >= 0) + this.writeUInt8(value, offset, noAssert) + else + this.writeUInt8(0xff + value + 1, offset, noAssert) +} + +function _writeInt16 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 1 < buf.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7fff, -0x8000) + } + + var len = buf.length + if (offset >= len) + return + + if (value >= 0) + _writeUInt16(buf, value, offset, littleEndian, noAssert) + else + _writeUInt16(buf, 0xffff + value + 1, offset, littleEndian, noAssert) +} + +Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { + _writeInt16(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { + _writeInt16(this, value, offset, false, noAssert) +} + +function _writeInt32 (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') + verifsint(value, 0x7fffffff, -0x80000000) + } + + var len = buf.length + if (offset >= len) + return + + if (value >= 0) + _writeUInt32(buf, value, offset, littleEndian, noAssert) + else + _writeUInt32(buf, 0xffffffff + value + 1, offset, littleEndian, noAssert) +} + +Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { + _writeInt32(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { + _writeInt32(this, value, offset, false, noAssert) +} + +function _writeFloat (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 3 < buf.length, 'Trying to write beyond buffer length') + verifIEEE754(value, 3.4028234663852886e+38, -3.4028234663852886e+38) + } + + var len = buf.length + if (offset >= len) + return + + ieee754.write(buf, value, offset, littleEndian, 23, 4) +} + +Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { + _writeFloat(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { + _writeFloat(this, value, offset, false, noAssert) +} + +function _writeDouble (buf, value, offset, littleEndian, noAssert) { + if (!noAssert) { + assert(value !== undefined && value !== null, 'missing value') + assert(typeof littleEndian === 'boolean', 'missing or invalid endian') + assert(offset !== undefined && offset !== null, 'missing offset') + assert(offset + 7 < buf.length, + 'Trying to write beyond buffer length') + verifIEEE754(value, 1.7976931348623157E+308, -1.7976931348623157E+308) + } + + var len = buf.length + if (offset >= len) + return + + ieee754.write(buf, value, offset, littleEndian, 52, 8) +} + +Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { + _writeDouble(this, value, offset, true, noAssert) +} + +Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { + _writeDouble(this, value, offset, false, noAssert) +} + +// fill(value, start=0, end=buffer.length) +Buffer.prototype.fill = function (value, start, end) { + if (!value) value = 0 + if (!start) start = 0 + if (!end) end = this.length + + if (typeof value === 'string') { + value = value.charCodeAt(0) + } + + assert(typeof value === 'number' && !isNaN(value), 'value is not a number') + assert(end >= start, 'end < start') + + // Fill 0 bytes; we're done + if (end === start) return + if (this.length === 0) return + + assert(start >= 0 && start < this.length, 'start out of bounds') + assert(end >= 0 && end <= this.length, 'end out of bounds') + + for (var i = start; i < end; i++) { + this[i] = value + } +} + +Buffer.prototype.inspect = function () { + var out = [] + var len = this.length + for (var i = 0; i < len; i++) { + out[i] = toHex(this[i]) + if (i === exports.INSPECT_MAX_BYTES) { + out[i + 1] = '...' + break + } + } + return '' +} + +/** + * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. + * Added in Node 0.12. Only available in browsers that support ArrayBuffer. + */ +Buffer.prototype.toArrayBuffer = function () { + if (typeof Uint8Array !== 'undefined') { + if (Buffer._useTypedArrays) { + return (new Buffer(this)).buffer + } else { + var buf = new Uint8Array(this.length) + for (var i = 0, len = buf.length; i < len; i += 1) + buf[i] = this[i] + return buf.buffer + } + } else { + throw new Error('Buffer.toArrayBuffer not supported in this browser') + } +} + +// HELPER FUNCTIONS +// ================ + +function stringtrim (str) { + if (str.trim) return str.trim() + return str.replace(/^\s+|\s+$/g, '') +} + +var BP = Buffer.prototype + +/** + * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods + */ +Buffer._augment = function (arr) { + arr._isBuffer = true + + // save reference to original Uint8Array get/set methods before overwriting + arr._get = arr.get + arr._set = arr.set + + // deprecated, will be removed in node 0.13+ + arr.get = BP.get + arr.set = BP.set + + arr.write = BP.write + arr.toString = BP.toString + arr.toLocaleString = BP.toString + arr.toJSON = BP.toJSON + arr.copy = BP.copy + arr.slice = BP.slice + arr.readUInt8 = BP.readUInt8 + arr.readUInt16LE = BP.readUInt16LE + arr.readUInt16BE = BP.readUInt16BE + arr.readUInt32LE = BP.readUInt32LE + arr.readUInt32BE = BP.readUInt32BE + arr.readInt8 = BP.readInt8 + arr.readInt16LE = BP.readInt16LE + arr.readInt16BE = BP.readInt16BE + arr.readInt32LE = BP.readInt32LE + arr.readInt32BE = BP.readInt32BE + arr.readFloatLE = BP.readFloatLE + arr.readFloatBE = BP.readFloatBE + arr.readDoubleLE = BP.readDoubleLE + arr.readDoubleBE = BP.readDoubleBE + arr.writeUInt8 = BP.writeUInt8 + arr.writeUInt16LE = BP.writeUInt16LE + arr.writeUInt16BE = BP.writeUInt16BE + arr.writeUInt32LE = BP.writeUInt32LE + arr.writeUInt32BE = BP.writeUInt32BE + arr.writeInt8 = BP.writeInt8 + arr.writeInt16LE = BP.writeInt16LE + arr.writeInt16BE = BP.writeInt16BE + arr.writeInt32LE = BP.writeInt32LE + arr.writeInt32BE = BP.writeInt32BE + arr.writeFloatLE = BP.writeFloatLE + arr.writeFloatBE = BP.writeFloatBE + arr.writeDoubleLE = BP.writeDoubleLE + arr.writeDoubleBE = BP.writeDoubleBE + arr.fill = BP.fill + arr.inspect = BP.inspect + arr.toArrayBuffer = BP.toArrayBuffer + + return arr +} + +// slice(start, end) +function clamp (index, len, defaultValue) { + if (typeof index !== 'number') return defaultValue + index = ~~index; // Coerce to integer. + if (index >= len) return len + if (index >= 0) return index + index += len + if (index >= 0) return index + return 0 +} + +function coerce (length) { + // Coerce length to a number (possibly NaN), round up + // in case it's fractional (e.g. 123.456) then do a + // double negate to coerce a NaN to 0. Easy, right? + length = ~~Math.ceil(+length) + return length < 0 ? 0 : length +} + +function isArray (subject) { + return (Array.isArray || function (subject) { + return Object.prototype.toString.call(subject) === '[object Array]' + })(subject) +} + +function isArrayish (subject) { + return isArray(subject) || Buffer.isBuffer(subject) || + subject && typeof subject === 'object' && + typeof subject.length === 'number' +} + +function toHex (n) { + if (n < 16) return '0' + n.toString(16) + return n.toString(16) +} + +function utf8ToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + var b = str.charCodeAt(i) + if (b <= 0x7F) + byteArray.push(str.charCodeAt(i)) + else { + var start = i + if (b >= 0xD800 && b <= 0xDFFF) i++ + var h = encodeURIComponent(str.slice(start, i+1)).substr(1).split('%') + for (var j = 0; j < h.length; j++) + byteArray.push(parseInt(h[j], 16)) + } + } + return byteArray +} + +function asciiToBytes (str) { + var byteArray = [] + for (var i = 0; i < str.length; i++) { + // Node's code seems to be doing this and not & 0x7F.. + byteArray.push(str.charCodeAt(i) & 0xFF) + } + return byteArray +} + +function utf16leToBytes (str) { + var c, hi, lo + var byteArray = [] + for (var i = 0; i < str.length; i++) { + c = str.charCodeAt(i) + hi = c >> 8 + lo = c % 256 + byteArray.push(lo) + byteArray.push(hi) + } + + return byteArray +} + +function base64ToBytes (str) { + return base64.toByteArray(str) +} + +function blitBuffer (src, dst, offset, length) { + var pos + for (var i = 0; i < length; i++) { + if ((i + offset >= dst.length) || (i >= src.length)) + break + dst[i + offset] = src[i] + } + return i +} + +function decodeUtf8Char (str) { + try { + return decodeURIComponent(str) + } catch (err) { + return String.fromCharCode(0xFFFD) // UTF 8 invalid char + } +} + +/* + * We have to make sure that the value is a valid integer. This means that it + * is non-negative. It has no fractional component and that it does not + * exceed the maximum allowed value. + */ +function verifuint (value, max) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value >= 0, 'specified a negative value for writing an unsigned value') + assert(value <= max, 'value is larger than maximum value for type') + assert(Math.floor(value) === value, 'value has a fractional component') +} + +function verifsint (value, max, min) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value <= max, 'value larger than maximum allowed value') + assert(value >= min, 'value smaller than minimum allowed value') + assert(Math.floor(value) === value, 'value has a fractional component') +} + +function verifIEEE754 (value, max, min) { + assert(typeof value === 'number', 'cannot write a non-number as a number') + assert(value <= max, 'value larger than maximum allowed value') + assert(value >= min, 'value smaller than minimum allowed value') +} + +function assert (test, message) { + if (!test) throw new Error(message || 'Failed assertion') +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/gulp-browserify/node_modules/browserify/node_modules/buffer/index.js","/../../node_modules/gulp-browserify/node_modules/browserify/node_modules/buffer") +},{"base64-js":4,"buffer":3,"ieee754":5,"oMfpAn":7}],4:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + +;(function (exports) { + 'use strict'; + + var Arr = (typeof Uint8Array !== 'undefined') + ? Uint8Array + : Array + + var PLUS = '+'.charCodeAt(0) + var SLASH = '/'.charCodeAt(0) + var NUMBER = '0'.charCodeAt(0) + var LOWER = 'a'.charCodeAt(0) + var UPPER = 'A'.charCodeAt(0) + + function decode (elt) { + var code = elt.charCodeAt(0) + if (code === PLUS) + return 62 // '+' + if (code === SLASH) + return 63 // '/' + if (code < NUMBER) + return -1 //no match + if (code < NUMBER + 10) + return code - NUMBER + 26 + 26 + if (code < UPPER + 26) + return code - UPPER + if (code < LOWER + 26) + return code - LOWER + 26 + } + + function b64ToByteArray (b64) { + var i, j, l, tmp, placeHolders, arr + + if (b64.length % 4 > 0) { + throw new Error('Invalid string. Length must be a multiple of 4') + } + + // the number of equal signs (place holders) + // if there are two placeholders, than the two characters before it + // represent one byte + // if there is only one, then the three characters before it represent 2 bytes + // this is just a cheap hack to not do indexOf twice + var len = b64.length + placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 + + // base64 is 4/3 + up to two characters of the original data + arr = new Arr(b64.length * 3 / 4 - placeHolders) + + // if there are placeholders, only get up to the last complete 4 chars + l = placeHolders > 0 ? b64.length - 4 : b64.length + + var L = 0 + + function push (v) { + arr[L++] = v + } + + for (i = 0, j = 0; i < l; i += 4, j += 3) { + tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) + push((tmp & 0xFF0000) >> 16) + push((tmp & 0xFF00) >> 8) + push(tmp & 0xFF) + } + + if (placeHolders === 2) { + tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) + push(tmp & 0xFF) + } else if (placeHolders === 1) { + tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) + push((tmp >> 8) & 0xFF) + push(tmp & 0xFF) + } + + return arr + } + + function uint8ToBase64 (uint8) { + var i, + extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes + output = "", + temp, length + + function encode (num) { + return lookup.charAt(num) + } + + function tripletToBase64 (num) { + return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) + } + + // go through the array every three bytes, we'll deal with trailing stuff later + for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { + temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) + output += tripletToBase64(temp) + } + + // pad the end with zeros, but make sure to not forget the extra bytes + switch (extraBytes) { + case 1: + temp = uint8[uint8.length - 1] + output += encode(temp >> 2) + output += encode((temp << 4) & 0x3F) + output += '==' + break + case 2: + temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) + output += encode(temp >> 10) + output += encode((temp >> 4) & 0x3F) + output += encode((temp << 2) & 0x3F) + output += '=' + break + } + + return output + } + + exports.toByteArray = b64ToByteArray + exports.fromByteArray = uint8ToBase64 +}(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/gulp-browserify/node_modules/browserify/node_modules/buffer/node_modules/base64-js/lib/b64.js","/../../node_modules/gulp-browserify/node_modules/browserify/node_modules/buffer/node_modules/base64-js/lib") +},{"buffer":3,"oMfpAn":7}],5:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +exports.read = function(buffer, offset, isLE, mLen, nBytes) { + var e, m, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + nBits = -7, + i = isLE ? (nBytes - 1) : 0, + d = isLE ? -1 : 1, + s = buffer[offset + i]; + + i += d; + + e = s & ((1 << (-nBits)) - 1); + s >>= (-nBits); + nBits += eLen; + for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); + + m = e & ((1 << (-nBits)) - 1); + e >>= (-nBits); + nBits += mLen; + for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); + + if (e === 0) { + e = 1 - eBias; + } else if (e === eMax) { + return m ? NaN : ((s ? -1 : 1) * Infinity); + } else { + m = m + Math.pow(2, mLen); + e = e - eBias; + } + return (s ? -1 : 1) * m * Math.pow(2, e - mLen); +}; + +exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { + var e, m, c, + eLen = nBytes * 8 - mLen - 1, + eMax = (1 << eLen) - 1, + eBias = eMax >> 1, + rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), + i = isLE ? 0 : (nBytes - 1), + d = isLE ? 1 : -1, + s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; + + value = Math.abs(value); + + if (isNaN(value) || value === Infinity) { + m = isNaN(value) ? 1 : 0; + e = eMax; + } else { + e = Math.floor(Math.log(value) / Math.LN2); + if (value * (c = Math.pow(2, -e)) < 1) { + e--; + c *= 2; + } + if (e + eBias >= 1) { + value += rt / c; + } else { + value += rt * Math.pow(2, 1 - eBias); + } + if (value * c >= 2) { + e++; + c /= 2; + } + + if (e + eBias >= eMax) { + m = 0; + e = eMax; + } else if (e + eBias >= 1) { + m = (value * c - 1) * Math.pow(2, mLen); + e = e + eBias; + } else { + m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); + e = 0; + } + } + + for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); + + e = (e << mLen) | m; + eLen += mLen; + for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); + + buffer[offset + i - d] |= s * 128; +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/gulp-browserify/node_modules/browserify/node_modules/buffer/node_modules/ieee754/index.js","/../../node_modules/gulp-browserify/node_modules/browserify/node_modules/buffer/node_modules/ieee754") +},{"buffer":3,"oMfpAn":7}],6:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +function EventEmitter() { + this._events = this._events || {}; + this._maxListeners = this._maxListeners || undefined; +} +module.exports = EventEmitter; + +// Backwards-compat with node 0.10.x +EventEmitter.EventEmitter = EventEmitter; + +EventEmitter.prototype._events = undefined; +EventEmitter.prototype._maxListeners = undefined; + +// By default EventEmitters will print a warning if more than 10 listeners are +// added to it. This is a useful default which helps finding memory leaks. +EventEmitter.defaultMaxListeners = 10; + +// Obviously not all Emitters should be limited to 10. This function allows +// that to be increased. Set to zero for unlimited. +EventEmitter.prototype.setMaxListeners = function(n) { + if (!isNumber(n) || n < 0 || isNaN(n)) + throw TypeError('n must be a positive number'); + this._maxListeners = n; + return this; +}; + +EventEmitter.prototype.emit = function(type) { + var er, handler, len, args, i, listeners; + + if (!this._events) + this._events = {}; + + // If there is no 'error' event listener then throw. + if (type === 'error') { + if (!this._events.error || + (isObject(this._events.error) && !this._events.error.length)) { + er = arguments[1]; + if (er instanceof Error) { + throw er; // Unhandled 'error' event + } else { + throw TypeError('Uncaught, unspecified "error" event.'); + } + return false; + } + } + + handler = this._events[type]; + + if (isUndefined(handler)) + return false; + + if (isFunction(handler)) { + switch (arguments.length) { + // fast cases + case 1: + handler.call(this); + break; + case 2: + handler.call(this, arguments[1]); + break; + case 3: + handler.call(this, arguments[1], arguments[2]); + break; + // slower + default: + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + handler.apply(this, args); + } + } else if (isObject(handler)) { + len = arguments.length; + args = new Array(len - 1); + for (i = 1; i < len; i++) + args[i - 1] = arguments[i]; + + listeners = handler.slice(); + len = listeners.length; + for (i = 0; i < len; i++) + listeners[i].apply(this, args); + } + + return true; +}; + +EventEmitter.prototype.addListener = function(type, listener) { + var m; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events) + this._events = {}; + + // To avoid recursion in the case that type === "newListener"! Before + // adding it to the listeners, first emit "newListener". + if (this._events.newListener) + this.emit('newListener', type, + isFunction(listener.listener) ? + listener.listener : listener); + + if (!this._events[type]) + // Optimize the case of one listener. Don't need the extra array object. + this._events[type] = listener; + else if (isObject(this._events[type])) + // If we've already got an array, just append. + this._events[type].push(listener); + else + // Adding the second element, need to change to array. + this._events[type] = [this._events[type], listener]; + + // Check for listener leak + if (isObject(this._events[type]) && !this._events[type].warned) { + var m; + if (!isUndefined(this._maxListeners)) { + m = this._maxListeners; + } else { + m = EventEmitter.defaultMaxListeners; + } + + if (m && m > 0 && this._events[type].length > m) { + this._events[type].warned = true; + console.error('(node) warning: possible EventEmitter memory ' + + 'leak detected. %d listeners added. ' + + 'Use emitter.setMaxListeners() to increase limit.', + this._events[type].length); + if (typeof console.trace === 'function') { + // not supported in IE 10 + console.trace(); + } + } + } + + return this; +}; + +EventEmitter.prototype.on = EventEmitter.prototype.addListener; + +EventEmitter.prototype.once = function(type, listener) { + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + var fired = false; + + function g() { + this.removeListener(type, g); + + if (!fired) { + fired = true; + listener.apply(this, arguments); + } + } + + g.listener = listener; + this.on(type, g); + + return this; +}; + +// emits a 'removeListener' event iff the listener was removed +EventEmitter.prototype.removeListener = function(type, listener) { + var list, position, length, i; + + if (!isFunction(listener)) + throw TypeError('listener must be a function'); + + if (!this._events || !this._events[type]) + return this; + + list = this._events[type]; + length = list.length; + position = -1; + + if (list === listener || + (isFunction(list.listener) && list.listener === listener)) { + delete this._events[type]; + if (this._events.removeListener) + this.emit('removeListener', type, listener); + + } else if (isObject(list)) { + for (i = length; i-- > 0;) { + if (list[i] === listener || + (list[i].listener && list[i].listener === listener)) { + position = i; + break; + } + } + + if (position < 0) + return this; + + if (list.length === 1) { + list.length = 0; + delete this._events[type]; + } else { + list.splice(position, 1); + } + + if (this._events.removeListener) + this.emit('removeListener', type, listener); + } + + return this; +}; + +EventEmitter.prototype.removeAllListeners = function(type) { + var key, listeners; + + if (!this._events) + return this; + + // not listening for removeListener, no need to emit + if (!this._events.removeListener) { + if (arguments.length === 0) + this._events = {}; + else if (this._events[type]) + delete this._events[type]; + return this; + } + + // emit removeListener for all listeners on all events + if (arguments.length === 0) { + for (key in this._events) { + if (key === 'removeListener') continue; + this.removeAllListeners(key); + } + this.removeAllListeners('removeListener'); + this._events = {}; + return this; + } + + listeners = this._events[type]; + + if (isFunction(listeners)) { + this.removeListener(type, listeners); + } else { + // LIFO order + while (listeners.length) + this.removeListener(type, listeners[listeners.length - 1]); + } + delete this._events[type]; + + return this; +}; + +EventEmitter.prototype.listeners = function(type) { + var ret; + if (!this._events || !this._events[type]) + ret = []; + else if (isFunction(this._events[type])) + ret = [this._events[type]]; + else + ret = this._events[type].slice(); + return ret; +}; + +EventEmitter.listenerCount = function(emitter, type) { + var ret; + if (!emitter._events || !emitter._events[type]) + ret = 0; + else if (isFunction(emitter._events[type])) + ret = 1; + else + ret = emitter._events[type].length; + return ret; +}; + +function isFunction(arg) { + return typeof arg === 'function'; +} + +function isNumber(arg) { + return typeof arg === 'number'; +} + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} + +function isUndefined(arg) { + return arg === void 0; +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/gulp-browserify/node_modules/browserify/node_modules/events/events.js","/../../node_modules/gulp-browserify/node_modules/browserify/node_modules/events") +},{"buffer":3,"oMfpAn":7}],7:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// shim for using process in browser + +var process = module.exports = {}; + +process.nextTick = (function () { + var canSetImmediate = typeof window !== 'undefined' + && window.setImmediate; + var canPost = typeof window !== 'undefined' + && window.postMessage && window.addEventListener + ; + + if (canSetImmediate) { + return function (f) { return window.setImmediate(f) }; + } + + if (canPost) { + var queue = []; + window.addEventListener('message', function (ev) { + var source = ev.source; + if ((source === window || source === null) && ev.data === 'process-tick') { + ev.stopPropagation(); + if (queue.length > 0) { + var fn = queue.shift(); + fn(); + } + } + }, true); + + return function nextTick(fn) { + queue.push(fn); + window.postMessage('process-tick', '*'); + }; + } + + return function nextTick(fn) { + setTimeout(fn, 0); + }; +})(); + +process.title = 'browser'; +process.browser = true; +process.env = {}; +process.argv = []; + +function noop() {} + +process.on = noop; +process.addListener = noop; +process.once = noop; +process.off = noop; +process.removeListener = noop; +process.removeAllListeners = noop; +process.emit = noop; + +process.binding = function (name) { + throw new Error('process.binding is not supported'); +} + +// TODO(shtylman) +process.cwd = function () { return '/' }; +process.chdir = function (dir) { + throw new Error('process.chdir is not supported'); +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/gulp-browserify/node_modules/browserify/node_modules/process/browser.js","/../../node_modules/gulp-browserify/node_modules/browserify/node_modules/process") +},{"buffer":3,"oMfpAn":7}],8:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var split = require('browser-split') +var ClassList = require('class-list') +var DataSet = require('data-set') +require('html-element') + +function context () { + + var cleanupFuncs = [] + + function h() { + var args = [].slice.call(arguments), e = null + function item (l) { + var r + function parseClass (string) { + var m = split(string, /([\.#]?[a-zA-Z0-9_:-]+)/) + if(/^\.|#/.test(m[1])) + e = document.createElement('div') + forEach(m, function (v) { + var s = v.substring(1,v.length) + if(!v) return + if(!e) + e = document.createElement(v) + else if (v[0] === '.') + ClassList(e).add(s) + else if (v[0] === '#') + e.setAttribute('id', s) + }) + } + + if(l == null) + ; + else if('string' === typeof l) { + if(!e) + parseClass(l) + else + e.appendChild(r = document.createTextNode(l)) + } + else if('number' === typeof l + || 'boolean' === typeof l + || l instanceof Date + || l instanceof RegExp ) { + e.appendChild(r = document.createTextNode(l.toString())) + } + //there might be a better way to handle this... + else if (isArray(l)) + forEach(l, item) + else if(isNode(l)) + e.appendChild(r = l) + else if(l instanceof Text) + e.appendChild(r = l) + else if ('object' === typeof l) { + for (var k in l) { + if('function' === typeof l[k]) { + if(/^on\w+/.test(k)) { + if (e.addEventListener){ + e.addEventListener(k.substring(2), l[k], false) + cleanupFuncs.push(function(){ + e.removeEventListener(k.substring(2), l[k], false) + }) + }else{ + e.attachEvent(k, l[k]) + cleanupFuncs.push(function(){ + e.detachEvent(k, l[k]) + }) + } + } else { + // observable + e[k] = l[k]() + cleanupFuncs.push(l[k](function (v) { + e[k] = v + })) + } + } + else if(k === 'style') { + if('string' === typeof l[k]) { + e.style.cssText = l[k] + }else{ + for (var s in l[k]) (function(s, v) { + if('function' === typeof v) { + // observable + e.style.setProperty(s, v()) + cleanupFuncs.push(v(function (val) { + e.style.setProperty(s, val) + })) + } else + e.style.setProperty(s, l[k][s]) + })(s, l[k][s]) + } + } else if (k.substr(0, 5) === "data-") { + DataSet(e)[k.substr(5)] = l[k] + } else { + e[k] = l[k] + } + } + } else if ('function' === typeof l) { + //assume it's an observable! + var v = l() + e.appendChild(r = isNode(v) ? v : document.createTextNode(v)) + + cleanupFuncs.push(l(function (v) { + if(isNode(v) && r.parentElement) + r.parentElement.replaceChild(v, r), r = v + else + r.textContent = v + })) + } + + return r + } + while(args.length) + item(args.shift()) + + return e + } + + h.cleanup = function () { + for (var i = 0; i < cleanupFuncs.length; i++){ + cleanupFuncs[i]() + } + } + + return h +} + +var h = module.exports = context() +h.context = context + +function isNode (el) { + return el && el.nodeName && el.nodeType +} + +function isText (el) { + return el && el.nodeName === '#text' && el.nodeType == 3 +} + +function forEach (arr, fn) { + if (arr.forEach) return arr.forEach(fn) + for (var i = 0; i < arr.length; i++) fn(arr[i], i) +} + +function isArray (arr) { + return Object.prototype.toString.call(arr) == '[object Array]' +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/hyperscript/index.js","/../../node_modules/hyperscript") +},{"browser-split":9,"buffer":3,"class-list":10,"data-set":12,"html-element":2,"oMfpAn":7}],9:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*! + * Cross-Browser Split 1.1.1 + * Copyright 2007-2012 Steven Levithan + * Available under the MIT License + * ECMAScript compliant, uniform cross-browser split method + */ + +/** + * Splits a string into an array of strings using a regex or string separator. Matches of the + * separator are not included in the result array. However, if `separator` is a regex that contains + * capturing groups, backreferences are spliced into the result each time `separator` is matched. + * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably + * cross-browser. + * @param {String} str String to split. + * @param {RegExp|String} separator Regex or string to use for separating the string. + * @param {Number} [limit] Maximum number of items to include in the result array. + * @returns {Array} Array of substrings. + * @example + * + * // Basic use + * split('a b c d', ' '); + * // -> ['a', 'b', 'c', 'd'] + * + * // With limit + * split('a b c d', ' ', 2); + * // -> ['a', 'b'] + * + * // Backreferences in result array + * split('..word1 word2..', /([a-z]+)(\d+)/i); + * // -> ['..', 'word', '1', ' ', 'word', '2', '..'] + */ +module.exports = (function split(undef) { + + var nativeSplit = String.prototype.split, + compliantExecNpcg = /()??/.exec("")[1] === undef, + // NPCG: nonparticipating capturing group + self; + + self = function(str, separator, limit) { + // If `separator` is not a regex, use `nativeSplit` + if (Object.prototype.toString.call(separator) !== "[object RegExp]") { + return nativeSplit.call(str, separator, limit); + } + var output = [], + flags = (separator.ignoreCase ? "i" : "") + (separator.multiline ? "m" : "") + (separator.extended ? "x" : "") + // Proposed for ES6 + (separator.sticky ? "y" : ""), + // Firefox 3+ + lastLastIndex = 0, + // Make `global` and avoid `lastIndex` issues by working with a copy + separator = new RegExp(separator.source, flags + "g"), + separator2, match, lastIndex, lastLength; + str += ""; // Type-convert + if (!compliantExecNpcg) { + // Doesn't need flags gy, but they don't hurt + separator2 = new RegExp("^" + separator.source + "$(?!\\s)", flags); + } + /* Values for `limit`, per the spec: + * If undefined: 4294967295 // Math.pow(2, 32) - 1 + * If 0, Infinity, or NaN: 0 + * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; + * If negative number: 4294967296 - Math.floor(Math.abs(limit)) + * If other: Type-convert, then use the above rules + */ + limit = limit === undef ? -1 >>> 0 : // Math.pow(2, 32) - 1 + limit >>> 0; // ToUint32(limit) + while (match = separator.exec(str)) { + // `separator.lastIndex` is not reliable cross-browser + lastIndex = match.index + match[0].length; + if (lastIndex > lastLastIndex) { + output.push(str.slice(lastLastIndex, match.index)); + // Fix browsers whose `exec` methods don't consistently return `undefined` for + // nonparticipating capturing groups + if (!compliantExecNpcg && match.length > 1) { + match[0].replace(separator2, function() { + for (var i = 1; i < arguments.length - 2; i++) { + if (arguments[i] === undef) { + match[i] = undef; + } + } + }); + } + if (match.length > 1 && match.index < str.length) { + Array.prototype.push.apply(output, match.slice(1)); + } + lastLength = match[0].length; + lastLastIndex = lastIndex; + if (output.length >= limit) { + break; + } + } + if (separator.lastIndex === match.index) { + separator.lastIndex++; // Avoid an infinite loop + } + } + if (lastLastIndex === str.length) { + if (lastLength || !separator.test("")) { + output.push(""); + } + } else { + output.push(str.slice(lastLastIndex)); + } + return output.length > limit ? output.slice(0, limit) : output; + }; + + return self; +})(); + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/hyperscript/node_modules/browser-split/index.js","/../../node_modules/hyperscript/node_modules/browser-split") +},{"buffer":3,"oMfpAn":7}],10:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// contains, add, remove, toggle +var indexof = require('indexof') + +module.exports = ClassList + +function ClassList(elem) { + var cl = elem.classList + + if (cl) { + return cl + } + + var classList = { + add: add + , remove: remove + , contains: contains + , toggle: toggle + , toString: $toString + , length: 0 + , item: item + } + + return classList + + function add(token) { + var list = getTokens() + if (indexof(list, token) > -1) { + return + } + list.push(token) + setTokens(list) + } + + function remove(token) { + var list = getTokens() + , index = indexof(list, token) + + if (index === -1) { + return + } + + list.splice(index, 1) + setTokens(list) + } + + function contains(token) { + return indexof(getTokens(), token) > -1 + } + + function toggle(token) { + if (contains(token)) { + remove(token) + return false + } else { + add(token) + return true + } + } + + function $toString() { + return elem.className + } + + function item(index) { + var tokens = getTokens() + return tokens[index] || null + } + + function getTokens() { + var className = elem.className + + return filter(className.split(" "), isTruthy) + } + + function setTokens(list) { + var length = list.length + + elem.className = list.join(" ") + classList.length = length + + for (var i = 0; i < list.length; i++) { + classList[i] = list[i] + } + + delete list[length] + } +} + +function filter (arr, fn) { + var ret = [] + for (var i = 0; i < arr.length; i++) { + if (fn(arr[i])) ret.push(arr[i]) + } + return ret +} + +function isTruthy(value) { + return !!value +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/hyperscript/node_modules/class-list/index.js","/../../node_modules/hyperscript/node_modules/class-list") +},{"buffer":3,"indexof":11,"oMfpAn":7}],11:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ + +var indexOf = [].indexOf; + +module.exports = function(arr, obj){ + if (indexOf) return arr.indexOf(obj); + for (var i = 0; i < arr.length; ++i) { + if (arr[i] === obj) return i; + } + return -1; +}; +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/hyperscript/node_modules/class-list/node_modules/indexof/index.js","/../../node_modules/hyperscript/node_modules/class-list/node_modules/indexof") +},{"buffer":3,"oMfpAn":7}],12:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Weakmap = require("weakmap") +var Individual = require("individual") + +var datasetMap = Individual("__DATA_SET_WEAKMAP", Weakmap()) + +module.exports = DataSet + +function DataSet(elem) { + if (elem.dataset) { + return elem.dataset + } + + var hash = datasetMap.get(elem) + + if (!hash) { + hash = createHash(elem) + datasetMap.set(elem, hash) + } + + return hash +} + +function createHash(elem) { + var attributes = elem.attributes + var hash = {} + + if (attributes === null || attributes === undefined) { + return hash + } + + for (var i = 0; i < attributes.length; i++) { + var attr = attributes[i] + + if (attr.name.substr(0,5) !== "data-") { + continue + } + + hash[attr.name.substr(5)] = attr.value + } + + return hash +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/hyperscript/node_modules/data-set/index.js","/../../node_modules/hyperscript/node_modules/data-set") +},{"buffer":3,"individual":13,"oMfpAn":7,"weakmap":15}],13:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var root = require("global") + +module.exports = Individual + +function Individual(key, value) { + if (root[key]) { + return root[key] + } + + Object.defineProperty(root, key, { + value: value + , configurable: true + }) + + return value +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/hyperscript/node_modules/data-set/node_modules/individual/index.js","/../../node_modules/hyperscript/node_modules/data-set/node_modules/individual") +},{"buffer":3,"global":14,"oMfpAn":7}],14:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/*global window, global*/ +if (typeof global !== "undefined") { + module.exports = global +} else if (typeof window !== "undefined") { + module.exports = window +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/hyperscript/node_modules/data-set/node_modules/individual/node_modules/global/index.js","/../../node_modules/hyperscript/node_modules/data-set/node_modules/individual/node_modules/global") +},{"buffer":3,"oMfpAn":7}],15:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +/* (The MIT License) + * + * Copyright (c) 2012 Brandon Benvie + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and + * associated documentation files (the 'Software'), to deal in the Software without restriction, + * including without limitation the rights to use, copy, modify, merge, publish, distribute, + * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included with all copies or + * substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING + * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +// Original WeakMap implementation by Gozala @ https://gist.github.com/1269991 +// Updated and bugfixed by Raynos @ https://gist.github.com/1638059 +// Expanded by Benvie @ https://github.com/Benvie/harmony-collections + +void function(global, undefined_, undefined){ + var getProps = Object.getOwnPropertyNames, + defProp = Object.defineProperty, + toSource = Function.prototype.toString, + create = Object.create, + hasOwn = Object.prototype.hasOwnProperty, + funcName = /^\n?function\s?(\w*)?_?\(/; + + + function define(object, key, value){ + if (typeof key === 'function') { + value = key; + key = nameOf(value).replace(/_$/, ''); + } + return defProp(object, key, { configurable: true, writable: true, value: value }); + } + + function nameOf(func){ + return typeof func !== 'function' + ? '' : 'name' in func + ? func.name : toSource.call(func).match(funcName)[1]; + } + + // ############ + // ### Data ### + // ############ + + var Data = (function(){ + var dataDesc = { value: { writable: true, value: undefined } }, + datalock = 'return function(k){if(k===s)return l}', + uids = create(null), + + createUID = function(){ + var key = Math.random().toString(36).slice(2); + return key in uids ? createUID() : uids[key] = key; + }, + + globalID = createUID(), + + storage = function(obj){ + if (hasOwn.call(obj, globalID)) + return obj[globalID]; + + if (!Object.isExtensible(obj)) + throw new TypeError("Object must be extensible"); + + var store = create(null); + defProp(obj, globalID, { value: store }); + return store; + }; + + // common per-object storage area made visible by patching getOwnPropertyNames' + define(Object, function getOwnPropertyNames(obj){ + var props = getProps(obj); + if (hasOwn.call(obj, globalID)) + props.splice(props.indexOf(globalID), 1); + return props; + }); + + function Data(){ + var puid = createUID(), + secret = {}; + + this.unlock = function(obj){ + var store = storage(obj); + if (hasOwn.call(store, puid)) + return store[puid](secret); + + var data = create(null, dataDesc); + defProp(store, puid, { + value: new Function('s', 'l', datalock)(secret, data) + }); + return data; + } + } + + define(Data.prototype, function get(o){ return this.unlock(o).value }); + define(Data.prototype, function set(o, v){ this.unlock(o).value = v }); + + return Data; + }()); + + + var WM = (function(data){ + var validate = function(key){ + if (key == null || typeof key !== 'object' && typeof key !== 'function') + throw new TypeError("Invalid WeakMap key"); + } + + var wrap = function(collection, value){ + var store = data.unlock(collection); + if (store.value) + throw new TypeError("Object is already a WeakMap"); + store.value = value; + } + + var unwrap = function(collection){ + var storage = data.unlock(collection).value; + if (!storage) + throw new TypeError("WeakMap is not generic"); + return storage; + } + + var initialize = function(weakmap, iterable){ + if (iterable !== null && typeof iterable === 'object' && typeof iterable.forEach === 'function') { + iterable.forEach(function(item, i){ + if (item instanceof Array && item.length === 2) + set.call(weakmap, iterable[i][0], iterable[i][1]); + }); + } + } + + + function WeakMap(iterable){ + if (this === global || this == null || this === WeakMap.prototype) + return new WeakMap(iterable); + + wrap(this, new Data); + initialize(this, iterable); + } + + function get(key){ + validate(key); + var value = unwrap(this).get(key); + return value === undefined_ ? undefined : value; + } + + function set(key, value){ + validate(key); + // store a token for explicit undefined so that "has" works correctly + unwrap(this).set(key, value === undefined ? undefined_ : value); + } + + function has(key){ + validate(key); + return unwrap(this).get(key) !== undefined; + } + + function delete_(key){ + validate(key); + var data = unwrap(this), + had = data.get(key) !== undefined; + data.set(key, undefined); + return had; + } + + function toString(){ + unwrap(this); + return '[object WeakMap]'; + } + + try { + var src = ('return '+delete_).replace('e_', '\\u0065'), + del = new Function('unwrap', 'validate', src)(unwrap, validate); + } catch (e) { + var del = delete_; + } + + var src = (''+Object).split('Object'); + var stringifier = function toString(){ + return src[0] + nameOf(this) + src[1]; + }; + + define(stringifier, stringifier); + + var prep = { __proto__: [] } instanceof Array + ? function(f){ f.__proto__ = stringifier } + : function(f){ define(f, stringifier) }; + + prep(WeakMap); + + [toString, get, set, has, del].forEach(function(method){ + define(WeakMap.prototype, method); + prep(method); + }); + + return WeakMap; + }(new Data)); + + var defaultCreator = Object.create + ? function(){ return Object.create(null) } + : function(){ return {} }; + + function createStorage(creator){ + var weakmap = new WM; + creator || (creator = defaultCreator); + + function storage(object, value){ + if (value || arguments.length === 2) { + weakmap.set(object, value); + } else { + value = weakmap.get(object); + if (value === undefined) { + value = creator(object); + weakmap.set(object, value); + } + } + return value; + } + + return storage; + } + + + if (typeof module !== 'undefined') { + module.exports = WM; + } else if (typeof exports !== 'undefined') { + exports.WeakMap = WM; + } else if (!('WeakMap' in global)) { + global.WeakMap = WM; + } + + WM.createStorage = createStorage; + if (global.WeakMap) + global.WeakMap.createStorage = createStorage; +}((0, eval)('this')); + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/hyperscript/node_modules/data-set/node_modules/weakmap/weakmap.js","/../../node_modules/hyperscript/node_modules/data-set/node_modules/weakmap") +},{"buffer":3,"oMfpAn":7}],16:[function(require,module,exports){ +module.exports={ + "name": "rxmarbles", + "version": "1.0.0", + "author": "Andre Staltz", + "repository": { + "type": "git", + "url": "git@github.com:staltz/rxmarbles.git" + }, + "license": "BSD 3-Clause", + "main": "js/app.js", + "dependencies": { + "rx": "~2.2.28", + "virtual-dom": "0.0.19", + "virtual-hyperscript": "4.4.0", + "hyperscript": "1.4.0" + }, + "devDependencies": { + "browserify": "~2.36.0", + "coffeeify": "~0.6.0", + "gulp": "~3.8.6", + "gulp-browserify": "^0.5.0", + "gulp-coffee": "^2.1.1", + "gulp-less": "^1.3.2", + "gulp-rimraf": "^0.1.0", + "gulp-uglify": "^0.3.1", + "gulp-util": "^2.2.20", + "uglify-js": "~2.4.13", + "watchify": "~0.4.1" + }, + "scripts": { + "preinstall": "rm -rf build && rm -rf node_modules", + "postinstall": "mkdir build && mkdir build/src && ln -s ../build/src node_modules/rxmarbles && ln -s ../package.json node_modules/package.json", + "update-gh-pages": "git checkout gh-pages && git merge master && rm dist/js/app.js && gulp build && git add dist/js/app.js && git commit --amend --no-edit && git push origin gh-pages && git checkout master" + } +} + +},{}],17:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +;(function (undefined) { + + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + var root = (objectTypes[typeof window] && window) || this, + freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports, + freeModule = objectTypes[typeof module] && module && !module.nodeType && module, + moduleExports = freeModule && freeModule.exports === freeExports && freeExports, + freeGlobal = objectTypes[typeof global] && global; + + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + var Rx = { + internals: {}, + config: { + Promise: root.Promise // Detect if promise exists + }, + helpers: { } + }; + + // Defaults + var noop = Rx.helpers.noop = function () { }, + identity = Rx.helpers.identity = function (x) { return x; }, + pluck = Rx.helpers.pluck = function (property) { return function (x) { return x[property]; }; }, + just = Rx.helpers.just = function (value) { return function () { return value; }; }, + defaultNow = Rx.helpers.defaultNow = Date.now, + defaultComparer = Rx.helpers.defaultComparer = function (x, y) { return isEqual(x, y); }, + defaultSubComparer = Rx.helpers.defaultSubComparer = function (x, y) { return x > y ? 1 : (x < y ? -1 : 0); }, + defaultKeySerializer = Rx.helpers.defaultKeySerializer = function (x) { return x.toString(); }, + defaultError = Rx.helpers.defaultError = function (err) { throw err; }, + isPromise = Rx.helpers.isPromise = function (p) { return !!p && typeof p.then === 'function' && p.then !== Rx.Observable.prototype.then; }, + asArray = Rx.helpers.asArray = function () { return Array.prototype.slice.call(arguments); }, + not = Rx.helpers.not = function (a) { return !a; }; + + // Errors + var sequenceContainsNoElements = 'Sequence contains no elements.'; + var argumentOutOfRange = 'Argument out of range'; + var objectDisposed = 'Object has been disposed'; + function checkDisposed() { if (this.isDisposed) { throw new Error(objectDisposed); } } + + // Shim in iterator support + var $iterator$ = (typeof Symbol === 'object' && Symbol.iterator) || + '_es6shim_iterator_'; + // Firefox ships a partial implementation using the name @@iterator. + // https://bugzilla.mozilla.org/show_bug.cgi?id=907077#c14 + // So use that name if we detect it. + if (root.Set && typeof new root.Set()['@@iterator'] === 'function') { + $iterator$ = '@@iterator'; + } + var doneEnumerator = { done: true, value: undefined }; + + /** `Object#toString` result shortcuts */ + var argsClass = '[object Arguments]', + arrayClass = '[object Array]', + boolClass = '[object Boolean]', + dateClass = '[object Date]', + errorClass = '[object Error]', + funcClass = '[object Function]', + numberClass = '[object Number]', + objectClass = '[object Object]', + regexpClass = '[object RegExp]', + stringClass = '[object String]'; + + var toString = Object.prototype.toString, + hasOwnProperty = Object.prototype.hasOwnProperty, + supportsArgsClass = toString.call(arguments) == argsClass, // For less -1); + } + }); + } + } + stackA.pop(); + stackB.pop(); + + return result; + } + var slice = Array.prototype.slice; + function argsOrArray(args, idx) { + return args.length === 1 && Array.isArray(args[idx]) ? + args[idx] : + slice.call(args); + } + var hasProp = {}.hasOwnProperty; + + /** @private */ + var inherits = this.inherits = Rx.internals.inherits = function (child, parent) { + function __() { this.constructor = child; } + __.prototype = parent.prototype; + child.prototype = new __(); + }; + + /** @private */ + var addProperties = Rx.internals.addProperties = function (obj) { + var sources = slice.call(arguments, 1); + for (var i = 0, len = sources.length; i < len; i++) { + var source = sources[i]; + for (var prop in source) { + obj[prop] = source[prop]; + } + } + }; + + // Rx Utils + var addRef = Rx.internals.addRef = function (xs, r) { + return new AnonymousObservable(function (observer) { + return new CompositeDisposable(r.getDisposable(), xs.subscribe(observer)); + }); + }; + + // Collection polyfills + function arrayInitialize(count, factory) { + var a = new Array(count); + for (var i = 0; i < count; i++) { + a[i] = factory(); + } + return a; + } + + // Collections + var IndexedItem = function (id, value) { + this.id = id; + this.value = value; + }; + + IndexedItem.prototype.compareTo = function (other) { + var c = this.value.compareTo(other.value); + if (c === 0) { + c = this.id - other.id; + } + return c; + }; + + // Priority Queue for Scheduling + var PriorityQueue = Rx.internals.PriorityQueue = function (capacity) { + this.items = new Array(capacity); + this.length = 0; + }; + + var priorityProto = PriorityQueue.prototype; + priorityProto.isHigherPriority = function (left, right) { + return this.items[left].compareTo(this.items[right]) < 0; + }; + + priorityProto.percolate = function (index) { + if (index >= this.length || index < 0) { + return; + } + var parent = index - 1 >> 1; + if (parent < 0 || parent === index) { + return; + } + if (this.isHigherPriority(index, parent)) { + var temp = this.items[index]; + this.items[index] = this.items[parent]; + this.items[parent] = temp; + this.percolate(parent); + } + }; + + priorityProto.heapify = function (index) { + if (index === undefined) { + index = 0; + } + if (index >= this.length || index < 0) { + return; + } + var left = 2 * index + 1, + right = 2 * index + 2, + first = index; + if (left < this.length && this.isHigherPriority(left, first)) { + first = left; + } + if (right < this.length && this.isHigherPriority(right, first)) { + first = right; + } + if (first !== index) { + var temp = this.items[index]; + this.items[index] = this.items[first]; + this.items[first] = temp; + this.heapify(first); + } + }; + + priorityProto.peek = function () { return this.items[0].value; }; + + priorityProto.removeAt = function (index) { + this.items[index] = this.items[--this.length]; + delete this.items[this.length]; + this.heapify(); + }; + + priorityProto.dequeue = function () { + var result = this.peek(); + this.removeAt(0); + return result; + }; + + priorityProto.enqueue = function (item) { + var index = this.length++; + this.items[index] = new IndexedItem(PriorityQueue.count++, item); + this.percolate(index); + }; + + priorityProto.remove = function (item) { + for (var i = 0; i < this.length; i++) { + if (this.items[i].value === item) { + this.removeAt(i); + return true; + } + } + return false; + }; + PriorityQueue.count = 0; + /** + * Represents a group of disposable resources that are disposed together. + * @constructor + */ + var CompositeDisposable = Rx.CompositeDisposable = function () { + this.disposables = argsOrArray(arguments, 0); + this.isDisposed = false; + this.length = this.disposables.length; + }; + + var CompositeDisposablePrototype = CompositeDisposable.prototype; + + /** + * Adds a disposable to the CompositeDisposable or disposes the disposable if the CompositeDisposable is disposed. + * @param {Mixed} item Disposable to add. + */ + CompositeDisposablePrototype.add = function (item) { + if (this.isDisposed) { + item.dispose(); + } else { + this.disposables.push(item); + this.length++; + } + }; + + /** + * Removes and disposes the first occurrence of a disposable from the CompositeDisposable. + * @param {Mixed} item Disposable to remove. + * @returns {Boolean} true if found; false otherwise. + */ + CompositeDisposablePrototype.remove = function (item) { + var shouldDispose = false; + if (!this.isDisposed) { + var idx = this.disposables.indexOf(item); + if (idx !== -1) { + shouldDispose = true; + this.disposables.splice(idx, 1); + this.length--; + item.dispose(); + } + + } + return shouldDispose; + }; + + /** + * Disposes all disposables in the group and removes them from the group. + */ + CompositeDisposablePrototype.dispose = function () { + if (!this.isDisposed) { + this.isDisposed = true; + var currentDisposables = this.disposables.slice(0); + this.disposables = []; + this.length = 0; + + for (var i = 0, len = currentDisposables.length; i < len; i++) { + currentDisposables[i].dispose(); + } + } + }; + + /** + * Removes and disposes all disposables from the CompositeDisposable, but does not dispose the CompositeDisposable. + */ + CompositeDisposablePrototype.clear = function () { + var currentDisposables = this.disposables.slice(0); + this.disposables = []; + this.length = 0; + for (var i = 0, len = currentDisposables.length; i < len; i++) { + currentDisposables[i].dispose(); + } + }; + + /** + * Determines whether the CompositeDisposable contains a specific disposable. + * @param {Mixed} item Disposable to search for. + * @returns {Boolean} true if the disposable was found; otherwise, false. + */ + CompositeDisposablePrototype.contains = function (item) { + return this.disposables.indexOf(item) !== -1; + }; + + /** + * Converts the existing CompositeDisposable to an array of disposables + * @returns {Array} An array of disposable objects. + */ + CompositeDisposablePrototype.toArray = function () { + return this.disposables.slice(0); + }; + + /** + * Provides a set of static methods for creating Disposables. + * + * @constructor + * @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once. + */ + var Disposable = Rx.Disposable = function (action) { + this.isDisposed = false; + this.action = action || noop; + }; + + /** Performs the task of cleaning up resources. */ + Disposable.prototype.dispose = function () { + if (!this.isDisposed) { + this.action(); + this.isDisposed = true; + } + }; + + /** + * Creates a disposable object that invokes the specified action when disposed. + * @param {Function} dispose Action to run during the first call to dispose. The action is guaranteed to be run at most once. + * @return {Disposable} The disposable object that runs the given action upon disposal. + */ + var disposableCreate = Disposable.create = function (action) { return new Disposable(action); }; + + /** + * Gets the disposable that does nothing when disposed. + */ + var disposableEmpty = Disposable.empty = { dispose: noop }; + + var BooleanDisposable = (function () { + function BooleanDisposable (isSingle) { + this.isSingle = isSingle; + this.isDisposed = false; + this.current = null; + } + + var booleanDisposablePrototype = BooleanDisposable.prototype; + + /** + * Gets the underlying disposable. + * @return The underlying disposable. + */ + booleanDisposablePrototype.getDisposable = function () { + return this.current; + }; + + /** + * Sets the underlying disposable. + * @param {Disposable} value The new underlying disposable. + */ + booleanDisposablePrototype.setDisposable = function (value) { + if (this.current && this.isSingle) { + throw new Error('Disposable has already been assigned'); + } + + var shouldDispose = this.isDisposed, old; + if (!shouldDispose) { + old = this.current; + this.current = value; + } + if (old) { + old.dispose(); + } + if (shouldDispose && value) { + value.dispose(); + } + }; + + /** + * Disposes the underlying disposable as well as all future replacements. + */ + booleanDisposablePrototype.dispose = function () { + var old; + if (!this.isDisposed) { + this.isDisposed = true; + old = this.current; + this.current = null; + } + if (old) { + old.dispose(); + } + }; + + return BooleanDisposable; + }()); + + /** + * Represents a disposable resource which only allows a single assignment of its underlying disposable resource. + * If an underlying disposable resource has already been set, future attempts to set the underlying disposable resource will throw an Error. + */ + var SingleAssignmentDisposable = Rx.SingleAssignmentDisposable = (function (super_) { + inherits(SingleAssignmentDisposable, super_); + + function SingleAssignmentDisposable() { + super_.call(this, true); + } + + return SingleAssignmentDisposable; + }(BooleanDisposable)); + + /** + * Represents a disposable resource whose underlying disposable resource can be replaced by another disposable resource, causing automatic disposal of the previous underlying disposable resource. + */ + var SerialDisposable = Rx.SerialDisposable = (function (super_) { + inherits(SerialDisposable, super_); + + function SerialDisposable() { + super_.call(this, false); + } + + return SerialDisposable; + }(BooleanDisposable)); + + /** + * Represents a disposable resource that only disposes its underlying disposable resource when all dependent disposable objects have been disposed. + */ + var RefCountDisposable = Rx.RefCountDisposable = (function () { + + function InnerDisposable(disposable) { + this.disposable = disposable; + this.disposable.count++; + this.isInnerDisposed = false; + } + + InnerDisposable.prototype.dispose = function () { + if (!this.disposable.isDisposed) { + if (!this.isInnerDisposed) { + this.isInnerDisposed = true; + this.disposable.count--; + if (this.disposable.count === 0 && this.disposable.isPrimaryDisposed) { + this.disposable.isDisposed = true; + this.disposable.underlyingDisposable.dispose(); + } + } + } + }; + + /** + * Initializes a new instance of the RefCountDisposable with the specified disposable. + * @constructor + * @param {Disposable} disposable Underlying disposable. + */ + function RefCountDisposable(disposable) { + this.underlyingDisposable = disposable; + this.isDisposed = false; + this.isPrimaryDisposed = false; + this.count = 0; + } + + /** + * Disposes the underlying disposable only when all dependent disposables have been disposed + */ + RefCountDisposable.prototype.dispose = function () { + if (!this.isDisposed) { + if (!this.isPrimaryDisposed) { + this.isPrimaryDisposed = true; + if (this.count === 0) { + this.isDisposed = true; + this.underlyingDisposable.dispose(); + } + } + } + }; + + /** + * Returns a dependent disposable that when disposed decreases the refcount on the underlying disposable. + * @returns {Disposable} A dependent disposable contributing to the reference count that manages the underlying disposable's lifetime. + */ + RefCountDisposable.prototype.getDisposable = function () { + return this.isDisposed ? disposableEmpty : new InnerDisposable(this); + }; + + return RefCountDisposable; + })(); + + function ScheduledDisposable(scheduler, disposable) { + this.scheduler = scheduler; + this.disposable = disposable; + this.isDisposed = false; + } + + ScheduledDisposable.prototype.dispose = function () { + var parent = this; + this.scheduler.schedule(function () { + if (!parent.isDisposed) { + parent.isDisposed = true; + parent.disposable.dispose(); + } + }); + }; + + var ScheduledItem = Rx.internals.ScheduledItem = function (scheduler, state, action, dueTime, comparer) { + this.scheduler = scheduler; + this.state = state; + this.action = action; + this.dueTime = dueTime; + this.comparer = comparer || defaultSubComparer; + this.disposable = new SingleAssignmentDisposable(); + } + + ScheduledItem.prototype.invoke = function () { + this.disposable.setDisposable(this.invokeCore()); + }; + + ScheduledItem.prototype.compareTo = function (other) { + return this.comparer(this.dueTime, other.dueTime); + }; + + ScheduledItem.prototype.isCancelled = function () { + return this.disposable.isDisposed; + }; + + ScheduledItem.prototype.invokeCore = function () { + return this.action(this.scheduler, this.state); + }; + + /** Provides a set of static properties to access commonly used schedulers. */ + var Scheduler = Rx.Scheduler = (function () { + + /** + * @constructor + * @private + */ + function Scheduler(now, schedule, scheduleRelative, scheduleAbsolute) { + this.now = now; + this._schedule = schedule; + this._scheduleRelative = scheduleRelative; + this._scheduleAbsolute = scheduleAbsolute; + } + + function invokeRecImmediate(scheduler, pair) { + var state = pair.first, action = pair.second, group = new CompositeDisposable(), + recursiveAction = function (state1) { + action(state1, function (state2) { + var isAdded = false, isDone = false, + d = scheduler.scheduleWithState(state2, function (scheduler1, state3) { + if (isAdded) { + group.remove(d); + } else { + isDone = true; + } + recursiveAction(state3); + return disposableEmpty; + }); + if (!isDone) { + group.add(d); + isAdded = true; + } + }); + }; + recursiveAction(state); + return group; + } + + function invokeRecDate(scheduler, pair, method) { + var state = pair.first, action = pair.second, group = new CompositeDisposable(), + recursiveAction = function (state1) { + action(state1, function (state2, dueTime1) { + var isAdded = false, isDone = false, + d = scheduler[method].call(scheduler, state2, dueTime1, function (scheduler1, state3) { + if (isAdded) { + group.remove(d); + } else { + isDone = true; + } + recursiveAction(state3); + return disposableEmpty; + }); + if (!isDone) { + group.add(d); + isAdded = true; + } + }); + }; + recursiveAction(state); + return group; + } + + function invokeAction(scheduler, action) { + action(); + return disposableEmpty; + } + + var schedulerProto = Scheduler.prototype; + + /** + * Returns a scheduler that wraps the original scheduler, adding exception handling for scheduled actions. + * @param {Function} handler Handler that's run if an exception is caught. The exception will be rethrown if the handler returns false. + * @returns {Scheduler} Wrapper around the original scheduler, enforcing exception handling. + */ + schedulerProto.catchException = schedulerProto['catch'] = function (handler) { + return new CatchScheduler(this, handler); + }; + + /** + * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation. + * @param {Number} period Period for running the work periodically. + * @param {Function} action Action to be executed. + * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort). + */ + schedulerProto.schedulePeriodic = function (period, action) { + return this.schedulePeriodicWithState(null, period, function () { + action(); + }); + }; + + /** + * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be scheduled using window.setInterval for the base implementation. + * @param {Mixed} state Initial state passed to the action upon the first iteration. + * @param {Number} period Period for running the work periodically. + * @param {Function} action Action to be executed, potentially updating the state. + * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort). + */ + schedulerProto.schedulePeriodicWithState = function (state, period, action) { + var s = state, id = setInterval(function () { + s = action(s); + }, period); + return disposableCreate(function () { + clearInterval(id); + }); + }; + + /** + * Schedules an action to be executed. + * @param {Function} action Action to execute. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.schedule = function (action) { + return this._schedule(action, invokeAction); + }; + + /** + * Schedules an action to be executed. + * @param state State passed to the action to be executed. + * @param {Function} action Action to be executed. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleWithState = function (state, action) { + return this._schedule(state, action); + }; + + /** + * Schedules an action to be executed after the specified relative due time. + * @param {Function} action Action to execute. + * @param {Number} dueTime Relative time after which to execute the action. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleWithRelative = function (dueTime, action) { + return this._scheduleRelative(action, dueTime, invokeAction); + }; + + /** + * Schedules an action to be executed after dueTime. + * @param state State passed to the action to be executed. + * @param {Function} action Action to be executed. + * @param {Number} dueTime Relative time after which to execute the action. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleWithRelativeAndState = function (state, dueTime, action) { + return this._scheduleRelative(state, dueTime, action); + }; + + /** + * Schedules an action to be executed at the specified absolute due time. + * @param {Function} action Action to execute. + * @param {Number} dueTime Absolute time at which to execute the action. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleWithAbsolute = function (dueTime, action) { + return this._scheduleAbsolute(action, dueTime, invokeAction); + }; + + /** + * Schedules an action to be executed at dueTime. + * @param {Mixed} state State passed to the action to be executed. + * @param {Function} action Action to be executed. + * @param {Number}dueTime Absolute time at which to execute the action. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleWithAbsoluteAndState = function (state, dueTime, action) { + return this._scheduleAbsolute(state, dueTime, action); + }; + + /** + * Schedules an action to be executed recursively. + * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleRecursive = function (action) { + return this.scheduleRecursiveWithState(action, function (_action, self) { + _action(function () { + self(_action); + }); + }); + }; + + /** + * Schedules an action to be executed recursively. + * @param {Mixed} state State passed to the action to be executed. + * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in recursive invocation state. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleRecursiveWithState = function (state, action) { + return this.scheduleWithState({ first: state, second: action }, function (s, p) { + return invokeRecImmediate(s, p); + }); + }; + + /** + * Schedules an action to be executed recursively after a specified relative due time. + * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action at the specified relative time. + * @param {Number}dueTime Relative time after which to execute the action for the first time. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleRecursiveWithRelative = function (dueTime, action) { + return this.scheduleRecursiveWithRelativeAndState(action, dueTime, function (_action, self) { + _action(function (dt) { + self(_action, dt); + }); + }); + }; + + /** + * Schedules an action to be executed recursively after a specified relative due time. + * @param {Mixed} state State passed to the action to be executed. + * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state. + * @param {Number}dueTime Relative time after which to execute the action for the first time. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleRecursiveWithRelativeAndState = function (state, dueTime, action) { + return this._scheduleRelative({ first: state, second: action }, dueTime, function (s, p) { + return invokeRecDate(s, p, 'scheduleWithRelativeAndState'); + }); + }; + + /** + * Schedules an action to be executed recursively at a specified absolute due time. + * @param {Function} action Action to execute recursively. The parameter passed to the action is used to trigger recursive scheduling of the action at the specified absolute time. + * @param {Number}dueTime Absolute time at which to execute the action for the first time. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleRecursiveWithAbsolute = function (dueTime, action) { + return this.scheduleRecursiveWithAbsoluteAndState(action, dueTime, function (_action, self) { + _action(function (dt) { + self(_action, dt); + }); + }); + }; + + /** + * Schedules an action to be executed recursively at a specified absolute due time. + * @param {Mixed} state State passed to the action to be executed. + * @param {Function} action Action to execute recursively. The last parameter passed to the action is used to trigger recursive scheduling of the action, passing in the recursive due time and invocation state. + * @param {Number}dueTime Absolute time at which to execute the action for the first time. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + schedulerProto.scheduleRecursiveWithAbsoluteAndState = function (state, dueTime, action) { + return this._scheduleAbsolute({ first: state, second: action }, dueTime, function (s, p) { + return invokeRecDate(s, p, 'scheduleWithAbsoluteAndState'); + }); + }; + + /** Gets the current time according to the local machine's system clock. */ + Scheduler.now = defaultNow; + + /** + * Normalizes the specified TimeSpan value to a positive value. + * @param {Number} timeSpan The time span value to normalize. + * @returns {Number} The specified TimeSpan value if it is zero or positive; otherwise, 0 + */ + Scheduler.normalize = function (timeSpan) { + if (timeSpan < 0) { + timeSpan = 0; + } + return timeSpan; + }; + + return Scheduler; + }()); + + var normalizeTime = Scheduler.normalize; + + var SchedulePeriodicRecursive = Rx.internals.SchedulePeriodicRecursive = (function () { + function tick(command, recurse) { + recurse(0, this._period); + try { + this._state = this._action(this._state); + } catch (e) { + this._cancel.dispose(); + throw e; + } + } + + function SchedulePeriodicRecursive(scheduler, state, period, action) { + this._scheduler = scheduler; + this._state = state; + this._period = period; + this._action = action; + } + + SchedulePeriodicRecursive.prototype.start = function () { + var d = new SingleAssignmentDisposable(); + this._cancel = d; + d.setDisposable(this._scheduler.scheduleRecursiveWithRelativeAndState(0, this._period, tick.bind(this))); + + return d; + }; + + return SchedulePeriodicRecursive; + }()); + + /** + * Gets a scheduler that schedules work immediately on the current thread. + */ + var immediateScheduler = Scheduler.immediate = (function () { + + function scheduleNow(state, action) { return action(this, state); } + + function scheduleRelative(state, dueTime, action) { + var dt = normalizeTime(dt); + while (dt - this.now() > 0) { } + return action(this, state); + } + + function scheduleAbsolute(state, dueTime, action) { + return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action); + } + + return new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute); + }()); + + /** + * Gets a scheduler that schedules work as soon as possible on the current thread. + */ + var currentThreadScheduler = Scheduler.currentThread = (function () { + var queue; + + function runTrampoline (q) { + var item; + while (q.length > 0) { + item = q.dequeue(); + if (!item.isCancelled()) { + // Note, do not schedule blocking work! + while (item.dueTime - Scheduler.now() > 0) { + } + if (!item.isCancelled()) { + item.invoke(); + } + } + } + } + + function scheduleNow(state, action) { + return this.scheduleWithRelativeAndState(state, 0, action); + } + + function scheduleRelative(state, dueTime, action) { + var dt = this.now() + Scheduler.normalize(dueTime), + si = new ScheduledItem(this, state, action, dt), + t; + if (!queue) { + queue = new PriorityQueue(4); + queue.enqueue(si); + try { + runTrampoline(queue); + } catch (e) { + throw e; + } finally { + queue = null; + } + } else { + queue.enqueue(si); + } + return si.disposable; + } + + function scheduleAbsolute(state, dueTime, action) { + return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action); + } + + var currentScheduler = new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute); + currentScheduler.scheduleRequired = function () { return queue === null; }; + currentScheduler.ensureTrampoline = function (action) { + if (queue === null) { + return this.schedule(action); + } else { + return action(); + } + }; + + return currentScheduler; + }()); + + + var scheduleMethod, clearMethod = noop; + (function () { + + var reNative = RegExp('^' + + String(toString) + .replace(/[.*+?^${}()|[\]\\]/g, '\\$&') + .replace(/toString| for [^\]]+/g, '.*?') + '$' + ); + + var setImmediate = typeof (setImmediate = freeGlobal && moduleExports && freeGlobal.setImmediate) == 'function' && + !reNative.test(setImmediate) && setImmediate, + clearImmediate = typeof (clearImmediate = freeGlobal && moduleExports && freeGlobal.clearImmediate) == 'function' && + !reNative.test(clearImmediate) && clearImmediate; + + function postMessageSupported () { + // Ensure not in a worker + if (!root.postMessage || root.importScripts) { return false; } + var isAsync = false, + oldHandler = root.onmessage; + // Test for async + root.onmessage = function () { isAsync = true; }; + root.postMessage('','*'); + root.onmessage = oldHandler; + + return isAsync; + } + + // Use in order, nextTick, setImmediate, postMessage, MessageChannel, script readystatechanged, setTimeout + if (typeof process !== 'undefined' && {}.toString.call(process) === '[object process]') { + scheduleMethod = process.nextTick; + } else if (typeof setImmediate === 'function') { + scheduleMethod = setImmediate; + clearMethod = clearImmediate; + } else if (postMessageSupported()) { + var MSG_PREFIX = 'ms.rx.schedule' + Math.random(), + tasks = {}, + taskId = 0; + + function onGlobalPostMessage(event) { + // Only if we're a match to avoid any other global events + if (typeof event.data === 'string' && event.data.substring(0, MSG_PREFIX.length) === MSG_PREFIX) { + var handleId = event.data.substring(MSG_PREFIX.length), + action = tasks[handleId]; + action(); + delete tasks[handleId]; + } + } + + if (root.addEventListener) { + root.addEventListener('message', onGlobalPostMessage, false); + } else { + root.attachEvent('onmessage', onGlobalPostMessage, false); + } + + scheduleMethod = function (action) { + var currentId = taskId++; + tasks[currentId] = action; + root.postMessage(MSG_PREFIX + currentId, '*'); + }; + } else if (!!root.MessageChannel) { + var channel = new root.MessageChannel(), + channelTasks = {}, + channelTaskId = 0; + + channel.port1.onmessage = function (event) { + var id = event.data, + action = channelTasks[id]; + action(); + delete channelTasks[id]; + }; + + scheduleMethod = function (action) { + var id = channelTaskId++; + channelTasks[id] = action; + channel.port2.postMessage(id); + }; + } else if ('document' in root && 'onreadystatechange' in root.document.createElement('script')) { + + scheduleMethod = function (action) { + var scriptElement = root.document.createElement('script'); + scriptElement.onreadystatechange = function () { + action(); + scriptElement.onreadystatechange = null; + scriptElement.parentNode.removeChild(scriptElement); + scriptElement = null; + }; + root.document.documentElement.appendChild(scriptElement); + }; + + } else { + scheduleMethod = function (action) { return setTimeout(action, 0); }; + clearMethod = clearTimeout; + } + }()); + + /** + * Gets a scheduler that schedules work via a timed callback based upon platform. + */ + var timeoutScheduler = Scheduler.timeout = (function () { + + function scheduleNow(state, action) { + var scheduler = this, + disposable = new SingleAssignmentDisposable(); + var id = scheduleMethod(function () { + if (!disposable.isDisposed) { + disposable.setDisposable(action(scheduler, state)); + } + }); + return new CompositeDisposable(disposable, disposableCreate(function () { + clearMethod(id); + })); + } + + function scheduleRelative(state, dueTime, action) { + var scheduler = this, + dt = Scheduler.normalize(dueTime); + if (dt === 0) { + return scheduler.scheduleWithState(state, action); + } + var disposable = new SingleAssignmentDisposable(); + var id = setTimeout(function () { + if (!disposable.isDisposed) { + disposable.setDisposable(action(scheduler, state)); + } + }, dt); + return new CompositeDisposable(disposable, disposableCreate(function () { + clearTimeout(id); + })); + } + + function scheduleAbsolute(state, dueTime, action) { + return this.scheduleWithRelativeAndState(state, dueTime - this.now(), action); + } + + return new Scheduler(defaultNow, scheduleNow, scheduleRelative, scheduleAbsolute); + })(); + + /** @private */ + var CatchScheduler = (function (_super) { + + function localNow() { + return this._scheduler.now(); + } + + function scheduleNow(state, action) { + return this._scheduler.scheduleWithState(state, this._wrap(action)); + } + + function scheduleRelative(state, dueTime, action) { + return this._scheduler.scheduleWithRelativeAndState(state, dueTime, this._wrap(action)); + } + + function scheduleAbsolute(state, dueTime, action) { + return this._scheduler.scheduleWithAbsoluteAndState(state, dueTime, this._wrap(action)); + } + + inherits(CatchScheduler, _super); + + /** @private */ + function CatchScheduler(scheduler, handler) { + this._scheduler = scheduler; + this._handler = handler; + this._recursiveOriginal = null; + this._recursiveWrapper = null; + _super.call(this, localNow, scheduleNow, scheduleRelative, scheduleAbsolute); + } + + /** @private */ + CatchScheduler.prototype._clone = function (scheduler) { + return new CatchScheduler(scheduler, this._handler); + }; + + /** @private */ + CatchScheduler.prototype._wrap = function (action) { + var parent = this; + return function (self, state) { + try { + return action(parent._getRecursiveWrapper(self), state); + } catch (e) { + if (!parent._handler(e)) { throw e; } + return disposableEmpty; + } + }; + }; + + /** @private */ + CatchScheduler.prototype._getRecursiveWrapper = function (scheduler) { + if (this._recursiveOriginal !== scheduler) { + this._recursiveOriginal = scheduler; + var wrapper = this._clone(scheduler); + wrapper._recursiveOriginal = scheduler; + wrapper._recursiveWrapper = wrapper; + this._recursiveWrapper = wrapper; + } + return this._recursiveWrapper; + }; + + /** @private */ + CatchScheduler.prototype.schedulePeriodicWithState = function (state, period, action) { + var self = this, failed = false, d = new SingleAssignmentDisposable(); + + d.setDisposable(this._scheduler.schedulePeriodicWithState(state, period, function (state1) { + if (failed) { return null; } + try { + return action(state1); + } catch (e) { + failed = true; + if (!self._handler(e)) { throw e; } + d.dispose(); + return null; + } + })); + + return d; + }; + + return CatchScheduler; + }(Scheduler)); + + /** + * Represents a notification to an observer. + */ + var Notification = Rx.Notification = (function () { + function Notification(kind, hasValue) { + this.hasValue = hasValue == null ? false : hasValue; + this.kind = kind; + } + + var NotificationPrototype = Notification.prototype; + + /** + * Invokes the delegate corresponding to the notification or the observer's method corresponding to the notification and returns the produced result. + * + * @memberOf Notification + * @param {Any} observerOrOnNext Delegate to invoke for an OnNext notification or Observer to invoke the notification on.. + * @param {Function} onError Delegate to invoke for an OnError notification. + * @param {Function} onCompleted Delegate to invoke for an OnCompleted notification. + * @returns {Any} Result produced by the observation. + */ + NotificationPrototype.accept = function (observerOrOnNext, onError, onCompleted) { + if (arguments.length === 1 && typeof observerOrOnNext === 'object') { + return this._acceptObservable(observerOrOnNext); + } + return this._accept(observerOrOnNext, onError, onCompleted); + }; + + /** + * Returns an observable sequence with a single notification. + * + * @memberOf Notification + * @param {Scheduler} [scheduler] Scheduler to send out the notification calls on. + * @returns {Observable} The observable sequence that surfaces the behavior of the notification upon subscription. + */ + NotificationPrototype.toObservable = function (scheduler) { + var notification = this; + scheduler || (scheduler = immediateScheduler); + return new AnonymousObservable(function (observer) { + return scheduler.schedule(function () { + notification._acceptObservable(observer); + if (notification.kind === 'N') { + observer.onCompleted(); + } + }); + }); + }; + + return Notification; + })(); + + /** + * Creates an object that represents an OnNext notification to an observer. + * @param {Any} value The value contained in the notification. + * @returns {Notification} The OnNext notification containing the value. + */ + var notificationCreateOnNext = Notification.createOnNext = (function () { + + function _accept (onNext) { + return onNext(this.value); + } + + function _acceptObservable(observer) { + return observer.onNext(this.value); + } + + function toString () { + return 'OnNext(' + this.value + ')'; + } + + return function (value) { + var notification = new Notification('N', true); + notification.value = value; + notification._accept = _accept; + notification._acceptObservable = _acceptObservable; + notification.toString = toString; + return notification; + }; + }()); + + /** + * Creates an object that represents an OnError notification to an observer. + * @param {Any} error The exception contained in the notification. + * @returns {Notification} The OnError notification containing the exception. + */ + var notificationCreateOnError = Notification.createOnError = (function () { + + function _accept (onNext, onError) { + return onError(this.exception); + } + + function _acceptObservable(observer) { + return observer.onError(this.exception); + } + + function toString () { + return 'OnError(' + this.exception + ')'; + } + + return function (exception) { + var notification = new Notification('E'); + notification.exception = exception; + notification._accept = _accept; + notification._acceptObservable = _acceptObservable; + notification.toString = toString; + return notification; + }; + }()); + + /** + * Creates an object that represents an OnCompleted notification to an observer. + * @returns {Notification} The OnCompleted notification. + */ + var notificationCreateOnCompleted = Notification.createOnCompleted = (function () { + + function _accept (onNext, onError, onCompleted) { + return onCompleted(); + } + + function _acceptObservable(observer) { + return observer.onCompleted(); + } + + function toString () { + return 'OnCompleted()'; + } + + return function () { + var notification = new Notification('C'); + notification._accept = _accept; + notification._acceptObservable = _acceptObservable; + notification.toString = toString; + return notification; + }; + }()); + + var Enumerator = Rx.internals.Enumerator = function (next) { + this._next = next; + }; + + Enumerator.prototype.next = function () { + return this._next(); + }; + + Enumerator.prototype[$iterator$] = function () { return this; } + + var Enumerable = Rx.internals.Enumerable = function (iterator) { + this._iterator = iterator; + }; + + Enumerable.prototype[$iterator$] = function () { + return this._iterator(); + }; + + Enumerable.prototype.concat = function () { + var sources = this; + return new AnonymousObservable(function (observer) { + var e; + try { + e = sources[$iterator$](); + } catch(err) { + observer.onError(); + return; + } + + var isDisposed, + subscription = new SerialDisposable(); + var cancelable = immediateScheduler.scheduleRecursive(function (self) { + var currentItem; + if (isDisposed) { return; } + + try { + currentItem = e.next(); + } catch (ex) { + observer.onError(ex); + return; + } + + if (currentItem.done) { + observer.onCompleted(); + return; + } + + // Check if promise + var currentValue = currentItem.value; + isPromise(currentValue) && (currentValue = observableFromPromise(currentValue)); + + var d = new SingleAssignmentDisposable(); + subscription.setDisposable(d); + d.setDisposable(currentValue.subscribe( + observer.onNext.bind(observer), + observer.onError.bind(observer), + function () { self(); }) + ); + }); + + return new CompositeDisposable(subscription, cancelable, disposableCreate(function () { + isDisposed = true; + })); + }); + }; + + Enumerable.prototype.catchException = function () { + var sources = this; + return new AnonymousObservable(function (observer) { + var e; + try { + e = sources[$iterator$](); + } catch(err) { + observer.onError(); + return; + } + + var isDisposed, + lastException, + subscription = new SerialDisposable(); + var cancelable = immediateScheduler.scheduleRecursive(function (self) { + if (isDisposed) { return; } + + var currentItem; + try { + currentItem = e.next(); + } catch (ex) { + observer.onError(ex); + return; + } + + if (currentItem.done) { + if (lastException) { + observer.onError(lastException); + } else { + observer.onCompleted(); + } + return; + } + + // Check if promise + var currentValue = currentItem.value; + isPromise(currentValue) && (currentValue = observableFromPromise(currentValue)); + + var d = new SingleAssignmentDisposable(); + subscription.setDisposable(d); + d.setDisposable(currentValue.subscribe( + observer.onNext.bind(observer), + function (exn) { + lastException = exn; + self(); + }, + observer.onCompleted.bind(observer))); + }); + return new CompositeDisposable(subscription, cancelable, disposableCreate(function () { + isDisposed = true; + })); + }); + }; + + var enumerableRepeat = Enumerable.repeat = function (value, repeatCount) { + if (repeatCount == null) { repeatCount = -1; } + return new Enumerable(function () { + var left = repeatCount; + return new Enumerator(function () { + if (left === 0) { return doneEnumerator; } + if (left > 0) { left--; } + return { done: false, value: value }; + }); + }); + }; + + var enumerableFor = Enumerable.forEach = function (source, selector, thisArg) { + selector || (selector = identity); + return new Enumerable(function () { + var index = -1; + return new Enumerator( + function () { + return ++index < source.length ? + { done: false, value: selector.call(thisArg, source[index], index, source) } : + doneEnumerator; + }); + }); + }; + + /** + * Supports push-style iteration over an observable sequence. + */ + var Observer = Rx.Observer = function () { }; + + /** + * Creates a notification callback from an observer. + * + * @param observer Observer object. + * @returns The action that forwards its input notification to the underlying observer. + */ + Observer.prototype.toNotifier = function () { + var observer = this; + return function (n) { + return n.accept(observer); + }; + }; + + /** + * Hides the identity of an observer. + + * @returns An observer that hides the identity of the specified observer. + */ + Observer.prototype.asObserver = function () { + return new AnonymousObserver(this.onNext.bind(this), this.onError.bind(this), this.onCompleted.bind(this)); + }; + + /** + * Checks access to the observer for grammar violations. This includes checking for multiple OnError or OnCompleted calls, as well as reentrancy in any of the observer methods. + * If a violation is detected, an Error is thrown from the offending observer method call. + * + * @returns An observer that checks callbacks invocations against the observer grammar and, if the checks pass, forwards those to the specified observer. + */ + Observer.prototype.checked = function () { return new CheckedObserver(this); }; + + /** + * Creates an observer from the specified OnNext, along with optional OnError, and OnCompleted actions. + * + * @static + * @memberOf Observer + * @param {Function} [onNext] Observer's OnNext action implementation. + * @param {Function} [onError] Observer's OnError action implementation. + * @param {Function} [onCompleted] Observer's OnCompleted action implementation. + * @returns {Observer} The observer object implemented using the given actions. + */ + var observerCreate = Observer.create = function (onNext, onError, onCompleted) { + onNext || (onNext = noop); + onError || (onError = defaultError); + onCompleted || (onCompleted = noop); + return new AnonymousObserver(onNext, onError, onCompleted); + }; + + /** + * Creates an observer from a notification callback. + * + * @static + * @memberOf Observer + * @param {Function} handler Action that handles a notification. + * @returns The observer object that invokes the specified handler using a notification corresponding to each message it receives. + */ + Observer.fromNotifier = function (handler) { + return new AnonymousObserver(function (x) { + return handler(notificationCreateOnNext(x)); + }, function (exception) { + return handler(notificationCreateOnError(exception)); + }, function () { + return handler(notificationCreateOnCompleted()); + }); + }; + + /** + * Schedules the invocation of observer methods on the given scheduler. + * @param {Scheduler} scheduler Scheduler to schedule observer messages on. + * @returns {Observer} Observer whose messages are scheduled on the given scheduler. + */ + Observer.notifyOn = function (scheduler) { + return new ObserveOnObserver(scheduler, this); + }; + + /** + * Abstract base class for implementations of the Observer class. + * This base class enforces the grammar of observers where OnError and OnCompleted are terminal messages. + */ + var AbstractObserver = Rx.internals.AbstractObserver = (function (_super) { + inherits(AbstractObserver, _super); + + /** + * Creates a new observer in a non-stopped state. + * + * @constructor + */ + function AbstractObserver() { + this.isStopped = false; + _super.call(this); + } + + /** + * Notifies the observer of a new element in the sequence. + * + * @memberOf AbstractObserver + * @param {Any} value Next element in the sequence. + */ + AbstractObserver.prototype.onNext = function (value) { + if (!this.isStopped) { + this.next(value); + } + }; + + /** + * Notifies the observer that an exception has occurred. + * + * @memberOf AbstractObserver + * @param {Any} error The error that has occurred. + */ + AbstractObserver.prototype.onError = function (error) { + if (!this.isStopped) { + this.isStopped = true; + this.error(error); + } + }; + + /** + * Notifies the observer of the end of the sequence. + */ + AbstractObserver.prototype.onCompleted = function () { + if (!this.isStopped) { + this.isStopped = true; + this.completed(); + } + }; + + /** + * Disposes the observer, causing it to transition to the stopped state. + */ + AbstractObserver.prototype.dispose = function () { + this.isStopped = true; + }; + + AbstractObserver.prototype.fail = function (e) { + if (!this.isStopped) { + this.isStopped = true; + this.error(e); + return true; + } + + return false; + }; + + return AbstractObserver; + }(Observer)); + + /** + * Class to create an Observer instance from delegate-based implementations of the on* methods. + */ + var AnonymousObserver = Rx.AnonymousObserver = (function (_super) { + inherits(AnonymousObserver, _super); + + /** + * Creates an observer from the specified OnNext, OnError, and OnCompleted actions. + * @param {Any} onNext Observer's OnNext action implementation. + * @param {Any} onError Observer's OnError action implementation. + * @param {Any} onCompleted Observer's OnCompleted action implementation. + */ + function AnonymousObserver(onNext, onError, onCompleted) { + _super.call(this); + this._onNext = onNext; + this._onError = onError; + this._onCompleted = onCompleted; + } + + /** + * Calls the onNext action. + * @param {Any} value Next element in the sequence. + */ + AnonymousObserver.prototype.next = function (value) { + this._onNext(value); + }; + + /** + * Calls the onError action. + * @param {Any} error The error that has occurred. + */ + AnonymousObserver.prototype.error = function (exception) { + this._onError(exception); + }; + + /** + * Calls the onCompleted action. + */ + AnonymousObserver.prototype.completed = function () { + this._onCompleted(); + }; + + return AnonymousObserver; + }(AbstractObserver)); + + var CheckedObserver = (function (_super) { + inherits(CheckedObserver, _super); + + function CheckedObserver(observer) { + _super.call(this); + this._observer = observer; + this._state = 0; // 0 - idle, 1 - busy, 2 - done + } + + var CheckedObserverPrototype = CheckedObserver.prototype; + + CheckedObserverPrototype.onNext = function (value) { + this.checkAccess(); + try { + this._observer.onNext(value); + } catch (e) { + throw e; + } finally { + this._state = 0; + } + }; + + CheckedObserverPrototype.onError = function (err) { + this.checkAccess(); + try { + this._observer.onError(err); + } catch (e) { + throw e; + } finally { + this._state = 2; + } + }; + + CheckedObserverPrototype.onCompleted = function () { + this.checkAccess(); + try { + this._observer.onCompleted(); + } catch (e) { + throw e; + } finally { + this._state = 2; + } + }; + + CheckedObserverPrototype.checkAccess = function () { + if (this._state === 1) { throw new Error('Re-entrancy detected'); } + if (this._state === 2) { throw new Error('Observer completed'); } + if (this._state === 0) { this._state = 1; } + }; + + return CheckedObserver; + }(Observer)); + + var ScheduledObserver = Rx.internals.ScheduledObserver = (function (_super) { + inherits(ScheduledObserver, _super); + + function ScheduledObserver(scheduler, observer) { + _super.call(this); + this.scheduler = scheduler; + this.observer = observer; + this.isAcquired = false; + this.hasFaulted = false; + this.queue = []; + this.disposable = new SerialDisposable(); + } + + ScheduledObserver.prototype.next = function (value) { + var self = this; + this.queue.push(function () { + self.observer.onNext(value); + }); + }; + + ScheduledObserver.prototype.error = function (exception) { + var self = this; + this.queue.push(function () { + self.observer.onError(exception); + }); + }; + + ScheduledObserver.prototype.completed = function () { + var self = this; + this.queue.push(function () { + self.observer.onCompleted(); + }); + }; + + ScheduledObserver.prototype.ensureActive = function () { + var isOwner = false, parent = this; + if (!this.hasFaulted && this.queue.length > 0) { + isOwner = !this.isAcquired; + this.isAcquired = true; + } + if (isOwner) { + this.disposable.setDisposable(this.scheduler.scheduleRecursive(function (self) { + var work; + if (parent.queue.length > 0) { + work = parent.queue.shift(); + } else { + parent.isAcquired = false; + return; + } + try { + work(); + } catch (ex) { + parent.queue = []; + parent.hasFaulted = true; + throw ex; + } + self(); + })); + } + }; + + ScheduledObserver.prototype.dispose = function () { + _super.prototype.dispose.call(this); + this.disposable.dispose(); + }; + + return ScheduledObserver; + }(AbstractObserver)); + + /** @private */ + var ObserveOnObserver = (function (_super) { + inherits(ObserveOnObserver, _super); + + /** @private */ + function ObserveOnObserver() { + _super.apply(this, arguments); + } + + /** @private */ + ObserveOnObserver.prototype.next = function (value) { + _super.prototype.next.call(this, value); + this.ensureActive(); + }; + + /** @private */ + ObserveOnObserver.prototype.error = function (e) { + _super.prototype.error.call(this, e); + this.ensureActive(); + }; + + /** @private */ + ObserveOnObserver.prototype.completed = function () { + _super.prototype.completed.call(this); + this.ensureActive(); + }; + + return ObserveOnObserver; + })(ScheduledObserver); + + var observableProto; + + /** + * Represents a push-style collection. + */ + var Observable = Rx.Observable = (function () { + + function Observable(subscribe) { + this._subscribe = subscribe; + } + + observableProto = Observable.prototype; + + /** + * Subscribes an observer to the observable sequence. + * + * @example + * 1 - source.subscribe(); + * 2 - source.subscribe(observer); + * 3 - source.subscribe(function (x) { console.log(x); }); + * 4 - source.subscribe(function (x) { console.log(x); }, function (err) { console.log(err); }); + * 5 - source.subscribe(function (x) { console.log(x); }, function (err) { console.log(err); }, function () { console.log('done'); }); + * @param {Mixed} [observerOrOnNext] The object that is to receive notifications or an action to invoke for each element in the observable sequence. + * @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. + * @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. + * @returns {Diposable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler. + */ + observableProto.subscribe = observableProto.forEach = function (observerOrOnNext, onError, onCompleted) { + var subscriber = typeof observerOrOnNext === 'object' ? + observerOrOnNext : + observerCreate(observerOrOnNext, onError, onCompleted); + + return this._subscribe(subscriber); + }; + + return Observable; + })(); + + /** + * Wraps the source sequence in order to run its observer callbacks on the specified scheduler. + * + * This only invokes observer callbacks on a scheduler. In case the subscription and/or unsubscription actions have side-effects + * that require to be run on a scheduler, use subscribeOn. + * + * @param {Scheduler} scheduler Scheduler to notify observers on. + * @returns {Observable} The source sequence whose observations happen on the specified scheduler. + */ + observableProto.observeOn = function (scheduler) { + var source = this; + return new AnonymousObservable(function (observer) { + return source.subscribe(new ObserveOnObserver(scheduler, observer)); + }); + }; + + /** + * Wraps the source sequence in order to run its subscription and unsubscription logic on the specified scheduler. This operation is not commonly used; + * see the remarks section for more information on the distinction between subscribeOn and observeOn. + + * This only performs the side-effects of subscription and unsubscription on the specified scheduler. In order to invoke observer + * callbacks on a scheduler, use observeOn. + + * @param {Scheduler} scheduler Scheduler to perform subscription and unsubscription actions on. + * @returns {Observable} The source sequence whose subscriptions and unsubscriptions happen on the specified scheduler. + */ + observableProto.subscribeOn = function (scheduler) { + var source = this; + return new AnonymousObservable(function (observer) { + var m = new SingleAssignmentDisposable(), d = new SerialDisposable(); + d.setDisposable(m); + m.setDisposable(scheduler.schedule(function () { + d.setDisposable(new ScheduledDisposable(scheduler, source.subscribe(observer))); + })); + return d; + }); + }; + + /** + * Converts a Promise to an Observable sequence + * @param {Promise} An ES6 Compliant promise. + * @returns {Observable} An Observable sequence which wraps the existing promise success and failure. + */ + var observableFromPromise = Observable.fromPromise = function (promise) { + return new AnonymousObservable(function (observer) { + promise.then( + function (value) { + observer.onNext(value); + observer.onCompleted(); + }, + function (reason) { + observer.onError(reason); + }); + + return function () { + if (promise && promise.abort) { + promise.abort(); + } + } + }); + }; + /* + * Converts an existing observable sequence to an ES6 Compatible Promise + * @example + * var promise = Rx.Observable.return(42).toPromise(RSVP.Promise); + * + * // With config + * Rx.config.Promise = RSVP.Promise; + * var promise = Rx.Observable.return(42).toPromise(); + * @param {Function} [promiseCtor] The constructor of the promise. If not provided, it looks for it in Rx.config.Promise. + * @returns {Promise} An ES6 compatible promise with the last value from the observable sequence. + */ + observableProto.toPromise = function (promiseCtor) { + promiseCtor || (promiseCtor = Rx.config.Promise); + if (!promiseCtor) { + throw new Error('Promise type not provided nor in Rx.config.Promise'); + } + var source = this; + return new promiseCtor(function (resolve, reject) { + // No cancellation can be done + var value, hasValue = false; + source.subscribe(function (v) { + value = v; + hasValue = true; + }, function (err) { + reject(err); + }, function () { + if (hasValue) { + resolve(value); + } + }); + }); + }; + /** + * Creates a list from an observable sequence. + * @returns An observable sequence containing a single element with a list containing all the elements of the source sequence. + */ + observableProto.toArray = function () { + var self = this; + return new AnonymousObservable(function(observer) { + var arr = []; + return self.subscribe( + arr.push.bind(arr), + observer.onError.bind(observer), + function () { + observer.onNext(arr); + observer.onCompleted(); + }); + }); + }; + + /** + * Creates an observable sequence from a specified subscribe method implementation. + * + * @example + * var res = Rx.Observable.create(function (observer) { return function () { } ); + * var res = Rx.Observable.create(function (observer) { return Rx.Disposable.empty; } ); + * var res = Rx.Observable.create(function (observer) { } ); + * + * @param {Function} subscribe Implementation of the resulting observable sequence's subscribe method, returning a function that will be wrapped in a Disposable. + * @returns {Observable} The observable sequence with the specified implementation for the Subscribe method. + */ + Observable.create = Observable.createWithDisposable = function (subscribe) { + return new AnonymousObservable(subscribe); + }; + + /** + * Returns an observable sequence that invokes the specified factory function whenever a new observer subscribes. + * + * @example + * var res = Rx.Observable.defer(function () { return Rx.Observable.fromArray([1,2,3]); }); + * @param {Function} observableFactory Observable factory function to invoke for each observer that subscribes to the resulting sequence or Promise. + * @returns {Observable} An observable sequence whose observers trigger an invocation of the given observable factory function. + */ + var observableDefer = Observable.defer = function (observableFactory) { + return new AnonymousObservable(function (observer) { + var result; + try { + result = observableFactory(); + } catch (e) { + return observableThrow(e).subscribe(observer); + } + isPromise(result) && (result = observableFromPromise(result)); + return result.subscribe(observer); + }); + }; + + /** + * Returns an empty observable sequence, using the specified scheduler to send out the single OnCompleted message. + * + * @example + * var res = Rx.Observable.empty(); + * var res = Rx.Observable.empty(Rx.Scheduler.timeout); + * @param {Scheduler} [scheduler] Scheduler to send the termination call on. + * @returns {Observable} An observable sequence with no elements. + */ + var observableEmpty = Observable.empty = function (scheduler) { + scheduler || (scheduler = immediateScheduler); + return new AnonymousObservable(function (observer) { + return scheduler.schedule(function () { + observer.onCompleted(); + }); + }); + }; + + /** + * Converts an array to an observable sequence, using an optional scheduler to enumerate the array. + * + * @example + * var res = Rx.Observable.fromArray([1,2,3]); + * var res = Rx.Observable.fromArray([1,2,3], Rx.Scheduler.timeout); + * @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on. + * @returns {Observable} The observable sequence whose elements are pulled from the given enumerable sequence. + */ + var observableFromArray = Observable.fromArray = function (array, scheduler) { + scheduler || (scheduler = currentThreadScheduler); + return new AnonymousObservable(function (observer) { + var count = 0, len = array.length; + return scheduler.scheduleRecursive(function (self) { + if (count < len) { + observer.onNext(array[count++]); + self(); + } else { + observer.onCompleted(); + } + }); + }); + }; + + /** + * Converts an iterable into an Observable sequence + * + * @example + * var res = Rx.Observable.fromIterable(new Map()); + * var res = Rx.Observable.fromIterable(new Set(), Rx.Scheduler.timeout); + * @param {Scheduler} [scheduler] Scheduler to run the enumeration of the input sequence on. + * @returns {Observable} The observable sequence whose elements are pulled from the given generator sequence. + */ + Observable.fromIterable = function (iterable, scheduler) { + scheduler || (scheduler = currentThreadScheduler); + return new AnonymousObservable(function (observer) { + var iterator; + try { + iterator = iterable[$iterator$](); + } catch (e) { + observer.onError(e); + return; + } + + return scheduler.scheduleRecursive(function (self) { + var next; + try { + next = iterator.next(); + } catch (err) { + observer.onError(err); + return; + } + + if (next.done) { + observer.onCompleted(); + } else { + observer.onNext(next.value); + self(); + } + }); + }); + }; + + /** + * Generates an observable sequence by running a state-driven loop producing the sequence's elements, using the specified scheduler to send out observer messages. + * + * @example + * var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }); + * var res = Rx.Observable.generate(0, function (x) { return x < 10; }, function (x) { return x + 1; }, function (x) { return x; }, Rx.Scheduler.timeout); + * @param {Mixed} initialState Initial state. + * @param {Function} condition Condition to terminate generation (upon returning false). + * @param {Function} iterate Iteration step function. + * @param {Function} resultSelector Selector function for results produced in the sequence. + * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not provided, defaults to Scheduler.currentThread. + * @returns {Observable} The generated sequence. + */ + Observable.generate = function (initialState, condition, iterate, resultSelector, scheduler) { + scheduler || (scheduler = currentThreadScheduler); + return new AnonymousObservable(function (observer) { + var first = true, state = initialState; + return scheduler.scheduleRecursive(function (self) { + var hasResult, result; + try { + if (first) { + first = false; + } else { + state = iterate(state); + } + hasResult = condition(state); + if (hasResult) { + result = resultSelector(state); + } + } catch (exception) { + observer.onError(exception); + return; + } + if (hasResult) { + observer.onNext(result); + self(); + } else { + observer.onCompleted(); + } + }); + }); + }; + + /** + * This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments. + * @example + * var res = Rx.Observable.of(1,2,3); + * @returns {Observable} The observable sequence whose elements are pulled from the given arguments. + */ + Observable.of = function () { + var len = arguments.length, args = new Array(len); + for(var i = 0; i < len; i++) { args[i] = arguments[i]; } + return observableFromArray(args); + }; + + /** + * This method creates a new Observable instance with a variable number of arguments, regardless of number or type of the arguments. + * @example + * var res = Rx.Observable.of(1,2,3); + * @param {Scheduler} scheduler A scheduler to use for scheduling the arguments. + * @returns {Observable} The observable sequence whose elements are pulled from the given arguments. + */ + var observableOf = Observable.ofWithScheduler = function (scheduler) { + var len = arguments.length - 1, args = new Array(len); + for(var i = 0; i < len; i++) { args[i] = arguments[i + 1]; } + return observableFromArray(args, scheduler); + }; + + /** + * Returns a non-terminating observable sequence, which can be used to denote an infinite duration (e.g. when using reactive joins). + * @returns {Observable} An observable sequence whose observers will never get called. + */ + var observableNever = Observable.never = function () { + return new AnonymousObservable(function () { + return disposableEmpty; + }); + }; + + /** + * Generates an observable sequence of integral numbers within a specified range, using the specified scheduler to send out observer messages. + * + * @example + * var res = Rx.Observable.range(0, 10); + * var res = Rx.Observable.range(0, 10, Rx.Scheduler.timeout); + * @param {Number} start The value of the first integer in the sequence. + * @param {Number} count The number of sequential integers to generate. + * @param {Scheduler} [scheduler] Scheduler to run the generator loop on. If not specified, defaults to Scheduler.currentThread. + * @returns {Observable} An observable sequence that contains a range of sequential integral numbers. + */ + Observable.range = function (start, count, scheduler) { + scheduler || (scheduler = currentThreadScheduler); + return new AnonymousObservable(function (observer) { + return scheduler.scheduleRecursiveWithState(0, function (i, self) { + if (i < count) { + observer.onNext(start + i); + self(i + 1); + } else { + observer.onCompleted(); + } + }); + }); + }; + + /** + * Generates an observable sequence that repeats the given element the specified number of times, using the specified scheduler to send out observer messages. + * + * @example + * var res = Rx.Observable.repeat(42); + * var res = Rx.Observable.repeat(42, 4); + * 3 - res = Rx.Observable.repeat(42, 4, Rx.Scheduler.timeout); + * 4 - res = Rx.Observable.repeat(42, null, Rx.Scheduler.timeout); + * @param {Mixed} value Element to repeat. + * @param {Number} repeatCount [Optiona] Number of times to repeat the element. If not specified, repeats indefinitely. + * @param {Scheduler} scheduler Scheduler to run the producer loop on. If not specified, defaults to Scheduler.immediate. + * @returns {Observable} An observable sequence that repeats the given element the specified number of times. + */ + Observable.repeat = function (value, repeatCount, scheduler) { + scheduler || (scheduler = currentThreadScheduler); + if (repeatCount == null) { + repeatCount = -1; + } + return observableReturn(value, scheduler).repeat(repeatCount); + }; + + /** + * Returns an observable sequence that contains a single element, using the specified scheduler to send out observer messages. + * There is an alias called 'just', and 'returnValue' for browsers 0) { + s = q.shift(); + subscribe(s); + } else { + activeCount--; + if (isStopped && activeCount === 0) { + observer.onCompleted(); + } + } + })); + }; + group.add(sources.subscribe(function (innerSource) { + if (activeCount < maxConcurrentOrOther) { + activeCount++; + subscribe(innerSource); + } else { + q.push(innerSource); + } + }, observer.onError.bind(observer), function () { + isStopped = true; + if (activeCount === 0) { + observer.onCompleted(); + } + })); + return group; + }); + }; + + /** + * Merges all the observable sequences into a single observable sequence. + * The scheduler is optional and if not specified, the immediate scheduler is used. + * + * @example + * 1 - merged = Rx.Observable.merge(xs, ys, zs); + * 2 - merged = Rx.Observable.merge([xs, ys, zs]); + * 3 - merged = Rx.Observable.merge(scheduler, xs, ys, zs); + * 4 - merged = Rx.Observable.merge(scheduler, [xs, ys, zs]); + * @returns {Observable} The observable sequence that merges the elements of the observable sequences. + */ + var observableMerge = Observable.merge = function () { + var scheduler, sources; + if (!arguments[0]) { + scheduler = immediateScheduler; + sources = slice.call(arguments, 1); + } else if (arguments[0].now) { + scheduler = arguments[0]; + sources = slice.call(arguments, 1); + } else { + scheduler = immediateScheduler; + sources = slice.call(arguments, 0); + } + if (Array.isArray(sources[0])) { + sources = sources[0]; + } + return observableFromArray(sources, scheduler).mergeObservable(); + }; + + /** + * Merges an observable sequence of observable sequences into an observable sequence. + * @returns {Observable} The observable sequence that merges the elements of the inner sequences. + */ + observableProto.mergeObservable = observableProto.mergeAll =function () { + var sources = this; + return new AnonymousObservable(function (observer) { + var group = new CompositeDisposable(), + isStopped = false, + m = new SingleAssignmentDisposable(); + + group.add(m); + m.setDisposable(sources.subscribe(function (innerSource) { + var innerSubscription = new SingleAssignmentDisposable(); + group.add(innerSubscription); + + // Check if Promise or Observable + if (isPromise(innerSource)) { + innerSource = observableFromPromise(innerSource); + } + + innerSubscription.setDisposable(innerSource.subscribe(function (x) { + observer.onNext(x); + }, observer.onError.bind(observer), function () { + group.remove(innerSubscription); + if (isStopped && group.length === 1) { observer.onCompleted(); } + })); + }, observer.onError.bind(observer), function () { + isStopped = true; + if (group.length === 1) { observer.onCompleted(); } + })); + return group; + }); + }; + + /** + * Continues an observable sequence that is terminated normally or by an exception with the next observable sequence. + * @param {Observable} second Second observable sequence used to produce results after the first sequence terminates. + * @returns {Observable} An observable sequence that concatenates the first and second sequence, even if the first sequence terminates exceptionally. + */ + observableProto.onErrorResumeNext = function (second) { + if (!second) { + throw new Error('Second observable is required'); + } + return onErrorResumeNext([this, second]); + }; + + /** + * Continues an observable sequence that is terminated normally or by an exception with the next observable sequence. + * + * @example + * 1 - res = Rx.Observable.onErrorResumeNext(xs, ys, zs); + * 1 - res = Rx.Observable.onErrorResumeNext([xs, ys, zs]); + * @returns {Observable} An observable sequence that concatenates the source sequences, even if a sequence terminates exceptionally. + */ + var onErrorResumeNext = Observable.onErrorResumeNext = function () { + var sources = argsOrArray(arguments, 0); + return new AnonymousObservable(function (observer) { + var pos = 0, subscription = new SerialDisposable(), + cancelable = immediateScheduler.scheduleRecursive(function (self) { + var current, d; + if (pos < sources.length) { + current = sources[pos++]; + isPromise(current) && (current = observableFromPromise(current)); + d = new SingleAssignmentDisposable(); + subscription.setDisposable(d); + d.setDisposable(current.subscribe(observer.onNext.bind(observer), function () { + self(); + }, function () { + self(); + })); + } else { + observer.onCompleted(); + } + }); + return new CompositeDisposable(subscription, cancelable); + }); + }; + + /** + * Returns the values from the source observable sequence only after the other observable sequence produces a value. + * @param {Observable | Promise} other The observable sequence or Promise that triggers propagation of elements of the source sequence. + * @returns {Observable} An observable sequence containing the elements of the source sequence starting from the point the other sequence triggered propagation. + */ + observableProto.skipUntil = function (other) { + var source = this; + return new AnonymousObservable(function (observer) { + var isOpen = false; + var disposables = new CompositeDisposable(source.subscribe(function (left) { + isOpen && observer.onNext(left); + }, observer.onError.bind(observer), function () { + isOpen && observer.onCompleted(); + })); + + isPromise(other) && (other = observableFromPromise(other)); + + var rightSubscription = new SingleAssignmentDisposable(); + disposables.add(rightSubscription); + rightSubscription.setDisposable(other.subscribe(function () { + isOpen = true; + rightSubscription.dispose(); + }, observer.onError.bind(observer), function () { + rightSubscription.dispose(); + })); + + return disposables; + }); + }; + + /** + * Transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. + * @returns {Observable} The observable sequence that at any point in time produces the elements of the most recent inner observable sequence that has been received. + */ + observableProto['switch'] = observableProto.switchLatest = function () { + var sources = this; + return new AnonymousObservable(function (observer) { + var hasLatest = false, + innerSubscription = new SerialDisposable(), + isStopped = false, + latest = 0, + subscription = sources.subscribe(function (innerSource) { + var d = new SingleAssignmentDisposable(), id = ++latest; + hasLatest = true; + innerSubscription.setDisposable(d); + + // Check if Promise or Observable + if (isPromise(innerSource)) { + innerSource = observableFromPromise(innerSource); + } + + d.setDisposable(innerSource.subscribe(function (x) { + if (latest === id) { + observer.onNext(x); + } + }, function (e) { + if (latest === id) { + observer.onError(e); + } + }, function () { + if (latest === id) { + hasLatest = false; + if (isStopped) { + observer.onCompleted(); + } + } + })); + }, observer.onError.bind(observer), function () { + isStopped = true; + if (!hasLatest) { + observer.onCompleted(); + } + }); + return new CompositeDisposable(subscription, innerSubscription); + }); + }; + + /** + * Returns the values from the source observable sequence until the other observable sequence produces a value. + * @param {Observable | Promise} other Observable sequence or Promise that terminates propagation of elements of the source sequence. + * @returns {Observable} An observable sequence containing the elements of the source sequence up to the point the other sequence interrupted further propagation. + */ + observableProto.takeUntil = function (other) { + var source = this; + return new AnonymousObservable(function (observer) { + isPromise(other) && (other = observableFromPromise(other)); + return new CompositeDisposable( + source.subscribe(observer), + other.subscribe(observer.onCompleted.bind(observer), observer.onError.bind(observer), noop) + ); + }); + }; + + function zipArray(second, resultSelector) { + var first = this; + return new AnonymousObservable(function (observer) { + var index = 0, len = second.length; + return first.subscribe(function (left) { + if (index < len) { + var right = second[index++], result; + try { + result = resultSelector(left, right); + } catch (e) { + observer.onError(e); + return; + } + observer.onNext(result); + } else { + observer.onCompleted(); + } + }, observer.onError.bind(observer), observer.onCompleted.bind(observer)); + }); + } + + /** + * Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences or an array have produced an element at a corresponding index. + * The last element in the arguments must be a function to invoke for each series of elements at corresponding indexes in the sources. + * + * @example + * 1 - res = obs1.zip(obs2, fn); + * 1 - res = x1.zip([1,2,3], fn); + * @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function. + */ + observableProto.zip = function () { + if (Array.isArray(arguments[0])) { + return zipArray.apply(this, arguments); + } + var parent = this, sources = slice.call(arguments), resultSelector = sources.pop(); + sources.unshift(parent); + return new AnonymousObservable(function (observer) { + var n = sources.length, + queues = arrayInitialize(n, function () { return []; }), + isDone = arrayInitialize(n, function () { return false; }); + + function next(i) { + var res, queuedValues; + if (queues.every(function (x) { return x.length > 0; })) { + try { + queuedValues = queues.map(function (x) { return x.shift(); }); + res = resultSelector.apply(parent, queuedValues); + } catch (ex) { + observer.onError(ex); + return; + } + observer.onNext(res); + } else if (isDone.filter(function (x, j) { return j !== i; }).every(identity)) { + observer.onCompleted(); + } + }; + + function done(i) { + isDone[i] = true; + if (isDone.every(function (x) { return x; })) { + observer.onCompleted(); + } + } + + var subscriptions = new Array(n); + for (var idx = 0; idx < n; idx++) { + (function (i) { + var source = sources[i], sad = new SingleAssignmentDisposable(); + isPromise(source) && (source = observableFromPromise(source)); + sad.setDisposable(source.subscribe(function (x) { + queues[i].push(x); + next(i); + }, observer.onError.bind(observer), function () { + done(i); + })); + subscriptions[i] = sad; + })(idx); + } + + return new CompositeDisposable(subscriptions); + }); + }; + /** + * Merges the specified observable sequences into one observable sequence by using the selector function whenever all of the observable sequences have produced an element at a corresponding index. + * @param arguments Observable sources. + * @param {Function} resultSelector Function to invoke for each series of elements at corresponding indexes in the sources. + * @returns {Observable} An observable sequence containing the result of combining elements of the sources using the specified result selector function. + */ + Observable.zip = function () { + var args = slice.call(arguments, 0), + first = args.shift(); + return first.zip.apply(first, args); + }; + + /** + * Merges the specified observable sequences into one observable sequence by emitting a list with the elements of the observable sequences at corresponding indexes. + * @param arguments Observable sources. + * @returns {Observable} An observable sequence containing lists of elements at corresponding indexes. + */ + Observable.zipArray = function () { + var sources = argsOrArray(arguments, 0); + return new AnonymousObservable(function (observer) { + var n = sources.length, + queues = arrayInitialize(n, function () { return []; }), + isDone = arrayInitialize(n, function () { return false; }); + + function next(i) { + if (queues.every(function (x) { return x.length > 0; })) { + var res = queues.map(function (x) { return x.shift(); }); + observer.onNext(res); + } else if (isDone.filter(function (x, j) { return j !== i; }).every(identity)) { + observer.onCompleted(); + return; + } + }; + + function done(i) { + isDone[i] = true; + if (isDone.every(identity)) { + observer.onCompleted(); + return; + } + } + + var subscriptions = new Array(n); + for (var idx = 0; idx < n; idx++) { + (function (i) { + subscriptions[i] = new SingleAssignmentDisposable(); + subscriptions[i].setDisposable(sources[i].subscribe(function (x) { + queues[i].push(x); + next(i); + }, observer.onError.bind(observer), function () { + done(i); + })); + })(idx); + } + + var compositeDisposable = new CompositeDisposable(subscriptions); + compositeDisposable.add(disposableCreate(function () { + for (var qIdx = 0, qLen = queues.length; qIdx < qLen; qIdx++) { + queues[qIdx] = []; + } + })); + return compositeDisposable; + }); + }; + + /** + * Hides the identity of an observable sequence. + * @returns {Observable} An observable sequence that hides the identity of the source sequence. + */ + observableProto.asObservable = function () { + var source = this; + return new AnonymousObservable(function (observer) { + return source.subscribe(observer); + }); + }; + + /** + * Projects each element of an observable sequence into zero or more buffers which are produced based on element count information. + * + * @example + * var res = xs.bufferWithCount(10); + * var res = xs.bufferWithCount(10, 1); + * @param {Number} count Length of each buffer. + * @param {Number} [skip] Number of elements to skip between creation of consecutive buffers. If not provided, defaults to the count. + * @returns {Observable} An observable sequence of buffers. + */ + observableProto.bufferWithCount = function (count, skip) { + if (typeof skip !== 'number') { + skip = count; + } + return this.windowWithCount(count, skip).selectMany(function (x) { + return x.toArray(); + }).where(function (x) { + return x.length > 0; + }); + }; + + /** + * Dematerializes the explicit notification values of an observable sequence as implicit notifications. + * @returns {Observable} An observable sequence exhibiting the behavior corresponding to the source sequence's notification values. + */ + observableProto.dematerialize = function () { + var source = this; + return new AnonymousObservable(function (observer) { + return source.subscribe(function (x) { + return x.accept(observer); + }, observer.onError.bind(observer), observer.onCompleted.bind(observer)); + }); + }; + + /** + * Returns an observable sequence that contains only distinct contiguous elements according to the keySelector and the comparer. + * + * var obs = observable.distinctUntilChanged(); + * var obs = observable.distinctUntilChanged(function (x) { return x.id; }); + * var obs = observable.distinctUntilChanged(function (x) { return x.id; }, function (x, y) { return x === y; }); + * + * @param {Function} [keySelector] A function to compute the comparison key for each element. If not provided, it projects the value. + * @param {Function} [comparer] Equality comparer for computed key values. If not provided, defaults to an equality comparer function. + * @returns {Observable} An observable sequence only containing the distinct contiguous elements, based on a computed key value, from the source sequence. + */ + observableProto.distinctUntilChanged = function (keySelector, comparer) { + var source = this; + keySelector || (keySelector = identity); + comparer || (comparer = defaultComparer); + return new AnonymousObservable(function (observer) { + var hasCurrentKey = false, currentKey; + return source.subscribe(function (value) { + var comparerEquals = false, key; + try { + key = keySelector(value); + } catch (exception) { + observer.onError(exception); + return; + } + if (hasCurrentKey) { + try { + comparerEquals = comparer(currentKey, key); + } catch (exception) { + observer.onError(exception); + return; + } + } + if (!hasCurrentKey || !comparerEquals) { + hasCurrentKey = true; + currentKey = key; + observer.onNext(value); + } + }, observer.onError.bind(observer), observer.onCompleted.bind(observer)); + }); + }; + + /** + * Invokes an action for each element in the observable sequence and invokes an action upon graceful or exceptional termination of the observable sequence. + * This method can be used for debugging, logging, etc. of query behavior by intercepting the message stream to run arbitrary actions for messages on the pipeline. + * + * @example + * var res = observable.doAction(observer); + * var res = observable.doAction(onNext); + * var res = observable.doAction(onNext, onError); + * var res = observable.doAction(onNext, onError, onCompleted); + * @param {Mixed} observerOrOnNext Action to invoke for each element in the observable sequence or an observer. + * @param {Function} [onError] Action to invoke upon exceptional termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function. + * @param {Function} [onCompleted] Action to invoke upon graceful termination of the observable sequence. Used if only the observerOrOnNext parameter is also a function. + * @returns {Observable} The source sequence with the side-effecting behavior applied. + */ + observableProto['do'] = observableProto.doAction = function (observerOrOnNext, onError, onCompleted) { + var source = this, onNextFunc; + if (typeof observerOrOnNext === 'function') { + onNextFunc = observerOrOnNext; + } else { + onNextFunc = observerOrOnNext.onNext.bind(observerOrOnNext); + onError = observerOrOnNext.onError.bind(observerOrOnNext); + onCompleted = observerOrOnNext.onCompleted.bind(observerOrOnNext); + } + return new AnonymousObservable(function (observer) { + return source.subscribe(function (x) { + try { + onNextFunc(x); + } catch (e) { + observer.onError(e); + } + observer.onNext(x); + }, function (exception) { + if (!onError) { + observer.onError(exception); + } else { + try { + onError(exception); + } catch (e) { + observer.onError(e); + } + observer.onError(exception); + } + }, function () { + if (!onCompleted) { + observer.onCompleted(); + } else { + try { + onCompleted(); + } catch (e) { + observer.onError(e); + } + observer.onCompleted(); + } + }); + }); + }; + + /** + * Invokes a specified action after the source observable sequence terminates gracefully or exceptionally. + * + * @example + * var res = observable.finallyAction(function () { console.log('sequence ended'; }); + * @param {Function} finallyAction Action to invoke after the source observable sequence terminates. + * @returns {Observable} Source sequence with the action-invoking termination behavior applied. + */ + observableProto['finally'] = observableProto.finallyAction = function (action) { + var source = this; + return new AnonymousObservable(function (observer) { + var subscription; + try { + subscription = source.subscribe(observer); + } catch (e) { + action(); + throw e; + } + return disposableCreate(function () { + try { + subscription.dispose(); + } catch (e) { + throw e; + } finally { + action(); + } + }); + }); + }; + + /** + * Ignores all elements in an observable sequence leaving only the termination messages. + * @returns {Observable} An empty observable sequence that signals termination, successful or exceptional, of the source sequence. + */ + observableProto.ignoreElements = function () { + var source = this; + return new AnonymousObservable(function (observer) { + return source.subscribe(noop, observer.onError.bind(observer), observer.onCompleted.bind(observer)); + }); + }; + + /** + * Materializes the implicit notifications of an observable sequence as explicit notification values. + * @returns {Observable} An observable sequence containing the materialized notification values from the source sequence. + */ + observableProto.materialize = function () { + var source = this; + return new AnonymousObservable(function (observer) { + return source.subscribe(function (value) { + observer.onNext(notificationCreateOnNext(value)); + }, function (e) { + observer.onNext(notificationCreateOnError(e)); + observer.onCompleted(); + }, function () { + observer.onNext(notificationCreateOnCompleted()); + observer.onCompleted(); + }); + }); + }; + + /** + * Repeats the observable sequence a specified number of times. If the repeat count is not specified, the sequence repeats indefinitely. + * + * @example + * var res = repeated = source.repeat(); + * var res = repeated = source.repeat(42); + * @param {Number} [repeatCount] Number of times to repeat the sequence. If not provided, repeats the sequence indefinitely. + * @returns {Observable} The observable sequence producing the elements of the given sequence repeatedly. + */ + observableProto.repeat = function (repeatCount) { + return enumerableRepeat(this, repeatCount).concat(); + }; + + /** + * Repeats the source observable sequence the specified number of times or until it successfully terminates. If the retry count is not specified, it retries indefinitely. + * + * @example + * var res = retried = retry.repeat(); + * var res = retried = retry.repeat(42); + * @param {Number} [retryCount] Number of times to retry the sequence. If not provided, retry the sequence indefinitely. + * @returns {Observable} An observable sequence producing the elements of the given sequence repeatedly until it terminates successfully. + */ + observableProto.retry = function (retryCount) { + return enumerableRepeat(this, retryCount).catchException(); + }; + + /** + * Applies an accumulator function over an observable sequence and returns each intermediate result. The optional seed value is used as the initial accumulator value. + * For aggregation behavior with no intermediate results, see Observable.aggregate. + * @example + * var res = source.scan(function (acc, x) { return acc + x; }); + * var res = source.scan(0, function (acc, x) { return acc + x; }); + * @param {Mixed} [seed] The initial accumulator value. + * @param {Function} accumulator An accumulator function to be invoked on each element. + * @returns {Observable} An observable sequence containing the accumulated values. + */ + observableProto.scan = function () { + var hasSeed = false, seed, accumulator, source = this; + if (arguments.length === 2) { + hasSeed = true; + seed = arguments[0]; + accumulator = arguments[1]; + } else { + accumulator = arguments[0]; + } + return new AnonymousObservable(function (observer) { + var hasAccumulation, accumulation, hasValue; + return source.subscribe ( + function (x) { + try { + if (!hasValue) { + hasValue = true; + } + + if (hasAccumulation) { + accumulation = accumulator(accumulation, x); + } else { + accumulation = hasSeed ? accumulator(seed, x) : x; + hasAccumulation = true; + } + } catch (e) { + observer.onError(e); + return; + } + + observer.onNext(accumulation); + }, + observer.onError.bind(observer), + function () { + if (!hasValue && hasSeed) { + observer.onNext(seed); + } + observer.onCompleted(); + } + ); + }); + }; + + /** + * Bypasses a specified number of elements at the end of an observable sequence. + * @description + * This operator accumulates a queue with a length enough to store the first `count` elements. As more elements are + * received, elements are taken from the front of the queue and produced on the result sequence. This causes elements to be delayed. + * @param count Number of elements to bypass at the end of the source sequence. + * @returns {Observable} An observable sequence containing the source sequence elements except for the bypassed ones at the end. + */ + observableProto.skipLast = function (count) { + var source = this; + return new AnonymousObservable(function (observer) { + var q = []; + return source.subscribe(function (x) { + q.push(x); + if (q.length > count) { + observer.onNext(q.shift()); + } + }, observer.onError.bind(observer), observer.onCompleted.bind(observer)); + }); + }; + + /** + * Prepends a sequence of values to an observable sequence with an optional scheduler and an argument list of values to prepend. + * + * var res = source.startWith(1, 2, 3); + * var res = source.startWith(Rx.Scheduler.timeout, 1, 2, 3); + * + * @memberOf Observable# + * @returns {Observable} The source sequence prepended with the specified values. + */ + observableProto.startWith = function () { + var values, scheduler, start = 0; + if (!!arguments.length && 'now' in Object(arguments[0])) { + scheduler = arguments[0]; + start = 1; + } else { + scheduler = immediateScheduler; + } + values = slice.call(arguments, start); + return enumerableFor([observableFromArray(values, scheduler), this]).concat(); + }; + + /** + * Returns a specified number of contiguous elements from the end of an observable sequence, using an optional scheduler to drain the queue. + * + * @example + * var res = source.takeLast(5); + * var res = source.takeLast(5, Rx.Scheduler.timeout); + * + * @description + * This operator accumulates a buffer with a length enough to store elements count elements. Upon completion of + * the source sequence, this buffer is drained on the result sequence. This causes the elements to be delayed. + * @param {Number} count Number of elements to take from the end of the source sequence. + * @param {Scheduler} [scheduler] Scheduler used to drain the queue upon completion of the source sequence. + * @returns {Observable} An observable sequence containing the specified number of elements from the end of the source sequence. + */ + observableProto.takeLast = function (count, scheduler) { + return this.takeLastBuffer(count).selectMany(function (xs) { return observableFromArray(xs, scheduler); }); + }; + + /** + * Returns an array with the specified number of contiguous elements from the end of an observable sequence. + * + * @description + * This operator accumulates a buffer with a length enough to store count elements. Upon completion of the + * source sequence, this buffer is produced on the result sequence. + * @param {Number} count Number of elements to take from the end of the source sequence. + * @returns {Observable} An observable sequence containing a single array with the specified number of elements from the end of the source sequence. + */ + observableProto.takeLastBuffer = function (count) { + var source = this; + return new AnonymousObservable(function (observer) { + var q = []; + return source.subscribe(function (x) { + q.push(x); + if (q.length > count) { + q.shift(); + } + }, observer.onError.bind(observer), function () { + observer.onNext(q); + observer.onCompleted(); + }); + }); + }; + + /** + * Projects each element of an observable sequence into zero or more windows which are produced based on element count information. + * + * var res = xs.windowWithCount(10); + * var res = xs.windowWithCount(10, 1); + * @param {Number} count Length of each window. + * @param {Number} [skip] Number of elements to skip between creation of consecutive windows. If not specified, defaults to the count. + * @returns {Observable} An observable sequence of windows. + */ + observableProto.windowWithCount = function (count, skip) { + var source = this; + if (count <= 0) { + throw new Error(argumentOutOfRange); + } + if (arguments.length === 1) { + skip = count; + } + if (skip <= 0) { + throw new Error(argumentOutOfRange); + } + return new AnonymousObservable(function (observer) { + var m = new SingleAssignmentDisposable(), + refCountDisposable = new RefCountDisposable(m), + n = 0, + q = [], + createWindow = function () { + var s = new Subject(); + q.push(s); + observer.onNext(addRef(s, refCountDisposable)); + }; + createWindow(); + m.setDisposable(source.subscribe(function (x) { + var s; + for (var i = 0, len = q.length; i < len; i++) { + q[i].onNext(x); + } + var c = n - count + 1; + if (c >= 0 && c % skip === 0) { + s = q.shift(); + s.onCompleted(); + } + n++; + if (n % skip === 0) { + createWindow(); + } + }, function (exception) { + while (q.length > 0) { + q.shift().onError(exception); + } + observer.onError(exception); + }, function () { + while (q.length > 0) { + q.shift().onCompleted(); + } + observer.onCompleted(); + })); + return refCountDisposable; + }); + }; + + function concatMap(selector) { + return this.map(function (x, i) { + var result = selector(x, i); + return isPromise(result) ? observableFromPromise(result) : result; + }).concatAll(); + } + + function concatMapObserver(onNext, onError, onCompleted) { + var source = this; + return new AnonymousObservable(function (observer) { + var index = 0; + + return source.subscribe( + function (x) { + observer.onNext(onNext(x, index++)); + }, + function (err) { + observer.onNext(onError(err)); + observer.completed(); + }, + function () { + observer.onNext(onCompleted()); + observer.onCompleted(); + }); + }).concatAll(); + } + + /** + * One of the Following: + * Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence. + * + * @example + * var res = source.selectMany(function (x) { return Rx.Observable.range(0, x); }); + * Or: + * Projects each element of an observable sequence to an observable sequence, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and merges the results into one observable sequence. + * + * var res = source.selectMany(function (x) { return Rx.Observable.range(0, x); }, function (x, y) { return x + y; }); + * Or: + * Projects each element of the source observable sequence to the other observable sequence and merges the resulting observable sequences into one observable sequence. + * + * var res = source.selectMany(Rx.Observable.fromArray([1,2,3])); + * @param selector A transform function to apply to each element or an observable sequence to project each element from the + * source sequence onto which could be either an observable or Promise. + * @param {Function} [resultSelector] A transform function to apply to each element of the intermediate sequence. + * @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element. + */ + observableProto.selectConcat = observableProto.concatMap = function (selector, resultSelector) { + if (resultSelector) { + return this.concatMap(function (x, i) { + var selectorResult = selector(x, i), + result = isPromise(selectorResult) ? observableFromPromise(selectorResult) : selectorResult; + + return result.map(function (y) { + return resultSelector(x, y, i); + }); + }); + } + if (typeof selector === 'function') { + return concatMap.call(this, selector); + } + return concatMap.call(this, function () { + return selector; + }); + }; + + /** + * Returns the elements of the specified sequence or the specified value in a singleton sequence if the sequence is empty. + * + * var res = obs = xs.defaultIfEmpty(); + * 2 - obs = xs.defaultIfEmpty(false); + * + * @memberOf Observable# + * @param defaultValue The value to return if the sequence is empty. If not provided, this defaults to null. + * @returns {Observable} An observable sequence that contains the specified default value if the source is empty; otherwise, the elements of the source itself. + */ + observableProto.defaultIfEmpty = function (defaultValue) { + var source = this; + if (defaultValue === undefined) { + defaultValue = null; + } + return new AnonymousObservable(function (observer) { + var found = false; + return source.subscribe(function (x) { + found = true; + observer.onNext(x); + }, observer.onError.bind(observer), function () { + if (!found) { + observer.onNext(defaultValue); + } + observer.onCompleted(); + }); + }); + }; + + /** + * Returns an observable sequence that contains only distinct elements according to the keySelector and the comparer. + * Usage of this operator should be considered carefully due to the maintenance of an internal lookup structure which can grow large. + * + * @example + * var res = obs = xs.distinct(); + * 2 - obs = xs.distinct(function (x) { return x.id; }); + * 2 - obs = xs.distinct(function (x) { return x.id; }, function (x) { return x.toString(); }); + * @param {Function} [keySelector] A function to compute the comparison key for each element. + * @param {Function} [keySerializer] Used to serialize the given object into a string for object comparison. + * @returns {Observable} An observable sequence only containing the distinct elements, based on a computed key value, from the source sequence. + */ + observableProto.distinct = function (keySelector, keySerializer) { + var source = this; + keySelector || (keySelector = identity); + keySerializer || (keySerializer = defaultKeySerializer); + return new AnonymousObservable(function (observer) { + var hashSet = {}; + return source.subscribe(function (x) { + var key, serializedKey, otherKey, hasMatch = false; + try { + key = keySelector(x); + serializedKey = keySerializer(key); + } catch (exception) { + observer.onError(exception); + return; + } + for (otherKey in hashSet) { + if (serializedKey === otherKey) { + hasMatch = true; + break; + } + } + if (!hasMatch) { + hashSet[serializedKey] = null; + observer.onNext(x); + } + }, observer.onError.bind(observer), observer.onCompleted.bind(observer)); + }); + }; + + /** + * Groups the elements of an observable sequence according to a specified key selector function and comparer and selects the resulting elements by using a specified function. + * + * @example + * var res = observable.groupBy(function (x) { return x.id; }); + * 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }); + * 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function (x) { return x.toString(); }); + * @param {Function} keySelector A function to extract the key for each element. + * @param {Function} [elementSelector] A function to map each source element to an element in an observable group. + * @param {Function} [keySerializer] Used to serialize the given object into a string for object comparison. + * @returns {Observable} A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value. + */ + observableProto.groupBy = function (keySelector, elementSelector, keySerializer) { + return this.groupByUntil(keySelector, elementSelector, function () { + return observableNever(); + }, keySerializer); + }; + + /** + * Groups the elements of an observable sequence according to a specified key selector function. + * A duration selector function is used to control the lifetime of groups. When a group expires, it receives an OnCompleted notification. When a new element with the same + * key value as a reclaimed group occurs, the group will be reborn with a new lifetime request. + * + * @example + * var res = observable.groupByUntil(function (x) { return x.id; }, null, function () { return Rx.Observable.never(); }); + * 2 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); }); + * 3 - observable.groupBy(function (x) { return x.id; }), function (x) { return x.name; }, function () { return Rx.Observable.never(); }, function (x) { return x.toString(); }); + * @param {Function} keySelector A function to extract the key for each element. + * @param {Function} durationSelector A function to signal the expiration of a group. + * @param {Function} [keySerializer] Used to serialize the given object into a string for object comparison. + * @returns {Observable} + * A sequence of observable groups, each of which corresponds to a unique key value, containing all elements that share that same key value. + * If a group's lifetime expires, a new group with the same key value can be created once an element with such a key value is encoutered. + * + */ + observableProto.groupByUntil = function (keySelector, elementSelector, durationSelector, keySerializer) { + var source = this; + elementSelector || (elementSelector = identity); + keySerializer || (keySerializer = defaultKeySerializer); + return new AnonymousObservable(function (observer) { + var map = {}, + groupDisposable = new CompositeDisposable(), + refCountDisposable = new RefCountDisposable(groupDisposable); + groupDisposable.add(source.subscribe(function (x) { + var duration, durationGroup, element, fireNewMapEntry, group, key, serializedKey, md, writer, w; + try { + key = keySelector(x); + serializedKey = keySerializer(key); + } catch (e) { + for (w in map) { + map[w].onError(e); + } + observer.onError(e); + return; + } + fireNewMapEntry = false; + try { + writer = map[serializedKey]; + if (!writer) { + writer = new Subject(); + map[serializedKey] = writer; + fireNewMapEntry = true; + } + } catch (e) { + for (w in map) { + map[w].onError(e); + } + observer.onError(e); + return; + } + if (fireNewMapEntry) { + group = new GroupedObservable(key, writer, refCountDisposable); + durationGroup = new GroupedObservable(key, writer); + try { + duration = durationSelector(durationGroup); + } catch (e) { + for (w in map) { + map[w].onError(e); + } + observer.onError(e); + return; + } + observer.onNext(group); + md = new SingleAssignmentDisposable(); + groupDisposable.add(md); + var expire = function () { + if (serializedKey in map) { + delete map[serializedKey]; + writer.onCompleted(); + } + groupDisposable.remove(md); + }; + md.setDisposable(duration.take(1).subscribe(noop, function (exn) { + for (w in map) { + map[w].onError(exn); + } + observer.onError(exn); + }, function () { + expire(); + })); + } + try { + element = elementSelector(x); + } catch (e) { + for (w in map) { + map[w].onError(e); + } + observer.onError(e); + return; + } + writer.onNext(element); + }, function (ex) { + for (var w in map) { + map[w].onError(ex); + } + observer.onError(ex); + }, function () { + for (var w in map) { + map[w].onCompleted(); + } + observer.onCompleted(); + })); + return refCountDisposable; + }); + }; + + /** + * Projects each element of an observable sequence into a new form by incorporating the element's index. + * @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element. + * @param {Any} [thisArg] Object to use as this when executing callback. + * @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source. + */ + observableProto.select = observableProto.map = function (selector, thisArg) { + var parent = this; + return new AnonymousObservable(function (observer) { + var count = 0; + return parent.subscribe(function (value) { + var result; + try { + result = selector.call(thisArg, value, count++, parent); + } catch (exception) { + observer.onError(exception); + return; + } + observer.onNext(result); + }, observer.onError.bind(observer), observer.onCompleted.bind(observer)); + }); + }; + + /** + * Retrieves the value of a specified property from all elements in the Observable sequence. + * @param {String} property The property to pluck. + * @returns {Observable} Returns a new Observable sequence of property values. + */ + observableProto.pluck = function (property) { + return this.select(function (x) { return x[property]; }); + }; + + function selectMany(selector) { + return this.select(function (x, i) { + var result = selector(x, i); + return isPromise(result) ? observableFromPromise(result) : result; + }).mergeObservable(); + } + + function selectManyObserver(onNext, onError, onCompleted) { + var source = this; + return new AnonymousObservable(function (observer) { + var index = 0; + + return source.subscribe( + function (x) { + observer.onNext(onNext(x, index++)); + }, + function (err) { + observer.onNext(onError(err)); + observer.completed(); + }, + function () { + observer.onNext(onCompleted()); + observer.onCompleted(); + }); + }).mergeAll(); + } + + /** + * One of the Following: + * Projects each element of an observable sequence to an observable sequence and merges the resulting observable sequences into one observable sequence. + * + * @example + * var res = source.selectMany(function (x) { return Rx.Observable.range(0, x); }); + * Or: + * Projects each element of an observable sequence to an observable sequence, invokes the result selector for the source element and each of the corresponding inner sequence's elements, and merges the results into one observable sequence. + * + * var res = source.selectMany(function (x) { return Rx.Observable.range(0, x); }, function (x, y) { return x + y; }); + * Or: + * Projects each element of the source observable sequence to the other observable sequence and merges the resulting observable sequences into one observable sequence. + * + * var res = source.selectMany(Rx.Observable.fromArray([1,2,3])); + * @param selector A transform function to apply to each element or an observable sequence to project each element from the + * source sequence onto which could be either an observable or Promise. + * @param {Function} [resultSelector] A transform function to apply to each element of the intermediate sequence. + * @returns {Observable} An observable sequence whose elements are the result of invoking the one-to-many transform function collectionSelector on each element of the input sequence and then mapping each of those sequence elements and their corresponding source element to a result element. + */ + observableProto.selectMany = observableProto.flatMap = function (selector, resultSelector) { + if (resultSelector) { + return this.selectMany(function (x, i) { + var selectorResult = selector(x, i), + result = isPromise(selectorResult) ? observableFromPromise(selectorResult) : selectorResult; + + return result.select(function (y) { + return resultSelector(x, y, i); + }); + }); + } + if (typeof selector === 'function') { + return selectMany.call(this, selector); + } + return selectMany.call(this, function () { + return selector; + }); + }; + + /** + * Projects each element of an observable sequence into a new sequence of observable sequences by incorporating the element's index and then + * transforms an observable sequence of observable sequences into an observable sequence producing values only from the most recent observable sequence. + * @param {Function} selector A transform function to apply to each source element; the second parameter of the function represents the index of the source element. + * @param {Any} [thisArg] Object to use as this when executing callback. + * @returns {Observable} An observable sequence whose elements are the result of invoking the transform function on each element of source producing an Observable of Observable sequences + * and that at any point in time produces the elements of the most recent inner observable sequence that has been received. + */ + observableProto.selectSwitch = observableProto.flatMapLatest = observableProto.switchMap = function (selector, thisArg) { + return this.select(selector, thisArg).switchLatest(); + }; + + /** + * Bypasses a specified number of elements in an observable sequence and then returns the remaining elements. + * @param {Number} count The number of elements to skip before returning the remaining elements. + * @returns {Observable} An observable sequence that contains the elements that occur after the specified index in the input sequence. + */ + observableProto.skip = function (count) { + if (count < 0) { + throw new Error(argumentOutOfRange); + } + var observable = this; + return new AnonymousObservable(function (observer) { + var remaining = count; + return observable.subscribe(function (x) { + if (remaining <= 0) { + observer.onNext(x); + } else { + remaining--; + } + }, observer.onError.bind(observer), observer.onCompleted.bind(observer)); + }); + }; + + /** + * Bypasses elements in an observable sequence as long as a specified condition is true and then returns the remaining elements. + * The element's index is used in the logic of the predicate function. + * + * var res = source.skipWhile(function (value) { return value < 10; }); + * var res = source.skipWhile(function (value, index) { return value < 10 || index < 10; }); + * @param {Function} predicate A function to test each element for a condition; the second parameter of the function represents the index of the source element. + * @param {Any} [thisArg] Object to use as this when executing callback. + * @returns {Observable} An observable sequence that contains the elements from the input sequence starting at the first element in the linear series that does not pass the test specified by predicate. + */ + observableProto.skipWhile = function (predicate, thisArg) { + var source = this; + return new AnonymousObservable(function (observer) { + var i = 0, running = false; + return source.subscribe(function (x) { + if (!running) { + try { + running = !predicate.call(thisArg, x, i++, source); + } catch (e) { + observer.onError(e); + return; + } + } + if (running) { + observer.onNext(x); + } + }, observer.onError.bind(observer), observer.onCompleted.bind(observer)); + }); + }; + + /** + * Returns a specified number of contiguous elements from the start of an observable sequence, using the specified scheduler for the edge case of take(0). + * + * var res = source.take(5); + * var res = source.take(0, Rx.Scheduler.timeout); + * @param {Number} count The number of elements to return. + * @param {Scheduler} [scheduler] Scheduler used to produce an OnCompleted message in case 0; + }, + /** + * Notifies all subscribed observers about the end of the sequence. + */ + onCompleted: function () { + checkDisposed.call(this); + if (!this.isStopped) { + var os = this.observers.slice(0); + this.isStopped = true; + for (var i = 0, len = os.length; i < len; i++) { + os[i].onCompleted(); + } + + this.observers = []; + } + }, + /** + * Notifies all subscribed observers about the exception. + * @param {Mixed} error The exception to send to all observers. + */ + onError: function (error) { + checkDisposed.call(this); + if (!this.isStopped) { + var os = this.observers.slice(0); + this.isStopped = true; + this.exception = error; + + for (var i = 0, len = os.length; i < len; i++) { + os[i].onError(error); + } + + this.observers = []; + } + }, + /** + * Notifies all subscribed observers about the arrival of the specified element in the sequence. + * @param {Mixed} value The value to send to all observers. + */ + onNext: function (value) { + checkDisposed.call(this); + if (!this.isStopped) { + this.value = value; + var os = this.observers.slice(0); + for (var i = 0, len = os.length; i < len; i++) { + os[i].onNext(value); + } + } + }, + /** + * Unsubscribe all observers and release resources. + */ + dispose: function () { + this.isDisposed = true; + this.observers = null; + this.value = null; + this.exception = null; + } + }); + + return BehaviorSubject; + }(Observable)); + + /** + * Represents an object that is both an observable sequence as well as an observer. + * Each notification is broadcasted to all subscribed and future observers, subject to buffer trimming policies. + */ + var ReplaySubject = Rx.ReplaySubject = (function (_super) { + + function RemovableDisposable (subject, observer) { + this.subject = subject; + this.observer = observer; + }; + + RemovableDisposable.prototype.dispose = function () { + this.observer.dispose(); + if (!this.subject.isDisposed) { + var idx = this.subject.observers.indexOf(this.observer); + this.subject.observers.splice(idx, 1); + } + }; + + function subscribe(observer) { + var so = new ScheduledObserver(this.scheduler, observer), + subscription = new RemovableDisposable(this, so); + checkDisposed.call(this); + this._trim(this.scheduler.now()); + this.observers.push(so); + + var n = this.q.length; + + for (var i = 0, len = this.q.length; i < len; i++) { + so.onNext(this.q[i].value); + } + + if (this.hasError) { + n++; + so.onError(this.error); + } else if (this.isStopped) { + n++; + so.onCompleted(); + } + + so.ensureActive(n); + return subscription; + } + + inherits(ReplaySubject, _super); + + /** + * Initializes a new instance of the ReplaySubject class with the specified buffer size, window size and scheduler. + * @param {Number} [bufferSize] Maximum element count of the replay buffer. + * @param {Number} [windowSize] Maximum time length of the replay buffer. + * @param {Scheduler} [scheduler] Scheduler the observers are invoked on. + */ + function ReplaySubject(bufferSize, windowSize, scheduler) { + this.bufferSize = bufferSize == null ? Number.MAX_VALUE : bufferSize; + this.windowSize = windowSize == null ? Number.MAX_VALUE : windowSize; + this.scheduler = scheduler || currentThreadScheduler; + this.q = []; + this.observers = []; + this.isStopped = false; + this.isDisposed = false; + this.hasError = false; + this.error = null; + _super.call(this, subscribe); + } + + addProperties(ReplaySubject.prototype, Observer, { + /** + * Indicates whether the subject has observers subscribed to it. + * @returns {Boolean} Indicates whether the subject has observers subscribed to it. + */ + hasObservers: function () { + return this.observers.length > 0; + }, + /* @private */ + _trim: function (now) { + while (this.q.length > this.bufferSize) { + this.q.shift(); + } + while (this.q.length > 0 && (now - this.q[0].interval) > this.windowSize) { + this.q.shift(); + } + }, + /** + * Notifies all subscribed observers about the arrival of the specified element in the sequence. + * @param {Mixed} value The value to send to all observers. + */ + onNext: function (value) { + var observer; + checkDisposed.call(this); + if (!this.isStopped) { + var now = this.scheduler.now(); + this.q.push({ interval: now, value: value }); + this._trim(now); + + var o = this.observers.slice(0); + for (var i = 0, len = o.length; i < len; i++) { + observer = o[i]; + observer.onNext(value); + observer.ensureActive(); + } + } + }, + /** + * Notifies all subscribed observers about the exception. + * @param {Mixed} error The exception to send to all observers. + */ + onError: function (error) { + var observer; + checkDisposed.call(this); + if (!this.isStopped) { + this.isStopped = true; + this.error = error; + this.hasError = true; + var now = this.scheduler.now(); + this._trim(now); + var o = this.observers.slice(0); + for (var i = 0, len = o.length; i < len; i++) { + observer = o[i]; + observer.onError(error); + observer.ensureActive(); + } + this.observers = []; + } + }, + /** + * Notifies all subscribed observers about the end of the sequence. + */ + onCompleted: function () { + var observer; + checkDisposed.call(this); + if (!this.isStopped) { + this.isStopped = true; + var now = this.scheduler.now(); + this._trim(now); + var o = this.observers.slice(0); + for (var i = 0, len = o.length; i < len; i++) { + observer = o[i]; + observer.onCompleted(); + observer.ensureActive(); + } + this.observers = []; + } + }, + /** + * Unsubscribe all observers and release resources. + */ + dispose: function () { + this.isDisposed = true; + this.observers = null; + } + }); + + return ReplaySubject; + }(Observable)); + + /** @private */ + var ConnectableObservable = Rx.ConnectableObservable = (function (_super) { + inherits(ConnectableObservable, _super); + + /** + * @constructor + * @private + */ + function ConnectableObservable(source, subject) { + var state = { + subject: subject, + source: source.asObservable(), + hasSubscription: false, + subscription: null + }; + + this.connect = function () { + if (!state.hasSubscription) { + state.hasSubscription = true; + state.subscription = new CompositeDisposable(state.source.subscribe(state.subject), disposableCreate(function () { + state.hasSubscription = false; + })); + } + return state.subscription; + }; + + function subscribe(observer) { + return state.subject.subscribe(observer); + } + + _super.call(this, subscribe); + } + + /** + * @private + * @memberOf ConnectableObservable + */ + ConnectableObservable.prototype.connect = function () { return this.connect(); }; + + /** + * @private + * @memberOf ConnectableObservable + */ + ConnectableObservable.prototype.refCount = function () { + var connectableSubscription = null, count = 0, source = this; + return new AnonymousObservable(function (observer) { + var shouldConnect, subscription; + count++; + shouldConnect = count === 1; + subscription = source.subscribe(observer); + if (shouldConnect) { + connectableSubscription = source.connect(); + } + return disposableCreate(function () { + subscription.dispose(); + count--; + if (count === 0) { + connectableSubscription.dispose(); + } + }); + }); + }; + + return ConnectableObservable; + }(Observable)); + + // Real Dictionary + var primes = [1, 3, 7, 13, 31, 61, 127, 251, 509, 1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139, 524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393, 67108859, 134217689, 268435399, 536870909, 1073741789, 2147483647]; + var noSuchkey = "no such key"; + var duplicatekey = "duplicate key"; + + function isPrime(candidate) { + if (candidate & 1 === 0) { + return candidate === 2; + } + var num1 = Math.sqrt(candidate), + num2 = 3; + while (num2 <= num1) { + if (candidate % num2 === 0) { + return false; + } + num2 += 2; + } + return true; + } + + function getPrime(min) { + var index, num, candidate; + for (index = 0; index < primes.length; ++index) { + num = primes[index]; + if (num >= min) { + return num; + } + } + candidate = min | 1; + while (candidate < primes[primes.length - 1]) { + if (isPrime(candidate)) { + return candidate; + } + candidate += 2; + } + return min; + } + + function stringHashFn(str) { + var hash = 757602046; + if (!str.length) { + return hash; + } + for (var i = 0, len = str.length; i < len; i++) { + var character = str.charCodeAt(i); + hash = ((hash<<5)-hash)+character; + hash = hash & hash; + } + return hash; + } + + function numberHashFn(key) { + var c2 = 0x27d4eb2d; + key = (key ^ 61) ^ (key >>> 16); + key = key + (key << 3); + key = key ^ (key >>> 4); + key = key * c2; + key = key ^ (key >>> 15); + return key; + } + + var getHashCode = (function () { + var uniqueIdCounter = 0; + + return function (obj) { + if (obj == null) { + throw new Error(noSuchkey); + } + + // Check for built-ins before tacking on our own for any object + if (typeof obj === 'string') { + return stringHashFn(obj); + } + + if (typeof obj === 'number') { + return numberHashFn(obj); + } + + if (typeof obj === 'boolean') { + return obj === true ? 1 : 0; + } + + if (obj instanceof Date) { + return obj.getTime(); + } + + if (obj.getHashCode) { + return obj.getHashCode(); + } + + var id = 17 * uniqueIdCounter++; + obj.getHashCode = function () { return id; }; + return id; + }; + } ()); + + function newEntry() { + return { key: null, value: null, next: 0, hashCode: 0 }; + } + + // Dictionary implementation + + var Dictionary = function (capacity, comparer) { + if (capacity < 0) { + throw new Error('out of range') + } + if (capacity > 0) { + this._initialize(capacity); + } + + this.comparer = comparer || defaultComparer; + this.freeCount = 0; + this.size = 0; + this.freeList = -1; + }; + + Dictionary.prototype._initialize = function (capacity) { + var prime = getPrime(capacity), i; + this.buckets = new Array(prime); + this.entries = new Array(prime); + for (i = 0; i < prime; i++) { + this.buckets[i] = -1; + this.entries[i] = newEntry(); + } + this.freeList = -1; + }; + Dictionary.prototype.count = function () { + return this.size; + }; + Dictionary.prototype.add = function (key, value) { + return this._insert(key, value, true); + }; + Dictionary.prototype._insert = function (key, value, add) { + if (!this.buckets) { + this._initialize(0); + } + var index3; + var num = getHashCode(key) & 2147483647; + var index1 = num % this.buckets.length; + for (var index2 = this.buckets[index1]; index2 >= 0; index2 = this.entries[index2].next) { + if (this.entries[index2].hashCode === num && this.comparer(this.entries[index2].key, key)) { + if (add) { + throw new Error(duplicatekey); + } + this.entries[index2].value = value; + return; + } + } + if (this.freeCount > 0) { + index3 = this.freeList; + this.freeList = this.entries[index3].next; + --this.freeCount; + } else { + if (this.size === this.entries.length) { + this._resize(); + index1 = num % this.buckets.length; + } + index3 = this.size; + ++this.size; + } + this.entries[index3].hashCode = num; + this.entries[index3].next = this.buckets[index1]; + this.entries[index3].key = key; + this.entries[index3].value = value; + this.buckets[index1] = index3; + }; + + Dictionary.prototype._resize = function () { + var prime = getPrime(this.size * 2), + numArray = new Array(prime); + for (index = 0; index < numArray.length; ++index) { + numArray[index] = -1; + } + var entryArray = new Array(prime); + for (index = 0; index < this.size; ++index) { + entryArray[index] = this.entries[index]; + } + for (var index = this.size; index < prime; ++index) { + entryArray[index] = newEntry(); + } + for (var index1 = 0; index1 < this.size; ++index1) { + var index2 = entryArray[index1].hashCode % prime; + entryArray[index1].next = numArray[index2]; + numArray[index2] = index1; + } + this.buckets = numArray; + this.entries = entryArray; + }; + + Dictionary.prototype.remove = function (key) { + if (this.buckets) { + var num = getHashCode(key) & 2147483647; + var index1 = num % this.buckets.length; + var index2 = -1; + for (var index3 = this.buckets[index1]; index3 >= 0; index3 = this.entries[index3].next) { + if (this.entries[index3].hashCode === num && this.comparer(this.entries[index3].key, key)) { + if (index2 < 0) { + this.buckets[index1] = this.entries[index3].next; + } else { + this.entries[index2].next = this.entries[index3].next; + } + this.entries[index3].hashCode = -1; + this.entries[index3].next = this.freeList; + this.entries[index3].key = null; + this.entries[index3].value = null; + this.freeList = index3; + ++this.freeCount; + return true; + } else { + index2 = index3; + } + } + } + return false; + }; + + Dictionary.prototype.clear = function () { + var index, len; + if (this.size <= 0) { + return; + } + for (index = 0, len = this.buckets.length; index < len; ++index) { + this.buckets[index] = -1; + } + for (index = 0; index < this.size; ++index) { + this.entries[index] = newEntry(); + } + this.freeList = -1; + this.size = 0; + }; + + Dictionary.prototype._findEntry = function (key) { + if (this.buckets) { + var num = getHashCode(key) & 2147483647; + for (var index = this.buckets[num % this.buckets.length]; index >= 0; index = this.entries[index].next) { + if (this.entries[index].hashCode === num && this.comparer(this.entries[index].key, key)) { + return index; + } + } + } + return -1; + }; + + Dictionary.prototype.count = function () { + return this.size - this.freeCount; + }; + + Dictionary.prototype.tryGetValue = function (key) { + var entry = this._findEntry(key); + if (entry >= 0) { + return this.entries[entry].value; + } + return undefined; + }; + + Dictionary.prototype.getValues = function () { + var index = 0, results = []; + if (this.entries) { + for (var index1 = 0; index1 < this.size; index1++) { + if (this.entries[index1].hashCode >= 0) { + results[index++] = this.entries[index1].value; + } + } + } + return results; + }; + + Dictionary.prototype.get = function (key) { + var entry = this._findEntry(key); + if (entry >= 0) { + return this.entries[entry].value; + } + throw new Error(noSuchkey); + }; + + Dictionary.prototype.set = function (key, value) { + this._insert(key, value, false); + }; + + Dictionary.prototype.containskey = function (key) { + return this._findEntry(key) >= 0; + }; + + /** + * Correlates the elements of two sequences based on overlapping durations. + * + * @param {Observable} right The right observable sequence to join elements for. + * @param {Function} leftDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap. + * @param {Function} rightDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap. + * @param {Function} resultSelector A function invoked to compute a result element for any two overlapping elements of the left and right observable sequences. The parameters passed to the function correspond with the elements from the left and right source sequences for which overlap occurs. + * @returns {Observable} An observable sequence that contains result elements computed from source elements that have an overlapping duration. + */ + observableProto.join = function (right, leftDurationSelector, rightDurationSelector, resultSelector) { + var left = this; + return new AnonymousObservable(function (observer) { + var group = new CompositeDisposable(), + leftDone = false, + leftId = 0, + leftMap = new Dictionary(), + rightDone = false, + rightId = 0, + rightMap = new Dictionary(); + group.add(left.subscribe(function (value) { + var duration, + expire, + id = leftId++, + md = new SingleAssignmentDisposable(), + result, + values; + leftMap.add(id, value); + group.add(md); + expire = function () { + if (leftMap.remove(id) && leftMap.count() === 0 && leftDone) { + observer.onCompleted(); + } + return group.remove(md); + }; + try { + duration = leftDurationSelector(value); + } catch (e) { + observer.onError(e); + return; + } + md.setDisposable(duration.take(1).subscribe(noop, observer.onError.bind(observer), function () { expire(); })); + values = rightMap.getValues(); + for (var i = 0; i < values.length; i++) { + try { + result = resultSelector(value, values[i]); + } catch (exception) { + observer.onError(exception); + return; + } + observer.onNext(result); + } + }, observer.onError.bind(observer), function () { + leftDone = true; + if (rightDone || leftMap.count() === 0) { + observer.onCompleted(); + } + })); + group.add(right.subscribe(function (value) { + var duration, + expire, + id = rightId++, + md = new SingleAssignmentDisposable(), + result, + values; + rightMap.add(id, value); + group.add(md); + expire = function () { + if (rightMap.remove(id) && rightMap.count() === 0 && rightDone) { + observer.onCompleted(); + } + return group.remove(md); + }; + try { + duration = rightDurationSelector(value); + } catch (exception) { + observer.onError(exception); + return; + } + md.setDisposable(duration.take(1).subscribe(noop, observer.onError.bind(observer), function () { expire(); })); + values = leftMap.getValues(); + for (var i = 0; i < values.length; i++) { + try { + result = resultSelector(values[i], value); + } catch (exception) { + observer.onError(exception); + return; + } + observer.onNext(result); + } + }, observer.onError.bind(observer), function () { + rightDone = true; + if (leftDone || rightMap.count() === 0) { + observer.onCompleted(); + } + })); + return group; + }); + }; + + /** + * Correlates the elements of two sequences based on overlapping durations, and groups the results. + * + * @param {Observable} right The right observable sequence to join elements for. + * @param {Function} leftDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the left observable sequence, used to determine overlap. + * @param {Function} rightDurationSelector A function to select the duration (expressed as an observable sequence) of each element of the right observable sequence, used to determine overlap. + * @param {Function} resultSelector A function invoked to compute a result element for any element of the left sequence with overlapping elements from the right observable sequence. The first parameter passed to the function is an element of the left sequence. The second parameter passed to the function is an observable sequence with elements from the right sequence that overlap with the left sequence's element. + * @returns {Observable} An observable sequence that contains result elements computed from source elements that have an overlapping duration. + */ + observableProto.groupJoin = function (right, leftDurationSelector, rightDurationSelector, resultSelector) { + var left = this; + return new AnonymousObservable(function (observer) { + var nothing = function () {}; + var group = new CompositeDisposable(); + var r = new RefCountDisposable(group); + var leftMap = new Dictionary(); + var rightMap = new Dictionary(); + var leftID = 0; + var rightID = 0; + + group.add(left.subscribe( + function (value) { + var s = new Subject(); + var id = leftID++; + leftMap.add(id, s); + var i, len, leftValues, rightValues; + + var result; + try { + result = resultSelector(value, addRef(s, r)); + } catch (e) { + leftValues = leftMap.getValues(); + for (i = 0, len = leftValues.length; i < len; i++) { + leftValues[i].onError(e); + } + observer.onError(e); + return; + } + observer.onNext(result); + + rightValues = rightMap.getValues(); + for (i = 0, len = rightValues.length; i < len; i++) { + s.onNext(rightValues[i]); + } + + var md = new SingleAssignmentDisposable(); + group.add(md); + + var expire = function () { + if (leftMap.remove(id)) { + s.onCompleted(); + } + + group.remove(md); + }; + + var duration; + try { + duration = leftDurationSelector(value); + } catch (e) { + leftValues = leftMap.getValues(); + for (i = 0, len = leftMap.length; i < len; i++) { + leftValues[i].onError(e); + } + observer.onError(e); + return; + } + + md.setDisposable(duration.take(1).subscribe( + nothing, + function (e) { + leftValues = leftMap.getValues(); + for (i = 0, len = leftValues.length; i < len; i++) { + leftValues[i].onError(e); + } + observer.onError(e); + }, + expire) + ); + }, + function (e) { + var leftValues = leftMap.getValues(); + for (var i = 0, len = leftValues.length; i < len; i++) { + leftValues[i].onError(e); + } + observer.onError(e); + }, + observer.onCompleted.bind(observer))); + + group.add(right.subscribe( + function (value) { + var leftValues, i, len; + var id = rightID++; + rightMap.add(id, value); + + var md = new SingleAssignmentDisposable(); + group.add(md); + + var expire = function () { + rightMap.remove(id); + group.remove(md); + }; + + var duration; + try { + duration = rightDurationSelector(value); + } catch (e) { + leftValues = leftMap.getValues(); + for (i = 0, len = leftMap.length; i < len; i++) { + leftValues[i].onError(e); + } + observer.onError(e); + return; + } + md.setDisposable(duration.take(1).subscribe( + nothing, + function (e) { + leftValues = leftMap.getValues(); + for (i = 0, len = leftMap.length; i < len; i++) { + leftValues[i].onError(e); + } + observer.onError(e); + }, + expire) + ); + + leftValues = leftMap.getValues(); + for (i = 0, len = leftValues.length; i < len; i++) { + leftValues[i].onNext(value); + } + }, + function (e) { + var leftValues = leftMap.getValues(); + for (var i = 0, len = leftValues.length; i < len; i++) { + leftValues[i].onError(e); + } + observer.onError(e); + })); + + return r; + }); + }; + + /** + * Projects each element of an observable sequence into zero or more buffers. + * + * @param {Mixed} bufferOpeningsOrClosingSelector Observable sequence whose elements denote the creation of new windows, or, a function invoked to define the boundaries of the produced windows (a new window is started when the previous one is closed, resulting in non-overlapping windows). + * @param {Function} [bufferClosingSelector] A function invoked to define the closing of each produced window. If a closing selector function is specified for the first parameter, this parameter is ignored. + * @returns {Observable} An observable sequence of windows. + */ + observableProto.buffer = function (bufferOpeningsOrClosingSelector, bufferClosingSelector) { + return this.window.apply(this, arguments).selectMany(function (x) { return x.toArray(); }); + }; + + /** + * Projects each element of an observable sequence into zero or more windows. + * + * @param {Mixed} windowOpeningsOrClosingSelector Observable sequence whose elements denote the creation of new windows, or, a function invoked to define the boundaries of the produced windows (a new window is started when the previous one is closed, resulting in non-overlapping windows). + * @param {Function} [windowClosingSelector] A function invoked to define the closing of each produced window. If a closing selector function is specified for the first parameter, this parameter is ignored. + * @returns {Observable} An observable sequence of windows. + */ + observableProto.window = function (windowOpeningsOrClosingSelector, windowClosingSelector) { + if (arguments.length === 1 && typeof arguments[0] !== 'function') { + return observableWindowWithBounaries.call(this, windowOpeningsOrClosingSelector); + } + return typeof windowOpeningsOrClosingSelector === 'function' ? + observableWindowWithClosingSelector.call(this, windowOpeningsOrClosingSelector) : + observableWindowWithOpenings.call(this, windowOpeningsOrClosingSelector, windowClosingSelector); + }; + + function observableWindowWithOpenings(windowOpenings, windowClosingSelector) { + return windowOpenings.groupJoin(this, windowClosingSelector, function () { + return observableEmpty(); + }, function (_, window) { + return window; + }); + } + + function observableWindowWithBounaries(windowBoundaries) { + var source = this; + return new AnonymousObservable(function (observer) { + var window = new Subject(), + d = new CompositeDisposable(), + r = new RefCountDisposable(d); + + observer.onNext(addRef(window, r)); + + d.add(source.subscribe(function (x) { + window.onNext(x); + }, function (err) { + window.onError(err); + observer.onError(err); + }, function () { + window.onCompleted(); + observer.onCompleted(); + })); + + d.add(windowBoundaries.subscribe(function (w) { + window.onCompleted(); + window = new Subject(); + observer.onNext(addRef(window, r)); + }, function (err) { + window.onError(err); + observer.onError(err); + }, function () { + window.onCompleted(); + observer.onCompleted(); + })); + + return r; + }); + } + + function observableWindowWithClosingSelector(windowClosingSelector) { + var source = this; + return new AnonymousObservable(function (observer) { + var createWindowClose, + m = new SerialDisposable(), + d = new CompositeDisposable(m), + r = new RefCountDisposable(d), + window = new Subject(); + observer.onNext(addRef(window, r)); + d.add(source.subscribe(function (x) { + window.onNext(x); + }, function (ex) { + window.onError(ex); + observer.onError(ex); + }, function () { + window.onCompleted(); + observer.onCompleted(); + })); + createWindowClose = function () { + var m1, windowClose; + try { + windowClose = windowClosingSelector(); + } catch (exception) { + observer.onError(exception); + return; + } + m1 = new SingleAssignmentDisposable(); + m.setDisposable(m1); + m1.setDisposable(windowClose.take(1).subscribe(noop, function (ex) { + window.onError(ex); + observer.onError(ex); + }, function () { + window.onCompleted(); + window = new Subject(); + observer.onNext(addRef(window, r)); + createWindowClose(); + })); + }; + createWindowClose(); + return r; + }); + } + + /** + * Returns a new observable that triggers on the second and subsequent triggerings of the input observable. + * The Nth triggering of the input observable passes the arguments from the N-1th and Nth triggering as a pair. + * The argument passed to the N-1th triggering is held in hidden internal state until the Nth triggering occurs. + * @returns {Observable} An observable that triggers on successive pairs of observations from the input observable as an array. + */ + observableProto.pairwise = function () { + var source = this; + return new AnonymousObservable(function (observer) { + var previous, hasPrevious = false; + return source.subscribe( + function (x) { + if (hasPrevious) { + observer.onNext([previous, x]); + } else { + hasPrevious = true; + } + previous = x; + }, + observer.onError.bind(observer), + observer.onCompleted.bind(observer)); + }); + }; + /** + * Returns two observables which partition the observations of the source by the given function. + * The first will trigger observations for those values for which the predicate returns true. + * The second will trigger observations for those values where the predicate returns false. + * The predicate is executed once for each subscribed observer. + * Both also propagate all error observations arising from the source and each completes + * when the source completes. + * @param {Function} predicate + * The function to determine which output Observable will trigger a particular observation. + * @returns {Array} + * An array of observables. The first triggers when the predicate returns true, + * and the second triggers when the predicate returns false. + */ + observableProto.partition = function(predicate, thisArg) { + var published = this.publish().refCount(); + return [ + published.filter(predicate, thisArg), + published.filter(function (x, i, o) { return !predicate.call(thisArg, x, i, o); }) + ]; + }; + + function enumerableWhile(condition, source) { + return new Enumerable(function () { + return new Enumerator(function () { + return condition() ? + { done: false, value: source } : + { done: true, value: undefined }; + }); + }); + } + + /** + * Returns an observable sequence that is the result of invoking the selector on the source sequence, without sharing subscriptions. + * This operator allows for a fluent style of writing queries that use the same sequence multiple times. + * + * @param {Function} selector Selector function which can use the source sequence as many times as needed, without sharing subscriptions to the source sequence. + * @returns {Observable} An observable sequence that contains the elements of a sequence produced by multicasting the source sequence within a selector function. + */ + observableProto.letBind = observableProto['let'] = function (func) { + return func(this); + }; + + /** + * Determines whether an observable collection contains values. There is an alias for this method called 'ifThen' for browsers 0) { + isOwner = !isAcquired; + isAcquired = true; + } + if (isOwner) { + m.setDisposable(scheduler.scheduleRecursive(function (self) { + var work; + if (q.length > 0) { + work = q.shift(); + } else { + isAcquired = false; + return; + } + var m1 = new SingleAssignmentDisposable(); + d.add(m1); + m1.setDisposable(work.subscribe(function (x) { + observer.onNext(x); + var result = null; + try { + result = selector(x); + } catch (e) { + observer.onError(e); + } + q.push(result); + activeCount++; + ensureActive(); + }, observer.onError.bind(observer), function () { + d.remove(m1); + activeCount--; + if (activeCount === 0) { + observer.onCompleted(); + } + })); + self(); + })); + } + }; + + q.push(source); + activeCount++; + ensureActive(); + return d; + }); + }; + + /** + * Runs all observable sequences in parallel and collect their last elements. + * + * @example + * 1 - res = Rx.Observable.forkJoin([obs1, obs2]); + * 1 - res = Rx.Observable.forkJoin(obs1, obs2, ...); + * @returns {Observable} An observable sequence with an array collecting the last elements of all the input sequences. + */ + Observable.forkJoin = function () { + var allSources = argsOrArray(arguments, 0); + return new AnonymousObservable(function (subscriber) { + var count = allSources.length; + if (count === 0) { + subscriber.onCompleted(); + return disposableEmpty; + } + var group = new CompositeDisposable(), + finished = false, + hasResults = new Array(count), + hasCompleted = new Array(count), + results = new Array(count); + + for (var idx = 0; idx < count; idx++) { + (function (i) { + var source = allSources[i]; + isPromise(source) && (source = observableFromPromise(source)); + group.add( + source.subscribe( + function (value) { + if (!finished) { + hasResults[i] = true; + results[i] = value; + } + }, + function (e) { + finished = true; + subscriber.onError(e); + group.dispose(); + }, + function () { + if (!finished) { + if (!hasResults[i]) { + subscriber.onCompleted(); + return; + } + hasCompleted[i] = true; + for (var ix = 0; ix < count; ix++) { + if (!hasCompleted[ix]) { return; } + } + finished = true; + subscriber.onNext(results); + subscriber.onCompleted(); + } + })); + })(idx); + } + + return group; + }); + }; + + /** + * Runs two observable sequences in parallel and combines their last elemenets. + * + * @param {Observable} second Second observable sequence. + * @param {Function} resultSelector Result selector function to invoke with the last elements of both sequences. + * @returns {Observable} An observable sequence with the result of calling the selector function with the last elements of both input sequences. + */ + observableProto.forkJoin = function (second, resultSelector) { + var first = this; + + return new AnonymousObservable(function (observer) { + var leftStopped = false, rightStopped = false, + hasLeft = false, hasRight = false, + lastLeft, lastRight, + leftSubscription = new SingleAssignmentDisposable(), rightSubscription = new SingleAssignmentDisposable(); + + isPromise(second) && (second = observableFromPromise(second)); + + leftSubscription.setDisposable( + first.subscribe(function (left) { + hasLeft = true; + lastLeft = left; + }, function (err) { + rightSubscription.dispose(); + observer.onError(err); + }, function () { + leftStopped = true; + if (rightStopped) { + if (!hasLeft) { + observer.onCompleted(); + } else if (!hasRight) { + observer.onCompleted(); + } else { + var result; + try { + result = resultSelector(lastLeft, lastRight); + } catch (e) { + observer.onError(e); + return; + } + observer.onNext(result); + observer.onCompleted(); + } + } + }) + ); + + rightSubscription.setDisposable( + second.subscribe(function (right) { + hasRight = true; + lastRight = right; + }, function (err) { + leftSubscription.dispose(); + observer.onError(err); + }, function () { + rightStopped = true; + if (leftStopped) { + if (!hasLeft) { + observer.onCompleted(); + } else if (!hasRight) { + observer.onCompleted(); + } else { + var result; + try { + result = resultSelector(lastLeft, lastRight); + } catch (e) { + observer.onError(e); + return; + } + observer.onNext(result); + observer.onCompleted(); + } + } + }) + ); + + return new CompositeDisposable(leftSubscription, rightSubscription); + }); + }; + + /** + * Comonadic bind operator. + * @param {Function} selector A transform function to apply to each element. + * @param {Object} scheduler Scheduler used to execute the operation. If not specified, defaults to the ImmediateScheduler. + * @returns {Observable} An observable sequence which results from the comonadic bind operation. + */ + observableProto.manySelect = function (selector, scheduler) { + scheduler || (scheduler = immediateScheduler); + var source = this; + return observableDefer(function () { + var chain; + + return source + .select( + function (x) { + var curr = new ChainObservable(x); + if (chain) { + chain.onNext(x); + } + chain = curr; + + return curr; + }) + .doAction( + noop, + function (e) { + if (chain) { + chain.onError(e); + } + }, + function () { + if (chain) { + chain.onCompleted(); + } + }) + .observeOn(scheduler) + .select(function (x, i, o) { return selector(x, i, o); }); + }); + }; + + var ChainObservable = (function (_super) { + + function subscribe (observer) { + var self = this, g = new CompositeDisposable(); + g.add(currentThreadScheduler.schedule(function () { + observer.onNext(self.head); + g.add(self.tail.mergeObservable().subscribe(observer)); + })); + + return g; + } + + inherits(ChainObservable, _super); + + function ChainObservable(head) { + _super.call(this, subscribe); + this.head = head; + this.tail = new AsyncSubject(); + } + + addProperties(ChainObservable.prototype, Observer, { + onCompleted: function () { + this.onNext(Observable.empty()); + }, + onError: function (e) { + this.onNext(Observable.throwException(e)); + }, + onNext: function (v) { + this.tail.onNext(v); + this.tail.onCompleted(); + } + }); + + return ChainObservable; + + }(Observable)); + + /** @private */ + var Map = (function () { + + /** + * @constructor + * @private + */ + function Map() { + this.keys = []; + this.values = []; + } + + /** + * @private + * @memberOf Map# + */ + Map.prototype['delete'] = function (key) { + var i = this.keys.indexOf(key); + if (i !== -1) { + this.keys.splice(i, 1); + this.values.splice(i, 1); + } + return i !== -1; + }; + + /** + * @private + * @memberOf Map# + */ + Map.prototype.get = function (key, fallback) { + var i = this.keys.indexOf(key); + return i !== -1 ? this.values[i] : fallback; + }; + + /** + * @private + * @memberOf Map# + */ + Map.prototype.set = function (key, value) { + var i = this.keys.indexOf(key); + if (i !== -1) { + this.values[i] = value; + } + this.values[this.keys.push(key) - 1] = value; + }; + + /** + * @private + * @memberOf Map# + */ + Map.prototype.size = function () { return this.keys.length; }; + + /** + * @private + * @memberOf Map# + */ + Map.prototype.has = function (key) { + return this.keys.indexOf(key) !== -1; + }; + + /** + * @private + * @memberOf Map# + */ + Map.prototype.getKeys = function () { return this.keys.slice(0); }; + + /** + * @private + * @memberOf Map# + */ + Map.prototype.getValues = function () { return this.values.slice(0); }; + + return Map; + }()); + + /** + * @constructor + * Represents a join pattern over observable sequences. + */ + function Pattern(patterns) { + this.patterns = patterns; + } + + /** + * Creates a pattern that matches the current plan matches and when the specified observable sequences has an available value. + * + * @param other Observable sequence to match in addition to the current pattern. + * @return Pattern object that matches when all observable sequences in the pattern have an available value. + */ + Pattern.prototype.and = function (other) { + var patterns = this.patterns.slice(0); + patterns.push(other); + return new Pattern(patterns); + }; + + /** + * Matches when all observable sequences in the pattern (specified using a chain of and operators) have an available value and projects the values. + * + * @param selector Selector that will be invoked with available values from the source sequences, in the same order of the sequences in the pattern. + * @return Plan that produces the projected values, to be fed (with other plans) to the when operator. + */ + Pattern.prototype.then = function (selector) { + return new Plan(this, selector); + }; + + function Plan(expression, selector) { + this.expression = expression; + this.selector = selector; + } + + Plan.prototype.activate = function (externalSubscriptions, observer, deactivate) { + var self = this; + var joinObservers = []; + for (var i = 0, len = this.expression.patterns.length; i < len; i++) { + joinObservers.push(planCreateObserver(externalSubscriptions, this.expression.patterns[i], observer.onError.bind(observer))); + } + var activePlan = new ActivePlan(joinObservers, function () { + var result; + try { + result = self.selector.apply(self, arguments); + } catch (exception) { + observer.onError(exception); + return; + } + observer.onNext(result); + }, function () { + for (var j = 0, jlen = joinObservers.length; j < jlen; j++) { + joinObservers[j].removeActivePlan(activePlan); + } + deactivate(activePlan); + }); + for (i = 0, len = joinObservers.length; i < len; i++) { + joinObservers[i].addActivePlan(activePlan); + } + return activePlan; + }; + + function planCreateObserver(externalSubscriptions, observable, onError) { + var entry = externalSubscriptions.get(observable); + if (!entry) { + var observer = new JoinObserver(observable, onError); + externalSubscriptions.set(observable, observer); + return observer; + } + return entry; + } + + // Active Plan + function ActivePlan(joinObserverArray, onNext, onCompleted) { + var i, joinObserver; + this.joinObserverArray = joinObserverArray; + this.onNext = onNext; + this.onCompleted = onCompleted; + this.joinObservers = new Map(); + for (i = 0; i < this.joinObserverArray.length; i++) { + joinObserver = this.joinObserverArray[i]; + this.joinObservers.set(joinObserver, joinObserver); + } + } + + ActivePlan.prototype.dequeue = function () { + var values = this.joinObservers.getValues(); + for (var i = 0, len = values.length; i < len; i++) { + values[i].queue.shift(); + } + }; + ActivePlan.prototype.match = function () { + var firstValues, i, len, isCompleted, values, hasValues = true; + for (i = 0, len = this.joinObserverArray.length; i < len; i++) { + if (this.joinObserverArray[i].queue.length === 0) { + hasValues = false; + break; + } + } + if (hasValues) { + firstValues = []; + isCompleted = false; + for (i = 0, len = this.joinObserverArray.length; i < len; i++) { + firstValues.push(this.joinObserverArray[i].queue[0]); + if (this.joinObserverArray[i].queue[0].kind === 'C') { + isCompleted = true; + } + } + if (isCompleted) { + this.onCompleted(); + } else { + this.dequeue(); + values = []; + for (i = 0; i < firstValues.length; i++) { + values.push(firstValues[i].value); + } + this.onNext.apply(this, values); + } + } + }; + + /** @private */ + var JoinObserver = (function (_super) { + + inherits(JoinObserver, _super); + + /** + * @constructor + * @private + */ + function JoinObserver(source, onError) { + _super.call(this); + this.source = source; + this.onError = onError; + this.queue = []; + this.activePlans = []; + this.subscription = new SingleAssignmentDisposable(); + this.isDisposed = false; + } + + var JoinObserverPrototype = JoinObserver.prototype; + + /** + * @memberOf JoinObserver# + * @private + */ + JoinObserverPrototype.next = function (notification) { + if (!this.isDisposed) { + if (notification.kind === 'E') { + this.onError(notification.exception); + return; + } + this.queue.push(notification); + var activePlans = this.activePlans.slice(0); + for (var i = 0, len = activePlans.length; i < len; i++) { + activePlans[i].match(); + } + } + }; + + /** + * @memberOf JoinObserver# + * @private + */ + JoinObserverPrototype.error = noop; + + /** + * @memberOf JoinObserver# + * @private + */ + JoinObserverPrototype.completed = noop; + + /** + * @memberOf JoinObserver# + * @private + */ + JoinObserverPrototype.addActivePlan = function (activePlan) { + this.activePlans.push(activePlan); + }; + + /** + * @memberOf JoinObserver# + * @private + */ + JoinObserverPrototype.subscribe = function () { + this.subscription.setDisposable(this.source.materialize().subscribe(this)); + }; + + /** + * @memberOf JoinObserver# + * @private + */ + JoinObserverPrototype.removeActivePlan = function (activePlan) { + var idx = this.activePlans.indexOf(activePlan); + this.activePlans.splice(idx, 1); + if (this.activePlans.length === 0) { + this.dispose(); + } + }; + + /** + * @memberOf JoinObserver# + * @private + */ + JoinObserverPrototype.dispose = function () { + _super.prototype.dispose.call(this); + if (!this.isDisposed) { + this.isDisposed = true; + this.subscription.dispose(); + } + }; + + return JoinObserver; + } (AbstractObserver)); + + /** + * Creates a pattern that matches when both observable sequences have an available value. + * + * @param right Observable sequence to match with the current sequence. + * @return {Pattern} Pattern object that matches when both observable sequences have an available value. + */ + observableProto.and = function (right) { + return new Pattern([this, right]); + }; + + /** + * Matches when the observable sequence has an available value and projects the value. + * + * @param selector Selector that will be invoked for values in the source sequence. + * @returns {Plan} Plan that produces the projected values, to be fed (with other plans) to the when operator. + */ + observableProto.then = function (selector) { + return new Pattern([this]).then(selector); + }; + + /** + * Joins together the results from several patterns. + * + * @param plans A series of plans (specified as an Array of as a series of arguments) created by use of the Then operator on patterns. + * @returns {Observable} Observable sequence with the results form matching several patterns. + */ + Observable.when = function () { + var plans = argsOrArray(arguments, 0); + return new AnonymousObservable(function (observer) { + var activePlans = [], + externalSubscriptions = new Map(), + group, + i, len, + joinObserver, + joinValues, + outObserver; + outObserver = observerCreate(observer.onNext.bind(observer), function (exception) { + var values = externalSubscriptions.getValues(); + for (var j = 0, jlen = values.length; j < jlen; j++) { + values[j].onError(exception); + } + observer.onError(exception); + }, observer.onCompleted.bind(observer)); + try { + for (i = 0, len = plans.length; i < len; i++) { + activePlans.push(plans[i].activate(externalSubscriptions, outObserver, function (activePlan) { + var idx = activePlans.indexOf(activePlan); + activePlans.splice(idx, 1); + if (activePlans.length === 0) { + outObserver.onCompleted(); + } + })); + } + } catch (e) { + observableThrow(e).subscribe(observer); + } + group = new CompositeDisposable(); + joinValues = externalSubscriptions.getValues(); + for (i = 0, len = joinValues.length; i < len; i++) { + joinObserver = joinValues[i]; + joinObserver.subscribe(); + group.add(joinObserver); + } + return group; + }); + }; + + function observableTimerDate(dueTime, scheduler) { + return new AnonymousObservable(function (observer) { + return scheduler.scheduleWithAbsolute(dueTime, function () { + observer.onNext(0); + observer.onCompleted(); + }); + }); + } + + function observableTimerDateAndPeriod(dueTime, period, scheduler) { + var p = normalizeTime(period); + return new AnonymousObservable(function (observer) { + var count = 0, d = dueTime; + return scheduler.scheduleRecursiveWithAbsolute(d, function (self) { + var now; + if (p > 0) { + now = scheduler.now(); + d = d + p; + if (d <= now) { + d = now + p; + } + } + observer.onNext(count++); + self(d); + }); + }); + } + + function observableTimerTimeSpan(dueTime, scheduler) { + var d = normalizeTime(dueTime); + return new AnonymousObservable(function (observer) { + return scheduler.scheduleWithRelative(d, function () { + observer.onNext(0); + observer.onCompleted(); + }); + }); + } + + function observableTimerTimeSpanAndPeriod(dueTime, period, scheduler) { + if (dueTime === period) { + return new AnonymousObservable(function (observer) { + return scheduler.schedulePeriodicWithState(0, period, function (count) { + observer.onNext(count); + return count + 1; + }); + }); + } + return observableDefer(function () { + return observableTimerDateAndPeriod(scheduler.now() + dueTime, period, scheduler); + }); + } + + /** + * Returns an observable sequence that produces a value after each period. + * + * @example + * 1 - res = Rx.Observable.interval(1000); + * 2 - res = Rx.Observable.interval(1000, Rx.Scheduler.timeout); + * + * @param {Number} period Period for producing the values in the resulting sequence (specified as an integer denoting milliseconds). + * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, Rx.Scheduler.timeout is used. + * @returns {Observable} An observable sequence that produces a value after each period. + */ + var observableinterval = Observable.interval = function (period, scheduler) { + scheduler || (scheduler = timeoutScheduler); + return observableTimerTimeSpanAndPeriod(period, period, scheduler); + }; + + /** + * Returns an observable sequence that produces a value after dueTime has elapsed and then after each period. + * + * @example + * 1 - res = Rx.Observable.timer(new Date()); + * 2 - res = Rx.Observable.timer(new Date(), 1000); + * 3 - res = Rx.Observable.timer(new Date(), Rx.Scheduler.timeout); + * 4 - res = Rx.Observable.timer(new Date(), 1000, Rx.Scheduler.timeout); + * + * 5 - res = Rx.Observable.timer(5000); + * 6 - res = Rx.Observable.timer(5000, 1000); + * 7 - res = Rx.Observable.timer(5000, Rx.Scheduler.timeout); + * 8 - res = Rx.Observable.timer(5000, 1000, Rx.Scheduler.timeout); + * + * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) at which to produce the first value. + * @param {Mixed} [periodOrScheduler] Period to produce subsequent values (specified as an integer denoting milliseconds), or the scheduler to run the timer on. If not specified, the resulting timer is not recurring. + * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, the timeout scheduler is used. + * @returns {Observable} An observable sequence that produces a value after due time has elapsed and then each period. + */ + var observableTimer = Observable.timer = function (dueTime, periodOrScheduler, scheduler) { + var period; + scheduler || (scheduler = timeoutScheduler); + if (periodOrScheduler !== undefined && typeof periodOrScheduler === 'number') { + period = periodOrScheduler; + } else if (periodOrScheduler !== undefined && typeof periodOrScheduler === 'object') { + scheduler = periodOrScheduler; + } + if (dueTime instanceof Date && period === undefined) { + return observableTimerDate(dueTime.getTime(), scheduler); + } + if (dueTime instanceof Date && period !== undefined) { + period = periodOrScheduler; + return observableTimerDateAndPeriod(dueTime.getTime(), period, scheduler); + } + if (period === undefined) { + return observableTimerTimeSpan(dueTime, scheduler); + } + return observableTimerTimeSpanAndPeriod(dueTime, period, scheduler); + }; + + function observableDelayTimeSpan(dueTime, scheduler) { + var source = this; + return new AnonymousObservable(function (observer) { + var active = false, + cancelable = new SerialDisposable(), + exception = null, + q = [], + running = false, + subscription; + subscription = source.materialize().timestamp(scheduler).subscribe(function (notification) { + var d, shouldRun; + if (notification.value.kind === 'E') { + q = []; + q.push(notification); + exception = notification.value.exception; + shouldRun = !running; + } else { + q.push({ value: notification.value, timestamp: notification.timestamp + dueTime }); + shouldRun = !active; + active = true; + } + if (shouldRun) { + if (exception !== null) { + observer.onError(exception); + } else { + d = new SingleAssignmentDisposable(); + cancelable.setDisposable(d); + d.setDisposable(scheduler.scheduleRecursiveWithRelative(dueTime, function (self) { + var e, recurseDueTime, result, shouldRecurse; + if (exception !== null) { + return; + } + running = true; + do { + result = null; + if (q.length > 0 && q[0].timestamp - scheduler.now() <= 0) { + result = q.shift().value; + } + if (result !== null) { + result.accept(observer); + } + } while (result !== null); + shouldRecurse = false; + recurseDueTime = 0; + if (q.length > 0) { + shouldRecurse = true; + recurseDueTime = Math.max(0, q[0].timestamp - scheduler.now()); + } else { + active = false; + } + e = exception; + running = false; + if (e !== null) { + observer.onError(e); + } else if (shouldRecurse) { + self(recurseDueTime); + } + })); + } + } + }); + return new CompositeDisposable(subscription, cancelable); + }); + } + + function observableDelayDate(dueTime, scheduler) { + var self = this; + return observableDefer(function () { + var timeSpan = dueTime - scheduler.now(); + return observableDelayTimeSpan.call(self, timeSpan, scheduler); + }); + } + + /** + * Time shifts the observable sequence by dueTime. The relative time intervals between the values are preserved. + * + * @example + * 1 - res = Rx.Observable.delay(new Date()); + * 2 - res = Rx.Observable.delay(new Date(), Rx.Scheduler.timeout); + * + * 3 - res = Rx.Observable.delay(5000); + * 4 - res = Rx.Observable.delay(5000, 1000, Rx.Scheduler.timeout); + * @memberOf Observable# + * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) by which to shift the observable sequence. + * @param {Scheduler} [scheduler] Scheduler to run the delay timers on. If not specified, the timeout scheduler is used. + * @returns {Observable} Time-shifted sequence. + */ + observableProto.delay = function (dueTime, scheduler) { + scheduler || (scheduler = timeoutScheduler); + return dueTime instanceof Date ? + observableDelayDate.call(this, dueTime.getTime(), scheduler) : + observableDelayTimeSpan.call(this, dueTime, scheduler); + }; + + /** + * Ignores values from an observable sequence which are followed by another value before dueTime. + * + * @example + * 1 - res = source.throttle(5000); // 5 seconds + * 2 - res = source.throttle(5000, scheduler); + * + * @param {Number} dueTime Duration of the throttle period for each value (specified as an integer denoting milliseconds). + * @param {Scheduler} [scheduler] Scheduler to run the throttle timers on. If not specified, the timeout scheduler is used. + * @returns {Observable} The throttled sequence. + */ + observableProto.throttle = function (dueTime, scheduler) { + scheduler || (scheduler = timeoutScheduler); + var source = this; + return this.throttleWithSelector(function () { return observableTimer(dueTime, scheduler); }) + }; + + /** + * Projects each element of an observable sequence into zero or more windows which are produced based on timing information. + * + * @example + * 1 - res = xs.windowWithTime(1000, scheduler); // non-overlapping segments of 1 second + * 2 - res = xs.windowWithTime(1000, 500 , scheduler); // segments of 1 second with time shift 0.5 seconds + * + * @param {Number} timeSpan Length of each window (specified as an integer denoting milliseconds). + * @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive windows (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent windows. + * @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used. + * @returns {Observable} An observable sequence of windows. + */ + observableProto.windowWithTime = function (timeSpan, timeShiftOrScheduler, scheduler) { + var source = this, timeShift; + if (timeShiftOrScheduler === undefined) { + timeShift = timeSpan; + } + if (scheduler === undefined) { + scheduler = timeoutScheduler; + } + if (typeof timeShiftOrScheduler === 'number') { + timeShift = timeShiftOrScheduler; + } else if (typeof timeShiftOrScheduler === 'object') { + timeShift = timeSpan; + scheduler = timeShiftOrScheduler; + } + return new AnonymousObservable(function (observer) { + var groupDisposable, + nextShift = timeShift, + nextSpan = timeSpan, + q = [], + refCountDisposable, + timerD = new SerialDisposable(), + totalTime = 0; + groupDisposable = new CompositeDisposable(timerD), + refCountDisposable = new RefCountDisposable(groupDisposable); + + function createTimer () { + var m = new SingleAssignmentDisposable(), + isSpan = false, + isShift = false; + timerD.setDisposable(m); + if (nextSpan === nextShift) { + isSpan = true; + isShift = true; + } else if (nextSpan < nextShift) { + isSpan = true; + } else { + isShift = true; + } + var newTotalTime = isSpan ? nextSpan : nextShift, + ts = newTotalTime - totalTime; + totalTime = newTotalTime; + if (isSpan) { + nextSpan += timeShift; + } + if (isShift) { + nextShift += timeShift; + } + m.setDisposable(scheduler.scheduleWithRelative(ts, function () { + var s; + if (isShift) { + s = new Subject(); + q.push(s); + observer.onNext(addRef(s, refCountDisposable)); + } + if (isSpan) { + s = q.shift(); + s.onCompleted(); + } + createTimer(); + })); + }; + q.push(new Subject()); + observer.onNext(addRef(q[0], refCountDisposable)); + createTimer(); + groupDisposable.add(source.subscribe(function (x) { + var i, s; + for (i = 0; i < q.length; i++) { + s = q[i]; + s.onNext(x); + } + }, function (e) { + var i, s; + for (i = 0; i < q.length; i++) { + s = q[i]; + s.onError(e); + } + observer.onError(e); + }, function () { + var i, s; + for (i = 0; i < q.length; i++) { + s = q[i]; + s.onCompleted(); + } + observer.onCompleted(); + })); + return refCountDisposable; + }); + }; + + /** + * Projects each element of an observable sequence into a window that is completed when either it's full or a given amount of time has elapsed. + * @example + * 1 - res = source.windowWithTimeOrCount(5000, 50); // 5s or 50 items + * 2 - res = source.windowWithTimeOrCount(5000, 50, scheduler); //5s or 50 items + * + * @memberOf Observable# + * @param {Number} timeSpan Maximum time length of a window. + * @param {Number} count Maximum element count of a window. + * @param {Scheduler} [scheduler] Scheduler to run windowing timers on. If not specified, the timeout scheduler is used. + * @returns {Observable} An observable sequence of windows. + */ + observableProto.windowWithTimeOrCount = function (timeSpan, count, scheduler) { + var source = this; + scheduler || (scheduler = timeoutScheduler); + return new AnonymousObservable(function (observer) { + var createTimer, + groupDisposable, + n = 0, + refCountDisposable, + s, + timerD = new SerialDisposable(), + windowId = 0; + groupDisposable = new CompositeDisposable(timerD); + refCountDisposable = new RefCountDisposable(groupDisposable); + createTimer = function (id) { + var m = new SingleAssignmentDisposable(); + timerD.setDisposable(m); + m.setDisposable(scheduler.scheduleWithRelative(timeSpan, function () { + var newId; + if (id !== windowId) { + return; + } + n = 0; + newId = ++windowId; + s.onCompleted(); + s = new Subject(); + observer.onNext(addRef(s, refCountDisposable)); + createTimer(newId); + })); + }; + s = new Subject(); + observer.onNext(addRef(s, refCountDisposable)); + createTimer(0); + groupDisposable.add(source.subscribe(function (x) { + var newId = 0, newWindow = false; + s.onNext(x); + n++; + if (n === count) { + newWindow = true; + n = 0; + newId = ++windowId; + s.onCompleted(); + s = new Subject(); + observer.onNext(addRef(s, refCountDisposable)); + } + if (newWindow) { + createTimer(newId); + } + }, function (e) { + s.onError(e); + observer.onError(e); + }, function () { + s.onCompleted(); + observer.onCompleted(); + })); + return refCountDisposable; + }); + }; + + /** + * Projects each element of an observable sequence into zero or more buffers which are produced based on timing information. + * + * @example + * 1 - res = xs.bufferWithTime(1000, scheduler); // non-overlapping segments of 1 second + * 2 - res = xs.bufferWithTime(1000, 500, scheduler; // segments of 1 second with time shift 0.5 seconds + * + * @param {Number} timeSpan Length of each buffer (specified as an integer denoting milliseconds). + * @param {Mixed} [timeShiftOrScheduler] Interval between creation of consecutive buffers (specified as an integer denoting milliseconds), or an optional scheduler parameter. If not specified, the time shift corresponds to the timeSpan parameter, resulting in non-overlapping adjacent buffers. + * @param {Scheduler} [scheduler] Scheduler to run buffer timers on. If not specified, the timeout scheduler is used. + * @returns {Observable} An observable sequence of buffers. + */ + observableProto.bufferWithTime = function (timeSpan, timeShiftOrScheduler, scheduler) { + return this.windowWithTime.apply(this, arguments).selectMany(function (x) { return x.toArray(); }); + }; + + /** + * Projects each element of an observable sequence into a buffer that is completed when either it's full or a given amount of time has elapsed. + * + * @example + * 1 - res = source.bufferWithTimeOrCount(5000, 50); // 5s or 50 items in an array + * 2 - res = source.bufferWithTimeOrCount(5000, 50, scheduler); // 5s or 50 items in an array + * + * @param {Number} timeSpan Maximum time length of a buffer. + * @param {Number} count Maximum element count of a buffer. + * @param {Scheduler} [scheduler] Scheduler to run bufferin timers on. If not specified, the timeout scheduler is used. + * @returns {Observable} An observable sequence of buffers. + */ + observableProto.bufferWithTimeOrCount = function (timeSpan, count, scheduler) { + return this.windowWithTimeOrCount(timeSpan, count, scheduler).selectMany(function (x) { + return x.toArray(); + }); + }; + + /** + * Records the time interval between consecutive values in an observable sequence. + * + * @example + * 1 - res = source.timeInterval(); + * 2 - res = source.timeInterval(Rx.Scheduler.timeout); + * + * @param [scheduler] Scheduler used to compute time intervals. If not specified, the timeout scheduler is used. + * @returns {Observable} An observable sequence with time interval information on values. + */ + observableProto.timeInterval = function (scheduler) { + var source = this; + scheduler || (scheduler = timeoutScheduler); + return observableDefer(function () { + var last = scheduler.now(); + return source.select(function (x) { + var now = scheduler.now(), span = now - last; + last = now; + return { + value: x, + interval: span + }; + }); + }); + }; + + /** + * Records the timestamp for each value in an observable sequence. + * + * @example + * 1 - res = source.timestamp(); // produces { value: x, timestamp: ts } + * 2 - res = source.timestamp(Rx.Scheduler.timeout); + * + * @param {Scheduler} [scheduler] Scheduler used to compute timestamps. If not specified, the timeout scheduler is used. + * @returns {Observable} An observable sequence with timestamp information on values. + */ + observableProto.timestamp = function (scheduler) { + scheduler || (scheduler = timeoutScheduler); + return this.select(function (x) { + return { + value: x, + timestamp: scheduler.now() + }; + }); + }; + + function sampleObservable(source, sampler) { + + return new AnonymousObservable(function (observer) { + var atEnd, value, hasValue; + + function sampleSubscribe() { + if (hasValue) { + hasValue = false; + observer.onNext(value); + } + if (atEnd) { + observer.onCompleted(); + } + } + + return new CompositeDisposable( + source.subscribe(function (newValue) { + hasValue = true; + value = newValue; + }, observer.onError.bind(observer), function () { + atEnd = true; + }), + sampler.subscribe(sampleSubscribe, observer.onError.bind(observer), sampleSubscribe) + ); + }); + } + + /** + * Samples the observable sequence at each interval. + * + * @example + * 1 - res = source.sample(sampleObservable); // Sampler tick sequence + * 2 - res = source.sample(5000); // 5 seconds + * 2 - res = source.sample(5000, Rx.Scheduler.timeout); // 5 seconds + * + * @param {Mixed} intervalOrSampler Interval at which to sample (specified as an integer denoting milliseconds) or Sampler Observable. + * @param {Scheduler} [scheduler] Scheduler to run the sampling timer on. If not specified, the timeout scheduler is used. + * @returns {Observable} Sampled observable sequence. + */ + observableProto.sample = function (intervalOrSampler, scheduler) { + scheduler || (scheduler = timeoutScheduler); + if (typeof intervalOrSampler === 'number') { + return sampleObservable(this, observableinterval(intervalOrSampler, scheduler)); + } + return sampleObservable(this, intervalOrSampler); + }; + + /** + * Returns the source observable sequence or the other observable sequence if dueTime elapses. + * + * @example + * 1 - res = source.timeout(new Date()); // As a date + * 2 - res = source.timeout(5000); // 5 seconds + * 3 - res = source.timeout(new Date(), Rx.Observable.returnValue(42)); // As a date and timeout observable + * 4 - res = source.timeout(5000, Rx.Observable.returnValue(42)); // 5 seconds and timeout observable + * 5 - res = source.timeout(new Date(), Rx.Observable.returnValue(42), Rx.Scheduler.timeout); // As a date and timeout observable + * 6 - res = source.timeout(5000, Rx.Observable.returnValue(42), Rx.Scheduler.timeout); // 5 seconds and timeout observable + * + * @param {Number} dueTime Absolute (specified as a Date object) or relative time (specified as an integer denoting milliseconds) when a timeout occurs. + * @param {Observable} [other] Sequence to return in case of a timeout. If not specified, a timeout error throwing sequence will be used. + * @param {Scheduler} [scheduler] Scheduler to run the timeout timers on. If not specified, the timeout scheduler is used. + * @returns {Observable} The source sequence switching to the other sequence in case of a timeout. + */ + observableProto.timeout = function (dueTime, other, scheduler) { + other || (other = observableThrow(new Error('Timeout'))); + scheduler || (scheduler = timeoutScheduler); + + var source = this, schedulerMethod = dueTime instanceof Date ? + 'scheduleWithAbsolute' : + 'scheduleWithRelative'; + + return new AnonymousObservable(function (observer) { + var id = 0, + original = new SingleAssignmentDisposable(), + subscription = new SerialDisposable(), + switched = false, + timer = new SerialDisposable(); + + subscription.setDisposable(original); + + var createTimer = function () { + var myId = id; + timer.setDisposable(scheduler[schedulerMethod](dueTime, function () { + if (id === myId) { + isPromise(other) && (other = observableFromPromise(other)); + subscription.setDisposable(other.subscribe(observer)); + } + })); + }; + + createTimer(); + + original.setDisposable(source.subscribe(function (x) { + if (!switched) { + id++; + observer.onNext(x); + createTimer(); + } + }, function (e) { + if (!switched) { + id++; + observer.onError(e); + } + }, function () { + if (!switched) { + id++; + observer.onCompleted(); + } + })); + return new CompositeDisposable(subscription, timer); + }); + }; + + /** + * Generates an observable sequence by iterating a state from an initial state until the condition fails. + * + * @example + * res = source.generateWithAbsoluteTime(0, + * function (x) { return return true; }, + * function (x) { return x + 1; }, + * function (x) { return x; }, + * function (x) { return new Date(); } + * }); + * + * @param {Mixed} initialState Initial state. + * @param {Function} condition Condition to terminate generation (upon returning false). + * @param {Function} iterate Iteration step function. + * @param {Function} resultSelector Selector function for results produced in the sequence. + * @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning Date values. + * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used. + * @returns {Observable} The generated sequence. + */ + Observable.generateWithAbsoluteTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) { + scheduler || (scheduler = timeoutScheduler); + return new AnonymousObservable(function (observer) { + var first = true, + hasResult = false, + result, + state = initialState, + time; + return scheduler.scheduleRecursiveWithAbsolute(scheduler.now(), function (self) { + if (hasResult) { + observer.onNext(result); + } + try { + if (first) { + first = false; + } else { + state = iterate(state); + } + hasResult = condition(state); + if (hasResult) { + result = resultSelector(state); + time = timeSelector(state); + } + } catch (e) { + observer.onError(e); + return; + } + if (hasResult) { + self(time); + } else { + observer.onCompleted(); + } + }); + }); + }; + + /** + * Generates an observable sequence by iterating a state from an initial state until the condition fails. + * + * @example + * res = source.generateWithRelativeTime(0, + * function (x) { return return true; }, + * function (x) { return x + 1; }, + * function (x) { return x; }, + * function (x) { return 500; } + * ); + * + * @param {Mixed} initialState Initial state. + * @param {Function} condition Condition to terminate generation (upon returning false). + * @param {Function} iterate Iteration step function. + * @param {Function} resultSelector Selector function for results produced in the sequence. + * @param {Function} timeSelector Time selector function to control the speed of values being produced each iteration, returning integer values denoting milliseconds. + * @param {Scheduler} [scheduler] Scheduler on which to run the generator loop. If not specified, the timeout scheduler is used. + * @returns {Observable} The generated sequence. + */ + Observable.generateWithRelativeTime = function (initialState, condition, iterate, resultSelector, timeSelector, scheduler) { + scheduler || (scheduler = timeoutScheduler); + return new AnonymousObservable(function (observer) { + var first = true, + hasResult = false, + result, + state = initialState, + time; + return scheduler.scheduleRecursiveWithRelative(0, function (self) { + if (hasResult) { + observer.onNext(result); + } + try { + if (first) { + first = false; + } else { + state = iterate(state); + } + hasResult = condition(state); + if (hasResult) { + result = resultSelector(state); + time = timeSelector(state); + } + } catch (e) { + observer.onError(e); + return; + } + if (hasResult) { + self(time); + } else { + observer.onCompleted(); + } + }); + }); + }; + + /** + * Time shifts the observable sequence by delaying the subscription. + * + * @example + * 1 - res = source.delaySubscription(5000); // 5s + * 2 - res = source.delaySubscription(5000, Rx.Scheduler.timeout); // 5 seconds + * + * @param {Number} dueTime Absolute or relative time to perform the subscription at. + * @param {Scheduler} [scheduler] Scheduler to run the subscription delay timer on. If not specified, the timeout scheduler is used. + * @returns {Observable} Time-shifted sequence. + */ + observableProto.delaySubscription = function (dueTime, scheduler) { + scheduler || (scheduler = timeoutScheduler); + return this.delayWithSelector(observableTimer(dueTime, scheduler), function () { return observableEmpty(); }); + }; + + /** + * Time shifts the observable sequence based on a subscription delay and a delay selector function for each element. + * + * @example + * 1 - res = source.delayWithSelector(function (x) { return Rx.Scheduler.timer(5000); }); // with selector only + * 1 - res = source.delayWithSelector(Rx.Observable.timer(2000), function (x) { return Rx.Observable.timer(x); }); // with delay and selector + * + * @param {Observable} [subscriptionDelay] Sequence indicating the delay for the subscription to the source. + * @param {Function} delayDurationSelector Selector function to retrieve a sequence indicating the delay for each given element. + * @returns {Observable} Time-shifted sequence. + */ + observableProto.delayWithSelector = function (subscriptionDelay, delayDurationSelector) { + var source = this, subDelay, selector; + if (typeof subscriptionDelay === 'function') { + selector = subscriptionDelay; + } else { + subDelay = subscriptionDelay; + selector = delayDurationSelector; + } + return new AnonymousObservable(function (observer) { + var delays = new CompositeDisposable(), atEnd = false, done = function () { + if (atEnd && delays.length === 0) { + observer.onCompleted(); + } + }, subscription = new SerialDisposable(), start = function () { + subscription.setDisposable(source.subscribe(function (x) { + var delay; + try { + delay = selector(x); + } catch (error) { + observer.onError(error); + return; + } + var d = new SingleAssignmentDisposable(); + delays.add(d); + d.setDisposable(delay.subscribe(function () { + observer.onNext(x); + delays.remove(d); + done(); + }, observer.onError.bind(observer), function () { + observer.onNext(x); + delays.remove(d); + done(); + })); + }, observer.onError.bind(observer), function () { + atEnd = true; + subscription.dispose(); + done(); + })); + }; + + if (!subDelay) { + start(); + } else { + subscription.setDisposable(subDelay.subscribe(function () { + start(); + }, observer.onError.bind(observer), function () { start(); })); + } + + return new CompositeDisposable(subscription, delays); + }); + }; + + /** + * Returns the source observable sequence, switching to the other observable sequence if a timeout is signaled. + * + * @example + * 1 - res = source.timeoutWithSelector(Rx.Observable.timer(500)); + * 2 - res = source.timeoutWithSelector(Rx.Observable.timer(500), function (x) { return Rx.Observable.timer(200); }); + * 3 - res = source.timeoutWithSelector(Rx.Observable.timer(500), function (x) { return Rx.Observable.timer(200); }, Rx.Observable.returnValue(42)); + * + * @param {Observable} [firstTimeout] Observable sequence that represents the timeout for the first element. If not provided, this defaults to Observable.never(). + * @param {Function} [timeoutDurationSelector] Selector to retrieve an observable sequence that represents the timeout between the current element and the next element. + * @param {Observable} [other] Sequence to return in case of a timeout. If not provided, this is set to Observable.throwException(). + * @returns {Observable} The source sequence switching to the other sequence in case of a timeout. + */ + observableProto.timeoutWithSelector = function (firstTimeout, timeoutdurationSelector, other) { + if (arguments.length === 1) { + timeoutdurationSelector = firstTimeout; + var firstTimeout = observableNever(); + } + other || (other = observableThrow(new Error('Timeout'))); + var source = this; + return new AnonymousObservable(function (observer) { + var subscription = new SerialDisposable(), timer = new SerialDisposable(), original = new SingleAssignmentDisposable(); + + subscription.setDisposable(original); + + var id = 0, switched = false, setTimer = function (timeout) { + var myId = id, timerWins = function () { + return id === myId; + }; + var d = new SingleAssignmentDisposable(); + timer.setDisposable(d); + d.setDisposable(timeout.subscribe(function () { + if (timerWins()) { + subscription.setDisposable(other.subscribe(observer)); + } + d.dispose(); + }, function (e) { + if (timerWins()) { + observer.onError(e); + } + }, function () { + if (timerWins()) { + subscription.setDisposable(other.subscribe(observer)); + } + })); + }; + + setTimer(firstTimeout); + var observerWins = function () { + var res = !switched; + if (res) { + id++; + } + return res; + }; + + original.setDisposable(source.subscribe(function (x) { + if (observerWins()) { + observer.onNext(x); + var timeout; + try { + timeout = timeoutdurationSelector(x); + } catch (e) { + observer.onError(e); + return; + } + setTimer(timeout); + } + }, function (e) { + if (observerWins()) { + observer.onError(e); + } + }, function () { + if (observerWins()) { + observer.onCompleted(); + } + })); + return new CompositeDisposable(subscription, timer); + }); + }; + + /** + * Ignores values from an observable sequence which are followed by another value within a computed throttle duration. + * + * @example + * 1 - res = source.delayWithSelector(function (x) { return Rx.Scheduler.timer(x + x); }); + * + * @param {Function} throttleDurationSelector Selector function to retrieve a sequence indicating the throttle duration for each given element. + * @returns {Observable} The throttled sequence. + */ + observableProto.throttleWithSelector = function (throttleDurationSelector) { + var source = this; + return new AnonymousObservable(function (observer) { + var value, hasValue = false, cancelable = new SerialDisposable(), id = 0, subscription = source.subscribe(function (x) { + var throttle; + try { + throttle = throttleDurationSelector(x); + } catch (e) { + observer.onError(e); + return; + } + hasValue = true; + value = x; + id++; + var currentid = id, d = new SingleAssignmentDisposable(); + cancelable.setDisposable(d); + d.setDisposable(throttle.subscribe(function () { + if (hasValue && id === currentid) { + observer.onNext(value); + } + hasValue = false; + d.dispose(); + }, observer.onError.bind(observer), function () { + if (hasValue && id === currentid) { + observer.onNext(value); + } + hasValue = false; + d.dispose(); + })); + }, function (e) { + cancelable.dispose(); + observer.onError(e); + hasValue = false; + id++; + }, function () { + cancelable.dispose(); + if (hasValue) { + observer.onNext(value); + } + observer.onCompleted(); + hasValue = false; + id++; + }); + return new CompositeDisposable(subscription, cancelable); + }); + }; + + /** + * Skips elements for the specified duration from the end of the observable source sequence, using the specified scheduler to run timers. + * + * 1 - res = source.skipLastWithTime(5000); + * 2 - res = source.skipLastWithTime(5000, scheduler); + * + * @description + * This operator accumulates a queue with a length enough to store elements received during the initial duration window. + * As more elements are received, elements older than the specified duration are taken from the queue and produced on the + * result sequence. This causes elements to be delayed with duration. + * @param {Number} duration Duration for skipping elements from the end of the sequence. + * @param {Scheduler} [scheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout + * @returns {Observable} An observable sequence with the elements skipped during the specified duration from the end of the source sequence. + */ + observableProto.skipLastWithTime = function (duration, scheduler) { + scheduler || (scheduler = timeoutScheduler); + var source = this; + return new AnonymousObservable(function (observer) { + var q = []; + return source.subscribe(function (x) { + var now = scheduler.now(); + q.push({ interval: now, value: x }); + while (q.length > 0 && now - q[0].interval >= duration) { + observer.onNext(q.shift().value); + } + }, observer.onError.bind(observer), function () { + var now = scheduler.now(); + while (q.length > 0 && now - q[0].interval >= duration) { + observer.onNext(q.shift().value); + } + observer.onCompleted(); + }); + }); + }; + + /** + * Returns elements within the specified duration from the end of the observable source sequence, using the specified schedulers to run timers and to drain the collected elements. + * + * @example + * 1 - res = source.takeLastWithTime(5000, [optional timer scheduler], [optional loop scheduler]); + * @description + * This operator accumulates a queue with a length enough to store elements received during the initial duration window. + * As more elements are received, elements older than the specified duration are taken from the queue and produced on the + * result sequence. This causes elements to be delayed with duration. + * @param {Number} duration Duration for taking elements from the end of the sequence. + * @param {Scheduler} [timerScheduler] Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout. + * @param {Scheduler} [loopScheduler] Scheduler to drain the collected elements. If not specified, defaults to Rx.Scheduler.immediate. + * @returns {Observable} An observable sequence with the elements taken during the specified duration from the end of the source sequence. + */ + observableProto.takeLastWithTime = function (duration, timerScheduler, loopScheduler) { + return this.takeLastBufferWithTime(duration, timerScheduler).selectMany(function (xs) { return observableFromArray(xs, loopScheduler); }); + }; + + /** + * Returns an array with the elements within the specified duration from the end of the observable source sequence, using the specified scheduler to run timers. + * + * @example + * 1 - res = source.takeLastBufferWithTime(5000, [optional scheduler]); + * @description + * This operator accumulates a queue with a length enough to store elements received during the initial duration window. + * As more elements are received, elements older than the specified duration are taken from the queue and produced on the + * result sequence. This causes elements to be delayed with duration. + * @param {Number} duration Duration for taking elements from the end of the sequence. + * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout. + * @returns {Observable} An observable sequence containing a single array with the elements taken during the specified duration from the end of the source sequence. + */ + observableProto.takeLastBufferWithTime = function (duration, scheduler) { + var source = this; + scheduler || (scheduler = timeoutScheduler); + return new AnonymousObservable(function (observer) { + var q = []; + + return source.subscribe(function (x) { + var now = scheduler.now(); + q.push({ interval: now, value: x }); + while (q.length > 0 && now - q[0].interval >= duration) { + q.shift(); + } + }, observer.onError.bind(observer), function () { + var now = scheduler.now(), res = []; + while (q.length > 0) { + var next = q.shift(); + if (now - next.interval <= duration) { + res.push(next.value); + } + } + + observer.onNext(res); + observer.onCompleted(); + }); + }); + }; + + /** + * Takes elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers. + * + * @example + * 1 - res = source.takeWithTime(5000, [optional scheduler]); + * @description + * This operator accumulates a queue with a length enough to store elements received during the initial duration window. + * As more elements are received, elements older than the specified duration are taken from the queue and produced on the + * result sequence. This causes elements to be delayed with duration. + * @param {Number} duration Duration for taking elements from the start of the sequence. + * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout. + * @returns {Observable} An observable sequence with the elements taken during the specified duration from the start of the source sequence. + */ + observableProto.takeWithTime = function (duration, scheduler) { + var source = this; + scheduler || (scheduler = timeoutScheduler); + return new AnonymousObservable(function (observer) { + var t = scheduler.scheduleWithRelative(duration, function () { + observer.onCompleted(); + }); + + return new CompositeDisposable(t, source.subscribe(observer)); + }); + }; + + /** + * Skips elements for the specified duration from the start of the observable source sequence, using the specified scheduler to run timers. + * + * @example + * 1 - res = source.skipWithTime(5000, [optional scheduler]); + * + * @description + * Specifying a zero value for duration doesn't guarantee no elements will be dropped from the start of the source sequence. + * This is a side-effect of the asynchrony introduced by the scheduler, where the action that causes callbacks from the source sequence to be forwarded + * may not execute immediately, despite the zero due time. + * + * Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the duration. + * @param {Number} duration Duration for skipping elements from the start of the sequence. + * @param {Scheduler} scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout. + * @returns {Observable} An observable sequence with the elements skipped during the specified duration from the start of the source sequence. + */ + observableProto.skipWithTime = function (duration, scheduler) { + var source = this; + scheduler || (scheduler = timeoutScheduler); + return new AnonymousObservable(function (observer) { + var open = false, + t = scheduler.scheduleWithRelative(duration, function () { open = true; }), + d = source.subscribe(function (x) { + if (open) { + observer.onNext(x); + } + }, observer.onError.bind(observer), observer.onCompleted.bind(observer)); + + return new CompositeDisposable(t, d); + }); + }; + + /** + * Skips elements from the observable source sequence until the specified start time, using the specified scheduler to run timers. + * Errors produced by the source sequence are always forwarded to the result sequence, even if the error occurs before the start time. + * + * @examples + * 1 - res = source.skipUntilWithTime(new Date(), [optional scheduler]); + * 2 - res = source.skipUntilWithTime(5000, [optional scheduler]); + * @param startTime Time to start taking elements from the source sequence. If this value is less than or equal to Date(), no elements will be skipped. + * @param scheduler Scheduler to run the timer on. If not specified, defaults to Rx.Scheduler.timeout. + * @returns {Observable} An observable sequence with the elements skipped until the specified start time. + */ + observableProto.skipUntilWithTime = function (startTime, scheduler) { + scheduler || (scheduler = timeoutScheduler); + var source = this, schedulerMethod = startTime instanceof Date ? + 'scheduleWithAbsolute' : + 'scheduleWithRelative'; + return new AnonymousObservable(function (observer) { + var open = false; + + return new CompositeDisposable( + scheduler[schedulerMethod](startTime, function () { open = true; }), + source.subscribe( + function (x) { open && observer.onNext(x); }, + observer.onError.bind(observer), + observer.onCompleted.bind(observer))); + }); + }; + + /** + * Takes elements for the specified duration until the specified end time, using the specified scheduler to run timers. + * + * @example + * 1 - res = source.takeUntilWithTime(new Date(), [optional scheduler]); + * 2 - res = source.takeUntilWithTime(5000, [optional scheduler]); + * @param {Number | Date} endTime Time to stop taking elements from the source sequence. If this value is less than or equal to new Date(), the result stream will complete immediately. + * @param {Scheduler} scheduler Scheduler to run the timer on. + * @returns {Observable} An observable sequence with the elements taken until the specified end time. + */ + observableProto.takeUntilWithTime = function (endTime, scheduler) { + scheduler || (scheduler = timeoutScheduler); + var source = this, schedulerMethod = endTime instanceof Date ? + 'scheduleWithAbsolute' : + 'scheduleWithRelative'; + return new AnonymousObservable(function (observer) { + return new CompositeDisposable(scheduler[schedulerMethod](endTime, function () { + observer.onCompleted(); + }), source.subscribe(observer)); + }); + }; + + /* + * Performs a exclusive waiting for the first to finish before subscribing to another observable. + * Observables that come in between subscriptions will be dropped on the floor. + * @returns {Observable} A exclusive observable with only the results that happen when subscribed. + */ + observableProto.exclusive = function () { + var sources = this; + return new AnonymousObservable(function (observer) { + var hasCurrent = false, + isStopped = false, + m = new SingleAssignmentDisposable(), + g = new CompositeDisposable(); + + g.add(m); + + m.setDisposable(sources.subscribe( + function (innerSource) { + if (!hasCurrent) { + hasCurrent = true; + + isPromise(innerSource) && (innerSource = observableFromPromise(innerSource)); + + var innerSubscription = new SingleAssignmentDisposable(); + g.add(innerSubscription); + + innerSubscription.setDisposable(innerSource.subscribe( + observer.onNext.bind(observer), + observer.onError.bind(observer), + function () { + g.remove(innerSubscription); + hasCurrent = false; + if (isStopped && g.length === 1) { + observer.onCompleted(); + } + })); + } + }, + observer.onError.bind(observer), + function () { + isStopped = true; + if (!hasCurrent && g.length === 1) { + observer.onCompleted(); + } + })); + + return g; + }); + }; + /* + * Performs a exclusive map waiting for the first to finish before subscribing to another observable. + * Observables that come in between subscriptions will be dropped on the floor. + * @param {Function} selector Selector to invoke for every item in the current subscription. + * @param {Any} [thisArg] An optional context to invoke with the selector parameter. + * @returns {Observable} An exclusive observable with only the results that happen when subscribed. + */ + observableProto.exclusiveMap = function (selector, thisArg) { + var sources = this; + return new AnonymousObservable(function (observer) { + var index = 0, + hasCurrent = false, + isStopped = true, + m = new SingleAssignmentDisposable(), + g = new CompositeDisposable(); + + g.add(m); + + m.setDisposable(sources.subscribe( + function (innerSource) { + + if (!hasCurrent) { + hasCurrent = true; + + innerSubscription = new SingleAssignmentDisposable(); + g.add(innerSubscription); + + isPromise(innerSource) && (innerSource = observableFromPromise(innerSource)); + + innerSubscription.setDisposable(innerSource.subscribe( + function (x) { + var result; + try { + result = selector.call(thisArg, x, index++, innerSource); + } catch (e) { + observer.onError(e); + return; + } + + observer.onNext(result); + }, + observer.onError.bind(observer), + function () { + g.remove(innerSubscription); + hasCurrent = false; + + if (isStopped && g.length === 1) { + observer.onCompleted(); + } + })); + } + }, + observer.onError.bind(observer), + function () { + isStopped = true; + if (g.length === 1 && !hasCurrent) { + observer.onCompleted(); + } + })); + return g; + }); + }; + /** Provides a set of extension methods for virtual time scheduling. */ + Rx.VirtualTimeScheduler = (function (_super) { + + function notImplemented() { + throw new Error('Not implemented'); + } + + function localNow() { + return this.toDateTimeOffset(this.clock); + } + + function scheduleNow(state, action) { + return this.scheduleAbsoluteWithState(state, this.clock, action); + } + + function scheduleRelative(state, dueTime, action) { + return this.scheduleRelativeWithState(state, this.toRelative(dueTime), action); + } + + function scheduleAbsolute(state, dueTime, action) { + return this.scheduleRelativeWithState(state, this.toRelative(dueTime - this.now()), action); + } + + function invokeAction(scheduler, action) { + action(); + return disposableEmpty; + } + + inherits(VirtualTimeScheduler, _super); + + /** + * Creates a new virtual time scheduler with the specified initial clock value and absolute time comparer. + * + * @constructor + * @param {Number} initialClock Initial value for the clock. + * @param {Function} comparer Comparer to determine causality of events based on absolute time. + */ + function VirtualTimeScheduler(initialClock, comparer) { + this.clock = initialClock; + this.comparer = comparer; + this.isEnabled = false; + this.queue = new PriorityQueue(1024); + _super.call(this, localNow, scheduleNow, scheduleRelative, scheduleAbsolute); + } + + var VirtualTimeSchedulerPrototype = VirtualTimeScheduler.prototype; + + /** + * Adds a relative time value to an absolute time value. + * @param {Number} absolute Absolute virtual time value. + * @param {Number} relative Relative virtual time value to add. + * @return {Number} Resulting absolute virtual time sum value. + */ + VirtualTimeSchedulerPrototype.add = notImplemented; + + /** + * Converts an absolute time to a number + * @param {Any} The absolute time. + * @returns {Number} The absolute time in ms + */ + VirtualTimeSchedulerPrototype.toDateTimeOffset = notImplemented; + + /** + * Converts the TimeSpan value to a relative virtual time value. + * @param {Number} timeSpan TimeSpan value to convert. + * @return {Number} Corresponding relative virtual time value. + */ + VirtualTimeSchedulerPrototype.toRelative = notImplemented; + + /** + * Schedules a periodic piece of work by dynamically discovering the scheduler's capabilities. The periodic task will be emulated using recursive scheduling. + * @param {Mixed} state Initial state passed to the action upon the first iteration. + * @param {Number} period Period for running the work periodically. + * @param {Function} action Action to be executed, potentially updating the state. + * @returns {Disposable} The disposable object used to cancel the scheduled recurring action (best effort). + */ + VirtualTimeSchedulerPrototype.schedulePeriodicWithState = function (state, period, action) { + var s = new SchedulePeriodicRecursive(this, state, period, action); + return s.start(); + }; + + /** + * Schedules an action to be executed after dueTime. + * @param {Mixed} state State passed to the action to be executed. + * @param {Number} dueTime Relative time after which to execute the action. + * @param {Function} action Action to be executed. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + VirtualTimeSchedulerPrototype.scheduleRelativeWithState = function (state, dueTime, action) { + var runAt = this.add(this.clock, dueTime); + return this.scheduleAbsoluteWithState(state, runAt, action); + }; + + /** + * Schedules an action to be executed at dueTime. + * @param {Number} dueTime Relative time after which to execute the action. + * @param {Function} action Action to be executed. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + VirtualTimeSchedulerPrototype.scheduleRelative = function (dueTime, action) { + return this.scheduleRelativeWithState(action, dueTime, invokeAction); + }; + + /** + * Starts the virtual time scheduler. + */ + VirtualTimeSchedulerPrototype.start = function () { + var next; + if (!this.isEnabled) { + this.isEnabled = true; + do { + next = this.getNext(); + if (next !== null) { + if (this.comparer(next.dueTime, this.clock) > 0) { + this.clock = next.dueTime; + } + next.invoke(); + } else { + this.isEnabled = false; + } + } while (this.isEnabled); + } + }; + + /** + * Stops the virtual time scheduler. + */ + VirtualTimeSchedulerPrototype.stop = function () { + this.isEnabled = false; + }; + + /** + * Advances the scheduler's clock to the specified time, running all work till that point. + * @param {Number} time Absolute time to advance the scheduler's clock to. + */ + VirtualTimeSchedulerPrototype.advanceTo = function (time) { + var next; + var dueToClock = this.comparer(this.clock, time); + if (this.comparer(this.clock, time) > 0) { + throw new Error(argumentOutOfRange); + } + if (dueToClock === 0) { + return; + } + if (!this.isEnabled) { + this.isEnabled = true; + do { + next = this.getNext(); + if (next !== null && this.comparer(next.dueTime, time) <= 0) { + if (this.comparer(next.dueTime, this.clock) > 0) { + this.clock = next.dueTime; + } + next.invoke(); + } else { + this.isEnabled = false; + } + } while (this.isEnabled); + this.clock = time; + } + }; + + /** + * Advances the scheduler's clock by the specified relative time, running all work scheduled for that timespan. + * @param {Number} time Relative time to advance the scheduler's clock by. + */ + VirtualTimeSchedulerPrototype.advanceBy = function (time) { + var dt = this.add(this.clock, time); + var dueToClock = this.comparer(this.clock, dt); + if (dueToClock > 0) { + throw new Error(argumentOutOfRange); + } + if (dueToClock === 0) { + return; + } + this.advanceTo(dt); + }; + + /** + * Advances the scheduler's clock by the specified relative time. + * @param {Number} time Relative time to advance the scheduler's clock by. + */ + VirtualTimeSchedulerPrototype.sleep = function (time) { + var dt = this.add(this.clock, time); + + if (this.comparer(this.clock, dt) >= 0) { + throw new Error(argumentOutOfRange); + } + + this.clock = dt; + }; + + /** + * Gets the next scheduled item to be executed. + * @returns {ScheduledItem} The next scheduled item. + */ + VirtualTimeSchedulerPrototype.getNext = function () { + var next; + while (this.queue.length > 0) { + next = this.queue.peek(); + if (next.isCancelled()) { + this.queue.dequeue(); + } else { + return next; + } + } + return null; + }; + + /** + * Schedules an action to be executed at dueTime. + * @param {Scheduler} scheduler Scheduler to execute the action on. + * @param {Number} dueTime Absolute time at which to execute the action. + * @param {Function} action Action to be executed. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + VirtualTimeSchedulerPrototype.scheduleAbsolute = function (dueTime, action) { + return this.scheduleAbsoluteWithState(action, dueTime, invokeAction); + }; + + /** + * Schedules an action to be executed at dueTime. + * @param {Mixed} state State passed to the action to be executed. + * @param {Number} dueTime Absolute time at which to execute the action. + * @param {Function} action Action to be executed. + * @returns {Disposable} The disposable object used to cancel the scheduled action (best effort). + */ + VirtualTimeSchedulerPrototype.scheduleAbsoluteWithState = function (state, dueTime, action) { + var self = this, + run = function (scheduler, state1) { + self.queue.remove(si); + return action(scheduler, state1); + }, + si = new ScheduledItem(self, state, run, dueTime, self.comparer); + self.queue.enqueue(si); + return si.disposable; + }; + + return VirtualTimeScheduler; + }(Scheduler)); + + /** Provides a virtual time scheduler that uses Date for absolute time and number for relative time. */ + Rx.HistoricalScheduler = (function (_super) { + inherits(HistoricalScheduler, _super); + + /** + * Creates a new historical scheduler with the specified initial clock value. + * + * @constructor + * @param {Number} initialClock Initial value for the clock. + * @param {Function} comparer Comparer to determine causality of events based on absolute time. + */ + function HistoricalScheduler(initialClock, comparer) { + var clock = initialClock == null ? 0 : initialClock; + var cmp = comparer || defaultSubComparer; + _super.call(this, clock, cmp); + } + + var HistoricalSchedulerProto = HistoricalScheduler.prototype; + + /** + * Adds a relative time value to an absolute time value. + * @param {Number} absolute Absolute virtual time value. + * @param {Number} relative Relative virtual time value to add. + * @return {Number} Resulting absolute virtual time sum value. + */ + HistoricalSchedulerProto.add = function (absolute, relative) { + return absolute + relative; + }; + + /** + * @private + */ + HistoricalSchedulerProto.toDateTimeOffset = function (absolute) { + return new Date(absolute).getTime(); + }; + + /** + * Converts the TimeSpan value to a relative virtual time value. + * + * @memberOf HistoricalScheduler + * @param {Number} timeSpan TimeSpan value to convert. + * @return {Number} Corresponding relative virtual time value. + */ + HistoricalSchedulerProto.toRelative = function (timeSpan) { + return timeSpan; + }; + + return HistoricalScheduler; + }(Rx.VirtualTimeScheduler)); + var AnonymousObservable = Rx.AnonymousObservable = (function (__super__) { + inherits(AnonymousObservable, __super__); + + // Fix subscriber to check for undefined or function returned to decorate as Disposable + function fixSubscriber(subscriber) { + if (typeof subscriber === 'undefined') { + subscriber = disposableEmpty; + } else if (typeof subscriber === 'function') { + subscriber = disposableCreate(subscriber); + } + + return subscriber; + } + + function AnonymousObservable(subscribe) { + if (!(this instanceof AnonymousObservable)) { + return new AnonymousObservable(subscribe); + } + + function s(observer) { + var setDisposable = function () { + try { + autoDetachObserver.setDisposable(fixSubscriber(subscribe(autoDetachObserver))); + } catch (e) { + if (!autoDetachObserver.fail(e)) { + throw e; + } + } + }; + + var autoDetachObserver = new AutoDetachObserver(observer); + if (currentThreadScheduler.scheduleRequired()) { + currentThreadScheduler.schedule(setDisposable); + } else { + setDisposable(); + } + + return autoDetachObserver; + } + + __super__.call(this, s); + } + + return AnonymousObservable; + + }(Observable)); + + /** @private */ + var AutoDetachObserver = (function (_super) { + inherits(AutoDetachObserver, _super); + + function AutoDetachObserver(observer) { + _super.call(this); + this.observer = observer; + this.m = new SingleAssignmentDisposable(); + } + + var AutoDetachObserverPrototype = AutoDetachObserver.prototype; + + AutoDetachObserverPrototype.next = function (value) { + var noError = false; + try { + this.observer.onNext(value); + noError = true; + } catch (e) { + throw e; + } finally { + if (!noError) { + this.dispose(); + } + } + }; + + AutoDetachObserverPrototype.error = function (exn) { + try { + this.observer.onError(exn); + } catch (e) { + throw e; + } finally { + this.dispose(); + } + }; + + AutoDetachObserverPrototype.completed = function () { + try { + this.observer.onCompleted(); + } catch (e) { + throw e; + } finally { + this.dispose(); + } + }; + + AutoDetachObserverPrototype.setDisposable = function (value) { this.m.setDisposable(value); }; + AutoDetachObserverPrototype.getDisposable = function (value) { return this.m.getDisposable(); }; + /* @private */ + AutoDetachObserverPrototype.disposable = function (value) { + return arguments.length ? this.getDisposable() : setDisposable(value); + }; + + AutoDetachObserverPrototype.dispose = function () { + _super.prototype.dispose.call(this); + this.m.dispose(); + }; + + return AutoDetachObserver; + }(AbstractObserver)); + + /** @private */ + var GroupedObservable = (function (_super) { + inherits(GroupedObservable, _super); + + function subscribe(observer) { + return this.underlyingObservable.subscribe(observer); + } + + /** + * @constructor + * @private + */ + function GroupedObservable(key, underlyingObservable, mergedDisposable) { + _super.call(this, subscribe); + this.key = key; + this.underlyingObservable = !mergedDisposable ? + underlyingObservable : + new AnonymousObservable(function (observer) { + return new CompositeDisposable(mergedDisposable.getDisposable(), underlyingObservable.subscribe(observer)); + }); + } + + return GroupedObservable; + }(Observable)); + + /** + * Represents an object that is both an observable sequence as well as an observer. + * Each notification is broadcasted to all subscribed observers. + */ + var Subject = Rx.Subject = (function (_super) { + function subscribe(observer) { + checkDisposed.call(this); + if (!this.isStopped) { + this.observers.push(observer); + return new InnerSubscription(this, observer); + } + if (this.exception) { + observer.onError(this.exception); + return disposableEmpty; + } + observer.onCompleted(); + return disposableEmpty; + } + + inherits(Subject, _super); + + /** + * Creates a subject. + * @constructor + */ + function Subject() { + _super.call(this, subscribe); + this.isDisposed = false, + this.isStopped = false, + this.observers = []; + } + + addProperties(Subject.prototype, Observer, { + /** + * Indicates whether the subject has observers subscribed to it. + * @returns {Boolean} Indicates whether the subject has observers subscribed to it. + */ + hasObservers: function () { + return this.observers.length > 0; + }, + /** + * Notifies all subscribed observers about the end of the sequence. + */ + onCompleted: function () { + checkDisposed.call(this); + if (!this.isStopped) { + var os = this.observers.slice(0); + this.isStopped = true; + for (var i = 0, len = os.length; i < len; i++) { + os[i].onCompleted(); + } + + this.observers = []; + } + }, + /** + * Notifies all subscribed observers about the exception. + * @param {Mixed} error The exception to send to all observers. + */ + onError: function (exception) { + checkDisposed.call(this); + if (!this.isStopped) { + var os = this.observers.slice(0); + this.isStopped = true; + this.exception = exception; + for (var i = 0, len = os.length; i < len; i++) { + os[i].onError(exception); + } + + this.observers = []; + } + }, + /** + * Notifies all subscribed observers about the arrival of the specified element in the sequence. + * @param {Mixed} value The value to send to all observers. + */ + onNext: function (value) { + checkDisposed.call(this); + if (!this.isStopped) { + var os = this.observers.slice(0); + for (var i = 0, len = os.length; i < len; i++) { + os[i].onNext(value); + } + } + }, + /** + * Unsubscribe all observers and release resources. + */ + dispose: function () { + this.isDisposed = true; + this.observers = null; + } + }); + + /** + * Creates a subject from the specified observer and observable. + * @param {Observer} observer The observer used to send messages to the subject. + * @param {Observable} observable The observable used to subscribe to messages sent from the subject. + * @returns {Subject} Subject implemented using the given observer and observable. + */ + Subject.create = function (observer, observable) { + return new AnonymousSubject(observer, observable); + }; + + return Subject; + }(Observable)); + + /** + * Represents the result of an asynchronous operation. + * The last value before the OnCompleted notification, or the error received through OnError, is sent to all subscribed observers. + */ + var AsyncSubject = Rx.AsyncSubject = (function (_super) { + + function subscribe(observer) { + checkDisposed.call(this); + + if (!this.isStopped) { + this.observers.push(observer); + return new InnerSubscription(this, observer); + } + + var ex = this.exception, + hv = this.hasValue, + v = this.value; + + if (ex) { + observer.onError(ex); + } else if (hv) { + observer.onNext(v); + observer.onCompleted(); + } else { + observer.onCompleted(); + } + + return disposableEmpty; + } + + inherits(AsyncSubject, _super); + + /** + * Creates a subject that can only receive one value and that value is cached for all future observations. + * @constructor + */ + function AsyncSubject() { + _super.call(this, subscribe); + + this.isDisposed = false; + this.isStopped = false; + this.value = null; + this.hasValue = false; + this.observers = []; + this.exception = null; + } + + addProperties(AsyncSubject.prototype, Observer, { + /** + * Indicates whether the subject has observers subscribed to it. + * @returns {Boolean} Indicates whether the subject has observers subscribed to it. + */ + hasObservers: function () { + checkDisposed.call(this); + return this.observers.length > 0; + }, + /** + * Notifies all subscribed observers about the end of the sequence, also causing the last received value to be sent out (if any). + */ + onCompleted: function () { + var o, i, len; + checkDisposed.call(this); + if (!this.isStopped) { + this.isStopped = true; + var os = this.observers.slice(0), + v = this.value, + hv = this.hasValue; + + if (hv) { + for (i = 0, len = os.length; i < len; i++) { + o = os[i]; + o.onNext(v); + o.onCompleted(); + } + } else { + for (i = 0, len = os.length; i < len; i++) { + os[i].onCompleted(); + } + } + + this.observers = []; + } + }, + /** + * Notifies all subscribed observers about the exception. + * @param {Mixed} error The exception to send to all observers. + */ + onError: function (exception) { + checkDisposed.call(this); + if (!this.isStopped) { + var os = this.observers.slice(0); + this.isStopped = true; + this.exception = exception; + + for (var i = 0, len = os.length; i < len; i++) { + os[i].onError(exception); + } + + this.observers = []; + } + }, + /** + * Sends a value to the subject. The last value received before successful termination will be sent to all subscribed and future observers. + * @param {Mixed} value The value to store in the subject. + */ + onNext: function (value) { + checkDisposed.call(this); + if (!this.isStopped) { + this.value = value; + this.hasValue = true; + } + }, + /** + * Unsubscribe all observers and release resources. + */ + dispose: function () { + this.isDisposed = true; + this.observers = null; + this.exception = null; + this.value = null; + } + }); + + return AsyncSubject; + }(Observable)); + + /** @private */ + var AnonymousSubject = (function (_super) { + inherits(AnonymousSubject, _super); + + function subscribe(observer) { + return this.observable.subscribe(observer); + } + + /** + * @private + * @constructor + */ + function AnonymousSubject(observer, observable) { + _super.call(this, subscribe); + this.observer = observer; + this.observable = observable; + } + + addProperties(AnonymousSubject.prototype, Observer, { + /** + * @private + * @memberOf AnonymousSubject# + */ + onCompleted: function () { + this.observer.onCompleted(); + }, + /** + * @private + * @memberOf AnonymousSubject# + */ + onError: function (exception) { + this.observer.onError(exception); + }, + /** + * @private + * @memberOf AnonymousSubject# + */ + onNext: function (value) { + this.observer.onNext(value); + } + }); + + return AnonymousSubject; + }(Observable)); + + if (typeof define == 'function' && typeof define.amd == 'object' && define.amd) { + root.Rx = Rx; + + define(function() { + return Rx; + }); + } else if (freeExports && freeModule) { + // in Node.js or RingoJS + if (moduleExports) { + (freeModule.exports = Rx).Rx = Rx; + } else { + freeExports.Rx = Rx; + } + } else { + // in a browser or Rhino + root.Rx = Rx; + } +}.call(this)); +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rx/dist/rx.all.js","/../../node_modules/rx/dist") +},{"buffer":3,"oMfpAn":7}],18:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. + +;(function (factory) { + var objectTypes = { + 'boolean': false, + 'function': true, + 'object': true, + 'number': false, + 'string': false, + 'undefined': false + }; + + var root = (objectTypes[typeof window] && window) || this, + freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports, + freeModule = objectTypes[typeof module] && module && !module.nodeType && module, + moduleExports = freeModule && freeModule.exports === freeExports && freeExports, + freeGlobal = objectTypes[typeof global] && global; + + if (freeGlobal && (freeGlobal.global === freeGlobal || freeGlobal.window === freeGlobal)) { + root = freeGlobal; + } + + // Because of build optimizers + if (typeof define === 'function' && define.amd) { + define(['rx.virtualtime', 'exports'], function (Rx, exports) { + root.Rx = factory(root, exports, Rx); + return root.Rx; + }); + } else if (typeof module === 'object' && module && module.exports === freeExports) { + module.exports = factory(root, module.exports, require('./rx.all')); + } else { + root.Rx = factory(root, {}, root.Rx); + } +}.call(this, function (root, exp, Rx, undefined) { + + // Defaults + var Observer = Rx.Observer, + Observable = Rx.Observable, + Notification = Rx.Notification, + VirtualTimeScheduler = Rx.VirtualTimeScheduler, + Disposable = Rx.Disposable, + disposableEmpty = Disposable.empty, + disposableCreate = Disposable.create, + CompositeDisposable = Rx.CompositeDisposable, + SingleAssignmentDisposable = Rx.SingleAssignmentDisposable, + slice = Array.prototype.slice, + inherits = Rx.internals.inherits, + defaultComparer = Rx.internals.isEqual; + + function argsOrArray(args, idx) { + return args.length === 1 && Array.isArray(args[idx]) ? + args[idx] : + slice.call(args); + } + + /** + * @private + * @constructor + */ + function OnNextPredicate(predicate) { + this.predicate = predicate; + }; + + /** + * @private + * @memberOf OnNextPredicate# + */ + OnNextPredicate.prototype.equals = function (other) { + if (other === this) { return true; } + if (other == null) { return false; } + if (other.kind !== 'N') { return false; } + return this.predicate(other.value); + }; + + /** + * @private + * @constructor + */ + function OnErrorPredicate(predicate) { + this.predicate = predicate; + }; + + /** + * @private + * @memberOf OnErrorPredicate# + */ + OnErrorPredicate.prototype.equals = function (other) { + if (other === this) { return true; } + if (other == null) { return false; } + if (other.kind !== 'E') { return false; } + return this.predicate(other.exception); + }; + + /** + * @static + * type Object + */ + var ReactiveTest = Rx.ReactiveTest = { + /** Default virtual time used for creation of observable sequences in unit tests. */ + created: 100, + /** Default virtual time used to subscribe to observable sequences in unit tests. */ + subscribed: 200, + /** Default virtual time used to dispose subscriptions in unit tests. */ + disposed: 1000, + + /** + * Factory method for an OnNext notification record at a given time with a given value or a predicate function. + * + * 1 - ReactiveTest.onNext(200, 42); + * 2 - ReactiveTest.onNext(200, function (x) { return x.length == 2; }); + * + * @param ticks Recorded virtual time the OnNext notification occurs. + * @param value Recorded value stored in the OnNext notification or a predicate. + * @return Recorded OnNext notification. + */ + onNext: function (ticks, value) { + if (typeof value === 'function') { + return new Recorded(ticks, new OnNextPredicate(value)); + } + return new Recorded(ticks, Notification.createOnNext(value)); + }, + /** + * Factory method for an OnError notification record at a given time with a given error. + * + * 1 - ReactiveTest.onNext(200, new Error('error')); + * 2 - ReactiveTest.onNext(200, function (e) { return e.message === 'error'; }); + * + * @param ticks Recorded virtual time the OnError notification occurs. + * @param exception Recorded exception stored in the OnError notification. + * @return Recorded OnError notification. + */ + onError: function (ticks, exception) { + if (typeof exception === 'function') { + return new Recorded(ticks, new OnErrorPredicate(exception)); + } + return new Recorded(ticks, Notification.createOnError(exception)); + }, + /** + * Factory method for an OnCompleted notification record at a given time. + * + * @param ticks Recorded virtual time the OnCompleted notification occurs. + * @return Recorded OnCompleted notification. + */ + onCompleted: function (ticks) { + return new Recorded(ticks, Notification.createOnCompleted()); + }, + /** + * Factory method for a subscription record based on a given subscription and disposal time. + * + * @param start Virtual time indicating when the subscription was created. + * @param end Virtual time indicating when the subscription was disposed. + * @return Subscription object. + */ + subscribe: function (start, end) { + return new Subscription(start, end); + } + }; + + /** + * Creates a new object recording the production of the specified value at the given virtual time. + * + * @constructor + * @param {Number} time Virtual time the value was produced on. + * @param {Mixed} value Value that was produced. + * @param {Function} comparer An optional comparer. + */ + var Recorded = Rx.Recorded = function (time, value, comparer) { + this.time = time; + this.value = value; + this.comparer = comparer || defaultComparer; + }; + + /** + * Checks whether the given recorded object is equal to the current instance. + * + * @param {Recorded} other Recorded object to check for equality. + * @returns {Boolean} true if both objects are equal; false otherwise. + */ + Recorded.prototype.equals = function (other) { + return this.time === other.time && this.comparer(this.value, other.value); + }; + + /** + * Returns a string representation of the current Recorded value. + * + * @returns {String} String representation of the current Recorded value. + */ + Recorded.prototype.toString = function () { + return this.value.toString() + '@' + this.time; + }; + + /** + * Creates a new subscription object with the given virtual subscription and unsubscription time. + * + * @constructor + * @param {Number} subscribe Virtual time at which the subscription occurred. + * @param {Number} unsubscribe Virtual time at which the unsubscription occurred. + */ + var Subscription = Rx.Subscription = function (start, end) { + this.subscribe = start; + this.unsubscribe = end || Number.MAX_VALUE; + }; + + /** + * Checks whether the given subscription is equal to the current instance. + * @param other Subscription object to check for equality. + * @returns {Boolean} true if both objects are equal; false otherwise. + */ + Subscription.prototype.equals = function (other) { + return this.subscribe === other.subscribe && this.unsubscribe === other.unsubscribe; + }; + + /** + * Returns a string representation of the current Subscription value. + * @returns {String} String representation of the current Subscription value. + */ + Subscription.prototype.toString = function () { + return '(' + this.subscribe + ', ' + this.unsubscribe === Number.MAX_VALUE ? 'Infinite' : this.unsubscribe + ')'; + }; + + /** @private */ + var MockDisposable = Rx.MockDisposable = function (scheduler) { + this.scheduler = scheduler; + this.disposes = []; + this.disposes.push(this.scheduler.clock); + }; + + /* + * @memberOf MockDisposable# + * @prviate + */ + MockDisposable.prototype.dispose = function () { + this.disposes.push(this.scheduler.clock); + }; + + /** @private */ + var MockObserver = (function (_super) { + inherits(MockObserver, _super); + + /* + * @constructor + * @prviate + */ + function MockObserver(scheduler) { + _super.call(this); + this.scheduler = scheduler; + this.messages = []; + } + + var MockObserverPrototype = MockObserver.prototype; + + /* + * @memberOf MockObserverPrototype# + * @prviate + */ + MockObserverPrototype.onNext = function (value) { + this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnNext(value))); + }; + + /* + * @memberOf MockObserverPrototype# + * @prviate + */ + MockObserverPrototype.onError = function (exception) { + this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnError(exception))); + }; + + /* + * @memberOf MockObserverPrototype# + * @prviate + */ + MockObserverPrototype.onCompleted = function () { + this.messages.push(new Recorded(this.scheduler.clock, Notification.createOnCompleted())); + }; + + return MockObserver; + })(Observer); + + /** @private */ + var HotObservable = (function (_super) { + + function subscribe(observer) { + var observable = this; + this.observers.push(observer); + this.subscriptions.push(new Subscription(this.scheduler.clock)); + var index = this.subscriptions.length - 1; + return disposableCreate(function () { + var idx = observable.observers.indexOf(observer); + observable.observers.splice(idx, 1); + observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock); + }); + } + + inherits(HotObservable, _super); + + /** + * @private + * @constructor + */ + function HotObservable(scheduler, messages) { + _super.call(this, subscribe); + var message, notification, observable = this; + this.scheduler = scheduler; + this.messages = messages; + this.subscriptions = []; + this.observers = []; + for (var i = 0, len = this.messages.length; i < len; i++) { + message = this.messages[i]; + notification = message.value; + (function (innerNotification) { + scheduler.scheduleAbsoluteWithState(null, message.time, function () { + var obs = observable.observers.slice(0); + + for (var j = 0, jLen = obs.length; j < jLen; j++) { + innerNotification.accept(obs[j]); + } + return disposableEmpty; + }); + })(notification); + } + } + + return HotObservable; + })(Observable); + + /** @private */ + var ColdObservable = (function (_super) { + + function subscribe(observer) { + var message, notification, observable = this; + this.subscriptions.push(new Subscription(this.scheduler.clock)); + var index = this.subscriptions.length - 1; + var d = new CompositeDisposable(); + for (var i = 0, len = this.messages.length; i < len; i++) { + message = this.messages[i]; + notification = message.value; + (function (innerNotification) { + d.add(observable.scheduler.scheduleRelativeWithState(null, message.time, function () { + innerNotification.accept(observer); + return disposableEmpty; + })); + })(notification); + } + return disposableCreate(function () { + observable.subscriptions[index] = new Subscription(observable.subscriptions[index].subscribe, observable.scheduler.clock); + d.dispose(); + }); + } + + inherits(ColdObservable, _super); + + /** + * @private + * @constructor + */ + function ColdObservable(scheduler, messages) { + _super.call(this, subscribe); + this.scheduler = scheduler; + this.messages = messages; + this.subscriptions = []; + } + + return ColdObservable; + })(Observable); + + /** Virtual time scheduler used for testing applications and libraries built using Reactive Extensions. */ + Rx.TestScheduler = (function (_super) { + inherits(TestScheduler, _super); + + function baseComparer(x, y) { + return x > y ? 1 : (x < y ? -1 : 0); + } + + /** @constructor */ + function TestScheduler() { + _super.call(this, 0, baseComparer); + } + + /** + * Schedules an action to be executed at the specified virtual time. + * + * @param state State passed to the action to be executed. + * @param dueTime Absolute virtual time at which to execute the action. + * @param action Action to be executed. + * @return Disposable object used to cancel the scheduled action (best effort). + */ + TestScheduler.prototype.scheduleAbsoluteWithState = function (state, dueTime, action) { + if (dueTime <= this.clock) { + dueTime = this.clock + 1; + } + return _super.prototype.scheduleAbsoluteWithState.call(this, state, dueTime, action); + }; + /** + * Adds a relative virtual time to an absolute virtual time value. + * + * @param absolute Absolute virtual time value. + * @param relative Relative virtual time value to add. + * @return Resulting absolute virtual time sum value. + */ + TestScheduler.prototype.add = function (absolute, relative) { + return absolute + relative; + }; + /** + * Converts the absolute virtual time value to a DateTimeOffset value. + * + * @param absolute Absolute virtual time value to convert. + * @return Corresponding DateTimeOffset value. + */ + TestScheduler.prototype.toDateTimeOffset = function (absolute) { + return new Date(absolute).getTime(); + }; + /** + * Converts the TimeSpan value to a relative virtual time value. + * + * @param timeSpan TimeSpan value to convert. + * @return Corresponding relative virtual time value. + */ + TestScheduler.prototype.toRelative = function (timeSpan) { + return timeSpan; + }; + /** + * Starts the test scheduler and uses the specified virtual times to invoke the factory function, subscribe to the resulting sequence, and dispose the subscription. + * + * @param create Factory method to create an observable sequence. + * @param created Virtual time at which to invoke the factory to create an observable sequence. + * @param subscribed Virtual time at which to subscribe to the created observable sequence. + * @param disposed Virtual time at which to dispose the subscription. + * @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active. + */ + TestScheduler.prototype.startWithTiming = function (create, created, subscribed, disposed) { + var observer = this.createObserver(), source, subscription; + this.scheduleAbsoluteWithState(null, created, function () { + source = create(); + return disposableEmpty; + }); + this.scheduleAbsoluteWithState(null, subscribed, function () { + subscription = source.subscribe(observer); + return disposableEmpty; + }); + this.scheduleAbsoluteWithState(null, disposed, function () { + subscription.dispose(); + return disposableEmpty; + }); + this.start(); + return observer; + }; + /** + * Starts the test scheduler and uses the specified virtual time to dispose the subscription to the sequence obtained through the factory function. + * Default virtual times are used for factory invocation and sequence subscription. + * + * @param create Factory method to create an observable sequence. + * @param disposed Virtual time at which to dispose the subscription. + * @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active. + */ + TestScheduler.prototype.startWithDispose = function (create, disposed) { + return this.startWithTiming(create, ReactiveTest.created, ReactiveTest.subscribed, disposed); + }; + /** + * Starts the test scheduler and uses default virtual times to invoke the factory function, to subscribe to the resulting sequence, and to dispose the subscription. + * + * @param create Factory method to create an observable sequence. + * @return Observer with timestamped recordings of notification messages that were received during the virtual time window when the subscription to the source sequence was active. + */ + TestScheduler.prototype.startWithCreate = function (create) { + return this.startWithTiming(create, ReactiveTest.created, ReactiveTest.subscribed, ReactiveTest.disposed); + }; + /** + * Creates a hot observable using the specified timestamped notification messages either as an array or arguments. + * + * @param messages Notifications to surface through the created sequence at their specified absolute virtual times. + * @return Hot observable sequence that can be used to assert the timing of subscriptions and notifications. + */ + TestScheduler.prototype.createHotObservable = function () { + var messages = argsOrArray(arguments, 0); + return new HotObservable(this, messages); + }; + /** + * Creates a cold observable using the specified timestamped notification messages either as an array or arguments. + * + * @param messages Notifications to surface through the created sequence at their specified virtual time offsets from the sequence subscription time. + * @return Cold observable sequence that can be used to assert the timing of subscriptions and notifications. + */ + TestScheduler.prototype.createColdObservable = function () { + var messages = argsOrArray(arguments, 0); + return new ColdObservable(this, messages); + }; + /** + * Creates an observer that records received notification messages and timestamps those. + * + * @return Observer that can be used to assert the timing of received notifications. + */ + TestScheduler.prototype.createObserver = function () { + return new MockObserver(this); + }; + + return TestScheduler; + })(VirtualTimeScheduler); + + return Rx; +})); +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rx/dist/rx.testing.js","/../../node_modules/rx/dist") +},{"./rx.all":17,"buffer":3,"oMfpAn":7}],19:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Rx = require('./dist/rx.all'); +require('./dist/rx.testing'); + +// Add specific Node functions +var EventEmitter = require('events').EventEmitter, + Observable = Rx.Observable; + +Rx.Node = { + /** + * @deprecated Use Rx.Observable.fromCallback from rx.async.js instead. + * + * Converts a callback function to an observable sequence. + * + * @param {Function} func Function to convert to an asynchronous function. + * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. + * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined. + * @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next. + * @returns {Function} Asynchronous function. + */ + fromCallback: function (func, scheduler, context, selector) { + return Observable.fromCallback(func, scheduler, context, selector); + }, + + /** + * @deprecated Use Rx.Observable.fromNodeCallback from rx.async.js instead. + * + * Converts a Node.js callback style function to an observable sequence. This must be in function (err, ...) format. + * + * @param {Function} func The function to call + * @param {Scheduler} [scheduler] Scheduler to run the function on. If not specified, defaults to Scheduler.timeout. + * @param {Mixed} [context] The context for the func parameter to be executed. If not specified, defaults to undefined. + * @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next. + * @returns {Function} An async function which when applied, returns an observable sequence with the callback arguments as an array. + */ + fromNodeCallback: function (func, scheduler, context, selector) { + return Observable.fromNodeCallback(func, scheduler, context, selector); + }, + + /** + * @deprecated Use Rx.Observable.fromNodeCallback from rx.async.js instead. + * + * Handles an event from the given EventEmitter as an observable sequence. + * + * @param {EventEmitter} eventEmitter The EventEmitter to subscribe to the given event. + * @param {String} eventName The event name to subscribe + * @param {Function} [selector] A selector which takes the arguments from the event handler to produce a single item to yield on next. + * @returns {Observable} An observable sequence generated from the named event from the given EventEmitter. The data will be returned as an array of arguments to the handler. + */ + fromEvent: function (eventEmitter, eventName, selector) { + return Observable.fromEvent(eventEmitter, eventName, selector); + }, + + /** + * Converts the given observable sequence to an event emitter with the given event name. + * The errors are handled on the 'error' event and completion on the 'end' event. + * @param {Observable} observable The observable sequence to convert to an EventEmitter. + * @param {String} eventName The event name to emit onNext calls. + * @returns {EventEmitter} An EventEmitter which emits the given eventName for each onNext call in addition to 'error' and 'end' events. + * You must call publish in order to invoke the subscription on the Observable sequuence. + */ + toEventEmitter: function (observable, eventName, selector) { + var e = new EventEmitter(); + selector || (selector = function (x) { return x; }); + + // Used to publish the events from the observable + e.publish = function () { + e.subscription = observable.subscribe( + function (x) { + e.emit(eventName, selector(x)); + }, + function (err) { + e.emit('error', err); + }, + function () { + e.emit('end'); + }); + }; + + return e; + }, + + /** + * Converts a flowing stream to an Observable sequence. + * @param {Stream} stream A stream to convert to a observable sequence. + * @returns {Observable} An observable sequence which fires on each 'data' event as well as handling 'error' and 'end' events. + */ + fromStream: function (stream) { + return Observable.create(function (observer) { + function dataHandler (data) { + observer.onNext(data); + } + + function errorHandler (err) { + observer.onError(err); + } + + function endHandler () { + observer.onCompleted(); + } + + stream.addListener('data', dataHandler); + stream.addListener('error', errorHandler); + stream.addListener('end', endHandler); + + return function () { + stream.removeListener('data', dataHandler); + stream.removeListener('error', errorHandler); + stream.removeListener('end', endHandler); + }; + }).publish().refCount(); + }, + + /** + * Writes an observable sequence to a stream + * @param {Observable} observable Observable sequence to write to a stream. + * @param {Stream} stream The stream to write to. + * @param {String} [encoding] The encoding of the item to write. + * @returns {Disposable} The subscription handle. + */ + writeToStream: function (observable, stream, encoding) { + return observable.subscribe( + function (x) { + stream.write(String(x), encoding); + }, + function (err) { + stream.emit('error', err); + }, function () { + // Hack check because STDIO is not closable + !stream._isStdio && stream.end(); + }); + } +}; + +module.exports = Rx; +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rx/rx.node.js","/../../node_modules/rx") +},{"./dist/rx.all":17,"./dist/rx.testing":18,"buffer":3,"events":6,"oMfpAn":7}],20:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Examples, Rx, Sandbox, SelectedExample, Utils, arrayOfInitialInputDiagrams$, continuous$; + +Rx = require('rx'); + +Examples = require('rxmarbles/models/examples'); + +SelectedExample = require('rxmarbles/controllers/selected-example'); + +Utils = require('rxmarbles/controllers/utils'); + +Sandbox = require('rxmarbles/views/sandbox'); + +arrayOfInitialInputDiagrams$ = new Rx.BehaviorSubject(null); + +SelectedExample.stream.map(function(example) { + return example["inputs"].map(Utils.prepareInputDiagram); +}).subscribe(function(x) { + arrayOfInitialInputDiagrams$.onNext(x); + return true; +}); + +continuous$ = Sandbox.getStreamOfArrayOfLiveInputDiagramStreams(); + +module.exports = { + initial$: arrayOfInitialInputDiagrams$, + continuous$: continuous$ +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/controllers/input-diagrams.js","/../../node_modules/rxmarbles/controllers") +},{"buffer":3,"oMfpAn":7,"rx":19,"rxmarbles/controllers/selected-example":22,"rxmarbles/controllers/utils":23,"rxmarbles/models/examples":27,"rxmarbles/views/sandbox":36}],21:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var END, Examples, InputDiagrams, Rx, SelectedExample, Utils, outputDiagramStream, + __slice = [].slice; + +Rx = require('rx'); + +Utils = require('rxmarbles/controllers/utils'); + +InputDiagrams = require('rxmarbles/controllers/input-diagrams'); + +SelectedExample = require('rxmarbles/controllers/selected-example'); + +Examples = require('rxmarbles/models/examples'); + +END = 100; + +outputDiagramStream = InputDiagrams.continuous$.filter(function(x) { + return x !== null; +}).flatMapLatest(function(arrayOfDiagramStreams) { + return Rx.Observable.combineLatest(arrayOfDiagramStreams, function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return args; + }); +}).combineLatest(SelectedExample.stream, function(diagrams, example) { + var d, endTime, inputVTStreams, outputDiagram, outputVTStream, vtscheduler; + endTime = END + 1; + vtscheduler = Utils.makeScheduler(); + inputVTStreams = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = diagrams.length; _i < _len; _i++) { + d = diagrams[_i]; + _results.push(Utils.toVTStream(d, vtscheduler, endTime)); + } + return _results; + })(); + outputVTStream = example["apply"](inputVTStreams, vtscheduler); + outputVTStream = outputVTStream.takeUntilWithTime(endTime, vtscheduler); + outputDiagram = Utils.getDiagramPromise(outputVTStream, vtscheduler, endTime); + vtscheduler.start(); + return outputDiagram; +}).mergeAll(); + +module.exports = outputDiagramStream; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/controllers/output-diagram.js","/../../node_modules/rxmarbles/controllers") +},{"buffer":3,"oMfpAn":7,"rx":19,"rxmarbles/controllers/input-diagrams":20,"rxmarbles/controllers/selected-example":22,"rxmarbles/controllers/utils":23,"rxmarbles/models/examples":27}],22:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Examples, OperatorsMenu, Rx, selectedExample$, selectedExampleKey$, urlHash; + +Rx = require('rx'); + +Examples = require('rxmarbles/models/examples'); + +OperatorsMenu = require('rxmarbles/views/operators-menu'); + +urlHash = window.location.hash.replace("#", "") || "merge"; + +selectedExampleKey$ = OperatorsMenu.getSelected$().startWith(urlHash); + +selectedExample$ = selectedExampleKey$.map(function(key) { + var example; + example = Examples[key]; + example.key = key; + return example; +}); + +module.exports = { + stream: selectedExample$ +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/controllers/selected-example.js","/../../node_modules/rxmarbles/controllers") +},{"buffer":3,"oMfpAn":7,"rx":19,"rxmarbles/models/examples":27,"rxmarbles/views/operators-menu":34}],23:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Rx, calculateMarbleContentHash, calculateMarbleDataHash, getDiagramPromise, makeScheduler, prepareInputDiagram, prepareInputDiagramItem, prepareInputDiagramStream, toVTStream; + +Rx = require('rx'); + +makeScheduler = function() { + var scheduler; + scheduler = new Rx.VirtualTimeScheduler(0, function(x, y) { + if (x > y) { + return 1; + } + if (x < y) { + return -1; + } + return 0; + }); + scheduler.add = function(absolute, relative) { + return absolute + relative; + }; + scheduler.toDateTimeOffset = function(absolute) { + return Math.floor(absolute); + }; + scheduler.toRelative = function(timeSpan) { + return timeSpan; + }; + return scheduler; +}; + +calculateMarbleContentHash = function(content) { + var SOME_PRIME_NUMBER, contentHash; + SOME_PRIME_NUMBER = 877; + contentHash = 0; + if (typeof content === "string") { + contentHash = content.split("").map(function(x) { + return x.charCodeAt(0); + }).reduce(function(x, y) { + return x + y; + }); + } else if (typeof content === "number") { + contentHash = content * SOME_PRIME_NUMBER; + } + return contentHash; +}; + +calculateMarbleDataHash = function(marbleData) { + var LARGE_PRIME, MAX, SMALL_PRIME, contentHash; + SMALL_PRIME = 7; + LARGE_PRIME = 1046527; + MAX = 100000; + contentHash = calculateMarbleContentHash(marbleData.content); + return ((marbleData.time + contentHash + SMALL_PRIME) * LARGE_PRIME) % MAX; +}; + +prepareInputDiagramItem = function(item) { + var result; + result = {}; + result.time = typeof item.time === "undefined" ? item.t : item.time; + result.content = typeof item.content === "undefined" ? item.d : item.content; + result.id = item.id != null ? item.id : calculateMarbleDataHash(result); + return result; +}; + +prepareInputDiagram = function(diagram) { + var i; + return (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = diagram.length; _i < _len; _i++) { + i = diagram[_i]; + _results.push(prepareInputDiagramItem(i)); + } + return _results; + })(); +}; + +prepareInputDiagramStream = function(diagramStream) { + return diagramStream.map(prepareInputDiagram); +}; + +toVTStream = function(diagramData, scheduler, endTime) { + var item, singleMarbleStreams, _i, _len; + singleMarbleStreams = []; + for (_i = 0, _len = diagramData.length; _i < _len; _i++) { + item = diagramData[_i]; + singleMarbleStreams.push(Rx.Observable.just(item, scheduler).delay(item.t || item.time, scheduler)); + } + return Rx.Observable.merge(singleMarbleStreams).takeUntilWithTime(endTime, scheduler).publish().refCount(); +}; + +getDiagramPromise = function(stream, scheduler, endTime) { + var subject; + subject = new Rx.BehaviorSubject([]); + stream.observeOn(scheduler).timestamp(scheduler).map(function(x) { + if (typeof x.value !== "object") { + x.value = { + content: x.value, + id: calculateMarbleContentHash(x.value) + }; + } + return { + time: (x.timestamp / endTime) * 100, + content: x.value.content, + id: x.value.id + }; + }).reduce(function(acc, x) { + acc.push(x); + return acc; + }, []).subscribe(function(x) { + subject.onNext(x); + return true; + }, function() { + console.warn("Error in the diagram promise stream"); + return 0; + }); + return subject.asObservable(); +}; + +module.exports = { + makeScheduler: makeScheduler, + toVTStream: toVTStream, + prepareInputDiagramStream: prepareInputDiagramStream, + prepareInputDiagram: prepareInputDiagram, + getDiagramPromise: getDiagramPromise +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/controllers/utils.js","/../../node_modules/rxmarbles/controllers") +},{"buffer":3,"oMfpAn":7,"rx":19}],24:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Rx; + +Rx = require('rx'); + +module.exports = { + "all": { + "label": "all(x => x < 10)", + "inputs": [ + [ + { + t: 5, + d: 1 + }, { + t: 15, + d: 2 + }, { + t: 25, + d: 3 + }, { + t: 35, + d: 4 + }, { + t: 65, + d: 5 + } + ] + ], + "apply": function(inputs) { + return inputs[0].all(function(x) { + return x.content < 10; + }); + } + }, + "any": { + "label": "any(x => x > 10)", + "inputs": [ + [ + { + t: 5, + d: 2 + }, { + t: 15, + d: 30 + }, { + t: 25, + d: 22 + }, { + t: 35, + d: 5 + }, { + t: 45, + d: 60 + }, { + t: 55, + d: 1 + } + ] + ], + "apply": function(inputs) { + return inputs[0].any(function(x) { + return x.content > 10; + }); + } + }, + "contains": { + "label": "contains(22)", + "inputs": [ + [ + { + t: 5, + d: 2 + }, { + t: 15, + d: 30 + }, { + t: 25, + d: 22 + }, { + t: 35, + d: 5 + }, { + t: 45, + d: 60 + }, { + t: 55, + d: 1 + } + ] + ], + "apply": function(inputs) { + return inputs[0].contains({ + content: 22 + }, function(x, y) { + return x.content === y.content; + }); + } + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/models/boolean-examples.js","/../../node_modules/rxmarbles/models") +},{"buffer":3,"oMfpAn":7,"rx":19}],25:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Rx; + +Rx = require('rx'); + +module.exports = { + "combineLatest": { + "label": "combineLatest((x, y) => \"\" + x + y)", + "inputs": [ + [ + { + t: 0, + d: 1 + }, { + t: 20, + d: 2 + }, { + t: 65, + d: 3 + }, { + t: 75, + d: 4 + }, { + t: 92, + d: 5 + } + ], [ + { + t: 10, + d: "A" + }, { + t: 25, + d: "B" + }, { + t: 50, + d: "C" + }, { + t: 57, + d: "D" + } + ] + ], + "apply": function(inputs) { + return Rx.Observable.combineLatest(inputs[0], inputs[1], function(x, y) { + return "" + x.content + y.content; + }); + } + }, + "concat": { + "label": "concat", + "inputs": [ + [ + { + t: 0, + d: 1 + }, { + t: 15, + d: 1 + }, { + t: 50, + d: 1 + } + ], [ + { + t: 13, + d: 2 + }, { + t: 30, + d: 2 + } + ] + ], + "apply": function(inputs) { + return Rx.Observable.concat(inputs); + } + }, + "merge": { + "label": "merge", + "inputs": [ + [ + { + t: 0, + d: 20 + }, { + t: 15, + d: 40 + }, { + t: 30, + d: 60 + }, { + t: 45, + d: 80 + }, { + t: 60, + d: 100 + } + ], [ + { + t: 37, + d: 1 + }, { + t: 68, + d: 1 + } + ] + ], + "apply": function(inputs) { + return Rx.Observable.merge(inputs); + } + }, + "sample": { + "label": "sample", + "inputs": [ + [ + { + t: 0, + d: 1 + }, { + t: 20, + d: 2 + }, { + t: 40, + d: 3 + }, { + t: 60, + d: 4 + }, { + t: 80, + d: 5 + } + ], [ + { + t: 10, + d: "A" + }, { + t: 25, + d: "B" + }, { + t: 33, + d: "C" + }, { + t: 70, + d: "D" + } + ] + ], + "apply": function(inputs) { + return inputs[0].sample(inputs[1]); + } + }, + "startWith": { + "label": "startWith(1)", + "inputs": [ + [ + { + t: 30, + d: 2 + }, { + t: 40, + d: 3 + } + ] + ], + "apply": function(inputs, scheduler) { + return inputs[0].startWith(scheduler, 1); + } + }, + "zip": { + "label": "zip", + "inputs": [ + [ + { + t: 0, + d: 1 + }, { + t: 20, + d: 2 + }, { + t: 65, + d: 3 + }, { + t: 75, + d: 4 + }, { + t: 92, + d: 5 + } + ], [ + { + t: 10, + d: "A" + }, { + t: 25, + d: "B" + }, { + t: 50, + d: "C" + }, { + t: 57, + d: "D" + } + ] + ], + "apply": function(inputs) { + return Rx.Observable.zip(inputs[0], inputs[1], function(x, y) { + return "" + x.content + y.content; + }); + } + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/models/combine-examples.js","/../../node_modules/rxmarbles/models") +},{"buffer":3,"oMfpAn":7,"rx":19}],26:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Rx; + +Rx = require('rx'); + +module.exports = { + "amb": { + "label": "amb", + "inputs": [ + [ + { + t: 10, + d: 20 + }, { + t: 20, + d: 40 + }, { + t: 30, + d: 60 + } + ], [ + { + t: 5, + d: 1 + }, { + t: 15, + d: 2 + }, { + t: 25, + d: 3 + } + ], [ + { + t: 20, + d: 0 + }, { + t: 32, + d: 0 + }, { + t: 44, + d: 0 + } + ] + ], + "apply": function(inputs) { + return Rx.Observable.amb(inputs); + } + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/models/conditional-examples.js","/../../node_modules/rxmarbles/models") +},{"buffer":3,"oMfpAn":7,"rx":19}],27:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Rx, applyCategory, booleanExamples, combineExamples, conditionalExamples, filterExamples, mathExamples, merge, transformExamples, + __slice = [].slice, + __hasProp = {}.hasOwnProperty; + +Rx = require('rx'); + +transformExamples = require('rxmarbles/models/transform-examples'); + +combineExamples = require('rxmarbles/models/combine-examples'); + +filterExamples = require('rxmarbles/models/filter-examples'); + +mathExamples = require('rxmarbles/models/math-examples'); + +booleanExamples = require('rxmarbles/models/boolean-examples'); + +conditionalExamples = require('rxmarbles/models/conditional-examples'); + +merge = function() { + var args, name, object, result, value, _i, _len; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + result = {}; + for (_i = 0, _len = args.length; _i < _len; _i++) { + object = args[_i]; + for (name in object) { + if (!__hasProp.call(object, name)) continue; + value = object[name]; + result[name] = object[name]; + } + } + return result; +}; + +applyCategory = function(examples, categoryName) { + var key, value; + for (key in examples) { + if (!__hasProp.call(examples, key)) continue; + value = examples[key]; + examples[key]["category"] = categoryName; + } + return examples; +}; + +module.exports = merge(applyCategory(transformExamples, "Transforming Operators"), applyCategory(combineExamples, "Combining Operators"), applyCategory(filterExamples, "Filtering Operators"), applyCategory(mathExamples, "Mathematical Operators"), applyCategory(booleanExamples, "Boolean Operators"), applyCategory(conditionalExamples, "Conditional Operators")); + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/models/examples.js","/../../node_modules/rxmarbles/models") +},{"buffer":3,"oMfpAn":7,"rx":19,"rxmarbles/models/boolean-examples":24,"rxmarbles/models/combine-examples":25,"rxmarbles/models/conditional-examples":26,"rxmarbles/models/filter-examples":28,"rxmarbles/models/math-examples":29,"rxmarbles/models/transform-examples":30}],28:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Rx; + +Rx = require('rx'); + +module.exports = { + "distinct": { + "label": "distinct", + "inputs": [ + [ + { + t: 5, + d: 1 + }, { + t: 20, + d: 2 + }, { + t: 35, + d: 2 + }, { + t: 60, + d: 1 + }, { + t: 70, + d: 3 + } + ] + ], + "apply": function(inputs) { + return inputs[0].distinct(function(x) { + return x.content; + }); + } + }, + "distinctUntilChanged": { + "label": "distinctUntilChanged", + "inputs": [ + [ + { + t: 5, + d: 1 + }, { + t: 20, + d: 2 + }, { + t: 35, + d: 2 + }, { + t: 60, + d: 1 + }, { + t: 70, + d: 3 + } + ] + ], + "apply": function(inputs) { + return inputs[0].distinctUntilChanged(function(x) { + return x.content; + }); + } + }, + "elementAt": { + "label": "elementAt(2)", + "inputs": [ + [ + { + t: 30, + d: 1 + }, { + t: 40, + d: 2 + }, { + t: 65, + d: 3 + }, { + t: 75, + d: 4 + } + ] + ], + "apply": function(inputs, scheduler) { + return inputs[0].elementAt(2); + } + }, + "filter": { + "label": "filter(x => x > 10)", + "inputs": [ + [ + { + t: 5, + d: 2 + }, { + t: 15, + d: 30 + }, { + t: 25, + d: 22 + }, { + t: 35, + d: 5 + }, { + t: 45, + d: 60 + }, { + t: 55, + d: 1 + } + ] + ], + "apply": function(inputs) { + return inputs[0].filter(function(x) { + return x.content > 10; + }); + } + }, + "find": { + "label": "find(x => x > 10)", + "inputs": [ + [ + { + t: 5, + d: 2 + }, { + t: 15, + d: 30 + }, { + t: 25, + d: 22 + }, { + t: 35, + d: 5 + }, { + t: 45, + d: 60 + }, { + t: 55, + d: 1 + } + ] + ], + "apply": function(inputs, scheduler) { + return inputs[0].find(function(x) { + return x.content > 10; + }); + } + }, + "first": { + "label": "first", + "inputs": [ + [ + { + t: 30, + d: 1 + }, { + t: 40, + d: 2 + }, { + t: 65, + d: 3 + }, { + t: 75, + d: 4 + } + ] + ], + "apply": function(inputs) { + return inputs[0].first(); + } + }, + "last": { + "label": "last", + "inputs": [ + [ + { + t: 30, + d: 1 + }, { + t: 40, + d: 2 + }, { + t: 65, + d: 3 + }, { + t: 75, + d: 4 + } + ] + ], + "apply": function(inputs) { + return inputs[0].last(); + } + }, + "skip": { + "label": "skip(2)", + "inputs": [ + [ + { + t: 30, + d: 1 + }, { + t: 40, + d: 2 + }, { + t: 65, + d: 3 + }, { + t: 75, + d: 4 + } + ] + ], + "apply": function(inputs) { + return inputs[0].skip(2); + } + }, + "skipUntil": { + "label": "skipUntil", + "inputs": [ + [ + { + t: 0, + d: 1 + }, { + t: 10, + d: 2 + }, { + t: 20, + d: 3 + }, { + t: 30, + d: 4 + }, { + t: 40, + d: 5 + }, { + t: 50, + d: 6 + }, { + t: 60, + d: 7 + }, { + t: 70, + d: 8 + }, { + t: 80, + d: 9 + } + ], [ + { + t: 47, + d: 0 + }, { + t: 73, + d: 0 + } + ] + ], + "apply": function(inputs) { + return inputs[0].skipUntil(inputs[1]); + } + }, + "take": { + "label": "take(2)", + "inputs": [ + [ + { + t: 30, + d: 1 + }, { + t: 40, + d: 2 + }, { + t: 65, + d: 3 + }, { + t: 75, + d: 4 + } + ] + ], + "apply": function(inputs, scheduler) { + return inputs[0].take(2, scheduler); + } + }, + "takeUntil": { + "label": "takeUntil", + "inputs": [ + [ + { + t: 0, + d: 1 + }, { + t: 10, + d: 2 + }, { + t: 20, + d: 3 + }, { + t: 30, + d: 4 + }, { + t: 40, + d: 5 + }, { + t: 50, + d: 6 + }, { + t: 60, + d: 7 + }, { + t: 70, + d: 8 + }, { + t: 80, + d: 9 + } + ], [ + { + t: 47, + d: 0 + }, { + t: 73, + d: 0 + } + ] + ], + "apply": function(inputs) { + return inputs[0].takeUntil(inputs[1]); + } + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/models/filter-examples.js","/../../node_modules/rxmarbles/models") +},{"buffer":3,"oMfpAn":7,"rx":19}],29:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Rx; + +Rx = require('rx'); + +module.exports = { + "aggregate": { + "label": "aggregate((x, y) => x + y)", + "inputs": [ + [ + { + t: 5, + d: 1 + }, { + t: 15, + d: 2 + }, { + t: 25, + d: 3 + }, { + t: 35, + d: 4 + }, { + t: 65, + d: 5 + } + ] + ], + "apply": function(inputs) { + return inputs[0].aggregate(function(x, y) { + return { + content: x.content + y.content, + time: x.time, + id: x.id + y.id + }; + }); + } + }, + "average": { + "label": "average", + "inputs": [ + [ + { + t: 5, + d: 1 + }, { + t: 15, + d: 2 + }, { + t: 30, + d: 2 + }, { + t: 50, + d: 2 + }, { + t: 65, + d: 5 + } + ] + ], + "apply": function(inputs) { + return inputs[0].average(function(x) { + return x.content; + }); + } + }, + "count": { + "label": "count(x => x > 10)", + "inputs": [ + [ + { + t: 5, + d: 2 + }, { + t: 15, + d: 30 + }, { + t: 25, + d: 22 + }, { + t: 35, + d: 5 + }, { + t: 45, + d: 60 + }, { + t: 55, + d: 1 + } + ] + ], + "apply": function(inputs) { + return inputs[0].count(function(x) { + return x.content > 10; + }); + } + }, + "max": { + "label": "max", + "inputs": [ + [ + { + t: 5, + d: 2 + }, { + t: 15, + d: 30 + }, { + t: 25, + d: 22 + }, { + t: 35, + d: 5 + }, { + t: 45, + d: 60 + }, { + t: 55, + d: 1 + } + ] + ], + "apply": function(inputs) { + return inputs[0].max(function(x, y) { + if (x.content > y.content) { + return 1; + } + if (x.content < y.content) { + return -1; + } + return 0; + }); + } + }, + "min": { + "label": "min", + "inputs": [ + [ + { + t: 5, + d: 2 + }, { + t: 15, + d: 30 + }, { + t: 25, + d: 22 + }, { + t: 35, + d: 5 + }, { + t: 45, + d: 60 + }, { + t: 55, + d: 1 + } + ] + ], + "apply": function(inputs) { + return inputs[0].min(function(x, y) { + if (x.content > y.content) { + return 1; + } + if (x.content < y.content) { + return -1; + } + return 0; + }); + } + }, + "sum": { + "label": "sum", + "inputs": [ + [ + { + t: 5, + d: 1 + }, { + t: 15, + d: 2 + }, { + t: 25, + d: 3 + }, { + t: 35, + d: 4 + }, { + t: 65, + d: 5 + } + ] + ], + "apply": function(inputs) { + return inputs[0].sum(function(x) { + return x.content; + }); + } + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/models/math-examples.js","/../../node_modules/rxmarbles/models") +},{"buffer":3,"oMfpAn":7,"rx":19}],30:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Rx; + +Rx = require('rx'); + +module.exports = { + "delay": { + "label": "delay", + "inputs": [ + [ + { + t: 0, + d: 1 + }, { + t: 10, + d: 2 + }, { + t: 20, + d: 1 + } + ] + ], + "apply": function(inputs, scheduler) { + return inputs[0].delay(20, scheduler); + } + }, + "delayWithSelector": { + "label": "delayWithSelector(x => Rx.Observable.timer(20 * x))", + "inputs": [ + [ + { + t: 0, + d: 1 + }, { + t: 10, + d: 2 + }, { + t: 20, + d: 1 + } + ] + ], + "apply": function(inputs, scheduler) { + return inputs[0].delayWithSelector(function(x) { + return Rx.Observable.timer(Number(x.content) * 20, 1000, scheduler); + }); + } + }, + "map": { + "label": "map(x => 10 * x)", + "inputs": [ + [ + { + t: 10, + d: 1 + }, { + t: 20, + d: 2 + }, { + t: 50, + d: 3 + } + ] + ], + "apply": function(inputs) { + return inputs[0].map(function(x) { + return { + content: x.content * 10, + time: x.time, + id: x.id + }; + }); + } + }, + "scan": { + "label": "scan((x, y) => x + y)", + "inputs": [ + [ + { + t: 5, + d: 1 + }, { + t: 15, + d: 2 + }, { + t: 25, + d: 3 + }, { + t: 35, + d: 4 + }, { + t: 65, + d: 5 + } + ] + ], + "apply": function(inputs) { + return inputs[0].scan(function(x, y) { + return { + content: x.content + y.content, + time: x.time, + id: x.id + y.id + }; + }); + } + }, + "throttle": { + "label": "throttle", + "inputs": [ + [ + { + t: 0, + d: 1 + }, { + t: 26, + d: 2 + }, { + t: 34, + d: 3 + }, { + t: 40, + d: 4 + }, { + t: 45, + d: 5 + }, { + t: 90, + d: 6 + } + ] + ], + "apply": function(inputs, scheduler) { + return inputs[0].throttle(20, scheduler); + } + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/models/transform-examples.js","/../../node_modules/rxmarbles/models") +},{"buffer":3,"oMfpAn":7,"rx":19}],31:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Marble, Rx, createArrowBodyElement, createArrowHeadElement, createMarblesContainerElement, makeDataStream, + __slice = [].slice; + +Rx = require('rx'); + +Marble = require('rxmarbles/views/marble'); + +createArrowBodyElement = function() { + var arrowBody; + arrowBody = document.createElement("div"); + arrowBody.className = "arrow"; + return arrowBody; +}; + +createArrowHeadElement = function() { + var arrowHead; + arrowHead = document.createElement("div"); + arrowHead.className = "arrow-head"; + return arrowHead; +}; + +createMarblesContainerElement = function(marbleViews) { + var m, marblesContainer, _i, _len; + marblesContainer = document.createElement("div"); + marblesContainer.className = "marbles"; + for (_i = 0, _len = marbleViews.length; _i < _len; _i++) { + m = marbleViews[_i]; + marblesContainer.appendChild(m); + } + return marblesContainer; +}; + +makeDataStream = function(marbleViews) { + var m; + return Rx.Observable.combineLatest((function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = marbleViews.length; _i < _len; _i++) { + m = marbleViews[_i]; + _results.push(m.dataStream); + } + return _results; + })(), function() { + var args; + args = 1 <= arguments.length ? __slice.call(arguments, 0) : []; + return args; + }); +}; + +module.exports = { + render: function(diagramData) { + var diagram, i, marbleViews; + diagram = document.createElement("div"); + diagram.className = "diagram"; + diagram.appendChild(createArrowBodyElement()); + diagram.appendChild(createArrowHeadElement()); + marbleViews = (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = diagramData.length; _i < _len; _i++) { + i = diagramData[_i]; + _results.push(Marble.render(i, true)); + } + return _results; + })(); + diagram.appendChild(createMarblesContainerElement(marbleViews)); + diagram.dataStream = makeDataStream(marbleViews); + return diagram; + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/views/input-diagram.js","/../../node_modules/rxmarbles/views") +},{"buffer":3,"oMfpAn":7,"rx":19,"rxmarbles/views/marble":32}],32:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var NUM_COLORS, Rx, SVG_BORDER_WIDTH, SVG_CX, SVG_CY, SVG_R, SVG_VIEWBOX, XMLNS, createContentElement, createMarbleSvg, createRootElement, getDxDragStream, getInteractiveLeftPosStream, getLeftPosStream, h, render, svg, virtualRender; + +Rx = require('rx'); + +h = require('virtual-hyperscript'); + +svg = require('virtual-hyperscript/svg'); + +XMLNS = "http://www.w3.org/2000/svg"; + +NUM_COLORS = 4; + +SVG_VIEWBOX = "0 0 1 1"; + +SVG_CX = 0.5; + +SVG_CY = 0.5; + +SVG_R = 0.47; + +SVG_BORDER_WIDTH = "0.06px"; + +getDxDragStream = function(element) { + return Rx.Observable.fromEvent(element, "mousedown").map(function() { + var dxStream, moveStream, upStream; + moveStream = Rx.Observable.fromEvent(document, "mousemove"); + upStream = Rx.Observable.fromEvent(document, "mouseup"); + dxStream = moveStream.map(function(ev) { + ev.stopPropagation; + ev.preventDefault(); + return ev.pageX; + }).windowWithCount(2, 1).flatMap(function(result) { + return result.toArray(); + }).map(function(array) { + return array[1] - array[0]; + }); + return dxStream.takeUntil(upStream); + }).concatAll(); +}; + +getInteractiveLeftPosStream = function(element, initialPos) { + return getDxDragStream(element).scan(initialPos, function(acc, dx) { + var err, pxToPercentage; + pxToPercentage = 1; + try { + pxToPercentage = 100.0 / element.parentElement.clientWidth; + } catch (_error) { + err = _error; + console.warn(err); + } + return acc + (dx * pxToPercentage); + }).map(function(pos) { + if (pos < 0) { + return 0; + } + if (pos > 100) { + return 100; + } + return pos; + }).map(Math.round).startWith(initialPos).distinctUntilChanged(); +}; + +createRootElement = function(draggable) { + var container; + container = document.createElement("div"); + container.className = "marble-container"; + if (draggable) { + container.className += " draggable"; + } + return container; +}; + +createMarbleSvg = function(item) { + var circle, colornum, marble; + colornum = (item.id % NUM_COLORS) + 1; + marble = document.createElementNS(XMLNS, "svg"); + marble.setAttribute("class", "marble"); + marble.setAttribute("viewBox", SVG_VIEWBOX); + circle = document.createElementNS(XMLNS, "circle"); + circle.setAttribute("cx", SVG_CX); + circle.setAttribute("cy", SVG_CY); + circle.setAttribute("r", SVG_R); + circle.setAttribute("class", "marble marble-color-" + colornum); + circle.setAttribute("stroke-width", SVG_BORDER_WIDTH); + marble.appendChild(circle); + return marble; +}; + +createContentElement = function(item) { + var content; + content = document.createElement("p"); + content.className = "marble-content"; + content.textContent = item != null ? item.content : void 0; + return content; +}; + +getLeftPosStream = function(item, draggable, element) { + if (draggable) { + return getInteractiveLeftPosStream(element, item.time); + } else { + return Rx.Observable.just(item.time); + } +}; + +virtualRender = function(marbleData) { + var colornum, content, leftPos; + colornum = (marbleData.id % 4) + 1; + leftPos = "" + marbleData.time + "%"; + content = "" + marbleData.content; + return h("div.marble-container", { + style: { + "left": leftPos + } + }, [ + svg("svg", { + attributes: { + "class": "marble", + viewBox: SVG_VIEWBOX + } + }, [ + svg("circle", { + attributes: { + "class": "marble marble-color-" + colornum, + cx: SVG_CX, + cy: SVG_CY, + r: SVG_R, + "stroke-width": SVG_BORDER_WIDTH + } + }) + ]), h("p.marble-content", {}, content) + ]); +}; + +render = function(item, draggable) { + var container, leftPosStream; + if (draggable == null) { + draggable = false; + } + container = createRootElement(draggable); + container.appendChild(createMarbleSvg(item)); + container.appendChild(createContentElement(item)); + leftPosStream = getLeftPosStream(item, draggable, container); + container.dataStream = leftPosStream.map(function(leftPos) { + return { + time: leftPos, + content: item.content, + id: item.id + }; + }); + leftPosStream.subscribe(function(leftPos) { + container.style.left = leftPos + "%"; + return true; + }); + return container; +}; + +module.exports = { + render: render, + virtualRender: virtualRender +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/views/marble.js","/../../node_modules/rxmarbles/views") +},{"buffer":3,"oMfpAn":7,"rx":19,"virtual-hyperscript":63,"virtual-hyperscript/svg":91}],33:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var h, renderLabel; + +h = require('hyperscript'); + +renderLabel = function(label) { + var attrs; + attrs = label.length > 20 ? { + style: { + "font-size": "1.5rem" + } + } : {}; + return h("span.operator-box-label", attrs, label); +}; + +module.exports = { + render: function(example) { + return h("div.operator-box", [renderLabel(example.label)]); + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/views/operator-box.js","/../../node_modules/rxmarbles/views") +},{"buffer":3,"hyperscript":8,"oMfpAn":7}],34:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Examples, Rx, fixListHeight, getDocumentHeight, h, organizeExamplesByCategory, renderExampleCategory, renderExampleItem, renderExampleItems, renderMenuContent, selected$, + __hasProp = {}.hasOwnProperty; + +h = require('hyperscript'); + +Rx = require('rx'); + +Examples = require('rxmarbles/models/examples'); + +selected$ = new Rx.Subject(); + +renderExampleCategory = function(categoryName) { + return h("li.category", "" + categoryName); +}; + +renderExampleItem = function(example) { + var link; + link = h("a", { + href: "#" + example.key + }, example.key); + Rx.Observable.fromEvent(link, "click").subscribe(function() { + selected$.onNext(example.key); + return true; + }); + return h("li", [link]); +}; + +renderExampleItems = function(examples) { + var example; + return (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = examples.length; _i < _len; _i++) { + example = examples[_i]; + _results.push(renderExampleItem(example)); + } + return _results; + })(); +}; + +organizeExamplesByCategory = function(examples) { + var categoryMap, key, value; + categoryMap = {}; + for (key in examples) { + if (!__hasProp.call(examples, key)) continue; + value = examples[key]; + value.key = key; + if (categoryMap.hasOwnProperty(value.category)) { + categoryMap[value.category].push(value); + } else { + categoryMap[value.category] = [value]; + } + } + return categoryMap; +}; + +renderMenuContent = function(examples) { + var categoryExamples, categoryMap, categoryName, listItems; + listItems = []; + categoryMap = organizeExamplesByCategory(examples); + for (categoryName in categoryMap) { + if (!__hasProp.call(categoryMap, categoryName)) continue; + categoryExamples = categoryMap[categoryName]; + listItems.push(renderExampleCategory(categoryName)); + listItems = listItems.concat(renderExampleItems(categoryExamples)); + } + listItems.push(h("li.category", "More")); + listItems.push(h("li", "Coming soon...")); + return listItems; +}; + +getDocumentHeight = function() { + var body, html; + body = document.body; + html = document.documentElement; + return Math.max(body.scrollHeight, body.offsetHeight, html.clientHeight, html.scrollHeight, html.offsetHeight); +}; + +fixListHeight = function(listElement) { + return Rx.Observable.timer(1).subscribe(function() { + var height; + height = getDocumentHeight() - listElement.getBoundingClientRect().top; + listElement.style.height = "" + height + "px"; + return true; + }); +}; + +module.exports = { + getSelected$: function() { + return selected$; + }, + render: function() { + var listElement; + listElement = h("ul.operators-menu", renderMenuContent(Examples)); + fixListHeight(listElement); + return listElement; + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/views/operators-menu.js","/../../node_modules/rxmarbles/views") +},{"buffer":3,"hyperscript":8,"oMfpAn":7,"rx":19,"rxmarbles/models/examples":27}],35:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Marble, Rx, VDOM, h, virtualRender, virtualRenderMarbles; + +Rx = require('rx'); + +h = require('virtual-hyperscript'); + +Marble = require('rxmarbles/views/marble'); + +VDOM = { + createElement: require('virtual-dom/create-element'), + diff: require('virtual-dom/diff'), + patch: require('virtual-dom/patch') +}; + +virtualRenderMarbles = function(diagramData) { + var m; + return h("div.marbles", (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = diagramData.length; _i < _len; _i++) { + m = diagramData[_i]; + _results.push(Marble.virtualRender(m)); + } + return _results; + })()); +}; + +virtualRender = function(diagramData) { + var children; + if (diagramData === null) { + return h("div.diagram"); + } else { + children = []; + children.push(h("div.arrow")); + children.push(h("div.arrow-head")); + children.push(virtualRenderMarbles(diagramData)); + return h("div.diagram", {}, children); + } +}; + +module.exports = { + render: function(diagramDataStream) { + var rootNode, tree; + tree = virtualRender(null); + rootNode = VDOM.createElement(tree); + diagramDataStream.subscribe(function(diagram) { + var newTree, patches; + newTree = virtualRender(diagram); + patches = VDOM.diff(tree, newTree); + rootNode = VDOM.patch(rootNode, patches); + tree = newTree; + return true; + }); + return rootNode; + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/views/output-diagram.js","/../../node_modules/rxmarbles/views") +},{"buffer":3,"oMfpAn":7,"rx":19,"rxmarbles/views/marble":32,"virtual-dom/create-element":38,"virtual-dom/diff":39,"virtual-dom/patch":58,"virtual-hyperscript":63}],36:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var InputDiagramView, OperatorBox, OutputDiagramView, Rx, Utils, createInputDiagramElements, createOperatorBoxElement, createOutputDiagramElement, h, streamOfArrayOfLiveInputDiagramStreams; + +Rx = require('rx'); + +h = require('hyperscript'); + +InputDiagramView = require('rxmarbles/views/input-diagram'); + +OperatorBox = require('rxmarbles/views/operator-box'); + +OutputDiagramView = require('rxmarbles/views/output-diagram'); + +Utils = require('rxmarbles/views/utils'); + +streamOfArrayOfLiveInputDiagramStreams = new Rx.BehaviorSubject(null); + +createInputDiagramElements = function() { + var InputDiagrams, inputDiagramElements; + InputDiagrams = require('rxmarbles/controllers/input-diagrams'); + inputDiagramElements = Utils.renderObservableDOMElement(InputDiagrams.initial$.map(function(diagrams) { + var d; + return (function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = diagrams.length; _i < _len; _i++) { + d = diagrams[_i]; + _results.push(InputDiagramView.render(d)); + } + return _results; + })(); + }).doAction(function(diagramViews) { + var diagram; + return streamOfArrayOfLiveInputDiagramStreams.onNext((function() { + var _i, _len, _results; + _results = []; + for (_i = 0, _len = diagramViews.length; _i < _len; _i++) { + diagram = diagramViews[_i]; + _results.push(diagram.dataStream); + } + return _results; + })()); + })); + return inputDiagramElements; +}; + +createOperatorBoxElement = function() { + var SelectedExample; + SelectedExample = require('rxmarbles/controllers/selected-example'); + return Utils.renderObservableDOMElement(SelectedExample.stream.map(function(example) { + return OperatorBox.render(example); + })); +}; + +createOutputDiagramElement = function() { + var OutputDiagram; + OutputDiagram = require('rxmarbles/controllers/output-diagram'); + return OutputDiagramView.render(OutputDiagram); +}; + +module.exports = { + getStreamOfArrayOfLiveInputDiagramStreams: function() { + return streamOfArrayOfLiveInputDiagramStreams; + }, + render: function() { + return h("div.sandbox", [createInputDiagramElements(), createOperatorBoxElement(), createOutputDiagramElement()]); + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/views/sandbox.js","/../../node_modules/rxmarbles/views") +},{"buffer":3,"hyperscript":8,"oMfpAn":7,"rx":19,"rxmarbles/controllers/input-diagrams":20,"rxmarbles/controllers/output-diagram":21,"rxmarbles/controllers/selected-example":22,"rxmarbles/views/input-diagram":31,"rxmarbles/views/operator-box":33,"rxmarbles/views/output-diagram":35,"rxmarbles/views/utils":37}],37:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = { + renderObservableDOMElement: function(elementStream) { + var wrapper; + wrapper = document.createElement("div"); + elementStream.subscribe(function(thing) { + var element, _i, _len; + wrapper.innerHTML = ""; + if (Array.isArray(thing)) { + for (_i = 0, _len = thing.length; _i < _len; _i++) { + element = thing[_i]; + wrapper.appendChild(element); + } + } else if (thing instanceof Element) { + wrapper.appendChild(thing); + } + return true; + }); + return wrapper; + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/rxmarbles/views/utils.js","/../../node_modules/rxmarbles/views") +},{"buffer":3,"oMfpAn":7}],38:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var createElement = require("vdom/create-element") + +module.exports = createElement + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/create-element.js","/../../node_modules/virtual-dom") +},{"buffer":3,"oMfpAn":7,"vdom/create-element":42}],39:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var diff = require("vtree/diff") + +module.exports = diff + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/diff.js","/../../node_modules/virtual-dom") +},{"buffer":3,"oMfpAn":7,"vtree/diff":48}],40:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = isObject + +function isObject(x) { + return typeof x === "object" && x !== null +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/is-object/index.js","/../../node_modules/virtual-dom/node_modules/is-object") +},{"buffer":3,"oMfpAn":7}],41:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var isObject = require("is-object") +var isHook = require("vtree/is-vhook") + +module.exports = applyProperties + +function applyProperties(node, props, previous) { + for (var propName in props) { + var propValue = props[propName] + + if (propValue === undefined) { + removeProperty(node, props, previous, propName); + } else if (isHook(propValue)) { + propValue.hook(node, + propName, + previous ? previous[propName] : undefined) + } else { + if (isObject(propValue)) { + patchObject(node, props, previous, propName, propValue); + } else if (propValue !== undefined) { + node[propName] = propValue + } + } + } +} + +function removeProperty(node, props, previous, propName) { + if (previous) { + var previousValue = previous[propName] + + if (!isHook(previousValue)) { + if (propName === "attributes") { + for (var attrName in previousValue) { + node.removeAttribute(attrName) + } + } else if (propName === "style") { + for (var i in previousValue) { + node.style[i] = "" + } + } else if (typeof previousValue === "string") { + node[propName] = "" + } else { + node[propName] = null + } + } + } +} + +function patchObject(node, props, previous, propName, propValue) { + var previousValue = previous ? previous[propName] : undefined + + // Set attributes + if (propName === "attributes") { + for (var attrName in propValue) { + var attrValue = propValue[attrName] + + if (attrValue === undefined) { + node.removeAttribute(attrName) + } else { + node.setAttribute(attrName, attrValue) + } + } + + return + } + + if(previousValue && isObject(previousValue) && + getPrototype(previousValue) !== getPrototype(propValue)) { + node[propName] = propValue + return + } + + if (!isObject(node[propName])) { + node[propName] = {} + } + + var replacer = propName === "style" ? "" : undefined + + for (var k in propValue) { + var value = propValue[k] + node[propName][k] = (value === undefined) ? replacer : value + } +} + +function getPrototype(value) { + if (Object.getPrototypeOf) { + return Object.getPrototypeOf(value) + } else if (value.__proto__) { + return value.__proto__ + } else if (value.constructor) { + return value.constructor.prototype + } +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vdom/apply-properties.js","/../../node_modules/virtual-dom/node_modules/vdom") +},{"buffer":3,"is-object":40,"oMfpAn":7,"vtree/is-vhook":51}],42:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var document = require("global/document") + +var applyProperties = require("./apply-properties") + +var isVNode = require("vtree/is-vnode") +var isVText = require("vtree/is-vtext") +var isWidget = require("vtree/is-widget") +var handleThunk = require("vtree/handle-thunk") + +module.exports = createElement + +function createElement(vnode, opts) { + var doc = opts ? opts.document || document : document + var warn = opts ? opts.warn : null + + vnode = handleThunk(vnode).a + + if (isWidget(vnode)) { + return vnode.init() + } else if (isVText(vnode)) { + return doc.createTextNode(vnode.text) + } else if (!isVNode(vnode)) { + if (warn) { + warn("Item is not a valid virtual dom node", vnode) + } + return null + } + + var node = (vnode.namespace === null) ? + doc.createElement(vnode.tagName) : + doc.createElementNS(vnode.namespace, vnode.tagName) + + var props = vnode.properties + applyProperties(node, props) + + var children = vnode.children + + for (var i = 0; i < children.length; i++) { + var childNode = createElement(children[i], opts) + if (childNode) { + node.appendChild(childNode) + } + } + + return node +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vdom/create-element.js","/../../node_modules/virtual-dom/node_modules/vdom") +},{"./apply-properties":41,"buffer":3,"global/document":44,"oMfpAn":7,"vtree/handle-thunk":49,"vtree/is-vnode":52,"vtree/is-vtext":53,"vtree/is-widget":54}],43:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Maps a virtual DOM tree onto a real DOM tree in an efficient manner. +// We don't want to read all of the DOM nodes in the tree so we use +// the in-order tree indexing to eliminate recursion down certain branches. +// We only recurse into a DOM node if we know that it contains a child of +// interest. + +var noChild = {} + +module.exports = domIndex + +function domIndex(rootNode, tree, indices, nodes) { + if (!indices || indices.length === 0) { + return {} + } else { + indices.sort(ascending) + return recurse(rootNode, tree, indices, nodes, 0) + } +} + +function recurse(rootNode, tree, indices, nodes, rootIndex) { + nodes = nodes || {} + + + if (rootNode) { + if (indexInRange(indices, rootIndex, rootIndex)) { + nodes[rootIndex] = rootNode + } + + var vChildren = tree.children + + if (vChildren) { + + var childNodes = rootNode.childNodes + + for (var i = 0; i < tree.children.length; i++) { + rootIndex += 1 + + var vChild = vChildren[i] || noChild + var nextIndex = rootIndex + (vChild.count || 0) + + // skip recursion down the tree if there are no nodes down here + if (indexInRange(indices, rootIndex, nextIndex)) { + recurse(childNodes[i], vChild, indices, nodes, rootIndex) + } + + rootIndex = nextIndex + } + } + } + + return nodes +} + +// Binary search for an index in the interval [left, right] +function indexInRange(indices, left, right) { + if (indices.length === 0) { + return false + } + + var minIndex = 0 + var maxIndex = indices.length - 1 + var currentIndex + var currentItem + + while (minIndex <= maxIndex) { + currentIndex = ((maxIndex + minIndex) / 2) >> 0 + currentItem = indices[currentIndex] + + if (minIndex === maxIndex) { + return currentItem >= left && currentItem <= right + } else if (currentItem < left) { + minIndex = currentIndex + 1 + } else if (currentItem > right) { + maxIndex = currentIndex - 1 + } else { + return true + } + } + + return false; +} + +function ascending(a, b) { + return a > b ? 1 : -1 +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vdom/dom-index.js","/../../node_modules/virtual-dom/node_modules/vdom") +},{"buffer":3,"oMfpAn":7}],44:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var topLevel = typeof global !== 'undefined' ? global : + typeof window !== 'undefined' ? window : {} +var minDoc = require('min-document'); + +if (typeof document !== 'undefined') { + module.exports = document; +} else { + var doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4']; + + if (!doccy) { + doccy = topLevel['__GLOBAL_DOCUMENT_CACHE@4'] = minDoc; + } + + module.exports = doccy; +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vdom/node_modules/global/document.js","/../../node_modules/virtual-dom/node_modules/vdom/node_modules/global") +},{"buffer":3,"min-document":2,"oMfpAn":7}],45:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var applyProperties = require("./apply-properties") + +var isWidget = require("vtree/is-widget") +var VPatch = require("vtree/vpatch") + +var render = require("./create-element") +var updateWidget = require("./update-widget") + +module.exports = applyPatch + +function applyPatch(vpatch, domNode, renderOptions) { + var type = vpatch.type + var vNode = vpatch.vNode + var patch = vpatch.patch + + switch (type) { + case VPatch.REMOVE: + return removeNode(domNode, vNode) + case VPatch.INSERT: + return insertNode(domNode, patch, renderOptions) + case VPatch.VTEXT: + return stringPatch(domNode, vNode, patch, renderOptions) + case VPatch.WIDGET: + return widgetPatch(domNode, vNode, patch, renderOptions) + case VPatch.VNODE: + return vNodePatch(domNode, vNode, patch, renderOptions) + case VPatch.ORDER: + reorderChildren(domNode, patch) + return domNode + case VPatch.PROPS: + applyProperties(domNode, patch, vNode.properties) + return domNode + case VPatch.THUNK: + return replaceRoot(domNode, + renderOptions.patch(domNode, patch, renderOptions)) + default: + return domNode + } +} + +function removeNode(domNode, vNode) { + var parentNode = domNode.parentNode + + if (parentNode) { + parentNode.removeChild(domNode) + } + + destroyWidget(domNode, vNode); + + return null +} + +function insertNode(parentNode, vNode, renderOptions) { + var newNode = render(vNode, renderOptions) + + if (parentNode) { + parentNode.appendChild(newNode) + } + + return parentNode +} + +function stringPatch(domNode, leftVNode, vText, renderOptions) { + var newNode + + if (domNode.nodeType === 3) { + domNode.replaceData(0, domNode.length, vText.text) + newNode = domNode + } else { + var parentNode = domNode.parentNode + newNode = render(vText, renderOptions) + + if (parentNode) { + parentNode.replaceChild(newNode, domNode) + } + } + + destroyWidget(domNode, leftVNode) + + return newNode +} + +function widgetPatch(domNode, leftVNode, widget, renderOptions) { + if (updateWidget(leftVNode, widget)) { + return widget.update(leftVNode, domNode) || domNode + } + + var parentNode = domNode.parentNode + var newWidget = render(widget, renderOptions) + + if (parentNode) { + parentNode.replaceChild(newWidget, domNode) + } + + destroyWidget(domNode, leftVNode) + + return newWidget +} + +function vNodePatch(domNode, leftVNode, vNode, renderOptions) { + var parentNode = domNode.parentNode + var newNode = render(vNode, renderOptions) + + if (parentNode) { + parentNode.replaceChild(newNode, domNode) + } + + destroyWidget(domNode, leftVNode) + + return newNode +} + +function destroyWidget(domNode, w) { + if (typeof w.destroy === "function" && isWidget(w)) { + w.destroy(domNode) + } +} + +function reorderChildren(domNode, bIndex) { + var children = [] + var childNodes = domNode.childNodes + var len = childNodes.length + var i + var reverseIndex = bIndex.reverse + + for (i = 0; i < len; i++) { + children.push(domNode.childNodes[i]) + } + + var insertOffset = 0 + var move + var node + var insertNode + for (i = 0; i < len; i++) { + move = bIndex[i] + if (move !== undefined && move !== i) { + // the element currently at this index will be moved later so increase the insert offset + if (reverseIndex[i] > i) { + insertOffset++ + } + + node = children[move] + insertNode = childNodes[i + insertOffset] + if (node !== insertNode) { + domNode.insertBefore(node, insertNode) + } + + // the moved element came from the front of the array so reduce the insert offset + if (move < i) { + insertOffset-- + } + } + + // element at this index is scheduled to be removed so increase insert offset + if (i in bIndex.removes) { + insertOffset++ + } + } +} + +function replaceRoot(oldRoot, newRoot) { + if (oldRoot && newRoot && oldRoot !== newRoot && oldRoot.parentNode) { + console.log(oldRoot) + oldRoot.parentNode.replaceChild(newRoot, oldRoot) + } + + return newRoot; +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vdom/patch-op.js","/../../node_modules/virtual-dom/node_modules/vdom") +},{"./apply-properties":41,"./create-element":42,"./update-widget":47,"buffer":3,"oMfpAn":7,"vtree/is-widget":54,"vtree/vpatch":56}],46:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var document = require("global/document") +var isArray = require("x-is-array") + +var domIndex = require("./dom-index") +var patchOp = require("./patch-op") +module.exports = patch + +function patch(rootNode, patches) { + return patchRecursive(rootNode, patches) +} + +function patchRecursive(rootNode, patches, renderOptions) { + var indices = patchIndices(patches) + + if (indices.length === 0) { + return rootNode + } + + var index = domIndex(rootNode, patches.a, indices) + var ownerDocument = rootNode.ownerDocument + + if (!renderOptions) { + renderOptions = { patch: patchRecursive } + if (ownerDocument !== document) { + renderOptions.document = ownerDocument + } + } + + for (var i = 0; i < indices.length; i++) { + var nodeIndex = indices[i] + rootNode = applyPatch(rootNode, + index[nodeIndex], + patches[nodeIndex], + renderOptions) + } + + return rootNode +} + +function applyPatch(rootNode, domNode, patchList, renderOptions) { + if (!domNode) { + return rootNode + } + + var newNode + + if (isArray(patchList)) { + for (var i = 0; i < patchList.length; i++) { + newNode = patchOp(patchList[i], domNode, renderOptions) + + if (domNode === rootNode) { + rootNode = newNode + } + } + } else { + newNode = patchOp(patchList, domNode, renderOptions) + + if (domNode === rootNode) { + rootNode = newNode + } + } + + return rootNode +} + +function patchIndices(patches) { + var indices = [] + + for (var key in patches) { + if (key !== "a") { + indices.push(Number(key)) + } + } + + return indices +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vdom/patch.js","/../../node_modules/virtual-dom/node_modules/vdom") +},{"./dom-index":43,"./patch-op":45,"buffer":3,"global/document":44,"oMfpAn":7,"x-is-array":57}],47:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var isWidget = require("vtree/is-widget") + +module.exports = updateWidget + +function updateWidget(a, b) { + if (isWidget(a) && isWidget(b)) { + if ("name" in a && "name" in b) { + return a.id === b.id + } else { + return a.init === b.init + } + } + + return false +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vdom/update-widget.js","/../../node_modules/virtual-dom/node_modules/vdom") +},{"buffer":3,"oMfpAn":7,"vtree/is-widget":54}],48:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var isArray = require("x-is-array") +var isObject = require("is-object") + +var VPatch = require("./vpatch") +var isVNode = require("./is-vnode") +var isVText = require("./is-vtext") +var isWidget = require("./is-widget") +var isThunk = require("./is-thunk") +var handleThunk = require("./handle-thunk") + +module.exports = diff + +function diff(a, b) { + var patch = { a: a } + walk(a, b, patch, 0) + return patch +} + +function walk(a, b, patch, index) { + if (a === b) { + if (isThunk(a) || isThunk(b)) { + thunks(a, b, patch, index) + } else { + hooks(b, patch, index) + } + return + } + + var apply = patch[index] + + if (b == null) { + apply = appendPatch(apply, new VPatch(VPatch.REMOVE, a, b)) + destroyWidgets(a, patch, index) + } else if (isThunk(a) || isThunk(b)) { + thunks(a, b, patch, index) + } else if (isVNode(b)) { + if (isVNode(a)) { + if (a.tagName === b.tagName && + a.namespace === b.namespace && + a.key === b.key) { + var propsPatch = diffProps(a.properties, b.properties, b.hooks) + if (propsPatch) { + apply = appendPatch(apply, + new VPatch(VPatch.PROPS, a, propsPatch)) + } + } else { + apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b)) + destroyWidgets(a, patch, index) + } + + apply = diffChildren(a, b, patch, apply, index) + } else { + apply = appendPatch(apply, new VPatch(VPatch.VNODE, a, b)) + destroyWidgets(a, patch, index) + } + } else if (isVText(b)) { + if (!isVText(a)) { + apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b)) + destroyWidgets(a, patch, index) + } else if (a.text !== b.text) { + apply = appendPatch(apply, new VPatch(VPatch.VTEXT, a, b)) + } + } else if (isWidget(b)) { + apply = appendPatch(apply, new VPatch(VPatch.WIDGET, a, b)) + + if (!isWidget(a)) { + destroyWidgets(a, patch, index) + } + } + + if (apply) { + patch[index] = apply + } +} + +function diffProps(a, b, hooks) { + var diff + + for (var aKey in a) { + if (!(aKey in b)) { + diff = diff || {} + diff[aKey] = undefined + } + + var aValue = a[aKey] + var bValue = b[aKey] + + if (hooks && aKey in hooks) { + diff = diff || {} + diff[aKey] = bValue + } else { + if (isObject(aValue) && isObject(bValue)) { + if (getPrototype(bValue) !== getPrototype(aValue)) { + diff = diff || {} + diff[aKey] = bValue + } else { + var objectDiff = diffProps(aValue, bValue) + if (objectDiff) { + diff = diff || {} + diff[aKey] = objectDiff + } + } + } else if (aValue !== bValue) { + diff = diff || {} + diff[aKey] = bValue + } + } + } + + for (var bKey in b) { + if (!(bKey in a)) { + diff = diff || {} + diff[bKey] = b[bKey] + } + } + + return diff +} + +function getPrototype(value) { + if (Object.getPrototypeOf) { + return Object.getPrototypeOf(value) + } else if (value.__proto__) { + return value.__proto__ + } else if (value.constructor) { + return value.constructor.prototype + } +} + +function diffChildren(a, b, patch, apply, index) { + var aChildren = a.children + var bChildren = reorder(aChildren, b.children) + + var aLen = aChildren.length + var bLen = bChildren.length + var len = aLen > bLen ? aLen : bLen + + for (var i = 0; i < len; i++) { + var leftNode = aChildren[i] + var rightNode = bChildren[i] + index += 1 + + if (!leftNode) { + if (rightNode) { + // Excess nodes in b need to be added + apply = appendPatch(apply, + new VPatch(VPatch.INSERT, null, rightNode)) + } + } else if (!rightNode) { + if (leftNode) { + // Excess nodes in a need to be removed + patch[index] = new VPatch(VPatch.REMOVE, leftNode, null) + destroyWidgets(leftNode, patch, index) + } + } else { + walk(leftNode, rightNode, patch, index) + } + + if (isVNode(leftNode) && leftNode.count) { + index += leftNode.count + } + } + + if (bChildren.moves) { + // Reorder nodes last + apply = appendPatch(apply, new VPatch(VPatch.ORDER, a, bChildren.moves)) + } + + return apply +} + +// Patch records for all destroyed widgets must be added because we need +// a DOM node reference for the destroy function +function destroyWidgets(vNode, patch, index) { + if (isWidget(vNode)) { + if (typeof vNode.destroy === "function") { + patch[index] = new VPatch(VPatch.REMOVE, vNode, null) + } + } else if (isVNode(vNode) && vNode.hasWidgets) { + var children = vNode.children + var len = children.length + for (var i = 0; i < len; i++) { + var child = children[i] + index += 1 + + destroyWidgets(child, patch, index) + + if (isVNode(child) && child.count) { + index += child.count + } + } + } +} + +// Create a sub-patch for thunks +function thunks(a, b, patch, index) { + var nodes = handleThunk(a, b); + var thunkPatch = diff(nodes.a, nodes.b) + if (hasPatches(thunkPatch)) { + patch[index] = new VPatch(VPatch.THUNK, null, thunkPatch) + } +} + +function hasPatches(patch) { + for (var index in patch) { + if (index !== "a") { + return true; + } + } + + return false; +} + +// Execute hooks when two nodes are identical +function hooks(vNode, patch, index) { + if (isVNode(vNode)) { + if (vNode.hooks) { + patch[index] = new VPatch(VPatch.PROPS, vNode.hooks, vNode.hooks) + } + + if (vNode.descendantHooks) { + var children = vNode.children + var len = children.length + for (var i = 0; i < len; i++) { + var child = children[i] + index += 1 + + hooks(child, patch, index) + + if (isVNode(child) && child.count) { + index += child.count + } + } + } + } +} + +// List diff, naive left to right reordering +function reorder(aChildren, bChildren) { + + var bKeys = keyIndex(bChildren) + + if (!bKeys) { + return bChildren + } + + var aKeys = keyIndex(aChildren) + + if (!aKeys) { + return bChildren + } + + var bMatch = {}, aMatch = {} + + for (var key in bKeys) { + bMatch[bKeys[key]] = aKeys[key] + } + + for (var key in aKeys) { + aMatch[aKeys[key]] = bKeys[key] + } + + var aLen = aChildren.length + var bLen = bChildren.length + var len = aLen > bLen ? aLen : bLen + var shuffle = [] + var freeIndex = 0 + var i = 0 + var moveIndex = 0 + var moves = {} + var removes = moves.removes = {} + var reverse = moves.reverse = {} + var hasMoves = false + + while (freeIndex < len) { + var move = aMatch[i] + if (move !== undefined) { + shuffle[i] = bChildren[move] + if (move !== moveIndex) { + moves[move] = moveIndex + reverse[moveIndex] = move + hasMoves = true + } + moveIndex++ + } else if (i in aMatch) { + shuffle[i] = undefined + removes[i] = moveIndex++ + hasMoves = true + } else { + while (bMatch[freeIndex] !== undefined) { + freeIndex++ + } + + if (freeIndex < len) { + var freeChild = bChildren[freeIndex] + if (freeChild) { + shuffle[i] = freeChild + if (freeIndex !== moveIndex) { + hasMoves = true + moves[freeIndex] = moveIndex + reverse[moveIndex] = freeIndex + } + moveIndex++ + } + freeIndex++ + } + } + i++ + } + + if (hasMoves) { + shuffle.moves = moves + } + + return shuffle +} + +function keyIndex(children) { + var i, keys + + for (i = 0; i < children.length; i++) { + var child = children[i] + + if (child.key !== undefined) { + keys = keys || {} + keys[child.key] = i + } + } + + return keys +} + +function appendPatch(apply, patch) { + if (apply) { + if (isArray(apply)) { + apply.push(patch) + } else { + apply = [apply, patch] + } + + return apply + } else { + return patch + } +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vtree/diff.js","/../../node_modules/virtual-dom/node_modules/vtree") +},{"./handle-thunk":49,"./is-thunk":50,"./is-vnode":52,"./is-vtext":53,"./is-widget":54,"./vpatch":56,"buffer":3,"is-object":40,"oMfpAn":7,"x-is-array":57}],49:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var isVNode = require("./is-vnode") +var isVText = require("./is-vtext") +var isWidget = require("./is-widget") +var isThunk = require("./is-thunk") + +module.exports = handleThunk + +function handleThunk(a, b) { + var renderedA = a + var renderedB = b + + if (isThunk(b)) { + renderedB = renderThunk(b, a) + } + + if (isThunk(a)) { + renderedA = renderThunk(a, null) + } + + return { + a: renderedA, + b: renderedB + } +} + +function renderThunk(thunk, previous) { + var renderedThunk = thunk.vnode + + if (!renderedThunk) { + renderedThunk = thunk.vnode = thunk.render(previous) + } + + if (!(isVNode(renderedThunk) || + isVText(renderedThunk) || + isWidget(renderedThunk))) { + throw new Error("thunk did not return a valid node"); + } + + return renderedThunk +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vtree/handle-thunk.js","/../../node_modules/virtual-dom/node_modules/vtree") +},{"./is-thunk":50,"./is-vnode":52,"./is-vtext":53,"./is-widget":54,"buffer":3,"oMfpAn":7}],50:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = isThunk + +function isThunk(t) { + return t && t.type === "Thunk" +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vtree/is-thunk.js","/../../node_modules/virtual-dom/node_modules/vtree") +},{"buffer":3,"oMfpAn":7}],51:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = isHook + +function isHook(hook) { + return hook && typeof hook.hook === "function" && + !hook.hasOwnProperty("hook") +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vtree/is-vhook.js","/../../node_modules/virtual-dom/node_modules/vtree") +},{"buffer":3,"oMfpAn":7}],52:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var version = require("./version") + +module.exports = isVirtualNode + +function isVirtualNode(x) { + return x && x.type === "VirtualNode" && x.version === version +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vtree/is-vnode.js","/../../node_modules/virtual-dom/node_modules/vtree") +},{"./version":55,"buffer":3,"oMfpAn":7}],53:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var version = require("./version") + +module.exports = isVirtualText + +function isVirtualText(x) { + return x && x.type === "VirtualText" && x.version === version +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vtree/is-vtext.js","/../../node_modules/virtual-dom/node_modules/vtree") +},{"./version":55,"buffer":3,"oMfpAn":7}],54:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = isWidget + +function isWidget(w) { + return w && w.type === "Widget" +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vtree/is-widget.js","/../../node_modules/virtual-dom/node_modules/vtree") +},{"buffer":3,"oMfpAn":7}],55:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = "1" + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vtree/version.js","/../../node_modules/virtual-dom/node_modules/vtree") +},{"buffer":3,"oMfpAn":7}],56:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var version = require("./version") + +VirtualPatch.NONE = 0 +VirtualPatch.VTEXT = 1 +VirtualPatch.VNODE = 2 +VirtualPatch.WIDGET = 3 +VirtualPatch.PROPS = 4 +VirtualPatch.ORDER = 5 +VirtualPatch.INSERT = 6 +VirtualPatch.REMOVE = 7 +VirtualPatch.THUNK = 8 + +module.exports = VirtualPatch + +function VirtualPatch(type, vNode, patch) { + this.type = Number(type) + this.vNode = vNode + this.patch = patch +} + +VirtualPatch.prototype.version = version +VirtualPatch.prototype.type = "VirtualPatch" + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/vtree/vpatch.js","/../../node_modules/virtual-dom/node_modules/vtree") +},{"./version":55,"buffer":3,"oMfpAn":7}],57:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var nativeIsArray = Array.isArray +var toString = Object.prototype.toString + +module.exports = nativeIsArray || isArray + +function isArray(obj) { + return toString.call(obj) === "[object Array]" +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/node_modules/x-is-array/index.js","/../../node_modules/virtual-dom/node_modules/x-is-array") +},{"buffer":3,"oMfpAn":7}],58:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var patch = require("vdom/patch") + +module.exports = patch + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-dom/patch.js","/../../node_modules/virtual-dom") +},{"buffer":3,"oMfpAn":7,"vdom/patch":46}],59:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = AttributeHook; + +function AttributeHook(value) { + if (!(this instanceof AttributeHook)) { + return new AttributeHook(value); + } + + this.value = value; +} + +AttributeHook.prototype.hook = function (node, prop, prev) { + if (prev && prev.value === this.value) { + return; + } + + node.setAttributeNS(null, prop, this.value) +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/hooks/attribute-hook.js","/../../node_modules/virtual-hyperscript/hooks") +},{"buffer":3,"oMfpAn":7}],60:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var DataSet = require("data-set") + +module.exports = DataSetHook; + +function DataSetHook(value) { + if (!(this instanceof DataSetHook)) { + return new DataSetHook(value); + } + + this.value = value; +} + +DataSetHook.prototype.hook = function (node, propertyName) { + var ds = DataSet(node) + var propName = propertyName.substr(5) + + ds[propName] = this.value; +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/hooks/data-set-hook.js","/../../node_modules/virtual-hyperscript/hooks") +},{"buffer":3,"data-set":65,"oMfpAn":7}],61:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var DataSet = require("data-set") + +module.exports = DataSetHook; + +function DataSetHook(value) { + if (!(this instanceof DataSetHook)) { + return new DataSetHook(value); + } + + this.value = value; +} + +DataSetHook.prototype.hook = function (node, propertyName) { + var ds = DataSet(node) + var propName = propertyName.substr(3) + + ds[propName] = this.value; +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/hooks/ev-hook.js","/../../node_modules/virtual-hyperscript/hooks") +},{"buffer":3,"data-set":65,"oMfpAn":7}],62:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = SoftSetHook; + +function SoftSetHook(value) { + if (!(this instanceof SoftSetHook)) { + return new SoftSetHook(value); + } + + this.value = value; +} + +SoftSetHook.prototype.hook = function (node, propertyName) { + if (node[propertyName] !== this.value) { + node[propertyName] = this.value; + } +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/hooks/soft-set-hook.js","/../../node_modules/virtual-hyperscript/hooks") +},{"buffer":3,"oMfpAn":7}],63:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var VNode = require("vtree/vnode.js") +var VText = require("vtree/vtext.js") +var isVNode = require("vtree/is-vnode") +var isVText = require("vtree/is-vtext") +var isWidget = require("vtree/is-widget") +var isHook = require("vtree/is-vhook") +var isVThunk = require("vtree/is-thunk") +var TypedError = require("error/typed") + +var parseTag = require("./parse-tag.js") +var softSetHook = require("./hooks/soft-set-hook.js") +var dataSetHook = require("./hooks/data-set-hook.js") +var evHook = require("./hooks/ev-hook.js") + +var UnexpectedVirtualElement = TypedError({ + type: "virtual-hyperscript.unexpected.virtual-element", + message: "Unexpected virtual child passed to h().\n" + + "Expected a VNode / Vthunk / VWidget / string but:\n" + + "got a {foreignObjectStr}.\n" + + "The parent vnode is {parentVnodeStr}.\n" + + "Suggested fix: change your `h(..., [ ... ])` callsite.", + foreignObjectStr: null, + parentVnodeStr: null, + foreignObject: null, + parentVnode: null +}) + +module.exports = h + +function h(tagName, properties, children) { + var childNodes = [] + var tag, props, key, namespace + + if (!children && isChildren(properties)) { + children = properties + props = {} + } + + props = props || properties || {} + tag = parseTag(tagName, props) + + // support keys + if ("key" in props) { + key = props.key + props.key = undefined + } + + // support namespace + if ("namespace" in props) { + namespace = props.namespace + props.namespace = undefined + } + + // fix cursor bug + if (tag === "input" && + "value" in props && + props.value !== undefined && + !isHook(props.value) + ) { + props.value = softSetHook(props.value) + } + + var keys = Object.keys(props) + var propName, value + for (var j = 0; j < keys.length; j++) { + propName = keys[j] + value = props[propName] + if (isHook(value)) { + continue + } + + // add data-foo support + if (propName.substr(0, 5) === "data-") { + props[propName] = dataSetHook(value) + } + + // add ev-foo support + if (propName.substr(0, 3) === "ev-") { + props[propName] = evHook(value) + } + } + + if (children !== undefined && children !== null) { + addChild(children, childNodes, tag, props) + } + + + var node = new VNode(tag, props, childNodes, key, namespace) + + return node +} + +function addChild(c, childNodes, tag, props) { + if (typeof c === "string") { + childNodes.push(new VText(c)) + } else if (isChild(c)) { + childNodes.push(c) + } else if (Array.isArray(c)) { + for (var i = 0; i < c.length; i++) { + addChild(c[i], childNodes, tag, props) + } + } else if (c === null || c === undefined) { + return + } else { + throw UnexpectedVirtualElement({ + foreignObjectStr: JSON.stringify(c), + foreignObject: c, + parentVnodeStr: JSON.stringify({ + tagName: tag, + properties: props + }), + parentVnode: { + tagName: tag, + properties: props + } + }) + } +} + +function isChild(x) { + return isVNode(x) || isVText(x) || isWidget(x) || isVThunk(x) +} + +function isChildren(x) { + return typeof x === "string" || Array.isArray(x) || isChild(x) +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/index.js","/../../node_modules/virtual-hyperscript") +},{"./hooks/data-set-hook.js":60,"./hooks/ev-hook.js":61,"./hooks/soft-set-hook.js":62,"./parse-tag.js":90,"buffer":3,"error/typed":81,"oMfpAn":7,"vtree/is-thunk":82,"vtree/is-vhook":83,"vtree/is-vnode":84,"vtree/is-vtext":85,"vtree/is-widget":86,"vtree/vnode.js":88,"vtree/vtext.js":89}],64:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = createHash + +function createHash(elem) { + var attributes = elem.attributes + var hash = {} + + if (attributes === null || attributes === undefined) { + return hash + } + + for (var i = 0; i < attributes.length; i++) { + var attr = attributes[i] + + if (attr.name.substr(0,5) !== "data-") { + continue + } + + hash[attr.name.substr(5)] = attr.value + } + + return hash +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/data-set/create-hash.js","/../../node_modules/virtual-hyperscript/node_modules/data-set") +},{"buffer":3,"oMfpAn":7}],65:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var createStore = require("weakmap-shim/create-store") +var Individual = require("individual") + +var createHash = require("./create-hash.js") + +var hashStore = Individual("__DATA_SET_WEAKMAP@3", createStore()) + +module.exports = DataSet + +function DataSet(elem) { + var store = hashStore(elem) + + if (!store.hash) { + store.hash = createHash(elem) + } + + return store.hash +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/data-set/index.js","/../../node_modules/virtual-hyperscript/node_modules/data-set") +},{"./create-hash.js":64,"buffer":3,"individual":66,"oMfpAn":7,"weakmap-shim/create-store":67}],66:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var root = typeof window !== 'undefined' ? + window : typeof global !== 'undefined' ? + global : {}; + +module.exports = Individual + +function Individual(key, value) { + if (root[key]) { + return root[key] + } + + Object.defineProperty(root, key, { + value: value + , configurable: true + }) + + return value +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/data-set/node_modules/individual/index.js","/../../node_modules/virtual-hyperscript/node_modules/data-set/node_modules/individual") +},{"buffer":3,"oMfpAn":7}],67:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var hiddenStore = require('./hidden-store.js'); + +module.exports = createStore; + +function createStore() { + var key = {}; + + return function (obj) { + if (typeof obj !== 'object' || obj === null) { + throw new Error('Weakmap-shim: Key must be object') + } + + var store = obj.valueOf(key); + return store && store.identity === key ? + store : hiddenStore(obj, key); + }; +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/data-set/node_modules/weakmap-shim/create-store.js","/../../node_modules/virtual-hyperscript/node_modules/data-set/node_modules/weakmap-shim") +},{"./hidden-store.js":68,"buffer":3,"oMfpAn":7}],68:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = hiddenStore; + +function hiddenStore(obj, key) { + var store = { identity: key }; + var valueOf = obj.valueOf; + + Object.defineProperty(obj, "valueOf", { + value: function (value) { + return value !== key ? + valueOf.apply(this, arguments) : store; + }, + writable: true + }); + + return store; +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/data-set/node_modules/weakmap-shim/hidden-store.js","/../../node_modules/virtual-hyperscript/node_modules/data-set/node_modules/weakmap-shim") +},{"buffer":3,"oMfpAn":7}],69:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// http://wiki.commonjs.org/wiki/Unit_Testing/1.0 +// +// THIS IS NOT TESTED NOR LIKELY TO WORK OUTSIDE V8! +// +// Originally from narwhal.js (http://narwhaljs.org) +// Copyright (c) 2009 Thomas Robinson <280north.com> +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the 'Software'), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN +// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// when used in node, this will actually load the util module we depend on +// versus loading the builtin util module as happens otherwise +// this is a bug in node module loading as far as I am concerned +var util = require('util/'); + +var pSlice = Array.prototype.slice; +var hasOwn = Object.prototype.hasOwnProperty; + +// 1. The assert module provides functions that throw +// AssertionError's when particular conditions are not met. The +// assert module must conform to the following interface. + +var assert = module.exports = ok; + +// 2. The AssertionError is defined in assert. +// new assert.AssertionError({ message: message, +// actual: actual, +// expected: expected }) + +assert.AssertionError = function AssertionError(options) { + this.name = 'AssertionError'; + this.actual = options.actual; + this.expected = options.expected; + this.operator = options.operator; + if (options.message) { + this.message = options.message; + this.generatedMessage = false; + } else { + this.message = getMessage(this); + this.generatedMessage = true; + } + var stackStartFunction = options.stackStartFunction || fail; + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, stackStartFunction); + } + else { + // non v8 browsers so we can have a stacktrace + var err = new Error(); + if (err.stack) { + var out = err.stack; + + // try to strip useless frames + var fn_name = stackStartFunction.name; + var idx = out.indexOf('\n' + fn_name); + if (idx >= 0) { + // once we have located the function frame + // we need to strip out everything before it (and its line) + var next_line = out.indexOf('\n', idx + 1); + out = out.substring(next_line + 1); + } + + this.stack = out; + } + } +}; + +// assert.AssertionError instanceof Error +util.inherits(assert.AssertionError, Error); + +function replacer(key, value) { + if (util.isUndefined(value)) { + return '' + value; + } + if (util.isNumber(value) && (isNaN(value) || !isFinite(value))) { + return value.toString(); + } + if (util.isFunction(value) || util.isRegExp(value)) { + return value.toString(); + } + return value; +} + +function truncate(s, n) { + if (util.isString(s)) { + return s.length < n ? s : s.slice(0, n); + } else { + return s; + } +} + +function getMessage(self) { + return truncate(JSON.stringify(self.actual, replacer), 128) + ' ' + + self.operator + ' ' + + truncate(JSON.stringify(self.expected, replacer), 128); +} + +// At present only the three keys mentioned above are used and +// understood by the spec. Implementations or sub modules can pass +// other keys to the AssertionError's constructor - they will be +// ignored. + +// 3. All of the following functions must throw an AssertionError +// when a corresponding condition is not met, with a message that +// may be undefined if not provided. All assertion methods provide +// both the actual and expected values to the assertion error for +// display purposes. + +function fail(actual, expected, message, operator, stackStartFunction) { + throw new assert.AssertionError({ + message: message, + actual: actual, + expected: expected, + operator: operator, + stackStartFunction: stackStartFunction + }); +} + +// EXTENSION! allows for well behaved errors defined elsewhere. +assert.fail = fail; + +// 4. Pure assertion tests whether a value is truthy, as determined +// by !!guard. +// assert.ok(guard, message_opt); +// This statement is equivalent to assert.equal(true, !!guard, +// message_opt);. To test strictly for the value true, use +// assert.strictEqual(true, guard, message_opt);. + +function ok(value, message) { + if (!value) fail(value, true, message, '==', assert.ok); +} +assert.ok = ok; + +// 5. The equality assertion tests shallow, coercive equality with +// ==. +// assert.equal(actual, expected, message_opt); + +assert.equal = function equal(actual, expected, message) { + if (actual != expected) fail(actual, expected, message, '==', assert.equal); +}; + +// 6. The non-equality assertion tests for whether two objects are not equal +// with != assert.notEqual(actual, expected, message_opt); + +assert.notEqual = function notEqual(actual, expected, message) { + if (actual == expected) { + fail(actual, expected, message, '!=', assert.notEqual); + } +}; + +// 7. The equivalence assertion tests a deep equality relation. +// assert.deepEqual(actual, expected, message_opt); + +assert.deepEqual = function deepEqual(actual, expected, message) { + if (!_deepEqual(actual, expected)) { + fail(actual, expected, message, 'deepEqual', assert.deepEqual); + } +}; + +function _deepEqual(actual, expected) { + // 7.1. All identical values are equivalent, as determined by ===. + if (actual === expected) { + return true; + + } else if (util.isBuffer(actual) && util.isBuffer(expected)) { + if (actual.length != expected.length) return false; + + for (var i = 0; i < actual.length; i++) { + if (actual[i] !== expected[i]) return false; + } + + return true; + + // 7.2. If the expected value is a Date object, the actual value is + // equivalent if it is also a Date object that refers to the same time. + } else if (util.isDate(actual) && util.isDate(expected)) { + return actual.getTime() === expected.getTime(); + + // 7.3 If the expected value is a RegExp object, the actual value is + // equivalent if it is also a RegExp object with the same source and + // properties (`global`, `multiline`, `lastIndex`, `ignoreCase`). + } else if (util.isRegExp(actual) && util.isRegExp(expected)) { + return actual.source === expected.source && + actual.global === expected.global && + actual.multiline === expected.multiline && + actual.lastIndex === expected.lastIndex && + actual.ignoreCase === expected.ignoreCase; + + // 7.4. Other pairs that do not both pass typeof value == 'object', + // equivalence is determined by ==. + } else if (!util.isObject(actual) && !util.isObject(expected)) { + return actual == expected; + + // 7.5 For all other Object pairs, including Array objects, equivalence is + // determined by having the same number of owned properties (as verified + // with Object.prototype.hasOwnProperty.call), the same set of keys + // (although not necessarily the same order), equivalent values for every + // corresponding key, and an identical 'prototype' property. Note: this + // accounts for both named and indexed properties on Arrays. + } else { + return objEquiv(actual, expected); + } +} + +function isArguments(object) { + return Object.prototype.toString.call(object) == '[object Arguments]'; +} + +function objEquiv(a, b) { + if (util.isNullOrUndefined(a) || util.isNullOrUndefined(b)) + return false; + // an identical 'prototype' property. + if (a.prototype !== b.prototype) return false; + //~~~I've managed to break Object.keys through screwy arguments passing. + // Converting to array solves the problem. + if (isArguments(a)) { + if (!isArguments(b)) { + return false; + } + a = pSlice.call(a); + b = pSlice.call(b); + return _deepEqual(a, b); + } + try { + var ka = objectKeys(a), + kb = objectKeys(b), + key, i; + } catch (e) {//happens when one is a string literal and the other isn't + return false; + } + // having the same number of owned properties (keys incorporates + // hasOwnProperty) + if (ka.length != kb.length) + return false; + //the same set of keys (although not necessarily the same order), + ka.sort(); + kb.sort(); + //~~~cheap key test + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) + return false; + } + //equivalent values for every corresponding key, and + //~~~possibly expensive deep test + for (i = ka.length - 1; i >= 0; i--) { + key = ka[i]; + if (!_deepEqual(a[key], b[key])) return false; + } + return true; +} + +// 8. The non-equivalence assertion tests for any deep inequality. +// assert.notDeepEqual(actual, expected, message_opt); + +assert.notDeepEqual = function notDeepEqual(actual, expected, message) { + if (_deepEqual(actual, expected)) { + fail(actual, expected, message, 'notDeepEqual', assert.notDeepEqual); + } +}; + +// 9. The strict equality assertion tests strict equality, as determined by ===. +// assert.strictEqual(actual, expected, message_opt); + +assert.strictEqual = function strictEqual(actual, expected, message) { + if (actual !== expected) { + fail(actual, expected, message, '===', assert.strictEqual); + } +}; + +// 10. The strict non-equality assertion tests for strict inequality, as +// determined by !==. assert.notStrictEqual(actual, expected, message_opt); + +assert.notStrictEqual = function notStrictEqual(actual, expected, message) { + if (actual === expected) { + fail(actual, expected, message, '!==', assert.notStrictEqual); + } +}; + +function expectedException(actual, expected) { + if (!actual || !expected) { + return false; + } + + if (Object.prototype.toString.call(expected) == '[object RegExp]') { + return expected.test(actual); + } else if (actual instanceof expected) { + return true; + } else if (expected.call({}, actual) === true) { + return true; + } + + return false; +} + +function _throws(shouldThrow, block, expected, message) { + var actual; + + if (util.isString(expected)) { + message = expected; + expected = null; + } + + try { + block(); + } catch (e) { + actual = e; + } + + message = (expected && expected.name ? ' (' + expected.name + ').' : '.') + + (message ? ' ' + message : '.'); + + if (shouldThrow && !actual) { + fail(actual, expected, 'Missing expected exception' + message); + } + + if (!shouldThrow && expectedException(actual, expected)) { + fail(actual, expected, 'Got unwanted exception' + message); + } + + if ((shouldThrow && actual && expected && + !expectedException(actual, expected)) || (!shouldThrow && actual)) { + throw actual; + } +} + +// 11. Expected to throw an error: +// assert.throws(block, Error_opt, message_opt); + +assert.throws = function(block, /*optional*/error, /*optional*/message) { + _throws.apply(this, [true].concat(pSlice.call(arguments))); +}; + +// EXTENSION! This is annoying to write outside this module. +assert.doesNotThrow = function(block, /*optional*/message) { + _throws.apply(this, [false].concat(pSlice.call(arguments))); +}; + +assert.ifError = function(err) { if (err) {throw err;}}; + +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (hasOwn.call(obj, key)) keys.push(key); + } + return keys; +}; + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/assert/assert.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/assert") +},{"buffer":3,"oMfpAn":7,"util/":72}],70:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +if (typeof Object.create === 'function') { + // implementation from standard node.js 'util' module + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + ctor.prototype = Object.create(superCtor.prototype, { + constructor: { + value: ctor, + enumerable: false, + writable: true, + configurable: true + } + }); + }; +} else { + // old school shim for old browsers + module.exports = function inherits(ctor, superCtor) { + ctor.super_ = superCtor + var TempCtor = function () {} + TempCtor.prototype = superCtor.prototype + ctor.prototype = new TempCtor() + ctor.prototype.constructor = ctor + } +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/assert/node_modules/util/node_modules/inherits/inherits_browser.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/assert/node_modules/util/node_modules/inherits") +},{"buffer":3,"oMfpAn":7}],71:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = function isBuffer(arg) { + return arg && typeof arg === 'object' + && typeof arg.copy === 'function' + && typeof arg.fill === 'function' + && typeof arg.readUInt8 === 'function'; +} +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/assert/node_modules/util/support/isBufferBrowser.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/assert/node_modules/util/support") +},{"buffer":3,"oMfpAn":7}],72:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. + +var formatRegExp = /%[sdj%]/g; +exports.format = function(f) { + if (!isString(f)) { + var objects = []; + for (var i = 0; i < arguments.length; i++) { + objects.push(inspect(arguments[i])); + } + return objects.join(' '); + } + + var i = 1; + var args = arguments; + var len = args.length; + var str = String(f).replace(formatRegExp, function(x) { + if (x === '%%') return '%'; + if (i >= len) return x; + switch (x) { + case '%s': return String(args[i++]); + case '%d': return Number(args[i++]); + case '%j': + try { + return JSON.stringify(args[i++]); + } catch (_) { + return '[Circular]'; + } + default: + return x; + } + }); + for (var x = args[i]; i < len; x = args[++i]) { + if (isNull(x) || !isObject(x)) { + str += ' ' + x; + } else { + str += ' ' + inspect(x); + } + } + return str; +}; + + +// Mark that a method should not be used. +// Returns a modified function which warns once by default. +// If --no-deprecation is set, then it is a no-op. +exports.deprecate = function(fn, msg) { + // Allow for deprecating things in the process of starting up. + if (isUndefined(global.process)) { + return function() { + return exports.deprecate(fn, msg).apply(this, arguments); + }; + } + + if (process.noDeprecation === true) { + return fn; + } + + var warned = false; + function deprecated() { + if (!warned) { + if (process.throwDeprecation) { + throw new Error(msg); + } else if (process.traceDeprecation) { + console.trace(msg); + } else { + console.error(msg); + } + warned = true; + } + return fn.apply(this, arguments); + } + + return deprecated; +}; + + +var debugs = {}; +var debugEnviron; +exports.debuglog = function(set) { + if (isUndefined(debugEnviron)) + debugEnviron = process.env.NODE_DEBUG || ''; + set = set.toUpperCase(); + if (!debugs[set]) { + if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) { + var pid = process.pid; + debugs[set] = function() { + var msg = exports.format.apply(exports, arguments); + console.error('%s %d: %s', set, pid, msg); + }; + } else { + debugs[set] = function() {}; + } + } + return debugs[set]; +}; + + +/** + * Echos the value of a value. Trys to print the value out + * in the best way possible given the different types. + * + * @param {Object} obj The object to print out. + * @param {Object} opts Optional options object that alters the output. + */ +/* legacy: obj, showHidden, depth, colors*/ +function inspect(obj, opts) { + // default options + var ctx = { + seen: [], + stylize: stylizeNoColor + }; + // legacy... + if (arguments.length >= 3) ctx.depth = arguments[2]; + if (arguments.length >= 4) ctx.colors = arguments[3]; + if (isBoolean(opts)) { + // legacy... + ctx.showHidden = opts; + } else if (opts) { + // got an "options" object + exports._extend(ctx, opts); + } + // set default options + if (isUndefined(ctx.showHidden)) ctx.showHidden = false; + if (isUndefined(ctx.depth)) ctx.depth = 2; + if (isUndefined(ctx.colors)) ctx.colors = false; + if (isUndefined(ctx.customInspect)) ctx.customInspect = true; + if (ctx.colors) ctx.stylize = stylizeWithColor; + return formatValue(ctx, obj, ctx.depth); +} +exports.inspect = inspect; + + +// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics +inspect.colors = { + 'bold' : [1, 22], + 'italic' : [3, 23], + 'underline' : [4, 24], + 'inverse' : [7, 27], + 'white' : [37, 39], + 'grey' : [90, 39], + 'black' : [30, 39], + 'blue' : [34, 39], + 'cyan' : [36, 39], + 'green' : [32, 39], + 'magenta' : [35, 39], + 'red' : [31, 39], + 'yellow' : [33, 39] +}; + +// Don't use 'blue' not visible on cmd.exe +inspect.styles = { + 'special': 'cyan', + 'number': 'yellow', + 'boolean': 'yellow', + 'undefined': 'grey', + 'null': 'bold', + 'string': 'green', + 'date': 'magenta', + // "name": intentionally not styling + 'regexp': 'red' +}; + + +function stylizeWithColor(str, styleType) { + var style = inspect.styles[styleType]; + + if (style) { + return '\u001b[' + inspect.colors[style][0] + 'm' + str + + '\u001b[' + inspect.colors[style][1] + 'm'; + } else { + return str; + } +} + + +function stylizeNoColor(str, styleType) { + return str; +} + + +function arrayToHash(array) { + var hash = {}; + + array.forEach(function(val, idx) { + hash[val] = true; + }); + + return hash; +} + + +function formatValue(ctx, value, recurseTimes) { + // Provide a hook for user-specified inspect functions. + // Check that value is an object with an inspect function on it + if (ctx.customInspect && + value && + isFunction(value.inspect) && + // Filter out the util module, it's inspect function is special + value.inspect !== exports.inspect && + // Also filter out any prototype objects using the circular check. + !(value.constructor && value.constructor.prototype === value)) { + var ret = value.inspect(recurseTimes, ctx); + if (!isString(ret)) { + ret = formatValue(ctx, ret, recurseTimes); + } + return ret; + } + + // Primitive types cannot have properties + var primitive = formatPrimitive(ctx, value); + if (primitive) { + return primitive; + } + + // Look up the keys of the object. + var keys = Object.keys(value); + var visibleKeys = arrayToHash(keys); + + if (ctx.showHidden) { + keys = Object.getOwnPropertyNames(value); + } + + // IE doesn't make error fields non-enumerable + // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx + if (isError(value) + && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) { + return formatError(value); + } + + // Some type of object without properties can be shortcutted. + if (keys.length === 0) { + if (isFunction(value)) { + var name = value.name ? ': ' + value.name : ''; + return ctx.stylize('[Function' + name + ']', 'special'); + } + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } + if (isDate(value)) { + return ctx.stylize(Date.prototype.toString.call(value), 'date'); + } + if (isError(value)) { + return formatError(value); + } + } + + var base = '', array = false, braces = ['{', '}']; + + // Make Array say that they are Array + if (isArray(value)) { + array = true; + braces = ['[', ']']; + } + + // Make functions say that they are functions + if (isFunction(value)) { + var n = value.name ? ': ' + value.name : ''; + base = ' [Function' + n + ']'; + } + + // Make RegExps say that they are RegExps + if (isRegExp(value)) { + base = ' ' + RegExp.prototype.toString.call(value); + } + + // Make dates with properties first say the date + if (isDate(value)) { + base = ' ' + Date.prototype.toUTCString.call(value); + } + + // Make error with message first say the error + if (isError(value)) { + base = ' ' + formatError(value); + } + + if (keys.length === 0 && (!array || value.length == 0)) { + return braces[0] + base + braces[1]; + } + + if (recurseTimes < 0) { + if (isRegExp(value)) { + return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); + } else { + return ctx.stylize('[Object]', 'special'); + } + } + + ctx.seen.push(value); + + var output; + if (array) { + output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); + } else { + output = keys.map(function(key) { + return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); + }); + } + + ctx.seen.pop(); + + return reduceToSingleString(output, base, braces); +} + + +function formatPrimitive(ctx, value) { + if (isUndefined(value)) + return ctx.stylize('undefined', 'undefined'); + if (isString(value)) { + var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') + .replace(/'/g, "\\'") + .replace(/\\"/g, '"') + '\''; + return ctx.stylize(simple, 'string'); + } + if (isNumber(value)) + return ctx.stylize('' + value, 'number'); + if (isBoolean(value)) + return ctx.stylize('' + value, 'boolean'); + // For some reason typeof null is "object", so special case here. + if (isNull(value)) + return ctx.stylize('null', 'null'); +} + + +function formatError(value) { + return '[' + Error.prototype.toString.call(value) + ']'; +} + + +function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { + var output = []; + for (var i = 0, l = value.length; i < l; ++i) { + if (hasOwnProperty(value, String(i))) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + String(i), true)); + } else { + output.push(''); + } + } + keys.forEach(function(key) { + if (!key.match(/^\d+$/)) { + output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, + key, true)); + } + }); + return output; +} + + +function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { + var name, str, desc; + desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] }; + if (desc.get) { + if (desc.set) { + str = ctx.stylize('[Getter/Setter]', 'special'); + } else { + str = ctx.stylize('[Getter]', 'special'); + } + } else { + if (desc.set) { + str = ctx.stylize('[Setter]', 'special'); + } + } + if (!hasOwnProperty(visibleKeys, key)) { + name = '[' + key + ']'; + } + if (!str) { + if (ctx.seen.indexOf(desc.value) < 0) { + if (isNull(recurseTimes)) { + str = formatValue(ctx, desc.value, null); + } else { + str = formatValue(ctx, desc.value, recurseTimes - 1); + } + if (str.indexOf('\n') > -1) { + if (array) { + str = str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n').substr(2); + } else { + str = '\n' + str.split('\n').map(function(line) { + return ' ' + line; + }).join('\n'); + } + } + } else { + str = ctx.stylize('[Circular]', 'special'); + } + } + if (isUndefined(name)) { + if (array && key.match(/^\d+$/)) { + return str; + } + name = JSON.stringify('' + key); + if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { + name = name.substr(1, name.length - 2); + name = ctx.stylize(name, 'name'); + } else { + name = name.replace(/'/g, "\\'") + .replace(/\\"/g, '"') + .replace(/(^"|"$)/g, "'"); + name = ctx.stylize(name, 'string'); + } + } + + return name + ': ' + str; +} + + +function reduceToSingleString(output, base, braces) { + var numLinesEst = 0; + var length = output.reduce(function(prev, cur) { + numLinesEst++; + if (cur.indexOf('\n') >= 0) numLinesEst++; + return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1; + }, 0); + + if (length > 60) { + return braces[0] + + (base === '' ? '' : base + '\n ') + + ' ' + + output.join(',\n ') + + ' ' + + braces[1]; + } + + return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; +} + + +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. +function isArray(ar) { + return Array.isArray(ar); +} +exports.isArray = isArray; + +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; + +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; + +function isNullOrUndefined(arg) { + return arg == null; +} +exports.isNullOrUndefined = isNullOrUndefined; + +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; + +function isString(arg) { + return typeof arg === 'string'; +} +exports.isString = isString; + +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; + +function isUndefined(arg) { + return arg === void 0; +} +exports.isUndefined = isUndefined; + +function isRegExp(re) { + return isObject(re) && objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; + +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; + +function isDate(d) { + return isObject(d) && objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; + +function isError(e) { + return isObject(e) && + (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; + +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; + +function isPrimitive(arg) { + return arg === null || + typeof arg === 'boolean' || + typeof arg === 'number' || + typeof arg === 'string' || + typeof arg === 'symbol' || // ES6 symbol + typeof arg === 'undefined'; +} +exports.isPrimitive = isPrimitive; + +exports.isBuffer = require('./support/isBuffer'); + +function objectToString(o) { + return Object.prototype.toString.call(o); +} + + +function pad(n) { + return n < 10 ? '0' + n.toString(10) : n.toString(10); +} + + +var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', + 'Oct', 'Nov', 'Dec']; + +// 26 Feb 16:19:34 +function timestamp() { + var d = new Date(); + var time = [pad(d.getHours()), + pad(d.getMinutes()), + pad(d.getSeconds())].join(':'); + return [d.getDate(), months[d.getMonth()], time].join(' '); +} + + +// log is just a thin wrapper to console.log that prepends a timestamp +exports.log = function() { + console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments)); +}; + + +/** + * Inherit the prototype methods from one constructor into another. + * + * The Function.prototype.inherits from lang.js rewritten as a standalone + * function (not on Function.prototype). NOTE: If this file is to be loaded + * during bootstrapping this function needs to be rewritten using some native + * functions as prototype setup using normal JavaScript does not work as + * expected during bootstrapping (see mirror.js in r114903). + * + * @param {function} ctor Constructor function which needs to inherit the + * prototype. + * @param {function} superCtor Constructor function to inherit prototype from. + */ +exports.inherits = require('inherits'); + +exports._extend = function(origin, add) { + // Don't do anything if add isn't an object + if (!add || !isObject(add)) return origin; + + var keys = Object.keys(add); + var i = keys.length; + while (i--) { + origin[keys[i]] = add[keys[i]]; + } + return origin; +}; + +function hasOwnProperty(obj, prop) { + return Object.prototype.hasOwnProperty.call(obj, prop); +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/assert/node_modules/util/util.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/assert/node_modules/util") +},{"./support/isBuffer":71,"buffer":3,"inherits":70,"oMfpAn":7}],73:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = function(obj) { + if (typeof obj === 'string') return camelCase(obj); + return walk(obj); +}; + +function walk (obj) { + if (!obj || typeof obj !== 'object') return obj; + if (isArray(obj)) return map(obj, walk); + return reduce(objectKeys(obj), function (acc, key) { + var camel = camelCase(key); + acc[camel] = walk(obj[key]); + return acc; + }, {}); +} + +function camelCase(str) { + return str.replace(/[_.-](\w|$)/g, function (_,x) { + return x.toUpperCase() + }); +} + +var isArray = Array.isArray || function (obj) { + return Object.prototype.toString.call(obj) === '[object Array]'; +}; + +var has = Object.prototype.hasOwnProperty; +var objectKeys = Object.keys || function (obj) { + var keys = []; + for (var key in obj) { + if (has.call(obj, key)) keys.push(key); + } + return keys; +}; + +function map (xs, f) { + if (xs.map) return xs.map(f); + var res = []; + for (var i = 0; i < xs.length; i++) { + res.push(f(xs[i], i)); + } + return res; +} + +function reduce (xs, f, acc) { + if (xs.reduce) return xs.reduce(f, acc); + for (var i = 0; i < xs.length; i++) { + acc = f(acc, xs[i], i); + } + return acc; +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/camelize/index.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/camelize") +},{"buffer":3,"oMfpAn":7}],74:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var nargs = /\{([0-9a-zA-Z]+)\}/g +var slice = Array.prototype.slice + +module.exports = template + +function template(string) { + var args + + if (arguments.length === 2 && typeof arguments[1] === "object") { + args = arguments[1] + } else { + args = slice.call(arguments, 1) + } + + if (!args || !args.hasOwnProperty) { + args = {} + } + + return string.replace(nargs, function replaceArg(match, i, index) { + var result + + if (string[index - 1] === "{" && + string[index + match.length] === "}") { + return i + } else { + result = args.hasOwnProperty(i) ? args[i] : null + if (result === null || result === undefined) { + return "" + } + + return result + } + }) +} +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/string-template/index.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/string-template") +},{"buffer":3,"oMfpAn":7}],75:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = hasKeys + +function hasKeys(source) { + return source !== null && + (typeof source === "object" || + typeof source === "function") +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend/has-keys.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend") +},{"buffer":3,"oMfpAn":7}],76:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var Keys = require("object-keys") +var hasKeys = require("./has-keys") + +module.exports = extend + +function extend(target) { + var sources = [].slice.call(arguments, 1) + + for (var i = 0; i < sources.length; i++) { + var source = sources[i] + + if (!hasKeys(source)) { + continue + } + + var keys = Keys(source) + + for (var j = 0; j < keys.length; j++) { + var name = keys[j] + target[name] = source[name] + } + } + + return target +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend/mutable.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend") +},{"./has-keys":75,"buffer":3,"oMfpAn":7,"object-keys":78}],77:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var hasOwn = Object.prototype.hasOwnProperty; +var toString = Object.prototype.toString; + +var isFunction = function (fn) { + var isFunc = (typeof fn === 'function' && !(fn instanceof RegExp)) || toString.call(fn) === '[object Function]'; + if (!isFunc && typeof window !== 'undefined') { + isFunc = fn === window.setTimeout || fn === window.alert || fn === window.confirm || fn === window.prompt; + } + return isFunc; +}; + +module.exports = function forEach(obj, fn) { + if (!isFunction(fn)) { + throw new TypeError('iterator must be a function'); + } + var i, k, + isString = typeof obj === 'string', + l = obj.length, + context = arguments.length > 2 ? arguments[2] : null; + if (l === +l) { + for (i = 0; i < l; i++) { + if (context === null) { + fn(isString ? obj.charAt(i) : obj[i], i, obj); + } else { + fn.call(context, isString ? obj.charAt(i) : obj[i], i, obj); + } + } + } else { + for (k in obj) { + if (hasOwn.call(obj, k)) { + if (context === null) { + fn(obj[k], k, obj); + } else { + fn.call(context, obj[k], k, obj); + } + } + } + } +}; + + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend/node_modules/object-keys/foreach.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend/node_modules/object-keys") +},{"buffer":3,"oMfpAn":7}],78:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = Object.keys || require('./shim'); + + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend/node_modules/object-keys/index.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend/node_modules/object-keys") +},{"./shim":80,"buffer":3,"oMfpAn":7}],79:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var toString = Object.prototype.toString; + +module.exports = function isArguments(value) { + var str = toString.call(value); + var isArguments = str === '[object Arguments]'; + if (!isArguments) { + isArguments = str !== '[object Array]' + && value !== null + && typeof value === 'object' + && typeof value.length === 'number' + && value.length >= 0 + && toString.call(value.callee) === '[object Function]'; + } + return isArguments; +}; + + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend/node_modules/object-keys/isArguments.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend/node_modules/object-keys") +},{"buffer":3,"oMfpAn":7}],80:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +(function () { + "use strict"; + + // modified from https://github.com/kriskowal/es5-shim + var has = Object.prototype.hasOwnProperty, + toString = Object.prototype.toString, + forEach = require('./foreach'), + isArgs = require('./isArguments'), + hasDontEnumBug = !({'toString': null}).propertyIsEnumerable('toString'), + hasProtoEnumBug = (function () {}).propertyIsEnumerable('prototype'), + dontEnums = [ + "toString", + "toLocaleString", + "valueOf", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "constructor" + ], + keysShim; + + keysShim = function keys(object) { + var isObject = object !== null && typeof object === 'object', + isFunction = toString.call(object) === '[object Function]', + isArguments = isArgs(object), + theKeys = []; + + if (!isObject && !isFunction && !isArguments) { + throw new TypeError("Object.keys called on a non-object"); + } + + if (isArguments) { + forEach(object, function (value) { + theKeys.push(value); + }); + } else { + var name, + skipProto = hasProtoEnumBug && isFunction; + + for (name in object) { + if (!(skipProto && name === 'prototype') && has.call(object, name)) { + theKeys.push(name); + } + } + } + + if (hasDontEnumBug) { + var ctor = object.constructor, + skipConstructor = ctor && ctor.prototype === object; + + forEach(dontEnums, function (dontEnum) { + if (!(skipConstructor && dontEnum === 'constructor') && has.call(object, dontEnum)) { + theKeys.push(dontEnum); + } + }); + } + return theKeys; + }; + + module.exports = keysShim; +}()); + + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend/node_modules/object-keys/shim.js","/../../node_modules/virtual-hyperscript/node_modules/error/node_modules/xtend/node_modules/object-keys") +},{"./foreach":77,"./isArguments":79,"buffer":3,"oMfpAn":7}],81:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var assert = require("assert/") +var camelize = require("camelize") +var template = require("string-template") +var extend = require("xtend/mutable") + +module.exports = TypedError + +function TypedError(args) { + assert(args, "args is required"); + assert(args.type, "args.type is required") + assert(args.message, "args.message is required") + + var message = args.message + + if (args.type && !args.name) { + var errorName = camelize(args.type) + "Error" + args.name = errorName[0].toUpperCase() + errorName.substr(1) + } + + createError.type = args.type; + createError._name = args.name; + + return createError; + + function createError(opts) { + var result = new Error() + + Object.defineProperty(result, "type", { + value: result.type, + enumerable: true, + writable: true, + configurable: true + }) + + var options = extend({}, args, opts) + + extend(result, options) + result.message = template(message, options) + + return result + } +} + + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/error/typed.js","/../../node_modules/virtual-hyperscript/node_modules/error") +},{"assert/":69,"buffer":3,"camelize":73,"oMfpAn":7,"string-template":74,"xtend/mutable":76}],82:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = isThunk + +function isThunk(t) { + return t && t.type === "Thunk" +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/vtree/is-thunk.js","/../../node_modules/virtual-hyperscript/node_modules/vtree") +},{"buffer":3,"oMfpAn":7}],83:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = isHook + +function isHook(hook) { + return hook && typeof hook.hook === "function" && + !hook.hasOwnProperty("hook") +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/vtree/is-vhook.js","/../../node_modules/virtual-hyperscript/node_modules/vtree") +},{"buffer":3,"oMfpAn":7}],84:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var version = require("./version") + +module.exports = isVirtualNode + +function isVirtualNode(x) { + return x && x.type === "VirtualNode" && x.version === version +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/vtree/is-vnode.js","/../../node_modules/virtual-hyperscript/node_modules/vtree") +},{"./version":87,"buffer":3,"oMfpAn":7}],85:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var version = require("./version") + +module.exports = isVirtualText + +function isVirtualText(x) { + return x && x.type === "VirtualText" && x.version === version +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/vtree/is-vtext.js","/../../node_modules/virtual-hyperscript/node_modules/vtree") +},{"./version":87,"buffer":3,"oMfpAn":7}],86:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = isWidget + +function isWidget(w) { + return w && w.type === "Widget" +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/vtree/is-widget.js","/../../node_modules/virtual-hyperscript/node_modules/vtree") +},{"buffer":3,"oMfpAn":7}],87:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +module.exports = "1" + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/vtree/version.js","/../../node_modules/virtual-hyperscript/node_modules/vtree") +},{"buffer":3,"oMfpAn":7}],88:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var version = require("./version") +var isVNode = require("./is-vnode") +var isWidget = require("./is-widget") +var isVHook = require("./is-vhook") + +module.exports = VirtualNode + +var noProperties = {} +var noChildren = [] + +function VirtualNode(tagName, properties, children, key, namespace) { + this.tagName = tagName + this.properties = properties || noProperties + this.children = children || noChildren + this.key = key != null ? String(key) : undefined + this.namespace = (typeof namespace === "string") ? namespace : null + + var count = (children && children.length) || 0 + var descendants = 0 + var hasWidgets = false + var descendantHooks = false + var hooks + + for (var propName in properties) { + if (properties.hasOwnProperty(propName)) { + var property = properties[propName] + if (isVHook(property)) { + if (!hooks) { + hooks = {} + } + + hooks[propName] = property + } + } + } + + for (var i = 0; i < count; i++) { + var child = children[i] + if (isVNode(child)) { + descendants += child.count || 0 + + if (!hasWidgets && child.hasWidgets) { + hasWidgets = true + } + + if (!descendantHooks && (child.hooks || child.descendantHooks)) { + descendantHooks = true + } + } else if (!hasWidgets && isWidget(child)) { + if (typeof child.destroy === "function") { + hasWidgets = true + } + } + } + + this.count = count + descendants + this.hasWidgets = hasWidgets + this.hooks = hooks + this.descendantHooks = descendantHooks +} + +VirtualNode.prototype.version = version +VirtualNode.prototype.type = "VirtualNode" + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/vtree/vnode.js","/../../node_modules/virtual-hyperscript/node_modules/vtree") +},{"./is-vhook":83,"./is-vnode":84,"./is-widget":86,"./version":87,"buffer":3,"oMfpAn":7}],89:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var version = require("./version") + +module.exports = VirtualText + +function VirtualText(text) { + this.text = String(text) +} + +VirtualText.prototype.version = version +VirtualText.prototype.type = "VirtualText" + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/node_modules/vtree/vtext.js","/../../node_modules/virtual-hyperscript/node_modules/vtree") +},{"./version":87,"buffer":3,"oMfpAn":7}],90:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var classIdSplit = /([\.#]?[a-zA-Z0-9_:-]+)/ +var notClassId = /^\.|#/ + +module.exports = parseTag + +function parseTag(tag, props) { + if (!tag) { + return "div" + } + + var noId = !("id" in props) + + var tagParts = tag.split(classIdSplit) + var tagName = null + + if (notClassId.test(tagParts[1])) { + tagName = "div" + } + + var classes, part, type, i + for (i = 0; i < tagParts.length; i++) { + part = tagParts[i] + + if (!part) { + continue + } + + type = part.charAt(0) + + if (!tagName) { + tagName = part + } else if (type === ".") { + classes = classes || [] + classes.push(part.substring(1, part.length)) + } else if (type === "#" && noId) { + props.id = part.substring(1, part.length) + } + } + + if (classes) { + if (props.className) { + classes.push(props.className) + } + + props.className = classes.join(" ") + } + + return tagName ? tagName.toLowerCase() : "div" +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/parse-tag.js","/../../node_modules/virtual-hyperscript") +},{"buffer":3,"oMfpAn":7}],91:[function(require,module,exports){ +(function (process,global,Buffer,__argument0,__argument1,__argument2,__argument3,__filename,__dirname){ +var attributeHook = require("./hooks/attribute-hook.js") +var h = require("./index.js") + +var BLACKLISTED_KEYS = { + "style": true, + "namespace": true, + "key": true +} +var SVG_NAMESPACE = "http://www.w3.org/2000/svg" + +module.exports = svg + +function svg(tagName, properties, children) { + if (!children && isChildren(properties)) { + children = properties + properties = {} + } + + properties = properties || {} + + // set namespace for svg + properties.namespace = SVG_NAMESPACE + + // for each key, if attribute & string, bool or number then + // convert it into a setAttribute hook + for (var key in properties) { + if (!properties.hasOwnProperty(key)) { + continue + } + + if (BLACKLISTED_KEYS[key]) { + continue + } + + var value = properties[key] + if (typeof value !== "string" && + typeof value !== "number" && + typeof value !== "boolean" + ) { + continue + } + + properties[key] = attributeHook(value) + } + + return h(tagName, properties, children) +} + +function isChildren(x) { + return typeof x === "string" || Array.isArray(x) +} + +}).call(this,require("oMfpAn"),typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("buffer").Buffer,arguments[3],arguments[4],arguments[5],arguments[6],"/../../node_modules/virtual-hyperscript/svg.js","/../../node_modules/virtual-hyperscript") +},{"./hooks/attribute-hook.js":59,"./index.js":63,"buffer":3,"oMfpAn":7}]},{},[1]) +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvYnVpbGQvc3JjL2Zha2VfYTU4MTMyZmMuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL2d1bHAtYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9ndWxwLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9pbmRleC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWIvYjY0LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9ndWxwLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvaWVlZTc1NC9pbmRleC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9ldmVudHMvZXZlbnRzLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9ndWxwLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHQvaW5kZXguanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL2h5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9icm93c2VyLXNwbGl0L2luZGV4LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvY2xhc3MtbGlzdC9pbmRleC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2NsYXNzLWxpc3Qvbm9kZV9tb2R1bGVzL2luZGV4b2YvaW5kZXguanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL2h5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldC9pbmRleC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2RhdGEtc2V0L25vZGVfbW9kdWxlcy9pbmRpdmlkdWFsL2luZGV4LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZGF0YS1zZXQvbm9kZV9tb2R1bGVzL2luZGl2aWR1YWwvbm9kZV9tb2R1bGVzL2dsb2JhbC9pbmRleC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2RhdGEtc2V0L25vZGVfbW9kdWxlcy93ZWFrbWFwL3dlYWttYXAuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3BhY2thZ2UuanNvbiIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvcngvZGlzdC9yeC5hbGwuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3J4L2Rpc3QvcngudGVzdGluZy5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvcngvcngubm9kZS5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvcnhtYXJibGVzL2NvbnRyb2xsZXJzL2lucHV0LWRpYWdyYW1zLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvY29udHJvbGxlcnMvb3V0cHV0LWRpYWdyYW0uanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy9jb250cm9sbGVycy9zZWxlY3RlZC1leGFtcGxlLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvY29udHJvbGxlcnMvdXRpbHMuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy9tb2RlbHMvYm9vbGVhbi1leGFtcGxlcy5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvcnhtYXJibGVzL21vZGVscy9jb21iaW5lLWV4YW1wbGVzLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvbW9kZWxzL2NvbmRpdGlvbmFsLWV4YW1wbGVzLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvbW9kZWxzL2V4YW1wbGVzLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvbW9kZWxzL2ZpbHRlci1leGFtcGxlcy5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvcnhtYXJibGVzL21vZGVscy9tYXRoLWV4YW1wbGVzLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvbW9kZWxzL3RyYW5zZm9ybS1leGFtcGxlcy5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvcnhtYXJibGVzL3ZpZXdzL2lucHV0LWRpYWdyYW0uanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy92aWV3cy9tYXJibGUuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy92aWV3cy9vcGVyYXRvci1ib3guanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy92aWV3cy9vcGVyYXRvcnMtbWVudS5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvcnhtYXJibGVzL3ZpZXdzL291dHB1dC1kaWFncmFtLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvdmlld3Mvc2FuZGJveC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvcnhtYXJibGVzL3ZpZXdzL3V0aWxzLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9jcmVhdGUtZWxlbWVudC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vZGlmZi5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL2lzLW9iamVjdC9pbmRleC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Zkb20vYXBwbHktcHJvcGVydGllcy5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Zkb20vY3JlYXRlLWVsZW1lbnQuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92ZG9tL2RvbS1pbmRleC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Zkb20vbm9kZV9tb2R1bGVzL2dsb2JhbC9kb2N1bWVudC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Zkb20vcGF0Y2gtb3AuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92ZG9tL3BhdGNoLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdmRvbS91cGRhdGUtd2lkZ2V0LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdnRyZWUvZGlmZi5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlL2hhbmRsZS10aHVuay5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlL2lzLXRodW5rLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdnRyZWUvaXMtdmhvb2suanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92dHJlZS9pcy12bm9kZS5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlL2lzLXZ0ZXh0LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdnRyZWUvaXMtd2lkZ2V0LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdnRyZWUvdmVyc2lvbi5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlL3ZwYXRjaC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3gtaXMtYXJyYXkvaW5kZXguanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL3BhdGNoLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L2hvb2tzL2F0dHJpYnV0ZS1ob29rLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L2hvb2tzL2RhdGEtc2V0LWhvb2suanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvaG9va3MvZXYtaG9vay5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ob29rcy9zb2Z0LXNldC1ob29rLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L2luZGV4LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldC9jcmVhdGUtaGFzaC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZGF0YS1zZXQvaW5kZXguanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2RhdGEtc2V0L25vZGVfbW9kdWxlcy9pbmRpdmlkdWFsL2luZGV4LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldC9ub2RlX21vZHVsZXMvd2Vha21hcC1zaGltL2NyZWF0ZS1zdG9yZS5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZGF0YS1zZXQvbm9kZV9tb2R1bGVzL3dlYWttYXAtc2hpbS9oaWRkZW4tc3RvcmUuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy9hc3NlcnQvYXNzZXJ0LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMvYXNzZXJ0L25vZGVfbW9kdWxlcy91dGlsL25vZGVfbW9kdWxlcy9pbmhlcml0cy9pbmhlcml0c19icm93c2VyLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMvYXNzZXJ0L25vZGVfbW9kdWxlcy91dGlsL3N1cHBvcnQvaXNCdWZmZXJCcm93c2VyLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMvYXNzZXJ0L25vZGVfbW9kdWxlcy91dGlsL3V0aWwuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy9jYW1lbGl6ZS9pbmRleC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL3N0cmluZy10ZW1wbGF0ZS9pbmRleC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL3h0ZW5kL2hhcy1rZXlzLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMveHRlbmQvbXV0YWJsZS5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL3h0ZW5kL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9mb3JlYWNoLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMveHRlbmQvbm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2luZGV4LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMveHRlbmQvbm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL2lzQXJndW1lbnRzLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMveHRlbmQvbm9kZV9tb2R1bGVzL29iamVjdC1rZXlzL3NoaW0uanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL3R5cGVkLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy92dHJlZS9pcy10aHVuay5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWUvaXMtdmhvb2suanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL3Z0cmVlL2lzLXZub2RlLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy92dHJlZS9pcy12dGV4dC5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWUvaXMtd2lkZ2V0LmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy92dHJlZS92ZXJzaW9uLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy92dHJlZS92bm9kZS5qcyIsIi9Vc2Vycy9hbWVkL0hvYmJ5L3J4bWFyYmxlcy9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWUvdnRleHQuanMiLCIvVXNlcnMvYW1lZC9Ib2JieS9yeG1hcmJsZXMvbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvcGFyc2UtdGFnLmpzIiwiL1VzZXJzL2FtZWQvSG9iYnkvcnhtYXJibGVzL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L3N2Zy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3QkE7QUFDQTtBQUNBOztBQ0ZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDdmxDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakpBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDckdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNYQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDNUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2xQQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwaFNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JmQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdIQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25OQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdVQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6TUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3JCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BHQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNyRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN0QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUZBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hEQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN2RkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzlFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1RBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDUEE7QUFDQTtBQUNBO0FBQ0E7O0FDSEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ0xBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDeEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25CQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFXQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pCQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzVrQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMzQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDSkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbEJBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaEVBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzdDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNSQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNUQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ1BBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNqRUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDWkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDbkRBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt0aHJvdyBuZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpfXZhciBmPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChmLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGYsZi5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgT3BlcmF0b3JzTWVudSwgUGFja2FnZSwgU2FuZGJveCwgb3BlcmF0b3JzTWVudUNvbnRhaW5lciwgcnhFbGVtZW50LCByeFZlcnNpb24sIHNhbmRib3hDb250YWluZXI7XG5cblNhbmRib3ggPSByZXF1aXJlKCdyeG1hcmJsZXMvdmlld3Mvc2FuZGJveCcpO1xuXG5PcGVyYXRvcnNNZW51ID0gcmVxdWlyZSgncnhtYXJibGVzL3ZpZXdzL29wZXJhdG9ycy1tZW51Jyk7XG5cblBhY2thZ2UgPSByZXF1aXJlKCdwYWNrYWdlLmpzb24nKTtcblxuc2FuZGJveENvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIjc2FuZGJveC1jb250YWluZXJcIik7XG5cbnNhbmRib3hDb250YWluZXIuaW5uZXJIVE1MID0gXCJcIjtcblxuc2FuZGJveENvbnRhaW5lci5hcHBlbmRDaGlsZChTYW5kYm94LnJlbmRlcigpKTtcblxub3BlcmF0b3JzTWVudUNvbnRhaW5lciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXCIub3BlcmF0b3JzLW1lbnUtY29udGFpbmVyXCIpO1xuXG5vcGVyYXRvcnNNZW51Q29udGFpbmVyLmFwcGVuZENoaWxkKE9wZXJhdG9yc01lbnUucmVuZGVyKCkpO1xuXG5kb2N1bWVudC5xdWVyeVNlbGVjdG9yKFwiI2FwcC12ZXJzaW9uXCIpLnRleHRDb250ZW50ID0gXCJ2XCIgKyBQYWNrYWdlLnZlcnNpb247XG5cbnJ4VmVyc2lvbiA9IFBhY2thZ2UuZGVwZW5kZW5jaWVzLnJ4LnJlcGxhY2UoLyh+fFxcXnxcXC5cXCspKi9nLCBcIlwiKTtcblxucnhFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihcIiNyeGpzLXZlcnNpb25cIik7XG5cbnJ4RWxlbWVudC50ZXh0Q29udGVudCA9IFwiUnhKUyB2XCIgKyByeFZlcnNpb247XG5cbnJ4RWxlbWVudC5ocmVmID0gXCJodHRwczovL2dpdGh1Yi5jb20vUmVhY3RpdmUtRXh0ZW5zaW9ucy9SeEpTL3RyZWUvdlwiICsgcnhWZXJzaW9uO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiL2Zha2VfYTU4MTMyZmMuanNcIixcIi9cIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2d1bHAtYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2d1bHAtYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLyohXG4gKiBUaGUgYnVmZmVyIG1vZHVsZSBmcm9tIG5vZGUuanMsIGZvciB0aGUgYnJvd3Nlci5cbiAqXG4gKiBAYXV0aG9yICAgRmVyb3NzIEFib3VraGFkaWplaCA8ZmVyb3NzQGZlcm9zcy5vcmc+IDxodHRwOi8vZmVyb3NzLm9yZz5cbiAqIEBsaWNlbnNlICBNSVRcbiAqL1xuXG52YXIgYmFzZTY0ID0gcmVxdWlyZSgnYmFzZTY0LWpzJylcbnZhciBpZWVlNzU0ID0gcmVxdWlyZSgnaWVlZTc1NCcpXG5cbmV4cG9ydHMuQnVmZmVyID0gQnVmZmVyXG5leHBvcnRzLlNsb3dCdWZmZXIgPSBCdWZmZXJcbmV4cG9ydHMuSU5TUEVDVF9NQVhfQllURVMgPSA1MFxuQnVmZmVyLnBvb2xTaXplID0gODE5MlxuXG4vKipcbiAqIElmIGBCdWZmZXIuX3VzZVR5cGVkQXJyYXlzYDpcbiAqICAgPT09IHRydWUgICAgVXNlIFVpbnQ4QXJyYXkgaW1wbGVtZW50YXRpb24gKGZhc3Rlc3QpXG4gKiAgID09PSBmYWxzZSAgIFVzZSBPYmplY3QgaW1wbGVtZW50YXRpb24gKGNvbXBhdGlibGUgZG93biB0byBJRTYpXG4gKi9cbkJ1ZmZlci5fdXNlVHlwZWRBcnJheXMgPSAoZnVuY3Rpb24gKCkge1xuICAvLyBEZXRlY3QgaWYgYnJvd3NlciBzdXBwb3J0cyBUeXBlZCBBcnJheXMuIFN1cHBvcnRlZCBicm93c2VycyBhcmUgSUUgMTArLCBGaXJlZm94IDQrLFxuICAvLyBDaHJvbWUgNyssIFNhZmFyaSA1LjErLCBPcGVyYSAxMS42KywgaU9TIDQuMisuIElmIHRoZSBicm93c2VyIGRvZXMgbm90IHN1cHBvcnQgYWRkaW5nXG4gIC8vIHByb3BlcnRpZXMgdG8gYFVpbnQ4QXJyYXlgIGluc3RhbmNlcywgdGhlbiB0aGF0J3MgdGhlIHNhbWUgYXMgbm8gYFVpbnQ4QXJyYXlgIHN1cHBvcnRcbiAgLy8gYmVjYXVzZSB3ZSBuZWVkIHRvIGJlIGFibGUgdG8gYWRkIGFsbCB0aGUgbm9kZSBCdWZmZXIgQVBJIG1ldGhvZHMuIFRoaXMgaXMgYW4gaXNzdWVcbiAgLy8gaW4gRmlyZWZveCA0LTI5LiBOb3cgZml4ZWQ6IGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTY5NTQzOFxuICB0cnkge1xuICAgIHZhciBidWYgPSBuZXcgQXJyYXlCdWZmZXIoMClcbiAgICB2YXIgYXJyID0gbmV3IFVpbnQ4QXJyYXkoYnVmKVxuICAgIGFyci5mb28gPSBmdW5jdGlvbiAoKSB7IHJldHVybiA0MiB9XG4gICAgcmV0dXJuIDQyID09PSBhcnIuZm9vKCkgJiZcbiAgICAgICAgdHlwZW9mIGFyci5zdWJhcnJheSA9PT0gJ2Z1bmN0aW9uJyAvLyBDaHJvbWUgOS0xMCBsYWNrIGBzdWJhcnJheWBcbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiBmYWxzZVxuICB9XG59KSgpXG5cbi8qKlxuICogQ2xhc3M6IEJ1ZmZlclxuICogPT09PT09PT09PT09PVxuICpcbiAqIFRoZSBCdWZmZXIgY29uc3RydWN0b3IgcmV0dXJucyBpbnN0YW5jZXMgb2YgYFVpbnQ4QXJyYXlgIHRoYXQgYXJlIGF1Z21lbnRlZFxuICogd2l0aCBmdW5jdGlvbiBwcm9wZXJ0aWVzIGZvciBhbGwgdGhlIG5vZGUgYEJ1ZmZlcmAgQVBJIGZ1bmN0aW9ucy4gV2UgdXNlXG4gKiBgVWludDhBcnJheWAgc28gdGhhdCBzcXVhcmUgYnJhY2tldCBub3RhdGlvbiB3b3JrcyBhcyBleHBlY3RlZCAtLSBpdCByZXR1cm5zXG4gKiBhIHNpbmdsZSBvY3RldC5cbiAqXG4gKiBCeSBhdWdtZW50aW5nIHRoZSBpbnN0YW5jZXMsIHdlIGNhbiBhdm9pZCBtb2RpZnlpbmcgdGhlIGBVaW50OEFycmF5YFxuICogcHJvdG90eXBlLlxuICovXG5mdW5jdGlvbiBCdWZmZXIgKHN1YmplY3QsIGVuY29kaW5nLCBub1plcm8pIHtcbiAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEJ1ZmZlcikpXG4gICAgcmV0dXJuIG5ldyBCdWZmZXIoc3ViamVjdCwgZW5jb2RpbmcsIG5vWmVybylcblxuICB2YXIgdHlwZSA9IHR5cGVvZiBzdWJqZWN0XG5cbiAgLy8gV29ya2Fyb3VuZDogbm9kZSdzIGJhc2U2NCBpbXBsZW1lbnRhdGlvbiBhbGxvd3MgZm9yIG5vbi1wYWRkZWQgc3RyaW5nc1xuICAvLyB3aGlsZSBiYXNlNjQtanMgZG9lcyBub3QuXG4gIGlmIChlbmNvZGluZyA9PT0gJ2Jhc2U2NCcgJiYgdHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBzdWJqZWN0ID0gc3RyaW5ndHJpbShzdWJqZWN0KVxuICAgIHdoaWxlIChzdWJqZWN0Lmxlbmd0aCAlIDQgIT09IDApIHtcbiAgICAgIHN1YmplY3QgPSBzdWJqZWN0ICsgJz0nXG4gICAgfVxuICB9XG5cbiAgLy8gRmluZCB0aGUgbGVuZ3RoXG4gIHZhciBsZW5ndGhcbiAgaWYgKHR5cGUgPT09ICdudW1iZXInKVxuICAgIGxlbmd0aCA9IGNvZXJjZShzdWJqZWN0KVxuICBlbHNlIGlmICh0eXBlID09PSAnc3RyaW5nJylcbiAgICBsZW5ndGggPSBCdWZmZXIuYnl0ZUxlbmd0aChzdWJqZWN0LCBlbmNvZGluZylcbiAgZWxzZSBpZiAodHlwZSA9PT0gJ29iamVjdCcpXG4gICAgbGVuZ3RoID0gY29lcmNlKHN1YmplY3QubGVuZ3RoKSAvLyBhc3N1bWUgdGhhdCBvYmplY3QgaXMgYXJyYXktbGlrZVxuICBlbHNlXG4gICAgdGhyb3cgbmV3IEVycm9yKCdGaXJzdCBhcmd1bWVudCBuZWVkcyB0byBiZSBhIG51bWJlciwgYXJyYXkgb3Igc3RyaW5nLicpXG5cbiAgdmFyIGJ1ZlxuICBpZiAoQnVmZmVyLl91c2VUeXBlZEFycmF5cykge1xuICAgIC8vIFByZWZlcnJlZDogUmV0dXJuIGFuIGF1Z21lbnRlZCBgVWludDhBcnJheWAgaW5zdGFuY2UgZm9yIGJlc3QgcGVyZm9ybWFuY2VcbiAgICBidWYgPSBCdWZmZXIuX2F1Z21lbnQobmV3IFVpbnQ4QXJyYXkobGVuZ3RoKSlcbiAgfSBlbHNlIHtcbiAgICAvLyBGYWxsYmFjazogUmV0dXJuIFRISVMgaW5zdGFuY2Ugb2YgQnVmZmVyIChjcmVhdGVkIGJ5IGBuZXdgKVxuICAgIGJ1ZiA9IHRoaXNcbiAgICBidWYubGVuZ3RoID0gbGVuZ3RoXG4gICAgYnVmLl9pc0J1ZmZlciA9IHRydWVcbiAgfVxuXG4gIHZhciBpXG4gIGlmIChCdWZmZXIuX3VzZVR5cGVkQXJyYXlzICYmIHR5cGVvZiBzdWJqZWN0LmJ5dGVMZW5ndGggPT09ICdudW1iZXInKSB7XG4gICAgLy8gU3BlZWQgb3B0aW1pemF0aW9uIC0tIHVzZSBzZXQgaWYgd2UncmUgY29weWluZyBmcm9tIGEgdHlwZWQgYXJyYXlcbiAgICBidWYuX3NldChzdWJqZWN0KVxuICB9IGVsc2UgaWYgKGlzQXJyYXlpc2goc3ViamVjdCkpIHtcbiAgICAvLyBUcmVhdCBhcnJheS1pc2ggb2JqZWN0cyBhcyBhIGJ5dGUgYXJyYXlcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChCdWZmZXIuaXNCdWZmZXIoc3ViamVjdCkpXG4gICAgICAgIGJ1ZltpXSA9IHN1YmplY3QucmVhZFVJbnQ4KGkpXG4gICAgICBlbHNlXG4gICAgICAgIGJ1ZltpXSA9IHN1YmplY3RbaV1cbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ3N0cmluZycpIHtcbiAgICBidWYud3JpdGUoc3ViamVjdCwgMCwgZW5jb2RpbmcpXG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gJ251bWJlcicgJiYgIUJ1ZmZlci5fdXNlVHlwZWRBcnJheXMgJiYgIW5vWmVybykge1xuICAgIGZvciAoaSA9IDA7IGkgPCBsZW5ndGg7IGkrKykge1xuICAgICAgYnVmW2ldID0gMFxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBidWZcbn1cblxuLy8gU1RBVElDIE1FVEhPRFNcbi8vID09PT09PT09PT09PT09XG5cbkJ1ZmZlci5pc0VuY29kaW5nID0gZnVuY3Rpb24gKGVuY29kaW5nKSB7XG4gIHN3aXRjaCAoU3RyaW5nKGVuY29kaW5nKS50b0xvd2VyQ2FzZSgpKSB7XG4gICAgY2FzZSAnaGV4JzpcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgY2FzZSAnYXNjaWknOlxuICAgIGNhc2UgJ2JpbmFyeSc6XG4gICAgY2FzZSAnYmFzZTY0JzpcbiAgICBjYXNlICdyYXcnOlxuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXR1cm4gdHJ1ZVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG5CdWZmZXIuaXNCdWZmZXIgPSBmdW5jdGlvbiAoYikge1xuICByZXR1cm4gISEoYiAhPT0gbnVsbCAmJiBiICE9PSB1bmRlZmluZWQgJiYgYi5faXNCdWZmZXIpXG59XG5cbkJ1ZmZlci5ieXRlTGVuZ3RoID0gZnVuY3Rpb24gKHN0ciwgZW5jb2RpbmcpIHtcbiAgdmFyIHJldFxuICBzdHIgPSBzdHIgKyAnJ1xuICBzd2l0Y2ggKGVuY29kaW5nIHx8ICd1dGY4Jykge1xuICAgIGNhc2UgJ2hleCc6XG4gICAgICByZXQgPSBzdHIubGVuZ3RoIC8gMlxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1dGY4JzpcbiAgICBjYXNlICd1dGYtOCc6XG4gICAgICByZXQgPSB1dGY4VG9CeXRlcyhzdHIpLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBjYXNlICdhc2NpaSc6XG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICBjYXNlICdyYXcnOlxuICAgICAgcmV0ID0gc3RyLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gYmFzZTY0VG9CeXRlcyhzdHIpLmxlbmd0aFxuICAgICAgYnJlYWtcbiAgICBjYXNlICd1Y3MyJzpcbiAgICBjYXNlICd1Y3MtMic6XG4gICAgY2FzZSAndXRmMTZsZSc6XG4gICAgY2FzZSAndXRmLTE2bGUnOlxuICAgICAgcmV0ID0gc3RyLmxlbmd0aCAqIDJcbiAgICAgIGJyZWFrXG4gICAgZGVmYXVsdDpcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5rbm93biBlbmNvZGluZycpXG4gIH1cbiAgcmV0dXJuIHJldFxufVxuXG5CdWZmZXIuY29uY2F0ID0gZnVuY3Rpb24gKGxpc3QsIHRvdGFsTGVuZ3RoKSB7XG4gIGFzc2VydChpc0FycmF5KGxpc3QpLCAnVXNhZ2U6IEJ1ZmZlci5jb25jYXQobGlzdCwgW3RvdGFsTGVuZ3RoXSlcXG4nICtcbiAgICAgICdsaXN0IHNob3VsZCBiZSBhbiBBcnJheS4nKVxuXG4gIGlmIChsaXN0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBuZXcgQnVmZmVyKDApXG4gIH0gZWxzZSBpZiAobGlzdC5sZW5ndGggPT09IDEpIHtcbiAgICByZXR1cm4gbGlzdFswXVxuICB9XG5cbiAgdmFyIGlcbiAgaWYgKHR5cGVvZiB0b3RhbExlbmd0aCAhPT0gJ251bWJlcicpIHtcbiAgICB0b3RhbExlbmd0aCA9IDBcbiAgICBmb3IgKGkgPSAwOyBpIDwgbGlzdC5sZW5ndGg7IGkrKykge1xuICAgICAgdG90YWxMZW5ndGggKz0gbGlzdFtpXS5sZW5ndGhcbiAgICB9XG4gIH1cblxuICB2YXIgYnVmID0gbmV3IEJ1ZmZlcih0b3RhbExlbmd0aClcbiAgdmFyIHBvcyA9IDBcbiAgZm9yIChpID0gMDsgaSA8IGxpc3QubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgaXRlbSA9IGxpc3RbaV1cbiAgICBpdGVtLmNvcHkoYnVmLCBwb3MpXG4gICAgcG9zICs9IGl0ZW0ubGVuZ3RoXG4gIH1cbiAgcmV0dXJuIGJ1ZlxufVxuXG4vLyBCVUZGRVIgSU5TVEFOQ0UgTUVUSE9EU1xuLy8gPT09PT09PT09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gX2hleFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gYnVmLmxlbmd0aCAtIG9mZnNldFxuICBpZiAoIWxlbmd0aCkge1xuICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICB9IGVsc2Uge1xuICAgIGxlbmd0aCA9IE51bWJlcihsZW5ndGgpXG4gICAgaWYgKGxlbmd0aCA+IHJlbWFpbmluZykge1xuICAgICAgbGVuZ3RoID0gcmVtYWluaW5nXG4gICAgfVxuICB9XG5cbiAgLy8gbXVzdCBiZSBhbiBldmVuIG51bWJlciBvZiBkaWdpdHNcbiAgdmFyIHN0ckxlbiA9IHN0cmluZy5sZW5ndGhcbiAgYXNzZXJ0KHN0ckxlbiAlIDIgPT09IDAsICdJbnZhbGlkIGhleCBzdHJpbmcnKVxuXG4gIGlmIChsZW5ndGggPiBzdHJMZW4gLyAyKSB7XG4gICAgbGVuZ3RoID0gc3RyTGVuIC8gMlxuICB9XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYnl0ZSA9IHBhcnNlSW50KHN0cmluZy5zdWJzdHIoaSAqIDIsIDIpLCAxNilcbiAgICBhc3NlcnQoIWlzTmFOKGJ5dGUpLCAnSW52YWxpZCBoZXggc3RyaW5nJylcbiAgICBidWZbb2Zmc2V0ICsgaV0gPSBieXRlXG4gIH1cbiAgQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPSBpICogMlxuICByZXR1cm4gaVxufVxuXG5mdW5jdGlvbiBfdXRmOFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKHV0ZjhUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuZnVuY3Rpb24gX2FzY2lpV3JpdGUgKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgY2hhcnNXcml0dGVuID0gQnVmZmVyLl9jaGFyc1dyaXR0ZW4gPVxuICAgIGJsaXRCdWZmZXIoYXNjaWlUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuZnVuY3Rpb24gX2JpbmFyeVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgcmV0dXJuIF9hc2NpaVdyaXRlKGJ1Ziwgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbn1cblxuZnVuY3Rpb24gX2Jhc2U2NFdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKGJhc2U2NFRvQnl0ZXMoc3RyaW5nKSwgYnVmLCBvZmZzZXQsIGxlbmd0aClcbiAgcmV0dXJuIGNoYXJzV3JpdHRlblxufVxuXG5mdW5jdGlvbiBfdXRmMTZsZVdyaXRlIChidWYsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpIHtcbiAgdmFyIGNoYXJzV3JpdHRlbiA9IEJ1ZmZlci5fY2hhcnNXcml0dGVuID1cbiAgICBibGl0QnVmZmVyKHV0ZjE2bGVUb0J5dGVzKHN0cmluZyksIGJ1Ziwgb2Zmc2V0LCBsZW5ndGgpXG4gIHJldHVybiBjaGFyc1dyaXR0ZW5cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZSA9IGZ1bmN0aW9uIChzdHJpbmcsIG9mZnNldCwgbGVuZ3RoLCBlbmNvZGluZykge1xuICAvLyBTdXBwb3J0IGJvdGggKHN0cmluZywgb2Zmc2V0LCBsZW5ndGgsIGVuY29kaW5nKVxuICAvLyBhbmQgdGhlIGxlZ2FjeSAoc3RyaW5nLCBlbmNvZGluZywgb2Zmc2V0LCBsZW5ndGgpXG4gIGlmIChpc0Zpbml0ZShvZmZzZXQpKSB7XG4gICAgaWYgKCFpc0Zpbml0ZShsZW5ndGgpKSB7XG4gICAgICBlbmNvZGluZyA9IGxlbmd0aFxuICAgICAgbGVuZ3RoID0gdW5kZWZpbmVkXG4gICAgfVxuICB9IGVsc2UgeyAgLy8gbGVnYWN5XG4gICAgdmFyIHN3YXAgPSBlbmNvZGluZ1xuICAgIGVuY29kaW5nID0gb2Zmc2V0XG4gICAgb2Zmc2V0ID0gbGVuZ3RoXG4gICAgbGVuZ3RoID0gc3dhcFxuICB9XG5cbiAgb2Zmc2V0ID0gTnVtYmVyKG9mZnNldCkgfHwgMFxuICB2YXIgcmVtYWluaW5nID0gdGhpcy5sZW5ndGggLSBvZmZzZXRcbiAgaWYgKCFsZW5ndGgpIHtcbiAgICBsZW5ndGggPSByZW1haW5pbmdcbiAgfSBlbHNlIHtcbiAgICBsZW5ndGggPSBOdW1iZXIobGVuZ3RoKVxuICAgIGlmIChsZW5ndGggPiByZW1haW5pbmcpIHtcbiAgICAgIGxlbmd0aCA9IHJlbWFpbmluZ1xuICAgIH1cbiAgfVxuICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKClcblxuICB2YXIgcmV0XG4gIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0ID0gX2hleFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldCA9IF91dGY4V3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYXNjaWknOlxuICAgICAgcmV0ID0gX2FzY2lpV3JpdGUodGhpcywgc3RyaW5nLCBvZmZzZXQsIGxlbmd0aClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldCA9IF9iaW5hcnlXcml0ZSh0aGlzLCBzdHJpbmcsIG9mZnNldCwgbGVuZ3RoKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gX2Jhc2U2NFdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXQgPSBfdXRmMTZsZVdyaXRlKHRoaXMsIHN0cmluZywgb2Zmc2V0LCBsZW5ndGgpXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uIChlbmNvZGluZywgc3RhcnQsIGVuZCkge1xuICB2YXIgc2VsZiA9IHRoaXNcblxuICBlbmNvZGluZyA9IFN0cmluZyhlbmNvZGluZyB8fCAndXRmOCcpLnRvTG93ZXJDYXNlKClcbiAgc3RhcnQgPSBOdW1iZXIoc3RhcnQpIHx8IDBcbiAgZW5kID0gKGVuZCAhPT0gdW5kZWZpbmVkKVxuICAgID8gTnVtYmVyKGVuZClcbiAgICA6IGVuZCA9IHNlbGYubGVuZ3RoXG5cbiAgLy8gRmFzdHBhdGggZW1wdHkgc3RyaW5nc1xuICBpZiAoZW5kID09PSBzdGFydClcbiAgICByZXR1cm4gJydcblxuICB2YXIgcmV0XG4gIHN3aXRjaCAoZW5jb2RpbmcpIHtcbiAgICBjYXNlICdoZXgnOlxuICAgICAgcmV0ID0gX2hleFNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3V0ZjgnOlxuICAgIGNhc2UgJ3V0Zi04JzpcbiAgICAgIHJldCA9IF91dGY4U2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYXNjaWknOlxuICAgICAgcmV0ID0gX2FzY2lpU2xpY2Uoc2VsZiwgc3RhcnQsIGVuZClcbiAgICAgIGJyZWFrXG4gICAgY2FzZSAnYmluYXJ5JzpcbiAgICAgIHJldCA9IF9iaW5hcnlTbGljZShzZWxmLCBzdGFydCwgZW5kKVxuICAgICAgYnJlYWtcbiAgICBjYXNlICdiYXNlNjQnOlxuICAgICAgcmV0ID0gX2Jhc2U2NFNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGNhc2UgJ3VjczInOlxuICAgIGNhc2UgJ3Vjcy0yJzpcbiAgICBjYXNlICd1dGYxNmxlJzpcbiAgICBjYXNlICd1dGYtMTZsZSc6XG4gICAgICByZXQgPSBfdXRmMTZsZVNsaWNlKHNlbGYsIHN0YXJ0LCBlbmQpXG4gICAgICBicmVha1xuICAgIGRlZmF1bHQ6XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1Vua25vd24gZW5jb2RpbmcnKVxuICB9XG4gIHJldHVybiByZXRcbn1cblxuQnVmZmVyLnByb3RvdHlwZS50b0pTT04gPSBmdW5jdGlvbiAoKSB7XG4gIHJldHVybiB7XG4gICAgdHlwZTogJ0J1ZmZlcicsXG4gICAgZGF0YTogQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwodGhpcy5fYXJyIHx8IHRoaXMsIDApXG4gIH1cbn1cblxuLy8gY29weSh0YXJnZXRCdWZmZXIsIHRhcmdldFN0YXJ0PTAsIHNvdXJjZVN0YXJ0PTAsIHNvdXJjZUVuZD1idWZmZXIubGVuZ3RoKVxuQnVmZmVyLnByb3RvdHlwZS5jb3B5ID0gZnVuY3Rpb24gKHRhcmdldCwgdGFyZ2V0X3N0YXJ0LCBzdGFydCwgZW5kKSB7XG4gIHZhciBzb3VyY2UgPSB0aGlzXG5cbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kICYmIGVuZCAhPT0gMCkgZW5kID0gdGhpcy5sZW5ndGhcbiAgaWYgKCF0YXJnZXRfc3RhcnQpIHRhcmdldF9zdGFydCA9IDBcblxuICAvLyBDb3B5IDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGFyZ2V0Lmxlbmd0aCA9PT0gMCB8fCBzb3VyY2UubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAvLyBGYXRhbCBlcnJvciBjb25kaXRpb25zXG4gIGFzc2VydChlbmQgPj0gc3RhcnQsICdzb3VyY2VFbmQgPCBzb3VyY2VTdGFydCcpXG4gIGFzc2VydCh0YXJnZXRfc3RhcnQgPj0gMCAmJiB0YXJnZXRfc3RhcnQgPCB0YXJnZXQubGVuZ3RoLFxuICAgICAgJ3RhcmdldFN0YXJ0IG91dCBvZiBib3VuZHMnKVxuICBhc3NlcnQoc3RhcnQgPj0gMCAmJiBzdGFydCA8IHNvdXJjZS5sZW5ndGgsICdzb3VyY2VTdGFydCBvdXQgb2YgYm91bmRzJylcbiAgYXNzZXJ0KGVuZCA+PSAwICYmIGVuZCA8PSBzb3VyY2UubGVuZ3RoLCAnc291cmNlRW5kIG91dCBvZiBib3VuZHMnKVxuXG4gIC8vIEFyZSB3ZSBvb2I/XG4gIGlmIChlbmQgPiB0aGlzLmxlbmd0aClcbiAgICBlbmQgPSB0aGlzLmxlbmd0aFxuICBpZiAodGFyZ2V0Lmxlbmd0aCAtIHRhcmdldF9zdGFydCA8IGVuZCAtIHN0YXJ0KVxuICAgIGVuZCA9IHRhcmdldC5sZW5ndGggLSB0YXJnZXRfc3RhcnQgKyBzdGFydFxuXG4gIHZhciBsZW4gPSBlbmQgLSBzdGFydFxuXG4gIGlmIChsZW4gPCAxMDAgfHwgIUJ1ZmZlci5fdXNlVHlwZWRBcnJheXMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgdGFyZ2V0W2kgKyB0YXJnZXRfc3RhcnRdID0gdGhpc1tpICsgc3RhcnRdXG4gIH0gZWxzZSB7XG4gICAgdGFyZ2V0Ll9zZXQodGhpcy5zdWJhcnJheShzdGFydCwgc3RhcnQgKyBsZW4pLCB0YXJnZXRfc3RhcnQpXG4gIH1cbn1cblxuZnVuY3Rpb24gX2Jhc2U2NFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgaWYgKHN0YXJ0ID09PSAwICYmIGVuZCA9PT0gYnVmLmxlbmd0aCkge1xuICAgIHJldHVybiBiYXNlNjQuZnJvbUJ5dGVBcnJheShidWYpXG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGJhc2U2NC5mcm9tQnl0ZUFycmF5KGJ1Zi5zbGljZShzdGFydCwgZW5kKSlcbiAgfVxufVxuXG5mdW5jdGlvbiBfdXRmOFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJlcyA9ICcnXG4gIHZhciB0bXAgPSAnJ1xuICBlbmQgPSBNYXRoLm1pbihidWYubGVuZ3RoLCBlbmQpXG5cbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBpZiAoYnVmW2ldIDw9IDB4N0YpIHtcbiAgICAgIHJlcyArPSBkZWNvZGVVdGY4Q2hhcih0bXApICsgU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gICAgICB0bXAgPSAnJ1xuICAgIH0gZWxzZSB7XG4gICAgICB0bXAgKz0gJyUnICsgYnVmW2ldLnRvU3RyaW5nKDE2KVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXMgKyBkZWNvZGVVdGY4Q2hhcih0bXApXG59XG5cbmZ1bmN0aW9uIF9hc2NpaVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIHJldCA9ICcnXG4gIGVuZCA9IE1hdGgubWluKGJ1Zi5sZW5ndGgsIGVuZClcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKylcbiAgICByZXQgKz0gU3RyaW5nLmZyb21DaGFyQ29kZShidWZbaV0pXG4gIHJldHVybiByZXRcbn1cblxuZnVuY3Rpb24gX2JpbmFyeVNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIF9hc2NpaVNsaWNlKGJ1Ziwgc3RhcnQsIGVuZClcbn1cblxuZnVuY3Rpb24gX2hleFNsaWNlIChidWYsIHN0YXJ0LCBlbmQpIHtcbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcblxuICBpZiAoIXN0YXJ0IHx8IHN0YXJ0IDwgMCkgc3RhcnQgPSAwXG4gIGlmICghZW5kIHx8IGVuZCA8IDAgfHwgZW5kID4gbGVuKSBlbmQgPSBsZW5cblxuICB2YXIgb3V0ID0gJydcbiAgZm9yICh2YXIgaSA9IHN0YXJ0OyBpIDwgZW5kOyBpKyspIHtcbiAgICBvdXQgKz0gdG9IZXgoYnVmW2ldKVxuICB9XG4gIHJldHVybiBvdXRcbn1cblxuZnVuY3Rpb24gX3V0ZjE2bGVTbGljZSAoYnVmLCBzdGFydCwgZW5kKSB7XG4gIHZhciBieXRlcyA9IGJ1Zi5zbGljZShzdGFydCwgZW5kKVxuICB2YXIgcmVzID0gJydcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBieXRlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgIHJlcyArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGJ5dGVzW2ldICsgYnl0ZXNbaSsxXSAqIDI1NilcbiAgfVxuICByZXR1cm4gcmVzXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuc2xpY2UgPSBmdW5jdGlvbiAoc3RhcnQsIGVuZCkge1xuICB2YXIgbGVuID0gdGhpcy5sZW5ndGhcbiAgc3RhcnQgPSBjbGFtcChzdGFydCwgbGVuLCAwKVxuICBlbmQgPSBjbGFtcChlbmQsIGxlbiwgbGVuKVxuXG4gIGlmIChCdWZmZXIuX3VzZVR5cGVkQXJyYXlzKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5fYXVnbWVudCh0aGlzLnN1YmFycmF5KHN0YXJ0LCBlbmQpKVxuICB9IGVsc2Uge1xuICAgIHZhciBzbGljZUxlbiA9IGVuZCAtIHN0YXJ0XG4gICAgdmFyIG5ld0J1ZiA9IG5ldyBCdWZmZXIoc2xpY2VMZW4sIHVuZGVmaW5lZCwgdHJ1ZSlcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNsaWNlTGVuOyBpKyspIHtcbiAgICAgIG5ld0J1ZltpXSA9IHRoaXNbaSArIHN0YXJ0XVxuICAgIH1cbiAgICByZXR1cm4gbmV3QnVmXG4gIH1cbn1cblxuLy8gYGdldGAgd2lsbCBiZSByZW1vdmVkIGluIE5vZGUgMC4xMytcbkJ1ZmZlci5wcm90b3R5cGUuZ2V0ID0gZnVuY3Rpb24gKG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLmdldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMucmVhZFVJbnQ4KG9mZnNldClcbn1cblxuLy8gYHNldGAgd2lsbCBiZSByZW1vdmVkIGluIE5vZGUgMC4xMytcbkJ1ZmZlci5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24gKHYsIG9mZnNldCkge1xuICBjb25zb2xlLmxvZygnLnNldCgpIGlzIGRlcHJlY2F0ZWQuIEFjY2VzcyB1c2luZyBhcnJheSBpbmRleGVzIGluc3RlYWQuJylcbiAgcmV0dXJuIHRoaXMud3JpdGVVSW50OCh2LCBvZmZzZXQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQ4ID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCA8IHRoaXMubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm5cblxuICByZXR1cm4gdGhpc1tvZmZzZXRdXG59XG5cbmZ1bmN0aW9uIF9yZWFkVUludDE2IChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDEgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgdmFyIHZhbFxuICBpZiAobGl0dGxlRW5kaWFuKSB7XG4gICAgdmFsID0gYnVmW29mZnNldF1cbiAgICBpZiAob2Zmc2V0ICsgMSA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgMV0gPDwgOFxuICB9IGVsc2Uge1xuICAgIHZhbCA9IGJ1ZltvZmZzZXRdIDw8IDhcbiAgICBpZiAob2Zmc2V0ICsgMSA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgMV1cbiAgfVxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDE2KHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQxNkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDE2KHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfcmVhZFVJbnQzMiAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIHZhciB2YWxcbiAgaWYgKGxpdHRsZUVuZGlhbikge1xuICAgIGlmIChvZmZzZXQgKyAyIDwgbGVuKVxuICAgICAgdmFsID0gYnVmW29mZnNldCArIDJdIDw8IDE2XG4gICAgaWYgKG9mZnNldCArIDEgPCBsZW4pXG4gICAgICB2YWwgfD0gYnVmW29mZnNldCArIDFdIDw8IDhcbiAgICB2YWwgfD0gYnVmW29mZnNldF1cbiAgICBpZiAob2Zmc2V0ICsgMyA8IGxlbilcbiAgICAgIHZhbCA9IHZhbCArIChidWZbb2Zmc2V0ICsgM10gPDwgMjQgPj4+IDApXG4gIH0gZWxzZSB7XG4gICAgaWYgKG9mZnNldCArIDEgPCBsZW4pXG4gICAgICB2YWwgPSBidWZbb2Zmc2V0ICsgMV0gPDwgMTZcbiAgICBpZiAob2Zmc2V0ICsgMiA8IGxlbilcbiAgICAgIHZhbCB8PSBidWZbb2Zmc2V0ICsgMl0gPDwgOFxuICAgIGlmIChvZmZzZXQgKyAzIDwgbGVuKVxuICAgICAgdmFsIHw9IGJ1ZltvZmZzZXQgKyAzXVxuICAgIHZhbCA9IHZhbCArIChidWZbb2Zmc2V0XSA8PCAyNCA+Pj4gMClcbiAgfVxuICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkxFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDMyKHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZFVJbnQzMkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkVUludDMyKHRoaXMsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQ4ID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsXG4gICAgICAgICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCA8IHRoaXMubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm5cblxuICB2YXIgbmVnID0gdGhpc1tvZmZzZXRdICYgMHg4MFxuICBpZiAobmVnKVxuICAgIHJldHVybiAoMHhmZiAtIHRoaXNbb2Zmc2V0XSArIDEpICogLTFcbiAgZWxzZVxuICAgIHJldHVybiB0aGlzW29mZnNldF1cbn1cblxuZnVuY3Rpb24gX3JlYWRJbnQxNiAoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAxIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byByZWFkIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIHZhciB2YWwgPSBfcmVhZFVJbnQxNihidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCB0cnVlKVxuICB2YXIgbmVnID0gdmFsICYgMHg4MDAwXG4gIGlmIChuZWcpXG4gICAgcmV0dXJuICgweGZmZmYgLSB2YWwgKyAxKSAqIC0xXG4gIGVsc2VcbiAgICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDE2TEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRJbnQxNih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQxNkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkSW50MTYodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF9yZWFkSW50MzIgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMyA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gcmVhZCBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICB2YXIgdmFsID0gX3JlYWRVSW50MzIoYnVmLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgdHJ1ZSlcbiAgdmFyIG5lZyA9IHZhbCAmIDB4ODAwMDAwMDBcbiAgaWYgKG5lZylcbiAgICByZXR1cm4gKDB4ZmZmZmZmZmYgLSB2YWwgKyAxKSAqIC0xXG4gIGVsc2VcbiAgICByZXR1cm4gdmFsXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEludDMyTEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRJbnQzMih0aGlzLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLnJlYWRJbnQzMkJFID0gZnVuY3Rpb24gKG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgcmV0dXJuIF9yZWFkSW50MzIodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF9yZWFkRmxvYXQgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgcmV0dXJuIGllZWU3NTQucmVhZChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCAyMywgNClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRmxvYXRMRSA9IGZ1bmN0aW9uIChvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIHJldHVybiBfcmVhZEZsb2F0KHRoaXMsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUucmVhZEZsb2F0QkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWRGbG9hdCh0aGlzLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3JlYWREb3VibGUgKGJ1Ziwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCArIDcgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHJlYWQgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICB9XG5cbiAgcmV0dXJuIGllZWU3NTQucmVhZChidWYsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCA1MiwgOClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlTEUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWREb3VibGUodGhpcywgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS5yZWFkRG91YmxlQkUgPSBmdW5jdGlvbiAob2Zmc2V0LCBub0Fzc2VydCkge1xuICByZXR1cm4gX3JlYWREb3VibGUodGhpcywgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVVSW50OCA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgPCB0aGlzLmxlbmd0aCwgJ3RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZ1aW50KHZhbHVlLCAweGZmKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aCkgcmV0dXJuXG5cbiAgdGhpc1tvZmZzZXRdID0gdmFsdWVcbn1cblxuZnVuY3Rpb24gX3dyaXRlVUludDE2IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDEgPCBidWYubGVuZ3RoLCAndHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnVpbnQodmFsdWUsIDB4ZmZmZilcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGZvciAodmFyIGkgPSAwLCBqID0gTWF0aC5taW4obGVuIC0gb2Zmc2V0LCAyKTsgaSA8IGo7IGkrKykge1xuICAgIGJ1ZltvZmZzZXQgKyBpXSA9XG4gICAgICAgICh2YWx1ZSAmICgweGZmIDw8ICg4ICogKGxpdHRsZUVuZGlhbiA/IGkgOiAxIC0gaSkpKSkgPj4+XG4gICAgICAgICAgICAobGl0dGxlRW5kaWFuID8gaSA6IDEgLSBpKSAqIDhcbiAgfVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2TEUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlVUludDE2QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlVUludDE2KHRoaXMsIHZhbHVlLCBvZmZzZXQsIGZhbHNlLCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3dyaXRlVUludDMyIChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAndHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnVpbnQodmFsdWUsIDB4ZmZmZmZmZmYpXG4gIH1cblxuICB2YXIgbGVuID0gYnVmLmxlbmd0aFxuICBpZiAob2Zmc2V0ID49IGxlbilcbiAgICByZXR1cm5cblxuICBmb3IgKHZhciBpID0gMCwgaiA9IE1hdGgubWluKGxlbiAtIG9mZnNldCwgNCk7IGkgPCBqOyBpKyspIHtcbiAgICBidWZbb2Zmc2V0ICsgaV0gPVxuICAgICAgICAodmFsdWUgPj4+IChsaXR0bGVFbmRpYW4gPyBpIDogMyAtIGkpICogOCkgJiAweGZmXG4gIH1cbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZVVJbnQzMkJFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZVVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQ4ID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCA8IHRoaXMubGVuZ3RoLCAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZnNpbnQodmFsdWUsIDB4N2YsIC0weDgwKVxuICB9XG5cbiAgaWYgKG9mZnNldCA+PSB0aGlzLmxlbmd0aClcbiAgICByZXR1cm5cblxuICBpZiAodmFsdWUgPj0gMClcbiAgICB0aGlzLndyaXRlVUludDgodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpXG4gIGVsc2VcbiAgICB0aGlzLndyaXRlVUludDgoMHhmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBub0Fzc2VydClcbn1cblxuZnVuY3Rpb24gX3dyaXRlSW50MTYgKGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydCkge1xuICBpZiAoIW5vQXNzZXJ0KSB7XG4gICAgYXNzZXJ0KHZhbHVlICE9PSB1bmRlZmluZWQgJiYgdmFsdWUgIT09IG51bGwsICdtaXNzaW5nIHZhbHVlJylcbiAgICBhc3NlcnQodHlwZW9mIGxpdHRsZUVuZGlhbiA9PT0gJ2Jvb2xlYW4nLCAnbWlzc2luZyBvciBpbnZhbGlkIGVuZGlhbicpXG4gICAgYXNzZXJ0KG9mZnNldCAhPT0gdW5kZWZpbmVkICYmIG9mZnNldCAhPT0gbnVsbCwgJ21pc3Npbmcgb2Zmc2V0JylcbiAgICBhc3NlcnQob2Zmc2V0ICsgMSA8IGJ1Zi5sZW5ndGgsICdUcnlpbmcgdG8gd3JpdGUgYmV5b25kIGJ1ZmZlciBsZW5ndGgnKVxuICAgIHZlcmlmc2ludCh2YWx1ZSwgMHg3ZmZmLCAtMHg4MDAwKVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgaWYgKHZhbHVlID49IDApXG4gICAgX3dyaXRlVUludDE2KGJ1ZiwgdmFsdWUsIG9mZnNldCwgbGl0dGxlRW5kaWFuLCBub0Fzc2VydClcbiAgZWxzZVxuICAgIF93cml0ZVVJbnQxNihidWYsIDB4ZmZmZiArIHZhbHVlICsgMSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MTZMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVJbnQxNih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCB0cnVlLCBub0Fzc2VydClcbn1cblxuQnVmZmVyLnByb3RvdHlwZS53cml0ZUludDE2QkUgPSBmdW5jdGlvbiAodmFsdWUsIG9mZnNldCwgbm9Bc3NlcnQpIHtcbiAgX3dyaXRlSW50MTYodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG5mdW5jdGlvbiBfd3JpdGVJbnQzMiAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyAzIDwgYnVmLmxlbmd0aCwgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZzaW50KHZhbHVlLCAweDdmZmZmZmZmLCAtMHg4MDAwMDAwMClcbiAgfVxuXG4gIHZhciBsZW4gPSBidWYubGVuZ3RoXG4gIGlmIChvZmZzZXQgPj0gbGVuKVxuICAgIHJldHVyblxuXG4gIGlmICh2YWx1ZSA+PSAwKVxuICAgIF93cml0ZVVJbnQzMihidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpXG4gIGVsc2VcbiAgICBfd3JpdGVVSW50MzIoYnVmLCAweGZmZmZmZmZmICsgdmFsdWUgKyAxLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVJbnQzMkxFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUludDMyKHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlSW50MzJCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVJbnQzMih0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZUZsb2F0IChidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgbm9Bc3NlcnQpIHtcbiAgaWYgKCFub0Fzc2VydCkge1xuICAgIGFzc2VydCh2YWx1ZSAhPT0gdW5kZWZpbmVkICYmIHZhbHVlICE9PSBudWxsLCAnbWlzc2luZyB2YWx1ZScpXG4gICAgYXNzZXJ0KHR5cGVvZiBsaXR0bGVFbmRpYW4gPT09ICdib29sZWFuJywgJ21pc3Npbmcgb3IgaW52YWxpZCBlbmRpYW4nKVxuICAgIGFzc2VydChvZmZzZXQgIT09IHVuZGVmaW5lZCAmJiBvZmZzZXQgIT09IG51bGwsICdtaXNzaW5nIG9mZnNldCcpXG4gICAgYXNzZXJ0KG9mZnNldCArIDMgPCBidWYubGVuZ3RoLCAnVHJ5aW5nIHRvIHdyaXRlIGJleW9uZCBidWZmZXIgbGVuZ3RoJylcbiAgICB2ZXJpZklFRUU3NTQodmFsdWUsIDMuNDAyODIzNDY2Mzg1Mjg4NmUrMzgsIC0zLjQwMjgyMzQ2NjM4NTI4ODZlKzM4KVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgMjMsIDQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVGbG9hdExFID0gZnVuY3Rpb24gKHZhbHVlLCBvZmZzZXQsIG5vQXNzZXJ0KSB7XG4gIF93cml0ZUZsb2F0KHRoaXMsIHZhbHVlLCBvZmZzZXQsIHRydWUsIG5vQXNzZXJ0KVxufVxuXG5CdWZmZXIucHJvdG90eXBlLndyaXRlRmxvYXRCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVGbG9hdCh0aGlzLCB2YWx1ZSwgb2Zmc2V0LCBmYWxzZSwgbm9Bc3NlcnQpXG59XG5cbmZ1bmN0aW9uIF93cml0ZURvdWJsZSAoYnVmLCB2YWx1ZSwgb2Zmc2V0LCBsaXR0bGVFbmRpYW4sIG5vQXNzZXJ0KSB7XG4gIGlmICghbm9Bc3NlcnQpIHtcbiAgICBhc3NlcnQodmFsdWUgIT09IHVuZGVmaW5lZCAmJiB2YWx1ZSAhPT0gbnVsbCwgJ21pc3NpbmcgdmFsdWUnKVxuICAgIGFzc2VydCh0eXBlb2YgbGl0dGxlRW5kaWFuID09PSAnYm9vbGVhbicsICdtaXNzaW5nIG9yIGludmFsaWQgZW5kaWFuJylcbiAgICBhc3NlcnQob2Zmc2V0ICE9PSB1bmRlZmluZWQgJiYgb2Zmc2V0ICE9PSBudWxsLCAnbWlzc2luZyBvZmZzZXQnKVxuICAgIGFzc2VydChvZmZzZXQgKyA3IDwgYnVmLmxlbmd0aCxcbiAgICAgICAgJ1RyeWluZyB0byB3cml0ZSBiZXlvbmQgYnVmZmVyIGxlbmd0aCcpXG4gICAgdmVyaWZJRUVFNzU0KHZhbHVlLCAxLjc5NzY5MzEzNDg2MjMxNTdFKzMwOCwgLTEuNzk3NjkzMTM0ODYyMzE1N0UrMzA4KVxuICB9XG5cbiAgdmFyIGxlbiA9IGJ1Zi5sZW5ndGhcbiAgaWYgKG9mZnNldCA+PSBsZW4pXG4gICAgcmV0dXJuXG5cbiAgaWVlZTc1NC53cml0ZShidWYsIHZhbHVlLCBvZmZzZXQsIGxpdHRsZUVuZGlhbiwgNTIsIDgpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVMRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgdHJ1ZSwgbm9Bc3NlcnQpXG59XG5cbkJ1ZmZlci5wcm90b3R5cGUud3JpdGVEb3VibGVCRSA9IGZ1bmN0aW9uICh2YWx1ZSwgb2Zmc2V0LCBub0Fzc2VydCkge1xuICBfd3JpdGVEb3VibGUodGhpcywgdmFsdWUsIG9mZnNldCwgZmFsc2UsIG5vQXNzZXJ0KVxufVxuXG4vLyBmaWxsKHZhbHVlLCBzdGFydD0wLCBlbmQ9YnVmZmVyLmxlbmd0aClcbkJ1ZmZlci5wcm90b3R5cGUuZmlsbCA9IGZ1bmN0aW9uICh2YWx1ZSwgc3RhcnQsIGVuZCkge1xuICBpZiAoIXZhbHVlKSB2YWx1ZSA9IDBcbiAgaWYgKCFzdGFydCkgc3RhcnQgPSAwXG4gIGlmICghZW5kKSBlbmQgPSB0aGlzLmxlbmd0aFxuXG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSB7XG4gICAgdmFsdWUgPSB2YWx1ZS5jaGFyQ29kZUF0KDApXG4gIH1cblxuICBhc3NlcnQodHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJyAmJiAhaXNOYU4odmFsdWUpLCAndmFsdWUgaXMgbm90IGEgbnVtYmVyJylcbiAgYXNzZXJ0KGVuZCA+PSBzdGFydCwgJ2VuZCA8IHN0YXJ0JylcblxuICAvLyBGaWxsIDAgYnl0ZXM7IHdlJ3JlIGRvbmVcbiAgaWYgKGVuZCA9PT0gc3RhcnQpIHJldHVyblxuICBpZiAodGhpcy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gIGFzc2VydChzdGFydCA+PSAwICYmIHN0YXJ0IDwgdGhpcy5sZW5ndGgsICdzdGFydCBvdXQgb2YgYm91bmRzJylcbiAgYXNzZXJ0KGVuZCA+PSAwICYmIGVuZCA8PSB0aGlzLmxlbmd0aCwgJ2VuZCBvdXQgb2YgYm91bmRzJylcblxuICBmb3IgKHZhciBpID0gc3RhcnQ7IGkgPCBlbmQ7IGkrKykge1xuICAgIHRoaXNbaV0gPSB2YWx1ZVxuICB9XG59XG5cbkJ1ZmZlci5wcm90b3R5cGUuaW5zcGVjdCA9IGZ1bmN0aW9uICgpIHtcbiAgdmFyIG91dCA9IFtdXG4gIHZhciBsZW4gPSB0aGlzLmxlbmd0aFxuICBmb3IgKHZhciBpID0gMDsgaSA8IGxlbjsgaSsrKSB7XG4gICAgb3V0W2ldID0gdG9IZXgodGhpc1tpXSlcbiAgICBpZiAoaSA9PT0gZXhwb3J0cy5JTlNQRUNUX01BWF9CWVRFUykge1xuICAgICAgb3V0W2kgKyAxXSA9ICcuLi4nXG4gICAgICBicmVha1xuICAgIH1cbiAgfVxuICByZXR1cm4gJzxCdWZmZXIgJyArIG91dC5qb2luKCcgJykgKyAnPidcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGBBcnJheUJ1ZmZlcmAgd2l0aCB0aGUgKmNvcGllZCogbWVtb3J5IG9mIHRoZSBidWZmZXIgaW5zdGFuY2UuXG4gKiBBZGRlZCBpbiBOb2RlIDAuMTIuIE9ubHkgYXZhaWxhYmxlIGluIGJyb3dzZXJzIHRoYXQgc3VwcG9ydCBBcnJheUJ1ZmZlci5cbiAqL1xuQnVmZmVyLnByb3RvdHlwZS50b0FycmF5QnVmZmVyID0gZnVuY3Rpb24gKCkge1xuICBpZiAodHlwZW9mIFVpbnQ4QXJyYXkgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgaWYgKEJ1ZmZlci5fdXNlVHlwZWRBcnJheXMpIHtcbiAgICAgIHJldHVybiAobmV3IEJ1ZmZlcih0aGlzKSkuYnVmZmVyXG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBidWYgPSBuZXcgVWludDhBcnJheSh0aGlzLmxlbmd0aClcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBidWYubGVuZ3RoOyBpIDwgbGVuOyBpICs9IDEpXG4gICAgICAgIGJ1ZltpXSA9IHRoaXNbaV1cbiAgICAgIHJldHVybiBidWYuYnVmZmVyXG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHRocm93IG5ldyBFcnJvcignQnVmZmVyLnRvQXJyYXlCdWZmZXIgbm90IHN1cHBvcnRlZCBpbiB0aGlzIGJyb3dzZXInKVxuICB9XG59XG5cbi8vIEhFTFBFUiBGVU5DVElPTlNcbi8vID09PT09PT09PT09PT09PT1cblxuZnVuY3Rpb24gc3RyaW5ndHJpbSAoc3RyKSB7XG4gIGlmIChzdHIudHJpbSkgcmV0dXJuIHN0ci50cmltKClcbiAgcmV0dXJuIHN0ci5yZXBsYWNlKC9eXFxzK3xcXHMrJC9nLCAnJylcbn1cblxudmFyIEJQID0gQnVmZmVyLnByb3RvdHlwZVxuXG4vKipcbiAqIEF1Z21lbnQgYSBVaW50OEFycmF5ICppbnN0YW5jZSogKG5vdCB0aGUgVWludDhBcnJheSBjbGFzcyEpIHdpdGggQnVmZmVyIG1ldGhvZHNcbiAqL1xuQnVmZmVyLl9hdWdtZW50ID0gZnVuY3Rpb24gKGFycikge1xuICBhcnIuX2lzQnVmZmVyID0gdHJ1ZVxuXG4gIC8vIHNhdmUgcmVmZXJlbmNlIHRvIG9yaWdpbmFsIFVpbnQ4QXJyYXkgZ2V0L3NldCBtZXRob2RzIGJlZm9yZSBvdmVyd3JpdGluZ1xuICBhcnIuX2dldCA9IGFyci5nZXRcbiAgYXJyLl9zZXQgPSBhcnIuc2V0XG5cbiAgLy8gZGVwcmVjYXRlZCwgd2lsbCBiZSByZW1vdmVkIGluIG5vZGUgMC4xMytcbiAgYXJyLmdldCA9IEJQLmdldFxuICBhcnIuc2V0ID0gQlAuc2V0XG5cbiAgYXJyLndyaXRlID0gQlAud3JpdGVcbiAgYXJyLnRvU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvTG9jYWxlU3RyaW5nID0gQlAudG9TdHJpbmdcbiAgYXJyLnRvSlNPTiA9IEJQLnRvSlNPTlxuICBhcnIuY29weSA9IEJQLmNvcHlcbiAgYXJyLnNsaWNlID0gQlAuc2xpY2VcbiAgYXJyLnJlYWRVSW50OCA9IEJQLnJlYWRVSW50OFxuICBhcnIucmVhZFVJbnQxNkxFID0gQlAucmVhZFVJbnQxNkxFXG4gIGFyci5yZWFkVUludDE2QkUgPSBCUC5yZWFkVUludDE2QkVcbiAgYXJyLnJlYWRVSW50MzJMRSA9IEJQLnJlYWRVSW50MzJMRVxuICBhcnIucmVhZFVJbnQzMkJFID0gQlAucmVhZFVJbnQzMkJFXG4gIGFyci5yZWFkSW50OCA9IEJQLnJlYWRJbnQ4XG4gIGFyci5yZWFkSW50MTZMRSA9IEJQLnJlYWRJbnQxNkxFXG4gIGFyci5yZWFkSW50MTZCRSA9IEJQLnJlYWRJbnQxNkJFXG4gIGFyci5yZWFkSW50MzJMRSA9IEJQLnJlYWRJbnQzMkxFXG4gIGFyci5yZWFkSW50MzJCRSA9IEJQLnJlYWRJbnQzMkJFXG4gIGFyci5yZWFkRmxvYXRMRSA9IEJQLnJlYWRGbG9hdExFXG4gIGFyci5yZWFkRmxvYXRCRSA9IEJQLnJlYWRGbG9hdEJFXG4gIGFyci5yZWFkRG91YmxlTEUgPSBCUC5yZWFkRG91YmxlTEVcbiAgYXJyLnJlYWREb3VibGVCRSA9IEJQLnJlYWREb3VibGVCRVxuICBhcnIud3JpdGVVSW50OCA9IEJQLndyaXRlVUludDhcbiAgYXJyLndyaXRlVUludDE2TEUgPSBCUC53cml0ZVVJbnQxNkxFXG4gIGFyci53cml0ZVVJbnQxNkJFID0gQlAud3JpdGVVSW50MTZCRVxuICBhcnIud3JpdGVVSW50MzJMRSA9IEJQLndyaXRlVUludDMyTEVcbiAgYXJyLndyaXRlVUludDMyQkUgPSBCUC53cml0ZVVJbnQzMkJFXG4gIGFyci53cml0ZUludDggPSBCUC53cml0ZUludDhcbiAgYXJyLndyaXRlSW50MTZMRSA9IEJQLndyaXRlSW50MTZMRVxuICBhcnIud3JpdGVJbnQxNkJFID0gQlAud3JpdGVJbnQxNkJFXG4gIGFyci53cml0ZUludDMyTEUgPSBCUC53cml0ZUludDMyTEVcbiAgYXJyLndyaXRlSW50MzJCRSA9IEJQLndyaXRlSW50MzJCRVxuICBhcnIud3JpdGVGbG9hdExFID0gQlAud3JpdGVGbG9hdExFXG4gIGFyci53cml0ZUZsb2F0QkUgPSBCUC53cml0ZUZsb2F0QkVcbiAgYXJyLndyaXRlRG91YmxlTEUgPSBCUC53cml0ZURvdWJsZUxFXG4gIGFyci53cml0ZURvdWJsZUJFID0gQlAud3JpdGVEb3VibGVCRVxuICBhcnIuZmlsbCA9IEJQLmZpbGxcbiAgYXJyLmluc3BlY3QgPSBCUC5pbnNwZWN0XG4gIGFyci50b0FycmF5QnVmZmVyID0gQlAudG9BcnJheUJ1ZmZlclxuXG4gIHJldHVybiBhcnJcbn1cblxuLy8gc2xpY2Uoc3RhcnQsIGVuZClcbmZ1bmN0aW9uIGNsYW1wIChpbmRleCwgbGVuLCBkZWZhdWx0VmFsdWUpIHtcbiAgaWYgKHR5cGVvZiBpbmRleCAhPT0gJ251bWJlcicpIHJldHVybiBkZWZhdWx0VmFsdWVcbiAgaW5kZXggPSB+fmluZGV4OyAgLy8gQ29lcmNlIHRvIGludGVnZXIuXG4gIGlmIChpbmRleCA+PSBsZW4pIHJldHVybiBsZW5cbiAgaWYgKGluZGV4ID49IDApIHJldHVybiBpbmRleFxuICBpbmRleCArPSBsZW5cbiAgaWYgKGluZGV4ID49IDApIHJldHVybiBpbmRleFxuICByZXR1cm4gMFxufVxuXG5mdW5jdGlvbiBjb2VyY2UgKGxlbmd0aCkge1xuICAvLyBDb2VyY2UgbGVuZ3RoIHRvIGEgbnVtYmVyIChwb3NzaWJseSBOYU4pLCByb3VuZCB1cFxuICAvLyBpbiBjYXNlIGl0J3MgZnJhY3Rpb25hbCAoZS5nLiAxMjMuNDU2KSB0aGVuIGRvIGFcbiAgLy8gZG91YmxlIG5lZ2F0ZSB0byBjb2VyY2UgYSBOYU4gdG8gMC4gRWFzeSwgcmlnaHQ/XG4gIGxlbmd0aCA9IH5+TWF0aC5jZWlsKCtsZW5ndGgpXG4gIHJldHVybiBsZW5ndGggPCAwID8gMCA6IGxlbmd0aFxufVxuXG5mdW5jdGlvbiBpc0FycmF5IChzdWJqZWN0KSB7XG4gIHJldHVybiAoQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAoc3ViamVjdCkge1xuICAgIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc3ViamVjdCkgPT09ICdbb2JqZWN0IEFycmF5XSdcbiAgfSkoc3ViamVjdClcbn1cblxuZnVuY3Rpb24gaXNBcnJheWlzaCAoc3ViamVjdCkge1xuICByZXR1cm4gaXNBcnJheShzdWJqZWN0KSB8fCBCdWZmZXIuaXNCdWZmZXIoc3ViamVjdCkgfHxcbiAgICAgIHN1YmplY3QgJiYgdHlwZW9mIHN1YmplY3QgPT09ICdvYmplY3QnICYmXG4gICAgICB0eXBlb2Ygc3ViamVjdC5sZW5ndGggPT09ICdudW1iZXInXG59XG5cbmZ1bmN0aW9uIHRvSGV4IChuKSB7XG4gIGlmIChuIDwgMTYpIHJldHVybiAnMCcgKyBuLnRvU3RyaW5nKDE2KVxuICByZXR1cm4gbi50b1N0cmluZygxNilcbn1cblxuZnVuY3Rpb24gdXRmOFRvQnl0ZXMgKHN0cikge1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgYiA9IHN0ci5jaGFyQ29kZUF0KGkpXG4gICAgaWYgKGIgPD0gMHg3RilcbiAgICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpKVxuICAgIGVsc2Uge1xuICAgICAgdmFyIHN0YXJ0ID0gaVxuICAgICAgaWYgKGIgPj0gMHhEODAwICYmIGIgPD0gMHhERkZGKSBpKytcbiAgICAgIHZhciBoID0gZW5jb2RlVVJJQ29tcG9uZW50KHN0ci5zbGljZShzdGFydCwgaSsxKSkuc3Vic3RyKDEpLnNwbGl0KCclJylcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgaC5sZW5ndGg7IGorKylcbiAgICAgICAgYnl0ZUFycmF5LnB1c2gocGFyc2VJbnQoaFtqXSwgMTYpKVxuICAgIH1cbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIGFzY2lpVG9CeXRlcyAoc3RyKSB7XG4gIHZhciBieXRlQXJyYXkgPSBbXVxuICBmb3IgKHZhciBpID0gMDsgaSA8IHN0ci5sZW5ndGg7IGkrKykge1xuICAgIC8vIE5vZGUncyBjb2RlIHNlZW1zIHRvIGJlIGRvaW5nIHRoaXMgYW5kIG5vdCAmIDB4N0YuLlxuICAgIGJ5dGVBcnJheS5wdXNoKHN0ci5jaGFyQ29kZUF0KGkpICYgMHhGRilcbiAgfVxuICByZXR1cm4gYnl0ZUFycmF5XG59XG5cbmZ1bmN0aW9uIHV0ZjE2bGVUb0J5dGVzIChzdHIpIHtcbiAgdmFyIGMsIGhpLCBsb1xuICB2YXIgYnl0ZUFycmF5ID0gW11cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBzdHIubGVuZ3RoOyBpKyspIHtcbiAgICBjID0gc3RyLmNoYXJDb2RlQXQoaSlcbiAgICBoaSA9IGMgPj4gOFxuICAgIGxvID0gYyAlIDI1NlxuICAgIGJ5dGVBcnJheS5wdXNoKGxvKVxuICAgIGJ5dGVBcnJheS5wdXNoKGhpKVxuICB9XG5cbiAgcmV0dXJuIGJ5dGVBcnJheVxufVxuXG5mdW5jdGlvbiBiYXNlNjRUb0J5dGVzIChzdHIpIHtcbiAgcmV0dXJuIGJhc2U2NC50b0J5dGVBcnJheShzdHIpXG59XG5cbmZ1bmN0aW9uIGJsaXRCdWZmZXIgKHNyYywgZHN0LCBvZmZzZXQsIGxlbmd0aCkge1xuICB2YXIgcG9zXG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoKGkgKyBvZmZzZXQgPj0gZHN0Lmxlbmd0aCkgfHwgKGkgPj0gc3JjLmxlbmd0aCkpXG4gICAgICBicmVha1xuICAgIGRzdFtpICsgb2Zmc2V0XSA9IHNyY1tpXVxuICB9XG4gIHJldHVybiBpXG59XG5cbmZ1bmN0aW9uIGRlY29kZVV0ZjhDaGFyIChzdHIpIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gZGVjb2RlVVJJQ29tcG9uZW50KHN0cilcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgcmV0dXJuIFN0cmluZy5mcm9tQ2hhckNvZGUoMHhGRkZEKSAvLyBVVEYgOCBpbnZhbGlkIGNoYXJcbiAgfVxufVxuXG4vKlxuICogV2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCB0aGUgdmFsdWUgaXMgYSB2YWxpZCBpbnRlZ2VyLiBUaGlzIG1lYW5zIHRoYXQgaXRcbiAqIGlzIG5vbi1uZWdhdGl2ZS4gSXQgaGFzIG5vIGZyYWN0aW9uYWwgY29tcG9uZW50IGFuZCB0aGF0IGl0IGRvZXMgbm90XG4gKiBleGNlZWQgdGhlIG1heGltdW0gYWxsb3dlZCB2YWx1ZS5cbiAqL1xuZnVuY3Rpb24gdmVyaWZ1aW50ICh2YWx1ZSwgbWF4KSB7XG4gIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLCAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpXG4gIGFzc2VydCh2YWx1ZSA+PSAwLCAnc3BlY2lmaWVkIGEgbmVnYXRpdmUgdmFsdWUgZm9yIHdyaXRpbmcgYW4gdW5zaWduZWQgdmFsdWUnKVxuICBhc3NlcnQodmFsdWUgPD0gbWF4LCAndmFsdWUgaXMgbGFyZ2VyIHRoYW4gbWF4aW11bSB2YWx1ZSBmb3IgdHlwZScpXG4gIGFzc2VydChNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUsICd2YWx1ZSBoYXMgYSBmcmFjdGlvbmFsIGNvbXBvbmVudCcpXG59XG5cbmZ1bmN0aW9uIHZlcmlmc2ludCAodmFsdWUsIG1heCwgbWluKSB7XG4gIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLCAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpXG4gIGFzc2VydCh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBsYXJnZXIgdGhhbiBtYXhpbXVtIGFsbG93ZWQgdmFsdWUnKVxuICBhc3NlcnQodmFsdWUgPj0gbWluLCAndmFsdWUgc21hbGxlciB0aGFuIG1pbmltdW0gYWxsb3dlZCB2YWx1ZScpXG4gIGFzc2VydChNYXRoLmZsb29yKHZhbHVlKSA9PT0gdmFsdWUsICd2YWx1ZSBoYXMgYSBmcmFjdGlvbmFsIGNvbXBvbmVudCcpXG59XG5cbmZ1bmN0aW9uIHZlcmlmSUVFRTc1NCAodmFsdWUsIG1heCwgbWluKSB7XG4gIGFzc2VydCh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInLCAnY2Fubm90IHdyaXRlIGEgbm9uLW51bWJlciBhcyBhIG51bWJlcicpXG4gIGFzc2VydCh2YWx1ZSA8PSBtYXgsICd2YWx1ZSBsYXJnZXIgdGhhbiBtYXhpbXVtIGFsbG93ZWQgdmFsdWUnKVxuICBhc3NlcnQodmFsdWUgPj0gbWluLCAndmFsdWUgc21hbGxlciB0aGFuIG1pbmltdW0gYWxsb3dlZCB2YWx1ZScpXG59XG5cbmZ1bmN0aW9uIGFzc2VydCAodGVzdCwgbWVzc2FnZSkge1xuICBpZiAoIXRlc3QpIHRocm93IG5ldyBFcnJvcihtZXNzYWdlIHx8ICdGYWlsZWQgYXNzZXJ0aW9uJylcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgbG9va3VwID0gJ0FCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8nO1xuXG47KGZ1bmN0aW9uIChleHBvcnRzKSB7XG5cdCd1c2Ugc3RyaWN0JztcblxuICB2YXIgQXJyID0gKHR5cGVvZiBVaW50OEFycmF5ICE9PSAndW5kZWZpbmVkJylcbiAgICA/IFVpbnQ4QXJyYXlcbiAgICA6IEFycmF5XG5cblx0dmFyIFBMVVMgICA9ICcrJy5jaGFyQ29kZUF0KDApXG5cdHZhciBTTEFTSCAgPSAnLycuY2hhckNvZGVBdCgwKVxuXHR2YXIgTlVNQkVSID0gJzAnLmNoYXJDb2RlQXQoMClcblx0dmFyIExPV0VSICA9ICdhJy5jaGFyQ29kZUF0KDApXG5cdHZhciBVUFBFUiAgPSAnQScuY2hhckNvZGVBdCgwKVxuXG5cdGZ1bmN0aW9uIGRlY29kZSAoZWx0KSB7XG5cdFx0dmFyIGNvZGUgPSBlbHQuY2hhckNvZGVBdCgwKVxuXHRcdGlmIChjb2RlID09PSBQTFVTKVxuXHRcdFx0cmV0dXJuIDYyIC8vICcrJ1xuXHRcdGlmIChjb2RlID09PSBTTEFTSClcblx0XHRcdHJldHVybiA2MyAvLyAnLydcblx0XHRpZiAoY29kZSA8IE5VTUJFUilcblx0XHRcdHJldHVybiAtMSAvL25vIG1hdGNoXG5cdFx0aWYgKGNvZGUgPCBOVU1CRVIgKyAxMClcblx0XHRcdHJldHVybiBjb2RlIC0gTlVNQkVSICsgMjYgKyAyNlxuXHRcdGlmIChjb2RlIDwgVVBQRVIgKyAyNilcblx0XHRcdHJldHVybiBjb2RlIC0gVVBQRVJcblx0XHRpZiAoY29kZSA8IExPV0VSICsgMjYpXG5cdFx0XHRyZXR1cm4gY29kZSAtIExPV0VSICsgMjZcblx0fVxuXG5cdGZ1bmN0aW9uIGI2NFRvQnl0ZUFycmF5IChiNjQpIHtcblx0XHR2YXIgaSwgaiwgbCwgdG1wLCBwbGFjZUhvbGRlcnMsIGFyclxuXG5cdFx0aWYgKGI2NC5sZW5ndGggJSA0ID4gMCkge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKCdJbnZhbGlkIHN0cmluZy4gTGVuZ3RoIG11c3QgYmUgYSBtdWx0aXBsZSBvZiA0Jylcblx0XHR9XG5cblx0XHQvLyB0aGUgbnVtYmVyIG9mIGVxdWFsIHNpZ25zIChwbGFjZSBob2xkZXJzKVxuXHRcdC8vIGlmIHRoZXJlIGFyZSB0d28gcGxhY2Vob2xkZXJzLCB0aGFuIHRoZSB0d28gY2hhcmFjdGVycyBiZWZvcmUgaXRcblx0XHQvLyByZXByZXNlbnQgb25lIGJ5dGVcblx0XHQvLyBpZiB0aGVyZSBpcyBvbmx5IG9uZSwgdGhlbiB0aGUgdGhyZWUgY2hhcmFjdGVycyBiZWZvcmUgaXQgcmVwcmVzZW50IDIgYnl0ZXNcblx0XHQvLyB0aGlzIGlzIGp1c3QgYSBjaGVhcCBoYWNrIHRvIG5vdCBkbyBpbmRleE9mIHR3aWNlXG5cdFx0dmFyIGxlbiA9IGI2NC5sZW5ndGhcblx0XHRwbGFjZUhvbGRlcnMgPSAnPScgPT09IGI2NC5jaGFyQXQobGVuIC0gMikgPyAyIDogJz0nID09PSBiNjQuY2hhckF0KGxlbiAtIDEpID8gMSA6IDBcblxuXHRcdC8vIGJhc2U2NCBpcyA0LzMgKyB1cCB0byB0d28gY2hhcmFjdGVycyBvZiB0aGUgb3JpZ2luYWwgZGF0YVxuXHRcdGFyciA9IG5ldyBBcnIoYjY0Lmxlbmd0aCAqIDMgLyA0IC0gcGxhY2VIb2xkZXJzKVxuXG5cdFx0Ly8gaWYgdGhlcmUgYXJlIHBsYWNlaG9sZGVycywgb25seSBnZXQgdXAgdG8gdGhlIGxhc3QgY29tcGxldGUgNCBjaGFyc1xuXHRcdGwgPSBwbGFjZUhvbGRlcnMgPiAwID8gYjY0Lmxlbmd0aCAtIDQgOiBiNjQubGVuZ3RoXG5cblx0XHR2YXIgTCA9IDBcblxuXHRcdGZ1bmN0aW9uIHB1c2ggKHYpIHtcblx0XHRcdGFycltMKytdID0gdlxuXHRcdH1cblxuXHRcdGZvciAoaSA9IDAsIGogPSAwOyBpIDwgbDsgaSArPSA0LCBqICs9IDMpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMTgpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPDwgMTIpIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAyKSkgPDwgNikgfCBkZWNvZGUoYjY0LmNoYXJBdChpICsgMykpXG5cdFx0XHRwdXNoKCh0bXAgJiAweEZGMDAwMCkgPj4gMTYpXG5cdFx0XHRwdXNoKCh0bXAgJiAweEZGMDApID4+IDgpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fVxuXG5cdFx0aWYgKHBsYWNlSG9sZGVycyA9PT0gMikge1xuXHRcdFx0dG1wID0gKGRlY29kZShiNjQuY2hhckF0KGkpKSA8PCAyKSB8IChkZWNvZGUoYjY0LmNoYXJBdChpICsgMSkpID4+IDQpXG5cdFx0XHRwdXNoKHRtcCAmIDB4RkYpXG5cdFx0fSBlbHNlIGlmIChwbGFjZUhvbGRlcnMgPT09IDEpIHtcblx0XHRcdHRtcCA9IChkZWNvZGUoYjY0LmNoYXJBdChpKSkgPDwgMTApIHwgKGRlY29kZShiNjQuY2hhckF0KGkgKyAxKSkgPDwgNCkgfCAoZGVjb2RlKGI2NC5jaGFyQXQoaSArIDIpKSA+PiAyKVxuXHRcdFx0cHVzaCgodG1wID4+IDgpICYgMHhGRilcblx0XHRcdHB1c2godG1wICYgMHhGRilcblx0XHR9XG5cblx0XHRyZXR1cm4gYXJyXG5cdH1cblxuXHRmdW5jdGlvbiB1aW50OFRvQmFzZTY0ICh1aW50OCkge1xuXHRcdHZhciBpLFxuXHRcdFx0ZXh0cmFCeXRlcyA9IHVpbnQ4Lmxlbmd0aCAlIDMsIC8vIGlmIHdlIGhhdmUgMSBieXRlIGxlZnQsIHBhZCAyIGJ5dGVzXG5cdFx0XHRvdXRwdXQgPSBcIlwiLFxuXHRcdFx0dGVtcCwgbGVuZ3RoXG5cblx0XHRmdW5jdGlvbiBlbmNvZGUgKG51bSkge1xuXHRcdFx0cmV0dXJuIGxvb2t1cC5jaGFyQXQobnVtKVxuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIHRyaXBsZXRUb0Jhc2U2NCAobnVtKSB7XG5cdFx0XHRyZXR1cm4gZW5jb2RlKG51bSA+PiAxOCAmIDB4M0YpICsgZW5jb2RlKG51bSA+PiAxMiAmIDB4M0YpICsgZW5jb2RlKG51bSA+PiA2ICYgMHgzRikgKyBlbmNvZGUobnVtICYgMHgzRilcblx0XHR9XG5cblx0XHQvLyBnbyB0aHJvdWdoIHRoZSBhcnJheSBldmVyeSB0aHJlZSBieXRlcywgd2UnbGwgZGVhbCB3aXRoIHRyYWlsaW5nIHN0dWZmIGxhdGVyXG5cdFx0Zm9yIChpID0gMCwgbGVuZ3RoID0gdWludDgubGVuZ3RoIC0gZXh0cmFCeXRlczsgaSA8IGxlbmd0aDsgaSArPSAzKSB7XG5cdFx0XHR0ZW1wID0gKHVpbnQ4W2ldIDw8IDE2KSArICh1aW50OFtpICsgMV0gPDwgOCkgKyAodWludDhbaSArIDJdKVxuXHRcdFx0b3V0cHV0ICs9IHRyaXBsZXRUb0Jhc2U2NCh0ZW1wKVxuXHRcdH1cblxuXHRcdC8vIHBhZCB0aGUgZW5kIHdpdGggemVyb3MsIGJ1dCBtYWtlIHN1cmUgdG8gbm90IGZvcmdldCB0aGUgZXh0cmEgYnl0ZXNcblx0XHRzd2l0Y2ggKGV4dHJhQnl0ZXMpIHtcblx0XHRcdGNhc2UgMTpcblx0XHRcdFx0dGVtcCA9IHVpbnQ4W3VpbnQ4Lmxlbmd0aCAtIDFdXG5cdFx0XHRcdG91dHB1dCArPSBlbmNvZGUodGVtcCA+PiAyKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wIDw8IDQpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9ICc9PSdcblx0XHRcdFx0YnJlYWtcblx0XHRcdGNhc2UgMjpcblx0XHRcdFx0dGVtcCA9ICh1aW50OFt1aW50OC5sZW5ndGggLSAyXSA8PCA4KSArICh1aW50OFt1aW50OC5sZW5ndGggLSAxXSlcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSh0ZW1wID4+IDEwKVxuXHRcdFx0XHRvdXRwdXQgKz0gZW5jb2RlKCh0ZW1wID4+IDQpICYgMHgzRilcblx0XHRcdFx0b3V0cHV0ICs9IGVuY29kZSgodGVtcCA8PCAyKSAmIDB4M0YpXG5cdFx0XHRcdG91dHB1dCArPSAnPSdcblx0XHRcdFx0YnJlYWtcblx0XHR9XG5cblx0XHRyZXR1cm4gb3V0cHV0XG5cdH1cblxuXHRleHBvcnRzLnRvQnl0ZUFycmF5ID0gYjY0VG9CeXRlQXJyYXlcblx0ZXhwb3J0cy5mcm9tQnl0ZUFycmF5ID0gdWludDhUb0Jhc2U2NFxufSh0eXBlb2YgZXhwb3J0cyA9PT0gJ3VuZGVmaW5lZCcgPyAodGhpcy5iYXNlNjRqcyA9IHt9KSA6IGV4cG9ydHMpKVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9ndWxwLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2J1ZmZlci9ub2RlX21vZHVsZXMvYmFzZTY0LWpzL2xpYi9iNjQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2Jhc2U2NC1qcy9saWJcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5leHBvcnRzLnJlYWQgPSBmdW5jdGlvbihidWZmZXIsIG9mZnNldCwgaXNMRSwgbUxlbiwgbkJ5dGVzKSB7XG4gIHZhciBlLCBtLFxuICAgICAgZUxlbiA9IG5CeXRlcyAqIDggLSBtTGVuIC0gMSxcbiAgICAgIGVNYXggPSAoMSA8PCBlTGVuKSAtIDEsXG4gICAgICBlQmlhcyA9IGVNYXggPj4gMSxcbiAgICAgIG5CaXRzID0gLTcsXG4gICAgICBpID0gaXNMRSA/IChuQnl0ZXMgLSAxKSA6IDAsXG4gICAgICBkID0gaXNMRSA/IC0xIDogMSxcbiAgICAgIHMgPSBidWZmZXJbb2Zmc2V0ICsgaV07XG5cbiAgaSArPSBkO1xuXG4gIGUgPSBzICYgKCgxIDw8ICgtbkJpdHMpKSAtIDEpO1xuICBzID4+PSAoLW5CaXRzKTtcbiAgbkJpdHMgKz0gZUxlbjtcbiAgZm9yICg7IG5CaXRzID4gMDsgZSA9IGUgKiAyNTYgKyBidWZmZXJbb2Zmc2V0ICsgaV0sIGkgKz0gZCwgbkJpdHMgLT0gOCk7XG5cbiAgbSA9IGUgJiAoKDEgPDwgKC1uQml0cykpIC0gMSk7XG4gIGUgPj49ICgtbkJpdHMpO1xuICBuQml0cyArPSBtTGVuO1xuICBmb3IgKDsgbkJpdHMgPiAwOyBtID0gbSAqIDI1NiArIGJ1ZmZlcltvZmZzZXQgKyBpXSwgaSArPSBkLCBuQml0cyAtPSA4KTtcblxuICBpZiAoZSA9PT0gMCkge1xuICAgIGUgPSAxIC0gZUJpYXM7XG4gIH0gZWxzZSBpZiAoZSA9PT0gZU1heCkge1xuICAgIHJldHVybiBtID8gTmFOIDogKChzID8gLTEgOiAxKSAqIEluZmluaXR5KTtcbiAgfSBlbHNlIHtcbiAgICBtID0gbSArIE1hdGgucG93KDIsIG1MZW4pO1xuICAgIGUgPSBlIC0gZUJpYXM7XG4gIH1cbiAgcmV0dXJuIChzID8gLTEgOiAxKSAqIG0gKiBNYXRoLnBvdygyLCBlIC0gbUxlbik7XG59O1xuXG5leHBvcnRzLndyaXRlID0gZnVuY3Rpb24oYnVmZmVyLCB2YWx1ZSwgb2Zmc2V0LCBpc0xFLCBtTGVuLCBuQnl0ZXMpIHtcbiAgdmFyIGUsIG0sIGMsXG4gICAgICBlTGVuID0gbkJ5dGVzICogOCAtIG1MZW4gLSAxLFxuICAgICAgZU1heCA9ICgxIDw8IGVMZW4pIC0gMSxcbiAgICAgIGVCaWFzID0gZU1heCA+PiAxLFxuICAgICAgcnQgPSAobUxlbiA9PT0gMjMgPyBNYXRoLnBvdygyLCAtMjQpIC0gTWF0aC5wb3coMiwgLTc3KSA6IDApLFxuICAgICAgaSA9IGlzTEUgPyAwIDogKG5CeXRlcyAtIDEpLFxuICAgICAgZCA9IGlzTEUgPyAxIDogLTEsXG4gICAgICBzID0gdmFsdWUgPCAwIHx8ICh2YWx1ZSA9PT0gMCAmJiAxIC8gdmFsdWUgPCAwKSA/IDEgOiAwO1xuXG4gIHZhbHVlID0gTWF0aC5hYnModmFsdWUpO1xuXG4gIGlmIChpc05hTih2YWx1ZSkgfHwgdmFsdWUgPT09IEluZmluaXR5KSB7XG4gICAgbSA9IGlzTmFOKHZhbHVlKSA/IDEgOiAwO1xuICAgIGUgPSBlTWF4O1xuICB9IGVsc2Uge1xuICAgIGUgPSBNYXRoLmZsb29yKE1hdGgubG9nKHZhbHVlKSAvIE1hdGguTE4yKTtcbiAgICBpZiAodmFsdWUgKiAoYyA9IE1hdGgucG93KDIsIC1lKSkgPCAxKSB7XG4gICAgICBlLS07XG4gICAgICBjICo9IDI7XG4gICAgfVxuICAgIGlmIChlICsgZUJpYXMgPj0gMSkge1xuICAgICAgdmFsdWUgKz0gcnQgLyBjO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YWx1ZSArPSBydCAqIE1hdGgucG93KDIsIDEgLSBlQmlhcyk7XG4gICAgfVxuICAgIGlmICh2YWx1ZSAqIGMgPj0gMikge1xuICAgICAgZSsrO1xuICAgICAgYyAvPSAyO1xuICAgIH1cblxuICAgIGlmIChlICsgZUJpYXMgPj0gZU1heCkge1xuICAgICAgbSA9IDA7XG4gICAgICBlID0gZU1heDtcbiAgICB9IGVsc2UgaWYgKGUgKyBlQmlhcyA+PSAxKSB7XG4gICAgICBtID0gKHZhbHVlICogYyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XG4gICAgICBlID0gZSArIGVCaWFzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gdmFsdWUgKiBNYXRoLnBvdygyLCBlQmlhcyAtIDEpICogTWF0aC5wb3coMiwgbUxlbik7XG4gICAgICBlID0gMDtcbiAgICB9XG4gIH1cblxuICBmb3IgKDsgbUxlbiA+PSA4OyBidWZmZXJbb2Zmc2V0ICsgaV0gPSBtICYgMHhmZiwgaSArPSBkLCBtIC89IDI1NiwgbUxlbiAtPSA4KTtcblxuICBlID0gKGUgPDwgbUxlbikgfCBtO1xuICBlTGVuICs9IG1MZW47XG4gIGZvciAoOyBlTGVuID4gMDsgYnVmZmVyW29mZnNldCArIGldID0gZSAmIDB4ZmYsIGkgKz0gZCwgZSAvPSAyNTYsIGVMZW4gLT0gOCk7XG5cbiAgYnVmZmVyW29mZnNldCArIGkgLSBkXSB8PSBzICogMTI4O1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2llZWU3NTQvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvZ3VscC1icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9idWZmZXIvbm9kZV9tb2R1bGVzL2llZWU3NTRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgSm95ZW50LCBJbmMuIGFuZCBvdGhlciBOb2RlIGNvbnRyaWJ1dG9ycy5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYVxuLy8gY29weSBvZiB0aGlzIHNvZnR3YXJlIGFuZCBhc3NvY2lhdGVkIGRvY3VtZW50YXRpb24gZmlsZXMgKHRoZVxuLy8gXCJTb2Z0d2FyZVwiKSwgdG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nXG4vLyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsXG4vLyBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0XG4vLyBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGVcbi8vIGZvbGxvd2luZyBjb25kaXRpb25zOlxuLy9cbi8vIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIHNoYWxsIGJlIGluY2x1ZGVkXG4vLyBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cbi8vXG4vLyBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTXG4vLyBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GXG4vLyBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOXG4vLyBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSxcbi8vIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUlxuLy8gT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRVxuLy8gVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cblxuZnVuY3Rpb24gRXZlbnRFbWl0dGVyKCkge1xuICB0aGlzLl9ldmVudHMgPSB0aGlzLl9ldmVudHMgfHwge307XG4gIHRoaXMuX21heExpc3RlbmVycyA9IHRoaXMuX21heExpc3RlbmVycyB8fCB1bmRlZmluZWQ7XG59XG5tb2R1bGUuZXhwb3J0cyA9IEV2ZW50RW1pdHRlcjtcblxuLy8gQmFja3dhcmRzLWNvbXBhdCB3aXRoIG5vZGUgMC4xMC54XG5FdmVudEVtaXR0ZXIuRXZlbnRFbWl0dGVyID0gRXZlbnRFbWl0dGVyO1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9ldmVudHMgPSB1bmRlZmluZWQ7XG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLl9tYXhMaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbi8vIEJ5IGRlZmF1bHQgRXZlbnRFbWl0dGVycyB3aWxsIHByaW50IGEgd2FybmluZyBpZiBtb3JlIHRoYW4gMTAgbGlzdGVuZXJzIGFyZVxuLy8gYWRkZWQgdG8gaXQuIFRoaXMgaXMgYSB1c2VmdWwgZGVmYXVsdCB3aGljaCBoZWxwcyBmaW5kaW5nIG1lbW9yeSBsZWFrcy5cbkV2ZW50RW1pdHRlci5kZWZhdWx0TWF4TGlzdGVuZXJzID0gMTA7XG5cbi8vIE9idmlvdXNseSBub3QgYWxsIEVtaXR0ZXJzIHNob3VsZCBiZSBsaW1pdGVkIHRvIDEwLiBUaGlzIGZ1bmN0aW9uIGFsbG93c1xuLy8gdGhhdCB0byBiZSBpbmNyZWFzZWQuIFNldCB0byB6ZXJvIGZvciB1bmxpbWl0ZWQuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnNldE1heExpc3RlbmVycyA9IGZ1bmN0aW9uKG4pIHtcbiAgaWYgKCFpc051bWJlcihuKSB8fCBuIDwgMCB8fCBpc05hTihuKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ24gbXVzdCBiZSBhIHBvc2l0aXZlIG51bWJlcicpO1xuICB0aGlzLl9tYXhMaXN0ZW5lcnMgPSBuO1xuICByZXR1cm4gdGhpcztcbn07XG5cbkV2ZW50RW1pdHRlci5wcm90b3R5cGUuZW1pdCA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGVyLCBoYW5kbGVyLCBsZW4sIGFyZ3MsIGksIGxpc3RlbmVycztcblxuICBpZiAoIXRoaXMuX2V2ZW50cylcbiAgICB0aGlzLl9ldmVudHMgPSB7fTtcblxuICAvLyBJZiB0aGVyZSBpcyBubyAnZXJyb3InIGV2ZW50IGxpc3RlbmVyIHRoZW4gdGhyb3cuXG4gIGlmICh0eXBlID09PSAnZXJyb3InKSB7XG4gICAgaWYgKCF0aGlzLl9ldmVudHMuZXJyb3IgfHxcbiAgICAgICAgKGlzT2JqZWN0KHRoaXMuX2V2ZW50cy5lcnJvcikgJiYgIXRoaXMuX2V2ZW50cy5lcnJvci5sZW5ndGgpKSB7XG4gICAgICBlciA9IGFyZ3VtZW50c1sxXTtcbiAgICAgIGlmIChlciBpbnN0YW5jZW9mIEVycm9yKSB7XG4gICAgICAgIHRocm93IGVyOyAvLyBVbmhhbmRsZWQgJ2Vycm9yJyBldmVudFxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhyb3cgVHlwZUVycm9yKCdVbmNhdWdodCwgdW5zcGVjaWZpZWQgXCJlcnJvclwiIGV2ZW50LicpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIGhhbmRsZXIgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzVW5kZWZpbmVkKGhhbmRsZXIpKVxuICAgIHJldHVybiBmYWxzZTtcblxuICBpZiAoaXNGdW5jdGlvbihoYW5kbGVyKSkge1xuICAgIHN3aXRjaCAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgLy8gZmFzdCBjYXNlc1xuICAgICAgY2FzZSAxOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcyk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAyOlxuICAgICAgICBoYW5kbGVyLmNhbGwodGhpcywgYXJndW1lbnRzWzFdKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIDM6XG4gICAgICAgIGhhbmRsZXIuY2FsbCh0aGlzLCBhcmd1bWVudHNbMV0sIGFyZ3VtZW50c1syXSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgLy8gc2xvd2VyXG4gICAgICBkZWZhdWx0OlxuICAgICAgICBsZW4gPSBhcmd1bWVudHMubGVuZ3RoO1xuICAgICAgICBhcmdzID0gbmV3IEFycmF5KGxlbiAtIDEpO1xuICAgICAgICBmb3IgKGkgPSAxOyBpIDwgbGVuOyBpKyspXG4gICAgICAgICAgYXJnc1tpIC0gMV0gPSBhcmd1bWVudHNbaV07XG4gICAgICAgIGhhbmRsZXIuYXBwbHkodGhpcywgYXJncyk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGlzT2JqZWN0KGhhbmRsZXIpKSB7XG4gICAgbGVuID0gYXJndW1lbnRzLmxlbmd0aDtcbiAgICBhcmdzID0gbmV3IEFycmF5KGxlbiAtIDEpO1xuICAgIGZvciAoaSA9IDE7IGkgPCBsZW47IGkrKylcbiAgICAgIGFyZ3NbaSAtIDFdID0gYXJndW1lbnRzW2ldO1xuXG4gICAgbGlzdGVuZXJzID0gaGFuZGxlci5zbGljZSgpO1xuICAgIGxlbiA9IGxpc3RlbmVycy5sZW5ndGg7XG4gICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKVxuICAgICAgbGlzdGVuZXJzW2ldLmFwcGx5KHRoaXMsIGFyZ3MpO1xuICB9XG5cbiAgcmV0dXJuIHRydWU7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmFkZExpc3RlbmVyID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgdmFyIG07XG5cbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuXG4gIC8vIFRvIGF2b2lkIHJlY3Vyc2lvbiBpbiB0aGUgY2FzZSB0aGF0IHR5cGUgPT09IFwibmV3TGlzdGVuZXJcIiEgQmVmb3JlXG4gIC8vIGFkZGluZyBpdCB0byB0aGUgbGlzdGVuZXJzLCBmaXJzdCBlbWl0IFwibmV3TGlzdGVuZXJcIi5cbiAgaWYgKHRoaXMuX2V2ZW50cy5uZXdMaXN0ZW5lcilcbiAgICB0aGlzLmVtaXQoJ25ld0xpc3RlbmVyJywgdHlwZSxcbiAgICAgICAgICAgICAgaXNGdW5jdGlvbihsaXN0ZW5lci5saXN0ZW5lcikgP1xuICAgICAgICAgICAgICBsaXN0ZW5lci5saXN0ZW5lciA6IGxpc3RlbmVyKTtcblxuICBpZiAoIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAvLyBPcHRpbWl6ZSB0aGUgY2FzZSBvZiBvbmUgbGlzdGVuZXIuIERvbid0IG5lZWQgdGhlIGV4dHJhIGFycmF5IG9iamVjdC5cbiAgICB0aGlzLl9ldmVudHNbdHlwZV0gPSBsaXN0ZW5lcjtcbiAgZWxzZSBpZiAoaXNPYmplY3QodGhpcy5fZXZlbnRzW3R5cGVdKSlcbiAgICAvLyBJZiB3ZSd2ZSBhbHJlYWR5IGdvdCBhbiBhcnJheSwganVzdCBhcHBlbmQuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdLnB1c2gobGlzdGVuZXIpO1xuICBlbHNlXG4gICAgLy8gQWRkaW5nIHRoZSBzZWNvbmQgZWxlbWVudCwgbmVlZCB0byBjaGFuZ2UgdG8gYXJyYXkuXG4gICAgdGhpcy5fZXZlbnRzW3R5cGVdID0gW3RoaXMuX2V2ZW50c1t0eXBlXSwgbGlzdGVuZXJdO1xuXG4gIC8vIENoZWNrIGZvciBsaXN0ZW5lciBsZWFrXG4gIGlmIChpc09iamVjdCh0aGlzLl9ldmVudHNbdHlwZV0pICYmICF0aGlzLl9ldmVudHNbdHlwZV0ud2FybmVkKSB7XG4gICAgdmFyIG07XG4gICAgaWYgKCFpc1VuZGVmaW5lZCh0aGlzLl9tYXhMaXN0ZW5lcnMpKSB7XG4gICAgICBtID0gdGhpcy5fbWF4TGlzdGVuZXJzO1xuICAgIH0gZWxzZSB7XG4gICAgICBtID0gRXZlbnRFbWl0dGVyLmRlZmF1bHRNYXhMaXN0ZW5lcnM7XG4gICAgfVxuXG4gICAgaWYgKG0gJiYgbSA+IDAgJiYgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCA+IG0pIHtcbiAgICAgIHRoaXMuX2V2ZW50c1t0eXBlXS53YXJuZWQgPSB0cnVlO1xuICAgICAgY29uc29sZS5lcnJvcignKG5vZGUpIHdhcm5pbmc6IHBvc3NpYmxlIEV2ZW50RW1pdHRlciBtZW1vcnkgJyArXG4gICAgICAgICAgICAgICAgICAgICdsZWFrIGRldGVjdGVkLiAlZCBsaXN0ZW5lcnMgYWRkZWQuICcgK1xuICAgICAgICAgICAgICAgICAgICAnVXNlIGVtaXR0ZXIuc2V0TWF4TGlzdGVuZXJzKCkgdG8gaW5jcmVhc2UgbGltaXQuJyxcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5fZXZlbnRzW3R5cGVdLmxlbmd0aCk7XG4gICAgICBpZiAodHlwZW9mIGNvbnNvbGUudHJhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgLy8gbm90IHN1cHBvcnRlZCBpbiBJRSAxMFxuICAgICAgICBjb25zb2xlLnRyYWNlKCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLm9uID0gRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5hZGRMaXN0ZW5lcjtcblxuRXZlbnRFbWl0dGVyLnByb3RvdHlwZS5vbmNlID0gZnVuY3Rpb24odHlwZSwgbGlzdGVuZXIpIHtcbiAgaWYgKCFpc0Z1bmN0aW9uKGxpc3RlbmVyKSlcbiAgICB0aHJvdyBUeXBlRXJyb3IoJ2xpc3RlbmVyIG11c3QgYmUgYSBmdW5jdGlvbicpO1xuXG4gIHZhciBmaXJlZCA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGcoKSB7XG4gICAgdGhpcy5yZW1vdmVMaXN0ZW5lcih0eXBlLCBnKTtcblxuICAgIGlmICghZmlyZWQpIHtcbiAgICAgIGZpcmVkID0gdHJ1ZTtcbiAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuICB9XG5cbiAgZy5saXN0ZW5lciA9IGxpc3RlbmVyO1xuICB0aGlzLm9uKHR5cGUsIGcpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gZW1pdHMgYSAncmVtb3ZlTGlzdGVuZXInIGV2ZW50IGlmZiB0aGUgbGlzdGVuZXIgd2FzIHJlbW92ZWRcbkV2ZW50RW1pdHRlci5wcm90b3R5cGUucmVtb3ZlTGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBsaXN0ZW5lcikge1xuICB2YXIgbGlzdCwgcG9zaXRpb24sIGxlbmd0aCwgaTtcblxuICBpZiAoIWlzRnVuY3Rpb24obGlzdGVuZXIpKVxuICAgIHRocm93IFR5cGVFcnJvcignbGlzdGVuZXIgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXR1cm4gdGhpcztcblxuICBsaXN0ID0gdGhpcy5fZXZlbnRzW3R5cGVdO1xuICBsZW5ndGggPSBsaXN0Lmxlbmd0aDtcbiAgcG9zaXRpb24gPSAtMTtcblxuICBpZiAobGlzdCA9PT0gbGlzdGVuZXIgfHxcbiAgICAgIChpc0Z1bmN0aW9uKGxpc3QubGlzdGVuZXIpICYmIGxpc3QubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgaWYgKHRoaXMuX2V2ZW50cy5yZW1vdmVMaXN0ZW5lcilcbiAgICAgIHRoaXMuZW1pdCgncmVtb3ZlTGlzdGVuZXInLCB0eXBlLCBsaXN0ZW5lcik7XG5cbiAgfSBlbHNlIGlmIChpc09iamVjdChsaXN0KSkge1xuICAgIGZvciAoaSA9IGxlbmd0aDsgaS0tID4gMDspIHtcbiAgICAgIGlmIChsaXN0W2ldID09PSBsaXN0ZW5lciB8fFxuICAgICAgICAgIChsaXN0W2ldLmxpc3RlbmVyICYmIGxpc3RbaV0ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSkge1xuICAgICAgICBwb3NpdGlvbiA9IGk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwb3NpdGlvbiA8IDApXG4gICAgICByZXR1cm4gdGhpcztcblxuICAgIGlmIChsaXN0Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgbGlzdC5sZW5ndGggPSAwO1xuICAgICAgZGVsZXRlIHRoaXMuX2V2ZW50c1t0eXBlXTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGlzdC5zcGxpY2UocG9zaXRpb24sIDEpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpXG4gICAgICB0aGlzLmVtaXQoJ3JlbW92ZUxpc3RlbmVyJywgdHlwZSwgbGlzdGVuZXIpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLnJlbW92ZUFsbExpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIGtleSwgbGlzdGVuZXJzO1xuXG4gIGlmICghdGhpcy5fZXZlbnRzKVxuICAgIHJldHVybiB0aGlzO1xuXG4gIC8vIG5vdCBsaXN0ZW5pbmcgZm9yIHJlbW92ZUxpc3RlbmVyLCBubyBuZWVkIHRvIGVtaXRcbiAgaWYgKCF0aGlzLl9ldmVudHMucmVtb3ZlTGlzdGVuZXIpIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMClcbiAgICAgIHRoaXMuX2V2ZW50cyA9IHt9O1xuICAgIGVsc2UgaWYgKHRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICAgIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvLyBlbWl0IHJlbW92ZUxpc3RlbmVyIGZvciBhbGwgbGlzdGVuZXJzIG9uIGFsbCBldmVudHNcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDApIHtcbiAgICBmb3IgKGtleSBpbiB0aGlzLl9ldmVudHMpIHtcbiAgICAgIGlmIChrZXkgPT09ICdyZW1vdmVMaXN0ZW5lcicpIGNvbnRpbnVlO1xuICAgICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoa2V5KTtcbiAgICB9XG4gICAgdGhpcy5yZW1vdmVBbGxMaXN0ZW5lcnMoJ3JlbW92ZUxpc3RlbmVyJyk7XG4gICAgdGhpcy5fZXZlbnRzID0ge307XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICBsaXN0ZW5lcnMgPSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgaWYgKGlzRnVuY3Rpb24obGlzdGVuZXJzKSkge1xuICAgIHRoaXMucmVtb3ZlTGlzdGVuZXIodHlwZSwgbGlzdGVuZXJzKTtcbiAgfSBlbHNlIHtcbiAgICAvLyBMSUZPIG9yZGVyXG4gICAgd2hpbGUgKGxpc3RlbmVycy5sZW5ndGgpXG4gICAgICB0aGlzLnJlbW92ZUxpc3RlbmVyKHR5cGUsIGxpc3RlbmVyc1tsaXN0ZW5lcnMubGVuZ3RoIC0gMV0pO1xuICB9XG4gIGRlbGV0ZSB0aGlzLl9ldmVudHNbdHlwZV07XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5FdmVudEVtaXR0ZXIucHJvdG90eXBlLmxpc3RlbmVycyA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgdmFyIHJldDtcbiAgaWYgKCF0aGlzLl9ldmVudHMgfHwgIXRoaXMuX2V2ZW50c1t0eXBlXSlcbiAgICByZXQgPSBbXTtcbiAgZWxzZSBpZiAoaXNGdW5jdGlvbih0aGlzLl9ldmVudHNbdHlwZV0pKVxuICAgIHJldCA9IFt0aGlzLl9ldmVudHNbdHlwZV1dO1xuICBlbHNlXG4gICAgcmV0ID0gdGhpcy5fZXZlbnRzW3R5cGVdLnNsaWNlKCk7XG4gIHJldHVybiByZXQ7XG59O1xuXG5FdmVudEVtaXR0ZXIubGlzdGVuZXJDb3VudCA9IGZ1bmN0aW9uKGVtaXR0ZXIsIHR5cGUpIHtcbiAgdmFyIHJldDtcbiAgaWYgKCFlbWl0dGVyLl9ldmVudHMgfHwgIWVtaXR0ZXIuX2V2ZW50c1t0eXBlXSlcbiAgICByZXQgPSAwO1xuICBlbHNlIGlmIChpc0Z1bmN0aW9uKGVtaXR0ZXIuX2V2ZW50c1t0eXBlXSkpXG4gICAgcmV0ID0gMTtcbiAgZWxzZVxuICAgIHJldCA9IGVtaXR0ZXIuX2V2ZW50c1t0eXBlXS5sZW5ndGg7XG4gIHJldHVybiByZXQ7XG59O1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cblxuZnVuY3Rpb24gaXNPYmplY3QoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnb2JqZWN0JyAmJiBhcmcgIT09IG51bGw7XG59XG5cbmZ1bmN0aW9uIGlzVW5kZWZpbmVkKGFyZykge1xuICByZXR1cm4gYXJnID09PSB2b2lkIDA7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2d1bHAtYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvYnJvd3NlcmlmeS9ub2RlX21vZHVsZXMvZXZlbnRzL2V2ZW50cy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9ndWxwLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2V2ZW50c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIHNoaW0gZm9yIHVzaW5nIHByb2Nlc3MgaW4gYnJvd3NlclxuXG52YXIgcHJvY2VzcyA9IG1vZHVsZS5leHBvcnRzID0ge307XG5cbnByb2Nlc3MubmV4dFRpY2sgPSAoZnVuY3Rpb24gKCkge1xuICAgIHZhciBjYW5TZXRJbW1lZGlhdGUgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5zZXRJbW1lZGlhdGU7XG4gICAgdmFyIGNhblBvc3QgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIHdpbmRvdy5wb3N0TWVzc2FnZSAmJiB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lclxuICAgIDtcblxuICAgIGlmIChjYW5TZXRJbW1lZGlhdGUpIHtcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChmKSB7IHJldHVybiB3aW5kb3cuc2V0SW1tZWRpYXRlKGYpIH07XG4gICAgfVxuXG4gICAgaWYgKGNhblBvc3QpIHtcbiAgICAgICAgdmFyIHF1ZXVlID0gW107XG4gICAgICAgIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgZnVuY3Rpb24gKGV2KSB7XG4gICAgICAgICAgICB2YXIgc291cmNlID0gZXYuc291cmNlO1xuICAgICAgICAgICAgaWYgKChzb3VyY2UgPT09IHdpbmRvdyB8fCBzb3VyY2UgPT09IG51bGwpICYmIGV2LmRhdGEgPT09ICdwcm9jZXNzLXRpY2snKSB7XG4gICAgICAgICAgICAgICAgZXYuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgaWYgKHF1ZXVlLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIGZuID0gcXVldWUuc2hpZnQoKTtcbiAgICAgICAgICAgICAgICAgICAgZm4oKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0sIHRydWUpO1xuXG4gICAgICAgIHJldHVybiBmdW5jdGlvbiBuZXh0VGljayhmbikge1xuICAgICAgICAgICAgcXVldWUucHVzaChmbik7XG4gICAgICAgICAgICB3aW5kb3cucG9zdE1lc3NhZ2UoJ3Byb2Nlc3MtdGljaycsICcqJyk7XG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgcmV0dXJuIGZ1bmN0aW9uIG5leHRUaWNrKGZuKSB7XG4gICAgICAgIHNldFRpbWVvdXQoZm4sIDApO1xuICAgIH07XG59KSgpO1xuXG5wcm9jZXNzLnRpdGxlID0gJ2Jyb3dzZXInO1xucHJvY2Vzcy5icm93c2VyID0gdHJ1ZTtcbnByb2Nlc3MuZW52ID0ge307XG5wcm9jZXNzLmFyZ3YgPSBbXTtcblxuZnVuY3Rpb24gbm9vcCgpIHt9XG5cbnByb2Nlc3Mub24gPSBub29wO1xucHJvY2Vzcy5hZGRMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLm9uY2UgPSBub29wO1xucHJvY2Vzcy5vZmYgPSBub29wO1xucHJvY2Vzcy5yZW1vdmVMaXN0ZW5lciA9IG5vb3A7XG5wcm9jZXNzLnJlbW92ZUFsbExpc3RlbmVycyA9IG5vb3A7XG5wcm9jZXNzLmVtaXQgPSBub29wO1xuXG5wcm9jZXNzLmJpbmRpbmcgPSBmdW5jdGlvbiAobmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5iaW5kaW5nIGlzIG5vdCBzdXBwb3J0ZWQnKTtcbn1cblxuLy8gVE9ETyhzaHR5bG1hbilcbnByb2Nlc3MuY3dkID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gJy8nIH07XG5wcm9jZXNzLmNoZGlyID0gZnVuY3Rpb24gKGRpcikge1xuICAgIHRocm93IG5ldyBFcnJvcigncHJvY2Vzcy5jaGRpciBpcyBub3Qgc3VwcG9ydGVkJyk7XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9ndWxwLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3MvYnJvd3Nlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9ndWxwLWJyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL2Jyb3dzZXJpZnkvbm9kZV9tb2R1bGVzL3Byb2Nlc3NcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgc3BsaXQgPSByZXF1aXJlKCdicm93c2VyLXNwbGl0JylcbnZhciBDbGFzc0xpc3QgPSByZXF1aXJlKCdjbGFzcy1saXN0JylcbnZhciBEYXRhU2V0ID0gcmVxdWlyZSgnZGF0YS1zZXQnKVxucmVxdWlyZSgnaHRtbC1lbGVtZW50JylcblxuZnVuY3Rpb24gY29udGV4dCAoKSB7XG5cbiAgdmFyIGNsZWFudXBGdW5jcyA9IFtdXG5cbiAgZnVuY3Rpb24gaCgpIHtcbiAgICB2YXIgYXJncyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzKSwgZSA9IG51bGxcbiAgICBmdW5jdGlvbiBpdGVtIChsKSB7XG4gICAgICB2YXIgclxuICAgICAgZnVuY3Rpb24gcGFyc2VDbGFzcyAoc3RyaW5nKSB7XG4gICAgICAgIHZhciBtID0gc3BsaXQoc3RyaW5nLCAvKFtcXC4jXT9bYS16QS1aMC05XzotXSspLylcbiAgICAgICAgaWYoL15cXC58Iy8udGVzdChtWzFdKSlcbiAgICAgICAgICBlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2JylcbiAgICAgICAgZm9yRWFjaChtLCBmdW5jdGlvbiAodikge1xuICAgICAgICAgIHZhciBzID0gdi5zdWJzdHJpbmcoMSx2Lmxlbmd0aClcbiAgICAgICAgICBpZighdikgcmV0dXJuXG4gICAgICAgICAgaWYoIWUpXG4gICAgICAgICAgICBlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh2KVxuICAgICAgICAgIGVsc2UgaWYgKHZbMF0gPT09ICcuJylcbiAgICAgICAgICAgIENsYXNzTGlzdChlKS5hZGQocylcbiAgICAgICAgICBlbHNlIGlmICh2WzBdID09PSAnIycpXG4gICAgICAgICAgICBlLnNldEF0dHJpYnV0ZSgnaWQnLCBzKVxuICAgICAgICB9KVxuICAgICAgfVxuXG4gICAgICBpZihsID09IG51bGwpXG4gICAgICAgIDtcbiAgICAgIGVsc2UgaWYoJ3N0cmluZycgPT09IHR5cGVvZiBsKSB7XG4gICAgICAgIGlmKCFlKVxuICAgICAgICAgIHBhcnNlQ2xhc3MobClcbiAgICAgICAgZWxzZVxuICAgICAgICAgIGUuYXBwZW5kQ2hpbGQociA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGwpKVxuICAgICAgfVxuICAgICAgZWxzZSBpZignbnVtYmVyJyA9PT0gdHlwZW9mIGxcbiAgICAgICAgfHwgJ2Jvb2xlYW4nID09PSB0eXBlb2YgbFxuICAgICAgICB8fCBsIGluc3RhbmNlb2YgRGF0ZVxuICAgICAgICB8fCBsIGluc3RhbmNlb2YgUmVnRXhwICkge1xuICAgICAgICAgIGUuYXBwZW5kQ2hpbGQociA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGwudG9TdHJpbmcoKSkpXG4gICAgICB9XG4gICAgICAvL3RoZXJlIG1pZ2h0IGJlIGEgYmV0dGVyIHdheSB0byBoYW5kbGUgdGhpcy4uLlxuICAgICAgZWxzZSBpZiAoaXNBcnJheShsKSlcbiAgICAgICAgZm9yRWFjaChsLCBpdGVtKVxuICAgICAgZWxzZSBpZihpc05vZGUobCkpXG4gICAgICAgIGUuYXBwZW5kQ2hpbGQociA9IGwpXG4gICAgICBlbHNlIGlmKGwgaW5zdGFuY2VvZiBUZXh0KVxuICAgICAgICBlLmFwcGVuZENoaWxkKHIgPSBsKVxuICAgICAgZWxzZSBpZiAoJ29iamVjdCcgPT09IHR5cGVvZiBsKSB7XG4gICAgICAgIGZvciAodmFyIGsgaW4gbCkge1xuICAgICAgICAgIGlmKCdmdW5jdGlvbicgPT09IHR5cGVvZiBsW2tdKSB7XG4gICAgICAgICAgICBpZigvXm9uXFx3Ky8udGVzdChrKSkge1xuICAgICAgICAgICAgICBpZiAoZS5hZGRFdmVudExpc3RlbmVyKXtcbiAgICAgICAgICAgICAgICBlLmFkZEV2ZW50TGlzdGVuZXIoay5zdWJzdHJpbmcoMiksIGxba10sIGZhbHNlKVxuICAgICAgICAgICAgICAgIGNsZWFudXBGdW5jcy5wdXNoKGZ1bmN0aW9uKCl7XG4gICAgICAgICAgICAgICAgICBlLnJlbW92ZUV2ZW50TGlzdGVuZXIoay5zdWJzdHJpbmcoMiksIGxba10sIGZhbHNlKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICAgIGUuYXR0YWNoRXZlbnQoaywgbFtrXSlcbiAgICAgICAgICAgICAgICBjbGVhbnVwRnVuY3MucHVzaChmdW5jdGlvbigpe1xuICAgICAgICAgICAgICAgICAgZS5kZXRhY2hFdmVudChrLCBsW2tdKVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIC8vIG9ic2VydmFibGVcbiAgICAgICAgICAgICAgZVtrXSA9IGxba10oKVxuICAgICAgICAgICAgICBjbGVhbnVwRnVuY3MucHVzaChsW2tdKGZ1bmN0aW9uICh2KSB7XG4gICAgICAgICAgICAgICAgZVtrXSA9IHZcbiAgICAgICAgICAgICAgfSkpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGVsc2UgaWYoayA9PT0gJ3N0eWxlJykge1xuICAgICAgICAgICAgaWYoJ3N0cmluZycgPT09IHR5cGVvZiBsW2tdKSB7XG4gICAgICAgICAgICAgIGUuc3R5bGUuY3NzVGV4dCA9IGxba11cbiAgICAgICAgICAgIH1lbHNle1xuICAgICAgICAgICAgICBmb3IgKHZhciBzIGluIGxba10pIChmdW5jdGlvbihzLCB2KSB7XG4gICAgICAgICAgICAgICAgaWYoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIHYpIHtcbiAgICAgICAgICAgICAgICAgIC8vIG9ic2VydmFibGVcbiAgICAgICAgICAgICAgICAgIGUuc3R5bGUuc2V0UHJvcGVydHkocywgdigpKVxuICAgICAgICAgICAgICAgICAgY2xlYW51cEZ1bmNzLnB1c2godihmdW5jdGlvbiAodmFsKSB7XG4gICAgICAgICAgICAgICAgICAgIGUuc3R5bGUuc2V0UHJvcGVydHkocywgdmFsKVxuICAgICAgICAgICAgICAgICAgfSkpXG4gICAgICAgICAgICAgICAgfSBlbHNlXG4gICAgICAgICAgICAgICAgICBlLnN0eWxlLnNldFByb3BlcnR5KHMsIGxba11bc10pXG4gICAgICAgICAgICAgIH0pKHMsIGxba11bc10pXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSBlbHNlIGlmIChrLnN1YnN0cigwLCA1KSA9PT0gXCJkYXRhLVwiKSB7XG4gICAgICAgICAgICBEYXRhU2V0KGUpW2suc3Vic3RyKDUpXSA9IGxba11cbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZVtrXSA9IGxba11cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoJ2Z1bmN0aW9uJyA9PT0gdHlwZW9mIGwpIHtcbiAgICAgICAgLy9hc3N1bWUgaXQncyBhbiBvYnNlcnZhYmxlIVxuICAgICAgICB2YXIgdiA9IGwoKVxuICAgICAgICBlLmFwcGVuZENoaWxkKHIgPSBpc05vZGUodikgPyB2IDogZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUodikpXG5cbiAgICAgICAgY2xlYW51cEZ1bmNzLnB1c2gobChmdW5jdGlvbiAodikge1xuICAgICAgICAgIGlmKGlzTm9kZSh2KSAmJiByLnBhcmVudEVsZW1lbnQpXG4gICAgICAgICAgICByLnBhcmVudEVsZW1lbnQucmVwbGFjZUNoaWxkKHYsIHIpLCByID0gdlxuICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgIHIudGV4dENvbnRlbnQgPSB2XG4gICAgICAgIH0pKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gclxuICAgIH1cbiAgICB3aGlsZShhcmdzLmxlbmd0aClcbiAgICAgIGl0ZW0oYXJncy5zaGlmdCgpKVxuXG4gICAgcmV0dXJuIGVcbiAgfVxuXG4gIGguY2xlYW51cCA9IGZ1bmN0aW9uICgpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNsZWFudXBGdW5jcy5sZW5ndGg7IGkrKyl7XG4gICAgICBjbGVhbnVwRnVuY3NbaV0oKVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBoXG59XG5cbnZhciBoID0gbW9kdWxlLmV4cG9ydHMgPSBjb250ZXh0KClcbmguY29udGV4dCA9IGNvbnRleHRcblxuZnVuY3Rpb24gaXNOb2RlIChlbCkge1xuICByZXR1cm4gZWwgJiYgZWwubm9kZU5hbWUgJiYgZWwubm9kZVR5cGVcbn1cblxuZnVuY3Rpb24gaXNUZXh0IChlbCkge1xuICByZXR1cm4gZWwgJiYgZWwubm9kZU5hbWUgPT09ICcjdGV4dCcgJiYgZWwubm9kZVR5cGUgPT0gM1xufVxuXG5mdW5jdGlvbiBmb3JFYWNoIChhcnIsIGZuKSB7XG4gIGlmIChhcnIuZm9yRWFjaCkgcmV0dXJuIGFyci5mb3JFYWNoKGZuKVxuICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykgZm4oYXJyW2ldLCBpKVxufVxuXG5mdW5jdGlvbiBpc0FycmF5IChhcnIpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChhcnIpID09ICdbb2JqZWN0IEFycmF5XSdcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHQvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKiFcbiAqIENyb3NzLUJyb3dzZXIgU3BsaXQgMS4xLjFcbiAqIENvcHlyaWdodCAyMDA3LTIwMTIgU3RldmVuIExldml0aGFuIDxzdGV2ZW5sZXZpdGhhbi5jb20+XG4gKiBBdmFpbGFibGUgdW5kZXIgdGhlIE1JVCBMaWNlbnNlXG4gKiBFQ01BU2NyaXB0IGNvbXBsaWFudCwgdW5pZm9ybSBjcm9zcy1icm93c2VyIHNwbGl0IG1ldGhvZFxuICovXG5cbi8qKlxuICogU3BsaXRzIGEgc3RyaW5nIGludG8gYW4gYXJyYXkgb2Ygc3RyaW5ncyB1c2luZyBhIHJlZ2V4IG9yIHN0cmluZyBzZXBhcmF0b3IuIE1hdGNoZXMgb2YgdGhlXG4gKiBzZXBhcmF0b3IgYXJlIG5vdCBpbmNsdWRlZCBpbiB0aGUgcmVzdWx0IGFycmF5LiBIb3dldmVyLCBpZiBgc2VwYXJhdG9yYCBpcyBhIHJlZ2V4IHRoYXQgY29udGFpbnNcbiAqIGNhcHR1cmluZyBncm91cHMsIGJhY2tyZWZlcmVuY2VzIGFyZSBzcGxpY2VkIGludG8gdGhlIHJlc3VsdCBlYWNoIHRpbWUgYHNlcGFyYXRvcmAgaXMgbWF0Y2hlZC5cbiAqIEZpeGVzIGJyb3dzZXIgYnVncyBjb21wYXJlZCB0byB0aGUgbmF0aXZlIGBTdHJpbmcucHJvdG90eXBlLnNwbGl0YCBhbmQgY2FuIGJlIHVzZWQgcmVsaWFibHlcbiAqIGNyb3NzLWJyb3dzZXIuXG4gKiBAcGFyYW0ge1N0cmluZ30gc3RyIFN0cmluZyB0byBzcGxpdC5cbiAqIEBwYXJhbSB7UmVnRXhwfFN0cmluZ30gc2VwYXJhdG9yIFJlZ2V4IG9yIHN0cmluZyB0byB1c2UgZm9yIHNlcGFyYXRpbmcgdGhlIHN0cmluZy5cbiAqIEBwYXJhbSB7TnVtYmVyfSBbbGltaXRdIE1heGltdW0gbnVtYmVyIG9mIGl0ZW1zIHRvIGluY2x1ZGUgaW4gdGhlIHJlc3VsdCBhcnJheS5cbiAqIEByZXR1cm5zIHtBcnJheX0gQXJyYXkgb2Ygc3Vic3RyaW5ncy5cbiAqIEBleGFtcGxlXG4gKlxuICogLy8gQmFzaWMgdXNlXG4gKiBzcGxpdCgnYSBiIGMgZCcsICcgJyk7XG4gKiAvLyAtPiBbJ2EnLCAnYicsICdjJywgJ2QnXVxuICpcbiAqIC8vIFdpdGggbGltaXRcbiAqIHNwbGl0KCdhIGIgYyBkJywgJyAnLCAyKTtcbiAqIC8vIC0+IFsnYScsICdiJ11cbiAqXG4gKiAvLyBCYWNrcmVmZXJlbmNlcyBpbiByZXN1bHQgYXJyYXlcbiAqIHNwbGl0KCcuLndvcmQxIHdvcmQyLi4nLCAvKFthLXpdKykoXFxkKykvaSk7XG4gKiAvLyAtPiBbJy4uJywgJ3dvcmQnLCAnMScsICcgJywgJ3dvcmQnLCAnMicsICcuLiddXG4gKi9cbm1vZHVsZS5leHBvcnRzID0gKGZ1bmN0aW9uIHNwbGl0KHVuZGVmKSB7XG5cbiAgdmFyIG5hdGl2ZVNwbGl0ID0gU3RyaW5nLnByb3RvdHlwZS5zcGxpdCxcbiAgICBjb21wbGlhbnRFeGVjTnBjZyA9IC8oKT8/Ly5leGVjKFwiXCIpWzFdID09PSB1bmRlZixcbiAgICAvLyBOUENHOiBub25wYXJ0aWNpcGF0aW5nIGNhcHR1cmluZyBncm91cFxuICAgIHNlbGY7XG5cbiAgc2VsZiA9IGZ1bmN0aW9uKHN0ciwgc2VwYXJhdG9yLCBsaW1pdCkge1xuICAgIC8vIElmIGBzZXBhcmF0b3JgIGlzIG5vdCBhIHJlZ2V4LCB1c2UgYG5hdGl2ZVNwbGl0YFxuICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoc2VwYXJhdG9yKSAhPT0gXCJbb2JqZWN0IFJlZ0V4cF1cIikge1xuICAgICAgcmV0dXJuIG5hdGl2ZVNwbGl0LmNhbGwoc3RyLCBzZXBhcmF0b3IsIGxpbWl0KTtcbiAgICB9XG4gICAgdmFyIG91dHB1dCA9IFtdLFxuICAgICAgZmxhZ3MgPSAoc2VwYXJhdG9yLmlnbm9yZUNhc2UgPyBcImlcIiA6IFwiXCIpICsgKHNlcGFyYXRvci5tdWx0aWxpbmUgPyBcIm1cIiA6IFwiXCIpICsgKHNlcGFyYXRvci5leHRlbmRlZCA/IFwieFwiIDogXCJcIikgKyAvLyBQcm9wb3NlZCBmb3IgRVM2XG4gICAgICAoc2VwYXJhdG9yLnN0aWNreSA/IFwieVwiIDogXCJcIiksXG4gICAgICAvLyBGaXJlZm94IDMrXG4gICAgICBsYXN0TGFzdEluZGV4ID0gMCxcbiAgICAgIC8vIE1ha2UgYGdsb2JhbGAgYW5kIGF2b2lkIGBsYXN0SW5kZXhgIGlzc3VlcyBieSB3b3JraW5nIHdpdGggYSBjb3B5XG4gICAgICBzZXBhcmF0b3IgPSBuZXcgUmVnRXhwKHNlcGFyYXRvci5zb3VyY2UsIGZsYWdzICsgXCJnXCIpLFxuICAgICAgc2VwYXJhdG9yMiwgbWF0Y2gsIGxhc3RJbmRleCwgbGFzdExlbmd0aDtcbiAgICBzdHIgKz0gXCJcIjsgLy8gVHlwZS1jb252ZXJ0XG4gICAgaWYgKCFjb21wbGlhbnRFeGVjTnBjZykge1xuICAgICAgLy8gRG9lc24ndCBuZWVkIGZsYWdzIGd5LCBidXQgdGhleSBkb24ndCBodXJ0XG4gICAgICBzZXBhcmF0b3IyID0gbmV3IFJlZ0V4cChcIl5cIiArIHNlcGFyYXRvci5zb3VyY2UgKyBcIiQoPyFcXFxccylcIiwgZmxhZ3MpO1xuICAgIH1cbiAgICAvKiBWYWx1ZXMgZm9yIGBsaW1pdGAsIHBlciB0aGUgc3BlYzpcbiAgICAgKiBJZiB1bmRlZmluZWQ6IDQyOTQ5NjcyOTUgLy8gTWF0aC5wb3coMiwgMzIpIC0gMVxuICAgICAqIElmIDAsIEluZmluaXR5LCBvciBOYU46IDBcbiAgICAgKiBJZiBwb3NpdGl2ZSBudW1iZXI6IGxpbWl0ID0gTWF0aC5mbG9vcihsaW1pdCk7IGlmIChsaW1pdCA+IDQyOTQ5NjcyOTUpIGxpbWl0IC09IDQyOTQ5NjcyOTY7XG4gICAgICogSWYgbmVnYXRpdmUgbnVtYmVyOiA0Mjk0OTY3Mjk2IC0gTWF0aC5mbG9vcihNYXRoLmFicyhsaW1pdCkpXG4gICAgICogSWYgb3RoZXI6IFR5cGUtY29udmVydCwgdGhlbiB1c2UgdGhlIGFib3ZlIHJ1bGVzXG4gICAgICovXG4gICAgbGltaXQgPSBsaW1pdCA9PT0gdW5kZWYgPyAtMSA+Pj4gMCA6IC8vIE1hdGgucG93KDIsIDMyKSAtIDFcbiAgICBsaW1pdCA+Pj4gMDsgLy8gVG9VaW50MzIobGltaXQpXG4gICAgd2hpbGUgKG1hdGNoID0gc2VwYXJhdG9yLmV4ZWMoc3RyKSkge1xuICAgICAgLy8gYHNlcGFyYXRvci5sYXN0SW5kZXhgIGlzIG5vdCByZWxpYWJsZSBjcm9zcy1icm93c2VyXG4gICAgICBsYXN0SW5kZXggPSBtYXRjaC5pbmRleCArIG1hdGNoWzBdLmxlbmd0aDtcbiAgICAgIGlmIChsYXN0SW5kZXggPiBsYXN0TGFzdEluZGV4KSB7XG4gICAgICAgIG91dHB1dC5wdXNoKHN0ci5zbGljZShsYXN0TGFzdEluZGV4LCBtYXRjaC5pbmRleCkpO1xuICAgICAgICAvLyBGaXggYnJvd3NlcnMgd2hvc2UgYGV4ZWNgIG1ldGhvZHMgZG9uJ3QgY29uc2lzdGVudGx5IHJldHVybiBgdW5kZWZpbmVkYCBmb3JcbiAgICAgICAgLy8gbm9ucGFydGljaXBhdGluZyBjYXB0dXJpbmcgZ3JvdXBzXG4gICAgICAgIGlmICghY29tcGxpYW50RXhlY05wY2cgJiYgbWF0Y2gubGVuZ3RoID4gMSkge1xuICAgICAgICAgIG1hdGNoWzBdLnJlcGxhY2Uoc2VwYXJhdG9yMiwgZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMTsgaSA8IGFyZ3VtZW50cy5sZW5ndGggLSAyOyBpKyspIHtcbiAgICAgICAgICAgICAgaWYgKGFyZ3VtZW50c1tpXSA9PT0gdW5kZWYpIHtcbiAgICAgICAgICAgICAgICBtYXRjaFtpXSA9IHVuZGVmO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKG1hdGNoLmxlbmd0aCA+IDEgJiYgbWF0Y2guaW5kZXggPCBzdHIubGVuZ3RoKSB7XG4gICAgICAgICAgQXJyYXkucHJvdG90eXBlLnB1c2guYXBwbHkob3V0cHV0LCBtYXRjaC5zbGljZSgxKSk7XG4gICAgICAgIH1cbiAgICAgICAgbGFzdExlbmd0aCA9IG1hdGNoWzBdLmxlbmd0aDtcbiAgICAgICAgbGFzdExhc3RJbmRleCA9IGxhc3RJbmRleDtcbiAgICAgICAgaWYgKG91dHB1dC5sZW5ndGggPj0gbGltaXQpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKHNlcGFyYXRvci5sYXN0SW5kZXggPT09IG1hdGNoLmluZGV4KSB7XG4gICAgICAgIHNlcGFyYXRvci5sYXN0SW5kZXgrKzsgLy8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcFxuICAgICAgfVxuICAgIH1cbiAgICBpZiAobGFzdExhc3RJbmRleCA9PT0gc3RyLmxlbmd0aCkge1xuICAgICAgaWYgKGxhc3RMZW5ndGggfHwgIXNlcGFyYXRvci50ZXN0KFwiXCIpKSB7XG4gICAgICAgIG91dHB1dC5wdXNoKFwiXCIpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaChzdHIuc2xpY2UobGFzdExhc3RJbmRleCkpO1xuICAgIH1cbiAgICByZXR1cm4gb3V0cHV0Lmxlbmd0aCA+IGxpbWl0ID8gb3V0cHV0LnNsaWNlKDAsIGxpbWl0KSA6IG91dHB1dDtcbiAgfTtcblxuICByZXR1cm4gc2VsZjtcbn0pKCk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9icm93c2VyLXNwbGl0L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9icm93c2VyLXNwbGl0XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gY29udGFpbnMsIGFkZCwgcmVtb3ZlLCB0b2dnbGVcbnZhciBpbmRleG9mID0gcmVxdWlyZSgnaW5kZXhvZicpXG5cbm1vZHVsZS5leHBvcnRzID0gQ2xhc3NMaXN0XG5cbmZ1bmN0aW9uIENsYXNzTGlzdChlbGVtKSB7XG4gICAgdmFyIGNsID0gZWxlbS5jbGFzc0xpc3RcblxuICAgIGlmIChjbCkge1xuICAgICAgICByZXR1cm4gY2xcbiAgICB9XG5cbiAgICB2YXIgY2xhc3NMaXN0ID0ge1xuICAgICAgICBhZGQ6IGFkZFxuICAgICAgICAsIHJlbW92ZTogcmVtb3ZlXG4gICAgICAgICwgY29udGFpbnM6IGNvbnRhaW5zXG4gICAgICAgICwgdG9nZ2xlOiB0b2dnbGVcbiAgICAgICAgLCB0b1N0cmluZzogJHRvU3RyaW5nXG4gICAgICAgICwgbGVuZ3RoOiAwXG4gICAgICAgICwgaXRlbTogaXRlbVxuICAgIH1cblxuICAgIHJldHVybiBjbGFzc0xpc3RcblxuICAgIGZ1bmN0aW9uIGFkZCh0b2tlbikge1xuICAgICAgICB2YXIgbGlzdCA9IGdldFRva2VucygpXG4gICAgICAgIGlmIChpbmRleG9mKGxpc3QsIHRva2VuKSA+IC0xKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuICAgICAgICBsaXN0LnB1c2godG9rZW4pXG4gICAgICAgIHNldFRva2VucyhsaXN0KVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJlbW92ZSh0b2tlbikge1xuICAgICAgICB2YXIgbGlzdCA9IGdldFRva2VucygpXG4gICAgICAgICAgICAsIGluZGV4ID0gaW5kZXhvZihsaXN0LCB0b2tlbilcblxuICAgICAgICBpZiAoaW5kZXggPT09IC0xKSB7XG4gICAgICAgICAgICByZXR1cm5cbiAgICAgICAgfVxuXG4gICAgICAgIGxpc3Quc3BsaWNlKGluZGV4LCAxKVxuICAgICAgICBzZXRUb2tlbnMobGlzdClcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBjb250YWlucyh0b2tlbikge1xuICAgICAgICByZXR1cm4gaW5kZXhvZihnZXRUb2tlbnMoKSwgdG9rZW4pID4gLTFcbiAgICB9XG5cbiAgICBmdW5jdGlvbiB0b2dnbGUodG9rZW4pIHtcbiAgICAgICAgaWYgKGNvbnRhaW5zKHRva2VuKSkge1xuICAgICAgICAgICAgcmVtb3ZlKHRva2VuKVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhZGQodG9rZW4pXG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gJHRvU3RyaW5nKCkge1xuICAgICAgICByZXR1cm4gZWxlbS5jbGFzc05hbWVcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBpdGVtKGluZGV4KSB7XG4gICAgICAgIHZhciB0b2tlbnMgPSBnZXRUb2tlbnMoKVxuICAgICAgICByZXR1cm4gdG9rZW5zW2luZGV4XSB8fCBudWxsXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0VG9rZW5zKCkge1xuICAgICAgICB2YXIgY2xhc3NOYW1lID0gZWxlbS5jbGFzc05hbWVcblxuICAgICAgICByZXR1cm4gZmlsdGVyKGNsYXNzTmFtZS5zcGxpdChcIiBcIiksIGlzVHJ1dGh5KVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNldFRva2VucyhsaXN0KSB7XG4gICAgICAgIHZhciBsZW5ndGggPSBsaXN0Lmxlbmd0aFxuXG4gICAgICAgIGVsZW0uY2xhc3NOYW1lID0gbGlzdC5qb2luKFwiIFwiKVxuICAgICAgICBjbGFzc0xpc3QubGVuZ3RoID0gbGVuZ3RoXG5cbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBjbGFzc0xpc3RbaV0gPSBsaXN0W2ldXG4gICAgICAgIH1cblxuICAgICAgICBkZWxldGUgbGlzdFtsZW5ndGhdXG4gICAgfVxufVxuXG5mdW5jdGlvbiBmaWx0ZXIgKGFyciwgZm4pIHtcbiAgICB2YXIgcmV0ID0gW11cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoZm4oYXJyW2ldKSkgcmV0LnB1c2goYXJyW2ldKVxuICAgIH1cbiAgICByZXR1cm4gcmV0XG59XG5cbmZ1bmN0aW9uIGlzVHJ1dGh5KHZhbHVlKSB7XG4gICAgcmV0dXJuICEhdmFsdWVcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2NsYXNzLWxpc3QvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2NsYXNzLWxpc3RcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5cbnZhciBpbmRleE9mID0gW10uaW5kZXhPZjtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihhcnIsIG9iail7XG4gIGlmIChpbmRleE9mKSByZXR1cm4gYXJyLmluZGV4T2Yob2JqKTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoYXJyW2ldID09PSBvYmopIHJldHVybiBpO1xuICB9XG4gIHJldHVybiAtMTtcbn07XG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvY2xhc3MtbGlzdC9ub2RlX21vZHVsZXMvaW5kZXhvZi9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvY2xhc3MtbGlzdC9ub2RlX21vZHVsZXMvaW5kZXhvZlwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBXZWFrbWFwID0gcmVxdWlyZShcIndlYWttYXBcIilcbnZhciBJbmRpdmlkdWFsID0gcmVxdWlyZShcImluZGl2aWR1YWxcIilcblxudmFyIGRhdGFzZXRNYXAgPSBJbmRpdmlkdWFsKFwiX19EQVRBX1NFVF9XRUFLTUFQXCIsIFdlYWttYXAoKSlcblxubW9kdWxlLmV4cG9ydHMgPSBEYXRhU2V0XG5cbmZ1bmN0aW9uIERhdGFTZXQoZWxlbSkge1xuICAgIGlmIChlbGVtLmRhdGFzZXQpIHtcbiAgICAgICAgcmV0dXJuIGVsZW0uZGF0YXNldFxuICAgIH1cblxuICAgIHZhciBoYXNoID0gZGF0YXNldE1hcC5nZXQoZWxlbSlcblxuICAgIGlmICghaGFzaCkge1xuICAgICAgICBoYXNoID0gY3JlYXRlSGFzaChlbGVtKVxuICAgICAgICBkYXRhc2V0TWFwLnNldChlbGVtLCBoYXNoKVxuICAgIH1cblxuICAgIHJldHVybiBoYXNoXG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUhhc2goZWxlbSkge1xuICAgIHZhciBhdHRyaWJ1dGVzID0gZWxlbS5hdHRyaWJ1dGVzXG4gICAgdmFyIGhhc2ggPSB7fVxuXG4gICAgaWYgKGF0dHJpYnV0ZXMgPT09IG51bGwgfHwgYXR0cmlidXRlcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBoYXNoXG4gICAgfVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhdHRyaWJ1dGVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBhdHRyID0gYXR0cmlidXRlc1tpXVxuXG4gICAgICAgIGlmIChhdHRyLm5hbWUuc3Vic3RyKDAsNSkgIT09IFwiZGF0YS1cIikge1xuICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGhhc2hbYXR0ci5uYW1lLnN1YnN0cig1KV0gPSBhdHRyLnZhbHVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGhhc2hcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2RhdGEtc2V0L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciByb290ID0gcmVxdWlyZShcImdsb2JhbFwiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IEluZGl2aWR1YWxcblxuZnVuY3Rpb24gSW5kaXZpZHVhbChrZXksIHZhbHVlKSB7XG4gICAgaWYgKHJvb3Rba2V5XSkge1xuICAgICAgICByZXR1cm4gcm9vdFtrZXldXG4gICAgfVxuXG4gICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KHJvb3QsIGtleSwge1xuICAgICAgICB2YWx1ZTogdmFsdWVcbiAgICAgICAgLCBjb25maWd1cmFibGU6IHRydWVcbiAgICB9KVxuXG4gICAgcmV0dXJuIHZhbHVlXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL2h5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldC9ub2RlX21vZHVsZXMvaW5kaXZpZHVhbC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZGF0YS1zZXQvbm9kZV9tb2R1bGVzL2luZGl2aWR1YWxcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vKmdsb2JhbCB3aW5kb3csIGdsb2JhbCovXG5pZiAodHlwZW9mIGdsb2JhbCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZ2xvYmFsXG59IGVsc2UgaWYgKHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICBtb2R1bGUuZXhwb3J0cyA9IHdpbmRvd1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZGF0YS1zZXQvbm9kZV9tb2R1bGVzL2luZGl2aWR1YWwvbm9kZV9tb2R1bGVzL2dsb2JhbC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZGF0YS1zZXQvbm9kZV9tb2R1bGVzL2luZGl2aWR1YWwvbm9kZV9tb2R1bGVzL2dsb2JhbFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8qIChUaGUgTUlUIExpY2Vuc2UpXHJcbiAqXHJcbiAqIENvcHlyaWdodCAoYykgMjAxMiBCcmFuZG9uIEJlbnZpZSA8aHR0cDovL2JiZW52aWUuY29tPlxyXG4gKlxyXG4gKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kXHJcbiAqIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICdTb2Z0d2FyZScpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLFxyXG4gKiBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLFxyXG4gKiBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcclxuICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcclxuICpcclxuICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgd2l0aCBhbGwgY29waWVzIG9yXHJcbiAqIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS5cclxuICpcclxuICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICdBUyBJUycsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IgSU1QTElFRCwgSU5DTFVESU5HXHJcbiAqIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORFxyXG4gKiBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZICBDTEFJTSxcclxuICogREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxyXG4gKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOIFRIRSBTT0ZUV0FSRS5cclxuICovXHJcblxyXG4vLyBPcmlnaW5hbCBXZWFrTWFwIGltcGxlbWVudGF0aW9uIGJ5IEdvemFsYSBAIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tLzEyNjk5OTFcclxuLy8gVXBkYXRlZCBhbmQgYnVnZml4ZWQgYnkgUmF5bm9zIEAgaHR0cHM6Ly9naXN0LmdpdGh1Yi5jb20vMTYzODA1OVxyXG4vLyBFeHBhbmRlZCBieSBCZW52aWUgQCBodHRwczovL2dpdGh1Yi5jb20vQmVudmllL2hhcm1vbnktY29sbGVjdGlvbnNcclxuXHJcbnZvaWQgZnVuY3Rpb24oZ2xvYmFsLCB1bmRlZmluZWRfLCB1bmRlZmluZWQpe1xyXG4gIHZhciBnZXRQcm9wcyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzLFxyXG4gICAgICBkZWZQcm9wICA9IE9iamVjdC5kZWZpbmVQcm9wZXJ0eSxcclxuICAgICAgdG9Tb3VyY2UgPSBGdW5jdGlvbi5wcm90b3R5cGUudG9TdHJpbmcsXHJcbiAgICAgIGNyZWF0ZSAgID0gT2JqZWN0LmNyZWF0ZSxcclxuICAgICAgaGFzT3duICAgPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LFxyXG4gICAgICBmdW5jTmFtZSA9IC9eXFxuP2Z1bmN0aW9uXFxzPyhcXHcqKT9fP1xcKC87XHJcblxyXG5cclxuICBmdW5jdGlvbiBkZWZpbmUob2JqZWN0LCBrZXksIHZhbHVlKXtcclxuICAgIGlmICh0eXBlb2Yga2V5ID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgIHZhbHVlID0ga2V5O1xyXG4gICAgICBrZXkgPSBuYW1lT2YodmFsdWUpLnJlcGxhY2UoL18kLywgJycpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGRlZlByb3Aob2JqZWN0LCBrZXksIHsgY29uZmlndXJhYmxlOiB0cnVlLCB3cml0YWJsZTogdHJ1ZSwgdmFsdWU6IHZhbHVlIH0pO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gbmFtZU9mKGZ1bmMpe1xyXG4gICAgcmV0dXJuIHR5cGVvZiBmdW5jICE9PSAnZnVuY3Rpb24nXHJcbiAgICAgICAgICA/ICcnIDogJ25hbWUnIGluIGZ1bmNcclxuICAgICAgICAgID8gZnVuYy5uYW1lIDogdG9Tb3VyY2UuY2FsbChmdW5jKS5tYXRjaChmdW5jTmFtZSlbMV07XHJcbiAgfVxyXG5cclxuICAvLyAjIyMjIyMjIyMjIyNcclxuICAvLyAjIyMgRGF0YSAjIyNcclxuICAvLyAjIyMjIyMjIyMjIyNcclxuXHJcbiAgdmFyIERhdGEgPSAoZnVuY3Rpb24oKXtcclxuICAgIHZhciBkYXRhRGVzYyA9IHsgdmFsdWU6IHsgd3JpdGFibGU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfSB9LFxyXG4gICAgICAgIGRhdGFsb2NrID0gJ3JldHVybiBmdW5jdGlvbihrKXtpZihrPT09cylyZXR1cm4gbH0nLFxyXG4gICAgICAgIHVpZHMgICAgID0gY3JlYXRlKG51bGwpLFxyXG5cclxuICAgICAgICBjcmVhdGVVSUQgPSBmdW5jdGlvbigpe1xyXG4gICAgICAgICAgdmFyIGtleSA9IE1hdGgucmFuZG9tKCkudG9TdHJpbmcoMzYpLnNsaWNlKDIpO1xyXG4gICAgICAgICAgcmV0dXJuIGtleSBpbiB1aWRzID8gY3JlYXRlVUlEKCkgOiB1aWRzW2tleV0gPSBrZXk7XHJcbiAgICAgICAgfSxcclxuXHJcbiAgICAgICAgZ2xvYmFsSUQgPSBjcmVhdGVVSUQoKSxcclxuXHJcbiAgICAgICAgc3RvcmFnZSA9IGZ1bmN0aW9uKG9iail7XHJcbiAgICAgICAgICBpZiAoaGFzT3duLmNhbGwob2JqLCBnbG9iYWxJRCkpXHJcbiAgICAgICAgICAgIHJldHVybiBvYmpbZ2xvYmFsSURdO1xyXG5cclxuICAgICAgICAgIGlmICghT2JqZWN0LmlzRXh0ZW5zaWJsZShvYmopKVxyXG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiT2JqZWN0IG11c3QgYmUgZXh0ZW5zaWJsZVwiKTtcclxuXHJcbiAgICAgICAgICB2YXIgc3RvcmUgPSBjcmVhdGUobnVsbCk7XHJcbiAgICAgICAgICBkZWZQcm9wKG9iaiwgZ2xvYmFsSUQsIHsgdmFsdWU6IHN0b3JlIH0pO1xyXG4gICAgICAgICAgcmV0dXJuIHN0b3JlO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgLy8gY29tbW9uIHBlci1vYmplY3Qgc3RvcmFnZSBhcmVhIG1hZGUgdmlzaWJsZSBieSBwYXRjaGluZyBnZXRPd25Qcm9wZXJ0eU5hbWVzJ1xyXG4gICAgZGVmaW5lKE9iamVjdCwgZnVuY3Rpb24gZ2V0T3duUHJvcGVydHlOYW1lcyhvYmope1xyXG4gICAgICB2YXIgcHJvcHMgPSBnZXRQcm9wcyhvYmopO1xyXG4gICAgICBpZiAoaGFzT3duLmNhbGwob2JqLCBnbG9iYWxJRCkpXHJcbiAgICAgICAgcHJvcHMuc3BsaWNlKHByb3BzLmluZGV4T2YoZ2xvYmFsSUQpLCAxKTtcclxuICAgICAgcmV0dXJuIHByb3BzO1xyXG4gICAgfSk7XHJcblxyXG4gICAgZnVuY3Rpb24gRGF0YSgpe1xyXG4gICAgICB2YXIgcHVpZCA9IGNyZWF0ZVVJRCgpLFxyXG4gICAgICAgICAgc2VjcmV0ID0ge307XHJcblxyXG4gICAgICB0aGlzLnVubG9jayA9IGZ1bmN0aW9uKG9iail7XHJcbiAgICAgICAgdmFyIHN0b3JlID0gc3RvcmFnZShvYmopO1xyXG4gICAgICAgIGlmIChoYXNPd24uY2FsbChzdG9yZSwgcHVpZCkpXHJcbiAgICAgICAgICByZXR1cm4gc3RvcmVbcHVpZF0oc2VjcmV0KTtcclxuXHJcbiAgICAgICAgdmFyIGRhdGEgPSBjcmVhdGUobnVsbCwgZGF0YURlc2MpO1xyXG4gICAgICAgIGRlZlByb3Aoc3RvcmUsIHB1aWQsIHtcclxuICAgICAgICAgIHZhbHVlOiBuZXcgRnVuY3Rpb24oJ3MnLCAnbCcsIGRhdGFsb2NrKShzZWNyZXQsIGRhdGEpXHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgcmV0dXJuIGRhdGE7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBkZWZpbmUoRGF0YS5wcm90b3R5cGUsIGZ1bmN0aW9uIGdldChvKXsgcmV0dXJuIHRoaXMudW5sb2NrKG8pLnZhbHVlIH0pO1xyXG4gICAgZGVmaW5lKERhdGEucHJvdG90eXBlLCBmdW5jdGlvbiBzZXQobywgdil7IHRoaXMudW5sb2NrKG8pLnZhbHVlID0gdiB9KTtcclxuXHJcbiAgICByZXR1cm4gRGF0YTtcclxuICB9KCkpO1xyXG5cclxuXHJcbiAgdmFyIFdNID0gKGZ1bmN0aW9uKGRhdGEpe1xyXG4gICAgdmFyIHZhbGlkYXRlID0gZnVuY3Rpb24oa2V5KXtcclxuICAgICAgaWYgKGtleSA9PSBudWxsIHx8IHR5cGVvZiBrZXkgIT09ICdvYmplY3QnICYmIHR5cGVvZiBrZXkgIT09ICdmdW5jdGlvbicpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIkludmFsaWQgV2Vha01hcCBrZXlcIik7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHdyYXAgPSBmdW5jdGlvbihjb2xsZWN0aW9uLCB2YWx1ZSl7XHJcbiAgICAgIHZhciBzdG9yZSA9IGRhdGEudW5sb2NrKGNvbGxlY3Rpb24pO1xyXG4gICAgICBpZiAoc3RvcmUudmFsdWUpXHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdCBpcyBhbHJlYWR5IGEgV2Vha01hcFwiKTtcclxuICAgICAgc3RvcmUudmFsdWUgPSB2YWx1ZTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgdW53cmFwID0gZnVuY3Rpb24oY29sbGVjdGlvbil7XHJcbiAgICAgIHZhciBzdG9yYWdlID0gZGF0YS51bmxvY2soY29sbGVjdGlvbikudmFsdWU7XHJcbiAgICAgIGlmICghc3RvcmFnZSlcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFwiV2Vha01hcCBpcyBub3QgZ2VuZXJpY1wiKTtcclxuICAgICAgcmV0dXJuIHN0b3JhZ2U7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIGluaXRpYWxpemUgPSBmdW5jdGlvbih3ZWFrbWFwLCBpdGVyYWJsZSl7XHJcbiAgICAgIGlmIChpdGVyYWJsZSAhPT0gbnVsbCAmJiB0eXBlb2YgaXRlcmFibGUgPT09ICdvYmplY3QnICYmIHR5cGVvZiBpdGVyYWJsZS5mb3JFYWNoID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgaXRlcmFibGUuZm9yRWFjaChmdW5jdGlvbihpdGVtLCBpKXtcclxuICAgICAgICAgIGlmIChpdGVtIGluc3RhbmNlb2YgQXJyYXkgJiYgaXRlbS5sZW5ndGggPT09IDIpXHJcbiAgICAgICAgICAgIHNldC5jYWxsKHdlYWttYXAsIGl0ZXJhYmxlW2ldWzBdLCBpdGVyYWJsZVtpXVsxXSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcblxyXG4gICAgZnVuY3Rpb24gV2Vha01hcChpdGVyYWJsZSl7XHJcbiAgICAgIGlmICh0aGlzID09PSBnbG9iYWwgfHwgdGhpcyA9PSBudWxsIHx8IHRoaXMgPT09IFdlYWtNYXAucHJvdG90eXBlKVxyXG4gICAgICAgIHJldHVybiBuZXcgV2Vha01hcChpdGVyYWJsZSk7XHJcblxyXG4gICAgICB3cmFwKHRoaXMsIG5ldyBEYXRhKTtcclxuICAgICAgaW5pdGlhbGl6ZSh0aGlzLCBpdGVyYWJsZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gZ2V0KGtleSl7XHJcbiAgICAgIHZhbGlkYXRlKGtleSk7XHJcbiAgICAgIHZhciB2YWx1ZSA9IHVud3JhcCh0aGlzKS5nZXQoa2V5KTtcclxuICAgICAgcmV0dXJuIHZhbHVlID09PSB1bmRlZmluZWRfID8gdW5kZWZpbmVkIDogdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gc2V0KGtleSwgdmFsdWUpe1xyXG4gICAgICB2YWxpZGF0ZShrZXkpO1xyXG4gICAgICAvLyBzdG9yZSBhIHRva2VuIGZvciBleHBsaWNpdCB1bmRlZmluZWQgc28gdGhhdCBcImhhc1wiIHdvcmtzIGNvcnJlY3RseVxyXG4gICAgICB1bndyYXAodGhpcykuc2V0KGtleSwgdmFsdWUgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZF8gOiB2YWx1ZSk7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gaGFzKGtleSl7XHJcbiAgICAgIHZhbGlkYXRlKGtleSk7XHJcbiAgICAgIHJldHVybiB1bndyYXAodGhpcykuZ2V0KGtleSkgIT09IHVuZGVmaW5lZDtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBkZWxldGVfKGtleSl7XHJcbiAgICAgIHZhbGlkYXRlKGtleSk7XHJcbiAgICAgIHZhciBkYXRhID0gdW53cmFwKHRoaXMpLFxyXG4gICAgICAgICAgaGFkID0gZGF0YS5nZXQoa2V5KSAhPT0gdW5kZWZpbmVkO1xyXG4gICAgICBkYXRhLnNldChrZXksIHVuZGVmaW5lZCk7XHJcbiAgICAgIHJldHVybiBoYWQ7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gdG9TdHJpbmcoKXtcclxuICAgICAgdW53cmFwKHRoaXMpO1xyXG4gICAgICByZXR1cm4gJ1tvYmplY3QgV2Vha01hcF0nO1xyXG4gICAgfVxyXG5cclxuICAgIHRyeSB7XHJcbiAgICAgIHZhciBzcmMgPSAoJ3JldHVybiAnK2RlbGV0ZV8pLnJlcGxhY2UoJ2VfJywgJ1xcXFx1MDA2NScpLFxyXG4gICAgICAgICAgZGVsID0gbmV3IEZ1bmN0aW9uKCd1bndyYXAnLCAndmFsaWRhdGUnLCBzcmMpKHVud3JhcCwgdmFsaWRhdGUpO1xyXG4gICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICB2YXIgZGVsID0gZGVsZXRlXztcclxuICAgIH1cclxuXHJcbiAgICB2YXIgc3JjID0gKCcnK09iamVjdCkuc3BsaXQoJ09iamVjdCcpO1xyXG4gICAgdmFyIHN0cmluZ2lmaWVyID0gZnVuY3Rpb24gdG9TdHJpbmcoKXtcclxuICAgICAgcmV0dXJuIHNyY1swXSArIG5hbWVPZih0aGlzKSArIHNyY1sxXTtcclxuICAgIH07XHJcblxyXG4gICAgZGVmaW5lKHN0cmluZ2lmaWVyLCBzdHJpbmdpZmllcik7XHJcblxyXG4gICAgdmFyIHByZXAgPSB7IF9fcHJvdG9fXzogW10gfSBpbnN0YW5jZW9mIEFycmF5XHJcbiAgICAgID8gZnVuY3Rpb24oZil7IGYuX19wcm90b19fID0gc3RyaW5naWZpZXIgfVxyXG4gICAgICA6IGZ1bmN0aW9uKGYpeyBkZWZpbmUoZiwgc3RyaW5naWZpZXIpIH07XHJcblxyXG4gICAgcHJlcChXZWFrTWFwKTtcclxuXHJcbiAgICBbdG9TdHJpbmcsIGdldCwgc2V0LCBoYXMsIGRlbF0uZm9yRWFjaChmdW5jdGlvbihtZXRob2Qpe1xyXG4gICAgICBkZWZpbmUoV2Vha01hcC5wcm90b3R5cGUsIG1ldGhvZCk7XHJcbiAgICAgIHByZXAobWV0aG9kKTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiBXZWFrTWFwO1xyXG4gIH0obmV3IERhdGEpKTtcclxuXHJcbiAgdmFyIGRlZmF1bHRDcmVhdG9yID0gT2JqZWN0LmNyZWF0ZVxyXG4gICAgPyBmdW5jdGlvbigpeyByZXR1cm4gT2JqZWN0LmNyZWF0ZShudWxsKSB9XHJcbiAgICA6IGZ1bmN0aW9uKCl7IHJldHVybiB7fSB9O1xyXG5cclxuICBmdW5jdGlvbiBjcmVhdGVTdG9yYWdlKGNyZWF0b3Ipe1xyXG4gICAgdmFyIHdlYWttYXAgPSBuZXcgV007XHJcbiAgICBjcmVhdG9yIHx8IChjcmVhdG9yID0gZGVmYXVsdENyZWF0b3IpO1xyXG5cclxuICAgIGZ1bmN0aW9uIHN0b3JhZ2Uob2JqZWN0LCB2YWx1ZSl7XHJcbiAgICAgIGlmICh2YWx1ZSB8fCBhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XHJcbiAgICAgICAgd2Vha21hcC5zZXQob2JqZWN0LCB2YWx1ZSk7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdmFsdWUgPSB3ZWFrbWFwLmdldChvYmplY3QpO1xyXG4gICAgICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICB2YWx1ZSA9IGNyZWF0b3Iob2JqZWN0KTtcclxuICAgICAgICAgIHdlYWttYXAuc2V0KG9iamVjdCwgdmFsdWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gdmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHN0b3JhZ2U7XHJcbiAgfVxyXG5cclxuXHJcbiAgaWYgKHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICBtb2R1bGUuZXhwb3J0cyA9IFdNO1xyXG4gIH0gZWxzZSBpZiAodHlwZW9mIGV4cG9ydHMgIT09ICd1bmRlZmluZWQnKSB7XHJcbiAgICBleHBvcnRzLldlYWtNYXAgPSBXTTtcclxuICB9IGVsc2UgaWYgKCEoJ1dlYWtNYXAnIGluIGdsb2JhbCkpIHtcclxuICAgIGdsb2JhbC5XZWFrTWFwID0gV007XHJcbiAgfVxyXG5cclxuICBXTS5jcmVhdGVTdG9yYWdlID0gY3JlYXRlU3RvcmFnZTtcclxuICBpZiAoZ2xvYmFsLldlYWtNYXApXHJcbiAgICBnbG9iYWwuV2Vha01hcC5jcmVhdGVTdG9yYWdlID0gY3JlYXRlU3RvcmFnZTtcclxufSgoMCwgZXZhbCkoJ3RoaXMnKSk7XHJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2RhdGEtc2V0L25vZGVfbW9kdWxlcy93ZWFrbWFwL3dlYWttYXAuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2RhdGEtc2V0L25vZGVfbW9kdWxlcy93ZWFrbWFwXCIpIiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIm5hbWVcIjogXCJyeG1hcmJsZXNcIixcbiAgXCJ2ZXJzaW9uXCI6IFwiMS4wLjBcIixcbiAgXCJhdXRob3JcIjogXCJBbmRyZSBTdGFsdHpcIixcbiAgXCJyZXBvc2l0b3J5XCI6IHtcbiAgICBcInR5cGVcIjogXCJnaXRcIixcbiAgICBcInVybFwiOiBcImdpdEBnaXRodWIuY29tOnN0YWx0ei9yeG1hcmJsZXMuZ2l0XCJcbiAgfSxcbiAgXCJsaWNlbnNlXCI6IFwiQlNEIDMtQ2xhdXNlXCIsXG4gIFwibWFpblwiOiBcImpzL2FwcC5qc1wiLFxuICBcImRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJyeFwiOiBcIn4yLjIuMjhcIixcbiAgICBcInZpcnR1YWwtZG9tXCI6IFwiMC4wLjE5XCIsXG4gICAgXCJ2aXJ0dWFsLWh5cGVyc2NyaXB0XCI6IFwiNC40LjBcIixcbiAgICBcImh5cGVyc2NyaXB0XCI6IFwiMS40LjBcIlxuICB9LFxuICBcImRldkRlcGVuZGVuY2llc1wiOiB7XG4gICAgXCJicm93c2VyaWZ5XCI6IFwifjIuMzYuMFwiLFxuICAgIFwiY29mZmVlaWZ5XCI6IFwifjAuNi4wXCIsXG4gICAgXCJndWxwXCI6IFwifjMuOC42XCIsXG4gICAgXCJndWxwLWJyb3dzZXJpZnlcIjogXCJeMC41LjBcIixcbiAgICBcImd1bHAtY29mZmVlXCI6IFwiXjIuMS4xXCIsXG4gICAgXCJndWxwLWxlc3NcIjogXCJeMS4zLjJcIixcbiAgICBcImd1bHAtcmltcmFmXCI6IFwiXjAuMS4wXCIsXG4gICAgXCJndWxwLXVnbGlmeVwiOiBcIl4wLjMuMVwiLFxuICAgIFwiZ3VscC11dGlsXCI6IFwiXjIuMi4yMFwiLFxuICAgIFwidWdsaWZ5LWpzXCI6IFwifjIuNC4xM1wiLFxuICAgIFwid2F0Y2hpZnlcIjogXCJ+MC40LjFcIlxuICB9LFxuICBcInNjcmlwdHNcIjoge1xuICAgIFwicHJlaW5zdGFsbFwiOiBcInJtIC1yZiBidWlsZCAmJiBybSAtcmYgbm9kZV9tb2R1bGVzXCIsXG4gICAgXCJwb3N0aW5zdGFsbFwiOiBcIm1rZGlyIGJ1aWxkICYmIG1rZGlyIGJ1aWxkL3NyYyAmJiBsbiAtcyAuLi9idWlsZC9zcmMgbm9kZV9tb2R1bGVzL3J4bWFyYmxlcyAmJiBsbiAtcyAuLi9wYWNrYWdlLmpzb24gbm9kZV9tb2R1bGVzL3BhY2thZ2UuanNvblwiLFxuICAgIFwidXBkYXRlLWdoLXBhZ2VzXCI6IFwiZ2l0IGNoZWNrb3V0IGdoLXBhZ2VzICYmIGdpdCBtZXJnZSBtYXN0ZXIgJiYgcm0gZGlzdC9qcy9hcHAuanMgJiYgZ3VscCBidWlsZCAmJiBnaXQgYWRkIGRpc3QvanMvYXBwLmpzICYmIGdpdCBjb21taXQgLS1hbWVuZCAtLW5vLWVkaXQgJiYgZ2l0IHB1c2ggb3JpZ2luIGdoLXBhZ2VzICYmIGdpdCBjaGVja291dCBtYXN0ZXJcIlxuICB9XG59XG4iLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBDb3B5cmlnaHQgKGMpIE1pY3Jvc29mdCBPcGVuIFRlY2hub2xvZ2llcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLiBTZWUgTGljZW5zZS50eHQgaW4gdGhlIHByb2plY3Qgcm9vdCBmb3IgbGljZW5zZSBpbmZvcm1hdGlvbi5cclxuXHJcbjsoZnVuY3Rpb24gKHVuZGVmaW5lZCkge1xyXG5cclxuICB2YXIgb2JqZWN0VHlwZXMgPSB7XHJcbiAgICAnYm9vbGVhbic6IGZhbHNlLFxyXG4gICAgJ2Z1bmN0aW9uJzogdHJ1ZSxcclxuICAgICdvYmplY3QnOiB0cnVlLFxyXG4gICAgJ251bWJlcic6IGZhbHNlLFxyXG4gICAgJ3N0cmluZyc6IGZhbHNlLFxyXG4gICAgJ3VuZGVmaW5lZCc6IGZhbHNlXHJcbiAgfTtcclxuXHJcbiAgdmFyIHJvb3QgPSAob2JqZWN0VHlwZXNbdHlwZW9mIHdpbmRvd10gJiYgd2luZG93KSB8fCB0aGlzLFxyXG4gICAgZnJlZUV4cG9ydHMgPSBvYmplY3RUeXBlc1t0eXBlb2YgZXhwb3J0c10gJiYgZXhwb3J0cyAmJiAhZXhwb3J0cy5ub2RlVHlwZSAmJiBleHBvcnRzLFxyXG4gICAgZnJlZU1vZHVsZSA9IG9iamVjdFR5cGVzW3R5cGVvZiBtb2R1bGVdICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZSxcclxuICAgIG1vZHVsZUV4cG9ydHMgPSBmcmVlTW9kdWxlICYmIGZyZWVNb2R1bGUuZXhwb3J0cyA9PT0gZnJlZUV4cG9ydHMgJiYgZnJlZUV4cG9ydHMsXHJcbiAgICBmcmVlR2xvYmFsID0gb2JqZWN0VHlwZXNbdHlwZW9mIGdsb2JhbF0gJiYgZ2xvYmFsO1xyXG4gIFxyXG4gIGlmIChmcmVlR2xvYmFsICYmIChmcmVlR2xvYmFsLmdsb2JhbCA9PT0gZnJlZUdsb2JhbCB8fCBmcmVlR2xvYmFsLndpbmRvdyA9PT0gZnJlZUdsb2JhbCkpIHtcclxuICAgIHJvb3QgPSBmcmVlR2xvYmFsO1xyXG4gIH1cclxuXHJcbiAgdmFyIFJ4ID0geyBcclxuICAgICAgaW50ZXJuYWxzOiB7fSwgXHJcbiAgICAgIGNvbmZpZzoge1xyXG4gICAgICAgIFByb21pc2U6IHJvb3QuUHJvbWlzZSAvLyBEZXRlY3QgaWYgcHJvbWlzZSBleGlzdHNcclxuICAgICAgfSxcclxuICAgICAgaGVscGVyczogeyB9XHJcbiAgfTtcclxuICAgIFxyXG4gIC8vIERlZmF1bHRzXHJcbiAgdmFyIG5vb3AgPSBSeC5oZWxwZXJzLm5vb3AgPSBmdW5jdGlvbiAoKSB7IH0sXHJcbiAgICBpZGVudGl0eSA9IFJ4LmhlbHBlcnMuaWRlbnRpdHkgPSBmdW5jdGlvbiAoeCkgeyByZXR1cm4geDsgfSxcclxuICAgIHBsdWNrID0gUnguaGVscGVycy5wbHVjayA9IGZ1bmN0aW9uIChwcm9wZXJ0eSkgeyByZXR1cm4gZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHhbcHJvcGVydHldOyB9OyB9LFxyXG4gICAganVzdCA9IFJ4LmhlbHBlcnMuanVzdCA9IGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gZnVuY3Rpb24gKCkgeyByZXR1cm4gdmFsdWU7IH07IH0sICAgIFxyXG4gICAgZGVmYXVsdE5vdyA9IFJ4LmhlbHBlcnMuZGVmYXVsdE5vdyA9IERhdGUubm93LFxyXG4gICAgZGVmYXVsdENvbXBhcmVyID0gUnguaGVscGVycy5kZWZhdWx0Q29tcGFyZXIgPSBmdW5jdGlvbiAoeCwgeSkgeyByZXR1cm4gaXNFcXVhbCh4LCB5KTsgfSxcclxuICAgIGRlZmF1bHRTdWJDb21wYXJlciA9IFJ4LmhlbHBlcnMuZGVmYXVsdFN1YkNvbXBhcmVyID0gZnVuY3Rpb24gKHgsIHkpIHsgcmV0dXJuIHggPiB5ID8gMSA6ICh4IDwgeSA/IC0xIDogMCk7IH0sXHJcbiAgICBkZWZhdWx0S2V5U2VyaWFsaXplciA9IFJ4LmhlbHBlcnMuZGVmYXVsdEtleVNlcmlhbGl6ZXIgPSBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC50b1N0cmluZygpOyB9LFxyXG4gICAgZGVmYXVsdEVycm9yID0gUnguaGVscGVycy5kZWZhdWx0RXJyb3IgPSBmdW5jdGlvbiAoZXJyKSB7IHRocm93IGVycjsgfSxcclxuICAgIGlzUHJvbWlzZSA9IFJ4LmhlbHBlcnMuaXNQcm9taXNlID0gZnVuY3Rpb24gKHApIHsgcmV0dXJuICEhcCAmJiB0eXBlb2YgcC50aGVuID09PSAnZnVuY3Rpb24nICYmIHAudGhlbiAhPT0gUnguT2JzZXJ2YWJsZS5wcm90b3R5cGUudGhlbjsgfSxcclxuICAgIGFzQXJyYXkgPSBSeC5oZWxwZXJzLmFzQXJyYXkgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMpOyB9LFxyXG4gICAgbm90ID0gUnguaGVscGVycy5ub3QgPSBmdW5jdGlvbiAoYSkgeyByZXR1cm4gIWE7IH07XHJcblxyXG4gIC8vIEVycm9yc1xyXG4gIHZhciBzZXF1ZW5jZUNvbnRhaW5zTm9FbGVtZW50cyA9ICdTZXF1ZW5jZSBjb250YWlucyBubyBlbGVtZW50cy4nO1xyXG4gIHZhciBhcmd1bWVudE91dE9mUmFuZ2UgPSAnQXJndW1lbnQgb3V0IG9mIHJhbmdlJztcclxuICB2YXIgb2JqZWN0RGlzcG9zZWQgPSAnT2JqZWN0IGhhcyBiZWVuIGRpc3Bvc2VkJztcclxuICBmdW5jdGlvbiBjaGVja0Rpc3Bvc2VkKCkgeyBpZiAodGhpcy5pc0Rpc3Bvc2VkKSB7IHRocm93IG5ldyBFcnJvcihvYmplY3REaXNwb3NlZCk7IH0gfSAgXHJcbiAgXHJcbiAgLy8gU2hpbSBpbiBpdGVyYXRvciBzdXBwb3J0XHJcbiAgdmFyICRpdGVyYXRvciQgPSAodHlwZW9mIFN5bWJvbCA9PT0gJ29iamVjdCcgJiYgU3ltYm9sLml0ZXJhdG9yKSB8fFxyXG4gICAgJ19lczZzaGltX2l0ZXJhdG9yXyc7XHJcbiAgLy8gRmlyZWZveCBzaGlwcyBhIHBhcnRpYWwgaW1wbGVtZW50YXRpb24gdXNpbmcgdGhlIG5hbWUgQEBpdGVyYXRvci5cclxuICAvLyBodHRwczovL2J1Z3ppbGxhLm1vemlsbGEub3JnL3Nob3dfYnVnLmNnaT9pZD05MDcwNzcjYzE0XHJcbiAgLy8gU28gdXNlIHRoYXQgbmFtZSBpZiB3ZSBkZXRlY3QgaXQuXHJcbiAgaWYgKHJvb3QuU2V0ICYmIHR5cGVvZiBuZXcgcm9vdC5TZXQoKVsnQEBpdGVyYXRvciddID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAkaXRlcmF0b3IkID0gJ0BAaXRlcmF0b3InO1xyXG4gIH1cclxuICB2YXIgZG9uZUVudW1lcmF0b3IgPSB7IGRvbmU6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcclxuXHJcbiAgLyoqIGBPYmplY3QjdG9TdHJpbmdgIHJlc3VsdCBzaG9ydGN1dHMgKi9cclxuICB2YXIgYXJnc0NsYXNzID0gJ1tvYmplY3QgQXJndW1lbnRzXScsXHJcbiAgICBhcnJheUNsYXNzID0gJ1tvYmplY3QgQXJyYXldJyxcclxuICAgIGJvb2xDbGFzcyA9ICdbb2JqZWN0IEJvb2xlYW5dJyxcclxuICAgIGRhdGVDbGFzcyA9ICdbb2JqZWN0IERhdGVdJyxcclxuICAgIGVycm9yQ2xhc3MgPSAnW29iamVjdCBFcnJvcl0nLFxyXG4gICAgZnVuY0NsYXNzID0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcclxuICAgIG51bWJlckNsYXNzID0gJ1tvYmplY3QgTnVtYmVyXScsXHJcbiAgICBvYmplY3RDbGFzcyA9ICdbb2JqZWN0IE9iamVjdF0nLFxyXG4gICAgcmVnZXhwQ2xhc3MgPSAnW29iamVjdCBSZWdFeHBdJyxcclxuICAgIHN0cmluZ0NsYXNzID0gJ1tvYmplY3QgU3RyaW5nXSc7XHJcblxyXG4gIHZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcsXHJcbiAgICBoYXNPd25Qcm9wZXJ0eSA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHksICBcclxuICAgIHN1cHBvcnRzQXJnc0NsYXNzID0gdG9TdHJpbmcuY2FsbChhcmd1bWVudHMpID09IGFyZ3NDbGFzcywgLy8gRm9yIGxlc3MgPElFOSAmJiBGRjw0XHJcbiAgICBzdXBvcnROb2RlQ2xhc3MsXHJcbiAgICBlcnJvclByb3RvID0gRXJyb3IucHJvdG90eXBlLFxyXG4gICAgb2JqZWN0UHJvdG8gPSBPYmplY3QucHJvdG90eXBlLFxyXG4gICAgcHJvcGVydHlJc0VudW1lcmFibGUgPSBvYmplY3RQcm90by5wcm9wZXJ0eUlzRW51bWVyYWJsZTtcclxuXHJcbiAgdHJ5IHtcclxuICAgICAgc3Vwb3J0Tm9kZUNsYXNzID0gISh0b1N0cmluZy5jYWxsKGRvY3VtZW50KSA9PSBvYmplY3RDbGFzcyAmJiAhKHsgJ3RvU3RyaW5nJzogMCB9ICsgJycpKTtcclxuICB9IGNhdGNoKGUpIHtcclxuICAgICAgc3Vwb3J0Tm9kZUNsYXNzID0gdHJ1ZTtcclxuICB9XHJcblxyXG4gIHZhciBzaGFkb3dlZFByb3BzID0gW1xyXG4gICAgJ2NvbnN0cnVjdG9yJywgJ2hhc093blByb3BlcnR5JywgJ2lzUHJvdG90eXBlT2YnLCAncHJvcGVydHlJc0VudW1lcmFibGUnLCAndG9Mb2NhbGVTdHJpbmcnLCAndG9TdHJpbmcnLCAndmFsdWVPZidcclxuICBdO1xyXG5cclxuICB2YXIgbm9uRW51bVByb3BzID0ge307XHJcbiAgbm9uRW51bVByb3BzW2FycmF5Q2xhc3NdID0gbm9uRW51bVByb3BzW2RhdGVDbGFzc10gPSBub25FbnVtUHJvcHNbbnVtYmVyQ2xhc3NdID0geyAnY29uc3RydWN0b3InOiB0cnVlLCAndG9Mb2NhbGVTdHJpbmcnOiB0cnVlLCAndG9TdHJpbmcnOiB0cnVlLCAndmFsdWVPZic6IHRydWUgfTtcclxuICBub25FbnVtUHJvcHNbYm9vbENsYXNzXSA9IG5vbkVudW1Qcm9wc1tzdHJpbmdDbGFzc10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUsICd0b1N0cmluZyc6IHRydWUsICd2YWx1ZU9mJzogdHJ1ZSB9O1xyXG4gIG5vbkVudW1Qcm9wc1tlcnJvckNsYXNzXSA9IG5vbkVudW1Qcm9wc1tmdW5jQ2xhc3NdID0gbm9uRW51bVByb3BzW3JlZ2V4cENsYXNzXSA9IHsgJ2NvbnN0cnVjdG9yJzogdHJ1ZSwgJ3RvU3RyaW5nJzogdHJ1ZSB9O1xyXG4gIG5vbkVudW1Qcm9wc1tvYmplY3RDbGFzc10gPSB7ICdjb25zdHJ1Y3Rvcic6IHRydWUgfTtcclxuXHJcbiAgdmFyIHN1cHBvcnQgPSB7fTtcclxuICAoZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGN0b3IgPSBmdW5jdGlvbigpIHsgdGhpcy54ID0gMTsgfSxcclxuICAgICAgcHJvcHMgPSBbXTtcclxuXHJcbiAgICBjdG9yLnByb3RvdHlwZSA9IHsgJ3ZhbHVlT2YnOiAxLCAneSc6IDEgfTtcclxuICAgIGZvciAodmFyIGtleSBpbiBuZXcgY3RvcikgeyBwcm9wcy5wdXNoKGtleSk7IH0gICAgICBcclxuICAgIGZvciAoa2V5IGluIGFyZ3VtZW50cykgeyB9XHJcblxyXG4gICAgLy8gRGV0ZWN0IGlmIGBuYW1lYCBvciBgbWVzc2FnZWAgcHJvcGVydGllcyBvZiBgRXJyb3IucHJvdG90eXBlYCBhcmUgZW51bWVyYWJsZSBieSBkZWZhdWx0LlxyXG4gICAgc3VwcG9ydC5lbnVtRXJyb3JQcm9wcyA9IHByb3BlcnR5SXNFbnVtZXJhYmxlLmNhbGwoZXJyb3JQcm90bywgJ21lc3NhZ2UnKSB8fCBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKGVycm9yUHJvdG8sICduYW1lJyk7XHJcblxyXG4gICAgLy8gRGV0ZWN0IGlmIGBwcm90b3R5cGVgIHByb3BlcnRpZXMgYXJlIGVudW1lcmFibGUgYnkgZGVmYXVsdC5cclxuICAgIHN1cHBvcnQuZW51bVByb3RvdHlwZXMgPSBwcm9wZXJ0eUlzRW51bWVyYWJsZS5jYWxsKGN0b3IsICdwcm90b3R5cGUnKTtcclxuXHJcbiAgICAvLyBEZXRlY3QgaWYgYGFyZ3VtZW50c2Agb2JqZWN0IGluZGV4ZXMgYXJlIG5vbi1lbnVtZXJhYmxlXHJcbiAgICBzdXBwb3J0Lm5vbkVudW1BcmdzID0ga2V5ICE9IDA7XHJcblxyXG4gICAgLy8gRGV0ZWN0IGlmIHByb3BlcnRpZXMgc2hhZG93aW5nIHRob3NlIG9uIGBPYmplY3QucHJvdG90eXBlYCBhcmUgbm9uLWVudW1lcmFibGUuXHJcbiAgICBzdXBwb3J0Lm5vbkVudW1TaGFkb3dzID0gIS92YWx1ZU9mLy50ZXN0KHByb3BzKTtcclxuICB9KDEpKTtcclxuXHJcbiAgZnVuY3Rpb24gaXNPYmplY3QodmFsdWUpIHtcclxuICAgIC8vIGNoZWNrIGlmIHRoZSB2YWx1ZSBpcyB0aGUgRUNNQVNjcmlwdCBsYW5ndWFnZSB0eXBlIG9mIE9iamVjdFxyXG4gICAgLy8gaHR0cDovL2VzNS5naXRodWIuaW8vI3g4XHJcbiAgICAvLyBhbmQgYXZvaWQgYSBWOCBidWdcclxuICAgIC8vIGh0dHBzOi8vY29kZS5nb29nbGUuY29tL3AvdjgvaXNzdWVzL2RldGFpbD9pZD0yMjkxXHJcbiAgICB2YXIgdHlwZSA9IHR5cGVvZiB2YWx1ZTtcclxuICAgIHJldHVybiB2YWx1ZSAmJiAodHlwZSA9PSAnZnVuY3Rpb24nIHx8IHR5cGUgPT0gJ29iamVjdCcpIHx8IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24ga2V5c0luKG9iamVjdCkge1xyXG4gICAgdmFyIHJlc3VsdCA9IFtdO1xyXG4gICAgaWYgKCFpc09iamVjdChvYmplY3QpKSB7XHJcbiAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9XHJcbiAgICBpZiAoc3VwcG9ydC5ub25FbnVtQXJncyAmJiBvYmplY3QubGVuZ3RoICYmIGlzQXJndW1lbnRzKG9iamVjdCkpIHtcclxuICAgICAgb2JqZWN0ID0gc2xpY2UuY2FsbChvYmplY3QpO1xyXG4gICAgfVxyXG4gICAgdmFyIHNraXBQcm90byA9IHN1cHBvcnQuZW51bVByb3RvdHlwZXMgJiYgdHlwZW9mIG9iamVjdCA9PSAnZnVuY3Rpb24nLFxyXG4gICAgICAgIHNraXBFcnJvclByb3BzID0gc3VwcG9ydC5lbnVtRXJyb3JQcm9wcyAmJiAob2JqZWN0ID09PSBlcnJvclByb3RvIHx8IG9iamVjdCBpbnN0YW5jZW9mIEVycm9yKTtcclxuXHJcbiAgICBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSB7XHJcbiAgICAgIGlmICghKHNraXBQcm90byAmJiBrZXkgPT0gJ3Byb3RvdHlwZScpICYmXHJcbiAgICAgICAgICAhKHNraXBFcnJvclByb3BzICYmIChrZXkgPT0gJ21lc3NhZ2UnIHx8IGtleSA9PSAnbmFtZScpKSkge1xyXG4gICAgICAgIHJlc3VsdC5wdXNoKGtleSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoc3VwcG9ydC5ub25FbnVtU2hhZG93cyAmJiBvYmplY3QgIT09IG9iamVjdFByb3RvKSB7XHJcbiAgICAgIHZhciBjdG9yID0gb2JqZWN0LmNvbnN0cnVjdG9yLFxyXG4gICAgICAgICAgaW5kZXggPSAtMSxcclxuICAgICAgICAgIGxlbmd0aCA9IHNoYWRvd2VkUHJvcHMubGVuZ3RoO1xyXG5cclxuICAgICAgaWYgKG9iamVjdCA9PT0gKGN0b3IgJiYgY3Rvci5wcm90b3R5cGUpKSB7XHJcbiAgICAgICAgdmFyIGNsYXNzTmFtZSA9IG9iamVjdCA9PT0gc3RyaW5nUHJvdG8gPyBzdHJpbmdDbGFzcyA6IG9iamVjdCA9PT0gZXJyb3JQcm90byA/IGVycm9yQ2xhc3MgOiB0b1N0cmluZy5jYWxsKG9iamVjdCksXHJcbiAgICAgICAgICAgIG5vbkVudW0gPSBub25FbnVtUHJvcHNbY2xhc3NOYW1lXTtcclxuICAgICAgfVxyXG4gICAgICB3aGlsZSAoKytpbmRleCA8IGxlbmd0aCkge1xyXG4gICAgICAgIGtleSA9IHNoYWRvd2VkUHJvcHNbaW5kZXhdO1xyXG4gICAgICAgIGlmICghKG5vbkVudW0gJiYgbm9uRW51bVtrZXldKSAmJiBoYXNPd25Qcm9wZXJ0eS5jYWxsKG9iamVjdCwga2V5KSkge1xyXG4gICAgICAgICAgcmVzdWx0LnB1c2goa2V5KTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHJldHVybiByZXN1bHQ7XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBpbnRlcm5hbEZvcihvYmplY3QsIGNhbGxiYWNrLCBrZXlzRnVuYykge1xyXG4gICAgdmFyIGluZGV4ID0gLTEsXHJcbiAgICAgIHByb3BzID0ga2V5c0Z1bmMob2JqZWN0KSxcclxuICAgICAgbGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xyXG5cclxuICAgIHdoaWxlICgrK2luZGV4IDwgbGVuZ3RoKSB7XHJcbiAgICAgIHZhciBrZXkgPSBwcm9wc1tpbmRleF07XHJcbiAgICAgIGlmIChjYWxsYmFjayhvYmplY3Rba2V5XSwga2V5LCBvYmplY3QpID09PSBmYWxzZSkge1xyXG4gICAgICAgIGJyZWFrO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICByZXR1cm4gb2JqZWN0O1xyXG4gIH0gICBcclxuXHJcbiAgZnVuY3Rpb24gaW50ZXJuYWxGb3JJbihvYmplY3QsIGNhbGxiYWNrKSB7XHJcbiAgICByZXR1cm4gaW50ZXJuYWxGb3Iob2JqZWN0LCBjYWxsYmFjaywga2V5c0luKTtcclxuICB9XHJcblxyXG4gIGZ1bmN0aW9uIGlzTm9kZSh2YWx1ZSkge1xyXG4gICAgLy8gSUUgPCA5IHByZXNlbnRzIERPTSBub2RlcyBhcyBgT2JqZWN0YCBvYmplY3RzIGV4Y2VwdCB0aGV5IGhhdmUgYHRvU3RyaW5nYFxyXG4gICAgLy8gbWV0aG9kcyB0aGF0IGFyZSBgdHlwZW9mYCBcInN0cmluZ1wiIGFuZCBzdGlsbCBjYW4gY29lcmNlIG5vZGVzIHRvIHN0cmluZ3NcclxuICAgIHJldHVybiB0eXBlb2YgdmFsdWUudG9TdHJpbmcgIT0gJ2Z1bmN0aW9uJyAmJiB0eXBlb2YgKHZhbHVlICsgJycpID09ICdzdHJpbmcnO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcclxuICAgIHJldHVybiAodmFsdWUgJiYgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnKSA/IHRvU3RyaW5nLmNhbGwodmFsdWUpID09IGFyZ3NDbGFzcyA6IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLy8gZmFsbGJhY2sgZm9yIGJyb3dzZXJzIHRoYXQgY2FuJ3QgZGV0ZWN0IGBhcmd1bWVudHNgIG9iamVjdHMgYnkgW1tDbGFzc11dXHJcbiAgaWYgKCFzdXBwb3J0c0FyZ3NDbGFzcykge1xyXG4gICAgaXNBcmd1bWVudHMgPSBmdW5jdGlvbih2YWx1ZSkge1xyXG4gICAgICByZXR1cm4gKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PSAnb2JqZWN0JykgPyBoYXNPd25Qcm9wZXJ0eS5jYWxsKHZhbHVlLCAnY2FsbGVlJykgOiBmYWxzZTtcclxuICAgIH07XHJcbiAgfVxyXG5cclxuICBmdW5jdGlvbiBpc0Z1bmN0aW9uKHZhbHVlKSB7XHJcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09ICdmdW5jdGlvbicgfHwgZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvLyBmYWxsYmFjayBmb3Igb2xkZXIgdmVyc2lvbnMgb2YgQ2hyb21lIGFuZCBTYWZhcmlcclxuICBpZiAoaXNGdW5jdGlvbigveC8pKSB7XHJcbiAgICBpc0Z1bmN0aW9uID0gZnVuY3Rpb24odmFsdWUpIHtcclxuICAgICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PSAnZnVuY3Rpb24nICYmIHRvU3RyaW5nLmNhbGwodmFsdWUpID09IGZ1bmNDbGFzcztcclxuICAgIH07XHJcbiAgfSAgICAgICAgXHJcblxyXG4gIHZhciBpc0VxdWFsID0gUnguaW50ZXJuYWxzLmlzRXF1YWwgPSBmdW5jdGlvbiAoeCwgeSkge1xyXG4gICAgcmV0dXJuIGRlZXBFcXVhbHMoeCwgeSwgW10sIFtdKTsgXHJcbiAgfTtcclxuXHJcbiAgLyoqIEBwcml2YXRlXHJcbiAgICogVXNlZCBmb3IgZGVlcCBjb21wYXJpc29uXHJcbiAgICoqL1xyXG4gIGZ1bmN0aW9uIGRlZXBFcXVhbHMoYSwgYiwgc3RhY2tBLCBzdGFja0IpIHtcclxuICAgIC8vIGV4aXQgZWFybHkgZm9yIGlkZW50aWNhbCB2YWx1ZXNcclxuICAgIGlmIChhID09PSBiKSB7XHJcbiAgICAgIC8vIHRyZWF0IGArMGAgdnMuIGAtMGAgYXMgbm90IGVxdWFsXHJcbiAgICAgIHJldHVybiBhICE9PSAwIHx8ICgxIC8gYSA9PSAxIC8gYik7XHJcbiAgICB9XHJcblxyXG4gICAgdmFyIHR5cGUgPSB0eXBlb2YgYSxcclxuICAgICAgICBvdGhlclR5cGUgPSB0eXBlb2YgYjtcclxuXHJcbiAgICAvLyBleGl0IGVhcmx5IGZvciB1bmxpa2UgcHJpbWl0aXZlIHZhbHVlc1xyXG4gICAgaWYgKGEgPT09IGEgJiYgKGEgPT0gbnVsbCB8fCBiID09IG51bGwgfHxcclxuICAgICAgICAodHlwZSAhPSAnZnVuY3Rpb24nICYmIHR5cGUgIT0gJ29iamVjdCcgJiYgb3RoZXJUeXBlICE9ICdmdW5jdGlvbicgJiYgb3RoZXJUeXBlICE9ICdvYmplY3QnKSkpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIGNvbXBhcmUgW1tDbGFzc11dIG5hbWVzXHJcbiAgICB2YXIgY2xhc3NOYW1lID0gdG9TdHJpbmcuY2FsbChhKSxcclxuICAgICAgICBvdGhlckNsYXNzID0gdG9TdHJpbmcuY2FsbChiKTtcclxuXHJcbiAgICBpZiAoY2xhc3NOYW1lID09IGFyZ3NDbGFzcykge1xyXG4gICAgICBjbGFzc05hbWUgPSBvYmplY3RDbGFzcztcclxuICAgIH1cclxuICAgIGlmIChvdGhlckNsYXNzID09IGFyZ3NDbGFzcykge1xyXG4gICAgICBvdGhlckNsYXNzID0gb2JqZWN0Q2xhc3M7XHJcbiAgICB9XHJcbiAgICBpZiAoY2xhc3NOYW1lICE9IG90aGVyQ2xhc3MpIHtcclxuICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgfVxyXG4gICAgc3dpdGNoIChjbGFzc05hbWUpIHtcclxuICAgICAgY2FzZSBib29sQ2xhc3M6XHJcbiAgICAgIGNhc2UgZGF0ZUNsYXNzOlxyXG4gICAgICAgIC8vIGNvZXJjZSBkYXRlcyBhbmQgYm9vbGVhbnMgdG8gbnVtYmVycywgZGF0ZXMgdG8gbWlsbGlzZWNvbmRzIGFuZCBib29sZWFuc1xyXG4gICAgICAgIC8vIHRvIGAxYCBvciBgMGAgdHJlYXRpbmcgaW52YWxpZCBkYXRlcyBjb2VyY2VkIHRvIGBOYU5gIGFzIG5vdCBlcXVhbFxyXG4gICAgICAgIHJldHVybiArYSA9PSArYjtcclxuXHJcbiAgICAgIGNhc2UgbnVtYmVyQ2xhc3M6XHJcbiAgICAgICAgLy8gdHJlYXQgYE5hTmAgdnMuIGBOYU5gIGFzIGVxdWFsXHJcbiAgICAgICAgcmV0dXJuIChhICE9ICthKVxyXG4gICAgICAgICAgPyBiICE9ICtiXHJcbiAgICAgICAgICAvLyBidXQgdHJlYXQgYC0wYCB2cy4gYCswYCBhcyBub3QgZXF1YWxcclxuICAgICAgICAgIDogKGEgPT0gMCA/ICgxIC8gYSA9PSAxIC8gYikgOiBhID09ICtiKTtcclxuXHJcbiAgICAgIGNhc2UgcmVnZXhwQ2xhc3M6XHJcbiAgICAgIGNhc2Ugc3RyaW5nQ2xhc3M6XHJcbiAgICAgICAgLy8gY29lcmNlIHJlZ2V4ZXMgdG8gc3RyaW5ncyAoaHR0cDovL2VzNS5naXRodWIuaW8vI3gxNS4xMC42LjQpXHJcbiAgICAgICAgLy8gdHJlYXQgc3RyaW5nIHByaW1pdGl2ZXMgYW5kIHRoZWlyIGNvcnJlc3BvbmRpbmcgb2JqZWN0IGluc3RhbmNlcyBhcyBlcXVhbFxyXG4gICAgICAgIHJldHVybiBhID09IFN0cmluZyhiKTtcclxuICAgIH1cclxuICAgIHZhciBpc0FyciA9IGNsYXNzTmFtZSA9PSBhcnJheUNsYXNzO1xyXG4gICAgaWYgKCFpc0Fycikge1xyXG5cclxuICAgICAgLy8gZXhpdCBmb3IgZnVuY3Rpb25zIGFuZCBET00gbm9kZXNcclxuICAgICAgaWYgKGNsYXNzTmFtZSAhPSBvYmplY3RDbGFzcyB8fCAoIXN1cHBvcnQubm9kZUNsYXNzICYmIChpc05vZGUoYSkgfHwgaXNOb2RlKGIpKSkpIHtcclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgIH1cclxuICAgICAgLy8gaW4gb2xkZXIgdmVyc2lvbnMgb2YgT3BlcmEsIGBhcmd1bWVudHNgIG9iamVjdHMgaGF2ZSBgQXJyYXlgIGNvbnN0cnVjdG9yc1xyXG4gICAgICB2YXIgY3RvckEgPSAhc3VwcG9ydC5hcmdzT2JqZWN0ICYmIGlzQXJndW1lbnRzKGEpID8gT2JqZWN0IDogYS5jb25zdHJ1Y3RvcixcclxuICAgICAgICAgIGN0b3JCID0gIXN1cHBvcnQuYXJnc09iamVjdCAmJiBpc0FyZ3VtZW50cyhiKSA/IE9iamVjdCA6IGIuY29uc3RydWN0b3I7XHJcblxyXG4gICAgICAvLyBub24gYE9iamVjdGAgb2JqZWN0IGluc3RhbmNlcyB3aXRoIGRpZmZlcmVudCBjb25zdHJ1Y3RvcnMgYXJlIG5vdCBlcXVhbFxyXG4gICAgICBpZiAoY3RvckEgIT0gY3RvckIgJiZcclxuICAgICAgICAgICAgIShoYXNPd25Qcm9wZXJ0eS5jYWxsKGEsICdjb25zdHJ1Y3RvcicpICYmIGhhc093blByb3BlcnR5LmNhbGwoYiwgJ2NvbnN0cnVjdG9yJykpICYmXHJcbiAgICAgICAgICAgICEoaXNGdW5jdGlvbihjdG9yQSkgJiYgY3RvckEgaW5zdGFuY2VvZiBjdG9yQSAmJiBpc0Z1bmN0aW9uKGN0b3JCKSAmJiBjdG9yQiBpbnN0YW5jZW9mIGN0b3JCKSAmJlxyXG4gICAgICAgICAgICAoJ2NvbnN0cnVjdG9yJyBpbiBhICYmICdjb25zdHJ1Y3RvcicgaW4gYilcclxuICAgICAgICAgICkge1xyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgLy8gYXNzdW1lIGN5Y2xpYyBzdHJ1Y3R1cmVzIGFyZSBlcXVhbFxyXG4gICAgLy8gdGhlIGFsZ29yaXRobSBmb3IgZGV0ZWN0aW5nIGN5Y2xpYyBzdHJ1Y3R1cmVzIGlzIGFkYXB0ZWQgZnJvbSBFUyA1LjFcclxuICAgIC8vIHNlY3Rpb24gMTUuMTIuMywgYWJzdHJhY3Qgb3BlcmF0aW9uIGBKT2AgKGh0dHA6Ly9lczUuZ2l0aHViLmlvLyN4MTUuMTIuMylcclxuICAgIHZhciBpbml0ZWRTdGFjayA9ICFzdGFja0E7XHJcbiAgICBzdGFja0EgfHwgKHN0YWNrQSA9IFtdKTtcclxuICAgIHN0YWNrQiB8fCAoc3RhY2tCID0gW10pO1xyXG5cclxuICAgIHZhciBsZW5ndGggPSBzdGFja0EubGVuZ3RoO1xyXG4gICAgd2hpbGUgKGxlbmd0aC0tKSB7XHJcbiAgICAgIGlmIChzdGFja0FbbGVuZ3RoXSA9PSBhKSB7XHJcbiAgICAgICAgcmV0dXJuIHN0YWNrQltsZW5ndGhdID09IGI7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHZhciBzaXplID0gMDtcclxuICAgIHJlc3VsdCA9IHRydWU7XHJcblxyXG4gICAgLy8gYWRkIGBhYCBhbmQgYGJgIHRvIHRoZSBzdGFjayBvZiB0cmF2ZXJzZWQgb2JqZWN0c1xyXG4gICAgc3RhY2tBLnB1c2goYSk7XHJcbiAgICBzdGFja0IucHVzaChiKTtcclxuXHJcbiAgICAvLyByZWN1cnNpdmVseSBjb21wYXJlIG9iamVjdHMgYW5kIGFycmF5cyAoc3VzY2VwdGlibGUgdG8gY2FsbCBzdGFjayBsaW1pdHMpXHJcbiAgICBpZiAoaXNBcnIpIHtcclxuICAgICAgLy8gY29tcGFyZSBsZW5ndGhzIHRvIGRldGVybWluZSBpZiBhIGRlZXAgY29tcGFyaXNvbiBpcyBuZWNlc3NhcnlcclxuICAgICAgbGVuZ3RoID0gYS5sZW5ndGg7XHJcbiAgICAgIHNpemUgPSBiLmxlbmd0aDtcclxuICAgICAgcmVzdWx0ID0gc2l6ZSA9PSBsZW5ndGg7XHJcblxyXG4gICAgICBpZiAocmVzdWx0KSB7XHJcbiAgICAgICAgLy8gZGVlcCBjb21wYXJlIHRoZSBjb250ZW50cywgaWdub3Jpbmcgbm9uLW51bWVyaWMgcHJvcGVydGllc1xyXG4gICAgICAgIHdoaWxlIChzaXplLS0pIHtcclxuICAgICAgICAgIHZhciBpbmRleCA9IGxlbmd0aCxcclxuICAgICAgICAgICAgICB2YWx1ZSA9IGJbc2l6ZV07XHJcblxyXG4gICAgICAgICAgaWYgKCEocmVzdWx0ID0gZGVlcEVxdWFscyhhW3NpemVdLCB2YWx1ZSwgc3RhY2tBLCBzdGFja0IpKSkge1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIGVsc2Uge1xyXG4gICAgICAvLyBkZWVwIGNvbXBhcmUgb2JqZWN0cyB1c2luZyBgZm9ySW5gLCBpbnN0ZWFkIG9mIGBmb3JPd25gLCB0byBhdm9pZCBgT2JqZWN0LmtleXNgXHJcbiAgICAgIC8vIHdoaWNoLCBpbiB0aGlzIGNhc2UsIGlzIG1vcmUgY29zdGx5XHJcbiAgICAgIGludGVybmFsRm9ySW4oYiwgZnVuY3Rpb24odmFsdWUsIGtleSwgYikge1xyXG4gICAgICAgIGlmIChoYXNPd25Qcm9wZXJ0eS5jYWxsKGIsIGtleSkpIHtcclxuICAgICAgICAgIC8vIGNvdW50IHRoZSBudW1iZXIgb2YgcHJvcGVydGllcy5cclxuICAgICAgICAgIHNpemUrKztcclxuICAgICAgICAgIC8vIGRlZXAgY29tcGFyZSBlYWNoIHByb3BlcnR5IHZhbHVlLlxyXG4gICAgICAgICAgcmV0dXJuIChyZXN1bHQgPSBoYXNPd25Qcm9wZXJ0eS5jYWxsKGEsIGtleSkgJiYgZGVlcEVxdWFscyhhW2tleV0sIHZhbHVlLCBzdGFja0EsIHN0YWNrQikpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgICBpZiAocmVzdWx0KSB7XHJcbiAgICAgICAgLy8gZW5zdXJlIGJvdGggb2JqZWN0cyBoYXZlIHRoZSBzYW1lIG51bWJlciBvZiBwcm9wZXJ0aWVzXHJcbiAgICAgICAgaW50ZXJuYWxGb3JJbihhLCBmdW5jdGlvbih2YWx1ZSwga2V5LCBhKSB7XHJcbiAgICAgICAgICBpZiAoaGFzT3duUHJvcGVydHkuY2FsbChhLCBrZXkpKSB7XHJcbiAgICAgICAgICAgIC8vIGBzaXplYCB3aWxsIGJlIGAtMWAgaWYgYGFgIGhhcyBtb3JlIHByb3BlcnRpZXMgdGhhbiBgYmBcclxuICAgICAgICAgICAgcmV0dXJuIChyZXN1bHQgPSAtLXNpemUgPiAtMSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICAgIHN0YWNrQS5wb3AoKTtcclxuICAgIHN0YWNrQi5wb3AoKTtcclxuXHJcbiAgICByZXR1cm4gcmVzdWx0O1xyXG4gIH1cclxuICAgIHZhciBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcclxuICAgIGZ1bmN0aW9uIGFyZ3NPckFycmF5KGFyZ3MsIGlkeCkge1xyXG4gICAgICAgIHJldHVybiBhcmdzLmxlbmd0aCA9PT0gMSAmJiBBcnJheS5pc0FycmF5KGFyZ3NbaWR4XSkgP1xyXG4gICAgICAgICAgICBhcmdzW2lkeF0gOlxyXG4gICAgICAgICAgICBzbGljZS5jYWxsKGFyZ3MpO1xyXG4gICAgfVxyXG4gICAgdmFyIGhhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi9cclxuICAgIHZhciBpbmhlcml0cyA9IHRoaXMuaW5oZXJpdHMgPSBSeC5pbnRlcm5hbHMuaW5oZXJpdHMgPSBmdW5jdGlvbiAoY2hpbGQsIHBhcmVudCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIF9fKCkgeyB0aGlzLmNvbnN0cnVjdG9yID0gY2hpbGQ7IH1cclxuICAgICAgICBfXy5wcm90b3R5cGUgPSBwYXJlbnQucHJvdG90eXBlO1xyXG4gICAgICAgIGNoaWxkLnByb3RvdHlwZSA9IG5ldyBfXygpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi8gICAgXHJcbiAgICB2YXIgYWRkUHJvcGVydGllcyA9IFJ4LmludGVybmFscy5hZGRQcm9wZXJ0aWVzID0gZnVuY3Rpb24gKG9iaikge1xyXG4gICAgICAgIHZhciBzb3VyY2VzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzb3VyY2VzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzW2ldO1xyXG4gICAgICAgICAgICBmb3IgKHZhciBwcm9wIGluIHNvdXJjZSkge1xyXG4gICAgICAgICAgICAgICAgb2JqW3Byb3BdID0gc291cmNlW3Byb3BdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvLyBSeCBVdGlsc1xyXG4gICAgdmFyIGFkZFJlZiA9IFJ4LmludGVybmFscy5hZGRSZWYgPSBmdW5jdGlvbiAoeHMsIHIpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZShyLmdldERpc3Bvc2FibGUoKSwgeHMuc3Vic2NyaWJlKG9ic2VydmVyKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8vIENvbGxlY3Rpb24gcG9seWZpbGxzXHJcbiAgICBmdW5jdGlvbiBhcnJheUluaXRpYWxpemUoY291bnQsIGZhY3RvcnkpIHtcclxuICAgICAgICB2YXIgYSA9IG5ldyBBcnJheShjb3VudCk7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGFbaV0gPSBmYWN0b3J5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBhO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIENvbGxlY3Rpb25zXHJcbiAgICB2YXIgSW5kZXhlZEl0ZW0gPSBmdW5jdGlvbiAoaWQsIHZhbHVlKSB7XHJcbiAgICAgICAgdGhpcy5pZCA9IGlkO1xyXG4gICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcclxuICAgIH07XHJcblxyXG4gICAgSW5kZXhlZEl0ZW0ucHJvdG90eXBlLmNvbXBhcmVUbyA9IGZ1bmN0aW9uIChvdGhlcikge1xyXG4gICAgICAgIHZhciBjID0gdGhpcy52YWx1ZS5jb21wYXJlVG8ob3RoZXIudmFsdWUpO1xyXG4gICAgICAgIGlmIChjID09PSAwKSB7XHJcbiAgICAgICAgICAgIGMgPSB0aGlzLmlkIC0gb3RoZXIuaWQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBjO1xyXG4gICAgfTtcclxuXHJcbiAgICAvLyBQcmlvcml0eSBRdWV1ZSBmb3IgU2NoZWR1bGluZ1xyXG4gICAgdmFyIFByaW9yaXR5UXVldWUgPSBSeC5pbnRlcm5hbHMuUHJpb3JpdHlRdWV1ZSA9IGZ1bmN0aW9uIChjYXBhY2l0eSkge1xyXG4gICAgICAgIHRoaXMuaXRlbXMgPSBuZXcgQXJyYXkoY2FwYWNpdHkpO1xyXG4gICAgICAgIHRoaXMubGVuZ3RoID0gMDtcclxuICAgIH07XHJcblxyXG4gICAgdmFyIHByaW9yaXR5UHJvdG8gPSBQcmlvcml0eVF1ZXVlLnByb3RvdHlwZTtcclxuICAgIHByaW9yaXR5UHJvdG8uaXNIaWdoZXJQcmlvcml0eSA9IGZ1bmN0aW9uIChsZWZ0LCByaWdodCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLml0ZW1zW2xlZnRdLmNvbXBhcmVUbyh0aGlzLml0ZW1zW3JpZ2h0XSkgPCAwO1xyXG4gICAgfTtcclxuXHJcbiAgICBwcmlvcml0eVByb3RvLnBlcmNvbGF0ZSA9IGZ1bmN0aW9uIChpbmRleCkge1xyXG4gICAgICAgIGlmIChpbmRleCA+PSB0aGlzLmxlbmd0aCB8fCBpbmRleCA8IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgcGFyZW50ID0gaW5kZXggLSAxID4+IDE7XHJcbiAgICAgICAgaWYgKHBhcmVudCA8IDAgfHwgcGFyZW50ID09PSBpbmRleCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmICh0aGlzLmlzSGlnaGVyUHJpb3JpdHkoaW5kZXgsIHBhcmVudCkpIHtcclxuICAgICAgICAgICAgdmFyIHRlbXAgPSB0aGlzLml0ZW1zW2luZGV4XTtcclxuICAgICAgICAgICAgdGhpcy5pdGVtc1tpbmRleF0gPSB0aGlzLml0ZW1zW3BhcmVudF07XHJcbiAgICAgICAgICAgIHRoaXMuaXRlbXNbcGFyZW50XSA9IHRlbXA7XHJcbiAgICAgICAgICAgIHRoaXMucGVyY29sYXRlKHBhcmVudCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICBwcmlvcml0eVByb3RvLmhlYXBpZnkgPSBmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgICBpZiAoaW5kZXggPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBpbmRleCA9IDA7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChpbmRleCA+PSB0aGlzLmxlbmd0aCB8fCBpbmRleCA8IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgbGVmdCA9IDIgKiBpbmRleCArIDEsXHJcbiAgICAgICAgICAgIHJpZ2h0ID0gMiAqIGluZGV4ICsgMixcclxuICAgICAgICAgICAgZmlyc3QgPSBpbmRleDtcclxuICAgICAgICBpZiAobGVmdCA8IHRoaXMubGVuZ3RoICYmIHRoaXMuaXNIaWdoZXJQcmlvcml0eShsZWZ0LCBmaXJzdCkpIHtcclxuICAgICAgICAgICAgZmlyc3QgPSBsZWZ0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocmlnaHQgPCB0aGlzLmxlbmd0aCAmJiB0aGlzLmlzSGlnaGVyUHJpb3JpdHkocmlnaHQsIGZpcnN0KSkge1xyXG4gICAgICAgICAgICBmaXJzdCA9IHJpZ2h0O1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoZmlyc3QgIT09IGluZGV4KSB7XHJcbiAgICAgICAgICAgIHZhciB0ZW1wID0gdGhpcy5pdGVtc1tpbmRleF07XHJcbiAgICAgICAgICAgIHRoaXMuaXRlbXNbaW5kZXhdID0gdGhpcy5pdGVtc1tmaXJzdF07XHJcbiAgICAgICAgICAgIHRoaXMuaXRlbXNbZmlyc3RdID0gdGVtcDtcclxuICAgICAgICAgICAgdGhpcy5oZWFwaWZ5KGZpcnN0KTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgXHJcbiAgICBwcmlvcml0eVByb3RvLnBlZWsgPSBmdW5jdGlvbiAoKSB7ICByZXR1cm4gdGhpcy5pdGVtc1swXS52YWx1ZTsgfTtcclxuXHJcbiAgICBwcmlvcml0eVByb3RvLnJlbW92ZUF0ID0gZnVuY3Rpb24gKGluZGV4KSB7XHJcbiAgICAgICAgdGhpcy5pdGVtc1tpbmRleF0gPSB0aGlzLml0ZW1zWy0tdGhpcy5sZW5ndGhdO1xyXG4gICAgICAgIGRlbGV0ZSB0aGlzLml0ZW1zW3RoaXMubGVuZ3RoXTtcclxuICAgICAgICB0aGlzLmhlYXBpZnkoKTtcclxuICAgIH07XHJcblxyXG4gICAgcHJpb3JpdHlQcm90by5kZXF1ZXVlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciByZXN1bHQgPSB0aGlzLnBlZWsoKTtcclxuICAgICAgICB0aGlzLnJlbW92ZUF0KDApO1xyXG4gICAgICAgIHJldHVybiByZXN1bHQ7XHJcbiAgICB9O1xyXG5cclxuICAgIHByaW9yaXR5UHJvdG8uZW5xdWV1ZSA9IGZ1bmN0aW9uIChpdGVtKSB7XHJcbiAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5sZW5ndGgrKztcclxuICAgICAgICB0aGlzLml0ZW1zW2luZGV4XSA9IG5ldyBJbmRleGVkSXRlbShQcmlvcml0eVF1ZXVlLmNvdW50KyssIGl0ZW0pO1xyXG4gICAgICAgIHRoaXMucGVyY29sYXRlKGluZGV4KTtcclxuICAgIH07XHJcblxyXG4gICAgcHJpb3JpdHlQcm90by5yZW1vdmUgPSBmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5pdGVtc1tpXS52YWx1ZSA9PT0gaXRlbSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yZW1vdmVBdChpKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgIH07XHJcbiAgICBQcmlvcml0eVF1ZXVlLmNvdW50ID0gMDtcclxuICAgIC8qKlxyXG4gICAgICogUmVwcmVzZW50cyBhIGdyb3VwIG9mIGRpc3Bvc2FibGUgcmVzb3VyY2VzIHRoYXQgYXJlIGRpc3Bvc2VkIHRvZ2V0aGVyLlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKi9cclxuICAgIHZhciBDb21wb3NpdGVEaXNwb3NhYmxlID0gUnguQ29tcG9zaXRlRGlzcG9zYWJsZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmRpc3Bvc2FibGVzID0gYXJnc09yQXJyYXkoYXJndW1lbnRzLCAwKTtcclxuICAgICAgICB0aGlzLmlzRGlzcG9zZWQgPSBmYWxzZTtcclxuICAgICAgICB0aGlzLmxlbmd0aCA9IHRoaXMuZGlzcG9zYWJsZXMubGVuZ3RoO1xyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgQ29tcG9zaXRlRGlzcG9zYWJsZVByb3RvdHlwZSA9IENvbXBvc2l0ZURpc3Bvc2FibGUucHJvdG90eXBlO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQWRkcyBhIGRpc3Bvc2FibGUgdG8gdGhlIENvbXBvc2l0ZURpc3Bvc2FibGUgb3IgZGlzcG9zZXMgdGhlIGRpc3Bvc2FibGUgaWYgdGhlIENvbXBvc2l0ZURpc3Bvc2FibGUgaXMgZGlzcG9zZWQuXHJcbiAgICAgKiBAcGFyYW0ge01peGVkfSBpdGVtIERpc3Bvc2FibGUgdG8gYWRkLlxyXG4gICAgICovICAgIFxyXG4gICAgQ29tcG9zaXRlRGlzcG9zYWJsZVByb3RvdHlwZS5hZGQgPSBmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgIGlmICh0aGlzLmlzRGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgaXRlbS5kaXNwb3NlKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgdGhpcy5kaXNwb3NhYmxlcy5wdXNoKGl0ZW0pO1xyXG4gICAgICAgICAgICB0aGlzLmxlbmd0aCsrO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZW1vdmVzIGFuZCBkaXNwb3NlcyB0aGUgZmlyc3Qgb2NjdXJyZW5jZSBvZiBhIGRpc3Bvc2FibGUgZnJvbSB0aGUgQ29tcG9zaXRlRGlzcG9zYWJsZS5cclxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGl0ZW0gRGlzcG9zYWJsZSB0byByZW1vdmUuXHJcbiAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gdHJ1ZSBpZiBmb3VuZDsgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICBDb21wb3NpdGVEaXNwb3NhYmxlUHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uIChpdGVtKSB7XHJcbiAgICAgICAgdmFyIHNob3VsZERpc3Bvc2UgPSBmYWxzZTtcclxuICAgICAgICBpZiAoIXRoaXMuaXNEaXNwb3NlZCkge1xyXG4gICAgICAgICAgICB2YXIgaWR4ID0gdGhpcy5kaXNwb3NhYmxlcy5pbmRleE9mKGl0ZW0pO1xyXG4gICAgICAgICAgICBpZiAoaWR4ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgc2hvdWxkRGlzcG9zZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2FibGVzLnNwbGljZShpZHgsIDEpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5sZW5ndGgtLTtcclxuICAgICAgICAgICAgICAgIGl0ZW0uZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2hvdWxkRGlzcG9zZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgRGlzcG9zZXMgYWxsIGRpc3Bvc2FibGVzIGluIHRoZSBncm91cCBhbmQgcmVtb3ZlcyB0aGVtIGZyb20gdGhlIGdyb3VwLiAgXHJcbiAgICAgKi9cclxuICAgIENvbXBvc2l0ZURpc3Bvc2FibGVQcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuaXNEaXNwb3NlZCkge1xyXG4gICAgICAgICAgICB0aGlzLmlzRGlzcG9zZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICB2YXIgY3VycmVudERpc3Bvc2FibGVzID0gdGhpcy5kaXNwb3NhYmxlcy5zbGljZSgwKTtcclxuICAgICAgICAgICAgdGhpcy5kaXNwb3NhYmxlcyA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLmxlbmd0aCA9IDA7XHJcblxyXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gY3VycmVudERpc3Bvc2FibGVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBjdXJyZW50RGlzcG9zYWJsZXNbaV0uZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlbW92ZXMgYW5kIGRpc3Bvc2VzIGFsbCBkaXNwb3NhYmxlcyBmcm9tIHRoZSBDb21wb3NpdGVEaXNwb3NhYmxlLCBidXQgZG9lcyBub3QgZGlzcG9zZSB0aGUgQ29tcG9zaXRlRGlzcG9zYWJsZS5cclxuICAgICAqLyAgIFxyXG4gICAgQ29tcG9zaXRlRGlzcG9zYWJsZVByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgY3VycmVudERpc3Bvc2FibGVzID0gdGhpcy5kaXNwb3NhYmxlcy5zbGljZSgwKTtcclxuICAgICAgICB0aGlzLmRpc3Bvc2FibGVzID0gW107XHJcbiAgICAgICAgdGhpcy5sZW5ndGggPSAwO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBjdXJyZW50RGlzcG9zYWJsZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgY3VycmVudERpc3Bvc2FibGVzW2ldLmRpc3Bvc2UoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIHRoZSBDb21wb3NpdGVEaXNwb3NhYmxlIGNvbnRhaW5zIGEgc3BlY2lmaWMgZGlzcG9zYWJsZS4gICAgXHJcbiAgICAgKiBAcGFyYW0ge01peGVkfSBpdGVtIERpc3Bvc2FibGUgdG8gc2VhcmNoIGZvci5cclxuICAgICAqIEByZXR1cm5zIHtCb29sZWFufSB0cnVlIGlmIHRoZSBkaXNwb3NhYmxlIHdhcyBmb3VuZDsgb3RoZXJ3aXNlLCBmYWxzZS5cclxuICAgICAqLyAgICBcclxuICAgIENvbXBvc2l0ZURpc3Bvc2FibGVQcm90b3R5cGUuY29udGFpbnMgPSBmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRpc3Bvc2FibGVzLmluZGV4T2YoaXRlbSkgIT09IC0xO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIHRoZSBleGlzdGluZyBDb21wb3NpdGVEaXNwb3NhYmxlIHRvIGFuIGFycmF5IG9mIGRpc3Bvc2FibGVzXHJcbiAgICAgKiBAcmV0dXJucyB7QXJyYXl9IEFuIGFycmF5IG9mIGRpc3Bvc2FibGUgb2JqZWN0cy5cclxuICAgICAqLyAgXHJcbiAgICBDb21wb3NpdGVEaXNwb3NhYmxlUHJvdG90eXBlLnRvQXJyYXkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZGlzcG9zYWJsZXMuc2xpY2UoMCk7XHJcbiAgICB9O1xyXG4gICAgXHJcbiAgICAvKipcclxuICAgICAqIFByb3ZpZGVzIGEgc2V0IG9mIHN0YXRpYyBtZXRob2RzIGZvciBjcmVhdGluZyBEaXNwb3NhYmxlcy5cclxuICAgICAqXHJcbiAgICAgKiBAY29uc3RydWN0b3IgXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkaXNwb3NlIEFjdGlvbiB0byBydW4gZHVyaW5nIHRoZSBmaXJzdCBjYWxsIHRvIGRpc3Bvc2UuIFRoZSBhY3Rpb24gaXMgZ3VhcmFudGVlZCB0byBiZSBydW4gYXQgbW9zdCBvbmNlLlxyXG4gICAgICovXHJcbiAgICB2YXIgRGlzcG9zYWJsZSA9IFJ4LkRpc3Bvc2FibGUgPSBmdW5jdGlvbiAoYWN0aW9uKSB7XHJcbiAgICAgICAgdGhpcy5pc0Rpc3Bvc2VkID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5hY3Rpb24gPSBhY3Rpb24gfHwgbm9vcDtcclxuICAgIH07XHJcblxyXG4gICAgLyoqIFBlcmZvcm1zIHRoZSB0YXNrIG9mIGNsZWFuaW5nIHVwIHJlc291cmNlcy4gKi8gICAgIFxyXG4gICAgRGlzcG9zYWJsZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoIXRoaXMuaXNEaXNwb3NlZCkge1xyXG4gICAgICAgICAgICB0aGlzLmFjdGlvbigpO1xyXG4gICAgICAgICAgICB0aGlzLmlzRGlzcG9zZWQgPSB0cnVlO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgZGlzcG9zYWJsZSBvYmplY3QgdGhhdCBpbnZva2VzIHRoZSBzcGVjaWZpZWQgYWN0aW9uIHdoZW4gZGlzcG9zZWQuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBkaXNwb3NlIEFjdGlvbiB0byBydW4gZHVyaW5nIHRoZSBmaXJzdCBjYWxsIHRvIGRpc3Bvc2UuIFRoZSBhY3Rpb24gaXMgZ3VhcmFudGVlZCB0byBiZSBydW4gYXQgbW9zdCBvbmNlLlxyXG4gICAgICogQHJldHVybiB7RGlzcG9zYWJsZX0gVGhlIGRpc3Bvc2FibGUgb2JqZWN0IHRoYXQgcnVucyB0aGUgZ2l2ZW4gYWN0aW9uIHVwb24gZGlzcG9zYWwuXHJcbiAgICAgKi9cclxuICAgIHZhciBkaXNwb3NhYmxlQ3JlYXRlID0gRGlzcG9zYWJsZS5jcmVhdGUgPSBmdW5jdGlvbiAoYWN0aW9uKSB7IHJldHVybiBuZXcgRGlzcG9zYWJsZShhY3Rpb24pOyB9O1xyXG5cclxuICAgIC8qKiBcclxuICAgICAqIEdldHMgdGhlIGRpc3Bvc2FibGUgdGhhdCBkb2VzIG5vdGhpbmcgd2hlbiBkaXNwb3NlZC4gXHJcbiAgICAgKi9cclxuICAgIHZhciBkaXNwb3NhYmxlRW1wdHkgPSBEaXNwb3NhYmxlLmVtcHR5ID0geyBkaXNwb3NlOiBub29wIH07XHJcblxyXG4gICAgdmFyIEJvb2xlYW5EaXNwb3NhYmxlID0gKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBmdW5jdGlvbiBCb29sZWFuRGlzcG9zYWJsZSAoaXNTaW5nbGUpIHtcclxuICAgICAgICAgICAgdGhpcy5pc1NpbmdsZSA9IGlzU2luZ2xlO1xyXG4gICAgICAgICAgICB0aGlzLmlzRGlzcG9zZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5jdXJyZW50ID0gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBib29sZWFuRGlzcG9zYWJsZVByb3RvdHlwZSA9IEJvb2xlYW5EaXNwb3NhYmxlLnByb3RvdHlwZTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogR2V0cyB0aGUgdW5kZXJseWluZyBkaXNwb3NhYmxlLlxyXG4gICAgICAgICAqIEByZXR1cm4gVGhlIHVuZGVybHlpbmcgZGlzcG9zYWJsZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBib29sZWFuRGlzcG9zYWJsZVByb3RvdHlwZS5nZXREaXNwb3NhYmxlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jdXJyZW50O1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNldHMgdGhlIHVuZGVybHlpbmcgZGlzcG9zYWJsZS5cclxuICAgICAgICAgKiBAcGFyYW0ge0Rpc3Bvc2FibGV9IHZhbHVlIFRoZSBuZXcgdW5kZXJseWluZyBkaXNwb3NhYmxlLlxyXG4gICAgICAgICAqLyAgXHJcbiAgICAgICAgYm9vbGVhbkRpc3Bvc2FibGVQcm90b3R5cGUuc2V0RGlzcG9zYWJsZSA9IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5jdXJyZW50ICYmIHRoaXMuaXNTaW5nbGUpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignRGlzcG9zYWJsZSBoYXMgYWxyZWFkeSBiZWVuIGFzc2lnbmVkJyk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHZhciBzaG91bGREaXNwb3NlID0gdGhpcy5pc0Rpc3Bvc2VkLCBvbGQ7XHJcbiAgICAgICAgICAgIGlmICghc2hvdWxkRGlzcG9zZSkge1xyXG4gICAgICAgICAgICAgICAgb2xkID0gdGhpcy5jdXJyZW50O1xyXG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyZW50ID0gdmFsdWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG9sZCkge1xyXG4gICAgICAgICAgICAgICAgb2xkLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoc2hvdWxkRGlzcG9zZSAmJiB2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqIFxyXG4gICAgICAgICAqIERpc3Bvc2VzIHRoZSB1bmRlcmx5aW5nIGRpc3Bvc2FibGUgYXMgd2VsbCBhcyBhbGwgZnV0dXJlIHJlcGxhY2VtZW50cy5cclxuICAgICAgICAgKi9cclxuICAgICAgICBib29sZWFuRGlzcG9zYWJsZVByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgb2xkO1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNEaXNwb3NlZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0Rpc3Bvc2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIG9sZCA9IHRoaXMuY3VycmVudDtcclxuICAgICAgICAgICAgICAgIHRoaXMuY3VycmVudCA9IG51bGw7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKG9sZCkge1xyXG4gICAgICAgICAgICAgICAgb2xkLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiBCb29sZWFuRGlzcG9zYWJsZTtcclxuICAgIH0oKSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXByZXNlbnRzIGEgZGlzcG9zYWJsZSByZXNvdXJjZSB3aGljaCBvbmx5IGFsbG93cyBhIHNpbmdsZSBhc3NpZ25tZW50IG9mIGl0cyB1bmRlcmx5aW5nIGRpc3Bvc2FibGUgcmVzb3VyY2UuXHJcbiAgICAgKiBJZiBhbiB1bmRlcmx5aW5nIGRpc3Bvc2FibGUgcmVzb3VyY2UgaGFzIGFscmVhZHkgYmVlbiBzZXQsIGZ1dHVyZSBhdHRlbXB0cyB0byBzZXQgdGhlIHVuZGVybHlpbmcgZGlzcG9zYWJsZSByZXNvdXJjZSB3aWxsIHRocm93IGFuIEVycm9yLlxyXG4gICAgICovXHJcbiAgICB2YXIgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUgPSBSeC5TaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSA9IChmdW5jdGlvbiAoc3VwZXJfKSB7XHJcbiAgICAgICAgaW5oZXJpdHMoU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUsIHN1cGVyXyk7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCkge1xyXG4gICAgICAgICAgICBzdXBlcl8uY2FsbCh0aGlzLCB0cnVlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZTtcclxuICAgIH0oQm9vbGVhbkRpc3Bvc2FibGUpKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlcHJlc2VudHMgYSBkaXNwb3NhYmxlIHJlc291cmNlIHdob3NlIHVuZGVybHlpbmcgZGlzcG9zYWJsZSByZXNvdXJjZSBjYW4gYmUgcmVwbGFjZWQgYnkgYW5vdGhlciBkaXNwb3NhYmxlIHJlc291cmNlLCBjYXVzaW5nIGF1dG9tYXRpYyBkaXNwb3NhbCBvZiB0aGUgcHJldmlvdXMgdW5kZXJseWluZyBkaXNwb3NhYmxlIHJlc291cmNlLlxyXG4gICAgICovXHJcbiAgICB2YXIgU2VyaWFsRGlzcG9zYWJsZSA9IFJ4LlNlcmlhbERpc3Bvc2FibGUgPSAoZnVuY3Rpb24gKHN1cGVyXykge1xyXG4gICAgICAgIGluaGVyaXRzKFNlcmlhbERpc3Bvc2FibGUsIHN1cGVyXyk7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIFNlcmlhbERpc3Bvc2FibGUoKSB7XHJcbiAgICAgICAgICAgIHN1cGVyXy5jYWxsKHRoaXMsIGZhbHNlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBTZXJpYWxEaXNwb3NhYmxlO1xyXG4gICAgfShCb29sZWFuRGlzcG9zYWJsZSkpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmVwcmVzZW50cyBhIGRpc3Bvc2FibGUgcmVzb3VyY2UgdGhhdCBvbmx5IGRpc3Bvc2VzIGl0cyB1bmRlcmx5aW5nIGRpc3Bvc2FibGUgcmVzb3VyY2Ugd2hlbiBhbGwgZGVwZW5kZW50IGRpc3Bvc2FibGUgb2JqZWN0cyBoYXZlIGJlZW4gZGlzcG9zZWQuXHJcbiAgICAgKi8gIFxyXG4gICAgdmFyIFJlZkNvdW50RGlzcG9zYWJsZSA9IFJ4LlJlZkNvdW50RGlzcG9zYWJsZSA9IChmdW5jdGlvbiAoKSB7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIElubmVyRGlzcG9zYWJsZShkaXNwb3NhYmxlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuZGlzcG9zYWJsZSA9IGRpc3Bvc2FibGU7XHJcbiAgICAgICAgICAgIHRoaXMuZGlzcG9zYWJsZS5jb3VudCsrO1xyXG4gICAgICAgICAgICB0aGlzLmlzSW5uZXJEaXNwb3NlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgSW5uZXJEaXNwb3NhYmxlLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuZGlzcG9zYWJsZS5pc0Rpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNJbm5lckRpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0lubmVyRGlzcG9zZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcG9zYWJsZS5jb3VudC0tO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmRpc3Bvc2FibGUuY291bnQgPT09IDAgJiYgdGhpcy5kaXNwb3NhYmxlLmlzUHJpbWFyeURpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZGlzcG9zYWJsZS5pc0Rpc3Bvc2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kaXNwb3NhYmxlLnVuZGVybHlpbmdEaXNwb3NhYmxlLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgUmVmQ291bnREaXNwb3NhYmxlIHdpdGggdGhlIHNwZWNpZmllZCBkaXNwb3NhYmxlLlxyXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAqIEBwYXJhbSB7RGlzcG9zYWJsZX0gZGlzcG9zYWJsZSBVbmRlcmx5aW5nIGRpc3Bvc2FibGUuXHJcbiAgICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIFJlZkNvdW50RGlzcG9zYWJsZShkaXNwb3NhYmxlKSB7XHJcbiAgICAgICAgICAgIHRoaXMudW5kZXJseWluZ0Rpc3Bvc2FibGUgPSBkaXNwb3NhYmxlO1xyXG4gICAgICAgICAgICB0aGlzLmlzRGlzcG9zZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5pc1ByaW1hcnlEaXNwb3NlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmNvdW50ID0gMDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKiBcclxuICAgICAgICAgKiBEaXNwb3NlcyB0aGUgdW5kZXJseWluZyBkaXNwb3NhYmxlIG9ubHkgd2hlbiBhbGwgZGVwZW5kZW50IGRpc3Bvc2FibGVzIGhhdmUgYmVlbiBkaXNwb3NlZCBcclxuICAgICAgICAgKi9cclxuICAgICAgICBSZWZDb3VudERpc3Bvc2FibGUucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5pc0Rpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNQcmltYXJ5RGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmlzUHJpbWFyeURpc3Bvc2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb3VudCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmlzRGlzcG9zZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVuZGVybHlpbmdEaXNwb3NhYmxlLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBSZXR1cm5zIGEgZGVwZW5kZW50IGRpc3Bvc2FibGUgdGhhdCB3aGVuIGRpc3Bvc2VkIGRlY3JlYXNlcyB0aGUgcmVmY291bnQgb24gdGhlIHVuZGVybHlpbmcgZGlzcG9zYWJsZS4gICAgICBcclxuICAgICAgICAgKiBAcmV0dXJucyB7RGlzcG9zYWJsZX0gQSBkZXBlbmRlbnQgZGlzcG9zYWJsZSBjb250cmlidXRpbmcgdG8gdGhlIHJlZmVyZW5jZSBjb3VudCB0aGF0IG1hbmFnZXMgdGhlIHVuZGVybHlpbmcgZGlzcG9zYWJsZSdzIGxpZmV0aW1lLlxyXG4gICAgICAgICAqLyAgICAgICAgXHJcbiAgICAgICAgUmVmQ291bnREaXNwb3NhYmxlLnByb3RvdHlwZS5nZXREaXNwb3NhYmxlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5pc0Rpc3Bvc2VkID8gZGlzcG9zYWJsZUVtcHR5IDogbmV3IElubmVyRGlzcG9zYWJsZSh0aGlzKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gUmVmQ291bnREaXNwb3NhYmxlO1xyXG4gICAgfSkoKTtcclxuXHJcbiAgICBmdW5jdGlvbiBTY2hlZHVsZWREaXNwb3NhYmxlKHNjaGVkdWxlciwgZGlzcG9zYWJsZSkge1xyXG4gICAgICAgIHRoaXMuc2NoZWR1bGVyID0gc2NoZWR1bGVyO1xyXG4gICAgICAgIHRoaXMuZGlzcG9zYWJsZSA9IGRpc3Bvc2FibGU7XHJcbiAgICAgICAgdGhpcy5pc0Rpc3Bvc2VkID0gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgU2NoZWR1bGVkRGlzcG9zYWJsZS5wcm90b3R5cGUuZGlzcG9zZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgcGFyZW50ID0gdGhpcztcclxuICAgICAgICB0aGlzLnNjaGVkdWxlci5zY2hlZHVsZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghcGFyZW50LmlzRGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgICAgIHBhcmVudC5pc0Rpc3Bvc2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHBhcmVudC5kaXNwb3NhYmxlLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICB2YXIgU2NoZWR1bGVkSXRlbSA9IFJ4LmludGVybmFscy5TY2hlZHVsZWRJdGVtID0gZnVuY3Rpb24gKHNjaGVkdWxlciwgc3RhdGUsIGFjdGlvbiwgZHVlVGltZSwgY29tcGFyZXIpIHtcclxuICAgICAgICB0aGlzLnNjaGVkdWxlciA9IHNjaGVkdWxlcjtcclxuICAgICAgICB0aGlzLnN0YXRlID0gc3RhdGU7XHJcbiAgICAgICAgdGhpcy5hY3Rpb24gPSBhY3Rpb247XHJcbiAgICAgICAgdGhpcy5kdWVUaW1lID0gZHVlVGltZTtcclxuICAgICAgICB0aGlzLmNvbXBhcmVyID0gY29tcGFyZXIgfHwgZGVmYXVsdFN1YkNvbXBhcmVyO1xyXG4gICAgICAgIHRoaXMuZGlzcG9zYWJsZSA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpO1xyXG4gICAgfVxyXG5cclxuICAgIFNjaGVkdWxlZEl0ZW0ucHJvdG90eXBlLmludm9rZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB0aGlzLmRpc3Bvc2FibGUuc2V0RGlzcG9zYWJsZSh0aGlzLmludm9rZUNvcmUoKSk7XHJcbiAgICB9O1xyXG5cclxuICAgIFNjaGVkdWxlZEl0ZW0ucHJvdG90eXBlLmNvbXBhcmVUbyA9IGZ1bmN0aW9uIChvdGhlcikge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNvbXBhcmVyKHRoaXMuZHVlVGltZSwgb3RoZXIuZHVlVGltZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIFNjaGVkdWxlZEl0ZW0ucHJvdG90eXBlLmlzQ2FuY2VsbGVkID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmRpc3Bvc2FibGUuaXNEaXNwb3NlZDtcclxuICAgIH07XHJcblxyXG4gICAgU2NoZWR1bGVkSXRlbS5wcm90b3R5cGUuaW52b2tlQ29yZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5hY3Rpb24odGhpcy5zY2hlZHVsZXIsIHRoaXMuc3RhdGUpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKiogUHJvdmlkZXMgYSBzZXQgb2Ygc3RhdGljIHByb3BlcnRpZXMgdG8gYWNjZXNzIGNvbW1vbmx5IHVzZWQgc2NoZWR1bGVycy4gKi9cclxuICAgIHZhciBTY2hlZHVsZXIgPSBSeC5TY2hlZHVsZXIgPSAoZnVuY3Rpb24gKCkge1xyXG5cclxuICAgICAgICAvKiogXHJcbiAgICAgICAgICogQGNvbnN0cnVjdG9yIFxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZnVuY3Rpb24gU2NoZWR1bGVyKG5vdywgc2NoZWR1bGUsIHNjaGVkdWxlUmVsYXRpdmUsIHNjaGVkdWxlQWJzb2x1dGUpIHtcclxuICAgICAgICAgICAgdGhpcy5ub3cgPSBub3c7XHJcbiAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlID0gc2NoZWR1bGU7XHJcbiAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlUmVsYXRpdmUgPSBzY2hlZHVsZVJlbGF0aXZlO1xyXG4gICAgICAgICAgICB0aGlzLl9zY2hlZHVsZUFic29sdXRlID0gc2NoZWR1bGVBYnNvbHV0ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGludm9rZVJlY0ltbWVkaWF0ZShzY2hlZHVsZXIsIHBhaXIpIHtcclxuICAgICAgICAgICAgdmFyIHN0YXRlID0gcGFpci5maXJzdCwgYWN0aW9uID0gcGFpci5zZWNvbmQsIGdyb3VwID0gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoKSxcclxuICAgICAgICAgICAgcmVjdXJzaXZlQWN0aW9uID0gZnVuY3Rpb24gKHN0YXRlMSkge1xyXG4gICAgICAgICAgICAgICAgYWN0aW9uKHN0YXRlMSwgZnVuY3Rpb24gKHN0YXRlMikge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpc0FkZGVkID0gZmFsc2UsIGlzRG9uZSA9IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgICAgIGQgPSBzY2hlZHVsZXIuc2NoZWR1bGVXaXRoU3RhdGUoc3RhdGUyLCBmdW5jdGlvbiAoc2NoZWR1bGVyMSwgc3RhdGUzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpc0FkZGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cC5yZW1vdmUoZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc0RvbmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlY3Vyc2l2ZUFjdGlvbihzdGF0ZTMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlzcG9zYWJsZUVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghaXNEb25lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwLmFkZChkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXNBZGRlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIHJlY3Vyc2l2ZUFjdGlvbihzdGF0ZSk7XHJcbiAgICAgICAgICAgIHJldHVybiBncm91cDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGludm9rZVJlY0RhdGUoc2NoZWR1bGVyLCBwYWlyLCBtZXRob2QpIHtcclxuICAgICAgICAgICAgdmFyIHN0YXRlID0gcGFpci5maXJzdCwgYWN0aW9uID0gcGFpci5zZWNvbmQsIGdyb3VwID0gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoKSxcclxuICAgICAgICAgICAgcmVjdXJzaXZlQWN0aW9uID0gZnVuY3Rpb24gKHN0YXRlMSkge1xyXG4gICAgICAgICAgICAgICAgYWN0aW9uKHN0YXRlMSwgZnVuY3Rpb24gKHN0YXRlMiwgZHVlVGltZTEpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaXNBZGRlZCA9IGZhbHNlLCBpc0RvbmUgPSBmYWxzZSxcclxuICAgICAgICAgICAgICAgICAgICBkID0gc2NoZWR1bGVyW21ldGhvZF0uY2FsbChzY2hlZHVsZXIsIHN0YXRlMiwgZHVlVGltZTEsIGZ1bmN0aW9uIChzY2hlZHVsZXIxLCBzdGF0ZTMpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzQWRkZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwLnJlbW92ZShkKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzRG9uZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVjdXJzaXZlQWN0aW9uKHN0YXRlMyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBkaXNwb3NhYmxlRW1wdHk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFpc0RvbmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAuYWRkKGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpc0FkZGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgcmVjdXJzaXZlQWN0aW9uKHN0YXRlKTtcclxuICAgICAgICAgICAgcmV0dXJuIGdyb3VwO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gaW52b2tlQWN0aW9uKHNjaGVkdWxlciwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIGFjdGlvbigpO1xyXG4gICAgICAgICAgICByZXR1cm4gZGlzcG9zYWJsZUVtcHR5O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIHNjaGVkdWxlclByb3RvID0gU2NoZWR1bGVyLnByb3RvdHlwZTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogUmV0dXJucyBhIHNjaGVkdWxlciB0aGF0IHdyYXBzIHRoZSBvcmlnaW5hbCBzY2hlZHVsZXIsIGFkZGluZyBleGNlcHRpb24gaGFuZGxpbmcgZm9yIHNjaGVkdWxlZCBhY3Rpb25zLiAgICAgICBcclxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBoYW5kbGVyIEhhbmRsZXIgdGhhdCdzIHJ1biBpZiBhbiBleGNlcHRpb24gaXMgY2F1Z2h0LiBUaGUgZXhjZXB0aW9uIHdpbGwgYmUgcmV0aHJvd24gaWYgdGhlIGhhbmRsZXIgcmV0dXJucyBmYWxzZS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7U2NoZWR1bGVyfSBXcmFwcGVyIGFyb3VuZCB0aGUgb3JpZ2luYWwgc2NoZWR1bGVyLCBlbmZvcmNpbmcgZXhjZXB0aW9uIGhhbmRsaW5nLlxyXG4gICAgICAgICAqLyAgICAgICAgXHJcbiAgICAgICAgc2NoZWR1bGVyUHJvdG8uY2F0Y2hFeGNlcHRpb24gPSBzY2hlZHVsZXJQcm90b1snY2F0Y2gnXSA9IGZ1bmN0aW9uIChoYW5kbGVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ2F0Y2hTY2hlZHVsZXIodGhpcywgaGFuZGxlcik7XHJcbiAgICAgICAgfTtcclxuICAgICAgICBcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTY2hlZHVsZXMgYSBwZXJpb2RpYyBwaWVjZSBvZiB3b3JrIGJ5IGR5bmFtaWNhbGx5IGRpc2NvdmVyaW5nIHRoZSBzY2hlZHVsZXIncyBjYXBhYmlsaXRpZXMuIFRoZSBwZXJpb2RpYyB0YXNrIHdpbGwgYmUgc2NoZWR1bGVkIHVzaW5nIHdpbmRvdy5zZXRJbnRlcnZhbCBmb3IgdGhlIGJhc2UgaW1wbGVtZW50YXRpb24uICAgICAgIFxyXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBwZXJpb2QgUGVyaW9kIGZvciBydW5uaW5nIHRoZSB3b3JrIHBlcmlvZGljYWxseS5cclxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhY3Rpb24gQWN0aW9uIHRvIGJlIGV4ZWN1dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtEaXNwb3NhYmxlfSBUaGUgZGlzcG9zYWJsZSBvYmplY3QgdXNlZCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCByZWN1cnJpbmcgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovICAgICAgICBcclxuICAgICAgICBzY2hlZHVsZXJQcm90by5zY2hlZHVsZVBlcmlvZGljID0gZnVuY3Rpb24gKHBlcmlvZCwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNjaGVkdWxlUGVyaW9kaWNXaXRoU3RhdGUobnVsbCwgcGVyaW9kLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBhY3Rpb24oKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogU2NoZWR1bGVzIGEgcGVyaW9kaWMgcGllY2Ugb2Ygd29yayBieSBkeW5hbWljYWxseSBkaXNjb3ZlcmluZyB0aGUgc2NoZWR1bGVyJ3MgY2FwYWJpbGl0aWVzLiBUaGUgcGVyaW9kaWMgdGFzayB3aWxsIGJlIHNjaGVkdWxlZCB1c2luZyB3aW5kb3cuc2V0SW50ZXJ2YWwgZm9yIHRoZSBiYXNlIGltcGxlbWVudGF0aW9uLiAgICAgICBcclxuICAgICAgICAgKiBAcGFyYW0ge01peGVkfSBzdGF0ZSBJbml0aWFsIHN0YXRlIHBhc3NlZCB0byB0aGUgYWN0aW9uIHVwb24gdGhlIGZpcnN0IGl0ZXJhdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gcGVyaW9kIFBlcmlvZCBmb3IgcnVubmluZyB0aGUgd29yayBwZXJpb2RpY2FsbHkuXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBiZSBleGVjdXRlZCwgcG90ZW50aWFsbHkgdXBkYXRpbmcgdGhlIHN0YXRlLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtEaXNwb3NhYmxlfSBUaGUgZGlzcG9zYWJsZSBvYmplY3QgdXNlZCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCByZWN1cnJpbmcgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2NoZWR1bGVyUHJvdG8uc2NoZWR1bGVQZXJpb2RpY1dpdGhTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSwgcGVyaW9kLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgdmFyIHMgPSBzdGF0ZSwgaWQgPSBzZXRJbnRlcnZhbChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBzID0gYWN0aW9uKHMpO1xyXG4gICAgICAgICAgICB9LCBwZXJpb2QpO1xyXG4gICAgICAgICAgICByZXR1cm4gZGlzcG9zYWJsZUNyZWF0ZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBjbGVhckludGVydmFsKGlkKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogU2NoZWR1bGVzIGFuIGFjdGlvbiB0byBiZSBleGVjdXRlZC4gICAgICAgIFxyXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFjdGlvbiBBY3Rpb24gdG8gZXhlY3V0ZS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RGlzcG9zYWJsZX0gVGhlIGRpc3Bvc2FibGUgb2JqZWN0IHVzZWQgdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2NoZWR1bGVyUHJvdG8uc2NoZWR1bGUgPSBmdW5jdGlvbiAoYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zY2hlZHVsZShhY3Rpb24sIGludm9rZUFjdGlvbik7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogU2NoZWR1bGVzIGFuIGFjdGlvbiB0byBiZSBleGVjdXRlZC4gICAgXHJcbiAgICAgICAgICogQHBhcmFtIHN0YXRlIFN0YXRlIHBhc3NlZCB0byB0aGUgYWN0aW9uIHRvIGJlIGV4ZWN1dGVkLlxyXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFjdGlvbiBBY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXHJcbiAgICAgICAgICogQHJldHVybnMge0Rpc3Bvc2FibGV9IFRoZSBkaXNwb3NhYmxlIG9iamVjdCB1c2VkIHRvIGNhbmNlbCB0aGUgc2NoZWR1bGVkIGFjdGlvbiAoYmVzdCBlZmZvcnQpLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHNjaGVkdWxlclByb3RvLnNjaGVkdWxlV2l0aFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NjaGVkdWxlKHN0YXRlLCBhY3Rpb24pO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNjaGVkdWxlcyBhbiBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQgYWZ0ZXIgdGhlIHNwZWNpZmllZCByZWxhdGl2ZSBkdWUgdGltZS4gICAgICAgXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBleGVjdXRlLlxyXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkdWVUaW1lIFJlbGF0aXZlIHRpbWUgYWZ0ZXIgd2hpY2ggdG8gZXhlY3V0ZSB0aGUgYWN0aW9uLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtEaXNwb3NhYmxlfSBUaGUgZGlzcG9zYWJsZSBvYmplY3QgdXNlZCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCBhY3Rpb24gKGJlc3QgZWZmb3J0KS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBzY2hlZHVsZXJQcm90by5zY2hlZHVsZVdpdGhSZWxhdGl2ZSA9IGZ1bmN0aW9uIChkdWVUaW1lLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NjaGVkdWxlUmVsYXRpdmUoYWN0aW9uLCBkdWVUaW1lLCBpbnZva2VBY3Rpb24pO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNjaGVkdWxlcyBhbiBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQgYWZ0ZXIgZHVlVGltZS4gICAgIFxyXG4gICAgICAgICAqIEBwYXJhbSBzdGF0ZSBTdGF0ZSBwYXNzZWQgdG8gdGhlIGFjdGlvbiB0byBiZSBleGVjdXRlZC5cclxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhY3Rpb24gQWN0aW9uIHRvIGJlIGV4ZWN1dGVkLlxyXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkdWVUaW1lIFJlbGF0aXZlIHRpbWUgYWZ0ZXIgd2hpY2ggdG8gZXhlY3V0ZSB0aGUgYWN0aW9uLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtEaXNwb3NhYmxlfSBUaGUgZGlzcG9zYWJsZSBvYmplY3QgdXNlZCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCBhY3Rpb24gKGJlc3QgZWZmb3J0KS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBzY2hlZHVsZXJQcm90by5zY2hlZHVsZVdpdGhSZWxhdGl2ZUFuZFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlLCBkdWVUaW1lLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NjaGVkdWxlUmVsYXRpdmUoc3RhdGUsIGR1ZVRpbWUsIGFjdGlvbik7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogU2NoZWR1bGVzIGFuIGFjdGlvbiB0byBiZSBleGVjdXRlZCBhdCB0aGUgc3BlY2lmaWVkIGFic29sdXRlIGR1ZSB0aW1lLiAgICBcclxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhY3Rpb24gQWN0aW9uIHRvIGV4ZWN1dGUuXHJcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGR1ZVRpbWUgQWJzb2x1dGUgdGltZSBhdCB3aGljaCB0byBleGVjdXRlIHRoZSBhY3Rpb24uXHJcbiAgICAgICAgICogQHJldHVybnMge0Rpc3Bvc2FibGV9IFRoZSBkaXNwb3NhYmxlIG9iamVjdCB1c2VkIHRvIGNhbmNlbCB0aGUgc2NoZWR1bGVkIGFjdGlvbiAoYmVzdCBlZmZvcnQpLlxyXG4gICAgICAgICAgKi9cclxuICAgICAgICBzY2hlZHVsZXJQcm90by5zY2hlZHVsZVdpdGhBYnNvbHV0ZSA9IGZ1bmN0aW9uIChkdWVUaW1lLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX3NjaGVkdWxlQWJzb2x1dGUoYWN0aW9uLCBkdWVUaW1lLCBpbnZva2VBY3Rpb24pO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNjaGVkdWxlcyBhbiBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQgYXQgZHVlVGltZS4gICAgIFxyXG4gICAgICAgICAqIEBwYXJhbSB7TWl4ZWR9IHN0YXRlIFN0YXRlIHBhc3NlZCB0byB0aGUgYWN0aW9uIHRvIGJlIGV4ZWN1dGVkLlxyXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGFjdGlvbiBBY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9ZHVlVGltZSBBYnNvbHV0ZSB0aW1lIGF0IHdoaWNoIHRvIGV4ZWN1dGUgdGhlIGFjdGlvbi5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RGlzcG9zYWJsZX0gVGhlIGRpc3Bvc2FibGUgb2JqZWN0IHVzZWQgdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2NoZWR1bGVyUHJvdG8uc2NoZWR1bGVXaXRoQWJzb2x1dGVBbmRTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSwgZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zY2hlZHVsZUFic29sdXRlKHN0YXRlLCBkdWVUaW1lLCBhY3Rpb24pO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNjaGVkdWxlcyBhbiBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQgcmVjdXJzaXZlbHkuXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBleGVjdXRlIHJlY3Vyc2l2ZWx5LiBUaGUgcGFyYW1ldGVyIHBhc3NlZCB0byB0aGUgYWN0aW9uIGlzIHVzZWQgdG8gdHJpZ2dlciByZWN1cnNpdmUgc2NoZWR1bGluZyBvZiB0aGUgYWN0aW9uLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtEaXNwb3NhYmxlfSBUaGUgZGlzcG9zYWJsZSBvYmplY3QgdXNlZCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCBhY3Rpb24gKGJlc3QgZWZmb3J0KS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBzY2hlZHVsZXJQcm90by5zY2hlZHVsZVJlY3Vyc2l2ZSA9IGZ1bmN0aW9uIChhY3Rpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2NoZWR1bGVSZWN1cnNpdmVXaXRoU3RhdGUoYWN0aW9uLCBmdW5jdGlvbiAoX2FjdGlvbiwgc2VsZikge1xyXG4gICAgICAgICAgICAgICAgX2FjdGlvbihmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZihfYWN0aW9uKTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTY2hlZHVsZXMgYW4gYWN0aW9uIHRvIGJlIGV4ZWN1dGVkIHJlY3Vyc2l2ZWx5LiAgICAgXHJcbiAgICAgICAgICogQHBhcmFtIHtNaXhlZH0gc3RhdGUgU3RhdGUgcGFzc2VkIHRvIHRoZSBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBleGVjdXRlIHJlY3Vyc2l2ZWx5LiBUaGUgbGFzdCBwYXJhbWV0ZXIgcGFzc2VkIHRvIHRoZSBhY3Rpb24gaXMgdXNlZCB0byB0cmlnZ2VyIHJlY3Vyc2l2ZSBzY2hlZHVsaW5nIG9mIHRoZSBhY3Rpb24sIHBhc3NpbmcgaW4gcmVjdXJzaXZlIGludm9jYXRpb24gc3RhdGUuXHJcbiAgICAgICAgICogQHJldHVybnMge0Rpc3Bvc2FibGV9IFRoZSBkaXNwb3NhYmxlIG9iamVjdCB1c2VkIHRvIGNhbmNlbCB0aGUgc2NoZWR1bGVkIGFjdGlvbiAoYmVzdCBlZmZvcnQpLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHNjaGVkdWxlclByb3RvLnNjaGVkdWxlUmVjdXJzaXZlV2l0aFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2NoZWR1bGVXaXRoU3RhdGUoeyBmaXJzdDogc3RhdGUsIHNlY29uZDogYWN0aW9uIH0sIGZ1bmN0aW9uIChzLCBwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaW52b2tlUmVjSW1tZWRpYXRlKHMsIHApO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTY2hlZHVsZXMgYW4gYWN0aW9uIHRvIGJlIGV4ZWN1dGVkIHJlY3Vyc2l2ZWx5IGFmdGVyIGEgc3BlY2lmaWVkIHJlbGF0aXZlIGR1ZSB0aW1lLiAgICAgXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBleGVjdXRlIHJlY3Vyc2l2ZWx5LiBUaGUgcGFyYW1ldGVyIHBhc3NlZCB0byB0aGUgYWN0aW9uIGlzIHVzZWQgdG8gdHJpZ2dlciByZWN1cnNpdmUgc2NoZWR1bGluZyBvZiB0aGUgYWN0aW9uIGF0IHRoZSBzcGVjaWZpZWQgcmVsYXRpdmUgdGltZS5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn1kdWVUaW1lIFJlbGF0aXZlIHRpbWUgYWZ0ZXIgd2hpY2ggdG8gZXhlY3V0ZSB0aGUgYWN0aW9uIGZvciB0aGUgZmlyc3QgdGltZS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RGlzcG9zYWJsZX0gVGhlIGRpc3Bvc2FibGUgb2JqZWN0IHVzZWQgdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2NoZWR1bGVyUHJvdG8uc2NoZWR1bGVSZWN1cnNpdmVXaXRoUmVsYXRpdmUgPSBmdW5jdGlvbiAoZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNjaGVkdWxlUmVjdXJzaXZlV2l0aFJlbGF0aXZlQW5kU3RhdGUoYWN0aW9uLCBkdWVUaW1lLCBmdW5jdGlvbiAoX2FjdGlvbiwgc2VsZikge1xyXG4gICAgICAgICAgICAgICAgX2FjdGlvbihmdW5jdGlvbiAoZHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmKF9hY3Rpb24sIGR0KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTY2hlZHVsZXMgYW4gYWN0aW9uIHRvIGJlIGV4ZWN1dGVkIHJlY3Vyc2l2ZWx5IGFmdGVyIGEgc3BlY2lmaWVkIHJlbGF0aXZlIGR1ZSB0aW1lLiAgXHJcbiAgICAgICAgICogQHBhcmFtIHtNaXhlZH0gc3RhdGUgU3RhdGUgcGFzc2VkIHRvIHRoZSBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBleGVjdXRlIHJlY3Vyc2l2ZWx5LiBUaGUgbGFzdCBwYXJhbWV0ZXIgcGFzc2VkIHRvIHRoZSBhY3Rpb24gaXMgdXNlZCB0byB0cmlnZ2VyIHJlY3Vyc2l2ZSBzY2hlZHVsaW5nIG9mIHRoZSBhY3Rpb24sIHBhc3NpbmcgaW4gdGhlIHJlY3Vyc2l2ZSBkdWUgdGltZSBhbmQgaW52b2NhdGlvbiBzdGF0ZS5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn1kdWVUaW1lIFJlbGF0aXZlIHRpbWUgYWZ0ZXIgd2hpY2ggdG8gZXhlY3V0ZSB0aGUgYWN0aW9uIGZvciB0aGUgZmlyc3QgdGltZS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RGlzcG9zYWJsZX0gVGhlIGRpc3Bvc2FibGUgb2JqZWN0IHVzZWQgdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2NoZWR1bGVyUHJvdG8uc2NoZWR1bGVSZWN1cnNpdmVXaXRoUmVsYXRpdmVBbmRTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSwgZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zY2hlZHVsZVJlbGF0aXZlKHsgZmlyc3Q6IHN0YXRlLCBzZWNvbmQ6IGFjdGlvbiB9LCBkdWVUaW1lLCBmdW5jdGlvbiAocywgcCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGludm9rZVJlY0RhdGUocywgcCwgJ3NjaGVkdWxlV2l0aFJlbGF0aXZlQW5kU3RhdGUnKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogU2NoZWR1bGVzIGFuIGFjdGlvbiB0byBiZSBleGVjdXRlZCByZWN1cnNpdmVseSBhdCBhIHNwZWNpZmllZCBhYnNvbHV0ZSBkdWUgdGltZS4gICAgXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBleGVjdXRlIHJlY3Vyc2l2ZWx5LiBUaGUgcGFyYW1ldGVyIHBhc3NlZCB0byB0aGUgYWN0aW9uIGlzIHVzZWQgdG8gdHJpZ2dlciByZWN1cnNpdmUgc2NoZWR1bGluZyBvZiB0aGUgYWN0aW9uIGF0IHRoZSBzcGVjaWZpZWQgYWJzb2x1dGUgdGltZS5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn1kdWVUaW1lIEFic29sdXRlIHRpbWUgYXQgd2hpY2ggdG8gZXhlY3V0ZSB0aGUgYWN0aW9uIGZvciB0aGUgZmlyc3QgdGltZS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RGlzcG9zYWJsZX0gVGhlIGRpc3Bvc2FibGUgb2JqZWN0IHVzZWQgdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2NoZWR1bGVyUHJvdG8uc2NoZWR1bGVSZWN1cnNpdmVXaXRoQWJzb2x1dGUgPSBmdW5jdGlvbiAoZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNjaGVkdWxlUmVjdXJzaXZlV2l0aEFic29sdXRlQW5kU3RhdGUoYWN0aW9uLCBkdWVUaW1lLCBmdW5jdGlvbiAoX2FjdGlvbiwgc2VsZikge1xyXG4gICAgICAgICAgICAgICAgX2FjdGlvbihmdW5jdGlvbiAoZHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmKF9hY3Rpb24sIGR0KTtcclxuICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTY2hlZHVsZXMgYW4gYWN0aW9uIHRvIGJlIGV4ZWN1dGVkIHJlY3Vyc2l2ZWx5IGF0IGEgc3BlY2lmaWVkIGFic29sdXRlIGR1ZSB0aW1lLiAgICAgXHJcbiAgICAgICAgICogQHBhcmFtIHtNaXhlZH0gc3RhdGUgU3RhdGUgcGFzc2VkIHRvIHRoZSBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBleGVjdXRlIHJlY3Vyc2l2ZWx5LiBUaGUgbGFzdCBwYXJhbWV0ZXIgcGFzc2VkIHRvIHRoZSBhY3Rpb24gaXMgdXNlZCB0byB0cmlnZ2VyIHJlY3Vyc2l2ZSBzY2hlZHVsaW5nIG9mIHRoZSBhY3Rpb24sIHBhc3NpbmcgaW4gdGhlIHJlY3Vyc2l2ZSBkdWUgdGltZSBhbmQgaW52b2NhdGlvbiBzdGF0ZS5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn1kdWVUaW1lIEFic29sdXRlIHRpbWUgYXQgd2hpY2ggdG8gZXhlY3V0ZSB0aGUgYWN0aW9uIGZvciB0aGUgZmlyc3QgdGltZS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RGlzcG9zYWJsZX0gVGhlIGRpc3Bvc2FibGUgb2JqZWN0IHVzZWQgdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgc2NoZWR1bGVyUHJvdG8uc2NoZWR1bGVSZWN1cnNpdmVXaXRoQWJzb2x1dGVBbmRTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSwgZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zY2hlZHVsZUFic29sdXRlKHsgZmlyc3Q6IHN0YXRlLCBzZWNvbmQ6IGFjdGlvbiB9LCBkdWVUaW1lLCBmdW5jdGlvbiAocywgcCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGludm9rZVJlY0RhdGUocywgcCwgJ3NjaGVkdWxlV2l0aEFic29sdXRlQW5kU3RhdGUnKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqIEdldHMgdGhlIGN1cnJlbnQgdGltZSBhY2NvcmRpbmcgdG8gdGhlIGxvY2FsIG1hY2hpbmUncyBzeXN0ZW0gY2xvY2suICovXHJcbiAgICAgICAgU2NoZWR1bGVyLm5vdyA9IGRlZmF1bHROb3c7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE5vcm1hbGl6ZXMgdGhlIHNwZWNpZmllZCBUaW1lU3BhbiB2YWx1ZSB0byBhIHBvc2l0aXZlIHZhbHVlLlxyXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aW1lU3BhbiBUaGUgdGltZSBzcGFuIHZhbHVlIHRvIG5vcm1hbGl6ZS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgc3BlY2lmaWVkIFRpbWVTcGFuIHZhbHVlIGlmIGl0IGlzIHplcm8gb3IgcG9zaXRpdmU7IG90aGVyd2lzZSwgMFxyXG4gICAgICAgICAqLyAgIFxyXG4gICAgICAgIFNjaGVkdWxlci5ub3JtYWxpemUgPSBmdW5jdGlvbiAodGltZVNwYW4pIHtcclxuICAgICAgICAgICAgaWYgKHRpbWVTcGFuIDwgMCkge1xyXG4gICAgICAgICAgICAgICAgdGltZVNwYW4gPSAwO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0aW1lU3BhbjtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gU2NoZWR1bGVyO1xyXG4gICAgfSgpKTtcclxuXHJcbiAgICB2YXIgbm9ybWFsaXplVGltZSA9IFNjaGVkdWxlci5ub3JtYWxpemU7XHJcbiAgICBcclxuICAgIHZhciBTY2hlZHVsZVBlcmlvZGljUmVjdXJzaXZlID0gUnguaW50ZXJuYWxzLlNjaGVkdWxlUGVyaW9kaWNSZWN1cnNpdmUgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIHRpY2soY29tbWFuZCwgcmVjdXJzZSkge1xyXG4gICAgICAgICAgICByZWN1cnNlKDAsIHRoaXMuX3BlcmlvZCk7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IHRoaXMuX2FjdGlvbih0aGlzLl9zdGF0ZSk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX2NhbmNlbC5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBTY2hlZHVsZVBlcmlvZGljUmVjdXJzaXZlKHNjaGVkdWxlciwgc3RhdGUsIHBlcmlvZCwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlciA9IHNjaGVkdWxlcjtcclxuICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSBzdGF0ZTtcclxuICAgICAgICAgICAgdGhpcy5fcGVyaW9kID0gcGVyaW9kO1xyXG4gICAgICAgICAgICB0aGlzLl9hY3Rpb24gPSBhY3Rpb247XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBTY2hlZHVsZVBlcmlvZGljUmVjdXJzaXZlLnByb3RvdHlwZS5zdGFydCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIGQgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgdGhpcy5fY2FuY2VsID0gZDtcclxuICAgICAgICAgICAgZC5zZXREaXNwb3NhYmxlKHRoaXMuX3NjaGVkdWxlci5zY2hlZHVsZVJlY3Vyc2l2ZVdpdGhSZWxhdGl2ZUFuZFN0YXRlKDAsIHRoaXMuX3BlcmlvZCwgdGljay5iaW5kKHRoaXMpKSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gZDtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gU2NoZWR1bGVQZXJpb2RpY1JlY3Vyc2l2ZTtcclxuICAgIH0oKSk7XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldHMgYSBzY2hlZHVsZXIgdGhhdCBzY2hlZHVsZXMgd29yayBpbW1lZGlhdGVseSBvbiB0aGUgY3VycmVudCB0aHJlYWQuXHJcbiAgICovICAgIFxyXG4gIHZhciBpbW1lZGlhdGVTY2hlZHVsZXIgPSBTY2hlZHVsZXIuaW1tZWRpYXRlID0gKGZ1bmN0aW9uICgpIHtcclxuXHJcbiAgICBmdW5jdGlvbiBzY2hlZHVsZU5vdyhzdGF0ZSwgYWN0aW9uKSB7IHJldHVybiBhY3Rpb24odGhpcywgc3RhdGUpOyB9XHJcblxyXG4gICAgZnVuY3Rpb24gc2NoZWR1bGVSZWxhdGl2ZShzdGF0ZSwgZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgIHZhciBkdCA9IG5vcm1hbGl6ZVRpbWUoZHQpO1xyXG4gICAgICB3aGlsZSAoZHQgLSB0aGlzLm5vdygpID4gMCkgeyB9XHJcbiAgICAgIHJldHVybiBhY3Rpb24odGhpcywgc3RhdGUpO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIHNjaGVkdWxlQWJzb2x1dGUoc3RhdGUsIGR1ZVRpbWUsIGFjdGlvbikge1xyXG4gICAgICByZXR1cm4gdGhpcy5zY2hlZHVsZVdpdGhSZWxhdGl2ZUFuZFN0YXRlKHN0YXRlLCBkdWVUaW1lIC0gdGhpcy5ub3coKSwgYWN0aW9uKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbmV3IFNjaGVkdWxlcihkZWZhdWx0Tm93LCBzY2hlZHVsZU5vdywgc2NoZWR1bGVSZWxhdGl2ZSwgc2NoZWR1bGVBYnNvbHV0ZSk7XHJcbiAgfSgpKTtcclxuXHJcbiAgICAvKiogXHJcbiAgICAgKiBHZXRzIGEgc2NoZWR1bGVyIHRoYXQgc2NoZWR1bGVzIHdvcmsgYXMgc29vbiBhcyBwb3NzaWJsZSBvbiB0aGUgY3VycmVudCB0aHJlYWQuXHJcbiAgICAgKi9cclxuICAgIHZhciBjdXJyZW50VGhyZWFkU2NoZWR1bGVyID0gU2NoZWR1bGVyLmN1cnJlbnRUaHJlYWQgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBxdWV1ZTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gcnVuVHJhbXBvbGluZSAocSkge1xyXG4gICAgICAgICAgICB2YXIgaXRlbTtcclxuICAgICAgICAgICAgd2hpbGUgKHEubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgaXRlbSA9IHEuZGVxdWV1ZSgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFpdGVtLmlzQ2FuY2VsbGVkKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAvLyBOb3RlLCBkbyBub3Qgc2NoZWR1bGUgYmxvY2tpbmcgd29yayFcclxuICAgICAgICAgICAgICAgICAgICB3aGlsZSAoaXRlbS5kdWVUaW1lIC0gU2NoZWR1bGVyLm5vdygpID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWl0ZW0uaXNDYW5jZWxsZWQoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpdGVtLmludm9rZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSAgICAgICAgICAgIFxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gc2NoZWR1bGVOb3coc3RhdGUsIGFjdGlvbikge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zY2hlZHVsZVdpdGhSZWxhdGl2ZUFuZFN0YXRlKHN0YXRlLCAwLCBhY3Rpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gc2NoZWR1bGVSZWxhdGl2ZShzdGF0ZSwgZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHZhciBkdCA9IHRoaXMubm93KCkgKyBTY2hlZHVsZXIubm9ybWFsaXplKGR1ZVRpbWUpLFxyXG4gICAgICAgICAgICAgICAgICAgIHNpID0gbmV3IFNjaGVkdWxlZEl0ZW0odGhpcywgc3RhdGUsIGFjdGlvbiwgZHQpLFxyXG4gICAgICAgICAgICAgICAgICAgIHQ7XHJcbiAgICAgICAgICAgIGlmICghcXVldWUpIHtcclxuICAgICAgICAgICAgICAgIHF1ZXVlID0gbmV3IFByaW9yaXR5UXVldWUoNCk7XHJcbiAgICAgICAgICAgICAgICBxdWV1ZS5lbnF1ZXVlKHNpKTtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcnVuVHJhbXBvbGluZShxdWV1ZSk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7IFxyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IGU7XHJcbiAgICAgICAgICAgICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgICAgICAgICAgICAgIHF1ZXVlID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHF1ZXVlLmVucXVldWUoc2kpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBzaS5kaXNwb3NhYmxlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gc2NoZWR1bGVBYnNvbHV0ZShzdGF0ZSwgZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNjaGVkdWxlV2l0aFJlbGF0aXZlQW5kU3RhdGUoc3RhdGUsIGR1ZVRpbWUgLSB0aGlzLm5vdygpLCBhY3Rpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIGN1cnJlbnRTY2hlZHVsZXIgPSBuZXcgU2NoZWR1bGVyKGRlZmF1bHROb3csIHNjaGVkdWxlTm93LCBzY2hlZHVsZVJlbGF0aXZlLCBzY2hlZHVsZUFic29sdXRlKTtcclxuICAgICAgICBjdXJyZW50U2NoZWR1bGVyLnNjaGVkdWxlUmVxdWlyZWQgPSBmdW5jdGlvbiAoKSB7IHJldHVybiBxdWV1ZSA9PT0gbnVsbDsgfTtcclxuICAgICAgICBjdXJyZW50U2NoZWR1bGVyLmVuc3VyZVRyYW1wb2xpbmUgPSBmdW5jdGlvbiAoYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIGlmIChxdWV1ZSA9PT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2NoZWR1bGUoYWN0aW9uKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhY3Rpb24oKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiBjdXJyZW50U2NoZWR1bGVyO1xyXG4gICAgfSgpKTtcclxuXHJcbiAgXHJcbiAgdmFyIHNjaGVkdWxlTWV0aG9kLCBjbGVhck1ldGhvZCA9IG5vb3A7XHJcbiAgKGZ1bmN0aW9uICgpIHtcclxuXHJcbiAgICAgIHZhciByZU5hdGl2ZSA9IFJlZ0V4cCgnXicgK1xyXG4gICAgICAgIFN0cmluZyh0b1N0cmluZylcclxuICAgICAgICAgIC5yZXBsYWNlKC9bLiorP14ke30oKXxbXFxdXFxcXF0vZywgJ1xcXFwkJicpXHJcbiAgICAgICAgICAucmVwbGFjZSgvdG9TdHJpbmd8IGZvciBbXlxcXV0rL2csICcuKj8nKSArICckJ1xyXG4gICAgICApO1xyXG5cclxuICAgICAgdmFyIHNldEltbWVkaWF0ZSA9IHR5cGVvZiAoc2V0SW1tZWRpYXRlID0gZnJlZUdsb2JhbCAmJiBtb2R1bGVFeHBvcnRzICYmIGZyZWVHbG9iYWwuc2V0SW1tZWRpYXRlKSA9PSAnZnVuY3Rpb24nICYmXHJcbiAgICAgICAgIXJlTmF0aXZlLnRlc3Qoc2V0SW1tZWRpYXRlKSAmJiBzZXRJbW1lZGlhdGUsXHJcbiAgICAgICAgY2xlYXJJbW1lZGlhdGUgPSB0eXBlb2YgKGNsZWFySW1tZWRpYXRlID0gZnJlZUdsb2JhbCAmJiBtb2R1bGVFeHBvcnRzICYmIGZyZWVHbG9iYWwuY2xlYXJJbW1lZGlhdGUpID09ICdmdW5jdGlvbicgJiZcclxuICAgICAgICAhcmVOYXRpdmUudGVzdChjbGVhckltbWVkaWF0ZSkgJiYgY2xlYXJJbW1lZGlhdGU7XHJcblxyXG4gICAgICBmdW5jdGlvbiBwb3N0TWVzc2FnZVN1cHBvcnRlZCAoKSB7XHJcbiAgICAgICAgLy8gRW5zdXJlIG5vdCBpbiBhIHdvcmtlclxyXG4gICAgICAgIGlmICghcm9vdC5wb3N0TWVzc2FnZSB8fCByb290LmltcG9ydFNjcmlwdHMpIHsgcmV0dXJuIGZhbHNlOyB9XHJcbiAgICAgICAgdmFyIGlzQXN5bmMgPSBmYWxzZSwgXHJcbiAgICAgICAgICAgIG9sZEhhbmRsZXIgPSByb290Lm9ubWVzc2FnZTtcclxuICAgICAgICAvLyBUZXN0IGZvciBhc3luY1xyXG4gICAgICAgIHJvb3Qub25tZXNzYWdlID0gZnVuY3Rpb24gKCkgeyBpc0FzeW5jID0gdHJ1ZTsgfTtcclxuICAgICAgICByb290LnBvc3RNZXNzYWdlKCcnLCcqJyk7XHJcbiAgICAgICAgcm9vdC5vbm1lc3NhZ2UgPSBvbGRIYW5kbGVyO1xyXG5cclxuICAgICAgICByZXR1cm4gaXNBc3luYztcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gVXNlIGluIG9yZGVyLCBuZXh0VGljaywgc2V0SW1tZWRpYXRlLCBwb3N0TWVzc2FnZSwgTWVzc2FnZUNoYW5uZWwsIHNjcmlwdCByZWFkeXN0YXRlY2hhbmdlZCwgc2V0VGltZW91dFxyXG4gICAgICBpZiAodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHt9LnRvU3RyaW5nLmNhbGwocHJvY2VzcykgPT09ICdbb2JqZWN0IHByb2Nlc3NdJykge1xyXG4gICAgICAgIHNjaGVkdWxlTWV0aG9kID0gcHJvY2Vzcy5uZXh0VGljaztcclxuICAgICAgfSBlbHNlIGlmICh0eXBlb2Ygc2V0SW1tZWRpYXRlID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgc2NoZWR1bGVNZXRob2QgPSBzZXRJbW1lZGlhdGU7XHJcbiAgICAgICAgY2xlYXJNZXRob2QgPSBjbGVhckltbWVkaWF0ZTtcclxuICAgICAgfSBlbHNlIGlmIChwb3N0TWVzc2FnZVN1cHBvcnRlZCgpKSB7XHJcbiAgICAgICAgICB2YXIgTVNHX1BSRUZJWCA9ICdtcy5yeC5zY2hlZHVsZScgKyBNYXRoLnJhbmRvbSgpLFxyXG4gICAgICAgICAgICB0YXNrcyA9IHt9LFxyXG4gICAgICAgICAgICB0YXNrSWQgPSAwO1xyXG5cclxuICAgICAgICAgIGZ1bmN0aW9uIG9uR2xvYmFsUG9zdE1lc3NhZ2UoZXZlbnQpIHtcclxuICAgICAgICAgICAgLy8gT25seSBpZiB3ZSdyZSBhIG1hdGNoIHRvIGF2b2lkIGFueSBvdGhlciBnbG9iYWwgZXZlbnRzXHJcbiAgICAgICAgICAgIGlmICh0eXBlb2YgZXZlbnQuZGF0YSA9PT0gJ3N0cmluZycgJiYgZXZlbnQuZGF0YS5zdWJzdHJpbmcoMCwgTVNHX1BSRUZJWC5sZW5ndGgpID09PSBNU0dfUFJFRklYKSB7XHJcbiAgICAgICAgICAgICAgdmFyIGhhbmRsZUlkID0gZXZlbnQuZGF0YS5zdWJzdHJpbmcoTVNHX1BSRUZJWC5sZW5ndGgpLFxyXG4gICAgICAgICAgICAgICAgYWN0aW9uID0gdGFza3NbaGFuZGxlSWRdO1xyXG4gICAgICAgICAgICAgIGFjdGlvbigpO1xyXG4gICAgICAgICAgICAgIGRlbGV0ZSB0YXNrc1toYW5kbGVJZF07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBpZiAocm9vdC5hZGRFdmVudExpc3RlbmVyKSB7XHJcbiAgICAgICAgICAgIHJvb3QuYWRkRXZlbnRMaXN0ZW5lcignbWVzc2FnZScsIG9uR2xvYmFsUG9zdE1lc3NhZ2UsIGZhbHNlKTtcclxuICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHJvb3QuYXR0YWNoRXZlbnQoJ29ubWVzc2FnZScsIG9uR2xvYmFsUG9zdE1lc3NhZ2UsIGZhbHNlKTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBzY2hlZHVsZU1ldGhvZCA9IGZ1bmN0aW9uIChhY3Rpb24pIHtcclxuICAgICAgICAgICAgdmFyIGN1cnJlbnRJZCA9IHRhc2tJZCsrO1xyXG4gICAgICAgICAgICB0YXNrc1tjdXJyZW50SWRdID0gYWN0aW9uO1xyXG4gICAgICAgICAgICByb290LnBvc3RNZXNzYWdlKE1TR19QUkVGSVggKyBjdXJyZW50SWQsICcqJyk7XHJcbiAgICAgICAgICB9O1xyXG4gICAgICB9IGVsc2UgaWYgKCEhcm9vdC5NZXNzYWdlQ2hhbm5lbCkge1xyXG4gICAgICAgICAgdmFyIGNoYW5uZWwgPSBuZXcgcm9vdC5NZXNzYWdlQ2hhbm5lbCgpLFxyXG4gICAgICAgICAgICBjaGFubmVsVGFza3MgPSB7fSxcclxuICAgICAgICAgICAgY2hhbm5lbFRhc2tJZCA9IDA7XHJcblxyXG4gICAgICAgICAgY2hhbm5lbC5wb3J0MS5vbm1lc3NhZ2UgPSBmdW5jdGlvbiAoZXZlbnQpIHtcclxuICAgICAgICAgICAgdmFyIGlkID0gZXZlbnQuZGF0YSxcclxuICAgICAgICAgICAgICBhY3Rpb24gPSBjaGFubmVsVGFza3NbaWRdO1xyXG4gICAgICAgICAgICBhY3Rpb24oKTtcclxuICAgICAgICAgICAgZGVsZXRlIGNoYW5uZWxUYXNrc1tpZF07XHJcbiAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgIHNjaGVkdWxlTWV0aG9kID0gZnVuY3Rpb24gKGFjdGlvbikge1xyXG4gICAgICAgICAgICB2YXIgaWQgPSBjaGFubmVsVGFza0lkKys7XHJcbiAgICAgICAgICAgIGNoYW5uZWxUYXNrc1tpZF0gPSBhY3Rpb247XHJcbiAgICAgICAgICAgIGNoYW5uZWwucG9ydDIucG9zdE1lc3NhZ2UoaWQpOyAgICAgXHJcbiAgICAgICAgICB9O1xyXG4gICAgICB9IGVsc2UgaWYgKCdkb2N1bWVudCcgaW4gcm9vdCAmJiAnb25yZWFkeXN0YXRlY2hhbmdlJyBpbiByb290LmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoJ3NjcmlwdCcpKSB7XHJcbiAgICAgICAgICBcclxuICAgICAgICBzY2hlZHVsZU1ldGhvZCA9IGZ1bmN0aW9uIChhY3Rpb24pIHtcclxuICAgICAgICAgIHZhciBzY3JpcHRFbGVtZW50ID0gcm9vdC5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCdzY3JpcHQnKTtcclxuICAgICAgICAgIHNjcmlwdEVsZW1lbnQub25yZWFkeXN0YXRlY2hhbmdlID0gZnVuY3Rpb24gKCkgeyBcclxuICAgICAgICAgICAgYWN0aW9uKCk7XHJcbiAgICAgICAgICAgIHNjcmlwdEVsZW1lbnQub25yZWFkeXN0YXRlY2hhbmdlID0gbnVsbDtcclxuICAgICAgICAgICAgc2NyaXB0RWxlbWVudC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHNjcmlwdEVsZW1lbnQpO1xyXG4gICAgICAgICAgICBzY3JpcHRFbGVtZW50ID0gbnVsbDsgIFxyXG4gICAgICAgICAgfTtcclxuICAgICAgICAgIHJvb3QuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmFwcGVuZENoaWxkKHNjcmlwdEVsZW1lbnQpOyAgXHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgc2NoZWR1bGVNZXRob2QgPSBmdW5jdGlvbiAoYWN0aW9uKSB7IHJldHVybiBzZXRUaW1lb3V0KGFjdGlvbiwgMCk7IH07XHJcbiAgICAgICAgY2xlYXJNZXRob2QgPSBjbGVhclRpbWVvdXQ7XHJcbiAgICAgIH1cclxuICB9KCkpO1xyXG5cclxuICAvKiogXHJcbiAgICogR2V0cyBhIHNjaGVkdWxlciB0aGF0IHNjaGVkdWxlcyB3b3JrIHZpYSBhIHRpbWVkIGNhbGxiYWNrIGJhc2VkIHVwb24gcGxhdGZvcm0uXHJcbiAgICovXHJcbiAgdmFyIHRpbWVvdXRTY2hlZHVsZXIgPSBTY2hlZHVsZXIudGltZW91dCA9IChmdW5jdGlvbiAoKSB7XHJcblxyXG4gICAgZnVuY3Rpb24gc2NoZWR1bGVOb3coc3RhdGUsIGFjdGlvbikge1xyXG4gICAgICAgIHZhciBzY2hlZHVsZXIgPSB0aGlzLFxyXG4gICAgICAgICAgZGlzcG9zYWJsZSA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpO1xyXG4gICAgICAgIHZhciBpZCA9IHNjaGVkdWxlTWV0aG9kKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIGlmICghZGlzcG9zYWJsZS5pc0Rpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgIGRpc3Bvc2FibGUuc2V0RGlzcG9zYWJsZShhY3Rpb24oc2NoZWR1bGVyLCBzdGF0ZSkpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIHJldHVybiBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZShkaXNwb3NhYmxlLCBkaXNwb3NhYmxlQ3JlYXRlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIGNsZWFyTWV0aG9kKGlkKTtcclxuICAgICAgICB9KSk7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gc2NoZWR1bGVSZWxhdGl2ZShzdGF0ZSwgZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgdmFyIHNjaGVkdWxlciA9IHRoaXMsXHJcbiAgICAgICAgICBkdCA9IFNjaGVkdWxlci5ub3JtYWxpemUoZHVlVGltZSk7XHJcbiAgICAgICAgaWYgKGR0ID09PSAwKSB7XHJcbiAgICAgICAgICByZXR1cm4gc2NoZWR1bGVyLnNjaGVkdWxlV2l0aFN0YXRlKHN0YXRlLCBhY3Rpb24pO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgZGlzcG9zYWJsZSA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpO1xyXG4gICAgICAgIHZhciBpZCA9IHNldFRpbWVvdXQoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgaWYgKCFkaXNwb3NhYmxlLmlzRGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgZGlzcG9zYWJsZS5zZXREaXNwb3NhYmxlKGFjdGlvbihzY2hlZHVsZXIsIHN0YXRlKSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSwgZHQpO1xyXG4gICAgICAgIHJldHVybiBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZShkaXNwb3NhYmxlLCBkaXNwb3NhYmxlQ3JlYXRlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIGNsZWFyVGltZW91dChpZCk7XHJcbiAgICAgICAgfSkpO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIHNjaGVkdWxlQWJzb2x1dGUoc3RhdGUsIGR1ZVRpbWUsIGFjdGlvbikge1xyXG4gICAgICByZXR1cm4gdGhpcy5zY2hlZHVsZVdpdGhSZWxhdGl2ZUFuZFN0YXRlKHN0YXRlLCBkdWVUaW1lIC0gdGhpcy5ub3coKSwgYWN0aW9uKTtcclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbmV3IFNjaGVkdWxlcihkZWZhdWx0Tm93LCBzY2hlZHVsZU5vdywgc2NoZWR1bGVSZWxhdGl2ZSwgc2NoZWR1bGVBYnNvbHV0ZSk7XHJcbiAgfSkoKTtcclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi9cclxuICAgIHZhciBDYXRjaFNjaGVkdWxlciA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGxvY2FsTm93KCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc2NoZWR1bGVyLm5vdygpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gc2NoZWR1bGVOb3coc3RhdGUsIGFjdGlvbikge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc2NoZWR1bGVyLnNjaGVkdWxlV2l0aFN0YXRlKHN0YXRlLCB0aGlzLl93cmFwKGFjdGlvbikpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gc2NoZWR1bGVSZWxhdGl2ZShzdGF0ZSwgZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9zY2hlZHVsZXIuc2NoZWR1bGVXaXRoUmVsYXRpdmVBbmRTdGF0ZShzdGF0ZSwgZHVlVGltZSwgdGhpcy5fd3JhcChhY3Rpb24pKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHNjaGVkdWxlQWJzb2x1dGUoc3RhdGUsIGR1ZVRpbWUsIGFjdGlvbikge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fc2NoZWR1bGVyLnNjaGVkdWxlV2l0aEFic29sdXRlQW5kU3RhdGUoc3RhdGUsIGR1ZVRpbWUsIHRoaXMuX3dyYXAoYWN0aW9uKSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpbmhlcml0cyhDYXRjaFNjaGVkdWxlciwgX3N1cGVyKTtcclxuXHJcbiAgICAgICAgLyoqIEBwcml2YXRlICovXHJcbiAgICAgICAgZnVuY3Rpb24gQ2F0Y2hTY2hlZHVsZXIoc2NoZWR1bGVyLCBoYW5kbGVyKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX3NjaGVkdWxlciA9IHNjaGVkdWxlcjtcclxuICAgICAgICAgICAgdGhpcy5faGFuZGxlciA9IGhhbmRsZXI7XHJcbiAgICAgICAgICAgIHRoaXMuX3JlY3Vyc2l2ZU9yaWdpbmFsID0gbnVsbDtcclxuICAgICAgICAgICAgdGhpcy5fcmVjdXJzaXZlV3JhcHBlciA9IG51bGw7XHJcbiAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMsIGxvY2FsTm93LCBzY2hlZHVsZU5vdywgc2NoZWR1bGVSZWxhdGl2ZSwgc2NoZWR1bGVBYnNvbHV0ZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKiogQHByaXZhdGUgKi9cclxuICAgICAgICBDYXRjaFNjaGVkdWxlci5wcm90b3R5cGUuX2Nsb25lID0gZnVuY3Rpb24gKHNjaGVkdWxlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IENhdGNoU2NoZWR1bGVyKHNjaGVkdWxlciwgdGhpcy5faGFuZGxlcik7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqIEBwcml2YXRlICovXHJcbiAgICAgICAgQ2F0Y2hTY2hlZHVsZXIucHJvdG90eXBlLl93cmFwID0gZnVuY3Rpb24gKGFjdGlvbikge1xyXG4gICAgICAgICAgICB2YXIgcGFyZW50ID0gdGhpcztcclxuICAgICAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChzZWxmLCBzdGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9uKHBhcmVudC5fZ2V0UmVjdXJzaXZlV3JhcHBlcihzZWxmKSwgc3RhdGUpO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghcGFyZW50Ll9oYW5kbGVyKGUpKSB7IHRocm93IGU7IH1cclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlzcG9zYWJsZUVtcHR5O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgICAgIENhdGNoU2NoZWR1bGVyLnByb3RvdHlwZS5fZ2V0UmVjdXJzaXZlV3JhcHBlciA9IGZ1bmN0aW9uIChzY2hlZHVsZXIpIHtcclxuICAgICAgICAgICAgaWYgKHRoaXMuX3JlY3Vyc2l2ZU9yaWdpbmFsICE9PSBzY2hlZHVsZXIpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3JlY3Vyc2l2ZU9yaWdpbmFsID0gc2NoZWR1bGVyO1xyXG4gICAgICAgICAgICAgICAgdmFyIHdyYXBwZXIgPSB0aGlzLl9jbG9uZShzY2hlZHVsZXIpO1xyXG4gICAgICAgICAgICAgICAgd3JhcHBlci5fcmVjdXJzaXZlT3JpZ2luYWwgPSBzY2hlZHVsZXI7XHJcbiAgICAgICAgICAgICAgICB3cmFwcGVyLl9yZWN1cnNpdmVXcmFwcGVyID0gd3JhcHBlcjtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3JlY3Vyc2l2ZVdyYXBwZXIgPSB3cmFwcGVyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9yZWN1cnNpdmVXcmFwcGVyO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgICAgIENhdGNoU2NoZWR1bGVyLnByb3RvdHlwZS5zY2hlZHVsZVBlcmlvZGljV2l0aFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlLCBwZXJpb2QsIGFjdGlvbikge1xyXG4gICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXMsIGZhaWxlZCA9IGZhbHNlLCBkID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCk7XHJcblxyXG4gICAgICAgICAgICBkLnNldERpc3Bvc2FibGUodGhpcy5fc2NoZWR1bGVyLnNjaGVkdWxlUGVyaW9kaWNXaXRoU3RhdGUoc3RhdGUsIHBlcmlvZCwgZnVuY3Rpb24gKHN0YXRlMSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGZhaWxlZCkgeyByZXR1cm4gbnVsbDsgfVxyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9uKHN0YXRlMSk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZmFpbGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoIXNlbGYuX2hhbmRsZXIoZSkpIHsgdGhyb3cgZTsgfVxyXG4gICAgICAgICAgICAgICAgICAgIGQuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBudWxsO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gZDtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gQ2F0Y2hTY2hlZHVsZXI7XHJcbiAgICB9KFNjaGVkdWxlcikpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFJlcHJlc2VudHMgYSBub3RpZmljYXRpb24gdG8gYW4gb2JzZXJ2ZXIuXHJcbiAgICAgKi9cclxuICAgIHZhciBOb3RpZmljYXRpb24gPSBSeC5Ob3RpZmljYXRpb24gPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGZ1bmN0aW9uIE5vdGlmaWNhdGlvbihraW5kLCBoYXNWYWx1ZSkgeyBcclxuICAgICAgICAgICAgdGhpcy5oYXNWYWx1ZSA9IGhhc1ZhbHVlID09IG51bGwgPyBmYWxzZSA6IGhhc1ZhbHVlO1xyXG4gICAgICAgICAgICB0aGlzLmtpbmQgPSBraW5kO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIE5vdGlmaWNhdGlvblByb3RvdHlwZSA9IE5vdGlmaWNhdGlvbi5wcm90b3R5cGU7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEludm9rZXMgdGhlIGRlbGVnYXRlIGNvcnJlc3BvbmRpbmcgdG8gdGhlIG5vdGlmaWNhdGlvbiBvciB0aGUgb2JzZXJ2ZXIncyBtZXRob2QgY29ycmVzcG9uZGluZyB0byB0aGUgbm90aWZpY2F0aW9uIGFuZCByZXR1cm5zIHRoZSBwcm9kdWNlZCByZXN1bHQuXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQG1lbWJlck9mIE5vdGlmaWNhdGlvblxyXG4gICAgICAgICAqIEBwYXJhbSB7QW55fSBvYnNlcnZlck9yT25OZXh0IERlbGVnYXRlIHRvIGludm9rZSBmb3IgYW4gT25OZXh0IG5vdGlmaWNhdGlvbiBvciBPYnNlcnZlciB0byBpbnZva2UgdGhlIG5vdGlmaWNhdGlvbiBvbi4uXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gb25FcnJvciBEZWxlZ2F0ZSB0byBpbnZva2UgZm9yIGFuIE9uRXJyb3Igbm90aWZpY2F0aW9uLlxyXG4gICAgICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IG9uQ29tcGxldGVkIERlbGVnYXRlIHRvIGludm9rZSBmb3IgYW4gT25Db21wbGV0ZWQgbm90aWZpY2F0aW9uLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtBbnl9IFJlc3VsdCBwcm9kdWNlZCBieSB0aGUgb2JzZXJ2YXRpb24uXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgTm90aWZpY2F0aW9uUHJvdG90eXBlLmFjY2VwdCA9IGZ1bmN0aW9uIChvYnNlcnZlck9yT25OZXh0LCBvbkVycm9yLCBvbkNvbXBsZXRlZCkge1xyXG4gICAgICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSAmJiB0eXBlb2Ygb2JzZXJ2ZXJPck9uTmV4dCA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9hY2NlcHRPYnNlcnZhYmxlKG9ic2VydmVyT3JPbk5leHQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLl9hY2NlcHQob2JzZXJ2ZXJPck9uTmV4dCwgb25FcnJvciwgb25Db21wbGV0ZWQpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFJldHVybnMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aXRoIGEgc2luZ2xlIG5vdGlmaWNhdGlvbi5cclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAbWVtYmVyT2YgTm90aWZpY2F0aW9uXHJcbiAgICAgICAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtzY2hlZHVsZXJdIFNjaGVkdWxlciB0byBzZW5kIG91dCB0aGUgbm90aWZpY2F0aW9uIGNhbGxzIG9uLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBUaGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHN1cmZhY2VzIHRoZSBiZWhhdmlvciBvZiB0aGUgbm90aWZpY2F0aW9uIHVwb24gc3Vic2NyaXB0aW9uLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIE5vdGlmaWNhdGlvblByb3RvdHlwZS50b09ic2VydmFibGUgPSBmdW5jdGlvbiAoc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgICAgIHZhciBub3RpZmljYXRpb24gPSB0aGlzO1xyXG4gICAgICAgICAgICBzY2hlZHVsZXIgfHwgKHNjaGVkdWxlciA9IGltbWVkaWF0ZVNjaGVkdWxlcik7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzY2hlZHVsZXIuc2NoZWR1bGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbi5fYWNjZXB0T2JzZXJ2YWJsZShvYnNlcnZlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5vdGlmaWNhdGlvbi5raW5kID09PSAnTicpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgcmV0dXJuIE5vdGlmaWNhdGlvbjtcclxuICAgIH0pKCk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYW4gT25OZXh0IG5vdGlmaWNhdGlvbiB0byBhbiBvYnNlcnZlci5cclxuICAgICAqIEBwYXJhbSB7QW55fSB2YWx1ZSBUaGUgdmFsdWUgY29udGFpbmVkIGluIHRoZSBub3RpZmljYXRpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7Tm90aWZpY2F0aW9ufSBUaGUgT25OZXh0IG5vdGlmaWNhdGlvbiBjb250YWluaW5nIHRoZSB2YWx1ZS5cclxuICAgICAqL1xyXG4gICAgdmFyIG5vdGlmaWNhdGlvbkNyZWF0ZU9uTmV4dCA9IE5vdGlmaWNhdGlvbi5jcmVhdGVPbk5leHQgPSAoZnVuY3Rpb24gKCkge1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBfYWNjZXB0IChvbk5leHQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG9uTmV4dCh0aGlzLnZhbHVlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIF9hY2NlcHRPYnNlcnZhYmxlKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBvYnNlcnZlci5vbk5leHQodGhpcy52YWx1ZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiB0b1N0cmluZyAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiAnT25OZXh0KCcgKyB0aGlzLnZhbHVlICsgJyknO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgICB2YXIgbm90aWZpY2F0aW9uID0gbmV3IE5vdGlmaWNhdGlvbignTicsIHRydWUpO1xyXG4gICAgICAgICAgICBub3RpZmljYXRpb24udmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICAgICAgbm90aWZpY2F0aW9uLl9hY2NlcHQgPSBfYWNjZXB0O1xyXG4gICAgICAgICAgICBub3RpZmljYXRpb24uX2FjY2VwdE9ic2VydmFibGUgPSBfYWNjZXB0T2JzZXJ2YWJsZTtcclxuICAgICAgICAgICAgbm90aWZpY2F0aW9uLnRvU3RyaW5nID0gdG9TdHJpbmc7XHJcbiAgICAgICAgICAgIHJldHVybiBub3RpZmljYXRpb247XHJcbiAgICAgICAgfTtcclxuICAgIH0oKSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYW4gT25FcnJvciBub3RpZmljYXRpb24gdG8gYW4gb2JzZXJ2ZXIuXHJcbiAgICAgKiBAcGFyYW0ge0FueX0gZXJyb3IgVGhlIGV4Y2VwdGlvbiBjb250YWluZWQgaW4gdGhlIG5vdGlmaWNhdGlvbi5cclxuICAgICAqIEByZXR1cm5zIHtOb3RpZmljYXRpb259IFRoZSBPbkVycm9yIG5vdGlmaWNhdGlvbiBjb250YWluaW5nIHRoZSBleGNlcHRpb24uXHJcbiAgICAgKi9cclxuICAgIHZhciBub3RpZmljYXRpb25DcmVhdGVPbkVycm9yID0gTm90aWZpY2F0aW9uLmNyZWF0ZU9uRXJyb3IgPSAoZnVuY3Rpb24gKCkge1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBfYWNjZXB0IChvbk5leHQsIG9uRXJyb3IpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG9uRXJyb3IodGhpcy5leGNlcHRpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gX2FjY2VwdE9ic2VydmFibGUob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmVyLm9uRXJyb3IodGhpcy5leGNlcHRpb24pO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gdG9TdHJpbmcgKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gJ09uRXJyb3IoJyArIHRoaXMuZXhjZXB0aW9uICsgJyknO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uIChleGNlcHRpb24pIHtcclxuICAgICAgICAgICAgdmFyIG5vdGlmaWNhdGlvbiA9IG5ldyBOb3RpZmljYXRpb24oJ0UnKTtcclxuICAgICAgICAgICAgbm90aWZpY2F0aW9uLmV4Y2VwdGlvbiA9IGV4Y2VwdGlvbjtcclxuICAgICAgICAgICAgbm90aWZpY2F0aW9uLl9hY2NlcHQgPSBfYWNjZXB0O1xyXG4gICAgICAgICAgICBub3RpZmljYXRpb24uX2FjY2VwdE9ic2VydmFibGUgPSBfYWNjZXB0T2JzZXJ2YWJsZTtcclxuICAgICAgICAgICAgbm90aWZpY2F0aW9uLnRvU3RyaW5nID0gdG9TdHJpbmc7XHJcbiAgICAgICAgICAgIHJldHVybiBub3RpZmljYXRpb247XHJcbiAgICAgICAgfTtcclxuICAgIH0oKSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGFuIG9iamVjdCB0aGF0IHJlcHJlc2VudHMgYW4gT25Db21wbGV0ZWQgbm90aWZpY2F0aW9uIHRvIGFuIG9ic2VydmVyLlxyXG4gICAgICogQHJldHVybnMge05vdGlmaWNhdGlvbn0gVGhlIE9uQ29tcGxldGVkIG5vdGlmaWNhdGlvbi5cclxuICAgICAqL1xyXG4gICAgdmFyIG5vdGlmaWNhdGlvbkNyZWF0ZU9uQ29tcGxldGVkID0gTm90aWZpY2F0aW9uLmNyZWF0ZU9uQ29tcGxldGVkID0gKGZ1bmN0aW9uICgpIHtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gX2FjY2VwdCAob25OZXh0LCBvbkVycm9yLCBvbkNvbXBsZXRlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gb25Db21wbGV0ZWQoKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIF9hY2NlcHRPYnNlcnZhYmxlKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgZnVuY3Rpb24gdG9TdHJpbmcgKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gJ09uQ29tcGxldGVkKCknO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIG5vdGlmaWNhdGlvbiA9IG5ldyBOb3RpZmljYXRpb24oJ0MnKTtcclxuICAgICAgICAgICAgbm90aWZpY2F0aW9uLl9hY2NlcHQgPSBfYWNjZXB0O1xyXG4gICAgICAgICAgICBub3RpZmljYXRpb24uX2FjY2VwdE9ic2VydmFibGUgPSBfYWNjZXB0T2JzZXJ2YWJsZTtcclxuICAgICAgICAgICAgbm90aWZpY2F0aW9uLnRvU3RyaW5nID0gdG9TdHJpbmc7XHJcbiAgICAgICAgICAgIHJldHVybiBub3RpZmljYXRpb247XHJcbiAgICAgICAgfTtcclxuICAgIH0oKSk7XHJcblxyXG4gIHZhciBFbnVtZXJhdG9yID0gUnguaW50ZXJuYWxzLkVudW1lcmF0b3IgPSBmdW5jdGlvbiAobmV4dCkge1xyXG4gICAgdGhpcy5fbmV4dCA9IG5leHQ7XHJcbiAgfTtcclxuXHJcbiAgRW51bWVyYXRvci5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHJldHVybiB0aGlzLl9uZXh0KCk7XHJcbiAgfTtcclxuXHJcbiAgRW51bWVyYXRvci5wcm90b3R5cGVbJGl0ZXJhdG9yJF0gPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzOyB9XHJcblxyXG4gIHZhciBFbnVtZXJhYmxlID0gUnguaW50ZXJuYWxzLkVudW1lcmFibGUgPSBmdW5jdGlvbiAoaXRlcmF0b3IpIHtcclxuICAgIHRoaXMuX2l0ZXJhdG9yID0gaXRlcmF0b3I7XHJcbiAgfTtcclxuXHJcbiAgRW51bWVyYWJsZS5wcm90b3R5cGVbJGl0ZXJhdG9yJF0gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5faXRlcmF0b3IoKTtcclxuICB9O1xyXG5cclxuICBFbnVtZXJhYmxlLnByb3RvdHlwZS5jb25jYXQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgc291cmNlcyA9IHRoaXM7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciBlO1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGUgPSBzb3VyY2VzWyRpdGVyYXRvciRdKCk7XHJcbiAgICAgIH0gY2F0Y2goZXJyKSB7XHJcbiAgICAgICAgb2JzZXJ2ZXIub25FcnJvcigpO1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIGlzRGlzcG9zZWQsIFxyXG4gICAgICAgIHN1YnNjcmlwdGlvbiA9IG5ldyBTZXJpYWxEaXNwb3NhYmxlKCk7XHJcbiAgICAgIHZhciBjYW5jZWxhYmxlID0gaW1tZWRpYXRlU2NoZWR1bGVyLnNjaGVkdWxlUmVjdXJzaXZlKGZ1bmN0aW9uIChzZWxmKSB7XHJcbiAgICAgICAgdmFyIGN1cnJlbnRJdGVtO1xyXG4gICAgICAgIGlmIChpc0Rpc3Bvc2VkKSB7IHJldHVybjsgfVxyXG5cclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgY3VycmVudEl0ZW0gPSBlLm5leHQoKTtcclxuICAgICAgICB9IGNhdGNoIChleCkge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleCk7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoY3VycmVudEl0ZW0uZG9uZSkge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIENoZWNrIGlmIHByb21pc2VcclxuICAgICAgICB2YXIgY3VycmVudFZhbHVlID0gY3VycmVudEl0ZW0udmFsdWU7XHJcbiAgICAgICAgaXNQcm9taXNlKGN1cnJlbnRWYWx1ZSkgJiYgKGN1cnJlbnRWYWx1ZSA9IG9ic2VydmFibGVGcm9tUHJvbWlzZShjdXJyZW50VmFsdWUpKTtcclxuXHJcbiAgICAgICAgdmFyIGQgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICBzdWJzY3JpcHRpb24uc2V0RGlzcG9zYWJsZShkKTtcclxuICAgICAgICBkLnNldERpc3Bvc2FibGUoY3VycmVudFZhbHVlLnN1YnNjcmliZShcclxuICAgICAgICAgIG9ic2VydmVyLm9uTmV4dC5iaW5kKG9ic2VydmVyKSxcclxuICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksXHJcbiAgICAgICAgICBmdW5jdGlvbiAoKSB7IHNlbGYoKTsgfSlcclxuICAgICAgICApO1xyXG4gICAgICB9KTtcclxuXHJcbiAgICAgIHJldHVybiBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZShzdWJzY3JpcHRpb24sIGNhbmNlbGFibGUsIGRpc3Bvc2FibGVDcmVhdGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlzRGlzcG9zZWQgPSB0cnVlO1xyXG4gICAgICB9KSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICBFbnVtZXJhYmxlLnByb3RvdHlwZS5jYXRjaEV4Y2VwdGlvbiA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBzb3VyY2VzID0gdGhpcztcclxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgdmFyIGU7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgZSA9IHNvdXJjZXNbJGl0ZXJhdG9yJF0oKTtcclxuICAgICAgfSBjYXRjaChlcnIpIHtcclxuICAgICAgICBvYnNlcnZlci5vbkVycm9yKCk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgaXNEaXNwb3NlZCwgXHJcbiAgICAgICAgbGFzdEV4Y2VwdGlvbixcclxuICAgICAgICBzdWJzY3JpcHRpb24gPSBuZXcgU2VyaWFsRGlzcG9zYWJsZSgpO1xyXG4gICAgICB2YXIgY2FuY2VsYWJsZSA9IGltbWVkaWF0ZVNjaGVkdWxlci5zY2hlZHVsZVJlY3Vyc2l2ZShmdW5jdGlvbiAoc2VsZikge1xyXG4gICAgICAgIGlmIChpc0Rpc3Bvc2VkKSB7IHJldHVybjsgfVxyXG5cclxuICAgICAgICB2YXIgY3VycmVudEl0ZW07XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgIGN1cnJlbnRJdGVtID0gZS5uZXh0KCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXgpIHtcclxuICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXgpO1xyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGN1cnJlbnRJdGVtLmRvbmUpIHtcclxuICAgICAgICAgIGlmIChsYXN0RXhjZXB0aW9uKSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IobGFzdEV4Y2VwdGlvbik7XHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgcHJvbWlzZVxyXG4gICAgICAgIHZhciBjdXJyZW50VmFsdWUgPSBjdXJyZW50SXRlbS52YWx1ZTtcclxuICAgICAgICBpc1Byb21pc2UoY3VycmVudFZhbHVlKSAmJiAoY3VycmVudFZhbHVlID0gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKGN1cnJlbnRWYWx1ZSkpOyAgICAgICAgXHJcblxyXG4gICAgICAgIHZhciBkID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCk7XHJcbiAgICAgICAgc3Vic2NyaXB0aW9uLnNldERpc3Bvc2FibGUoZCk7XHJcbiAgICAgICAgZC5zZXREaXNwb3NhYmxlKGN1cnJlbnRWYWx1ZS5zdWJzY3JpYmUoXHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQuYmluZChvYnNlcnZlciksXHJcbiAgICAgICAgICBmdW5jdGlvbiAoZXhuKSB7XHJcbiAgICAgICAgICAgIGxhc3RFeGNlcHRpb24gPSBleG47XHJcbiAgICAgICAgICAgIHNlbGYoKTtcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZC5iaW5kKG9ic2VydmVyKSkpO1xyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuIG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKHN1YnNjcmlwdGlvbiwgY2FuY2VsYWJsZSwgZGlzcG9zYWJsZUNyZWF0ZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaXNEaXNwb3NlZCA9IHRydWU7XHJcbiAgICAgIH0pKTtcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIHZhciBlbnVtZXJhYmxlUmVwZWF0ID0gRW51bWVyYWJsZS5yZXBlYXQgPSBmdW5jdGlvbiAodmFsdWUsIHJlcGVhdENvdW50KSB7XHJcbiAgICBpZiAocmVwZWF0Q291bnQgPT0gbnVsbCkgeyByZXBlYXRDb3VudCA9IC0xOyB9XHJcbiAgICByZXR1cm4gbmV3IEVudW1lcmFibGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICB2YXIgbGVmdCA9IHJlcGVhdENvdW50O1xyXG4gICAgICByZXR1cm4gbmV3IEVudW1lcmF0b3IoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmIChsZWZ0ID09PSAwKSB7IHJldHVybiBkb25lRW51bWVyYXRvcjsgfVxyXG4gICAgICAgIGlmIChsZWZ0ID4gMCkgeyBsZWZ0LS07IH1cclxuICAgICAgICByZXR1cm4geyBkb25lOiBmYWxzZSwgdmFsdWU6IHZhbHVlIH07XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgdmFyIGVudW1lcmFibGVGb3IgPSBFbnVtZXJhYmxlLmZvckVhY2ggPSBmdW5jdGlvbiAoc291cmNlLCBzZWxlY3RvciwgdGhpc0FyZykge1xyXG4gICAgc2VsZWN0b3IgfHwgKHNlbGVjdG9yID0gaWRlbnRpdHkpO1xyXG4gICAgcmV0dXJuIG5ldyBFbnVtZXJhYmxlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIGluZGV4ID0gLTE7XHJcbiAgICAgIHJldHVybiBuZXcgRW51bWVyYXRvcihcclxuICAgICAgICBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICByZXR1cm4gKytpbmRleCA8IHNvdXJjZS5sZW5ndGggP1xyXG4gICAgICAgICAgICB7IGRvbmU6IGZhbHNlLCB2YWx1ZTogc2VsZWN0b3IuY2FsbCh0aGlzQXJnLCBzb3VyY2VbaW5kZXhdLCBpbmRleCwgc291cmNlKSB9IDpcclxuICAgICAgICAgICAgZG9uZUVudW1lcmF0b3I7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBTdXBwb3J0cyBwdXNoLXN0eWxlIGl0ZXJhdGlvbiBvdmVyIGFuIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICovXHJcbiAgdmFyIE9ic2VydmVyID0gUnguT2JzZXJ2ZXIgPSBmdW5jdGlvbiAoKSB7IH07XHJcblxyXG4gIC8qKlxyXG4gICAqICBDcmVhdGVzIGEgbm90aWZpY2F0aW9uIGNhbGxiYWNrIGZyb20gYW4gb2JzZXJ2ZXIuXHJcbiAgICogIFxyXG4gICAqIEBwYXJhbSBvYnNlcnZlciBPYnNlcnZlciBvYmplY3QuXHJcbiAgICogQHJldHVybnMgVGhlIGFjdGlvbiB0aGF0IGZvcndhcmRzIGl0cyBpbnB1dCBub3RpZmljYXRpb24gdG8gdGhlIHVuZGVybHlpbmcgb2JzZXJ2ZXIuXHJcbiAgICovXHJcbiAgT2JzZXJ2ZXIucHJvdG90eXBlLnRvTm90aWZpZXIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgb2JzZXJ2ZXIgPSB0aGlzO1xyXG4gICAgcmV0dXJuIGZ1bmN0aW9uIChuKSB7XHJcbiAgICAgIHJldHVybiBuLmFjY2VwdChvYnNlcnZlcik7XHJcbiAgICB9O1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqICBIaWRlcyB0aGUgaWRlbnRpdHkgb2YgYW4gb2JzZXJ2ZXIuXHJcblxyXG4gICAqIEByZXR1cm5zIEFuIG9ic2VydmVyIHRoYXQgaGlkZXMgdGhlIGlkZW50aXR5IG9mIHRoZSBzcGVjaWZpZWQgb2JzZXJ2ZXIuIFxyXG4gICAqLyAgIFxyXG4gIE9ic2VydmVyLnByb3RvdHlwZS5hc09ic2VydmVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZlcih0aGlzLm9uTmV4dC5iaW5kKHRoaXMpLCB0aGlzLm9uRXJyb3IuYmluZCh0aGlzKSwgdGhpcy5vbkNvbXBsZXRlZC5iaW5kKHRoaXMpKTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiAgQ2hlY2tzIGFjY2VzcyB0byB0aGUgb2JzZXJ2ZXIgZm9yIGdyYW1tYXIgdmlvbGF0aW9ucy4gVGhpcyBpbmNsdWRlcyBjaGVja2luZyBmb3IgbXVsdGlwbGUgT25FcnJvciBvciBPbkNvbXBsZXRlZCBjYWxscywgYXMgd2VsbCBhcyByZWVudHJhbmN5IGluIGFueSBvZiB0aGUgb2JzZXJ2ZXIgbWV0aG9kcy5cclxuICAgKiAgSWYgYSB2aW9sYXRpb24gaXMgZGV0ZWN0ZWQsIGFuIEVycm9yIGlzIHRocm93biBmcm9tIHRoZSBvZmZlbmRpbmcgb2JzZXJ2ZXIgbWV0aG9kIGNhbGwuXHJcbiAgICogIFxyXG4gICAqIEByZXR1cm5zIEFuIG9ic2VydmVyIHRoYXQgY2hlY2tzIGNhbGxiYWNrcyBpbnZvY2F0aW9ucyBhZ2FpbnN0IHRoZSBvYnNlcnZlciBncmFtbWFyIGFuZCwgaWYgdGhlIGNoZWNrcyBwYXNzLCBmb3J3YXJkcyB0aG9zZSB0byB0aGUgc3BlY2lmaWVkIG9ic2VydmVyLlxyXG4gICAqLyAgICBcclxuICBPYnNlcnZlci5wcm90b3R5cGUuY2hlY2tlZCA9IGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyBDaGVja2VkT2JzZXJ2ZXIodGhpcyk7IH07XHJcblxyXG4gIC8qKlxyXG4gICAqICBDcmVhdGVzIGFuIG9ic2VydmVyIGZyb20gdGhlIHNwZWNpZmllZCBPbk5leHQsIGFsb25nIHdpdGggb3B0aW9uYWwgT25FcnJvciwgYW5kIE9uQ29tcGxldGVkIGFjdGlvbnMuXHJcbiAgICogIFxyXG4gICAqIEBzdGF0aWNcclxuICAgKiBAbWVtYmVyT2YgT2JzZXJ2ZXJcclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbb25OZXh0XSBPYnNlcnZlcidzIE9uTmV4dCBhY3Rpb24gaW1wbGVtZW50YXRpb24uXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29uRXJyb3JdIE9ic2VydmVyJ3MgT25FcnJvciBhY3Rpb24gaW1wbGVtZW50YXRpb24uXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29uQ29tcGxldGVkXSBPYnNlcnZlcidzIE9uQ29tcGxldGVkIGFjdGlvbiBpbXBsZW1lbnRhdGlvbi5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2ZXJ9IFRoZSBvYnNlcnZlciBvYmplY3QgaW1wbGVtZW50ZWQgdXNpbmcgdGhlIGdpdmVuIGFjdGlvbnMuXHJcbiAgICovXHJcbiAgdmFyIG9ic2VydmVyQ3JlYXRlID0gT2JzZXJ2ZXIuY3JlYXRlID0gZnVuY3Rpb24gKG9uTmV4dCwgb25FcnJvciwgb25Db21wbGV0ZWQpIHtcclxuICAgIG9uTmV4dCB8fCAob25OZXh0ID0gbm9vcCk7XHJcbiAgICBvbkVycm9yIHx8IChvbkVycm9yID0gZGVmYXVsdEVycm9yKTtcclxuICAgIG9uQ29tcGxldGVkIHx8IChvbkNvbXBsZXRlZCA9IG5vb3ApO1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZlcihvbk5leHQsIG9uRXJyb3IsIG9uQ29tcGxldGVkKTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiAgQ3JlYXRlcyBhbiBvYnNlcnZlciBmcm9tIGEgbm90aWZpY2F0aW9uIGNhbGxiYWNrLlxyXG4gICAqICBcclxuICAgKiBAc3RhdGljXHJcbiAgICogQG1lbWJlck9mIE9ic2VydmVyXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gaGFuZGxlciBBY3Rpb24gdGhhdCBoYW5kbGVzIGEgbm90aWZpY2F0aW9uLlxyXG4gICAqIEByZXR1cm5zIFRoZSBvYnNlcnZlciBvYmplY3QgdGhhdCBpbnZva2VzIHRoZSBzcGVjaWZpZWQgaGFuZGxlciB1c2luZyBhIG5vdGlmaWNhdGlvbiBjb3JyZXNwb25kaW5nIHRvIGVhY2ggbWVzc2FnZSBpdCByZWNlaXZlcy5cclxuICAgKi9cclxuICBPYnNlcnZlci5mcm9tTm90aWZpZXIgPSBmdW5jdGlvbiAoaGFuZGxlcikge1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZlcihmdW5jdGlvbiAoeCkge1xyXG4gICAgICByZXR1cm4gaGFuZGxlcihub3RpZmljYXRpb25DcmVhdGVPbk5leHQoeCkpO1xyXG4gICAgfSwgZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xyXG4gICAgICByZXR1cm4gaGFuZGxlcihub3RpZmljYXRpb25DcmVhdGVPbkVycm9yKGV4Y2VwdGlvbikpO1xyXG4gICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICByZXR1cm4gaGFuZGxlcihub3RpZmljYXRpb25DcmVhdGVPbkNvbXBsZXRlZCgpKTtcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFNjaGVkdWxlcyB0aGUgaW52b2NhdGlvbiBvZiBvYnNlcnZlciBtZXRob2RzIG9uIHRoZSBnaXZlbiBzY2hlZHVsZXIuXHJcbiAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IHNjaGVkdWxlciBTY2hlZHVsZXIgdG8gc2NoZWR1bGUgb2JzZXJ2ZXIgbWVzc2FnZXMgb24uXHJcbiAgICogQHJldHVybnMge09ic2VydmVyfSBPYnNlcnZlciB3aG9zZSBtZXNzYWdlcyBhcmUgc2NoZWR1bGVkIG9uIHRoZSBnaXZlbiBzY2hlZHVsZXIuXHJcbiAgICovXHJcbiAgT2JzZXJ2ZXIubm90aWZ5T24gPSBmdW5jdGlvbiAoc2NoZWR1bGVyKSB7XHJcbiAgICByZXR1cm4gbmV3IE9ic2VydmVPbk9ic2VydmVyKHNjaGVkdWxlciwgdGhpcyk7XHJcbiAgfTtcclxuICBcclxuICAgIC8qKlxyXG4gICAgICogQWJzdHJhY3QgYmFzZSBjbGFzcyBmb3IgaW1wbGVtZW50YXRpb25zIG9mIHRoZSBPYnNlcnZlciBjbGFzcy5cclxuICAgICAqIFRoaXMgYmFzZSBjbGFzcyBlbmZvcmNlcyB0aGUgZ3JhbW1hciBvZiBvYnNlcnZlcnMgd2hlcmUgT25FcnJvciBhbmQgT25Db21wbGV0ZWQgYXJlIHRlcm1pbmFsIG1lc3NhZ2VzLiBcclxuICAgICAqL1xyXG4gICAgdmFyIEFic3RyYWN0T2JzZXJ2ZXIgPSBSeC5pbnRlcm5hbHMuQWJzdHJhY3RPYnNlcnZlciA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICAgICAgaW5oZXJpdHMoQWJzdHJhY3RPYnNlcnZlciwgX3N1cGVyKTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ3JlYXRlcyBhIG5ldyBvYnNlcnZlciBpbiBhIG5vbi1zdG9wcGVkIHN0YXRlLlxyXG4gICAgICAgICAqXHJcbiAgICAgICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZnVuY3Rpb24gQWJzdHJhY3RPYnNlcnZlcigpIHtcclxuICAgICAgICAgICAgdGhpcy5pc1N0b3BwZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgX3N1cGVyLmNhbGwodGhpcyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBOb3RpZmllcyB0aGUgb2JzZXJ2ZXIgb2YgYSBuZXcgZWxlbWVudCBpbiB0aGUgc2VxdWVuY2UuXHJcbiAgICAgICAgICogIFxyXG4gICAgICAgICAqIEBtZW1iZXJPZiBBYnN0cmFjdE9ic2VydmVyXHJcbiAgICAgICAgICogQHBhcmFtIHtBbnl9IHZhbHVlIE5leHQgZWxlbWVudCBpbiB0aGUgc2VxdWVuY2UuIFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEFic3RyYWN0T2JzZXJ2ZXIucHJvdG90eXBlLm9uTmV4dCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNTdG9wcGVkKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm5leHQodmFsdWUpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogTm90aWZpZXMgdGhlIG9ic2VydmVyIHRoYXQgYW4gZXhjZXB0aW9uIGhhcyBvY2N1cnJlZC5cclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAbWVtYmVyT2YgQWJzdHJhY3RPYnNlcnZlclxyXG4gICAgICAgICAqIEBwYXJhbSB7QW55fSBlcnJvciBUaGUgZXJyb3IgdGhhdCBoYXMgb2NjdXJyZWQuICAgICBcclxuICAgICAgICAgKi8gICAgXHJcbiAgICAgICAgQWJzdHJhY3RPYnNlcnZlci5wcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uIChlcnJvcikge1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNTdG9wcGVkKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzU3RvcHBlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yKGVycm9yKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIE5vdGlmaWVzIHRoZSBvYnNlcnZlciBvZiB0aGUgZW5kIG9mIHRoZSBzZXF1ZW5jZS5cclxuICAgICAgICAgKi8gICAgXHJcbiAgICAgICAgQWJzdHJhY3RPYnNlcnZlci5wcm90b3R5cGUub25Db21wbGV0ZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5pc1N0b3BwZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaXNTdG9wcGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuY29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBEaXNwb3NlcyB0aGUgb2JzZXJ2ZXIsIGNhdXNpbmcgaXQgdG8gdHJhbnNpdGlvbiB0byB0aGUgc3RvcHBlZCBzdGF0ZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBBYnN0cmFjdE9ic2VydmVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB0aGlzLmlzU3RvcHBlZCA9IHRydWU7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgQWJzdHJhY3RPYnNlcnZlci5wcm90b3R5cGUuZmFpbCA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5pc1N0b3BwZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaXNTdG9wcGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IoZSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiBBYnN0cmFjdE9ic2VydmVyO1xyXG4gICAgfShPYnNlcnZlcikpO1xyXG5cclxuICAvKipcclxuICAgKiBDbGFzcyB0byBjcmVhdGUgYW4gT2JzZXJ2ZXIgaW5zdGFuY2UgZnJvbSBkZWxlZ2F0ZS1iYXNlZCBpbXBsZW1lbnRhdGlvbnMgb2YgdGhlIG9uKiBtZXRob2RzLlxyXG4gICAqL1xyXG4gIHZhciBBbm9ueW1vdXNPYnNlcnZlciA9IFJ4LkFub255bW91c09ic2VydmVyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgIGluaGVyaXRzKEFub255bW91c09ic2VydmVyLCBfc3VwZXIpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhbiBvYnNlcnZlciBmcm9tIHRoZSBzcGVjaWZpZWQgT25OZXh0LCBPbkVycm9yLCBhbmQgT25Db21wbGV0ZWQgYWN0aW9ucy5cclxuICAgICAqIEBwYXJhbSB7QW55fSBvbk5leHQgT2JzZXJ2ZXIncyBPbk5leHQgYWN0aW9uIGltcGxlbWVudGF0aW9uLlxyXG4gICAgICogQHBhcmFtIHtBbnl9IG9uRXJyb3IgT2JzZXJ2ZXIncyBPbkVycm9yIGFjdGlvbiBpbXBsZW1lbnRhdGlvbi5cclxuICAgICAqIEBwYXJhbSB7QW55fSBvbkNvbXBsZXRlZCBPYnNlcnZlcidzIE9uQ29tcGxldGVkIGFjdGlvbiBpbXBsZW1lbnRhdGlvbi4gIFxyXG4gICAgICovICAgICAgXHJcbiAgICBmdW5jdGlvbiBBbm9ueW1vdXNPYnNlcnZlcihvbk5leHQsIG9uRXJyb3IsIG9uQ29tcGxldGVkKSB7XHJcbiAgICAgIF9zdXBlci5jYWxsKHRoaXMpO1xyXG4gICAgICB0aGlzLl9vbk5leHQgPSBvbk5leHQ7XHJcbiAgICAgIHRoaXMuX29uRXJyb3IgPSBvbkVycm9yO1xyXG4gICAgICB0aGlzLl9vbkNvbXBsZXRlZCA9IG9uQ29tcGxldGVkO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2FsbHMgdGhlIG9uTmV4dCBhY3Rpb24uXHJcbiAgICAgKiBAcGFyYW0ge0FueX0gdmFsdWUgTmV4dCBlbGVtZW50IGluIHRoZSBzZXF1ZW5jZS4gICBcclxuICAgICAqLyAgICAgXHJcbiAgICBBbm9ueW1vdXNPYnNlcnZlci5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICB0aGlzLl9vbk5leHQodmFsdWUpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENhbGxzIHRoZSBvbkVycm9yIGFjdGlvbi5cclxuICAgICAqIEBwYXJhbSB7QW55fSBlcnJvciBUaGUgZXJyb3IgdGhhdCBoYXMgb2NjdXJyZWQuICAgXHJcbiAgICAgKi8gICAgIFxyXG4gICAgQW5vbnltb3VzT2JzZXJ2ZXIucHJvdG90eXBlLmVycm9yID0gZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xyXG4gICAgICB0aGlzLl9vbkVycm9yKGV4Y2VwdGlvbik7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIENhbGxzIHRoZSBvbkNvbXBsZXRlZCBhY3Rpb24uXHJcbiAgICAgKi8gICAgICAgIFxyXG4gICAgQW5vbnltb3VzT2JzZXJ2ZXIucHJvdG90eXBlLmNvbXBsZXRlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdGhpcy5fb25Db21wbGV0ZWQoKTtcclxuICAgIH07XHJcblxyXG4gICAgcmV0dXJuIEFub255bW91c09ic2VydmVyO1xyXG4gIH0oQWJzdHJhY3RPYnNlcnZlcikpO1xyXG5cclxuICAgIHZhciBDaGVja2VkT2JzZXJ2ZXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgIGluaGVyaXRzKENoZWNrZWRPYnNlcnZlciwgX3N1cGVyKTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gQ2hlY2tlZE9ic2VydmVyKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLl9vYnNlcnZlciA9IG9ic2VydmVyO1xyXG4gICAgICAgICAgICB0aGlzLl9zdGF0ZSA9IDA7IC8vIDAgLSBpZGxlLCAxIC0gYnVzeSwgMiAtIGRvbmVcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBDaGVja2VkT2JzZXJ2ZXJQcm90b3R5cGUgPSBDaGVja2VkT2JzZXJ2ZXIucHJvdG90eXBlO1xyXG5cclxuICAgICAgICBDaGVja2VkT2JzZXJ2ZXJQcm90b3R5cGUub25OZXh0ID0gZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgIHRoaXMuY2hlY2tBY2Nlc3MoKTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX29ic2VydmVyLm9uTmV4dCh2YWx1ZSk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlOyAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgfSBmaW5hbGx5IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gMDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIENoZWNrZWRPYnNlcnZlclByb3RvdHlwZS5vbkVycm9yID0gZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgICAgICB0aGlzLmNoZWNrQWNjZXNzKCk7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLl9vYnNlcnZlci5vbkVycm9yKGVycik7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlOyAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgfSBmaW5hbGx5IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3N0YXRlID0gMjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIENoZWNrZWRPYnNlcnZlclByb3RvdHlwZS5vbkNvbXBsZXRlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy5jaGVja0FjY2VzcygpO1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkgeyBcclxuICAgICAgICAgICAgICAgIHRocm93IGU7ICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICB9IGZpbmFsbHkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5fc3RhdGUgPSAyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgQ2hlY2tlZE9ic2VydmVyUHJvdG90eXBlLmNoZWNrQWNjZXNzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5fc3RhdGUgPT09IDEpIHsgdGhyb3cgbmV3IEVycm9yKCdSZS1lbnRyYW5jeSBkZXRlY3RlZCcpOyB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gMikgeyB0aHJvdyBuZXcgRXJyb3IoJ09ic2VydmVyIGNvbXBsZXRlZCcpOyB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLl9zdGF0ZSA9PT0gMCkgeyB0aGlzLl9zdGF0ZSA9IDE7IH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gQ2hlY2tlZE9ic2VydmVyO1xyXG4gICAgfShPYnNlcnZlcikpO1xyXG5cclxuICB2YXIgU2NoZWR1bGVkT2JzZXJ2ZXIgPSBSeC5pbnRlcm5hbHMuU2NoZWR1bGVkT2JzZXJ2ZXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgaW5oZXJpdHMoU2NoZWR1bGVkT2JzZXJ2ZXIsIF9zdXBlcik7XHJcblxyXG4gICAgZnVuY3Rpb24gU2NoZWR1bGVkT2JzZXJ2ZXIoc2NoZWR1bGVyLCBvYnNlcnZlcikge1xyXG4gICAgICBfc3VwZXIuY2FsbCh0aGlzKTtcclxuICAgICAgdGhpcy5zY2hlZHVsZXIgPSBzY2hlZHVsZXI7XHJcbiAgICAgIHRoaXMub2JzZXJ2ZXIgPSBvYnNlcnZlcjtcclxuICAgICAgdGhpcy5pc0FjcXVpcmVkID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuaGFzRmF1bHRlZCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLnF1ZXVlID0gW107XHJcbiAgICAgIHRoaXMuZGlzcG9zYWJsZSA9IG5ldyBTZXJpYWxEaXNwb3NhYmxlKCk7XHJcbiAgICB9XHJcblxyXG4gICAgU2NoZWR1bGVkT2JzZXJ2ZXIucHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICB0aGlzLnF1ZXVlLnB1c2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHNlbGYub2JzZXJ2ZXIub25OZXh0KHZhbHVlKTtcclxuICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIFNjaGVkdWxlZE9ic2VydmVyLnByb3RvdHlwZS5lcnJvciA9IGZ1bmN0aW9uIChleGNlcHRpb24pIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICB0aGlzLnF1ZXVlLnB1c2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHNlbGYub2JzZXJ2ZXIub25FcnJvcihleGNlcHRpb24pO1xyXG4gICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgU2NoZWR1bGVkT2JzZXJ2ZXIucHJvdG90eXBlLmNvbXBsZXRlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICB0aGlzLnF1ZXVlLnB1c2goZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHNlbGYub2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIFNjaGVkdWxlZE9ic2VydmVyLnByb3RvdHlwZS5lbnN1cmVBY3RpdmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgIHZhciBpc093bmVyID0gZmFsc2UsIHBhcmVudCA9IHRoaXM7XHJcbiAgICAgIGlmICghdGhpcy5oYXNGYXVsdGVkICYmIHRoaXMucXVldWUubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGlzT3duZXIgPSAhdGhpcy5pc0FjcXVpcmVkO1xyXG4gICAgICAgIHRoaXMuaXNBY3F1aXJlZCA9IHRydWU7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKGlzT3duZXIpIHtcclxuICAgICAgICB0aGlzLmRpc3Bvc2FibGUuc2V0RGlzcG9zYWJsZSh0aGlzLnNjaGVkdWxlci5zY2hlZHVsZVJlY3Vyc2l2ZShmdW5jdGlvbiAoc2VsZikge1xyXG4gICAgICAgICAgdmFyIHdvcms7XHJcbiAgICAgICAgICBpZiAocGFyZW50LnF1ZXVlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgd29yayA9IHBhcmVudC5xdWV1ZS5zaGlmdCgpO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcGFyZW50LmlzQWNxdWlyZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgd29yaygpO1xyXG4gICAgICAgICAgfSBjYXRjaCAoZXgpIHtcclxuICAgICAgICAgICAgcGFyZW50LnF1ZXVlID0gW107XHJcbiAgICAgICAgICAgIHBhcmVudC5oYXNGYXVsdGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgdGhyb3cgZXg7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBzZWxmKCk7XHJcbiAgICAgICAgfSkpO1xyXG4gICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIFNjaGVkdWxlZE9ic2VydmVyLnByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICBfc3VwZXIucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcclxuICAgICAgdGhpcy5kaXNwb3NhYmxlLmRpc3Bvc2UoKTtcclxuICAgIH07XHJcblxyXG4gICAgcmV0dXJuIFNjaGVkdWxlZE9ic2VydmVyO1xyXG4gIH0oQWJzdHJhY3RPYnNlcnZlcikpO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgdmFyIE9ic2VydmVPbk9ic2VydmVyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgICAgICBpbmhlcml0cyhPYnNlcnZlT25PYnNlcnZlciwgX3N1cGVyKTtcclxuXHJcbiAgICAgICAgLyoqIEBwcml2YXRlICovIFxyXG4gICAgICAgIGZ1bmN0aW9uIE9ic2VydmVPbk9ic2VydmVyKCkge1xyXG4gICAgICAgICAgICBfc3VwZXIuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKiBAcHJpdmF0ZSAqLyBcclxuICAgICAgICBPYnNlcnZlT25PYnNlcnZlci5wcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgICBfc3VwZXIucHJvdG90eXBlLm5leHQuY2FsbCh0aGlzLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgIHRoaXMuZW5zdXJlQWN0aXZlKCk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqIEBwcml2YXRlICovIFxyXG4gICAgICAgIE9ic2VydmVPbk9ic2VydmVyLnByb3RvdHlwZS5lcnJvciA9IGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgIF9zdXBlci5wcm90b3R5cGUuZXJyb3IuY2FsbCh0aGlzLCBlKTtcclxuICAgICAgICAgICAgdGhpcy5lbnN1cmVBY3RpdmUoKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKiogQHByaXZhdGUgKi8gXHJcbiAgICAgICAgT2JzZXJ2ZU9uT2JzZXJ2ZXIucHJvdG90eXBlLmNvbXBsZXRlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgX3N1cGVyLnByb3RvdHlwZS5jb21wbGV0ZWQuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgdGhpcy5lbnN1cmVBY3RpdmUoKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gT2JzZXJ2ZU9uT2JzZXJ2ZXI7XHJcbiAgICB9KShTY2hlZHVsZWRPYnNlcnZlcik7XHJcblxyXG4gIHZhciBvYnNlcnZhYmxlUHJvdG87XHJcblxyXG4gIC8qKlxyXG4gICAqIFJlcHJlc2VudHMgYSBwdXNoLXN0eWxlIGNvbGxlY3Rpb24uXHJcbiAgICovXHJcbiAgdmFyIE9ic2VydmFibGUgPSBSeC5PYnNlcnZhYmxlID0gKGZ1bmN0aW9uICgpIHtcclxuXHJcbiAgICBmdW5jdGlvbiBPYnNlcnZhYmxlKHN1YnNjcmliZSkge1xyXG4gICAgICB0aGlzLl9zdWJzY3JpYmUgPSBzdWJzY3JpYmU7XHJcbiAgICB9XHJcblxyXG4gICAgb2JzZXJ2YWJsZVByb3RvID0gT2JzZXJ2YWJsZS5wcm90b3R5cGU7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgU3Vic2NyaWJlcyBhbiBvYnNlcnZlciB0byB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgMSAtIHNvdXJjZS5zdWJzY3JpYmUoKTtcclxuICAgICAqICAyIC0gc291cmNlLnN1YnNjcmliZShvYnNlcnZlcik7XHJcbiAgICAgKiAgMyAtIHNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHsgY29uc29sZS5sb2coeCk7IH0pO1xyXG4gICAgICogIDQgLSBzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7IGNvbnNvbGUubG9nKHgpOyB9LCBmdW5jdGlvbiAoZXJyKSB7IGNvbnNvbGUubG9nKGVycik7IH0pO1xyXG4gICAgICogIDUgLSBzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7IGNvbnNvbGUubG9nKHgpOyB9LCBmdW5jdGlvbiAoZXJyKSB7IGNvbnNvbGUubG9nKGVycik7IH0sIGZ1bmN0aW9uICgpIHsgY29uc29sZS5sb2coJ2RvbmUnKTsgfSk7XHJcbiAgICAgKiAgQHBhcmFtIHtNaXhlZH0gW29ic2VydmVyT3JPbk5leHRdIFRoZSBvYmplY3QgdGhhdCBpcyB0byByZWNlaXZlIG5vdGlmaWNhdGlvbnMgb3IgYW4gYWN0aW9uIHRvIGludm9rZSBmb3IgZWFjaCBlbGVtZW50IGluIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAgICogIEBwYXJhbSB7RnVuY3Rpb259IFtvbkVycm9yXSBBY3Rpb24gdG8gaW52b2tlIHVwb24gZXhjZXB0aW9uYWwgdGVybWluYXRpb24gb2YgdGhlIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgKiAgQHBhcmFtIHtGdW5jdGlvbn0gW29uQ29tcGxldGVkXSBBY3Rpb24gdG8gaW52b2tlIHVwb24gZ3JhY2VmdWwgdGVybWluYXRpb24gb2YgdGhlIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgKiAgQHJldHVybnMge0RpcG9zYWJsZX0gVGhlIHNvdXJjZSBzZXF1ZW5jZSB3aG9zZSBzdWJzY3JpcHRpb25zIGFuZCB1bnN1YnNjcmlwdGlvbnMgaGFwcGVuIG9uIHRoZSBzcGVjaWZpZWQgc2NoZWR1bGVyLiBcclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnN1YnNjcmliZSA9IG9ic2VydmFibGVQcm90by5mb3JFYWNoID0gZnVuY3Rpb24gKG9ic2VydmVyT3JPbk5leHQsIG9uRXJyb3IsIG9uQ29tcGxldGVkKSB7XHJcbiAgICAgIHZhciBzdWJzY3JpYmVyID0gdHlwZW9mIG9ic2VydmVyT3JPbk5leHQgPT09ICdvYmplY3QnID9cclxuICAgICAgICBvYnNlcnZlck9yT25OZXh0IDpcclxuICAgICAgICBvYnNlcnZlckNyZWF0ZShvYnNlcnZlck9yT25OZXh0LCBvbkVycm9yLCBvbkNvbXBsZXRlZCk7XHJcblxyXG4gICAgICByZXR1cm4gdGhpcy5fc3Vic2NyaWJlKHN1YnNjcmliZXIpO1xyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gT2JzZXJ2YWJsZTtcclxuICB9KSgpO1xyXG5cclxuICAgICAvKipcclxuICAgICAqICBXcmFwcyB0aGUgc291cmNlIHNlcXVlbmNlIGluIG9yZGVyIHRvIHJ1biBpdHMgb2JzZXJ2ZXIgY2FsbGJhY2tzIG9uIHRoZSBzcGVjaWZpZWQgc2NoZWR1bGVyLlxyXG4gICAgICogXHJcbiAgICAgKiAgVGhpcyBvbmx5IGludm9rZXMgb2JzZXJ2ZXIgY2FsbGJhY2tzIG9uIGEgc2NoZWR1bGVyLiBJbiBjYXNlIHRoZSBzdWJzY3JpcHRpb24gYW5kL29yIHVuc3Vic2NyaXB0aW9uIGFjdGlvbnMgaGF2ZSBzaWRlLWVmZmVjdHNcclxuICAgICAqICB0aGF0IHJlcXVpcmUgdG8gYmUgcnVuIG9uIGEgc2NoZWR1bGVyLCB1c2Ugc3Vic2NyaWJlT24uXHJcbiAgICAgKiAgICAgICAgICBcclxuICAgICAqICBAcGFyYW0ge1NjaGVkdWxlcn0gc2NoZWR1bGVyIFNjaGVkdWxlciB0byBub3RpZnkgb2JzZXJ2ZXJzIG9uLlxyXG4gICAgICogIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBUaGUgc291cmNlIHNlcXVlbmNlIHdob3NlIG9ic2VydmF0aW9ucyBoYXBwZW4gb24gdGhlIHNwZWNpZmllZCBzY2hlZHVsZXIuICAgICBcclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLm9ic2VydmVPbiA9IGZ1bmN0aW9uIChzY2hlZHVsZXIpIHtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic2NyaWJlKG5ldyBPYnNlcnZlT25PYnNlcnZlcihzY2hlZHVsZXIsIG9ic2VydmVyKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgICAvKipcclxuICAgICAqICBXcmFwcyB0aGUgc291cmNlIHNlcXVlbmNlIGluIG9yZGVyIHRvIHJ1biBpdHMgc3Vic2NyaXB0aW9uIGFuZCB1bnN1YnNjcmlwdGlvbiBsb2dpYyBvbiB0aGUgc3BlY2lmaWVkIHNjaGVkdWxlci4gVGhpcyBvcGVyYXRpb24gaXMgbm90IGNvbW1vbmx5IHVzZWQ7XHJcbiAgICAgKiAgc2VlIHRoZSByZW1hcmtzIHNlY3Rpb24gZm9yIG1vcmUgaW5mb3JtYXRpb24gb24gdGhlIGRpc3RpbmN0aW9uIGJldHdlZW4gc3Vic2NyaWJlT24gYW5kIG9ic2VydmVPbi5cclxuXHJcbiAgICAgKiAgVGhpcyBvbmx5IHBlcmZvcm1zIHRoZSBzaWRlLWVmZmVjdHMgb2Ygc3Vic2NyaXB0aW9uIGFuZCB1bnN1YnNjcmlwdGlvbiBvbiB0aGUgc3BlY2lmaWVkIHNjaGVkdWxlci4gSW4gb3JkZXIgdG8gaW52b2tlIG9ic2VydmVyXHJcbiAgICAgKiAgY2FsbGJhY2tzIG9uIGEgc2NoZWR1bGVyLCB1c2Ugb2JzZXJ2ZU9uLlxyXG5cclxuICAgICAqICBAcGFyYW0ge1NjaGVkdWxlcn0gc2NoZWR1bGVyIFNjaGVkdWxlciB0byBwZXJmb3JtIHN1YnNjcmlwdGlvbiBhbmQgdW5zdWJzY3JpcHRpb24gYWN0aW9ucyBvbi5cclxuICAgICAqICBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIHNvdXJjZSBzZXF1ZW5jZSB3aG9zZSBzdWJzY3JpcHRpb25zIGFuZCB1bnN1YnNjcmlwdGlvbnMgaGFwcGVuIG9uIHRoZSBzcGVjaWZpZWQgc2NoZWR1bGVyLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uc3Vic2NyaWJlT24gPSBmdW5jdGlvbiAoc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRoaXM7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgbSA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpLCBkID0gbmV3IFNlcmlhbERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgZC5zZXREaXNwb3NhYmxlKG0pO1xyXG4gICAgICAgICAgICBtLnNldERpc3Bvc2FibGUoc2NoZWR1bGVyLnNjaGVkdWxlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGQuc2V0RGlzcG9zYWJsZShuZXcgU2NoZWR1bGVkRGlzcG9zYWJsZShzY2hlZHVsZXIsIHNvdXJjZS5zdWJzY3JpYmUob2JzZXJ2ZXIpKSk7XHJcbiAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgcmV0dXJuIGQ7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAvKipcclxuICAgKiBDb252ZXJ0cyBhIFByb21pc2UgdG8gYW4gT2JzZXJ2YWJsZSBzZXF1ZW5jZVxyXG4gICAqIEBwYXJhbSB7UHJvbWlzZX0gQW4gRVM2IENvbXBsaWFudCBwcm9taXNlLlxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBPYnNlcnZhYmxlIHNlcXVlbmNlIHdoaWNoIHdyYXBzIHRoZSBleGlzdGluZyBwcm9taXNlIHN1Y2Nlc3MgYW5kIGZhaWx1cmUuXHJcbiAgICovXHJcbiAgdmFyIG9ic2VydmFibGVGcm9tUHJvbWlzZSA9IE9ic2VydmFibGUuZnJvbVByb21pc2UgPSBmdW5jdGlvbiAocHJvbWlzZSkge1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICBwcm9taXNlLnRoZW4oXHJcbiAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQodmFsdWUpO1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICB9LCBcclxuICAgICAgICBmdW5jdGlvbiAocmVhc29uKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKHJlYXNvbik7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlmIChwcm9taXNlICYmIHByb21pc2UuYWJvcnQpIHtcclxuICAgICAgICAgIHByb21pc2UuYWJvcnQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH07XHJcbiAgICAvKlxyXG4gICAgICogQ29udmVydHMgYW4gZXhpc3Rpbmcgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0byBhbiBFUzYgQ29tcGF0aWJsZSBQcm9taXNlXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogdmFyIHByb21pc2UgPSBSeC5PYnNlcnZhYmxlLnJldHVybig0MikudG9Qcm9taXNlKFJTVlAuUHJvbWlzZSk7XHJcbiAgICAgKiBcclxuICAgICAqIC8vIFdpdGggY29uZmlnXHJcbiAgICAgKiBSeC5jb25maWcuUHJvbWlzZSA9IFJTVlAuUHJvbWlzZTtcclxuICAgICAqIHZhciBwcm9taXNlID0gUnguT2JzZXJ2YWJsZS5yZXR1cm4oNDIpLnRvUHJvbWlzZSgpO1xyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3Byb21pc2VDdG9yXSBUaGUgY29uc3RydWN0b3Igb2YgdGhlIHByb21pc2UuIElmIG5vdCBwcm92aWRlZCwgaXQgbG9va3MgZm9yIGl0IGluIFJ4LmNvbmZpZy5Qcm9taXNlLlxyXG4gICAgICogQHJldHVybnMge1Byb21pc2V9IEFuIEVTNiBjb21wYXRpYmxlIHByb21pc2Ugd2l0aCB0aGUgbGFzdCB2YWx1ZSBmcm9tIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8udG9Qcm9taXNlID0gZnVuY3Rpb24gKHByb21pc2VDdG9yKSB7XHJcbiAgICAgICAgcHJvbWlzZUN0b3IgfHwgKHByb21pc2VDdG9yID0gUnguY29uZmlnLlByb21pc2UpO1xyXG4gICAgICAgIGlmICghcHJvbWlzZUN0b3IpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdQcm9taXNlIHR5cGUgbm90IHByb3ZpZGVkIG5vciBpbiBSeC5jb25maWcuUHJvbWlzZScpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICByZXR1cm4gbmV3IHByb21pc2VDdG9yKGZ1bmN0aW9uIChyZXNvbHZlLCByZWplY3QpIHtcclxuICAgICAgICAgICAgLy8gTm8gY2FuY2VsbGF0aW9uIGNhbiBiZSBkb25lXHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSwgaGFzVmFsdWUgPSBmYWxzZTtcclxuICAgICAgICAgICAgc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAodikge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSB2O1xyXG4gICAgICAgICAgICAgICAgaGFzVmFsdWUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICByZWplY3QoZXJyKTtcclxuICAgICAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGhhc1ZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzb2x2ZSh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuICAvKipcclxuICAgKiBDcmVhdGVzIGEgbGlzdCBmcm9tIGFuIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICogQHJldHVybnMgQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBjb250YWluaW5nIGEgc2luZ2xlIGVsZW1lbnQgd2l0aCBhIGxpc3QgY29udGFpbmluZyBhbGwgdGhlIGVsZW1lbnRzIG9mIHRoZSBzb3VyY2Ugc2VxdWVuY2UuICBcclxuICAgKi9cclxuICBvYnNlcnZhYmxlUHJvdG8udG9BcnJheSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbihvYnNlcnZlcikge1xyXG4gICAgICB2YXIgYXJyID0gW107XHJcbiAgICAgIHJldHVybiBzZWxmLnN1YnNjcmliZShcclxuICAgICAgICBhcnIucHVzaC5iaW5kKGFyciksXHJcbiAgICAgICAgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSxcclxuICAgICAgICBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQoYXJyKTtcclxuICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIENyZWF0ZXMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBmcm9tIGEgc3BlY2lmaWVkIHN1YnNjcmliZSBtZXRob2QgaW1wbGVtZW50YXRpb24uXHJcbiAgICAgKiAgXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLmNyZWF0ZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHsgcmV0dXJuIGZ1bmN0aW9uICgpIHsgfSApO1xyXG4gICAgICogIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLmNyZWF0ZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHsgcmV0dXJuIFJ4LkRpc3Bvc2FibGUuZW1wdHk7IH0gKTsgXHJcbiAgICAgKiAgdmFyIHJlcyA9IFJ4Lk9ic2VydmFibGUuY3JlYXRlKGZ1bmN0aW9uIChvYnNlcnZlcikgeyB9ICk7IFxyXG4gICAgICogIFxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gc3Vic2NyaWJlIEltcGxlbWVudGF0aW9uIG9mIHRoZSByZXN1bHRpbmcgb2JzZXJ2YWJsZSBzZXF1ZW5jZSdzIHN1YnNjcmliZSBtZXRob2QsIHJldHVybmluZyBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSB3cmFwcGVkIGluIGEgRGlzcG9zYWJsZS5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBUaGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aXRoIHRoZSBzcGVjaWZpZWQgaW1wbGVtZW50YXRpb24gZm9yIHRoZSBTdWJzY3JpYmUgbWV0aG9kLlxyXG4gICAgICovXHJcbiAgICBPYnNlcnZhYmxlLmNyZWF0ZSA9IE9ic2VydmFibGUuY3JlYXRlV2l0aERpc3Bvc2FibGUgPSBmdW5jdGlvbiAoc3Vic2NyaWJlKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKHN1YnNjcmliZSk7XHJcbiAgICB9O1xyXG5cclxuICAvKipcclxuICAgKiAgUmV0dXJucyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgaW52b2tlcyB0aGUgc3BlY2lmaWVkIGZhY3RvcnkgZnVuY3Rpb24gd2hlbmV2ZXIgYSBuZXcgb2JzZXJ2ZXIgc3Vic2NyaWJlcy5cclxuICAgKiAgXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiAgdmFyIHJlcyA9IFJ4Lk9ic2VydmFibGUuZGVmZXIoZnVuY3Rpb24gKCkgeyByZXR1cm4gUnguT2JzZXJ2YWJsZS5mcm9tQXJyYXkoWzEsMiwzXSk7IH0pOyAgICBcclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBvYnNlcnZhYmxlRmFjdG9yeSBPYnNlcnZhYmxlIGZhY3RvcnkgZnVuY3Rpb24gdG8gaW52b2tlIGZvciBlYWNoIG9ic2VydmVyIHRoYXQgc3Vic2NyaWJlcyB0byB0aGUgcmVzdWx0aW5nIHNlcXVlbmNlIG9yIFByb21pc2UuXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2Ugd2hvc2Ugb2JzZXJ2ZXJzIHRyaWdnZXIgYW4gaW52b2NhdGlvbiBvZiB0aGUgZ2l2ZW4gb2JzZXJ2YWJsZSBmYWN0b3J5IGZ1bmN0aW9uLlxyXG4gICAqL1xyXG4gIHZhciBvYnNlcnZhYmxlRGVmZXIgPSBPYnNlcnZhYmxlLmRlZmVyID0gZnVuY3Rpb24gKG9ic2VydmFibGVGYWN0b3J5KSB7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciByZXN1bHQ7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgcmVzdWx0ID0gb2JzZXJ2YWJsZUZhY3RvcnkoKTtcclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIHJldHVybiBvYnNlcnZhYmxlVGhyb3coZSkuc3Vic2NyaWJlKG9ic2VydmVyKTtcclxuICAgICAgfVxyXG4gICAgICBpc1Byb21pc2UocmVzdWx0KSAmJiAocmVzdWx0ID0gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKHJlc3VsdCkpO1xyXG4gICAgICByZXR1cm4gcmVzdWx0LnN1YnNjcmliZShvYnNlcnZlcik7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFJldHVybnMgYW4gZW1wdHkgb2JzZXJ2YWJsZSBzZXF1ZW5jZSwgdXNpbmcgdGhlIHNwZWNpZmllZCBzY2hlZHVsZXIgdG8gc2VuZCBvdXQgdGhlIHNpbmdsZSBPbkNvbXBsZXRlZCBtZXNzYWdlLlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICB2YXIgcmVzID0gUnguT2JzZXJ2YWJsZS5lbXB0eSgpOyAgXHJcbiAgICAgKiAgdmFyIHJlcyA9IFJ4Lk9ic2VydmFibGUuZW1wdHkoUnguU2NoZWR1bGVyLnRpbWVvdXQpOyAgXHJcbiAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gW3NjaGVkdWxlcl0gU2NoZWR1bGVyIHRvIHNlbmQgdGhlIHRlcm1pbmF0aW9uIGNhbGwgb24uXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aXRoIG5vIGVsZW1lbnRzLlxyXG4gICAgICovXHJcbiAgICB2YXIgb2JzZXJ2YWJsZUVtcHR5ID0gT2JzZXJ2YWJsZS5lbXB0eSA9IGZ1bmN0aW9uIChzY2hlZHVsZXIpIHtcclxuICAgICAgICBzY2hlZHVsZXIgfHwgKHNjaGVkdWxlciA9IGltbWVkaWF0ZVNjaGVkdWxlcik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gc2NoZWR1bGVyLnNjaGVkdWxlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogIENvbnZlcnRzIGFuIGFycmF5IHRvIGFuIG9ic2VydmFibGUgc2VxdWVuY2UsIHVzaW5nIGFuIG9wdGlvbmFsIHNjaGVkdWxlciB0byBlbnVtZXJhdGUgdGhlIGFycmF5LlxyXG4gICAqICBcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqICB2YXIgcmVzID0gUnguT2JzZXJ2YWJsZS5mcm9tQXJyYXkoWzEsMiwzXSk7XHJcbiAgICogIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLmZyb21BcnJheShbMSwyLDNdLCBSeC5TY2hlZHVsZXIudGltZW91dCk7XHJcbiAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtzY2hlZHVsZXJdIFNjaGVkdWxlciB0byBydW4gdGhlIGVudW1lcmF0aW9uIG9mIHRoZSBpbnB1dCBzZXF1ZW5jZSBvbi5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIG9ic2VydmFibGUgc2VxdWVuY2Ugd2hvc2UgZWxlbWVudHMgYXJlIHB1bGxlZCBmcm9tIHRoZSBnaXZlbiBlbnVtZXJhYmxlIHNlcXVlbmNlLlxyXG4gICAqL1xyXG4gIHZhciBvYnNlcnZhYmxlRnJvbUFycmF5ID0gT2JzZXJ2YWJsZS5mcm9tQXJyYXkgPSBmdW5jdGlvbiAoYXJyYXksIHNjaGVkdWxlcikge1xyXG4gICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSBjdXJyZW50VGhyZWFkU2NoZWR1bGVyKTtcclxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgdmFyIGNvdW50ID0gMCwgbGVuID0gYXJyYXkubGVuZ3RoO1xyXG4gICAgICByZXR1cm4gc2NoZWR1bGVyLnNjaGVkdWxlUmVjdXJzaXZlKGZ1bmN0aW9uIChzZWxmKSB7XHJcbiAgICAgICAgaWYgKGNvdW50IDwgbGVuKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQoYXJyYXlbY291bnQrK10pO1xyXG4gICAgICAgICAgc2VsZigpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiAgQ29udmVydHMgYW4gaXRlcmFibGUgaW50byBhbiBPYnNlcnZhYmxlIHNlcXVlbmNlXHJcbiAgICogIFxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLmZyb21JdGVyYWJsZShuZXcgTWFwKCkpO1xyXG4gICAqICB2YXIgcmVzID0gUnguT2JzZXJ2YWJsZS5mcm9tSXRlcmFibGUobmV3IFNldCgpLCBSeC5TY2hlZHVsZXIudGltZW91dCk7XHJcbiAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtzY2hlZHVsZXJdIFNjaGVkdWxlciB0byBydW4gdGhlIGVudW1lcmF0aW9uIG9mIHRoZSBpbnB1dCBzZXF1ZW5jZSBvbi5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIG9ic2VydmFibGUgc2VxdWVuY2Ugd2hvc2UgZWxlbWVudHMgYXJlIHB1bGxlZCBmcm9tIHRoZSBnaXZlbiBnZW5lcmF0b3Igc2VxdWVuY2UuXHJcbiAgICovXHJcbiAgT2JzZXJ2YWJsZS5mcm9tSXRlcmFibGUgPSBmdW5jdGlvbiAoaXRlcmFibGUsIHNjaGVkdWxlcikge1xyXG4gICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSBjdXJyZW50VGhyZWFkU2NoZWR1bGVyKTtcclxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgdmFyIGl0ZXJhdG9yO1xyXG4gICAgICB0cnkge1xyXG4gICAgICAgIGl0ZXJhdG9yID0gaXRlcmFibGVbJGl0ZXJhdG9yJF0oKTtcclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gc2NoZWR1bGVyLnNjaGVkdWxlUmVjdXJzaXZlKGZ1bmN0aW9uIChzZWxmKSB7XHJcbiAgICAgICAgdmFyIG5leHQ7XHJcbiAgICAgICAgdHJ5IHtcclxuICAgICAgICAgIG5leHQgPSBpdGVyYXRvci5uZXh0KCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGVycik7XHJcbiAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAobmV4dC5kb25lKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQobmV4dC52YWx1ZSk7XHJcbiAgICAgICAgICBzZWxmKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgR2VuZXJhdGVzIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgYnkgcnVubmluZyBhIHN0YXRlLWRyaXZlbiBsb29wIHByb2R1Y2luZyB0aGUgc2VxdWVuY2UncyBlbGVtZW50cywgdXNpbmcgdGhlIHNwZWNpZmllZCBzY2hlZHVsZXIgdG8gc2VuZCBvdXQgb2JzZXJ2ZXIgbWVzc2FnZXMuXHJcbiAgICAgKiAgXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLmdlbmVyYXRlKDAsIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4IDwgMTA7IH0sIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ICsgMTsgfSwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHg7IH0pO1xyXG4gICAgICogIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLmdlbmVyYXRlKDAsIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4IDwgMTA7IH0sIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ICsgMTsgfSwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHg7IH0sIFJ4LlNjaGVkdWxlci50aW1lb3V0KTtcclxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGluaXRpYWxTdGF0ZSBJbml0aWFsIHN0YXRlLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29uZGl0aW9uIENvbmRpdGlvbiB0byB0ZXJtaW5hdGUgZ2VuZXJhdGlvbiAodXBvbiByZXR1cm5pbmcgZmFsc2UpLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZSBJdGVyYXRpb24gc3RlcCBmdW5jdGlvbi5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlc3VsdFNlbGVjdG9yIFNlbGVjdG9yIGZ1bmN0aW9uIGZvciByZXN1bHRzIHByb2R1Y2VkIGluIHRoZSBzZXF1ZW5jZS5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSBTY2hlZHVsZXIgb24gd2hpY2ggdG8gcnVuIHRoZSBnZW5lcmF0b3IgbG9vcC4gSWYgbm90IHByb3ZpZGVkLCBkZWZhdWx0cyB0byBTY2hlZHVsZXIuY3VycmVudFRocmVhZC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBUaGUgZ2VuZXJhdGVkIHNlcXVlbmNlLlxyXG4gICAgICovXHJcbiAgICBPYnNlcnZhYmxlLmdlbmVyYXRlID0gZnVuY3Rpb24gKGluaXRpYWxTdGF0ZSwgY29uZGl0aW9uLCBpdGVyYXRlLCByZXN1bHRTZWxlY3Rvciwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSBjdXJyZW50VGhyZWFkU2NoZWR1bGVyKTtcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBmaXJzdCA9IHRydWUsIHN0YXRlID0gaW5pdGlhbFN0YXRlO1xyXG4gICAgICAgICAgICByZXR1cm4gc2NoZWR1bGVyLnNjaGVkdWxlUmVjdXJzaXZlKGZ1bmN0aW9uIChzZWxmKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgaGFzUmVzdWx0LCByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gaXRlcmF0ZShzdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGhhc1Jlc3VsdCA9IGNvbmRpdGlvbihzdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc1Jlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHRTZWxlY3RvcihzdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleGNlcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChoYXNSZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQocmVzdWx0KTtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmKCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogIFRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgT2JzZXJ2YWJsZSBpbnN0YW5jZSB3aXRoIGEgdmFyaWFibGUgbnVtYmVyIG9mIGFyZ3VtZW50cywgcmVnYXJkbGVzcyBvZiBudW1iZXIgb3IgdHlwZSBvZiB0aGUgYXJndW1lbnRzLlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLm9mKDEsMiwzKTtcclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIG9ic2VydmFibGUgc2VxdWVuY2Ugd2hvc2UgZWxlbWVudHMgYXJlIHB1bGxlZCBmcm9tIHRoZSBnaXZlbiBhcmd1bWVudHMuXHJcbiAgICovXHJcbiAgT2JzZXJ2YWJsZS5vZiA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBsZW4gPSBhcmd1bWVudHMubGVuZ3RoLCBhcmdzID0gbmV3IEFycmF5KGxlbik7XHJcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHsgYXJnc1tpXSA9IGFyZ3VtZW50c1tpXTsgfVxyXG4gICAgcmV0dXJuIG9ic2VydmFibGVGcm9tQXJyYXkoYXJncyk7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogIFRoaXMgbWV0aG9kIGNyZWF0ZXMgYSBuZXcgT2JzZXJ2YWJsZSBpbnN0YW5jZSB3aXRoIGEgdmFyaWFibGUgbnVtYmVyIG9mIGFyZ3VtZW50cywgcmVnYXJkbGVzcyBvZiBudW1iZXIgb3IgdHlwZSBvZiB0aGUgYXJndW1lbnRzLiBcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqICB2YXIgcmVzID0gUnguT2JzZXJ2YWJsZS5vZigxLDIsMyk7XHJcbiAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IHNjaGVkdWxlciBBIHNjaGVkdWxlciB0byB1c2UgZm9yIHNjaGVkdWxpbmcgdGhlIGFyZ3VtZW50cy5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIG9ic2VydmFibGUgc2VxdWVuY2Ugd2hvc2UgZWxlbWVudHMgYXJlIHB1bGxlZCBmcm9tIHRoZSBnaXZlbiBhcmd1bWVudHMuXHJcbiAgICovXHJcbiAgdmFyIG9ic2VydmFibGVPZiA9IE9ic2VydmFibGUub2ZXaXRoU2NoZWR1bGVyID0gZnVuY3Rpb24gKHNjaGVkdWxlcikge1xyXG4gICAgdmFyIGxlbiA9IGFyZ3VtZW50cy5sZW5ndGggLSAxLCBhcmdzID0gbmV3IEFycmF5KGxlbik7XHJcbiAgICBmb3IodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHsgYXJnc1tpXSA9IGFyZ3VtZW50c1tpICsgMV07IH1cclxuICAgIHJldHVybiBvYnNlcnZhYmxlRnJvbUFycmF5KGFyZ3MsIHNjaGVkdWxlcik7XHJcbiAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBSZXR1cm5zIGEgbm9uLXRlcm1pbmF0aW5nIG9ic2VydmFibGUgc2VxdWVuY2UsIHdoaWNoIGNhbiBiZSB1c2VkIHRvIGRlbm90ZSBhbiBpbmZpbml0ZSBkdXJhdGlvbiAoZS5nLiB3aGVuIHVzaW5nIHJlYWN0aXZlIGpvaW5zKS5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdob3NlIG9ic2VydmVycyB3aWxsIG5ldmVyIGdldCBjYWxsZWQuXHJcbiAgICAgKi9cclxuICAgIHZhciBvYnNlcnZhYmxlTmV2ZXIgPSBPYnNlcnZhYmxlLm5ldmVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBkaXNwb3NhYmxlRW1wdHk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIEdlbmVyYXRlcyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIG9mIGludGVncmFsIG51bWJlcnMgd2l0aGluIGEgc3BlY2lmaWVkIHJhbmdlLCB1c2luZyB0aGUgc3BlY2lmaWVkIHNjaGVkdWxlciB0byBzZW5kIG91dCBvYnNlcnZlciBtZXNzYWdlcy5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgdmFyIHJlcyA9IFJ4Lk9ic2VydmFibGUucmFuZ2UoMCwgMTApO1xyXG4gICAgICogIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLnJhbmdlKDAsIDEwLCBSeC5TY2hlZHVsZXIudGltZW91dCk7XHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gc3RhcnQgVGhlIHZhbHVlIG9mIHRoZSBmaXJzdCBpbnRlZ2VyIGluIHRoZSBzZXF1ZW5jZS5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjb3VudCBUaGUgbnVtYmVyIG9mIHNlcXVlbnRpYWwgaW50ZWdlcnMgdG8gZ2VuZXJhdGUuXHJcbiAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gW3NjaGVkdWxlcl0gU2NoZWR1bGVyIHRvIHJ1biB0aGUgZ2VuZXJhdG9yIGxvb3Agb24uIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIFNjaGVkdWxlci5jdXJyZW50VGhyZWFkLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBjb250YWlucyBhIHJhbmdlIG9mIHNlcXVlbnRpYWwgaW50ZWdyYWwgbnVtYmVycy5cclxuICAgICAqL1xyXG4gICAgT2JzZXJ2YWJsZS5yYW5nZSA9IGZ1bmN0aW9uIChzdGFydCwgY291bnQsIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHNjaGVkdWxlciB8fCAoc2NoZWR1bGVyID0gY3VycmVudFRocmVhZFNjaGVkdWxlcik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gc2NoZWR1bGVyLnNjaGVkdWxlUmVjdXJzaXZlV2l0aFN0YXRlKDAsIGZ1bmN0aW9uIChpLCBzZWxmKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaSA8IGNvdW50KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHN0YXJ0ICsgaSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZihpICsgMSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBHZW5lcmF0ZXMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHJlcGVhdHMgdGhlIGdpdmVuIGVsZW1lbnQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgdGltZXMsIHVzaW5nIHRoZSBzcGVjaWZpZWQgc2NoZWR1bGVyIHRvIHNlbmQgb3V0IG9ic2VydmVyIG1lc3NhZ2VzLlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICB2YXIgcmVzID0gUnguT2JzZXJ2YWJsZS5yZXBlYXQoNDIpO1xyXG4gICAgICogIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLnJlcGVhdCg0MiwgNCk7XHJcbiAgICAgKiAgMyAtIHJlcyA9IFJ4Lk9ic2VydmFibGUucmVwZWF0KDQyLCA0LCBSeC5TY2hlZHVsZXIudGltZW91dCk7XHJcbiAgICAgKiAgNCAtIHJlcyA9IFJ4Lk9ic2VydmFibGUucmVwZWF0KDQyLCBudWxsLCBSeC5TY2hlZHVsZXIudGltZW91dCk7XHJcbiAgICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZSBFbGVtZW50IHRvIHJlcGVhdC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSByZXBlYXRDb3VudCBbT3B0aW9uYV0gTnVtYmVyIG9mIHRpbWVzIHRvIHJlcGVhdCB0aGUgZWxlbWVudC4gSWYgbm90IHNwZWNpZmllZCwgcmVwZWF0cyBpbmRlZmluaXRlbHkuXHJcbiAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gc2NoZWR1bGVyIFNjaGVkdWxlciB0byBydW4gdGhlIHByb2R1Y2VyIGxvb3Agb24uIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIFNjaGVkdWxlci5pbW1lZGlhdGUuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHJlcGVhdHMgdGhlIGdpdmVuIGVsZW1lbnQgdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgdGltZXMuXHJcbiAgICAgKi9cclxuICAgIE9ic2VydmFibGUucmVwZWF0ID0gZnVuY3Rpb24gKHZhbHVlLCByZXBlYXRDb3VudCwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSBjdXJyZW50VGhyZWFkU2NoZWR1bGVyKTtcclxuICAgICAgICBpZiAocmVwZWF0Q291bnQgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICByZXBlYXRDb3VudCA9IC0xO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZVJldHVybih2YWx1ZSwgc2NoZWR1bGVyKS5yZXBlYXQocmVwZWF0Q291bnQpO1xyXG4gICAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogIFJldHVybnMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbnRhaW5zIGEgc2luZ2xlIGVsZW1lbnQsIHVzaW5nIHRoZSBzcGVjaWZpZWQgc2NoZWR1bGVyIHRvIHNlbmQgb3V0IG9ic2VydmVyIG1lc3NhZ2VzLlxyXG4gICAqICBUaGVyZSBpcyBhbiBhbGlhcyBjYWxsZWQgJ2p1c3QnLCBhbmQgJ3JldHVyblZhbHVlJyBmb3IgYnJvd3NlcnMgPElFOS5cclxuICAgKiAgXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiAgdmFyIHJlcyA9IFJ4Lk9ic2VydmFibGUucmV0dXJuKDQyKTtcclxuICAgKiAgdmFyIHJlcyA9IFJ4Lk9ic2VydmFibGUucmV0dXJuKDQyLCBSeC5TY2hlZHVsZXIudGltZW91dCk7XHJcbiAgICogQHBhcmFtIHtNaXhlZH0gdmFsdWUgU2luZ2xlIGVsZW1lbnQgaW4gdGhlIHJlc3VsdGluZyBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBzY2hlZHVsZXIgU2NoZWR1bGVyIHRvIHNlbmQgdGhlIHNpbmdsZSBlbGVtZW50IG9uLiBJZiBub3Qgc3BlY2lmaWVkLCBkZWZhdWx0cyB0byBTY2hlZHVsZXIuaW1tZWRpYXRlLlxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgdGhlIHNpbmdsZSBzcGVjaWZpZWQgZWxlbWVudC5cclxuICAgKi9cclxuICB2YXIgb2JzZXJ2YWJsZVJldHVybiA9IE9ic2VydmFibGVbJ3JldHVybiddID0gT2JzZXJ2YWJsZS5yZXR1cm5WYWx1ZSA9IE9ic2VydmFibGUuanVzdCA9IGZ1bmN0aW9uICh2YWx1ZSwgc2NoZWR1bGVyKSB7XHJcbiAgICBzY2hlZHVsZXIgfHwgKHNjaGVkdWxlciA9IGltbWVkaWF0ZVNjaGVkdWxlcik7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHJldHVybiBzY2hlZHVsZXIuc2NoZWR1bGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIG9ic2VydmVyLm9uTmV4dCh2YWx1ZSk7XHJcbiAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFJldHVybnMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHRlcm1pbmF0ZXMgd2l0aCBhbiBleGNlcHRpb24sIHVzaW5nIHRoZSBzcGVjaWZpZWQgc2NoZWR1bGVyIHRvIHNlbmQgb3V0IHRoZSBzaW5nbGUgb25FcnJvciBtZXNzYWdlLlxyXG4gICAgICogIFRoZXJlIGlzIGFuIGFsaWFzIHRvIHRoaXMgbWV0aG9kIGNhbGxlZCAndGhyb3dFeGNlcHRpb24nIGZvciBicm93c2VycyA8SUU5LlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICB2YXIgcmVzID0gUnguT2JzZXJ2YWJsZS50aHJvd0V4Y2VwdGlvbihuZXcgRXJyb3IoJ0Vycm9yJykpO1xyXG4gICAgICogIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLnRocm93RXhjZXB0aW9uKG5ldyBFcnJvcignRXJyb3InKSwgUnguU2NoZWR1bGVyLnRpbWVvdXQpO1xyXG4gICAgICogQHBhcmFtIHtNaXhlZH0gZXhjZXB0aW9uIEFuIG9iamVjdCB1c2VkIGZvciB0aGUgc2VxdWVuY2UncyB0ZXJtaW5hdGlvbi5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBzY2hlZHVsZXIgU2NoZWR1bGVyIHRvIHNlbmQgdGhlIGV4Y2VwdGlvbmFsIHRlcm1pbmF0aW9uIGNhbGwgb24uIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIFNjaGVkdWxlci5pbW1lZGlhdGUuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCB0ZXJtaW5hdGVzIGV4Y2VwdGlvbmFsbHkgd2l0aCB0aGUgc3BlY2lmaWVkIGV4Y2VwdGlvbiBvYmplY3QuXHJcbiAgICAgKi9cclxuICAgIHZhciBvYnNlcnZhYmxlVGhyb3cgPSBPYnNlcnZhYmxlWyd0aHJvdyddID0gT2JzZXJ2YWJsZS50aHJvd0V4Y2VwdGlvbiA9IGZ1bmN0aW9uIChleGNlcHRpb24sIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHNjaGVkdWxlciB8fCAoc2NoZWR1bGVyID0gaW1tZWRpYXRlU2NoZWR1bGVyKTtcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzY2hlZHVsZXIuc2NoZWR1bGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleGNlcHRpb24pO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gIC8qKlxyXG4gICAqICBDb25zdHJ1Y3RzIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBkZXBlbmRzIG9uIGEgcmVzb3VyY2Ugb2JqZWN0LCB3aG9zZSBsaWZldGltZSBpcyB0aWVkIHRvIHRoZSByZXN1bHRpbmcgb2JzZXJ2YWJsZSBzZXF1ZW5jZSdzIGxpZmV0aW1lLlxyXG4gICAqICBcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqICB2YXIgcmVzID0gUnguT2JzZXJ2YWJsZS51c2luZyhmdW5jdGlvbiAoKSB7IHJldHVybiBuZXcgQXN5bmNTdWJqZWN0KCk7IH0sIGZ1bmN0aW9uIChzKSB7IHJldHVybiBzOyB9KTtcclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSByZXNvdXJjZUZhY3RvcnkgRmFjdG9yeSBmdW5jdGlvbiB0byBvYnRhaW4gYSByZXNvdXJjZSBvYmplY3QuXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gb2JzZXJ2YWJsZUZhY3RvcnkgRmFjdG9yeSBmdW5jdGlvbiB0byBvYnRhaW4gYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGRlcGVuZHMgb24gdGhlIG9idGFpbmVkIHJlc291cmNlLlxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdob3NlIGxpZmV0aW1lIGNvbnRyb2xzIHRoZSBsaWZldGltZSBvZiB0aGUgZGVwZW5kZW50IHJlc291cmNlIG9iamVjdC5cclxuICAgKi9cclxuICBPYnNlcnZhYmxlLnVzaW5nID0gZnVuY3Rpb24gKHJlc291cmNlRmFjdG9yeSwgb2JzZXJ2YWJsZUZhY3RvcnkpIHtcclxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgdmFyIGRpc3Bvc2FibGUgPSBkaXNwb3NhYmxlRW1wdHksIHJlc291cmNlLCBzb3VyY2U7XHJcbiAgICAgIHRyeSB7XHJcbiAgICAgICAgcmVzb3VyY2UgPSByZXNvdXJjZUZhY3RvcnkoKTtcclxuICAgICAgICBpZiAocmVzb3VyY2UpIHtcclxuICAgICAgICAgIGRpc3Bvc2FibGUgPSByZXNvdXJjZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgc291cmNlID0gb2JzZXJ2YWJsZUZhY3RvcnkocmVzb3VyY2UpO1xyXG4gICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcclxuICAgICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUob2JzZXJ2YWJsZVRocm93KGV4Y2VwdGlvbikuc3Vic2NyaWJlKG9ic2VydmVyKSwgZGlzcG9zYWJsZSk7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKHNvdXJjZS5zdWJzY3JpYmUob2JzZXJ2ZXIpLCBkaXNwb3NhYmxlKTtcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFByb3BhZ2F0ZXMgdGhlIG9ic2VydmFibGUgc2VxdWVuY2Ugb3IgUHJvbWlzZSB0aGF0IHJlYWN0cyBmaXJzdC5cclxuICAgKiBAcGFyYW0ge09ic2VydmFibGV9IHJpZ2h0U291cmNlIFNlY29uZCBvYnNlcnZhYmxlIHNlcXVlbmNlIG9yIFByb21pc2UuXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc3VyZmFjZXMgZWl0aGVyIG9mIHRoZSBnaXZlbiBzZXF1ZW5jZXMsIHdoaWNoZXZlciByZWFjdGVkIGZpcnN0LlxyXG4gICAqLyAgXHJcbiAgb2JzZXJ2YWJsZVByb3RvLmFtYiA9IGZ1bmN0aW9uIChyaWdodFNvdXJjZSkge1xyXG4gICAgdmFyIGxlZnRTb3VyY2UgPSB0aGlzO1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICB2YXIgY2hvaWNlLFxyXG4gICAgICAgIGxlZnRDaG9pY2UgPSAnTCcsIHJpZ2h0Q2hvaWNlID0gJ1InLFxyXG4gICAgICAgIGxlZnRTdWJzY3JpcHRpb24gPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKSxcclxuICAgICAgICByaWdodFN1YnNjcmlwdGlvbiA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpO1xyXG5cclxuICAgICAgaXNQcm9taXNlKHJpZ2h0U291cmNlKSAmJiAocmlnaHRTb3VyY2UgPSBvYnNlcnZhYmxlRnJvbVByb21pc2UocmlnaHRTb3VyY2UpKTtcclxuXHJcbiAgICAgIGZ1bmN0aW9uIGNob2ljZUwoKSB7XHJcbiAgICAgICAgaWYgKCFjaG9pY2UpIHtcclxuICAgICAgICAgIGNob2ljZSA9IGxlZnRDaG9pY2U7XHJcbiAgICAgICAgICByaWdodFN1YnNjcmlwdGlvbi5kaXNwb3NlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBmdW5jdGlvbiBjaG9pY2VSKCkge1xyXG4gICAgICAgIGlmICghY2hvaWNlKSB7XHJcbiAgICAgICAgICBjaG9pY2UgPSByaWdodENob2ljZTtcclxuICAgICAgICAgIGxlZnRTdWJzY3JpcHRpb24uZGlzcG9zZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgbGVmdFN1YnNjcmlwdGlvbi5zZXREaXNwb3NhYmxlKGxlZnRTb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uIChsZWZ0KSB7XHJcbiAgICAgICAgY2hvaWNlTCgpO1xyXG4gICAgICAgIGlmIChjaG9pY2UgPT09IGxlZnRDaG9pY2UpIHtcclxuICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChsZWZ0KTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIGZ1bmN0aW9uIChlcnIpIHtcclxuICAgICAgICBjaG9pY2VMKCk7XHJcbiAgICAgICAgaWYgKGNob2ljZSA9PT0gbGVmdENob2ljZSkge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlcnIpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGNob2ljZUwoKTtcclxuICAgICAgICBpZiAoY2hvaWNlID09PSBsZWZ0Q2hvaWNlKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSkpO1xyXG5cclxuICAgICAgcmlnaHRTdWJzY3JpcHRpb24uc2V0RGlzcG9zYWJsZShyaWdodFNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHJpZ2h0KSB7XHJcbiAgICAgICAgY2hvaWNlUigpO1xyXG4gICAgICAgIGlmIChjaG9pY2UgPT09IHJpZ2h0Q2hvaWNlKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQocmlnaHQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSwgZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgIGNob2ljZVIoKTtcclxuICAgICAgICBpZiAoY2hvaWNlID09PSByaWdodENob2ljZSkge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlcnIpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGNob2ljZVIoKTtcclxuICAgICAgICBpZiAoY2hvaWNlID09PSByaWdodENob2ljZSkge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pKTtcclxuXHJcbiAgICAgIHJldHVybiBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZShsZWZ0U3Vic2NyaXB0aW9uLCByaWdodFN1YnNjcmlwdGlvbik7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBQcm9wYWdhdGVzIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIG9yIFByb21pc2UgdGhhdCByZWFjdHMgZmlyc3QuXHJcbiAgICpcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqIHZhciA9IFJ4Lk9ic2VydmFibGUuYW1iKHhzLCB5cywgenMpO1xyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc3VyZmFjZXMgYW55IG9mIHRoZSBnaXZlbiBzZXF1ZW5jZXMsIHdoaWNoZXZlciByZWFjdGVkIGZpcnN0LlxyXG4gICAqLyAgXHJcbiAgT2JzZXJ2YWJsZS5hbWIgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgYWNjID0gb2JzZXJ2YWJsZU5ldmVyKCksXHJcbiAgICAgIGl0ZW1zID0gYXJnc09yQXJyYXkoYXJndW1lbnRzLCAwKTtcclxuICAgIGZ1bmN0aW9uIGZ1bmMocHJldmlvdXMsIGN1cnJlbnQpIHtcclxuICAgICAgcmV0dXJuIHByZXZpb3VzLmFtYihjdXJyZW50KTtcclxuICAgIH1cclxuICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBpdGVtcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICBhY2MgPSBmdW5jKGFjYywgaXRlbXNbaV0pO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGFjYztcclxuICB9O1xyXG5cclxuICBmdW5jdGlvbiBvYnNlcnZhYmxlQ2F0Y2hIYW5kbGVyKHNvdXJjZSwgaGFuZGxlcikge1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICB2YXIgZDEgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKSwgc3Vic2NyaXB0aW9uID0gbmV3IFNlcmlhbERpc3Bvc2FibGUoKTtcclxuICAgICAgc3Vic2NyaXB0aW9uLnNldERpc3Bvc2FibGUoZDEpO1xyXG4gICAgICBkMS5zZXREaXNwb3NhYmxlKHNvdXJjZS5zdWJzY3JpYmUob2JzZXJ2ZXIub25OZXh0LmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XHJcbiAgICAgICAgdmFyIGQsIHJlc3VsdDtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgcmVzdWx0ID0gaGFuZGxlcihleGNlcHRpb24pO1xyXG4gICAgICAgIH0gY2F0Y2ggKGV4KSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGV4KTtcclxuICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcbiAgICAgICAgaXNQcm9taXNlKHJlc3VsdCkgJiYgKHJlc3VsdCA9IG9ic2VydmFibGVGcm9tUHJvbWlzZShyZXN1bHQpKTtcclxuXHJcbiAgICAgICAgZCA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpO1xyXG4gICAgICAgIHN1YnNjcmlwdGlvbi5zZXREaXNwb3NhYmxlKGQpO1xyXG4gICAgICAgIGQuc2V0RGlzcG9zYWJsZShyZXN1bHQuc3Vic2NyaWJlKG9ic2VydmVyKSk7XHJcbiAgICAgIH0sIG9ic2VydmVyLm9uQ29tcGxldGVkLmJpbmQob2JzZXJ2ZXIpKSk7XHJcbiAgICAgIFxyXG4gICAgICByZXR1cm4gc3Vic2NyaXB0aW9uO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBDb250aW51ZXMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGlzIHRlcm1pbmF0ZWQgYnkgYW4gZXhjZXB0aW9uIHdpdGggdGhlIG5leHQgb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgKiBAZXhhbXBsZVxyXG4gICAqIDEgLSB4cy5jYXRjaEV4Y2VwdGlvbih5cylcclxuICAgKiAyIC0geHMuY2F0Y2hFeGNlcHRpb24oZnVuY3Rpb24gKGV4KSB7IHJldHVybiB5cyhleCk7IH0pXHJcbiAgICogQHBhcmFtIHtNaXhlZH0gaGFuZGxlck9yU2Vjb25kIEV4Y2VwdGlvbiBoYW5kbGVyIGZ1bmN0aW9uIHRoYXQgcmV0dXJucyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGdpdmVuIHRoZSBlcnJvciB0aGF0IG9jY3VycmVkIGluIHRoZSBmaXJzdCBzZXF1ZW5jZSwgb3IgYSBzZWNvbmQgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB1c2VkIHRvIHByb2R1Y2UgcmVzdWx0cyB3aGVuIGFuIGVycm9yIG9jY3VycmVkIGluIHRoZSBmaXJzdCBzZXF1ZW5jZS5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBjb250YWluaW5nIHRoZSBmaXJzdCBzZXF1ZW5jZSdzIGVsZW1lbnRzLCBmb2xsb3dlZCBieSB0aGUgZWxlbWVudHMgb2YgdGhlIGhhbmRsZXIgc2VxdWVuY2UgaW4gY2FzZSBhbiBleGNlcHRpb24gb2NjdXJyZWQuXHJcbiAgICovICAgICAgXHJcbiAgb2JzZXJ2YWJsZVByb3RvWydjYXRjaCddID0gb2JzZXJ2YWJsZVByb3RvLmNhdGNoRXhjZXB0aW9uID0gZnVuY3Rpb24gKGhhbmRsZXJPclNlY29uZCkge1xyXG4gICAgcmV0dXJuIHR5cGVvZiBoYW5kbGVyT3JTZWNvbmQgPT09ICdmdW5jdGlvbicgP1xyXG4gICAgICBvYnNlcnZhYmxlQ2F0Y2hIYW5kbGVyKHRoaXMsIGhhbmRsZXJPclNlY29uZCkgOlxyXG4gICAgICBvYnNlcnZhYmxlQ2F0Y2goW3RoaXMsIGhhbmRsZXJPclNlY29uZF0pO1xyXG4gIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb250aW51ZXMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGlzIHRlcm1pbmF0ZWQgYnkgYW4gZXhjZXB0aW9uIHdpdGggdGhlIG5leHQgb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIDEgLSByZXMgPSBSeC5PYnNlcnZhYmxlLmNhdGNoRXhjZXB0aW9uKHhzLCB5cywgenMpO1xyXG4gICAgICogMiAtIHJlcyA9IFJ4Lk9ic2VydmFibGUuY2F0Y2hFeGNlcHRpb24oW3hzLCB5cywgenNdKTtcclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgZWxlbWVudHMgZnJvbSBjb25zZWN1dGl2ZSBzb3VyY2Ugc2VxdWVuY2VzIHVudGlsIGEgc291cmNlIHNlcXVlbmNlIHRlcm1pbmF0ZXMgc3VjY2Vzc2Z1bGx5LlxyXG4gICAgICovXHJcbiAgICB2YXIgb2JzZXJ2YWJsZUNhdGNoID0gT2JzZXJ2YWJsZS5jYXRjaEV4Y2VwdGlvbiA9IE9ic2VydmFibGVbJ2NhdGNoJ10gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGl0ZW1zID0gYXJnc09yQXJyYXkoYXJndW1lbnRzLCAwKTtcclxuICAgICAgICByZXR1cm4gZW51bWVyYWJsZUZvcihpdGVtcykuY2F0Y2hFeGNlcHRpb24oKTtcclxuICAgIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIE1lcmdlcyB0aGUgc3BlY2lmaWVkIG9ic2VydmFibGUgc2VxdWVuY2VzIGludG8gb25lIG9ic2VydmFibGUgc2VxdWVuY2UgYnkgdXNpbmcgdGhlIHNlbGVjdG9yIGZ1bmN0aW9uIHdoZW5ldmVyIGFueSBvZiB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZXMgb3IgUHJvbWlzZXMgcHJvZHVjZXMgYW4gZWxlbWVudC5cclxuICAgKiBUaGlzIGNhbiBiZSBpbiB0aGUgZm9ybSBvZiBhbiBhcmd1bWVudCBsaXN0IG9mIG9ic2VydmFibGVzIG9yIGFuIGFycmF5LlxyXG4gICAqXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiAxIC0gb2JzID0gb2JzZXJ2YWJsZS5jb21iaW5lTGF0ZXN0KG9iczEsIG9iczIsIG9iczMsIGZ1bmN0aW9uIChvMSwgbzIsIG8zKSB7IHJldHVybiBvMSArIG8yICsgbzM7IH0pO1xyXG4gICAqIDIgLSBvYnMgPSBvYnNlcnZhYmxlLmNvbWJpbmVMYXRlc3QoW29iczEsIG9iczIsIG9iczNdLCBmdW5jdGlvbiAobzEsIG8yLCBvMykgeyByZXR1cm4gbzEgKyBvMiArIG8zOyB9KTtcclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBjb250YWluaW5nIHRoZSByZXN1bHQgb2YgY29tYmluaW5nIGVsZW1lbnRzIG9mIHRoZSBzb3VyY2VzIHVzaW5nIHRoZSBzcGVjaWZpZWQgcmVzdWx0IHNlbGVjdG9yIGZ1bmN0aW9uLiBcclxuICAgKi9cclxuICBvYnNlcnZhYmxlUHJvdG8uY29tYmluZUxhdGVzdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBhcmdzID0gc2xpY2UuY2FsbChhcmd1bWVudHMpO1xyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnc1swXSkpIHtcclxuICAgICAgYXJnc1swXS51bnNoaWZ0KHRoaXMpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgYXJncy51bnNoaWZ0KHRoaXMpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIGNvbWJpbmVMYXRlc3QuYXBwbHkodGhpcywgYXJncyk7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogTWVyZ2VzIHRoZSBzcGVjaWZpZWQgb2JzZXJ2YWJsZSBzZXF1ZW5jZXMgaW50byBvbmUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSBieSB1c2luZyB0aGUgc2VsZWN0b3IgZnVuY3Rpb24gd2hlbmV2ZXIgYW55IG9mIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlcyBvciBQcm9taXNlcyBwcm9kdWNlcyBhbiBlbGVtZW50LlxyXG4gICAqIFxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogMSAtIG9icyA9IFJ4Lk9ic2VydmFibGUuY29tYmluZUxhdGVzdChvYnMxLCBvYnMyLCBvYnMzLCBmdW5jdGlvbiAobzEsIG8yLCBvMykgeyByZXR1cm4gbzEgKyBvMiArIG8zOyB9KTtcclxuICAgKiAyIC0gb2JzID0gUnguT2JzZXJ2YWJsZS5jb21iaW5lTGF0ZXN0KFtvYnMxLCBvYnMyLCBvYnMzXSwgZnVuY3Rpb24gKG8xLCBvMiwgbzMpIHsgcmV0dXJuIG8xICsgbzIgKyBvMzsgfSk7ICAgICBcclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBjb250YWluaW5nIHRoZSByZXN1bHQgb2YgY29tYmluaW5nIGVsZW1lbnRzIG9mIHRoZSBzb3VyY2VzIHVzaW5nIHRoZSBzcGVjaWZpZWQgcmVzdWx0IHNlbGVjdG9yIGZ1bmN0aW9uLlxyXG4gICAqL1xyXG4gIHZhciBjb21iaW5lTGF0ZXN0ID0gT2JzZXJ2YWJsZS5jb21iaW5lTGF0ZXN0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cyksIHJlc3VsdFNlbGVjdG9yID0gYXJncy5wb3AoKTtcclxuICAgIFxyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoYXJnc1swXSkpIHtcclxuICAgICAgYXJncyA9IGFyZ3NbMF07XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICB2YXIgZmFsc2VGYWN0b3J5ID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFsc2U7IH0sXHJcbiAgICAgICAgbiA9IGFyZ3MubGVuZ3RoLFxyXG4gICAgICAgIGhhc1ZhbHVlID0gYXJyYXlJbml0aWFsaXplKG4sIGZhbHNlRmFjdG9yeSksXHJcbiAgICAgICAgaGFzVmFsdWVBbGwgPSBmYWxzZSxcclxuICAgICAgICBpc0RvbmUgPSBhcnJheUluaXRpYWxpemUobiwgZmFsc2VGYWN0b3J5KSxcclxuICAgICAgICB2YWx1ZXMgPSBuZXcgQXJyYXkobik7XHJcblxyXG4gICAgICBmdW5jdGlvbiBuZXh0KGkpIHtcclxuICAgICAgICB2YXIgcmVzO1xyXG4gICAgICAgIGhhc1ZhbHVlW2ldID0gdHJ1ZTtcclxuICAgICAgICBpZiAoaGFzVmFsdWVBbGwgfHwgKGhhc1ZhbHVlQWxsID0gaGFzVmFsdWUuZXZlcnkoaWRlbnRpdHkpKSkge1xyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmVzID0gcmVzdWx0U2VsZWN0b3IuYXBwbHkobnVsbCwgdmFsdWVzKTtcclxuICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXgpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQocmVzKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGlzRG9uZS5maWx0ZXIoZnVuY3Rpb24gKHgsIGopIHsgcmV0dXJuIGogIT09IGk7IH0pLmV2ZXJ5KGlkZW50aXR5KSkge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGZ1bmN0aW9uIGRvbmUgKGkpIHtcclxuICAgICAgICBpc0RvbmVbaV0gPSB0cnVlO1xyXG4gICAgICAgIGlmIChpc0RvbmUuZXZlcnkoaWRlbnRpdHkpKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG5cclxuICAgICAgdmFyIHN1YnNjcmlwdGlvbnMgPSBuZXcgQXJyYXkobik7XHJcbiAgICAgIGZvciAodmFyIGlkeCA9IDA7IGlkeCA8IG47IGlkeCsrKSB7XHJcbiAgICAgICAgKGZ1bmN0aW9uIChpKSB7XHJcbiAgICAgICAgICB2YXIgc291cmNlID0gYXJnc1tpXSwgc2FkID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCk7XHJcbiAgICAgICAgICBpc1Byb21pc2Uoc291cmNlKSAmJiAoc291cmNlID0gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKHNvdXJjZSkpO1xyXG4gICAgICAgICAgc2FkLnNldERpc3Bvc2FibGUoc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICB2YWx1ZXNbaV0gPSB4O1xyXG4gICAgICAgICAgICBuZXh0KGkpO1xyXG4gICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBkb25lKGkpO1xyXG4gICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgc3Vic2NyaXB0aW9uc1tpXSA9IHNhZDtcclxuICAgICAgICB9KGlkeCkpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc3Vic2NyaXB0aW9ucyk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uY2F0ZW5hdGVzIGFsbCB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZXMuICBUaGlzIHRha2VzIGluIGVpdGhlciBhbiBhcnJheSBvciB2YXJpYWJsZSBhcmd1bWVudHMgdG8gY29uY2F0ZW5hdGUuXHJcbiAgICAgKiBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAxIC0gY29uY2F0ZW5hdGVkID0geHMuY29uY2F0KHlzLCB6cyk7XHJcbiAgICAgKiAyIC0gY29uY2F0ZW5hdGVkID0geHMuY29uY2F0KFt5cywgenNdKTtcclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgY29udGFpbnMgdGhlIGVsZW1lbnRzIG9mIGVhY2ggZ2l2ZW4gc2VxdWVuY2UsIGluIHNlcXVlbnRpYWwgb3JkZXIuIFxyXG4gICAgICovIFxyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmNvbmNhdCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgaXRlbXMgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMCk7XHJcbiAgICAgICAgaXRlbXMudW5zaGlmdCh0aGlzKTtcclxuICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZUNvbmNhdC5hcHBseSh0aGlzLCBpdGVtcyk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29uY2F0ZW5hdGVzIGFsbCB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZXMuXHJcbiAgICAgKiBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAxIC0gcmVzID0gUnguT2JzZXJ2YWJsZS5jb25jYXQoeHMsIHlzLCB6cyk7XHJcbiAgICAgKiAyIC0gcmVzID0gUnguT2JzZXJ2YWJsZS5jb25jYXQoW3hzLCB5cywgenNdKTtcclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgY29udGFpbnMgdGhlIGVsZW1lbnRzIG9mIGVhY2ggZ2l2ZW4gc2VxdWVuY2UsIGluIHNlcXVlbnRpYWwgb3JkZXIuIFxyXG4gICAgICovXHJcbiAgICB2YXIgb2JzZXJ2YWJsZUNvbmNhdCA9IE9ic2VydmFibGUuY29uY2F0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBzb3VyY2VzID0gYXJnc09yQXJyYXkoYXJndW1lbnRzLCAwKTtcclxuICAgICAgICByZXR1cm4gZW51bWVyYWJsZUZvcihzb3VyY2VzKS5jb25jYXQoKTtcclxuICAgIH07ICBcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbmNhdGVuYXRlcyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIG9mIG9ic2VydmFibGUgc2VxdWVuY2VzLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBjb250YWlucyB0aGUgZWxlbWVudHMgb2YgZWFjaCBvYnNlcnZlZCBpbm5lciBzZXF1ZW5jZSwgaW4gc2VxdWVudGlhbCBvcmRlci4gXHJcbiAgICAgKi8gXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uY29uY2F0T2JzZXJ2YWJsZSA9IG9ic2VydmFibGVQcm90by5jb25jYXRBbGwgPWZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5tZXJnZSgxKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBNZXJnZXMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBvZiBvYnNlcnZhYmxlIHNlcXVlbmNlcyBpbnRvIGFuIG9ic2VydmFibGUgc2VxdWVuY2UsIGxpbWl0aW5nIHRoZSBudW1iZXIgb2YgY29uY3VycmVudCBzdWJzY3JpcHRpb25zIHRvIGlubmVyIHNlcXVlbmNlcy5cclxuICAgICAqIE9yIG1lcmdlcyB0d28gb2JzZXJ2YWJsZSBzZXF1ZW5jZXMgaW50byBhIHNpbmdsZSBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogMSAtIG1lcmdlZCA9IHNvdXJjZXMubWVyZ2UoMSk7XHJcbiAgICAgKiAyIC0gbWVyZ2VkID0gc291cmNlLm1lcmdlKG90aGVyU291cmNlKTsgIFxyXG4gICAgICogQHBhcmFtIHtNaXhlZH0gW21heENvbmN1cnJlbnRPck90aGVyXSBNYXhpbXVtIG51bWJlciBvZiBpbm5lciBvYnNlcnZhYmxlIHNlcXVlbmNlcyBiZWluZyBzdWJzY3JpYmVkIHRvIGNvbmN1cnJlbnRseSBvciB0aGUgc2Vjb25kIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBtZXJnZXMgdGhlIGVsZW1lbnRzIG9mIHRoZSBpbm5lciBzZXF1ZW5jZXMuIFxyXG4gICAgICovIFxyXG4gICAgb2JzZXJ2YWJsZVByb3RvLm1lcmdlID0gZnVuY3Rpb24gKG1heENvbmN1cnJlbnRPck90aGVyKSB7XHJcbiAgICAgICAgaWYgKHR5cGVvZiBtYXhDb25jdXJyZW50T3JPdGhlciAhPT0gJ251bWJlcicpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVNZXJnZSh0aGlzLCBtYXhDb25jdXJyZW50T3JPdGhlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBzb3VyY2VzID0gdGhpcztcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBhY3RpdmVDb3VudCA9IDAsXHJcbiAgICAgICAgICAgICAgICBncm91cCA9IG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKCksXHJcbiAgICAgICAgICAgICAgICBpc1N0b3BwZWQgPSBmYWxzZSxcclxuICAgICAgICAgICAgICAgIHEgPSBbXSxcclxuICAgICAgICAgICAgICAgIHN1YnNjcmliZSA9IGZ1bmN0aW9uICh4cykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzdWJzY3JpcHRpb24gPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgICAgICAgICBncm91cC5hZGQoc3Vic2NyaXB0aW9uKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIHByb21pc2VzIHN1cHBvcnRcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaXNQcm9taXNlKHhzKSkgeyB4cyA9IG9ic2VydmFibGVGcm9tUHJvbWlzZSh4cyk7IH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnNldERpc3Bvc2FibGUoeHMuc3Vic2NyaWJlKG9ic2VydmVyLm9uTmV4dC5iaW5kKG9ic2VydmVyKSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcztcclxuICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXAucmVtb3ZlKHN1YnNjcmlwdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBxLnNoaWZ0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmUocyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVDb3VudC0tO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlzU3RvcHBlZCAmJiBhY3RpdmVDb3VudCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBncm91cC5hZGQoc291cmNlcy5zdWJzY3JpYmUoZnVuY3Rpb24gKGlubmVyU291cmNlKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYWN0aXZlQ291bnQgPCBtYXhDb25jdXJyZW50T3JPdGhlcikge1xyXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZUNvdW50Kys7XHJcbiAgICAgICAgICAgICAgICAgICAgc3Vic2NyaWJlKGlubmVyU291cmNlKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcS5wdXNoKGlubmVyU291cmNlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaXNTdG9wcGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGlmIChhY3RpdmVDb3VudCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgcmV0dXJuIGdyb3VwO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1lcmdlcyBhbGwgdGhlIG9ic2VydmFibGUgc2VxdWVuY2VzIGludG8gYSBzaW5nbGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZS4gIFxyXG4gICAgICogVGhlIHNjaGVkdWxlciBpcyBvcHRpb25hbCBhbmQgaWYgbm90IHNwZWNpZmllZCwgdGhlIGltbWVkaWF0ZSBzY2hlZHVsZXIgaXMgdXNlZC5cclxuICAgICAqIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIDEgLSBtZXJnZWQgPSBSeC5PYnNlcnZhYmxlLm1lcmdlKHhzLCB5cywgenMpO1xyXG4gICAgICogMiAtIG1lcmdlZCA9IFJ4Lk9ic2VydmFibGUubWVyZ2UoW3hzLCB5cywgenNdKTtcclxuICAgICAqIDMgLSBtZXJnZWQgPSBSeC5PYnNlcnZhYmxlLm1lcmdlKHNjaGVkdWxlciwgeHMsIHlzLCB6cyk7XHJcbiAgICAgKiA0IC0gbWVyZ2VkID0gUnguT2JzZXJ2YWJsZS5tZXJnZShzY2hlZHVsZXIsIFt4cywgeXMsIHpzXSk7ICAgIFxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgbWVyZ2VzIHRoZSBlbGVtZW50cyBvZiB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZXMuIFxyXG4gICAgICovICBcclxuICAgIHZhciBvYnNlcnZhYmxlTWVyZ2UgPSBPYnNlcnZhYmxlLm1lcmdlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBzY2hlZHVsZXIsIHNvdXJjZXM7XHJcbiAgICAgICAgaWYgKCFhcmd1bWVudHNbMF0pIHtcclxuICAgICAgICAgICAgc2NoZWR1bGVyID0gaW1tZWRpYXRlU2NoZWR1bGVyO1xyXG4gICAgICAgICAgICBzb3VyY2VzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDEpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoYXJndW1lbnRzWzBdLm5vdykge1xyXG4gICAgICAgICAgICBzY2hlZHVsZXIgPSBhcmd1bWVudHNbMF07XHJcbiAgICAgICAgICAgIHNvdXJjZXMgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgc2NoZWR1bGVyID0gaW1tZWRpYXRlU2NoZWR1bGVyO1xyXG4gICAgICAgICAgICBzb3VyY2VzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIDApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShzb3VyY2VzWzBdKSkge1xyXG4gICAgICAgICAgICBzb3VyY2VzID0gc291cmNlc1swXTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG9ic2VydmFibGVGcm9tQXJyYXkoc291cmNlcywgc2NoZWR1bGVyKS5tZXJnZU9ic2VydmFibGUoKTtcclxuICAgIH07ICAgXHJcblxyXG4gIC8qKlxyXG4gICAqIE1lcmdlcyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIG9mIG9ic2VydmFibGUgc2VxdWVuY2VzIGludG8gYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBtZXJnZXMgdGhlIGVsZW1lbnRzIG9mIHRoZSBpbm5lciBzZXF1ZW5jZXMuICAgXHJcbiAgICovICBcclxuICBvYnNlcnZhYmxlUHJvdG8ubWVyZ2VPYnNlcnZhYmxlID0gb2JzZXJ2YWJsZVByb3RvLm1lcmdlQWxsID1mdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgc291cmNlcyA9IHRoaXM7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciBncm91cCA9IG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKCksXHJcbiAgICAgICAgaXNTdG9wcGVkID0gZmFsc2UsXHJcbiAgICAgICAgbSA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpO1xyXG5cclxuICAgICAgZ3JvdXAuYWRkKG0pO1xyXG4gICAgICBtLnNldERpc3Bvc2FibGUoc291cmNlcy5zdWJzY3JpYmUoZnVuY3Rpb24gKGlubmVyU291cmNlKSB7XHJcbiAgICAgICAgdmFyIGlubmVyU3Vic2NyaXB0aW9uID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCk7XHJcbiAgICAgICAgZ3JvdXAuYWRkKGlubmVyU3Vic2NyaXB0aW9uKTtcclxuXHJcbiAgICAgICAgLy8gQ2hlY2sgaWYgUHJvbWlzZSBvciBPYnNlcnZhYmxlXHJcbiAgICAgICAgaWYgKGlzUHJvbWlzZShpbm5lclNvdXJjZSkpIHtcclxuICAgICAgICAgICAgaW5uZXJTb3VyY2UgPSBvYnNlcnZhYmxlRnJvbVByb21pc2UoaW5uZXJTb3VyY2UpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaW5uZXJTdWJzY3JpcHRpb24uc2V0RGlzcG9zYWJsZShpbm5lclNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHgpO1xyXG4gICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgZ3JvdXAucmVtb3ZlKGlubmVyU3Vic2NyaXB0aW9uKTtcclxuICAgICAgICAgICAgaWYgKGlzU3RvcHBlZCAmJiBncm91cC5sZW5ndGggPT09IDEpIHsgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTsgfVxyXG4gICAgICAgIH0pKTtcclxuICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGlzU3RvcHBlZCA9IHRydWU7XHJcbiAgICAgICAgaWYgKGdyb3VwLmxlbmd0aCA9PT0gMSkgeyBvYnNlcnZlci5vbkNvbXBsZXRlZCgpOyB9XHJcbiAgICAgIH0pKTtcclxuICAgICAgcmV0dXJuIGdyb3VwO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogQ29udGludWVzIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBpcyB0ZXJtaW5hdGVkIG5vcm1hbGx5IG9yIGJ5IGFuIGV4Y2VwdGlvbiB3aXRoIHRoZSBuZXh0IG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICogQHBhcmFtIHtPYnNlcnZhYmxlfSBzZWNvbmQgU2Vjb25kIG9ic2VydmFibGUgc2VxdWVuY2UgdXNlZCB0byBwcm9kdWNlIHJlc3VsdHMgYWZ0ZXIgdGhlIGZpcnN0IHNlcXVlbmNlIHRlcm1pbmF0ZXMuXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBjb25jYXRlbmF0ZXMgdGhlIGZpcnN0IGFuZCBzZWNvbmQgc2VxdWVuY2UsIGV2ZW4gaWYgdGhlIGZpcnN0IHNlcXVlbmNlIHRlcm1pbmF0ZXMgZXhjZXB0aW9uYWxseS5cclxuICAgKi9cclxuICBvYnNlcnZhYmxlUHJvdG8ub25FcnJvclJlc3VtZU5leHQgPSBmdW5jdGlvbiAoc2Vjb25kKSB7XHJcbiAgICBpZiAoIXNlY29uZCkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NlY29uZCBvYnNlcnZhYmxlIGlzIHJlcXVpcmVkJyk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gb25FcnJvclJlc3VtZU5leHQoW3RoaXMsIHNlY29uZF0pO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIENvbnRpbnVlcyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgaXMgdGVybWluYXRlZCBub3JtYWxseSBvciBieSBhbiBleGNlcHRpb24gd2l0aCB0aGUgbmV4dCBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAqIFxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogMSAtIHJlcyA9IFJ4Lk9ic2VydmFibGUub25FcnJvclJlc3VtZU5leHQoeHMsIHlzLCB6cyk7XHJcbiAgICogMSAtIHJlcyA9IFJ4Lk9ic2VydmFibGUub25FcnJvclJlc3VtZU5leHQoW3hzLCB5cywgenNdKTtcclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbmNhdGVuYXRlcyB0aGUgc291cmNlIHNlcXVlbmNlcywgZXZlbiBpZiBhIHNlcXVlbmNlIHRlcm1pbmF0ZXMgZXhjZXB0aW9uYWxseS4gICBcclxuICAgKi9cclxuICB2YXIgb25FcnJvclJlc3VtZU5leHQgPSBPYnNlcnZhYmxlLm9uRXJyb3JSZXN1bWVOZXh0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgdmFyIHNvdXJjZXMgPSBhcmdzT3JBcnJheShhcmd1bWVudHMsIDApO1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICB2YXIgcG9zID0gMCwgc3Vic2NyaXB0aW9uID0gbmV3IFNlcmlhbERpc3Bvc2FibGUoKSxcclxuICAgICAgY2FuY2VsYWJsZSA9IGltbWVkaWF0ZVNjaGVkdWxlci5zY2hlZHVsZVJlY3Vyc2l2ZShmdW5jdGlvbiAoc2VsZikge1xyXG4gICAgICAgIHZhciBjdXJyZW50LCBkO1xyXG4gICAgICAgIGlmIChwb3MgPCBzb3VyY2VzLmxlbmd0aCkge1xyXG4gICAgICAgICAgY3VycmVudCA9IHNvdXJjZXNbcG9zKytdO1xyXG4gICAgICAgICAgaXNQcm9taXNlKGN1cnJlbnQpICYmIChjdXJyZW50ID0gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKGN1cnJlbnQpKTtcclxuICAgICAgICAgIGQgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgIHN1YnNjcmlwdGlvbi5zZXREaXNwb3NhYmxlKGQpO1xyXG4gICAgICAgICAgZC5zZXREaXNwb3NhYmxlKGN1cnJlbnQuc3Vic2NyaWJlKG9ic2VydmVyLm9uTmV4dC5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgIHNlbGYoKTtcclxuICAgICAgICAgIH0sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICBzZWxmKCk7XHJcbiAgICAgICAgICB9KSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICAgICAgcmV0dXJuIG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKHN1YnNjcmlwdGlvbiwgY2FuY2VsYWJsZSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBSZXR1cm5zIHRoZSB2YWx1ZXMgZnJvbSB0aGUgc291cmNlIG9ic2VydmFibGUgc2VxdWVuY2Ugb25seSBhZnRlciB0aGUgb3RoZXIgb2JzZXJ2YWJsZSBzZXF1ZW5jZSBwcm9kdWNlcyBhIHZhbHVlLlxyXG4gICAqIEBwYXJhbSB7T2JzZXJ2YWJsZSB8IFByb21pc2V9IG90aGVyIFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIG9yIFByb21pc2UgdGhhdCB0cmlnZ2VycyBwcm9wYWdhdGlvbiBvZiBlbGVtZW50cyBvZiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgdGhlIGVsZW1lbnRzIG9mIHRoZSBzb3VyY2Ugc2VxdWVuY2Ugc3RhcnRpbmcgZnJvbSB0aGUgcG9pbnQgdGhlIG90aGVyIHNlcXVlbmNlIHRyaWdnZXJlZCBwcm9wYWdhdGlvbi4gICAgXHJcbiAgICovXHJcbiAgb2JzZXJ2YWJsZVByb3RvLnNraXBVbnRpbCA9IGZ1bmN0aW9uIChvdGhlcikge1xyXG4gICAgdmFyIHNvdXJjZSA9IHRoaXM7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciBpc09wZW4gPSBmYWxzZTtcclxuICAgICAgdmFyIGRpc3Bvc2FibGVzID0gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAobGVmdCkge1xyXG4gICAgICAgIGlzT3BlbiAmJiBvYnNlcnZlci5vbk5leHQobGVmdCk7XHJcbiAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpc09wZW4gJiYgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgfSkpO1xyXG5cclxuICAgICAgaXNQcm9taXNlKG90aGVyKSAmJiAob3RoZXIgPSBvYnNlcnZhYmxlRnJvbVByb21pc2Uob3RoZXIpKTtcclxuXHJcbiAgICAgIHZhciByaWdodFN1YnNjcmlwdGlvbiA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpO1xyXG4gICAgICBkaXNwb3NhYmxlcy5hZGQocmlnaHRTdWJzY3JpcHRpb24pO1xyXG4gICAgICByaWdodFN1YnNjcmlwdGlvbi5zZXREaXNwb3NhYmxlKG90aGVyLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaXNPcGVuID0gdHJ1ZTtcclxuICAgICAgICByaWdodFN1YnNjcmlwdGlvbi5kaXNwb3NlKCk7XHJcbiAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByaWdodFN1YnNjcmlwdGlvbi5kaXNwb3NlKCk7XHJcbiAgICAgIH0pKTtcclxuXHJcbiAgICAgIHJldHVybiBkaXNwb3NhYmxlcztcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBUcmFuc2Zvcm1zIGFuIG9ic2VydmFibGUgc2VxdWVuY2Ugb2Ygb2JzZXJ2YWJsZSBzZXF1ZW5jZXMgaW50byBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHByb2R1Y2luZyB2YWx1ZXMgb25seSBmcm9tIHRoZSBtb3N0IHJlY2VudCBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgYXQgYW55IHBvaW50IGluIHRpbWUgcHJvZHVjZXMgdGhlIGVsZW1lbnRzIG9mIHRoZSBtb3N0IHJlY2VudCBpbm5lciBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgaGFzIGJlZW4gcmVjZWl2ZWQuICBcclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvWydzd2l0Y2gnXSA9IG9ic2VydmFibGVQcm90by5zd2l0Y2hMYXRlc3QgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIHNvdXJjZXMgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGhhc0xhdGVzdCA9IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgaW5uZXJTdWJzY3JpcHRpb24gPSBuZXcgU2VyaWFsRGlzcG9zYWJsZSgpLFxyXG4gICAgICAgICAgICAgICAgaXNTdG9wcGVkID0gZmFsc2UsXHJcbiAgICAgICAgICAgICAgICBsYXRlc3QgPSAwLFxyXG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uID0gc291cmNlcy5zdWJzY3JpYmUoZnVuY3Rpb24gKGlubmVyU291cmNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGQgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKSwgaWQgPSArK2xhdGVzdDtcclxuICAgICAgICAgICAgICAgICAgICBoYXNMYXRlc3QgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlubmVyU3Vic2NyaXB0aW9uLnNldERpc3Bvc2FibGUoZCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIC8vIENoZWNrIGlmIFByb21pc2Ugb3IgT2JzZXJ2YWJsZVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1Byb21pc2UoaW5uZXJTb3VyY2UpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlubmVyU291cmNlID0gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKGlubmVyU291cmNlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGQuc2V0RGlzcG9zYWJsZShpbm5lclNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxhdGVzdCA9PT0gaWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsYXRlc3QgPT09IGlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAobGF0ZXN0ID09PSBpZCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzTGF0ZXN0ID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaXNTdG9wcGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpc1N0b3BwZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghaGFzTGF0ZXN0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZShzdWJzY3JpcHRpb24sIGlubmVyU3Vic2NyaXB0aW9uKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybnMgdGhlIHZhbHVlcyBmcm9tIHRoZSBzb3VyY2Ugb2JzZXJ2YWJsZSBzZXF1ZW5jZSB1bnRpbCB0aGUgb3RoZXIgb2JzZXJ2YWJsZSBzZXF1ZW5jZSBwcm9kdWNlcyBhIHZhbHVlLlxyXG4gICAqIEBwYXJhbSB7T2JzZXJ2YWJsZSB8IFByb21pc2V9IG90aGVyIE9ic2VydmFibGUgc2VxdWVuY2Ugb3IgUHJvbWlzZSB0aGF0IHRlcm1pbmF0ZXMgcHJvcGFnYXRpb24gb2YgZWxlbWVudHMgb2YgdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBjb250YWluaW5nIHRoZSBlbGVtZW50cyBvZiB0aGUgc291cmNlIHNlcXVlbmNlIHVwIHRvIHRoZSBwb2ludCB0aGUgb3RoZXIgc2VxdWVuY2UgaW50ZXJydXB0ZWQgZnVydGhlciBwcm9wYWdhdGlvbi4gICBcclxuICAgKi9cclxuICBvYnNlcnZhYmxlUHJvdG8udGFrZVVudGlsID0gZnVuY3Rpb24gKG90aGVyKSB7XHJcbiAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgaXNQcm9taXNlKG90aGVyKSAmJiAob3RoZXIgPSBvYnNlcnZhYmxlRnJvbVByb21pc2Uob3RoZXIpKTtcclxuICAgICAgcmV0dXJuIG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKFxyXG4gICAgICAgIHNvdXJjZS5zdWJzY3JpYmUob2JzZXJ2ZXIpLFxyXG4gICAgICAgIG90aGVyLnN1YnNjcmliZShvYnNlcnZlci5vbkNvbXBsZXRlZC5iaW5kKG9ic2VydmVyKSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgbm9vcClcclxuICAgICAgKTtcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gIGZ1bmN0aW9uIHppcEFycmF5KHNlY29uZCwgcmVzdWx0U2VsZWN0b3IpIHtcclxuICAgIHZhciBmaXJzdCA9IHRoaXM7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciBpbmRleCA9IDAsIGxlbiA9IHNlY29uZC5sZW5ndGg7XHJcbiAgICAgIHJldHVybiBmaXJzdC5zdWJzY3JpYmUoZnVuY3Rpb24gKGxlZnQpIHtcclxuICAgICAgICBpZiAoaW5kZXggPCBsZW4pIHtcclxuICAgICAgICAgIHZhciByaWdodCA9IHNlY29uZFtpbmRleCsrXSwgcmVzdWx0O1xyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0U2VsZWN0b3IobGVmdCwgcmlnaHQpO1xyXG4gICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQocmVzdWx0KTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIG9ic2VydmVyLm9uQ29tcGxldGVkLmJpbmQob2JzZXJ2ZXIpKTtcclxuICAgIH0pO1xyXG4gIH0gICAgXHJcblxyXG4gIC8qKlxyXG4gICAqIE1lcmdlcyB0aGUgc3BlY2lmaWVkIG9ic2VydmFibGUgc2VxdWVuY2VzIGludG8gb25lIG9ic2VydmFibGUgc2VxdWVuY2UgYnkgdXNpbmcgdGhlIHNlbGVjdG9yIGZ1bmN0aW9uIHdoZW5ldmVyIGFsbCBvZiB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZXMgb3IgYW4gYXJyYXkgaGF2ZSBwcm9kdWNlZCBhbiBlbGVtZW50IGF0IGEgY29ycmVzcG9uZGluZyBpbmRleC5cclxuICAgKiBUaGUgbGFzdCBlbGVtZW50IGluIHRoZSBhcmd1bWVudHMgbXVzdCBiZSBhIGZ1bmN0aW9uIHRvIGludm9rZSBmb3IgZWFjaCBzZXJpZXMgb2YgZWxlbWVudHMgYXQgY29ycmVzcG9uZGluZyBpbmRleGVzIGluIHRoZSBzb3VyY2VzLlxyXG4gICAqXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiAxIC0gcmVzID0gb2JzMS56aXAob2JzMiwgZm4pO1xyXG4gICAqIDEgLSByZXMgPSB4MS56aXAoWzEsMiwzXSwgZm4pOyAgXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyB0aGUgcmVzdWx0IG9mIGNvbWJpbmluZyBlbGVtZW50cyBvZiB0aGUgc291cmNlcyB1c2luZyB0aGUgc3BlY2lmaWVkIHJlc3VsdCBzZWxlY3RvciBmdW5jdGlvbi4gXHJcbiAgICovICAgXHJcbiAgb2JzZXJ2YWJsZVByb3RvLnppcCA9IGZ1bmN0aW9uICgpIHtcclxuICAgIGlmIChBcnJheS5pc0FycmF5KGFyZ3VtZW50c1swXSkpIHtcclxuICAgICAgcmV0dXJuIHppcEFycmF5LmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XHJcbiAgICB9XHJcbiAgICB2YXIgcGFyZW50ID0gdGhpcywgc291cmNlcyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzKSwgcmVzdWx0U2VsZWN0b3IgPSBzb3VyY2VzLnBvcCgpO1xyXG4gICAgc291cmNlcy51bnNoaWZ0KHBhcmVudCk7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciBuID0gc291cmNlcy5sZW5ndGgsXHJcbiAgICAgICAgcXVldWVzID0gYXJyYXlJbml0aWFsaXplKG4sIGZ1bmN0aW9uICgpIHsgcmV0dXJuIFtdOyB9KSxcclxuICAgICAgICBpc0RvbmUgPSBhcnJheUluaXRpYWxpemUobiwgZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFsc2U7IH0pO1xyXG4gICAgICAgIFxyXG4gICAgICBmdW5jdGlvbiBuZXh0KGkpIHtcclxuICAgICAgICB2YXIgcmVzLCBxdWV1ZWRWYWx1ZXM7XHJcbiAgICAgICAgaWYgKHF1ZXVlcy5ldmVyeShmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5sZW5ndGggPiAwOyB9KSkge1xyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcXVldWVkVmFsdWVzID0gcXVldWVzLm1hcChmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5zaGlmdCgpOyB9KTtcclxuICAgICAgICAgICAgcmVzID0gcmVzdWx0U2VsZWN0b3IuYXBwbHkocGFyZW50LCBxdWV1ZWRWYWx1ZXMpO1xyXG4gICAgICAgICAgfSBjYXRjaCAoZXgpIHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChyZXMpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoaXNEb25lLmZpbHRlcihmdW5jdGlvbiAoeCwgaikgeyByZXR1cm4gaiAhPT0gaTsgfSkuZXZlcnkoaWRlbnRpdHkpKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfTtcclxuXHJcbiAgICAgIGZ1bmN0aW9uIGRvbmUoaSkge1xyXG4gICAgICAgIGlzRG9uZVtpXSA9IHRydWU7XHJcbiAgICAgICAgaWYgKGlzRG9uZS5ldmVyeShmdW5jdGlvbiAoeCkgeyByZXR1cm4geDsgfSkpIHtcclxuICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgc3Vic2NyaXB0aW9ucyA9IG5ldyBBcnJheShuKTtcclxuICAgICAgZm9yICh2YXIgaWR4ID0gMDsgaWR4IDwgbjsgaWR4KyspIHtcclxuICAgICAgICAoZnVuY3Rpb24gKGkpIHtcclxuICAgICAgICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzW2ldLCBzYWQgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgIGlzUHJvbWlzZShzb3VyY2UpICYmIChzb3VyY2UgPSBvYnNlcnZhYmxlRnJvbVByb21pc2Uoc291cmNlKSk7XHJcbiAgICAgICAgICBzYWQuc2V0RGlzcG9zYWJsZShzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgIHF1ZXVlc1tpXS5wdXNoKHgpO1xyXG4gICAgICAgICAgICBuZXh0KGkpO1xyXG4gICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBkb25lKGkpO1xyXG4gICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgc3Vic2NyaXB0aW9uc1tpXSA9IHNhZDtcclxuICAgICAgICB9KShpZHgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc3Vic2NyaXB0aW9ucyk7XHJcbiAgICB9KTtcclxuICB9O1xyXG4gICAgLyoqXHJcbiAgICAgKiBNZXJnZXMgdGhlIHNwZWNpZmllZCBvYnNlcnZhYmxlIHNlcXVlbmNlcyBpbnRvIG9uZSBvYnNlcnZhYmxlIHNlcXVlbmNlIGJ5IHVzaW5nIHRoZSBzZWxlY3RvciBmdW5jdGlvbiB3aGVuZXZlciBhbGwgb2YgdGhlIG9ic2VydmFibGUgc2VxdWVuY2VzIGhhdmUgcHJvZHVjZWQgYW4gZWxlbWVudCBhdCBhIGNvcnJlc3BvbmRpbmcgaW5kZXguXHJcbiAgICAgKiBAcGFyYW0gYXJndW1lbnRzIE9ic2VydmFibGUgc291cmNlcy5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlc3VsdFNlbGVjdG9yIEZ1bmN0aW9uIHRvIGludm9rZSBmb3IgZWFjaCBzZXJpZXMgb2YgZWxlbWVudHMgYXQgY29ycmVzcG9uZGluZyBpbmRleGVzIGluIHRoZSBzb3VyY2VzLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyB0aGUgcmVzdWx0IG9mIGNvbWJpbmluZyBlbGVtZW50cyBvZiB0aGUgc291cmNlcyB1c2luZyB0aGUgc3BlY2lmaWVkIHJlc3VsdCBzZWxlY3RvciBmdW5jdGlvbi5cclxuICAgICAqL1xyXG4gICAgT2JzZXJ2YWJsZS56aXAgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGFyZ3MgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMCksXHJcbiAgICAgICAgICAgIGZpcnN0ID0gYXJncy5zaGlmdCgpO1xyXG4gICAgICAgIHJldHVybiBmaXJzdC56aXAuYXBwbHkoZmlyc3QsIGFyZ3MpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIE1lcmdlcyB0aGUgc3BlY2lmaWVkIG9ic2VydmFibGUgc2VxdWVuY2VzIGludG8gb25lIG9ic2VydmFibGUgc2VxdWVuY2UgYnkgZW1pdHRpbmcgYSBsaXN0IHdpdGggdGhlIGVsZW1lbnRzIG9mIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlcyBhdCBjb3JyZXNwb25kaW5nIGluZGV4ZXMuXHJcbiAgICAgKiBAcGFyYW0gYXJndW1lbnRzIE9ic2VydmFibGUgc291cmNlcy5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgbGlzdHMgb2YgZWxlbWVudHMgYXQgY29ycmVzcG9uZGluZyBpbmRleGVzLlxyXG4gICAgICovXHJcbiAgICBPYnNlcnZhYmxlLnppcEFycmF5ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBzb3VyY2VzID0gYXJnc09yQXJyYXkoYXJndW1lbnRzLCAwKTtcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBuID0gc291cmNlcy5sZW5ndGgsXHJcbiAgICAgICAgICAgICAgcXVldWVzID0gYXJyYXlJbml0aWFsaXplKG4sIGZ1bmN0aW9uICgpIHsgcmV0dXJuIFtdOyB9KSxcclxuICAgICAgICAgICAgICBpc0RvbmUgPSBhcnJheUluaXRpYWxpemUobiwgZnVuY3Rpb24gKCkgeyByZXR1cm4gZmFsc2U7IH0pO1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gbmV4dChpKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocXVldWVzLmV2ZXJ5KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4Lmxlbmd0aCA+IDA7IH0pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIHJlcyA9IHF1ZXVlcy5tYXAoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHguc2hpZnQoKTsgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHJlcyk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGlzRG9uZS5maWx0ZXIoZnVuY3Rpb24gKHgsIGopIHsgcmV0dXJuIGogIT09IGk7IH0pLmV2ZXJ5KGlkZW50aXR5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgZnVuY3Rpb24gZG9uZShpKSB7XHJcbiAgICAgICAgICAgICAgICBpc0RvbmVbaV0gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzRG9uZS5ldmVyeShpZGVudGl0eSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdmFyIHN1YnNjcmlwdGlvbnMgPSBuZXcgQXJyYXkobik7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGlkeCA9IDA7IGlkeCA8IG47IGlkeCsrKSB7XHJcbiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKGkpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb25zW2ldID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uc1tpXS5zZXREaXNwb3NhYmxlKHNvdXJjZXNbaV0uc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHF1ZXVlc1tpXS5wdXNoKHgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXh0KGkpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZG9uZShpKTtcclxuICAgICAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICB9KShpZHgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICB2YXIgY29tcG9zaXRlRGlzcG9zYWJsZSA9IG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKHN1YnNjcmlwdGlvbnMpO1xyXG4gICAgICAgICAgICBjb21wb3NpdGVEaXNwb3NhYmxlLmFkZChkaXNwb3NhYmxlQ3JlYXRlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIHFJZHggPSAwLCBxTGVuID0gcXVldWVzLmxlbmd0aDsgcUlkeCA8IHFMZW47IHFJZHgrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHF1ZXVlc1txSWR4XSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgIHJldHVybiBjb21wb3NpdGVEaXNwb3NhYmxlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBIaWRlcyB0aGUgaWRlbnRpdHkgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgaGlkZXMgdGhlIGlkZW50aXR5IG9mIHRoZSBzb3VyY2Ugc2VxdWVuY2UuICAgIFxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uYXNPYnNlcnZhYmxlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5zdWJzY3JpYmUob2JzZXJ2ZXIpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogIFByb2plY3RzIGVhY2ggZWxlbWVudCBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGludG8gemVybyBvciBtb3JlIGJ1ZmZlcnMgd2hpY2ggYXJlIHByb2R1Y2VkIGJhc2VkIG9uIGVsZW1lbnQgY291bnQgaW5mb3JtYXRpb24uXHJcbiAgICogIFxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogIHZhciByZXMgPSB4cy5idWZmZXJXaXRoQ291bnQoMTApO1xyXG4gICAqICB2YXIgcmVzID0geHMuYnVmZmVyV2l0aENvdW50KDEwLCAxKTtcclxuICAgKiBAcGFyYW0ge051bWJlcn0gY291bnQgTGVuZ3RoIG9mIGVhY2ggYnVmZmVyLlxyXG4gICAqIEBwYXJhbSB7TnVtYmVyfSBbc2tpcF0gTnVtYmVyIG9mIGVsZW1lbnRzIHRvIHNraXAgYmV0d2VlbiBjcmVhdGlvbiBvZiBjb25zZWN1dGl2ZSBidWZmZXJzLiBJZiBub3QgcHJvdmlkZWQsIGRlZmF1bHRzIHRvIHRoZSBjb3VudC5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBvZiBidWZmZXJzLiAgICBcclxuICAgKi9cclxuICBvYnNlcnZhYmxlUHJvdG8uYnVmZmVyV2l0aENvdW50ID0gZnVuY3Rpb24gKGNvdW50LCBza2lwKSB7XHJcbiAgICBpZiAodHlwZW9mIHNraXAgIT09ICdudW1iZXInKSB7XHJcbiAgICAgIHNraXAgPSBjb3VudDtcclxuICAgIH1cclxuICAgIHJldHVybiB0aGlzLndpbmRvd1dpdGhDb3VudChjb3VudCwgc2tpcCkuc2VsZWN0TWFueShmdW5jdGlvbiAoeCkge1xyXG4gICAgICByZXR1cm4geC50b0FycmF5KCk7XHJcbiAgICB9KS53aGVyZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICByZXR1cm4geC5sZW5ndGggPiAwO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERlbWF0ZXJpYWxpemVzIHRoZSBleHBsaWNpdCBub3RpZmljYXRpb24gdmFsdWVzIG9mIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgYXMgaW1wbGljaXQgbm90aWZpY2F0aW9ucy5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGV4aGliaXRpbmcgdGhlIGJlaGF2aW9yIGNvcnJlc3BvbmRpbmcgdG8gdGhlIHNvdXJjZSBzZXF1ZW5jZSdzIG5vdGlmaWNhdGlvbiB2YWx1ZXMuXHJcbiAgICAgKi8gXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uZGVtYXRlcmlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4geC5hY2NlcHQob2JzZXJ2ZXIpO1xyXG4gICAgICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBvYnNlcnZlci5vbkNvbXBsZXRlZC5iaW5kKG9ic2VydmVyKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFJldHVybnMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbnRhaW5zIG9ubHkgZGlzdGluY3QgY29udGlndW91cyBlbGVtZW50cyBhY2NvcmRpbmcgdG8gdGhlIGtleVNlbGVjdG9yIGFuZCB0aGUgY29tcGFyZXIuXHJcbiAgICAgKiAgXHJcbiAgICAgKiAgdmFyIG9icyA9IG9ic2VydmFibGUuZGlzdGluY3RVbnRpbENoYW5nZWQoKTtcclxuICAgICAqICB2YXIgb2JzID0gb2JzZXJ2YWJsZS5kaXN0aW5jdFVudGlsQ2hhbmdlZChmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5pZDsgfSk7XHJcbiAgICAgKiAgdmFyIG9icyA9IG9ic2VydmFibGUuZGlzdGluY3RVbnRpbENoYW5nZWQoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHguaWQ7IH0sIGZ1bmN0aW9uICh4LCB5KSB7IHJldHVybiB4ID09PSB5OyB9KTtcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBba2V5U2VsZWN0b3JdIEEgZnVuY3Rpb24gdG8gY29tcHV0ZSB0aGUgY29tcGFyaXNvbiBrZXkgZm9yIGVhY2ggZWxlbWVudC4gSWYgbm90IHByb3ZpZGVkLCBpdCBwcm9qZWN0cyB0aGUgdmFsdWUuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyZXJdIEVxdWFsaXR5IGNvbXBhcmVyIGZvciBjb21wdXRlZCBrZXkgdmFsdWVzLiBJZiBub3QgcHJvdmlkZWQsIGRlZmF1bHRzIHRvIGFuIGVxdWFsaXR5IGNvbXBhcmVyIGZ1bmN0aW9uLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2Ugb25seSBjb250YWluaW5nIHRoZSBkaXN0aW5jdCBjb250aWd1b3VzIGVsZW1lbnRzLCBiYXNlZCBvbiBhIGNvbXB1dGVkIGtleSB2YWx1ZSwgZnJvbSB0aGUgc291cmNlIHNlcXVlbmNlLiAgIFxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uZGlzdGluY3RVbnRpbENoYW5nZWQgPSBmdW5jdGlvbiAoa2V5U2VsZWN0b3IsIGNvbXBhcmVyKSB7XHJcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRoaXM7XHJcbiAgICAgICAga2V5U2VsZWN0b3IgfHwgKGtleVNlbGVjdG9yID0gaWRlbnRpdHkpO1xyXG4gICAgICAgIGNvbXBhcmVyIHx8IChjb21wYXJlciA9IGRlZmF1bHRDb21wYXJlcik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgaGFzQ3VycmVudEtleSA9IGZhbHNlLCBjdXJyZW50S2V5O1xyXG4gICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIHZhciBjb21wYXJlckVxdWFscyA9IGZhbHNlLCBrZXk7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleSA9IGtleVNlbGVjdG9yKHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXhjZXB0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFzQ3VycmVudEtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbXBhcmVyRXF1YWxzID0gY29tcGFyZXIoY3VycmVudEtleSwga2V5KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleGNlcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCFoYXNDdXJyZW50S2V5IHx8ICFjb21wYXJlckVxdWFscykge1xyXG4gICAgICAgICAgICAgICAgICAgIGhhc0N1cnJlbnRLZXkgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGN1cnJlbnRLZXkgPSBrZXk7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgb2JzZXJ2ZXIub25Db21wbGV0ZWQuYmluZChvYnNlcnZlcikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBJbnZva2VzIGFuIGFjdGlvbiBmb3IgZWFjaCBlbGVtZW50IGluIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIGFuZCBpbnZva2VzIGFuIGFjdGlvbiB1cG9uIGdyYWNlZnVsIG9yIGV4Y2VwdGlvbmFsIHRlcm1pbmF0aW9uIG9mIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAgICogIFRoaXMgbWV0aG9kIGNhbiBiZSB1c2VkIGZvciBkZWJ1Z2dpbmcsIGxvZ2dpbmcsIGV0Yy4gb2YgcXVlcnkgYmVoYXZpb3IgYnkgaW50ZXJjZXB0aW5nIHRoZSBtZXNzYWdlIHN0cmVhbSB0byBydW4gYXJiaXRyYXJ5IGFjdGlvbnMgZm9yIG1lc3NhZ2VzIG9uIHRoZSBwaXBlbGluZS5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgdmFyIHJlcyA9IG9ic2VydmFibGUuZG9BY3Rpb24ob2JzZXJ2ZXIpO1xyXG4gICAgICogIHZhciByZXMgPSBvYnNlcnZhYmxlLmRvQWN0aW9uKG9uTmV4dCk7XHJcbiAgICAgKiAgdmFyIHJlcyA9IG9ic2VydmFibGUuZG9BY3Rpb24ob25OZXh0LCBvbkVycm9yKTtcclxuICAgICAqICB2YXIgcmVzID0gb2JzZXJ2YWJsZS5kb0FjdGlvbihvbk5leHQsIG9uRXJyb3IsIG9uQ29tcGxldGVkKTtcclxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IG9ic2VydmVyT3JPbk5leHQgQWN0aW9uIHRvIGludm9rZSBmb3IgZWFjaCBlbGVtZW50IGluIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIG9yIGFuIG9ic2VydmVyLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29uRXJyb3JdICBBY3Rpb24gdG8gaW52b2tlIHVwb24gZXhjZXB0aW9uYWwgdGVybWluYXRpb24gb2YgdGhlIG9ic2VydmFibGUgc2VxdWVuY2UuIFVzZWQgaWYgb25seSB0aGUgb2JzZXJ2ZXJPck9uTmV4dCBwYXJhbWV0ZXIgaXMgYWxzbyBhIGZ1bmN0aW9uLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW29uQ29tcGxldGVkXSAgQWN0aW9uIHRvIGludm9rZSB1cG9uIGdyYWNlZnVsIHRlcm1pbmF0aW9uIG9mIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlLiBVc2VkIGlmIG9ubHkgdGhlIG9ic2VydmVyT3JPbk5leHQgcGFyYW1ldGVyIGlzIGFsc28gYSBmdW5jdGlvbi5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBUaGUgc291cmNlIHNlcXVlbmNlIHdpdGggdGhlIHNpZGUtZWZmZWN0aW5nIGJlaGF2aW9yIGFwcGxpZWQuICAgXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90b1snZG8nXSA9IG9ic2VydmFibGVQcm90by5kb0FjdGlvbiA9IGZ1bmN0aW9uIChvYnNlcnZlck9yT25OZXh0LCBvbkVycm9yLCBvbkNvbXBsZXRlZCkge1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzLCBvbk5leHRGdW5jO1xyXG4gICAgICAgIGlmICh0eXBlb2Ygb2JzZXJ2ZXJPck9uTmV4dCA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICBvbk5leHRGdW5jID0gb2JzZXJ2ZXJPck9uTmV4dDtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBvbk5leHRGdW5jID0gb2JzZXJ2ZXJPck9uTmV4dC5vbk5leHQuYmluZChvYnNlcnZlck9yT25OZXh0KTtcclxuICAgICAgICAgICAgb25FcnJvciA9IG9ic2VydmVyT3JPbk5leHQub25FcnJvci5iaW5kKG9ic2VydmVyT3JPbk5leHQpO1xyXG4gICAgICAgICAgICBvbkNvbXBsZXRlZCA9IG9ic2VydmVyT3JPbk5leHQub25Db21wbGV0ZWQuYmluZChvYnNlcnZlck9yT25OZXh0KTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBvbk5leHRGdW5jKHgpO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQoeCk7XHJcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChleGNlcHRpb24pIHtcclxuICAgICAgICAgICAgICAgIGlmICghb25FcnJvcikge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXhjZXB0aW9uKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb25FcnJvcihleGNlcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleGNlcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIW9uQ29tcGxldGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogIEludm9rZXMgYSBzcGVjaWZpZWQgYWN0aW9uIGFmdGVyIHRoZSBzb3VyY2Ugb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0ZXJtaW5hdGVzIGdyYWNlZnVsbHkgb3IgZXhjZXB0aW9uYWxseS5cclxuICAgKiAgXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiAgdmFyIHJlcyA9IG9ic2VydmFibGUuZmluYWxseUFjdGlvbihmdW5jdGlvbiAoKSB7IGNvbnNvbGUubG9nKCdzZXF1ZW5jZSBlbmRlZCc7IH0pO1xyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZpbmFsbHlBY3Rpb24gQWN0aW9uIHRvIGludm9rZSBhZnRlciB0aGUgc291cmNlIG9ic2VydmFibGUgc2VxdWVuY2UgdGVybWluYXRlcy5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gU291cmNlIHNlcXVlbmNlIHdpdGggdGhlIGFjdGlvbi1pbnZva2luZyB0ZXJtaW5hdGlvbiBiZWhhdmlvciBhcHBsaWVkLiBcclxuICAgKi8gIFxyXG4gIG9ic2VydmFibGVQcm90b1snZmluYWxseSddID0gb2JzZXJ2YWJsZVByb3RvLmZpbmFsbHlBY3Rpb24gPSBmdW5jdGlvbiAoYWN0aW9uKSB7XHJcbiAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgdmFyIHN1YnNjcmlwdGlvbjtcclxuICAgICAgdHJ5IHtcclxuICAgICAgICBzdWJzY3JpcHRpb24gPSBzb3VyY2Uuc3Vic2NyaWJlKG9ic2VydmVyKTtcclxuICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgIGFjdGlvbigpO1xyXG4gICAgICAgIHRocm93IGU7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIGRpc3Bvc2FibGVDcmVhdGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICBzdWJzY3JpcHRpb24uZGlzcG9zZSgpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGUpIHsgXHJcbiAgICAgICAgICB0aHJvdyBlOyAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgfSBmaW5hbGx5IHtcclxuICAgICAgICAgIGFjdGlvbigpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIElnbm9yZXMgYWxsIGVsZW1lbnRzIGluIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgbGVhdmluZyBvbmx5IHRoZSB0ZXJtaW5hdGlvbiBtZXNzYWdlcy5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBlbXB0eSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc2lnbmFscyB0ZXJtaW5hdGlvbiwgc3VjY2Vzc2Z1bCBvciBleGNlcHRpb25hbCwgb2YgdGhlIHNvdXJjZSBzZXF1ZW5jZS4gICAgXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5pZ25vcmVFbGVtZW50cyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic2NyaWJlKG5vb3AsIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIG9ic2VydmVyLm9uQ29tcGxldGVkLmJpbmQob2JzZXJ2ZXIpKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgTWF0ZXJpYWxpemVzIHRoZSBpbXBsaWNpdCBub3RpZmljYXRpb25zIG9mIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgYXMgZXhwbGljaXQgbm90aWZpY2F0aW9uIHZhbHVlcy5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgdGhlIG1hdGVyaWFsaXplZCBub3RpZmljYXRpb24gdmFsdWVzIGZyb20gdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqLyAgICBcclxuICAgIG9ic2VydmFibGVQcm90by5tYXRlcmlhbGl6ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KG5vdGlmaWNhdGlvbkNyZWF0ZU9uTmV4dCh2YWx1ZSkpO1xyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KG5vdGlmaWNhdGlvbkNyZWF0ZU9uRXJyb3IoZSkpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KG5vdGlmaWNhdGlvbkNyZWF0ZU9uQ29tcGxldGVkKCkpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFJlcGVhdHMgdGhlIG9ic2VydmFibGUgc2VxdWVuY2UgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIHRpbWVzLiBJZiB0aGUgcmVwZWF0IGNvdW50IGlzIG5vdCBzcGVjaWZpZWQsIHRoZSBzZXF1ZW5jZSByZXBlYXRzIGluZGVmaW5pdGVseS5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgdmFyIHJlcyA9IHJlcGVhdGVkID0gc291cmNlLnJlcGVhdCgpO1xyXG4gICAgICogIHZhciByZXMgPSByZXBlYXRlZCA9IHNvdXJjZS5yZXBlYXQoNDIpO1xyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IFtyZXBlYXRDb3VudF0gIE51bWJlciBvZiB0aW1lcyB0byByZXBlYXQgdGhlIHNlcXVlbmNlLiBJZiBub3QgcHJvdmlkZWQsIHJlcGVhdHMgdGhlIHNlcXVlbmNlIGluZGVmaW5pdGVseS5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBUaGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSBwcm9kdWNpbmcgdGhlIGVsZW1lbnRzIG9mIHRoZSBnaXZlbiBzZXF1ZW5jZSByZXBlYXRlZGx5LiAgIFxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8ucmVwZWF0ID0gZnVuY3Rpb24gKHJlcGVhdENvdW50KSB7XHJcbiAgICAgICAgcmV0dXJuIGVudW1lcmFibGVSZXBlYXQodGhpcywgcmVwZWF0Q291bnQpLmNvbmNhdCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBSZXBlYXRzIHRoZSBzb3VyY2Ugb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiB0aW1lcyBvciB1bnRpbCBpdCBzdWNjZXNzZnVsbHkgdGVybWluYXRlcy4gSWYgdGhlIHJldHJ5IGNvdW50IGlzIG5vdCBzcGVjaWZpZWQsIGl0IHJldHJpZXMgaW5kZWZpbml0ZWx5LlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICB2YXIgcmVzID0gcmV0cmllZCA9IHJldHJ5LnJlcGVhdCgpO1xyXG4gICAgICogIHZhciByZXMgPSByZXRyaWVkID0gcmV0cnkucmVwZWF0KDQyKTtcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBbcmV0cnlDb3VudF0gIE51bWJlciBvZiB0aW1lcyB0byByZXRyeSB0aGUgc2VxdWVuY2UuIElmIG5vdCBwcm92aWRlZCwgcmV0cnkgdGhlIHNlcXVlbmNlIGluZGVmaW5pdGVseS5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHByb2R1Y2luZyB0aGUgZWxlbWVudHMgb2YgdGhlIGdpdmVuIHNlcXVlbmNlIHJlcGVhdGVkbHkgdW50aWwgaXQgdGVybWluYXRlcyBzdWNjZXNzZnVsbHkuIFxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8ucmV0cnkgPSBmdW5jdGlvbiAocmV0cnlDb3VudCkge1xyXG4gICAgICAgIHJldHVybiBlbnVtZXJhYmxlUmVwZWF0KHRoaXMsIHJldHJ5Q291bnQpLmNhdGNoRXhjZXB0aW9uKCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIEFwcGxpZXMgYW4gYWNjdW11bGF0b3IgZnVuY3Rpb24gb3ZlciBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGFuZCByZXR1cm5zIGVhY2ggaW50ZXJtZWRpYXRlIHJlc3VsdC4gVGhlIG9wdGlvbmFsIHNlZWQgdmFsdWUgaXMgdXNlZCBhcyB0aGUgaW5pdGlhbCBhY2N1bXVsYXRvciB2YWx1ZS5cclxuICAgICAqICBGb3IgYWdncmVnYXRpb24gYmVoYXZpb3Igd2l0aCBubyBpbnRlcm1lZGlhdGUgcmVzdWx0cywgc2VlIE9ic2VydmFibGUuYWdncmVnYXRlLlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICB2YXIgcmVzID0gc291cmNlLnNjYW4oZnVuY3Rpb24gKGFjYywgeCkgeyByZXR1cm4gYWNjICsgeDsgfSk7XHJcbiAgICAgKiAgdmFyIHJlcyA9IHNvdXJjZS5zY2FuKDAsIGZ1bmN0aW9uIChhY2MsIHgpIHsgcmV0dXJuIGFjYyArIHg7IH0pO1xyXG4gICAgICogQHBhcmFtIHtNaXhlZH0gW3NlZWRdIFRoZSBpbml0aWFsIGFjY3VtdWxhdG9yIHZhbHVlLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWNjdW11bGF0b3IgQW4gYWNjdW11bGF0b3IgZnVuY3Rpb24gdG8gYmUgaW52b2tlZCBvbiBlYWNoIGVsZW1lbnQuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBjb250YWluaW5nIHRoZSBhY2N1bXVsYXRlZCB2YWx1ZXMuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5zY2FuID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBoYXNTZWVkID0gZmFsc2UsIHNlZWQsIGFjY3VtdWxhdG9yLCBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XHJcbiAgICAgICAgICAgIGhhc1NlZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBzZWVkID0gYXJndW1lbnRzWzBdO1xyXG4gICAgICAgICAgICBhY2N1bXVsYXRvciA9IGFyZ3VtZW50c1sxXTsgICAgICAgIFxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGFjY3VtdWxhdG9yID0gYXJndW1lbnRzWzBdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBoYXNBY2N1bXVsYXRpb24sIGFjY3VtdWxhdGlvbiwgaGFzVmFsdWU7XHJcbiAgICAgICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic2NyaWJlIChcclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzVmFsdWUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChoYXNBY2N1bXVsYXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjY3VtdWxhdGlvbiA9IGFjY3VtdWxhdG9yKGFjY3VtdWxhdGlvbiwgeCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY2N1bXVsYXRpb24gPSBoYXNTZWVkID8gYWNjdW11bGF0b3Ioc2VlZCwgeCkgOiB4O1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaGFzQWNjdW11bGF0aW9uID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChhY2N1bXVsYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFoYXNWYWx1ZSAmJiBoYXNTZWVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChzZWVkKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgQnlwYXNzZXMgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIGVsZW1lbnRzIGF0IHRoZSBlbmQgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqIEBkZXNjcmlwdGlvblxyXG4gICAgICogIFRoaXMgb3BlcmF0b3IgYWNjdW11bGF0ZXMgYSBxdWV1ZSB3aXRoIGEgbGVuZ3RoIGVub3VnaCB0byBzdG9yZSB0aGUgZmlyc3QgYGNvdW50YCBlbGVtZW50cy4gQXMgbW9yZSBlbGVtZW50cyBhcmVcclxuICAgICAqICByZWNlaXZlZCwgZWxlbWVudHMgYXJlIHRha2VuIGZyb20gdGhlIGZyb250IG9mIHRoZSBxdWV1ZSBhbmQgcHJvZHVjZWQgb24gdGhlIHJlc3VsdCBzZXF1ZW5jZS4gVGhpcyBjYXVzZXMgZWxlbWVudHMgdG8gYmUgZGVsYXllZC4gICAgIFxyXG4gICAgICogQHBhcmFtIGNvdW50IE51bWJlciBvZiBlbGVtZW50cyB0byBieXBhc3MgYXQgdGhlIGVuZCBvZiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyB0aGUgc291cmNlIHNlcXVlbmNlIGVsZW1lbnRzIGV4Y2VwdCBmb3IgdGhlIGJ5cGFzc2VkIG9uZXMgYXQgdGhlIGVuZC4gICBcclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnNraXBMYXN0ID0gZnVuY3Rpb24gKGNvdW50KSB7XHJcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRoaXM7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgcSA9IFtdO1xyXG4gICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgcS5wdXNoKHgpO1xyXG4gICAgICAgICAgICAgICAgaWYgKHEubGVuZ3RoID4gY291bnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQocS5zaGlmdCgpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgb2JzZXJ2ZXIub25Db21wbGV0ZWQuYmluZChvYnNlcnZlcikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBQcmVwZW5kcyBhIHNlcXVlbmNlIG9mIHZhbHVlcyB0byBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdpdGggYW4gb3B0aW9uYWwgc2NoZWR1bGVyIGFuZCBhbiBhcmd1bWVudCBsaXN0IG9mIHZhbHVlcyB0byBwcmVwZW5kLlxyXG4gICAgICogIFxyXG4gICAgICogIHZhciByZXMgPSBzb3VyY2Uuc3RhcnRXaXRoKDEsIDIsIDMpO1xyXG4gICAgICogIHZhciByZXMgPSBzb3VyY2Uuc3RhcnRXaXRoKFJ4LlNjaGVkdWxlci50aW1lb3V0LCAxLCAyLCAzKTtcclxuICAgICAqICBcclxuICAgICAqIEBtZW1iZXJPZiBPYnNlcnZhYmxlI1xyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IFRoZSBzb3VyY2Ugc2VxdWVuY2UgcHJlcGVuZGVkIHdpdGggdGhlIHNwZWNpZmllZCB2YWx1ZXMuICBcclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnN0YXJ0V2l0aCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgdmFsdWVzLCBzY2hlZHVsZXIsIHN0YXJ0ID0gMDtcclxuICAgICAgICBpZiAoISFhcmd1bWVudHMubGVuZ3RoICYmICdub3cnIGluIE9iamVjdChhcmd1bWVudHNbMF0pKSB7XHJcbiAgICAgICAgICAgIHNjaGVkdWxlciA9IGFyZ3VtZW50c1swXTtcclxuICAgICAgICAgICAgc3RhcnQgPSAxO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIHNjaGVkdWxlciA9IGltbWVkaWF0ZVNjaGVkdWxlcjtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFsdWVzID0gc2xpY2UuY2FsbChhcmd1bWVudHMsIHN0YXJ0KTtcclxuICAgICAgICByZXR1cm4gZW51bWVyYWJsZUZvcihbb2JzZXJ2YWJsZUZyb21BcnJheSh2YWx1ZXMsIHNjaGVkdWxlciksIHRoaXNdKS5jb25jYXQoKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgUmV0dXJucyBhIHNwZWNpZmllZCBudW1iZXIgb2YgY29udGlndW91cyBlbGVtZW50cyBmcm9tIHRoZSBlbmQgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSwgdXNpbmcgYW4gb3B0aW9uYWwgc2NoZWR1bGVyIHRvIGRyYWluIHRoZSBxdWV1ZS5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgdmFyIHJlcyA9IHNvdXJjZS50YWtlTGFzdCg1KTtcclxuICAgICAqICB2YXIgcmVzID0gc291cmNlLnRha2VMYXN0KDUsIFJ4LlNjaGVkdWxlci50aW1lb3V0KTtcclxuICAgICAqICBcclxuICAgICAqIEBkZXNjcmlwdGlvblxyXG4gICAgICogIFRoaXMgb3BlcmF0b3IgYWNjdW11bGF0ZXMgYSBidWZmZXIgd2l0aCBhIGxlbmd0aCBlbm91Z2ggdG8gc3RvcmUgZWxlbWVudHMgY291bnQgZWxlbWVudHMuIFVwb24gY29tcGxldGlvbiBvZlxyXG4gICAgICogIHRoZSBzb3VyY2Ugc2VxdWVuY2UsIHRoaXMgYnVmZmVyIGlzIGRyYWluZWQgb24gdGhlIHJlc3VsdCBzZXF1ZW5jZS4gVGhpcyBjYXVzZXMgdGhlIGVsZW1lbnRzIHRvIGJlIGRlbGF5ZWQuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY291bnQgTnVtYmVyIG9mIGVsZW1lbnRzIHRvIHRha2UgZnJvbSB0aGUgZW5kIG9mIHRoZSBzb3VyY2Ugc2VxdWVuY2UuXHJcbiAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gW3NjaGVkdWxlcl0gU2NoZWR1bGVyIHVzZWQgdG8gZHJhaW4gdGhlIHF1ZXVlIHVwb24gY29tcGxldGlvbiBvZiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyB0aGUgc3BlY2lmaWVkIG51bWJlciBvZiBlbGVtZW50cyBmcm9tIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqLyAgIFxyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnRha2VMYXN0ID0gZnVuY3Rpb24gKGNvdW50LCBzY2hlZHVsZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy50YWtlTGFzdEJ1ZmZlcihjb3VudCkuc2VsZWN0TWFueShmdW5jdGlvbiAoeHMpIHsgcmV0dXJuIG9ic2VydmFibGVGcm9tQXJyYXkoeHMsIHNjaGVkdWxlcik7IH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBSZXR1cm5zIGFuIGFycmF5IHdpdGggdGhlIHNwZWNpZmllZCBudW1iZXIgb2YgY29udGlndW91cyBlbGVtZW50cyBmcm9tIHRoZSBlbmQgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqICBcclxuICAgICAqIEBkZXNjcmlwdGlvblxyXG4gICAgICogIFRoaXMgb3BlcmF0b3IgYWNjdW11bGF0ZXMgYSBidWZmZXIgd2l0aCBhIGxlbmd0aCBlbm91Z2ggdG8gc3RvcmUgY291bnQgZWxlbWVudHMuIFVwb24gY29tcGxldGlvbiBvZiB0aGVcclxuICAgICAqICBzb3VyY2Ugc2VxdWVuY2UsIHRoaXMgYnVmZmVyIGlzIHByb2R1Y2VkIG9uIHRoZSByZXN1bHQgc2VxdWVuY2UuICAgICAgIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNvdW50IE51bWJlciBvZiBlbGVtZW50cyB0byB0YWtlIGZyb20gdGhlIGVuZCBvZiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyBhIHNpbmdsZSBhcnJheSB3aXRoIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGVsZW1lbnRzIGZyb20gdGhlIGVuZCBvZiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8udGFrZUxhc3RCdWZmZXIgPSBmdW5jdGlvbiAoY291bnQpIHtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBxID0gW107XHJcbiAgICAgICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICBxLnB1c2goeCk7XHJcbiAgICAgICAgICAgICAgICBpZiAocS5sZW5ndGggPiBjb3VudCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHEuc2hpZnQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHEpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFByb2plY3RzIGVhY2ggZWxlbWVudCBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGludG8gemVybyBvciBtb3JlIHdpbmRvd3Mgd2hpY2ggYXJlIHByb2R1Y2VkIGJhc2VkIG9uIGVsZW1lbnQgY291bnQgaW5mb3JtYXRpb24uXHJcbiAgICAgKiAgXHJcbiAgICAgKiAgdmFyIHJlcyA9IHhzLndpbmRvd1dpdGhDb3VudCgxMCk7XHJcbiAgICAgKiAgdmFyIHJlcyA9IHhzLndpbmRvd1dpdGhDb3VudCgxMCwgMSk7XHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY291bnQgTGVuZ3RoIG9mIGVhY2ggd2luZG93LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IFtza2lwXSBOdW1iZXIgb2YgZWxlbWVudHMgdG8gc2tpcCBiZXR3ZWVuIGNyZWF0aW9uIG9mIGNvbnNlY3V0aXZlIHdpbmRvd3MuIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIHRoZSBjb3VudC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIG9mIHdpbmRvd3MuICBcclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLndpbmRvd1dpdGhDb3VudCA9IGZ1bmN0aW9uIChjb3VudCwgc2tpcCkge1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIGlmIChjb3VudCA8PSAwKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihhcmd1bWVudE91dE9mUmFuZ2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgICAgICBza2lwID0gY291bnQ7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChza2lwIDw9IDApIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGFyZ3VtZW50T3V0T2ZSYW5nZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIG0gPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKSxcclxuICAgICAgICAgICAgICAgIHJlZkNvdW50RGlzcG9zYWJsZSA9IG5ldyBSZWZDb3VudERpc3Bvc2FibGUobSksXHJcbiAgICAgICAgICAgICAgICBuID0gMCxcclxuICAgICAgICAgICAgICAgIHEgPSBbXSxcclxuICAgICAgICAgICAgICAgIGNyZWF0ZVdpbmRvdyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcS5wdXNoKHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChhZGRSZWYocywgcmVmQ291bnREaXNwb3NhYmxlKSk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBjcmVhdGVXaW5kb3coKTtcclxuICAgICAgICAgICAgbS5zZXREaXNwb3NhYmxlKHNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzO1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHEubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBxW2ldLm9uTmV4dCh4KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHZhciBjID0gbiAtIGNvdW50ICsgMTtcclxuICAgICAgICAgICAgICAgIGlmIChjID49IDAgJiYgYyAlIHNraXAgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICBzID0gcS5zaGlmdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHMub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG4rKztcclxuICAgICAgICAgICAgICAgIGlmIChuICUgc2tpcCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZVdpbmRvdygpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAocS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcS5zaGlmdCgpLm9uRXJyb3IoZXhjZXB0aW9uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXhjZXB0aW9uKTtcclxuICAgICAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgd2hpbGUgKHEubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHEuc2hpZnQoKS5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICByZXR1cm4gcmVmQ291bnREaXNwb3NhYmxlO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICBmdW5jdGlvbiBjb25jYXRNYXAoc2VsZWN0b3IpIHtcclxuICAgICAgcmV0dXJuIHRoaXMubWFwKGZ1bmN0aW9uICh4LCBpKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHNlbGVjdG9yKHgsIGkpO1xyXG4gICAgICAgIHJldHVybiBpc1Byb21pc2UocmVzdWx0KSA/IG9ic2VydmFibGVGcm9tUHJvbWlzZShyZXN1bHQpIDogcmVzdWx0O1xyXG4gICAgICB9KS5jb25jYXRBbGwoKTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBjb25jYXRNYXBPYnNlcnZlcihvbk5leHQsIG9uRXJyb3IsIG9uQ29tcGxldGVkKSB7XHJcbiAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgdmFyIGluZGV4ID0gMDtcclxuXHJcbiAgICAgICAgcmV0dXJuIHNvdXJjZS5zdWJzY3JpYmUoXHJcbiAgICAgICAgICBmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICBvYnNlcnZlci5vbk5leHQob25OZXh0KHgsIGluZGV4KyspKTtcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChvbkVycm9yKGVycikpO1xyXG4gICAgICAgICAgICBvYnNlcnZlci5jb21wbGV0ZWQoKTtcclxuICAgICAgICAgIH0sIFxyXG4gICAgICAgICAgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBvYnNlcnZlci5vbk5leHQob25Db21wbGV0ZWQoKSk7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICB9KTtcclxuICAgICAgfSkuY29uY2F0QWxsKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgT25lIG9mIHRoZSBGb2xsb3dpbmc6XHJcbiAgICAgKiAgUHJvamVjdHMgZWFjaCBlbGVtZW50IG9mIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdG8gYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBhbmQgbWVyZ2VzIHRoZSByZXN1bHRpbmcgb2JzZXJ2YWJsZSBzZXF1ZW5jZXMgaW50byBvbmUgb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgdmFyIHJlcyA9IHNvdXJjZS5zZWxlY3RNYW55KGZ1bmN0aW9uICh4KSB7IHJldHVybiBSeC5PYnNlcnZhYmxlLnJhbmdlKDAsIHgpOyB9KTtcclxuICAgICAqICBPcjpcclxuICAgICAqICBQcm9qZWN0cyBlYWNoIGVsZW1lbnQgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0byBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlLCBpbnZva2VzIHRoZSByZXN1bHQgc2VsZWN0b3IgZm9yIHRoZSBzb3VyY2UgZWxlbWVudCBhbmQgZWFjaCBvZiB0aGUgY29ycmVzcG9uZGluZyBpbm5lciBzZXF1ZW5jZSdzIGVsZW1lbnRzLCBhbmQgbWVyZ2VzIHRoZSByZXN1bHRzIGludG8gb25lIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgKiAgXHJcbiAgICAgKiAgdmFyIHJlcyA9IHNvdXJjZS5zZWxlY3RNYW55KGZ1bmN0aW9uICh4KSB7IHJldHVybiBSeC5PYnNlcnZhYmxlLnJhbmdlKDAsIHgpOyB9LCBmdW5jdGlvbiAoeCwgeSkgeyByZXR1cm4geCArIHk7IH0pO1xyXG4gICAgICogIE9yOlxyXG4gICAgICogIFByb2plY3RzIGVhY2ggZWxlbWVudCBvZiB0aGUgc291cmNlIG9ic2VydmFibGUgc2VxdWVuY2UgdG8gdGhlIG90aGVyIG9ic2VydmFibGUgc2VxdWVuY2UgYW5kIG1lcmdlcyB0aGUgcmVzdWx0aW5nIG9ic2VydmFibGUgc2VxdWVuY2VzIGludG8gb25lIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgKiAgXHJcbiAgICAgKiAgdmFyIHJlcyA9IHNvdXJjZS5zZWxlY3RNYW55KFJ4Lk9ic2VydmFibGUuZnJvbUFycmF5KFsxLDIsM10pKTtcclxuICAgICAqIEBwYXJhbSBzZWxlY3RvciBBIHRyYW5zZm9ybSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGVsZW1lbnQgb3IgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0byBwcm9qZWN0IGVhY2ggZWxlbWVudCBmcm9tIHRoZSBcclxuICAgICAqIHNvdXJjZSBzZXF1ZW5jZSBvbnRvIHdoaWNoIGNvdWxkIGJlIGVpdGhlciBhbiBvYnNlcnZhYmxlIG9yIFByb21pc2UuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcmVzdWx0U2VsZWN0b3JdICBBIHRyYW5zZm9ybSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGVsZW1lbnQgb2YgdGhlIGludGVybWVkaWF0ZSBzZXF1ZW5jZS5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdob3NlIGVsZW1lbnRzIGFyZSB0aGUgcmVzdWx0IG9mIGludm9raW5nIHRoZSBvbmUtdG8tbWFueSB0cmFuc2Zvcm0gZnVuY3Rpb24gY29sbGVjdGlvblNlbGVjdG9yIG9uIGVhY2ggZWxlbWVudCBvZiB0aGUgaW5wdXQgc2VxdWVuY2UgYW5kIHRoZW4gbWFwcGluZyBlYWNoIG9mIHRob3NlIHNlcXVlbmNlIGVsZW1lbnRzIGFuZCB0aGVpciBjb3JyZXNwb25kaW5nIHNvdXJjZSBlbGVtZW50IHRvIGEgcmVzdWx0IGVsZW1lbnQuICAgXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5zZWxlY3RDb25jYXQgPSBvYnNlcnZhYmxlUHJvdG8uY29uY2F0TWFwID0gZnVuY3Rpb24gKHNlbGVjdG9yLCByZXN1bHRTZWxlY3Rvcikge1xyXG4gICAgICBpZiAocmVzdWx0U2VsZWN0b3IpIHtcclxuICAgICAgICAgIHJldHVybiB0aGlzLmNvbmNhdE1hcChmdW5jdGlvbiAoeCwgaSkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZWN0b3JSZXN1bHQgPSBzZWxlY3Rvcih4LCBpKSxcclxuICAgICAgICAgICAgICByZXN1bHQgPSBpc1Byb21pc2Uoc2VsZWN0b3JSZXN1bHQpID8gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKHNlbGVjdG9yUmVzdWx0KSA6IHNlbGVjdG9yUmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5tYXAoZnVuY3Rpb24gKHkpIHtcclxuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0U2VsZWN0b3IoeCwgeSwgaSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHR5cGVvZiBzZWxlY3RvciA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgIHJldHVybiBjb25jYXRNYXAuY2FsbCh0aGlzLCBzZWxlY3Rvcik7XHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIGNvbmNhdE1hcC5jYWxsKHRoaXMsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gc2VsZWN0b3I7XHJcbiAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBSZXR1cm5zIHRoZSBlbGVtZW50cyBvZiB0aGUgc3BlY2lmaWVkIHNlcXVlbmNlIG9yIHRoZSBzcGVjaWZpZWQgdmFsdWUgaW4gYSBzaW5nbGV0b24gc2VxdWVuY2UgaWYgdGhlIHNlcXVlbmNlIGlzIGVtcHR5LlxyXG4gICAgICogIFxyXG4gICAgICogIHZhciByZXMgPSBvYnMgPSB4cy5kZWZhdWx0SWZFbXB0eSgpO1xyXG4gICAgICogIDIgLSBvYnMgPSB4cy5kZWZhdWx0SWZFbXB0eShmYWxzZSk7XHJcbiAgICAgKiAgICAgIFxyXG4gICAgICogQG1lbWJlck9mIE9ic2VydmFibGUjXHJcbiAgICAgKiBAcGFyYW0gZGVmYXVsdFZhbHVlIFRoZSB2YWx1ZSB0byByZXR1cm4gaWYgdGhlIHNlcXVlbmNlIGlzIGVtcHR5LiBJZiBub3QgcHJvdmlkZWQsIHRoaXMgZGVmYXVsdHMgdG8gbnVsbC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgY29udGFpbnMgdGhlIHNwZWNpZmllZCBkZWZhdWx0IHZhbHVlIGlmIHRoZSBzb3VyY2UgaXMgZW1wdHk7IG90aGVyd2lzZSwgdGhlIGVsZW1lbnRzIG9mIHRoZSBzb3VyY2UgaXRzZWxmLiBcclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmRlZmF1bHRJZkVtcHR5ID0gZnVuY3Rpb24gKGRlZmF1bHRWYWx1ZSkge1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIGlmIChkZWZhdWx0VmFsdWUgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBkZWZhdWx0VmFsdWUgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBmb3VuZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgZm91bmQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHgpO1xyXG4gICAgICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWZvdW5kKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KGRlZmF1bHRWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgUmV0dXJucyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgY29udGFpbnMgb25seSBkaXN0aW5jdCBlbGVtZW50cyBhY2NvcmRpbmcgdG8gdGhlIGtleVNlbGVjdG9yIGFuZCB0aGUgY29tcGFyZXIuXHJcbiAgICAgKiAgVXNhZ2Ugb2YgdGhpcyBvcGVyYXRvciBzaG91bGQgYmUgY29uc2lkZXJlZCBjYXJlZnVsbHkgZHVlIHRvIHRoZSBtYWludGVuYW5jZSBvZiBhbiBpbnRlcm5hbCBsb29rdXAgc3RydWN0dXJlIHdoaWNoIGNhbiBncm93IGxhcmdlLiBcclxuICAgICAqIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICB2YXIgcmVzID0gb2JzID0geHMuZGlzdGluY3QoKTtcclxuICAgICAqICAyIC0gb2JzID0geHMuZGlzdGluY3QoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHguaWQ7IH0pO1xyXG4gICAgICogIDIgLSBvYnMgPSB4cy5kaXN0aW5jdChmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5pZDsgfSwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHgudG9TdHJpbmcoKTsgfSk7ICBcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtrZXlTZWxlY3Rvcl0gIEEgZnVuY3Rpb24gdG8gY29tcHV0ZSB0aGUgY29tcGFyaXNvbiBrZXkgZm9yIGVhY2ggZWxlbWVudC5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtrZXlTZXJpYWxpemVyXSAgVXNlZCB0byBzZXJpYWxpemUgdGhlIGdpdmVuIG9iamVjdCBpbnRvIGEgc3RyaW5nIGZvciBvYmplY3QgY29tcGFyaXNvbi5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIG9ubHkgY29udGFpbmluZyB0aGUgZGlzdGluY3QgZWxlbWVudHMsIGJhc2VkIG9uIGEgY29tcHV0ZWQga2V5IHZhbHVlLCBmcm9tIHRoZSBzb3VyY2Ugc2VxdWVuY2UuXHJcbiAgICAgKi9cclxuICAgb2JzZXJ2YWJsZVByb3RvLmRpc3RpbmN0ID0gZnVuY3Rpb24gKGtleVNlbGVjdG9yLCBrZXlTZXJpYWxpemVyKSB7XHJcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRoaXM7XHJcbiAgICAgICAga2V5U2VsZWN0b3IgfHwgKGtleVNlbGVjdG9yID0gaWRlbnRpdHkpO1xyXG4gICAgICAgIGtleVNlcmlhbGl6ZXIgfHwgKGtleVNlcmlhbGl6ZXIgPSBkZWZhdWx0S2V5U2VyaWFsaXplcik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgaGFzaFNldCA9IHt9O1xyXG4gICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGtleSwgc2VyaWFsaXplZEtleSwgb3RoZXJLZXksIGhhc01hdGNoID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleSA9IGtleVNlbGVjdG9yKHgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHNlcmlhbGl6ZWRLZXkgPSBrZXlTZXJpYWxpemVyKGtleSk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGV4Y2VwdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgZm9yIChvdGhlcktleSBpbiBoYXNoU2V0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHNlcmlhbGl6ZWRLZXkgPT09IG90aGVyS2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc01hdGNoID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKCFoYXNNYXRjaCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGhhc2hTZXRbc2VyaWFsaXplZEtleV0gPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh4KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgb2JzZXJ2ZXIub25Db21wbGV0ZWQuYmluZChvYnNlcnZlcikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBHcm91cHMgdGhlIGVsZW1lbnRzIG9mIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgYWNjb3JkaW5nIHRvIGEgc3BlY2lmaWVkIGtleSBzZWxlY3RvciBmdW5jdGlvbiBhbmQgY29tcGFyZXIgYW5kIHNlbGVjdHMgdGhlIHJlc3VsdGluZyBlbGVtZW50cyBieSB1c2luZyBhIHNwZWNpZmllZCBmdW5jdGlvbi5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgdmFyIHJlcyA9IG9ic2VydmFibGUuZ3JvdXBCeShmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5pZDsgfSk7XHJcbiAgICAgKiAgMiAtIG9ic2VydmFibGUuZ3JvdXBCeShmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5pZDsgfSksIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4Lm5hbWU7IH0pO1xyXG4gICAgICogIDMgLSBvYnNlcnZhYmxlLmdyb3VwQnkoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHguaWQ7IH0pLCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5uYW1lOyB9LCBmdW5jdGlvbiAoeCkgeyByZXR1cm4geC50b1N0cmluZygpOyB9KTtcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGtleVNlbGVjdG9yIEEgZnVuY3Rpb24gdG8gZXh0cmFjdCB0aGUga2V5IGZvciBlYWNoIGVsZW1lbnQuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbZWxlbWVudFNlbGVjdG9yXSAgQSBmdW5jdGlvbiB0byBtYXAgZWFjaCBzb3VyY2UgZWxlbWVudCB0byBhbiBlbGVtZW50IGluIGFuIG9ic2VydmFibGUgZ3JvdXAuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBba2V5U2VyaWFsaXplcl0gIFVzZWQgdG8gc2VyaWFsaXplIHRoZSBnaXZlbiBvYmplY3QgaW50byBhIHN0cmluZyBmb3Igb2JqZWN0IGNvbXBhcmlzb24uXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQSBzZXF1ZW5jZSBvZiBvYnNlcnZhYmxlIGdyb3VwcywgZWFjaCBvZiB3aGljaCBjb3JyZXNwb25kcyB0byBhIHVuaXF1ZSBrZXkgdmFsdWUsIGNvbnRhaW5pbmcgYWxsIGVsZW1lbnRzIHRoYXQgc2hhcmUgdGhhdCBzYW1lIGtleSB2YWx1ZS4gICAgXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5ncm91cEJ5ID0gZnVuY3Rpb24gKGtleVNlbGVjdG9yLCBlbGVtZW50U2VsZWN0b3IsIGtleVNlcmlhbGl6ZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5ncm91cEJ5VW50aWwoa2V5U2VsZWN0b3IsIGVsZW1lbnRTZWxlY3RvciwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZU5ldmVyKCk7XHJcbiAgICAgICAgfSwga2V5U2VyaWFsaXplcik7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIEdyb3VwcyB0aGUgZWxlbWVudHMgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBhY2NvcmRpbmcgdG8gYSBzcGVjaWZpZWQga2V5IHNlbGVjdG9yIGZ1bmN0aW9uLlxyXG4gICAgICogIEEgZHVyYXRpb24gc2VsZWN0b3IgZnVuY3Rpb24gaXMgdXNlZCB0byBjb250cm9sIHRoZSBsaWZldGltZSBvZiBncm91cHMuIFdoZW4gYSBncm91cCBleHBpcmVzLCBpdCByZWNlaXZlcyBhbiBPbkNvbXBsZXRlZCBub3RpZmljYXRpb24uIFdoZW4gYSBuZXcgZWxlbWVudCB3aXRoIHRoZSBzYW1lXHJcbiAgICAgKiAga2V5IHZhbHVlIGFzIGEgcmVjbGFpbWVkIGdyb3VwIG9jY3VycywgdGhlIGdyb3VwIHdpbGwgYmUgcmVib3JuIHdpdGggYSBuZXcgbGlmZXRpbWUgcmVxdWVzdC5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgdmFyIHJlcyA9IG9ic2VydmFibGUuZ3JvdXBCeVVudGlsKGZ1bmN0aW9uICh4KSB7IHJldHVybiB4LmlkOyB9LCBudWxsLCAgZnVuY3Rpb24gKCkgeyByZXR1cm4gUnguT2JzZXJ2YWJsZS5uZXZlcigpOyB9KTtcclxuICAgICAqICAyIC0gb2JzZXJ2YWJsZS5ncm91cEJ5KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4LmlkOyB9KSwgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHgubmFtZTsgfSwgIGZ1bmN0aW9uICgpIHsgcmV0dXJuIFJ4Lk9ic2VydmFibGUubmV2ZXIoKTsgfSk7XHJcbiAgICAgKiAgMyAtIG9ic2VydmFibGUuZ3JvdXBCeShmdW5jdGlvbiAoeCkgeyByZXR1cm4geC5pZDsgfSksIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4Lm5hbWU7IH0sICBmdW5jdGlvbiAoKSB7IHJldHVybiBSeC5PYnNlcnZhYmxlLm5ldmVyKCk7IH0sIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4LnRvU3RyaW5nKCk7IH0pO1xyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5U2VsZWN0b3IgQSBmdW5jdGlvbiB0byBleHRyYWN0IHRoZSBrZXkgZm9yIGVhY2ggZWxlbWVudC5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGR1cmF0aW9uU2VsZWN0b3IgQSBmdW5jdGlvbiB0byBzaWduYWwgdGhlIGV4cGlyYXRpb24gb2YgYSBncm91cC5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtrZXlTZXJpYWxpemVyXSAgVXNlZCB0byBzZXJpYWxpemUgdGhlIGdpdmVuIG9iamVjdCBpbnRvIGEgc3RyaW5nIGZvciBvYmplY3QgY29tcGFyaXNvbi5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBcclxuICAgICAqICBBIHNlcXVlbmNlIG9mIG9ic2VydmFibGUgZ3JvdXBzLCBlYWNoIG9mIHdoaWNoIGNvcnJlc3BvbmRzIHRvIGEgdW5pcXVlIGtleSB2YWx1ZSwgY29udGFpbmluZyBhbGwgZWxlbWVudHMgdGhhdCBzaGFyZSB0aGF0IHNhbWUga2V5IHZhbHVlLlxyXG4gICAgICogIElmIGEgZ3JvdXAncyBsaWZldGltZSBleHBpcmVzLCBhIG5ldyBncm91cCB3aXRoIHRoZSBzYW1lIGtleSB2YWx1ZSBjYW4gYmUgY3JlYXRlZCBvbmNlIGFuIGVsZW1lbnQgd2l0aCBzdWNoIGEga2V5IHZhbHVlIGlzIGVuY291dGVyZWQuXHJcbiAgICAgKiAgICAgIFxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uZ3JvdXBCeVVudGlsID0gZnVuY3Rpb24gKGtleVNlbGVjdG9yLCBlbGVtZW50U2VsZWN0b3IsIGR1cmF0aW9uU2VsZWN0b3IsIGtleVNlcmlhbGl6ZXIpIHtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICBlbGVtZW50U2VsZWN0b3IgfHwgKGVsZW1lbnRTZWxlY3RvciA9IGlkZW50aXR5KTtcclxuICAgICAgICBrZXlTZXJpYWxpemVyIHx8IChrZXlTZXJpYWxpemVyID0gZGVmYXVsdEtleVNlcmlhbGl6ZXIpO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIG1hcCA9IHt9LFxyXG4gICAgICAgICAgICAgICAgZ3JvdXBEaXNwb3NhYmxlID0gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoKSxcclxuICAgICAgICAgICAgICAgIHJlZkNvdW50RGlzcG9zYWJsZSA9IG5ldyBSZWZDb3VudERpc3Bvc2FibGUoZ3JvdXBEaXNwb3NhYmxlKTtcclxuICAgICAgICAgICAgZ3JvdXBEaXNwb3NhYmxlLmFkZChzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgZHVyYXRpb24sIGR1cmF0aW9uR3JvdXAsIGVsZW1lbnQsIGZpcmVOZXdNYXBFbnRyeSwgZ3JvdXAsIGtleSwgc2VyaWFsaXplZEtleSwgbWQsIHdyaXRlciwgdztcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAga2V5ID0ga2V5U2VsZWN0b3IoeCk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VyaWFsaXplZEtleSA9IGtleVNlcmlhbGl6ZXIoa2V5KTtcclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHcgaW4gbWFwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcFt3XS5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGZpcmVOZXdNYXBFbnRyeSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICB3cml0ZXIgPSBtYXBbc2VyaWFsaXplZEtleV07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKCF3cml0ZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyID0gbmV3IFN1YmplY3QoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbWFwW3NlcmlhbGl6ZWRLZXldID0gd3JpdGVyO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaXJlTmV3TWFwRW50cnkgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHcgaW4gbWFwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG1hcFt3XS5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChmaXJlTmV3TWFwRW50cnkpIHtcclxuICAgICAgICAgICAgICAgICAgICBncm91cCA9IG5ldyBHcm91cGVkT2JzZXJ2YWJsZShrZXksIHdyaXRlciwgcmVmQ291bnREaXNwb3NhYmxlKTtcclxuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbkdyb3VwID0gbmV3IEdyb3VwZWRPYnNlcnZhYmxlKGtleSwgd3JpdGVyKTtcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IGR1cmF0aW9uU2VsZWN0b3IoZHVyYXRpb25Hcm91cCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKHcgaW4gbWFwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBbd10ub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChncm91cCk7XHJcbiAgICAgICAgICAgICAgICAgICAgbWQgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgICAgICAgICBncm91cERpc3Bvc2FibGUuYWRkKG1kKTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgZXhwaXJlID0gZnVuY3Rpb24gICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNlcmlhbGl6ZWRLZXkgaW4gbWFwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkZWxldGUgbWFwW3NlcmlhbGl6ZWRLZXldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgd3JpdGVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBEaXNwb3NhYmxlLnJlbW92ZShtZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgICAgICBtZC5zZXREaXNwb3NhYmxlKGR1cmF0aW9uLnRha2UoMSkuc3Vic2NyaWJlKG5vb3AsIGZ1bmN0aW9uIChleG4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm9yICh3IGluIG1hcCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbWFwW3ddLm9uRXJyb3IoZXhuKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGV4bik7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBleHBpcmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGVsZW1lbnQgPSBlbGVtZW50U2VsZWN0b3IoeCk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh3IGluIG1hcCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBtYXBbd10ub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB3cml0ZXIub25OZXh0KGVsZW1lbnQpO1xyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoZXgpIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIHcgaW4gbWFwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbWFwW3ddLm9uRXJyb3IoZXgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleCk7XHJcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIHcgaW4gbWFwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbWFwW3ddLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgIHJldHVybiByZWZDb3VudERpc3Bvc2FibGU7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFByb2plY3RzIGVhY2ggZWxlbWVudCBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGludG8gYSBuZXcgZm9ybSBieSBpbmNvcnBvcmF0aW5nIHRoZSBlbGVtZW50J3MgaW5kZXguXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxlY3RvciBBIHRyYW5zZm9ybSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIHNvdXJjZSBlbGVtZW50OyB0aGUgc2Vjb25kIHBhcmFtZXRlciBvZiB0aGUgZnVuY3Rpb24gcmVwcmVzZW50cyB0aGUgaW5kZXggb2YgdGhlIHNvdXJjZSBlbGVtZW50LlxyXG4gICAgICogQHBhcmFtIHtBbnl9IFt0aGlzQXJnXSBPYmplY3QgdG8gdXNlIGFzIHRoaXMgd2hlbiBleGVjdXRpbmcgY2FsbGJhY2suXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aG9zZSBlbGVtZW50cyBhcmUgdGhlIHJlc3VsdCBvZiBpbnZva2luZyB0aGUgdHJhbnNmb3JtIGZ1bmN0aW9uIG9uIGVhY2ggZWxlbWVudCBvZiBzb3VyY2UuIFxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uc2VsZWN0ID0gb2JzZXJ2YWJsZVByb3RvLm1hcCA9IGZ1bmN0aW9uIChzZWxlY3RvciwgdGhpc0FyZykge1xyXG4gICAgICAgIHZhciBwYXJlbnQgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGNvdW50ID0gMDtcclxuICAgICAgICAgICAgcmV0dXJuIHBhcmVudC5zdWJzY3JpYmUoZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBzZWxlY3Rvci5jYWxsKHRoaXNBcmcsIHZhbHVlLCBjb3VudCsrLCBwYXJlbnQpO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleGNlcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChyZXN1bHQpO1xyXG4gICAgICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBvYnNlcnZlci5vbkNvbXBsZXRlZC5iaW5kKG9ic2VydmVyKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0cmlldmVzIHRoZSB2YWx1ZSBvZiBhIHNwZWNpZmllZCBwcm9wZXJ0eSBmcm9tIGFsbCBlbGVtZW50cyBpbiB0aGUgT2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqIEBwYXJhbSB7U3RyaW5nfSBwcm9wZXJ0eSBUaGUgcHJvcGVydHkgdG8gcGx1Y2suXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gUmV0dXJucyBhIG5ldyBPYnNlcnZhYmxlIHNlcXVlbmNlIG9mIHByb3BlcnR5IHZhbHVlcy5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnBsdWNrID0gZnVuY3Rpb24gKHByb3BlcnR5KSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4W3Byb3BlcnR5XTsgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIGZ1bmN0aW9uIHNlbGVjdE1hbnkoc2VsZWN0b3IpIHtcclxuICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uICh4LCBpKSB7XHJcbiAgICAgICAgdmFyIHJlc3VsdCA9IHNlbGVjdG9yKHgsIGkpO1xyXG4gICAgICAgIHJldHVybiBpc1Byb21pc2UocmVzdWx0KSA/IG9ic2VydmFibGVGcm9tUHJvbWlzZShyZXN1bHQpIDogcmVzdWx0O1xyXG4gICAgICB9KS5tZXJnZU9ic2VydmFibGUoKTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBzZWxlY3RNYW55T2JzZXJ2ZXIob25OZXh0LCBvbkVycm9yLCBvbkNvbXBsZXRlZCkge1xyXG4gICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgIHZhciBpbmRleCA9IDA7XHJcblxyXG4gICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KG9uTmV4dCh4LCBpbmRleCsrKSk7XHJcbiAgICAgICAgICB9LFxyXG4gICAgICAgICAgZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgICAgICBvYnNlcnZlci5vbk5leHQob25FcnJvcihlcnIpKTtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIuY29tcGxldGVkKCk7XHJcbiAgICAgICAgICB9LCBcclxuICAgICAgICAgIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KG9uQ29tcGxldGVkKCkpO1xyXG4gICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgIH0pLm1lcmdlQWxsKCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgT25lIG9mIHRoZSBGb2xsb3dpbmc6XHJcbiAgICAgKiAgUHJvamVjdHMgZWFjaCBlbGVtZW50IG9mIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdG8gYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBhbmQgbWVyZ2VzIHRoZSByZXN1bHRpbmcgb2JzZXJ2YWJsZSBzZXF1ZW5jZXMgaW50byBvbmUgb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgdmFyIHJlcyA9IHNvdXJjZS5zZWxlY3RNYW55KGZ1bmN0aW9uICh4KSB7IHJldHVybiBSeC5PYnNlcnZhYmxlLnJhbmdlKDAsIHgpOyB9KTtcclxuICAgICAqICBPcjpcclxuICAgICAqICBQcm9qZWN0cyBlYWNoIGVsZW1lbnQgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0byBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlLCBpbnZva2VzIHRoZSByZXN1bHQgc2VsZWN0b3IgZm9yIHRoZSBzb3VyY2UgZWxlbWVudCBhbmQgZWFjaCBvZiB0aGUgY29ycmVzcG9uZGluZyBpbm5lciBzZXF1ZW5jZSdzIGVsZW1lbnRzLCBhbmQgbWVyZ2VzIHRoZSByZXN1bHRzIGludG8gb25lIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgKiAgXHJcbiAgICAgKiAgdmFyIHJlcyA9IHNvdXJjZS5zZWxlY3RNYW55KGZ1bmN0aW9uICh4KSB7IHJldHVybiBSeC5PYnNlcnZhYmxlLnJhbmdlKDAsIHgpOyB9LCBmdW5jdGlvbiAoeCwgeSkgeyByZXR1cm4geCArIHk7IH0pO1xyXG4gICAgICogIE9yOlxyXG4gICAgICogIFByb2plY3RzIGVhY2ggZWxlbWVudCBvZiB0aGUgc291cmNlIG9ic2VydmFibGUgc2VxdWVuY2UgdG8gdGhlIG90aGVyIG9ic2VydmFibGUgc2VxdWVuY2UgYW5kIG1lcmdlcyB0aGUgcmVzdWx0aW5nIG9ic2VydmFibGUgc2VxdWVuY2VzIGludG8gb25lIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgKiAgXHJcbiAgICAgKiAgdmFyIHJlcyA9IHNvdXJjZS5zZWxlY3RNYW55KFJ4Lk9ic2VydmFibGUuZnJvbUFycmF5KFsxLDIsM10pKTtcclxuICAgICAqIEBwYXJhbSBzZWxlY3RvciBBIHRyYW5zZm9ybSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGVsZW1lbnQgb3IgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0byBwcm9qZWN0IGVhY2ggZWxlbWVudCBmcm9tIHRoZSBcclxuICAgICAqIHNvdXJjZSBzZXF1ZW5jZSBvbnRvIHdoaWNoIGNvdWxkIGJlIGVpdGhlciBhbiBvYnNlcnZhYmxlIG9yIFByb21pc2UuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcmVzdWx0U2VsZWN0b3JdICBBIHRyYW5zZm9ybSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGVsZW1lbnQgb2YgdGhlIGludGVybWVkaWF0ZSBzZXF1ZW5jZS5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdob3NlIGVsZW1lbnRzIGFyZSB0aGUgcmVzdWx0IG9mIGludm9raW5nIHRoZSBvbmUtdG8tbWFueSB0cmFuc2Zvcm0gZnVuY3Rpb24gY29sbGVjdGlvblNlbGVjdG9yIG9uIGVhY2ggZWxlbWVudCBvZiB0aGUgaW5wdXQgc2VxdWVuY2UgYW5kIHRoZW4gbWFwcGluZyBlYWNoIG9mIHRob3NlIHNlcXVlbmNlIGVsZW1lbnRzIGFuZCB0aGVpciBjb3JyZXNwb25kaW5nIHNvdXJjZSBlbGVtZW50IHRvIGEgcmVzdWx0IGVsZW1lbnQuICAgXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5zZWxlY3RNYW55ID0gb2JzZXJ2YWJsZVByb3RvLmZsYXRNYXAgPSBmdW5jdGlvbiAoc2VsZWN0b3IsIHJlc3VsdFNlbGVjdG9yKSB7XHJcbiAgICAgIGlmIChyZXN1bHRTZWxlY3Rvcikge1xyXG4gICAgICAgICAgcmV0dXJuIHRoaXMuc2VsZWN0TWFueShmdW5jdGlvbiAoeCwgaSkge1xyXG4gICAgICAgICAgICB2YXIgc2VsZWN0b3JSZXN1bHQgPSBzZWxlY3Rvcih4LCBpKSxcclxuICAgICAgICAgICAgICByZXN1bHQgPSBpc1Byb21pc2Uoc2VsZWN0b3JSZXN1bHQpID8gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKHNlbGVjdG9yUmVzdWx0KSA6IHNlbGVjdG9yUmVzdWx0O1xyXG5cclxuICAgICAgICAgICAgcmV0dXJuIHJlc3VsdC5zZWxlY3QoZnVuY3Rpb24gKHkpIHtcclxuICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0U2VsZWN0b3IoeCwgeSwgaSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgICAgaWYgKHR5cGVvZiBzZWxlY3RvciA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgIHJldHVybiBzZWxlY3RNYW55LmNhbGwodGhpcywgc2VsZWN0b3IpO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiBzZWxlY3RNYW55LmNhbGwodGhpcywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHJldHVybiBzZWxlY3RvcjtcclxuICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFByb2plY3RzIGVhY2ggZWxlbWVudCBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGludG8gYSBuZXcgc2VxdWVuY2Ugb2Ygb2JzZXJ2YWJsZSBzZXF1ZW5jZXMgYnkgaW5jb3Jwb3JhdGluZyB0aGUgZWxlbWVudCdzIGluZGV4IGFuZCB0aGVuIFxyXG4gICAgICogIHRyYW5zZm9ybXMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBvZiBvYnNlcnZhYmxlIHNlcXVlbmNlcyBpbnRvIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgcHJvZHVjaW5nIHZhbHVlcyBvbmx5IGZyb20gdGhlIG1vc3QgcmVjZW50IG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxlY3RvciBBIHRyYW5zZm9ybSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIHNvdXJjZSBlbGVtZW50OyB0aGUgc2Vjb25kIHBhcmFtZXRlciBvZiB0aGUgZnVuY3Rpb24gcmVwcmVzZW50cyB0aGUgaW5kZXggb2YgdGhlIHNvdXJjZSBlbGVtZW50LlxyXG4gICAgICogQHBhcmFtIHtBbnl9IFt0aGlzQXJnXSBPYmplY3QgdG8gdXNlIGFzIHRoaXMgd2hlbiBleGVjdXRpbmcgY2FsbGJhY2suXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aG9zZSBlbGVtZW50cyBhcmUgdGhlIHJlc3VsdCBvZiBpbnZva2luZyB0aGUgdHJhbnNmb3JtIGZ1bmN0aW9uIG9uIGVhY2ggZWxlbWVudCBvZiBzb3VyY2UgcHJvZHVjaW5nIGFuIE9ic2VydmFibGUgb2YgT2JzZXJ2YWJsZSBzZXF1ZW5jZXMgXHJcbiAgICAgKiAgYW5kIHRoYXQgYXQgYW55IHBvaW50IGluIHRpbWUgcHJvZHVjZXMgdGhlIGVsZW1lbnRzIG9mIHRoZSBtb3N0IHJlY2VudCBpbm5lciBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgaGFzIGJlZW4gcmVjZWl2ZWQuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5zZWxlY3RTd2l0Y2ggPSBvYnNlcnZhYmxlUHJvdG8uZmxhdE1hcExhdGVzdCA9IG9ic2VydmFibGVQcm90by5zd2l0Y2hNYXAgPSBmdW5jdGlvbiAoc2VsZWN0b3IsIHRoaXNBcmcpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zZWxlY3Qoc2VsZWN0b3IsIHRoaXNBcmcpLnN3aXRjaExhdGVzdCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEJ5cGFzc2VzIGEgc3BlY2lmaWVkIG51bWJlciBvZiBlbGVtZW50cyBpbiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGFuZCB0aGVuIHJldHVybnMgdGhlIHJlbWFpbmluZyBlbGVtZW50cy5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjb3VudCBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHNraXAgYmVmb3JlIHJldHVybmluZyB0aGUgcmVtYWluaW5nIGVsZW1lbnRzLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBjb250YWlucyB0aGUgZWxlbWVudHMgdGhhdCBvY2N1ciBhZnRlciB0aGUgc3BlY2lmaWVkIGluZGV4IGluIHRoZSBpbnB1dCBzZXF1ZW5jZS4gICBcclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnNraXAgPSBmdW5jdGlvbiAoY291bnQpIHtcclxuICAgICAgICBpZiAoY291bnQgPCAwKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihhcmd1bWVudE91dE9mUmFuZ2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgb2JzZXJ2YWJsZSA9IHRoaXM7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgcmVtYWluaW5nID0gY291bnQ7XHJcbiAgICAgICAgICAgIHJldHVybiBvYnNlcnZhYmxlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlbWFpbmluZyA8PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHgpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICByZW1haW5pbmctLTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgb2JzZXJ2ZXIub25Db21wbGV0ZWQuYmluZChvYnNlcnZlcikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBCeXBhc3NlcyBlbGVtZW50cyBpbiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGFzIGxvbmcgYXMgYSBzcGVjaWZpZWQgY29uZGl0aW9uIGlzIHRydWUgYW5kIHRoZW4gcmV0dXJucyB0aGUgcmVtYWluaW5nIGVsZW1lbnRzLlxyXG4gICAgICogIFRoZSBlbGVtZW50J3MgaW5kZXggaXMgdXNlZCBpbiB0aGUgbG9naWMgb2YgdGhlIHByZWRpY2F0ZSBmdW5jdGlvbi5cclxuICAgICAqICBcclxuICAgICAqICB2YXIgcmVzID0gc291cmNlLnNraXBXaGlsZShmdW5jdGlvbiAodmFsdWUpIHsgcmV0dXJuIHZhbHVlIDwgMTA7IH0pO1xyXG4gICAgICogIHZhciByZXMgPSBzb3VyY2Uuc2tpcFdoaWxlKGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHsgcmV0dXJuIHZhbHVlIDwgMTAgfHwgaW5kZXggPCAxMDsgfSk7XHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgQSBmdW5jdGlvbiB0byB0ZXN0IGVhY2ggZWxlbWVudCBmb3IgYSBjb25kaXRpb247IHRoZSBzZWNvbmQgcGFyYW1ldGVyIG9mIHRoZSBmdW5jdGlvbiByZXByZXNlbnRzIHRoZSBpbmRleCBvZiB0aGUgc291cmNlIGVsZW1lbnQuXHJcbiAgICAgKiBAcGFyYW0ge0FueX0gW3RoaXNBcmddIE9iamVjdCB0byB1c2UgYXMgdGhpcyB3aGVuIGV4ZWN1dGluZyBjYWxsYmFjay4gICAgIFxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBjb250YWlucyB0aGUgZWxlbWVudHMgZnJvbSB0aGUgaW5wdXQgc2VxdWVuY2Ugc3RhcnRpbmcgYXQgdGhlIGZpcnN0IGVsZW1lbnQgaW4gdGhlIGxpbmVhciBzZXJpZXMgdGhhdCBkb2VzIG5vdCBwYXNzIHRoZSB0ZXN0IHNwZWNpZmllZCBieSBwcmVkaWNhdGUuICAgXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5za2lwV2hpbGUgPSBmdW5jdGlvbiAocHJlZGljYXRlLCB0aGlzQXJnKSB7XHJcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRoaXM7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgaSA9IDAsIHJ1bm5pbmcgPSBmYWxzZTtcclxuICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgIGlmICghcnVubmluZykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bm5pbmcgPSAhcHJlZGljYXRlLmNhbGwodGhpc0FyZywgeCwgaSsrLCBzb3VyY2UpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChydW5uaW5nKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBvYnNlcnZlci5vbkNvbXBsZXRlZC5iaW5kKG9ic2VydmVyKSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFJldHVybnMgYSBzcGVjaWZpZWQgbnVtYmVyIG9mIGNvbnRpZ3VvdXMgZWxlbWVudHMgZnJvbSB0aGUgc3RhcnQgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSwgdXNpbmcgdGhlIHNwZWNpZmllZCBzY2hlZHVsZXIgZm9yIHRoZSBlZGdlIGNhc2Ugb2YgdGFrZSgwKS5cclxuICAgICAqICBcclxuICAgICAqICB2YXIgcmVzID0gc291cmNlLnRha2UoNSk7XHJcbiAgICAgKiAgdmFyIHJlcyA9IHNvdXJjZS50YWtlKDAsIFJ4LlNjaGVkdWxlci50aW1lb3V0KTtcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBjb3VudCBUaGUgbnVtYmVyIG9mIGVsZW1lbnRzIHRvIHJldHVybi5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSBTY2hlZHVsZXIgdXNlZCB0byBwcm9kdWNlIGFuIE9uQ29tcGxldGVkIG1lc3NhZ2UgaW4gY2FzZSA8cGFyYW1yZWYgbmFtZT1cImNvdW50IGNvdW50PC9wYXJhbXJlZj4gaXMgc2V0IHRvIDAuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbnRhaW5zIHRoZSBzcGVjaWZpZWQgbnVtYmVyIG9mIGVsZW1lbnRzIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBpbnB1dCBzZXF1ZW5jZS4gIFxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8udGFrZSA9IGZ1bmN0aW9uIChjb3VudCwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgaWYgKGNvdW50IDwgMCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYXJndW1lbnRPdXRPZlJhbmdlKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGNvdW50ID09PSAwKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBvYnNlcnZhYmxlRW1wdHkoc2NoZWR1bGVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdmFyIG9ic2VydmFibGUgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIHJlbWFpbmluZyA9IGNvdW50O1xyXG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgIGlmIChyZW1haW5pbmcgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVtYWluaW5nLS07XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyZW1haW5pbmcgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIG9ic2VydmVyLm9uQ29tcGxldGVkLmJpbmQob2JzZXJ2ZXIpKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgUmV0dXJucyBlbGVtZW50cyBmcm9tIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgYXMgbG9uZyBhcyBhIHNwZWNpZmllZCBjb25kaXRpb24gaXMgdHJ1ZS5cclxuICAgICAqICBUaGUgZWxlbWVudCdzIGluZGV4IGlzIHVzZWQgaW4gdGhlIGxvZ2ljIG9mIHRoZSBwcmVkaWNhdGUgZnVuY3Rpb24uXHJcbiAgICAgKiAgXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIHZhciByZXMgPSBzb3VyY2UudGFrZVdoaWxlKGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gdmFsdWUgPCAxMDsgfSk7XHJcbiAgICAgKiAgdmFyIHJlcyA9IHNvdXJjZS50YWtlV2hpbGUoZnVuY3Rpb24gKHZhbHVlLCBpbmRleCkgeyByZXR1cm4gdmFsdWUgPCAxMCB8fCBpbmRleCA8IDEwOyB9KTtcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBBIGZ1bmN0aW9uIHRvIHRlc3QgZWFjaCBlbGVtZW50IGZvciBhIGNvbmRpdGlvbjsgdGhlIHNlY29uZCBwYXJhbWV0ZXIgb2YgdGhlIGZ1bmN0aW9uIHJlcHJlc2VudHMgdGhlIGluZGV4IG9mIHRoZSBzb3VyY2UgZWxlbWVudC5cclxuICAgICAqIEBwYXJhbSB7QW55fSBbdGhpc0FyZ10gT2JqZWN0IHRvIHVzZSBhcyB0aGlzIHdoZW4gZXhlY3V0aW5nIGNhbGxiYWNrLiAgICAgXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbnRhaW5zIHRoZSBlbGVtZW50cyBmcm9tIHRoZSBpbnB1dCBzZXF1ZW5jZSB0aGF0IG9jY3VyIGJlZm9yZSB0aGUgZWxlbWVudCBhdCB3aGljaCB0aGUgdGVzdCBubyBsb25nZXIgcGFzc2VzLiAgXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by50YWtlV2hpbGUgPSBmdW5jdGlvbiAocHJlZGljYXRlLCB0aGlzQXJnKSB7XHJcbiAgICAgICAgdmFyIG9ic2VydmFibGUgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGkgPSAwLCBydW5uaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGUuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAocnVubmluZykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJ1bm5pbmcgPSBwcmVkaWNhdGUuY2FsbCh0aGlzQXJnLCB4LCBpKyssIG9ic2VydmFibGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAocnVubmluZykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQoeCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIG9ic2VydmVyLm9uQ29tcGxldGVkLmJpbmQob2JzZXJ2ZXIpKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgRmlsdGVycyB0aGUgZWxlbWVudHMgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBiYXNlZCBvbiBhIHByZWRpY2F0ZSBieSBpbmNvcnBvcmF0aW5nIHRoZSBlbGVtZW50J3MgaW5kZXguXHJcbiAgICAgKiAgXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIHZhciByZXMgPSBzb3VyY2Uud2hlcmUoZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB2YWx1ZSA8IDEwOyB9KTtcclxuICAgICAqICB2YXIgcmVzID0gc291cmNlLndoZXJlKGZ1bmN0aW9uICh2YWx1ZSwgaW5kZXgpIHsgcmV0dXJuIHZhbHVlIDwgMTAgfHwgaW5kZXggPCAxMDsgfSk7XHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBwcmVkaWNhdGUgQSBmdW5jdGlvbiB0byB0ZXN0IGVhY2ggc291cmNlIGVsZW1lbnQgZm9yIGEgY29uZGl0aW9uOyB0aGUgc2Vjb25kIHBhcmFtZXRlciBvZiB0aGUgZnVuY3Rpb24gcmVwcmVzZW50cyB0aGUgaW5kZXggb2YgdGhlIHNvdXJjZSBlbGVtZW50LlxyXG4gICAgICogQHBhcmFtIHtBbnl9IFt0aGlzQXJnXSBPYmplY3QgdG8gdXNlIGFzIHRoaXMgd2hlbiBleGVjdXRpbmcgY2FsbGJhY2suXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbnRhaW5zIGVsZW1lbnRzIGZyb20gdGhlIGlucHV0IHNlcXVlbmNlIHRoYXQgc2F0aXNmeSB0aGUgY29uZGl0aW9uLiAgIFxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8ud2hlcmUgPSBvYnNlcnZhYmxlUHJvdG8uZmlsdGVyID0gZnVuY3Rpb24gKHByZWRpY2F0ZSwgdGhpc0FyZykge1xyXG4gICAgICAgIHZhciBwYXJlbnQgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGNvdW50ID0gMDtcclxuICAgICAgICAgICAgcmV0dXJuIHBhcmVudC5zdWJzY3JpYmUoZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgc2hvdWxkUnVuO1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBzaG91bGRSdW4gPSBwcmVkaWNhdGUuY2FsbCh0aGlzQXJnLCB2YWx1ZSwgY291bnQrKywgcGFyZW50KTtcclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXhjZXB0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoc2hvdWxkUnVuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgb2JzZXJ2ZXIub25Db21wbGV0ZWQuYmluZChvYnNlcnZlcikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgb2JzZXJ2YWJsZVByb3RvLmZpbmFsVmFsdWUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgdmFyIGhhc1ZhbHVlID0gZmFsc2UsIHZhbHVlO1xyXG4gICAgICByZXR1cm4gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgIGhhc1ZhbHVlID0gdHJ1ZTtcclxuICAgICAgICB2YWx1ZSA9IHg7XHJcbiAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoIWhhc1ZhbHVlKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKG5ldyBFcnJvcihzZXF1ZW5jZUNvbnRhaW5zTm9FbGVtZW50cykpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQodmFsdWUpO1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgICBmdW5jdGlvbiBleHRyZW1hQnkoc291cmNlLCBrZXlTZWxlY3RvciwgY29tcGFyZXIpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBoYXNWYWx1ZSA9IGZhbHNlLCBsYXN0S2V5ID0gbnVsbCwgbGlzdCA9IFtdO1xyXG4gICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGNvbXBhcmlzb24sIGtleTtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAga2V5ID0ga2V5U2VsZWN0b3IoeCk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbXBhcmlzb24gPSAwO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFoYXNWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGhhc1ZhbHVlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBsYXN0S2V5ID0ga2V5O1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb21wYXJpc29uID0gY29tcGFyZXIoa2V5LCBsYXN0S2V5KTtcclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChleDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleDEpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGNvbXBhcmlzb24gPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGFzdEtleSA9IGtleTtcclxuICAgICAgICAgICAgICAgICAgICBsaXN0ID0gW107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoY29tcGFyaXNvbiA+PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbGlzdC5wdXNoKHgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQobGlzdCk7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBmaXJzdE9ubHkoeCkge1xyXG4gICAgICAgIGlmICh4Lmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3Ioc2VxdWVuY2VDb250YWluc05vRWxlbWVudHMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4geFswXTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGxpZXMgYW4gYWNjdW11bGF0b3IgZnVuY3Rpb24gb3ZlciBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlLCByZXR1cm5pbmcgdGhlIHJlc3VsdCBvZiB0aGUgYWdncmVnYXRpb24gYXMgYSBzaW5nbGUgZWxlbWVudCBpbiB0aGUgcmVzdWx0IHNlcXVlbmNlLiBUaGUgc3BlY2lmaWVkIHNlZWQgdmFsdWUgaXMgdXNlZCBhcyB0aGUgaW5pdGlhbCBhY2N1bXVsYXRvciB2YWx1ZS5cclxuICAgICAqIEZvciBhZ2dyZWdhdGlvbiBiZWhhdmlvciB3aXRoIGluY3JlbWVudGFsIGludGVybWVkaWF0ZSByZXN1bHRzLCBzZWUgT2JzZXJ2YWJsZS5zY2FuLlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIDEgLSByZXMgPSBzb3VyY2UuYWdncmVnYXRlKGZ1bmN0aW9uIChhY2MsIHgpIHsgcmV0dXJuIGFjYyArIHg7IH0pO1xyXG4gICAgICogMiAtIHJlcyA9IHNvdXJjZS5hZ2dyZWdhdGUoMCwgZnVuY3Rpb24gKGFjYywgeCkgeyByZXR1cm4gYWNjICsgeDsgfSk7XHJcbiAgICAgKiBAcGFyYW0ge01peGVkfSBbc2VlZF0gVGhlIGluaXRpYWwgYWNjdW11bGF0b3IgdmFsdWUuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhY2N1bXVsYXRvciBBbiBhY2N1bXVsYXRvciBmdW5jdGlvbiB0byBiZSBpbnZva2VkIG9uIGVhY2ggZWxlbWVudC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgYSBzaW5nbGUgZWxlbWVudCB3aXRoIHRoZSBmaW5hbCBhY2N1bXVsYXRvciB2YWx1ZS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmFnZ3JlZ2F0ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICB2YXIgc2VlZCwgaGFzU2VlZCwgYWNjdW11bGF0b3I7XHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIpIHtcclxuICAgICAgICAgICAgc2VlZCA9IGFyZ3VtZW50c1swXTtcclxuICAgICAgICAgICAgaGFzU2VlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIGFjY3VtdWxhdG9yID0gYXJndW1lbnRzWzFdO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGFjY3VtdWxhdG9yID0gYXJndW1lbnRzWzBdO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gaGFzU2VlZCA/IHRoaXMuc2NhbihzZWVkLCBhY2N1bXVsYXRvcikuc3RhcnRXaXRoKHNlZWQpLmZpbmFsVmFsdWUoKSA6IHRoaXMuc2NhbihhY2N1bXVsYXRvcikuZmluYWxWYWx1ZSgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEFwcGxpZXMgYW4gYWNjdW11bGF0b3IgZnVuY3Rpb24gb3ZlciBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlLCByZXR1cm5pbmcgdGhlIHJlc3VsdCBvZiB0aGUgYWdncmVnYXRpb24gYXMgYSBzaW5nbGUgZWxlbWVudCBpbiB0aGUgcmVzdWx0IHNlcXVlbmNlLiBUaGUgc3BlY2lmaWVkIHNlZWQgdmFsdWUgaXMgdXNlZCBhcyB0aGUgaW5pdGlhbCBhY2N1bXVsYXRvciB2YWx1ZS5cclxuICAgICAqIEZvciBhZ2dyZWdhdGlvbiBiZWhhdmlvciB3aXRoIGluY3JlbWVudGFsIGludGVybWVkaWF0ZSByZXN1bHRzLCBzZWUgT2JzZXJ2YWJsZS5zY2FuLlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIDEgLSByZXMgPSBzb3VyY2UucmVkdWNlKGZ1bmN0aW9uIChhY2MsIHgpIHsgcmV0dXJuIGFjYyArIHg7IH0pO1xyXG4gICAgICogMiAtIHJlcyA9IHNvdXJjZS5yZWR1Y2UoZnVuY3Rpb24gKGFjYywgeCkgeyByZXR1cm4gYWNjICsgeDsgfSwgMCk7XHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhY2N1bXVsYXRvciBBbiBhY2N1bXVsYXRvciBmdW5jdGlvbiB0byBiZSBpbnZva2VkIG9uIGVhY2ggZWxlbWVudC5cclxuICAgICAqIEBwYXJhbSB7QW55fSBbc2VlZF0gVGhlIGluaXRpYWwgYWNjdW11bGF0b3IgdmFsdWUuICAgICBcclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgYSBzaW5nbGUgZWxlbWVudCB3aXRoIHRoZSBmaW5hbCBhY2N1bXVsYXRvciB2YWx1ZS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnJlZHVjZSA9IGZ1bmN0aW9uIChhY2N1bXVsYXRvcikge1xyXG4gICAgICAgIHZhciBzZWVkLCBoYXNTZWVkO1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAyKSB7XHJcbiAgICAgICAgICAgIGhhc1NlZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICBzZWVkID0gYXJndW1lbnRzWzFdO1xyXG4gICAgICAgIH0gXHJcbiAgICAgICAgcmV0dXJuIGhhc1NlZWQgPyB0aGlzLnNjYW4oc2VlZCwgYWNjdW11bGF0b3IpLnN0YXJ0V2l0aChzZWVkKS5maW5hbFZhbHVlKCkgOiB0aGlzLnNjYW4oYWNjdW11bGF0b3IpLmZpbmFsVmFsdWUoKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBEZXRlcm1pbmVzIHdoZXRoZXIgYW55IGVsZW1lbnQgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBzYXRpc2ZpZXMgYSBjb25kaXRpb24gaWYgcHJlc2VudCwgZWxzZSBpZiBhbnkgaXRlbXMgYXJlIGluIHRoZSBzZXF1ZW5jZS5cclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiB2YXIgcmVzdWx0ID0gc291cmNlLmFueSgpO1xyXG4gICAgICogdmFyIHJlc3VsdCA9IHNvdXJjZS5hbnkoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHggPiAzOyB9KTtcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGVdIEEgZnVuY3Rpb24gdG8gdGVzdCBlYWNoIGVsZW1lbnQgZm9yIGEgY29uZGl0aW9uLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyBhIHNpbmdsZSBlbGVtZW50IGRldGVybWluaW5nIHdoZXRoZXIgYW55IGVsZW1lbnRzIGluIHRoZSBzb3VyY2Ugc2VxdWVuY2UgcGFzcyB0aGUgdGVzdCBpbiB0aGUgc3BlY2lmaWVkIHByZWRpY2F0ZSBpZiBnaXZlbiwgZWxzZSBpZiBhbnkgaXRlbXMgYXJlIGluIHRoZSBzZXF1ZW5jZS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnNvbWUgPSBvYnNlcnZhYmxlUHJvdG8uYW55ID0gZnVuY3Rpb24gKHByZWRpY2F0ZSwgdGhpc0FyZykge1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBwcmVkaWNhdGUgPyBcclxuICAgICAgICAgICAgc291cmNlLndoZXJlKHByZWRpY2F0ZSwgdGhpc0FyZykuYW55KCkgOiBcclxuICAgICAgICAgICAgbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHRydWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KGZhbHNlKTtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIERldGVybWluZXMgd2hldGhlciBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGlzIGVtcHR5LlxyXG4gICAgICpcclxuICAgICAqIEBtZW1iZXJPZiBPYnNlcnZhYmxlI1xyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyBhIHNpbmdsZSBlbGVtZW50IGRldGVybWluaW5nIHdoZXRoZXIgdGhlIHNvdXJjZSBzZXF1ZW5jZSBpcyBlbXB0eS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmlzRW1wdHkgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuYW55KCkuc2VsZWN0KGZ1bmN0aW9uIChiKSB7IHJldHVybiAhYjsgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGFsbCBlbGVtZW50cyBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHNhdGlzZnkgYSBjb25kaXRpb24uXHJcbiAgICAgKiBcclxuICAgICAqIDEgLSByZXMgPSBzb3VyY2UuYWxsKGZ1bmN0aW9uICh2YWx1ZSkgeyByZXR1cm4gdmFsdWUubGVuZ3RoID4gMzsgfSk7XHJcbiAgICAgKiBAbWVtYmVyT2YgT2JzZXJ2YWJsZSNcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGVdIEEgZnVuY3Rpb24gdG8gdGVzdCBlYWNoIGVsZW1lbnQgZm9yIGEgY29uZGl0aW9uLlxyXG4gICAgICogQHBhcmFtIHtBbnl9IFt0aGlzQXJnXSBPYmplY3QgdG8gdXNlIGFzIHRoaXMgd2hlbiBleGVjdXRpbmcgY2FsbGJhY2suXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBjb250YWluaW5nIGEgc2luZ2xlIGVsZW1lbnQgZGV0ZXJtaW5pbmcgd2hldGhlciBhbGwgZWxlbWVudHMgaW4gdGhlIHNvdXJjZSBzZXF1ZW5jZSBwYXNzIHRoZSB0ZXN0IGluIHRoZSBzcGVjaWZpZWQgcHJlZGljYXRlLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uZXZlcnkgPSBvYnNlcnZhYmxlUHJvdG8uYWxsID0gZnVuY3Rpb24gKHByZWRpY2F0ZSwgdGhpc0FyZykge1xyXG4gICAgICAgIHJldHVybiB0aGlzLndoZXJlKGZ1bmN0aW9uICh2KSB7XHJcbiAgICAgICAgICAgIHJldHVybiAhcHJlZGljYXRlKHYpO1xyXG4gICAgICAgIH0sIHRoaXNBcmcpLmFueSgpLnNlbGVjdChmdW5jdGlvbiAoYikge1xyXG4gICAgICAgICAgICByZXR1cm4gIWI7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogRGV0ZXJtaW5lcyB3aGV0aGVyIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbnMgYSBzcGVjaWZpZWQgZWxlbWVudCB3aXRoIGFuIG9wdGlvbmFsIGVxdWFsaXR5IGNvbXBhcmVyLlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIDEgLSByZXMgPSBzb3VyY2UuY29udGFpbnMoNDIpO1xyXG4gICAgICogMiAtIHJlcyA9IHNvdXJjZS5jb250YWlucyh7IHZhbHVlOiA0MiB9LCBmdW5jdGlvbiAoeCwgeSkgeyByZXR1cm4geC52YWx1ZSA9PT0geS52YWx1ZTsgfSk7XHJcbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGxvY2F0ZSBpbiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmVyXSBBbiBlcXVhbGl0eSBjb21wYXJlciB0byBjb21wYXJlIGVsZW1lbnRzLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyBhIHNpbmdsZSBlbGVtZW50IGRldGVybWluaW5nIHdoZXRoZXIgdGhlIHNvdXJjZSBzZXF1ZW5jZSBjb250YWlucyBhbiBlbGVtZW50IHRoYXQgaGFzIHRoZSBzcGVjaWZpZWQgdmFsdWUuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5jb250YWlucyA9IGZ1bmN0aW9uICh2YWx1ZSwgY29tcGFyZXIpIHtcclxuICAgICAgICBjb21wYXJlciB8fCAoY29tcGFyZXIgPSBkZWZhdWx0Q29tcGFyZXIpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLndoZXJlKGZ1bmN0aW9uICh2KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBjb21wYXJlcih2LCB2YWx1ZSk7XHJcbiAgICAgICAgfSkuYW55KCk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgYSB2YWx1ZSB0aGF0IHJlcHJlc2VudHMgaG93IG1hbnkgZWxlbWVudHMgaW4gdGhlIHNwZWNpZmllZCBvYnNlcnZhYmxlIHNlcXVlbmNlIHNhdGlzZnkgYSBjb25kaXRpb24gaWYgcHJvdmlkZWQsIGVsc2UgdGhlIGNvdW50IG9mIGl0ZW1zLlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIHJlcyA9IHNvdXJjZS5jb3VudCgpO1xyXG4gICAgICogcmVzID0gc291cmNlLmNvdW50KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ID4gMzsgfSk7XHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlXUEgZnVuY3Rpb24gdG8gdGVzdCBlYWNoIGVsZW1lbnQgZm9yIGEgY29uZGl0aW9uLlxyXG4gICAgICogQHBhcmFtIHtBbnl9IFt0aGlzQXJnXSBPYmplY3QgdG8gdXNlIGFzIHRoaXMgd2hlbiBleGVjdXRpbmcgY2FsbGJhY2suICAgICAgICBcclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgYSBzaW5nbGUgZWxlbWVudCB3aXRoIGEgbnVtYmVyIHRoYXQgcmVwcmVzZW50cyBob3cgbWFueSBlbGVtZW50cyBpbiB0aGUgaW5wdXQgc2VxdWVuY2Ugc2F0aXNmeSB0aGUgY29uZGl0aW9uIGluIHRoZSBwcmVkaWNhdGUgZnVuY3Rpb24gaWYgcHJvdmlkZWQsIGVsc2UgdGhlIGNvdW50IG9mIGl0ZW1zIGluIHRoZSBzZXF1ZW5jZS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmNvdW50ID0gZnVuY3Rpb24gKHByZWRpY2F0ZSwgdGhpc0FyZykge1xyXG4gICAgICAgIHJldHVybiBwcmVkaWNhdGUgP1xyXG4gICAgICAgICAgICB0aGlzLndoZXJlKHByZWRpY2F0ZSwgdGhpc0FyZykuY291bnQoKSA6XHJcbiAgICAgICAgICAgIHRoaXMuYWdncmVnYXRlKDAsIGZ1bmN0aW9uIChjb3VudCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGNvdW50ICsgMTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tcHV0ZXMgdGhlIHN1bSBvZiBhIHNlcXVlbmNlIG9mIHZhbHVlcyB0aGF0IGFyZSBvYnRhaW5lZCBieSBpbnZva2luZyBhbiBvcHRpb25hbCB0cmFuc2Zvcm0gZnVuY3Rpb24gb24gZWFjaCBlbGVtZW50IG9mIHRoZSBpbnB1dCBzZXF1ZW5jZSwgZWxzZSBpZiBub3Qgc3BlY2lmaWVkIGNvbXB1dGVzIHRoZSBzdW0gb24gZWFjaCBpdGVtIGluIHRoZSBzZXF1ZW5jZS5cclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiB2YXIgcmVzID0gc291cmNlLnN1bSgpO1xyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5zdW0oZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHgudmFsdWU7IH0pO1xyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3NlbGVjdG9yXSBBIHRyYW5zZm9ybSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGVsZW1lbnQuXHJcbiAgICAgKiBAcGFyYW0ge0FueX0gW3RoaXNBcmddIE9iamVjdCB0byB1c2UgYXMgdGhpcyB3aGVuIGV4ZWN1dGluZyBjYWxsYmFjay4gICAgICAgIFxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyBhIHNpbmdsZSBlbGVtZW50IHdpdGggdGhlIHN1bSBvZiB0aGUgdmFsdWVzIGluIHRoZSBzb3VyY2Ugc2VxdWVuY2UuXHJcbiAgICAgKi8gICAgXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uc3VtID0gZnVuY3Rpb24gKGtleVNlbGVjdG9yLCB0aGlzQXJnKSB7XHJcbiAgICAgICAgcmV0dXJuIGtleVNlbGVjdG9yID8gXHJcbiAgICAgICAgICAgIHRoaXMuc2VsZWN0KGtleVNlbGVjdG9yLCB0aGlzQXJnKS5zdW0oKSA6XHJcbiAgICAgICAgICAgIHRoaXMuYWdncmVnYXRlKDAsIGZ1bmN0aW9uIChwcmV2LCBjdXJyKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcHJldiArIGN1cnI7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGVsZW1lbnRzIGluIGFuIG9ic2VydmFibGUgc2VxdWVuY2Ugd2l0aCB0aGUgbWluaW11bSBrZXkgdmFsdWUgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgY29tcGFyZXIuXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5taW5CeShmdW5jdGlvbiAoeCkgeyByZXR1cm4geC52YWx1ZTsgfSk7XHJcbiAgICAgKiB2YXIgcmVzID0gc291cmNlLm1pbkJ5KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4LnZhbHVlOyB9LCBmdW5jdGlvbiAoeCwgeSkgeyByZXR1cm4geCAtIHk7IH0pO1xyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0ga2V5U2VsZWN0b3IgS2V5IHNlbGVjdG9yIGZ1bmN0aW9uLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmVyXSBDb21wYXJlciB1c2VkIHRvIGNvbXBhcmUga2V5IHZhbHVlcy5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgYSBsaXN0IG9mIHplcm8gb3IgbW9yZSBlbGVtZW50cyB0aGF0IGhhdmUgYSBtaW5pbXVtIGtleSB2YWx1ZS5cclxuICAgICAqLyAgXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8ubWluQnkgPSBmdW5jdGlvbiAoa2V5U2VsZWN0b3IsIGNvbXBhcmVyKSB7XHJcbiAgICAgICAgY29tcGFyZXIgfHwgKGNvbXBhcmVyID0gZGVmYXVsdFN1YkNvbXBhcmVyKTtcclxuICAgICAgICByZXR1cm4gZXh0cmVtYUJ5KHRoaXMsIGtleVNlbGVjdG9yLCBmdW5jdGlvbiAoeCwgeSkge1xyXG4gICAgICAgICAgICByZXR1cm4gY29tcGFyZXIoeCwgeSkgKiAtMTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBtaW5pbXVtIGVsZW1lbnQgaW4gYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBhY2NvcmRpbmcgdG8gdGhlIG9wdGlvbmFsIGNvbXBhcmVyIGVsc2UgYSBkZWZhdWx0IGdyZWF0ZXIgdGhhbiBsZXNzIHRoYW4gY2hlY2suXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5taW4oKTtcclxuICAgICAqIHZhciByZXMgPSBzb3VyY2UubWluKGZ1bmN0aW9uICh4LCB5KSB7IHJldHVybiB4LnZhbHVlIC0geS52YWx1ZTsgfSk7XHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbY29tcGFyZXJdIENvbXBhcmVyIHVzZWQgdG8gY29tcGFyZSBlbGVtZW50cy5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgYSBzaW5nbGUgZWxlbWVudCB3aXRoIHRoZSBtaW5pbXVtIGVsZW1lbnQgaW4gdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLm1pbiA9IGZ1bmN0aW9uIChjb21wYXJlcikge1xyXG4gICAgICAgIHJldHVybiB0aGlzLm1pbkJ5KGlkZW50aXR5LCBjb21wYXJlcikuc2VsZWN0KGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmaXJzdE9ubHkoeCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgZWxlbWVudHMgaW4gYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aXRoIHRoZSBtYXhpbXVtICBrZXkgdmFsdWUgYWNjb3JkaW5nIHRvIHRoZSBzcGVjaWZpZWQgY29tcGFyZXIuXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5tYXhCeShmdW5jdGlvbiAoeCkgeyByZXR1cm4geC52YWx1ZTsgfSk7XHJcbiAgICAgKiB2YXIgcmVzID0gc291cmNlLm1heEJ5KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4LnZhbHVlOyB9LCBmdW5jdGlvbiAoeCwgeSkgeyByZXR1cm4geCAtIHk7OyB9KTtcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGtleVNlbGVjdG9yIEtleSBzZWxlY3RvciBmdW5jdGlvbi5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtjb21wYXJlcl0gIENvbXBhcmVyIHVzZWQgdG8gY29tcGFyZSBrZXkgdmFsdWVzLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyBhIGxpc3Qgb2YgemVybyBvciBtb3JlIGVsZW1lbnRzIHRoYXQgaGF2ZSBhIG1heGltdW0ga2V5IHZhbHVlLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8ubWF4QnkgPSBmdW5jdGlvbiAoa2V5U2VsZWN0b3IsIGNvbXBhcmVyKSB7XHJcbiAgICAgICAgY29tcGFyZXIgfHwgKGNvbXBhcmVyID0gZGVmYXVsdFN1YkNvbXBhcmVyKTtcclxuICAgICAgICByZXR1cm4gZXh0cmVtYUJ5KHRoaXMsIGtleVNlbGVjdG9yLCBjb21wYXJlcik7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgbWF4aW11bSB2YWx1ZSBpbiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGNvbXBhcmVyLlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIHZhciByZXMgPSBzb3VyY2UubWF4KCk7XHJcbiAgICAgKiB2YXIgcmVzID0gc291cmNlLm1heChmdW5jdGlvbiAoeCwgeSkgeyByZXR1cm4geC52YWx1ZSAtIHkudmFsdWU7IH0pO1xyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmVyXSBDb21wYXJlciB1c2VkIHRvIGNvbXBhcmUgZWxlbWVudHMuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBjb250YWluaW5nIGEgc2luZ2xlIGVsZW1lbnQgd2l0aCB0aGUgbWF4aW11bSBlbGVtZW50IGluIHRoZSBzb3VyY2Ugc2VxdWVuY2UuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5tYXggPSBmdW5jdGlvbiAoY29tcGFyZXIpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5tYXhCeShpZGVudGl0eSwgY29tcGFyZXIpLnNlbGVjdChmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICByZXR1cm4gZmlyc3RPbmx5KHgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbXB1dGVzIHRoZSBhdmVyYWdlIG9mIGFuIG9ic2VydmFibGUgc2VxdWVuY2Ugb2YgdmFsdWVzIHRoYXQgYXJlIGluIHRoZSBzZXF1ZW5jZSBvciBvYnRhaW5lZCBieSBpbnZva2luZyBhIHRyYW5zZm9ybSBmdW5jdGlvbiBvbiBlYWNoIGVsZW1lbnQgb2YgdGhlIGlucHV0IHNlcXVlbmNlIGlmIHByZXNlbnQuXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogdmFyIHJlcyA9IHJlcyA9IHNvdXJjZS5hdmVyYWdlKCk7XHJcbiAgICAgKiB2YXIgcmVzID0gcmVzID0gc291cmNlLmF2ZXJhZ2UoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHgudmFsdWU7IH0pO1xyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3NlbGVjdG9yXSBBIHRyYW5zZm9ybSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGVsZW1lbnQuXHJcbiAgICAgKiBAcGFyYW0ge0FueX0gW3RoaXNBcmddIE9iamVjdCB0byB1c2UgYXMgdGhpcyB3aGVuIGV4ZWN1dGluZyBjYWxsYmFjay4gICAgICAgIFxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgY29udGFpbmluZyBhIHNpbmdsZSBlbGVtZW50IHdpdGggdGhlIGF2ZXJhZ2Ugb2YgdGhlIHNlcXVlbmNlIG9mIHZhbHVlcy5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmF2ZXJhZ2UgPSBmdW5jdGlvbiAoa2V5U2VsZWN0b3IsIHRoaXNBcmcpIHtcclxuICAgICAgICByZXR1cm4ga2V5U2VsZWN0b3IgP1xyXG4gICAgICAgICAgICB0aGlzLnNlbGVjdChrZXlTZWxlY3RvciwgdGhpc0FyZykuYXZlcmFnZSgpIDpcclxuICAgICAgICAgICAgdGhpcy5zY2FuKHtcclxuICAgICAgICAgICAgICAgIHN1bTogMCxcclxuICAgICAgICAgICAgICAgIGNvdW50OiAwXHJcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChwcmV2LCBjdXIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3VtOiBwcmV2LnN1bSArIGN1cixcclxuICAgICAgICAgICAgICAgICAgICBjb3VudDogcHJldi5jb3VudCArIDFcclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0pLmZpbmFsVmFsdWUoKS5zZWxlY3QoZnVuY3Rpb24gKHMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChzLmNvdW50ID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdUaGUgaW5wdXQgc2VxdWVuY2Ugd2FzIGVtcHR5Jyk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gcy5zdW0gLyBzLmNvdW50O1xyXG4gICAgICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gIGZ1bmN0aW9uIHNlcXVlbmNlRXF1YWxBcnJheShmaXJzdCwgc2Vjb25kLCBjb21wYXJlcikge1xyXG4gICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgdmFyIGNvdW50ID0gMCwgbGVuID0gc2Vjb25kLmxlbmd0aDtcclxuICAgICAgICByZXR1cm4gZmlyc3Quc3Vic2NyaWJlKGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgdmFyIGVxdWFsID0gZmFsc2U7XHJcbiAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICBpZiAoY291bnQgPCBsZW4pIHtcclxuICAgICAgICAgICAgICBlcXVhbCA9IGNvbXBhcmVyKHZhbHVlLCBzZWNvbmRbY291bnQrK10pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIGlmICghZXF1YWwpIHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KGZhbHNlKTtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQoY291bnQgPT09IGxlbik7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqICBEZXRlcm1pbmVzIHdoZXRoZXIgdHdvIHNlcXVlbmNlcyBhcmUgZXF1YWwgYnkgY29tcGFyaW5nIHRoZSBlbGVtZW50cyBwYWlyd2lzZSB1c2luZyBhIHNwZWNpZmllZCBlcXVhbGl0eSBjb21wYXJlci5cclxuICAgKiBcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqIHZhciByZXMgPSByZXMgPSBzb3VyY2Uuc2VxdWVuY2VFcXVhbChbMSwyLDNdKTtcclxuICAgKiB2YXIgcmVzID0gcmVzID0gc291cmNlLnNlcXVlbmNlRXF1YWwoW3sgdmFsdWU6IDQyIH1dLCBmdW5jdGlvbiAoeCwgeSkgeyByZXR1cm4geC52YWx1ZSA9PT0geS52YWx1ZTsgfSk7XHJcbiAgICogMyAtIHJlcyA9IHNvdXJjZS5zZXF1ZW5jZUVxdWFsKFJ4Lk9ic2VydmFibGUucmV0dXJuVmFsdWUoNDIpKTtcclxuICAgKiA0IC0gcmVzID0gc291cmNlLnNlcXVlbmNlRXF1YWwoUnguT2JzZXJ2YWJsZS5yZXR1cm5WYWx1ZSh7IHZhbHVlOiA0MiB9KSwgZnVuY3Rpb24gKHgsIHkpIHsgcmV0dXJuIHgudmFsdWUgPT09IHkudmFsdWU7IH0pO1xyXG4gICAqIEBwYXJhbSB7T2JzZXJ2YWJsZX0gc2Vjb25kIFNlY29uZCBvYnNlcnZhYmxlIHNlcXVlbmNlIG9yIGFycmF5IHRvIGNvbXBhcmUuXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW2NvbXBhcmVyXSBDb21wYXJlciB1c2VkIHRvIGNvbXBhcmUgZWxlbWVudHMgb2YgYm90aCBzZXF1ZW5jZXMuXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBjb250YWlucyBhIHNpbmdsZSBlbGVtZW50IHdoaWNoIGluZGljYXRlcyB3aGV0aGVyIGJvdGggc2VxdWVuY2VzIGFyZSBvZiBlcXVhbCBsZW5ndGggYW5kIHRoZWlyIGNvcnJlc3BvbmRpbmcgZWxlbWVudHMgYXJlIGVxdWFsIGFjY29yZGluZyB0byB0aGUgc3BlY2lmaWVkIGVxdWFsaXR5IGNvbXBhcmVyLlxyXG4gICAqL1xyXG4gIG9ic2VydmFibGVQcm90by5zZXF1ZW5jZUVxdWFsID0gZnVuY3Rpb24gKHNlY29uZCwgY29tcGFyZXIpIHtcclxuICAgIHZhciBmaXJzdCA9IHRoaXM7XHJcbiAgICBjb21wYXJlciB8fCAoY29tcGFyZXIgPSBkZWZhdWx0Q29tcGFyZXIpO1xyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkoc2Vjb25kKSkge1xyXG4gICAgICByZXR1cm4gc2VxdWVuY2VFcXVhbEFycmF5KGZpcnN0LCBzZWNvbmQsIGNvbXBhcmVyKTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgdmFyIGRvbmVsID0gZmFsc2UsIGRvbmVyID0gZmFsc2UsIHFsID0gW10sIHFyID0gW107XHJcbiAgICAgIHZhciBzdWJzY3JpcHRpb24xID0gZmlyc3Quc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgdmFyIGVxdWFsLCB2O1xyXG4gICAgICAgIGlmIChxci5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIHYgPSBxci5zaGlmdCgpO1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgIGVxdWFsID0gY29tcGFyZXIodiwgeCk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoIWVxdWFsKSB7XHJcbiAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KGZhbHNlKTtcclxuICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChkb25lcikge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KGZhbHNlKTtcclxuICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHFsLnB1c2goeCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZG9uZWwgPSB0cnVlO1xyXG4gICAgICAgIGlmIChxbC5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgIGlmIChxci5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChmYWxzZSk7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKGRvbmVyKSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh0cnVlKTtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgaXNQcm9taXNlKHNlY29uZCkgJiYgKHNlY29uZCA9IG9ic2VydmFibGVGcm9tUHJvbWlzZShzZWNvbmQpKTtcclxuICAgICAgdmFyIHN1YnNjcmlwdGlvbjIgPSBzZWNvbmQuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgdmFyIGVxdWFsLCB2O1xyXG4gICAgICAgIGlmIChxbC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICB2ID0gcWwuc2hpZnQoKTtcclxuICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGVxdWFsID0gY29tcGFyZXIodiwgeCk7XHJcbiAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleGNlcHRpb24pO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBpZiAoIWVxdWFsKSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChmYWxzZSk7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSBlbHNlIGlmIChkb25lbCkge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KGZhbHNlKTtcclxuICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIHFyLnB1c2goeCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgZG9uZXIgPSB0cnVlO1xyXG4gICAgICAgIGlmIChxci5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgIGlmIChxbC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChmYWxzZSk7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICB9IGVsc2UgaWYgKGRvbmVsKSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh0cnVlKTtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc3Vic2NyaXB0aW9uMSwgc3Vic2NyaXB0aW9uMik7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAgIGZ1bmN0aW9uIGVsZW1lbnRBdE9yRGVmYXVsdChzb3VyY2UsIGluZGV4LCBoYXNEZWZhdWx0LCBkZWZhdWx0VmFsdWUpIHtcclxuICAgICAgICBpZiAoaW5kZXggPCAwKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihhcmd1bWVudE91dE9mUmFuZ2UpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBpID0gaW5kZXg7XHJcbiAgICAgICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaSA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh4KTtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaS0tO1xyXG4gICAgICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWhhc0RlZmF1bHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKG5ldyBFcnJvcihhcmd1bWVudE91dE9mUmFuZ2UpKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KGRlZmF1bHRWYWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBlbGVtZW50IGF0IGEgc3BlY2lmaWVkIGluZGV4IGluIGEgc2VxdWVuY2UuXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5lbGVtZW50QXQoNSk7XHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXggVGhlIHplcm8tYmFzZWQgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0cmlldmUuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHByb2R1Y2VzIHRoZSBlbGVtZW50IGF0IHRoZSBzcGVjaWZpZWQgcG9zaXRpb24gaW4gdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmVsZW1lbnRBdCA9ICBmdW5jdGlvbiAoaW5kZXgpIHtcclxuICAgICAgICByZXR1cm4gZWxlbWVudEF0T3JEZWZhdWx0KHRoaXMsIGluZGV4LCBmYWxzZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgZWxlbWVudCBhdCBhIHNwZWNpZmllZCBpbmRleCBpbiBhIHNlcXVlbmNlIG9yIGEgZGVmYXVsdCB2YWx1ZSBpZiB0aGUgaW5kZXggaXMgb3V0IG9mIHJhbmdlLlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIHZhciByZXMgPSBzb3VyY2UuZWxlbWVudEF0T3JEZWZhdWx0KDUpO1xyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5lbGVtZW50QXRPckRlZmF1bHQoNSwgMCk7XHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gaW5kZXggVGhlIHplcm8tYmFzZWQgaW5kZXggb2YgdGhlIGVsZW1lbnQgdG8gcmV0cmlldmUuXHJcbiAgICAgKiBAcGFyYW0gW2RlZmF1bHRWYWx1ZV0gVGhlIGRlZmF1bHQgdmFsdWUgaWYgdGhlIGluZGV4IGlzIG91dHNpZGUgdGhlIGJvdW5kcyBvZiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBwcm9kdWNlcyB0aGUgZWxlbWVudCBhdCB0aGUgc3BlY2lmaWVkIHBvc2l0aW9uIGluIHRoZSBzb3VyY2Ugc2VxdWVuY2UsIG9yIGEgZGVmYXVsdCB2YWx1ZSBpZiB0aGUgaW5kZXggaXMgb3V0c2lkZSB0aGUgYm91bmRzIG9mIHRoZSBzb3VyY2Ugc2VxdWVuY2UuXHJcbiAgICAgKi8gICAgXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uZWxlbWVudEF0T3JEZWZhdWx0ID0gZnVuY3Rpb24gKGluZGV4LCBkZWZhdWx0VmFsdWUpIHtcclxuICAgICAgICByZXR1cm4gZWxlbWVudEF0T3JEZWZhdWx0KHRoaXMsIGluZGV4LCB0cnVlLCBkZWZhdWx0VmFsdWUpO1xyXG4gICAgfTtcclxuXHJcbiAgICBmdW5jdGlvbiBzaW5nbGVPckRlZmF1bHRBc3luYyhzb3VyY2UsIGhhc0RlZmF1bHQsIGRlZmF1bHRWYWx1ZSkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIHZhbHVlID0gZGVmYXVsdFZhbHVlLCBzZWVuVmFsdWUgPSBmYWxzZTtcclxuICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgIGlmIChzZWVuVmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKG5ldyBFcnJvcignU2VxdWVuY2UgY29udGFpbnMgbW9yZSB0aGFuIG9uZSBlbGVtZW50JykpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IHg7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VlblZhbHVlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzZWVuVmFsdWUgJiYgIWhhc0RlZmF1bHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKG5ldyBFcnJvcihzZXF1ZW5jZUNvbnRhaW5zTm9FbGVtZW50cykpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgb25seSBlbGVtZW50IG9mIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBzYXRpc2ZpZXMgdGhlIGNvbmRpdGlvbiBpbiB0aGUgb3B0aW9uYWwgcHJlZGljYXRlLCBhbmQgcmVwb3J0cyBhbiBleGNlcHRpb24gaWYgdGhlcmUgaXMgbm90IGV4YWN0bHkgb25lIGVsZW1lbnQgaW4gdGhlIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogdmFyIHJlcyA9IHJlcyA9IHNvdXJjZS5zaW5nbGUoKTtcclxuICAgICAqIHZhciByZXMgPSByZXMgPSBzb3VyY2Uuc2luZ2xlKGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ID09PSA0MjsgfSk7XHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlXSBBIHByZWRpY2F0ZSBmdW5jdGlvbiB0byBldmFsdWF0ZSBmb3IgZWxlbWVudHMgaW4gdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqIEBwYXJhbSB7QW55fSBbdGhpc0FyZ10gT2JqZWN0IHRvIHVzZSBhcyBgdGhpc2Agd2hlbiBleGVjdXRpbmcgdGhlIHByZWRpY2F0ZS4gICAgICAgIFxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IFNlcXVlbmNlIGNvbnRhaW5pbmcgdGhlIHNpbmdsZSBlbGVtZW50IGluIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc2F0aXNmaWVzIHRoZSBjb25kaXRpb24gaW4gdGhlIHByZWRpY2F0ZS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnNpbmdsZSA9IGZ1bmN0aW9uIChwcmVkaWNhdGUsIHRoaXNBcmcpIHtcclxuICAgICAgICByZXR1cm4gcHJlZGljYXRlID9cclxuICAgICAgICAgICAgdGhpcy53aGVyZShwcmVkaWNhdGUsIHRoaXNBcmcpLnNpbmdsZSgpIDpcclxuICAgICAgICAgICAgc2luZ2xlT3JEZWZhdWx0QXN5bmModGhpcywgZmFsc2UpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIG9ubHkgZWxlbWVudCBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgbWF0Y2hlcyB0aGUgcHJlZGljYXRlLCBvciBhIGRlZmF1bHQgdmFsdWUgaWYgbm8gc3VjaCBlbGVtZW50IGV4aXN0czsgdGhpcyBtZXRob2QgcmVwb3J0cyBhbiBleGNlcHRpb24gaWYgdGhlcmUgaXMgbW9yZSB0aGFuIG9uZSBlbGVtZW50IGluIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIHZhciByZXMgPSByZXMgPSBzb3VyY2Uuc2luZ2xlT3JEZWZhdWx0KCk7XHJcbiAgICAgKiB2YXIgcmVzID0gcmVzID0gc291cmNlLnNpbmdsZU9yRGVmYXVsdChmdW5jdGlvbiAoeCkgeyByZXR1cm4geCA9PT0gNDI7IH0pO1xyXG4gICAgICogcmVzID0gc291cmNlLnNpbmdsZU9yRGVmYXVsdChmdW5jdGlvbiAoeCkgeyByZXR1cm4geCA9PT0gNDI7IH0sIDApO1xyXG4gICAgICogcmVzID0gc291cmNlLnNpbmdsZU9yRGVmYXVsdChudWxsLCAwKTtcclxuICAgICAqIEBtZW1iZXJPZiBPYnNlcnZhYmxlI1xyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIEEgcHJlZGljYXRlIGZ1bmN0aW9uIHRvIGV2YWx1YXRlIGZvciBlbGVtZW50cyBpbiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICogQHBhcmFtIFtkZWZhdWx0VmFsdWVdIFRoZSBkZWZhdWx0IHZhbHVlIGlmIHRoZSBpbmRleCBpcyBvdXRzaWRlIHRoZSBib3VuZHMgb2YgdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqIEBwYXJhbSB7QW55fSBbdGhpc0FyZ10gT2JqZWN0IHRvIHVzZSBhcyBgdGhpc2Agd2hlbiBleGVjdXRpbmcgdGhlIHByZWRpY2F0ZS4gICAgICAgIFxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IFNlcXVlbmNlIGNvbnRhaW5pbmcgdGhlIHNpbmdsZSBlbGVtZW50IGluIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc2F0aXNmaWVzIHRoZSBjb25kaXRpb24gaW4gdGhlIHByZWRpY2F0ZSwgb3IgYSBkZWZhdWx0IHZhbHVlIGlmIG5vIHN1Y2ggZWxlbWVudCBleGlzdHMuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5zaW5nbGVPckRlZmF1bHQgPSBmdW5jdGlvbiAocHJlZGljYXRlLCBkZWZhdWx0VmFsdWUsIHRoaXNBcmcpIHtcclxuICAgICAgICByZXR1cm4gcHJlZGljYXRlP1xyXG4gICAgICAgICAgICB0aGlzLndoZXJlKHByZWRpY2F0ZSwgdGhpc0FyZykuc2luZ2xlT3JEZWZhdWx0KG51bGwsIGRlZmF1bHRWYWx1ZSkgOlxyXG4gICAgICAgICAgICBzaW5nbGVPckRlZmF1bHRBc3luYyh0aGlzLCB0cnVlLCBkZWZhdWx0VmFsdWUpXHJcbiAgICB9O1xyXG4gICAgZnVuY3Rpb24gZmlyc3RPckRlZmF1bHRBc3luYyhzb3VyY2UsIGhhc0RlZmF1bHQsIGRlZmF1bHRWYWx1ZSkge1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh4KTtcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGlmICghaGFzRGVmYXVsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IobmV3IEVycm9yKHNlcXVlbmNlQ29udGFpbnNOb0VsZW1lbnRzKSk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChkZWZhdWx0VmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgZmlyc3QgZWxlbWVudCBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc2F0aXNmaWVzIHRoZSBjb25kaXRpb24gaW4gdGhlIHByZWRpY2F0ZSBpZiBwcmVzZW50IGVsc2UgdGhlIGZpcnN0IGl0ZW0gaW4gdGhlIHNlcXVlbmNlLlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIHZhciByZXMgPSByZXMgPSBzb3VyY2UuZmlyc3QoKTtcclxuICAgICAqIHZhciByZXMgPSByZXMgPSBzb3VyY2UuZmlyc3QoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHggPiAzOyB9KTtcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGVdIEEgcHJlZGljYXRlIGZ1bmN0aW9uIHRvIGV2YWx1YXRlIGZvciBlbGVtZW50cyBpbiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICogQHBhcmFtIHtBbnl9IFt0aGlzQXJnXSBPYmplY3QgdG8gdXNlIGFzIGB0aGlzYCB3aGVuIGV4ZWN1dGluZyB0aGUgcHJlZGljYXRlLiAgICAgXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gU2VxdWVuY2UgY29udGFpbmluZyB0aGUgZmlyc3QgZWxlbWVudCBpbiB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHNhdGlzZmllcyB0aGUgY29uZGl0aW9uIGluIHRoZSBwcmVkaWNhdGUgaWYgcHJvdmlkZWQsIGVsc2UgdGhlIGZpcnN0IGl0ZW0gaW4gdGhlIHNlcXVlbmNlLlxyXG4gICAgICovICAgIFxyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmZpcnN0ID0gZnVuY3Rpb24gKHByZWRpY2F0ZSwgdGhpc0FyZykge1xyXG4gICAgICAgIHJldHVybiBwcmVkaWNhdGUgP1xyXG4gICAgICAgICAgICB0aGlzLndoZXJlKHByZWRpY2F0ZSwgdGhpc0FyZykuZmlyc3QoKSA6XHJcbiAgICAgICAgICAgIGZpcnN0T3JEZWZhdWx0QXN5bmModGhpcywgZmFsc2UpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgdGhlIGZpcnN0IGVsZW1lbnQgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHNhdGlzZmllcyB0aGUgY29uZGl0aW9uIGluIHRoZSBwcmVkaWNhdGUsIG9yIGEgZGVmYXVsdCB2YWx1ZSBpZiBubyBzdWNoIGVsZW1lbnQgZXhpc3RzLlxyXG4gICAgICogQGV4YW1wbGUgICAgIFxyXG4gICAgICogdmFyIHJlcyA9IHJlcyA9IHNvdXJjZS5maXJzdE9yRGVmYXVsdCgpO1xyXG4gICAgICogdmFyIHJlcyA9IHJlcyA9IHNvdXJjZS5maXJzdE9yRGVmYXVsdChmdW5jdGlvbiAoeCkgeyByZXR1cm4geCA+IDM7IH0pO1xyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5maXJzdE9yRGVmYXVsdChmdW5jdGlvbiAoeCkgeyByZXR1cm4geCA+IDM7IH0sIDApO1xyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5maXJzdE9yRGVmYXVsdChudWxsLCAwKTtcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGVdIEEgcHJlZGljYXRlIGZ1bmN0aW9uIHRvIGV2YWx1YXRlIGZvciBlbGVtZW50cyBpbiB0aGUgc291cmNlIHNlcXVlbmNlLiBcclxuICAgICAqIEBwYXJhbSB7QW55fSBbZGVmYXVsdFZhbHVlXSBUaGUgZGVmYXVsdCB2YWx1ZSBpZiBubyBzdWNoIGVsZW1lbnQgZXhpc3RzLiAgSWYgbm90IHNwZWNpZmllZCwgZGVmYXVsdHMgdG8gbnVsbC5cclxuICAgICAqIEBwYXJhbSB7QW55fSBbdGhpc0FyZ10gT2JqZWN0IHRvIHVzZSBhcyBgdGhpc2Agd2hlbiBleGVjdXRpbmcgdGhlIHByZWRpY2F0ZS5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBTZXF1ZW5jZSBjb250YWluaW5nIHRoZSBmaXJzdCBlbGVtZW50IGluIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc2F0aXNmaWVzIHRoZSBjb25kaXRpb24gaW4gdGhlIHByZWRpY2F0ZSwgb3IgYSBkZWZhdWx0IHZhbHVlIGlmIG5vIHN1Y2ggZWxlbWVudCBleGlzdHMuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5maXJzdE9yRGVmYXVsdCA9IGZ1bmN0aW9uIChwcmVkaWNhdGUsIGRlZmF1bHRWYWx1ZSwgdGhpc0FyZykge1xyXG4gICAgICAgIHJldHVybiBwcmVkaWNhdGUgP1xyXG4gICAgICAgICAgICB0aGlzLndoZXJlKHByZWRpY2F0ZSkuZmlyc3RPckRlZmF1bHQobnVsbCwgZGVmYXVsdFZhbHVlKSA6XHJcbiAgICAgICAgICAgIGZpcnN0T3JEZWZhdWx0QXN5bmModGhpcywgdHJ1ZSwgZGVmYXVsdFZhbHVlKTtcclxuICAgIH07XHJcblxyXG4gICAgZnVuY3Rpb24gbGFzdE9yRGVmYXVsdEFzeW5jKHNvdXJjZSwgaGFzRGVmYXVsdCwgZGVmYXVsdFZhbHVlKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgdmFsdWUgPSBkZWZhdWx0VmFsdWUsIHNlZW5WYWx1ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgdmFsdWUgPSB4O1xyXG4gICAgICAgICAgICAgICAgc2VlblZhbHVlID0gdHJ1ZTtcclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCFzZWVuVmFsdWUgJiYgIWhhc0RlZmF1bHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKG5ldyBFcnJvcihzZXF1ZW5jZUNvbnRhaW5zTm9FbGVtZW50cykpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyB0aGUgbGFzdCBlbGVtZW50IG9mIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBzYXRpc2ZpZXMgdGhlIGNvbmRpdGlvbiBpbiB0aGUgcHJlZGljYXRlIGlmIHNwZWNpZmllZCwgZWxzZSB0aGUgbGFzdCBlbGVtZW50LlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIHZhciByZXMgPSBzb3VyY2UubGFzdCgpO1xyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5sYXN0KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ID4gMzsgfSk7XHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbcHJlZGljYXRlXSBBIHByZWRpY2F0ZSBmdW5jdGlvbiB0byBldmFsdWF0ZSBmb3IgZWxlbWVudHMgaW4gdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqIEBwYXJhbSB7QW55fSBbdGhpc0FyZ10gT2JqZWN0IHRvIHVzZSBhcyBgdGhpc2Agd2hlbiBleGVjdXRpbmcgdGhlIHByZWRpY2F0ZS4gICAgIFxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IFNlcXVlbmNlIGNvbnRhaW5pbmcgdGhlIGxhc3QgZWxlbWVudCBpbiB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHNhdGlzZmllcyB0aGUgY29uZGl0aW9uIGluIHRoZSBwcmVkaWNhdGUuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5sYXN0ID0gZnVuY3Rpb24gKHByZWRpY2F0ZSwgdGhpc0FyZykge1xyXG4gICAgICAgIHJldHVybiBwcmVkaWNhdGUgP1xyXG4gICAgICAgICAgICB0aGlzLndoZXJlKHByZWRpY2F0ZSwgdGhpc0FyZykubGFzdCgpIDpcclxuICAgICAgICAgICAgbGFzdE9yRGVmYXVsdEFzeW5jKHRoaXMsIGZhbHNlKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSBsYXN0IGVsZW1lbnQgb2YgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHNhdGlzZmllcyB0aGUgY29uZGl0aW9uIGluIHRoZSBwcmVkaWNhdGUsIG9yIGEgZGVmYXVsdCB2YWx1ZSBpZiBubyBzdWNoIGVsZW1lbnQgZXhpc3RzLlxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIHZhciByZXMgPSBzb3VyY2UubGFzdE9yRGVmYXVsdCgpO1xyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5sYXN0T3JEZWZhdWx0KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4ID4gMzsgfSk7XHJcbiAgICAgKiB2YXIgcmVzID0gc291cmNlLmxhc3RPckRlZmF1bHQoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHggPiAzOyB9LCAwKTtcclxuICAgICAqIHZhciByZXMgPSBzb3VyY2UubGFzdE9yRGVmYXVsdChudWxsLCAwKTtcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtwcmVkaWNhdGVdIEEgcHJlZGljYXRlIGZ1bmN0aW9uIHRvIGV2YWx1YXRlIGZvciBlbGVtZW50cyBpbiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICogQHBhcmFtIFtkZWZhdWx0VmFsdWVdIFRoZSBkZWZhdWx0IHZhbHVlIGlmIG5vIHN1Y2ggZWxlbWVudCBleGlzdHMuICBJZiBub3Qgc3BlY2lmaWVkLCBkZWZhdWx0cyB0byBudWxsLlxyXG4gICAgICogQHBhcmFtIHtBbnl9IFt0aGlzQXJnXSBPYmplY3QgdG8gdXNlIGFzIGB0aGlzYCB3aGVuIGV4ZWN1dGluZyB0aGUgcHJlZGljYXRlLiAgICAgXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gU2VxdWVuY2UgY29udGFpbmluZyB0aGUgbGFzdCBlbGVtZW50IGluIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc2F0aXNmaWVzIHRoZSBjb25kaXRpb24gaW4gdGhlIHByZWRpY2F0ZSwgb3IgYSBkZWZhdWx0IHZhbHVlIGlmIG5vIHN1Y2ggZWxlbWVudCBleGlzdHMuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5sYXN0T3JEZWZhdWx0ID0gZnVuY3Rpb24gKHByZWRpY2F0ZSwgZGVmYXVsdFZhbHVlLCB0aGlzQXJnKSB7XHJcbiAgICAgICAgcmV0dXJuIHByZWRpY2F0ZSA/IFxyXG4gICAgICAgICAgICB0aGlzLndoZXJlKHByZWRpY2F0ZSwgdGhpc0FyZykubGFzdE9yRGVmYXVsdChudWxsLCBkZWZhdWx0VmFsdWUpIDpcclxuICAgICAgICAgICAgbGFzdE9yRGVmYXVsdEFzeW5jKHRoaXMsIHRydWUsIGRlZmF1bHRWYWx1ZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIGZ1bmN0aW9uIGZpbmRWYWx1ZSAoc291cmNlLCBwcmVkaWNhdGUsIHRoaXNBcmcsIHlpZWxkSW5kZXgpIHtcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBpID0gMDtcclxuICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzaG91bGRSdW47XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNob3VsZFJ1biA9IHByZWRpY2F0ZS5jYWxsKHRoaXNBcmcsIHgsIGksIHNvdXJjZSk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChzaG91bGRSdW4pIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQoeWllbGRJbmRleCA/IGkgOiB4KTtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpKys7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh5aWVsZEluZGV4ID8gLTEgOiB1bmRlZmluZWQpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7ICAgICAgICBcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFNlYXJjaGVzIGZvciBhbiBlbGVtZW50IHRoYXQgbWF0Y2hlcyB0aGUgY29uZGl0aW9ucyBkZWZpbmVkIGJ5IHRoZSBzcGVjaWZpZWQgcHJlZGljYXRlLCBhbmQgcmV0dXJucyB0aGUgZmlyc3Qgb2NjdXJyZW5jZSB3aXRoaW4gdGhlIGVudGlyZSBPYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZGljYXRlIFRoZSBwcmVkaWNhdGUgdGhhdCBkZWZpbmVzIHRoZSBjb25kaXRpb25zIG9mIHRoZSBlbGVtZW50IHRvIHNlYXJjaCBmb3IuXHJcbiAgICAgKiBAcGFyYW0ge0FueX0gW3RoaXNBcmddIE9iamVjdCB0byB1c2UgYXMgYHRoaXNgIHdoZW4gZXhlY3V0aW5nIHRoZSBwcmVkaWNhdGUuICAgICAgICAgIFxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIE9ic2VydmFibGUgc2VxdWVuY2Ugd2l0aCB0aGUgZmlyc3QgZWxlbWVudCB0aGF0IG1hdGNoZXMgdGhlIGNvbmRpdGlvbnMgZGVmaW5lZCBieSB0aGUgc3BlY2lmaWVkIHByZWRpY2F0ZSwgaWYgZm91bmQ7IG90aGVyd2lzZSwgdW5kZWZpbmVkLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uZmluZCA9IGZ1bmN0aW9uIChwcmVkaWNhdGUsIHRoaXNBcmcpIHtcclxuICAgICAgICByZXR1cm4gZmluZFZhbHVlKHRoaXMsIHByZWRpY2F0ZSwgdGhpc0FyZywgZmFsc2UpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFNlYXJjaGVzIGZvciBhbiBlbGVtZW50IHRoYXQgbWF0Y2hlcyB0aGUgY29uZGl0aW9ucyBkZWZpbmVkIGJ5IHRoZSBzcGVjaWZpZWQgcHJlZGljYXRlLCBhbmQgcmV0dXJucyBcclxuICAgICAqIGFuIE9ic2VydmFibGUgc2VxdWVuY2Ugd2l0aCB0aGUgemVyby1iYXNlZCBpbmRleCBvZiB0aGUgZmlyc3Qgb2NjdXJyZW5jZSB3aXRoaW4gdGhlIGVudGlyZSBPYnNlcnZhYmxlIHNlcXVlbmNlLiBcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBUaGUgcHJlZGljYXRlIHRoYXQgZGVmaW5lcyB0aGUgY29uZGl0aW9ucyBvZiB0aGUgZWxlbWVudCB0byBzZWFyY2ggZm9yLlxyXG4gICAgICogQHBhcmFtIHtBbnl9IFt0aGlzQXJnXSBPYmplY3QgdG8gdXNlIGFzIGB0aGlzYCB3aGVuIGV4ZWN1dGluZyB0aGUgcHJlZGljYXRlLiAgICAgICAgICBcclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBPYnNlcnZhYmxlIHNlcXVlbmNlIHdpdGggdGhlIHplcm8tYmFzZWQgaW5kZXggb2YgdGhlIGZpcnN0IG9jY3VycmVuY2Ugb2YgYW4gZWxlbWVudCB0aGF0IG1hdGNoZXMgdGhlIGNvbmRpdGlvbnMgZGVmaW5lZCBieSBtYXRjaCwgaWYgZm91bmQ7IG90aGVyd2lzZSwg4oCTMS5cclxuICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uZmluZEluZGV4ID0gZnVuY3Rpb24gKHByZWRpY2F0ZSwgdGhpc0FyZykge1xyXG4gICAgICAgIHJldHVybiBmaW5kVmFsdWUodGhpcywgcHJlZGljYXRlLCB0aGlzQXJnLCB0cnVlKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBJbnZva2VzIHRoZSBzcGVjaWZpZWQgZnVuY3Rpb24gYXN5bmNocm9ub3VzbHkgb24gdGhlIHNwZWNpZmllZCBzY2hlZHVsZXIsIHN1cmZhY2luZyB0aGUgcmVzdWx0IHRocm91Z2ggYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIHZhciByZXMgPSBSeC5PYnNlcnZhYmxlLnN0YXJ0KGZ1bmN0aW9uICgpIHsgY29uc29sZS5sb2coJ2hlbGxvJyk7IH0pO1xyXG4gICAgICogdmFyIHJlcyA9IFJ4Lk9ic2VydmFibGUuc3RhcnQoZnVuY3Rpb24gKCkgeyBjb25zb2xlLmxvZygnaGVsbG8nKTsgfSwgUnguU2NoZWR1bGVyLnRpbWVvdXQpO1xyXG4gICAgICogdmFyIHJlcyA9IFJ4Lk9ic2VydmFibGUuc3RhcnQoZnVuY3Rpb24gKCkgeyB0aGlzLmxvZygnaGVsbG8nKTsgfSwgUnguU2NoZWR1bGVyLnRpbWVvdXQsIGNvbnNvbGUpO1xyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIEZ1bmN0aW9uIHRvIHJ1biBhc3luY2hyb25vdXNseS5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSAgU2NoZWR1bGVyIHRvIHJ1biB0aGUgZnVuY3Rpb24gb24uIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIFNjaGVkdWxlci50aW1lb3V0LlxyXG4gICAgICogQHBhcmFtIFtjb250ZXh0XSAgVGhlIGNvbnRleHQgZm9yIHRoZSBmdW5jIHBhcmFtZXRlciB0byBiZSBleGVjdXRlZC4gIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIHVuZGVmaW5lZC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGV4cG9zaW5nIHRoZSBmdW5jdGlvbidzIHJlc3VsdCB2YWx1ZSwgb3IgYW4gZXhjZXB0aW9uLlxyXG4gICAgICogXHJcbiAgICAgKiBSZW1hcmtzXHJcbiAgICAgKiAqIFRoZSBmdW5jdGlvbiBpcyBjYWxsZWQgaW1tZWRpYXRlbHksIG5vdCBkdXJpbmcgdGhlIHN1YnNjcmlwdGlvbiBvZiB0aGUgcmVzdWx0aW5nIHNlcXVlbmNlLlxyXG4gICAgICogKiBNdWx0aXBsZSBzdWJzY3JpcHRpb25zIHRvIHRoZSByZXN1bHRpbmcgc2VxdWVuY2UgY2FuIG9ic2VydmUgdGhlIGZ1bmN0aW9uJ3MgcmVzdWx0LiAgXHJcbiAgICAgKi9cclxuICAgIE9ic2VydmFibGUuc3RhcnQgPSBmdW5jdGlvbiAoZnVuYywgc2NoZWR1bGVyLCBjb250ZXh0KSB7XHJcbiAgICAgICAgcmV0dXJuIG9ic2VydmFibGVUb0FzeW5jKGZ1bmMsIHNjaGVkdWxlciwgY29udGV4dCkoKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0cyB0aGUgZnVuY3Rpb24gaW50byBhbiBhc3luY2hyb25vdXMgZnVuY3Rpb24uIEVhY2ggaW52b2NhdGlvbiBvZiB0aGUgcmVzdWx0aW5nIGFzeW5jaHJvbm91cyBmdW5jdGlvbiBjYXVzZXMgYW4gaW52b2NhdGlvbiBvZiB0aGUgb3JpZ2luYWwgc3luY2hyb25vdXMgZnVuY3Rpb24gb24gdGhlIHNwZWNpZmllZCBzY2hlZHVsZXIuXHJcbiAgICAgKiBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiB2YXIgcmVzID0gUnguT2JzZXJ2YWJsZS50b0FzeW5jKGZ1bmN0aW9uICh4LCB5KSB7IHJldHVybiB4ICsgeTsgfSkoNCwgMyk7XHJcbiAgICAgKiB2YXIgcmVzID0gUnguT2JzZXJ2YWJsZS50b0FzeW5jKGZ1bmN0aW9uICh4LCB5KSB7IHJldHVybiB4ICsgeTsgfSwgUnguU2NoZWR1bGVyLnRpbWVvdXQpKDQsIDMpO1xyXG4gICAgICogdmFyIHJlcyA9IFJ4Lk9ic2VydmFibGUudG9Bc3luYyhmdW5jdGlvbiAoeCkgeyB0aGlzLmxvZyh4KTsgfSwgUnguU2NoZWR1bGVyLnRpbWVvdXQsIGNvbnNvbGUpKCdoZWxsbycpO1xyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jdGlvbiBGdW5jdGlvbiB0byBjb252ZXJ0IHRvIGFuIGFzeW5jaHJvbm91cyBmdW5jdGlvbi5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSBTY2hlZHVsZXIgdG8gcnVuIHRoZSBmdW5jdGlvbiBvbi4gSWYgbm90IHNwZWNpZmllZCwgZGVmYXVsdHMgdG8gU2NoZWR1bGVyLnRpbWVvdXQuXHJcbiAgICAgKiBAcGFyYW0ge01peGVkfSBbY29udGV4dF0gVGhlIGNvbnRleHQgZm9yIHRoZSBmdW5jIHBhcmFtZXRlciB0byBiZSBleGVjdXRlZC4gIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIHVuZGVmaW5lZC5cclxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gQXN5bmNocm9ub3VzIGZ1bmN0aW9uLlxyXG4gICAgICovXHJcbiAgICB2YXIgb2JzZXJ2YWJsZVRvQXN5bmMgPSBPYnNlcnZhYmxlLnRvQXN5bmMgPSBmdW5jdGlvbiAoZnVuYywgc2NoZWR1bGVyLCBjb250ZXh0KSB7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSB0aW1lb3V0U2NoZWR1bGVyKTtcclxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgYXJncyA9IGFyZ3VtZW50cywgXHJcbiAgICAgICAgICAgICAgICBzdWJqZWN0ID0gbmV3IEFzeW5jU3ViamVjdCgpO1xyXG5cclxuICAgICAgICAgICAgc2NoZWR1bGVyLnNjaGVkdWxlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHZhciByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IGZ1bmMuYXBwbHkoY29udGV4dCwgYXJncyk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3ViamVjdC5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHN1YmplY3Qub25OZXh0KHJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICBzdWJqZWN0Lm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gc3ViamVjdC5hc09ic2VydmFibGUoKTtcclxuICAgICAgICB9O1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENvbnZlcnRzIGEgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZS4gXHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmN0aW9uIEZ1bmN0aW9uIHdpdGggYSBjYWxsYmFjayBhcyB0aGUgbGFzdCBwYXJhbWV0ZXIgdG8gY29udmVydCB0byBhbiBPYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtzY2hlZHVsZXJdIFNjaGVkdWxlciB0byBydW4gdGhlIGZ1bmN0aW9uIG9uLiBJZiBub3Qgc3BlY2lmaWVkLCBkZWZhdWx0cyB0byBTY2hlZHVsZXIudGltZW91dC5cclxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IFtjb250ZXh0XSBUaGUgY29udGV4dCBmb3IgdGhlIGZ1bmMgcGFyYW1ldGVyIHRvIGJlIGV4ZWN1dGVkLiAgSWYgbm90IHNwZWNpZmllZCwgZGVmYXVsdHMgdG8gdW5kZWZpbmVkLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3NlbGVjdG9yXSBBIHNlbGVjdG9yIHdoaWNoIHRha2VzIHRoZSBhcmd1bWVudHMgZnJvbSB0aGUgY2FsbGJhY2sgdG8gcHJvZHVjZSBhIHNpbmdsZSBpdGVtIHRvIHlpZWxkIG9uIG5leHQuXHJcbiAgICAgKiBAcmV0dXJucyB7RnVuY3Rpb259IEEgZnVuY3Rpb24sIHdoZW4gZXhlY3V0ZWQgd2l0aCB0aGUgcmVxdWlyZWQgcGFyYW1ldGVycyBtaW51cyB0aGUgY2FsbGJhY2ssIHByb2R1Y2VzIGFuIE9ic2VydmFibGUgc2VxdWVuY2Ugd2l0aCBhIHNpbmdsZSB2YWx1ZSBvZiB0aGUgYXJndW1lbnRzIHRvIHRoZSBjYWxsYmFjayBhcyBhbiBhcnJheS5cclxuICAgICAqL1xyXG4gICAgT2JzZXJ2YWJsZS5mcm9tQ2FsbGJhY2sgPSBmdW5jdGlvbiAoZnVuYywgc2NoZWR1bGVyLCBjb250ZXh0LCBzZWxlY3Rvcikge1xyXG4gICAgICAgIHNjaGVkdWxlciB8fCAoc2NoZWR1bGVyID0gaW1tZWRpYXRlU2NoZWR1bGVyKTtcclxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzY2hlZHVsZXIuc2NoZWR1bGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGhhbmRsZXIoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0cyA9IGU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IHNlbGVjdG9yKGFyZ3VtZW50cyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGVycik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IHJlc3VsdHNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChyZXN1bHRzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGFyZ3MucHVzaChoYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgICAgICBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29udmVydHMgYSBOb2RlLmpzIGNhbGxiYWNrIHN0eWxlIGZ1bmN0aW9uIHRvIGFuIG9ic2VydmFibGUgc2VxdWVuY2UuICBUaGlzIG11c3QgYmUgaW4gZnVuY3Rpb24gKGVyciwgLi4uKSBmb3JtYXQuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYWxsXHJcbiAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gW3NjaGVkdWxlcl0gU2NoZWR1bGVyIHRvIHJ1biB0aGUgZnVuY3Rpb24gb24uIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIFNjaGVkdWxlci50aW1lb3V0LlxyXG4gICAgICogQHBhcmFtIHtNaXhlZH0gW2NvbnRleHRdIFRoZSBjb250ZXh0IGZvciB0aGUgZnVuYyBwYXJhbWV0ZXIgdG8gYmUgZXhlY3V0ZWQuICBJZiBub3Qgc3BlY2lmaWVkLCBkZWZhdWx0cyB0byB1bmRlZmluZWQuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbc2VsZWN0b3JdIEEgc2VsZWN0b3Igd2hpY2ggdGFrZXMgdGhlIGFyZ3VtZW50cyBmcm9tIHRoZSBjYWxsYmFjayBtaW51cyB0aGUgZXJyb3IgdG8gcHJvZHVjZSBhIHNpbmdsZSBpdGVtIHRvIHlpZWxkIG9uIG5leHQuICAgICBcclxuICAgICAqIEByZXR1cm5zIHtGdW5jdGlvbn0gQW4gYXN5bmMgZnVuY3Rpb24gd2hpY2ggd2hlbiBhcHBsaWVkLCByZXR1cm5zIGFuIG9ic2VydmFibGUgc2VxdWVuY2Ugd2l0aCB0aGUgY2FsbGJhY2sgYXJndW1lbnRzIGFzIGFuIGFycmF5LlxyXG4gICAgICovXHJcbiAgICBPYnNlcnZhYmxlLmZyb21Ob2RlQ2FsbGJhY2sgPSBmdW5jdGlvbiAoZnVuYywgc2NoZWR1bGVyLCBjb250ZXh0LCBzZWxlY3Rvcikge1xyXG4gICAgICAgIHNjaGVkdWxlciB8fCAoc2NoZWR1bGVyID0gaW1tZWRpYXRlU2NoZWR1bGVyKTtcclxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzY2hlZHVsZXIuc2NoZWR1bGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIGhhbmRsZXIoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlcnIpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXJyKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgdmFyIHJlc3VsdHMgPSBzbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IHNlbGVjdG9yKHJlc3VsdHMpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHJlc3VsdHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0cyA9IHJlc3VsdHNbMF07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChyZXN1bHRzKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGFyZ3MucHVzaChoYW5kbGVyKTtcclxuICAgICAgICAgICAgICAgICAgICBmdW5jLmFwcGx5KGNvbnRleHQsIGFyZ3MpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH07XHJcbiAgICB9O1xyXG5cclxuICBmdW5jdGlvbiBjcmVhdGVMaXN0ZW5lciAoZWxlbWVudCwgbmFtZSwgaGFuZGxlcikge1xyXG4gICAgLy8gTm9kZS5qcyBzcGVjaWZpY1xyXG4gICAgaWYgKGVsZW1lbnQuYWRkTGlzdGVuZXIpIHtcclxuICAgICAgZWxlbWVudC5hZGRMaXN0ZW5lcihuYW1lLCBoYW5kbGVyKTtcclxuICAgICAgcmV0dXJuIGRpc3Bvc2FibGVDcmVhdGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlTGlzdGVuZXIobmFtZSwgaGFuZGxlcik7XHJcbiAgICAgIH0pO1xyXG4gICAgfSBcclxuICAgIGlmIChlbGVtZW50LmFkZEV2ZW50TGlzdGVuZXIpIHtcclxuICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKG5hbWUsIGhhbmRsZXIsIGZhbHNlKTtcclxuICAgICAgcmV0dXJuIGRpc3Bvc2FibGVDcmVhdGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihuYW1lLCBoYW5kbGVyLCBmYWxzZSk7XHJcbiAgICAgIH0pO1xyXG4gICAgfVxyXG4gICAgdGhyb3cgbmV3IEVycm9yKCdObyBsaXN0ZW5lciBmb3VuZCcpO1xyXG4gIH1cclxuXHJcbiAgZnVuY3Rpb24gY3JlYXRlRXZlbnRMaXN0ZW5lciAoZWwsIGV2ZW50TmFtZSwgaGFuZGxlcikge1xyXG4gICAgdmFyIGRpc3Bvc2FibGVzID0gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoKTtcclxuXHJcbiAgICAvLyBBc3VtZSBOb2RlTGlzdFxyXG4gICAgaWYgKHR5cGVvZiBlbC5pdGVtID09PSAnZnVuY3Rpb24nICYmIHR5cGVvZiBlbC5sZW5ndGggPT09ICdudW1iZXInKSB7XHJcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBlbC5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgIGRpc3Bvc2FibGVzLmFkZChjcmVhdGVFdmVudExpc3RlbmVyKGVsLml0ZW0oaSksIGV2ZW50TmFtZSwgaGFuZGxlcikpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2UgaWYgKGVsKSB7XHJcbiAgICAgIGRpc3Bvc2FibGVzLmFkZChjcmVhdGVMaXN0ZW5lcihlbCwgZXZlbnROYW1lLCBoYW5kbGVyKSk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIGRpc3Bvc2FibGVzO1xyXG4gIH1cclxuXHJcbiAgLy8gQ2hlY2sgZm9yIEFuZ3VsYXIvalF1ZXJ5L1plcHRvIHN1cHBvcnRcclxuICB2YXIganEgPVxyXG4gICAhIXJvb3QuYW5ndWxhciAmJiAhIWFuZ3VsYXIuZWxlbWVudCA/IGFuZ3VsYXIuZWxlbWVudCA6XHJcbiAgICghIXJvb3QualF1ZXJ5ID8gcm9vdC5qUXVlcnkgOiAoXHJcbiAgICAgISFyb290LlplcHRvID8gcm9vdC5aZXB0byA6IG51bGwpKTtcclxuXHJcbiAgLy8gQ2hlY2sgZm9yIGVtYmVyXHJcbiAgdmFyIGVtYmVyID0gISFyb290LkVtYmVyICYmIHR5cGVvZiByb290LkVtYmVyLmFkZExpc3RlbmVyID09PSAnZnVuY3Rpb24nO1xyXG5cclxuICAvKipcclxuICAgKiBDcmVhdGVzIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgYnkgYWRkaW5nIGFuIGV2ZW50IGxpc3RlbmVyIHRvIHRoZSBtYXRjaGluZyBET01FbGVtZW50IG9yIGVhY2ggaXRlbSBpbiB0aGUgTm9kZUxpc3QuXHJcbiAgICpcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqICAgdmFyIHNvdXJjZSA9IFJ4Lk9ic2VydmFibGUuZnJvbUV2ZW50KGVsZW1lbnQsICdtb3VzZXVwJyk7XHJcbiAgICogXHJcbiAgICogQHBhcmFtIHtPYmplY3R9IGVsZW1lbnQgVGhlIERPTUVsZW1lbnQgb3IgTm9kZUxpc3QgdG8gYXR0YWNoIGEgbGlzdGVuZXIuXHJcbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50TmFtZSBUaGUgZXZlbnQgbmFtZSB0byBhdHRhY2ggdGhlIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3NlbGVjdG9yXSBBIHNlbGVjdG9yIHdoaWNoIHRha2VzIHRoZSBhcmd1bWVudHMgZnJvbSB0aGUgZXZlbnQgaGFuZGxlciB0byBwcm9kdWNlIGEgc2luZ2xlIGl0ZW0gdG8geWllbGQgb24gbmV4dC4gICAgIFxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIG9mIGV2ZW50cyBmcm9tIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBhbmQgdGhlIHNwZWNpZmllZCBldmVudC5cclxuICAgKi9cclxuICBPYnNlcnZhYmxlLmZyb21FdmVudCA9IGZ1bmN0aW9uIChlbGVtZW50LCBldmVudE5hbWUsIHNlbGVjdG9yKSB7XHJcbiAgICBpZiAoZW1iZXIpIHtcclxuICAgICAgcmV0dXJuIGZyb21FdmVudFBhdHRlcm4oXHJcbiAgICAgICAgZnVuY3Rpb24gKGgpIHsgRW1iZXIuYWRkTGlzdGVuZXIoZWxlbWVudCwgZXZlbnROYW1lLCBoKTsgfSxcclxuICAgICAgICBmdW5jdGlvbiAoaCkgeyBFbWJlci5yZW1vdmVMaXN0ZW5lcihlbGVtZW50LCBldmVudE5hbWUsIGgpOyB9LFxyXG4gICAgICAgIHNlbGVjdG9yKTtcclxuICAgIH0gICAgXHJcbiAgICBpZiAoanEpIHtcclxuICAgICAgdmFyICRlbGVtID0ganEoZWxlbWVudCk7XHJcbiAgICAgIHJldHVybiBmcm9tRXZlbnRQYXR0ZXJuKFxyXG4gICAgICAgIGZ1bmN0aW9uIChoKSB7ICRlbGVtLm9uKGV2ZW50TmFtZSwgaCk7IH0sXHJcbiAgICAgICAgZnVuY3Rpb24gKGgpIHsgJGVsZW0ub2ZmKGV2ZW50TmFtZSwgaCk7IH0sXHJcbiAgICAgICAgc2VsZWN0b3IpO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICByZXR1cm4gY3JlYXRlRXZlbnRMaXN0ZW5lcihcclxuICAgICAgICBlbGVtZW50LCBcclxuICAgICAgICBldmVudE5hbWUsIFxyXG4gICAgICAgIGZ1bmN0aW9uIGhhbmRsZXIgKGUpIHsgXHJcbiAgICAgICAgICB2YXIgcmVzdWx0cyA9IGU7XHJcblxyXG4gICAgICAgICAgaWYgKHNlbGVjdG9yKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgcmVzdWx0cyA9IHNlbGVjdG9yKGFyZ3VtZW50cyk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycikge1xyXG4gICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXJyKTtcclxuICAgICAgICAgICAgICByZXR1cm5cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG5cclxuICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChyZXN1bHRzKTsgXHJcbiAgICAgICAgfSk7XHJcbiAgICB9KS5wdWJsaXNoKCkucmVmQ291bnQoKTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiBDcmVhdGVzIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgZnJvbSBhbiBldmVudCBlbWl0dGVyIHZpYSBhbiBhZGRIYW5kbGVyL3JlbW92ZUhhbmRsZXIgcGFpci5cclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhZGRIYW5kbGVyIFRoZSBmdW5jdGlvbiB0byBhZGQgYSBoYW5kbGVyIHRvIHRoZSBlbWl0dGVyLlxyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IFtyZW1vdmVIYW5kbGVyXSBUaGUgb3B0aW9uYWwgZnVuY3Rpb24gdG8gcmVtb3ZlIGEgaGFuZGxlciBmcm9tIGFuIGVtaXR0ZXIuXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3NlbGVjdG9yXSBBIHNlbGVjdG9yIHdoaWNoIHRha2VzIHRoZSBhcmd1bWVudHMgZnJvbSB0aGUgZXZlbnQgaGFuZGxlciB0byBwcm9kdWNlIGEgc2luZ2xlIGl0ZW0gdG8geWllbGQgb24gbmV4dC5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aGljaCB3cmFwcyBhbiBldmVudCBmcm9tIGFuIGV2ZW50IGVtaXR0ZXJcclxuICAgKi9cclxuICB2YXIgZnJvbUV2ZW50UGF0dGVybiA9IE9ic2VydmFibGUuZnJvbUV2ZW50UGF0dGVybiA9IGZ1bmN0aW9uIChhZGRIYW5kbGVyLCByZW1vdmVIYW5kbGVyLCBzZWxlY3Rvcikge1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICBmdW5jdGlvbiBpbm5lckhhbmRsZXIgKGUpIHtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gZTtcclxuICAgICAgICBpZiAoc2VsZWN0b3IpIHtcclxuICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHJlc3VsdCA9IHNlbGVjdG9yKGFyZ3VtZW50cyk7XHJcbiAgICAgICAgICB9IGNhdGNoIChlcnIpIHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlcnIpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG9ic2VydmVyLm9uTmV4dChyZXN1bHQpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICB2YXIgcmV0dXJuVmFsdWUgPSBhZGRIYW5kbGVyKGlubmVySGFuZGxlcik7XHJcbiAgICAgIHJldHVybiBkaXNwb3NhYmxlQ3JlYXRlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAocmVtb3ZlSGFuZGxlcikge1xyXG4gICAgICAgICAgcmVtb3ZlSGFuZGxlcihpbm5lckhhbmRsZXIsIHJldHVyblZhbHVlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gICAgfSkucHVibGlzaCgpLnJlZkNvdW50KCk7XHJcbiAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogSW52b2tlcyB0aGUgYXN5bmNocm9ub3VzIGZ1bmN0aW9uLCBzdXJmYWNpbmcgdGhlIHJlc3VsdCB0aHJvdWdoIGFuIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gZnVuY3Rpb25Bc3luYyBBc3luY2hyb25vdXMgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhIFByb21pc2UgdG8gcnVuLlxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGV4cG9zaW5nIHRoZSBmdW5jdGlvbidzIHJlc3VsdCB2YWx1ZSwgb3IgYW4gZXhjZXB0aW9uLlxyXG4gICAqL1xyXG4gIE9ic2VydmFibGUuc3RhcnRBc3luYyA9IGZ1bmN0aW9uIChmdW5jdGlvbkFzeW5jKSB7XHJcbiAgICB2YXIgcHJvbWlzZTtcclxuICAgIHRyeSB7XHJcbiAgICAgIHByb21pc2UgPSBmdW5jdGlvbkFzeW5jKCk7XHJcbiAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgIHJldHVybiBvYnNlcnZhYmxlVGhyb3coZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKHByb21pc2UpO1xyXG4gIH1cclxuXHJcbiAgdmFyIFBhdXNhYmxlT2JzZXJ2YWJsZSA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcblxyXG4gICAgaW5oZXJpdHMoUGF1c2FibGVPYnNlcnZhYmxlLCBfc3VwZXIpO1xyXG5cclxuICAgIGZ1bmN0aW9uIHN1YnNjcmliZShvYnNlcnZlcikge1xyXG4gICAgICB2YXIgY29ubiA9IHRoaXMuc291cmNlLnB1Ymxpc2goKSxcclxuICAgICAgICBzdWJzY3JpcHRpb24gPSBjb25uLnN1YnNjcmliZShvYnNlcnZlciksXHJcbiAgICAgICAgY29ubmVjdGlvbiA9IGRpc3Bvc2FibGVFbXB0eTtcclxuXHJcbiAgICAgIHZhciBwYXVzYWJsZSA9IHRoaXMuc3ViamVjdC5kaXN0aW5jdFVudGlsQ2hhbmdlZCgpLnN1YnNjcmliZShmdW5jdGlvbiAoYikge1xyXG4gICAgICAgIGlmIChiKSB7XHJcbiAgICAgICAgICBjb25uZWN0aW9uID0gY29ubi5jb25uZWN0KCk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGNvbm5lY3Rpb24uZGlzcG9zZSgpO1xyXG4gICAgICAgICAgY29ubmVjdGlvbiA9IGRpc3Bvc2FibGVFbXB0eTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgICAgcmV0dXJuIG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKHN1YnNjcmlwdGlvbiwgY29ubmVjdGlvbiwgcGF1c2FibGUpO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIFBhdXNhYmxlT2JzZXJ2YWJsZShzb3VyY2UsIHN1YmplY3QpIHtcclxuICAgICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7XHJcbiAgICAgIHRoaXMuc3ViamVjdCA9IHN1YmplY3QgfHwgbmV3IFN1YmplY3QoKTtcclxuICAgICAgdGhpcy5pc1BhdXNlZCA9IHRydWU7XHJcbiAgICAgIF9zdXBlci5jYWxsKHRoaXMsIHN1YnNjcmliZSk7XHJcbiAgICB9XHJcblxyXG4gICAgUGF1c2FibGVPYnNlcnZhYmxlLnByb3RvdHlwZS5wYXVzZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgaWYgKHRoaXMuaXNQYXVzZWQgPT09IHRydWUpe1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmlzUGF1c2VkID0gdHJ1ZTtcclxuICAgICAgdGhpcy5zdWJqZWN0Lm9uTmV4dChmYWxzZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIFBhdXNhYmxlT2JzZXJ2YWJsZS5wcm90b3R5cGUucmVzdW1lID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICBpZiAodGhpcy5pc1BhdXNlZCA9PT0gZmFsc2Upe1xyXG4gICAgICAgIHJldHVybjtcclxuICAgICAgfVxyXG4gICAgICB0aGlzLmlzUGF1c2VkID0gZmFsc2U7XHJcbiAgICAgIHRoaXMuc3ViamVjdC5vbk5leHQodHJ1ZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiBQYXVzYWJsZU9ic2VydmFibGU7XHJcblxyXG4gIH0oT2JzZXJ2YWJsZSkpO1xyXG5cclxuICAvKipcclxuICAgKiBQYXVzZXMgdGhlIHVuZGVybHlpbmcgb2JzZXJ2YWJsZSBzZXF1ZW5jZSBiYXNlZCB1cG9uIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHdoaWNoIHlpZWxkcyB0cnVlL2ZhbHNlLlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogdmFyIHBhdXNlciA9IG5ldyBSeC5TdWJqZWN0KCk7XHJcbiAgICogdmFyIHNvdXJjZSA9IFJ4Lk9ic2VydmFibGUuaW50ZXJ2YWwoMTAwKS5wYXVzYWJsZShwYXVzZXIpO1xyXG4gICAqIEBwYXJhbSB7T2JzZXJ2YWJsZX0gcGF1c2VyIFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHVzZWQgdG8gcGF1c2UgdGhlIHVuZGVybHlpbmcgc2VxdWVuY2UuXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHdoaWNoIGlzIHBhdXNlZCBiYXNlZCB1cG9uIHRoZSBwYXVzZXIuXHJcbiAgICovXHJcbiAgb2JzZXJ2YWJsZVByb3RvLnBhdXNhYmxlID0gZnVuY3Rpb24gKHBhdXNlcikge1xyXG4gICAgcmV0dXJuIG5ldyBQYXVzYWJsZU9ic2VydmFibGUodGhpcywgcGF1c2VyKTtcclxuICB9O1xyXG4gIGZ1bmN0aW9uIGNvbWJpbmVMYXRlc3RTb3VyY2Uoc291cmNlLCBzdWJqZWN0LCByZXN1bHRTZWxlY3Rvcikge1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICB2YXIgbiA9IDIsXHJcbiAgICAgICAgaGFzVmFsdWUgPSBbZmFsc2UsIGZhbHNlXSxcclxuICAgICAgICBoYXNWYWx1ZUFsbCA9IGZhbHNlLFxyXG4gICAgICAgIGlzRG9uZSA9IGZhbHNlLFxyXG4gICAgICAgIHZhbHVlcyA9IG5ldyBBcnJheShuKTtcclxuXHJcbiAgICAgIGZ1bmN0aW9uIG5leHQoeCwgaSkge1xyXG4gICAgICAgIHZhbHVlc1tpXSA9IHhcclxuICAgICAgICB2YXIgcmVzO1xyXG4gICAgICAgIGhhc1ZhbHVlW2ldID0gdHJ1ZTtcclxuICAgICAgICBpZiAoaGFzVmFsdWVBbGwgfHwgKGhhc1ZhbHVlQWxsID0gaGFzVmFsdWUuZXZlcnkoaWRlbnRpdHkpKSkge1xyXG4gICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgcmVzID0gcmVzdWx0U2VsZWN0b3IuYXBwbHkobnVsbCwgdmFsdWVzKTtcclxuICAgICAgICAgIH0gY2F0Y2ggKGV4KSB7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXgpO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQocmVzKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGlzRG9uZSkge1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIHJldHVybiBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZShcclxuICAgICAgICBzb3VyY2Uuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgbmV4dCh4LCAwKTtcclxuICAgICAgICAgIH0sXHJcbiAgICAgICAgICBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLFxyXG4gICAgICAgICAgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBpc0RvbmUgPSB0cnVlO1xyXG4gICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgfSksXHJcbiAgICAgICAgc3ViamVjdC5zdWJzY3JpYmUoXHJcbiAgICAgICAgICBmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICBuZXh0KHgsIDEpO1xyXG4gICAgICAgICAgfSxcclxuICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlcikpXHJcbiAgICAgICAgKTtcclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgdmFyIFBhdXNhYmxlQnVmZmVyZWRPYnNlcnZhYmxlID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuXHJcbiAgICBpbmhlcml0cyhQYXVzYWJsZUJ1ZmZlcmVkT2JzZXJ2YWJsZSwgX3N1cGVyKTtcclxuXHJcbiAgICBmdW5jdGlvbiBzdWJzY3JpYmUob2JzZXJ2ZXIpIHtcclxuICAgICAgdmFyIHEgPSBbXSwgcHJldmlvdXMgPSB0cnVlO1xyXG4gICAgICBcclxuICAgICAgdmFyIHN1YnNjcmlwdGlvbiA9ICBcclxuICAgICAgICBjb21iaW5lTGF0ZXN0U291cmNlKFxyXG4gICAgICAgICAgdGhpcy5zb3VyY2UsXHJcbiAgICAgICAgICB0aGlzLnN1YmplY3QuZGlzdGluY3RVbnRpbENoYW5nZWQoKSwgXHJcbiAgICAgICAgICBmdW5jdGlvbiAoZGF0YSwgc2hvdWxkRmlyZSkge1xyXG4gICAgICAgICAgICByZXR1cm4geyBkYXRhOiBkYXRhLCBzaG91bGRGaXJlOiBzaG91bGRGaXJlIH07ICAgICAgXHJcbiAgICAgICAgICB9KVxyXG4gICAgICAgICAgLnN1YnNjcmliZShcclxuICAgICAgICAgICAgZnVuY3Rpb24gKHJlc3VsdHMpIHtcclxuICAgICAgICAgICAgICBpZiAocmVzdWx0cy5zaG91bGRGaXJlICYmIHByZXZpb3VzKSB7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQocmVzdWx0cy5kYXRhKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgaWYgKHJlc3VsdHMuc2hvdWxkRmlyZSAmJiAhcHJldmlvdXMpIHtcclxuICAgICAgICAgICAgICAgIHdoaWxlIChxLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHEuc2hpZnQoKSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBwcmV2aW91cyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICghcmVzdWx0cy5zaG91bGRGaXJlICYmICFwcmV2aW91cykge1xyXG4gICAgICAgICAgICAgICAgcS5wdXNoKHJlc3VsdHMuZGF0YSk7XHJcbiAgICAgICAgICAgICAgfSBlbHNlIGlmICghcmVzdWx0cy5zaG91bGRGaXJlICYmIHByZXZpb3VzKSB7XHJcbiAgICAgICAgICAgICAgICBwcmV2aW91cyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIH0sIFxyXG4gICAgICAgICAgICBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgLy8gRW1wdHkgYnVmZmVyIGJlZm9yZSBzZW5kaW5nIGVycm9yXHJcbiAgICAgICAgICAgICAgd2hpbGUgKHEubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHEuc2hpZnQoKSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXJyKTtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgIC8vIEVtcHR5IGJ1ZmZlciBiZWZvcmUgc2VuZGluZyBjb21wbGV0aW9uXHJcbiAgICAgICAgICAgICAgd2hpbGUgKHEubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHEuc2hpZnQoKSk7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7ICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgKTtcclxuXHJcbiAgICAgIHRoaXMuc3ViamVjdC5vbk5leHQoZmFsc2UpO1xyXG5cclxuICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvbjsgICAgICBcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBQYXVzYWJsZUJ1ZmZlcmVkT2JzZXJ2YWJsZShzb3VyY2UsIHN1YmplY3QpIHtcclxuICAgICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7XHJcbiAgICAgIHRoaXMuc3ViamVjdCA9IHN1YmplY3QgfHwgbmV3IFN1YmplY3QoKTtcclxuICAgICAgdGhpcy5pc1BhdXNlZCA9IHRydWU7XHJcbiAgICAgIF9zdXBlci5jYWxsKHRoaXMsIHN1YnNjcmliZSk7XHJcbiAgICB9XHJcblxyXG4gICAgUGF1c2FibGVCdWZmZXJlZE9ic2VydmFibGUucHJvdG90eXBlLnBhdXNlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICBpZiAodGhpcy5pc1BhdXNlZCA9PT0gdHJ1ZSl7XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuaXNQYXVzZWQgPSB0cnVlO1xyXG4gICAgICB0aGlzLnN1YmplY3Qub25OZXh0KGZhbHNlKTtcclxuICAgIH07XHJcblxyXG4gICAgUGF1c2FibGVCdWZmZXJlZE9ic2VydmFibGUucHJvdG90eXBlLnJlc3VtZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgaWYgKHRoaXMuaXNQYXVzZWQgPT09IGZhbHNlKXtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgdGhpcy5pc1BhdXNlZCA9IGZhbHNlO1xyXG4gICAgICB0aGlzLnN1YmplY3Qub25OZXh0KHRydWUpO1xyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gUGF1c2FibGVCdWZmZXJlZE9ic2VydmFibGU7IFxyXG5cclxuICB9KE9ic2VydmFibGUpKTtcclxuXHJcbiAgLyoqXHJcbiAgICogUGF1c2VzIHRoZSB1bmRlcmx5aW5nIG9ic2VydmFibGUgc2VxdWVuY2UgYmFzZWQgdXBvbiB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aGljaCB5aWVsZHMgdHJ1ZS9mYWxzZSxcclxuICAgKiBhbmQgeWllbGRzIHRoZSB2YWx1ZXMgdGhhdCB3ZXJlIGJ1ZmZlcmVkIHdoaWxlIHBhdXNlZC5cclxuICAgKiBAZXhhbXBsZVxyXG4gICAqIHZhciBwYXVzZXIgPSBuZXcgUnguU3ViamVjdCgpO1xyXG4gICAqIHZhciBzb3VyY2UgPSBSeC5PYnNlcnZhYmxlLmludGVydmFsKDEwMCkucGF1c2FibGVCdWZmZXJlZChwYXVzZXIpO1xyXG4gICAqIEBwYXJhbSB7T2JzZXJ2YWJsZX0gcGF1c2VyIFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHVzZWQgdG8gcGF1c2UgdGhlIHVuZGVybHlpbmcgc2VxdWVuY2UuXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHdoaWNoIGlzIHBhdXNlZCBiYXNlZCB1cG9uIHRoZSBwYXVzZXIuXHJcbiAgICovICBcclxuICBvYnNlcnZhYmxlUHJvdG8ucGF1c2FibGVCdWZmZXJlZCA9IGZ1bmN0aW9uIChzdWJqZWN0KSB7XHJcbiAgICByZXR1cm4gbmV3IFBhdXNhYmxlQnVmZmVyZWRPYnNlcnZhYmxlKHRoaXMsIHN1YmplY3QpO1xyXG4gIH07XHJcblxyXG4gIC8qKlxyXG4gICAqIEF0dGFjaGVzIGEgY29udHJvbGxlciB0byB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aXRoIHRoZSBhYmlsaXR5IHRvIHF1ZXVlLlxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogdmFyIHNvdXJjZSA9IFJ4Lk9ic2VydmFibGUuaW50ZXJ2YWwoMTAwKS5jb250cm9sbGVkKCk7XHJcbiAgICogc291cmNlLnJlcXVlc3QoMyk7IC8vIFJlYWRzIDMgdmFsdWVzXHJcbiAgICogQHBhcmFtIHtPYnNlcnZhYmxlfSBwYXVzZXIgVGhlIG9ic2VydmFibGUgc2VxdWVuY2UgdXNlZCB0byBwYXVzZSB0aGUgdW5kZXJseWluZyBzZXF1ZW5jZS5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIG9ic2VydmFibGUgc2VxdWVuY2Ugd2hpY2ggaXMgcGF1c2VkIGJhc2VkIHVwb24gdGhlIHBhdXNlci5cclxuICAgKi8gXHJcbiAgb2JzZXJ2YWJsZVByb3RvLmNvbnRyb2xsZWQgPSBmdW5jdGlvbiAoZW5hYmxlUXVldWUpIHtcclxuICAgIGlmIChlbmFibGVRdWV1ZSA9PSBudWxsKSB7ICBlbmFibGVRdWV1ZSA9IHRydWU7IH1cclxuICAgIHJldHVybiBuZXcgQ29udHJvbGxlZE9ic2VydmFibGUodGhpcywgZW5hYmxlUXVldWUpO1xyXG4gIH07XHJcbiAgdmFyIENvbnRyb2xsZWRPYnNlcnZhYmxlID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuXHJcbiAgICBpbmhlcml0cyhDb250cm9sbGVkT2JzZXJ2YWJsZSwgX3N1cGVyKTtcclxuXHJcbiAgICBmdW5jdGlvbiBzdWJzY3JpYmUgKG9ic2VydmVyKSB7XHJcbiAgICAgIHJldHVybiB0aGlzLnNvdXJjZS5zdWJzY3JpYmUob2JzZXJ2ZXIpO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIENvbnRyb2xsZWRPYnNlcnZhYmxlIChzb3VyY2UsIGVuYWJsZVF1ZXVlKSB7XHJcbiAgICAgIF9zdXBlci5jYWxsKHRoaXMsIHN1YnNjcmliZSk7XHJcbiAgICAgIHRoaXMuc3ViamVjdCA9IG5ldyBDb250cm9sbGVkU3ViamVjdChlbmFibGVRdWV1ZSk7XHJcbiAgICAgIHRoaXMuc291cmNlID0gc291cmNlLm11bHRpY2FzdCh0aGlzLnN1YmplY3QpLnJlZkNvdW50KCk7XHJcbiAgICB9XHJcblxyXG4gICAgQ29udHJvbGxlZE9ic2VydmFibGUucHJvdG90eXBlLnJlcXVlc3QgPSBmdW5jdGlvbiAobnVtYmVyT2ZJdGVtcykge1xyXG4gICAgICBpZiAobnVtYmVyT2ZJdGVtcyA9PSBudWxsKSB7IG51bWJlck9mSXRlbXMgPSAtMTsgfVxyXG4gICAgICByZXR1cm4gdGhpcy5zdWJqZWN0LnJlcXVlc3QobnVtYmVyT2ZJdGVtcyk7XHJcbiAgICB9O1xyXG5cclxuICAgIHJldHVybiBDb250cm9sbGVkT2JzZXJ2YWJsZTtcclxuXHJcbiAgfShPYnNlcnZhYmxlKSk7XHJcblxyXG4gICAgdmFyIENvbnRyb2xsZWRTdWJqZWN0ID0gUnguQ29udHJvbGxlZFN1YmplY3QgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBzdWJzY3JpYmUgKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnN1YmplY3Quc3Vic2NyaWJlKG9ic2VydmVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGluaGVyaXRzKENvbnRyb2xsZWRTdWJqZWN0LCBfc3VwZXIpO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBDb250cm9sbGVkU3ViamVjdChlbmFibGVRdWV1ZSkge1xyXG4gICAgICAgICAgICBpZiAoZW5hYmxlUXVldWUgPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgZW5hYmxlUXVldWUgPSB0cnVlO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBzdWJzY3JpYmUpO1xyXG4gICAgICAgICAgICB0aGlzLnN1YmplY3QgPSBuZXcgU3ViamVjdCgpO1xyXG4gICAgICAgICAgICB0aGlzLmVuYWJsZVF1ZXVlID0gZW5hYmxlUXVldWU7XHJcbiAgICAgICAgICAgIHRoaXMucXVldWUgPSBlbmFibGVRdWV1ZSA/IFtdIDogbnVsbDtcclxuICAgICAgICAgICAgdGhpcy5yZXF1ZXN0ZWRDb3VudCA9IDA7XHJcbiAgICAgICAgICAgIHRoaXMucmVxdWVzdGVkRGlzcG9zYWJsZSA9IGRpc3Bvc2FibGVFbXB0eTtcclxuICAgICAgICAgICAgdGhpcy5lcnJvciA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMuaGFzRmFpbGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMuaGFzQ29tcGxldGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgIHRoaXMuY29udHJvbGxlZERpc3Bvc2FibGUgPSBkaXNwb3NhYmxlRW1wdHk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBhZGRQcm9wZXJ0aWVzKENvbnRyb2xsZWRTdWJqZWN0LnByb3RvdHlwZSwgT2JzZXJ2ZXIsIHtcclxuICAgICAgICAgICAgb25Db21wbGV0ZWQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGNoZWNrRGlzcG9zZWQuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuaGFzQ29tcGxldGVkID0gdHJ1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuZW5hYmxlUXVldWUgfHwgdGhpcy5xdWV1ZS5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnN1YmplY3Qub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgb25FcnJvcjogZnVuY3Rpb24gKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICBjaGVja0Rpc3Bvc2VkLmNhbGwodGhpcyk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmhhc0ZhaWxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gZXJyb3I7XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmVuYWJsZVF1ZXVlIHx8IHRoaXMucXVldWUubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdWJqZWN0Lm9uRXJyb3IoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgfSAgIFxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBvbk5leHQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgY2hlY2tEaXNwb3NlZC5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgdmFyIGhhc1JlcXVlc3RlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlcXVlc3RlZENvdW50ID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuZW5hYmxlUXVldWUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5xdWV1ZS5wdXNoKHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLnJlcXVlc3RlZENvdW50ICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5yZXF1ZXN0ZWRDb3VudC0tID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2VDdXJyZW50UmVxdWVzdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGhhc1JlcXVlc3RlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgaWYgKGhhc1JlcXVlc3RlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3ViamVjdC5vbk5leHQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBfcHJvY2Vzc1JlcXVlc3Q6IGZ1bmN0aW9uIChudW1iZXJPZkl0ZW1zKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5lbmFibGVRdWV1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIC8vY29uc29sZS5sb2coJ3F1ZXVlIGxlbmd0aCcsIHRoaXMucXVldWUubGVuZ3RoKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgd2hpbGUgKHRoaXMucXVldWUubGVuZ3RoID49IG51bWJlck9mSXRlbXMgJiYgbnVtYmVyT2ZJdGVtcyA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy9jb25zb2xlLmxvZygnbnVtYmVyIG9mIGl0ZW1zJywgbnVtYmVyT2ZJdGVtcyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuc3ViamVjdC5vbk5leHQodGhpcy5xdWV1ZS5zaGlmdCgpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbnVtYmVyT2ZJdGVtcy0tO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMucXVldWUubGVuZ3RoICE9PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB7IG51bWJlck9mSXRlbXM6IG51bWJlck9mSXRlbXMsIHJldHVyblZhbHVlOiB0cnVlIH07XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgbnVtYmVyT2ZJdGVtczogbnVtYmVyT2ZJdGVtcywgcmV0dXJuVmFsdWU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmhhc0ZhaWxlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuc3ViamVjdC5vbkVycm9yKHRoaXMuZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbGxlZERpc3Bvc2FibGUuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuY29udHJvbGxlZERpc3Bvc2FibGUgPSBkaXNwb3NhYmxlRW1wdHk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHRoaXMuaGFzQ29tcGxldGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5zdWJqZWN0Lm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250cm9sbGVkRGlzcG9zYWJsZS5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb250cm9sbGVkRGlzcG9zYWJsZSA9IGRpc3Bvc2FibGVFbXB0eTsgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHsgbnVtYmVyT2ZJdGVtczogbnVtYmVyT2ZJdGVtcywgcmV0dXJuVmFsdWU6IGZhbHNlIH07XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIHJlcXVlc3Q6IGZ1bmN0aW9uIChudW1iZXIpIHtcclxuICAgICAgICAgICAgICAgIGNoZWNrRGlzcG9zZWQuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZGlzcG9zZUN1cnJlbnRSZXF1ZXN0KCk7XHJcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXMsXHJcbiAgICAgICAgICAgICAgICAgICAgciA9IHRoaXMuX3Byb2Nlc3NSZXF1ZXN0KG51bWJlcik7XHJcblxyXG4gICAgICAgICAgICAgICAgbnVtYmVyID0gci5udW1iZXJPZkl0ZW1zO1xyXG4gICAgICAgICAgICAgICAgaWYgKCFyLnJldHVyblZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yZXF1ZXN0ZWRDb3VudCA9IG51bWJlcjtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJlcXVlc3RlZERpc3Bvc2FibGUgPSBkaXNwb3NhYmxlQ3JlYXRlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5yZXF1ZXN0ZWRDb3VudCA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLnJlcXVlc3RlZERpc3Bvc2FibGVcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpc3Bvc2FibGVFbXB0eTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgZGlzcG9zZUN1cnJlbnRSZXF1ZXN0OiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJlcXVlc3RlZERpc3Bvc2FibGUuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5yZXF1ZXN0ZWREaXNwb3NhYmxlID0gZGlzcG9zYWJsZUVtcHR5O1xyXG4gICAgICAgICAgICB9LFxyXG5cclxuICAgICAgICAgICAgZGlzcG9zZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0Rpc3Bvc2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZXJyb3IgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdWJqZWN0LmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgIHRoaXMucmVxdWVzdGVkRGlzcG9zYWJsZS5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIENvbnRyb2xsZWRTdWJqZWN0O1xyXG4gICAgfShPYnNlcnZhYmxlKSk7XHJcbiAgICAvKipcclxuICAgICAqIE11bHRpY2FzdHMgdGhlIHNvdXJjZSBzZXF1ZW5jZSBub3RpZmljYXRpb25zIHRocm91Z2ggYW4gaW5zdGFudGlhdGVkIHN1YmplY3QgaW50byBhbGwgdXNlcyBvZiB0aGUgc2VxdWVuY2Ugd2l0aGluIGEgc2VsZWN0b3IgZnVuY3Rpb24uIEVhY2hcclxuICAgICAqIHN1YnNjcmlwdGlvbiB0byB0aGUgcmVzdWx0aW5nIHNlcXVlbmNlIGNhdXNlcyBhIHNlcGFyYXRlIG11bHRpY2FzdCBpbnZvY2F0aW9uLCBleHBvc2luZyB0aGUgc2VxdWVuY2UgcmVzdWx0aW5nIGZyb20gdGhlIHNlbGVjdG9yIGZ1bmN0aW9uJ3NcclxuICAgICAqIGludm9jYXRpb24uIEZvciBzcGVjaWFsaXphdGlvbnMgd2l0aCBmaXhlZCBzdWJqZWN0IHR5cGVzLCBzZWUgUHVibGlzaCwgUHVibGlzaExhc3QsIGFuZCBSZXBsYXkuXHJcbiAgICAgKiBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAxIC0gcmVzID0gc291cmNlLm11bHRpY2FzdChvYnNlcnZhYmxlKTtcclxuICAgICAqIDIgLSByZXMgPSBzb3VyY2UubXVsdGljYXN0KGZ1bmN0aW9uICgpIHsgcmV0dXJuIG5ldyBTdWJqZWN0KCk7IH0sIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4OyB9KTtcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbnxTdWJqZWN0fSBzdWJqZWN0T3JTdWJqZWN0U2VsZWN0b3IgXHJcbiAgICAgKiBGYWN0b3J5IGZ1bmN0aW9uIHRvIGNyZWF0ZSBhbiBpbnRlcm1lZGlhdGUgc3ViamVjdCB0aHJvdWdoIHdoaWNoIHRoZSBzb3VyY2Ugc2VxdWVuY2UncyBlbGVtZW50cyB3aWxsIGJlIG11bHRpY2FzdCB0byB0aGUgc2VsZWN0b3IgZnVuY3Rpb24uXHJcbiAgICAgKiBPcjpcclxuICAgICAqIFN1YmplY3QgdG8gcHVzaCBzb3VyY2UgZWxlbWVudHMgaW50by5cclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3NlbGVjdG9yXSBPcHRpb25hbCBzZWxlY3RvciBmdW5jdGlvbiB3aGljaCBjYW4gdXNlIHRoZSBtdWx0aWNhc3RlZCBzb3VyY2Ugc2VxdWVuY2Ugc3ViamVjdCB0byB0aGUgcG9saWNpZXMgZW5mb3JjZWQgYnkgdGhlIGNyZWF0ZWQgc3ViamVjdC4gU3BlY2lmaWVkIG9ubHkgaWYgPHBhcmFtcmVmIG5hbWU9XCJzdWJqZWN0T3JTdWJqZWN0U2VsZWN0b3JcIiBpcyBhIGZhY3RvcnkgZnVuY3Rpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbnRhaW5zIHRoZSBlbGVtZW50cyBvZiBhIHNlcXVlbmNlIHByb2R1Y2VkIGJ5IG11bHRpY2FzdGluZyB0aGUgc291cmNlIHNlcXVlbmNlIHdpdGhpbiBhIHNlbGVjdG9yIGZ1bmN0aW9uLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8ubXVsdGljYXN0ID0gZnVuY3Rpb24gKHN1YmplY3RPclN1YmplY3RTZWxlY3Rvciwgc2VsZWN0b3IpIHtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICByZXR1cm4gdHlwZW9mIHN1YmplY3RPclN1YmplY3RTZWxlY3RvciA9PT0gJ2Z1bmN0aW9uJyA/XHJcbiAgICAgICAgICAgIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICAgICAgdmFyIGNvbm5lY3RhYmxlID0gc291cmNlLm11bHRpY2FzdChzdWJqZWN0T3JTdWJqZWN0U2VsZWN0b3IoKSk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc2VsZWN0b3IoY29ubmVjdGFibGUpLnN1YnNjcmliZShvYnNlcnZlciksIGNvbm5lY3RhYmxlLmNvbm5lY3QoKSk7XHJcbiAgICAgICAgICAgIH0pIDpcclxuICAgICAgICAgICAgbmV3IENvbm5lY3RhYmxlT2JzZXJ2YWJsZShzb3VyY2UsIHN1YmplY3RPclN1YmplY3RTZWxlY3Rvcik7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgaXMgdGhlIHJlc3VsdCBvZiBpbnZva2luZyB0aGUgc2VsZWN0b3Igb24gYSBjb25uZWN0YWJsZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc2hhcmVzIGEgc2luZ2xlIHN1YnNjcmlwdGlvbiB0byB0aGUgdW5kZXJseWluZyBzZXF1ZW5jZS5cclxuICAgICAqIFRoaXMgb3BlcmF0b3IgaXMgYSBzcGVjaWFsaXphdGlvbiBvZiBNdWx0aWNhc3QgdXNpbmcgYSByZWd1bGFyIFN1YmplY3QuXHJcbiAgICAgKiBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiB2YXIgcmVzcmVzID0gc291cmNlLnB1Ymxpc2goKTtcclxuICAgICAqIHZhciByZXMgPSBzb3VyY2UucHVibGlzaChmdW5jdGlvbiAoeCkgeyByZXR1cm4geDsgfSk7XHJcbiAgICAgKiBcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IFtzZWxlY3Rvcl0gU2VsZWN0b3IgZnVuY3Rpb24gd2hpY2ggY2FuIHVzZSB0aGUgbXVsdGljYXN0ZWQgc291cmNlIHNlcXVlbmNlIGFzIG1hbnkgdGltZXMgYXMgbmVlZGVkLCB3aXRob3V0IGNhdXNpbmcgbXVsdGlwbGUgc3Vic2NyaXB0aW9ucyB0byB0aGUgc291cmNlIHNlcXVlbmNlLiBTdWJzY3JpYmVycyB0byB0aGUgZ2l2ZW4gc291cmNlIHdpbGwgcmVjZWl2ZSBhbGwgbm90aWZpY2F0aW9ucyBvZiB0aGUgc291cmNlIGZyb20gdGhlIHRpbWUgb2YgdGhlIHN1YnNjcmlwdGlvbiBvbi5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgY29udGFpbnMgdGhlIGVsZW1lbnRzIG9mIGEgc2VxdWVuY2UgcHJvZHVjZWQgYnkgbXVsdGljYXN0aW5nIHRoZSBzb3VyY2Ugc2VxdWVuY2Ugd2l0aGluIGEgc2VsZWN0b3IgZnVuY3Rpb24uXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5wdWJsaXNoID0gZnVuY3Rpb24gKHNlbGVjdG9yKSB7XHJcbiAgICAgICAgcmV0dXJuICFzZWxlY3RvciA/XHJcbiAgICAgICAgICAgIHRoaXMubXVsdGljYXN0KG5ldyBTdWJqZWN0KCkpIDpcclxuICAgICAgICAgICAgdGhpcy5tdWx0aWNhc3QoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBTdWJqZWN0KCk7XHJcbiAgICAgICAgICAgIH0sIHNlbGVjdG9yKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBzaGFyZXMgYSBzaW5nbGUgc3Vic2NyaXB0aW9uIHRvIHRoZSB1bmRlcmx5aW5nIHNlcXVlbmNlLlxyXG4gICAgICogVGhpcyBvcGVyYXRvciBpcyBhIHNwZWNpYWxpemF0aW9uIG9mIHB1Ymxpc2ggd2hpY2ggY3JlYXRlcyBhIHN1YnNjcmlwdGlvbiB3aGVuIHRoZSBudW1iZXIgb2Ygb2JzZXJ2ZXJzIGdvZXMgZnJvbSB6ZXJvIHRvIG9uZSwgdGhlbiBzaGFyZXMgdGhhdCBzdWJzY3JpcHRpb24gd2l0aCBhbGwgc3Vic2VxdWVudCBvYnNlcnZlcnMgdW50aWwgdGhlIG51bWJlciBvZiBvYnNlcnZlcnMgcmV0dXJucyB0byB6ZXJvLCBhdCB3aGljaCBwb2ludCB0aGUgc3Vic2NyaXB0aW9uIGlzIGRpc3Bvc2VkLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5zaGFyZSgpO1xyXG4gICAgICogXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbnRhaW5zIHRoZSBlbGVtZW50cyBvZiBhIHNlcXVlbmNlIHByb2R1Y2VkIGJ5IG11bHRpY2FzdGluZyB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uc2hhcmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMucHVibGlzaChudWxsKS5yZWZDb3VudCgpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGlzIHRoZSByZXN1bHQgb2YgaW52b2tpbmcgdGhlIHNlbGVjdG9yIG9uIGEgY29ubmVjdGFibGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHNoYXJlcyBhIHNpbmdsZSBzdWJzY3JpcHRpb24gdG8gdGhlIHVuZGVybHlpbmcgc2VxdWVuY2UgY29udGFpbmluZyBvbmx5IHRoZSBsYXN0IG5vdGlmaWNhdGlvbi5cclxuICAgICAqIFRoaXMgb3BlcmF0b3IgaXMgYSBzcGVjaWFsaXphdGlvbiBvZiBNdWx0aWNhc3QgdXNpbmcgYSBBc3luY1N1YmplY3QuXHJcbiAgICAgKiBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiB2YXIgcmVzID0gc291cmNlLnB1Ymxpc2hMYXN0KCk7XHJcbiAgICAgKiB2YXIgcmVzID0gc291cmNlLnB1Ymxpc2hMYXN0KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4OyB9KTtcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHNlbGVjdG9yIFtPcHRpb25hbF0gU2VsZWN0b3IgZnVuY3Rpb24gd2hpY2ggY2FuIHVzZSB0aGUgbXVsdGljYXN0ZWQgc291cmNlIHNlcXVlbmNlIGFzIG1hbnkgdGltZXMgYXMgbmVlZGVkLCB3aXRob3V0IGNhdXNpbmcgbXVsdGlwbGUgc3Vic2NyaXB0aW9ucyB0byB0aGUgc291cmNlIHNlcXVlbmNlLiBTdWJzY3JpYmVycyB0byB0aGUgZ2l2ZW4gc291cmNlIHdpbGwgb25seSByZWNlaXZlIHRoZSBsYXN0IG5vdGlmaWNhdGlvbiBvZiB0aGUgc291cmNlLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBjb250YWlucyB0aGUgZWxlbWVudHMgb2YgYSBzZXF1ZW5jZSBwcm9kdWNlZCBieSBtdWx0aWNhc3RpbmcgdGhlIHNvdXJjZSBzZXF1ZW5jZSB3aXRoaW4gYSBzZWxlY3RvciBmdW5jdGlvbi5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnB1Ymxpc2hMYXN0ID0gZnVuY3Rpb24gKHNlbGVjdG9yKSB7XHJcbiAgICAgICAgcmV0dXJuICFzZWxlY3RvciA/XHJcbiAgICAgICAgICAgIHRoaXMubXVsdGljYXN0KG5ldyBBc3luY1N1YmplY3QoKSkgOlxyXG4gICAgICAgICAgICB0aGlzLm11bHRpY2FzdChmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbmV3IEFzeW5jU3ViamVjdCgpO1xyXG4gICAgICAgICAgICB9LCBzZWxlY3Rvcik7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgaXMgdGhlIHJlc3VsdCBvZiBpbnZva2luZyB0aGUgc2VsZWN0b3Igb24gYSBjb25uZWN0YWJsZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc2hhcmVzIGEgc2luZ2xlIHN1YnNjcmlwdGlvbiB0byB0aGUgdW5kZXJseWluZyBzZXF1ZW5jZSBhbmQgc3RhcnRzIHdpdGggaW5pdGlhbFZhbHVlLlxyXG4gICAgICogVGhpcyBvcGVyYXRvciBpcyBhIHNwZWNpYWxpemF0aW9uIG9mIE11bHRpY2FzdCB1c2luZyBhIEJlaGF2aW9yU3ViamVjdC5cclxuICAgICAqIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqIHZhciByZXMgPSBzb3VyY2UucHVibGlzaFZhbHVlKDQyKTtcclxuICAgICAqIHZhciByZXMgPSBzb3VyY2UucHVibGlzaFZhbHVlKGZ1bmN0aW9uICh4KSB7IHJldHVybiB4LnNlbGVjdChmdW5jdGlvbiAoeSkgeyByZXR1cm4geSAqIHk7IH0pIH0sIDQyKTtcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3NlbGVjdG9yXSBPcHRpb25hbCBzZWxlY3RvciBmdW5jdGlvbiB3aGljaCBjYW4gdXNlIHRoZSBtdWx0aWNhc3RlZCBzb3VyY2Ugc2VxdWVuY2UgYXMgbWFueSB0aW1lcyBhcyBuZWVkZWQsIHdpdGhvdXQgY2F1c2luZyBtdWx0aXBsZSBzdWJzY3JpcHRpb25zIHRvIHRoZSBzb3VyY2Ugc2VxdWVuY2UuIFN1YnNjcmliZXJzIHRvIHRoZSBnaXZlbiBzb3VyY2Ugd2lsbCByZWNlaXZlIGltbWVkaWF0ZWx5IHJlY2VpdmUgdGhlIGluaXRpYWwgdmFsdWUsIGZvbGxvd2VkIGJ5IGFsbCBub3RpZmljYXRpb25zIG9mIHRoZSBzb3VyY2UgZnJvbSB0aGUgdGltZSBvZiB0aGUgc3Vic2NyaXB0aW9uIG9uLlxyXG4gICAgICogQHBhcmFtIHtNaXhlZH0gaW5pdGlhbFZhbHVlIEluaXRpYWwgdmFsdWUgcmVjZWl2ZWQgYnkgb2JzZXJ2ZXJzIHVwb24gc3Vic2NyaXB0aW9uLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBjb250YWlucyB0aGUgZWxlbWVudHMgb2YgYSBzZXF1ZW5jZSBwcm9kdWNlZCBieSBtdWx0aWNhc3RpbmcgdGhlIHNvdXJjZSBzZXF1ZW5jZSB3aXRoaW4gYSBzZWxlY3RvciBmdW5jdGlvbi5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnB1Ymxpc2hWYWx1ZSA9IGZ1bmN0aW9uIChpbml0aWFsVmFsdWVPclNlbGVjdG9yLCBpbml0aWFsVmFsdWUpIHtcclxuICAgICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMiA/XHJcbiAgICAgICAgICAgIHRoaXMubXVsdGljYXN0KGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgQmVoYXZpb3JTdWJqZWN0KGluaXRpYWxWYWx1ZSk7XHJcbiAgICAgICAgICAgIH0sIGluaXRpYWxWYWx1ZU9yU2VsZWN0b3IpIDpcclxuICAgICAgICAgICAgdGhpcy5tdWx0aWNhc3QobmV3IEJlaGF2aW9yU3ViamVjdChpbml0aWFsVmFsdWVPclNlbGVjdG9yKSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc2hhcmVzIGEgc2luZ2xlIHN1YnNjcmlwdGlvbiB0byB0aGUgdW5kZXJseWluZyBzZXF1ZW5jZSBhbmQgc3RhcnRzIHdpdGggYW4gaW5pdGlhbFZhbHVlLlxyXG4gICAgICogVGhpcyBvcGVyYXRvciBpcyBhIHNwZWNpYWxpemF0aW9uIG9mIHB1Ymxpc2hWYWx1ZSB3aGljaCBjcmVhdGVzIGEgc3Vic2NyaXB0aW9uIHdoZW4gdGhlIG51bWJlciBvZiBvYnNlcnZlcnMgZ29lcyBmcm9tIHplcm8gdG8gb25lLCB0aGVuIHNoYXJlcyB0aGF0IHN1YnNjcmlwdGlvbiB3aXRoIGFsbCBzdWJzZXF1ZW50IG9ic2VydmVycyB1bnRpbCB0aGUgbnVtYmVyIG9mIG9ic2VydmVycyByZXR1cm5zIHRvIHplcm8sIGF0IHdoaWNoIHBvaW50IHRoZSBzdWJzY3JpcHRpb24gaXMgZGlzcG9zZWQuXHJcbiAgICAgKiBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiB2YXIgcmVzID0gc291cmNlLnNoYXJlVmFsdWUoNDIpO1xyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge01peGVkfSBpbml0aWFsVmFsdWUgSW5pdGlhbCB2YWx1ZSByZWNlaXZlZCBieSBvYnNlcnZlcnMgdXBvbiBzdWJzY3JpcHRpb24uXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbnRhaW5zIHRoZSBlbGVtZW50cyBvZiBhIHNlcXVlbmNlIHByb2R1Y2VkIGJ5IG11bHRpY2FzdGluZyB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uc2hhcmVWYWx1ZSA9IGZ1bmN0aW9uIChpbml0aWFsVmFsdWUpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5wdWJsaXNoVmFsdWUoaW5pdGlhbFZhbHVlKS5cclxuICAgICAgICAgICAgcmVmQ291bnQoKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGludm9raW5nIHRoZSBzZWxlY3RvciBvbiBhIGNvbm5lY3RhYmxlIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBzaGFyZXMgYSBzaW5nbGUgc3Vic2NyaXB0aW9uIHRvIHRoZSB1bmRlcmx5aW5nIHNlcXVlbmNlIHJlcGxheWluZyBub3RpZmljYXRpb25zIHN1YmplY3QgdG8gYSBtYXhpbXVtIHRpbWUgbGVuZ3RoIGZvciB0aGUgcmVwbGF5IGJ1ZmZlci5cclxuICAgICAqIFRoaXMgb3BlcmF0b3IgaXMgYSBzcGVjaWFsaXphdGlvbiBvZiBNdWx0aWNhc3QgdXNpbmcgYSBSZXBsYXlTdWJqZWN0LlxyXG4gICAgICogXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5yZXBsYXkobnVsbCwgMyk7XHJcbiAgICAgKiB2YXIgcmVzID0gc291cmNlLnJlcGxheShudWxsLCAzLCA1MDApO1xyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5yZXBsYXkobnVsbCwgMywgNTAwLCBzY2hlZHVsZXIpO1xyXG4gICAgICogdmFyIHJlcyA9IHNvdXJjZS5yZXBsYXkoZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHgudGFrZSg2KS5yZXBlYXQoKTsgfSwgMywgNTAwLCBzY2hlZHVsZXIpO1xyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0gc2VsZWN0b3IgW09wdGlvbmFsXSBTZWxlY3RvciBmdW5jdGlvbiB3aGljaCBjYW4gdXNlIHRoZSBtdWx0aWNhc3RlZCBzb3VyY2Ugc2VxdWVuY2UgYXMgbWFueSB0aW1lcyBhcyBuZWVkZWQsIHdpdGhvdXQgY2F1c2luZyBtdWx0aXBsZSBzdWJzY3JpcHRpb25zIHRvIHRoZSBzb3VyY2Ugc2VxdWVuY2UuIFN1YnNjcmliZXJzIHRvIHRoZSBnaXZlbiBzb3VyY2Ugd2lsbCByZWNlaXZlIGFsbCB0aGUgbm90aWZpY2F0aW9ucyBvZiB0aGUgc291cmNlIHN1YmplY3QgdG8gdGhlIHNwZWNpZmllZCByZXBsYXkgYnVmZmVyIHRyaW1taW5nIHBvbGljeS5cclxuICAgICAqIEBwYXJhbSBidWZmZXJTaXplIFtPcHRpb25hbF0gTWF4aW11bSBlbGVtZW50IGNvdW50IG9mIHRoZSByZXBsYXkgYnVmZmVyLlxyXG4gICAgICogQHBhcmFtIHdpbmRvdyBbT3B0aW9uYWxdIE1heGltdW0gdGltZSBsZW5ndGggb2YgdGhlIHJlcGxheSBidWZmZXIuXHJcbiAgICAgKiBAcGFyYW0gc2NoZWR1bGVyIFtPcHRpb25hbF0gU2NoZWR1bGVyIHdoZXJlIGNvbm5lY3RlZCBvYnNlcnZlcnMgd2l0aGluIHRoZSBzZWxlY3RvciBmdW5jdGlvbiB3aWxsIGJlIGludm9rZWQgb24uXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbnRhaW5zIHRoZSBlbGVtZW50cyBvZiBhIHNlcXVlbmNlIHByb2R1Y2VkIGJ5IG11bHRpY2FzdGluZyB0aGUgc291cmNlIHNlcXVlbmNlIHdpdGhpbiBhIHNlbGVjdG9yIGZ1bmN0aW9uLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8ucmVwbGF5ID0gZnVuY3Rpb24gKHNlbGVjdG9yLCBidWZmZXJTaXplLCB3aW5kb3csIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHJldHVybiAhc2VsZWN0b3IgP1xyXG4gICAgICAgICAgICB0aGlzLm11bHRpY2FzdChuZXcgUmVwbGF5U3ViamVjdChidWZmZXJTaXplLCB3aW5kb3csIHNjaGVkdWxlcikpIDpcclxuICAgICAgICAgICAgdGhpcy5tdWx0aWNhc3QoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZXBsYXlTdWJqZWN0KGJ1ZmZlclNpemUsIHdpbmRvdywgc2NoZWR1bGVyKTtcclxuICAgICAgICAgICAgfSwgc2VsZWN0b3IpO1xyXG4gICAgfTtcclxuXHJcbiAgLyoqXHJcbiAgICogUmV0dXJucyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgc2hhcmVzIGEgc2luZ2xlIHN1YnNjcmlwdGlvbiB0byB0aGUgdW5kZXJseWluZyBzZXF1ZW5jZSByZXBsYXlpbmcgbm90aWZpY2F0aW9ucyBzdWJqZWN0IHRvIGEgbWF4aW11bSB0aW1lIGxlbmd0aCBmb3IgdGhlIHJlcGxheSBidWZmZXIuXHJcbiAgICogVGhpcyBvcGVyYXRvciBpcyBhIHNwZWNpYWxpemF0aW9uIG9mIHJlcGxheSB3aGljaCBjcmVhdGVzIGEgc3Vic2NyaXB0aW9uIHdoZW4gdGhlIG51bWJlciBvZiBvYnNlcnZlcnMgZ29lcyBmcm9tIHplcm8gdG8gb25lLCB0aGVuIHNoYXJlcyB0aGF0IHN1YnNjcmlwdGlvbiB3aXRoIGFsbCBzdWJzZXF1ZW50IG9ic2VydmVycyB1bnRpbCB0aGUgbnVtYmVyIG9mIG9ic2VydmVycyByZXR1cm5zIHRvIHplcm8sIGF0IHdoaWNoIHBvaW50IHRoZSBzdWJzY3JpcHRpb24gaXMgZGlzcG9zZWQuXHJcbiAgICogXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiB2YXIgcmVzID0gc291cmNlLnNoYXJlUmVwbGF5KDMpO1xyXG4gICAqIHZhciByZXMgPSBzb3VyY2Uuc2hhcmVSZXBsYXkoMywgNTAwKTtcclxuICAgKiB2YXIgcmVzID0gc291cmNlLnNoYXJlUmVwbGF5KDMsIDUwMCwgc2NoZWR1bGVyKTtcclxuICAgKiBcclxuXHJcbiAgICogQHBhcmFtIGJ1ZmZlclNpemUgW09wdGlvbmFsXSBNYXhpbXVtIGVsZW1lbnQgY291bnQgb2YgdGhlIHJlcGxheSBidWZmZXIuXHJcbiAgICogQHBhcmFtIHdpbmRvdyBbT3B0aW9uYWxdIE1heGltdW0gdGltZSBsZW5ndGggb2YgdGhlIHJlcGxheSBidWZmZXIuXHJcbiAgICogQHBhcmFtIHNjaGVkdWxlciBbT3B0aW9uYWxdIFNjaGVkdWxlciB3aGVyZSBjb25uZWN0ZWQgb2JzZXJ2ZXJzIHdpdGhpbiB0aGUgc2VsZWN0b3IgZnVuY3Rpb24gd2lsbCBiZSBpbnZva2VkIG9uLlxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgY29udGFpbnMgdGhlIGVsZW1lbnRzIG9mIGEgc2VxdWVuY2UgcHJvZHVjZWQgYnkgbXVsdGljYXN0aW5nIHRoZSBzb3VyY2Ugc2VxdWVuY2UuXHJcbiAgICovXHJcbiAgb2JzZXJ2YWJsZVByb3RvLnNoYXJlUmVwbGF5ID0gZnVuY3Rpb24gKGJ1ZmZlclNpemUsIHdpbmRvdywgc2NoZWR1bGVyKSB7XHJcbiAgICByZXR1cm4gdGhpcy5yZXBsYXkobnVsbCwgYnVmZmVyU2l6ZSwgd2luZG93LCBzY2hlZHVsZXIpLnJlZkNvdW50KCk7XHJcbiAgfTtcclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi9cclxuICAgIHZhciBJbm5lclN1YnNjcmlwdGlvbiA9IGZ1bmN0aW9uIChzdWJqZWN0LCBvYnNlcnZlcikge1xyXG4gICAgICAgIHRoaXMuc3ViamVjdCA9IHN1YmplY3Q7XHJcbiAgICAgICAgdGhpcy5vYnNlcnZlciA9IG9ic2VydmVyO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIEBwcml2YXRlXHJcbiAgICAgKiBAbWVtYmVyT2YgSW5uZXJTdWJzY3JpcHRpb25cclxuICAgICAqL1xyXG4gICAgSW5uZXJTdWJzY3JpcHRpb24ucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnN1YmplY3QuaXNEaXNwb3NlZCAmJiB0aGlzLm9ic2VydmVyICE9PSBudWxsKSB7XHJcbiAgICAgICAgICAgIHZhciBpZHggPSB0aGlzLnN1YmplY3Qub2JzZXJ2ZXJzLmluZGV4T2YodGhpcy5vYnNlcnZlcik7XHJcbiAgICAgICAgICAgIHRoaXMuc3ViamVjdC5vYnNlcnZlcnMuc3BsaWNlKGlkeCwgMSk7XHJcbiAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBudWxsO1xyXG4gICAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgUmVwcmVzZW50cyBhIHZhbHVlIHRoYXQgY2hhbmdlcyBvdmVyIHRpbWUuXHJcbiAgICAgKiAgT2JzZXJ2ZXJzIGNhbiBzdWJzY3JpYmUgdG8gdGhlIHN1YmplY3QgdG8gcmVjZWl2ZSB0aGUgbGFzdCAob3IgaW5pdGlhbCkgdmFsdWUgYW5kIGFsbCBzdWJzZXF1ZW50IG5vdGlmaWNhdGlvbnMuXHJcbiAgICAgKi9cclxuICAgIHZhciBCZWhhdmlvclN1YmplY3QgPSBSeC5CZWhhdmlvclN1YmplY3QgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgIGZ1bmN0aW9uIHN1YnNjcmliZShvYnNlcnZlcikge1xyXG4gICAgICAgICAgICBjaGVja0Rpc3Bvc2VkLmNhbGwodGhpcyk7XHJcbiAgICAgICAgICAgIGlmICghdGhpcy5pc1N0b3BwZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXJzLnB1c2gob2JzZXJ2ZXIpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHRoaXMudmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBJbm5lclN1YnNjcmlwdGlvbih0aGlzLCBvYnNlcnZlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgdmFyIGV4ID0gdGhpcy5leGNlcHRpb247XHJcbiAgICAgICAgICAgIGlmIChleCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBkaXNwb3NhYmxlRW1wdHk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpbmhlcml0cyhCZWhhdmlvclN1YmplY3QsIF9zdXBlcik7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAqICBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgQmVoYXZpb3JTdWJqZWN0IGNsYXNzIHdoaWNoIGNyZWF0ZXMgYSBzdWJqZWN0IHRoYXQgY2FjaGVzIGl0cyBsYXN0IHZhbHVlIGFuZCBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkIHZhbHVlLlxyXG4gICAgICAgICAqICBAcGFyYW0ge01peGVkfSB2YWx1ZSBJbml0aWFsIHZhbHVlIHNlbnQgdG8gb2JzZXJ2ZXJzIHdoZW4gbm8gb3RoZXIgdmFsdWUgaGFzIGJlZW4gcmVjZWl2ZWQgYnkgdGhlIHN1YmplY3QgeWV0LlxyXG4gICAgICAgICAqLyAgICAgICBcclxuICAgICAgICBmdW5jdGlvbiBCZWhhdmlvclN1YmplY3QodmFsdWUpIHtcclxuICAgICAgICAgICAgX3N1cGVyLmNhbGwodGhpcywgc3Vic2NyaWJlKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZSxcclxuICAgICAgICAgICAgdGhpcy5vYnNlcnZlcnMgPSBbXSxcclxuICAgICAgICAgICAgdGhpcy5pc0Rpc3Bvc2VkID0gZmFsc2UsXHJcbiAgICAgICAgICAgIHRoaXMuaXNTdG9wcGVkID0gZmFsc2UsXHJcbiAgICAgICAgICAgIHRoaXMuZXhjZXB0aW9uID0gbnVsbDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFkZFByb3BlcnRpZXMoQmVoYXZpb3JTdWJqZWN0LnByb3RvdHlwZSwgT2JzZXJ2ZXIsIHtcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIEluZGljYXRlcyB3aGV0aGVyIHRoZSBzdWJqZWN0IGhhcyBvYnNlcnZlcnMgc3Vic2NyaWJlZCB0byBpdC5cclxuICAgICAgICAgICAgICogQHJldHVybnMge0Jvb2xlYW59IEluZGljYXRlcyB3aGV0aGVyIHRoZSBzdWJqZWN0IGhhcyBvYnNlcnZlcnMgc3Vic2NyaWJlZCB0byBpdC5cclxuICAgICAgICAgICAgICovICAgICAgICAgXHJcbiAgICAgICAgICAgIGhhc09ic2VydmVyczogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHRoaXMub2JzZXJ2ZXJzLmxlbmd0aCA+IDA7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBOb3RpZmllcyBhbGwgc3Vic2NyaWJlZCBvYnNlcnZlcnMgYWJvdXQgdGhlIGVuZCBvZiB0aGUgc2VxdWVuY2UuXHJcbiAgICAgICAgICAgICAqLyBcclxuICAgICAgICAgICAgb25Db21wbGV0ZWQ6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGNoZWNrRGlzcG9zZWQuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc1N0b3BwZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb3MgPSB0aGlzLm9ic2VydmVycy5zbGljZSgwKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmlzU3RvcHBlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IG9zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9zW2ldLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVycyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTm90aWZpZXMgYWxsIHN1YnNjcmliZWQgb2JzZXJ2ZXJzIGFib3V0IHRoZSBleGNlcHRpb24uXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB7TWl4ZWR9IGVycm9yIFRoZSBleGNlcHRpb24gdG8gc2VuZCB0byBhbGwgb2JzZXJ2ZXJzLlxyXG4gICAgICAgICAgICAgKi8gICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIG9uRXJyb3I6IGZ1bmN0aW9uIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgY2hlY2tEaXNwb3NlZC5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzU3RvcHBlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvcyA9IHRoaXMub2JzZXJ2ZXJzLnNsaWNlKDApO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNTdG9wcGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IGVycm9yO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gb3MubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3NbaV0ub25FcnJvcihlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVycyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTm90aWZpZXMgYWxsIHN1YnNjcmliZWQgb2JzZXJ2ZXJzIGFib3V0IHRoZSBhcnJpdmFsIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbiB0aGUgc2VxdWVuY2UuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZW5kIHRvIGFsbCBvYnNlcnZlcnMuXHJcbiAgICAgICAgICAgICAqLyAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIG9uTmV4dDogZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICBjaGVja0Rpc3Bvc2VkLmNhbGwodGhpcyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNTdG9wcGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvcyA9IHRoaXMub2JzZXJ2ZXJzLnNsaWNlKDApO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvc1tpXS5vbk5leHQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIFVuc3Vic2NyaWJlIGFsbCBvYnNlcnZlcnMgYW5kIHJlbGVhc2UgcmVzb3VyY2VzLlxyXG4gICAgICAgICAgICAgKi8gICAgICAgICAgICBcclxuICAgICAgICAgICAgZGlzcG9zZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0Rpc3Bvc2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXJzID0gbnVsbDtcclxuICAgICAgICAgICAgICAgIHRoaXMudmFsdWUgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5leGNlcHRpb24gPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBCZWhhdmlvclN1YmplY3Q7XHJcbiAgICB9KE9ic2VydmFibGUpKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJlcHJlc2VudHMgYW4gb2JqZWN0IHRoYXQgaXMgYm90aCBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGFzIHdlbGwgYXMgYW4gb2JzZXJ2ZXIuXHJcbiAgICAgKiBFYWNoIG5vdGlmaWNhdGlvbiBpcyBicm9hZGNhc3RlZCB0byBhbGwgc3Vic2NyaWJlZCBhbmQgZnV0dXJlIG9ic2VydmVycywgc3ViamVjdCB0byBidWZmZXIgdHJpbW1pbmcgcG9saWNpZXMuXHJcbiAgICAgKi8gIFxyXG4gICAgdmFyIFJlcGxheVN1YmplY3QgPSBSeC5SZXBsYXlTdWJqZWN0ID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gUmVtb3ZhYmxlRGlzcG9zYWJsZSAoc3ViamVjdCwgb2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5zdWJqZWN0ID0gc3ViamVjdDtcclxuICAgICAgICAgICAgdGhpcy5vYnNlcnZlciA9IG9ic2VydmVyO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIFJlbW92YWJsZURpc3Bvc2FibGUucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXIuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuc3ViamVjdC5pc0Rpc3Bvc2VkKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgaWR4ID0gdGhpcy5zdWJqZWN0Lm9ic2VydmVycy5pbmRleE9mKHRoaXMub2JzZXJ2ZXIpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zdWJqZWN0Lm9ic2VydmVycy5zcGxpY2UoaWR4LCAxKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHN1YnNjcmliZShvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgc28gPSBuZXcgU2NoZWR1bGVkT2JzZXJ2ZXIodGhpcy5zY2hlZHVsZXIsIG9ic2VydmVyKSxcclxuICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbiA9IG5ldyBSZW1vdmFibGVEaXNwb3NhYmxlKHRoaXMsIHNvKTtcclxuICAgICAgICAgICAgY2hlY2tEaXNwb3NlZC5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLl90cmltKHRoaXMuc2NoZWR1bGVyLm5vdygpKTtcclxuICAgICAgICAgICAgdGhpcy5vYnNlcnZlcnMucHVzaChzbyk7XHJcblxyXG4gICAgICAgICAgICB2YXIgbiA9IHRoaXMucS5sZW5ndGg7XHJcblxyXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gdGhpcy5xLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBzby5vbk5leHQodGhpcy5xW2ldLnZhbHVlKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHRoaXMuaGFzRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIG4rKztcclxuICAgICAgICAgICAgICAgIHNvLm9uRXJyb3IodGhpcy5lcnJvcik7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAodGhpcy5pc1N0b3BwZWQpIHtcclxuICAgICAgICAgICAgICAgIG4rKztcclxuICAgICAgICAgICAgICAgIHNvLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHNvLmVuc3VyZUFjdGl2ZShuKTtcclxuICAgICAgICAgICAgcmV0dXJuIHN1YnNjcmlwdGlvbjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGluaGVyaXRzKFJlcGxheVN1YmplY3QsIF9zdXBlcik7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqICBJbml0aWFsaXplcyBhIG5ldyBpbnN0YW5jZSBvZiB0aGUgUmVwbGF5U3ViamVjdCBjbGFzcyB3aXRoIHRoZSBzcGVjaWZpZWQgYnVmZmVyIHNpemUsIHdpbmRvdyBzaXplIGFuZCBzY2hlZHVsZXIuXHJcbiAgICAgICAgICogIEBwYXJhbSB7TnVtYmVyfSBbYnVmZmVyU2l6ZV0gTWF4aW11bSBlbGVtZW50IGNvdW50IG9mIHRoZSByZXBsYXkgYnVmZmVyLlxyXG4gICAgICAgICAqICBAcGFyYW0ge051bWJlcn0gW3dpbmRvd1NpemVdIE1heGltdW0gdGltZSBsZW5ndGggb2YgdGhlIHJlcGxheSBidWZmZXIuXHJcbiAgICAgICAgICogIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSBTY2hlZHVsZXIgdGhlIG9ic2VydmVycyBhcmUgaW52b2tlZCBvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbiBSZXBsYXlTdWJqZWN0KGJ1ZmZlclNpemUsIHdpbmRvd1NpemUsIHNjaGVkdWxlcikge1xyXG4gICAgICAgICAgICB0aGlzLmJ1ZmZlclNpemUgPSBidWZmZXJTaXplID09IG51bGwgPyBOdW1iZXIuTUFYX1ZBTFVFIDogYnVmZmVyU2l6ZTtcclxuICAgICAgICAgICAgdGhpcy53aW5kb3dTaXplID0gd2luZG93U2l6ZSA9PSBudWxsID8gTnVtYmVyLk1BWF9WQUxVRSA6IHdpbmRvd1NpemU7XHJcbiAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVyID0gc2NoZWR1bGVyIHx8IGN1cnJlbnRUaHJlYWRTY2hlZHVsZXI7XHJcbiAgICAgICAgICAgIHRoaXMucSA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLm9ic2VydmVycyA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLmlzU3RvcHBlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmlzRGlzcG9zZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5oYXNFcnJvciA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLmVycm9yID0gbnVsbDtcclxuICAgICAgICAgICAgX3N1cGVyLmNhbGwodGhpcywgc3Vic2NyaWJlKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFkZFByb3BlcnRpZXMoUmVwbGF5U3ViamVjdC5wcm90b3R5cGUsIE9ic2VydmVyLCB7XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3ViamVjdCBoYXMgb2JzZXJ2ZXJzIHN1YnNjcmliZWQgdG8gaXQuXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtCb29sZWFufSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3ViamVjdCBoYXMgb2JzZXJ2ZXJzIHN1YnNjcmliZWQgdG8gaXQuXHJcbiAgICAgICAgICAgICAqLyAgICAgICAgIFxyXG4gICAgICAgICAgICBoYXNPYnNlcnZlcnM6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9ic2VydmVycy5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICB9LCAgICAgICAgICAgIFxyXG4gICAgICAgICAgICAvKiBAcHJpdmF0ZSAgKi9cclxuICAgICAgICAgICAgX3RyaW06IGZ1bmN0aW9uIChub3cpIHtcclxuICAgICAgICAgICAgICAgIHdoaWxlICh0aGlzLnEubGVuZ3RoID4gdGhpcy5idWZmZXJTaXplKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5xLnNoaWZ0KCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAodGhpcy5xLmxlbmd0aCA+IDAgJiYgKG5vdyAtIHRoaXMucVswXS5pbnRlcnZhbCkgPiB0aGlzLndpbmRvd1NpemUpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnEuc2hpZnQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIE5vdGlmaWVzIGFsbCBzdWJzY3JpYmVkIG9ic2VydmVycyBhYm91dCB0aGUgYXJyaXZhbCBvZiB0aGUgc3BlY2lmaWVkIGVsZW1lbnQgaW4gdGhlIHNlcXVlbmNlLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2VuZCB0byBhbGwgb2JzZXJ2ZXJzLlxyXG4gICAgICAgICAgICAgKi8gICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBvbk5leHQ6IGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG9ic2VydmVyO1xyXG4gICAgICAgICAgICAgICAgY2hlY2tEaXNwb3NlZC5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzU3RvcHBlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLnNjaGVkdWxlci5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnEucHVzaCh7IGludGVydmFsOiBub3csIHZhbHVlOiB2YWx1ZSB9KTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmltKG5vdyk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvID0gdGhpcy5vYnNlcnZlcnMuc2xpY2UoMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IG8ubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIgPSBvW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5lbnN1cmVBY3RpdmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBOb3RpZmllcyBhbGwgc3Vic2NyaWJlZCBvYnNlcnZlcnMgYWJvdXQgdGhlIGV4Y2VwdGlvbi5cclxuICAgICAgICAgICAgICogQHBhcmFtIHtNaXhlZH0gZXJyb3IgVGhlIGV4Y2VwdGlvbiB0byBzZW5kIHRvIGFsbCBvYnNlcnZlcnMuXHJcbiAgICAgICAgICAgICAqLyAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIG9uRXJyb3I6IGZ1bmN0aW9uIChlcnJvcikge1xyXG4gICAgICAgICAgICAgICAgdmFyIG9ic2VydmVyO1xyXG4gICAgICAgICAgICAgICAgY2hlY2tEaXNwb3NlZC5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzU3RvcHBlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNTdG9wcGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9yID0gZXJyb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYXNFcnJvciA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG5vdyA9IHRoaXMuc2NoZWR1bGVyLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX3RyaW0obm93KTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbyA9IHRoaXMub2JzZXJ2ZXJzLnNsaWNlKDApO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyID0gb1tpXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlcnJvcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmVuc3VyZUFjdGl2ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVycyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTm90aWZpZXMgYWxsIHN1YnNjcmliZWQgb2JzZXJ2ZXJzIGFib3V0IHRoZSBlbmQgb2YgdGhlIHNlcXVlbmNlLlxyXG4gICAgICAgICAgICAgKi8gICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIG9uQ29tcGxldGVkOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgb2JzZXJ2ZXI7XHJcbiAgICAgICAgICAgICAgICBjaGVja0Rpc3Bvc2VkLmNhbGwodGhpcyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNTdG9wcGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc1N0b3BwZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBub3cgPSB0aGlzLnNjaGVkdWxlci5ub3coKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLl90cmltKG5vdyk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG8gPSB0aGlzLm9ic2VydmVycy5zbGljZSgwKTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gby5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlciA9IG9baV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLmVuc3VyZUFjdGl2ZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVycyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVW5zdWJzY3JpYmUgYWxsIG9ic2VydmVycyBhbmQgcmVsZWFzZSByZXNvdXJjZXMuXHJcbiAgICAgICAgICAgICAqLyAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBkaXNwb3NlOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzRGlzcG9zZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vYnNlcnZlcnMgPSBudWxsO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIHJldHVybiBSZXBsYXlTdWJqZWN0O1xyXG4gICAgfShPYnNlcnZhYmxlKSk7XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICB2YXIgQ29ubmVjdGFibGVPYnNlcnZhYmxlID0gUnguQ29ubmVjdGFibGVPYnNlcnZhYmxlID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgICAgICBpbmhlcml0cyhDb25uZWN0YWJsZU9ic2VydmFibGUsIF9zdXBlcik7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZnVuY3Rpb24gQ29ubmVjdGFibGVPYnNlcnZhYmxlKHNvdXJjZSwgc3ViamVjdCkge1xyXG4gICAgICAgICAgICB2YXIgc3RhdGUgPSB7XHJcbiAgICAgICAgICAgICAgICBzdWJqZWN0OiBzdWJqZWN0LFxyXG4gICAgICAgICAgICAgICAgc291cmNlOiBzb3VyY2UuYXNPYnNlcnZhYmxlKCksXHJcbiAgICAgICAgICAgICAgICBoYXNTdWJzY3JpcHRpb246IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uOiBudWxsXHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICB0aGlzLmNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXN0YXRlLmhhc1N1YnNjcmlwdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIHN0YXRlLmhhc1N1YnNjcmlwdGlvbiA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhdGUuc3Vic2NyaXB0aW9uID0gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc3RhdGUuc291cmNlLnN1YnNjcmliZShzdGF0ZS5zdWJqZWN0KSwgZGlzcG9zYWJsZUNyZWF0ZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlLmhhc1N1YnNjcmlwdGlvbiA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBzdGF0ZS5zdWJzY3JpcHRpb247XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBzdWJzY3JpYmUob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBzdGF0ZS5zdWJqZWN0LnN1YnNjcmliZShvYnNlcnZlcik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMsIHN1YnNjcmliZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqIEBtZW1iZXJPZiBDb25uZWN0YWJsZU9ic2VydmFibGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBDb25uZWN0YWJsZU9ic2VydmFibGUucHJvdG90eXBlLmNvbm5lY3QgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLmNvbm5lY3QoKTsgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKiBAbWVtYmVyT2YgQ29ubmVjdGFibGVPYnNlcnZhYmxlXHJcbiAgICAgICAgICovICAgICAgICBcclxuICAgICAgICBDb25uZWN0YWJsZU9ic2VydmFibGUucHJvdG90eXBlLnJlZkNvdW50ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgY29ubmVjdGFibGVTdWJzY3JpcHRpb24gPSBudWxsLCBjb3VudCA9IDAsIHNvdXJjZSA9IHRoaXM7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgICAgIHZhciBzaG91bGRDb25uZWN0LCBzdWJzY3JpcHRpb247XHJcbiAgICAgICAgICAgICAgICBjb3VudCsrO1xyXG4gICAgICAgICAgICAgICAgc2hvdWxkQ29ubmVjdCA9IGNvdW50ID09PSAxO1xyXG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uID0gc291cmNlLnN1YnNjcmliZShvYnNlcnZlcik7XHJcbiAgICAgICAgICAgICAgICBpZiAoc2hvdWxkQ29ubmVjdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbm5lY3RhYmxlU3Vic2NyaXB0aW9uID0gc291cmNlLmNvbm5lY3QoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiBkaXNwb3NhYmxlQ3JlYXRlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24uZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvdW50LS07XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbm5lY3RhYmxlU3Vic2NyaXB0aW9uLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgcmV0dXJuIENvbm5lY3RhYmxlT2JzZXJ2YWJsZTtcclxuICAgIH0oT2JzZXJ2YWJsZSkpO1xyXG5cclxuICAgIC8vIFJlYWwgRGljdGlvbmFyeVxyXG4gICAgdmFyIHByaW1lcyA9IFsxLCAzLCA3LCAxMywgMzEsIDYxLCAxMjcsIDI1MSwgNTA5LCAxMDIxLCAyMDM5LCA0MDkzLCA4MTkxLCAxNjM4MSwgMzI3NDksIDY1NTIxLCAxMzEwNzEsIDI2MjEzOSwgNTI0Mjg3LCAxMDQ4NTczLCAyMDk3MTQzLCA0MTk0MzAxLCA4Mzg4NTkzLCAxNjc3NzIxMywgMzM1NTQzOTMsIDY3MTA4ODU5LCAxMzQyMTc2ODksIDI2ODQzNTM5OSwgNTM2ODcwOTA5LCAxMDczNzQxNzg5LCAyMTQ3NDgzNjQ3XTtcclxuICAgIHZhciBub1N1Y2hrZXkgPSBcIm5vIHN1Y2gga2V5XCI7XHJcbiAgICB2YXIgZHVwbGljYXRla2V5ID0gXCJkdXBsaWNhdGUga2V5XCI7XHJcblxyXG4gICAgZnVuY3Rpb24gaXNQcmltZShjYW5kaWRhdGUpIHtcclxuICAgICAgICBpZiAoY2FuZGlkYXRlICYgMSA9PT0gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gY2FuZGlkYXRlID09PSAyO1xyXG4gICAgICAgIH1cclxuICAgICAgICB2YXIgbnVtMSA9IE1hdGguc3FydChjYW5kaWRhdGUpLFxyXG4gICAgICAgICAgICBudW0yID0gMztcclxuICAgICAgICB3aGlsZSAobnVtMiA8PSBudW0xKSB7XHJcbiAgICAgICAgICAgIGlmIChjYW5kaWRhdGUgJSBudW0yID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgbnVtMiArPSAyO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBnZXRQcmltZShtaW4pIHtcclxuICAgICAgICB2YXIgaW5kZXgsIG51bSwgY2FuZGlkYXRlO1xyXG4gICAgICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IHByaW1lcy5sZW5ndGg7ICsraW5kZXgpIHtcclxuICAgICAgICAgICAgbnVtID0gcHJpbWVzW2luZGV4XTtcclxuICAgICAgICAgICAgaWYgKG51bSA+PSBtaW4pIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBudW07XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY2FuZGlkYXRlID0gbWluIHwgMTtcclxuICAgICAgICB3aGlsZSAoY2FuZGlkYXRlIDwgcHJpbWVzW3ByaW1lcy5sZW5ndGggLSAxXSkge1xyXG4gICAgICAgICAgICBpZiAoaXNQcmltZShjYW5kaWRhdGUpKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY2FuZGlkYXRlO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGNhbmRpZGF0ZSArPSAyO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbWluO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIHN0cmluZ0hhc2hGbihzdHIpIHtcclxuICAgICAgICB2YXIgaGFzaCA9IDc1NzYwMjA0NjtcclxuICAgICAgICBpZiAoIXN0ci5sZW5ndGgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGhhc2g7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBzdHIubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgdmFyIGNoYXJhY3RlciA9IHN0ci5jaGFyQ29kZUF0KGkpO1xyXG4gICAgICAgICAgICBoYXNoID0gKChoYXNoPDw1KS1oYXNoKStjaGFyYWN0ZXI7XHJcbiAgICAgICAgICAgIGhhc2ggPSBoYXNoICYgaGFzaDtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIGhhc2g7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gbnVtYmVySGFzaEZuKGtleSkge1xyXG4gICAgICAgIHZhciBjMiA9IDB4MjdkNGViMmQ7IFxyXG4gICAgICAgIGtleSA9IChrZXkgXiA2MSkgXiAoa2V5ID4+PiAxNik7XHJcbiAgICAgICAga2V5ID0ga2V5ICsgKGtleSA8PCAzKTtcclxuICAgICAgICBrZXkgPSBrZXkgXiAoa2V5ID4+PiA0KTtcclxuICAgICAgICBrZXkgPSBrZXkgKiBjMjtcclxuICAgICAgICBrZXkgPSBrZXkgXiAoa2V5ID4+PiAxNSk7XHJcbiAgICAgICAgcmV0dXJuIGtleTtcclxuICAgIH1cclxuXHJcbiAgICB2YXIgZ2V0SGFzaENvZGUgPSAoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciB1bmlxdWVJZENvdW50ZXIgPSAwO1xyXG5cclxuICAgICAgICByZXR1cm4gZnVuY3Rpb24gKG9iaikge1xyXG4gICAgICAgICAgICBpZiAob2JqID09IG51bGwpIHsgXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3Iobm9TdWNoa2V5KTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gQ2hlY2sgZm9yIGJ1aWx0LWlucyBiZWZvcmUgdGFja2luZyBvbiBvdXIgb3duIGZvciBhbnkgb2JqZWN0XHJcbiAgICAgICAgICAgIGlmICh0eXBlb2Ygb2JqID09PSAnc3RyaW5nJykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHN0cmluZ0hhc2hGbihvYmopO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAodHlwZW9mIG9iaiA9PT0gJ251bWJlcicpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBudW1iZXJIYXNoRm4ob2JqKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKHR5cGVvZiBvYmogPT09ICdib29sZWFuJykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iaiA9PT0gdHJ1ZSA/IDEgOiAwO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBpZiAob2JqIGluc3RhbmNlb2YgRGF0ZSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG9iai5nZXRUaW1lKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChvYmouZ2V0SGFzaENvZGUpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBvYmouZ2V0SGFzaENvZGUoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdmFyIGlkID0gMTcgKiB1bmlxdWVJZENvdW50ZXIrKztcclxuICAgICAgICAgICAgb2JqLmdldEhhc2hDb2RlID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gaWQ7IH07XHJcbiAgICAgICAgICAgIHJldHVybiBpZDtcclxuICAgICAgICB9O1xyXG4gICAgfSAoKSk7XHJcblxyXG4gICAgZnVuY3Rpb24gbmV3RW50cnkoKSB7XHJcbiAgICAgICAgcmV0dXJuIHsga2V5OiBudWxsLCB2YWx1ZTogbnVsbCwgbmV4dDogMCwgaGFzaENvZGU6IDAgfTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBEaWN0aW9uYXJ5IGltcGxlbWVudGF0aW9uXHJcblxyXG4gICAgdmFyIERpY3Rpb25hcnkgPSBmdW5jdGlvbiAoY2FwYWNpdHksIGNvbXBhcmVyKSB7XHJcbiAgICAgICAgaWYgKGNhcGFjaXR5IDwgMCkge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ291dCBvZiByYW5nZScpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChjYXBhY2l0eSA+IDApIHtcclxuICAgICAgICAgICAgdGhpcy5faW5pdGlhbGl6ZShjYXBhY2l0eSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIFxyXG4gICAgICAgIHRoaXMuY29tcGFyZXIgPSBjb21wYXJlciB8fCBkZWZhdWx0Q29tcGFyZXI7XHJcbiAgICAgICAgdGhpcy5mcmVlQ291bnQgPSAwO1xyXG4gICAgICAgIHRoaXMuc2l6ZSA9IDA7XHJcbiAgICAgICAgdGhpcy5mcmVlTGlzdCA9IC0xO1xyXG4gICAgfTtcclxuXHJcbiAgICBEaWN0aW9uYXJ5LnByb3RvdHlwZS5faW5pdGlhbGl6ZSA9IGZ1bmN0aW9uIChjYXBhY2l0eSkge1xyXG4gICAgICAgIHZhciBwcmltZSA9IGdldFByaW1lKGNhcGFjaXR5KSwgaTtcclxuICAgICAgICB0aGlzLmJ1Y2tldHMgPSBuZXcgQXJyYXkocHJpbWUpO1xyXG4gICAgICAgIHRoaXMuZW50cmllcyA9IG5ldyBBcnJheShwcmltZSk7XHJcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IHByaW1lOyBpKyspIHtcclxuICAgICAgICAgICAgdGhpcy5idWNrZXRzW2ldID0gLTE7XHJcbiAgICAgICAgICAgIHRoaXMuZW50cmllc1tpXSA9IG5ld0VudHJ5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZnJlZUxpc3QgPSAtMTtcclxuICAgIH07XHJcbiAgICBEaWN0aW9uYXJ5LnByb3RvdHlwZS5jb3VudCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy5zaXplO1xyXG4gICAgfTtcclxuICAgIERpY3Rpb25hcnkucHJvdG90eXBlLmFkZCA9IGZ1bmN0aW9uIChrZXksIHZhbHVlKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuX2luc2VydChrZXksIHZhbHVlLCB0cnVlKTtcclxuICAgIH07XHJcbiAgICBEaWN0aW9uYXJ5LnByb3RvdHlwZS5faW5zZXJ0ID0gZnVuY3Rpb24gKGtleSwgdmFsdWUsIGFkZCkge1xyXG4gICAgICAgIGlmICghdGhpcy5idWNrZXRzKSB7XHJcbiAgICAgICAgICAgIHRoaXMuX2luaXRpYWxpemUoMCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBpbmRleDM7XHJcbiAgICAgICAgdmFyIG51bSA9IGdldEhhc2hDb2RlKGtleSkgJiAyMTQ3NDgzNjQ3O1xyXG4gICAgICAgIHZhciBpbmRleDEgPSBudW0gJSB0aGlzLmJ1Y2tldHMubGVuZ3RoO1xyXG4gICAgICAgIGZvciAodmFyIGluZGV4MiA9IHRoaXMuYnVja2V0c1tpbmRleDFdOyBpbmRleDIgPj0gMDsgaW5kZXgyID0gdGhpcy5lbnRyaWVzW2luZGV4Ml0ubmV4dCkge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5lbnRyaWVzW2luZGV4Ml0uaGFzaENvZGUgPT09IG51bSAmJiB0aGlzLmNvbXBhcmVyKHRoaXMuZW50cmllc1tpbmRleDJdLmtleSwga2V5KSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKGFkZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihkdXBsaWNhdGVrZXkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdGhpcy5lbnRyaWVzW2luZGV4Ml0udmFsdWUgPSB2YWx1ZTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodGhpcy5mcmVlQ291bnQgPiAwKSB7XHJcbiAgICAgICAgICAgIGluZGV4MyA9IHRoaXMuZnJlZUxpc3Q7XHJcbiAgICAgICAgICAgIHRoaXMuZnJlZUxpc3QgPSB0aGlzLmVudHJpZXNbaW5kZXgzXS5uZXh0O1xyXG4gICAgICAgICAgICAtLXRoaXMuZnJlZUNvdW50O1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnNpemUgPT09IHRoaXMuZW50cmllcy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuX3Jlc2l6ZSgpO1xyXG4gICAgICAgICAgICAgICAgaW5kZXgxID0gbnVtICUgdGhpcy5idWNrZXRzLmxlbmd0aDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpbmRleDMgPSB0aGlzLnNpemU7XHJcbiAgICAgICAgICAgICsrdGhpcy5zaXplO1xyXG4gICAgICAgIH1cclxuICAgICAgICB0aGlzLmVudHJpZXNbaW5kZXgzXS5oYXNoQ29kZSA9IG51bTtcclxuICAgICAgICB0aGlzLmVudHJpZXNbaW5kZXgzXS5uZXh0ID0gdGhpcy5idWNrZXRzW2luZGV4MV07XHJcbiAgICAgICAgdGhpcy5lbnRyaWVzW2luZGV4M10ua2V5ID0ga2V5O1xyXG4gICAgICAgIHRoaXMuZW50cmllc1tpbmRleDNdLnZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgdGhpcy5idWNrZXRzW2luZGV4MV0gPSBpbmRleDM7XHJcbiAgICB9O1xyXG5cclxuICAgIERpY3Rpb25hcnkucHJvdG90eXBlLl9yZXNpemUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIHByaW1lID0gZ2V0UHJpbWUodGhpcy5zaXplICogMiksXHJcbiAgICAgICAgICAgIG51bUFycmF5ID0gbmV3IEFycmF5KHByaW1lKTtcclxuICAgICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCBudW1BcnJheS5sZW5ndGg7ICsraW5kZXgpIHtcclxuICAgICAgICAgICAgbnVtQXJyYXlbaW5kZXhdID0gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBlbnRyeUFycmF5ID0gbmV3IEFycmF5KHByaW1lKTtcclxuICAgICAgICBmb3IgKGluZGV4ID0gMDsgaW5kZXggPCB0aGlzLnNpemU7ICsraW5kZXgpIHtcclxuICAgICAgICAgICAgZW50cnlBcnJheVtpbmRleF0gPSB0aGlzLmVudHJpZXNbaW5kZXhdO1xyXG4gICAgICAgIH1cclxuICAgICAgICBmb3IgKHZhciBpbmRleCA9IHRoaXMuc2l6ZTsgaW5kZXggPCBwcmltZTsgKytpbmRleCkge1xyXG4gICAgICAgICAgICBlbnRyeUFycmF5W2luZGV4XSA9IG5ld0VudHJ5KCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAodmFyIGluZGV4MSA9IDA7IGluZGV4MSA8IHRoaXMuc2l6ZTsgKytpbmRleDEpIHtcclxuICAgICAgICAgICAgdmFyIGluZGV4MiA9IGVudHJ5QXJyYXlbaW5kZXgxXS5oYXNoQ29kZSAlIHByaW1lO1xyXG4gICAgICAgICAgICBlbnRyeUFycmF5W2luZGV4MV0ubmV4dCA9IG51bUFycmF5W2luZGV4Ml07XHJcbiAgICAgICAgICAgIG51bUFycmF5W2luZGV4Ml0gPSBpbmRleDE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuYnVja2V0cyA9IG51bUFycmF5O1xyXG4gICAgICAgIHRoaXMuZW50cmllcyA9IGVudHJ5QXJyYXk7XHJcbiAgICB9O1xyXG5cclxuICAgIERpY3Rpb25hcnkucHJvdG90eXBlLnJlbW92ZSA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICBpZiAodGhpcy5idWNrZXRzKSB7XHJcbiAgICAgICAgICAgIHZhciBudW0gPSBnZXRIYXNoQ29kZShrZXkpICYgMjE0NzQ4MzY0NztcclxuICAgICAgICAgICAgdmFyIGluZGV4MSA9IG51bSAlIHRoaXMuYnVja2V0cy5sZW5ndGg7XHJcbiAgICAgICAgICAgIHZhciBpbmRleDIgPSAtMTtcclxuICAgICAgICAgICAgZm9yICh2YXIgaW5kZXgzID0gdGhpcy5idWNrZXRzW2luZGV4MV07IGluZGV4MyA+PSAwOyBpbmRleDMgPSB0aGlzLmVudHJpZXNbaW5kZXgzXS5uZXh0KSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5lbnRyaWVzW2luZGV4M10uaGFzaENvZGUgPT09IG51bSAmJiB0aGlzLmNvbXBhcmVyKHRoaXMuZW50cmllc1tpbmRleDNdLmtleSwga2V5KSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpbmRleDIgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuYnVja2V0c1tpbmRleDFdID0gdGhpcy5lbnRyaWVzW2luZGV4M10ubmV4dDtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVudHJpZXNbaW5kZXgyXS5uZXh0ID0gdGhpcy5lbnRyaWVzW2luZGV4M10ubmV4dDtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5lbnRyaWVzW2luZGV4M10uaGFzaENvZGUgPSAtMTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVudHJpZXNbaW5kZXgzXS5uZXh0ID0gdGhpcy5mcmVlTGlzdDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmVudHJpZXNbaW5kZXgzXS5rZXkgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZW50cmllc1tpbmRleDNdLnZhbHVlID0gbnVsbDtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmZyZWVMaXN0ID0gaW5kZXgzO1xyXG4gICAgICAgICAgICAgICAgICAgICsrdGhpcy5mcmVlQ291bnQ7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGluZGV4MiA9IGluZGV4MztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9O1xyXG5cclxuICAgIERpY3Rpb25hcnkucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBpbmRleCwgbGVuO1xyXG4gICAgICAgIGlmICh0aGlzLnNpemUgPD0gMCkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAoaW5kZXggPSAwLCBsZW4gPSB0aGlzLmJ1Y2tldHMubGVuZ3RoOyBpbmRleCA8IGxlbjsgKytpbmRleCkge1xyXG4gICAgICAgICAgICB0aGlzLmJ1Y2tldHNbaW5kZXhdID0gLTE7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGZvciAoaW5kZXggPSAwOyBpbmRleCA8IHRoaXMuc2l6ZTsgKytpbmRleCkge1xyXG4gICAgICAgICAgICB0aGlzLmVudHJpZXNbaW5kZXhdID0gbmV3RW50cnkoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgdGhpcy5mcmVlTGlzdCA9IC0xO1xyXG4gICAgICAgIHRoaXMuc2l6ZSA9IDA7XHJcbiAgICB9O1xyXG5cclxuICAgIERpY3Rpb25hcnkucHJvdG90eXBlLl9maW5kRW50cnkgPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgaWYgKHRoaXMuYnVja2V0cykge1xyXG4gICAgICAgICAgICB2YXIgbnVtID0gZ2V0SGFzaENvZGUoa2V5KSAmIDIxNDc0ODM2NDc7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGluZGV4ID0gdGhpcy5idWNrZXRzW251bSAlIHRoaXMuYnVja2V0cy5sZW5ndGhdOyBpbmRleCA+PSAwOyBpbmRleCA9IHRoaXMuZW50cmllc1tpbmRleF0ubmV4dCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuZW50cmllc1tpbmRleF0uaGFzaENvZGUgPT09IG51bSAmJiB0aGlzLmNvbXBhcmVyKHRoaXMuZW50cmllc1tpbmRleF0ua2V5LCBrZXkpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGluZGV4O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiAtMTtcclxuICAgIH07XHJcblxyXG4gICAgRGljdGlvbmFyeS5wcm90b3R5cGUuY291bnQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuc2l6ZSAtIHRoaXMuZnJlZUNvdW50O1xyXG4gICAgfTtcclxuXHJcbiAgICBEaWN0aW9uYXJ5LnByb3RvdHlwZS50cnlHZXRWYWx1ZSA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICB2YXIgZW50cnkgPSB0aGlzLl9maW5kRW50cnkoa2V5KTtcclxuICAgICAgICBpZiAoZW50cnkgPj0gMCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5lbnRyaWVzW2VudHJ5XS52YWx1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgIH07XHJcblxyXG4gICAgRGljdGlvbmFyeS5wcm90b3R5cGUuZ2V0VmFsdWVzID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBpbmRleCA9IDAsIHJlc3VsdHMgPSBbXTtcclxuICAgICAgICBpZiAodGhpcy5lbnRyaWVzKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGluZGV4MSA9IDA7IGluZGV4MSA8IHRoaXMuc2l6ZTsgaW5kZXgxKyspIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmVudHJpZXNbaW5kZXgxXS5oYXNoQ29kZSA+PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmVzdWx0c1tpbmRleCsrXSA9IHRoaXMuZW50cmllc1tpbmRleDFdLnZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiByZXN1bHRzO1xyXG4gICAgfTtcclxuXHJcbiAgICBEaWN0aW9uYXJ5LnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgdmFyIGVudHJ5ID0gdGhpcy5fZmluZEVudHJ5KGtleSk7XHJcbiAgICAgICAgaWYgKGVudHJ5ID49IDApIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuZW50cmllc1tlbnRyeV0udmFsdWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihub1N1Y2hrZXkpO1xyXG4gICAgfTtcclxuXHJcbiAgICBEaWN0aW9uYXJ5LnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xyXG4gICAgICAgIHRoaXMuX2luc2VydChrZXksIHZhbHVlLCBmYWxzZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIERpY3Rpb25hcnkucHJvdG90eXBlLmNvbnRhaW5za2V5ID0gZnVuY3Rpb24gKGtleSkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLl9maW5kRW50cnkoa2V5KSA+PSAwO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBDb3JyZWxhdGVzIHRoZSBlbGVtZW50cyBvZiB0d28gc2VxdWVuY2VzIGJhc2VkIG9uIG92ZXJsYXBwaW5nIGR1cmF0aW9ucy5cclxuICAgICAqICBcclxuICAgICAqICBAcGFyYW0ge09ic2VydmFibGV9IHJpZ2h0IFRoZSByaWdodCBvYnNlcnZhYmxlIHNlcXVlbmNlIHRvIGpvaW4gZWxlbWVudHMgZm9yLlxyXG4gICAgICogIEBwYXJhbSB7RnVuY3Rpb259IGxlZnREdXJhdGlvblNlbGVjdG9yIEEgZnVuY3Rpb24gdG8gc2VsZWN0IHRoZSBkdXJhdGlvbiAoZXhwcmVzc2VkIGFzIGFuIG9ic2VydmFibGUgc2VxdWVuY2UpIG9mIGVhY2ggZWxlbWVudCBvZiB0aGUgbGVmdCBvYnNlcnZhYmxlIHNlcXVlbmNlLCB1c2VkIHRvIGRldGVybWluZSBvdmVybGFwLlxyXG4gICAgICogIEBwYXJhbSB7RnVuY3Rpb259IHJpZ2h0RHVyYXRpb25TZWxlY3RvciBBIGZ1bmN0aW9uIHRvIHNlbGVjdCB0aGUgZHVyYXRpb24gKGV4cHJlc3NlZCBhcyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlKSBvZiBlYWNoIGVsZW1lbnQgb2YgdGhlIHJpZ2h0IG9ic2VydmFibGUgc2VxdWVuY2UsIHVzZWQgdG8gZGV0ZXJtaW5lIG92ZXJsYXAuXHJcbiAgICAgKiAgQHBhcmFtIHtGdW5jdGlvbn0gcmVzdWx0U2VsZWN0b3IgQSBmdW5jdGlvbiBpbnZva2VkIHRvIGNvbXB1dGUgYSByZXN1bHQgZWxlbWVudCBmb3IgYW55IHR3byBvdmVybGFwcGluZyBlbGVtZW50cyBvZiB0aGUgbGVmdCBhbmQgcmlnaHQgb2JzZXJ2YWJsZSBzZXF1ZW5jZXMuIFRoZSBwYXJhbWV0ZXJzIHBhc3NlZCB0byB0aGUgZnVuY3Rpb24gY29ycmVzcG9uZCB3aXRoIHRoZSBlbGVtZW50cyBmcm9tIHRoZSBsZWZ0IGFuZCByaWdodCBzb3VyY2Ugc2VxdWVuY2VzIGZvciB3aGljaCBvdmVybGFwIG9jY3Vycy5cclxuICAgICAqICBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNvbnRhaW5zIHJlc3VsdCBlbGVtZW50cyBjb21wdXRlZCBmcm9tIHNvdXJjZSBlbGVtZW50cyB0aGF0IGhhdmUgYW4gb3ZlcmxhcHBpbmcgZHVyYXRpb24uXHJcbiAgICAgKi8gICAgXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uam9pbiA9IGZ1bmN0aW9uIChyaWdodCwgbGVmdER1cmF0aW9uU2VsZWN0b3IsIHJpZ2h0RHVyYXRpb25TZWxlY3RvciwgcmVzdWx0U2VsZWN0b3IpIHtcclxuICAgICAgICB2YXIgbGVmdCA9IHRoaXM7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgZ3JvdXAgPSBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZSgpLFxyXG4gICAgICAgICAgICBsZWZ0RG9uZSA9IGZhbHNlLFxyXG4gICAgICAgICAgICBsZWZ0SWQgPSAwLFxyXG4gICAgICAgICAgICBsZWZ0TWFwID0gbmV3IERpY3Rpb25hcnkoKSxcclxuICAgICAgICAgICAgcmlnaHREb25lID0gZmFsc2UsXHJcbiAgICAgICAgICAgIHJpZ2h0SWQgPSAwLFxyXG4gICAgICAgICAgICByaWdodE1hcCA9IG5ldyBEaWN0aW9uYXJ5KCk7XHJcbiAgICAgICAgICAgIGdyb3VwLmFkZChsZWZ0LnN1YnNjcmliZShmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIHZhciBkdXJhdGlvbixcclxuICAgICAgICAgICAgICAgIGV4cGlyZSxcclxuICAgICAgICAgICAgICAgIGlkID0gbGVmdElkKyssXHJcbiAgICAgICAgICAgICAgICBtZCA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0LFxyXG4gICAgICAgICAgICAgICAgdmFsdWVzO1xyXG4gICAgICAgICAgICAgICAgbGVmdE1hcC5hZGQoaWQsIHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIGdyb3VwLmFkZChtZCk7XHJcbiAgICAgICAgICAgICAgICBleHBpcmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGxlZnRNYXAucmVtb3ZlKGlkKSAmJiBsZWZ0TWFwLmNvdW50KCkgPT09IDAgJiYgbGVmdERvbmUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGdyb3VwLnJlbW92ZShtZCk7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBkdXJhdGlvbiA9IGxlZnREdXJhdGlvblNlbGVjdG9yKHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG1kLnNldERpc3Bvc2FibGUoZHVyYXRpb24udGFrZSgxKS5zdWJzY3JpYmUobm9vcCwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkgeyBleHBpcmUoKTsgfSkpO1xyXG4gICAgICAgICAgICAgICAgdmFsdWVzID0gcmlnaHRNYXAuZ2V0VmFsdWVzKCk7XHJcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdFNlbGVjdG9yKHZhbHVlLCB2YWx1ZXNbaV0pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGV4Y2VwdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGV4Y2VwdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGxlZnREb25lID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGlmIChyaWdodERvbmUgfHwgbGVmdE1hcC5jb3VudCgpID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICBncm91cC5hZGQocmlnaHQuc3Vic2NyaWJlKGZ1bmN0aW9uICh2YWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGR1cmF0aW9uLFxyXG4gICAgICAgICAgICAgICAgZXhwaXJlLFxyXG4gICAgICAgICAgICAgICAgaWQgPSByaWdodElkKyssXHJcbiAgICAgICAgICAgICAgICBtZCA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0LFxyXG4gICAgICAgICAgICAgICAgdmFsdWVzO1xyXG4gICAgICAgICAgICAgICAgcmlnaHRNYXAuYWRkKGlkLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICBncm91cC5hZGQobWQpO1xyXG4gICAgICAgICAgICAgICAgZXhwaXJlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChyaWdodE1hcC5yZW1vdmUoaWQpICYmIHJpZ2h0TWFwLmNvdW50KCkgPT09IDAgJiYgcmlnaHREb25lKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBncm91cC5yZW1vdmUobWQpO1xyXG4gICAgICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZHVyYXRpb24gPSByaWdodER1cmF0aW9uU2VsZWN0b3IodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleGNlcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG1kLnNldERpc3Bvc2FibGUoZHVyYXRpb24udGFrZSgxKS5zdWJzY3JpYmUobm9vcCwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkgeyBleHBpcmUoKTsgfSkpO1xyXG4gICAgICAgICAgICAgICAgdmFsdWVzID0gbGVmdE1hcC5nZXRWYWx1ZXMoKTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmFsdWVzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0U2VsZWN0b3IodmFsdWVzW2ldLCB2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZXhjZXB0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXhjZXB0aW9uKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQocmVzdWx0KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgcmlnaHREb25lID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGlmIChsZWZ0RG9uZSB8fCByaWdodE1hcC5jb3VudCgpID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICByZXR1cm4gZ3JvdXA7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIENvcnJlbGF0ZXMgdGhlIGVsZW1lbnRzIG9mIHR3byBzZXF1ZW5jZXMgYmFzZWQgb24gb3ZlcmxhcHBpbmcgZHVyYXRpb25zLCBhbmQgZ3JvdXBzIHRoZSByZXN1bHRzLlxyXG4gICAgICogIFxyXG4gICAgICogIEBwYXJhbSB7T2JzZXJ2YWJsZX0gcmlnaHQgVGhlIHJpZ2h0IG9ic2VydmFibGUgc2VxdWVuY2UgdG8gam9pbiBlbGVtZW50cyBmb3IuXHJcbiAgICAgKiAgQHBhcmFtIHtGdW5jdGlvbn0gbGVmdER1cmF0aW9uU2VsZWN0b3IgQSBmdW5jdGlvbiB0byBzZWxlY3QgdGhlIGR1cmF0aW9uIChleHByZXNzZWQgYXMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSkgb2YgZWFjaCBlbGVtZW50IG9mIHRoZSBsZWZ0IG9ic2VydmFibGUgc2VxdWVuY2UsIHVzZWQgdG8gZGV0ZXJtaW5lIG92ZXJsYXAuXHJcbiAgICAgKiAgQHBhcmFtIHtGdW5jdGlvbn0gcmlnaHREdXJhdGlvblNlbGVjdG9yIEEgZnVuY3Rpb24gdG8gc2VsZWN0IHRoZSBkdXJhdGlvbiAoZXhwcmVzc2VkIGFzIGFuIG9ic2VydmFibGUgc2VxdWVuY2UpIG9mIGVhY2ggZWxlbWVudCBvZiB0aGUgcmlnaHQgb2JzZXJ2YWJsZSBzZXF1ZW5jZSwgdXNlZCB0byBkZXRlcm1pbmUgb3ZlcmxhcC5cclxuICAgICAqICBAcGFyYW0ge0Z1bmN0aW9ufSByZXN1bHRTZWxlY3RvciBBIGZ1bmN0aW9uIGludm9rZWQgdG8gY29tcHV0ZSBhIHJlc3VsdCBlbGVtZW50IGZvciBhbnkgZWxlbWVudCBvZiB0aGUgbGVmdCBzZXF1ZW5jZSB3aXRoIG92ZXJsYXBwaW5nIGVsZW1lbnRzIGZyb20gdGhlIHJpZ2h0IG9ic2VydmFibGUgc2VxdWVuY2UuIFRoZSBmaXJzdCBwYXJhbWV0ZXIgcGFzc2VkIHRvIHRoZSBmdW5jdGlvbiBpcyBhbiBlbGVtZW50IG9mIHRoZSBsZWZ0IHNlcXVlbmNlLiBUaGUgc2Vjb25kIHBhcmFtZXRlciBwYXNzZWQgdG8gdGhlIGZ1bmN0aW9uIGlzIGFuIG9ic2VydmFibGUgc2VxdWVuY2Ugd2l0aCBlbGVtZW50cyBmcm9tIHRoZSByaWdodCBzZXF1ZW5jZSB0aGF0IG92ZXJsYXAgd2l0aCB0aGUgbGVmdCBzZXF1ZW5jZSdzIGVsZW1lbnQuXHJcbiAgICAgKiAgQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBjb250YWlucyByZXN1bHQgZWxlbWVudHMgY29tcHV0ZWQgZnJvbSBzb3VyY2UgZWxlbWVudHMgdGhhdCBoYXZlIGFuIG92ZXJsYXBwaW5nIGR1cmF0aW9uLlxyXG4gICAgICovICAgIFxyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmdyb3VwSm9pbiA9IGZ1bmN0aW9uIChyaWdodCwgbGVmdER1cmF0aW9uU2VsZWN0b3IsIHJpZ2h0RHVyYXRpb25TZWxlY3RvciwgcmVzdWx0U2VsZWN0b3IpIHtcclxuICAgICAgICB2YXIgbGVmdCA9IHRoaXM7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgbm90aGluZyA9IGZ1bmN0aW9uICgpIHt9O1xyXG4gICAgICAgICAgICB2YXIgZ3JvdXAgPSBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZSgpO1xyXG4gICAgICAgICAgICB2YXIgciA9IG5ldyBSZWZDb3VudERpc3Bvc2FibGUoZ3JvdXApO1xyXG4gICAgICAgICAgICB2YXIgbGVmdE1hcCA9IG5ldyBEaWN0aW9uYXJ5KCk7XHJcbiAgICAgICAgICAgIHZhciByaWdodE1hcCA9IG5ldyBEaWN0aW9uYXJ5KCk7XHJcbiAgICAgICAgICAgIHZhciBsZWZ0SUQgPSAwO1xyXG4gICAgICAgICAgICB2YXIgcmlnaHRJRCA9IDA7XHJcblxyXG4gICAgICAgICAgICBncm91cC5hZGQobGVmdC5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgcyA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGlkID0gbGVmdElEKys7XHJcbiAgICAgICAgICAgICAgICAgICAgbGVmdE1hcC5hZGQoaWQsIHMpO1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBpLCBsZW4sIGxlZnRWYWx1ZXMsIHJpZ2h0VmFsdWVzO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICB2YXIgcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHJlc3VsdFNlbGVjdG9yKHZhbHVlLCBhZGRSZWYocywgcikpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFZhbHVlcyA9IGxlZnRNYXAuZ2V0VmFsdWVzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxlZnRWYWx1ZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZnRWYWx1ZXNbaV0ub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChyZXN1bHQpO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICByaWdodFZhbHVlcyA9IHJpZ2h0TWFwLmdldFZhbHVlcygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IHJpZ2h0VmFsdWVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHMub25OZXh0KHJpZ2h0VmFsdWVzW2ldKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtZCA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwLmFkZChtZCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBleHBpcmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsZWZ0TWFwLnJlbW92ZShpZCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwLnJlbW92ZShtZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGR1cmF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gbGVmdER1cmF0aW9uU2VsZWN0b3IodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFZhbHVlcyA9IGxlZnRNYXAuZ2V0VmFsdWVzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxlZnRNYXAubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZnRWYWx1ZXNbaV0ub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICBtZC5zZXREaXNwb3NhYmxlKGR1cmF0aW9uLnRha2UoMSkuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBub3RoaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFZhbHVlcyA9IGxlZnRNYXAuZ2V0VmFsdWVzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBsZWZ0VmFsdWVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFZhbHVlc1tpXS5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJlKVxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcbiAgICAgICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbGVmdFZhbHVlcyA9IGxlZnRNYXAuZ2V0VmFsdWVzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IGxlZnRWYWx1ZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFZhbHVlc1tpXS5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkLmJpbmQob2JzZXJ2ZXIpKSk7XHJcblxyXG4gICAgICAgICAgICBncm91cC5hZGQocmlnaHQuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGxlZnRWYWx1ZXMsIGksIGxlbjtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgaWQgPSByaWdodElEKys7XHJcbiAgICAgICAgICAgICAgICAgICAgcmlnaHRNYXAuYWRkKGlkLCB2YWx1ZSk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBtZCA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGdyb3VwLmFkZChtZCk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBleHBpcmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0TWFwLnJlbW92ZShpZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwLnJlbW92ZShtZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIGR1cmF0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGR1cmF0aW9uID0gcmlnaHREdXJhdGlvblNlbGVjdG9yKHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGxlZnRWYWx1ZXMgPSBsZWZ0TWFwLmdldFZhbHVlcygpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBsZWZ0TWFwLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZWZ0VmFsdWVzW2ldLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBtZC5zZXREaXNwb3NhYmxlKGR1cmF0aW9uLnRha2UoMSkuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBub3RoaW5nLFxyXG4gICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFZhbHVlcyA9IGxlZnRNYXAuZ2V0VmFsdWVzKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBsZWZ0TWFwLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFZhbHVlc1tpXS5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgZXhwaXJlKVxyXG4gICAgICAgICAgICAgICAgICAgICk7XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGxlZnRWYWx1ZXMgPSBsZWZ0TWFwLmdldFZhbHVlcygpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGxlZnRWYWx1ZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgbGVmdFZhbHVlc1tpXS5vbk5leHQodmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBsZWZ0VmFsdWVzID0gbGVmdE1hcC5nZXRWYWx1ZXMoKTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gbGVmdFZhbHVlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBsZWZ0VmFsdWVzW2ldLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgICAgICAgICB9KSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gcjtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgUHJvamVjdHMgZWFjaCBlbGVtZW50IG9mIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgaW50byB6ZXJvIG9yIG1vcmUgYnVmZmVycy5cclxuICAgICAqICBcclxuICAgICAqICBAcGFyYW0ge01peGVkfSBidWZmZXJPcGVuaW5nc09yQ2xvc2luZ1NlbGVjdG9yIE9ic2VydmFibGUgc2VxdWVuY2Ugd2hvc2UgZWxlbWVudHMgZGVub3RlIHRoZSBjcmVhdGlvbiBvZiBuZXcgd2luZG93cywgb3IsIGEgZnVuY3Rpb24gaW52b2tlZCB0byBkZWZpbmUgdGhlIGJvdW5kYXJpZXMgb2YgdGhlIHByb2R1Y2VkIHdpbmRvd3MgKGEgbmV3IHdpbmRvdyBpcyBzdGFydGVkIHdoZW4gdGhlIHByZXZpb3VzIG9uZSBpcyBjbG9zZWQsIHJlc3VsdGluZyBpbiBub24tb3ZlcmxhcHBpbmcgd2luZG93cykuXHJcbiAgICAgKiAgQHBhcmFtIHtGdW5jdGlvbn0gW2J1ZmZlckNsb3NpbmdTZWxlY3Rvcl0gQSBmdW5jdGlvbiBpbnZva2VkIHRvIGRlZmluZSB0aGUgY2xvc2luZyBvZiBlYWNoIHByb2R1Y2VkIHdpbmRvdy4gSWYgYSBjbG9zaW5nIHNlbGVjdG9yIGZ1bmN0aW9uIGlzIHNwZWNpZmllZCBmb3IgdGhlIGZpcnN0IHBhcmFtZXRlciwgdGhpcyBwYXJhbWV0ZXIgaXMgaWdub3JlZC5cclxuICAgICAqICBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBvZiB3aW5kb3dzLiAgICBcclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmJ1ZmZlciA9IGZ1bmN0aW9uIChidWZmZXJPcGVuaW5nc09yQ2xvc2luZ1NlbGVjdG9yLCBidWZmZXJDbG9zaW5nU2VsZWN0b3IpIHtcclxuICAgICAgICByZXR1cm4gdGhpcy53aW5kb3cuYXBwbHkodGhpcywgYXJndW1lbnRzKS5zZWxlY3RNYW55KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4LnRvQXJyYXkoKTsgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFByb2plY3RzIGVhY2ggZWxlbWVudCBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGludG8gemVybyBvciBtb3JlIHdpbmRvd3MuXHJcbiAgICAgKiAgXHJcbiAgICAgKiAgQHBhcmFtIHtNaXhlZH0gd2luZG93T3BlbmluZ3NPckNsb3NpbmdTZWxlY3RvciBPYnNlcnZhYmxlIHNlcXVlbmNlIHdob3NlIGVsZW1lbnRzIGRlbm90ZSB0aGUgY3JlYXRpb24gb2YgbmV3IHdpbmRvd3MsIG9yLCBhIGZ1bmN0aW9uIGludm9rZWQgdG8gZGVmaW5lIHRoZSBib3VuZGFyaWVzIG9mIHRoZSBwcm9kdWNlZCB3aW5kb3dzIChhIG5ldyB3aW5kb3cgaXMgc3RhcnRlZCB3aGVuIHRoZSBwcmV2aW91cyBvbmUgaXMgY2xvc2VkLCByZXN1bHRpbmcgaW4gbm9uLW92ZXJsYXBwaW5nIHdpbmRvd3MpLlxyXG4gICAgICogIEBwYXJhbSB7RnVuY3Rpb259IFt3aW5kb3dDbG9zaW5nU2VsZWN0b3JdIEEgZnVuY3Rpb24gaW52b2tlZCB0byBkZWZpbmUgdGhlIGNsb3Npbmcgb2YgZWFjaCBwcm9kdWNlZCB3aW5kb3cuIElmIGEgY2xvc2luZyBzZWxlY3RvciBmdW5jdGlvbiBpcyBzcGVjaWZpZWQgZm9yIHRoZSBmaXJzdCBwYXJhbWV0ZXIsIHRoaXMgcGFyYW1ldGVyIGlzIGlnbm9yZWQuXHJcbiAgICAgKiAgQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2Ugb2Ygd2luZG93cy5cclxuICAgICAqLyAgICBcclxuICAgIG9ic2VydmFibGVQcm90by53aW5kb3cgPSBmdW5jdGlvbiAod2luZG93T3BlbmluZ3NPckNsb3NpbmdTZWxlY3Rvciwgd2luZG93Q2xvc2luZ1NlbGVjdG9yKSB7XHJcbiAgICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDEgJiYgdHlwZW9mIGFyZ3VtZW50c1swXSAhPT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZVdpbmRvd1dpdGhCb3VuYXJpZXMuY2FsbCh0aGlzLCB3aW5kb3dPcGVuaW5nc09yQ2xvc2luZ1NlbGVjdG9yKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHR5cGVvZiB3aW5kb3dPcGVuaW5nc09yQ2xvc2luZ1NlbGVjdG9yID09PSAnZnVuY3Rpb24nID9cclxuICAgICAgICAgICAgb2JzZXJ2YWJsZVdpbmRvd1dpdGhDbG9zaW5nU2VsZWN0b3IuY2FsbCh0aGlzLCB3aW5kb3dPcGVuaW5nc09yQ2xvc2luZ1NlbGVjdG9yKSA6XHJcbiAgICAgICAgICAgIG9ic2VydmFibGVXaW5kb3dXaXRoT3BlbmluZ3MuY2FsbCh0aGlzLCB3aW5kb3dPcGVuaW5nc09yQ2xvc2luZ1NlbGVjdG9yLCB3aW5kb3dDbG9zaW5nU2VsZWN0b3IpO1xyXG4gICAgfTtcclxuICAgIFxyXG4gICAgZnVuY3Rpb24gb2JzZXJ2YWJsZVdpbmRvd1dpdGhPcGVuaW5ncyh3aW5kb3dPcGVuaW5ncywgd2luZG93Q2xvc2luZ1NlbGVjdG9yKSB7XHJcbiAgICAgICAgcmV0dXJuIHdpbmRvd09wZW5pbmdzLmdyb3VwSm9pbih0aGlzLCB3aW5kb3dDbG9zaW5nU2VsZWN0b3IsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVFbXB0eSgpO1xyXG4gICAgICAgIH0sIGZ1bmN0aW9uIChfLCB3aW5kb3cpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHdpbmRvdztcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBvYnNlcnZhYmxlV2luZG93V2l0aEJvdW5hcmllcyh3aW5kb3dCb3VuZGFyaWVzKSB7XHJcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRoaXM7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgd2luZG93ID0gbmV3IFN1YmplY3QoKSwgXHJcbiAgICAgICAgICAgICAgICBkID0gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoKSwgXHJcbiAgICAgICAgICAgICAgICByID0gbmV3IFJlZkNvdW50RGlzcG9zYWJsZShkKTtcclxuXHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChhZGRSZWYod2luZG93LCByKSk7XHJcblxyXG4gICAgICAgICAgICBkLmFkZChzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cub25OZXh0KHgpO1xyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cub25FcnJvcihlcnIpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlcnIpO1xyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIH0pKTtcclxuXHJcbiAgICAgICAgICAgIGQuYWRkKHdpbmRvd0JvdW5kYXJpZXMuc3Vic2NyaWJlKGZ1bmN0aW9uICh3KSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIHdpbmRvdyA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQoYWRkUmVmKHdpbmRvdywgcikpO1xyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cub25FcnJvcihlcnIpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlcnIpO1xyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB3aW5kb3cub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIH0pKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiByO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIG9ic2VydmFibGVXaW5kb3dXaXRoQ2xvc2luZ1NlbGVjdG9yKHdpbmRvd0Nsb3NpbmdTZWxlY3Rvcikge1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGNyZWF0ZVdpbmRvd0Nsb3NlLFxyXG4gICAgICAgICAgICAgICAgbSA9IG5ldyBTZXJpYWxEaXNwb3NhYmxlKCksXHJcbiAgICAgICAgICAgICAgICBkID0gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUobSksXHJcbiAgICAgICAgICAgICAgICByID0gbmV3IFJlZkNvdW50RGlzcG9zYWJsZShkKSxcclxuICAgICAgICAgICAgICAgIHdpbmRvdyA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChhZGRSZWYod2luZG93LCByKSk7XHJcbiAgICAgICAgICAgIGQuYWRkKHNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgIHdpbmRvdy5vbk5leHQoeCk7XHJcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChleCkge1xyXG4gICAgICAgICAgICAgICAgd2luZG93Lm9uRXJyb3IoZXgpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleCk7XHJcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHdpbmRvdy5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICBjcmVhdGVXaW5kb3dDbG9zZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBtMSwgd2luZG93Q2xvc2U7XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvd0Nsb3NlID0gd2luZG93Q2xvc2luZ1NlbGVjdG9yKCk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGV4Y2VwdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbTEgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgICAgIG0uc2V0RGlzcG9zYWJsZShtMSk7XHJcbiAgICAgICAgICAgICAgICBtMS5zZXREaXNwb3NhYmxlKHdpbmRvd0Nsb3NlLnRha2UoMSkuc3Vic2NyaWJlKG5vb3AsIGZ1bmN0aW9uIChleCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHdpbmRvdy5vbkVycm9yKGV4KTtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGV4KTtcclxuICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICB3aW5kb3cub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB3aW5kb3cgPSBuZXcgU3ViamVjdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChhZGRSZWYod2luZG93LCByKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgY3JlYXRlV2luZG93Q2xvc2UoKTtcclxuICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgY3JlYXRlV2luZG93Q2xvc2UoKTtcclxuICAgICAgICAgICAgcmV0dXJuIHI7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIFJldHVybnMgYSBuZXcgb2JzZXJ2YWJsZSB0aGF0IHRyaWdnZXJzIG9uIHRoZSBzZWNvbmQgYW5kIHN1YnNlcXVlbnQgdHJpZ2dlcmluZ3Mgb2YgdGhlIGlucHV0IG9ic2VydmFibGUuIFxyXG4gICAqIFRoZSBOdGggdHJpZ2dlcmluZyBvZiB0aGUgaW5wdXQgb2JzZXJ2YWJsZSBwYXNzZXMgdGhlIGFyZ3VtZW50cyBmcm9tIHRoZSBOLTF0aCBhbmQgTnRoIHRyaWdnZXJpbmcgYXMgYSBwYWlyLiBcclxuICAgKiBUaGUgYXJndW1lbnQgcGFzc2VkIHRvIHRoZSBOLTF0aCB0cmlnZ2VyaW5nIGlzIGhlbGQgaW4gaGlkZGVuIGludGVybmFsIHN0YXRlIHVudGlsIHRoZSBOdGggdHJpZ2dlcmluZyBvY2N1cnMuXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgdGhhdCB0cmlnZ2VycyBvbiBzdWNjZXNzaXZlIHBhaXJzIG9mIG9ic2VydmF0aW9ucyBmcm9tIHRoZSBpbnB1dCBvYnNlcnZhYmxlIGFzIGFuIGFycmF5LlxyXG4gICAqL1xyXG4gIG9ic2VydmFibGVQcm90by5wYWlyd2lzZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICB2YXIgcHJldmlvdXMsIGhhc1ByZXZpb3VzID0gZmFsc2U7XHJcbiAgICAgIHJldHVybiBzb3VyY2Uuc3Vic2NyaWJlKFxyXG4gICAgICAgIGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICBpZiAoaGFzUHJldmlvdXMpIHtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KFtwcmV2aW91cywgeF0pO1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgaGFzUHJldmlvdXMgPSB0cnVlO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgcHJldmlvdXMgPSB4O1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSxcclxuICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZC5iaW5kKG9ic2VydmVyKSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG4gIC8qKiBcclxuICAgKiBSZXR1cm5zIHR3byBvYnNlcnZhYmxlcyB3aGljaCBwYXJ0aXRpb24gdGhlIG9ic2VydmF0aW9ucyBvZiB0aGUgc291cmNlIGJ5IHRoZSBnaXZlbiBmdW5jdGlvbi5cclxuICAgKiBUaGUgZmlyc3Qgd2lsbCB0cmlnZ2VyIG9ic2VydmF0aW9ucyBmb3IgdGhvc2UgdmFsdWVzIGZvciB3aGljaCB0aGUgcHJlZGljYXRlIHJldHVybnMgdHJ1ZS4gXHJcbiAgICogVGhlIHNlY29uZCB3aWxsIHRyaWdnZXIgb2JzZXJ2YXRpb25zIGZvciB0aG9zZSB2YWx1ZXMgd2hlcmUgdGhlIHByZWRpY2F0ZSByZXR1cm5zIGZhbHNlLiBcclxuICAgKiBUaGUgcHJlZGljYXRlIGlzIGV4ZWN1dGVkIG9uY2UgZm9yIGVhY2ggc3Vic2NyaWJlZCBvYnNlcnZlci4gXHJcbiAgICogQm90aCBhbHNvIHByb3BhZ2F0ZSBhbGwgZXJyb3Igb2JzZXJ2YXRpb25zIGFyaXNpbmcgZnJvbSB0aGUgc291cmNlIGFuZCBlYWNoIGNvbXBsZXRlcyBcclxuICAgKiB3aGVuIHRoZSBzb3VyY2UgY29tcGxldGVzLlxyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWRpY2F0ZSBcclxuICAgKiAgICBUaGUgZnVuY3Rpb24gdG8gZGV0ZXJtaW5lIHdoaWNoIG91dHB1dCBPYnNlcnZhYmxlIHdpbGwgdHJpZ2dlciBhIHBhcnRpY3VsYXIgb2JzZXJ2YXRpb24uXHJcbiAgICogQHJldHVybnMge0FycmF5fVxyXG4gICAqICAgIEFuIGFycmF5IG9mIG9ic2VydmFibGVzLiBUaGUgZmlyc3QgdHJpZ2dlcnMgd2hlbiB0aGUgcHJlZGljYXRlIHJldHVybnMgdHJ1ZSwgXHJcbiAgICogICAgYW5kIHRoZSBzZWNvbmQgdHJpZ2dlcnMgd2hlbiB0aGUgcHJlZGljYXRlIHJldHVybnMgZmFsc2UuXHJcbiAgKi9cclxuICBvYnNlcnZhYmxlUHJvdG8ucGFydGl0aW9uID0gZnVuY3Rpb24ocHJlZGljYXRlLCB0aGlzQXJnKSB7XHJcbiAgICB2YXIgcHVibGlzaGVkID0gdGhpcy5wdWJsaXNoKCkucmVmQ291bnQoKTtcclxuICAgIHJldHVybiBbIFxyXG4gICAgICBwdWJsaXNoZWQuZmlsdGVyKHByZWRpY2F0ZSwgdGhpc0FyZyksIFxyXG4gICAgICBwdWJsaXNoZWQuZmlsdGVyKGZ1bmN0aW9uICh4LCBpLCBvKSB7IHJldHVybiAhcHJlZGljYXRlLmNhbGwodGhpc0FyZywgeCwgaSwgbyk7IH0pXHJcbiAgICBdO1xyXG4gIH07XHJcblxyXG4gIGZ1bmN0aW9uIGVudW1lcmFibGVXaGlsZShjb25kaXRpb24sIHNvdXJjZSkge1xyXG4gICAgcmV0dXJuIG5ldyBFbnVtZXJhYmxlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgcmV0dXJuIG5ldyBFbnVtZXJhdG9yKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gY29uZGl0aW9uKCkgP1xyXG4gICAgICAgICAgeyBkb25lOiBmYWxzZSwgdmFsdWU6IHNvdXJjZSB9IDpcclxuICAgICAgICAgIHsgZG9uZTogdHJ1ZSwgdmFsdWU6IHVuZGVmaW5lZCB9OyAgXHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAgICAvKipcclxuICAgICAqICBSZXR1cm5zIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBpcyB0aGUgcmVzdWx0IG9mIGludm9raW5nIHRoZSBzZWxlY3RvciBvbiB0aGUgc291cmNlIHNlcXVlbmNlLCB3aXRob3V0IHNoYXJpbmcgc3Vic2NyaXB0aW9ucy5cclxuICAgICAqICBUaGlzIG9wZXJhdG9yIGFsbG93cyBmb3IgYSBmbHVlbnQgc3R5bGUgb2Ygd3JpdGluZyBxdWVyaWVzIHRoYXQgdXNlIHRoZSBzYW1lIHNlcXVlbmNlIG11bHRpcGxlIHRpbWVzLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHNlbGVjdG9yIFNlbGVjdG9yIGZ1bmN0aW9uIHdoaWNoIGNhbiB1c2UgdGhlIHNvdXJjZSBzZXF1ZW5jZSBhcyBtYW55IHRpbWVzIGFzIG5lZWRlZCwgd2l0aG91dCBzaGFyaW5nIHN1YnNjcmlwdGlvbnMgdG8gdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgY29udGFpbnMgdGhlIGVsZW1lbnRzIG9mIGEgc2VxdWVuY2UgcHJvZHVjZWQgYnkgbXVsdGljYXN0aW5nIHRoZSBzb3VyY2Ugc2VxdWVuY2Ugd2l0aGluIGEgc2VsZWN0b3IgZnVuY3Rpb24uXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5sZXRCaW5kID0gb2JzZXJ2YWJsZVByb3RvWydsZXQnXSA9IGZ1bmN0aW9uIChmdW5jKSB7XHJcbiAgICAgICAgcmV0dXJuIGZ1bmModGhpcyk7XHJcbiAgICB9O1xyXG5cclxuICAgLyoqXHJcbiAgICogIERldGVybWluZXMgd2hldGhlciBhbiBvYnNlcnZhYmxlIGNvbGxlY3Rpb24gY29udGFpbnMgdmFsdWVzLiBUaGVyZSBpcyBhbiBhbGlhcyBmb3IgdGhpcyBtZXRob2QgY2FsbGVkICdpZlRoZW4nIGZvciBicm93c2VycyA8SUU5XHJcbiAgICogIFxyXG4gICAqIEBleGFtcGxlXHJcbiAgICogIDEgLSByZXMgPSBSeC5PYnNlcnZhYmxlLmlmKGNvbmRpdGlvbiwgb2JzMSk7XHJcbiAgICogIDIgLSByZXMgPSBSeC5PYnNlcnZhYmxlLmlmKGNvbmRpdGlvbiwgb2JzMSwgb2JzMik7XHJcbiAgICogIDMgLSByZXMgPSBSeC5PYnNlcnZhYmxlLmlmKGNvbmRpdGlvbiwgb2JzMSwgc2NoZWR1bGVyKTtcclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb25kaXRpb24gVGhlIGNvbmRpdGlvbiB3aGljaCBkZXRlcm1pbmVzIGlmIHRoZSB0aGVuU291cmNlIG9yIGVsc2VTb3VyY2Ugd2lsbCBiZSBydW4uXHJcbiAgICogQHBhcmFtIHtPYnNlcnZhYmxlfSB0aGVuU291cmNlIFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIG9yIFByb21pc2UgdGhhdCB3aWxsIGJlIHJ1biBpZiB0aGUgY29uZGl0aW9uIGZ1bmN0aW9uIHJldHVybnMgdHJ1ZS5cclxuICAgKiBAcGFyYW0ge09ic2VydmFibGV9IFtlbHNlU291cmNlXSBUaGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSBvciBQcm9taXNlIHRoYXQgd2lsbCBiZSBydW4gaWYgdGhlIGNvbmRpdGlvbiBmdW5jdGlvbiByZXR1cm5zIGZhbHNlLiBJZiB0aGlzIGlzIG5vdCBwcm92aWRlZCwgaXQgZGVmYXVsdHMgdG8gUnguT2JzZXJ2YWJlLkVtcHR5IHdpdGggdGhlIHNwZWNpZmllZCBzY2hlZHVsZXIuICBcclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aGljaCBpcyBlaXRoZXIgdGhlIHRoZW5Tb3VyY2Ugb3IgZWxzZVNvdXJjZS5cclxuICAgKi9cclxuICBPYnNlcnZhYmxlWydpZiddID0gT2JzZXJ2YWJsZS5pZlRoZW4gPSBmdW5jdGlvbiAoY29uZGl0aW9uLCB0aGVuU291cmNlLCBlbHNlU291cmNlT3JTY2hlZHVsZXIpIHtcclxuICAgIHJldHVybiBvYnNlcnZhYmxlRGVmZXIoZnVuY3Rpb24gKCkge1xyXG4gICAgICBlbHNlU291cmNlT3JTY2hlZHVsZXIgfHwgKGVsc2VTb3VyY2VPclNjaGVkdWxlciA9IG9ic2VydmFibGVFbXB0eSgpKTtcclxuXHJcbiAgICAgIGlzUHJvbWlzZSh0aGVuU291cmNlKSAmJiAodGhlblNvdXJjZSA9IG9ic2VydmFibGVGcm9tUHJvbWlzZSh0aGVuU291cmNlKSk7XHJcbiAgICAgIGlzUHJvbWlzZShlbHNlU291cmNlT3JTY2hlZHVsZXIpICYmIChlbHNlU291cmNlT3JTY2hlZHVsZXIgPSBvYnNlcnZhYmxlRnJvbVByb21pc2UoZWxzZVNvdXJjZU9yU2NoZWR1bGVyKSk7XHJcblxyXG4gICAgICAvLyBBc3N1bWUgYSBzY2hlZHVsZXIgZm9yIGVtcHR5IG9ubHlcclxuICAgICAgdHlwZW9mIGVsc2VTb3VyY2VPclNjaGVkdWxlci5ub3cgPT09ICdmdW5jdGlvbicgJiYgKGVsc2VTb3VyY2VPclNjaGVkdWxlciA9IG9ic2VydmFibGVFbXB0eShlbHNlU291cmNlT3JTY2hlZHVsZXIpKTtcclxuICAgICAgcmV0dXJuIGNvbmRpdGlvbigpID8gdGhlblNvdXJjZSA6IGVsc2VTb3VyY2VPclNjaGVkdWxlcjtcclxuICAgIH0pO1xyXG4gIH07XHJcblxyXG4gICAvKipcclxuICAgKiAgQ29uY2F0ZW5hdGVzIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlcyBvYnRhaW5lZCBieSBydW5uaW5nIHRoZSBzcGVjaWZpZWQgcmVzdWx0IHNlbGVjdG9yIGZvciBlYWNoIGVsZW1lbnQgaW4gc291cmNlLlxyXG4gICAqIFRoZXJlIGlzIGFuIGFsaWFzIGZvciB0aGlzIG1ldGhvZCBjYWxsZWQgJ2ZvckluJyBmb3IgYnJvd3NlcnMgPElFOVxyXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZXMgQW4gYXJyYXkgb2YgdmFsdWVzIHRvIHR1cm4gaW50byBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlc3VsdFNlbGVjdG9yIEEgZnVuY3Rpb24gdG8gYXBwbHkgdG8gZWFjaCBpdGVtIGluIHRoZSBzb3VyY2VzIGFycmF5IHRvIHR1cm4gaXQgaW50byBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGZyb20gdGhlIGNvbmNhdGVuYXRlZCBvYnNlcnZhYmxlIHNlcXVlbmNlcy4gIFxyXG4gICAqLyBcclxuICBPYnNlcnZhYmxlWydmb3InXSA9IE9ic2VydmFibGUuZm9ySW4gPSBmdW5jdGlvbiAoc291cmNlcywgcmVzdWx0U2VsZWN0b3IpIHtcclxuICAgIHJldHVybiBlbnVtZXJhYmxlRm9yKHNvdXJjZXMsIHJlc3VsdFNlbGVjdG9yKS5jb25jYXQoKTtcclxuICB9O1xyXG5cclxuICAgLyoqXHJcbiAgICogIFJlcGVhdHMgc291cmNlIGFzIGxvbmcgYXMgY29uZGl0aW9uIGhvbGRzIGVtdWxhdGluZyBhIHdoaWxlIGxvb3AuXHJcbiAgICogVGhlcmUgaXMgYW4gYWxpYXMgZm9yIHRoaXMgbWV0aG9kIGNhbGxlZCAnd2hpbGVEbycgZm9yIGJyb3dzZXJzIDxJRTlcclxuICAgKlxyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGNvbmRpdGlvbiBUaGUgY29uZGl0aW9uIHdoaWNoIGRldGVybWluZXMgaWYgdGhlIHNvdXJjZSB3aWxsIGJlIHJlcGVhdGVkLlxyXG4gICAqIEBwYXJhbSB7T2JzZXJ2YWJsZX0gc291cmNlIFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgd2lsbCBiZSBydW4gaWYgdGhlIGNvbmRpdGlvbiBmdW5jdGlvbiByZXR1cm5zIHRydWUuXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2Ugd2hpY2ggaXMgcmVwZWF0ZWQgYXMgbG9uZyBhcyB0aGUgY29uZGl0aW9uIGhvbGRzLiAgXHJcbiAgICovXHJcbiAgdmFyIG9ic2VydmFibGVXaGlsZURvID0gT2JzZXJ2YWJsZVsnd2hpbGUnXSA9IE9ic2VydmFibGUud2hpbGVEbyA9IGZ1bmN0aW9uIChjb25kaXRpb24sIHNvdXJjZSkge1xyXG4gICAgaXNQcm9taXNlKHNvdXJjZSkgJiYgKHNvdXJjZSA9IG9ic2VydmFibGVGcm9tUHJvbWlzZShzb3VyY2UpKTtcclxuICAgIHJldHVybiBlbnVtZXJhYmxlV2hpbGUoY29uZGl0aW9uLCBzb3VyY2UpLmNvbmNhdCgpO1xyXG4gIH07XHJcblxyXG4gICAgIC8qKlxyXG4gICAgICogIFJlcGVhdHMgc291cmNlIGFzIGxvbmcgYXMgY29uZGl0aW9uIGhvbGRzIGVtdWxhdGluZyBhIGRvIHdoaWxlIGxvb3AuXHJcbiAgICAgKlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29uZGl0aW9uIFRoZSBjb25kaXRpb24gd2hpY2ggZGV0ZXJtaW5lcyBpZiB0aGUgc291cmNlIHdpbGwgYmUgcmVwZWF0ZWQuXHJcbiAgICAgKiBAcGFyYW0ge09ic2VydmFibGV9IHNvdXJjZSBUaGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IHdpbGwgYmUgcnVuIGlmIHRoZSBjb25kaXRpb24gZnVuY3Rpb24gcmV0dXJucyB0cnVlLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2Ugd2hpY2ggaXMgcmVwZWF0ZWQgYXMgbG9uZyBhcyB0aGUgY29uZGl0aW9uIGhvbGRzLiBcclxuICAgICAqLyBcclxuICAgIG9ic2VydmFibGVQcm90by5kb1doaWxlID0gZnVuY3Rpb24gKGNvbmRpdGlvbikge1xyXG4gICAgICAgIHJldHVybiBvYnNlcnZhYmxlQ29uY2F0KFt0aGlzLCBvYnNlcnZhYmxlV2hpbGVEbyhjb25kaXRpb24sIHRoaXMpXSk7XHJcbiAgICB9O1xyXG5cclxuICAgLyoqXHJcbiAgICogIFVzZXMgc2VsZWN0b3IgdG8gZGV0ZXJtaW5lIHdoaWNoIHNvdXJjZSBpbiBzb3VyY2VzIHRvIHVzZS5cclxuICAgKiAgVGhlcmUgaXMgYW4gYWxpYXMgJ3N3aXRjaENhc2UnIGZvciBicm93c2VycyA8SUU5LlxyXG4gICAqICBcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqICAxIC0gcmVzID0gUnguT2JzZXJ2YWJsZS5jYXNlKHNlbGVjdG9yLCB7ICcxJzogb2JzMSwgJzInOiBvYnMyIH0pO1xyXG4gICAqICAxIC0gcmVzID0gUnguT2JzZXJ2YWJsZS5jYXNlKHNlbGVjdG9yLCB7ICcxJzogb2JzMSwgJzInOiBvYnMyIH0sIG9iczApO1xyXG4gICAqICAxIC0gcmVzID0gUnguT2JzZXJ2YWJsZS5jYXNlKHNlbGVjdG9yLCB7ICcxJzogb2JzMSwgJzInOiBvYnMyIH0sIHNjaGVkdWxlcik7XHJcbiAgICogXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZWN0b3IgVGhlIGZ1bmN0aW9uIHdoaWNoIGV4dHJhY3RzIHRoZSB2YWx1ZSBmb3IgdG8gdGVzdCBpbiBhIGNhc2Ugc3RhdGVtZW50LlxyXG4gICAqIEBwYXJhbSB7QXJyYXl9IHNvdXJjZXMgQSBvYmplY3Qgd2hpY2ggaGFzIGtleXMgd2hpY2ggY29ycmVzcG9uZCB0byB0aGUgY2FzZSBzdGF0ZW1lbnQgbGFiZWxzLlxyXG4gICAqIEBwYXJhbSB7T2JzZXJ2YWJsZX0gW2Vsc2VTb3VyY2VdIFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIG9yIFByb21pc2UgdGhhdCB3aWxsIGJlIHJ1biBpZiB0aGUgc291cmNlcyBhcmUgbm90IG1hdGNoZWQuIElmIHRoaXMgaXMgbm90IHByb3ZpZGVkLCBpdCBkZWZhdWx0cyB0byBSeC5PYnNlcnZhYmUuZW1wdHkgd2l0aCB0aGUgc3BlY2lmaWVkIHNjaGVkdWxlci5cclxuICAgKiAgICAgICBcclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aGljaCBpcyBkZXRlcm1pbmVkIGJ5IGEgY2FzZSBzdGF0ZW1lbnQuICBcclxuICAgKi9cclxuICBPYnNlcnZhYmxlWydjYXNlJ10gPSBPYnNlcnZhYmxlLnN3aXRjaENhc2UgPSBmdW5jdGlvbiAoc2VsZWN0b3IsIHNvdXJjZXMsIGRlZmF1bHRTb3VyY2VPclNjaGVkdWxlcikge1xyXG4gICAgcmV0dXJuIG9ic2VydmFibGVEZWZlcihmdW5jdGlvbiAoKSB7XHJcbiAgICAgIGRlZmF1bHRTb3VyY2VPclNjaGVkdWxlciB8fCAoZGVmYXVsdFNvdXJjZU9yU2NoZWR1bGVyID0gb2JzZXJ2YWJsZUVtcHR5KCkpO1xyXG5cclxuICAgICAgdHlwZW9mIGRlZmF1bHRTb3VyY2VPclNjaGVkdWxlci5ub3cgPT09ICdmdW5jdGlvbicgJiYgKGRlZmF1bHRTb3VyY2VPclNjaGVkdWxlciA9IG9ic2VydmFibGVFbXB0eShkZWZhdWx0U291cmNlT3JTY2hlZHVsZXIpKTtcclxuICAgICAgXHJcbiAgICAgIHZhciByZXN1bHQgPSBzb3VyY2VzW3NlbGVjdG9yKCldO1xyXG4gICAgICBpc1Byb21pc2UocmVzdWx0KSAmJiAocmVzdWx0ID0gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKHJlc3VsdCkpO1xyXG4gICAgICBcclxuICAgICAgcmV0dXJuIHJlc3VsdCB8fCBkZWZhdWx0U291cmNlT3JTY2hlZHVsZXI7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAgICAvKipcclxuICAgICAqICBFeHBhbmRzIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgYnkgcmVjdXJzaXZlbHkgaW52b2tpbmcgc2VsZWN0b3IuXHJcbiAgICAgKiAgXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxlY3RvciBTZWxlY3RvciBmdW5jdGlvbiB0byBpbnZva2UgZm9yIGVhY2ggcHJvZHVjZWQgZWxlbWVudCwgcmVzdWx0aW5nIGluIGFub3RoZXIgc2VxdWVuY2UgdG8gd2hpY2ggdGhlIHNlbGVjdG9yIHdpbGwgYmUgaW52b2tlZCByZWN1cnNpdmVseSBhZ2Fpbi5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSBTY2hlZHVsZXIgb24gd2hpY2ggdG8gcGVyZm9ybSB0aGUgZXhwYW5zaW9uLiBJZiBub3QgcHJvdmlkZWQsIHRoaXMgZGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgdGhyZWFkIHNjaGVkdWxlci5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGNvbnRhaW5pbmcgYWxsIHRoZSBlbGVtZW50cyBwcm9kdWNlZCBieSB0aGUgcmVjdXJzaXZlIGV4cGFuc2lvbi5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmV4cGFuZCA9IGZ1bmN0aW9uIChzZWxlY3Rvciwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSBpbW1lZGlhdGVTY2hlZHVsZXIpO1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIHEgPSBbXSxcclxuICAgICAgICAgICAgICAgIG0gPSBuZXcgU2VyaWFsRGlzcG9zYWJsZSgpLFxyXG4gICAgICAgICAgICAgICAgZCA9IG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKG0pLFxyXG4gICAgICAgICAgICAgICAgYWN0aXZlQ291bnQgPSAwLFxyXG4gICAgICAgICAgICAgICAgaXNBY3F1aXJlZCA9IGZhbHNlO1xyXG5cclxuICAgICAgICAgICAgdmFyIGVuc3VyZUFjdGl2ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBpc093bmVyID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBpZiAocS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaXNPd25lciA9ICFpc0FjcXVpcmVkO1xyXG4gICAgICAgICAgICAgICAgICAgIGlzQWNxdWlyZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGlzT3duZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICBtLnNldERpc3Bvc2FibGUoc2NoZWR1bGVyLnNjaGVkdWxlUmVjdXJzaXZlKGZ1bmN0aW9uIChzZWxmKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciB3b3JrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAocS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB3b3JrID0gcS5zaGlmdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNBY3F1aXJlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBtMSA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkLmFkZChtMSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG0xLnNldERpc3Bvc2FibGUod29yay5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhciByZXN1bHQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBzZWxlY3Rvcih4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcS5wdXNoKHJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVDb3VudCsrO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5zdXJlQWN0aXZlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGQucmVtb3ZlKG0xKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdGl2ZUNvdW50LS07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYWN0aXZlQ291bnQgPT09IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYoKTtcclxuICAgICAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBxLnB1c2goc291cmNlKTtcclxuICAgICAgICAgICAgYWN0aXZlQ291bnQrKztcclxuICAgICAgICAgICAgZW5zdXJlQWN0aXZlKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBkO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgIC8qKlxyXG4gICAqICBSdW5zIGFsbCBvYnNlcnZhYmxlIHNlcXVlbmNlcyBpbiBwYXJhbGxlbCBhbmQgY29sbGVjdCB0aGVpciBsYXN0IGVsZW1lbnRzLlxyXG4gICAqICBcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqICAxIC0gcmVzID0gUnguT2JzZXJ2YWJsZS5mb3JrSm9pbihbb2JzMSwgb2JzMl0pO1xyXG4gICAqICAxIC0gcmVzID0gUnguT2JzZXJ2YWJsZS5mb3JrSm9pbihvYnMxLCBvYnMyLCAuLi4pOyAgXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2Ugd2l0aCBhbiBhcnJheSBjb2xsZWN0aW5nIHRoZSBsYXN0IGVsZW1lbnRzIG9mIGFsbCB0aGUgaW5wdXQgc2VxdWVuY2VzLlxyXG4gICAqL1xyXG4gIE9ic2VydmFibGUuZm9ya0pvaW4gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICB2YXIgYWxsU291cmNlcyA9IGFyZ3NPckFycmF5KGFyZ3VtZW50cywgMCk7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKHN1YnNjcmliZXIpIHtcclxuICAgICAgdmFyIGNvdW50ID0gYWxsU291cmNlcy5sZW5ndGg7XHJcbiAgICAgIGlmIChjb3VudCA9PT0gMCkge1xyXG4gICAgICAgIHN1YnNjcmliZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICByZXR1cm4gZGlzcG9zYWJsZUVtcHR5O1xyXG4gICAgICB9XHJcbiAgICAgIHZhciBncm91cCA9IG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKCksXHJcbiAgICAgICAgZmluaXNoZWQgPSBmYWxzZSxcclxuICAgICAgICBoYXNSZXN1bHRzID0gbmV3IEFycmF5KGNvdW50KSxcclxuICAgICAgICBoYXNDb21wbGV0ZWQgPSBuZXcgQXJyYXkoY291bnQpLFxyXG4gICAgICAgIHJlc3VsdHMgPSBuZXcgQXJyYXkoY291bnQpO1xyXG5cclxuICAgICAgZm9yICh2YXIgaWR4ID0gMDsgaWR4IDwgY291bnQ7IGlkeCsrKSB7XHJcbiAgICAgICAgKGZ1bmN0aW9uIChpKSB7XHJcbiAgICAgICAgICB2YXIgc291cmNlID0gYWxsU291cmNlc1tpXTtcclxuICAgICAgICAgIGlzUHJvbWlzZShzb3VyY2UpICYmIChzb3VyY2UgPSBvYnNlcnZhYmxlRnJvbVByb21pc2Uoc291cmNlKSk7XHJcbiAgICAgICAgICBncm91cC5hZGQoXHJcbiAgICAgICAgICAgIHNvdXJjZS5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAgZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgaWYgKCFmaW5pc2hlZCkge1xyXG4gICAgICAgICAgICAgICAgaGFzUmVzdWx0c1tpXSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICByZXN1bHRzW2ldID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBcclxuICAgICAgICAgICAgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICBmaW5pc2hlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgc3Vic2NyaWJlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgIGdyb3VwLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgfSwgXHJcbiAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICBpZiAoIWZpbmlzaGVkKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWhhc1Jlc3VsdHNbaV0pIHtcclxuICAgICAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaGFzQ29tcGxldGVkW2ldID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGl4ID0gMDsgaXggPCBjb3VudDsgaXgrKykge1xyXG4gICAgICAgICAgICAgICAgICBpZiAoIWhhc0NvbXBsZXRlZFtpeF0pIHsgcmV0dXJuOyB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBmaW5pc2hlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBzdWJzY3JpYmVyLm9uTmV4dChyZXN1bHRzKTtcclxuICAgICAgICAgICAgICAgIHN1YnNjcmliZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pKTtcclxuICAgICAgICB9KShpZHgpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICByZXR1cm4gZ3JvdXA7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAgLyoqXHJcbiAgICogIFJ1bnMgdHdvIG9ic2VydmFibGUgc2VxdWVuY2VzIGluIHBhcmFsbGVsIGFuZCBjb21iaW5lcyB0aGVpciBsYXN0IGVsZW1lbmV0cy5cclxuICAgKlxyXG4gICAqIEBwYXJhbSB7T2JzZXJ2YWJsZX0gc2Vjb25kIFNlY29uZCBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlc3VsdFNlbGVjdG9yIFJlc3VsdCBzZWxlY3RvciBmdW5jdGlvbiB0byBpbnZva2Ugd2l0aCB0aGUgbGFzdCBlbGVtZW50cyBvZiBib3RoIHNlcXVlbmNlcy5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aXRoIHRoZSByZXN1bHQgb2YgY2FsbGluZyB0aGUgc2VsZWN0b3IgZnVuY3Rpb24gd2l0aCB0aGUgbGFzdCBlbGVtZW50cyBvZiBib3RoIGlucHV0IHNlcXVlbmNlcy5cclxuICAgKi9cclxuICBvYnNlcnZhYmxlUHJvdG8uZm9ya0pvaW4gPSBmdW5jdGlvbiAoc2Vjb25kLCByZXN1bHRTZWxlY3Rvcikge1xyXG4gICAgdmFyIGZpcnN0ID0gdGhpcztcclxuXHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciBsZWZ0U3RvcHBlZCA9IGZhbHNlLCByaWdodFN0b3BwZWQgPSBmYWxzZSxcclxuICAgICAgICBoYXNMZWZ0ID0gZmFsc2UsIGhhc1JpZ2h0ID0gZmFsc2UsXHJcbiAgICAgICAgbGFzdExlZnQsIGxhc3RSaWdodCxcclxuICAgICAgICBsZWZ0U3Vic2NyaXB0aW9uID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCksIHJpZ2h0U3Vic2NyaXB0aW9uID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCk7XHJcblxyXG4gICAgICBpc1Byb21pc2Uoc2Vjb25kKSAmJiAoc2Vjb25kID0gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKHNlY29uZCkpO1xyXG5cclxuICAgICAgbGVmdFN1YnNjcmlwdGlvbi5zZXREaXNwb3NhYmxlKFxyXG4gICAgICAgICAgZmlyc3Quc3Vic2NyaWJlKGZ1bmN0aW9uIChsZWZ0KSB7XHJcbiAgICAgICAgICAgIGhhc0xlZnQgPSB0cnVlO1xyXG4gICAgICAgICAgICBsYXN0TGVmdCA9IGxlZnQ7XHJcbiAgICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICAgIHJpZ2h0U3Vic2NyaXB0aW9uLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlcnIpO1xyXG4gICAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBsZWZ0U3RvcHBlZCA9IHRydWU7XHJcbiAgICAgICAgICAgIGlmIChyaWdodFN0b3BwZWQpIHtcclxuICAgICAgICAgICAgICBpZiAoIWhhc0xlZnQpIHtcclxuICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICB9IGVsc2UgaWYgKCFoYXNSaWdodCkge1xyXG4gICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgcmVzdWx0O1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0U2VsZWN0b3IobGFzdExlZnQsIGxhc3RSaWdodCk7XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChyZXN1bHQpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH0pXHJcbiAgICAgICk7XHJcblxyXG4gICAgICByaWdodFN1YnNjcmlwdGlvbi5zZXREaXNwb3NhYmxlKFxyXG4gICAgICAgIHNlY29uZC5zdWJzY3JpYmUoZnVuY3Rpb24gKHJpZ2h0KSB7XHJcbiAgICAgICAgICBoYXNSaWdodCA9IHRydWU7XHJcbiAgICAgICAgICBsYXN0UmlnaHQgPSByaWdodDtcclxuICAgICAgICB9LCBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgICBsZWZ0U3Vic2NyaXB0aW9uLmRpc3Bvc2UoKTtcclxuICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXJyKTtcclxuICAgICAgICB9LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICByaWdodFN0b3BwZWQgPSB0cnVlO1xyXG4gICAgICAgICAgaWYgKGxlZnRTdG9wcGVkKSB7XHJcbiAgICAgICAgICAgIGlmICghaGFzTGVmdCkge1xyXG4gICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoIWhhc1JpZ2h0KSB7XHJcbiAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICB2YXIgcmVzdWx0O1xyXG4gICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHRTZWxlY3RvcihsYXN0TGVmdCwgbGFzdFJpZ2h0KTtcclxuICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuO1xyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQocmVzdWx0KTtcclxuICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSlcclxuICAgICAgKTtcclxuXHJcbiAgICAgIHJldHVybiBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZShsZWZ0U3Vic2NyaXB0aW9uLCByaWdodFN1YnNjcmlwdGlvbik7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ29tb25hZGljIGJpbmQgb3BlcmF0b3IuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBzZWxlY3RvciBBIHRyYW5zZm9ybSBmdW5jdGlvbiB0byBhcHBseSB0byBlYWNoIGVsZW1lbnQuXHJcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gc2NoZWR1bGVyIFNjaGVkdWxlciB1c2VkIHRvIGV4ZWN1dGUgdGhlIG9wZXJhdGlvbi4gSWYgbm90IHNwZWNpZmllZCwgZGVmYXVsdHMgdG8gdGhlIEltbWVkaWF0ZVNjaGVkdWxlci5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdoaWNoIHJlc3VsdHMgZnJvbSB0aGUgY29tb25hZGljIGJpbmQgb3BlcmF0aW9uLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8ubWFueVNlbGVjdCA9IGZ1bmN0aW9uIChzZWxlY3Rvciwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSBpbW1lZGlhdGVTY2hlZHVsZXIpO1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBvYnNlcnZhYmxlRGVmZXIoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgY2hhaW47XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gc291cmNlXHJcbiAgICAgICAgICAgICAgICAuc2VsZWN0KFxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBjdXJyID0gbmV3IENoYWluT2JzZXJ2YWJsZSh4KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNoYWluKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFpbi5vbk5leHQoeCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW4gPSBjdXJyO1xyXG5cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGN1cnI7XHJcbiAgICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgIC5kb0FjdGlvbihcclxuICAgICAgICAgICAgICAgICAgICBub29wLFxyXG4gICAgICAgICAgICAgICAgICAgIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjaGFpbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhaW4ub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY2hhaW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYWluLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9KVxyXG4gICAgICAgICAgICAgICAgLm9ic2VydmVPbihzY2hlZHVsZXIpXHJcbiAgICAgICAgICAgICAgICAuc2VsZWN0KGZ1bmN0aW9uICh4LCBpLCBvKSB7IHJldHVybiBzZWxlY3Rvcih4LCBpLCBvKTsgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIHZhciBDaGFpbk9ic2VydmFibGUgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBzdWJzY3JpYmUgKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcywgZyA9IG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKCk7XHJcbiAgICAgICAgICAgIGcuYWRkKGN1cnJlbnRUaHJlYWRTY2hlZHVsZXIuc2NoZWR1bGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHNlbGYuaGVhZCk7XHJcbiAgICAgICAgICAgICAgICBnLmFkZChzZWxmLnRhaWwubWVyZ2VPYnNlcnZhYmxlKCkuc3Vic2NyaWJlKG9ic2VydmVyKSk7XHJcbiAgICAgICAgICAgIH0pKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBnO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaW5oZXJpdHMoQ2hhaW5PYnNlcnZhYmxlLCBfc3VwZXIpO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBDaGFpbk9ic2VydmFibGUoaGVhZCkge1xyXG4gICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBzdWJzY3JpYmUpO1xyXG4gICAgICAgICAgICB0aGlzLmhlYWQgPSBoZWFkO1xyXG4gICAgICAgICAgICB0aGlzLnRhaWwgPSBuZXcgQXN5bmNTdWJqZWN0KCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBhZGRQcm9wZXJ0aWVzKENoYWluT2JzZXJ2YWJsZS5wcm90b3R5cGUsIE9ic2VydmVyLCB7XHJcbiAgICAgICAgICAgIG9uQ29tcGxldGVkOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9uTmV4dChPYnNlcnZhYmxlLmVtcHR5KCkpO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICBvbkVycm9yOiBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbk5leHQoT2JzZXJ2YWJsZS50aHJvd0V4Y2VwdGlvbihlKSk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIG9uTmV4dDogZnVuY3Rpb24gKHYpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMudGFpbC5vbk5leHQodik7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnRhaWwub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gQ2hhaW5PYnNlcnZhYmxlO1xyXG5cclxuICAgIH0oT2JzZXJ2YWJsZSkpO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgdmFyIE1hcCA9IChmdW5jdGlvbiAoKSB7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZnVuY3Rpb24gTWFwKCkge1xyXG4gICAgICAgICAgICB0aGlzLmtleXMgPSBbXTtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZXMgPSBbXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICogQG1lbWJlck9mIE1hcCNcclxuICAgICAgICAgKi9cclxuICAgICAgICBNYXAucHJvdG90eXBlWydkZWxldGUnXSA9IGZ1bmN0aW9uIChrZXkpIHtcclxuICAgICAgICAgICAgdmFyIGkgPSB0aGlzLmtleXMuaW5kZXhPZihrZXkpO1xyXG4gICAgICAgICAgICBpZiAoaSAhPT0gLTEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMua2V5cy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlcy5zcGxpY2UoaSwgMSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGkgIT09IC0xO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICogQG1lbWJlck9mIE1hcCNcclxuICAgICAgICAgKi9cclxuICAgICAgICBNYXAucHJvdG90eXBlLmdldCA9IGZ1bmN0aW9uIChrZXksIGZhbGxiYWNrKSB7XHJcbiAgICAgICAgICAgIHZhciBpID0gdGhpcy5rZXlzLmluZGV4T2Yoa2V5KTtcclxuICAgICAgICAgICAgcmV0dXJuIGkgIT09IC0xID8gdGhpcy52YWx1ZXNbaV0gOiBmYWxsYmFjaztcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqIEBtZW1iZXJPZiBNYXAjXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgTWFwLnByb3RvdHlwZS5zZXQgPSBmdW5jdGlvbiAoa2V5LCB2YWx1ZSkge1xyXG4gICAgICAgICAgICB2YXIgaSA9IHRoaXMua2V5cy5pbmRleE9mKGtleSk7XHJcbiAgICAgICAgICAgIGlmIChpICE9PSAtMSkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy52YWx1ZXNbaV0gPSB2YWx1ZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLnZhbHVlc1t0aGlzLmtleXMucHVzaChrZXkpIC0gMV0gPSB2YWx1ZTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqIEBtZW1iZXJPZiBNYXAjXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgTWFwLnByb3RvdHlwZS5zaXplID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy5rZXlzLmxlbmd0aDsgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKiBAbWVtYmVyT2YgTWFwI1xyXG4gICAgICAgICAqLyAgICAgICAgXHJcbiAgICAgICAgTWFwLnByb3RvdHlwZS5oYXMgPSBmdW5jdGlvbiAoa2V5KSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmtleXMuaW5kZXhPZihrZXkpICE9PSAtMTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqIEBtZW1iZXJPZiBNYXAjXHJcbiAgICAgICAgICovICAgICAgICBcclxuICAgICAgICBNYXAucHJvdG90eXBlLmdldEtleXMgPSBmdW5jdGlvbiAoKSB7IHJldHVybiB0aGlzLmtleXMuc2xpY2UoMCk7IH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICogQG1lbWJlck9mIE1hcCNcclxuICAgICAgICAgKi8gICAgICAgIFxyXG4gICAgICAgIE1hcC5wcm90b3R5cGUuZ2V0VmFsdWVzID0gZnVuY3Rpb24gKCkgeyByZXR1cm4gdGhpcy52YWx1ZXMuc2xpY2UoMCk7IH07XHJcblxyXG4gICAgICAgIHJldHVybiBNYXA7XHJcbiAgICB9KCkpO1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBSZXByZXNlbnRzIGEgam9pbiBwYXR0ZXJuIG92ZXIgb2JzZXJ2YWJsZSBzZXF1ZW5jZXMuXHJcbiAgICAgKi9cclxuICAgIGZ1bmN0aW9uIFBhdHRlcm4ocGF0dGVybnMpIHtcclxuICAgICAgICB0aGlzLnBhdHRlcm5zID0gcGF0dGVybnM7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgQ3JlYXRlcyBhIHBhdHRlcm4gdGhhdCBtYXRjaGVzIHRoZSBjdXJyZW50IHBsYW4gbWF0Y2hlcyBhbmQgd2hlbiB0aGUgc3BlY2lmaWVkIG9ic2VydmFibGUgc2VxdWVuY2VzIGhhcyBhbiBhdmFpbGFibGUgdmFsdWUuXHJcbiAgICAgKiAgXHJcbiAgICAgKiAgQHBhcmFtIG90aGVyIE9ic2VydmFibGUgc2VxdWVuY2UgdG8gbWF0Y2ggaW4gYWRkaXRpb24gdG8gdGhlIGN1cnJlbnQgcGF0dGVybi5cclxuICAgICAqICBAcmV0dXJuIFBhdHRlcm4gb2JqZWN0IHRoYXQgbWF0Y2hlcyB3aGVuIGFsbCBvYnNlcnZhYmxlIHNlcXVlbmNlcyBpbiB0aGUgcGF0dGVybiBoYXZlIGFuIGF2YWlsYWJsZSB2YWx1ZS4gICBcclxuICAgICAqLyBcclxuICAgIFBhdHRlcm4ucHJvdG90eXBlLmFuZCA9IGZ1bmN0aW9uIChvdGhlcikge1xyXG4gICAgICAgIHZhciBwYXR0ZXJucyA9IHRoaXMucGF0dGVybnMuc2xpY2UoMCk7XHJcbiAgICAgICAgcGF0dGVybnMucHVzaChvdGhlcik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQYXR0ZXJuKHBhdHRlcm5zKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgTWF0Y2hlcyB3aGVuIGFsbCBvYnNlcnZhYmxlIHNlcXVlbmNlcyBpbiB0aGUgcGF0dGVybiAoc3BlY2lmaWVkIHVzaW5nIGEgY2hhaW4gb2YgYW5kIG9wZXJhdG9ycykgaGF2ZSBhbiBhdmFpbGFibGUgdmFsdWUgYW5kIHByb2plY3RzIHRoZSB2YWx1ZXMuXHJcbiAgICAgKiAgXHJcbiAgICAgKiAgQHBhcmFtIHNlbGVjdG9yIFNlbGVjdG9yIHRoYXQgd2lsbCBiZSBpbnZva2VkIHdpdGggYXZhaWxhYmxlIHZhbHVlcyBmcm9tIHRoZSBzb3VyY2Ugc2VxdWVuY2VzLCBpbiB0aGUgc2FtZSBvcmRlciBvZiB0aGUgc2VxdWVuY2VzIGluIHRoZSBwYXR0ZXJuLlxyXG4gICAgICogIEByZXR1cm4gUGxhbiB0aGF0IHByb2R1Y2VzIHRoZSBwcm9qZWN0ZWQgdmFsdWVzLCB0byBiZSBmZWQgKHdpdGggb3RoZXIgcGxhbnMpIHRvIHRoZSB3aGVuIG9wZXJhdG9yLlxyXG4gICAgICovXHJcbiAgICBQYXR0ZXJuLnByb3RvdHlwZS50aGVuID0gZnVuY3Rpb24gKHNlbGVjdG9yKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBQbGFuKHRoaXMsIHNlbGVjdG9yKTtcclxuICAgIH07XHJcblxyXG4gICAgZnVuY3Rpb24gUGxhbihleHByZXNzaW9uLCBzZWxlY3Rvcikge1xyXG4gICAgICAgIHRoaXMuZXhwcmVzc2lvbiA9IGV4cHJlc3Npb247XHJcbiAgICAgICAgdGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xyXG4gICAgfVxyXG4gICAgXHJcbiAgICBQbGFuLnByb3RvdHlwZS5hY3RpdmF0ZSA9IGZ1bmN0aW9uIChleHRlcm5hbFN1YnNjcmlwdGlvbnMsIG9ic2VydmVyLCBkZWFjdGl2YXRlKSB7XHJcbiAgICAgICAgdmFyIHNlbGYgPSB0aGlzO1xyXG4gICAgICAgIHZhciBqb2luT2JzZXJ2ZXJzID0gW107XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMuZXhwcmVzc2lvbi5wYXR0ZXJucy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICBqb2luT2JzZXJ2ZXJzLnB1c2gocGxhbkNyZWF0ZU9ic2VydmVyKGV4dGVybmFsU3Vic2NyaXB0aW9ucywgdGhpcy5leHByZXNzaW9uLnBhdHRlcm5zW2ldLCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHZhciBhY3RpdmVQbGFuID0gbmV3IEFjdGl2ZVBsYW4oam9pbk9ic2VydmVycywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgcmVzdWx0O1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgcmVzdWx0ID0gc2VsZi5zZWxlY3Rvci5hcHBseShzZWxmLCBhcmd1bWVudHMpO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChleGNlcHRpb24pIHtcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXhjZXB0aW9uKTtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBvYnNlcnZlci5vbk5leHQocmVzdWx0KTtcclxuICAgICAgICB9LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIGZvciAodmFyIGogPSAwLCBqbGVuID0gam9pbk9ic2VydmVycy5sZW5ndGg7IGogPCBqbGVuOyBqKyspIHtcclxuICAgICAgICAgICAgICAgIGpvaW5PYnNlcnZlcnNbal0ucmVtb3ZlQWN0aXZlUGxhbihhY3RpdmVQbGFuKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBkZWFjdGl2YXRlKGFjdGl2ZVBsYW4pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IGpvaW5PYnNlcnZlcnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgam9pbk9ic2VydmVyc1tpXS5hZGRBY3RpdmVQbGFuKGFjdGl2ZVBsYW4pO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYWN0aXZlUGxhbjtcclxuICAgIH07XHJcblxyXG4gICAgZnVuY3Rpb24gcGxhbkNyZWF0ZU9ic2VydmVyKGV4dGVybmFsU3Vic2NyaXB0aW9ucywgb2JzZXJ2YWJsZSwgb25FcnJvcikge1xyXG4gICAgICAgIHZhciBlbnRyeSA9IGV4dGVybmFsU3Vic2NyaXB0aW9ucy5nZXQob2JzZXJ2YWJsZSk7XHJcbiAgICAgICAgaWYgKCFlbnRyeSkge1xyXG4gICAgICAgICAgICB2YXIgb2JzZXJ2ZXIgPSBuZXcgSm9pbk9ic2VydmVyKG9ic2VydmFibGUsIG9uRXJyb3IpO1xyXG4gICAgICAgICAgICBleHRlcm5hbFN1YnNjcmlwdGlvbnMuc2V0KG9ic2VydmFibGUsIG9ic2VydmVyKTtcclxuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZW50cnk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQWN0aXZlIFBsYW5cclxuICAgIGZ1bmN0aW9uIEFjdGl2ZVBsYW4oam9pbk9ic2VydmVyQXJyYXksIG9uTmV4dCwgb25Db21wbGV0ZWQpIHtcclxuICAgICAgICB2YXIgaSwgam9pbk9ic2VydmVyO1xyXG4gICAgICAgIHRoaXMuam9pbk9ic2VydmVyQXJyYXkgPSBqb2luT2JzZXJ2ZXJBcnJheTtcclxuICAgICAgICB0aGlzLm9uTmV4dCA9IG9uTmV4dDtcclxuICAgICAgICB0aGlzLm9uQ29tcGxldGVkID0gb25Db21wbGV0ZWQ7XHJcbiAgICAgICAgdGhpcy5qb2luT2JzZXJ2ZXJzID0gbmV3IE1hcCgpO1xyXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCB0aGlzLmpvaW5PYnNlcnZlckFycmF5Lmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgIGpvaW5PYnNlcnZlciA9IHRoaXMuam9pbk9ic2VydmVyQXJyYXlbaV07XHJcbiAgICAgICAgICAgIHRoaXMuam9pbk9ic2VydmVycy5zZXQoam9pbk9ic2VydmVyLCBqb2luT2JzZXJ2ZXIpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBBY3RpdmVQbGFuLnByb3RvdHlwZS5kZXF1ZXVlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciB2YWx1ZXMgPSB0aGlzLmpvaW5PYnNlcnZlcnMuZ2V0VmFsdWVzKCk7XHJcbiAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHZhbHVlcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICB2YWx1ZXNbaV0ucXVldWUuc2hpZnQoKTtcclxuICAgICAgICB9XHJcbiAgICB9O1xyXG4gICAgQWN0aXZlUGxhbi5wcm90b3R5cGUubWF0Y2ggPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIGZpcnN0VmFsdWVzLCBpLCBsZW4sIGlzQ29tcGxldGVkLCB2YWx1ZXMsIGhhc1ZhbHVlcyA9IHRydWU7XHJcbiAgICAgICAgZm9yIChpID0gMCwgbGVuID0gdGhpcy5qb2luT2JzZXJ2ZXJBcnJheS5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5qb2luT2JzZXJ2ZXJBcnJheVtpXS5xdWV1ZS5sZW5ndGggPT09IDApIHtcclxuICAgICAgICAgICAgICAgIGhhc1ZhbHVlcyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGhhc1ZhbHVlcykge1xyXG4gICAgICAgICAgICBmaXJzdFZhbHVlcyA9IFtdO1xyXG4gICAgICAgICAgICBpc0NvbXBsZXRlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSB0aGlzLmpvaW5PYnNlcnZlckFycmF5Lmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBmaXJzdFZhbHVlcy5wdXNoKHRoaXMuam9pbk9ic2VydmVyQXJyYXlbaV0ucXVldWVbMF0pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuam9pbk9ic2VydmVyQXJyYXlbaV0ucXVldWVbMF0ua2luZCA9PT0gJ0MnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaXNDb21wbGV0ZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmIChpc0NvbXBsZXRlZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5kZXF1ZXVlKCk7XHJcbiAgICAgICAgICAgICAgICB2YWx1ZXMgPSBbXTtcclxuICAgICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBmaXJzdFZhbHVlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlcy5wdXNoKGZpcnN0VmFsdWVzW2ldLnZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMub25OZXh0LmFwcGx5KHRoaXMsIHZhbHVlcyk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgdmFyIEpvaW5PYnNlcnZlciA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcblxyXG4gICAgICAgIGluaGVyaXRzKEpvaW5PYnNlcnZlciwgX3N1cGVyKTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbiBKb2luT2JzZXJ2ZXIoc291cmNlLCBvbkVycm9yKSB7XHJcbiAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTtcclxuICAgICAgICAgICAgdGhpcy5vbkVycm9yID0gb25FcnJvcjtcclxuICAgICAgICAgICAgdGhpcy5xdWV1ZSA9IFtdO1xyXG4gICAgICAgICAgICB0aGlzLmFjdGl2ZVBsYW5zID0gW107XHJcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCk7XHJcbiAgICAgICAgICAgIHRoaXMuaXNEaXNwb3NlZCA9IGZhbHNlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIEpvaW5PYnNlcnZlclByb3RvdHlwZSA9IEpvaW5PYnNlcnZlci5wcm90b3R5cGU7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBtZW1iZXJPZiBKb2luT2JzZXJ2ZXIjXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBKb2luT2JzZXJ2ZXJQcm90b3R5cGUubmV4dCA9IGZ1bmN0aW9uIChub3RpZmljYXRpb24pIHtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzRGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgICAgIGlmIChub3RpZmljYXRpb24ua2luZCA9PT0gJ0UnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5vbkVycm9yKG5vdGlmaWNhdGlvbi5leGNlcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMucXVldWUucHVzaChub3RpZmljYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgdmFyIGFjdGl2ZVBsYW5zID0gdGhpcy5hY3RpdmVQbGFucy5zbGljZSgwKTtcclxuICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBhY3RpdmVQbGFucy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIGFjdGl2ZVBsYW5zW2ldLm1hdGNoKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAbWVtYmVyT2YgSm9pbk9ic2VydmVyI1xyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovICAgICAgICBcclxuICAgICAgICBKb2luT2JzZXJ2ZXJQcm90b3R5cGUuZXJyb3IgPSBub29wO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAbWVtYmVyT2YgSm9pbk9ic2VydmVyI1xyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICovICAgICAgICBcclxuICAgICAgICBKb2luT2JzZXJ2ZXJQcm90b3R5cGUuY29tcGxldGVkID0gbm9vcDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQG1lbWJlck9mIEpvaW5PYnNlcnZlciNcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEpvaW5PYnNlcnZlclByb3RvdHlwZS5hZGRBY3RpdmVQbGFuID0gZnVuY3Rpb24gKGFjdGl2ZVBsYW4pIHtcclxuICAgICAgICAgICAgdGhpcy5hY3RpdmVQbGFucy5wdXNoKGFjdGl2ZVBsYW4pO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBtZW1iZXJPZiBKb2luT2JzZXJ2ZXIjXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi8gICAgICAgIFxyXG4gICAgICAgIEpvaW5PYnNlcnZlclByb3RvdHlwZS5zdWJzY3JpYmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9uLnNldERpc3Bvc2FibGUodGhpcy5zb3VyY2UubWF0ZXJpYWxpemUoKS5zdWJzY3JpYmUodGhpcykpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBtZW1iZXJPZiBKb2luT2JzZXJ2ZXIjXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi8gICAgICAgIFxyXG4gICAgICAgIEpvaW5PYnNlcnZlclByb3RvdHlwZS5yZW1vdmVBY3RpdmVQbGFuID0gZnVuY3Rpb24gKGFjdGl2ZVBsYW4pIHtcclxuICAgICAgICAgICAgdmFyIGlkeCA9IHRoaXMuYWN0aXZlUGxhbnMuaW5kZXhPZihhY3RpdmVQbGFuKTtcclxuICAgICAgICAgICAgdGhpcy5hY3RpdmVQbGFucy5zcGxpY2UoaWR4LCAxKTtcclxuICAgICAgICAgICAgaWYgKHRoaXMuYWN0aXZlUGxhbnMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBtZW1iZXJPZiBKb2luT2JzZXJ2ZXIjXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi8gICAgICAgIFxyXG4gICAgICAgIEpvaW5PYnNlcnZlclByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzRGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaXNEaXNwb3NlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnN1YnNjcmlwdGlvbi5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9O1xyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiBKb2luT2JzZXJ2ZXI7XHJcbiAgICB9IChBYnN0cmFjdE9ic2VydmVyKSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgQ3JlYXRlcyBhIHBhdHRlcm4gdGhhdCBtYXRjaGVzIHdoZW4gYm90aCBvYnNlcnZhYmxlIHNlcXVlbmNlcyBoYXZlIGFuIGF2YWlsYWJsZSB2YWx1ZS5cclxuICAgICAqICBcclxuICAgICAqICBAcGFyYW0gcmlnaHQgT2JzZXJ2YWJsZSBzZXF1ZW5jZSB0byBtYXRjaCB3aXRoIHRoZSBjdXJyZW50IHNlcXVlbmNlLlxyXG4gICAgICogIEByZXR1cm4ge1BhdHRlcm59IFBhdHRlcm4gb2JqZWN0IHRoYXQgbWF0Y2hlcyB3aGVuIGJvdGggb2JzZXJ2YWJsZSBzZXF1ZW5jZXMgaGF2ZSBhbiBhdmFpbGFibGUgdmFsdWUuICAgICBcclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmFuZCA9IGZ1bmN0aW9uIChyaWdodCkge1xyXG4gICAgICAgIHJldHVybiBuZXcgUGF0dGVybihbdGhpcywgcmlnaHRdKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgTWF0Y2hlcyB3aGVuIHRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIGhhcyBhbiBhdmFpbGFibGUgdmFsdWUgYW5kIHByb2plY3RzIHRoZSB2YWx1ZS5cclxuICAgICAqICBcclxuICAgICAqICBAcGFyYW0gc2VsZWN0b3IgU2VsZWN0b3IgdGhhdCB3aWxsIGJlIGludm9rZWQgZm9yIHZhbHVlcyBpbiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICogIEByZXR1cm5zIHtQbGFufSBQbGFuIHRoYXQgcHJvZHVjZXMgdGhlIHByb2plY3RlZCB2YWx1ZXMsIHRvIGJlIGZlZCAod2l0aCBvdGhlciBwbGFucykgdG8gdGhlIHdoZW4gb3BlcmF0b3IuIFxyXG4gICAgICovICAgIFxyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnRoZW4gPSBmdW5jdGlvbiAoc2VsZWN0b3IpIHtcclxuICAgICAgICByZXR1cm4gbmV3IFBhdHRlcm4oW3RoaXNdKS50aGVuKHNlbGVjdG9yKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgSm9pbnMgdG9nZXRoZXIgdGhlIHJlc3VsdHMgZnJvbSBzZXZlcmFsIHBhdHRlcm5zLlxyXG4gICAgICogIFxyXG4gICAgICogIEBwYXJhbSBwbGFucyBBIHNlcmllcyBvZiBwbGFucyAoc3BlY2lmaWVkIGFzIGFuIEFycmF5IG9mIGFzIGEgc2VyaWVzIG9mIGFyZ3VtZW50cykgY3JlYXRlZCBieSB1c2Ugb2YgdGhlIFRoZW4gb3BlcmF0b3Igb24gcGF0dGVybnMuXHJcbiAgICAgKiAgQHJldHVybnMge09ic2VydmFibGV9IE9ic2VydmFibGUgc2VxdWVuY2Ugd2l0aCB0aGUgcmVzdWx0cyBmb3JtIG1hdGNoaW5nIHNldmVyYWwgcGF0dGVybnMuIFxyXG4gICAgICovXHJcbiAgICBPYnNlcnZhYmxlLndoZW4gPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdmFyIHBsYW5zID0gYXJnc09yQXJyYXkoYXJndW1lbnRzLCAwKTtcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBhY3RpdmVQbGFucyA9IFtdLFxyXG4gICAgICAgICAgICAgICAgZXh0ZXJuYWxTdWJzY3JpcHRpb25zID0gbmV3IE1hcCgpLFxyXG4gICAgICAgICAgICAgICAgZ3JvdXAsXHJcbiAgICAgICAgICAgICAgICBpLCBsZW4sXHJcbiAgICAgICAgICAgICAgICBqb2luT2JzZXJ2ZXIsXHJcbiAgICAgICAgICAgICAgICBqb2luVmFsdWVzLFxyXG4gICAgICAgICAgICAgICAgb3V0T2JzZXJ2ZXI7XHJcbiAgICAgICAgICAgIG91dE9ic2VydmVyID0gb2JzZXJ2ZXJDcmVhdGUob2JzZXJ2ZXIub25OZXh0LmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgdmFsdWVzID0gZXh0ZXJuYWxTdWJzY3JpcHRpb25zLmdldFZhbHVlcygpO1xyXG4gICAgICAgICAgICAgICAgZm9yICh2YXIgaiA9IDAsIGpsZW4gPSB2YWx1ZXMubGVuZ3RoOyBqIDwgamxlbjsgaisrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWVzW2pdLm9uRXJyb3IoZXhjZXB0aW9uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXhjZXB0aW9uKTtcclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25Db21wbGV0ZWQuYmluZChvYnNlcnZlcikpO1xyXG4gICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMCwgbGVuID0gcGxhbnMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBhY3RpdmVQbGFucy5wdXNoKHBsYW5zW2ldLmFjdGl2YXRlKGV4dGVybmFsU3Vic2NyaXB0aW9ucywgb3V0T2JzZXJ2ZXIsIGZ1bmN0aW9uIChhY3RpdmVQbGFuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBpZHggPSBhY3RpdmVQbGFucy5pbmRleE9mKGFjdGl2ZVBsYW4pO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBhY3RpdmVQbGFucy5zcGxpY2UoaWR4LCAxKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGFjdGl2ZVBsYW5zLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0T2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2YWJsZVRocm93KGUpLnN1YnNjcmliZShvYnNlcnZlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZ3JvdXAgPSBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZSgpO1xyXG4gICAgICAgICAgICBqb2luVmFsdWVzID0gZXh0ZXJuYWxTdWJzY3JpcHRpb25zLmdldFZhbHVlcygpO1xyXG4gICAgICAgICAgICBmb3IgKGkgPSAwLCBsZW4gPSBqb2luVmFsdWVzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBqb2luT2JzZXJ2ZXIgPSBqb2luVmFsdWVzW2ldO1xyXG4gICAgICAgICAgICAgICAgam9pbk9ic2VydmVyLnN1YnNjcmliZSgpO1xyXG4gICAgICAgICAgICAgICAgZ3JvdXAuYWRkKGpvaW5PYnNlcnZlcik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGdyb3VwO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICBmdW5jdGlvbiBvYnNlcnZhYmxlVGltZXJEYXRlKGR1ZVRpbWUsIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHNjaGVkdWxlci5zY2hlZHVsZVdpdGhBYnNvbHV0ZShkdWVUaW1lLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQoMCk7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgZnVuY3Rpb24gb2JzZXJ2YWJsZVRpbWVyRGF0ZUFuZFBlcmlvZChkdWVUaW1lLCBwZXJpb2QsIHNjaGVkdWxlcikge1xyXG4gICAgdmFyIHAgPSBub3JtYWxpemVUaW1lKHBlcmlvZCk7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciBjb3VudCA9IDAsIGQgPSBkdWVUaW1lO1xyXG4gICAgICByZXR1cm4gc2NoZWR1bGVyLnNjaGVkdWxlUmVjdXJzaXZlV2l0aEFic29sdXRlKGQsIGZ1bmN0aW9uIChzZWxmKSB7XHJcbiAgICAgICAgdmFyIG5vdztcclxuICAgICAgICBpZiAocCA+IDApIHtcclxuICAgICAgICAgIG5vdyA9IHNjaGVkdWxlci5ub3coKTtcclxuICAgICAgICAgIGQgPSBkICsgcDtcclxuICAgICAgICAgIGlmIChkIDw9IG5vdykge1xyXG4gICAgICAgICAgICBkID0gbm93ICsgcDtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgb2JzZXJ2ZXIub25OZXh0KGNvdW50KyspO1xyXG4gICAgICAgIHNlbGYoZCk7XHJcbiAgICAgIH0pO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIG9ic2VydmFibGVUaW1lclRpbWVTcGFuKGR1ZVRpbWUsIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHZhciBkID0gbm9ybWFsaXplVGltZShkdWVUaW1lKTtcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBzY2hlZHVsZXIuc2NoZWR1bGVXaXRoUmVsYXRpdmUoZCwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KDApO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gIGZ1bmN0aW9uIG9ic2VydmFibGVUaW1lclRpbWVTcGFuQW5kUGVyaW9kKGR1ZVRpbWUsIHBlcmlvZCwgc2NoZWR1bGVyKSB7XHJcbiAgICBpZiAoZHVlVGltZSA9PT0gcGVyaW9kKSB7XHJcbiAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICByZXR1cm4gc2NoZWR1bGVyLnNjaGVkdWxlUGVyaW9kaWNXaXRoU3RhdGUoMCwgcGVyaW9kLCBmdW5jdGlvbiAoY291bnQpIHtcclxuICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChjb3VudCk7XHJcbiAgICAgICAgICByZXR1cm4gY291bnQgKyAxO1xyXG4gICAgICAgIH0pO1xyXG4gICAgICB9KTtcclxuICAgIH1cclxuICAgIHJldHVybiBvYnNlcnZhYmxlRGVmZXIoZnVuY3Rpb24gKCkge1xyXG4gICAgICByZXR1cm4gb2JzZXJ2YWJsZVRpbWVyRGF0ZUFuZFBlcmlvZChzY2hlZHVsZXIubm93KCkgKyBkdWVUaW1lLCBwZXJpb2QsIHNjaGVkdWxlcik7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgUmV0dXJucyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgcHJvZHVjZXMgYSB2YWx1ZSBhZnRlciBlYWNoIHBlcmlvZC5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgMSAtIHJlcyA9IFJ4Lk9ic2VydmFibGUuaW50ZXJ2YWwoMTAwMCk7XHJcbiAgICAgKiAgMiAtIHJlcyA9IFJ4Lk9ic2VydmFibGUuaW50ZXJ2YWwoMTAwMCwgUnguU2NoZWR1bGVyLnRpbWVvdXQpO1xyXG4gICAgICogICAgICBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBwZXJpb2QgUGVyaW9kIGZvciBwcm9kdWNpbmcgdGhlIHZhbHVlcyBpbiB0aGUgcmVzdWx0aW5nIHNlcXVlbmNlIChzcGVjaWZpZWQgYXMgYW4gaW50ZWdlciBkZW5vdGluZyBtaWxsaXNlY29uZHMpLlxyXG4gICAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtzY2hlZHVsZXJdIFNjaGVkdWxlciB0byBydW4gdGhlIHRpbWVyIG9uLiBJZiBub3Qgc3BlY2lmaWVkLCBSeC5TY2hlZHVsZXIudGltZW91dCBpcyB1c2VkLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBwcm9kdWNlcyBhIHZhbHVlIGFmdGVyIGVhY2ggcGVyaW9kLlxyXG4gICAgICovXHJcbiAgICB2YXIgb2JzZXJ2YWJsZWludGVydmFsID0gT2JzZXJ2YWJsZS5pbnRlcnZhbCA9IGZ1bmN0aW9uIChwZXJpb2QsIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHNjaGVkdWxlciB8fCAoc2NoZWR1bGVyID0gdGltZW91dFNjaGVkdWxlcik7XHJcbiAgICAgICAgcmV0dXJuIG9ic2VydmFibGVUaW1lclRpbWVTcGFuQW5kUGVyaW9kKHBlcmlvZCwgcGVyaW9kLCBzY2hlZHVsZXIpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBSZXR1cm5zIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBwcm9kdWNlcyBhIHZhbHVlIGFmdGVyIGR1ZVRpbWUgaGFzIGVsYXBzZWQgYW5kIHRoZW4gYWZ0ZXIgZWFjaCBwZXJpb2QuXHJcbiAgICAgKiAgXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIDEgLSByZXMgPSBSeC5PYnNlcnZhYmxlLnRpbWVyKG5ldyBEYXRlKCkpO1xyXG4gICAgICogIDIgLSByZXMgPSBSeC5PYnNlcnZhYmxlLnRpbWVyKG5ldyBEYXRlKCksIDEwMDApO1xyXG4gICAgICogIDMgLSByZXMgPSBSeC5PYnNlcnZhYmxlLnRpbWVyKG5ldyBEYXRlKCksIFJ4LlNjaGVkdWxlci50aW1lb3V0KTtcclxuICAgICAqICA0IC0gcmVzID0gUnguT2JzZXJ2YWJsZS50aW1lcihuZXcgRGF0ZSgpLCAxMDAwLCBSeC5TY2hlZHVsZXIudGltZW91dCk7XHJcbiAgICAgKiAgXHJcbiAgICAgKiAgNSAtIHJlcyA9IFJ4Lk9ic2VydmFibGUudGltZXIoNTAwMCk7XHJcbiAgICAgKiAgNiAtIHJlcyA9IFJ4Lk9ic2VydmFibGUudGltZXIoNTAwMCwgMTAwMCk7XHJcbiAgICAgKiAgNyAtIHJlcyA9IFJ4Lk9ic2VydmFibGUudGltZXIoNTAwMCwgUnguU2NoZWR1bGVyLnRpbWVvdXQpO1xyXG4gICAgICogIDggLSByZXMgPSBSeC5PYnNlcnZhYmxlLnRpbWVyKDUwMDAsIDEwMDAsIFJ4LlNjaGVkdWxlci50aW1lb3V0KTtcclxuICAgICAqICBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkdWVUaW1lIEFic29sdXRlIChzcGVjaWZpZWQgYXMgYSBEYXRlIG9iamVjdCkgb3IgcmVsYXRpdmUgdGltZSAoc3BlY2lmaWVkIGFzIGFuIGludGVnZXIgZGVub3RpbmcgbWlsbGlzZWNvbmRzKSBhdCB3aGljaCB0byBwcm9kdWNlIHRoZSBmaXJzdCB2YWx1ZS5cclxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IFtwZXJpb2RPclNjaGVkdWxlcl0gIFBlcmlvZCB0byBwcm9kdWNlIHN1YnNlcXVlbnQgdmFsdWVzIChzcGVjaWZpZWQgYXMgYW4gaW50ZWdlciBkZW5vdGluZyBtaWxsaXNlY29uZHMpLCBvciB0aGUgc2NoZWR1bGVyIHRvIHJ1biB0aGUgdGltZXIgb24uIElmIG5vdCBzcGVjaWZpZWQsIHRoZSByZXN1bHRpbmcgdGltZXIgaXMgbm90IHJlY3VycmluZy5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSAgU2NoZWR1bGVyIHRvIHJ1biB0aGUgdGltZXIgb24uIElmIG5vdCBzcGVjaWZpZWQsIHRoZSB0aW1lb3V0IHNjaGVkdWxlciBpcyB1c2VkLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBwcm9kdWNlcyBhIHZhbHVlIGFmdGVyIGR1ZSB0aW1lIGhhcyBlbGFwc2VkIGFuZCB0aGVuIGVhY2ggcGVyaW9kLlxyXG4gICAgICovXHJcbiAgICB2YXIgb2JzZXJ2YWJsZVRpbWVyID0gT2JzZXJ2YWJsZS50aW1lciA9IGZ1bmN0aW9uIChkdWVUaW1lLCBwZXJpb2RPclNjaGVkdWxlciwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgdmFyIHBlcmlvZDtcclxuICAgICAgICBzY2hlZHVsZXIgfHwgKHNjaGVkdWxlciA9IHRpbWVvdXRTY2hlZHVsZXIpO1xyXG4gICAgICAgIGlmIChwZXJpb2RPclNjaGVkdWxlciAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBwZXJpb2RPclNjaGVkdWxlciA9PT0gJ251bWJlcicpIHtcclxuICAgICAgICAgICAgcGVyaW9kID0gcGVyaW9kT3JTY2hlZHVsZXI7XHJcbiAgICAgICAgfSBlbHNlIGlmIChwZXJpb2RPclNjaGVkdWxlciAhPT0gdW5kZWZpbmVkICYmIHR5cGVvZiBwZXJpb2RPclNjaGVkdWxlciA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgc2NoZWR1bGVyID0gcGVyaW9kT3JTY2hlZHVsZXI7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChkdWVUaW1lIGluc3RhbmNlb2YgRGF0ZSAmJiBwZXJpb2QgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZVRpbWVyRGF0ZShkdWVUaW1lLmdldFRpbWUoKSwgc2NoZWR1bGVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGR1ZVRpbWUgaW5zdGFuY2VvZiBEYXRlICYmIHBlcmlvZCAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgIHBlcmlvZCA9IHBlcmlvZE9yU2NoZWR1bGVyO1xyXG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZVRpbWVyRGF0ZUFuZFBlcmlvZChkdWVUaW1lLmdldFRpbWUoKSwgcGVyaW9kLCBzY2hlZHVsZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAocGVyaW9kID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVUaW1lclRpbWVTcGFuKGR1ZVRpbWUsIHNjaGVkdWxlcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBvYnNlcnZhYmxlVGltZXJUaW1lU3BhbkFuZFBlcmlvZChkdWVUaW1lLCBwZXJpb2QsIHNjaGVkdWxlcik7XHJcbiAgICB9O1xyXG5cclxuICAgIGZ1bmN0aW9uIG9ic2VydmFibGVEZWxheVRpbWVTcGFuKGR1ZVRpbWUsIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGFjdGl2ZSA9IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgY2FuY2VsYWJsZSA9IG5ldyBTZXJpYWxEaXNwb3NhYmxlKCksXHJcbiAgICAgICAgICAgICAgICBleGNlcHRpb24gPSBudWxsLFxyXG4gICAgICAgICAgICAgICAgcSA9IFtdLFxyXG4gICAgICAgICAgICAgICAgcnVubmluZyA9IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uO1xyXG4gICAgICAgICAgICBzdWJzY3JpcHRpb24gPSBzb3VyY2UubWF0ZXJpYWxpemUoKS50aW1lc3RhbXAoc2NoZWR1bGVyKS5zdWJzY3JpYmUoZnVuY3Rpb24gKG5vdGlmaWNhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgdmFyIGQsIHNob3VsZFJ1bjtcclxuICAgICAgICAgICAgICAgIGlmIChub3RpZmljYXRpb24udmFsdWUua2luZCA9PT0gJ0UnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcSA9IFtdO1xyXG4gICAgICAgICAgICAgICAgICAgIHEucHVzaChub3RpZmljYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIGV4Y2VwdGlvbiA9IG5vdGlmaWNhdGlvbi52YWx1ZS5leGNlcHRpb247XHJcbiAgICAgICAgICAgICAgICAgICAgc2hvdWxkUnVuID0gIXJ1bm5pbmc7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHEucHVzaCh7IHZhbHVlOiBub3RpZmljYXRpb24udmFsdWUsIHRpbWVzdGFtcDogbm90aWZpY2F0aW9uLnRpbWVzdGFtcCArIGR1ZVRpbWUgfSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc2hvdWxkUnVuID0gIWFjdGl2ZTtcclxuICAgICAgICAgICAgICAgICAgICBhY3RpdmUgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKHNob3VsZFJ1bikge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChleGNlcHRpb24gIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihleGNlcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGQgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FuY2VsYWJsZS5zZXREaXNwb3NhYmxlKGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkLnNldERpc3Bvc2FibGUoc2NoZWR1bGVyLnNjaGVkdWxlUmVjdXJzaXZlV2l0aFJlbGF0aXZlKGR1ZVRpbWUsIGZ1bmN0aW9uIChzZWxmKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIgZSwgcmVjdXJzZUR1ZVRpbWUsIHJlc3VsdCwgc2hvdWxkUmVjdXJzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChleGNlcHRpb24gIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBydW5uaW5nID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBudWxsO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxLmxlbmd0aCA+IDAgJiYgcVswXS50aW1lc3RhbXAgLSBzY2hlZHVsZXIubm93KCkgPD0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBxLnNoaWZ0KCkudmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChyZXN1bHQgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LmFjY2VwdChvYnNlcnZlcik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSB3aGlsZSAocmVzdWx0ICE9PSBudWxsKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNob3VsZFJlY3Vyc2UgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlY3Vyc2VEdWVUaW1lID0gMDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChxLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaG91bGRSZWN1cnNlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWN1cnNlRHVlVGltZSA9IE1hdGgubWF4KDAsIHFbMF0udGltZXN0YW1wIC0gc2NoZWR1bGVyLm5vdygpKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWN0aXZlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBlID0gZXhjZXB0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcnVubmluZyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGUgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIGlmIChzaG91bGRSZWN1cnNlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZihyZWN1cnNlRHVlVGltZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc3Vic2NyaXB0aW9uLCBjYW5jZWxhYmxlKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICBmdW5jdGlvbiBvYnNlcnZhYmxlRGVsYXlEYXRlKGR1ZVRpbWUsIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHZhciBzZWxmID0gdGhpcztcclxuICAgICAgICByZXR1cm4gb2JzZXJ2YWJsZURlZmVyKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIHRpbWVTcGFuID0gZHVlVGltZSAtIHNjaGVkdWxlci5ub3coKTtcclxuICAgICAgICAgICAgcmV0dXJuIG9ic2VydmFibGVEZWxheVRpbWVTcGFuLmNhbGwoc2VsZiwgdGltZVNwYW4sIHNjaGVkdWxlcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgVGltZSBzaGlmdHMgdGhlIG9ic2VydmFibGUgc2VxdWVuY2UgYnkgZHVlVGltZS4gVGhlIHJlbGF0aXZlIHRpbWUgaW50ZXJ2YWxzIGJldHdlZW4gdGhlIHZhbHVlcyBhcmUgcHJlc2VydmVkLlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICAxIC0gcmVzID0gUnguT2JzZXJ2YWJsZS5kZWxheShuZXcgRGF0ZSgpKTtcclxuICAgICAqICAyIC0gcmVzID0gUnguT2JzZXJ2YWJsZS5kZWxheShuZXcgRGF0ZSgpLCBSeC5TY2hlZHVsZXIudGltZW91dCk7XHJcbiAgICAgKiAgXHJcbiAgICAgKiAgMyAtIHJlcyA9IFJ4Lk9ic2VydmFibGUuZGVsYXkoNTAwMCk7XHJcbiAgICAgKiAgNCAtIHJlcyA9IFJ4Lk9ic2VydmFibGUuZGVsYXkoNTAwMCwgMTAwMCwgUnguU2NoZWR1bGVyLnRpbWVvdXQpO1xyXG4gICAgICogQG1lbWJlck9mIE9ic2VydmFibGUjXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZHVlVGltZSBBYnNvbHV0ZSAoc3BlY2lmaWVkIGFzIGEgRGF0ZSBvYmplY3QpIG9yIHJlbGF0aXZlIHRpbWUgKHNwZWNpZmllZCBhcyBhbiBpbnRlZ2VyIGRlbm90aW5nIG1pbGxpc2Vjb25kcykgYnkgd2hpY2ggdG8gc2hpZnQgdGhlIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gW3NjaGVkdWxlcl0gU2NoZWR1bGVyIHRvIHJ1biB0aGUgZGVsYXkgdGltZXJzIG9uLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgdGltZW91dCBzY2hlZHVsZXIgaXMgdXNlZC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBUaW1lLXNoaWZ0ZWQgc2VxdWVuY2UuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5kZWxheSA9IGZ1bmN0aW9uIChkdWVUaW1lLCBzY2hlZHVsZXIpIHtcclxuICAgICAgICBzY2hlZHVsZXIgfHwgKHNjaGVkdWxlciA9IHRpbWVvdXRTY2hlZHVsZXIpO1xyXG4gICAgICAgIHJldHVybiBkdWVUaW1lIGluc3RhbmNlb2YgRGF0ZSA/XHJcbiAgICAgICAgICAgIG9ic2VydmFibGVEZWxheURhdGUuY2FsbCh0aGlzLCBkdWVUaW1lLmdldFRpbWUoKSwgc2NoZWR1bGVyKSA6XHJcbiAgICAgICAgICAgIG9ic2VydmFibGVEZWxheVRpbWVTcGFuLmNhbGwodGhpcywgZHVlVGltZSwgc2NoZWR1bGVyKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgSWdub3JlcyB2YWx1ZXMgZnJvbSBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdoaWNoIGFyZSBmb2xsb3dlZCBieSBhbm90aGVyIHZhbHVlIGJlZm9yZSBkdWVUaW1lLlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICAxIC0gcmVzID0gc291cmNlLnRocm90dGxlKDUwMDApOyAvLyA1IHNlY29uZHNcclxuICAgICAqICAyIC0gcmVzID0gc291cmNlLnRocm90dGxlKDUwMDAsIHNjaGVkdWxlcik7ICAgICAgICBcclxuICAgICAqIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGR1ZVRpbWUgRHVyYXRpb24gb2YgdGhlIHRocm90dGxlIHBlcmlvZCBmb3IgZWFjaCB2YWx1ZSAoc3BlY2lmaWVkIGFzIGFuIGludGVnZXIgZGVub3RpbmcgbWlsbGlzZWNvbmRzKS5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSAgU2NoZWR1bGVyIHRvIHJ1biB0aGUgdGhyb3R0bGUgdGltZXJzIG9uLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgdGltZW91dCBzY2hlZHVsZXIgaXMgdXNlZC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBUaGUgdGhyb3R0bGVkIHNlcXVlbmNlLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8udGhyb3R0bGUgPSBmdW5jdGlvbiAoZHVlVGltZSwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSB0aW1lb3V0U2NoZWR1bGVyKTtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICByZXR1cm4gdGhpcy50aHJvdHRsZVdpdGhTZWxlY3RvcihmdW5jdGlvbiAoKSB7IHJldHVybiBvYnNlcnZhYmxlVGltZXIoZHVlVGltZSwgc2NoZWR1bGVyKTsgfSlcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgUHJvamVjdHMgZWFjaCBlbGVtZW50IG9mIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgaW50byB6ZXJvIG9yIG1vcmUgd2luZG93cyB3aGljaCBhcmUgcHJvZHVjZWQgYmFzZWQgb24gdGltaW5nIGluZm9ybWF0aW9uLlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICAxIC0gcmVzID0geHMud2luZG93V2l0aFRpbWUoMTAwMCwgc2NoZWR1bGVyKTsgLy8gbm9uLW92ZXJsYXBwaW5nIHNlZ21lbnRzIG9mIDEgc2Vjb25kXHJcbiAgICAgKiAgMiAtIHJlcyA9IHhzLndpbmRvd1dpdGhUaW1lKDEwMDAsIDUwMCAsIHNjaGVkdWxlcik7IC8vIHNlZ21lbnRzIG9mIDEgc2Vjb25kIHdpdGggdGltZSBzaGlmdCAwLjUgc2Vjb25kc1xyXG4gICAgICogICAgICBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aW1lU3BhbiBMZW5ndGggb2YgZWFjaCB3aW5kb3cgKHNwZWNpZmllZCBhcyBhbiBpbnRlZ2VyIGRlbm90aW5nIG1pbGxpc2Vjb25kcykuXHJcbiAgICAgKiBAcGFyYW0ge01peGVkfSBbdGltZVNoaWZ0T3JTY2hlZHVsZXJdICBJbnRlcnZhbCBiZXR3ZWVuIGNyZWF0aW9uIG9mIGNvbnNlY3V0aXZlIHdpbmRvd3MgKHNwZWNpZmllZCBhcyBhbiBpbnRlZ2VyIGRlbm90aW5nIG1pbGxpc2Vjb25kcyksIG9yIGFuIG9wdGlvbmFsIHNjaGVkdWxlciBwYXJhbWV0ZXIuIElmIG5vdCBzcGVjaWZpZWQsIHRoZSB0aW1lIHNoaWZ0IGNvcnJlc3BvbmRzIHRvIHRoZSB0aW1lU3BhbiBwYXJhbWV0ZXIsIHJlc3VsdGluZyBpbiBub24tb3ZlcmxhcHBpbmcgYWRqYWNlbnQgd2luZG93cy5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSAgU2NoZWR1bGVyIHRvIHJ1biB3aW5kb3dpbmcgdGltZXJzIG9uLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgdGltZW91dCBzY2hlZHVsZXIgaXMgdXNlZC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIG9mIHdpbmRvd3MuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by53aW5kb3dXaXRoVGltZSA9IGZ1bmN0aW9uICh0aW1lU3BhbiwgdGltZVNoaWZ0T3JTY2hlZHVsZXIsIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzLCB0aW1lU2hpZnQ7XHJcbiAgICAgICAgaWYgKHRpbWVTaGlmdE9yU2NoZWR1bGVyID09PSB1bmRlZmluZWQpIHtcclxuICAgICAgICAgICAgdGltZVNoaWZ0ID0gdGltZVNwYW47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChzY2hlZHVsZXIgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICBzY2hlZHVsZXIgPSB0aW1lb3V0U2NoZWR1bGVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAodHlwZW9mIHRpbWVTaGlmdE9yU2NoZWR1bGVyID09PSAnbnVtYmVyJykge1xyXG4gICAgICAgICAgICB0aW1lU2hpZnQgPSB0aW1lU2hpZnRPclNjaGVkdWxlcjtcclxuICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiB0aW1lU2hpZnRPclNjaGVkdWxlciA9PT0gJ29iamVjdCcpIHtcclxuICAgICAgICAgICAgdGltZVNoaWZ0ID0gdGltZVNwYW47XHJcbiAgICAgICAgICAgIHNjaGVkdWxlciA9IHRpbWVTaGlmdE9yU2NoZWR1bGVyO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBncm91cERpc3Bvc2FibGUsXHJcbiAgICAgICAgICAgICAgICBuZXh0U2hpZnQgPSB0aW1lU2hpZnQsXHJcbiAgICAgICAgICAgICAgICBuZXh0U3BhbiA9IHRpbWVTcGFuLFxyXG4gICAgICAgICAgICAgICAgcSA9IFtdLFxyXG4gICAgICAgICAgICAgICAgcmVmQ291bnREaXNwb3NhYmxlLFxyXG4gICAgICAgICAgICAgICAgdGltZXJEID0gbmV3IFNlcmlhbERpc3Bvc2FibGUoKSxcclxuICAgICAgICAgICAgICAgIHRvdGFsVGltZSA9IDA7XHJcbiAgICAgICAgICAgICAgICBncm91cERpc3Bvc2FibGUgPSBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZSh0aW1lckQpLFxyXG4gICAgICAgICAgICAgICAgcmVmQ291bnREaXNwb3NhYmxlID0gbmV3IFJlZkNvdW50RGlzcG9zYWJsZShncm91cERpc3Bvc2FibGUpO1xyXG5cclxuICAgICAgICAgICAgIGZ1bmN0aW9uIGNyZWF0ZVRpbWVyICgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBtID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCksXHJcbiAgICAgICAgICAgICAgICAgICAgaXNTcGFuID0gZmFsc2UsXHJcbiAgICAgICAgICAgICAgICAgICAgaXNTaGlmdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgdGltZXJELnNldERpc3Bvc2FibGUobSk7XHJcbiAgICAgICAgICAgICAgICBpZiAobmV4dFNwYW4gPT09IG5leHRTaGlmdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlzU3BhbiA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgaXNTaGlmdCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKG5leHRTcGFuIDwgbmV4dFNoaWZ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaXNTcGFuID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaXNTaGlmdCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB2YXIgbmV3VG90YWxUaW1lID0gaXNTcGFuID8gbmV4dFNwYW4gOiBuZXh0U2hpZnQsXHJcbiAgICAgICAgICAgICAgICAgICAgdHMgPSBuZXdUb3RhbFRpbWUgLSB0b3RhbFRpbWU7XHJcbiAgICAgICAgICAgICAgICB0b3RhbFRpbWUgPSBuZXdUb3RhbFRpbWU7XHJcbiAgICAgICAgICAgICAgICBpZiAoaXNTcGFuKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV4dFNwYW4gKz0gdGltZVNoaWZ0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgaWYgKGlzU2hpZnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXh0U2hpZnQgKz0gdGltZVNoaWZ0O1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbS5zZXREaXNwb3NhYmxlKHNjaGVkdWxlci5zY2hlZHVsZVdpdGhSZWxhdGl2ZSh0cywgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBzO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1NoaWZ0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHMgPSBuZXcgU3ViamVjdCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBxLnB1c2gocyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChhZGRSZWYocywgcmVmQ291bnREaXNwb3NhYmxlKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGlmIChpc1NwYW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcyA9IHEuc2hpZnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcy5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVUaW1lcigpO1xyXG4gICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICBxLnB1c2gobmV3IFN1YmplY3QoKSk7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChhZGRSZWYocVswXSwgcmVmQ291bnREaXNwb3NhYmxlKSk7XHJcbiAgICAgICAgICAgIGNyZWF0ZVRpbWVyKCk7XHJcbiAgICAgICAgICAgIGdyb3VwRGlzcG9zYWJsZS5hZGQoc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGksIHM7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBxW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIHMub25OZXh0KHgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgdmFyIGksIHM7XHJcbiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgcS5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgIHMgPSBxW2ldO1xyXG4gICAgICAgICAgICAgICAgICAgIHMub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBpLCBzO1xyXG4gICAgICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHEubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICBzID0gcVtpXTtcclxuICAgICAgICAgICAgICAgICAgICBzLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgIHJldHVybiByZWZDb3VudERpc3Bvc2FibGU7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFByb2plY3RzIGVhY2ggZWxlbWVudCBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGludG8gYSB3aW5kb3cgdGhhdCBpcyBjb21wbGV0ZWQgd2hlbiBlaXRoZXIgaXQncyBmdWxsIG9yIGEgZ2l2ZW4gYW1vdW50IG9mIHRpbWUgaGFzIGVsYXBzZWQuXHJcbiAgICAgKiAgQGV4YW1wbGVcclxuICAgICAqICAxIC0gcmVzID0gc291cmNlLndpbmRvd1dpdGhUaW1lT3JDb3VudCg1MDAwLCA1MCk7IC8vIDVzIG9yIDUwIGl0ZW1zXHJcbiAgICAgKiAgMiAtIHJlcyA9IHNvdXJjZS53aW5kb3dXaXRoVGltZU9yQ291bnQoNTAwMCwgNTAsIHNjaGVkdWxlcik7IC8vNXMgb3IgNTAgaXRlbXNcclxuICAgICAqICAgICAgXHJcbiAgICAgKiBAbWVtYmVyT2YgT2JzZXJ2YWJsZSNcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aW1lU3BhbiBNYXhpbXVtIHRpbWUgbGVuZ3RoIG9mIGEgd2luZG93LlxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGNvdW50IE1heGltdW0gZWxlbWVudCBjb3VudCBvZiBhIHdpbmRvdy5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSAgU2NoZWR1bGVyIHRvIHJ1biB3aW5kb3dpbmcgdGltZXJzIG9uLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgdGltZW91dCBzY2hlZHVsZXIgaXMgdXNlZC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIG9mIHdpbmRvd3MuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by53aW5kb3dXaXRoVGltZU9yQ291bnQgPSBmdW5jdGlvbiAodGltZVNwYW4sIGNvdW50LCBzY2hlZHVsZXIpIHtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICBzY2hlZHVsZXIgfHwgKHNjaGVkdWxlciA9IHRpbWVvdXRTY2hlZHVsZXIpO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGNyZWF0ZVRpbWVyLFxyXG4gICAgICAgICAgICAgICAgZ3JvdXBEaXNwb3NhYmxlLFxyXG4gICAgICAgICAgICAgICAgbiA9IDAsXHJcbiAgICAgICAgICAgICAgICByZWZDb3VudERpc3Bvc2FibGUsXHJcbiAgICAgICAgICAgICAgICBzLFxyXG4gICAgICAgICAgICAgICAgdGltZXJEID0gbmV3IFNlcmlhbERpc3Bvc2FibGUoKSxcclxuICAgICAgICAgICAgICAgIHdpbmRvd0lkID0gMDtcclxuICAgICAgICAgICAgZ3JvdXBEaXNwb3NhYmxlID0gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUodGltZXJEKTtcclxuICAgICAgICAgICAgcmVmQ291bnREaXNwb3NhYmxlID0gbmV3IFJlZkNvdW50RGlzcG9zYWJsZShncm91cERpc3Bvc2FibGUpO1xyXG4gICAgICAgICAgICBjcmVhdGVUaW1lciA9IGZ1bmN0aW9uIChpZCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG0gPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgICAgIHRpbWVyRC5zZXREaXNwb3NhYmxlKG0pO1xyXG4gICAgICAgICAgICAgICAgbS5zZXREaXNwb3NhYmxlKHNjaGVkdWxlci5zY2hlZHVsZVdpdGhSZWxhdGl2ZSh0aW1lU3BhbiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBuZXdJZDtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoaWQgIT09IHdpbmRvd0lkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgbiA9IDA7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV3SWQgPSArK3dpbmRvd0lkO1xyXG4gICAgICAgICAgICAgICAgICAgIHMub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICBzID0gbmV3IFN1YmplY3QoKTtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQoYWRkUmVmKHMsIHJlZkNvdW50RGlzcG9zYWJsZSkpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNyZWF0ZVRpbWVyKG5ld0lkKTtcclxuICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgfTtcclxuICAgICAgICAgICAgcyA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChhZGRSZWYocywgcmVmQ291bnREaXNwb3NhYmxlKSk7XHJcbiAgICAgICAgICAgIGNyZWF0ZVRpbWVyKDApO1xyXG4gICAgICAgICAgICBncm91cERpc3Bvc2FibGUuYWRkKHNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBuZXdJZCA9IDAsIG5ld1dpbmRvdyA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgcy5vbk5leHQoeCk7XHJcbiAgICAgICAgICAgICAgICBuKys7XHJcbiAgICAgICAgICAgICAgICBpZiAobiA9PT0gY291bnQpIHtcclxuICAgICAgICAgICAgICAgICAgICBuZXdXaW5kb3cgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIG4gPSAwO1xyXG4gICAgICAgICAgICAgICAgICAgIG5ld0lkID0gKyt3aW5kb3dJZDtcclxuICAgICAgICAgICAgICAgICAgICBzLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgcyA9IG5ldyBTdWJqZWN0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KGFkZFJlZihzLCByZWZDb3VudERpc3Bvc2FibGUpKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChuZXdXaW5kb3cpIHtcclxuICAgICAgICAgICAgICAgICAgICBjcmVhdGVUaW1lcihuZXdJZCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIGZ1bmN0aW9uIChlKSB7XHJcbiAgICAgICAgICAgICAgICBzLm9uRXJyb3IoZSk7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBzLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgIHJldHVybiByZWZDb3VudERpc3Bvc2FibGU7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFByb2plY3RzIGVhY2ggZWxlbWVudCBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGludG8gemVybyBvciBtb3JlIGJ1ZmZlcnMgd2hpY2ggYXJlIHByb2R1Y2VkIGJhc2VkIG9uIHRpbWluZyBpbmZvcm1hdGlvbi5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgMSAtIHJlcyA9IHhzLmJ1ZmZlcldpdGhUaW1lKDEwMDAsIHNjaGVkdWxlcik7IC8vIG5vbi1vdmVybGFwcGluZyBzZWdtZW50cyBvZiAxIHNlY29uZFxyXG4gICAgICogIDIgLSByZXMgPSB4cy5idWZmZXJXaXRoVGltZSgxMDAwLCA1MDAsIHNjaGVkdWxlcjsgLy8gc2VnbWVudHMgb2YgMSBzZWNvbmQgd2l0aCB0aW1lIHNoaWZ0IDAuNSBzZWNvbmRzXHJcbiAgICAgKiAgICAgIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRpbWVTcGFuIExlbmd0aCBvZiBlYWNoIGJ1ZmZlciAoc3BlY2lmaWVkIGFzIGFuIGludGVnZXIgZGVub3RpbmcgbWlsbGlzZWNvbmRzKS5cclxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IFt0aW1lU2hpZnRPclNjaGVkdWxlcl0gIEludGVydmFsIGJldHdlZW4gY3JlYXRpb24gb2YgY29uc2VjdXRpdmUgYnVmZmVycyAoc3BlY2lmaWVkIGFzIGFuIGludGVnZXIgZGVub3RpbmcgbWlsbGlzZWNvbmRzKSwgb3IgYW4gb3B0aW9uYWwgc2NoZWR1bGVyIHBhcmFtZXRlci4gSWYgbm90IHNwZWNpZmllZCwgdGhlIHRpbWUgc2hpZnQgY29ycmVzcG9uZHMgdG8gdGhlIHRpbWVTcGFuIHBhcmFtZXRlciwgcmVzdWx0aW5nIGluIG5vbi1vdmVybGFwcGluZyBhZGphY2VudCBidWZmZXJzLlxyXG4gICAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtzY2hlZHVsZXJdICBTY2hlZHVsZXIgdG8gcnVuIGJ1ZmZlciB0aW1lcnMgb24uIElmIG5vdCBzcGVjaWZpZWQsIHRoZSB0aW1lb3V0IHNjaGVkdWxlciBpcyB1c2VkLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2Ugb2YgYnVmZmVycy5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLmJ1ZmZlcldpdGhUaW1lID0gZnVuY3Rpb24gKHRpbWVTcGFuLCB0aW1lU2hpZnRPclNjaGVkdWxlciwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMud2luZG93V2l0aFRpbWUuYXBwbHkodGhpcywgYXJndW1lbnRzKS5zZWxlY3RNYW55KGZ1bmN0aW9uICh4KSB7IHJldHVybiB4LnRvQXJyYXkoKTsgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFByb2plY3RzIGVhY2ggZWxlbWVudCBvZiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGludG8gYSBidWZmZXIgdGhhdCBpcyBjb21wbGV0ZWQgd2hlbiBlaXRoZXIgaXQncyBmdWxsIG9yIGEgZ2l2ZW4gYW1vdW50IG9mIHRpbWUgaGFzIGVsYXBzZWQuXHJcbiAgICAgKiAgXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIDEgLSByZXMgPSBzb3VyY2UuYnVmZmVyV2l0aFRpbWVPckNvdW50KDUwMDAsIDUwKTsgLy8gNXMgb3IgNTAgaXRlbXMgaW4gYW4gYXJyYXkgXHJcbiAgICAgKiAgMiAtIHJlcyA9IHNvdXJjZS5idWZmZXJXaXRoVGltZU9yQ291bnQoNTAwMCwgNTAsIHNjaGVkdWxlcik7IC8vIDVzIG9yIDUwIGl0ZW1zIGluIGFuIGFycmF5XHJcbiAgICAgKiAgICAgIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHRpbWVTcGFuIE1heGltdW0gdGltZSBsZW5ndGggb2YgYSBidWZmZXIuXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gY291bnQgTWF4aW11bSBlbGVtZW50IGNvdW50IG9mIGEgYnVmZmVyLlxyXG4gICAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtzY2hlZHVsZXJdICBTY2hlZHVsZXIgdG8gcnVuIGJ1ZmZlcmluIHRpbWVycyBvbi4gSWYgbm90IHNwZWNpZmllZCwgdGhlIHRpbWVvdXQgc2NoZWR1bGVyIGlzIHVzZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBvZiBidWZmZXJzLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uYnVmZmVyV2l0aFRpbWVPckNvdW50ID0gZnVuY3Rpb24gKHRpbWVTcGFuLCBjb3VudCwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMud2luZG93V2l0aFRpbWVPckNvdW50KHRpbWVTcGFuLCBjb3VudCwgc2NoZWR1bGVyKS5zZWxlY3RNYW55KGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgIHJldHVybiB4LnRvQXJyYXkoKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgUmVjb3JkcyB0aGUgdGltZSBpbnRlcnZhbCBiZXR3ZWVuIGNvbnNlY3V0aXZlIHZhbHVlcyBpbiBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICAxIC0gcmVzID0gc291cmNlLnRpbWVJbnRlcnZhbCgpO1xyXG4gICAgICogIDIgLSByZXMgPSBzb3VyY2UudGltZUludGVydmFsKFJ4LlNjaGVkdWxlci50aW1lb3V0KTtcclxuICAgICAqICAgICAgXHJcbiAgICAgKiBAcGFyYW0gW3NjaGVkdWxlcl0gIFNjaGVkdWxlciB1c2VkIHRvIGNvbXB1dGUgdGltZSBpbnRlcnZhbHMuIElmIG5vdCBzcGVjaWZpZWQsIHRoZSB0aW1lb3V0IHNjaGVkdWxlciBpcyB1c2VkLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2Ugd2l0aCB0aW1lIGludGVydmFsIGluZm9ybWF0aW9uIG9uIHZhbHVlcy5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnRpbWVJbnRlcnZhbCA9IGZ1bmN0aW9uIChzY2hlZHVsZXIpIHtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICBzY2hlZHVsZXIgfHwgKHNjaGVkdWxlciA9IHRpbWVvdXRTY2hlZHVsZXIpO1xyXG4gICAgICAgIHJldHVybiBvYnNlcnZhYmxlRGVmZXIoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgbGFzdCA9IHNjaGVkdWxlci5ub3coKTtcclxuICAgICAgICAgICAgcmV0dXJuIHNvdXJjZS5zZWxlY3QoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBub3cgPSBzY2hlZHVsZXIubm93KCksIHNwYW4gPSBub3cgLSBsYXN0O1xyXG4gICAgICAgICAgICAgICAgbGFzdCA9IG5vdztcclxuICAgICAgICAgICAgICAgIHJldHVybiB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IHgsXHJcbiAgICAgICAgICAgICAgICAgICAgaW50ZXJ2YWw6IHNwYW5cclxuICAgICAgICAgICAgICAgIH07XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBSZWNvcmRzIHRoZSB0aW1lc3RhbXAgZm9yIGVhY2ggdmFsdWUgaW4gYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgMSAtIHJlcyA9IHNvdXJjZS50aW1lc3RhbXAoKTsgLy8gcHJvZHVjZXMgeyB2YWx1ZTogeCwgdGltZXN0YW1wOiB0cyB9XHJcbiAgICAgKiAgMiAtIHJlcyA9IHNvdXJjZS50aW1lc3RhbXAoUnguU2NoZWR1bGVyLnRpbWVvdXQpO1xyXG4gICAgICogICAgICBcclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSAgU2NoZWR1bGVyIHVzZWQgdG8gY29tcHV0ZSB0aW1lc3RhbXBzLiBJZiBub3Qgc3BlY2lmaWVkLCB0aGUgdGltZW91dCBzY2hlZHVsZXIgaXMgdXNlZC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdpdGggdGltZXN0YW1wIGluZm9ybWF0aW9uIG9uIHZhbHVlcy5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnRpbWVzdGFtcCA9IGZ1bmN0aW9uIChzY2hlZHVsZXIpIHtcclxuICAgICAgICBzY2hlZHVsZXIgfHwgKHNjaGVkdWxlciA9IHRpbWVvdXRTY2hlZHVsZXIpO1xyXG4gICAgICAgIHJldHVybiB0aGlzLnNlbGVjdChmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICByZXR1cm4ge1xyXG4gICAgICAgICAgICAgICAgdmFsdWU6IHgsXHJcbiAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IHNjaGVkdWxlci5ub3coKVxyXG4gICAgICAgICAgICB9O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICBmdW5jdGlvbiBzYW1wbGVPYnNlcnZhYmxlKHNvdXJjZSwgc2FtcGxlcikge1xyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGF0RW5kLCB2YWx1ZSwgaGFzVmFsdWU7XHJcblxyXG4gICAgICAgICAgICBmdW5jdGlvbiBzYW1wbGVTdWJzY3JpYmUoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFzVmFsdWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBoYXNWYWx1ZSA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoYXRFbmQpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoXHJcbiAgICAgICAgICAgICAgICBzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uIChuZXdWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGhhc1ZhbHVlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YWx1ZSA9IG5ld1ZhbHVlO1xyXG4gICAgICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGF0RW5kID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0pLFxyXG4gICAgICAgICAgICAgICAgc2FtcGxlci5zdWJzY3JpYmUoc2FtcGxlU3Vic2NyaWJlLCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBzYW1wbGVTdWJzY3JpYmUpXHJcbiAgICAgICAgICAgICk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgU2FtcGxlcyB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSBhdCBlYWNoIGludGVydmFsLlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICAxIC0gcmVzID0gc291cmNlLnNhbXBsZShzYW1wbGVPYnNlcnZhYmxlKTsgLy8gU2FtcGxlciB0aWNrIHNlcXVlbmNlXHJcbiAgICAgKiAgMiAtIHJlcyA9IHNvdXJjZS5zYW1wbGUoNTAwMCk7IC8vIDUgc2Vjb25kc1xyXG4gICAgICogIDIgLSByZXMgPSBzb3VyY2Uuc2FtcGxlKDUwMDAsIFJ4LlNjaGVkdWxlci50aW1lb3V0KTsgLy8gNSBzZWNvbmRzXHJcbiAgICAgKiAgICAgIFxyXG4gICAgICogQHBhcmFtIHtNaXhlZH0gaW50ZXJ2YWxPclNhbXBsZXIgSW50ZXJ2YWwgYXQgd2hpY2ggdG8gc2FtcGxlIChzcGVjaWZpZWQgYXMgYW4gaW50ZWdlciBkZW5vdGluZyBtaWxsaXNlY29uZHMpIG9yIFNhbXBsZXIgT2JzZXJ2YWJsZS5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSAgU2NoZWR1bGVyIHRvIHJ1biB0aGUgc2FtcGxpbmcgdGltZXIgb24uIElmIG5vdCBzcGVjaWZpZWQsIHRoZSB0aW1lb3V0IHNjaGVkdWxlciBpcyB1c2VkLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IFNhbXBsZWQgb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnNhbXBsZSA9IGZ1bmN0aW9uIChpbnRlcnZhbE9yU2FtcGxlciwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSB0aW1lb3V0U2NoZWR1bGVyKTtcclxuICAgICAgICBpZiAodHlwZW9mIGludGVydmFsT3JTYW1wbGVyID09PSAnbnVtYmVyJykge1xyXG4gICAgICAgICAgICByZXR1cm4gc2FtcGxlT2JzZXJ2YWJsZSh0aGlzLCBvYnNlcnZhYmxlaW50ZXJ2YWwoaW50ZXJ2YWxPclNhbXBsZXIsIHNjaGVkdWxlcikpO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gc2FtcGxlT2JzZXJ2YWJsZSh0aGlzLCBpbnRlcnZhbE9yU2FtcGxlcik7XHJcbiAgICB9O1xyXG5cclxuICAvKipcclxuICAgKiAgUmV0dXJucyB0aGUgc291cmNlIG9ic2VydmFibGUgc2VxdWVuY2Ugb3IgdGhlIG90aGVyIG9ic2VydmFibGUgc2VxdWVuY2UgaWYgZHVlVGltZSBlbGFwc2VzLlxyXG4gICAqICBcclxuICAgKiBAZXhhbXBsZVxyXG4gICAqICAxIC0gcmVzID0gc291cmNlLnRpbWVvdXQobmV3IERhdGUoKSk7IC8vIEFzIGEgZGF0ZVxyXG4gICAqICAyIC0gcmVzID0gc291cmNlLnRpbWVvdXQoNTAwMCk7IC8vIDUgc2Vjb25kc1xyXG4gICAqICAzIC0gcmVzID0gc291cmNlLnRpbWVvdXQobmV3IERhdGUoKSwgUnguT2JzZXJ2YWJsZS5yZXR1cm5WYWx1ZSg0MikpOyAvLyBBcyBhIGRhdGUgYW5kIHRpbWVvdXQgb2JzZXJ2YWJsZVxyXG4gICAqICA0IC0gcmVzID0gc291cmNlLnRpbWVvdXQoNTAwMCwgUnguT2JzZXJ2YWJsZS5yZXR1cm5WYWx1ZSg0MikpOyAvLyA1IHNlY29uZHMgYW5kIHRpbWVvdXQgb2JzZXJ2YWJsZVxyXG4gICAqICA1IC0gcmVzID0gc291cmNlLnRpbWVvdXQobmV3IERhdGUoKSwgUnguT2JzZXJ2YWJsZS5yZXR1cm5WYWx1ZSg0MiksIFJ4LlNjaGVkdWxlci50aW1lb3V0KTsgLy8gQXMgYSBkYXRlIGFuZCB0aW1lb3V0IG9ic2VydmFibGVcclxuICAgKiAgNiAtIHJlcyA9IHNvdXJjZS50aW1lb3V0KDUwMDAsIFJ4Lk9ic2VydmFibGUucmV0dXJuVmFsdWUoNDIpLCBSeC5TY2hlZHVsZXIudGltZW91dCk7IC8vIDUgc2Vjb25kcyBhbmQgdGltZW91dCBvYnNlcnZhYmxlXHJcbiAgICogICAgICBcclxuICAgKiBAcGFyYW0ge051bWJlcn0gZHVlVGltZSBBYnNvbHV0ZSAoc3BlY2lmaWVkIGFzIGEgRGF0ZSBvYmplY3QpIG9yIHJlbGF0aXZlIHRpbWUgKHNwZWNpZmllZCBhcyBhbiBpbnRlZ2VyIGRlbm90aW5nIG1pbGxpc2Vjb25kcykgd2hlbiBhIHRpbWVvdXQgb2NjdXJzLlxyXG4gICAqIEBwYXJhbSB7T2JzZXJ2YWJsZX0gW290aGVyXSAgU2VxdWVuY2UgdG8gcmV0dXJuIGluIGNhc2Ugb2YgYSB0aW1lb3V0LiBJZiBub3Qgc3BlY2lmaWVkLCBhIHRpbWVvdXQgZXJyb3IgdGhyb3dpbmcgc2VxdWVuY2Ugd2lsbCBiZSB1c2VkLlxyXG4gICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSAgU2NoZWR1bGVyIHRvIHJ1biB0aGUgdGltZW91dCB0aW1lcnMgb24uIElmIG5vdCBzcGVjaWZpZWQsIHRoZSB0aW1lb3V0IHNjaGVkdWxlciBpcyB1c2VkLlxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBUaGUgc291cmNlIHNlcXVlbmNlIHN3aXRjaGluZyB0byB0aGUgb3RoZXIgc2VxdWVuY2UgaW4gY2FzZSBvZiBhIHRpbWVvdXQuXHJcbiAgICovXHJcbiAgb2JzZXJ2YWJsZVByb3RvLnRpbWVvdXQgPSBmdW5jdGlvbiAoZHVlVGltZSwgb3RoZXIsIHNjaGVkdWxlcikge1xyXG4gICAgb3RoZXIgfHwgKG90aGVyID0gb2JzZXJ2YWJsZVRocm93KG5ldyBFcnJvcignVGltZW91dCcpKSk7XHJcbiAgICBzY2hlZHVsZXIgfHwgKHNjaGVkdWxlciA9IHRpbWVvdXRTY2hlZHVsZXIpO1xyXG4gICAgXHJcbiAgICB2YXIgc291cmNlID0gdGhpcywgc2NoZWR1bGVyTWV0aG9kID0gZHVlVGltZSBpbnN0YW5jZW9mIERhdGUgP1xyXG4gICAgICAnc2NoZWR1bGVXaXRoQWJzb2x1dGUnIDpcclxuICAgICAgJ3NjaGVkdWxlV2l0aFJlbGF0aXZlJztcclxuXHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciBpZCA9IDAsXHJcbiAgICAgICAgb3JpZ2luYWwgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKSxcclxuICAgICAgICBzdWJzY3JpcHRpb24gPSBuZXcgU2VyaWFsRGlzcG9zYWJsZSgpLFxyXG4gICAgICAgIHN3aXRjaGVkID0gZmFsc2UsXHJcbiAgICAgICAgdGltZXIgPSBuZXcgU2VyaWFsRGlzcG9zYWJsZSgpO1xyXG5cclxuICAgICAgc3Vic2NyaXB0aW9uLnNldERpc3Bvc2FibGUob3JpZ2luYWwpO1xyXG5cclxuICAgICAgdmFyIGNyZWF0ZVRpbWVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIHZhciBteUlkID0gaWQ7XHJcbiAgICAgICAgdGltZXIuc2V0RGlzcG9zYWJsZShzY2hlZHVsZXJbc2NoZWR1bGVyTWV0aG9kXShkdWVUaW1lLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBpZiAoaWQgPT09IG15SWQpIHtcclxuICAgICAgICAgICAgaXNQcm9taXNlKG90aGVyKSAmJiAob3RoZXIgPSBvYnNlcnZhYmxlRnJvbVByb21pc2Uob3RoZXIpKTtcclxuICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnNldERpc3Bvc2FibGUob3RoZXIuc3Vic2NyaWJlKG9ic2VydmVyKSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSkpO1xyXG4gICAgICB9O1xyXG5cclxuICAgICAgY3JlYXRlVGltZXIoKTtcclxuICAgICAgXHJcbiAgICAgIG9yaWdpbmFsLnNldERpc3Bvc2FibGUoc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgIGlmICghc3dpdGNoZWQpIHtcclxuICAgICAgICAgIGlkKys7XHJcbiAgICAgICAgICBvYnNlcnZlci5vbk5leHQoeCk7XHJcbiAgICAgICAgICBjcmVhdGVUaW1lcigpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSwgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICBpZiAoIXN3aXRjaGVkKSB7XHJcbiAgICAgICAgICBpZCsrO1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICBpZiAoIXN3aXRjaGVkKSB7XHJcbiAgICAgICAgICBpZCsrO1xyXG4gICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pKTtcclxuICAgICAgcmV0dXJuIG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKHN1YnNjcmlwdGlvbiwgdGltZXIpO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBHZW5lcmF0ZXMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBieSBpdGVyYXRpbmcgYSBzdGF0ZSBmcm9tIGFuIGluaXRpYWwgc3RhdGUgdW50aWwgdGhlIGNvbmRpdGlvbiBmYWlscy5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgcmVzID0gc291cmNlLmdlbmVyYXRlV2l0aEFic29sdXRlVGltZSgwLCBcclxuICAgICAqICAgICAgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHJldHVybiB0cnVlOyB9LCBcclxuICAgICAqICAgICAgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHggKyAxOyB9LCBcclxuICAgICAqICAgICAgZnVuY3Rpb24gKHgpIHsgcmV0dXJuIHg7IH0sIFxyXG4gICAgICogICAgICBmdW5jdGlvbiAoeCkgeyByZXR1cm4gbmV3IERhdGUoKTsgfVxyXG4gICAgICogIH0pO1xyXG4gICAgICogICAgICBcclxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGluaXRpYWxTdGF0ZSBJbml0aWFsIHN0YXRlLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29uZGl0aW9uIENvbmRpdGlvbiB0byB0ZXJtaW5hdGUgZ2VuZXJhdGlvbiAodXBvbiByZXR1cm5pbmcgZmFsc2UpLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZSBJdGVyYXRpb24gc3RlcCBmdW5jdGlvbi5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlc3VsdFNlbGVjdG9yIFNlbGVjdG9yIGZ1bmN0aW9uIGZvciByZXN1bHRzIHByb2R1Y2VkIGluIHRoZSBzZXF1ZW5jZS5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHRpbWVTZWxlY3RvciBUaW1lIHNlbGVjdG9yIGZ1bmN0aW9uIHRvIGNvbnRyb2wgdGhlIHNwZWVkIG9mIHZhbHVlcyBiZWluZyBwcm9kdWNlZCBlYWNoIGl0ZXJhdGlvbiwgcmV0dXJuaW5nIERhdGUgdmFsdWVzLlxyXG4gICAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtzY2hlZHVsZXJdICBTY2hlZHVsZXIgb24gd2hpY2ggdG8gcnVuIHRoZSBnZW5lcmF0b3IgbG9vcC4gSWYgbm90IHNwZWNpZmllZCwgdGhlIHRpbWVvdXQgc2NoZWR1bGVyIGlzIHVzZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIGdlbmVyYXRlZCBzZXF1ZW5jZS5cclxuICAgICAqL1xyXG4gICAgT2JzZXJ2YWJsZS5nZW5lcmF0ZVdpdGhBYnNvbHV0ZVRpbWUgPSBmdW5jdGlvbiAoaW5pdGlhbFN0YXRlLCBjb25kaXRpb24sIGl0ZXJhdGUsIHJlc3VsdFNlbGVjdG9yLCB0aW1lU2VsZWN0b3IsIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHNjaGVkdWxlciB8fCAoc2NoZWR1bGVyID0gdGltZW91dFNjaGVkdWxlcik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgZmlyc3QgPSB0cnVlLFxyXG4gICAgICAgICAgICAgICAgaGFzUmVzdWx0ID0gZmFsc2UsXHJcbiAgICAgICAgICAgICAgICByZXN1bHQsXHJcbiAgICAgICAgICAgICAgICBzdGF0ZSA9IGluaXRpYWxTdGF0ZSxcclxuICAgICAgICAgICAgICAgIHRpbWU7XHJcbiAgICAgICAgICAgIHJldHVybiBzY2hlZHVsZXIuc2NoZWR1bGVSZWN1cnNpdmVXaXRoQWJzb2x1dGUoc2NoZWR1bGVyLm5vdygpLCBmdW5jdGlvbiAoc2VsZikge1xyXG4gICAgICAgICAgICAgICAgaWYgKGhhc1Jlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChyZXN1bHQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAoZmlyc3QpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZmlyc3QgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdGF0ZSA9IGl0ZXJhdGUoc3RhdGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBoYXNSZXN1bHQgPSBjb25kaXRpb24oc3RhdGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChoYXNSZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0ID0gcmVzdWx0U2VsZWN0b3Ioc3RhdGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aW1lID0gdGltZVNlbGVjdG9yKHN0YXRlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGNhdGNoIChlKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFzUmVzdWx0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2VsZih0aW1lKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIEdlbmVyYXRlcyBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGJ5IGl0ZXJhdGluZyBhIHN0YXRlIGZyb20gYW4gaW5pdGlhbCBzdGF0ZSB1bnRpbCB0aGUgY29uZGl0aW9uIGZhaWxzLlxyXG4gICAgICogXHJcbiAgICAgKiBAZXhhbXBsZSBcclxuICAgICAqICByZXMgPSBzb3VyY2UuZ2VuZXJhdGVXaXRoUmVsYXRpdmVUaW1lKDAsIFxyXG4gICAgICogICAgICBmdW5jdGlvbiAoeCkgeyByZXR1cm4gcmV0dXJuIHRydWU7IH0sIFxyXG4gICAgICogICAgICBmdW5jdGlvbiAoeCkgeyByZXR1cm4geCArIDE7IH0sIFxyXG4gICAgICogICAgICBmdW5jdGlvbiAoeCkgeyByZXR1cm4geDsgfSwgXHJcbiAgICAgKiAgICAgIGZ1bmN0aW9uICh4KSB7IHJldHVybiA1MDA7IH1cclxuICAgICAqICApO1xyXG4gICAgICogICAgICBcclxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IGluaXRpYWxTdGF0ZSBJbml0aWFsIHN0YXRlLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29uZGl0aW9uIENvbmRpdGlvbiB0byB0ZXJtaW5hdGUgZ2VuZXJhdGlvbiAodXBvbiByZXR1cm5pbmcgZmFsc2UpLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gaXRlcmF0ZSBJdGVyYXRpb24gc3RlcCBmdW5jdGlvbi5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHJlc3VsdFNlbGVjdG9yIFNlbGVjdG9yIGZ1bmN0aW9uIGZvciByZXN1bHRzIHByb2R1Y2VkIGluIHRoZSBzZXF1ZW5jZS5cclxuICAgICAqIEBwYXJhbSB7RnVuY3Rpb259IHRpbWVTZWxlY3RvciBUaW1lIHNlbGVjdG9yIGZ1bmN0aW9uIHRvIGNvbnRyb2wgdGhlIHNwZWVkIG9mIHZhbHVlcyBiZWluZyBwcm9kdWNlZCBlYWNoIGl0ZXJhdGlvbiwgcmV0dXJuaW5nIGludGVnZXIgdmFsdWVzIGRlbm90aW5nIG1pbGxpc2Vjb25kcy5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSAgU2NoZWR1bGVyIG9uIHdoaWNoIHRvIHJ1biB0aGUgZ2VuZXJhdG9yIGxvb3AuIElmIG5vdCBzcGVjaWZpZWQsIHRoZSB0aW1lb3V0IHNjaGVkdWxlciBpcyB1c2VkLlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IFRoZSBnZW5lcmF0ZWQgc2VxdWVuY2UuXHJcbiAgICAgKi9cclxuICAgIE9ic2VydmFibGUuZ2VuZXJhdGVXaXRoUmVsYXRpdmVUaW1lID0gZnVuY3Rpb24gKGluaXRpYWxTdGF0ZSwgY29uZGl0aW9uLCBpdGVyYXRlLCByZXN1bHRTZWxlY3RvciwgdGltZVNlbGVjdG9yLCBzY2hlZHVsZXIpIHtcclxuICAgICAgICBzY2hlZHVsZXIgfHwgKHNjaGVkdWxlciA9IHRpbWVvdXRTY2hlZHVsZXIpO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGZpcnN0ID0gdHJ1ZSxcclxuICAgICAgICAgICAgICAgIGhhc1Jlc3VsdCA9IGZhbHNlLFxyXG4gICAgICAgICAgICAgICAgcmVzdWx0LFxyXG4gICAgICAgICAgICAgICAgc3RhdGUgPSBpbml0aWFsU3RhdGUsXHJcbiAgICAgICAgICAgICAgICB0aW1lO1xyXG4gICAgICAgICAgICByZXR1cm4gc2NoZWR1bGVyLnNjaGVkdWxlUmVjdXJzaXZlV2l0aFJlbGF0aXZlKDAsIGZ1bmN0aW9uIChzZWxmKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFzUmVzdWx0KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChmaXJzdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBmaXJzdCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHN0YXRlID0gaXRlcmF0ZShzdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGhhc1Jlc3VsdCA9IGNvbmRpdGlvbihzdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc1Jlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZXN1bHRTZWxlY3RvcihzdGF0ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpbWUgPSB0aW1lU2VsZWN0b3Ioc3RhdGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGlmIChoYXNSZXN1bHQpIHtcclxuICAgICAgICAgICAgICAgICAgICBzZWxmKHRpbWUpO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgVGltZSBzaGlmdHMgdGhlIG9ic2VydmFibGUgc2VxdWVuY2UgYnkgZGVsYXlpbmcgdGhlIHN1YnNjcmlwdGlvbi5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgMSAtIHJlcyA9IHNvdXJjZS5kZWxheVN1YnNjcmlwdGlvbig1MDAwKTsgLy8gNXNcclxuICAgICAqICAyIC0gcmVzID0gc291cmNlLmRlbGF5U3Vic2NyaXB0aW9uKDUwMDAsIFJ4LlNjaGVkdWxlci50aW1lb3V0KTsgLy8gNSBzZWNvbmRzXHJcbiAgICAgKiAgICAgIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGR1ZVRpbWUgQWJzb2x1dGUgb3IgcmVsYXRpdmUgdGltZSB0byBwZXJmb3JtIHRoZSBzdWJzY3JpcHRpb24gYXQuXHJcbiAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gW3NjaGVkdWxlcl0gIFNjaGVkdWxlciB0byBydW4gdGhlIHN1YnNjcmlwdGlvbiBkZWxheSB0aW1lciBvbi4gSWYgbm90IHNwZWNpZmllZCwgdGhlIHRpbWVvdXQgc2NoZWR1bGVyIGlzIHVzZWQuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGltZS1zaGlmdGVkIHNlcXVlbmNlLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uZGVsYXlTdWJzY3JpcHRpb24gPSBmdW5jdGlvbiAoZHVlVGltZSwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSB0aW1lb3V0U2NoZWR1bGVyKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5kZWxheVdpdGhTZWxlY3RvcihvYnNlcnZhYmxlVGltZXIoZHVlVGltZSwgc2NoZWR1bGVyKSwgZnVuY3Rpb24gKCkgeyByZXR1cm4gb2JzZXJ2YWJsZUVtcHR5KCk7IH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBUaW1lIHNoaWZ0cyB0aGUgb2JzZXJ2YWJsZSBzZXF1ZW5jZSBiYXNlZCBvbiBhIHN1YnNjcmlwdGlvbiBkZWxheSBhbmQgYSBkZWxheSBzZWxlY3RvciBmdW5jdGlvbiBmb3IgZWFjaCBlbGVtZW50LlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICAxIC0gcmVzID0gc291cmNlLmRlbGF5V2l0aFNlbGVjdG9yKGZ1bmN0aW9uICh4KSB7IHJldHVybiBSeC5TY2hlZHVsZXIudGltZXIoNTAwMCk7IH0pOyAvLyB3aXRoIHNlbGVjdG9yIG9ubHlcclxuICAgICAqICAxIC0gcmVzID0gc291cmNlLmRlbGF5V2l0aFNlbGVjdG9yKFJ4Lk9ic2VydmFibGUudGltZXIoMjAwMCksIGZ1bmN0aW9uICh4KSB7IHJldHVybiBSeC5PYnNlcnZhYmxlLnRpbWVyKHgpOyB9KTsgLy8gd2l0aCBkZWxheSBhbmQgc2VsZWN0b3JcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge09ic2VydmFibGV9IFtzdWJzY3JpcHRpb25EZWxheV0gIFNlcXVlbmNlIGluZGljYXRpbmcgdGhlIGRlbGF5IGZvciB0aGUgc3Vic2NyaXB0aW9uIHRvIHRoZSBzb3VyY2UuIFxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gZGVsYXlEdXJhdGlvblNlbGVjdG9yIFNlbGVjdG9yIGZ1bmN0aW9uIHRvIHJldHJpZXZlIGEgc2VxdWVuY2UgaW5kaWNhdGluZyB0aGUgZGVsYXkgZm9yIGVhY2ggZ2l2ZW4gZWxlbWVudC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBUaW1lLXNoaWZ0ZWQgc2VxdWVuY2UuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by5kZWxheVdpdGhTZWxlY3RvciA9IGZ1bmN0aW9uIChzdWJzY3JpcHRpb25EZWxheSwgZGVsYXlEdXJhdGlvblNlbGVjdG9yKSB7XHJcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRoaXMsIHN1YkRlbGF5LCBzZWxlY3RvcjtcclxuICAgICAgICBpZiAodHlwZW9mIHN1YnNjcmlwdGlvbkRlbGF5ID09PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgICAgIHNlbGVjdG9yID0gc3Vic2NyaXB0aW9uRGVsYXk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgc3ViRGVsYXkgPSBzdWJzY3JpcHRpb25EZWxheTtcclxuICAgICAgICAgICAgc2VsZWN0b3IgPSBkZWxheUR1cmF0aW9uU2VsZWN0b3I7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIGRlbGF5cyA9IG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKCksIGF0RW5kID0gZmFsc2UsIGRvbmUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoYXRFbmQgJiYgZGVsYXlzLmxlbmd0aCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sIHN1YnNjcmlwdGlvbiA9IG5ldyBTZXJpYWxEaXNwb3NhYmxlKCksIHN0YXJ0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnNldERpc3Bvc2FibGUoc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkZWxheTtcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxheSA9IHNlbGVjdG9yKHgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXJyb3IpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHZhciBkID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZGVsYXlzLmFkZChkKTtcclxuICAgICAgICAgICAgICAgICAgICBkLnNldERpc3Bvc2FibGUoZGVsYXkuc3Vic2NyaWJlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkZWxheXMucmVtb3ZlKGQpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBkb25lKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQoeCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRlbGF5cy5yZW1vdmUoZCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGRvbmUoKTtcclxuICAgICAgICAgICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgYXRFbmQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZG9uZSgpO1xyXG4gICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgaWYgKCFzdWJEZWxheSkge1xyXG4gICAgICAgICAgICAgICAgc3RhcnQoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi5zZXREaXNwb3NhYmxlKHN1YkRlbGF5LnN1YnNjcmliZShmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc3RhcnQoKTtcclxuICAgICAgICAgICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIGZ1bmN0aW9uICgpIHsgc3RhcnQoKTsgfSkpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc3Vic2NyaXB0aW9uLCBkZWxheXMpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBSZXR1cm5zIHRoZSBzb3VyY2Ugb2JzZXJ2YWJsZSBzZXF1ZW5jZSwgc3dpdGNoaW5nIHRvIHRoZSBvdGhlciBvYnNlcnZhYmxlIHNlcXVlbmNlIGlmIGEgdGltZW91dCBpcyBzaWduYWxlZC5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgMSAtIHJlcyA9IHNvdXJjZS50aW1lb3V0V2l0aFNlbGVjdG9yKFJ4Lk9ic2VydmFibGUudGltZXIoNTAwKSk7IFxyXG4gICAgICogIDIgLSByZXMgPSBzb3VyY2UudGltZW91dFdpdGhTZWxlY3RvcihSeC5PYnNlcnZhYmxlLnRpbWVyKDUwMCksIGZ1bmN0aW9uICh4KSB7IHJldHVybiBSeC5PYnNlcnZhYmxlLnRpbWVyKDIwMCk7IH0pO1xyXG4gICAgICogIDMgLSByZXMgPSBzb3VyY2UudGltZW91dFdpdGhTZWxlY3RvcihSeC5PYnNlcnZhYmxlLnRpbWVyKDUwMCksIGZ1bmN0aW9uICh4KSB7IHJldHVybiBSeC5PYnNlcnZhYmxlLnRpbWVyKDIwMCk7IH0sIFJ4Lk9ic2VydmFibGUucmV0dXJuVmFsdWUoNDIpKTtcclxuICAgICAqICAgICAgXHJcbiAgICAgKiBAcGFyYW0ge09ic2VydmFibGV9IFtmaXJzdFRpbWVvdXRdICBPYnNlcnZhYmxlIHNlcXVlbmNlIHRoYXQgcmVwcmVzZW50cyB0aGUgdGltZW91dCBmb3IgdGhlIGZpcnN0IGVsZW1lbnQuIElmIG5vdCBwcm92aWRlZCwgdGhpcyBkZWZhdWx0cyB0byBPYnNlcnZhYmxlLm5ldmVyKCkuXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbdGltZW91dER1cmF0aW9uU2VsZWN0b3JdIFNlbGVjdG9yIHRvIHJldHJpZXZlIGFuIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCByZXByZXNlbnRzIHRoZSB0aW1lb3V0IGJldHdlZW4gdGhlIGN1cnJlbnQgZWxlbWVudCBhbmQgdGhlIG5leHQgZWxlbWVudC5cclxuICAgICAqIEBwYXJhbSB7T2JzZXJ2YWJsZX0gW290aGVyXSAgU2VxdWVuY2UgdG8gcmV0dXJuIGluIGNhc2Ugb2YgYSB0aW1lb3V0LiBJZiBub3QgcHJvdmlkZWQsIHRoaXMgaXMgc2V0IHRvIE9ic2VydmFibGUudGhyb3dFeGNlcHRpb24oKS4gXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gVGhlIHNvdXJjZSBzZXF1ZW5jZSBzd2l0Y2hpbmcgdG8gdGhlIG90aGVyIHNlcXVlbmNlIGluIGNhc2Ugb2YgYSB0aW1lb3V0LlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8udGltZW91dFdpdGhTZWxlY3RvciA9IGZ1bmN0aW9uIChmaXJzdFRpbWVvdXQsIHRpbWVvdXRkdXJhdGlvblNlbGVjdG9yLCBvdGhlcikge1xyXG4gICAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgIHRpbWVvdXRkdXJhdGlvblNlbGVjdG9yID0gZmlyc3RUaW1lb3V0O1xyXG4gICAgICAgICAgICB2YXIgZmlyc3RUaW1lb3V0ID0gb2JzZXJ2YWJsZU5ldmVyKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIG90aGVyIHx8IChvdGhlciA9IG9ic2VydmFibGVUaHJvdyhuZXcgRXJyb3IoJ1RpbWVvdXQnKSkpO1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIHN1YnNjcmlwdGlvbiA9IG5ldyBTZXJpYWxEaXNwb3NhYmxlKCksIHRpbWVyID0gbmV3IFNlcmlhbERpc3Bvc2FibGUoKSwgb3JpZ2luYWwgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuXHJcbiAgICAgICAgICAgIHN1YnNjcmlwdGlvbi5zZXREaXNwb3NhYmxlKG9yaWdpbmFsKTtcclxuXHJcbiAgICAgICAgICAgIHZhciBpZCA9IDAsIHN3aXRjaGVkID0gZmFsc2UsIHNldFRpbWVyID0gZnVuY3Rpb24gKHRpbWVvdXQpIHtcclxuICAgICAgICAgICAgICAgIHZhciBteUlkID0gaWQsIHRpbWVyV2lucyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaWQgPT09IG15SWQ7XHJcbiAgICAgICAgICAgICAgICB9O1xyXG4gICAgICAgICAgICAgICAgdmFyIGQgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgICAgIHRpbWVyLnNldERpc3Bvc2FibGUoZCk7XHJcbiAgICAgICAgICAgICAgICBkLnNldERpc3Bvc2FibGUodGltZW91dC5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aW1lcldpbnMoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24uc2V0RGlzcG9zYWJsZShvdGhlci5zdWJzY3JpYmUob2JzZXJ2ZXIpKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgZC5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB9LCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICh0aW1lcldpbnMoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0sIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAodGltZXJXaW5zKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgc3Vic2NyaXB0aW9uLnNldERpc3Bvc2FibGUob3RoZXIuc3Vic2NyaWJlKG9ic2VydmVyKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICB9O1xyXG5cclxuICAgICAgICAgICAgc2V0VGltZXIoZmlyc3RUaW1lb3V0KTtcclxuICAgICAgICAgICAgdmFyIG9ic2VydmVyV2lucyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHZhciByZXMgPSAhc3dpdGNoZWQ7XHJcbiAgICAgICAgICAgICAgICBpZiAocmVzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWQrKztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHJldHVybiByZXM7XHJcbiAgICAgICAgICAgIH07XHJcblxyXG4gICAgICAgICAgICBvcmlnaW5hbC5zZXREaXNwb3NhYmxlKHNvdXJjZS5zdWJzY3JpYmUoZnVuY3Rpb24gKHgpIHtcclxuICAgICAgICAgICAgICAgIGlmIChvYnNlcnZlcldpbnMoKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh4KTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgdGltZW91dDtcclxuICAgICAgICAgICAgICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB0aW1lb3V0ID0gdGltZW91dGR1cmF0aW9uU2VsZWN0b3IoeCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIHNldFRpbWVyKHRpbWVvdXQpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoZSkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG9ic2VydmVyV2lucygpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKG9ic2VydmVyV2lucygpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc3Vic2NyaXB0aW9uLCB0aW1lcik7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIElnbm9yZXMgdmFsdWVzIGZyb20gYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aGljaCBhcmUgZm9sbG93ZWQgYnkgYW5vdGhlciB2YWx1ZSB3aXRoaW4gYSBjb21wdXRlZCB0aHJvdHRsZSBkdXJhdGlvbi5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgMSAtIHJlcyA9IHNvdXJjZS5kZWxheVdpdGhTZWxlY3RvcihmdW5jdGlvbiAoeCkgeyByZXR1cm4gUnguU2NoZWR1bGVyLnRpbWVyKHggKyB4KTsgfSk7IFxyXG4gICAgICogXHJcbiAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSB0aHJvdHRsZUR1cmF0aW9uU2VsZWN0b3IgU2VsZWN0b3IgZnVuY3Rpb24gdG8gcmV0cmlldmUgYSBzZXF1ZW5jZSBpbmRpY2F0aW5nIHRoZSB0aHJvdHRsZSBkdXJhdGlvbiBmb3IgZWFjaCBnaXZlbiBlbGVtZW50LlxyXG4gICAgICogQHJldHVybnMge09ic2VydmFibGV9IFRoZSB0aHJvdHRsZWQgc2VxdWVuY2UuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by50aHJvdHRsZVdpdGhTZWxlY3RvciA9IGZ1bmN0aW9uICh0aHJvdHRsZUR1cmF0aW9uU2VsZWN0b3IpIHtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciB2YWx1ZSwgaGFzVmFsdWUgPSBmYWxzZSwgY2FuY2VsYWJsZSA9IG5ldyBTZXJpYWxEaXNwb3NhYmxlKCksIGlkID0gMCwgc3Vic2NyaXB0aW9uID0gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHRocm90dGxlO1xyXG4gICAgICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdHRsZSA9IHRocm90dGxlRHVyYXRpb25TZWxlY3Rvcih4KTtcclxuICAgICAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGhhc1ZhbHVlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHZhbHVlID0geDtcclxuICAgICAgICAgICAgICAgIGlkKys7XHJcbiAgICAgICAgICAgICAgICB2YXIgY3VycmVudGlkID0gaWQsIGQgPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgICAgIGNhbmNlbGFibGUuc2V0RGlzcG9zYWJsZShkKTtcclxuICAgICAgICAgICAgICAgIGQuc2V0RGlzcG9zYWJsZSh0aHJvdHRsZS5zdWJzY3JpYmUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChoYXNWYWx1ZSAmJiBpZCA9PT0gY3VycmVudGlkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGhhc1ZhbHVlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgZC5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGhhc1ZhbHVlICYmIGlkID09PSBjdXJyZW50aWQpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgaGFzVmFsdWUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICBkLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgfSwgZnVuY3Rpb24gKGUpIHtcclxuICAgICAgICAgICAgICAgIGNhbmNlbGFibGUuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcihlKTtcclxuICAgICAgICAgICAgICAgIGhhc1ZhbHVlID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICBpZCsrO1xyXG4gICAgICAgICAgICB9LCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBjYW5jZWxhYmxlLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgIGlmIChoYXNWYWx1ZSkge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dCh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgaGFzVmFsdWUgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgIGlkKys7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc3Vic2NyaXB0aW9uLCBjYW5jZWxhYmxlKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgU2tpcHMgZWxlbWVudHMgZm9yIHRoZSBzcGVjaWZpZWQgZHVyYXRpb24gZnJvbSB0aGUgZW5kIG9mIHRoZSBvYnNlcnZhYmxlIHNvdXJjZSBzZXF1ZW5jZSwgdXNpbmcgdGhlIHNwZWNpZmllZCBzY2hlZHVsZXIgdG8gcnVuIHRpbWVycy5cclxuICAgICAqICBcclxuICAgICAqICAxIC0gcmVzID0gc291cmNlLnNraXBMYXN0V2l0aFRpbWUoNTAwMCk7ICAgICBcclxuICAgICAqICAyIC0gcmVzID0gc291cmNlLnNraXBMYXN0V2l0aFRpbWUoNTAwMCwgc2NoZWR1bGVyKTsgXHJcbiAgICAgKiAgICAgIFxyXG4gICAgICogQGRlc2NyaXB0aW9uXHJcbiAgICAgKiAgVGhpcyBvcGVyYXRvciBhY2N1bXVsYXRlcyBhIHF1ZXVlIHdpdGggYSBsZW5ndGggZW5vdWdoIHRvIHN0b3JlIGVsZW1lbnRzIHJlY2VpdmVkIGR1cmluZyB0aGUgaW5pdGlhbCBkdXJhdGlvbiB3aW5kb3cuXHJcbiAgICAgKiAgQXMgbW9yZSBlbGVtZW50cyBhcmUgcmVjZWl2ZWQsIGVsZW1lbnRzIG9sZGVyIHRoYW4gdGhlIHNwZWNpZmllZCBkdXJhdGlvbiBhcmUgdGFrZW4gZnJvbSB0aGUgcXVldWUgYW5kIHByb2R1Y2VkIG9uIHRoZVxyXG4gICAgICogIHJlc3VsdCBzZXF1ZW5jZS4gVGhpcyBjYXVzZXMgZWxlbWVudHMgdG8gYmUgZGVsYXllZCB3aXRoIGR1cmF0aW9uLiAgICAgICAgICBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkdXJhdGlvbiBEdXJhdGlvbiBmb3Igc2tpcHBpbmcgZWxlbWVudHMgZnJvbSB0aGUgZW5kIG9mIHRoZSBzZXF1ZW5jZS5cclxuICAgICAqIEBwYXJhbSB7U2NoZWR1bGVyfSBbc2NoZWR1bGVyXSAgU2NoZWR1bGVyIHRvIHJ1biB0aGUgdGltZXIgb24uIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIFJ4LlNjaGVkdWxlci50aW1lb3V0XHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aXRoIHRoZSBlbGVtZW50cyBza2lwcGVkIGR1cmluZyB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uIGZyb20gdGhlIGVuZCBvZiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8uc2tpcExhc3RXaXRoVGltZSA9IGZ1bmN0aW9uIChkdXJhdGlvbiwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSB0aW1lb3V0U2NoZWR1bGVyKTtcclxuICAgICAgICB2YXIgc291cmNlID0gdGhpcztcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBxID0gW107XHJcbiAgICAgICAgICAgIHJldHVybiBzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbm93ID0gc2NoZWR1bGVyLm5vdygpO1xyXG4gICAgICAgICAgICAgICAgcS5wdXNoKHsgaW50ZXJ2YWw6IG5vdywgdmFsdWU6IHggfSk7XHJcbiAgICAgICAgICAgICAgICB3aGlsZSAocS5sZW5ndGggPiAwICYmIG5vdyAtIHFbMF0uaW50ZXJ2YWwgPj0gZHVyYXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQocS5zaGlmdCgpLnZhbHVlKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSwgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG5vdyA9IHNjaGVkdWxlci5ub3coKTtcclxuICAgICAgICAgICAgICAgIHdoaWxlIChxLmxlbmd0aCA+IDAgJiYgbm93IC0gcVswXS5pbnRlcnZhbCA+PSBkdXJhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uTmV4dChxLnNoaWZ0KCkudmFsdWUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFJldHVybnMgZWxlbWVudHMgd2l0aGluIHRoZSBzcGVjaWZpZWQgZHVyYXRpb24gZnJvbSB0aGUgZW5kIG9mIHRoZSBvYnNlcnZhYmxlIHNvdXJjZSBzZXF1ZW5jZSwgdXNpbmcgdGhlIHNwZWNpZmllZCBzY2hlZHVsZXJzIHRvIHJ1biB0aW1lcnMgYW5kIHRvIGRyYWluIHRoZSBjb2xsZWN0ZWQgZWxlbWVudHMuXHJcbiAgICAgKiAgXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIDEgLSByZXMgPSBzb3VyY2UudGFrZUxhc3RXaXRoVGltZSg1MDAwLCBbb3B0aW9uYWwgdGltZXIgc2NoZWR1bGVyXSwgW29wdGlvbmFsIGxvb3Agc2NoZWR1bGVyXSk7IFxyXG4gICAgICogQGRlc2NyaXB0aW9uXHJcbiAgICAgKiAgVGhpcyBvcGVyYXRvciBhY2N1bXVsYXRlcyBhIHF1ZXVlIHdpdGggYSBsZW5ndGggZW5vdWdoIHRvIHN0b3JlIGVsZW1lbnRzIHJlY2VpdmVkIGR1cmluZyB0aGUgaW5pdGlhbCBkdXJhdGlvbiB3aW5kb3cuXHJcbiAgICAgKiAgQXMgbW9yZSBlbGVtZW50cyBhcmUgcmVjZWl2ZWQsIGVsZW1lbnRzIG9sZGVyIHRoYW4gdGhlIHNwZWNpZmllZCBkdXJhdGlvbiBhcmUgdGFrZW4gZnJvbSB0aGUgcXVldWUgYW5kIHByb2R1Y2VkIG9uIHRoZVxyXG4gICAgICogIHJlc3VsdCBzZXF1ZW5jZS4gVGhpcyBjYXVzZXMgZWxlbWVudHMgdG8gYmUgZGVsYXllZCB3aXRoIGR1cmF0aW9uLiAgICBcclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSBkdXJhdGlvbiBEdXJhdGlvbiBmb3IgdGFraW5nIGVsZW1lbnRzIGZyb20gdGhlIGVuZCBvZiB0aGUgc2VxdWVuY2UuXHJcbiAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gW3RpbWVyU2NoZWR1bGVyXSAgU2NoZWR1bGVyIHRvIHJ1biB0aGUgdGltZXIgb24uIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIFJ4LlNjaGVkdWxlci50aW1lb3V0LlxyXG4gICAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtsb29wU2NoZWR1bGVyXSAgU2NoZWR1bGVyIHRvIGRyYWluIHRoZSBjb2xsZWN0ZWQgZWxlbWVudHMuIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIFJ4LlNjaGVkdWxlci5pbW1lZGlhdGUuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aXRoIHRoZSBlbGVtZW50cyB0YWtlbiBkdXJpbmcgdGhlIHNwZWNpZmllZCBkdXJhdGlvbiBmcm9tIHRoZSBlbmQgb2YgdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnRha2VMYXN0V2l0aFRpbWUgPSBmdW5jdGlvbiAoZHVyYXRpb24sIHRpbWVyU2NoZWR1bGVyLCBsb29wU2NoZWR1bGVyKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudGFrZUxhc3RCdWZmZXJXaXRoVGltZShkdXJhdGlvbiwgdGltZXJTY2hlZHVsZXIpLnNlbGVjdE1hbnkoZnVuY3Rpb24gKHhzKSB7IHJldHVybiBvYnNlcnZhYmxlRnJvbUFycmF5KHhzLCBsb29wU2NoZWR1bGVyKTsgfSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogIFJldHVybnMgYW4gYXJyYXkgd2l0aCB0aGUgZWxlbWVudHMgd2l0aGluIHRoZSBzcGVjaWZpZWQgZHVyYXRpb24gZnJvbSB0aGUgZW5kIG9mIHRoZSBvYnNlcnZhYmxlIHNvdXJjZSBzZXF1ZW5jZSwgdXNpbmcgdGhlIHNwZWNpZmllZCBzY2hlZHVsZXIgdG8gcnVuIHRpbWVycy5cclxuICAgICAqICBcclxuICAgICAqIEBleGFtcGxlXHJcbiAgICAgKiAgMSAtIHJlcyA9IHNvdXJjZS50YWtlTGFzdEJ1ZmZlcldpdGhUaW1lKDUwMDAsIFtvcHRpb25hbCBzY2hlZHVsZXJdKTsgXHJcbiAgICAgKiBAZGVzY3JpcHRpb25cclxuICAgICAqICBUaGlzIG9wZXJhdG9yIGFjY3VtdWxhdGVzIGEgcXVldWUgd2l0aCBhIGxlbmd0aCBlbm91Z2ggdG8gc3RvcmUgZWxlbWVudHMgcmVjZWl2ZWQgZHVyaW5nIHRoZSBpbml0aWFsIGR1cmF0aW9uIHdpbmRvdy5cclxuICAgICAqICBBcyBtb3JlIGVsZW1lbnRzIGFyZSByZWNlaXZlZCwgZWxlbWVudHMgb2xkZXIgdGhhbiB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uIGFyZSB0YWtlbiBmcm9tIHRoZSBxdWV1ZSBhbmQgcHJvZHVjZWQgb24gdGhlXHJcbiAgICAgKiAgcmVzdWx0IHNlcXVlbmNlLiBUaGlzIGNhdXNlcyBlbGVtZW50cyB0byBiZSBkZWxheWVkIHdpdGggZHVyYXRpb24uICAgXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZHVyYXRpb24gRHVyYXRpb24gZm9yIHRha2luZyBlbGVtZW50cyBmcm9tIHRoZSBlbmQgb2YgdGhlIHNlcXVlbmNlLlxyXG4gICAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IHNjaGVkdWxlciBTY2hlZHVsZXIgdG8gcnVuIHRoZSB0aW1lciBvbi4gSWYgbm90IHNwZWNpZmllZCwgZGVmYXVsdHMgdG8gUnguU2NoZWR1bGVyLnRpbWVvdXQuXHJcbiAgICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBjb250YWluaW5nIGEgc2luZ2xlIGFycmF5IHdpdGggdGhlIGVsZW1lbnRzIHRha2VuIGR1cmluZyB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uIGZyb20gdGhlIGVuZCBvZiB0aGUgc291cmNlIHNlcXVlbmNlLlxyXG4gICAgICovXHJcbiAgICBvYnNlcnZhYmxlUHJvdG8udGFrZUxhc3RCdWZmZXJXaXRoVGltZSA9IGZ1bmN0aW9uIChkdXJhdGlvbiwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRoaXM7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSB0aW1lb3V0U2NoZWR1bGVyKTtcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBxID0gW107XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gc291cmNlLnN1YnNjcmliZShmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIG5vdyA9IHNjaGVkdWxlci5ub3coKTtcclxuICAgICAgICAgICAgICAgIHEucHVzaCh7IGludGVydmFsOiBub3csIHZhbHVlOiB4IH0pO1xyXG4gICAgICAgICAgICAgICAgd2hpbGUgKHEubGVuZ3RoID4gMCAmJiBub3cgLSBxWzBdLmludGVydmFsID49IGR1cmF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcS5zaGlmdCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LCBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbm93ID0gc2NoZWR1bGVyLm5vdygpLCByZXMgPSBbXTtcclxuICAgICAgICAgICAgICAgIHdoaWxlIChxLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgbmV4dCA9IHEuc2hpZnQoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobm93IC0gbmV4dC5pbnRlcnZhbCA8PSBkdXJhdGlvbikge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXMucHVzaChuZXh0LnZhbHVlKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHJlcyk7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgVGFrZXMgZWxlbWVudHMgZm9yIHRoZSBzcGVjaWZpZWQgZHVyYXRpb24gZnJvbSB0aGUgc3RhcnQgb2YgdGhlIG9ic2VydmFibGUgc291cmNlIHNlcXVlbmNlLCB1c2luZyB0aGUgc3BlY2lmaWVkIHNjaGVkdWxlciB0byBydW4gdGltZXJzLlxyXG4gICAgICogIFxyXG4gICAgICogQGV4YW1wbGVcclxuICAgICAqICAxIC0gcmVzID0gc291cmNlLnRha2VXaXRoVGltZSg1MDAwLCAgW29wdGlvbmFsIHNjaGVkdWxlcl0pOyBcclxuICAgICAqIEBkZXNjcmlwdGlvblxyXG4gICAgICogIFRoaXMgb3BlcmF0b3IgYWNjdW11bGF0ZXMgYSBxdWV1ZSB3aXRoIGEgbGVuZ3RoIGVub3VnaCB0byBzdG9yZSBlbGVtZW50cyByZWNlaXZlZCBkdXJpbmcgdGhlIGluaXRpYWwgZHVyYXRpb24gd2luZG93LlxyXG4gICAgICogIEFzIG1vcmUgZWxlbWVudHMgYXJlIHJlY2VpdmVkLCBlbGVtZW50cyBvbGRlciB0aGFuIHRoZSBzcGVjaWZpZWQgZHVyYXRpb24gYXJlIHRha2VuIGZyb20gdGhlIHF1ZXVlIGFuZCBwcm9kdWNlZCBvbiB0aGVcclxuICAgICAqICByZXN1bHQgc2VxdWVuY2UuIFRoaXMgY2F1c2VzIGVsZW1lbnRzIHRvIGJlIGRlbGF5ZWQgd2l0aCBkdXJhdGlvbi4gICAgXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gZHVyYXRpb24gRHVyYXRpb24gZm9yIHRha2luZyBlbGVtZW50cyBmcm9tIHRoZSBzdGFydCBvZiB0aGUgc2VxdWVuY2UuXHJcbiAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gc2NoZWR1bGVyIFNjaGVkdWxlciB0byBydW4gdGhlIHRpbWVyIG9uLiBJZiBub3Qgc3BlY2lmaWVkLCBkZWZhdWx0cyB0byBSeC5TY2hlZHVsZXIudGltZW91dC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdpdGggdGhlIGVsZW1lbnRzIHRha2VuIGR1cmluZyB0aGUgc3BlY2lmaWVkIGR1cmF0aW9uIGZyb20gdGhlIHN0YXJ0IG9mIHRoZSBzb3VyY2Ugc2VxdWVuY2UuXHJcbiAgICAgKi9cclxuICAgIG9ic2VydmFibGVQcm90by50YWtlV2l0aFRpbWUgPSBmdW5jdGlvbiAoZHVyYXRpb24sIHNjaGVkdWxlcikge1xyXG4gICAgICAgIHZhciBzb3VyY2UgPSB0aGlzO1xyXG4gICAgICAgIHNjaGVkdWxlciB8fCAoc2NoZWR1bGVyID0gdGltZW91dFNjaGVkdWxlcik7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICAgICAgICB2YXIgdCA9IHNjaGVkdWxlci5zY2hlZHVsZVdpdGhSZWxhdGl2ZShkdXJhdGlvbiwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUodCwgc291cmNlLnN1YnNjcmliZShvYnNlcnZlcikpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBTa2lwcyBlbGVtZW50cyBmb3IgdGhlIHNwZWNpZmllZCBkdXJhdGlvbiBmcm9tIHRoZSBzdGFydCBvZiB0aGUgb2JzZXJ2YWJsZSBzb3VyY2Ugc2VxdWVuY2UsIHVzaW5nIHRoZSBzcGVjaWZpZWQgc2NoZWR1bGVyIHRvIHJ1biB0aW1lcnMuXHJcbiAgICAgKiAgXHJcbiAgICAgKiBAZXhhbXBsZVxyXG4gICAgICogIDEgLSByZXMgPSBzb3VyY2Uuc2tpcFdpdGhUaW1lKDUwMDAsIFtvcHRpb25hbCBzY2hlZHVsZXJdKTsgXHJcbiAgICAgKiAgXHJcbiAgICAgKiBAZGVzY3JpcHRpb24gICAgIFxyXG4gICAgICogIFNwZWNpZnlpbmcgYSB6ZXJvIHZhbHVlIGZvciBkdXJhdGlvbiBkb2Vzbid0IGd1YXJhbnRlZSBubyBlbGVtZW50cyB3aWxsIGJlIGRyb3BwZWQgZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqICBUaGlzIGlzIGEgc2lkZS1lZmZlY3Qgb2YgdGhlIGFzeW5jaHJvbnkgaW50cm9kdWNlZCBieSB0aGUgc2NoZWR1bGVyLCB3aGVyZSB0aGUgYWN0aW9uIHRoYXQgY2F1c2VzIGNhbGxiYWNrcyBmcm9tIHRoZSBzb3VyY2Ugc2VxdWVuY2UgdG8gYmUgZm9yd2FyZGVkXHJcbiAgICAgKiAgbWF5IG5vdCBleGVjdXRlIGltbWVkaWF0ZWx5LCBkZXNwaXRlIHRoZSB6ZXJvIGR1ZSB0aW1lLlxyXG4gICAgICogIFxyXG4gICAgICogIEVycm9ycyBwcm9kdWNlZCBieSB0aGUgc291cmNlIHNlcXVlbmNlIGFyZSBhbHdheXMgZm9yd2FyZGVkIHRvIHRoZSByZXN1bHQgc2VxdWVuY2UsIGV2ZW4gaWYgdGhlIGVycm9yIG9jY3VycyBiZWZvcmUgdGhlIGR1cmF0aW9uLiAgICAgIFxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IGR1cmF0aW9uIER1cmF0aW9uIGZvciBza2lwcGluZyBlbGVtZW50cyBmcm9tIHRoZSBzdGFydCBvZiB0aGUgc2VxdWVuY2UuXHJcbiAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gc2NoZWR1bGVyIFNjaGVkdWxlciB0byBydW4gdGhlIHRpbWVyIG9uLiBJZiBub3Qgc3BlY2lmaWVkLCBkZWZhdWx0cyB0byBSeC5TY2hlZHVsZXIudGltZW91dC5cclxuICAgICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdpdGggdGhlIGVsZW1lbnRzIHNraXBwZWQgZHVyaW5nIHRoZSBzcGVjaWZpZWQgZHVyYXRpb24gZnJvbSB0aGUgc3RhcnQgb2YgdGhlIHNvdXJjZSBzZXF1ZW5jZS5cclxuICAgICAqL1xyXG4gICAgb2JzZXJ2YWJsZVByb3RvLnNraXBXaXRoVGltZSA9IGZ1bmN0aW9uIChkdXJhdGlvbiwgc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgdmFyIHNvdXJjZSA9IHRoaXM7XHJcbiAgICAgICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSB0aW1lb3V0U2NoZWR1bGVyKTtcclxuICAgICAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBvcGVuID0gZmFsc2UsXHJcbiAgICAgICAgICAgICAgICB0ID0gc2NoZWR1bGVyLnNjaGVkdWxlV2l0aFJlbGF0aXZlKGR1cmF0aW9uLCBmdW5jdGlvbiAoKSB7IG9wZW4gPSB0cnVlOyB9KSxcclxuICAgICAgICAgICAgICAgIGQgPSBzb3VyY2Uuc3Vic2NyaWJlKGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG9wZW4pIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH0sIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksIG9ic2VydmVyLm9uQ29tcGxldGVkLmJpbmQob2JzZXJ2ZXIpKTtcclxuXHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZSh0LCBkKTtcclxuICAgICAgICB9KTtcclxuICAgIH07XHJcblxyXG4gIC8qKlxyXG4gICAqICBTa2lwcyBlbGVtZW50cyBmcm9tIHRoZSBvYnNlcnZhYmxlIHNvdXJjZSBzZXF1ZW5jZSB1bnRpbCB0aGUgc3BlY2lmaWVkIHN0YXJ0IHRpbWUsIHVzaW5nIHRoZSBzcGVjaWZpZWQgc2NoZWR1bGVyIHRvIHJ1biB0aW1lcnMuXHJcbiAgICogIEVycm9ycyBwcm9kdWNlZCBieSB0aGUgc291cmNlIHNlcXVlbmNlIGFyZSBhbHdheXMgZm9yd2FyZGVkIHRvIHRoZSByZXN1bHQgc2VxdWVuY2UsIGV2ZW4gaWYgdGhlIGVycm9yIG9jY3VycyBiZWZvcmUgdGhlIHN0YXJ0IHRpbWUuXHJcbiAgICogIFxyXG4gICAqIEBleGFtcGxlc1xyXG4gICAqICAxIC0gcmVzID0gc291cmNlLnNraXBVbnRpbFdpdGhUaW1lKG5ldyBEYXRlKCksIFtvcHRpb25hbCBzY2hlZHVsZXJdKTsgICBcclxuICAgKiAgMiAtIHJlcyA9IHNvdXJjZS5za2lwVW50aWxXaXRoVGltZSg1MDAwLCBbb3B0aW9uYWwgc2NoZWR1bGVyXSk7ICAgICAgICAgICBcclxuICAgKiBAcGFyYW0gc3RhcnRUaW1lIFRpbWUgdG8gc3RhcnQgdGFraW5nIGVsZW1lbnRzIGZyb20gdGhlIHNvdXJjZSBzZXF1ZW5jZS4gSWYgdGhpcyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gRGF0ZSgpLCBubyBlbGVtZW50cyB3aWxsIGJlIHNraXBwZWQuXHJcbiAgICogQHBhcmFtIHNjaGVkdWxlciBTY2hlZHVsZXIgdG8gcnVuIHRoZSB0aW1lciBvbi4gSWYgbm90IHNwZWNpZmllZCwgZGVmYXVsdHMgdG8gUnguU2NoZWR1bGVyLnRpbWVvdXQuXHJcbiAgICogQHJldHVybnMge09ic2VydmFibGV9IEFuIG9ic2VydmFibGUgc2VxdWVuY2Ugd2l0aCB0aGUgZWxlbWVudHMgc2tpcHBlZCB1bnRpbCB0aGUgc3BlY2lmaWVkIHN0YXJ0IHRpbWUuIFxyXG4gICAqL1xyXG4gIG9ic2VydmFibGVQcm90by5za2lwVW50aWxXaXRoVGltZSA9IGZ1bmN0aW9uIChzdGFydFRpbWUsIHNjaGVkdWxlcikge1xyXG4gICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSB0aW1lb3V0U2NoZWR1bGVyKTtcclxuICAgIHZhciBzb3VyY2UgPSB0aGlzLCBzY2hlZHVsZXJNZXRob2QgPSBzdGFydFRpbWUgaW5zdGFuY2VvZiBEYXRlID9cclxuICAgICAgJ3NjaGVkdWxlV2l0aEFic29sdXRlJyA6XHJcbiAgICAgICdzY2hlZHVsZVdpdGhSZWxhdGl2ZSc7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciBvcGVuID0gZmFsc2U7XHJcblxyXG4gICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoXHJcbiAgICAgICAgc2NoZWR1bGVyW3NjaGVkdWxlck1ldGhvZF0oc3RhcnRUaW1lLCBmdW5jdGlvbiAoKSB7IG9wZW4gPSB0cnVlOyB9KSxcclxuICAgICAgICBzb3VyY2Uuc3Vic2NyaWJlKFxyXG4gICAgICAgICAgZnVuY3Rpb24gKHgpIHsgb3BlbiAmJiBvYnNlcnZlci5vbk5leHQoeCk7IH0sIFxyXG4gICAgICAgICAgb2JzZXJ2ZXIub25FcnJvci5iaW5kKG9ic2VydmVyKSxcclxuICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkLmJpbmQob2JzZXJ2ZXIpKSk7XHJcbiAgICB9KTtcclxuICB9O1xyXG5cclxuICAvKipcclxuICAgKiAgVGFrZXMgZWxlbWVudHMgZm9yIHRoZSBzcGVjaWZpZWQgZHVyYXRpb24gdW50aWwgdGhlIHNwZWNpZmllZCBlbmQgdGltZSwgdXNpbmcgdGhlIHNwZWNpZmllZCBzY2hlZHVsZXIgdG8gcnVuIHRpbWVycy5cclxuICAgKiAgXHJcbiAgICogQGV4YW1wbGVcclxuICAgKiAgMSAtIHJlcyA9IHNvdXJjZS50YWtlVW50aWxXaXRoVGltZShuZXcgRGF0ZSgpLCBbb3B0aW9uYWwgc2NoZWR1bGVyXSk7XHJcbiAgICogIDIgLSByZXMgPSBzb3VyY2UudGFrZVVudGlsV2l0aFRpbWUoNTAwMCwgW29wdGlvbmFsIHNjaGVkdWxlcl0pOyAgIFxyXG4gICAqIEBwYXJhbSB7TnVtYmVyIHwgRGF0ZX0gZW5kVGltZSBUaW1lIHRvIHN0b3AgdGFraW5nIGVsZW1lbnRzIGZyb20gdGhlIHNvdXJjZSBzZXF1ZW5jZS4gSWYgdGhpcyB2YWx1ZSBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8gbmV3IERhdGUoKSwgdGhlIHJlc3VsdCBzdHJlYW0gd2lsbCBjb21wbGV0ZSBpbW1lZGlhdGVseS5cclxuICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gc2NoZWR1bGVyIFNjaGVkdWxlciB0byBydW4gdGhlIHRpbWVyIG9uLlxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHdpdGggdGhlIGVsZW1lbnRzIHRha2VuIHVudGlsIHRoZSBzcGVjaWZpZWQgZW5kIHRpbWUuXHJcbiAgICovXHJcbiAgb2JzZXJ2YWJsZVByb3RvLnRha2VVbnRpbFdpdGhUaW1lID0gZnVuY3Rpb24gKGVuZFRpbWUsIHNjaGVkdWxlcikge1xyXG4gICAgc2NoZWR1bGVyIHx8IChzY2hlZHVsZXIgPSB0aW1lb3V0U2NoZWR1bGVyKTtcclxuICAgIHZhciBzb3VyY2UgPSB0aGlzLCBzY2hlZHVsZXJNZXRob2QgPSBlbmRUaW1lIGluc3RhbmNlb2YgRGF0ZSA/XHJcbiAgICAgICdzY2hlZHVsZVdpdGhBYnNvbHV0ZScgOlxyXG4gICAgICAnc2NoZWR1bGVXaXRoUmVsYXRpdmUnO1xyXG4gICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKGZ1bmN0aW9uIChvYnNlcnZlcikge1xyXG4gICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoc2NoZWR1bGVyW3NjaGVkdWxlck1ldGhvZF0oZW5kVGltZSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgIH0pLCAgc291cmNlLnN1YnNjcmliZShvYnNlcnZlcikpO1xyXG4gICAgfSk7XHJcbiAgfTtcclxuXHJcbiAgLypcclxuICAgKiBQZXJmb3JtcyBhIGV4Y2x1c2l2ZSB3YWl0aW5nIGZvciB0aGUgZmlyc3QgdG8gZmluaXNoIGJlZm9yZSBzdWJzY3JpYmluZyB0byBhbm90aGVyIG9ic2VydmFibGUuXHJcbiAgICogT2JzZXJ2YWJsZXMgdGhhdCBjb21lIGluIGJldHdlZW4gc3Vic2NyaXB0aW9ucyB3aWxsIGJlIGRyb3BwZWQgb24gdGhlIGZsb29yLlxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBIGV4Y2x1c2l2ZSBvYnNlcnZhYmxlIHdpdGggb25seSB0aGUgcmVzdWx0cyB0aGF0IGhhcHBlbiB3aGVuIHN1YnNjcmliZWQuXHJcbiAgICovXHJcbiAgb2JzZXJ2YWJsZVByb3RvLmV4Y2x1c2l2ZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgIHZhciBzb3VyY2VzID0gdGhpcztcclxuICAgIHJldHVybiBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgdmFyIGhhc0N1cnJlbnQgPSBmYWxzZSxcclxuICAgICAgICBpc1N0b3BwZWQgPSBmYWxzZSxcclxuICAgICAgICBtID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCksXHJcbiAgICAgICAgZyA9IG5ldyBDb21wb3NpdGVEaXNwb3NhYmxlKCk7XHJcblxyXG4gICAgICBnLmFkZChtKTtcclxuXHJcbiAgICAgIG0uc2V0RGlzcG9zYWJsZShzb3VyY2VzLnN1YnNjcmliZShcclxuICAgICAgICBmdW5jdGlvbiAoaW5uZXJTb3VyY2UpIHtcclxuICAgICAgICAgIGlmICghaGFzQ3VycmVudCkge1xyXG4gICAgICAgICAgICBoYXNDdXJyZW50ID0gdHJ1ZTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlzUHJvbWlzZShpbm5lclNvdXJjZSkgJiYgKGlubmVyU291cmNlID0gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKGlubmVyU291cmNlKSk7XHJcblxyXG4gICAgICAgICAgICB2YXIgaW5uZXJTdWJzY3JpcHRpb24gPSBuZXcgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgZy5hZGQoaW5uZXJTdWJzY3JpcHRpb24pO1xyXG5cclxuICAgICAgICAgICAgaW5uZXJTdWJzY3JpcHRpb24uc2V0RGlzcG9zYWJsZShpbm5lclNvdXJjZS5zdWJzY3JpYmUoXHJcbiAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0LmJpbmQob2JzZXJ2ZXIpLFxyXG4gICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksXHJcbiAgICAgICAgICAgICAgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgZy5yZW1vdmUoaW5uZXJTdWJzY3JpcHRpb24pO1xyXG4gICAgICAgICAgICAgICAgaGFzQ3VycmVudCA9IGZhbHNlO1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzU3RvcHBlZCAmJiBnLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLFxyXG4gICAgICAgIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIGlzU3RvcHBlZCA9IHRydWU7XHJcbiAgICAgICAgICBpZiAoIWhhc0N1cnJlbnQgJiYgZy5sZW5ndGggPT09IDEpIHsgXHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSkpO1xyXG5cclxuICAgICAgcmV0dXJuIGc7XHJcbiAgICB9KTtcclxuICB9O1xyXG4gIC8qXHJcbiAgICogUGVyZm9ybXMgYSBleGNsdXNpdmUgbWFwIHdhaXRpbmcgZm9yIHRoZSBmaXJzdCB0byBmaW5pc2ggYmVmb3JlIHN1YnNjcmliaW5nIHRvIGFub3RoZXIgb2JzZXJ2YWJsZS5cclxuICAgKiBPYnNlcnZhYmxlcyB0aGF0IGNvbWUgaW4gYmV0d2VlbiBzdWJzY3JpcHRpb25zIHdpbGwgYmUgZHJvcHBlZCBvbiB0aGUgZmxvb3IuXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gc2VsZWN0b3IgU2VsZWN0b3IgdG8gaW52b2tlIGZvciBldmVyeSBpdGVtIGluIHRoZSBjdXJyZW50IHN1YnNjcmlwdGlvbi5cclxuICAgKiBAcGFyYW0ge0FueX0gW3RoaXNBcmddIEFuIG9wdGlvbmFsIGNvbnRleHQgdG8gaW52b2tlIHdpdGggdGhlIHNlbGVjdG9yIHBhcmFtZXRlci5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gZXhjbHVzaXZlIG9ic2VydmFibGUgd2l0aCBvbmx5IHRoZSByZXN1bHRzIHRoYXQgaGFwcGVuIHdoZW4gc3Vic2NyaWJlZC5cclxuICAgKi9cclxuICBvYnNlcnZhYmxlUHJvdG8uZXhjbHVzaXZlTWFwID0gZnVuY3Rpb24gKHNlbGVjdG9yLCB0aGlzQXJnKSB7XHJcbiAgICB2YXIgc291cmNlcyA9IHRoaXM7XHJcbiAgICByZXR1cm4gbmV3IEFub255bW91c09ic2VydmFibGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIHZhciBpbmRleCA9IDAsXHJcbiAgICAgICAgaGFzQ3VycmVudCA9IGZhbHNlLFxyXG4gICAgICAgIGlzU3RvcHBlZCA9IHRydWUsXHJcbiAgICAgICAgbSA9IG5ldyBTaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSgpLFxyXG4gICAgICAgIGcgPSBuZXcgQ29tcG9zaXRlRGlzcG9zYWJsZSgpO1xyXG5cclxuICAgICAgZy5hZGQobSk7XHJcblxyXG4gICAgICBtLnNldERpc3Bvc2FibGUoc291cmNlcy5zdWJzY3JpYmUoXHJcbiAgICAgICAgZnVuY3Rpb24gKGlubmVyU291cmNlKSB7XHJcblxyXG4gICAgICAgICAgaWYgKCFoYXNDdXJyZW50KSB7XHJcbiAgICAgICAgICAgIGhhc0N1cnJlbnQgPSB0cnVlOyAgICAgICAgICBcclxuXHJcbiAgICAgICAgICAgIGlubmVyU3Vic2NyaXB0aW9uID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCk7XHJcbiAgICAgICAgICAgIGcuYWRkKGlubmVyU3Vic2NyaXB0aW9uKTtcclxuXHJcbiAgICAgICAgICAgIGlzUHJvbWlzZShpbm5lclNvdXJjZSkgJiYgKGlubmVyU291cmNlID0gb2JzZXJ2YWJsZUZyb21Qcm9taXNlKGlubmVyU291cmNlKSk7ICAgICAgXHJcblxyXG4gICAgICAgICAgICBpbm5lclN1YnNjcmlwdGlvbi5zZXREaXNwb3NhYmxlKGlubmVyU291cmNlLnN1YnNjcmliZShcclxuICAgICAgICAgICAgICBmdW5jdGlvbiAoeCkge1xyXG4gICAgICAgICAgICAgICAgdmFyIHJlc3VsdDtcclxuICAgICAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IHNlbGVjdG9yLmNhbGwodGhpc0FyZywgeCwgaW5kZXgrKywgaW5uZXJTb3VyY2UpO1xyXG4gICAgICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xyXG4gICAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yKGUpO1xyXG4gICAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25OZXh0KHJlc3VsdCk7XHJcbiAgICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgICBvYnNlcnZlci5vbkVycm9yLmJpbmQob2JzZXJ2ZXIpLFxyXG4gICAgICAgICAgICAgIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIGcucmVtb3ZlKGlubmVyU3Vic2NyaXB0aW9uKTtcclxuICAgICAgICAgICAgICAgIGhhc0N1cnJlbnQgPSBmYWxzZTtcclxuXHJcbiAgICAgICAgICAgICAgICBpZiAoaXNTdG9wcGVkICYmIGcubGVuZ3RoID09PSAxKSB7XHJcbiAgICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfSkpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0sIFxyXG4gICAgICAgIG9ic2VydmVyLm9uRXJyb3IuYmluZChvYnNlcnZlciksXHJcbiAgICAgICAgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgaXNTdG9wcGVkID0gdHJ1ZTtcclxuICAgICAgICAgIGlmIChnLmxlbmd0aCA9PT0gMSAmJiAhaGFzQ3VycmVudCkge1xyXG4gICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH0pKTtcclxuICAgICAgcmV0dXJuIGc7XHJcbiAgICB9KTtcclxuICB9O1xyXG4gICAgLyoqIFByb3ZpZGVzIGEgc2V0IG9mIGV4dGVuc2lvbiBtZXRob2RzIGZvciB2aXJ0dWFsIHRpbWUgc2NoZWR1bGluZy4gKi9cclxuICAgIFJ4LlZpcnR1YWxUaW1lU2NoZWR1bGVyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gbm90SW1wbGVtZW50ZWQoKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignTm90IGltcGxlbWVudGVkJyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBsb2NhbE5vdygpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudG9EYXRlVGltZU9mZnNldCh0aGlzLmNsb2NrKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHNjaGVkdWxlTm93KHN0YXRlLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2NoZWR1bGVBYnNvbHV0ZVdpdGhTdGF0ZShzdGF0ZSwgdGhpcy5jbG9jaywgYWN0aW9uKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIHNjaGVkdWxlUmVsYXRpdmUoc3RhdGUsIGR1ZVRpbWUsIGFjdGlvbikge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zY2hlZHVsZVJlbGF0aXZlV2l0aFN0YXRlKHN0YXRlLCB0aGlzLnRvUmVsYXRpdmUoZHVlVGltZSksIGFjdGlvbik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBmdW5jdGlvbiBzY2hlZHVsZUFic29sdXRlKHN0YXRlLCBkdWVUaW1lLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2NoZWR1bGVSZWxhdGl2ZVdpdGhTdGF0ZShzdGF0ZSwgdGhpcy50b1JlbGF0aXZlKGR1ZVRpbWUgLSB0aGlzLm5vdygpKSwgYWN0aW9uKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGZ1bmN0aW9uIGludm9rZUFjdGlvbihzY2hlZHVsZXIsIGFjdGlvbikge1xyXG4gICAgICAgICAgICBhY3Rpb24oKTtcclxuICAgICAgICAgICAgcmV0dXJuIGRpc3Bvc2FibGVFbXB0eTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGluaGVyaXRzKFZpcnR1YWxUaW1lU2NoZWR1bGVyLCBfc3VwZXIpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDcmVhdGVzIGEgbmV3IHZpcnR1YWwgdGltZSBzY2hlZHVsZXIgd2l0aCB0aGUgc3BlY2lmaWVkIGluaXRpYWwgY2xvY2sgdmFsdWUgYW5kIGFic29sdXRlIHRpbWUgY29tcGFyZXIuXHJcbiAgICAgICAgICpcclxuICAgICAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gaW5pdGlhbENsb2NrIEluaXRpYWwgdmFsdWUgZm9yIHRoZSBjbG9jay5cclxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBjb21wYXJlciBDb21wYXJlciB0byBkZXRlcm1pbmUgY2F1c2FsaXR5IG9mIGV2ZW50cyBiYXNlZCBvbiBhYnNvbHV0ZSB0aW1lLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIFZpcnR1YWxUaW1lU2NoZWR1bGVyKGluaXRpYWxDbG9jaywgY29tcGFyZXIpIHtcclxuICAgICAgICAgICAgdGhpcy5jbG9jayA9IGluaXRpYWxDbG9jaztcclxuICAgICAgICAgICAgdGhpcy5jb21wYXJlciA9IGNvbXBhcmVyO1xyXG4gICAgICAgICAgICB0aGlzLmlzRW5hYmxlZCA9IGZhbHNlO1xyXG4gICAgICAgICAgICB0aGlzLnF1ZXVlID0gbmV3IFByaW9yaXR5UXVldWUoMTAyNCk7XHJcbiAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMsIGxvY2FsTm93LCBzY2hlZHVsZU5vdywgc2NoZWR1bGVSZWxhdGl2ZSwgc2NoZWR1bGVBYnNvbHV0ZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgVmlydHVhbFRpbWVTY2hlZHVsZXJQcm90b3R5cGUgPSBWaXJ0dWFsVGltZVNjaGVkdWxlci5wcm90b3R5cGU7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEFkZHMgYSByZWxhdGl2ZSB0aW1lIHZhbHVlIHRvIGFuIGFic29sdXRlIHRpbWUgdmFsdWUuXHJcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGFic29sdXRlIEFic29sdXRlIHZpcnR1YWwgdGltZSB2YWx1ZS5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gcmVsYXRpdmUgUmVsYXRpdmUgdmlydHVhbCB0aW1lIHZhbHVlIHRvIGFkZC5cclxuICAgICAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IFJlc3VsdGluZyBhYnNvbHV0ZSB2aXJ0dWFsIHRpbWUgc3VtIHZhbHVlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFZpcnR1YWxUaW1lU2NoZWR1bGVyUHJvdG90eXBlLmFkZCA9IG5vdEltcGxlbWVudGVkO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDb252ZXJ0cyBhbiBhYnNvbHV0ZSB0aW1lIHRvIGEgbnVtYmVyIFxyXG4gICAgICAgICAqIEBwYXJhbSB7QW55fSBUaGUgYWJzb2x1dGUgdGltZS5cclxuICAgICAgICAgKiBAcmV0dXJucyB7TnVtYmVyfSBUaGUgYWJzb2x1dGUgdGltZSBpbiBtc1xyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFZpcnR1YWxUaW1lU2NoZWR1bGVyUHJvdG90eXBlLnRvRGF0ZVRpbWVPZmZzZXQgPSBub3RJbXBsZW1lbnRlZDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ29udmVydHMgdGhlIFRpbWVTcGFuIHZhbHVlIHRvIGEgcmVsYXRpdmUgdmlydHVhbCB0aW1lIHZhbHVlLiAgICAgICBcclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gdGltZVNwYW4gVGltZVNwYW4gdmFsdWUgdG8gY29udmVydC5cclxuICAgICAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IENvcnJlc3BvbmRpbmcgcmVsYXRpdmUgdmlydHVhbCB0aW1lIHZhbHVlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFZpcnR1YWxUaW1lU2NoZWR1bGVyUHJvdG90eXBlLnRvUmVsYXRpdmUgPSBub3RJbXBsZW1lbnRlZDtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogU2NoZWR1bGVzIGEgcGVyaW9kaWMgcGllY2Ugb2Ygd29yayBieSBkeW5hbWljYWxseSBkaXNjb3ZlcmluZyB0aGUgc2NoZWR1bGVyJ3MgY2FwYWJpbGl0aWVzLiBUaGUgcGVyaW9kaWMgdGFzayB3aWxsIGJlIGVtdWxhdGVkIHVzaW5nIHJlY3Vyc2l2ZSBzY2hlZHVsaW5nLiAgICAgICBcclxuICAgICAgICAgKiBAcGFyYW0ge01peGVkfSBzdGF0ZSBJbml0aWFsIHN0YXRlIHBhc3NlZCB0byB0aGUgYWN0aW9uIHVwb24gdGhlIGZpcnN0IGl0ZXJhdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gcGVyaW9kIFBlcmlvZCBmb3IgcnVubmluZyB0aGUgd29yayBwZXJpb2RpY2FsbHkuXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBiZSBleGVjdXRlZCwgcG90ZW50aWFsbHkgdXBkYXRpbmcgdGhlIHN0YXRlLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtEaXNwb3NhYmxlfSBUaGUgZGlzcG9zYWJsZSBvYmplY3QgdXNlZCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCByZWN1cnJpbmcgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovICAgICAgXHJcbiAgICAgICAgVmlydHVhbFRpbWVTY2hlZHVsZXJQcm90b3R5cGUuc2NoZWR1bGVQZXJpb2RpY1dpdGhTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSwgcGVyaW9kLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgdmFyIHMgPSBuZXcgU2NoZWR1bGVQZXJpb2RpY1JlY3Vyc2l2ZSh0aGlzLCBzdGF0ZSwgcGVyaW9kLCBhY3Rpb24pO1xyXG4gICAgICAgICAgICByZXR1cm4gcy5zdGFydCgpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNjaGVkdWxlcyBhbiBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQgYWZ0ZXIgZHVlVGltZS5cclxuICAgICAgICAgKiBAcGFyYW0ge01peGVkfSBzdGF0ZSBTdGF0ZSBwYXNzZWQgdG8gdGhlIGFjdGlvbiB0byBiZSBleGVjdXRlZC5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gZHVlVGltZSBSZWxhdGl2ZSB0aW1lIGFmdGVyIHdoaWNoIHRvIGV4ZWN1dGUgdGhlIGFjdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhY3Rpb24gQWN0aW9uIHRvIGJlIGV4ZWN1dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtEaXNwb3NhYmxlfSBUaGUgZGlzcG9zYWJsZSBvYmplY3QgdXNlZCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCBhY3Rpb24gKGJlc3QgZWZmb3J0KS5cclxuICAgICAgICAgKi8gICAgICAgICAgICBcclxuICAgICAgICBWaXJ0dWFsVGltZVNjaGVkdWxlclByb3RvdHlwZS5zY2hlZHVsZVJlbGF0aXZlV2l0aFN0YXRlID0gZnVuY3Rpb24gKHN0YXRlLCBkdWVUaW1lLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgdmFyIHJ1bkF0ID0gdGhpcy5hZGQodGhpcy5jbG9jaywgZHVlVGltZSk7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLnNjaGVkdWxlQWJzb2x1dGVXaXRoU3RhdGUoc3RhdGUsIHJ1bkF0LCBhY3Rpb24pO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFNjaGVkdWxlcyBhbiBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQgYXQgZHVlVGltZS4gICAgICBcclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gZHVlVGltZSBSZWxhdGl2ZSB0aW1lIGFmdGVyIHdoaWNoIHRvIGV4ZWN1dGUgdGhlIGFjdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBhY3Rpb24gQWN0aW9uIHRvIGJlIGV4ZWN1dGVkLlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtEaXNwb3NhYmxlfSBUaGUgZGlzcG9zYWJsZSBvYmplY3QgdXNlZCB0byBjYW5jZWwgdGhlIHNjaGVkdWxlZCBhY3Rpb24gKGJlc3QgZWZmb3J0KS5cclxuICAgICAgICAgKi8gICAgICAgICAgXHJcbiAgICAgICAgVmlydHVhbFRpbWVTY2hlZHVsZXJQcm90b3R5cGUuc2NoZWR1bGVSZWxhdGl2ZSA9IGZ1bmN0aW9uIChkdWVUaW1lLCBhY3Rpb24pIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc2NoZWR1bGVSZWxhdGl2ZVdpdGhTdGF0ZShhY3Rpb24sIGR1ZVRpbWUsIGludm9rZUFjdGlvbik7XHJcbiAgICAgICAgfTsgICAgXHJcblxyXG4gICAgICAgIC8qKiBcclxuICAgICAgICAgKiBTdGFydHMgdGhlIHZpcnR1YWwgdGltZSBzY2hlZHVsZXIuIFxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFZpcnR1YWxUaW1lU2NoZWR1bGVyUHJvdG90eXBlLnN0YXJ0ID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgbmV4dDtcclxuICAgICAgICAgICAgaWYgKCF0aGlzLmlzRW5hYmxlZCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0VuYWJsZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgZG8ge1xyXG4gICAgICAgICAgICAgICAgICAgIG5leHQgPSB0aGlzLmdldE5leHQoKTtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobmV4dCAhPT0gbnVsbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGhpcy5jb21wYXJlcihuZXh0LmR1ZVRpbWUsIHRoaXMuY2xvY2spID4gMCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5jbG9jayA9IG5leHQuZHVlVGltZTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBuZXh0Lmludm9rZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuaXNFbmFibGVkID0gZmFsc2U7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfSB3aGlsZSAodGhpcy5pc0VuYWJsZWQpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqIFxyXG4gICAgICAgICAqIFN0b3BzIHRoZSB2aXJ0dWFsIHRpbWUgc2NoZWR1bGVyLiAgXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgVmlydHVhbFRpbWVTY2hlZHVsZXJQcm90b3R5cGUuc3RvcCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy5pc0VuYWJsZWQgPSBmYWxzZTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBBZHZhbmNlcyB0aGUgc2NoZWR1bGVyJ3MgY2xvY2sgdG8gdGhlIHNwZWNpZmllZCB0aW1lLCBydW5uaW5nIGFsbCB3b3JrIHRpbGwgdGhhdCBwb2ludC5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gdGltZSBBYnNvbHV0ZSB0aW1lIHRvIGFkdmFuY2UgdGhlIHNjaGVkdWxlcidzIGNsb2NrIHRvLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFZpcnR1YWxUaW1lU2NoZWR1bGVyUHJvdG90eXBlLmFkdmFuY2VUbyA9IGZ1bmN0aW9uICh0aW1lKSB7XHJcbiAgICAgICAgICAgIHZhciBuZXh0O1xyXG4gICAgICAgICAgICB2YXIgZHVlVG9DbG9jayA9IHRoaXMuY29tcGFyZXIodGhpcy5jbG9jaywgdGltZSk7XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbXBhcmVyKHRoaXMuY2xvY2ssIHRpbWUpID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGFyZ3VtZW50T3V0T2ZSYW5nZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGR1ZVRvQ2xvY2sgPT09IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNFbmFibGVkKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzRW5hYmxlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICBkbyB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmV4dCA9IHRoaXMuZ2V0TmV4dCgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChuZXh0ICE9PSBudWxsICYmIHRoaXMuY29tcGFyZXIobmV4dC5kdWVUaW1lLCB0aW1lKSA8PSAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbXBhcmVyKG5leHQuZHVlVGltZSwgdGhpcy5jbG9jaykgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmNsb2NrID0gbmV4dC5kdWVUaW1lO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG5leHQuaW52b2tlKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5pc0VuYWJsZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IHdoaWxlICh0aGlzLmlzRW5hYmxlZCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmNsb2NrID0gdGltZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEFkdmFuY2VzIHRoZSBzY2hlZHVsZXIncyBjbG9jayBieSB0aGUgc3BlY2lmaWVkIHJlbGF0aXZlIHRpbWUsIHJ1bm5pbmcgYWxsIHdvcmsgc2NoZWR1bGVkIGZvciB0aGF0IHRpbWVzcGFuLlxyXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aW1lIFJlbGF0aXZlIHRpbWUgdG8gYWR2YW5jZSB0aGUgc2NoZWR1bGVyJ3MgY2xvY2sgYnkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgVmlydHVhbFRpbWVTY2hlZHVsZXJQcm90b3R5cGUuYWR2YW5jZUJ5ID0gZnVuY3Rpb24gKHRpbWUpIHtcclxuICAgICAgICAgICAgdmFyIGR0ID0gdGhpcy5hZGQodGhpcy5jbG9jaywgdGltZSk7XHJcbiAgICAgICAgICAgIHZhciBkdWVUb0Nsb2NrID0gdGhpcy5jb21wYXJlcih0aGlzLmNsb2NrLCBkdCk7XHJcbiAgICAgICAgICAgIGlmIChkdWVUb0Nsb2NrID4gMCkge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGFyZ3VtZW50T3V0T2ZSYW5nZSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGR1ZVRvQ2xvY2sgPT09IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB0aGlzLmFkdmFuY2VUbyhkdCk7XHJcbiAgICAgICAgfTsgICAgICAgIFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBBZHZhbmNlcyB0aGUgc2NoZWR1bGVyJ3MgY2xvY2sgYnkgdGhlIHNwZWNpZmllZCByZWxhdGl2ZSB0aW1lLiAgICAgIFxyXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSB0aW1lIFJlbGF0aXZlIHRpbWUgdG8gYWR2YW5jZSB0aGUgc2NoZWR1bGVyJ3MgY2xvY2sgYnkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgVmlydHVhbFRpbWVTY2hlZHVsZXJQcm90b3R5cGUuc2xlZXAgPSBmdW5jdGlvbiAodGltZSkge1xyXG4gICAgICAgICAgICB2YXIgZHQgPSB0aGlzLmFkZCh0aGlzLmNsb2NrLCB0aW1lKTtcclxuXHJcbiAgICAgICAgICAgIGlmICh0aGlzLmNvbXBhcmVyKHRoaXMuY2xvY2ssIGR0KSA+PSAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYXJndW1lbnRPdXRPZlJhbmdlKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgdGhpcy5jbG9jayA9IGR0O1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEdldHMgdGhlIG5leHQgc2NoZWR1bGVkIGl0ZW0gdG8gYmUgZXhlY3V0ZWQuICAgICAgICAgIFxyXG4gICAgICAgICAqIEByZXR1cm5zIHtTY2hlZHVsZWRJdGVtfSBUaGUgbmV4dCBzY2hlZHVsZWQgaXRlbS5cclxuICAgICAgICAgKi8gICAgICAgICAgXHJcbiAgICAgICAgVmlydHVhbFRpbWVTY2hlZHVsZXJQcm90b3R5cGUuZ2V0TmV4dCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdmFyIG5leHQ7XHJcbiAgICAgICAgICAgIHdoaWxlICh0aGlzLnF1ZXVlLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIG5leHQgPSB0aGlzLnF1ZXVlLnBlZWsoKTtcclxuICAgICAgICAgICAgICAgIGlmIChuZXh0LmlzQ2FuY2VsbGVkKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnF1ZXVlLmRlcXVldWUoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG5leHQ7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIG51bGw7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogU2NoZWR1bGVzIGFuIGFjdGlvbiB0byBiZSBleGVjdXRlZCBhdCBkdWVUaW1lLiAgICAgICBcclxuICAgICAgICAgKiBAcGFyYW0ge1NjaGVkdWxlcn0gc2NoZWR1bGVyIFNjaGVkdWxlciB0byBleGVjdXRlIHRoZSBhY3Rpb24gb24uXHJcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGR1ZVRpbWUgQWJzb2x1dGUgdGltZSBhdCB3aGljaCB0byBleGVjdXRlIHRoZSBhY3Rpb24uXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBiZSBleGVjdXRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RGlzcG9zYWJsZX0gVGhlIGRpc3Bvc2FibGUgb2JqZWN0IHVzZWQgdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovICAgICAgICAgICBcclxuICAgICAgICBWaXJ0dWFsVGltZVNjaGVkdWxlclByb3RvdHlwZS5zY2hlZHVsZUFic29sdXRlID0gZnVuY3Rpb24gKGR1ZVRpbWUsIGFjdGlvbikge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zY2hlZHVsZUFic29sdXRlV2l0aFN0YXRlKGFjdGlvbiwgZHVlVGltZSwgaW52b2tlQWN0aW9uKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTY2hlZHVsZXMgYW4gYWN0aW9uIHRvIGJlIGV4ZWN1dGVkIGF0IGR1ZVRpbWUuXHJcbiAgICAgICAgICogQHBhcmFtIHtNaXhlZH0gc3RhdGUgU3RhdGUgcGFzc2VkIHRvIHRoZSBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXHJcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGR1ZVRpbWUgQWJzb2x1dGUgdGltZSBhdCB3aGljaCB0byBleGVjdXRlIHRoZSBhY3Rpb24uXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gYWN0aW9uIEFjdGlvbiB0byBiZSBleGVjdXRlZC5cclxuICAgICAgICAgKiBAcmV0dXJucyB7RGlzcG9zYWJsZX0gVGhlIGRpc3Bvc2FibGUgb2JqZWN0IHVzZWQgdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgVmlydHVhbFRpbWVTY2hlZHVsZXJQcm90b3R5cGUuc2NoZWR1bGVBYnNvbHV0ZVdpdGhTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSwgZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIHZhciBzZWxmID0gdGhpcyxcclxuICAgICAgICAgICAgICAgIHJ1biA9IGZ1bmN0aW9uIChzY2hlZHVsZXIsIHN0YXRlMSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHNlbGYucXVldWUucmVtb3ZlKHNpKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWN0aW9uKHNjaGVkdWxlciwgc3RhdGUxKTtcclxuICAgICAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgICAgICBzaSA9IG5ldyBTY2hlZHVsZWRJdGVtKHNlbGYsIHN0YXRlLCBydW4sIGR1ZVRpbWUsIHNlbGYuY29tcGFyZXIpO1xyXG4gICAgICAgICAgICBzZWxmLnF1ZXVlLmVucXVldWUoc2kpO1xyXG4gICAgICAgICAgICByZXR1cm4gc2kuZGlzcG9zYWJsZTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gVmlydHVhbFRpbWVTY2hlZHVsZXI7XHJcbiAgICB9KFNjaGVkdWxlcikpO1xyXG5cclxuICAgIC8qKiBQcm92aWRlcyBhIHZpcnR1YWwgdGltZSBzY2hlZHVsZXIgdGhhdCB1c2VzIERhdGUgZm9yIGFic29sdXRlIHRpbWUgYW5kIG51bWJlciBmb3IgcmVsYXRpdmUgdGltZS4gKi9cclxuICAgIFJ4Lkhpc3RvcmljYWxTY2hlZHVsZXIgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgIGluaGVyaXRzKEhpc3RvcmljYWxTY2hlZHVsZXIsIF9zdXBlcik7XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENyZWF0ZXMgYSBuZXcgaGlzdG9yaWNhbCBzY2hlZHVsZXIgd2l0aCB0aGUgc3BlY2lmaWVkIGluaXRpYWwgY2xvY2sgdmFsdWUuXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgICAgICogQHBhcmFtIHtOdW1iZXJ9IGluaXRpYWxDbG9jayBJbml0aWFsIHZhbHVlIGZvciB0aGUgY2xvY2suXHJcbiAgICAgICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyZXIgQ29tcGFyZXIgdG8gZGV0ZXJtaW5lIGNhdXNhbGl0eSBvZiBldmVudHMgYmFzZWQgb24gYWJzb2x1dGUgdGltZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbiBIaXN0b3JpY2FsU2NoZWR1bGVyKGluaXRpYWxDbG9jaywgY29tcGFyZXIpIHtcclxuICAgICAgICAgICAgdmFyIGNsb2NrID0gaW5pdGlhbENsb2NrID09IG51bGwgPyAwIDogaW5pdGlhbENsb2NrO1xyXG4gICAgICAgICAgICB2YXIgY21wID0gY29tcGFyZXIgfHwgZGVmYXVsdFN1YkNvbXBhcmVyO1xyXG4gICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBjbG9jaywgY21wKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHZhciBIaXN0b3JpY2FsU2NoZWR1bGVyUHJvdG8gPSBIaXN0b3JpY2FsU2NoZWR1bGVyLnByb3RvdHlwZTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQWRkcyBhIHJlbGF0aXZlIHRpbWUgdmFsdWUgdG8gYW4gYWJzb2x1dGUgdGltZSB2YWx1ZS5cclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gYWJzb2x1dGUgQWJzb2x1dGUgdmlydHVhbCB0aW1lIHZhbHVlLlxyXG4gICAgICAgICAqIEBwYXJhbSB7TnVtYmVyfSByZWxhdGl2ZSBSZWxhdGl2ZSB2aXJ0dWFsIHRpbWUgdmFsdWUgdG8gYWRkLlxyXG4gICAgICAgICAqIEByZXR1cm4ge051bWJlcn0gUmVzdWx0aW5nIGFic29sdXRlIHZpcnR1YWwgdGltZSBzdW0gdmFsdWUuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgSGlzdG9yaWNhbFNjaGVkdWxlclByb3RvLmFkZCA9IGZ1bmN0aW9uIChhYnNvbHV0ZSwgcmVsYXRpdmUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFic29sdXRlICsgcmVsYXRpdmU7XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBIaXN0b3JpY2FsU2NoZWR1bGVyUHJvdG8udG9EYXRlVGltZU9mZnNldCA9IGZ1bmN0aW9uIChhYnNvbHV0ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IERhdGUoYWJzb2x1dGUpLmdldFRpbWUoKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDb252ZXJ0cyB0aGUgVGltZVNwYW4gdmFsdWUgdG8gYSByZWxhdGl2ZSB2aXJ0dWFsIHRpbWUgdmFsdWUuXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQG1lbWJlck9mIEhpc3RvcmljYWxTY2hlZHVsZXIgICAgICAgICBcclxuICAgICAgICAgKiBAcGFyYW0ge051bWJlcn0gdGltZVNwYW4gVGltZVNwYW4gdmFsdWUgdG8gY29udmVydC5cclxuICAgICAgICAgKiBAcmV0dXJuIHtOdW1iZXJ9IENvcnJlc3BvbmRpbmcgcmVsYXRpdmUgdmlydHVhbCB0aW1lIHZhbHVlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIEhpc3RvcmljYWxTY2hlZHVsZXJQcm90by50b1JlbGF0aXZlID0gZnVuY3Rpb24gKHRpbWVTcGFuKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aW1lU3BhbjtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gSGlzdG9yaWNhbFNjaGVkdWxlcjsgICAgXHJcbiAgICB9KFJ4LlZpcnR1YWxUaW1lU2NoZWR1bGVyKSk7XHJcbiAgdmFyIEFub255bW91c09ic2VydmFibGUgPSBSeC5Bbm9ueW1vdXNPYnNlcnZhYmxlID0gKGZ1bmN0aW9uIChfX3N1cGVyX18pIHtcclxuICAgIGluaGVyaXRzKEFub255bW91c09ic2VydmFibGUsIF9fc3VwZXJfXyk7XHJcblxyXG4gICAgLy8gRml4IHN1YnNjcmliZXIgdG8gY2hlY2sgZm9yIHVuZGVmaW5lZCBvciBmdW5jdGlvbiByZXR1cm5lZCB0byBkZWNvcmF0ZSBhcyBEaXNwb3NhYmxlXHJcbiAgICBmdW5jdGlvbiBmaXhTdWJzY3JpYmVyKHN1YnNjcmliZXIpIHtcclxuICAgICAgaWYgKHR5cGVvZiBzdWJzY3JpYmVyID09PSAndW5kZWZpbmVkJykge1xyXG4gICAgICAgIHN1YnNjcmliZXIgPSBkaXNwb3NhYmxlRW1wdHk7XHJcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHN1YnNjcmliZXIgPT09ICdmdW5jdGlvbicpIHtcclxuICAgICAgICBzdWJzY3JpYmVyID0gZGlzcG9zYWJsZUNyZWF0ZShzdWJzY3JpYmVyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgcmV0dXJuIHN1YnNjcmliZXI7XHJcbiAgICB9XHJcblxyXG4gICAgZnVuY3Rpb24gQW5vbnltb3VzT2JzZXJ2YWJsZShzdWJzY3JpYmUpIHtcclxuICAgICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEFub255bW91c09ic2VydmFibGUpKSB7XHJcbiAgICAgICAgcmV0dXJuIG5ldyBBbm9ueW1vdXNPYnNlcnZhYmxlKHN1YnNjcmliZSk7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGZ1bmN0aW9uIHMob2JzZXJ2ZXIpIHtcclxuICAgICAgICB2YXIgc2V0RGlzcG9zYWJsZSA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGF1dG9EZXRhY2hPYnNlcnZlci5zZXREaXNwb3NhYmxlKGZpeFN1YnNjcmliZXIoc3Vic2NyaWJlKGF1dG9EZXRhY2hPYnNlcnZlcikpKTtcclxuICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcclxuICAgICAgICAgICAgaWYgKCFhdXRvRGV0YWNoT2JzZXJ2ZXIuZmFpbChlKSkge1xyXG4gICAgICAgICAgICAgIHRocm93IGU7XHJcbiAgICAgICAgICAgIH0gXHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgdmFyIGF1dG9EZXRhY2hPYnNlcnZlciA9IG5ldyBBdXRvRGV0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpO1xyXG4gICAgICAgIGlmIChjdXJyZW50VGhyZWFkU2NoZWR1bGVyLnNjaGVkdWxlUmVxdWlyZWQoKSkge1xyXG4gICAgICAgICAgY3VycmVudFRocmVhZFNjaGVkdWxlci5zY2hlZHVsZShzZXREaXNwb3NhYmxlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgc2V0RGlzcG9zYWJsZSgpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGF1dG9EZXRhY2hPYnNlcnZlcjtcclxuICAgICAgfVxyXG5cclxuICAgICAgX19zdXBlcl9fLmNhbGwodGhpcywgcyk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIEFub255bW91c09ic2VydmFibGU7XHJcblxyXG4gIH0oT2JzZXJ2YWJsZSkpO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqL1xyXG4gICAgdmFyIEF1dG9EZXRhY2hPYnNlcnZlciA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICAgICAgaW5oZXJpdHMoQXV0b0RldGFjaE9ic2VydmVyLCBfc3VwZXIpO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBBdXRvRGV0YWNoT2JzZXJ2ZXIob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgX3N1cGVyLmNhbGwodGhpcyk7XHJcbiAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXIgPSBvYnNlcnZlcjtcclxuICAgICAgICAgICAgdGhpcy5tID0gbmV3IFNpbmdsZUFzc2lnbm1lbnREaXNwb3NhYmxlKCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB2YXIgQXV0b0RldGFjaE9ic2VydmVyUHJvdG90eXBlID0gQXV0b0RldGFjaE9ic2VydmVyLnByb3RvdHlwZTtcclxuXHJcbiAgICAgICAgQXV0b0RldGFjaE9ic2VydmVyUHJvdG90eXBlLm5leHQgPSBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdmFyIG5vRXJyb3IgPSBmYWxzZTtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXIub25OZXh0KHZhbHVlKTtcclxuICAgICAgICAgICAgICAgIG5vRXJyb3IgPSB0cnVlO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7IFxyXG4gICAgICAgICAgICAgICAgdGhyb3cgZTsgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIH0gZmluYWxseSB7XHJcbiAgICAgICAgICAgICAgICBpZiAoIW5vRXJyb3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIEF1dG9EZXRhY2hPYnNlcnZlclByb3RvdHlwZS5lcnJvciA9IGZ1bmN0aW9uIChleG4pIHtcclxuICAgICAgICAgICAgdHJ5IHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXIub25FcnJvcihleG4pO1xyXG4gICAgICAgICAgICB9IGNhdGNoIChlKSB7IFxyXG4gICAgICAgICAgICAgICAgdGhyb3cgZTsgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIH0gZmluYWxseSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmRpc3Bvc2UoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIEF1dG9EZXRhY2hPYnNlcnZlclByb3RvdHlwZS5jb21wbGV0ZWQgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHsgXHJcbiAgICAgICAgICAgICAgICB0aHJvdyBlOyAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgfSBmaW5hbGx5IHtcclxuICAgICAgICAgICAgICAgIHRoaXMuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfTtcclxuXHJcbiAgICAgICAgQXV0b0RldGFjaE9ic2VydmVyUHJvdG90eXBlLnNldERpc3Bvc2FibGUgPSBmdW5jdGlvbiAodmFsdWUpIHsgdGhpcy5tLnNldERpc3Bvc2FibGUodmFsdWUpOyB9O1xyXG4gICAgICAgIEF1dG9EZXRhY2hPYnNlcnZlclByb3RvdHlwZS5nZXREaXNwb3NhYmxlID0gZnVuY3Rpb24gKHZhbHVlKSB7IHJldHVybiB0aGlzLm0uZ2V0RGlzcG9zYWJsZSgpOyB9O1xyXG4gICAgICAgIC8qIEBwcml2YXRlICovXHJcbiAgICAgICAgQXV0b0RldGFjaE9ic2VydmVyUHJvdG90eXBlLmRpc3Bvc2FibGUgPSBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0aGlzLmdldERpc3Bvc2FibGUoKSA6IHNldERpc3Bvc2FibGUodmFsdWUpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIEF1dG9EZXRhY2hPYnNlcnZlclByb3RvdHlwZS5kaXNwb3NlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICBfc3VwZXIucHJvdG90eXBlLmRpc3Bvc2UuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgdGhpcy5tLmRpc3Bvc2UoKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gQXV0b0RldGFjaE9ic2VydmVyO1xyXG4gICAgfShBYnN0cmFjdE9ic2VydmVyKSk7XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICB2YXIgR3JvdXBlZE9ic2VydmFibGUgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG4gICAgICAgIGluaGVyaXRzKEdyb3VwZWRPYnNlcnZhYmxlLCBfc3VwZXIpO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBzdWJzY3JpYmUob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudW5kZXJseWluZ09ic2VydmFibGUuc3Vic2NyaWJlKG9ic2VydmVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKiBcclxuICAgICAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIEdyb3VwZWRPYnNlcnZhYmxlKGtleSwgdW5kZXJseWluZ09ic2VydmFibGUsIG1lcmdlZERpc3Bvc2FibGUpIHtcclxuICAgICAgICAgICAgX3N1cGVyLmNhbGwodGhpcywgc3Vic2NyaWJlKTtcclxuICAgICAgICAgICAgdGhpcy5rZXkgPSBrZXk7XHJcbiAgICAgICAgICAgIHRoaXMudW5kZXJseWluZ09ic2VydmFibGUgPSAhbWVyZ2VkRGlzcG9zYWJsZSA/XHJcbiAgICAgICAgICAgICAgICB1bmRlcmx5aW5nT2JzZXJ2YWJsZSA6XHJcbiAgICAgICAgICAgICAgICBuZXcgQW5vbnltb3VzT2JzZXJ2YWJsZShmdW5jdGlvbiAob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUobWVyZ2VkRGlzcG9zYWJsZS5nZXREaXNwb3NhYmxlKCksIHVuZGVybHlpbmdPYnNlcnZhYmxlLnN1YnNjcmliZShvYnNlcnZlcikpO1xyXG4gICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gR3JvdXBlZE9ic2VydmFibGU7XHJcbiAgICB9KE9ic2VydmFibGUpKTtcclxuXHJcbiAgICAvKipcclxuICAgICAqICBSZXByZXNlbnRzIGFuIG9iamVjdCB0aGF0IGlzIGJvdGggYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSBhcyB3ZWxsIGFzIGFuIG9ic2VydmVyLlxyXG4gICAgICogIEVhY2ggbm90aWZpY2F0aW9uIGlzIGJyb2FkY2FzdGVkIHRvIGFsbCBzdWJzY3JpYmVkIG9ic2VydmVycy5cclxuICAgICAqL1xyXG4gICAgdmFyIFN1YmplY3QgPSBSeC5TdWJqZWN0ID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgICAgICBmdW5jdGlvbiBzdWJzY3JpYmUob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgY2hlY2tEaXNwb3NlZC5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuaXNTdG9wcGVkKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVycy5wdXNoKG9ic2VydmVyKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBuZXcgSW5uZXJTdWJzY3JpcHRpb24odGhpcywgb2JzZXJ2ZXIpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGlmICh0aGlzLmV4Y2VwdGlvbikge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25FcnJvcih0aGlzLmV4Y2VwdGlvbik7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZGlzcG9zYWJsZUVtcHR5O1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIG9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIHJldHVybiBkaXNwb3NhYmxlRW1wdHk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpbmhlcml0cyhTdWJqZWN0LCBfc3VwZXIpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDcmVhdGVzIGEgc3ViamVjdC5cclxuICAgICAgICAgKiBAY29uc3RydWN0b3JcclxuICAgICAgICAgKi8gICAgICBcclxuICAgICAgICBmdW5jdGlvbiBTdWJqZWN0KCkge1xyXG4gICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBzdWJzY3JpYmUpO1xyXG4gICAgICAgICAgICB0aGlzLmlzRGlzcG9zZWQgPSBmYWxzZSxcclxuICAgICAgICAgICAgdGhpcy5pc1N0b3BwZWQgPSBmYWxzZSxcclxuICAgICAgICAgICAgdGhpcy5vYnNlcnZlcnMgPSBbXTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGFkZFByb3BlcnRpZXMoU3ViamVjdC5wcm90b3R5cGUsIE9ic2VydmVyLCB7XHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3ViamVjdCBoYXMgb2JzZXJ2ZXJzIHN1YnNjcmliZWQgdG8gaXQuXHJcbiAgICAgICAgICAgICAqIEByZXR1cm5zIHtCb29sZWFufSBJbmRpY2F0ZXMgd2hldGhlciB0aGUgc3ViamVjdCBoYXMgb2JzZXJ2ZXJzIHN1YnNjcmliZWQgdG8gaXQuXHJcbiAgICAgICAgICAgICAqLyAgICAgICAgIFxyXG4gICAgICAgICAgICBoYXNPYnNlcnZlcnM6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLm9ic2VydmVycy5sZW5ndGggPiAwO1xyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTm90aWZpZXMgYWxsIHN1YnNjcmliZWQgb2JzZXJ2ZXJzIGFib3V0IHRoZSBlbmQgb2YgdGhlIHNlcXVlbmNlLlxyXG4gICAgICAgICAgICAgKi8gICAgICAgICAgICAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBvbkNvbXBsZXRlZDogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgY2hlY2tEaXNwb3NlZC5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzU3RvcHBlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHZhciBvcyA9IHRoaXMub2JzZXJ2ZXJzLnNsaWNlKDApO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNTdG9wcGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBmb3IgKHZhciBpID0gMCwgbGVuID0gb3MubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgb3NbaV0ub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXJzID0gW107XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBOb3RpZmllcyBhbGwgc3Vic2NyaWJlZCBvYnNlcnZlcnMgYWJvdXQgdGhlIGV4Y2VwdGlvbi5cclxuICAgICAgICAgICAgICogQHBhcmFtIHtNaXhlZH0gZXJyb3IgVGhlIGV4Y2VwdGlvbiB0byBzZW5kIHRvIGFsbCBvYnNlcnZlcnMuXHJcbiAgICAgICAgICAgICAqLyAgICAgICAgICAgICAgIFxyXG4gICAgICAgICAgICBvbkVycm9yOiBmdW5jdGlvbiAoZXhjZXB0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICBjaGVja0Rpc3Bvc2VkLmNhbGwodGhpcyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNTdG9wcGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9zID0gdGhpcy5vYnNlcnZlcnMuc2xpY2UoMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5pc1N0b3BwZWQgPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZXhjZXB0aW9uID0gZXhjZXB0aW9uO1xyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvc1tpXS5vbkVycm9yKGV4Y2VwdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVycyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTm90aWZpZXMgYWxsIHN1YnNjcmliZWQgb2JzZXJ2ZXJzIGFib3V0IHRoZSBhcnJpdmFsIG9mIHRoZSBzcGVjaWZpZWQgZWxlbWVudCBpbiB0aGUgc2VxdWVuY2UuXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlIFRoZSB2YWx1ZSB0byBzZW5kIHRvIGFsbCBvYnNlcnZlcnMuXHJcbiAgICAgICAgICAgICAqLyAgICAgICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIG9uTmV4dDogZnVuY3Rpb24gKHZhbHVlKSB7XHJcbiAgICAgICAgICAgICAgICBjaGVja0Rpc3Bvc2VkLmNhbGwodGhpcyk7XHJcbiAgICAgICAgICAgICAgICBpZiAoIXRoaXMuaXNTdG9wcGVkKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9zID0gdGhpcy5vYnNlcnZlcnMuc2xpY2UoMCk7XHJcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IG9zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIG9zW2ldLm9uTmV4dCh2YWx1ZSk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogVW5zdWJzY3JpYmUgYWxsIG9ic2VydmVycyBhbmQgcmVsZWFzZSByZXNvdXJjZXMuXHJcbiAgICAgICAgICAgICAqLyAgICAgICAgICAgICAgICBcclxuICAgICAgICAgICAgZGlzcG9zZTogZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc0Rpc3Bvc2VkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXJzID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDcmVhdGVzIGEgc3ViamVjdCBmcm9tIHRoZSBzcGVjaWZpZWQgb2JzZXJ2ZXIgYW5kIG9ic2VydmFibGUuXHJcbiAgICAgICAgICogQHBhcmFtIHtPYnNlcnZlcn0gb2JzZXJ2ZXIgVGhlIG9ic2VydmVyIHVzZWQgdG8gc2VuZCBtZXNzYWdlcyB0byB0aGUgc3ViamVjdC5cclxuICAgICAgICAgKiBAcGFyYW0ge09ic2VydmFibGV9IG9ic2VydmFibGUgVGhlIG9ic2VydmFibGUgdXNlZCB0byBzdWJzY3JpYmUgdG8gbWVzc2FnZXMgc2VudCBmcm9tIHRoZSBzdWJqZWN0LlxyXG4gICAgICAgICAqIEByZXR1cm5zIHtTdWJqZWN0fSBTdWJqZWN0IGltcGxlbWVudGVkIHVzaW5nIHRoZSBnaXZlbiBvYnNlcnZlciBhbmQgb2JzZXJ2YWJsZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBTdWJqZWN0LmNyZWF0ZSA9IGZ1bmN0aW9uIChvYnNlcnZlciwgb2JzZXJ2YWJsZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEFub255bW91c1N1YmplY3Qob2JzZXJ2ZXIsIG9ic2VydmFibGUpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIHJldHVybiBTdWJqZWN0O1xyXG4gICAgfShPYnNlcnZhYmxlKSk7XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiAgUmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIGFuIGFzeW5jaHJvbm91cyBvcGVyYXRpb24uXHJcbiAgICAgKiAgVGhlIGxhc3QgdmFsdWUgYmVmb3JlIHRoZSBPbkNvbXBsZXRlZCBub3RpZmljYXRpb24sIG9yIHRoZSBlcnJvciByZWNlaXZlZCB0aHJvdWdoIE9uRXJyb3IsIGlzIHNlbnQgdG8gYWxsIHN1YnNjcmliZWQgb2JzZXJ2ZXJzLlxyXG4gICAgICovICAgXHJcbiAgICB2YXIgQXN5bmNTdWJqZWN0ID0gUnguQXN5bmNTdWJqZWN0ID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gc3Vic2NyaWJlKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIGNoZWNrRGlzcG9zZWQuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGlmICghdGhpcy5pc1N0b3BwZWQpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXJzLnB1c2gob2JzZXJ2ZXIpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBJbm5lclN1YnNjcmlwdGlvbih0aGlzLCBvYnNlcnZlcik7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHZhciBleCA9IHRoaXMuZXhjZXB0aW9uLFxyXG4gICAgICAgICAgICAgICAgaHYgPSB0aGlzLmhhc1ZhbHVlLFxyXG4gICAgICAgICAgICAgICAgdiA9IHRoaXMudmFsdWU7XHJcblxyXG4gICAgICAgICAgICBpZiAoZXgpIHtcclxuICAgICAgICAgICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXgpO1xyXG4gICAgICAgICAgICB9IGVsc2UgaWYgKGh2KSB7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbk5leHQodik7XHJcbiAgICAgICAgICAgICAgICBvYnNlcnZlci5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgcmV0dXJuIGRpc3Bvc2FibGVFbXB0eTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGluaGVyaXRzKEFzeW5jU3ViamVjdCwgX3N1cGVyKTtcclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ3JlYXRlcyBhIHN1YmplY3QgdGhhdCBjYW4gb25seSByZWNlaXZlIG9uZSB2YWx1ZSBhbmQgdGhhdCB2YWx1ZSBpcyBjYWNoZWQgZm9yIGFsbCBmdXR1cmUgb2JzZXJ2YXRpb25zLlxyXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAqLyBcclxuICAgICAgICBmdW5jdGlvbiBBc3luY1N1YmplY3QoKSB7XHJcbiAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMsIHN1YnNjcmliZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmlzRGlzcG9zZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5pc1N0b3BwZWQgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy52YWx1ZSA9IG51bGw7XHJcbiAgICAgICAgICAgIHRoaXMuaGFzVmFsdWUgPSBmYWxzZTtcclxuICAgICAgICAgICAgdGhpcy5vYnNlcnZlcnMgPSBbXTtcclxuICAgICAgICAgICAgdGhpcy5leGNlcHRpb24gPSBudWxsO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgYWRkUHJvcGVydGllcyhBc3luY1N1YmplY3QucHJvdG90eXBlLCBPYnNlcnZlciwge1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHN1YmplY3QgaGFzIG9ic2VydmVycyBzdWJzY3JpYmVkIHRvIGl0LlxyXG4gICAgICAgICAgICAgKiBAcmV0dXJucyB7Qm9vbGVhbn0gSW5kaWNhdGVzIHdoZXRoZXIgdGhlIHN1YmplY3QgaGFzIG9ic2VydmVycyBzdWJzY3JpYmVkIHRvIGl0LlxyXG4gICAgICAgICAgICAgKi8gICAgICAgICBcclxuICAgICAgICAgICAgaGFzT2JzZXJ2ZXJzOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBjaGVja0Rpc3Bvc2VkLmNhbGwodGhpcyk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gdGhpcy5vYnNlcnZlcnMubGVuZ3RoID4gMDtcclxuICAgICAgICAgICAgfSxcclxuICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAqIE5vdGlmaWVzIGFsbCBzdWJzY3JpYmVkIG9ic2VydmVycyBhYm91dCB0aGUgZW5kIG9mIHRoZSBzZXF1ZW5jZSwgYWxzbyBjYXVzaW5nIHRoZSBsYXN0IHJlY2VpdmVkIHZhbHVlIHRvIGJlIHNlbnQgb3V0IChpZiBhbnkpLlxyXG4gICAgICAgICAgICAgKi8gXHJcbiAgICAgICAgICAgIG9uQ29tcGxldGVkOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB2YXIgbywgaSwgbGVuO1xyXG4gICAgICAgICAgICAgICAgY2hlY2tEaXNwb3NlZC5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLmlzU3RvcHBlZCkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaXNTdG9wcGVkID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb3MgPSB0aGlzLm9ic2VydmVycy5zbGljZSgwKSxcclxuICAgICAgICAgICAgICAgICAgICAgICAgdiA9IHRoaXMudmFsdWUsXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGh2ID0gdGhpcy5oYXNWYWx1ZTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKGh2KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IG9zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvID0gb3NbaV07XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvLm9uTmV4dCh2KTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG8ub25Db21wbGV0ZWQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoaSA9IDAsIGxlbiA9IG9zLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvc1tpXS5vbkNvbXBsZXRlZCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVycyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogTm90aWZpZXMgYWxsIHN1YnNjcmliZWQgb2JzZXJ2ZXJzIGFib3V0IHRoZSBleGNlcHRpb24uXHJcbiAgICAgICAgICAgICAqIEBwYXJhbSB7TWl4ZWR9IGVycm9yIFRoZSBleGNlcHRpb24gdG8gc2VuZCB0byBhbGwgb2JzZXJ2ZXJzLlxyXG4gICAgICAgICAgICAgKi8gXHJcbiAgICAgICAgICAgIG9uRXJyb3I6IGZ1bmN0aW9uIChleGNlcHRpb24pIHtcclxuICAgICAgICAgICAgICAgIGNoZWNrRGlzcG9zZWQuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc1N0b3BwZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB2YXIgb3MgPSB0aGlzLm9ic2VydmVycy5zbGljZSgwKTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmlzU3RvcHBlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5leGNlcHRpb24gPSBleGNlcHRpb247XHJcblxyXG4gICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSBvcy5sZW5ndGg7IGkgPCBsZW47IGkrKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBvc1tpXS5vbkVycm9yKGV4Y2VwdGlvbik7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVycyA9IFtdO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9LFxyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogU2VuZHMgYSB2YWx1ZSB0byB0aGUgc3ViamVjdC4gVGhlIGxhc3QgdmFsdWUgcmVjZWl2ZWQgYmVmb3JlIHN1Y2Nlc3NmdWwgdGVybWluYXRpb24gd2lsbCBiZSBzZW50IHRvIGFsbCBzdWJzY3JpYmVkIGFuZCBmdXR1cmUgb2JzZXJ2ZXJzLlxyXG4gICAgICAgICAgICAgKiBAcGFyYW0ge01peGVkfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc3RvcmUgaW4gdGhlIHN1YmplY3QuXHJcbiAgICAgICAgICAgICAqLyAgICAgICAgICAgICBcclxuICAgICAgICAgICAgb25OZXh0OiBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIGNoZWNrRGlzcG9zZWQuY2FsbCh0aGlzKTtcclxuICAgICAgICAgICAgICAgIGlmICghdGhpcy5pc1N0b3BwZWQpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gdmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5oYXNWYWx1ZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBVbnN1YnNjcmliZSBhbGwgb2JzZXJ2ZXJzIGFuZCByZWxlYXNlIHJlc291cmNlcy5cclxuICAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIGRpc3Bvc2U6IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuaXNEaXNwb3NlZCA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVycyA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmV4Y2VwdGlvbiA9IG51bGw7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnZhbHVlID0gbnVsbDtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gQXN5bmNTdWJqZWN0O1xyXG4gICAgfShPYnNlcnZhYmxlKSk7XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICB2YXIgQW5vbnltb3VzU3ViamVjdCA9IChmdW5jdGlvbiAoX3N1cGVyKSB7XHJcbiAgICAgICAgaW5oZXJpdHMoQW5vbnltb3VzU3ViamVjdCwgX3N1cGVyKTtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gc3Vic2NyaWJlKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aGlzLm9ic2VydmFibGUuc3Vic2NyaWJlKG9ic2VydmVyKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEBwcml2YXRlXHJcbiAgICAgICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgZnVuY3Rpb24gQW5vbnltb3VzU3ViamVjdChvYnNlcnZlciwgb2JzZXJ2YWJsZSkge1xyXG4gICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBzdWJzY3JpYmUpO1xyXG4gICAgICAgICAgICB0aGlzLm9ic2VydmVyID0gb2JzZXJ2ZXI7XHJcbiAgICAgICAgICAgIHRoaXMub2JzZXJ2YWJsZSA9IG9ic2VydmFibGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBhZGRQcm9wZXJ0aWVzKEFub255bW91c1N1YmplY3QucHJvdG90eXBlLCBPYnNlcnZlciwge1xyXG4gICAgICAgICAgICAvKipcclxuICAgICAgICAgICAgICogQHByaXZhdGVcclxuICAgICAgICAgICAgICogQG1lbWJlck9mIEFub255bW91c1N1YmplY3QjXHJcbiAgICAgICAgICAgICovXHJcbiAgICAgICAgICAgIG9uQ29tcGxldGVkOiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLm9ic2VydmVyLm9uQ29tcGxldGVkKCk7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAgICAgKiBAbWVtYmVyT2YgQW5vbnltb3VzU3ViamVjdCNcclxuICAgICAgICAgICAgKi8gICAgICAgICAgICBcclxuICAgICAgICAgICAgb25FcnJvcjogZnVuY3Rpb24gKGV4Y2VwdGlvbikge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5vYnNlcnZlci5vbkVycm9yKGV4Y2VwdGlvbik7XHJcbiAgICAgICAgICAgIH0sXHJcbiAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAgICAgKiBAbWVtYmVyT2YgQW5vbnltb3VzU3ViamVjdCNcclxuICAgICAgICAgICAgKi8gICAgICAgICAgICBcclxuICAgICAgICAgICAgb25OZXh0OiBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXIub25OZXh0KHZhbHVlKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICByZXR1cm4gQW5vbnltb3VzU3ViamVjdDtcclxuICAgIH0oT2JzZXJ2YWJsZSkpO1xyXG5cclxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09ICdmdW5jdGlvbicgJiYgdHlwZW9mIGRlZmluZS5hbWQgPT0gJ29iamVjdCcgJiYgZGVmaW5lLmFtZCkge1xyXG4gICAgICAgIHJvb3QuUnggPSBSeDtcclxuXHJcbiAgICAgICAgZGVmaW5lKGZ1bmN0aW9uKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gUng7XHJcbiAgICAgICAgfSk7XHJcbiAgICB9IGVsc2UgaWYgKGZyZWVFeHBvcnRzICYmIGZyZWVNb2R1bGUpIHtcclxuICAgICAgICAvLyBpbiBOb2RlLmpzIG9yIFJpbmdvSlNcclxuICAgICAgICBpZiAobW9kdWxlRXhwb3J0cykge1xyXG4gICAgICAgICAgICAoZnJlZU1vZHVsZS5leHBvcnRzID0gUngpLlJ4ID0gUng7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgIGZyZWVFeHBvcnRzLlJ4ID0gUng7XHJcbiAgICAgICAgfVxyXG4gICAgfSBlbHNlIHtcclxuICAgICAgICAvLyBpbiBhIGJyb3dzZXIgb3IgUmhpbm9cclxuICAgICAgICByb290LlJ4ID0gUng7XHJcbiAgICB9XHJcbn0uY2FsbCh0aGlzKSk7XG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeC9kaXN0L3J4LmFsbC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeC9kaXN0XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IChjKSBNaWNyb3NvZnQgT3BlbiBUZWNobm9sb2dpZXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcblxyXG47KGZ1bmN0aW9uIChmYWN0b3J5KSB7XHJcbiAgICB2YXIgb2JqZWN0VHlwZXMgPSB7XHJcbiAgICAgICAgJ2Jvb2xlYW4nOiBmYWxzZSxcclxuICAgICAgICAnZnVuY3Rpb24nOiB0cnVlLFxyXG4gICAgICAgICdvYmplY3QnOiB0cnVlLFxyXG4gICAgICAgICdudW1iZXInOiBmYWxzZSxcclxuICAgICAgICAnc3RyaW5nJzogZmFsc2UsXHJcbiAgICAgICAgJ3VuZGVmaW5lZCc6IGZhbHNlXHJcbiAgICB9O1xyXG5cclxuICAgIHZhciByb290ID0gKG9iamVjdFR5cGVzW3R5cGVvZiB3aW5kb3ddICYmIHdpbmRvdykgfHwgdGhpcyxcclxuICAgICAgICBmcmVlRXhwb3J0cyA9IG9iamVjdFR5cGVzW3R5cGVvZiBleHBvcnRzXSAmJiBleHBvcnRzICYmICFleHBvcnRzLm5vZGVUeXBlICYmIGV4cG9ydHMsXHJcbiAgICAgICAgZnJlZU1vZHVsZSA9IG9iamVjdFR5cGVzW3R5cGVvZiBtb2R1bGVdICYmIG1vZHVsZSAmJiAhbW9kdWxlLm5vZGVUeXBlICYmIG1vZHVsZSxcclxuICAgICAgICBtb2R1bGVFeHBvcnRzID0gZnJlZU1vZHVsZSAmJiBmcmVlTW9kdWxlLmV4cG9ydHMgPT09IGZyZWVFeHBvcnRzICYmIGZyZWVFeHBvcnRzLFxyXG4gICAgICAgIGZyZWVHbG9iYWwgPSBvYmplY3RUeXBlc1t0eXBlb2YgZ2xvYmFsXSAmJiBnbG9iYWw7XHJcbiAgICBcclxuICAgIGlmIChmcmVlR2xvYmFsICYmIChmcmVlR2xvYmFsLmdsb2JhbCA9PT0gZnJlZUdsb2JhbCB8fCBmcmVlR2xvYmFsLndpbmRvdyA9PT0gZnJlZUdsb2JhbCkpIHtcclxuICAgICAgICByb290ID0gZnJlZUdsb2JhbDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBCZWNhdXNlIG9mIGJ1aWxkIG9wdGltaXplcnNcclxuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcclxuICAgICAgICBkZWZpbmUoWydyeC52aXJ0dWFsdGltZScsICdleHBvcnRzJ10sIGZ1bmN0aW9uIChSeCwgZXhwb3J0cykge1xyXG4gICAgICAgICAgICByb290LlJ4ID0gZmFjdG9yeShyb290LCBleHBvcnRzLCBSeCk7XHJcbiAgICAgICAgICAgIHJldHVybiByb290LlJ4O1xyXG4gICAgICAgIH0pO1xyXG4gICAgfSBlbHNlIGlmICh0eXBlb2YgbW9kdWxlID09PSAnb2JqZWN0JyAmJiBtb2R1bGUgJiYgbW9kdWxlLmV4cG9ydHMgPT09IGZyZWVFeHBvcnRzKSB7XHJcbiAgICAgICAgbW9kdWxlLmV4cG9ydHMgPSBmYWN0b3J5KHJvb3QsIG1vZHVsZS5leHBvcnRzLCByZXF1aXJlKCcuL3J4LmFsbCcpKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcm9vdC5SeCA9IGZhY3Rvcnkocm9vdCwge30sIHJvb3QuUngpO1xyXG4gICAgfVxyXG59LmNhbGwodGhpcywgZnVuY3Rpb24gKHJvb3QsIGV4cCwgUngsIHVuZGVmaW5lZCkge1xyXG4gICAgXHJcbiAgICAvLyBEZWZhdWx0c1xyXG4gICAgdmFyIE9ic2VydmVyID0gUnguT2JzZXJ2ZXIsXHJcbiAgICAgICAgT2JzZXJ2YWJsZSA9IFJ4Lk9ic2VydmFibGUsXHJcbiAgICAgICAgTm90aWZpY2F0aW9uID0gUnguTm90aWZpY2F0aW9uLFxyXG4gICAgICAgIFZpcnR1YWxUaW1lU2NoZWR1bGVyID0gUnguVmlydHVhbFRpbWVTY2hlZHVsZXIsXHJcbiAgICAgICAgRGlzcG9zYWJsZSA9IFJ4LkRpc3Bvc2FibGUsXHJcbiAgICAgICAgZGlzcG9zYWJsZUVtcHR5ID0gRGlzcG9zYWJsZS5lbXB0eSxcclxuICAgICAgICBkaXNwb3NhYmxlQ3JlYXRlID0gRGlzcG9zYWJsZS5jcmVhdGUsXHJcbiAgICAgICAgQ29tcG9zaXRlRGlzcG9zYWJsZSA9IFJ4LkNvbXBvc2l0ZURpc3Bvc2FibGUsXHJcbiAgICAgICAgU2luZ2xlQXNzaWdubWVudERpc3Bvc2FibGUgPSBSeC5TaW5nbGVBc3NpZ25tZW50RGlzcG9zYWJsZSxcclxuICAgICAgICBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZSxcclxuICAgICAgICBpbmhlcml0cyA9IFJ4LmludGVybmFscy5pbmhlcml0cyxcclxuICAgICAgICBkZWZhdWx0Q29tcGFyZXIgPSBSeC5pbnRlcm5hbHMuaXNFcXVhbDtcclxuXHJcbiAgICBmdW5jdGlvbiBhcmdzT3JBcnJheShhcmdzLCBpZHgpIHtcclxuICAgICAgICByZXR1cm4gYXJncy5sZW5ndGggPT09IDEgJiYgQXJyYXkuaXNBcnJheShhcmdzW2lkeF0pID9cclxuICAgICAgICAgICAgYXJnc1tpZHhdIDpcclxuICAgICAgICAgICAgc2xpY2UuY2FsbChhcmdzKTtcclxuICAgIH1cclxuXHJcbiAgICAvKiogXHJcbiAgICAgKiBAcHJpdmF0ZSBcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBPbk5leHRQcmVkaWNhdGUocHJlZGljYXRlKSB7XHJcbiAgICAgICAgdGhpcy5wcmVkaWNhdGUgPSBwcmVkaWNhdGU7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKiBcclxuICAgICAqIEBwcml2YXRlIFxyXG4gICAgICogQG1lbWJlck9mIE9uTmV4dFByZWRpY2F0ZSNcclxuICAgICAqLyAgICBcclxuICAgIE9uTmV4dFByZWRpY2F0ZS5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKG90aGVyKSB7XHJcbiAgICAgICAgaWYgKG90aGVyID09PSB0aGlzKSB7IHJldHVybiB0cnVlOyB9XHJcbiAgICAgICAgaWYgKG90aGVyID09IG51bGwpIHsgcmV0dXJuIGZhbHNlOyB9XHJcbiAgICAgICAgaWYgKG90aGVyLmtpbmQgIT09ICdOJykgeyByZXR1cm4gZmFsc2U7IH1cclxuICAgICAgICByZXR1cm4gdGhpcy5wcmVkaWNhdGUob3RoZXIudmFsdWUpO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKiogXHJcbiAgICAgKiBAcHJpdmF0ZSBcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICovXHJcbiAgICBmdW5jdGlvbiBPbkVycm9yUHJlZGljYXRlKHByZWRpY2F0ZSkge1xyXG4gICAgICAgIHRoaXMucHJlZGljYXRlID0gcHJlZGljYXRlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKiogXHJcbiAgICAgKiBAcHJpdmF0ZSBcclxuICAgICAqIEBtZW1iZXJPZiBPbkVycm9yUHJlZGljYXRlI1xyXG4gICAgICovICAgICAgIFxyXG4gICAgT25FcnJvclByZWRpY2F0ZS5wcm90b3R5cGUuZXF1YWxzID0gZnVuY3Rpb24gKG90aGVyKSB7XHJcbiAgICAgICAgaWYgKG90aGVyID09PSB0aGlzKSB7IHJldHVybiB0cnVlOyB9XHJcbiAgICAgICAgaWYgKG90aGVyID09IG51bGwpIHsgcmV0dXJuIGZhbHNlOyB9XHJcbiAgICAgICAgaWYgKG90aGVyLmtpbmQgIT09ICdFJykgeyByZXR1cm4gZmFsc2U7IH1cclxuICAgICAgICByZXR1cm4gdGhpcy5wcmVkaWNhdGUob3RoZXIuZXhjZXB0aW9uKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqIFxyXG4gICAgICogQHN0YXRpY1xyXG4gICAgICogdHlwZSBPYmplY3RcclxuICAgICAqL1xyXG4gICAgdmFyIFJlYWN0aXZlVGVzdCA9IFJ4LlJlYWN0aXZlVGVzdCA9IHtcclxuICAgICAgICAvKiogRGVmYXVsdCB2aXJ0dWFsIHRpbWUgdXNlZCBmb3IgY3JlYXRpb24gb2Ygb2JzZXJ2YWJsZSBzZXF1ZW5jZXMgaW4gdW5pdCB0ZXN0cy4gKi9cclxuICAgICAgICBjcmVhdGVkOiAxMDAsXHJcbiAgICAgICAgLyoqIERlZmF1bHQgdmlydHVhbCB0aW1lIHVzZWQgdG8gc3Vic2NyaWJlIHRvIG9ic2VydmFibGUgc2VxdWVuY2VzIGluIHVuaXQgdGVzdHMuICovXHJcbiAgICAgICAgc3Vic2NyaWJlZDogMjAwLFxyXG4gICAgICAgIC8qKiBEZWZhdWx0IHZpcnR1YWwgdGltZSB1c2VkIHRvIGRpc3Bvc2Ugc3Vic2NyaXB0aW9ucyBpbiB1bml0IHRlc3RzLiAqL1xyXG4gICAgICAgIGRpc3Bvc2VkOiAxMDAwLFxyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBGYWN0b3J5IG1ldGhvZCBmb3IgYW4gT25OZXh0IG5vdGlmaWNhdGlvbiByZWNvcmQgYXQgYSBnaXZlbiB0aW1lIHdpdGggYSBnaXZlbiB2YWx1ZSBvciBhIHByZWRpY2F0ZSBmdW5jdGlvbi5cclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiAxIC0gUmVhY3RpdmVUZXN0Lm9uTmV4dCgyMDAsIDQyKTtcclxuICAgICAgICAgKiAyIC0gUmVhY3RpdmVUZXN0Lm9uTmV4dCgyMDAsIGZ1bmN0aW9uICh4KSB7IHJldHVybiB4Lmxlbmd0aCA9PSAyOyB9KTtcclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAcGFyYW0gdGlja3MgUmVjb3JkZWQgdmlydHVhbCB0aW1lIHRoZSBPbk5leHQgbm90aWZpY2F0aW9uIG9jY3Vycy5cclxuICAgICAgICAgKiBAcGFyYW0gdmFsdWUgUmVjb3JkZWQgdmFsdWUgc3RvcmVkIGluIHRoZSBPbk5leHQgbm90aWZpY2F0aW9uIG9yIGEgcHJlZGljYXRlLlxyXG4gICAgICAgICAqIEByZXR1cm4gUmVjb3JkZWQgT25OZXh0IG5vdGlmaWNhdGlvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICBvbk5leHQ6IGZ1bmN0aW9uICh0aWNrcywgdmFsdWUpIHtcclxuICAgICAgICAgICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWNvcmRlZCh0aWNrcywgbmV3IE9uTmV4dFByZWRpY2F0ZSh2YWx1ZSkpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVjb3JkZWQodGlja3MsIE5vdGlmaWNhdGlvbi5jcmVhdGVPbk5leHQodmFsdWUpKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEZhY3RvcnkgbWV0aG9kIGZvciBhbiBPbkVycm9yIG5vdGlmaWNhdGlvbiByZWNvcmQgYXQgYSBnaXZlbiB0aW1lIHdpdGggYSBnaXZlbiBlcnJvci5cclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiAxIC0gUmVhY3RpdmVUZXN0Lm9uTmV4dCgyMDAsIG5ldyBFcnJvcignZXJyb3InKSk7XHJcbiAgICAgICAgICogMiAtIFJlYWN0aXZlVGVzdC5vbk5leHQoMjAwLCBmdW5jdGlvbiAoZSkgeyByZXR1cm4gZS5tZXNzYWdlID09PSAnZXJyb3InOyB9KTtcclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAcGFyYW0gdGlja3MgUmVjb3JkZWQgdmlydHVhbCB0aW1lIHRoZSBPbkVycm9yIG5vdGlmaWNhdGlvbiBvY2N1cnMuXHJcbiAgICAgICAgICogQHBhcmFtIGV4Y2VwdGlvbiBSZWNvcmRlZCBleGNlcHRpb24gc3RvcmVkIGluIHRoZSBPbkVycm9yIG5vdGlmaWNhdGlvbi5cclxuICAgICAgICAgKiBAcmV0dXJuIFJlY29yZGVkIE9uRXJyb3Igbm90aWZpY2F0aW9uLiBcclxuICAgICAgICAgKi8gICAgICBcclxuICAgICAgICBvbkVycm9yOiBmdW5jdGlvbiAodGlja3MsIGV4Y2VwdGlvbikge1xyXG4gICAgICAgICAgICBpZiAodHlwZW9mIGV4Y2VwdGlvbiA9PT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWNvcmRlZCh0aWNrcywgbmV3IE9uRXJyb3JQcmVkaWNhdGUoZXhjZXB0aW9uKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBSZWNvcmRlZCh0aWNrcywgTm90aWZpY2F0aW9uLmNyZWF0ZU9uRXJyb3IoZXhjZXB0aW9uKSk7XHJcbiAgICAgICAgfSxcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBGYWN0b3J5IG1ldGhvZCBmb3IgYW4gT25Db21wbGV0ZWQgbm90aWZpY2F0aW9uIHJlY29yZCBhdCBhIGdpdmVuIHRpbWUuXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQHBhcmFtIHRpY2tzIFJlY29yZGVkIHZpcnR1YWwgdGltZSB0aGUgT25Db21wbGV0ZWQgbm90aWZpY2F0aW9uIG9jY3Vycy5cclxuICAgICAgICAgKiBAcmV0dXJuIFJlY29yZGVkIE9uQ29tcGxldGVkIG5vdGlmaWNhdGlvbi5cclxuICAgICAgICAgKi9cclxuICAgICAgICBvbkNvbXBsZXRlZDogZnVuY3Rpb24gKHRpY2tzKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgUmVjb3JkZWQodGlja3MsIE5vdGlmaWNhdGlvbi5jcmVhdGVPbkNvbXBsZXRlZCgpKTtcclxuICAgICAgICB9LFxyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIEZhY3RvcnkgbWV0aG9kIGZvciBhIHN1YnNjcmlwdGlvbiByZWNvcmQgYmFzZWQgb24gYSBnaXZlbiBzdWJzY3JpcHRpb24gYW5kIGRpc3Bvc2FsIHRpbWUuXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQHBhcmFtIHN0YXJ0IFZpcnR1YWwgdGltZSBpbmRpY2F0aW5nIHdoZW4gdGhlIHN1YnNjcmlwdGlvbiB3YXMgY3JlYXRlZC5cclxuICAgICAgICAgKiBAcGFyYW0gZW5kIFZpcnR1YWwgdGltZSBpbmRpY2F0aW5nIHdoZW4gdGhlIHN1YnNjcmlwdGlvbiB3YXMgZGlzcG9zZWQuXHJcbiAgICAgICAgICogQHJldHVybiBTdWJzY3JpcHRpb24gb2JqZWN0LlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIHN1YnNjcmliZTogZnVuY3Rpb24gKHN0YXJ0LCBlbmQpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBTdWJzY3JpcHRpb24oc3RhcnQsIGVuZCk7XHJcbiAgICAgICAgfVxyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBuZXcgb2JqZWN0IHJlY29yZGluZyB0aGUgcHJvZHVjdGlvbiBvZiB0aGUgc3BlY2lmaWVkIHZhbHVlIGF0IHRoZSBnaXZlbiB2aXJ0dWFsIHRpbWUuXHJcbiAgICAgKlxyXG4gICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgKiBAcGFyYW0ge051bWJlcn0gdGltZSBWaXJ0dWFsIHRpbWUgdGhlIHZhbHVlIHdhcyBwcm9kdWNlZCBvbi5cclxuICAgICAqIEBwYXJhbSB7TWl4ZWR9IHZhbHVlIFZhbHVlIHRoYXQgd2FzIHByb2R1Y2VkLlxyXG4gICAgICogQHBhcmFtIHtGdW5jdGlvbn0gY29tcGFyZXIgQW4gb3B0aW9uYWwgY29tcGFyZXIuXHJcbiAgICAgKi9cclxuICAgIHZhciBSZWNvcmRlZCA9IFJ4LlJlY29yZGVkID0gZnVuY3Rpb24gKHRpbWUsIHZhbHVlLCBjb21wYXJlcikge1xyXG4gICAgICAgIHRoaXMudGltZSA9IHRpbWU7XHJcbiAgICAgICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xyXG4gICAgICAgIHRoaXMuY29tcGFyZXIgPSBjb21wYXJlciB8fCBkZWZhdWx0Q29tcGFyZXI7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGdpdmVuIHJlY29yZGVkIG9iamVjdCBpcyBlcXVhbCB0byB0aGUgY3VycmVudCBpbnN0YW5jZS5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0ge1JlY29yZGVkfSBvdGhlciBSZWNvcmRlZCBvYmplY3QgdG8gY2hlY2sgZm9yIGVxdWFsaXR5LlxyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgYm90aCBvYmplY3RzIGFyZSBlcXVhbDsgZmFsc2Ugb3RoZXJ3aXNlLiAgXHJcbiAgICAgKi8gIFxyXG4gICAgUmVjb3JkZWQucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnRpbWUgPT09IG90aGVyLnRpbWUgJiYgdGhpcy5jb21wYXJlcih0aGlzLnZhbHVlLCBvdGhlci52YWx1ZSk7XHJcbiAgICB9O1xyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgY3VycmVudCBSZWNvcmRlZCB2YWx1ZS5cclxuICAgICAqXHJcbiAgICAgKiBAcmV0dXJucyB7U3RyaW5nfSBTdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnJlbnQgUmVjb3JkZWQgdmFsdWUuIFxyXG4gICAgICovICAgXHJcbiAgICBSZWNvcmRlZC5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMudmFsdWUudG9TdHJpbmcoKSArICdAJyArIHRoaXMudGltZTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgbmV3IHN1YnNjcmlwdGlvbiBvYmplY3Qgd2l0aCB0aGUgZ2l2ZW4gdmlydHVhbCBzdWJzY3JpcHRpb24gYW5kIHVuc3Vic2NyaXB0aW9uIHRpbWUuXHJcbiAgICAgKiBcclxuICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICogQHBhcmFtIHtOdW1iZXJ9IHN1YnNjcmliZSBWaXJ0dWFsIHRpbWUgYXQgd2hpY2ggdGhlIHN1YnNjcmlwdGlvbiBvY2N1cnJlZC5cclxuICAgICAqIEBwYXJhbSB7TnVtYmVyfSB1bnN1YnNjcmliZSBWaXJ0dWFsIHRpbWUgYXQgd2hpY2ggdGhlIHVuc3Vic2NyaXB0aW9uIG9jY3VycmVkLlxyXG4gICAgICovXHJcbiAgICB2YXIgU3Vic2NyaXB0aW9uID0gUnguU3Vic2NyaXB0aW9uID0gZnVuY3Rpb24gKHN0YXJ0LCBlbmQpIHtcclxuICAgICAgICB0aGlzLnN1YnNjcmliZSA9IHN0YXJ0O1xyXG4gICAgICAgIHRoaXMudW5zdWJzY3JpYmUgPSBlbmQgfHwgTnVtYmVyLk1BWF9WQUxVRTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDaGVja3Mgd2hldGhlciB0aGUgZ2l2ZW4gc3Vic2NyaXB0aW9uIGlzIGVxdWFsIHRvIHRoZSBjdXJyZW50IGluc3RhbmNlLlxyXG4gICAgICogQHBhcmFtIG90aGVyIFN1YnNjcmlwdGlvbiBvYmplY3QgdG8gY2hlY2sgZm9yIGVxdWFsaXR5LlxyXG4gICAgICogQHJldHVybnMge0Jvb2xlYW59IHRydWUgaWYgYm90aCBvYmplY3RzIGFyZSBlcXVhbDsgZmFsc2Ugb3RoZXJ3aXNlLlxyXG4gICAgICovXHJcbiAgICBTdWJzY3JpcHRpb24ucHJvdG90eXBlLmVxdWFscyA9IGZ1bmN0aW9uIChvdGhlcikge1xyXG4gICAgICAgIHJldHVybiB0aGlzLnN1YnNjcmliZSA9PT0gb3RoZXIuc3Vic2NyaWJlICYmIHRoaXMudW5zdWJzY3JpYmUgPT09IG90aGVyLnVuc3Vic2NyaWJlO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgYSBzdHJpbmcgcmVwcmVzZW50YXRpb24gb2YgdGhlIGN1cnJlbnQgU3Vic2NyaXB0aW9uIHZhbHVlLlxyXG4gICAgICogQHJldHVybnMge1N0cmluZ30gU3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBjdXJyZW50IFN1YnNjcmlwdGlvbiB2YWx1ZS5cclxuICAgICAqL1xyXG4gICAgU3Vic2NyaXB0aW9uLnByb3RvdHlwZS50b1N0cmluZyA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICByZXR1cm4gJygnICsgdGhpcy5zdWJzY3JpYmUgKyAnLCAnICsgdGhpcy51bnN1YnNjcmliZSA9PT0gTnVtYmVyLk1BWF9WQUxVRSA/ICdJbmZpbml0ZScgOiB0aGlzLnVuc3Vic2NyaWJlICsgJyknO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKiogQHByaXZhdGUgKi9cclxuICAgIHZhciBNb2NrRGlzcG9zYWJsZSA9IFJ4Lk1vY2tEaXNwb3NhYmxlID0gZnVuY3Rpb24gKHNjaGVkdWxlcikge1xyXG4gICAgICAgIHRoaXMuc2NoZWR1bGVyID0gc2NoZWR1bGVyO1xyXG4gICAgICAgIHRoaXMuZGlzcG9zZXMgPSBbXTtcclxuICAgICAgICB0aGlzLmRpc3Bvc2VzLnB1c2godGhpcy5zY2hlZHVsZXIuY2xvY2spO1xyXG4gICAgfTtcclxuXHJcbiAgICAvKlxyXG4gICAgICogQG1lbWJlck9mIE1vY2tEaXNwb3NhYmxlI1xyXG4gICAgICogQHBydmlhdGVcclxuICAgICAqL1xyXG4gICAgTW9ja0Rpc3Bvc2FibGUucHJvdG90eXBlLmRpc3Bvc2UgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgdGhpcy5kaXNwb3Nlcy5wdXNoKHRoaXMuc2NoZWR1bGVyLmNsb2NrKTtcclxuICAgIH07XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICB2YXIgTW9ja09ic2VydmVyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgICAgICBpbmhlcml0cyhNb2NrT2JzZXJ2ZXIsIF9zdXBlcik7XHJcblxyXG4gICAgICAgIC8qXHJcbiAgICAgICAgICogQGNvbnN0cnVjdG9yXHJcbiAgICAgICAgICogQHBydmlhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBmdW5jdGlvbiBNb2NrT2JzZXJ2ZXIoc2NoZWR1bGVyKSB7XHJcbiAgICAgICAgICAgIF9zdXBlci5jYWxsKHRoaXMpO1xyXG4gICAgICAgICAgICB0aGlzLnNjaGVkdWxlciA9IHNjaGVkdWxlcjtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlcyA9IFtdO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgdmFyIE1vY2tPYnNlcnZlclByb3RvdHlwZSA9IE1vY2tPYnNlcnZlci5wcm90b3R5cGU7XHJcblxyXG4gICAgICAgIC8qXHJcbiAgICAgICAgICogQG1lbWJlck9mIE1vY2tPYnNlcnZlclByb3RvdHlwZSNcclxuICAgICAgICAgKiBAcHJ2aWF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIE1vY2tPYnNlcnZlclByb3RvdHlwZS5vbk5leHQgPSBmdW5jdGlvbiAodmFsdWUpIHtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5wdXNoKG5ldyBSZWNvcmRlZCh0aGlzLnNjaGVkdWxlci5jbG9jaywgTm90aWZpY2F0aW9uLmNyZWF0ZU9uTmV4dCh2YWx1ZSkpKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICAvKlxyXG4gICAgICAgICAqIEBtZW1iZXJPZiBNb2NrT2JzZXJ2ZXJQcm90b3R5cGUjXHJcbiAgICAgICAgICogQHBydmlhdGVcclxuICAgICAgICAgKi9cclxuICAgICAgICBNb2NrT2JzZXJ2ZXJQcm90b3R5cGUub25FcnJvciA9IGZ1bmN0aW9uIChleGNlcHRpb24pIHtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5wdXNoKG5ldyBSZWNvcmRlZCh0aGlzLnNjaGVkdWxlci5jbG9jaywgTm90aWZpY2F0aW9uLmNyZWF0ZU9uRXJyb3IoZXhjZXB0aW9uKSkpO1xyXG4gICAgICAgIH07XHJcblxyXG4gICAgICAgIC8qXHJcbiAgICAgICAgICogQG1lbWJlck9mIE1vY2tPYnNlcnZlclByb3RvdHlwZSNcclxuICAgICAgICAgKiBAcHJ2aWF0ZVxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIE1vY2tPYnNlcnZlclByb3RvdHlwZS5vbkNvbXBsZXRlZCA9IGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgdGhpcy5tZXNzYWdlcy5wdXNoKG5ldyBSZWNvcmRlZCh0aGlzLnNjaGVkdWxlci5jbG9jaywgTm90aWZpY2F0aW9uLmNyZWF0ZU9uQ29tcGxldGVkKCkpKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gTW9ja09ic2VydmVyO1xyXG4gICAgfSkoT2JzZXJ2ZXIpO1xyXG5cclxuICAgIC8qKiBAcHJpdmF0ZSAqLyAgICBcclxuICAgIHZhciBIb3RPYnNlcnZhYmxlID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuXHJcbiAgICAgICAgZnVuY3Rpb24gc3Vic2NyaWJlKG9ic2VydmVyKSB7XHJcbiAgICAgICAgICAgIHZhciBvYnNlcnZhYmxlID0gdGhpcztcclxuICAgICAgICAgICAgdGhpcy5vYnNlcnZlcnMucHVzaChvYnNlcnZlcik7XHJcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKG5ldyBTdWJzY3JpcHRpb24odGhpcy5zY2hlZHVsZXIuY2xvY2spKTtcclxuICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5zdWJzY3JpcHRpb25zLmxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgIHJldHVybiBkaXNwb3NhYmxlQ3JlYXRlKGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHZhciBpZHggPSBvYnNlcnZhYmxlLm9ic2VydmVycy5pbmRleE9mKG9ic2VydmVyKTtcclxuICAgICAgICAgICAgICAgIG9ic2VydmFibGUub2JzZXJ2ZXJzLnNwbGljZShpZHgsIDEpO1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2YWJsZS5zdWJzY3JpcHRpb25zW2luZGV4XSA9IG5ldyBTdWJzY3JpcHRpb24ob2JzZXJ2YWJsZS5zdWJzY3JpcHRpb25zW2luZGV4XS5zdWJzY3JpYmUsIG9ic2VydmFibGUuc2NoZWR1bGVyLmNsb2NrKTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpbmhlcml0cyhIb3RPYnNlcnZhYmxlLCBfc3VwZXIpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIEhvdE9ic2VydmFibGUoc2NoZWR1bGVyLCBtZXNzYWdlcykge1xyXG4gICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCBzdWJzY3JpYmUpO1xyXG4gICAgICAgICAgICB2YXIgbWVzc2FnZSwgbm90aWZpY2F0aW9uLCBvYnNlcnZhYmxlID0gdGhpcztcclxuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZXIgPSBzY2hlZHVsZXI7XHJcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlcztcclxuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zID0gW107XHJcbiAgICAgICAgICAgIHRoaXMub2JzZXJ2ZXJzID0gW107XHJcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBsZW4gPSB0aGlzLm1lc3NhZ2VzLmxlbmd0aDsgaSA8IGxlbjsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBtZXNzYWdlID0gdGhpcy5tZXNzYWdlc1tpXTtcclxuICAgICAgICAgICAgICAgIG5vdGlmaWNhdGlvbiA9IG1lc3NhZ2UudmFsdWU7XHJcbiAgICAgICAgICAgICAgICAoZnVuY3Rpb24gKGlubmVyTm90aWZpY2F0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgc2NoZWR1bGVyLnNjaGVkdWxlQWJzb2x1dGVXaXRoU3RhdGUobnVsbCwgbWVzc2FnZS50aW1lLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHZhciBvYnMgPSBvYnNlcnZhYmxlLm9ic2VydmVycy5zbGljZSgwKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAodmFyIGogPSAwLCBqTGVuID0gb2JzLmxlbmd0aDsgaiA8IGpMZW47IGorKykge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5uZXJOb3RpZmljYXRpb24uYWNjZXB0KG9ic1tqXSk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpc3Bvc2FibGVFbXB0eTtcclxuICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIH0pKG5vdGlmaWNhdGlvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBIb3RPYnNlcnZhYmxlO1xyXG4gICAgfSkoT2JzZXJ2YWJsZSk7XHJcblxyXG4gICAgLyoqIEBwcml2YXRlICovXHJcbiAgICB2YXIgQ29sZE9ic2VydmFibGUgPSAoZnVuY3Rpb24gKF9zdXBlcikge1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBzdWJzY3JpYmUob2JzZXJ2ZXIpIHtcclxuICAgICAgICAgICAgdmFyIG1lc3NhZ2UsIG5vdGlmaWNhdGlvbiwgb2JzZXJ2YWJsZSA9IHRoaXM7XHJcbiAgICAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9ucy5wdXNoKG5ldyBTdWJzY3JpcHRpb24odGhpcy5zY2hlZHVsZXIuY2xvY2spKTtcclxuICAgICAgICAgICAgdmFyIGluZGV4ID0gdGhpcy5zdWJzY3JpcHRpb25zLmxlbmd0aCAtIDE7XHJcbiAgICAgICAgICAgIHZhciBkID0gbmV3IENvbXBvc2l0ZURpc3Bvc2FibGUoKTtcclxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDAsIGxlbiA9IHRoaXMubWVzc2FnZXMubGVuZ3RoOyBpIDwgbGVuOyBpKyspIHtcclxuICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSB0aGlzLm1lc3NhZ2VzW2ldO1xyXG4gICAgICAgICAgICAgICAgbm90aWZpY2F0aW9uID0gbWVzc2FnZS52YWx1ZTtcclxuICAgICAgICAgICAgICAgIChmdW5jdGlvbiAoaW5uZXJOb3RpZmljYXRpb24pIHtcclxuICAgICAgICAgICAgICAgICAgICBkLmFkZChvYnNlcnZhYmxlLnNjaGVkdWxlci5zY2hlZHVsZVJlbGF0aXZlV2l0aFN0YXRlKG51bGwsIG1lc3NhZ2UudGltZSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpbm5lck5vdGlmaWNhdGlvbi5hY2NlcHQob2JzZXJ2ZXIpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZGlzcG9zYWJsZUVtcHR5O1xyXG4gICAgICAgICAgICAgICAgICAgIH0pKTtcclxuICAgICAgICAgICAgICAgIH0pKG5vdGlmaWNhdGlvbik7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGRpc3Bvc2FibGVDcmVhdGUoZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICAgICAgb2JzZXJ2YWJsZS5zdWJzY3JpcHRpb25zW2luZGV4XSA9IG5ldyBTdWJzY3JpcHRpb24ob2JzZXJ2YWJsZS5zdWJzY3JpcHRpb25zW2luZGV4XS5zdWJzY3JpYmUsIG9ic2VydmFibGUuc2NoZWR1bGVyLmNsb2NrKTtcclxuICAgICAgICAgICAgICAgIGQuZGlzcG9zZSgpO1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGluaGVyaXRzKENvbGRPYnNlcnZhYmxlLCBfc3VwZXIpO1xyXG5cclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBAcHJpdmF0ZVxyXG4gICAgICAgICAqIEBjb25zdHJ1Y3RvclxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIGZ1bmN0aW9uIENvbGRPYnNlcnZhYmxlKHNjaGVkdWxlciwgbWVzc2FnZXMpIHtcclxuICAgICAgICAgICAgX3N1cGVyLmNhbGwodGhpcywgc3Vic2NyaWJlKTtcclxuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZXIgPSBzY2hlZHVsZXI7XHJcbiAgICAgICAgICAgIHRoaXMubWVzc2FnZXMgPSBtZXNzYWdlcztcclxuICAgICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb25zID0gW107XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gQ29sZE9ic2VydmFibGU7XHJcbiAgICB9KShPYnNlcnZhYmxlKTtcclxuXHJcbiAgICAvKiogVmlydHVhbCB0aW1lIHNjaGVkdWxlciB1c2VkIGZvciB0ZXN0aW5nIGFwcGxpY2F0aW9ucyBhbmQgbGlicmFyaWVzIGJ1aWx0IHVzaW5nIFJlYWN0aXZlIEV4dGVuc2lvbnMuICovXHJcbiAgICBSeC5UZXN0U2NoZWR1bGVyID0gKGZ1bmN0aW9uIChfc3VwZXIpIHtcclxuICAgICAgICBpbmhlcml0cyhUZXN0U2NoZWR1bGVyLCBfc3VwZXIpO1xyXG5cclxuICAgICAgICBmdW5jdGlvbiBiYXNlQ29tcGFyZXIoeCwgeSkge1xyXG4gICAgICAgICAgICByZXR1cm4geCA+IHkgPyAxIDogKHggPCB5ID8gLTEgOiAwKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8qKiBAY29uc3RydWN0b3IgKi9cclxuICAgICAgICBmdW5jdGlvbiBUZXN0U2NoZWR1bGVyKCkge1xyXG4gICAgICAgICAgICBfc3VwZXIuY2FsbCh0aGlzLCAwLCBiYXNlQ29tcGFyZXIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogU2NoZWR1bGVzIGFuIGFjdGlvbiB0byBiZSBleGVjdXRlZCBhdCB0aGUgc3BlY2lmaWVkIHZpcnR1YWwgdGltZS5cclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAcGFyYW0gc3RhdGUgU3RhdGUgcGFzc2VkIHRvIHRoZSBhY3Rpb24gdG8gYmUgZXhlY3V0ZWQuXHJcbiAgICAgICAgICogQHBhcmFtIGR1ZVRpbWUgQWJzb2x1dGUgdmlydHVhbCB0aW1lIGF0IHdoaWNoIHRvIGV4ZWN1dGUgdGhlIGFjdGlvbi5cclxuICAgICAgICAgKiBAcGFyYW0gYWN0aW9uIEFjdGlvbiB0byBiZSBleGVjdXRlZC5cclxuICAgICAgICAgKiBAcmV0dXJuIERpc3Bvc2FibGUgb2JqZWN0IHVzZWQgdG8gY2FuY2VsIHRoZSBzY2hlZHVsZWQgYWN0aW9uIChiZXN0IGVmZm9ydCkuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgVGVzdFNjaGVkdWxlci5wcm90b3R5cGUuc2NoZWR1bGVBYnNvbHV0ZVdpdGhTdGF0ZSA9IGZ1bmN0aW9uIChzdGF0ZSwgZHVlVGltZSwgYWN0aW9uKSB7XHJcbiAgICAgICAgICAgIGlmIChkdWVUaW1lIDw9IHRoaXMuY2xvY2spIHtcclxuICAgICAgICAgICAgICAgIGR1ZVRpbWUgPSB0aGlzLmNsb2NrICsgMTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gX3N1cGVyLnByb3RvdHlwZS5zY2hlZHVsZUFic29sdXRlV2l0aFN0YXRlLmNhbGwodGhpcywgc3RhdGUsIGR1ZVRpbWUsIGFjdGlvbik7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBBZGRzIGEgcmVsYXRpdmUgdmlydHVhbCB0aW1lIHRvIGFuIGFic29sdXRlIHZpcnR1YWwgdGltZSB2YWx1ZS5cclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAcGFyYW0gYWJzb2x1dGUgQWJzb2x1dGUgdmlydHVhbCB0aW1lIHZhbHVlLlxyXG4gICAgICAgICAqIEBwYXJhbSByZWxhdGl2ZSBSZWxhdGl2ZSB2aXJ0dWFsIHRpbWUgdmFsdWUgdG8gYWRkLlxyXG4gICAgICAgICAqIEByZXR1cm4gUmVzdWx0aW5nIGFic29sdXRlIHZpcnR1YWwgdGltZSBzdW0gdmFsdWUuXHJcbiAgICAgICAgICovXHJcbiAgICAgICAgVGVzdFNjaGVkdWxlci5wcm90b3R5cGUuYWRkID0gZnVuY3Rpb24gKGFic29sdXRlLCByZWxhdGl2ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gYWJzb2x1dGUgKyByZWxhdGl2ZTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIENvbnZlcnRzIHRoZSBhYnNvbHV0ZSB2aXJ0dWFsIHRpbWUgdmFsdWUgdG8gYSBEYXRlVGltZU9mZnNldCB2YWx1ZS5cclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAcGFyYW0gYWJzb2x1dGUgQWJzb2x1dGUgdmlydHVhbCB0aW1lIHZhbHVlIHRvIGNvbnZlcnQuXHJcbiAgICAgICAgICogQHJldHVybiBDb3JyZXNwb25kaW5nIERhdGVUaW1lT2Zmc2V0IHZhbHVlLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFRlc3RTY2hlZHVsZXIucHJvdG90eXBlLnRvRGF0ZVRpbWVPZmZzZXQgPSBmdW5jdGlvbiAoYWJzb2x1dGUpIHtcclxuICAgICAgICAgICAgcmV0dXJuIG5ldyBEYXRlKGFic29sdXRlKS5nZXRUaW1lKCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDb252ZXJ0cyB0aGUgVGltZVNwYW4gdmFsdWUgdG8gYSByZWxhdGl2ZSB2aXJ0dWFsIHRpbWUgdmFsdWUuXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQHBhcmFtIHRpbWVTcGFuIFRpbWVTcGFuIHZhbHVlIHRvIGNvbnZlcnQuXHJcbiAgICAgICAgICogQHJldHVybiBDb3JyZXNwb25kaW5nIHJlbGF0aXZlIHZpcnR1YWwgdGltZSB2YWx1ZS5cclxuICAgICAgICAgKi9cclxuICAgICAgICBUZXN0U2NoZWR1bGVyLnByb3RvdHlwZS50b1JlbGF0aXZlID0gZnVuY3Rpb24gKHRpbWVTcGFuKSB7XHJcbiAgICAgICAgICAgIHJldHVybiB0aW1lU3BhbjtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFN0YXJ0cyB0aGUgdGVzdCBzY2hlZHVsZXIgYW5kIHVzZXMgdGhlIHNwZWNpZmllZCB2aXJ0dWFsIHRpbWVzIHRvIGludm9rZSB0aGUgZmFjdG9yeSBmdW5jdGlvbiwgc3Vic2NyaWJlIHRvIHRoZSByZXN1bHRpbmcgc2VxdWVuY2UsIGFuZCBkaXNwb3NlIHRoZSBzdWJzY3JpcHRpb24uXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQHBhcmFtIGNyZWF0ZSBGYWN0b3J5IG1ldGhvZCB0byBjcmVhdGUgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAgICAgKiBAcGFyYW0gY3JlYXRlZCBWaXJ0dWFsIHRpbWUgYXQgd2hpY2ggdG8gaW52b2tlIHRoZSBmYWN0b3J5IHRvIGNyZWF0ZSBhbiBvYnNlcnZhYmxlIHNlcXVlbmNlLlxyXG4gICAgICAgICAqIEBwYXJhbSBzdWJzY3JpYmVkIFZpcnR1YWwgdGltZSBhdCB3aGljaCB0byBzdWJzY3JpYmUgdG8gdGhlIGNyZWF0ZWQgb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAgICAgKiBAcGFyYW0gZGlzcG9zZWQgVmlydHVhbCB0aW1lIGF0IHdoaWNoIHRvIGRpc3Bvc2UgdGhlIHN1YnNjcmlwdGlvbi5cclxuICAgICAgICAgKiBAcmV0dXJuIE9ic2VydmVyIHdpdGggdGltZXN0YW1wZWQgcmVjb3JkaW5ncyBvZiBub3RpZmljYXRpb24gbWVzc2FnZXMgdGhhdCB3ZXJlIHJlY2VpdmVkIGR1cmluZyB0aGUgdmlydHVhbCB0aW1lIHdpbmRvdyB3aGVuIHRoZSBzdWJzY3JpcHRpb24gdG8gdGhlIHNvdXJjZSBzZXF1ZW5jZSB3YXMgYWN0aXZlLlxyXG4gICAgICAgICAqLyAgICAgICAgXHJcbiAgICAgICAgVGVzdFNjaGVkdWxlci5wcm90b3R5cGUuc3RhcnRXaXRoVGltaW5nID0gZnVuY3Rpb24gKGNyZWF0ZSwgY3JlYXRlZCwgc3Vic2NyaWJlZCwgZGlzcG9zZWQpIHtcclxuICAgICAgICAgICAgdmFyIG9ic2VydmVyID0gdGhpcy5jcmVhdGVPYnNlcnZlcigpLCBzb3VyY2UsIHN1YnNjcmlwdGlvbjtcclxuICAgICAgICAgICAgdGhpcy5zY2hlZHVsZUFic29sdXRlV2l0aFN0YXRlKG51bGwsIGNyZWF0ZWQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHNvdXJjZSA9IGNyZWF0ZSgpO1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGRpc3Bvc2FibGVFbXB0eTtcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIHRoaXMuc2NoZWR1bGVBYnNvbHV0ZVdpdGhTdGF0ZShudWxsLCBzdWJzY3JpYmVkLCBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgICAgICBzdWJzY3JpcHRpb24gPSBzb3VyY2Uuc3Vic2NyaWJlKG9ic2VydmVyKTtcclxuICAgICAgICAgICAgICAgIHJldHVybiBkaXNwb3NhYmxlRW1wdHk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICB0aGlzLnNjaGVkdWxlQWJzb2x1dGVXaXRoU3RhdGUobnVsbCwgZGlzcG9zZWQsIGZ1bmN0aW9uICgpIHtcclxuICAgICAgICAgICAgICAgIHN1YnNjcmlwdGlvbi5kaXNwb3NlKCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZGlzcG9zYWJsZUVtcHR5O1xyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgdGhpcy5zdGFydCgpO1xyXG4gICAgICAgICAgICByZXR1cm4gb2JzZXJ2ZXI7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBTdGFydHMgdGhlIHRlc3Qgc2NoZWR1bGVyIGFuZCB1c2VzIHRoZSBzcGVjaWZpZWQgdmlydHVhbCB0aW1lIHRvIGRpc3Bvc2UgdGhlIHN1YnNjcmlwdGlvbiB0byB0aGUgc2VxdWVuY2Ugb2J0YWluZWQgdGhyb3VnaCB0aGUgZmFjdG9yeSBmdW5jdGlvbi5cclxuICAgICAgICAgKiBEZWZhdWx0IHZpcnR1YWwgdGltZXMgYXJlIHVzZWQgZm9yIGZhY3RvcnkgaW52b2NhdGlvbiBhbmQgc2VxdWVuY2Ugc3Vic2NyaXB0aW9uLlxyXG4gICAgICAgICAqIFxyXG4gICAgICAgICAqIEBwYXJhbSBjcmVhdGUgRmFjdG9yeSBtZXRob2QgdG8gY3JlYXRlIGFuIG9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICAgICAgICogQHBhcmFtIGRpc3Bvc2VkIFZpcnR1YWwgdGltZSBhdCB3aGljaCB0byBkaXNwb3NlIHRoZSBzdWJzY3JpcHRpb24uXHJcbiAgICAgICAgICogQHJldHVybiBPYnNlcnZlciB3aXRoIHRpbWVzdGFtcGVkIHJlY29yZGluZ3Mgb2Ygbm90aWZpY2F0aW9uIG1lc3NhZ2VzIHRoYXQgd2VyZSByZWNlaXZlZCBkdXJpbmcgdGhlIHZpcnR1YWwgdGltZSB3aW5kb3cgd2hlbiB0aGUgc3Vic2NyaXB0aW9uIHRvIHRoZSBzb3VyY2Ugc2VxdWVuY2Ugd2FzIGFjdGl2ZS5cclxuICAgICAgICAgKi8gICAgICAgIFxyXG4gICAgICAgIFRlc3RTY2hlZHVsZXIucHJvdG90eXBlLnN0YXJ0V2l0aERpc3Bvc2UgPSBmdW5jdGlvbiAoY3JlYXRlLCBkaXNwb3NlZCkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydFdpdGhUaW1pbmcoY3JlYXRlLCBSZWFjdGl2ZVRlc3QuY3JlYXRlZCwgUmVhY3RpdmVUZXN0LnN1YnNjcmliZWQsIGRpc3Bvc2VkKTtcclxuICAgICAgICB9O1xyXG4gICAgICAgIC8qKlxyXG4gICAgICAgICAqIFN0YXJ0cyB0aGUgdGVzdCBzY2hlZHVsZXIgYW5kIHVzZXMgZGVmYXVsdCB2aXJ0dWFsIHRpbWVzIHRvIGludm9rZSB0aGUgZmFjdG9yeSBmdW5jdGlvbiwgdG8gc3Vic2NyaWJlIHRvIHRoZSByZXN1bHRpbmcgc2VxdWVuY2UsIGFuZCB0byBkaXNwb3NlIHRoZSBzdWJzY3JpcHRpb24uXHJcbiAgICAgICAgICogXHJcbiAgICAgICAgICogQHBhcmFtIGNyZWF0ZSBGYWN0b3J5IG1ldGhvZCB0byBjcmVhdGUgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgICAgICAgKiBAcmV0dXJuIE9ic2VydmVyIHdpdGggdGltZXN0YW1wZWQgcmVjb3JkaW5ncyBvZiBub3RpZmljYXRpb24gbWVzc2FnZXMgdGhhdCB3ZXJlIHJlY2VpdmVkIGR1cmluZyB0aGUgdmlydHVhbCB0aW1lIHdpbmRvdyB3aGVuIHRoZSBzdWJzY3JpcHRpb24gdG8gdGhlIHNvdXJjZSBzZXF1ZW5jZSB3YXMgYWN0aXZlLlxyXG4gICAgICAgICAqLyAgICAgICAgXHJcbiAgICAgICAgVGVzdFNjaGVkdWxlci5wcm90b3R5cGUuc3RhcnRXaXRoQ3JlYXRlID0gZnVuY3Rpb24gKGNyZWF0ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5zdGFydFdpdGhUaW1pbmcoY3JlYXRlLCBSZWFjdGl2ZVRlc3QuY3JlYXRlZCwgUmVhY3RpdmVUZXN0LnN1YnNjcmliZWQsIFJlYWN0aXZlVGVzdC5kaXNwb3NlZCk7XHJcbiAgICAgICAgfTtcclxuICAgICAgICAvKipcclxuICAgICAgICAgKiBDcmVhdGVzIGEgaG90IG9ic2VydmFibGUgdXNpbmcgdGhlIHNwZWNpZmllZCB0aW1lc3RhbXBlZCBub3RpZmljYXRpb24gbWVzc2FnZXMgZWl0aGVyIGFzIGFuIGFycmF5IG9yIGFyZ3VtZW50cy5cclxuICAgICAgICAgKiBcclxuICAgICAgICAgKiBAcGFyYW0gbWVzc2FnZXMgTm90aWZpY2F0aW9ucyB0byBzdXJmYWNlIHRocm91Z2ggdGhlIGNyZWF0ZWQgc2VxdWVuY2UgYXQgdGhlaXIgc3BlY2lmaWVkIGFic29sdXRlIHZpcnR1YWwgdGltZXMuXHJcbiAgICAgICAgICogQHJldHVybiBIb3Qgb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0aGF0IGNhbiBiZSB1c2VkIHRvIGFzc2VydCB0aGUgdGltaW5nIG9mIHN1YnNjcmlwdGlvbnMgYW5kIG5vdGlmaWNhdGlvbnMuXHJcbiAgICAgICAgICovICAgICAgICBcclxuICAgICAgICBUZXN0U2NoZWR1bGVyLnByb3RvdHlwZS5jcmVhdGVIb3RPYnNlcnZhYmxlID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICB2YXIgbWVzc2FnZXMgPSBhcmdzT3JBcnJheShhcmd1bWVudHMsIDApO1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IEhvdE9ic2VydmFibGUodGhpcywgbWVzc2FnZXMpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ3JlYXRlcyBhIGNvbGQgb2JzZXJ2YWJsZSB1c2luZyB0aGUgc3BlY2lmaWVkIHRpbWVzdGFtcGVkIG5vdGlmaWNhdGlvbiBtZXNzYWdlcyBlaXRoZXIgYXMgYW4gYXJyYXkgb3IgYXJndW1lbnRzLlxyXG4gICAgICAgICAqIFxyXG4gICAgICAgICAqIEBwYXJhbSBtZXNzYWdlcyBOb3RpZmljYXRpb25zIHRvIHN1cmZhY2UgdGhyb3VnaCB0aGUgY3JlYXRlZCBzZXF1ZW5jZSBhdCB0aGVpciBzcGVjaWZpZWQgdmlydHVhbCB0aW1lIG9mZnNldHMgZnJvbSB0aGUgc2VxdWVuY2Ugc3Vic2NyaXB0aW9uIHRpbWUuXHJcbiAgICAgICAgICogQHJldHVybiBDb2xkIG9ic2VydmFibGUgc2VxdWVuY2UgdGhhdCBjYW4gYmUgdXNlZCB0byBhc3NlcnQgdGhlIHRpbWluZyBvZiBzdWJzY3JpcHRpb25zIGFuZCBub3RpZmljYXRpb25zLlxyXG4gICAgICAgICAqLyAgICAgICAgXHJcbiAgICAgICAgVGVzdFNjaGVkdWxlci5wcm90b3R5cGUuY3JlYXRlQ29sZE9ic2VydmFibGUgPSBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICAgIHZhciBtZXNzYWdlcyA9IGFyZ3NPckFycmF5KGFyZ3VtZW50cywgMCk7XHJcbiAgICAgICAgICAgIHJldHVybiBuZXcgQ29sZE9ic2VydmFibGUodGhpcywgbWVzc2FnZXMpO1xyXG4gICAgICAgIH07XHJcbiAgICAgICAgLyoqXHJcbiAgICAgICAgICogQ3JlYXRlcyBhbiBvYnNlcnZlciB0aGF0IHJlY29yZHMgcmVjZWl2ZWQgbm90aWZpY2F0aW9uIG1lc3NhZ2VzIGFuZCB0aW1lc3RhbXBzIHRob3NlLlxyXG4gICAgICAgICAqIFxyXG4gICAgICAgICAqIEByZXR1cm4gT2JzZXJ2ZXIgdGhhdCBjYW4gYmUgdXNlZCB0byBhc3NlcnQgdGhlIHRpbWluZyBvZiByZWNlaXZlZCBub3RpZmljYXRpb25zLlxyXG4gICAgICAgICAqL1xyXG4gICAgICAgIFRlc3RTY2hlZHVsZXIucHJvdG90eXBlLmNyZWF0ZU9ic2VydmVyID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICAgICAgICByZXR1cm4gbmV3IE1vY2tPYnNlcnZlcih0aGlzKTtcclxuICAgICAgICB9O1xyXG5cclxuICAgICAgICByZXR1cm4gVGVzdFNjaGVkdWxlcjtcclxuICAgIH0pKFZpcnR1YWxUaW1lU2NoZWR1bGVyKTtcclxuXHJcbiAgICByZXR1cm4gUng7XHJcbn0pKTtcbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4L2Rpc3QvcngudGVzdGluZy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeC9kaXN0XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIFJ4ID0gcmVxdWlyZSgnLi9kaXN0L3J4LmFsbCcpO1xyXG5yZXF1aXJlKCcuL2Rpc3QvcngudGVzdGluZycpO1xyXG5cclxuLy8gQWRkIHNwZWNpZmljIE5vZGUgZnVuY3Rpb25zXHJcbnZhciBFdmVudEVtaXR0ZXIgPSByZXF1aXJlKCdldmVudHMnKS5FdmVudEVtaXR0ZXIsXHJcbiAgT2JzZXJ2YWJsZSA9IFJ4Lk9ic2VydmFibGU7XHJcblxyXG5SeC5Ob2RlID0ge1xyXG4gIC8qKlxyXG4gICAqIEBkZXByZWNhdGVkIFVzZSBSeC5PYnNlcnZhYmxlLmZyb21DYWxsYmFjayBmcm9tIHJ4LmFzeW5jLmpzIGluc3RlYWQuXHJcbiAgICpcclxuICAgKiBDb252ZXJ0cyBhIGNhbGxiYWNrIGZ1bmN0aW9uIHRvIGFuIG9ic2VydmFibGUgc2VxdWVuY2UuIFxyXG4gICAqIFxyXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGZ1bmMgRnVuY3Rpb24gdG8gY29udmVydCB0byBhbiBhc3luY2hyb25vdXMgZnVuY3Rpb24uXHJcbiAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtzY2hlZHVsZXJdIFNjaGVkdWxlciB0byBydW4gdGhlIGZ1bmN0aW9uIG9uLiBJZiBub3Qgc3BlY2lmaWVkLCBkZWZhdWx0cyB0byBTY2hlZHVsZXIudGltZW91dC5cclxuICAgKiBAcGFyYW0ge01peGVkfSBbY29udGV4dF0gVGhlIGNvbnRleHQgZm9yIHRoZSBmdW5jIHBhcmFtZXRlciB0byBiZSBleGVjdXRlZC4gIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIHVuZGVmaW5lZC5cclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbc2VsZWN0b3JdIEEgc2VsZWN0b3Igd2hpY2ggdGFrZXMgdGhlIGFyZ3VtZW50cyBmcm9tIHRoZSBldmVudCBoYW5kbGVyIHRvIHByb2R1Y2UgYSBzaW5nbGUgaXRlbSB0byB5aWVsZCBvbiBuZXh0LiAgICAgXHJcbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBBc3luY2hyb25vdXMgZnVuY3Rpb24uXHJcbiAgICovXHJcbiAgZnJvbUNhbGxiYWNrOiBmdW5jdGlvbiAoZnVuYywgc2NoZWR1bGVyLCBjb250ZXh0LCBzZWxlY3Rvcikge1xyXG4gICAgcmV0dXJuIE9ic2VydmFibGUuZnJvbUNhbGxiYWNrKGZ1bmMsIHNjaGVkdWxlciwgY29udGV4dCwgc2VsZWN0b3IpO1xyXG4gIH0sXHJcblxyXG4gIC8qKlxyXG4gICAqIEBkZXByZWNhdGVkIFVzZSBSeC5PYnNlcnZhYmxlLmZyb21Ob2RlQ2FsbGJhY2sgZnJvbSByeC5hc3luYy5qcyBpbnN0ZWFkLlxyXG4gICAqXHJcbiAgICogQ29udmVydHMgYSBOb2RlLmpzIGNhbGxiYWNrIHN0eWxlIGZ1bmN0aW9uIHRvIGFuIG9ic2VydmFibGUgc2VxdWVuY2UuICBUaGlzIG11c3QgYmUgaW4gZnVuY3Rpb24gKGVyciwgLi4uKSBmb3JtYXQuXHJcbiAgICpcclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBmdW5jIFRoZSBmdW5jdGlvbiB0byBjYWxsXHJcbiAgICogQHBhcmFtIHtTY2hlZHVsZXJ9IFtzY2hlZHVsZXJdIFNjaGVkdWxlciB0byBydW4gdGhlIGZ1bmN0aW9uIG9uLiBJZiBub3Qgc3BlY2lmaWVkLCBkZWZhdWx0cyB0byBTY2hlZHVsZXIudGltZW91dC5cclxuICAgKiBAcGFyYW0ge01peGVkfSBbY29udGV4dF0gVGhlIGNvbnRleHQgZm9yIHRoZSBmdW5jIHBhcmFtZXRlciB0byBiZSBleGVjdXRlZC4gIElmIG5vdCBzcGVjaWZpZWQsIGRlZmF1bHRzIHRvIHVuZGVmaW5lZC5cclxuICAgKiBAcGFyYW0ge0Z1bmN0aW9ufSBbc2VsZWN0b3JdIEEgc2VsZWN0b3Igd2hpY2ggdGFrZXMgdGhlIGFyZ3VtZW50cyBmcm9tIHRoZSBldmVudCBoYW5kbGVyIHRvIHByb2R1Y2UgYSBzaW5nbGUgaXRlbSB0byB5aWVsZCBvbiBuZXh0LiAgICAgXHJcbiAgICogQHJldHVybnMge0Z1bmN0aW9ufSBBbiBhc3luYyBmdW5jdGlvbiB3aGljaCB3aGVuIGFwcGxpZWQsIHJldHVybnMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aXRoIHRoZSBjYWxsYmFjayBhcmd1bWVudHMgYXMgYW4gYXJyYXkuXHJcbiAgICovXHJcbiAgZnJvbU5vZGVDYWxsYmFjazogZnVuY3Rpb24gKGZ1bmMsIHNjaGVkdWxlciwgY29udGV4dCwgc2VsZWN0b3IpIHtcclxuICAgIHJldHVybiBPYnNlcnZhYmxlLmZyb21Ob2RlQ2FsbGJhY2soZnVuYywgc2NoZWR1bGVyLCBjb250ZXh0LCBzZWxlY3Rvcik7XHJcbiAgfSxcclxuXHJcbiAgLyoqXHJcbiAgICogQGRlcHJlY2F0ZWQgVXNlIFJ4Lk9ic2VydmFibGUuZnJvbU5vZGVDYWxsYmFjayBmcm9tIHJ4LmFzeW5jLmpzIGluc3RlYWQuXHJcbiAgICogICAgXHJcbiAgICogSGFuZGxlcyBhbiBldmVudCBmcm9tIHRoZSBnaXZlbiBFdmVudEVtaXR0ZXIgYXMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgKlxyXG4gICAqIEBwYXJhbSB7RXZlbnRFbWl0dGVyfSBldmVudEVtaXR0ZXIgVGhlIEV2ZW50RW1pdHRlciB0byBzdWJzY3JpYmUgdG8gdGhlIGdpdmVuIGV2ZW50LlxyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUgdG8gc3Vic2NyaWJlXHJcbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gW3NlbGVjdG9yXSBBIHNlbGVjdG9yIHdoaWNoIHRha2VzIHRoZSBhcmd1bWVudHMgZnJvbSB0aGUgZXZlbnQgaGFuZGxlciB0byBwcm9kdWNlIGEgc2luZ2xlIGl0ZW0gdG8geWllbGQgb24gbmV4dC4gICAgIFxyXG4gICAqIEByZXR1cm5zIHtPYnNlcnZhYmxlfSBBbiBvYnNlcnZhYmxlIHNlcXVlbmNlIGdlbmVyYXRlZCBmcm9tIHRoZSBuYW1lZCBldmVudCBmcm9tIHRoZSBnaXZlbiBFdmVudEVtaXR0ZXIuICBUaGUgZGF0YSB3aWxsIGJlIHJldHVybmVkIGFzIGFuIGFycmF5IG9mIGFyZ3VtZW50cyB0byB0aGUgaGFuZGxlci5cclxuICAgKi9cclxuICBmcm9tRXZlbnQ6IGZ1bmN0aW9uIChldmVudEVtaXR0ZXIsIGV2ZW50TmFtZSwgc2VsZWN0b3IpIHtcclxuICAgIHJldHVybiBPYnNlcnZhYmxlLmZyb21FdmVudChldmVudEVtaXR0ZXIsIGV2ZW50TmFtZSwgc2VsZWN0b3IpO1xyXG4gIH0sXHJcblxyXG4gIC8qKlxyXG4gICAqIENvbnZlcnRzIHRoZSBnaXZlbiBvYnNlcnZhYmxlIHNlcXVlbmNlIHRvIGFuIGV2ZW50IGVtaXR0ZXIgd2l0aCB0aGUgZ2l2ZW4gZXZlbnQgbmFtZS4gXHJcbiAgICogVGhlIGVycm9ycyBhcmUgaGFuZGxlZCBvbiB0aGUgJ2Vycm9yJyBldmVudCBhbmQgY29tcGxldGlvbiBvbiB0aGUgJ2VuZCcgZXZlbnQuXHJcbiAgICogQHBhcmFtIHtPYnNlcnZhYmxlfSBvYnNlcnZhYmxlIFRoZSBvYnNlcnZhYmxlIHNlcXVlbmNlIHRvIGNvbnZlcnQgdG8gYW4gRXZlbnRFbWl0dGVyLlxyXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudE5hbWUgVGhlIGV2ZW50IG5hbWUgdG8gZW1pdCBvbk5leHQgY2FsbHMuXHJcbiAgICogQHJldHVybnMge0V2ZW50RW1pdHRlcn0gQW4gRXZlbnRFbWl0dGVyIHdoaWNoIGVtaXRzIHRoZSBnaXZlbiBldmVudE5hbWUgZm9yIGVhY2ggb25OZXh0IGNhbGwgaW4gYWRkaXRpb24gdG8gJ2Vycm9yJyBhbmQgJ2VuZCcgZXZlbnRzLiAgXHJcbiAgICogICBZb3UgbXVzdCBjYWxsIHB1Ymxpc2ggaW4gb3JkZXIgdG8gaW52b2tlIHRoZSBzdWJzY3JpcHRpb24gb24gdGhlIE9ic2VydmFibGUgc2VxdXVlbmNlLlxyXG4gICAqL1xyXG4gIHRvRXZlbnRFbWl0dGVyOiBmdW5jdGlvbiAob2JzZXJ2YWJsZSwgZXZlbnROYW1lLCBzZWxlY3Rvcikge1xyXG4gICAgdmFyIGUgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgICBzZWxlY3RvciB8fCAoc2VsZWN0b3IgPSBmdW5jdGlvbiAoeCkgeyByZXR1cm4geDsgfSk7XHJcblxyXG4gICAgLy8gVXNlZCB0byBwdWJsaXNoIHRoZSBldmVudHMgZnJvbSB0aGUgb2JzZXJ2YWJsZVxyXG4gICAgZS5wdWJsaXNoID0gZnVuY3Rpb24gKCkge1xyXG4gICAgICBlLnN1YnNjcmlwdGlvbiA9IG9ic2VydmFibGUuc3Vic2NyaWJlKFxyXG4gICAgICAgIGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgICBlLmVtaXQoZXZlbnROYW1lLCBzZWxlY3Rvcih4KSk7XHJcbiAgICAgICAgfSwgXHJcbiAgICAgICAgZnVuY3Rpb24gKGVycikge1xyXG4gICAgICAgICAgZS5lbWl0KCdlcnJvcicsIGVycik7XHJcbiAgICAgICAgfSxcclxuICAgICAgICBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgICBlLmVtaXQoJ2VuZCcpO1xyXG4gICAgICAgIH0pO1xyXG4gICAgfTtcclxuXHJcbiAgICByZXR1cm4gZTtcclxuICB9LFxyXG5cclxuICAvKipcclxuICAgKiBDb252ZXJ0cyBhIGZsb3dpbmcgc3RyZWFtIHRvIGFuIE9ic2VydmFibGUgc2VxdWVuY2UuXHJcbiAgICogQHBhcmFtIHtTdHJlYW19IHN0cmVhbSBBIHN0cmVhbSB0byBjb252ZXJ0IHRvIGEgb2JzZXJ2YWJsZSBzZXF1ZW5jZS5cclxuICAgKiBAcmV0dXJucyB7T2JzZXJ2YWJsZX0gQW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB3aGljaCBmaXJlcyBvbiBlYWNoICdkYXRhJyBldmVudCBhcyB3ZWxsIGFzIGhhbmRsaW5nICdlcnJvcicgYW5kICdlbmQnIGV2ZW50cy5cclxuICAgKi9cclxuICBmcm9tU3RyZWFtOiBmdW5jdGlvbiAoc3RyZWFtKSB7XHJcbiAgICByZXR1cm4gT2JzZXJ2YWJsZS5jcmVhdGUoZnVuY3Rpb24gKG9ic2VydmVyKSB7XHJcbiAgICAgIGZ1bmN0aW9uIGRhdGFIYW5kbGVyIChkYXRhKSB7XHJcbiAgICAgICAgb2JzZXJ2ZXIub25OZXh0KGRhdGEpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBmdW5jdGlvbiBlcnJvckhhbmRsZXIgKGVycikge1xyXG4gICAgICAgIG9ic2VydmVyLm9uRXJyb3IoZXJyKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgZnVuY3Rpb24gZW5kSGFuZGxlciAoKSB7XHJcbiAgICAgICAgb2JzZXJ2ZXIub25Db21wbGV0ZWQoKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgc3RyZWFtLmFkZExpc3RlbmVyKCdkYXRhJywgZGF0YUhhbmRsZXIpO1xyXG4gICAgICBzdHJlYW0uYWRkTGlzdGVuZXIoJ2Vycm9yJywgZXJyb3JIYW5kbGVyKTtcclxuICAgICAgc3RyZWFtLmFkZExpc3RlbmVyKCdlbmQnLCBlbmRIYW5kbGVyKTtcclxuICAgICAgXHJcbiAgICAgIHJldHVybiBmdW5jdGlvbiAoKSB7XHJcbiAgICAgICAgc3RyZWFtLnJlbW92ZUxpc3RlbmVyKCdkYXRhJywgZGF0YUhhbmRsZXIpO1xyXG4gICAgICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignZXJyb3InLCBlcnJvckhhbmRsZXIpO1xyXG4gICAgICAgIHN0cmVhbS5yZW1vdmVMaXN0ZW5lcignZW5kJywgZW5kSGFuZGxlcik7XHJcbiAgICAgIH07XHJcbiAgICB9KS5wdWJsaXNoKCkucmVmQ291bnQoKTtcclxuICB9LFxyXG5cclxuICAvKipcclxuICAgKiBXcml0ZXMgYW4gb2JzZXJ2YWJsZSBzZXF1ZW5jZSB0byBhIHN0cmVhbVxyXG4gICAqIEBwYXJhbSB7T2JzZXJ2YWJsZX0gb2JzZXJ2YWJsZSBPYnNlcnZhYmxlIHNlcXVlbmNlIHRvIHdyaXRlIHRvIGEgc3RyZWFtLlxyXG4gICAqIEBwYXJhbSB7U3RyZWFtfSBzdHJlYW0gVGhlIHN0cmVhbSB0byB3cml0ZSB0by5cclxuICAgKiBAcGFyYW0ge1N0cmluZ30gW2VuY29kaW5nXSBUaGUgZW5jb2Rpbmcgb2YgdGhlIGl0ZW0gdG8gd3JpdGUuXHJcbiAgICogQHJldHVybnMge0Rpc3Bvc2FibGV9IFRoZSBzdWJzY3JpcHRpb24gaGFuZGxlLlxyXG4gICAqL1xyXG4gIHdyaXRlVG9TdHJlYW06IGZ1bmN0aW9uIChvYnNlcnZhYmxlLCBzdHJlYW0sIGVuY29kaW5nKSB7XHJcbiAgICByZXR1cm4gb2JzZXJ2YWJsZS5zdWJzY3JpYmUoXHJcbiAgICAgIGZ1bmN0aW9uICh4KSB7XHJcbiAgICAgICAgc3RyZWFtLndyaXRlKFN0cmluZyh4KSwgZW5jb2RpbmcpO1xyXG4gICAgICB9LFxyXG4gICAgICBmdW5jdGlvbiAoZXJyKSB7XHJcbiAgICAgICAgc3RyZWFtLmVtaXQoJ2Vycm9yJywgZXJyKTtcclxuICAgICAgfSwgZnVuY3Rpb24gKCkge1xyXG4gICAgICAgIC8vIEhhY2sgY2hlY2sgYmVjYXVzZSBTVERJTyBpcyBub3QgY2xvc2FibGVcclxuICAgICAgICAhc3RyZWFtLl9pc1N0ZGlvICYmIHN0cmVhbS5lbmQoKTtcclxuICAgICAgfSk7XHJcbiAgfVxyXG59O1xyXG5cclxubW9kdWxlLmV4cG9ydHMgPSBSeDtcbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4L3J4Lm5vZGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgRXhhbXBsZXMsIFJ4LCBTYW5kYm94LCBTZWxlY3RlZEV4YW1wbGUsIFV0aWxzLCBhcnJheU9mSW5pdGlhbElucHV0RGlhZ3JhbXMkLCBjb250aW51b3VzJDtcblxuUnggPSByZXF1aXJlKCdyeCcpO1xuXG5FeGFtcGxlcyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9tb2RlbHMvZXhhbXBsZXMnKTtcblxuU2VsZWN0ZWRFeGFtcGxlID0gcmVxdWlyZSgncnhtYXJibGVzL2NvbnRyb2xsZXJzL3NlbGVjdGVkLWV4YW1wbGUnKTtcblxuVXRpbHMgPSByZXF1aXJlKCdyeG1hcmJsZXMvY29udHJvbGxlcnMvdXRpbHMnKTtcblxuU2FuZGJveCA9IHJlcXVpcmUoJ3J4bWFyYmxlcy92aWV3cy9zYW5kYm94Jyk7XG5cbmFycmF5T2ZJbml0aWFsSW5wdXREaWFncmFtcyQgPSBuZXcgUnguQmVoYXZpb3JTdWJqZWN0KG51bGwpO1xuXG5TZWxlY3RlZEV4YW1wbGUuc3RyZWFtLm1hcChmdW5jdGlvbihleGFtcGxlKSB7XG4gIHJldHVybiBleGFtcGxlW1wiaW5wdXRzXCJdLm1hcChVdGlscy5wcmVwYXJlSW5wdXREaWFncmFtKTtcbn0pLnN1YnNjcmliZShmdW5jdGlvbih4KSB7XG4gIGFycmF5T2ZJbml0aWFsSW5wdXREaWFncmFtcyQub25OZXh0KHgpO1xuICByZXR1cm4gdHJ1ZTtcbn0pO1xuXG5jb250aW51b3VzJCA9IFNhbmRib3guZ2V0U3RyZWFtT2ZBcnJheU9mTGl2ZUlucHV0RGlhZ3JhbVN0cmVhbXMoKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGluaXRpYWwkOiBhcnJheU9mSW5pdGlhbElucHV0RGlhZ3JhbXMkLFxuICBjb250aW51b3VzJDogY29udGludW91cyRcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy9jb250cm9sbGVycy9pbnB1dC1kaWFncmFtcy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvY29udHJvbGxlcnNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgRU5ELCBFeGFtcGxlcywgSW5wdXREaWFncmFtcywgUngsIFNlbGVjdGVkRXhhbXBsZSwgVXRpbHMsIG91dHB1dERpYWdyYW1TdHJlYW0sXG4gIF9fc2xpY2UgPSBbXS5zbGljZTtcblxuUnggPSByZXF1aXJlKCdyeCcpO1xuXG5VdGlscyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9jb250cm9sbGVycy91dGlscycpO1xuXG5JbnB1dERpYWdyYW1zID0gcmVxdWlyZSgncnhtYXJibGVzL2NvbnRyb2xsZXJzL2lucHV0LWRpYWdyYW1zJyk7XG5cblNlbGVjdGVkRXhhbXBsZSA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9jb250cm9sbGVycy9zZWxlY3RlZC1leGFtcGxlJyk7XG5cbkV4YW1wbGVzID0gcmVxdWlyZSgncnhtYXJibGVzL21vZGVscy9leGFtcGxlcycpO1xuXG5FTkQgPSAxMDA7XG5cbm91dHB1dERpYWdyYW1TdHJlYW0gPSBJbnB1dERpYWdyYW1zLmNvbnRpbnVvdXMkLmZpbHRlcihmdW5jdGlvbih4KSB7XG4gIHJldHVybiB4ICE9PSBudWxsO1xufSkuZmxhdE1hcExhdGVzdChmdW5jdGlvbihhcnJheU9mRGlhZ3JhbVN0cmVhbXMpIHtcbiAgcmV0dXJuIFJ4Lk9ic2VydmFibGUuY29tYmluZUxhdGVzdChhcnJheU9mRGlhZ3JhbVN0cmVhbXMsIGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmdzO1xuICAgIGFyZ3MgPSAxIDw9IGFyZ3VtZW50cy5sZW5ndGggPyBfX3NsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSA6IFtdO1xuICAgIHJldHVybiBhcmdzO1xuICB9KTtcbn0pLmNvbWJpbmVMYXRlc3QoU2VsZWN0ZWRFeGFtcGxlLnN0cmVhbSwgZnVuY3Rpb24oZGlhZ3JhbXMsIGV4YW1wbGUpIHtcbiAgdmFyIGQsIGVuZFRpbWUsIGlucHV0VlRTdHJlYW1zLCBvdXRwdXREaWFncmFtLCBvdXRwdXRWVFN0cmVhbSwgdnRzY2hlZHVsZXI7XG4gIGVuZFRpbWUgPSBFTkQgKyAxO1xuICB2dHNjaGVkdWxlciA9IFV0aWxzLm1ha2VTY2hlZHVsZXIoKTtcbiAgaW5wdXRWVFN0cmVhbXMgPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIF9pLCBfbGVuLCBfcmVzdWx0cztcbiAgICBfcmVzdWx0cyA9IFtdO1xuICAgIGZvciAoX2kgPSAwLCBfbGVuID0gZGlhZ3JhbXMubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgIGQgPSBkaWFncmFtc1tfaV07XG4gICAgICBfcmVzdWx0cy5wdXNoKFV0aWxzLnRvVlRTdHJlYW0oZCwgdnRzY2hlZHVsZXIsIGVuZFRpbWUpKTtcbiAgICB9XG4gICAgcmV0dXJuIF9yZXN1bHRzO1xuICB9KSgpO1xuICBvdXRwdXRWVFN0cmVhbSA9IGV4YW1wbGVbXCJhcHBseVwiXShpbnB1dFZUU3RyZWFtcywgdnRzY2hlZHVsZXIpO1xuICBvdXRwdXRWVFN0cmVhbSA9IG91dHB1dFZUU3RyZWFtLnRha2VVbnRpbFdpdGhUaW1lKGVuZFRpbWUsIHZ0c2NoZWR1bGVyKTtcbiAgb3V0cHV0RGlhZ3JhbSA9IFV0aWxzLmdldERpYWdyYW1Qcm9taXNlKG91dHB1dFZUU3RyZWFtLCB2dHNjaGVkdWxlciwgZW5kVGltZSk7XG4gIHZ0c2NoZWR1bGVyLnN0YXJ0KCk7XG4gIHJldHVybiBvdXRwdXREaWFncmFtO1xufSkubWVyZ2VBbGwoKTtcblxubW9kdWxlLmV4cG9ydHMgPSBvdXRwdXREaWFncmFtU3RyZWFtO1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvY29udHJvbGxlcnMvb3V0cHV0LWRpYWdyYW0uanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL2NvbnRyb2xsZXJzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIEV4YW1wbGVzLCBPcGVyYXRvcnNNZW51LCBSeCwgc2VsZWN0ZWRFeGFtcGxlJCwgc2VsZWN0ZWRFeGFtcGxlS2V5JCwgdXJsSGFzaDtcblxuUnggPSByZXF1aXJlKCdyeCcpO1xuXG5FeGFtcGxlcyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9tb2RlbHMvZXhhbXBsZXMnKTtcblxuT3BlcmF0b3JzTWVudSA9IHJlcXVpcmUoJ3J4bWFyYmxlcy92aWV3cy9vcGVyYXRvcnMtbWVudScpO1xuXG51cmxIYXNoID0gd2luZG93LmxvY2F0aW9uLmhhc2gucmVwbGFjZShcIiNcIiwgXCJcIikgfHwgXCJtZXJnZVwiO1xuXG5zZWxlY3RlZEV4YW1wbGVLZXkkID0gT3BlcmF0b3JzTWVudS5nZXRTZWxlY3RlZCQoKS5zdGFydFdpdGgodXJsSGFzaCk7XG5cbnNlbGVjdGVkRXhhbXBsZSQgPSBzZWxlY3RlZEV4YW1wbGVLZXkkLm1hcChmdW5jdGlvbihrZXkpIHtcbiAgdmFyIGV4YW1wbGU7XG4gIGV4YW1wbGUgPSBFeGFtcGxlc1trZXldO1xuICBleGFtcGxlLmtleSA9IGtleTtcbiAgcmV0dXJuIGV4YW1wbGU7XG59KTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHN0cmVhbTogc2VsZWN0ZWRFeGFtcGxlJFxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL2NvbnRyb2xsZXJzL3NlbGVjdGVkLWV4YW1wbGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL2NvbnRyb2xsZXJzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIFJ4LCBjYWxjdWxhdGVNYXJibGVDb250ZW50SGFzaCwgY2FsY3VsYXRlTWFyYmxlRGF0YUhhc2gsIGdldERpYWdyYW1Qcm9taXNlLCBtYWtlU2NoZWR1bGVyLCBwcmVwYXJlSW5wdXREaWFncmFtLCBwcmVwYXJlSW5wdXREaWFncmFtSXRlbSwgcHJlcGFyZUlucHV0RGlhZ3JhbVN0cmVhbSwgdG9WVFN0cmVhbTtcblxuUnggPSByZXF1aXJlKCdyeCcpO1xuXG5tYWtlU2NoZWR1bGVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzY2hlZHVsZXI7XG4gIHNjaGVkdWxlciA9IG5ldyBSeC5WaXJ0dWFsVGltZVNjaGVkdWxlcigwLCBmdW5jdGlvbih4LCB5KSB7XG4gICAgaWYgKHggPiB5KSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gICAgaWYgKHggPCB5KSB7XG4gICAgICByZXR1cm4gLTE7XG4gICAgfVxuICAgIHJldHVybiAwO1xuICB9KTtcbiAgc2NoZWR1bGVyLmFkZCA9IGZ1bmN0aW9uKGFic29sdXRlLCByZWxhdGl2ZSkge1xuICAgIHJldHVybiBhYnNvbHV0ZSArIHJlbGF0aXZlO1xuICB9O1xuICBzY2hlZHVsZXIudG9EYXRlVGltZU9mZnNldCA9IGZ1bmN0aW9uKGFic29sdXRlKSB7XG4gICAgcmV0dXJuIE1hdGguZmxvb3IoYWJzb2x1dGUpO1xuICB9O1xuICBzY2hlZHVsZXIudG9SZWxhdGl2ZSA9IGZ1bmN0aW9uKHRpbWVTcGFuKSB7XG4gICAgcmV0dXJuIHRpbWVTcGFuO1xuICB9O1xuICByZXR1cm4gc2NoZWR1bGVyO1xufTtcblxuY2FsY3VsYXRlTWFyYmxlQ29udGVudEhhc2ggPSBmdW5jdGlvbihjb250ZW50KSB7XG4gIHZhciBTT01FX1BSSU1FX05VTUJFUiwgY29udGVudEhhc2g7XG4gIFNPTUVfUFJJTUVfTlVNQkVSID0gODc3O1xuICBjb250ZW50SGFzaCA9IDA7XG4gIGlmICh0eXBlb2YgY29udGVudCA9PT0gXCJzdHJpbmdcIikge1xuICAgIGNvbnRlbnRIYXNoID0gY29udGVudC5zcGxpdChcIlwiKS5tYXAoZnVuY3Rpb24oeCkge1xuICAgICAgcmV0dXJuIHguY2hhckNvZGVBdCgwKTtcbiAgICB9KS5yZWR1Y2UoZnVuY3Rpb24oeCwgeSkge1xuICAgICAgcmV0dXJuIHggKyB5O1xuICAgIH0pO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBjb250ZW50ID09PSBcIm51bWJlclwiKSB7XG4gICAgY29udGVudEhhc2ggPSBjb250ZW50ICogU09NRV9QUklNRV9OVU1CRVI7XG4gIH1cbiAgcmV0dXJuIGNvbnRlbnRIYXNoO1xufTtcblxuY2FsY3VsYXRlTWFyYmxlRGF0YUhhc2ggPSBmdW5jdGlvbihtYXJibGVEYXRhKSB7XG4gIHZhciBMQVJHRV9QUklNRSwgTUFYLCBTTUFMTF9QUklNRSwgY29udGVudEhhc2g7XG4gIFNNQUxMX1BSSU1FID0gNztcbiAgTEFSR0VfUFJJTUUgPSAxMDQ2NTI3O1xuICBNQVggPSAxMDAwMDA7XG4gIGNvbnRlbnRIYXNoID0gY2FsY3VsYXRlTWFyYmxlQ29udGVudEhhc2gobWFyYmxlRGF0YS5jb250ZW50KTtcbiAgcmV0dXJuICgobWFyYmxlRGF0YS50aW1lICsgY29udGVudEhhc2ggKyBTTUFMTF9QUklNRSkgKiBMQVJHRV9QUklNRSkgJSBNQVg7XG59O1xuXG5wcmVwYXJlSW5wdXREaWFncmFtSXRlbSA9IGZ1bmN0aW9uKGl0ZW0pIHtcbiAgdmFyIHJlc3VsdDtcbiAgcmVzdWx0ID0ge307XG4gIHJlc3VsdC50aW1lID0gdHlwZW9mIGl0ZW0udGltZSA9PT0gXCJ1bmRlZmluZWRcIiA/IGl0ZW0udCA6IGl0ZW0udGltZTtcbiAgcmVzdWx0LmNvbnRlbnQgPSB0eXBlb2YgaXRlbS5jb250ZW50ID09PSBcInVuZGVmaW5lZFwiID8gaXRlbS5kIDogaXRlbS5jb250ZW50O1xuICByZXN1bHQuaWQgPSBpdGVtLmlkICE9IG51bGwgPyBpdGVtLmlkIDogY2FsY3VsYXRlTWFyYmxlRGF0YUhhc2gocmVzdWx0KTtcbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbnByZXBhcmVJbnB1dERpYWdyYW0gPSBmdW5jdGlvbihkaWFncmFtKSB7XG4gIHZhciBpO1xuICByZXR1cm4gKGZ1bmN0aW9uKCkge1xuICAgIHZhciBfaSwgX2xlbiwgX3Jlc3VsdHM7XG4gICAgX3Jlc3VsdHMgPSBbXTtcbiAgICBmb3IgKF9pID0gMCwgX2xlbiA9IGRpYWdyYW0ubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgIGkgPSBkaWFncmFtW19pXTtcbiAgICAgIF9yZXN1bHRzLnB1c2gocHJlcGFyZUlucHV0RGlhZ3JhbUl0ZW0oaSkpO1xuICAgIH1cbiAgICByZXR1cm4gX3Jlc3VsdHM7XG4gIH0pKCk7XG59O1xuXG5wcmVwYXJlSW5wdXREaWFncmFtU3RyZWFtID0gZnVuY3Rpb24oZGlhZ3JhbVN0cmVhbSkge1xuICByZXR1cm4gZGlhZ3JhbVN0cmVhbS5tYXAocHJlcGFyZUlucHV0RGlhZ3JhbSk7XG59O1xuXG50b1ZUU3RyZWFtID0gZnVuY3Rpb24oZGlhZ3JhbURhdGEsIHNjaGVkdWxlciwgZW5kVGltZSkge1xuICB2YXIgaXRlbSwgc2luZ2xlTWFyYmxlU3RyZWFtcywgX2ksIF9sZW47XG4gIHNpbmdsZU1hcmJsZVN0cmVhbXMgPSBbXTtcbiAgZm9yIChfaSA9IDAsIF9sZW4gPSBkaWFncmFtRGF0YS5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgIGl0ZW0gPSBkaWFncmFtRGF0YVtfaV07XG4gICAgc2luZ2xlTWFyYmxlU3RyZWFtcy5wdXNoKFJ4Lk9ic2VydmFibGUuanVzdChpdGVtLCBzY2hlZHVsZXIpLmRlbGF5KGl0ZW0udCB8fCBpdGVtLnRpbWUsIHNjaGVkdWxlcikpO1xuICB9XG4gIHJldHVybiBSeC5PYnNlcnZhYmxlLm1lcmdlKHNpbmdsZU1hcmJsZVN0cmVhbXMpLnRha2VVbnRpbFdpdGhUaW1lKGVuZFRpbWUsIHNjaGVkdWxlcikucHVibGlzaCgpLnJlZkNvdW50KCk7XG59O1xuXG5nZXREaWFncmFtUHJvbWlzZSA9IGZ1bmN0aW9uKHN0cmVhbSwgc2NoZWR1bGVyLCBlbmRUaW1lKSB7XG4gIHZhciBzdWJqZWN0O1xuICBzdWJqZWN0ID0gbmV3IFJ4LkJlaGF2aW9yU3ViamVjdChbXSk7XG4gIHN0cmVhbS5vYnNlcnZlT24oc2NoZWR1bGVyKS50aW1lc3RhbXAoc2NoZWR1bGVyKS5tYXAoZnVuY3Rpb24oeCkge1xuICAgIGlmICh0eXBlb2YgeC52YWx1ZSAhPT0gXCJvYmplY3RcIikge1xuICAgICAgeC52YWx1ZSA9IHtcbiAgICAgICAgY29udGVudDogeC52YWx1ZSxcbiAgICAgICAgaWQ6IGNhbGN1bGF0ZU1hcmJsZUNvbnRlbnRIYXNoKHgudmFsdWUpXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4ge1xuICAgICAgdGltZTogKHgudGltZXN0YW1wIC8gZW5kVGltZSkgKiAxMDAsXG4gICAgICBjb250ZW50OiB4LnZhbHVlLmNvbnRlbnQsXG4gICAgICBpZDogeC52YWx1ZS5pZFxuICAgIH07XG4gIH0pLnJlZHVjZShmdW5jdGlvbihhY2MsIHgpIHtcbiAgICBhY2MucHVzaCh4KTtcbiAgICByZXR1cm4gYWNjO1xuICB9LCBbXSkuc3Vic2NyaWJlKGZ1bmN0aW9uKHgpIHtcbiAgICBzdWJqZWN0Lm9uTmV4dCh4KTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSwgZnVuY3Rpb24oKSB7XG4gICAgY29uc29sZS53YXJuKFwiRXJyb3IgaW4gdGhlIGRpYWdyYW0gcHJvbWlzZSBzdHJlYW1cIik7XG4gICAgcmV0dXJuIDA7XG4gIH0pO1xuICByZXR1cm4gc3ViamVjdC5hc09ic2VydmFibGUoKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBtYWtlU2NoZWR1bGVyOiBtYWtlU2NoZWR1bGVyLFxuICB0b1ZUU3RyZWFtOiB0b1ZUU3RyZWFtLFxuICBwcmVwYXJlSW5wdXREaWFncmFtU3RyZWFtOiBwcmVwYXJlSW5wdXREaWFncmFtU3RyZWFtLFxuICBwcmVwYXJlSW5wdXREaWFncmFtOiBwcmVwYXJlSW5wdXREaWFncmFtLFxuICBnZXREaWFncmFtUHJvbWlzZTogZ2V0RGlhZ3JhbVByb21pc2Vcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy9jb250cm9sbGVycy91dGlscy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvY29udHJvbGxlcnNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgUng7XG5cblJ4ID0gcmVxdWlyZSgncngnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIFwiYWxsXCI6IHtcbiAgICBcImxhYmVsXCI6IFwiYWxsKHggPT4geCA8IDEwKVwiLFxuICAgIFwiaW5wdXRzXCI6IFtcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIHQ6IDUsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMTUsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMjUsXG4gICAgICAgICAgZDogM1xuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMzUsXG4gICAgICAgICAgZDogNFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNjUsXG4gICAgICAgICAgZDogNVxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIGlucHV0c1swXS5hbGwoZnVuY3Rpb24oeCkge1xuICAgICAgICByZXR1cm4geC5jb250ZW50IDwgMTA7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG4gIFwiYW55XCI6IHtcbiAgICBcImxhYmVsXCI6IFwiYW55KHggPT4geCA+IDEwKVwiLFxuICAgIFwiaW5wdXRzXCI6IFtcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIHQ6IDUsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMTUsXG4gICAgICAgICAgZDogMzBcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDI1LFxuICAgICAgICAgIGQ6IDIyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAzNSxcbiAgICAgICAgICBkOiA1XG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA0NSxcbiAgICAgICAgICBkOiA2MFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNTUsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIGlucHV0c1swXS5hbnkoZnVuY3Rpb24oeCkge1xuICAgICAgICByZXR1cm4geC5jb250ZW50ID4gMTA7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG4gIFwiY29udGFpbnNcIjoge1xuICAgIFwibGFiZWxcIjogXCJjb250YWlucygyMilcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiA1LFxuICAgICAgICAgIGQ6IDJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDE1LFxuICAgICAgICAgIGQ6IDMwXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAyNSxcbiAgICAgICAgICBkOiAyMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMzUsXG4gICAgICAgICAgZDogNVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNDUsXG4gICAgICAgICAgZDogNjBcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDU1LFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfVxuICAgICAgXVxuICAgIF0sXG4gICAgXCJhcHBseVwiOiBmdW5jdGlvbihpbnB1dHMpIHtcbiAgICAgIHJldHVybiBpbnB1dHNbMF0uY29udGFpbnMoe1xuICAgICAgICBjb250ZW50OiAyMlxuICAgICAgfSwgZnVuY3Rpb24oeCwgeSkge1xuICAgICAgICByZXR1cm4geC5jb250ZW50ID09PSB5LmNvbnRlbnQ7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy9tb2RlbHMvYm9vbGVhbi1leGFtcGxlcy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvbW9kZWxzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIFJ4O1xuXG5SeCA9IHJlcXVpcmUoJ3J4Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBcImNvbWJpbmVMYXRlc3RcIjoge1xuICAgIFwibGFiZWxcIjogXCJjb21iaW5lTGF0ZXN0KCh4LCB5KSA9PiBcXFwiXFxcIiArIHggKyB5KVwiLFxuICAgIFwiaW5wdXRzXCI6IFtcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIHQ6IDAsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMjAsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNjUsXG4gICAgICAgICAgZDogM1xuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNzUsXG4gICAgICAgICAgZDogNFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogOTIsXG4gICAgICAgICAgZDogNVxuICAgICAgICB9XG4gICAgICBdLCBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAxMCxcbiAgICAgICAgICBkOiBcIkFcIlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMjUsXG4gICAgICAgICAgZDogXCJCXCJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDUwLFxuICAgICAgICAgIGQ6IFwiQ1wiXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA1NyxcbiAgICAgICAgICBkOiBcIkRcIlxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIFJ4Lk9ic2VydmFibGUuY29tYmluZUxhdGVzdChpbnB1dHNbMF0sIGlucHV0c1sxXSwgZnVuY3Rpb24oeCwgeSkge1xuICAgICAgICByZXR1cm4gXCJcIiArIHguY29udGVudCArIHkuY29udGVudDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbiAgXCJjb25jYXRcIjoge1xuICAgIFwibGFiZWxcIjogXCJjb25jYXRcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAwLFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDE1LFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDUwLFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfVxuICAgICAgXSwgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogMTMsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMzAsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIFJ4Lk9ic2VydmFibGUuY29uY2F0KGlucHV0cyk7XG4gICAgfVxuICB9LFxuICBcIm1lcmdlXCI6IHtcbiAgICBcImxhYmVsXCI6IFwibWVyZ2VcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAwLFxuICAgICAgICAgIGQ6IDIwXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAxNSxcbiAgICAgICAgICBkOiA0MFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMzAsXG4gICAgICAgICAgZDogNjBcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDQ1LFxuICAgICAgICAgIGQ6IDgwXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA2MCxcbiAgICAgICAgICBkOiAxMDBcbiAgICAgICAgfVxuICAgICAgXSwgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogMzcsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNjgsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIFJ4Lk9ic2VydmFibGUubWVyZ2UoaW5wdXRzKTtcbiAgICB9XG4gIH0sXG4gIFwic2FtcGxlXCI6IHtcbiAgICBcImxhYmVsXCI6IFwic2FtcGxlXCIsXG4gICAgXCJpbnB1dHNcIjogW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogMCxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAyMCxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA0MCxcbiAgICAgICAgICBkOiAzXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA2MCxcbiAgICAgICAgICBkOiA0XG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA4MCxcbiAgICAgICAgICBkOiA1XG4gICAgICAgIH1cbiAgICAgIF0sIFtcbiAgICAgICAge1xuICAgICAgICAgIHQ6IDEwLFxuICAgICAgICAgIGQ6IFwiQVwiXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAyNSxcbiAgICAgICAgICBkOiBcIkJcIlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMzMsXG4gICAgICAgICAgZDogXCJDXCJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDcwLFxuICAgICAgICAgIGQ6IFwiRFwiXG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgICByZXR1cm4gaW5wdXRzWzBdLnNhbXBsZShpbnB1dHNbMV0pO1xuICAgIH1cbiAgfSxcbiAgXCJzdGFydFdpdGhcIjoge1xuICAgIFwibGFiZWxcIjogXCJzdGFydFdpdGgoMSlcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAzMCxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA0MCxcbiAgICAgICAgICBkOiAzXG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzLCBzY2hlZHVsZXIpIHtcbiAgICAgIHJldHVybiBpbnB1dHNbMF0uc3RhcnRXaXRoKHNjaGVkdWxlciwgMSk7XG4gICAgfVxuICB9LFxuICBcInppcFwiOiB7XG4gICAgXCJsYWJlbFwiOiBcInppcFwiLFxuICAgIFwiaW5wdXRzXCI6IFtcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIHQ6IDAsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMjAsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNjUsXG4gICAgICAgICAgZDogM1xuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNzUsXG4gICAgICAgICAgZDogNFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogOTIsXG4gICAgICAgICAgZDogNVxuICAgICAgICB9XG4gICAgICBdLCBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAxMCxcbiAgICAgICAgICBkOiBcIkFcIlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMjUsXG4gICAgICAgICAgZDogXCJCXCJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDUwLFxuICAgICAgICAgIGQ6IFwiQ1wiXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA1NyxcbiAgICAgICAgICBkOiBcIkRcIlxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIFJ4Lk9ic2VydmFibGUuemlwKGlucHV0c1swXSwgaW5wdXRzWzFdLCBmdW5jdGlvbih4LCB5KSB7XG4gICAgICAgIHJldHVybiBcIlwiICsgeC5jb250ZW50ICsgeS5jb250ZW50O1xuICAgICAgfSk7XG4gICAgfVxuICB9XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvbW9kZWxzL2NvbWJpbmUtZXhhbXBsZXMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL21vZGVsc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBSeDtcblxuUnggPSByZXF1aXJlKCdyeCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgXCJhbWJcIjoge1xuICAgIFwibGFiZWxcIjogXCJhbWJcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAxMCxcbiAgICAgICAgICBkOiAyMFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMjAsXG4gICAgICAgICAgZDogNDBcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDMwLFxuICAgICAgICAgIGQ6IDYwXG4gICAgICAgIH1cbiAgICAgIF0sIFtcbiAgICAgICAge1xuICAgICAgICAgIHQ6IDUsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMTUsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMjUsXG4gICAgICAgICAgZDogM1xuICAgICAgICB9XG4gICAgICBdLCBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAyMCxcbiAgICAgICAgICBkOiAwXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAzMixcbiAgICAgICAgICBkOiAwXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA0NCxcbiAgICAgICAgICBkOiAwXG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgICByZXR1cm4gUnguT2JzZXJ2YWJsZS5hbWIoaW5wdXRzKTtcbiAgICB9XG4gIH1cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy9tb2RlbHMvY29uZGl0aW9uYWwtZXhhbXBsZXMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL21vZGVsc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBSeCwgYXBwbHlDYXRlZ29yeSwgYm9vbGVhbkV4YW1wbGVzLCBjb21iaW5lRXhhbXBsZXMsIGNvbmRpdGlvbmFsRXhhbXBsZXMsIGZpbHRlckV4YW1wbGVzLCBtYXRoRXhhbXBsZXMsIG1lcmdlLCB0cmFuc2Zvcm1FeGFtcGxlcyxcbiAgX19zbGljZSA9IFtdLnNsaWNlLFxuICBfX2hhc1Byb3AgPSB7fS5oYXNPd25Qcm9wZXJ0eTtcblxuUnggPSByZXF1aXJlKCdyeCcpO1xuXG50cmFuc2Zvcm1FeGFtcGxlcyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9tb2RlbHMvdHJhbnNmb3JtLWV4YW1wbGVzJyk7XG5cbmNvbWJpbmVFeGFtcGxlcyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9tb2RlbHMvY29tYmluZS1leGFtcGxlcycpO1xuXG5maWx0ZXJFeGFtcGxlcyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9tb2RlbHMvZmlsdGVyLWV4YW1wbGVzJyk7XG5cbm1hdGhFeGFtcGxlcyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9tb2RlbHMvbWF0aC1leGFtcGxlcycpO1xuXG5ib29sZWFuRXhhbXBsZXMgPSByZXF1aXJlKCdyeG1hcmJsZXMvbW9kZWxzL2Jvb2xlYW4tZXhhbXBsZXMnKTtcblxuY29uZGl0aW9uYWxFeGFtcGxlcyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9tb2RlbHMvY29uZGl0aW9uYWwtZXhhbXBsZXMnKTtcblxubWVyZ2UgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGFyZ3MsIG5hbWUsIG9iamVjdCwgcmVzdWx0LCB2YWx1ZSwgX2ksIF9sZW47XG4gIGFyZ3MgPSAxIDw9IGFyZ3VtZW50cy5sZW5ndGggPyBfX3NsaWNlLmNhbGwoYXJndW1lbnRzLCAwKSA6IFtdO1xuICByZXN1bHQgPSB7fTtcbiAgZm9yIChfaSA9IDAsIF9sZW4gPSBhcmdzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgb2JqZWN0ID0gYXJnc1tfaV07XG4gICAgZm9yIChuYW1lIGluIG9iamVjdCkge1xuICAgICAgaWYgKCFfX2hhc1Byb3AuY2FsbChvYmplY3QsIG5hbWUpKSBjb250aW51ZTtcbiAgICAgIHZhbHVlID0gb2JqZWN0W25hbWVdO1xuICAgICAgcmVzdWx0W25hbWVdID0gb2JqZWN0W25hbWVdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufTtcblxuYXBwbHlDYXRlZ29yeSA9IGZ1bmN0aW9uKGV4YW1wbGVzLCBjYXRlZ29yeU5hbWUpIHtcbiAgdmFyIGtleSwgdmFsdWU7XG4gIGZvciAoa2V5IGluIGV4YW1wbGVzKSB7XG4gICAgaWYgKCFfX2hhc1Byb3AuY2FsbChleGFtcGxlcywga2V5KSkgY29udGludWU7XG4gICAgdmFsdWUgPSBleGFtcGxlc1trZXldO1xuICAgIGV4YW1wbGVzW2tleV1bXCJjYXRlZ29yeVwiXSA9IGNhdGVnb3J5TmFtZTtcbiAgfVxuICByZXR1cm4gZXhhbXBsZXM7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IG1lcmdlKGFwcGx5Q2F0ZWdvcnkodHJhbnNmb3JtRXhhbXBsZXMsIFwiVHJhbnNmb3JtaW5nIE9wZXJhdG9yc1wiKSwgYXBwbHlDYXRlZ29yeShjb21iaW5lRXhhbXBsZXMsIFwiQ29tYmluaW5nIE9wZXJhdG9yc1wiKSwgYXBwbHlDYXRlZ29yeShmaWx0ZXJFeGFtcGxlcywgXCJGaWx0ZXJpbmcgT3BlcmF0b3JzXCIpLCBhcHBseUNhdGVnb3J5KG1hdGhFeGFtcGxlcywgXCJNYXRoZW1hdGljYWwgT3BlcmF0b3JzXCIpLCBhcHBseUNhdGVnb3J5KGJvb2xlYW5FeGFtcGxlcywgXCJCb29sZWFuIE9wZXJhdG9yc1wiKSwgYXBwbHlDYXRlZ29yeShjb25kaXRpb25hbEV4YW1wbGVzLCBcIkNvbmRpdGlvbmFsIE9wZXJhdG9yc1wiKSk7XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy9tb2RlbHMvZXhhbXBsZXMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL21vZGVsc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBSeDtcblxuUnggPSByZXF1aXJlKCdyeCcpO1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgXCJkaXN0aW5jdFwiOiB7XG4gICAgXCJsYWJlbFwiOiBcImRpc3RpbmN0XCIsXG4gICAgXCJpbnB1dHNcIjogW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogNSxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAyMCxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAzNSxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA2MCxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA3MCxcbiAgICAgICAgICBkOiAzXG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgICByZXR1cm4gaW5wdXRzWzBdLmRpc3RpbmN0KGZ1bmN0aW9uKHgpIHtcbiAgICAgICAgcmV0dXJuIHguY29udGVudDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbiAgXCJkaXN0aW5jdFVudGlsQ2hhbmdlZFwiOiB7XG4gICAgXCJsYWJlbFwiOiBcImRpc3RpbmN0VW50aWxDaGFuZ2VkXCIsXG4gICAgXCJpbnB1dHNcIjogW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogNSxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAyMCxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAzNSxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA2MCxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA3MCxcbiAgICAgICAgICBkOiAzXG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgICByZXR1cm4gaW5wdXRzWzBdLmRpc3RpbmN0VW50aWxDaGFuZ2VkKGZ1bmN0aW9uKHgpIHtcbiAgICAgICAgcmV0dXJuIHguY29udGVudDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbiAgXCJlbGVtZW50QXRcIjoge1xuICAgIFwibGFiZWxcIjogXCJlbGVtZW50QXQoMilcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAzMCxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA0MCxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA2NSxcbiAgICAgICAgICBkOiAzXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA3NSxcbiAgICAgICAgICBkOiA0XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzLCBzY2hlZHVsZXIpIHtcbiAgICAgIHJldHVybiBpbnB1dHNbMF0uZWxlbWVudEF0KDIpO1xuICAgIH1cbiAgfSxcbiAgXCJmaWx0ZXJcIjoge1xuICAgIFwibGFiZWxcIjogXCJmaWx0ZXIoeCA9PiB4ID4gMTApXCIsXG4gICAgXCJpbnB1dHNcIjogW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogNSxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAxNSxcbiAgICAgICAgICBkOiAzMFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMjUsXG4gICAgICAgICAgZDogMjJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDM1LFxuICAgICAgICAgIGQ6IDVcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDQ1LFxuICAgICAgICAgIGQ6IDYwXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA1NSxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgICByZXR1cm4gaW5wdXRzWzBdLmZpbHRlcihmdW5jdGlvbih4KSB7XG4gICAgICAgIHJldHVybiB4LmNvbnRlbnQgPiAxMDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbiAgXCJmaW5kXCI6IHtcbiAgICBcImxhYmVsXCI6IFwiZmluZCh4ID0+IHggPiAxMClcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiA1LFxuICAgICAgICAgIGQ6IDJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDE1LFxuICAgICAgICAgIGQ6IDMwXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAyNSxcbiAgICAgICAgICBkOiAyMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMzUsXG4gICAgICAgICAgZDogNVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNDUsXG4gICAgICAgICAgZDogNjBcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDU1LFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfVxuICAgICAgXVxuICAgIF0sXG4gICAgXCJhcHBseVwiOiBmdW5jdGlvbihpbnB1dHMsIHNjaGVkdWxlcikge1xuICAgICAgcmV0dXJuIGlucHV0c1swXS5maW5kKGZ1bmN0aW9uKHgpIHtcbiAgICAgICAgcmV0dXJuIHguY29udGVudCA+IDEwO1xuICAgICAgfSk7XG4gICAgfVxuICB9LFxuICBcImZpcnN0XCI6IHtcbiAgICBcImxhYmVsXCI6IFwiZmlyc3RcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAzMCxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA0MCxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA2NSxcbiAgICAgICAgICBkOiAzXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA3NSxcbiAgICAgICAgICBkOiA0XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgICByZXR1cm4gaW5wdXRzWzBdLmZpcnN0KCk7XG4gICAgfVxuICB9LFxuICBcImxhc3RcIjoge1xuICAgIFwibGFiZWxcIjogXCJsYXN0XCIsXG4gICAgXCJpbnB1dHNcIjogW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogMzAsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNDAsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNjUsXG4gICAgICAgICAgZDogM1xuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNzUsXG4gICAgICAgICAgZDogNFxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIGlucHV0c1swXS5sYXN0KCk7XG4gICAgfVxuICB9LFxuICBcInNraXBcIjoge1xuICAgIFwibGFiZWxcIjogXCJza2lwKDIpXCIsXG4gICAgXCJpbnB1dHNcIjogW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogMzAsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNDAsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNjUsXG4gICAgICAgICAgZDogM1xuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNzUsXG4gICAgICAgICAgZDogNFxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIGlucHV0c1swXS5za2lwKDIpO1xuICAgIH1cbiAgfSxcbiAgXCJza2lwVW50aWxcIjoge1xuICAgIFwibGFiZWxcIjogXCJza2lwVW50aWxcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAwLFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDEwLFxuICAgICAgICAgIGQ6IDJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDIwLFxuICAgICAgICAgIGQ6IDNcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDMwLFxuICAgICAgICAgIGQ6IDRcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDQwLFxuICAgICAgICAgIGQ6IDVcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDUwLFxuICAgICAgICAgIGQ6IDZcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDYwLFxuICAgICAgICAgIGQ6IDdcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDcwLFxuICAgICAgICAgIGQ6IDhcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDgwLFxuICAgICAgICAgIGQ6IDlcbiAgICAgICAgfVxuICAgICAgXSwgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogNDcsXG4gICAgICAgICAgZDogMFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNzMsXG4gICAgICAgICAgZDogMFxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIGlucHV0c1swXS5za2lwVW50aWwoaW5wdXRzWzFdKTtcbiAgICB9XG4gIH0sXG4gIFwidGFrZVwiOiB7XG4gICAgXCJsYWJlbFwiOiBcInRha2UoMilcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAzMCxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA0MCxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA2NSxcbiAgICAgICAgICBkOiAzXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA3NSxcbiAgICAgICAgICBkOiA0XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzLCBzY2hlZHVsZXIpIHtcbiAgICAgIHJldHVybiBpbnB1dHNbMF0udGFrZSgyLCBzY2hlZHVsZXIpO1xuICAgIH1cbiAgfSxcbiAgXCJ0YWtlVW50aWxcIjoge1xuICAgIFwibGFiZWxcIjogXCJ0YWtlVW50aWxcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAwLFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDEwLFxuICAgICAgICAgIGQ6IDJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDIwLFxuICAgICAgICAgIGQ6IDNcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDMwLFxuICAgICAgICAgIGQ6IDRcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDQwLFxuICAgICAgICAgIGQ6IDVcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDUwLFxuICAgICAgICAgIGQ6IDZcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDYwLFxuICAgICAgICAgIGQ6IDdcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDcwLFxuICAgICAgICAgIGQ6IDhcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDgwLFxuICAgICAgICAgIGQ6IDlcbiAgICAgICAgfVxuICAgICAgXSwgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogNDcsXG4gICAgICAgICAgZDogMFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNzMsXG4gICAgICAgICAgZDogMFxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIGlucHV0c1swXS50YWtlVW50aWwoaW5wdXRzWzFdKTtcbiAgICB9XG4gIH1cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy9tb2RlbHMvZmlsdGVyLWV4YW1wbGVzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy9tb2RlbHNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgUng7XG5cblJ4ID0gcmVxdWlyZSgncngnKTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIFwiYWdncmVnYXRlXCI6IHtcbiAgICBcImxhYmVsXCI6IFwiYWdncmVnYXRlKCh4LCB5KSA9PiB4ICsgeSlcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiA1LFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDE1LFxuICAgICAgICAgIGQ6IDJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDI1LFxuICAgICAgICAgIGQ6IDNcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDM1LFxuICAgICAgICAgIGQ6IDRcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDY1LFxuICAgICAgICAgIGQ6IDVcbiAgICAgICAgfVxuICAgICAgXVxuICAgIF0sXG4gICAgXCJhcHBseVwiOiBmdW5jdGlvbihpbnB1dHMpIHtcbiAgICAgIHJldHVybiBpbnB1dHNbMF0uYWdncmVnYXRlKGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiB4LmNvbnRlbnQgKyB5LmNvbnRlbnQsXG4gICAgICAgICAgdGltZTogeC50aW1lLFxuICAgICAgICAgIGlkOiB4LmlkICsgeS5pZFxuICAgICAgICB9O1xuICAgICAgfSk7XG4gICAgfVxuICB9LFxuICBcImF2ZXJhZ2VcIjoge1xuICAgIFwibGFiZWxcIjogXCJhdmVyYWdlXCIsXG4gICAgXCJpbnB1dHNcIjogW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogNSxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAxNSxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAzMCxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA1MCxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA2NSxcbiAgICAgICAgICBkOiA1XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgICByZXR1cm4gaW5wdXRzWzBdLmF2ZXJhZ2UoZnVuY3Rpb24oeCkge1xuICAgICAgICByZXR1cm4geC5jb250ZW50O1xuICAgICAgfSk7XG4gICAgfVxuICB9LFxuICBcImNvdW50XCI6IHtcbiAgICBcImxhYmVsXCI6IFwiY291bnQoeCA9PiB4ID4gMTApXCIsXG4gICAgXCJpbnB1dHNcIjogW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogNSxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAxNSxcbiAgICAgICAgICBkOiAzMFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMjUsXG4gICAgICAgICAgZDogMjJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDM1LFxuICAgICAgICAgIGQ6IDVcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDQ1LFxuICAgICAgICAgIGQ6IDYwXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA1NSxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgICByZXR1cm4gaW5wdXRzWzBdLmNvdW50KGZ1bmN0aW9uKHgpIHtcbiAgICAgICAgcmV0dXJuIHguY29udGVudCA+IDEwO1xuICAgICAgfSk7XG4gICAgfVxuICB9LFxuICBcIm1heFwiOiB7XG4gICAgXCJsYWJlbFwiOiBcIm1heFwiLFxuICAgIFwiaW5wdXRzXCI6IFtcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIHQ6IDUsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMTUsXG4gICAgICAgICAgZDogMzBcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDI1LFxuICAgICAgICAgIGQ6IDIyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAzNSxcbiAgICAgICAgICBkOiA1XG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA0NSxcbiAgICAgICAgICBkOiA2MFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNTUsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cykge1xuICAgICAgcmV0dXJuIGlucHV0c1swXS5tYXgoZnVuY3Rpb24oeCwgeSkge1xuICAgICAgICBpZiAoeC5jb250ZW50ID4geS5jb250ZW50KSB7XG4gICAgICAgICAgcmV0dXJuIDE7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHguY29udGVudCA8IHkuY29udGVudCkge1xuICAgICAgICAgIHJldHVybiAtMTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gMDtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbiAgXCJtaW5cIjoge1xuICAgIFwibGFiZWxcIjogXCJtaW5cIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiA1LFxuICAgICAgICAgIGQ6IDJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDE1LFxuICAgICAgICAgIGQ6IDMwXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAyNSxcbiAgICAgICAgICBkOiAyMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMzUsXG4gICAgICAgICAgZDogNVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNDUsXG4gICAgICAgICAgZDogNjBcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDU1LFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfVxuICAgICAgXVxuICAgIF0sXG4gICAgXCJhcHBseVwiOiBmdW5jdGlvbihpbnB1dHMpIHtcbiAgICAgIHJldHVybiBpbnB1dHNbMF0ubWluKGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgICAgaWYgKHguY29udGVudCA+IHkuY29udGVudCkge1xuICAgICAgICAgIHJldHVybiAxO1xuICAgICAgICB9XG4gICAgICAgIGlmICh4LmNvbnRlbnQgPCB5LmNvbnRlbnQpIHtcbiAgICAgICAgICByZXR1cm4gLTE7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIDA7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG4gIFwic3VtXCI6IHtcbiAgICBcImxhYmVsXCI6IFwic3VtXCIsXG4gICAgXCJpbnB1dHNcIjogW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogNSxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAxNSxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAyNSxcbiAgICAgICAgICBkOiAzXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAzNSxcbiAgICAgICAgICBkOiA0XG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA2NSxcbiAgICAgICAgICBkOiA1XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgICByZXR1cm4gaW5wdXRzWzBdLnN1bShmdW5jdGlvbih4KSB7XG4gICAgICAgIHJldHVybiB4LmNvbnRlbnQ7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy9tb2RlbHMvbWF0aC1leGFtcGxlcy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvbW9kZWxzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIFJ4O1xuXG5SeCA9IHJlcXVpcmUoJ3J4Jyk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBcImRlbGF5XCI6IHtcbiAgICBcImxhYmVsXCI6IFwiZGVsYXlcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAwLFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDEwLFxuICAgICAgICAgIGQ6IDJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDIwLFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfVxuICAgICAgXVxuICAgIF0sXG4gICAgXCJhcHBseVwiOiBmdW5jdGlvbihpbnB1dHMsIHNjaGVkdWxlcikge1xuICAgICAgcmV0dXJuIGlucHV0c1swXS5kZWxheSgyMCwgc2NoZWR1bGVyKTtcbiAgICB9XG4gIH0sXG4gIFwiZGVsYXlXaXRoU2VsZWN0b3JcIjoge1xuICAgIFwibGFiZWxcIjogXCJkZWxheVdpdGhTZWxlY3Rvcih4ID0+IFJ4Lk9ic2VydmFibGUudGltZXIoMjAgKiB4KSlcIixcbiAgICBcImlucHV0c1wiOiBbXG4gICAgICBbXG4gICAgICAgIHtcbiAgICAgICAgICB0OiAwLFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDEwLFxuICAgICAgICAgIGQ6IDJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDIwLFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfVxuICAgICAgXVxuICAgIF0sXG4gICAgXCJhcHBseVwiOiBmdW5jdGlvbihpbnB1dHMsIHNjaGVkdWxlcikge1xuICAgICAgcmV0dXJuIGlucHV0c1swXS5kZWxheVdpdGhTZWxlY3RvcihmdW5jdGlvbih4KSB7XG4gICAgICAgIHJldHVybiBSeC5PYnNlcnZhYmxlLnRpbWVyKE51bWJlcih4LmNvbnRlbnQpICogMjAsIDEwMDAsIHNjaGVkdWxlcik7XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG4gIFwibWFwXCI6IHtcbiAgICBcImxhYmVsXCI6IFwibWFwKHggPT4gMTAgKiB4KVwiLFxuICAgIFwiaW5wdXRzXCI6IFtcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIHQ6IDEwLFxuICAgICAgICAgIGQ6IDFcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDIwLFxuICAgICAgICAgIGQ6IDJcbiAgICAgICAgfSwge1xuICAgICAgICAgIHQ6IDUwLFxuICAgICAgICAgIGQ6IDNcbiAgICAgICAgfVxuICAgICAgXVxuICAgIF0sXG4gICAgXCJhcHBseVwiOiBmdW5jdGlvbihpbnB1dHMpIHtcbiAgICAgIHJldHVybiBpbnB1dHNbMF0ubWFwKGZ1bmN0aW9uKHgpIHtcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBjb250ZW50OiB4LmNvbnRlbnQgKiAxMCxcbiAgICAgICAgICB0aW1lOiB4LnRpbWUsXG4gICAgICAgICAgaWQ6IHguaWRcbiAgICAgICAgfTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfSxcbiAgXCJzY2FuXCI6IHtcbiAgICBcImxhYmVsXCI6IFwic2NhbigoeCwgeSkgPT4geCArIHkpXCIsXG4gICAgXCJpbnB1dHNcIjogW1xuICAgICAgW1xuICAgICAgICB7XG4gICAgICAgICAgdDogNSxcbiAgICAgICAgICBkOiAxXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAxNSxcbiAgICAgICAgICBkOiAyXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAyNSxcbiAgICAgICAgICBkOiAzXG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiAzNSxcbiAgICAgICAgICBkOiA0XG4gICAgICAgIH0sIHtcbiAgICAgICAgICB0OiA2NSxcbiAgICAgICAgICBkOiA1XG4gICAgICAgIH1cbiAgICAgIF1cbiAgICBdLFxuICAgIFwiYXBwbHlcIjogZnVuY3Rpb24oaW5wdXRzKSB7XG4gICAgICByZXR1cm4gaW5wdXRzWzBdLnNjYW4oZnVuY3Rpb24oeCwgeSkge1xuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIGNvbnRlbnQ6IHguY29udGVudCArIHkuY29udGVudCxcbiAgICAgICAgICB0aW1lOiB4LnRpbWUsXG4gICAgICAgICAgaWQ6IHguaWQgKyB5LmlkXG4gICAgICAgIH07XG4gICAgICB9KTtcbiAgICB9XG4gIH0sXG4gIFwidGhyb3R0bGVcIjoge1xuICAgIFwibGFiZWxcIjogXCJ0aHJvdHRsZVwiLFxuICAgIFwiaW5wdXRzXCI6IFtcbiAgICAgIFtcbiAgICAgICAge1xuICAgICAgICAgIHQ6IDAsXG4gICAgICAgICAgZDogMVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMjYsXG4gICAgICAgICAgZDogMlxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogMzQsXG4gICAgICAgICAgZDogM1xuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNDAsXG4gICAgICAgICAgZDogNFxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogNDUsXG4gICAgICAgICAgZDogNVxuICAgICAgICB9LCB7XG4gICAgICAgICAgdDogOTAsXG4gICAgICAgICAgZDogNlxuICAgICAgICB9XG4gICAgICBdXG4gICAgXSxcbiAgICBcImFwcGx5XCI6IGZ1bmN0aW9uKGlucHV0cywgc2NoZWR1bGVyKSB7XG4gICAgICByZXR1cm4gaW5wdXRzWzBdLnRocm90dGxlKDIwLCBzY2hlZHVsZXIpO1xuICAgIH1cbiAgfVxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL21vZGVscy90cmFuc2Zvcm0tZXhhbXBsZXMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL21vZGVsc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBNYXJibGUsIFJ4LCBjcmVhdGVBcnJvd0JvZHlFbGVtZW50LCBjcmVhdGVBcnJvd0hlYWRFbGVtZW50LCBjcmVhdGVNYXJibGVzQ29udGFpbmVyRWxlbWVudCwgbWFrZURhdGFTdHJlYW0sXG4gIF9fc2xpY2UgPSBbXS5zbGljZTtcblxuUnggPSByZXF1aXJlKCdyeCcpO1xuXG5NYXJibGUgPSByZXF1aXJlKCdyeG1hcmJsZXMvdmlld3MvbWFyYmxlJyk7XG5cbmNyZWF0ZUFycm93Qm9keUVsZW1lbnQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGFycm93Qm9keTtcbiAgYXJyb3dCb2R5ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgYXJyb3dCb2R5LmNsYXNzTmFtZSA9IFwiYXJyb3dcIjtcbiAgcmV0dXJuIGFycm93Qm9keTtcbn07XG5cbmNyZWF0ZUFycm93SGVhZEVsZW1lbnQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGFycm93SGVhZDtcbiAgYXJyb3dIZWFkID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgYXJyb3dIZWFkLmNsYXNzTmFtZSA9IFwiYXJyb3ctaGVhZFwiO1xuICByZXR1cm4gYXJyb3dIZWFkO1xufTtcblxuY3JlYXRlTWFyYmxlc0NvbnRhaW5lckVsZW1lbnQgPSBmdW5jdGlvbihtYXJibGVWaWV3cykge1xuICB2YXIgbSwgbWFyYmxlc0NvbnRhaW5lciwgX2ksIF9sZW47XG4gIG1hcmJsZXNDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuICBtYXJibGVzQ29udGFpbmVyLmNsYXNzTmFtZSA9IFwibWFyYmxlc1wiO1xuICBmb3IgKF9pID0gMCwgX2xlbiA9IG1hcmJsZVZpZXdzLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgbSA9IG1hcmJsZVZpZXdzW19pXTtcbiAgICBtYXJibGVzQ29udGFpbmVyLmFwcGVuZENoaWxkKG0pO1xuICB9XG4gIHJldHVybiBtYXJibGVzQ29udGFpbmVyO1xufTtcblxubWFrZURhdGFTdHJlYW0gPSBmdW5jdGlvbihtYXJibGVWaWV3cykge1xuICB2YXIgbTtcbiAgcmV0dXJuIFJ4Lk9ic2VydmFibGUuY29tYmluZUxhdGVzdCgoZnVuY3Rpb24oKSB7XG4gICAgdmFyIF9pLCBfbGVuLCBfcmVzdWx0cztcbiAgICBfcmVzdWx0cyA9IFtdO1xuICAgIGZvciAoX2kgPSAwLCBfbGVuID0gbWFyYmxlVmlld3MubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgIG0gPSBtYXJibGVWaWV3c1tfaV07XG4gICAgICBfcmVzdWx0cy5wdXNoKG0uZGF0YVN0cmVhbSk7XG4gICAgfVxuICAgIHJldHVybiBfcmVzdWx0cztcbiAgfSkoKSwgZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZ3M7XG4gICAgYXJncyA9IDEgPD0gYXJndW1lbnRzLmxlbmd0aCA/IF9fc2xpY2UuY2FsbChhcmd1bWVudHMsIDApIDogW107XG4gICAgcmV0dXJuIGFyZ3M7XG4gIH0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJlbmRlcjogZnVuY3Rpb24oZGlhZ3JhbURhdGEpIHtcbiAgICB2YXIgZGlhZ3JhbSwgaSwgbWFyYmxlVmlld3M7XG4gICAgZGlhZ3JhbSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgZGlhZ3JhbS5jbGFzc05hbWUgPSBcImRpYWdyYW1cIjtcbiAgICBkaWFncmFtLmFwcGVuZENoaWxkKGNyZWF0ZUFycm93Qm9keUVsZW1lbnQoKSk7XG4gICAgZGlhZ3JhbS5hcHBlbmRDaGlsZChjcmVhdGVBcnJvd0hlYWRFbGVtZW50KCkpO1xuICAgIG1hcmJsZVZpZXdzID0gKGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIF9pLCBfbGVuLCBfcmVzdWx0cztcbiAgICAgIF9yZXN1bHRzID0gW107XG4gICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IGRpYWdyYW1EYXRhLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgIGkgPSBkaWFncmFtRGF0YVtfaV07XG4gICAgICAgIF9yZXN1bHRzLnB1c2goTWFyYmxlLnJlbmRlcihpLCB0cnVlKSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gX3Jlc3VsdHM7XG4gICAgfSkoKTtcbiAgICBkaWFncmFtLmFwcGVuZENoaWxkKGNyZWF0ZU1hcmJsZXNDb250YWluZXJFbGVtZW50KG1hcmJsZVZpZXdzKSk7XG4gICAgZGlhZ3JhbS5kYXRhU3RyZWFtID0gbWFrZURhdGFTdHJlYW0obWFyYmxlVmlld3MpO1xuICAgIHJldHVybiBkaWFncmFtO1xuICB9XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvdmlld3MvaW5wdXQtZGlhZ3JhbS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvdmlld3NcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgTlVNX0NPTE9SUywgUngsIFNWR19CT1JERVJfV0lEVEgsIFNWR19DWCwgU1ZHX0NZLCBTVkdfUiwgU1ZHX1ZJRVdCT1gsIFhNTE5TLCBjcmVhdGVDb250ZW50RWxlbWVudCwgY3JlYXRlTWFyYmxlU3ZnLCBjcmVhdGVSb290RWxlbWVudCwgZ2V0RHhEcmFnU3RyZWFtLCBnZXRJbnRlcmFjdGl2ZUxlZnRQb3NTdHJlYW0sIGdldExlZnRQb3NTdHJlYW0sIGgsIHJlbmRlciwgc3ZnLCB2aXJ0dWFsUmVuZGVyO1xuXG5SeCA9IHJlcXVpcmUoJ3J4Jyk7XG5cbmggPSByZXF1aXJlKCd2aXJ0dWFsLWh5cGVyc2NyaXB0Jyk7XG5cbnN2ZyA9IHJlcXVpcmUoJ3ZpcnR1YWwtaHlwZXJzY3JpcHQvc3ZnJyk7XG5cblhNTE5TID0gXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiO1xuXG5OVU1fQ09MT1JTID0gNDtcblxuU1ZHX1ZJRVdCT1ggPSBcIjAgMCAxIDFcIjtcblxuU1ZHX0NYID0gMC41O1xuXG5TVkdfQ1kgPSAwLjU7XG5cblNWR19SID0gMC40NztcblxuU1ZHX0JPUkRFUl9XSURUSCA9IFwiMC4wNnB4XCI7XG5cbmdldER4RHJhZ1N0cmVhbSA9IGZ1bmN0aW9uKGVsZW1lbnQpIHtcbiAgcmV0dXJuIFJ4Lk9ic2VydmFibGUuZnJvbUV2ZW50KGVsZW1lbnQsIFwibW91c2Vkb3duXCIpLm1hcChmdW5jdGlvbigpIHtcbiAgICB2YXIgZHhTdHJlYW0sIG1vdmVTdHJlYW0sIHVwU3RyZWFtO1xuICAgIG1vdmVTdHJlYW0gPSBSeC5PYnNlcnZhYmxlLmZyb21FdmVudChkb2N1bWVudCwgXCJtb3VzZW1vdmVcIik7XG4gICAgdXBTdHJlYW0gPSBSeC5PYnNlcnZhYmxlLmZyb21FdmVudChkb2N1bWVudCwgXCJtb3VzZXVwXCIpO1xuICAgIGR4U3RyZWFtID0gbW92ZVN0cmVhbS5tYXAoZnVuY3Rpb24oZXYpIHtcbiAgICAgIGV2LnN0b3BQcm9wYWdhdGlvbjtcbiAgICAgIGV2LnByZXZlbnREZWZhdWx0KCk7XG4gICAgICByZXR1cm4gZXYucGFnZVg7XG4gICAgfSkud2luZG93V2l0aENvdW50KDIsIDEpLmZsYXRNYXAoZnVuY3Rpb24ocmVzdWx0KSB7XG4gICAgICByZXR1cm4gcmVzdWx0LnRvQXJyYXkoKTtcbiAgICB9KS5tYXAoZnVuY3Rpb24oYXJyYXkpIHtcbiAgICAgIHJldHVybiBhcnJheVsxXSAtIGFycmF5WzBdO1xuICAgIH0pO1xuICAgIHJldHVybiBkeFN0cmVhbS50YWtlVW50aWwodXBTdHJlYW0pO1xuICB9KS5jb25jYXRBbGwoKTtcbn07XG5cbmdldEludGVyYWN0aXZlTGVmdFBvc1N0cmVhbSA9IGZ1bmN0aW9uKGVsZW1lbnQsIGluaXRpYWxQb3MpIHtcbiAgcmV0dXJuIGdldER4RHJhZ1N0cmVhbShlbGVtZW50KS5zY2FuKGluaXRpYWxQb3MsIGZ1bmN0aW9uKGFjYywgZHgpIHtcbiAgICB2YXIgZXJyLCBweFRvUGVyY2VudGFnZTtcbiAgICBweFRvUGVyY2VudGFnZSA9IDE7XG4gICAgdHJ5IHtcbiAgICAgIHB4VG9QZXJjZW50YWdlID0gMTAwLjAgLyBlbGVtZW50LnBhcmVudEVsZW1lbnQuY2xpZW50V2lkdGg7XG4gICAgfSBjYXRjaCAoX2Vycm9yKSB7XG4gICAgICBlcnIgPSBfZXJyb3I7XG4gICAgICBjb25zb2xlLndhcm4oZXJyKTtcbiAgICB9XG4gICAgcmV0dXJuIGFjYyArIChkeCAqIHB4VG9QZXJjZW50YWdlKTtcbiAgfSkubWFwKGZ1bmN0aW9uKHBvcykge1xuICAgIGlmIChwb3MgPCAwKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gICAgaWYgKHBvcyA+IDEwMCkge1xuICAgICAgcmV0dXJuIDEwMDtcbiAgICB9XG4gICAgcmV0dXJuIHBvcztcbiAgfSkubWFwKE1hdGgucm91bmQpLnN0YXJ0V2l0aChpbml0aWFsUG9zKS5kaXN0aW5jdFVudGlsQ2hhbmdlZCgpO1xufTtcblxuY3JlYXRlUm9vdEVsZW1lbnQgPSBmdW5jdGlvbihkcmFnZ2FibGUpIHtcbiAgdmFyIGNvbnRhaW5lcjtcbiAgY29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKTtcbiAgY29udGFpbmVyLmNsYXNzTmFtZSA9IFwibWFyYmxlLWNvbnRhaW5lclwiO1xuICBpZiAoZHJhZ2dhYmxlKSB7XG4gICAgY29udGFpbmVyLmNsYXNzTmFtZSArPSBcIiBkcmFnZ2FibGVcIjtcbiAgfVxuICByZXR1cm4gY29udGFpbmVyO1xufTtcblxuY3JlYXRlTWFyYmxlU3ZnID0gZnVuY3Rpb24oaXRlbSkge1xuICB2YXIgY2lyY2xlLCBjb2xvcm51bSwgbWFyYmxlO1xuICBjb2xvcm51bSA9IChpdGVtLmlkICUgTlVNX0NPTE9SUykgKyAxO1xuICBtYXJibGUgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoWE1MTlMsIFwic3ZnXCIpO1xuICBtYXJibGUuc2V0QXR0cmlidXRlKFwiY2xhc3NcIiwgXCJtYXJibGVcIik7XG4gIG1hcmJsZS5zZXRBdHRyaWJ1dGUoXCJ2aWV3Qm94XCIsIFNWR19WSUVXQk9YKTtcbiAgY2lyY2xlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFhNTE5TLCBcImNpcmNsZVwiKTtcbiAgY2lyY2xlLnNldEF0dHJpYnV0ZShcImN4XCIsIFNWR19DWCk7XG4gIGNpcmNsZS5zZXRBdHRyaWJ1dGUoXCJjeVwiLCBTVkdfQ1kpO1xuICBjaXJjbGUuc2V0QXR0cmlidXRlKFwiclwiLCBTVkdfUik7XG4gIGNpcmNsZS5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCBcIm1hcmJsZSBtYXJibGUtY29sb3ItXCIgKyBjb2xvcm51bSk7XG4gIGNpcmNsZS5zZXRBdHRyaWJ1dGUoXCJzdHJva2Utd2lkdGhcIiwgU1ZHX0JPUkRFUl9XSURUSCk7XG4gIG1hcmJsZS5hcHBlbmRDaGlsZChjaXJjbGUpO1xuICByZXR1cm4gbWFyYmxlO1xufTtcblxuY3JlYXRlQ29udGVudEVsZW1lbnQgPSBmdW5jdGlvbihpdGVtKSB7XG4gIHZhciBjb250ZW50O1xuICBjb250ZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInBcIik7XG4gIGNvbnRlbnQuY2xhc3NOYW1lID0gXCJtYXJibGUtY29udGVudFwiO1xuICBjb250ZW50LnRleHRDb250ZW50ID0gaXRlbSAhPSBudWxsID8gaXRlbS5jb250ZW50IDogdm9pZCAwO1xuICByZXR1cm4gY29udGVudDtcbn07XG5cbmdldExlZnRQb3NTdHJlYW0gPSBmdW5jdGlvbihpdGVtLCBkcmFnZ2FibGUsIGVsZW1lbnQpIHtcbiAgaWYgKGRyYWdnYWJsZSkge1xuICAgIHJldHVybiBnZXRJbnRlcmFjdGl2ZUxlZnRQb3NTdHJlYW0oZWxlbWVudCwgaXRlbS50aW1lKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gUnguT2JzZXJ2YWJsZS5qdXN0KGl0ZW0udGltZSk7XG4gIH1cbn07XG5cbnZpcnR1YWxSZW5kZXIgPSBmdW5jdGlvbihtYXJibGVEYXRhKSB7XG4gIHZhciBjb2xvcm51bSwgY29udGVudCwgbGVmdFBvcztcbiAgY29sb3JudW0gPSAobWFyYmxlRGF0YS5pZCAlIDQpICsgMTtcbiAgbGVmdFBvcyA9IFwiXCIgKyBtYXJibGVEYXRhLnRpbWUgKyBcIiVcIjtcbiAgY29udGVudCA9IFwiXCIgKyBtYXJibGVEYXRhLmNvbnRlbnQ7XG4gIHJldHVybiBoKFwiZGl2Lm1hcmJsZS1jb250YWluZXJcIiwge1xuICAgIHN0eWxlOiB7XG4gICAgICBcImxlZnRcIjogbGVmdFBvc1xuICAgIH1cbiAgfSwgW1xuICAgIHN2ZyhcInN2Z1wiLCB7XG4gICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgIFwiY2xhc3NcIjogXCJtYXJibGVcIixcbiAgICAgICAgdmlld0JveDogU1ZHX1ZJRVdCT1hcbiAgICAgIH1cbiAgICB9LCBbXG4gICAgICBzdmcoXCJjaXJjbGVcIiwge1xuICAgICAgICBhdHRyaWJ1dGVzOiB7XG4gICAgICAgICAgXCJjbGFzc1wiOiBcIm1hcmJsZSBtYXJibGUtY29sb3ItXCIgKyBjb2xvcm51bSxcbiAgICAgICAgICBjeDogU1ZHX0NYLFxuICAgICAgICAgIGN5OiBTVkdfQ1ksXG4gICAgICAgICAgcjogU1ZHX1IsXG4gICAgICAgICAgXCJzdHJva2Utd2lkdGhcIjogU1ZHX0JPUkRFUl9XSURUSFxuICAgICAgICB9XG4gICAgICB9KVxuICAgIF0pLCBoKFwicC5tYXJibGUtY29udGVudFwiLCB7fSwgY29udGVudClcbiAgXSk7XG59O1xuXG5yZW5kZXIgPSBmdW5jdGlvbihpdGVtLCBkcmFnZ2FibGUpIHtcbiAgdmFyIGNvbnRhaW5lciwgbGVmdFBvc1N0cmVhbTtcbiAgaWYgKGRyYWdnYWJsZSA9PSBudWxsKSB7XG4gICAgZHJhZ2dhYmxlID0gZmFsc2U7XG4gIH1cbiAgY29udGFpbmVyID0gY3JlYXRlUm9vdEVsZW1lbnQoZHJhZ2dhYmxlKTtcbiAgY29udGFpbmVyLmFwcGVuZENoaWxkKGNyZWF0ZU1hcmJsZVN2ZyhpdGVtKSk7XG4gIGNvbnRhaW5lci5hcHBlbmRDaGlsZChjcmVhdGVDb250ZW50RWxlbWVudChpdGVtKSk7XG4gIGxlZnRQb3NTdHJlYW0gPSBnZXRMZWZ0UG9zU3RyZWFtKGl0ZW0sIGRyYWdnYWJsZSwgY29udGFpbmVyKTtcbiAgY29udGFpbmVyLmRhdGFTdHJlYW0gPSBsZWZ0UG9zU3RyZWFtLm1hcChmdW5jdGlvbihsZWZ0UG9zKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHRpbWU6IGxlZnRQb3MsXG4gICAgICBjb250ZW50OiBpdGVtLmNvbnRlbnQsXG4gICAgICBpZDogaXRlbS5pZFxuICAgIH07XG4gIH0pO1xuICBsZWZ0UG9zU3RyZWFtLnN1YnNjcmliZShmdW5jdGlvbihsZWZ0UG9zKSB7XG4gICAgY29udGFpbmVyLnN0eWxlLmxlZnQgPSBsZWZ0UG9zICsgXCIlXCI7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0pO1xuICByZXR1cm4gY29udGFpbmVyO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJlbmRlcjogcmVuZGVyLFxuICB2aXJ0dWFsUmVuZGVyOiB2aXJ0dWFsUmVuZGVyXG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvdmlld3MvbWFyYmxlLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy92aWV3c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBoLCByZW5kZXJMYWJlbDtcblxuaCA9IHJlcXVpcmUoJ2h5cGVyc2NyaXB0Jyk7XG5cbnJlbmRlckxhYmVsID0gZnVuY3Rpb24obGFiZWwpIHtcbiAgdmFyIGF0dHJzO1xuICBhdHRycyA9IGxhYmVsLmxlbmd0aCA+IDIwID8ge1xuICAgIHN0eWxlOiB7XG4gICAgICBcImZvbnQtc2l6ZVwiOiBcIjEuNXJlbVwiXG4gICAgfVxuICB9IDoge307XG4gIHJldHVybiBoKFwic3Bhbi5vcGVyYXRvci1ib3gtbGFiZWxcIiwgYXR0cnMsIGxhYmVsKTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICByZW5kZXI6IGZ1bmN0aW9uKGV4YW1wbGUpIHtcbiAgICByZXR1cm4gaChcImRpdi5vcGVyYXRvci1ib3hcIiwgW3JlbmRlckxhYmVsKGV4YW1wbGUubGFiZWwpXSk7XG4gIH1cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy92aWV3cy9vcGVyYXRvci1ib3guanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL3ZpZXdzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIEV4YW1wbGVzLCBSeCwgZml4TGlzdEhlaWdodCwgZ2V0RG9jdW1lbnRIZWlnaHQsIGgsIG9yZ2FuaXplRXhhbXBsZXNCeUNhdGVnb3J5LCByZW5kZXJFeGFtcGxlQ2F0ZWdvcnksIHJlbmRlckV4YW1wbGVJdGVtLCByZW5kZXJFeGFtcGxlSXRlbXMsIHJlbmRlck1lbnVDb250ZW50LCBzZWxlY3RlZCQsXG4gIF9faGFzUHJvcCA9IHt9Lmhhc093blByb3BlcnR5O1xuXG5oID0gcmVxdWlyZSgnaHlwZXJzY3JpcHQnKTtcblxuUnggPSByZXF1aXJlKCdyeCcpO1xuXG5FeGFtcGxlcyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9tb2RlbHMvZXhhbXBsZXMnKTtcblxuc2VsZWN0ZWQkID0gbmV3IFJ4LlN1YmplY3QoKTtcblxucmVuZGVyRXhhbXBsZUNhdGVnb3J5ID0gZnVuY3Rpb24oY2F0ZWdvcnlOYW1lKSB7XG4gIHJldHVybiBoKFwibGkuY2F0ZWdvcnlcIiwgXCJcIiArIGNhdGVnb3J5TmFtZSk7XG59O1xuXG5yZW5kZXJFeGFtcGxlSXRlbSA9IGZ1bmN0aW9uKGV4YW1wbGUpIHtcbiAgdmFyIGxpbms7XG4gIGxpbmsgPSBoKFwiYVwiLCB7XG4gICAgaHJlZjogXCIjXCIgKyBleGFtcGxlLmtleVxuICB9LCBleGFtcGxlLmtleSk7XG4gIFJ4Lk9ic2VydmFibGUuZnJvbUV2ZW50KGxpbmssIFwiY2xpY2tcIikuc3Vic2NyaWJlKGZ1bmN0aW9uKCkge1xuICAgIHNlbGVjdGVkJC5vbk5leHQoZXhhbXBsZS5rZXkpO1xuICAgIHJldHVybiB0cnVlO1xuICB9KTtcbiAgcmV0dXJuIGgoXCJsaVwiLCBbbGlua10pO1xufTtcblxucmVuZGVyRXhhbXBsZUl0ZW1zID0gZnVuY3Rpb24oZXhhbXBsZXMpIHtcbiAgdmFyIGV4YW1wbGU7XG4gIHJldHVybiAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIF9pLCBfbGVuLCBfcmVzdWx0cztcbiAgICBfcmVzdWx0cyA9IFtdO1xuICAgIGZvciAoX2kgPSAwLCBfbGVuID0gZXhhbXBsZXMubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgIGV4YW1wbGUgPSBleGFtcGxlc1tfaV07XG4gICAgICBfcmVzdWx0cy5wdXNoKHJlbmRlckV4YW1wbGVJdGVtKGV4YW1wbGUpKTtcbiAgICB9XG4gICAgcmV0dXJuIF9yZXN1bHRzO1xuICB9KSgpO1xufTtcblxub3JnYW5pemVFeGFtcGxlc0J5Q2F0ZWdvcnkgPSBmdW5jdGlvbihleGFtcGxlcykge1xuICB2YXIgY2F0ZWdvcnlNYXAsIGtleSwgdmFsdWU7XG4gIGNhdGVnb3J5TWFwID0ge307XG4gIGZvciAoa2V5IGluIGV4YW1wbGVzKSB7XG4gICAgaWYgKCFfX2hhc1Byb3AuY2FsbChleGFtcGxlcywga2V5KSkgY29udGludWU7XG4gICAgdmFsdWUgPSBleGFtcGxlc1trZXldO1xuICAgIHZhbHVlLmtleSA9IGtleTtcbiAgICBpZiAoY2F0ZWdvcnlNYXAuaGFzT3duUHJvcGVydHkodmFsdWUuY2F0ZWdvcnkpKSB7XG4gICAgICBjYXRlZ29yeU1hcFt2YWx1ZS5jYXRlZ29yeV0ucHVzaCh2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNhdGVnb3J5TWFwW3ZhbHVlLmNhdGVnb3J5XSA9IFt2YWx1ZV07XG4gICAgfVxuICB9XG4gIHJldHVybiBjYXRlZ29yeU1hcDtcbn07XG5cbnJlbmRlck1lbnVDb250ZW50ID0gZnVuY3Rpb24oZXhhbXBsZXMpIHtcbiAgdmFyIGNhdGVnb3J5RXhhbXBsZXMsIGNhdGVnb3J5TWFwLCBjYXRlZ29yeU5hbWUsIGxpc3RJdGVtcztcbiAgbGlzdEl0ZW1zID0gW107XG4gIGNhdGVnb3J5TWFwID0gb3JnYW5pemVFeGFtcGxlc0J5Q2F0ZWdvcnkoZXhhbXBsZXMpO1xuICBmb3IgKGNhdGVnb3J5TmFtZSBpbiBjYXRlZ29yeU1hcCkge1xuICAgIGlmICghX19oYXNQcm9wLmNhbGwoY2F0ZWdvcnlNYXAsIGNhdGVnb3J5TmFtZSkpIGNvbnRpbnVlO1xuICAgIGNhdGVnb3J5RXhhbXBsZXMgPSBjYXRlZ29yeU1hcFtjYXRlZ29yeU5hbWVdO1xuICAgIGxpc3RJdGVtcy5wdXNoKHJlbmRlckV4YW1wbGVDYXRlZ29yeShjYXRlZ29yeU5hbWUpKTtcbiAgICBsaXN0SXRlbXMgPSBsaXN0SXRlbXMuY29uY2F0KHJlbmRlckV4YW1wbGVJdGVtcyhjYXRlZ29yeUV4YW1wbGVzKSk7XG4gIH1cbiAgbGlzdEl0ZW1zLnB1c2goaChcImxpLmNhdGVnb3J5XCIsIFwiTW9yZVwiKSk7XG4gIGxpc3RJdGVtcy5wdXNoKGgoXCJsaVwiLCBcIkNvbWluZyBzb29uLi4uXCIpKTtcbiAgcmV0dXJuIGxpc3RJdGVtcztcbn07XG5cbmdldERvY3VtZW50SGVpZ2h0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBib2R5LCBodG1sO1xuICBib2R5ID0gZG9jdW1lbnQuYm9keTtcbiAgaHRtbCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgcmV0dXJuIE1hdGgubWF4KGJvZHkuc2Nyb2xsSGVpZ2h0LCBib2R5Lm9mZnNldEhlaWdodCwgaHRtbC5jbGllbnRIZWlnaHQsIGh0bWwuc2Nyb2xsSGVpZ2h0LCBodG1sLm9mZnNldEhlaWdodCk7XG59O1xuXG5maXhMaXN0SGVpZ2h0ID0gZnVuY3Rpb24obGlzdEVsZW1lbnQpIHtcbiAgcmV0dXJuIFJ4Lk9ic2VydmFibGUudGltZXIoMSkuc3Vic2NyaWJlKGZ1bmN0aW9uKCkge1xuICAgIHZhciBoZWlnaHQ7XG4gICAgaGVpZ2h0ID0gZ2V0RG9jdW1lbnRIZWlnaHQoKSAtIGxpc3RFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcDtcbiAgICBsaXN0RWxlbWVudC5zdHlsZS5oZWlnaHQgPSBcIlwiICsgaGVpZ2h0ICsgXCJweFwiO1xuICAgIHJldHVybiB0cnVlO1xuICB9KTtcbn07XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuICBnZXRTZWxlY3RlZCQ6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBzZWxlY3RlZCQ7XG4gIH0sXG4gIHJlbmRlcjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGxpc3RFbGVtZW50O1xuICAgIGxpc3RFbGVtZW50ID0gaChcInVsLm9wZXJhdG9ycy1tZW51XCIsIHJlbmRlck1lbnVDb250ZW50KEV4YW1wbGVzKSk7XG4gICAgZml4TGlzdEhlaWdodChsaXN0RWxlbWVudCk7XG4gICAgcmV0dXJuIGxpc3RFbGVtZW50O1xuICB9XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvdmlld3Mvb3BlcmF0b3JzLW1lbnUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL3ZpZXdzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIE1hcmJsZSwgUngsIFZET00sIGgsIHZpcnR1YWxSZW5kZXIsIHZpcnR1YWxSZW5kZXJNYXJibGVzO1xuXG5SeCA9IHJlcXVpcmUoJ3J4Jyk7XG5cbmggPSByZXF1aXJlKCd2aXJ0dWFsLWh5cGVyc2NyaXB0Jyk7XG5cbk1hcmJsZSA9IHJlcXVpcmUoJ3J4bWFyYmxlcy92aWV3cy9tYXJibGUnKTtcblxuVkRPTSA9IHtcbiAgY3JlYXRlRWxlbWVudDogcmVxdWlyZSgndmlydHVhbC1kb20vY3JlYXRlLWVsZW1lbnQnKSxcbiAgZGlmZjogcmVxdWlyZSgndmlydHVhbC1kb20vZGlmZicpLFxuICBwYXRjaDogcmVxdWlyZSgndmlydHVhbC1kb20vcGF0Y2gnKVxufTtcblxudmlydHVhbFJlbmRlck1hcmJsZXMgPSBmdW5jdGlvbihkaWFncmFtRGF0YSkge1xuICB2YXIgbTtcbiAgcmV0dXJuIGgoXCJkaXYubWFyYmxlc1wiLCAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIF9pLCBfbGVuLCBfcmVzdWx0cztcbiAgICBfcmVzdWx0cyA9IFtdO1xuICAgIGZvciAoX2kgPSAwLCBfbGVuID0gZGlhZ3JhbURhdGEubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgIG0gPSBkaWFncmFtRGF0YVtfaV07XG4gICAgICBfcmVzdWx0cy5wdXNoKE1hcmJsZS52aXJ0dWFsUmVuZGVyKG0pKTtcbiAgICB9XG4gICAgcmV0dXJuIF9yZXN1bHRzO1xuICB9KSgpKTtcbn07XG5cbnZpcnR1YWxSZW5kZXIgPSBmdW5jdGlvbihkaWFncmFtRGF0YSkge1xuICB2YXIgY2hpbGRyZW47XG4gIGlmIChkaWFncmFtRGF0YSA9PT0gbnVsbCkge1xuICAgIHJldHVybiBoKFwiZGl2LmRpYWdyYW1cIik7XG4gIH0gZWxzZSB7XG4gICAgY2hpbGRyZW4gPSBbXTtcbiAgICBjaGlsZHJlbi5wdXNoKGgoXCJkaXYuYXJyb3dcIikpO1xuICAgIGNoaWxkcmVuLnB1c2goaChcImRpdi5hcnJvdy1oZWFkXCIpKTtcbiAgICBjaGlsZHJlbi5wdXNoKHZpcnR1YWxSZW5kZXJNYXJibGVzKGRpYWdyYW1EYXRhKSk7XG4gICAgcmV0dXJuIGgoXCJkaXYuZGlhZ3JhbVwiLCB7fSwgY2hpbGRyZW4pO1xuICB9XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcbiAgcmVuZGVyOiBmdW5jdGlvbihkaWFncmFtRGF0YVN0cmVhbSkge1xuICAgIHZhciByb290Tm9kZSwgdHJlZTtcbiAgICB0cmVlID0gdmlydHVhbFJlbmRlcihudWxsKTtcbiAgICByb290Tm9kZSA9IFZET00uY3JlYXRlRWxlbWVudCh0cmVlKTtcbiAgICBkaWFncmFtRGF0YVN0cmVhbS5zdWJzY3JpYmUoZnVuY3Rpb24oZGlhZ3JhbSkge1xuICAgICAgdmFyIG5ld1RyZWUsIHBhdGNoZXM7XG4gICAgICBuZXdUcmVlID0gdmlydHVhbFJlbmRlcihkaWFncmFtKTtcbiAgICAgIHBhdGNoZXMgPSBWRE9NLmRpZmYodHJlZSwgbmV3VHJlZSk7XG4gICAgICByb290Tm9kZSA9IFZET00ucGF0Y2gocm9vdE5vZGUsIHBhdGNoZXMpO1xuICAgICAgdHJlZSA9IG5ld1RyZWU7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9KTtcbiAgICByZXR1cm4gcm9vdE5vZGU7XG4gIH1cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3J4bWFyYmxlcy92aWV3cy9vdXRwdXQtZGlhZ3JhbS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvdmlld3NcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgSW5wdXREaWFncmFtVmlldywgT3BlcmF0b3JCb3gsIE91dHB1dERpYWdyYW1WaWV3LCBSeCwgVXRpbHMsIGNyZWF0ZUlucHV0RGlhZ3JhbUVsZW1lbnRzLCBjcmVhdGVPcGVyYXRvckJveEVsZW1lbnQsIGNyZWF0ZU91dHB1dERpYWdyYW1FbGVtZW50LCBoLCBzdHJlYW1PZkFycmF5T2ZMaXZlSW5wdXREaWFncmFtU3RyZWFtcztcblxuUnggPSByZXF1aXJlKCdyeCcpO1xuXG5oID0gcmVxdWlyZSgnaHlwZXJzY3JpcHQnKTtcblxuSW5wdXREaWFncmFtVmlldyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy92aWV3cy9pbnB1dC1kaWFncmFtJyk7XG5cbk9wZXJhdG9yQm94ID0gcmVxdWlyZSgncnhtYXJibGVzL3ZpZXdzL29wZXJhdG9yLWJveCcpO1xuXG5PdXRwdXREaWFncmFtVmlldyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy92aWV3cy9vdXRwdXQtZGlhZ3JhbScpO1xuXG5VdGlscyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy92aWV3cy91dGlscycpO1xuXG5zdHJlYW1PZkFycmF5T2ZMaXZlSW5wdXREaWFncmFtU3RyZWFtcyA9IG5ldyBSeC5CZWhhdmlvclN1YmplY3QobnVsbCk7XG5cbmNyZWF0ZUlucHV0RGlhZ3JhbUVsZW1lbnRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBJbnB1dERpYWdyYW1zLCBpbnB1dERpYWdyYW1FbGVtZW50cztcbiAgSW5wdXREaWFncmFtcyA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9jb250cm9sbGVycy9pbnB1dC1kaWFncmFtcycpO1xuICBpbnB1dERpYWdyYW1FbGVtZW50cyA9IFV0aWxzLnJlbmRlck9ic2VydmFibGVET01FbGVtZW50KElucHV0RGlhZ3JhbXMuaW5pdGlhbCQubWFwKGZ1bmN0aW9uKGRpYWdyYW1zKSB7XG4gICAgdmFyIGQ7XG4gICAgcmV0dXJuIChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfaSwgX2xlbiwgX3Jlc3VsdHM7XG4gICAgICBfcmVzdWx0cyA9IFtdO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBkaWFncmFtcy5sZW5ndGg7IF9pIDwgX2xlbjsgX2krKykge1xuICAgICAgICBkID0gZGlhZ3JhbXNbX2ldO1xuICAgICAgICBfcmVzdWx0cy5wdXNoKElucHV0RGlhZ3JhbVZpZXcucmVuZGVyKGQpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBfcmVzdWx0cztcbiAgICB9KSgpO1xuICB9KS5kb0FjdGlvbihmdW5jdGlvbihkaWFncmFtVmlld3MpIHtcbiAgICB2YXIgZGlhZ3JhbTtcbiAgICByZXR1cm4gc3RyZWFtT2ZBcnJheU9mTGl2ZUlucHV0RGlhZ3JhbVN0cmVhbXMub25OZXh0KChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBfaSwgX2xlbiwgX3Jlc3VsdHM7XG4gICAgICBfcmVzdWx0cyA9IFtdO1xuICAgICAgZm9yIChfaSA9IDAsIF9sZW4gPSBkaWFncmFtVmlld3MubGVuZ3RoOyBfaSA8IF9sZW47IF9pKyspIHtcbiAgICAgICAgZGlhZ3JhbSA9IGRpYWdyYW1WaWV3c1tfaV07XG4gICAgICAgIF9yZXN1bHRzLnB1c2goZGlhZ3JhbS5kYXRhU3RyZWFtKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBfcmVzdWx0cztcbiAgICB9KSgpKTtcbiAgfSkpO1xuICByZXR1cm4gaW5wdXREaWFncmFtRWxlbWVudHM7XG59O1xuXG5jcmVhdGVPcGVyYXRvckJveEVsZW1lbnQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIFNlbGVjdGVkRXhhbXBsZTtcbiAgU2VsZWN0ZWRFeGFtcGxlID0gcmVxdWlyZSgncnhtYXJibGVzL2NvbnRyb2xsZXJzL3NlbGVjdGVkLWV4YW1wbGUnKTtcbiAgcmV0dXJuIFV0aWxzLnJlbmRlck9ic2VydmFibGVET01FbGVtZW50KFNlbGVjdGVkRXhhbXBsZS5zdHJlYW0ubWFwKGZ1bmN0aW9uKGV4YW1wbGUpIHtcbiAgICByZXR1cm4gT3BlcmF0b3JCb3gucmVuZGVyKGV4YW1wbGUpO1xuICB9KSk7XG59O1xuXG5jcmVhdGVPdXRwdXREaWFncmFtRWxlbWVudCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgT3V0cHV0RGlhZ3JhbTtcbiAgT3V0cHV0RGlhZ3JhbSA9IHJlcXVpcmUoJ3J4bWFyYmxlcy9jb250cm9sbGVycy9vdXRwdXQtZGlhZ3JhbScpO1xuICByZXR1cm4gT3V0cHV0RGlhZ3JhbVZpZXcucmVuZGVyKE91dHB1dERpYWdyYW0pO1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG4gIGdldFN0cmVhbU9mQXJyYXlPZkxpdmVJbnB1dERpYWdyYW1TdHJlYW1zOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gc3RyZWFtT2ZBcnJheU9mTGl2ZUlucHV0RGlhZ3JhbVN0cmVhbXM7XG4gIH0sXG4gIHJlbmRlcjogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGgoXCJkaXYuc2FuZGJveFwiLCBbY3JlYXRlSW5wdXREaWFncmFtRWxlbWVudHMoKSwgY3JlYXRlT3BlcmF0b3JCb3hFbGVtZW50KCksIGNyZWF0ZU91dHB1dERpYWdyYW1FbGVtZW50KCldKTtcbiAgfVxufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL3ZpZXdzL3NhbmRib3guanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL3ZpZXdzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xubW9kdWxlLmV4cG9ydHMgPSB7XG4gIHJlbmRlck9ic2VydmFibGVET01FbGVtZW50OiBmdW5jdGlvbihlbGVtZW50U3RyZWFtKSB7XG4gICAgdmFyIHdyYXBwZXI7XG4gICAgd3JhcHBlciA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgZWxlbWVudFN0cmVhbS5zdWJzY3JpYmUoZnVuY3Rpb24odGhpbmcpIHtcbiAgICAgIHZhciBlbGVtZW50LCBfaSwgX2xlbjtcbiAgICAgIHdyYXBwZXIuaW5uZXJIVE1MID0gXCJcIjtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KHRoaW5nKSkge1xuICAgICAgICBmb3IgKF9pID0gMCwgX2xlbiA9IHRoaW5nLmxlbmd0aDsgX2kgPCBfbGVuOyBfaSsrKSB7XG4gICAgICAgICAgZWxlbWVudCA9IHRoaW5nW19pXTtcbiAgICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHRoaW5nIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgICB3cmFwcGVyLmFwcGVuZENoaWxkKHRoaW5nKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICAgIHJldHVybiB3cmFwcGVyO1xuICB9XG59O1xuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy9yeG1hcmJsZXMvdmlld3MvdXRpbHMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvcnhtYXJibGVzL3ZpZXdzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGNyZWF0ZUVsZW1lbnQgPSByZXF1aXJlKFwidmRvbS9jcmVhdGUtZWxlbWVudFwiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUVsZW1lbnRcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vY3JlYXRlLWVsZW1lbnQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb21cIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgZGlmZiA9IHJlcXVpcmUoXCJ2dHJlZS9kaWZmXCIpXG5cbm1vZHVsZS5leHBvcnRzID0gZGlmZlxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9kaWZmLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xubW9kdWxlLmV4cG9ydHMgPSBpc09iamVjdFxuXG5mdW5jdGlvbiBpc09iamVjdCh4KSB7XG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcIm9iamVjdFwiICYmIHggIT09IG51bGxcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL2lzLW9iamVjdC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvaXMtb2JqZWN0XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGlzT2JqZWN0ID0gcmVxdWlyZShcImlzLW9iamVjdFwiKVxudmFyIGlzSG9vayA9IHJlcXVpcmUoXCJ2dHJlZS9pcy12aG9va1wiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGFwcGx5UHJvcGVydGllc1xuXG5mdW5jdGlvbiBhcHBseVByb3BlcnRpZXMobm9kZSwgcHJvcHMsIHByZXZpb3VzKSB7XG4gICAgZm9yICh2YXIgcHJvcE5hbWUgaW4gcHJvcHMpIHtcbiAgICAgICAgdmFyIHByb3BWYWx1ZSA9IHByb3BzW3Byb3BOYW1lXVxuXG4gICAgICAgIGlmIChwcm9wVmFsdWUgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmVtb3ZlUHJvcGVydHkobm9kZSwgcHJvcHMsIHByZXZpb3VzLCBwcm9wTmFtZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaXNIb29rKHByb3BWYWx1ZSkpIHtcbiAgICAgICAgICAgIHByb3BWYWx1ZS5ob29rKG5vZGUsXG4gICAgICAgICAgICAgICAgcHJvcE5hbWUsXG4gICAgICAgICAgICAgICAgcHJldmlvdXMgPyBwcmV2aW91c1twcm9wTmFtZV0gOiB1bmRlZmluZWQpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoaXNPYmplY3QocHJvcFZhbHVlKSkge1xuICAgICAgICAgICAgICAgIHBhdGNoT2JqZWN0KG5vZGUsIHByb3BzLCBwcmV2aW91cywgcHJvcE5hbWUsIHByb3BWYWx1ZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHByb3BWYWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgbm9kZVtwcm9wTmFtZV0gPSBwcm9wVmFsdWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVtb3ZlUHJvcGVydHkobm9kZSwgcHJvcHMsIHByZXZpb3VzLCBwcm9wTmFtZSkge1xuICAgIGlmIChwcmV2aW91cykge1xuICAgICAgICB2YXIgcHJldmlvdXNWYWx1ZSA9IHByZXZpb3VzW3Byb3BOYW1lXVxuXG4gICAgICAgIGlmICghaXNIb29rKHByZXZpb3VzVmFsdWUpKSB7XG4gICAgICAgICAgICBpZiAocHJvcE5hbWUgPT09IFwiYXR0cmlidXRlc1wiKSB7XG4gICAgICAgICAgICAgICAgZm9yICh2YXIgYXR0ck5hbWUgaW4gcHJldmlvdXNWYWx1ZSkge1xuICAgICAgICAgICAgICAgICAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShhdHRyTmFtZSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHByb3BOYW1lID09PSBcInN0eWxlXCIpIHtcbiAgICAgICAgICAgICAgICBmb3IgKHZhciBpIGluIHByZXZpb3VzVmFsdWUpIHtcbiAgICAgICAgICAgICAgICAgICAgbm9kZS5zdHlsZVtpXSA9IFwiXCJcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2UgaWYgKHR5cGVvZiBwcmV2aW91c1ZhbHVlID09PSBcInN0cmluZ1wiKSB7XG4gICAgICAgICAgICAgICAgbm9kZVtwcm9wTmFtZV0gPSBcIlwiXG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIG5vZGVbcHJvcE5hbWVdID0gbnVsbFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiBwYXRjaE9iamVjdChub2RlLCBwcm9wcywgcHJldmlvdXMsIHByb3BOYW1lLCBwcm9wVmFsdWUpIHtcbiAgICB2YXIgcHJldmlvdXNWYWx1ZSA9IHByZXZpb3VzID8gcHJldmlvdXNbcHJvcE5hbWVdIDogdW5kZWZpbmVkXG5cbiAgICAvLyBTZXQgYXR0cmlidXRlc1xuICAgIGlmIChwcm9wTmFtZSA9PT0gXCJhdHRyaWJ1dGVzXCIpIHtcbiAgICAgICAgZm9yICh2YXIgYXR0ck5hbWUgaW4gcHJvcFZhbHVlKSB7XG4gICAgICAgICAgICB2YXIgYXR0clZhbHVlID0gcHJvcFZhbHVlW2F0dHJOYW1lXVxuXG4gICAgICAgICAgICBpZiAoYXR0clZhbHVlID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBub2RlLnJlbW92ZUF0dHJpYnV0ZShhdHRyTmFtZSlcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoYXR0ck5hbWUsIGF0dHJWYWx1ZSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmKHByZXZpb3VzVmFsdWUgJiYgaXNPYmplY3QocHJldmlvdXNWYWx1ZSkgJiZcbiAgICAgICAgZ2V0UHJvdG90eXBlKHByZXZpb3VzVmFsdWUpICE9PSBnZXRQcm90b3R5cGUocHJvcFZhbHVlKSkge1xuICAgICAgICBub2RlW3Byb3BOYW1lXSA9IHByb3BWYWx1ZVxuICAgICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIWlzT2JqZWN0KG5vZGVbcHJvcE5hbWVdKSkge1xuICAgICAgICBub2RlW3Byb3BOYW1lXSA9IHt9XG4gICAgfVxuXG4gICAgdmFyIHJlcGxhY2VyID0gcHJvcE5hbWUgPT09IFwic3R5bGVcIiA/IFwiXCIgOiB1bmRlZmluZWRcblxuICAgIGZvciAodmFyIGsgaW4gcHJvcFZhbHVlKSB7XG4gICAgICAgIHZhciB2YWx1ZSA9IHByb3BWYWx1ZVtrXVxuICAgICAgICBub2RlW3Byb3BOYW1lXVtrXSA9ICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSA/IHJlcGxhY2VyIDogdmFsdWVcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGdldFByb3RvdHlwZSh2YWx1ZSkge1xuICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSlcbiAgICB9IGVsc2UgaWYgKHZhbHVlLl9fcHJvdG9fXykge1xuICAgICAgICByZXR1cm4gdmFsdWUuX19wcm90b19fXG4gICAgfSBlbHNlIGlmICh2YWx1ZS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICByZXR1cm4gdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlXG4gICAgfVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdmRvbS9hcHBseS1wcm9wZXJ0aWVzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92ZG9tXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGRvY3VtZW50ID0gcmVxdWlyZShcImdsb2JhbC9kb2N1bWVudFwiKVxuXG52YXIgYXBwbHlQcm9wZXJ0aWVzID0gcmVxdWlyZShcIi4vYXBwbHktcHJvcGVydGllc1wiKVxuXG52YXIgaXNWTm9kZSA9IHJlcXVpcmUoXCJ2dHJlZS9pcy12bm9kZVwiKVxudmFyIGlzVlRleHQgPSByZXF1aXJlKFwidnRyZWUvaXMtdnRleHRcIilcbnZhciBpc1dpZGdldCA9IHJlcXVpcmUoXCJ2dHJlZS9pcy13aWRnZXRcIilcbnZhciBoYW5kbGVUaHVuayA9IHJlcXVpcmUoXCJ2dHJlZS9oYW5kbGUtdGh1bmtcIilcblxubW9kdWxlLmV4cG9ydHMgPSBjcmVhdGVFbGVtZW50XG5cbmZ1bmN0aW9uIGNyZWF0ZUVsZW1lbnQodm5vZGUsIG9wdHMpIHtcbiAgICB2YXIgZG9jID0gb3B0cyA/IG9wdHMuZG9jdW1lbnQgfHwgZG9jdW1lbnQgOiBkb2N1bWVudFxuICAgIHZhciB3YXJuID0gb3B0cyA/IG9wdHMud2FybiA6IG51bGxcblxuICAgIHZub2RlID0gaGFuZGxlVGh1bmsodm5vZGUpLmFcblxuICAgIGlmIChpc1dpZGdldCh2bm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIHZub2RlLmluaXQoKVxuICAgIH0gZWxzZSBpZiAoaXNWVGV4dCh2bm9kZSkpIHtcbiAgICAgICAgcmV0dXJuIGRvYy5jcmVhdGVUZXh0Tm9kZSh2bm9kZS50ZXh0KVxuICAgIH0gZWxzZSBpZiAoIWlzVk5vZGUodm5vZGUpKSB7XG4gICAgICAgIGlmICh3YXJuKSB7XG4gICAgICAgICAgICB3YXJuKFwiSXRlbSBpcyBub3QgYSB2YWxpZCB2aXJ0dWFsIGRvbSBub2RlXCIsIHZub2RlKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgdmFyIG5vZGUgPSAodm5vZGUubmFtZXNwYWNlID09PSBudWxsKSA/XG4gICAgICAgIGRvYy5jcmVhdGVFbGVtZW50KHZub2RlLnRhZ05hbWUpIDpcbiAgICAgICAgZG9jLmNyZWF0ZUVsZW1lbnROUyh2bm9kZS5uYW1lc3BhY2UsIHZub2RlLnRhZ05hbWUpXG5cbiAgICB2YXIgcHJvcHMgPSB2bm9kZS5wcm9wZXJ0aWVzXG4gICAgYXBwbHlQcm9wZXJ0aWVzKG5vZGUsIHByb3BzKVxuXG4gICAgdmFyIGNoaWxkcmVuID0gdm5vZGUuY2hpbGRyZW5cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGNoaWxkTm9kZSA9IGNyZWF0ZUVsZW1lbnQoY2hpbGRyZW5baV0sIG9wdHMpXG4gICAgICAgIGlmIChjaGlsZE5vZGUpIHtcbiAgICAgICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoY2hpbGROb2RlKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGVcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Zkb20vY3JlYXRlLWVsZW1lbnQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Zkb21cIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG4vLyBNYXBzIGEgdmlydHVhbCBET00gdHJlZSBvbnRvIGEgcmVhbCBET00gdHJlZSBpbiBhbiBlZmZpY2llbnQgbWFubmVyLlxuLy8gV2UgZG9uJ3Qgd2FudCB0byByZWFkIGFsbCBvZiB0aGUgRE9NIG5vZGVzIGluIHRoZSB0cmVlIHNvIHdlIHVzZVxuLy8gdGhlIGluLW9yZGVyIHRyZWUgaW5kZXhpbmcgdG8gZWxpbWluYXRlIHJlY3Vyc2lvbiBkb3duIGNlcnRhaW4gYnJhbmNoZXMuXG4vLyBXZSBvbmx5IHJlY3Vyc2UgaW50byBhIERPTSBub2RlIGlmIHdlIGtub3cgdGhhdCBpdCBjb250YWlucyBhIGNoaWxkIG9mXG4vLyBpbnRlcmVzdC5cblxudmFyIG5vQ2hpbGQgPSB7fVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRvbUluZGV4XG5cbmZ1bmN0aW9uIGRvbUluZGV4KHJvb3ROb2RlLCB0cmVlLCBpbmRpY2VzLCBub2Rlcykge1xuICAgIGlmICghaW5kaWNlcyB8fCBpbmRpY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4ge31cbiAgICB9IGVsc2Uge1xuICAgICAgICBpbmRpY2VzLnNvcnQoYXNjZW5kaW5nKVxuICAgICAgICByZXR1cm4gcmVjdXJzZShyb290Tm9kZSwgdHJlZSwgaW5kaWNlcywgbm9kZXMsIDApXG4gICAgfVxufVxuXG5mdW5jdGlvbiByZWN1cnNlKHJvb3ROb2RlLCB0cmVlLCBpbmRpY2VzLCBub2Rlcywgcm9vdEluZGV4KSB7XG4gICAgbm9kZXMgPSBub2RlcyB8fCB7fVxuXG5cbiAgICBpZiAocm9vdE5vZGUpIHtcbiAgICAgICAgaWYgKGluZGV4SW5SYW5nZShpbmRpY2VzLCByb290SW5kZXgsIHJvb3RJbmRleCkpIHtcbiAgICAgICAgICAgIG5vZGVzW3Jvb3RJbmRleF0gPSByb290Tm9kZVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHZDaGlsZHJlbiA9IHRyZWUuY2hpbGRyZW5cblxuICAgICAgICBpZiAodkNoaWxkcmVuKSB7XG5cbiAgICAgICAgICAgIHZhciBjaGlsZE5vZGVzID0gcm9vdE5vZGUuY2hpbGROb2Rlc1xuXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRyZWUuY2hpbGRyZW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICByb290SW5kZXggKz0gMVxuXG4gICAgICAgICAgICAgICAgdmFyIHZDaGlsZCA9IHZDaGlsZHJlbltpXSB8fCBub0NoaWxkXG4gICAgICAgICAgICAgICAgdmFyIG5leHRJbmRleCA9IHJvb3RJbmRleCArICh2Q2hpbGQuY291bnQgfHwgMClcblxuICAgICAgICAgICAgICAgIC8vIHNraXAgcmVjdXJzaW9uIGRvd24gdGhlIHRyZWUgaWYgdGhlcmUgYXJlIG5vIG5vZGVzIGRvd24gaGVyZVxuICAgICAgICAgICAgICAgIGlmIChpbmRleEluUmFuZ2UoaW5kaWNlcywgcm9vdEluZGV4LCBuZXh0SW5kZXgpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlY3Vyc2UoY2hpbGROb2Rlc1tpXSwgdkNoaWxkLCBpbmRpY2VzLCBub2Rlcywgcm9vdEluZGV4KVxuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIHJvb3RJbmRleCA9IG5leHRJbmRleFxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG5vZGVzXG59XG5cbi8vIEJpbmFyeSBzZWFyY2ggZm9yIGFuIGluZGV4IGluIHRoZSBpbnRlcnZhbCBbbGVmdCwgcmlnaHRdXG5mdW5jdGlvbiBpbmRleEluUmFuZ2UoaW5kaWNlcywgbGVmdCwgcmlnaHQpIHtcbiAgICBpZiAoaW5kaWNlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlXG4gICAgfVxuXG4gICAgdmFyIG1pbkluZGV4ID0gMFxuICAgIHZhciBtYXhJbmRleCA9IGluZGljZXMubGVuZ3RoIC0gMVxuICAgIHZhciBjdXJyZW50SW5kZXhcbiAgICB2YXIgY3VycmVudEl0ZW1cblxuICAgIHdoaWxlIChtaW5JbmRleCA8PSBtYXhJbmRleCkge1xuICAgICAgICBjdXJyZW50SW5kZXggPSAoKG1heEluZGV4ICsgbWluSW5kZXgpIC8gMikgPj4gMFxuICAgICAgICBjdXJyZW50SXRlbSA9IGluZGljZXNbY3VycmVudEluZGV4XVxuXG4gICAgICAgIGlmIChtaW5JbmRleCA9PT0gbWF4SW5kZXgpIHtcbiAgICAgICAgICAgIHJldHVybiBjdXJyZW50SXRlbSA+PSBsZWZ0ICYmIGN1cnJlbnRJdGVtIDw9IHJpZ2h0XG4gICAgICAgIH0gZWxzZSBpZiAoY3VycmVudEl0ZW0gPCBsZWZ0KSB7XG4gICAgICAgICAgICBtaW5JbmRleCA9IGN1cnJlbnRJbmRleCArIDFcbiAgICAgICAgfSBlbHNlICBpZiAoY3VycmVudEl0ZW0gPiByaWdodCkge1xuICAgICAgICAgICAgbWF4SW5kZXggPSBjdXJyZW50SW5kZXggLSAxXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gdHJ1ZVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBhc2NlbmRpbmcoYSwgYikge1xuICAgIHJldHVybiBhID4gYiA/IDEgOiAtMVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdmRvbS9kb20taW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Zkb21cIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgdG9wTGV2ZWwgPSB0eXBlb2YgZ2xvYmFsICE9PSAndW5kZWZpbmVkJyA/IGdsb2JhbCA6XG4gICAgdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgPyB3aW5kb3cgOiB7fVxudmFyIG1pbkRvYyA9IHJlcXVpcmUoJ21pbi1kb2N1bWVudCcpO1xuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgIG1vZHVsZS5leHBvcnRzID0gZG9jdW1lbnQ7XG59IGVsc2Uge1xuICAgIHZhciBkb2NjeSA9IHRvcExldmVsWydfX0dMT0JBTF9ET0NVTUVOVF9DQUNIRUA0J107XG5cbiAgICBpZiAoIWRvY2N5KSB7XG4gICAgICAgIGRvY2N5ID0gdG9wTGV2ZWxbJ19fR0xPQkFMX0RPQ1VNRU5UX0NBQ0hFQDQnXSA9IG1pbkRvYztcbiAgICB9XG5cbiAgICBtb2R1bGUuZXhwb3J0cyA9IGRvY2N5O1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdmRvbS9ub2RlX21vZHVsZXMvZ2xvYmFsL2RvY3VtZW50LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92ZG9tL25vZGVfbW9kdWxlcy9nbG9iYWxcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgYXBwbHlQcm9wZXJ0aWVzID0gcmVxdWlyZShcIi4vYXBwbHktcHJvcGVydGllc1wiKVxuXG52YXIgaXNXaWRnZXQgPSByZXF1aXJlKFwidnRyZWUvaXMtd2lkZ2V0XCIpXG52YXIgVlBhdGNoID0gcmVxdWlyZShcInZ0cmVlL3ZwYXRjaFwiKVxuXG52YXIgcmVuZGVyID0gcmVxdWlyZShcIi4vY3JlYXRlLWVsZW1lbnRcIilcbnZhciB1cGRhdGVXaWRnZXQgPSByZXF1aXJlKFwiLi91cGRhdGUtd2lkZ2V0XCIpXG5cbm1vZHVsZS5leHBvcnRzID0gYXBwbHlQYXRjaFxuXG5mdW5jdGlvbiBhcHBseVBhdGNoKHZwYXRjaCwgZG9tTm9kZSwgcmVuZGVyT3B0aW9ucykge1xuICAgIHZhciB0eXBlID0gdnBhdGNoLnR5cGVcbiAgICB2YXIgdk5vZGUgPSB2cGF0Y2gudk5vZGVcbiAgICB2YXIgcGF0Y2ggPSB2cGF0Y2gucGF0Y2hcblxuICAgIHN3aXRjaCAodHlwZSkge1xuICAgICAgICBjYXNlIFZQYXRjaC5SRU1PVkU6XG4gICAgICAgICAgICByZXR1cm4gcmVtb3ZlTm9kZShkb21Ob2RlLCB2Tm9kZSlcbiAgICAgICAgY2FzZSBWUGF0Y2guSU5TRVJUOlxuICAgICAgICAgICAgcmV0dXJuIGluc2VydE5vZGUoZG9tTm9kZSwgcGF0Y2gsIHJlbmRlck9wdGlvbnMpXG4gICAgICAgIGNhc2UgVlBhdGNoLlZURVhUOlxuICAgICAgICAgICAgcmV0dXJuIHN0cmluZ1BhdGNoKGRvbU5vZGUsIHZOb2RlLCBwYXRjaCwgcmVuZGVyT3B0aW9ucylcbiAgICAgICAgY2FzZSBWUGF0Y2guV0lER0VUOlxuICAgICAgICAgICAgcmV0dXJuIHdpZGdldFBhdGNoKGRvbU5vZGUsIHZOb2RlLCBwYXRjaCwgcmVuZGVyT3B0aW9ucylcbiAgICAgICAgY2FzZSBWUGF0Y2guVk5PREU6XG4gICAgICAgICAgICByZXR1cm4gdk5vZGVQYXRjaChkb21Ob2RlLCB2Tm9kZSwgcGF0Y2gsIHJlbmRlck9wdGlvbnMpXG4gICAgICAgIGNhc2UgVlBhdGNoLk9SREVSOlxuICAgICAgICAgICAgcmVvcmRlckNoaWxkcmVuKGRvbU5vZGUsIHBhdGNoKVxuICAgICAgICAgICAgcmV0dXJuIGRvbU5vZGVcbiAgICAgICAgY2FzZSBWUGF0Y2guUFJPUFM6XG4gICAgICAgICAgICBhcHBseVByb3BlcnRpZXMoZG9tTm9kZSwgcGF0Y2gsIHZOb2RlLnByb3BlcnRpZXMpXG4gICAgICAgICAgICByZXR1cm4gZG9tTm9kZVxuICAgICAgICBjYXNlIFZQYXRjaC5USFVOSzpcbiAgICAgICAgICAgIHJldHVybiByZXBsYWNlUm9vdChkb21Ob2RlLFxuICAgICAgICAgICAgICAgIHJlbmRlck9wdGlvbnMucGF0Y2goZG9tTm9kZSwgcGF0Y2gsIHJlbmRlck9wdGlvbnMpKVxuICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgcmV0dXJuIGRvbU5vZGVcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlbW92ZU5vZGUoZG9tTm9kZSwgdk5vZGUpIHtcbiAgICB2YXIgcGFyZW50Tm9kZSA9IGRvbU5vZGUucGFyZW50Tm9kZVxuXG4gICAgaWYgKHBhcmVudE5vZGUpIHtcbiAgICAgICAgcGFyZW50Tm9kZS5yZW1vdmVDaGlsZChkb21Ob2RlKVxuICAgIH1cblxuICAgIGRlc3Ryb3lXaWRnZXQoZG9tTm9kZSwgdk5vZGUpO1xuXG4gICAgcmV0dXJuIG51bGxcbn1cblxuZnVuY3Rpb24gaW5zZXJ0Tm9kZShwYXJlbnROb2RlLCB2Tm9kZSwgcmVuZGVyT3B0aW9ucykge1xuICAgIHZhciBuZXdOb2RlID0gcmVuZGVyKHZOb2RlLCByZW5kZXJPcHRpb25zKVxuXG4gICAgaWYgKHBhcmVudE5vZGUpIHtcbiAgICAgICAgcGFyZW50Tm9kZS5hcHBlbmRDaGlsZChuZXdOb2RlKVxuICAgIH1cblxuICAgIHJldHVybiBwYXJlbnROb2RlXG59XG5cbmZ1bmN0aW9uIHN0cmluZ1BhdGNoKGRvbU5vZGUsIGxlZnRWTm9kZSwgdlRleHQsIHJlbmRlck9wdGlvbnMpIHtcbiAgICB2YXIgbmV3Tm9kZVxuXG4gICAgaWYgKGRvbU5vZGUubm9kZVR5cGUgPT09IDMpIHtcbiAgICAgICAgZG9tTm9kZS5yZXBsYWNlRGF0YSgwLCBkb21Ob2RlLmxlbmd0aCwgdlRleHQudGV4dClcbiAgICAgICAgbmV3Tm9kZSA9IGRvbU5vZGVcbiAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcGFyZW50Tm9kZSA9IGRvbU5vZGUucGFyZW50Tm9kZVxuICAgICAgICBuZXdOb2RlID0gcmVuZGVyKHZUZXh0LCByZW5kZXJPcHRpb25zKVxuXG4gICAgICAgIGlmIChwYXJlbnROb2RlKSB7XG4gICAgICAgICAgICBwYXJlbnROb2RlLnJlcGxhY2VDaGlsZChuZXdOb2RlLCBkb21Ob2RlKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgZGVzdHJveVdpZGdldChkb21Ob2RlLCBsZWZ0Vk5vZGUpXG5cbiAgICByZXR1cm4gbmV3Tm9kZVxufVxuXG5mdW5jdGlvbiB3aWRnZXRQYXRjaChkb21Ob2RlLCBsZWZ0Vk5vZGUsIHdpZGdldCwgcmVuZGVyT3B0aW9ucykge1xuICAgIGlmICh1cGRhdGVXaWRnZXQobGVmdFZOb2RlLCB3aWRnZXQpKSB7XG4gICAgICAgIHJldHVybiB3aWRnZXQudXBkYXRlKGxlZnRWTm9kZSwgZG9tTm9kZSkgfHwgZG9tTm9kZVxuICAgIH1cblxuICAgIHZhciBwYXJlbnROb2RlID0gZG9tTm9kZS5wYXJlbnROb2RlXG4gICAgdmFyIG5ld1dpZGdldCA9IHJlbmRlcih3aWRnZXQsIHJlbmRlck9wdGlvbnMpXG5cbiAgICBpZiAocGFyZW50Tm9kZSkge1xuICAgICAgICBwYXJlbnROb2RlLnJlcGxhY2VDaGlsZChuZXdXaWRnZXQsIGRvbU5vZGUpXG4gICAgfVxuXG4gICAgZGVzdHJveVdpZGdldChkb21Ob2RlLCBsZWZ0Vk5vZGUpXG5cbiAgICByZXR1cm4gbmV3V2lkZ2V0XG59XG5cbmZ1bmN0aW9uIHZOb2RlUGF0Y2goZG9tTm9kZSwgbGVmdFZOb2RlLCB2Tm9kZSwgcmVuZGVyT3B0aW9ucykge1xuICAgIHZhciBwYXJlbnROb2RlID0gZG9tTm9kZS5wYXJlbnROb2RlXG4gICAgdmFyIG5ld05vZGUgPSByZW5kZXIodk5vZGUsIHJlbmRlck9wdGlvbnMpXG5cbiAgICBpZiAocGFyZW50Tm9kZSkge1xuICAgICAgICBwYXJlbnROb2RlLnJlcGxhY2VDaGlsZChuZXdOb2RlLCBkb21Ob2RlKVxuICAgIH1cblxuICAgIGRlc3Ryb3lXaWRnZXQoZG9tTm9kZSwgbGVmdFZOb2RlKVxuXG4gICAgcmV0dXJuIG5ld05vZGVcbn1cblxuZnVuY3Rpb24gZGVzdHJveVdpZGdldChkb21Ob2RlLCB3KSB7XG4gICAgaWYgKHR5cGVvZiB3LmRlc3Ryb3kgPT09IFwiZnVuY3Rpb25cIiAmJiBpc1dpZGdldCh3KSkge1xuICAgICAgICB3LmRlc3Ryb3koZG9tTm9kZSlcbiAgICB9XG59XG5cbmZ1bmN0aW9uIHJlb3JkZXJDaGlsZHJlbihkb21Ob2RlLCBiSW5kZXgpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSBbXVxuICAgIHZhciBjaGlsZE5vZGVzID0gZG9tTm9kZS5jaGlsZE5vZGVzXG4gICAgdmFyIGxlbiA9IGNoaWxkTm9kZXMubGVuZ3RoXG4gICAgdmFyIGlcbiAgICB2YXIgcmV2ZXJzZUluZGV4ID0gYkluZGV4LnJldmVyc2VcblxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBjaGlsZHJlbi5wdXNoKGRvbU5vZGUuY2hpbGROb2Rlc1tpXSlcbiAgICB9XG5cbiAgICB2YXIgaW5zZXJ0T2Zmc2V0ID0gMFxuICAgIHZhciBtb3ZlXG4gICAgdmFyIG5vZGVcbiAgICB2YXIgaW5zZXJ0Tm9kZVxuICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICBtb3ZlID0gYkluZGV4W2ldXG4gICAgICAgIGlmIChtb3ZlICE9PSB1bmRlZmluZWQgJiYgbW92ZSAhPT0gaSkge1xuICAgICAgICAgICAgLy8gdGhlIGVsZW1lbnQgY3VycmVudGx5IGF0IHRoaXMgaW5kZXggd2lsbCBiZSBtb3ZlZCBsYXRlciBzbyBpbmNyZWFzZSB0aGUgaW5zZXJ0IG9mZnNldFxuICAgICAgICAgICAgaWYgKHJldmVyc2VJbmRleFtpXSA+IGkpIHtcbiAgICAgICAgICAgICAgICBpbnNlcnRPZmZzZXQrK1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBub2RlID0gY2hpbGRyZW5bbW92ZV1cbiAgICAgICAgICAgIGluc2VydE5vZGUgPSBjaGlsZE5vZGVzW2kgKyBpbnNlcnRPZmZzZXRdXG4gICAgICAgICAgICBpZiAobm9kZSAhPT0gaW5zZXJ0Tm9kZSkge1xuICAgICAgICAgICAgICAgIGRvbU5vZGUuaW5zZXJ0QmVmb3JlKG5vZGUsIGluc2VydE5vZGUpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIHRoZSBtb3ZlZCBlbGVtZW50IGNhbWUgZnJvbSB0aGUgZnJvbnQgb2YgdGhlIGFycmF5IHNvIHJlZHVjZSB0aGUgaW5zZXJ0IG9mZnNldFxuICAgICAgICAgICAgaWYgKG1vdmUgPCBpKSB7XG4gICAgICAgICAgICAgICAgaW5zZXJ0T2Zmc2V0LS1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGVsZW1lbnQgYXQgdGhpcyBpbmRleCBpcyBzY2hlZHVsZWQgdG8gYmUgcmVtb3ZlZCBzbyBpbmNyZWFzZSBpbnNlcnQgb2Zmc2V0XG4gICAgICAgIGlmIChpIGluIGJJbmRleC5yZW1vdmVzKSB7XG4gICAgICAgICAgICBpbnNlcnRPZmZzZXQrK1xuICAgICAgICB9XG4gICAgfVxufVxuXG5mdW5jdGlvbiByZXBsYWNlUm9vdChvbGRSb290LCBuZXdSb290KSB7XG4gICAgaWYgKG9sZFJvb3QgJiYgbmV3Um9vdCAmJiBvbGRSb290ICE9PSBuZXdSb290ICYmIG9sZFJvb3QucGFyZW50Tm9kZSkge1xuICAgICAgICBjb25zb2xlLmxvZyhvbGRSb290KVxuICAgICAgICBvbGRSb290LnBhcmVudE5vZGUucmVwbGFjZUNoaWxkKG5ld1Jvb3QsIG9sZFJvb3QpXG4gICAgfVxuXG4gICAgcmV0dXJuIG5ld1Jvb3Q7XG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92ZG9tL3BhdGNoLW9wLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92ZG9tXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGRvY3VtZW50ID0gcmVxdWlyZShcImdsb2JhbC9kb2N1bWVudFwiKVxudmFyIGlzQXJyYXkgPSByZXF1aXJlKFwieC1pcy1hcnJheVwiKVxuXG52YXIgZG9tSW5kZXggPSByZXF1aXJlKFwiLi9kb20taW5kZXhcIilcbnZhciBwYXRjaE9wID0gcmVxdWlyZShcIi4vcGF0Y2gtb3BcIilcbm1vZHVsZS5leHBvcnRzID0gcGF0Y2hcblxuZnVuY3Rpb24gcGF0Y2gocm9vdE5vZGUsIHBhdGNoZXMpIHtcbiAgICByZXR1cm4gcGF0Y2hSZWN1cnNpdmUocm9vdE5vZGUsIHBhdGNoZXMpXG59XG5cbmZ1bmN0aW9uIHBhdGNoUmVjdXJzaXZlKHJvb3ROb2RlLCBwYXRjaGVzLCByZW5kZXJPcHRpb25zKSB7XG4gICAgdmFyIGluZGljZXMgPSBwYXRjaEluZGljZXMocGF0Y2hlcylcblxuICAgIGlmIChpbmRpY2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gcm9vdE5vZGVcbiAgICB9XG5cbiAgICB2YXIgaW5kZXggPSBkb21JbmRleChyb290Tm9kZSwgcGF0Y2hlcy5hLCBpbmRpY2VzKVxuICAgIHZhciBvd25lckRvY3VtZW50ID0gcm9vdE5vZGUub3duZXJEb2N1bWVudFxuXG4gICAgaWYgKCFyZW5kZXJPcHRpb25zKSB7XG4gICAgICAgIHJlbmRlck9wdGlvbnMgPSB7IHBhdGNoOiBwYXRjaFJlY3Vyc2l2ZSB9XG4gICAgICAgIGlmIChvd25lckRvY3VtZW50ICE9PSBkb2N1bWVudCkge1xuICAgICAgICAgICAgcmVuZGVyT3B0aW9ucy5kb2N1bWVudCA9IG93bmVyRG9jdW1lbnRcbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaW5kaWNlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgbm9kZUluZGV4ID0gaW5kaWNlc1tpXVxuICAgICAgICByb290Tm9kZSA9IGFwcGx5UGF0Y2gocm9vdE5vZGUsXG4gICAgICAgICAgICBpbmRleFtub2RlSW5kZXhdLFxuICAgICAgICAgICAgcGF0Y2hlc1tub2RlSW5kZXhdLFxuICAgICAgICAgICAgcmVuZGVyT3B0aW9ucylcbiAgICB9XG5cbiAgICByZXR1cm4gcm9vdE5vZGVcbn1cblxuZnVuY3Rpb24gYXBwbHlQYXRjaChyb290Tm9kZSwgZG9tTm9kZSwgcGF0Y2hMaXN0LCByZW5kZXJPcHRpb25zKSB7XG4gICAgaWYgKCFkb21Ob2RlKSB7XG4gICAgICAgIHJldHVybiByb290Tm9kZVxuICAgIH1cblxuICAgIHZhciBuZXdOb2RlXG5cbiAgICBpZiAoaXNBcnJheShwYXRjaExpc3QpKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGF0Y2hMaXN0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBuZXdOb2RlID0gcGF0Y2hPcChwYXRjaExpc3RbaV0sIGRvbU5vZGUsIHJlbmRlck9wdGlvbnMpXG5cbiAgICAgICAgICAgIGlmIChkb21Ob2RlID09PSByb290Tm9kZSkge1xuICAgICAgICAgICAgICAgIHJvb3ROb2RlID0gbmV3Tm9kZVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgICAgbmV3Tm9kZSA9IHBhdGNoT3AocGF0Y2hMaXN0LCBkb21Ob2RlLCByZW5kZXJPcHRpb25zKVxuXG4gICAgICAgIGlmIChkb21Ob2RlID09PSByb290Tm9kZSkge1xuICAgICAgICAgICAgcm9vdE5vZGUgPSBuZXdOb2RlXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcm9vdE5vZGVcbn1cblxuZnVuY3Rpb24gcGF0Y2hJbmRpY2VzKHBhdGNoZXMpIHtcbiAgICB2YXIgaW5kaWNlcyA9IFtdXG5cbiAgICBmb3IgKHZhciBrZXkgaW4gcGF0Y2hlcykge1xuICAgICAgICBpZiAoa2V5ICE9PSBcImFcIikge1xuICAgICAgICAgICAgaW5kaWNlcy5wdXNoKE51bWJlcihrZXkpKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGluZGljZXNcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Zkb20vcGF0Y2guanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Zkb21cIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgaXNXaWRnZXQgPSByZXF1aXJlKFwidnRyZWUvaXMtd2lkZ2V0XCIpXG5cbm1vZHVsZS5leHBvcnRzID0gdXBkYXRlV2lkZ2V0XG5cbmZ1bmN0aW9uIHVwZGF0ZVdpZGdldChhLCBiKSB7XG4gICAgaWYgKGlzV2lkZ2V0KGEpICYmIGlzV2lkZ2V0KGIpKSB7XG4gICAgICAgIGlmIChcIm5hbWVcIiBpbiBhICYmIFwibmFtZVwiIGluIGIpIHtcbiAgICAgICAgICAgIHJldHVybiBhLmlkID09PSBiLmlkXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gYS5pbml0ID09PSBiLmluaXRcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBmYWxzZVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdmRvbS91cGRhdGUtd2lkZ2V0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92ZG9tXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGlzQXJyYXkgPSByZXF1aXJlKFwieC1pcy1hcnJheVwiKVxudmFyIGlzT2JqZWN0ID0gcmVxdWlyZShcImlzLW9iamVjdFwiKVxuXG52YXIgVlBhdGNoID0gcmVxdWlyZShcIi4vdnBhdGNoXCIpXG52YXIgaXNWTm9kZSA9IHJlcXVpcmUoXCIuL2lzLXZub2RlXCIpXG52YXIgaXNWVGV4dCA9IHJlcXVpcmUoXCIuL2lzLXZ0ZXh0XCIpXG52YXIgaXNXaWRnZXQgPSByZXF1aXJlKFwiLi9pcy13aWRnZXRcIilcbnZhciBpc1RodW5rID0gcmVxdWlyZShcIi4vaXMtdGh1bmtcIilcbnZhciBoYW5kbGVUaHVuayA9IHJlcXVpcmUoXCIuL2hhbmRsZS10aHVua1wiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGRpZmZcblxuZnVuY3Rpb24gZGlmZihhLCBiKSB7XG4gICAgdmFyIHBhdGNoID0geyBhOiBhIH1cbiAgICB3YWxrKGEsIGIsIHBhdGNoLCAwKVxuICAgIHJldHVybiBwYXRjaFxufVxuXG5mdW5jdGlvbiB3YWxrKGEsIGIsIHBhdGNoLCBpbmRleCkge1xuICAgIGlmIChhID09PSBiKSB7XG4gICAgICAgIGlmIChpc1RodW5rKGEpIHx8IGlzVGh1bmsoYikpIHtcbiAgICAgICAgICAgIHRodW5rcyhhLCBiLCBwYXRjaCwgaW5kZXgpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBob29rcyhiLCBwYXRjaCwgaW5kZXgpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdmFyIGFwcGx5ID0gcGF0Y2hbaW5kZXhdXG5cbiAgICBpZiAoYiA9PSBudWxsKSB7XG4gICAgICAgIGFwcGx5ID0gYXBwZW5kUGF0Y2goYXBwbHksIG5ldyBWUGF0Y2goVlBhdGNoLlJFTU9WRSwgYSwgYikpXG4gICAgICAgIGRlc3Ryb3lXaWRnZXRzKGEsIHBhdGNoLCBpbmRleClcbiAgICB9IGVsc2UgaWYgKGlzVGh1bmsoYSkgfHwgaXNUaHVuayhiKSkge1xuICAgICAgICB0aHVua3MoYSwgYiwgcGF0Y2gsIGluZGV4KVxuICAgIH0gZWxzZSBpZiAoaXNWTm9kZShiKSkge1xuICAgICAgICBpZiAoaXNWTm9kZShhKSkge1xuICAgICAgICAgICAgaWYgKGEudGFnTmFtZSA9PT0gYi50YWdOYW1lICYmXG4gICAgICAgICAgICAgICAgYS5uYW1lc3BhY2UgPT09IGIubmFtZXNwYWNlICYmXG4gICAgICAgICAgICAgICAgYS5rZXkgPT09IGIua2V5KSB7XG4gICAgICAgICAgICAgICAgdmFyIHByb3BzUGF0Y2ggPSBkaWZmUHJvcHMoYS5wcm9wZXJ0aWVzLCBiLnByb3BlcnRpZXMsIGIuaG9va3MpXG4gICAgICAgICAgICAgICAgaWYgKHByb3BzUGF0Y2gpIHtcbiAgICAgICAgICAgICAgICAgICAgYXBwbHkgPSBhcHBlbmRQYXRjaChhcHBseSxcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBWUGF0Y2goVlBhdGNoLlBST1BTLCBhLCBwcm9wc1BhdGNoKSlcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGFwcGx5ID0gYXBwZW5kUGF0Y2goYXBwbHksIG5ldyBWUGF0Y2goVlBhdGNoLlZOT0RFLCBhLCBiKSlcbiAgICAgICAgICAgICAgICBkZXN0cm95V2lkZ2V0cyhhLCBwYXRjaCwgaW5kZXgpXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGFwcGx5ID0gZGlmZkNoaWxkcmVuKGEsIGIsIHBhdGNoLCBhcHBseSwgaW5kZXgpXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBhcHBseSA9IGFwcGVuZFBhdGNoKGFwcGx5LCBuZXcgVlBhdGNoKFZQYXRjaC5WTk9ERSwgYSwgYikpXG4gICAgICAgICAgICBkZXN0cm95V2lkZ2V0cyhhLCBwYXRjaCwgaW5kZXgpXG4gICAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGlzVlRleHQoYikpIHtcbiAgICAgICAgaWYgKCFpc1ZUZXh0KGEpKSB7XG4gICAgICAgICAgICBhcHBseSA9IGFwcGVuZFBhdGNoKGFwcGx5LCBuZXcgVlBhdGNoKFZQYXRjaC5WVEVYVCwgYSwgYikpXG4gICAgICAgICAgICBkZXN0cm95V2lkZ2V0cyhhLCBwYXRjaCwgaW5kZXgpXG4gICAgICAgIH0gZWxzZSBpZiAoYS50ZXh0ICE9PSBiLnRleHQpIHtcbiAgICAgICAgICAgIGFwcGx5ID0gYXBwZW5kUGF0Y2goYXBwbHksIG5ldyBWUGF0Y2goVlBhdGNoLlZURVhULCBhLCBiKSlcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNXaWRnZXQoYikpIHtcbiAgICAgICAgYXBwbHkgPSBhcHBlbmRQYXRjaChhcHBseSwgbmV3IFZQYXRjaChWUGF0Y2guV0lER0VULCBhLCBiKSlcblxuICAgICAgICBpZiAoIWlzV2lkZ2V0KGEpKSB7XG4gICAgICAgICAgICBkZXN0cm95V2lkZ2V0cyhhLCBwYXRjaCwgaW5kZXgpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoYXBwbHkpIHtcbiAgICAgICAgcGF0Y2hbaW5kZXhdID0gYXBwbHlcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGRpZmZQcm9wcyhhLCBiLCBob29rcykge1xuICAgIHZhciBkaWZmXG5cbiAgICBmb3IgKHZhciBhS2V5IGluIGEpIHtcbiAgICAgICAgaWYgKCEoYUtleSBpbiBiKSkge1xuICAgICAgICAgICAgZGlmZiA9IGRpZmYgfHwge31cbiAgICAgICAgICAgIGRpZmZbYUtleV0gPSB1bmRlZmluZWRcbiAgICAgICAgfVxuXG4gICAgICAgIHZhciBhVmFsdWUgPSBhW2FLZXldXG4gICAgICAgIHZhciBiVmFsdWUgPSBiW2FLZXldXG5cbiAgICAgICAgaWYgKGhvb2tzICYmIGFLZXkgaW4gaG9va3MpIHtcbiAgICAgICAgICAgIGRpZmYgPSBkaWZmIHx8IHt9XG4gICAgICAgICAgICBkaWZmW2FLZXldID0gYlZhbHVlXG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoaXNPYmplY3QoYVZhbHVlKSAmJiBpc09iamVjdChiVmFsdWUpKSB7XG4gICAgICAgICAgICAgICAgaWYgKGdldFByb3RvdHlwZShiVmFsdWUpICE9PSBnZXRQcm90b3R5cGUoYVZhbHVlKSkge1xuICAgICAgICAgICAgICAgICAgICBkaWZmID0gZGlmZiB8fCB7fVxuICAgICAgICAgICAgICAgICAgICBkaWZmW2FLZXldID0gYlZhbHVlXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG9iamVjdERpZmYgPSBkaWZmUHJvcHMoYVZhbHVlLCBiVmFsdWUpXG4gICAgICAgICAgICAgICAgICAgIGlmIChvYmplY3REaWZmKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaWZmID0gZGlmZiB8fCB7fVxuICAgICAgICAgICAgICAgICAgICAgICAgZGlmZlthS2V5XSA9IG9iamVjdERpZmZcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSBpZiAoYVZhbHVlICE9PSBiVmFsdWUpIHtcbiAgICAgICAgICAgICAgICBkaWZmID0gZGlmZiB8fCB7fVxuICAgICAgICAgICAgICAgIGRpZmZbYUtleV0gPSBiVmFsdWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGJLZXkgaW4gYikge1xuICAgICAgICBpZiAoIShiS2V5IGluIGEpKSB7XG4gICAgICAgICAgICBkaWZmID0gZGlmZiB8fCB7fVxuICAgICAgICAgICAgZGlmZltiS2V5XSA9IGJbYktleV1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBkaWZmXG59XG5cbmZ1bmN0aW9uIGdldFByb3RvdHlwZSh2YWx1ZSkge1xuICAgIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YpIHtcbiAgICAgICAgcmV0dXJuIE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSlcbiAgICB9IGVsc2UgaWYgKHZhbHVlLl9fcHJvdG9fXykge1xuICAgICAgICByZXR1cm4gdmFsdWUuX19wcm90b19fXG4gICAgfSBlbHNlIGlmICh2YWx1ZS5jb25zdHJ1Y3Rvcikge1xuICAgICAgICByZXR1cm4gdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlXG4gICAgfVxufVxuXG5mdW5jdGlvbiBkaWZmQ2hpbGRyZW4oYSwgYiwgcGF0Y2gsIGFwcGx5LCBpbmRleCkge1xuICAgIHZhciBhQ2hpbGRyZW4gPSBhLmNoaWxkcmVuXG4gICAgdmFyIGJDaGlsZHJlbiA9IHJlb3JkZXIoYUNoaWxkcmVuLCBiLmNoaWxkcmVuKVxuXG4gICAgdmFyIGFMZW4gPSBhQ2hpbGRyZW4ubGVuZ3RoXG4gICAgdmFyIGJMZW4gPSBiQ2hpbGRyZW4ubGVuZ3RoXG4gICAgdmFyIGxlbiA9IGFMZW4gPiBiTGVuID8gYUxlbiA6IGJMZW5cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgdmFyIGxlZnROb2RlID0gYUNoaWxkcmVuW2ldXG4gICAgICAgIHZhciByaWdodE5vZGUgPSBiQ2hpbGRyZW5baV1cbiAgICAgICAgaW5kZXggKz0gMVxuXG4gICAgICAgIGlmICghbGVmdE5vZGUpIHtcbiAgICAgICAgICAgIGlmIChyaWdodE5vZGUpIHtcbiAgICAgICAgICAgICAgICAvLyBFeGNlc3Mgbm9kZXMgaW4gYiBuZWVkIHRvIGJlIGFkZGVkXG4gICAgICAgICAgICAgICAgYXBwbHkgPSBhcHBlbmRQYXRjaChhcHBseSxcbiAgICAgICAgICAgICAgICAgICAgbmV3IFZQYXRjaChWUGF0Y2guSU5TRVJULCBudWxsLCByaWdodE5vZGUpKVxuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKCFyaWdodE5vZGUpIHtcbiAgICAgICAgICAgIGlmIChsZWZ0Tm9kZSkge1xuICAgICAgICAgICAgICAgIC8vIEV4Y2VzcyBub2RlcyBpbiBhIG5lZWQgdG8gYmUgcmVtb3ZlZFxuICAgICAgICAgICAgICAgIHBhdGNoW2luZGV4XSA9IG5ldyBWUGF0Y2goVlBhdGNoLlJFTU9WRSwgbGVmdE5vZGUsIG51bGwpXG4gICAgICAgICAgICAgICAgZGVzdHJveVdpZGdldHMobGVmdE5vZGUsIHBhdGNoLCBpbmRleClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdhbGsobGVmdE5vZGUsIHJpZ2h0Tm9kZSwgcGF0Y2gsIGluZGV4KVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGlzVk5vZGUobGVmdE5vZGUpICYmIGxlZnROb2RlLmNvdW50KSB7XG4gICAgICAgICAgICBpbmRleCArPSBsZWZ0Tm9kZS5jb3VudFxuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGJDaGlsZHJlbi5tb3Zlcykge1xuICAgICAgICAvLyBSZW9yZGVyIG5vZGVzIGxhc3RcbiAgICAgICAgYXBwbHkgPSBhcHBlbmRQYXRjaChhcHBseSwgbmV3IFZQYXRjaChWUGF0Y2guT1JERVIsIGEsIGJDaGlsZHJlbi5tb3ZlcykpXG4gICAgfVxuXG4gICAgcmV0dXJuIGFwcGx5XG59XG5cbi8vIFBhdGNoIHJlY29yZHMgZm9yIGFsbCBkZXN0cm95ZWQgd2lkZ2V0cyBtdXN0IGJlIGFkZGVkIGJlY2F1c2Ugd2UgbmVlZFxuLy8gYSBET00gbm9kZSByZWZlcmVuY2UgZm9yIHRoZSBkZXN0cm95IGZ1bmN0aW9uXG5mdW5jdGlvbiBkZXN0cm95V2lkZ2V0cyh2Tm9kZSwgcGF0Y2gsIGluZGV4KSB7XG4gICAgaWYgKGlzV2lkZ2V0KHZOb2RlKSkge1xuICAgICAgICBpZiAodHlwZW9mIHZOb2RlLmRlc3Ryb3kgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICAgICAgcGF0Y2hbaW5kZXhdID0gbmV3IFZQYXRjaChWUGF0Y2guUkVNT1ZFLCB2Tm9kZSwgbnVsbClcbiAgICAgICAgfVxuICAgIH0gZWxzZSBpZiAoaXNWTm9kZSh2Tm9kZSkgJiYgdk5vZGUuaGFzV2lkZ2V0cykge1xuICAgICAgICB2YXIgY2hpbGRyZW4gPSB2Tm9kZS5jaGlsZHJlblxuICAgICAgICB2YXIgbGVuID0gY2hpbGRyZW4ubGVuZ3RoXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICAgIHZhciBjaGlsZCA9IGNoaWxkcmVuW2ldXG4gICAgICAgICAgICBpbmRleCArPSAxXG5cbiAgICAgICAgICAgIGRlc3Ryb3lXaWRnZXRzKGNoaWxkLCBwYXRjaCwgaW5kZXgpXG5cbiAgICAgICAgICAgIGlmIChpc1ZOb2RlKGNoaWxkKSAmJiBjaGlsZC5jb3VudCkge1xuICAgICAgICAgICAgICAgIGluZGV4ICs9IGNoaWxkLmNvdW50XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG59XG5cbi8vIENyZWF0ZSBhIHN1Yi1wYXRjaCBmb3IgdGh1bmtzXG5mdW5jdGlvbiB0aHVua3MoYSwgYiwgcGF0Y2gsIGluZGV4KSB7XG4gICAgdmFyIG5vZGVzID0gaGFuZGxlVGh1bmsoYSwgYik7XG4gICAgdmFyIHRodW5rUGF0Y2ggPSBkaWZmKG5vZGVzLmEsIG5vZGVzLmIpXG4gICAgaWYgKGhhc1BhdGNoZXModGh1bmtQYXRjaCkpIHtcbiAgICAgICAgcGF0Y2hbaW5kZXhdID0gbmV3IFZQYXRjaChWUGF0Y2guVEhVTkssIG51bGwsIHRodW5rUGF0Y2gpXG4gICAgfVxufVxuXG5mdW5jdGlvbiBoYXNQYXRjaGVzKHBhdGNoKSB7XG4gICAgZm9yICh2YXIgaW5kZXggaW4gcGF0Y2gpIHtcbiAgICAgICAgaWYgKGluZGV4ICE9PSBcImFcIikge1xuICAgICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZmFsc2U7XG59XG5cbi8vIEV4ZWN1dGUgaG9va3Mgd2hlbiB0d28gbm9kZXMgYXJlIGlkZW50aWNhbFxuZnVuY3Rpb24gaG9va3Modk5vZGUsIHBhdGNoLCBpbmRleCkge1xuICAgIGlmIChpc1ZOb2RlKHZOb2RlKSkge1xuICAgICAgICBpZiAodk5vZGUuaG9va3MpIHtcbiAgICAgICAgICAgIHBhdGNoW2luZGV4XSA9IG5ldyBWUGF0Y2goVlBhdGNoLlBST1BTLCB2Tm9kZS5ob29rcywgdk5vZGUuaG9va3MpXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodk5vZGUuZGVzY2VuZGFudEhvb2tzKSB7XG4gICAgICAgICAgICB2YXIgY2hpbGRyZW4gPSB2Tm9kZS5jaGlsZHJlblxuICAgICAgICAgICAgdmFyIGxlbiA9IGNoaWxkcmVuLmxlbmd0aFxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IGNoaWxkcmVuW2ldXG4gICAgICAgICAgICAgICAgaW5kZXggKz0gMVxuXG4gICAgICAgICAgICAgICAgaG9va3MoY2hpbGQsIHBhdGNoLCBpbmRleClcblxuICAgICAgICAgICAgICAgIGlmIChpc1ZOb2RlKGNoaWxkKSAmJiBjaGlsZC5jb3VudCkge1xuICAgICAgICAgICAgICAgICAgICBpbmRleCArPSBjaGlsZC5jb3VudFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuLy8gTGlzdCBkaWZmLCBuYWl2ZSBsZWZ0IHRvIHJpZ2h0IHJlb3JkZXJpbmdcbmZ1bmN0aW9uIHJlb3JkZXIoYUNoaWxkcmVuLCBiQ2hpbGRyZW4pIHtcblxuICAgIHZhciBiS2V5cyA9IGtleUluZGV4KGJDaGlsZHJlbilcblxuICAgIGlmICghYktleXMpIHtcbiAgICAgICAgcmV0dXJuIGJDaGlsZHJlblxuICAgIH1cblxuICAgIHZhciBhS2V5cyA9IGtleUluZGV4KGFDaGlsZHJlbilcblxuICAgIGlmICghYUtleXMpIHtcbiAgICAgICAgcmV0dXJuIGJDaGlsZHJlblxuICAgIH1cblxuICAgIHZhciBiTWF0Y2ggPSB7fSwgYU1hdGNoID0ge31cblxuICAgIGZvciAodmFyIGtleSBpbiBiS2V5cykge1xuICAgICAgICBiTWF0Y2hbYktleXNba2V5XV0gPSBhS2V5c1trZXldXG4gICAgfVxuXG4gICAgZm9yICh2YXIga2V5IGluIGFLZXlzKSB7XG4gICAgICAgIGFNYXRjaFthS2V5c1trZXldXSA9IGJLZXlzW2tleV1cbiAgICB9XG5cbiAgICB2YXIgYUxlbiA9IGFDaGlsZHJlbi5sZW5ndGhcbiAgICB2YXIgYkxlbiA9IGJDaGlsZHJlbi5sZW5ndGhcbiAgICB2YXIgbGVuID0gYUxlbiA+IGJMZW4gPyBhTGVuIDogYkxlblxuICAgIHZhciBzaHVmZmxlID0gW11cbiAgICB2YXIgZnJlZUluZGV4ID0gMFxuICAgIHZhciBpID0gMFxuICAgIHZhciBtb3ZlSW5kZXggPSAwXG4gICAgdmFyIG1vdmVzID0ge31cbiAgICB2YXIgcmVtb3ZlcyA9IG1vdmVzLnJlbW92ZXMgPSB7fVxuICAgIHZhciByZXZlcnNlID0gbW92ZXMucmV2ZXJzZSA9IHt9XG4gICAgdmFyIGhhc01vdmVzID0gZmFsc2VcblxuICAgIHdoaWxlIChmcmVlSW5kZXggPCBsZW4pIHtcbiAgICAgICAgdmFyIG1vdmUgPSBhTWF0Y2hbaV1cbiAgICAgICAgaWYgKG1vdmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc2h1ZmZsZVtpXSA9IGJDaGlsZHJlblttb3ZlXVxuICAgICAgICAgICAgaWYgKG1vdmUgIT09IG1vdmVJbmRleCkge1xuICAgICAgICAgICAgICAgIG1vdmVzW21vdmVdID0gbW92ZUluZGV4XG4gICAgICAgICAgICAgICAgcmV2ZXJzZVttb3ZlSW5kZXhdID0gbW92ZVxuICAgICAgICAgICAgICAgIGhhc01vdmVzID0gdHJ1ZVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgbW92ZUluZGV4KytcbiAgICAgICAgfSBlbHNlIGlmIChpIGluIGFNYXRjaCkge1xuICAgICAgICAgICAgc2h1ZmZsZVtpXSA9IHVuZGVmaW5lZFxuICAgICAgICAgICAgcmVtb3Zlc1tpXSA9IG1vdmVJbmRleCsrXG4gICAgICAgICAgICBoYXNNb3ZlcyA9IHRydWVcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHdoaWxlIChiTWF0Y2hbZnJlZUluZGV4XSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgZnJlZUluZGV4KytcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGZyZWVJbmRleCA8IGxlbikge1xuICAgICAgICAgICAgICAgIHZhciBmcmVlQ2hpbGQgPSBiQ2hpbGRyZW5bZnJlZUluZGV4XVxuICAgICAgICAgICAgICAgIGlmIChmcmVlQ2hpbGQpIHtcbiAgICAgICAgICAgICAgICAgICAgc2h1ZmZsZVtpXSA9IGZyZWVDaGlsZFxuICAgICAgICAgICAgICAgICAgICBpZiAoZnJlZUluZGV4ICE9PSBtb3ZlSW5kZXgpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGhhc01vdmVzID0gdHJ1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgbW92ZXNbZnJlZUluZGV4XSA9IG1vdmVJbmRleFxuICAgICAgICAgICAgICAgICAgICAgICAgcmV2ZXJzZVttb3ZlSW5kZXhdID0gZnJlZUluZGV4XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgbW92ZUluZGV4KytcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgZnJlZUluZGV4KytcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpKytcbiAgICB9XG5cbiAgICBpZiAoaGFzTW92ZXMpIHtcbiAgICAgICAgc2h1ZmZsZS5tb3ZlcyA9IG1vdmVzXG4gICAgfVxuXG4gICAgcmV0dXJuIHNodWZmbGVcbn1cblxuZnVuY3Rpb24ga2V5SW5kZXgoY2hpbGRyZW4pIHtcbiAgICB2YXIgaSwga2V5c1xuXG4gICAgZm9yIChpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IGNoaWxkcmVuW2ldXG5cbiAgICAgICAgaWYgKGNoaWxkLmtleSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBrZXlzID0ga2V5cyB8fCB7fVxuICAgICAgICAgICAga2V5c1tjaGlsZC5rZXldID0gaVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIGtleXNcbn1cblxuZnVuY3Rpb24gYXBwZW5kUGF0Y2goYXBwbHksIHBhdGNoKSB7XG4gICAgaWYgKGFwcGx5KSB7XG4gICAgICAgIGlmIChpc0FycmF5KGFwcGx5KSkge1xuICAgICAgICAgICAgYXBwbHkucHVzaChwYXRjaClcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGFwcGx5ID0gW2FwcGx5LCBwYXRjaF1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBhcHBseVxuICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiBwYXRjaFxuICAgIH1cbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlL2RpZmYuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGlzVk5vZGUgPSByZXF1aXJlKFwiLi9pcy12bm9kZVwiKVxudmFyIGlzVlRleHQgPSByZXF1aXJlKFwiLi9pcy12dGV4dFwiKVxudmFyIGlzV2lkZ2V0ID0gcmVxdWlyZShcIi4vaXMtd2lkZ2V0XCIpXG52YXIgaXNUaHVuayA9IHJlcXVpcmUoXCIuL2lzLXRodW5rXCIpXG5cbm1vZHVsZS5leHBvcnRzID0gaGFuZGxlVGh1bmtcblxuZnVuY3Rpb24gaGFuZGxlVGh1bmsoYSwgYikge1xuICAgIHZhciByZW5kZXJlZEEgPSBhXG4gICAgdmFyIHJlbmRlcmVkQiA9IGJcblxuICAgIGlmIChpc1RodW5rKGIpKSB7XG4gICAgICAgIHJlbmRlcmVkQiA9IHJlbmRlclRodW5rKGIsIGEpXG4gICAgfVxuXG4gICAgaWYgKGlzVGh1bmsoYSkpIHtcbiAgICAgICAgcmVuZGVyZWRBID0gcmVuZGVyVGh1bmsoYSwgbnVsbClcbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgICBhOiByZW5kZXJlZEEsXG4gICAgICAgIGI6IHJlbmRlcmVkQlxuICAgIH1cbn1cblxuZnVuY3Rpb24gcmVuZGVyVGh1bmsodGh1bmssIHByZXZpb3VzKSB7XG4gICAgdmFyIHJlbmRlcmVkVGh1bmsgPSB0aHVuay52bm9kZVxuXG4gICAgaWYgKCFyZW5kZXJlZFRodW5rKSB7XG4gICAgICAgIHJlbmRlcmVkVGh1bmsgPSB0aHVuay52bm9kZSA9IHRodW5rLnJlbmRlcihwcmV2aW91cylcbiAgICB9XG5cbiAgICBpZiAoIShpc1ZOb2RlKHJlbmRlcmVkVGh1bmspIHx8XG4gICAgICAgICAgICBpc1ZUZXh0KHJlbmRlcmVkVGh1bmspIHx8XG4gICAgICAgICAgICBpc1dpZGdldChyZW5kZXJlZFRodW5rKSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwidGh1bmsgZGlkIG5vdCByZXR1cm4gYSB2YWxpZCBub2RlXCIpO1xuICAgIH1cblxuICAgIHJldHVybiByZW5kZXJlZFRodW5rXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92dHJlZS9oYW5kbGUtdGh1bmsuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xubW9kdWxlLmV4cG9ydHMgPSBpc1RodW5rXHJcblxyXG5mdW5jdGlvbiBpc1RodW5rKHQpIHtcclxuICAgIHJldHVybiB0ICYmIHQudHlwZSA9PT0gXCJUaHVua1wiXHJcbn1cclxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdnRyZWUvaXMtdGh1bmsuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xubW9kdWxlLmV4cG9ydHMgPSBpc0hvb2tcblxuZnVuY3Rpb24gaXNIb29rKGhvb2spIHtcbiAgICByZXR1cm4gaG9vayAmJiB0eXBlb2YgaG9vay5ob29rID09PSBcImZ1bmN0aW9uXCIgJiZcbiAgICAgICAgIWhvb2suaGFzT3duUHJvcGVydHkoXCJob29rXCIpXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92dHJlZS9pcy12aG9vay5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdnRyZWVcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgdmVyc2lvbiA9IHJlcXVpcmUoXCIuL3ZlcnNpb25cIilcblxubW9kdWxlLmV4cG9ydHMgPSBpc1ZpcnR1YWxOb2RlXG5cbmZ1bmN0aW9uIGlzVmlydHVhbE5vZGUoeCkge1xuICAgIHJldHVybiB4ICYmIHgudHlwZSA9PT0gXCJWaXJ0dWFsTm9kZVwiICYmIHgudmVyc2lvbiA9PT0gdmVyc2lvblxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdnRyZWUvaXMtdm5vZGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIHZlcnNpb24gPSByZXF1aXJlKFwiLi92ZXJzaW9uXCIpXG5cbm1vZHVsZS5leHBvcnRzID0gaXNWaXJ0dWFsVGV4dFxuXG5mdW5jdGlvbiBpc1ZpcnR1YWxUZXh0KHgpIHtcbiAgICByZXR1cm4geCAmJiB4LnR5cGUgPT09IFwiVmlydHVhbFRleHRcIiAmJiB4LnZlcnNpb24gPT09IHZlcnNpb25cbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlL2lzLXZ0ZXh0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92dHJlZVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzID0gaXNXaWRnZXRcblxuZnVuY3Rpb24gaXNXaWRnZXQodykge1xuICAgIHJldHVybiB3ICYmIHcudHlwZSA9PT0gXCJXaWRnZXRcIlxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdnRyZWUvaXMtd2lkZ2V0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL25vZGVfbW9kdWxlcy92dHJlZVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzID0gXCIxXCJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlL3ZlcnNpb24uanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIHZlcnNpb24gPSByZXF1aXJlKFwiLi92ZXJzaW9uXCIpXG5cblZpcnR1YWxQYXRjaC5OT05FID0gMFxuVmlydHVhbFBhdGNoLlZURVhUID0gMVxuVmlydHVhbFBhdGNoLlZOT0RFID0gMlxuVmlydHVhbFBhdGNoLldJREdFVCA9IDNcblZpcnR1YWxQYXRjaC5QUk9QUyA9IDRcblZpcnR1YWxQYXRjaC5PUkRFUiA9IDVcblZpcnR1YWxQYXRjaC5JTlNFUlQgPSA2XG5WaXJ0dWFsUGF0Y2guUkVNT1ZFID0gN1xuVmlydHVhbFBhdGNoLlRIVU5LID0gOFxuXG5tb2R1bGUuZXhwb3J0cyA9IFZpcnR1YWxQYXRjaFxuXG5mdW5jdGlvbiBWaXJ0dWFsUGF0Y2godHlwZSwgdk5vZGUsIHBhdGNoKSB7XG4gICAgdGhpcy50eXBlID0gTnVtYmVyKHR5cGUpXG4gICAgdGhpcy52Tm9kZSA9IHZOb2RlXG4gICAgdGhpcy5wYXRjaCA9IHBhdGNoXG59XG5cblZpcnR1YWxQYXRjaC5wcm90b3R5cGUudmVyc2lvbiA9IHZlcnNpb25cblZpcnR1YWxQYXRjaC5wcm90b3R5cGUudHlwZSA9IFwiVmlydHVhbFBhdGNoXCJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3Z0cmVlL3ZwYXRjaC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWRvbS9ub2RlX21vZHVsZXMvdnRyZWVcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgbmF0aXZlSXNBcnJheSA9IEFycmF5LmlzQXJyYXlcbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmdcblxubW9kdWxlLmV4cG9ydHMgPSBuYXRpdmVJc0FycmF5IHx8IGlzQXJyYXlcblxuZnVuY3Rpb24gaXNBcnJheShvYmopIHtcbiAgICByZXR1cm4gdG9TdHJpbmcuY2FsbChvYmopID09PSBcIltvYmplY3QgQXJyYXldXCJcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3gtaXMtYXJyYXkvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1kb20vbm9kZV9tb2R1bGVzL3gtaXMtYXJyYXlcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgcGF0Y2ggPSByZXF1aXJlKFwidmRvbS9wYXRjaFwiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IHBhdGNoXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tL3BhdGNoLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtZG9tXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xubW9kdWxlLmV4cG9ydHMgPSBBdHRyaWJ1dGVIb29rO1xuXG5mdW5jdGlvbiBBdHRyaWJ1dGVIb29rKHZhbHVlKSB7XG4gICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIEF0dHJpYnV0ZUhvb2spKSB7XG4gICAgICAgIHJldHVybiBuZXcgQXR0cmlidXRlSG9vayh2YWx1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xufVxuXG5BdHRyaWJ1dGVIb29rLnByb3RvdHlwZS5ob29rID0gZnVuY3Rpb24gKG5vZGUsIHByb3AsIHByZXYpIHtcbiAgICBpZiAocHJldiAmJiBwcmV2LnZhbHVlID09PSB0aGlzLnZhbHVlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBub2RlLnNldEF0dHJpYnV0ZU5TKG51bGwsIHByb3AsIHRoaXMudmFsdWUpXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvaG9va3MvYXR0cmlidXRlLWhvb2suanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ob29rc1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBEYXRhU2V0ID0gcmVxdWlyZShcImRhdGEtc2V0XCIpXG5cbm1vZHVsZS5leHBvcnRzID0gRGF0YVNldEhvb2s7XG5cbmZ1bmN0aW9uIERhdGFTZXRIb29rKHZhbHVlKSB7XG4gICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIERhdGFTZXRIb29rKSkge1xuICAgICAgICByZXR1cm4gbmV3IERhdGFTZXRIb29rKHZhbHVlKTtcbiAgICB9XG5cbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG59XG5cbkRhdGFTZXRIb29rLnByb3RvdHlwZS5ob29rID0gZnVuY3Rpb24gKG5vZGUsIHByb3BlcnR5TmFtZSkge1xuICAgIHZhciBkcyA9IERhdGFTZXQobm9kZSlcbiAgICB2YXIgcHJvcE5hbWUgPSBwcm9wZXJ0eU5hbWUuc3Vic3RyKDUpXG5cbiAgICBkc1twcm9wTmFtZV0gPSB0aGlzLnZhbHVlO1xufTtcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ob29rcy9kYXRhLXNldC1ob29rLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvaG9va3NcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgRGF0YVNldCA9IHJlcXVpcmUoXCJkYXRhLXNldFwiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IERhdGFTZXRIb29rO1xuXG5mdW5jdGlvbiBEYXRhU2V0SG9vayh2YWx1ZSkge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBEYXRhU2V0SG9vaykpIHtcbiAgICAgICAgcmV0dXJuIG5ldyBEYXRhU2V0SG9vayh2YWx1ZSk7XG4gICAgfVxuXG4gICAgdGhpcy52YWx1ZSA9IHZhbHVlO1xufVxuXG5EYXRhU2V0SG9vay5wcm90b3R5cGUuaG9vayA9IGZ1bmN0aW9uIChub2RlLCBwcm9wZXJ0eU5hbWUpIHtcbiAgICB2YXIgZHMgPSBEYXRhU2V0KG5vZGUpXG4gICAgdmFyIHByb3BOYW1lID0gcHJvcGVydHlOYW1lLnN1YnN0cigzKVxuXG4gICAgZHNbcHJvcE5hbWVdID0gdGhpcy52YWx1ZTtcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvaG9va3MvZXYtaG9vay5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L2hvb2tzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xubW9kdWxlLmV4cG9ydHMgPSBTb2Z0U2V0SG9vaztcblxuZnVuY3Rpb24gU29mdFNldEhvb2sodmFsdWUpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgU29mdFNldEhvb2spKSB7XG4gICAgICAgIHJldHVybiBuZXcgU29mdFNldEhvb2sodmFsdWUpO1xuICAgIH1cblxuICAgIHRoaXMudmFsdWUgPSB2YWx1ZTtcbn1cblxuU29mdFNldEhvb2sucHJvdG90eXBlLmhvb2sgPSBmdW5jdGlvbiAobm9kZSwgcHJvcGVydHlOYW1lKSB7XG4gICAgaWYgKG5vZGVbcHJvcGVydHlOYW1lXSAhPT0gdGhpcy52YWx1ZSkge1xuICAgICAgICBub2RlW3Byb3BlcnR5TmFtZV0gPSB0aGlzLnZhbHVlO1xuICAgIH1cbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvaG9va3Mvc29mdC1zZXQtaG9vay5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L2hvb2tzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIFZOb2RlID0gcmVxdWlyZShcInZ0cmVlL3Zub2RlLmpzXCIpXG52YXIgVlRleHQgPSByZXF1aXJlKFwidnRyZWUvdnRleHQuanNcIilcbnZhciBpc1ZOb2RlID0gcmVxdWlyZShcInZ0cmVlL2lzLXZub2RlXCIpXG52YXIgaXNWVGV4dCA9IHJlcXVpcmUoXCJ2dHJlZS9pcy12dGV4dFwiKVxudmFyIGlzV2lkZ2V0ID0gcmVxdWlyZShcInZ0cmVlL2lzLXdpZGdldFwiKVxudmFyIGlzSG9vayA9IHJlcXVpcmUoXCJ2dHJlZS9pcy12aG9va1wiKVxudmFyIGlzVlRodW5rID0gcmVxdWlyZShcInZ0cmVlL2lzLXRodW5rXCIpXG52YXIgVHlwZWRFcnJvciA9IHJlcXVpcmUoXCJlcnJvci90eXBlZFwiKVxuXG52YXIgcGFyc2VUYWcgPSByZXF1aXJlKFwiLi9wYXJzZS10YWcuanNcIilcbnZhciBzb2Z0U2V0SG9vayA9IHJlcXVpcmUoXCIuL2hvb2tzL3NvZnQtc2V0LWhvb2suanNcIilcbnZhciBkYXRhU2V0SG9vayA9IHJlcXVpcmUoXCIuL2hvb2tzL2RhdGEtc2V0LWhvb2suanNcIilcbnZhciBldkhvb2sgPSByZXF1aXJlKFwiLi9ob29rcy9ldi1ob29rLmpzXCIpXG5cbnZhciBVbmV4cGVjdGVkVmlydHVhbEVsZW1lbnQgPSBUeXBlZEVycm9yKHtcbiAgICB0eXBlOiBcInZpcnR1YWwtaHlwZXJzY3JpcHQudW5leHBlY3RlZC52aXJ0dWFsLWVsZW1lbnRcIixcbiAgICBtZXNzYWdlOiBcIlVuZXhwZWN0ZWQgdmlydHVhbCBjaGlsZCBwYXNzZWQgdG8gaCgpLlxcblwiICtcbiAgICAgICAgXCJFeHBlY3RlZCBhIFZOb2RlIC8gVnRodW5rIC8gVldpZGdldCAvIHN0cmluZyBidXQ6XFxuXCIgK1xuICAgICAgICBcImdvdCBhIHtmb3JlaWduT2JqZWN0U3RyfS5cXG5cIiArXG4gICAgICAgIFwiVGhlIHBhcmVudCB2bm9kZSBpcyB7cGFyZW50Vm5vZGVTdHJ9LlxcblwiICtcbiAgICAgICAgXCJTdWdnZXN0ZWQgZml4OiBjaGFuZ2UgeW91ciBgaCguLi4sIFsgLi4uIF0pYCBjYWxsc2l0ZS5cIixcbiAgICBmb3JlaWduT2JqZWN0U3RyOiBudWxsLFxuICAgIHBhcmVudFZub2RlU3RyOiBudWxsLFxuICAgIGZvcmVpZ25PYmplY3Q6IG51bGwsXG4gICAgcGFyZW50Vm5vZGU6IG51bGxcbn0pXG5cbm1vZHVsZS5leHBvcnRzID0gaFxuXG5mdW5jdGlvbiBoKHRhZ05hbWUsIHByb3BlcnRpZXMsIGNoaWxkcmVuKSB7XG4gICAgdmFyIGNoaWxkTm9kZXMgPSBbXVxuICAgIHZhciB0YWcsIHByb3BzLCBrZXksIG5hbWVzcGFjZVxuXG4gICAgaWYgKCFjaGlsZHJlbiAmJiBpc0NoaWxkcmVuKHByb3BlcnRpZXMpKSB7XG4gICAgICAgIGNoaWxkcmVuID0gcHJvcGVydGllc1xuICAgICAgICBwcm9wcyA9IHt9XG4gICAgfVxuXG4gICAgcHJvcHMgPSBwcm9wcyB8fCBwcm9wZXJ0aWVzIHx8IHt9XG4gICAgdGFnID0gcGFyc2VUYWcodGFnTmFtZSwgcHJvcHMpXG5cbiAgICAvLyBzdXBwb3J0IGtleXNcbiAgICBpZiAoXCJrZXlcIiBpbiBwcm9wcykge1xuICAgICAgICBrZXkgPSBwcm9wcy5rZXlcbiAgICAgICAgcHJvcHMua2V5ID0gdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgLy8gc3VwcG9ydCBuYW1lc3BhY2VcbiAgICBpZiAoXCJuYW1lc3BhY2VcIiBpbiBwcm9wcykge1xuICAgICAgICBuYW1lc3BhY2UgPSBwcm9wcy5uYW1lc3BhY2VcbiAgICAgICAgcHJvcHMubmFtZXNwYWNlID0gdW5kZWZpbmVkXG4gICAgfVxuXG4gICAgLy8gZml4IGN1cnNvciBidWdcbiAgICBpZiAodGFnID09PSBcImlucHV0XCIgJiZcbiAgICAgICAgXCJ2YWx1ZVwiIGluIHByb3BzICYmXG4gICAgICAgIHByb3BzLnZhbHVlICE9PSB1bmRlZmluZWQgJiZcbiAgICAgICAgIWlzSG9vayhwcm9wcy52YWx1ZSlcbiAgICApIHtcbiAgICAgICAgcHJvcHMudmFsdWUgPSBzb2Z0U2V0SG9vayhwcm9wcy52YWx1ZSlcbiAgICB9XG5cbiAgICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHByb3BzKVxuICAgIHZhciBwcm9wTmFtZSwgdmFsdWVcbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IGtleXMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgcHJvcE5hbWUgPSBrZXlzW2pdXG4gICAgICAgIHZhbHVlID0gcHJvcHNbcHJvcE5hbWVdXG4gICAgICAgIGlmIChpc0hvb2sodmFsdWUpKSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gYWRkIGRhdGEtZm9vIHN1cHBvcnRcbiAgICAgICAgaWYgKHByb3BOYW1lLnN1YnN0cigwLCA1KSA9PT0gXCJkYXRhLVwiKSB7XG4gICAgICAgICAgICBwcm9wc1twcm9wTmFtZV0gPSBkYXRhU2V0SG9vayh2YWx1ZSlcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGFkZCBldi1mb28gc3VwcG9ydFxuICAgICAgICBpZiAocHJvcE5hbWUuc3Vic3RyKDAsIDMpID09PSBcImV2LVwiKSB7XG4gICAgICAgICAgICBwcm9wc1twcm9wTmFtZV0gPSBldkhvb2sodmFsdWUpXG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY2hpbGRyZW4gIT09IHVuZGVmaW5lZCAmJiBjaGlsZHJlbiAhPT0gbnVsbCkge1xuICAgICAgICBhZGRDaGlsZChjaGlsZHJlbiwgY2hpbGROb2RlcywgdGFnLCBwcm9wcylcbiAgICB9XG5cblxuICAgIHZhciBub2RlID0gbmV3IFZOb2RlKHRhZywgcHJvcHMsIGNoaWxkTm9kZXMsIGtleSwgbmFtZXNwYWNlKVxuXG4gICAgcmV0dXJuIG5vZGVcbn1cblxuZnVuY3Rpb24gYWRkQ2hpbGQoYywgY2hpbGROb2RlcywgdGFnLCBwcm9wcykge1xuICAgIGlmICh0eXBlb2YgYyA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgICBjaGlsZE5vZGVzLnB1c2gobmV3IFZUZXh0KGMpKVxuICAgIH0gZWxzZSBpZiAoaXNDaGlsZChjKSkge1xuICAgICAgICBjaGlsZE5vZGVzLnB1c2goYylcbiAgICB9IGVsc2UgaWYgKEFycmF5LmlzQXJyYXkoYykpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBhZGRDaGlsZChjW2ldLCBjaGlsZE5vZGVzLCB0YWcsIHByb3BzKVxuICAgICAgICB9XG4gICAgfSBlbHNlIGlmIChjID09PSBudWxsIHx8IGMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm5cbiAgICB9IGVsc2Uge1xuICAgICAgICB0aHJvdyBVbmV4cGVjdGVkVmlydHVhbEVsZW1lbnQoe1xuICAgICAgICAgICAgZm9yZWlnbk9iamVjdFN0cjogSlNPTi5zdHJpbmdpZnkoYyksXG4gICAgICAgICAgICBmb3JlaWduT2JqZWN0OiBjLFxuICAgICAgICAgICAgcGFyZW50Vm5vZGVTdHI6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICAgICAgICB0YWdOYW1lOiB0YWcsXG4gICAgICAgICAgICAgICAgcHJvcGVydGllczogcHJvcHNcbiAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgcGFyZW50Vm5vZGU6IHtcbiAgICAgICAgICAgICAgICB0YWdOYW1lOiB0YWcsXG4gICAgICAgICAgICAgICAgcHJvcGVydGllczogcHJvcHNcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG59XG5cbmZ1bmN0aW9uIGlzQ2hpbGQoeCkge1xuICAgIHJldHVybiBpc1ZOb2RlKHgpIHx8IGlzVlRleHQoeCkgfHwgaXNXaWRnZXQoeCkgfHwgaXNWVGh1bmsoeClcbn1cblxuZnVuY3Rpb24gaXNDaGlsZHJlbih4KSB7XG4gICAgcmV0dXJuIHR5cGVvZiB4ID09PSBcInN0cmluZ1wiIHx8IEFycmF5LmlzQXJyYXkoeCkgfHwgaXNDaGlsZCh4KVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5tb2R1bGUuZXhwb3J0cyA9IGNyZWF0ZUhhc2hcblxuZnVuY3Rpb24gY3JlYXRlSGFzaChlbGVtKSB7XG4gICAgdmFyIGF0dHJpYnV0ZXMgPSBlbGVtLmF0dHJpYnV0ZXNcbiAgICB2YXIgaGFzaCA9IHt9XG5cbiAgICBpZiAoYXR0cmlidXRlcyA9PT0gbnVsbCB8fCBhdHRyaWJ1dGVzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGhhc2hcbiAgICB9XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGF0dHJpYnV0ZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGF0dHIgPSBhdHRyaWJ1dGVzW2ldXG5cbiAgICAgICAgaWYgKGF0dHIubmFtZS5zdWJzdHIoMCw1KSAhPT0gXCJkYXRhLVwiKSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgaGFzaFthdHRyLm5hbWUuc3Vic3RyKDUpXSA9IGF0dHIudmFsdWVcbiAgICB9XG5cbiAgICByZXR1cm4gaGFzaFxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldC9jcmVhdGUtaGFzaC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBjcmVhdGVTdG9yZSA9IHJlcXVpcmUoXCJ3ZWFrbWFwLXNoaW0vY3JlYXRlLXN0b3JlXCIpXG52YXIgSW5kaXZpZHVhbCA9IHJlcXVpcmUoXCJpbmRpdmlkdWFsXCIpXG5cbnZhciBjcmVhdGVIYXNoID0gcmVxdWlyZShcIi4vY3JlYXRlLWhhc2guanNcIilcblxudmFyIGhhc2hTdG9yZSA9IEluZGl2aWR1YWwoXCJfX0RBVEFfU0VUX1dFQUtNQVBAM1wiLCBjcmVhdGVTdG9yZSgpKVxuXG5tb2R1bGUuZXhwb3J0cyA9IERhdGFTZXRcblxuZnVuY3Rpb24gRGF0YVNldChlbGVtKSB7XG4gICAgdmFyIHN0b3JlID0gaGFzaFN0b3JlKGVsZW0pXG5cbiAgICBpZiAoIXN0b3JlLmhhc2gpIHtcbiAgICAgICAgc3RvcmUuaGFzaCA9IGNyZWF0ZUhhc2goZWxlbSlcbiAgICB9XG5cbiAgICByZXR1cm4gc3RvcmUuaGFzaFxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciByb290ID0gdHlwZW9mIHdpbmRvdyAhPT0gJ3VuZGVmaW5lZCcgP1xuICAgIHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID9cbiAgICBnbG9iYWwgOiB7fTtcblxubW9kdWxlLmV4cG9ydHMgPSBJbmRpdmlkdWFsXG5cbmZ1bmN0aW9uIEluZGl2aWR1YWwoa2V5LCB2YWx1ZSkge1xuICAgIGlmIChyb290W2tleV0pIHtcbiAgICAgICAgcmV0dXJuIHJvb3Rba2V5XVxuICAgIH1cblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyb290LCBrZXksIHtcbiAgICAgICAgdmFsdWU6IHZhbHVlXG4gICAgICAgICwgY29uZmlndXJhYmxlOiB0cnVlXG4gICAgfSlcblxuICAgIHJldHVybiB2YWx1ZVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldC9ub2RlX21vZHVsZXMvaW5kaXZpZHVhbC9pbmRleC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9kYXRhLXNldC9ub2RlX21vZHVsZXMvaW5kaXZpZHVhbFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBoaWRkZW5TdG9yZSA9IHJlcXVpcmUoJy4vaGlkZGVuLXN0b3JlLmpzJyk7XG5cbm1vZHVsZS5leHBvcnRzID0gY3JlYXRlU3RvcmU7XG5cbmZ1bmN0aW9uIGNyZWF0ZVN0b3JlKCkge1xuICAgIHZhciBrZXkgPSB7fTtcblxuICAgIHJldHVybiBmdW5jdGlvbiAob2JqKSB7XG4gICAgICAgIGlmICh0eXBlb2Ygb2JqICE9PSAnb2JqZWN0JyB8fCBvYmogPT09IG51bGwpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignV2Vha21hcC1zaGltOiBLZXkgbXVzdCBiZSBvYmplY3QnKVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHN0b3JlID0gb2JqLnZhbHVlT2Yoa2V5KTtcbiAgICAgICAgcmV0dXJuIHN0b3JlICYmIHN0b3JlLmlkZW50aXR5ID09PSBrZXkgP1xuICAgICAgICAgICAgc3RvcmUgOiBoaWRkZW5TdG9yZShvYmosIGtleSk7XG4gICAgfTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZGF0YS1zZXQvbm9kZV9tb2R1bGVzL3dlYWttYXAtc2hpbS9jcmVhdGUtc3RvcmUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZGF0YS1zZXQvbm9kZV9tb2R1bGVzL3dlYWttYXAtc2hpbVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzID0gaGlkZGVuU3RvcmU7XG5cbmZ1bmN0aW9uIGhpZGRlblN0b3JlKG9iaiwga2V5KSB7XG4gICAgdmFyIHN0b3JlID0geyBpZGVudGl0eToga2V5IH07XG4gICAgdmFyIHZhbHVlT2YgPSBvYmoudmFsdWVPZjtcblxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShvYmosIFwidmFsdWVPZlwiLCB7XG4gICAgICAgIHZhbHVlOiBmdW5jdGlvbiAodmFsdWUpIHtcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZSAhPT0ga2V5ID9cbiAgICAgICAgICAgICAgICB2YWx1ZU9mLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgOiBzdG9yZTtcbiAgICAgICAgfSxcbiAgICAgICAgd3JpdGFibGU6IHRydWVcbiAgICB9KTtcblxuICAgIHJldHVybiBzdG9yZTtcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZGF0YS1zZXQvbm9kZV9tb2R1bGVzL3dlYWttYXAtc2hpbS9oaWRkZW4tc3RvcmUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZGF0YS1zZXQvbm9kZV9tb2R1bGVzL3dlYWttYXAtc2hpbVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbi8vIGh0dHA6Ly93aWtpLmNvbW1vbmpzLm9yZy93aWtpL1VuaXRfVGVzdGluZy8xLjBcbi8vXG4vLyBUSElTIElTIE5PVCBURVNURUQgTk9SIExJS0VMWSBUTyBXT1JLIE9VVFNJREUgVjghXG4vL1xuLy8gT3JpZ2luYWxseSBmcm9tIG5hcndoYWwuanMgKGh0dHA6Ly9uYXJ3aGFsanMub3JnKVxuLy8gQ29weXJpZ2h0IChjKSAyMDA5IFRob21hcyBSb2JpbnNvbiA8Mjgwbm9ydGguY29tPlxuLy9cbi8vIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHlcbi8vIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICdTb2Z0d2FyZScpLCB0b1xuLy8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdpdGhvdXQgbGltaXRhdGlvbiB0aGVcbi8vIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXNcbi8vIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6XG4vL1xuLy8gVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbi8vIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAnQVMgSVMnLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4vLyBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRVxuLy8gQVVUSE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU5cbi8vIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT05cbi8vIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLlxuXG4vLyB3aGVuIHVzZWQgaW4gbm9kZSwgdGhpcyB3aWxsIGFjdHVhbGx5IGxvYWQgdGhlIHV0aWwgbW9kdWxlIHdlIGRlcGVuZCBvblxuLy8gdmVyc3VzIGxvYWRpbmcgdGhlIGJ1aWx0aW4gdXRpbCBtb2R1bGUgYXMgaGFwcGVucyBvdGhlcndpc2Vcbi8vIHRoaXMgaXMgYSBidWcgaW4gbm9kZSBtb2R1bGUgbG9hZGluZyBhcyBmYXIgYXMgSSBhbSBjb25jZXJuZWRcbnZhciB1dGlsID0gcmVxdWlyZSgndXRpbC8nKTtcblxudmFyIHBTbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZTtcbnZhciBoYXNPd24gPSBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5O1xuXG4vLyAxLiBUaGUgYXNzZXJ0IG1vZHVsZSBwcm92aWRlcyBmdW5jdGlvbnMgdGhhdCB0aHJvd1xuLy8gQXNzZXJ0aW9uRXJyb3IncyB3aGVuIHBhcnRpY3VsYXIgY29uZGl0aW9ucyBhcmUgbm90IG1ldC4gVGhlXG4vLyBhc3NlcnQgbW9kdWxlIG11c3QgY29uZm9ybSB0byB0aGUgZm9sbG93aW5nIGludGVyZmFjZS5cblxudmFyIGFzc2VydCA9IG1vZHVsZS5leHBvcnRzID0gb2s7XG5cbi8vIDIuIFRoZSBBc3NlcnRpb25FcnJvciBpcyBkZWZpbmVkIGluIGFzc2VydC5cbi8vIG5ldyBhc3NlcnQuQXNzZXJ0aW9uRXJyb3IoeyBtZXNzYWdlOiBtZXNzYWdlLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFjdHVhbDogYWN0dWFsLFxuLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBleHBlY3RlZCB9KVxuXG5hc3NlcnQuQXNzZXJ0aW9uRXJyb3IgPSBmdW5jdGlvbiBBc3NlcnRpb25FcnJvcihvcHRpb25zKSB7XG4gIHRoaXMubmFtZSA9ICdBc3NlcnRpb25FcnJvcic7XG4gIHRoaXMuYWN0dWFsID0gb3B0aW9ucy5hY3R1YWw7XG4gIHRoaXMuZXhwZWN0ZWQgPSBvcHRpb25zLmV4cGVjdGVkO1xuICB0aGlzLm9wZXJhdG9yID0gb3B0aW9ucy5vcGVyYXRvcjtcbiAgaWYgKG9wdGlvbnMubWVzc2FnZSkge1xuICAgIHRoaXMubWVzc2FnZSA9IG9wdGlvbnMubWVzc2FnZTtcbiAgICB0aGlzLmdlbmVyYXRlZE1lc3NhZ2UgPSBmYWxzZTtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLm1lc3NhZ2UgPSBnZXRNZXNzYWdlKHRoaXMpO1xuICAgIHRoaXMuZ2VuZXJhdGVkTWVzc2FnZSA9IHRydWU7XG4gIH1cbiAgdmFyIHN0YWNrU3RhcnRGdW5jdGlvbiA9IG9wdGlvbnMuc3RhY2tTdGFydEZ1bmN0aW9uIHx8IGZhaWw7XG5cbiAgaWYgKEVycm9yLmNhcHR1cmVTdGFja1RyYWNlKSB7XG4gICAgRXJyb3IuY2FwdHVyZVN0YWNrVHJhY2UodGhpcywgc3RhY2tTdGFydEZ1bmN0aW9uKTtcbiAgfVxuICBlbHNlIHtcbiAgICAvLyBub24gdjggYnJvd3NlcnMgc28gd2UgY2FuIGhhdmUgYSBzdGFja3RyYWNlXG4gICAgdmFyIGVyciA9IG5ldyBFcnJvcigpO1xuICAgIGlmIChlcnIuc3RhY2spIHtcbiAgICAgIHZhciBvdXQgPSBlcnIuc3RhY2s7XG5cbiAgICAgIC8vIHRyeSB0byBzdHJpcCB1c2VsZXNzIGZyYW1lc1xuICAgICAgdmFyIGZuX25hbWUgPSBzdGFja1N0YXJ0RnVuY3Rpb24ubmFtZTtcbiAgICAgIHZhciBpZHggPSBvdXQuaW5kZXhPZignXFxuJyArIGZuX25hbWUpO1xuICAgICAgaWYgKGlkeCA+PSAwKSB7XG4gICAgICAgIC8vIG9uY2Ugd2UgaGF2ZSBsb2NhdGVkIHRoZSBmdW5jdGlvbiBmcmFtZVxuICAgICAgICAvLyB3ZSBuZWVkIHRvIHN0cmlwIG91dCBldmVyeXRoaW5nIGJlZm9yZSBpdCAoYW5kIGl0cyBsaW5lKVxuICAgICAgICB2YXIgbmV4dF9saW5lID0gb3V0LmluZGV4T2YoJ1xcbicsIGlkeCArIDEpO1xuICAgICAgICBvdXQgPSBvdXQuc3Vic3RyaW5nKG5leHRfbGluZSArIDEpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLnN0YWNrID0gb3V0O1xuICAgIH1cbiAgfVxufTtcblxuLy8gYXNzZXJ0LkFzc2VydGlvbkVycm9yIGluc3RhbmNlb2YgRXJyb3JcbnV0aWwuaW5oZXJpdHMoYXNzZXJ0LkFzc2VydGlvbkVycm9yLCBFcnJvcik7XG5cbmZ1bmN0aW9uIHJlcGxhY2VyKGtleSwgdmFsdWUpIHtcbiAgaWYgKHV0aWwuaXNVbmRlZmluZWQodmFsdWUpKSB7XG4gICAgcmV0dXJuICcnICsgdmFsdWU7XG4gIH1cbiAgaWYgKHV0aWwuaXNOdW1iZXIodmFsdWUpICYmIChpc05hTih2YWx1ZSkgfHwgIWlzRmluaXRlKHZhbHVlKSkpIHtcbiAgICByZXR1cm4gdmFsdWUudG9TdHJpbmcoKTtcbiAgfVxuICBpZiAodXRpbC5pc0Z1bmN0aW9uKHZhbHVlKSB8fCB1dGlsLmlzUmVnRXhwKHZhbHVlKSkge1xuICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpO1xuICB9XG4gIHJldHVybiB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gdHJ1bmNhdGUocywgbikge1xuICBpZiAodXRpbC5pc1N0cmluZyhzKSkge1xuICAgIHJldHVybiBzLmxlbmd0aCA8IG4gPyBzIDogcy5zbGljZSgwLCBuKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcztcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRNZXNzYWdlKHNlbGYpIHtcbiAgcmV0dXJuIHRydW5jYXRlKEpTT04uc3RyaW5naWZ5KHNlbGYuYWN0dWFsLCByZXBsYWNlciksIDEyOCkgKyAnICcgK1xuICAgICAgICAgc2VsZi5vcGVyYXRvciArICcgJyArXG4gICAgICAgICB0cnVuY2F0ZShKU09OLnN0cmluZ2lmeShzZWxmLmV4cGVjdGVkLCByZXBsYWNlciksIDEyOCk7XG59XG5cbi8vIEF0IHByZXNlbnQgb25seSB0aGUgdGhyZWUga2V5cyBtZW50aW9uZWQgYWJvdmUgYXJlIHVzZWQgYW5kXG4vLyB1bmRlcnN0b29kIGJ5IHRoZSBzcGVjLiBJbXBsZW1lbnRhdGlvbnMgb3Igc3ViIG1vZHVsZXMgY2FuIHBhc3Ncbi8vIG90aGVyIGtleXMgdG8gdGhlIEFzc2VydGlvbkVycm9yJ3MgY29uc3RydWN0b3IgLSB0aGV5IHdpbGwgYmVcbi8vIGlnbm9yZWQuXG5cbi8vIDMuIEFsbCBvZiB0aGUgZm9sbG93aW5nIGZ1bmN0aW9ucyBtdXN0IHRocm93IGFuIEFzc2VydGlvbkVycm9yXG4vLyB3aGVuIGEgY29ycmVzcG9uZGluZyBjb25kaXRpb24gaXMgbm90IG1ldCwgd2l0aCBhIG1lc3NhZ2UgdGhhdFxuLy8gbWF5IGJlIHVuZGVmaW5lZCBpZiBub3QgcHJvdmlkZWQuICBBbGwgYXNzZXJ0aW9uIG1ldGhvZHMgcHJvdmlkZVxuLy8gYm90aCB0aGUgYWN0dWFsIGFuZCBleHBlY3RlZCB2YWx1ZXMgdG8gdGhlIGFzc2VydGlvbiBlcnJvciBmb3Jcbi8vIGRpc3BsYXkgcHVycG9zZXMuXG5cbmZ1bmN0aW9uIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgb3BlcmF0b3IsIHN0YWNrU3RhcnRGdW5jdGlvbikge1xuICB0aHJvdyBuZXcgYXNzZXJ0LkFzc2VydGlvbkVycm9yKHtcbiAgICBtZXNzYWdlOiBtZXNzYWdlLFxuICAgIGFjdHVhbDogYWN0dWFsLFxuICAgIGV4cGVjdGVkOiBleHBlY3RlZCxcbiAgICBvcGVyYXRvcjogb3BlcmF0b3IsXG4gICAgc3RhY2tTdGFydEZ1bmN0aW9uOiBzdGFja1N0YXJ0RnVuY3Rpb25cbiAgfSk7XG59XG5cbi8vIEVYVEVOU0lPTiEgYWxsb3dzIGZvciB3ZWxsIGJlaGF2ZWQgZXJyb3JzIGRlZmluZWQgZWxzZXdoZXJlLlxuYXNzZXJ0LmZhaWwgPSBmYWlsO1xuXG4vLyA0LiBQdXJlIGFzc2VydGlvbiB0ZXN0cyB3aGV0aGVyIGEgdmFsdWUgaXMgdHJ1dGh5LCBhcyBkZXRlcm1pbmVkXG4vLyBieSAhIWd1YXJkLlxuLy8gYXNzZXJ0Lm9rKGd1YXJkLCBtZXNzYWdlX29wdCk7XG4vLyBUaGlzIHN0YXRlbWVudCBpcyBlcXVpdmFsZW50IHRvIGFzc2VydC5lcXVhbCh0cnVlLCAhIWd1YXJkLFxuLy8gbWVzc2FnZV9vcHQpOy4gVG8gdGVzdCBzdHJpY3RseSBmb3IgdGhlIHZhbHVlIHRydWUsIHVzZVxuLy8gYXNzZXJ0LnN0cmljdEVxdWFsKHRydWUsIGd1YXJkLCBtZXNzYWdlX29wdCk7LlxuXG5mdW5jdGlvbiBvayh2YWx1ZSwgbWVzc2FnZSkge1xuICBpZiAoIXZhbHVlKSBmYWlsKHZhbHVlLCB0cnVlLCBtZXNzYWdlLCAnPT0nLCBhc3NlcnQub2spO1xufVxuYXNzZXJ0Lm9rID0gb2s7XG5cbi8vIDUuIFRoZSBlcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgc2hhbGxvdywgY29lcmNpdmUgZXF1YWxpdHkgd2l0aFxuLy8gPT0uXG4vLyBhc3NlcnQuZXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuZXF1YWwgPSBmdW5jdGlvbiBlcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlKSB7XG4gIGlmIChhY3R1YWwgIT0gZXhwZWN0ZWQpIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJz09JywgYXNzZXJ0LmVxdWFsKTtcbn07XG5cbi8vIDYuIFRoZSBub24tZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIGZvciB3aGV0aGVyIHR3byBvYmplY3RzIGFyZSBub3QgZXF1YWxcbi8vIHdpdGggIT0gYXNzZXJ0Lm5vdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdEVxdWFsID0gZnVuY3Rpb24gbm90RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsID09IGV4cGVjdGVkKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnIT0nLCBhc3NlcnQubm90RXF1YWwpO1xuICB9XG59O1xuXG4vLyA3LiBUaGUgZXF1aXZhbGVuY2UgYXNzZXJ0aW9uIHRlc3RzIGEgZGVlcCBlcXVhbGl0eSByZWxhdGlvbi5cbi8vIGFzc2VydC5kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQuZGVlcEVxdWFsID0gZnVuY3Rpb24gZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKCFfZGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQpKSB7XG4gICAgZmFpbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlLCAnZGVlcEVxdWFsJywgYXNzZXJ0LmRlZXBFcXVhbCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCkge1xuICAvLyA3LjEuIEFsbCBpZGVudGljYWwgdmFsdWVzIGFyZSBlcXVpdmFsZW50LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbiAgaWYgKGFjdHVhbCA9PT0gZXhwZWN0ZWQpIHtcbiAgICByZXR1cm4gdHJ1ZTtcblxuICB9IGVsc2UgaWYgKHV0aWwuaXNCdWZmZXIoYWN0dWFsKSAmJiB1dGlsLmlzQnVmZmVyKGV4cGVjdGVkKSkge1xuICAgIGlmIChhY3R1YWwubGVuZ3RoICE9IGV4cGVjdGVkLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhY3R1YWwubGVuZ3RoOyBpKyspIHtcbiAgICAgIGlmIChhY3R1YWxbaV0gIT09IGV4cGVjdGVkW2ldKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRydWU7XG5cbiAgLy8gNy4yLiBJZiB0aGUgZXhwZWN0ZWQgdmFsdWUgaXMgYSBEYXRlIG9iamVjdCwgdGhlIGFjdHVhbCB2YWx1ZSBpc1xuICAvLyBlcXVpdmFsZW50IGlmIGl0IGlzIGFsc28gYSBEYXRlIG9iamVjdCB0aGF0IHJlZmVycyB0byB0aGUgc2FtZSB0aW1lLlxuICB9IGVsc2UgaWYgKHV0aWwuaXNEYXRlKGFjdHVhbCkgJiYgdXRpbC5pc0RhdGUoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbC5nZXRUaW1lKCkgPT09IGV4cGVjdGVkLmdldFRpbWUoKTtcblxuICAvLyA3LjMgSWYgdGhlIGV4cGVjdGVkIHZhbHVlIGlzIGEgUmVnRXhwIG9iamVjdCwgdGhlIGFjdHVhbCB2YWx1ZSBpc1xuICAvLyBlcXVpdmFsZW50IGlmIGl0IGlzIGFsc28gYSBSZWdFeHAgb2JqZWN0IHdpdGggdGhlIHNhbWUgc291cmNlIGFuZFxuICAvLyBwcm9wZXJ0aWVzIChgZ2xvYmFsYCwgYG11bHRpbGluZWAsIGBsYXN0SW5kZXhgLCBgaWdub3JlQ2FzZWApLlxuICB9IGVsc2UgaWYgKHV0aWwuaXNSZWdFeHAoYWN0dWFsKSAmJiB1dGlsLmlzUmVnRXhwKGV4cGVjdGVkKSkge1xuICAgIHJldHVybiBhY3R1YWwuc291cmNlID09PSBleHBlY3RlZC5zb3VyY2UgJiZcbiAgICAgICAgICAgYWN0dWFsLmdsb2JhbCA9PT0gZXhwZWN0ZWQuZ2xvYmFsICYmXG4gICAgICAgICAgIGFjdHVhbC5tdWx0aWxpbmUgPT09IGV4cGVjdGVkLm11bHRpbGluZSAmJlxuICAgICAgICAgICBhY3R1YWwubGFzdEluZGV4ID09PSBleHBlY3RlZC5sYXN0SW5kZXggJiZcbiAgICAgICAgICAgYWN0dWFsLmlnbm9yZUNhc2UgPT09IGV4cGVjdGVkLmlnbm9yZUNhc2U7XG5cbiAgLy8gNy40LiBPdGhlciBwYWlycyB0aGF0IGRvIG5vdCBib3RoIHBhc3MgdHlwZW9mIHZhbHVlID09ICdvYmplY3QnLFxuICAvLyBlcXVpdmFsZW5jZSBpcyBkZXRlcm1pbmVkIGJ5ID09LlxuICB9IGVsc2UgaWYgKCF1dGlsLmlzT2JqZWN0KGFjdHVhbCkgJiYgIXV0aWwuaXNPYmplY3QoZXhwZWN0ZWQpKSB7XG4gICAgcmV0dXJuIGFjdHVhbCA9PSBleHBlY3RlZDtcblxuICAvLyA3LjUgRm9yIGFsbCBvdGhlciBPYmplY3QgcGFpcnMsIGluY2x1ZGluZyBBcnJheSBvYmplY3RzLCBlcXVpdmFsZW5jZSBpc1xuICAvLyBkZXRlcm1pbmVkIGJ5IGhhdmluZyB0aGUgc2FtZSBudW1iZXIgb2Ygb3duZWQgcHJvcGVydGllcyAoYXMgdmVyaWZpZWRcbiAgLy8gd2l0aCBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwpLCB0aGUgc2FtZSBzZXQgb2Yga2V5c1xuICAvLyAoYWx0aG91Z2ggbm90IG5lY2Vzc2FyaWx5IHRoZSBzYW1lIG9yZGVyKSwgZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5XG4gIC8vIGNvcnJlc3BvbmRpbmcga2V5LCBhbmQgYW4gaWRlbnRpY2FsICdwcm90b3R5cGUnIHByb3BlcnR5LiBOb3RlOiB0aGlzXG4gIC8vIGFjY291bnRzIGZvciBib3RoIG5hbWVkIGFuZCBpbmRleGVkIHByb3BlcnRpZXMgb24gQXJyYXlzLlxuICB9IGVsc2Uge1xuICAgIHJldHVybiBvYmpFcXVpdihhY3R1YWwsIGV4cGVjdGVkKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc0FyZ3VtZW50cyhvYmplY3QpIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmplY3QpID09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xufVxuXG5mdW5jdGlvbiBvYmpFcXVpdihhLCBiKSB7XG4gIGlmICh1dGlsLmlzTnVsbE9yVW5kZWZpbmVkKGEpIHx8IHV0aWwuaXNOdWxsT3JVbmRlZmluZWQoYikpXG4gICAgcmV0dXJuIGZhbHNlO1xuICAvLyBhbiBpZGVudGljYWwgJ3Byb3RvdHlwZScgcHJvcGVydHkuXG4gIGlmIChhLnByb3RvdHlwZSAhPT0gYi5wcm90b3R5cGUpIHJldHVybiBmYWxzZTtcbiAgLy9+fn5JJ3ZlIG1hbmFnZWQgdG8gYnJlYWsgT2JqZWN0LmtleXMgdGhyb3VnaCBzY3Jld3kgYXJndW1lbnRzIHBhc3NpbmcuXG4gIC8vICAgQ29udmVydGluZyB0byBhcnJheSBzb2x2ZXMgdGhlIHByb2JsZW0uXG4gIGlmIChpc0FyZ3VtZW50cyhhKSkge1xuICAgIGlmICghaXNBcmd1bWVudHMoYikpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgYSA9IHBTbGljZS5jYWxsKGEpO1xuICAgIGIgPSBwU2xpY2UuY2FsbChiKTtcbiAgICByZXR1cm4gX2RlZXBFcXVhbChhLCBiKTtcbiAgfVxuICB0cnkge1xuICAgIHZhciBrYSA9IG9iamVjdEtleXMoYSksXG4gICAgICAgIGtiID0gb2JqZWN0S2V5cyhiKSxcbiAgICAgICAga2V5LCBpO1xuICB9IGNhdGNoIChlKSB7Ly9oYXBwZW5zIHdoZW4gb25lIGlzIGEgc3RyaW5nIGxpdGVyYWwgYW5kIHRoZSBvdGhlciBpc24ndFxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICAvLyBoYXZpbmcgdGhlIHNhbWUgbnVtYmVyIG9mIG93bmVkIHByb3BlcnRpZXMgKGtleXMgaW5jb3Jwb3JhdGVzXG4gIC8vIGhhc093blByb3BlcnR5KVxuICBpZiAoa2EubGVuZ3RoICE9IGtiLmxlbmd0aClcbiAgICByZXR1cm4gZmFsc2U7XG4gIC8vdGhlIHNhbWUgc2V0IG9mIGtleXMgKGFsdGhvdWdoIG5vdCBuZWNlc3NhcmlseSB0aGUgc2FtZSBvcmRlciksXG4gIGthLnNvcnQoKTtcbiAga2Iuc29ydCgpO1xuICAvL35+fmNoZWFwIGtleSB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgaWYgKGthW2ldICE9IGtiW2ldKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIC8vZXF1aXZhbGVudCB2YWx1ZXMgZm9yIGV2ZXJ5IGNvcnJlc3BvbmRpbmcga2V5LCBhbmRcbiAgLy9+fn5wb3NzaWJseSBleHBlbnNpdmUgZGVlcCB0ZXN0XG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAga2V5ID0ga2FbaV07XG4gICAgaWYgKCFfZGVlcEVxdWFsKGFba2V5XSwgYltrZXldKSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG4vLyA4LiBUaGUgbm9uLWVxdWl2YWxlbmNlIGFzc2VydGlvbiB0ZXN0cyBmb3IgYW55IGRlZXAgaW5lcXVhbGl0eS5cbi8vIGFzc2VydC5ub3REZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZV9vcHQpO1xuXG5hc3NlcnQubm90RGVlcEVxdWFsID0gZnVuY3Rpb24gbm90RGVlcEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKF9kZWVwRXF1YWwoYWN0dWFsLCBleHBlY3RlZCkpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICdub3REZWVwRXF1YWwnLCBhc3NlcnQubm90RGVlcEVxdWFsKTtcbiAgfVxufTtcblxuLy8gOS4gVGhlIHN0cmljdCBlcXVhbGl0eSBhc3NlcnRpb24gdGVzdHMgc3RyaWN0IGVxdWFsaXR5LCBhcyBkZXRlcm1pbmVkIGJ5ID09PS5cbi8vIGFzc2VydC5zdHJpY3RFcXVhbChhY3R1YWwsIGV4cGVjdGVkLCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC5zdHJpY3RFcXVhbCA9IGZ1bmN0aW9uIHN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgaWYgKGFjdHVhbCAhPT0gZXhwZWN0ZWQpIHtcbiAgICBmYWlsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2UsICc9PT0nLCBhc3NlcnQuc3RyaWN0RXF1YWwpO1xuICB9XG59O1xuXG4vLyAxMC4gVGhlIHN0cmljdCBub24tZXF1YWxpdHkgYXNzZXJ0aW9uIHRlc3RzIGZvciBzdHJpY3QgaW5lcXVhbGl0eSwgYXNcbi8vIGRldGVybWluZWQgYnkgIT09LiAgYXNzZXJ0Lm5vdFN0cmljdEVxdWFsKGFjdHVhbCwgZXhwZWN0ZWQsIG1lc3NhZ2Vfb3B0KTtcblxuYXNzZXJ0Lm5vdFN0cmljdEVxdWFsID0gZnVuY3Rpb24gbm90U3RyaWN0RXF1YWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSkge1xuICBpZiAoYWN0dWFsID09PSBleHBlY3RlZCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgbWVzc2FnZSwgJyE9PScsIGFzc2VydC5ub3RTdHJpY3RFcXVhbCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpIHtcbiAgaWYgKCFhY3R1YWwgfHwgIWV4cGVjdGVkKSB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgaWYgKE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChleHBlY3RlZCkgPT0gJ1tvYmplY3QgUmVnRXhwXScpIHtcbiAgICByZXR1cm4gZXhwZWN0ZWQudGVzdChhY3R1YWwpO1xuICB9IGVsc2UgaWYgKGFjdHVhbCBpbnN0YW5jZW9mIGV4cGVjdGVkKSB7XG4gICAgcmV0dXJuIHRydWU7XG4gIH0gZWxzZSBpZiAoZXhwZWN0ZWQuY2FsbCh7fSwgYWN0dWFsKSA9PT0gdHJ1ZSkge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBfdGhyb3dzKHNob3VsZFRocm93LCBibG9jaywgZXhwZWN0ZWQsIG1lc3NhZ2UpIHtcbiAgdmFyIGFjdHVhbDtcblxuICBpZiAodXRpbC5pc1N0cmluZyhleHBlY3RlZCkpIHtcbiAgICBtZXNzYWdlID0gZXhwZWN0ZWQ7XG4gICAgZXhwZWN0ZWQgPSBudWxsO1xuICB9XG5cbiAgdHJ5IHtcbiAgICBibG9jaygpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgYWN0dWFsID0gZTtcbiAgfVxuXG4gIG1lc3NhZ2UgPSAoZXhwZWN0ZWQgJiYgZXhwZWN0ZWQubmFtZSA/ICcgKCcgKyBleHBlY3RlZC5uYW1lICsgJykuJyA6ICcuJykgK1xuICAgICAgICAgICAgKG1lc3NhZ2UgPyAnICcgKyBtZXNzYWdlIDogJy4nKTtcblxuICBpZiAoc2hvdWxkVGhyb3cgJiYgIWFjdHVhbCkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgJ01pc3NpbmcgZXhwZWN0ZWQgZXhjZXB0aW9uJyArIG1lc3NhZ2UpO1xuICB9XG5cbiAgaWYgKCFzaG91bGRUaHJvdyAmJiBleHBlY3RlZEV4Y2VwdGlvbihhY3R1YWwsIGV4cGVjdGVkKSkge1xuICAgIGZhaWwoYWN0dWFsLCBleHBlY3RlZCwgJ0dvdCB1bndhbnRlZCBleGNlcHRpb24nICsgbWVzc2FnZSk7XG4gIH1cblxuICBpZiAoKHNob3VsZFRocm93ICYmIGFjdHVhbCAmJiBleHBlY3RlZCAmJlxuICAgICAgIWV4cGVjdGVkRXhjZXB0aW9uKGFjdHVhbCwgZXhwZWN0ZWQpKSB8fCAoIXNob3VsZFRocm93ICYmIGFjdHVhbCkpIHtcbiAgICB0aHJvdyBhY3R1YWw7XG4gIH1cbn1cblxuLy8gMTEuIEV4cGVjdGVkIHRvIHRocm93IGFuIGVycm9yOlxuLy8gYXNzZXJ0LnRocm93cyhibG9jaywgRXJyb3Jfb3B0LCBtZXNzYWdlX29wdCk7XG5cbmFzc2VydC50aHJvd3MgPSBmdW5jdGlvbihibG9jaywgLypvcHRpb25hbCovZXJyb3IsIC8qb3B0aW9uYWwqL21lc3NhZ2UpIHtcbiAgX3Rocm93cy5hcHBseSh0aGlzLCBbdHJ1ZV0uY29uY2F0KHBTbGljZS5jYWxsKGFyZ3VtZW50cykpKTtcbn07XG5cbi8vIEVYVEVOU0lPTiEgVGhpcyBpcyBhbm5veWluZyB0byB3cml0ZSBvdXRzaWRlIHRoaXMgbW9kdWxlLlxuYXNzZXJ0LmRvZXNOb3RUaHJvdyA9IGZ1bmN0aW9uKGJsb2NrLCAvKm9wdGlvbmFsKi9tZXNzYWdlKSB7XG4gIF90aHJvd3MuYXBwbHkodGhpcywgW2ZhbHNlXS5jb25jYXQocFNsaWNlLmNhbGwoYXJndW1lbnRzKSkpO1xufTtcblxuYXNzZXJ0LmlmRXJyb3IgPSBmdW5jdGlvbihlcnIpIHsgaWYgKGVycikge3Rocm93IGVycjt9fTtcblxudmFyIG9iamVjdEtleXMgPSBPYmplY3Qua2V5cyB8fCBmdW5jdGlvbiAob2JqKSB7XG4gIHZhciBrZXlzID0gW107XG4gIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICBpZiAoaGFzT3duLmNhbGwob2JqLCBrZXkpKSBrZXlzLnB1c2goa2V5KTtcbiAgfVxuICByZXR1cm4ga2V5cztcbn07XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy9hc3NlcnQvYXNzZXJ0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy9hc3NlcnRcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5pZiAodHlwZW9mIE9iamVjdC5jcmVhdGUgPT09ICdmdW5jdGlvbicpIHtcbiAgLy8gaW1wbGVtZW50YXRpb24gZnJvbSBzdGFuZGFyZCBub2RlLmpzICd1dGlsJyBtb2R1bGVcbiAgbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBpbmhlcml0cyhjdG9yLCBzdXBlckN0b3IpIHtcbiAgICBjdG9yLnN1cGVyXyA9IHN1cGVyQ3RvclxuICAgIGN0b3IucHJvdG90eXBlID0gT2JqZWN0LmNyZWF0ZShzdXBlckN0b3IucHJvdG90eXBlLCB7XG4gICAgICBjb25zdHJ1Y3Rvcjoge1xuICAgICAgICB2YWx1ZTogY3RvcixcbiAgICAgICAgZW51bWVyYWJsZTogZmFsc2UsXG4gICAgICAgIHdyaXRhYmxlOiB0cnVlLFxuICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgIH1cbiAgICB9KTtcbiAgfTtcbn0gZWxzZSB7XG4gIC8vIG9sZCBzY2hvb2wgc2hpbSBmb3Igb2xkIGJyb3dzZXJzXG4gIG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaW5oZXJpdHMoY3Rvciwgc3VwZXJDdG9yKSB7XG4gICAgY3Rvci5zdXBlcl8gPSBzdXBlckN0b3JcbiAgICB2YXIgVGVtcEN0b3IgPSBmdW5jdGlvbiAoKSB7fVxuICAgIFRlbXBDdG9yLnByb3RvdHlwZSA9IHN1cGVyQ3Rvci5wcm90b3R5cGVcbiAgICBjdG9yLnByb3RvdHlwZSA9IG5ldyBUZW1wQ3RvcigpXG4gICAgY3Rvci5wcm90b3R5cGUuY29uc3RydWN0b3IgPSBjdG9yXG4gIH1cbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL2Fzc2VydC9ub2RlX21vZHVsZXMvdXRpbC9ub2RlX21vZHVsZXMvaW5oZXJpdHMvaW5oZXJpdHNfYnJvd3Nlci5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMvYXNzZXJ0L25vZGVfbW9kdWxlcy91dGlsL25vZGVfbW9kdWxlcy9pbmhlcml0c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNCdWZmZXIoYXJnKSB7XG4gIHJldHVybiBhcmcgJiYgdHlwZW9mIGFyZyA9PT0gJ29iamVjdCdcbiAgICAmJiB0eXBlb2YgYXJnLmNvcHkgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLmZpbGwgPT09ICdmdW5jdGlvbidcbiAgICAmJiB0eXBlb2YgYXJnLnJlYWRVSW50OCA9PT0gJ2Z1bmN0aW9uJztcbn1cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy9hc3NlcnQvbm9kZV9tb2R1bGVzL3V0aWwvc3VwcG9ydC9pc0J1ZmZlckJyb3dzZXIuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL2Fzc2VydC9ub2RlX21vZHVsZXMvdXRpbC9zdXBwb3J0XCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xuLy8gQ29weXJpZ2h0IEpveWVudCwgSW5jLiBhbmQgb3RoZXIgTm9kZSBjb250cmlidXRvcnMuXG4vL1xuLy8gUGVybWlzc2lvbiBpcyBoZXJlYnkgZ3JhbnRlZCwgZnJlZSBvZiBjaGFyZ2UsIHRvIGFueSBwZXJzb24gb2J0YWluaW5nIGFcbi8vIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGVcbi8vIFwiU29mdHdhcmVcIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZ1xuLy8gd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLFxuLy8gZGlzdHJpYnV0ZSwgc3VibGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdFxuLy8gcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcyBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlXG4vLyBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZFxuLy8gaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4vL1xuLy8gVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEIFwiQVMgSVNcIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTU1xuLy8gT1IgSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRlxuLy8gTUVSQ0hBTlRBQklMSVRZLCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTlxuLy8gTk8gRVZFTlQgU0hBTEwgVEhFIEFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sXG4vLyBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1Jcbi8vIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLCBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEVcbi8vIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuXG5cbnZhciBmb3JtYXRSZWdFeHAgPSAvJVtzZGolXS9nO1xuZXhwb3J0cy5mb3JtYXQgPSBmdW5jdGlvbihmKSB7XG4gIGlmICghaXNTdHJpbmcoZikpIHtcbiAgICB2YXIgb2JqZWN0cyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJndW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBvYmplY3RzLnB1c2goaW5zcGVjdChhcmd1bWVudHNbaV0pKTtcbiAgICB9XG4gICAgcmV0dXJuIG9iamVjdHMuam9pbignICcpO1xuICB9XG5cbiAgdmFyIGkgPSAxO1xuICB2YXIgYXJncyA9IGFyZ3VtZW50cztcbiAgdmFyIGxlbiA9IGFyZ3MubGVuZ3RoO1xuICB2YXIgc3RyID0gU3RyaW5nKGYpLnJlcGxhY2UoZm9ybWF0UmVnRXhwLCBmdW5jdGlvbih4KSB7XG4gICAgaWYgKHggPT09ICclJScpIHJldHVybiAnJSc7XG4gICAgaWYgKGkgPj0gbGVuKSByZXR1cm4geDtcbiAgICBzd2l0Y2ggKHgpIHtcbiAgICAgIGNhc2UgJyVzJzogcmV0dXJuIFN0cmluZyhhcmdzW2krK10pO1xuICAgICAgY2FzZSAnJWQnOiByZXR1cm4gTnVtYmVyKGFyZ3NbaSsrXSk7XG4gICAgICBjYXNlICclaic6XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KGFyZ3NbaSsrXSk7XG4gICAgICAgIH0gY2F0Y2ggKF8pIHtcbiAgICAgICAgICByZXR1cm4gJ1tDaXJjdWxhcl0nO1xuICAgICAgICB9XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4geDtcbiAgICB9XG4gIH0pO1xuICBmb3IgKHZhciB4ID0gYXJnc1tpXTsgaSA8IGxlbjsgeCA9IGFyZ3NbKytpXSkge1xuICAgIGlmIChpc051bGwoeCkgfHwgIWlzT2JqZWN0KHgpKSB7XG4gICAgICBzdHIgKz0gJyAnICsgeDtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyICs9ICcgJyArIGluc3BlY3QoeCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBzdHI7XG59O1xuXG5cbi8vIE1hcmsgdGhhdCBhIG1ldGhvZCBzaG91bGQgbm90IGJlIHVzZWQuXG4vLyBSZXR1cm5zIGEgbW9kaWZpZWQgZnVuY3Rpb24gd2hpY2ggd2FybnMgb25jZSBieSBkZWZhdWx0LlxuLy8gSWYgLS1uby1kZXByZWNhdGlvbiBpcyBzZXQsIHRoZW4gaXQgaXMgYSBuby1vcC5cbmV4cG9ydHMuZGVwcmVjYXRlID0gZnVuY3Rpb24oZm4sIG1zZykge1xuICAvLyBBbGxvdyBmb3IgZGVwcmVjYXRpbmcgdGhpbmdzIGluIHRoZSBwcm9jZXNzIG9mIHN0YXJ0aW5nIHVwLlxuICBpZiAoaXNVbmRlZmluZWQoZ2xvYmFsLnByb2Nlc3MpKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIGV4cG9ydHMuZGVwcmVjYXRlKGZuLCBtc2cpLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfTtcbiAgfVxuXG4gIGlmIChwcm9jZXNzLm5vRGVwcmVjYXRpb24gPT09IHRydWUpIHtcbiAgICByZXR1cm4gZm47XG4gIH1cblxuICB2YXIgd2FybmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGRlcHJlY2F0ZWQoKSB7XG4gICAgaWYgKCF3YXJuZWQpIHtcbiAgICAgIGlmIChwcm9jZXNzLnRocm93RGVwcmVjYXRpb24pIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKG1zZyk7XG4gICAgICB9IGVsc2UgaWYgKHByb2Nlc3MudHJhY2VEZXByZWNhdGlvbikge1xuICAgICAgICBjb25zb2xlLnRyYWNlKG1zZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zb2xlLmVycm9yKG1zZyk7XG4gICAgICB9XG4gICAgICB3YXJuZWQgPSB0cnVlO1xuICAgIH1cbiAgICByZXR1cm4gZm4uYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgfVxuXG4gIHJldHVybiBkZXByZWNhdGVkO1xufTtcblxuXG52YXIgZGVidWdzID0ge307XG52YXIgZGVidWdFbnZpcm9uO1xuZXhwb3J0cy5kZWJ1Z2xvZyA9IGZ1bmN0aW9uKHNldCkge1xuICBpZiAoaXNVbmRlZmluZWQoZGVidWdFbnZpcm9uKSlcbiAgICBkZWJ1Z0Vudmlyb24gPSBwcm9jZXNzLmVudi5OT0RFX0RFQlVHIHx8ICcnO1xuICBzZXQgPSBzZXQudG9VcHBlckNhc2UoKTtcbiAgaWYgKCFkZWJ1Z3Nbc2V0XSkge1xuICAgIGlmIChuZXcgUmVnRXhwKCdcXFxcYicgKyBzZXQgKyAnXFxcXGInLCAnaScpLnRlc3QoZGVidWdFbnZpcm9uKSkge1xuICAgICAgdmFyIHBpZCA9IHByb2Nlc3MucGlkO1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHtcbiAgICAgICAgdmFyIG1zZyA9IGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cyk7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoJyVzICVkOiAlcycsIHNldCwgcGlkLCBtc2cpO1xuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgZGVidWdzW3NldF0gPSBmdW5jdGlvbigpIHt9O1xuICAgIH1cbiAgfVxuICByZXR1cm4gZGVidWdzW3NldF07XG59O1xuXG5cbi8qKlxuICogRWNob3MgdGhlIHZhbHVlIG9mIGEgdmFsdWUuIFRyeXMgdG8gcHJpbnQgdGhlIHZhbHVlIG91dFxuICogaW4gdGhlIGJlc3Qgd2F5IHBvc3NpYmxlIGdpdmVuIHRoZSBkaWZmZXJlbnQgdHlwZXMuXG4gKlxuICogQHBhcmFtIHtPYmplY3R9IG9iaiBUaGUgb2JqZWN0IHRvIHByaW50IG91dC5cbiAqIEBwYXJhbSB7T2JqZWN0fSBvcHRzIE9wdGlvbmFsIG9wdGlvbnMgb2JqZWN0IHRoYXQgYWx0ZXJzIHRoZSBvdXRwdXQuXG4gKi9cbi8qIGxlZ2FjeTogb2JqLCBzaG93SGlkZGVuLCBkZXB0aCwgY29sb3JzKi9cbmZ1bmN0aW9uIGluc3BlY3Qob2JqLCBvcHRzKSB7XG4gIC8vIGRlZmF1bHQgb3B0aW9uc1xuICB2YXIgY3R4ID0ge1xuICAgIHNlZW46IFtdLFxuICAgIHN0eWxpemU6IHN0eWxpemVOb0NvbG9yXG4gIH07XG4gIC8vIGxlZ2FjeS4uLlxuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+PSAzKSBjdHguZGVwdGggPSBhcmd1bWVudHNbMl07XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID49IDQpIGN0eC5jb2xvcnMgPSBhcmd1bWVudHNbM107XG4gIGlmIChpc0Jvb2xlYW4ob3B0cykpIHtcbiAgICAvLyBsZWdhY3kuLi5cbiAgICBjdHguc2hvd0hpZGRlbiA9IG9wdHM7XG4gIH0gZWxzZSBpZiAob3B0cykge1xuICAgIC8vIGdvdCBhbiBcIm9wdGlvbnNcIiBvYmplY3RcbiAgICBleHBvcnRzLl9leHRlbmQoY3R4LCBvcHRzKTtcbiAgfVxuICAvLyBzZXQgZGVmYXVsdCBvcHRpb25zXG4gIGlmIChpc1VuZGVmaW5lZChjdHguc2hvd0hpZGRlbikpIGN0eC5zaG93SGlkZGVuID0gZmFsc2U7XG4gIGlmIChpc1VuZGVmaW5lZChjdHguZGVwdGgpKSBjdHguZGVwdGggPSAyO1xuICBpZiAoaXNVbmRlZmluZWQoY3R4LmNvbG9ycykpIGN0eC5jb2xvcnMgPSBmYWxzZTtcbiAgaWYgKGlzVW5kZWZpbmVkKGN0eC5jdXN0b21JbnNwZWN0KSkgY3R4LmN1c3RvbUluc3BlY3QgPSB0cnVlO1xuICBpZiAoY3R4LmNvbG9ycykgY3R4LnN0eWxpemUgPSBzdHlsaXplV2l0aENvbG9yO1xuICByZXR1cm4gZm9ybWF0VmFsdWUoY3R4LCBvYmosIGN0eC5kZXB0aCk7XG59XG5leHBvcnRzLmluc3BlY3QgPSBpbnNwZWN0O1xuXG5cbi8vIGh0dHA6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQU5TSV9lc2NhcGVfY29kZSNncmFwaGljc1xuaW5zcGVjdC5jb2xvcnMgPSB7XG4gICdib2xkJyA6IFsxLCAyMl0sXG4gICdpdGFsaWMnIDogWzMsIDIzXSxcbiAgJ3VuZGVybGluZScgOiBbNCwgMjRdLFxuICAnaW52ZXJzZScgOiBbNywgMjddLFxuICAnd2hpdGUnIDogWzM3LCAzOV0sXG4gICdncmV5JyA6IFs5MCwgMzldLFxuICAnYmxhY2snIDogWzMwLCAzOV0sXG4gICdibHVlJyA6IFszNCwgMzldLFxuICAnY3lhbicgOiBbMzYsIDM5XSxcbiAgJ2dyZWVuJyA6IFszMiwgMzldLFxuICAnbWFnZW50YScgOiBbMzUsIDM5XSxcbiAgJ3JlZCcgOiBbMzEsIDM5XSxcbiAgJ3llbGxvdycgOiBbMzMsIDM5XVxufTtcblxuLy8gRG9uJ3QgdXNlICdibHVlJyBub3QgdmlzaWJsZSBvbiBjbWQuZXhlXG5pbnNwZWN0LnN0eWxlcyA9IHtcbiAgJ3NwZWNpYWwnOiAnY3lhbicsXG4gICdudW1iZXInOiAneWVsbG93JyxcbiAgJ2Jvb2xlYW4nOiAneWVsbG93JyxcbiAgJ3VuZGVmaW5lZCc6ICdncmV5JyxcbiAgJ251bGwnOiAnYm9sZCcsXG4gICdzdHJpbmcnOiAnZ3JlZW4nLFxuICAnZGF0ZSc6ICdtYWdlbnRhJyxcbiAgLy8gXCJuYW1lXCI6IGludGVudGlvbmFsbHkgbm90IHN0eWxpbmdcbiAgJ3JlZ2V4cCc6ICdyZWQnXG59O1xuXG5cbmZ1bmN0aW9uIHN0eWxpemVXaXRoQ29sb3Ioc3RyLCBzdHlsZVR5cGUpIHtcbiAgdmFyIHN0eWxlID0gaW5zcGVjdC5zdHlsZXNbc3R5bGVUeXBlXTtcblxuICBpZiAoc3R5bGUpIHtcbiAgICByZXR1cm4gJ1xcdTAwMWJbJyArIGluc3BlY3QuY29sb3JzW3N0eWxlXVswXSArICdtJyArIHN0ciArXG4gICAgICAgICAgICdcXHUwMDFiWycgKyBpbnNwZWN0LmNvbG9yc1tzdHlsZV1bMV0gKyAnbSc7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIHN0cjtcbiAgfVxufVxuXG5cbmZ1bmN0aW9uIHN0eWxpemVOb0NvbG9yKHN0ciwgc3R5bGVUeXBlKSB7XG4gIHJldHVybiBzdHI7XG59XG5cblxuZnVuY3Rpb24gYXJyYXlUb0hhc2goYXJyYXkpIHtcbiAgdmFyIGhhc2ggPSB7fTtcblxuICBhcnJheS5mb3JFYWNoKGZ1bmN0aW9uKHZhbCwgaWR4KSB7XG4gICAgaGFzaFt2YWxdID0gdHJ1ZTtcbiAgfSk7XG5cbiAgcmV0dXJuIGhhc2g7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0VmFsdWUoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzKSB7XG4gIC8vIFByb3ZpZGUgYSBob29rIGZvciB1c2VyLXNwZWNpZmllZCBpbnNwZWN0IGZ1bmN0aW9ucy5cbiAgLy8gQ2hlY2sgdGhhdCB2YWx1ZSBpcyBhbiBvYmplY3Qgd2l0aCBhbiBpbnNwZWN0IGZ1bmN0aW9uIG9uIGl0XG4gIGlmIChjdHguY3VzdG9tSW5zcGVjdCAmJlxuICAgICAgdmFsdWUgJiZcbiAgICAgIGlzRnVuY3Rpb24odmFsdWUuaW5zcGVjdCkgJiZcbiAgICAgIC8vIEZpbHRlciBvdXQgdGhlIHV0aWwgbW9kdWxlLCBpdCdzIGluc3BlY3QgZnVuY3Rpb24gaXMgc3BlY2lhbFxuICAgICAgdmFsdWUuaW5zcGVjdCAhPT0gZXhwb3J0cy5pbnNwZWN0ICYmXG4gICAgICAvLyBBbHNvIGZpbHRlciBvdXQgYW55IHByb3RvdHlwZSBvYmplY3RzIHVzaW5nIHRoZSBjaXJjdWxhciBjaGVjay5cbiAgICAgICEodmFsdWUuY29uc3RydWN0b3IgJiYgdmFsdWUuY29uc3RydWN0b3IucHJvdG90eXBlID09PSB2YWx1ZSkpIHtcbiAgICB2YXIgcmV0ID0gdmFsdWUuaW5zcGVjdChyZWN1cnNlVGltZXMsIGN0eCk7XG4gICAgaWYgKCFpc1N0cmluZyhyZXQpKSB7XG4gICAgICByZXQgPSBmb3JtYXRWYWx1ZShjdHgsIHJldCwgcmVjdXJzZVRpbWVzKTtcbiAgICB9XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIC8vIFByaW1pdGl2ZSB0eXBlcyBjYW5ub3QgaGF2ZSBwcm9wZXJ0aWVzXG4gIHZhciBwcmltaXRpdmUgPSBmb3JtYXRQcmltaXRpdmUoY3R4LCB2YWx1ZSk7XG4gIGlmIChwcmltaXRpdmUpIHtcbiAgICByZXR1cm4gcHJpbWl0aXZlO1xuICB9XG5cbiAgLy8gTG9vayB1cCB0aGUga2V5cyBvZiB0aGUgb2JqZWN0LlxuICB2YXIga2V5cyA9IE9iamVjdC5rZXlzKHZhbHVlKTtcbiAgdmFyIHZpc2libGVLZXlzID0gYXJyYXlUb0hhc2goa2V5cyk7XG5cbiAgaWYgKGN0eC5zaG93SGlkZGVuKSB7XG4gICAga2V5cyA9IE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHZhbHVlKTtcbiAgfVxuXG4gIC8vIElFIGRvZXNuJ3QgbWFrZSBlcnJvciBmaWVsZHMgbm9uLWVudW1lcmFibGVcbiAgLy8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL2R3dzUyc2J0KHY9dnMuOTQpLmFzcHhcbiAgaWYgKGlzRXJyb3IodmFsdWUpXG4gICAgICAmJiAoa2V5cy5pbmRleE9mKCdtZXNzYWdlJykgPj0gMCB8fCBrZXlzLmluZGV4T2YoJ2Rlc2NyaXB0aW9uJykgPj0gMCkpIHtcbiAgICByZXR1cm4gZm9ybWF0RXJyb3IodmFsdWUpO1xuICB9XG5cbiAgLy8gU29tZSB0eXBlIG9mIG9iamVjdCB3aXRob3V0IHByb3BlcnRpZXMgY2FuIGJlIHNob3J0Y3V0dGVkLlxuICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICBpZiAoaXNGdW5jdGlvbih2YWx1ZSkpIHtcbiAgICAgIHZhciBuYW1lID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoJ1tGdW5jdGlvbicgKyBuYW1lICsgJ10nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgICByZXR1cm4gY3R4LnN0eWxpemUoUmVnRXhwLnByb3RvdHlwZS50b1N0cmluZy5jYWxsKHZhbHVlKSwgJ3JlZ2V4cCcpO1xuICAgIH1cbiAgICBpZiAoaXNEYXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKERhdGUucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwodmFsdWUpLCAnZGF0ZScpO1xuICAgIH1cbiAgICBpZiAoaXNFcnJvcih2YWx1ZSkpIHtcbiAgICAgIHJldHVybiBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGJhc2UgPSAnJywgYXJyYXkgPSBmYWxzZSwgYnJhY2VzID0gWyd7JywgJ30nXTtcblxuICAvLyBNYWtlIEFycmF5IHNheSB0aGF0IHRoZXkgYXJlIEFycmF5XG4gIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgIGFycmF5ID0gdHJ1ZTtcbiAgICBicmFjZXMgPSBbJ1snLCAnXSddO1xuICB9XG5cbiAgLy8gTWFrZSBmdW5jdGlvbnMgc2F5IHRoYXQgdGhleSBhcmUgZnVuY3Rpb25zXG4gIGlmIChpc0Z1bmN0aW9uKHZhbHVlKSkge1xuICAgIHZhciBuID0gdmFsdWUubmFtZSA/ICc6ICcgKyB2YWx1ZS5uYW1lIDogJyc7XG4gICAgYmFzZSA9ICcgW0Z1bmN0aW9uJyArIG4gKyAnXSc7XG4gIH1cblxuICAvLyBNYWtlIFJlZ0V4cHMgc2F5IHRoYXQgdGhleSBhcmUgUmVnRXhwc1xuICBpZiAoaXNSZWdFeHAodmFsdWUpKSB7XG4gICAgYmFzZSA9ICcgJyArIFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGRhdGVzIHdpdGggcHJvcGVydGllcyBmaXJzdCBzYXkgdGhlIGRhdGVcbiAgaWYgKGlzRGF0ZSh2YWx1ZSkpIHtcbiAgICBiYXNlID0gJyAnICsgRGF0ZS5wcm90b3R5cGUudG9VVENTdHJpbmcuY2FsbCh2YWx1ZSk7XG4gIH1cblxuICAvLyBNYWtlIGVycm9yIHdpdGggbWVzc2FnZSBmaXJzdCBzYXkgdGhlIGVycm9yXG4gIGlmIChpc0Vycm9yKHZhbHVlKSkge1xuICAgIGJhc2UgPSAnICcgKyBmb3JtYXRFcnJvcih2YWx1ZSk7XG4gIH1cblxuICBpZiAoa2V5cy5sZW5ndGggPT09IDAgJiYgKCFhcnJheSB8fCB2YWx1ZS5sZW5ndGggPT0gMCkpIHtcbiAgICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArIGJyYWNlc1sxXTtcbiAgfVxuXG4gIGlmIChyZWN1cnNlVGltZXMgPCAwKSB7XG4gICAgaWYgKGlzUmVnRXhwKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKFJlZ0V4cC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSksICdyZWdleHAnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGN0eC5zdHlsaXplKCdbT2JqZWN0XScsICdzcGVjaWFsJyk7XG4gICAgfVxuICB9XG5cbiAgY3R4LnNlZW4ucHVzaCh2YWx1ZSk7XG5cbiAgdmFyIG91dHB1dDtcbiAgaWYgKGFycmF5KSB7XG4gICAgb3V0cHV0ID0gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cyk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0ID0ga2V5cy5tYXAoZnVuY3Rpb24oa2V5KSB7XG4gICAgICByZXR1cm4gZm9ybWF0UHJvcGVydHkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5LCBhcnJheSk7XG4gICAgfSk7XG4gIH1cblxuICBjdHguc2Vlbi5wb3AoKTtcblxuICByZXR1cm4gcmVkdWNlVG9TaW5nbGVTdHJpbmcob3V0cHV0LCBiYXNlLCBicmFjZXMpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdFByaW1pdGl2ZShjdHgsIHZhbHVlKSB7XG4gIGlmIChpc1VuZGVmaW5lZCh2YWx1ZSkpXG4gICAgcmV0dXJuIGN0eC5zdHlsaXplKCd1bmRlZmluZWQnLCAndW5kZWZpbmVkJyk7XG4gIGlmIChpc1N0cmluZyh2YWx1ZSkpIHtcbiAgICB2YXIgc2ltcGxlID0gJ1xcJycgKyBKU09OLnN0cmluZ2lmeSh2YWx1ZSkucmVwbGFjZSgvXlwifFwiJC9nLCAnJylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5yZXBsYWNlKC9cXFxcXCIvZywgJ1wiJykgKyAnXFwnJztcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoc2ltcGxlLCAnc3RyaW5nJyk7XG4gIH1cbiAgaWYgKGlzTnVtYmVyKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ251bWJlcicpO1xuICBpZiAoaXNCb29sZWFuKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJycgKyB2YWx1ZSwgJ2Jvb2xlYW4nKTtcbiAgLy8gRm9yIHNvbWUgcmVhc29uIHR5cGVvZiBudWxsIGlzIFwib2JqZWN0XCIsIHNvIHNwZWNpYWwgY2FzZSBoZXJlLlxuICBpZiAoaXNOdWxsKHZhbHVlKSlcbiAgICByZXR1cm4gY3R4LnN0eWxpemUoJ251bGwnLCAnbnVsbCcpO1xufVxuXG5cbmZ1bmN0aW9uIGZvcm1hdEVycm9yKHZhbHVlKSB7XG4gIHJldHVybiAnWycgKyBFcnJvci5wcm90b3R5cGUudG9TdHJpbmcuY2FsbCh2YWx1ZSkgKyAnXSc7XG59XG5cblxuZnVuY3Rpb24gZm9ybWF0QXJyYXkoY3R4LCB2YWx1ZSwgcmVjdXJzZVRpbWVzLCB2aXNpYmxlS2V5cywga2V5cykge1xuICB2YXIgb3V0cHV0ID0gW107XG4gIGZvciAodmFyIGkgPSAwLCBsID0gdmFsdWUubGVuZ3RoOyBpIDwgbDsgKytpKSB7XG4gICAgaWYgKGhhc093blByb3BlcnR5KHZhbHVlLCBTdHJpbmcoaSkpKSB7XG4gICAgICBvdXRwdXQucHVzaChmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLFxuICAgICAgICAgIFN0cmluZyhpKSwgdHJ1ZSkpO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXRwdXQucHVzaCgnJyk7XG4gICAgfVxuICB9XG4gIGtleXMuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICBpZiAoIWtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIG91dHB1dC5wdXNoKGZvcm1hdFByb3BlcnR5KGN0eCwgdmFsdWUsIHJlY3Vyc2VUaW1lcywgdmlzaWJsZUtleXMsXG4gICAgICAgICAga2V5LCB0cnVlKSk7XG4gICAgfVxuICB9KTtcbiAgcmV0dXJuIG91dHB1dDtcbn1cblxuXG5mdW5jdGlvbiBmb3JtYXRQcm9wZXJ0eShjdHgsIHZhbHVlLCByZWN1cnNlVGltZXMsIHZpc2libGVLZXlzLCBrZXksIGFycmF5KSB7XG4gIHZhciBuYW1lLCBzdHIsIGRlc2M7XG4gIGRlc2MgPSBPYmplY3QuZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKHZhbHVlLCBrZXkpIHx8IHsgdmFsdWU6IHZhbHVlW2tleV0gfTtcbiAgaWYgKGRlc2MuZ2V0KSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW0dldHRlci9TZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyID0gY3R4LnN0eWxpemUoJ1tHZXR0ZXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRlc2Muc2V0KSB7XG4gICAgICBzdHIgPSBjdHguc3R5bGl6ZSgnW1NldHRlcl0nLCAnc3BlY2lhbCcpO1xuICAgIH1cbiAgfVxuICBpZiAoIWhhc093blByb3BlcnR5KHZpc2libGVLZXlzLCBrZXkpKSB7XG4gICAgbmFtZSA9ICdbJyArIGtleSArICddJztcbiAgfVxuICBpZiAoIXN0cikge1xuICAgIGlmIChjdHguc2Vlbi5pbmRleE9mKGRlc2MudmFsdWUpIDwgMCkge1xuICAgICAgaWYgKGlzTnVsbChyZWN1cnNlVGltZXMpKSB7XG4gICAgICAgIHN0ciA9IGZvcm1hdFZhbHVlKGN0eCwgZGVzYy52YWx1ZSwgbnVsbCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzdHIgPSBmb3JtYXRWYWx1ZShjdHgsIGRlc2MudmFsdWUsIHJlY3Vyc2VUaW1lcyAtIDEpO1xuICAgICAgfVxuICAgICAgaWYgKHN0ci5pbmRleE9mKCdcXG4nKSA+IC0xKSB7XG4gICAgICAgIGlmIChhcnJheSkge1xuICAgICAgICAgIHN0ciA9IHN0ci5zcGxpdCgnXFxuJykubWFwKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgICAgIHJldHVybiAnICAnICsgbGluZTtcbiAgICAgICAgICB9KS5qb2luKCdcXG4nKS5zdWJzdHIoMik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgc3RyID0gJ1xcbicgKyBzdHIuc3BsaXQoJ1xcbicpLm1hcChmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgICAgICByZXR1cm4gJyAgICcgKyBsaW5lO1xuICAgICAgICAgIH0pLmpvaW4oJ1xcbicpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0ciA9IGN0eC5zdHlsaXplKCdbQ2lyY3VsYXJdJywgJ3NwZWNpYWwnKTtcbiAgICB9XG4gIH1cbiAgaWYgKGlzVW5kZWZpbmVkKG5hbWUpKSB7XG4gICAgaWYgKGFycmF5ICYmIGtleS5tYXRjaCgvXlxcZCskLykpIHtcbiAgICAgIHJldHVybiBzdHI7XG4gICAgfVxuICAgIG5hbWUgPSBKU09OLnN0cmluZ2lmeSgnJyArIGtleSk7XG4gICAgaWYgKG5hbWUubWF0Y2goL15cIihbYS16QS1aX11bYS16QS1aXzAtOV0qKVwiJC8pKSB7XG4gICAgICBuYW1lID0gbmFtZS5zdWJzdHIoMSwgbmFtZS5sZW5ndGggLSAyKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnbmFtZScpO1xuICAgIH0gZWxzZSB7XG4gICAgICBuYW1lID0gbmFtZS5yZXBsYWNlKC8nL2csIFwiXFxcXCdcIilcbiAgICAgICAgICAgICAgICAgLnJlcGxhY2UoL1xcXFxcIi9nLCAnXCInKVxuICAgICAgICAgICAgICAgICAucmVwbGFjZSgvKF5cInxcIiQpL2csIFwiJ1wiKTtcbiAgICAgIG5hbWUgPSBjdHguc3R5bGl6ZShuYW1lLCAnc3RyaW5nJyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5hbWUgKyAnOiAnICsgc3RyO1xufVxuXG5cbmZ1bmN0aW9uIHJlZHVjZVRvU2luZ2xlU3RyaW5nKG91dHB1dCwgYmFzZSwgYnJhY2VzKSB7XG4gIHZhciBudW1MaW5lc0VzdCA9IDA7XG4gIHZhciBsZW5ndGggPSBvdXRwdXQucmVkdWNlKGZ1bmN0aW9uKHByZXYsIGN1cikge1xuICAgIG51bUxpbmVzRXN0Kys7XG4gICAgaWYgKGN1ci5pbmRleE9mKCdcXG4nKSA+PSAwKSBudW1MaW5lc0VzdCsrO1xuICAgIHJldHVybiBwcmV2ICsgY3VyLnJlcGxhY2UoL1xcdTAwMWJcXFtcXGRcXGQ/bS9nLCAnJykubGVuZ3RoICsgMTtcbiAgfSwgMCk7XG5cbiAgaWYgKGxlbmd0aCA+IDYwKSB7XG4gICAgcmV0dXJuIGJyYWNlc1swXSArXG4gICAgICAgICAgIChiYXNlID09PSAnJyA/ICcnIDogYmFzZSArICdcXG4gJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBvdXRwdXQuam9pbignLFxcbiAgJykgK1xuICAgICAgICAgICAnICcgK1xuICAgICAgICAgICBicmFjZXNbMV07XG4gIH1cblxuICByZXR1cm4gYnJhY2VzWzBdICsgYmFzZSArICcgJyArIG91dHB1dC5qb2luKCcsICcpICsgJyAnICsgYnJhY2VzWzFdO1xufVxuXG5cbi8vIE5PVEU6IFRoZXNlIHR5cGUgY2hlY2tpbmcgZnVuY3Rpb25zIGludGVudGlvbmFsbHkgZG9uJ3QgdXNlIGBpbnN0YW5jZW9mYFxuLy8gYmVjYXVzZSBpdCBpcyBmcmFnaWxlIGFuZCBjYW4gYmUgZWFzaWx5IGZha2VkIHdpdGggYE9iamVjdC5jcmVhdGUoKWAuXG5mdW5jdGlvbiBpc0FycmF5KGFyKSB7XG4gIHJldHVybiBBcnJheS5pc0FycmF5KGFyKTtcbn1cbmV4cG9ydHMuaXNBcnJheSA9IGlzQXJyYXk7XG5cbmZ1bmN0aW9uIGlzQm9vbGVhbihhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdib29sZWFuJztcbn1cbmV4cG9ydHMuaXNCb29sZWFuID0gaXNCb29sZWFuO1xuXG5mdW5jdGlvbiBpc051bGwoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IG51bGw7XG59XG5leHBvcnRzLmlzTnVsbCA9IGlzTnVsbDtcblxuZnVuY3Rpb24gaXNOdWxsT3JVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNOdWxsT3JVbmRlZmluZWQgPSBpc051bGxPclVuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNOdW1iZXIoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnbnVtYmVyJztcbn1cbmV4cG9ydHMuaXNOdW1iZXIgPSBpc051bWJlcjtcblxuZnVuY3Rpb24gaXNTdHJpbmcoYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3RyaW5nJztcbn1cbmV4cG9ydHMuaXNTdHJpbmcgPSBpc1N0cmluZztcblxuZnVuY3Rpb24gaXNTeW1ib2woYXJnKSB7XG4gIHJldHVybiB0eXBlb2YgYXJnID09PSAnc3ltYm9sJztcbn1cbmV4cG9ydHMuaXNTeW1ib2wgPSBpc1N5bWJvbDtcblxuZnVuY3Rpb24gaXNVbmRlZmluZWQoYXJnKSB7XG4gIHJldHVybiBhcmcgPT09IHZvaWQgMDtcbn1cbmV4cG9ydHMuaXNVbmRlZmluZWQgPSBpc1VuZGVmaW5lZDtcblxuZnVuY3Rpb24gaXNSZWdFeHAocmUpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHJlKSAmJiBvYmplY3RUb1N0cmluZyhyZSkgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufVxuZXhwb3J0cy5pc1JlZ0V4cCA9IGlzUmVnRXhwO1xuXG5mdW5jdGlvbiBpc09iamVjdChhcmcpIHtcbiAgcmV0dXJuIHR5cGVvZiBhcmcgPT09ICdvYmplY3QnICYmIGFyZyAhPT0gbnVsbDtcbn1cbmV4cG9ydHMuaXNPYmplY3QgPSBpc09iamVjdDtcblxuZnVuY3Rpb24gaXNEYXRlKGQpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KGQpICYmIG9iamVjdFRvU3RyaW5nKGQpID09PSAnW29iamVjdCBEYXRlXSc7XG59XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcblxuZnVuY3Rpb24gaXNFcnJvcihlKSB7XG4gIHJldHVybiBpc09iamVjdChlKSAmJlxuICAgICAgKG9iamVjdFRvU3RyaW5nKGUpID09PSAnW29iamVjdCBFcnJvcl0nIHx8IGUgaW5zdGFuY2VvZiBFcnJvcik7XG59XG5leHBvcnRzLmlzRXJyb3IgPSBpc0Vycm9yO1xuXG5mdW5jdGlvbiBpc0Z1bmN0aW9uKGFyZykge1xuICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ2Z1bmN0aW9uJztcbn1cbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5cbmZ1bmN0aW9uIGlzUHJpbWl0aXZlKGFyZykge1xuICByZXR1cm4gYXJnID09PSBudWxsIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnYm9vbGVhbicgfHxcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICdudW1iZXInIHx8XG4gICAgICAgICB0eXBlb2YgYXJnID09PSAnc3RyaW5nJyB8fFxuICAgICAgICAgdHlwZW9mIGFyZyA9PT0gJ3N5bWJvbCcgfHwgIC8vIEVTNiBzeW1ib2xcbiAgICAgICAgIHR5cGVvZiBhcmcgPT09ICd1bmRlZmluZWQnO1xufVxuZXhwb3J0cy5pc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlO1xuXG5leHBvcnRzLmlzQnVmZmVyID0gcmVxdWlyZSgnLi9zdXBwb3J0L2lzQnVmZmVyJyk7XG5cbmZ1bmN0aW9uIG9iamVjdFRvU3RyaW5nKG8pIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvKTtcbn1cblxuXG5mdW5jdGlvbiBwYWQobikge1xuICByZXR1cm4gbiA8IDEwID8gJzAnICsgbi50b1N0cmluZygxMCkgOiBuLnRvU3RyaW5nKDEwKTtcbn1cblxuXG52YXIgbW9udGhzID0gWydKYW4nLCAnRmViJywgJ01hcicsICdBcHInLCAnTWF5JywgJ0p1bicsICdKdWwnLCAnQXVnJywgJ1NlcCcsXG4gICAgICAgICAgICAgICdPY3QnLCAnTm92JywgJ0RlYyddO1xuXG4vLyAyNiBGZWIgMTY6MTk6MzRcbmZ1bmN0aW9uIHRpbWVzdGFtcCgpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZSgpO1xuICB2YXIgdGltZSA9IFtwYWQoZC5nZXRIb3VycygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0TWludXRlcygpKSxcbiAgICAgICAgICAgICAgcGFkKGQuZ2V0U2Vjb25kcygpKV0uam9pbignOicpO1xuICByZXR1cm4gW2QuZ2V0RGF0ZSgpLCBtb250aHNbZC5nZXRNb250aCgpXSwgdGltZV0uam9pbignICcpO1xufVxuXG5cbi8vIGxvZyBpcyBqdXN0IGEgdGhpbiB3cmFwcGVyIHRvIGNvbnNvbGUubG9nIHRoYXQgcHJlcGVuZHMgYSB0aW1lc3RhbXBcbmV4cG9ydHMubG9nID0gZnVuY3Rpb24oKSB7XG4gIGNvbnNvbGUubG9nKCclcyAtICVzJywgdGltZXN0YW1wKCksIGV4cG9ydHMuZm9ybWF0LmFwcGx5KGV4cG9ydHMsIGFyZ3VtZW50cykpO1xufTtcblxuXG4vKipcbiAqIEluaGVyaXQgdGhlIHByb3RvdHlwZSBtZXRob2RzIGZyb20gb25lIGNvbnN0cnVjdG9yIGludG8gYW5vdGhlci5cbiAqXG4gKiBUaGUgRnVuY3Rpb24ucHJvdG90eXBlLmluaGVyaXRzIGZyb20gbGFuZy5qcyByZXdyaXR0ZW4gYXMgYSBzdGFuZGFsb25lXG4gKiBmdW5jdGlvbiAobm90IG9uIEZ1bmN0aW9uLnByb3RvdHlwZSkuIE5PVEU6IElmIHRoaXMgZmlsZSBpcyB0byBiZSBsb2FkZWRcbiAqIGR1cmluZyBib290c3RyYXBwaW5nIHRoaXMgZnVuY3Rpb24gbmVlZHMgdG8gYmUgcmV3cml0dGVuIHVzaW5nIHNvbWUgbmF0aXZlXG4gKiBmdW5jdGlvbnMgYXMgcHJvdG90eXBlIHNldHVwIHVzaW5nIG5vcm1hbCBKYXZhU2NyaXB0IGRvZXMgbm90IHdvcmsgYXNcbiAqIGV4cGVjdGVkIGR1cmluZyBib290c3RyYXBwaW5nIChzZWUgbWlycm9yLmpzIGluIHIxMTQ5MDMpLlxuICpcbiAqIEBwYXJhbSB7ZnVuY3Rpb259IGN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gd2hpY2ggbmVlZHMgdG8gaW5oZXJpdCB0aGVcbiAqICAgICBwcm90b3R5cGUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9ufSBzdXBlckN0b3IgQ29uc3RydWN0b3IgZnVuY3Rpb24gdG8gaW5oZXJpdCBwcm90b3R5cGUgZnJvbS5cbiAqL1xuZXhwb3J0cy5pbmhlcml0cyA9IHJlcXVpcmUoJ2luaGVyaXRzJyk7XG5cbmV4cG9ydHMuX2V4dGVuZCA9IGZ1bmN0aW9uKG9yaWdpbiwgYWRkKSB7XG4gIC8vIERvbid0IGRvIGFueXRoaW5nIGlmIGFkZCBpc24ndCBhbiBvYmplY3RcbiAgaWYgKCFhZGQgfHwgIWlzT2JqZWN0KGFkZCkpIHJldHVybiBvcmlnaW47XG5cbiAgdmFyIGtleXMgPSBPYmplY3Qua2V5cyhhZGQpO1xuICB2YXIgaSA9IGtleXMubGVuZ3RoO1xuICB3aGlsZSAoaS0tKSB7XG4gICAgb3JpZ2luW2tleXNbaV1dID0gYWRkW2tleXNbaV1dO1xuICB9XG4gIHJldHVybiBvcmlnaW47XG59O1xuXG5mdW5jdGlvbiBoYXNPd25Qcm9wZXJ0eShvYmosIHByb3ApIHtcbiAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChvYmosIHByb3ApO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMvYXNzZXJ0L25vZGVfbW9kdWxlcy91dGlsL3V0aWwuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL2Fzc2VydC9ub2RlX21vZHVsZXMvdXRpbFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ob2JqKSB7XG4gICAgaWYgKHR5cGVvZiBvYmogPT09ICdzdHJpbmcnKSByZXR1cm4gY2FtZWxDYXNlKG9iaik7XG4gICAgcmV0dXJuIHdhbGsob2JqKTtcbn07XG5cbmZ1bmN0aW9uIHdhbGsgKG9iaikge1xuICAgIGlmICghb2JqIHx8IHR5cGVvZiBvYmogIT09ICdvYmplY3QnKSByZXR1cm4gb2JqO1xuICAgIGlmIChpc0FycmF5KG9iaikpIHJldHVybiBtYXAob2JqLCB3YWxrKTtcbiAgICByZXR1cm4gcmVkdWNlKG9iamVjdEtleXMob2JqKSwgZnVuY3Rpb24gKGFjYywga2V5KSB7XG4gICAgICAgIHZhciBjYW1lbCA9IGNhbWVsQ2FzZShrZXkpO1xuICAgICAgICBhY2NbY2FtZWxdID0gd2FsayhvYmpba2V5XSk7XG4gICAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xufVxuXG5mdW5jdGlvbiBjYW1lbENhc2Uoc3RyKSB7XG4gICAgcmV0dXJuIHN0ci5yZXBsYWNlKC9bXy4tXShcXHd8JCkvZywgZnVuY3Rpb24gKF8seCkge1xuICAgICAgICByZXR1cm4geC50b1VwcGVyQ2FzZSgpXG4gICAgfSk7XG59XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheSB8fCBmdW5jdGlvbiAob2JqKSB7XG4gICAgcmV0dXJuIE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuY2FsbChvYmopID09PSAnW29iamVjdCBBcnJheV0nO1xufTtcblxudmFyIGhhcyA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgb2JqZWN0S2V5cyA9IE9iamVjdC5rZXlzIHx8IGZ1bmN0aW9uIChvYmopIHtcbiAgICB2YXIga2V5cyA9IFtdO1xuICAgIGZvciAodmFyIGtleSBpbiBvYmopIHtcbiAgICAgICAgaWYgKGhhcy5jYWxsKG9iaiwga2V5KSkga2V5cy5wdXNoKGtleSk7XG4gICAgfVxuICAgIHJldHVybiBrZXlzO1xufTtcblxuZnVuY3Rpb24gbWFwICh4cywgZikge1xuICAgIGlmICh4cy5tYXApIHJldHVybiB4cy5tYXAoZik7XG4gICAgdmFyIHJlcyA9IFtdO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcmVzLnB1c2goZih4c1tpXSwgaSkpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzO1xufVxuXG5mdW5jdGlvbiByZWR1Y2UgKHhzLCBmLCBhY2MpIHtcbiAgICBpZiAoeHMucmVkdWNlKSByZXR1cm4geHMucmVkdWNlKGYsIGFjYyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBhY2MgPSBmKGFjYywgeHNbaV0sIGkpO1xuICAgIH1cbiAgICByZXR1cm4gYWNjO1xufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMvY2FtZWxpemUvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL2NhbWVsaXplXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIG5hcmdzID0gL1xceyhbMC05YS16QS1aXSspXFx9L2dcbnZhciBzbGljZSA9IEFycmF5LnByb3RvdHlwZS5zbGljZVxuXG5tb2R1bGUuZXhwb3J0cyA9IHRlbXBsYXRlXG5cbmZ1bmN0aW9uIHRlbXBsYXRlKHN0cmluZykge1xuICAgIHZhciBhcmdzXG4gICAgXG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPT09IDIgJiYgdHlwZW9mIGFyZ3VtZW50c1sxXSA9PT0gXCJvYmplY3RcIikge1xuICAgICAgICBhcmdzID0gYXJndW1lbnRzWzFdXG4gICAgfSBlbHNlIHtcbiAgICAgICAgYXJncyA9IHNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuICAgIH1cblxuICAgIGlmICghYXJncyB8fCAhYXJncy5oYXNPd25Qcm9wZXJ0eSkge1xuICAgICAgICBhcmdzID0ge31cbiAgICB9XG5cbiAgICByZXR1cm4gc3RyaW5nLnJlcGxhY2UobmFyZ3MsIGZ1bmN0aW9uIHJlcGxhY2VBcmcobWF0Y2gsIGksIGluZGV4KSB7XG4gICAgICAgIHZhciByZXN1bHRcblxuICAgICAgICBpZiAoc3RyaW5nW2luZGV4IC0gMV0gPT09IFwie1wiICYmXG4gICAgICAgICAgICBzdHJpbmdbaW5kZXggKyBtYXRjaC5sZW5ndGhdID09PSBcIn1cIikge1xuICAgICAgICAgICAgcmV0dXJuIGlcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc3VsdCA9IGFyZ3MuaGFzT3duUHJvcGVydHkoaSkgPyBhcmdzW2ldIDogbnVsbFxuICAgICAgICAgICAgaWYgKHJlc3VsdCA9PT0gbnVsbCB8fCByZXN1bHQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgIHJldHVybiBcIlwiXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHJldHVybiByZXN1bHRcbiAgICAgICAgfVxuICAgIH0pXG59XG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMvc3RyaW5nLXRlbXBsYXRlL2luZGV4LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy9zdHJpbmctdGVtcGxhdGVcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5tb2R1bGUuZXhwb3J0cyA9IGhhc0tleXNcblxuZnVuY3Rpb24gaGFzS2V5cyhzb3VyY2UpIHtcbiAgICByZXR1cm4gc291cmNlICE9PSBudWxsICYmXG4gICAgICAgICh0eXBlb2Ygc291cmNlID09PSBcIm9iamVjdFwiIHx8XG4gICAgICAgIHR5cGVvZiBzb3VyY2UgPT09IFwiZnVuY3Rpb25cIilcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL3h0ZW5kL2hhcy1rZXlzLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy94dGVuZFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBLZXlzID0gcmVxdWlyZShcIm9iamVjdC1rZXlzXCIpXG52YXIgaGFzS2V5cyA9IHJlcXVpcmUoXCIuL2hhcy1rZXlzXCIpXG5cbm1vZHVsZS5leHBvcnRzID0gZXh0ZW5kXG5cbmZ1bmN0aW9uIGV4dGVuZCh0YXJnZXQpIHtcbiAgICB2YXIgc291cmNlcyA9IFtdLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKVxuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzb3VyY2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBzb3VyY2UgPSBzb3VyY2VzW2ldXG5cbiAgICAgICAgaWYgKCFoYXNLZXlzKHNvdXJjZSkpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICB2YXIga2V5cyA9IEtleXMoc291cmNlKVxuXG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwga2V5cy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgdmFyIG5hbWUgPSBrZXlzW2pdXG4gICAgICAgICAgICB0YXJnZXRbbmFtZV0gPSBzb3VyY2VbbmFtZV1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0YXJnZXRcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL3h0ZW5kL211dGFibGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL3h0ZW5kXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGhhc093biA9IE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHk7XG52YXIgdG9TdHJpbmcgPSBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nO1xuXG52YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uIChmbikge1xuXHR2YXIgaXNGdW5jID0gKHR5cGVvZiBmbiA9PT0gJ2Z1bmN0aW9uJyAmJiAhKGZuIGluc3RhbmNlb2YgUmVnRXhwKSkgfHwgdG9TdHJpbmcuY2FsbChmbikgPT09ICdbb2JqZWN0IEZ1bmN0aW9uXSc7XG5cdGlmICghaXNGdW5jICYmIHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnKSB7XG5cdFx0aXNGdW5jID0gZm4gPT09IHdpbmRvdy5zZXRUaW1lb3V0IHx8IGZuID09PSB3aW5kb3cuYWxlcnQgfHwgZm4gPT09IHdpbmRvdy5jb25maXJtIHx8IGZuID09PSB3aW5kb3cucHJvbXB0O1xuXHR9XG5cdHJldHVybiBpc0Z1bmM7XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIGZvckVhY2gob2JqLCBmbikge1xuXHRpZiAoIWlzRnVuY3Rpb24oZm4pKSB7XG5cdFx0dGhyb3cgbmV3IFR5cGVFcnJvcignaXRlcmF0b3IgbXVzdCBiZSBhIGZ1bmN0aW9uJyk7XG5cdH1cblx0dmFyIGksIGssXG5cdFx0aXNTdHJpbmcgPSB0eXBlb2Ygb2JqID09PSAnc3RyaW5nJyxcblx0XHRsID0gb2JqLmxlbmd0aCxcblx0XHRjb250ZXh0ID0gYXJndW1lbnRzLmxlbmd0aCA+IDIgPyBhcmd1bWVudHNbMl0gOiBudWxsO1xuXHRpZiAobCA9PT0gK2wpIHtcblx0XHRmb3IgKGkgPSAwOyBpIDwgbDsgaSsrKSB7XG5cdFx0XHRpZiAoY29udGV4dCA9PT0gbnVsbCkge1xuXHRcdFx0XHRmbihpc1N0cmluZyA/IG9iai5jaGFyQXQoaSkgOiBvYmpbaV0sIGksIG9iaik7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmbi5jYWxsKGNvbnRleHQsIGlzU3RyaW5nID8gb2JqLmNoYXJBdChpKSA6IG9ialtpXSwgaSwgb2JqKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0Zm9yIChrIGluIG9iaikge1xuXHRcdFx0aWYgKGhhc093bi5jYWxsKG9iaiwgaykpIHtcblx0XHRcdFx0aWYgKGNvbnRleHQgPT09IG51bGwpIHtcblx0XHRcdFx0XHRmbihvYmpba10sIGssIG9iaik7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Zm4uY2FsbChjb250ZXh0LCBvYmpba10sIGssIG9iaik7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cbn07XG5cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL3h0ZW5kL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5cy9mb3JlYWNoLmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy94dGVuZC9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXNcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5tb2R1bGUuZXhwb3J0cyA9IE9iamVjdC5rZXlzIHx8IHJlcXVpcmUoJy4vc2hpbScpO1xuXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy94dGVuZC9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaW5kZXguanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL3h0ZW5kL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciB0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmc7XG5cbm1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24gaXNBcmd1bWVudHModmFsdWUpIHtcblx0dmFyIHN0ciA9IHRvU3RyaW5nLmNhbGwodmFsdWUpO1xuXHR2YXIgaXNBcmd1bWVudHMgPSBzdHIgPT09ICdbb2JqZWN0IEFyZ3VtZW50c10nO1xuXHRpZiAoIWlzQXJndW1lbnRzKSB7XG5cdFx0aXNBcmd1bWVudHMgPSBzdHIgIT09ICdbb2JqZWN0IEFycmF5XSdcblx0XHRcdCYmIHZhbHVlICE9PSBudWxsXG5cdFx0XHQmJiB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnXG5cdFx0XHQmJiB0eXBlb2YgdmFsdWUubGVuZ3RoID09PSAnbnVtYmVyJ1xuXHRcdFx0JiYgdmFsdWUubGVuZ3RoID49IDBcblx0XHRcdCYmIHRvU3RyaW5nLmNhbGwodmFsdWUuY2FsbGVlKSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJztcblx0fVxuXHRyZXR1cm4gaXNBcmd1bWVudHM7XG59O1xuXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy94dGVuZC9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvaXNBcmd1bWVudHMuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvZXJyb3Ivbm9kZV9tb2R1bGVzL3h0ZW5kL25vZGVfbW9kdWxlcy9vYmplY3Qta2V5c1wiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbihmdW5jdGlvbiAoKSB7XG5cdFwidXNlIHN0cmljdFwiO1xuXG5cdC8vIG1vZGlmaWVkIGZyb20gaHR0cHM6Ly9naXRodWIuY29tL2tyaXNrb3dhbC9lczUtc2hpbVxuXHR2YXIgaGFzID0gT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eSxcblx0XHR0b1N0cmluZyA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJpbmcsXG5cdFx0Zm9yRWFjaCA9IHJlcXVpcmUoJy4vZm9yZWFjaCcpLFxuXHRcdGlzQXJncyA9IHJlcXVpcmUoJy4vaXNBcmd1bWVudHMnKSxcblx0XHRoYXNEb250RW51bUJ1ZyA9ICEoeyd0b1N0cmluZyc6IG51bGx9KS5wcm9wZXJ0eUlzRW51bWVyYWJsZSgndG9TdHJpbmcnKSxcblx0XHRoYXNQcm90b0VudW1CdWcgPSAoZnVuY3Rpb24gKCkge30pLnByb3BlcnR5SXNFbnVtZXJhYmxlKCdwcm90b3R5cGUnKSxcblx0XHRkb250RW51bXMgPSBbXG5cdFx0XHRcInRvU3RyaW5nXCIsXG5cdFx0XHRcInRvTG9jYWxlU3RyaW5nXCIsXG5cdFx0XHRcInZhbHVlT2ZcIixcblx0XHRcdFwiaGFzT3duUHJvcGVydHlcIixcblx0XHRcdFwiaXNQcm90b3R5cGVPZlwiLFxuXHRcdFx0XCJwcm9wZXJ0eUlzRW51bWVyYWJsZVwiLFxuXHRcdFx0XCJjb25zdHJ1Y3RvclwiXG5cdFx0XSxcblx0XHRrZXlzU2hpbTtcblxuXHRrZXlzU2hpbSA9IGZ1bmN0aW9uIGtleXMob2JqZWN0KSB7XG5cdFx0dmFyIGlzT2JqZWN0ID0gb2JqZWN0ICE9PSBudWxsICYmIHR5cGVvZiBvYmplY3QgPT09ICdvYmplY3QnLFxuXHRcdFx0aXNGdW5jdGlvbiA9IHRvU3RyaW5nLmNhbGwob2JqZWN0KSA9PT0gJ1tvYmplY3QgRnVuY3Rpb25dJyxcblx0XHRcdGlzQXJndW1lbnRzID0gaXNBcmdzKG9iamVjdCksXG5cdFx0XHR0aGVLZXlzID0gW107XG5cblx0XHRpZiAoIWlzT2JqZWN0ICYmICFpc0Z1bmN0aW9uICYmICFpc0FyZ3VtZW50cykge1xuXHRcdFx0dGhyb3cgbmV3IFR5cGVFcnJvcihcIk9iamVjdC5rZXlzIGNhbGxlZCBvbiBhIG5vbi1vYmplY3RcIik7XG5cdFx0fVxuXG5cdFx0aWYgKGlzQXJndW1lbnRzKSB7XG5cdFx0XHRmb3JFYWNoKG9iamVjdCwgZnVuY3Rpb24gKHZhbHVlKSB7XG5cdFx0XHRcdHRoZUtleXMucHVzaCh2YWx1ZSk7XG5cdFx0XHR9KTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIG5hbWUsXG5cdFx0XHRcdHNraXBQcm90byA9IGhhc1Byb3RvRW51bUJ1ZyAmJiBpc0Z1bmN0aW9uO1xuXG5cdFx0XHRmb3IgKG5hbWUgaW4gb2JqZWN0KSB7XG5cdFx0XHRcdGlmICghKHNraXBQcm90byAmJiBuYW1lID09PSAncHJvdG90eXBlJykgJiYgaGFzLmNhbGwob2JqZWN0LCBuYW1lKSkge1xuXHRcdFx0XHRcdHRoZUtleXMucHVzaChuYW1lKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmIChoYXNEb250RW51bUJ1Zykge1xuXHRcdFx0dmFyIGN0b3IgPSBvYmplY3QuY29uc3RydWN0b3IsXG5cdFx0XHRcdHNraXBDb25zdHJ1Y3RvciA9IGN0b3IgJiYgY3Rvci5wcm90b3R5cGUgPT09IG9iamVjdDtcblxuXHRcdFx0Zm9yRWFjaChkb250RW51bXMsIGZ1bmN0aW9uIChkb250RW51bSkge1xuXHRcdFx0XHRpZiAoIShza2lwQ29uc3RydWN0b3IgJiYgZG9udEVudW0gPT09ICdjb25zdHJ1Y3RvcicpICYmIGhhcy5jYWxsKG9iamVjdCwgZG9udEVudW0pKSB7XG5cdFx0XHRcdFx0dGhlS2V5cy5wdXNoKGRvbnRFbnVtKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGVLZXlzO1xuXHR9O1xuXG5cdG1vZHVsZS5leHBvcnRzID0ga2V5c1NoaW07XG59KCkpO1xuXG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL2Vycm9yL25vZGVfbW9kdWxlcy94dGVuZC9ub2RlX21vZHVsZXMvb2JqZWN0LWtleXMvc2hpbS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci9ub2RlX21vZHVsZXMveHRlbmQvbm9kZV9tb2R1bGVzL29iamVjdC1rZXlzXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xudmFyIGFzc2VydCA9IHJlcXVpcmUoXCJhc3NlcnQvXCIpXG52YXIgY2FtZWxpemUgPSByZXF1aXJlKFwiY2FtZWxpemVcIilcbnZhciB0ZW1wbGF0ZSA9IHJlcXVpcmUoXCJzdHJpbmctdGVtcGxhdGVcIilcbnZhciBleHRlbmQgPSByZXF1aXJlKFwieHRlbmQvbXV0YWJsZVwiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IFR5cGVkRXJyb3JcblxuZnVuY3Rpb24gVHlwZWRFcnJvcihhcmdzKSB7XG4gICAgYXNzZXJ0KGFyZ3MsIFwiYXJncyBpcyByZXF1aXJlZFwiKTtcbiAgICBhc3NlcnQoYXJncy50eXBlLCBcImFyZ3MudHlwZSBpcyByZXF1aXJlZFwiKVxuICAgIGFzc2VydChhcmdzLm1lc3NhZ2UsIFwiYXJncy5tZXNzYWdlIGlzIHJlcXVpcmVkXCIpXG5cbiAgICB2YXIgbWVzc2FnZSA9IGFyZ3MubWVzc2FnZVxuXG4gICAgaWYgKGFyZ3MudHlwZSAmJiAhYXJncy5uYW1lKSB7XG4gICAgICAgIHZhciBlcnJvck5hbWUgPSBjYW1lbGl6ZShhcmdzLnR5cGUpICsgXCJFcnJvclwiXG4gICAgICAgIGFyZ3MubmFtZSA9IGVycm9yTmFtZVswXS50b1VwcGVyQ2FzZSgpICsgZXJyb3JOYW1lLnN1YnN0cigxKVxuICAgIH1cblxuICAgIGNyZWF0ZUVycm9yLnR5cGUgPSBhcmdzLnR5cGU7XG4gICAgY3JlYXRlRXJyb3IuX25hbWUgPSBhcmdzLm5hbWU7XG5cbiAgICByZXR1cm4gY3JlYXRlRXJyb3I7XG5cbiAgICBmdW5jdGlvbiBjcmVhdGVFcnJvcihvcHRzKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSBuZXcgRXJyb3IoKVxuXG4gICAgICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXN1bHQsIFwidHlwZVwiLCB7XG4gICAgICAgICAgICB2YWx1ZTogcmVzdWx0LnR5cGUsXG4gICAgICAgICAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgICAgICAgICAgd3JpdGFibGU6IHRydWUsXG4gICAgICAgICAgICBjb25maWd1cmFibGU6IHRydWVcbiAgICAgICAgfSlcblxuICAgICAgICB2YXIgb3B0aW9ucyA9IGV4dGVuZCh7fSwgYXJncywgb3B0cylcblxuICAgICAgICBleHRlbmQocmVzdWx0LCBvcHRpb25zKVxuICAgICAgICByZXN1bHQubWVzc2FnZSA9IHRlbXBsYXRlKG1lc3NhZ2UsIG9wdGlvbnMpXG5cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH1cbn1cblxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvci90eXBlZC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy9lcnJvclwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzID0gaXNUaHVua1xyXG5cclxuZnVuY3Rpb24gaXNUaHVuayh0KSB7XHJcbiAgICByZXR1cm4gdCAmJiB0LnR5cGUgPT09IFwiVGh1bmtcIlxyXG59XHJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWUvaXMtdGh1bmsuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWVcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG5tb2R1bGUuZXhwb3J0cyA9IGlzSG9va1xuXG5mdW5jdGlvbiBpc0hvb2soaG9vaykge1xuICAgIHJldHVybiBob29rICYmIHR5cGVvZiBob29rLmhvb2sgPT09IFwiZnVuY3Rpb25cIiAmJlxuICAgICAgICAhaG9vay5oYXNPd25Qcm9wZXJ0eShcImhvb2tcIilcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWUvaXMtdmhvb2suanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWVcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgdmVyc2lvbiA9IHJlcXVpcmUoXCIuL3ZlcnNpb25cIilcblxubW9kdWxlLmV4cG9ydHMgPSBpc1ZpcnR1YWxOb2RlXG5cbmZ1bmN0aW9uIGlzVmlydHVhbE5vZGUoeCkge1xuICAgIHJldHVybiB4ICYmIHgudHlwZSA9PT0gXCJWaXJ0dWFsTm9kZVwiICYmIHgudmVyc2lvbiA9PT0gdmVyc2lvblxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy92dHJlZS9pcy12bm9kZS5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy92dHJlZVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciB2ZXJzaW9uID0gcmVxdWlyZShcIi4vdmVyc2lvblwiKVxuXG5tb2R1bGUuZXhwb3J0cyA9IGlzVmlydHVhbFRleHRcblxuZnVuY3Rpb24gaXNWaXJ0dWFsVGV4dCh4KSB7XG4gICAgcmV0dXJuIHggJiYgeC50eXBlID09PSBcIlZpcnR1YWxUZXh0XCIgJiYgeC52ZXJzaW9uID09PSB2ZXJzaW9uXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL3Z0cmVlL2lzLXZ0ZXh0LmpzXCIsXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL3Z0cmVlXCIpIiwiKGZ1bmN0aW9uIChwcm9jZXNzLGdsb2JhbCxCdWZmZXIsX19hcmd1bWVudDAsX19hcmd1bWVudDEsX19hcmd1bWVudDIsX19hcmd1bWVudDMsX19maWxlbmFtZSxfX2Rpcm5hbWUpe1xubW9kdWxlLmV4cG9ydHMgPSBpc1dpZGdldFxuXG5mdW5jdGlvbiBpc1dpZGdldCh3KSB7XG4gICAgcmV0dXJuIHcgJiYgdy50eXBlID09PSBcIldpZGdldFwiXG59XG5cbn0pLmNhbGwodGhpcyxyZXF1aXJlKFwib01mcEFuXCIpLHR5cGVvZiBzZWxmICE9PSBcInVuZGVmaW5lZFwiID8gc2VsZiA6IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgPyB3aW5kb3cgOiB7fSxyZXF1aXJlKFwiYnVmZmVyXCIpLkJ1ZmZlcixhcmd1bWVudHNbM10sYXJndW1lbnRzWzRdLGFyZ3VtZW50c1s1XSxhcmd1bWVudHNbNl0sXCIvLi4vLi4vbm9kZV9tb2R1bGVzL3ZpcnR1YWwtaHlwZXJzY3JpcHQvbm9kZV9tb2R1bGVzL3Z0cmVlL2lzLXdpZGdldC5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy92dHJlZVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbm1vZHVsZS5leHBvcnRzID0gXCIxXCJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWUvdmVyc2lvbi5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L25vZGVfbW9kdWxlcy92dHJlZVwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciB2ZXJzaW9uID0gcmVxdWlyZShcIi4vdmVyc2lvblwiKVxudmFyIGlzVk5vZGUgPSByZXF1aXJlKFwiLi9pcy12bm9kZVwiKVxudmFyIGlzV2lkZ2V0ID0gcmVxdWlyZShcIi4vaXMtd2lkZ2V0XCIpXG52YXIgaXNWSG9vayA9IHJlcXVpcmUoXCIuL2lzLXZob29rXCIpXG5cbm1vZHVsZS5leHBvcnRzID0gVmlydHVhbE5vZGVcblxudmFyIG5vUHJvcGVydGllcyA9IHt9XG52YXIgbm9DaGlsZHJlbiA9IFtdXG5cbmZ1bmN0aW9uIFZpcnR1YWxOb2RlKHRhZ05hbWUsIHByb3BlcnRpZXMsIGNoaWxkcmVuLCBrZXksIG5hbWVzcGFjZSkge1xuICAgIHRoaXMudGFnTmFtZSA9IHRhZ05hbWVcbiAgICB0aGlzLnByb3BlcnRpZXMgPSBwcm9wZXJ0aWVzIHx8IG5vUHJvcGVydGllc1xuICAgIHRoaXMuY2hpbGRyZW4gPSBjaGlsZHJlbiB8fCBub0NoaWxkcmVuXG4gICAgdGhpcy5rZXkgPSBrZXkgIT0gbnVsbCA/IFN0cmluZyhrZXkpIDogdW5kZWZpbmVkXG4gICAgdGhpcy5uYW1lc3BhY2UgPSAodHlwZW9mIG5hbWVzcGFjZSA9PT0gXCJzdHJpbmdcIikgPyBuYW1lc3BhY2UgOiBudWxsXG5cbiAgICB2YXIgY291bnQgPSAoY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoKSB8fCAwXG4gICAgdmFyIGRlc2NlbmRhbnRzID0gMFxuICAgIHZhciBoYXNXaWRnZXRzID0gZmFsc2VcbiAgICB2YXIgZGVzY2VuZGFudEhvb2tzID0gZmFsc2VcbiAgICB2YXIgaG9va3NcblxuICAgIGZvciAodmFyIHByb3BOYW1lIGluIHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKHByb3BlcnRpZXMuaGFzT3duUHJvcGVydHkocHJvcE5hbWUpKSB7XG4gICAgICAgICAgICB2YXIgcHJvcGVydHkgPSBwcm9wZXJ0aWVzW3Byb3BOYW1lXVxuICAgICAgICAgICAgaWYgKGlzVkhvb2socHJvcGVydHkpKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFob29rcykge1xuICAgICAgICAgICAgICAgICAgICBob29rcyA9IHt9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgaG9va3NbcHJvcE5hbWVdID0gcHJvcGVydHlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY291bnQ7IGkrKykge1xuICAgICAgICB2YXIgY2hpbGQgPSBjaGlsZHJlbltpXVxuICAgICAgICBpZiAoaXNWTm9kZShjaGlsZCkpIHtcbiAgICAgICAgICAgIGRlc2NlbmRhbnRzICs9IGNoaWxkLmNvdW50IHx8IDBcblxuICAgICAgICAgICAgaWYgKCFoYXNXaWRnZXRzICYmIGNoaWxkLmhhc1dpZGdldHMpIHtcbiAgICAgICAgICAgICAgICBoYXNXaWRnZXRzID0gdHJ1ZVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWRlc2NlbmRhbnRIb29rcyAmJiAoY2hpbGQuaG9va3MgfHwgY2hpbGQuZGVzY2VuZGFudEhvb2tzKSkge1xuICAgICAgICAgICAgICAgIGRlc2NlbmRhbnRIb29rcyA9IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmICghaGFzV2lkZ2V0cyAmJiBpc1dpZGdldChjaGlsZCkpIHtcbiAgICAgICAgICAgIGlmICh0eXBlb2YgY2hpbGQuZGVzdHJveSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgICAgICAgICAgaGFzV2lkZ2V0cyA9IHRydWVcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuY291bnQgPSBjb3VudCArIGRlc2NlbmRhbnRzXG4gICAgdGhpcy5oYXNXaWRnZXRzID0gaGFzV2lkZ2V0c1xuICAgIHRoaXMuaG9va3MgPSBob29rc1xuICAgIHRoaXMuZGVzY2VuZGFudEhvb2tzID0gZGVzY2VuZGFudEhvb2tzXG59XG5cblZpcnR1YWxOb2RlLnByb3RvdHlwZS52ZXJzaW9uID0gdmVyc2lvblxuVmlydHVhbE5vZGUucHJvdG90eXBlLnR5cGUgPSBcIlZpcnR1YWxOb2RlXCJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWUvdm5vZGUuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWVcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgdmVyc2lvbiA9IHJlcXVpcmUoXCIuL3ZlcnNpb25cIilcblxubW9kdWxlLmV4cG9ydHMgPSBWaXJ0dWFsVGV4dFxuXG5mdW5jdGlvbiBWaXJ0dWFsVGV4dCh0ZXh0KSB7XG4gICAgdGhpcy50ZXh0ID0gU3RyaW5nKHRleHQpXG59XG5cblZpcnR1YWxUZXh0LnByb3RvdHlwZS52ZXJzaW9uID0gdmVyc2lvblxuVmlydHVhbFRleHQucHJvdG90eXBlLnR5cGUgPSBcIlZpcnR1YWxUZXh0XCJcblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWUvdnRleHQuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9ub2RlX21vZHVsZXMvdnRyZWVcIikiLCIoZnVuY3Rpb24gKHByb2Nlc3MsZ2xvYmFsLEJ1ZmZlcixfX2FyZ3VtZW50MCxfX2FyZ3VtZW50MSxfX2FyZ3VtZW50MixfX2FyZ3VtZW50MyxfX2ZpbGVuYW1lLF9fZGlybmFtZSl7XG52YXIgY2xhc3NJZFNwbGl0ID0gLyhbXFwuI10/W2EtekEtWjAtOV86LV0rKS9cbnZhciBub3RDbGFzc0lkID0gL15cXC58Iy9cblxubW9kdWxlLmV4cG9ydHMgPSBwYXJzZVRhZ1xuXG5mdW5jdGlvbiBwYXJzZVRhZyh0YWcsIHByb3BzKSB7XG4gICAgaWYgKCF0YWcpIHtcbiAgICAgICAgcmV0dXJuIFwiZGl2XCJcbiAgICB9XG5cbiAgICB2YXIgbm9JZCA9ICEoXCJpZFwiIGluIHByb3BzKVxuXG4gICAgdmFyIHRhZ1BhcnRzID0gdGFnLnNwbGl0KGNsYXNzSWRTcGxpdClcbiAgICB2YXIgdGFnTmFtZSA9IG51bGxcblxuICAgIGlmIChub3RDbGFzc0lkLnRlc3QodGFnUGFydHNbMV0pKSB7XG4gICAgICAgIHRhZ05hbWUgPSBcImRpdlwiXG4gICAgfVxuXG4gICAgdmFyIGNsYXNzZXMsIHBhcnQsIHR5cGUsIGlcbiAgICBmb3IgKGkgPSAwOyBpIDwgdGFnUGFydHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgcGFydCA9IHRhZ1BhcnRzW2ldXG5cbiAgICAgICAgaWYgKCFwYXJ0KSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgdHlwZSA9IHBhcnQuY2hhckF0KDApXG5cbiAgICAgICAgaWYgKCF0YWdOYW1lKSB7XG4gICAgICAgICAgICB0YWdOYW1lID0gcGFydFxuICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT09IFwiLlwiKSB7XG4gICAgICAgICAgICBjbGFzc2VzID0gY2xhc3NlcyB8fCBbXVxuICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKHBhcnQuc3Vic3RyaW5nKDEsIHBhcnQubGVuZ3RoKSlcbiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09PSBcIiNcIiAmJiBub0lkKSB7XG4gICAgICAgICAgICBwcm9wcy5pZCA9IHBhcnQuc3Vic3RyaW5nKDEsIHBhcnQubGVuZ3RoKVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNsYXNzZXMpIHtcbiAgICAgICAgaWYgKHByb3BzLmNsYXNzTmFtZSkge1xuICAgICAgICAgICAgY2xhc3Nlcy5wdXNoKHByb3BzLmNsYXNzTmFtZSlcbiAgICAgICAgfVxuXG4gICAgICAgIHByb3BzLmNsYXNzTmFtZSA9IGNsYXNzZXMuam9pbihcIiBcIilcbiAgICB9XG5cbiAgICByZXR1cm4gdGFnTmFtZSA/IHRhZ05hbWUudG9Mb3dlckNhc2UoKSA6IFwiZGl2XCJcbn1cblxufSkuY2FsbCh0aGlzLHJlcXVpcmUoXCJvTWZwQW5cIiksdHlwZW9mIHNlbGYgIT09IFwidW5kZWZpbmVkXCIgPyBzZWxmIDogdHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHt9LHJlcXVpcmUoXCJidWZmZXJcIikuQnVmZmVyLGFyZ3VtZW50c1szXSxhcmd1bWVudHNbNF0sYXJndW1lbnRzWzVdLGFyZ3VtZW50c1s2XSxcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdC9wYXJzZS10YWcuanNcIixcIi8uLi8uLi9ub2RlX21vZHVsZXMvdmlydHVhbC1oeXBlcnNjcmlwdFwiKSIsIihmdW5jdGlvbiAocHJvY2VzcyxnbG9iYWwsQnVmZmVyLF9fYXJndW1lbnQwLF9fYXJndW1lbnQxLF9fYXJndW1lbnQyLF9fYXJndW1lbnQzLF9fZmlsZW5hbWUsX19kaXJuYW1lKXtcbnZhciBhdHRyaWJ1dGVIb29rID0gcmVxdWlyZShcIi4vaG9va3MvYXR0cmlidXRlLWhvb2suanNcIilcbnZhciBoID0gcmVxdWlyZShcIi4vaW5kZXguanNcIilcblxudmFyIEJMQUNLTElTVEVEX0tFWVMgPSB7XG4gICAgXCJzdHlsZVwiOiB0cnVlLFxuICAgIFwibmFtZXNwYWNlXCI6IHRydWUsXG4gICAgXCJrZXlcIjogdHJ1ZVxufVxudmFyIFNWR19OQU1FU1BBQ0UgPSBcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCJcblxubW9kdWxlLmV4cG9ydHMgPSBzdmdcblxuZnVuY3Rpb24gc3ZnKHRhZ05hbWUsIHByb3BlcnRpZXMsIGNoaWxkcmVuKSB7XG4gICAgaWYgKCFjaGlsZHJlbiAmJiBpc0NoaWxkcmVuKHByb3BlcnRpZXMpKSB7XG4gICAgICAgIGNoaWxkcmVuID0gcHJvcGVydGllc1xuICAgICAgICBwcm9wZXJ0aWVzID0ge31cbiAgICB9XG5cbiAgICBwcm9wZXJ0aWVzID0gcHJvcGVydGllcyB8fCB7fVxuXG4gICAgLy8gc2V0IG5hbWVzcGFjZSBmb3Igc3ZnXG4gICAgcHJvcGVydGllcy5uYW1lc3BhY2UgPSBTVkdfTkFNRVNQQUNFXG5cbiAgICAvLyBmb3IgZWFjaCBrZXksIGlmIGF0dHJpYnV0ZSAmIHN0cmluZywgYm9vbCBvciBudW1iZXIgdGhlblxuICAgIC8vIGNvbnZlcnQgaXQgaW50byBhIHNldEF0dHJpYnV0ZSBob29rXG4gICAgZm9yICh2YXIga2V5IGluIHByb3BlcnRpZXMpIHtcbiAgICAgICAgaWYgKCFwcm9wZXJ0aWVzLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBpZiAoQkxBQ0tMSVNURURfS0VZU1trZXldKSB7XG4gICAgICAgICAgICBjb250aW51ZVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHZhbHVlID0gcHJvcGVydGllc1trZXldXG4gICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIgJiZcbiAgICAgICAgICAgIHR5cGVvZiB2YWx1ZSAhPT0gXCJudW1iZXJcIiAmJlxuICAgICAgICAgICAgdHlwZW9mIHZhbHVlICE9PSBcImJvb2xlYW5cIlxuICAgICAgICApIHtcbiAgICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICBwcm9wZXJ0aWVzW2tleV0gPSBhdHRyaWJ1dGVIb29rKHZhbHVlKVxuICAgIH1cblxuICAgIHJldHVybiBoKHRhZ05hbWUsIHByb3BlcnRpZXMsIGNoaWxkcmVuKVxufVxuXG5mdW5jdGlvbiBpc0NoaWxkcmVuKHgpIHtcbiAgICByZXR1cm4gdHlwZW9mIHggPT09IFwic3RyaW5nXCIgfHwgQXJyYXkuaXNBcnJheSh4KVxufVxuXG59KS5jYWxsKHRoaXMscmVxdWlyZShcIm9NZnBBblwiKSx0eXBlb2Ygc2VsZiAhPT0gXCJ1bmRlZmluZWRcIiA/IHNlbGYgOiB0eXBlb2Ygd2luZG93ICE9PSBcInVuZGVmaW5lZFwiID8gd2luZG93IDoge30scmVxdWlyZShcImJ1ZmZlclwiKS5CdWZmZXIsYXJndW1lbnRzWzNdLGFyZ3VtZW50c1s0XSxhcmd1bWVudHNbNV0sYXJndW1lbnRzWzZdLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0L3N2Zy5qc1wiLFwiLy4uLy4uL25vZGVfbW9kdWxlcy92aXJ0dWFsLWh5cGVyc2NyaXB0XCIpIl19 diff --git a/src/models/boolean-examples.coffee b/src/models/boolean-examples.coffee index 15ddaaf..4b4a9e5 100644 --- a/src/models/boolean-examples.coffee +++ b/src/models/boolean-examples.coffee @@ -9,6 +9,14 @@ module.exports = { "apply": (inputs) -> inputs[0].all((x) -> x.content < 10) } + "any": { + "label": "any(x => x > 10)" + "inputs": [ + [{t:5, d:2}, {t:15, d:30}, {t:25, d:22}, {t:35, d:5}, {t:45, d:60}, {t:55, d:1}] + ] + "apply": (inputs) -> inputs[0].any((x) -> x.content > 10) + } + "contains": { "label": "contains(22)" "inputs": [ diff --git a/src/models/math-examples.coffee b/src/models/math-examples.coffee index 4d34593..4d20256 100644 --- a/src/models/math-examples.coffee +++ b/src/models/math-examples.coffee @@ -50,5 +50,13 @@ module.exports = { return 0 ) } + + "sum": { + "label": "sum" + "inputs": [ + [{t:5, d:1}, {t:15, d:2}, {t:25, d:3}, {t:35, d:4}, {t:65, d:5}] + ] + "apply": (inputs) -> inputs[0].sum((x) -> x.content) + } } diff --git a/src/models/transform-examples.coffee b/src/models/transform-examples.coffee index 32bddaa..c7f8363 100644 --- a/src/models/transform-examples.coffee +++ b/src/models/transform-examples.coffee @@ -1,25 +1,23 @@ Rx = require 'rx' module.exports = { - # "concatMap": { - # "comingsoon": true - # } - "delay": { "label": "delay" "inputs": [ - [{t:0, d:1}, {t:10, d:2}] + [{t:0, d:1}, {t:10, d:2}, {t:20, d:1}] ] "apply": (inputs, scheduler) -> inputs[0].delay(20, scheduler) } - # "flatMap": { - # "comingsoon": true - # } - - # "flatMapLatest": { - # "comingsoon": true - # } + "delayWithSelector": { + "label": "delayWithSelector(x => Rx.Observable.timer(20 * x))" + "inputs": [ + [{t:0, d:1}, {t:10, d:2}, {t:20, d:1}] + ] + "apply": (inputs, scheduler) -> inputs[0].delayWithSelector((x) -> + return Rx.Observable.timer(Number(x.content) * 20, 1000, scheduler) + ) + } "map": { "label": "map(x => 10 * x)"