@interncom/diplomatic 0.13.1 → 0.13.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- function nV(Z){let X=Z.length,W=0,V=0;while(V<X){let l=Z.charCodeAt(V++);if((l&4294967168)===0){W++;continue}else if((l&4294965248)===0)W+=2;else{if(l>=55296&&l<=56319){if(V<X){let K=Z.charCodeAt(V);if((K&64512)===56320)++V,l=((l&1023)<<10)+(K&1023)+65536}}if((l&4294901760)===0)W+=3;else W+=4}}return W}function g0(Z,X,W){let V=Z.length,l=W,K=0;while(K<V){let G=Z.charCodeAt(K++);if((G&4294967168)===0){X[l++]=G;continue}else if((G&4294965248)===0)X[l++]=G>>6&31|192;else{if(G>=55296&&G<=56319){if(K<V){let m=Z.charCodeAt(K);if((m&64512)===56320)++K,G=((G&1023)<<10)+(m&1023)+65536}}if((G&4294901760)===0)X[l++]=G>>12&15|224,X[l++]=G>>6&63|128;else X[l++]=G>>18&7|240,X[l++]=G>>12&63|128,X[l++]=G>>6&63|128}X[l++]=G&63|128}}var H0=new TextEncoder,h0=50;function U0(Z,X,W){H0.encodeInto(Z,X.subarray(W))}function _V(Z,X,W){if(Z.length>h0)U0(Z,X,W);else g0(Z,X,W)}var P0=4096;function UW(Z,X,W){let V=X,l=V+W,K=[],G="";while(V<l){let m=Z[V++];if((m&128)===0)K.push(m);else if((m&224)===192){let R=Z[V++]&63;K.push((m&31)<<6|R)}else if((m&240)===224){let R=Z[V++]&63,J=Z[V++]&63;K.push((m&31)<<12|R<<6|J)}else if((m&248)===240){let R=Z[V++]&63,J=Z[V++]&63,C=Z[V++]&63,F=(m&7)<<18|R<<12|J<<6|C;if(F>65535)F-=65536,K.push(F>>>10&1023|55296),F=56320|F&1023;K.push(F)}else K.push(m);if(K.length>=P0)G+=String.fromCharCode(...K),K.length=0}if(K.length>0)G+=String.fromCharCode(...K);return G}var O0=new TextDecoder,i0=200;function E0(Z,X,W){let V=Z.subarray(X,X+W);return O0.decode(V)}function aV(Z,X,W){if(W>i0)return E0(Z,X,W);else return UW(Z,X,W)}class XX{type;data;constructor(Z,X){this.type=Z,this.data=X}}class WZ extends Error{constructor(Z){super(Z);let X=Object.create(WZ.prototype);Object.setPrototypeOf(this,X),Object.defineProperty(this,"name",{configurable:!0,enumerable:!1,value:WZ.name})}}var WX=4294967295;function sV(Z,X,W){let V=W/4294967296,l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function AX(Z,X,W){let V=Math.floor(W/4294967296),l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function vX(Z,X){let W=Z.getInt32(X),V=Z.getUint32(X+4);return W*4294967296+V}function rV(Z,X){let W=Z.getUint32(X),V=Z.getUint32(X+4);return W*4294967296+V}var B0=-1,j0=4294967295,u0=17179869183;function w0({sec:Z,nsec:X}){if(Z>=0&&X>=0&&Z<=u0)if(X===0&&Z<=j0){let W=new Uint8Array(4);return new DataView(W.buffer).setUint32(0,Z),W}else{let W=Z/4294967296,V=Z&4294967295,l=new Uint8Array(8),K=new DataView(l.buffer);return K.setUint32(0,X<<2|W&3),K.setUint32(4,V),l}else{let W=new Uint8Array(12),V=new DataView(W.buffer);return V.setUint32(0,X),AX(V,4,Z),W}}function D0(Z){let X=Z.getTime(),W=Math.floor(X/1000),V=(X-W*1000)*1e6,l=Math.floor(V/1e9);return{sec:W+l,nsec:V-l*1e9}}function A0(Z){if(Z instanceof Date){let X=D0(Z);return w0(X)}else return null}function v0(Z){let X=new DataView(Z.buffer,Z.byteOffset,Z.byteLength);switch(Z.byteLength){case 4:{let W=X.getUint32(0),V=0;return{sec:W,nsec:0}}case 8:{let W=X.getUint32(0),V=X.getUint32(4),l=(W&3)*4294967296+V,K=W>>>2;return{sec:l,nsec:K}}case 12:{let W=vX(X,4),V=X.getUint32(0);return{sec:W,nsec:V}}default:throw new WZ(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${Z.length}`)}}function $0(Z){let X=v0(Z);return new Date(X.sec*1000+X.nsec/1e6)}var tV={type:B0,encode:A0,decode:$0};class VX{static defaultCodec=new VX;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(tV)}register({type:Z,encode:X,decode:W}){if(Z>=0)this.encoders[Z]=X,this.decoders[Z]=W;else{let V=-1-Z;this.builtInEncoders[V]=X,this.builtInDecoders[V]=W}}tryToEncode(Z,X){for(let W=0;W<this.builtInEncoders.length;W++){let V=this.builtInEncoders[W];if(V!=null){let l=V(Z,X);if(l!=null){let K=-1-W;return new XX(K,l)}}}for(let W=0;W<this.encoders.length;W++){let V=this.encoders[W];if(V!=null){let l=V(Z,X);if(l!=null)return new XX(W,l)}}if(Z instanceof XX)return Z;return null}decode(Z,X,W){let V=X<0?this.builtInDecoders[-1-X]:this.decoders[X];if(V)return V(Z,X,W);else return new XX(X,Z)}}function o0(Z){return Z instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&Z instanceof SharedArrayBuffer}function cX(Z){if(Z instanceof Uint8Array)return Z;else if(ArrayBuffer.isView(Z))return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength);else if(o0(Z))return new Uint8Array(Z);else return Uint8Array.from(Z)}var f0=100,q0=2048;class $X{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??VX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.maxDepth=Z?.maxDepth??f0,this.initialBufferSize=Z?.initialBufferSize??q0,this.sortKeys=Z?.sortKeys??!1,this.forceFloat32=Z?.forceFloat32??!1,this.ignoreUndefined=Z?.ignoreUndefined??!1,this.forceIntegerToFloat=Z?.forceIntegerToFloat??!1,this.pos=0,this.view=new DataView(new ArrayBuffer(this.initialBufferSize)),this.bytes=new Uint8Array(this.view.buffer)}clone(){return new $X({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,maxDepth:this.maxDepth,initialBufferSize:this.initialBufferSize,sortKeys:this.sortKeys,forceFloat32:this.forceFloat32,ignoreUndefined:this.ignoreUndefined,forceIntegerToFloat:this.forceIntegerToFloat})}reinitializeState(){this.pos=0}encodeSharedRef(Z){if(this.entered)return this.clone().encodeSharedRef(Z);try{return this.entered=!0,this.reinitializeState(),this.doEncode(Z,1),this.bytes.subarray(0,this.pos)}finally{this.entered=!1}}encode(Z){if(this.entered)return this.clone().encode(Z);try{return this.entered=!0,this.reinitializeState(),this.doEncode(Z,1),this.bytes.slice(0,this.pos)}finally{this.entered=!1}}doEncode(Z,X){if(X>this.maxDepth)throw Error(`Too deep objects in depth ${X}`);if(Z==null)this.encodeNil();else if(typeof Z==="boolean")this.encodeBoolean(Z);else if(typeof Z==="number")if(!this.forceIntegerToFloat)this.encodeNumber(Z);else this.encodeNumberAsFloat(Z);else if(typeof Z==="string")this.encodeString(Z);else if(this.useBigInt64&&typeof Z==="bigint")this.encodeBigInt64(Z);else this.encodeObject(Z,X)}ensureBufferSizeToWrite(Z){let X=this.pos+Z;if(this.view.byteLength<X)this.resizeBuffer(X*2)}resizeBuffer(Z){let X=new ArrayBuffer(Z),W=new Uint8Array(X),V=new DataView(X);W.set(this.bytes),this.view=V,this.bytes=W}encodeNil(){this.writeU8(192)}encodeBoolean(Z){if(Z===!1)this.writeU8(194);else this.writeU8(195)}encodeNumber(Z){if(!this.forceIntegerToFloat&&Number.isSafeInteger(Z))if(Z>=0)if(Z<128)this.writeU8(Z);else if(Z<256)this.writeU8(204),this.writeU8(Z);else if(Z<65536)this.writeU8(205),this.writeU16(Z);else if(Z<4294967296)this.writeU8(206),this.writeU32(Z);else if(!this.useBigInt64)this.writeU8(207),this.writeU64(Z);else this.encodeNumberAsFloat(Z);else if(Z>=-32)this.writeU8(224|Z+32);else if(Z>=-128)this.writeU8(208),this.writeI8(Z);else if(Z>=-32768)this.writeU8(209),this.writeI16(Z);else if(Z>=-2147483648)this.writeU8(210),this.writeI32(Z);else if(!this.useBigInt64)this.writeU8(211),this.writeI64(Z);else this.encodeNumberAsFloat(Z);else this.encodeNumberAsFloat(Z)}encodeNumberAsFloat(Z){if(this.forceFloat32)this.writeU8(202),this.writeF32(Z);else this.writeU8(203),this.writeF64(Z)}encodeBigInt64(Z){if(Z>=BigInt(0))this.writeU8(207),this.writeBigUint64(Z);else this.writeU8(211),this.writeBigInt64(Z)}writeStringHeader(Z){if(Z<32)this.writeU8(160+Z);else if(Z<256)this.writeU8(217),this.writeU8(Z);else if(Z<65536)this.writeU8(218),this.writeU16(Z);else if(Z<4294967296)this.writeU8(219),this.writeU32(Z);else throw Error(`Too long string: ${Z} bytes in UTF-8`)}encodeString(Z){let W=nV(Z);this.ensureBufferSizeToWrite(5+W),this.writeStringHeader(W),_V(Z,this.bytes,this.pos),this.pos+=W}encodeObject(Z,X){let W=this.extensionCodec.tryToEncode(Z,this.context);if(W!=null)this.encodeExtension(W);else if(Array.isArray(Z))this.encodeArray(Z,X);else if(ArrayBuffer.isView(Z))this.encodeBinary(Z);else if(typeof Z==="object")this.encodeMap(Z,X);else throw Error(`Unrecognized object: ${Object.prototype.toString.apply(Z)}`)}encodeBinary(Z){let X=Z.byteLength;if(X<256)this.writeU8(196),this.writeU8(X);else if(X<65536)this.writeU8(197),this.writeU16(X);else if(X<4294967296)this.writeU8(198),this.writeU32(X);else throw Error(`Too large binary: ${X}`);let W=cX(Z);this.writeU8a(W)}encodeArray(Z,X){let W=Z.length;if(W<16)this.writeU8(144+W);else if(W<65536)this.writeU8(220),this.writeU16(W);else if(W<4294967296)this.writeU8(221),this.writeU32(W);else throw Error(`Too large array: ${W}`);for(let V of Z)this.doEncode(V,X+1)}countWithoutUndefined(Z,X){let W=0;for(let V of X)if(Z[V]!==void 0)W++;return W}encodeMap(Z,X){let W=Object.keys(Z);if(this.sortKeys)W.sort();let V=this.ignoreUndefined?this.countWithoutUndefined(Z,W):W.length;if(V<16)this.writeU8(128+V);else if(V<65536)this.writeU8(222),this.writeU16(V);else if(V<4294967296)this.writeU8(223),this.writeU32(V);else throw Error(`Too large map object: ${V}`);for(let l of W){let K=Z[l];if(!(this.ignoreUndefined&&K===void 0))this.encodeString(l),this.doEncode(K,X+1)}}encodeExtension(Z){if(typeof Z.data==="function"){let W=Z.data(this.pos+6),V=W.length;if(V>=4294967296)throw Error(`Too large extension object: ${V}`);this.writeU8(201),this.writeU32(V),this.writeI8(Z.type),this.writeU8a(W);return}let X=Z.data.length;if(X===1)this.writeU8(212);else if(X===2)this.writeU8(213);else if(X===4)this.writeU8(214);else if(X===8)this.writeU8(215);else if(X===16)this.writeU8(216);else if(X<256)this.writeU8(199),this.writeU8(X);else if(X<65536)this.writeU8(200),this.writeU16(X);else if(X<4294967296)this.writeU8(201),this.writeU32(X);else throw Error(`Too large extension object: ${X}`);this.writeI8(Z.type),this.writeU8a(Z.data)}writeU8(Z){this.ensureBufferSizeToWrite(1),this.view.setUint8(this.pos,Z),this.pos++}writeU8a(Z){let X=Z.length;this.ensureBufferSizeToWrite(X),this.bytes.set(Z,this.pos),this.pos+=X}writeI8(Z){this.ensureBufferSizeToWrite(1),this.view.setInt8(this.pos,Z),this.pos++}writeU16(Z){this.ensureBufferSizeToWrite(2),this.view.setUint16(this.pos,Z),this.pos+=2}writeI16(Z){this.ensureBufferSizeToWrite(2),this.view.setInt16(this.pos,Z),this.pos+=2}writeU32(Z){this.ensureBufferSizeToWrite(4),this.view.setUint32(this.pos,Z),this.pos+=4}writeI32(Z){this.ensureBufferSizeToWrite(4),this.view.setInt32(this.pos,Z),this.pos+=4}writeF32(Z){this.ensureBufferSizeToWrite(4),this.view.setFloat32(this.pos,Z),this.pos+=4}writeF64(Z){this.ensureBufferSizeToWrite(8),this.view.setFloat64(this.pos,Z),this.pos+=8}writeU64(Z){this.ensureBufferSizeToWrite(8),sV(this.view,this.pos,Z),this.pos+=8}writeI64(Z){this.ensureBufferSizeToWrite(8),AX(this.view,this.pos,Z),this.pos+=8}writeBigUint64(Z){this.ensureBufferSizeToWrite(8),this.view.setBigUint64(this.pos,Z),this.pos+=8}writeBigInt64(Z){this.ensureBufferSizeToWrite(8),this.view.setBigInt64(this.pos,Z),this.pos+=8}}function vZ(Z,X){return new $X(X).encodeSharedRef(Z)}function oX(Z){return`${Z<0?"-":""}0x${Math.abs(Z).toString(16).padStart(2,"0")}`}var n0=16,_0=16;class PW{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(Z=n0,X=_0){this.maxKeyLength=Z,this.maxLengthPerKey=X,this.caches=[];for(let W=0;W<this.maxKeyLength;W++)this.caches.push([])}canBeCached(Z){return Z>0&&Z<=this.maxKeyLength}find(Z,X,W){let V=this.caches[W-1];Z:for(let l of V){let K=l.bytes;for(let G=0;G<W;G++)if(K[G]!==Z[X+G])continue Z;return l.str}return null}store(Z,X){let W=this.caches[Z.length-1],V={bytes:Z,str:X};if(W.length>=this.maxLengthPerKey)W[Math.random()*W.length|0]=V;else W.push(V)}decode(Z,X,W){let V=this.find(Z,X,W);if(V!=null)return this.hit++,V;this.miss++;let l=UW(Z,X,W),K=Uint8Array.prototype.slice.call(Z,X,X+W);return this.store(K,l),l}}var OW="array",pX="map_key",Zl="map_value",a0=(Z)=>{if(typeof Z==="string"||typeof Z==="number")return Z;throw new WZ("The type of key must be string or number but "+typeof Z)};class Xl{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(Z){let X=this.getUninitializedStateFromPool();X.type=OW,X.position=0,X.size=Z,X.array=Array(Z)}pushMapState(Z){let X=this.getUninitializedStateFromPool();X.type=pX,X.readCount=0,X.size=Z,X.map={}}getUninitializedStateFromPool(){if(this.stackHeadPosition++,this.stackHeadPosition===this.stack.length){let Z={type:void 0,size:0,array:void 0,position:0,readCount:0,map:void 0,key:null};this.stack.push(Z)}return this.stack[this.stackHeadPosition]}release(Z){if(this.stack[this.stackHeadPosition]!==Z)throw Error("Invalid stack state. Released state is not on top of the stack.");if(Z.type===OW){let W=Z;W.size=0,W.array=void 0,W.position=0,W.type=void 0}if(Z.type===pX||Z.type===Zl){let W=Z;W.size=0,W.map=void 0,W.readCount=0,W.type=void 0}this.stackHeadPosition--}reset(){this.stack.length=0,this.stackHeadPosition=-1}}var QX=-1,iW=new DataView(new ArrayBuffer(0)),s0=new Uint8Array(iW.buffer);try{iW.getInt8(0)}catch(Z){if(!(Z instanceof RangeError))throw Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access")}var eV=RangeError("Insufficient data"),r0=new PW;class fX{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=iW;bytes=s0;headByte=QX;stack=new Xl;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??VX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.rawStrings=Z?.rawStrings??!1,this.maxStrLength=Z?.maxStrLength??WX,this.maxBinLength=Z?.maxBinLength??WX,this.maxArrayLength=Z?.maxArrayLength??WX,this.maxMapLength=Z?.maxMapLength??WX,this.maxExtLength=Z?.maxExtLength??WX,this.keyDecoder=Z?.keyDecoder!==void 0?Z.keyDecoder:r0,this.mapKeyConverter=Z?.mapKeyConverter??a0}clone(){return new fX({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,rawStrings:this.rawStrings,maxStrLength:this.maxStrLength,maxBinLength:this.maxBinLength,maxArrayLength:this.maxArrayLength,maxMapLength:this.maxMapLength,maxExtLength:this.maxExtLength,keyDecoder:this.keyDecoder})}reinitializeState(){this.totalPos=0,this.headByte=QX,this.stack.reset()}setBuffer(Z){let X=cX(Z);this.bytes=X,this.view=new DataView(X.buffer,X.byteOffset,X.byteLength),this.pos=0}appendBuffer(Z){if(this.headByte===QX&&!this.hasRemaining(1))this.setBuffer(Z);else{let X=this.bytes.subarray(this.pos),W=cX(Z),V=new Uint8Array(X.length+W.length);V.set(X),V.set(W,X.length),this.setBuffer(V)}}hasRemaining(Z){return this.view.byteLength-this.pos>=Z}createExtraByteError(Z){let{view:X,pos:W}=this;return RangeError(`Extra ${X.byteLength-W} of ${X.byteLength} byte(s) found at buffer[${Z}]`)}decode(Z){if(this.entered)return this.clone().decode(Z);try{this.entered=!0,this.reinitializeState(),this.setBuffer(Z);let X=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return X}finally{this.entered=!1}}*decodeMulti(Z){if(this.entered){yield*this.clone().decodeMulti(Z);return}try{this.entered=!0,this.reinitializeState(),this.setBuffer(Z);while(this.hasRemaining(1))yield this.doDecodeSync()}finally{this.entered=!1}}async decodeAsync(Z){if(this.entered)return this.clone().decodeAsync(Z);try{this.entered=!0;let X=!1,W;for await(let G of Z){if(X)throw this.entered=!1,this.createExtraByteError(this.totalPos);this.appendBuffer(G);try{W=this.doDecodeSync(),X=!0}catch(m){if(!(m instanceof RangeError))throw m}this.totalPos+=this.pos}if(X){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return W}let{headByte:V,pos:l,totalPos:K}=this;throw RangeError(`Insufficient data in parsing ${oX(V)} at ${K} (${l} in the current buffer)`)}finally{this.entered=!1}}decodeArrayStream(Z){return this.decodeMultiAsync(Z,!0)}decodeStream(Z){return this.decodeMultiAsync(Z,!1)}async*decodeMultiAsync(Z,X){if(this.entered){yield*this.clone().decodeMultiAsync(Z,X);return}try{this.entered=!0;let W=X,V=-1;for await(let l of Z){if(X&&V===0)throw this.createExtraByteError(this.totalPos);if(this.appendBuffer(l),W)V=this.readArraySize(),W=!1,this.complete();try{while(!0)if(yield this.doDecodeSync(),--V===0)break}catch(K){if(!(K instanceof RangeError))throw K}this.totalPos+=this.pos}}finally{this.entered=!1}}doDecodeSync(){Z:while(!0){let Z=this.readHeadByte(),X;if(Z>=224)X=Z-256;else if(Z<192)if(Z<128)X=Z;else if(Z<144){let V=Z-128;if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z<160){let V=Z-144;if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else{let V=Z-160;X=this.decodeString(V,0)}else if(Z===192)X=null;else if(Z===194)X=!1;else if(Z===195)X=!0;else if(Z===202)X=this.readF32();else if(Z===203)X=this.readF64();else if(Z===204)X=this.readU8();else if(Z===205)X=this.readU16();else if(Z===206)X=this.readU32();else if(Z===207)if(this.useBigInt64)X=this.readU64AsBigInt();else X=this.readU64();else if(Z===208)X=this.readI8();else if(Z===209)X=this.readI16();else if(Z===210)X=this.readI32();else if(Z===211)if(this.useBigInt64)X=this.readI64AsBigInt();else X=this.readI64();else if(Z===217){let V=this.lookU8();X=this.decodeString(V,1)}else if(Z===218){let V=this.lookU16();X=this.decodeString(V,2)}else if(Z===219){let V=this.lookU32();X=this.decodeString(V,4)}else if(Z===220){let V=this.readU16();if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else if(Z===221){let V=this.readU32();if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else if(Z===222){let V=this.readU16();if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z===223){let V=this.readU32();if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z===196){let V=this.lookU8();X=this.decodeBinary(V,1)}else if(Z===197){let V=this.lookU16();X=this.decodeBinary(V,2)}else if(Z===198){let V=this.lookU32();X=this.decodeBinary(V,4)}else if(Z===212)X=this.decodeExtension(1,0);else if(Z===213)X=this.decodeExtension(2,0);else if(Z===214)X=this.decodeExtension(4,0);else if(Z===215)X=this.decodeExtension(8,0);else if(Z===216)X=this.decodeExtension(16,0);else if(Z===199){let V=this.lookU8();X=this.decodeExtension(V,1)}else if(Z===200){let V=this.lookU16();X=this.decodeExtension(V,2)}else if(Z===201){let V=this.lookU32();X=this.decodeExtension(V,4)}else throw new WZ(`Unrecognized type byte: ${oX(Z)}`);this.complete();let W=this.stack;while(W.length>0){let V=W.top();if(V.type===OW)if(V.array[V.position]=X,V.position++,V.position===V.size)X=V.array,W.release(V);else continue Z;else if(V.type===pX){if(X==="__proto__")throw new WZ("The key __proto__ is not allowed");V.key=this.mapKeyConverter(X),V.type=Zl;continue Z}else if(V.map[V.key]=X,V.readCount++,V.readCount===V.size)X=V.map,W.release(V);else{V.key=null,V.type=pX;continue Z}}return X}}readHeadByte(){if(this.headByte===QX)this.headByte=this.readU8();return this.headByte}complete(){this.headByte=QX}readArraySize(){let Z=this.readHeadByte();switch(Z){case 220:return this.readU16();case 221:return this.readU32();default:if(Z<160)return Z-144;else throw new WZ(`Unrecognized array type byte: ${oX(Z)}`)}}pushMapState(Z){if(Z>this.maxMapLength)throw new WZ(`Max length exceeded: map length (${Z}) > maxMapLengthLength (${this.maxMapLength})`);this.stack.pushMapState(Z)}pushArrayState(Z){if(Z>this.maxArrayLength)throw new WZ(`Max length exceeded: array length (${Z}) > maxArrayLength (${this.maxArrayLength})`);this.stack.pushArrayState(Z)}decodeString(Z,X){if(!this.rawStrings||this.stateIsMapKey())return this.decodeUtf8String(Z,X);return this.decodeBinary(Z,X)}decodeUtf8String(Z,X){if(Z>this.maxStrLength)throw new WZ(`Max length exceeded: UTF-8 byte length (${Z}) > maxStrLength (${this.maxStrLength})`);if(this.bytes.byteLength<this.pos+X+Z)throw eV;let W=this.pos+X,V;if(this.stateIsMapKey()&&this.keyDecoder?.canBeCached(Z))V=this.keyDecoder.decode(this.bytes,W,Z);else V=aV(this.bytes,W,Z);return this.pos+=X+Z,V}stateIsMapKey(){if(this.stack.length>0)return this.stack.top().type===pX;return!1}decodeBinary(Z,X){if(Z>this.maxBinLength)throw new WZ(`Max length exceeded: bin length (${Z}) > maxBinLength (${this.maxBinLength})`);if(!this.hasRemaining(Z+X))throw eV;let W=this.pos+X,V=this.bytes.subarray(W,W+Z);return this.pos+=X+Z,V}decodeExtension(Z,X){if(Z>this.maxExtLength)throw new WZ(`Max length exceeded: ext length (${Z}) > maxExtLength (${this.maxExtLength})`);let W=this.view.getInt8(this.pos+X),V=this.decodeBinary(Z,X+1);return this.extensionCodec.decode(V,W,this.context)}lookU8(){return this.view.getUint8(this.pos)}lookU16(){return this.view.getUint16(this.pos)}lookU32(){return this.view.getUint32(this.pos)}readU8(){let Z=this.view.getUint8(this.pos);return this.pos++,Z}readI8(){let Z=this.view.getInt8(this.pos);return this.pos++,Z}readU16(){let Z=this.view.getUint16(this.pos);return this.pos+=2,Z}readI16(){let Z=this.view.getInt16(this.pos);return this.pos+=2,Z}readU32(){let Z=this.view.getUint32(this.pos);return this.pos+=4,Z}readI32(){let Z=this.view.getInt32(this.pos);return this.pos+=4,Z}readU64(){let Z=rV(this.view,this.pos);return this.pos+=8,Z}readI64(){let Z=vX(this.view,this.pos);return this.pos+=8,Z}readU64AsBigInt(){let Z=this.view.getBigUint64(this.pos);return this.pos+=8,Z}readI64AsBigInt(){let Z=this.view.getBigInt64(this.pos);return this.pos+=8,Z}readF32(){let Z=this.view.getFloat32(this.pos);return this.pos+=4,Z}readF64(){let Z=this.view.getFloat64(this.pos);return this.pos+=8,Z}}function EW(Z,X){return new fX(X).decode(Z)}class UZ{listeners=new Map;addEventListener(Z,X){let W=this.listeners.get(Z);if(!W)W=new Set,this.listeners.set(Z,W);return W.add(X),()=>{this.removeEventListener(Z,X)}}removeEventListener(Z,X){let W=this.listeners.get(Z);if(W){if(W.delete(X),W.size===0)this.listeners.delete(Z)}}emit(Z,X){let W=this.listeners.get(Z);if(W){let V=Array.from(W);for(let l of V)l(X)}}emitAll(Z){let X=Array.from(this.listeners.keys());for(let W of X)this.emit(W,Z)}}class IZ{getter;static eventName="update";emitter;constructor(Z){this.getter=Z;this.emitter=new UZ}get=()=>this.getter();async emit(){let Z=await this.getter();queueMicrotask(()=>this.emitter.emit(IZ.eventName,Z))}listen(Z){return this.emitter.addEventListener(IZ.eventName,Z),()=>{this.emitter.removeEventListener(IZ.eventName,Z)}}}var PZ=64;var Wl=32,OZ=8;var qX=32;var Vl=30000,ll=512,z;((y)=>{y[y.Success=0]="Success";y[y.InvalidSignature=3]="InvalidSignature";y[y.ClockOutOfSync=4]="ClockOutOfSync";y[y.UserNotRegistered=5]="UserNotRegistered";y[y.ServerMisconfigured=6]="ServerMisconfigured";y[y.MissingBody=7]="MissingBody";y[y.ExtraBodyContent=8]="ExtraBodyContent";y[y.MissingParam=9]="MissingParam";y[y.InvalidParam=10]="InvalidParam";y[y.InvalidRequest=11]="InvalidRequest";y[y.InternalError=12]="InternalError";y[y.NotFound=13]="NotFound";y[y.InvalidMessage=14]="InvalidMessage";y[y.NoChange=15]="NoChange";y[y.DatabaseClosed=16]="DatabaseClosed";y[y.StorageError=17]="StorageError";y[y.DatabaseError=18]="DatabaseError";y[y.HashMismatch=19]="HashMismatch";y[y.DecryptionError=20]="DecryptionError";y[y.NotImplemented=21]="NotImplemented";y[y.MissingSeed=22]="MissingSeed";y[y.OutOfBounds=23]="OutOfBounds";y[y.HostError=24]="HostError";y[y.CommunicationError=25]="CommunicationError";y[y.VarLimitExceeded=26]="VarLimitExceeded";y[y.InvalidResponse=27]="InvalidResponse";y[y.ConnectionClosed=28]="ConnectionClosed";y[y.CryptoError=29]="CryptoError"})(z||={});function b(Z){return[Z,0]}function Y(Z){return[void 0,Z]}function t0(Z){if(Z<0)console.info("N",Z),console.trace();if(typeof Z!=="bigint")Z=BigInt(Z);if(Z<0n)return Y(10);let X=[];while(Z>0n){let W=Number(Z&0x7fn);if(Z>>=7n,Z>0n)X.push(W|128);else X.push(W)}if(X.length===0)return b(new Uint8Array([0]));if(X.length>8)return Y(26);return b(new Uint8Array(X))}function e0(Z,X=0){let W=0n,V=0,l=X;while(!0){if(l>=Z.length)return Y(14);let K=Z[l++];if(K===void 0)return Y(14);if(W|=BigInt(K&127)<<BigInt(V),(K&128)===0){if(l-X>8)return Y(26);return b({value:W>0x1fffffffffffffn?W:Number(W),bytesRead:l-X})}if(V+=7,V>=56)return Y(26)}}class O{data;pos=0;constructor(Z){this.data=Z}static async fromResponse(Z){let X=await Z.arrayBuffer(),W=new Uint8Array(X);return new O(W)}readBigInt(){if(this.pos+8>this.data.length)return Y(7);let Z=new DataView(this.data.buffer,this.data.byteOffset+this.pos).getBigUint64(0,!1);return this.pos+=8,b(Z)}readDate(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return b(new Date(Z))}readVarInt(){let[Z,X]=e0(this.data,this.pos);if(X!==0)return Y(X);this.pos+=Z.bytesRead;let W=Z.value;return b(typeof W==="bigint"?Number(W):W)}readVarString(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);let l=new TextDecoder().decode(W);return b(l)}readBytes(Z){if(Z<0)return Y(10);if(this.pos+Z>this.data.length)return Y(23);let X=this.data.slice(this.pos,this.pos+Z);return this.pos+=Z,b(X)}readVarBytes(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return this.readBytes(Z)}readStruct(Z){return Z.decode(this)}readStructs(Z){let X=[];while(!this.done()){let[W,V]=this.readStruct(Z);if(V!==0)return Y(V);X.push(W)}return b(X)}readBytesSeq(Z){let X=[];while(!this.done()){let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);X.push(W)}return b(X)}done(){return this.pos>=this.data.length}consumed(){return this.pos}}class E{parts=[];writeBigInt(Z){let X=new Uint8Array(8);new DataView(X.buffer).setBigUint64(0,Z,!1),this.parts.push(X)}writeDate(Z){let X=Z.getTime();return this.writeVarInt(X)}writeVarInt(Z){let[X,W]=t0(Z);if(W!==0)return W;return this.parts.push(X),0}writeVarString(Z){let X=new TextEncoder().encode(Z),W=this.writeVarInt(X.length);if(W!==0)return W;return this.writeBytes(X),0}prependBytes(Z){this.parts.unshift(Z.slice())}writeBytes(Z){this.parts.push(Z.slice())}writeVarBytes(Z){let X=this.writeVarInt(Z.length);if(X!==0)return X;return this.writeBytes(Z),0}writeStruct(Z,X){return Z.encode(this,X)}writeStructs(Z,X){for(let W of X){let V=this.writeStruct(Z,W);if(V!==0)return V}return 0}writeBytesSeq(Z){for(let X of Z)this.writeBytes(X)}result(){let Z=this.parts.reduce((V,l)=>V+l.length,0),X=new Uint8Array(Z),W=0;for(let V of this.parts)X.set(V,W),W+=V.length;return X}wipe(){for(let Z of this.parts)Z.fill(0);this.parts.length=0}*scan(){for(let Z of this.parts)yield Z}}async function BW(Z,X){let W=new E,V=W.writeDate(X);if(V!==0)return Y(V);let l=W.result(),K=await Z.sign(l);return b({pubKey:Z.publicKey,sig:K,timestamp:X})}async function iZ(Z,X,W){let V=W.now().getTime(),l=Z.timestamp.getTime();if(Math.abs(V-l)>Vl)return 4;let G=new E;G.writeDate(Z.timestamp);let m=G.result();if(!await X.checkSigEd25519(Z.sig,m,Z.pubKey))return 3;return 0}var s={encode(Z,X){let W=Z.writeVarBytes(X.id);if(W!==0)return W;let V=Z.writeDate(X.ts);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let[V,l]=Z.readDate();if(l!==0)return Y(l);return b({id:X,ts:V})}};function lX(Z){let X=new E,W=X.writeStruct(s,Z);if(W!==0)return Y(W);let V=X.result();return b(V)}async function ZK(Z){return lX({id:Z,ts:new Date(0)})}var JZ={encode(Z,X){let W=Z.writeVarBytes(X.eid);if(W!==0)return W;let V=Z.writeVarInt(X.off);if(V!==0)return V;let l=Z.writeVarInt(X.ctr);if(l!==0)return l;let K=Z.writeVarInt(X.len);if(K!==0)return K;if(X.hsh)Z.writeBytes(X.hsh);return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let V=new O(X),[,l]=s.decode(V);if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let[m,R]=Z.readVarInt();if(R!==0)return Y(R);let[J,C]=Z.readVarInt();if(C!==0)return Y(C);let F;if(J>0){let[d,k]=Z.readBytes(qX);if(k!==0)return Y(k);F=d}return b({eid:X,off:K,ctr:m,len:J,hsh:F})}};function YZ(Z){return Array.from(Z).map((W)=>W.toString(16).padStart(2,"0")).join("")}function yX(Z){if(Z.length%2!==0)throw Error("Invalid hex string");let X=new Uint8Array(Z.length/2);for(let W=0;W<Z.length;W+=2)X[W/2]=Number.parseInt(Z.substr(W,2),16);return X}function n(Z,X){if(Z===X)return!0;if(Z.byteLength!==X.byteLength)return!1;return Z.every((W,V)=>W===X[V])}var g;if(typeof Uint8Array.prototype.toBase64==="function")g=(Z)=>Z.toBase64();else g=(Z)=>btoa(String.fromCharCode(...Z));var e;if(typeof Uint8Array.fromBase64==="function")e=(Z)=>Uint8Array.fromBase64(Z);else e=(Z)=>Uint8Array.from(atob(Z),(X)=>X.charCodeAt(0));function XK(Z){return g(Z).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function jW(Z){let X=Z.length%4===0?"":"=".repeat(4-Z.length%4),W=Z.replace(/-/g,"+").replace(/_/g,"/")+X;return e(W)}function TZ(Z,X){let W=new Uint8Array(Z.length+X.length);return W.set(Z,0),W.set(X,Z.length),W}function Kl(Z,X,W){return W.checkSigEd25519(Z.sig,Z.headCph,X)}async function Gl(Z,X,W,V){let l;if(Z.bod&&Z.len>0)l=await W.blake3(Z.bod);let K=new E,G=JZ.encode(K,{...Z,hsh:l});if(G!==0)return Y(G);let m=K.result(),R=await X.kdmFor(m),J=V.deriveCipher(R,"encrypt"),C=await J.encrypt(m),F=Z.bod?await J.encrypt(Z.bod):new Uint8Array(0),d=await X.sign(C);return b({sig:d,kdm:R,headCph:C,bodyCph:F})}async function uW(Z,X,W,V,l){let K=new O(Z),[G,m]=JZ.decode(K);if(m!==0)return Y(14);let R;try{R=X&&X.length>0?await W.decrypt(X):void 0}catch{return Y(20)}let J=G.hsh&&R===void 0,C=G.hsh===void 0&&R!==void 0;if(J||C)return Y(19);if(G.hsh&&R){let d=await V.blake3(R);if(!n(d,G.hsh))return Y(19)}let F=l??await V.blake3(Z);return b({msgHead:G,bod:R,headHash:F})}class EZ{now(){return new Date}}function ml(Z,X,W,V){let l=X.getTime()-Z.getTime(),K=W.getTime()-V.getTime();return(l+K)/2}var SX={encode(Z,X){if(Z.writeVarInt(X.quota),X.quota>0){if(X.usage===void 0)return 9;Z.writeVarInt(X.usage)}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let V;if(X>0){let[l,K]=Z.readVarInt();if(K!==0)return Y(K);V=l}return b({quota:X,usage:V})}};var wW={encode(Z,X){Z.writeBytes(new Uint8Array([X.status]));let W=Z.writeDate(X.timeRcvd);if(W!==0)return W;let V=Z.writeDate(X.timeSent);if(V!==0)return V;let l=Z.writeVarInt(X.subscription.term);if(l!==0)return l;let K=Z.writeVarInt(X.subscription.elapsed);if(K!==0)return K;let G=Z.writeStruct(SX,X.subscription.stat);if(G!==0)return G;let m=Z.writeStruct(SX,X.subscription.dyn);if(m!==0)return m;return 0},decode(Z){let[X,W]=Z.readBytes(1);if(W!==0)return Y(W);let V=X[0],[l,K]=Z.readDate();if(K!==0)return Y(K);let[G,m]=Z.readDate();if(m!==0)return Y(m);let[R,J]=Z.readVarInt();if(J!==0)return Y(J);let[C,F]=Z.readVarInt();if(F!==0)return Y(F);let[d,k]=Z.readStruct(SX);if(k!==0)return Y(k);let[I,T]=Z.readStruct(SX);if(T!==0)return Y(T);return b({status:V,timeRcvd:l,timeSent:G,subscription:{term:R,elapsed:C,stat:d,dyn:I}})}};var DW={encode(Z,X){let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarInt(X.seq);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let[V,l]=Z.readVarInt();if(l!==0)return Y(l);return b({headCph:X,seq:V})}};var RZ={encode(Z,X){Z.writeBytes(X.pubKey),Z.writeBytes(X.sig);let W=Z.writeDate(X.timestamp);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readBytes(Wl);if(W!==0)return Y(W);let[V,l]=Z.readBytes(PZ);if(l!==0)return Y(l);let[K,G]=Z.readDate();if(G!==0)return Y(G);return b({pubKey:X,sig:V,timestamp:K})}};var Yl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;for(let G of V)l.writeVarInt(G);return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await iZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);if(F!==0)return F;if(!C)return 5;let[d,k]=X.readVarInt();if(k!==0)return k;if(!X.done())return 8;let[I,T]=await K.listHeads(J,d);if(T!==0)return T;return W.writeStructs(DW,I)},decodeResp(Z){return Z.readStructs(DW)}};var AW={encode(Z,X){Z.writeVarInt(X.seq);let W=Z.writeVarBytes(X.bodyCph);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);return b({seq:X,bodyCph:V})}};var Rl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;for(let G of V){let m=l.writeVarInt(G);if(m!==0)return m}return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await iZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);if(F!==0)return F;if(!C)return 5;let d=[];while(!X.done()){let[T,L]=X.readVarInt();if(L!==0)return L;d.push(T)}console.info(`PULL: ${d.length} bags`);let[k,I]=await K.getBodies(J,d);if(I!==0)return I;if(!k)return 17;for(let{seq:T,bodyCph:L}of k){let p={seq:T,bodyCph:L},Q=W.writeStruct(AW,p);if(Q!==0)return Q}return 0},decodeResp(Z){return Z.readStructs(AW)}};var vW={encode(Z,X){Z.writeBytes(X.sig),Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarBytes(X.bodyCph);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readBytes(PZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(OZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);let[m,R]=Z.readVarBytes();if(R!==0)return Y(R);return b({sig:X,kdm:V,headCph:K,bodyCph:m})}};var nX={encode(Z,X){let W=Z.writeVarInt(X.seq);if(W!==0)return W;let V=Z.writeVarBytes(X.headCph);if(V!==0)return V;let l=X.bodyCph?X.bodyCph.length:0,K=Z.writeVarInt(l);if(K!==0)return K;if(l>0){if(!X.bodyCph)return 10;Z.writeBytes(X.bodyCph)}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let m;if(K>0){let[R,J]=Z.readBytes(K);if(J!==0)return Y(J);m=R}return b({seq:X,headCph:V,bodyCph:m})}};var _X={encode(Z,X){Z.writeBytes(X.sig),Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readBytes(PZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(OZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return b({sig:X,kdm:V,headCph:K})}};var aX={encode(Z,X){if(Z.writeVarInt(X.idx),Z.writeBytes(new Uint8Array([X.status])),X.status===0)Z.writeVarInt(X.seq);return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readBytes(1);if(l!==0)return Y(l);let K=V[0];if(K!==0)return b({idx:X,status:K});let[G,m]=Z.readVarInt();if(m!==0)return Y(m);return b({idx:X,status:K,seq:G})}};var Jl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;let G=l.writeStructs(vW,V);if(G!==0)return G;return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K,notifier:G}=Z,[m,R]=X.readStruct(RZ);if(R!==0)return R;let J=await iZ(m,l,V);if(J!==0)return J;let{pubKey:C}=m,[F,d]=await K.hasUser(C);if(d!==0)return d;if(!F)return 5;let[k,I]=X.readStructs(vW);if(I!==0)return I;console.info(`PUSH: ${k.length} bags`);let T=[],L=[];for(let c=0;c<k.length;c++){let M=k[c];if(!await Kl(M,C,l)){let B={idx:c,status:3},i=W.writeStruct(aX,B);if(i!==0)return i;continue}T.push(c),L.push(M)}let[p,Q]=await K.setBags(C,L);if(Q!==0)return Q;if(!p||p.length!==L.length)return 17;let S=[];for(let c=0;c<L.length;c++){let M=L[c],H=T[c],B=p[c],i=new E,U=i.writeStruct(_X,M);if(U!==0)return U;let u=i.result(),D={seq:B,headCph:u};if(k.length===1&&M.bodyCph.length<=ll)D.bodyCph=M.bodyCph;S.push(D);let y={idx:H,status:0,seq:B},o=W.writeStruct(aX,y);if(o!==0)return o}if(S.length>0){let c=new E,M=c.writeStructs(nX,S);if(M!==0)return M;let H=c.result();await Promise.resolve(G.push(C,H))}return 0},decodeResp(Z){return Z.readStructs(aX)}};var Cl={async encodeReq(Z,X,W,V,l){return l.writeStruct(RZ,W)},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await iZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G;if(!X.done())return 8;let[C,F]=await K.addUser(J);if(F!==0)return F;return 0},decodeResp(Z){return b(void 0)}};class $W{url;websocket;constructor(Z){this.url=Z}connected(){return this.websocket!==void 0&&this.websocket.readyState===WebSocket.OPEN}async connect(Z,X,W=()=>{},V=()=>{}){let{url:l}=this;if(this.websocket)this.websocket.close(),this.websocket=void 0;let K=new E;K.writeStruct(RZ,Z);let G=K.result(),m=YZ(G);return l.searchParams.set("t",m),this.websocket=new WebSocket(l),this.websocket.binaryType="arraybuffer",this.websocket.onopen=()=>{console.log("CONNECTED"),V()},this.websocket.onclose=()=>{console.log("DISCONNECTED"),this.websocket=void 0,W()},this.websocket.onmessage=(R)=>{let J=new Uint8Array(R.data);X(J)},this.websocket.onerror=(R)=>{console.log(`ERROR: ${JSON.stringify(R)}`),this.websocket=void 0,W()},Promise.resolve(0)}disconnect(){this.websocket?.close(),this.websocket=void 0}}var r={user:{path:"/user",endpoint:Cl,name:0},push:{path:"/push",endpoint:Jl,name:2},peek:{path:"/peek",endpoint:Yl,name:1},pull:{path:"/pull",endpoint:Rl,name:3}},WK={0:r.user,2:r.push,1:r.peek,3:r.pull},gR={[r.user.path]:r.user,[r.push.path]:r.push,[r.peek.path]:r.peek,[r.pull.path]:r.pull};class oW{url;listener;constructor(Z){this.url=Z;this.listener=new $W(Z)}async call(Z,X){let{path:W}=WK[Z],V=new URL(W,this.url);try{return await VK(V,X)}catch{return Y(25)}}}var fW=(Z)=>{return new oW(Z.handle)};async function VK(Z,X){let W=await fetch(Z,{method:"POST",body:X.result().slice()});if(!W.ok)return Y(24);let V=await O.fromResponse(W);return b(V)}class sX{enclave;crypto;host;clock;transport;updateHostMeta;constructor(Z,X,W,V,l,K){this.enclave=Z;this.crypto=X;this.host=W;this.clock=V;this.transport=l;this.updateHostMeta=K}async call(Z,X){let{clock:W,transport:V}=this,{endpoint:l,name:K}=Z,G=await this.identity(),m=W.now(),[R,J]=await BW(G,m);if(J!==0)return Y(J);let C=new E,F=await l.encodeReq(this,G,R,X,C);if(F!==0)return Y(F);let d=W.now(),[k,I]=await V.call(K,C),T=W.now();if(I!==0)return Y(I);let[L,p]=k.readStruct(wW);if(p!==0)return Y(p);if(L.status!==0)return Y(L.status);let S={clockOffset:ml(d,L.timeRcvd,L.timeSent,T),subscription:L.subscription},c=await this.updateHostMeta(S);if(c!==0)return Y(c);return l.decodeResp(k)}identity=()=>{let{host:Z,enclave:X}=this;return X.deriveIdentity(Z.label,Z.idx??0)};seal=async(Z)=>{let{crypto:X,enclave:W}=this,V=await this.identity();return Gl(Z,V,X,W)};register=()=>this.call(r.user,[]);peek=(Z)=>this.call(r.peek,[Z]);push=(Z)=>this.call(r.push,Z);pull=(Z)=>this.call(r.pull,Z);listen=async(Z,X,W)=>{let{clock:V,transport:l}=this,{listener:K}=l,G=await this.identity(),m=V.now(),[R,J]=await BW(G,m);if(J!==0)return J;return await K.connect(R,Z,X,W)};isConnected(){let Z=this.transport?.listener;if(Z&&typeof Z.connected==="function")return Z.connected();return!0}closeListener(){this.transport?.listener?.disconnect()}}var qW={encode(Z,X){let W=Z.writeVarString(X.lbl);if(W!==0)return W;let V=Z.writeVarInt(X.idx);if(V!==0)return V;let l=Z.writeVarInt(X.num);if(l!==0)return l;return Z.writeBytes(X.hsh),Z.writeBytes(X.sig),0},decode(Z){let[X,W]=Z.readVarString();if(W!==0)return Y(W);let[V,l]=Z.readVarInt();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let[m,R]=Z.readBytes(qX);if(R!==0)return Y(R);let[J,C]=Z.readBytes(PZ);if(C!==0)return Y(C);return b({lbl:X,idx:V,num:K,hsh:m,sig:J})}};var nW={encode(Z,X){let W=Z.writeStruct(qW,X.head);if(W!==0)return W;let V=Z.writeVarBytes(X.indexEnc);if(V!==0)return V;let l=Z.writeVarBytes(X.bodyEnc);if(l!==0)return l;return 0},decode(Z){let[X,W]=Z.readStruct(qW);if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return b({head:X,indexEnc:V,bodyEnc:K})}};var _W={encode(Z,X){Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarInt(X.lenBody);if(V!==0)return V;if(X.lenBody>0&&X.offBody!==void 0){let l=Z.writeVarInt(X.offBody);if(l!==0)return l}return 0},decode(Z){let[X,W]=Z.readBytes(OZ);if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let m;if(K>0){let[R,J]=Z.readVarInt();if(J!==0)return Y(J);m=R}return b({kdm:X,headCph:V,lenBody:K,offBody:m})}};async function Fl(Z,X,W,V,l){let K=await l.deriveIdentity(Z,X),G=new E,m=new E,R=0,J=0;for(let p of W){let Q=new E,S=Q.writeStruct(JZ,p.head);if(S!==0)return Y(S);let c=Q.result(),M=await K.kdmFor(c),H=l.deriveCipher(M,"encrypt"),B=await H.encrypt(c),i=p.body?await H.encrypt(p.body):new Uint8Array(0),U=p.head.len>0&&p.head.hsh!==void 0?i.length:0,u={kdm:M,headCph:B,lenBody:U,offBody:U>0?J:void 0},D=G.writeStruct(_W,u);if(D!==0)return Y(D);if(p.body)m.writeBytes(i),J+=i.length;R++}let C=m.result(),F=G.result(),d=await V.blake3(F),k=await K.sign(d),I={lbl:Z,idx:X,num:R,hsh:d,sig:k},T=new E;T.writeStruct(nW,{head:I,indexEnc:F,bodyEnc:C});let L=T.result();return b(L)}async function bl(Z,X,W){let[V,l]=nW.decode(new O(Z));if(l!==0)return Y(l);let{head:K,indexEnc:G,bodyEnc:m}=V,R=await W.deriveIdentity(K.lbl,K.idx);if(!await X.checkSigEd25519(K.sig,K.hsh,R.publicKey))return Y(3);let C=await X.blake3(G);if(!n(C,K.hsh))return Y(19);let F=new O(G),d=[];for(let I=0;I<K.num;I++){let[T,L]=F.readStruct(_W);if(L!==0)return Y(L);d.push(T)}if(d.length!==K.num)return Y(14);let k=[];for(let I of d){let T=W.deriveCipher(I.kdm,"decrypt"),L;try{L=await T.decrypt(I.headCph)}catch{return Y(20)}let[p,Q]=JZ.decode(new O(L));if(Q!==0)return Y(Q);let S;if(I.lenBody>0&&I.offBody!==void 0){if(p.hsh===void 0)return Y(14);let c=m.slice(I.offBody,I.offBody+I.lenBody);try{S=await T.decrypt(c)}catch{return Y(20)}let M=await X.blake3(S);if(!n(M,p.hsh))return Y(19)}k.push({head:p,body:S})}return b(k)}async function dl({now:Z,bod:X,crypto:W}){let V=await W.genRandomBytes(8),l=new E,K=l.writeStruct(s,{id:V,ts:Z});if(K!==0)return Y(K);let G=l.result();return rX({now:Z,eid:G,ctr:0,bod:X,crypto:W})}async function rX({now:Z,eid:X,ctr:W,bod:V,crypto:l}){let K=new O(X),[G,m]=s.decode(K);if(m!==0)return Y(m);let R=Z.getTime()-G.ts.getTime(),J,C=V?.length??0;if(V&&C>0)J=await l.blake3(V);return b({eid:X,off:R,ctr:W,len:C,hsh:J})}function kl(Z,X){let W=Z.length<X.length?Z.length:X.length;for(let V=0;V<W;V++)if(Z[V]!==X[V])return Z[V]-X[V];return Z.length-X.length}async function KX(Z,X){let W=Array.from(Z);W.sort(kl);let V=0;for(let G of W)V+=G.length;let l=new Uint8Array(V),K=0;for(let G of W)l.set(G,K),K+=G.length;return X.blake3(l)}function Il(Z){let X=new E,W=X.writeVarBytes(Z.eid);if(W!==0)return Y(W);let V=X.writeDate(Z.updatedAt);if(V!==0)return Y(V);let l=X.writeVarInt(Z.ctr);if(l!==0)return Y(l);return b(X.result())}async function zX(Z,X){let W=[];for(let V of Z){let[l,K]=Il(V);if(K!==0||!l)return Y(K);W.push(l)}return b(await KX(W,X))}var pJ=Symbol("MasterSeed"),yJ=Symbol("SealedMasterKey"),kZ=32,aW=24+kZ+16;function VZ(Z){if(Z.byteLength!==kZ)return Y(10);return b(Z)}function yZ(Z){if(Z.byteLength!==aW)return Y(10);return b(Z)}var zJ=Symbol("EntityID");function Tl(Z){return"type"in Z}var NJ=Symbol("DerivationSeed"),MJ=Symbol("PublicKey"),xJ=Symbol("PrivateKey"),gJ=Symbol("HostSpecificKeyPair"),HJ=Symbol("Hash");function lK(Z){if(!Z)return!1;if(typeof Z!=="object")return!1;if("body"in Z===!1)return!1;if("type"in Z===!1)return!1;return!0}function KK(Z){if(!Z.bod||Z.bod.length===0){let V={off:Z.off,ctr:Z.ctr,eid:Z.eid};return b(V)}let X=EW(Z.bod);if(lK(X)===!1)return console.warn("msg body invalid",X),Y(14);let W={off:Z.off,ctr:Z.ctr,eid:Z.eid,gid:X.gid,pid:X.pid,tags:X.tags,type:X.type,body:X.body};return b(W)}class NX{applier;emitter=new UZ;clearer;onDirtyEids;cacheDriven;peerIngest;constructor(Z,X,W,V){this.applier=Z;this.clearer=X,this.onDirtyEids=W,this.cacheDriven=V?.cacheDriven??!1,this.peerIngest=V?.peerIngest}apply=async(Z)=>{let X=[],W=[];for(let m of Z){let[R,J]=KK(m);if(W.push(J),J!==0)continue;X.push(R)}let{stats:V,types:l,eids:K}=await this.applier(X),G=[];for(let m=0;m<Z.length;m++){let R=W[m],J=V[m];if(R!==0){G.push(R);continue}if(J!==0){G.push(J);continue}G.push(0)}if(!this.cacheDriven)for(let m of l)this.emitter.emit(m,null);if(K.length>0)this.onDirtyEids?.(K);return G};clear=async()=>{let Z=await this.clearer();if(Z!==0)return Z;return this.emitter.emitAll(null),Z};notify=(Z)=>{for(let X of Z)this.emitter.emit(X,null)};refresh=async(Z)=>{if(this.peerIngest){await this.peerIngest(Z);return}};on=(Z,X)=>{this.emitter.addEventListener(Z,X)};off=(Z,X)=>{this.emitter.removeEventListener(Z,X)}}var sW={apply:async function(Z){return Z.map(()=>0)},clear:async function(){return 0},notify:function(Z){},refresh:async function(Z){},on:function(Z,X){},off:function(Z,X){}};var q="entities",tX="entity_type_created_at",tW="entity_type_updated_at",eW="entity_type_group_id",ZV="entity_type_parent_id",GX="entity_tags",Ll="db",cl=13;function GK(Z){return"typ"in Z}function mK(Z){let X={bod:Z.body,crd:Z.createdAt,...Z.ctr!==0?{ctr:Z.ctr}:{},eid:g(Z.eid),gid:Z.gid,pid:Z.pid?g(Z.pid):void 0,tgs:Z.tags,typ:Z.type,upd:Z.updatedAt};if(X.gid===void 0)delete X.gid;if(X.pid===void 0)delete X.pid;if(X.tgs===void 0)delete X.tgs;if(X.ctr===void 0)delete X.ctr;return X}function YK(Z){if(!v(Z))return{eid:g(Z.eid),upd:Z.updatedAt,...Z.ctr!==0?{ctr:Z.ctr}:{}};return mK(Z)}function mX(Z){return{body:Z.bod,createdAt:Z.crd,updatedAt:Z.upd,ctr:Z.ctr??0,type:Z.typ,eid:e(Z.eid),gid:Z.gid,pid:Z.pid?e(Z.pid):void 0,...Z.tgs!==void 0?{tags:Z.tgs}:{}}}function rW(Z){if(GK(Z))return mX(Z);return{eid:e(Z.eid),updatedAt:Z.upd,ctr:Z.ctr??0}}class XV{db;opening;async init(){await this.ensureDb()}async ensureDb(){if(this.db)return this.db;if(this.opening)return this.opening;return this.opening=JK().then((Z)=>{return Z.onversionchange=()=>{if(Z.close(),this.db===Z)this.db=void 0},this.db=Z,this.opening=void 0,Z},(Z)=>{throw this.opening=void 0,Z}),this.opening}apply=async(Z)=>{let X=new Set,W=[],V;try{V=await this.ensureDb()}catch{return{stats:Z.map(()=>16),types:X,eids:W}}let l=V.transaction(q,"readwrite"),K=l.objectStore(q);return new Promise((G)=>{let m=Array(Z.length).fill(0);if(Z.length<1){G({stats:[],types:X,eids:W});return}l.oncomplete=()=>{G({stats:m,types:X,eids:W})},l.onerror=()=>{for(let J=0;J<m.length;J++)if(m[J]===void 0)m[J]=18;G({stats:m,types:X,eids:W})};let R=new Map;for(let J=0;J<Z.length;J++){let C=Z[J],F=g(C.eid),d={op:C,index:J},k=R.get(F);if(k)k.push(d);else R.set(F,[d])}for(let[J,C]of R){if(C.length<1)continue;let F=K.get(J);F.onsuccess=()=>{let d=F.result,k=d?rW(d):void 0,I=!1;for(let{op:T,index:L}of C){let[p,Q]=YX(k,T);if(Q!==0){m[L]=Q;continue}if(p===void 0){m[L]=12;continue}I=!0;for(let S of RX(k,p))X.add(S);k=p}if(I)W.push(C[0].op.eid);if(k){let T=K.put(YK(k));T.onerror=(L)=>{L.preventDefault();for(let{index:p}of C)m[p]=18}}},F.onerror=()=>{for(let{index:d}of C)m[d]=18}}})};async clear(){let Z;try{Z=await this.ensureDb()}catch{return 16}let X=Z.transaction(q,"readwrite"),W=X.objectStore(q);return new Promise((V)=>{X.oncomplete=()=>V(0),X.onerror=()=>V(18),W.clear()})}async getRow(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let W=g(Z),l=X.transaction(q,"readonly").objectStore(q);return new Promise((K)=>{let G=l.get(W);G.onsuccess=()=>{let m=G.result;if(!m)K(b(void 0));else K(b(rW(m)))},G.onerror=()=>K(Y(18))})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!v(X))return b(void 0);return b(X)}async getAllOfTypeUpdatedBetween(Z,X,W){let V;try{V=await this.ensureDb()}catch{return Y(16)}let K=V.transaction(q,"readonly").objectStore(q).index(tW);return new Promise((G)=>{let m=K.getAll(IDBKeyRange.bound([Z,X],[Z,W]));m.onsuccess=()=>{let R=m.result;G(b(R.map(mX)))},m.onerror=()=>G(Y(18))})}async getGroupMembers(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(q,"readonly").objectStore(q).index(eW);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z,X]));G.onsuccess=()=>{let m=G.result;K(b(m.map(mX)))},G.onerror=()=>K(Y(18))})}async getAllOfType(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(q,"readonly").objectStore(q).index(tX);return new Promise((l)=>{let K=V.getAll(IDBKeyRange.bound([Z],[Z,[]]));K.onsuccess=()=>{let G=K.result;l(b(G.map(mX)))},K.onerror=()=>l(Y(18))})}async getByTag(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(q,"readonly").objectStore(q).index(GX);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only(X));G.onsuccess=()=>{let R=G.result.filter((J)=>J.typ===Z).map(mX);K(b(R))},G.onerror=()=>K(Y(18))})}async getAllEntities(Z){if("pid"in Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let W=g(Z.pid),l=X.transaction(q,"readonly").objectStore(q).index(ZV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z.type,W]));G.onsuccess=()=>{let R=G.result.map(mX);K(b(R))},G.onerror=()=>K(Y(18))})}else if("gid"in Z)return await this.getGroupMembers(Z.type,Z.gid);else if("tag"in Z)return await this.getByTag(Z.type,Z.tag);else if("updatedBetween"in Z)return await this.getAllOfTypeUpdatedBetween(Z.type,Z.updatedBetween.start,Z.updatedBetween.end);return await this.getAllOfType(Z.type)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return b(X)}async countEntities({type:Z}){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(q,"readonly").objectStore(q).index(tX);return new Promise((l)=>{let K=IDBKeyRange.bound([Z],[Z,[]]),G=V.count(K);G.onsuccess=()=>l(b(G.result)),G.onerror=()=>l(Y(18))})}async checksum(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(q,"readonly").objectStore(q),l=[];return new Promise((K)=>{let G=V.openCursor();G.onsuccess=()=>{let m=G.result;if(m){let R=m.value;l.push(MX(rW(R))),m.continue()}else zX(l,Z).then(K)},G.onerror=()=>K(Y(18))})}}function RK(Z,X){if(!Z.objectStoreNames.contains(q))Z.createObjectStore(q,{keyPath:"eid",autoIncrement:!1});let W=X.objectStore(q);if(!W.indexNames.contains(tX))W.createIndex(tX,["typ","crd"],{unique:!1});if(!W.indexNames.contains(tW))W.createIndex(tW,["typ","upd"],{unique:!1});if(!W.indexNames.contains(eW))W.createIndex(eW,["typ","gid"],{unique:!1});if(!W.indexNames.contains(ZV))W.createIndex(ZV,["typ","pid"],{unique:!1});if(W.indexNames.contains(GX)){if(W.index(GX).keyPath!=="tgs")W.deleteIndex(GX)}if(!W.indexNames.contains(GX))W.createIndex(GX,"tgs",{unique:!1,multiEntry:!0})}function JK(){return new Promise((Z,X)=>{let W=indexedDB.open(Ll,cl);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!l){X(Error("Transaction is null during EntDB upgrade"));return}try{RK(V,l)}catch(K){X(K instanceof Error?K:Error(String(K)))}},W.onblocked=()=>{console.warn(`[DIPLOMATIC] EntDB IDB upgrade blocked (${Ll} → v${cl}); waiting for other connections to close`)},W.onsuccess=()=>Z(W.result),W.onerror=()=>X(W.error??Error("EntDB IndexedDB open failed"))})}async function Ql(){let Z=new XV;return await Z.init(),Z}class eX{ents=new Map;useIndex;byType=new Map;byTypePid=new Map;byTypeGid=new Map;byTypeTag=new Map;constructor(Z=[],X){this.useIndex=X?.indexes!==!1;for(let W of Z)this.put(W)}put(Z){let X=g(Z.eid),W=this.ents.get(X);if(W!==void 0&&v(W))this.unindex(X,W);if(this.ents.set(X,Z),v(Z))this.index(X,Z)}del(Z){let X=this.ents.get(Z);if(X===void 0)return;if(v(X))this.unindex(Z,X);this.ents.delete(Z)}index(Z,X){if(!this.useIndex)return;let W=this.byType.get(X.type);if(!W)W=new Map,this.byType.set(X.type,W);if(W.set(Z,X),X.pid){let V=g(X.pid),l=this.byTypePid.get(X.type);if(!l)l=new Map,this.byTypePid.set(X.type,l);let K=l.get(V);if(!K)K=new Map,l.set(V,K);K.set(Z,X)}if(typeof X.gid==="string"){let V=this.byTypeGid.get(X.type);if(!V)V=new Map,this.byTypeGid.set(X.type,V);let l=V.get(X.gid);if(!l)l=new Map,V.set(X.gid,l);l.set(Z,X)}if(X.tags){let V=this.byTypeTag.get(X.type);if(!V)V=new Map,this.byTypeTag.set(X.type,V);for(let l of X.tags){let K=V.get(l);if(!K)K=new Map,V.set(l,K);K.set(Z,X)}}}unindex(Z,X){if(!this.useIndex)return;let W=this.byType.get(X.type);if(W){if(W.delete(Z),W.size===0)this.byType.delete(X.type)}if(X.pid){let V=g(X.pid),l=this.byTypePid.get(X.type),K=l?.get(V);if(K){if(K.delete(Z),K.size===0)l?.delete(V)}if(l&&l.size===0)this.byTypePid.delete(X.type)}if(typeof X.gid==="string"){let V=this.byTypeGid.get(X.type),l=V?.get(X.gid);if(l){if(l.delete(Z),l.size===0)V?.delete(X.gid)}if(V&&V.size===0)this.byTypeGid.delete(X.type)}if(X.tags){let V=this.byTypeTag.get(X.type);if(V){for(let l of X.tags){let K=V.get(l);if(K){if(K.delete(Z),K.size===0)V.delete(l)}}if(V.size===0)this.byTypeTag.delete(X.type)}}}clearIndexes(){this.byType.clear(),this.byTypePid.clear(),this.byTypeGid.clear(),this.byTypeTag.clear()}bucketList(Z){if(!Z||Z.size===0)return[];let X=[];for(let W of Z.values())X.push(W);return X}async apply(Z){let X=new Set,W=[],V=[];for(let l of Z){let K=g(l.eid),G=this.ents.get(K),[m,R]=YX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of RX(G,m))X.add(J);this.put(m),W.push(l.eid),V.push(0)}return{stats:V,types:X,eids:W}}async clear(){return this.ents.clear(),this.clearIndexes(),0}async getRow(Z){let X=g(Z),W=this.ents.get(X);return b(W)}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!v(X))return b(void 0);return b(X)}async getAllEntities({type:Z,gid:X,pid:W,tag:V,updatedBetween:l}){if(this.useIndex){if(W!==void 0){let G=g(W);return b(this.bucketList(this.byTypePid.get(Z)?.get(G)))}if(X!==void 0)return b(this.bucketList(this.byTypeGid.get(Z)?.get(X)));if(V!==void 0)return b(this.bucketList(this.byTypeTag.get(Z)?.get(V)));if(l!==void 0){let G=[],m=this.byType.get(Z);if(m){for(let R of m.values())if(R.updatedAt>=l.start&&R.updatedAt<=l.end)G.push(R)}return b(G)}return b(this.bucketList(this.byType.get(Z)))}let K=[];if(W!==void 0){for(let G of this.ents.values())if(v(G)&&G.type===Z&&G.pid&&n(G.pid,W))K.push(G)}else if(X!==void 0){for(let G of this.ents.values())if(v(G)&&G.type===Z&&(typeof G.gid==="string"&&G.gid===X))K.push(G)}else if(V!==void 0){for(let G of this.ents.values())if(v(G)&&G.type===Z&&G.tags&&G.tags.includes(V))K.push(G)}else if(l!==void 0){for(let G of this.ents.values())if(v(G)&&G.type===Z&&G.updatedAt>=l.start&&G.updatedAt<=l.end)K.push(G)}else for(let G of this.ents.values())if(v(G)&&G.type===Z)K.push(G);return b(K)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return b(X)}async countEntities({type:Z}){if(this.useIndex)return b(this.byType.get(Z)?.size??0);let X=0;for(let W of this.ents.values())if(v(W)&&W.type===Z)X+=1;return b(X)}async checksum(Z){let X=[];for(let W of this.ents.values())X.push(MX(W));return zX(X,Z)}}async function WV(Z){let X=await Ql();if(Z?.cache===!1)return X;return new xX(X,void 0,{indexes:Z?.indexes})}class xX{mem;durable;warmed=new Set;listeners=new Set;chain=Promise.resolve();constructor(Z,X,W){if(this.durable=Z,this.mem=new eX(X??[],{indexes:W?.indexes}),X)for(let V of X)this.warmed.add(V.type)}subscribe(Z){return this.listeners.add(Z),()=>{this.listeners.delete(Z)}}emit(Z){if(Z.size<1)return;for(let X of this.listeners)X(Z)}run(Z){let X=this.chain.then(Z,Z);return this.chain=X.then(()=>{return},()=>{return}),X}apply(Z){return this.run(async()=>{await this.pullEids(Z.map((K)=>K.eid));let X=IK(this.mem,Z);this.emit(X.types);let W=await this.durable.apply(Z),{changed:V,status:l}=await this.pullEids(Z.map((K)=>K.eid));if(this.emit(V),l!==0)return{stats:Z.map(()=>l),types:W.types,eids:W.eids};return W})}clear(){return this.run(async()=>{let Z=await this.durable.clear();if(Z!==0)return Z;let X=this.mem.ents.size>0;return await this.mem.clear(),this.warmed.clear(),0})}ingestFromDurable(Z){return this.run(async()=>{let{changed:X,status:W}=await this.pullEids(Z);return this.emit(X),W})}async pullEids(Z){let X=new Set,W=new Set;for(let V of Z){let l=g(V);if(W.has(l))continue;W.add(l);let K=this.mem.ents.get(l),[G,m]=await this.durable.getRow(V);if(m!==0)return{changed:X,status:m};if(G){if(this.mem.put(G),!K||!CK(K,G)){if(v(G))X.add(G.type);if(K!==void 0&&v(K))X.add(K.type)}}else if(K!==void 0){if(this.mem.del(l),v(K))X.add(K.type)}}return{changed:X,status:0}}async warmType(Z){if(this.warmed.has(Z))return 0;let[X,W]=await this.durable.getEntities({type:Z});if(W!==0)return W;if(X)for(let V of X){let l=g(V.eid),K=this.mem.ents.get(l);if(!K||kK(V,K))this.mem.put(V)}return this.warmed.add(Z),0}async getRow(Z){let X=g(Z);if(this.mem.ents.has(X))return this.mem.getRow(Z);return this.run(async()=>{if(this.mem.ents.has(X))return this.mem.getRow(Z);let[W,V]=await this.durable.getRow(Z);if(V!==0)return Y(V);if(W)this.mem.put(W);return b(W)})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!v(X))return b(void 0);return b(X)}async getEntities(Z){if(!this.warmed.has(Z.type)){let X=await this.run(()=>this.warmType(Z.type));if(X!==0)return Y(X)}return this.mem.getEntities(Z)}async countEntities({type:Z}){if(!this.warmed.has(Z)){let X=await this.run(()=>this.warmType(Z));if(X!==0)return Y(X)}return this.mem.countEntities({type:Z})}async checksum(Z){return this.durable.checksum(Z)}}function CK(Z,X){if(v(Z)!==v(X))return!1;if(Z.ctr!==X.ctr)return!1;if(Z.updatedAt.getTime()!==X.updatedAt.getTime())return!1;if(!n(Z.eid,X.eid))return!1;if(!v(Z)||!v(X))return!0;if(Z.createdAt.getTime()!==X.createdAt.getTime())return!1;if(Z.type!==X.type)return!1;if(Z.gid!==X.gid)return!1;if(!bK(Z.pid,X.pid))return!1;if(!FK(Z.tags,X.tags))return!1;return dK(Z.body,X.body)}function FK(Z,X){if(Z===X)return!0;if(Z===void 0||X===void 0)return!1;if(Z.length!==X.length)return!1;for(let W=0;W<Z.length;W++)if(Z[W]!==X[W])return!1;return!0}function bK(Z,X){if(Z===void 0&&X===void 0)return!0;if(Z===void 0||X===void 0)return!1;return n(Z,X)}function dK(Z,X){if(Object.is(Z,X))return!0;if(Z instanceof Uint8Array&&X instanceof Uint8Array)return n(Z,X);if(Z instanceof Date&&X instanceof Date)return Z.getTime()===X.getTime();try{return n(vZ(Z),vZ(X))}catch{return!1}}function kK(Z,X){let W=Z.updatedAt.getTime(),V=X.updatedAt.getTime();if(W!==V)return W>V;return Z.ctr>X.ctr}function IK(Z,X){let W=new Set,V=[];for(let l of X){let K=g(l.eid),G=Z.ents.get(K),[m,R]=YX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of RX(G,m))W.add(J);Z.put(m),V.push(0)}return{stats:V,types:W}}function ZW(Z){if(Z instanceof xX){let X=new NX((W)=>Z.apply(W),()=>Z.clear(),void 0,{cacheDriven:!0,peerIngest:async(W)=>{await Z.ingestFromDurable(W)}});return Z.subscribe((W)=>X.notify(W)),X}return new NX((X)=>Z.apply(X),()=>Z.clear())}function v(Z){return"type"in Z}function TK(Z){return!v(Z)}function pl(Z){if(!Array.isArray(Z)||Z.length===0)return;let X=new Set,W=[];for(let V of Z){if(typeof V!=="string"||V.length===0)continue;if(X.has(V))continue;X.add(V),W.push(V)}return W.length>0?W:void 0}function MX(Z){return{eid:Z.eid,ctr:Z.ctr,updatedAt:Z.updatedAt}}function VV(Z){let X=new O(Z.eid),[W,V]=X.readStruct(s);if(V!==0)return Y(V);return b({eid:Z.eid,ctr:Z.ctr,updatedAt:new Date(W.ts.getTime()+Z.off)})}function YX(Z,X){let W=new O(X.eid),[V,l]=W.readStruct(s);if(l!==0)return Y(l);let K=new Date(V.ts.getTime()+X.off);if(Z!==void 0&&K<=Z.updatedAt)return Y(15);if(Tl(X)){let G=pl(X.tags);return b({eid:X.eid,gid:X.gid,pid:X.pid,...G!==void 0?{tags:G}:{},type:X.type,createdAt:V.ts,updatedAt:K,ctr:X.ctr,body:X.body})}return b({eid:X.eid,updatedAt:K,ctr:X.ctr})}function RX(Z,X){let W=new Set;if(Z!==void 0&&v(Z))W.add(Z.type);if(v(X))W.add(X.type);return[...W]}var LK={getEnt:async()=>Y(21),getRow:async()=>Y(21),getEntities:async(Z)=>Y(21),countEntities:async()=>Y(21),checksum:async()=>Y(21),apply:async(Z)=>({stats:Z.map(()=>21),types:new Set,eids:[]}),clear:async()=>21};class XW{inflight=null;again=!1;run(Z){if(this.again=!0,this.inflight)return this.inflight;return this.inflight=this.drain(Z),this.inflight}async flush(){if(!this.inflight)return;try{await this.inflight}catch{}}async drain(Z){try{this.again=!1;let X=await Z();while(this.again)this.again=!1,X=await Z();return X}finally{this.inflight=null}}}var WW=100;class gX{timer=null;delayMs;work;tail=new XW;constructor(Z,X){this.delayMs=Z<0?0:Z,this.work=X}schedule(){if(this.delayMs<=0){this.fire();return}if(this.timer!==null)clearTimeout(this.timer);this.timer=setTimeout(()=>{this.timer=null,this.fire()},this.delayMs)}async flush(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null,this.fire();await this.tail.flush()}cancel(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null}fire(){return this.tail.run(this.work)}}function yl(Z){let X=new O(Z.eid),[W,V]=s.decode(X);if(V!==0)return;return W.ts.getTime()+Z.off}function cK(Z,X){let W=yl(Z),V=yl(X);if(W===void 0&&V===void 0)return 0;if(W===void 0)return 1;if(V===void 0)return-1;if(V!==W)return V-W;return X.ctr-Z.ctr}function JX(Z,X){return Z.slice().sort((W,V)=>cK(X(W),X(V)))}var $Z={phase:"idle"},CX=50;function VW(Z,X,W){if(Z<=0||X<=0)return!1;if(Z===1||Z===X)return!0;return Z%W===0}function lW(Z,X){if(typeof navigator.msSaveOrOpenBlob==="function"){navigator.msSaveOrOpenBlob(Z,X);return}let W=URL.createObjectURL(Z),V=document.createElement("a");V.href=W,V.download=X,document.body.appendChild(V),V.click(),document.body.removeChild(V),URL.revokeObjectURL(W)}function Sl(Z,X,W){let V=[],l=[],K=0;for(let G of Z){let m=X(G);if(l.length>0&&K+m>W)V.push(l),l=[],K=0;if(l.push(G),K+=m,K>=W)V.push(l),l=[],K=0}if(l.length>0)V.push(l);return V}async function lV(Z,X,W){let V=Z.length;if(V<1)return[];let l=Array(V),K=0,G=Math.min(Math.max(1,X),V),m=async()=>{while(!0){let J=K;if(K+=1,J>=V)return;l[J]=await W(Z[J],J)}},R=[];for(let J=0;J<G;J++)R.push(m());return await Promise.all(R),l}async function KW(Z,X,W,V){let l=new O(Z.headCph),[K,G]=l.readStruct(_X);if(G!==0)return Y(G);let{sig:m,kdm:R,headCph:J}=K;if(!await V.checkSigEd25519(m,J,X))return Y(3);let F=W.deriveCipher(R,"decrypt"),d;try{d=await F.decrypt(J)}catch{return Y(20)}return b({kdm:R,headEnc:d})}var SZ="f",BZ="t",LZ="e";function QK(Z){return Z===SZ||Z===BZ||Z===LZ}function FX(Z){if(Z===!0||Z===BZ)return BZ;if(Z===LZ)return LZ;return SZ}function pK(Z){return FX(Z.apld)===SZ}function KV(Z){return Z!==0&&Z!==15&&Z!==18&&Z!==17}function oZ(Z,X,W){if(Z.apld=X,X===LZ&&W!==void 0)Z.err=W;else delete Z.err}async function jZ(Z,X,W,V){let l=V?.body!==!1,K=FX(X.apld),G=X.body,m=G?.length??0,R;if(l&&G&&m>0)R=await W.blake3(G);let J={eid:X.eid,off:X.off??0,ctr:X.ctr??0,len:m,hsh:R},C={hash:Z,head:J,apld:K};if(l&&G!==void 0)C.body=G;if(K===LZ&&X.err!==void 0)C.err=X.err;return C}var GV=1048576,mV=1048576,Nl=64;function yK(Z){return Z.sig.length+Z.kdm.length+Z.headCph.length+Z.bodyCph.length}async function SK(Z,X,W,V,l){if(V.length<1)return 0;let[K,G]=await Z.push(V);if(G!==0)return G;if(!K)return 27;for(let R of K){if(R.status!==0){console.error("push err",R);continue}let J=l[R.idx];if(!J){console.error("no hash",R);continue}await X.uploads.deq(W,[J])}let m=await X.hosts.get(W);if(m){let R=m.lastSeq,J=R,C=[];for(let F of K)if(F.status===0)C.push(F.seq);C.sort((F,d)=>F-d);for(let F of C)if(F===R+1)R=F;if(R>J)await X.hosts.touch(W,R)}return 0}async function zl(Z,X){if(X.length<1)return b([]);let W=new Map,V=[];for(let m of X)W.set(m.seq,m),V.push(m.seq);let[l,K]=await Z.pull(V);if(K!==0)return Y(K);if(!l)return Y(27);let G=[];for(let{seq:m,bodyCph:R}of l){let J=W.get(m);if(!J)continue;G.push({dl:J,bodyCph:R})}return b(G)}async function zK(Z,X,W,V){if(V.length<1)return b({parts:[],hashes:[]});let l=[],K=[],G=[],m=new Map;for(let{dl:J,bodyCph:C}of V){let{head:F,kdm:d,seq:k,host:I}=J,[T,L]=await Ml(J,W);if(L!==0||!T){let U=m.get(I)??[];U.push(k),m.set(I,U);continue}let{headEnc:p,headEncHash:Q}=T,S=X.deriveCipher(d,"decrypt"),[c,M]=await uW(p,C,S,W,Q);if(M!==0||!c){let U=m.get(I)??[];U.push(k),m.set(I,U);continue}let H={head:F,body:c.bod},B=c.headHash;G.push({key:B,data:Hl(H)}),l.push(H),K.push(B);let i=m.get(I)??[];i.push(k),m.set(I,i)}let R=await Z.messages.add(G);for(let[J,C]of m)await Z.downloads.deq(J,C);for(let J=0;J<R.length;J++){let C=R[J];if(C!==0&&C!==15)console.error("ERR storing",z[C],"for message",J)}return b({parts:l,hashes:K})}async function Ml(Z,X){let W=Z.headEnc;if(!W){let l=new E,K=l.writeStruct(JZ,Z.head);if(K!==0)return Y(K);W=l.result()}if(Z.headEncHash)return b({headEnc:W,headEncHash:Z.headEncHash});let V=await X.blake3(W);return b({headEnc:W,headEncHash:V})}async function xl(Z,X,W){let V=new Set;for(let G of X)V.add(g(G));if(V.size<1)return;let l=Array.from(await Z.downloads.list());if(l.length<1)return;let K=new Map;for(let G of l){let m;if(G.headEncHash)m=g(G.headEncHash);else{let[J,C]=await Ml(G,W);if(C!==0||!J)continue;m=g(J.headEncHash)}if(!V.has(m))continue;let R=K.get(G.host)??[];R.push(G.seq),K.set(G.host,R)}for(let[G,m]of K)await Z.downloads.deq(G,m)}async function YV({conn:Z,store:X,enclave:W,host:V,crypto:l,onProgress:K,peekProgressEvery:G,peekConcurrency:m}){let R=await Z.identity(),J=[],[C,F]=await Z.peek(V.lastSeq);if(F!==0)return F;let d=C.length,k=G??CX,I=m??Nl;if(K&&d>0)K({phase:"peek",host:V.label,done:0,total:d});let T=0,L=await lV(C,I,async(Q)=>{let[S,c]=await KW(Q,R.publicKey,W,l),M;if(c!==0||!S)M={ok:!1,seq:Q.seq,stat:c};else{let H=await l.blake3(S.headEnc);M={ok:!0,seq:Q.seq,kdm:S.kdm,headEnc:S.headEnc,headEncHash:H}}if(T+=1,K&&VW(T,d,k))K({phase:"peek",host:V.label,done:T,total:d});return M}),p=new Set;for(let Q of L){if(!Q.ok){console.error("peek: decrypting item head",Q.stat);continue}let S=g(Q.headEncHash);if(await X.messages.has(Q.headEncHash)){console.info("peek: local msg; skip download, deq upload"),await X.uploads.deq(V.label,[Q.headEncHash]),await X.downloads.deq(V.label,[Q.seq]);continue}if(p.has(S)){await X.downloads.deq(V.label,[Q.seq]);continue}let M=new O(Q.headEnc),[H,B]=M.readStruct(JZ);if(B!==0){console.error("peek: reading item head",B);continue}p.add(S),J.push({kdm:Q.kdm,head:H,seq:Q.seq,host:V.label,headEnc:Q.headEnc,headEncHash:Q.headEncHash})}if(await X.downloads.enq(J),C.length>0){let Q=Math.max(...C.map((S)=>S.seq));await X.hosts.recordStats(V.label,{lastSeq:Q})}if(K)K({phase:"peek",host:V.label,done:d,total:d});return 0}async function gl({conn:Z,store:X,host:W,maxPushBytes:V,onProgress:l}){let K=V??GV,G=await X.uploads.list(W.label),m=G.length,R=0;if(l&&m>0)l({phase:"push",host:W.label,done:0,total:m});let J=[],C=[],F=0,d=async()=>{if(J.length<1)return 0;let k=J.length,I=await SK(Z,X,W.label,J,C);if(J=[],C=[],F=0,I===0){if(R+=k,l)l({phase:"push",host:W.label,done:R,total:m})}return I};for(let k of G){let I=await X.messages.get(k);if(!I){R+=1;continue}let T={...I.head,bod:I.body},[L,p]=await Z.seal(T);if(p!==0)return p;if(!L)return 12;let Q=yK(L);if(J.length>0&&F+Q>K){let S=await d();if(S!==0)return S}if(J.push(L),C.push(k),F+=Q,F>=K){let S=await d();if(S!==0)return S}}return d()}async function RV({conn:Z,store:X,enclave:W,host:V,crypto:l,maxPullBytes:K,onProgress:G},m){let R=K??mV,J=await X.downloads.list(),C=Array.from(J).filter((L)=>L.host===V.label);if(C.length<1)return 15;let F=JX(C,(L)=>L.head),d=Sl(F,(L)=>L.head.len,R),k=F.length,I=0;if(G)G({phase:"pull",host:V.label,done:0,total:k});let T=zl(Z,d[0]);for(let L=0;L<d.length;L++){let[p,Q]=await T;if(Q!==0||!p)return Q;if(I+=d[L].length,G)G({phase:"pull",host:V.label,done:I,total:k});let S=d[L+1];if(S)T=zl(Z,S);if(G)G({phase:"open",host:V.label,done:I,total:k});let c=JX(p,(H)=>H.dl.head),[,M]=await zK(X,W,l,c);if(M!==0)return M;if(m){if(G)G({phase:"exec",host:V.label,done:I,total:k});await m()}}return 0}function Hl({head:Z,body:X}){let W={eid:Z.eid,body:X,apld:SZ};if(Z.off!==0)W.off=Z.off;if(Z.ctr!==0)W.ctr=Z.ctr;return W}async function hl(Z,{conn:X,store:W,enclave:V,host:l,crypto:K,onProgress:G},m){let R=l.label,J=await X.identity(),C=new O(Z),[F,d]=C.readStructs(nX);if(d!==0){console.error("Failed decoding notif",z[d]);return}let k=!1,T=(await W.hosts.get(R))?.lastSeq,L=[],p=!1;for(let c of F){let[M,H]=await KW({seq:c.seq,headCph:c.headCph},J.publicKey,V,K);if(H!==0){console.error("Failed decrypting notif",z[H]);continue}let B=await K.blake3(M.headEnc);if(await W.messages.has(B))continue;let i=new O(M.headEnc),[U,u]=i.readStruct(JZ);if(u!==0){console.error("Failed to parse head",z[u]);continue}if(!c.bodyCph&&U.len>0)p=!0,await W.downloads.enq([{seq:c.seq,host:R,kdm:M.kdm,head:U,headEnc:M.headEnc,headEncHash:B}]);else L.push({...M,head:U,bodyCph:c.bodyCph,headEncHash:B});if(T===void 0||c.seq!==T+1)console.log("out of seq",c.seq,T),k=!0;else T=c.seq}if(T!==void 0)await W.hosts.touch(l.label,T);let Q=[];for(let c of L){let M=V.deriveCipher(c.kdm,"decrypt"),[H,B]=await uW(c.headEnc,c.bodyCph,M,K);if(B!==0){console.error("Failed to open body",z[B]);continue}Q.push({key:c.headEncHash,data:Hl({head:c.head,body:H.bod})})}let S=await W.messages.add(Q);for(let c=0;c<S.length;c++){let M=S[c];if(M!==0&&M!==15)console.error("ERR storing",z[M],"for message",c)}if(G&&Q.length>0)G({phase:"open",host:l.label,done:Q.length,total:Q.length});if(k||p||Q.length>0)m()}async function JV(Z,X={}){let W=X.pull!==!1,V=X.push===!0,{conn:l,store:K,enclave:G,host:m,crypto:R,onProgress:J,peekProgressEvery:C,peekConcurrency:F}=Z,d=await l.identity(),[k,I]=await l.peek(0);if(I!==0)return Y(I);let T=k.length,L=C??CX,p=F??Nl;if(J&&T>0)J({phase:"peek",host:m.label,done:0,total:T});let Q=0,S=await lV(k,p,async(h)=>{let[j,P]=await KW(h,d.publicKey,G,R),A;if(P!==0||!j)A={ok:!1,seq:h.seq,stat:P};else{let x=await R.blake3(j.headEnc);A={ok:!0,seq:h.seq,kdm:j.kdm,headEnc:j.headEnc,headEncHash:x}}if(Q+=1,J&&VW(Q,T,L))J({phase:"peek",host:m.label,done:Q,total:T});return A}),c=new Map;for(let h of S){if(!h.ok)continue;let j=g(h.headEncHash),P=c.get(j);if(P)P.count+=1;else c.set(j,{hash:h.headEncHash,count:1,sample:h})}let M=0,H=[];for(let h of c.values()){if(h.count>1)M+=h.count-1;H.push(h.hash)}let B=k.length,i=c.size,U=await KX(H,R),u=[],D=0;for(let h of c.values()){if(await K.messages.has(h.hash)){await K.uploads.deq(m.label,[h.hash]);continue}if(D+=1,!W)continue;let P=h.sample,A=new O(P.headEnc),[x,_]=A.readStruct(JZ);if(_!==0){console.error("reconcile: reading msg header",_);continue}u.push({kdm:P.kdm,head:x,seq:P.seq,host:m.label,headEnc:P.headEnc,headEncHash:P.headEncHash})}if(u.length>0)await K.downloads.enq(u);let y=0;if(V){let h=await K.messages.listKeys(),j=new Set(c.keys()),P=[];for(let A of h)if(!j.has(g(A)))y+=1,P.push(A);if(P.length>0)await K.uploads.enq(m.label,P)}else{let h=await K.messages.listKeys(),j=new Set(c.keys());for(let P of h)if(!j.has(g(P)))y+=1}let o=k.length>0?Math.max(...k.map((h)=>h.seq)):0;if(await K.hosts.recordStats(m.label,{setLastSeq:o}),J)J({phase:"peek",host:m.label,done:T,total:T});return b({msgcheck:U,numBags:B,uniqueMsgs:i,numDupes:M,missingLocal:D,missingHost:y})}class bX{clock;state;store;transport;crypto;forceSkewHandlingByDefault;onScheduleSync;connections=new Map;applyChain=Promise.resolve();syncRuns=new XW;clientState;xferState;maxPushBytes;maxPullBytes;peekProgressEvery=CX;lastProgress=$Z;scheduledSync;constructor(Z,X,W,V,l,K=!0,G=GV,m=mV,R){this.clock=Z;this.state=X;this.store=W;this.transport=V;this.crypto=l;this.forceSkewHandlingByDefault=K;this.onScheduleSync=R;this.maxPushBytes=G,this.maxPullBytes=m,this.clientState=new IZ(()=>this.getClientState()),this.xferState=new IZ(()=>this.getXferState()),this.scheduledSync=new gX(WW,async()=>{try{console.info("Running scheduled sync"),await this.sync()}catch(J){console.error("Debounced sync failed:",J)}})}emitProgress=(Z)=>{this.lastProgress=Z,this.xferState.emit()};async setSeed(Z,X){await this.store.seed.save(Z,X),this.clientState.emit()}async getClientState(){let{store:Z,connections:X}=this,W=await Z.seed.load(),V=await Z.hosts.list(),l=!1;for(let K of X.values())if(K.isConnected()){l=!0;break}return{hasSeed:W!==void 0,hasHost:Array.from(V).length>0,connected:l}}async getXferState(){let{uploads:Z,downloads:X}=this.store,W=await Z.count();return{numDownloads:await X.count(),numUploads:W,progress:this.lastProgress}}apply=(Z,X)=>{return this.enqueueApplyJob(()=>this.doApply(Z,X))};async doApply(Z,X={enqueueUpload:!0,triggerUpload:!0}){let W=[],V=[];for(let{head:K,body:G}of Z){let m=new E;m.writeStruct(JZ,K);let R=m.result(),J=await this.crypto.blake3(R),C={eid:K.eid,body:G,apld:SZ};if(K.off!==0)C.off=K.off;if(K.ctr!==0)C.ctr=K.ctr;W.push(J),V.push({key:J,data:C})}await this.store.messages.add(V),await xl(this.store,W,this.crypto);let l=await this.doApplyHashes(W);if(X.enqueueUpload){let K=[];for(let G=0;G<W.length;G++){let m=l[G];if(m===0||m===15)K.push(W[G])}if(K.length>0){let G=await this.store.hosts.list();for(let m of G)await this.store.uploads.enq(m.label,K);this.xferState.emit()}}if(X.triggerUpload)this.scheduleSync();return l}enqueueApplyJob(Z){let X=this.applyChain.then(Z,Z);return this.applyChain=X.then(()=>{return},()=>{return}),X}drainApplyQueue(){return this.enqueueApplyJob(()=>this.doDrainApplyQueue())}async doDrainApplyQueue(){let Z=await this.store.messages.list({apld:SZ});if(Z.length<1)return[];let X=JX(Z,(W)=>W.head);return this.applyStored(X)}applyHashes=(Z)=>{return this.enqueueApplyJob(()=>this.doApplyHashes(Z))};async doApplyHashes(Z){let X=[];for(let l of Z){let K=await this.store.messages.get(l);if(K)X.push(K)}let W=await this.applyStored(X),V=new Map;for(let l=0;l<X.length;l++)V.set(g(X[l].hash),W[l]??12);return Z.map((l)=>V.get(g(l))??13)}async applyStored(Z){if(Z.length<1)return[];let X=Z.map((K)=>({...K.head,bod:K.body})),W=await this.state.apply(X),V=[],l=[];for(let K=0;K<Z.length;K++){let G=W[K];if(G===0||G===15)V.push(Z[K].hash);else if(G!==void 0&&KV(G))l.push({key:Z[K].hash,err:G})}if(V.length>0)await this.store.messages.markApplied(V);if(l.length>0)await this.store.messages.markFailed(l);return W}async insertRaw(Z){let{clock:X,crypto:W}=this,[V,l]=await dl({now:X.now(),bod:Z,crypto:W});if(l!==0)return Y(l);let G=(await this.apply([{head:V,body:Z}]))[0];if(G!==0&&G!==15)return Y(G??12);return b(V)}async makeUpdate(Z,X){let{clock:W,crypto:V}=this,l=W.now();if(Z.updatedAt.getTime()>l.getTime())return Y(4);let K=Z.ctr+1,[G,m]=await rX({now:l,eid:Z.eid,ctr:K,bod:X,crypto:V});if(m!==0)return Y(m);return b({head:G,body:X})}async updateWithSkew(Z,X,W){if(W===!1)return Y(4);let{clock:V,crypto:l}=this,K=V.now(),G=new O(Z.eid),[m,R]=G.readStruct(s);if(R!==0)return Y(R);let J=Z.updatedAt.getTime()-m.ts.getTime(),C={eid:Z.eid,off:J+1,ctr:Z.ctr+1,len:0},d=(await this.apply([{head:C,body:void 0}]))[0];if(d!==0&&d!==15)return Y(d??12);if(X===void 0)return b(C);let[k,I]=lX({id:m.id,ts:K});if(I!==0)return Y(I);let[T,L]=await rX({now:K,eid:k,ctr:0,bod:X,crypto:l});if(L!==0)return Y(L);let Q=(await this.apply([{head:T,body:X}]))[0];if(Q!==0&&Q!==15)return Y(Q??12);return b(T)}async updateRaw(Z,X,W=this.forceSkewHandlingByDefault){if(Z.updatedAt.getTime()>this.clock.now().getTime())return this.updateWithSkew(Z,X,W);return this.enqueueApplyJob(async()=>{let[V,l]=await this.makeUpdate(Z,X);if(l!==0)return Y(l);let G=(await this.doApply([V]))[0];if(G!==0&&G!==15)return Y(G??12);return b(V.head)})}async insert(Z){let{body:X,type:W,gid:V,pid:l,tags:K}=Z,m=vZ({body:X,type:W,gid:V,pid:l,tags:K});return this.insertRaw(m)}async update(Z){let{prior:X,body:W,type:V,gid:l,pid:K,tags:G,force:m}=Z,J=vZ({body:W,type:V,gid:l,pid:K,tags:G});return this.updateRaw(X,J,m??this.forceSkewHandlingByDefault)}async delete(Z){let X=Z.force??!0;if("prior"in Z)return this.updateRaw(Z.prior,void 0,X);let[W,V]=await this.revFromArchive(Z.eid);if(V!==0)return Y(V);return this.updateRaw(W,void 0,X)}async revFromArchive(Z){let X=await this.store.messages.last(Z);if(X)return VV(X.head);let W=new O(Z),[V,l]=W.readStruct(s);if(l!==0)return Y(l);return b({eid:Z,ctr:-1,updatedAt:V.ts})}async genEID(Z){let{clock:X,crypto:W}=this,V=X.now();if(Z!==void 0)return lX({id:Z,ts:V});let l=await W.genRandomBytes(8);return lX({id:l,ts:V})}sync(){return this.syncRuns.run(()=>this.doSync())}async doSync(){let{connections:Z,crypto:X,store:W}=this,V=await W.seed.load();if(!V)return 22;await this.drainApplyQueue();for(let[l,K]of Z){let G=await W.hosts.get(l);if(!G)continue;let m={conn:K,store:W,enclave:V,host:G,crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},R=await YV(m);if(R!==0)return console.error(`Failed to peek: ${R}`),this.emitProgress({phase:"idle"}),R;this.xferState.emit();let J=await gl(m);if(J!==0)return console.error(`Failed to push: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await RV(m,async()=>{await this.drainApplyQueue()});if(C!==0&&C!==15)return console.error(`Failed to pull: ${C}`),this.emitProgress({phase:"idle"}),C;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async rebuild(Z){if(this.scheduledSync.cancel(),await this.syncRuns.flush(),Z?.checkHost??!0){let W=await this.repull();if(W!==0)return W}return this.enqueueApplyJob(()=>this.replay())}async msgcheck(){let Z=await this.store.messages.listKeys();return KX(Z,this.crypto)}listMsgs(Z){return this.store.messages.list(Z)}countMsgs(Z){return this.store.messages.count(Z)}async reconcile(Z,X){this.scheduledSync.cancel(),await this.syncRuns.flush();let{connections:W,crypto:V,store:l}=this,K=await l.seed.load();if(!K)return Y(22);let G=await l.hosts.get(Z);if(!G)return Y(13);let m=W.get(Z);if(!m||!m.isConnected()){if(await this.connectToHost(G,!1,!1),G=await l.hosts.get(Z),!G)return Y(13);m=W.get(Z)}if(!m)return Y(12);let R={conn:m,store:l,enclave:K,crypto:V,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},[J,C]=await JV({...R,host:G},X);if(this.xferState.emit(),C!==0)return this.emitProgress({phase:"idle"}),Y(C);if(!J)return this.emitProgress({phase:"idle"}),Y(12);if(X?.sync===!1)return this.emitProgress({phase:"idle"}),b(J);let F=await this.sync();if(F!==0)return Y(F);let d=await l.hosts.get(Z);if(!d)return Y(13);let[k,I]=await JV({...R,host:d},{pull:!1,push:!1});if(this.xferState.emit(),this.emitProgress({phase:"idle"}),I!==0)return Y(I);if(!k)return Y(12);return b(k)}async repull(){let{connections:Z,crypto:X,store:W}=this,V=await W.seed.load();if(!V)return 22;let l=Array.from(await W.hosts.list());if(l.length<1)return 0;for(let K of l){let G=Z.get(K.label);if(!G||!G.isConnected())await this.connectToHost(K,!1,!1)}for(let[K,G]of Z){let m=await W.hosts.get(K);if(!m)continue;let R={conn:G,store:W,enclave:V,host:{...m,lastSeq:0},crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},J=await YV(R);if(J!==0)return console.error(`rebuild: failed to peek: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await RV(R);if(C!==0&&C!==15)return console.error(`rebuild: failed to pull: ${C}`),this.emitProgress({phase:"idle"}),C;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async replay(){let Z=await this.state.clear();if(Z!==0)return Z;let X=await this.store.messages.list(),W=JX(X,(K)=>K.head),V=W.length;if(V<1)return this.emitProgress({phase:"idle"}),0;let l=0;while(l<W.length){let K=0,G=0,m=l;for(let J=l;J<W.length&&G<100&&K<102400;J++)K+=W[J].head.len,G++,m=J+1;let R=W.slice(l,m);await this.applyStored(R),this.emitProgress({phase:"exec",done:m,total:V}),l=m}return this.emitProgress({phase:"idle"}),0}async wipe(Z){let X=Z?.msgs!==!1,W=Z?.ents!==!1,V=Z?.meta!==!1,l=Z?.seed===!0;this.scheduledSync.cancel(),await this.disconnect(),await this.syncRuns.flush();let{store:K}=this;if(V)await K.hosts.wipe(),await K.uploads.wipe(),await K.downloads.wipe();if(X)await K.messages.wipe();if(l)await K.seed.wipe();if(W)await this.state.clear();this.lastProgress=$Z,this.clientState.emit(),this.xferState.emit()}import=async(Z,X)=>{let{crypto:W,store:V}=this,l=X?.onProgress,K=await V.seed.load();if(!K)return 22;console.time("import: decoding file...");let G=await Z.bytes(),[m,R]=await bl(G,W,K);if(R!==0)return R;console.timeEnd("import: decoding file...");let J=0;while(J<m.length){let C=0,F=0,d=J;for(let T=J;T<m.length&&F<100&&C<102400;T++)C+=m[T].head.len,F++,d=T+1;let k=m.slice(J,d);console.time(`import: applying [${J}, ${d}]`);let I=await this.apply(k,{enqueueUpload:!0,triggerUpload:!1});console.timeEnd(`import: applying [${J}, ${d}]`);for(let T=0;T<k.length;T++){let L=I[T];if(L!==0&&L!==15)console.warn(`failed to import msg ${J+T}: ${z[L]}`)}if(l)queueMicrotask(()=>l(d,m.length,0));this.emitProgress({phase:"import",done:d,total:m.length}),J=d}return this.scheduleSync(),this.emitProgress({phase:"idle"}),0};scheduleSync=()=>{if(this.onScheduleSync){this.onScheduleSync();return}this.scheduledSync.schedule()};async exportBytes(){let{crypto:Z,store:X}=this,W=await X.seed.load();if(!W)return Y(22);let V=await X.messages.list();return Fl("export",0,V,Z,W)}async export(Z){let[X,W]=await this.exportBytes();if(W!==0)return W;if(!X)return 12;let V=new Blob([X.slice()]);return lW(V,Z),0}async link(Z,X=!0){if(await this.store.hosts.add(Z),this.clientState.emit(),X){let W=await this.store.hosts.get(Z.label);if(W)await this.connectToHost(W)}}async unlink(Z){await this.store.hosts.del(Z),this.clientState.emit()}async hosts(){return Array.from(await this.store.hosts.list())}connectToHost=async(Z,X=!0,W=!0)=>{let{clock:V,connections:l,crypto:K,store:G,transport:m}=this,R=l.get(Z.label);if(R){if(R.isConnected())return;try{R.closeListener()}catch{}l.delete(Z.label)}let J=await G.seed.load();if(!J)return;console.info(`Connecting to ${Z.handle} (${Z.label})`);let C=new sX(J,K,Z,V,m(Z),(F)=>G.hosts.set(Z.label,F));if(await C.register(),X)await C.listen(async(F)=>{let d={conn:C,store:G,enclave:J,host:Z,crypto:K,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery};return hl(F,d,this.scheduleSync)},()=>this.clientState.emit(),()=>this.clientState.emit());if(l.set(Z.label,C),this.clientState.emit(),W)this.scheduleSync()};async connect(Z=!0,X=!0){let{connectToHost:W,scheduleSync:V,store:l}=this;if(!await l.seed.load())return;await this.drainApplyQueue();let G=await l.hosts.list();for(let m of G)await W(m,Z,!1);if(X)V()}disconnect=async()=>{for(let Z of this.connections.values())try{Z.closeListener()}catch{}this.connections.clear(),this.clientState.emit()}}var fZ=typeof globalThis==="object"&&"crypto"in globalThis?globalThis.crypto:void 0;function GW(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function CV(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function a(Z,...X){if(!CV(Z))throw Error("Uint8Array expected");if(X.length>0&&!X.includes(Z.length))throw Error("Uint8Array expected of length "+X+", got length="+Z.length)}function FV(Z,X=!0){if(Z.destroyed)throw Error("Hash instance has been destroyed");if(X&&Z.finished)throw Error("Hash#digest() has already been called")}function Ul(Z,X){a(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function bV(Z){if(typeof Z!=="boolean")throw Error(`boolean expected, not ${Z}`)}/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */var zZ=(Z)=>new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4));var NK=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!NK)throw Error("Non little-endian hardware is not supported");function MK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function mW(Z){if(typeof Z==="string")Z=MK(Z);else if(CV(Z))Z=YW(Z);else throw Error("Uint8Array expected, got "+typeof Z);return Z}function Pl(Z,X){if(X==null||typeof X!=="object")throw Error("options must be defined");return Object.assign(Z,X)}function Ol(Z,X){if(Z.length!==X.length)return!1;let W=0;for(let V=0;V<Z.length;V++)W|=Z[V]^X[V];return W===0}var il=(Z,X)=>{function W(V,...l){if(a(V),Z.nonceLength!==void 0){let C=l[0];if(!C)throw Error("nonce / iv required");if(Z.varSizeNonce)a(C);else a(C,Z.nonceLength)}let K=Z.tagLength;if(K&&l[1]!==void 0)a(l[1]);let G=X(V,...l),m=(C,F)=>{if(F!==void 0){if(C!==2)throw Error("cipher output not supported");a(F)}},R=!1;return{encrypt(C,F){if(R)throw Error("cannot encrypt() twice with same key + nonce");return R=!0,a(C),m(G.encrypt.length,F),G.encrypt(C,F)},decrypt(C,F){if(a(C),K&&C.length<K)throw Error("invalid ciphertext length: smaller than tagLength="+K);return m(G.decrypt.length,F),G.decrypt(C,F)}}}return Object.assign(W,Z),W};function dV(Z,X,W=!0){if(X===void 0)return new Uint8Array(Z);if(X.length!==Z)throw Error("invalid output length, expected "+Z+", got: "+X.length);if(W&&!xK(X))throw Error("invalid output, must be aligned");return X}function xK(Z){return Z.byteOffset%4===0}function YW(Z){return Uint8Array.from(Z)}function cZ(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function HX(Z=32){if(fZ&&typeof fZ.getRandomValues==="function")return fZ.getRandomValues(new Uint8Array(Z));if(fZ&&typeof fZ.randomBytes==="function")return fZ.randomBytes(Z);throw Error("crypto.getRandomValues must be defined")}var Bl=(Z)=>Uint8Array.from(Z.split("").map((X)=>X.charCodeAt(0))),gK=Bl("expand 16-byte k"),HK=Bl("expand 32-byte k"),hK=zZ(gK),UK=zZ(HK);function N(Z,X){return Z<<X|Z>>>32-X}function kV(Z){return Z.byteOffset%4===0}var RW=64,PK=16,jl=4294967295,El=new Uint32Array;function OK(Z,X,W,V,l,K,G,m){let R=l.length,J=new Uint8Array(RW),C=zZ(J),F=kV(l)&&kV(K),d=F?zZ(l):El,k=F?zZ(K):El;for(let I=0;I<R;G++){if(Z(X,W,V,C,G,m),G>=jl)throw Error("arx: counter overflow");let T=Math.min(RW,R-I);if(F&&T===RW){let L=I/4;if(I%4!==0)throw Error("arx: invalid block position");for(let p=0,Q;p<PK;p++)Q=L+p,k[Q]=d[Q]^C[p];I+=RW;continue}for(let L=0,p;L<T;L++)p=I+L,K[p]=l[p]^J[L];I+=T}}function ul(Z,X){let{allowShortKeys:W,extendNonceFn:V,counterLength:l,counterRight:K,rounds:G}=Pl({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},X);if(typeof Z!=="function")throw Error("core must be a function");return GW(l),GW(G),bV(K),bV(W),(m,R,J,C,F=0)=>{a(m),a(R),a(J);let d=J.length;if(C===void 0)C=new Uint8Array(d);if(a(C),GW(F),F<0||F>=jl)throw Error("arx: counter overflow");if(C.length<d)throw Error(`arx: output (${C.length}) is shorter than data (${d})`);let k=[],I=m.length,T,L;if(I===32)k.push(T=YW(m)),L=UK;else if(I===16&&W)T=new Uint8Array(32),T.set(m),T.set(m,16),L=hK,k.push(T);else throw Error(`arx: invalid 32-byte key, got length=${I}`);if(!kV(R))k.push(R=YW(R));let p=zZ(T);if(V){if(R.length!==24)throw Error("arx: extended nonce must be 24 bytes");V(L,p,zZ(R.subarray(0,16)),p),R=R.subarray(16)}let Q=16-l;if(Q!==R.length)throw Error(`arx: nonce must be ${Q} or 16 bytes`);if(Q!==12){let c=new Uint8Array(12);c.set(R,K?0:12-R.length),R=c,k.push(R)}let S=zZ(R);return OK(Z,L,p,S,J,C,F,G),cZ(...k),C}}var t=(Z,X)=>Z[X++]&255|(Z[X++]&255)<<8;class wl{constructor(Z){this.blockLen=16,this.outputLen=16,this.buffer=new Uint8Array(16),this.r=new Uint16Array(10),this.h=new Uint16Array(10),this.pad=new Uint16Array(8),this.pos=0,this.finished=!1,Z=mW(Z),a(Z,32);let X=t(Z,0),W=t(Z,2),V=t(Z,4),l=t(Z,6),K=t(Z,8),G=t(Z,10),m=t(Z,12),R=t(Z,14);this.r[0]=X&8191,this.r[1]=(X>>>13|W<<3)&8191,this.r[2]=(W>>>10|V<<6)&7939,this.r[3]=(V>>>7|l<<9)&8191,this.r[4]=(l>>>4|K<<12)&255,this.r[5]=K>>>1&8190,this.r[6]=(K>>>14|G<<2)&8191,this.r[7]=(G>>>11|m<<5)&8065,this.r[8]=(m>>>8|R<<8)&8191,this.r[9]=R>>>5&127;for(let J=0;J<8;J++)this.pad[J]=t(Z,16+2*J)}process(Z,X,W=!1){let V=W?0:2048,{h:l,r:K}=this,G=K[0],m=K[1],R=K[2],J=K[3],C=K[4],F=K[5],d=K[6],k=K[7],I=K[8],T=K[9],L=t(Z,X+0),p=t(Z,X+2),Q=t(Z,X+4),S=t(Z,X+6),c=t(Z,X+8),M=t(Z,X+10),H=t(Z,X+12),B=t(Z,X+14),i=l[0]+(L&8191),U=l[1]+((L>>>13|p<<3)&8191),u=l[2]+((p>>>10|Q<<6)&8191),D=l[3]+((Q>>>7|S<<9)&8191),y=l[4]+((S>>>4|c<<12)&8191),o=l[5]+(c>>>1&8191),h=l[6]+((c>>>14|M<<2)&8191),j=l[7]+((M>>>11|H<<5)&8191),P=l[8]+((H>>>8|B<<8)&8191),A=l[9]+(B>>>5|V),x=0,_=x+i*G+U*(5*T)+u*(5*I)+D*(5*k)+y*(5*d);x=_>>>13,_&=8191,_+=o*(5*F)+h*(5*C)+j*(5*J)+P*(5*R)+A*(5*m),x+=_>>>13,_&=8191;let XZ=x+i*m+U*G+u*(5*T)+D*(5*I)+y*(5*k);x=XZ>>>13,XZ&=8191,XZ+=o*(5*d)+h*(5*F)+j*(5*C)+P*(5*J)+A*(5*R),x+=XZ>>>13,XZ&=8191;let mZ=x+i*R+U*m+u*G+D*(5*T)+y*(5*I);x=mZ>>>13,mZ&=8191,mZ+=o*(5*k)+h*(5*d)+j*(5*F)+P*(5*C)+A*(5*J),x+=mZ>>>13,mZ&=8191;let f=x+i*J+U*R+u*m+D*G+y*(5*T);x=f>>>13,f&=8191,f+=o*(5*I)+h*(5*k)+j*(5*d)+P*(5*F)+A*(5*C),x+=f>>>13,f&=8191;let pZ=x+i*C+U*J+u*R+D*m+y*G;x=pZ>>>13,pZ&=8191,pZ+=o*(5*T)+h*(5*I)+j*(5*k)+P*(5*d)+A*(5*F),x+=pZ>>>13,pZ&=8191;let sZ=x+i*F+U*C+u*J+D*R+y*m;x=sZ>>>13,sZ&=8191,sZ+=o*G+h*(5*T)+j*(5*I)+P*(5*k)+A*(5*d),x+=sZ>>>13,sZ&=8191;let rZ=x+i*d+U*F+u*C+D*J+y*R;x=rZ>>>13,rZ&=8191,rZ+=o*m+h*G+j*(5*T)+P*(5*I)+A*(5*k),x+=rZ>>>13,rZ&=8191;let tZ=x+i*k+U*d+u*F+D*C+y*J;x=tZ>>>13,tZ&=8191,tZ+=o*R+h*m+j*G+P*(5*T)+A*(5*I),x+=tZ>>>13,tZ&=8191;let eZ=x+i*I+U*k+u*d+D*F+y*C;x=eZ>>>13,eZ&=8191,eZ+=o*J+h*R+j*m+P*G+A*(5*T),x+=eZ>>>13,eZ&=8191;let ZX=x+i*T+U*I+u*k+D*d+y*F;x=ZX>>>13,ZX&=8191,ZX+=o*C+h*J+j*R+P*m+A*G,x+=ZX>>>13,ZX&=8191,x=(x<<2)+x|0,x=x+_|0,_=x&8191,x=x>>>13,XZ+=x,l[0]=_,l[1]=XZ,l[2]=mZ,l[3]=f,l[4]=pZ,l[5]=sZ,l[6]=rZ,l[7]=tZ,l[8]=eZ,l[9]=ZX}finalize(){let{h:Z,pad:X}=this,W=new Uint16Array(10),V=Z[1]>>>13;Z[1]&=8191;for(let G=2;G<10;G++)Z[G]+=V,V=Z[G]>>>13,Z[G]&=8191;Z[0]+=V*5,V=Z[0]>>>13,Z[0]&=8191,Z[1]+=V,V=Z[1]>>>13,Z[1]&=8191,Z[2]+=V,W[0]=Z[0]+5,V=W[0]>>>13,W[0]&=8191;for(let G=1;G<10;G++)W[G]=Z[G]+V,V=W[G]>>>13,W[G]&=8191;W[9]-=8192;let l=(V^1)-1;for(let G=0;G<10;G++)W[G]&=l;l=~l;for(let G=0;G<10;G++)Z[G]=Z[G]&l|W[G];Z[0]=(Z[0]|Z[1]<<13)&65535,Z[1]=(Z[1]>>>3|Z[2]<<10)&65535,Z[2]=(Z[2]>>>6|Z[3]<<7)&65535,Z[3]=(Z[3]>>>9|Z[4]<<4)&65535,Z[4]=(Z[4]>>>12|Z[5]<<1|Z[6]<<14)&65535,Z[5]=(Z[6]>>>2|Z[7]<<11)&65535,Z[6]=(Z[7]>>>5|Z[8]<<8)&65535,Z[7]=(Z[8]>>>8|Z[9]<<5)&65535;let K=Z[0]+X[0];Z[0]=K&65535;for(let G=1;G<8;G++)K=(Z[G]+X[G]|0)+(K>>>16)|0,Z[G]=K&65535;cZ(W)}update(Z){FV(this);let{buffer:X,blockLen:W}=this;Z=mW(Z);let V=Z.length;for(let l=0;l<V;){let K=Math.min(W-this.pos,V-l);if(K===W){for(;W<=V-l;l+=W)this.process(Z,l);continue}if(X.set(Z.subarray(l,l+K),this.pos),this.pos+=K,l+=K,this.pos===W)this.process(X,0,!1),this.pos=0}return this}destroy(){cZ(this.h,this.r,this.buffer,this.pad)}digestInto(Z){FV(this),Ul(Z,this),this.finished=!0;let{buffer:X,h:W}=this,{pos:V}=this;if(V){X[V++]=1;for(;V<16;V++)X[V]=0;this.process(X,0,!0)}this.finalize();let l=0;for(let K=0;K<8;K++)Z[l++]=W[K]>>>0,Z[l++]=W[K]>>>8;return Z}digest(){let{buffer:Z,outputLen:X}=this;this.digestInto(Z);let W=Z.slice(0,X);return this.destroy(),W}}function iK(Z){let X=(V,l)=>Z(l).update(mW(V)).digest(),W=Z(new Uint8Array(32));return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var IV=iK((Z)=>new wl(Z));function EK(Z,X,W,V,l,K=20){let G=Z[0],m=X[0],R=X[1],J=X[2],C=X[3],F=Z[1],d=W[0],k=W[1],I=l,T=0,L=Z[2],p=X[4],Q=X[5],S=X[6],c=X[7],M=Z[3],H=G,B=m,i=R,U=J,u=C,D=F,y=d,o=k,h=I,j=T,P=L,A=p,x=Q,_=S,XZ=c,mZ=M;for(let pZ=0;pZ<K;pZ+=2)u^=N(H+x|0,7),h^=N(u+H|0,9),x^=N(h+u|0,13),H^=N(x+h|0,18),j^=N(D+B|0,7),_^=N(j+D|0,9),B^=N(_+j|0,13),D^=N(B+_|0,18),XZ^=N(P+y|0,7),i^=N(XZ+P|0,9),y^=N(i+XZ|0,13),P^=N(y+i|0,18),U^=N(mZ+A|0,7),o^=N(U+mZ|0,9),A^=N(o+U|0,13),mZ^=N(A+o|0,18),B^=N(H+U|0,7),i^=N(B+H|0,9),U^=N(i+B|0,13),H^=N(U+i|0,18),y^=N(D+u|0,7),o^=N(y+D|0,9),u^=N(o+y|0,13),D^=N(u+o|0,18),A^=N(P+j|0,7),h^=N(A+P|0,9),j^=N(h+A|0,13),P^=N(j+h|0,18),x^=N(mZ+XZ|0,7),_^=N(x+mZ|0,9),XZ^=N(_+x|0,13),mZ^=N(XZ+_|0,18);let f=0;V[f++]=G+H|0,V[f++]=m+B|0,V[f++]=R+i|0,V[f++]=J+U|0,V[f++]=C+u|0,V[f++]=F+D|0,V[f++]=d+y|0,V[f++]=k+o|0,V[f++]=I+h|0,V[f++]=T+j|0,V[f++]=L+P|0,V[f++]=p+A|0,V[f++]=Q+x|0,V[f++]=S+_|0,V[f++]=c+XZ|0,V[f++]=M+mZ|0}function BK(Z,X,W,V){let l=Z[0],K=X[0],G=X[1],m=X[2],R=X[3],J=Z[1],C=W[0],F=W[1],d=W[2],k=W[3],I=Z[2],T=X[4],L=X[5],p=X[6],Q=X[7],S=Z[3];for(let M=0;M<20;M+=2)R^=N(l+L|0,7),d^=N(R+l|0,9),L^=N(d+R|0,13),l^=N(L+d|0,18),k^=N(J+K|0,7),p^=N(k+J|0,9),K^=N(p+k|0,13),J^=N(K+p|0,18),Q^=N(I+C|0,7),G^=N(Q+I|0,9),C^=N(G+Q|0,13),I^=N(C+G|0,18),m^=N(S+T|0,7),F^=N(m+S|0,9),T^=N(F+m|0,13),S^=N(T+F|0,18),K^=N(l+m|0,7),G^=N(K+l|0,9),m^=N(G+K|0,13),l^=N(m+G|0,18),C^=N(J+R|0,7),F^=N(C+J|0,9),R^=N(F+C|0,13),J^=N(R+F|0,18),T^=N(I+k|0,7),d^=N(T+I|0,9),k^=N(d+T|0,13),I^=N(k+d|0,18),L^=N(S+Q|0,7),p^=N(L+S|0,9),Q^=N(p+L|0,13),S^=N(Q+p|0,18);let c=0;V[c++]=l,V[c++]=J,V[c++]=I,V[c++]=S,V[c++]=C,V[c++]=F,V[c++]=d,V[c++]=k}var TV=ul(EK,{counterRight:!0,extendNonceFn:BK}),LV=il({blockSize:64,nonceLength:24,tagLength:16},(Z,X)=>{return{encrypt(W,V){V=dV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32);V.set(W,32),cZ(l),TV(Z,X,V,V);let G=IV(K,l);return V.set(G,16),cZ(V.subarray(0,16),G),V.subarray(16)},decrypt(W,V){a(W),V=dV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32,48),G=V.subarray(48);V.set(W,32),cZ(l);let m=TV(Z,X,l,l),R=IV(G,m);if(!Ol(K,R))throw Error("invalid tag");return TV(Z,X,V.subarray(16),V.subarray(16)),cZ(l,K,R),G}}});/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function jK(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function hX(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function qZ(Z,...X){if(!jK(Z))throw Error("Uint8Array expected");if(X.length>0&&!X.includes(Z.length))throw Error("Uint8Array expected of length "+X+", got length="+Z.length)}function UX(Z,X=!0){if(Z.destroyed)throw Error("Hash instance has been destroyed");if(X&&Z.finished)throw Error("Hash#digest() has already been called")}function JW(Z,X){qZ(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function Dl(Z){return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength)}function dX(Z){return new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4))}function kX(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function PX(Z,X){return Z<<32-X|Z>>>X}var Al=(()=>new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68)();function vl(Z){return Z<<24&4278190080|Z<<8&16711680|Z>>>8&65280|Z>>>24&255}var $l=Al?(Z)=>Z:(Z)=>vl(Z);function uK(Z){for(let X=0;X<Z.length;X++)Z[X]=vl(Z[X]);return Z}var lZ=Al?(Z)=>Z:uK;function wK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function IX(Z){if(typeof Z==="string")Z=wK(Z);return qZ(Z),Z}class cV{}function ol(Z){let X=(V,l)=>Z(l).update(IX(V)).digest(),W=Z({});return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var fl=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var CW=BigInt(4294967295),ql=BigInt(32);function QV(Z,X=!1){if(X)return{h:Number(Z&CW),l:Number(Z>>ql&CW)};return{h:Number(Z>>ql&CW)|0,l:Number(Z&CW)|0}}function NZ(Z,X,W,V,l){return Z=Z+X+l|0,V=PX(V^Z,16),W=W+V|0,X=PX(X^W,12),{a:Z,b:X,c:W,d:V}}function MZ(Z,X,W,V,l){return Z=Z+X+l|0,V=PX(V^Z,8),W=W+V|0,X=PX(X^W,7),{a:Z,b:X,c:W,d:V}}class pV extends cV{constructor(Z,X){super();this.finished=!1,this.destroyed=!1,this.length=0,this.pos=0,hX(Z),hX(X),this.blockLen=Z,this.outputLen=X,this.buffer=new Uint8Array(Z),this.buffer32=dX(this.buffer)}update(Z){UX(this),Z=IX(Z),qZ(Z);let{blockLen:X,buffer:W,buffer32:V}=this,l=Z.length,K=Z.byteOffset,G=Z.buffer;for(let m=0;m<l;){if(this.pos===X)lZ(V),this.compress(V,0,!1),lZ(V),this.pos=0;let R=Math.min(X-this.pos,l-m),J=K+m;if(R===X&&!(J%4)&&m+R<l){let C=new Uint32Array(G,J,Math.floor((l-m)/4));lZ(C);for(let F=0;m+X<l;F+=V.length,m+=X)this.length+=X,this.compress(C,F,!1);lZ(C);continue}W.set(Z.subarray(m,m+R),this.pos),this.pos+=R,this.length+=R,m+=R}return this}digestInto(Z){UX(this),JW(Z,this);let{pos:X,buffer32:W}=this;this.finished=!0,kX(this.buffer.subarray(X)),lZ(W),this.compress(W,0,!0),lZ(W);let V=dX(Z);this.get().forEach((l,K)=>V[K]=$l(l))}digest(){let{buffer:Z,outputLen:X}=this;this.digestInto(Z);let W=Z.slice(0,X);return this.destroy(),W}_cloneInto(Z){let{buffer:X,length:W,finished:V,destroyed:l,outputLen:K,pos:G}=this;return Z||(Z=new this.constructor({dkLen:K})),Z.set(...this.get()),Z.buffer.set(X),Z.destroyed=l,Z.finished=V,Z.length=W,Z.pos=G,Z.outputLen=K,Z}clone(){return this._cloneInto()}}function yV(Z,X,W,V,l,K,G,m,R,J,C,F,d,k,I,T,L,p,Q,S){let c=0;for(let M=0;M<V;M++)({a:l,b:R,c:d,d:L}=NZ(l,R,d,L,W[X+Z[c++]])),{a:l,b:R,c:d,d:L}=MZ(l,R,d,L,W[X+Z[c++]]),{a:K,b:J,c:k,d:p}=NZ(K,J,k,p,W[X+Z[c++]]),{a:K,b:J,c:k,d:p}=MZ(K,J,k,p,W[X+Z[c++]]),{a:G,b:C,c:I,d:Q}=NZ(G,C,I,Q,W[X+Z[c++]]),{a:G,b:C,c:I,d:Q}=MZ(G,C,I,Q,W[X+Z[c++]]),{a:m,b:F,c:T,d:S}=NZ(m,F,T,S,W[X+Z[c++]]),{a:m,b:F,c:T,d:S}=MZ(m,F,T,S,W[X+Z[c++]]),{a:l,b:J,c:I,d:S}=NZ(l,J,I,S,W[X+Z[c++]]),{a:l,b:J,c:I,d:S}=MZ(l,J,I,S,W[X+Z[c++]]),{a:K,b:C,c:T,d:L}=NZ(K,C,T,L,W[X+Z[c++]]),{a:K,b:C,c:T,d:L}=MZ(K,C,T,L,W[X+Z[c++]]),{a:G,b:F,c:d,d:p}=NZ(G,F,d,p,W[X+Z[c++]]),{a:G,b:F,c:d,d:p}=MZ(G,F,d,p,W[X+Z[c++]]),{a:m,b:R,c:k,d:Q}=NZ(m,R,k,Q,W[X+Z[c++]]),{a:m,b:R,c:k,d:Q}=MZ(m,R,k,Q,W[X+Z[c++]]);return{v0:l,v1:K,v2:G,v3:m,v4:R,v5:J,v6:C,v7:F,v8:d,v9:k,v10:I,v11:T,v12:L,v13:p,v14:Q,v15:S}}var QZ={CHUNK_START:1,CHUNK_END:2,PARENT:4,ROOT:8,KEYED_HASH:16,DERIVE_KEY_CONTEXT:32,DERIVE_KEY_MATERIAL:64},xZ=fl.slice(),nl=(()=>{let Z=Array.from({length:16},(V,l)=>l),X=(V)=>[2,6,3,10,7,0,4,13,1,11,12,5,9,14,15,8].map((l)=>V[l]),W=[];for(let V=0,l=Z;V<7;V++,l=X(l))W.push(...l);return Uint8Array.from(W)})();class SV extends pV{constructor(Z={},X=0){super(64,Z.dkLen===void 0?32:Z.dkLen);this.chunkPos=0,this.chunksDone=0,this.flags=0,this.stack=[],this.posOut=0,this.bufferOut32=new Uint32Array(16),this.chunkOut=0,this.enableXOF=!0;let{key:W,context:V}=Z,l=V!==void 0;if(W!==void 0){if(l)throw Error('Only "key" or "context" can be specified at same time');let K=IX(W).slice();qZ(K,32),this.IV=dX(K),lZ(this.IV),this.flags=X|QZ.KEYED_HASH}else if(l){let K=IX(V),G=new SV({dkLen:32},QZ.DERIVE_KEY_CONTEXT).update(K).digest();this.IV=dX(G),lZ(this.IV),this.flags=X|QZ.DERIVE_KEY_MATERIAL}else this.IV=xZ.slice(),this.flags=X;this.state=this.IV.slice(),this.bufferOut=Dl(this.bufferOut32)}get(){return[]}set(){}b2Compress(Z,X,W,V=0){let{state:l,pos:K}=this,{h:G,l:m}=QV(BigInt(Z),!0),{v0:R,v1:J,v2:C,v3:F,v4:d,v5:k,v6:I,v7:T,v8:L,v9:p,v10:Q,v11:S,v12:c,v13:M,v14:H,v15:B}=yV(nl,V,W,7,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],xZ[0],xZ[1],xZ[2],xZ[3],G,m,K,X);l[0]=R^L,l[1]=J^p,l[2]=C^Q,l[3]=F^S,l[4]=d^c,l[5]=k^M,l[6]=I^H,l[7]=T^B}compress(Z,X=0,W=!1){let V=this.flags;if(!this.chunkPos)V|=QZ.CHUNK_START;if(this.chunkPos===15||W)V|=QZ.CHUNK_END;if(!W)this.pos=this.blockLen;if(this.b2Compress(this.chunksDone,V,Z,X),this.chunkPos+=1,this.chunkPos===16||W){let l=this.state;this.state=this.IV.slice();for(let K,G=this.chunksDone+1;W||!(G&1);G>>=1){if(!(K=this.stack.pop()))break;this.buffer32.set(K,0),this.buffer32.set(l,8),this.pos=this.blockLen,this.b2Compress(0,this.flags|QZ.PARENT,this.buffer32,0),l=this.state,this.state=this.IV.slice()}this.chunksDone++,this.chunkPos=0,this.stack.push(l)}this.pos=0}_cloneInto(Z){Z=super._cloneInto(Z);let{IV:X,flags:W,state:V,chunkPos:l,posOut:K,chunkOut:G,stack:m,chunksDone:R}=this;return Z.state.set(V.slice()),Z.stack=m.map((J)=>Uint32Array.from(J)),Z.IV.set(X),Z.flags=W,Z.chunkPos=l,Z.chunksDone=R,Z.posOut=K,Z.chunkOut=G,Z.enableXOF=this.enableXOF,Z.bufferOut32.set(this.bufferOut32),Z}destroy(){this.destroyed=!0,kX(this.state,this.buffer32,this.IV,this.bufferOut32),kX(...this.stack)}b2CompressOut(){let{state:Z,pos:X,flags:W,buffer32:V,bufferOut32:l}=this,{h:K,l:G}=QV(BigInt(this.chunkOut++));lZ(V);let{v0:m,v1:R,v2:J,v3:C,v4:F,v5:d,v6:k,v7:I,v8:T,v9:L,v10:p,v11:Q,v12:S,v13:c,v14:M,v15:H}=yV(nl,0,V,7,Z[0],Z[1],Z[2],Z[3],Z[4],Z[5],Z[6],Z[7],xZ[0],xZ[1],xZ[2],xZ[3],G,K,X,W);l[0]=m^T,l[1]=R^L,l[2]=J^p,l[3]=C^Q,l[4]=F^S,l[5]=d^c,l[6]=k^M,l[7]=I^H,l[8]=Z[0]^T,l[9]=Z[1]^L,l[10]=Z[2]^p,l[11]=Z[3]^Q,l[12]=Z[4]^S,l[13]=Z[5]^c,l[14]=Z[6]^M,l[15]=Z[7]^H,lZ(V),lZ(l),this.posOut=0}finish(){if(this.finished)return;this.finished=!0,kX(this.buffer.subarray(this.pos));let Z=this.flags|QZ.ROOT;if(this.stack.length)Z|=QZ.PARENT,lZ(this.buffer32),this.compress(this.buffer32,0,!0),lZ(this.buffer32),this.chunksDone=0,this.pos=this.blockLen;else Z|=(!this.chunkPos?QZ.CHUNK_START:0)|QZ.CHUNK_END;this.flags=Z,this.b2CompressOut()}writeInto(Z){UX(this,!1),qZ(Z),this.finish();let{blockLen:X,bufferOut:W}=this;for(let V=0,l=Z.length;V<l;){if(this.posOut>=X)this.b2CompressOut();let K=Math.min(X-this.posOut,l-V);Z.set(W.subarray(this.posOut,this.posOut+K),V),this.posOut+=K,V+=K}return Z}xofInto(Z){if(!this.enableXOF)throw Error("XOF is not possible after digest call");return this.writeInto(Z)}xof(Z){return hX(Z),this.xofInto(new Uint8Array(Z))}digestInto(Z){if(JW(Z,this),this.finished)throw Error("digest() was already called");return this.enableXOF=!1,this.writeInto(Z),this.destroy(),Z}digest(){return this.digestInto(new Uint8Array(this.outputLen))}}var _l=ol((Z)=>new SV(Z));var DK=32,v5=Symbol("X25519Sk");function al(Z){if(Z.byteLength!==DK)return Y(10);return b(Z)}var w=(1n<<255n)-19n,AK=121665n,sl=new Uint8Array(32);sl[0]=9;function rl(Z){let X=0n;for(let W=Z.length-1;W>=0;W--)X=X<<8n|BigInt(Z[W]);return X}function vK(Z){let X=new Uint8Array(32),W=(Z%w+w)%w;for(let V=0;V<32;V++)X[V]=Number(W&0xffn),W>>=8n;return X}function $K(Z){let X=Z.slice();return X[31]&=127,rl(X)}function oK(Z){let X=Z.slice();return X[0]&=248,X[31]&=127,X[31]|=64,X}function FW(Z,X,W){let V=-Z,l=(X^W)&V;return[X^l,W^l]}function fK(Z){let X=w-2n,W=(Z%w+w)%w,V=1n;while(X>0n){if(X&1n)V=V*W%w;W=W*W%w,X>>=1n}return V}function qK(Z,X){let W=oK(Z),V=$K(X),l=1n,K=0n,G=V,m=1n,R=0n,J=rl(W);for(let C=254;C>=0;C--){let F=J>>BigInt(C)&1n;R^=F,[l,G]=FW(R,l,G),[K,m]=FW(R,K,m),R=F;let d=(l+K)%w,k=d*d%w,I=(l-K+w)%w,T=I*I%w,L=(k-T+w)%w,p=(G+m)%w,S=(G-m+w)%w*d%w,c=p*I%w,M=(S+c)%w,H=(S-c+w)%w;G=M*M%w,m=V*H*H%w,l=k*T%w,K=L*(k+AK*L)%w}return[l,G]=FW(R,l,G),[K,m]=FW(R,K,m),W.fill(0),vK(l*fK(K)%w)}function tl(Z){return qK(Z,sl)}var zV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function el(Z){let X=new Uint8Array(zV.length+32);return X.set(zV),X.set(Z.subarray(0,32),zV.length),X}var NV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]);function Z0(Z){let X=new Uint8Array(NV.length+32);return X.set(NV),X.set(Z.subarray(0,32),NV.length),X}function X0(Z){return typeof Z==="string"?new TextEncoder().encode(Z):Z}function gZ(Z){let X=new ArrayBuffer(Z.byteLength);return new Uint8Array(X).set(Z),X}class nZ{verifyKeys=new Map;async genRandomBytes(Z){return HX(Z)}async gen256BitSecureRandomSeed(){return HX(32)}async encryptXSalsa20Poly1305Combined(Z,X){let W=HX(24),l=LV(X,W).encrypt(Z);return new Uint8Array([...W,...l])}async decryptXSalsa20Poly1305Combined(Z,X){let W=Z.slice(0,24),V=Z.slice(24);return LV(X,W).decrypt(V)}async deriveEd25519KeyPair(Z){let X=Z,W=el(X),V=gZ(W),l;try{let J=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!0,["sign"]);l=await globalThis.crypto.subtle.exportKey("jwk",J)}finally{W.fill(0),new Uint8Array(V).fill(0)}if(typeof l.x!=="string")throw Error("Ed25519 JWK missing x");let K=l.x;l.d=void 0;let G=await globalThis.crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:K},{name:"Ed25519"},!0,["verify"]),m=new Uint8Array(await globalThis.crypto.subtle.exportKey("raw",G));this.verifyKeys.set(YZ(m),G);let R=new Uint8Array(64);return R.set(X,0),R.set(m,32),{keyType:"ed25519",privateKey:R,publicKey:m}}async importSignKey(Z){let X=Z.subarray(0,32),W=el(X),V=gZ(W);try{return await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!1,["sign"])}finally{W.fill(0),new Uint8Array(V).fill(0)}}async importVerifyKey(Z){let X=YZ(Z),W=this.verifyKeys.get(X);if(W)return W;let V=await globalThis.crypto.subtle.importKey("raw",gZ(Z),{name:"Ed25519"},!1,["verify"]);return this.verifyKeys.set(X,V),V}async signEd25519(Z,X){let W=X0(Z),V=await this.importSignKey(X),l=await globalThis.crypto.subtle.sign({name:"Ed25519"},V,gZ(W));return new Uint8Array(l)}async checkSigEd25519(Z,X,W){let V=X0(X);try{let l=await this.importVerifyKey(W);return await globalThis.crypto.subtle.verify({name:"Ed25519"},l,gZ(Z),gZ(V))}catch{return!1}}async blake3(Z){return _l(Z)}async genX25519(){let Z=await HX(32);Z[0]&=248,Z[31]&=127,Z[31]|=64;let[X,W]=al(Z);if(W!==0||X===void 0)throw Z.fill(0),Error("X25519 scalar brand failed");let V=tl(X),l=Z0(X),K=gZ(l);try{let G=await globalThis.crypto.subtle.importKey("pkcs8",K,{name:"X25519"},!0,["deriveBits"]),m=await globalThis.crypto.subtle.exportKey("jwk",G);if(typeof m.x!=="string")throw Error("X25519 JWK missing x");let R=jW(m.x);if(m.d=void 0,!n(R,V))throw Error("X25519 WebCrypto pub != RFC 7748");return{priv:X,pub:V}}catch(G){throw X.fill(0),G}finally{l.fill(0),new Uint8Array(K).fill(0)}}async x25519Shared(Z,X){let W=Z0(Z),V=gZ(W);try{let l=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"X25519"},!1,["deriveBits"]),K=await globalThis.crypto.subtle.importKey("raw",gZ(X),{name:"X25519"},!1,[]),G=await globalThis.crypto.subtle.deriveBits({name:"X25519",public:K},l,256);return new Uint8Array(G)}finally{W.fill(0),new Uint8Array(V).fill(0)}}}var nK=new nZ,TX=nK;import{useEffect as hW,useState as DV}from"react";class MV{db;constructor(Z){this.db=Z}async enq(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(CZ,"readwrite"),V=W.objectStore(CZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=`${G.host}:${G.seq}`;V.put(G,m)}})}async deq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(CZ,"readwrite"),l=V.objectStore(CZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=`${Z}:${m}`;l.delete(R)}})}async list(){let X=this.db.transaction(CZ,"readonly").objectStore(CZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async count(){let X=this.db.transaction(CZ,"readonly").objectStore(CZ);return new Promise((W,V)=>{let l=X.count();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(CZ,"readwrite"),X=Z.objectStore(CZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}function W0(Z){return{label:Z.label,handle:new URL(Z.handle),idx:Z.idx,lastSeq:Z.lastSeq||0,clockOffset:Z.clockOffset,subscription:Z.subscription}}function _K(Z,X){let W={...Z};if(X.setLastSeq!==void 0)W.lastSeq=X.setLastSeq;else if(X.lastSeq!==void 0){let V=W.lastSeq||0;if(X.lastSeq>V)W.lastSeq=X.lastSeq}return delete W.numBags,delete W.numDupes,W}class xV{db;constructor(Z){this.db=Z}async add(Z){let X=await this.get(Z.label),W=X!==void 0&&X.handle.href===Z.handle.href&&(X.idx??0)===(Z.idx??0);return this.put({...Z,lastSeq:W?X.lastSeq:0,clockOffset:W?X.clockOffset:void 0,subscription:W?X.subscription:void 0})}async put(Z){let X={...Z,handle:Z.handle.toString(),lastSeq:Z.lastSeq??0},W=this.db.transaction(KZ,"readwrite"),V=W.objectStore(KZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error),V.put(X)})}async touch(Z,X){return this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.db.transaction(KZ,"readwrite"),V=W.objectStore(KZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);let G=V.get(Z);G.onsuccess=()=>{let m=G.result;if(!m)return;V.put(_K(m,X))}})}async get(Z){let W=this.db.transaction(KZ,"readonly").objectStore(KZ);return new Promise((V,l)=>{let K=W.get(Z);K.onsuccess=()=>{let G=K.result;if(!G)V(void 0);else V(W0(G))},K.onerror=()=>l(K.error)})}async set(Z,X){let W=await this.get(Z);if(!W)return 13;try{return await this.put({...W,...X}),0}catch{return 18}}async del(Z){let X=this.db.transaction(KZ,"readwrite"),W=X.objectStore(KZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}async list(){let X=this.db.transaction(KZ,"readonly").objectStore(KZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>{let K=l.result;W(K.map(W0))},l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(KZ,"readwrite"),X=Z.objectStore(KZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}class gV{crypto;db;constructor(Z,X){this.crypto=X;this.db=Z}async add(Z){let X=this.db.transaction($,"readwrite"),W=X.objectStore($);return new Promise((V)=>{if(Z.length===0){V([]);return}let l=Array(Z.length).fill(0);X.oncomplete=()=>V(l),X.onerror=()=>{for(let K=0;K<l.length;K++)l[K]=18;V(l)};for(let K=0;K<Z.length;K++){let{key:G,data:m}=Z[K],R=g(G),J=W.put(m,R);J.onerror=(C)=>{C.preventDefault(),l[K]=18}}})}async del(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction($,"readwrite"),V=W.objectStore($);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=g(G);V.delete(m)}})}async get(Z){let W=this.db.transaction($,"readonly").objectStore($);return new Promise((V,l)=>{let K=g(Z),G=W.get(K);G.onsuccess=async()=>{let m=G.result;if(m)V(await jZ(Z,m,this.crypto));else V(void 0)},G.onerror=()=>l(G.error)})}async has(Z){return await this.get(Z)!==void 0}async list(Z){let X=Z?.apld,W=Z?.body!==!1,l=this.db.transaction($,"readonly").objectStore($);return new Promise((K,G)=>{let m=[],R=X===void 0?l.openCursor():l.index(OX).openCursor(IDBKeyRange.only(X));R.onsuccess=(J)=>{let C=J.target.result;if(C){let F=X===void 0?C.key:C.primaryKey,d=C.value;m.push({hash:e(F),data:d}),C.continue()}else Promise.all(m.map(({hash:F,data:d})=>jZ(F,d,this.crypto,{body:W}))).then(K).catch(G)},R.onerror=()=>G(R.error)})}async count(Z){let W=this.db.transaction($,"readonly").objectStore($);return new Promise((V,l)=>{let K=Z===void 0?W.count():W.index(OX).count(IDBKeyRange.only(Z));K.onsuccess=()=>V(K.result),K.onerror=()=>l(K.error)})}async listKeys(){let X=this.db.transaction($,"readonly").objectStore($);return new Promise((W,V)=>{let l=[],K=X.openKeyCursor();K.onsuccess=(G)=>{let m=G.target.result;if(m)l.push(e(m.key)),m.continue();else W(l)},K.onerror=()=>V(K.error)})}async last(Z){let W=this.db.transaction($,"readonly").objectStore($);return new Promise((V,l)=>{let K,G=W.openCursor();G.onsuccess=async(m)=>{let R=m.target.result;if(R){let{key:J,value:C}=R;if(n(Z,C.eid)){if(!K||(C.ctr??0)>(K.data.ctr??0)||(C.ctr??0)===(K.data.ctr??0)&&(C.off??0)>(K.data.off??0))K={key:J,data:C}}R.continue()}else if(K){let J=e(K.key);V(await jZ(J,K.data,this.crypto))}else V(void 0)},G.onerror=()=>l(G.error)})}async markApplied(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction($,"readwrite"),V=W.objectStore($);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=g(G),R=V.get(m);R.onsuccess=()=>{let J=R.result;if(!J)return;oZ(J,BZ),V.put(J,m)},R.onerror=(J)=>{J.preventDefault()}}})}async markFailed(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction($,"readwrite"),V=W.objectStore($);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let{key:G,err:m}of X){let R=g(G),J=V.get(R);J.onsuccess=()=>{let C=J.result;if(!C)return;oZ(C,LZ,m),V.put(C,R)},J.onerror=(C)=>{C.preventDefault()}}})}async wipe(){let Z=this.db.transaction($,"readwrite"),X=Z.objectStore($);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var _Z={encode(Z,X){let W=Z.writeVarString(X.handle);if(W!==0)return W;let V=Z.writeVarString(X.label);if(V!==0)return V;return Z.writeVarInt(X.idx??0)},decode(Z){let[X,W]=Z.readVarString();if(W!==0)return Y(W);let[V,l]=Z.readVarString();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);return b({handle:X,label:V,idx:K})}};var bW=1,HV={encode(Z,X){if(X.v!==bW)return 10;let[,W]=VZ(X.masterSeed);if(W!==0)return W;let V=Z.writeVarInt(X.v);if(V!==0)return V;Z.writeBytes(X.masterSeed);let l=Z.writeVarInt(X.hosts.length);if(l!==0)return l;for(let K of X.hosts){let G=Z.writeStruct(_Z,K);if(G!==0)return G}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X!==bW)return Y(14);let[V,l]=Z.readBytes(kZ);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=VZ(V);if(G!==0)return Y(G);if(K===void 0)return Y(14);let[m,R]=Z.readVarInt();if(R!==0)return Y(R);if(m===void 0||m<0)return Y(10);let J=[];for(let C=0;C<m;C++){let[F,d]=Z.readStruct(_Z);if(d!==0)return Y(d);if(F===void 0)return Y(14);J.push(F)}return b({v:bW,masterSeed:K,hosts:J})}};function V0(Z,X){let[W,V]=VZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(10);let[l,K]=VZ(W.slice());if(K!==0)return Y(K);if(l===void 0)return Y(10);return b({v:bW,masterSeed:l,hosts:X.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))})}var dW={encode(Z,X){let[,W]=VZ(X.masterSeed);if(W!==0)return W;Z.writeBytes(X.masterSeed);let V=Z.writeVarInt(X.hosts.length);if(V!==0)return V;for(let l of X.hosts){let K=Z.writeStruct(_Z,l);if(K!==0)return K}return 0},decode(Z){let[X,W]=Z.readBytes(kZ);if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=VZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);if(K===void 0||K<0)return Y(10);let m=[];for(let R=0;R<K;R++){let[J,C]=Z.readStruct(_Z);if(C!==0)return Y(C);if(J===void 0)return Y(14);m.push(J)}return b({masterSeed:V,hosts:m})}};var aK=new TextEncoder().encode("diplomatic.qrpair.v1"),iX=32,sK=iX+24+16,rK=32,BF=Symbol("DHKEReq"),jF=Symbol("DHKEResp");function hV(Z){if(Z.byteLength!==iX)return Y(10);return b(Z)}function UV(Z){if(Z.byteLength<sK)return Y(10);return b(Z)}var kW=new nZ;async function PV(Z,X,W,V){let l;try{l=await kW.x25519Shared(Z,X)}catch{return Y(29)}try{if(l.byteLength!==iX||l.every((m)=>m===0))return Y(10);let K=TZ(l,aK),G=TZ(K,TZ(W,V));try{let m=await kW.blake3(G);return b(m.slice(0,rK))}finally{K.fill(0),G.fill(0)}}finally{l.fill(0)}}class EX{#Z;#X;constructor(Z,X){this.#Z=Z,this.#X=X}static async create(){let Z;try{let X=await kW.genX25519();Z=X.priv;let[W,V]=hV(X.pub);if(V!==0)return Y(V);if(W===void 0)return Y(10);let l=new EX(Z,W);return Z=void 0,b(l)}catch{return Y(29)}finally{Z?.fill(0)}}wipe(){this.#Z.fill(0)}get dhkeReq(){let[Z,X]=hV(this.#X.slice());if(Z===void 0)throw Error(`dhkeReq ${X}`);return Z}async finish(Z){let X=Z.subarray(0,iX),W=Z.subarray(iX),[V,l]=await PV(this.#Z,X,this.#X,X);if(l!==0)return Y(l);if(V===void 0)return Y(12);let K;try{try{K=await kW.decryptXSalsa20Poly1305Combined(W,V)}catch{return Y(20)}let G=new O(K),[m,R]=G.readStruct(dW);if(R!==0)return Y(R);if(m===void 0)return Y(14);try{let[J,C]=ZZ.fromBytes(m.masterSeed);if(C!==0)return Y(C);if(J===void 0)return Y(12);return this.wipe(),b({enclave:J,hosts:m.hosts.map((F)=>({...F}))})}finally{m.masterSeed.fill(0)}}finally{V.fill(0),K?.fill(0)}}}function HZ(Z){let X=new Uint8Array(Z);if(Z>0)crypto.getRandomValues(X);return X}var uZ=32,l0=-7,K0=-8,G0=-257,BX=[{type:"public-key",alg:l0},{type:"public-key",alg:K0},{type:"public-key",alg:G0}];function IW(Z){return Z.trim().toLowerCase().replace(/\.$/,"")||"localhost"}function hZ(Z){let X=new Uint8Array(Z.byteLength);return X.set(Z),X.buffer}function m0(Z){if(Z instanceof ArrayBuffer)return new Uint8Array(Z).slice();return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength).slice()}function wZ(Z){if(Z?.rpId!==void 0)return b(Z.rpId);if(typeof location>"u")return Y(9);return b(IW(location.hostname))}function DZ(){if(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")return 24;return 0}function AZ(Z){if(Z===null||Z.type!=="public-key"||!("rawId"in Z)||typeof Z.getClientExtensionResults!=="function")return Y(27);return b(Z)}async function jX(Z){if(typeof PublicKeyCredential>"u")return!1;let X=PublicKeyCredential.getClientCapabilities;if(typeof X!=="function")return!0;let W=await X.call(PublicKeyCredential);if(Z in W)return W[Z]===!0;return!0}function Y0(){return jX("extension:largeBlob")}async function TW(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-seed",K={residentKey:"required",requireResidentKey:!0,userVerification:"required"};if(Z?.authenticatorAttachment!==void 0)K.authenticatorAttachment=Z.authenticatorAttachment;let G={largeBlob:{support:"required"}},m;try{m=await navigator.credentials.create({publicKey:{challenge:HZ(uZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:HZ(16),name:l,displayName:l},pubKeyCredParams:BX,authenticatorSelection:K,extensions:G}})}catch{return Y(24)}let[R,J]=AZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);if(R.getClientExtensionResults().largeBlob?.supported!==!0)return Y(24);return b(new Uint8Array(R.rawId))}async function uX(Z,X,W){let V=DZ();if(V!==0)return V;let[l,K]=wZ(W);if(K!==0)return K;if(l===void 0)return 9;let G={largeBlob:{write:hZ(X)}},m;try{m=await navigator.credentials.get({publicKey:{challenge:HZ(uZ),rpId:l,allowCredentials:[{type:"public-key",id:hZ(Z)}],userVerification:"required",extensions:G}})}catch{return 24}let[R,J]=AZ(m);if(J!==0)return J;if(R===void 0)return 27;if(R.getClientExtensionResults().largeBlob?.written!==!0)return 24;return 0}async function LW(Z,X){let W=DZ();if(W!==0)return Y(W);let[V,l]=wZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(9);let K={largeBlob:{read:!0}},G;try{let d={challenge:HZ(uZ),rpId:V,userVerification:"required",extensions:K};if(Z!==void 0)d.allowCredentials=[{type:"public-key",id:hZ(Z)}];G=await navigator.credentials.get({publicKey:d})}catch{return Y(24)}let[m,R]=AZ(G);if(R!==0)return Y(R);if(m===void 0)return Y(27);let C=m.getClientExtensionResults().largeBlob;if(C===void 0||C.blob===void 0)return Y(7);let F=m0(C.blob);if(F.byteLength===0)return Y(7);return b({blob:F,credId:new Uint8Array(m.rawId)})}var cW=new TextEncoder().encode("diplomatic.prf.v1"),OV=32;async function tK(){return jX("extension:prf")}async function R0(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-prf",K={residentKey:"required",requireResidentKey:!0,userVerification:"required"};if(Z?.authenticatorAttachment!==void 0)K.authenticatorAttachment=Z.authenticatorAttachment;let G=Z?.salt!==void 0?hZ(Z.salt):void 0,m=G===void 0?{}:{eval:{first:G}},R;try{R=await navigator.credentials.create({publicKey:{challenge:HZ(uZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:HZ(16),name:l,displayName:l},pubKeyCredParams:BX,authenticatorSelection:K,extensions:{prf:m}}})}catch{return Y(24)}let[J,C]=AZ(R);if(C!==0)return Y(C);if(J===void 0)return Y(27);let F=J.getClientExtensionResults();return b({credId:new Uint8Array(J.rawId),prfEnabled:F.prf?.enabled===!0})}async function iV(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.salt??cW,K=hZ(l),G={challenge:HZ(uZ),rpId:W,userVerification:"required",extensions:{prf:{eval:{first:K}}}};if(Z?.credId!==void 0)G.allowCredentials=[{type:"public-key",id:hZ(Z.credId)}];let m;try{m=await navigator.credentials.get({publicKey:G})}catch{return Y(24)}let[R,J]=AZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);let C=R.getClientExtensionResults().prf?.results;if(C?.first===void 0)return Y(7);let F=C.first,d=F instanceof ArrayBuffer?new Uint8Array(F):new Uint8Array(F.buffer,F.byteOffset,F.byteLength),k=d.byteLength>=OV?d.slice(0,OV):d;if(k.byteLength!==OV)return Y(27);return b({prf:k,credId:new Uint8Array(R.rawId)})}var QW="dmFyIEEwPTY0O3ZhciBVWj0zMixfMD04O3ZhciBDJD0zMjt2YXIgUlo9MzAwMDAsSFo9NTEyLEQ7KCh3KT0+e3dbdy5TdWNjZXNzPTBdPSJTdWNjZXNzIjt3W3cuSW52YWxpZFNpZ25hdHVyZT0zXT0iSW52YWxpZFNpZ25hdHVyZSI7d1t3LkNsb2NrT3V0T2ZTeW5jPTRdPSJDbG9ja091dE9mU3luYyI7d1t3LlVzZXJOb3RSZWdpc3RlcmVkPTVdPSJVc2VyTm90UmVnaXN0ZXJlZCI7d1t3LlNlcnZlck1pc2NvbmZpZ3VyZWQ9Nl09IlNlcnZlck1pc2NvbmZpZ3VyZWQiO3dbdy5NaXNzaW5nQm9keT03XT0iTWlzc2luZ0JvZHkiO3dbdy5FeHRyYUJvZHlDb250ZW50PThdPSJFeHRyYUJvZHlDb250ZW50Ijt3W3cuTWlzc2luZ1BhcmFtPTldPSJNaXNzaW5nUGFyYW0iO3dbdy5JbnZhbGlkUGFyYW09MTBdPSJJbnZhbGlkUGFyYW0iO3dbdy5JbnZhbGlkUmVxdWVzdD0xMV09IkludmFsaWRSZXF1ZXN0Ijt3W3cuSW50ZXJuYWxFcnJvcj0xMl09IkludGVybmFsRXJyb3IiO3dbdy5Ob3RGb3VuZD0xM109Ik5vdEZvdW5kIjt3W3cuSW52YWxpZE1lc3NhZ2U9MTRdPSJJbnZhbGlkTWVzc2FnZSI7d1t3Lk5vQ2hhbmdlPTE1XT0iTm9DaGFuZ2UiO3dbdy5EYXRhYmFzZUNsb3NlZD0xNl09IkRhdGFiYXNlQ2xvc2VkIjt3W3cuU3RvcmFnZUVycm9yPTE3XT0iU3RvcmFnZUVycm9yIjt3W3cuRGF0YWJhc2VFcnJvcj0xOF09IkRhdGFiYXNlRXJyb3IiO3dbdy5IYXNoTWlzbWF0Y2g9MTldPSJIYXNoTWlzbWF0Y2giO3dbdy5EZWNyeXB0aW9uRXJyb3I9MjBdPSJEZWNyeXB0aW9uRXJyb3IiO3dbdy5Ob3RJbXBsZW1lbnRlZD0yMV09Ik5vdEltcGxlbWVudGVkIjt3W3cuTWlzc2luZ1NlZWQ9MjJdPSJNaXNzaW5nU2VlZCI7d1t3Lk91dE9mQm91bmRzPTIzXT0iT3V0T2ZCb3VuZHMiO3dbdy5Ib3N0RXJyb3I9MjRdPSJIb3N0RXJyb3IiO3dbdy5Db21tdW5pY2F0aW9uRXJyb3I9MjVdPSJDb21tdW5pY2F0aW9uRXJyb3IiO3dbdy5WYXJMaW1pdEV4Y2VlZGVkPTI2XT0iVmFyTGltaXRFeGNlZWRlZCI7d1t3LkludmFsaWRSZXNwb25zZT0yN109IkludmFsaWRSZXNwb25zZSI7d1t3LkNvbm5lY3Rpb25DbG9zZWQ9MjhdPSJDb25uZWN0aW9uQ2xvc2VkIjt3W3cuQ3J5cHRvRXJyb3I9MjldPSJDcnlwdG9FcnJvciJ9KShEfHw9e30pO2Z1bmN0aW9uIHFaKCQpe2lmKCEkfHx0eXBlb2YgJCE9PSJvYmplY3QiKXJldHVybiExO2lmKCEoIm9wImluICQpfHwhKCJpZCJpbiAkKSlyZXR1cm4hMTtyZXR1cm4gdHlwZW9mICQub3A9PT0ic3RyaW5nIiYmdHlwZW9mICQuaWQ9PT0ibnVtYmVyIn1mdW5jdGlvbiBNWigkKXtsZXQgSj0kLmxlbmd0aCxaPTAsUT0wO3doaWxlKFE8Sil7bGV0IFk9JC5jaGFyQ29kZUF0KFErKyk7aWYoKFkmNDI5NDk2NzE2OCk9PT0wKXtaKys7Y29udGludWV9ZWxzZSBpZigoWSY0Mjk0OTY1MjQ4KT09PTApWis9MjtlbHNle2lmKFk+PTU1Mjk2JiZZPD01NjMxOSl7aWYoUTxKKXtsZXQgVj0kLmNoYXJDb2RlQXQoUSk7aWYoKFYmNjQ1MTIpPT09NTYzMjApKytRLFk9KChZJjEwMjMpPDwxMCkrKFYmMTAyMykrNjU1MzZ9fWlmKChZJjQyOTQ5MDE3NjApPT09MClaKz0zO2Vsc2UgWis9NH19cmV0dXJuIFp9ZnVuY3Rpb24gJFkoJCxKLFope2xldCBRPSQubGVuZ3RoLFk9WixWPTA7d2hpbGUoVjxRKXtsZXQgWD0kLmNoYXJDb2RlQXQoVisrKTtpZigoWCY0Mjk0OTY3MTY4KT09PTApe0pbWSsrXT1YO2NvbnRpbnVlfWVsc2UgaWYoKFgmNDI5NDk2NTI0OCk9PT0wKUpbWSsrXT1YPj42JjMxfDE5MjtlbHNle2lmKFg+PTU1Mjk2JiZYPD01NjMxOSl7aWYoVjxRKXtsZXQgVz0kLmNoYXJDb2RlQXQoVik7aWYoKFcmNjQ1MTIpPT09NTYzMjApKytWLFg9KChYJjEwMjMpPDwxMCkrKFcmMTAyMykrNjU1MzZ9fWlmKChYJjQyOTQ5MDE3NjApPT09MClKW1krK109WD4+MTImMTV8MjI0LEpbWSsrXT1YPj42JjYzfDEyODtlbHNlIEpbWSsrXT1YPj4xOCY3fDI0MCxKW1krK109WD4+MTImNjN8MTI4LEpbWSsrXT1YPj42JjYzfDEyOH1KW1krK109WCY2M3wxMjh9fXZhciBKWT1uZXcgVGV4dEVuY29kZXIsWlk9NTA7ZnVuY3Rpb24gUVkoJCxKLFope0pZLmVuY29kZUludG8oJCxKLnN1YmFycmF5KFopKX1mdW5jdGlvbiBJWigkLEosWil7aWYoJC5sZW5ndGg+WlkpUVkoJCxKLFopO2Vsc2UgJFkoJCxKLFopfXZhciBZWT00MDk2O2Z1bmN0aW9uIFlKKCQsSixaKXtsZXQgUT1KLFk9UStaLFY9W10sWD0iIjt3aGlsZShRPFkpe2xldCBXPSRbUSsrXTtpZigoVyYxMjgpPT09MClWLnB1c2goVyk7ZWxzZSBpZigoVyYyMjQpPT09MTkyKXtsZXQgej0kW1ErK10mNjM7Vi5wdXNoKChXJjMxKTw8Nnx6KX1lbHNlIGlmKChXJjI0MCk9PT0yMjQpe2xldCB6PSRbUSsrXSY2MyxLPSRbUSsrXSY2MztWLnB1c2goKFcmMzEpPDwxMnx6PDw2fEspfWVsc2UgaWYoKFcmMjQ4KT09PTI0MCl7bGV0IHo9JFtRKytdJjYzLEs9JFtRKytdJjYzLEY9JFtRKytdJjYzLE49KFcmNyk8PDE4fHo8PDEyfEs8PDZ8RjtpZihOPjY1NTM1KU4tPTY1NTM2LFYucHVzaChOPj4+MTAmMTAyM3w1NTI5NiksTj01NjMyMHxOJjEwMjM7Vi5wdXNoKE4pfWVsc2UgVi5wdXNoKFcpO2lmKFYubGVuZ3RoPj1ZWSlYKz1TdHJpbmcuZnJvbUNoYXJDb2RlKC4uLlYpLFYubGVuZ3RoPTB9aWYoVi5sZW5ndGg+MClYKz1TdHJpbmcuZnJvbUNoYXJDb2RlKC4uLlYpO3JldHVybiBYfXZhciBWWT1uZXcgVGV4dERlY29kZXIsWFk9MjAwO2Z1bmN0aW9uIFdZKCQsSixaKXtsZXQgUT0kLnN1YmFycmF5KEosSitaKTtyZXR1cm4gVlkuZGVjb2RlKFEpfWZ1bmN0aW9uIENaKCQsSixaKXtpZihaPlhZKXJldHVybiBXWSgkLEosWik7ZWxzZSByZXR1cm4gWUooJCxKLFopfWNsYXNzIHIwe3R5cGU7ZGF0YTtjb25zdHJ1Y3RvcigkLEope3RoaXMudHlwZT0kLHRoaXMuZGF0YT1KfX1jbGFzcyBlIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IoJCl7c3VwZXIoJCk7bGV0IEo9T2JqZWN0LmNyZWF0ZShlLnByb3RvdHlwZSk7T2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsSiksT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIm5hbWUiLHtjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMSx2YWx1ZTplLm5hbWV9KX19dmFyIG8wPTQyOTQ5NjcyOTU7ZnVuY3Rpb24gUFooJCxKLFope2xldCBRPVovNDI5NDk2NzI5NixZPVo7JC5zZXRVaW50MzIoSixRKSwkLnNldFVpbnQzMihKKzQsWSl9ZnVuY3Rpb24gUCQoJCxKLFope2xldCBRPU1hdGguZmxvb3IoWi80Mjk0OTY3Mjk2KSxZPVo7JC5zZXRVaW50MzIoSixRKSwkLnNldFVpbnQzMihKKzQsWSl9ZnVuY3Rpb24gdyQoJCxKKXtsZXQgWj0kLmdldEludDMyKEopLFE9JC5nZXRVaW50MzIoSis0KTtyZXR1cm4gWio0Mjk0OTY3Mjk2K1F9ZnVuY3Rpb24gd1ooJCxKKXtsZXQgWj0kLmdldFVpbnQzMihKKSxRPSQuZ2V0VWludDMyKEorNCk7cmV0dXJuIFoqNDI5NDk2NzI5NitRfXZhciBHWT0tMSx6WT00Mjk0OTY3Mjk1LEtZPTE3MTc5ODY5MTgzO2Z1bmN0aW9uIEZZKHtzZWM6JCxuc2VjOkp9KXtpZigkPj0wJiZKPj0wJiYkPD1LWSlpZihKPT09MCYmJDw9elkpe2xldCBaPW5ldyBVaW50OEFycmF5KDQpO3JldHVybiBuZXcgRGF0YVZpZXcoWi5idWZmZXIpLnNldFVpbnQzMigwLCQpLFp9ZWxzZXtsZXQgWj0kLzQyOTQ5NjcyOTYsUT0kJjQyOTQ5NjcyOTUsWT1uZXcgVWludDhBcnJheSg4KSxWPW5ldyBEYXRhVmlldyhZLmJ1ZmZlcik7cmV0dXJuIFYuc2V0VWludDMyKDAsSjw8MnxaJjMpLFYuc2V0VWludDMyKDQsUSksWX1lbHNle2xldCBaPW5ldyBVaW50OEFycmF5KDEyKSxRPW5ldyBEYXRhVmlldyhaLmJ1ZmZlcik7cmV0dXJuIFEuc2V0VWludDMyKDAsSiksUCQoUSw0LCQpLFp9fWZ1bmN0aW9uIE5ZKCQpe2xldCBKPSQuZ2V0VGltZSgpLFo9TWF0aC5mbG9vcihKLzEwMDApLFE9KEotWioxMDAwKSoxZTYsWT1NYXRoLmZsb29yKFEvMWU5KTtyZXR1cm57c2VjOlorWSxuc2VjOlEtWSoxZTl9fWZ1bmN0aW9uIE9ZKCQpe2lmKCQgaW5zdGFuY2VvZiBEYXRlKXtsZXQgSj1OWSgkKTtyZXR1cm4gRlkoSil9ZWxzZSByZXR1cm4gbnVsbH1mdW5jdGlvbiBVWSgkKXtsZXQgSj1uZXcgRGF0YVZpZXcoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LCQuYnl0ZUxlbmd0aCk7c3dpdGNoKCQuYnl0ZUxlbmd0aCl7Y2FzZSA0OntsZXQgWj1KLmdldFVpbnQzMigwKSxRPTA7cmV0dXJue3NlYzpaLG5zZWM6MH19Y2FzZSA4OntsZXQgWj1KLmdldFVpbnQzMigwKSxRPUouZ2V0VWludDMyKDQpLFk9KFomMykqNDI5NDk2NzI5NitRLFY9Wj4+PjI7cmV0dXJue3NlYzpZLG5zZWM6Vn19Y2FzZSAxMjp7bGV0IFo9dyQoSiw0KSxRPUouZ2V0VWludDMyKDApO3JldHVybntzZWM6Wixuc2VjOlF9fWRlZmF1bHQ6dGhyb3cgbmV3IGUoYFVucmVjb2duaXplZCBkYXRhIHNpemUgZm9yIHRpbWVzdGFtcCAoZXhwZWN0ZWQgNCwgOCwgb3IgMTIpOiAkeyQubGVuZ3RofWApfX1mdW5jdGlvbiBSWSgkKXtsZXQgSj1VWSgkKTtyZXR1cm4gbmV3IERhdGUoSi5zZWMqMTAwMCtKLm5zZWMvMWU2KX12YXIgVFo9e3R5cGU6R1ksZW5jb2RlOk9ZLGRlY29kZTpSWX07Y2xhc3MgYTB7c3RhdGljIGRlZmF1bHRDb2RlYz1uZXcgYTA7X19icmFuZDtidWlsdEluRW5jb2RlcnM9W107YnVpbHRJbkRlY29kZXJzPVtdO2VuY29kZXJzPVtdO2RlY29kZXJzPVtdO2NvbnN0cnVjdG9yKCl7dGhpcy5yZWdpc3RlcihUWil9cmVnaXN0ZXIoe3R5cGU6JCxlbmNvZGU6SixkZWNvZGU6Wn0pe2lmKCQ+PTApdGhpcy5lbmNvZGVyc1skXT1KLHRoaXMuZGVjb2RlcnNbJF09WjtlbHNle2xldCBRPS0xLSQ7dGhpcy5idWlsdEluRW5jb2RlcnNbUV09Six0aGlzLmJ1aWx0SW5EZWNvZGVyc1tRXT1afX10cnlUb0VuY29kZSgkLEope2ZvcihsZXQgWj0wO1o8dGhpcy5idWlsdEluRW5jb2RlcnMubGVuZ3RoO1orKyl7bGV0IFE9dGhpcy5idWlsdEluRW5jb2RlcnNbWl07aWYoUSE9bnVsbCl7bGV0IFk9USgkLEopO2lmKFkhPW51bGwpe2xldCBWPS0xLVo7cmV0dXJuIG5ldyByMChWLFkpfX19Zm9yKGxldCBaPTA7Wjx0aGlzLmVuY29kZXJzLmxlbmd0aDtaKyspe2xldCBRPXRoaXMuZW5jb2RlcnNbWl07aWYoUSE9bnVsbCl7bGV0IFk9USgkLEopO2lmKFkhPW51bGwpcmV0dXJuIG5ldyByMChaLFkpfX1pZigkIGluc3RhbmNlb2YgcjApcmV0dXJuICQ7cmV0dXJuIG51bGx9ZGVjb2RlKCQsSixaKXtsZXQgUT1KPDA/dGhpcy5idWlsdEluRGVjb2RlcnNbLTEtSl06dGhpcy5kZWNvZGVyc1tKXTtpZihRKXJldHVybiBRKCQsSixaKTtlbHNlIHJldHVybiBuZXcgcjAoSiwkKX19ZnVuY3Rpb24gSFkoJCl7cmV0dXJuICQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcnx8dHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyPCJ1IiYmJCBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyfWZ1bmN0aW9uIFckKCQpe2lmKCQgaW5zdGFuY2VvZiBVaW50OEFycmF5KXJldHVybiAkO2Vsc2UgaWYoQXJyYXlCdWZmZXIuaXNWaWV3KCQpKXJldHVybiBuZXcgVWludDhBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKTtlbHNlIGlmKEhZKCQpKXJldHVybiBuZXcgVWludDhBcnJheSgkKTtlbHNlIHJldHVybiBVaW50OEFycmF5LmZyb20oJCl9dmFyIHFZPTEwMCxNWT0yMDQ4O2NsYXNzIFQke2V4dGVuc2lvbkNvZGVjO2NvbnRleHQ7dXNlQmlnSW50NjQ7bWF4RGVwdGg7aW5pdGlhbEJ1ZmZlclNpemU7c29ydEtleXM7Zm9yY2VGbG9hdDMyO2lnbm9yZVVuZGVmaW5lZDtmb3JjZUludGVnZXJUb0Zsb2F0O3Bvczt2aWV3O2J5dGVzO2VudGVyZWQ9ITE7Y29uc3RydWN0b3IoJCl7dGhpcy5leHRlbnNpb25Db2RlYz0kPy5leHRlbnNpb25Db2RlYz8/YTAuZGVmYXVsdENvZGVjLHRoaXMuY29udGV4dD0kPy5jb250ZXh0LHRoaXMudXNlQmlnSW50NjQ9JD8udXNlQmlnSW50NjQ/PyExLHRoaXMubWF4RGVwdGg9JD8ubWF4RGVwdGg/P3FZLHRoaXMuaW5pdGlhbEJ1ZmZlclNpemU9JD8uaW5pdGlhbEJ1ZmZlclNpemU/P01ZLHRoaXMuc29ydEtleXM9JD8uc29ydEtleXM/PyExLHRoaXMuZm9yY2VGbG9hdDMyPSQ/LmZvcmNlRmxvYXQzMj8/ITEsdGhpcy5pZ25vcmVVbmRlZmluZWQ9JD8uaWdub3JlVW5kZWZpbmVkPz8hMSx0aGlzLmZvcmNlSW50ZWdlclRvRmxvYXQ9JD8uZm9yY2VJbnRlZ2VyVG9GbG9hdD8/ITEsdGhpcy5wb3M9MCx0aGlzLnZpZXc9bmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcih0aGlzLmluaXRpYWxCdWZmZXJTaXplKSksdGhpcy5ieXRlcz1uZXcgVWludDhBcnJheSh0aGlzLnZpZXcuYnVmZmVyKX1jbG9uZSgpe3JldHVybiBuZXcgVCQoe2V4dGVuc2lvbkNvZGVjOnRoaXMuZXh0ZW5zaW9uQ29kZWMsY29udGV4dDp0aGlzLmNvbnRleHQsdXNlQmlnSW50NjQ6dGhpcy51c2VCaWdJbnQ2NCxtYXhEZXB0aDp0aGlzLm1heERlcHRoLGluaXRpYWxCdWZmZXJTaXplOnRoaXMuaW5pdGlhbEJ1ZmZlclNpemUsc29ydEtleXM6dGhpcy5zb3J0S2V5cyxmb3JjZUZsb2F0MzI6dGhpcy5mb3JjZUZsb2F0MzIsaWdub3JlVW5kZWZpbmVkOnRoaXMuaWdub3JlVW5kZWZpbmVkLGZvcmNlSW50ZWdlclRvRmxvYXQ6dGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0fSl9cmVpbml0aWFsaXplU3RhdGUoKXt0aGlzLnBvcz0wfWVuY29kZVNoYXJlZFJlZigkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmNvZGVTaGFyZWRSZWYoJCk7dHJ5e3JldHVybiB0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuZG9FbmNvZGUoJCwxKSx0aGlzLmJ5dGVzLnN1YmFycmF5KDAsdGhpcy5wb3MpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1lbmNvZGUoJCl7aWYodGhpcy5lbnRlcmVkKXJldHVybiB0aGlzLmNsb25lKCkuZW5jb2RlKCQpO3RyeXtyZXR1cm4gdGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLmRvRW5jb2RlKCQsMSksdGhpcy5ieXRlcy5zbGljZSgwLHRoaXMucG9zKX1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19ZG9FbmNvZGUoJCxKKXtpZihKPnRoaXMubWF4RGVwdGgpdGhyb3cgRXJyb3IoYFRvbyBkZWVwIG9iamVjdHMgaW4gZGVwdGggJHtKfWApO2lmKCQ9PW51bGwpdGhpcy5lbmNvZGVOaWwoKTtlbHNlIGlmKHR5cGVvZiAkPT09ImJvb2xlYW4iKXRoaXMuZW5jb2RlQm9vbGVhbigkKTtlbHNlIGlmKHR5cGVvZiAkPT09Im51bWJlciIpaWYoIXRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdCl0aGlzLmVuY29kZU51bWJlcigkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIGlmKHR5cGVvZiAkPT09InN0cmluZyIpdGhpcy5lbmNvZGVTdHJpbmcoJCk7ZWxzZSBpZih0aGlzLnVzZUJpZ0ludDY0JiZ0eXBlb2YgJD09PSJiaWdpbnQiKXRoaXMuZW5jb2RlQmlnSW50NjQoJCk7ZWxzZSB0aGlzLmVuY29kZU9iamVjdCgkLEopfWVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKCQpe2xldCBKPXRoaXMucG9zKyQ7aWYodGhpcy52aWV3LmJ5dGVMZW5ndGg8Sil0aGlzLnJlc2l6ZUJ1ZmZlcihKKjIpfXJlc2l6ZUJ1ZmZlcigkKXtsZXQgSj1uZXcgQXJyYXlCdWZmZXIoJCksWj1uZXcgVWludDhBcnJheShKKSxRPW5ldyBEYXRhVmlldyhKKTtaLnNldCh0aGlzLmJ5dGVzKSx0aGlzLnZpZXc9USx0aGlzLmJ5dGVzPVp9ZW5jb2RlTmlsKCl7dGhpcy53cml0ZVU4KDE5Mil9ZW5jb2RlQm9vbGVhbigkKXtpZigkPT09ITEpdGhpcy53cml0ZVU4KDE5NCk7ZWxzZSB0aGlzLndyaXRlVTgoMTk1KX1lbmNvZGVOdW1iZXIoJCl7aWYoIXRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdCYmTnVtYmVyLmlzU2FmZUludGVnZXIoJCkpaWYoJD49MClpZigkPDEyOCl0aGlzLndyaXRlVTgoJCk7ZWxzZSBpZigkPDI1Nil0aGlzLndyaXRlVTgoMjA0KSx0aGlzLndyaXRlVTgoJCk7ZWxzZSBpZigkPDY1NTM2KXRoaXMud3JpdGVVOCgyMDUpLHRoaXMud3JpdGVVMTYoJCk7ZWxzZSBpZigkPDQyOTQ5NjcyOTYpdGhpcy53cml0ZVU4KDIwNiksdGhpcy53cml0ZVUzMigkKTtlbHNlIGlmKCF0aGlzLnVzZUJpZ0ludDY0KXRoaXMud3JpdGVVOCgyMDcpLHRoaXMud3JpdGVVNjQoJCk7ZWxzZSB0aGlzLmVuY29kZU51bWJlckFzRmxvYXQoJCk7ZWxzZSBpZigkPj0tMzIpdGhpcy53cml0ZVU4KDIyNHwkKzMyKTtlbHNlIGlmKCQ+PS0xMjgpdGhpcy53cml0ZVU4KDIwOCksdGhpcy53cml0ZUk4KCQpO2Vsc2UgaWYoJD49LTMyNzY4KXRoaXMud3JpdGVVOCgyMDkpLHRoaXMud3JpdGVJMTYoJCk7ZWxzZSBpZigkPj0tMjE0NzQ4MzY0OCl0aGlzLndyaXRlVTgoMjEwKSx0aGlzLndyaXRlSTMyKCQpO2Vsc2UgaWYoIXRoaXMudXNlQmlnSW50NjQpdGhpcy53cml0ZVU4KDIxMSksdGhpcy53cml0ZUk2NCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKX1lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpe2lmKHRoaXMuZm9yY2VGbG9hdDMyKXRoaXMud3JpdGVVOCgyMDIpLHRoaXMud3JpdGVGMzIoJCk7ZWxzZSB0aGlzLndyaXRlVTgoMjAzKSx0aGlzLndyaXRlRjY0KCQpfWVuY29kZUJpZ0ludDY0KCQpe2lmKCQ+PUJpZ0ludCgwKSl0aGlzLndyaXRlVTgoMjA3KSx0aGlzLndyaXRlQmlnVWludDY0KCQpO2Vsc2UgdGhpcy53cml0ZVU4KDIxMSksdGhpcy53cml0ZUJpZ0ludDY0KCQpfXdyaXRlU3RyaW5nSGVhZGVyKCQpe2lmKCQ8MzIpdGhpcy53cml0ZVU4KDE2MCskKTtlbHNlIGlmKCQ8MjU2KXRoaXMud3JpdGVVOCgyMTcpLHRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8NjU1MzYpdGhpcy53cml0ZVU4KDIxOCksdGhpcy53cml0ZVUxNigkKTtlbHNlIGlmKCQ8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjE5KSx0aGlzLndyaXRlVTMyKCQpO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsb25nIHN0cmluZzogJHskfSBieXRlcyBpbiBVVEYtOGApfWVuY29kZVN0cmluZygkKXtsZXQgWj1NWigkKTt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDUrWiksdGhpcy53cml0ZVN0cmluZ0hlYWRlcihaKSxJWigkLHRoaXMuYnl0ZXMsdGhpcy5wb3MpLHRoaXMucG9zKz1afWVuY29kZU9iamVjdCgkLEope2xldCBaPXRoaXMuZXh0ZW5zaW9uQ29kZWMudHJ5VG9FbmNvZGUoJCx0aGlzLmNvbnRleHQpO2lmKFohPW51bGwpdGhpcy5lbmNvZGVFeHRlbnNpb24oWik7ZWxzZSBpZihBcnJheS5pc0FycmF5KCQpKXRoaXMuZW5jb2RlQXJyYXkoJCxKKTtlbHNlIGlmKEFycmF5QnVmZmVyLmlzVmlldygkKSl0aGlzLmVuY29kZUJpbmFyeSgkKTtlbHNlIGlmKHR5cGVvZiAkPT09Im9iamVjdCIpdGhpcy5lbmNvZGVNYXAoJCxKKTtlbHNlIHRocm93IEVycm9yKGBVbnJlY29nbml6ZWQgb2JqZWN0OiAke09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuYXBwbHkoJCl9YCl9ZW5jb2RlQmluYXJ5KCQpe2xldCBKPSQuYnl0ZUxlbmd0aDtpZihKPDI1Nil0aGlzLndyaXRlVTgoMTk2KSx0aGlzLndyaXRlVTgoSik7ZWxzZSBpZihKPDY1NTM2KXRoaXMud3JpdGVVOCgxOTcpLHRoaXMud3JpdGVVMTYoSik7ZWxzZSBpZihKPDQyOTQ5NjcyOTYpdGhpcy53cml0ZVU4KDE5OCksdGhpcy53cml0ZVUzMihKKTtlbHNlIHRocm93IEVycm9yKGBUb28gbGFyZ2UgYmluYXJ5OiAke0p9YCk7bGV0IFo9VyQoJCk7dGhpcy53cml0ZVU4YShaKX1lbmNvZGVBcnJheSgkLEope2xldCBaPSQubGVuZ3RoO2lmKFo8MTYpdGhpcy53cml0ZVU4KDE0NCtaKTtlbHNlIGlmKFo8NjU1MzYpdGhpcy53cml0ZVU4KDIyMCksdGhpcy53cml0ZVUxNihaKTtlbHNlIGlmKFo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjIxKSx0aGlzLndyaXRlVTMyKFopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBhcnJheTogJHtafWApO2ZvcihsZXQgUSBvZiAkKXRoaXMuZG9FbmNvZGUoUSxKKzEpfWNvdW50V2l0aG91dFVuZGVmaW5lZCgkLEope2xldCBaPTA7Zm9yKGxldCBRIG9mIEopaWYoJFtRXSE9PXZvaWQgMClaKys7cmV0dXJuIFp9ZW5jb2RlTWFwKCQsSil7bGV0IFo9T2JqZWN0LmtleXMoJCk7aWYodGhpcy5zb3J0S2V5cylaLnNvcnQoKTtsZXQgUT10aGlzLmlnbm9yZVVuZGVmaW5lZD90aGlzLmNvdW50V2l0aG91dFVuZGVmaW5lZCgkLFopOloubGVuZ3RoO2lmKFE8MTYpdGhpcy53cml0ZVU4KDEyOCtRKTtlbHNlIGlmKFE8NjU1MzYpdGhpcy53cml0ZVU4KDIyMiksdGhpcy53cml0ZVUxNihRKTtlbHNlIGlmKFE8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjIzKSx0aGlzLndyaXRlVTMyKFEpO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBtYXAgb2JqZWN0OiAke1F9YCk7Zm9yKGxldCBZIG9mIFope2xldCBWPSRbWV07aWYoISh0aGlzLmlnbm9yZVVuZGVmaW5lZCYmVj09PXZvaWQgMCkpdGhpcy5lbmNvZGVTdHJpbmcoWSksdGhpcy5kb0VuY29kZShWLEorMSl9fWVuY29kZUV4dGVuc2lvbigkKXtpZih0eXBlb2YgJC5kYXRhPT09ImZ1bmN0aW9uIil7bGV0IFo9JC5kYXRhKHRoaXMucG9zKzYpLFE9Wi5sZW5ndGg7aWYoUT49NDI5NDk2NzI5Nil0aHJvdyBFcnJvcihgVG9vIGxhcmdlIGV4dGVuc2lvbiBvYmplY3Q6ICR7UX1gKTt0aGlzLndyaXRlVTgoMjAxKSx0aGlzLndyaXRlVTMyKFEpLHRoaXMud3JpdGVJOCgkLnR5cGUpLHRoaXMud3JpdGVVOGEoWik7cmV0dXJufWxldCBKPSQuZGF0YS5sZW5ndGg7aWYoSj09PTEpdGhpcy53cml0ZVU4KDIxMik7ZWxzZSBpZihKPT09Mil0aGlzLndyaXRlVTgoMjEzKTtlbHNlIGlmKEo9PT00KXRoaXMud3JpdGVVOCgyMTQpO2Vsc2UgaWYoSj09PTgpdGhpcy53cml0ZVU4KDIxNSk7ZWxzZSBpZihKPT09MTYpdGhpcy53cml0ZVU4KDIxNik7ZWxzZSBpZihKPDI1Nil0aGlzLndyaXRlVTgoMTk5KSx0aGlzLndyaXRlVTgoSik7ZWxzZSBpZihKPDY1NTM2KXRoaXMud3JpdGVVOCgyMDApLHRoaXMud3JpdGVVMTYoSik7ZWxzZSBpZihKPDQyOTQ5NjcyOTYpdGhpcy53cml0ZVU4KDIwMSksdGhpcy53cml0ZVUzMihKKTtlbHNlIHRocm93IEVycm9yKGBUb28gbGFyZ2UgZXh0ZW5zaW9uIG9iamVjdDogJHtKfWApO3RoaXMud3JpdGVJOCgkLnR5cGUpLHRoaXMud3JpdGVVOGEoJC5kYXRhKX13cml0ZVU4KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMSksdGhpcy52aWV3LnNldFVpbnQ4KHRoaXMucG9zLCQpLHRoaXMucG9zKyt9d3JpdGVVOGEoJCl7bGV0IEo9JC5sZW5ndGg7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZShKKSx0aGlzLmJ5dGVzLnNldCgkLHRoaXMucG9zKSx0aGlzLnBvcys9Sn13cml0ZUk4KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMSksdGhpcy52aWV3LnNldEludDgodGhpcy5wb3MsJCksdGhpcy5wb3MrK313cml0ZVUxNigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDIpLHRoaXMudmlldy5zZXRVaW50MTYodGhpcy5wb3MsJCksdGhpcy5wb3MrPTJ9d3JpdGVJMTYoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgyKSx0aGlzLnZpZXcuc2V0SW50MTYodGhpcy5wb3MsJCksdGhpcy5wb3MrPTJ9d3JpdGVVMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0VWludDMyKHRoaXMucG9zLCQpLHRoaXMucG9zKz00fXdyaXRlSTMyKCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNCksdGhpcy52aWV3LnNldEludDMyKHRoaXMucG9zLCQpLHRoaXMucG9zKz00fXdyaXRlRjMyKCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNCksdGhpcy52aWV3LnNldEZsb2F0MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVGNjQoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg4KSx0aGlzLnZpZXcuc2V0RmxvYXQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZVU2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLFBaKHRoaXMudmlldyx0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUk2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLFAkKHRoaXMudmlldyx0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUJpZ1VpbnQ2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5wb3MsJCksdGhpcy5wb3MrPTh9d3JpdGVCaWdJbnQ2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRCaWdJbnQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH19ZnVuY3Rpb24gRTAoJCxKKXtyZXR1cm4gbmV3IFQkKEopLmVuY29kZVNoYXJlZFJlZigkKX1mdW5jdGlvbiBqJCgkKXtyZXR1cm5gJHskPDA/Ii0iOiIifTB4JHtNYXRoLmFicygkKS50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpfWB9dmFyIElZPTE2LENZPTE2O2NsYXNzIFZKe2hpdD0wO21pc3M9MDtjYWNoZXM7bWF4S2V5TGVuZ3RoO21heExlbmd0aFBlcktleTtjb25zdHJ1Y3RvcigkPUlZLEo9Q1kpe3RoaXMubWF4S2V5TGVuZ3RoPSQsdGhpcy5tYXhMZW5ndGhQZXJLZXk9Six0aGlzLmNhY2hlcz1bXTtmb3IobGV0IFo9MDtaPHRoaXMubWF4S2V5TGVuZ3RoO1orKyl0aGlzLmNhY2hlcy5wdXNoKFtdKX1jYW5CZUNhY2hlZCgkKXtyZXR1cm4gJD4wJiYkPD10aGlzLm1heEtleUxlbmd0aH1maW5kKCQsSixaKXtsZXQgUT10aGlzLmNhY2hlc1taLTFdOyQ6Zm9yKGxldCBZIG9mIFEpe2xldCBWPVkuYnl0ZXM7Zm9yKGxldCBYPTA7WDxaO1grKylpZihWW1hdIT09JFtKK1hdKWNvbnRpbnVlICQ7cmV0dXJuIFkuc3RyfXJldHVybiBudWxsfXN0b3JlKCQsSil7bGV0IFo9dGhpcy5jYWNoZXNbJC5sZW5ndGgtMV0sUT17Ynl0ZXM6JCxzdHI6Sn07aWYoWi5sZW5ndGg+PXRoaXMubWF4TGVuZ3RoUGVyS2V5KVpbTWF0aC5yYW5kb20oKSpaLmxlbmd0aHwwXT1RO2Vsc2UgWi5wdXNoKFEpfWRlY29kZSgkLEosWil7bGV0IFE9dGhpcy5maW5kKCQsSixaKTtpZihRIT1udWxsKXJldHVybiB0aGlzLmhpdCsrLFE7dGhpcy5taXNzKys7bGV0IFk9WUooJCxKLFopLFY9VWludDhBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCgkLEosSitaKTtyZXR1cm4gdGhpcy5zdG9yZShWLFkpLFl9fXZhciBYSj0iYXJyYXkiLHokPSJtYXBfa2V5IixEWj0ibWFwX3ZhbHVlIixQWT0oJCk9PntpZih0eXBlb2YgJD09PSJzdHJpbmcifHx0eXBlb2YgJD09PSJudW1iZXIiKXJldHVybiAkO3Rocm93IG5ldyBlKCJUaGUgdHlwZSBvZiBrZXkgbXVzdCBiZSBzdHJpbmcgb3IgbnVtYmVyIGJ1dCAiK3R5cGVvZiAkKX07Y2xhc3MgQVp7c3RhY2s9W107c3RhY2tIZWFkUG9zaXRpb249LTE7Z2V0IGxlbmd0aCgpe3JldHVybiB0aGlzLnN0YWNrSGVhZFBvc2l0aW9uKzF9dG9wKCl7cmV0dXJuIHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl19cHVzaEFycmF5U3RhdGUoJCl7bGV0IEo9dGhpcy5nZXRVbmluaXRpYWxpemVkU3RhdGVGcm9tUG9vbCgpO0oudHlwZT1YSixKLnBvc2l0aW9uPTAsSi5zaXplPSQsSi5hcnJheT1BcnJheSgkKX1wdXNoTWFwU3RhdGUoJCl7bGV0IEo9dGhpcy5nZXRVbmluaXRpYWxpemVkU3RhdGVGcm9tUG9vbCgpO0oudHlwZT16JCxKLnJlYWRDb3VudD0wLEouc2l6ZT0kLEoubWFwPXt9fWdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCl7aWYodGhpcy5zdGFja0hlYWRQb3NpdGlvbisrLHRoaXMuc3RhY2tIZWFkUG9zaXRpb249PT10aGlzLnN0YWNrLmxlbmd0aCl7bGV0ICQ9e3R5cGU6dm9pZCAwLHNpemU6MCxhcnJheTp2b2lkIDAscG9zaXRpb246MCxyZWFkQ291bnQ6MCxtYXA6dm9pZCAwLGtleTpudWxsfTt0aGlzLnN0YWNrLnB1c2goJCl9cmV0dXJuIHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl19cmVsZWFzZSgkKXtpZih0aGlzLnN0YWNrW3RoaXMuc3RhY2tIZWFkUG9zaXRpb25dIT09JCl0aHJvdyBFcnJvcigiSW52YWxpZCBzdGFjayBzdGF0ZS4gUmVsZWFzZWQgc3RhdGUgaXMgbm90IG9uIHRvcCBvZiB0aGUgc3RhY2suIik7aWYoJC50eXBlPT09WEope2xldCBaPSQ7Wi5zaXplPTAsWi5hcnJheT12b2lkIDAsWi5wb3NpdGlvbj0wLFoudHlwZT12b2lkIDB9aWYoJC50eXBlPT09eiR8fCQudHlwZT09PURaKXtsZXQgWj0kO1ouc2l6ZT0wLFoubWFwPXZvaWQgMCxaLnJlYWRDb3VudD0wLFoudHlwZT12b2lkIDB9dGhpcy5zdGFja0hlYWRQb3NpdGlvbi0tfXJlc2V0KCl7dGhpcy5zdGFjay5sZW5ndGg9MCx0aGlzLnN0YWNrSGVhZFBvc2l0aW9uPS0xfX12YXIgRyQ9LTEsV0o9bmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcigwKSksd1k9bmV3IFVpbnQ4QXJyYXkoV0ouYnVmZmVyKTt0cnl7V0ouZ2V0SW50OCgwKX1jYXRjaCgkKXtpZighKCQgaW5zdGFuY2VvZiBSYW5nZUVycm9yKSl0aHJvdyBFcnJvcigiVGhpcyBtb2R1bGUgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgY3VycmVudCBKYXZhU2NyaXB0IGVuZ2luZSBiZWNhdXNlIERhdGFWaWV3IGRvZXMgbm90IHRocm93IFJhbmdlRXJyb3Igb24gb3V0LW9mLWJvdW5kcyBhY2Nlc3MiKX12YXIgalo9UmFuZ2VFcnJvcigiSW5zdWZmaWNpZW50IGRhdGEiKSxUWT1uZXcgVko7Y2xhc3MgRCR7ZXh0ZW5zaW9uQ29kZWM7Y29udGV4dDt1c2VCaWdJbnQ2NDtyYXdTdHJpbmdzO21heFN0ckxlbmd0aDttYXhCaW5MZW5ndGg7bWF4QXJyYXlMZW5ndGg7bWF4TWFwTGVuZ3RoO21heEV4dExlbmd0aDtrZXlEZWNvZGVyO21hcEtleUNvbnZlcnRlcjt0b3RhbFBvcz0wO3Bvcz0wO3ZpZXc9V0o7Ynl0ZXM9d1k7aGVhZEJ5dGU9RyQ7c3RhY2s9bmV3IEFaO2VudGVyZWQ9ITE7Y29uc3RydWN0b3IoJCl7dGhpcy5leHRlbnNpb25Db2RlYz0kPy5leHRlbnNpb25Db2RlYz8/YTAuZGVmYXVsdENvZGVjLHRoaXMuY29udGV4dD0kPy5jb250ZXh0LHRoaXMudXNlQmlnSW50NjQ9JD8udXNlQmlnSW50NjQ/PyExLHRoaXMucmF3U3RyaW5ncz0kPy5yYXdTdHJpbmdzPz8hMSx0aGlzLm1heFN0ckxlbmd0aD0kPy5tYXhTdHJMZW5ndGg/P28wLHRoaXMubWF4QmluTGVuZ3RoPSQ/Lm1heEJpbkxlbmd0aD8/bzAsdGhpcy5tYXhBcnJheUxlbmd0aD0kPy5tYXhBcnJheUxlbmd0aD8/bzAsdGhpcy5tYXhNYXBMZW5ndGg9JD8ubWF4TWFwTGVuZ3RoPz9vMCx0aGlzLm1heEV4dExlbmd0aD0kPy5tYXhFeHRMZW5ndGg/P28wLHRoaXMua2V5RGVjb2Rlcj0kPy5rZXlEZWNvZGVyIT09dm9pZCAwPyQua2V5RGVjb2RlcjpUWSx0aGlzLm1hcEtleUNvbnZlcnRlcj0kPy5tYXBLZXlDb252ZXJ0ZXI/P1BZfWNsb25lKCl7cmV0dXJuIG5ldyBEJCh7ZXh0ZW5zaW9uQ29kZWM6dGhpcy5leHRlbnNpb25Db2RlYyxjb250ZXh0OnRoaXMuY29udGV4dCx1c2VCaWdJbnQ2NDp0aGlzLnVzZUJpZ0ludDY0LHJhd1N0cmluZ3M6dGhpcy5yYXdTdHJpbmdzLG1heFN0ckxlbmd0aDp0aGlzLm1heFN0ckxlbmd0aCxtYXhCaW5MZW5ndGg6dGhpcy5tYXhCaW5MZW5ndGgsbWF4QXJyYXlMZW5ndGg6dGhpcy5tYXhBcnJheUxlbmd0aCxtYXhNYXBMZW5ndGg6dGhpcy5tYXhNYXBMZW5ndGgsbWF4RXh0TGVuZ3RoOnRoaXMubWF4RXh0TGVuZ3RoLGtleURlY29kZXI6dGhpcy5rZXlEZWNvZGVyfSl9cmVpbml0aWFsaXplU3RhdGUoKXt0aGlzLnRvdGFsUG9zPTAsdGhpcy5oZWFkQnl0ZT1HJCx0aGlzLnN0YWNrLnJlc2V0KCl9c2V0QnVmZmVyKCQpe2xldCBKPVckKCQpO3RoaXMuYnl0ZXM9Six0aGlzLnZpZXc9bmV3IERhdGFWaWV3KEouYnVmZmVyLEouYnl0ZU9mZnNldCxKLmJ5dGVMZW5ndGgpLHRoaXMucG9zPTB9YXBwZW5kQnVmZmVyKCQpe2lmKHRoaXMuaGVhZEJ5dGU9PT1HJCYmIXRoaXMuaGFzUmVtYWluaW5nKDEpKXRoaXMuc2V0QnVmZmVyKCQpO2Vsc2V7bGV0IEo9dGhpcy5ieXRlcy5zdWJhcnJheSh0aGlzLnBvcyksWj1XJCgkKSxRPW5ldyBVaW50OEFycmF5KEoubGVuZ3RoK1oubGVuZ3RoKTtRLnNldChKKSxRLnNldChaLEoubGVuZ3RoKSx0aGlzLnNldEJ1ZmZlcihRKX19aGFzUmVtYWluaW5nKCQpe3JldHVybiB0aGlzLnZpZXcuYnl0ZUxlbmd0aC10aGlzLnBvcz49JH1jcmVhdGVFeHRyYUJ5dGVFcnJvcigkKXtsZXR7dmlldzpKLHBvczpafT10aGlzO3JldHVybiBSYW5nZUVycm9yKGBFeHRyYSAke0ouYnl0ZUxlbmd0aC1afSBvZiAke0ouYnl0ZUxlbmd0aH0gYnl0ZShzKSBmb3VuZCBhdCBidWZmZXJbJHskfV1gKX1kZWNvZGUoJCl7aWYodGhpcy5lbnRlcmVkKXJldHVybiB0aGlzLmNsb25lKCkuZGVjb2RlKCQpO3RyeXt0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuc2V0QnVmZmVyKCQpO2xldCBKPXRoaXMuZG9EZWNvZGVTeW5jKCk7aWYodGhpcy5oYXNSZW1haW5pbmcoMSkpdGhyb3cgdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnBvcyk7cmV0dXJuIEp9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fSpkZWNvZGVNdWx0aSgkKXtpZih0aGlzLmVudGVyZWQpe3lpZWxkKnRoaXMuY2xvbmUoKS5kZWNvZGVNdWx0aSgkKTtyZXR1cm59dHJ5e3RoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5zZXRCdWZmZXIoJCk7d2hpbGUodGhpcy5oYXNSZW1haW5pbmcoMSkpeWllbGQgdGhpcy5kb0RlY29kZVN5bmMoKX1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19YXN5bmMgZGVjb2RlQXN5bmMoJCl7aWYodGhpcy5lbnRlcmVkKXJldHVybiB0aGlzLmNsb25lKCkuZGVjb2RlQXN5bmMoJCk7dHJ5e3RoaXMuZW50ZXJlZD0hMDtsZXQgSj0hMSxaO2ZvciBhd2FpdChsZXQgWCBvZiAkKXtpZihKKXRocm93IHRoaXMuZW50ZXJlZD0hMSx0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMudG90YWxQb3MpO3RoaXMuYXBwZW5kQnVmZmVyKFgpO3RyeXtaPXRoaXMuZG9EZWNvZGVTeW5jKCksSj0hMH1jYXRjaChXKXtpZighKFcgaW5zdGFuY2VvZiBSYW5nZUVycm9yKSl0aHJvdyBXfXRoaXMudG90YWxQb3MrPXRoaXMucG9zfWlmKEope2lmKHRoaXMuaGFzUmVtYWluaW5nKDEpKXRocm93IHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7cmV0dXJuIFp9bGV0e2hlYWRCeXRlOlEscG9zOlksdG90YWxQb3M6Vn09dGhpczt0aHJvdyBSYW5nZUVycm9yKGBJbnN1ZmZpY2llbnQgZGF0YSBpbiBwYXJzaW5nICR7aiQoUSl9IGF0ICR7Vn0gKCR7WX0gaW4gdGhlIGN1cnJlbnQgYnVmZmVyKWApfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kZWNvZGVBcnJheVN0cmVhbSgkKXtyZXR1cm4gdGhpcy5kZWNvZGVNdWx0aUFzeW5jKCQsITApfWRlY29kZVN0cmVhbSgkKXtyZXR1cm4gdGhpcy5kZWNvZGVNdWx0aUFzeW5jKCQsITEpfWFzeW5jKmRlY29kZU11bHRpQXN5bmMoJCxKKXtpZih0aGlzLmVudGVyZWQpe3lpZWxkKnRoaXMuY2xvbmUoKS5kZWNvZGVNdWx0aUFzeW5jKCQsSik7cmV0dXJufXRyeXt0aGlzLmVudGVyZWQ9ITA7bGV0IFo9SixRPS0xO2ZvciBhd2FpdChsZXQgWSBvZiAkKXtpZihKJiZRPT09MCl0aHJvdyB0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMudG90YWxQb3MpO2lmKHRoaXMuYXBwZW5kQnVmZmVyKFkpLFopUT10aGlzLnJlYWRBcnJheVNpemUoKSxaPSExLHRoaXMuY29tcGxldGUoKTt0cnl7d2hpbGUoITApaWYoeWllbGQgdGhpcy5kb0RlY29kZVN5bmMoKSwtLVE9PT0wKWJyZWFrfWNhdGNoKFYpe2lmKCEoViBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IFZ9dGhpcy50b3RhbFBvcys9dGhpcy5wb3N9fWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kb0RlY29kZVN5bmMoKXskOndoaWxlKCEwKXtsZXQgJD10aGlzLnJlYWRIZWFkQnl0ZSgpLEo7aWYoJD49MjI0KUo9JC0yNTY7ZWxzZSBpZigkPDE5MilpZigkPDEyOClKPSQ7ZWxzZSBpZigkPDE0NCl7bGV0IFE9JC0xMjg7aWYoUSE9PTApe3RoaXMucHVzaE1hcFN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj17fX1lbHNlIGlmKCQ8MTYwKXtsZXQgUT0kLTE0NDtpZihRIT09MCl7dGhpcy5wdXNoQXJyYXlTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIEo9W119ZWxzZXtsZXQgUT0kLTE2MDtKPXRoaXMuZGVjb2RlU3RyaW5nKFEsMCl9ZWxzZSBpZigkPT09MTkyKUo9bnVsbDtlbHNlIGlmKCQ9PT0xOTQpSj0hMTtlbHNlIGlmKCQ9PT0xOTUpSj0hMDtlbHNlIGlmKCQ9PT0yMDIpSj10aGlzLnJlYWRGMzIoKTtlbHNlIGlmKCQ9PT0yMDMpSj10aGlzLnJlYWRGNjQoKTtlbHNlIGlmKCQ9PT0yMDQpSj10aGlzLnJlYWRVOCgpO2Vsc2UgaWYoJD09PTIwNSlKPXRoaXMucmVhZFUxNigpO2Vsc2UgaWYoJD09PTIwNilKPXRoaXMucmVhZFUzMigpO2Vsc2UgaWYoJD09PTIwNylpZih0aGlzLnVzZUJpZ0ludDY0KUo9dGhpcy5yZWFkVTY0QXNCaWdJbnQoKTtlbHNlIEo9dGhpcy5yZWFkVTY0KCk7ZWxzZSBpZigkPT09MjA4KUo9dGhpcy5yZWFkSTgoKTtlbHNlIGlmKCQ9PT0yMDkpSj10aGlzLnJlYWRJMTYoKTtlbHNlIGlmKCQ9PT0yMTApSj10aGlzLnJlYWRJMzIoKTtlbHNlIGlmKCQ9PT0yMTEpaWYodGhpcy51c2VCaWdJbnQ2NClKPXRoaXMucmVhZEk2NEFzQmlnSW50KCk7ZWxzZSBKPXRoaXMucmVhZEk2NCgpO2Vsc2UgaWYoJD09PTIxNyl7bGV0IFE9dGhpcy5sb29rVTgoKTtKPXRoaXMuZGVjb2RlU3RyaW5nKFEsMSl9ZWxzZSBpZigkPT09MjE4KXtsZXQgUT10aGlzLmxvb2tVMTYoKTtKPXRoaXMuZGVjb2RlU3RyaW5nKFEsMil9ZWxzZSBpZigkPT09MjE5KXtsZXQgUT10aGlzLmxvb2tVMzIoKTtKPXRoaXMuZGVjb2RlU3RyaW5nKFEsNCl9ZWxzZSBpZigkPT09MjIwKXtsZXQgUT10aGlzLnJlYWRVMTYoKTtpZihRIT09MCl7dGhpcy5wdXNoQXJyYXlTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIEo9W119ZWxzZSBpZigkPT09MjIxKXtsZXQgUT10aGlzLnJlYWRVMzIoKTtpZihRIT09MCl7dGhpcy5wdXNoQXJyYXlTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIEo9W119ZWxzZSBpZigkPT09MjIyKXtsZXQgUT10aGlzLnJlYWRVMTYoKTtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBKPXt9fWVsc2UgaWYoJD09PTIyMyl7bGV0IFE9dGhpcy5yZWFkVTMyKCk7aWYoUSE9PTApe3RoaXMucHVzaE1hcFN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj17fX1lbHNlIGlmKCQ9PT0xOTYpe2xldCBRPXRoaXMubG9va1U4KCk7Sj10aGlzLmRlY29kZUJpbmFyeShRLDEpfWVsc2UgaWYoJD09PTE5Nyl7bGV0IFE9dGhpcy5sb29rVTE2KCk7Sj10aGlzLmRlY29kZUJpbmFyeShRLDIpfWVsc2UgaWYoJD09PTE5OCl7bGV0IFE9dGhpcy5sb29rVTMyKCk7Sj10aGlzLmRlY29kZUJpbmFyeShRLDQpfWVsc2UgaWYoJD09PTIxMilKPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDEsMCk7ZWxzZSBpZigkPT09MjEzKUo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMiwwKTtlbHNlIGlmKCQ9PT0yMTQpSj10aGlzLmRlY29kZUV4dGVuc2lvbig0LDApO2Vsc2UgaWYoJD09PTIxNSlKPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDgsMCk7ZWxzZSBpZigkPT09MjE2KUo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMTYsMCk7ZWxzZSBpZigkPT09MTk5KXtsZXQgUT10aGlzLmxvb2tVOCgpO0o9dGhpcy5kZWNvZGVFeHRlbnNpb24oUSwxKX1lbHNlIGlmKCQ9PT0yMDApe2xldCBRPXRoaXMubG9va1UxNigpO0o9dGhpcy5kZWNvZGVFeHRlbnNpb24oUSwyKX1lbHNlIGlmKCQ9PT0yMDEpe2xldCBRPXRoaXMubG9va1UzMigpO0o9dGhpcy5kZWNvZGVFeHRlbnNpb24oUSw0KX1lbHNlIHRocm93IG5ldyBlKGBVbnJlY29nbml6ZWQgdHlwZSBieXRlOiAke2okKCQpfWApO3RoaXMuY29tcGxldGUoKTtsZXQgWj10aGlzLnN0YWNrO3doaWxlKFoubGVuZ3RoPjApe2xldCBRPVoudG9wKCk7aWYoUS50eXBlPT09WEopaWYoUS5hcnJheVtRLnBvc2l0aW9uXT1KLFEucG9zaXRpb24rKyxRLnBvc2l0aW9uPT09US5zaXplKUo9US5hcnJheSxaLnJlbGVhc2UoUSk7ZWxzZSBjb250aW51ZSAkO2Vsc2UgaWYoUS50eXBlPT09eiQpe2lmKEo9PT0iX19wcm90b19fIil0aHJvdyBuZXcgZSgiVGhlIGtleSBfX3Byb3RvX18gaXMgbm90IGFsbG93ZWQiKTtRLmtleT10aGlzLm1hcEtleUNvbnZlcnRlcihKKSxRLnR5cGU9RFo7Y29udGludWUgJH1lbHNlIGlmKFEubWFwW1Eua2V5XT1KLFEucmVhZENvdW50KyssUS5yZWFkQ291bnQ9PT1RLnNpemUpSj1RLm1hcCxaLnJlbGVhc2UoUSk7ZWxzZXtRLmtleT1udWxsLFEudHlwZT16JDtjb250aW51ZSAkfX1yZXR1cm4gSn19cmVhZEhlYWRCeXRlKCl7aWYodGhpcy5oZWFkQnl0ZT09PUckKXRoaXMuaGVhZEJ5dGU9dGhpcy5yZWFkVTgoKTtyZXR1cm4gdGhpcy5oZWFkQnl0ZX1jb21wbGV0ZSgpe3RoaXMuaGVhZEJ5dGU9RyR9cmVhZEFycmF5U2l6ZSgpe2xldCAkPXRoaXMucmVhZEhlYWRCeXRlKCk7c3dpdGNoKCQpe2Nhc2UgMjIwOnJldHVybiB0aGlzLnJlYWRVMTYoKTtjYXNlIDIyMTpyZXR1cm4gdGhpcy5yZWFkVTMyKCk7ZGVmYXVsdDppZigkPDE2MClyZXR1cm4gJC0xNDQ7ZWxzZSB0aHJvdyBuZXcgZShgVW5yZWNvZ25pemVkIGFycmF5IHR5cGUgYnl0ZTogJHtqJCgkKX1gKX19cHVzaE1hcFN0YXRlKCQpe2lmKCQ+dGhpcy5tYXhNYXBMZW5ndGgpdGhyb3cgbmV3IGUoYE1heCBsZW5ndGggZXhjZWVkZWQ6IG1hcCBsZW5ndGggKCR7JH0pID4gbWF4TWFwTGVuZ3RoTGVuZ3RoICgke3RoaXMubWF4TWFwTGVuZ3RofSlgKTt0aGlzLnN0YWNrLnB1c2hNYXBTdGF0ZSgkKX1wdXNoQXJyYXlTdGF0ZSgkKXtpZigkPnRoaXMubWF4QXJyYXlMZW5ndGgpdGhyb3cgbmV3IGUoYE1heCBsZW5ndGggZXhjZWVkZWQ6IGFycmF5IGxlbmd0aCAoJHskfSkgPiBtYXhBcnJheUxlbmd0aCAoJHt0aGlzLm1heEFycmF5TGVuZ3RofSlgKTt0aGlzLnN0YWNrLnB1c2hBcnJheVN0YXRlKCQpfWRlY29kZVN0cmluZygkLEope2lmKCF0aGlzLnJhd1N0cmluZ3N8fHRoaXMuc3RhdGVJc01hcEtleSgpKXJldHVybiB0aGlzLmRlY29kZVV0ZjhTdHJpbmcoJCxKKTtyZXR1cm4gdGhpcy5kZWNvZGVCaW5hcnkoJCxKKX1kZWNvZGVVdGY4U3RyaW5nKCQsSil7aWYoJD50aGlzLm1heFN0ckxlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogVVRGLTggYnl0ZSBsZW5ndGggKCR7JH0pID4gbWF4U3RyTGVuZ3RoICgke3RoaXMubWF4U3RyTGVuZ3RofSlgKTtpZih0aGlzLmJ5dGVzLmJ5dGVMZW5ndGg8dGhpcy5wb3MrSiskKXRocm93IGpaO2xldCBaPXRoaXMucG9zK0osUTtpZih0aGlzLnN0YXRlSXNNYXBLZXkoKSYmdGhpcy5rZXlEZWNvZGVyPy5jYW5CZUNhY2hlZCgkKSlRPXRoaXMua2V5RGVjb2Rlci5kZWNvZGUodGhpcy5ieXRlcyxaLCQpO2Vsc2UgUT1DWih0aGlzLmJ5dGVzLFosJCk7cmV0dXJuIHRoaXMucG9zKz1KKyQsUX1zdGF0ZUlzTWFwS2V5KCl7aWYodGhpcy5zdGFjay5sZW5ndGg+MClyZXR1cm4gdGhpcy5zdGFjay50b3AoKS50eXBlPT09eiQ7cmV0dXJuITF9ZGVjb2RlQmluYXJ5KCQsSil7aWYoJD50aGlzLm1heEJpbkxlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogYmluIGxlbmd0aCAoJHskfSkgPiBtYXhCaW5MZW5ndGggKCR7dGhpcy5tYXhCaW5MZW5ndGh9KWApO2lmKCF0aGlzLmhhc1JlbWFpbmluZygkK0opKXRocm93IGpaO2xldCBaPXRoaXMucG9zK0osUT10aGlzLmJ5dGVzLnN1YmFycmF5KFosWiskKTtyZXR1cm4gdGhpcy5wb3MrPUorJCxRfWRlY29kZUV4dGVuc2lvbigkLEope2lmKCQ+dGhpcy5tYXhFeHRMZW5ndGgpdGhyb3cgbmV3IGUoYE1heCBsZW5ndGggZXhjZWVkZWQ6IGV4dCBsZW5ndGggKCR7JH0pID4gbWF4RXh0TGVuZ3RoICgke3RoaXMubWF4RXh0TGVuZ3RofSlgKTtsZXQgWj10aGlzLnZpZXcuZ2V0SW50OCh0aGlzLnBvcytKKSxRPXRoaXMuZGVjb2RlQmluYXJ5KCQsSisxKTtyZXR1cm4gdGhpcy5leHRlbnNpb25Db2RlYy5kZWNvZGUoUSxaLHRoaXMuY29udGV4dCl9bG9va1U4KCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50OCh0aGlzLnBvcyl9bG9va1UxNigpe3JldHVybiB0aGlzLnZpZXcuZ2V0VWludDE2KHRoaXMucG9zKX1sb29rVTMyKCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50MzIodGhpcy5wb3MpfXJlYWRVOCgpe2xldCAkPXRoaXMudmlldy5nZXRVaW50OCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKyssJH1yZWFkSTgoKXtsZXQgJD10aGlzLnZpZXcuZ2V0SW50OCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKyssJH1yZWFkVTE2KCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQxNih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz0yLCR9cmVhZEkxNigpe2xldCAkPXRoaXMudmlldy5nZXRJbnQxNih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz0yLCR9cmVhZFUzMigpe2xldCAkPXRoaXMudmlldy5nZXRVaW50MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRJMzIoKXtsZXQgJD10aGlzLnZpZXcuZ2V0SW50MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRVNjQoKXtsZXQgJD13Wih0aGlzLnZpZXcsdGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCwkfXJlYWRJNjQoKXtsZXQgJD13JCh0aGlzLnZpZXcsdGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCwkfXJlYWRVNjRBc0JpZ0ludCgpe2xldCAkPXRoaXMudmlldy5nZXRCaWdVaW50NjQodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCwkfXJlYWRJNjRBc0JpZ0ludCgpe2xldCAkPXRoaXMudmlldy5nZXRCaWdJbnQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEYzMigpe2xldCAkPXRoaXMudmlldy5nZXRGbG9hdDMyKHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTQsJH1yZWFkRjY0KCl7bGV0ICQ9dGhpcy52aWV3LmdldEZsb2F0NjQodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCwkfX1mdW5jdGlvbiBHSigkLEope3JldHVybiBuZXcgRCQoSikuZGVjb2RlKCQpfWNsYXNzIEske2xpc3RlbmVycz1uZXcgTWFwO2FkZEV2ZW50TGlzdGVuZXIoJCxKKXtsZXQgWj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoIVopWj1uZXcgU2V0LHRoaXMubGlzdGVuZXJzLnNldCgkLFopO3JldHVybiBaLmFkZChKKSwoKT0+e3RoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigkLEopfX1yZW1vdmVFdmVudExpc3RlbmVyKCQsSil7bGV0IFo9dGhpcy5saXN0ZW5lcnMuZ2V0KCQpO2lmKFope2lmKFouZGVsZXRlKEopLFouc2l6ZT09PTApdGhpcy5saXN0ZW5lcnMuZGVsZXRlKCQpfX1lbWl0KCQsSil7bGV0IFo9dGhpcy5saXN0ZW5lcnMuZ2V0KCQpO2lmKFope2xldCBRPUFycmF5LmZyb20oWik7Zm9yKGxldCBZIG9mIFEpWShKKX19ZW1pdEFsbCgkKXtsZXQgSj1BcnJheS5mcm9tKHRoaXMubGlzdGVuZXJzLmtleXMoKSk7Zm9yKGxldCBaIG9mIEopdGhpcy5lbWl0KFosJCl9fWNsYXNzIGYwe2dldHRlcjtzdGF0aWMgZXZlbnROYW1lPSJ1cGRhdGUiO2VtaXR0ZXI7Y29uc3RydWN0b3IoJCl7dGhpcy5nZXR0ZXI9JDt0aGlzLmVtaXR0ZXI9bmV3IEskfWdldD0oKT0+dGhpcy5nZXR0ZXIoKTthc3luYyBlbWl0KCl7bGV0ICQ9YXdhaXQgdGhpcy5nZXR0ZXIoKTtxdWV1ZU1pY3JvdGFzaygoKT0+dGhpcy5lbWl0dGVyLmVtaXQoZjAuZXZlbnROYW1lLCQpKX1saXN0ZW4oJCl7cmV0dXJuIHRoaXMuZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKGYwLmV2ZW50TmFtZSwkKSwoKT0+e3RoaXMuZW1pdHRlci5yZW1vdmVFdmVudExpc3RlbmVyKGYwLmV2ZW50TmFtZSwkKX19fWZ1bmN0aW9uIE8oJCl7cmV0dXJuWyQsMF19ZnVuY3Rpb24gRygkKXtyZXR1cm5bdm9pZCAwLCRdfWZ1bmN0aW9uIGpZKCQpe2lmKCQ8MCljb25zb2xlLmluZm8oIk4iLCQpLGNvbnNvbGUudHJhY2UoKTtpZih0eXBlb2YgJCE9PSJiaWdpbnQiKSQ9QmlnSW50KCQpO2lmKCQ8MG4pcmV0dXJuIEcoMTApO2xldCBKPVtdO3doaWxlKCQ+MG4pe2xldCBaPU51bWJlcigkJjB4N2ZuKTtpZigkPj49N24sJD4wbilKLnB1c2goWnwxMjgpO2Vsc2UgSi5wdXNoKFopfWlmKEoubGVuZ3RoPT09MClyZXR1cm4gTyhuZXcgVWludDhBcnJheShbMF0pKTtpZihKLmxlbmd0aD44KXJldHVybiBHKDI2KTtyZXR1cm4gTyhuZXcgVWludDhBcnJheShKKSl9ZnVuY3Rpb24gRFkoJCxKPTApe2xldCBaPTBuLFE9MCxZPUo7d2hpbGUoITApe2lmKFk+PSQubGVuZ3RoKXJldHVybiBHKDE0KTtsZXQgVj0kW1krK107aWYoVj09PXZvaWQgMClyZXR1cm4gRygxNCk7aWYoWnw9QmlnSW50KFYmMTI3KTw8QmlnSW50KFEpLChWJjEyOCk9PT0wKXtpZihZLUo+OClyZXR1cm4gRygyNik7cmV0dXJuIE8oe3ZhbHVlOlo+MHgxZmZmZmZmZmZmZmZmZm4/WjpOdW1iZXIoWiksYnl0ZXNSZWFkOlktSn0pfWlmKFErPTcsUT49NTYpcmV0dXJuIEcoMjYpfX1jbGFzcyBte2RhdGE7cG9zPTA7Y29uc3RydWN0b3IoJCl7dGhpcy5kYXRhPSR9c3RhdGljIGFzeW5jIGZyb21SZXNwb25zZSgkKXtsZXQgSj1hd2FpdCAkLmFycmF5QnVmZmVyKCksWj1uZXcgVWludDhBcnJheShKKTtyZXR1cm4gbmV3IG0oWil9cmVhZEJpZ0ludCgpe2lmKHRoaXMucG9zKzg+dGhpcy5kYXRhLmxlbmd0aClyZXR1cm4gRyg3KTtsZXQgJD1uZXcgRGF0YVZpZXcodGhpcy5kYXRhLmJ1ZmZlcix0aGlzLmRhdGEuYnl0ZU9mZnNldCt0aGlzLnBvcykuZ2V0QmlnVWludDY0KDAsITEpO3JldHVybiB0aGlzLnBvcys9OCxPKCQpfXJlYWREYXRlKCl7bGV0WyQsSl09dGhpcy5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7cmV0dXJuIE8obmV3IERhdGUoJCkpfXJlYWRWYXJJbnQoKXtsZXRbJCxKXT1EWSh0aGlzLmRhdGEsdGhpcy5wb3MpO2lmKEohPT0wKXJldHVybiBHKEopO3RoaXMucG9zKz0kLmJ5dGVzUmVhZDtsZXQgWj0kLnZhbHVlO3JldHVybiBPKHR5cGVvZiBaPT09ImJpZ2ludCI/TnVtYmVyKFopOlopfXJlYWRWYXJTdHJpbmcoKXtsZXRbJCxKXT10aGlzLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbWixRXT10aGlzLnJlYWRCeXRlcygkKTtpZihRIT09MClyZXR1cm4gRyhRKTtsZXQgWT1uZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoWik7cmV0dXJuIE8oWSl9cmVhZEJ5dGVzKCQpe2lmKCQ8MClyZXR1cm4gRygxMCk7aWYodGhpcy5wb3MrJD50aGlzLmRhdGEubGVuZ3RoKXJldHVybiBHKDIzKTtsZXQgSj10aGlzLmRhdGEuc2xpY2UodGhpcy5wb3MsdGhpcy5wb3MrJCk7cmV0dXJuIHRoaXMucG9zKz0kLE8oSil9cmVhZFZhckJ5dGVzKCl7bGV0WyQsSl09dGhpcy5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7cmV0dXJuIHRoaXMucmVhZEJ5dGVzKCQpfXJlYWRTdHJ1Y3QoJCl7cmV0dXJuICQuZGVjb2RlKHRoaXMpfXJlYWRTdHJ1Y3RzKCQpe2xldCBKPVtdO3doaWxlKCF0aGlzLmRvbmUoKSl7bGV0W1osUV09dGhpcy5yZWFkU3RydWN0KCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO0oucHVzaChaKX1yZXR1cm4gTyhKKX1yZWFkQnl0ZXNTZXEoJCl7bGV0IEo9W107d2hpbGUoIXRoaXMuZG9uZSgpKXtsZXRbWixRXT10aGlzLnJlYWRCeXRlcygkKTtpZihRIT09MClyZXR1cm4gRyhRKTtKLnB1c2goWil9cmV0dXJuIE8oSil9ZG9uZSgpe3JldHVybiB0aGlzLnBvcz49dGhpcy5kYXRhLmxlbmd0aH1jb25zdW1lZCgpe3JldHVybiB0aGlzLnBvc319Y2xhc3MgU3twYXJ0cz1bXTt3cml0ZUJpZ0ludCgkKXtsZXQgSj1uZXcgVWludDhBcnJheSg4KTtuZXcgRGF0YVZpZXcoSi5idWZmZXIpLnNldEJpZ1VpbnQ2NCgwLCQsITEpLHRoaXMucGFydHMucHVzaChKKX13cml0ZURhdGUoJCl7bGV0IEo9JC5nZXRUaW1lKCk7cmV0dXJuIHRoaXMud3JpdGVWYXJJbnQoSil9d3JpdGVWYXJJbnQoJCl7bGV0W0osWl09alkoJCk7aWYoWiE9PTApcmV0dXJuIFo7cmV0dXJuIHRoaXMucGFydHMucHVzaChKKSwwfXdyaXRlVmFyU3RyaW5nKCQpe2xldCBKPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSxaPXRoaXMud3JpdGVWYXJJbnQoSi5sZW5ndGgpO2lmKFohPT0wKXJldHVybiBaO3JldHVybiB0aGlzLndyaXRlQnl0ZXMoSiksMH1wcmVwZW5kQnl0ZXMoJCl7dGhpcy5wYXJ0cy51bnNoaWZ0KCQuc2xpY2UoKSl9d3JpdGVCeXRlcygkKXt0aGlzLnBhcnRzLnB1c2goJC5zbGljZSgpKX13cml0ZVZhckJ5dGVzKCQpe2xldCBKPXRoaXMud3JpdGVWYXJJbnQoJC5sZW5ndGgpO2lmKEohPT0wKXJldHVybiBKO3JldHVybiB0aGlzLndyaXRlQnl0ZXMoJCksMH13cml0ZVN0cnVjdCgkLEope3JldHVybiAkLmVuY29kZSh0aGlzLEopfXdyaXRlU3RydWN0cygkLEope2ZvcihsZXQgWiBvZiBKKXtsZXQgUT10aGlzLndyaXRlU3RydWN0KCQsWik7aWYoUSE9PTApcmV0dXJuIFF9cmV0dXJuIDB9d3JpdGVCeXRlc1NlcSgkKXtmb3IobGV0IEogb2YgJCl0aGlzLndyaXRlQnl0ZXMoSil9cmVzdWx0KCl7bGV0ICQ9dGhpcy5wYXJ0cy5yZWR1Y2UoKFEsWSk9PlErWS5sZW5ndGgsMCksSj1uZXcgVWludDhBcnJheSgkKSxaPTA7Zm9yKGxldCBRIG9mIHRoaXMucGFydHMpSi5zZXQoUSxaKSxaKz1RLmxlbmd0aDtyZXR1cm4gSn13aXBlKCl7Zm9yKGxldCAkIG9mIHRoaXMucGFydHMpJC5maWxsKDApO3RoaXMucGFydHMubGVuZ3RoPTB9KnNjYW4oKXtmb3IobGV0ICQgb2YgdGhpcy5wYXJ0cyl5aWVsZCAkfX1hc3luYyBmdW5jdGlvbiB6SigkLEope2xldCBaPW5ldyBTLFE9Wi53cml0ZURhdGUoSik7aWYoUSE9PTApcmV0dXJuIEcoUSk7bGV0IFk9Wi5yZXN1bHQoKSxWPWF3YWl0ICQuc2lnbihZKTtyZXR1cm4gTyh7cHViS2V5OiQucHVibGljS2V5LHNpZzpWLHRpbWVzdGFtcDpKfSl9YXN5bmMgZnVuY3Rpb24gTDAoJCxKLFope2xldCBRPVoubm93KCkuZ2V0VGltZSgpLFk9JC50aW1lc3RhbXAuZ2V0VGltZSgpO2lmKE1hdGguYWJzKFEtWSk+UlopcmV0dXJuIDQ7bGV0IFg9bmV3IFM7WC53cml0ZURhdGUoJC50aW1lc3RhbXApO2xldCBXPVgucmVzdWx0KCk7aWYoIWF3YWl0IEouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLFcsJC5wdWJLZXkpKXJldHVybiAzO3JldHVybiAwfXZhciBWMD17ZW5jb2RlKCQsSil7bGV0IFo9JC53cml0ZVZhckJ5dGVzKEouaWQpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVEYXRlKEoudHMpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFyQnl0ZXMoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWREYXRlKCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7cmV0dXJuIE8oe2lkOkosdHM6UX0pfX07ZnVuY3Rpb24gQSQoJCl7bGV0IEo9bmV3IFMsWj1KLndyaXRlU3RydWN0KFYwLCQpO2lmKFohPT0wKXJldHVybiBHKFopO2xldCBRPUoucmVzdWx0KCk7cmV0dXJuIE8oUSl9dmFyIEcwPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5laWQpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJJbnQoSi5vZmYpO2lmKFEhPT0wKXJldHVybiBRO2xldCBZPSQud3JpdGVWYXJJbnQoSi5jdHIpO2lmKFkhPT0wKXJldHVybiBZO2xldCBWPSQud3JpdGVWYXJJbnQoSi5sZW4pO2lmKFYhPT0wKXJldHVybiBWO2lmKEouaHNoKSQud3JpdGVCeXRlcyhKLmhzaCk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJCeXRlcygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldCBRPW5ldyBtKEopLFssWV09VjAuZGVjb2RlKFEpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtXLHpdPSQucmVhZFZhckludCgpO2lmKHohPT0wKXJldHVybiBHKHopO2xldFtLLEZdPSQucmVhZFZhckludCgpO2lmKEYhPT0wKXJldHVybiBHKEYpO2xldCBOO2lmKEs+MCl7bGV0W1UsUl09JC5yZWFkQnl0ZXMoQyQpO2lmKFIhPT0wKXJldHVybiBHKFIpO049VX1yZXR1cm4gTyh7ZWlkOkosb2ZmOlYsY3RyOlcsbGVuOkssaHNoOk59KX19O2Z1bmN0aW9uIFUwKCQpe3JldHVybiBBcnJheS5mcm9tKCQpLm1hcCgoWik9PloudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIjAiKSkuam9pbigiIil9ZnVuY3Rpb24gX1ooJCl7aWYoJC5sZW5ndGglMiE9PTApdGhyb3cgRXJyb3IoIkludmFsaWQgaGV4IHN0cmluZyIpO2xldCBKPW5ldyBVaW50OEFycmF5KCQubGVuZ3RoLzIpO2ZvcihsZXQgWj0wO1o8JC5sZW5ndGg7Wis9MilKW1ovMl09TnVtYmVyLnBhcnNlSW50KCQuc3Vic3RyKFosMiksMTYpO3JldHVybiBKfWZ1bmN0aW9uIHIoJCxKKXtpZigkPT09SilyZXR1cm4hMDtpZigkLmJ5dGVMZW5ndGghPT1KLmJ5dGVMZW5ndGgpcmV0dXJuITE7cmV0dXJuICQuZXZlcnkoKFosUSk9Plo9PT1KW1FdKX12YXIgQjtpZih0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUudG9CYXNlNjQ9PT0iZnVuY3Rpb24iKUI9KCQpPT4kLnRvQmFzZTY0KCk7ZWxzZSBCPSgkKT0+YnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlKC4uLiQpKTt2YXIgTjA7aWYodHlwZW9mIFVpbnQ4QXJyYXkuZnJvbUJhc2U2ND09PSJmdW5jdGlvbiIpTjA9KCQpPT5VaW50OEFycmF5LmZyb21CYXNlNjQoJCk7ZWxzZSBOMD0oJCk9PlVpbnQ4QXJyYXkuZnJvbShhdG9iKCQpLChKKT0+Si5jaGFyQ29kZUF0KDApKTtmdW5jdGlvbiBMWigkKXtsZXQgSj0kLmxlbmd0aCU0PT09MD8iIjoiPSIucmVwZWF0KDQtJC5sZW5ndGglNCksWj0kLnJlcGxhY2UoLy0vZywiKyIpLnJlcGxhY2UoL18vZywiLyIpK0o7cmV0dXJuIE4wKFopfWZ1bmN0aW9uIFIwKCQsSil7bGV0IFo9bmV3IFVpbnQ4QXJyYXkoJC5sZW5ndGgrSi5sZW5ndGgpO3JldHVybiBaLnNldCgkLDApLFouc2V0KEosJC5sZW5ndGgpLFp9ZnVuY3Rpb24geFooJCxKLFope3JldHVybiBaLmNoZWNrU2lnRWQyNTUxOSgkLnNpZywkLmhlYWRDcGgsSil9YXN5bmMgZnVuY3Rpb24gQlooJCxKLFosUSl7bGV0IFk7aWYoJC5ib2QmJiQubGVuPjApWT1hd2FpdCBaLmJsYWtlMygkLmJvZCk7bGV0IFY9bmV3IFMsWD1HMC5lbmNvZGUoVix7Li4uJCxoc2g6WX0pO2lmKFghPT0wKXJldHVybiBHKFgpO2xldCBXPVYucmVzdWx0KCksej1hd2FpdCBKLmtkbUZvcihXKSxLPVEuZGVyaXZlQ2lwaGVyKHosImVuY3J5cHQiKSxGPWF3YWl0IEsuZW5jcnlwdChXKSxOPSQuYm9kP2F3YWl0IEsuZW5jcnlwdCgkLmJvZCk6bmV3IFVpbnQ4QXJyYXkoMCksVT1hd2FpdCBKLnNpZ24oRik7cmV0dXJuIE8oe3NpZzpVLGtkbTp6LGhlYWRDcGg6Rixib2R5Q3BoOk59KX1hc3luYyBmdW5jdGlvbiBLSigkLEosWixRLFkpe2xldCBWPW5ldyBtKCQpLFtYLFddPUcwLmRlY29kZShWKTtpZihXIT09MClyZXR1cm4gRygxNCk7bGV0IHo7dHJ5e3o9SiYmSi5sZW5ndGg+MD9hd2FpdCBaLmRlY3J5cHQoSik6dm9pZCAwfWNhdGNoe3JldHVybiBHKDIwKX1sZXQgSz1YLmhzaCYmej09PXZvaWQgMCxGPVguaHNoPT09dm9pZCAwJiZ6IT09dm9pZCAwO2lmKEt8fEYpcmV0dXJuIEcoMTkpO2lmKFguaHNoJiZ6KXtsZXQgVT1hd2FpdCBRLmJsYWtlMyh6KTtpZighcihVLFguaHNoKSlyZXR1cm4gRygxOSl9bGV0IE49WT8/YXdhaXQgUS5ibGFrZTMoJCk7cmV0dXJuIE8oe21zZ0hlYWQ6WCxib2Q6eixoZWFkSGFzaDpOfSl9Y2xhc3MgRkp7bm93KCl7cmV0dXJuIG5ldyBEYXRlfX1mdW5jdGlvbiBrWigkLEosWixRKXtsZXQgWT1KLmdldFRpbWUoKS0kLmdldFRpbWUoKSxWPVouZ2V0VGltZSgpLVEuZ2V0VGltZSgpO3JldHVybihZK1YpLzJ9dmFyIEYkPXtlbmNvZGUoJCxKKXtpZigkLndyaXRlVmFySW50KEoucXVvdGEpLEoucXVvdGE+MCl7aWYoSi51c2FnZT09PXZvaWQgMClyZXR1cm4gOTskLndyaXRlVmFySW50KEoudXNhZ2UpfXJldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFySW50KCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE7aWYoSj4wKXtsZXRbWSxWXT0kLnJlYWRWYXJJbnQoKTtpZihWIT09MClyZXR1cm4gRyhWKTtRPVl9cmV0dXJuIE8oe3F1b3RhOkosdXNhZ2U6UX0pfX07dmFyIE5KPXtlbmNvZGUoJCxKKXskLndyaXRlQnl0ZXMobmV3IFVpbnQ4QXJyYXkoW0ouc3RhdHVzXSkpO2xldCBaPSQud3JpdGVEYXRlKEoudGltZVJjdmQpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVEYXRlKEoudGltZVNlbnQpO2lmKFEhPT0wKXJldHVybiBRO2xldCBZPSQud3JpdGVWYXJJbnQoSi5zdWJzY3JpcHRpb24udGVybSk7aWYoWSE9PTApcmV0dXJuIFk7bGV0IFY9JC53cml0ZVZhckludChKLnN1YnNjcmlwdGlvbi5lbGFwc2VkKTtpZihWIT09MClyZXR1cm4gVjtsZXQgWD0kLndyaXRlU3RydWN0KEYkLEouc3Vic2NyaXB0aW9uLnN0YXQpO2lmKFghPT0wKXJldHVybiBYO2xldCBXPSQud3JpdGVTdHJ1Y3QoRiQsSi5zdWJzY3JpcHRpb24uZHluKTtpZihXIT09MClyZXR1cm4gVztyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKDEpO2lmKFohPT0wKXJldHVybiBHKFopO2xldCBRPUpbMF0sW1ksVl09JC5yZWFkRGF0ZSgpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtYLFddPSQucmVhZERhdGUoKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXRbeixLXT0kLnJlYWRWYXJJbnQoKTtpZihLIT09MClyZXR1cm4gRyhLKTtsZXRbRixOXT0kLnJlYWRWYXJJbnQoKTtpZihOIT09MClyZXR1cm4gRyhOKTtsZXRbVSxSXT0kLnJlYWRTdHJ1Y3QoRiQpO2lmKFIhPT0wKXJldHVybiBHKFIpO2xldFtxLEhdPSQucmVhZFN0cnVjdChGJCk7aWYoSCE9PTApcmV0dXJuIEcoSCk7cmV0dXJuIE8oe3N0YXR1czpRLHRpbWVSY3ZkOlksdGltZVNlbnQ6WCxzdWJzY3JpcHRpb246e3Rlcm06eixlbGFwc2VkOkYsc3RhdDpVLGR5bjpxfX0pfX07dmFyIE9KPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5oZWFkQ3BoKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFySW50KEouc2VxKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhckJ5dGVzKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09JC5yZWFkVmFySW50KCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7cmV0dXJuIE8oe2hlYWRDcGg6SixzZXE6UX0pfX07dmFyIFgwPXtlbmNvZGUoJCxKKXskLndyaXRlQnl0ZXMoSi5wdWJLZXkpLCQud3JpdGVCeXRlcyhKLnNpZyk7bGV0IFo9JC53cml0ZURhdGUoSi50aW1lc3RhbXApO2lmKFohPT0wKXJldHVybiBaO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoVVopO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZEJ5dGVzKEEwKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWREYXRlKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIE8oe3B1YktleTpKLHNpZzpRLHRpbWVzdGFtcDpWfSl9fTt2YXIgRVo9e2FzeW5jIGVuY29kZVJlcSgkLEosWixRLFkpe2xldCBWPVkud3JpdGVTdHJ1Y3QoWDAsWik7aWYoViE9PTApcmV0dXJuIFY7Zm9yKGxldCBYIG9mIFEpWS53cml0ZVZhckludChYKTtyZXR1cm4gMH0sYXN5bmMgaGFuZGxlUmVxKCQsSixaKXtsZXR7Y2xvY2s6USxjcnlwdG86WSxzdG9yYWdlOlZ9PSQsW1gsV109Si5yZWFkU3RydWN0KFgwKTtpZihXIT09MClyZXR1cm4gVztsZXQgej1hd2FpdCBMMChYLFksUSk7aWYoeiE9PTApcmV0dXJuIHo7bGV0e3B1YktleTpLfT1YLFtGLE5dPWF3YWl0IFYuaGFzVXNlcihLKTtpZihOIT09MClyZXR1cm4gTjtpZighRilyZXR1cm4gNTtsZXRbVSxSXT1KLnJlYWRWYXJJbnQoKTtpZihSIT09MClyZXR1cm4gUjtpZighSi5kb25lKCkpcmV0dXJuIDg7bGV0W3EsSF09YXdhaXQgVi5saXN0SGVhZHMoSyxVKTtpZihIIT09MClyZXR1cm4gSDtyZXR1cm4gWi53cml0ZVN0cnVjdHMoT0oscSl9LGRlY29kZVJlc3AoJCl7cmV0dXJuICQucmVhZFN0cnVjdHMoT0opfX07dmFyIFVKPXtlbmNvZGUoJCxKKXskLndyaXRlVmFySW50KEouc2VxKTtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5ib2R5Q3BoKTtpZihaIT09MClyZXR1cm4gWjtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhckludCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZFZhckJ5dGVzKCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7cmV0dXJuIE8oe3NlcTpKLGJvZHlDcGg6UX0pfX07dmFyIGZaPXthc3luYyBlbmNvZGVSZXEoJCxKLFosUSxZKXtsZXQgVj1ZLndyaXRlU3RydWN0KFgwLFopO2lmKFYhPT0wKXJldHVybiBWO2ZvcihsZXQgWCBvZiBRKXtsZXQgVz1ZLndyaXRlVmFySW50KFgpO2lmKFchPT0wKXJldHVybiBXfXJldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxKLFope2xldHtjbG9jazpRLGNyeXB0bzpZLHN0b3JhZ2U6Vn09JCxbWCxXXT1KLnJlYWRTdHJ1Y3QoWDApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEwwKFgsWSxRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVgsW0YsTl09YXdhaXQgVi5oYXNVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO2lmKCFGKXJldHVybiA1O2xldCBVPVtdO3doaWxlKCFKLmRvbmUoKSl7bGV0W0gsTV09Si5yZWFkVmFySW50KCk7aWYoTSE9PTApcmV0dXJuIE07VS5wdXNoKEgpfWNvbnNvbGUuaW5mbyhgUFVMTDogJHtVLmxlbmd0aH0gYmFnc2ApO2xldFtSLHFdPWF3YWl0IFYuZ2V0Qm9kaWVzKEssVSk7aWYocSE9PTApcmV0dXJuIHE7aWYoIVIpcmV0dXJuIDE3O2ZvcihsZXR7c2VxOkgsYm9keUNwaDpNfW9mIFIpe2xldCBQPXtzZXE6SCxib2R5Q3BoOk19LEM9Wi53cml0ZVN0cnVjdChVSixQKTtpZihDIT09MClyZXR1cm4gQ31yZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyhVSil9fTt2YXIgUko9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhKLnNpZyksJC53cml0ZUJ5dGVzKEoua2RtKTtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5oZWFkQ3BoKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFyQnl0ZXMoSi5ib2R5Q3BoKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKEEwKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRCeXRlcyhfMCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbVyx6XT0kLnJlYWRWYXJCeXRlcygpO2lmKHohPT0wKXJldHVybiBHKHopO3JldHVybiBPKHtzaWc6SixrZG06USxoZWFkQ3BoOlYsYm9keUNwaDpXfSl9fTt2YXIgXyQ9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJJbnQoSi5zZXEpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFEhPT0wKXJldHVybiBRO2xldCBZPUouYm9keUNwaD9KLmJvZHlDcGgubGVuZ3RoOjAsVj0kLndyaXRlVmFySW50KFkpO2lmKFYhPT0wKXJldHVybiBWO2lmKFk+MCl7aWYoIUouYm9keUNwaClyZXR1cm4gMTA7JC53cml0ZUJ5dGVzKEouYm9keUNwaCl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJCeXRlcygpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldCBXO2lmKFY+MCl7bGV0W3osS109JC5yZWFkQnl0ZXMoVik7aWYoSyE9PTApcmV0dXJuIEcoSyk7Vz16fXJldHVybiBPKHtzZXE6SixoZWFkQ3BoOlEsYm9keUNwaDpXfSl9fTt2YXIgTCQ9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhKLnNpZyksJC53cml0ZUJ5dGVzKEoua2RtKTtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5oZWFkQ3BoKTtpZihaIT09MClyZXR1cm4gWjtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKEEwKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRCeXRlcyhfMCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gTyh7c2lnOkosa2RtOlEsaGVhZENwaDpWfSl9fTt2YXIgeCQ9e2VuY29kZSgkLEope2lmKCQud3JpdGVWYXJJbnQoSi5pZHgpLCQud3JpdGVCeXRlcyhuZXcgVWludDhBcnJheShbSi5zdGF0dXNdKSksSi5zdGF0dXM9PT0wKSQud3JpdGVWYXJJbnQoSi5zZXEpO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFySW50KCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09JC5yZWFkQnl0ZXMoMSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0IFY9UVswXTtpZihWIT09MClyZXR1cm4gTyh7aWR4Okosc3RhdHVzOlZ9KTtsZXRbWCxXXT0kLnJlYWRWYXJJbnQoKTtpZihXIT09MClyZXR1cm4gRyhXKTtyZXR1cm4gTyh7aWR4Okosc3RhdHVzOlYsc2VxOlh9KX19O3ZhciBnWj17YXN5bmMgZW5jb2RlUmVxKCQsSixaLFEsWSl7bGV0IFY9WS53cml0ZVN0cnVjdChYMCxaKTtpZihWIT09MClyZXR1cm4gVjtsZXQgWD1ZLndyaXRlU3RydWN0cyhSSixRKTtpZihYIT09MClyZXR1cm4gWDtyZXR1cm4gMH0sYXN5bmMgaGFuZGxlUmVxKCQsSixaKXtsZXR7Y2xvY2s6USxjcnlwdG86WSxzdG9yYWdlOlYsbm90aWZpZXI6WH09JCxbVyx6XT1KLnJlYWRTdHJ1Y3QoWDApO2lmKHohPT0wKXJldHVybiB6O2xldCBLPWF3YWl0IEwwKFcsWSxRKTtpZihLIT09MClyZXR1cm4gSztsZXR7cHViS2V5OkZ9PVcsW04sVV09YXdhaXQgVi5oYXNVc2VyKEYpO2lmKFUhPT0wKXJldHVybiBVO2lmKCFOKXJldHVybiA1O2xldFtSLHFdPUoucmVhZFN0cnVjdHMoUkopO2lmKHEhPT0wKXJldHVybiBxO2NvbnNvbGUuaW5mbyhgUFVTSDogJHtSLmxlbmd0aH0gYmFnc2ApO2xldCBIPVtdLE09W107Zm9yKGxldCBJPTA7STxSLmxlbmd0aDtJKyspe2xldCBBPVJbSV07aWYoIWF3YWl0IHhaKEEsRixZKSl7bGV0IGc9e2lkeDpJLHN0YXR1czozfSxmPVoud3JpdGVTdHJ1Y3QoeCQsZyk7aWYoZiE9PTApcmV0dXJuIGY7Y29udGludWV9SC5wdXNoKEkpLE0ucHVzaChBKX1sZXRbUCxDXT1hd2FpdCBWLnNldEJhZ3MoRixNKTtpZihDIT09MClyZXR1cm4gQztpZighUHx8UC5sZW5ndGghPT1NLmxlbmd0aClyZXR1cm4gMTc7bGV0IFQ9W107Zm9yKGxldCBJPTA7STxNLmxlbmd0aDtJKyspe2xldCBBPU1bSV0sTD1IW0ldLGc9UFtJXSxmPW5ldyBTLGs9Zi53cml0ZVN0cnVjdChMJCxBKTtpZihrIT09MClyZXR1cm4gaztsZXQgeT1mLnJlc3VsdCgpLGg9e3NlcTpnLGhlYWRDcGg6eX07aWYoUi5sZW5ndGg9PT0xJiZBLmJvZHlDcGgubGVuZ3RoPD1IWiloLmJvZHlDcGg9QS5ib2R5Q3BoO1QucHVzaChoKTtsZXQgdz17aWR4Okwsc3RhdHVzOjAsc2VxOmd9LHA9Wi53cml0ZVN0cnVjdCh4JCx3KTtpZihwIT09MClyZXR1cm4gcH1pZihULmxlbmd0aD4wKXtsZXQgST1uZXcgUyxBPUkud3JpdGVTdHJ1Y3RzKF8kLFQpO2lmKEEhPT0wKXJldHVybiBBO2xldCBMPUkucmVzdWx0KCk7YXdhaXQgUHJvbWlzZS5yZXNvbHZlKFgucHVzaChGLEwpKX1yZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyh4JCl9fTt2YXIgbVo9e2FzeW5jIGVuY29kZVJlcSgkLEosWixRLFkpe3JldHVybiBZLndyaXRlU3RydWN0KFgwLFopfSxhc3luYyBoYW5kbGVSZXEoJCxKLFope2xldHtjbG9jazpRLGNyeXB0bzpZLHN0b3JhZ2U6Vn09JCxbWCxXXT1KLnJlYWRTdHJ1Y3QoWDApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEwwKFgsWSxRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVg7aWYoIUouZG9uZSgpKXJldHVybiA4O2xldFtGLE5dPWF3YWl0IFYuYWRkVXNlcihLKTtpZihOIT09MClyZXR1cm4gTjtyZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gTyh2b2lkIDApfX07Y2xhc3MgSEp7dXJsO3dlYnNvY2tldDtjb25zdHJ1Y3RvcigkKXt0aGlzLnVybD0kfWNvbm5lY3RlZCgpe3JldHVybiB0aGlzLndlYnNvY2tldCE9PXZvaWQgMCYmdGhpcy53ZWJzb2NrZXQucmVhZHlTdGF0ZT09PVdlYlNvY2tldC5PUEVOfWFzeW5jIGNvbm5lY3QoJCxKLFo9KCk9Pnt9LFE9KCk9Pnt9KXtsZXR7dXJsOll9PXRoaXM7aWYodGhpcy53ZWJzb2NrZXQpdGhpcy53ZWJzb2NrZXQuY2xvc2UoKSx0aGlzLndlYnNvY2tldD12b2lkIDA7bGV0IFY9bmV3IFM7Vi53cml0ZVN0cnVjdChYMCwkKTtsZXQgWD1WLnJlc3VsdCgpLFc9VTAoWCk7cmV0dXJuIFkuc2VhcmNoUGFyYW1zLnNldCgidCIsVyksdGhpcy53ZWJzb2NrZXQ9bmV3IFdlYlNvY2tldChZKSx0aGlzLndlYnNvY2tldC5iaW5hcnlUeXBlPSJhcnJheWJ1ZmZlciIsdGhpcy53ZWJzb2NrZXQub25vcGVuPSgpPT57Y29uc29sZS5sb2coIkNPTk5FQ1RFRCIpLFEoKX0sdGhpcy53ZWJzb2NrZXQub25jbG9zZT0oKT0+e2NvbnNvbGUubG9nKCJESVNDT05ORUNURUQiKSx0aGlzLndlYnNvY2tldD12b2lkIDAsWigpfSx0aGlzLndlYnNvY2tldC5vbm1lc3NhZ2U9KHopPT57bGV0IEs9bmV3IFVpbnQ4QXJyYXkoei5kYXRhKTtKKEspfSx0aGlzLndlYnNvY2tldC5vbmVycm9yPSh6KT0+e2NvbnNvbGUubG9nKGBFUlJPUjogJHtKU09OLnN0cmluZ2lmeSh6KX1gKSx0aGlzLndlYnNvY2tldD12b2lkIDAsWigpfSxQcm9taXNlLnJlc29sdmUoMCl9ZGlzY29ubmVjdCgpe3RoaXMud2Vic29ja2V0Py5jbG9zZSgpLHRoaXMud2Vic29ja2V0PXZvaWQgMH19dmFyIGE9e3VzZXI6e3BhdGg6Ii91c2VyIixlbmRwb2ludDptWixuYW1lOjB9LHB1c2g6e3BhdGg6Ii9wdXNoIixlbmRwb2ludDpnWixuYW1lOjJ9LHBlZWs6e3BhdGg6Ii9wZWVrIixlbmRwb2ludDpFWixuYW1lOjF9LHB1bGw6e3BhdGg6Ii9wdWxsIixlbmRwb2ludDpmWixuYW1lOjN9fSxBWT17MDphLnVzZXIsMjphLnB1c2gsMTphLnBlZWssMzphLnB1bGx9LHVXPXtbYS51c2VyLnBhdGhdOmEudXNlcixbYS5wdXNoLnBhdGhdOmEucHVzaCxbYS5wZWVrLnBhdGhdOmEucGVlayxbYS5wdWxsLnBhdGhdOmEucHVsbH07Y2xhc3MgU1p7dXJsO2xpc3RlbmVyO2NvbnN0cnVjdG9yKCQpe3RoaXMudXJsPSQ7dGhpcy5saXN0ZW5lcj1uZXcgSEooJCl9YXN5bmMgY2FsbCgkLEope2xldHtwYXRoOlp9PUFZWyRdLFE9bmV3IFVSTChaLHRoaXMudXJsKTt0cnl7cmV0dXJuIGF3YWl0IF9ZKFEsSil9Y2F0Y2h7cmV0dXJuIEcoMjUpfX19dmFyIHZaPSgkKT0+e3JldHVybiBuZXcgU1ooJC5oYW5kbGUpfTthc3luYyBmdW5jdGlvbiBfWSgkLEope2xldCBaPWF3YWl0IGZldGNoKCQse21ldGhvZDoiUE9TVCIsYm9keTpKLnJlc3VsdCgpLnNsaWNlKCl9KTtpZighWi5vaylyZXR1cm4gRygyNCk7bGV0IFE9YXdhaXQgbS5mcm9tUmVzcG9uc2UoWik7cmV0dXJuIE8oUSl9Y2xhc3MgQiR7ZW5jbGF2ZTtjcnlwdG87aG9zdDtjbG9jazt0cmFuc3BvcnQ7dXBkYXRlSG9zdE1ldGE7Y29uc3RydWN0b3IoJCxKLFosUSxZLFYpe3RoaXMuZW5jbGF2ZT0kO3RoaXMuY3J5cHRvPUo7dGhpcy5ob3N0PVo7dGhpcy5jbG9jaz1RO3RoaXMudHJhbnNwb3J0PVk7dGhpcy51cGRhdGVIb3N0TWV0YT1WfWFzeW5jIGNhbGwoJCxKKXtsZXR7Y2xvY2s6Wix0cmFuc3BvcnQ6UX09dGhpcyx7ZW5kcG9pbnQ6WSxuYW1lOlZ9PSQsWD1hd2FpdCB0aGlzLmlkZW50aXR5KCksVz1aLm5vdygpLFt6LEtdPWF3YWl0IHpKKFgsVyk7aWYoSyE9PTApcmV0dXJuIEcoSyk7bGV0IEY9bmV3IFMsTj1hd2FpdCBZLmVuY29kZVJlcSh0aGlzLFgseixKLEYpO2lmKE4hPT0wKXJldHVybiBHKE4pO2xldCBVPVoubm93KCksW1IscV09YXdhaXQgUS5jYWxsKFYsRiksSD1aLm5vdygpO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldFtNLFBdPVIucmVhZFN0cnVjdChOSik7aWYoUCE9PTApcmV0dXJuIEcoUCk7aWYoTS5zdGF0dXMhPT0wKXJldHVybiBHKE0uc3RhdHVzKTtsZXQgVD17Y2xvY2tPZmZzZXQ6a1ooVSxNLnRpbWVSY3ZkLE0udGltZVNlbnQsSCksc3Vic2NyaXB0aW9uOk0uc3Vic2NyaXB0aW9ufSxJPWF3YWl0IHRoaXMudXBkYXRlSG9zdE1ldGEoVCk7aWYoSSE9PTApcmV0dXJuIEcoSSk7cmV0dXJuIFkuZGVjb2RlUmVzcChSKX1pZGVudGl0eT0oKT0+e2xldHtob3N0OiQsZW5jbGF2ZTpKfT10aGlzO3JldHVybiBKLmRlcml2ZUlkZW50aXR5KCQubGFiZWwsJC5pZHg/PzApfTtzZWFsPWFzeW5jKCQpPT57bGV0e2NyeXB0bzpKLGVuY2xhdmU6Wn09dGhpcyxRPWF3YWl0IHRoaXMuaWRlbnRpdHkoKTtyZXR1cm4gQlooJCxRLEosWil9O3JlZ2lzdGVyPSgpPT50aGlzLmNhbGwoYS51c2VyLFtdKTtwZWVrPSgkKT0+dGhpcy5jYWxsKGEucGVlayxbJF0pO3B1c2g9KCQpPT50aGlzLmNhbGwoYS5wdXNoLCQpO3B1bGw9KCQpPT50aGlzLmNhbGwoYS5wdWxsLCQpO2xpc3Rlbj1hc3luYygkLEosWik9PntsZXR7Y2xvY2s6USx0cmFuc3BvcnQ6WX09dGhpcyx7bGlzdGVuZXI6Vn09WSxYPWF3YWl0IHRoaXMuaWRlbnRpdHkoKSxXPVEubm93KCksW3osS109YXdhaXQgekooWCxXKTtpZihLIT09MClyZXR1cm4gSztyZXR1cm4gYXdhaXQgVi5jb25uZWN0KHosJCxKLFopfTtpc0Nvbm5lY3RlZCgpe2xldCAkPXRoaXMudHJhbnNwb3J0Py5saXN0ZW5lcjtpZigkJiZ0eXBlb2YgJC5jb25uZWN0ZWQ9PT0iZnVuY3Rpb24iKXJldHVybiAkLmNvbm5lY3RlZCgpO3JldHVybiEwfWNsb3NlTGlzdGVuZXIoKXt0aGlzLnRyYW5zcG9ydD8ubGlzdGVuZXI/LmRpc2Nvbm5lY3QoKX19dmFyIHFKPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyU3RyaW5nKEoubGJsKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFySW50KEouaWR4KTtpZihRIT09MClyZXR1cm4gUTtsZXQgWT0kLndyaXRlVmFySW50KEoubnVtKTtpZihZIT09MClyZXR1cm4gWTtyZXR1cm4gJC53cml0ZUJ5dGVzKEouaHNoKSwkLndyaXRlQnl0ZXMoSi5zaWcpLDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJJbnQoKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbVyx6XT0kLnJlYWRCeXRlcyhDJCk7aWYoeiE9PTApcmV0dXJuIEcoeik7bGV0W0ssRl09JC5yZWFkQnl0ZXMoQTApO2lmKEYhPT0wKXJldHVybiBHKEYpO3JldHVybiBPKHtsYmw6SixpZHg6USxudW06Vixoc2g6VyxzaWc6S30pfX07dmFyIE1KPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlU3RydWN0KHFKLEouaGVhZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckJ5dGVzKEouaW5kZXhFbmMpO2lmKFEhPT0wKXJldHVybiBRO2xldCBZPSQud3JpdGVWYXJCeXRlcyhKLmJvZHlFbmMpO2lmKFkhPT0wKXJldHVybiBZO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkU3RydWN0KHFKKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJCeXRlcygpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckJ5dGVzKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIE8oe2hlYWQ6SixpbmRleEVuYzpRLGJvZHlFbmM6Vn0pfX07dmFyIElKPXtlbmNvZGUoJCxKKXskLndyaXRlQnl0ZXMoSi5rZG0pO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJJbnQoSi5sZW5Cb2R5KTtpZihRIT09MClyZXR1cm4gUTtpZihKLmxlbkJvZHk+MCYmSi5vZmZCb2R5IT09dm9pZCAwKXtsZXQgWT0kLndyaXRlVmFySW50KEoub2ZmQm9keSk7aWYoWSE9PTApcmV0dXJuIFl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRCeXRlcyhfMCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09JC5yZWFkVmFyQnl0ZXMoKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXQgVztpZihWPjApe2xldFt6LEtdPSQucmVhZFZhckludCgpO2lmKEshPT0wKXJldHVybiBHKEspO1c9en1yZXR1cm4gTyh7a2RtOkosaGVhZENwaDpRLGxlbkJvZHk6VixvZmZCb2R5Old9KX19O2FzeW5jIGZ1bmN0aW9uIHlaKCQsSixaLFEsWSl7bGV0IFY9YXdhaXQgWS5kZXJpdmVJZGVudGl0eSgkLEopLFg9bmV3IFMsVz1uZXcgUyx6PTAsSz0wO2ZvcihsZXQgUCBvZiBaKXtsZXQgQz1uZXcgUyxUPUMud3JpdGVTdHJ1Y3QoRzAsUC5oZWFkKTtpZihUIT09MClyZXR1cm4gRyhUKTtsZXQgST1DLnJlc3VsdCgpLEE9YXdhaXQgVi5rZG1Gb3IoSSksTD1ZLmRlcml2ZUNpcGhlcihBLCJlbmNyeXB0IiksZz1hd2FpdCBMLmVuY3J5cHQoSSksZj1QLmJvZHk/YXdhaXQgTC5lbmNyeXB0KFAuYm9keSk6bmV3IFVpbnQ4QXJyYXkoMCksaz1QLmhlYWQubGVuPjAmJlAuaGVhZC5oc2ghPT12b2lkIDA/Zi5sZW5ndGg6MCx5PXtrZG06QSxoZWFkQ3BoOmcsbGVuQm9keTprLG9mZkJvZHk6az4wP0s6dm9pZCAwfSxoPVgud3JpdGVTdHJ1Y3QoSUoseSk7aWYoaCE9PTApcmV0dXJuIEcoaCk7aWYoUC5ib2R5KVcud3JpdGVCeXRlcyhmKSxLKz1mLmxlbmd0aDt6Kyt9bGV0IEY9Vy5yZXN1bHQoKSxOPVgucmVzdWx0KCksVT1hd2FpdCBRLmJsYWtlMyhOKSxSPWF3YWl0IFYuc2lnbihVKSxxPXtsYmw6JCxpZHg6SixudW06eixoc2g6VSxzaWc6Un0sSD1uZXcgUztILndyaXRlU3RydWN0KE1KLHtoZWFkOnEsaW5kZXhFbmM6Tixib2R5RW5jOkZ9KTtsZXQgTT1ILnJlc3VsdCgpO3JldHVybiBPKE0pfWFzeW5jIGZ1bmN0aW9uIGJaKCQsSixaKXtsZXRbUSxZXT1NSi5kZWNvZGUobmV3IG0oJCkpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldHtoZWFkOlYsaW5kZXhFbmM6WCxib2R5RW5jOld9PVEsej1hd2FpdCBaLmRlcml2ZUlkZW50aXR5KFYubGJsLFYuaWR4KTtpZighYXdhaXQgSi5jaGVja1NpZ0VkMjU1MTkoVi5zaWcsVi5oc2gsei5wdWJsaWNLZXkpKXJldHVybiBHKDMpO2xldCBGPWF3YWl0IEouYmxha2UzKFgpO2lmKCFyKEYsVi5oc2gpKXJldHVybiBHKDE5KTtsZXQgTj1uZXcgbShYKSxVPVtdO2ZvcihsZXQgcT0wO3E8Vi5udW07cSsrKXtsZXRbSCxNXT1OLnJlYWRTdHJ1Y3QoSUopO2lmKE0hPT0wKXJldHVybiBHKE0pO1UucHVzaChIKX1pZihVLmxlbmd0aCE9PVYubnVtKXJldHVybiBHKDE0KTtsZXQgUj1bXTtmb3IobGV0IHEgb2YgVSl7bGV0IEg9Wi5kZXJpdmVDaXBoZXIocS5rZG0sImRlY3J5cHQiKSxNO3RyeXtNPWF3YWl0IEguZGVjcnlwdChxLmhlYWRDcGgpfWNhdGNoe3JldHVybiBHKDIwKX1sZXRbUCxDXT1HMC5kZWNvZGUobmV3IG0oTSkpO2lmKEMhPT0wKXJldHVybiBHKEMpO2xldCBUO2lmKHEubGVuQm9keT4wJiZxLm9mZkJvZHkhPT12b2lkIDApe2lmKFAuaHNoPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXQgST1XLnNsaWNlKHEub2ZmQm9keSxxLm9mZkJvZHkrcS5sZW5Cb2R5KTt0cnl7VD1hd2FpdCBILmRlY3J5cHQoSSl9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldCBBPWF3YWl0IEouYmxha2UzKFQpO2lmKCFyKEEsUC5oc2gpKXJldHVybiBHKDE5KX1SLnB1c2goe2hlYWQ6UCxib2R5OlR9KX1yZXR1cm4gTyhSKX1hc3luYyBmdW5jdGlvbiBoWih7bm93OiQsYm9kOkosY3J5cHRvOlp9KXtsZXQgUT1hd2FpdCBaLmdlblJhbmRvbUJ5dGVzKDgpLFk9bmV3IFMsVj1ZLndyaXRlU3RydWN0KFYwLHtpZDpRLHRzOiR9KTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXQgWD1ZLnJlc3VsdCgpO3JldHVybiBrJCh7bm93OiQsZWlkOlgsY3RyOjAsYm9kOkosY3J5cHRvOlp9KX1hc3luYyBmdW5jdGlvbiBrJCh7bm93OiQsZWlkOkosY3RyOlosYm9kOlEsY3J5cHRvOll9KXtsZXQgVj1uZXcgbShKKSxbWCxXXT1WMC5kZWNvZGUoVik7aWYoVyE9PTApcmV0dXJuIEcoVyk7bGV0IHo9JC5nZXRUaW1lKCktWC50cy5nZXRUaW1lKCksSyxGPVE/Lmxlbmd0aD8/MDtpZihRJiZGPjApSz1hd2FpdCBZLmJsYWtlMyhRKTtyZXR1cm4gTyh7ZWlkOkosb2ZmOnosY3RyOlosbGVuOkYsaHNoOkt9KX1mdW5jdGlvbiBMWSgkLEope2xldCBaPSQubGVuZ3RoPEoubGVuZ3RoPyQubGVuZ3RoOkoubGVuZ3RoO2ZvcihsZXQgUT0wO1E8WjtRKyspaWYoJFtRXSE9PUpbUV0pcmV0dXJuICRbUV0tSltRXTtyZXR1cm4gJC5sZW5ndGgtSi5sZW5ndGh9YXN5bmMgZnVuY3Rpb24gTiQoJCxKKXtsZXQgWj1BcnJheS5mcm9tKCQpO1ouc29ydChMWSk7bGV0IFE9MDtmb3IobGV0IFggb2YgWilRKz1YLmxlbmd0aDtsZXQgWT1uZXcgVWludDhBcnJheShRKSxWPTA7Zm9yKGxldCBYIG9mIFopWS5zZXQoWCxWKSxWKz1YLmxlbmd0aDtyZXR1cm4gSi5ibGFrZTMoWSl9ZnVuY3Rpb24geFkoJCl7bGV0IEo9bmV3IFMsWj1KLndyaXRlVmFyQnl0ZXMoJC5laWQpO2lmKFohPT0wKXJldHVybiBHKFopO2xldCBRPUoud3JpdGVEYXRlKCQudXBkYXRlZEF0KTtpZihRIT09MClyZXR1cm4gRyhRKTtsZXQgWT1KLndyaXRlVmFySW50KCQuY3RyKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTyhKLnJlc3VsdCgpKX1hc3luYyBmdW5jdGlvbiBFJCgkLEope2xldCBaPVtdO2ZvcihsZXQgUSBvZiAkKXtsZXRbWSxWXT14WShRKTtpZihWIT09MHx8IVkpcmV0dXJuIEcoVik7Wi5wdXNoKFkpfXJldHVybiBPKGF3YWl0IE4kKFosSikpfXZhciBTRz1TeW1ib2woIk1hc3RlclNlZWQiKSx2Rz1TeW1ib2woIlNlYWxlZE1hc3RlcktleSIpLEgwPTMyLGlaPTI0K0gwKzE2O2Z1bmN0aW9uICQwKCQpe2lmKCQuYnl0ZUxlbmd0aCE9PUgwKXJldHVybiBHKDEwKTtyZXR1cm4gTygkKX1mdW5jdGlvbiB4MCgkKXtpZigkLmJ5dGVMZW5ndGghPT1pWilyZXR1cm4gRygxMCk7cmV0dXJuIE8oJCl9dmFyIGJHPVN5bWJvbCgiRW50aXR5SUQiKTtmdW5jdGlvbiBsWigkKXtyZXR1cm4idHlwZSJpbiAkfXZhciBoRz1TeW1ib2woIkRlcml2YXRpb25TZWVkIiksaUc9U3ltYm9sKCJQdWJsaWNLZXkiKSxsRz1TeW1ib2woIlByaXZhdGVLZXkiKSx1Rz1TeW1ib2woIkhvc3RTcGVjaWZpY0tleVBhaXIiKSxwRz1TeW1ib2woIkhhc2giKTtmdW5jdGlvbiBCWSgkKXtpZighJClyZXR1cm4hMTtpZih0eXBlb2YgJCE9PSJvYmplY3QiKXJldHVybiExO2lmKCJib2R5ImluICQ9PT0hMSlyZXR1cm4hMTtpZigidHlwZSJpbiAkPT09ITEpcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24ga1koJCl7aWYoISQuYm9kfHwkLmJvZC5sZW5ndGg9PT0wKXtsZXQgUT17b2ZmOiQub2ZmLGN0cjokLmN0cixlaWQ6JC5laWR9O3JldHVybiBPKFEpfWxldCBKPUdKKCQuYm9kKTtpZihCWShKKT09PSExKXJldHVybiBjb25zb2xlLndhcm4oIm1zZyBib2R5IGludmFsaWQiLEopLEcoMTQpO2xldCBaPXtvZmY6JC5vZmYsY3RyOiQuY3RyLGVpZDokLmVpZCxnaWQ6Si5naWQscGlkOkoucGlkLHRhZ3M6Si50YWdzLHR5cGU6Si50eXBlLGJvZHk6Si5ib2R5fTtyZXR1cm4gTyhaKX1jbGFzcyBmJHthcHBsaWVyO2VtaXR0ZXI9bmV3IEskO2NsZWFyZXI7b25EaXJ0eUVpZHM7Y2FjaGVEcml2ZW47cGVlckluZ2VzdDtjb25zdHJ1Y3RvcigkLEosWixRKXt0aGlzLmFwcGxpZXI9JDt0aGlzLmNsZWFyZXI9Six0aGlzLm9uRGlydHlFaWRzPVosdGhpcy5jYWNoZURyaXZlbj1RPy5jYWNoZURyaXZlbj8/ITEsdGhpcy5wZWVySW5nZXN0PVE/LnBlZXJJbmdlc3R9YXBwbHk9YXN5bmMoJCk9PntsZXQgSj1bXSxaPVtdO2ZvcihsZXQgVyBvZiAkKXtsZXRbeixLXT1rWShXKTtpZihaLnB1c2goSyksSyE9PTApY29udGludWU7Si5wdXNoKHopfWxldHtzdGF0czpRLHR5cGVzOlksZWlkczpWfT1hd2FpdCB0aGlzLmFwcGxpZXIoSiksWD1bXTtmb3IobGV0IFc9MDtXPCQubGVuZ3RoO1crKyl7bGV0IHo9WltXXSxLPVFbV107aWYoeiE9PTApe1gucHVzaCh6KTtjb250aW51ZX1pZihLIT09MCl7WC5wdXNoKEspO2NvbnRpbnVlfVgucHVzaCgwKX1pZighdGhpcy5jYWNoZURyaXZlbilmb3IobGV0IFcgb2YgWSl0aGlzLmVtaXR0ZXIuZW1pdChXLG51bGwpO2lmKFYubGVuZ3RoPjApdGhpcy5vbkRpcnR5RWlkcz8uKFYpO3JldHVybiBYfTtjbGVhcj1hc3luYygpPT57bGV0ICQ9YXdhaXQgdGhpcy5jbGVhcmVyKCk7aWYoJCE9PTApcmV0dXJuICQ7cmV0dXJuIHRoaXMuZW1pdHRlci5lbWl0QWxsKG51bGwpLCR9O25vdGlmeT0oJCk9Pntmb3IobGV0IEogb2YgJCl0aGlzLmVtaXR0ZXIuZW1pdChKLG51bGwpfTtyZWZyZXNoPWFzeW5jKCQpPT57aWYodGhpcy5wZWVySW5nZXN0KXthd2FpdCB0aGlzLnBlZXJJbmdlc3QoJCk7cmV0dXJufX07b249KCQsSik9Pnt0aGlzLmVtaXR0ZXIuYWRkRXZlbnRMaXN0ZW5lcigkLEopfTtvZmY9KCQsSik9Pnt0aGlzLmVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigkLEopfX12YXIgbj0iZW50aXRpZXMiLGckPSJlbnRpdHlfdHlwZV9jcmVhdGVkX2F0IixQSj0iZW50aXR5X3R5cGVfdXBkYXRlZF9hdCIsd0o9ImVudGl0eV90eXBlX2dyb3VwX2lkIixUSj0iZW50aXR5X3R5cGVfcGFyZW50X2lkIixzMD0iZW50aXR5X3RhZ3MiLHVaPSJkYiIscFo9MTM7ZnVuY3Rpb24gRVkoJCl7cmV0dXJuInR5cCJpbiAkfWZ1bmN0aW9uIGZZKCQpe2xldCBKPXtib2Q6JC5ib2R5LGNyZDokLmNyZWF0ZWRBdCwuLi4kLmN0ciE9PTA/e2N0cjokLmN0cn06e30sZWlkOkIoJC5laWQpLGdpZDokLmdpZCxwaWQ6JC5waWQ/QigkLnBpZCk6dm9pZCAwLHRnczokLnRhZ3MsdHlwOiQudHlwZSx1cGQ6JC51cGRhdGVkQXR9O2lmKEouZ2lkPT09dm9pZCAwKWRlbGV0ZSBKLmdpZDtpZihKLnBpZD09PXZvaWQgMClkZWxldGUgSi5waWQ7aWYoSi50Z3M9PT12b2lkIDApZGVsZXRlIEoudGdzO2lmKEouY3RyPT09dm9pZCAwKWRlbGV0ZSBKLmN0cjtyZXR1cm4gSn1mdW5jdGlvbiBnWSgkKXtpZighbCgkKSlyZXR1cm57ZWlkOkIoJC5laWQpLHVwZDokLnVwZGF0ZWRBdCwuLi4kLmN0ciE9PTA/e2N0cjokLmN0cn06e319O3JldHVybiBmWSgkKX1mdW5jdGlvbiB0MCgkKXtyZXR1cm57Ym9keTokLmJvZCxjcmVhdGVkQXQ6JC5jcmQsdXBkYXRlZEF0OiQudXBkLGN0cjokLmN0cj8/MCx0eXBlOiQudHlwLGVpZDpOMCgkLmVpZCksZ2lkOiQuZ2lkLHBpZDokLnBpZD9OMCgkLnBpZCk6dm9pZCAwLC4uLiQudGdzIT09dm9pZCAwP3t0YWdzOiQudGdzfTp7fX19ZnVuY3Rpb24gQ0ooJCl7aWYoRVkoJCkpcmV0dXJuIHQwKCQpO3JldHVybntlaWQ6TjAoJC5laWQpLHVwZGF0ZWRBdDokLnVwZCxjdHI6JC5jdHI/PzB9fWNsYXNzIGNae2RiO29wZW5pbmc7YXN5bmMgaW5pdCgpe2F3YWl0IHRoaXMuZW5zdXJlRGIoKX1hc3luYyBlbnN1cmVEYigpe2lmKHRoaXMuZGIpcmV0dXJuIHRoaXMuZGI7aWYodGhpcy5vcGVuaW5nKXJldHVybiB0aGlzLm9wZW5pbmc7cmV0dXJuIHRoaXMub3BlbmluZz1TWSgpLnRoZW4oKCQpPT57cmV0dXJuICQub252ZXJzaW9uY2hhbmdlPSgpPT57aWYoJC5jbG9zZSgpLHRoaXMuZGI9PT0kKXRoaXMuZGI9dm9pZCAwfSx0aGlzLmRiPSQsdGhpcy5vcGVuaW5nPXZvaWQgMCwkfSwoJCk9Pnt0aHJvdyB0aGlzLm9wZW5pbmc9dm9pZCAwLCR9KSx0aGlzLm9wZW5pbmd9YXBwbHk9YXN5bmMoJCk9PntsZXQgSj1uZXcgU2V0LFo9W10sUTt0cnl7UT1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJue3N0YXRzOiQubWFwKCgpPT4xNiksdHlwZXM6SixlaWRzOlp9fWxldCBZPVEudHJhbnNhY3Rpb24obiwicmVhZHdyaXRlIiksVj1ZLm9iamVjdFN0b3JlKG4pO3JldHVybiBuZXcgUHJvbWlzZSgoWCk9PntsZXQgVz1BcnJheSgkLmxlbmd0aCkuZmlsbCgwKTtpZigkLmxlbmd0aDwxKXtYKHtzdGF0czpbXSx0eXBlczpKLGVpZHM6Wn0pO3JldHVybn1ZLm9uY29tcGxldGU9KCk9PntYKHtzdGF0czpXLHR5cGVzOkosZWlkczpafSl9LFkub25lcnJvcj0oKT0+e2ZvcihsZXQgSz0wO0s8Vy5sZW5ndGg7SysrKWlmKFdbS109PT12b2lkIDApV1tLXT0xODtYKHtzdGF0czpXLHR5cGVzOkosZWlkczpafSl9O2xldCB6PW5ldyBNYXA7Zm9yKGxldCBLPTA7SzwkLmxlbmd0aDtLKyspe2xldCBGPSRbS10sTj1CKEYuZWlkKSxVPXtvcDpGLGluZGV4Okt9LFI9ei5nZXQoTik7aWYoUilSLnB1c2goVSk7ZWxzZSB6LnNldChOLFtVXSl9Zm9yKGxldFtLLEZdb2Ygeil7aWYoRi5sZW5ndGg8MSljb250aW51ZTtsZXQgTj1WLmdldChLKTtOLm9uc3VjY2Vzcz0oKT0+e2xldCBVPU4ucmVzdWx0LFI9VT9DSihVKTp2b2lkIDAscT0hMTtmb3IobGV0e29wOkgsaW5kZXg6TX1vZiBGKXtsZXRbUCxDXT1lMChSLEgpO2lmKEMhPT0wKXtXW01dPUM7Y29udGludWV9aWYoUD09PXZvaWQgMCl7V1tNXT0xMjtjb250aW51ZX1xPSEwO2ZvcihsZXQgVCBvZiAkJChSLFApKUouYWRkKFQpO1I9UH1pZihxKVoucHVzaChGWzBdLm9wLmVpZCk7aWYoUil7bGV0IEg9Vi5wdXQoZ1koUikpO0gub25lcnJvcj0oTSk9PntNLnByZXZlbnREZWZhdWx0KCk7Zm9yKGxldHtpbmRleDpQfW9mIEYpV1tQXT0xOH19fSxOLm9uZXJyb3I9KCk9Pntmb3IobGV0e2luZGV4OlV9b2YgRilXW1VdPTE4fX19KX07YXN5bmMgY2xlYXIoKXtsZXQgJDt0cnl7JD1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIDE2fWxldCBKPSQudHJhbnNhY3Rpb24obiwicmVhZHdyaXRlIiksWj1KLm9iamVjdFN0b3JlKG4pO3JldHVybiBuZXcgUHJvbWlzZSgoUSk9PntKLm9uY29tcGxldGU9KCk9PlEoMCksSi5vbmVycm9yPSgpPT5RKDE4KSxaLmNsZWFyKCl9KX1hc3luYyBnZXRSb3coJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgWj1CKCQpLFk9Si50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pO3JldHVybiBuZXcgUHJvbWlzZSgoVik9PntsZXQgWD1ZLmdldChaKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0O2lmKCFXKVYoTyh2b2lkIDApKTtlbHNlIFYoTyhDSihXKSkpfSxYLm9uZXJyb3I9KCk9PlYoRygxOCkpfSl9YXN5bmMgZ2V0RW50KCQpe2xldFtKLFpdPWF3YWl0IHRoaXMuZ2V0Um93KCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDB8fCFsKEopKXJldHVybiBPKHZvaWQgMCk7cmV0dXJuIE8oSil9YXN5bmMgZ2V0QWxsT2ZUeXBlVXBkYXRlZEJldHdlZW4oJCxKLFope2xldCBRO3RyeXtRPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFY9US50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KFBKKTtyZXR1cm4gbmV3IFByb21pc2UoKFgpPT57bGV0IFc9Vi5nZXRBbGwoSURCS2V5UmFuZ2UuYm91bmQoWyQsSl0sWyQsWl0pKTtXLm9uc3VjY2Vzcz0oKT0+e2xldCB6PVcucmVzdWx0O1goTyh6Lm1hcCh0MCkpKX0sVy5vbmVycm9yPSgpPT5YKEcoMTgpKX0pfWFzeW5jIGdldEdyb3VwTWVtYmVycygkLEope2xldCBaO3RyeXtaPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFk9Wi50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KHdKKTtyZXR1cm4gbmV3IFByb21pc2UoKFYpPT57bGV0IFg9WS5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShbJCxKXSkpO1gub25zdWNjZXNzPSgpPT57bGV0IFc9WC5yZXN1bHQ7VihPKFcubWFwKHQwKSkpfSxYLm9uZXJyb3I9KCk9PlYoRygxOCkpfSl9YXN5bmMgZ2V0QWxsT2ZUeXBlKCQpe2xldCBKO3RyeXtKPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFE9Si50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KGckKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFY9US5nZXRBbGwoSURCS2V5UmFuZ2UuYm91bmQoWyRdLFskLFtdXSkpO1Yub25zdWNjZXNzPSgpPT57bGV0IFg9Vi5yZXN1bHQ7WShPKFgubWFwKHQwKSkpfSxWLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9YXN5bmMgZ2V0QnlUYWcoJCxKKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBZPVoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChzMCk7cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBYPVkuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoSikpO1gub25zdWNjZXNzPSgpPT57bGV0IHo9WC5yZXN1bHQuZmlsdGVyKChLKT0+Sy50eXA9PT0kKS5tYXAodDApO1YoTyh6KSl9LFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBnZXRBbGxFbnRpdGllcygkKXtpZigicGlkImluICQpe2xldCBKO3RyeXtKPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFo9QigkLnBpZCksWT1KLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgoVEopO3JldHVybiBuZXcgUHJvbWlzZSgoVik9PntsZXQgWD1ZLmdldEFsbChJREJLZXlSYW5nZS5vbmx5KFskLnR5cGUsWl0pKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCB6PVgucmVzdWx0Lm1hcCh0MCk7VihPKHopKX0sWC5vbmVycm9yPSgpPT5WKEcoMTgpKX0pfWVsc2UgaWYoImdpZCJpbiAkKXJldHVybiBhd2FpdCB0aGlzLmdldEdyb3VwTWVtYmVycygkLnR5cGUsJC5naWQpO2Vsc2UgaWYoInRhZyJpbiAkKXJldHVybiBhd2FpdCB0aGlzLmdldEJ5VGFnKCQudHlwZSwkLnRhZyk7ZWxzZSBpZigidXBkYXRlZEJldHdlZW4iaW4gJClyZXR1cm4gYXdhaXQgdGhpcy5nZXRBbGxPZlR5cGVVcGRhdGVkQmV0d2VlbigkLnR5cGUsJC51cGRhdGVkQmV0d2Vlbi5zdGFydCwkLnVwZGF0ZWRCZXR3ZWVuLmVuZCk7cmV0dXJuIGF3YWl0IHRoaXMuZ2V0QWxsT2ZUeXBlKCQudHlwZSl9YXN5bmMgZ2V0RW50aXRpZXMoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRBbGxFbnRpdGllcygkKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gTyhKKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtsZXQgSjt0cnl7Sj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBRPUoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChnJCk7cmV0dXJuIG5ldyBQcm9taXNlKChZKT0+e2xldCBWPUlEQktleVJhbmdlLmJvdW5kKFskXSxbJCxbXV0pLFg9US5jb3VudChWKTtYLm9uc3VjY2Vzcz0oKT0+WShPKFgucmVzdWx0KSksWC5vbmVycm9yPSgpPT5ZKEcoMTgpKX0pfWFzeW5jIGNoZWNrc3VtKCQpe2xldCBKO3RyeXtKPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFE9Si50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLFk9W107cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBYPVEub3BlbkN1cnNvcigpO1gub25zdWNjZXNzPSgpPT57bGV0IFc9WC5yZXN1bHQ7aWYoVyl7bGV0IHo9Vy52YWx1ZTtZLnB1c2gobSQoQ0ooeikpKSxXLmNvbnRpbnVlKCl9ZWxzZSBFJChZLCQpLnRoZW4oVil9LFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX19ZnVuY3Rpb24gbVkoJCxKKXtpZighJC5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKG4pKSQuY3JlYXRlT2JqZWN0U3RvcmUobix7a2V5UGF0aDoiZWlkIixhdXRvSW5jcmVtZW50OiExfSk7bGV0IFo9Si5vYmplY3RTdG9yZShuKTtpZighWi5pbmRleE5hbWVzLmNvbnRhaW5zKGckKSlaLmNyZWF0ZUluZGV4KGckLFsidHlwIiwiY3JkIl0se3VuaXF1ZTohMX0pO2lmKCFaLmluZGV4TmFtZXMuY29udGFpbnMoUEopKVouY3JlYXRlSW5kZXgoUEosWyJ0eXAiLCJ1cGQiXSx7dW5pcXVlOiExfSk7aWYoIVouaW5kZXhOYW1lcy5jb250YWlucyh3SikpWi5jcmVhdGVJbmRleCh3SixbInR5cCIsImdpZCJdLHt1bmlxdWU6ITF9KTtpZighWi5pbmRleE5hbWVzLmNvbnRhaW5zKFRKKSlaLmNyZWF0ZUluZGV4KFRKLFsidHlwIiwicGlkIl0se3VuaXF1ZTohMX0pO2lmKFouaW5kZXhOYW1lcy5jb250YWlucyhzMCkpe2lmKFouaW5kZXgoczApLmtleVBhdGghPT0idGdzIilaLmRlbGV0ZUluZGV4KHMwKX1pZighWi5pbmRleE5hbWVzLmNvbnRhaW5zKHMwKSlaLmNyZWF0ZUluZGV4KHMwLCJ0Z3MiLHt1bmlxdWU6ITEsbXVsdGlFbnRyeTohMH0pfWZ1bmN0aW9uIFNZKCl7cmV0dXJuIG5ldyBQcm9taXNlKCgkLEopPT57bGV0IFo9aW5kZXhlZERCLm9wZW4odVoscFopO1oub251cGdyYWRlbmVlZGVkPSgpPT57bGV0e3Jlc3VsdDpRLHRyYW5zYWN0aW9uOll9PVo7aWYoIVkpe0ooRXJyb3IoIlRyYW5zYWN0aW9uIGlzIG51bGwgZHVyaW5nIEVudERCIHVwZ3JhZGUiKSk7cmV0dXJufXRyeXttWShRLFkpfWNhdGNoKFYpe0ooViBpbnN0YW5jZW9mIEVycm9yP1Y6RXJyb3IoU3RyaW5nKFYpKSl9fSxaLm9uYmxvY2tlZD0oKT0+e2NvbnNvbGUud2FybihgW0RJUExPTUFUSUNdIEVudERCIElEQiB1cGdyYWRlIGJsb2NrZWQgKCR7dVp9IOKGkiB2JHtwWn0pOyB3YWl0aW5nIGZvciBvdGhlciBjb25uZWN0aW9ucyB0byBjbG9zZWApfSxaLm9uc3VjY2Vzcz0oKT0+JChaLnJlc3VsdCksWi5vbmVycm9yPSgpPT5KKFouZXJyb3I/P0Vycm9yKCJFbnREQiBJbmRleGVkREIgb3BlbiBmYWlsZWQiKSl9KX1hc3luYyBmdW5jdGlvbiBuWigpe2xldCAkPW5ldyBjWjtyZXR1cm4gYXdhaXQgJC5pbml0KCksJH1jbGFzcyBqSntlbnRzPW5ldyBNYXA7dXNlSW5kZXg7YnlUeXBlPW5ldyBNYXA7YnlUeXBlUGlkPW5ldyBNYXA7YnlUeXBlR2lkPW5ldyBNYXA7YnlUeXBlVGFnPW5ldyBNYXA7Y29uc3RydWN0b3IoJD1bXSxKKXt0aGlzLnVzZUluZGV4PUo/LmluZGV4ZXMhPT0hMTtmb3IobGV0IFogb2YgJCl0aGlzLnB1dChaKX1wdXQoJCl7bGV0IEo9QigkLmVpZCksWj10aGlzLmVudHMuZ2V0KEopO2lmKFohPT12b2lkIDAmJmwoWikpdGhpcy51bmluZGV4KEosWik7aWYodGhpcy5lbnRzLnNldChKLCQpLGwoJCkpdGhpcy5pbmRleChKLCQpfWRlbCgkKXtsZXQgSj10aGlzLmVudHMuZ2V0KCQpO2lmKEo9PT12b2lkIDApcmV0dXJuO2lmKGwoSikpdGhpcy51bmluZGV4KCQsSik7dGhpcy5lbnRzLmRlbGV0ZSgkKX1pbmRleCgkLEope2lmKCF0aGlzLnVzZUluZGV4KXJldHVybjtsZXQgWj10aGlzLmJ5VHlwZS5nZXQoSi50eXBlKTtpZighWilaPW5ldyBNYXAsdGhpcy5ieVR5cGUuc2V0KEoudHlwZSxaKTtpZihaLnNldCgkLEopLEoucGlkKXtsZXQgUT1CKEoucGlkKSxZPXRoaXMuYnlUeXBlUGlkLmdldChKLnR5cGUpO2lmKCFZKVk9bmV3IE1hcCx0aGlzLmJ5VHlwZVBpZC5zZXQoSi50eXBlLFkpO2xldCBWPVkuZ2V0KFEpO2lmKCFWKVY9bmV3IE1hcCxZLnNldChRLFYpO1Yuc2V0KCQsSil9aWYodHlwZW9mIEouZ2lkPT09InN0cmluZyIpe2xldCBRPXRoaXMuYnlUeXBlR2lkLmdldChKLnR5cGUpO2lmKCFRKVE9bmV3IE1hcCx0aGlzLmJ5VHlwZUdpZC5zZXQoSi50eXBlLFEpO2xldCBZPVEuZ2V0KEouZ2lkKTtpZighWSlZPW5ldyBNYXAsUS5zZXQoSi5naWQsWSk7WS5zZXQoJCxKKX1pZihKLnRhZ3Mpe2xldCBRPXRoaXMuYnlUeXBlVGFnLmdldChKLnR5cGUpO2lmKCFRKVE9bmV3IE1hcCx0aGlzLmJ5VHlwZVRhZy5zZXQoSi50eXBlLFEpO2ZvcihsZXQgWSBvZiBKLnRhZ3Mpe2xldCBWPVEuZ2V0KFkpO2lmKCFWKVY9bmV3IE1hcCxRLnNldChZLFYpO1Yuc2V0KCQsSil9fX11bmluZGV4KCQsSil7aWYoIXRoaXMudXNlSW5kZXgpcmV0dXJuO2xldCBaPXRoaXMuYnlUeXBlLmdldChKLnR5cGUpO2lmKFope2lmKFouZGVsZXRlKCQpLFouc2l6ZT09PTApdGhpcy5ieVR5cGUuZGVsZXRlKEoudHlwZSl9aWYoSi5waWQpe2xldCBRPUIoSi5waWQpLFk9dGhpcy5ieVR5cGVQaWQuZ2V0KEoudHlwZSksVj1ZPy5nZXQoUSk7aWYoVil7aWYoVi5kZWxldGUoJCksVi5zaXplPT09MClZPy5kZWxldGUoUSl9aWYoWSYmWS5zaXplPT09MCl0aGlzLmJ5VHlwZVBpZC5kZWxldGUoSi50eXBlKX1pZih0eXBlb2YgSi5naWQ9PT0ic3RyaW5nIil7bGV0IFE9dGhpcy5ieVR5cGVHaWQuZ2V0KEoudHlwZSksWT1RPy5nZXQoSi5naWQpO2lmKFkpe2lmKFkuZGVsZXRlKCQpLFkuc2l6ZT09PTApUT8uZGVsZXRlKEouZ2lkKX1pZihRJiZRLnNpemU9PT0wKXRoaXMuYnlUeXBlR2lkLmRlbGV0ZShKLnR5cGUpfWlmKEoudGFncyl7bGV0IFE9dGhpcy5ieVR5cGVUYWcuZ2V0KEoudHlwZSk7aWYoUSl7Zm9yKGxldCBZIG9mIEoudGFncyl7bGV0IFY9US5nZXQoWSk7aWYoVil7aWYoVi5kZWxldGUoJCksVi5zaXplPT09MClRLmRlbGV0ZShZKX19aWYoUS5zaXplPT09MCl0aGlzLmJ5VHlwZVRhZy5kZWxldGUoSi50eXBlKX19fWNsZWFySW5kZXhlcygpe3RoaXMuYnlUeXBlLmNsZWFyKCksdGhpcy5ieVR5cGVQaWQuY2xlYXIoKSx0aGlzLmJ5VHlwZUdpZC5jbGVhcigpLHRoaXMuYnlUeXBlVGFnLmNsZWFyKCl9YnVja2V0TGlzdCgkKXtpZighJHx8JC5zaXplPT09MClyZXR1cm5bXTtsZXQgSj1bXTtmb3IobGV0IFogb2YgJC52YWx1ZXMoKSlKLnB1c2goWik7cmV0dXJuIEp9YXN5bmMgYXBwbHkoJCl7bGV0IEo9bmV3IFNldCxaPVtdLFE9W107Zm9yKGxldCBZIG9mICQpe2xldCBWPUIoWS5laWQpLFg9dGhpcy5lbnRzLmdldChWKSxbVyx6XT1lMChYLFkpO2lmKHohPT0wKXtRLnB1c2goeik7Y29udGludWV9aWYoVz09PXZvaWQgMCl7US5wdXNoKDEyKTtjb250aW51ZX1mb3IobGV0IEsgb2YgJCQoWCxXKSlKLmFkZChLKTt0aGlzLnB1dChXKSxaLnB1c2goWS5laWQpLFEucHVzaCgwKX1yZXR1cm57c3RhdHM6USx0eXBlczpKLGVpZHM6Wn19YXN5bmMgY2xlYXIoKXtyZXR1cm4gdGhpcy5lbnRzLmNsZWFyKCksdGhpcy5jbGVhckluZGV4ZXMoKSwwfWFzeW5jIGdldFJvdygkKXtsZXQgSj1CKCQpLFo9dGhpcy5lbnRzLmdldChKKTtyZXR1cm4gTyhaKX1hc3luYyBnZXRFbnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRSb3coJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMHx8IWwoSikpcmV0dXJuIE8odm9pZCAwKTtyZXR1cm4gTyhKKX1hc3luYyBnZXRBbGxFbnRpdGllcyh7dHlwZTokLGdpZDpKLHBpZDpaLHRhZzpRLHVwZGF0ZWRCZXR3ZWVuOll9KXtpZih0aGlzLnVzZUluZGV4KXtpZihaIT09dm9pZCAwKXtsZXQgWD1CKFopO3JldHVybiBPKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZVBpZC5nZXQoJCk/LmdldChYKSkpfWlmKEohPT12b2lkIDApcmV0dXJuIE8odGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlR2lkLmdldCgkKT8uZ2V0KEopKSk7aWYoUSE9PXZvaWQgMClyZXR1cm4gTyh0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGVUYWcuZ2V0KCQpPy5nZXQoUSkpKTtpZihZIT09dm9pZCAwKXtsZXQgWD1bXSxXPXRoaXMuYnlUeXBlLmdldCgkKTtpZihXKXtmb3IobGV0IHogb2YgVy52YWx1ZXMoKSlpZih6LnVwZGF0ZWRBdD49WS5zdGFydCYmei51cGRhdGVkQXQ8PVkuZW5kKVgucHVzaCh6KX1yZXR1cm4gTyhYKX1yZXR1cm4gTyh0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGUuZ2V0KCQpKSl9bGV0IFY9W107aWYoWiE9PXZvaWQgMCl7Zm9yKGxldCBYIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihsKFgpJiZYLnR5cGU9PT0kJiZYLnBpZCYmcihYLnBpZCxaKSlWLnB1c2goWCl9ZWxzZSBpZihKIT09dm9pZCAwKXtmb3IobGV0IFggb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGwoWCkmJlgudHlwZT09PSQmJih0eXBlb2YgWC5naWQ9PT0ic3RyaW5nIiYmWC5naWQ9PT1KKSlWLnB1c2goWCl9ZWxzZSBpZihRIT09dm9pZCAwKXtmb3IobGV0IFggb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGwoWCkmJlgudHlwZT09PSQmJlgudGFncyYmWC50YWdzLmluY2x1ZGVzKFEpKVYucHVzaChYKX1lbHNlIGlmKFkhPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYobChYKSYmWC50eXBlPT09JCYmWC51cGRhdGVkQXQ+PVkuc3RhcnQmJlgudXBkYXRlZEF0PD1ZLmVuZClWLnB1c2goWCl9ZWxzZSBmb3IobGV0IFggb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGwoWCkmJlgudHlwZT09PSQpVi5wdXNoKFgpO3JldHVybiBPKFYpfWFzeW5jIGdldEVudGl0aWVzKCQpe2xldFtKLFpdPWF3YWl0IHRoaXMuZ2V0QWxsRW50aXRpZXMoJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7cmV0dXJuIE8oSil9YXN5bmMgY291bnRFbnRpdGllcyh7dHlwZTokfSl7aWYodGhpcy51c2VJbmRleClyZXR1cm4gTyh0aGlzLmJ5VHlwZS5nZXQoJCk/LnNpemU/PzApO2xldCBKPTA7Zm9yKGxldCBaIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihsKFopJiZaLnR5cGU9PT0kKUorPTE7cmV0dXJuIE8oSil9YXN5bmMgY2hlY2tzdW0oJCl7bGV0IEo9W107Zm9yKGxldCBaIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlKLnB1c2gobSQoWikpO3JldHVybiBFJChKLCQpfX1hc3luYyBmdW5jdGlvbiBkWigkKXtsZXQgSj1hd2FpdCBuWigpO2lmKCQ/LmNhY2hlPT09ITEpcmV0dXJuIEo7cmV0dXJuIG5ldyBESihKLHZvaWQgMCx7aW5kZXhlczokPy5pbmRleGVzfSl9Y2xhc3MgREp7bWVtO2R1cmFibGU7d2FybWVkPW5ldyBTZXQ7bGlzdGVuZXJzPW5ldyBTZXQ7Y2hhaW49UHJvbWlzZS5yZXNvbHZlKCk7Y29uc3RydWN0b3IoJCxKLFope2lmKHRoaXMuZHVyYWJsZT0kLHRoaXMubWVtPW5ldyBqSihKPz9bXSx7aW5kZXhlczpaPy5pbmRleGVzfSksSilmb3IobGV0IFEgb2YgSil0aGlzLndhcm1lZC5hZGQoUS50eXBlKX1zdWJzY3JpYmUoJCl7cmV0dXJuIHRoaXMubGlzdGVuZXJzLmFkZCgkKSwoKT0+e3RoaXMubGlzdGVuZXJzLmRlbGV0ZSgkKX19ZW1pdCgkKXtpZigkLnNpemU8MSlyZXR1cm47Zm9yKGxldCBKIG9mIHRoaXMubGlzdGVuZXJzKUooJCl9cnVuKCQpe2xldCBKPXRoaXMuY2hhaW4udGhlbigkLCQpO3JldHVybiB0aGlzLmNoYWluPUoudGhlbigoKT0+e3JldHVybn0sKCk9PntyZXR1cm59KSxKfWFwcGx5KCQpe3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57YXdhaXQgdGhpcy5wdWxsRWlkcygkLm1hcCgoVik9PlYuZWlkKSk7bGV0IEo9bFkodGhpcy5tZW0sJCk7dGhpcy5lbWl0KEoudHlwZXMpO2xldCBaPWF3YWl0IHRoaXMuZHVyYWJsZS5hcHBseSgkKSx7Y2hhbmdlZDpRLHN0YXR1czpZfT1hd2FpdCB0aGlzLnB1bGxFaWRzKCQubWFwKChWKT0+Vi5laWQpKTtpZih0aGlzLmVtaXQoUSksWSE9PTApcmV0dXJue3N0YXRzOiQubWFwKCgpPT5ZKSx0eXBlczpaLnR5cGVzLGVpZHM6Wi5laWRzfTtyZXR1cm4gWn0pfWNsZWFyKCl7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9PntsZXQgJD1hd2FpdCB0aGlzLmR1cmFibGUuY2xlYXIoKTtpZigkIT09MClyZXR1cm4gJDtsZXQgSj10aGlzLm1lbS5lbnRzLnNpemU+MDtyZXR1cm4gYXdhaXQgdGhpcy5tZW0uY2xlYXIoKSx0aGlzLndhcm1lZC5jbGVhcigpLDB9KX1pbmdlc3RGcm9tRHVyYWJsZSgkKXtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2xldHtjaGFuZ2VkOkosc3RhdHVzOlp9PWF3YWl0IHRoaXMucHVsbEVpZHMoJCk7cmV0dXJuIHRoaXMuZW1pdChKKSxafSl9YXN5bmMgcHVsbEVpZHMoJCl7bGV0IEo9bmV3IFNldCxaPW5ldyBTZXQ7Zm9yKGxldCBRIG9mICQpe2xldCBZPUIoUSk7aWYoWi5oYXMoWSkpY29udGludWU7Wi5hZGQoWSk7bGV0IFY9dGhpcy5tZW0uZW50cy5nZXQoWSksW1gsV109YXdhaXQgdGhpcy5kdXJhYmxlLmdldFJvdyhRKTtpZihXIT09MClyZXR1cm57Y2hhbmdlZDpKLHN0YXR1czpXfTtpZihYKXtpZih0aGlzLm1lbS5wdXQoWCksIVZ8fCF2WShWLFgpKXtpZihsKFgpKUouYWRkKFgudHlwZSk7aWYoViE9PXZvaWQgMCYmbChWKSlKLmFkZChWLnR5cGUpfX1lbHNlIGlmKFYhPT12b2lkIDApe2lmKHRoaXMubWVtLmRlbChZKSxsKFYpKUouYWRkKFYudHlwZSl9fXJldHVybntjaGFuZ2VkOkosc3RhdHVzOjB9fWFzeW5jIHdhcm1UeXBlKCQpe2lmKHRoaXMud2FybWVkLmhhcygkKSlyZXR1cm4gMDtsZXRbSixaXT1hd2FpdCB0aGlzLmR1cmFibGUuZ2V0RW50aXRpZXMoe3R5cGU6JH0pO2lmKFohPT0wKXJldHVybiBaO2lmKEopZm9yKGxldCBRIG9mIEope2xldCBZPUIoUS5laWQpLFY9dGhpcy5tZW0uZW50cy5nZXQoWSk7aWYoIVZ8fGlZKFEsVikpdGhpcy5tZW0ucHV0KFEpfXJldHVybiB0aGlzLndhcm1lZC5hZGQoJCksMH1hc3luYyBnZXRSb3coJCl7bGV0IEo9QigkKTtpZih0aGlzLm1lbS5lbnRzLmhhcyhKKSlyZXR1cm4gdGhpcy5tZW0uZ2V0Um93KCQpO3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57aWYodGhpcy5tZW0uZW50cy5oYXMoSikpcmV0dXJuIHRoaXMubWVtLmdldFJvdygkKTtsZXRbWixRXT1hd2FpdCB0aGlzLmR1cmFibGUuZ2V0Um93KCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFopdGhpcy5tZW0ucHV0KFopO3JldHVybiBPKFopfSl9YXN5bmMgZ2V0RW50KCQpe2xldFtKLFpdPWF3YWl0IHRoaXMuZ2V0Um93KCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDB8fCFsKEopKXJldHVybiBPKHZvaWQgMCk7cmV0dXJuIE8oSil9YXN5bmMgZ2V0RW50aXRpZXMoJCl7aWYoIXRoaXMud2FybWVkLmhhcygkLnR5cGUpKXtsZXQgSj1hd2FpdCB0aGlzLnJ1bigoKT0+dGhpcy53YXJtVHlwZSgkLnR5cGUpKTtpZihKIT09MClyZXR1cm4gRyhKKX1yZXR1cm4gdGhpcy5tZW0uZ2V0RW50aXRpZXMoJCl9YXN5bmMgY291bnRFbnRpdGllcyh7dHlwZTokfSl7aWYoIXRoaXMud2FybWVkLmhhcygkKSl7bGV0IEo9YXdhaXQgdGhpcy5ydW4oKCk9PnRoaXMud2FybVR5cGUoJCkpO2lmKEohPT0wKXJldHVybiBHKEopfXJldHVybiB0aGlzLm1lbS5jb3VudEVudGl0aWVzKHt0eXBlOiR9KX1hc3luYyBjaGVja3N1bSgkKXtyZXR1cm4gdGhpcy5kdXJhYmxlLmNoZWNrc3VtKCQpfX1mdW5jdGlvbiB2WSgkLEope2lmKGwoJCkhPT1sKEopKXJldHVybiExO2lmKCQuY3RyIT09Si5jdHIpcmV0dXJuITE7aWYoJC51cGRhdGVkQXQuZ2V0VGltZSgpIT09Si51cGRhdGVkQXQuZ2V0VGltZSgpKXJldHVybiExO2lmKCFyKCQuZWlkLEouZWlkKSlyZXR1cm4hMTtpZighbCgkKXx8IWwoSikpcmV0dXJuITA7aWYoJC5jcmVhdGVkQXQuZ2V0VGltZSgpIT09Si5jcmVhdGVkQXQuZ2V0VGltZSgpKXJldHVybiExO2lmKCQudHlwZSE9PUoudHlwZSlyZXR1cm4hMTtpZigkLmdpZCE9PUouZ2lkKXJldHVybiExO2lmKCFiWSgkLnBpZCxKLnBpZCkpcmV0dXJuITE7aWYoIXlZKCQudGFncyxKLnRhZ3MpKXJldHVybiExO3JldHVybiBoWSgkLmJvZHksSi5ib2R5KX1mdW5jdGlvbiB5WSgkLEope2lmKCQ9PT1KKXJldHVybiEwO2lmKCQ9PT12b2lkIDB8fEo9PT12b2lkIDApcmV0dXJuITE7aWYoJC5sZW5ndGghPT1KLmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IFo9MDtaPCQubGVuZ3RoO1orKylpZigkW1pdIT09SltaXSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBiWSgkLEope2lmKCQ9PT12b2lkIDAmJko9PT12b2lkIDApcmV0dXJuITA7aWYoJD09PXZvaWQgMHx8Sj09PXZvaWQgMClyZXR1cm4hMTtyZXR1cm4gcigkLEopfWZ1bmN0aW9uIGhZKCQsSil7aWYoT2JqZWN0LmlzKCQsSikpcmV0dXJuITA7aWYoJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkmJkogaW5zdGFuY2VvZiBVaW50OEFycmF5KXJldHVybiByKCQsSik7aWYoJCBpbnN0YW5jZW9mIERhdGUmJkogaW5zdGFuY2VvZiBEYXRlKXJldHVybiAkLmdldFRpbWUoKT09PUouZ2V0VGltZSgpO3RyeXtyZXR1cm4gcihFMCgkKSxFMChKKSl9Y2F0Y2h7cmV0dXJuITF9fWZ1bmN0aW9uIGlZKCQsSil7bGV0IFo9JC51cGRhdGVkQXQuZ2V0VGltZSgpLFE9Si51cGRhdGVkQXQuZ2V0VGltZSgpO2lmKFohPT1RKXJldHVybiBaPlE7cmV0dXJuICQuY3RyPkouY3RyfWZ1bmN0aW9uIGxZKCQsSil7bGV0IFo9bmV3IFNldCxRPVtdO2ZvcihsZXQgWSBvZiBKKXtsZXQgVj1CKFkuZWlkKSxYPSQuZW50cy5nZXQoViksW1csel09ZTAoWCxZKTtpZih6IT09MCl7US5wdXNoKHopO2NvbnRpbnVlfWlmKFc9PT12b2lkIDApe1EucHVzaCgxMik7Y29udGludWV9Zm9yKGxldCBLIG9mICQkKFgsVykpWi5hZGQoSyk7JC5wdXQoVyksUS5wdXNoKDApfXJldHVybntzdGF0czpRLHR5cGVzOlp9fWZ1bmN0aW9uIGwoJCl7cmV0dXJuInR5cGUiaW4gJH1mdW5jdGlvbiB1WSgkKXtpZighQXJyYXkuaXNBcnJheSgkKXx8JC5sZW5ndGg9PT0wKXJldHVybjtsZXQgSj1uZXcgU2V0LFo9W107Zm9yKGxldCBRIG9mICQpe2lmKHR5cGVvZiBRIT09InN0cmluZyJ8fFEubGVuZ3RoPT09MCljb250aW51ZTtpZihKLmhhcyhRKSljb250aW51ZTtKLmFkZChRKSxaLnB1c2goUSl9cmV0dXJuIFoubGVuZ3RoPjA/Wjp2b2lkIDB9ZnVuY3Rpb24gbSQoJCl7cmV0dXJue2VpZDokLmVpZCxjdHI6JC5jdHIsdXBkYXRlZEF0OiQudXBkYXRlZEF0fX1mdW5jdGlvbiByWigkKXtsZXQgSj1uZXcgbSgkLmVpZCksW1osUV09Si5yZWFkU3RydWN0KFYwKTtpZihRIT09MClyZXR1cm4gRyhRKTtyZXR1cm4gTyh7ZWlkOiQuZWlkLGN0cjokLmN0cix1cGRhdGVkQXQ6bmV3IERhdGUoWi50cy5nZXRUaW1lKCkrJC5vZmYpfSl9ZnVuY3Rpb24gZTAoJCxKKXtsZXQgWj1uZXcgbShKLmVpZCksW1EsWV09Wi5yZWFkU3RydWN0KFYwKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXQgVj1uZXcgRGF0ZShRLnRzLmdldFRpbWUoKStKLm9mZik7aWYoJCE9PXZvaWQgMCYmVjw9JC51cGRhdGVkQXQpcmV0dXJuIEcoMTUpO2lmKGxaKEopKXtsZXQgWD11WShKLnRhZ3MpO3JldHVybiBPKHtlaWQ6Si5laWQsZ2lkOkouZ2lkLHBpZDpKLnBpZCwuLi5YIT09dm9pZCAwP3t0YWdzOlh9Ont9LHR5cGU6Si50eXBlLGNyZWF0ZWRBdDpRLnRzLHVwZGF0ZWRBdDpWLGN0cjpKLmN0cixib2R5OkouYm9keX0pfXJldHVybiBPKHtlaWQ6Si5laWQsdXBkYXRlZEF0OlYsY3RyOkouY3RyfSl9ZnVuY3Rpb24gJCQoJCxKKXtsZXQgWj1uZXcgU2V0O2lmKCQhPT12b2lkIDAmJmwoJCkpWi5hZGQoJC50eXBlKTtpZihsKEopKVouYWRkKEoudHlwZSk7cmV0dXJuWy4uLlpdfWNsYXNzIFMke2luZmxpZ2h0PW51bGw7YWdhaW49ITE7cnVuKCQpe2lmKHRoaXMuYWdhaW49ITAsdGhpcy5pbmZsaWdodClyZXR1cm4gdGhpcy5pbmZsaWdodDtyZXR1cm4gdGhpcy5pbmZsaWdodD10aGlzLmRyYWluKCQpLHRoaXMuaW5mbGlnaHR9YXN5bmMgZmx1c2goKXtpZighdGhpcy5pbmZsaWdodClyZXR1cm47dHJ5e2F3YWl0IHRoaXMuaW5mbGlnaHR9Y2F0Y2h7fX1hc3luYyBkcmFpbigkKXt0cnl7dGhpcy5hZ2Fpbj0hMTtsZXQgSj1hd2FpdCAkKCk7d2hpbGUodGhpcy5hZ2Fpbil0aGlzLmFnYWluPSExLEo9YXdhaXQgJCgpO3JldHVybiBKfWZpbmFsbHl7dGhpcy5pbmZsaWdodD1udWxsfX19dmFyIG9aPTEwMDtjbGFzcyBBSnt0aW1lcj1udWxsO2RlbGF5TXM7d29yazt0YWlsPW5ldyBTJDtjb25zdHJ1Y3RvcigkLEope3RoaXMuZGVsYXlNcz0kPDA/MDokLHRoaXMud29yaz1KfXNjaGVkdWxlKCl7aWYodGhpcy5kZWxheU1zPD0wKXt0aGlzLmZpcmUoKTtyZXR1cm59aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpO3RoaXMudGltZXI9c2V0VGltZW91dCgoKT0+e3RoaXMudGltZXI9bnVsbCx0aGlzLmZpcmUoKX0sdGhpcy5kZWxheU1zKX1hc3luYyBmbHVzaCgpe2lmKHRoaXMudGltZXIhPT1udWxsKWNsZWFyVGltZW91dCh0aGlzLnRpbWVyKSx0aGlzLnRpbWVyPW51bGwsdGhpcy5maXJlKCk7YXdhaXQgdGhpcy50YWlsLmZsdXNoKCl9Y2FuY2VsKCl7aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLHRoaXMudGltZXI9bnVsbH1maXJlKCl7cmV0dXJuIHRoaXMudGFpbC5ydW4odGhpcy53b3JrKX19ZnVuY3Rpb24gYVooJCl7bGV0IEo9bmV3IG0oJC5laWQpLFtaLFFdPVYwLmRlY29kZShKKTtpZihRIT09MClyZXR1cm47cmV0dXJuIFoudHMuZ2V0VGltZSgpKyQub2ZmfWZ1bmN0aW9uIHBZKCQsSil7bGV0IFo9YVooJCksUT1hWihKKTtpZihaPT09dm9pZCAwJiZRPT09dm9pZCAwKXJldHVybiAwO2lmKFo9PT12b2lkIDApcmV0dXJuIDE7aWYoUT09PXZvaWQgMClyZXR1cm4tMTtpZihRIT09WilyZXR1cm4gUS1aO3JldHVybiBKLmN0ci0kLmN0cn1mdW5jdGlvbiBKJCgkLEope3JldHVybiAkLnNsaWNlKCkuc29ydCgoWixRKT0+cFkoSihaKSxKKFEpKSl9dmFyIF9KPXtwaGFzZToiaWRsZSJ9LE8kPTUwO2Z1bmN0aW9uIExKKCQsSixaKXtpZigkPD0wfHxKPD0wKXJldHVybiExO2lmKCQ9PT0xfHwkPT09SilyZXR1cm4hMDtyZXR1cm4gJCVaPT09MH1mdW5jdGlvbiBzWigkLEope2lmKHR5cGVvZiBuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYj09PSJmdW5jdGlvbiIpe25hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iKCQsSik7cmV0dXJufWxldCBaPVVSTC5jcmVhdGVPYmplY3RVUkwoJCksUT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7US5ocmVmPVosUS5kb3dubG9hZD1KLGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoUSksUS5jbGljaygpLGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoUSksVVJMLnJldm9rZU9iamVjdFVSTChaKX1mdW5jdGlvbiB0WigkLEosWil7bGV0IFE9W10sWT1bXSxWPTA7Zm9yKGxldCBYIG9mICQpe2xldCBXPUooWCk7aWYoWS5sZW5ndGg+MCYmVitXPlopUS5wdXNoKFkpLFk9W10sVj0wO2lmKFkucHVzaChYKSxWKz1XLFY+PVopUS5wdXNoKFkpLFk9W10sVj0wfWlmKFkubGVuZ3RoPjApUS5wdXNoKFkpO3JldHVybiBRfWFzeW5jIGZ1bmN0aW9uIHhKKCQsSixaKXtsZXQgUT0kLmxlbmd0aDtpZihRPDEpcmV0dXJuW107bGV0IFk9QXJyYXkoUSksVj0wLFg9TWF0aC5taW4oTWF0aC5tYXgoMSxKKSxRKSxXPWFzeW5jKCk9Pnt3aGlsZSghMCl7bGV0IEs9VjtpZihWKz0xLEs+PVEpcmV0dXJuO1lbS109YXdhaXQgWigkW0tdLEspfX0sej1bXTtmb3IobGV0IEs9MDtLPFg7SysrKXoucHVzaChXKCkpO3JldHVybiBhd2FpdCBQcm9taXNlLmFsbCh6KSxZfWFzeW5jIGZ1bmN0aW9uIHYkKCQsSixaLFEpe2xldCBZPW5ldyBtKCQuaGVhZENwaCksW1YsWF09WS5yZWFkU3RydWN0KEwkKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXR7c2lnOlcsa2RtOnosaGVhZENwaDpLfT1WO2lmKCFhd2FpdCBRLmNoZWNrU2lnRWQyNTUxOShXLEssSikpcmV0dXJuIEcoMyk7bGV0IE49Wi5kZXJpdmVDaXBoZXIoeiwiZGVjcnlwdCIpLFU7dHJ5e1U9YXdhaXQgTi5kZWNyeXB0KEspfWNhdGNoe3JldHVybiBHKDIwKX1yZXR1cm4gTyh7a2RtOnosaGVhZEVuYzpVfSl9dmFyIFEkPSJmIix5JD0idCIsWiQ9ImUiO2Z1bmN0aW9uIGNZKCQpe2lmKCQ9PT0hMHx8JD09PXkkKXJldHVybiB5JDtpZigkPT09WiQpcmV0dXJuIFokO3JldHVybiBRJH1mdW5jdGlvbiBlWigkKXtyZXR1cm4gJCE9PTAmJiQhPT0xNSYmJCE9PTE4JiYkIT09MTd9ZnVuY3Rpb24gQkooJCxKLFope2lmKCQuYXBsZD1KLEo9PT1aJCYmWiE9PXZvaWQgMCkkLmVycj1aO2Vsc2UgZGVsZXRlICQuZXJyfWFzeW5jIGZ1bmN0aW9uIGIkKCQsSixaLFEpe2xldCBZPVE/LmJvZHkhPT0hMSxWPWNZKEouYXBsZCksWD1KLmJvZHksVz1YPy5sZW5ndGg/PzAsejtpZihZJiZYJiZXPjApej1hd2FpdCBaLmJsYWtlMyhYKTtsZXQgSz17ZWlkOkouZWlkLG9mZjpKLm9mZj8/MCxjdHI6Si5jdHI/PzAsbGVuOlcsaHNoOnp9LEY9e2hhc2g6JCxoZWFkOkssYXBsZDpWfTtpZihZJiZYIT09dm9pZCAwKUYuYm9keT1YO2lmKFY9PT1aJCYmSi5lcnIhPT12b2lkIDApRi5lcnI9Si5lcnI7cmV0dXJuIEZ9dmFyIGtKPTEwNDg1NzYsRUo9MTA0ODU3NixKUT02NDtmdW5jdGlvbiBuWSgkKXtyZXR1cm4gJC5zaWcubGVuZ3RoKyQua2RtLmxlbmd0aCskLmhlYWRDcGgubGVuZ3RoKyQuYm9keUNwaC5sZW5ndGh9YXN5bmMgZnVuY3Rpb24gZFkoJCxKLFosUSxZKXtpZihRLmxlbmd0aDwxKXJldHVybiAwO2xldFtWLFhdPWF3YWl0ICQucHVzaChRKTtpZihYIT09MClyZXR1cm4gWDtpZighVilyZXR1cm4gMjc7Zm9yKGxldCB6IG9mIFYpe2lmKHouc3RhdHVzIT09MCl7Y29uc29sZS5lcnJvcigicHVzaCBlcnIiLHopO2NvbnRpbnVlfWxldCBLPVlbei5pZHhdO2lmKCFLKXtjb25zb2xlLmVycm9yKCJubyBoYXNoIix6KTtjb250aW51ZX1hd2FpdCBKLnVwbG9hZHMuZGVxKFosW0tdKX1sZXQgVz1hd2FpdCBKLmhvc3RzLmdldChaKTtpZihXKXtsZXQgej1XLmxhc3RTZXEsSz16LEY9W107Zm9yKGxldCBOIG9mIFYpaWYoTi5zdGF0dXM9PT0wKUYucHVzaChOLnNlcSk7Ri5zb3J0KChOLFUpPT5OLVUpO2ZvcihsZXQgTiBvZiBGKWlmKE49PT16KzEpej1OO2lmKHo+Sylhd2FpdCBKLmhvc3RzLnRvdWNoKFoseil9cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gJFEoJCxKKXtpZihKLmxlbmd0aDwxKXJldHVybiBPKFtdKTtsZXQgWj1uZXcgTWFwLFE9W107Zm9yKGxldCBXIG9mIEopWi5zZXQoVy5zZXEsVyksUS5wdXNoKFcuc2VxKTtsZXRbWSxWXT1hd2FpdCAkLnB1bGwoUSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoIVkpcmV0dXJuIEcoMjcpO2xldCBYPVtdO2ZvcihsZXR7c2VxOlcsYm9keUNwaDp6fW9mIFkpe2xldCBLPVouZ2V0KFcpO2lmKCFLKWNvbnRpbnVlO1gucHVzaCh7ZGw6Syxib2R5Q3BoOnp9KX1yZXR1cm4gTyhYKX1hc3luYyBmdW5jdGlvbiByWSgkLEosWixRKXtpZihRLmxlbmd0aDwxKXJldHVybiBPKHtwYXJ0czpbXSxoYXNoZXM6W119KTtsZXQgWT1bXSxWPVtdLFg9W10sVz1uZXcgTWFwO2ZvcihsZXR7ZGw6Syxib2R5Q3BoOkZ9b2YgUSl7bGV0e2hlYWQ6TixrZG06VSxzZXE6Uixob3N0OnF9PUssW0gsTV09YXdhaXQgWlEoSyxaKTtpZihNIT09MHx8IUgpe2xldCBrPVcuZ2V0KHEpPz9bXTtrLnB1c2goUiksVy5zZXQocSxrKTtjb250aW51ZX1sZXR7aGVhZEVuYzpQLGhlYWRFbmNIYXNoOkN9PUgsVD1KLmRlcml2ZUNpcGhlcihVLCJkZWNyeXB0IiksW0ksQV09YXdhaXQgS0ooUCxGLFQsWixDKTtpZihBIT09MHx8IUkpe2xldCBrPVcuZ2V0KHEpPz9bXTtrLnB1c2goUiksVy5zZXQocSxrKTtjb250aW51ZX1sZXQgTD17aGVhZDpOLGJvZHk6SS5ib2R9LGc9SS5oZWFkSGFzaDtYLnB1c2goe2tleTpnLGRhdGE6VlEoTCl9KSxZLnB1c2goTCksVi5wdXNoKGcpO2xldCBmPVcuZ2V0KHEpPz9bXTtmLnB1c2goUiksVy5zZXQocSxmKX1sZXQgej1hd2FpdCAkLm1lc3NhZ2VzLmFkZChYKTtmb3IobGV0W0ssRl1vZiBXKWF3YWl0ICQuZG93bmxvYWRzLmRlcShLLEYpO2ZvcihsZXQgSz0wO0s8ei5sZW5ndGg7SysrKXtsZXQgRj16W0tdO2lmKEYhPT0wJiZGIT09MTUpY29uc29sZS5lcnJvcigiRVJSIHN0b3JpbmciLERbRl0sImZvciBtZXNzYWdlIixLKX1yZXR1cm4gTyh7cGFydHM6WSxoYXNoZXM6Vn0pfWFzeW5jIGZ1bmN0aW9uIFpRKCQsSil7bGV0IFo9JC5oZWFkRW5jO2lmKCFaKXtsZXQgWT1uZXcgUyxWPVkud3JpdGVTdHJ1Y3QoRzAsJC5oZWFkKTtpZihWIT09MClyZXR1cm4gRyhWKTtaPVkucmVzdWx0KCl9aWYoJC5oZWFkRW5jSGFzaClyZXR1cm4gTyh7aGVhZEVuYzpaLGhlYWRFbmNIYXNoOiQuaGVhZEVuY0hhc2h9KTtsZXQgUT1hd2FpdCBKLmJsYWtlMyhaKTtyZXR1cm4gTyh7aGVhZEVuYzpaLGhlYWRFbmNIYXNoOlF9KX1hc3luYyBmdW5jdGlvbiBRUSgkLEosWil7bGV0IFE9bmV3IFNldDtmb3IobGV0IFggb2YgSilRLmFkZChCKFgpKTtpZihRLnNpemU8MSlyZXR1cm47bGV0IFk9QXJyYXkuZnJvbShhd2FpdCAkLmRvd25sb2Fkcy5saXN0KCkpO2lmKFkubGVuZ3RoPDEpcmV0dXJuO2xldCBWPW5ldyBNYXA7Zm9yKGxldCBYIG9mIFkpe2xldCBXO2lmKFguaGVhZEVuY0hhc2gpVz1CKFguaGVhZEVuY0hhc2gpO2Vsc2V7bGV0W0ssRl09YXdhaXQgWlEoWCxaKTtpZihGIT09MHx8IUspY29udGludWU7Vz1CKEsuaGVhZEVuY0hhc2gpfWlmKCFRLmhhcyhXKSljb250aW51ZTtsZXQgej1WLmdldChYLmhvc3QpPz9bXTt6LnB1c2goWC5zZXEpLFYuc2V0KFguaG9zdCx6KX1mb3IobGV0W1gsV11vZiBWKWF3YWl0ICQuZG93bmxvYWRzLmRlcShYLFcpfWFzeW5jIGZ1bmN0aW9uIGZKKHtjb25uOiQsc3RvcmU6SixlbmNsYXZlOlosaG9zdDpRLGNyeXB0bzpZLG9uUHJvZ3Jlc3M6VixwZWVrUHJvZ3Jlc3NFdmVyeTpYLHBlZWtDb25jdXJyZW5jeTpXfSl7bGV0IHo9YXdhaXQgJC5pZGVudGl0eSgpLEs9W10sW0YsTl09YXdhaXQgJC5wZWVrKFEubGFzdFNlcSk7aWYoTiE9PTApcmV0dXJuIE47bGV0IFU9Ri5sZW5ndGgsUj1YPz9PJCxxPVc/P0pRO2lmKFYmJlU+MClWKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6MCx0b3RhbDpVfSk7bGV0IEg9MCxNPWF3YWl0IHhKKEYscSxhc3luYyhDKT0+e2xldFtULEldPWF3YWl0IHYkKEMsei5wdWJsaWNLZXksWixZKSxBO2lmKEkhPT0wfHwhVClBPXtvazohMSxzZXE6Qy5zZXEsc3RhdDpJfTtlbHNle2xldCBMPWF3YWl0IFkuYmxha2UzKFQuaGVhZEVuYyk7QT17b2s6ITAsc2VxOkMuc2VxLGtkbTpULmtkbSxoZWFkRW5jOlQuaGVhZEVuYyxoZWFkRW5jSGFzaDpMfX1pZihIKz0xLFYmJkxKKEgsVSxSKSlWKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6SCx0b3RhbDpVfSk7cmV0dXJuIEF9KSxQPW5ldyBTZXQ7Zm9yKGxldCBDIG9mIE0pe2lmKCFDLm9rKXtjb25zb2xlLmVycm9yKCJwZWVrOiBkZWNyeXB0aW5nIGl0ZW0gaGVhZCIsQy5zdGF0KTtjb250aW51ZX1sZXQgVD1CKEMuaGVhZEVuY0hhc2gpO2lmKGF3YWl0IEoubWVzc2FnZXMuaGFzKEMuaGVhZEVuY0hhc2gpKXtjb25zb2xlLmluZm8oInBlZWs6IGxvY2FsIG1zZzsgc2tpcCBkb3dubG9hZCwgZGVxIHVwbG9hZCIpLGF3YWl0IEoudXBsb2Fkcy5kZXEoUS5sYWJlbCxbQy5oZWFkRW5jSGFzaF0pLGF3YWl0IEouZG93bmxvYWRzLmRlcShRLmxhYmVsLFtDLnNlcV0pO2NvbnRpbnVlfWlmKFAuaGFzKFQpKXthd2FpdCBKLmRvd25sb2Fkcy5kZXEoUS5sYWJlbCxbQy5zZXFdKTtjb250aW51ZX1sZXQgQT1uZXcgbShDLmhlYWRFbmMpLFtMLGddPUEucmVhZFN0cnVjdChHMCk7aWYoZyE9PTApe2NvbnNvbGUuZXJyb3IoInBlZWs6IHJlYWRpbmcgaXRlbSBoZWFkIixnKTtjb250aW51ZX1QLmFkZChUKSxLLnB1c2goe2tkbTpDLmtkbSxoZWFkOkwsc2VxOkMuc2VxLGhvc3Q6US5sYWJlbCxoZWFkRW5jOkMuaGVhZEVuYyxoZWFkRW5jSGFzaDpDLmhlYWRFbmNIYXNofSl9aWYoYXdhaXQgSi5kb3dubG9hZHMuZW5xKEspLEYubGVuZ3RoPjApe2xldCBDPU1hdGgubWF4KC4uLkYubWFwKChUKT0+VC5zZXEpKTthd2FpdCBKLmhvc3RzLnJlY29yZFN0YXRzKFEubGFiZWwse2xhc3RTZXE6Q30pfWlmKFYpVih7cGhhc2U6InBlZWsiLGhvc3Q6US5sYWJlbCxkb25lOlUsdG90YWw6VX0pO3JldHVybiAwfWFzeW5jIGZ1bmN0aW9uIFlRKHtjb25uOiQsc3RvcmU6Sixob3N0OlosbWF4UHVzaEJ5dGVzOlEsb25Qcm9ncmVzczpZfSl7bGV0IFY9UT8/a0osWD1hd2FpdCBKLnVwbG9hZHMubGlzdChaLmxhYmVsKSxXPVgubGVuZ3RoLHo9MDtpZihZJiZXPjApWSh7cGhhc2U6InB1c2giLGhvc3Q6Wi5sYWJlbCxkb25lOjAsdG90YWw6V30pO2xldCBLPVtdLEY9W10sTj0wLFU9YXN5bmMoKT0+e2lmKEsubGVuZ3RoPDEpcmV0dXJuIDA7bGV0IFI9Sy5sZW5ndGgscT1hd2FpdCBkWSgkLEosWi5sYWJlbCxLLEYpO2lmKEs9W10sRj1bXSxOPTAscT09PTApe2lmKHorPVIsWSlZKHtwaGFzZToicHVzaCIsaG9zdDpaLmxhYmVsLGRvbmU6eix0b3RhbDpXfSl9cmV0dXJuIHF9O2ZvcihsZXQgUiBvZiBYKXtsZXQgcT1hd2FpdCBKLm1lc3NhZ2VzLmdldChSKTtpZighcSl7eis9MTtjb250aW51ZX1sZXQgSD17Li4ucS5oZWFkLGJvZDpxLmJvZHl9LFtNLFBdPWF3YWl0ICQuc2VhbChIKTtpZihQIT09MClyZXR1cm4gUDtpZighTSlyZXR1cm4gMTI7bGV0IEM9blkoTSk7aWYoSy5sZW5ndGg+MCYmTitDPlYpe2xldCBUPWF3YWl0IFUoKTtpZihUIT09MClyZXR1cm4gVH1pZihLLnB1c2goTSksRi5wdXNoKFIpLE4rPUMsTj49Vil7bGV0IFQ9YXdhaXQgVSgpO2lmKFQhPT0wKXJldHVybiBUfX1yZXR1cm4gVSgpfWFzeW5jIGZ1bmN0aW9uIGdKKHtjb25uOiQsc3RvcmU6SixlbmNsYXZlOlosaG9zdDpRLGNyeXB0bzpZLG1heFB1bGxCeXRlczpWLG9uUHJvZ3Jlc3M6WH0sVyl7bGV0IHo9Vj8/RUosSz1hd2FpdCBKLmRvd25sb2Fkcy5saXN0KCksRj1BcnJheS5mcm9tKEspLmZpbHRlcigoTSk9Pk0uaG9zdD09PVEubGFiZWwpO2lmKEYubGVuZ3RoPDEpcmV0dXJuIDE1O2xldCBOPUokKEYsKE0pPT5NLmhlYWQpLFU9dFooTiwoTSk9Pk0uaGVhZC5sZW4seiksUj1OLmxlbmd0aCxxPTA7aWYoWClYKHtwaGFzZToicHVsbCIsaG9zdDpRLmxhYmVsLGRvbmU6MCx0b3RhbDpSfSk7bGV0IEg9JFEoJCxVWzBdKTtmb3IobGV0IE09MDtNPFUubGVuZ3RoO00rKyl7bGV0W1AsQ109YXdhaXQgSDtpZihDIT09MHx8IVApcmV0dXJuIEM7aWYocSs9VVtNXS5sZW5ndGgsWClYKHtwaGFzZToicHVsbCIsaG9zdDpRLmxhYmVsLGRvbmU6cSx0b3RhbDpSfSk7bGV0IFQ9VVtNKzFdO2lmKFQpSD0kUSgkLFQpO2lmKFgpWCh7cGhhc2U6Im9wZW4iLGhvc3Q6US5sYWJlbCxkb25lOnEsdG90YWw6Un0pO2xldCBJPUokKFAsKEwpPT5MLmRsLmhlYWQpLFssQV09YXdhaXQgclkoSixaLFksSSk7aWYoQSE9PTApcmV0dXJuIEE7aWYoVyl7aWYoWClYKHtwaGFzZToiZXhlYyIsaG9zdDpRLmxhYmVsLGRvbmU6cSx0b3RhbDpSfSk7YXdhaXQgVygpfX1yZXR1cm4gMH1mdW5jdGlvbiBWUSh7aGVhZDokLGJvZHk6Sn0pe2xldCBaPXtlaWQ6JC5laWQsYm9keTpKLGFwbGQ6USR9O2lmKCQub2ZmIT09MClaLm9mZj0kLm9mZjtpZigkLmN0ciE9PTApWi5jdHI9JC5jdHI7cmV0dXJuIFp9YXN5bmMgZnVuY3Rpb24gWFEoJCx7Y29ubjpKLHN0b3JlOlosZW5jbGF2ZTpRLGhvc3Q6WSxjcnlwdG86VixvblByb2dyZXNzOlh9LFcpe2xldCB6PVkubGFiZWwsSz1hd2FpdCBKLmlkZW50aXR5KCksRj1uZXcgbSgkKSxbTixVXT1GLnJlYWRTdHJ1Y3RzKF8kKTtpZihVIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIGRlY29kaW5nIG5vdGlmIixEW1VdKTtyZXR1cm59bGV0IFI9ITEsSD0oYXdhaXQgWi5ob3N0cy5nZXQoeikpPy5sYXN0U2VxLE09W10sUD0hMTtmb3IobGV0IEkgb2YgTil7bGV0W0EsTF09YXdhaXQgdiQoe3NlcTpJLnNlcSxoZWFkQ3BoOkkuaGVhZENwaH0sSy5wdWJsaWNLZXksUSxWKTtpZihMIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIGRlY3J5cHRpbmcgbm90aWYiLERbTF0pO2NvbnRpbnVlfWxldCBnPWF3YWl0IFYuYmxha2UzKEEuaGVhZEVuYyk7aWYoYXdhaXQgWi5tZXNzYWdlcy5oYXMoZykpY29udGludWU7bGV0IGY9bmV3IG0oQS5oZWFkRW5jKSxbayx5XT1mLnJlYWRTdHJ1Y3QoRzApO2lmKHkhPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgdG8gcGFyc2UgaGVhZCIsRFt5XSk7Y29udGludWV9aWYoIUkuYm9keUNwaCYmay5sZW4+MClQPSEwLGF3YWl0IFouZG93bmxvYWRzLmVucShbe3NlcTpJLnNlcSxob3N0Onosa2RtOkEua2RtLGhlYWQ6ayxoZWFkRW5jOkEuaGVhZEVuYyxoZWFkRW5jSGFzaDpnfV0pO2Vsc2UgTS5wdXNoKHsuLi5BLGhlYWQ6ayxib2R5Q3BoOkkuYm9keUNwaCxoZWFkRW5jSGFzaDpnfSk7aWYoSD09PXZvaWQgMHx8SS5zZXEhPT1IKzEpY29uc29sZS5sb2coIm91dCBvZiBzZXEiLEkuc2VxLEgpLFI9ITA7ZWxzZSBIPUkuc2VxfWlmKEghPT12b2lkIDApYXdhaXQgWi5ob3N0cy50b3VjaChZLmxhYmVsLEgpO2xldCBDPVtdO2ZvcihsZXQgSSBvZiBNKXtsZXQgQT1RLmRlcml2ZUNpcGhlcihJLmtkbSwiZGVjcnlwdCIpLFtMLGddPWF3YWl0IEtKKEkuaGVhZEVuYyxJLmJvZHlDcGgsQSxWKTtpZihnIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIHRvIG9wZW4gYm9keSIsRFtnXSk7Y29udGludWV9Qy5wdXNoKHtrZXk6SS5oZWFkRW5jSGFzaCxkYXRhOlZRKHtoZWFkOkkuaGVhZCxib2R5OkwuYm9kfSl9KX1sZXQgVD1hd2FpdCBaLm1lc3NhZ2VzLmFkZChDKTtmb3IobGV0IEk9MDtJPFQubGVuZ3RoO0krKyl7bGV0IEE9VFtJXTtpZihBIT09MCYmQSE9PTE1KWNvbnNvbGUuZXJyb3IoIkVSUiBzdG9yaW5nIixEW0FdLCJmb3IgbWVzc2FnZSIsSSl9aWYoWCYmQy5sZW5ndGg+MClYKHtwaGFzZToib3BlbiIsaG9zdDpZLmxhYmVsLGRvbmU6Qy5sZW5ndGgsdG90YWw6Qy5sZW5ndGh9KTtpZihSfHxQfHxDLmxlbmd0aD4wKVcoKX1hc3luYyBmdW5jdGlvbiBtSigkLEo9e30pe2xldCBaPUoucHVsbCE9PSExLFE9Si5wdXNoPT09ITAse2Nvbm46WSxzdG9yZTpWLGVuY2xhdmU6WCxob3N0OlcsY3J5cHRvOnosb25Qcm9ncmVzczpLLHBlZWtQcm9ncmVzc0V2ZXJ5OkYscGVla0NvbmN1cnJlbmN5Ok59PSQsVT1hd2FpdCBZLmlkZW50aXR5KCksW1IscV09YXdhaXQgWS5wZWVrKDApO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldCBIPVIubGVuZ3RoLE09Rj8/TyQsUD1OPz9KUTtpZihLJiZIPjApSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOjAsdG90YWw6SH0pO2xldCBDPTAsVD1hd2FpdCB4SihSLFAsYXN5bmMoeCk9PntsZXRbdixFXT1hd2FpdCB2JCh4LFUucHVibGljS2V5LFgseiksaTtpZihFIT09MHx8IXYpaT17b2s6ITEsc2VxOnguc2VxLHN0YXQ6RX07ZWxzZXtsZXQgXz1hd2FpdCB6LmJsYWtlMyh2LmhlYWRFbmMpO2k9e29rOiEwLHNlcTp4LnNlcSxrZG06di5rZG0saGVhZEVuYzp2LmhlYWRFbmMsaGVhZEVuY0hhc2g6X319aWYoQys9MSxLJiZMSihDLEgsTSkpSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOkMsdG90YWw6SH0pO3JldHVybiBpfSksST1uZXcgTWFwO2ZvcihsZXQgeCBvZiBUKXtpZigheC5vayljb250aW51ZTtsZXQgdj1CKHguaGVhZEVuY0hhc2gpLEU9SS5nZXQodik7aWYoRSlFLmNvdW50Kz0xO2Vsc2UgSS5zZXQodix7aGFzaDp4LmhlYWRFbmNIYXNoLGNvdW50OjEsc2FtcGxlOnh9KX1sZXQgQT0wLEw9W107Zm9yKGxldCB4IG9mIEkudmFsdWVzKCkpe2lmKHguY291bnQ+MSlBKz14LmNvdW50LTE7TC5wdXNoKHguaGFzaCl9bGV0IGc9Ui5sZW5ndGgsZj1JLnNpemUsaz1hd2FpdCBOJChMLHopLHk9W10saD0wO2ZvcihsZXQgeCBvZiBJLnZhbHVlcygpKXtpZihhd2FpdCBWLm1lc3NhZ2VzLmhhcyh4Lmhhc2gpKXthd2FpdCBWLnVwbG9hZHMuZGVxKFcubGFiZWwsW3guaGFzaF0pO2NvbnRpbnVlfWlmKGgrPTEsIVopY29udGludWU7bGV0IEU9eC5zYW1wbGUsaT1uZXcgbShFLmhlYWRFbmMpLFtfLGRdPWkucmVhZFN0cnVjdChHMCk7aWYoZCE9PTApe2NvbnNvbGUuZXJyb3IoInJlY29uY2lsZTogcmVhZGluZyBtc2cgaGVhZGVyIixkKTtjb250aW51ZX15LnB1c2goe2tkbTpFLmtkbSxoZWFkOl8sc2VxOkUuc2VxLGhvc3Q6Vy5sYWJlbCxoZWFkRW5jOkUuaGVhZEVuYyxoZWFkRW5jSGFzaDpFLmhlYWRFbmNIYXNofSl9aWYoeS5sZW5ndGg+MClhd2FpdCBWLmRvd25sb2Fkcy5lbnEoeSk7bGV0IHc9MDtpZihRKXtsZXQgeD1hd2FpdCBWLm1lc3NhZ2VzLmxpc3RLZXlzKCksdj1uZXcgU2V0KEkua2V5cygpKSxFPVtdO2ZvcihsZXQgaSBvZiB4KWlmKCF2LmhhcyhCKGkpKSl3Kz0xLEUucHVzaChpKTtpZihFLmxlbmd0aD4wKWF3YWl0IFYudXBsb2Fkcy5lbnEoVy5sYWJlbCxFKX1lbHNle2xldCB4PWF3YWl0IFYubWVzc2FnZXMubGlzdEtleXMoKSx2PW5ldyBTZXQoSS5rZXlzKCkpO2ZvcihsZXQgRSBvZiB4KWlmKCF2LmhhcyhCKEUpKSl3Kz0xfWxldCBwPVIubGVuZ3RoPjA/TWF0aC5tYXgoLi4uUi5tYXAoKHgpPT54LnNlcSkpOjA7aWYoYXdhaXQgVi5ob3N0cy5yZWNvcmRTdGF0cyhXLmxhYmVsLHtzZXRMYXN0U2VxOnB9KSxLKUsoe3BoYXNlOiJwZWVrIixob3N0OlcubGFiZWwsZG9uZTpILHRvdGFsOkh9KTtyZXR1cm4gTyh7bXNnY2hlY2s6ayxudW1CYWdzOmcsdW5pcXVlTXNnczpmLG51bUR1cGVzOkEsbWlzc2luZ0xvY2FsOmgsbWlzc2luZ0hvc3Q6d30pfWNsYXNzIFNKe2Nsb2NrO3N0YXRlO3N0b3JlO3RyYW5zcG9ydDtjcnlwdG87Zm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQ7b25TY2hlZHVsZVN5bmM7Y29ubmVjdGlvbnM9bmV3IE1hcDthcHBseUNoYWluPVByb21pc2UucmVzb2x2ZSgpO3N5bmNSdW5zPW5ldyBTJDtjbGllbnRTdGF0ZTt4ZmVyU3RhdGU7bWF4UHVzaEJ5dGVzO21heFB1bGxCeXRlcztwZWVrUHJvZ3Jlc3NFdmVyeT1PJDtsYXN0UHJvZ3Jlc3M9X0o7c2NoZWR1bGVkU3luYztjb25zdHJ1Y3RvcigkLEosWixRLFksVj0hMCxYPWtKLFc9RUoseil7dGhpcy5jbG9jaz0kO3RoaXMuc3RhdGU9Sjt0aGlzLnN0b3JlPVo7dGhpcy50cmFuc3BvcnQ9UTt0aGlzLmNyeXB0bz1ZO3RoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQ9Vjt0aGlzLm9uU2NoZWR1bGVTeW5jPXo7dGhpcy5tYXhQdXNoQnl0ZXM9WCx0aGlzLm1heFB1bGxCeXRlcz1XLHRoaXMuY2xpZW50U3RhdGU9bmV3IGYwKCgpPT50aGlzLmdldENsaWVudFN0YXRlKCkpLHRoaXMueGZlclN0YXRlPW5ldyBmMCgoKT0+dGhpcy5nZXRYZmVyU3RhdGUoKSksdGhpcy5zY2hlZHVsZWRTeW5jPW5ldyBBSihvWixhc3luYygpPT57dHJ5e2NvbnNvbGUuaW5mbygiUnVubmluZyBzY2hlZHVsZWQgc3luYyIpLGF3YWl0IHRoaXMuc3luYygpfWNhdGNoKEspe2NvbnNvbGUuZXJyb3IoIkRlYm91bmNlZCBzeW5jIGZhaWxlZDoiLEspfX0pfWVtaXRQcm9ncmVzcz0oJCk9Pnt0aGlzLmxhc3RQcm9ncmVzcz0kLHRoaXMueGZlclN0YXRlLmVtaXQoKX07YXN5bmMgc2V0U2VlZCgkLEope2F3YWl0IHRoaXMuc3RvcmUuc2VlZC5zYXZlKCQsSiksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9YXN5bmMgZ2V0Q2xpZW50U3RhdGUoKXtsZXR7c3RvcmU6JCxjb25uZWN0aW9uczpKfT10aGlzLFo9YXdhaXQgJC5zZWVkLmxvYWQoKSxRPWF3YWl0ICQuaG9zdHMubGlzdCgpLFk9ITE7Zm9yKGxldCBWIG9mIEoudmFsdWVzKCkpaWYoVi5pc0Nvbm5lY3RlZCgpKXtZPSEwO2JyZWFrfXJldHVybntoYXNTZWVkOlohPT12b2lkIDAsaGFzSG9zdDpBcnJheS5mcm9tKFEpLmxlbmd0aD4wLGNvbm5lY3RlZDpZfX1hc3luYyBnZXRYZmVyU3RhdGUoKXtsZXR7dXBsb2FkczokLGRvd25sb2FkczpKfT10aGlzLnN0b3JlLFo9YXdhaXQgJC5jb3VudCgpO3JldHVybntudW1Eb3dubG9hZHM6YXdhaXQgSi5jb3VudCgpLG51bVVwbG9hZHM6Wixwcm9ncmVzczp0aGlzLmxhc3RQcm9ncmVzc319YXBwbHk9KCQsSik9PntyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMuZG9BcHBseSgkLEopKX07YXN5bmMgZG9BcHBseSgkLEo9e2VucXVldWVVcGxvYWQ6ITAsdHJpZ2dlclVwbG9hZDohMH0pe2xldCBaPVtdLFE9W107Zm9yKGxldHtoZWFkOlYsYm9keTpYfW9mICQpe2xldCBXPW5ldyBTO1cud3JpdGVTdHJ1Y3QoRzAsVik7bGV0IHo9Vy5yZXN1bHQoKSxLPWF3YWl0IHRoaXMuY3J5cHRvLmJsYWtlMyh6KSxGPXtlaWQ6Vi5laWQsYm9keTpYLGFwbGQ6USR9O2lmKFYub2ZmIT09MClGLm9mZj1WLm9mZjtpZihWLmN0ciE9PTApRi5jdHI9Vi5jdHI7Wi5wdXNoKEspLFEucHVzaCh7a2V5OkssZGF0YTpGfSl9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5hZGQoUSksYXdhaXQgUVEodGhpcy5zdG9yZSxaLHRoaXMuY3J5cHRvKTtsZXQgWT1hd2FpdCB0aGlzLmRvQXBwbHlIYXNoZXMoWik7aWYoSi5lbnF1ZXVlVXBsb2FkKXtsZXQgVj1bXTtmb3IobGV0IFg9MDtYPFoubGVuZ3RoO1grKyl7bGV0IFc9WVtYXTtpZihXPT09MHx8Vz09PTE1KVYucHVzaChaW1hdKX1pZihWLmxlbmd0aD4wKXtsZXQgWD1hd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmxpc3QoKTtmb3IobGV0IFcgb2YgWClhd2FpdCB0aGlzLnN0b3JlLnVwbG9hZHMuZW5xKFcubGFiZWwsVik7dGhpcy54ZmVyU3RhdGUuZW1pdCgpfX1pZihKLnRyaWdnZXJVcGxvYWQpdGhpcy5zY2hlZHVsZVN5bmMoKTtyZXR1cm4gWX1lbnF1ZXVlQXBwbHlKb2IoJCl7bGV0IEo9dGhpcy5hcHBseUNoYWluLnRoZW4oJCwkKTtyZXR1cm4gdGhpcy5hcHBseUNoYWluPUoudGhlbigoKT0+e3JldHVybn0sKCk9PntyZXR1cm59KSxKfWRyYWluQXBwbHlRdWV1ZSgpe3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5kb0RyYWluQXBwbHlRdWV1ZSgpKX1hc3luYyBkb0RyYWluQXBwbHlRdWV1ZSgpe2xldCAkPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdCh7YXBsZDpRJH0pO2lmKCQubGVuZ3RoPDEpcmV0dXJuW107bGV0IEo9SiQoJCwoWik9PlouaGVhZCk7cmV0dXJuIHRoaXMuYXBwbHlTdG9yZWQoSil9YXBwbHlIYXNoZXM9KCQpPT57cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvQXBwbHlIYXNoZXMoJCkpfTthc3luYyBkb0FwcGx5SGFzaGVzKCQpe2xldCBKPVtdO2ZvcihsZXQgWSBvZiAkKXtsZXQgVj1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmdldChZKTtpZihWKUoucHVzaChWKX1sZXQgWj1hd2FpdCB0aGlzLmFwcGx5U3RvcmVkKEopLFE9bmV3IE1hcDtmb3IobGV0IFk9MDtZPEoubGVuZ3RoO1krKylRLnNldChCKEpbWV0uaGFzaCksWltZXT8/MTIpO3JldHVybiAkLm1hcCgoWSk9PlEuZ2V0KEIoWSkpPz8xMyl9YXN5bmMgYXBwbHlTdG9yZWQoJCl7aWYoJC5sZW5ndGg8MSlyZXR1cm5bXTtsZXQgSj0kLm1hcCgoVik9Pih7Li4uVi5oZWFkLGJvZDpWLmJvZHl9KSksWj1hd2FpdCB0aGlzLnN0YXRlLmFwcGx5KEopLFE9W10sWT1bXTtmb3IobGV0IFY9MDtWPCQubGVuZ3RoO1YrKyl7bGV0IFg9WltWXTtpZihYPT09MHx8WD09PTE1KVEucHVzaCgkW1ZdLmhhc2gpO2Vsc2UgaWYoWCE9PXZvaWQgMCYmZVooWCkpWS5wdXNoKHtrZXk6JFtWXS5oYXNoLGVycjpYfSl9aWYoUS5sZW5ndGg+MClhd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLm1hcmtBcHBsaWVkKFEpO2lmKFkubGVuZ3RoPjApYXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5tYXJrRmFpbGVkKFkpO3JldHVybiBafWFzeW5jIGluc2VydFJhdygkKXtsZXR7Y2xvY2s6SixjcnlwdG86Wn09dGhpcyxbUSxZXT1hd2FpdCBoWih7bm93Okoubm93KCksYm9kOiQsY3J5cHRvOlp9KTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXQgWD0oYXdhaXQgdGhpcy5hcHBseShbe2hlYWQ6USxib2R5OiR9XSkpWzBdO2lmKFghPT0wJiZYIT09MTUpcmV0dXJuIEcoWD8/MTIpO3JldHVybiBPKFEpfWFzeW5jIG1ha2VVcGRhdGUoJCxKKXtsZXR7Y2xvY2s6WixjcnlwdG86UX09dGhpcyxZPVoubm93KCk7aWYoJC51cGRhdGVkQXQuZ2V0VGltZSgpPlkuZ2V0VGltZSgpKXJldHVybiBHKDQpO2xldCBWPSQuY3RyKzEsW1gsV109YXdhaXQgayQoe25vdzpZLGVpZDokLmVpZCxjdHI6Vixib2Q6SixjcnlwdG86UX0pO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBPKHtoZWFkOlgsYm9keTpKfSl9YXN5bmMgdXBkYXRlV2l0aFNrZXcoJCxKLFope2lmKFo9PT0hMSlyZXR1cm4gRyg0KTtsZXR7Y2xvY2s6USxjcnlwdG86WX09dGhpcyxWPVEubm93KCksWD1uZXcgbSgkLmVpZCksW1csel09WC5yZWFkU3RydWN0KFYwKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXQgSz0kLnVwZGF0ZWRBdC5nZXRUaW1lKCktVy50cy5nZXRUaW1lKCksRj17ZWlkOiQuZWlkLG9mZjpLKzEsY3RyOiQuY3RyKzEsbGVuOjB9LFU9KGF3YWl0IHRoaXMuYXBwbHkoW3toZWFkOkYsYm9keTp2b2lkIDB9XSkpWzBdO2lmKFUhPT0wJiZVIT09MTUpcmV0dXJuIEcoVT8/MTIpO2lmKEo9PT12b2lkIDApcmV0dXJuIE8oRik7bGV0W1IscV09QSQoe2lkOlcuaWQsdHM6Vn0pO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldFtILE1dPWF3YWl0IGskKHtub3c6VixlaWQ6UixjdHI6MCxib2Q6SixjcnlwdG86WX0pO2lmKE0hPT0wKXJldHVybiBHKE0pO2xldCBDPShhd2FpdCB0aGlzLmFwcGx5KFt7aGVhZDpILGJvZHk6Sn1dKSlbMF07aWYoQyE9PTAmJkMhPT0xNSlyZXR1cm4gRyhDPz8xMik7cmV0dXJuIE8oSCl9YXN5bmMgdXBkYXRlUmF3KCQsSixaPXRoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQpe2lmKCQudXBkYXRlZEF0LmdldFRpbWUoKT50aGlzLmNsb2NrLm5vdygpLmdldFRpbWUoKSlyZXR1cm4gdGhpcy51cGRhdGVXaXRoU2tldygkLEosWik7cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKGFzeW5jKCk9PntsZXRbUSxZXT1hd2FpdCB0aGlzLm1ha2VVcGRhdGUoJCxKKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXQgWD0oYXdhaXQgdGhpcy5kb0FwcGx5KFtRXSkpWzBdO2lmKFghPT0wJiZYIT09MTUpcmV0dXJuIEcoWD8/MTIpO3JldHVybiBPKFEuaGVhZCl9KX1hc3luYyBpbnNlcnQoJCl7bGV0e2JvZHk6Six0eXBlOlosZ2lkOlEscGlkOlksdGFnczpWfT0kLFc9RTAoe2JvZHk6Six0eXBlOlosZ2lkOlEscGlkOlksdGFnczpWfSk7cmV0dXJuIHRoaXMuaW5zZXJ0UmF3KFcpfWFzeW5jIHVwZGF0ZSgkKXtsZXR7cHJpb3I6Sixib2R5OlosdHlwZTpRLGdpZDpZLHBpZDpWLHRhZ3M6WCxmb3JjZTpXfT0kLEs9RTAoe2JvZHk6Wix0eXBlOlEsZ2lkOlkscGlkOlYsdGFnczpYfSk7cmV0dXJuIHRoaXMudXBkYXRlUmF3KEosSyxXPz90aGlzLmZvcmNlU2tld0hhbmRsaW5nQnlEZWZhdWx0KX1hc3luYyBkZWxldGUoJCl7bGV0IEo9JC5mb3JjZT8/ITA7aWYoInByaW9yImluICQpcmV0dXJuIHRoaXMudXBkYXRlUmF3KCQucHJpb3Isdm9pZCAwLEopO2xldFtaLFFdPWF3YWl0IHRoaXMucmV2RnJvbUFyY2hpdmUoJC5laWQpO2lmKFEhPT0wKXJldHVybiBHKFEpO3JldHVybiB0aGlzLnVwZGF0ZVJhdyhaLHZvaWQgMCxKKX1hc3luYyByZXZGcm9tQXJjaGl2ZSgkKXtsZXQgSj1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxhc3QoJCk7aWYoSilyZXR1cm4gclooSi5oZWFkKTtsZXQgWj1uZXcgbSgkKSxbUSxZXT1aLnJlYWRTdHJ1Y3QoVjApO2lmKFkhPT0wKXJldHVybiBHKFkpO3JldHVybiBPKHtlaWQ6JCxjdHI6LTEsdXBkYXRlZEF0OlEudHN9KX1hc3luYyBnZW5FSUQoJCl7bGV0e2Nsb2NrOkosY3J5cHRvOlp9PXRoaXMsUT1KLm5vdygpO2lmKCQhPT12b2lkIDApcmV0dXJuIEEkKHtpZDokLHRzOlF9KTtsZXQgWT1hd2FpdCBaLmdlblJhbmRvbUJ5dGVzKDgpO3JldHVybiBBJCh7aWQ6WSx0czpRfSl9c3luYygpe3JldHVybiB0aGlzLnN5bmNSdW5zLnJ1bigoKT0+dGhpcy5kb1N5bmMoKSl9YXN5bmMgZG9TeW5jKCl7bGV0e2Nvbm5lY3Rpb25zOiQsY3J5cHRvOkosc3RvcmU6Wn09dGhpcyxRPWF3YWl0IFouc2VlZC5sb2FkKCk7aWYoIVEpcmV0dXJuIDIyO2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCk7Zm9yKGxldFtZLFZdb2YgJCl7bGV0IFg9YXdhaXQgWi5ob3N0cy5nZXQoWSk7aWYoIVgpY29udGludWU7bGV0IFc9e2Nvbm46VixzdG9yZTpaLGVuY2xhdmU6USxob3N0OlgsY3J5cHRvOkosbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LHo9YXdhaXQgZkooVyk7aWYoeiE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwZWVrOiAke3p9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLHo7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBLPWF3YWl0IFlRKFcpO2lmKEshPT0wKXJldHVybiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcHVzaDogJHtLfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxLO3RoaXMueGZlclN0YXRlLmVtaXQoKTtsZXQgRj1hd2FpdCBnSihXLGFzeW5jKCk9Pnthd2FpdCB0aGlzLmRyYWluQXBwbHlRdWV1ZSgpfSk7aWYoRiE9PTAmJkYhPT0xNSlyZXR1cm4gY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHB1bGw6ICR7Rn1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRjt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHJlYnVpbGQoJCl7aWYodGhpcy5zY2hlZHVsZWRTeW5jLmNhbmNlbCgpLGF3YWl0IHRoaXMuc3luY1J1bnMuZmx1c2goKSwkPy5jaGVja0hvc3Q/PyEwKXtsZXQgWj1hd2FpdCB0aGlzLnJlcHVsbCgpO2lmKFohPT0wKXJldHVybiBafXJldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5yZXBsYXkoKSl9YXN5bmMgbXNnY2hlY2soKXtsZXQgJD1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3RLZXlzKCk7cmV0dXJuIE4kKCQsdGhpcy5jcnlwdG8pfWxpc3RNc2dzKCQpe3JldHVybiB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3QoJCl9Y291bnRNc2dzKCQpe3JldHVybiB0aGlzLnN0b3JlLm1lc3NhZ2VzLmNvdW50KCQpfWFzeW5jIHJlY29uY2lsZSgkLEope3RoaXMuc2NoZWR1bGVkU3luYy5jYW5jZWwoKSxhd2FpdCB0aGlzLnN5bmNSdW5zLmZsdXNoKCk7bGV0e2Nvbm5lY3Rpb25zOlosY3J5cHRvOlEsc3RvcmU6WX09dGhpcyxWPWF3YWl0IFkuc2VlZC5sb2FkKCk7aWYoIVYpcmV0dXJuIEcoMjIpO2xldCBYPWF3YWl0IFkuaG9zdHMuZ2V0KCQpO2lmKCFYKXJldHVybiBHKDEzKTtsZXQgVz1aLmdldCgkKTtpZighV3x8IVcuaXNDb25uZWN0ZWQoKSl7aWYoYXdhaXQgdGhpcy5jb25uZWN0VG9Ib3N0KFgsITEsITEpLFg9YXdhaXQgWS5ob3N0cy5nZXQoJCksIVgpcmV0dXJuIEcoMTMpO1c9Wi5nZXQoJCl9aWYoIVcpcmV0dXJuIEcoMTIpO2xldCB6PXtjb25uOlcsc3RvcmU6WSxlbmNsYXZlOlYsY3J5cHRvOlEsbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LFtLLEZdPWF3YWl0IG1KKHsuLi56LGhvc3Q6WH0sSik7aWYodGhpcy54ZmVyU3RhdGUuZW1pdCgpLEYhPT0wKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRyhGKTtpZighSylyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEcoMTIpO2lmKEo/LnN5bmM9PT0hMSlyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLE8oSyk7bGV0IE49YXdhaXQgdGhpcy5zeW5jKCk7aWYoTiE9PTApcmV0dXJuIEcoTik7bGV0IFU9YXdhaXQgWS5ob3N0cy5nZXQoJCk7aWYoIVUpcmV0dXJuIEcoMTMpO2xldFtSLHFdPWF3YWl0IG1KKHsuLi56LGhvc3Q6VX0se3B1bGw6ITEscHVzaDohMX0pO2lmKHRoaXMueGZlclN0YXRlLmVtaXQoKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSkscSE9PTApcmV0dXJuIEcocSk7aWYoIVIpcmV0dXJuIEcoMTIpO3JldHVybiBPKFIpfWFzeW5jIHJlcHVsbCgpe2xldHtjb25uZWN0aW9uczokLGNyeXB0bzpKLHN0b3JlOlp9PXRoaXMsUT1hd2FpdCBaLnNlZWQubG9hZCgpO2lmKCFRKXJldHVybiAyMjtsZXQgWT1BcnJheS5mcm9tKGF3YWl0IFouaG9zdHMubGlzdCgpKTtpZihZLmxlbmd0aDwxKXJldHVybiAwO2ZvcihsZXQgViBvZiBZKXtsZXQgWD0kLmdldChWLmxhYmVsKTtpZighWHx8IVguaXNDb25uZWN0ZWQoKSlhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QoViwhMSwhMSl9Zm9yKGxldFtWLFhdb2YgJCl7bGV0IFc9YXdhaXQgWi5ob3N0cy5nZXQoVik7aWYoIVcpY29udGludWU7bGV0IHo9e2Nvbm46WCxzdG9yZTpaLGVuY2xhdmU6USxob3N0OnsuLi5XLGxhc3RTZXE6MH0sY3J5cHRvOkosbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LEs9YXdhaXQgZkooeik7aWYoSyE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYHJlYnVpbGQ6IGZhaWxlZCB0byBwZWVrOiAke0t9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEs7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBGPWF3YWl0IGdKKHopO2lmKEYhPT0wJiZGIT09MTUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoYHJlYnVpbGQ6IGZhaWxlZCB0byBwdWxsOiAke0Z9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEY7dGhpcy54ZmVyU3RhdGUuZW1pdCgpfXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH1hc3luYyByZXBsYXkoKXtsZXQgJD1hd2FpdCB0aGlzLnN0YXRlLmNsZWFyKCk7aWYoJCE9PTApcmV0dXJuICQ7bGV0IEo9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0KCksWj1KJChKLChWKT0+Vi5oZWFkKSxRPVoubGVuZ3RoO2lmKFE8MSlyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDA7bGV0IFk9MDt3aGlsZShZPFoubGVuZ3RoKXtsZXQgVj0wLFg9MCxXPVk7Zm9yKGxldCBLPVk7SzxaLmxlbmd0aCYmWDwxMDAmJlY8MTAyNDAwO0srKylWKz1aW0tdLmhlYWQubGVuLFgrKyxXPUsrMTtsZXQgej1aLnNsaWNlKFksVyk7YXdhaXQgdGhpcy5hcHBseVN0b3JlZCh6KSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImV4ZWMiLGRvbmU6Vyx0b3RhbDpRfSksWT1XfXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH1hc3luYyB3aXBlKCQpe2xldCBKPSQ/Lm1zZ3MhPT0hMSxaPSQ/LmVudHMhPT0hMSxRPSQ/Lm1ldGEhPT0hMSxZPSQ/LnNlZWQ9PT0hMDt0aGlzLnNjaGVkdWxlZFN5bmMuY2FuY2VsKCksYXdhaXQgdGhpcy5kaXNjb25uZWN0KCksYXdhaXQgdGhpcy5zeW5jUnVucy5mbHVzaCgpO2xldHtzdG9yZTpWfT10aGlzO2lmKFEpYXdhaXQgVi5ob3N0cy53aXBlKCksYXdhaXQgVi51cGxvYWRzLndpcGUoKSxhd2FpdCBWLmRvd25sb2Fkcy53aXBlKCk7aWYoSilhd2FpdCBWLm1lc3NhZ2VzLndpcGUoKTtpZihZKWF3YWl0IFYuc2VlZC53aXBlKCk7aWYoWilhd2FpdCB0aGlzLnN0YXRlLmNsZWFyKCk7dGhpcy5sYXN0UHJvZ3Jlc3M9X0osdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksdGhpcy54ZmVyU3RhdGUuZW1pdCgpfWltcG9ydD1hc3luYygkLEopPT57bGV0e2NyeXB0bzpaLHN0b3JlOlF9PXRoaXMsWT1KPy5vblByb2dyZXNzLFY9YXdhaXQgUS5zZWVkLmxvYWQoKTtpZighVilyZXR1cm4gMjI7Y29uc29sZS50aW1lKCJpbXBvcnQ6IGRlY29kaW5nIGZpbGUuLi4iKTtsZXQgWD1hd2FpdCAkLmJ5dGVzKCksW1csel09YXdhaXQgYlooWCxaLFYpO2lmKHohPT0wKXJldHVybiB6O2NvbnNvbGUudGltZUVuZCgiaW1wb3J0OiBkZWNvZGluZyBmaWxlLi4uIik7bGV0IEs9MDt3aGlsZShLPFcubGVuZ3RoKXtsZXQgRj0wLE49MCxVPUs7Zm9yKGxldCBIPUs7SDxXLmxlbmd0aCYmTjwxMDAmJkY8MTAyNDAwO0grKylGKz1XW0hdLmhlYWQubGVuLE4rKyxVPUgrMTtsZXQgUj1XLnNsaWNlKEssVSk7Y29uc29sZS50aW1lKGBpbXBvcnQ6IGFwcGx5aW5nIFske0t9LCAke1V9XWApO2xldCBxPWF3YWl0IHRoaXMuYXBwbHkoUix7ZW5xdWV1ZVVwbG9hZDohMCx0cmlnZ2VyVXBsb2FkOiExfSk7Y29uc29sZS50aW1lRW5kKGBpbXBvcnQ6IGFwcGx5aW5nIFske0t9LCAke1V9XWApO2ZvcihsZXQgSD0wO0g8Ui5sZW5ndGg7SCsrKXtsZXQgTT1xW0hdO2lmKE0hPT0wJiZNIT09MTUpY29uc29sZS53YXJuKGBmYWlsZWQgdG8gaW1wb3J0IG1zZyAke0srSH06ICR7RFtNXX1gKX1pZihZKXF1ZXVlTWljcm90YXNrKCgpPT5ZKFUsVy5sZW5ndGgsMCkpO3RoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaW1wb3J0Iixkb25lOlUsdG90YWw6Vy5sZW5ndGh9KSxLPVV9cmV0dXJuIHRoaXMuc2NoZWR1bGVTeW5jKCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9O3NjaGVkdWxlU3luYz0oKT0+e2lmKHRoaXMub25TY2hlZHVsZVN5bmMpe3RoaXMub25TY2hlZHVsZVN5bmMoKTtyZXR1cm59dGhpcy5zY2hlZHVsZWRTeW5jLnNjaGVkdWxlKCl9O2FzeW5jIGV4cG9ydEJ5dGVzKCl7bGV0e2NyeXB0bzokLHN0b3JlOkp9PXRoaXMsWj1hd2FpdCBKLnNlZWQubG9hZCgpO2lmKCFaKXJldHVybiBHKDIyKTtsZXQgUT1hd2FpdCBKLm1lc3NhZ2VzLmxpc3QoKTtyZXR1cm4geVooImV4cG9ydCIsMCxRLCQsWil9YXN5bmMgZXhwb3J0KCQpe2xldFtKLFpdPWF3YWl0IHRoaXMuZXhwb3J0Qnl0ZXMoKTtpZihaIT09MClyZXR1cm4gWjtpZighSilyZXR1cm4gMTI7bGV0IFE9bmV3IEJsb2IoW0ouc2xpY2UoKV0pO3JldHVybiBzWihRLCQpLDB9YXN5bmMgbGluaygkLEo9ITApe2lmKGF3YWl0IHRoaXMuc3RvcmUuaG9zdHMuYWRkKCQpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLEope2xldCBaPWF3YWl0IHRoaXMuc3RvcmUuaG9zdHMuZ2V0KCQubGFiZWwpO2lmKFopYXdhaXQgdGhpcy5jb25uZWN0VG9Ib3N0KFopfX1hc3luYyB1bmxpbmsoJCl7YXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5kZWwoJCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9YXN5bmMgaG9zdHMoKXtyZXR1cm4gQXJyYXkuZnJvbShhd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmxpc3QoKSl9Y29ubmVjdFRvSG9zdD1hc3luYygkLEo9ITAsWj0hMCk9PntsZXR7Y2xvY2s6USxjb25uZWN0aW9uczpZLGNyeXB0bzpWLHN0b3JlOlgsdHJhbnNwb3J0Old9PXRoaXMsej1ZLmdldCgkLmxhYmVsKTtpZih6KXtpZih6LmlzQ29ubmVjdGVkKCkpcmV0dXJuO3RyeXt6LmNsb3NlTGlzdGVuZXIoKX1jYXRjaHt9WS5kZWxldGUoJC5sYWJlbCl9bGV0IEs9YXdhaXQgWC5zZWVkLmxvYWQoKTtpZighSylyZXR1cm47Y29uc29sZS5pbmZvKGBDb25uZWN0aW5nIHRvICR7JC5oYW5kbGV9ICgkeyQubGFiZWx9KWApO2xldCBGPW5ldyBCJChLLFYsJCxRLFcoJCksKE4pPT5YLmhvc3RzLnNldCgkLmxhYmVsLE4pKTtpZihhd2FpdCBGLnJlZ2lzdGVyKCksSilhd2FpdCBGLmxpc3Rlbihhc3luYyhOKT0+e2xldCBVPXtjb25uOkYsc3RvcmU6WCxlbmNsYXZlOkssaG9zdDokLGNyeXB0bzpWLG1heFB1c2hCeXRlczp0aGlzLm1heFB1c2hCeXRlcyxtYXhQdWxsQnl0ZXM6dGhpcy5tYXhQdWxsQnl0ZXMsb25Qcm9ncmVzczp0aGlzLmVtaXRQcm9ncmVzcyxwZWVrUHJvZ3Jlc3NFdmVyeTp0aGlzLnBlZWtQcm9ncmVzc0V2ZXJ5fTtyZXR1cm4gWFEoTixVLHRoaXMuc2NoZWR1bGVTeW5jKX0sKCk9PnRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLCgpPT50aGlzLmNsaWVudFN0YXRlLmVtaXQoKSk7aWYoWS5zZXQoJC5sYWJlbCxGKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKSxaKXRoaXMuc2NoZWR1bGVTeW5jKCl9O2FzeW5jIGNvbm5lY3QoJD0hMCxKPSEwKXtsZXR7Y29ubmVjdFRvSG9zdDpaLHNjaGVkdWxlU3luYzpRLHN0b3JlOll9PXRoaXM7aWYoIWF3YWl0IFkuc2VlZC5sb2FkKCkpcmV0dXJuO2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCk7bGV0IFg9YXdhaXQgWS5ob3N0cy5saXN0KCk7Zm9yKGxldCBXIG9mIFgpYXdhaXQgWihXLCQsITEpO2lmKEopUSgpfWRpc2Nvbm5lY3Q9YXN5bmMoKT0+e2ZvcihsZXQgJCBvZiB0aGlzLmNvbm5lY3Rpb25zLnZhbHVlcygpKXRyeXskLmNsb3NlTGlzdGVuZXIoKX1jYXRjaHt9dGhpcy5jb25uZWN0aW9ucy5jbGVhcigpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpfX12YXIgZzA9dHlwZW9mIGdsb2JhbFRoaXM9PT0ib2JqZWN0IiYmImNyeXB0byJpbiBnbG9iYWxUaGlzP2dsb2JhbFRoaXMuY3J5cHRvOnZvaWQgMDtmdW5jdGlvbiBoJCgkKXtpZighTnVtYmVyLmlzU2FmZUludGVnZXIoJCl8fCQ8MCl0aHJvdyBFcnJvcigicG9zaXRpdmUgaW50ZWdlciBleHBlY3RlZCwgZ290ICIrJCl9ZnVuY3Rpb24gdkooJCl7cmV0dXJuICQgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxBcnJheUJ1ZmZlci5pc1ZpZXcoJCkmJiQuY29uc3RydWN0b3IubmFtZT09PSJVaW50OEFycmF5In1mdW5jdGlvbiBvKCQsLi4uSil7aWYoIXZKKCQpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIik7aWYoSi5sZW5ndGg+MCYmIUouaW5jbHVkZXMoJC5sZW5ndGgpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIG9mIGxlbmd0aCAiK0orIiwgZ290IGxlbmd0aD0iKyQubGVuZ3RoKX1mdW5jdGlvbiB5SigkLEo9ITApe2lmKCQuZGVzdHJveWVkKXRocm93IEVycm9yKCJIYXNoIGluc3RhbmNlIGhhcyBiZWVuIGRlc3Ryb3llZCIpO2lmKEomJiQuZmluaXNoZWQpdGhyb3cgRXJyb3IoIkhhc2gjZGlnZXN0KCkgaGFzIGFscmVhZHkgYmVlbiBjYWxsZWQiKX1mdW5jdGlvbiBXUSgkLEope28oJCk7bGV0IFo9Si5vdXRwdXRMZW47aWYoJC5sZW5ndGg8Wil0aHJvdyBFcnJvcigiZGlnZXN0SW50bygpIGV4cGVjdHMgb3V0cHV0IGJ1ZmZlciBvZiBsZW5ndGggYXQgbGVhc3QgIitaKX1mdW5jdGlvbiBiSigkKXtpZih0eXBlb2YgJCE9PSJib29sZWFuIil0aHJvdyBFcnJvcihgYm9vbGVhbiBleHBlY3RlZCwgbm90ICR7JH1gKX0vKiEgbm9ibGUtY2lwaGVycyAtIE1JVCBMaWNlbnNlIChjKSAyMDIzIFBhdWwgTWlsbGVyIChwYXVsbWlsbHIuY29tKSAqL3ZhciBDMD0oJCk9Pm5ldyBVaW50MzJBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsTWF0aC5mbG9vcigkLmJ5dGVMZW5ndGgvNCkpO3ZhciBvWT1uZXcgVWludDhBcnJheShuZXcgVWludDMyQXJyYXkoWzI4NzQ1NDAyMF0pLmJ1ZmZlcilbMF09PT02ODtpZighb1kpdGhyb3cgRXJyb3IoIk5vbiBsaXR0bGUtZW5kaWFuIGhhcmR3YXJlIGlzIG5vdCBzdXBwb3J0ZWQiKTtmdW5jdGlvbiBhWSgkKXtpZih0eXBlb2YgJCE9PSJzdHJpbmciKXRocm93IEVycm9yKCJzdHJpbmcgZXhwZWN0ZWQiKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkobmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpKX1mdW5jdGlvbiBpJCgkKXtpZih0eXBlb2YgJD09PSJzdHJpbmciKSQ9YVkoJCk7ZWxzZSBpZih2SigkKSkkPWwkKCQpO2Vsc2UgdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQsIGdvdCAiK3R5cGVvZiAkKTtyZXR1cm4gJH1mdW5jdGlvbiBHUSgkLEope2lmKEo9PW51bGx8fHR5cGVvZiBKIT09Im9iamVjdCIpdGhyb3cgRXJyb3IoIm9wdGlvbnMgbXVzdCBiZSBkZWZpbmVkIik7cmV0dXJuIE9iamVjdC5hc3NpZ24oJCxKKX1mdW5jdGlvbiB6USgkLEope2lmKCQubGVuZ3RoIT09Si5sZW5ndGgpcmV0dXJuITE7bGV0IFo9MDtmb3IobGV0IFE9MDtRPCQubGVuZ3RoO1ErKylafD0kW1FdXkpbUV07cmV0dXJuIFo9PT0wfXZhciBLUT0oJCxKKT0+e2Z1bmN0aW9uIFooUSwuLi5ZKXtpZihvKFEpLCQubm9uY2VMZW5ndGghPT12b2lkIDApe2xldCBGPVlbMF07aWYoIUYpdGhyb3cgRXJyb3IoIm5vbmNlIC8gaXYgcmVxdWlyZWQiKTtpZigkLnZhclNpemVOb25jZSlvKEYpO2Vsc2UgbyhGLCQubm9uY2VMZW5ndGgpfWxldCBWPSQudGFnTGVuZ3RoO2lmKFYmJllbMV0hPT12b2lkIDApbyhZWzFdKTtsZXQgWD1KKFEsLi4uWSksVz0oRixOKT0+e2lmKE4hPT12b2lkIDApe2lmKEYhPT0yKXRocm93IEVycm9yKCJjaXBoZXIgb3V0cHV0IG5vdCBzdXBwb3J0ZWQiKTtvKE4pfX0sej0hMTtyZXR1cm57ZW5jcnlwdChGLE4pe2lmKHopdGhyb3cgRXJyb3IoImNhbm5vdCBlbmNyeXB0KCkgdHdpY2Ugd2l0aCBzYW1lIGtleSArIG5vbmNlIik7cmV0dXJuIHo9ITAsbyhGKSxXKFguZW5jcnlwdC5sZW5ndGgsTiksWC5lbmNyeXB0KEYsTil9LGRlY3J5cHQoRixOKXtpZihvKEYpLFYmJkYubGVuZ3RoPFYpdGhyb3cgRXJyb3IoImludmFsaWQgY2lwaGVydGV4dCBsZW5ndGg6IHNtYWxsZXIgdGhhbiB0YWdMZW5ndGg9IitWKTtyZXR1cm4gVyhYLmRlY3J5cHQubGVuZ3RoLE4pLFguZGVjcnlwdChGLE4pfX19cmV0dXJuIE9iamVjdC5hc3NpZ24oWiwkKSxafTtmdW5jdGlvbiBoSigkLEosWj0hMCl7aWYoSj09PXZvaWQgMClyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJCk7aWYoSi5sZW5ndGghPT0kKXRocm93IEVycm9yKCJpbnZhbGlkIG91dHB1dCBsZW5ndGgsIGV4cGVjdGVkICIrJCsiLCBnb3Q6ICIrSi5sZW5ndGgpO2lmKFomJiFzWShKKSl0aHJvdyBFcnJvcigiaW52YWxpZCBvdXRwdXQsIG11c3QgYmUgYWxpZ25lZCIpO3JldHVybiBKfWZ1bmN0aW9uIHNZKCQpe3JldHVybiAkLmJ5dGVPZmZzZXQlND09PTB9ZnVuY3Rpb24gbCQoJCl7cmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX1mdW5jdGlvbiBxMCguLi4kKXtmb3IobGV0IEo9MDtKPCQubGVuZ3RoO0orKykkW0pdLmZpbGwoMCl9ZnVuY3Rpb24gVSQoJD0zMil7aWYoZzAmJnR5cGVvZiBnMC5nZXRSYW5kb21WYWx1ZXM9PT0iZnVuY3Rpb24iKXJldHVybiBnMC5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQ4QXJyYXkoJCkpO2lmKGcwJiZ0eXBlb2YgZzAucmFuZG9tQnl0ZXM9PT0iZnVuY3Rpb24iKXJldHVybiBnMC5yYW5kb21CeXRlcygkKTt0aHJvdyBFcnJvcigiY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBtdXN0IGJlIGRlZmluZWQiKX12YXIgTlE9KCQpPT5VaW50OEFycmF5LmZyb20oJC5zcGxpdCgiIikubWFwKChKKT0+Si5jaGFyQ29kZUF0KDApKSksdFk9TlEoImV4cGFuZCAxNi1ieXRlIGsiKSxlWT1OUSgiZXhwYW5kIDMyLWJ5dGUgayIpLCRWPUMwKHRZKSxKVj1DMChlWSk7ZnVuY3Rpb24gaigkLEope3JldHVybiAkPDxKfCQ+Pj4zMi1KfWZ1bmN0aW9uIGlKKCQpe3JldHVybiAkLmJ5dGVPZmZzZXQlND09PTB9dmFyIHUkPTY0LFpWPTE2LE9RPTQyOTQ5NjcyOTUsRlE9bmV3IFVpbnQzMkFycmF5O2Z1bmN0aW9uIFFWKCQsSixaLFEsWSxWLFgsVyl7bGV0IHo9WS5sZW5ndGgsSz1uZXcgVWludDhBcnJheSh1JCksRj1DMChLKSxOPWlKKFkpJiZpSihWKSxVPU4/QzAoWSk6RlEsUj1OP0MwKFYpOkZRO2ZvcihsZXQgcT0wO3E8ejtYKyspe2lmKCQoSixaLFEsRixYLFcpLFg+PU9RKXRocm93IEVycm9yKCJhcng6IGNvdW50ZXIgb3ZlcmZsb3ciKTtsZXQgSD1NYXRoLm1pbih1JCx6LXEpO2lmKE4mJkg9PT11JCl7bGV0IE09cS80O2lmKHElNCE9PTApdGhyb3cgRXJyb3IoImFyeDogaW52YWxpZCBibG9jayBwb3NpdGlvbiIpO2ZvcihsZXQgUD0wLEM7UDxaVjtQKyspQz1NK1AsUltDXT1VW0NdXkZbUF07cSs9dSQ7Y29udGludWV9Zm9yKGxldCBNPTAsUDtNPEg7TSsrKVA9cStNLFZbUF09WVtQXV5LW01dO3ErPUh9fWZ1bmN0aW9uIFVRKCQsSil7bGV0e2FsbG93U2hvcnRLZXlzOlosZXh0ZW5kTm9uY2VGbjpRLGNvdW50ZXJMZW5ndGg6WSxjb3VudGVyUmlnaHQ6Vixyb3VuZHM6WH09R1Eoe2FsbG93U2hvcnRLZXlzOiExLGNvdW50ZXJMZW5ndGg6OCxjb3VudGVyUmlnaHQ6ITEscm91bmRzOjIwfSxKKTtpZih0eXBlb2YgJCE9PSJmdW5jdGlvbiIpdGhyb3cgRXJyb3IoImNvcmUgbXVzdCBiZSBhIGZ1bmN0aW9uIik7cmV0dXJuIGgkKFkpLGgkKFgpLGJKKFYpLGJKKFopLChXLHosSyxGLE49MCk9PntvKFcpLG8oeiksbyhLKTtsZXQgVT1LLmxlbmd0aDtpZihGPT09dm9pZCAwKUY9bmV3IFVpbnQ4QXJyYXkoVSk7aWYobyhGKSxoJChOKSxOPDB8fE4+PU9RKXRocm93IEVycm9yKCJhcng6IGNvdW50ZXIgb3ZlcmZsb3ciKTtpZihGLmxlbmd0aDxVKXRocm93IEVycm9yKGBhcng6IG91dHB1dCAoJHtGLmxlbmd0aH0pIGlzIHNob3J0ZXIgdGhhbiBkYXRhICgke1V9KWApO2xldCBSPVtdLHE9Vy5sZW5ndGgsSCxNO2lmKHE9PT0zMilSLnB1c2goSD1sJChXKSksTT1KVjtlbHNlIGlmKHE9PT0xNiYmWilIPW5ldyBVaW50OEFycmF5KDMyKSxILnNldChXKSxILnNldChXLDE2KSxNPSRWLFIucHVzaChIKTtlbHNlIHRocm93IEVycm9yKGBhcng6IGludmFsaWQgMzItYnl0ZSBrZXksIGdvdCBsZW5ndGg9JHtxfWApO2lmKCFpSih6KSlSLnB1c2goej1sJCh6KSk7bGV0IFA9QzAoSCk7aWYoUSl7aWYoei5sZW5ndGghPT0yNCl0aHJvdyBFcnJvcigiYXJ4OiBleHRlbmRlZCBub25jZSBtdXN0IGJlIDI0IGJ5dGVzIik7UShNLFAsQzAoei5zdWJhcnJheSgwLDE2KSksUCksej16LnN1YmFycmF5KDE2KX1sZXQgQz0xNi1ZO2lmKEMhPT16Lmxlbmd0aCl0aHJvdyBFcnJvcihgYXJ4OiBub25jZSBtdXN0IGJlICR7Q30gb3IgMTYgYnl0ZXNgKTtpZihDIT09MTIpe2xldCBJPW5ldyBVaW50OEFycmF5KDEyKTtJLnNldCh6LFY/MDoxMi16Lmxlbmd0aCksej1JLFIucHVzaCh6KX1sZXQgVD1DMCh6KTtyZXR1cm4gUVYoJCxNLFAsVCxLLEYsTixYKSxxMCguLi5SKSxGfX12YXIgcz0oJCxKKT0+JFtKKytdJjI1NXwoJFtKKytdJjI1NSk8PDg7Y2xhc3MgUlF7Y29uc3RydWN0b3IoJCl7dGhpcy5ibG9ja0xlbj0xNix0aGlzLm91dHB1dExlbj0xNix0aGlzLmJ1ZmZlcj1uZXcgVWludDhBcnJheSgxNiksdGhpcy5yPW5ldyBVaW50MTZBcnJheSgxMCksdGhpcy5oPW5ldyBVaW50MTZBcnJheSgxMCksdGhpcy5wYWQ9bmV3IFVpbnQxNkFycmF5KDgpLHRoaXMucG9zPTAsdGhpcy5maW5pc2hlZD0hMSwkPWkkKCQpLG8oJCwzMik7bGV0IEo9cygkLDApLFo9cygkLDIpLFE9cygkLDQpLFk9cygkLDYpLFY9cygkLDgpLFg9cygkLDEwKSxXPXMoJCwxMiksej1zKCQsMTQpO3RoaXMuclswXT1KJjgxOTEsdGhpcy5yWzFdPShKPj4+MTN8Wjw8MykmODE5MSx0aGlzLnJbMl09KFo+Pj4xMHxRPDw2KSY3OTM5LHRoaXMuclszXT0oUT4+Pjd8WTw8OSkmODE5MSx0aGlzLnJbNF09KFk+Pj40fFY8PDEyKSYyNTUsdGhpcy5yWzVdPVY+Pj4xJjgxOTAsdGhpcy5yWzZdPShWPj4+MTR8WDw8MikmODE5MSx0aGlzLnJbN109KFg+Pj4xMXxXPDw1KSY4MDY1LHRoaXMucls4XT0oVz4+Pjh8ejw8OCkmODE5MSx0aGlzLnJbOV09ej4+PjUmMTI3O2ZvcihsZXQgSz0wO0s8ODtLKyspdGhpcy5wYWRbS109cygkLDE2KzIqSyl9cHJvY2VzcygkLEosWj0hMSl7bGV0IFE9Wj8wOjIwNDgse2g6WSxyOlZ9PXRoaXMsWD1WWzBdLFc9VlsxXSx6PVZbMl0sSz1WWzNdLEY9Vls0XSxOPVZbNV0sVT1WWzZdLFI9Vls3XSxxPVZbOF0sSD1WWzldLE09cygkLEorMCksUD1zKCQsSisyKSxDPXMoJCxKKzQpLFQ9cygkLEorNiksST1zKCQsSis4KSxBPXMoJCxKKzEwKSxMPXMoJCxKKzEyKSxnPXMoJCxKKzE0KSxmPVlbMF0rKE0mODE5MSksaz1ZWzFdKygoTT4+PjEzfFA8PDMpJjgxOTEpLHk9WVsyXSsoKFA+Pj4xMHxDPDw2KSY4MTkxKSxoPVlbM10rKChDPj4+N3xUPDw5KSY4MTkxKSx3PVlbNF0rKChUPj4+NHxJPDwxMikmODE5MSkscD1ZWzVdKyhJPj4+MSY4MTkxKSx4PVlbNl0rKChJPj4+MTR8QTw8MikmODE5MSksdj1ZWzddKygoQT4+PjExfEw8PDUpJjgxOTEpLEU9WVs4XSsoKEw+Pj44fGc8PDgpJjgxOTEpLGk9WVs5XSsoZz4+PjV8USksXz0wLGQ9XytmKlgrayooNSpIKSt5Kig1KnEpK2gqKDUqUikrdyooNSpVKTtfPWQ+Pj4xMyxkJj04MTkxLGQrPXAqKDUqTikreCooNSpGKSt2Kig1KkspK0UqKDUqeikraSooNSpXKSxfKz1kPj4+MTMsZCY9ODE5MTtsZXQgdD1fK2YqVytrKlgreSooNSpIKStoKig1KnEpK3cqKDUqUik7Xz10Pj4+MTMsdCY9ODE5MSx0Kz1wKig1KlUpK3gqKDUqTikrdiooNSpGKStFKig1KkspK2kqKDUqeiksXys9dD4+PjEzLHQmPTgxOTE7bGV0IFkwPV8rZip6K2sqVyt5KlgraCooNSpIKSt3Kig1KnEpO189WTA+Pj4xMyxZMCY9ODE5MSxZMCs9cCooNSpSKSt4Kig1KlUpK3YqKDUqTikrRSooNSpGKStpKig1KkspLF8rPVkwPj4+MTMsWTAmPTgxOTE7bGV0IGM9XytmKksrayp6K3kqVytoKlgrdyooNSpIKTtfPWM+Pj4xMyxjJj04MTkxLGMrPXAqKDUqcSkreCooNSpSKSt2Kig1KlUpK0UqKDUqTikraSooNSpGKSxfKz1jPj4+MTMsYyY9ODE5MTtsZXQgSTA9XytmKkYraypLK3kqeitoKlcrdypYO189STA+Pj4xMyxJMCY9ODE5MSxJMCs9cCooNSpIKSt4Kig1KnEpK3YqKDUqUikrRSooNSpVKStpKig1Kk4pLF8rPUkwPj4+MTMsSTAmPTgxOTE7bGV0IHUwPV8rZipOK2sqRit5KksraCp6K3cqVztfPXUwPj4+MTMsdTAmPTgxOTEsdTArPXAqWCt4Kig1KkgpK3YqKDUqcSkrRSooNSpSKStpKig1KlUpLF8rPXUwPj4+MTMsdTAmPTgxOTE7bGV0IHAwPV8rZipVK2sqTit5KkYraCpLK3cqejtfPXAwPj4+MTMscDAmPTgxOTEscDArPXAqVyt4KlgrdiooNSpIKStFKig1KnEpK2kqKDUqUiksXys9cDA+Pj4xMyxwMCY9ODE5MTtsZXQgYzA9XytmKlIraypVK3kqTitoKkYrdypLO189YzA+Pj4xMyxjMCY9ODE5MSxjMCs9cCp6K3gqVyt2KlgrRSooNSpIKStpKig1KnEpLF8rPWMwPj4+MTMsYzAmPTgxOTE7bGV0IG4wPV8rZipxK2sqUit5KlUraCpOK3cqRjtfPW4wPj4+MTMsbjAmPTgxOTEsbjArPXAqSyt4KnordipXK0UqWCtpKig1KkgpLF8rPW4wPj4+MTMsbjAmPTgxOTE7bGV0IGQwPV8rZipIK2sqcSt5KlIraCpVK3cqTjtfPWQwPj4+MTMsZDAmPTgxOTEsZDArPXAqRit4Kksrdip6K0UqVytpKlgsXys9ZDA+Pj4xMyxkMCY9ODE5MSxfPShfPDwyKStffDAsXz1fK2R8MCxkPV8mODE5MSxfPV8+Pj4xMyx0Kz1fLFlbMF09ZCxZWzFdPXQsWVsyXT1ZMCxZWzNdPWMsWVs0XT1JMCxZWzVdPXUwLFlbNl09cDAsWVs3XT1jMCxZWzhdPW4wLFlbOV09ZDB9ZmluYWxpemUoKXtsZXR7aDokLHBhZDpKfT10aGlzLFo9bmV3IFVpbnQxNkFycmF5KDEwKSxRPSRbMV0+Pj4xMzskWzFdJj04MTkxO2ZvcihsZXQgWD0yO1g8MTA7WCsrKSRbWF0rPVEsUT0kW1hdPj4+MTMsJFtYXSY9ODE5MTskWzBdKz1RKjUsUT0kWzBdPj4+MTMsJFswXSY9ODE5MSwkWzFdKz1RLFE9JFsxXT4+PjEzLCRbMV0mPTgxOTEsJFsyXSs9USxaWzBdPSRbMF0rNSxRPVpbMF0+Pj4xMyxaWzBdJj04MTkxO2ZvcihsZXQgWD0xO1g8MTA7WCsrKVpbWF09JFtYXStRLFE9WltYXT4+PjEzLFpbWF0mPTgxOTE7Wls5XS09ODE5MjtsZXQgWT0oUV4xKS0xO2ZvcihsZXQgWD0wO1g8MTA7WCsrKVpbWF0mPVk7WT1+WTtmb3IobGV0IFg9MDtYPDEwO1grKykkW1hdPSRbWF0mWXxaW1hdOyRbMF09KCRbMF18JFsxXTw8MTMpJjY1NTM1LCRbMV09KCRbMV0+Pj4zfCRbMl08PDEwKSY2NTUzNSwkWzJdPSgkWzJdPj4+NnwkWzNdPDw3KSY2NTUzNSwkWzNdPSgkWzNdPj4+OXwkWzRdPDw0KSY2NTUzNSwkWzRdPSgkWzRdPj4+MTJ8JFs1XTw8MXwkWzZdPDwxNCkmNjU1MzUsJFs1XT0oJFs2XT4+PjJ8JFs3XTw8MTEpJjY1NTM1LCRbNl09KCRbN10+Pj41fCRbOF08PDgpJjY1NTM1LCRbN109KCRbOF0+Pj44fCRbOV08PDUpJjY1NTM1O2xldCBWPSRbMF0rSlswXTskWzBdPVYmNjU1MzU7Zm9yKGxldCBYPTE7WDw4O1grKylWPSgkW1hdK0pbWF18MCkrKFY+Pj4xNil8MCwkW1hdPVYmNjU1MzU7cTAoWil9dXBkYXRlKCQpe3lKKHRoaXMpO2xldHtidWZmZXI6SixibG9ja0xlbjpafT10aGlzOyQ9aSQoJCk7bGV0IFE9JC5sZW5ndGg7Zm9yKGxldCBZPTA7WTxROyl7bGV0IFY9TWF0aC5taW4oWi10aGlzLnBvcyxRLVkpO2lmKFY9PT1aKXtmb3IoO1o8PVEtWTtZKz1aKXRoaXMucHJvY2VzcygkLFkpO2NvbnRpbnVlfWlmKEouc2V0KCQuc3ViYXJyYXkoWSxZK1YpLHRoaXMucG9zKSx0aGlzLnBvcys9VixZKz1WLHRoaXMucG9zPT09Wil0aGlzLnByb2Nlc3MoSiwwLCExKSx0aGlzLnBvcz0wfXJldHVybiB0aGlzfWRlc3Ryb3koKXtxMCh0aGlzLmgsdGhpcy5yLHRoaXMuYnVmZmVyLHRoaXMucGFkKX1kaWdlc3RJbnRvKCQpe3lKKHRoaXMpLFdRKCQsdGhpcyksdGhpcy5maW5pc2hlZD0hMDtsZXR7YnVmZmVyOkosaDpafT10aGlzLHtwb3M6UX09dGhpcztpZihRKXtKW1ErK109MTtmb3IoO1E8MTY7USsrKUpbUV09MDt0aGlzLnByb2Nlc3MoSiwwLCEwKX10aGlzLmZpbmFsaXplKCk7bGV0IFk9MDtmb3IobGV0IFY9MDtWPDg7VisrKSRbWSsrXT1aW1ZdPj4+MCwkW1krK109WltWXT4+Pjg7cmV0dXJuICR9ZGlnZXN0KCl7bGV0e2J1ZmZlcjokLG91dHB1dExlbjpKfT10aGlzO3RoaXMuZGlnZXN0SW50bygkKTtsZXQgWj0kLnNsaWNlKDAsSik7cmV0dXJuIHRoaXMuZGVzdHJveSgpLFp9fWZ1bmN0aW9uIFlWKCQpe2xldCBKPShRLFkpPT4kKFkpLnVwZGF0ZShpJChRKSkuZGlnZXN0KCksWj0kKG5ldyBVaW50OEFycmF5KDMyKSk7cmV0dXJuIEoub3V0cHV0TGVuPVoub3V0cHV0TGVuLEouYmxvY2tMZW49Wi5ibG9ja0xlbixKLmNyZWF0ZT0oUSk9PiQoUSksSn12YXIgbEo9WVYoKCQpPT5uZXcgUlEoJCkpO2Z1bmN0aW9uIFZWKCQsSixaLFEsWSxWPTIwKXtsZXQgWD0kWzBdLFc9SlswXSx6PUpbMV0sSz1KWzJdLEY9SlszXSxOPSRbMV0sVT1aWzBdLFI9WlsxXSxxPVksSD0wLE09JFsyXSxQPUpbNF0sQz1KWzVdLFQ9Sls2XSxJPUpbN10sQT0kWzNdLEw9WCxnPVcsZj16LGs9Syx5PUYsaD1OLHc9VSxwPVIseD1xLHY9SCxFPU0saT1QLF89QyxkPVQsdD1JLFkwPUE7Zm9yKGxldCBJMD0wO0kwPFY7STArPTIpeV49aihMK198MCw3KSx4Xj1qKHkrTHwwLDkpLF9ePWooeCt5fDAsMTMpLExePWooXyt4fDAsMTgpLHZePWooaCtnfDAsNyksZF49aih2K2h8MCw5KSxnXj1qKGQrdnwwLDEzKSxoXj1qKGcrZHwwLDE4KSx0Xj1qKEUrd3wwLDcpLGZePWoodCtFfDAsOSksd149aihmK3R8MCwxMyksRV49aih3K2Z8MCwxOCksa149aihZMCtpfDAsNykscF49aihrK1kwfDAsOSksaV49aihwK2t8MCwxMyksWTBePWooaStwfDAsMTgpLGdePWooTCtrfDAsNyksZl49aihnK0x8MCw5KSxrXj1qKGYrZ3wwLDEzKSxMXj1qKGsrZnwwLDE4KSx3Xj1qKGgreXwwLDcpLHBePWoodytofDAsOSkseV49aihwK3d8MCwxMyksaF49aih5K3B8MCwxOCksaV49aihFK3Z8MCw3KSx4Xj1qKGkrRXwwLDkpLHZePWooeCtpfDAsMTMpLEVePWoodit4fDAsMTgpLF9ePWooWTArdHwwLDcpLGRePWooXytZMHwwLDkpLHRePWooZCtffDAsMTMpLFkwXj1qKHQrZHwwLDE4KTtsZXQgYz0wO1FbYysrXT1YK0x8MCxRW2MrK109VytnfDAsUVtjKytdPXorZnwwLFFbYysrXT1LK2t8MCxRW2MrK109Rit5fDAsUVtjKytdPU4raHwwLFFbYysrXT1VK3d8MCxRW2MrK109UitwfDAsUVtjKytdPXEreHwwLFFbYysrXT1IK3Z8MCxRW2MrK109TStFfDAsUVtjKytdPVAraXwwLFFbYysrXT1DK198MCxRW2MrK109VCtkfDAsUVtjKytdPUkrdHwwLFFbYysrXT1BK1kwfDB9ZnVuY3Rpb24gWFYoJCxKLFosUSl7bGV0IFk9JFswXSxWPUpbMF0sWD1KWzFdLFc9SlsyXSx6PUpbM10sSz0kWzFdLEY9WlswXSxOPVpbMV0sVT1aWzJdLFI9WlszXSxxPSRbMl0sSD1KWzRdLE09Sls1XSxQPUpbNl0sQz1KWzddLFQ9JFszXTtmb3IobGV0IEE9MDtBPDIwO0ErPTIpel49aihZK018MCw3KSxVXj1qKHorWXwwLDkpLE1ePWooVSt6fDAsMTMpLFlePWooTStVfDAsMTgpLFJePWooSytWfDAsNyksUF49aihSK0t8MCw5KSxWXj1qKFArUnwwLDEzKSxLXj1qKFYrUHwwLDE4KSxDXj1qKHErRnwwLDcpLFhePWooQytxfDAsOSksRl49aihYK0N8MCwxMykscV49aihGK1h8MCwxOCksV149aihUK0h8MCw3KSxOXj1qKFcrVHwwLDkpLEhePWooTitXfDAsMTMpLFRePWooSCtOfDAsMTgpLFZePWooWStXfDAsNyksWF49aihWK1l8MCw5KSxXXj1qKFgrVnwwLDEzKSxZXj1qKFcrWHwwLDE4KSxGXj1qKEsrenwwLDcpLE5ePWooRitLfDAsOSksel49aihOK0Z8MCwxMyksS149aih6K058MCwxOCksSF49aihxK1J8MCw3KSxVXj1qKEgrcXwwLDkpLFJePWooVStIfDAsMTMpLHFePWooUitVfDAsMTgpLE1ePWooVCtDfDAsNyksUF49aihNK1R8MCw5KSxDXj1qKFArTXwwLDEzKSxUXj1qKEMrUHwwLDE4KTtsZXQgST0wO1FbSSsrXT1ZLFFbSSsrXT1LLFFbSSsrXT1xLFFbSSsrXT1ULFFbSSsrXT1GLFFbSSsrXT1OLFFbSSsrXT1VLFFbSSsrXT1SfXZhciB1Sj1VUShWVix7Y291bnRlclJpZ2h0OiEwLGV4dGVuZE5vbmNlRm46WFZ9KSxwSj1LUSh7YmxvY2tTaXplOjY0LG5vbmNlTGVuZ3RoOjI0LHRhZ0xlbmd0aDoxNn0sKCQsSik9PntyZXR1cm57ZW5jcnlwdChaLFEpe1E9aEooWi5sZW5ndGgrMzIsUSwhMSk7bGV0IFk9US5zdWJhcnJheSgwLDMyKSxWPVEuc3ViYXJyYXkoMzIpO1Euc2V0KFosMzIpLHEwKFkpLHVKKCQsSixRLFEpO2xldCBYPWxKKFYsWSk7cmV0dXJuIFEuc2V0KFgsMTYpLHEwKFEuc3ViYXJyYXkoMCwxNiksWCksUS5zdWJhcnJheSgxNil9LGRlY3J5cHQoWixRKXtvKFopLFE9aEooWi5sZW5ndGgrMzIsUSwhMSk7bGV0IFk9US5zdWJhcnJheSgwLDMyKSxWPVEuc3ViYXJyYXkoMzIsNDgpLFg9US5zdWJhcnJheSg0OCk7US5zZXQoWiwzMikscTAoWSk7bGV0IFc9dUooJCxKLFksWSksej1sSihYLFcpO2lmKCF6UShWLHopKXRocm93IEVycm9yKCJpbnZhbGlkIHRhZyIpO3JldHVybiB1SigkLEosUS5zdWJhcnJheSgxNiksUS5zdWJhcnJheSgxNikpLHEwKFksVix6KSxYfX19KTsvKiEgbm9ibGUtaGFzaGVzIC0gTUlUIExpY2Vuc2UgKGMpIDIwMjIgUGF1bCBNaWxsZXIgKHBhdWxtaWxsci5jb20pICovZnVuY3Rpb24gV1YoJCl7cmV0dXJuICQgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxBcnJheUJ1ZmZlci5pc1ZpZXcoJCkmJiQuY29uc3RydWN0b3IubmFtZT09PSJVaW50OEFycmF5In1mdW5jdGlvbiBSJCgkKXtpZighTnVtYmVyLmlzU2FmZUludGVnZXIoJCl8fCQ8MCl0aHJvdyBFcnJvcigicG9zaXRpdmUgaW50ZWdlciBleHBlY3RlZCwgZ290ICIrJCl9ZnVuY3Rpb24gbTAoJCwuLi5KKXtpZighV1YoJCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQiKTtpZihKLmxlbmd0aD4wJiYhSi5pbmNsdWRlcygkLmxlbmd0aCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQgb2YgbGVuZ3RoICIrSisiLCBnb3QgbGVuZ3RoPSIrJC5sZW5ndGgpfWZ1bmN0aW9uIEgkKCQsSj0hMCl7aWYoJC5kZXN0cm95ZWQpdGhyb3cgRXJyb3IoIkhhc2ggaW5zdGFuY2UgaGFzIGJlZW4gZGVzdHJveWVkIik7aWYoSiYmJC5maW5pc2hlZCl0aHJvdyBFcnJvcigiSGFzaCNkaWdlc3QoKSBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZCIpfWZ1bmN0aW9uIHAkKCQsSil7bTAoJCk7bGV0IFo9Si5vdXRwdXRMZW47aWYoJC5sZW5ndGg8Wil0aHJvdyBFcnJvcigiZGlnZXN0SW50bygpIGV4cGVjdHMgb3V0cHV0IGJ1ZmZlciBvZiBsZW5ndGggYXQgbGVhc3QgIitaKX1mdW5jdGlvbiBIUSgkKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LCQuYnl0ZUxlbmd0aCl9ZnVuY3Rpb24gWSQoJCl7cmV0dXJuIG5ldyBVaW50MzJBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsTWF0aC5mbG9vcigkLmJ5dGVMZW5ndGgvNCkpfWZ1bmN0aW9uIFYkKC4uLiQpe2ZvcihsZXQgSj0wO0o8JC5sZW5ndGg7SisrKSRbSl0uZmlsbCgwKX1mdW5jdGlvbiBxJCgkLEope3JldHVybiAkPDwzMi1KfCQ+Pj5KfXZhciBxUT0oKCk9Pm5ldyBVaW50OEFycmF5KG5ldyBVaW50MzJBcnJheShbMjg3NDU0MDIwXSkuYnVmZmVyKVswXT09PTY4KSgpO2Z1bmN0aW9uIE1RKCQpe3JldHVybiAkPDwyNCY0Mjc4MTkwMDgwfCQ8PDgmMTY3MTE2ODB8JD4+PjgmNjUyODB8JD4+PjI0JjI1NX12YXIgSVE9cVE/KCQpPT4kOigkKT0+TVEoJCk7ZnVuY3Rpb24gR1YoJCl7Zm9yKGxldCBKPTA7SjwkLmxlbmd0aDtKKyspJFtKXT1NUSgkW0pdKTtyZXR1cm4gJH12YXIgSjA9cVE/KCQpPT4kOkdWO2Z1bmN0aW9uIHpWKCQpe2lmKHR5cGVvZiAkIT09InN0cmluZyIpdGhyb3cgRXJyb3IoInN0cmluZyBleHBlY3RlZCIpO3JldHVybiBuZXcgVWludDhBcnJheShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCkpfWZ1bmN0aW9uIFgkKCQpe2lmKHR5cGVvZiAkPT09InN0cmluZyIpJD16VigkKTtyZXR1cm4gbTAoJCksJH1jbGFzcyBjSnt9ZnVuY3Rpb24gQ1EoJCl7bGV0IEo9KFEsWSk9PiQoWSkudXBkYXRlKFgkKFEpKS5kaWdlc3QoKSxaPSQoe30pO3JldHVybiBKLm91dHB1dExlbj1aLm91dHB1dExlbixKLmJsb2NrTGVuPVouYmxvY2tMZW4sSi5jcmVhdGU9KFEpPT4kKFEpLEp9dmFyIFBRPVVpbnQzMkFycmF5LmZyb20oWzE3NzkwMzM3MDMsMzE0NDEzNDI3NywxMDEzOTA0MjQyLDI3NzM0ODA3NjIsMTM1OTg5MzExOSwyNjAwODIyOTI0LDUyODczNDYzNSwxNTQxNDU5MjI1XSk7dmFyIGMkPUJpZ0ludCg0Mjk0OTY3Mjk1KSx3UT1CaWdJbnQoMzIpO2Z1bmN0aW9uIG5KKCQsSj0hMSl7aWYoSilyZXR1cm57aDpOdW1iZXIoJCZjJCksbDpOdW1iZXIoJD4+d1EmYyQpfTtyZXR1cm57aDpOdW1iZXIoJD4+d1EmYyQpfDAsbDpOdW1iZXIoJCZjJCl8MH19ZnVuY3Rpb24gUDAoJCxKLFosUSxZKXtyZXR1cm4gJD0kK0orWXwwLFE9cSQoUV4kLDE2KSxaPVorUXwwLEo9cSQoSl5aLDEyKSx7YTokLGI6SixjOlosZDpRfX1mdW5jdGlvbiB3MCgkLEosWixRLFkpe3JldHVybiAkPSQrSitZfDAsUT1xJChRXiQsOCksWj1aK1F8MCxKPXEkKEpeWiw3KSx7YTokLGI6SixjOlosZDpRfX1jbGFzcyBkSiBleHRlbmRzIGNKe2NvbnN0cnVjdG9yKCQsSil7c3VwZXIoKTt0aGlzLmZpbmlzaGVkPSExLHRoaXMuZGVzdHJveWVkPSExLHRoaXMubGVuZ3RoPTAsdGhpcy5wb3M9MCxSJCgkKSxSJChKKSx0aGlzLmJsb2NrTGVuPSQsdGhpcy5vdXRwdXRMZW49Six0aGlzLmJ1ZmZlcj1uZXcgVWludDhBcnJheSgkKSx0aGlzLmJ1ZmZlcjMyPVkkKHRoaXMuYnVmZmVyKX11cGRhdGUoJCl7SCQodGhpcyksJD1YJCgkKSxtMCgkKTtsZXR7YmxvY2tMZW46SixidWZmZXI6WixidWZmZXIzMjpRfT10aGlzLFk9JC5sZW5ndGgsVj0kLmJ5dGVPZmZzZXQsWD0kLmJ1ZmZlcjtmb3IobGV0IFc9MDtXPFk7KXtpZih0aGlzLnBvcz09PUopSjAoUSksdGhpcy5jb21wcmVzcyhRLDAsITEpLEowKFEpLHRoaXMucG9zPTA7bGV0IHo9TWF0aC5taW4oSi10aGlzLnBvcyxZLVcpLEs9VitXO2lmKHo9PT1KJiYhKEslNCkmJlcrejxZKXtsZXQgRj1uZXcgVWludDMyQXJyYXkoWCxLLE1hdGguZmxvb3IoKFktVykvNCkpO0owKEYpO2ZvcihsZXQgTj0wO1crSjxZO04rPVEubGVuZ3RoLFcrPUopdGhpcy5sZW5ndGgrPUosdGhpcy5jb21wcmVzcyhGLE4sITEpO0owKEYpO2NvbnRpbnVlfVouc2V0KCQuc3ViYXJyYXkoVyxXK3opLHRoaXMucG9zKSx0aGlzLnBvcys9eix0aGlzLmxlbmd0aCs9eixXKz16fXJldHVybiB0aGlzfWRpZ2VzdEludG8oJCl7SCQodGhpcykscCQoJCx0aGlzKTtsZXR7cG9zOkosYnVmZmVyMzI6Wn09dGhpczt0aGlzLmZpbmlzaGVkPSEwLFYkKHRoaXMuYnVmZmVyLnN1YmFycmF5KEopKSxKMChaKSx0aGlzLmNvbXByZXNzKFosMCwhMCksSjAoWik7bGV0IFE9WSQoJCk7dGhpcy5nZXQoKS5mb3JFYWNoKChZLFYpPT5RW1ZdPUlRKFkpKX1kaWdlc3QoKXtsZXR7YnVmZmVyOiQsb3V0cHV0TGVuOkp9PXRoaXM7dGhpcy5kaWdlc3RJbnRvKCQpO2xldCBaPSQuc2xpY2UoMCxKKTtyZXR1cm4gdGhpcy5kZXN0cm95KCksWn1fY2xvbmVJbnRvKCQpe2xldHtidWZmZXI6SixsZW5ndGg6WixmaW5pc2hlZDpRLGRlc3Ryb3llZDpZLG91dHB1dExlbjpWLHBvczpYfT10aGlzO3JldHVybiAkfHwoJD1uZXcgdGhpcy5jb25zdHJ1Y3Rvcih7ZGtMZW46Vn0pKSwkLnNldCguLi50aGlzLmdldCgpKSwkLmJ1ZmZlci5zZXQoSiksJC5kZXN0cm95ZWQ9WSwkLmZpbmlzaGVkPVEsJC5sZW5ndGg9WiwkLnBvcz1YLCQub3V0cHV0TGVuPVYsJH1jbG9uZSgpe3JldHVybiB0aGlzLl9jbG9uZUludG8oKX19ZnVuY3Rpb24gckooJCxKLFosUSxZLFYsWCxXLHosSyxGLE4sVSxSLHEsSCxNLFAsQyxUKXtsZXQgST0wO2ZvcihsZXQgQT0wO0E8UTtBKyspKHthOlksYjp6LGM6VSxkOk19PVAwKFkseixVLE0sWltKKyRbSSsrXV0pKSx7YTpZLGI6eixjOlUsZDpNfT13MChZLHosVSxNLFpbSiskW0krK11dKSx7YTpWLGI6SyxjOlIsZDpQfT1QMChWLEssUixQLFpbSiskW0krK11dKSx7YTpWLGI6SyxjOlIsZDpQfT13MChWLEssUixQLFpbSiskW0krK11dKSx7YTpYLGI6RixjOnEsZDpDfT1QMChYLEYscSxDLFpbSiskW0krK11dKSx7YTpYLGI6RixjOnEsZDpDfT13MChYLEYscSxDLFpbSiskW0krK11dKSx7YTpXLGI6TixjOkgsZDpUfT1QMChXLE4sSCxULFpbSiskW0krK11dKSx7YTpXLGI6TixjOkgsZDpUfT13MChXLE4sSCxULFpbSiskW0krK11dKSx7YTpZLGI6SyxjOnEsZDpUfT1QMChZLEsscSxULFpbSiskW0krK11dKSx7YTpZLGI6SyxjOnEsZDpUfT13MChZLEsscSxULFpbSiskW0krK11dKSx7YTpWLGI6RixjOkgsZDpNfT1QMChWLEYsSCxNLFpbSiskW0krK11dKSx7YTpWLGI6RixjOkgsZDpNfT13MChWLEYsSCxNLFpbSiskW0krK11dKSx7YTpYLGI6TixjOlUsZDpQfT1QMChYLE4sVSxQLFpbSiskW0krK11dKSx7YTpYLGI6TixjOlUsZDpQfT13MChYLE4sVSxQLFpbSiskW0krK11dKSx7YTpXLGI6eixjOlIsZDpDfT1QMChXLHosUixDLFpbSiskW0krK11dKSx7YTpXLGI6eixjOlIsZDpDfT13MChXLHosUixDLFpbSiskW0krK11dKTtyZXR1cm57djA6WSx2MTpWLHYyOlgsdjM6Vyx2NDp6LHY1OkssdjY6Rix2NzpOLHY4OlUsdjk6Uix2MTA6cSx2MTE6SCx2MTI6TSx2MTM6UCx2MTQ6Qyx2MTU6VH19dmFyIE0wPXtDSFVOS19TVEFSVDoxLENIVU5LX0VORDoyLFBBUkVOVDo0LFJPT1Q6OCxLRVlFRF9IQVNIOjE2LERFUklWRV9LRVlfQ09OVEVYVDozMixERVJJVkVfS0VZX01BVEVSSUFMOjY0fSxUMD1QUS5zbGljZSgpLFRRPSgoKT0+e2xldCAkPUFycmF5LmZyb20oe2xlbmd0aDoxNn0sKFEsWSk9PlkpLEo9KFEpPT5bMiw2LDMsMTAsNywwLDQsMTMsMSwxMSwxMiw1LDksMTQsMTUsOF0ubWFwKChZKT0+UVtZXSksWj1bXTtmb3IobGV0IFE9MCxZPSQ7UTw3O1ErKyxZPUooWSkpWi5wdXNoKC4uLlkpO3JldHVybiBVaW50OEFycmF5LmZyb20oWil9KSgpO2NsYXNzIG9KIGV4dGVuZHMgZEp7Y29uc3RydWN0b3IoJD17fSxKPTApe3N1cGVyKDY0LCQuZGtMZW49PT12b2lkIDA/MzI6JC5ka0xlbik7dGhpcy5jaHVua1Bvcz0wLHRoaXMuY2h1bmtzRG9uZT0wLHRoaXMuZmxhZ3M9MCx0aGlzLnN0YWNrPVtdLHRoaXMucG9zT3V0PTAsdGhpcy5idWZmZXJPdXQzMj1uZXcgVWludDMyQXJyYXkoMTYpLHRoaXMuY2h1bmtPdXQ9MCx0aGlzLmVuYWJsZVhPRj0hMDtsZXR7a2V5OlosY29udGV4dDpRfT0kLFk9USE9PXZvaWQgMDtpZihaIT09dm9pZCAwKXtpZihZKXRocm93IEVycm9yKCdPbmx5ICJrZXkiIG9yICJjb250ZXh0IiBjYW4gYmUgc3BlY2lmaWVkIGF0IHNhbWUgdGltZScpO2xldCBWPVgkKFopLnNsaWNlKCk7bTAoViwzMiksdGhpcy5JVj1ZJChWKSxKMCh0aGlzLklWKSx0aGlzLmZsYWdzPUp8TTAuS0VZRURfSEFTSH1lbHNlIGlmKFkpe2xldCBWPVgkKFEpLFg9bmV3IG9KKHtka0xlbjozMn0sTTAuREVSSVZFX0tFWV9DT05URVhUKS51cGRhdGUoVikuZGlnZXN0KCk7dGhpcy5JVj1ZJChYKSxKMCh0aGlzLklWKSx0aGlzLmZsYWdzPUp8TTAuREVSSVZFX0tFWV9NQVRFUklBTH1lbHNlIHRoaXMuSVY9VDAuc2xpY2UoKSx0aGlzLmZsYWdzPUo7dGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCksdGhpcy5idWZmZXJPdXQ9SFEodGhpcy5idWZmZXJPdXQzMil9Z2V0KCl7cmV0dXJuW119c2V0KCl7fWIyQ29tcHJlc3MoJCxKLFosUT0wKXtsZXR7c3RhdGU6WSxwb3M6Vn09dGhpcyx7aDpYLGw6V309bkooQmlnSW50KCQpLCEwKSx7djA6eix2MTpLLHYyOkYsdjM6Tix2NDpVLHY1OlIsdjY6cSx2NzpILHY4Ok0sdjk6UCx2MTA6Qyx2MTE6VCx2MTI6SSx2MTM6QSx2MTQ6TCx2MTU6Z309ckooVFEsUSxaLDcsWVswXSxZWzFdLFlbMl0sWVszXSxZWzRdLFlbNV0sWVs2XSxZWzddLFQwWzBdLFQwWzFdLFQwWzJdLFQwWzNdLFgsVyxWLEopO1lbMF09el5NLFlbMV09S15QLFlbMl09Rl5DLFlbM109Tl5ULFlbNF09VV5JLFlbNV09Ul5BLFlbNl09cV5MLFlbN109SF5nfWNvbXByZXNzKCQsSj0wLFo9ITEpe2xldCBRPXRoaXMuZmxhZ3M7aWYoIXRoaXMuY2h1bmtQb3MpUXw9TTAuQ0hVTktfU1RBUlQ7aWYodGhpcy5jaHVua1Bvcz09PTE1fHxaKVF8PU0wLkNIVU5LX0VORDtpZighWil0aGlzLnBvcz10aGlzLmJsb2NrTGVuO2lmKHRoaXMuYjJDb21wcmVzcyh0aGlzLmNodW5rc0RvbmUsUSwkLEopLHRoaXMuY2h1bmtQb3MrPTEsdGhpcy5jaHVua1Bvcz09PTE2fHxaKXtsZXQgWT10aGlzLnN0YXRlO3RoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpO2ZvcihsZXQgVixYPXRoaXMuY2h1bmtzRG9uZSsxO1p8fCEoWCYxKTtYPj49MSl7aWYoIShWPXRoaXMuc3RhY2sucG9wKCkpKWJyZWFrO3RoaXMuYnVmZmVyMzIuc2V0KFYsMCksdGhpcy5idWZmZXIzMi5zZXQoWSw4KSx0aGlzLnBvcz10aGlzLmJsb2NrTGVuLHRoaXMuYjJDb21wcmVzcygwLHRoaXMuZmxhZ3N8TTAuUEFSRU5ULHRoaXMuYnVmZmVyMzIsMCksWT10aGlzLnN0YXRlLHRoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpfXRoaXMuY2h1bmtzRG9uZSsrLHRoaXMuY2h1bmtQb3M9MCx0aGlzLnN0YWNrLnB1c2goWSl9dGhpcy5wb3M9MH1fY2xvbmVJbnRvKCQpeyQ9c3VwZXIuX2Nsb25lSW50bygkKTtsZXR7SVY6SixmbGFnczpaLHN0YXRlOlEsY2h1bmtQb3M6WSxwb3NPdXQ6VixjaHVua091dDpYLHN0YWNrOlcsY2h1bmtzRG9uZTp6fT10aGlzO3JldHVybiAkLnN0YXRlLnNldChRLnNsaWNlKCkpLCQuc3RhY2s9Vy5tYXAoKEspPT5VaW50MzJBcnJheS5mcm9tKEspKSwkLklWLnNldChKKSwkLmZsYWdzPVosJC5jaHVua1Bvcz1ZLCQuY2h1bmtzRG9uZT16LCQucG9zT3V0PVYsJC5jaHVua091dD1YLCQuZW5hYmxlWE9GPXRoaXMuZW5hYmxlWE9GLCQuYnVmZmVyT3V0MzIuc2V0KHRoaXMuYnVmZmVyT3V0MzIpLCR9ZGVzdHJveSgpe3RoaXMuZGVzdHJveWVkPSEwLFYkKHRoaXMuc3RhdGUsdGhpcy5idWZmZXIzMix0aGlzLklWLHRoaXMuYnVmZmVyT3V0MzIpLFYkKC4uLnRoaXMuc3RhY2spfWIyQ29tcHJlc3NPdXQoKXtsZXR7c3RhdGU6JCxwb3M6SixmbGFnczpaLGJ1ZmZlcjMyOlEsYnVmZmVyT3V0MzI6WX09dGhpcyx7aDpWLGw6WH09bkooQmlnSW50KHRoaXMuY2h1bmtPdXQrKykpO0owKFEpO2xldHt2MDpXLHYxOnosdjI6Syx2MzpGLHY0Ok4sdjU6VSx2NjpSLHY3OnEsdjg6SCx2OTpNLHYxMDpQLHYxMTpDLHYxMjpULHYxMzpJLHYxNDpBLHYxNTpMfT1ySihUUSwwLFEsNywkWzBdLCRbMV0sJFsyXSwkWzNdLCRbNF0sJFs1XSwkWzZdLCRbN10sVDBbMF0sVDBbMV0sVDBbMl0sVDBbM10sWCxWLEosWik7WVswXT1XXkgsWVsxXT16Xk0sWVsyXT1LXlAsWVszXT1GXkMsWVs0XT1OXlQsWVs1XT1VXkksWVs2XT1SXkEsWVs3XT1xXkwsWVs4XT0kWzBdXkgsWVs5XT0kWzFdXk0sWVsxMF09JFsyXV5QLFlbMTFdPSRbM11eQyxZWzEyXT0kWzRdXlQsWVsxM109JFs1XV5JLFlbMTRdPSRbNl1eQSxZWzE1XT0kWzddXkwsSjAoUSksSjAoWSksdGhpcy5wb3NPdXQ9MH1maW5pc2goKXtpZih0aGlzLmZpbmlzaGVkKXJldHVybjt0aGlzLmZpbmlzaGVkPSEwLFYkKHRoaXMuYnVmZmVyLnN1YmFycmF5KHRoaXMucG9zKSk7bGV0ICQ9dGhpcy5mbGFnc3xNMC5ST09UO2lmKHRoaXMuc3RhY2subGVuZ3RoKSR8PU0wLlBBUkVOVCxKMCh0aGlzLmJ1ZmZlcjMyKSx0aGlzLmNvbXByZXNzKHRoaXMuYnVmZmVyMzIsMCwhMCksSjAodGhpcy5idWZmZXIzMiksdGhpcy5jaHVua3NEb25lPTAsdGhpcy5wb3M9dGhpcy5ibG9ja0xlbjtlbHNlICR8PSghdGhpcy5jaHVua1Bvcz9NMC5DSFVOS19TVEFSVDowKXxNMC5DSFVOS19FTkQ7dGhpcy5mbGFncz0kLHRoaXMuYjJDb21wcmVzc091dCgpfXdyaXRlSW50bygkKXtIJCh0aGlzLCExKSxtMCgkKSx0aGlzLmZpbmlzaCgpO2xldHtibG9ja0xlbjpKLGJ1ZmZlck91dDpafT10aGlzO2ZvcihsZXQgUT0wLFk9JC5sZW5ndGg7UTxZOyl7aWYodGhpcy5wb3NPdXQ+PUopdGhpcy5iMkNvbXByZXNzT3V0KCk7bGV0IFY9TWF0aC5taW4oSi10aGlzLnBvc091dCxZLVEpOyQuc2V0KFouc3ViYXJyYXkodGhpcy5wb3NPdXQsdGhpcy5wb3NPdXQrViksUSksdGhpcy5wb3NPdXQrPVYsUSs9Vn1yZXR1cm4gJH14b2ZJbnRvKCQpe2lmKCF0aGlzLmVuYWJsZVhPRil0aHJvdyBFcnJvcigiWE9GIGlzIG5vdCBwb3NzaWJsZSBhZnRlciBkaWdlc3QgY2FsbCIpO3JldHVybiB0aGlzLndyaXRlSW50bygkKX14b2YoJCl7cmV0dXJuIFIkKCQpLHRoaXMueG9mSW50byhuZXcgVWludDhBcnJheSgkKSl9ZGlnZXN0SW50bygkKXtpZihwJCgkLHRoaXMpLHRoaXMuZmluaXNoZWQpdGhyb3cgRXJyb3IoImRpZ2VzdCgpIHdhcyBhbHJlYWR5IGNhbGxlZCIpO3JldHVybiB0aGlzLmVuYWJsZVhPRj0hMSx0aGlzLndyaXRlSW50bygkKSx0aGlzLmRlc3Ryb3koKSwkfWRpZ2VzdCgpe3JldHVybiB0aGlzLmRpZ2VzdEludG8obmV3IFVpbnQ4QXJyYXkodGhpcy5vdXRwdXRMZW4pKX19dmFyIGpRPUNRKCgkKT0+bmV3IG9KKCQpKTt2YXIgS1Y9MzIsWUY9U3ltYm9sKCJYMjU1MTlTayIpO2Z1bmN0aW9uIERRKCQpe2lmKCQuYnl0ZUxlbmd0aCE9PUtWKXJldHVybiBHKDEwKTtyZXR1cm4gTygkKX12YXIgYj0oMW48PDI1NW4pLTE5bixGVj0xMjE2NjVuLEFRPW5ldyBVaW50OEFycmF5KDMyKTtBUVswXT05O2Z1bmN0aW9uIF9RKCQpe2xldCBKPTBuO2ZvcihsZXQgWj0kLmxlbmd0aC0xO1o+PTA7Wi0tKUo9Sjw8OG58QmlnSW50KCRbWl0pO3JldHVybiBKfWZ1bmN0aW9uIE5WKCQpe2xldCBKPW5ldyBVaW50OEFycmF5KDMyKSxaPSgkJWIrYiklYjtmb3IobGV0IFE9MDtRPDMyO1ErKylKW1FdPU51bWJlcihaJjB4ZmZuKSxaPj49OG47cmV0dXJuIEp9ZnVuY3Rpb24gT1YoJCl7bGV0IEo9JC5zbGljZSgpO3JldHVybiBKWzMxXSY9MTI3LF9RKEopfWZ1bmN0aW9uIFVWKCQpe2xldCBKPSQuc2xpY2UoKTtyZXR1cm4gSlswXSY9MjQ4LEpbMzFdJj0xMjcsSlszMV18PTY0LEp9ZnVuY3Rpb24gbiQoJCxKLFope2xldCBRPS0kLFk9KEpeWikmUTtyZXR1cm5bSl5ZLFpeWV19ZnVuY3Rpb24gUlYoJCl7bGV0IEo9Yi0ybixaPSgkJWIrYiklYixRPTFuO3doaWxlKEo+MG4pe2lmKEomMW4pUT1RKlolYjtaPVoqWiViLEo+Pj0xbn1yZXR1cm4gUX1mdW5jdGlvbiBIVigkLEope2xldCBaPVVWKCQpLFE9T1YoSiksWT0xbixWPTBuLFg9USxXPTFuLHo9MG4sSz1fUShaKTtmb3IobGV0IEY9MjU0O0Y+PTA7Ri0tKXtsZXQgTj1LPj5CaWdJbnQoRikmMW47el49TixbWSxYXT1uJCh6LFksWCksW1YsV109biQoeixWLFcpLHo9TjtsZXQgVT0oWStWKSViLFI9VSpVJWIscT0oWS1WK2IpJWIsSD1xKnElYixNPShSLUgrYiklYixQPShYK1cpJWIsVD0oWC1XK2IpJWIqVSViLEk9UCpxJWIsQT0oVCtJKSViLEw9KFQtSStiKSViO1g9QSpBJWIsVz1RKkwqTCViLFk9UipIJWIsVj1NKihSK0ZWKk0pJWJ9cmV0dXJuW1ksWF09biQoeixZLFgpLFtWLFddPW4kKHosVixXKSxaLmZpbGwoMCksTlYoWSpSVihWKSViKX1mdW5jdGlvbiBMUSgkKXtyZXR1cm4gSFYoJCxBUSl9dmFyIGFKPW5ldyBVaW50OEFycmF5KFs0OCw0NiwyLDEsMCw0OCw1LDYsMyw0MywxMDEsMTEyLDQsMzQsNCwzMl0pO2Z1bmN0aW9uIHhRKCQpe2xldCBKPW5ldyBVaW50OEFycmF5KGFKLmxlbmd0aCszMik7cmV0dXJuIEouc2V0KGFKKSxKLnNldCgkLnN1YmFycmF5KDAsMzIpLGFKLmxlbmd0aCksSn12YXIgc0o9bmV3IFVpbnQ4QXJyYXkoWzQ4LDQ2LDIsMSwwLDQ4LDUsNiwzLDQzLDEwMSwxMTAsNCwzNCw0LDMyXSk7ZnVuY3Rpb24gQlEoJCl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoc0oubGVuZ3RoKzMyKTtyZXR1cm4gSi5zZXQoc0opLEouc2V0KCQuc3ViYXJyYXkoMCwzMiksc0oubGVuZ3RoKSxKfWZ1bmN0aW9uIGtRKCQpe3JldHVybiB0eXBlb2YgJD09PSJzdHJpbmciP25ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKTokfWZ1bmN0aW9uIGowKCQpe2xldCBKPW5ldyBBcnJheUJ1ZmZlcigkLmJ5dGVMZW5ndGgpO3JldHVybiBuZXcgVWludDhBcnJheShKKS5zZXQoJCksSn1jbGFzcyBTMHt2ZXJpZnlLZXlzPW5ldyBNYXA7YXN5bmMgZ2VuUmFuZG9tQnl0ZXMoJCl7cmV0dXJuIFUkKCQpfWFzeW5jIGdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKXtyZXR1cm4gVSQoMzIpfWFzeW5jIGVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoJCxKKXtsZXQgWj1VJCgyNCksWT1wSihKLFopLmVuY3J5cHQoJCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KFsuLi5aLC4uLlldKX1hc3luYyBkZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKCQsSil7bGV0IFo9JC5zbGljZSgwLDI0KSxRPSQuc2xpY2UoMjQpO3JldHVybiBwSihKLFopLmRlY3J5cHQoUSl9YXN5bmMgZGVyaXZlRWQyNTUxOUtleVBhaXIoJCl7bGV0IEo9JCxaPXhRKEopLFE9ajAoWiksWTt0cnl7bGV0IEs9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLFEse25hbWU6IkVkMjU1MTkifSwhMCxbInNpZ24iXSk7WT1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCJqd2siLEspfWZpbmFsbHl7Wi5maWxsKDApLG5ldyBVaW50OEFycmF5KFEpLmZpbGwoMCl9aWYodHlwZW9mIFkueCE9PSJzdHJpbmciKXRocm93IEVycm9yKCJFZDI1NTE5IEpXSyBtaXNzaW5nIHgiKTtsZXQgVj1ZLng7WS5kPXZvaWQgMDtsZXQgWD1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJqd2siLHtrdHk6Ik9LUCIsY3J2OiJFZDI1NTE5Iix4OlZ9LHtuYW1lOiJFZDI1NTE5In0sITAsWyJ2ZXJpZnkiXSksVz1uZXcgVWludDhBcnJheShhd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCJyYXciLFgpKTt0aGlzLnZlcmlmeUtleXMuc2V0KFUwKFcpLFgpO2xldCB6PW5ldyBVaW50OEFycmF5KDY0KTtyZXR1cm4gei5zZXQoSiwwKSx6LnNldChXLDMyKSx7a2V5VHlwZToiZWQyNTUxOSIscHJpdmF0ZUtleTp6LHB1YmxpY0tleTpXfX1hc3luYyBpbXBvcnRTaWduS2V5KCQpe2xldCBKPSQuc3ViYXJyYXkoMCwzMiksWj14UShKKSxRPWowKFopO3RyeXtyZXR1cm4gYXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLFEse25hbWU6IkVkMjU1MTkifSwhMSxbInNpZ24iXSl9ZmluYWxseXtaLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoUSkuZmlsbCgwKX19YXN5bmMgaW1wb3J0VmVyaWZ5S2V5KCQpe2xldCBKPVUwKCQpLFo9dGhpcy52ZXJpZnlLZXlzLmdldChKKTtpZihaKXJldHVybiBaO2xldCBRPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInJhdyIsajAoJCkse25hbWU6IkVkMjU1MTkifSwhMSxbInZlcmlmeSJdKTtyZXR1cm4gdGhpcy52ZXJpZnlLZXlzLnNldChKLFEpLFF9YXN5bmMgc2lnbkVkMjU1MTkoJCxKKXtsZXQgWj1rUSgkKSxRPWF3YWl0IHRoaXMuaW1wb3J0U2lnbktleShKKSxZPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5zaWduKHtuYW1lOiJFZDI1NTE5In0sUSxqMChaKSk7cmV0dXJuIG5ldyBVaW50OEFycmF5KFkpfWFzeW5jIGNoZWNrU2lnRWQyNTUxOSgkLEosWil7bGV0IFE9a1EoSik7dHJ5e2xldCBZPWF3YWl0IHRoaXMuaW1wb3J0VmVyaWZ5S2V5KFopO3JldHVybiBhd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUudmVyaWZ5KHtuYW1lOiJFZDI1NTE5In0sWSxqMCgkKSxqMChRKSl9Y2F0Y2h7cmV0dXJuITF9fWFzeW5jIGJsYWtlMygkKXtyZXR1cm4galEoJCl9YXN5bmMgZ2VuWDI1NTE5KCl7bGV0ICQ9YXdhaXQgVSQoMzIpOyRbMF0mPTI0OCwkWzMxXSY9MTI3LCRbMzFdfD02NDtsZXRbSixaXT1EUSgkKTtpZihaIT09MHx8Sj09PXZvaWQgMCl0aHJvdyAkLmZpbGwoMCksRXJyb3IoIlgyNTUxOSBzY2FsYXIgYnJhbmQgZmFpbGVkIik7bGV0IFE9TFEoSiksWT1CUShKKSxWPWowKFkpO3RyeXtsZXQgWD1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsVix7bmFtZToiWDI1NTE5In0sITAsWyJkZXJpdmVCaXRzIl0pLFc9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgiandrIixYKTtpZih0eXBlb2YgVy54IT09InN0cmluZyIpdGhyb3cgRXJyb3IoIlgyNTUxOSBKV0sgbWlzc2luZyB4Iik7bGV0IHo9TFooVy54KTtpZihXLmQ9dm9pZCAwLCFyKHosUSkpdGhyb3cgRXJyb3IoIlgyNTUxOSBXZWJDcnlwdG8gcHViICE9IFJGQyA3NzQ4Iik7cmV0dXJue3ByaXY6SixwdWI6UX19Y2F0Y2goWCl7dGhyb3cgSi5maWxsKDApLFh9ZmluYWxseXtZLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoVikuZmlsbCgwKX19YXN5bmMgeDI1NTE5U2hhcmVkKCQsSil7bGV0IFo9QlEoJCksUT1qMChaKTt0cnl7bGV0IFk9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLFEse25hbWU6IlgyNTUxOSJ9LCExLFsiZGVyaXZlQml0cyJdKSxWPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInJhdyIsajAoSikse25hbWU6IlgyNTUxOSJ9LCExLFtdKSxYPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5kZXJpdmVCaXRzKHtuYW1lOiJYMjU1MTkiLHB1YmxpYzpWfSxZLDI1Nik7cmV0dXJuIG5ldyBVaW50OEFycmF5KFgpfWZpbmFsbHl7Wi5maWxsKDApLG5ldyBVaW50OEFycmF5KFEpLmZpbGwoMCl9fX12YXIgcVY9bmV3IFMwLGQkPXFWO3ZhciB2MD17ZW5jb2RlKCQsSil7bGV0IFo9JC53cml0ZVZhclN0cmluZyhKLmhhbmRsZSk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhclN0cmluZyhKLmxhYmVsKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gJC53cml0ZVZhckludChKLmlkeD8/MCl9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gTyh7aGFuZGxlOkosbGFiZWw6USxpZHg6Vn0pfX07dmFyIHIkPTEsdEo9e2VuY29kZSgkLEope2lmKEoudiE9PXIkKXJldHVybiAxMDtsZXRbLFpdPSQwKEoubWFzdGVyU2VlZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckludChKLnYpO2lmKFEhPT0wKXJldHVybiBROyQud3JpdGVCeXRlcyhKLm1hc3RlclNlZWQpO2xldCBZPSQud3JpdGVWYXJJbnQoSi5ob3N0cy5sZW5ndGgpO2lmKFkhPT0wKXJldHVybiBZO2ZvcihsZXQgViBvZiBKLmhvc3RzKXtsZXQgWD0kLndyaXRlU3RydWN0KHYwLFYpO2lmKFghPT0wKXJldHVybiBYfXJldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFySW50KCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSiE9PXIkKXJldHVybiBHKDE0KTtsZXRbUSxZXT0kLnJlYWRCeXRlcyhIMCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1YsWF09JDAoUSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1csel09JC5yZWFkVmFySW50KCk7aWYoeiE9PTApcmV0dXJuIEcoeik7aWYoVz09PXZvaWQgMHx8VzwwKXJldHVybiBHKDEwKTtsZXQgSz1bXTtmb3IobGV0IEY9MDtGPFc7RisrKXtsZXRbTixVXT0kLnJlYWRTdHJ1Y3QodjApO2lmKFUhPT0wKXJldHVybiBHKFUpO2lmKE49PT12b2lkIDApcmV0dXJuIEcoMTQpO0sucHVzaChOKX1yZXR1cm4gTyh7djpyJCxtYXN0ZXJTZWVkOlYsaG9zdHM6S30pfX07ZnVuY3Rpb24gRVEoJCxKKXtsZXRbWixRXT0kMCgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDEwKTtsZXRbWSxWXT0kMChaLnNsaWNlKCkpO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFk9PT12b2lkIDApcmV0dXJuIEcoMTApO3JldHVybiBPKHt2OnIkLG1hc3RlclNlZWQ6WSxob3N0czpKLm1hcCgoWCk9Pih7aGFuZGxlOlguaGFuZGxlLGxhYmVsOlgubGFiZWwsaWR4OlguaWR4Pz8wfSkpfSl9dmFyIG8kPXtlbmNvZGUoJCxKKXtsZXRbLFpdPSQwKEoubWFzdGVyU2VlZCk7aWYoWiE9PTApcmV0dXJuIFo7JC53cml0ZUJ5dGVzKEoubWFzdGVyU2VlZCk7bGV0IFE9JC53cml0ZVZhckludChKLmhvc3RzLmxlbmd0aCk7aWYoUSE9PTApcmV0dXJuIFE7Zm9yKGxldCBZIG9mIEouaG9zdHMpe2xldCBWPSQud3JpdGVTdHJ1Y3QodjAsWSk7aWYoViE9PTApcmV0dXJuIFZ9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRCeXRlcyhIMCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1EsWV09JDAoSik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1YsWF09JC5yZWFkVmFySW50KCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMHx8VjwwKXJldHVybiBHKDEwKTtsZXQgVz1bXTtmb3IobGV0IHo9MDt6PFY7eisrKXtsZXRbSyxGXT0kLnJlYWRTdHJ1Y3QodjApO2lmKEYhPT0wKXJldHVybiBHKEYpO2lmKEs9PT12b2lkIDApcmV0dXJuIEcoMTQpO1cucHVzaChLKX1yZXR1cm4gTyh7bWFzdGVyU2VlZDpRLGhvc3RzOld9KX19O3ZhciBNVj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMucXJwYWlyLnYxIiksTSQ9MzIsSVY9TSQrMjQrMTYsQ1Y9MzIsU0Y9U3ltYm9sKCJESEtFUmVxIiksdkY9U3ltYm9sKCJESEtFUmVzcCIpO2Z1bmN0aW9uIGZRKCQpe2lmKCQuYnl0ZUxlbmd0aCE9PU0kKXJldHVybiBHKDEwKTtyZXR1cm4gTygkKX1mdW5jdGlvbiBnUSgkKXtpZigkLmJ5dGVMZW5ndGg8SVYpcmV0dXJuIEcoMTApO3JldHVybiBPKCQpfXZhciBhJD1uZXcgUzA7YXN5bmMgZnVuY3Rpb24gZUooJCxKLFosUSl7bGV0IFk7dHJ5e1k9YXdhaXQgYSQueDI1NTE5U2hhcmVkKCQsSil9Y2F0Y2h7cmV0dXJuIEcoMjkpfXRyeXtpZihZLmJ5dGVMZW5ndGghPT1NJHx8WS5ldmVyeSgoVyk9Plc9PT0wKSlyZXR1cm4gRygxMCk7bGV0IFY9UjAoWSxNViksWD1SMChWLFIwKFosUSkpO3RyeXtsZXQgVz1hd2FpdCBhJC5ibGFrZTMoWCk7cmV0dXJuIE8oVy5zbGljZSgwLENWKSl9ZmluYWxseXtWLmZpbGwoMCksWC5maWxsKDApfX1maW5hbGx5e1kuZmlsbCgwKX19Y2xhc3MgcyR7IyQ7I0o7Y29uc3RydWN0b3IoJCxKKXt0aGlzLiMkPSQsdGhpcy4jSj1KfXN0YXRpYyBhc3luYyBjcmVhdGUoKXtsZXQgJDt0cnl7bGV0IEo9YXdhaXQgYSQuZ2VuWDI1NTE5KCk7JD1KLnByaXY7bGV0W1osUV09ZlEoSi5wdWIpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldCBZPW5ldyBzJCgkLFopO3JldHVybiAkPXZvaWQgMCxPKFkpfWNhdGNoe3JldHVybiBHKDI5KX1maW5hbGx5eyQ/LmZpbGwoMCl9fXdpcGUoKXt0aGlzLiMkLmZpbGwoMCl9Z2V0IGRoa2VSZXEoKXtsZXRbJCxKXT1mUSh0aGlzLiNKLnNsaWNlKCkpO2lmKCQ9PT12b2lkIDApdGhyb3cgRXJyb3IoYGRoa2VSZXEgJHtKfWApO3JldHVybiAkfWFzeW5jIGZpbmlzaCgkKXtsZXQgSj0kLnN1YmFycmF5KDAsTSQpLFo9JC5zdWJhcnJheShNJCksW1EsWV09YXdhaXQgZUoodGhpcy4jJCxKLHRoaXMuI0osSik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0IFY7dHJ5e3RyeXtWPWF3YWl0IGEkLmRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoWixRKX1jYXRjaHtyZXR1cm4gRygyMCl9bGV0IFg9bmV3IG0oViksW1csel09WC5yZWFkU3RydWN0KG8kKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwKXJldHVybiBHKDE0KTt0cnl7bGV0W0ssRl09VzAuZnJvbUJ5dGVzKFcubWFzdGVyU2VlZCk7aWYoRiE9PTApcmV0dXJuIEcoRik7aWYoSz09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIHRoaXMud2lwZSgpLE8oe2VuY2xhdmU6Syxob3N0czpXLmhvc3RzLm1hcCgoTik9Pih7Li4uTn0pKX0pfWZpbmFsbHl7Vy5tYXN0ZXJTZWVkLmZpbGwoMCl9fWZpbmFsbHl7US5maWxsKDApLFY/LmZpbGwoMCl9fX1mdW5jdGlvbiBEMCgkKXtsZXQgSj1uZXcgVWludDhBcnJheSgkKTtpZigkPjApY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhKKTtyZXR1cm4gSn12YXIgeTA9MzIsUFY9LTcsd1Y9LTgsVFY9LTI1Nyx0JD1be3R5cGU6InB1YmxpYy1rZXkiLGFsZzpQVn0se3R5cGU6InB1YmxpYy1rZXkiLGFsZzp3Vn0se3R5cGU6InB1YmxpYy1rZXkiLGFsZzpUVn1dO2Z1bmN0aW9uIGpWKCQpe3JldHVybiAkLnRyaW0oKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1wuJC8sIiIpfHwibG9jYWxob3N0In1mdW5jdGlvbiBCMCgkKXtsZXQgSj1uZXcgVWludDhBcnJheSgkLmJ5dGVMZW5ndGgpO3JldHVybiBKLnNldCgkKSxKLmJ1ZmZlcn1mdW5jdGlvbiBtUSgkKXtpZigkIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpLnNsaWNlKCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpLnNsaWNlKCl9ZnVuY3Rpb24gYjAoJCl7aWYoJD8ucnBJZCE9PXZvaWQgMClyZXR1cm4gTygkLnJwSWQpO2lmKHR5cGVvZiBsb2NhdGlvbj4idSIpcmV0dXJuIEcoOSk7cmV0dXJuIE8oalYobG9jYXRpb24uaG9zdG5hbWUpKX1mdW5jdGlvbiBoMCgpe2lmKHR5cGVvZiBuYXZpZ2F0b3I+InUifHwhbmF2aWdhdG9yLmNyZWRlbnRpYWxzfHx0eXBlb2YgUHVibGljS2V5Q3JlZGVudGlhbD4idSIpcmV0dXJuIDI0O3JldHVybiAwfWZ1bmN0aW9uIGkwKCQpe2lmKCQ9PT1udWxsfHwkLnR5cGUhPT0icHVibGljLWtleSJ8fCEoInJhd0lkImluICQpfHx0eXBlb2YgJC5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzIT09ImZ1bmN0aW9uIilyZXR1cm4gRygyNyk7cmV0dXJuIE8oJCl9YXN5bmMgZnVuY3Rpb24gU1EoJCl7bGV0IEo9aDAoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbWixRXT1iMCgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDkpO2xldCBZPSQ/LnVzZXJOYW1lPz8iZGlwbG9tYXRpYy1zZWVkIixWPXtyZXNpZGVudEtleToicmVxdWlyZWQiLHJlcXVpcmVSZXNpZGVudEtleTohMCx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCJ9O2lmKCQ/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50IT09dm9pZCAwKVYuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ9JC5hdXRoZW50aWNhdG9yQXR0YWNobWVudDtsZXQgWD17bGFyZ2VCbG9iOntzdXBwb3J0OiJyZXF1aXJlZCJ9fSxXO3RyeXtXPWF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5jcmVhdGUoe3B1YmxpY0tleTp7Y2hhbGxlbmdlOkQwKHkwKSxycDp7aWQ6WixuYW1lOiQ/LnJwTmFtZT8/IkRJUExPTUFUSUMifSx1c2VyOntpZDpEMCgxNiksbmFtZTpZLGRpc3BsYXlOYW1lOll9LHB1YktleUNyZWRQYXJhbXM6dCQsYXV0aGVudGljYXRvclNlbGVjdGlvbjpWLGV4dGVuc2lvbnM6WH19KX1jYXRjaHtyZXR1cm4gRygyNCl9bGV0W3osS109aTAoVyk7aWYoSyE9PTApcmV0dXJuIEcoSyk7aWYoej09PXZvaWQgMClyZXR1cm4gRygyNyk7aWYoei5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCkubGFyZ2VCbG9iPy5zdXBwb3J0ZWQhPT0hMClyZXR1cm4gRygyNCk7cmV0dXJuIE8obmV3IFVpbnQ4QXJyYXkoei5yYXdJZCkpfWFzeW5jIGZ1bmN0aW9uICRaKCQsSixaKXtsZXQgUT1oMCgpO2lmKFEhPT0wKXJldHVybiBRO2xldFtZLFZdPWIwKFopO2lmKFYhPT0wKXJldHVybiBWO2lmKFk9PT12b2lkIDApcmV0dXJuIDk7bGV0IFg9e2xhcmdlQmxvYjp7d3JpdGU6QjAoSil9fSxXO3RyeXtXPWF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5nZXQoe3B1YmxpY0tleTp7Y2hhbGxlbmdlOkQwKHkwKSxycElkOlksYWxsb3dDcmVkZW50aWFsczpbe3R5cGU6InB1YmxpYy1rZXkiLGlkOkIwKCQpfV0sdXNlclZlcmlmaWNhdGlvbjoicmVxdWlyZWQiLGV4dGVuc2lvbnM6WH19KX1jYXRjaHtyZXR1cm4gMjR9bGV0W3osS109aTAoVyk7aWYoSyE9PTApcmV0dXJuIEs7aWYoej09PXZvaWQgMClyZXR1cm4gMjc7aWYoei5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCkubGFyZ2VCbG9iPy53cml0dGVuIT09ITApcmV0dXJuIDI0O3JldHVybiAwfWFzeW5jIGZ1bmN0aW9uIHZRKCQsSil7bGV0IFo9aDAoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT1iMChKKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDkpO2xldCBWPXtsYXJnZUJsb2I6e3JlYWQ6ITB9fSxYO3RyeXtsZXQgVT17Y2hhbGxlbmdlOkQwKHkwKSxycElkOlEsdXNlclZlcmlmaWNhdGlvbjoicmVxdWlyZWQiLGV4dGVuc2lvbnM6Vn07aWYoJCE9PXZvaWQgMClVLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOiJwdWJsaWMta2V5IixpZDpCMCgkKX1dO1g9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmdldCh7cHVibGljS2V5OlV9KX1jYXRjaHtyZXR1cm4gRygyNCl9bGV0W1csel09aTAoWCk7aWYoeiE9PTApcmV0dXJuIEcoeik7aWYoVz09PXZvaWQgMClyZXR1cm4gRygyNyk7bGV0IEY9Vy5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCkubGFyZ2VCbG9iO2lmKEY9PT12b2lkIDB8fEYuYmxvYj09PXZvaWQgMClyZXR1cm4gRyg3KTtsZXQgTj1tUShGLmJsb2IpO2lmKE4uYnl0ZUxlbmd0aD09PTApcmV0dXJuIEcoNyk7cmV0dXJuIE8oe2Jsb2I6TixjcmVkSWQ6bmV3IFVpbnQ4QXJyYXkoVy5yYXdJZCl9KX12YXIgWlo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCJkaXBsb21hdGljLnByZi52MSIpLEpaPTMyO2FzeW5jIGZ1bmN0aW9uIHlRKCQpe2xldCBKPWgwKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1osUV09YjAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgWT0kPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtcHJmIixWPXtyZXNpZGVudEtleToicmVxdWlyZWQiLHJlcXVpcmVSZXNpZGVudEtleTohMCx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCJ9O2lmKCQ/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50IT09dm9pZCAwKVYuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ9JC5hdXRoZW50aWNhdG9yQXR0YWNobWVudDtsZXQgWD0kPy5zYWx0IT09dm9pZCAwP0IwKCQuc2FsdCk6dm9pZCAwLFc9WD09PXZvaWQgMD97fTp7ZXZhbDp7Zmlyc3Q6WH19LHo7dHJ5e3o9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmNyZWF0ZSh7cHVibGljS2V5OntjaGFsbGVuZ2U6RDAoeTApLHJwOntpZDpaLG5hbWU6JD8ucnBOYW1lPz8iRElQTE9NQVRJQyJ9LHVzZXI6e2lkOkQwKDE2KSxuYW1lOlksZGlzcGxheU5hbWU6WX0scHViS2V5Q3JlZFBhcmFtczp0JCxhdXRoZW50aWNhdG9yU2VsZWN0aW9uOlYsZXh0ZW5zaW9uczp7cHJmOld9fX0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbSyxGXT1pMCh6KTtpZihGIT09MClyZXR1cm4gRyhGKTtpZihLPT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgTj1LLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKTtyZXR1cm4gTyh7Y3JlZElkOm5ldyBVaW50OEFycmF5KEsucmF3SWQpLHByZkVuYWJsZWQ6Ti5wcmY/LmVuYWJsZWQ9PT0hMH0pfWFzeW5jIGZ1bmN0aW9uIFFaKCQpe2xldCBKPWgwKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1osUV09YjAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgWT0kPy5zYWx0Pz9aWixWPUIwKFkpLFg9e2NoYWxsZW5nZTpEMCh5MCkscnBJZDpaLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixleHRlbnNpb25zOntwcmY6e2V2YWw6e2ZpcnN0OlZ9fX19O2lmKCQ/LmNyZWRJZCE9PXZvaWQgMClYLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOiJwdWJsaWMta2V5IixpZDpCMCgkLmNyZWRJZCl9XTtsZXQgVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6WH0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbeixLXT1pMChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgRj16LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5wcmY/LnJlc3VsdHM7aWYoRj8uZmlyc3Q9PT12b2lkIDApcmV0dXJuIEcoNyk7bGV0IE49Ri5maXJzdCxVPU4gaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcj9uZXcgVWludDhBcnJheShOKTpuZXcgVWludDhBcnJheShOLmJ1ZmZlcixOLmJ5dGVPZmZzZXQsTi5ieXRlTGVuZ3RoKSxSPVUuYnl0ZUxlbmd0aD49Slo/VS5zbGljZSgwLEpaKTpVO2lmKFIuYnl0ZUxlbmd0aCE9PUpaKXJldHVybiBHKDI3KTtyZXR1cm4gTyh7cHJmOlIsY3JlZElkOm5ldyBVaW50OEFycmF5KHoucmF3SWQpfSl9dmFyIGUkPSIiO3ZhciBKSj10eXBlb2YgZ2xvYmFsVGhpcy5Xb3JrZXI9PT0iZnVuY3Rpb24iP2dsb2JhbFRoaXMuV29ya2VyOnZvaWQgMCxZWj1KSj09PXZvaWQgMD92b2lkIDA6SkoucHJvdG90eXBlLnBvc3RNZXNzYWdlLCRKO2Z1bmN0aW9uIEFWKCl7aWYodHlwZW9mIGUkIT09InN0cmluZyJ8fGUkLmxlbmd0aD09PTApdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSB3b3JrZXIgc291cmNlIG5vdCBlbWJlZGRlZDsgcnVuIHBrZyBidWlsZCBiZWZvcmUgc3Bhd24iKTtyZXR1cm4gYXRvYihlJCl9ZnVuY3Rpb24gX1YoKXtpZigkSiE9PXZvaWQgMClyZXR1cm4gJEo7bGV0ICQ9bmV3IEJsb2IoW0FWKCldLHt0eXBlOiJ0ZXh0L2phdmFzY3JpcHQifSk7cmV0dXJuICRKPVVSTC5jcmVhdGVPYmplY3RVUkwoJCksJEp9ZnVuY3Rpb24gYlEoKXtpZihKSj09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBzcGF3biBzeW5jIHdvcmtlciIpO3JldHVybiBuZXcgSkooX1YoKSx7dHlwZToibW9kdWxlIn0pfWZ1bmN0aW9uIGhRKCQsSixaKXtpZihZWj09PXZvaWQgMCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIFdvcmtlciBBUEkgdW5hdmFpbGFibGU7IGNhbm5vdCBwb3N0IHRvIHN5bmMgd29ya2VyIik7aWYoWiE9PXZvaWQgMCYmWi5sZW5ndGg+MClZWi5jYWxsKCQsSix7dHJhbnNmZXI6Wn0pO2Vsc2UgWVouY2FsbCgkLEopfXZhciBMVj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMud3JhcC52MSIpLHhWPTMyLEJWPTE2LHowPW5ldyBTMDtjbGFzcyBXMHsjJDtjb25zdHJ1Y3RvcigkKXt0aGlzLiMkPSR9c3RhdGljIGFzeW5jIGZyb21SYW5kb20oKXtsZXQgJD1hd2FpdCB6MC5nZW4yNTZCaXRTZWN1cmVSYW5kb21TZWVkKCksW0osWl09JDAoJCk7aWYoWiE9PTB8fEo9PT12b2lkIDApdGhyb3cgRXJyb3IoYGVuY2xhdmU6IGludmFsaWQgcmFuZG9tIHNlZWQgKCR7Wn0pYCk7cmV0dXJuIG5ldyBXMChKKX1zdGF0aWMgZnJvbUJ5dGVzKCQpe2xldFtKLFpdPSQwKCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtRLFldPSQwKEouc2xpY2UoKSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMCk7cmV0dXJuIE8obmV3IFcwKFEpKX1hc3luYyBzZWFsV2l0aFBhc3NrZXkoJCl7bGV0IEo9JD8uc2FsdD8/WlosWj0kPy5jcmVkSWQ7aWYoWj09PXZvaWQgMCYmJD8uY3JlYXRlQ3JlZElmTmVlZGVkPT09ITApe2xldFtWLFhdPWF3YWl0IHlRKHtycElkOiQ/LnJwSWQscnBOYW1lOiQ/LnJwTmFtZSx1c2VyTmFtZTokPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtcHJmIixhdXRoZW50aWNhdG9yQXR0YWNobWVudDokPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCxzYWx0Okp9KTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDI0KTtpZighVi5wcmZFbmFibGVkKXJldHVybiBHKDI0KTtaPVYuY3JlZElkfWxldFtRLFldPWF3YWl0IFFaKHtycElkOiQ/LnJwSWQscnBOYW1lOiQ/LnJwTmFtZSxjcmVkSWQ6WixzYWx0Okp9KTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbVixYXT1hd2FpdCB0aGlzLiNRKFEucHJmKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gTyh7c2VhbGVkTWFzdGVyOlYsc2FsdDpKLnNsaWNlKCksY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXN0YXRpYyBhc3luYyB1bnNlYWxXaXRoUGFzc2tleSgkLEope2xldFtaLFFdPWF3YWl0IFFaKHtycElkOkoucnBJZCxycE5hbWU6Si5ycE5hbWUsY3JlZElkOkouY3JlZElkLHNhbHQ6Si5zYWx0fSk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRyg3KTt0cnl7bGV0W1ksVl09YXdhaXQgVzAuI1ooJCxaLnByZik7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIE8oe2VuY2xhdmU6WSxjcmVkSWQ6Wi5jcmVkSWQuc2xpY2UoKX0pfWZpbmFsbHl7Wi5wcmYuZmlsbCgwKX19YXN5bmMgcGVyc2lzdFRvTGFyZ2VCbG9iKCQ9W10sSil7bGV0IFo9Sj8uY3JlZElkO2lmKFo9PT12b2lkIDApe2xldFtWLFhdPWF3YWl0IFNRKEopO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMjQpO1o9Vn1sZXRbUSxZXT10aGlzLiNZKCQpO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoMTIpO3RyeXtsZXQgVj1hd2FpdCAkWihaLFEsSik7aWYoViE9PTApcmV0dXJuIEcoVik7cmV0dXJuIE8oWil9ZmluYWxseXtRLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBmcm9tTGFyZ2VCbG9iKCQpe2xldFtKLFpdPWF3YWl0IHZRKCQ/LmNyZWRJZCwkKTtpZihaIT09MClyZXR1cm4gRyhaKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtyZXR1cm4gVzAuI1YoSi5ibG9iLEouY3JlZElkKX1maW5hbGx5e0ouYmxvYi5maWxsKDApfX1zdGF0aWMgYXN5bmMgY2xlYXJMYXJnZUJsb2IoJCxKKXtyZXR1cm4gJFooJCxuZXcgVWludDhBcnJheShIMCksSil9c3RhdGljIHBhaXJSZXF1ZXN0KCl7cmV0dXJuIHMkLmNyZWF0ZSgpfWFzeW5jIHBhaXJBY2NlcHQoJCxKKXtsZXQgWjt0cnl7Wj1hd2FpdCB6MC5nZW5YMjU1MTkoKX1jYXRjaHtyZXR1cm4gRygyOSl9dHJ5e2xldFtRLFldPWF3YWl0IGVKKFoucHJpdiwkLCQsWi5wdWIpO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoMTIpO3RyeXtsZXRbVixYXT10aGlzLiNKKEopO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMTIpO3RyeXtsZXQgVz1hd2FpdCB6MC5lbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKFYsUSk7cmV0dXJuIGdRKFIwKFoucHViLFcpKX1jYXRjaHtyZXR1cm4gRygxMil9ZmluYWxseXtWLmZpbGwoMCl9fWZpbmFsbHl7US5maWxsKDApfX1maW5hbGx5e1oucHJpdi5maWxsKDApfX0jSigkKXtsZXQgSj10aGlzLiMkLnNsaWNlKCksW1osUV09JDAoSik7aWYoUSE9PTApcmV0dXJuIEouZmlsbCgwKSxHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEouZmlsbCgwKSxHKDEwKTt0cnl7bGV0IFk9e21hc3RlclNlZWQ6Wixob3N0czokLm1hcCgoWCk9Pih7aGFuZGxlOlguaGFuZGxlLGxhYmVsOlgubGFiZWwsaWR4OlguaWR4Pz8wfSkpfSxWPW5ldyBTO3RyeXtsZXQgWD1WLndyaXRlU3RydWN0KG8kLFkpO2lmKFghPT0wKXJldHVybiBHKFgpO3JldHVybiBPKFYucmVzdWx0KCkpfWZpbmFsbHl7Vi53aXBlKCl9fWZpbmFsbHl7Wi5maWxsKDApfX1zcGF3blN5bmNXb3JrZXIoJCl7bGV0IEo9YlEoKSxaPXRoaXMuIyQuc2xpY2UoKTtyZXR1cm4gaFEoSix7aWQ6JC5pZCxvcDoic2V0U2VlZCIsc2VlZDpaLHBlcnNpc3Q6JC5wZXJzaXN0fSxbWi5idWZmZXJdKSxKfWRlcml2ZUNpcGhlcigkLEope2xldCBaPSQuc2xpY2UoKSxRPShYKT0+dGhpcy4jRyhaLFgpLFk9KFgpPT50aGlzLiN6KFosWCk7cmV0dXJue2VuY3J5cHQ6T2JqZWN0LmZyZWV6ZSh7ZW5jcnlwdDpRfSksZGVjcnlwdDpPYmplY3QuZnJlZXplKHtkZWNyeXB0Oll9KSxib3RoOk9iamVjdC5mcmVlemUoe2VuY3J5cHQ6USxkZWNyeXB0Oll9KX1bSl19YXN5bmMgZGVyaXZlSWRlbnRpdHkoJCxKPTApe2xldCBaPSQsUT1KLFk9YXdhaXQgdGhpcy4jVyhaLFEpLFY9WS5wdWJsaWNLZXk7cmV0dXJuIFkucHJpdmF0ZUtleS5maWxsKDApLE9iamVjdC5mcmVlemUoe3B1YmxpY0tleTpWLHNpZ246KFgpPT50aGlzLiNGKFosUSxYKSxrZG1Gb3I6KFgpPT50aGlzLiNOKFosUSxYKX0pfWFzeW5jI1EoJCl7bGV0W0osWl09YXdhaXQgaVEoejAsJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBRPWF3YWl0IHowLmVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQodGhpcy4jJCxKKTtyZXR1cm4geDAoUSl9Y2F0Y2h7cmV0dXJuIEcoMTIpfWZpbmFsbHl7Si5maWxsKDApfX1zdGF0aWMgYXN5bmMjWigkLEope2xldFssWl09eDAoJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09YXdhaXQgaVEoejAsSik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0IFY7dHJ5e3RyeXtWPWF3YWl0IHowLmRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoJCxRKX1jYXRjaHtyZXR1cm4gRygyMCl9cmV0dXJuIFcwLmZyb21CeXRlcyhWKX1maW5hbGx5e1EuZmlsbCgwKSxWPy5maWxsKDApfX0jWSgkKXtsZXQgSj10aGlzLiMkLnNsaWNlKCksW1osUV09JDAoSik7aWYoUSE9PTApcmV0dXJuIEouZmlsbCgwKSxHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEouZmlsbCgwKSxHKDEwKTt0cnl7bGV0W1ksVl09RVEoWiwkKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFg9bmV3IFMsVz1YLndyaXRlU3RydWN0KHRKLFkpO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBPKFgucmVzdWx0KCkpfWZpbmFsbHl7WS5tYXN0ZXJTZWVkLmZpbGwoMCl9fWZpbmFsbHl7Wi5maWxsKDApfX1zdGF0aWMjVigkLEope2lmKCQuYnl0ZUxlbmd0aD09PTB8fCQuZXZlcnkoKFYpPT5WPT09MCkpcmV0dXJuIEcoMjIpO2lmKCQuYnl0ZUxlbmd0aD09PUgwKXtpZigkLmV2ZXJ5KChXKT0+Vz09PTApKXJldHVybiBHKDIyKTtsZXRbVixYXT1XMC5mcm9tQnl0ZXMoJCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIE8oe2VuY2xhdmU6Vixob3N0czpbXSxjcmVkSWQ6Sn0pfWxldCBaPW5ldyBtKCQpLFtRLFldPVoucmVhZFN0cnVjdCh0Sik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxNCk7dHJ5e2lmKFEubWFzdGVyU2VlZC5ldmVyeSgoVyk9Plc9PT0wKSlyZXR1cm4gRygyMik7bGV0W1YsWF09VzAuZnJvbUJ5dGVzKFEubWFzdGVyU2VlZCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIE8oe2VuY2xhdmU6Vixob3N0czpRLmhvc3RzLm1hcCgoVyk9Pih7Li4uV30pKSxjcmVkSWQ6Sn0pfWZpbmFsbHl7US5tYXN0ZXJTZWVkLmZpbGwoMCl9fWFzeW5jI0coJCxKKXtsZXQgWj1hd2FpdCB0aGlzLiNYKCQpO3RyeXtyZXR1cm4gYXdhaXQgejAuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChKLFopfWZpbmFsbHl7Wi5maWxsKDApfX1hc3luYyN6KCQsSil7bGV0IFo9YXdhaXQgdGhpcy4jWCgkKTt0cnl7cmV0dXJuIGF3YWl0IHowLmRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoSixaKX1maW5hbGx5e1ouZmlsbCgwKX19YXN5bmMjWCgkKXtyZXR1cm4gejAuYmxha2UzKFIwKHRoaXMuIyQsJCkpfWFzeW5jI0soJCxKKXtsZXQgWj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCksUT1uZXcgVWludDhBcnJheSg4KTtyZXR1cm4gbmV3IERhdGFWaWV3KFEuYnVmZmVyKS5zZXRCaWdVaW50NjQoMCxCaWdJbnQoSiksITEpLGF3YWl0IHRoaXMuI1goUjAoWixRKSl9YXN5bmMjVygkLEope2xldCBaPWF3YWl0IHRoaXMuI0soJCxKKTt0cnl7cmV0dXJuIGF3YWl0IHowLmRlcml2ZUVkMjU1MTlLZXlQYWlyKFopfWZpbmFsbHl7Wi5maWxsKDApfX1hc3luYyNGKCQsSixaKXtsZXQgUT1hd2FpdCB0aGlzLiNXKCQsSik7dHJ5e3JldHVybiBhd2FpdCB6MC5zaWduRWQyNTUxOShaLFEucHJpdmF0ZUtleSl9ZmluYWxseXtRLnByaXZhdGVLZXkuZmlsbCgwKX19YXN5bmMjTigkLEosWil7bGV0IFE9YXdhaXQgdGhpcy4jVygkLEopLFk9UjAoUS5wcml2YXRlS2V5LFopO1EucHJpdmF0ZUtleS5maWxsKDApO3RyeXtyZXR1cm4oYXdhaXQgejAuYmxha2UzKFkpKS5zbGljZSgwLF8wKX1maW5hbGx5e1kuZmlsbCgwKX19fWFzeW5jIGZ1bmN0aW9uIGlRKCQsSixaPUxWKXtpZihKLmJ5dGVMZW5ndGg8QlYpcmV0dXJuIEcoMTApO2xldCBRPWF3YWl0ICQuYmxha2UzKFIwKEosWikpO3JldHVybiBPKFEuc2xpY2UoMCx4VikpfWNsYXNzIFZae2RiO2NvbnN0cnVjdG9yKCQpe3RoaXMuZGI9JH1hc3luYyBlbnEoJCl7bGV0IEo9Wy4uLiRdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihLMCwicmVhZHdyaXRlIiksUT1aLm9iamVjdFN0b3JlKEswKTtyZXR1cm4gbmV3IFByb21pc2UoKFksVik9PntaLm9uY29tcGxldGU9KCk9PlkoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvcik7Zm9yKGxldCBYIG9mIEope2xldCBXPWAke1guaG9zdH06JHtYLnNlcX1gO1EucHV0KFgsVyl9fSl9YXN5bmMgZGVxKCQsSil7bGV0IFo9Wy4uLkpdO2lmKFoubGVuZ3RoPT09MClyZXR1cm47bGV0IFE9dGhpcy5kYi50cmFuc2FjdGlvbihLMCwicmVhZHdyaXRlIiksWT1RLm9iamVjdFN0b3JlKEswKTtyZXR1cm4gbmV3IFByb21pc2UoKFYsWCk9PntRLm9uY29tcGxldGU9KCk9PlYoKSxRLm9uZXJyb3I9KCk9PlgoUS5lcnJvcik7Zm9yKGxldCBXIG9mIFope2xldCB6PWAkeyR9OiR7V31gO1kuZGVsZXRlKHopfX0pfWFzeW5jIGxpc3QoKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKEswKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PntsZXQgWT1KLmdldEFsbCgpO1kub25zdWNjZXNzPSgpPT5aKFkucmVzdWx0KSxZLm9uZXJyb3I9KCk9PlEoWS5lcnJvcil9KX1hc3luYyBjb3VudCgpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oSzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBZPUouY291bnQoKTtZLm9uc3VjY2Vzcz0oKT0+WihZLnJlc3VsdCksWS5vbmVycm9yPSgpPT5RKFkuZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oSzAsInJlYWR3cml0ZSIpLEo9JC5vYmplY3RTdG9yZShLMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5aKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLEouY2xlYXIoKX0pfX1mdW5jdGlvbiBsUSgkKXtyZXR1cm57bGFiZWw6JC5sYWJlbCxoYW5kbGU6bmV3IFVSTCgkLmhhbmRsZSksaWR4OiQuaWR4LGxhc3RTZXE6JC5sYXN0U2VxfHwwLGNsb2NrT2Zmc2V0OiQuY2xvY2tPZmZzZXQsc3Vic2NyaXB0aW9uOiQuc3Vic2NyaXB0aW9ufX1mdW5jdGlvbiBrVigkLEope2xldCBaPXsuLi4kfTtpZihKLnNldExhc3RTZXEhPT12b2lkIDApWi5sYXN0U2VxPUouc2V0TGFzdFNlcTtlbHNlIGlmKEoubGFzdFNlcSE9PXZvaWQgMCl7bGV0IFE9Wi5sYXN0U2VxfHwwO2lmKEoubGFzdFNlcT5RKVoubGFzdFNlcT1KLmxhc3RTZXF9cmV0dXJuIGRlbGV0ZSBaLm51bUJhZ3MsZGVsZXRlIFoubnVtRHVwZXMsWn1jbGFzcyBYWntkYjtjb25zdHJ1Y3RvcigkKXt0aGlzLmRiPSR9YXN5bmMgYWRkKCQpe2xldCBKPWF3YWl0IHRoaXMuZ2V0KCQubGFiZWwpLFo9SiE9PXZvaWQgMCYmSi5oYW5kbGUuaHJlZj09PSQuaGFuZGxlLmhyZWYmJihKLmlkeD8/MCk9PT0oJC5pZHg/PzApO3JldHVybiB0aGlzLnB1dCh7Li4uJCxsYXN0U2VxOlo/Si5sYXN0U2VxOjAsY2xvY2tPZmZzZXQ6Wj9KLmNsb2NrT2Zmc2V0OnZvaWQgMCxzdWJzY3JpcHRpb246Wj9KLnN1YnNjcmlwdGlvbjp2b2lkIDB9KX1hc3luYyBwdXQoJCl7bGV0IEo9ey4uLiQsaGFuZGxlOiQuaGFuZGxlLnRvU3RyaW5nKCksbGFzdFNlcTokLmxhc3RTZXE/PzB9LFo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZHdyaXRlIiksUT1aLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFksVik9PntaLm9uY29tcGxldGU9KCk9PlkoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvciksUS5wdXQoSil9KX1hc3luYyB0b3VjaCgkLEope3JldHVybiB0aGlzLnJlY29yZFN0YXRzKCQse2xhc3RTZXE6Sn0pfWFzeW5jIHJlY29yZFN0YXRzKCQsSil7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZHdyaXRlIiksUT1aLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFksVik9PntaLm9uY29tcGxldGU9KCk9PlkoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvcik7bGV0IFg9US5nZXQoJCk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1YLnJlc3VsdDtpZighVylyZXR1cm47US5wdXQoa1YoVyxKKSl9fSl9YXN5bmMgZ2V0KCQpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e2xldCBWPVouZ2V0KCQpO1Yub25zdWNjZXNzPSgpPT57bGV0IFg9Vi5yZXN1bHQ7aWYoIVgpUSh2b2lkIDApO2Vsc2UgUShsUShYKSl9LFYub25lcnJvcj0oKT0+WShWLmVycm9yKX0pfWFzeW5jIHNldCgkLEope2xldCBaPWF3YWl0IHRoaXMuZ2V0KCQpO2lmKCFaKXJldHVybiAxMzt0cnl7cmV0dXJuIGF3YWl0IHRoaXMucHV0KHsuLi5aLC4uLkp9KSwwfWNhdGNoe3JldHVybiAxOH19YXN5bmMgZGVsKCQpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWR3cml0ZSIpLFo9Si5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFkpPT57Si5vbmNvbXBsZXRlPSgpPT5RKCksSi5vbmVycm9yPSgpPT5ZKEouZXJyb3IpLFouZGVsZXRlKCQpfSl9YXN5bmMgbGlzdCgpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBZPUouZ2V0QWxsKCk7WS5vbnN1Y2Nlc3M9KCk9PntsZXQgVj1ZLnJlc3VsdDtaKFYubWFwKGxRKSl9LFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxKPSQub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+eyQub25jb21wbGV0ZT0oKT0+WigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxKLmNsZWFyKCl9KX19Y2xhc3MgV1p7Y3J5cHRvO2RiO2NvbnN0cnVjdG9yKCQsSil7dGhpcy5jcnlwdG89Sjt0aGlzLmRiPSR9YXN5bmMgYWRkKCQpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZHdyaXRlIiksWj1KLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoUSk9PntpZigkLmxlbmd0aD09PTApe1EoW10pO3JldHVybn1sZXQgWT1BcnJheSgkLmxlbmd0aCkuZmlsbCgwKTtKLm9uY29tcGxldGU9KCk9PlEoWSksSi5vbmVycm9yPSgpPT57Zm9yKGxldCBWPTA7VjxZLmxlbmd0aDtWKyspWVtWXT0xODtRKFkpfTtmb3IobGV0IFY9MDtWPCQubGVuZ3RoO1YrKyl7bGV0e2tleTpYLGRhdGE6V309JFtWXSx6PUIoWCksSz1aLnB1dChXLHopO0sub25lcnJvcj0oRik9PntGLnByZXZlbnREZWZhdWx0KCksWVtWXT0xOH19fSl9YXN5bmMgZGVsKCQpe2xldCBKPVsuLi4kXTtpZihKLmxlbmd0aD09PTApcmV0dXJuO2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZHdyaXRlIiksUT1aLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKTtmb3IobGV0IFggb2YgSil7bGV0IFc9QihYKTtRLmRlbGV0ZShXKX19KX1hc3luYyBnZXQoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e2xldCBWPUIoJCksWD1aLmdldChWKTtYLm9uc3VjY2Vzcz1hc3luYygpPT57bGV0IFc9WC5yZXN1bHQ7aWYoVylRKGF3YWl0IGIkKCQsVyx0aGlzLmNyeXB0bykpO2Vsc2UgUSh2b2lkIDApfSxYLm9uZXJyb3I9KCk9PlkoWC5lcnJvcil9KX1hc3luYyBoYXMoJCl7cmV0dXJuIGF3YWl0IHRoaXMuZ2V0KCQpIT09dm9pZCAwfWFzeW5jIGxpc3QoJCl7bGV0IEo9JD8uYXBsZCxaPSQ/LmJvZHkhPT0hMSxZPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZG9ubHkiKS5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFYsWCk9PntsZXQgVz1bXSx6PUo9PT12b2lkIDA/WS5vcGVuQ3Vyc29yKCk6WS5pbmRleChJJCkub3BlbkN1cnNvcihJREJLZXlSYW5nZS5vbmx5KEopKTt6Lm9uc3VjY2Vzcz0oSyk9PntsZXQgRj1LLnRhcmdldC5yZXN1bHQ7aWYoRil7bGV0IE49Sj09PXZvaWQgMD9GLmtleTpGLnByaW1hcnlLZXksVT1GLnZhbHVlO1cucHVzaCh7aGFzaDpOMChOKSxkYXRhOlV9KSxGLmNvbnRpbnVlKCl9ZWxzZSBQcm9taXNlLmFsbChXLm1hcCgoe2hhc2g6TixkYXRhOlV9KT0+YiQoTixVLHRoaXMuY3J5cHRvLHtib2R5Olp9KSkpLnRoZW4oVikuY2F0Y2goWCl9LHoub25lcnJvcj0oKT0+WCh6LmVycm9yKX0pfWFzeW5jIGNvdW50KCQpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZG9ubHkiKS5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntsZXQgVj0kPT09dm9pZCAwP1ouY291bnQoKTpaLmluZGV4KEkkKS5jb3VudChJREJLZXlSYW5nZS5vbmx5KCQpKTtWLm9uc3VjY2Vzcz0oKT0+UShWLnJlc3VsdCksVi5vbmVycm9yPSgpPT5ZKFYuZXJyb3IpfSl9YXN5bmMgbGlzdEtleXMoKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFk9W10sVj1KLm9wZW5LZXlDdXJzb3IoKTtWLm9uc3VjY2Vzcz0oWCk9PntsZXQgVz1YLnRhcmdldC5yZXN1bHQ7aWYoVylZLnB1c2goTjAoVy5rZXkpKSxXLmNvbnRpbnVlKCk7ZWxzZSBaKFkpfSxWLm9uZXJyb3I9KCk9PlEoVi5lcnJvcil9KX1hc3luYyBsYXN0KCQpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZG9ubHkiKS5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntsZXQgVixYPVoub3BlbkN1cnNvcigpO1gub25zdWNjZXNzPWFzeW5jKFcpPT57bGV0IHo9Vy50YXJnZXQucmVzdWx0O2lmKHope2xldHtrZXk6Syx2YWx1ZTpGfT16O2lmKHIoJCxGLmVpZCkpe2lmKCFWfHwoRi5jdHI/PzApPihWLmRhdGEuY3RyPz8wKXx8KEYuY3RyPz8wKT09PShWLmRhdGEuY3RyPz8wKSYmKEYub2ZmPz8wKT4oVi5kYXRhLm9mZj8/MCkpVj17a2V5OkssZGF0YTpGfX16LmNvbnRpbnVlKCl9ZWxzZSBpZihWKXtsZXQgSz1OMChWLmtleSk7UShhd2FpdCBiJChLLFYuZGF0YSx0aGlzLmNyeXB0bykpfWVsc2UgUSh2b2lkIDApfSxYLm9uZXJyb3I9KCk9PlkoWC5lcnJvcil9KX1hc3luYyBtYXJrQXBwbGllZCgkKXtsZXQgSj1bLi4uJF07aWYoSi5sZW5ndGg9PT0wKXJldHVybjtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWR3cml0ZSIpLFE9Wi5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFksVik9PntaLm9uY29tcGxldGU9KCk9PlkoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvcik7Zm9yKGxldCBYIG9mIEope2xldCBXPUIoWCksej1RLmdldChXKTt6Lm9uc3VjY2Vzcz0oKT0+e2xldCBLPXoucmVzdWx0O2lmKCFLKXJldHVybjtCSihLLHkkKSxRLnB1dChLLFcpfSx6Lm9uZXJyb3I9KEspPT57Sy5wcmV2ZW50RGVmYXVsdCgpfX19KX1hc3luYyBtYXJrRmFpbGVkKCQpe2xldCBKPVsuLi4kXTtpZihKLmxlbmd0aD09PTApcmV0dXJuO2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZHdyaXRlIiksUT1aLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKTtmb3IobGV0e2tleTpYLGVycjpXfW9mIEope2xldCB6PUIoWCksSz1RLmdldCh6KTtLLm9uc3VjY2Vzcz0oKT0+e2xldCBGPUsucmVzdWx0O2lmKCFGKXJldHVybjtCSihGLFokLFcpLFEucHV0KEYseil9LEsub25lcnJvcj0oRik9PntGLnByZXZlbnREZWZhdWx0KCl9fX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWR3cml0ZSIpLEo9JC5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PnskLm9uY29tcGxldGU9KCk9PlooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksSi5jbGVhcigpfSl9fWNsYXNzIEdaeyMkOyNKOyNROyNaO2NvbnN0cnVjdG9yKCQpe2lmKHRoaXMuI1o9JC5wZXJzaXN0TWV0YSx0aGlzLiNRPXtycElkOiQucnBJZCxycE5hbWU6JC5ycE5hbWV9LCQubWV0YSE9PXZvaWQgMCl0aGlzLiNKPWwwKCQubWV0YSl9Z2V0IG1ldGEoKXtyZXR1cm4gdGhpcy4jSj09PXZvaWQgMD92b2lkIDA6bDAodGhpcy4jSil9c2V0TWV0YSgkKXt0aGlzLiNKPSQ9PT12b2lkIDA/dm9pZCAwOmwwKCQpfWFzeW5jIHNhdmUoJCxKKXtpZihKPy5wZXJzaXN0PT09ITApcmV0dXJuIFByb21pc2UucmVqZWN0KEVycm9yKCJwcmYtc3RvcmU6IHVzZSB3cmFwQW5kU2F2ZShlbmNsYXZlKSB0byBwZXJzaXN0IHNlYWxlZCBtYXN0ZXIiKSk7cmV0dXJuIHRoaXMuIyQ9JCx0aGlzLiMkfWFzeW5jIHdyYXBBbmRTYXZlKCQsSil7bGV0W1osUV09YXdhaXQgJC5zZWFsV2l0aFBhc3NrZXkoey4uLnRoaXMuI1Esc2FsdDpKPy5zYWx0LGNyZWRJZDpKPy5jcmVkSWQ/P3RoaXMuI0o/LmNyZWRJZCxjcmVhdGVDcmVkSWZOZWVkZWQ6Sj8uY3JlYXRlQ3JlZElmTmVlZGVkPz9KPy5jcmVkSWQ9PT12b2lkIDAsdXNlck5hbWU6ImRpcGxvbWF0aWMtcHJmIn0pO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMTIpO2xldCBZPXtzZWFsZWRNYXN0ZXI6Wi5zZWFsZWRNYXN0ZXIsc2FsdDpaLnNhbHQsY3JlZElkOlouY3JlZElkfTtyZXR1cm4gdGhpcy4jSj1ZLHRoaXMuIyQ9JCxhd2FpdCB0aGlzLiNaKGwwKFkpKSxPKHRoaXMuIyQpfWFzeW5jIGxvYWQoKXtyZXR1cm4gdGhpcy4jJH1hc3luYyB1bmxvY2soKXtsZXQgJD10aGlzLiNKO2lmKCQ9PT12b2lkIDApcmV0dXJuIEcoMjIpO2xldFtKLFpdPWF3YWl0IFcwLnVuc2VhbFdpdGhQYXNza2V5KCQuc2VhbGVkTWFzdGVyLHsuLi50aGlzLiNRLHNhbHQ6JC5zYWx0LGNyZWRJZDokLmNyZWRJZH0pO2lmKFohPT0wKXJldHVybiBHKFopO2lmKHRoaXMuIyQ9Si5lbmNsYXZlLEouY3JlZElkLmJ5dGVMZW5ndGg+MCYmKCQuY3JlZElkPT09dm9pZCAwfHwhcigkLmNyZWRJZCxKLmNyZWRJZCkpKXtsZXQgUT17c2VhbGVkTWFzdGVyOiQuc2VhbGVkTWFzdGVyLHNhbHQ6JC5zYWx0LGNyZWRJZDpKLmNyZWRJZC5zbGljZSgpfTt0aGlzLiNKPVEsYXdhaXQgdGhpcy4jWihsMChRKSl9cmV0dXJuIE8oSi5lbmNsYXZlKX1hc3luYyBhZG9wdFNlYWxlZCgkLEope3JldHVybiB0aGlzLiNKPWwwKEopLHRoaXMuIyQ9JCxhd2FpdCB0aGlzLiNaKGwwKEopKSxPKHRoaXMuIyQpfWFzeW5jIHdpcGUoKXt0aGlzLiMkPXZvaWQgMCx0aGlzLiNKPXZvaWQgMCxhd2FpdCB0aGlzLiNaKHZvaWQgMCl9fWZ1bmN0aW9uIGwwKCQpe2xldFtKLFpdPXgwKCQuc2VhbGVkTWFzdGVyLnNsaWNlKCkpO3JldHVybntzZWFsZWRNYXN0ZXI6Wj09PTAmJkohPT12b2lkIDA/SjokLnNlYWxlZE1hc3RlcixzYWx0OiQuc2FsdC5zbGljZSgpLGNyZWRJZDokLmNyZWRJZD09PXZvaWQgMD92b2lkIDA6JC5jcmVkSWQuc2xpY2UoKX19dmFyIEVWPSJkaXBsb21hdGljLnBpbi8iO2Z1bmN0aW9uIGZWKCQpe3JldHVybiBFVitVMCgkKX1hc3luYyBmdW5jdGlvbiB1USgkLEosWil7bGV0IFE9YXdhaXQgSi5kZXJpdmVJZGVudGl0eShmVihaKSwwKTtyZXR1cm4gJC5ibGFrZTMoUS5wdWJsaWNLZXkpfWFzeW5jIGZ1bmN0aW9uIHBRKCQsSil7bGV0IFo9YXdhaXQgJC5nZW4yNTZCaXRTZWN1cmVSYW5kb21TZWVkKCksUT1hd2FpdCB1USgkLEosWik7cmV0dXJue246WixoOlF9fWFzeW5jIGZ1bmN0aW9uIGNRKCQsSixaKXtsZXQgUT1hd2FpdCB1USgkLEosWi5uKTtyZXR1cm4gZ1YoUSxaLmgpfWZ1bmN0aW9uIG5RKCQpe2lmKCQ9PT12b2lkIDB8fCQ9PT1udWxsfHx0eXBlb2YgJCE9PSJvYmplY3QiKXJldHVybjtsZXQgSj0kO2lmKCEoSi5uIGluc3RhbmNlb2YgVWludDhBcnJheSl8fCEoSi5oIGluc3RhbmNlb2YgVWludDhBcnJheSkpcmV0dXJuO2lmKEoubi5ieXRlTGVuZ3RoPDF8fEouaC5ieXRlTGVuZ3RoPDEpcmV0dXJuO3JldHVybntuOkoubi5zbGljZSgpLGg6Si5oLnNsaWNlKCl9fWZ1bmN0aW9uIGRRKCQpe3JldHVybntuOiQubi5zbGljZSgpLGg6JC5oLnNsaWNlKCl9fWZ1bmN0aW9uIGdWKCQsSil7aWYoJC5ieXRlTGVuZ3RoIT09Si5ieXRlTGVuZ3RoKXJldHVybiExO2xldCBaPTA7Zm9yKGxldCBRPTA7UTwkLmJ5dGVMZW5ndGg7USsrKVp8PSRbUV1eSltRXTtyZXR1cm4gWj09PTB9dmFyIFpKPSJwcmZNZXRhIix6Wj0iaWRQaW4iLHJRPSJpZFB1YiI7Y2xhc3MgS1p7IyQ7ZGI7I0o7Y29uc3RydWN0b3IoJCxKKXt0aGlzLmRiPSQsdGhpcy4jSj1KfWFzeW5jIHNhdmUoJCxKKXtyZXR1cm4gYXdhaXQgdGhpcy4jUSgkKSx0aGlzLiMkPSQsdGhpcy4jJH1hc3luYyBsb2FkKCl7cmV0dXJuIHRoaXMuIyR9YXN5bmMgY2xlYXJTZXNzaW9uKCl7dGhpcy4jJD12b2lkIDB9YXN5bmMgd2lwZSgpe3RoaXMuIyQ9dm9pZCAwO2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWR3cml0ZSIpLEo9JC5vYmplY3RTdG9yZShRMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5aKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLEouZGVsZXRlKFpKKSxKLmRlbGV0ZSh6WiksSi5kZWxldGUoclEpfSl9YXN5bmMgbG9hZFByZk1ldGEoKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFEwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PntsZXQgWT1KLmdldChaSik7WS5vbnN1Y2Nlc3M9KCk9PntaKG1WKFkucmVzdWx0KSl9LFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfWFzeW5jIHBlcnNpc3RQcmZNZXRhKCQpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWR3cml0ZSIpLFo9Si5vYmplY3RTdG9yZShRMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFkpPT57aWYoSi5vbmNvbXBsZXRlPSgpPT5RKCksSi5vbmVycm9yPSgpPT5ZKEouZXJyb3IpLCQ9PT12b2lkIDApe1ouZGVsZXRlKFpKKTtyZXR1cm59bGV0IFY9e3NlYWxlZE1hc3RlcjokLnNlYWxlZE1hc3Rlci5zbGljZSgpLHNhbHQ6JC5zYWx0LnNsaWNlKCksY3JlZElkOiQuY3JlZElkPT09dm9pZCAwP3ZvaWQgMDokLmNyZWRJZC5zbGljZSgpfTtaLnB1dChWLFpKKX0pfWFzeW5jIGhhc1ByZk1ldGEoKXtyZXR1cm4gYXdhaXQgdGhpcy5sb2FkUHJmTWV0YSgpIT09dm9pZCAwfWFzeW5jIGxhc3RQcmZDcmVkSWQoKXtsZXQgJD1hd2FpdCB0aGlzLmxvYWRQcmZNZXRhKCk7cmV0dXJuICQ/LmNyZWRJZD09PXZvaWQgMD92b2lkIDA6JC5jcmVkSWQuc2xpY2UoKX1hc3luYyBvcGVuUHJmU3RvcmUoJCl7bGV0IEo9YXdhaXQgdGhpcy5sb2FkUHJmTWV0YSgpO3JldHVybiBuZXcgR1ooe3JwSWQ6JC5ycElkLHJwTmFtZTokLnJwTmFtZSxtZXRhOkoscGVyc2lzdE1ldGE6KFopPT50aGlzLnBlcnNpc3RQcmZNZXRhKFopfSl9YXN5bmMjUSgkKXthd2FpdCB0aGlzLiNWKHJRKTtsZXQgSj1hd2FpdCB0aGlzLiNaKCk7aWYoSiE9PXZvaWQgMCl7aWYoIWF3YWl0IGNRKHRoaXMuI0osJCxKKSl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIHNlZWQgZG9lcyBub3QgbWF0Y2ggdGhpcyBkZXZpY2UncyBpZGVudGl0eSAobG9jYWwgZGF0YSB3YXMgY3JlYXRlZCB3aXRoIGEgZGlmZmVyZW50IG1hc3RlciBzZWVkKSIpO3JldHVybn1sZXQgWj1hd2FpdCBwUSh0aGlzLiNKLCQpO2F3YWl0IHRoaXMuI1koWil9I1ooKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFEwLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PntsZXQgWT1KLmdldCh6Wik7WS5vbnN1Y2Nlc3M9KCk9PlooblEoWS5yZXN1bHQpKSxZLm9uZXJyb3I9KCk9PlEoWS5lcnJvcil9KX0jWSgkKXtsZXQgSj1kUSgkKSxaPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWR3cml0ZSIpLFE9Wi5vYmplY3RTdG9yZShRMCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57Wi5vbmNvbXBsZXRlPSgpPT5ZKCksWi5vbmVycm9yPSgpPT5WKFouZXJyb3IpLFEucHV0KEoselopfSl9I1YoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZHdyaXRlIiksWj1KLm9iamVjdFN0b3JlKFEwKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntKLm9uY29tcGxldGU9KCk9PlEoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvciksWi5kZWxldGUoJCl9KX19ZnVuY3Rpb24gbVYoJCl7aWYoJD09PXZvaWQgMHx8JD09PW51bGx8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuO2xldCBKPSQ7aWYoIShKLnNlYWxlZE1hc3RlciBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpfHwhKEouc2FsdCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKXJldHVybjtsZXRbWixRXT14MChKLnNlYWxlZE1hc3Rlcik7aWYoUSE9PTB8fFo9PT12b2lkIDApcmV0dXJuO3JldHVybntzZWFsZWRNYXN0ZXI6WixzYWx0Okouc2FsdC5zbGljZSgpLGNyZWRJZDpKLmNyZWRJZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXk/Si5jcmVkSWQuc2xpY2UoKTp2b2lkIDB9fWNsYXNzIEZae2RiO2NvbnN0cnVjdG9yKCQpe3RoaXMuZGI9JH1hc3luYyBlbnEoJCxKKXtsZXQgWj1bLi4uSl07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgUT10aGlzLmRiLnRyYW5zYWN0aW9uKEYwLCJyZWFkd3JpdGUiKSxZPVEub2JqZWN0U3RvcmUoRjApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e1Eub25jb21wbGV0ZT0oKT0+VigpLFEub25lcnJvcj0oKT0+WChRLmVycm9yKTtmb3IobGV0IFcgb2YgWil7bGV0IHo9VTAoVyk7WS5wdXQoe2hvc3Q6JCxoYXNoOnp9KX19KX1hc3luYyBkZXEoJCxKKXtsZXQgWj1bLi4uSl07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgUT10aGlzLmRiLnRyYW5zYWN0aW9uKEYwLCJyZWFkd3JpdGUiKSxZPVEub2JqZWN0U3RvcmUoRjApO3JldHVybiBuZXcgUHJvbWlzZSgoVixYKT0+e1Eub25jb21wbGV0ZT0oKT0+VigpLFEub25lcnJvcj0oKT0+WChRLmVycm9yKTtmb3IobGV0IFcgb2YgWil7bGV0IHo9VTAoVyk7WS5kZWxldGUoWyQsel0pfX0pfWFzeW5jIGxpc3QoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihGMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShGMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFkpPT57bGV0IFY9Wi5nZXRBbGwoKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVYucmVzdWx0LmZpbHRlcigoeik9PnouaG9zdD09PSQpLm1hcCgoeik9PnouaGFzaCk7UShXLm1hcCgoeik9Pl9aKHopKSl9LFYub25lcnJvcj0oKT0+WShWLmVycm9yKX0pfWFzeW5jIGNvdW50KCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihGMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShGMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFk9Si5jb3VudCgpO1kub25zdWNjZXNzPSgpPT5aKFkucmVzdWx0KSxZLm9uZXJyb3I9KCk9PlEoWS5lcnJvcil9KX1hc3luYyB3aXBlKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihGMCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKEYwKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PnskLm9uY29tcGxldGU9KCk9PlooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksSi5jbGVhcigpfSl9fXZhciBRMD0ic2VlZE1ldGEiLFowPSJob3N0cyIsRjA9InVwbG9hZFF1ZXVlIixLMD0iZG93bmxvYWRRdWV1ZSIsdT0ibWVzc2FnZXMiLEkkPSJhcGxkIixvUT0zLGFRPSJkaXBsb21hdGljLXN0b3JlLWRiIjtjbGFzcyBzUXtzZWVkO2hvc3RzO3VwbG9hZHM7ZG93bmxvYWRzO21lc3NhZ2VzO2RiO2NvbnN0cnVjdG9yKCQsSil7dGhpcy5kYj0kLHRoaXMuc2VlZD1uZXcgS1ooJCxKKSx0aGlzLmhvc3RzPW5ldyBYWigkKSx0aGlzLnVwbG9hZHM9bmV3IEZaKCQpLHRoaXMuZG93bmxvYWRzPW5ldyBWWigkKSx0aGlzLm1lc3NhZ2VzPW5ldyBXWigkLEopfWFzeW5jIHdpcGUoKXthd2FpdCB0aGlzLmhvc3RzLndpcGUoKSxhd2FpdCB0aGlzLnVwbG9hZHMud2lwZSgpLGF3YWl0IHRoaXMuZG93bmxvYWRzLndpcGUoKSxhd2FpdCB0aGlzLm1lc3NhZ2VzLndpcGUoKX19YXN5bmMgZnVuY3Rpb24gU1YoKXtyZXR1cm4gbmV3IFByb21pc2UoKCQsSik9PntsZXQgWj1pbmRleGVkREIub3BlbihhUSxvUSk7Wi5vbnVwZ3JhZGVuZWVkZWQ9KCk9PntsZXR7cmVzdWx0OlEsdHJhbnNhY3Rpb246WX09WjtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKFEwKSlRLmNyZWF0ZU9iamVjdFN0b3JlKFEwKTtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKFowKSlRLmNyZWF0ZU9iamVjdFN0b3JlKFowLHtrZXlQYXRoOiJsYWJlbCJ9KTtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKEYwKSlRLmNyZWF0ZU9iamVjdFN0b3JlKEYwLHtrZXlQYXRoOlsiaG9zdCIsImhhc2giXX0pO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnMoSzApKVEuY3JlYXRlT2JqZWN0U3RvcmUoSzApO2xldCBWO2lmKCFRLm9iamVjdFN0b3JlTmFtZXMuY29udGFpbnModSkpVj1RLmNyZWF0ZU9iamVjdFN0b3JlKHUpO2Vsc2V7aWYoIVkpdGhyb3cgRXJyb3IoIm1pc3NpbmcgdXBncmFkZSB0cmFuc2FjdGlvbiBmb3IgbWVzc2FnZXMgc3RvcmUiKTtWPVkub2JqZWN0U3RvcmUodSl9aWYoIVYuaW5kZXhOYW1lcy5jb250YWlucyhJJCkpVi5jcmVhdGVJbmRleChJJCwiYXBsZCIse3VuaXF1ZTohMX0pfSxaLm9uYmxvY2tlZD0oKT0+e2NvbnNvbGUud2FybihgW0RJUExPTUFUSUNdIHByb3RvY29sIHN0b3JlIElEQiB1cGdyYWRlIGJsb2NrZWQgKCR7YVF9IOKGkiB2JHtvUX0pOyB3YWl0aW5nIGZvciBvdGhlciBjb25uZWN0aW9ucyB0byBjbG9zZWApfSxaLm9uc3VjY2Vzcz0oKT0+e2xldCBRPVoucmVzdWx0O1Eub252ZXJzaW9uY2hhbmdlPSgpPT57US5jbG9zZSgpfSwkKFEpfSxaLm9uZXJyb3I9KCk9PkooWi5lcnJvcj8/RXJyb3IoInByb3RvY29sIHN0b3JlIEluZGV4ZWREQiBvcGVuIGZhaWxlZCIpKX0pfWFzeW5jIGZ1bmN0aW9uIHRRKCQpe2xldCBKPWF3YWl0IFNWKCk7aWYodHlwZW9mIG5hdmlnYXRvcjwidSImJm5hdmlnYXRvci5zdG9yYWdlPy5wZXJzaXN0KXRyeXthd2FpdCBQcm9taXNlLnJhY2UoW25hdmlnYXRvci5zdG9yYWdlLnBlcnNpc3QoKSxuZXcgUHJvbWlzZSgoWik9PntzZXRUaW1lb3V0KCgpPT5aKCExKSwyMDAwKX0pXSl9Y2F0Y2h7fXJldHVybiBuZXcgc1EoSiwkKX1jbGFzcyBOWntjbGllbnQ7ZW50REI7cG9zdDt3aGVuUmVhZHk7cmVzb2x2ZVJlYWR5O3JlamVjdFJlYWR5O2NvbnN0cnVjdG9yKCQpe3RoaXMucG9zdD0kLHRoaXMud2hlblJlYWR5PW5ldyBQcm9taXNlKChKLFopPT57dGhpcy5yZXNvbHZlUmVhZHk9Six0aGlzLnJlamVjdFJlYWR5PVp9KX1hc3luYyBpbml0KCl7dHJ5e2xldCAkPWF3YWl0IHRRKGQkKSxKPWF3YWl0IGRaKHtjYWNoZTohMX0pLFo9bmV3IGYkKEouYXBwbHksKCk9PkouY2xlYXIoKSwoVik9PntpZihWLmxlbmd0aDwxKXJldHVybjt0aGlzLnBvc3Qoe2tpbmQ6ImRpcnR5IixlaWRzOlYubWFwKChYKT0+WC5zbGljZSgpKX0pfSksUT1aLmNsZWFyO1ouY2xlYXI9YXN5bmMoKT0+e2xldCBWPWF3YWl0IFEoKTtpZihWPT09MCl0aGlzLnBvc3Qoe2tpbmQ6IndpcGVkIn0pO3JldHVybiBWfTtsZXQgWT1uZXcgU0oobmV3IEZKLFosJCx2WixkJCk7dGhpcy5jbGllbnQ9WSx0aGlzLmVudERCPUosWS5jbGllbnRTdGF0ZS5saXN0ZW4oKCk9Pnt0aGlzLmVtaXRDbGllbnRTdGF0ZSgpfSksWS54ZmVyU3RhdGUubGlzdGVuKCgpPT57dGhpcy5lbWl0WGZlclN0YXRlKCl9KSxhd2FpdCB0aGlzLmVtaXRYZmVyU3RhdGUoKSx0aGlzLnBvc3Qoe2tpbmQ6InJlYWR5In0pLHRoaXMubWFya1JlYWR5KCl9Y2F0Y2goJCl7bGV0IEo9JCBpbnN0YW5jZW9mIEVycm9yPyQ6RXJyb3IoU3RyaW5nKCQpKTt0aHJvdyB0aGlzLnBvc3Qoe2tpbmQ6ImluaXRFcnJvciIsbWVzc2FnZTpKLm1lc3NhZ2V9KSx0aGlzLmZhaWxSZWFkeShKKSxKfX1tYXJrUmVhZHkoKXtsZXQgJD10aGlzLnJlc29sdmVSZWFkeTtpZih0aGlzLnJlc29sdmVSZWFkeT12b2lkIDAsdGhpcy5yZWplY3RSZWFkeT12b2lkIDAsJCkkKCl9ZmFpbFJlYWR5KCQpe2xldCBKPXRoaXMucmVqZWN0UmVhZHk7aWYodGhpcy5yZXNvbHZlUmVhZHk9dm9pZCAwLHRoaXMucmVqZWN0UmVhZHk9dm9pZCAwLEopSigkKX1yZXF1aXJlQ2xpZW50KCl7aWYoIXRoaXMuY2xpZW50KXRocm93IEVycm9yKCJXb3JrZXJSdW50aW1lIG5vdCBpbml0aWFsaXplZCIpO3JldHVybiB0aGlzLmNsaWVudH1hc3luYyBlbWl0Q2xpZW50U3RhdGUoKXtsZXQgJD10aGlzLmNsaWVudDtpZighJClyZXR1cm47bGV0IEo9YXdhaXQgJC5jbGllbnRTdGF0ZS5nZXQoKTt0aGlzLnBvc3Qoe2tpbmQ6ImNsaWVudFN0YXRlIixjb25uZWN0ZWQ6Si5jb25uZWN0ZWR9KX1hc3luYyBlbWl0WGZlclN0YXRlKCl7bGV0ICQ9dGhpcy5jbGllbnQ7aWYoISQpcmV0dXJuO2xldCBKPWF3YWl0ICQueGZlclN0YXRlLmdldCgpO3RoaXMucG9zdCh7a2luZDoieGZlclN0YXRlIixzdGF0ZTpKfSl9aG9zdEZyb21TZXJpYWxpemVkKCQpe3JldHVybntoYW5kbGU6bmV3IFVSTCgkLmhhbmRsZSksbGFiZWw6JC5sYWJlbCxpZHg6JC5pZHh9fWFzeW5jIGhhbmRsZSgkKXthd2FpdCB0aGlzLndoZW5SZWFkeTtsZXQgSj10aGlzLnJlcXVpcmVDbGllbnQoKTtzd2l0Y2goJC5vcCl7Y2FzZSJwaW5nIjpyZXR1cm4icG9uZyI7Y2FzZSJzZXRTZWVkIjp7bGV0W1osUV09VzAuZnJvbUJ5dGVzKCQuc2VlZCk7aWYoJC5zZWVkLmZpbGwoMCksUSE9PTB8fFo9PT12b2lkIDApdGhyb3cgbmV3IE8wKFEpO2F3YWl0IEouc2V0U2VlZChaLHtwZXJzaXN0OiQucGVyc2lzdH0pO3JldHVybn1jYXNlImxpbmsiOnthd2FpdCBKLmxpbmsodGhpcy5ob3N0RnJvbVNlcmlhbGl6ZWQoJC5ob3N0KSwkLmNvbm5lY3Q/PyEwKTtyZXR1cm59Y2FzZSJ1bmxpbmsiOnthd2FpdCBKLnVubGluaygkLmxhYmVsKTtyZXR1cm59Y2FzZSJjb25uZWN0Ijp7YXdhaXQgSi5jb25uZWN0KCQubGlzdGVuPz8hMCwkLnN5bmM/PyEwKTtyZXR1cm59Y2FzZSJkaXNjb25uZWN0Ijp7YXdhaXQgSi5kaXNjb25uZWN0KCk7cmV0dXJufWNhc2Uic3luYyI6cmV0dXJuIGF3YWl0IEouc3luYygpO2Nhc2UicmVidWlsZCI6cmV0dXJuIGF3YWl0IEoucmVidWlsZCh7Y2hlY2tIb3N0OiQuY2hlY2tIb3N0Pz8hMH0pO2Nhc2UicmVjb25jaWxlIjp7bGV0W1osUV09YXdhaXQgSi5yZWNvbmNpbGUoJC5ob3N0TGFiZWwse3B1bGw6JC5wdWxsLHB1c2g6JC5wdXNoLHN5bmM6JC5zeW5jfSk7aWYoUSE9PTApdGhyb3cgbmV3IE8wKFEpO2lmKCFaKXRocm93IG5ldyBPMCgxMik7cmV0dXJuIFp9Y2FzZSJtc2djaGVjayI6cmV0dXJuIGF3YWl0IEoubXNnY2hlY2soKTtjYXNlImVudGNoZWNrIjp7bGV0IFo9dGhpcy5lbnREQjtpZighWil0aHJvdyBuZXcgTzAoMTIpO2xldFtRLFldPWF3YWl0IFouY2hlY2tzdW0oZCQpO2lmKFkhPT0wKXRocm93IG5ldyBPMChZKTtpZighUSl0aHJvdyBuZXcgTzAoMTIpO3JldHVybiBRfWNhc2Uid2lwZSI6e2F3YWl0IEoud2lwZSh7bXNnczokLm1zZ3MsZW50czokLmVudHMsbWV0YTokLm1ldGEsc2VlZDokLnNlZWR9KTtyZXR1cm59Y2FzZSJpbXBvcnQiOntsZXQgWj0kLmJ5dGVzLnNsaWNlKCksUT1uZXcgQmxvYihbWl0pLFk9bmV3IEZpbGUoW1FdLCJpbXBvcnQuZGlwIik7cmV0dXJuIGF3YWl0IEouaW1wb3J0KFkpfWNhc2UiZXhwb3J0Ijp7bGV0W1osUV09YXdhaXQgSi5leHBvcnRCeXRlcygpO2lmKFEhPT0wKXRocm93IG5ldyBPMChRKTtpZighWil0aHJvdyBuZXcgTzAoMTIpO3JldHVybiBafWNhc2UiZ2V0WGZlclN0YXRlIjpyZXR1cm4gYXdhaXQgSi54ZmVyU3RhdGUuZ2V0KCk7ZGVmYXVsdDp7bGV0IFo9JDt0aHJvdyBFcnJvcigidW5rbm93biB3b3JrZXIgY29tbWFuZCIpfX19fWNsYXNzIE8wIGV4dGVuZHMgRXJyb3J7c3RhdHVzO2NvbnN0cnVjdG9yKCQpe3N1cGVyKGBXb3JrZXJTdGF0dXNFcnJvcjogJHtEWyRdfWApO3RoaXMuc3RhdHVzPSQ7dGhpcy5uYW1lPSJXb3JrZXJTdGF0dXNFcnJvciJ9fWZ1bmN0aW9uIFFKKCQsSil7cmV0dXJue2tpbmQ6InJlcGx5IixpZDokLG9rOiEwLHJlc3VsdDpKfX1mdW5jdGlvbiBPWigkLEope3JldHVybntraW5kOiJyZXBseSIsaWQ6JCxvazohMSxzdGF0dXM6Sn19dmFyIGswPWdsb2JhbFRoaXMsZVE9bmV3IE5aKCgkLEopPT57aWYoSiYmSi5sZW5ndGg+MClrMC5wb3N0TWVzc2FnZSgkLEopO2Vsc2UgazAucG9zdE1lc3NhZ2UoJCl9KTtrMC5vbm1lc3NhZ2U9KCQpPT57bGV0IEo9JC5kYXRhO2lmKCFxWihKKSlyZXR1cm47dlYoSil9O2FzeW5jIGZ1bmN0aW9uIHZWKCQpe3RyeXtsZXQgSj1hd2FpdCBlUS5oYW5kbGUoJCk7aWYoKCQub3A9PT0iZXhwb3J0Inx8JC5vcD09PSJtc2djaGVjayJ8fCQub3A9PT0iZW50Y2hlY2siKSYmSiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpe2xldCBaPUouc2xpY2UoKTtrMC5wb3N0TWVzc2FnZShRSigkLmlkLFopLFtaLmJ1ZmZlcl0pO3JldHVybn1pZigkLm9wPT09InJlY29uY2lsZSImJkomJnR5cGVvZiBKPT09Im9iamVjdCImJiJtc2djaGVjayJpbiBKJiZKLm1zZ2NoZWNrIGluc3RhbmNlb2YgVWludDhBcnJheSl7bGV0IFo9Si5tc2djaGVjay5zbGljZSgpLFE9ey4uLkosbXNnY2hlY2s6Wn07azAucG9zdE1lc3NhZ2UoUUooJC5pZCxRKSxbWi5idWZmZXJdKTtyZXR1cm59azAucG9zdE1lc3NhZ2UoUUooJC5pZCxKKSl9Y2F0Y2goSil7aWYoSiBpbnN0YW5jZW9mIE8wKXtrMC5wb3N0TWVzc2FnZShPWigkLmlkLEouc3RhdHVzKSk7cmV0dXJufWNvbnNvbGUuZXJyb3IoIndvcmtlciBjb21tYW5kIGZhaWxlZCIsSiksazAucG9zdE1lc3NhZ2UoT1ooJC5pZCwxMikpfX1lUS5pbml0KCkuY2F0Y2goKCQpPT57Y29uc29sZS5lcnJvcigid29ya2VyIGluaXQgZmFpbGVkIiwkKX0pOwo=";var yW=typeof globalThis.Worker==="function"?globalThis.Worker:void 0,EV=yW===void 0?void 0:yW.prototype.postMessage,pW;function eK(){if(typeof QW!=="string"||QW.length===0)throw Error("[DIPLOMATIC] worker source not embedded; run pkg build before spawn");return atob(QW)}function ZG(){if(pW!==void 0)return pW;let Z=new Blob([eK()],{type:"text/javascript"});return pW=URL.createObjectURL(Z),pW}function J0(){if(yW===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot spawn sync worker");return new yW(ZG(),{type:"module"})}function C0(Z,X,W){if(EV===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot post to sync worker");if(W!==void 0&&W.length>0)EV.call(Z,X,{transfer:W});else EV.call(Z,X)}var XG=new TextEncoder().encode("diplomatic.wrap.v1"),WG=32,VG=16,FZ=new nZ;class ZZ{#Z;constructor(Z){this.#Z=Z}static async fromRandom(){let Z=await FZ.gen256BitSecureRandomSeed(),[X,W]=VZ(Z);if(W!==0||X===void 0)throw Error(`enclave: invalid random seed (${W})`);return new ZZ(X)}static fromBytes(Z){let[X,W]=VZ(Z);if(W!==0)return Y(W);if(X===void 0)return Y(10);let[V,l]=VZ(X.slice());if(l!==0)return Y(l);if(V===void 0)return Y(10);return b(new ZZ(V))}async sealWithPasskey(Z){let X=Z?.salt??cW,W=Z?.credId;if(W===void 0&&Z?.createCredIfNeeded===!0){let[K,G]=await R0({rpId:Z?.rpId,rpName:Z?.rpName,userName:Z?.userName??"diplomatic-prf",authenticatorAttachment:Z?.authenticatorAttachment,salt:X});if(G!==0)return Y(G);if(K===void 0)return Y(24);if(!K.prfEnabled)return Y(24);W=K.credId}let[V,l]=await iV({rpId:Z?.rpId,rpName:Z?.rpName,credId:W,salt:X});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await this.#W(V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);return b({sealedMaster:K,salt:X.slice(),credId:V.credId.slice()})}finally{V.prf.fill(0)}}static async unsealWithPasskey(Z,X){let[W,V]=await iV({rpId:X.rpId,rpName:X.rpName,credId:X.credId,salt:X.salt});if(V!==0)return Y(V);if(W===void 0)return Y(7);try{let[l,K]=await ZZ.#V(Z,W.prf);if(K!==0)return Y(K);if(l===void 0)return Y(12);return b({enclave:l,credId:W.credId.slice()})}finally{W.prf.fill(0)}}async persistToLargeBlob(Z=[],X){let W=X?.credId;if(W===void 0){let[K,G]=await TW(X);if(G!==0)return Y(G);if(K===void 0)return Y(24);W=K}let[V,l]=this.#l(Z);if(l!==0)return Y(l);if(V===void 0)return Y(12);try{let K=await uX(W,V,X);if(K!==0)return Y(K);return b(W)}finally{V.fill(0)}}static async fromLargeBlob(Z){let[X,W]=await LW(Z?.credId,Z);if(W!==0)return Y(W);if(X===void 0)return Y(7);try{return ZZ.#K(X.blob,X.credId)}finally{X.blob.fill(0)}}static async clearLargeBlob(Z,X){return uX(Z,new Uint8Array(kZ),X)}static pairRequest(){return EX.create()}async pairAccept(Z,X){let W;try{W=await FZ.genX25519()}catch{return Y(29)}try{let[V,l]=await PV(W.priv,Z,Z,W.pub);if(l!==0)return Y(l);if(V===void 0)return Y(12);try{let[K,G]=this.#X(X);if(G!==0)return Y(G);if(K===void 0)return Y(12);try{let m=await FZ.encryptXSalsa20Poly1305Combined(K,V);return UV(TZ(W.pub,m))}catch{return Y(12)}finally{K.fill(0)}}finally{V.fill(0)}}finally{W.priv.fill(0)}}#X(Z){let X=this.#Z.slice(),[W,V]=VZ(X);if(V!==0)return X.fill(0),Y(V);if(W===void 0)return X.fill(0),Y(10);try{let l={masterSeed:W,hosts:Z.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))},K=new E;try{let G=K.writeStruct(dW,l);if(G!==0)return Y(G);return b(K.result())}finally{K.wipe()}}finally{W.fill(0)}}spawnSyncWorker(Z){let X=J0(),W=this.#Z.slice();return C0(X,{id:Z.id,op:"setSeed",seed:W,persist:Z.persist},[W.buffer]),X}deriveCipher(Z,X){let W=Z.slice(),V=(G)=>this.#Y(W,G),l=(G)=>this.#R(W,G);return{encrypt:Object.freeze({encrypt:V}),decrypt:Object.freeze({decrypt:l}),both:Object.freeze({encrypt:V,decrypt:l})}[X]}async deriveIdentity(Z,X=0){let W=Z,V=X,l=await this.#m(W,V),K=l.publicKey;return l.privateKey.fill(0),Object.freeze({publicKey:K,sign:(G)=>this.#C(W,V,G),kdmFor:(G)=>this.#F(W,V,G)})}async#W(Z){let[X,W]=await F0(FZ,Z);if(W!==0)return Y(W);if(X===void 0)return Y(12);try{let V=await FZ.encryptXSalsa20Poly1305Combined(this.#Z,X);return yZ(V)}catch{return Y(12)}finally{X.fill(0)}}static async#V(Z,X){let[,W]=yZ(Z);if(W!==0)return Y(W);let[V,l]=await F0(FZ,X);if(l!==0)return Y(l);if(V===void 0)return Y(12);let K;try{try{K=await FZ.decryptXSalsa20Poly1305Combined(Z,V)}catch{return Y(20)}return ZZ.fromBytes(K)}finally{V.fill(0),K?.fill(0)}}#l(Z){let X=this.#Z.slice(),[W,V]=VZ(X);if(V!==0)return X.fill(0),Y(V);if(W===void 0)return X.fill(0),Y(10);try{let[l,K]=V0(W,Z);if(K!==0)return Y(K);if(l===void 0)return Y(12);try{let G=new E,m=G.writeStruct(HV,l);if(m!==0)return Y(m);return b(G.result())}finally{l.masterSeed.fill(0)}}finally{W.fill(0)}}static#K(Z,X){if(Z.byteLength===0||Z.every((K)=>K===0))return Y(22);if(Z.byteLength===kZ){if(Z.every((m)=>m===0))return Y(22);let[K,G]=ZZ.fromBytes(Z);if(G!==0)return Y(G);if(K===void 0)return Y(12);return b({enclave:K,hosts:[],credId:X})}let W=new O(Z),[V,l]=W.readStruct(HV);if(l!==0)return Y(l);if(V===void 0)return Y(14);try{if(V.masterSeed.every((m)=>m===0))return Y(22);let[K,G]=ZZ.fromBytes(V.masterSeed);if(G!==0)return Y(G);if(K===void 0)return Y(12);return b({enclave:K,hosts:V.hosts.map((m)=>({...m})),credId:X})}finally{V.masterSeed.fill(0)}}async#Y(Z,X){let W=await this.#G(Z);try{return await FZ.encryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#R(Z,X){let W=await this.#G(Z);try{return await FZ.decryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#G(Z){return FZ.blake3(TZ(this.#Z,Z))}async#J(Z,X){let W=new TextEncoder().encode(Z),V=new Uint8Array(8);return new DataView(V.buffer).setBigUint64(0,BigInt(X),!1),await this.#G(TZ(W,V))}async#m(Z,X){let W=await this.#J(Z,X);try{return await FZ.deriveEd25519KeyPair(W)}finally{W.fill(0)}}async#C(Z,X,W){let V=await this.#m(Z,X);try{return await FZ.signEd25519(W,V.privateKey)}finally{V.privateKey.fill(0)}}async#F(Z,X,W){let V=await this.#m(Z,X),l=TZ(V.privateKey,W);V.privateKey.fill(0);try{return(await FZ.blake3(l)).slice(0,OZ)}finally{l.fill(0)}}}async function F0(Z,X,W=XG){if(X.byteLength<VG)return Y(10);let V=await Z.blake3(TZ(X,W));return b(V.slice(0,WG))}class SW{#Z;#X;#W;#V;constructor(Z){if(this.#V=Z.persistMeta,this.#W={rpId:Z.rpId,rpName:Z.rpName},Z.meta!==void 0)this.#X=aZ(Z.meta)}get meta(){return this.#X===void 0?void 0:aZ(this.#X)}setMeta(Z){this.#X=Z===void 0?void 0:aZ(Z)}async save(Z,X){if(X?.persist===!0)return Promise.reject(Error("prf-store: use wrapAndSave(enclave) to persist sealed master"));return this.#Z=Z,this.#Z}async wrapAndSave(Z,X){let[W,V]=await Z.sealWithPasskey({...this.#W,salt:X?.salt,credId:X?.credId??this.#X?.credId,createCredIfNeeded:X?.createCredIfNeeded??X?.credId===void 0,userName:"diplomatic-prf"});if(V!==0)return Y(V);if(W===void 0)return Y(12);let l={sealedMaster:W.sealedMaster,salt:W.salt,credId:W.credId};return this.#X=l,this.#Z=Z,await this.#V(aZ(l)),b(this.#Z)}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await ZZ.unsealWithPasskey(Z.sealedMaster,{...this.#W,salt:Z.salt,credId:Z.credId});if(W!==0)return Y(W);if(this.#Z=X.enclave,X.credId.byteLength>0&&(Z.credId===void 0||!n(Z.credId,X.credId))){let V={sealedMaster:Z.sealedMaster,salt:Z.salt,credId:X.credId.slice()};this.#X=V,await this.#V(aZ(V))}return b(X.enclave)}async adoptSealed(Z,X){return this.#X=aZ(X),this.#Z=Z,await this.#V(aZ(X)),b(this.#Z)}async wipe(){this.#Z=void 0,this.#X=void 0,await this.#V(void 0)}}function aZ(Z){let[X,W]=yZ(Z.sealedMaster.slice());return{sealedMaster:W===0&&X!==void 0?X:Z.sealedMaster,salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()}}var lG="diplomatic.pin/";function KG(Z){return lG+YZ(Z)}async function b0(Z,X,W){let V=await X.deriveIdentity(KG(W),0);return Z.blake3(V.publicKey)}async function zW(Z,X){let W=await Z.gen256BitSecureRandomSeed(),V=await b0(Z,X,W);return{n:W,h:V}}async function NW(Z,X,W){let V=await b0(Z,X,W.n);return GG(V,W.h)}function d0(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.n instanceof Uint8Array)||!(X.h instanceof Uint8Array))return;if(X.n.byteLength<1||X.h.byteLength<1)return;return{n:X.n.slice(),h:X.h.slice()}}function MW(Z){return{n:Z.n.slice(),h:Z.h.slice()}}function GG(Z,X){if(Z.byteLength!==X.byteLength)return!1;let W=0;for(let V=0;V<Z.byteLength;V++)W|=Z[V]^X[V];return W===0}var xW="prfMeta",BV="idPin",k0="idPub";class gW{#Z;db;#X;constructor(Z,X){this.db=Z,this.#X=X}async save(Z,X){return await this.#W(Z),this.#Z=Z,this.#Z}async load(){return this.#Z}async clearSession(){this.#Z=void 0}async wipe(){this.#Z=void 0;let Z=this.db.transaction(GZ,"readwrite"),X=Z.objectStore(GZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.delete(xW),X.delete(BV),X.delete(k0)})}async loadPrfMeta(){let X=this.db.transaction(GZ,"readonly").objectStore(GZ);return new Promise((W,V)=>{let l=X.get(xW);l.onsuccess=()=>{W(mG(l.result))},l.onerror=()=>V(l.error)})}async persistPrfMeta(Z){let X=this.db.transaction(GZ,"readwrite"),W=X.objectStore(GZ);return new Promise((V,l)=>{if(X.oncomplete=()=>V(),X.onerror=()=>l(X.error),Z===void 0){W.delete(xW);return}let K={sealedMaster:Z.sealedMaster.slice(),salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()};W.put(K,xW)})}async hasPrfMeta(){return await this.loadPrfMeta()!==void 0}async lastPrfCredId(){let Z=await this.loadPrfMeta();return Z?.credId===void 0?void 0:Z.credId.slice()}async openPrfStore(Z){let X=await this.loadPrfMeta();return new SW({rpId:Z.rpId,rpName:Z.rpName,meta:X,persistMeta:(W)=>this.persistPrfMeta(W)})}async#W(Z){await this.#K(k0);let X=await this.#V();if(X!==void 0){if(!await NW(this.#X,Z,X))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)");return}let W=await zW(this.#X,Z);await this.#l(W)}#V(){let X=this.db.transaction(GZ,"readonly").objectStore(GZ);return new Promise((W,V)=>{let l=X.get(BV);l.onsuccess=()=>W(d0(l.result)),l.onerror=()=>V(l.error)})}#l(Z){let X=MW(Z),W=this.db.transaction(GZ,"readwrite"),V=W.objectStore(GZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error),V.put(X,BV)})}#K(Z){let X=this.db.transaction(GZ,"readwrite"),W=X.objectStore(GZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}}function mG(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.sealedMaster instanceof Uint8Array)||!(X.salt instanceof Uint8Array))return;let[W,V]=yZ(X.sealedMaster);if(V!==0||W===void 0)return;return{sealedMaster:W,salt:X.salt.slice(),credId:X.credId instanceof Uint8Array?X.credId.slice():void 0}}class jV{db;constructor(Z){this.db=Z}async enq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(bZ,"readwrite"),l=V.objectStore(bZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=YZ(m);l.put({host:Z,hash:R})}})}async deq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(bZ,"readwrite"),l=V.objectStore(bZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=YZ(m);l.delete([Z,R])}})}async list(Z){let W=this.db.transaction(bZ,"readonly").objectStore(bZ);return new Promise((V,l)=>{let K=W.getAll();K.onsuccess=()=>{let m=K.result.filter((R)=>R.host===Z).map((R)=>R.hash);V(m.map((R)=>yX(R)))},K.onerror=()=>l(K.error)})}async count(){let X=this.db.transaction(bZ,"readonly").objectStore(bZ);return new Promise((W,V)=>{let l=X.count();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(bZ,"readwrite"),X=Z.objectStore(bZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var GZ="seedMeta",KZ="hosts",bZ="uploadQueue",CZ="downloadQueue",$="messages",OX="apld",I0=3,T0="diplomatic-store-db";class uV{seed;hosts;uploads;downloads;messages;db;constructor(Z,X){this.db=Z,this.seed=new gW(Z,X),this.hosts=new xV(Z),this.uploads=new jV(Z),this.downloads=new MV(Z),this.messages=new gV(Z,X)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}async function YG(){return new Promise((Z,X)=>{let W=indexedDB.open(T0,I0);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!V.objectStoreNames.contains(GZ))V.createObjectStore(GZ);if(!V.objectStoreNames.contains(KZ))V.createObjectStore(KZ,{keyPath:"label"});if(!V.objectStoreNames.contains(bZ))V.createObjectStore(bZ,{keyPath:["host","hash"]});if(!V.objectStoreNames.contains(CZ))V.createObjectStore(CZ);let K;if(!V.objectStoreNames.contains($))K=V.createObjectStore($);else{if(!l)throw Error("missing upgrade transaction for messages store");K=l.objectStore($)}if(!K.indexNames.contains(OX))K.createIndex(OX,"apld",{unique:!1})},W.onblocked=()=>{console.warn(`[DIPLOMATIC] protocol store IDB upgrade blocked (${T0} → v${I0}); waiting for other connections to close`)},W.onsuccess=()=>{let V=W.result;V.onversionchange=()=>{V.close()},Z(V)},W.onerror=()=>X(W.error??Error("protocol store IndexedDB open failed"))})}async function wV(Z){let X=await YG();if(typeof navigator<"u"&&navigator.storage?.persist)try{await Promise.race([navigator.storage.persist(),new Promise((W)=>{setTimeout(()=>W(!1),2000)})])}catch{}return new uV(X,Z)}function L0(Z){if(!Z||typeof Z!=="object")return!1;if(!("kind"in Z))return!1;return typeof Z.kind==="string"}function c0(Z){if(typeof Z!=="number")return;return Z}function RG(Z){if(!Z||typeof Z!=="object")return;if(!("phase"in Z))return;let X=JG(Z.phase);if(X===void 0)return;let W={phase:X};if("host"in Z&&typeof Z.host==="string")W.host=Z.host;if("done"in Z&&typeof Z.done==="number")W.done=Z.done;if("total"in Z&&typeof Z.total==="number")W.total=Z.total;if("bytesDone"in Z&&typeof Z.bytesDone==="number")W.bytesDone=Z.bytesDone;if("bytesTotal"in Z&&typeof Z.bytesTotal==="number")W.bytesTotal=Z.bytesTotal;return W}function JG(Z){if(Z==="peek"||Z==="pull"||Z==="open"||Z==="exec"||Z==="push"||Z==="import"||Z==="idle"||Z==="apply")return Z==="apply"?"exec":Z;return}function Q0(Z){if(!Z||typeof Z!=="object")return;if(!("numUploads"in Z)||!("numDownloads"in Z))return;if(typeof Z.numUploads!=="number"||typeof Z.numDownloads!=="number")return;let X={phase:"idle"};if("progress"in Z){let W=RG(Z.progress);if(W===void 0)return;X=W}return{numUploads:Z.numUploads,numDownloads:Z.numDownloads,progress:X}}var dZ="[DIPLOMATIC]";class DX{worker;state;store;local;nextId=1;pending=new Map;readyTimeoutMs;scheduledSync;cachedClientState={hasSeed:!1,hasHost:!1,connected:!1};cachedXferState={numUploads:0,numDownloads:0,progress:$Z};clientState;xferState;constructor(Z,X,W,V,l){this.state=Z,this.store=X,this.readyTimeoutMs=l,this.clientState=new IZ(async()=>this.cachedClientState),this.xferState=new IZ(async()=>this.cachedXferState),this.scheduledSync=new gX(V,async()=>{if(!this.worker)return;try{await this.request({id:this.allocId(),op:"sync"})}catch(K){console.error(`${dZ} worker sync after local write failed`,K)}}),this.local=new bX(W,Z,X,()=>{throw Error(`${dZ} local writer has no transport (use worker for network)`)},TX,!0,void 0,void 0,()=>{this.scheduledSync.schedule()}),this.local.xferState.listen((K)=>{this.cachedXferState={numUploads:K.numUploads,numDownloads:K.numDownloads,progress:this.cachedXferState.progress},this.xferState.emit()})}bindWorker(Z){let X=this.worker;if(X){X.onmessage=null,X.onerror=null,X.onmessageerror=null;try{X.terminate()}catch{}}this.worker=Z,Z.onmessage=(W)=>{this.onMessage(W.data)},Z.onerror=(W)=>{console.error(`${dZ} worker error`,W),this.failPending(Error(`${dZ} worker failed to load`))},Z.onmessageerror=()=>{this.failPending(Error(`${dZ} worker message error`))}}failPending(Z){for(let[,X]of this.pending)X.reject(Z);this.pending.clear()}async flushScheduledSync(){await this.scheduledSync.flush()}static async open(Z,X,W={}){let V=W.clock??new EZ,l=W.syncDebounceMs??WW,K=W.readyTimeoutMs??15000,G=new DX(Z,X,V,l,K);return await G.hydrateStateFromStore(X),G}async hydrateStateFromStore(Z){await this.loadSession(!1);let X=await Z.uploads.count(),W=await Z.downloads.count();this.cachedXferState={numUploads:X,numDownloads:W,progress:$Z}}async loadSession(Z){let X=await this.store.seed.load(),W=await this.store.hosts.list();this.cachedClientState={hasSeed:X!==void 0,hasHost:Array.from(W).length>0,connected:Z}}async pullRemoteXfer(){let Z=await this.request({id:this.allocId(),op:"getXferState"}),X=Q0(Z);if(X!==void 0)this.cachedXferState=X}requireWorker(){if(!this.worker)throw Error(`${dZ} no sync worker; call setSeed first`);return this.worker}async ping(){if(await this.request({id:this.allocId(),op:"ping"})!=="pong")throw Error(`${dZ} worker ping failed`)}terminate(){this.scheduledSync.cancel();let Z=this.worker;if(this.worker=void 0,Z)try{Z.terminate()}catch{}this.failPending(Error(`${dZ} worker terminated`))}onMessage(Z){if(!L0(Z))return;let X=Z;switch(X.kind){case"ready":return;case"initError":{this.failPending(Error(`${dZ} worker init failed: ${X.message}`));return}case"clientState":{if(this.cachedClientState.connected===X.connected)return;this.cachedClientState={...this.cachedClientState,connected:X.connected},this.clientState.emit();return}case"xferState":{this.cachedXferState=X.state,this.xferState.emit();return}case"dirty":{this.state.refresh(X.eids.map(FG));return}case"wiped":{this.state.clear();return}case"reply":{let W=this.pending.get(X.id);if(!W)return;if(this.pending.delete(X.id),X.ok)W.resolve(X.result);else W.reject(new wX(X.status));return}default:return}}allocId(){let Z=this.nextId;return this.nextId+=1,Z}request(Z,X){let W=this.requireWorker();return new Promise((V,l)=>{if(this.pending.set(Z.id,{resolve:V,reject:l}),X&&X.length>0)W.postMessage(Z,X);else W.postMessage(Z)})}async requestStatus(Z,X){try{let W=await this.request(Z,X),V=c0(W);if(V!==void 0)return V;return 0}catch(W){if(W instanceof wX)return W.status;return 12}}serializeHost(Z){return{handle:Z.handle.href,label:Z.label,idx:Z.idx??0}}async setSeed(Z,X){await this.local.setSeed(Z,X),await this.loadSession(!1),this.clientState.emit();let W=this.allocId(),V=this.readyTimeoutMs;await new Promise((l,K)=>{let G=void 0,m=(R)=>{if(G!==void 0)clearTimeout(G);R()};this.pending.set(W,{resolve:(R)=>m(()=>l(R)),reject:(R)=>m(()=>K(R))}),G=setTimeout(()=>{this.pending.delete(W),K(Error(`${dZ} setSeed worker timeout after ${V}ms`))},V);try{let R=Z.spawnSyncWorker({id:W,persist:X?.persist});this.bindWorker(R)}catch(R){if(this.pending.delete(W),G!==void 0)clearTimeout(G);K(R instanceof Error?R:Error(String(R)))}});try{await this.pullRemoteXfer()}catch{}}async link(Z,X=!0){await this.local.link(Z,!1),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),await this.request({id:this.allocId(),op:"link",host:this.serializeHost(Z),connect:X})}async unlink(Z){if(await this.local.unlink(Z),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),!this.worker)return;await this.request({id:this.allocId(),op:"unlink",label:Z})}async hosts(){return this.local.hosts()}async connect(Z=!0,X=!0){if(!this.worker)return;await this.request({id:this.allocId(),op:"connect",listen:Z,sync:X})}async disconnect(){if(!this.worker)return;await this.request({id:this.allocId(),op:"disconnect"})}async insertRaw(Z){return this.local.insertRaw(Z)}async updateRaw(Z,X,W){return this.local.updateRaw(Z,X,W)}async insert(Z){return this.local.insert(Z)}async update(Z){return this.local.update(Z)}async delete(Z){return this.local.delete(Z)}async genEID(Z){return this.local.genEID(Z)}async sync(){if(!this.worker)return 0;return this.requestStatus({id:this.allocId(),op:"sync"})}async rebuild(Z){return this.scheduledSync.cancel(),await this.scheduledSync.flush(),this.requestStatus({id:this.allocId(),op:"rebuild",checkHost:Z?.checkHost})}async listMsgs(Z){return this.local.listMsgs(Z)}async countMsgs(Z){return this.local.countMsgs(Z)}async reconcile(Z,X){try{let W=await this.request({id:this.allocId(),op:"reconcile",hostLabel:Z,pull:X?.pull,push:X?.push,sync:X?.sync});if(!CG(W))return Y(12);return b(W)}catch(W){if(W instanceof wX&&W.status!==0)return Y(W.status);return Y(12)}}async msgcheck(){let Z=await this.request({id:this.allocId(),op:"msgcheck"});if(!(Z instanceof Uint8Array))throw Error(`${dZ} msgcheck: expected Uint8Array`);return Z}async entcheck(){let Z=await this.request({id:this.allocId(),op:"entcheck"});if(!(Z instanceof Uint8Array))throw Error(`${dZ} entcheck: expected Uint8Array`);return Z}async wipe(Z){if(await this.local.wipe(Z),this.worker)await this.request({id:this.allocId(),op:"wipe",msgs:Z?.msgs,ents:Z?.ents,meta:Z?.meta,seed:Z?.seed});await this.hydrateStateFromStore(this.store),this.clientState.emit(),this.xferState.emit()}async import(Z){let X=new Uint8Array(await Z.arrayBuffer());return this.requestStatus({id:this.allocId(),op:"import",bytes:X},[X.buffer])}async export(Z,X){try{let W=await this.request({id:this.allocId(),op:"export"});if(!(W instanceof Uint8Array))return 12;let V=new Blob([W.slice()]);return lW(V,Z),0}catch(W){if(W instanceof wX)return W.status;return 12}}}class wX extends Error{status;constructor(Z){super(`WorkerReplyError: ${z[Z]}`);this.status=Z;this.name="WorkerReplyError"}}function CG(Z){if(!Z||typeof Z!=="object")return!1;let X=Z;return X.msgcheck instanceof Uint8Array&&X.msgcheck.length===32&&typeof X.numBags==="number"&&typeof X.numDupes==="number"}function FG(Z){return Z}var LX="[DIPLOMATIC]";async function HW(Z){let X=Z.clock??new EZ;if(Z.worker===!0&&bG(Z)!==void 0)throw Error(`${LX} worker path requires IndexedDB on both sides; do not pass store (got a custom store)`);if(Z.worker!==!0){console.info(`${LX} sync on main thread `+"(no worker — app did not request a worker)");let l=await p0(Z.store);return dG(X,Z.state,l)}if(typeof Worker>"u")throw Error(`${LX} worker: true but Worker API is unavailable`);let W=await p0(void 0),V=await DX.open(Z.state,W,{readyTimeoutMs:Z.readyTimeoutMs,clock:X,syncDebounceMs:Z.syncDebounceMs});return console.info(`${LX} worker-mode client open (sync Worker starts on setSeed via Enclave)`),{client:V,mode:"worker",dispose:()=>{console.info(`${LX} terminating sync worker`),V.terminate()}}}function bG(Z){if("store"in Z)return Z.store;return}async function dG(Z,X,W){let V=new bX(Z,X,W,fW,TX);return{client:V,mode:"main",dispose:()=>{V.disconnect()}}}async function p0(Z){if(Z!==void 0)return Z;if(typeof indexedDB>"u")throw Error(`${LX} IndexedDB is unavailable; pass store explicitly (e.g. new MemoryStore(crypto))`);return wV(TX)}function kG(Z){let[X,W]=DV();return hW(()=>{async function V(){let K=await Z.clientState.get();W(K)}let l=Z.clientState.listen(V);return V(),()=>{l()}},[Z]),X}function IG(Z){let[X,W]=DV();return hW(()=>{async function V(){let K=await Z.xferState.get();W(K)}let l=Z.xferState.listen(V);return V(),()=>{l()}},[Z]),X}function TG(Z){hW(()=>{async function X(){try{if(!(await Z.clientState.get()).hasSeed)return;await Z.connect(),await Z.sync()}catch(K){console.error("reconnectAndSync failed",K)}}function W(){X()}function V(){if(typeof document<"u"&&document.visibilityState==="visible")X()}function l(){X()}if(globalThis.addEventListener("online",W),typeof document<"u")document.addEventListener("visibilitychange",V);return globalThis.addEventListener("focus",l),globalThis.addEventListener("pageshow",l),()=>{if(globalThis.removeEventListener("online",W),typeof document<"u")document.removeEventListener("visibilitychange",V);globalThis.removeEventListener("focus",l),globalThis.removeEventListener("pageshow",l)}},[Z])}function LG(Z={}){let X=Z.clock??new EZ,{seed:W,host:V,readyTimeoutMs:l}=Z,K=Z.worker===!0,G="store"in Z?Z.store:void 0,[m,R]=DV({stateMgr:sW});return hW(()=>{let J=!1,C;return(async()=>{let F=await WV();if(J)return;let d=ZW(F),k=K?await HW({state:d,clock:X,worker:!0,readyTimeoutMs:l}):await HW({state:d,clock:X,store:G,readyTimeoutMs:l});if(J){k.dispose();return}C=k.dispose;let{client:I,mode:T}=k;if(W)await I.setSeed(W);if(V)await I.link(V);if(J){C();return}R({client:I,entDB:F,stateMgr:d,mode:T,error:void 0})})().catch((F)=>{let d=F instanceof Error?F:Error(String(F));if(console.error("[DIPLOMATIC] useClient init failed",d),!J)R((k)=>({...k,client:void 0,error:d}))}),()=>{J=!0,C?.()}},[X,W,V,K,G,l]),m}import{use as cG,useEffect as y0,useRef as QG,useState as pG}from"react";function S0(Z,X,W){let[V,l]=pG();return y0(()=>{async function K(){let G=await W();l(G)}return K(),Z.on(X,K),()=>{Z.off(X,K)}},[Z,X,W]),V}function yG(Z,X,W){let V=QG(W());return y0(()=>{async function l(){V.current=W()}return Z.on(X,l),()=>{Z.off(X,l)}},[Z,X,W]),cG(V.current)}function z0(Z,X){return`${Z}:${X}`}class AV{queue=new Map;async enq(Z){for(let X of Z){let W=z0(X.host,X.seq);this.queue.set(W,X)}}async deq(Z,X){for(let W of X){let V=z0(Z,W);this.queue.delete(V)}}async list(){let Z=[];for(let X of this.queue.values())Z.push(X);return Z}async count(){return this.queue.size}async wipe(){this.queue.clear()}}function SG(Z,X){if(X.setLastSeq!==void 0)Z.lastSeq=X.setLastSeq;else if(X.lastSeq!==void 0&&X.lastSeq>Z.lastSeq)Z.lastSeq=X.lastSeq}class vV{hosts=new Map;async add(Z){let X=this.hosts.get(Z.label),W=X!==void 0&&X.handle===Z.handle&&(X.idx??0)===(Z.idx??0),V={...Z,lastSeq:W?X.lastSeq:0,clockOffset:W?X.clockOffset:void 0,subscription:W?X.subscription:void 0};this.hosts.set(Z.label,V)}async touch(Z,X){await this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.hosts.get(Z);if(!W)return;SG(W,X),this.hosts.set(Z,{...W})}async get(Z){return this.hosts.get(Z)}async set(Z,X){let W=this.hosts.get(Z);if(!W)return 13;return this.hosts.set(Z,{...W,...X}),0}async del(Z){this.hosts.delete(Z)}async list(){return this.hosts.values()}async wipe(){this.hosts.clear()}}class $V{crypto;messages=new Map;constructor(Z){this.crypto=Z}async add(Z){let X=[];for(let{key:W,data:V}of Z)this.messages.set(g(W),V),X.push(0);return X}async del(Z){for(let X of Z)this.messages.delete(g(X))}async get(Z){let X=this.messages.get(g(Z));if(X)return await jZ(Z,X,this.crypto);return}async has(Z){return this.messages.has(g(Z))}async list(Z){let X=Z?.apld,W=Z?.body!==!1,V=[];for(let[l,K]of this.messages){if(X!==void 0&&FX(K.apld)!==X)continue;let G=e(l);V.push(await jZ(G,K,this.crypto,{body:W}))}return V}async count(Z){if(Z===void 0)return this.messages.size;let X=0;for(let W of this.messages.values())if(FX(W.apld)===Z)X++;return X}async listKeys(){let Z=[];for(let X of this.messages.keys())Z.push(e(X));return Z}async last(Z){let X;for(let[W,V]of this.messages){if(n(Z,V.eid)===!1)continue;let l=e(W);if(X===void 0)X={hash:l,data:V};else if((V.ctr??0)>(X.data.ctr??0)||(V.ctr??0)===(X.data.ctr??0)&&(V.off??0)>(X.data.off??0))X={hash:l,data:V}}if(X)return await jZ(X.hash,X.data,this.crypto);return}async markApplied(Z){for(let X of Z){let W=this.messages.get(g(X));if(!W)continue;oZ(W,BZ)}}async markFailed(Z){for(let{key:X,err:W}of Z){let V=this.messages.get(g(X));if(!V)continue;oZ(V,LZ,W)}}async wipe(){this.messages.clear()}}class oV{#Z;#X;#W;constructor(Z){this.#X=Z}async save(Z,X){if(this.#W!==void 0){if(!await NW(this.#X,Z,this.#W))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)")}else this.#W=await zW(this.#X,Z);return this.#Z=Z,this.#Z}async load(){return this.#Z}async wipe(){this.#Z=void 0,this.#W=void 0}peekPin(){return this.#W===void 0?void 0:MW(this.#W)}}class fV{queue=new Map;async enq(Z,X){let W=this.queue.get(Z)||new Set;this.queue.set(Z,W);for(let V of X)W.add(YZ(V))}async deq(Z,X){let W=this.queue.get(Z);if(W)for(let V of X)W.delete(YZ(V))}async list(Z){let X=this.queue.get(Z);if(!X)return[];let W=[];for(let V of X)W.push(yX(V));return W}async count(){let Z=0;for(let X of this.queue.values())Z+=X.size;return Z}async wipe(){this.queue.clear()}}class N0{seed;hosts=new vV;uploads=new fV;downloads=new AV;messages;constructor(Z){this.seed=new oV(Z),this.messages=new $V(Z)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}class M0{singletonType;latest;latestOff=-1;emitter=new UZ;constructor(Z){this.singletonType=Z}async apply(Z){for(let X of Z){let W=new O(X.eid),[V,l]=W.readStruct(s);if(l!==0)continue;let K=new E;K.writeVarString(this.singletonType);let G=K.result();if(V.id.length===G.length&&V.id.every((m,R)=>m===G[R])){if(this.latest===void 0||X.off>this.latestOff)this.latestOff=X.off,this.latest=X.bod,this.emitter.emit(this.singletonType,null)}}return Z.map(()=>0)}clear=async()=>{return this.latest=void 0,this.latestOff=-1,this.emitter.emit(this.singletonType,null),0};notify=(Z)=>{for(let X of Z)if(X===this.singletonType)this.emitter.emit(this.singletonType,null)};refresh=async(Z)=>{this.notify([this.singletonType])};on=(Z,X)=>{this.emitter.addEventListener(Z,X)};off=(Z,X)=>{this.emitter.removeEventListener(Z,X)}}var qV={capable(){return Y0()},async createCred(Z){return TW(Z)},async write(Z,X,W){return uX(Z,X,W)},async read(Z,X){let[W,V]=await LW(Z,X);if(V!==0||W===void 0)return Y(V);return b(W.blob)}};class x0{#Z;#X;#W;#V;constructor(Z){if(this.#W=Z.rpId,this.#V=Z.rpName,Z.credId!==void 0)this.#X=Z.credId.slice()}get credId(){if(this.#X===void 0)return;return this.#X.slice()}setCredId(Z){this.#X=Z===void 0?void 0:Z.slice()}async save(Z,X){if(X?.persist!==!0)return this.#Z=Z,this.#Z;let[W,V]=await Z.persistToLargeBlob([],{rpId:this.#W,rpName:this.#V,credId:this.#X});if(V!==0||W===void 0)return Promise.reject(Error(`persistToLargeBlob status ${V}`));return this.#X=W,this.#Z=Z,this.#Z}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await ZZ.fromLargeBlob({rpId:this.#W,rpName:this.#V,credId:Z});if(W!==0||X===void 0)return Y(W);return this.#Z=X.enclave,b(X.enclave)}async wipe(){let Z=this.#X;if(Z!==void 0){let X=await ZZ.clearLargeBlob(Z,{rpId:this.#W});if(X!==0)return Promise.reject(Error(`clearLargeBlob status ${X}`))}this.#Z=void 0,this.#X=void 0}}function Vk(){return qV.capable()}export{TG as useSyncOnResume,yG as useStateWatcherSuspense,S0 as useStateWatcher,IG as useClientXferState,kG as useClientState,LG as useClient,VW as shouldEmitItemProgress,oZ as setApld,VV as revFromHead,MX as revFromEntity,tK as prfCapable,wV as openIDBStore,WV as openEntDB,HW as openDiplomaticClient,sW as nullStateManager,LK as nullEntDB,pl as normalizeTags,Vk as largeBlobCapable,TK as isTombstone,KV as isTerminalApplyFailure,pK as isPendingApply,v as isLiveEnt,QK as isApldState,$Z as idleProgress,yX as htob,fW as hostHTTPTransport,ZK as genSingletonEID,ZW as entStateManager,Il as encodeEntRev,s as eidCodec,IW as defaultWebAuthnRpId,CX as defaultPeekProgressEvery,TX as crypto,kl as cmpBytes,KX as checksumSet,zX as checksumEntRevs,YZ as btoh,XK as btob64url,g as btob64,jW as b64urltob,e as b64tob,yZ as asSealedMasterKey,UV as asDHKEResp,hV as asDHKEReq,FX as apldFromStored,DX as WorkerClient,UZ as TypedEventEmitter,bX as SyncClient,z as Status,NX as StateManager,M0 as SingletonStateManager,aW as SEALED_MASTER_KEY_LEN,SW as PrfSeedStore,x0 as PasskeySeedStore,EX as PairRequest,N0 as MemoryStore,kZ as MASTER_SEED_LEN,uV as IDBStore,gW as IDBSeedStore,oW as HTTPTransport,XV as EntIDB,eX as EntDBMemory,E as Encoder,ZZ as Enclave,O as Decoder,cW as DEFAULT_PRF_SALT,EZ as Clock,xX as CachedEntDB,SZ as APLD_PENDING,LZ as APLD_ERROR,BZ as APLD_APPLIED};
1
+ function nV(Z){let X=Z.length,W=0,V=0;while(V<X){let l=Z.charCodeAt(V++);if((l&4294967168)===0){W++;continue}else if((l&4294965248)===0)W+=2;else{if(l>=55296&&l<=56319){if(V<X){let K=Z.charCodeAt(V);if((K&64512)===56320)++V,l=((l&1023)<<10)+(K&1023)+65536}}if((l&4294901760)===0)W+=3;else W+=4}}return W}function x0(Z,X,W){let V=Z.length,l=W,K=0;while(K<V){let G=Z.charCodeAt(K++);if((G&4294967168)===0){X[l++]=G;continue}else if((G&4294965248)===0)X[l++]=G>>6&31|192;else{if(G>=55296&&G<=56319){if(K<V){let m=Z.charCodeAt(K);if((m&64512)===56320)++K,G=((G&1023)<<10)+(m&1023)+65536}}if((G&4294901760)===0)X[l++]=G>>12&15|224,X[l++]=G>>6&63|128;else X[l++]=G>>18&7|240,X[l++]=G>>12&63|128,X[l++]=G>>6&63|128}X[l++]=G&63|128}}var H0=new TextEncoder,h0=50;function U0(Z,X,W){H0.encodeInto(Z,X.subarray(W))}function _V(Z,X,W){if(Z.length>h0)U0(Z,X,W);else x0(Z,X,W)}var P0=4096;function UW(Z,X,W){let V=X,l=V+W,K=[],G="";while(V<l){let m=Z[V++];if((m&128)===0)K.push(m);else if((m&224)===192){let R=Z[V++]&63;K.push((m&31)<<6|R)}else if((m&240)===224){let R=Z[V++]&63,J=Z[V++]&63;K.push((m&31)<<12|R<<6|J)}else if((m&248)===240){let R=Z[V++]&63,J=Z[V++]&63,C=Z[V++]&63,F=(m&7)<<18|R<<12|J<<6|C;if(F>65535)F-=65536,K.push(F>>>10&1023|55296),F=56320|F&1023;K.push(F)}else K.push(m);if(K.length>=P0)G+=String.fromCharCode(...K),K.length=0}if(K.length>0)G+=String.fromCharCode(...K);return G}var O0=new TextDecoder,i0=200;function j0(Z,X,W){let V=Z.subarray(X,X+W);return O0.decode(V)}function aV(Z,X,W){if(W>i0)return j0(Z,X,W);else return UW(Z,X,W)}class XX{type;data;constructor(Z,X){this.type=Z,this.data=X}}class WZ extends Error{constructor(Z){super(Z);let X=Object.create(WZ.prototype);Object.setPrototypeOf(this,X),Object.defineProperty(this,"name",{configurable:!0,enumerable:!1,value:WZ.name})}}var WX=4294967295;function sV(Z,X,W){let V=W/4294967296,l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function AX(Z,X,W){let V=Math.floor(W/4294967296),l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function vX(Z,X){let W=Z.getInt32(X),V=Z.getUint32(X+4);return W*4294967296+V}function rV(Z,X){let W=Z.getUint32(X),V=Z.getUint32(X+4);return W*4294967296+V}var B0=-1,E0=4294967295,u0=17179869183;function w0({sec:Z,nsec:X}){if(Z>=0&&X>=0&&Z<=u0)if(X===0&&Z<=E0){let W=new Uint8Array(4);return new DataView(W.buffer).setUint32(0,Z),W}else{let W=Z/4294967296,V=Z&4294967295,l=new Uint8Array(8),K=new DataView(l.buffer);return K.setUint32(0,X<<2|W&3),K.setUint32(4,V),l}else{let W=new Uint8Array(12),V=new DataView(W.buffer);return V.setUint32(0,X),AX(V,4,Z),W}}function D0(Z){let X=Z.getTime(),W=Math.floor(X/1000),V=(X-W*1000)*1e6,l=Math.floor(V/1e9);return{sec:W+l,nsec:V-l*1e9}}function A0(Z){if(Z instanceof Date){let X=D0(Z);return w0(X)}else return null}function v0(Z){let X=new DataView(Z.buffer,Z.byteOffset,Z.byteLength);switch(Z.byteLength){case 4:{let W=X.getUint32(0),V=0;return{sec:W,nsec:0}}case 8:{let W=X.getUint32(0),V=X.getUint32(4),l=(W&3)*4294967296+V,K=W>>>2;return{sec:l,nsec:K}}case 12:{let W=vX(X,4),V=X.getUint32(0);return{sec:W,nsec:V}}default:throw new WZ(`Unrecognized data size for timestamp (expected 4, 8, or 12): ${Z.length}`)}}function $0(Z){let X=v0(Z);return new Date(X.sec*1000+X.nsec/1e6)}var tV={type:B0,encode:A0,decode:$0};class VX{static defaultCodec=new VX;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(tV)}register({type:Z,encode:X,decode:W}){if(Z>=0)this.encoders[Z]=X,this.decoders[Z]=W;else{let V=-1-Z;this.builtInEncoders[V]=X,this.builtInDecoders[V]=W}}tryToEncode(Z,X){for(let W=0;W<this.builtInEncoders.length;W++){let V=this.builtInEncoders[W];if(V!=null){let l=V(Z,X);if(l!=null){let K=-1-W;return new XX(K,l)}}}for(let W=0;W<this.encoders.length;W++){let V=this.encoders[W];if(V!=null){let l=V(Z,X);if(l!=null)return new XX(W,l)}}if(Z instanceof XX)return Z;return null}decode(Z,X,W){let V=X<0?this.builtInDecoders[-1-X]:this.decoders[X];if(V)return V(Z,X,W);else return new XX(X,Z)}}function q0(Z){return Z instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&Z instanceof SharedArrayBuffer}function cX(Z){if(Z instanceof Uint8Array)return Z;else if(ArrayBuffer.isView(Z))return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength);else if(q0(Z))return new Uint8Array(Z);else return Uint8Array.from(Z)}var f0=100,o0=2048;class $X{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??VX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.maxDepth=Z?.maxDepth??f0,this.initialBufferSize=Z?.initialBufferSize??o0,this.sortKeys=Z?.sortKeys??!1,this.forceFloat32=Z?.forceFloat32??!1,this.ignoreUndefined=Z?.ignoreUndefined??!1,this.forceIntegerToFloat=Z?.forceIntegerToFloat??!1,this.pos=0,this.view=new DataView(new ArrayBuffer(this.initialBufferSize)),this.bytes=new Uint8Array(this.view.buffer)}clone(){return new $X({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,maxDepth:this.maxDepth,initialBufferSize:this.initialBufferSize,sortKeys:this.sortKeys,forceFloat32:this.forceFloat32,ignoreUndefined:this.ignoreUndefined,forceIntegerToFloat:this.forceIntegerToFloat})}reinitializeState(){this.pos=0}encodeSharedRef(Z){if(this.entered)return this.clone().encodeSharedRef(Z);try{return this.entered=!0,this.reinitializeState(),this.doEncode(Z,1),this.bytes.subarray(0,this.pos)}finally{this.entered=!1}}encode(Z){if(this.entered)return this.clone().encode(Z);try{return this.entered=!0,this.reinitializeState(),this.doEncode(Z,1),this.bytes.slice(0,this.pos)}finally{this.entered=!1}}doEncode(Z,X){if(X>this.maxDepth)throw Error(`Too deep objects in depth ${X}`);if(Z==null)this.encodeNil();else if(typeof Z==="boolean")this.encodeBoolean(Z);else if(typeof Z==="number")if(!this.forceIntegerToFloat)this.encodeNumber(Z);else this.encodeNumberAsFloat(Z);else if(typeof Z==="string")this.encodeString(Z);else if(this.useBigInt64&&typeof Z==="bigint")this.encodeBigInt64(Z);else this.encodeObject(Z,X)}ensureBufferSizeToWrite(Z){let X=this.pos+Z;if(this.view.byteLength<X)this.resizeBuffer(X*2)}resizeBuffer(Z){let X=new ArrayBuffer(Z),W=new Uint8Array(X),V=new DataView(X);W.set(this.bytes),this.view=V,this.bytes=W}encodeNil(){this.writeU8(192)}encodeBoolean(Z){if(Z===!1)this.writeU8(194);else this.writeU8(195)}encodeNumber(Z){if(!this.forceIntegerToFloat&&Number.isSafeInteger(Z))if(Z>=0)if(Z<128)this.writeU8(Z);else if(Z<256)this.writeU8(204),this.writeU8(Z);else if(Z<65536)this.writeU8(205),this.writeU16(Z);else if(Z<4294967296)this.writeU8(206),this.writeU32(Z);else if(!this.useBigInt64)this.writeU8(207),this.writeU64(Z);else this.encodeNumberAsFloat(Z);else if(Z>=-32)this.writeU8(224|Z+32);else if(Z>=-128)this.writeU8(208),this.writeI8(Z);else if(Z>=-32768)this.writeU8(209),this.writeI16(Z);else if(Z>=-2147483648)this.writeU8(210),this.writeI32(Z);else if(!this.useBigInt64)this.writeU8(211),this.writeI64(Z);else this.encodeNumberAsFloat(Z);else this.encodeNumberAsFloat(Z)}encodeNumberAsFloat(Z){if(this.forceFloat32)this.writeU8(202),this.writeF32(Z);else this.writeU8(203),this.writeF64(Z)}encodeBigInt64(Z){if(Z>=BigInt(0))this.writeU8(207),this.writeBigUint64(Z);else this.writeU8(211),this.writeBigInt64(Z)}writeStringHeader(Z){if(Z<32)this.writeU8(160+Z);else if(Z<256)this.writeU8(217),this.writeU8(Z);else if(Z<65536)this.writeU8(218),this.writeU16(Z);else if(Z<4294967296)this.writeU8(219),this.writeU32(Z);else throw Error(`Too long string: ${Z} bytes in UTF-8`)}encodeString(Z){let W=nV(Z);this.ensureBufferSizeToWrite(5+W),this.writeStringHeader(W),_V(Z,this.bytes,this.pos),this.pos+=W}encodeObject(Z,X){let W=this.extensionCodec.tryToEncode(Z,this.context);if(W!=null)this.encodeExtension(W);else if(Array.isArray(Z))this.encodeArray(Z,X);else if(ArrayBuffer.isView(Z))this.encodeBinary(Z);else if(typeof Z==="object")this.encodeMap(Z,X);else throw Error(`Unrecognized object: ${Object.prototype.toString.apply(Z)}`)}encodeBinary(Z){let X=Z.byteLength;if(X<256)this.writeU8(196),this.writeU8(X);else if(X<65536)this.writeU8(197),this.writeU16(X);else if(X<4294967296)this.writeU8(198),this.writeU32(X);else throw Error(`Too large binary: ${X}`);let W=cX(Z);this.writeU8a(W)}encodeArray(Z,X){let W=Z.length;if(W<16)this.writeU8(144+W);else if(W<65536)this.writeU8(220),this.writeU16(W);else if(W<4294967296)this.writeU8(221),this.writeU32(W);else throw Error(`Too large array: ${W}`);for(let V of Z)this.doEncode(V,X+1)}countWithoutUndefined(Z,X){let W=0;for(let V of X)if(Z[V]!==void 0)W++;return W}encodeMap(Z,X){let W=Object.keys(Z);if(this.sortKeys)W.sort();let V=this.ignoreUndefined?this.countWithoutUndefined(Z,W):W.length;if(V<16)this.writeU8(128+V);else if(V<65536)this.writeU8(222),this.writeU16(V);else if(V<4294967296)this.writeU8(223),this.writeU32(V);else throw Error(`Too large map object: ${V}`);for(let l of W){let K=Z[l];if(!(this.ignoreUndefined&&K===void 0))this.encodeString(l),this.doEncode(K,X+1)}}encodeExtension(Z){if(typeof Z.data==="function"){let W=Z.data(this.pos+6),V=W.length;if(V>=4294967296)throw Error(`Too large extension object: ${V}`);this.writeU8(201),this.writeU32(V),this.writeI8(Z.type),this.writeU8a(W);return}let X=Z.data.length;if(X===1)this.writeU8(212);else if(X===2)this.writeU8(213);else if(X===4)this.writeU8(214);else if(X===8)this.writeU8(215);else if(X===16)this.writeU8(216);else if(X<256)this.writeU8(199),this.writeU8(X);else if(X<65536)this.writeU8(200),this.writeU16(X);else if(X<4294967296)this.writeU8(201),this.writeU32(X);else throw Error(`Too large extension object: ${X}`);this.writeI8(Z.type),this.writeU8a(Z.data)}writeU8(Z){this.ensureBufferSizeToWrite(1),this.view.setUint8(this.pos,Z),this.pos++}writeU8a(Z){let X=Z.length;this.ensureBufferSizeToWrite(X),this.bytes.set(Z,this.pos),this.pos+=X}writeI8(Z){this.ensureBufferSizeToWrite(1),this.view.setInt8(this.pos,Z),this.pos++}writeU16(Z){this.ensureBufferSizeToWrite(2),this.view.setUint16(this.pos,Z),this.pos+=2}writeI16(Z){this.ensureBufferSizeToWrite(2),this.view.setInt16(this.pos,Z),this.pos+=2}writeU32(Z){this.ensureBufferSizeToWrite(4),this.view.setUint32(this.pos,Z),this.pos+=4}writeI32(Z){this.ensureBufferSizeToWrite(4),this.view.setInt32(this.pos,Z),this.pos+=4}writeF32(Z){this.ensureBufferSizeToWrite(4),this.view.setFloat32(this.pos,Z),this.pos+=4}writeF64(Z){this.ensureBufferSizeToWrite(8),this.view.setFloat64(this.pos,Z),this.pos+=8}writeU64(Z){this.ensureBufferSizeToWrite(8),sV(this.view,this.pos,Z),this.pos+=8}writeI64(Z){this.ensureBufferSizeToWrite(8),AX(this.view,this.pos,Z),this.pos+=8}writeBigUint64(Z){this.ensureBufferSizeToWrite(8),this.view.setBigUint64(this.pos,Z),this.pos+=8}writeBigInt64(Z){this.ensureBufferSizeToWrite(8),this.view.setBigInt64(this.pos,Z),this.pos+=8}}function vZ(Z,X){return new $X(X).encodeSharedRef(Z)}function qX(Z){return`${Z<0?"-":""}0x${Math.abs(Z).toString(16).padStart(2,"0")}`}var n0=16,_0=16;class PW{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(Z=n0,X=_0){this.maxKeyLength=Z,this.maxLengthPerKey=X,this.caches=[];for(let W=0;W<this.maxKeyLength;W++)this.caches.push([])}canBeCached(Z){return Z>0&&Z<=this.maxKeyLength}find(Z,X,W){let V=this.caches[W-1];Z:for(let l of V){let K=l.bytes;for(let G=0;G<W;G++)if(K[G]!==Z[X+G])continue Z;return l.str}return null}store(Z,X){let W=this.caches[Z.length-1],V={bytes:Z,str:X};if(W.length>=this.maxLengthPerKey)W[Math.random()*W.length|0]=V;else W.push(V)}decode(Z,X,W){let V=this.find(Z,X,W);if(V!=null)return this.hit++,V;this.miss++;let l=UW(Z,X,W),K=Uint8Array.prototype.slice.call(Z,X,X+W);return this.store(K,l),l}}var OW="array",pX="map_key",Zl="map_value",a0=(Z)=>{if(typeof Z==="string"||typeof Z==="number")return Z;throw new WZ("The type of key must be string or number but "+typeof Z)};class Xl{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(Z){let X=this.getUninitializedStateFromPool();X.type=OW,X.position=0,X.size=Z,X.array=Array(Z)}pushMapState(Z){let X=this.getUninitializedStateFromPool();X.type=pX,X.readCount=0,X.size=Z,X.map={}}getUninitializedStateFromPool(){if(this.stackHeadPosition++,this.stackHeadPosition===this.stack.length){let Z={type:void 0,size:0,array:void 0,position:0,readCount:0,map:void 0,key:null};this.stack.push(Z)}return this.stack[this.stackHeadPosition]}release(Z){if(this.stack[this.stackHeadPosition]!==Z)throw Error("Invalid stack state. Released state is not on top of the stack.");if(Z.type===OW){let W=Z;W.size=0,W.array=void 0,W.position=0,W.type=void 0}if(Z.type===pX||Z.type===Zl){let W=Z;W.size=0,W.map=void 0,W.readCount=0,W.type=void 0}this.stackHeadPosition--}reset(){this.stack.length=0,this.stackHeadPosition=-1}}var QX=-1,iW=new DataView(new ArrayBuffer(0)),s0=new Uint8Array(iW.buffer);try{iW.getInt8(0)}catch(Z){if(!(Z instanceof RangeError))throw Error("This module is not supported in the current JavaScript engine because DataView does not throw RangeError on out-of-bounds access")}var eV=RangeError("Insufficient data"),r0=new PW;class fX{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=iW;bytes=s0;headByte=QX;stack=new Xl;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??VX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.rawStrings=Z?.rawStrings??!1,this.maxStrLength=Z?.maxStrLength??WX,this.maxBinLength=Z?.maxBinLength??WX,this.maxArrayLength=Z?.maxArrayLength??WX,this.maxMapLength=Z?.maxMapLength??WX,this.maxExtLength=Z?.maxExtLength??WX,this.keyDecoder=Z?.keyDecoder!==void 0?Z.keyDecoder:r0,this.mapKeyConverter=Z?.mapKeyConverter??a0}clone(){return new fX({extensionCodec:this.extensionCodec,context:this.context,useBigInt64:this.useBigInt64,rawStrings:this.rawStrings,maxStrLength:this.maxStrLength,maxBinLength:this.maxBinLength,maxArrayLength:this.maxArrayLength,maxMapLength:this.maxMapLength,maxExtLength:this.maxExtLength,keyDecoder:this.keyDecoder})}reinitializeState(){this.totalPos=0,this.headByte=QX,this.stack.reset()}setBuffer(Z){let X=cX(Z);this.bytes=X,this.view=new DataView(X.buffer,X.byteOffset,X.byteLength),this.pos=0}appendBuffer(Z){if(this.headByte===QX&&!this.hasRemaining(1))this.setBuffer(Z);else{let X=this.bytes.subarray(this.pos),W=cX(Z),V=new Uint8Array(X.length+W.length);V.set(X),V.set(W,X.length),this.setBuffer(V)}}hasRemaining(Z){return this.view.byteLength-this.pos>=Z}createExtraByteError(Z){let{view:X,pos:W}=this;return RangeError(`Extra ${X.byteLength-W} of ${X.byteLength} byte(s) found at buffer[${Z}]`)}decode(Z){if(this.entered)return this.clone().decode(Z);try{this.entered=!0,this.reinitializeState(),this.setBuffer(Z);let X=this.doDecodeSync();if(this.hasRemaining(1))throw this.createExtraByteError(this.pos);return X}finally{this.entered=!1}}*decodeMulti(Z){if(this.entered){yield*this.clone().decodeMulti(Z);return}try{this.entered=!0,this.reinitializeState(),this.setBuffer(Z);while(this.hasRemaining(1))yield this.doDecodeSync()}finally{this.entered=!1}}async decodeAsync(Z){if(this.entered)return this.clone().decodeAsync(Z);try{this.entered=!0;let X=!1,W;for await(let G of Z){if(X)throw this.entered=!1,this.createExtraByteError(this.totalPos);this.appendBuffer(G);try{W=this.doDecodeSync(),X=!0}catch(m){if(!(m instanceof RangeError))throw m}this.totalPos+=this.pos}if(X){if(this.hasRemaining(1))throw this.createExtraByteError(this.totalPos);return W}let{headByte:V,pos:l,totalPos:K}=this;throw RangeError(`Insufficient data in parsing ${qX(V)} at ${K} (${l} in the current buffer)`)}finally{this.entered=!1}}decodeArrayStream(Z){return this.decodeMultiAsync(Z,!0)}decodeStream(Z){return this.decodeMultiAsync(Z,!1)}async*decodeMultiAsync(Z,X){if(this.entered){yield*this.clone().decodeMultiAsync(Z,X);return}try{this.entered=!0;let W=X,V=-1;for await(let l of Z){if(X&&V===0)throw this.createExtraByteError(this.totalPos);if(this.appendBuffer(l),W)V=this.readArraySize(),W=!1,this.complete();try{while(!0)if(yield this.doDecodeSync(),--V===0)break}catch(K){if(!(K instanceof RangeError))throw K}this.totalPos+=this.pos}}finally{this.entered=!1}}doDecodeSync(){Z:while(!0){let Z=this.readHeadByte(),X;if(Z>=224)X=Z-256;else if(Z<192)if(Z<128)X=Z;else if(Z<144){let V=Z-128;if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z<160){let V=Z-144;if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else{let V=Z-160;X=this.decodeString(V,0)}else if(Z===192)X=null;else if(Z===194)X=!1;else if(Z===195)X=!0;else if(Z===202)X=this.readF32();else if(Z===203)X=this.readF64();else if(Z===204)X=this.readU8();else if(Z===205)X=this.readU16();else if(Z===206)X=this.readU32();else if(Z===207)if(this.useBigInt64)X=this.readU64AsBigInt();else X=this.readU64();else if(Z===208)X=this.readI8();else if(Z===209)X=this.readI16();else if(Z===210)X=this.readI32();else if(Z===211)if(this.useBigInt64)X=this.readI64AsBigInt();else X=this.readI64();else if(Z===217){let V=this.lookU8();X=this.decodeString(V,1)}else if(Z===218){let V=this.lookU16();X=this.decodeString(V,2)}else if(Z===219){let V=this.lookU32();X=this.decodeString(V,4)}else if(Z===220){let V=this.readU16();if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else if(Z===221){let V=this.readU32();if(V!==0){this.pushArrayState(V),this.complete();continue Z}else X=[]}else if(Z===222){let V=this.readU16();if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z===223){let V=this.readU32();if(V!==0){this.pushMapState(V),this.complete();continue Z}else X={}}else if(Z===196){let V=this.lookU8();X=this.decodeBinary(V,1)}else if(Z===197){let V=this.lookU16();X=this.decodeBinary(V,2)}else if(Z===198){let V=this.lookU32();X=this.decodeBinary(V,4)}else if(Z===212)X=this.decodeExtension(1,0);else if(Z===213)X=this.decodeExtension(2,0);else if(Z===214)X=this.decodeExtension(4,0);else if(Z===215)X=this.decodeExtension(8,0);else if(Z===216)X=this.decodeExtension(16,0);else if(Z===199){let V=this.lookU8();X=this.decodeExtension(V,1)}else if(Z===200){let V=this.lookU16();X=this.decodeExtension(V,2)}else if(Z===201){let V=this.lookU32();X=this.decodeExtension(V,4)}else throw new WZ(`Unrecognized type byte: ${qX(Z)}`);this.complete();let W=this.stack;while(W.length>0){let V=W.top();if(V.type===OW)if(V.array[V.position]=X,V.position++,V.position===V.size)X=V.array,W.release(V);else continue Z;else if(V.type===pX){if(X==="__proto__")throw new WZ("The key __proto__ is not allowed");V.key=this.mapKeyConverter(X),V.type=Zl;continue Z}else if(V.map[V.key]=X,V.readCount++,V.readCount===V.size)X=V.map,W.release(V);else{V.key=null,V.type=pX;continue Z}}return X}}readHeadByte(){if(this.headByte===QX)this.headByte=this.readU8();return this.headByte}complete(){this.headByte=QX}readArraySize(){let Z=this.readHeadByte();switch(Z){case 220:return this.readU16();case 221:return this.readU32();default:if(Z<160)return Z-144;else throw new WZ(`Unrecognized array type byte: ${qX(Z)}`)}}pushMapState(Z){if(Z>this.maxMapLength)throw new WZ(`Max length exceeded: map length (${Z}) > maxMapLengthLength (${this.maxMapLength})`);this.stack.pushMapState(Z)}pushArrayState(Z){if(Z>this.maxArrayLength)throw new WZ(`Max length exceeded: array length (${Z}) > maxArrayLength (${this.maxArrayLength})`);this.stack.pushArrayState(Z)}decodeString(Z,X){if(!this.rawStrings||this.stateIsMapKey())return this.decodeUtf8String(Z,X);return this.decodeBinary(Z,X)}decodeUtf8String(Z,X){if(Z>this.maxStrLength)throw new WZ(`Max length exceeded: UTF-8 byte length (${Z}) > maxStrLength (${this.maxStrLength})`);if(this.bytes.byteLength<this.pos+X+Z)throw eV;let W=this.pos+X,V;if(this.stateIsMapKey()&&this.keyDecoder?.canBeCached(Z))V=this.keyDecoder.decode(this.bytes,W,Z);else V=aV(this.bytes,W,Z);return this.pos+=X+Z,V}stateIsMapKey(){if(this.stack.length>0)return this.stack.top().type===pX;return!1}decodeBinary(Z,X){if(Z>this.maxBinLength)throw new WZ(`Max length exceeded: bin length (${Z}) > maxBinLength (${this.maxBinLength})`);if(!this.hasRemaining(Z+X))throw eV;let W=this.pos+X,V=this.bytes.subarray(W,W+Z);return this.pos+=X+Z,V}decodeExtension(Z,X){if(Z>this.maxExtLength)throw new WZ(`Max length exceeded: ext length (${Z}) > maxExtLength (${this.maxExtLength})`);let W=this.view.getInt8(this.pos+X),V=this.decodeBinary(Z,X+1);return this.extensionCodec.decode(V,W,this.context)}lookU8(){return this.view.getUint8(this.pos)}lookU16(){return this.view.getUint16(this.pos)}lookU32(){return this.view.getUint32(this.pos)}readU8(){let Z=this.view.getUint8(this.pos);return this.pos++,Z}readI8(){let Z=this.view.getInt8(this.pos);return this.pos++,Z}readU16(){let Z=this.view.getUint16(this.pos);return this.pos+=2,Z}readI16(){let Z=this.view.getInt16(this.pos);return this.pos+=2,Z}readU32(){let Z=this.view.getUint32(this.pos);return this.pos+=4,Z}readI32(){let Z=this.view.getInt32(this.pos);return this.pos+=4,Z}readU64(){let Z=rV(this.view,this.pos);return this.pos+=8,Z}readI64(){let Z=vX(this.view,this.pos);return this.pos+=8,Z}readU64AsBigInt(){let Z=this.view.getBigUint64(this.pos);return this.pos+=8,Z}readI64AsBigInt(){let Z=this.view.getBigInt64(this.pos);return this.pos+=8,Z}readF32(){let Z=this.view.getFloat32(this.pos);return this.pos+=4,Z}readF64(){let Z=this.view.getFloat64(this.pos);return this.pos+=8,Z}}function jW(Z,X){return new fX(X).decode(Z)}class UZ{listeners=new Map;addEventListener(Z,X){let W=this.listeners.get(Z);if(!W)W=new Set,this.listeners.set(Z,W);return W.add(X),()=>{this.removeEventListener(Z,X)}}removeEventListener(Z,X){let W=this.listeners.get(Z);if(W){if(W.delete(X),W.size===0)this.listeners.delete(Z)}}emit(Z,X){let W=this.listeners.get(Z);if(W){let V=Array.from(W);for(let l of V)l(X)}}emitAll(Z){let X=Array.from(this.listeners.keys());for(let W of X)this.emit(W,Z)}}class TZ{getter;static eventName="update";emitter;constructor(Z){this.getter=Z;this.emitter=new UZ}get=()=>this.getter();async emit(){let Z=await this.getter();queueMicrotask(()=>this.emitter.emit(TZ.eventName,Z))}listen(Z){return this.emitter.addEventListener(TZ.eventName,Z),()=>{this.emitter.removeEventListener(TZ.eventName,Z)}}}var PZ=64;var Wl=32,OZ=8;var oX=32;var Vl=30000,ll=512,z;((y)=>{y[y.Success=0]="Success";y[y.InvalidSignature=3]="InvalidSignature";y[y.ClockOutOfSync=4]="ClockOutOfSync";y[y.UserNotRegistered=5]="UserNotRegistered";y[y.ServerMisconfigured=6]="ServerMisconfigured";y[y.MissingBody=7]="MissingBody";y[y.ExtraBodyContent=8]="ExtraBodyContent";y[y.MissingParam=9]="MissingParam";y[y.InvalidParam=10]="InvalidParam";y[y.InvalidRequest=11]="InvalidRequest";y[y.InternalError=12]="InternalError";y[y.NotFound=13]="NotFound";y[y.InvalidMessage=14]="InvalidMessage";y[y.NoChange=15]="NoChange";y[y.DatabaseClosed=16]="DatabaseClosed";y[y.StorageError=17]="StorageError";y[y.DatabaseError=18]="DatabaseError";y[y.HashMismatch=19]="HashMismatch";y[y.DecryptionError=20]="DecryptionError";y[y.NotImplemented=21]="NotImplemented";y[y.MissingSeed=22]="MissingSeed";y[y.OutOfBounds=23]="OutOfBounds";y[y.HostError=24]="HostError";y[y.CommunicationError=25]="CommunicationError";y[y.VarLimitExceeded=26]="VarLimitExceeded";y[y.InvalidResponse=27]="InvalidResponse";y[y.ConnectionClosed=28]="ConnectionClosed";y[y.CryptoError=29]="CryptoError"})(z||={});function b(Z){return[Z,0]}function Y(Z){return[void 0,Z]}function t0(Z){if(Z<0)console.info("N",Z),console.trace();if(typeof Z!=="bigint")Z=BigInt(Z);if(Z<0n)return Y(10);let X=[];while(Z>0n){let W=Number(Z&0x7fn);if(Z>>=7n,Z>0n)X.push(W|128);else X.push(W)}if(X.length===0)return b(new Uint8Array([0]));if(X.length>8)return Y(26);return b(new Uint8Array(X))}function e0(Z,X=0){let W=0n,V=0,l=X;while(!0){if(l>=Z.length)return Y(14);let K=Z[l++];if(K===void 0)return Y(14);if(W|=BigInt(K&127)<<BigInt(V),(K&128)===0){if(l-X>8)return Y(26);return b({value:W>0x1fffffffffffffn?W:Number(W),bytesRead:l-X})}if(V+=7,V>=56)return Y(26)}}class O{data;pos=0;constructor(Z){this.data=Z}static async fromResponse(Z){let X=await Z.arrayBuffer(),W=new Uint8Array(X);return new O(W)}readBigInt(){if(this.pos+8>this.data.length)return Y(7);let Z=new DataView(this.data.buffer,this.data.byteOffset+this.pos).getBigUint64(0,!1);return this.pos+=8,b(Z)}readDate(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return b(new Date(Z))}readVarInt(){let[Z,X]=e0(this.data,this.pos);if(X!==0)return Y(X);this.pos+=Z.bytesRead;let W=Z.value;return b(typeof W==="bigint"?Number(W):W)}readVarString(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);let l=new TextDecoder().decode(W);return b(l)}readBytes(Z){if(Z<0)return Y(10);if(this.pos+Z>this.data.length)return Y(23);let X=this.data.slice(this.pos,this.pos+Z);return this.pos+=Z,b(X)}readVarBytes(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return this.readBytes(Z)}readStruct(Z){return Z.decode(this)}readStructs(Z){let X=[];while(!this.done()){let[W,V]=this.readStruct(Z);if(V!==0)return Y(V);X.push(W)}return b(X)}readBytesSeq(Z){let X=[];while(!this.done()){let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);X.push(W)}return b(X)}done(){return this.pos>=this.data.length}consumed(){return this.pos}}class j{parts=[];writeBigInt(Z){let X=new Uint8Array(8);new DataView(X.buffer).setBigUint64(0,Z,!1),this.parts.push(X)}writeDate(Z){let X=Z.getTime();return this.writeVarInt(X)}writeVarInt(Z){let[X,W]=t0(Z);if(W!==0)return W;return this.parts.push(X),0}writeVarString(Z){let X=new TextEncoder().encode(Z),W=this.writeVarInt(X.length);if(W!==0)return W;return this.writeBytes(X),0}prependBytes(Z){this.parts.unshift(Z.slice())}writeBytes(Z){this.parts.push(Z.slice())}writeVarBytes(Z){let X=this.writeVarInt(Z.length);if(X!==0)return X;return this.writeBytes(Z),0}writeStruct(Z,X){return Z.encode(this,X)}writeStructs(Z,X){for(let W of X){let V=this.writeStruct(Z,W);if(V!==0)return V}return 0}writeBytesSeq(Z){for(let X of Z)this.writeBytes(X)}result(){let Z=this.parts.reduce((V,l)=>V+l.length,0),X=new Uint8Array(Z),W=0;for(let V of this.parts)X.set(V,W),W+=V.length;return X}wipe(){for(let Z of this.parts)Z.fill(0);this.parts.length=0}*scan(){for(let Z of this.parts)yield Z}}async function BW(Z,X){let W=new j,V=W.writeDate(X);if(V!==0)return Y(V);let l=W.result(),K=await Z.sign(l);return b({pubKey:Z.publicKey,sig:K,timestamp:X})}async function iZ(Z,X,W){let V=W.now().getTime(),l=Z.timestamp.getTime();if(Math.abs(V-l)>Vl)return 4;let G=new j;G.writeDate(Z.timestamp);let m=G.result();if(!await X.checkSigEd25519(Z.sig,m,Z.pubKey))return 3;return 0}var s={encode(Z,X){let W=Z.writeVarBytes(X.id);if(W!==0)return W;let V=Z.writeDate(X.ts);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let[V,l]=Z.readDate();if(l!==0)return Y(l);return b({id:X,ts:V})}};function lX(Z){let X=new j,W=X.writeStruct(s,Z);if(W!==0)return Y(W);let V=X.result();return b(V)}async function ZK(Z){return lX({id:Z,ts:new Date(0)})}var JZ={encode(Z,X){let W=Z.writeVarBytes(X.eid);if(W!==0)return W;let V=Z.writeVarInt(X.off);if(V!==0)return V;let l=Z.writeVarInt(X.ctr);if(l!==0)return l;let K=Z.writeVarInt(X.len);if(K!==0)return K;if(X.hsh)Z.writeBytes(X.hsh);return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let V=new O(X),[,l]=s.decode(V);if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let[m,R]=Z.readVarInt();if(R!==0)return Y(R);let[J,C]=Z.readVarInt();if(C!==0)return Y(C);let F;if(J>0){let[d,k]=Z.readBytes(oX);if(k!==0)return Y(k);F=d}return b({eid:X,off:K,ctr:m,len:J,hsh:F})}};function YZ(Z){return Array.from(Z).map((W)=>W.toString(16).padStart(2,"0")).join("")}function yX(Z){if(Z.length%2!==0)throw Error("Invalid hex string");let X=new Uint8Array(Z.length/2);for(let W=0;W<Z.length;W+=2)X[W/2]=Number.parseInt(Z.substr(W,2),16);return X}function n(Z,X){if(Z===X)return!0;if(Z.byteLength!==X.byteLength)return!1;return Z.every((W,V)=>W===X[V])}var x;if(typeof Uint8Array.prototype.toBase64==="function")x=(Z)=>Z.toBase64();else x=(Z)=>btoa(String.fromCharCode(...Z));var e;if(typeof Uint8Array.fromBase64==="function")e=(Z)=>Uint8Array.fromBase64(Z);else e=(Z)=>Uint8Array.from(atob(Z),(X)=>X.charCodeAt(0));function XK(Z){return x(Z).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function EW(Z){let X=Z.length%4===0?"":"=".repeat(4-Z.length%4),W=Z.replace(/-/g,"+").replace(/_/g,"/")+X;return e(W)}function IZ(Z,X){let W=new Uint8Array(Z.length+X.length);return W.set(Z,0),W.set(X,Z.length),W}function Kl(Z,X,W){return W.checkSigEd25519(Z.sig,Z.headCph,X)}async function Gl(Z,X,W,V){let l;if(Z.bod&&Z.len>0)l=await W.blake3(Z.bod);let K=new j,G=JZ.encode(K,{...Z,hsh:l});if(G!==0)return Y(G);let m=K.result(),R=await X.kdmFor(m),J=V.deriveCipher(R,"encrypt"),C=await J.encrypt(m),F=Z.bod?await J.encrypt(Z.bod):new Uint8Array(0),d=await X.sign(C);return b({sig:d,kdm:R,headCph:C,bodyCph:F})}async function uW(Z,X,W,V,l){let K=new O(Z),[G,m]=JZ.decode(K);if(m!==0)return Y(14);let R;try{R=X&&X.length>0?await W.decrypt(X):void 0}catch{return Y(20)}let J=G.hsh&&R===void 0,C=G.hsh===void 0&&R!==void 0;if(J||C)return Y(19);if(G.hsh&&R){let d=await V.blake3(R);if(!n(d,G.hsh))return Y(19)}let F=l??await V.blake3(Z);return b({msgHead:G,bod:R,headHash:F})}class jZ{now(){return new Date}}function ml(Z,X,W,V){let l=X.getTime()-Z.getTime(),K=W.getTime()-V.getTime();return(l+K)/2}var SX={encode(Z,X){if(Z.writeVarInt(X.quota),X.quota>0){if(X.usage===void 0)return 9;Z.writeVarInt(X.usage)}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let V;if(X>0){let[l,K]=Z.readVarInt();if(K!==0)return Y(K);V=l}return b({quota:X,usage:V})}};var wW={encode(Z,X){Z.writeBytes(new Uint8Array([X.status]));let W=Z.writeDate(X.timeRcvd);if(W!==0)return W;let V=Z.writeDate(X.timeSent);if(V!==0)return V;let l=Z.writeVarInt(X.subscription.term);if(l!==0)return l;let K=Z.writeVarInt(X.subscription.elapsed);if(K!==0)return K;let G=Z.writeStruct(SX,X.subscription.stat);if(G!==0)return G;let m=Z.writeStruct(SX,X.subscription.dyn);if(m!==0)return m;return 0},decode(Z){let[X,W]=Z.readBytes(1);if(W!==0)return Y(W);let V=X[0],[l,K]=Z.readDate();if(K!==0)return Y(K);let[G,m]=Z.readDate();if(m!==0)return Y(m);let[R,J]=Z.readVarInt();if(J!==0)return Y(J);let[C,F]=Z.readVarInt();if(F!==0)return Y(F);let[d,k]=Z.readStruct(SX);if(k!==0)return Y(k);let[T,I]=Z.readStruct(SX);if(I!==0)return Y(I);return b({status:V,timeRcvd:l,timeSent:G,subscription:{term:R,elapsed:C,stat:d,dyn:T}})}};var DW={encode(Z,X){let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarInt(X.seq);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readVarBytes();if(W!==0)return Y(W);let[V,l]=Z.readVarInt();if(l!==0)return Y(l);return b({headCph:X,seq:V})}};var RZ={encode(Z,X){Z.writeBytes(X.pubKey),Z.writeBytes(X.sig);let W=Z.writeDate(X.timestamp);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readBytes(Wl);if(W!==0)return Y(W);let[V,l]=Z.readBytes(PZ);if(l!==0)return Y(l);let[K,G]=Z.readDate();if(G!==0)return Y(G);return b({pubKey:X,sig:V,timestamp:K})}};var Yl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;for(let G of V)l.writeVarInt(G);return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await iZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);if(F!==0)return F;if(!C)return 5;let[d,k]=X.readVarInt();if(k!==0)return k;if(!X.done())return 8;let[T,I]=await K.listHeads(J,d);if(I!==0)return I;return W.writeStructs(DW,T)},decodeResp(Z){return Z.readStructs(DW)}};var AW={encode(Z,X){Z.writeVarInt(X.seq);let W=Z.writeVarBytes(X.bodyCph);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);return b({seq:X,bodyCph:V})}};var Rl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;for(let G of V){let m=l.writeVarInt(G);if(m!==0)return m}return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await iZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G,[C,F]=await K.hasUser(J);if(F!==0)return F;if(!C)return 5;let d=[];while(!X.done()){let[I,L]=X.readVarInt();if(L!==0)return L;d.push(I)}console.info(`PULL: ${d.length} bags`);let[k,T]=await K.getBodies(J,d);if(T!==0)return T;if(!k)return 17;for(let{seq:I,bodyCph:L}of k){let p={seq:I,bodyCph:L},Q=W.writeStruct(AW,p);if(Q!==0)return Q}return 0},decodeResp(Z){return Z.readStructs(AW)}};var vW={encode(Z,X){Z.writeBytes(X.sig),Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarBytes(X.bodyCph);if(V!==0)return V;return 0},decode(Z){let[X,W]=Z.readBytes(PZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(OZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);let[m,R]=Z.readVarBytes();if(R!==0)return Y(R);return b({sig:X,kdm:V,headCph:K,bodyCph:m})}};var nX={encode(Z,X){let W=Z.writeVarInt(X.seq);if(W!==0)return W;let V=Z.writeVarBytes(X.headCph);if(V!==0)return V;let l=X.bodyCph?X.bodyCph.length:0,K=Z.writeVarInt(l);if(K!==0)return K;if(l>0){if(!X.bodyCph)return 10;Z.writeBytes(X.bodyCph)}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let m;if(K>0){let[R,J]=Z.readBytes(K);if(J!==0)return Y(J);m=R}return b({seq:X,headCph:V,bodyCph:m})}};var _X={encode(Z,X){Z.writeBytes(X.sig),Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;return 0},decode(Z){let[X,W]=Z.readBytes(PZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(OZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return b({sig:X,kdm:V,headCph:K})}};var aX={encode(Z,X){if(Z.writeVarInt(X.idx),Z.writeBytes(new Uint8Array([X.status])),X.status===0)Z.writeVarInt(X.seq);return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);let[V,l]=Z.readBytes(1);if(l!==0)return Y(l);let K=V[0];if(K!==0)return b({idx:X,status:K});let[G,m]=Z.readVarInt();if(m!==0)return Y(m);return b({idx:X,status:K,seq:G})}};var Jl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(RZ,W);if(K!==0)return K;let G=l.writeStructs(vW,V);if(G!==0)return G;return 0},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K,notifier:G}=Z,[m,R]=X.readStruct(RZ);if(R!==0)return R;let J=await iZ(m,l,V);if(J!==0)return J;let{pubKey:C}=m,[F,d]=await K.hasUser(C);if(d!==0)return d;if(!F)return 5;let[k,T]=X.readStructs(vW);if(T!==0)return T;console.info(`PUSH: ${k.length} bags`);let I=[],L=[];for(let c=0;c<k.length;c++){let M=k[c];if(!await Kl(M,C,l)){let B={idx:c,status:3},i=W.writeStruct(aX,B);if(i!==0)return i;continue}I.push(c),L.push(M)}let[p,Q]=await K.setBags(C,L);if(Q!==0)return Q;if(!p||p.length!==L.length)return 17;let S=[];for(let c=0;c<L.length;c++){let M=L[c],H=I[c],B=p[c],i=new j,U=i.writeStruct(_X,M);if(U!==0)return U;let u=i.result(),D={seq:B,headCph:u};if(k.length===1&&M.bodyCph.length<=ll)D.bodyCph=M.bodyCph;S.push(D);let y={idx:H,status:0,seq:B},q=W.writeStruct(aX,y);if(q!==0)return q}if(S.length>0){let c=new j,M=c.writeStructs(nX,S);if(M!==0)return M;let H=c.result();await Promise.resolve(G.push(C,H))}return 0},decodeResp(Z){return Z.readStructs(aX)}};var Cl={async encodeReq(Z,X,W,V,l){return l.writeStruct(RZ,W)},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(RZ);if(m!==0)return m;let R=await iZ(G,l,V);if(R!==0)return R;let{pubKey:J}=G;if(!X.done())return 8;let[C,F]=await K.addUser(J);if(F!==0)return F;return 0},decodeResp(Z){return b(void 0)}};class $W{url;websocket;constructor(Z){this.url=Z}connected(){return this.websocket!==void 0&&this.websocket.readyState===WebSocket.OPEN}async connect(Z,X,W=()=>{},V=()=>{}){let{url:l}=this;if(this.websocket)this.websocket.close(),this.websocket=void 0;let K=new j;K.writeStruct(RZ,Z);let G=K.result(),m=YZ(G);return l.searchParams.set("t",m),this.websocket=new WebSocket(l),this.websocket.binaryType="arraybuffer",this.websocket.onopen=()=>{console.log("CONNECTED"),V()},this.websocket.onclose=()=>{console.log("DISCONNECTED"),this.websocket=void 0,W()},this.websocket.onmessage=(R)=>{let J=new Uint8Array(R.data);X(J)},this.websocket.onerror=(R)=>{console.log(`ERROR: ${JSON.stringify(R)}`),this.websocket=void 0,W()},Promise.resolve(0)}disconnect(){this.websocket?.close(),this.websocket=void 0}}var r={user:{path:"/user",endpoint:Cl,name:0},push:{path:"/push",endpoint:Jl,name:2},peek:{path:"/peek",endpoint:Yl,name:1},pull:{path:"/pull",endpoint:Rl,name:3}},WK={0:r.user,2:r.push,1:r.peek,3:r.pull},xR={[r.user.path]:r.user,[r.push.path]:r.push,[r.peek.path]:r.peek,[r.pull.path]:r.pull};class qW{url;listener;constructor(Z){this.url=Z;this.listener=new $W(Z)}async call(Z,X){let{path:W}=WK[Z],V=new URL(W,this.url);try{return await VK(V,X)}catch{return Y(25)}}}var fW=(Z)=>{return new qW(Z.handle)};async function VK(Z,X){let W=await fetch(Z,{method:"POST",body:X.result().slice()});if(!W.ok)return Y(24);let V=await O.fromResponse(W);return b(V)}class sX{enclave;crypto;host;clock;transport;updateHostMeta;constructor(Z,X,W,V,l,K){this.enclave=Z;this.crypto=X;this.host=W;this.clock=V;this.transport=l;this.updateHostMeta=K}async call(Z,X){let{clock:W,transport:V}=this,{endpoint:l,name:K}=Z,G=await this.identity(),m=W.now(),[R,J]=await BW(G,m);if(J!==0)return Y(J);let C=new j,F=await l.encodeReq(this,G,R,X,C);if(F!==0)return Y(F);let d=W.now(),[k,T]=await V.call(K,C),I=W.now();if(T!==0)return Y(T);let[L,p]=k.readStruct(wW);if(p!==0)return Y(p);if(L.status!==0)return Y(L.status);let S={clockOffset:ml(d,L.timeRcvd,L.timeSent,I),subscription:L.subscription},c=await this.updateHostMeta(S);if(c!==0)return Y(c);return l.decodeResp(k)}identity=()=>{let{host:Z,enclave:X}=this;return X.deriveIdentity(Z.label,Z.idx??0)};seal=async(Z)=>{let{crypto:X,enclave:W}=this,V=await this.identity();return Gl(Z,V,X,W)};register=()=>this.call(r.user,[]);peek=(Z)=>this.call(r.peek,[Z]);push=(Z)=>this.call(r.push,Z);pull=(Z)=>this.call(r.pull,Z);listen=async(Z,X,W)=>{let{clock:V,transport:l}=this,{listener:K}=l,G=await this.identity(),m=V.now(),[R,J]=await BW(G,m);if(J!==0)return J;return await K.connect(R,Z,X,W)};isConnected(){let Z=this.transport?.listener;if(Z&&typeof Z.connected==="function")return Z.connected();return!0}closeListener(){this.transport?.listener?.disconnect()}}var oW={encode(Z,X){let W=Z.writeVarString(X.lbl);if(W!==0)return W;let V=Z.writeVarInt(X.idx);if(V!==0)return V;let l=Z.writeVarInt(X.num);if(l!==0)return l;return Z.writeBytes(X.hsh),Z.writeBytes(X.sig),0},decode(Z){let[X,W]=Z.readVarString();if(W!==0)return Y(W);let[V,l]=Z.readVarInt();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let[m,R]=Z.readBytes(oX);if(R!==0)return Y(R);let[J,C]=Z.readBytes(PZ);if(C!==0)return Y(C);return b({lbl:X,idx:V,num:K,hsh:m,sig:J})}};var nW={encode(Z,X){let W=Z.writeStruct(oW,X.head);if(W!==0)return W;let V=Z.writeVarBytes(X.indexEnc);if(V!==0)return V;let l=Z.writeVarBytes(X.bodyEnc);if(l!==0)return l;return 0},decode(Z){let[X,W]=Z.readStruct(oW);if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return b({head:X,indexEnc:V,bodyEnc:K})}};var _W={encode(Z,X){Z.writeBytes(X.kdm);let W=Z.writeVarBytes(X.headCph);if(W!==0)return W;let V=Z.writeVarInt(X.lenBody);if(V!==0)return V;if(X.lenBody>0&&X.offBody!==void 0){let l=Z.writeVarInt(X.offBody);if(l!==0)return l}return 0},decode(Z){let[X,W]=Z.readBytes(OZ);if(W!==0)return Y(W);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);let m;if(K>0){let[R,J]=Z.readVarInt();if(J!==0)return Y(J);m=R}return b({kdm:X,headCph:V,lenBody:K,offBody:m})}};async function Fl(Z,X,W,V,l){let K=await l.deriveIdentity(Z,X),G=new j,m=new j,R=0,J=0;for(let p of W){let Q=new j,S=Q.writeStruct(JZ,p.head);if(S!==0)return Y(S);let c=Q.result(),M=await K.kdmFor(c),H=l.deriveCipher(M,"encrypt"),B=await H.encrypt(c),i=p.body?await H.encrypt(p.body):new Uint8Array(0),U=p.head.len>0&&p.head.hsh!==void 0?i.length:0,u={kdm:M,headCph:B,lenBody:U,offBody:U>0?J:void 0},D=G.writeStruct(_W,u);if(D!==0)return Y(D);if(p.body)m.writeBytes(i),J+=i.length;R++}let C=m.result(),F=G.result(),d=await V.blake3(F),k=await K.sign(d),T={lbl:Z,idx:X,num:R,hsh:d,sig:k},I=new j;I.writeStruct(nW,{head:T,indexEnc:F,bodyEnc:C});let L=I.result();return b(L)}async function bl(Z,X,W){let[V,l]=nW.decode(new O(Z));if(l!==0)return Y(l);let{head:K,indexEnc:G,bodyEnc:m}=V,R=await W.deriveIdentity(K.lbl,K.idx);if(!await X.checkSigEd25519(K.sig,K.hsh,R.publicKey))return Y(3);let C=await X.blake3(G);if(!n(C,K.hsh))return Y(19);let F=new O(G),d=[];for(let T=0;T<K.num;T++){let[I,L]=F.readStruct(_W);if(L!==0)return Y(L);d.push(I)}if(d.length!==K.num)return Y(14);let k=[];for(let T of d){let I=W.deriveCipher(T.kdm,"decrypt"),L;try{L=await I.decrypt(T.headCph)}catch{return Y(20)}let[p,Q]=JZ.decode(new O(L));if(Q!==0)return Y(Q);let S;if(T.lenBody>0&&T.offBody!==void 0){if(p.hsh===void 0)return Y(14);let c=m.slice(T.offBody,T.offBody+T.lenBody);try{S=await I.decrypt(c)}catch{return Y(20)}let M=await X.blake3(S);if(!n(M,p.hsh))return Y(19)}k.push({head:p,body:S})}return b(k)}async function dl({now:Z,bod:X,crypto:W}){let V=await W.genRandomBytes(8),l=new j,K=l.writeStruct(s,{id:V,ts:Z});if(K!==0)return Y(K);let G=l.result();return rX({now:Z,eid:G,ctr:0,bod:X,crypto:W})}async function rX({now:Z,eid:X,ctr:W,bod:V,crypto:l}){let K=new O(X),[G,m]=s.decode(K);if(m!==0)return Y(m);let R=Z.getTime()-G.ts.getTime(),J,C=V?.length??0;if(V&&C>0)J=await l.blake3(V);return b({eid:X,off:R,ctr:W,len:C,hsh:J})}function kl(Z,X){let W=Z.length<X.length?Z.length:X.length;for(let V=0;V<W;V++)if(Z[V]!==X[V])return Z[V]-X[V];return Z.length-X.length}async function KX(Z,X){let W=Array.from(Z);W.sort(kl);let V=0;for(let G of W)V+=G.length;let l=new Uint8Array(V),K=0;for(let G of W)l.set(G,K),K+=G.length;return X.blake3(l)}function Tl(Z){let X=new j,W=X.writeVarBytes(Z.eid);if(W!==0)return Y(W);let V=X.writeDate(Z.updatedAt);if(V!==0)return Y(V);let l=X.writeVarInt(Z.ctr);if(l!==0)return Y(l);return b(X.result())}async function zX(Z,X){let W=[];for(let V of Z){let[l,K]=Tl(V);if(K!==0||!l)return Y(K);W.push(l)}return b(await KX(W,X))}var pJ=Symbol("MasterSeed"),yJ=Symbol("SealedMasterKey"),kZ=32,aW=24+kZ+16;function VZ(Z){if(Z.byteLength!==kZ)return Y(10);return b(Z)}function yZ(Z){if(Z.byteLength!==aW)return Y(10);return b(Z)}var zJ=Symbol("EntityID");function Il(Z){return"type"in Z}var NJ=Symbol("DerivationSeed"),MJ=Symbol("PublicKey"),gJ=Symbol("PrivateKey"),xJ=Symbol("HostSpecificKeyPair"),HJ=Symbol("Hash");function lK(Z){if(!Z)return!1;if(typeof Z!=="object")return!1;if("body"in Z===!1)return!1;if("type"in Z===!1)return!1;return!0}function KK(Z){if(!Z.bod||Z.bod.length===0){let V={off:Z.off,ctr:Z.ctr,eid:Z.eid};return b(V)}let X=jW(Z.bod);if(lK(X)===!1)return console.warn("msg body invalid",X),Y(14);let W={off:Z.off,ctr:Z.ctr,eid:Z.eid,gid:X.gid,pid:X.pid,tags:X.tags,type:X.type,body:X.body};return b(W)}class NX{applier;emitter=new UZ;clearer;onDirtyEids;cacheDriven;peerIngest;constructor(Z,X,W,V){this.applier=Z;this.clearer=X,this.onDirtyEids=W,this.cacheDriven=V?.cacheDriven??!1,this.peerIngest=V?.peerIngest}apply=async(Z)=>{let X=[],W=[];for(let m of Z){let[R,J]=KK(m);if(W.push(J),J!==0)continue;X.push(R)}let{stats:V,types:l,eids:K}=await this.applier(X),G=[];for(let m=0;m<Z.length;m++){let R=W[m],J=V[m];if(R!==0){G.push(R);continue}if(J!==0){G.push(J);continue}G.push(0)}if(!this.cacheDriven)for(let m of l)this.emitter.emit(m,null);if(K.length>0)this.onDirtyEids?.(K);return G};clear=async()=>{let Z=await this.clearer();if(Z!==0)return Z;return this.emitter.emitAll(null),Z};notify=(Z)=>{for(let X of Z)this.emitter.emit(X,null)};refresh=async(Z)=>{if(this.peerIngest){await this.peerIngest(Z);return}};on=(Z,X)=>{this.emitter.addEventListener(Z,X)};off=(Z,X)=>{this.emitter.removeEventListener(Z,X)}}var sW={apply:async function(Z){return Z.map(()=>0)},clear:async function(){return 0},notify:function(Z){},refresh:async function(Z){},on:function(Z,X){},off:function(Z,X){}};var o="entities",tX="entity_type_created_at",tW="entity_type_updated_at",eW="entity_type_group_id",ZV="entity_type_parent_id",GX="entity_tags",Ll="db",cl=13;function GK(Z){return"typ"in Z}function mK(Z){let X={bod:Z.body,crd:Z.createdAt,...Z.ctr!==0?{ctr:Z.ctr}:{},eid:x(Z.eid),gid:Z.gid,pid:Z.pid?x(Z.pid):void 0,tgs:Z.tags,typ:Z.type,upd:Z.updatedAt};if(X.gid===void 0)delete X.gid;if(X.pid===void 0)delete X.pid;if(X.tgs===void 0)delete X.tgs;if(X.ctr===void 0)delete X.ctr;return X}function YK(Z){if(!v(Z))return{eid:x(Z.eid),upd:Z.updatedAt,...Z.ctr!==0?{ctr:Z.ctr}:{}};return mK(Z)}function mX(Z){return{body:Z.bod,createdAt:Z.crd,updatedAt:Z.upd,ctr:Z.ctr??0,type:Z.typ,eid:e(Z.eid),gid:Z.gid,pid:Z.pid?e(Z.pid):void 0,...Z.tgs!==void 0?{tags:Z.tgs}:{}}}function rW(Z){if(GK(Z))return mX(Z);return{eid:e(Z.eid),updatedAt:Z.upd,ctr:Z.ctr??0}}class XV{db;opening;async init(){await this.ensureDb()}async ensureDb(){if(this.db)return this.db;if(this.opening)return this.opening;return this.opening=JK().then((Z)=>{return Z.onversionchange=()=>{if(Z.close(),this.db===Z)this.db=void 0},this.db=Z,this.opening=void 0,Z},(Z)=>{throw this.opening=void 0,Z}),this.opening}apply=async(Z)=>{let X=new Set,W=[],V;try{V=await this.ensureDb()}catch{return{stats:Z.map(()=>16),types:X,eids:W}}let l=V.transaction(o,"readwrite"),K=l.objectStore(o);return new Promise((G)=>{let m=Array(Z.length).fill(0);if(Z.length<1){G({stats:[],types:X,eids:W});return}l.oncomplete=()=>{G({stats:m,types:X,eids:W})},l.onerror=()=>{for(let J=0;J<m.length;J++)if(m[J]===void 0)m[J]=18;G({stats:m,types:X,eids:W})};let R=new Map;for(let J=0;J<Z.length;J++){let C=Z[J],F=x(C.eid),d={op:C,index:J},k=R.get(F);if(k)k.push(d);else R.set(F,[d])}for(let[J,C]of R){if(C.length<1)continue;let F=K.get(J);F.onsuccess=()=>{let d=F.result,k=d?rW(d):void 0,T=!1;for(let{op:I,index:L}of C){let[p,Q]=YX(k,I);if(Q!==0){m[L]=Q;continue}if(p===void 0){m[L]=12;continue}T=!0;for(let S of RX(k,p))X.add(S);k=p}if(T)W.push(C[0].op.eid);if(k){let I=K.put(YK(k));I.onerror=(L)=>{L.preventDefault();for(let{index:p}of C)m[p]=18}}},F.onerror=()=>{for(let{index:d}of C)m[d]=18}}})};async clear(){let Z;try{Z=await this.ensureDb()}catch{return 16}let X=Z.transaction(o,"readwrite"),W=X.objectStore(o);return new Promise((V)=>{X.oncomplete=()=>V(0),X.onerror=()=>V(18),W.clear()})}async getRow(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let W=x(Z),l=X.transaction(o,"readonly").objectStore(o);return new Promise((K)=>{let G=l.get(W);G.onsuccess=()=>{let m=G.result;if(!m)K(b(void 0));else K(b(rW(m)))},G.onerror=()=>K(Y(18))})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!v(X))return b(void 0);return b(X)}async getAllOfTypeUpdatedBetween(Z,X,W){let V;try{V=await this.ensureDb()}catch{return Y(16)}let K=V.transaction(o,"readonly").objectStore(o).index(tW);return new Promise((G)=>{let m=K.getAll(IDBKeyRange.bound([Z,X],[Z,W]));m.onsuccess=()=>{let R=m.result;G(b(R.map(mX)))},m.onerror=()=>G(Y(18))})}async getGroupMembers(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(o,"readonly").objectStore(o).index(eW);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z,X]));G.onsuccess=()=>{let m=G.result;K(b(m.map(mX)))},G.onerror=()=>K(Y(18))})}async getAllOfType(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(o,"readonly").objectStore(o).index(tX);return new Promise((l)=>{let K=V.getAll(IDBKeyRange.bound([Z],[Z,[]]));K.onsuccess=()=>{let G=K.result;l(b(G.map(mX)))},K.onerror=()=>l(Y(18))})}async getByTag(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(o,"readonly").objectStore(o).index(GX);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only(X));G.onsuccess=()=>{let R=G.result.filter((J)=>J.typ===Z).map(mX);K(b(R))},G.onerror=()=>K(Y(18))})}async getAllEntities(Z){if("pid"in Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let W=x(Z.pid),l=X.transaction(o,"readonly").objectStore(o).index(ZV);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z.type,W]));G.onsuccess=()=>{let R=G.result.map(mX);K(b(R))},G.onerror=()=>K(Y(18))})}else if("gid"in Z)return await this.getGroupMembers(Z.type,Z.gid);else if("tag"in Z)return await this.getByTag(Z.type,Z.tag);else if("updatedBetween"in Z)return await this.getAllOfTypeUpdatedBetween(Z.type,Z.updatedBetween.start,Z.updatedBetween.end);return await this.getAllOfType(Z.type)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return b(X)}async countEntities({type:Z}){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(o,"readonly").objectStore(o).index(tX);return new Promise((l)=>{let K=IDBKeyRange.bound([Z],[Z,[]]),G=V.count(K);G.onsuccess=()=>l(b(G.result)),G.onerror=()=>l(Y(18))})}async checksum(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(o,"readonly").objectStore(o),l=[];return new Promise((K)=>{let G=V.openCursor();G.onsuccess=()=>{let m=G.result;if(m){let R=m.value;l.push(MX(rW(R))),m.continue()}else zX(l,Z).then(K)},G.onerror=()=>K(Y(18))})}}function RK(Z,X){if(!Z.objectStoreNames.contains(o))Z.createObjectStore(o,{keyPath:"eid",autoIncrement:!1});let W=X.objectStore(o);if(!W.indexNames.contains(tX))W.createIndex(tX,["typ","crd"],{unique:!1});if(!W.indexNames.contains(tW))W.createIndex(tW,["typ","upd"],{unique:!1});if(!W.indexNames.contains(eW))W.createIndex(eW,["typ","gid"],{unique:!1});if(!W.indexNames.contains(ZV))W.createIndex(ZV,["typ","pid"],{unique:!1});if(W.indexNames.contains(GX)){if(W.index(GX).keyPath!=="tgs")W.deleteIndex(GX)}if(!W.indexNames.contains(GX))W.createIndex(GX,"tgs",{unique:!1,multiEntry:!0})}function JK(){return new Promise((Z,X)=>{let W=indexedDB.open(Ll,cl);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!l){X(Error("Transaction is null during EntDB upgrade"));return}try{RK(V,l)}catch(K){X(K instanceof Error?K:Error(String(K)))}},W.onblocked=()=>{console.warn(`[DIPLOMATIC] EntDB IDB upgrade blocked (${Ll} → v${cl}); waiting for other connections to close`)},W.onsuccess=()=>Z(W.result),W.onerror=()=>X(W.error??Error("EntDB IndexedDB open failed"))})}async function Ql(){let Z=new XV;return await Z.init(),Z}class eX{ents=new Map;useIndex;byType=new Map;byTypePid=new Map;byTypeGid=new Map;byTypeTag=new Map;constructor(Z=[],X){this.useIndex=X?.indexes!==!1;for(let W of Z)this.put(W)}put(Z){let X=x(Z.eid),W=this.ents.get(X);if(W!==void 0&&v(W))this.unindex(X,W);if(this.ents.set(X,Z),v(Z))this.index(X,Z)}del(Z){let X=this.ents.get(Z);if(X===void 0)return;if(v(X))this.unindex(Z,X);this.ents.delete(Z)}index(Z,X){if(!this.useIndex)return;let W=this.byType.get(X.type);if(!W)W=new Map,this.byType.set(X.type,W);if(W.set(Z,X),X.pid){let V=x(X.pid),l=this.byTypePid.get(X.type);if(!l)l=new Map,this.byTypePid.set(X.type,l);let K=l.get(V);if(!K)K=new Map,l.set(V,K);K.set(Z,X)}if(typeof X.gid==="string"){let V=this.byTypeGid.get(X.type);if(!V)V=new Map,this.byTypeGid.set(X.type,V);let l=V.get(X.gid);if(!l)l=new Map,V.set(X.gid,l);l.set(Z,X)}if(X.tags){let V=this.byTypeTag.get(X.type);if(!V)V=new Map,this.byTypeTag.set(X.type,V);for(let l of X.tags){let K=V.get(l);if(!K)K=new Map,V.set(l,K);K.set(Z,X)}}}unindex(Z,X){if(!this.useIndex)return;let W=this.byType.get(X.type);if(W){if(W.delete(Z),W.size===0)this.byType.delete(X.type)}if(X.pid){let V=x(X.pid),l=this.byTypePid.get(X.type),K=l?.get(V);if(K){if(K.delete(Z),K.size===0)l?.delete(V)}if(l&&l.size===0)this.byTypePid.delete(X.type)}if(typeof X.gid==="string"){let V=this.byTypeGid.get(X.type),l=V?.get(X.gid);if(l){if(l.delete(Z),l.size===0)V?.delete(X.gid)}if(V&&V.size===0)this.byTypeGid.delete(X.type)}if(X.tags){let V=this.byTypeTag.get(X.type);if(V){for(let l of X.tags){let K=V.get(l);if(K){if(K.delete(Z),K.size===0)V.delete(l)}}if(V.size===0)this.byTypeTag.delete(X.type)}}}clearIndexes(){this.byType.clear(),this.byTypePid.clear(),this.byTypeGid.clear(),this.byTypeTag.clear()}bucketList(Z){if(!Z||Z.size===0)return[];let X=[];for(let W of Z.values())X.push(W);return X}async apply(Z){let X=new Set,W=[],V=[];for(let l of Z){let K=x(l.eid),G=this.ents.get(K),[m,R]=YX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of RX(G,m))X.add(J);this.put(m),W.push(l.eid),V.push(0)}return{stats:V,types:X,eids:W}}async clear(){return this.ents.clear(),this.clearIndexes(),0}async getRow(Z){let X=x(Z),W=this.ents.get(X);return b(W)}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!v(X))return b(void 0);return b(X)}async getAllEntities({type:Z,gid:X,pid:W,tag:V,updatedBetween:l}){if(this.useIndex){if(W!==void 0){let G=x(W);return b(this.bucketList(this.byTypePid.get(Z)?.get(G)))}if(X!==void 0)return b(this.bucketList(this.byTypeGid.get(Z)?.get(X)));if(V!==void 0)return b(this.bucketList(this.byTypeTag.get(Z)?.get(V)));if(l!==void 0){let G=[],m=this.byType.get(Z);if(m){for(let R of m.values())if(R.updatedAt>=l.start&&R.updatedAt<=l.end)G.push(R)}return b(G)}return b(this.bucketList(this.byType.get(Z)))}let K=[];if(W!==void 0){for(let G of this.ents.values())if(v(G)&&G.type===Z&&G.pid&&n(G.pid,W))K.push(G)}else if(X!==void 0){for(let G of this.ents.values())if(v(G)&&G.type===Z&&(typeof G.gid==="string"&&G.gid===X))K.push(G)}else if(V!==void 0){for(let G of this.ents.values())if(v(G)&&G.type===Z&&G.tags&&G.tags.includes(V))K.push(G)}else if(l!==void 0){for(let G of this.ents.values())if(v(G)&&G.type===Z&&G.updatedAt>=l.start&&G.updatedAt<=l.end)K.push(G)}else for(let G of this.ents.values())if(v(G)&&G.type===Z)K.push(G);return b(K)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return b(X)}async countEntities({type:Z}){if(this.useIndex)return b(this.byType.get(Z)?.size??0);let X=0;for(let W of this.ents.values())if(v(W)&&W.type===Z)X+=1;return b(X)}async checksum(Z){let X=[];for(let W of this.ents.values())X.push(MX(W));return zX(X,Z)}}async function WV(Z){let X=await Ql();if(Z?.cache===!1)return X;return new gX(X,void 0,{indexes:Z?.indexes})}class gX{mem;durable;warmed=new Set;listeners=new Set;chain=Promise.resolve();constructor(Z,X,W){if(this.durable=Z,this.mem=new eX(X??[],{indexes:W?.indexes}),X)for(let V of X)this.warmed.add(V.type)}subscribe(Z){return this.listeners.add(Z),()=>{this.listeners.delete(Z)}}emit(Z){if(Z.size<1)return;for(let X of this.listeners)X(Z)}run(Z){let X=this.chain.then(Z,Z);return this.chain=X.then(()=>{return},()=>{return}),X}apply(Z){return this.run(async()=>{await this.pullEids(Z.map((K)=>K.eid));let X=TK(this.mem,Z);this.emit(X.types);let W=await this.durable.apply(Z),{changed:V,status:l}=await this.pullEids(Z.map((K)=>K.eid));if(this.emit(V),l!==0)return{stats:Z.map(()=>l),types:W.types,eids:W.eids};return W})}clear(){return this.run(async()=>{let Z=await this.durable.clear();if(Z!==0)return Z;let X=this.mem.ents.size>0;return await this.mem.clear(),this.warmed.clear(),0})}ingestFromDurable(Z){return this.run(async()=>{let{changed:X,status:W}=await this.pullEids(Z);return this.emit(X),W})}async pullEids(Z){let X=new Set,W=new Set;for(let V of Z){let l=x(V);if(W.has(l))continue;W.add(l);let K=this.mem.ents.get(l),[G,m]=await this.durable.getRow(V);if(m!==0)return{changed:X,status:m};if(G){if(this.mem.put(G),!K||!CK(K,G)){if(v(G))X.add(G.type);if(K!==void 0&&v(K))X.add(K.type)}}else if(K!==void 0){if(this.mem.del(l),v(K))X.add(K.type)}}return{changed:X,status:0}}async warmType(Z){if(this.warmed.has(Z))return 0;let[X,W]=await this.durable.getEntities({type:Z});if(W!==0)return W;if(X)for(let V of X){let l=x(V.eid),K=this.mem.ents.get(l);if(!K||kK(V,K))this.mem.put(V)}return this.warmed.add(Z),0}async getRow(Z){let X=x(Z);if(this.mem.ents.has(X))return this.mem.getRow(Z);return this.run(async()=>{if(this.mem.ents.has(X))return this.mem.getRow(Z);let[W,V]=await this.durable.getRow(Z);if(V!==0)return Y(V);if(W)this.mem.put(W);return b(W)})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!v(X))return b(void 0);return b(X)}async getEntities(Z){if(!this.warmed.has(Z.type)){let X=await this.run(()=>this.warmType(Z.type));if(X!==0)return Y(X)}return this.mem.getEntities(Z)}async countEntities({type:Z}){if(!this.warmed.has(Z)){let X=await this.run(()=>this.warmType(Z));if(X!==0)return Y(X)}return this.mem.countEntities({type:Z})}async checksum(Z){return this.durable.checksum(Z)}}function CK(Z,X){if(v(Z)!==v(X))return!1;if(Z.ctr!==X.ctr)return!1;if(Z.updatedAt.getTime()!==X.updatedAt.getTime())return!1;if(!n(Z.eid,X.eid))return!1;if(!v(Z)||!v(X))return!0;if(Z.createdAt.getTime()!==X.createdAt.getTime())return!1;if(Z.type!==X.type)return!1;if(Z.gid!==X.gid)return!1;if(!bK(Z.pid,X.pid))return!1;if(!FK(Z.tags,X.tags))return!1;return dK(Z.body,X.body)}function FK(Z,X){if(Z===X)return!0;if(Z===void 0||X===void 0)return!1;if(Z.length!==X.length)return!1;for(let W=0;W<Z.length;W++)if(Z[W]!==X[W])return!1;return!0}function bK(Z,X){if(Z===void 0&&X===void 0)return!0;if(Z===void 0||X===void 0)return!1;return n(Z,X)}function dK(Z,X){if(Object.is(Z,X))return!0;if(Z instanceof Uint8Array&&X instanceof Uint8Array)return n(Z,X);if(Z instanceof Date&&X instanceof Date)return Z.getTime()===X.getTime();try{return n(vZ(Z),vZ(X))}catch{return!1}}function kK(Z,X){let W=Z.updatedAt.getTime(),V=X.updatedAt.getTime();if(W!==V)return W>V;return Z.ctr>X.ctr}function TK(Z,X){let W=new Set,V=[];for(let l of X){let K=x(l.eid),G=Z.ents.get(K),[m,R]=YX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of RX(G,m))W.add(J);Z.put(m),V.push(0)}return{stats:V,types:W}}function ZW(Z){if(Z instanceof gX){let X=new NX((W)=>Z.apply(W),()=>Z.clear(),void 0,{cacheDriven:!0,peerIngest:async(W)=>{await Z.ingestFromDurable(W)}});return Z.subscribe((W)=>X.notify(W)),X}return new NX((X)=>Z.apply(X),()=>Z.clear())}function v(Z){return"type"in Z}function IK(Z){return!v(Z)}function pl(Z){if(!Array.isArray(Z)||Z.length===0)return;let X=new Set,W=[];for(let V of Z){if(typeof V!=="string"||V.length===0)continue;if(X.has(V))continue;X.add(V),W.push(V)}return W.length>0?W:void 0}function MX(Z){return{eid:Z.eid,ctr:Z.ctr,updatedAt:Z.updatedAt}}function VV(Z){let X=new O(Z.eid),[W,V]=X.readStruct(s);if(V!==0)return Y(V);return b({eid:Z.eid,ctr:Z.ctr,updatedAt:new Date(W.ts.getTime()+Z.off)})}function YX(Z,X){let W=new O(X.eid),[V,l]=W.readStruct(s);if(l!==0)return Y(l);let K=new Date(V.ts.getTime()+X.off);if(Z!==void 0&&K<=Z.updatedAt)return Y(15);if(Il(X)){let G=pl(X.tags);return b({eid:X.eid,gid:X.gid,pid:X.pid,...G!==void 0?{tags:G}:{},type:X.type,createdAt:V.ts,updatedAt:K,ctr:X.ctr,body:X.body})}return b({eid:X.eid,updatedAt:K,ctr:X.ctr})}function RX(Z,X){let W=new Set;if(Z!==void 0&&v(Z))W.add(Z.type);if(v(X))W.add(X.type);return[...W]}var LK={getEnt:async()=>Y(21),getRow:async()=>Y(21),getEntities:async(Z)=>Y(21),countEntities:async()=>Y(21),checksum:async()=>Y(21),apply:async(Z)=>({stats:Z.map(()=>21),types:new Set,eids:[]}),clear:async()=>21};class XW{inflight=null;again=!1;run(Z){if(this.again=!0,this.inflight)return this.inflight;return this.inflight=this.drain(Z),this.inflight}async flush(){if(!this.inflight)return;try{await this.inflight}catch{}}async drain(Z){try{this.again=!1;let X=await Z();while(this.again)this.again=!1,X=await Z();return X}finally{this.inflight=null}}}var WW=100;class xX{timer=null;delayMs;work;tail=new XW;constructor(Z,X){this.delayMs=Z<0?0:Z,this.work=X}schedule(){if(this.delayMs<=0){this.fire();return}if(this.timer!==null)clearTimeout(this.timer);this.timer=setTimeout(()=>{this.timer=null,this.fire()},this.delayMs)}async flush(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null,this.fire();await this.tail.flush()}cancel(){if(this.timer!==null)clearTimeout(this.timer),this.timer=null}fire(){return this.tail.run(this.work)}}function yl(Z){let X=new O(Z.eid),[W,V]=s.decode(X);if(V!==0)return;return W.ts.getTime()+Z.off}function cK(Z,X){let W=yl(Z),V=yl(X);if(W===void 0&&V===void 0)return 0;if(W===void 0)return 1;if(V===void 0)return-1;if(V!==W)return V-W;return X.ctr-Z.ctr}function JX(Z,X){return Z.slice().sort((W,V)=>cK(X(W),X(V)))}var $Z={phase:"idle"},CX=50;function VW(Z,X,W){if(Z<=0||X<=0)return!1;if(Z===1||Z===X)return!0;return Z%W===0}function lW(Z,X){if(typeof navigator.msSaveOrOpenBlob==="function"){navigator.msSaveOrOpenBlob(Z,X);return}let W=URL.createObjectURL(Z),V=document.createElement("a");V.href=W,V.download=X,document.body.appendChild(V),V.click(),document.body.removeChild(V),URL.revokeObjectURL(W)}function Sl(Z,X,W){let V=[],l=[],K=0;for(let G of Z){let m=X(G);if(l.length>0&&K+m>W)V.push(l),l=[],K=0;if(l.push(G),K+=m,K>=W)V.push(l),l=[],K=0}if(l.length>0)V.push(l);return V}async function lV(Z,X,W){let V=Z.length;if(V<1)return[];let l=Array(V),K=0,G=Math.min(Math.max(1,X),V),m=async()=>{while(!0){let J=K;if(K+=1,J>=V)return;l[J]=await W(Z[J],J)}},R=[];for(let J=0;J<G;J++)R.push(m());return await Promise.all(R),l}async function KW(Z,X,W,V){let l=new O(Z.headCph),[K,G]=l.readStruct(_X);if(G!==0)return Y(G);let{sig:m,kdm:R,headCph:J}=K;if(!await V.checkSigEd25519(m,J,X))return Y(3);let F=W.deriveCipher(R,"decrypt"),d;try{d=await F.decrypt(J)}catch{return Y(20)}return b({kdm:R,headEnc:d})}var SZ="f",BZ="t",LZ="e";function QK(Z){return Z===SZ||Z===BZ||Z===LZ}function FX(Z){if(Z===!0||Z===BZ)return BZ;if(Z===LZ)return LZ;return SZ}function pK(Z){return FX(Z.apld)===SZ}function KV(Z){return Z!==0&&Z!==15&&Z!==18&&Z!==17}function qZ(Z,X,W){if(Z.apld=X,X===LZ&&W!==void 0)Z.err=W;else delete Z.err}async function EZ(Z,X,W,V){let l=V?.body!==!1,K=FX(X.apld),G=X.body,m=G?.length??0,R;if(l&&G&&m>0)R=await W.blake3(G);let J={eid:X.eid,off:X.off??0,ctr:X.ctr??0,len:m,hsh:R},C={hash:Z,head:J,apld:K};if(l&&G!==void 0)C.body=G;if(K===LZ&&X.err!==void 0)C.err=X.err;return C}var GV=1048576,mV=1048576,Nl=64;function yK(Z){return Z.sig.length+Z.kdm.length+Z.headCph.length+Z.bodyCph.length}async function SK(Z,X,W,V,l){if(V.length<1)return 0;let[K,G]=await Z.push(V);if(G!==0)return G;if(!K)return 27;for(let R of K){if(R.status!==0){console.error("push err",R);continue}let J=l[R.idx];if(!J){console.error("no hash",R);continue}await X.uploads.deq(W,[J])}let m=await X.hosts.get(W);if(m){let R=m.lastSeq,J=R,C=[];for(let F of K)if(F.status===0)C.push(F.seq);C.sort((F,d)=>F-d);for(let F of C)if(F===R+1)R=F;if(R>J)await X.hosts.touch(W,R)}return 0}async function zl(Z,X){if(X.length<1)return b([]);let W=new Map,V=[];for(let m of X)W.set(m.seq,m),V.push(m.seq);let[l,K]=await Z.pull(V);if(K!==0)return Y(K);if(!l)return Y(27);let G=[];for(let{seq:m,bodyCph:R}of l){let J=W.get(m);if(!J)continue;G.push({dl:J,bodyCph:R})}return b(G)}async function zK(Z,X,W,V){if(V.length<1)return b({parts:[],hashes:[]});let l=[],K=[],G=[],m=new Map;for(let{dl:J,bodyCph:C}of V){let{head:F,kdm:d,seq:k,host:T}=J,[I,L]=await Ml(J,W);if(L!==0||!I){let U=m.get(T)??[];U.push(k),m.set(T,U);continue}let{headEnc:p,headEncHash:Q}=I,S=X.deriveCipher(d,"decrypt"),[c,M]=await uW(p,C,S,W,Q);if(M!==0||!c){let U=m.get(T)??[];U.push(k),m.set(T,U);continue}let H={head:F,body:c.bod},B=c.headHash;G.push({key:B,data:Hl(H)}),l.push(H),K.push(B);let i=m.get(T)??[];i.push(k),m.set(T,i)}let R=await Z.messages.add(G);for(let[J,C]of m)await Z.downloads.deq(J,C);for(let J=0;J<R.length;J++){let C=R[J];if(C!==0&&C!==15)console.error("ERR storing",z[C],"for message",J)}return b({parts:l,hashes:K})}async function Ml(Z,X){let W=Z.headEnc;if(!W){let l=new j,K=l.writeStruct(JZ,Z.head);if(K!==0)return Y(K);W=l.result()}if(Z.headEncHash)return b({headEnc:W,headEncHash:Z.headEncHash});let V=await X.blake3(W);return b({headEnc:W,headEncHash:V})}async function gl(Z,X,W){let V=new Set;for(let G of X)V.add(x(G));if(V.size<1)return;let l=Array.from(await Z.downloads.list());if(l.length<1)return;let K=new Map;for(let G of l){let m;if(G.headEncHash)m=x(G.headEncHash);else{let[J,C]=await Ml(G,W);if(C!==0||!J)continue;m=x(J.headEncHash)}if(!V.has(m))continue;let R=K.get(G.host)??[];R.push(G.seq),K.set(G.host,R)}for(let[G,m]of K)await Z.downloads.deq(G,m)}async function YV({conn:Z,store:X,enclave:W,host:V,crypto:l,onProgress:K,peekProgressEvery:G,peekConcurrency:m}){let R=await Z.identity(),J=[],[C,F]=await Z.peek(V.lastSeq);if(F!==0)return F;let d=C.length,k=G??CX,T=m??Nl;if(K&&d>0)K({phase:"peek",host:V.label,done:0,total:d});let I=0,L=await lV(C,T,async(Q)=>{let[S,c]=await KW(Q,R.publicKey,W,l),M;if(c!==0||!S)M={ok:!1,seq:Q.seq,stat:c};else{let H=await l.blake3(S.headEnc);M={ok:!0,seq:Q.seq,kdm:S.kdm,headEnc:S.headEnc,headEncHash:H}}if(I+=1,K&&VW(I,d,k))K({phase:"peek",host:V.label,done:I,total:d});return M}),p=new Set;for(let Q of L){if(!Q.ok){console.error("peek: decrypting item head",Q.stat);continue}let S=x(Q.headEncHash);if(await X.messages.has(Q.headEncHash)){console.info("peek: local msg; skip download, deq upload"),await X.uploads.deq(V.label,[Q.headEncHash]),await X.downloads.deq(V.label,[Q.seq]);continue}if(p.has(S)){await X.downloads.deq(V.label,[Q.seq]);continue}let M=new O(Q.headEnc),[H,B]=M.readStruct(JZ);if(B!==0){console.error("peek: reading item head",B);continue}p.add(S),J.push({kdm:Q.kdm,head:H,seq:Q.seq,host:V.label,headEnc:Q.headEnc,headEncHash:Q.headEncHash})}if(await X.downloads.enq(J),C.length>0){let Q=Math.max(...C.map((S)=>S.seq));await X.hosts.recordStats(V.label,{lastSeq:Q})}if(K)K({phase:"peek",host:V.label,done:d,total:d});return 0}async function xl({conn:Z,store:X,host:W,maxPushBytes:V,onProgress:l}){let K=V??GV,G=await X.uploads.list(W.label),m=G.length,R=0;if(l&&m>0)l({phase:"push",host:W.label,done:0,total:m});let J=[],C=[],F=0,d=async()=>{if(J.length<1)return 0;let k=J.length,T=await SK(Z,X,W.label,J,C);if(J=[],C=[],F=0,T===0){if(R+=k,l)l({phase:"push",host:W.label,done:R,total:m})}return T};for(let k of G){let T=await X.messages.get(k);if(!T){R+=1;continue}let I={...T.head,bod:T.body},[L,p]=await Z.seal(I);if(p!==0)return p;if(!L)return 12;let Q=yK(L);if(J.length>0&&F+Q>K){let S=await d();if(S!==0)return S}if(J.push(L),C.push(k),F+=Q,F>=K){let S=await d();if(S!==0)return S}}return d()}async function RV({conn:Z,store:X,enclave:W,host:V,crypto:l,maxPullBytes:K,onProgress:G},m){let R=K??mV,J=await X.downloads.list(),C=Array.from(J).filter((L)=>L.host===V.label);if(C.length<1)return 15;let F=JX(C,(L)=>L.head),d=Sl(F,(L)=>L.head.len,R),k=F.length,T=0;if(G)G({phase:"pull",host:V.label,done:0,total:k});let I=zl(Z,d[0]);for(let L=0;L<d.length;L++){let[p,Q]=await I;if(Q!==0||!p)return Q;if(T+=d[L].length,G)G({phase:"pull",host:V.label,done:T,total:k});let S=d[L+1];if(S)I=zl(Z,S);if(G)G({phase:"open",host:V.label,done:T,total:k});let c=JX(p,(H)=>H.dl.head),[,M]=await zK(X,W,l,c);if(M!==0)return M;if(m){if(G)G({phase:"exec",host:V.label,done:T,total:k});await m()}}return 0}function Hl({head:Z,body:X}){let W={eid:Z.eid,body:X,apld:SZ};if(Z.off!==0)W.off=Z.off;if(Z.ctr!==0)W.ctr=Z.ctr;return W}async function hl(Z,{conn:X,store:W,enclave:V,host:l,crypto:K,onProgress:G},m){let R=l.label,J=await X.identity(),C=new O(Z),[F,d]=C.readStructs(nX);if(d!==0){console.error("Failed decoding notif",z[d]);return}let k=!1,I=(await W.hosts.get(R))?.lastSeq,L=[],p=!1;for(let c of F){let[M,H]=await KW({seq:c.seq,headCph:c.headCph},J.publicKey,V,K);if(H!==0){console.error("Failed decrypting notif",z[H]);continue}let B=await K.blake3(M.headEnc);if(await W.messages.has(B))continue;let i=new O(M.headEnc),[U,u]=i.readStruct(JZ);if(u!==0){console.error("Failed to parse head",z[u]);continue}if(!c.bodyCph&&U.len>0)p=!0,await W.downloads.enq([{seq:c.seq,host:R,kdm:M.kdm,head:U,headEnc:M.headEnc,headEncHash:B}]);else L.push({...M,head:U,bodyCph:c.bodyCph,headEncHash:B});if(I===void 0||c.seq!==I+1)console.log("out of seq",c.seq,I),k=!0;else I=c.seq}if(I!==void 0)await W.hosts.touch(l.label,I);let Q=[];for(let c of L){let M=V.deriveCipher(c.kdm,"decrypt"),[H,B]=await uW(c.headEnc,c.bodyCph,M,K);if(B!==0){console.error("Failed to open body",z[B]);continue}Q.push({key:c.headEncHash,data:Hl({head:c.head,body:H.bod})})}let S=await W.messages.add(Q);for(let c=0;c<S.length;c++){let M=S[c];if(M!==0&&M!==15)console.error("ERR storing",z[M],"for message",c)}if(G&&Q.length>0)G({phase:"open",host:l.label,done:Q.length,total:Q.length});if(k||p||Q.length>0)m()}async function JV(Z,X={}){let W=X.pull!==!1,V=X.push===!0,{conn:l,store:K,enclave:G,host:m,crypto:R,onProgress:J,peekProgressEvery:C,peekConcurrency:F}=Z,d=await l.identity(),[k,T]=await l.peek(0);if(T!==0)return Y(T);let I=k.length,L=C??CX,p=F??Nl;if(J&&I>0)J({phase:"peek",host:m.label,done:0,total:I});let Q=0,S=await lV(k,p,async(h)=>{let[E,P]=await KW(h,d.publicKey,G,R),A;if(P!==0||!E)A={ok:!1,seq:h.seq,stat:P};else{let g=await R.blake3(E.headEnc);A={ok:!0,seq:h.seq,kdm:E.kdm,headEnc:E.headEnc,headEncHash:g}}if(Q+=1,J&&VW(Q,I,L))J({phase:"peek",host:m.label,done:Q,total:I});return A}),c=new Map;for(let h of S){if(!h.ok)continue;let E=x(h.headEncHash),P=c.get(E);if(P)P.count+=1;else c.set(E,{hash:h.headEncHash,count:1,sample:h})}let M=0,H=[];for(let h of c.values()){if(h.count>1)M+=h.count-1;H.push(h.hash)}let B=k.length,i=c.size,U=await KX(H,R),u=[],D=0;for(let h of c.values()){if(await K.messages.has(h.hash)){await K.uploads.deq(m.label,[h.hash]);continue}if(D+=1,!W)continue;let P=h.sample,A=new O(P.headEnc),[g,_]=A.readStruct(JZ);if(_!==0){console.error("reconcile: reading msg header",_);continue}u.push({kdm:P.kdm,head:g,seq:P.seq,host:m.label,headEnc:P.headEnc,headEncHash:P.headEncHash})}if(u.length>0)await K.downloads.enq(u);let y=0;if(V){let h=await K.messages.listKeys(),E=new Set(c.keys()),P=[];for(let A of h)if(!E.has(x(A)))y+=1,P.push(A);if(P.length>0)await K.uploads.enq(m.label,P)}else{let h=await K.messages.listKeys(),E=new Set(c.keys());for(let P of h)if(!E.has(x(P)))y+=1}let q=k.length>0?Math.max(...k.map((h)=>h.seq)):0;if(await K.hosts.recordStats(m.label,{setLastSeq:q}),J)J({phase:"peek",host:m.label,done:I,total:I});return b({msgcheck:U,numBags:B,uniqueMsgs:i,numDupes:M,missingLocal:D,missingHost:y})}class bX{clock;state;store;transport;crypto;forceSkewHandlingByDefault;onScheduleSync;connections=new Map;applyChain=Promise.resolve();syncRuns=new XW;clientState;xferState;maxPushBytes;maxPullBytes;peekProgressEvery=CX;lastProgress=$Z;scheduledSync;constructor(Z,X,W,V,l,K=!0,G=GV,m=mV,R){this.clock=Z;this.state=X;this.store=W;this.transport=V;this.crypto=l;this.forceSkewHandlingByDefault=K;this.onScheduleSync=R;this.maxPushBytes=G,this.maxPullBytes=m,this.clientState=new TZ(()=>this.getClientState()),this.xferState=new TZ(()=>this.getXferState()),this.scheduledSync=new xX(WW,async()=>{try{console.info("Running scheduled sync"),await this.sync()}catch(J){console.error("Debounced sync failed:",J)}})}emitProgress=(Z)=>{this.lastProgress=Z,this.xferState.emit()};async setSeed(Z,X){await this.store.seed.save(Z,X),this.clientState.emit()}async getClientState(){let{store:Z,connections:X}=this,W=await Z.seed.load(),V=await Z.hosts.list(),l=!1;for(let K of X.values())if(K.isConnected()){l=!0;break}return{hasSeed:W!==void 0,hasHost:Array.from(V).length>0,connected:l}}async getXferState(){let{uploads:Z,downloads:X}=this.store,W=await Z.count();return{numDownloads:await X.count(),numUploads:W,progress:this.lastProgress}}apply=(Z,X)=>{return this.enqueueApplyJob(()=>this.doApply(Z,X))};async doApply(Z,X={enqueueUpload:!0,triggerUpload:!0}){let W=[],V=[];for(let{head:K,body:G}of Z){let m=new j;m.writeStruct(JZ,K);let R=m.result(),J=await this.crypto.blake3(R),C={eid:K.eid,body:G,apld:SZ};if(K.off!==0)C.off=K.off;if(K.ctr!==0)C.ctr=K.ctr;W.push(J),V.push({key:J,data:C})}await this.store.messages.add(V),await gl(this.store,W,this.crypto);let l=await this.doApplyHashes(W);if(X.enqueueUpload){let K=[];for(let G=0;G<W.length;G++){let m=l[G];if(m===0||m===15)K.push(W[G])}if(K.length>0){let G=await this.store.hosts.list();for(let m of G)await this.store.uploads.enq(m.label,K);this.xferState.emit()}}if(X.triggerUpload)this.scheduleSync();return l}enqueueApplyJob(Z){let X=this.applyChain.then(Z,Z);return this.applyChain=X.then(()=>{return},()=>{return}),X}drainApplyQueue(){return this.enqueueApplyJob(()=>this.doDrainApplyQueue())}async doDrainApplyQueue(){let Z=await this.store.messages.list({apld:SZ});if(Z.length<1)return[];let X=JX(Z,(W)=>W.head);return this.applyStored(X)}applyHashes=(Z)=>{return this.enqueueApplyJob(()=>this.doApplyHashes(Z))};async doApplyHashes(Z){let X=[];for(let l of Z){let K=await this.store.messages.get(l);if(K)X.push(K)}let W=await this.applyStored(X),V=new Map;for(let l=0;l<X.length;l++)V.set(x(X[l].hash),W[l]??12);return Z.map((l)=>V.get(x(l))??13)}async applyStored(Z){if(Z.length<1)return[];let X=Z.map((K)=>({...K.head,bod:K.body})),W=await this.state.apply(X),V=[],l=[];for(let K=0;K<Z.length;K++){let G=W[K];if(G===0||G===15)V.push(Z[K].hash);else if(G!==void 0&&KV(G))l.push({key:Z[K].hash,err:G})}if(V.length>0)await this.store.messages.markApplied(V);if(l.length>0)await this.store.messages.markFailed(l);return W}async insertRaw(Z){let{clock:X,crypto:W}=this,[V,l]=await dl({now:X.now(),bod:Z,crypto:W});if(l!==0)return Y(l);let G=(await this.apply([{head:V,body:Z}]))[0];if(G!==0&&G!==15)return Y(G??12);return b(V)}async makeUpdate(Z,X){let{clock:W,crypto:V}=this,l=W.now();if(Z.updatedAt.getTime()>l.getTime())return Y(4);let K=Z.ctr+1,[G,m]=await rX({now:l,eid:Z.eid,ctr:K,bod:X,crypto:V});if(m!==0)return Y(m);return b({head:G,body:X})}async updateWithSkew(Z,X,W){if(W===!1)return Y(4);let{clock:V,crypto:l}=this,K=V.now(),G=new O(Z.eid),[m,R]=G.readStruct(s);if(R!==0)return Y(R);let J=Z.updatedAt.getTime()-m.ts.getTime(),C={eid:Z.eid,off:J+1,ctr:Z.ctr+1,len:0},d=(await this.apply([{head:C,body:void 0}]))[0];if(d!==0&&d!==15)return Y(d??12);if(X===void 0)return b(C);let[k,T]=lX({id:m.id,ts:K});if(T!==0)return Y(T);let[I,L]=await rX({now:K,eid:k,ctr:0,bod:X,crypto:l});if(L!==0)return Y(L);let Q=(await this.apply([{head:I,body:X}]))[0];if(Q!==0&&Q!==15)return Y(Q??12);return b(I)}async updateRaw(Z,X,W=this.forceSkewHandlingByDefault){if(Z.updatedAt.getTime()>this.clock.now().getTime())return this.updateWithSkew(Z,X,W);return this.enqueueApplyJob(async()=>{let[V,l]=await this.makeUpdate(Z,X);if(l!==0)return Y(l);let G=(await this.doApply([V]))[0];if(G!==0&&G!==15)return Y(G??12);return b(V.head)})}async insert(Z){let{body:X,type:W,gid:V,pid:l,tags:K}=Z,m=vZ({body:X,type:W,gid:V,pid:l,tags:K});return this.insertRaw(m)}async update(Z){let{prior:X,body:W,type:V,gid:l,pid:K,tags:G,force:m}=Z,J=vZ({body:W,type:V,gid:l,pid:K,tags:G});return this.updateRaw(X,J,m??this.forceSkewHandlingByDefault)}async delete(Z){let X=Z.force??!0;if("prior"in Z)return this.updateRaw(Z.prior,void 0,X);let[W,V]=await this.revFromArchive(Z.eid);if(V!==0)return Y(V);return this.updateRaw(W,void 0,X)}async revFromArchive(Z){let X=await this.store.messages.last(Z);if(X)return VV(X.head);let W=new O(Z),[V,l]=W.readStruct(s);if(l!==0)return Y(l);return b({eid:Z,ctr:-1,updatedAt:V.ts})}async genEID(Z){let{clock:X,crypto:W}=this,V=X.now();if(Z!==void 0)return lX({id:Z,ts:V});let l=await W.genRandomBytes(8);return lX({id:l,ts:V})}sync(){return this.syncRuns.run(()=>this.doSync())}async doSync(){let{connections:Z,crypto:X,store:W}=this,V=await W.seed.load();if(!V)return 22;await this.drainApplyQueue();for(let[l,K]of Z){let G=await W.hosts.get(l);if(!G)continue;let m={conn:K,store:W,enclave:V,host:G,crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},R=await YV(m);if(R!==0)return console.error(`Failed to peek: ${R}`),this.emitProgress({phase:"idle"}),R;this.xferState.emit();let J=await xl(m);if(J!==0)return console.error(`Failed to push: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await RV(m,async()=>{await this.drainApplyQueue()});if(C!==0&&C!==15)return console.error(`Failed to pull: ${C}`),this.emitProgress({phase:"idle"}),C;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async rebuild(Z){if(this.scheduledSync.cancel(),await this.syncRuns.flush(),Z?.checkHost??!0){let W=await this.repull();if(W!==0)return W}return this.enqueueApplyJob(()=>this.replay())}async msgcheck(){let Z=await this.store.messages.listKeys();return KX(Z,this.crypto)}listMsgs(Z){return this.store.messages.list(Z)}countMsgs(Z){return this.store.messages.count(Z)}async reconcile(Z,X){this.scheduledSync.cancel(),await this.syncRuns.flush();let{connections:W,crypto:V,store:l}=this,K=await l.seed.load();if(!K)return Y(22);let G=await l.hosts.get(Z);if(!G)return Y(13);let m=W.get(Z);if(!m||!m.isConnected()){if(await this.connectToHost(G,!1,!1),G=await l.hosts.get(Z),!G)return Y(13);m=W.get(Z)}if(!m)return Y(12);let R={conn:m,store:l,enclave:K,crypto:V,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},[J,C]=await JV({...R,host:G},X);if(this.xferState.emit(),C!==0)return this.emitProgress({phase:"idle"}),Y(C);if(!J)return this.emitProgress({phase:"idle"}),Y(12);if(X?.sync===!1)return this.emitProgress({phase:"idle"}),b(J);let F=await this.sync();if(F!==0)return Y(F);let d=await l.hosts.get(Z);if(!d)return Y(13);let[k,T]=await JV({...R,host:d},{pull:!1,push:!1});if(this.xferState.emit(),this.emitProgress({phase:"idle"}),T!==0)return Y(T);if(!k)return Y(12);return b(k)}async repull(){let{connections:Z,crypto:X,store:W}=this,V=await W.seed.load();if(!V)return 22;let l=Array.from(await W.hosts.list());if(l.length<1)return 0;for(let K of l){let G=Z.get(K.label);if(!G||!G.isConnected())await this.connectToHost(K,!1,!1)}for(let[K,G]of Z){let m=await W.hosts.get(K);if(!m)continue;let R={conn:G,store:W,enclave:V,host:{...m,lastSeq:0},crypto:X,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery},J=await YV(R);if(J!==0)return console.error(`rebuild: failed to peek: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await RV(R);if(C!==0&&C!==15)return console.error(`rebuild: failed to pull: ${C}`),this.emitProgress({phase:"idle"}),C;this.xferState.emit()}return this.emitProgress({phase:"idle"}),0}async replay(){let Z=await this.state.clear();if(Z!==0)return Z;let X=await this.store.messages.list(),W=JX(X,(K)=>K.head),V=W.length;if(V<1)return this.emitProgress({phase:"idle"}),0;let l=0;while(l<W.length){let K=0,G=0,m=l;for(let J=l;J<W.length&&G<100&&K<102400;J++)K+=W[J].head.len,G++,m=J+1;let R=W.slice(l,m);await this.applyStored(R),this.emitProgress({phase:"exec",done:m,total:V}),l=m}return this.emitProgress({phase:"idle"}),0}async wipe(Z){let X=Z?.msgs!==!1,W=Z?.ents!==!1,V=Z?.meta!==!1,l=Z?.seed===!0;this.scheduledSync.cancel(),await this.disconnect(),await this.syncRuns.flush();let{store:K}=this;if(V)await K.hosts.wipe(),await K.uploads.wipe(),await K.downloads.wipe();if(X)await K.messages.wipe();if(l)await K.seed.wipe();if(W)await this.state.clear();this.lastProgress=$Z,this.clientState.emit(),this.xferState.emit()}import=async(Z,X)=>{let{crypto:W,store:V}=this,l=X?.onProgress,K=await V.seed.load();if(!K)return 22;console.time("import: decoding file...");let G=await Z.bytes(),[m,R]=await bl(G,W,K);if(R!==0)return R;console.timeEnd("import: decoding file...");let J=0;while(J<m.length){let C=0,F=0,d=J;for(let I=J;I<m.length&&F<100&&C<102400;I++)C+=m[I].head.len,F++,d=I+1;let k=m.slice(J,d);console.time(`import: applying [${J}, ${d}]`);let T=await this.apply(k,{enqueueUpload:!0,triggerUpload:!1});console.timeEnd(`import: applying [${J}, ${d}]`);for(let I=0;I<k.length;I++){let L=T[I];if(L!==0&&L!==15)console.warn(`failed to import msg ${J+I}: ${z[L]}`)}if(l)queueMicrotask(()=>l(d,m.length,0));this.emitProgress({phase:"import",done:d,total:m.length}),J=d}return this.scheduleSync(),this.emitProgress({phase:"idle"}),0};scheduleSync=()=>{if(this.onScheduleSync){this.onScheduleSync();return}this.scheduledSync.schedule()};async exportBytes(){let{crypto:Z,store:X}=this,W=await X.seed.load();if(!W)return Y(22);let V=await X.messages.list();return Fl("export",0,V,Z,W)}async export(Z){let[X,W]=await this.exportBytes();if(W!==0)return W;if(!X)return 12;let V=new Blob([X.slice()]);return lW(V,Z),0}async link(Z,X=!0){if(await this.store.hosts.add(Z),this.clientState.emit(),X){let W=await this.store.hosts.get(Z.label);if(W)await this.connectToHost(W)}}async unlink(Z){await this.store.hosts.del(Z),this.clientState.emit()}async hosts(){return Array.from(await this.store.hosts.list())}connectToHost=async(Z,X=!0,W=!0)=>{let{clock:V,connections:l,crypto:K,store:G,transport:m}=this,R=l.get(Z.label);if(R){if(R.isConnected())return;try{R.closeListener()}catch{}l.delete(Z.label)}let J=await G.seed.load();if(!J)return;console.info(`Connecting to ${Z.handle} (${Z.label})`);let C=new sX(J,K,Z,V,m(Z),(F)=>G.hosts.set(Z.label,F));if(await C.register(),X)await C.listen(async(F)=>{let d={conn:C,store:G,enclave:J,host:Z,crypto:K,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery};return hl(F,d,this.scheduleSync)},()=>this.clientState.emit(),()=>this.clientState.emit());if(l.set(Z.label,C),this.clientState.emit(),W)this.scheduleSync()};async connect(Z=!0,X=!0){let{connectToHost:W,scheduleSync:V,store:l}=this;if(!await l.seed.load())return;await this.drainApplyQueue();let G=await l.hosts.list();for(let m of G)await W(m,Z,!1);if(X)V()}disconnect=async()=>{for(let Z of this.connections.values())try{Z.closeListener()}catch{}this.connections.clear(),this.clientState.emit()}}var fZ=typeof globalThis==="object"&&"crypto"in globalThis?globalThis.crypto:void 0;function GW(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function CV(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function a(Z,...X){if(!CV(Z))throw Error("Uint8Array expected");if(X.length>0&&!X.includes(Z.length))throw Error("Uint8Array expected of length "+X+", got length="+Z.length)}function FV(Z,X=!0){if(Z.destroyed)throw Error("Hash instance has been destroyed");if(X&&Z.finished)throw Error("Hash#digest() has already been called")}function Ul(Z,X){a(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function bV(Z){if(typeof Z!=="boolean")throw Error(`boolean expected, not ${Z}`)}/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */var zZ=(Z)=>new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4));var NK=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!NK)throw Error("Non little-endian hardware is not supported");function MK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function mW(Z){if(typeof Z==="string")Z=MK(Z);else if(CV(Z))Z=YW(Z);else throw Error("Uint8Array expected, got "+typeof Z);return Z}function Pl(Z,X){if(X==null||typeof X!=="object")throw Error("options must be defined");return Object.assign(Z,X)}function Ol(Z,X){if(Z.length!==X.length)return!1;let W=0;for(let V=0;V<Z.length;V++)W|=Z[V]^X[V];return W===0}var il=(Z,X)=>{function W(V,...l){if(a(V),Z.nonceLength!==void 0){let C=l[0];if(!C)throw Error("nonce / iv required");if(Z.varSizeNonce)a(C);else a(C,Z.nonceLength)}let K=Z.tagLength;if(K&&l[1]!==void 0)a(l[1]);let G=X(V,...l),m=(C,F)=>{if(F!==void 0){if(C!==2)throw Error("cipher output not supported");a(F)}},R=!1;return{encrypt(C,F){if(R)throw Error("cannot encrypt() twice with same key + nonce");return R=!0,a(C),m(G.encrypt.length,F),G.encrypt(C,F)},decrypt(C,F){if(a(C),K&&C.length<K)throw Error("invalid ciphertext length: smaller than tagLength="+K);return m(G.decrypt.length,F),G.decrypt(C,F)}}}return Object.assign(W,Z),W};function dV(Z,X,W=!0){if(X===void 0)return new Uint8Array(Z);if(X.length!==Z)throw Error("invalid output length, expected "+Z+", got: "+X.length);if(W&&!gK(X))throw Error("invalid output, must be aligned");return X}function gK(Z){return Z.byteOffset%4===0}function YW(Z){return Uint8Array.from(Z)}function cZ(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function HX(Z=32){if(fZ&&typeof fZ.getRandomValues==="function")return fZ.getRandomValues(new Uint8Array(Z));if(fZ&&typeof fZ.randomBytes==="function")return fZ.randomBytes(Z);throw Error("crypto.getRandomValues must be defined")}var Bl=(Z)=>Uint8Array.from(Z.split("").map((X)=>X.charCodeAt(0))),xK=Bl("expand 16-byte k"),HK=Bl("expand 32-byte k"),hK=zZ(xK),UK=zZ(HK);function N(Z,X){return Z<<X|Z>>>32-X}function kV(Z){return Z.byteOffset%4===0}var RW=64,PK=16,El=4294967295,jl=new Uint32Array;function OK(Z,X,W,V,l,K,G,m){let R=l.length,J=new Uint8Array(RW),C=zZ(J),F=kV(l)&&kV(K),d=F?zZ(l):jl,k=F?zZ(K):jl;for(let T=0;T<R;G++){if(Z(X,W,V,C,G,m),G>=El)throw Error("arx: counter overflow");let I=Math.min(RW,R-T);if(F&&I===RW){let L=T/4;if(T%4!==0)throw Error("arx: invalid block position");for(let p=0,Q;p<PK;p++)Q=L+p,k[Q]=d[Q]^C[p];T+=RW;continue}for(let L=0,p;L<I;L++)p=T+L,K[p]=l[p]^J[L];T+=I}}function ul(Z,X){let{allowShortKeys:W,extendNonceFn:V,counterLength:l,counterRight:K,rounds:G}=Pl({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},X);if(typeof Z!=="function")throw Error("core must be a function");return GW(l),GW(G),bV(K),bV(W),(m,R,J,C,F=0)=>{a(m),a(R),a(J);let d=J.length;if(C===void 0)C=new Uint8Array(d);if(a(C),GW(F),F<0||F>=El)throw Error("arx: counter overflow");if(C.length<d)throw Error(`arx: output (${C.length}) is shorter than data (${d})`);let k=[],T=m.length,I,L;if(T===32)k.push(I=YW(m)),L=UK;else if(T===16&&W)I=new Uint8Array(32),I.set(m),I.set(m,16),L=hK,k.push(I);else throw Error(`arx: invalid 32-byte key, got length=${T}`);if(!kV(R))k.push(R=YW(R));let p=zZ(I);if(V){if(R.length!==24)throw Error("arx: extended nonce must be 24 bytes");V(L,p,zZ(R.subarray(0,16)),p),R=R.subarray(16)}let Q=16-l;if(Q!==R.length)throw Error(`arx: nonce must be ${Q} or 16 bytes`);if(Q!==12){let c=new Uint8Array(12);c.set(R,K?0:12-R.length),R=c,k.push(R)}let S=zZ(R);return OK(Z,L,p,S,J,C,F,G),cZ(...k),C}}var t=(Z,X)=>Z[X++]&255|(Z[X++]&255)<<8;class wl{constructor(Z){this.blockLen=16,this.outputLen=16,this.buffer=new Uint8Array(16),this.r=new Uint16Array(10),this.h=new Uint16Array(10),this.pad=new Uint16Array(8),this.pos=0,this.finished=!1,Z=mW(Z),a(Z,32);let X=t(Z,0),W=t(Z,2),V=t(Z,4),l=t(Z,6),K=t(Z,8),G=t(Z,10),m=t(Z,12),R=t(Z,14);this.r[0]=X&8191,this.r[1]=(X>>>13|W<<3)&8191,this.r[2]=(W>>>10|V<<6)&7939,this.r[3]=(V>>>7|l<<9)&8191,this.r[4]=(l>>>4|K<<12)&255,this.r[5]=K>>>1&8190,this.r[6]=(K>>>14|G<<2)&8191,this.r[7]=(G>>>11|m<<5)&8065,this.r[8]=(m>>>8|R<<8)&8191,this.r[9]=R>>>5&127;for(let J=0;J<8;J++)this.pad[J]=t(Z,16+2*J)}process(Z,X,W=!1){let V=W?0:2048,{h:l,r:K}=this,G=K[0],m=K[1],R=K[2],J=K[3],C=K[4],F=K[5],d=K[6],k=K[7],T=K[8],I=K[9],L=t(Z,X+0),p=t(Z,X+2),Q=t(Z,X+4),S=t(Z,X+6),c=t(Z,X+8),M=t(Z,X+10),H=t(Z,X+12),B=t(Z,X+14),i=l[0]+(L&8191),U=l[1]+((L>>>13|p<<3)&8191),u=l[2]+((p>>>10|Q<<6)&8191),D=l[3]+((Q>>>7|S<<9)&8191),y=l[4]+((S>>>4|c<<12)&8191),q=l[5]+(c>>>1&8191),h=l[6]+((c>>>14|M<<2)&8191),E=l[7]+((M>>>11|H<<5)&8191),P=l[8]+((H>>>8|B<<8)&8191),A=l[9]+(B>>>5|V),g=0,_=g+i*G+U*(5*I)+u*(5*T)+D*(5*k)+y*(5*d);g=_>>>13,_&=8191,_+=q*(5*F)+h*(5*C)+E*(5*J)+P*(5*R)+A*(5*m),g+=_>>>13,_&=8191;let XZ=g+i*m+U*G+u*(5*I)+D*(5*T)+y*(5*k);g=XZ>>>13,XZ&=8191,XZ+=q*(5*d)+h*(5*F)+E*(5*C)+P*(5*J)+A*(5*R),g+=XZ>>>13,XZ&=8191;let mZ=g+i*R+U*m+u*G+D*(5*I)+y*(5*T);g=mZ>>>13,mZ&=8191,mZ+=q*(5*k)+h*(5*d)+E*(5*F)+P*(5*C)+A*(5*J),g+=mZ>>>13,mZ&=8191;let f=g+i*J+U*R+u*m+D*G+y*(5*I);g=f>>>13,f&=8191,f+=q*(5*T)+h*(5*k)+E*(5*d)+P*(5*F)+A*(5*C),g+=f>>>13,f&=8191;let pZ=g+i*C+U*J+u*R+D*m+y*G;g=pZ>>>13,pZ&=8191,pZ+=q*(5*I)+h*(5*T)+E*(5*k)+P*(5*d)+A*(5*F),g+=pZ>>>13,pZ&=8191;let sZ=g+i*F+U*C+u*J+D*R+y*m;g=sZ>>>13,sZ&=8191,sZ+=q*G+h*(5*I)+E*(5*T)+P*(5*k)+A*(5*d),g+=sZ>>>13,sZ&=8191;let rZ=g+i*d+U*F+u*C+D*J+y*R;g=rZ>>>13,rZ&=8191,rZ+=q*m+h*G+E*(5*I)+P*(5*T)+A*(5*k),g+=rZ>>>13,rZ&=8191;let tZ=g+i*k+U*d+u*F+D*C+y*J;g=tZ>>>13,tZ&=8191,tZ+=q*R+h*m+E*G+P*(5*I)+A*(5*T),g+=tZ>>>13,tZ&=8191;let eZ=g+i*T+U*k+u*d+D*F+y*C;g=eZ>>>13,eZ&=8191,eZ+=q*J+h*R+E*m+P*G+A*(5*I),g+=eZ>>>13,eZ&=8191;let ZX=g+i*I+U*T+u*k+D*d+y*F;g=ZX>>>13,ZX&=8191,ZX+=q*C+h*J+E*R+P*m+A*G,g+=ZX>>>13,ZX&=8191,g=(g<<2)+g|0,g=g+_|0,_=g&8191,g=g>>>13,XZ+=g,l[0]=_,l[1]=XZ,l[2]=mZ,l[3]=f,l[4]=pZ,l[5]=sZ,l[6]=rZ,l[7]=tZ,l[8]=eZ,l[9]=ZX}finalize(){let{h:Z,pad:X}=this,W=new Uint16Array(10),V=Z[1]>>>13;Z[1]&=8191;for(let G=2;G<10;G++)Z[G]+=V,V=Z[G]>>>13,Z[G]&=8191;Z[0]+=V*5,V=Z[0]>>>13,Z[0]&=8191,Z[1]+=V,V=Z[1]>>>13,Z[1]&=8191,Z[2]+=V,W[0]=Z[0]+5,V=W[0]>>>13,W[0]&=8191;for(let G=1;G<10;G++)W[G]=Z[G]+V,V=W[G]>>>13,W[G]&=8191;W[9]-=8192;let l=(V^1)-1;for(let G=0;G<10;G++)W[G]&=l;l=~l;for(let G=0;G<10;G++)Z[G]=Z[G]&l|W[G];Z[0]=(Z[0]|Z[1]<<13)&65535,Z[1]=(Z[1]>>>3|Z[2]<<10)&65535,Z[2]=(Z[2]>>>6|Z[3]<<7)&65535,Z[3]=(Z[3]>>>9|Z[4]<<4)&65535,Z[4]=(Z[4]>>>12|Z[5]<<1|Z[6]<<14)&65535,Z[5]=(Z[6]>>>2|Z[7]<<11)&65535,Z[6]=(Z[7]>>>5|Z[8]<<8)&65535,Z[7]=(Z[8]>>>8|Z[9]<<5)&65535;let K=Z[0]+X[0];Z[0]=K&65535;for(let G=1;G<8;G++)K=(Z[G]+X[G]|0)+(K>>>16)|0,Z[G]=K&65535;cZ(W)}update(Z){FV(this);let{buffer:X,blockLen:W}=this;Z=mW(Z);let V=Z.length;for(let l=0;l<V;){let K=Math.min(W-this.pos,V-l);if(K===W){for(;W<=V-l;l+=W)this.process(Z,l);continue}if(X.set(Z.subarray(l,l+K),this.pos),this.pos+=K,l+=K,this.pos===W)this.process(X,0,!1),this.pos=0}return this}destroy(){cZ(this.h,this.r,this.buffer,this.pad)}digestInto(Z){FV(this),Ul(Z,this),this.finished=!0;let{buffer:X,h:W}=this,{pos:V}=this;if(V){X[V++]=1;for(;V<16;V++)X[V]=0;this.process(X,0,!0)}this.finalize();let l=0;for(let K=0;K<8;K++)Z[l++]=W[K]>>>0,Z[l++]=W[K]>>>8;return Z}digest(){let{buffer:Z,outputLen:X}=this;this.digestInto(Z);let W=Z.slice(0,X);return this.destroy(),W}}function iK(Z){let X=(V,l)=>Z(l).update(mW(V)).digest(),W=Z(new Uint8Array(32));return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var TV=iK((Z)=>new wl(Z));function jK(Z,X,W,V,l,K=20){let G=Z[0],m=X[0],R=X[1],J=X[2],C=X[3],F=Z[1],d=W[0],k=W[1],T=l,I=0,L=Z[2],p=X[4],Q=X[5],S=X[6],c=X[7],M=Z[3],H=G,B=m,i=R,U=J,u=C,D=F,y=d,q=k,h=T,E=I,P=L,A=p,g=Q,_=S,XZ=c,mZ=M;for(let pZ=0;pZ<K;pZ+=2)u^=N(H+g|0,7),h^=N(u+H|0,9),g^=N(h+u|0,13),H^=N(g+h|0,18),E^=N(D+B|0,7),_^=N(E+D|0,9),B^=N(_+E|0,13),D^=N(B+_|0,18),XZ^=N(P+y|0,7),i^=N(XZ+P|0,9),y^=N(i+XZ|0,13),P^=N(y+i|0,18),U^=N(mZ+A|0,7),q^=N(U+mZ|0,9),A^=N(q+U|0,13),mZ^=N(A+q|0,18),B^=N(H+U|0,7),i^=N(B+H|0,9),U^=N(i+B|0,13),H^=N(U+i|0,18),y^=N(D+u|0,7),q^=N(y+D|0,9),u^=N(q+y|0,13),D^=N(u+q|0,18),A^=N(P+E|0,7),h^=N(A+P|0,9),E^=N(h+A|0,13),P^=N(E+h|0,18),g^=N(mZ+XZ|0,7),_^=N(g+mZ|0,9),XZ^=N(_+g|0,13),mZ^=N(XZ+_|0,18);let f=0;V[f++]=G+H|0,V[f++]=m+B|0,V[f++]=R+i|0,V[f++]=J+U|0,V[f++]=C+u|0,V[f++]=F+D|0,V[f++]=d+y|0,V[f++]=k+q|0,V[f++]=T+h|0,V[f++]=I+E|0,V[f++]=L+P|0,V[f++]=p+A|0,V[f++]=Q+g|0,V[f++]=S+_|0,V[f++]=c+XZ|0,V[f++]=M+mZ|0}function BK(Z,X,W,V){let l=Z[0],K=X[0],G=X[1],m=X[2],R=X[3],J=Z[1],C=W[0],F=W[1],d=W[2],k=W[3],T=Z[2],I=X[4],L=X[5],p=X[6],Q=X[7],S=Z[3];for(let M=0;M<20;M+=2)R^=N(l+L|0,7),d^=N(R+l|0,9),L^=N(d+R|0,13),l^=N(L+d|0,18),k^=N(J+K|0,7),p^=N(k+J|0,9),K^=N(p+k|0,13),J^=N(K+p|0,18),Q^=N(T+C|0,7),G^=N(Q+T|0,9),C^=N(G+Q|0,13),T^=N(C+G|0,18),m^=N(S+I|0,7),F^=N(m+S|0,9),I^=N(F+m|0,13),S^=N(I+F|0,18),K^=N(l+m|0,7),G^=N(K+l|0,9),m^=N(G+K|0,13),l^=N(m+G|0,18),C^=N(J+R|0,7),F^=N(C+J|0,9),R^=N(F+C|0,13),J^=N(R+F|0,18),I^=N(T+k|0,7),d^=N(I+T|0,9),k^=N(d+I|0,13),T^=N(k+d|0,18),L^=N(S+Q|0,7),p^=N(L+S|0,9),Q^=N(p+L|0,13),S^=N(Q+p|0,18);let c=0;V[c++]=l,V[c++]=J,V[c++]=T,V[c++]=S,V[c++]=C,V[c++]=F,V[c++]=d,V[c++]=k}var IV=ul(jK,{counterRight:!0,extendNonceFn:BK}),LV=il({blockSize:64,nonceLength:24,tagLength:16},(Z,X)=>{return{encrypt(W,V){V=dV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32);V.set(W,32),cZ(l),IV(Z,X,V,V);let G=TV(K,l);return V.set(G,16),cZ(V.subarray(0,16),G),V.subarray(16)},decrypt(W,V){a(W),V=dV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32,48),G=V.subarray(48);V.set(W,32),cZ(l);let m=IV(Z,X,l,l),R=TV(G,m);if(!Ol(K,R))throw Error("invalid tag");return IV(Z,X,V.subarray(16),V.subarray(16)),cZ(l,K,R),G}}});/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function EK(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function hX(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function oZ(Z,...X){if(!EK(Z))throw Error("Uint8Array expected");if(X.length>0&&!X.includes(Z.length))throw Error("Uint8Array expected of length "+X+", got length="+Z.length)}function UX(Z,X=!0){if(Z.destroyed)throw Error("Hash instance has been destroyed");if(X&&Z.finished)throw Error("Hash#digest() has already been called")}function JW(Z,X){oZ(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function Dl(Z){return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength)}function dX(Z){return new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4))}function kX(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function PX(Z,X){return Z<<32-X|Z>>>X}var Al=(()=>new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68)();function vl(Z){return Z<<24&4278190080|Z<<8&16711680|Z>>>8&65280|Z>>>24&255}var $l=Al?(Z)=>Z:(Z)=>vl(Z);function uK(Z){for(let X=0;X<Z.length;X++)Z[X]=vl(Z[X]);return Z}var lZ=Al?(Z)=>Z:uK;function wK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function TX(Z){if(typeof Z==="string")Z=wK(Z);return oZ(Z),Z}class cV{}function ql(Z){let X=(V,l)=>Z(l).update(TX(V)).digest(),W=Z({});return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var fl=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var CW=BigInt(4294967295),ol=BigInt(32);function QV(Z,X=!1){if(X)return{h:Number(Z&CW),l:Number(Z>>ol&CW)};return{h:Number(Z>>ol&CW)|0,l:Number(Z&CW)|0}}function NZ(Z,X,W,V,l){return Z=Z+X+l|0,V=PX(V^Z,16),W=W+V|0,X=PX(X^W,12),{a:Z,b:X,c:W,d:V}}function MZ(Z,X,W,V,l){return Z=Z+X+l|0,V=PX(V^Z,8),W=W+V|0,X=PX(X^W,7),{a:Z,b:X,c:W,d:V}}class pV extends cV{constructor(Z,X){super();this.finished=!1,this.destroyed=!1,this.length=0,this.pos=0,hX(Z),hX(X),this.blockLen=Z,this.outputLen=X,this.buffer=new Uint8Array(Z),this.buffer32=dX(this.buffer)}update(Z){UX(this),Z=TX(Z),oZ(Z);let{blockLen:X,buffer:W,buffer32:V}=this,l=Z.length,K=Z.byteOffset,G=Z.buffer;for(let m=0;m<l;){if(this.pos===X)lZ(V),this.compress(V,0,!1),lZ(V),this.pos=0;let R=Math.min(X-this.pos,l-m),J=K+m;if(R===X&&!(J%4)&&m+R<l){let C=new Uint32Array(G,J,Math.floor((l-m)/4));lZ(C);for(let F=0;m+X<l;F+=V.length,m+=X)this.length+=X,this.compress(C,F,!1);lZ(C);continue}W.set(Z.subarray(m,m+R),this.pos),this.pos+=R,this.length+=R,m+=R}return this}digestInto(Z){UX(this),JW(Z,this);let{pos:X,buffer32:W}=this;this.finished=!0,kX(this.buffer.subarray(X)),lZ(W),this.compress(W,0,!0),lZ(W);let V=dX(Z);this.get().forEach((l,K)=>V[K]=$l(l))}digest(){let{buffer:Z,outputLen:X}=this;this.digestInto(Z);let W=Z.slice(0,X);return this.destroy(),W}_cloneInto(Z){let{buffer:X,length:W,finished:V,destroyed:l,outputLen:K,pos:G}=this;return Z||(Z=new this.constructor({dkLen:K})),Z.set(...this.get()),Z.buffer.set(X),Z.destroyed=l,Z.finished=V,Z.length=W,Z.pos=G,Z.outputLen=K,Z}clone(){return this._cloneInto()}}function yV(Z,X,W,V,l,K,G,m,R,J,C,F,d,k,T,I,L,p,Q,S){let c=0;for(let M=0;M<V;M++)({a:l,b:R,c:d,d:L}=NZ(l,R,d,L,W[X+Z[c++]])),{a:l,b:R,c:d,d:L}=MZ(l,R,d,L,W[X+Z[c++]]),{a:K,b:J,c:k,d:p}=NZ(K,J,k,p,W[X+Z[c++]]),{a:K,b:J,c:k,d:p}=MZ(K,J,k,p,W[X+Z[c++]]),{a:G,b:C,c:T,d:Q}=NZ(G,C,T,Q,W[X+Z[c++]]),{a:G,b:C,c:T,d:Q}=MZ(G,C,T,Q,W[X+Z[c++]]),{a:m,b:F,c:I,d:S}=NZ(m,F,I,S,W[X+Z[c++]]),{a:m,b:F,c:I,d:S}=MZ(m,F,I,S,W[X+Z[c++]]),{a:l,b:J,c:T,d:S}=NZ(l,J,T,S,W[X+Z[c++]]),{a:l,b:J,c:T,d:S}=MZ(l,J,T,S,W[X+Z[c++]]),{a:K,b:C,c:I,d:L}=NZ(K,C,I,L,W[X+Z[c++]]),{a:K,b:C,c:I,d:L}=MZ(K,C,I,L,W[X+Z[c++]]),{a:G,b:F,c:d,d:p}=NZ(G,F,d,p,W[X+Z[c++]]),{a:G,b:F,c:d,d:p}=MZ(G,F,d,p,W[X+Z[c++]]),{a:m,b:R,c:k,d:Q}=NZ(m,R,k,Q,W[X+Z[c++]]),{a:m,b:R,c:k,d:Q}=MZ(m,R,k,Q,W[X+Z[c++]]);return{v0:l,v1:K,v2:G,v3:m,v4:R,v5:J,v6:C,v7:F,v8:d,v9:k,v10:T,v11:I,v12:L,v13:p,v14:Q,v15:S}}var QZ={CHUNK_START:1,CHUNK_END:2,PARENT:4,ROOT:8,KEYED_HASH:16,DERIVE_KEY_CONTEXT:32,DERIVE_KEY_MATERIAL:64},gZ=fl.slice(),nl=(()=>{let Z=Array.from({length:16},(V,l)=>l),X=(V)=>[2,6,3,10,7,0,4,13,1,11,12,5,9,14,15,8].map((l)=>V[l]),W=[];for(let V=0,l=Z;V<7;V++,l=X(l))W.push(...l);return Uint8Array.from(W)})();class SV extends pV{constructor(Z={},X=0){super(64,Z.dkLen===void 0?32:Z.dkLen);this.chunkPos=0,this.chunksDone=0,this.flags=0,this.stack=[],this.posOut=0,this.bufferOut32=new Uint32Array(16),this.chunkOut=0,this.enableXOF=!0;let{key:W,context:V}=Z,l=V!==void 0;if(W!==void 0){if(l)throw Error('Only "key" or "context" can be specified at same time');let K=TX(W).slice();oZ(K,32),this.IV=dX(K),lZ(this.IV),this.flags=X|QZ.KEYED_HASH}else if(l){let K=TX(V),G=new SV({dkLen:32},QZ.DERIVE_KEY_CONTEXT).update(K).digest();this.IV=dX(G),lZ(this.IV),this.flags=X|QZ.DERIVE_KEY_MATERIAL}else this.IV=gZ.slice(),this.flags=X;this.state=this.IV.slice(),this.bufferOut=Dl(this.bufferOut32)}get(){return[]}set(){}b2Compress(Z,X,W,V=0){let{state:l,pos:K}=this,{h:G,l:m}=QV(BigInt(Z),!0),{v0:R,v1:J,v2:C,v3:F,v4:d,v5:k,v6:T,v7:I,v8:L,v9:p,v10:Q,v11:S,v12:c,v13:M,v14:H,v15:B}=yV(nl,V,W,7,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],gZ[0],gZ[1],gZ[2],gZ[3],G,m,K,X);l[0]=R^L,l[1]=J^p,l[2]=C^Q,l[3]=F^S,l[4]=d^c,l[5]=k^M,l[6]=T^H,l[7]=I^B}compress(Z,X=0,W=!1){let V=this.flags;if(!this.chunkPos)V|=QZ.CHUNK_START;if(this.chunkPos===15||W)V|=QZ.CHUNK_END;if(!W)this.pos=this.blockLen;if(this.b2Compress(this.chunksDone,V,Z,X),this.chunkPos+=1,this.chunkPos===16||W){let l=this.state;this.state=this.IV.slice();for(let K,G=this.chunksDone+1;W||!(G&1);G>>=1){if(!(K=this.stack.pop()))break;this.buffer32.set(K,0),this.buffer32.set(l,8),this.pos=this.blockLen,this.b2Compress(0,this.flags|QZ.PARENT,this.buffer32,0),l=this.state,this.state=this.IV.slice()}this.chunksDone++,this.chunkPos=0,this.stack.push(l)}this.pos=0}_cloneInto(Z){Z=super._cloneInto(Z);let{IV:X,flags:W,state:V,chunkPos:l,posOut:K,chunkOut:G,stack:m,chunksDone:R}=this;return Z.state.set(V.slice()),Z.stack=m.map((J)=>Uint32Array.from(J)),Z.IV.set(X),Z.flags=W,Z.chunkPos=l,Z.chunksDone=R,Z.posOut=K,Z.chunkOut=G,Z.enableXOF=this.enableXOF,Z.bufferOut32.set(this.bufferOut32),Z}destroy(){this.destroyed=!0,kX(this.state,this.buffer32,this.IV,this.bufferOut32),kX(...this.stack)}b2CompressOut(){let{state:Z,pos:X,flags:W,buffer32:V,bufferOut32:l}=this,{h:K,l:G}=QV(BigInt(this.chunkOut++));lZ(V);let{v0:m,v1:R,v2:J,v3:C,v4:F,v5:d,v6:k,v7:T,v8:I,v9:L,v10:p,v11:Q,v12:S,v13:c,v14:M,v15:H}=yV(nl,0,V,7,Z[0],Z[1],Z[2],Z[3],Z[4],Z[5],Z[6],Z[7],gZ[0],gZ[1],gZ[2],gZ[3],G,K,X,W);l[0]=m^I,l[1]=R^L,l[2]=J^p,l[3]=C^Q,l[4]=F^S,l[5]=d^c,l[6]=k^M,l[7]=T^H,l[8]=Z[0]^I,l[9]=Z[1]^L,l[10]=Z[2]^p,l[11]=Z[3]^Q,l[12]=Z[4]^S,l[13]=Z[5]^c,l[14]=Z[6]^M,l[15]=Z[7]^H,lZ(V),lZ(l),this.posOut=0}finish(){if(this.finished)return;this.finished=!0,kX(this.buffer.subarray(this.pos));let Z=this.flags|QZ.ROOT;if(this.stack.length)Z|=QZ.PARENT,lZ(this.buffer32),this.compress(this.buffer32,0,!0),lZ(this.buffer32),this.chunksDone=0,this.pos=this.blockLen;else Z|=(!this.chunkPos?QZ.CHUNK_START:0)|QZ.CHUNK_END;this.flags=Z,this.b2CompressOut()}writeInto(Z){UX(this,!1),oZ(Z),this.finish();let{blockLen:X,bufferOut:W}=this;for(let V=0,l=Z.length;V<l;){if(this.posOut>=X)this.b2CompressOut();let K=Math.min(X-this.posOut,l-V);Z.set(W.subarray(this.posOut,this.posOut+K),V),this.posOut+=K,V+=K}return Z}xofInto(Z){if(!this.enableXOF)throw Error("XOF is not possible after digest call");return this.writeInto(Z)}xof(Z){return hX(Z),this.xofInto(new Uint8Array(Z))}digestInto(Z){if(JW(Z,this),this.finished)throw Error("digest() was already called");return this.enableXOF=!1,this.writeInto(Z),this.destroy(),Z}digest(){return this.digestInto(new Uint8Array(this.outputLen))}}var _l=ql((Z)=>new SV(Z));var DK=32,v5=Symbol("X25519Sk");function al(Z){if(Z.byteLength!==DK)return Y(10);return b(Z)}var w=(1n<<255n)-19n,AK=121665n,sl=new Uint8Array(32);sl[0]=9;function rl(Z){let X=0n;for(let W=Z.length-1;W>=0;W--)X=X<<8n|BigInt(Z[W]);return X}function vK(Z){let X=new Uint8Array(32),W=(Z%w+w)%w;for(let V=0;V<32;V++)X[V]=Number(W&0xffn),W>>=8n;return X}function $K(Z){let X=Z.slice();return X[31]&=127,rl(X)}function qK(Z){let X=Z.slice();return X[0]&=248,X[31]&=127,X[31]|=64,X}function FW(Z,X,W){let V=-Z,l=(X^W)&V;return[X^l,W^l]}function fK(Z){let X=w-2n,W=(Z%w+w)%w,V=1n;while(X>0n){if(X&1n)V=V*W%w;W=W*W%w,X>>=1n}return V}function oK(Z,X){let W=qK(Z),V=$K(X),l=1n,K=0n,G=V,m=1n,R=0n,J=rl(W);for(let C=254;C>=0;C--){let F=J>>BigInt(C)&1n;R^=F,[l,G]=FW(R,l,G),[K,m]=FW(R,K,m),R=F;let d=(l+K)%w,k=d*d%w,T=(l-K+w)%w,I=T*T%w,L=(k-I+w)%w,p=(G+m)%w,S=(G-m+w)%w*d%w,c=p*T%w,M=(S+c)%w,H=(S-c+w)%w;G=M*M%w,m=V*H*H%w,l=k*I%w,K=L*(k+AK*L)%w}return[l,G]=FW(R,l,G),[K,m]=FW(R,K,m),W.fill(0),vK(l*fK(K)%w)}function tl(Z){return oK(Z,sl)}var zV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function el(Z){let X=new Uint8Array(zV.length+32);return X.set(zV),X.set(Z.subarray(0,32),zV.length),X}var NV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,110,4,34,4,32]);function Z0(Z){let X=new Uint8Array(NV.length+32);return X.set(NV),X.set(Z.subarray(0,32),NV.length),X}function X0(Z){return typeof Z==="string"?new TextEncoder().encode(Z):Z}function xZ(Z){let X=new ArrayBuffer(Z.byteLength);return new Uint8Array(X).set(Z),X}class nZ{verifyKeys=new Map;async genRandomBytes(Z){return HX(Z)}async gen256BitSecureRandomSeed(){return HX(32)}async encryptXSalsa20Poly1305Combined(Z,X){let W=HX(24),l=LV(X,W).encrypt(Z);return new Uint8Array([...W,...l])}async decryptXSalsa20Poly1305Combined(Z,X){let W=Z.slice(0,24),V=Z.slice(24);return LV(X,W).decrypt(V)}async deriveEd25519KeyPair(Z){let X=Z,W=el(X),V=xZ(W),l;try{let J=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!0,["sign"]);l=await globalThis.crypto.subtle.exportKey("jwk",J)}finally{W.fill(0),new Uint8Array(V).fill(0)}if(typeof l.x!=="string")throw Error("Ed25519 JWK missing x");let K=l.x;l.d=void 0;let G=await globalThis.crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:K},{name:"Ed25519"},!0,["verify"]),m=new Uint8Array(await globalThis.crypto.subtle.exportKey("raw",G));this.verifyKeys.set(YZ(m),G);let R=new Uint8Array(64);return R.set(X,0),R.set(m,32),{keyType:"ed25519",privateKey:R,publicKey:m}}async importSignKey(Z){let X=Z.subarray(0,32),W=el(X),V=xZ(W);try{return await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"Ed25519"},!1,["sign"])}finally{W.fill(0),new Uint8Array(V).fill(0)}}async importVerifyKey(Z){let X=YZ(Z),W=this.verifyKeys.get(X);if(W)return W;let V=await globalThis.crypto.subtle.importKey("raw",xZ(Z),{name:"Ed25519"},!1,["verify"]);return this.verifyKeys.set(X,V),V}async signEd25519(Z,X){let W=X0(Z),V=await this.importSignKey(X),l=await globalThis.crypto.subtle.sign({name:"Ed25519"},V,xZ(W));return new Uint8Array(l)}async checkSigEd25519(Z,X,W){let V=X0(X);try{let l=await this.importVerifyKey(W);return await globalThis.crypto.subtle.verify({name:"Ed25519"},l,xZ(Z),xZ(V))}catch{return!1}}async blake3(Z){return _l(Z)}async genX25519(){let Z=await HX(32);Z[0]&=248,Z[31]&=127,Z[31]|=64;let[X,W]=al(Z);if(W!==0||X===void 0)throw Z.fill(0),Error("X25519 scalar brand failed");let V=tl(X),l=Z0(X),K=xZ(l);try{let G=await globalThis.crypto.subtle.importKey("pkcs8",K,{name:"X25519"},!0,["deriveBits"]),m=await globalThis.crypto.subtle.exportKey("jwk",G);if(typeof m.x!=="string")throw Error("X25519 JWK missing x");let R=EW(m.x);if(m.d=void 0,!n(R,V))throw Error("X25519 WebCrypto pub != RFC 7748");return{priv:X,pub:V}}catch(G){throw X.fill(0),G}finally{l.fill(0),new Uint8Array(K).fill(0)}}async x25519Shared(Z,X){let W=Z0(Z),V=xZ(W);try{let l=await globalThis.crypto.subtle.importKey("pkcs8",V,{name:"X25519"},!1,["deriveBits"]),K=await globalThis.crypto.subtle.importKey("raw",xZ(X),{name:"X25519"},!1,[]),G=await globalThis.crypto.subtle.deriveBits({name:"X25519",public:K},l,256);return new Uint8Array(G)}finally{W.fill(0),new Uint8Array(V).fill(0)}}}var nK=new nZ,IX=nK;import{useEffect as hW,useState as DV}from"react";class MV{db;constructor(Z){this.db=Z}async enq(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction(CZ,"readwrite"),V=W.objectStore(CZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=`${G.host}:${G.seq}`;V.put(G,m)}})}async deq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(CZ,"readwrite"),l=V.objectStore(CZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=`${Z}:${m}`;l.delete(R)}})}async list(){let X=this.db.transaction(CZ,"readonly").objectStore(CZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async count(){let X=this.db.transaction(CZ,"readonly").objectStore(CZ);return new Promise((W,V)=>{let l=X.count();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(CZ,"readwrite"),X=Z.objectStore(CZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}function W0(Z){return{label:Z.label,handle:new URL(Z.handle),idx:Z.idx,lastSeq:Z.lastSeq||0,clockOffset:Z.clockOffset,subscription:Z.subscription}}function _K(Z,X){let W={...Z};if(X.setLastSeq!==void 0)W.lastSeq=X.setLastSeq;else if(X.lastSeq!==void 0){let V=W.lastSeq||0;if(X.lastSeq>V)W.lastSeq=X.lastSeq}return delete W.numBags,delete W.numDupes,W}class gV{db;constructor(Z){this.db=Z}async add(Z){let X=await this.get(Z.label),W=X!==void 0&&X.handle.href===Z.handle.href&&(X.idx??0)===(Z.idx??0);return this.put({...Z,lastSeq:W?X.lastSeq:0,clockOffset:W?X.clockOffset:void 0,subscription:W?X.subscription:void 0})}async put(Z){let X={...Z,handle:Z.handle.toString(),lastSeq:Z.lastSeq??0},W=this.db.transaction(KZ,"readwrite"),V=W.objectStore(KZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error),V.put(X)})}async touch(Z,X){return this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.db.transaction(KZ,"readwrite"),V=W.objectStore(KZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);let G=V.get(Z);G.onsuccess=()=>{let m=G.result;if(!m)return;V.put(_K(m,X))}})}async get(Z){let W=this.db.transaction(KZ,"readonly").objectStore(KZ);return new Promise((V,l)=>{let K=W.get(Z);K.onsuccess=()=>{let G=K.result;if(!G)V(void 0);else V(W0(G))},K.onerror=()=>l(K.error)})}async set(Z,X){let W=await this.get(Z);if(!W)return 13;try{return await this.put({...W,...X}),0}catch{return 18}}async del(Z){let X=this.db.transaction(KZ,"readwrite"),W=X.objectStore(KZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}async list(){let X=this.db.transaction(KZ,"readonly").objectStore(KZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>{let K=l.result;W(K.map(W0))},l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(KZ,"readwrite"),X=Z.objectStore(KZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}class xV{crypto;db;constructor(Z,X){this.crypto=X;this.db=Z}async add(Z){let X=this.db.transaction($,"readwrite"),W=X.objectStore($);return new Promise((V)=>{if(Z.length===0){V([]);return}let l=Array(Z.length).fill(0);X.oncomplete=()=>V(l),X.onerror=()=>{for(let K=0;K<l.length;K++)l[K]=18;V(l)};for(let K=0;K<Z.length;K++){let{key:G,data:m}=Z[K],R=x(G),J=W.put(m,R);J.onerror=(C)=>{C.preventDefault(),l[K]=18}}})}async del(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction($,"readwrite"),V=W.objectStore($);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=x(G);V.delete(m)}})}async get(Z){let W=this.db.transaction($,"readonly").objectStore($);return new Promise((V,l)=>{let K=x(Z),G=W.get(K);G.onsuccess=async()=>{let m=G.result;if(m)V(await EZ(Z,m,this.crypto));else V(void 0)},G.onerror=()=>l(G.error)})}async has(Z){return await this.get(Z)!==void 0}async list(Z){let X=Z?.apld,W=Z?.body!==!1,l=this.db.transaction($,"readonly").objectStore($);return new Promise((K,G)=>{let m=[],R=X===void 0?l.openCursor():l.index(OX).openCursor(IDBKeyRange.only(X));R.onsuccess=(J)=>{let C=J.target.result;if(C){let F=X===void 0?C.key:C.primaryKey,d=C.value;m.push({hash:e(F),data:d}),C.continue()}else Promise.all(m.map(({hash:F,data:d})=>EZ(F,d,this.crypto,{body:W}))).then(K).catch(G)},R.onerror=()=>G(R.error)})}async count(Z){let W=this.db.transaction($,"readonly").objectStore($);return new Promise((V,l)=>{let K=Z===void 0?W.count():W.index(OX).count(IDBKeyRange.only(Z));K.onsuccess=()=>V(K.result),K.onerror=()=>l(K.error)})}async listKeys(){let X=this.db.transaction($,"readonly").objectStore($);return new Promise((W,V)=>{let l=[],K=X.openKeyCursor();K.onsuccess=(G)=>{let m=G.target.result;if(m)l.push(e(m.key)),m.continue();else W(l)},K.onerror=()=>V(K.error)})}async last(Z){let W=this.db.transaction($,"readonly").objectStore($);return new Promise((V,l)=>{let K,G=W.openCursor();G.onsuccess=async(m)=>{let R=m.target.result;if(R){let{key:J,value:C}=R;if(n(Z,C.eid)){if(!K||(C.ctr??0)>(K.data.ctr??0)||(C.ctr??0)===(K.data.ctr??0)&&(C.off??0)>(K.data.off??0))K={key:J,data:C}}R.continue()}else if(K){let J=e(K.key);V(await EZ(J,K.data,this.crypto))}else V(void 0)},G.onerror=()=>l(G.error)})}async markApplied(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction($,"readwrite"),V=W.objectStore($);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let G of X){let m=x(G),R=V.get(m);R.onsuccess=()=>{let J=R.result;if(!J)return;qZ(J,BZ),V.put(J,m)},R.onerror=(J)=>{J.preventDefault()}}})}async markFailed(Z){let X=[...Z];if(X.length===0)return;let W=this.db.transaction($,"readwrite"),V=W.objectStore($);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error);for(let{key:G,err:m}of X){let R=x(G),J=V.get(R);J.onsuccess=()=>{let C=J.result;if(!C)return;qZ(C,LZ,m),V.put(C,R)},J.onerror=(C)=>{C.preventDefault()}}})}async wipe(){let Z=this.db.transaction($,"readwrite"),X=Z.objectStore($);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var _Z={encode(Z,X){let W=Z.writeVarString(X.handle);if(W!==0)return W;let V=Z.writeVarString(X.label);if(V!==0)return V;return Z.writeVarInt(X.idx??0)},decode(Z){let[X,W]=Z.readVarString();if(W!==0)return Y(W);let[V,l]=Z.readVarString();if(l!==0)return Y(l);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);return b({handle:X,label:V,idx:K})}};var bW=1,HV={encode(Z,X){if(X.v!==bW)return 10;let[,W]=VZ(X.masterSeed);if(W!==0)return W;let V=Z.writeVarInt(X.v);if(V!==0)return V;Z.writeBytes(X.masterSeed);let l=Z.writeVarInt(X.hosts.length);if(l!==0)return l;for(let K of X.hosts){let G=Z.writeStruct(_Z,K);if(G!==0)return G}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X!==bW)return Y(14);let[V,l]=Z.readBytes(kZ);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=VZ(V);if(G!==0)return Y(G);if(K===void 0)return Y(14);let[m,R]=Z.readVarInt();if(R!==0)return Y(R);if(m===void 0||m<0)return Y(10);let J=[];for(let C=0;C<m;C++){let[F,d]=Z.readStruct(_Z);if(d!==0)return Y(d);if(F===void 0)return Y(14);J.push(F)}return b({v:bW,masterSeed:K,hosts:J})}};function V0(Z,X){let[W,V]=VZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(10);let[l,K]=VZ(W.slice());if(K!==0)return Y(K);if(l===void 0)return Y(10);return b({v:bW,masterSeed:l,hosts:X.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))})}var dW={encode(Z,X){let[,W]=VZ(X.masterSeed);if(W!==0)return W;Z.writeBytes(X.masterSeed);let V=Z.writeVarInt(X.hosts.length);if(V!==0)return V;for(let l of X.hosts){let K=Z.writeStruct(_Z,l);if(K!==0)return K}return 0},decode(Z){let[X,W]=Z.readBytes(kZ);if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=VZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=Z.readVarInt();if(G!==0)return Y(G);if(K===void 0||K<0)return Y(10);let m=[];for(let R=0;R<K;R++){let[J,C]=Z.readStruct(_Z);if(C!==0)return Y(C);if(J===void 0)return Y(14);m.push(J)}return b({masterSeed:V,hosts:m})}};var aK=new TextEncoder().encode("diplomatic.qrpair.v1"),iX=32,sK=iX+24+16,rK=32,BF=Symbol("DHKEReq"),EF=Symbol("DHKEResp");function hV(Z){if(Z.byteLength!==iX)return Y(10);return b(Z)}function UV(Z){if(Z.byteLength<sK)return Y(10);return b(Z)}var kW=new nZ;async function PV(Z,X,W,V){let l;try{l=await kW.x25519Shared(Z,X)}catch{return Y(29)}try{if(l.byteLength!==iX||l.every((m)=>m===0))return Y(10);let K=IZ(l,aK),G=IZ(K,IZ(W,V));try{let m=await kW.blake3(G);return b(m.slice(0,rK))}finally{K.fill(0),G.fill(0)}}finally{l.fill(0)}}class jX{#Z;#X;constructor(Z,X){this.#Z=Z,this.#X=X}static async create(){let Z;try{let X=await kW.genX25519();Z=X.priv;let[W,V]=hV(X.pub);if(V!==0)return Y(V);if(W===void 0)return Y(10);let l=new jX(Z,W);return Z=void 0,b(l)}catch{return Y(29)}finally{Z?.fill(0)}}wipe(){this.#Z.fill(0)}get dhkeReq(){let[Z,X]=hV(this.#X.slice());if(Z===void 0)throw Error(`dhkeReq ${X}`);return Z}async finish(Z){let X=Z.subarray(0,iX),W=Z.subarray(iX),[V,l]=await PV(this.#Z,X,this.#X,X);if(l!==0)return Y(l);if(V===void 0)return Y(12);let K;try{try{K=await kW.decryptXSalsa20Poly1305Combined(W,V)}catch{return Y(20)}let G=new O(K),[m,R]=G.readStruct(dW);if(R!==0)return Y(R);if(m===void 0)return Y(14);try{let[J,C]=ZZ.fromBytes(m.masterSeed);if(C!==0)return Y(C);if(J===void 0)return Y(12);return this.wipe(),b({enclave:J,hosts:m.hosts.map((F)=>({...F}))})}finally{m.masterSeed.fill(0)}}finally{V.fill(0),K?.fill(0)}}}function HZ(Z){let X=new Uint8Array(Z);if(Z>0)crypto.getRandomValues(X);return X}var uZ=32,l0=-7,K0=-8,G0=-257,BX=[{type:"public-key",alg:l0},{type:"public-key",alg:K0},{type:"public-key",alg:G0}];function TW(Z){return Z.trim().toLowerCase().replace(/\.$/,"")||"localhost"}function hZ(Z){let X=new Uint8Array(Z.byteLength);return X.set(Z),X.buffer}function m0(Z){if(Z instanceof ArrayBuffer)return new Uint8Array(Z).slice();return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength).slice()}function wZ(Z){if(Z?.rpId!==void 0)return b(Z.rpId);if(typeof location>"u")return Y(9);return b(TW(location.hostname))}function DZ(){if(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")return 24;return 0}function AZ(Z){if(Z===null||Z.type!=="public-key"||!("rawId"in Z)||typeof Z.getClientExtensionResults!=="function")return Y(27);return b(Z)}async function EX(Z){if(typeof PublicKeyCredential>"u")return!1;let X=PublicKeyCredential.getClientCapabilities;if(typeof X!=="function")return!0;let W=await X.call(PublicKeyCredential);if(Z in W)return W[Z]===!0;return!0}function Y0(){return EX("extension:largeBlob")}async function IW(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-seed",K={residentKey:"required",requireResidentKey:!0,userVerification:"required"};if(Z?.authenticatorAttachment!==void 0)K.authenticatorAttachment=Z.authenticatorAttachment;let G={largeBlob:{support:"required"}},m;try{m=await navigator.credentials.create({publicKey:{challenge:HZ(uZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:HZ(16),name:l,displayName:l},pubKeyCredParams:BX,authenticatorSelection:K,extensions:G,...Z?.hints!==void 0?{hints:Z.hints}:{}}})}catch{return Y(24)}let[R,J]=AZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);if(R.getClientExtensionResults().largeBlob?.supported!==!0)return Y(24);return b(new Uint8Array(R.rawId))}async function uX(Z,X,W){let V=DZ();if(V!==0)return V;let[l,K]=wZ(W);if(K!==0)return K;if(l===void 0)return 9;let G={largeBlob:{write:hZ(X)}},m;try{m=await navigator.credentials.get({publicKey:{challenge:HZ(uZ),rpId:l,allowCredentials:[{type:"public-key",id:hZ(Z)}],userVerification:"required",extensions:G,...W?.hints!==void 0?{hints:W.hints}:{}}})}catch{return 24}let[R,J]=AZ(m);if(J!==0)return J;if(R===void 0)return 27;if(R.getClientExtensionResults().largeBlob?.written!==!0)return 24;return 0}async function LW(Z,X){let W=DZ();if(W!==0)return Y(W);let[V,l]=wZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(9);let K={largeBlob:{read:!0}},G;try{let d={challenge:HZ(uZ),rpId:V,userVerification:"required",extensions:K};if(X?.hints!==void 0)d.hints=X.hints;if(Z!==void 0)d.allowCredentials=[{type:"public-key",id:hZ(Z)}];G=await navigator.credentials.get({publicKey:d})}catch{return Y(24)}let[m,R]=AZ(G);if(R!==0)return Y(R);if(m===void 0)return Y(27);let C=m.getClientExtensionResults().largeBlob;if(C===void 0||C.blob===void 0)return Y(7);let F=m0(C.blob);if(F.byteLength===0)return Y(7);return b({blob:F,credId:new Uint8Array(m.rawId)})}var cW=new TextEncoder().encode("diplomatic.prf.v1"),OV=32;async function tK(){return EX("extension:prf")}async function R0(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.userName??"diplomatic-prf",K={residentKey:"required",requireResidentKey:!0,userVerification:"required"};if(Z?.authenticatorAttachment!==void 0)K.authenticatorAttachment=Z.authenticatorAttachment;let G=Z?.salt!==void 0?hZ(Z.salt):void 0,m=G===void 0?{}:{eval:{first:G}},R;try{R=await navigator.credentials.create({publicKey:{challenge:HZ(uZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:HZ(16),name:l,displayName:l},pubKeyCredParams:BX,authenticatorSelection:K,extensions:{prf:m},...Z?.hints!==void 0?{hints:Z.hints}:{}}})}catch{return Y(24)}let[J,C]=AZ(R);if(C!==0)return Y(C);if(J===void 0)return Y(27);let F=J.getClientExtensionResults();return b({credId:new Uint8Array(J.rawId),prfEnabled:F.prf?.enabled===!0})}async function iV(Z){let X=DZ();if(X!==0)return Y(X);let[W,V]=wZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.salt??cW,K=hZ(l),G={challenge:HZ(uZ),rpId:W,userVerification:"required",extensions:{prf:{eval:{first:K}}}};if(Z?.hints!==void 0)G.hints=Z.hints;if(Z?.credId!==void 0)G.allowCredentials=[{type:"public-key",id:hZ(Z.credId)}];let m;try{m=await navigator.credentials.get({publicKey:G})}catch{return Y(24)}let[R,J]=AZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);let C=R.getClientExtensionResults().prf?.results;if(C?.first===void 0)return Y(7);let F=C.first,d=F instanceof ArrayBuffer?new Uint8Array(F):new Uint8Array(F.buffer,F.byteOffset,F.byteLength),k=d.byteLength>=OV?d.slice(0,OV):d;if(k.byteLength!==OV)return Y(27);return b({prf:k,credId:new Uint8Array(R.rawId)})}var QW="dmFyIEEwPTY0O3ZhciBVWj0zMixfMD04O3ZhciBDJD0zMjt2YXIgUlo9MzAwMDAsSFo9NTEyLEQ7KCh3KT0+e3dbdy5TdWNjZXNzPTBdPSJTdWNjZXNzIjt3W3cuSW52YWxpZFNpZ25hdHVyZT0zXT0iSW52YWxpZFNpZ25hdHVyZSI7d1t3LkNsb2NrT3V0T2ZTeW5jPTRdPSJDbG9ja091dE9mU3luYyI7d1t3LlVzZXJOb3RSZWdpc3RlcmVkPTVdPSJVc2VyTm90UmVnaXN0ZXJlZCI7d1t3LlNlcnZlck1pc2NvbmZpZ3VyZWQ9Nl09IlNlcnZlck1pc2NvbmZpZ3VyZWQiO3dbdy5NaXNzaW5nQm9keT03XT0iTWlzc2luZ0JvZHkiO3dbdy5FeHRyYUJvZHlDb250ZW50PThdPSJFeHRyYUJvZHlDb250ZW50Ijt3W3cuTWlzc2luZ1BhcmFtPTldPSJNaXNzaW5nUGFyYW0iO3dbdy5JbnZhbGlkUGFyYW09MTBdPSJJbnZhbGlkUGFyYW0iO3dbdy5JbnZhbGlkUmVxdWVzdD0xMV09IkludmFsaWRSZXF1ZXN0Ijt3W3cuSW50ZXJuYWxFcnJvcj0xMl09IkludGVybmFsRXJyb3IiO3dbdy5Ob3RGb3VuZD0xM109Ik5vdEZvdW5kIjt3W3cuSW52YWxpZE1lc3NhZ2U9MTRdPSJJbnZhbGlkTWVzc2FnZSI7d1t3Lk5vQ2hhbmdlPTE1XT0iTm9DaGFuZ2UiO3dbdy5EYXRhYmFzZUNsb3NlZD0xNl09IkRhdGFiYXNlQ2xvc2VkIjt3W3cuU3RvcmFnZUVycm9yPTE3XT0iU3RvcmFnZUVycm9yIjt3W3cuRGF0YWJhc2VFcnJvcj0xOF09IkRhdGFiYXNlRXJyb3IiO3dbdy5IYXNoTWlzbWF0Y2g9MTldPSJIYXNoTWlzbWF0Y2giO3dbdy5EZWNyeXB0aW9uRXJyb3I9MjBdPSJEZWNyeXB0aW9uRXJyb3IiO3dbdy5Ob3RJbXBsZW1lbnRlZD0yMV09Ik5vdEltcGxlbWVudGVkIjt3W3cuTWlzc2luZ1NlZWQ9MjJdPSJNaXNzaW5nU2VlZCI7d1t3Lk91dE9mQm91bmRzPTIzXT0iT3V0T2ZCb3VuZHMiO3dbdy5Ib3N0RXJyb3I9MjRdPSJIb3N0RXJyb3IiO3dbdy5Db21tdW5pY2F0aW9uRXJyb3I9MjVdPSJDb21tdW5pY2F0aW9uRXJyb3IiO3dbdy5WYXJMaW1pdEV4Y2VlZGVkPTI2XT0iVmFyTGltaXRFeGNlZWRlZCI7d1t3LkludmFsaWRSZXNwb25zZT0yN109IkludmFsaWRSZXNwb25zZSI7d1t3LkNvbm5lY3Rpb25DbG9zZWQ9MjhdPSJDb25uZWN0aW9uQ2xvc2VkIjt3W3cuQ3J5cHRvRXJyb3I9MjldPSJDcnlwdG9FcnJvciJ9KShEfHw9e30pO2Z1bmN0aW9uIHFaKCQpe2lmKCEkfHx0eXBlb2YgJCE9PSJvYmplY3QiKXJldHVybiExO2lmKCEoIm9wImluICQpfHwhKCJpZCJpbiAkKSlyZXR1cm4hMTtyZXR1cm4gdHlwZW9mICQub3A9PT0ic3RyaW5nIiYmdHlwZW9mICQuaWQ9PT0ibnVtYmVyIn1mdW5jdGlvbiBNWigkKXtsZXQgSj0kLmxlbmd0aCxaPTAsUT0wO3doaWxlKFE8Sil7bGV0IFk9JC5jaGFyQ29kZUF0KFErKyk7aWYoKFkmNDI5NDk2NzE2OCk9PT0wKXtaKys7Y29udGludWV9ZWxzZSBpZigoWSY0Mjk0OTY1MjQ4KT09PTApWis9MjtlbHNle2lmKFk+PTU1Mjk2JiZZPD01NjMxOSl7aWYoUTxKKXtsZXQgVj0kLmNoYXJDb2RlQXQoUSk7aWYoKFYmNjQ1MTIpPT09NTYzMjApKytRLFk9KChZJjEwMjMpPDwxMCkrKFYmMTAyMykrNjU1MzZ9fWlmKChZJjQyOTQ5MDE3NjApPT09MClaKz0zO2Vsc2UgWis9NH19cmV0dXJuIFp9ZnVuY3Rpb24gJFkoJCxKLFope2xldCBRPSQubGVuZ3RoLFk9WixWPTA7d2hpbGUoVjxRKXtsZXQgWD0kLmNoYXJDb2RlQXQoVisrKTtpZigoWCY0Mjk0OTY3MTY4KT09PTApe0pbWSsrXT1YO2NvbnRpbnVlfWVsc2UgaWYoKFgmNDI5NDk2NTI0OCk9PT0wKUpbWSsrXT1YPj42JjMxfDE5MjtlbHNle2lmKFg+PTU1Mjk2JiZYPD01NjMxOSl7aWYoVjxRKXtsZXQgVz0kLmNoYXJDb2RlQXQoVik7aWYoKFcmNjQ1MTIpPT09NTYzMjApKytWLFg9KChYJjEwMjMpPDwxMCkrKFcmMTAyMykrNjU1MzZ9fWlmKChYJjQyOTQ5MDE3NjApPT09MClKW1krK109WD4+MTImMTV8MjI0LEpbWSsrXT1YPj42JjYzfDEyODtlbHNlIEpbWSsrXT1YPj4xOCY3fDI0MCxKW1krK109WD4+MTImNjN8MTI4LEpbWSsrXT1YPj42JjYzfDEyOH1KW1krK109WCY2M3wxMjh9fXZhciBKWT1uZXcgVGV4dEVuY29kZXIsWlk9NTA7ZnVuY3Rpb24gUVkoJCxKLFope0pZLmVuY29kZUludG8oJCxKLnN1YmFycmF5KFopKX1mdW5jdGlvbiBJWigkLEosWil7aWYoJC5sZW5ndGg+WlkpUVkoJCxKLFopO2Vsc2UgJFkoJCxKLFopfXZhciBZWT00MDk2O2Z1bmN0aW9uIFlKKCQsSixaKXtsZXQgUT1KLFk9UStaLFY9W10sWD0iIjt3aGlsZShRPFkpe2xldCBXPSRbUSsrXTtpZigoVyYxMjgpPT09MClWLnB1c2goVyk7ZWxzZSBpZigoVyYyMjQpPT09MTkyKXtsZXQgej0kW1ErK10mNjM7Vi5wdXNoKChXJjMxKTw8Nnx6KX1lbHNlIGlmKChXJjI0MCk9PT0yMjQpe2xldCB6PSRbUSsrXSY2MyxLPSRbUSsrXSY2MztWLnB1c2goKFcmMzEpPDwxMnx6PDw2fEspfWVsc2UgaWYoKFcmMjQ4KT09PTI0MCl7bGV0IHo9JFtRKytdJjYzLEs9JFtRKytdJjYzLEY9JFtRKytdJjYzLE49KFcmNyk8PDE4fHo8PDEyfEs8PDZ8RjtpZihOPjY1NTM1KU4tPTY1NTM2LFYucHVzaChOPj4+MTAmMTAyM3w1NTI5NiksTj01NjMyMHxOJjEwMjM7Vi5wdXNoKE4pfWVsc2UgVi5wdXNoKFcpO2lmKFYubGVuZ3RoPj1ZWSlYKz1TdHJpbmcuZnJvbUNoYXJDb2RlKC4uLlYpLFYubGVuZ3RoPTB9aWYoVi5sZW5ndGg+MClYKz1TdHJpbmcuZnJvbUNoYXJDb2RlKC4uLlYpO3JldHVybiBYfXZhciBWWT1uZXcgVGV4dERlY29kZXIsWFk9MjAwO2Z1bmN0aW9uIFdZKCQsSixaKXtsZXQgUT0kLnN1YmFycmF5KEosSitaKTtyZXR1cm4gVlkuZGVjb2RlKFEpfWZ1bmN0aW9uIENaKCQsSixaKXtpZihaPlhZKXJldHVybiBXWSgkLEosWik7ZWxzZSByZXR1cm4gWUooJCxKLFopfWNsYXNzIHIwe3R5cGU7ZGF0YTtjb25zdHJ1Y3RvcigkLEope3RoaXMudHlwZT0kLHRoaXMuZGF0YT1KfX1jbGFzcyBlIGV4dGVuZHMgRXJyb3J7Y29uc3RydWN0b3IoJCl7c3VwZXIoJCk7bGV0IEo9T2JqZWN0LmNyZWF0ZShlLnByb3RvdHlwZSk7T2JqZWN0LnNldFByb3RvdHlwZU9mKHRoaXMsSiksT2JqZWN0LmRlZmluZVByb3BlcnR5KHRoaXMsIm5hbWUiLHtjb25maWd1cmFibGU6ITAsZW51bWVyYWJsZTohMSx2YWx1ZTplLm5hbWV9KX19dmFyIG8wPTQyOTQ5NjcyOTU7ZnVuY3Rpb24gUFooJCxKLFope2xldCBRPVovNDI5NDk2NzI5NixZPVo7JC5zZXRVaW50MzIoSixRKSwkLnNldFVpbnQzMihKKzQsWSl9ZnVuY3Rpb24gUCQoJCxKLFope2xldCBRPU1hdGguZmxvb3IoWi80Mjk0OTY3Mjk2KSxZPVo7JC5zZXRVaW50MzIoSixRKSwkLnNldFVpbnQzMihKKzQsWSl9ZnVuY3Rpb24gdyQoJCxKKXtsZXQgWj0kLmdldEludDMyKEopLFE9JC5nZXRVaW50MzIoSis0KTtyZXR1cm4gWio0Mjk0OTY3Mjk2K1F9ZnVuY3Rpb24gd1ooJCxKKXtsZXQgWj0kLmdldFVpbnQzMihKKSxRPSQuZ2V0VWludDMyKEorNCk7cmV0dXJuIFoqNDI5NDk2NzI5NitRfXZhciBHWT0tMSx6WT00Mjk0OTY3Mjk1LEtZPTE3MTc5ODY5MTgzO2Z1bmN0aW9uIEZZKHtzZWM6JCxuc2VjOkp9KXtpZigkPj0wJiZKPj0wJiYkPD1LWSlpZihKPT09MCYmJDw9elkpe2xldCBaPW5ldyBVaW50OEFycmF5KDQpO3JldHVybiBuZXcgRGF0YVZpZXcoWi5idWZmZXIpLnNldFVpbnQzMigwLCQpLFp9ZWxzZXtsZXQgWj0kLzQyOTQ5NjcyOTYsUT0kJjQyOTQ5NjcyOTUsWT1uZXcgVWludDhBcnJheSg4KSxWPW5ldyBEYXRhVmlldyhZLmJ1ZmZlcik7cmV0dXJuIFYuc2V0VWludDMyKDAsSjw8MnxaJjMpLFYuc2V0VWludDMyKDQsUSksWX1lbHNle2xldCBaPW5ldyBVaW50OEFycmF5KDEyKSxRPW5ldyBEYXRhVmlldyhaLmJ1ZmZlcik7cmV0dXJuIFEuc2V0VWludDMyKDAsSiksUCQoUSw0LCQpLFp9fWZ1bmN0aW9uIE5ZKCQpe2xldCBKPSQuZ2V0VGltZSgpLFo9TWF0aC5mbG9vcihKLzEwMDApLFE9KEotWioxMDAwKSoxZTYsWT1NYXRoLmZsb29yKFEvMWU5KTtyZXR1cm57c2VjOlorWSxuc2VjOlEtWSoxZTl9fWZ1bmN0aW9uIE9ZKCQpe2lmKCQgaW5zdGFuY2VvZiBEYXRlKXtsZXQgSj1OWSgkKTtyZXR1cm4gRlkoSil9ZWxzZSByZXR1cm4gbnVsbH1mdW5jdGlvbiBVWSgkKXtsZXQgSj1uZXcgRGF0YVZpZXcoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LCQuYnl0ZUxlbmd0aCk7c3dpdGNoKCQuYnl0ZUxlbmd0aCl7Y2FzZSA0OntsZXQgWj1KLmdldFVpbnQzMigwKSxRPTA7cmV0dXJue3NlYzpaLG5zZWM6MH19Y2FzZSA4OntsZXQgWj1KLmdldFVpbnQzMigwKSxRPUouZ2V0VWludDMyKDQpLFk9KFomMykqNDI5NDk2NzI5NitRLFY9Wj4+PjI7cmV0dXJue3NlYzpZLG5zZWM6Vn19Y2FzZSAxMjp7bGV0IFo9dyQoSiw0KSxRPUouZ2V0VWludDMyKDApO3JldHVybntzZWM6Wixuc2VjOlF9fWRlZmF1bHQ6dGhyb3cgbmV3IGUoYFVucmVjb2duaXplZCBkYXRhIHNpemUgZm9yIHRpbWVzdGFtcCAoZXhwZWN0ZWQgNCwgOCwgb3IgMTIpOiAkeyQubGVuZ3RofWApfX1mdW5jdGlvbiBSWSgkKXtsZXQgSj1VWSgkKTtyZXR1cm4gbmV3IERhdGUoSi5zZWMqMTAwMCtKLm5zZWMvMWU2KX12YXIgVFo9e3R5cGU6R1ksZW5jb2RlOk9ZLGRlY29kZTpSWX07Y2xhc3MgYTB7c3RhdGljIGRlZmF1bHRDb2RlYz1uZXcgYTA7X19icmFuZDtidWlsdEluRW5jb2RlcnM9W107YnVpbHRJbkRlY29kZXJzPVtdO2VuY29kZXJzPVtdO2RlY29kZXJzPVtdO2NvbnN0cnVjdG9yKCl7dGhpcy5yZWdpc3RlcihUWil9cmVnaXN0ZXIoe3R5cGU6JCxlbmNvZGU6SixkZWNvZGU6Wn0pe2lmKCQ+PTApdGhpcy5lbmNvZGVyc1skXT1KLHRoaXMuZGVjb2RlcnNbJF09WjtlbHNle2xldCBRPS0xLSQ7dGhpcy5idWlsdEluRW5jb2RlcnNbUV09Six0aGlzLmJ1aWx0SW5EZWNvZGVyc1tRXT1afX10cnlUb0VuY29kZSgkLEope2ZvcihsZXQgWj0wO1o8dGhpcy5idWlsdEluRW5jb2RlcnMubGVuZ3RoO1orKyl7bGV0IFE9dGhpcy5idWlsdEluRW5jb2RlcnNbWl07aWYoUSE9bnVsbCl7bGV0IFk9USgkLEopO2lmKFkhPW51bGwpe2xldCBWPS0xLVo7cmV0dXJuIG5ldyByMChWLFkpfX19Zm9yKGxldCBaPTA7Wjx0aGlzLmVuY29kZXJzLmxlbmd0aDtaKyspe2xldCBRPXRoaXMuZW5jb2RlcnNbWl07aWYoUSE9bnVsbCl7bGV0IFk9USgkLEopO2lmKFkhPW51bGwpcmV0dXJuIG5ldyByMChaLFkpfX1pZigkIGluc3RhbmNlb2YgcjApcmV0dXJuICQ7cmV0dXJuIG51bGx9ZGVjb2RlKCQsSixaKXtsZXQgUT1KPDA/dGhpcy5idWlsdEluRGVjb2RlcnNbLTEtSl06dGhpcy5kZWNvZGVyc1tKXTtpZihRKXJldHVybiBRKCQsSixaKTtlbHNlIHJldHVybiBuZXcgcjAoSiwkKX19ZnVuY3Rpb24gSFkoJCl7cmV0dXJuICQgaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcnx8dHlwZW9mIFNoYXJlZEFycmF5QnVmZmVyPCJ1IiYmJCBpbnN0YW5jZW9mIFNoYXJlZEFycmF5QnVmZmVyfWZ1bmN0aW9uIFckKCQpe2lmKCQgaW5zdGFuY2VvZiBVaW50OEFycmF5KXJldHVybiAkO2Vsc2UgaWYoQXJyYXlCdWZmZXIuaXNWaWV3KCQpKXJldHVybiBuZXcgVWludDhBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKTtlbHNlIGlmKEhZKCQpKXJldHVybiBuZXcgVWludDhBcnJheSgkKTtlbHNlIHJldHVybiBVaW50OEFycmF5LmZyb20oJCl9dmFyIHFZPTEwMCxNWT0yMDQ4O2NsYXNzIFQke2V4dGVuc2lvbkNvZGVjO2NvbnRleHQ7dXNlQmlnSW50NjQ7bWF4RGVwdGg7aW5pdGlhbEJ1ZmZlclNpemU7c29ydEtleXM7Zm9yY2VGbG9hdDMyO2lnbm9yZVVuZGVmaW5lZDtmb3JjZUludGVnZXJUb0Zsb2F0O3Bvczt2aWV3O2J5dGVzO2VudGVyZWQ9ITE7Y29uc3RydWN0b3IoJCl7dGhpcy5leHRlbnNpb25Db2RlYz0kPy5leHRlbnNpb25Db2RlYz8/YTAuZGVmYXVsdENvZGVjLHRoaXMuY29udGV4dD0kPy5jb250ZXh0LHRoaXMudXNlQmlnSW50NjQ9JD8udXNlQmlnSW50NjQ/PyExLHRoaXMubWF4RGVwdGg9JD8ubWF4RGVwdGg/P3FZLHRoaXMuaW5pdGlhbEJ1ZmZlclNpemU9JD8uaW5pdGlhbEJ1ZmZlclNpemU/P01ZLHRoaXMuc29ydEtleXM9JD8uc29ydEtleXM/PyExLHRoaXMuZm9yY2VGbG9hdDMyPSQ/LmZvcmNlRmxvYXQzMj8/ITEsdGhpcy5pZ25vcmVVbmRlZmluZWQ9JD8uaWdub3JlVW5kZWZpbmVkPz8hMSx0aGlzLmZvcmNlSW50ZWdlclRvRmxvYXQ9JD8uZm9yY2VJbnRlZ2VyVG9GbG9hdD8/ITEsdGhpcy5wb3M9MCx0aGlzLnZpZXc9bmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcih0aGlzLmluaXRpYWxCdWZmZXJTaXplKSksdGhpcy5ieXRlcz1uZXcgVWludDhBcnJheSh0aGlzLnZpZXcuYnVmZmVyKX1jbG9uZSgpe3JldHVybiBuZXcgVCQoe2V4dGVuc2lvbkNvZGVjOnRoaXMuZXh0ZW5zaW9uQ29kZWMsY29udGV4dDp0aGlzLmNvbnRleHQsdXNlQmlnSW50NjQ6dGhpcy51c2VCaWdJbnQ2NCxtYXhEZXB0aDp0aGlzLm1heERlcHRoLGluaXRpYWxCdWZmZXJTaXplOnRoaXMuaW5pdGlhbEJ1ZmZlclNpemUsc29ydEtleXM6dGhpcy5zb3J0S2V5cyxmb3JjZUZsb2F0MzI6dGhpcy5mb3JjZUZsb2F0MzIsaWdub3JlVW5kZWZpbmVkOnRoaXMuaWdub3JlVW5kZWZpbmVkLGZvcmNlSW50ZWdlclRvRmxvYXQ6dGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0fSl9cmVpbml0aWFsaXplU3RhdGUoKXt0aGlzLnBvcz0wfWVuY29kZVNoYXJlZFJlZigkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmNvZGVTaGFyZWRSZWYoJCk7dHJ5e3JldHVybiB0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuZG9FbmNvZGUoJCwxKSx0aGlzLmJ5dGVzLnN1YmFycmF5KDAsdGhpcy5wb3MpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1lbmNvZGUoJCl7aWYodGhpcy5lbnRlcmVkKXJldHVybiB0aGlzLmNsb25lKCkuZW5jb2RlKCQpO3RyeXtyZXR1cm4gdGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLmRvRW5jb2RlKCQsMSksdGhpcy5ieXRlcy5zbGljZSgwLHRoaXMucG9zKX1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19ZG9FbmNvZGUoJCxKKXtpZihKPnRoaXMubWF4RGVwdGgpdGhyb3cgRXJyb3IoYFRvbyBkZWVwIG9iamVjdHMgaW4gZGVwdGggJHtKfWApO2lmKCQ9PW51bGwpdGhpcy5lbmNvZGVOaWwoKTtlbHNlIGlmKHR5cGVvZiAkPT09ImJvb2xlYW4iKXRoaXMuZW5jb2RlQm9vbGVhbigkKTtlbHNlIGlmKHR5cGVvZiAkPT09Im51bWJlciIpaWYoIXRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdCl0aGlzLmVuY29kZU51bWJlcigkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIGlmKHR5cGVvZiAkPT09InN0cmluZyIpdGhpcy5lbmNvZGVTdHJpbmcoJCk7ZWxzZSBpZih0aGlzLnVzZUJpZ0ludDY0JiZ0eXBlb2YgJD09PSJiaWdpbnQiKXRoaXMuZW5jb2RlQmlnSW50NjQoJCk7ZWxzZSB0aGlzLmVuY29kZU9iamVjdCgkLEopfWVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKCQpe2xldCBKPXRoaXMucG9zKyQ7aWYodGhpcy52aWV3LmJ5dGVMZW5ndGg8Sil0aGlzLnJlc2l6ZUJ1ZmZlcihKKjIpfXJlc2l6ZUJ1ZmZlcigkKXtsZXQgSj1uZXcgQXJyYXlCdWZmZXIoJCksWj1uZXcgVWludDhBcnJheShKKSxRPW5ldyBEYXRhVmlldyhKKTtaLnNldCh0aGlzLmJ5dGVzKSx0aGlzLnZpZXc9USx0aGlzLmJ5dGVzPVp9ZW5jb2RlTmlsKCl7dGhpcy53cml0ZVU4KDE5Mil9ZW5jb2RlQm9vbGVhbigkKXtpZigkPT09ITEpdGhpcy53cml0ZVU4KDE5NCk7ZWxzZSB0aGlzLndyaXRlVTgoMTk1KX1lbmNvZGVOdW1iZXIoJCl7aWYoIXRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdCYmTnVtYmVyLmlzU2FmZUludGVnZXIoJCkpaWYoJD49MClpZigkPDEyOCl0aGlzLndyaXRlVTgoJCk7ZWxzZSBpZigkPDI1Nil0aGlzLndyaXRlVTgoMjA0KSx0aGlzLndyaXRlVTgoJCk7ZWxzZSBpZigkPDY1NTM2KXRoaXMud3JpdGVVOCgyMDUpLHRoaXMud3JpdGVVMTYoJCk7ZWxzZSBpZigkPDQyOTQ5NjcyOTYpdGhpcy53cml0ZVU4KDIwNiksdGhpcy53cml0ZVUzMigkKTtlbHNlIGlmKCF0aGlzLnVzZUJpZ0ludDY0KXRoaXMud3JpdGVVOCgyMDcpLHRoaXMud3JpdGVVNjQoJCk7ZWxzZSB0aGlzLmVuY29kZU51bWJlckFzRmxvYXQoJCk7ZWxzZSBpZigkPj0tMzIpdGhpcy53cml0ZVU4KDIyNHwkKzMyKTtlbHNlIGlmKCQ+PS0xMjgpdGhpcy53cml0ZVU4KDIwOCksdGhpcy53cml0ZUk4KCQpO2Vsc2UgaWYoJD49LTMyNzY4KXRoaXMud3JpdGVVOCgyMDkpLHRoaXMud3JpdGVJMTYoJCk7ZWxzZSBpZigkPj0tMjE0NzQ4MzY0OCl0aGlzLndyaXRlVTgoMjEwKSx0aGlzLndyaXRlSTMyKCQpO2Vsc2UgaWYoIXRoaXMudXNlQmlnSW50NjQpdGhpcy53cml0ZVU4KDIxMSksdGhpcy53cml0ZUk2NCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKX1lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpe2lmKHRoaXMuZm9yY2VGbG9hdDMyKXRoaXMud3JpdGVVOCgyMDIpLHRoaXMud3JpdGVGMzIoJCk7ZWxzZSB0aGlzLndyaXRlVTgoMjAzKSx0aGlzLndyaXRlRjY0KCQpfWVuY29kZUJpZ0ludDY0KCQpe2lmKCQ+PUJpZ0ludCgwKSl0aGlzLndyaXRlVTgoMjA3KSx0aGlzLndyaXRlQmlnVWludDY0KCQpO2Vsc2UgdGhpcy53cml0ZVU4KDIxMSksdGhpcy53cml0ZUJpZ0ludDY0KCQpfXdyaXRlU3RyaW5nSGVhZGVyKCQpe2lmKCQ8MzIpdGhpcy53cml0ZVU4KDE2MCskKTtlbHNlIGlmKCQ8MjU2KXRoaXMud3JpdGVVOCgyMTcpLHRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8NjU1MzYpdGhpcy53cml0ZVU4KDIxOCksdGhpcy53cml0ZVUxNigkKTtlbHNlIGlmKCQ8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjE5KSx0aGlzLndyaXRlVTMyKCQpO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsb25nIHN0cmluZzogJHskfSBieXRlcyBpbiBVVEYtOGApfWVuY29kZVN0cmluZygkKXtsZXQgWj1NWigkKTt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDUrWiksdGhpcy53cml0ZVN0cmluZ0hlYWRlcihaKSxJWigkLHRoaXMuYnl0ZXMsdGhpcy5wb3MpLHRoaXMucG9zKz1afWVuY29kZU9iamVjdCgkLEope2xldCBaPXRoaXMuZXh0ZW5zaW9uQ29kZWMudHJ5VG9FbmNvZGUoJCx0aGlzLmNvbnRleHQpO2lmKFohPW51bGwpdGhpcy5lbmNvZGVFeHRlbnNpb24oWik7ZWxzZSBpZihBcnJheS5pc0FycmF5KCQpKXRoaXMuZW5jb2RlQXJyYXkoJCxKKTtlbHNlIGlmKEFycmF5QnVmZmVyLmlzVmlldygkKSl0aGlzLmVuY29kZUJpbmFyeSgkKTtlbHNlIGlmKHR5cGVvZiAkPT09Im9iamVjdCIpdGhpcy5lbmNvZGVNYXAoJCxKKTtlbHNlIHRocm93IEVycm9yKGBVbnJlY29nbml6ZWQgb2JqZWN0OiAke09iamVjdC5wcm90b3R5cGUudG9TdHJpbmcuYXBwbHkoJCl9YCl9ZW5jb2RlQmluYXJ5KCQpe2xldCBKPSQuYnl0ZUxlbmd0aDtpZihKPDI1Nil0aGlzLndyaXRlVTgoMTk2KSx0aGlzLndyaXRlVTgoSik7ZWxzZSBpZihKPDY1NTM2KXRoaXMud3JpdGVVOCgxOTcpLHRoaXMud3JpdGVVMTYoSik7ZWxzZSBpZihKPDQyOTQ5NjcyOTYpdGhpcy53cml0ZVU4KDE5OCksdGhpcy53cml0ZVUzMihKKTtlbHNlIHRocm93IEVycm9yKGBUb28gbGFyZ2UgYmluYXJ5OiAke0p9YCk7bGV0IFo9VyQoJCk7dGhpcy53cml0ZVU4YShaKX1lbmNvZGVBcnJheSgkLEope2xldCBaPSQubGVuZ3RoO2lmKFo8MTYpdGhpcy53cml0ZVU4KDE0NCtaKTtlbHNlIGlmKFo8NjU1MzYpdGhpcy53cml0ZVU4KDIyMCksdGhpcy53cml0ZVUxNihaKTtlbHNlIGlmKFo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjIxKSx0aGlzLndyaXRlVTMyKFopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBhcnJheTogJHtafWApO2ZvcihsZXQgUSBvZiAkKXRoaXMuZG9FbmNvZGUoUSxKKzEpfWNvdW50V2l0aG91dFVuZGVmaW5lZCgkLEope2xldCBaPTA7Zm9yKGxldCBRIG9mIEopaWYoJFtRXSE9PXZvaWQgMClaKys7cmV0dXJuIFp9ZW5jb2RlTWFwKCQsSil7bGV0IFo9T2JqZWN0LmtleXMoJCk7aWYodGhpcy5zb3J0S2V5cylaLnNvcnQoKTtsZXQgUT10aGlzLmlnbm9yZVVuZGVmaW5lZD90aGlzLmNvdW50V2l0aG91dFVuZGVmaW5lZCgkLFopOloubGVuZ3RoO2lmKFE8MTYpdGhpcy53cml0ZVU4KDEyOCtRKTtlbHNlIGlmKFE8NjU1MzYpdGhpcy53cml0ZVU4KDIyMiksdGhpcy53cml0ZVUxNihRKTtlbHNlIGlmKFE8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjIzKSx0aGlzLndyaXRlVTMyKFEpO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBtYXAgb2JqZWN0OiAke1F9YCk7Zm9yKGxldCBZIG9mIFope2xldCBWPSRbWV07aWYoISh0aGlzLmlnbm9yZVVuZGVmaW5lZCYmVj09PXZvaWQgMCkpdGhpcy5lbmNvZGVTdHJpbmcoWSksdGhpcy5kb0VuY29kZShWLEorMSl9fWVuY29kZUV4dGVuc2lvbigkKXtpZih0eXBlb2YgJC5kYXRhPT09ImZ1bmN0aW9uIil7bGV0IFo9JC5kYXRhKHRoaXMucG9zKzYpLFE9Wi5sZW5ndGg7aWYoUT49NDI5NDk2NzI5Nil0aHJvdyBFcnJvcihgVG9vIGxhcmdlIGV4dGVuc2lvbiBvYmplY3Q6ICR7UX1gKTt0aGlzLndyaXRlVTgoMjAxKSx0aGlzLndyaXRlVTMyKFEpLHRoaXMud3JpdGVJOCgkLnR5cGUpLHRoaXMud3JpdGVVOGEoWik7cmV0dXJufWxldCBKPSQuZGF0YS5sZW5ndGg7aWYoSj09PTEpdGhpcy53cml0ZVU4KDIxMik7ZWxzZSBpZihKPT09Mil0aGlzLndyaXRlVTgoMjEzKTtlbHNlIGlmKEo9PT00KXRoaXMud3JpdGVVOCgyMTQpO2Vsc2UgaWYoSj09PTgpdGhpcy53cml0ZVU4KDIxNSk7ZWxzZSBpZihKPT09MTYpdGhpcy53cml0ZVU4KDIxNik7ZWxzZSBpZihKPDI1Nil0aGlzLndyaXRlVTgoMTk5KSx0aGlzLndyaXRlVTgoSik7ZWxzZSBpZihKPDY1NTM2KXRoaXMud3JpdGVVOCgyMDApLHRoaXMud3JpdGVVMTYoSik7ZWxzZSBpZihKPDQyOTQ5NjcyOTYpdGhpcy53cml0ZVU4KDIwMSksdGhpcy53cml0ZVUzMihKKTtlbHNlIHRocm93IEVycm9yKGBUb28gbGFyZ2UgZXh0ZW5zaW9uIG9iamVjdDogJHtKfWApO3RoaXMud3JpdGVJOCgkLnR5cGUpLHRoaXMud3JpdGVVOGEoJC5kYXRhKX13cml0ZVU4KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMSksdGhpcy52aWV3LnNldFVpbnQ4KHRoaXMucG9zLCQpLHRoaXMucG9zKyt9d3JpdGVVOGEoJCl7bGV0IEo9JC5sZW5ndGg7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZShKKSx0aGlzLmJ5dGVzLnNldCgkLHRoaXMucG9zKSx0aGlzLnBvcys9Sn13cml0ZUk4KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMSksdGhpcy52aWV3LnNldEludDgodGhpcy5wb3MsJCksdGhpcy5wb3MrK313cml0ZVUxNigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDIpLHRoaXMudmlldy5zZXRVaW50MTYodGhpcy5wb3MsJCksdGhpcy5wb3MrPTJ9d3JpdGVJMTYoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgyKSx0aGlzLnZpZXcuc2V0SW50MTYodGhpcy5wb3MsJCksdGhpcy5wb3MrPTJ9d3JpdGVVMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0VWludDMyKHRoaXMucG9zLCQpLHRoaXMucG9zKz00fXdyaXRlSTMyKCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNCksdGhpcy52aWV3LnNldEludDMyKHRoaXMucG9zLCQpLHRoaXMucG9zKz00fXdyaXRlRjMyKCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNCksdGhpcy52aWV3LnNldEZsb2F0MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVGNjQoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg4KSx0aGlzLnZpZXcuc2V0RmxvYXQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZVU2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLFBaKHRoaXMudmlldyx0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUk2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLFAkKHRoaXMudmlldyx0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUJpZ1VpbnQ2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRCaWdVaW50NjQodGhpcy5wb3MsJCksdGhpcy5wb3MrPTh9d3JpdGVCaWdJbnQ2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRCaWdJbnQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH19ZnVuY3Rpb24gRTAoJCxKKXtyZXR1cm4gbmV3IFQkKEopLmVuY29kZVNoYXJlZFJlZigkKX1mdW5jdGlvbiBqJCgkKXtyZXR1cm5gJHskPDA/Ii0iOiIifTB4JHtNYXRoLmFicygkKS50b1N0cmluZygxNikucGFkU3RhcnQoMiwiMCIpfWB9dmFyIElZPTE2LENZPTE2O2NsYXNzIFZKe2hpdD0wO21pc3M9MDtjYWNoZXM7bWF4S2V5TGVuZ3RoO21heExlbmd0aFBlcktleTtjb25zdHJ1Y3RvcigkPUlZLEo9Q1kpe3RoaXMubWF4S2V5TGVuZ3RoPSQsdGhpcy5tYXhMZW5ndGhQZXJLZXk9Six0aGlzLmNhY2hlcz1bXTtmb3IobGV0IFo9MDtaPHRoaXMubWF4S2V5TGVuZ3RoO1orKyl0aGlzLmNhY2hlcy5wdXNoKFtdKX1jYW5CZUNhY2hlZCgkKXtyZXR1cm4gJD4wJiYkPD10aGlzLm1heEtleUxlbmd0aH1maW5kKCQsSixaKXtsZXQgUT10aGlzLmNhY2hlc1taLTFdOyQ6Zm9yKGxldCBZIG9mIFEpe2xldCBWPVkuYnl0ZXM7Zm9yKGxldCBYPTA7WDxaO1grKylpZihWW1hdIT09JFtKK1hdKWNvbnRpbnVlICQ7cmV0dXJuIFkuc3RyfXJldHVybiBudWxsfXN0b3JlKCQsSil7bGV0IFo9dGhpcy5jYWNoZXNbJC5sZW5ndGgtMV0sUT17Ynl0ZXM6JCxzdHI6Sn07aWYoWi5sZW5ndGg+PXRoaXMubWF4TGVuZ3RoUGVyS2V5KVpbTWF0aC5yYW5kb20oKSpaLmxlbmd0aHwwXT1RO2Vsc2UgWi5wdXNoKFEpfWRlY29kZSgkLEosWil7bGV0IFE9dGhpcy5maW5kKCQsSixaKTtpZihRIT1udWxsKXJldHVybiB0aGlzLmhpdCsrLFE7dGhpcy5taXNzKys7bGV0IFk9WUooJCxKLFopLFY9VWludDhBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbCgkLEosSitaKTtyZXR1cm4gdGhpcy5zdG9yZShWLFkpLFl9fXZhciBYSj0iYXJyYXkiLHokPSJtYXBfa2V5IixEWj0ibWFwX3ZhbHVlIixQWT0oJCk9PntpZih0eXBlb2YgJD09PSJzdHJpbmcifHx0eXBlb2YgJD09PSJudW1iZXIiKXJldHVybiAkO3Rocm93IG5ldyBlKCJUaGUgdHlwZSBvZiBrZXkgbXVzdCBiZSBzdHJpbmcgb3IgbnVtYmVyIGJ1dCAiK3R5cGVvZiAkKX07Y2xhc3MgQVp7c3RhY2s9W107c3RhY2tIZWFkUG9zaXRpb249LTE7Z2V0IGxlbmd0aCgpe3JldHVybiB0aGlzLnN0YWNrSGVhZFBvc2l0aW9uKzF9dG9wKCl7cmV0dXJuIHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl19cHVzaEFycmF5U3RhdGUoJCl7bGV0IEo9dGhpcy5nZXRVbmluaXRpYWxpemVkU3RhdGVGcm9tUG9vbCgpO0oudHlwZT1YSixKLnBvc2l0aW9uPTAsSi5zaXplPSQsSi5hcnJheT1BcnJheSgkKX1wdXNoTWFwU3RhdGUoJCl7bGV0IEo9dGhpcy5nZXRVbmluaXRpYWxpemVkU3RhdGVGcm9tUG9vbCgpO0oudHlwZT16JCxKLnJlYWRDb3VudD0wLEouc2l6ZT0kLEoubWFwPXt9fWdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCl7aWYodGhpcy5zdGFja0hlYWRQb3NpdGlvbisrLHRoaXMuc3RhY2tIZWFkUG9zaXRpb249PT10aGlzLnN0YWNrLmxlbmd0aCl7bGV0ICQ9e3R5cGU6dm9pZCAwLHNpemU6MCxhcnJheTp2b2lkIDAscG9zaXRpb246MCxyZWFkQ291bnQ6MCxtYXA6dm9pZCAwLGtleTpudWxsfTt0aGlzLnN0YWNrLnB1c2goJCl9cmV0dXJuIHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl19cmVsZWFzZSgkKXtpZih0aGlzLnN0YWNrW3RoaXMuc3RhY2tIZWFkUG9zaXRpb25dIT09JCl0aHJvdyBFcnJvcigiSW52YWxpZCBzdGFjayBzdGF0ZS4gUmVsZWFzZWQgc3RhdGUgaXMgbm90IG9uIHRvcCBvZiB0aGUgc3RhY2suIik7aWYoJC50eXBlPT09WEope2xldCBaPSQ7Wi5zaXplPTAsWi5hcnJheT12b2lkIDAsWi5wb3NpdGlvbj0wLFoudHlwZT12b2lkIDB9aWYoJC50eXBlPT09eiR8fCQudHlwZT09PURaKXtsZXQgWj0kO1ouc2l6ZT0wLFoubWFwPXZvaWQgMCxaLnJlYWRDb3VudD0wLFoudHlwZT12b2lkIDB9dGhpcy5zdGFja0hlYWRQb3NpdGlvbi0tfXJlc2V0KCl7dGhpcy5zdGFjay5sZW5ndGg9MCx0aGlzLnN0YWNrSGVhZFBvc2l0aW9uPS0xfX12YXIgRyQ9LTEsV0o9bmV3IERhdGFWaWV3KG5ldyBBcnJheUJ1ZmZlcigwKSksd1k9bmV3IFVpbnQ4QXJyYXkoV0ouYnVmZmVyKTt0cnl7V0ouZ2V0SW50OCgwKX1jYXRjaCgkKXtpZighKCQgaW5zdGFuY2VvZiBSYW5nZUVycm9yKSl0aHJvdyBFcnJvcigiVGhpcyBtb2R1bGUgaXMgbm90IHN1cHBvcnRlZCBpbiB0aGUgY3VycmVudCBKYXZhU2NyaXB0IGVuZ2luZSBiZWNhdXNlIERhdGFWaWV3IGRvZXMgbm90IHRocm93IFJhbmdlRXJyb3Igb24gb3V0LW9mLWJvdW5kcyBhY2Nlc3MiKX12YXIgalo9UmFuZ2VFcnJvcigiSW5zdWZmaWNpZW50IGRhdGEiKSxUWT1uZXcgVko7Y2xhc3MgRCR7ZXh0ZW5zaW9uQ29kZWM7Y29udGV4dDt1c2VCaWdJbnQ2NDtyYXdTdHJpbmdzO21heFN0ckxlbmd0aDttYXhCaW5MZW5ndGg7bWF4QXJyYXlMZW5ndGg7bWF4TWFwTGVuZ3RoO21heEV4dExlbmd0aDtrZXlEZWNvZGVyO21hcEtleUNvbnZlcnRlcjt0b3RhbFBvcz0wO3Bvcz0wO3ZpZXc9V0o7Ynl0ZXM9d1k7aGVhZEJ5dGU9RyQ7c3RhY2s9bmV3IEFaO2VudGVyZWQ9ITE7Y29uc3RydWN0b3IoJCl7dGhpcy5leHRlbnNpb25Db2RlYz0kPy5leHRlbnNpb25Db2RlYz8/YTAuZGVmYXVsdENvZGVjLHRoaXMuY29udGV4dD0kPy5jb250ZXh0LHRoaXMudXNlQmlnSW50NjQ9JD8udXNlQmlnSW50NjQ/PyExLHRoaXMucmF3U3RyaW5ncz0kPy5yYXdTdHJpbmdzPz8hMSx0aGlzLm1heFN0ckxlbmd0aD0kPy5tYXhTdHJMZW5ndGg/P28wLHRoaXMubWF4QmluTGVuZ3RoPSQ/Lm1heEJpbkxlbmd0aD8/bzAsdGhpcy5tYXhBcnJheUxlbmd0aD0kPy5tYXhBcnJheUxlbmd0aD8/bzAsdGhpcy5tYXhNYXBMZW5ndGg9JD8ubWF4TWFwTGVuZ3RoPz9vMCx0aGlzLm1heEV4dExlbmd0aD0kPy5tYXhFeHRMZW5ndGg/P28wLHRoaXMua2V5RGVjb2Rlcj0kPy5rZXlEZWNvZGVyIT09dm9pZCAwPyQua2V5RGVjb2RlcjpUWSx0aGlzLm1hcEtleUNvbnZlcnRlcj0kPy5tYXBLZXlDb252ZXJ0ZXI/P1BZfWNsb25lKCl7cmV0dXJuIG5ldyBEJCh7ZXh0ZW5zaW9uQ29kZWM6dGhpcy5leHRlbnNpb25Db2RlYyxjb250ZXh0OnRoaXMuY29udGV4dCx1c2VCaWdJbnQ2NDp0aGlzLnVzZUJpZ0ludDY0LHJhd1N0cmluZ3M6dGhpcy5yYXdTdHJpbmdzLG1heFN0ckxlbmd0aDp0aGlzLm1heFN0ckxlbmd0aCxtYXhCaW5MZW5ndGg6dGhpcy5tYXhCaW5MZW5ndGgsbWF4QXJyYXlMZW5ndGg6dGhpcy5tYXhBcnJheUxlbmd0aCxtYXhNYXBMZW5ndGg6dGhpcy5tYXhNYXBMZW5ndGgsbWF4RXh0TGVuZ3RoOnRoaXMubWF4RXh0TGVuZ3RoLGtleURlY29kZXI6dGhpcy5rZXlEZWNvZGVyfSl9cmVpbml0aWFsaXplU3RhdGUoKXt0aGlzLnRvdGFsUG9zPTAsdGhpcy5oZWFkQnl0ZT1HJCx0aGlzLnN0YWNrLnJlc2V0KCl9c2V0QnVmZmVyKCQpe2xldCBKPVckKCQpO3RoaXMuYnl0ZXM9Six0aGlzLnZpZXc9bmV3IERhdGFWaWV3KEouYnVmZmVyLEouYnl0ZU9mZnNldCxKLmJ5dGVMZW5ndGgpLHRoaXMucG9zPTB9YXBwZW5kQnVmZmVyKCQpe2lmKHRoaXMuaGVhZEJ5dGU9PT1HJCYmIXRoaXMuaGFzUmVtYWluaW5nKDEpKXRoaXMuc2V0QnVmZmVyKCQpO2Vsc2V7bGV0IEo9dGhpcy5ieXRlcy5zdWJhcnJheSh0aGlzLnBvcyksWj1XJCgkKSxRPW5ldyBVaW50OEFycmF5KEoubGVuZ3RoK1oubGVuZ3RoKTtRLnNldChKKSxRLnNldChaLEoubGVuZ3RoKSx0aGlzLnNldEJ1ZmZlcihRKX19aGFzUmVtYWluaW5nKCQpe3JldHVybiB0aGlzLnZpZXcuYnl0ZUxlbmd0aC10aGlzLnBvcz49JH1jcmVhdGVFeHRyYUJ5dGVFcnJvcigkKXtsZXR7dmlldzpKLHBvczpafT10aGlzO3JldHVybiBSYW5nZUVycm9yKGBFeHRyYSAke0ouYnl0ZUxlbmd0aC1afSBvZiAke0ouYnl0ZUxlbmd0aH0gYnl0ZShzKSBmb3VuZCBhdCBidWZmZXJbJHskfV1gKX1kZWNvZGUoJCl7aWYodGhpcy5lbnRlcmVkKXJldHVybiB0aGlzLmNsb25lKCkuZGVjb2RlKCQpO3RyeXt0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuc2V0QnVmZmVyKCQpO2xldCBKPXRoaXMuZG9EZWNvZGVTeW5jKCk7aWYodGhpcy5oYXNSZW1haW5pbmcoMSkpdGhyb3cgdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnBvcyk7cmV0dXJuIEp9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fSpkZWNvZGVNdWx0aSgkKXtpZih0aGlzLmVudGVyZWQpe3lpZWxkKnRoaXMuY2xvbmUoKS5kZWNvZGVNdWx0aSgkKTtyZXR1cm59dHJ5e3RoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5zZXRCdWZmZXIoJCk7d2hpbGUodGhpcy5oYXNSZW1haW5pbmcoMSkpeWllbGQgdGhpcy5kb0RlY29kZVN5bmMoKX1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19YXN5bmMgZGVjb2RlQXN5bmMoJCl7aWYodGhpcy5lbnRlcmVkKXJldHVybiB0aGlzLmNsb25lKCkuZGVjb2RlQXN5bmMoJCk7dHJ5e3RoaXMuZW50ZXJlZD0hMDtsZXQgSj0hMSxaO2ZvciBhd2FpdChsZXQgWCBvZiAkKXtpZihKKXRocm93IHRoaXMuZW50ZXJlZD0hMSx0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMudG90YWxQb3MpO3RoaXMuYXBwZW5kQnVmZmVyKFgpO3RyeXtaPXRoaXMuZG9EZWNvZGVTeW5jKCksSj0hMH1jYXRjaChXKXtpZighKFcgaW5zdGFuY2VvZiBSYW5nZUVycm9yKSl0aHJvdyBXfXRoaXMudG90YWxQb3MrPXRoaXMucG9zfWlmKEope2lmKHRoaXMuaGFzUmVtYWluaW5nKDEpKXRocm93IHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7cmV0dXJuIFp9bGV0e2hlYWRCeXRlOlEscG9zOlksdG90YWxQb3M6Vn09dGhpczt0aHJvdyBSYW5nZUVycm9yKGBJbnN1ZmZpY2llbnQgZGF0YSBpbiBwYXJzaW5nICR7aiQoUSl9IGF0ICR7Vn0gKCR7WX0gaW4gdGhlIGN1cnJlbnQgYnVmZmVyKWApfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kZWNvZGVBcnJheVN0cmVhbSgkKXtyZXR1cm4gdGhpcy5kZWNvZGVNdWx0aUFzeW5jKCQsITApfWRlY29kZVN0cmVhbSgkKXtyZXR1cm4gdGhpcy5kZWNvZGVNdWx0aUFzeW5jKCQsITEpfWFzeW5jKmRlY29kZU11bHRpQXN5bmMoJCxKKXtpZih0aGlzLmVudGVyZWQpe3lpZWxkKnRoaXMuY2xvbmUoKS5kZWNvZGVNdWx0aUFzeW5jKCQsSik7cmV0dXJufXRyeXt0aGlzLmVudGVyZWQ9ITA7bGV0IFo9SixRPS0xO2ZvciBhd2FpdChsZXQgWSBvZiAkKXtpZihKJiZRPT09MCl0aHJvdyB0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMudG90YWxQb3MpO2lmKHRoaXMuYXBwZW5kQnVmZmVyKFkpLFopUT10aGlzLnJlYWRBcnJheVNpemUoKSxaPSExLHRoaXMuY29tcGxldGUoKTt0cnl7d2hpbGUoITApaWYoeWllbGQgdGhpcy5kb0RlY29kZVN5bmMoKSwtLVE9PT0wKWJyZWFrfWNhdGNoKFYpe2lmKCEoViBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IFZ9dGhpcy50b3RhbFBvcys9dGhpcy5wb3N9fWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kb0RlY29kZVN5bmMoKXskOndoaWxlKCEwKXtsZXQgJD10aGlzLnJlYWRIZWFkQnl0ZSgpLEo7aWYoJD49MjI0KUo9JC0yNTY7ZWxzZSBpZigkPDE5MilpZigkPDEyOClKPSQ7ZWxzZSBpZigkPDE0NCl7bGV0IFE9JC0xMjg7aWYoUSE9PTApe3RoaXMucHVzaE1hcFN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj17fX1lbHNlIGlmKCQ8MTYwKXtsZXQgUT0kLTE0NDtpZihRIT09MCl7dGhpcy5wdXNoQXJyYXlTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIEo9W119ZWxzZXtsZXQgUT0kLTE2MDtKPXRoaXMuZGVjb2RlU3RyaW5nKFEsMCl9ZWxzZSBpZigkPT09MTkyKUo9bnVsbDtlbHNlIGlmKCQ9PT0xOTQpSj0hMTtlbHNlIGlmKCQ9PT0xOTUpSj0hMDtlbHNlIGlmKCQ9PT0yMDIpSj10aGlzLnJlYWRGMzIoKTtlbHNlIGlmKCQ9PT0yMDMpSj10aGlzLnJlYWRGNjQoKTtlbHNlIGlmKCQ9PT0yMDQpSj10aGlzLnJlYWRVOCgpO2Vsc2UgaWYoJD09PTIwNSlKPXRoaXMucmVhZFUxNigpO2Vsc2UgaWYoJD09PTIwNilKPXRoaXMucmVhZFUzMigpO2Vsc2UgaWYoJD09PTIwNylpZih0aGlzLnVzZUJpZ0ludDY0KUo9dGhpcy5yZWFkVTY0QXNCaWdJbnQoKTtlbHNlIEo9dGhpcy5yZWFkVTY0KCk7ZWxzZSBpZigkPT09MjA4KUo9dGhpcy5yZWFkSTgoKTtlbHNlIGlmKCQ9PT0yMDkpSj10aGlzLnJlYWRJMTYoKTtlbHNlIGlmKCQ9PT0yMTApSj10aGlzLnJlYWRJMzIoKTtlbHNlIGlmKCQ9PT0yMTEpaWYodGhpcy51c2VCaWdJbnQ2NClKPXRoaXMucmVhZEk2NEFzQmlnSW50KCk7ZWxzZSBKPXRoaXMucmVhZEk2NCgpO2Vsc2UgaWYoJD09PTIxNyl7bGV0IFE9dGhpcy5sb29rVTgoKTtKPXRoaXMuZGVjb2RlU3RyaW5nKFEsMSl9ZWxzZSBpZigkPT09MjE4KXtsZXQgUT10aGlzLmxvb2tVMTYoKTtKPXRoaXMuZGVjb2RlU3RyaW5nKFEsMil9ZWxzZSBpZigkPT09MjE5KXtsZXQgUT10aGlzLmxvb2tVMzIoKTtKPXRoaXMuZGVjb2RlU3RyaW5nKFEsNCl9ZWxzZSBpZigkPT09MjIwKXtsZXQgUT10aGlzLnJlYWRVMTYoKTtpZihRIT09MCl7dGhpcy5wdXNoQXJyYXlTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIEo9W119ZWxzZSBpZigkPT09MjIxKXtsZXQgUT10aGlzLnJlYWRVMzIoKTtpZihRIT09MCl7dGhpcy5wdXNoQXJyYXlTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIEo9W119ZWxzZSBpZigkPT09MjIyKXtsZXQgUT10aGlzLnJlYWRVMTYoKTtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBKPXt9fWVsc2UgaWYoJD09PTIyMyl7bGV0IFE9dGhpcy5yZWFkVTMyKCk7aWYoUSE9PTApe3RoaXMucHVzaE1hcFN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgSj17fX1lbHNlIGlmKCQ9PT0xOTYpe2xldCBRPXRoaXMubG9va1U4KCk7Sj10aGlzLmRlY29kZUJpbmFyeShRLDEpfWVsc2UgaWYoJD09PTE5Nyl7bGV0IFE9dGhpcy5sb29rVTE2KCk7Sj10aGlzLmRlY29kZUJpbmFyeShRLDIpfWVsc2UgaWYoJD09PTE5OCl7bGV0IFE9dGhpcy5sb29rVTMyKCk7Sj10aGlzLmRlY29kZUJpbmFyeShRLDQpfWVsc2UgaWYoJD09PTIxMilKPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDEsMCk7ZWxzZSBpZigkPT09MjEzKUo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMiwwKTtlbHNlIGlmKCQ9PT0yMTQpSj10aGlzLmRlY29kZUV4dGVuc2lvbig0LDApO2Vsc2UgaWYoJD09PTIxNSlKPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDgsMCk7ZWxzZSBpZigkPT09MjE2KUo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMTYsMCk7ZWxzZSBpZigkPT09MTk5KXtsZXQgUT10aGlzLmxvb2tVOCgpO0o9dGhpcy5kZWNvZGVFeHRlbnNpb24oUSwxKX1lbHNlIGlmKCQ9PT0yMDApe2xldCBRPXRoaXMubG9va1UxNigpO0o9dGhpcy5kZWNvZGVFeHRlbnNpb24oUSwyKX1lbHNlIGlmKCQ9PT0yMDEpe2xldCBRPXRoaXMubG9va1UzMigpO0o9dGhpcy5kZWNvZGVFeHRlbnNpb24oUSw0KX1lbHNlIHRocm93IG5ldyBlKGBVbnJlY29nbml6ZWQgdHlwZSBieXRlOiAke2okKCQpfWApO3RoaXMuY29tcGxldGUoKTtsZXQgWj10aGlzLnN0YWNrO3doaWxlKFoubGVuZ3RoPjApe2xldCBRPVoudG9wKCk7aWYoUS50eXBlPT09WEopaWYoUS5hcnJheVtRLnBvc2l0aW9uXT1KLFEucG9zaXRpb24rKyxRLnBvc2l0aW9uPT09US5zaXplKUo9US5hcnJheSxaLnJlbGVhc2UoUSk7ZWxzZSBjb250aW51ZSAkO2Vsc2UgaWYoUS50eXBlPT09eiQpe2lmKEo9PT0iX19wcm90b19fIil0aHJvdyBuZXcgZSgiVGhlIGtleSBfX3Byb3RvX18gaXMgbm90IGFsbG93ZWQiKTtRLmtleT10aGlzLm1hcEtleUNvbnZlcnRlcihKKSxRLnR5cGU9RFo7Y29udGludWUgJH1lbHNlIGlmKFEubWFwW1Eua2V5XT1KLFEucmVhZENvdW50KyssUS5yZWFkQ291bnQ9PT1RLnNpemUpSj1RLm1hcCxaLnJlbGVhc2UoUSk7ZWxzZXtRLmtleT1udWxsLFEudHlwZT16JDtjb250aW51ZSAkfX1yZXR1cm4gSn19cmVhZEhlYWRCeXRlKCl7aWYodGhpcy5oZWFkQnl0ZT09PUckKXRoaXMuaGVhZEJ5dGU9dGhpcy5yZWFkVTgoKTtyZXR1cm4gdGhpcy5oZWFkQnl0ZX1jb21wbGV0ZSgpe3RoaXMuaGVhZEJ5dGU9RyR9cmVhZEFycmF5U2l6ZSgpe2xldCAkPXRoaXMucmVhZEhlYWRCeXRlKCk7c3dpdGNoKCQpe2Nhc2UgMjIwOnJldHVybiB0aGlzLnJlYWRVMTYoKTtjYXNlIDIyMTpyZXR1cm4gdGhpcy5yZWFkVTMyKCk7ZGVmYXVsdDppZigkPDE2MClyZXR1cm4gJC0xNDQ7ZWxzZSB0aHJvdyBuZXcgZShgVW5yZWNvZ25pemVkIGFycmF5IHR5cGUgYnl0ZTogJHtqJCgkKX1gKX19cHVzaE1hcFN0YXRlKCQpe2lmKCQ+dGhpcy5tYXhNYXBMZW5ndGgpdGhyb3cgbmV3IGUoYE1heCBsZW5ndGggZXhjZWVkZWQ6IG1hcCBsZW5ndGggKCR7JH0pID4gbWF4TWFwTGVuZ3RoTGVuZ3RoICgke3RoaXMubWF4TWFwTGVuZ3RofSlgKTt0aGlzLnN0YWNrLnB1c2hNYXBTdGF0ZSgkKX1wdXNoQXJyYXlTdGF0ZSgkKXtpZigkPnRoaXMubWF4QXJyYXlMZW5ndGgpdGhyb3cgbmV3IGUoYE1heCBsZW5ndGggZXhjZWVkZWQ6IGFycmF5IGxlbmd0aCAoJHskfSkgPiBtYXhBcnJheUxlbmd0aCAoJHt0aGlzLm1heEFycmF5TGVuZ3RofSlgKTt0aGlzLnN0YWNrLnB1c2hBcnJheVN0YXRlKCQpfWRlY29kZVN0cmluZygkLEope2lmKCF0aGlzLnJhd1N0cmluZ3N8fHRoaXMuc3RhdGVJc01hcEtleSgpKXJldHVybiB0aGlzLmRlY29kZVV0ZjhTdHJpbmcoJCxKKTtyZXR1cm4gdGhpcy5kZWNvZGVCaW5hcnkoJCxKKX1kZWNvZGVVdGY4U3RyaW5nKCQsSil7aWYoJD50aGlzLm1heFN0ckxlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogVVRGLTggYnl0ZSBsZW5ndGggKCR7JH0pID4gbWF4U3RyTGVuZ3RoICgke3RoaXMubWF4U3RyTGVuZ3RofSlgKTtpZih0aGlzLmJ5dGVzLmJ5dGVMZW5ndGg8dGhpcy5wb3MrSiskKXRocm93IGpaO2xldCBaPXRoaXMucG9zK0osUTtpZih0aGlzLnN0YXRlSXNNYXBLZXkoKSYmdGhpcy5rZXlEZWNvZGVyPy5jYW5CZUNhY2hlZCgkKSlRPXRoaXMua2V5RGVjb2Rlci5kZWNvZGUodGhpcy5ieXRlcyxaLCQpO2Vsc2UgUT1DWih0aGlzLmJ5dGVzLFosJCk7cmV0dXJuIHRoaXMucG9zKz1KKyQsUX1zdGF0ZUlzTWFwS2V5KCl7aWYodGhpcy5zdGFjay5sZW5ndGg+MClyZXR1cm4gdGhpcy5zdGFjay50b3AoKS50eXBlPT09eiQ7cmV0dXJuITF9ZGVjb2RlQmluYXJ5KCQsSil7aWYoJD50aGlzLm1heEJpbkxlbmd0aCl0aHJvdyBuZXcgZShgTWF4IGxlbmd0aCBleGNlZWRlZDogYmluIGxlbmd0aCAoJHskfSkgPiBtYXhCaW5MZW5ndGggKCR7dGhpcy5tYXhCaW5MZW5ndGh9KWApO2lmKCF0aGlzLmhhc1JlbWFpbmluZygkK0opKXRocm93IGpaO2xldCBaPXRoaXMucG9zK0osUT10aGlzLmJ5dGVzLnN1YmFycmF5KFosWiskKTtyZXR1cm4gdGhpcy5wb3MrPUorJCxRfWRlY29kZUV4dGVuc2lvbigkLEope2lmKCQ+dGhpcy5tYXhFeHRMZW5ndGgpdGhyb3cgbmV3IGUoYE1heCBsZW5ndGggZXhjZWVkZWQ6IGV4dCBsZW5ndGggKCR7JH0pID4gbWF4RXh0TGVuZ3RoICgke3RoaXMubWF4RXh0TGVuZ3RofSlgKTtsZXQgWj10aGlzLnZpZXcuZ2V0SW50OCh0aGlzLnBvcytKKSxRPXRoaXMuZGVjb2RlQmluYXJ5KCQsSisxKTtyZXR1cm4gdGhpcy5leHRlbnNpb25Db2RlYy5kZWNvZGUoUSxaLHRoaXMuY29udGV4dCl9bG9va1U4KCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50OCh0aGlzLnBvcyl9bG9va1UxNigpe3JldHVybiB0aGlzLnZpZXcuZ2V0VWludDE2KHRoaXMucG9zKX1sb29rVTMyKCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50MzIodGhpcy5wb3MpfXJlYWRVOCgpe2xldCAkPXRoaXMudmlldy5nZXRVaW50OCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKyssJH1yZWFkSTgoKXtsZXQgJD10aGlzLnZpZXcuZ2V0SW50OCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKyssJH1yZWFkVTE2KCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQxNih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz0yLCR9cmVhZEkxNigpe2xldCAkPXRoaXMudmlldy5nZXRJbnQxNih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz0yLCR9cmVhZFUzMigpe2xldCAkPXRoaXMudmlldy5nZXRVaW50MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRJMzIoKXtsZXQgJD10aGlzLnZpZXcuZ2V0SW50MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRVNjQoKXtsZXQgJD13Wih0aGlzLnZpZXcsdGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCwkfXJlYWRJNjQoKXtsZXQgJD13JCh0aGlzLnZpZXcsdGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCwkfXJlYWRVNjRBc0JpZ0ludCgpe2xldCAkPXRoaXMudmlldy5nZXRCaWdVaW50NjQodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCwkfXJlYWRJNjRBc0JpZ0ludCgpe2xldCAkPXRoaXMudmlldy5nZXRCaWdJbnQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEYzMigpe2xldCAkPXRoaXMudmlldy5nZXRGbG9hdDMyKHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTQsJH1yZWFkRjY0KCl7bGV0ICQ9dGhpcy52aWV3LmdldEZsb2F0NjQodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9OCwkfX1mdW5jdGlvbiBHSigkLEope3JldHVybiBuZXcgRCQoSikuZGVjb2RlKCQpfWNsYXNzIEske2xpc3RlbmVycz1uZXcgTWFwO2FkZEV2ZW50TGlzdGVuZXIoJCxKKXtsZXQgWj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoIVopWj1uZXcgU2V0LHRoaXMubGlzdGVuZXJzLnNldCgkLFopO3JldHVybiBaLmFkZChKKSwoKT0+e3RoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcigkLEopfX1yZW1vdmVFdmVudExpc3RlbmVyKCQsSil7bGV0IFo9dGhpcy5saXN0ZW5lcnMuZ2V0KCQpO2lmKFope2lmKFouZGVsZXRlKEopLFouc2l6ZT09PTApdGhpcy5saXN0ZW5lcnMuZGVsZXRlKCQpfX1lbWl0KCQsSil7bGV0IFo9dGhpcy5saXN0ZW5lcnMuZ2V0KCQpO2lmKFope2xldCBRPUFycmF5LmZyb20oWik7Zm9yKGxldCBZIG9mIFEpWShKKX19ZW1pdEFsbCgkKXtsZXQgSj1BcnJheS5mcm9tKHRoaXMubGlzdGVuZXJzLmtleXMoKSk7Zm9yKGxldCBaIG9mIEopdGhpcy5lbWl0KFosJCl9fWNsYXNzIGYwe2dldHRlcjtzdGF0aWMgZXZlbnROYW1lPSJ1cGRhdGUiO2VtaXR0ZXI7Y29uc3RydWN0b3IoJCl7dGhpcy5nZXR0ZXI9JDt0aGlzLmVtaXR0ZXI9bmV3IEskfWdldD0oKT0+dGhpcy5nZXR0ZXIoKTthc3luYyBlbWl0KCl7bGV0ICQ9YXdhaXQgdGhpcy5nZXR0ZXIoKTtxdWV1ZU1pY3JvdGFzaygoKT0+dGhpcy5lbWl0dGVyLmVtaXQoZjAuZXZlbnROYW1lLCQpKX1saXN0ZW4oJCl7cmV0dXJuIHRoaXMuZW1pdHRlci5hZGRFdmVudExpc3RlbmVyKGYwLmV2ZW50TmFtZSwkKSwoKT0+e3RoaXMuZW1pdHRlci5yZW1vdmVFdmVudExpc3RlbmVyKGYwLmV2ZW50TmFtZSwkKX19fWZ1bmN0aW9uIE8oJCl7cmV0dXJuWyQsMF19ZnVuY3Rpb24gRygkKXtyZXR1cm5bdm9pZCAwLCRdfWZ1bmN0aW9uIGpZKCQpe2lmKCQ8MCljb25zb2xlLmluZm8oIk4iLCQpLGNvbnNvbGUudHJhY2UoKTtpZih0eXBlb2YgJCE9PSJiaWdpbnQiKSQ9QmlnSW50KCQpO2lmKCQ8MG4pcmV0dXJuIEcoMTApO2xldCBKPVtdO3doaWxlKCQ+MG4pe2xldCBaPU51bWJlcigkJjB4N2ZuKTtpZigkPj49N24sJD4wbilKLnB1c2goWnwxMjgpO2Vsc2UgSi5wdXNoKFopfWlmKEoubGVuZ3RoPT09MClyZXR1cm4gTyhuZXcgVWludDhBcnJheShbMF0pKTtpZihKLmxlbmd0aD44KXJldHVybiBHKDI2KTtyZXR1cm4gTyhuZXcgVWludDhBcnJheShKKSl9ZnVuY3Rpb24gRFkoJCxKPTApe2xldCBaPTBuLFE9MCxZPUo7d2hpbGUoITApe2lmKFk+PSQubGVuZ3RoKXJldHVybiBHKDE0KTtsZXQgVj0kW1krK107aWYoVj09PXZvaWQgMClyZXR1cm4gRygxNCk7aWYoWnw9QmlnSW50KFYmMTI3KTw8QmlnSW50KFEpLChWJjEyOCk9PT0wKXtpZihZLUo+OClyZXR1cm4gRygyNik7cmV0dXJuIE8oe3ZhbHVlOlo+MHgxZmZmZmZmZmZmZmZmZm4/WjpOdW1iZXIoWiksYnl0ZXNSZWFkOlktSn0pfWlmKFErPTcsUT49NTYpcmV0dXJuIEcoMjYpfX1jbGFzcyBte2RhdGE7cG9zPTA7Y29uc3RydWN0b3IoJCl7dGhpcy5kYXRhPSR9c3RhdGljIGFzeW5jIGZyb21SZXNwb25zZSgkKXtsZXQgSj1hd2FpdCAkLmFycmF5QnVmZmVyKCksWj1uZXcgVWludDhBcnJheShKKTtyZXR1cm4gbmV3IG0oWil9cmVhZEJpZ0ludCgpe2lmKHRoaXMucG9zKzg+dGhpcy5kYXRhLmxlbmd0aClyZXR1cm4gRyg3KTtsZXQgJD1uZXcgRGF0YVZpZXcodGhpcy5kYXRhLmJ1ZmZlcix0aGlzLmRhdGEuYnl0ZU9mZnNldCt0aGlzLnBvcykuZ2V0QmlnVWludDY0KDAsITEpO3JldHVybiB0aGlzLnBvcys9OCxPKCQpfXJlYWREYXRlKCl7bGV0WyQsSl09dGhpcy5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7cmV0dXJuIE8obmV3IERhdGUoJCkpfXJlYWRWYXJJbnQoKXtsZXRbJCxKXT1EWSh0aGlzLmRhdGEsdGhpcy5wb3MpO2lmKEohPT0wKXJldHVybiBHKEopO3RoaXMucG9zKz0kLmJ5dGVzUmVhZDtsZXQgWj0kLnZhbHVlO3JldHVybiBPKHR5cGVvZiBaPT09ImJpZ2ludCI/TnVtYmVyKFopOlopfXJlYWRWYXJTdHJpbmcoKXtsZXRbJCxKXT10aGlzLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbWixRXT10aGlzLnJlYWRCeXRlcygkKTtpZihRIT09MClyZXR1cm4gRyhRKTtsZXQgWT1uZXcgVGV4dERlY29kZXIoKS5kZWNvZGUoWik7cmV0dXJuIE8oWSl9cmVhZEJ5dGVzKCQpe2lmKCQ8MClyZXR1cm4gRygxMCk7aWYodGhpcy5wb3MrJD50aGlzLmRhdGEubGVuZ3RoKXJldHVybiBHKDIzKTtsZXQgSj10aGlzLmRhdGEuc2xpY2UodGhpcy5wb3MsdGhpcy5wb3MrJCk7cmV0dXJuIHRoaXMucG9zKz0kLE8oSil9cmVhZFZhckJ5dGVzKCl7bGV0WyQsSl09dGhpcy5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7cmV0dXJuIHRoaXMucmVhZEJ5dGVzKCQpfXJlYWRTdHJ1Y3QoJCl7cmV0dXJuICQuZGVjb2RlKHRoaXMpfXJlYWRTdHJ1Y3RzKCQpe2xldCBKPVtdO3doaWxlKCF0aGlzLmRvbmUoKSl7bGV0W1osUV09dGhpcy5yZWFkU3RydWN0KCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO0oucHVzaChaKX1yZXR1cm4gTyhKKX1yZWFkQnl0ZXNTZXEoJCl7bGV0IEo9W107d2hpbGUoIXRoaXMuZG9uZSgpKXtsZXRbWixRXT10aGlzLnJlYWRCeXRlcygkKTtpZihRIT09MClyZXR1cm4gRyhRKTtKLnB1c2goWil9cmV0dXJuIE8oSil9ZG9uZSgpe3JldHVybiB0aGlzLnBvcz49dGhpcy5kYXRhLmxlbmd0aH1jb25zdW1lZCgpe3JldHVybiB0aGlzLnBvc319Y2xhc3MgU3twYXJ0cz1bXTt3cml0ZUJpZ0ludCgkKXtsZXQgSj1uZXcgVWludDhBcnJheSg4KTtuZXcgRGF0YVZpZXcoSi5idWZmZXIpLnNldEJpZ1VpbnQ2NCgwLCQsITEpLHRoaXMucGFydHMucHVzaChKKX13cml0ZURhdGUoJCl7bGV0IEo9JC5nZXRUaW1lKCk7cmV0dXJuIHRoaXMud3JpdGVWYXJJbnQoSil9d3JpdGVWYXJJbnQoJCl7bGV0W0osWl09alkoJCk7aWYoWiE9PTApcmV0dXJuIFo7cmV0dXJuIHRoaXMucGFydHMucHVzaChKKSwwfXdyaXRlVmFyU3RyaW5nKCQpe2xldCBKPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSxaPXRoaXMud3JpdGVWYXJJbnQoSi5sZW5ndGgpO2lmKFohPT0wKXJldHVybiBaO3JldHVybiB0aGlzLndyaXRlQnl0ZXMoSiksMH1wcmVwZW5kQnl0ZXMoJCl7dGhpcy5wYXJ0cy51bnNoaWZ0KCQuc2xpY2UoKSl9d3JpdGVCeXRlcygkKXt0aGlzLnBhcnRzLnB1c2goJC5zbGljZSgpKX13cml0ZVZhckJ5dGVzKCQpe2xldCBKPXRoaXMud3JpdGVWYXJJbnQoJC5sZW5ndGgpO2lmKEohPT0wKXJldHVybiBKO3JldHVybiB0aGlzLndyaXRlQnl0ZXMoJCksMH13cml0ZVN0cnVjdCgkLEope3JldHVybiAkLmVuY29kZSh0aGlzLEopfXdyaXRlU3RydWN0cygkLEope2ZvcihsZXQgWiBvZiBKKXtsZXQgUT10aGlzLndyaXRlU3RydWN0KCQsWik7aWYoUSE9PTApcmV0dXJuIFF9cmV0dXJuIDB9d3JpdGVCeXRlc1NlcSgkKXtmb3IobGV0IEogb2YgJCl0aGlzLndyaXRlQnl0ZXMoSil9cmVzdWx0KCl7bGV0ICQ9dGhpcy5wYXJ0cy5yZWR1Y2UoKFEsWSk9PlErWS5sZW5ndGgsMCksSj1uZXcgVWludDhBcnJheSgkKSxaPTA7Zm9yKGxldCBRIG9mIHRoaXMucGFydHMpSi5zZXQoUSxaKSxaKz1RLmxlbmd0aDtyZXR1cm4gSn13aXBlKCl7Zm9yKGxldCAkIG9mIHRoaXMucGFydHMpJC5maWxsKDApO3RoaXMucGFydHMubGVuZ3RoPTB9KnNjYW4oKXtmb3IobGV0ICQgb2YgdGhpcy5wYXJ0cyl5aWVsZCAkfX1hc3luYyBmdW5jdGlvbiB6SigkLEope2xldCBaPW5ldyBTLFE9Wi53cml0ZURhdGUoSik7aWYoUSE9PTApcmV0dXJuIEcoUSk7bGV0IFk9Wi5yZXN1bHQoKSxWPWF3YWl0ICQuc2lnbihZKTtyZXR1cm4gTyh7cHViS2V5OiQucHVibGljS2V5LHNpZzpWLHRpbWVzdGFtcDpKfSl9YXN5bmMgZnVuY3Rpb24gTDAoJCxKLFope2xldCBRPVoubm93KCkuZ2V0VGltZSgpLFk9JC50aW1lc3RhbXAuZ2V0VGltZSgpO2lmKE1hdGguYWJzKFEtWSk+UlopcmV0dXJuIDQ7bGV0IFg9bmV3IFM7WC53cml0ZURhdGUoJC50aW1lc3RhbXApO2xldCBXPVgucmVzdWx0KCk7aWYoIWF3YWl0IEouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLFcsJC5wdWJLZXkpKXJldHVybiAzO3JldHVybiAwfXZhciBWMD17ZW5jb2RlKCQsSil7bGV0IFo9JC53cml0ZVZhckJ5dGVzKEouaWQpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVEYXRlKEoudHMpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFyQnl0ZXMoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWREYXRlKCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7cmV0dXJuIE8oe2lkOkosdHM6UX0pfX07ZnVuY3Rpb24gQSQoJCl7bGV0IEo9bmV3IFMsWj1KLndyaXRlU3RydWN0KFYwLCQpO2lmKFohPT0wKXJldHVybiBHKFopO2xldCBRPUoucmVzdWx0KCk7cmV0dXJuIE8oUSl9dmFyIEcwPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5laWQpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJJbnQoSi5vZmYpO2lmKFEhPT0wKXJldHVybiBRO2xldCBZPSQud3JpdGVWYXJJbnQoSi5jdHIpO2lmKFkhPT0wKXJldHVybiBZO2xldCBWPSQud3JpdGVWYXJJbnQoSi5sZW4pO2lmKFYhPT0wKXJldHVybiBWO2lmKEouaHNoKSQud3JpdGVCeXRlcyhKLmhzaCk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJCeXRlcygpO2lmKFohPT0wKXJldHVybiBHKFopO2xldCBRPW5ldyBtKEopLFssWV09VjAuZGVjb2RlKFEpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtXLHpdPSQucmVhZFZhckludCgpO2lmKHohPT0wKXJldHVybiBHKHopO2xldFtLLEZdPSQucmVhZFZhckludCgpO2lmKEYhPT0wKXJldHVybiBHKEYpO2xldCBOO2lmKEs+MCl7bGV0W1UsUl09JC5yZWFkQnl0ZXMoQyQpO2lmKFIhPT0wKXJldHVybiBHKFIpO049VX1yZXR1cm4gTyh7ZWlkOkosb2ZmOlYsY3RyOlcsbGVuOkssaHNoOk59KX19O2Z1bmN0aW9uIFUwKCQpe3JldHVybiBBcnJheS5mcm9tKCQpLm1hcCgoWik9PloudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIjAiKSkuam9pbigiIil9ZnVuY3Rpb24gX1ooJCl7aWYoJC5sZW5ndGglMiE9PTApdGhyb3cgRXJyb3IoIkludmFsaWQgaGV4IHN0cmluZyIpO2xldCBKPW5ldyBVaW50OEFycmF5KCQubGVuZ3RoLzIpO2ZvcihsZXQgWj0wO1o8JC5sZW5ndGg7Wis9MilKW1ovMl09TnVtYmVyLnBhcnNlSW50KCQuc3Vic3RyKFosMiksMTYpO3JldHVybiBKfWZ1bmN0aW9uIHIoJCxKKXtpZigkPT09SilyZXR1cm4hMDtpZigkLmJ5dGVMZW5ndGghPT1KLmJ5dGVMZW5ndGgpcmV0dXJuITE7cmV0dXJuICQuZXZlcnkoKFosUSk9Plo9PT1KW1FdKX12YXIgQjtpZih0eXBlb2YgVWludDhBcnJheS5wcm90b3R5cGUudG9CYXNlNjQ9PT0iZnVuY3Rpb24iKUI9KCQpPT4kLnRvQmFzZTY0KCk7ZWxzZSBCPSgkKT0+YnRvYShTdHJpbmcuZnJvbUNoYXJDb2RlKC4uLiQpKTt2YXIgTjA7aWYodHlwZW9mIFVpbnQ4QXJyYXkuZnJvbUJhc2U2ND09PSJmdW5jdGlvbiIpTjA9KCQpPT5VaW50OEFycmF5LmZyb21CYXNlNjQoJCk7ZWxzZSBOMD0oJCk9PlVpbnQ4QXJyYXkuZnJvbShhdG9iKCQpLChKKT0+Si5jaGFyQ29kZUF0KDApKTtmdW5jdGlvbiBMWigkKXtsZXQgSj0kLmxlbmd0aCU0PT09MD8iIjoiPSIucmVwZWF0KDQtJC5sZW5ndGglNCksWj0kLnJlcGxhY2UoLy0vZywiKyIpLnJlcGxhY2UoL18vZywiLyIpK0o7cmV0dXJuIE4wKFopfWZ1bmN0aW9uIFIwKCQsSil7bGV0IFo9bmV3IFVpbnQ4QXJyYXkoJC5sZW5ndGgrSi5sZW5ndGgpO3JldHVybiBaLnNldCgkLDApLFouc2V0KEosJC5sZW5ndGgpLFp9ZnVuY3Rpb24geFooJCxKLFope3JldHVybiBaLmNoZWNrU2lnRWQyNTUxOSgkLnNpZywkLmhlYWRDcGgsSil9YXN5bmMgZnVuY3Rpb24gQlooJCxKLFosUSl7bGV0IFk7aWYoJC5ib2QmJiQubGVuPjApWT1hd2FpdCBaLmJsYWtlMygkLmJvZCk7bGV0IFY9bmV3IFMsWD1HMC5lbmNvZGUoVix7Li4uJCxoc2g6WX0pO2lmKFghPT0wKXJldHVybiBHKFgpO2xldCBXPVYucmVzdWx0KCksej1hd2FpdCBKLmtkbUZvcihXKSxLPVEuZGVyaXZlQ2lwaGVyKHosImVuY3J5cHQiKSxGPWF3YWl0IEsuZW5jcnlwdChXKSxOPSQuYm9kP2F3YWl0IEsuZW5jcnlwdCgkLmJvZCk6bmV3IFVpbnQ4QXJyYXkoMCksVT1hd2FpdCBKLnNpZ24oRik7cmV0dXJuIE8oe3NpZzpVLGtkbTp6LGhlYWRDcGg6Rixib2R5Q3BoOk59KX1hc3luYyBmdW5jdGlvbiBLSigkLEosWixRLFkpe2xldCBWPW5ldyBtKCQpLFtYLFddPUcwLmRlY29kZShWKTtpZihXIT09MClyZXR1cm4gRygxNCk7bGV0IHo7dHJ5e3o9SiYmSi5sZW5ndGg+MD9hd2FpdCBaLmRlY3J5cHQoSik6dm9pZCAwfWNhdGNoe3JldHVybiBHKDIwKX1sZXQgSz1YLmhzaCYmej09PXZvaWQgMCxGPVguaHNoPT09dm9pZCAwJiZ6IT09dm9pZCAwO2lmKEt8fEYpcmV0dXJuIEcoMTkpO2lmKFguaHNoJiZ6KXtsZXQgVT1hd2FpdCBRLmJsYWtlMyh6KTtpZighcihVLFguaHNoKSlyZXR1cm4gRygxOSl9bGV0IE49WT8/YXdhaXQgUS5ibGFrZTMoJCk7cmV0dXJuIE8oe21zZ0hlYWQ6WCxib2Q6eixoZWFkSGFzaDpOfSl9Y2xhc3MgRkp7bm93KCl7cmV0dXJuIG5ldyBEYXRlfX1mdW5jdGlvbiBrWigkLEosWixRKXtsZXQgWT1KLmdldFRpbWUoKS0kLmdldFRpbWUoKSxWPVouZ2V0VGltZSgpLVEuZ2V0VGltZSgpO3JldHVybihZK1YpLzJ9dmFyIEYkPXtlbmNvZGUoJCxKKXtpZigkLndyaXRlVmFySW50KEoucXVvdGEpLEoucXVvdGE+MCl7aWYoSi51c2FnZT09PXZvaWQgMClyZXR1cm4gOTskLndyaXRlVmFySW50KEoudXNhZ2UpfXJldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFySW50KCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0IFE7aWYoSj4wKXtsZXRbWSxWXT0kLnJlYWRWYXJJbnQoKTtpZihWIT09MClyZXR1cm4gRyhWKTtRPVl9cmV0dXJuIE8oe3F1b3RhOkosdXNhZ2U6UX0pfX07dmFyIE5KPXtlbmNvZGUoJCxKKXskLndyaXRlQnl0ZXMobmV3IFVpbnQ4QXJyYXkoW0ouc3RhdHVzXSkpO2xldCBaPSQud3JpdGVEYXRlKEoudGltZVJjdmQpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVEYXRlKEoudGltZVNlbnQpO2lmKFEhPT0wKXJldHVybiBRO2xldCBZPSQud3JpdGVWYXJJbnQoSi5zdWJzY3JpcHRpb24udGVybSk7aWYoWSE9PTApcmV0dXJuIFk7bGV0IFY9JC53cml0ZVZhckludChKLnN1YnNjcmlwdGlvbi5lbGFwc2VkKTtpZihWIT09MClyZXR1cm4gVjtsZXQgWD0kLndyaXRlU3RydWN0KEYkLEouc3Vic2NyaXB0aW9uLnN0YXQpO2lmKFghPT0wKXJldHVybiBYO2xldCBXPSQud3JpdGVTdHJ1Y3QoRiQsSi5zdWJzY3JpcHRpb24uZHluKTtpZihXIT09MClyZXR1cm4gVztyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKDEpO2lmKFohPT0wKXJldHVybiBHKFopO2xldCBRPUpbMF0sW1ksVl09JC5yZWFkRGF0ZSgpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtYLFddPSQucmVhZERhdGUoKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXRbeixLXT0kLnJlYWRWYXJJbnQoKTtpZihLIT09MClyZXR1cm4gRyhLKTtsZXRbRixOXT0kLnJlYWRWYXJJbnQoKTtpZihOIT09MClyZXR1cm4gRyhOKTtsZXRbVSxSXT0kLnJlYWRTdHJ1Y3QoRiQpO2lmKFIhPT0wKXJldHVybiBHKFIpO2xldFtxLEhdPSQucmVhZFN0cnVjdChGJCk7aWYoSCE9PTApcmV0dXJuIEcoSCk7cmV0dXJuIE8oe3N0YXR1czpRLHRpbWVSY3ZkOlksdGltZVNlbnQ6WCxzdWJzY3JpcHRpb246e3Rlcm06eixlbGFwc2VkOkYsc3RhdDpVLGR5bjpxfX0pfX07dmFyIE9KPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5oZWFkQ3BoKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFySW50KEouc2VxKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhckJ5dGVzKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09JC5yZWFkVmFySW50KCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7cmV0dXJuIE8oe2hlYWRDcGg6SixzZXE6UX0pfX07dmFyIFgwPXtlbmNvZGUoJCxKKXskLndyaXRlQnl0ZXMoSi5wdWJLZXkpLCQud3JpdGVCeXRlcyhKLnNpZyk7bGV0IFo9JC53cml0ZURhdGUoSi50aW1lc3RhbXApO2lmKFohPT0wKXJldHVybiBaO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkQnl0ZXMoVVopO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZEJ5dGVzKEEwKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWREYXRlKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIE8oe3B1YktleTpKLHNpZzpRLHRpbWVzdGFtcDpWfSl9fTt2YXIgRVo9e2FzeW5jIGVuY29kZVJlcSgkLEosWixRLFkpe2xldCBWPVkud3JpdGVTdHJ1Y3QoWDAsWik7aWYoViE9PTApcmV0dXJuIFY7Zm9yKGxldCBYIG9mIFEpWS53cml0ZVZhckludChYKTtyZXR1cm4gMH0sYXN5bmMgaGFuZGxlUmVxKCQsSixaKXtsZXR7Y2xvY2s6USxjcnlwdG86WSxzdG9yYWdlOlZ9PSQsW1gsV109Si5yZWFkU3RydWN0KFgwKTtpZihXIT09MClyZXR1cm4gVztsZXQgej1hd2FpdCBMMChYLFksUSk7aWYoeiE9PTApcmV0dXJuIHo7bGV0e3B1YktleTpLfT1YLFtGLE5dPWF3YWl0IFYuaGFzVXNlcihLKTtpZihOIT09MClyZXR1cm4gTjtpZighRilyZXR1cm4gNTtsZXRbVSxSXT1KLnJlYWRWYXJJbnQoKTtpZihSIT09MClyZXR1cm4gUjtpZighSi5kb25lKCkpcmV0dXJuIDg7bGV0W3EsSF09YXdhaXQgVi5saXN0SGVhZHMoSyxVKTtpZihIIT09MClyZXR1cm4gSDtyZXR1cm4gWi53cml0ZVN0cnVjdHMoT0oscSl9LGRlY29kZVJlc3AoJCl7cmV0dXJuICQucmVhZFN0cnVjdHMoT0opfX07dmFyIFVKPXtlbmNvZGUoJCxKKXskLndyaXRlVmFySW50KEouc2VxKTtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5ib2R5Q3BoKTtpZihaIT09MClyZXR1cm4gWjtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZFZhckludCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPSQucmVhZFZhckJ5dGVzKCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7cmV0dXJuIE8oe3NlcTpKLGJvZHlDcGg6UX0pfX07dmFyIGZaPXthc3luYyBlbmNvZGVSZXEoJCxKLFosUSxZKXtsZXQgVj1ZLndyaXRlU3RydWN0KFgwLFopO2lmKFYhPT0wKXJldHVybiBWO2ZvcihsZXQgWCBvZiBRKXtsZXQgVz1ZLndyaXRlVmFySW50KFgpO2lmKFchPT0wKXJldHVybiBXfXJldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxKLFope2xldHtjbG9jazpRLGNyeXB0bzpZLHN0b3JhZ2U6Vn09JCxbWCxXXT1KLnJlYWRTdHJ1Y3QoWDApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEwwKFgsWSxRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVgsW0YsTl09YXdhaXQgVi5oYXNVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO2lmKCFGKXJldHVybiA1O2xldCBVPVtdO3doaWxlKCFKLmRvbmUoKSl7bGV0W0gsTV09Si5yZWFkVmFySW50KCk7aWYoTSE9PTApcmV0dXJuIE07VS5wdXNoKEgpfWNvbnNvbGUuaW5mbyhgUFVMTDogJHtVLmxlbmd0aH0gYmFnc2ApO2xldFtSLHFdPWF3YWl0IFYuZ2V0Qm9kaWVzKEssVSk7aWYocSE9PTApcmV0dXJuIHE7aWYoIVIpcmV0dXJuIDE3O2ZvcihsZXR7c2VxOkgsYm9keUNwaDpNfW9mIFIpe2xldCBQPXtzZXE6SCxib2R5Q3BoOk19LEM9Wi53cml0ZVN0cnVjdChVSixQKTtpZihDIT09MClyZXR1cm4gQ31yZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyhVSil9fTt2YXIgUko9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhKLnNpZyksJC53cml0ZUJ5dGVzKEoua2RtKTtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5oZWFkQ3BoKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFyQnl0ZXMoSi5ib2R5Q3BoKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKEEwKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRCeXRlcyhfMCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbVyx6XT0kLnJlYWRWYXJCeXRlcygpO2lmKHohPT0wKXJldHVybiBHKHopO3JldHVybiBPKHtzaWc6SixrZG06USxoZWFkQ3BoOlYsYm9keUNwaDpXfSl9fTt2YXIgXyQ9e2VuY29kZSgkLEope2xldCBaPSQud3JpdGVWYXJJbnQoSi5zZXEpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFEhPT0wKXJldHVybiBRO2xldCBZPUouYm9keUNwaD9KLmJvZHlDcGgubGVuZ3RoOjAsVj0kLndyaXRlVmFySW50KFkpO2lmKFYhPT0wKXJldHVybiBWO2lmKFk+MCl7aWYoIUouYm9keUNwaClyZXR1cm4gMTA7JC53cml0ZUJ5dGVzKEouYm9keUNwaCl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJCeXRlcygpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldCBXO2lmKFY+MCl7bGV0W3osS109JC5yZWFkQnl0ZXMoVik7aWYoSyE9PTApcmV0dXJuIEcoSyk7Vz16fXJldHVybiBPKHtzZXE6SixoZWFkQ3BoOlEsYm9keUNwaDpXfSl9fTt2YXIgTCQ9e2VuY29kZSgkLEopeyQud3JpdGVCeXRlcyhKLnNpZyksJC53cml0ZUJ5dGVzKEoua2RtKTtsZXQgWj0kLndyaXRlVmFyQnl0ZXMoSi5oZWFkQ3BoKTtpZihaIT09MClyZXR1cm4gWjtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtKLFpdPSQucmVhZEJ5dGVzKEEwKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRCeXRlcyhfMCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0W1YsWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gTyh7c2lnOkosa2RtOlEsaGVhZENwaDpWfSl9fTt2YXIgeCQ9e2VuY29kZSgkLEope2lmKCQud3JpdGVWYXJJbnQoSi5pZHgpLCQud3JpdGVCeXRlcyhuZXcgVWludDhBcnJheShbSi5zdGF0dXNdKSksSi5zdGF0dXM9PT0wKSQud3JpdGVWYXJJbnQoSi5zZXEpO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFySW50KCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09JC5yZWFkQnl0ZXMoMSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7bGV0IFY9UVswXTtpZihWIT09MClyZXR1cm4gTyh7aWR4Okosc3RhdHVzOlZ9KTtsZXRbWCxXXT0kLnJlYWRWYXJJbnQoKTtpZihXIT09MClyZXR1cm4gRyhXKTtyZXR1cm4gTyh7aWR4Okosc3RhdHVzOlYsc2VxOlh9KX19O3ZhciBnWj17YXN5bmMgZW5jb2RlUmVxKCQsSixaLFEsWSl7bGV0IFY9WS53cml0ZVN0cnVjdChYMCxaKTtpZihWIT09MClyZXR1cm4gVjtsZXQgWD1ZLndyaXRlU3RydWN0cyhSSixRKTtpZihYIT09MClyZXR1cm4gWDtyZXR1cm4gMH0sYXN5bmMgaGFuZGxlUmVxKCQsSixaKXtsZXR7Y2xvY2s6USxjcnlwdG86WSxzdG9yYWdlOlYsbm90aWZpZXI6WH09JCxbVyx6XT1KLnJlYWRTdHJ1Y3QoWDApO2lmKHohPT0wKXJldHVybiB6O2xldCBLPWF3YWl0IEwwKFcsWSxRKTtpZihLIT09MClyZXR1cm4gSztsZXR7cHViS2V5OkZ9PVcsW04sVV09YXdhaXQgVi5oYXNVc2VyKEYpO2lmKFUhPT0wKXJldHVybiBVO2lmKCFOKXJldHVybiA1O2xldFtSLHFdPUoucmVhZFN0cnVjdHMoUkopO2lmKHEhPT0wKXJldHVybiBxO2NvbnNvbGUuaW5mbyhgUFVTSDogJHtSLmxlbmd0aH0gYmFnc2ApO2xldCBIPVtdLE09W107Zm9yKGxldCBJPTA7STxSLmxlbmd0aDtJKyspe2xldCBBPVJbSV07aWYoIWF3YWl0IHhaKEEsRixZKSl7bGV0IGc9e2lkeDpJLHN0YXR1czozfSxmPVoud3JpdGVTdHJ1Y3QoeCQsZyk7aWYoZiE9PTApcmV0dXJuIGY7Y29udGludWV9SC5wdXNoKEkpLE0ucHVzaChBKX1sZXRbUCxDXT1hd2FpdCBWLnNldEJhZ3MoRixNKTtpZihDIT09MClyZXR1cm4gQztpZighUHx8UC5sZW5ndGghPT1NLmxlbmd0aClyZXR1cm4gMTc7bGV0IFQ9W107Zm9yKGxldCBJPTA7STxNLmxlbmd0aDtJKyspe2xldCBBPU1bSV0sTD1IW0ldLGc9UFtJXSxmPW5ldyBTLGs9Zi53cml0ZVN0cnVjdChMJCxBKTtpZihrIT09MClyZXR1cm4gaztsZXQgeT1mLnJlc3VsdCgpLGg9e3NlcTpnLGhlYWRDcGg6eX07aWYoUi5sZW5ndGg9PT0xJiZBLmJvZHlDcGgubGVuZ3RoPD1IWiloLmJvZHlDcGg9QS5ib2R5Q3BoO1QucHVzaChoKTtsZXQgdz17aWR4Okwsc3RhdHVzOjAsc2VxOmd9LHA9Wi53cml0ZVN0cnVjdCh4JCx3KTtpZihwIT09MClyZXR1cm4gcH1pZihULmxlbmd0aD4wKXtsZXQgST1uZXcgUyxBPUkud3JpdGVTdHJ1Y3RzKF8kLFQpO2lmKEEhPT0wKXJldHVybiBBO2xldCBMPUkucmVzdWx0KCk7YXdhaXQgUHJvbWlzZS5yZXNvbHZlKFgucHVzaChGLEwpKX1yZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyh4JCl9fTt2YXIgbVo9e2FzeW5jIGVuY29kZVJlcSgkLEosWixRLFkpe3JldHVybiBZLndyaXRlU3RydWN0KFgwLFopfSxhc3luYyBoYW5kbGVSZXEoJCxKLFope2xldHtjbG9jazpRLGNyeXB0bzpZLHN0b3JhZ2U6Vn09JCxbWCxXXT1KLnJlYWRTdHJ1Y3QoWDApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEwwKFgsWSxRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVg7aWYoIUouZG9uZSgpKXJldHVybiA4O2xldFtGLE5dPWF3YWl0IFYuYWRkVXNlcihLKTtpZihOIT09MClyZXR1cm4gTjtyZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gTyh2b2lkIDApfX07Y2xhc3MgSEp7dXJsO3dlYnNvY2tldDtjb25zdHJ1Y3RvcigkKXt0aGlzLnVybD0kfWNvbm5lY3RlZCgpe3JldHVybiB0aGlzLndlYnNvY2tldCE9PXZvaWQgMCYmdGhpcy53ZWJzb2NrZXQucmVhZHlTdGF0ZT09PVdlYlNvY2tldC5PUEVOfWFzeW5jIGNvbm5lY3QoJCxKLFo9KCk9Pnt9LFE9KCk9Pnt9KXtsZXR7dXJsOll9PXRoaXM7aWYodGhpcy53ZWJzb2NrZXQpdGhpcy53ZWJzb2NrZXQuY2xvc2UoKSx0aGlzLndlYnNvY2tldD12b2lkIDA7bGV0IFY9bmV3IFM7Vi53cml0ZVN0cnVjdChYMCwkKTtsZXQgWD1WLnJlc3VsdCgpLFc9VTAoWCk7cmV0dXJuIFkuc2VhcmNoUGFyYW1zLnNldCgidCIsVyksdGhpcy53ZWJzb2NrZXQ9bmV3IFdlYlNvY2tldChZKSx0aGlzLndlYnNvY2tldC5iaW5hcnlUeXBlPSJhcnJheWJ1ZmZlciIsdGhpcy53ZWJzb2NrZXQub25vcGVuPSgpPT57Y29uc29sZS5sb2coIkNPTk5FQ1RFRCIpLFEoKX0sdGhpcy53ZWJzb2NrZXQub25jbG9zZT0oKT0+e2NvbnNvbGUubG9nKCJESVNDT05ORUNURUQiKSx0aGlzLndlYnNvY2tldD12b2lkIDAsWigpfSx0aGlzLndlYnNvY2tldC5vbm1lc3NhZ2U9KHopPT57bGV0IEs9bmV3IFVpbnQ4QXJyYXkoei5kYXRhKTtKKEspfSx0aGlzLndlYnNvY2tldC5vbmVycm9yPSh6KT0+e2NvbnNvbGUubG9nKGBFUlJPUjogJHtKU09OLnN0cmluZ2lmeSh6KX1gKSx0aGlzLndlYnNvY2tldD12b2lkIDAsWigpfSxQcm9taXNlLnJlc29sdmUoMCl9ZGlzY29ubmVjdCgpe3RoaXMud2Vic29ja2V0Py5jbG9zZSgpLHRoaXMud2Vic29ja2V0PXZvaWQgMH19dmFyIGE9e3VzZXI6e3BhdGg6Ii91c2VyIixlbmRwb2ludDptWixuYW1lOjB9LHB1c2g6e3BhdGg6Ii9wdXNoIixlbmRwb2ludDpnWixuYW1lOjJ9LHBlZWs6e3BhdGg6Ii9wZWVrIixlbmRwb2ludDpFWixuYW1lOjF9LHB1bGw6e3BhdGg6Ii9wdWxsIixlbmRwb2ludDpmWixuYW1lOjN9fSxBWT17MDphLnVzZXIsMjphLnB1c2gsMTphLnBlZWssMzphLnB1bGx9LHVXPXtbYS51c2VyLnBhdGhdOmEudXNlcixbYS5wdXNoLnBhdGhdOmEucHVzaCxbYS5wZWVrLnBhdGhdOmEucGVlayxbYS5wdWxsLnBhdGhdOmEucHVsbH07Y2xhc3MgU1p7dXJsO2xpc3RlbmVyO2NvbnN0cnVjdG9yKCQpe3RoaXMudXJsPSQ7dGhpcy5saXN0ZW5lcj1uZXcgSEooJCl9YXN5bmMgY2FsbCgkLEope2xldHtwYXRoOlp9PUFZWyRdLFE9bmV3IFVSTChaLHRoaXMudXJsKTt0cnl7cmV0dXJuIGF3YWl0IF9ZKFEsSil9Y2F0Y2h7cmV0dXJuIEcoMjUpfX19dmFyIHZaPSgkKT0+e3JldHVybiBuZXcgU1ooJC5oYW5kbGUpfTthc3luYyBmdW5jdGlvbiBfWSgkLEope2xldCBaPWF3YWl0IGZldGNoKCQse21ldGhvZDoiUE9TVCIsYm9keTpKLnJlc3VsdCgpLnNsaWNlKCl9KTtpZighWi5vaylyZXR1cm4gRygyNCk7bGV0IFE9YXdhaXQgbS5mcm9tUmVzcG9uc2UoWik7cmV0dXJuIE8oUSl9Y2xhc3MgQiR7ZW5jbGF2ZTtjcnlwdG87aG9zdDtjbG9jazt0cmFuc3BvcnQ7dXBkYXRlSG9zdE1ldGE7Y29uc3RydWN0b3IoJCxKLFosUSxZLFYpe3RoaXMuZW5jbGF2ZT0kO3RoaXMuY3J5cHRvPUo7dGhpcy5ob3N0PVo7dGhpcy5jbG9jaz1RO3RoaXMudHJhbnNwb3J0PVk7dGhpcy51cGRhdGVIb3N0TWV0YT1WfWFzeW5jIGNhbGwoJCxKKXtsZXR7Y2xvY2s6Wix0cmFuc3BvcnQ6UX09dGhpcyx7ZW5kcG9pbnQ6WSxuYW1lOlZ9PSQsWD1hd2FpdCB0aGlzLmlkZW50aXR5KCksVz1aLm5vdygpLFt6LEtdPWF3YWl0IHpKKFgsVyk7aWYoSyE9PTApcmV0dXJuIEcoSyk7bGV0IEY9bmV3IFMsTj1hd2FpdCBZLmVuY29kZVJlcSh0aGlzLFgseixKLEYpO2lmKE4hPT0wKXJldHVybiBHKE4pO2xldCBVPVoubm93KCksW1IscV09YXdhaXQgUS5jYWxsKFYsRiksSD1aLm5vdygpO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldFtNLFBdPVIucmVhZFN0cnVjdChOSik7aWYoUCE9PTApcmV0dXJuIEcoUCk7aWYoTS5zdGF0dXMhPT0wKXJldHVybiBHKE0uc3RhdHVzKTtsZXQgVD17Y2xvY2tPZmZzZXQ6a1ooVSxNLnRpbWVSY3ZkLE0udGltZVNlbnQsSCksc3Vic2NyaXB0aW9uOk0uc3Vic2NyaXB0aW9ufSxJPWF3YWl0IHRoaXMudXBkYXRlSG9zdE1ldGEoVCk7aWYoSSE9PTApcmV0dXJuIEcoSSk7cmV0dXJuIFkuZGVjb2RlUmVzcChSKX1pZGVudGl0eT0oKT0+e2xldHtob3N0OiQsZW5jbGF2ZTpKfT10aGlzO3JldHVybiBKLmRlcml2ZUlkZW50aXR5KCQubGFiZWwsJC5pZHg/PzApfTtzZWFsPWFzeW5jKCQpPT57bGV0e2NyeXB0bzpKLGVuY2xhdmU6Wn09dGhpcyxRPWF3YWl0IHRoaXMuaWRlbnRpdHkoKTtyZXR1cm4gQlooJCxRLEosWil9O3JlZ2lzdGVyPSgpPT50aGlzLmNhbGwoYS51c2VyLFtdKTtwZWVrPSgkKT0+dGhpcy5jYWxsKGEucGVlayxbJF0pO3B1c2g9KCQpPT50aGlzLmNhbGwoYS5wdXNoLCQpO3B1bGw9KCQpPT50aGlzLmNhbGwoYS5wdWxsLCQpO2xpc3Rlbj1hc3luYygkLEosWik9PntsZXR7Y2xvY2s6USx0cmFuc3BvcnQ6WX09dGhpcyx7bGlzdGVuZXI6Vn09WSxYPWF3YWl0IHRoaXMuaWRlbnRpdHkoKSxXPVEubm93KCksW3osS109YXdhaXQgekooWCxXKTtpZihLIT09MClyZXR1cm4gSztyZXR1cm4gYXdhaXQgVi5jb25uZWN0KHosJCxKLFopfTtpc0Nvbm5lY3RlZCgpe2xldCAkPXRoaXMudHJhbnNwb3J0Py5saXN0ZW5lcjtpZigkJiZ0eXBlb2YgJC5jb25uZWN0ZWQ9PT0iZnVuY3Rpb24iKXJldHVybiAkLmNvbm5lY3RlZCgpO3JldHVybiEwfWNsb3NlTGlzdGVuZXIoKXt0aGlzLnRyYW5zcG9ydD8ubGlzdGVuZXI/LmRpc2Nvbm5lY3QoKX19dmFyIHFKPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlVmFyU3RyaW5nKEoubGJsKTtpZihaIT09MClyZXR1cm4gWjtsZXQgUT0kLndyaXRlVmFySW50KEouaWR4KTtpZihRIT09MClyZXR1cm4gUTtsZXQgWT0kLndyaXRlVmFySW50KEoubnVtKTtpZihZIT09MClyZXR1cm4gWTtyZXR1cm4gJC53cml0ZUJ5dGVzKEouaHNoKSwkLndyaXRlQnl0ZXMoSi5zaWcpLDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJJbnQoKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbVyx6XT0kLnJlYWRCeXRlcyhDJCk7aWYoeiE9PTApcmV0dXJuIEcoeik7bGV0W0ssRl09JC5yZWFkQnl0ZXMoQTApO2lmKEYhPT0wKXJldHVybiBHKEYpO3JldHVybiBPKHtsYmw6SixpZHg6USxudW06Vixoc2g6VyxzaWc6S30pfX07dmFyIE1KPXtlbmNvZGUoJCxKKXtsZXQgWj0kLndyaXRlU3RydWN0KHFKLEouaGVhZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckJ5dGVzKEouaW5kZXhFbmMpO2lmKFEhPT0wKXJldHVybiBRO2xldCBZPSQud3JpdGVWYXJCeXRlcyhKLmJvZHlFbmMpO2lmKFkhPT0wKXJldHVybiBZO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkU3RydWN0KHFKKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJCeXRlcygpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtWLFhdPSQucmVhZFZhckJ5dGVzKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIE8oe2hlYWQ6SixpbmRleEVuYzpRLGJvZHlFbmM6Vn0pfX07dmFyIElKPXtlbmNvZGUoJCxKKXskLndyaXRlQnl0ZXMoSi5rZG0pO2xldCBaPSQud3JpdGVWYXJCeXRlcyhKLmhlYWRDcGgpO2lmKFohPT0wKXJldHVybiBaO2xldCBRPSQud3JpdGVWYXJJbnQoSi5sZW5Cb2R5KTtpZihRIT09MClyZXR1cm4gUTtpZihKLmxlbkJvZHk+MCYmSi5vZmZCb2R5IT09dm9pZCAwKXtsZXQgWT0kLndyaXRlVmFySW50KEoub2ZmQm9keSk7aWYoWSE9PTApcmV0dXJuIFl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRCeXRlcyhfMCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W1EsWV09JC5yZWFkVmFyQnl0ZXMoKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXQgVztpZihWPjApe2xldFt6LEtdPSQucmVhZFZhckludCgpO2lmKEshPT0wKXJldHVybiBHKEspO1c9en1yZXR1cm4gTyh7a2RtOkosaGVhZENwaDpRLGxlbkJvZHk6VixvZmZCb2R5Old9KX19O2FzeW5jIGZ1bmN0aW9uIHlaKCQsSixaLFEsWSl7bGV0IFY9YXdhaXQgWS5kZXJpdmVJZGVudGl0eSgkLEopLFg9bmV3IFMsVz1uZXcgUyx6PTAsSz0wO2ZvcihsZXQgUCBvZiBaKXtsZXQgQz1uZXcgUyxUPUMud3JpdGVTdHJ1Y3QoRzAsUC5oZWFkKTtpZihUIT09MClyZXR1cm4gRyhUKTtsZXQgST1DLnJlc3VsdCgpLEE9YXdhaXQgVi5rZG1Gb3IoSSksTD1ZLmRlcml2ZUNpcGhlcihBLCJlbmNyeXB0IiksZz1hd2FpdCBMLmVuY3J5cHQoSSksZj1QLmJvZHk/YXdhaXQgTC5lbmNyeXB0KFAuYm9keSk6bmV3IFVpbnQ4QXJyYXkoMCksaz1QLmhlYWQubGVuPjAmJlAuaGVhZC5oc2ghPT12b2lkIDA/Zi5sZW5ndGg6MCx5PXtrZG06QSxoZWFkQ3BoOmcsbGVuQm9keTprLG9mZkJvZHk6az4wP0s6dm9pZCAwfSxoPVgud3JpdGVTdHJ1Y3QoSUoseSk7aWYoaCE9PTApcmV0dXJuIEcoaCk7aWYoUC5ib2R5KVcud3JpdGVCeXRlcyhmKSxLKz1mLmxlbmd0aDt6Kyt9bGV0IEY9Vy5yZXN1bHQoKSxOPVgucmVzdWx0KCksVT1hd2FpdCBRLmJsYWtlMyhOKSxSPWF3YWl0IFYuc2lnbihVKSxxPXtsYmw6JCxpZHg6SixudW06eixoc2g6VSxzaWc6Un0sSD1uZXcgUztILndyaXRlU3RydWN0KE1KLHtoZWFkOnEsaW5kZXhFbmM6Tixib2R5RW5jOkZ9KTtsZXQgTT1ILnJlc3VsdCgpO3JldHVybiBPKE0pfWFzeW5jIGZ1bmN0aW9uIGJaKCQsSixaKXtsZXRbUSxZXT1NSi5kZWNvZGUobmV3IG0oJCkpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldHtoZWFkOlYsaW5kZXhFbmM6WCxib2R5RW5jOld9PVEsej1hd2FpdCBaLmRlcml2ZUlkZW50aXR5KFYubGJsLFYuaWR4KTtpZighYXdhaXQgSi5jaGVja1NpZ0VkMjU1MTkoVi5zaWcsVi5oc2gsei5wdWJsaWNLZXkpKXJldHVybiBHKDMpO2xldCBGPWF3YWl0IEouYmxha2UzKFgpO2lmKCFyKEYsVi5oc2gpKXJldHVybiBHKDE5KTtsZXQgTj1uZXcgbShYKSxVPVtdO2ZvcihsZXQgcT0wO3E8Vi5udW07cSsrKXtsZXRbSCxNXT1OLnJlYWRTdHJ1Y3QoSUopO2lmKE0hPT0wKXJldHVybiBHKE0pO1UucHVzaChIKX1pZihVLmxlbmd0aCE9PVYubnVtKXJldHVybiBHKDE0KTtsZXQgUj1bXTtmb3IobGV0IHEgb2YgVSl7bGV0IEg9Wi5kZXJpdmVDaXBoZXIocS5rZG0sImRlY3J5cHQiKSxNO3RyeXtNPWF3YWl0IEguZGVjcnlwdChxLmhlYWRDcGgpfWNhdGNoe3JldHVybiBHKDIwKX1sZXRbUCxDXT1HMC5kZWNvZGUobmV3IG0oTSkpO2lmKEMhPT0wKXJldHVybiBHKEMpO2xldCBUO2lmKHEubGVuQm9keT4wJiZxLm9mZkJvZHkhPT12b2lkIDApe2lmKFAuaHNoPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXQgST1XLnNsaWNlKHEub2ZmQm9keSxxLm9mZkJvZHkrcS5sZW5Cb2R5KTt0cnl7VD1hd2FpdCBILmRlY3J5cHQoSSl9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldCBBPWF3YWl0IEouYmxha2UzKFQpO2lmKCFyKEEsUC5oc2gpKXJldHVybiBHKDE5KX1SLnB1c2goe2hlYWQ6UCxib2R5OlR9KX1yZXR1cm4gTyhSKX1hc3luYyBmdW5jdGlvbiBoWih7bm93OiQsYm9kOkosY3J5cHRvOlp9KXtsZXQgUT1hd2FpdCBaLmdlblJhbmRvbUJ5dGVzKDgpLFk9bmV3IFMsVj1ZLndyaXRlU3RydWN0KFYwLHtpZDpRLHRzOiR9KTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXQgWD1ZLnJlc3VsdCgpO3JldHVybiBrJCh7bm93OiQsZWlkOlgsY3RyOjAsYm9kOkosY3J5cHRvOlp9KX1hc3luYyBmdW5jdGlvbiBrJCh7bm93OiQsZWlkOkosY3RyOlosYm9kOlEsY3J5cHRvOll9KXtsZXQgVj1uZXcgbShKKSxbWCxXXT1WMC5kZWNvZGUoVik7aWYoVyE9PTApcmV0dXJuIEcoVyk7bGV0IHo9JC5nZXRUaW1lKCktWC50cy5nZXRUaW1lKCksSyxGPVE/Lmxlbmd0aD8/MDtpZihRJiZGPjApSz1hd2FpdCBZLmJsYWtlMyhRKTtyZXR1cm4gTyh7ZWlkOkosb2ZmOnosY3RyOlosbGVuOkYsaHNoOkt9KX1mdW5jdGlvbiBMWSgkLEope2xldCBaPSQubGVuZ3RoPEoubGVuZ3RoPyQubGVuZ3RoOkoubGVuZ3RoO2ZvcihsZXQgUT0wO1E8WjtRKyspaWYoJFtRXSE9PUpbUV0pcmV0dXJuICRbUV0tSltRXTtyZXR1cm4gJC5sZW5ndGgtSi5sZW5ndGh9YXN5bmMgZnVuY3Rpb24gTiQoJCxKKXtsZXQgWj1BcnJheS5mcm9tKCQpO1ouc29ydChMWSk7bGV0IFE9MDtmb3IobGV0IFggb2YgWilRKz1YLmxlbmd0aDtsZXQgWT1uZXcgVWludDhBcnJheShRKSxWPTA7Zm9yKGxldCBYIG9mIFopWS5zZXQoWCxWKSxWKz1YLmxlbmd0aDtyZXR1cm4gSi5ibGFrZTMoWSl9ZnVuY3Rpb24geFkoJCl7bGV0IEo9bmV3IFMsWj1KLndyaXRlVmFyQnl0ZXMoJC5laWQpO2lmKFohPT0wKXJldHVybiBHKFopO2xldCBRPUoud3JpdGVEYXRlKCQudXBkYXRlZEF0KTtpZihRIT09MClyZXR1cm4gRyhRKTtsZXQgWT1KLndyaXRlVmFySW50KCQuY3RyKTtpZihZIT09MClyZXR1cm4gRyhZKTtyZXR1cm4gTyhKLnJlc3VsdCgpKX1hc3luYyBmdW5jdGlvbiBFJCgkLEope2xldCBaPVtdO2ZvcihsZXQgUSBvZiAkKXtsZXRbWSxWXT14WShRKTtpZihWIT09MHx8IVkpcmV0dXJuIEcoVik7Wi5wdXNoKFkpfXJldHVybiBPKGF3YWl0IE4kKFosSikpfXZhciBTRz1TeW1ib2woIk1hc3RlclNlZWQiKSx2Rz1TeW1ib2woIlNlYWxlZE1hc3RlcktleSIpLEgwPTMyLGlaPTI0K0gwKzE2O2Z1bmN0aW9uICQwKCQpe2lmKCQuYnl0ZUxlbmd0aCE9PUgwKXJldHVybiBHKDEwKTtyZXR1cm4gTygkKX1mdW5jdGlvbiB4MCgkKXtpZigkLmJ5dGVMZW5ndGghPT1pWilyZXR1cm4gRygxMCk7cmV0dXJuIE8oJCl9dmFyIGJHPVN5bWJvbCgiRW50aXR5SUQiKTtmdW5jdGlvbiBsWigkKXtyZXR1cm4idHlwZSJpbiAkfXZhciBoRz1TeW1ib2woIkRlcml2YXRpb25TZWVkIiksaUc9U3ltYm9sKCJQdWJsaWNLZXkiKSxsRz1TeW1ib2woIlByaXZhdGVLZXkiKSx1Rz1TeW1ib2woIkhvc3RTcGVjaWZpY0tleVBhaXIiKSxwRz1TeW1ib2woIkhhc2giKTtmdW5jdGlvbiBCWSgkKXtpZighJClyZXR1cm4hMTtpZih0eXBlb2YgJCE9PSJvYmplY3QiKXJldHVybiExO2lmKCJib2R5ImluICQ9PT0hMSlyZXR1cm4hMTtpZigidHlwZSJpbiAkPT09ITEpcmV0dXJuITE7cmV0dXJuITB9ZnVuY3Rpb24ga1koJCl7aWYoISQuYm9kfHwkLmJvZC5sZW5ndGg9PT0wKXtsZXQgUT17b2ZmOiQub2ZmLGN0cjokLmN0cixlaWQ6JC5laWR9O3JldHVybiBPKFEpfWxldCBKPUdKKCQuYm9kKTtpZihCWShKKT09PSExKXJldHVybiBjb25zb2xlLndhcm4oIm1zZyBib2R5IGludmFsaWQiLEopLEcoMTQpO2xldCBaPXtvZmY6JC5vZmYsY3RyOiQuY3RyLGVpZDokLmVpZCxnaWQ6Si5naWQscGlkOkoucGlkLHRhZ3M6Si50YWdzLHR5cGU6Si50eXBlLGJvZHk6Si5ib2R5fTtyZXR1cm4gTyhaKX1jbGFzcyBmJHthcHBsaWVyO2VtaXR0ZXI9bmV3IEskO2NsZWFyZXI7b25EaXJ0eUVpZHM7Y2FjaGVEcml2ZW47cGVlckluZ2VzdDtjb25zdHJ1Y3RvcigkLEosWixRKXt0aGlzLmFwcGxpZXI9JDt0aGlzLmNsZWFyZXI9Six0aGlzLm9uRGlydHlFaWRzPVosdGhpcy5jYWNoZURyaXZlbj1RPy5jYWNoZURyaXZlbj8/ITEsdGhpcy5wZWVySW5nZXN0PVE/LnBlZXJJbmdlc3R9YXBwbHk9YXN5bmMoJCk9PntsZXQgSj1bXSxaPVtdO2ZvcihsZXQgVyBvZiAkKXtsZXRbeixLXT1rWShXKTtpZihaLnB1c2goSyksSyE9PTApY29udGludWU7Si5wdXNoKHopfWxldHtzdGF0czpRLHR5cGVzOlksZWlkczpWfT1hd2FpdCB0aGlzLmFwcGxpZXIoSiksWD1bXTtmb3IobGV0IFc9MDtXPCQubGVuZ3RoO1crKyl7bGV0IHo9WltXXSxLPVFbV107aWYoeiE9PTApe1gucHVzaCh6KTtjb250aW51ZX1pZihLIT09MCl7WC5wdXNoKEspO2NvbnRpbnVlfVgucHVzaCgwKX1pZighdGhpcy5jYWNoZURyaXZlbilmb3IobGV0IFcgb2YgWSl0aGlzLmVtaXR0ZXIuZW1pdChXLG51bGwpO2lmKFYubGVuZ3RoPjApdGhpcy5vbkRpcnR5RWlkcz8uKFYpO3JldHVybiBYfTtjbGVhcj1hc3luYygpPT57bGV0ICQ9YXdhaXQgdGhpcy5jbGVhcmVyKCk7aWYoJCE9PTApcmV0dXJuICQ7cmV0dXJuIHRoaXMuZW1pdHRlci5lbWl0QWxsKG51bGwpLCR9O25vdGlmeT0oJCk9Pntmb3IobGV0IEogb2YgJCl0aGlzLmVtaXR0ZXIuZW1pdChKLG51bGwpfTtyZWZyZXNoPWFzeW5jKCQpPT57aWYodGhpcy5wZWVySW5nZXN0KXthd2FpdCB0aGlzLnBlZXJJbmdlc3QoJCk7cmV0dXJufX07b249KCQsSik9Pnt0aGlzLmVtaXR0ZXIuYWRkRXZlbnRMaXN0ZW5lcigkLEopfTtvZmY9KCQsSik9Pnt0aGlzLmVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcigkLEopfX12YXIgbj0iZW50aXRpZXMiLGckPSJlbnRpdHlfdHlwZV9jcmVhdGVkX2F0IixQSj0iZW50aXR5X3R5cGVfdXBkYXRlZF9hdCIsd0o9ImVudGl0eV90eXBlX2dyb3VwX2lkIixUSj0iZW50aXR5X3R5cGVfcGFyZW50X2lkIixzMD0iZW50aXR5X3RhZ3MiLHVaPSJkYiIscFo9MTM7ZnVuY3Rpb24gRVkoJCl7cmV0dXJuInR5cCJpbiAkfWZ1bmN0aW9uIGZZKCQpe2xldCBKPXtib2Q6JC5ib2R5LGNyZDokLmNyZWF0ZWRBdCwuLi4kLmN0ciE9PTA/e2N0cjokLmN0cn06e30sZWlkOkIoJC5laWQpLGdpZDokLmdpZCxwaWQ6JC5waWQ/QigkLnBpZCk6dm9pZCAwLHRnczokLnRhZ3MsdHlwOiQudHlwZSx1cGQ6JC51cGRhdGVkQXR9O2lmKEouZ2lkPT09dm9pZCAwKWRlbGV0ZSBKLmdpZDtpZihKLnBpZD09PXZvaWQgMClkZWxldGUgSi5waWQ7aWYoSi50Z3M9PT12b2lkIDApZGVsZXRlIEoudGdzO2lmKEouY3RyPT09dm9pZCAwKWRlbGV0ZSBKLmN0cjtyZXR1cm4gSn1mdW5jdGlvbiBnWSgkKXtpZighbCgkKSlyZXR1cm57ZWlkOkIoJC5laWQpLHVwZDokLnVwZGF0ZWRBdCwuLi4kLmN0ciE9PTA/e2N0cjokLmN0cn06e319O3JldHVybiBmWSgkKX1mdW5jdGlvbiB0MCgkKXtyZXR1cm57Ym9keTokLmJvZCxjcmVhdGVkQXQ6JC5jcmQsdXBkYXRlZEF0OiQudXBkLGN0cjokLmN0cj8/MCx0eXBlOiQudHlwLGVpZDpOMCgkLmVpZCksZ2lkOiQuZ2lkLHBpZDokLnBpZD9OMCgkLnBpZCk6dm9pZCAwLC4uLiQudGdzIT09dm9pZCAwP3t0YWdzOiQudGdzfTp7fX19ZnVuY3Rpb24gQ0ooJCl7aWYoRVkoJCkpcmV0dXJuIHQwKCQpO3JldHVybntlaWQ6TjAoJC5laWQpLHVwZGF0ZWRBdDokLnVwZCxjdHI6JC5jdHI/PzB9fWNsYXNzIGNae2RiO29wZW5pbmc7YXN5bmMgaW5pdCgpe2F3YWl0IHRoaXMuZW5zdXJlRGIoKX1hc3luYyBlbnN1cmVEYigpe2lmKHRoaXMuZGIpcmV0dXJuIHRoaXMuZGI7aWYodGhpcy5vcGVuaW5nKXJldHVybiB0aGlzLm9wZW5pbmc7cmV0dXJuIHRoaXMub3BlbmluZz1TWSgpLnRoZW4oKCQpPT57cmV0dXJuICQub252ZXJzaW9uY2hhbmdlPSgpPT57aWYoJC5jbG9zZSgpLHRoaXMuZGI9PT0kKXRoaXMuZGI9dm9pZCAwfSx0aGlzLmRiPSQsdGhpcy5vcGVuaW5nPXZvaWQgMCwkfSwoJCk9Pnt0aHJvdyB0aGlzLm9wZW5pbmc9dm9pZCAwLCR9KSx0aGlzLm9wZW5pbmd9YXBwbHk9YXN5bmMoJCk9PntsZXQgSj1uZXcgU2V0LFo9W10sUTt0cnl7UT1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJue3N0YXRzOiQubWFwKCgpPT4xNiksdHlwZXM6SixlaWRzOlp9fWxldCBZPVEudHJhbnNhY3Rpb24obiwicmVhZHdyaXRlIiksVj1ZLm9iamVjdFN0b3JlKG4pO3JldHVybiBuZXcgUHJvbWlzZSgoWCk9PntsZXQgVz1BcnJheSgkLmxlbmd0aCkuZmlsbCgwKTtpZigkLmxlbmd0aDwxKXtYKHtzdGF0czpbXSx0eXBlczpKLGVpZHM6Wn0pO3JldHVybn1ZLm9uY29tcGxldGU9KCk9PntYKHtzdGF0czpXLHR5cGVzOkosZWlkczpafSl9LFkub25lcnJvcj0oKT0+e2ZvcihsZXQgSz0wO0s8Vy5sZW5ndGg7SysrKWlmKFdbS109PT12b2lkIDApV1tLXT0xODtYKHtzdGF0czpXLHR5cGVzOkosZWlkczpafSl9O2xldCB6PW5ldyBNYXA7Zm9yKGxldCBLPTA7SzwkLmxlbmd0aDtLKyspe2xldCBGPSRbS10sTj1CKEYuZWlkKSxVPXtvcDpGLGluZGV4Okt9LFI9ei5nZXQoTik7aWYoUilSLnB1c2goVSk7ZWxzZSB6LnNldChOLFtVXSl9Zm9yKGxldFtLLEZdb2Ygeil7aWYoRi5sZW5ndGg8MSljb250aW51ZTtsZXQgTj1WLmdldChLKTtOLm9uc3VjY2Vzcz0oKT0+e2xldCBVPU4ucmVzdWx0LFI9VT9DSihVKTp2b2lkIDAscT0hMTtmb3IobGV0e29wOkgsaW5kZXg6TX1vZiBGKXtsZXRbUCxDXT1lMChSLEgpO2lmKEMhPT0wKXtXW01dPUM7Y29udGludWV9aWYoUD09PXZvaWQgMCl7V1tNXT0xMjtjb250aW51ZX1xPSEwO2ZvcihsZXQgVCBvZiAkJChSLFApKUouYWRkKFQpO1I9UH1pZihxKVoucHVzaChGWzBdLm9wLmVpZCk7aWYoUil7bGV0IEg9Vi5wdXQoZ1koUikpO0gub25lcnJvcj0oTSk9PntNLnByZXZlbnREZWZhdWx0KCk7Zm9yKGxldHtpbmRleDpQfW9mIEYpV1tQXT0xOH19fSxOLm9uZXJyb3I9KCk9Pntmb3IobGV0e2luZGV4OlV9b2YgRilXW1VdPTE4fX19KX07YXN5bmMgY2xlYXIoKXtsZXQgJDt0cnl7JD1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIDE2fWxldCBKPSQudHJhbnNhY3Rpb24obiwicmVhZHdyaXRlIiksWj1KLm9iamVjdFN0b3JlKG4pO3JldHVybiBuZXcgUHJvbWlzZSgoUSk9PntKLm9uY29tcGxldGU9KCk9PlEoMCksSi5vbmVycm9yPSgpPT5RKDE4KSxaLmNsZWFyKCl9KX1hc3luYyBnZXRSb3coJCl7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgWj1CKCQpLFk9Si50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pO3JldHVybiBuZXcgUHJvbWlzZSgoVik9PntsZXQgWD1ZLmdldChaKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0O2lmKCFXKVYoTyh2b2lkIDApKTtlbHNlIFYoTyhDSihXKSkpfSxYLm9uZXJyb3I9KCk9PlYoRygxOCkpfSl9YXN5bmMgZ2V0RW50KCQpe2xldFtKLFpdPWF3YWl0IHRoaXMuZ2V0Um93KCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDB8fCFsKEopKXJldHVybiBPKHZvaWQgMCk7cmV0dXJuIE8oSil9YXN5bmMgZ2V0QWxsT2ZUeXBlVXBkYXRlZEJldHdlZW4oJCxKLFope2xldCBRO3RyeXtRPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFY9US50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KFBKKTtyZXR1cm4gbmV3IFByb21pc2UoKFgpPT57bGV0IFc9Vi5nZXRBbGwoSURCS2V5UmFuZ2UuYm91bmQoWyQsSl0sWyQsWl0pKTtXLm9uc3VjY2Vzcz0oKT0+e2xldCB6PVcucmVzdWx0O1goTyh6Lm1hcCh0MCkpKX0sVy5vbmVycm9yPSgpPT5YKEcoMTgpKX0pfWFzeW5jIGdldEdyb3VwTWVtYmVycygkLEope2xldCBaO3RyeXtaPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFk9Wi50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KHdKKTtyZXR1cm4gbmV3IFByb21pc2UoKFYpPT57bGV0IFg9WS5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShbJCxKXSkpO1gub25zdWNjZXNzPSgpPT57bGV0IFc9WC5yZXN1bHQ7VihPKFcubWFwKHQwKSkpfSxYLm9uZXJyb3I9KCk9PlYoRygxOCkpfSl9YXN5bmMgZ2V0QWxsT2ZUeXBlKCQpe2xldCBKO3RyeXtKPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFE9Si50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KGckKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFY9US5nZXRBbGwoSURCS2V5UmFuZ2UuYm91bmQoWyRdLFskLFtdXSkpO1Yub25zdWNjZXNzPSgpPT57bGV0IFg9Vi5yZXN1bHQ7WShPKFgubWFwKHQwKSkpfSxWLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9YXN5bmMgZ2V0QnlUYWcoJCxKKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBZPVoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChzMCk7cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBYPVkuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoSikpO1gub25zdWNjZXNzPSgpPT57bGV0IHo9WC5yZXN1bHQuZmlsdGVyKChLKT0+Sy50eXA9PT0kKS5tYXAodDApO1YoTyh6KSl9LFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBnZXRBbGxFbnRpdGllcygkKXtpZigicGlkImluICQpe2xldCBKO3RyeXtKPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFo9QigkLnBpZCksWT1KLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgoVEopO3JldHVybiBuZXcgUHJvbWlzZSgoVik9PntsZXQgWD1ZLmdldEFsbChJREJLZXlSYW5nZS5vbmx5KFskLnR5cGUsWl0pKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCB6PVgucmVzdWx0Lm1hcCh0MCk7VihPKHopKX0sWC5vbmVycm9yPSgpPT5WKEcoMTgpKX0pfWVsc2UgaWYoImdpZCJpbiAkKXJldHVybiBhd2FpdCB0aGlzLmdldEdyb3VwTWVtYmVycygkLnR5cGUsJC5naWQpO2Vsc2UgaWYoInRhZyJpbiAkKXJldHVybiBhd2FpdCB0aGlzLmdldEJ5VGFnKCQudHlwZSwkLnRhZyk7ZWxzZSBpZigidXBkYXRlZEJldHdlZW4iaW4gJClyZXR1cm4gYXdhaXQgdGhpcy5nZXRBbGxPZlR5cGVVcGRhdGVkQmV0d2VlbigkLnR5cGUsJC51cGRhdGVkQmV0d2Vlbi5zdGFydCwkLnVwZGF0ZWRCZXR3ZWVuLmVuZCk7cmV0dXJuIGF3YWl0IHRoaXMuZ2V0QWxsT2ZUeXBlKCQudHlwZSl9YXN5bmMgZ2V0RW50aXRpZXMoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRBbGxFbnRpdGllcygkKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gTyhKKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtsZXQgSjt0cnl7Sj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBRPUoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChnJCk7cmV0dXJuIG5ldyBQcm9taXNlKChZKT0+e2xldCBWPUlEQktleVJhbmdlLmJvdW5kKFskXSxbJCxbXV0pLFg9US5jb3VudChWKTtYLm9uc3VjY2Vzcz0oKT0+WShPKFgucmVzdWx0KSksWC5vbmVycm9yPSgpPT5ZKEcoMTgpKX0pfWFzeW5jIGNoZWNrc3VtKCQpe2xldCBKO3RyeXtKPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IFE9Si50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLFk9W107cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBYPVEub3BlbkN1cnNvcigpO1gub25zdWNjZXNzPSgpPT57bGV0IFc9WC5yZXN1bHQ7aWYoVyl7bGV0IHo9Vy52YWx1ZTtZLnB1c2gobSQoQ0ooeikpKSxXLmNvbnRpbnVlKCl9ZWxzZSBFJChZLCQpLnRoZW4oVil9LFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX19ZnVuY3Rpb24gbVkoJCxKKXtpZighJC5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKG4pKSQuY3JlYXRlT2JqZWN0U3RvcmUobix7a2V5UGF0aDoiZWlkIixhdXRvSW5jcmVtZW50OiExfSk7bGV0IFo9Si5vYmplY3RTdG9yZShuKTtpZighWi5pbmRleE5hbWVzLmNvbnRhaW5zKGckKSlaLmNyZWF0ZUluZGV4KGckLFsidHlwIiwiY3JkIl0se3VuaXF1ZTohMX0pO2lmKCFaLmluZGV4TmFtZXMuY29udGFpbnMoUEopKVouY3JlYXRlSW5kZXgoUEosWyJ0eXAiLCJ1cGQiXSx7dW5pcXVlOiExfSk7aWYoIVouaW5kZXhOYW1lcy5jb250YWlucyh3SikpWi5jcmVhdGVJbmRleCh3SixbInR5cCIsImdpZCJdLHt1bmlxdWU6ITF9KTtpZighWi5pbmRleE5hbWVzLmNvbnRhaW5zKFRKKSlaLmNyZWF0ZUluZGV4KFRKLFsidHlwIiwicGlkIl0se3VuaXF1ZTohMX0pO2lmKFouaW5kZXhOYW1lcy5jb250YWlucyhzMCkpe2lmKFouaW5kZXgoczApLmtleVBhdGghPT0idGdzIilaLmRlbGV0ZUluZGV4KHMwKX1pZighWi5pbmRleE5hbWVzLmNvbnRhaW5zKHMwKSlaLmNyZWF0ZUluZGV4KHMwLCJ0Z3MiLHt1bmlxdWU6ITEsbXVsdGlFbnRyeTohMH0pfWZ1bmN0aW9uIFNZKCl7cmV0dXJuIG5ldyBQcm9taXNlKCgkLEopPT57bGV0IFo9aW5kZXhlZERCLm9wZW4odVoscFopO1oub251cGdyYWRlbmVlZGVkPSgpPT57bGV0e3Jlc3VsdDpRLHRyYW5zYWN0aW9uOll9PVo7aWYoIVkpe0ooRXJyb3IoIlRyYW5zYWN0aW9uIGlzIG51bGwgZHVyaW5nIEVudERCIHVwZ3JhZGUiKSk7cmV0dXJufXRyeXttWShRLFkpfWNhdGNoKFYpe0ooViBpbnN0YW5jZW9mIEVycm9yP1Y6RXJyb3IoU3RyaW5nKFYpKSl9fSxaLm9uYmxvY2tlZD0oKT0+e2NvbnNvbGUud2FybihgW0RJUExPTUFUSUNdIEVudERCIElEQiB1cGdyYWRlIGJsb2NrZWQgKCR7dVp9IOKGkiB2JHtwWn0pOyB3YWl0aW5nIGZvciBvdGhlciBjb25uZWN0aW9ucyB0byBjbG9zZWApfSxaLm9uc3VjY2Vzcz0oKT0+JChaLnJlc3VsdCksWi5vbmVycm9yPSgpPT5KKFouZXJyb3I/P0Vycm9yKCJFbnREQiBJbmRleGVkREIgb3BlbiBmYWlsZWQiKSl9KX1hc3luYyBmdW5jdGlvbiBuWigpe2xldCAkPW5ldyBjWjtyZXR1cm4gYXdhaXQgJC5pbml0KCksJH1jbGFzcyBqSntlbnRzPW5ldyBNYXA7dXNlSW5kZXg7YnlUeXBlPW5ldyBNYXA7YnlUeXBlUGlkPW5ldyBNYXA7YnlUeXBlR2lkPW5ldyBNYXA7YnlUeXBlVGFnPW5ldyBNYXA7Y29uc3RydWN0b3IoJD1bXSxKKXt0aGlzLnVzZUluZGV4PUo/LmluZGV4ZXMhPT0hMTtmb3IobGV0IFogb2YgJCl0aGlzLnB1dChaKX1wdXQoJCl7bGV0IEo9QigkLmVpZCksWj10aGlzLmVudHMuZ2V0KEopO2lmKFohPT12b2lkIDAmJmwoWikpdGhpcy51bmluZGV4KEosWik7aWYodGhpcy5lbnRzLnNldChKLCQpLGwoJCkpdGhpcy5pbmRleChKLCQpfWRlbCgkKXtsZXQgSj10aGlzLmVudHMuZ2V0KCQpO2lmKEo9PT12b2lkIDApcmV0dXJuO2lmKGwoSikpdGhpcy51bmluZGV4KCQsSik7dGhpcy5lbnRzLmRlbGV0ZSgkKX1pbmRleCgkLEope2lmKCF0aGlzLnVzZUluZGV4KXJldHVybjtsZXQgWj10aGlzLmJ5VHlwZS5nZXQoSi50eXBlKTtpZighWilaPW5ldyBNYXAsdGhpcy5ieVR5cGUuc2V0KEoudHlwZSxaKTtpZihaLnNldCgkLEopLEoucGlkKXtsZXQgUT1CKEoucGlkKSxZPXRoaXMuYnlUeXBlUGlkLmdldChKLnR5cGUpO2lmKCFZKVk9bmV3IE1hcCx0aGlzLmJ5VHlwZVBpZC5zZXQoSi50eXBlLFkpO2xldCBWPVkuZ2V0KFEpO2lmKCFWKVY9bmV3IE1hcCxZLnNldChRLFYpO1Yuc2V0KCQsSil9aWYodHlwZW9mIEouZ2lkPT09InN0cmluZyIpe2xldCBRPXRoaXMuYnlUeXBlR2lkLmdldChKLnR5cGUpO2lmKCFRKVE9bmV3IE1hcCx0aGlzLmJ5VHlwZUdpZC5zZXQoSi50eXBlLFEpO2xldCBZPVEuZ2V0KEouZ2lkKTtpZighWSlZPW5ldyBNYXAsUS5zZXQoSi5naWQsWSk7WS5zZXQoJCxKKX1pZihKLnRhZ3Mpe2xldCBRPXRoaXMuYnlUeXBlVGFnLmdldChKLnR5cGUpO2lmKCFRKVE9bmV3IE1hcCx0aGlzLmJ5VHlwZVRhZy5zZXQoSi50eXBlLFEpO2ZvcihsZXQgWSBvZiBKLnRhZ3Mpe2xldCBWPVEuZ2V0KFkpO2lmKCFWKVY9bmV3IE1hcCxRLnNldChZLFYpO1Yuc2V0KCQsSil9fX11bmluZGV4KCQsSil7aWYoIXRoaXMudXNlSW5kZXgpcmV0dXJuO2xldCBaPXRoaXMuYnlUeXBlLmdldChKLnR5cGUpO2lmKFope2lmKFouZGVsZXRlKCQpLFouc2l6ZT09PTApdGhpcy5ieVR5cGUuZGVsZXRlKEoudHlwZSl9aWYoSi5waWQpe2xldCBRPUIoSi5waWQpLFk9dGhpcy5ieVR5cGVQaWQuZ2V0KEoudHlwZSksVj1ZPy5nZXQoUSk7aWYoVil7aWYoVi5kZWxldGUoJCksVi5zaXplPT09MClZPy5kZWxldGUoUSl9aWYoWSYmWS5zaXplPT09MCl0aGlzLmJ5VHlwZVBpZC5kZWxldGUoSi50eXBlKX1pZih0eXBlb2YgSi5naWQ9PT0ic3RyaW5nIil7bGV0IFE9dGhpcy5ieVR5cGVHaWQuZ2V0KEoudHlwZSksWT1RPy5nZXQoSi5naWQpO2lmKFkpe2lmKFkuZGVsZXRlKCQpLFkuc2l6ZT09PTApUT8uZGVsZXRlKEouZ2lkKX1pZihRJiZRLnNpemU9PT0wKXRoaXMuYnlUeXBlR2lkLmRlbGV0ZShKLnR5cGUpfWlmKEoudGFncyl7bGV0IFE9dGhpcy5ieVR5cGVUYWcuZ2V0KEoudHlwZSk7aWYoUSl7Zm9yKGxldCBZIG9mIEoudGFncyl7bGV0IFY9US5nZXQoWSk7aWYoVil7aWYoVi5kZWxldGUoJCksVi5zaXplPT09MClRLmRlbGV0ZShZKX19aWYoUS5zaXplPT09MCl0aGlzLmJ5VHlwZVRhZy5kZWxldGUoSi50eXBlKX19fWNsZWFySW5kZXhlcygpe3RoaXMuYnlUeXBlLmNsZWFyKCksdGhpcy5ieVR5cGVQaWQuY2xlYXIoKSx0aGlzLmJ5VHlwZUdpZC5jbGVhcigpLHRoaXMuYnlUeXBlVGFnLmNsZWFyKCl9YnVja2V0TGlzdCgkKXtpZighJHx8JC5zaXplPT09MClyZXR1cm5bXTtsZXQgSj1bXTtmb3IobGV0IFogb2YgJC52YWx1ZXMoKSlKLnB1c2goWik7cmV0dXJuIEp9YXN5bmMgYXBwbHkoJCl7bGV0IEo9bmV3IFNldCxaPVtdLFE9W107Zm9yKGxldCBZIG9mICQpe2xldCBWPUIoWS5laWQpLFg9dGhpcy5lbnRzLmdldChWKSxbVyx6XT1lMChYLFkpO2lmKHohPT0wKXtRLnB1c2goeik7Y29udGludWV9aWYoVz09PXZvaWQgMCl7US5wdXNoKDEyKTtjb250aW51ZX1mb3IobGV0IEsgb2YgJCQoWCxXKSlKLmFkZChLKTt0aGlzLnB1dChXKSxaLnB1c2goWS5laWQpLFEucHVzaCgwKX1yZXR1cm57c3RhdHM6USx0eXBlczpKLGVpZHM6Wn19YXN5bmMgY2xlYXIoKXtyZXR1cm4gdGhpcy5lbnRzLmNsZWFyKCksdGhpcy5jbGVhckluZGV4ZXMoKSwwfWFzeW5jIGdldFJvdygkKXtsZXQgSj1CKCQpLFo9dGhpcy5lbnRzLmdldChKKTtyZXR1cm4gTyhaKX1hc3luYyBnZXRFbnQoJCl7bGV0W0osWl09YXdhaXQgdGhpcy5nZXRSb3coJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMHx8IWwoSikpcmV0dXJuIE8odm9pZCAwKTtyZXR1cm4gTyhKKX1hc3luYyBnZXRBbGxFbnRpdGllcyh7dHlwZTokLGdpZDpKLHBpZDpaLHRhZzpRLHVwZGF0ZWRCZXR3ZWVuOll9KXtpZih0aGlzLnVzZUluZGV4KXtpZihaIT09dm9pZCAwKXtsZXQgWD1CKFopO3JldHVybiBPKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZVBpZC5nZXQoJCk/LmdldChYKSkpfWlmKEohPT12b2lkIDApcmV0dXJuIE8odGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlR2lkLmdldCgkKT8uZ2V0KEopKSk7aWYoUSE9PXZvaWQgMClyZXR1cm4gTyh0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGVUYWcuZ2V0KCQpPy5nZXQoUSkpKTtpZihZIT09dm9pZCAwKXtsZXQgWD1bXSxXPXRoaXMuYnlUeXBlLmdldCgkKTtpZihXKXtmb3IobGV0IHogb2YgVy52YWx1ZXMoKSlpZih6LnVwZGF0ZWRBdD49WS5zdGFydCYmei51cGRhdGVkQXQ8PVkuZW5kKVgucHVzaCh6KX1yZXR1cm4gTyhYKX1yZXR1cm4gTyh0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGUuZ2V0KCQpKSl9bGV0IFY9W107aWYoWiE9PXZvaWQgMCl7Zm9yKGxldCBYIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihsKFgpJiZYLnR5cGU9PT0kJiZYLnBpZCYmcihYLnBpZCxaKSlWLnB1c2goWCl9ZWxzZSBpZihKIT09dm9pZCAwKXtmb3IobGV0IFggb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGwoWCkmJlgudHlwZT09PSQmJih0eXBlb2YgWC5naWQ9PT0ic3RyaW5nIiYmWC5naWQ9PT1KKSlWLnB1c2goWCl9ZWxzZSBpZihRIT09dm9pZCAwKXtmb3IobGV0IFggb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGwoWCkmJlgudHlwZT09PSQmJlgudGFncyYmWC50YWdzLmluY2x1ZGVzKFEpKVYucHVzaChYKX1lbHNlIGlmKFkhPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYobChYKSYmWC50eXBlPT09JCYmWC51cGRhdGVkQXQ+PVkuc3RhcnQmJlgudXBkYXRlZEF0PD1ZLmVuZClWLnB1c2goWCl9ZWxzZSBmb3IobGV0IFggb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGwoWCkmJlgudHlwZT09PSQpVi5wdXNoKFgpO3JldHVybiBPKFYpfWFzeW5jIGdldEVudGl0aWVzKCQpe2xldFtKLFpdPWF3YWl0IHRoaXMuZ2V0QWxsRW50aXRpZXMoJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7cmV0dXJuIE8oSil9YXN5bmMgY291bnRFbnRpdGllcyh7dHlwZTokfSl7aWYodGhpcy51c2VJbmRleClyZXR1cm4gTyh0aGlzLmJ5VHlwZS5nZXQoJCk/LnNpemU/PzApO2xldCBKPTA7Zm9yKGxldCBaIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihsKFopJiZaLnR5cGU9PT0kKUorPTE7cmV0dXJuIE8oSil9YXN5bmMgY2hlY2tzdW0oJCl7bGV0IEo9W107Zm9yKGxldCBaIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlKLnB1c2gobSQoWikpO3JldHVybiBFJChKLCQpfX1hc3luYyBmdW5jdGlvbiBkWigkKXtsZXQgSj1hd2FpdCBuWigpO2lmKCQ/LmNhY2hlPT09ITEpcmV0dXJuIEo7cmV0dXJuIG5ldyBESihKLHZvaWQgMCx7aW5kZXhlczokPy5pbmRleGVzfSl9Y2xhc3MgREp7bWVtO2R1cmFibGU7d2FybWVkPW5ldyBTZXQ7bGlzdGVuZXJzPW5ldyBTZXQ7Y2hhaW49UHJvbWlzZS5yZXNvbHZlKCk7Y29uc3RydWN0b3IoJCxKLFope2lmKHRoaXMuZHVyYWJsZT0kLHRoaXMubWVtPW5ldyBqSihKPz9bXSx7aW5kZXhlczpaPy5pbmRleGVzfSksSilmb3IobGV0IFEgb2YgSil0aGlzLndhcm1lZC5hZGQoUS50eXBlKX1zdWJzY3JpYmUoJCl7cmV0dXJuIHRoaXMubGlzdGVuZXJzLmFkZCgkKSwoKT0+e3RoaXMubGlzdGVuZXJzLmRlbGV0ZSgkKX19ZW1pdCgkKXtpZigkLnNpemU8MSlyZXR1cm47Zm9yKGxldCBKIG9mIHRoaXMubGlzdGVuZXJzKUooJCl9cnVuKCQpe2xldCBKPXRoaXMuY2hhaW4udGhlbigkLCQpO3JldHVybiB0aGlzLmNoYWluPUoudGhlbigoKT0+e3JldHVybn0sKCk9PntyZXR1cm59KSxKfWFwcGx5KCQpe3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57YXdhaXQgdGhpcy5wdWxsRWlkcygkLm1hcCgoVik9PlYuZWlkKSk7bGV0IEo9bFkodGhpcy5tZW0sJCk7dGhpcy5lbWl0KEoudHlwZXMpO2xldCBaPWF3YWl0IHRoaXMuZHVyYWJsZS5hcHBseSgkKSx7Y2hhbmdlZDpRLHN0YXR1czpZfT1hd2FpdCB0aGlzLnB1bGxFaWRzKCQubWFwKChWKT0+Vi5laWQpKTtpZih0aGlzLmVtaXQoUSksWSE9PTApcmV0dXJue3N0YXRzOiQubWFwKCgpPT5ZKSx0eXBlczpaLnR5cGVzLGVpZHM6Wi5laWRzfTtyZXR1cm4gWn0pfWNsZWFyKCl7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9PntsZXQgJD1hd2FpdCB0aGlzLmR1cmFibGUuY2xlYXIoKTtpZigkIT09MClyZXR1cm4gJDtsZXQgSj10aGlzLm1lbS5lbnRzLnNpemU+MDtyZXR1cm4gYXdhaXQgdGhpcy5tZW0uY2xlYXIoKSx0aGlzLndhcm1lZC5jbGVhcigpLDB9KX1pbmdlc3RGcm9tRHVyYWJsZSgkKXtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2xldHtjaGFuZ2VkOkosc3RhdHVzOlp9PWF3YWl0IHRoaXMucHVsbEVpZHMoJCk7cmV0dXJuIHRoaXMuZW1pdChKKSxafSl9YXN5bmMgcHVsbEVpZHMoJCl7bGV0IEo9bmV3IFNldCxaPW5ldyBTZXQ7Zm9yKGxldCBRIG9mICQpe2xldCBZPUIoUSk7aWYoWi5oYXMoWSkpY29udGludWU7Wi5hZGQoWSk7bGV0IFY9dGhpcy5tZW0uZW50cy5nZXQoWSksW1gsV109YXdhaXQgdGhpcy5kdXJhYmxlLmdldFJvdyhRKTtpZihXIT09MClyZXR1cm57Y2hhbmdlZDpKLHN0YXR1czpXfTtpZihYKXtpZih0aGlzLm1lbS5wdXQoWCksIVZ8fCF2WShWLFgpKXtpZihsKFgpKUouYWRkKFgudHlwZSk7aWYoViE9PXZvaWQgMCYmbChWKSlKLmFkZChWLnR5cGUpfX1lbHNlIGlmKFYhPT12b2lkIDApe2lmKHRoaXMubWVtLmRlbChZKSxsKFYpKUouYWRkKFYudHlwZSl9fXJldHVybntjaGFuZ2VkOkosc3RhdHVzOjB9fWFzeW5jIHdhcm1UeXBlKCQpe2lmKHRoaXMud2FybWVkLmhhcygkKSlyZXR1cm4gMDtsZXRbSixaXT1hd2FpdCB0aGlzLmR1cmFibGUuZ2V0RW50aXRpZXMoe3R5cGU6JH0pO2lmKFohPT0wKXJldHVybiBaO2lmKEopZm9yKGxldCBRIG9mIEope2xldCBZPUIoUS5laWQpLFY9dGhpcy5tZW0uZW50cy5nZXQoWSk7aWYoIVZ8fGlZKFEsVikpdGhpcy5tZW0ucHV0KFEpfXJldHVybiB0aGlzLndhcm1lZC5hZGQoJCksMH1hc3luYyBnZXRSb3coJCl7bGV0IEo9QigkKTtpZih0aGlzLm1lbS5lbnRzLmhhcyhKKSlyZXR1cm4gdGhpcy5tZW0uZ2V0Um93KCQpO3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57aWYodGhpcy5tZW0uZW50cy5oYXMoSikpcmV0dXJuIHRoaXMubWVtLmdldFJvdygkKTtsZXRbWixRXT1hd2FpdCB0aGlzLmR1cmFibGUuZ2V0Um93KCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFopdGhpcy5tZW0ucHV0KFopO3JldHVybiBPKFopfSl9YXN5bmMgZ2V0RW50KCQpe2xldFtKLFpdPWF3YWl0IHRoaXMuZ2V0Um93KCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDB8fCFsKEopKXJldHVybiBPKHZvaWQgMCk7cmV0dXJuIE8oSil9YXN5bmMgZ2V0RW50aXRpZXMoJCl7aWYoIXRoaXMud2FybWVkLmhhcygkLnR5cGUpKXtsZXQgSj1hd2FpdCB0aGlzLnJ1bigoKT0+dGhpcy53YXJtVHlwZSgkLnR5cGUpKTtpZihKIT09MClyZXR1cm4gRyhKKX1yZXR1cm4gdGhpcy5tZW0uZ2V0RW50aXRpZXMoJCl9YXN5bmMgY291bnRFbnRpdGllcyh7dHlwZTokfSl7aWYoIXRoaXMud2FybWVkLmhhcygkKSl7bGV0IEo9YXdhaXQgdGhpcy5ydW4oKCk9PnRoaXMud2FybVR5cGUoJCkpO2lmKEohPT0wKXJldHVybiBHKEopfXJldHVybiB0aGlzLm1lbS5jb3VudEVudGl0aWVzKHt0eXBlOiR9KX1hc3luYyBjaGVja3N1bSgkKXtyZXR1cm4gdGhpcy5kdXJhYmxlLmNoZWNrc3VtKCQpfX1mdW5jdGlvbiB2WSgkLEope2lmKGwoJCkhPT1sKEopKXJldHVybiExO2lmKCQuY3RyIT09Si5jdHIpcmV0dXJuITE7aWYoJC51cGRhdGVkQXQuZ2V0VGltZSgpIT09Si51cGRhdGVkQXQuZ2V0VGltZSgpKXJldHVybiExO2lmKCFyKCQuZWlkLEouZWlkKSlyZXR1cm4hMTtpZighbCgkKXx8IWwoSikpcmV0dXJuITA7aWYoJC5jcmVhdGVkQXQuZ2V0VGltZSgpIT09Si5jcmVhdGVkQXQuZ2V0VGltZSgpKXJldHVybiExO2lmKCQudHlwZSE9PUoudHlwZSlyZXR1cm4hMTtpZigkLmdpZCE9PUouZ2lkKXJldHVybiExO2lmKCFiWSgkLnBpZCxKLnBpZCkpcmV0dXJuITE7aWYoIXlZKCQudGFncyxKLnRhZ3MpKXJldHVybiExO3JldHVybiBoWSgkLmJvZHksSi5ib2R5KX1mdW5jdGlvbiB5WSgkLEope2lmKCQ9PT1KKXJldHVybiEwO2lmKCQ9PT12b2lkIDB8fEo9PT12b2lkIDApcmV0dXJuITE7aWYoJC5sZW5ndGghPT1KLmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IFo9MDtaPCQubGVuZ3RoO1orKylpZigkW1pdIT09SltaXSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBiWSgkLEope2lmKCQ9PT12b2lkIDAmJko9PT12b2lkIDApcmV0dXJuITA7aWYoJD09PXZvaWQgMHx8Sj09PXZvaWQgMClyZXR1cm4hMTtyZXR1cm4gcigkLEopfWZ1bmN0aW9uIGhZKCQsSil7aWYoT2JqZWN0LmlzKCQsSikpcmV0dXJuITA7aWYoJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkmJkogaW5zdGFuY2VvZiBVaW50OEFycmF5KXJldHVybiByKCQsSik7aWYoJCBpbnN0YW5jZW9mIERhdGUmJkogaW5zdGFuY2VvZiBEYXRlKXJldHVybiAkLmdldFRpbWUoKT09PUouZ2V0VGltZSgpO3RyeXtyZXR1cm4gcihFMCgkKSxFMChKKSl9Y2F0Y2h7cmV0dXJuITF9fWZ1bmN0aW9uIGlZKCQsSil7bGV0IFo9JC51cGRhdGVkQXQuZ2V0VGltZSgpLFE9Si51cGRhdGVkQXQuZ2V0VGltZSgpO2lmKFohPT1RKXJldHVybiBaPlE7cmV0dXJuICQuY3RyPkouY3RyfWZ1bmN0aW9uIGxZKCQsSil7bGV0IFo9bmV3IFNldCxRPVtdO2ZvcihsZXQgWSBvZiBKKXtsZXQgVj1CKFkuZWlkKSxYPSQuZW50cy5nZXQoViksW1csel09ZTAoWCxZKTtpZih6IT09MCl7US5wdXNoKHopO2NvbnRpbnVlfWlmKFc9PT12b2lkIDApe1EucHVzaCgxMik7Y29udGludWV9Zm9yKGxldCBLIG9mICQkKFgsVykpWi5hZGQoSyk7JC5wdXQoVyksUS5wdXNoKDApfXJldHVybntzdGF0czpRLHR5cGVzOlp9fWZ1bmN0aW9uIGwoJCl7cmV0dXJuInR5cGUiaW4gJH1mdW5jdGlvbiB1WSgkKXtpZighQXJyYXkuaXNBcnJheSgkKXx8JC5sZW5ndGg9PT0wKXJldHVybjtsZXQgSj1uZXcgU2V0LFo9W107Zm9yKGxldCBRIG9mICQpe2lmKHR5cGVvZiBRIT09InN0cmluZyJ8fFEubGVuZ3RoPT09MCljb250aW51ZTtpZihKLmhhcyhRKSljb250aW51ZTtKLmFkZChRKSxaLnB1c2goUSl9cmV0dXJuIFoubGVuZ3RoPjA/Wjp2b2lkIDB9ZnVuY3Rpb24gbSQoJCl7cmV0dXJue2VpZDokLmVpZCxjdHI6JC5jdHIsdXBkYXRlZEF0OiQudXBkYXRlZEF0fX1mdW5jdGlvbiByWigkKXtsZXQgSj1uZXcgbSgkLmVpZCksW1osUV09Si5yZWFkU3RydWN0KFYwKTtpZihRIT09MClyZXR1cm4gRyhRKTtyZXR1cm4gTyh7ZWlkOiQuZWlkLGN0cjokLmN0cix1cGRhdGVkQXQ6bmV3IERhdGUoWi50cy5nZXRUaW1lKCkrJC5vZmYpfSl9ZnVuY3Rpb24gZTAoJCxKKXtsZXQgWj1uZXcgbShKLmVpZCksW1EsWV09Wi5yZWFkU3RydWN0KFYwKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXQgVj1uZXcgRGF0ZShRLnRzLmdldFRpbWUoKStKLm9mZik7aWYoJCE9PXZvaWQgMCYmVjw9JC51cGRhdGVkQXQpcmV0dXJuIEcoMTUpO2lmKGxaKEopKXtsZXQgWD11WShKLnRhZ3MpO3JldHVybiBPKHtlaWQ6Si5laWQsZ2lkOkouZ2lkLHBpZDpKLnBpZCwuLi5YIT09dm9pZCAwP3t0YWdzOlh9Ont9LHR5cGU6Si50eXBlLGNyZWF0ZWRBdDpRLnRzLHVwZGF0ZWRBdDpWLGN0cjpKLmN0cixib2R5OkouYm9keX0pfXJldHVybiBPKHtlaWQ6Si5laWQsdXBkYXRlZEF0OlYsY3RyOkouY3RyfSl9ZnVuY3Rpb24gJCQoJCxKKXtsZXQgWj1uZXcgU2V0O2lmKCQhPT12b2lkIDAmJmwoJCkpWi5hZGQoJC50eXBlKTtpZihsKEopKVouYWRkKEoudHlwZSk7cmV0dXJuWy4uLlpdfWNsYXNzIFMke2luZmxpZ2h0PW51bGw7YWdhaW49ITE7cnVuKCQpe2lmKHRoaXMuYWdhaW49ITAsdGhpcy5pbmZsaWdodClyZXR1cm4gdGhpcy5pbmZsaWdodDtyZXR1cm4gdGhpcy5pbmZsaWdodD10aGlzLmRyYWluKCQpLHRoaXMuaW5mbGlnaHR9YXN5bmMgZmx1c2goKXtpZighdGhpcy5pbmZsaWdodClyZXR1cm47dHJ5e2F3YWl0IHRoaXMuaW5mbGlnaHR9Y2F0Y2h7fX1hc3luYyBkcmFpbigkKXt0cnl7dGhpcy5hZ2Fpbj0hMTtsZXQgSj1hd2FpdCAkKCk7d2hpbGUodGhpcy5hZ2Fpbil0aGlzLmFnYWluPSExLEo9YXdhaXQgJCgpO3JldHVybiBKfWZpbmFsbHl7dGhpcy5pbmZsaWdodD1udWxsfX19dmFyIG9aPTEwMDtjbGFzcyBBSnt0aW1lcj1udWxsO2RlbGF5TXM7d29yazt0YWlsPW5ldyBTJDtjb25zdHJ1Y3RvcigkLEope3RoaXMuZGVsYXlNcz0kPDA/MDokLHRoaXMud29yaz1KfXNjaGVkdWxlKCl7aWYodGhpcy5kZWxheU1zPD0wKXt0aGlzLmZpcmUoKTtyZXR1cm59aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpO3RoaXMudGltZXI9c2V0VGltZW91dCgoKT0+e3RoaXMudGltZXI9bnVsbCx0aGlzLmZpcmUoKX0sdGhpcy5kZWxheU1zKX1hc3luYyBmbHVzaCgpe2lmKHRoaXMudGltZXIhPT1udWxsKWNsZWFyVGltZW91dCh0aGlzLnRpbWVyKSx0aGlzLnRpbWVyPW51bGwsdGhpcy5maXJlKCk7YXdhaXQgdGhpcy50YWlsLmZsdXNoKCl9Y2FuY2VsKCl7aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLHRoaXMudGltZXI9bnVsbH1maXJlKCl7cmV0dXJuIHRoaXMudGFpbC5ydW4odGhpcy53b3JrKX19ZnVuY3Rpb24gYVooJCl7bGV0IEo9bmV3IG0oJC5laWQpLFtaLFFdPVYwLmRlY29kZShKKTtpZihRIT09MClyZXR1cm47cmV0dXJuIFoudHMuZ2V0VGltZSgpKyQub2ZmfWZ1bmN0aW9uIHBZKCQsSil7bGV0IFo9YVooJCksUT1hWihKKTtpZihaPT09dm9pZCAwJiZRPT09dm9pZCAwKXJldHVybiAwO2lmKFo9PT12b2lkIDApcmV0dXJuIDE7aWYoUT09PXZvaWQgMClyZXR1cm4tMTtpZihRIT09WilyZXR1cm4gUS1aO3JldHVybiBKLmN0ci0kLmN0cn1mdW5jdGlvbiBKJCgkLEope3JldHVybiAkLnNsaWNlKCkuc29ydCgoWixRKT0+cFkoSihaKSxKKFEpKSl9dmFyIF9KPXtwaGFzZToiaWRsZSJ9LE8kPTUwO2Z1bmN0aW9uIExKKCQsSixaKXtpZigkPD0wfHxKPD0wKXJldHVybiExO2lmKCQ9PT0xfHwkPT09SilyZXR1cm4hMDtyZXR1cm4gJCVaPT09MH1mdW5jdGlvbiBzWigkLEope2lmKHR5cGVvZiBuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYj09PSJmdW5jdGlvbiIpe25hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iKCQsSik7cmV0dXJufWxldCBaPVVSTC5jcmVhdGVPYmplY3RVUkwoJCksUT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7US5ocmVmPVosUS5kb3dubG9hZD1KLGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoUSksUS5jbGljaygpLGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoUSksVVJMLnJldm9rZU9iamVjdFVSTChaKX1mdW5jdGlvbiB0WigkLEosWil7bGV0IFE9W10sWT1bXSxWPTA7Zm9yKGxldCBYIG9mICQpe2xldCBXPUooWCk7aWYoWS5sZW5ndGg+MCYmVitXPlopUS5wdXNoKFkpLFk9W10sVj0wO2lmKFkucHVzaChYKSxWKz1XLFY+PVopUS5wdXNoKFkpLFk9W10sVj0wfWlmKFkubGVuZ3RoPjApUS5wdXNoKFkpO3JldHVybiBRfWFzeW5jIGZ1bmN0aW9uIHhKKCQsSixaKXtsZXQgUT0kLmxlbmd0aDtpZihRPDEpcmV0dXJuW107bGV0IFk9QXJyYXkoUSksVj0wLFg9TWF0aC5taW4oTWF0aC5tYXgoMSxKKSxRKSxXPWFzeW5jKCk9Pnt3aGlsZSghMCl7bGV0IEs9VjtpZihWKz0xLEs+PVEpcmV0dXJuO1lbS109YXdhaXQgWigkW0tdLEspfX0sej1bXTtmb3IobGV0IEs9MDtLPFg7SysrKXoucHVzaChXKCkpO3JldHVybiBhd2FpdCBQcm9taXNlLmFsbCh6KSxZfWFzeW5jIGZ1bmN0aW9uIHYkKCQsSixaLFEpe2xldCBZPW5ldyBtKCQuaGVhZENwaCksW1YsWF09WS5yZWFkU3RydWN0KEwkKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXR7c2lnOlcsa2RtOnosaGVhZENwaDpLfT1WO2lmKCFhd2FpdCBRLmNoZWNrU2lnRWQyNTUxOShXLEssSikpcmV0dXJuIEcoMyk7bGV0IE49Wi5kZXJpdmVDaXBoZXIoeiwiZGVjcnlwdCIpLFU7dHJ5e1U9YXdhaXQgTi5kZWNyeXB0KEspfWNhdGNoe3JldHVybiBHKDIwKX1yZXR1cm4gTyh7a2RtOnosaGVhZEVuYzpVfSl9dmFyIFEkPSJmIix5JD0idCIsWiQ9ImUiO2Z1bmN0aW9uIGNZKCQpe2lmKCQ9PT0hMHx8JD09PXkkKXJldHVybiB5JDtpZigkPT09WiQpcmV0dXJuIFokO3JldHVybiBRJH1mdW5jdGlvbiBlWigkKXtyZXR1cm4gJCE9PTAmJiQhPT0xNSYmJCE9PTE4JiYkIT09MTd9ZnVuY3Rpb24gQkooJCxKLFope2lmKCQuYXBsZD1KLEo9PT1aJCYmWiE9PXZvaWQgMCkkLmVycj1aO2Vsc2UgZGVsZXRlICQuZXJyfWFzeW5jIGZ1bmN0aW9uIGIkKCQsSixaLFEpe2xldCBZPVE/LmJvZHkhPT0hMSxWPWNZKEouYXBsZCksWD1KLmJvZHksVz1YPy5sZW5ndGg/PzAsejtpZihZJiZYJiZXPjApej1hd2FpdCBaLmJsYWtlMyhYKTtsZXQgSz17ZWlkOkouZWlkLG9mZjpKLm9mZj8/MCxjdHI6Si5jdHI/PzAsbGVuOlcsaHNoOnp9LEY9e2hhc2g6JCxoZWFkOkssYXBsZDpWfTtpZihZJiZYIT09dm9pZCAwKUYuYm9keT1YO2lmKFY9PT1aJCYmSi5lcnIhPT12b2lkIDApRi5lcnI9Si5lcnI7cmV0dXJuIEZ9dmFyIGtKPTEwNDg1NzYsRUo9MTA0ODU3NixKUT02NDtmdW5jdGlvbiBuWSgkKXtyZXR1cm4gJC5zaWcubGVuZ3RoKyQua2RtLmxlbmd0aCskLmhlYWRDcGgubGVuZ3RoKyQuYm9keUNwaC5sZW5ndGh9YXN5bmMgZnVuY3Rpb24gZFkoJCxKLFosUSxZKXtpZihRLmxlbmd0aDwxKXJldHVybiAwO2xldFtWLFhdPWF3YWl0ICQucHVzaChRKTtpZihYIT09MClyZXR1cm4gWDtpZighVilyZXR1cm4gMjc7Zm9yKGxldCB6IG9mIFYpe2lmKHouc3RhdHVzIT09MCl7Y29uc29sZS5lcnJvcigicHVzaCBlcnIiLHopO2NvbnRpbnVlfWxldCBLPVlbei5pZHhdO2lmKCFLKXtjb25zb2xlLmVycm9yKCJubyBoYXNoIix6KTtjb250aW51ZX1hd2FpdCBKLnVwbG9hZHMuZGVxKFosW0tdKX1sZXQgVz1hd2FpdCBKLmhvc3RzLmdldChaKTtpZihXKXtsZXQgej1XLmxhc3RTZXEsSz16LEY9W107Zm9yKGxldCBOIG9mIFYpaWYoTi5zdGF0dXM9PT0wKUYucHVzaChOLnNlcSk7Ri5zb3J0KChOLFUpPT5OLVUpO2ZvcihsZXQgTiBvZiBGKWlmKE49PT16KzEpej1OO2lmKHo+Sylhd2FpdCBKLmhvc3RzLnRvdWNoKFoseil9cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gJFEoJCxKKXtpZihKLmxlbmd0aDwxKXJldHVybiBPKFtdKTtsZXQgWj1uZXcgTWFwLFE9W107Zm9yKGxldCBXIG9mIEopWi5zZXQoVy5zZXEsVyksUS5wdXNoKFcuc2VxKTtsZXRbWSxWXT1hd2FpdCAkLnB1bGwoUSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoIVkpcmV0dXJuIEcoMjcpO2xldCBYPVtdO2ZvcihsZXR7c2VxOlcsYm9keUNwaDp6fW9mIFkpe2xldCBLPVouZ2V0KFcpO2lmKCFLKWNvbnRpbnVlO1gucHVzaCh7ZGw6Syxib2R5Q3BoOnp9KX1yZXR1cm4gTyhYKX1hc3luYyBmdW5jdGlvbiByWSgkLEosWixRKXtpZihRLmxlbmd0aDwxKXJldHVybiBPKHtwYXJ0czpbXSxoYXNoZXM6W119KTtsZXQgWT1bXSxWPVtdLFg9W10sVz1uZXcgTWFwO2ZvcihsZXR7ZGw6Syxib2R5Q3BoOkZ9b2YgUSl7bGV0e2hlYWQ6TixrZG06VSxzZXE6Uixob3N0OnF9PUssW0gsTV09YXdhaXQgWlEoSyxaKTtpZihNIT09MHx8IUgpe2xldCBrPVcuZ2V0KHEpPz9bXTtrLnB1c2goUiksVy5zZXQocSxrKTtjb250aW51ZX1sZXR7aGVhZEVuYzpQLGhlYWRFbmNIYXNoOkN9PUgsVD1KLmRlcml2ZUNpcGhlcihVLCJkZWNyeXB0IiksW0ksQV09YXdhaXQgS0ooUCxGLFQsWixDKTtpZihBIT09MHx8IUkpe2xldCBrPVcuZ2V0KHEpPz9bXTtrLnB1c2goUiksVy5zZXQocSxrKTtjb250aW51ZX1sZXQgTD17aGVhZDpOLGJvZHk6SS5ib2R9LGc9SS5oZWFkSGFzaDtYLnB1c2goe2tleTpnLGRhdGE6VlEoTCl9KSxZLnB1c2goTCksVi5wdXNoKGcpO2xldCBmPVcuZ2V0KHEpPz9bXTtmLnB1c2goUiksVy5zZXQocSxmKX1sZXQgej1hd2FpdCAkLm1lc3NhZ2VzLmFkZChYKTtmb3IobGV0W0ssRl1vZiBXKWF3YWl0ICQuZG93bmxvYWRzLmRlcShLLEYpO2ZvcihsZXQgSz0wO0s8ei5sZW5ndGg7SysrKXtsZXQgRj16W0tdO2lmKEYhPT0wJiZGIT09MTUpY29uc29sZS5lcnJvcigiRVJSIHN0b3JpbmciLERbRl0sImZvciBtZXNzYWdlIixLKX1yZXR1cm4gTyh7cGFydHM6WSxoYXNoZXM6Vn0pfWFzeW5jIGZ1bmN0aW9uIFpRKCQsSil7bGV0IFo9JC5oZWFkRW5jO2lmKCFaKXtsZXQgWT1uZXcgUyxWPVkud3JpdGVTdHJ1Y3QoRzAsJC5oZWFkKTtpZihWIT09MClyZXR1cm4gRyhWKTtaPVkucmVzdWx0KCl9aWYoJC5oZWFkRW5jSGFzaClyZXR1cm4gTyh7aGVhZEVuYzpaLGhlYWRFbmNIYXNoOiQuaGVhZEVuY0hhc2h9KTtsZXQgUT1hd2FpdCBKLmJsYWtlMyhaKTtyZXR1cm4gTyh7aGVhZEVuYzpaLGhlYWRFbmNIYXNoOlF9KX1hc3luYyBmdW5jdGlvbiBRUSgkLEosWil7bGV0IFE9bmV3IFNldDtmb3IobGV0IFggb2YgSilRLmFkZChCKFgpKTtpZihRLnNpemU8MSlyZXR1cm47bGV0IFk9QXJyYXkuZnJvbShhd2FpdCAkLmRvd25sb2Fkcy5saXN0KCkpO2lmKFkubGVuZ3RoPDEpcmV0dXJuO2xldCBWPW5ldyBNYXA7Zm9yKGxldCBYIG9mIFkpe2xldCBXO2lmKFguaGVhZEVuY0hhc2gpVz1CKFguaGVhZEVuY0hhc2gpO2Vsc2V7bGV0W0ssRl09YXdhaXQgWlEoWCxaKTtpZihGIT09MHx8IUspY29udGludWU7Vz1CKEsuaGVhZEVuY0hhc2gpfWlmKCFRLmhhcyhXKSljb250aW51ZTtsZXQgej1WLmdldChYLmhvc3QpPz9bXTt6LnB1c2goWC5zZXEpLFYuc2V0KFguaG9zdCx6KX1mb3IobGV0W1gsV11vZiBWKWF3YWl0ICQuZG93bmxvYWRzLmRlcShYLFcpfWFzeW5jIGZ1bmN0aW9uIGZKKHtjb25uOiQsc3RvcmU6SixlbmNsYXZlOlosaG9zdDpRLGNyeXB0bzpZLG9uUHJvZ3Jlc3M6VixwZWVrUHJvZ3Jlc3NFdmVyeTpYLHBlZWtDb25jdXJyZW5jeTpXfSl7bGV0IHo9YXdhaXQgJC5pZGVudGl0eSgpLEs9W10sW0YsTl09YXdhaXQgJC5wZWVrKFEubGFzdFNlcSk7aWYoTiE9PTApcmV0dXJuIE47bGV0IFU9Ri5sZW5ndGgsUj1YPz9PJCxxPVc/P0pRO2lmKFYmJlU+MClWKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6MCx0b3RhbDpVfSk7bGV0IEg9MCxNPWF3YWl0IHhKKEYscSxhc3luYyhDKT0+e2xldFtULEldPWF3YWl0IHYkKEMsei5wdWJsaWNLZXksWixZKSxBO2lmKEkhPT0wfHwhVClBPXtvazohMSxzZXE6Qy5zZXEsc3RhdDpJfTtlbHNle2xldCBMPWF3YWl0IFkuYmxha2UzKFQuaGVhZEVuYyk7QT17b2s6ITAsc2VxOkMuc2VxLGtkbTpULmtkbSxoZWFkRW5jOlQuaGVhZEVuYyxoZWFkRW5jSGFzaDpMfX1pZihIKz0xLFYmJkxKKEgsVSxSKSlWKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6SCx0b3RhbDpVfSk7cmV0dXJuIEF9KSxQPW5ldyBTZXQ7Zm9yKGxldCBDIG9mIE0pe2lmKCFDLm9rKXtjb25zb2xlLmVycm9yKCJwZWVrOiBkZWNyeXB0aW5nIGl0ZW0gaGVhZCIsQy5zdGF0KTtjb250aW51ZX1sZXQgVD1CKEMuaGVhZEVuY0hhc2gpO2lmKGF3YWl0IEoubWVzc2FnZXMuaGFzKEMuaGVhZEVuY0hhc2gpKXtjb25zb2xlLmluZm8oInBlZWs6IGxvY2FsIG1zZzsgc2tpcCBkb3dubG9hZCwgZGVxIHVwbG9hZCIpLGF3YWl0IEoudXBsb2Fkcy5kZXEoUS5sYWJlbCxbQy5oZWFkRW5jSGFzaF0pLGF3YWl0IEouZG93bmxvYWRzLmRlcShRLmxhYmVsLFtDLnNlcV0pO2NvbnRpbnVlfWlmKFAuaGFzKFQpKXthd2FpdCBKLmRvd25sb2Fkcy5kZXEoUS5sYWJlbCxbQy5zZXFdKTtjb250aW51ZX1sZXQgQT1uZXcgbShDLmhlYWRFbmMpLFtMLGddPUEucmVhZFN0cnVjdChHMCk7aWYoZyE9PTApe2NvbnNvbGUuZXJyb3IoInBlZWs6IHJlYWRpbmcgaXRlbSBoZWFkIixnKTtjb250aW51ZX1QLmFkZChUKSxLLnB1c2goe2tkbTpDLmtkbSxoZWFkOkwsc2VxOkMuc2VxLGhvc3Q6US5sYWJlbCxoZWFkRW5jOkMuaGVhZEVuYyxoZWFkRW5jSGFzaDpDLmhlYWRFbmNIYXNofSl9aWYoYXdhaXQgSi5kb3dubG9hZHMuZW5xKEspLEYubGVuZ3RoPjApe2xldCBDPU1hdGgubWF4KC4uLkYubWFwKChUKT0+VC5zZXEpKTthd2FpdCBKLmhvc3RzLnJlY29yZFN0YXRzKFEubGFiZWwse2xhc3RTZXE6Q30pfWlmKFYpVih7cGhhc2U6InBlZWsiLGhvc3Q6US5sYWJlbCxkb25lOlUsdG90YWw6VX0pO3JldHVybiAwfWFzeW5jIGZ1bmN0aW9uIFlRKHtjb25uOiQsc3RvcmU6Sixob3N0OlosbWF4UHVzaEJ5dGVzOlEsb25Qcm9ncmVzczpZfSl7bGV0IFY9UT8/a0osWD1hd2FpdCBKLnVwbG9hZHMubGlzdChaLmxhYmVsKSxXPVgubGVuZ3RoLHo9MDtpZihZJiZXPjApWSh7cGhhc2U6InB1c2giLGhvc3Q6Wi5sYWJlbCxkb25lOjAsdG90YWw6V30pO2xldCBLPVtdLEY9W10sTj0wLFU9YXN5bmMoKT0+e2lmKEsubGVuZ3RoPDEpcmV0dXJuIDA7bGV0IFI9Sy5sZW5ndGgscT1hd2FpdCBkWSgkLEosWi5sYWJlbCxLLEYpO2lmKEs9W10sRj1bXSxOPTAscT09PTApe2lmKHorPVIsWSlZKHtwaGFzZToicHVzaCIsaG9zdDpaLmxhYmVsLGRvbmU6eix0b3RhbDpXfSl9cmV0dXJuIHF9O2ZvcihsZXQgUiBvZiBYKXtsZXQgcT1hd2FpdCBKLm1lc3NhZ2VzLmdldChSKTtpZighcSl7eis9MTtjb250aW51ZX1sZXQgSD17Li4ucS5oZWFkLGJvZDpxLmJvZHl9LFtNLFBdPWF3YWl0ICQuc2VhbChIKTtpZihQIT09MClyZXR1cm4gUDtpZighTSlyZXR1cm4gMTI7bGV0IEM9blkoTSk7aWYoSy5sZW5ndGg+MCYmTitDPlYpe2xldCBUPWF3YWl0IFUoKTtpZihUIT09MClyZXR1cm4gVH1pZihLLnB1c2goTSksRi5wdXNoKFIpLE4rPUMsTj49Vil7bGV0IFQ9YXdhaXQgVSgpO2lmKFQhPT0wKXJldHVybiBUfX1yZXR1cm4gVSgpfWFzeW5jIGZ1bmN0aW9uIGdKKHtjb25uOiQsc3RvcmU6SixlbmNsYXZlOlosaG9zdDpRLGNyeXB0bzpZLG1heFB1bGxCeXRlczpWLG9uUHJvZ3Jlc3M6WH0sVyl7bGV0IHo9Vj8/RUosSz1hd2FpdCBKLmRvd25sb2Fkcy5saXN0KCksRj1BcnJheS5mcm9tKEspLmZpbHRlcigoTSk9Pk0uaG9zdD09PVEubGFiZWwpO2lmKEYubGVuZ3RoPDEpcmV0dXJuIDE1O2xldCBOPUokKEYsKE0pPT5NLmhlYWQpLFU9dFooTiwoTSk9Pk0uaGVhZC5sZW4seiksUj1OLmxlbmd0aCxxPTA7aWYoWClYKHtwaGFzZToicHVsbCIsaG9zdDpRLmxhYmVsLGRvbmU6MCx0b3RhbDpSfSk7bGV0IEg9JFEoJCxVWzBdKTtmb3IobGV0IE09MDtNPFUubGVuZ3RoO00rKyl7bGV0W1AsQ109YXdhaXQgSDtpZihDIT09MHx8IVApcmV0dXJuIEM7aWYocSs9VVtNXS5sZW5ndGgsWClYKHtwaGFzZToicHVsbCIsaG9zdDpRLmxhYmVsLGRvbmU6cSx0b3RhbDpSfSk7bGV0IFQ9VVtNKzFdO2lmKFQpSD0kUSgkLFQpO2lmKFgpWCh7cGhhc2U6Im9wZW4iLGhvc3Q6US5sYWJlbCxkb25lOnEsdG90YWw6Un0pO2xldCBJPUokKFAsKEwpPT5MLmRsLmhlYWQpLFssQV09YXdhaXQgclkoSixaLFksSSk7aWYoQSE9PTApcmV0dXJuIEE7aWYoVyl7aWYoWClYKHtwaGFzZToiZXhlYyIsaG9zdDpRLmxhYmVsLGRvbmU6cSx0b3RhbDpSfSk7YXdhaXQgVygpfX1yZXR1cm4gMH1mdW5jdGlvbiBWUSh7aGVhZDokLGJvZHk6Sn0pe2xldCBaPXtlaWQ6JC5laWQsYm9keTpKLGFwbGQ6USR9O2lmKCQub2ZmIT09MClaLm9mZj0kLm9mZjtpZigkLmN0ciE9PTApWi5jdHI9JC5jdHI7cmV0dXJuIFp9YXN5bmMgZnVuY3Rpb24gWFEoJCx7Y29ubjpKLHN0b3JlOlosZW5jbGF2ZTpRLGhvc3Q6WSxjcnlwdG86VixvblByb2dyZXNzOlh9LFcpe2xldCB6PVkubGFiZWwsSz1hd2FpdCBKLmlkZW50aXR5KCksRj1uZXcgbSgkKSxbTixVXT1GLnJlYWRTdHJ1Y3RzKF8kKTtpZihVIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIGRlY29kaW5nIG5vdGlmIixEW1VdKTtyZXR1cm59bGV0IFI9ITEsSD0oYXdhaXQgWi5ob3N0cy5nZXQoeikpPy5sYXN0U2VxLE09W10sUD0hMTtmb3IobGV0IEkgb2YgTil7bGV0W0EsTF09YXdhaXQgdiQoe3NlcTpJLnNlcSxoZWFkQ3BoOkkuaGVhZENwaH0sSy5wdWJsaWNLZXksUSxWKTtpZihMIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIGRlY3J5cHRpbmcgbm90aWYiLERbTF0pO2NvbnRpbnVlfWxldCBnPWF3YWl0IFYuYmxha2UzKEEuaGVhZEVuYyk7aWYoYXdhaXQgWi5tZXNzYWdlcy5oYXMoZykpY29udGludWU7bGV0IGY9bmV3IG0oQS5oZWFkRW5jKSxbayx5XT1mLnJlYWRTdHJ1Y3QoRzApO2lmKHkhPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgdG8gcGFyc2UgaGVhZCIsRFt5XSk7Y29udGludWV9aWYoIUkuYm9keUNwaCYmay5sZW4+MClQPSEwLGF3YWl0IFouZG93bmxvYWRzLmVucShbe3NlcTpJLnNlcSxob3N0Onosa2RtOkEua2RtLGhlYWQ6ayxoZWFkRW5jOkEuaGVhZEVuYyxoZWFkRW5jSGFzaDpnfV0pO2Vsc2UgTS5wdXNoKHsuLi5BLGhlYWQ6ayxib2R5Q3BoOkkuYm9keUNwaCxoZWFkRW5jSGFzaDpnfSk7aWYoSD09PXZvaWQgMHx8SS5zZXEhPT1IKzEpY29uc29sZS5sb2coIm91dCBvZiBzZXEiLEkuc2VxLEgpLFI9ITA7ZWxzZSBIPUkuc2VxfWlmKEghPT12b2lkIDApYXdhaXQgWi5ob3N0cy50b3VjaChZLmxhYmVsLEgpO2xldCBDPVtdO2ZvcihsZXQgSSBvZiBNKXtsZXQgQT1RLmRlcml2ZUNpcGhlcihJLmtkbSwiZGVjcnlwdCIpLFtMLGddPWF3YWl0IEtKKEkuaGVhZEVuYyxJLmJvZHlDcGgsQSxWKTtpZihnIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIHRvIG9wZW4gYm9keSIsRFtnXSk7Y29udGludWV9Qy5wdXNoKHtrZXk6SS5oZWFkRW5jSGFzaCxkYXRhOlZRKHtoZWFkOkkuaGVhZCxib2R5OkwuYm9kfSl9KX1sZXQgVD1hd2FpdCBaLm1lc3NhZ2VzLmFkZChDKTtmb3IobGV0IEk9MDtJPFQubGVuZ3RoO0krKyl7bGV0IEE9VFtJXTtpZihBIT09MCYmQSE9PTE1KWNvbnNvbGUuZXJyb3IoIkVSUiBzdG9yaW5nIixEW0FdLCJmb3IgbWVzc2FnZSIsSSl9aWYoWCYmQy5sZW5ndGg+MClYKHtwaGFzZToib3BlbiIsaG9zdDpZLmxhYmVsLGRvbmU6Qy5sZW5ndGgsdG90YWw6Qy5sZW5ndGh9KTtpZihSfHxQfHxDLmxlbmd0aD4wKVcoKX1hc3luYyBmdW5jdGlvbiBtSigkLEo9e30pe2xldCBaPUoucHVsbCE9PSExLFE9Si5wdXNoPT09ITAse2Nvbm46WSxzdG9yZTpWLGVuY2xhdmU6WCxob3N0OlcsY3J5cHRvOnosb25Qcm9ncmVzczpLLHBlZWtQcm9ncmVzc0V2ZXJ5OkYscGVla0NvbmN1cnJlbmN5Ok59PSQsVT1hd2FpdCBZLmlkZW50aXR5KCksW1IscV09YXdhaXQgWS5wZWVrKDApO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldCBIPVIubGVuZ3RoLE09Rj8/TyQsUD1OPz9KUTtpZihLJiZIPjApSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOjAsdG90YWw6SH0pO2xldCBDPTAsVD1hd2FpdCB4SihSLFAsYXN5bmMoeCk9PntsZXRbdixFXT1hd2FpdCB2JCh4LFUucHVibGljS2V5LFgseiksaTtpZihFIT09MHx8IXYpaT17b2s6ITEsc2VxOnguc2VxLHN0YXQ6RX07ZWxzZXtsZXQgXz1hd2FpdCB6LmJsYWtlMyh2LmhlYWRFbmMpO2k9e29rOiEwLHNlcTp4LnNlcSxrZG06di5rZG0saGVhZEVuYzp2LmhlYWRFbmMsaGVhZEVuY0hhc2g6X319aWYoQys9MSxLJiZMSihDLEgsTSkpSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOkMsdG90YWw6SH0pO3JldHVybiBpfSksST1uZXcgTWFwO2ZvcihsZXQgeCBvZiBUKXtpZigheC5vayljb250aW51ZTtsZXQgdj1CKHguaGVhZEVuY0hhc2gpLEU9SS5nZXQodik7aWYoRSlFLmNvdW50Kz0xO2Vsc2UgSS5zZXQodix7aGFzaDp4LmhlYWRFbmNIYXNoLGNvdW50OjEsc2FtcGxlOnh9KX1sZXQgQT0wLEw9W107Zm9yKGxldCB4IG9mIEkudmFsdWVzKCkpe2lmKHguY291bnQ+MSlBKz14LmNvdW50LTE7TC5wdXNoKHguaGFzaCl9bGV0IGc9Ui5sZW5ndGgsZj1JLnNpemUsaz1hd2FpdCBOJChMLHopLHk9W10saD0wO2ZvcihsZXQgeCBvZiBJLnZhbHVlcygpKXtpZihhd2FpdCBWLm1lc3NhZ2VzLmhhcyh4Lmhhc2gpKXthd2FpdCBWLnVwbG9hZHMuZGVxKFcubGFiZWwsW3guaGFzaF0pO2NvbnRpbnVlfWlmKGgrPTEsIVopY29udGludWU7bGV0IEU9eC5zYW1wbGUsaT1uZXcgbShFLmhlYWRFbmMpLFtfLGRdPWkucmVhZFN0cnVjdChHMCk7aWYoZCE9PTApe2NvbnNvbGUuZXJyb3IoInJlY29uY2lsZTogcmVhZGluZyBtc2cgaGVhZGVyIixkKTtjb250aW51ZX15LnB1c2goe2tkbTpFLmtkbSxoZWFkOl8sc2VxOkUuc2VxLGhvc3Q6Vy5sYWJlbCxoZWFkRW5jOkUuaGVhZEVuYyxoZWFkRW5jSGFzaDpFLmhlYWRFbmNIYXNofSl9aWYoeS5sZW5ndGg+MClhd2FpdCBWLmRvd25sb2Fkcy5lbnEoeSk7bGV0IHc9MDtpZihRKXtsZXQgeD1hd2FpdCBWLm1lc3NhZ2VzLmxpc3RLZXlzKCksdj1uZXcgU2V0KEkua2V5cygpKSxFPVtdO2ZvcihsZXQgaSBvZiB4KWlmKCF2LmhhcyhCKGkpKSl3Kz0xLEUucHVzaChpKTtpZihFLmxlbmd0aD4wKWF3YWl0IFYudXBsb2Fkcy5lbnEoVy5sYWJlbCxFKX1lbHNle2xldCB4PWF3YWl0IFYubWVzc2FnZXMubGlzdEtleXMoKSx2PW5ldyBTZXQoSS5rZXlzKCkpO2ZvcihsZXQgRSBvZiB4KWlmKCF2LmhhcyhCKEUpKSl3Kz0xfWxldCBwPVIubGVuZ3RoPjA/TWF0aC5tYXgoLi4uUi5tYXAoKHgpPT54LnNlcSkpOjA7aWYoYXdhaXQgVi5ob3N0cy5yZWNvcmRTdGF0cyhXLmxhYmVsLHtzZXRMYXN0U2VxOnB9KSxLKUsoe3BoYXNlOiJwZWVrIixob3N0OlcubGFiZWwsZG9uZTpILHRvdGFsOkh9KTtyZXR1cm4gTyh7bXNnY2hlY2s6ayxudW1CYWdzOmcsdW5pcXVlTXNnczpmLG51bUR1cGVzOkEsbWlzc2luZ0xvY2FsOmgsbWlzc2luZ0hvc3Q6d30pfWNsYXNzIFNKe2Nsb2NrO3N0YXRlO3N0b3JlO3RyYW5zcG9ydDtjcnlwdG87Zm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQ7b25TY2hlZHVsZVN5bmM7Y29ubmVjdGlvbnM9bmV3IE1hcDthcHBseUNoYWluPVByb21pc2UucmVzb2x2ZSgpO3N5bmNSdW5zPW5ldyBTJDtjbGllbnRTdGF0ZTt4ZmVyU3RhdGU7bWF4UHVzaEJ5dGVzO21heFB1bGxCeXRlcztwZWVrUHJvZ3Jlc3NFdmVyeT1PJDtsYXN0UHJvZ3Jlc3M9X0o7c2NoZWR1bGVkU3luYztjb25zdHJ1Y3RvcigkLEosWixRLFksVj0hMCxYPWtKLFc9RUoseil7dGhpcy5jbG9jaz0kO3RoaXMuc3RhdGU9Sjt0aGlzLnN0b3JlPVo7dGhpcy50cmFuc3BvcnQ9UTt0aGlzLmNyeXB0bz1ZO3RoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQ9Vjt0aGlzLm9uU2NoZWR1bGVTeW5jPXo7dGhpcy5tYXhQdXNoQnl0ZXM9WCx0aGlzLm1heFB1bGxCeXRlcz1XLHRoaXMuY2xpZW50U3RhdGU9bmV3IGYwKCgpPT50aGlzLmdldENsaWVudFN0YXRlKCkpLHRoaXMueGZlclN0YXRlPW5ldyBmMCgoKT0+dGhpcy5nZXRYZmVyU3RhdGUoKSksdGhpcy5zY2hlZHVsZWRTeW5jPW5ldyBBSihvWixhc3luYygpPT57dHJ5e2NvbnNvbGUuaW5mbygiUnVubmluZyBzY2hlZHVsZWQgc3luYyIpLGF3YWl0IHRoaXMuc3luYygpfWNhdGNoKEspe2NvbnNvbGUuZXJyb3IoIkRlYm91bmNlZCBzeW5jIGZhaWxlZDoiLEspfX0pfWVtaXRQcm9ncmVzcz0oJCk9Pnt0aGlzLmxhc3RQcm9ncmVzcz0kLHRoaXMueGZlclN0YXRlLmVtaXQoKX07YXN5bmMgc2V0U2VlZCgkLEope2F3YWl0IHRoaXMuc3RvcmUuc2VlZC5zYXZlKCQsSiksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9YXN5bmMgZ2V0Q2xpZW50U3RhdGUoKXtsZXR7c3RvcmU6JCxjb25uZWN0aW9uczpKfT10aGlzLFo9YXdhaXQgJC5zZWVkLmxvYWQoKSxRPWF3YWl0ICQuaG9zdHMubGlzdCgpLFk9ITE7Zm9yKGxldCBWIG9mIEoudmFsdWVzKCkpaWYoVi5pc0Nvbm5lY3RlZCgpKXtZPSEwO2JyZWFrfXJldHVybntoYXNTZWVkOlohPT12b2lkIDAsaGFzSG9zdDpBcnJheS5mcm9tKFEpLmxlbmd0aD4wLGNvbm5lY3RlZDpZfX1hc3luYyBnZXRYZmVyU3RhdGUoKXtsZXR7dXBsb2FkczokLGRvd25sb2FkczpKfT10aGlzLnN0b3JlLFo9YXdhaXQgJC5jb3VudCgpO3JldHVybntudW1Eb3dubG9hZHM6YXdhaXQgSi5jb3VudCgpLG51bVVwbG9hZHM6Wixwcm9ncmVzczp0aGlzLmxhc3RQcm9ncmVzc319YXBwbHk9KCQsSik9PntyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMuZG9BcHBseSgkLEopKX07YXN5bmMgZG9BcHBseSgkLEo9e2VucXVldWVVcGxvYWQ6ITAsdHJpZ2dlclVwbG9hZDohMH0pe2xldCBaPVtdLFE9W107Zm9yKGxldHtoZWFkOlYsYm9keTpYfW9mICQpe2xldCBXPW5ldyBTO1cud3JpdGVTdHJ1Y3QoRzAsVik7bGV0IHo9Vy5yZXN1bHQoKSxLPWF3YWl0IHRoaXMuY3J5cHRvLmJsYWtlMyh6KSxGPXtlaWQ6Vi5laWQsYm9keTpYLGFwbGQ6USR9O2lmKFYub2ZmIT09MClGLm9mZj1WLm9mZjtpZihWLmN0ciE9PTApRi5jdHI9Vi5jdHI7Wi5wdXNoKEspLFEucHVzaCh7a2V5OkssZGF0YTpGfSl9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5hZGQoUSksYXdhaXQgUVEodGhpcy5zdG9yZSxaLHRoaXMuY3J5cHRvKTtsZXQgWT1hd2FpdCB0aGlzLmRvQXBwbHlIYXNoZXMoWik7aWYoSi5lbnF1ZXVlVXBsb2FkKXtsZXQgVj1bXTtmb3IobGV0IFg9MDtYPFoubGVuZ3RoO1grKyl7bGV0IFc9WVtYXTtpZihXPT09MHx8Vz09PTE1KVYucHVzaChaW1hdKX1pZihWLmxlbmd0aD4wKXtsZXQgWD1hd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmxpc3QoKTtmb3IobGV0IFcgb2YgWClhd2FpdCB0aGlzLnN0b3JlLnVwbG9hZHMuZW5xKFcubGFiZWwsVik7dGhpcy54ZmVyU3RhdGUuZW1pdCgpfX1pZihKLnRyaWdnZXJVcGxvYWQpdGhpcy5zY2hlZHVsZVN5bmMoKTtyZXR1cm4gWX1lbnF1ZXVlQXBwbHlKb2IoJCl7bGV0IEo9dGhpcy5hcHBseUNoYWluLnRoZW4oJCwkKTtyZXR1cm4gdGhpcy5hcHBseUNoYWluPUoudGhlbigoKT0+e3JldHVybn0sKCk9PntyZXR1cm59KSxKfWRyYWluQXBwbHlRdWV1ZSgpe3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5kb0RyYWluQXBwbHlRdWV1ZSgpKX1hc3luYyBkb0RyYWluQXBwbHlRdWV1ZSgpe2xldCAkPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdCh7YXBsZDpRJH0pO2lmKCQubGVuZ3RoPDEpcmV0dXJuW107bGV0IEo9SiQoJCwoWik9PlouaGVhZCk7cmV0dXJuIHRoaXMuYXBwbHlTdG9yZWQoSil9YXBwbHlIYXNoZXM9KCQpPT57cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvQXBwbHlIYXNoZXMoJCkpfTthc3luYyBkb0FwcGx5SGFzaGVzKCQpe2xldCBKPVtdO2ZvcihsZXQgWSBvZiAkKXtsZXQgVj1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmdldChZKTtpZihWKUoucHVzaChWKX1sZXQgWj1hd2FpdCB0aGlzLmFwcGx5U3RvcmVkKEopLFE9bmV3IE1hcDtmb3IobGV0IFk9MDtZPEoubGVuZ3RoO1krKylRLnNldChCKEpbWV0uaGFzaCksWltZXT8/MTIpO3JldHVybiAkLm1hcCgoWSk9PlEuZ2V0KEIoWSkpPz8xMyl9YXN5bmMgYXBwbHlTdG9yZWQoJCl7aWYoJC5sZW5ndGg8MSlyZXR1cm5bXTtsZXQgSj0kLm1hcCgoVik9Pih7Li4uVi5oZWFkLGJvZDpWLmJvZHl9KSksWj1hd2FpdCB0aGlzLnN0YXRlLmFwcGx5KEopLFE9W10sWT1bXTtmb3IobGV0IFY9MDtWPCQubGVuZ3RoO1YrKyl7bGV0IFg9WltWXTtpZihYPT09MHx8WD09PTE1KVEucHVzaCgkW1ZdLmhhc2gpO2Vsc2UgaWYoWCE9PXZvaWQgMCYmZVooWCkpWS5wdXNoKHtrZXk6JFtWXS5oYXNoLGVycjpYfSl9aWYoUS5sZW5ndGg+MClhd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLm1hcmtBcHBsaWVkKFEpO2lmKFkubGVuZ3RoPjApYXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5tYXJrRmFpbGVkKFkpO3JldHVybiBafWFzeW5jIGluc2VydFJhdygkKXtsZXR7Y2xvY2s6SixjcnlwdG86Wn09dGhpcyxbUSxZXT1hd2FpdCBoWih7bm93Okoubm93KCksYm9kOiQsY3J5cHRvOlp9KTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXQgWD0oYXdhaXQgdGhpcy5hcHBseShbe2hlYWQ6USxib2R5OiR9XSkpWzBdO2lmKFghPT0wJiZYIT09MTUpcmV0dXJuIEcoWD8/MTIpO3JldHVybiBPKFEpfWFzeW5jIG1ha2VVcGRhdGUoJCxKKXtsZXR7Y2xvY2s6WixjcnlwdG86UX09dGhpcyxZPVoubm93KCk7aWYoJC51cGRhdGVkQXQuZ2V0VGltZSgpPlkuZ2V0VGltZSgpKXJldHVybiBHKDQpO2xldCBWPSQuY3RyKzEsW1gsV109YXdhaXQgayQoe25vdzpZLGVpZDokLmVpZCxjdHI6Vixib2Q6SixjcnlwdG86UX0pO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBPKHtoZWFkOlgsYm9keTpKfSl9YXN5bmMgdXBkYXRlV2l0aFNrZXcoJCxKLFope2lmKFo9PT0hMSlyZXR1cm4gRyg0KTtsZXR7Y2xvY2s6USxjcnlwdG86WX09dGhpcyxWPVEubm93KCksWD1uZXcgbSgkLmVpZCksW1csel09WC5yZWFkU3RydWN0KFYwKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXQgSz0kLnVwZGF0ZWRBdC5nZXRUaW1lKCktVy50cy5nZXRUaW1lKCksRj17ZWlkOiQuZWlkLG9mZjpLKzEsY3RyOiQuY3RyKzEsbGVuOjB9LFU9KGF3YWl0IHRoaXMuYXBwbHkoW3toZWFkOkYsYm9keTp2b2lkIDB9XSkpWzBdO2lmKFUhPT0wJiZVIT09MTUpcmV0dXJuIEcoVT8/MTIpO2lmKEo9PT12b2lkIDApcmV0dXJuIE8oRik7bGV0W1IscV09QSQoe2lkOlcuaWQsdHM6Vn0pO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldFtILE1dPWF3YWl0IGskKHtub3c6VixlaWQ6UixjdHI6MCxib2Q6SixjcnlwdG86WX0pO2lmKE0hPT0wKXJldHVybiBHKE0pO2xldCBDPShhd2FpdCB0aGlzLmFwcGx5KFt7aGVhZDpILGJvZHk6Sn1dKSlbMF07aWYoQyE9PTAmJkMhPT0xNSlyZXR1cm4gRyhDPz8xMik7cmV0dXJuIE8oSCl9YXN5bmMgdXBkYXRlUmF3KCQsSixaPXRoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQpe2lmKCQudXBkYXRlZEF0LmdldFRpbWUoKT50aGlzLmNsb2NrLm5vdygpLmdldFRpbWUoKSlyZXR1cm4gdGhpcy51cGRhdGVXaXRoU2tldygkLEosWik7cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKGFzeW5jKCk9PntsZXRbUSxZXT1hd2FpdCB0aGlzLm1ha2VVcGRhdGUoJCxKKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXQgWD0oYXdhaXQgdGhpcy5kb0FwcGx5KFtRXSkpWzBdO2lmKFghPT0wJiZYIT09MTUpcmV0dXJuIEcoWD8/MTIpO3JldHVybiBPKFEuaGVhZCl9KX1hc3luYyBpbnNlcnQoJCl7bGV0e2JvZHk6Six0eXBlOlosZ2lkOlEscGlkOlksdGFnczpWfT0kLFc9RTAoe2JvZHk6Six0eXBlOlosZ2lkOlEscGlkOlksdGFnczpWfSk7cmV0dXJuIHRoaXMuaW5zZXJ0UmF3KFcpfWFzeW5jIHVwZGF0ZSgkKXtsZXR7cHJpb3I6Sixib2R5OlosdHlwZTpRLGdpZDpZLHBpZDpWLHRhZ3M6WCxmb3JjZTpXfT0kLEs9RTAoe2JvZHk6Wix0eXBlOlEsZ2lkOlkscGlkOlYsdGFnczpYfSk7cmV0dXJuIHRoaXMudXBkYXRlUmF3KEosSyxXPz90aGlzLmZvcmNlU2tld0hhbmRsaW5nQnlEZWZhdWx0KX1hc3luYyBkZWxldGUoJCl7bGV0IEo9JC5mb3JjZT8/ITA7aWYoInByaW9yImluICQpcmV0dXJuIHRoaXMudXBkYXRlUmF3KCQucHJpb3Isdm9pZCAwLEopO2xldFtaLFFdPWF3YWl0IHRoaXMucmV2RnJvbUFyY2hpdmUoJC5laWQpO2lmKFEhPT0wKXJldHVybiBHKFEpO3JldHVybiB0aGlzLnVwZGF0ZVJhdyhaLHZvaWQgMCxKKX1hc3luYyByZXZGcm9tQXJjaGl2ZSgkKXtsZXQgSj1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxhc3QoJCk7aWYoSilyZXR1cm4gclooSi5oZWFkKTtsZXQgWj1uZXcgbSgkKSxbUSxZXT1aLnJlYWRTdHJ1Y3QoVjApO2lmKFkhPT0wKXJldHVybiBHKFkpO3JldHVybiBPKHtlaWQ6JCxjdHI6LTEsdXBkYXRlZEF0OlEudHN9KX1hc3luYyBnZW5FSUQoJCl7bGV0e2Nsb2NrOkosY3J5cHRvOlp9PXRoaXMsUT1KLm5vdygpO2lmKCQhPT12b2lkIDApcmV0dXJuIEEkKHtpZDokLHRzOlF9KTtsZXQgWT1hd2FpdCBaLmdlblJhbmRvbUJ5dGVzKDgpO3JldHVybiBBJCh7aWQ6WSx0czpRfSl9c3luYygpe3JldHVybiB0aGlzLnN5bmNSdW5zLnJ1bigoKT0+dGhpcy5kb1N5bmMoKSl9YXN5bmMgZG9TeW5jKCl7bGV0e2Nvbm5lY3Rpb25zOiQsY3J5cHRvOkosc3RvcmU6Wn09dGhpcyxRPWF3YWl0IFouc2VlZC5sb2FkKCk7aWYoIVEpcmV0dXJuIDIyO2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCk7Zm9yKGxldFtZLFZdb2YgJCl7bGV0IFg9YXdhaXQgWi5ob3N0cy5nZXQoWSk7aWYoIVgpY29udGludWU7bGV0IFc9e2Nvbm46VixzdG9yZTpaLGVuY2xhdmU6USxob3N0OlgsY3J5cHRvOkosbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LHo9YXdhaXQgZkooVyk7aWYoeiE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwZWVrOiAke3p9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLHo7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBLPWF3YWl0IFlRKFcpO2lmKEshPT0wKXJldHVybiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcHVzaDogJHtLfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxLO3RoaXMueGZlclN0YXRlLmVtaXQoKTtsZXQgRj1hd2FpdCBnSihXLGFzeW5jKCk9Pnthd2FpdCB0aGlzLmRyYWluQXBwbHlRdWV1ZSgpfSk7aWYoRiE9PTAmJkYhPT0xNSlyZXR1cm4gY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHB1bGw6ICR7Rn1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRjt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHJlYnVpbGQoJCl7aWYodGhpcy5zY2hlZHVsZWRTeW5jLmNhbmNlbCgpLGF3YWl0IHRoaXMuc3luY1J1bnMuZmx1c2goKSwkPy5jaGVja0hvc3Q/PyEwKXtsZXQgWj1hd2FpdCB0aGlzLnJlcHVsbCgpO2lmKFohPT0wKXJldHVybiBafXJldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5yZXBsYXkoKSl9YXN5bmMgbXNnY2hlY2soKXtsZXQgJD1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3RLZXlzKCk7cmV0dXJuIE4kKCQsdGhpcy5jcnlwdG8pfWxpc3RNc2dzKCQpe3JldHVybiB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3QoJCl9Y291bnRNc2dzKCQpe3JldHVybiB0aGlzLnN0b3JlLm1lc3NhZ2VzLmNvdW50KCQpfWFzeW5jIHJlY29uY2lsZSgkLEope3RoaXMuc2NoZWR1bGVkU3luYy5jYW5jZWwoKSxhd2FpdCB0aGlzLnN5bmNSdW5zLmZsdXNoKCk7bGV0e2Nvbm5lY3Rpb25zOlosY3J5cHRvOlEsc3RvcmU6WX09dGhpcyxWPWF3YWl0IFkuc2VlZC5sb2FkKCk7aWYoIVYpcmV0dXJuIEcoMjIpO2xldCBYPWF3YWl0IFkuaG9zdHMuZ2V0KCQpO2lmKCFYKXJldHVybiBHKDEzKTtsZXQgVz1aLmdldCgkKTtpZighV3x8IVcuaXNDb25uZWN0ZWQoKSl7aWYoYXdhaXQgdGhpcy5jb25uZWN0VG9Ib3N0KFgsITEsITEpLFg9YXdhaXQgWS5ob3N0cy5nZXQoJCksIVgpcmV0dXJuIEcoMTMpO1c9Wi5nZXQoJCl9aWYoIVcpcmV0dXJuIEcoMTIpO2xldCB6PXtjb25uOlcsc3RvcmU6WSxlbmNsYXZlOlYsY3J5cHRvOlEsbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LFtLLEZdPWF3YWl0IG1KKHsuLi56LGhvc3Q6WH0sSik7aWYodGhpcy54ZmVyU3RhdGUuZW1pdCgpLEYhPT0wKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRyhGKTtpZighSylyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEcoMTIpO2lmKEo/LnN5bmM9PT0hMSlyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLE8oSyk7bGV0IE49YXdhaXQgdGhpcy5zeW5jKCk7aWYoTiE9PTApcmV0dXJuIEcoTik7bGV0IFU9YXdhaXQgWS5ob3N0cy5nZXQoJCk7aWYoIVUpcmV0dXJuIEcoMTMpO2xldFtSLHFdPWF3YWl0IG1KKHsuLi56LGhvc3Q6VX0se3B1bGw6ITEscHVzaDohMX0pO2lmKHRoaXMueGZlclN0YXRlLmVtaXQoKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSkscSE9PTApcmV0dXJuIEcocSk7aWYoIVIpcmV0dXJuIEcoMTIpO3JldHVybiBPKFIpfWFzeW5jIHJlcHVsbCgpe2xldHtjb25uZWN0aW9uczokLGNyeXB0bzpKLHN0b3JlOlp9PXRoaXMsUT1hd2FpdCBaLnNlZWQubG9hZCgpO2lmKCFRKXJldHVybiAyMjtsZXQgWT1BcnJheS5mcm9tKGF3YWl0IFouaG9zdHMubGlzdCgpKTtpZihZLmxlbmd0aDwxKXJldHVybiAwO2ZvcihsZXQgViBvZiBZKXtsZXQgWD0kLmdldChWLmxhYmVsKTtpZighWHx8IVguaXNDb25uZWN0ZWQoKSlhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QoViwhMSwhMSl9Zm9yKGxldFtWLFhdb2YgJCl7bGV0IFc9YXdhaXQgWi5ob3N0cy5nZXQoVik7aWYoIVcpY29udGludWU7bGV0IHo9e2Nvbm46WCxzdG9yZTpaLGVuY2xhdmU6USxob3N0OnsuLi5XLGxhc3RTZXE6MH0sY3J5cHRvOkosbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LEs9YXdhaXQgZkooeik7aWYoSyE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYHJlYnVpbGQ6IGZhaWxlZCB0byBwZWVrOiAke0t9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEs7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBGPWF3YWl0IGdKKHopO2lmKEYhPT0wJiZGIT09MTUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoYHJlYnVpbGQ6IGZhaWxlZCB0byBwdWxsOiAke0Z9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEY7dGhpcy54ZmVyU3RhdGUuZW1pdCgpfXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH1hc3luYyByZXBsYXkoKXtsZXQgJD1hd2FpdCB0aGlzLnN0YXRlLmNsZWFyKCk7aWYoJCE9PTApcmV0dXJuICQ7bGV0IEo9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0KCksWj1KJChKLChWKT0+Vi5oZWFkKSxRPVoubGVuZ3RoO2lmKFE8MSlyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDA7bGV0IFk9MDt3aGlsZShZPFoubGVuZ3RoKXtsZXQgVj0wLFg9MCxXPVk7Zm9yKGxldCBLPVk7SzxaLmxlbmd0aCYmWDwxMDAmJlY8MTAyNDAwO0srKylWKz1aW0tdLmhlYWQubGVuLFgrKyxXPUsrMTtsZXQgej1aLnNsaWNlKFksVyk7YXdhaXQgdGhpcy5hcHBseVN0b3JlZCh6KSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImV4ZWMiLGRvbmU6Vyx0b3RhbDpRfSksWT1XfXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH1hc3luYyB3aXBlKCQpe2xldCBKPSQ/Lm1zZ3MhPT0hMSxaPSQ/LmVudHMhPT0hMSxRPSQ/Lm1ldGEhPT0hMSxZPSQ/LnNlZWQ9PT0hMDt0aGlzLnNjaGVkdWxlZFN5bmMuY2FuY2VsKCksYXdhaXQgdGhpcy5kaXNjb25uZWN0KCksYXdhaXQgdGhpcy5zeW5jUnVucy5mbHVzaCgpO2xldHtzdG9yZTpWfT10aGlzO2lmKFEpYXdhaXQgVi5ob3N0cy53aXBlKCksYXdhaXQgVi51cGxvYWRzLndpcGUoKSxhd2FpdCBWLmRvd25sb2Fkcy53aXBlKCk7aWYoSilhd2FpdCBWLm1lc3NhZ2VzLndpcGUoKTtpZihZKWF3YWl0IFYuc2VlZC53aXBlKCk7aWYoWilhd2FpdCB0aGlzLnN0YXRlLmNsZWFyKCk7dGhpcy5sYXN0UHJvZ3Jlc3M9X0osdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksdGhpcy54ZmVyU3RhdGUuZW1pdCgpfWltcG9ydD1hc3luYygkLEopPT57bGV0e2NyeXB0bzpaLHN0b3JlOlF9PXRoaXMsWT1KPy5vblByb2dyZXNzLFY9YXdhaXQgUS5zZWVkLmxvYWQoKTtpZighVilyZXR1cm4gMjI7Y29uc29sZS50aW1lKCJpbXBvcnQ6IGRlY29kaW5nIGZpbGUuLi4iKTtsZXQgWD1hd2FpdCAkLmJ5dGVzKCksW1csel09YXdhaXQgYlooWCxaLFYpO2lmKHohPT0wKXJldHVybiB6O2NvbnNvbGUudGltZUVuZCgiaW1wb3J0OiBkZWNvZGluZyBmaWxlLi4uIik7bGV0IEs9MDt3aGlsZShLPFcubGVuZ3RoKXtsZXQgRj0wLE49MCxVPUs7Zm9yKGxldCBIPUs7SDxXLmxlbmd0aCYmTjwxMDAmJkY8MTAyNDAwO0grKylGKz1XW0hdLmhlYWQubGVuLE4rKyxVPUgrMTtsZXQgUj1XLnNsaWNlKEssVSk7Y29uc29sZS50aW1lKGBpbXBvcnQ6IGFwcGx5aW5nIFske0t9LCAke1V9XWApO2xldCBxPWF3YWl0IHRoaXMuYXBwbHkoUix7ZW5xdWV1ZVVwbG9hZDohMCx0cmlnZ2VyVXBsb2FkOiExfSk7Y29uc29sZS50aW1lRW5kKGBpbXBvcnQ6IGFwcGx5aW5nIFske0t9LCAke1V9XWApO2ZvcihsZXQgSD0wO0g8Ui5sZW5ndGg7SCsrKXtsZXQgTT1xW0hdO2lmKE0hPT0wJiZNIT09MTUpY29uc29sZS53YXJuKGBmYWlsZWQgdG8gaW1wb3J0IG1zZyAke0srSH06ICR7RFtNXX1gKX1pZihZKXF1ZXVlTWljcm90YXNrKCgpPT5ZKFUsVy5sZW5ndGgsMCkpO3RoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaW1wb3J0Iixkb25lOlUsdG90YWw6Vy5sZW5ndGh9KSxLPVV9cmV0dXJuIHRoaXMuc2NoZWR1bGVTeW5jKCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9O3NjaGVkdWxlU3luYz0oKT0+e2lmKHRoaXMub25TY2hlZHVsZVN5bmMpe3RoaXMub25TY2hlZHVsZVN5bmMoKTtyZXR1cm59dGhpcy5zY2hlZHVsZWRTeW5jLnNjaGVkdWxlKCl9O2FzeW5jIGV4cG9ydEJ5dGVzKCl7bGV0e2NyeXB0bzokLHN0b3JlOkp9PXRoaXMsWj1hd2FpdCBKLnNlZWQubG9hZCgpO2lmKCFaKXJldHVybiBHKDIyKTtsZXQgUT1hd2FpdCBKLm1lc3NhZ2VzLmxpc3QoKTtyZXR1cm4geVooImV4cG9ydCIsMCxRLCQsWil9YXN5bmMgZXhwb3J0KCQpe2xldFtKLFpdPWF3YWl0IHRoaXMuZXhwb3J0Qnl0ZXMoKTtpZihaIT09MClyZXR1cm4gWjtpZighSilyZXR1cm4gMTI7bGV0IFE9bmV3IEJsb2IoW0ouc2xpY2UoKV0pO3JldHVybiBzWihRLCQpLDB9YXN5bmMgbGluaygkLEo9ITApe2lmKGF3YWl0IHRoaXMuc3RvcmUuaG9zdHMuYWRkKCQpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLEope2xldCBaPWF3YWl0IHRoaXMuc3RvcmUuaG9zdHMuZ2V0KCQubGFiZWwpO2lmKFopYXdhaXQgdGhpcy5jb25uZWN0VG9Ib3N0KFopfX1hc3luYyB1bmxpbmsoJCl7YXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5kZWwoJCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9YXN5bmMgaG9zdHMoKXtyZXR1cm4gQXJyYXkuZnJvbShhd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmxpc3QoKSl9Y29ubmVjdFRvSG9zdD1hc3luYygkLEo9ITAsWj0hMCk9PntsZXR7Y2xvY2s6USxjb25uZWN0aW9uczpZLGNyeXB0bzpWLHN0b3JlOlgsdHJhbnNwb3J0Old9PXRoaXMsej1ZLmdldCgkLmxhYmVsKTtpZih6KXtpZih6LmlzQ29ubmVjdGVkKCkpcmV0dXJuO3RyeXt6LmNsb3NlTGlzdGVuZXIoKX1jYXRjaHt9WS5kZWxldGUoJC5sYWJlbCl9bGV0IEs9YXdhaXQgWC5zZWVkLmxvYWQoKTtpZighSylyZXR1cm47Y29uc29sZS5pbmZvKGBDb25uZWN0aW5nIHRvICR7JC5oYW5kbGV9ICgkeyQubGFiZWx9KWApO2xldCBGPW5ldyBCJChLLFYsJCxRLFcoJCksKE4pPT5YLmhvc3RzLnNldCgkLmxhYmVsLE4pKTtpZihhd2FpdCBGLnJlZ2lzdGVyKCksSilhd2FpdCBGLmxpc3Rlbihhc3luYyhOKT0+e2xldCBVPXtjb25uOkYsc3RvcmU6WCxlbmNsYXZlOkssaG9zdDokLGNyeXB0bzpWLG1heFB1c2hCeXRlczp0aGlzLm1heFB1c2hCeXRlcyxtYXhQdWxsQnl0ZXM6dGhpcy5tYXhQdWxsQnl0ZXMsb25Qcm9ncmVzczp0aGlzLmVtaXRQcm9ncmVzcyxwZWVrUHJvZ3Jlc3NFdmVyeTp0aGlzLnBlZWtQcm9ncmVzc0V2ZXJ5fTtyZXR1cm4gWFEoTixVLHRoaXMuc2NoZWR1bGVTeW5jKX0sKCk9PnRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLCgpPT50aGlzLmNsaWVudFN0YXRlLmVtaXQoKSk7aWYoWS5zZXQoJC5sYWJlbCxGKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKSxaKXRoaXMuc2NoZWR1bGVTeW5jKCl9O2FzeW5jIGNvbm5lY3QoJD0hMCxKPSEwKXtsZXR7Y29ubmVjdFRvSG9zdDpaLHNjaGVkdWxlU3luYzpRLHN0b3JlOll9PXRoaXM7aWYoIWF3YWl0IFkuc2VlZC5sb2FkKCkpcmV0dXJuO2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCk7bGV0IFg9YXdhaXQgWS5ob3N0cy5saXN0KCk7Zm9yKGxldCBXIG9mIFgpYXdhaXQgWihXLCQsITEpO2lmKEopUSgpfWRpc2Nvbm5lY3Q9YXN5bmMoKT0+e2ZvcihsZXQgJCBvZiB0aGlzLmNvbm5lY3Rpb25zLnZhbHVlcygpKXRyeXskLmNsb3NlTGlzdGVuZXIoKX1jYXRjaHt9dGhpcy5jb25uZWN0aW9ucy5jbGVhcigpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpfX12YXIgZzA9dHlwZW9mIGdsb2JhbFRoaXM9PT0ib2JqZWN0IiYmImNyeXB0byJpbiBnbG9iYWxUaGlzP2dsb2JhbFRoaXMuY3J5cHRvOnZvaWQgMDtmdW5jdGlvbiBoJCgkKXtpZighTnVtYmVyLmlzU2FmZUludGVnZXIoJCl8fCQ8MCl0aHJvdyBFcnJvcigicG9zaXRpdmUgaW50ZWdlciBleHBlY3RlZCwgZ290ICIrJCl9ZnVuY3Rpb24gdkooJCl7cmV0dXJuICQgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxBcnJheUJ1ZmZlci5pc1ZpZXcoJCkmJiQuY29uc3RydWN0b3IubmFtZT09PSJVaW50OEFycmF5In1mdW5jdGlvbiBvKCQsLi4uSil7aWYoIXZKKCQpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIik7aWYoSi5sZW5ndGg+MCYmIUouaW5jbHVkZXMoJC5sZW5ndGgpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIG9mIGxlbmd0aCAiK0orIiwgZ290IGxlbmd0aD0iKyQubGVuZ3RoKX1mdW5jdGlvbiB5SigkLEo9ITApe2lmKCQuZGVzdHJveWVkKXRocm93IEVycm9yKCJIYXNoIGluc3RhbmNlIGhhcyBiZWVuIGRlc3Ryb3llZCIpO2lmKEomJiQuZmluaXNoZWQpdGhyb3cgRXJyb3IoIkhhc2gjZGlnZXN0KCkgaGFzIGFscmVhZHkgYmVlbiBjYWxsZWQiKX1mdW5jdGlvbiBXUSgkLEope28oJCk7bGV0IFo9Si5vdXRwdXRMZW47aWYoJC5sZW5ndGg8Wil0aHJvdyBFcnJvcigiZGlnZXN0SW50bygpIGV4cGVjdHMgb3V0cHV0IGJ1ZmZlciBvZiBsZW5ndGggYXQgbGVhc3QgIitaKX1mdW5jdGlvbiBiSigkKXtpZih0eXBlb2YgJCE9PSJib29sZWFuIil0aHJvdyBFcnJvcihgYm9vbGVhbiBleHBlY3RlZCwgbm90ICR7JH1gKX0vKiEgbm9ibGUtY2lwaGVycyAtIE1JVCBMaWNlbnNlIChjKSAyMDIzIFBhdWwgTWlsbGVyIChwYXVsbWlsbHIuY29tKSAqL3ZhciBDMD0oJCk9Pm5ldyBVaW50MzJBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsTWF0aC5mbG9vcigkLmJ5dGVMZW5ndGgvNCkpO3ZhciBvWT1uZXcgVWludDhBcnJheShuZXcgVWludDMyQXJyYXkoWzI4NzQ1NDAyMF0pLmJ1ZmZlcilbMF09PT02ODtpZighb1kpdGhyb3cgRXJyb3IoIk5vbiBsaXR0bGUtZW5kaWFuIGhhcmR3YXJlIGlzIG5vdCBzdXBwb3J0ZWQiKTtmdW5jdGlvbiBhWSgkKXtpZih0eXBlb2YgJCE9PSJzdHJpbmciKXRocm93IEVycm9yKCJzdHJpbmcgZXhwZWN0ZWQiKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkobmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpKX1mdW5jdGlvbiBpJCgkKXtpZih0eXBlb2YgJD09PSJzdHJpbmciKSQ9YVkoJCk7ZWxzZSBpZih2SigkKSkkPWwkKCQpO2Vsc2UgdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQsIGdvdCAiK3R5cGVvZiAkKTtyZXR1cm4gJH1mdW5jdGlvbiBHUSgkLEope2lmKEo9PW51bGx8fHR5cGVvZiBKIT09Im9iamVjdCIpdGhyb3cgRXJyb3IoIm9wdGlvbnMgbXVzdCBiZSBkZWZpbmVkIik7cmV0dXJuIE9iamVjdC5hc3NpZ24oJCxKKX1mdW5jdGlvbiB6USgkLEope2lmKCQubGVuZ3RoIT09Si5sZW5ndGgpcmV0dXJuITE7bGV0IFo9MDtmb3IobGV0IFE9MDtRPCQubGVuZ3RoO1ErKylafD0kW1FdXkpbUV07cmV0dXJuIFo9PT0wfXZhciBLUT0oJCxKKT0+e2Z1bmN0aW9uIFooUSwuLi5ZKXtpZihvKFEpLCQubm9uY2VMZW5ndGghPT12b2lkIDApe2xldCBGPVlbMF07aWYoIUYpdGhyb3cgRXJyb3IoIm5vbmNlIC8gaXYgcmVxdWlyZWQiKTtpZigkLnZhclNpemVOb25jZSlvKEYpO2Vsc2UgbyhGLCQubm9uY2VMZW5ndGgpfWxldCBWPSQudGFnTGVuZ3RoO2lmKFYmJllbMV0hPT12b2lkIDApbyhZWzFdKTtsZXQgWD1KKFEsLi4uWSksVz0oRixOKT0+e2lmKE4hPT12b2lkIDApe2lmKEYhPT0yKXRocm93IEVycm9yKCJjaXBoZXIgb3V0cHV0IG5vdCBzdXBwb3J0ZWQiKTtvKE4pfX0sej0hMTtyZXR1cm57ZW5jcnlwdChGLE4pe2lmKHopdGhyb3cgRXJyb3IoImNhbm5vdCBlbmNyeXB0KCkgdHdpY2Ugd2l0aCBzYW1lIGtleSArIG5vbmNlIik7cmV0dXJuIHo9ITAsbyhGKSxXKFguZW5jcnlwdC5sZW5ndGgsTiksWC5lbmNyeXB0KEYsTil9LGRlY3J5cHQoRixOKXtpZihvKEYpLFYmJkYubGVuZ3RoPFYpdGhyb3cgRXJyb3IoImludmFsaWQgY2lwaGVydGV4dCBsZW5ndGg6IHNtYWxsZXIgdGhhbiB0YWdMZW5ndGg9IitWKTtyZXR1cm4gVyhYLmRlY3J5cHQubGVuZ3RoLE4pLFguZGVjcnlwdChGLE4pfX19cmV0dXJuIE9iamVjdC5hc3NpZ24oWiwkKSxafTtmdW5jdGlvbiBoSigkLEosWj0hMCl7aWYoSj09PXZvaWQgMClyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJCk7aWYoSi5sZW5ndGghPT0kKXRocm93IEVycm9yKCJpbnZhbGlkIG91dHB1dCBsZW5ndGgsIGV4cGVjdGVkICIrJCsiLCBnb3Q6ICIrSi5sZW5ndGgpO2lmKFomJiFzWShKKSl0aHJvdyBFcnJvcigiaW52YWxpZCBvdXRwdXQsIG11c3QgYmUgYWxpZ25lZCIpO3JldHVybiBKfWZ1bmN0aW9uIHNZKCQpe3JldHVybiAkLmJ5dGVPZmZzZXQlND09PTB9ZnVuY3Rpb24gbCQoJCl7cmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX1mdW5jdGlvbiBxMCguLi4kKXtmb3IobGV0IEo9MDtKPCQubGVuZ3RoO0orKykkW0pdLmZpbGwoMCl9ZnVuY3Rpb24gVSQoJD0zMil7aWYoZzAmJnR5cGVvZiBnMC5nZXRSYW5kb21WYWx1ZXM9PT0iZnVuY3Rpb24iKXJldHVybiBnMC5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQ4QXJyYXkoJCkpO2lmKGcwJiZ0eXBlb2YgZzAucmFuZG9tQnl0ZXM9PT0iZnVuY3Rpb24iKXJldHVybiBnMC5yYW5kb21CeXRlcygkKTt0aHJvdyBFcnJvcigiY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBtdXN0IGJlIGRlZmluZWQiKX12YXIgTlE9KCQpPT5VaW50OEFycmF5LmZyb20oJC5zcGxpdCgiIikubWFwKChKKT0+Si5jaGFyQ29kZUF0KDApKSksdFk9TlEoImV4cGFuZCAxNi1ieXRlIGsiKSxlWT1OUSgiZXhwYW5kIDMyLWJ5dGUgayIpLCRWPUMwKHRZKSxKVj1DMChlWSk7ZnVuY3Rpb24gaigkLEope3JldHVybiAkPDxKfCQ+Pj4zMi1KfWZ1bmN0aW9uIGlKKCQpe3JldHVybiAkLmJ5dGVPZmZzZXQlND09PTB9dmFyIHUkPTY0LFpWPTE2LE9RPTQyOTQ5NjcyOTUsRlE9bmV3IFVpbnQzMkFycmF5O2Z1bmN0aW9uIFFWKCQsSixaLFEsWSxWLFgsVyl7bGV0IHo9WS5sZW5ndGgsSz1uZXcgVWludDhBcnJheSh1JCksRj1DMChLKSxOPWlKKFkpJiZpSihWKSxVPU4/QzAoWSk6RlEsUj1OP0MwKFYpOkZRO2ZvcihsZXQgcT0wO3E8ejtYKyspe2lmKCQoSixaLFEsRixYLFcpLFg+PU9RKXRocm93IEVycm9yKCJhcng6IGNvdW50ZXIgb3ZlcmZsb3ciKTtsZXQgSD1NYXRoLm1pbih1JCx6LXEpO2lmKE4mJkg9PT11JCl7bGV0IE09cS80O2lmKHElNCE9PTApdGhyb3cgRXJyb3IoImFyeDogaW52YWxpZCBibG9jayBwb3NpdGlvbiIpO2ZvcihsZXQgUD0wLEM7UDxaVjtQKyspQz1NK1AsUltDXT1VW0NdXkZbUF07cSs9dSQ7Y29udGludWV9Zm9yKGxldCBNPTAsUDtNPEg7TSsrKVA9cStNLFZbUF09WVtQXV5LW01dO3ErPUh9fWZ1bmN0aW9uIFVRKCQsSil7bGV0e2FsbG93U2hvcnRLZXlzOlosZXh0ZW5kTm9uY2VGbjpRLGNvdW50ZXJMZW5ndGg6WSxjb3VudGVyUmlnaHQ6Vixyb3VuZHM6WH09R1Eoe2FsbG93U2hvcnRLZXlzOiExLGNvdW50ZXJMZW5ndGg6OCxjb3VudGVyUmlnaHQ6ITEscm91bmRzOjIwfSxKKTtpZih0eXBlb2YgJCE9PSJmdW5jdGlvbiIpdGhyb3cgRXJyb3IoImNvcmUgbXVzdCBiZSBhIGZ1bmN0aW9uIik7cmV0dXJuIGgkKFkpLGgkKFgpLGJKKFYpLGJKKFopLChXLHosSyxGLE49MCk9PntvKFcpLG8oeiksbyhLKTtsZXQgVT1LLmxlbmd0aDtpZihGPT09dm9pZCAwKUY9bmV3IFVpbnQ4QXJyYXkoVSk7aWYobyhGKSxoJChOKSxOPDB8fE4+PU9RKXRocm93IEVycm9yKCJhcng6IGNvdW50ZXIgb3ZlcmZsb3ciKTtpZihGLmxlbmd0aDxVKXRocm93IEVycm9yKGBhcng6IG91dHB1dCAoJHtGLmxlbmd0aH0pIGlzIHNob3J0ZXIgdGhhbiBkYXRhICgke1V9KWApO2xldCBSPVtdLHE9Vy5sZW5ndGgsSCxNO2lmKHE9PT0zMilSLnB1c2goSD1sJChXKSksTT1KVjtlbHNlIGlmKHE9PT0xNiYmWilIPW5ldyBVaW50OEFycmF5KDMyKSxILnNldChXKSxILnNldChXLDE2KSxNPSRWLFIucHVzaChIKTtlbHNlIHRocm93IEVycm9yKGBhcng6IGludmFsaWQgMzItYnl0ZSBrZXksIGdvdCBsZW5ndGg9JHtxfWApO2lmKCFpSih6KSlSLnB1c2goej1sJCh6KSk7bGV0IFA9QzAoSCk7aWYoUSl7aWYoei5sZW5ndGghPT0yNCl0aHJvdyBFcnJvcigiYXJ4OiBleHRlbmRlZCBub25jZSBtdXN0IGJlIDI0IGJ5dGVzIik7UShNLFAsQzAoei5zdWJhcnJheSgwLDE2KSksUCksej16LnN1YmFycmF5KDE2KX1sZXQgQz0xNi1ZO2lmKEMhPT16Lmxlbmd0aCl0aHJvdyBFcnJvcihgYXJ4OiBub25jZSBtdXN0IGJlICR7Q30gb3IgMTYgYnl0ZXNgKTtpZihDIT09MTIpe2xldCBJPW5ldyBVaW50OEFycmF5KDEyKTtJLnNldCh6LFY/MDoxMi16Lmxlbmd0aCksej1JLFIucHVzaCh6KX1sZXQgVD1DMCh6KTtyZXR1cm4gUVYoJCxNLFAsVCxLLEYsTixYKSxxMCguLi5SKSxGfX12YXIgcz0oJCxKKT0+JFtKKytdJjI1NXwoJFtKKytdJjI1NSk8PDg7Y2xhc3MgUlF7Y29uc3RydWN0b3IoJCl7dGhpcy5ibG9ja0xlbj0xNix0aGlzLm91dHB1dExlbj0xNix0aGlzLmJ1ZmZlcj1uZXcgVWludDhBcnJheSgxNiksdGhpcy5yPW5ldyBVaW50MTZBcnJheSgxMCksdGhpcy5oPW5ldyBVaW50MTZBcnJheSgxMCksdGhpcy5wYWQ9bmV3IFVpbnQxNkFycmF5KDgpLHRoaXMucG9zPTAsdGhpcy5maW5pc2hlZD0hMSwkPWkkKCQpLG8oJCwzMik7bGV0IEo9cygkLDApLFo9cygkLDIpLFE9cygkLDQpLFk9cygkLDYpLFY9cygkLDgpLFg9cygkLDEwKSxXPXMoJCwxMiksej1zKCQsMTQpO3RoaXMuclswXT1KJjgxOTEsdGhpcy5yWzFdPShKPj4+MTN8Wjw8MykmODE5MSx0aGlzLnJbMl09KFo+Pj4xMHxRPDw2KSY3OTM5LHRoaXMuclszXT0oUT4+Pjd8WTw8OSkmODE5MSx0aGlzLnJbNF09KFk+Pj40fFY8PDEyKSYyNTUsdGhpcy5yWzVdPVY+Pj4xJjgxOTAsdGhpcy5yWzZdPShWPj4+MTR8WDw8MikmODE5MSx0aGlzLnJbN109KFg+Pj4xMXxXPDw1KSY4MDY1LHRoaXMucls4XT0oVz4+Pjh8ejw8OCkmODE5MSx0aGlzLnJbOV09ej4+PjUmMTI3O2ZvcihsZXQgSz0wO0s8ODtLKyspdGhpcy5wYWRbS109cygkLDE2KzIqSyl9cHJvY2VzcygkLEosWj0hMSl7bGV0IFE9Wj8wOjIwNDgse2g6WSxyOlZ9PXRoaXMsWD1WWzBdLFc9VlsxXSx6PVZbMl0sSz1WWzNdLEY9Vls0XSxOPVZbNV0sVT1WWzZdLFI9Vls3XSxxPVZbOF0sSD1WWzldLE09cygkLEorMCksUD1zKCQsSisyKSxDPXMoJCxKKzQpLFQ9cygkLEorNiksST1zKCQsSis4KSxBPXMoJCxKKzEwKSxMPXMoJCxKKzEyKSxnPXMoJCxKKzE0KSxmPVlbMF0rKE0mODE5MSksaz1ZWzFdKygoTT4+PjEzfFA8PDMpJjgxOTEpLHk9WVsyXSsoKFA+Pj4xMHxDPDw2KSY4MTkxKSxoPVlbM10rKChDPj4+N3xUPDw5KSY4MTkxKSx3PVlbNF0rKChUPj4+NHxJPDwxMikmODE5MSkscD1ZWzVdKyhJPj4+MSY4MTkxKSx4PVlbNl0rKChJPj4+MTR8QTw8MikmODE5MSksdj1ZWzddKygoQT4+PjExfEw8PDUpJjgxOTEpLEU9WVs4XSsoKEw+Pj44fGc8PDgpJjgxOTEpLGk9WVs5XSsoZz4+PjV8USksXz0wLGQ9XytmKlgrayooNSpIKSt5Kig1KnEpK2gqKDUqUikrdyooNSpVKTtfPWQ+Pj4xMyxkJj04MTkxLGQrPXAqKDUqTikreCooNSpGKSt2Kig1KkspK0UqKDUqeikraSooNSpXKSxfKz1kPj4+MTMsZCY9ODE5MTtsZXQgdD1fK2YqVytrKlgreSooNSpIKStoKig1KnEpK3cqKDUqUik7Xz10Pj4+MTMsdCY9ODE5MSx0Kz1wKig1KlUpK3gqKDUqTikrdiooNSpGKStFKig1KkspK2kqKDUqeiksXys9dD4+PjEzLHQmPTgxOTE7bGV0IFkwPV8rZip6K2sqVyt5KlgraCooNSpIKSt3Kig1KnEpO189WTA+Pj4xMyxZMCY9ODE5MSxZMCs9cCooNSpSKSt4Kig1KlUpK3YqKDUqTikrRSooNSpGKStpKig1KkspLF8rPVkwPj4+MTMsWTAmPTgxOTE7bGV0IGM9XytmKksrayp6K3kqVytoKlgrdyooNSpIKTtfPWM+Pj4xMyxjJj04MTkxLGMrPXAqKDUqcSkreCooNSpSKSt2Kig1KlUpK0UqKDUqTikraSooNSpGKSxfKz1jPj4+MTMsYyY9ODE5MTtsZXQgSTA9XytmKkYraypLK3kqeitoKlcrdypYO189STA+Pj4xMyxJMCY9ODE5MSxJMCs9cCooNSpIKSt4Kig1KnEpK3YqKDUqUikrRSooNSpVKStpKig1Kk4pLF8rPUkwPj4+MTMsSTAmPTgxOTE7bGV0IHUwPV8rZipOK2sqRit5KksraCp6K3cqVztfPXUwPj4+MTMsdTAmPTgxOTEsdTArPXAqWCt4Kig1KkgpK3YqKDUqcSkrRSooNSpSKStpKig1KlUpLF8rPXUwPj4+MTMsdTAmPTgxOTE7bGV0IHAwPV8rZipVK2sqTit5KkYraCpLK3cqejtfPXAwPj4+MTMscDAmPTgxOTEscDArPXAqVyt4KlgrdiooNSpIKStFKig1KnEpK2kqKDUqUiksXys9cDA+Pj4xMyxwMCY9ODE5MTtsZXQgYzA9XytmKlIraypVK3kqTitoKkYrdypLO189YzA+Pj4xMyxjMCY9ODE5MSxjMCs9cCp6K3gqVyt2KlgrRSooNSpIKStpKig1KnEpLF8rPWMwPj4+MTMsYzAmPTgxOTE7bGV0IG4wPV8rZipxK2sqUit5KlUraCpOK3cqRjtfPW4wPj4+MTMsbjAmPTgxOTEsbjArPXAqSyt4KnordipXK0UqWCtpKig1KkgpLF8rPW4wPj4+MTMsbjAmPTgxOTE7bGV0IGQwPV8rZipIK2sqcSt5KlIraCpVK3cqTjtfPWQwPj4+MTMsZDAmPTgxOTEsZDArPXAqRit4Kksrdip6K0UqVytpKlgsXys9ZDA+Pj4xMyxkMCY9ODE5MSxfPShfPDwyKStffDAsXz1fK2R8MCxkPV8mODE5MSxfPV8+Pj4xMyx0Kz1fLFlbMF09ZCxZWzFdPXQsWVsyXT1ZMCxZWzNdPWMsWVs0XT1JMCxZWzVdPXUwLFlbNl09cDAsWVs3XT1jMCxZWzhdPW4wLFlbOV09ZDB9ZmluYWxpemUoKXtsZXR7aDokLHBhZDpKfT10aGlzLFo9bmV3IFVpbnQxNkFycmF5KDEwKSxRPSRbMV0+Pj4xMzskWzFdJj04MTkxO2ZvcihsZXQgWD0yO1g8MTA7WCsrKSRbWF0rPVEsUT0kW1hdPj4+MTMsJFtYXSY9ODE5MTskWzBdKz1RKjUsUT0kWzBdPj4+MTMsJFswXSY9ODE5MSwkWzFdKz1RLFE9JFsxXT4+PjEzLCRbMV0mPTgxOTEsJFsyXSs9USxaWzBdPSRbMF0rNSxRPVpbMF0+Pj4xMyxaWzBdJj04MTkxO2ZvcihsZXQgWD0xO1g8MTA7WCsrKVpbWF09JFtYXStRLFE9WltYXT4+PjEzLFpbWF0mPTgxOTE7Wls5XS09ODE5MjtsZXQgWT0oUV4xKS0xO2ZvcihsZXQgWD0wO1g8MTA7WCsrKVpbWF0mPVk7WT1+WTtmb3IobGV0IFg9MDtYPDEwO1grKykkW1hdPSRbWF0mWXxaW1hdOyRbMF09KCRbMF18JFsxXTw8MTMpJjY1NTM1LCRbMV09KCRbMV0+Pj4zfCRbMl08PDEwKSY2NTUzNSwkWzJdPSgkWzJdPj4+NnwkWzNdPDw3KSY2NTUzNSwkWzNdPSgkWzNdPj4+OXwkWzRdPDw0KSY2NTUzNSwkWzRdPSgkWzRdPj4+MTJ8JFs1XTw8MXwkWzZdPDwxNCkmNjU1MzUsJFs1XT0oJFs2XT4+PjJ8JFs3XTw8MTEpJjY1NTM1LCRbNl09KCRbN10+Pj41fCRbOF08PDgpJjY1NTM1LCRbN109KCRbOF0+Pj44fCRbOV08PDUpJjY1NTM1O2xldCBWPSRbMF0rSlswXTskWzBdPVYmNjU1MzU7Zm9yKGxldCBYPTE7WDw4O1grKylWPSgkW1hdK0pbWF18MCkrKFY+Pj4xNil8MCwkW1hdPVYmNjU1MzU7cTAoWil9dXBkYXRlKCQpe3lKKHRoaXMpO2xldHtidWZmZXI6SixibG9ja0xlbjpafT10aGlzOyQ9aSQoJCk7bGV0IFE9JC5sZW5ndGg7Zm9yKGxldCBZPTA7WTxROyl7bGV0IFY9TWF0aC5taW4oWi10aGlzLnBvcyxRLVkpO2lmKFY9PT1aKXtmb3IoO1o8PVEtWTtZKz1aKXRoaXMucHJvY2VzcygkLFkpO2NvbnRpbnVlfWlmKEouc2V0KCQuc3ViYXJyYXkoWSxZK1YpLHRoaXMucG9zKSx0aGlzLnBvcys9VixZKz1WLHRoaXMucG9zPT09Wil0aGlzLnByb2Nlc3MoSiwwLCExKSx0aGlzLnBvcz0wfXJldHVybiB0aGlzfWRlc3Ryb3koKXtxMCh0aGlzLmgsdGhpcy5yLHRoaXMuYnVmZmVyLHRoaXMucGFkKX1kaWdlc3RJbnRvKCQpe3lKKHRoaXMpLFdRKCQsdGhpcyksdGhpcy5maW5pc2hlZD0hMDtsZXR7YnVmZmVyOkosaDpafT10aGlzLHtwb3M6UX09dGhpcztpZihRKXtKW1ErK109MTtmb3IoO1E8MTY7USsrKUpbUV09MDt0aGlzLnByb2Nlc3MoSiwwLCEwKX10aGlzLmZpbmFsaXplKCk7bGV0IFk9MDtmb3IobGV0IFY9MDtWPDg7VisrKSRbWSsrXT1aW1ZdPj4+MCwkW1krK109WltWXT4+Pjg7cmV0dXJuICR9ZGlnZXN0KCl7bGV0e2J1ZmZlcjokLG91dHB1dExlbjpKfT10aGlzO3RoaXMuZGlnZXN0SW50bygkKTtsZXQgWj0kLnNsaWNlKDAsSik7cmV0dXJuIHRoaXMuZGVzdHJveSgpLFp9fWZ1bmN0aW9uIFlWKCQpe2xldCBKPShRLFkpPT4kKFkpLnVwZGF0ZShpJChRKSkuZGlnZXN0KCksWj0kKG5ldyBVaW50OEFycmF5KDMyKSk7cmV0dXJuIEoub3V0cHV0TGVuPVoub3V0cHV0TGVuLEouYmxvY2tMZW49Wi5ibG9ja0xlbixKLmNyZWF0ZT0oUSk9PiQoUSksSn12YXIgbEo9WVYoKCQpPT5uZXcgUlEoJCkpO2Z1bmN0aW9uIFZWKCQsSixaLFEsWSxWPTIwKXtsZXQgWD0kWzBdLFc9SlswXSx6PUpbMV0sSz1KWzJdLEY9SlszXSxOPSRbMV0sVT1aWzBdLFI9WlsxXSxxPVksSD0wLE09JFsyXSxQPUpbNF0sQz1KWzVdLFQ9Sls2XSxJPUpbN10sQT0kWzNdLEw9WCxnPVcsZj16LGs9Syx5PUYsaD1OLHc9VSxwPVIseD1xLHY9SCxFPU0saT1QLF89QyxkPVQsdD1JLFkwPUE7Zm9yKGxldCBJMD0wO0kwPFY7STArPTIpeV49aihMK198MCw3KSx4Xj1qKHkrTHwwLDkpLF9ePWooeCt5fDAsMTMpLExePWooXyt4fDAsMTgpLHZePWooaCtnfDAsNyksZF49aih2K2h8MCw5KSxnXj1qKGQrdnwwLDEzKSxoXj1qKGcrZHwwLDE4KSx0Xj1qKEUrd3wwLDcpLGZePWoodCtFfDAsOSksd149aihmK3R8MCwxMyksRV49aih3K2Z8MCwxOCksa149aihZMCtpfDAsNykscF49aihrK1kwfDAsOSksaV49aihwK2t8MCwxMyksWTBePWooaStwfDAsMTgpLGdePWooTCtrfDAsNyksZl49aihnK0x8MCw5KSxrXj1qKGYrZ3wwLDEzKSxMXj1qKGsrZnwwLDE4KSx3Xj1qKGgreXwwLDcpLHBePWoodytofDAsOSkseV49aihwK3d8MCwxMyksaF49aih5K3B8MCwxOCksaV49aihFK3Z8MCw3KSx4Xj1qKGkrRXwwLDkpLHZePWooeCtpfDAsMTMpLEVePWoodit4fDAsMTgpLF9ePWooWTArdHwwLDcpLGRePWooXytZMHwwLDkpLHRePWooZCtffDAsMTMpLFkwXj1qKHQrZHwwLDE4KTtsZXQgYz0wO1FbYysrXT1YK0x8MCxRW2MrK109VytnfDAsUVtjKytdPXorZnwwLFFbYysrXT1LK2t8MCxRW2MrK109Rit5fDAsUVtjKytdPU4raHwwLFFbYysrXT1VK3d8MCxRW2MrK109UitwfDAsUVtjKytdPXEreHwwLFFbYysrXT1IK3Z8MCxRW2MrK109TStFfDAsUVtjKytdPVAraXwwLFFbYysrXT1DK198MCxRW2MrK109VCtkfDAsUVtjKytdPUkrdHwwLFFbYysrXT1BK1kwfDB9ZnVuY3Rpb24gWFYoJCxKLFosUSl7bGV0IFk9JFswXSxWPUpbMF0sWD1KWzFdLFc9SlsyXSx6PUpbM10sSz0kWzFdLEY9WlswXSxOPVpbMV0sVT1aWzJdLFI9WlszXSxxPSRbMl0sSD1KWzRdLE09Sls1XSxQPUpbNl0sQz1KWzddLFQ9JFszXTtmb3IobGV0IEE9MDtBPDIwO0ErPTIpel49aihZK018MCw3KSxVXj1qKHorWXwwLDkpLE1ePWooVSt6fDAsMTMpLFlePWooTStVfDAsMTgpLFJePWooSytWfDAsNyksUF49aihSK0t8MCw5KSxWXj1qKFArUnwwLDEzKSxLXj1qKFYrUHwwLDE4KSxDXj1qKHErRnwwLDcpLFhePWooQytxfDAsOSksRl49aihYK0N8MCwxMykscV49aihGK1h8MCwxOCksV149aihUK0h8MCw3KSxOXj1qKFcrVHwwLDkpLEhePWooTitXfDAsMTMpLFRePWooSCtOfDAsMTgpLFZePWooWStXfDAsNyksWF49aihWK1l8MCw5KSxXXj1qKFgrVnwwLDEzKSxZXj1qKFcrWHwwLDE4KSxGXj1qKEsrenwwLDcpLE5ePWooRitLfDAsOSksel49aihOK0Z8MCwxMyksS149aih6K058MCwxOCksSF49aihxK1J8MCw3KSxVXj1qKEgrcXwwLDkpLFJePWooVStIfDAsMTMpLHFePWooUitVfDAsMTgpLE1ePWooVCtDfDAsNyksUF49aihNK1R8MCw5KSxDXj1qKFArTXwwLDEzKSxUXj1qKEMrUHwwLDE4KTtsZXQgST0wO1FbSSsrXT1ZLFFbSSsrXT1LLFFbSSsrXT1xLFFbSSsrXT1ULFFbSSsrXT1GLFFbSSsrXT1OLFFbSSsrXT1VLFFbSSsrXT1SfXZhciB1Sj1VUShWVix7Y291bnRlclJpZ2h0OiEwLGV4dGVuZE5vbmNlRm46WFZ9KSxwSj1LUSh7YmxvY2tTaXplOjY0LG5vbmNlTGVuZ3RoOjI0LHRhZ0xlbmd0aDoxNn0sKCQsSik9PntyZXR1cm57ZW5jcnlwdChaLFEpe1E9aEooWi5sZW5ndGgrMzIsUSwhMSk7bGV0IFk9US5zdWJhcnJheSgwLDMyKSxWPVEuc3ViYXJyYXkoMzIpO1Euc2V0KFosMzIpLHEwKFkpLHVKKCQsSixRLFEpO2xldCBYPWxKKFYsWSk7cmV0dXJuIFEuc2V0KFgsMTYpLHEwKFEuc3ViYXJyYXkoMCwxNiksWCksUS5zdWJhcnJheSgxNil9LGRlY3J5cHQoWixRKXtvKFopLFE9aEooWi5sZW5ndGgrMzIsUSwhMSk7bGV0IFk9US5zdWJhcnJheSgwLDMyKSxWPVEuc3ViYXJyYXkoMzIsNDgpLFg9US5zdWJhcnJheSg0OCk7US5zZXQoWiwzMikscTAoWSk7bGV0IFc9dUooJCxKLFksWSksej1sSihYLFcpO2lmKCF6UShWLHopKXRocm93IEVycm9yKCJpbnZhbGlkIHRhZyIpO3JldHVybiB1SigkLEosUS5zdWJhcnJheSgxNiksUS5zdWJhcnJheSgxNikpLHEwKFksVix6KSxYfX19KTsvKiEgbm9ibGUtaGFzaGVzIC0gTUlUIExpY2Vuc2UgKGMpIDIwMjIgUGF1bCBNaWxsZXIgKHBhdWxtaWxsci5jb20pICovZnVuY3Rpb24gV1YoJCl7cmV0dXJuICQgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxBcnJheUJ1ZmZlci5pc1ZpZXcoJCkmJiQuY29uc3RydWN0b3IubmFtZT09PSJVaW50OEFycmF5In1mdW5jdGlvbiBSJCgkKXtpZighTnVtYmVyLmlzU2FmZUludGVnZXIoJCl8fCQ8MCl0aHJvdyBFcnJvcigicG9zaXRpdmUgaW50ZWdlciBleHBlY3RlZCwgZ290ICIrJCl9ZnVuY3Rpb24gbTAoJCwuLi5KKXtpZighV1YoJCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQiKTtpZihKLmxlbmd0aD4wJiYhSi5pbmNsdWRlcygkLmxlbmd0aCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQgb2YgbGVuZ3RoICIrSisiLCBnb3QgbGVuZ3RoPSIrJC5sZW5ndGgpfWZ1bmN0aW9uIEgkKCQsSj0hMCl7aWYoJC5kZXN0cm95ZWQpdGhyb3cgRXJyb3IoIkhhc2ggaW5zdGFuY2UgaGFzIGJlZW4gZGVzdHJveWVkIik7aWYoSiYmJC5maW5pc2hlZCl0aHJvdyBFcnJvcigiSGFzaCNkaWdlc3QoKSBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZCIpfWZ1bmN0aW9uIHAkKCQsSil7bTAoJCk7bGV0IFo9Si5vdXRwdXRMZW47aWYoJC5sZW5ndGg8Wil0aHJvdyBFcnJvcigiZGlnZXN0SW50bygpIGV4cGVjdHMgb3V0cHV0IGJ1ZmZlciBvZiBsZW5ndGggYXQgbGVhc3QgIitaKX1mdW5jdGlvbiBIUSgkKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LCQuYnl0ZUxlbmd0aCl9ZnVuY3Rpb24gWSQoJCl7cmV0dXJuIG5ldyBVaW50MzJBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsTWF0aC5mbG9vcigkLmJ5dGVMZW5ndGgvNCkpfWZ1bmN0aW9uIFYkKC4uLiQpe2ZvcihsZXQgSj0wO0o8JC5sZW5ndGg7SisrKSRbSl0uZmlsbCgwKX1mdW5jdGlvbiBxJCgkLEope3JldHVybiAkPDwzMi1KfCQ+Pj5KfXZhciBxUT0oKCk9Pm5ldyBVaW50OEFycmF5KG5ldyBVaW50MzJBcnJheShbMjg3NDU0MDIwXSkuYnVmZmVyKVswXT09PTY4KSgpO2Z1bmN0aW9uIE1RKCQpe3JldHVybiAkPDwyNCY0Mjc4MTkwMDgwfCQ8PDgmMTY3MTE2ODB8JD4+PjgmNjUyODB8JD4+PjI0JjI1NX12YXIgSVE9cVE/KCQpPT4kOigkKT0+TVEoJCk7ZnVuY3Rpb24gR1YoJCl7Zm9yKGxldCBKPTA7SjwkLmxlbmd0aDtKKyspJFtKXT1NUSgkW0pdKTtyZXR1cm4gJH12YXIgSjA9cVE/KCQpPT4kOkdWO2Z1bmN0aW9uIHpWKCQpe2lmKHR5cGVvZiAkIT09InN0cmluZyIpdGhyb3cgRXJyb3IoInN0cmluZyBleHBlY3RlZCIpO3JldHVybiBuZXcgVWludDhBcnJheShuZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCkpfWZ1bmN0aW9uIFgkKCQpe2lmKHR5cGVvZiAkPT09InN0cmluZyIpJD16VigkKTtyZXR1cm4gbTAoJCksJH1jbGFzcyBjSnt9ZnVuY3Rpb24gQ1EoJCl7bGV0IEo9KFEsWSk9PiQoWSkudXBkYXRlKFgkKFEpKS5kaWdlc3QoKSxaPSQoe30pO3JldHVybiBKLm91dHB1dExlbj1aLm91dHB1dExlbixKLmJsb2NrTGVuPVouYmxvY2tMZW4sSi5jcmVhdGU9KFEpPT4kKFEpLEp9dmFyIFBRPVVpbnQzMkFycmF5LmZyb20oWzE3NzkwMzM3MDMsMzE0NDEzNDI3NywxMDEzOTA0MjQyLDI3NzM0ODA3NjIsMTM1OTg5MzExOSwyNjAwODIyOTI0LDUyODczNDYzNSwxNTQxNDU5MjI1XSk7dmFyIGMkPUJpZ0ludCg0Mjk0OTY3Mjk1KSx3UT1CaWdJbnQoMzIpO2Z1bmN0aW9uIG5KKCQsSj0hMSl7aWYoSilyZXR1cm57aDpOdW1iZXIoJCZjJCksbDpOdW1iZXIoJD4+d1EmYyQpfTtyZXR1cm57aDpOdW1iZXIoJD4+d1EmYyQpfDAsbDpOdW1iZXIoJCZjJCl8MH19ZnVuY3Rpb24gUDAoJCxKLFosUSxZKXtyZXR1cm4gJD0kK0orWXwwLFE9cSQoUV4kLDE2KSxaPVorUXwwLEo9cSQoSl5aLDEyKSx7YTokLGI6SixjOlosZDpRfX1mdW5jdGlvbiB3MCgkLEosWixRLFkpe3JldHVybiAkPSQrSitZfDAsUT1xJChRXiQsOCksWj1aK1F8MCxKPXEkKEpeWiw3KSx7YTokLGI6SixjOlosZDpRfX1jbGFzcyBkSiBleHRlbmRzIGNKe2NvbnN0cnVjdG9yKCQsSil7c3VwZXIoKTt0aGlzLmZpbmlzaGVkPSExLHRoaXMuZGVzdHJveWVkPSExLHRoaXMubGVuZ3RoPTAsdGhpcy5wb3M9MCxSJCgkKSxSJChKKSx0aGlzLmJsb2NrTGVuPSQsdGhpcy5vdXRwdXRMZW49Six0aGlzLmJ1ZmZlcj1uZXcgVWludDhBcnJheSgkKSx0aGlzLmJ1ZmZlcjMyPVkkKHRoaXMuYnVmZmVyKX11cGRhdGUoJCl7SCQodGhpcyksJD1YJCgkKSxtMCgkKTtsZXR7YmxvY2tMZW46SixidWZmZXI6WixidWZmZXIzMjpRfT10aGlzLFk9JC5sZW5ndGgsVj0kLmJ5dGVPZmZzZXQsWD0kLmJ1ZmZlcjtmb3IobGV0IFc9MDtXPFk7KXtpZih0aGlzLnBvcz09PUopSjAoUSksdGhpcy5jb21wcmVzcyhRLDAsITEpLEowKFEpLHRoaXMucG9zPTA7bGV0IHo9TWF0aC5taW4oSi10aGlzLnBvcyxZLVcpLEs9VitXO2lmKHo9PT1KJiYhKEslNCkmJlcrejxZKXtsZXQgRj1uZXcgVWludDMyQXJyYXkoWCxLLE1hdGguZmxvb3IoKFktVykvNCkpO0owKEYpO2ZvcihsZXQgTj0wO1crSjxZO04rPVEubGVuZ3RoLFcrPUopdGhpcy5sZW5ndGgrPUosdGhpcy5jb21wcmVzcyhGLE4sITEpO0owKEYpO2NvbnRpbnVlfVouc2V0KCQuc3ViYXJyYXkoVyxXK3opLHRoaXMucG9zKSx0aGlzLnBvcys9eix0aGlzLmxlbmd0aCs9eixXKz16fXJldHVybiB0aGlzfWRpZ2VzdEludG8oJCl7SCQodGhpcykscCQoJCx0aGlzKTtsZXR7cG9zOkosYnVmZmVyMzI6Wn09dGhpczt0aGlzLmZpbmlzaGVkPSEwLFYkKHRoaXMuYnVmZmVyLnN1YmFycmF5KEopKSxKMChaKSx0aGlzLmNvbXByZXNzKFosMCwhMCksSjAoWik7bGV0IFE9WSQoJCk7dGhpcy5nZXQoKS5mb3JFYWNoKChZLFYpPT5RW1ZdPUlRKFkpKX1kaWdlc3QoKXtsZXR7YnVmZmVyOiQsb3V0cHV0TGVuOkp9PXRoaXM7dGhpcy5kaWdlc3RJbnRvKCQpO2xldCBaPSQuc2xpY2UoMCxKKTtyZXR1cm4gdGhpcy5kZXN0cm95KCksWn1fY2xvbmVJbnRvKCQpe2xldHtidWZmZXI6SixsZW5ndGg6WixmaW5pc2hlZDpRLGRlc3Ryb3llZDpZLG91dHB1dExlbjpWLHBvczpYfT10aGlzO3JldHVybiAkfHwoJD1uZXcgdGhpcy5jb25zdHJ1Y3Rvcih7ZGtMZW46Vn0pKSwkLnNldCguLi50aGlzLmdldCgpKSwkLmJ1ZmZlci5zZXQoSiksJC5kZXN0cm95ZWQ9WSwkLmZpbmlzaGVkPVEsJC5sZW5ndGg9WiwkLnBvcz1YLCQub3V0cHV0TGVuPVYsJH1jbG9uZSgpe3JldHVybiB0aGlzLl9jbG9uZUludG8oKX19ZnVuY3Rpb24gckooJCxKLFosUSxZLFYsWCxXLHosSyxGLE4sVSxSLHEsSCxNLFAsQyxUKXtsZXQgST0wO2ZvcihsZXQgQT0wO0E8UTtBKyspKHthOlksYjp6LGM6VSxkOk19PVAwKFkseixVLE0sWltKKyRbSSsrXV0pKSx7YTpZLGI6eixjOlUsZDpNfT13MChZLHosVSxNLFpbSiskW0krK11dKSx7YTpWLGI6SyxjOlIsZDpQfT1QMChWLEssUixQLFpbSiskW0krK11dKSx7YTpWLGI6SyxjOlIsZDpQfT13MChWLEssUixQLFpbSiskW0krK11dKSx7YTpYLGI6RixjOnEsZDpDfT1QMChYLEYscSxDLFpbSiskW0krK11dKSx7YTpYLGI6RixjOnEsZDpDfT13MChYLEYscSxDLFpbSiskW0krK11dKSx7YTpXLGI6TixjOkgsZDpUfT1QMChXLE4sSCxULFpbSiskW0krK11dKSx7YTpXLGI6TixjOkgsZDpUfT13MChXLE4sSCxULFpbSiskW0krK11dKSx7YTpZLGI6SyxjOnEsZDpUfT1QMChZLEsscSxULFpbSiskW0krK11dKSx7YTpZLGI6SyxjOnEsZDpUfT13MChZLEsscSxULFpbSiskW0krK11dKSx7YTpWLGI6RixjOkgsZDpNfT1QMChWLEYsSCxNLFpbSiskW0krK11dKSx7YTpWLGI6RixjOkgsZDpNfT13MChWLEYsSCxNLFpbSiskW0krK11dKSx7YTpYLGI6TixjOlUsZDpQfT1QMChYLE4sVSxQLFpbSiskW0krK11dKSx7YTpYLGI6TixjOlUsZDpQfT13MChYLE4sVSxQLFpbSiskW0krK11dKSx7YTpXLGI6eixjOlIsZDpDfT1QMChXLHosUixDLFpbSiskW0krK11dKSx7YTpXLGI6eixjOlIsZDpDfT13MChXLHosUixDLFpbSiskW0krK11dKTtyZXR1cm57djA6WSx2MTpWLHYyOlgsdjM6Vyx2NDp6LHY1OkssdjY6Rix2NzpOLHY4OlUsdjk6Uix2MTA6cSx2MTE6SCx2MTI6TSx2MTM6UCx2MTQ6Qyx2MTU6VH19dmFyIE0wPXtDSFVOS19TVEFSVDoxLENIVU5LX0VORDoyLFBBUkVOVDo0LFJPT1Q6OCxLRVlFRF9IQVNIOjE2LERFUklWRV9LRVlfQ09OVEVYVDozMixERVJJVkVfS0VZX01BVEVSSUFMOjY0fSxUMD1QUS5zbGljZSgpLFRRPSgoKT0+e2xldCAkPUFycmF5LmZyb20oe2xlbmd0aDoxNn0sKFEsWSk9PlkpLEo9KFEpPT5bMiw2LDMsMTAsNywwLDQsMTMsMSwxMSwxMiw1LDksMTQsMTUsOF0ubWFwKChZKT0+UVtZXSksWj1bXTtmb3IobGV0IFE9MCxZPSQ7UTw3O1ErKyxZPUooWSkpWi5wdXNoKC4uLlkpO3JldHVybiBVaW50OEFycmF5LmZyb20oWil9KSgpO2NsYXNzIG9KIGV4dGVuZHMgZEp7Y29uc3RydWN0b3IoJD17fSxKPTApe3N1cGVyKDY0LCQuZGtMZW49PT12b2lkIDA/MzI6JC5ka0xlbik7dGhpcy5jaHVua1Bvcz0wLHRoaXMuY2h1bmtzRG9uZT0wLHRoaXMuZmxhZ3M9MCx0aGlzLnN0YWNrPVtdLHRoaXMucG9zT3V0PTAsdGhpcy5idWZmZXJPdXQzMj1uZXcgVWludDMyQXJyYXkoMTYpLHRoaXMuY2h1bmtPdXQ9MCx0aGlzLmVuYWJsZVhPRj0hMDtsZXR7a2V5OlosY29udGV4dDpRfT0kLFk9USE9PXZvaWQgMDtpZihaIT09dm9pZCAwKXtpZihZKXRocm93IEVycm9yKCdPbmx5ICJrZXkiIG9yICJjb250ZXh0IiBjYW4gYmUgc3BlY2lmaWVkIGF0IHNhbWUgdGltZScpO2xldCBWPVgkKFopLnNsaWNlKCk7bTAoViwzMiksdGhpcy5JVj1ZJChWKSxKMCh0aGlzLklWKSx0aGlzLmZsYWdzPUp8TTAuS0VZRURfSEFTSH1lbHNlIGlmKFkpe2xldCBWPVgkKFEpLFg9bmV3IG9KKHtka0xlbjozMn0sTTAuREVSSVZFX0tFWV9DT05URVhUKS51cGRhdGUoVikuZGlnZXN0KCk7dGhpcy5JVj1ZJChYKSxKMCh0aGlzLklWKSx0aGlzLmZsYWdzPUp8TTAuREVSSVZFX0tFWV9NQVRFUklBTH1lbHNlIHRoaXMuSVY9VDAuc2xpY2UoKSx0aGlzLmZsYWdzPUo7dGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCksdGhpcy5idWZmZXJPdXQ9SFEodGhpcy5idWZmZXJPdXQzMil9Z2V0KCl7cmV0dXJuW119c2V0KCl7fWIyQ29tcHJlc3MoJCxKLFosUT0wKXtsZXR7c3RhdGU6WSxwb3M6Vn09dGhpcyx7aDpYLGw6V309bkooQmlnSW50KCQpLCEwKSx7djA6eix2MTpLLHYyOkYsdjM6Tix2NDpVLHY1OlIsdjY6cSx2NzpILHY4Ok0sdjk6UCx2MTA6Qyx2MTE6VCx2MTI6SSx2MTM6QSx2MTQ6TCx2MTU6Z309ckooVFEsUSxaLDcsWVswXSxZWzFdLFlbMl0sWVszXSxZWzRdLFlbNV0sWVs2XSxZWzddLFQwWzBdLFQwWzFdLFQwWzJdLFQwWzNdLFgsVyxWLEopO1lbMF09el5NLFlbMV09S15QLFlbMl09Rl5DLFlbM109Tl5ULFlbNF09VV5JLFlbNV09Ul5BLFlbNl09cV5MLFlbN109SF5nfWNvbXByZXNzKCQsSj0wLFo9ITEpe2xldCBRPXRoaXMuZmxhZ3M7aWYoIXRoaXMuY2h1bmtQb3MpUXw9TTAuQ0hVTktfU1RBUlQ7aWYodGhpcy5jaHVua1Bvcz09PTE1fHxaKVF8PU0wLkNIVU5LX0VORDtpZighWil0aGlzLnBvcz10aGlzLmJsb2NrTGVuO2lmKHRoaXMuYjJDb21wcmVzcyh0aGlzLmNodW5rc0RvbmUsUSwkLEopLHRoaXMuY2h1bmtQb3MrPTEsdGhpcy5jaHVua1Bvcz09PTE2fHxaKXtsZXQgWT10aGlzLnN0YXRlO3RoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpO2ZvcihsZXQgVixYPXRoaXMuY2h1bmtzRG9uZSsxO1p8fCEoWCYxKTtYPj49MSl7aWYoIShWPXRoaXMuc3RhY2sucG9wKCkpKWJyZWFrO3RoaXMuYnVmZmVyMzIuc2V0KFYsMCksdGhpcy5idWZmZXIzMi5zZXQoWSw4KSx0aGlzLnBvcz10aGlzLmJsb2NrTGVuLHRoaXMuYjJDb21wcmVzcygwLHRoaXMuZmxhZ3N8TTAuUEFSRU5ULHRoaXMuYnVmZmVyMzIsMCksWT10aGlzLnN0YXRlLHRoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpfXRoaXMuY2h1bmtzRG9uZSsrLHRoaXMuY2h1bmtQb3M9MCx0aGlzLnN0YWNrLnB1c2goWSl9dGhpcy5wb3M9MH1fY2xvbmVJbnRvKCQpeyQ9c3VwZXIuX2Nsb25lSW50bygkKTtsZXR7SVY6SixmbGFnczpaLHN0YXRlOlEsY2h1bmtQb3M6WSxwb3NPdXQ6VixjaHVua091dDpYLHN0YWNrOlcsY2h1bmtzRG9uZTp6fT10aGlzO3JldHVybiAkLnN0YXRlLnNldChRLnNsaWNlKCkpLCQuc3RhY2s9Vy5tYXAoKEspPT5VaW50MzJBcnJheS5mcm9tKEspKSwkLklWLnNldChKKSwkLmZsYWdzPVosJC5jaHVua1Bvcz1ZLCQuY2h1bmtzRG9uZT16LCQucG9zT3V0PVYsJC5jaHVua091dD1YLCQuZW5hYmxlWE9GPXRoaXMuZW5hYmxlWE9GLCQuYnVmZmVyT3V0MzIuc2V0KHRoaXMuYnVmZmVyT3V0MzIpLCR9ZGVzdHJveSgpe3RoaXMuZGVzdHJveWVkPSEwLFYkKHRoaXMuc3RhdGUsdGhpcy5idWZmZXIzMix0aGlzLklWLHRoaXMuYnVmZmVyT3V0MzIpLFYkKC4uLnRoaXMuc3RhY2spfWIyQ29tcHJlc3NPdXQoKXtsZXR7c3RhdGU6JCxwb3M6SixmbGFnczpaLGJ1ZmZlcjMyOlEsYnVmZmVyT3V0MzI6WX09dGhpcyx7aDpWLGw6WH09bkooQmlnSW50KHRoaXMuY2h1bmtPdXQrKykpO0owKFEpO2xldHt2MDpXLHYxOnosdjI6Syx2MzpGLHY0Ok4sdjU6VSx2NjpSLHY3OnEsdjg6SCx2OTpNLHYxMDpQLHYxMTpDLHYxMjpULHYxMzpJLHYxNDpBLHYxNTpMfT1ySihUUSwwLFEsNywkWzBdLCRbMV0sJFsyXSwkWzNdLCRbNF0sJFs1XSwkWzZdLCRbN10sVDBbMF0sVDBbMV0sVDBbMl0sVDBbM10sWCxWLEosWik7WVswXT1XXkgsWVsxXT16Xk0sWVsyXT1LXlAsWVszXT1GXkMsWVs0XT1OXlQsWVs1XT1VXkksWVs2XT1SXkEsWVs3XT1xXkwsWVs4XT0kWzBdXkgsWVs5XT0kWzFdXk0sWVsxMF09JFsyXV5QLFlbMTFdPSRbM11eQyxZWzEyXT0kWzRdXlQsWVsxM109JFs1XV5JLFlbMTRdPSRbNl1eQSxZWzE1XT0kWzddXkwsSjAoUSksSjAoWSksdGhpcy5wb3NPdXQ9MH1maW5pc2goKXtpZih0aGlzLmZpbmlzaGVkKXJldHVybjt0aGlzLmZpbmlzaGVkPSEwLFYkKHRoaXMuYnVmZmVyLnN1YmFycmF5KHRoaXMucG9zKSk7bGV0ICQ9dGhpcy5mbGFnc3xNMC5ST09UO2lmKHRoaXMuc3RhY2subGVuZ3RoKSR8PU0wLlBBUkVOVCxKMCh0aGlzLmJ1ZmZlcjMyKSx0aGlzLmNvbXByZXNzKHRoaXMuYnVmZmVyMzIsMCwhMCksSjAodGhpcy5idWZmZXIzMiksdGhpcy5jaHVua3NEb25lPTAsdGhpcy5wb3M9dGhpcy5ibG9ja0xlbjtlbHNlICR8PSghdGhpcy5jaHVua1Bvcz9NMC5DSFVOS19TVEFSVDowKXxNMC5DSFVOS19FTkQ7dGhpcy5mbGFncz0kLHRoaXMuYjJDb21wcmVzc091dCgpfXdyaXRlSW50bygkKXtIJCh0aGlzLCExKSxtMCgkKSx0aGlzLmZpbmlzaCgpO2xldHtibG9ja0xlbjpKLGJ1ZmZlck91dDpafT10aGlzO2ZvcihsZXQgUT0wLFk9JC5sZW5ndGg7UTxZOyl7aWYodGhpcy5wb3NPdXQ+PUopdGhpcy5iMkNvbXByZXNzT3V0KCk7bGV0IFY9TWF0aC5taW4oSi10aGlzLnBvc091dCxZLVEpOyQuc2V0KFouc3ViYXJyYXkodGhpcy5wb3NPdXQsdGhpcy5wb3NPdXQrViksUSksdGhpcy5wb3NPdXQrPVYsUSs9Vn1yZXR1cm4gJH14b2ZJbnRvKCQpe2lmKCF0aGlzLmVuYWJsZVhPRil0aHJvdyBFcnJvcigiWE9GIGlzIG5vdCBwb3NzaWJsZSBhZnRlciBkaWdlc3QgY2FsbCIpO3JldHVybiB0aGlzLndyaXRlSW50bygkKX14b2YoJCl7cmV0dXJuIFIkKCQpLHRoaXMueG9mSW50byhuZXcgVWludDhBcnJheSgkKSl9ZGlnZXN0SW50bygkKXtpZihwJCgkLHRoaXMpLHRoaXMuZmluaXNoZWQpdGhyb3cgRXJyb3IoImRpZ2VzdCgpIHdhcyBhbHJlYWR5IGNhbGxlZCIpO3JldHVybiB0aGlzLmVuYWJsZVhPRj0hMSx0aGlzLndyaXRlSW50bygkKSx0aGlzLmRlc3Ryb3koKSwkfWRpZ2VzdCgpe3JldHVybiB0aGlzLmRpZ2VzdEludG8obmV3IFVpbnQ4QXJyYXkodGhpcy5vdXRwdXRMZW4pKX19dmFyIGpRPUNRKCgkKT0+bmV3IG9KKCQpKTt2YXIgS1Y9MzIsWUY9U3ltYm9sKCJYMjU1MTlTayIpO2Z1bmN0aW9uIERRKCQpe2lmKCQuYnl0ZUxlbmd0aCE9PUtWKXJldHVybiBHKDEwKTtyZXR1cm4gTygkKX12YXIgYj0oMW48PDI1NW4pLTE5bixGVj0xMjE2NjVuLEFRPW5ldyBVaW50OEFycmF5KDMyKTtBUVswXT05O2Z1bmN0aW9uIF9RKCQpe2xldCBKPTBuO2ZvcihsZXQgWj0kLmxlbmd0aC0xO1o+PTA7Wi0tKUo9Sjw8OG58QmlnSW50KCRbWl0pO3JldHVybiBKfWZ1bmN0aW9uIE5WKCQpe2xldCBKPW5ldyBVaW50OEFycmF5KDMyKSxaPSgkJWIrYiklYjtmb3IobGV0IFE9MDtRPDMyO1ErKylKW1FdPU51bWJlcihaJjB4ZmZuKSxaPj49OG47cmV0dXJuIEp9ZnVuY3Rpb24gT1YoJCl7bGV0IEo9JC5zbGljZSgpO3JldHVybiBKWzMxXSY9MTI3LF9RKEopfWZ1bmN0aW9uIFVWKCQpe2xldCBKPSQuc2xpY2UoKTtyZXR1cm4gSlswXSY9MjQ4LEpbMzFdJj0xMjcsSlszMV18PTY0LEp9ZnVuY3Rpb24gbiQoJCxKLFope2xldCBRPS0kLFk9KEpeWikmUTtyZXR1cm5bSl5ZLFpeWV19ZnVuY3Rpb24gUlYoJCl7bGV0IEo9Yi0ybixaPSgkJWIrYiklYixRPTFuO3doaWxlKEo+MG4pe2lmKEomMW4pUT1RKlolYjtaPVoqWiViLEo+Pj0xbn1yZXR1cm4gUX1mdW5jdGlvbiBIVigkLEope2xldCBaPVVWKCQpLFE9T1YoSiksWT0xbixWPTBuLFg9USxXPTFuLHo9MG4sSz1fUShaKTtmb3IobGV0IEY9MjU0O0Y+PTA7Ri0tKXtsZXQgTj1LPj5CaWdJbnQoRikmMW47el49TixbWSxYXT1uJCh6LFksWCksW1YsV109biQoeixWLFcpLHo9TjtsZXQgVT0oWStWKSViLFI9VSpVJWIscT0oWS1WK2IpJWIsSD1xKnElYixNPShSLUgrYiklYixQPShYK1cpJWIsVD0oWC1XK2IpJWIqVSViLEk9UCpxJWIsQT0oVCtJKSViLEw9KFQtSStiKSViO1g9QSpBJWIsVz1RKkwqTCViLFk9UipIJWIsVj1NKihSK0ZWKk0pJWJ9cmV0dXJuW1ksWF09biQoeixZLFgpLFtWLFddPW4kKHosVixXKSxaLmZpbGwoMCksTlYoWSpSVihWKSViKX1mdW5jdGlvbiBMUSgkKXtyZXR1cm4gSFYoJCxBUSl9dmFyIGFKPW5ldyBVaW50OEFycmF5KFs0OCw0NiwyLDEsMCw0OCw1LDYsMyw0MywxMDEsMTEyLDQsMzQsNCwzMl0pO2Z1bmN0aW9uIHhRKCQpe2xldCBKPW5ldyBVaW50OEFycmF5KGFKLmxlbmd0aCszMik7cmV0dXJuIEouc2V0KGFKKSxKLnNldCgkLnN1YmFycmF5KDAsMzIpLGFKLmxlbmd0aCksSn12YXIgc0o9bmV3IFVpbnQ4QXJyYXkoWzQ4LDQ2LDIsMSwwLDQ4LDUsNiwzLDQzLDEwMSwxMTAsNCwzNCw0LDMyXSk7ZnVuY3Rpb24gQlEoJCl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoc0oubGVuZ3RoKzMyKTtyZXR1cm4gSi5zZXQoc0opLEouc2V0KCQuc3ViYXJyYXkoMCwzMiksc0oubGVuZ3RoKSxKfWZ1bmN0aW9uIGtRKCQpe3JldHVybiB0eXBlb2YgJD09PSJzdHJpbmciP25ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKTokfWZ1bmN0aW9uIGowKCQpe2xldCBKPW5ldyBBcnJheUJ1ZmZlcigkLmJ5dGVMZW5ndGgpO3JldHVybiBuZXcgVWludDhBcnJheShKKS5zZXQoJCksSn1jbGFzcyBTMHt2ZXJpZnlLZXlzPW5ldyBNYXA7YXN5bmMgZ2VuUmFuZG9tQnl0ZXMoJCl7cmV0dXJuIFUkKCQpfWFzeW5jIGdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKXtyZXR1cm4gVSQoMzIpfWFzeW5jIGVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoJCxKKXtsZXQgWj1VJCgyNCksWT1wSihKLFopLmVuY3J5cHQoJCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KFsuLi5aLC4uLlldKX1hc3luYyBkZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKCQsSil7bGV0IFo9JC5zbGljZSgwLDI0KSxRPSQuc2xpY2UoMjQpO3JldHVybiBwSihKLFopLmRlY3J5cHQoUSl9YXN5bmMgZGVyaXZlRWQyNTUxOUtleVBhaXIoJCl7bGV0IEo9JCxaPXhRKEopLFE9ajAoWiksWTt0cnl7bGV0IEs9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLFEse25hbWU6IkVkMjU1MTkifSwhMCxbInNpZ24iXSk7WT1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCJqd2siLEspfWZpbmFsbHl7Wi5maWxsKDApLG5ldyBVaW50OEFycmF5KFEpLmZpbGwoMCl9aWYodHlwZW9mIFkueCE9PSJzdHJpbmciKXRocm93IEVycm9yKCJFZDI1NTE5IEpXSyBtaXNzaW5nIHgiKTtsZXQgVj1ZLng7WS5kPXZvaWQgMDtsZXQgWD1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJqd2siLHtrdHk6Ik9LUCIsY3J2OiJFZDI1NTE5Iix4OlZ9LHtuYW1lOiJFZDI1NTE5In0sITAsWyJ2ZXJpZnkiXSksVz1uZXcgVWludDhBcnJheShhd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuZXhwb3J0S2V5KCJyYXciLFgpKTt0aGlzLnZlcmlmeUtleXMuc2V0KFUwKFcpLFgpO2xldCB6PW5ldyBVaW50OEFycmF5KDY0KTtyZXR1cm4gei5zZXQoSiwwKSx6LnNldChXLDMyKSx7a2V5VHlwZToiZWQyNTUxOSIscHJpdmF0ZUtleTp6LHB1YmxpY0tleTpXfX1hc3luYyBpbXBvcnRTaWduS2V5KCQpe2xldCBKPSQuc3ViYXJyYXkoMCwzMiksWj14UShKKSxRPWowKFopO3RyeXtyZXR1cm4gYXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLFEse25hbWU6IkVkMjU1MTkifSwhMSxbInNpZ24iXSl9ZmluYWxseXtaLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoUSkuZmlsbCgwKX19YXN5bmMgaW1wb3J0VmVyaWZ5S2V5KCQpe2xldCBKPVUwKCQpLFo9dGhpcy52ZXJpZnlLZXlzLmdldChKKTtpZihaKXJldHVybiBaO2xldCBRPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInJhdyIsajAoJCkse25hbWU6IkVkMjU1MTkifSwhMSxbInZlcmlmeSJdKTtyZXR1cm4gdGhpcy52ZXJpZnlLZXlzLnNldChKLFEpLFF9YXN5bmMgc2lnbkVkMjU1MTkoJCxKKXtsZXQgWj1rUSgkKSxRPWF3YWl0IHRoaXMuaW1wb3J0U2lnbktleShKKSxZPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5zaWduKHtuYW1lOiJFZDI1NTE5In0sUSxqMChaKSk7cmV0dXJuIG5ldyBVaW50OEFycmF5KFkpfWFzeW5jIGNoZWNrU2lnRWQyNTUxOSgkLEosWil7bGV0IFE9a1EoSik7dHJ5e2xldCBZPWF3YWl0IHRoaXMuaW1wb3J0VmVyaWZ5S2V5KFopO3JldHVybiBhd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUudmVyaWZ5KHtuYW1lOiJFZDI1NTE5In0sWSxqMCgkKSxqMChRKSl9Y2F0Y2h7cmV0dXJuITF9fWFzeW5jIGJsYWtlMygkKXtyZXR1cm4galEoJCl9YXN5bmMgZ2VuWDI1NTE5KCl7bGV0ICQ9YXdhaXQgVSQoMzIpOyRbMF0mPTI0OCwkWzMxXSY9MTI3LCRbMzFdfD02NDtsZXRbSixaXT1EUSgkKTtpZihaIT09MHx8Sj09PXZvaWQgMCl0aHJvdyAkLmZpbGwoMCksRXJyb3IoIlgyNTUxOSBzY2FsYXIgYnJhbmQgZmFpbGVkIik7bGV0IFE9TFEoSiksWT1CUShKKSxWPWowKFkpO3RyeXtsZXQgWD1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsVix7bmFtZToiWDI1NTE5In0sITAsWyJkZXJpdmVCaXRzIl0pLFc9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgiandrIixYKTtpZih0eXBlb2YgVy54IT09InN0cmluZyIpdGhyb3cgRXJyb3IoIlgyNTUxOSBKV0sgbWlzc2luZyB4Iik7bGV0IHo9TFooVy54KTtpZihXLmQ9dm9pZCAwLCFyKHosUSkpdGhyb3cgRXJyb3IoIlgyNTUxOSBXZWJDcnlwdG8gcHViICE9IFJGQyA3NzQ4Iik7cmV0dXJue3ByaXY6SixwdWI6UX19Y2F0Y2goWCl7dGhyb3cgSi5maWxsKDApLFh9ZmluYWxseXtZLmZpbGwoMCksbmV3IFVpbnQ4QXJyYXkoVikuZmlsbCgwKX19YXN5bmMgeDI1NTE5U2hhcmVkKCQsSil7bGV0IFo9QlEoJCksUT1qMChaKTt0cnl7bGV0IFk9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLFEse25hbWU6IlgyNTUxOSJ9LCExLFsiZGVyaXZlQml0cyJdKSxWPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoInJhdyIsajAoSikse25hbWU6IlgyNTUxOSJ9LCExLFtdKSxYPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5kZXJpdmVCaXRzKHtuYW1lOiJYMjU1MTkiLHB1YmxpYzpWfSxZLDI1Nik7cmV0dXJuIG5ldyBVaW50OEFycmF5KFgpfWZpbmFsbHl7Wi5maWxsKDApLG5ldyBVaW50OEFycmF5KFEpLmZpbGwoMCl9fX12YXIgcVY9bmV3IFMwLGQkPXFWO3ZhciB2MD17ZW5jb2RlKCQsSil7bGV0IFo9JC53cml0ZVZhclN0cmluZyhKLmhhbmRsZSk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhclN0cmluZyhKLmxhYmVsKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gJC53cml0ZVZhckludChKLmlkeD8/MCl9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbUSxZXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihZIT09MClyZXR1cm4gRyhZKTtsZXRbVixYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gTyh7aGFuZGxlOkosbGFiZWw6USxpZHg6Vn0pfX07dmFyIHIkPTEsdEo9e2VuY29kZSgkLEope2lmKEoudiE9PXIkKXJldHVybiAxMDtsZXRbLFpdPSQwKEoubWFzdGVyU2VlZCk7aWYoWiE9PTApcmV0dXJuIFo7bGV0IFE9JC53cml0ZVZhckludChKLnYpO2lmKFEhPT0wKXJldHVybiBROyQud3JpdGVCeXRlcyhKLm1hc3RlclNlZWQpO2xldCBZPSQud3JpdGVWYXJJbnQoSi5ob3N0cy5sZW5ndGgpO2lmKFkhPT0wKXJldHVybiBZO2ZvcihsZXQgViBvZiBKLmhvc3RzKXtsZXQgWD0kLndyaXRlU3RydWN0KHYwLFYpO2lmKFghPT0wKXJldHVybiBYfXJldHVybiAwfSxkZWNvZGUoJCl7bGV0W0osWl09JC5yZWFkVmFySW50KCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSiE9PXIkKXJldHVybiBHKDE0KTtsZXRbUSxZXT0kLnJlYWRCeXRlcyhIMCk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1YsWF09JDAoUSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1csel09JC5yZWFkVmFySW50KCk7aWYoeiE9PTApcmV0dXJuIEcoeik7aWYoVz09PXZvaWQgMHx8VzwwKXJldHVybiBHKDEwKTtsZXQgSz1bXTtmb3IobGV0IEY9MDtGPFc7RisrKXtsZXRbTixVXT0kLnJlYWRTdHJ1Y3QodjApO2lmKFUhPT0wKXJldHVybiBHKFUpO2lmKE49PT12b2lkIDApcmV0dXJuIEcoMTQpO0sucHVzaChOKX1yZXR1cm4gTyh7djpyJCxtYXN0ZXJTZWVkOlYsaG9zdHM6S30pfX07ZnVuY3Rpb24gRVEoJCxKKXtsZXRbWixRXT0kMCgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDEwKTtsZXRbWSxWXT0kMChaLnNsaWNlKCkpO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFk9PT12b2lkIDApcmV0dXJuIEcoMTApO3JldHVybiBPKHt2OnIkLG1hc3RlclNlZWQ6WSxob3N0czpKLm1hcCgoWCk9Pih7aGFuZGxlOlguaGFuZGxlLGxhYmVsOlgubGFiZWwsaWR4OlguaWR4Pz8wfSkpfSl9dmFyIG8kPXtlbmNvZGUoJCxKKXtsZXRbLFpdPSQwKEoubWFzdGVyU2VlZCk7aWYoWiE9PTApcmV0dXJuIFo7JC53cml0ZUJ5dGVzKEoubWFzdGVyU2VlZCk7bGV0IFE9JC53cml0ZVZhckludChKLmhvc3RzLmxlbmd0aCk7aWYoUSE9PTApcmV0dXJuIFE7Zm9yKGxldCBZIG9mIEouaG9zdHMpe2xldCBWPSQud3JpdGVTdHJ1Y3QodjAsWSk7aWYoViE9PTApcmV0dXJuIFZ9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbSixaXT0kLnJlYWRCeXRlcyhIMCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1EsWV09JDAoSik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1YsWF09JC5yZWFkVmFySW50KCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoVj09PXZvaWQgMHx8VjwwKXJldHVybiBHKDEwKTtsZXQgVz1bXTtmb3IobGV0IHo9MDt6PFY7eisrKXtsZXRbSyxGXT0kLnJlYWRTdHJ1Y3QodjApO2lmKEYhPT0wKXJldHVybiBHKEYpO2lmKEs9PT12b2lkIDApcmV0dXJuIEcoMTQpO1cucHVzaChLKX1yZXR1cm4gTyh7bWFzdGVyU2VlZDpRLGhvc3RzOld9KX19O3ZhciBNVj1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMucXJwYWlyLnYxIiksTSQ9MzIsSVY9TSQrMjQrMTYsQ1Y9MzIsU0Y9U3ltYm9sKCJESEtFUmVxIiksdkY9U3ltYm9sKCJESEtFUmVzcCIpO2Z1bmN0aW9uIGZRKCQpe2lmKCQuYnl0ZUxlbmd0aCE9PU0kKXJldHVybiBHKDEwKTtyZXR1cm4gTygkKX1mdW5jdGlvbiBnUSgkKXtpZigkLmJ5dGVMZW5ndGg8SVYpcmV0dXJuIEcoMTApO3JldHVybiBPKCQpfXZhciBhJD1uZXcgUzA7YXN5bmMgZnVuY3Rpb24gZUooJCxKLFosUSl7bGV0IFk7dHJ5e1k9YXdhaXQgYSQueDI1NTE5U2hhcmVkKCQsSil9Y2F0Y2h7cmV0dXJuIEcoMjkpfXRyeXtpZihZLmJ5dGVMZW5ndGghPT1NJHx8WS5ldmVyeSgoVyk9Plc9PT0wKSlyZXR1cm4gRygxMCk7bGV0IFY9UjAoWSxNViksWD1SMChWLFIwKFosUSkpO3RyeXtsZXQgVz1hd2FpdCBhJC5ibGFrZTMoWCk7cmV0dXJuIE8oVy5zbGljZSgwLENWKSl9ZmluYWxseXtWLmZpbGwoMCksWC5maWxsKDApfX1maW5hbGx5e1kuZmlsbCgwKX19Y2xhc3MgcyR7IyQ7I0o7Y29uc3RydWN0b3IoJCxKKXt0aGlzLiMkPSQsdGhpcy4jSj1KfXN0YXRpYyBhc3luYyBjcmVhdGUoKXtsZXQgJDt0cnl7bGV0IEo9YXdhaXQgYSQuZ2VuWDI1NTE5KCk7JD1KLnByaXY7bGV0W1osUV09ZlEoSi5wdWIpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldCBZPW5ldyBzJCgkLFopO3JldHVybiAkPXZvaWQgMCxPKFkpfWNhdGNoe3JldHVybiBHKDI5KX1maW5hbGx5eyQ/LmZpbGwoMCl9fXdpcGUoKXt0aGlzLiMkLmZpbGwoMCl9Z2V0IGRoa2VSZXEoKXtsZXRbJCxKXT1mUSh0aGlzLiNKLnNsaWNlKCkpO2lmKCQ9PT12b2lkIDApdGhyb3cgRXJyb3IoYGRoa2VSZXEgJHtKfWApO3JldHVybiAkfWFzeW5jIGZpbmlzaCgkKXtsZXQgSj0kLnN1YmFycmF5KDAsTSQpLFo9JC5zdWJhcnJheShNJCksW1EsWV09YXdhaXQgZUoodGhpcy4jJCxKLHRoaXMuI0osSik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0IFY7dHJ5e3RyeXtWPWF3YWl0IGEkLmRlY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoWixRKX1jYXRjaHtyZXR1cm4gRygyMCl9bGV0IFg9bmV3IG0oViksW1csel09WC5yZWFkU3RydWN0KG8kKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwKXJldHVybiBHKDE0KTt0cnl7bGV0W0ssRl09VzAuZnJvbUJ5dGVzKFcubWFzdGVyU2VlZCk7aWYoRiE9PTApcmV0dXJuIEcoRik7aWYoSz09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIHRoaXMud2lwZSgpLE8oe2VuY2xhdmU6Syxob3N0czpXLmhvc3RzLm1hcCgoTik9Pih7Li4uTn0pKX0pfWZpbmFsbHl7Vy5tYXN0ZXJTZWVkLmZpbGwoMCl9fWZpbmFsbHl7US5maWxsKDApLFY/LmZpbGwoMCl9fX1mdW5jdGlvbiBEMCgkKXtsZXQgSj1uZXcgVWludDhBcnJheSgkKTtpZigkPjApY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhKKTtyZXR1cm4gSn12YXIgeTA9MzIsUFY9LTcsd1Y9LTgsVFY9LTI1Nyx0JD1be3R5cGU6InB1YmxpYy1rZXkiLGFsZzpQVn0se3R5cGU6InB1YmxpYy1rZXkiLGFsZzp3Vn0se3R5cGU6InB1YmxpYy1rZXkiLGFsZzpUVn1dO2Z1bmN0aW9uIGpWKCQpe3JldHVybiAkLnRyaW0oKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1wuJC8sIiIpfHwibG9jYWxob3N0In1mdW5jdGlvbiBCMCgkKXtsZXQgSj1uZXcgVWludDhBcnJheSgkLmJ5dGVMZW5ndGgpO3JldHVybiBKLnNldCgkKSxKLmJ1ZmZlcn1mdW5jdGlvbiBtUSgkKXtpZigkIGluc3RhbmNlb2YgQXJyYXlCdWZmZXIpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpLnNsaWNlKCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpLnNsaWNlKCl9ZnVuY3Rpb24gYjAoJCl7aWYoJD8ucnBJZCE9PXZvaWQgMClyZXR1cm4gTygkLnJwSWQpO2lmKHR5cGVvZiBsb2NhdGlvbj4idSIpcmV0dXJuIEcoOSk7cmV0dXJuIE8oalYobG9jYXRpb24uaG9zdG5hbWUpKX1mdW5jdGlvbiBoMCgpe2lmKHR5cGVvZiBuYXZpZ2F0b3I+InUifHwhbmF2aWdhdG9yLmNyZWRlbnRpYWxzfHx0eXBlb2YgUHVibGljS2V5Q3JlZGVudGlhbD4idSIpcmV0dXJuIDI0O3JldHVybiAwfWZ1bmN0aW9uIGkwKCQpe2lmKCQ9PT1udWxsfHwkLnR5cGUhPT0icHVibGljLWtleSJ8fCEoInJhd0lkImluICQpfHx0eXBlb2YgJC5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzIT09ImZ1bmN0aW9uIilyZXR1cm4gRygyNyk7cmV0dXJuIE8oJCl9YXN5bmMgZnVuY3Rpb24gU1EoJCl7bGV0IEo9aDAoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbWixRXT1iMCgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDkpO2xldCBZPSQ/LnVzZXJOYW1lPz8iZGlwbG9tYXRpYy1zZWVkIixWPXtyZXNpZGVudEtleToicmVxdWlyZWQiLHJlcXVpcmVSZXNpZGVudEtleTohMCx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCJ9O2lmKCQ/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50IT09dm9pZCAwKVYuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ9JC5hdXRoZW50aWNhdG9yQXR0YWNobWVudDtsZXQgWD17bGFyZ2VCbG9iOntzdXBwb3J0OiJyZXF1aXJlZCJ9fSxXO3RyeXtXPWF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5jcmVhdGUoe3B1YmxpY0tleTp7Y2hhbGxlbmdlOkQwKHkwKSxycDp7aWQ6WixuYW1lOiQ/LnJwTmFtZT8/IkRJUExPTUFUSUMifSx1c2VyOntpZDpEMCgxNiksbmFtZTpZLGRpc3BsYXlOYW1lOll9LHB1YktleUNyZWRQYXJhbXM6dCQsYXV0aGVudGljYXRvclNlbGVjdGlvbjpWLGV4dGVuc2lvbnM6WCwuLi4kPy5oaW50cyE9PXZvaWQgMD97aGludHM6JC5oaW50c306e319fSl9Y2F0Y2h7cmV0dXJuIEcoMjQpfWxldFt6LEtdPWkwKFcpO2lmKEshPT0wKXJldHVybiBHKEspO2lmKHo9PT12b2lkIDApcmV0dXJuIEcoMjcpO2lmKHouZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLmxhcmdlQmxvYj8uc3VwcG9ydGVkIT09ITApcmV0dXJuIEcoMjQpO3JldHVybiBPKG5ldyBVaW50OEFycmF5KHoucmF3SWQpKX1hc3luYyBmdW5jdGlvbiAkWigkLEosWil7bGV0IFE9aDAoKTtpZihRIT09MClyZXR1cm4gUTtsZXRbWSxWXT1iMChaKTtpZihWIT09MClyZXR1cm4gVjtpZihZPT09dm9pZCAwKXJldHVybiA5O2xldCBYPXtsYXJnZUJsb2I6e3dyaXRlOkIwKEopfX0sVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpEMCh5MCkscnBJZDpZLGFsbG93Q3JlZGVudGlhbHM6W3t0eXBlOiJwdWJsaWMta2V5IixpZDpCMCgkKX1dLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixleHRlbnNpb25zOlgsLi4uWj8uaGludHMhPT12b2lkIDA/e2hpbnRzOlouaGludHN9Ont9fX0pfWNhdGNoe3JldHVybiAyNH1sZXRbeixLXT1pMChXKTtpZihLIT09MClyZXR1cm4gSztpZih6PT09dm9pZCAwKXJldHVybiAyNztpZih6LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5sYXJnZUJsb2I/LndyaXR0ZW4hPT0hMClyZXR1cm4gMjQ7cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gdlEoJCxKKXtsZXQgWj1oMCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPWIwKEopO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoOSk7bGV0IFY9e2xhcmdlQmxvYjp7cmVhZDohMH19LFg7dHJ5e2xldCBVPXtjaGFsbGVuZ2U6RDAoeTApLHJwSWQ6USx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCIsZXh0ZW5zaW9uczpWfTtpZihKPy5oaW50cyE9PXZvaWQgMClVLmhpbnRzPUouaGludHM7aWYoJCE9PXZvaWQgMClVLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOiJwdWJsaWMta2V5IixpZDpCMCgkKX1dO1g9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmdldCh7cHVibGljS2V5OlV9KX1jYXRjaHtyZXR1cm4gRygyNCl9bGV0W1csel09aTAoWCk7aWYoeiE9PTApcmV0dXJuIEcoeik7aWYoVz09PXZvaWQgMClyZXR1cm4gRygyNyk7bGV0IEY9Vy5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCkubGFyZ2VCbG9iO2lmKEY9PT12b2lkIDB8fEYuYmxvYj09PXZvaWQgMClyZXR1cm4gRyg3KTtsZXQgTj1tUShGLmJsb2IpO2lmKE4uYnl0ZUxlbmd0aD09PTApcmV0dXJuIEcoNyk7cmV0dXJuIE8oe2Jsb2I6TixjcmVkSWQ6bmV3IFVpbnQ4QXJyYXkoVy5yYXdJZCl9KX12YXIgWlo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCJkaXBsb21hdGljLnByZi52MSIpLEpaPTMyO2FzeW5jIGZ1bmN0aW9uIHlRKCQpe2xldCBKPWgwKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1osUV09YjAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoWj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgWT0kPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtcHJmIixWPXtyZXNpZGVudEtleToicmVxdWlyZWQiLHJlcXVpcmVSZXNpZGVudEtleTohMCx1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCJ9O2lmKCQ/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50IT09dm9pZCAwKVYuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ9JC5hdXRoZW50aWNhdG9yQXR0YWNobWVudDtsZXQgWD0kPy5zYWx0IT09dm9pZCAwP0IwKCQuc2FsdCk6dm9pZCAwLFc9WD09PXZvaWQgMD97fTp7ZXZhbDp7Zmlyc3Q6WH19LHo7dHJ5e3o9YXdhaXQgbmF2aWdhdG9yLmNyZWRlbnRpYWxzLmNyZWF0ZSh7cHVibGljS2V5OntjaGFsbGVuZ2U6RDAoeTApLHJwOntpZDpaLG5hbWU6JD8ucnBOYW1lPz8iRElQTE9NQVRJQyJ9LHVzZXI6e2lkOkQwKDE2KSxuYW1lOlksZGlzcGxheU5hbWU6WX0scHViS2V5Q3JlZFBhcmFtczp0JCxhdXRoZW50aWNhdG9yU2VsZWN0aW9uOlYsZXh0ZW5zaW9uczp7cHJmOld9LC4uLiQ/LmhpbnRzIT09dm9pZCAwP3toaW50czokLmhpbnRzfTp7fX19KX1jYXRjaHtyZXR1cm4gRygyNCl9bGV0W0ssRl09aTAoeik7aWYoRiE9PTApcmV0dXJuIEcoRik7aWYoSz09PXZvaWQgMClyZXR1cm4gRygyNyk7bGV0IE49Sy5nZXRDbGllbnRFeHRlbnNpb25SZXN1bHRzKCk7cmV0dXJuIE8oe2NyZWRJZDpuZXcgVWludDhBcnJheShLLnJhd0lkKSxwcmZFbmFibGVkOk4ucHJmPy5lbmFibGVkPT09ITB9KX1hc3luYyBmdW5jdGlvbiBRWigkKXtsZXQgSj1oMCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtaLFFdPWIwKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoOSk7bGV0IFk9JD8uc2FsdD8/WlosVj1CMChZKSxYPXtjaGFsbGVuZ2U6RDAoeTApLHJwSWQ6Wix1c2VyVmVyaWZpY2F0aW9uOiJyZXF1aXJlZCIsZXh0ZW5zaW9uczp7cHJmOntldmFsOntmaXJzdDpWfX19fTtpZigkPy5oaW50cyE9PXZvaWQgMClYLmhpbnRzPSQuaGludHM7aWYoJD8uY3JlZElkIT09dm9pZCAwKVguYWxsb3dDcmVkZW50aWFscz1be3R5cGU6InB1YmxpYy1rZXkiLGlkOkIwKCQuY3JlZElkKX1dO2xldCBXO3RyeXtXPWF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5nZXQoe3B1YmxpY0tleTpYfSl9Y2F0Y2h7cmV0dXJuIEcoMjQpfWxldFt6LEtdPWkwKFcpO2lmKEshPT0wKXJldHVybiBHKEspO2lmKHo9PT12b2lkIDApcmV0dXJuIEcoMjcpO2xldCBGPXouZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLnByZj8ucmVzdWx0cztpZihGPy5maXJzdD09PXZvaWQgMClyZXR1cm4gRyg3KTtsZXQgTj1GLmZpcnN0LFU9TiBpbnN0YW5jZW9mIEFycmF5QnVmZmVyP25ldyBVaW50OEFycmF5KE4pOm5ldyBVaW50OEFycmF5KE4uYnVmZmVyLE4uYnl0ZU9mZnNldCxOLmJ5dGVMZW5ndGgpLFI9VS5ieXRlTGVuZ3RoPj1KWj9VLnNsaWNlKDAsSlopOlU7aWYoUi5ieXRlTGVuZ3RoIT09SlopcmV0dXJuIEcoMjcpO3JldHVybiBPKHtwcmY6UixjcmVkSWQ6bmV3IFVpbnQ4QXJyYXkoei5yYXdJZCl9KX12YXIgZSQ9IiI7dmFyIEpKPXR5cGVvZiBnbG9iYWxUaGlzLldvcmtlcj09PSJmdW5jdGlvbiI/Z2xvYmFsVGhpcy5Xb3JrZXI6dm9pZCAwLFlaPUpKPT09dm9pZCAwP3ZvaWQgMDpKSi5wcm90b3R5cGUucG9zdE1lc3NhZ2UsJEo7ZnVuY3Rpb24gQVYoKXtpZih0eXBlb2YgZSQhPT0ic3RyaW5nInx8ZSQubGVuZ3RoPT09MCl0aHJvdyBFcnJvcigiW0RJUExPTUFUSUNdIHdvcmtlciBzb3VyY2Ugbm90IGVtYmVkZGVkOyBydW4gcGtnIGJ1aWxkIGJlZm9yZSBzcGF3biIpO3JldHVybiBhdG9iKGUkKX1mdW5jdGlvbiBfVigpe2lmKCRKIT09dm9pZCAwKXJldHVybiAkSjtsZXQgJD1uZXcgQmxvYihbQVYoKV0se3R5cGU6InRleHQvamF2YXNjcmlwdCJ9KTtyZXR1cm4gJEo9VVJMLmNyZWF0ZU9iamVjdFVSTCgkKSwkSn1mdW5jdGlvbiBiUSgpe2lmKEpKPT09dm9pZCAwKXRocm93IEVycm9yKCJbRElQTE9NQVRJQ10gV29ya2VyIEFQSSB1bmF2YWlsYWJsZTsgY2Fubm90IHNwYXduIHN5bmMgd29ya2VyIik7cmV0dXJuIG5ldyBKSihfVigpLHt0eXBlOiJtb2R1bGUifSl9ZnVuY3Rpb24gaFEoJCxKLFope2lmKFlaPT09dm9pZCAwKXRocm93IEVycm9yKCJbRElQTE9NQVRJQ10gV29ya2VyIEFQSSB1bmF2YWlsYWJsZTsgY2Fubm90IHBvc3QgdG8gc3luYyB3b3JrZXIiKTtpZihaIT09dm9pZCAwJiZaLmxlbmd0aD4wKVlaLmNhbGwoJCxKLHt0cmFuc2ZlcjpafSk7ZWxzZSBZWi5jYWxsKCQsSil9dmFyIExWPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgiZGlwbG9tYXRpYy53cmFwLnYxIikseFY9MzIsQlY9MTYsejA9bmV3IFMwO2NsYXNzIFcweyMkO2NvbnN0cnVjdG9yKCQpe3RoaXMuIyQ9JH1zdGF0aWMgYXN5bmMgZnJvbVJhbmRvbSgpe2xldCAkPWF3YWl0IHowLmdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKSxbSixaXT0kMCgkKTtpZihaIT09MHx8Sj09PXZvaWQgMCl0aHJvdyBFcnJvcihgZW5jbGF2ZTogaW52YWxpZCByYW5kb20gc2VlZCAoJHtafSlgKTtyZXR1cm4gbmV3IFcwKEopfXN0YXRpYyBmcm9tQnl0ZXMoJCl7bGV0W0osWl09JDAoJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxMCk7bGV0W1EsWV09JDAoSi5zbGljZSgpKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEwKTtyZXR1cm4gTyhuZXcgVzAoUSkpfWFzeW5jIHNlYWxXaXRoUGFzc2tleSgkKXtsZXQgSj0kPy5zYWx0Pz9aWixaPSQ/LmNyZWRJZDtpZihaPT09dm9pZCAwJiYkPy5jcmVhdGVDcmVkSWZOZWVkZWQ9PT0hMCl7bGV0W1YsWF09YXdhaXQgeVEoe3JwSWQ6JD8ucnBJZCxycE5hbWU6JD8ucnBOYW1lLHVzZXJOYW1lOiQ/LnVzZXJOYW1lPz8iZGlwbG9tYXRpYy1wcmYiLGF1dGhlbnRpY2F0b3JBdHRhY2htZW50OiQ/LmF1dGhlbnRpY2F0b3JBdHRhY2htZW50LGhpbnRzOiQ/LmhpbnRzLHNhbHQ6Sn0pO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMjQpO2lmKCFWLnByZkVuYWJsZWQpcmV0dXJuIEcoMjQpO1o9Vi5jcmVkSWR9bGV0W1EsWV09YXdhaXQgUVooe3JwSWQ6JD8ucnBJZCxycE5hbWU6JD8ucnBOYW1lLGNyZWRJZDpaLHNhbHQ6SixoaW50czokPy5oaW50c30pO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoNyk7dHJ5e2xldFtWLFhdPWF3YWl0IHRoaXMuI1EoUS5wcmYpO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBPKHtzZWFsZWRNYXN0ZXI6VixzYWx0Okouc2xpY2UoKSxjcmVkSWQ6US5jcmVkSWQuc2xpY2UoKX0pfWZpbmFsbHl7US5wcmYuZmlsbCgwKX19c3RhdGljIGFzeW5jIHVuc2VhbFdpdGhQYXNza2V5KCQsSil7bGV0W1osUV09YXdhaXQgUVooe3JwSWQ6Si5ycElkLHJwTmFtZTpKLnJwTmFtZSxoaW50czpKLmhpbnRzLGNyZWRJZDpKLmNyZWRJZCxzYWx0Okouc2FsdH0pO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKFo9PT12b2lkIDApcmV0dXJuIEcoNyk7dHJ5e2xldFtZLFZdPWF3YWl0IFcwLiNaKCQsWi5wcmYpO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFk9PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBPKHtlbmNsYXZlOlksY3JlZElkOlouY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1oucHJmLmZpbGwoMCl9fWFzeW5jIHBlcnNpc3RUb0xhcmdlQmxvYigkPVtdLEope2xldCBaPUo/LmNyZWRJZDtpZihaPT09dm9pZCAwKXtsZXRbVixYXT1hd2FpdCBTUShKKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDI0KTtaPVZ9bGV0W1EsWV09dGhpcy4jWSgkKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFY9YXdhaXQgJFooWixRLEopO2lmKFYhPT0wKXJldHVybiBHKFYpO3JldHVybiBPKFopfWZpbmFsbHl7US5maWxsKDApfX1zdGF0aWMgYXN5bmMgZnJvbUxhcmdlQmxvYigkKXtsZXRbSixaXT1hd2FpdCB2USgkPy5jcmVkSWQsJCk7aWYoWiE9PTApcmV0dXJuIEcoWik7aWYoSj09PXZvaWQgMClyZXR1cm4gRyg3KTt0cnl7cmV0dXJuIFcwLiNWKEouYmxvYixKLmNyZWRJZCl9ZmluYWxseXtKLmJsb2IuZmlsbCgwKX19c3RhdGljIGFzeW5jIGNsZWFyTGFyZ2VCbG9iKCQsSil7cmV0dXJuICRaKCQsbmV3IFVpbnQ4QXJyYXkoSDApLEopfXN0YXRpYyBwYWlyUmVxdWVzdCgpe3JldHVybiBzJC5jcmVhdGUoKX1hc3luYyBwYWlyQWNjZXB0KCQsSil7bGV0IFo7dHJ5e1o9YXdhaXQgejAuZ2VuWDI1NTE5KCl9Y2F0Y2h7cmV0dXJuIEcoMjkpfXRyeXtsZXRbUSxZXT1hd2FpdCBlSihaLnByaXYsJCwkLFoucHViKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0W1YsWF09dGhpcy4jSihKKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFc9YXdhaXQgejAuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChWLFEpO3JldHVybiBnUShSMChaLnB1YixXKSl9Y2F0Y2h7cmV0dXJuIEcoMTIpfWZpbmFsbHl7Vi5maWxsKDApfX1maW5hbGx5e1EuZmlsbCgwKX19ZmluYWxseXtaLnByaXYuZmlsbCgwKX19I0ooJCl7bGV0IEo9dGhpcy4jJC5zbGljZSgpLFtaLFFdPSQwKEopO2lmKFEhPT0wKXJldHVybiBKLmZpbGwoMCksRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBKLmZpbGwoMCksRygxMCk7dHJ5e2xldCBZPXttYXN0ZXJTZWVkOlosaG9zdHM6JC5tYXAoKFgpPT4oe2hhbmRsZTpYLmhhbmRsZSxsYWJlbDpYLmxhYmVsLGlkeDpYLmlkeD8/MH0pKX0sVj1uZXcgUzt0cnl7bGV0IFg9Vi53cml0ZVN0cnVjdChvJCxZKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gTyhWLnJlc3VsdCgpKX1maW5hbGx5e1Yud2lwZSgpfX1maW5hbGx5e1ouZmlsbCgwKX19c3Bhd25TeW5jV29ya2VyKCQpe2xldCBKPWJRKCksWj10aGlzLiMkLnNsaWNlKCk7cmV0dXJuIGhRKEose2lkOiQuaWQsb3A6InNldFNlZWQiLHNlZWQ6WixwZXJzaXN0OiQucGVyc2lzdH0sW1ouYnVmZmVyXSksSn1kZXJpdmVDaXBoZXIoJCxKKXtsZXQgWj0kLnNsaWNlKCksUT0oWCk9PnRoaXMuI0coWixYKSxZPShYKT0+dGhpcy4jeihaLFgpO3JldHVybntlbmNyeXB0Ok9iamVjdC5mcmVlemUoe2VuY3J5cHQ6UX0pLGRlY3J5cHQ6T2JqZWN0LmZyZWV6ZSh7ZGVjcnlwdDpZfSksYm90aDpPYmplY3QuZnJlZXplKHtlbmNyeXB0OlEsZGVjcnlwdDpZfSl9W0pdfWFzeW5jIGRlcml2ZUlkZW50aXR5KCQsSj0wKXtsZXQgWj0kLFE9SixZPWF3YWl0IHRoaXMuI1coWixRKSxWPVkucHVibGljS2V5O3JldHVybiBZLnByaXZhdGVLZXkuZmlsbCgwKSxPYmplY3QuZnJlZXplKHtwdWJsaWNLZXk6VixzaWduOihYKT0+dGhpcy4jRihaLFEsWCksa2RtRm9yOihYKT0+dGhpcy4jTihaLFEsWCl9KX1hc3luYyNRKCQpe2xldFtKLFpdPWF3YWl0IGlRKHowLCQpO2lmKFohPT0wKXJldHVybiBHKFopO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoMTIpO3RyeXtsZXQgUT1hd2FpdCB6MC5lbmNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKHRoaXMuIyQsSik7cmV0dXJuIHgwKFEpfWNhdGNoe3JldHVybiBHKDEyKX1maW5hbGx5e0ouZmlsbCgwKX19c3RhdGljIGFzeW5jI1ooJCxKKXtsZXRbLFpdPXgwKCQpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtRLFldPWF3YWl0IGlRKHowLEopO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoMTIpO2xldCBWO3RyeXt0cnl7Vj1hd2FpdCB6MC5kZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKCQsUSl9Y2F0Y2h7cmV0dXJuIEcoMjApfXJldHVybiBXMC5mcm9tQnl0ZXMoVil9ZmluYWxseXtRLmZpbGwoMCksVj8uZmlsbCgwKX19I1koJCl7bGV0IEo9dGhpcy4jJC5zbGljZSgpLFtaLFFdPSQwKEopO2lmKFEhPT0wKXJldHVybiBKLmZpbGwoMCksRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBKLmZpbGwoMCksRygxMCk7dHJ5e2xldFtZLFZdPUVRKFosJCk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoWT09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBYPW5ldyBTLFc9WC53cml0ZVN0cnVjdCh0SixZKTtpZihXIT09MClyZXR1cm4gRyhXKTtyZXR1cm4gTyhYLnJlc3VsdCgpKX1maW5hbGx5e1kubWFzdGVyU2VlZC5maWxsKDApfX1maW5hbGx5e1ouZmlsbCgwKX19c3RhdGljI1YoJCxKKXtpZigkLmJ5dGVMZW5ndGg9PT0wfHwkLmV2ZXJ5KChWKT0+Vj09PTApKXJldHVybiBHKDIyKTtpZigkLmJ5dGVMZW5ndGg9PT1IMCl7aWYoJC5ldmVyeSgoVyk9Plc9PT0wKSlyZXR1cm4gRygyMik7bGV0W1YsWF09VzAuZnJvbUJ5dGVzKCQpO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBPKHtlbmNsYXZlOlYsaG9zdHM6W10sY3JlZElkOkp9KX1sZXQgWj1uZXcgbSgkKSxbUSxZXT1aLnJlYWRTdHJ1Y3QodEopO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoMTQpO3RyeXtpZihRLm1hc3RlclNlZWQuZXZlcnkoKFcpPT5XPT09MCkpcmV0dXJuIEcoMjIpO2xldFtWLFhdPVcwLmZyb21CeXRlcyhRLm1hc3RlclNlZWQpO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBPKHtlbmNsYXZlOlYsaG9zdHM6US5ob3N0cy5tYXAoKFcpPT4oey4uLld9KSksY3JlZElkOkp9KX1maW5hbGx5e1EubWFzdGVyU2VlZC5maWxsKDApfX1hc3luYyNHKCQsSil7bGV0IFo9YXdhaXQgdGhpcy4jWCgkKTt0cnl7cmV0dXJuIGF3YWl0IHowLmVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoSixaKX1maW5hbGx5e1ouZmlsbCgwKX19YXN5bmMjeigkLEope2xldCBaPWF3YWl0IHRoaXMuI1goJCk7dHJ5e3JldHVybiBhd2FpdCB6MC5kZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKEosWil9ZmluYWxseXtaLmZpbGwoMCl9fWFzeW5jI1goJCl7cmV0dXJuIHowLmJsYWtlMyhSMCh0aGlzLiMkLCQpKX1hc3luYyNLKCQsSil7bGV0IFo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpLFE9bmV3IFVpbnQ4QXJyYXkoOCk7cmV0dXJuIG5ldyBEYXRhVmlldyhRLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsQmlnSW50KEopLCExKSxhd2FpdCB0aGlzLiNYKFIwKFosUSkpfWFzeW5jI1coJCxKKXtsZXQgWj1hd2FpdCB0aGlzLiNLKCQsSik7dHJ5e3JldHVybiBhd2FpdCB6MC5kZXJpdmVFZDI1NTE5S2V5UGFpcihaKX1maW5hbGx5e1ouZmlsbCgwKX19YXN5bmMjRigkLEosWil7bGV0IFE9YXdhaXQgdGhpcy4jVygkLEopO3RyeXtyZXR1cm4gYXdhaXQgejAuc2lnbkVkMjU1MTkoWixRLnByaXZhdGVLZXkpfWZpbmFsbHl7US5wcml2YXRlS2V5LmZpbGwoMCl9fWFzeW5jI04oJCxKLFope2xldCBRPWF3YWl0IHRoaXMuI1coJCxKKSxZPVIwKFEucHJpdmF0ZUtleSxaKTtRLnByaXZhdGVLZXkuZmlsbCgwKTt0cnl7cmV0dXJuKGF3YWl0IHowLmJsYWtlMyhZKSkuc2xpY2UoMCxfMCl9ZmluYWxseXtZLmZpbGwoMCl9fX1hc3luYyBmdW5jdGlvbiBpUSgkLEosWj1MVil7aWYoSi5ieXRlTGVuZ3RoPEJWKXJldHVybiBHKDEwKTtsZXQgUT1hd2FpdCAkLmJsYWtlMyhSMChKLFopKTtyZXR1cm4gTyhRLnNsaWNlKDAseFYpKX1jbGFzcyBWWntkYjtjb25zdHJ1Y3RvcigkKXt0aGlzLmRiPSR9YXN5bmMgZW5xKCQpe2xldCBKPVsuLi4kXTtpZihKLmxlbmd0aD09PTApcmV0dXJuO2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oSzAsInJlYWR3cml0ZSIpLFE9Wi5vYmplY3RTdG9yZShLMCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57Wi5vbmNvbXBsZXRlPSgpPT5ZKCksWi5vbmVycm9yPSgpPT5WKFouZXJyb3IpO2ZvcihsZXQgWCBvZiBKKXtsZXQgVz1gJHtYLmhvc3R9OiR7WC5zZXF9YDtRLnB1dChYLFcpfX0pfWFzeW5jIGRlcSgkLEope2xldCBaPVsuLi5KXTtpZihaLmxlbmd0aD09PTApcmV0dXJuO2xldCBRPXRoaXMuZGIudHJhbnNhY3Rpb24oSzAsInJlYWR3cml0ZSIpLFk9US5vYmplY3RTdG9yZShLMCk7cmV0dXJuIG5ldyBQcm9taXNlKChWLFgpPT57US5vbmNvbXBsZXRlPSgpPT5WKCksUS5vbmVycm9yPSgpPT5YKFEuZXJyb3IpO2ZvcihsZXQgVyBvZiBaKXtsZXQgej1gJHskfToke1d9YDtZLmRlbGV0ZSh6KX19KX1hc3luYyBsaXN0KCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihLMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShLMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFk9Si5nZXRBbGwoKTtZLm9uc3VjY2Vzcz0oKT0+WihZLnJlc3VsdCksWS5vbmVycm9yPSgpPT5RKFkuZXJyb3IpfSl9YXN5bmMgY291bnQoKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKEswKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PntsZXQgWT1KLmNvdW50KCk7WS5vbnN1Y2Nlc3M9KCk9PlooWS5yZXN1bHQpLFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKEswLCJyZWFkd3JpdGUiKSxKPSQub2JqZWN0U3RvcmUoSzApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+eyQub25jb21wbGV0ZT0oKT0+WigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxKLmNsZWFyKCl9KX19ZnVuY3Rpb24gbFEoJCl7cmV0dXJue2xhYmVsOiQubGFiZWwsaGFuZGxlOm5ldyBVUkwoJC5oYW5kbGUpLGlkeDokLmlkeCxsYXN0U2VxOiQubGFzdFNlcXx8MCxjbG9ja09mZnNldDokLmNsb2NrT2Zmc2V0LHN1YnNjcmlwdGlvbjokLnN1YnNjcmlwdGlvbn19ZnVuY3Rpb24ga1YoJCxKKXtsZXQgWj17Li4uJH07aWYoSi5zZXRMYXN0U2VxIT09dm9pZCAwKVoubGFzdFNlcT1KLnNldExhc3RTZXE7ZWxzZSBpZihKLmxhc3RTZXEhPT12b2lkIDApe2xldCBRPVoubGFzdFNlcXx8MDtpZihKLmxhc3RTZXE+USlaLmxhc3RTZXE9Si5sYXN0U2VxfXJldHVybiBkZWxldGUgWi5udW1CYWdzLGRlbGV0ZSBaLm51bUR1cGVzLFp9Y2xhc3MgWFp7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGFkZCgkKXtsZXQgSj1hd2FpdCB0aGlzLmdldCgkLmxhYmVsKSxaPUohPT12b2lkIDAmJkouaGFuZGxlLmhyZWY9PT0kLmhhbmRsZS5ocmVmJiYoSi5pZHg/PzApPT09KCQuaWR4Pz8wKTtyZXR1cm4gdGhpcy5wdXQoey4uLiQsbGFzdFNlcTpaP0oubGFzdFNlcTowLGNsb2NrT2Zmc2V0Olo/Si5jbG9ja09mZnNldDp2b2lkIDAsc3Vic2NyaXB0aW9uOlo/Si5zdWJzY3JpcHRpb246dm9pZCAwfSl9YXN5bmMgcHV0KCQpe2xldCBKPXsuLi4kLGhhbmRsZTokLmhhbmRsZS50b1N0cmluZygpLGxhc3RTZXE6JC5sYXN0U2VxPz8wfSxaPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWR3cml0ZSIpLFE9Wi5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57Wi5vbmNvbXBsZXRlPSgpPT5ZKCksWi5vbmVycm9yPSgpPT5WKFouZXJyb3IpLFEucHV0KEopfSl9YXN5bmMgdG91Y2goJCxKKXtyZXR1cm4gdGhpcy5yZWNvcmRTdGF0cygkLHtsYXN0U2VxOkp9KX1hc3luYyByZWNvcmRTdGF0cygkLEope2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWR3cml0ZSIpLFE9Wi5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57Wi5vbmNvbXBsZXRlPSgpPT5ZKCksWi5vbmVycm9yPSgpPT5WKFouZXJyb3IpO2xldCBYPVEuZ2V0KCQpO1gub25zdWNjZXNzPSgpPT57bGV0IFc9WC5yZXN1bHQ7aWYoIVcpcmV0dXJuO1EucHV0KGtWKFcsSikpfX0pfWFzeW5jIGdldCgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntsZXQgVj1aLmdldCgkKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBYPVYucmVzdWx0O2lmKCFYKVEodm9pZCAwKTtlbHNlIFEobFEoWCkpfSxWLm9uZXJyb3I9KCk9PlkoVi5lcnJvcil9KX1hc3luYyBzZXQoJCxKKXtsZXQgWj1hd2FpdCB0aGlzLmdldCgkKTtpZighWilyZXR1cm4gMTM7dHJ5e3JldHVybiBhd2FpdCB0aGlzLnB1dCh7Li4uWiwuLi5KfSksMH1jYXRjaHtyZXR1cm4gMTh9fWFzeW5jIGRlbCgkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e0oub25jb21wbGV0ZT0oKT0+USgpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKSxaLmRlbGV0ZSgkKX0pfWFzeW5jIGxpc3QoKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PntsZXQgWT1KLmdldEFsbCgpO1kub25zdWNjZXNzPSgpPT57bGV0IFY9WS5yZXN1bHQ7WihWLm1hcChsUSkpfSxZLm9uZXJyb3I9KCk9PlEoWS5lcnJvcil9KX1hc3luYyB3aXBlKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZHdyaXRlIiksSj0kLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFosUSk9PnskLm9uY29tcGxldGU9KCk9PlooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksSi5jbGVhcigpfSl9fWNsYXNzIFdae2NyeXB0bztkYjtjb25zdHJ1Y3RvcigkLEope3RoaXMuY3J5cHRvPUo7dGhpcy5kYj0kfWFzeW5jIGFkZCgkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWR3cml0ZSIpLFo9Si5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFEpPT57aWYoJC5sZW5ndGg9PT0wKXtRKFtdKTtyZXR1cm59bGV0IFk9QXJyYXkoJC5sZW5ndGgpLmZpbGwoMCk7Si5vbmNvbXBsZXRlPSgpPT5RKFkpLEoub25lcnJvcj0oKT0+e2ZvcihsZXQgVj0wO1Y8WS5sZW5ndGg7VisrKVlbVl09MTg7UShZKX07Zm9yKGxldCBWPTA7VjwkLmxlbmd0aDtWKyspe2xldHtrZXk6WCxkYXRhOld9PSRbVl0sej1CKFgpLEs9Wi5wdXQoVyx6KTtLLm9uZXJyb3I9KEYpPT57Ri5wcmV2ZW50RGVmYXVsdCgpLFlbVl09MTh9fX0pfWFzeW5jIGRlbCgkKXtsZXQgSj1bLi4uJF07aWYoSi5sZW5ndGg9PT0wKXJldHVybjtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWR3cml0ZSIpLFE9Wi5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFksVik9PntaLm9uY29tcGxldGU9KCk9PlkoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvcik7Zm9yKGxldCBYIG9mIEope2xldCBXPUIoWCk7US5kZWxldGUoVyl9fSl9YXN5bmMgZ2V0KCQpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZG9ubHkiKS5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFEsWSk9PntsZXQgVj1CKCQpLFg9Wi5nZXQoVik7WC5vbnN1Y2Nlc3M9YXN5bmMoKT0+e2xldCBXPVgucmVzdWx0O2lmKFcpUShhd2FpdCBiJCgkLFcsdGhpcy5jcnlwdG8pKTtlbHNlIFEodm9pZCAwKX0sWC5vbmVycm9yPSgpPT5ZKFguZXJyb3IpfSl9YXN5bmMgaGFzKCQpe3JldHVybiBhd2FpdCB0aGlzLmdldCgkKSE9PXZvaWQgMH1hc3luYyBsaXN0KCQpe2xldCBKPSQ/LmFwbGQsWj0kPy5ib2R5IT09ITEsWT10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChWLFgpPT57bGV0IFc9W10sej1KPT09dm9pZCAwP1kub3BlbkN1cnNvcigpOlkuaW5kZXgoSSQpLm9wZW5DdXJzb3IoSURCS2V5UmFuZ2Uub25seShKKSk7ei5vbnN1Y2Nlc3M9KEspPT57bGV0IEY9Sy50YXJnZXQucmVzdWx0O2lmKEYpe2xldCBOPUo9PT12b2lkIDA/Ri5rZXk6Ri5wcmltYXJ5S2V5LFU9Ri52YWx1ZTtXLnB1c2goe2hhc2g6TjAoTiksZGF0YTpVfSksRi5jb250aW51ZSgpfWVsc2UgUHJvbWlzZS5hbGwoVy5tYXAoKHtoYXNoOk4sZGF0YTpVfSk9PmIkKE4sVSx0aGlzLmNyeXB0byx7Ym9keTpafSkpKS50aGVuKFYpLmNhdGNoKFgpfSx6Lm9uZXJyb3I9KCk9Plgoei5lcnJvcil9KX1hc3luYyBjb3VudCgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFkpPT57bGV0IFY9JD09PXZvaWQgMD9aLmNvdW50KCk6Wi5pbmRleChJJCkuY291bnQoSURCS2V5UmFuZ2Uub25seSgkKSk7Vi5vbnN1Y2Nlc3M9KCk9PlEoVi5yZXN1bHQpLFYub25lcnJvcj0oKT0+WShWLmVycm9yKX0pfWFzeW5jIGxpc3RLZXlzKCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBZPVtdLFY9Si5vcGVuS2V5Q3Vyc29yKCk7Vi5vbnN1Y2Nlc3M9KFgpPT57bGV0IFc9WC50YXJnZXQucmVzdWx0O2lmKFcpWS5wdXNoKE4wKFcua2V5KSksVy5jb250aW51ZSgpO2Vsc2UgWihZKX0sVi5vbmVycm9yPSgpPT5RKFYuZXJyb3IpfSl9YXN5bmMgbGFzdCgkKXtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFkpPT57bGV0IFYsWD1aLm9wZW5DdXJzb3IoKTtYLm9uc3VjY2Vzcz1hc3luYyhXKT0+e2xldCB6PVcudGFyZ2V0LnJlc3VsdDtpZih6KXtsZXR7a2V5OkssdmFsdWU6Rn09ejtpZihyKCQsRi5laWQpKXtpZighVnx8KEYuY3RyPz8wKT4oVi5kYXRhLmN0cj8/MCl8fChGLmN0cj8/MCk9PT0oVi5kYXRhLmN0cj8/MCkmJihGLm9mZj8/MCk+KFYuZGF0YS5vZmY/PzApKVY9e2tleTpLLGRhdGE6Rn19ei5jb250aW51ZSgpfWVsc2UgaWYoVil7bGV0IEs9TjAoVi5rZXkpO1EoYXdhaXQgYiQoSyxWLmRhdGEsdGhpcy5jcnlwdG8pKX1lbHNlIFEodm9pZCAwKX0sWC5vbmVycm9yPSgpPT5ZKFguZXJyb3IpfSl9YXN5bmMgbWFya0FwcGxpZWQoJCl7bGV0IEo9Wy4uLiRdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChZLFYpPT57Wi5vbmNvbXBsZXRlPSgpPT5ZKCksWi5vbmVycm9yPSgpPT5WKFouZXJyb3IpO2ZvcihsZXQgWCBvZiBKKXtsZXQgVz1CKFgpLHo9US5nZXQoVyk7ei5vbnN1Y2Nlc3M9KCk9PntsZXQgSz16LnJlc3VsdDtpZighSylyZXR1cm47QkooSyx5JCksUS5wdXQoSyxXKX0sei5vbmVycm9yPShLKT0+e0sucHJldmVudERlZmF1bHQoKX19fSl9YXN5bmMgbWFya0ZhaWxlZCgkKXtsZXQgSj1bLi4uJF07aWYoSi5sZW5ndGg9PT0wKXJldHVybjtsZXQgWj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWR3cml0ZSIpLFE9Wi5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFksVik9PntaLm9uY29tcGxldGU9KCk9PlkoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvcik7Zm9yKGxldHtrZXk6WCxlcnI6V31vZiBKKXtsZXQgej1CKFgpLEs9US5nZXQoeik7Sy5vbnN1Y2Nlc3M9KCk9PntsZXQgRj1LLnJlc3VsdDtpZighRilyZXR1cm47QkooRixaJCxXKSxRLnB1dChGLHopfSxLLm9uZXJyb3I9KEYpPT57Ri5wcmV2ZW50RGVmYXVsdCgpfX19KX1hc3luYyB3aXBlKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkd3JpdGUiKSxKPSQub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5aKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLEouY2xlYXIoKX0pfX1jbGFzcyBHWnsjJDsjSjsjUTsjWjtjb25zdHJ1Y3RvcigkKXtpZih0aGlzLiNaPSQucGVyc2lzdE1ldGEsdGhpcy4jUT17cnBJZDokLnJwSWQscnBOYW1lOiQucnBOYW1lfSwkLm1ldGEhPT12b2lkIDApdGhpcy4jSj1sMCgkLm1ldGEpfWdldCBtZXRhKCl7cmV0dXJuIHRoaXMuI0o9PT12b2lkIDA/dm9pZCAwOmwwKHRoaXMuI0opfXNldE1ldGEoJCl7dGhpcy4jSj0kPT09dm9pZCAwP3ZvaWQgMDpsMCgkKX1hc3luYyBzYXZlKCQsSil7aWYoSj8ucGVyc2lzdD09PSEwKXJldHVybiBQcm9taXNlLnJlamVjdChFcnJvcigicHJmLXN0b3JlOiB1c2Ugd3JhcEFuZFNhdmUoZW5jbGF2ZSkgdG8gcGVyc2lzdCBzZWFsZWQgbWFzdGVyIikpO3JldHVybiB0aGlzLiMkPSQsdGhpcy4jJH1hc3luYyB3cmFwQW5kU2F2ZSgkLEope2xldFtaLFFdPWF3YWl0ICQuc2VhbFdpdGhQYXNza2V5KHsuLi50aGlzLiNRLHNhbHQ6Sj8uc2FsdCxjcmVkSWQ6Sj8uY3JlZElkPz90aGlzLiNKPy5jcmVkSWQsY3JlYXRlQ3JlZElmTmVlZGVkOko/LmNyZWF0ZUNyZWRJZk5lZWRlZD8/Sj8uY3JlZElkPT09dm9pZCAwLHVzZXJOYW1lOiJkaXBsb21hdGljLXByZiIsYXV0aGVudGljYXRvckF0dGFjaG1lbnQ6Sj8uYXV0aGVudGljYXRvckF0dGFjaG1lbnQsaGludHM6Sj8uaGludHN9KTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDEyKTtsZXQgWT17c2VhbGVkTWFzdGVyOlouc2VhbGVkTWFzdGVyLHNhbHQ6Wi5zYWx0LGNyZWRJZDpaLmNyZWRJZH07cmV0dXJuIHRoaXMuI0o9WSx0aGlzLiMkPSQsYXdhaXQgdGhpcy4jWihsMChZKSksTyh0aGlzLiMkKX1hc3luYyBsb2FkKCl7cmV0dXJuIHRoaXMuIyR9YXN5bmMgdW5sb2NrKCl7bGV0ICQ9dGhpcy4jSjtpZigkPT09dm9pZCAwKXJldHVybiBHKDIyKTtsZXRbSixaXT1hd2FpdCBXMC51bnNlYWxXaXRoUGFzc2tleSgkLnNlYWxlZE1hc3Rlcix7Li4udGhpcy4jUSxzYWx0OiQuc2FsdCxjcmVkSWQ6JC5jcmVkSWR9KTtpZihaIT09MClyZXR1cm4gRyhaKTtpZih0aGlzLiMkPUouZW5jbGF2ZSxKLmNyZWRJZC5ieXRlTGVuZ3RoPjAmJigkLmNyZWRJZD09PXZvaWQgMHx8IXIoJC5jcmVkSWQsSi5jcmVkSWQpKSl7bGV0IFE9e3NlYWxlZE1hc3RlcjokLnNlYWxlZE1hc3RlcixzYWx0OiQuc2FsdCxjcmVkSWQ6Si5jcmVkSWQuc2xpY2UoKX07dGhpcy4jSj1RLGF3YWl0IHRoaXMuI1oobDAoUSkpfXJldHVybiBPKEouZW5jbGF2ZSl9YXN5bmMgYWRvcHRTZWFsZWQoJCxKKXtyZXR1cm4gdGhpcy4jSj1sMChKKSx0aGlzLiMkPSQsYXdhaXQgdGhpcy4jWihsMChKKSksTyh0aGlzLiMkKX1hc3luYyB3aXBlKCl7dGhpcy4jJD12b2lkIDAsdGhpcy4jSj12b2lkIDAsYXdhaXQgdGhpcy4jWih2b2lkIDApfX1mdW5jdGlvbiBsMCgkKXtsZXRbSixaXT14MCgkLnNlYWxlZE1hc3Rlci5zbGljZSgpKTtyZXR1cm57c2VhbGVkTWFzdGVyOlo9PT0wJiZKIT09dm9pZCAwP0o6JC5zZWFsZWRNYXN0ZXIsc2FsdDokLnNhbHQuc2xpY2UoKSxjcmVkSWQ6JC5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9fXZhciBFVj0iZGlwbG9tYXRpYy5waW4vIjtmdW5jdGlvbiBmVigkKXtyZXR1cm4gRVYrVTAoJCl9YXN5bmMgZnVuY3Rpb24gdVEoJCxKLFope2xldCBRPWF3YWl0IEouZGVyaXZlSWRlbnRpdHkoZlYoWiksMCk7cmV0dXJuICQuYmxha2UzKFEucHVibGljS2V5KX1hc3luYyBmdW5jdGlvbiBwUSgkLEope2xldCBaPWF3YWl0ICQuZ2VuMjU2Qml0U2VjdXJlUmFuZG9tU2VlZCgpLFE9YXdhaXQgdVEoJCxKLFopO3JldHVybntuOlosaDpRfX1hc3luYyBmdW5jdGlvbiBjUSgkLEosWil7bGV0IFE9YXdhaXQgdVEoJCxKLFoubik7cmV0dXJuIGdWKFEsWi5oKX1mdW5jdGlvbiBuUSgkKXtpZigkPT09dm9pZCAwfHwkPT09bnVsbHx8dHlwZW9mICQhPT0ib2JqZWN0IilyZXR1cm47bGV0IEo9JDtpZighKEoubiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpfHwhKEouaCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKXJldHVybjtpZihKLm4uYnl0ZUxlbmd0aDwxfHxKLmguYnl0ZUxlbmd0aDwxKXJldHVybjtyZXR1cm57bjpKLm4uc2xpY2UoKSxoOkouaC5zbGljZSgpfX1mdW5jdGlvbiBkUSgkKXtyZXR1cm57bjokLm4uc2xpY2UoKSxoOiQuaC5zbGljZSgpfX1mdW5jdGlvbiBnVigkLEope2lmKCQuYnl0ZUxlbmd0aCE9PUouYnl0ZUxlbmd0aClyZXR1cm4hMTtsZXQgWj0wO2ZvcihsZXQgUT0wO1E8JC5ieXRlTGVuZ3RoO1ErKylafD0kW1FdXkpbUV07cmV0dXJuIFo9PT0wfXZhciBaSj0icHJmTWV0YSIselo9ImlkUGluIixyUT0iaWRQdWIiO2NsYXNzIEtaeyMkO2RiOyNKO2NvbnN0cnVjdG9yKCQsSil7dGhpcy5kYj0kLHRoaXMuI0o9Sn1hc3luYyBzYXZlKCQsSil7cmV0dXJuIGF3YWl0IHRoaXMuI1EoJCksdGhpcy4jJD0kLHRoaXMuIyR9YXN5bmMgbG9hZCgpe3JldHVybiB0aGlzLiMkfWFzeW5jIGNsZWFyU2Vzc2lvbigpe3RoaXMuIyQ9dm9pZCAwfWFzeW5jIHdpcGUoKXt0aGlzLiMkPXZvaWQgMDtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKFEwLCJyZWFkd3JpdGUiKSxKPSQub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+eyQub25jb21wbGV0ZT0oKT0+WigpLCQub25lcnJvcj0oKT0+USgkLmVycm9yKSxKLmRlbGV0ZShaSiksSi5kZWxldGUoelopLEouZGVsZXRlKHJRKX0pfWFzeW5jIGxvYWRQcmZNZXRhKCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShRMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFk9Si5nZXQoWkopO1kub25zdWNjZXNzPSgpPT57WihtVihZLnJlc3VsdCkpfSxZLm9uZXJyb3I9KCk9PlEoWS5lcnJvcil9KX1hc3luYyBwZXJzaXN0UHJmTWV0YSgkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFEwLCJyZWFkd3JpdGUiKSxaPUoub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e2lmKEoub25jb21wbGV0ZT0oKT0+USgpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKSwkPT09dm9pZCAwKXtaLmRlbGV0ZShaSik7cmV0dXJufWxldCBWPXtzZWFsZWRNYXN0ZXI6JC5zZWFsZWRNYXN0ZXIuc2xpY2UoKSxzYWx0OiQuc2FsdC5zbGljZSgpLGNyZWRJZDokLmNyZWRJZD09PXZvaWQgMD92b2lkIDA6JC5jcmVkSWQuc2xpY2UoKX07Wi5wdXQoVixaSil9KX1hc3luYyBoYXNQcmZNZXRhKCl7cmV0dXJuIGF3YWl0IHRoaXMubG9hZFByZk1ldGEoKSE9PXZvaWQgMH1hc3luYyBsYXN0UHJmQ3JlZElkKCl7bGV0ICQ9YXdhaXQgdGhpcy5sb2FkUHJmTWV0YSgpO3JldHVybiAkPy5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9YXN5bmMgb3BlblByZlN0b3JlKCQpe2xldCBKPWF3YWl0IHRoaXMubG9hZFByZk1ldGEoKTtyZXR1cm4gbmV3IEdaKHtycElkOiQucnBJZCxycE5hbWU6JC5ycE5hbWUsbWV0YTpKLHBlcnNpc3RNZXRhOihaKT0+dGhpcy5wZXJzaXN0UHJmTWV0YShaKX0pfWFzeW5jI1EoJCl7YXdhaXQgdGhpcy4jVihyUSk7bGV0IEo9YXdhaXQgdGhpcy4jWigpO2lmKEohPT12b2lkIDApe2lmKCFhd2FpdCBjUSh0aGlzLiNKLCQsSikpdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSBzZWVkIGRvZXMgbm90IG1hdGNoIHRoaXMgZGV2aWNlJ3MgaWRlbnRpdHkgKGxvY2FsIGRhdGEgd2FzIGNyZWF0ZWQgd2l0aCBhIGRpZmZlcmVudCBtYXN0ZXIgc2VlZCkiKTtyZXR1cm59bGV0IFo9YXdhaXQgcFEodGhpcy4jSiwkKTthd2FpdCB0aGlzLiNZKFopfSNaKCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihRMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShRMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57bGV0IFk9Si5nZXQoelopO1kub25zdWNjZXNzPSgpPT5aKG5RKFkucmVzdWx0KSksWS5vbmVycm9yPSgpPT5RKFkuZXJyb3IpfSl9I1koJCl7bGV0IEo9ZFEoJCksWj10aGlzLmRiLnRyYW5zYWN0aW9uKFEwLCJyZWFkd3JpdGUiKSxRPVoub2JqZWN0U3RvcmUoUTApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxWKT0+e1oub25jb21wbGV0ZT0oKT0+WSgpLFoub25lcnJvcj0oKT0+VihaLmVycm9yKSxRLnB1dChKLHpaKX0pfSNWKCQpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oUTAsInJlYWR3cml0ZSIpLFo9Si5vYmplY3RTdG9yZShRMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFkpPT57Si5vbmNvbXBsZXRlPSgpPT5RKCksSi5vbmVycm9yPSgpPT5ZKEouZXJyb3IpLFouZGVsZXRlKCQpfSl9fWZ1bmN0aW9uIG1WKCQpe2lmKCQ9PT12b2lkIDB8fCQ9PT1udWxsfHx0eXBlb2YgJCE9PSJvYmplY3QiKXJldHVybjtsZXQgSj0kO2lmKCEoSi5zZWFsZWRNYXN0ZXIgaW5zdGFuY2VvZiBVaW50OEFycmF5KXx8IShKLnNhbHQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSlyZXR1cm47bGV0W1osUV09eDAoSi5zZWFsZWRNYXN0ZXIpO2lmKFEhPT0wfHxaPT09dm9pZCAwKXJldHVybjtyZXR1cm57c2VhbGVkTWFzdGVyOlosc2FsdDpKLnNhbHQuc2xpY2UoKSxjcmVkSWQ6Si5jcmVkSWQgaW5zdGFuY2VvZiBVaW50OEFycmF5P0ouY3JlZElkLnNsaWNlKCk6dm9pZCAwfX1jbGFzcyBGWntkYjtjb25zdHJ1Y3RvcigkKXt0aGlzLmRiPSR9YXN5bmMgZW5xKCQsSil7bGV0IFo9Wy4uLkpdO2lmKFoubGVuZ3RoPT09MClyZXR1cm47bGV0IFE9dGhpcy5kYi50cmFuc2FjdGlvbihGMCwicmVhZHdyaXRlIiksWT1RLm9iamVjdFN0b3JlKEYwKTtyZXR1cm4gbmV3IFByb21pc2UoKFYsWCk9PntRLm9uY29tcGxldGU9KCk9PlYoKSxRLm9uZXJyb3I9KCk9PlgoUS5lcnJvcik7Zm9yKGxldCBXIG9mIFope2xldCB6PVUwKFcpO1kucHV0KHtob3N0OiQsaGFzaDp6fSl9fSl9YXN5bmMgZGVxKCQsSil7bGV0IFo9Wy4uLkpdO2lmKFoubGVuZ3RoPT09MClyZXR1cm47bGV0IFE9dGhpcy5kYi50cmFuc2FjdGlvbihGMCwicmVhZHdyaXRlIiksWT1RLm9iamVjdFN0b3JlKEYwKTtyZXR1cm4gbmV3IFByb21pc2UoKFYsWCk9PntRLm9uY29tcGxldGU9KCk9PlYoKSxRLm9uZXJyb3I9KCk9PlgoUS5lcnJvcik7Zm9yKGxldCBXIG9mIFope2xldCB6PVUwKFcpO1kuZGVsZXRlKFskLHpdKX19KX1hc3luYyBsaXN0KCQpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oRjAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoRjApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxZKT0+e2xldCBWPVouZ2V0QWxsKCk7Vi5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1WLnJlc3VsdC5maWx0ZXIoKHopPT56Lmhvc3Q9PT0kKS5tYXAoKHopPT56Lmhhc2gpO1EoVy5tYXAoKHopPT5fWih6KSkpfSxWLm9uZXJyb3I9KCk9PlkoVi5lcnJvcil9KX1hc3luYyBjb3VudCgpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oRjAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoRjApO3JldHVybiBuZXcgUHJvbWlzZSgoWixRKT0+e2xldCBZPUouY291bnQoKTtZLm9uc3VjY2Vzcz0oKT0+WihZLnJlc3VsdCksWS5vbmVycm9yPSgpPT5RKFkuZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oRjAsInJlYWR3cml0ZSIpLEo9JC5vYmplY3RTdG9yZShGMCk7cmV0dXJuIG5ldyBQcm9taXNlKChaLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5aKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLEouY2xlYXIoKX0pfX12YXIgUTA9InNlZWRNZXRhIixaMD0iaG9zdHMiLEYwPSJ1cGxvYWRRdWV1ZSIsSzA9ImRvd25sb2FkUXVldWUiLHU9Im1lc3NhZ2VzIixJJD0iYXBsZCIsb1E9MyxhUT0iZGlwbG9tYXRpYy1zdG9yZS1kYiI7Y2xhc3Mgc1F7c2VlZDtob3N0czt1cGxvYWRzO2Rvd25sb2FkczttZXNzYWdlcztkYjtjb25zdHJ1Y3RvcigkLEope3RoaXMuZGI9JCx0aGlzLnNlZWQ9bmV3IEtaKCQsSiksdGhpcy5ob3N0cz1uZXcgWFooJCksdGhpcy51cGxvYWRzPW5ldyBGWigkKSx0aGlzLmRvd25sb2Fkcz1uZXcgVlooJCksdGhpcy5tZXNzYWdlcz1uZXcgV1ooJCxKKX1hc3luYyB3aXBlKCl7YXdhaXQgdGhpcy5ob3N0cy53aXBlKCksYXdhaXQgdGhpcy51cGxvYWRzLndpcGUoKSxhd2FpdCB0aGlzLmRvd25sb2Fkcy53aXBlKCksYXdhaXQgdGhpcy5tZXNzYWdlcy53aXBlKCl9fWFzeW5jIGZ1bmN0aW9uIFNWKCl7cmV0dXJuIG5ldyBQcm9taXNlKCgkLEopPT57bGV0IFo9aW5kZXhlZERCLm9wZW4oYVEsb1EpO1oub251cGdyYWRlbmVlZGVkPSgpPT57bGV0e3Jlc3VsdDpRLHRyYW5zYWN0aW9uOll9PVo7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhRMCkpUS5jcmVhdGVPYmplY3RTdG9yZShRMCk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhaMCkpUS5jcmVhdGVPYmplY3RTdG9yZShaMCx7a2V5UGF0aDoibGFiZWwifSk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhGMCkpUS5jcmVhdGVPYmplY3RTdG9yZShGMCx7a2V5UGF0aDpbImhvc3QiLCJoYXNoIl19KTtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKEswKSlRLmNyZWF0ZU9iamVjdFN0b3JlKEswKTtsZXQgVjtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKHUpKVY9US5jcmVhdGVPYmplY3RTdG9yZSh1KTtlbHNle2lmKCFZKXRocm93IEVycm9yKCJtaXNzaW5nIHVwZ3JhZGUgdHJhbnNhY3Rpb24gZm9yIG1lc3NhZ2VzIHN0b3JlIik7Vj1ZLm9iamVjdFN0b3JlKHUpfWlmKCFWLmluZGV4TmFtZXMuY29udGFpbnMoSSQpKVYuY3JlYXRlSW5kZXgoSSQsImFwbGQiLHt1bmlxdWU6ITF9KX0sWi5vbmJsb2NrZWQ9KCk9Pntjb25zb2xlLndhcm4oYFtESVBMT01BVElDXSBwcm90b2NvbCBzdG9yZSBJREIgdXBncmFkZSBibG9ja2VkICgke2FRfSDihpIgdiR7b1F9KTsgd2FpdGluZyBmb3Igb3RoZXIgY29ubmVjdGlvbnMgdG8gY2xvc2VgKX0sWi5vbnN1Y2Nlc3M9KCk9PntsZXQgUT1aLnJlc3VsdDtRLm9udmVyc2lvbmNoYW5nZT0oKT0+e1EuY2xvc2UoKX0sJChRKX0sWi5vbmVycm9yPSgpPT5KKFouZXJyb3I/P0Vycm9yKCJwcm90b2NvbCBzdG9yZSBJbmRleGVkREIgb3BlbiBmYWlsZWQiKSl9KX1hc3luYyBmdW5jdGlvbiB0USgkKXtsZXQgSj1hd2FpdCBTVigpO2lmKHR5cGVvZiBuYXZpZ2F0b3I8InUiJiZuYXZpZ2F0b3Iuc3RvcmFnZT8ucGVyc2lzdCl0cnl7YXdhaXQgUHJvbWlzZS5yYWNlKFtuYXZpZ2F0b3Iuc3RvcmFnZS5wZXJzaXN0KCksbmV3IFByb21pc2UoKFopPT57c2V0VGltZW91dCgoKT0+WighMSksMjAwMCl9KV0pfWNhdGNoe31yZXR1cm4gbmV3IHNRKEosJCl9Y2xhc3MgTlp7Y2xpZW50O2VudERCO3Bvc3Q7d2hlblJlYWR5O3Jlc29sdmVSZWFkeTtyZWplY3RSZWFkeTtjb25zdHJ1Y3RvcigkKXt0aGlzLnBvc3Q9JCx0aGlzLndoZW5SZWFkeT1uZXcgUHJvbWlzZSgoSixaKT0+e3RoaXMucmVzb2x2ZVJlYWR5PUosdGhpcy5yZWplY3RSZWFkeT1afSl9YXN5bmMgaW5pdCgpe3RyeXtsZXQgJD1hd2FpdCB0UShkJCksSj1hd2FpdCBkWih7Y2FjaGU6ITF9KSxaPW5ldyBmJChKLmFwcGx5LCgpPT5KLmNsZWFyKCksKFYpPT57aWYoVi5sZW5ndGg8MSlyZXR1cm47dGhpcy5wb3N0KHtraW5kOiJkaXJ0eSIsZWlkczpWLm1hcCgoWCk9Plguc2xpY2UoKSl9KX0pLFE9Wi5jbGVhcjtaLmNsZWFyPWFzeW5jKCk9PntsZXQgVj1hd2FpdCBRKCk7aWYoVj09PTApdGhpcy5wb3N0KHtraW5kOiJ3aXBlZCJ9KTtyZXR1cm4gVn07bGV0IFk9bmV3IFNKKG5ldyBGSixaLCQsdlosZCQpO3RoaXMuY2xpZW50PVksdGhpcy5lbnREQj1KLFkuY2xpZW50U3RhdGUubGlzdGVuKCgpPT57dGhpcy5lbWl0Q2xpZW50U3RhdGUoKX0pLFkueGZlclN0YXRlLmxpc3RlbigoKT0+e3RoaXMuZW1pdFhmZXJTdGF0ZSgpfSksYXdhaXQgdGhpcy5lbWl0WGZlclN0YXRlKCksdGhpcy5wb3N0KHtraW5kOiJyZWFkeSJ9KSx0aGlzLm1hcmtSZWFkeSgpfWNhdGNoKCQpe2xldCBKPSQgaW5zdGFuY2VvZiBFcnJvcj8kOkVycm9yKFN0cmluZygkKSk7dGhyb3cgdGhpcy5wb3N0KHtraW5kOiJpbml0RXJyb3IiLG1lc3NhZ2U6Si5tZXNzYWdlfSksdGhpcy5mYWlsUmVhZHkoSiksSn19bWFya1JlYWR5KCl7bGV0ICQ9dGhpcy5yZXNvbHZlUmVhZHk7aWYodGhpcy5yZXNvbHZlUmVhZHk9dm9pZCAwLHRoaXMucmVqZWN0UmVhZHk9dm9pZCAwLCQpJCgpfWZhaWxSZWFkeSgkKXtsZXQgSj10aGlzLnJlamVjdFJlYWR5O2lmKHRoaXMucmVzb2x2ZVJlYWR5PXZvaWQgMCx0aGlzLnJlamVjdFJlYWR5PXZvaWQgMCxKKUooJCl9cmVxdWlyZUNsaWVudCgpe2lmKCF0aGlzLmNsaWVudCl0aHJvdyBFcnJvcigiV29ya2VyUnVudGltZSBub3QgaW5pdGlhbGl6ZWQiKTtyZXR1cm4gdGhpcy5jbGllbnR9YXN5bmMgZW1pdENsaWVudFN0YXRlKCl7bGV0ICQ9dGhpcy5jbGllbnQ7aWYoISQpcmV0dXJuO2xldCBKPWF3YWl0ICQuY2xpZW50U3RhdGUuZ2V0KCk7dGhpcy5wb3N0KHtraW5kOiJjbGllbnRTdGF0ZSIsY29ubmVjdGVkOkouY29ubmVjdGVkfSl9YXN5bmMgZW1pdFhmZXJTdGF0ZSgpe2xldCAkPXRoaXMuY2xpZW50O2lmKCEkKXJldHVybjtsZXQgSj1hd2FpdCAkLnhmZXJTdGF0ZS5nZXQoKTt0aGlzLnBvc3Qoe2tpbmQ6InhmZXJTdGF0ZSIsc3RhdGU6Sn0pfWhvc3RGcm9tU2VyaWFsaXplZCgkKXtyZXR1cm57aGFuZGxlOm5ldyBVUkwoJC5oYW5kbGUpLGxhYmVsOiQubGFiZWwsaWR4OiQuaWR4fX1hc3luYyBoYW5kbGUoJCl7YXdhaXQgdGhpcy53aGVuUmVhZHk7bGV0IEo9dGhpcy5yZXF1aXJlQ2xpZW50KCk7c3dpdGNoKCQub3Ape2Nhc2UicGluZyI6cmV0dXJuInBvbmciO2Nhc2Uic2V0U2VlZCI6e2xldFtaLFFdPVcwLmZyb21CeXRlcygkLnNlZWQpO2lmKCQuc2VlZC5maWxsKDApLFEhPT0wfHxaPT09dm9pZCAwKXRocm93IG5ldyBPMChRKTthd2FpdCBKLnNldFNlZWQoWix7cGVyc2lzdDokLnBlcnNpc3R9KTtyZXR1cm59Y2FzZSJsaW5rIjp7YXdhaXQgSi5saW5rKHRoaXMuaG9zdEZyb21TZXJpYWxpemVkKCQuaG9zdCksJC5jb25uZWN0Pz8hMCk7cmV0dXJufWNhc2UidW5saW5rIjp7YXdhaXQgSi51bmxpbmsoJC5sYWJlbCk7cmV0dXJufWNhc2UiY29ubmVjdCI6e2F3YWl0IEouY29ubmVjdCgkLmxpc3Rlbj8/ITAsJC5zeW5jPz8hMCk7cmV0dXJufWNhc2UiZGlzY29ubmVjdCI6e2F3YWl0IEouZGlzY29ubmVjdCgpO3JldHVybn1jYXNlInN5bmMiOnJldHVybiBhd2FpdCBKLnN5bmMoKTtjYXNlInJlYnVpbGQiOnJldHVybiBhd2FpdCBKLnJlYnVpbGQoe2NoZWNrSG9zdDokLmNoZWNrSG9zdD8/ITB9KTtjYXNlInJlY29uY2lsZSI6e2xldFtaLFFdPWF3YWl0IEoucmVjb25jaWxlKCQuaG9zdExhYmVsLHtwdWxsOiQucHVsbCxwdXNoOiQucHVzaCxzeW5jOiQuc3luY30pO2lmKFEhPT0wKXRocm93IG5ldyBPMChRKTtpZighWil0aHJvdyBuZXcgTzAoMTIpO3JldHVybiBafWNhc2UibXNnY2hlY2siOnJldHVybiBhd2FpdCBKLm1zZ2NoZWNrKCk7Y2FzZSJlbnRjaGVjayI6e2xldCBaPXRoaXMuZW50REI7aWYoIVopdGhyb3cgbmV3IE8wKDEyKTtsZXRbUSxZXT1hd2FpdCBaLmNoZWNrc3VtKGQkKTtpZihZIT09MCl0aHJvdyBuZXcgTzAoWSk7aWYoIVEpdGhyb3cgbmV3IE8wKDEyKTtyZXR1cm4gUX1jYXNlIndpcGUiOnthd2FpdCBKLndpcGUoe21zZ3M6JC5tc2dzLGVudHM6JC5lbnRzLG1ldGE6JC5tZXRhLHNlZWQ6JC5zZWVkfSk7cmV0dXJufWNhc2UiaW1wb3J0Ijp7bGV0IFo9JC5ieXRlcy5zbGljZSgpLFE9bmV3IEJsb2IoW1pdKSxZPW5ldyBGaWxlKFtRXSwiaW1wb3J0LmRpcCIpO3JldHVybiBhd2FpdCBKLmltcG9ydChZKX1jYXNlImV4cG9ydCI6e2xldFtaLFFdPWF3YWl0IEouZXhwb3J0Qnl0ZXMoKTtpZihRIT09MCl0aHJvdyBuZXcgTzAoUSk7aWYoIVopdGhyb3cgbmV3IE8wKDEyKTtyZXR1cm4gWn1jYXNlImdldFhmZXJTdGF0ZSI6cmV0dXJuIGF3YWl0IEoueGZlclN0YXRlLmdldCgpO2RlZmF1bHQ6e2xldCBaPSQ7dGhyb3cgRXJyb3IoInVua25vd24gd29ya2VyIGNvbW1hbmQiKX19fX1jbGFzcyBPMCBleHRlbmRzIEVycm9ye3N0YXR1cztjb25zdHJ1Y3RvcigkKXtzdXBlcihgV29ya2VyU3RhdHVzRXJyb3I6ICR7RFskXX1gKTt0aGlzLnN0YXR1cz0kO3RoaXMubmFtZT0iV29ya2VyU3RhdHVzRXJyb3IifX1mdW5jdGlvbiBRSigkLEope3JldHVybntraW5kOiJyZXBseSIsaWQ6JCxvazohMCxyZXN1bHQ6Sn19ZnVuY3Rpb24gT1ooJCxKKXtyZXR1cm57a2luZDoicmVwbHkiLGlkOiQsb2s6ITEsc3RhdHVzOkp9fXZhciBrMD1nbG9iYWxUaGlzLGVRPW5ldyBOWigoJCxKKT0+e2lmKEomJkoubGVuZ3RoPjApazAucG9zdE1lc3NhZ2UoJCxKKTtlbHNlIGswLnBvc3RNZXNzYWdlKCQpfSk7azAub25tZXNzYWdlPSgkKT0+e2xldCBKPSQuZGF0YTtpZighcVooSikpcmV0dXJuO3ZWKEopfTthc3luYyBmdW5jdGlvbiB2VigkKXt0cnl7bGV0IEo9YXdhaXQgZVEuaGFuZGxlKCQpO2lmKCgkLm9wPT09ImV4cG9ydCJ8fCQub3A9PT0ibXNnY2hlY2sifHwkLm9wPT09ImVudGNoZWNrIikmJkogaW5zdGFuY2VvZiBVaW50OEFycmF5KXtsZXQgWj1KLnNsaWNlKCk7azAucG9zdE1lc3NhZ2UoUUooJC5pZCxaKSxbWi5idWZmZXJdKTtyZXR1cm59aWYoJC5vcD09PSJyZWNvbmNpbGUiJiZKJiZ0eXBlb2YgSj09PSJvYmplY3QiJiYibXNnY2hlY2siaW4gSiYmSi5tc2djaGVjayBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpe2xldCBaPUoubXNnY2hlY2suc2xpY2UoKSxRPXsuLi5KLG1zZ2NoZWNrOlp9O2swLnBvc3RNZXNzYWdlKFFKKCQuaWQsUSksW1ouYnVmZmVyXSk7cmV0dXJufWswLnBvc3RNZXNzYWdlKFFKKCQuaWQsSikpfWNhdGNoKEope2lmKEogaW5zdGFuY2VvZiBPMCl7azAucG9zdE1lc3NhZ2UoT1ooJC5pZCxKLnN0YXR1cykpO3JldHVybn1jb25zb2xlLmVycm9yKCJ3b3JrZXIgY29tbWFuZCBmYWlsZWQiLEopLGswLnBvc3RNZXNzYWdlKE9aKCQuaWQsMTIpKX19ZVEuaW5pdCgpLmNhdGNoKCgkKT0+e2NvbnNvbGUuZXJyb3IoIndvcmtlciBpbml0IGZhaWxlZCIsJCl9KTsK";var yW=typeof globalThis.Worker==="function"?globalThis.Worker:void 0,jV=yW===void 0?void 0:yW.prototype.postMessage,pW;function eK(){if(typeof QW!=="string"||QW.length===0)throw Error("[DIPLOMATIC] worker source not embedded; run pkg build before spawn");return atob(QW)}function ZG(){if(pW!==void 0)return pW;let Z=new Blob([eK()],{type:"text/javascript"});return pW=URL.createObjectURL(Z),pW}function J0(){if(yW===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot spawn sync worker");return new yW(ZG(),{type:"module"})}function C0(Z,X,W){if(jV===void 0)throw Error("[DIPLOMATIC] Worker API unavailable; cannot post to sync worker");if(W!==void 0&&W.length>0)jV.call(Z,X,{transfer:W});else jV.call(Z,X)}var XG=new TextEncoder().encode("diplomatic.wrap.v1"),WG=32,VG=16,FZ=new nZ;class ZZ{#Z;constructor(Z){this.#Z=Z}static async fromRandom(){let Z=await FZ.gen256BitSecureRandomSeed(),[X,W]=VZ(Z);if(W!==0||X===void 0)throw Error(`enclave: invalid random seed (${W})`);return new ZZ(X)}static fromBytes(Z){let[X,W]=VZ(Z);if(W!==0)return Y(W);if(X===void 0)return Y(10);let[V,l]=VZ(X.slice());if(l!==0)return Y(l);if(V===void 0)return Y(10);return b(new ZZ(V))}async sealWithPasskey(Z){let X=Z?.salt??cW,W=Z?.credId;if(W===void 0&&Z?.createCredIfNeeded===!0){let[K,G]=await R0({rpId:Z?.rpId,rpName:Z?.rpName,userName:Z?.userName??"diplomatic-prf",authenticatorAttachment:Z?.authenticatorAttachment,hints:Z?.hints,salt:X});if(G!==0)return Y(G);if(K===void 0)return Y(24);if(!K.prfEnabled)return Y(24);W=K.credId}let[V,l]=await iV({rpId:Z?.rpId,rpName:Z?.rpName,credId:W,salt:X,hints:Z?.hints});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await this.#W(V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);return b({sealedMaster:K,salt:X.slice(),credId:V.credId.slice()})}finally{V.prf.fill(0)}}static async unsealWithPasskey(Z,X){let[W,V]=await iV({rpId:X.rpId,rpName:X.rpName,hints:X.hints,credId:X.credId,salt:X.salt});if(V!==0)return Y(V);if(W===void 0)return Y(7);try{let[l,K]=await ZZ.#V(Z,W.prf);if(K!==0)return Y(K);if(l===void 0)return Y(12);return b({enclave:l,credId:W.credId.slice()})}finally{W.prf.fill(0)}}async persistToLargeBlob(Z=[],X){let W=X?.credId;if(W===void 0){let[K,G]=await IW(X);if(G!==0)return Y(G);if(K===void 0)return Y(24);W=K}let[V,l]=this.#l(Z);if(l!==0)return Y(l);if(V===void 0)return Y(12);try{let K=await uX(W,V,X);if(K!==0)return Y(K);return b(W)}finally{V.fill(0)}}static async fromLargeBlob(Z){let[X,W]=await LW(Z?.credId,Z);if(W!==0)return Y(W);if(X===void 0)return Y(7);try{return ZZ.#K(X.blob,X.credId)}finally{X.blob.fill(0)}}static async clearLargeBlob(Z,X){return uX(Z,new Uint8Array(kZ),X)}static pairRequest(){return jX.create()}async pairAccept(Z,X){let W;try{W=await FZ.genX25519()}catch{return Y(29)}try{let[V,l]=await PV(W.priv,Z,Z,W.pub);if(l!==0)return Y(l);if(V===void 0)return Y(12);try{let[K,G]=this.#X(X);if(G!==0)return Y(G);if(K===void 0)return Y(12);try{let m=await FZ.encryptXSalsa20Poly1305Combined(K,V);return UV(IZ(W.pub,m))}catch{return Y(12)}finally{K.fill(0)}}finally{V.fill(0)}}finally{W.priv.fill(0)}}#X(Z){let X=this.#Z.slice(),[W,V]=VZ(X);if(V!==0)return X.fill(0),Y(V);if(W===void 0)return X.fill(0),Y(10);try{let l={masterSeed:W,hosts:Z.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))},K=new j;try{let G=K.writeStruct(dW,l);if(G!==0)return Y(G);return b(K.result())}finally{K.wipe()}}finally{W.fill(0)}}spawnSyncWorker(Z){let X=J0(),W=this.#Z.slice();return C0(X,{id:Z.id,op:"setSeed",seed:W,persist:Z.persist},[W.buffer]),X}deriveCipher(Z,X){let W=Z.slice(),V=(G)=>this.#Y(W,G),l=(G)=>this.#R(W,G);return{encrypt:Object.freeze({encrypt:V}),decrypt:Object.freeze({decrypt:l}),both:Object.freeze({encrypt:V,decrypt:l})}[X]}async deriveIdentity(Z,X=0){let W=Z,V=X,l=await this.#m(W,V),K=l.publicKey;return l.privateKey.fill(0),Object.freeze({publicKey:K,sign:(G)=>this.#C(W,V,G),kdmFor:(G)=>this.#F(W,V,G)})}async#W(Z){let[X,W]=await F0(FZ,Z);if(W!==0)return Y(W);if(X===void 0)return Y(12);try{let V=await FZ.encryptXSalsa20Poly1305Combined(this.#Z,X);return yZ(V)}catch{return Y(12)}finally{X.fill(0)}}static async#V(Z,X){let[,W]=yZ(Z);if(W!==0)return Y(W);let[V,l]=await F0(FZ,X);if(l!==0)return Y(l);if(V===void 0)return Y(12);let K;try{try{K=await FZ.decryptXSalsa20Poly1305Combined(Z,V)}catch{return Y(20)}return ZZ.fromBytes(K)}finally{V.fill(0),K?.fill(0)}}#l(Z){let X=this.#Z.slice(),[W,V]=VZ(X);if(V!==0)return X.fill(0),Y(V);if(W===void 0)return X.fill(0),Y(10);try{let[l,K]=V0(W,Z);if(K!==0)return Y(K);if(l===void 0)return Y(12);try{let G=new j,m=G.writeStruct(HV,l);if(m!==0)return Y(m);return b(G.result())}finally{l.masterSeed.fill(0)}}finally{W.fill(0)}}static#K(Z,X){if(Z.byteLength===0||Z.every((K)=>K===0))return Y(22);if(Z.byteLength===kZ){if(Z.every((m)=>m===0))return Y(22);let[K,G]=ZZ.fromBytes(Z);if(G!==0)return Y(G);if(K===void 0)return Y(12);return b({enclave:K,hosts:[],credId:X})}let W=new O(Z),[V,l]=W.readStruct(HV);if(l!==0)return Y(l);if(V===void 0)return Y(14);try{if(V.masterSeed.every((m)=>m===0))return Y(22);let[K,G]=ZZ.fromBytes(V.masterSeed);if(G!==0)return Y(G);if(K===void 0)return Y(12);return b({enclave:K,hosts:V.hosts.map((m)=>({...m})),credId:X})}finally{V.masterSeed.fill(0)}}async#Y(Z,X){let W=await this.#G(Z);try{return await FZ.encryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#R(Z,X){let W=await this.#G(Z);try{return await FZ.decryptXSalsa20Poly1305Combined(X,W)}finally{W.fill(0)}}async#G(Z){return FZ.blake3(IZ(this.#Z,Z))}async#J(Z,X){let W=new TextEncoder().encode(Z),V=new Uint8Array(8);return new DataView(V.buffer).setBigUint64(0,BigInt(X),!1),await this.#G(IZ(W,V))}async#m(Z,X){let W=await this.#J(Z,X);try{return await FZ.deriveEd25519KeyPair(W)}finally{W.fill(0)}}async#C(Z,X,W){let V=await this.#m(Z,X);try{return await FZ.signEd25519(W,V.privateKey)}finally{V.privateKey.fill(0)}}async#F(Z,X,W){let V=await this.#m(Z,X),l=IZ(V.privateKey,W);V.privateKey.fill(0);try{return(await FZ.blake3(l)).slice(0,OZ)}finally{l.fill(0)}}}async function F0(Z,X,W=XG){if(X.byteLength<VG)return Y(10);let V=await Z.blake3(IZ(X,W));return b(V.slice(0,WG))}class SW{#Z;#X;#W;#V;constructor(Z){if(this.#V=Z.persistMeta,this.#W={rpId:Z.rpId,rpName:Z.rpName},Z.meta!==void 0)this.#X=aZ(Z.meta)}get meta(){return this.#X===void 0?void 0:aZ(this.#X)}setMeta(Z){this.#X=Z===void 0?void 0:aZ(Z)}async save(Z,X){if(X?.persist===!0)return Promise.reject(Error("prf-store: use wrapAndSave(enclave) to persist sealed master"));return this.#Z=Z,this.#Z}async wrapAndSave(Z,X){let[W,V]=await Z.sealWithPasskey({...this.#W,salt:X?.salt,credId:X?.credId??this.#X?.credId,createCredIfNeeded:X?.createCredIfNeeded??X?.credId===void 0,userName:"diplomatic-prf",authenticatorAttachment:X?.authenticatorAttachment,hints:X?.hints});if(V!==0)return Y(V);if(W===void 0)return Y(12);let l={sealedMaster:W.sealedMaster,salt:W.salt,credId:W.credId};return this.#X=l,this.#Z=Z,await this.#V(aZ(l)),b(this.#Z)}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await ZZ.unsealWithPasskey(Z.sealedMaster,{...this.#W,salt:Z.salt,credId:Z.credId});if(W!==0)return Y(W);if(this.#Z=X.enclave,X.credId.byteLength>0&&(Z.credId===void 0||!n(Z.credId,X.credId))){let V={sealedMaster:Z.sealedMaster,salt:Z.salt,credId:X.credId.slice()};this.#X=V,await this.#V(aZ(V))}return b(X.enclave)}async adoptSealed(Z,X){return this.#X=aZ(X),this.#Z=Z,await this.#V(aZ(X)),b(this.#Z)}async wipe(){this.#Z=void 0,this.#X=void 0,await this.#V(void 0)}}function aZ(Z){let[X,W]=yZ(Z.sealedMaster.slice());return{sealedMaster:W===0&&X!==void 0?X:Z.sealedMaster,salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()}}var lG="diplomatic.pin/";function KG(Z){return lG+YZ(Z)}async function b0(Z,X,W){let V=await X.deriveIdentity(KG(W),0);return Z.blake3(V.publicKey)}async function zW(Z,X){let W=await Z.gen256BitSecureRandomSeed(),V=await b0(Z,X,W);return{n:W,h:V}}async function NW(Z,X,W){let V=await b0(Z,X,W.n);return GG(V,W.h)}function d0(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.n instanceof Uint8Array)||!(X.h instanceof Uint8Array))return;if(X.n.byteLength<1||X.h.byteLength<1)return;return{n:X.n.slice(),h:X.h.slice()}}function MW(Z){return{n:Z.n.slice(),h:Z.h.slice()}}function GG(Z,X){if(Z.byteLength!==X.byteLength)return!1;let W=0;for(let V=0;V<Z.byteLength;V++)W|=Z[V]^X[V];return W===0}var gW="prfMeta",BV="idPin",k0="idPub";class xW{#Z;db;#X;constructor(Z,X){this.db=Z,this.#X=X}async save(Z,X){return await this.#W(Z),this.#Z=Z,this.#Z}async load(){return this.#Z}async clearSession(){this.#Z=void 0}async wipe(){this.#Z=void 0;let Z=this.db.transaction(GZ,"readwrite"),X=Z.objectStore(GZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.delete(gW),X.delete(BV),X.delete(k0)})}async loadPrfMeta(){let X=this.db.transaction(GZ,"readonly").objectStore(GZ);return new Promise((W,V)=>{let l=X.get(gW);l.onsuccess=()=>{W(mG(l.result))},l.onerror=()=>V(l.error)})}async persistPrfMeta(Z){let X=this.db.transaction(GZ,"readwrite"),W=X.objectStore(GZ);return new Promise((V,l)=>{if(X.oncomplete=()=>V(),X.onerror=()=>l(X.error),Z===void 0){W.delete(gW);return}let K={sealedMaster:Z.sealedMaster.slice(),salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()};W.put(K,gW)})}async hasPrfMeta(){return await this.loadPrfMeta()!==void 0}async lastPrfCredId(){let Z=await this.loadPrfMeta();return Z?.credId===void 0?void 0:Z.credId.slice()}async openPrfStore(Z){let X=await this.loadPrfMeta();return new SW({rpId:Z.rpId,rpName:Z.rpName,meta:X,persistMeta:(W)=>this.persistPrfMeta(W)})}async#W(Z){await this.#K(k0);let X=await this.#V();if(X!==void 0){if(!await NW(this.#X,Z,X))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)");return}let W=await zW(this.#X,Z);await this.#l(W)}#V(){let X=this.db.transaction(GZ,"readonly").objectStore(GZ);return new Promise((W,V)=>{let l=X.get(BV);l.onsuccess=()=>W(d0(l.result)),l.onerror=()=>V(l.error)})}#l(Z){let X=MW(Z),W=this.db.transaction(GZ,"readwrite"),V=W.objectStore(GZ);return new Promise((l,K)=>{W.oncomplete=()=>l(),W.onerror=()=>K(W.error),V.put(X,BV)})}#K(Z){let X=this.db.transaction(GZ,"readwrite"),W=X.objectStore(GZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}}function mG(Z){if(Z===void 0||Z===null||typeof Z!=="object")return;let X=Z;if(!(X.sealedMaster instanceof Uint8Array)||!(X.salt instanceof Uint8Array))return;let[W,V]=yZ(X.sealedMaster);if(V!==0||W===void 0)return;return{sealedMaster:W,salt:X.salt.slice(),credId:X.credId instanceof Uint8Array?X.credId.slice():void 0}}class EV{db;constructor(Z){this.db=Z}async enq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(bZ,"readwrite"),l=V.objectStore(bZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=YZ(m);l.put({host:Z,hash:R})}})}async deq(Z,X){let W=[...X];if(W.length===0)return;let V=this.db.transaction(bZ,"readwrite"),l=V.objectStore(bZ);return new Promise((K,G)=>{V.oncomplete=()=>K(),V.onerror=()=>G(V.error);for(let m of W){let R=YZ(m);l.delete([Z,R])}})}async list(Z){let W=this.db.transaction(bZ,"readonly").objectStore(bZ);return new Promise((V,l)=>{let K=W.getAll();K.onsuccess=()=>{let m=K.result.filter((R)=>R.host===Z).map((R)=>R.hash);V(m.map((R)=>yX(R)))},K.onerror=()=>l(K.error)})}async count(){let X=this.db.transaction(bZ,"readonly").objectStore(bZ);return new Promise((W,V)=>{let l=X.count();l.onsuccess=()=>W(l.result),l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(bZ,"readwrite"),X=Z.objectStore(bZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var GZ="seedMeta",KZ="hosts",bZ="uploadQueue",CZ="downloadQueue",$="messages",OX="apld",T0=3,I0="diplomatic-store-db";class uV{seed;hosts;uploads;downloads;messages;db;constructor(Z,X){this.db=Z,this.seed=new xW(Z,X),this.hosts=new gV(Z),this.uploads=new EV(Z),this.downloads=new MV(Z),this.messages=new xV(Z,X)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}async function YG(){return new Promise((Z,X)=>{let W=indexedDB.open(I0,T0);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!V.objectStoreNames.contains(GZ))V.createObjectStore(GZ);if(!V.objectStoreNames.contains(KZ))V.createObjectStore(KZ,{keyPath:"label"});if(!V.objectStoreNames.contains(bZ))V.createObjectStore(bZ,{keyPath:["host","hash"]});if(!V.objectStoreNames.contains(CZ))V.createObjectStore(CZ);let K;if(!V.objectStoreNames.contains($))K=V.createObjectStore($);else{if(!l)throw Error("missing upgrade transaction for messages store");K=l.objectStore($)}if(!K.indexNames.contains(OX))K.createIndex(OX,"apld",{unique:!1})},W.onblocked=()=>{console.warn(`[DIPLOMATIC] protocol store IDB upgrade blocked (${I0} → v${T0}); waiting for other connections to close`)},W.onsuccess=()=>{let V=W.result;V.onversionchange=()=>{V.close()},Z(V)},W.onerror=()=>X(W.error??Error("protocol store IndexedDB open failed"))})}async function wV(Z){let X=await YG();if(typeof navigator<"u"&&navigator.storage?.persist)try{await Promise.race([navigator.storage.persist(),new Promise((W)=>{setTimeout(()=>W(!1),2000)})])}catch{}return new uV(X,Z)}function L0(Z){if(!Z||typeof Z!=="object")return!1;if(!("kind"in Z))return!1;return typeof Z.kind==="string"}function c0(Z){if(typeof Z!=="number")return;return Z}function RG(Z){if(!Z||typeof Z!=="object")return;if(!("phase"in Z))return;let X=JG(Z.phase);if(X===void 0)return;let W={phase:X};if("host"in Z&&typeof Z.host==="string")W.host=Z.host;if("done"in Z&&typeof Z.done==="number")W.done=Z.done;if("total"in Z&&typeof Z.total==="number")W.total=Z.total;if("bytesDone"in Z&&typeof Z.bytesDone==="number")W.bytesDone=Z.bytesDone;if("bytesTotal"in Z&&typeof Z.bytesTotal==="number")W.bytesTotal=Z.bytesTotal;return W}function JG(Z){if(Z==="peek"||Z==="pull"||Z==="open"||Z==="exec"||Z==="push"||Z==="import"||Z==="idle"||Z==="apply")return Z==="apply"?"exec":Z;return}function Q0(Z){if(!Z||typeof Z!=="object")return;if(!("numUploads"in Z)||!("numDownloads"in Z))return;if(typeof Z.numUploads!=="number"||typeof Z.numDownloads!=="number")return;let X={phase:"idle"};if("progress"in Z){let W=RG(Z.progress);if(W===void 0)return;X=W}return{numUploads:Z.numUploads,numDownloads:Z.numDownloads,progress:X}}var dZ="[DIPLOMATIC]";class DX{worker;state;store;local;nextId=1;pending=new Map;readyTimeoutMs;scheduledSync;cachedClientState={hasSeed:!1,hasHost:!1,connected:!1};cachedXferState={numUploads:0,numDownloads:0,progress:$Z};clientState;xferState;constructor(Z,X,W,V,l){this.state=Z,this.store=X,this.readyTimeoutMs=l,this.clientState=new TZ(async()=>this.cachedClientState),this.xferState=new TZ(async()=>this.cachedXferState),this.scheduledSync=new xX(V,async()=>{if(!this.worker)return;try{await this.request({id:this.allocId(),op:"sync"})}catch(K){console.error(`${dZ} worker sync after local write failed`,K)}}),this.local=new bX(W,Z,X,()=>{throw Error(`${dZ} local writer has no transport (use worker for network)`)},IX,!0,void 0,void 0,()=>{this.scheduledSync.schedule()}),this.local.xferState.listen((K)=>{this.cachedXferState={numUploads:K.numUploads,numDownloads:K.numDownloads,progress:this.cachedXferState.progress},this.xferState.emit()})}bindWorker(Z){let X=this.worker;if(X){X.onmessage=null,X.onerror=null,X.onmessageerror=null;try{X.terminate()}catch{}}this.worker=Z,Z.onmessage=(W)=>{this.onMessage(W.data)},Z.onerror=(W)=>{console.error(`${dZ} worker error`,W),this.failPending(Error(`${dZ} worker failed to load`))},Z.onmessageerror=()=>{this.failPending(Error(`${dZ} worker message error`))}}failPending(Z){for(let[,X]of this.pending)X.reject(Z);this.pending.clear()}async flushScheduledSync(){await this.scheduledSync.flush()}static async open(Z,X,W={}){let V=W.clock??new jZ,l=W.syncDebounceMs??WW,K=W.readyTimeoutMs??15000,G=new DX(Z,X,V,l,K);return await G.hydrateStateFromStore(X),G}async hydrateStateFromStore(Z){await this.loadSession(!1);let X=await Z.uploads.count(),W=await Z.downloads.count();this.cachedXferState={numUploads:X,numDownloads:W,progress:$Z}}async loadSession(Z){let X=await this.store.seed.load(),W=await this.store.hosts.list();this.cachedClientState={hasSeed:X!==void 0,hasHost:Array.from(W).length>0,connected:Z}}async pullRemoteXfer(){let Z=await this.request({id:this.allocId(),op:"getXferState"}),X=Q0(Z);if(X!==void 0)this.cachedXferState=X}requireWorker(){if(!this.worker)throw Error(`${dZ} no sync worker; call setSeed first`);return this.worker}async ping(){if(await this.request({id:this.allocId(),op:"ping"})!=="pong")throw Error(`${dZ} worker ping failed`)}terminate(){this.scheduledSync.cancel();let Z=this.worker;if(this.worker=void 0,Z)try{Z.terminate()}catch{}this.failPending(Error(`${dZ} worker terminated`))}onMessage(Z){if(!L0(Z))return;let X=Z;switch(X.kind){case"ready":return;case"initError":{this.failPending(Error(`${dZ} worker init failed: ${X.message}`));return}case"clientState":{if(this.cachedClientState.connected===X.connected)return;this.cachedClientState={...this.cachedClientState,connected:X.connected},this.clientState.emit();return}case"xferState":{this.cachedXferState=X.state,this.xferState.emit();return}case"dirty":{this.state.refresh(X.eids.map(FG));return}case"wiped":{this.state.clear();return}case"reply":{let W=this.pending.get(X.id);if(!W)return;if(this.pending.delete(X.id),X.ok)W.resolve(X.result);else W.reject(new wX(X.status));return}default:return}}allocId(){let Z=this.nextId;return this.nextId+=1,Z}request(Z,X){let W=this.requireWorker();return new Promise((V,l)=>{if(this.pending.set(Z.id,{resolve:V,reject:l}),X&&X.length>0)W.postMessage(Z,X);else W.postMessage(Z)})}async requestStatus(Z,X){try{let W=await this.request(Z,X),V=c0(W);if(V!==void 0)return V;return 0}catch(W){if(W instanceof wX)return W.status;return 12}}serializeHost(Z){return{handle:Z.handle.href,label:Z.label,idx:Z.idx??0}}async setSeed(Z,X){await this.local.setSeed(Z,X),await this.loadSession(!1),this.clientState.emit();let W=this.allocId(),V=this.readyTimeoutMs;await new Promise((l,K)=>{let G=void 0,m=(R)=>{if(G!==void 0)clearTimeout(G);R()};this.pending.set(W,{resolve:(R)=>m(()=>l(R)),reject:(R)=>m(()=>K(R))}),G=setTimeout(()=>{this.pending.delete(W),K(Error(`${dZ} setSeed worker timeout after ${V}ms`))},V);try{let R=Z.spawnSyncWorker({id:W,persist:X?.persist});this.bindWorker(R)}catch(R){if(this.pending.delete(W),G!==void 0)clearTimeout(G);K(R instanceof Error?R:Error(String(R)))}});try{await this.pullRemoteXfer()}catch{}}async link(Z,X=!0){await this.local.link(Z,!1),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),await this.request({id:this.allocId(),op:"link",host:this.serializeHost(Z),connect:X})}async unlink(Z){if(await this.local.unlink(Z),await this.loadSession(this.cachedClientState.connected),this.clientState.emit(),!this.worker)return;await this.request({id:this.allocId(),op:"unlink",label:Z})}async hosts(){return this.local.hosts()}async connect(Z=!0,X=!0){if(!this.worker)return;await this.request({id:this.allocId(),op:"connect",listen:Z,sync:X})}async disconnect(){if(!this.worker)return;await this.request({id:this.allocId(),op:"disconnect"})}async insertRaw(Z){return this.local.insertRaw(Z)}async updateRaw(Z,X,W){return this.local.updateRaw(Z,X,W)}async insert(Z){return this.local.insert(Z)}async update(Z){return this.local.update(Z)}async delete(Z){return this.local.delete(Z)}async genEID(Z){return this.local.genEID(Z)}async sync(){if(!this.worker)return 0;return this.requestStatus({id:this.allocId(),op:"sync"})}async rebuild(Z){return this.scheduledSync.cancel(),await this.scheduledSync.flush(),this.requestStatus({id:this.allocId(),op:"rebuild",checkHost:Z?.checkHost})}async listMsgs(Z){return this.local.listMsgs(Z)}async countMsgs(Z){return this.local.countMsgs(Z)}async reconcile(Z,X){try{let W=await this.request({id:this.allocId(),op:"reconcile",hostLabel:Z,pull:X?.pull,push:X?.push,sync:X?.sync});if(!CG(W))return Y(12);return b(W)}catch(W){if(W instanceof wX&&W.status!==0)return Y(W.status);return Y(12)}}async msgcheck(){let Z=await this.request({id:this.allocId(),op:"msgcheck"});if(!(Z instanceof Uint8Array))throw Error(`${dZ} msgcheck: expected Uint8Array`);return Z}async entcheck(){let Z=await this.request({id:this.allocId(),op:"entcheck"});if(!(Z instanceof Uint8Array))throw Error(`${dZ} entcheck: expected Uint8Array`);return Z}async wipe(Z){if(await this.local.wipe(Z),this.worker)await this.request({id:this.allocId(),op:"wipe",msgs:Z?.msgs,ents:Z?.ents,meta:Z?.meta,seed:Z?.seed});await this.hydrateStateFromStore(this.store),this.clientState.emit(),this.xferState.emit()}async import(Z){let X=new Uint8Array(await Z.arrayBuffer());return this.requestStatus({id:this.allocId(),op:"import",bytes:X},[X.buffer])}async export(Z,X){try{let W=await this.request({id:this.allocId(),op:"export"});if(!(W instanceof Uint8Array))return 12;let V=new Blob([W.slice()]);return lW(V,Z),0}catch(W){if(W instanceof wX)return W.status;return 12}}}class wX extends Error{status;constructor(Z){super(`WorkerReplyError: ${z[Z]}`);this.status=Z;this.name="WorkerReplyError"}}function CG(Z){if(!Z||typeof Z!=="object")return!1;let X=Z;return X.msgcheck instanceof Uint8Array&&X.msgcheck.length===32&&typeof X.numBags==="number"&&typeof X.numDupes==="number"}function FG(Z){return Z}var LX="[DIPLOMATIC]";async function HW(Z){let X=Z.clock??new jZ;if(Z.worker===!0&&bG(Z)!==void 0)throw Error(`${LX} worker path requires IndexedDB on both sides; do not pass store (got a custom store)`);if(Z.worker!==!0){console.info(`${LX} sync on main thread `+"(no worker — app did not request a worker)");let l=await p0(Z.store);return dG(X,Z.state,l)}if(typeof Worker>"u")throw Error(`${LX} worker: true but Worker API is unavailable`);let W=await p0(void 0),V=await DX.open(Z.state,W,{readyTimeoutMs:Z.readyTimeoutMs,clock:X,syncDebounceMs:Z.syncDebounceMs});return console.info(`${LX} worker-mode client open (sync Worker starts on setSeed via Enclave)`),{client:V,mode:"worker",dispose:()=>{console.info(`${LX} terminating sync worker`),V.terminate()}}}function bG(Z){if("store"in Z)return Z.store;return}async function dG(Z,X,W){let V=new bX(Z,X,W,fW,IX);return{client:V,mode:"main",dispose:()=>{V.disconnect()}}}async function p0(Z){if(Z!==void 0)return Z;if(typeof indexedDB>"u")throw Error(`${LX} IndexedDB is unavailable; pass store explicitly (e.g. new MemoryStore(crypto))`);return wV(IX)}function kG(Z){let[X,W]=DV();return hW(()=>{async function V(){let K=await Z.clientState.get();W(K)}let l=Z.clientState.listen(V);return V(),()=>{l()}},[Z]),X}function TG(Z){let[X,W]=DV();return hW(()=>{async function V(){let K=await Z.xferState.get();W(K)}let l=Z.xferState.listen(V);return V(),()=>{l()}},[Z]),X}function IG(Z){hW(()=>{async function X(){try{if(!(await Z.clientState.get()).hasSeed)return;await Z.connect(),await Z.sync()}catch(K){console.error("reconnectAndSync failed",K)}}function W(){X()}function V(){if(typeof document<"u"&&document.visibilityState==="visible")X()}function l(){X()}if(globalThis.addEventListener("online",W),typeof document<"u")document.addEventListener("visibilitychange",V);return globalThis.addEventListener("focus",l),globalThis.addEventListener("pageshow",l),()=>{if(globalThis.removeEventListener("online",W),typeof document<"u")document.removeEventListener("visibilitychange",V);globalThis.removeEventListener("focus",l),globalThis.removeEventListener("pageshow",l)}},[Z])}function LG(Z={}){let X=Z.clock??new jZ,{seed:W,host:V,readyTimeoutMs:l}=Z,K=Z.worker===!0,G="store"in Z?Z.store:void 0,[m,R]=DV({stateMgr:sW});return hW(()=>{let J=!1,C;return(async()=>{let F=await WV();if(J)return;let d=ZW(F),k=K?await HW({state:d,clock:X,worker:!0,readyTimeoutMs:l}):await HW({state:d,clock:X,store:G,readyTimeoutMs:l});if(J){k.dispose();return}C=k.dispose;let{client:T,mode:I}=k;if(W)await T.setSeed(W);if(V)await T.link(V);if(J){C();return}R({client:T,entDB:F,stateMgr:d,mode:I,error:void 0})})().catch((F)=>{let d=F instanceof Error?F:Error(String(F));if(console.error("[DIPLOMATIC] useClient init failed",d),!J)R((k)=>({...k,client:void 0,error:d}))}),()=>{J=!0,C?.()}},[X,W,V,K,G,l]),m}import{use as cG,useEffect as y0,useRef as QG,useState as pG}from"react";function S0(Z,X,W){let[V,l]=pG();return y0(()=>{async function K(){let G=await W();l(G)}return K(),Z.on(X,K),()=>{Z.off(X,K)}},[Z,X,W]),V}function yG(Z,X,W){let V=QG(W());return y0(()=>{async function l(){V.current=W()}return Z.on(X,l),()=>{Z.off(X,l)}},[Z,X,W]),cG(V.current)}function z0(Z,X){return`${Z}:${X}`}class AV{queue=new Map;async enq(Z){for(let X of Z){let W=z0(X.host,X.seq);this.queue.set(W,X)}}async deq(Z,X){for(let W of X){let V=z0(Z,W);this.queue.delete(V)}}async list(){let Z=[];for(let X of this.queue.values())Z.push(X);return Z}async count(){return this.queue.size}async wipe(){this.queue.clear()}}function SG(Z,X){if(X.setLastSeq!==void 0)Z.lastSeq=X.setLastSeq;else if(X.lastSeq!==void 0&&X.lastSeq>Z.lastSeq)Z.lastSeq=X.lastSeq}class vV{hosts=new Map;async add(Z){let X=this.hosts.get(Z.label),W=X!==void 0&&X.handle===Z.handle&&(X.idx??0)===(Z.idx??0),V={...Z,lastSeq:W?X.lastSeq:0,clockOffset:W?X.clockOffset:void 0,subscription:W?X.subscription:void 0};this.hosts.set(Z.label,V)}async touch(Z,X){await this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.hosts.get(Z);if(!W)return;SG(W,X),this.hosts.set(Z,{...W})}async get(Z){return this.hosts.get(Z)}async set(Z,X){let W=this.hosts.get(Z);if(!W)return 13;return this.hosts.set(Z,{...W,...X}),0}async del(Z){this.hosts.delete(Z)}async list(){return this.hosts.values()}async wipe(){this.hosts.clear()}}class $V{crypto;messages=new Map;constructor(Z){this.crypto=Z}async add(Z){let X=[];for(let{key:W,data:V}of Z)this.messages.set(x(W),V),X.push(0);return X}async del(Z){for(let X of Z)this.messages.delete(x(X))}async get(Z){let X=this.messages.get(x(Z));if(X)return await EZ(Z,X,this.crypto);return}async has(Z){return this.messages.has(x(Z))}async list(Z){let X=Z?.apld,W=Z?.body!==!1,V=[];for(let[l,K]of this.messages){if(X!==void 0&&FX(K.apld)!==X)continue;let G=e(l);V.push(await EZ(G,K,this.crypto,{body:W}))}return V}async count(Z){if(Z===void 0)return this.messages.size;let X=0;for(let W of this.messages.values())if(FX(W.apld)===Z)X++;return X}async listKeys(){let Z=[];for(let X of this.messages.keys())Z.push(e(X));return Z}async last(Z){let X;for(let[W,V]of this.messages){if(n(Z,V.eid)===!1)continue;let l=e(W);if(X===void 0)X={hash:l,data:V};else if((V.ctr??0)>(X.data.ctr??0)||(V.ctr??0)===(X.data.ctr??0)&&(V.off??0)>(X.data.off??0))X={hash:l,data:V}}if(X)return await EZ(X.hash,X.data,this.crypto);return}async markApplied(Z){for(let X of Z){let W=this.messages.get(x(X));if(!W)continue;qZ(W,BZ)}}async markFailed(Z){for(let{key:X,err:W}of Z){let V=this.messages.get(x(X));if(!V)continue;qZ(V,LZ,W)}}async wipe(){this.messages.clear()}}class qV{#Z;#X;#W;constructor(Z){this.#X=Z}async save(Z,X){if(this.#W!==void 0){if(!await NW(this.#X,Z,this.#W))throw Error("[DIPLOMATIC] seed does not match this device's identity (local data was created with a different master seed)")}else this.#W=await zW(this.#X,Z);return this.#Z=Z,this.#Z}async load(){return this.#Z}async wipe(){this.#Z=void 0,this.#W=void 0}peekPin(){return this.#W===void 0?void 0:MW(this.#W)}}class fV{queue=new Map;async enq(Z,X){let W=this.queue.get(Z)||new Set;this.queue.set(Z,W);for(let V of X)W.add(YZ(V))}async deq(Z,X){let W=this.queue.get(Z);if(W)for(let V of X)W.delete(YZ(V))}async list(Z){let X=this.queue.get(Z);if(!X)return[];let W=[];for(let V of X)W.push(yX(V));return W}async count(){let Z=0;for(let X of this.queue.values())Z+=X.size;return Z}async wipe(){this.queue.clear()}}class N0{seed;hosts=new vV;uploads=new fV;downloads=new AV;messages;constructor(Z){this.seed=new qV(Z),this.messages=new $V(Z)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}class M0{singletonType;latest;latestOff=-1;emitter=new UZ;constructor(Z){this.singletonType=Z}async apply(Z){for(let X of Z){let W=new O(X.eid),[V,l]=W.readStruct(s);if(l!==0)continue;let K=new j;K.writeVarString(this.singletonType);let G=K.result();if(V.id.length===G.length&&V.id.every((m,R)=>m===G[R])){if(this.latest===void 0||X.off>this.latestOff)this.latestOff=X.off,this.latest=X.bod,this.emitter.emit(this.singletonType,null)}}return Z.map(()=>0)}clear=async()=>{return this.latest=void 0,this.latestOff=-1,this.emitter.emit(this.singletonType,null),0};notify=(Z)=>{for(let X of Z)if(X===this.singletonType)this.emitter.emit(this.singletonType,null)};refresh=async(Z)=>{this.notify([this.singletonType])};on=(Z,X)=>{this.emitter.addEventListener(Z,X)};off=(Z,X)=>{this.emitter.removeEventListener(Z,X)}}var oV={capable(){return Y0()},async createCred(Z){return IW(Z)},async write(Z,X,W){return uX(Z,X,W)},async read(Z,X){let[W,V]=await LW(Z,X);if(V!==0||W===void 0)return Y(V);return b(W.blob)}};class g0{#Z;#X;#W;#V;constructor(Z){if(this.#W=Z.rpId,this.#V=Z.rpName,Z.credId!==void 0)this.#X=Z.credId.slice()}get credId(){if(this.#X===void 0)return;return this.#X.slice()}setCredId(Z){this.#X=Z===void 0?void 0:Z.slice()}async save(Z,X){if(X?.persist!==!0)return this.#Z=Z,this.#Z;let[W,V]=await Z.persistToLargeBlob([],{rpId:this.#W,rpName:this.#V,credId:this.#X});if(V!==0||W===void 0)return Promise.reject(Error(`persistToLargeBlob status ${V}`));return this.#X=W,this.#Z=Z,this.#Z}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await ZZ.fromLargeBlob({rpId:this.#W,rpName:this.#V,credId:Z});if(W!==0||X===void 0)return Y(W);return this.#Z=X.enclave,b(X.enclave)}async wipe(){let Z=this.#X;if(Z!==void 0){let X=await ZZ.clearLargeBlob(Z,{rpId:this.#W});if(X!==0)return Promise.reject(Error(`clearLargeBlob status ${X}`))}this.#Z=void 0,this.#X=void 0}}function Vk(){return oV.capable()}export{IG as useSyncOnResume,yG as useStateWatcherSuspense,S0 as useStateWatcher,TG as useClientXferState,kG as useClientState,LG as useClient,VW as shouldEmitItemProgress,qZ as setApld,VV as revFromHead,MX as revFromEntity,tK as prfCapable,wV as openIDBStore,WV as openEntDB,HW as openDiplomaticClient,sW as nullStateManager,LK as nullEntDB,pl as normalizeTags,Vk as largeBlobCapable,IK as isTombstone,KV as isTerminalApplyFailure,pK as isPendingApply,v as isLiveEnt,QK as isApldState,$Z as idleProgress,yX as htob,fW as hostHTTPTransport,ZK as genSingletonEID,ZW as entStateManager,Tl as encodeEntRev,s as eidCodec,TW as defaultWebAuthnRpId,CX as defaultPeekProgressEvery,IX as crypto,kl as cmpBytes,KX as checksumSet,zX as checksumEntRevs,YZ as btoh,XK as btob64url,x as btob64,EW as b64urltob,e as b64tob,yZ as asSealedMasterKey,UV as asDHKEResp,hV as asDHKEReq,FX as apldFromStored,DX as WorkerClient,UZ as TypedEventEmitter,bX as SyncClient,z as Status,NX as StateManager,M0 as SingletonStateManager,aW as SEALED_MASTER_KEY_LEN,SW as PrfSeedStore,g0 as PasskeySeedStore,jX as PairRequest,N0 as MemoryStore,kZ as MASTER_SEED_LEN,uV as IDBStore,xW as IDBSeedStore,qW as HTTPTransport,XV as EntIDB,eX as EntDBMemory,j as Encoder,ZZ as Enclave,O as Decoder,cW as DEFAULT_PRF_SALT,jZ as Clock,gX as CachedEntDB,SZ as APLD_PENDING,LZ as APLD_ERROR,BZ as APLD_APPLIED};