@interncom/diplomatic 0.12.1 → 0.12.2
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.
package/dist/web/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function EV(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 Y0(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 R0=new TextEncoder,J0=50;function C0(Z,X,W){R0.encodeInto(Z,X.subarray(W))}function wV(Z,X,W){if(Z.length>J0)C0(Z,X,W);else Y0(Z,X,W)}var F0=4096;function gW(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>=F0)G+=String.fromCharCode(...K),K.length=0}if(K.length>0)G+=String.fromCharCode(...K);return G}var d0=new TextDecoder,b0=200;function c0(Z,X,W){let V=Z.subarray(X,X+W);return d0.decode(V)}function DV(Z,X,W){if(W>b0)return c0(Z,X,W);else return gW(Z,X,W)}class tZ{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 eZ=4294967295;function AV(Z,X,W){let V=W/4294967296,l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function oX(Z,X,W){let V=Math.floor(W/4294967296),l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function nX(Z,X){let W=Z.getInt32(X),V=Z.getUint32(X+4);return W*4294967296+V}function oV(Z,X){let W=Z.getUint32(X),V=Z.getUint32(X+4);return W*4294967296+V}var k0=-1,T0=4294967295,I0=17179869183;function p0({sec:Z,nsec:X}){if(Z>=0&&X>=0&&Z<=I0)if(X===0&&Z<=T0){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),oX(V,4,Z),W}}function L0(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 y0(Z){if(Z instanceof Date){let X=L0(Z);return p0(X)}else return null}function Q0(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=nX(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 M0(Z){let X=Q0(Z);return new Date(X.sec*1000+X.nsec/1e6)}var nV={type:k0,encode:y0,decode:M0};class ZX{static defaultCodec=new ZX;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(nV)}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 tZ(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 tZ(W,l)}}if(Z instanceof tZ)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 tZ(X,Z)}}function z0(Z){return Z instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&Z instanceof SharedArrayBuffer}function IX(Z){if(Z instanceof Uint8Array)return Z;else if(ArrayBuffer.isView(Z))return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength);else if(z0(Z))return new Uint8Array(Z);else return Uint8Array.from(Z)}var h0=100,S0=2048;class vX{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??ZX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.maxDepth=Z?.maxDepth??h0,this.initialBufferSize=Z?.initialBufferSize??S0,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 vX({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=EV(Z);this.ensureBufferSizeToWrite(5+W),this.writeStringHeader(W),wV(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=IX(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),AV(this.view,this.pos,Z),this.pos+=8}writeI64(Z){this.ensureBufferSizeToWrite(8),oX(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 AZ(Z,X){return new vX(X).encodeSharedRef(Z)}function fX(Z){return`${Z<0?"-":""}0x${Math.abs(Z).toString(16).padStart(2,"0")}`}var N0=16,g0=16;class xW{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(Z=N0,X=g0){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=gW(Z,X,W),K=Uint8Array.prototype.slice.call(Z,X,X+W);return this.store(K,l),l}}var HW="array",LX="map_key",fV="map_value",x0=(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 $V{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(Z){let X=this.getUninitializedStateFromPool();X.type=HW,X.position=0,X.size=Z,X.array=Array(Z)}pushMapState(Z){let X=this.getUninitializedStateFromPool();X.type=LX,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===HW){let W=Z;W.size=0,W.array=void 0,W.position=0,W.type=void 0}if(Z.type===LX||Z.type===fV){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 pX=-1,PW=new DataView(new ArrayBuffer(0)),H0=new Uint8Array(PW.buffer);try{PW.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 vV=RangeError("Insufficient data"),P0=new xW;class $X{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=PW;bytes=H0;headByte=pX;stack=new $V;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??ZX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.rawStrings=Z?.rawStrings??!1,this.maxStrLength=Z?.maxStrLength??eZ,this.maxBinLength=Z?.maxBinLength??eZ,this.maxArrayLength=Z?.maxArrayLength??eZ,this.maxMapLength=Z?.maxMapLength??eZ,this.maxExtLength=Z?.maxExtLength??eZ,this.keyDecoder=Z?.keyDecoder!==void 0?Z.keyDecoder:P0,this.mapKeyConverter=Z?.mapKeyConverter??x0}clone(){return new $X({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=pX,this.stack.reset()}setBuffer(Z){let X=IX(Z);this.bytes=X,this.view=new DataView(X.buffer,X.byteOffset,X.byteLength),this.pos=0}appendBuffer(Z){if(this.headByte===pX&&!this.hasRemaining(1))this.setBuffer(Z);else{let X=this.bytes.subarray(this.pos),W=IX(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 ${fX(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: ${fX(Z)}`);this.complete();let W=this.stack;while(W.length>0){let V=W.top();if(V.type===HW)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===LX){if(X==="__proto__")throw new WZ("The key __proto__ is not allowed");V.key=this.mapKeyConverter(X),V.type=fV;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=LX;continue Z}}return X}}readHeadByte(){if(this.headByte===pX)this.headByte=this.readU8();return this.headByte}complete(){this.headByte=pX}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: ${fX(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 vV;let W=this.pos+X,V;if(this.stateIsMapKey()&&this.keyDecoder?.canBeCached(Z))V=this.keyDecoder.decode(this.bytes,W,Z);else V=DV(this.bytes,W,Z);return this.pos+=X+Z,V}stateIsMapKey(){if(this.stack.length>0)return this.stack.top().type===LX;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 vV;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=oV(this.view,this.pos);return this.pos+=8,Z}readI64(){let Z=nX(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 iW(Z,X){return new $X(X).decode(Z)}class gZ{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 bZ{getter;static eventName="update";emitter;constructor(Z){this.getter=Z;this.emitter=new gZ}get=()=>this.getter();async emit(){let Z=await this.getter();queueMicrotask(()=>this.emitter.emit(bZ.eventName,Z))}listen(Z){return this.emitter.addEventListener(bZ.eventName,Z),()=>{this.emitter.removeEventListener(bZ.eventName,Z)}}}var xZ=64;var qV=32,HZ=8;var qX=32;var aV=30000,_V=512,z;((Q)=>{Q[Q.Success=0]="Success";Q[Q.InvalidSignature=3]="InvalidSignature";Q[Q.ClockOutOfSync=4]="ClockOutOfSync";Q[Q.UserNotRegistered=5]="UserNotRegistered";Q[Q.ServerMisconfigured=6]="ServerMisconfigured";Q[Q.MissingBody=7]="MissingBody";Q[Q.ExtraBodyContent=8]="ExtraBodyContent";Q[Q.MissingParam=9]="MissingParam";Q[Q.InvalidParam=10]="InvalidParam";Q[Q.InvalidRequest=11]="InvalidRequest";Q[Q.InternalError=12]="InternalError";Q[Q.NotFound=13]="NotFound";Q[Q.InvalidMessage=14]="InvalidMessage";Q[Q.NoChange=15]="NoChange";Q[Q.DatabaseClosed=16]="DatabaseClosed";Q[Q.StorageError=17]="StorageError";Q[Q.DatabaseError=18]="DatabaseError";Q[Q.HashMismatch=19]="HashMismatch";Q[Q.DecryptionError=20]="DecryptionError";Q[Q.NotImplemented=21]="NotImplemented";Q[Q.MissingSeed=22]="MissingSeed";Q[Q.OutOfBounds=23]="OutOfBounds";Q[Q.HostError=24]="HostError";Q[Q.CommunicationError=25]="CommunicationError";Q[Q.VarLimitExceeded=26]="VarLimitExceeded";Q[Q.InvalidResponse=27]="InvalidResponse";Q[Q.ConnectionClosed=28]="ConnectionClosed"})(z||={});function d(Z){return[Z,0]}function Y(Z){return[void 0,Z]}function i0(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 d(new Uint8Array([0]));if(X.length>8)return Y(26);return d(new Uint8Array(X))}function U0(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 d({value:W>0x1fffffffffffffn?W:Number(W),bytesRead:l-X})}if(V+=7,V>=56)return Y(26)}}class P{data;pos=0;constructor(Z){this.data=Z}static async fromResponse(Z){let X=await Z.arrayBuffer(),W=new Uint8Array(X);return new P(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,d(Z)}readDate(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return d(new Date(Z))}readVarInt(){let[Z,X]=U0(this.data,this.pos);if(X!==0)return Y(X);this.pos+=Z.bytesRead;let W=Z.value;return d(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 d(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,d(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 d(X)}readBytesSeq(Z){let X=[];while(!this.done()){let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);X.push(W)}return d(X)}done(){return this.pos>=this.data.length}consumed(){return this.pos}}class i{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]=i0(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)}writeBytes(Z){this.parts.push(Z)}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}*scan(){for(let Z of this.parts)yield Z}}async function UW(Z,X){let W=new i,V=W.writeDate(X);if(V!==0)return Y(V);let l=W.result(),K=await Z.sign(l);return d({pubKey:Z.publicKey,sig:K,timestamp:X})}async function PZ(Z,X,W){let V=W.now().getTime(),l=Z.timestamp.getTime();if(Math.abs(V-l)>aV)return 4;let G=new i;G.writeDate(Z.timestamp);let m=G.result();if(!await X.checkSigEd25519(Z.sig,m,Z.pubKey))return 3;return 0}var _={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 d({id:X,ts:V})}};function XX(Z){let X=new i,W=X.writeStruct(_,Z);if(W!==0)return Y(W);let V=X.result();return d(V)}async function u0(Z){return XX({id:Z,ts:new Date(0)})}var YZ={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 P(X),[,l]=_.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[b,c]=Z.readBytes(qX);if(c!==0)return Y(c);F=b}return d({eid:X,off:K,ctr:m,len:J,hsh:F})}};function GZ(Z){return Array.from(Z).map((W)=>W.toString(16).padStart(2,"0")).join("")}function iZ(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 e(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 t;if(typeof Uint8Array.fromBase64==="function")t=(Z)=>Uint8Array.fromBase64(Z);else t=(Z)=>Uint8Array.from(atob(Z),(X)=>X.charCodeAt(0));function uW(Z){return g(Z).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function OW(Z){let X=Z.length%4===0?"":"=".repeat(4-Z.length%4),W=Z.replace(/-/g,"+").replace(/_/g,"/")+X;return t(W)}function yX(Z,X){let W=new Uint8Array(Z.length+X.length);return W.set(Z,0),W.set(X,Z.length),W}function sV(Z,X,W){return W.checkSigEd25519(Z.sig,Z.headCph,X)}async function rV(Z,X,W,V){let l;if(Z.bod&&Z.len>0)l=await W.blake3(Z.bod);let K=new i,G=YZ.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),b=await X.sign(C);return d({sig:b,kdm:R,headCph:C,bodyCph:F})}async function BW(Z,X,W,V,l){let K=new P(Z),[G,m]=YZ.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 b=await V.blake3(R);if(!e(b,G.hsh))return Y(19)}let F=l??await V.blake3(Z);return d({msgHead:G,bod:R,headHash:F})}class pZ{now(){return new Date}}function tV(Z,X,W,V){let l=X.getTime()-Z.getTime(),K=W.getTime()-V.getTime();return(l+K)/2}var QX={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 d({quota:X,usage:V})}};var jW={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(QX,X.subscription.stat);if(G!==0)return G;let m=Z.writeStruct(QX,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[b,c]=Z.readStruct(QX);if(c!==0)return Y(c);let[k,T]=Z.readStruct(QX);if(T!==0)return Y(T);return d({status:V,timeRcvd:l,timeSent:G,subscription:{term:R,elapsed:C,stat:b,dyn:k}})}};var EW={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 d({headCph:X,seq:V})}};var mZ={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(qV);if(W!==0)return Y(W);let[V,l]=Z.readBytes(xZ);if(l!==0)return Y(l);let[K,G]=Z.readDate();if(G!==0)return Y(G);return d({pubKey:X,sig:V,timestamp:K})}};var eV={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(mZ,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(mZ);if(m!==0)return m;let R=await PZ(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[b,c]=X.readVarInt();if(c!==0)return c;if(!X.done())return 8;let[k,T]=await K.listHeads(J,b);if(T!==0)return T;return W.writeStructs(EW,k)},decodeResp(Z){return Z.readStructs(EW)}};var wW={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 d({seq:X,bodyCph:V})}};var Zl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(mZ,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(mZ);if(m!==0)return m;let R=await PZ(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 b=[];while(!X.done()){let[T,I]=X.readVarInt();if(I!==0)return I;b.push(T)}console.info(`PULL: ${b.length} bags`);let[c,k]=await K.getBodies(J,b);if(k!==0)return k;if(!c)return 17;for(let{seq:T,bodyCph:I}of c){let y={seq:T,bodyCph:I},L=W.writeStruct(wW,y);if(L!==0)return L}return 0},decodeResp(Z){return Z.readStructs(wW)}};var DW={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(xZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(HZ);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 d({sig:X,kdm:V,headCph:K,bodyCph:m})}};var aX={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 d({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(xZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(HZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return d({sig:X,kdm:V,headCph:K})}};var sX={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 d({idx:X,status:K});let[G,m]=Z.readVarInt();if(m!==0)return Y(m);return d({idx:X,status:K,seq:G})}};var Xl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(mZ,W);if(K!==0)return K;let G=l.writeStructs(DW,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(mZ);if(R!==0)return R;let J=await PZ(m,l,V);if(J!==0)return J;let{pubKey:C}=m,[F,b]=await K.hasUser(C);if(b!==0)return b;if(!F)return 5;let[c,k]=X.readStructs(DW);if(k!==0)return k;console.info(`PUSH: ${c.length} bags`);let T=[],I=[];for(let p=0;p<c.length;p++){let S=c[p];if(!await sV(S,C,l)){let B={idx:p,status:3},O=W.writeStruct(sX,B);if(O!==0)return O;continue}T.push(p),I.push(S)}let[y,L]=await K.setBags(C,I);if(L!==0)return L;if(!y||y.length!==I.length)return 17;let M=[];for(let p=0;p<I.length;p++){let S=I[p],H=T[p],B=y[p],O=new i,U=O.writeStruct(_X,S);if(U!==0)return U;let E=O.result(),Q={seq:B,headCph:E};if(c.length===1&&S.bodyCph.length<=_V)Q.bodyCph=S.bodyCph;M.push(Q);let A={idx:H,status:0,seq:B},n=W.writeStruct(sX,A);if(n!==0)return n}if(M.length>0){let p=new i,S=p.writeStructs(aX,M);if(S!==0)return S;let H=p.result();await Promise.resolve(G.push(C,H))}return 0},decodeResp(Z){return Z.readStructs(sX)}};var Wl={async encodeReq(Z,X,W,V,l){return l.writeStruct(mZ,W)},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(mZ);if(m!==0)return m;let R=await PZ(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 d(void 0)}};class AW{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 i;K.writeStruct(mZ,Z);let G=K.result(),m=GZ(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 s={user:{path:"/user",endpoint:Wl,name:0},push:{path:"/push",endpoint:Xl,name:2},peek:{path:"/peek",endpoint:eV,name:1},pull:{path:"/pull",endpoint:Zl,name:3}},O0={0:s.user,2:s.push,1:s.peek,3:s.pull},aY={[s.user.path]:s.user,[s.push.path]:s.push,[s.peek.path]:s.peek,[s.pull.path]:s.pull};class oW{url;listener;constructor(Z){this.url=Z;this.listener=new AW(Z)}async call(Z,X){let{path:W}=O0[Z],V=new URL(W,this.url);try{return await B0(V,X)}catch{return Y(25)}}}var rX=(Z)=>{return new oW(Z.handle)};async function B0(Z,X){let W=await fetch(Z,{method:"POST",body:X.result().slice()});if(!W.ok)return Y(24);let V=await P.fromResponse(W);return d(V)}class tX{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 UW(G,m);if(J!==0)return Y(J);let C=new i,F=await l.encodeReq(this,G,R,X,C);if(F!==0)return Y(F);let b=W.now(),[c,k]=await V.call(K,C),T=W.now();if(k!==0)return Y(k);let[I,y]=c.readStruct(jW);if(y!==0)return Y(y);if(I.status!==0)return Y(I.status);let M={clockOffset:tV(b,I.timeRcvd,I.timeSent,T),subscription:I.subscription},p=await this.updateHostMeta(M);if(p!==0)return Y(p);return l.decodeResp(c)}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 rV(Z,V,X,W)};register=()=>this.call(s.user,[]);peek=(Z)=>this.call(s.peek,[Z]);push=(Z)=>this.call(s.push,Z);pull=(Z)=>this.call(s.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 UW(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 nW={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(xZ);if(C!==0)return Y(C);return d({lbl:X,idx:V,num:K,hsh:m,sig:J})}};var vW={encode(Z,X){let W=Z.writeStruct(nW,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(nW);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 d({head:X,indexEnc:V,bodyEnc:K})}};var fW={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(HZ);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 d({kdm:X,headCph:V,lenBody:K,offBody:m})}};async function Vl(Z,X,W,V,l){let K=await l.deriveIdentity(Z,X),G=new i,m=new i,R=0,J=0;for(let y of W){let L=new i,M=L.writeStruct(YZ,y.head);if(M!==0)return Y(M);let p=L.result(),S=await K.kdmFor(p),H=l.deriveCipher(S,"encrypt"),B=await H.encrypt(p),O=y.body?await H.encrypt(y.body):new Uint8Array(0),U=y.head.len>0&&y.head.hsh!==void 0?O.length:0,E={kdm:S,headCph:B,lenBody:U,offBody:U>0?J:void 0},Q=G.writeStruct(fW,E);if(Q!==0)return Y(Q);if(y.body)m.writeBytes(O),J+=O.length;R++}let C=m.result(),F=G.result(),b=await V.blake3(F),c=await K.sign(b),k={lbl:Z,idx:X,num:R,hsh:b,sig:c},T=new i;T.writeStruct(vW,{head:k,indexEnc:F,bodyEnc:C});let I=T.result();return d(I)}async function ll(Z,X,W){let[V,l]=vW.decode(new P(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(!e(C,K.hsh))return Y(19);let F=new P(G),b=[];for(let k=0;k<K.num;k++){let[T,I]=F.readStruct(fW);if(I!==0)return Y(I);b.push(T)}if(b.length!==K.num)return Y(14);let c=[];for(let k of b){let T=W.deriveCipher(k.kdm,"decrypt"),I;try{I=await T.decrypt(k.headCph)}catch{return Y(20)}let[y,L]=YZ.decode(new P(I));if(L!==0)return Y(L);let M;if(k.lenBody>0&&k.offBody!==void 0){if(y.hsh===void 0)return Y(14);let p=m.slice(k.offBody,k.offBody+k.lenBody);try{M=await T.decrypt(p)}catch{return Y(20)}let S=await X.blake3(M);if(!e(S,y.hsh))return Y(19)}c.push({head:y,body:M})}return d(c)}async function Kl({now:Z,bod:X,crypto:W}){let V=await W.genRandomBytes(8),l=new i,K=l.writeStruct(_,{id:V,ts:Z});if(K!==0)return Y(K);let G=l.result();return eX({now:Z,eid:G,ctr:0,bod:X,crypto:W})}async function eX({now:Z,eid:X,ctr:W,bod:V,crypto:l}){let K=new P(X),[G,m]=_.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 d({eid:X,off:R,ctr:W,len:C,hsh:J})}function Gl(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 WX(Z,X){let W=Array.from(Z);W.sort(Gl);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 ml(Z){let X=new i,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 d(X.result())}async function MX(Z,X){let W=[];for(let V of Z){let[l,K]=ml(V);if(K!==0||!l)return Y(K);W.push(l)}return d(await WX(W,X))}var AR=Symbol("MasterSeed"),oR=Symbol("SealedMasterKey"),dZ=32,$W=24+dZ+16;function ZZ(Z){if(Z.byteLength!==dZ)return Y(10);return d(Z)}function LZ(Z){if(Z.byteLength!==$W)return Y(10);return d(Z)}var vR=Symbol("EntityID");function Yl(Z){return"type"in Z}var fR=Symbol("DerivationSeed"),$R=Symbol("PublicKey"),qR=Symbol("PrivateKey"),aR=Symbol("HostSpecificKeyPair"),_R=Symbol("Hash");function j0(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 E0(Z){if(!Z.bod||Z.bod.length===0){let V={off:Z.off,ctr:Z.ctr,eid:Z.eid};return d(V)}let X=iW(Z.bod);if(j0(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 d(W)}class zX{applier;emitter=new gZ;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]=E0(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 qW={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 f="entities",ZW="entity_type_created_at",_W="entity_type_updated_at",sW="entity_type_group_id",rW="entity_type_parent_id",VX="entity_tags",Rl="db",Jl=13;function w0(Z){return"typ"in Z}function D0(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 A0(Z){if(!D(Z))return{eid:g(Z.eid),upd:Z.updatedAt,...Z.ctr!==0?{ctr:Z.ctr}:{}};return D0(Z)}function lX(Z){return{body:Z.bod,createdAt:Z.crd,updatedAt:Z.upd,ctr:Z.ctr??0,type:Z.typ,eid:t(Z.eid),gid:Z.gid,pid:Z.pid?t(Z.pid):void 0,...Z.tgs!==void 0?{tags:Z.tgs}:{}}}function aW(Z){if(w0(Z))return lX(Z);return{eid:t(Z.eid),updatedAt:Z.upd,ctr:Z.ctr??0}}class tW{db;opening;async init(){await this.ensureDb()}async ensureDb(){if(this.db)return this.db;if(this.opening)return this.opening;return this.opening=n0().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(f,"readwrite"),K=l.objectStore(f);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),b={op:C,index:J},c=R.get(F);if(c)c.push(b);else R.set(F,[b])}for(let[J,C]of R){if(C.length<1)continue;let F=K.get(J);F.onsuccess=()=>{let b=F.result,c=b?aW(b):void 0,k=!1;for(let{op:T,index:I}of C){let[y,L]=KX(c,T);if(L!==0){m[I]=L;continue}if(y===void 0){m[I]=12;continue}k=!0;for(let M of GX(c,y))X.add(M);c=y}if(k)W.push(C[0].op.eid);if(c){let T=K.put(A0(c));T.onerror=(I)=>{I.preventDefault();for(let{index:y}of C)m[y]=18}}},F.onerror=()=>{for(let{index:b}of C)m[b]=18}}})};async clear(){let Z;try{Z=await this.ensureDb()}catch{return 16}let X=Z.transaction(f,"readwrite"),W=X.objectStore(f);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(f,"readonly").objectStore(f);return new Promise((K)=>{let G=l.get(W);G.onsuccess=()=>{let m=G.result;if(!m)K(d(void 0));else K(d(aW(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||!D(X))return d(void 0);return d(X)}async getAllOfTypeUpdatedBetween(Z,X,W){let V;try{V=await this.ensureDb()}catch{return Y(16)}let K=V.transaction(f,"readonly").objectStore(f).index(_W);return new Promise((G)=>{let m=K.getAll(IDBKeyRange.bound([Z,X],[Z,W]));m.onsuccess=()=>{let R=m.result;G(d(R.map(lX)))},m.onerror=()=>G(Y(18))})}async getGroupMembers(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(f,"readonly").objectStore(f).index(sW);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z,X]));G.onsuccess=()=>{let m=G.result;K(d(m.map(lX)))},G.onerror=()=>K(Y(18))})}async getAllOfType(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(f,"readonly").objectStore(f).index(ZW);return new Promise((l)=>{let K=V.getAll(IDBKeyRange.bound([Z],[Z,[]]));K.onsuccess=()=>{let G=K.result;l(d(G.map(lX)))},K.onerror=()=>l(Y(18))})}async getByTag(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(f,"readonly").objectStore(f).index(VX);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only(X));G.onsuccess=()=>{let R=G.result.filter((J)=>J.typ===Z).map(lX);K(d(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(f,"readonly").objectStore(f).index(rW);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z.type,W]));G.onsuccess=()=>{let R=G.result.map(lX);K(d(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 d(X)}async countEntities({type:Z}){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(f,"readonly").objectStore(f).index(ZW);return new Promise((l)=>{let K=IDBKeyRange.bound([Z],[Z,[]]),G=V.count(K);G.onsuccess=()=>l(d(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(f,"readonly").objectStore(f),l=[];return new Promise((K)=>{let G=V.openCursor();G.onsuccess=()=>{let m=G.result;if(m){let R=m.value;l.push(hX(aW(R))),m.continue()}else MX(l,Z).then(K)},G.onerror=()=>K(Y(18))})}}function o0(Z,X){if(!Z.objectStoreNames.contains(f))Z.createObjectStore(f,{keyPath:"eid",autoIncrement:!1});let W=X.objectStore(f);if(!W.indexNames.contains(ZW))W.createIndex(ZW,["typ","crd"],{unique:!1});if(!W.indexNames.contains(_W))W.createIndex(_W,["typ","upd"],{unique:!1});if(!W.indexNames.contains(sW))W.createIndex(sW,["typ","gid"],{unique:!1});if(!W.indexNames.contains(rW))W.createIndex(rW,["typ","pid"],{unique:!1});if(W.indexNames.contains(VX)){if(W.index(VX).keyPath!=="tgs")W.deleteIndex(VX)}if(!W.indexNames.contains(VX))W.createIndex(VX,"tgs",{unique:!1,multiEntry:!0})}function n0(){return new Promise((Z,X)=>{let W=indexedDB.open(Rl,Jl);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!l){X(Error("Transaction is null during EntDB upgrade"));return}try{o0(V,l)}catch(K){X(K instanceof Error?K:Error(String(K)))}},W.onblocked=()=>{console.warn(`[DIPLOMATIC] EntDB IDB upgrade blocked (${Rl} → v${Jl}); waiting for other connections to close`)},W.onsuccess=()=>Z(W.result),W.onerror=()=>X(W.error??Error("EntDB IndexedDB open failed"))})}async function Cl(){let Z=new tW;return await Z.init(),Z}class XW{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&&D(W))this.unindex(X,W);if(this.ents.set(X,Z),D(Z))this.index(X,Z)}del(Z){let X=this.ents.get(Z);if(X===void 0)return;if(D(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]=KX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of GX(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 d(W)}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!D(X))return d(void 0);return d(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 d(this.bucketList(this.byTypePid.get(Z)?.get(G)))}if(X!==void 0)return d(this.bucketList(this.byTypeGid.get(Z)?.get(X)));if(V!==void 0)return d(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 d(G)}return d(this.bucketList(this.byType.get(Z)))}let K=[];if(W!==void 0){for(let G of this.ents.values())if(D(G)&&G.type===Z&&G.pid&&e(G.pid,W))K.push(G)}else if(X!==void 0){for(let G of this.ents.values())if(D(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(D(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(D(G)&&G.type===Z&&G.updatedAt>=l.start&&G.updatedAt<=l.end)K.push(G)}else for(let G of this.ents.values())if(D(G)&&G.type===Z)K.push(G);return d(K)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return d(X)}async countEntities({type:Z}){if(this.useIndex)return d(this.byType.get(Z)?.size??0);let X=0;for(let W of this.ents.values())if(D(W)&&W.type===Z)X+=1;return d(X)}async checksum(Z){let X=[];for(let W of this.ents.values())X.push(hX(W));return MX(X,Z)}}async function eW(Z){let X=await Cl();if(Z?.cache===!1)return X;return new SX(X,void 0,{indexes:Z?.indexes})}class SX{mem;durable;warmed=new Set;listeners=new Set;chain=Promise.resolve();constructor(Z,X,W){if(this.durable=Z,this.mem=new XW(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=_0(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||!v0(K,G)){if(D(G))X.add(G.type);if(K!==void 0&&D(K))X.add(K.type)}}else if(K!==void 0){if(this.mem.del(l),D(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||a0(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 d(W)})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!D(X))return d(void 0);return d(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 v0(Z,X){if(D(Z)!==D(X))return!1;if(Z.ctr!==X.ctr)return!1;if(Z.updatedAt.getTime()!==X.updatedAt.getTime())return!1;if(!e(Z.eid,X.eid))return!1;if(!D(Z)||!D(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(!$0(Z.pid,X.pid))return!1;if(!f0(Z.tags,X.tags))return!1;return q0(Z.body,X.body)}function f0(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 $0(Z,X){if(Z===void 0&&X===void 0)return!0;if(Z===void 0||X===void 0)return!1;return e(Z,X)}function q0(Z,X){if(Object.is(Z,X))return!0;if(Z instanceof Uint8Array&&X instanceof Uint8Array)return e(Z,X);if(Z instanceof Date&&X instanceof Date)return Z.getTime()===X.getTime();try{return e(AZ(Z),AZ(X))}catch{return!1}}function a0(Z,X){let W=Z.updatedAt.getTime(),V=X.updatedAt.getTime();if(W!==V)return W>V;return Z.ctr>X.ctr}function _0(Z,X){let W=new Set,V=[];for(let l of X){let K=g(l.eid),G=Z.ents.get(K),[m,R]=KX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of GX(G,m))W.add(J);Z.put(m),V.push(0)}return{stats:V,types:W}}function WW(Z){if(Z instanceof SX){let X=new zX((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 zX((X)=>Z.apply(X),()=>Z.clear())}function D(Z){return"type"in Z}function s0(Z){return!D(Z)}function Fl(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 hX(Z){return{eid:Z.eid,ctr:Z.ctr,updatedAt:Z.updatedAt}}function ZV(Z){let X=new P(Z.eid),[W,V]=X.readStruct(_);if(V!==0)return Y(V);return d({eid:Z.eid,ctr:Z.ctr,updatedAt:new Date(W.ts.getTime()+Z.off)})}function KX(Z,X){let W=new P(X.eid),[V,l]=W.readStruct(_);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(Yl(X)){let G=Fl(X.tags);return d({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 d({eid:X.eid,updatedAt:K,ctr:X.ctr})}function GX(Z,X){let W=new Set;if(Z!==void 0&&D(Z))W.add(Z.type);if(D(X))W.add(X.type);return[...W]}var r0={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 VW{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 lW=100;class NX{timer=null;delayMs;work;tail=new VW;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 dl(Z){let X=new P(Z.eid),[W,V]=_.decode(X);if(V!==0)return;return W.ts.getTime()+Z.off}function t0(Z,X){let W=dl(Z),V=dl(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 mX(Z,X){return Z.slice().sort((W,V)=>t0(X(W),X(V)))}var oZ={phase:"idle"},YX=50;function KW(Z,X,W){if(Z<=0||X<=0)return!1;if(Z===1||Z===X)return!0;return Z%W===0}function GW(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 bl(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 XV(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 mW(Z,X,W,V){let l=new P(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"),b;try{b=await F.decrypt(J)}catch{return Y(20)}return d({kdm:R,headEnc:b})}var yZ="f",UZ="t",cZ="e";function e0(Z){return Z===yZ||Z===UZ||Z===cZ}function RX(Z){if(Z===!0||Z===UZ)return UZ;if(Z===cZ)return cZ;return yZ}function ZK(Z){return RX(Z.apld)===yZ}function WV(Z){return Z!==0&&Z!==15&&Z!==18&&Z!==17}function nZ(Z,X,W){if(Z.apld=X,X===cZ&&W!==void 0)Z.err=W;else delete Z.err}async function uZ(Z,X,W,V){let l=V?.body!==!1,K=RX(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===cZ&&X.err!==void 0)C.err=X.err;return C}var VV=1048576,lV=1048576,kl=64;function XK(Z){return Z.sig.length+Z.kdm.length+Z.headCph.length+Z.bodyCph.length}async function WK(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,b)=>F-b);for(let F of C)if(F===R+1)R=F;if(R>J)await X.hosts.touch(W,R)}return 0}async function cl(Z,X){if(X.length<1)return d([]);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 d(G)}async function VK(Z,X,W,V){if(V.length<1)return d({parts:[],hashes:[]});let l=[],K=[],G=[],m=new Map;for(let{dl:J,bodyCph:C}of V){let{head:F,kdm:b,seq:c,host:k}=J,[T,I]=await Tl(J,W);if(I!==0||!T){let U=m.get(k)??[];U.push(c),m.set(k,U);continue}let{headEnc:y,headEncHash:L}=T,M=X.deriveCipher(b,"decrypt"),[p,S]=await BW(y,C,M,W,L);if(S!==0||!p){let U=m.get(k)??[];U.push(c),m.set(k,U);continue}let H={head:F,body:p.bod},B=p.headHash;G.push({key:B,data:Ll(H)}),l.push(H),K.push(B);let O=m.get(k)??[];O.push(c),m.set(k,O)}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 d({parts:l,hashes:K})}async function Tl(Z,X){let W=Z.headEnc;if(!W){let l=new i,K=l.writeStruct(YZ,Z.head);if(K!==0)return Y(K);W=l.result()}if(Z.headEncHash)return d({headEnc:W,headEncHash:Z.headEncHash});let V=await X.blake3(W);return d({headEnc:W,headEncHash:V})}async function Il(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 Tl(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 KV({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 b=C.length,c=G??YX,k=m??kl;if(K&&b>0)K({phase:"peek",host:V.label,done:0,total:b});let T=0,I=await XV(C,k,async(L)=>{let[M,p]=await mW(L,R.publicKey,W,l),S;if(p!==0||!M)S={ok:!1,seq:L.seq,stat:p};else{let H=await l.blake3(M.headEnc);S={ok:!0,seq:L.seq,kdm:M.kdm,headEnc:M.headEnc,headEncHash:H}}if(T+=1,K&&KW(T,b,c))K({phase:"peek",host:V.label,done:T,total:b});return S}),y=new Set;for(let L of I){if(!L.ok){console.error("peek: decrypting item head",L.stat);continue}let M=g(L.headEncHash);if(await X.messages.has(L.headEncHash)){console.info("peek: local msg; skip download, deq upload"),await X.uploads.deq(V.label,[L.headEncHash]),await X.downloads.deq(V.label,[L.seq]);continue}if(y.has(M)){await X.downloads.deq(V.label,[L.seq]);continue}let S=new P(L.headEnc),[H,B]=S.readStruct(YZ);if(B!==0){console.error("peek: reading item head",B);continue}y.add(M),J.push({kdm:L.kdm,head:H,seq:L.seq,host:V.label,headEnc:L.headEnc,headEncHash:L.headEncHash})}if(await X.downloads.enq(J),C.length>0){let L=Math.max(...C.map((M)=>M.seq));await X.hosts.recordStats(V.label,{lastSeq:L})}if(K)K({phase:"peek",host:V.label,done:b,total:b});return 0}async function pl({conn:Z,store:X,host:W,maxPushBytes:V,onProgress:l}){let K=V??VV,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,b=async()=>{if(J.length<1)return 0;let c=J.length,k=await WK(Z,X,W.label,J,C);if(J=[],C=[],F=0,k===0){if(R+=c,l)l({phase:"push",host:W.label,done:R,total:m})}return k};for(let c of G){let k=await X.messages.get(c);if(!k){R+=1;continue}let T={...k.head,bod:k.body},[I,y]=await Z.seal(T);if(y!==0)return y;if(!I)return 12;let L=XK(I);if(J.length>0&&F+L>K){let M=await b();if(M!==0)return M}if(J.push(I),C.push(c),F+=L,F>=K){let M=await b();if(M!==0)return M}}return b()}async function GV({conn:Z,store:X,enclave:W,host:V,crypto:l,maxPullBytes:K,onProgress:G},m){let R=K??lV,J=await X.downloads.list(),C=Array.from(J).filter((I)=>I.host===V.label);if(C.length<1)return 15;let F=mX(C,(I)=>I.head),b=bl(F,(I)=>I.head.len,R),c=F.length,k=0;if(G)G({phase:"pull",host:V.label,done:0,total:c});let T=cl(Z,b[0]);for(let I=0;I<b.length;I++){let[y,L]=await T;if(L!==0||!y)return L;if(k+=b[I].length,G)G({phase:"pull",host:V.label,done:k,total:c});let M=b[I+1];if(M)T=cl(Z,M);if(G)G({phase:"open",host:V.label,done:k,total:c});let p=mX(y,(H)=>H.dl.head),[,S]=await VK(X,W,l,p);if(S!==0)return S;if(m){if(G)G({phase:"exec",host:V.label,done:k,total:c});await m()}}return 0}function Ll({head:Z,body:X}){let W={eid:Z.eid,body:X,apld:yZ};if(Z.off!==0)W.off=Z.off;if(Z.ctr!==0)W.ctr=Z.ctr;return W}async function yl(Z,{conn:X,store:W,enclave:V,host:l,crypto:K,onProgress:G},m){let R=l.label,J=await X.identity(),C=new P(Z),[F,b]=C.readStructs(aX);if(b!==0){console.error("Failed decoding notif",z[b]);return}let c=!1,T=(await W.hosts.get(R))?.lastSeq,I=[],y=!1;for(let p of F){let[S,H]=await mW({seq:p.seq,headCph:p.headCph},J.publicKey,V,K);if(H!==0){console.error("Failed decrypting notif",z[H]);continue}let B=await K.blake3(S.headEnc);if(await W.messages.has(B))continue;let O=new P(S.headEnc),[U,E]=O.readStruct(YZ);if(E!==0){console.error("Failed to parse head",z[E]);continue}if(!p.bodyCph&&U.len>0)y=!0,await W.downloads.enq([{seq:p.seq,host:R,kdm:S.kdm,head:U,headEnc:S.headEnc,headEncHash:B}]);else I.push({...S,head:U,bodyCph:p.bodyCph,headEncHash:B});if(T===void 0||p.seq!==T+1)console.log("out of seq",p.seq,T),c=!0;else T=p.seq}if(T!==void 0)await W.hosts.touch(l.label,T);let L=[];for(let p of I){let S=V.deriveCipher(p.kdm,"decrypt"),[H,B]=await BW(p.headEnc,p.bodyCph,S,K);if(B!==0){console.error("Failed to open body",z[B]);continue}L.push({key:p.headEncHash,data:Ll({head:p.head,body:H.bod})})}let M=await W.messages.add(L);for(let p=0;p<M.length;p++){let S=M[p];if(S!==0&&S!==15)console.error("ERR storing",z[S],"for message",p)}if(G&&L.length>0)G({phase:"open",host:l.label,done:L.length,total:L.length});if(c||y||L.length>0)m()}async function mV(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,b=await l.identity(),[c,k]=await l.peek(0);if(k!==0)return Y(k);let T=c.length,I=C??YX,y=F??kl;if(J&&T>0)J({phase:"peek",host:m.label,done:0,total:T});let L=0,M=await XV(c,y,async(x)=>{let[j,u]=await mW(x,b.publicKey,G,R),w;if(u!==0||!j)w={ok:!1,seq:x.seq,stat:u};else{let N=await R.blake3(j.headEnc);w={ok:!0,seq:x.seq,kdm:j.kdm,headEnc:j.headEnc,headEncHash:N}}if(L+=1,J&&KW(L,T,I))J({phase:"peek",host:m.label,done:L,total:T});return w}),p=new Map;for(let x of M){if(!x.ok)continue;let j=g(x.headEncHash),u=p.get(j);if(u)u.count+=1;else p.set(j,{hash:x.headEncHash,count:1,sample:x})}let S=0,H=[];for(let x of p.values()){if(x.count>1)S+=x.count-1;H.push(x.hash)}let B=c.length,O=p.size,U=await WX(H,R),E=[],Q=0;for(let x of p.values()){if(await K.messages.has(x.hash)){await K.uploads.deq(m.label,[x.hash]);continue}if(Q+=1,!W)continue;let u=x.sample,w=new P(u.headEnc),[N,q]=w.readStruct(YZ);if(q!==0){console.error("reconcile: reading msg header",q);continue}E.push({kdm:u.kdm,head:N,seq:u.seq,host:m.label,headEnc:u.headEnc,headEncHash:u.headEncHash})}if(E.length>0)await K.downloads.enq(E);let A=0;if(V){let x=await K.messages.listKeys(),j=new Set(p.keys()),u=[];for(let w of x)if(!j.has(g(w)))A+=1,u.push(w);if(u.length>0)await K.uploads.enq(m.label,u)}else{let x=await K.messages.listKeys(),j=new Set(p.keys());for(let u of x)if(!j.has(g(u)))A+=1}let n=c.length>0?Math.max(...c.map((x)=>x.seq)):0;if(await K.hosts.recordStats(m.label,{setLastSeq:n}),J)J({phase:"peek",host:m.label,done:T,total:T});return d({msgcheck:U,numBags:B,uniqueMsgs:O,numDupes:S,missingLocal:Q,missingHost:A})}class vZ{clock;state;store;transport;crypto;forceSkewHandlingByDefault;onScheduleSync;connections=new Map;applyChain=Promise.resolve();syncRuns=new VW;clientState;xferState;maxPushBytes;maxPullBytes;peekProgressEvery=YX;lastProgress=oZ;scheduledSync;constructor(Z,X,W,V,l,K=!0,G=VV,m=lV,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 bZ(()=>this.getClientState()),this.xferState=new bZ(()=>this.getXferState()),this.scheduledSync=new NX(lW,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 i;m.writeStruct(YZ,K);let R=m.result(),J=await this.crypto.blake3(R),C={eid:K.eid,body:G,apld:yZ};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 Il(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:yZ});if(Z.length<1)return[];let X=mX(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&&WV(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 Kl({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 d(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 eX({now:l,eid:Z.eid,ctr:K,bod:X,crypto:V});if(m!==0)return Y(m);return d({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 P(Z.eid),[m,R]=G.readStruct(_);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},b=(await this.apply([{head:C,body:void 0}]))[0];if(b!==0&&b!==15)return Y(b??12);if(X===void 0)return d(C);let[c,k]=XX({id:m.id,ts:K});if(k!==0)return Y(k);let[T,I]=await eX({now:K,eid:c,ctr:0,bod:X,crypto:l});if(I!==0)return Y(I);let L=(await this.apply([{head:T,body:X}]))[0];if(L!==0&&L!==15)return Y(L??12);return d(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 d(V.head)})}async insert(Z){let{body:X,type:W,gid:V,pid:l,tags:K}=Z,m=AZ({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=AZ({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 ZV(X.head);let W=new P(Z),[V,l]=W.readStruct(_);if(l!==0)return Y(l);return d({eid:Z,ctr:-1,updatedAt:V.ts})}async genEID(Z){let{clock:X,crypto:W}=this,V=X.now();if(Z!==void 0)return XX({id:Z,ts:V});let l=await W.genRandomBytes(8);return XX({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 KV(m);if(R!==0)return console.error(`Failed to peek: ${R}`),this.emitProgress({phase:"idle"}),R;this.xferState.emit();let J=await pl(m);if(J!==0)return console.error(`Failed to push: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await GV(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 WX(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 mV({...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"}),d(J);let F=await this.sync();if(F!==0)return Y(F);let b=await l.hosts.get(Z);if(!b)return Y(13);let[c,k]=await mV({...R,host:b},{pull:!1,push:!1});if(this.xferState.emit(),this.emitProgress({phase:"idle"}),k!==0)return Y(k);if(!c)return Y(12);return d(c)}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 KV(R);if(J!==0)return console.error(`rebuild: failed to peek: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await GV(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=mX(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=oZ,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 ll(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,b=J;for(let T=J;T<m.length&&F<100&&C<102400;T++)C+=m[T].head.len,F++,b=T+1;let c=m.slice(J,b);console.time(`import: applying [${J}, ${b}]`);let k=await this.apply(c,{enqueueUpload:!0,triggerUpload:!1});console.timeEnd(`import: applying [${J}, ${b}]`);for(let T=0;T<c.length;T++){let I=k[T];if(I!==0&&I!==15)console.warn(`failed to import msg ${J+T}: ${z[I]}`)}if(l)queueMicrotask(()=>l(b,m.length,0));this.emitProgress({phase:"import",done:b,total:m.length}),J=b}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 Vl("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 GW(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 tX(J,K,Z,V,m(Z),(F)=>G.hosts.set(Z.label,F));if(await C.register(),X)await C.listen(async(F)=>{let b={conn:C,store:G,enclave:J,host:Z,crypto:K,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery};return yl(F,b,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 YW(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function YV(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function a(Z,...X){if(!YV(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 RV(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 Ql(Z,X){a(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function JV(Z){if(typeof Z!=="boolean")throw Error(`boolean expected, not ${Z}`)}/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */var QZ=(Z)=>new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4));var lK=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!lK)throw Error("Non little-endian hardware is not supported");function KK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function RW(Z){if(typeof Z==="string")Z=KK(Z);else if(YV(Z))Z=JW(Z);else throw Error("Uint8Array expected, got "+typeof Z);return Z}function Ml(Z,X){if(X==null||typeof X!=="object")throw Error("options must be defined");return Object.assign(Z,X)}function zl(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 hl=(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 CV(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 JW(Z){return Uint8Array.from(Z)}function kZ(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function CW(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 Nl=(Z)=>Uint8Array.from(Z.split("").map((X)=>X.charCodeAt(0))),mK=Nl("expand 16-byte k"),YK=Nl("expand 32-byte k"),RK=QZ(mK),JK=QZ(YK);function h(Z,X){return Z<<X|Z>>>32-X}function FV(Z){return Z.byteOffset%4===0}var FW=64,CK=16,gl=4294967295,Sl=new Uint32Array;function FK(Z,X,W,V,l,K,G,m){let R=l.length,J=new Uint8Array(FW),C=QZ(J),F=FV(l)&&FV(K),b=F?QZ(l):Sl,c=F?QZ(K):Sl;for(let k=0;k<R;G++){if(Z(X,W,V,C,G,m),G>=gl)throw Error("arx: counter overflow");let T=Math.min(FW,R-k);if(F&&T===FW){let I=k/4;if(k%4!==0)throw Error("arx: invalid block position");for(let y=0,L;y<CK;y++)L=I+y,c[L]=b[L]^C[y];k+=FW;continue}for(let I=0,y;I<T;I++)y=k+I,K[y]=l[y]^J[I];k+=T}}function xl(Z,X){let{allowShortKeys:W,extendNonceFn:V,counterLength:l,counterRight:K,rounds:G}=Ml({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},X);if(typeof Z!=="function")throw Error("core must be a function");return YW(l),YW(G),JV(K),JV(W),(m,R,J,C,F=0)=>{a(m),a(R),a(J);let b=J.length;if(C===void 0)C=new Uint8Array(b);if(a(C),YW(F),F<0||F>=gl)throw Error("arx: counter overflow");if(C.length<b)throw Error(`arx: output (${C.length}) is shorter than data (${b})`);let c=[],k=m.length,T,I;if(k===32)c.push(T=JW(m)),I=JK;else if(k===16&&W)T=new Uint8Array(32),T.set(m),T.set(m,16),I=RK,c.push(T);else throw Error(`arx: invalid 32-byte key, got length=${k}`);if(!FV(R))c.push(R=JW(R));let y=QZ(T);if(V){if(R.length!==24)throw Error("arx: extended nonce must be 24 bytes");V(I,y,QZ(R.subarray(0,16)),y),R=R.subarray(16)}let L=16-l;if(L!==R.length)throw Error(`arx: nonce must be ${L} or 16 bytes`);if(L!==12){let p=new Uint8Array(12);p.set(R,K?0:12-R.length),R=p,c.push(R)}let M=QZ(R);return FK(Z,I,y,M,J,C,F,G),kZ(...c),C}}var r=(Z,X)=>Z[X++]&255|(Z[X++]&255)<<8;class Hl{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=RW(Z),a(Z,32);let X=r(Z,0),W=r(Z,2),V=r(Z,4),l=r(Z,6),K=r(Z,8),G=r(Z,10),m=r(Z,12),R=r(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]=r(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],b=K[6],c=K[7],k=K[8],T=K[9],I=r(Z,X+0),y=r(Z,X+2),L=r(Z,X+4),M=r(Z,X+6),p=r(Z,X+8),S=r(Z,X+10),H=r(Z,X+12),B=r(Z,X+14),O=l[0]+(I&8191),U=l[1]+((I>>>13|y<<3)&8191),E=l[2]+((y>>>10|L<<6)&8191),Q=l[3]+((L>>>7|M<<9)&8191),A=l[4]+((M>>>4|p<<12)&8191),n=l[5]+(p>>>1&8191),x=l[6]+((p>>>14|S<<2)&8191),j=l[7]+((S>>>11|H<<5)&8191),u=l[8]+((H>>>8|B<<8)&8191),w=l[9]+(B>>>5|V),N=0,q=N+O*G+U*(5*T)+E*(5*k)+Q*(5*c)+A*(5*b);N=q>>>13,q&=8191,q+=n*(5*F)+x*(5*C)+j*(5*J)+u*(5*R)+w*(5*m),N+=q>>>13,q&=8191;let XZ=N+O*m+U*G+E*(5*T)+Q*(5*k)+A*(5*c);N=XZ>>>13,XZ&=8191,XZ+=n*(5*b)+x*(5*F)+j*(5*C)+u*(5*J)+w*(5*R),N+=XZ>>>13,XZ&=8191;let KZ=N+O*R+U*m+E*G+Q*(5*T)+A*(5*k);N=KZ>>>13,KZ&=8191,KZ+=n*(5*c)+x*(5*b)+j*(5*F)+u*(5*C)+w*(5*J),N+=KZ>>>13,KZ&=8191;let v=N+O*J+U*R+E*m+Q*G+A*(5*T);N=v>>>13,v&=8191,v+=n*(5*k)+x*(5*c)+j*(5*b)+u*(5*F)+w*(5*C),N+=v>>>13,v&=8191;let IZ=N+O*C+U*J+E*R+Q*m+A*G;N=IZ>>>13,IZ&=8191,IZ+=n*(5*T)+x*(5*k)+j*(5*c)+u*(5*b)+w*(5*F),N+=IZ>>>13,IZ&=8191;let qZ=N+O*F+U*C+E*J+Q*R+A*m;N=qZ>>>13,qZ&=8191,qZ+=n*G+x*(5*T)+j*(5*k)+u*(5*c)+w*(5*b),N+=qZ>>>13,qZ&=8191;let aZ=N+O*b+U*F+E*C+Q*J+A*R;N=aZ>>>13,aZ&=8191,aZ+=n*m+x*G+j*(5*T)+u*(5*k)+w*(5*c),N+=aZ>>>13,aZ&=8191;let _Z=N+O*c+U*b+E*F+Q*C+A*J;N=_Z>>>13,_Z&=8191,_Z+=n*R+x*m+j*G+u*(5*T)+w*(5*k),N+=_Z>>>13,_Z&=8191;let sZ=N+O*k+U*c+E*b+Q*F+A*C;N=sZ>>>13,sZ&=8191,sZ+=n*J+x*R+j*m+u*G+w*(5*T),N+=sZ>>>13,sZ&=8191;let rZ=N+O*T+U*k+E*c+Q*b+A*F;N=rZ>>>13,rZ&=8191,rZ+=n*C+x*J+j*R+u*m+w*G,N+=rZ>>>13,rZ&=8191,N=(N<<2)+N|0,N=N+q|0,q=N&8191,N=N>>>13,XZ+=N,l[0]=q,l[1]=XZ,l[2]=KZ,l[3]=v,l[4]=IZ,l[5]=qZ,l[6]=aZ,l[7]=_Z,l[8]=sZ,l[9]=rZ}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;kZ(W)}update(Z){RV(this);let{buffer:X,blockLen:W}=this;Z=RW(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(){kZ(this.h,this.r,this.buffer,this.pad)}digestInto(Z){RV(this),Ql(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 dK(Z){let X=(V,l)=>Z(l).update(RW(V)).digest(),W=Z(new Uint8Array(32));return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var dV=dK((Z)=>new Hl(Z));function bK(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],b=W[0],c=W[1],k=l,T=0,I=Z[2],y=X[4],L=X[5],M=X[6],p=X[7],S=Z[3],H=G,B=m,O=R,U=J,E=C,Q=F,A=b,n=c,x=k,j=T,u=I,w=y,N=L,q=M,XZ=p,KZ=S;for(let IZ=0;IZ<K;IZ+=2)E^=h(H+N|0,7),x^=h(E+H|0,9),N^=h(x+E|0,13),H^=h(N+x|0,18),j^=h(Q+B|0,7),q^=h(j+Q|0,9),B^=h(q+j|0,13),Q^=h(B+q|0,18),XZ^=h(u+A|0,7),O^=h(XZ+u|0,9),A^=h(O+XZ|0,13),u^=h(A+O|0,18),U^=h(KZ+w|0,7),n^=h(U+KZ|0,9),w^=h(n+U|0,13),KZ^=h(w+n|0,18),B^=h(H+U|0,7),O^=h(B+H|0,9),U^=h(O+B|0,13),H^=h(U+O|0,18),A^=h(Q+E|0,7),n^=h(A+Q|0,9),E^=h(n+A|0,13),Q^=h(E+n|0,18),w^=h(u+j|0,7),x^=h(w+u|0,9),j^=h(x+w|0,13),u^=h(j+x|0,18),N^=h(KZ+XZ|0,7),q^=h(N+KZ|0,9),XZ^=h(q+N|0,13),KZ^=h(XZ+q|0,18);let v=0;V[v++]=G+H|0,V[v++]=m+B|0,V[v++]=R+O|0,V[v++]=J+U|0,V[v++]=C+E|0,V[v++]=F+Q|0,V[v++]=b+A|0,V[v++]=c+n|0,V[v++]=k+x|0,V[v++]=T+j|0,V[v++]=I+u|0,V[v++]=y+w|0,V[v++]=L+N|0,V[v++]=M+q|0,V[v++]=p+XZ|0,V[v++]=S+KZ|0}function cK(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],b=W[2],c=W[3],k=Z[2],T=X[4],I=X[5],y=X[6],L=X[7],M=Z[3];for(let S=0;S<20;S+=2)R^=h(l+I|0,7),b^=h(R+l|0,9),I^=h(b+R|0,13),l^=h(I+b|0,18),c^=h(J+K|0,7),y^=h(c+J|0,9),K^=h(y+c|0,13),J^=h(K+y|0,18),L^=h(k+C|0,7),G^=h(L+k|0,9),C^=h(G+L|0,13),k^=h(C+G|0,18),m^=h(M+T|0,7),F^=h(m+M|0,9),T^=h(F+m|0,13),M^=h(T+F|0,18),K^=h(l+m|0,7),G^=h(K+l|0,9),m^=h(G+K|0,13),l^=h(m+G|0,18),C^=h(J+R|0,7),F^=h(C+J|0,9),R^=h(F+C|0,13),J^=h(R+F|0,18),T^=h(k+c|0,7),b^=h(T+k|0,9),c^=h(b+T|0,13),k^=h(c+b|0,18),I^=h(M+L|0,7),y^=h(I+M|0,9),L^=h(y+I|0,13),M^=h(L+y|0,18);let p=0;V[p++]=l,V[p++]=J,V[p++]=k,V[p++]=M,V[p++]=C,V[p++]=F,V[p++]=b,V[p++]=c}var bV=xl(bK,{counterRight:!0,extendNonceFn:cK}),cV=hl({blockSize:64,nonceLength:24,tagLength:16},(Z,X)=>{return{encrypt(W,V){V=CV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32);V.set(W,32),kZ(l),bV(Z,X,V,V);let G=dV(K,l);return V.set(G,16),kZ(V.subarray(0,16),G),V.subarray(16)},decrypt(W,V){a(W),V=CV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32,48),G=V.subarray(48);V.set(W,32),kZ(l);let m=bV(Z,X,l,l),R=dV(G,m);if(!zl(K,R))throw Error("invalid tag");return bV(Z,X,V.subarray(16),V.subarray(16)),kZ(l,K,R),G}}});/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function kK(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function gX(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function $Z(Z,...X){if(!kK(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 xX(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 dW(Z,X){$Z(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function Pl(Z){return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength)}function JX(Z){return new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4))}function CX(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function HX(Z,X){return Z<<32-X|Z>>>X}var il=(()=>new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68)();function Ul(Z){return Z<<24&4278190080|Z<<8&16711680|Z>>>8&65280|Z>>>24&255}var ul=il?(Z)=>Z:(Z)=>Ul(Z);function TK(Z){for(let X=0;X<Z.length;X++)Z[X]=Ul(Z[X]);return Z}var VZ=il?(Z)=>Z:TK;function IK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function FX(Z){if(typeof Z==="string")Z=IK(Z);return $Z(Z),Z}class kV{}function Ol(Z){let X=(V,l)=>Z(l).update(FX(V)).digest(),W=Z({});return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var Bl=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var bW=BigInt(4294967295),jl=BigInt(32);function TV(Z,X=!1){if(X)return{h:Number(Z&bW),l:Number(Z>>jl&bW)};return{h:Number(Z>>jl&bW)|0,l:Number(Z&bW)|0}}function MZ(Z,X,W,V,l){return Z=Z+X+l|0,V=HX(V^Z,16),W=W+V|0,X=HX(X^W,12),{a:Z,b:X,c:W,d:V}}function zZ(Z,X,W,V,l){return Z=Z+X+l|0,V=HX(V^Z,8),W=W+V|0,X=HX(X^W,7),{a:Z,b:X,c:W,d:V}}class IV extends kV{constructor(Z,X){super();this.finished=!1,this.destroyed=!1,this.length=0,this.pos=0,gX(Z),gX(X),this.blockLen=Z,this.outputLen=X,this.buffer=new Uint8Array(Z),this.buffer32=JX(this.buffer)}update(Z){xX(this),Z=FX(Z),$Z(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)VZ(V),this.compress(V,0,!1),VZ(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));VZ(C);for(let F=0;m+X<l;F+=V.length,m+=X)this.length+=X,this.compress(C,F,!1);VZ(C);continue}W.set(Z.subarray(m,m+R),this.pos),this.pos+=R,this.length+=R,m+=R}return this}digestInto(Z){xX(this),dW(Z,this);let{pos:X,buffer32:W}=this;this.finished=!0,CX(this.buffer.subarray(X)),VZ(W),this.compress(W,0,!0),VZ(W);let V=JX(Z);this.get().forEach((l,K)=>V[K]=ul(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 pV(Z,X,W,V,l,K,G,m,R,J,C,F,b,c,k,T,I,y,L,M){let p=0;for(let S=0;S<V;S++)({a:l,b:R,c:b,d:I}=MZ(l,R,b,I,W[X+Z[p++]])),{a:l,b:R,c:b,d:I}=zZ(l,R,b,I,W[X+Z[p++]]),{a:K,b:J,c,d:y}=MZ(K,J,c,y,W[X+Z[p++]]),{a:K,b:J,c,d:y}=zZ(K,J,c,y,W[X+Z[p++]]),{a:G,b:C,c:k,d:L}=MZ(G,C,k,L,W[X+Z[p++]]),{a:G,b:C,c:k,d:L}=zZ(G,C,k,L,W[X+Z[p++]]),{a:m,b:F,c:T,d:M}=MZ(m,F,T,M,W[X+Z[p++]]),{a:m,b:F,c:T,d:M}=zZ(m,F,T,M,W[X+Z[p++]]),{a:l,b:J,c:k,d:M}=MZ(l,J,k,M,W[X+Z[p++]]),{a:l,b:J,c:k,d:M}=zZ(l,J,k,M,W[X+Z[p++]]),{a:K,b:C,c:T,d:I}=MZ(K,C,T,I,W[X+Z[p++]]),{a:K,b:C,c:T,d:I}=zZ(K,C,T,I,W[X+Z[p++]]),{a:G,b:F,c:b,d:y}=MZ(G,F,b,y,W[X+Z[p++]]),{a:G,b:F,c:b,d:y}=zZ(G,F,b,y,W[X+Z[p++]]),{a:m,b:R,c,d:L}=MZ(m,R,c,L,W[X+Z[p++]]),{a:m,b:R,c,d:L}=zZ(m,R,c,L,W[X+Z[p++]]);return{v0:l,v1:K,v2:G,v3:m,v4:R,v5:J,v6:C,v7:F,v8:b,v9:c,v10:k,v11:T,v12:I,v13:y,v14:L,v15:M}}var TZ={CHUNK_START:1,CHUNK_END:2,PARENT:4,ROOT:8,KEYED_HASH:16,DERIVE_KEY_CONTEXT:32,DERIVE_KEY_MATERIAL:64},hZ=Bl.slice(),El=(()=>{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 LV extends IV{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=FX(W).slice();$Z(K,32),this.IV=JX(K),VZ(this.IV),this.flags=X|TZ.KEYED_HASH}else if(l){let K=FX(V),G=new LV({dkLen:32},TZ.DERIVE_KEY_CONTEXT).update(K).digest();this.IV=JX(G),VZ(this.IV),this.flags=X|TZ.DERIVE_KEY_MATERIAL}else this.IV=hZ.slice(),this.flags=X;this.state=this.IV.slice(),this.bufferOut=Pl(this.bufferOut32)}get(){return[]}set(){}b2Compress(Z,X,W,V=0){let{state:l,pos:K}=this,{h:G,l:m}=TV(BigInt(Z),!0),{v0:R,v1:J,v2:C,v3:F,v4:b,v5:c,v6:k,v7:T,v8:I,v9:y,v10:L,v11:M,v12:p,v13:S,v14:H,v15:B}=pV(El,V,W,7,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],hZ[0],hZ[1],hZ[2],hZ[3],G,m,K,X);l[0]=R^I,l[1]=J^y,l[2]=C^L,l[3]=F^M,l[4]=b^p,l[5]=c^S,l[6]=k^H,l[7]=T^B}compress(Z,X=0,W=!1){let V=this.flags;if(!this.chunkPos)V|=TZ.CHUNK_START;if(this.chunkPos===15||W)V|=TZ.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|TZ.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,CX(this.state,this.buffer32,this.IV,this.bufferOut32),CX(...this.stack)}b2CompressOut(){let{state:Z,pos:X,flags:W,buffer32:V,bufferOut32:l}=this,{h:K,l:G}=TV(BigInt(this.chunkOut++));VZ(V);let{v0:m,v1:R,v2:J,v3:C,v4:F,v5:b,v6:c,v7:k,v8:T,v9:I,v10:y,v11:L,v12:M,v13:p,v14:S,v15:H}=pV(El,0,V,7,Z[0],Z[1],Z[2],Z[3],Z[4],Z[5],Z[6],Z[7],hZ[0],hZ[1],hZ[2],hZ[3],G,K,X,W);l[0]=m^T,l[1]=R^I,l[2]=J^y,l[3]=C^L,l[4]=F^M,l[5]=b^p,l[6]=c^S,l[7]=k^H,l[8]=Z[0]^T,l[9]=Z[1]^I,l[10]=Z[2]^y,l[11]=Z[3]^L,l[12]=Z[4]^M,l[13]=Z[5]^p,l[14]=Z[6]^S,l[15]=Z[7]^H,VZ(V),VZ(l),this.posOut=0}finish(){if(this.finished)return;this.finished=!0,CX(this.buffer.subarray(this.pos));let Z=this.flags|TZ.ROOT;if(this.stack.length)Z|=TZ.PARENT,VZ(this.buffer32),this.compress(this.buffer32,0,!0),VZ(this.buffer32),this.chunksDone=0,this.pos=this.blockLen;else Z|=(!this.chunkPos?TZ.CHUNK_START:0)|TZ.CHUNK_END;this.flags=Z,this.b2CompressOut()}writeInto(Z){xX(this,!1),$Z(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 gX(Z),this.xofInto(new Uint8Array(Z))}digestInto(Z){if(dW(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 wl=Ol((Z)=>new LV(Z));var yV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function Dl(Z){let X=new Uint8Array(yV.length+32);return X.set(yV),X.set(Z.subarray(0,32),yV.length),X}function Al(Z){return typeof Z==="string"?new TextEncoder().encode(Z):Z}function dX(Z){let X=new ArrayBuffer(Z.byteLength);return new Uint8Array(X).set(Z),X}class QV{verifyKeys=new Map;signKeys=new Map;async genRandomBytes(Z){return CW(Z)}async gen256BitSecureRandomSeed(){return CW(32)}async encryptXSalsa20Poly1305Combined(Z,X){let W=CW(24),l=cV(X,W).encrypt(Z);return new Uint8Array([...W,...l])}async decryptXSalsa20Poly1305Combined(Z,X){let W=Z.slice(0,24),V=Z.slice(24);return cV(X,W).decrypt(V)}async deriveEd25519KeyPair(Z){let X=Z,W=Dl(X),V=await globalThis.crypto.subtle.importKey("pkcs8",dX(W),{name:"Ed25519"},!0,["sign"]),l=await globalThis.crypto.subtle.exportKey("jwk",V);if(typeof l.x!=="string")throw Error("Ed25519 JWK missing x");let K=await globalThis.crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:l.x},{name:"Ed25519"},!0,["verify"]),G=new Uint8Array(await globalThis.crypto.subtle.exportKey("raw",K)),m=new Uint8Array(64);return m.set(X,0),m.set(G,32),this.signKeys.set(GZ(X),V),this.verifyKeys.set(GZ(G),K),{keyType:"ed25519",privateKey:m,publicKey:G}}async importSignKey(Z){let X=Z.subarray(0,32),W=GZ(X),V=this.signKeys.get(W);if(V)return V;let l=Dl(X),K=await globalThis.crypto.subtle.importKey("pkcs8",dX(l),{name:"Ed25519"},!1,["sign"]);return this.signKeys.set(W,K),K}async importVerifyKey(Z){let X=GZ(Z),W=this.verifyKeys.get(X);if(W)return W;let V=await globalThis.crypto.subtle.importKey("raw",dX(Z),{name:"Ed25519"},!1,["verify"]);return this.verifyKeys.set(X,V),V}async signEd25519(Z,X){let W=Al(Z),V=await this.importSignKey(X),l=await globalThis.crypto.subtle.sign({name:"Ed25519"},V,dX(W));return new Uint8Array(l)}async checkSigEd25519(Z,X,W){let V=Al(X);try{let l=await this.importVerifyKey(W);return await globalThis.crypto.subtle.verify({name:"Ed25519"},l,dX(Z),dX(V))}catch{return!1}}async blake3(Z){return wl(Z)}}var pK=new QV,SZ=pK;import{useEffect as SW,useState as iV}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(RZ,"readwrite"),V=W.objectStore(RZ);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(RZ,"readwrite"),l=V.objectStore(RZ);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(RZ,"readonly").objectStore(RZ);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(RZ,"readonly").objectStore(RZ);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(RZ,"readwrite"),X=Z.objectStore(RZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}function ol(Z){return{label:Z.label,handle:new URL(Z.handle),idx:Z.idx,lastSeq:Z.lastSeq||0,clockOffset:Z.clockOffset,subscription:Z.subscription}}function LK(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 zV{db;constructor(Z){this.db=Z}async add(Z){return this.put({...Z,lastSeq:0})}async put(Z){let X={...Z,handle:Z.handle.toString(),lastSeq:Z.lastSeq??0},W=this.db.transaction(lZ,"readwrite"),V=W.objectStore(lZ);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(lZ,"readwrite"),V=W.objectStore(lZ);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(LK(m,X))}})}async get(Z){let W=this.db.transaction(lZ,"readonly").objectStore(lZ);return new Promise((V,l)=>{let K=W.get(Z);K.onsuccess=()=>{let G=K.result;if(!G)V(void 0);else V(ol(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(lZ,"readwrite"),W=X.objectStore(lZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}async list(){let X=this.db.transaction(lZ,"readonly").objectStore(lZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>{let K=l.result;W(K.map(ol))},l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(lZ,"readwrite"),X=Z.objectStore(lZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}class hV{crypto;db;constructor(Z,X){this.crypto=X;this.db=Z}async add(Z){let X=this.db.transaction(o,"readwrite"),W=X.objectStore(o);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(o,"readwrite"),V=W.objectStore(o);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(o,"readonly").objectStore(o);return new Promise((V,l)=>{let K=g(Z),G=W.get(K);G.onsuccess=async()=>{let m=G.result;if(m)V(await uZ(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(o,"readonly").objectStore(o);return new Promise((K,G)=>{let m=[],R=X===void 0?l.openCursor():l.index(PX).openCursor(IDBKeyRange.only(X));R.onsuccess=(J)=>{let C=J.target.result;if(C){let F=X===void 0?C.key:C.primaryKey,b=C.value;m.push({hash:t(F),data:b}),C.continue()}else Promise.all(m.map(({hash:F,data:b})=>uZ(F,b,this.crypto,{body:W}))).then(K).catch(G)},R.onerror=()=>G(R.error)})}async count(Z){let W=this.db.transaction(o,"readonly").objectStore(o);return new Promise((V,l)=>{let K=Z===void 0?W.count():W.index(PX).count(IDBKeyRange.only(Z));K.onsuccess=()=>V(K.result),K.onerror=()=>l(K.error)})}async listKeys(){let X=this.db.transaction(o,"readonly").objectStore(o);return new Promise((W,V)=>{let l=[],K=X.openKeyCursor();K.onsuccess=(G)=>{let m=G.target.result;if(m)l.push(t(m.key)),m.continue();else W(l)},K.onerror=()=>V(K.error)})}async last(Z){let W=this.db.transaction(o,"readonly").objectStore(o);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(e(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=t(K.key);V(await uZ(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(o,"readwrite"),V=W.objectStore(o);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;nZ(J,UZ),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(o,"readwrite"),V=W.objectStore(o);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;nZ(C,cZ,m),V.put(C,R)},J.onerror=(C)=>{C.preventDefault()}}})}async wipe(){let Z=this.db.transaction(o,"readwrite"),X=Z.objectStore(o);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var OZ={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 d({handle:X,label:V,idx:K})}};var iX=1,cW={encode(Z,X){if(X.v!==iX)return 10;let[,W]=ZZ(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(OZ,K);if(G!==0)return G}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X!==iX)return Y(14);let[V,l]=Z.readBytes(dZ);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=ZZ(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,b]=Z.readStruct(OZ);if(b!==0)return Y(b);if(F===void 0)return Y(14);J.push(F)}return d({v:iX,masterSeed:K,hosts:J})}};function SV(Z,X){let[W,V]=ZZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(10);let[l,K]=ZZ(W.slice());if(K!==0)return Y(K);if(l===void 0)return Y(10);return d({v:iX,masterSeed:l,hosts:X.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))})}var UX={encode(Z,X){let[,W]=ZZ(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(OZ,l);if(K!==0)return K}return 0},decode(Z){let[X,W]=Z.readBytes(dZ);if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=ZZ(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(OZ);if(C!==0)return Y(C);if(J===void 0)return Y(14);m.push(J)}return d({masterSeed:V,hosts:m})}};function NZ(Z){let X=new Uint8Array(Z);if(Z>0)crypto.getRandomValues(X);return X}var BZ=32,nl=-7,vl=-8,fl=-257,uX=[{type:"public-key",alg:nl},{type:"public-key",alg:vl},{type:"public-key",alg:fl}];function kW(Z){return Z.trim().toLowerCase().replace(/\.$/,"")||"localhost"}function jZ(Z){let X=new Uint8Array(Z.byteLength);return X.set(Z),X}function EZ(Z){if(Z?.rpId!==void 0)return d(Z.rpId);if(typeof location>"u")return Y(9);return d(kW(location.hostname))}function wZ(){if(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")return 24;return 0}function DZ(Z){if(Z===null||Z.type!=="public-key"||!("rawId"in Z)||typeof Z.getClientExtensionResults!=="function")return Y(27);return d(Z)}async function OX(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 $l(){return OX("extension:largeBlob")}async function TW(Z){let X=wZ();if(X!==0)return Y(X);let[W,V]=EZ(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:NZ(BZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:NZ(16),name:l,displayName:l},pubKeyCredParams:uX,authenticatorSelection:K,extensions:G}})}catch{return Y(24)}let[R,J]=DZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);if(R.getClientExtensionResults().largeBlob?.supported!==!0)return Y(24);return d(new Uint8Array(R.rawId))}async function BX(Z,X,W){let V=wZ();if(V!==0)return V;let[l,K]=EZ(W);if(K!==0)return K;if(l===void 0)return 9;let G={largeBlob:{write:jZ(X)}},m;try{m=await navigator.credentials.get({publicKey:{challenge:NZ(BZ),rpId:l,allowCredentials:[{type:"public-key",id:jZ(Z)}],userVerification:"required",extensions:G}})}catch{return 24}let[R,J]=DZ(m);if(J!==0)return J;if(R===void 0)return 27;if(R.getClientExtensionResults().largeBlob?.written!==!0)return 24;return 0}async function IW(Z,X){let W=wZ();if(W!==0)return Y(W);let[V,l]=EZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(9);let K={largeBlob:{read:!0}},G;try{let F={challenge:NZ(BZ),rpId:V,userVerification:"required",extensions:K};if(Z!==void 0)F.allowCredentials=[{type:"public-key",id:jZ(Z)}];G=await navigator.credentials.get({publicKey:F})}catch{return Y(24)}let[m,R]=DZ(G);if(R!==0)return Y(R);if(m===void 0)return Y(27);let C=m.getClientExtensionResults().largeBlob?.blob;if(C===void 0)return Y(7);return d({blob:new Uint8Array(C),credId:new Uint8Array(m.rawId)})}var jX=new TextEncoder().encode("diplomatic.prf.v1"),NV=32;async function yK(){return OX("extension:prf")}async function gV(Z){let X=wZ();if(X!==0)return Y(X);let[W,V]=EZ(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",authenticatorAttachment:Z?.authenticatorAttachment??"platform"},G;try{G=await navigator.credentials.create({publicKey:{challenge:NZ(BZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:NZ(16),name:l,displayName:l},pubKeyCredParams:uX,authenticatorSelection:K,extensions:{prf:{}}}})}catch{return Y(24)}let[m,R]=DZ(G);if(R!==0)return Y(R);if(m===void 0)return Y(27);let J=m.getClientExtensionResults();return d({credId:new Uint8Array(m.rawId),prfEnabled:J.prf?.enabled===!0})}async function bX(Z){let X=wZ();if(X!==0)return Y(X);let[W,V]=EZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.salt??jX,K=jZ(l),G={challenge:NZ(BZ),rpId:W,userVerification:"required",extensions:{prf:{eval:{first:K}}}};if(Z?.credId!==void 0)G.allowCredentials=[{type:"public-key",id:jZ(Z.credId)}];let m;try{m=await navigator.credentials.get({publicKey:G})}catch{return Y(24)}let[R,J]=DZ(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,b=F instanceof ArrayBuffer?new Uint8Array(F):new Uint8Array(F.buffer,F.byteOffset,F.byteLength),c=b.byteLength>=NV?b.slice(0,NV):b;if(c.byteLength!==NV)return Y(27);return d({prf:c,credId:new Uint8Array(R.rawId)})}var pW="dmFyIHcwPTY0O3ZhciBYSj0zMixUMD04O3ZhciBJJD0zMjt2YXIgV0o9MzAwMDAsR0o9NTEyLGo7KCh3KT0+e3dbdy5TdWNjZXNzPTBdPSJTdWNjZXNzIjt3W3cuSW52YWxpZFNpZ25hdHVyZT0zXT0iSW52YWxpZFNpZ25hdHVyZSI7d1t3LkNsb2NrT3V0T2ZTeW5jPTRdPSJDbG9ja091dE9mU3luYyI7d1t3LlVzZXJOb3RSZWdpc3RlcmVkPTVdPSJVc2VyTm90UmVnaXN0ZXJlZCI7d1t3LlNlcnZlck1pc2NvbmZpZ3VyZWQ9Nl09IlNlcnZlck1pc2NvbmZpZ3VyZWQiO3dbdy5NaXNzaW5nQm9keT03XT0iTWlzc2luZ0JvZHkiO3dbdy5FeHRyYUJvZHlDb250ZW50PThdPSJFeHRyYUJvZHlDb250ZW50Ijt3W3cuTWlzc2luZ1BhcmFtPTldPSJNaXNzaW5nUGFyYW0iO3dbdy5JbnZhbGlkUGFyYW09MTBdPSJJbnZhbGlkUGFyYW0iO3dbdy5JbnZhbGlkUmVxdWVzdD0xMV09IkludmFsaWRSZXF1ZXN0Ijt3W3cuSW50ZXJuYWxFcnJvcj0xMl09IkludGVybmFsRXJyb3IiO3dbdy5Ob3RGb3VuZD0xM109Ik5vdEZvdW5kIjt3W3cuSW52YWxpZE1lc3NhZ2U9MTRdPSJJbnZhbGlkTWVzc2FnZSI7d1t3Lk5vQ2hhbmdlPTE1XT0iTm9DaGFuZ2UiO3dbdy5EYXRhYmFzZUNsb3NlZD0xNl09IkRhdGFiYXNlQ2xvc2VkIjt3W3cuU3RvcmFnZUVycm9yPTE3XT0iU3RvcmFnZUVycm9yIjt3W3cuRGF0YWJhc2VFcnJvcj0xOF09IkRhdGFiYXNlRXJyb3IiO3dbdy5IYXNoTWlzbWF0Y2g9MTldPSJIYXNoTWlzbWF0Y2giO3dbdy5EZWNyeXB0aW9uRXJyb3I9MjBdPSJEZWNyeXB0aW9uRXJyb3IiO3dbdy5Ob3RJbXBsZW1lbnRlZD0yMV09Ik5vdEltcGxlbWVudGVkIjt3W3cuTWlzc2luZ1NlZWQ9MjJdPSJNaXNzaW5nU2VlZCI7d1t3Lk91dE9mQm91bmRzPTIzXT0iT3V0T2ZCb3VuZHMiO3dbdy5Ib3N0RXJyb3I9MjRdPSJIb3N0RXJyb3IiO3dbdy5Db21tdW5pY2F0aW9uRXJyb3I9MjVdPSJDb21tdW5pY2F0aW9uRXJyb3IiO3dbdy5WYXJMaW1pdEV4Y2VlZGVkPTI2XT0iVmFyTGltaXRFeGNlZWRlZCI7d1t3LkludmFsaWRSZXNwb25zZT0yN109IkludmFsaWRSZXNwb25zZSI7d1t3LkNvbm5lY3Rpb25DbG9zZWQ9MjhdPSJDb25uZWN0aW9uQ2xvc2VkIn0pKGp8fD17fSk7ZnVuY3Rpb24gekooJCl7aWYoISR8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuITE7aWYoISgib3AiaW4gJCl8fCEoImlkImluICQpKXJldHVybiExO3JldHVybiB0eXBlb2YgJC5vcD09PSJzdHJpbmciJiZ0eXBlb2YgJC5pZD09PSJudW1iZXIifWZ1bmN0aW9uIEtKKCQpe2xldCBaPSQubGVuZ3RoLEo9MCxRPTA7d2hpbGUoUTxaKXtsZXQgVj0kLmNoYXJDb2RlQXQoUSsrKTtpZigoViY0Mjk0OTY3MTY4KT09PTApe0orKztjb250aW51ZX1lbHNlIGlmKChWJjQyOTQ5NjUyNDgpPT09MClKKz0yO2Vsc2V7aWYoVj49NTUyOTYmJlY8PTU2MzE5KXtpZihRPFope2xldCBZPSQuY2hhckNvZGVBdChRKTtpZigoWSY2NDUxMik9PT01NjMyMCkrK1EsVj0oKFYmMTAyMyk8PDEwKSsoWSYxMDIzKSs2NTUzNn19aWYoKFYmNDI5NDkwMTc2MCk9PT0wKUorPTM7ZWxzZSBKKz00fX1yZXR1cm4gSn1mdW5jdGlvbiBMUSgkLFosSil7bGV0IFE9JC5sZW5ndGgsVj1KLFk9MDt3aGlsZShZPFEpe2xldCBYPSQuY2hhckNvZGVBdChZKyspO2lmKChYJjQyOTQ5NjcxNjgpPT09MCl7WltWKytdPVg7Y29udGludWV9ZWxzZSBpZigoWCY0Mjk0OTY1MjQ4KT09PTApWltWKytdPVg+PjYmMzF8MTkyO2Vsc2V7aWYoWD49NTUyOTYmJlg8PTU2MzE5KXtpZihZPFEpe2xldCBXPSQuY2hhckNvZGVBdChZKTtpZigoVyY2NDUxMik9PT01NjMyMCkrK1ksWD0oKFgmMTAyMyk8PDEwKSsoVyYxMDIzKSs2NTUzNn19aWYoKFgmNDI5NDkwMTc2MCk9PT0wKVpbVisrXT1YPj4xMiYxNXwyMjQsWltWKytdPVg+PjYmNjN8MTI4O2Vsc2UgWltWKytdPVg+PjE4Jjd8MjQwLFpbVisrXT1YPj4xMiY2M3wxMjgsWltWKytdPVg+PjYmNjN8MTI4fVpbVisrXT1YJjYzfDEyOH19dmFyIHhRPW5ldyBUZXh0RW5jb2RlcixmUT01MDtmdW5jdGlvbiBrUSgkLFosSil7eFEuZW5jb2RlSW50bygkLFouc3ViYXJyYXkoSikpfWZ1bmN0aW9uIEZKKCQsWixKKXtpZigkLmxlbmd0aD5mUSlrUSgkLFosSik7ZWxzZSBMUSgkLFosSil9dmFyIEJRPTQwOTY7ZnVuY3Rpb24gZSQoJCxaLEope2xldCBRPVosVj1RK0osWT1bXSxYPSIiO3doaWxlKFE8Vil7bGV0IFc9JFtRKytdO2lmKChXJjEyOCk9PT0wKVkucHVzaChXKTtlbHNlIGlmKChXJjIyNCk9PT0xOTIpe2xldCB6PSRbUSsrXSY2MztZLnB1c2goKFcmMzEpPDw2fHopfWVsc2UgaWYoKFcmMjQwKT09PTIyNCl7bGV0IHo9JFtRKytdJjYzLEs9JFtRKytdJjYzO1kucHVzaCgoVyYzMSk8PDEyfHo8PDZ8Syl9ZWxzZSBpZigoVyYyNDgpPT09MjQwKXtsZXQgej0kW1ErK10mNjMsSz0kW1ErK10mNjMsRj0kW1ErK10mNjMsTj0oVyY3KTw8MTh8ejw8MTJ8Szw8NnxGO2lmKE4+NjU1MzUpTi09NjU1MzYsWS5wdXNoKE4+Pj4xMCYxMDIzfDU1Mjk2KSxOPTU2MzIwfE4mMTAyMztZLnB1c2goTil9ZWxzZSBZLnB1c2goVyk7aWYoWS5sZW5ndGg+PUJRKVgrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uWSksWS5sZW5ndGg9MH1pZihZLmxlbmd0aD4wKVgrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uWSk7cmV0dXJuIFh9dmFyIEVRPW5ldyBUZXh0RGVjb2RlcixtUT0yMDA7ZnVuY3Rpb24gZ1EoJCxaLEope2xldCBRPSQuc3ViYXJyYXkoWixaK0opO3JldHVybiBFUS5kZWNvZGUoUSl9ZnVuY3Rpb24gTkooJCxaLEope2lmKEo+bVEpcmV0dXJuIGdRKCQsWixKKTtlbHNlIHJldHVybiBlJCgkLFosSil9Y2xhc3MgdTB7dHlwZTtkYXRhO2NvbnN0cnVjdG9yKCQsWil7dGhpcy50eXBlPSQsdGhpcy5kYXRhPVp9fWNsYXNzIHMgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcigkKXtzdXBlcigkKTtsZXQgWj1PYmplY3QuY3JlYXRlKHMucHJvdG90eXBlKTtPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcyxaKSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibmFtZSIse2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiExLHZhbHVlOnMubmFtZX0pfX12YXIgbDA9NDI5NDk2NzI5NTtmdW5jdGlvbiBSSigkLFosSil7bGV0IFE9Si80Mjk0OTY3Mjk2LFY9SjskLnNldFVpbnQzMihaLFEpLCQuc2V0VWludDMyKForNCxWKX1mdW5jdGlvbiBIJCgkLFosSil7bGV0IFE9TWF0aC5mbG9vcihKLzQyOTQ5NjcyOTYpLFY9SjskLnNldFVpbnQzMihaLFEpLCQuc2V0VWludDMyKForNCxWKX1mdW5jdGlvbiBNJCgkLFope2xldCBKPSQuZ2V0SW50MzIoWiksUT0kLmdldFVpbnQzMihaKzQpO3JldHVybiBKKjQyOTQ5NjcyOTYrUX1mdW5jdGlvbiBVSigkLFope2xldCBKPSQuZ2V0VWludDMyKFopLFE9JC5nZXRVaW50MzIoWis0KTtyZXR1cm4gSio0Mjk0OTY3Mjk2K1F9dmFyIFNRPS0xLHZRPTQyOTQ5NjcyOTUsYlE9MTcxNzk4NjkxODM7ZnVuY3Rpb24geVEoe3NlYzokLG5zZWM6Wn0pe2lmKCQ+PTAmJlo+PTAmJiQ8PWJRKWlmKFo9PT0wJiYkPD12USl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoNCk7cmV0dXJuIG5ldyBEYXRhVmlldyhKLmJ1ZmZlcikuc2V0VWludDMyKDAsJCksSn1lbHNle2xldCBKPSQvNDI5NDk2NzI5NixRPSQmNDI5NDk2NzI5NSxWPW5ldyBVaW50OEFycmF5KDgpLFk9bmV3IERhdGFWaWV3KFYuYnVmZmVyKTtyZXR1cm4gWS5zZXRVaW50MzIoMCxaPDwyfEomMyksWS5zZXRVaW50MzIoNCxRKSxWfWVsc2V7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoMTIpLFE9bmV3IERhdGFWaWV3KEouYnVmZmVyKTtyZXR1cm4gUS5zZXRVaW50MzIoMCxaKSxIJChRLDQsJCksSn19ZnVuY3Rpb24gaVEoJCl7bGV0IFo9JC5nZXRUaW1lKCksSj1NYXRoLmZsb29yKFovMTAwMCksUT0oWi1KKjEwMDApKjFlNixWPU1hdGguZmxvb3IoUS8xZTkpO3JldHVybntzZWM6SitWLG5zZWM6US1WKjFlOX19ZnVuY3Rpb24gaFEoJCl7aWYoJCBpbnN0YW5jZW9mIERhdGUpe2xldCBaPWlRKCQpO3JldHVybiB5UShaKX1lbHNlIHJldHVybiBudWxsfWZ1bmN0aW9uIHVRKCQpe2xldCBaPW5ldyBEYXRhVmlldygkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKTtzd2l0Y2goJC5ieXRlTGVuZ3RoKXtjYXNlIDQ6e2xldCBKPVouZ2V0VWludDMyKDApLFE9MDtyZXR1cm57c2VjOkosbnNlYzowfX1jYXNlIDg6e2xldCBKPVouZ2V0VWludDMyKDApLFE9Wi5nZXRVaW50MzIoNCksVj0oSiYzKSo0Mjk0OTY3Mjk2K1EsWT1KPj4+MjtyZXR1cm57c2VjOlYsbnNlYzpZfX1jYXNlIDEyOntsZXQgSj1NJChaLDQpLFE9Wi5nZXRVaW50MzIoMCk7cmV0dXJue3NlYzpKLG5zZWM6UX19ZGVmYXVsdDp0aHJvdyBuZXcgcyhgVW5yZWNvZ25pemVkIGRhdGEgc2l6ZSBmb3IgdGltZXN0YW1wIChleHBlY3RlZCA0LCA4LCBvciAxMik6ICR7JC5sZW5ndGh9YCl9fWZ1bmN0aW9uIGxRKCQpe2xldCBaPXVRKCQpO3JldHVybiBuZXcgRGF0ZShaLnNlYyoxMDAwK1oubnNlYy8xZTYpfXZhciBPSj17dHlwZTpTUSxlbmNvZGU6aFEsZGVjb2RlOmxRfTtjbGFzcyBwMHtzdGF0aWMgZGVmYXVsdENvZGVjPW5ldyBwMDtfX2JyYW5kO2J1aWx0SW5FbmNvZGVycz1bXTtidWlsdEluRGVjb2RlcnM9W107ZW5jb2RlcnM9W107ZGVjb2RlcnM9W107Y29uc3RydWN0b3IoKXt0aGlzLnJlZ2lzdGVyKE9KKX1yZWdpc3Rlcih7dHlwZTokLGVuY29kZTpaLGRlY29kZTpKfSl7aWYoJD49MCl0aGlzLmVuY29kZXJzWyRdPVosdGhpcy5kZWNvZGVyc1skXT1KO2Vsc2V7bGV0IFE9LTEtJDt0aGlzLmJ1aWx0SW5FbmNvZGVyc1tRXT1aLHRoaXMuYnVpbHRJbkRlY29kZXJzW1FdPUp9fXRyeVRvRW5jb2RlKCQsWil7Zm9yKGxldCBKPTA7Sjx0aGlzLmJ1aWx0SW5FbmNvZGVycy5sZW5ndGg7SisrKXtsZXQgUT10aGlzLmJ1aWx0SW5FbmNvZGVyc1tKXTtpZihRIT1udWxsKXtsZXQgVj1RKCQsWik7aWYoViE9bnVsbCl7bGV0IFk9LTEtSjtyZXR1cm4gbmV3IHUwKFksVil9fX1mb3IobGV0IEo9MDtKPHRoaXMuZW5jb2RlcnMubGVuZ3RoO0orKyl7bGV0IFE9dGhpcy5lbmNvZGVyc1tKXTtpZihRIT1udWxsKXtsZXQgVj1RKCQsWik7aWYoViE9bnVsbClyZXR1cm4gbmV3IHUwKEosVil9fWlmKCQgaW5zdGFuY2VvZiB1MClyZXR1cm4gJDtyZXR1cm4gbnVsbH1kZWNvZGUoJCxaLEope2xldCBRPVo8MD90aGlzLmJ1aWx0SW5EZWNvZGVyc1stMS1aXTp0aGlzLmRlY29kZXJzW1pdO2lmKFEpcmV0dXJuIFEoJCxaLEopO2Vsc2UgcmV0dXJuIG5ldyB1MChaLCQpfX1mdW5jdGlvbiBwUSgkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHx0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXI8InUiJiYkIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXJ9ZnVuY3Rpb24gUSQoJCl7aWYoJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuICQ7ZWxzZSBpZihBcnJheUJ1ZmZlci5pc1ZpZXcoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpO2Vsc2UgaWYocFEoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpO2Vsc2UgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX12YXIgblE9MTAwLGNRPTIwNDg7Y2xhc3MgQyR7ZXh0ZW5zaW9uQ29kZWM7Y29udGV4dDt1c2VCaWdJbnQ2NDttYXhEZXB0aDtpbml0aWFsQnVmZmVyU2l6ZTtzb3J0S2V5cztmb3JjZUZsb2F0MzI7aWdub3JlVW5kZWZpbmVkO2ZvcmNlSW50ZWdlclRvRmxvYXQ7cG9zO3ZpZXc7Ynl0ZXM7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9wMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5tYXhEZXB0aD0kPy5tYXhEZXB0aD8/blEsdGhpcy5pbml0aWFsQnVmZmVyU2l6ZT0kPy5pbml0aWFsQnVmZmVyU2l6ZT8/Y1EsdGhpcy5zb3J0S2V5cz0kPy5zb3J0S2V5cz8/ITEsdGhpcy5mb3JjZUZsb2F0MzI9JD8uZm9yY2VGbG9hdDMyPz8hMSx0aGlzLmlnbm9yZVVuZGVmaW5lZD0kPy5pZ25vcmVVbmRlZmluZWQ/PyExLHRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdD0kPy5mb3JjZUludGVnZXJUb0Zsb2F0Pz8hMSx0aGlzLnBvcz0wLHRoaXMudmlldz1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKHRoaXMuaW5pdGlhbEJ1ZmZlclNpemUpKSx0aGlzLmJ5dGVzPW5ldyBVaW50OEFycmF5KHRoaXMudmlldy5idWZmZXIpfWNsb25lKCl7cmV0dXJuIG5ldyBDJCh7ZXh0ZW5zaW9uQ29kZWM6dGhpcy5leHRlbnNpb25Db2RlYyxjb250ZXh0OnRoaXMuY29udGV4dCx1c2VCaWdJbnQ2NDp0aGlzLnVzZUJpZ0ludDY0LG1heERlcHRoOnRoaXMubWF4RGVwdGgsaW5pdGlhbEJ1ZmZlclNpemU6dGhpcy5pbml0aWFsQnVmZmVyU2l6ZSxzb3J0S2V5czp0aGlzLnNvcnRLZXlzLGZvcmNlRmxvYXQzMjp0aGlzLmZvcmNlRmxvYXQzMixpZ25vcmVVbmRlZmluZWQ6dGhpcy5pZ25vcmVVbmRlZmluZWQsZm9yY2VJbnRlZ2VyVG9GbG9hdDp0aGlzLmZvcmNlSW50ZWdlclRvRmxvYXR9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMucG9zPTB9ZW5jb2RlU2hhcmVkUmVmKCQpe2lmKHRoaXMuZW50ZXJlZClyZXR1cm4gdGhpcy5jbG9uZSgpLmVuY29kZVNoYXJlZFJlZigkKTt0cnl7cmV0dXJuIHRoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5kb0VuY29kZSgkLDEpLHRoaXMuYnl0ZXMuc3ViYXJyYXkoMCx0aGlzLnBvcyl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWVuY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmNvZGUoJCk7dHJ5e3JldHVybiB0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuZG9FbmNvZGUoJCwxKSx0aGlzLmJ5dGVzLnNsaWNlKDAsdGhpcy5wb3MpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kb0VuY29kZSgkLFope2lmKFo+dGhpcy5tYXhEZXB0aCl0aHJvdyBFcnJvcihgVG9vIGRlZXAgb2JqZWN0cyBpbiBkZXB0aCAke1p9YCk7aWYoJD09bnVsbCl0aGlzLmVuY29kZU5pbCgpO2Vsc2UgaWYodHlwZW9mICQ9PT0iYm9vbGVhbiIpdGhpcy5lbmNvZGVCb29sZWFuKCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ibnVtYmVyIilpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0KXRoaXMuZW5jb2RlTnVtYmVyKCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ic3RyaW5nIil0aGlzLmVuY29kZVN0cmluZygkKTtlbHNlIGlmKHRoaXMudXNlQmlnSW50NjQmJnR5cGVvZiAkPT09ImJpZ2ludCIpdGhpcy5lbmNvZGVCaWdJbnQ2NCgkKTtlbHNlIHRoaXMuZW5jb2RlT2JqZWN0KCQsWil9ZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoJCl7bGV0IFo9dGhpcy5wb3MrJDtpZih0aGlzLnZpZXcuYnl0ZUxlbmd0aDxaKXRoaXMucmVzaXplQnVmZmVyKFoqMil9cmVzaXplQnVmZmVyKCQpe2xldCBaPW5ldyBBcnJheUJ1ZmZlcigkKSxKPW5ldyBVaW50OEFycmF5KFopLFE9bmV3IERhdGFWaWV3KFopO0ouc2V0KHRoaXMuYnl0ZXMpLHRoaXMudmlldz1RLHRoaXMuYnl0ZXM9Sn1lbmNvZGVOaWwoKXt0aGlzLndyaXRlVTgoMTkyKX1lbmNvZGVCb29sZWFuKCQpe2lmKCQ9PT0hMSl0aGlzLndyaXRlVTgoMTk0KTtlbHNlIHRoaXMud3JpdGVVOCgxOTUpfWVuY29kZU51bWJlcigkKXtpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0JiZOdW1iZXIuaXNTYWZlSW50ZWdlcigkKSlpZigkPj0wKWlmKCQ8MTI4KXRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8MjU2KXRoaXMud3JpdGVVOCgyMDQpLHRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8NjU1MzYpdGhpcy53cml0ZVU4KDIwNSksdGhpcy53cml0ZVUxNigkKTtlbHNlIGlmKCQ8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjA2KSx0aGlzLndyaXRlVTMyKCQpO2Vsc2UgaWYoIXRoaXMudXNlQmlnSW50NjQpdGhpcy53cml0ZVU4KDIwNyksdGhpcy53cml0ZVU2NCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIGlmKCQ+PS0zMil0aGlzLndyaXRlVTgoMjI0fCQrMzIpO2Vsc2UgaWYoJD49LTEyOCl0aGlzLndyaXRlVTgoMjA4KSx0aGlzLndyaXRlSTgoJCk7ZWxzZSBpZigkPj0tMzI3NjgpdGhpcy53cml0ZVU4KDIwOSksdGhpcy53cml0ZUkxNigkKTtlbHNlIGlmKCQ+PS0yMTQ3NDgzNjQ4KXRoaXMud3JpdGVVOCgyMTApLHRoaXMud3JpdGVJMzIoJCk7ZWxzZSBpZighdGhpcy51c2VCaWdJbnQ2NCl0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlSTY0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpfWVuY29kZU51bWJlckFzRmxvYXQoJCl7aWYodGhpcy5mb3JjZUZsb2F0MzIpdGhpcy53cml0ZVU4KDIwMiksdGhpcy53cml0ZUYzMigkKTtlbHNlIHRoaXMud3JpdGVVOCgyMDMpLHRoaXMud3JpdGVGNjQoJCl9ZW5jb2RlQmlnSW50NjQoJCl7aWYoJD49QmlnSW50KDApKXRoaXMud3JpdGVVOCgyMDcpLHRoaXMud3JpdGVCaWdVaW50NjQoJCk7ZWxzZSB0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlQmlnSW50NjQoJCl9d3JpdGVTdHJpbmdIZWFkZXIoJCl7aWYoJDwzMil0aGlzLndyaXRlVTgoMTYwKyQpO2Vsc2UgaWYoJDwyNTYpdGhpcy53cml0ZVU4KDIxNyksdGhpcy53cml0ZVU4KCQpO2Vsc2UgaWYoJDw2NTUzNil0aGlzLndyaXRlVTgoMjE4KSx0aGlzLndyaXRlVTE2KCQpO2Vsc2UgaWYoJDw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMTkpLHRoaXMud3JpdGVVMzIoJCk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxvbmcgc3RyaW5nOiAkeyR9IGJ5dGVzIGluIFVURi04YCl9ZW5jb2RlU3RyaW5nKCQpe2xldCBKPUtKKCQpO3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNStKKSx0aGlzLndyaXRlU3RyaW5nSGVhZGVyKEopLEZKKCQsdGhpcy5ieXRlcyx0aGlzLnBvcyksdGhpcy5wb3MrPUp9ZW5jb2RlT2JqZWN0KCQsWil7bGV0IEo9dGhpcy5leHRlbnNpb25Db2RlYy50cnlUb0VuY29kZSgkLHRoaXMuY29udGV4dCk7aWYoSiE9bnVsbCl0aGlzLmVuY29kZUV4dGVuc2lvbihKKTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoJCkpdGhpcy5lbmNvZGVBcnJheSgkLFopO2Vsc2UgaWYoQXJyYXlCdWZmZXIuaXNWaWV3KCQpKXRoaXMuZW5jb2RlQmluYXJ5KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ib2JqZWN0Iil0aGlzLmVuY29kZU1hcCgkLFopO2Vsc2UgdGhyb3cgRXJyb3IoYFVucmVjb2duaXplZCBvYmplY3Q6ICR7T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5hcHBseSgkKX1gKX1lbmNvZGVCaW5hcnkoJCl7bGV0IFo9JC5ieXRlTGVuZ3RoO2lmKFo8MjU2KXRoaXMud3JpdGVVOCgxOTYpLHRoaXMud3JpdGVVOChaKTtlbHNlIGlmKFo8NjU1MzYpdGhpcy53cml0ZVU4KDE5NyksdGhpcy53cml0ZVUxNihaKTtlbHNlIGlmKFo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMTk4KSx0aGlzLndyaXRlVTMyKFopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBiaW5hcnk6ICR7Wn1gKTtsZXQgSj1RJCgkKTt0aGlzLndyaXRlVThhKEopfWVuY29kZUFycmF5KCQsWil7bGV0IEo9JC5sZW5ndGg7aWYoSjwxNil0aGlzLndyaXRlVTgoMTQ0K0opO2Vsc2UgaWYoSjw2NTUzNil0aGlzLndyaXRlVTgoMjIwKSx0aGlzLndyaXRlVTE2KEopO2Vsc2UgaWYoSjw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjEpLHRoaXMud3JpdGVVMzIoSik7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIGFycmF5OiAke0p9YCk7Zm9yKGxldCBRIG9mICQpdGhpcy5kb0VuY29kZShRLForMSl9Y291bnRXaXRob3V0VW5kZWZpbmVkKCQsWil7bGV0IEo9MDtmb3IobGV0IFEgb2YgWilpZigkW1FdIT09dm9pZCAwKUorKztyZXR1cm4gSn1lbmNvZGVNYXAoJCxaKXtsZXQgSj1PYmplY3Qua2V5cygkKTtpZih0aGlzLnNvcnRLZXlzKUouc29ydCgpO2xldCBRPXRoaXMuaWdub3JlVW5kZWZpbmVkP3RoaXMuY291bnRXaXRob3V0VW5kZWZpbmVkKCQsSik6Si5sZW5ndGg7aWYoUTwxNil0aGlzLndyaXRlVTgoMTI4K1EpO2Vsc2UgaWYoUTw2NTUzNil0aGlzLndyaXRlVTgoMjIyKSx0aGlzLndyaXRlVTE2KFEpO2Vsc2UgaWYoUTw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjMpLHRoaXMud3JpdGVVMzIoUSk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIG1hcCBvYmplY3Q6ICR7UX1gKTtmb3IobGV0IFYgb2YgSil7bGV0IFk9JFtWXTtpZighKHRoaXMuaWdub3JlVW5kZWZpbmVkJiZZPT09dm9pZCAwKSl0aGlzLmVuY29kZVN0cmluZyhWKSx0aGlzLmRvRW5jb2RlKFksWisxKX19ZW5jb2RlRXh0ZW5zaW9uKCQpe2lmKHR5cGVvZiAkLmRhdGE9PT0iZnVuY3Rpb24iKXtsZXQgSj0kLmRhdGEodGhpcy5wb3MrNiksUT1KLmxlbmd0aDtpZihRPj00Mjk0OTY3Mjk2KXRocm93IEVycm9yKGBUb28gbGFyZ2UgZXh0ZW5zaW9uIG9iamVjdDogJHtRfWApO3RoaXMud3JpdGVVOCgyMDEpLHRoaXMud3JpdGVVMzIoUSksdGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YShKKTtyZXR1cm59bGV0IFo9JC5kYXRhLmxlbmd0aDtpZihaPT09MSl0aGlzLndyaXRlVTgoMjEyKTtlbHNlIGlmKFo9PT0yKXRoaXMud3JpdGVVOCgyMTMpO2Vsc2UgaWYoWj09PTQpdGhpcy53cml0ZVU4KDIxNCk7ZWxzZSBpZihaPT09OCl0aGlzLndyaXRlVTgoMjE1KTtlbHNlIGlmKFo9PT0xNil0aGlzLndyaXRlVTgoMjE2KTtlbHNlIGlmKFo8MjU2KXRoaXMud3JpdGVVOCgxOTkpLHRoaXMud3JpdGVVOChaKTtlbHNlIGlmKFo8NjU1MzYpdGhpcy53cml0ZVU4KDIwMCksdGhpcy53cml0ZVUxNihaKTtlbHNlIGlmKFo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjAxKSx0aGlzLndyaXRlVTMyKFopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBleHRlbnNpb24gb2JqZWN0OiAke1p9YCk7dGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YSgkLmRhdGEpfXdyaXRlVTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0VWludDgodGhpcy5wb3MsJCksdGhpcy5wb3MrK313cml0ZVU4YSgkKXtsZXQgWj0kLmxlbmd0aDt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKFopLHRoaXMuYnl0ZXMuc2V0KCQsdGhpcy5wb3MpLHRoaXMucG9zKz1afXdyaXRlSTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0SW50OCh0aGlzLnBvcywkKSx0aGlzLnBvcysrfXdyaXRlVTE2KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMiksdGhpcy52aWV3LnNldFVpbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZUkxNigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDIpLHRoaXMudmlldy5zZXRJbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZVUzMigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDQpLHRoaXMudmlldy5zZXRVaW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVJMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0SW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVGMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0RmxvYXQzMih0aGlzLnBvcywkKSx0aGlzLnBvcys9NH13cml0ZUY2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRGbG9hdDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlVTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksUkoodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlSTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksSCQodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlQmlnVWludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ1VpbnQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUJpZ0ludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ0ludDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fX1mdW5jdGlvbiBfMCgkLFope3JldHVybiBuZXcgQyQoWikuZW5jb2RlU2hhcmVkUmVmKCQpfWZ1bmN0aW9uIFAkKCQpe3JldHVybmAkeyQ8MD8iLSI6IiJ9MHgke01hdGguYWJzKCQpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCIwIil9YH12YXIgZFE9MTYsclE9MTY7Y2xhc3MgJFp7aGl0PTA7bWlzcz0wO2NhY2hlczttYXhLZXlMZW5ndGg7bWF4TGVuZ3RoUGVyS2V5O2NvbnN0cnVjdG9yKCQ9ZFEsWj1yUSl7dGhpcy5tYXhLZXlMZW5ndGg9JCx0aGlzLm1heExlbmd0aFBlcktleT1aLHRoaXMuY2FjaGVzPVtdO2ZvcihsZXQgSj0wO0o8dGhpcy5tYXhLZXlMZW5ndGg7SisrKXRoaXMuY2FjaGVzLnB1c2goW10pfWNhbkJlQ2FjaGVkKCQpe3JldHVybiAkPjAmJiQ8PXRoaXMubWF4S2V5TGVuZ3RofWZpbmQoJCxaLEope2xldCBRPXRoaXMuY2FjaGVzW0otMV07JDpmb3IobGV0IFYgb2YgUSl7bGV0IFk9Vi5ieXRlcztmb3IobGV0IFg9MDtYPEo7WCsrKWlmKFlbWF0hPT0kW1orWF0pY29udGludWUgJDtyZXR1cm4gVi5zdHJ9cmV0dXJuIG51bGx9c3RvcmUoJCxaKXtsZXQgSj10aGlzLmNhY2hlc1skLmxlbmd0aC0xXSxRPXtieXRlczokLHN0cjpafTtpZihKLmxlbmd0aD49dGhpcy5tYXhMZW5ndGhQZXJLZXkpSltNYXRoLnJhbmRvbSgpKkoubGVuZ3RofDBdPVE7ZWxzZSBKLnB1c2goUSl9ZGVjb2RlKCQsWixKKXtsZXQgUT10aGlzLmZpbmQoJCxaLEopO2lmKFEhPW51bGwpcmV0dXJuIHRoaXMuaGl0KyssUTt0aGlzLm1pc3MrKztsZXQgVj1lJCgkLFosSiksWT1VaW50OEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCQsWixaK0opO3JldHVybiB0aGlzLnN0b3JlKFksViksVn19dmFyIFpaPSJhcnJheSIsWSQ9Im1hcF9rZXkiLElKPSJtYXBfdmFsdWUiLG9RPSgkKT0+e2lmKHR5cGVvZiAkPT09InN0cmluZyJ8fHR5cGVvZiAkPT09Im51bWJlciIpcmV0dXJuICQ7dGhyb3cgbmV3IHMoIlRoZSB0eXBlIG9mIGtleSBtdXN0IGJlIHN0cmluZyBvciBudW1iZXIgYnV0ICIrdHlwZW9mICQpfTtjbGFzcyBISntzdGFjaz1bXTtzdGFja0hlYWRQb3NpdGlvbj0tMTtnZXQgbGVuZ3RoKCl7cmV0dXJuIHRoaXMuc3RhY2tIZWFkUG9zaXRpb24rMX10b3AoKXtyZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1wdXNoQXJyYXlTdGF0ZSgkKXtsZXQgWj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Wi50eXBlPVpaLFoucG9zaXRpb249MCxaLnNpemU9JCxaLmFycmF5PUFycmF5KCQpfXB1c2hNYXBTdGF0ZSgkKXtsZXQgWj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Wi50eXBlPVkkLFoucmVhZENvdW50PTAsWi5zaXplPSQsWi5tYXA9e319Z2V0VW5pbml0aWFsaXplZFN0YXRlRnJvbVBvb2woKXtpZih0aGlzLnN0YWNrSGVhZFBvc2l0aW9uKyssdGhpcy5zdGFja0hlYWRQb3NpdGlvbj09PXRoaXMuc3RhY2subGVuZ3RoKXtsZXQgJD17dHlwZTp2b2lkIDAsc2l6ZTowLGFycmF5OnZvaWQgMCxwb3NpdGlvbjowLHJlYWRDb3VudDowLG1hcDp2b2lkIDAsa2V5Om51bGx9O3RoaXMuc3RhY2sucHVzaCgkKX1yZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1yZWxlYXNlKCQpe2lmKHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl0hPT0kKXRocm93IEVycm9yKCJJbnZhbGlkIHN0YWNrIHN0YXRlLiBSZWxlYXNlZCBzdGF0ZSBpcyBub3Qgb24gdG9wIG9mIHRoZSBzdGFjay4iKTtpZigkLnR5cGU9PT1aWil7bGV0IEo9JDtKLnNpemU9MCxKLmFycmF5PXZvaWQgMCxKLnBvc2l0aW9uPTAsSi50eXBlPXZvaWQgMH1pZigkLnR5cGU9PT1ZJHx8JC50eXBlPT09SUope2xldCBKPSQ7Si5zaXplPTAsSi5tYXA9dm9pZCAwLEoucmVhZENvdW50PTAsSi50eXBlPXZvaWQgMH10aGlzLnN0YWNrSGVhZFBvc2l0aW9uLS19cmVzZXQoKXt0aGlzLnN0YWNrLmxlbmd0aD0wLHRoaXMuc3RhY2tIZWFkUG9zaXRpb249LTF9fXZhciBWJD0tMSxKWj1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDApKSxhUT1uZXcgVWludDhBcnJheShKWi5idWZmZXIpO3RyeXtKWi5nZXRJbnQ4KDApfWNhdGNoKCQpe2lmKCEoJCBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IEVycm9yKCJUaGlzIG1vZHVsZSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IEphdmFTY3JpcHQgZW5naW5lIGJlY2F1c2UgRGF0YVZpZXcgZG9lcyBub3QgdGhyb3cgUmFuZ2VFcnJvciBvbiBvdXQtb2YtYm91bmRzIGFjY2VzcyIpfXZhciBxSj1SYW5nZUVycm9yKCJJbnN1ZmZpY2llbnQgZGF0YSIpLHNRPW5ldyAkWjtjbGFzcyB3JHtleHRlbnNpb25Db2RlYztjb250ZXh0O3VzZUJpZ0ludDY0O3Jhd1N0cmluZ3M7bWF4U3RyTGVuZ3RoO21heEJpbkxlbmd0aDttYXhBcnJheUxlbmd0aDttYXhNYXBMZW5ndGg7bWF4RXh0TGVuZ3RoO2tleURlY29kZXI7bWFwS2V5Q29udmVydGVyO3RvdGFsUG9zPTA7cG9zPTA7dmlldz1KWjtieXRlcz1hUTtoZWFkQnl0ZT1WJDtzdGFjaz1uZXcgSEo7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9wMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5yYXdTdHJpbmdzPSQ/LnJhd1N0cmluZ3M/PyExLHRoaXMubWF4U3RyTGVuZ3RoPSQ/Lm1heFN0ckxlbmd0aD8/bDAsdGhpcy5tYXhCaW5MZW5ndGg9JD8ubWF4QmluTGVuZ3RoPz9sMCx0aGlzLm1heEFycmF5TGVuZ3RoPSQ/Lm1heEFycmF5TGVuZ3RoPz9sMCx0aGlzLm1heE1hcExlbmd0aD0kPy5tYXhNYXBMZW5ndGg/P2wwLHRoaXMubWF4RXh0TGVuZ3RoPSQ/Lm1heEV4dExlbmd0aD8/bDAsdGhpcy5rZXlEZWNvZGVyPSQ/LmtleURlY29kZXIhPT12b2lkIDA/JC5rZXlEZWNvZGVyOnNRLHRoaXMubWFwS2V5Q29udmVydGVyPSQ/Lm1hcEtleUNvbnZlcnRlcj8/b1F9Y2xvbmUoKXtyZXR1cm4gbmV3IHckKHtleHRlbnNpb25Db2RlYzp0aGlzLmV4dGVuc2lvbkNvZGVjLGNvbnRleHQ6dGhpcy5jb250ZXh0LHVzZUJpZ0ludDY0OnRoaXMudXNlQmlnSW50NjQscmF3U3RyaW5nczp0aGlzLnJhd1N0cmluZ3MsbWF4U3RyTGVuZ3RoOnRoaXMubWF4U3RyTGVuZ3RoLG1heEJpbkxlbmd0aDp0aGlzLm1heEJpbkxlbmd0aCxtYXhBcnJheUxlbmd0aDp0aGlzLm1heEFycmF5TGVuZ3RoLG1heE1hcExlbmd0aDp0aGlzLm1heE1hcExlbmd0aCxtYXhFeHRMZW5ndGg6dGhpcy5tYXhFeHRMZW5ndGgsa2V5RGVjb2Rlcjp0aGlzLmtleURlY29kZXJ9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMudG90YWxQb3M9MCx0aGlzLmhlYWRCeXRlPVYkLHRoaXMuc3RhY2sucmVzZXQoKX1zZXRCdWZmZXIoJCl7bGV0IFo9USQoJCk7dGhpcy5ieXRlcz1aLHRoaXMudmlldz1uZXcgRGF0YVZpZXcoWi5idWZmZXIsWi5ieXRlT2Zmc2V0LFouYnl0ZUxlbmd0aCksdGhpcy5wb3M9MH1hcHBlbmRCdWZmZXIoJCl7aWYodGhpcy5oZWFkQnl0ZT09PVYkJiYhdGhpcy5oYXNSZW1haW5pbmcoMSkpdGhpcy5zZXRCdWZmZXIoJCk7ZWxzZXtsZXQgWj10aGlzLmJ5dGVzLnN1YmFycmF5KHRoaXMucG9zKSxKPVEkKCQpLFE9bmV3IFVpbnQ4QXJyYXkoWi5sZW5ndGgrSi5sZW5ndGgpO1Euc2V0KFopLFEuc2V0KEosWi5sZW5ndGgpLHRoaXMuc2V0QnVmZmVyKFEpfX1oYXNSZW1haW5pbmcoJCl7cmV0dXJuIHRoaXMudmlldy5ieXRlTGVuZ3RoLXRoaXMucG9zPj0kfWNyZWF0ZUV4dHJhQnl0ZUVycm9yKCQpe2xldHt2aWV3OloscG9zOkp9PXRoaXM7cmV0dXJuIFJhbmdlRXJyb3IoYEV4dHJhICR7Wi5ieXRlTGVuZ3RoLUp9IG9mICR7Wi5ieXRlTGVuZ3RofSBieXRlKHMpIGZvdW5kIGF0IGJ1ZmZlclskeyR9XWApfWRlY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGUoJCk7dHJ5e3RoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5zZXRCdWZmZXIoJCk7bGV0IFo9dGhpcy5kb0RlY29kZVN5bmMoKTtpZih0aGlzLmhhc1JlbWFpbmluZygxKSl0aHJvdyB0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMucG9zKTtyZXR1cm4gWn1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19KmRlY29kZU11bHRpKCQpe2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpKCQpO3JldHVybn10cnl7dGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLnNldEJ1ZmZlcigkKTt3aGlsZSh0aGlzLmhhc1JlbWFpbmluZygxKSl5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1hc3luYyBkZWNvZGVBc3luYygkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGVBc3luYygkKTt0cnl7dGhpcy5lbnRlcmVkPSEwO2xldCBaPSExLEo7Zm9yIGF3YWl0KGxldCBYIG9mICQpe2lmKFopdGhyb3cgdGhpcy5lbnRlcmVkPSExLHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7dGhpcy5hcHBlbmRCdWZmZXIoWCk7dHJ5e0o9dGhpcy5kb0RlY29kZVN5bmMoKSxaPSEwfWNhdGNoKFcpe2lmKCEoVyBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IFd9dGhpcy50b3RhbFBvcys9dGhpcy5wb3N9aWYoWil7aWYodGhpcy5oYXNSZW1haW5pbmcoMSkpdGhyb3cgdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnRvdGFsUG9zKTtyZXR1cm4gSn1sZXR7aGVhZEJ5dGU6USxwb3M6Vix0b3RhbFBvczpZfT10aGlzO3Rocm93IFJhbmdlRXJyb3IoYEluc3VmZmljaWVudCBkYXRhIGluIHBhcnNpbmcgJHtQJChRKX0gYXQgJHtZfSAoJHtWfSBpbiB0aGUgY3VycmVudCBidWZmZXIpYCl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRlY29kZUFycmF5U3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMCl9ZGVjb2RlU3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMSl9YXN5bmMqZGVjb2RlTXVsdGlBc3luYygkLFope2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpQXN5bmMoJCxaKTtyZXR1cm59dHJ5e3RoaXMuZW50ZXJlZD0hMDtsZXQgSj1aLFE9LTE7Zm9yIGF3YWl0KGxldCBWIG9mICQpe2lmKFomJlE9PT0wKXRocm93IHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7aWYodGhpcy5hcHBlbmRCdWZmZXIoViksSilRPXRoaXMucmVhZEFycmF5U2l6ZSgpLEo9ITEsdGhpcy5jb21wbGV0ZSgpO3RyeXt3aGlsZSghMClpZih5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpLC0tUT09PTApYnJlYWt9Y2F0Y2goWSl7aWYoIShZIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikpdGhyb3cgWX10aGlzLnRvdGFsUG9zKz10aGlzLnBvc319ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRvRGVjb2RlU3luYygpeyQ6d2hpbGUoITApe2xldCAkPXRoaXMucmVhZEhlYWRCeXRlKCksWjtpZigkPj0yMjQpWj0kLTI1NjtlbHNlIGlmKCQ8MTkyKWlmKCQ8MTI4KVo9JDtlbHNlIGlmKCQ8MTQ0KXtsZXQgUT0kLTEyODtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBaPXt9fWVsc2UgaWYoJDwxNjApe2xldCBRPSQtMTQ0O2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNle2xldCBRPSQtMTYwO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwwKX1lbHNlIGlmKCQ9PT0xOTIpWj1udWxsO2Vsc2UgaWYoJD09PTE5NClaPSExO2Vsc2UgaWYoJD09PTE5NSlaPSEwO2Vsc2UgaWYoJD09PTIwMilaPXRoaXMucmVhZEYzMigpO2Vsc2UgaWYoJD09PTIwMylaPXRoaXMucmVhZEY2NCgpO2Vsc2UgaWYoJD09PTIwNClaPXRoaXMucmVhZFU4KCk7ZWxzZSBpZigkPT09MjA1KVo9dGhpcy5yZWFkVTE2KCk7ZWxzZSBpZigkPT09MjA2KVo9dGhpcy5yZWFkVTMyKCk7ZWxzZSBpZigkPT09MjA3KWlmKHRoaXMudXNlQmlnSW50NjQpWj10aGlzLnJlYWRVNjRBc0JpZ0ludCgpO2Vsc2UgWj10aGlzLnJlYWRVNjQoKTtlbHNlIGlmKCQ9PT0yMDgpWj10aGlzLnJlYWRJOCgpO2Vsc2UgaWYoJD09PTIwOSlaPXRoaXMucmVhZEkxNigpO2Vsc2UgaWYoJD09PTIxMClaPXRoaXMucmVhZEkzMigpO2Vsc2UgaWYoJD09PTIxMSlpZih0aGlzLnVzZUJpZ0ludDY0KVo9dGhpcy5yZWFkSTY0QXNCaWdJbnQoKTtlbHNlIFo9dGhpcy5yZWFkSTY0KCk7ZWxzZSBpZigkPT09MjE3KXtsZXQgUT10aGlzLmxvb2tVOCgpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwxKX1lbHNlIGlmKCQ9PT0yMTgpe2xldCBRPXRoaXMubG9va1UxNigpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwyKX1lbHNlIGlmKCQ9PT0yMTkpe2xldCBRPXRoaXMubG9va1UzMigpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSw0KX1lbHNlIGlmKCQ9PT0yMjApe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNlIGlmKCQ9PT0yMjEpe2xldCBRPXRoaXMucmVhZFUzMigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNlIGlmKCQ9PT0yMjIpe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hNYXBTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIFo9e319ZWxzZSBpZigkPT09MjIzKXtsZXQgUT10aGlzLnJlYWRVMzIoKTtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBaPXt9fWVsc2UgaWYoJD09PTE5Nil7bGV0IFE9dGhpcy5sb29rVTgoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsMSl9ZWxzZSBpZigkPT09MTk3KXtsZXQgUT10aGlzLmxvb2tVMTYoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsMil9ZWxzZSBpZigkPT09MTk4KXtsZXQgUT10aGlzLmxvb2tVMzIoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsNCl9ZWxzZSBpZigkPT09MjEyKVo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMSwwKTtlbHNlIGlmKCQ9PT0yMTMpWj10aGlzLmRlY29kZUV4dGVuc2lvbigyLDApO2Vsc2UgaWYoJD09PTIxNClaPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDQsMCk7ZWxzZSBpZigkPT09MjE1KVo9dGhpcy5kZWNvZGVFeHRlbnNpb24oOCwwKTtlbHNlIGlmKCQ9PT0yMTYpWj10aGlzLmRlY29kZUV4dGVuc2lvbigxNiwwKTtlbHNlIGlmKCQ9PT0xOTkpe2xldCBRPXRoaXMubG9va1U4KCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDEpfWVsc2UgaWYoJD09PTIwMCl7bGV0IFE9dGhpcy5sb29rVTE2KCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDIpfWVsc2UgaWYoJD09PTIwMSl7bGV0IFE9dGhpcy5sb29rVTMyKCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDQpfWVsc2UgdGhyb3cgbmV3IHMoYFVucmVjb2duaXplZCB0eXBlIGJ5dGU6ICR7UCQoJCl9YCk7dGhpcy5jb21wbGV0ZSgpO2xldCBKPXRoaXMuc3RhY2s7d2hpbGUoSi5sZW5ndGg+MCl7bGV0IFE9Si50b3AoKTtpZihRLnR5cGU9PT1aWilpZihRLmFycmF5W1EucG9zaXRpb25dPVosUS5wb3NpdGlvbisrLFEucG9zaXRpb249PT1RLnNpemUpWj1RLmFycmF5LEoucmVsZWFzZShRKTtlbHNlIGNvbnRpbnVlICQ7ZWxzZSBpZihRLnR5cGU9PT1ZJCl7aWYoWj09PSJfX3Byb3RvX18iKXRocm93IG5ldyBzKCJUaGUga2V5IF9fcHJvdG9fXyBpcyBub3QgYWxsb3dlZCIpO1Eua2V5PXRoaXMubWFwS2V5Q29udmVydGVyKFopLFEudHlwZT1JSjtjb250aW51ZSAkfWVsc2UgaWYoUS5tYXBbUS5rZXldPVosUS5yZWFkQ291bnQrKyxRLnJlYWRDb3VudD09PVEuc2l6ZSlaPVEubWFwLEoucmVsZWFzZShRKTtlbHNle1Eua2V5PW51bGwsUS50eXBlPVkkO2NvbnRpbnVlICR9fXJldHVybiBafX1yZWFkSGVhZEJ5dGUoKXtpZih0aGlzLmhlYWRCeXRlPT09ViQpdGhpcy5oZWFkQnl0ZT10aGlzLnJlYWRVOCgpO3JldHVybiB0aGlzLmhlYWRCeXRlfWNvbXBsZXRlKCl7dGhpcy5oZWFkQnl0ZT1WJH1yZWFkQXJyYXlTaXplKCl7bGV0ICQ9dGhpcy5yZWFkSGVhZEJ5dGUoKTtzd2l0Y2goJCl7Y2FzZSAyMjA6cmV0dXJuIHRoaXMucmVhZFUxNigpO2Nhc2UgMjIxOnJldHVybiB0aGlzLnJlYWRVMzIoKTtkZWZhdWx0OmlmKCQ8MTYwKXJldHVybiAkLTE0NDtlbHNlIHRocm93IG5ldyBzKGBVbnJlY29nbml6ZWQgYXJyYXkgdHlwZSBieXRlOiAke1AkKCQpfWApfX1wdXNoTWFwU3RhdGUoJCl7aWYoJD50aGlzLm1heE1hcExlbmd0aCl0aHJvdyBuZXcgcyhgTWF4IGxlbmd0aCBleGNlZWRlZDogbWFwIGxlbmd0aCAoJHskfSkgPiBtYXhNYXBMZW5ndGhMZW5ndGggKCR7dGhpcy5tYXhNYXBMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaE1hcFN0YXRlKCQpfXB1c2hBcnJheVN0YXRlKCQpe2lmKCQ+dGhpcy5tYXhBcnJheUxlbmd0aCl0aHJvdyBuZXcgcyhgTWF4IGxlbmd0aCBleGNlZWRlZDogYXJyYXkgbGVuZ3RoICgkeyR9KSA+IG1heEFycmF5TGVuZ3RoICgke3RoaXMubWF4QXJyYXlMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaEFycmF5U3RhdGUoJCl9ZGVjb2RlU3RyaW5nKCQsWil7aWYoIXRoaXMucmF3U3RyaW5nc3x8dGhpcy5zdGF0ZUlzTWFwS2V5KCkpcmV0dXJuIHRoaXMuZGVjb2RlVXRmOFN0cmluZygkLFopO3JldHVybiB0aGlzLmRlY29kZUJpbmFyeSgkLFopfWRlY29kZVV0ZjhTdHJpbmcoJCxaKXtpZigkPnRoaXMubWF4U3RyTGVuZ3RoKXRocm93IG5ldyBzKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBVVEYtOCBieXRlIGxlbmd0aCAoJHskfSkgPiBtYXhTdHJMZW5ndGggKCR7dGhpcy5tYXhTdHJMZW5ndGh9KWApO2lmKHRoaXMuYnl0ZXMuYnl0ZUxlbmd0aDx0aGlzLnBvcytaKyQpdGhyb3cgcUo7bGV0IEo9dGhpcy5wb3MrWixRO2lmKHRoaXMuc3RhdGVJc01hcEtleSgpJiZ0aGlzLmtleURlY29kZXI/LmNhbkJlQ2FjaGVkKCQpKVE9dGhpcy5rZXlEZWNvZGVyLmRlY29kZSh0aGlzLmJ5dGVzLEosJCk7ZWxzZSBRPU5KKHRoaXMuYnl0ZXMsSiwkKTtyZXR1cm4gdGhpcy5wb3MrPVorJCxRfXN0YXRlSXNNYXBLZXkoKXtpZih0aGlzLnN0YWNrLmxlbmd0aD4wKXJldHVybiB0aGlzLnN0YWNrLnRvcCgpLnR5cGU9PT1ZJDtyZXR1cm4hMX1kZWNvZGVCaW5hcnkoJCxaKXtpZigkPnRoaXMubWF4QmluTGVuZ3RoKXRocm93IG5ldyBzKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBiaW4gbGVuZ3RoICgkeyR9KSA+IG1heEJpbkxlbmd0aCAoJHt0aGlzLm1heEJpbkxlbmd0aH0pYCk7aWYoIXRoaXMuaGFzUmVtYWluaW5nKCQrWikpdGhyb3cgcUo7bGV0IEo9dGhpcy5wb3MrWixRPXRoaXMuYnl0ZXMuc3ViYXJyYXkoSixKKyQpO3JldHVybiB0aGlzLnBvcys9WiskLFF9ZGVjb2RlRXh0ZW5zaW9uKCQsWil7aWYoJD50aGlzLm1heEV4dExlbmd0aCl0aHJvdyBuZXcgcyhgTWF4IGxlbmd0aCBleGNlZWRlZDogZXh0IGxlbmd0aCAoJHskfSkgPiBtYXhFeHRMZW5ndGggKCR7dGhpcy5tYXhFeHRMZW5ndGh9KWApO2xldCBKPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zK1opLFE9dGhpcy5kZWNvZGVCaW5hcnkoJCxaKzEpO3JldHVybiB0aGlzLmV4dGVuc2lvbkNvZGVjLmRlY29kZShRLEosdGhpcy5jb250ZXh0KX1sb29rVTgoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKX1sb29rVTE2KCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50MTYodGhpcy5wb3MpfWxvb2tVMzIoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyl9cmVhZFU4KCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRJOCgpe2xldCAkPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRVMTYoKXtsZXQgJD10aGlzLnZpZXcuZ2V0VWludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkSTE2KCl7bGV0ICQ9dGhpcy52aWV3LmdldEludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkVTMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZEkzMigpe2xldCAkPXRoaXMudmlldy5nZXRJbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZFU2NCgpe2xldCAkPVVKKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NCgpe2xldCAkPU0kKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZFU2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ0ludDY0KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTgsJH1yZWFkRjMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldEZsb2F0MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRGNjQoKXtsZXQgJD10aGlzLnZpZXcuZ2V0RmxvYXQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9fWZ1bmN0aW9uIFFaKCQsWil7cmV0dXJuIG5ldyB3JChaKS5kZWNvZGUoJCl9Y2xhc3MgWCR7bGlzdGVuZXJzPW5ldyBNYXA7YWRkRXZlbnRMaXN0ZW5lcigkLFope2xldCBKPXRoaXMubGlzdGVuZXJzLmdldCgkKTtpZighSilKPW5ldyBTZXQsdGhpcy5saXN0ZW5lcnMuc2V0KCQsSik7cmV0dXJuIEouYWRkKFopLCgpPT57dGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCQsWil9fXJlbW92ZUV2ZW50TGlzdGVuZXIoJCxaKXtsZXQgSj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoSil7aWYoSi5kZWxldGUoWiksSi5zaXplPT09MCl0aGlzLmxpc3RlbmVycy5kZWxldGUoJCl9fWVtaXQoJCxaKXtsZXQgSj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoSil7bGV0IFE9QXJyYXkuZnJvbShKKTtmb3IobGV0IFYgb2YgUSlWKFopfX1lbWl0QWxsKCQpe2xldCBaPUFycmF5LmZyb20odGhpcy5saXN0ZW5lcnMua2V5cygpKTtmb3IobGV0IEogb2YgWil0aGlzLmVtaXQoSiwkKX19Y2xhc3MgTDB7Z2V0dGVyO3N0YXRpYyBldmVudE5hbWU9InVwZGF0ZSI7ZW1pdHRlcjtjb25zdHJ1Y3RvcigkKXt0aGlzLmdldHRlcj0kO3RoaXMuZW1pdHRlcj1uZXcgWCR9Z2V0PSgpPT50aGlzLmdldHRlcigpO2FzeW5jIGVtaXQoKXtsZXQgJD1hd2FpdCB0aGlzLmdldHRlcigpO3F1ZXVlTWljcm90YXNrKCgpPT50aGlzLmVtaXR0ZXIuZW1pdChMMC5ldmVudE5hbWUsJCkpfWxpc3RlbigkKXtyZXR1cm4gdGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoTDAuZXZlbnROYW1lLCQpLCgpPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoTDAuZXZlbnROYW1lLCQpfX19ZnVuY3Rpb24gUigkKXtyZXR1cm5bJCwwXX1mdW5jdGlvbiBHKCQpe3JldHVyblt2b2lkIDAsJF19ZnVuY3Rpb24gdFEoJCl7aWYoJDwwKWNvbnNvbGUuaW5mbygiTiIsJCksY29uc29sZS50cmFjZSgpO2lmKHR5cGVvZiAkIT09ImJpZ2ludCIpJD1CaWdJbnQoJCk7aWYoJDwwbilyZXR1cm4gRygxMCk7bGV0IFo9W107d2hpbGUoJD4wbil7bGV0IEo9TnVtYmVyKCQmMHg3Zm4pO2lmKCQ+Pj03biwkPjBuKVoucHVzaChKfDEyOCk7ZWxzZSBaLnB1c2goSil9aWYoWi5sZW5ndGg9PT0wKXJldHVybiBSKG5ldyBVaW50OEFycmF5KFswXSkpO2lmKFoubGVuZ3RoPjgpcmV0dXJuIEcoMjYpO3JldHVybiBSKG5ldyBVaW50OEFycmF5KFopKX1mdW5jdGlvbiBlUSgkLFo9MCl7bGV0IEo9MG4sUT0wLFY9Wjt3aGlsZSghMCl7aWYoVj49JC5sZW5ndGgpcmV0dXJuIEcoMTQpO2xldCBZPSRbVisrXTtpZihZPT09dm9pZCAwKXJldHVybiBHKDE0KTtpZihKfD1CaWdJbnQoWSYxMjcpPDxCaWdJbnQoUSksKFkmMTI4KT09PTApe2lmKFYtWj44KXJldHVybiBHKDI2KTtyZXR1cm4gUih7dmFsdWU6Sj4weDFmZmZmZmZmZmZmZmZmbj9KOk51bWJlcihKKSxieXRlc1JlYWQ6Vi1afSl9aWYoUSs9NyxRPj01NilyZXR1cm4gRygyNil9fWNsYXNzIGd7ZGF0YTtwb3M9MDtjb25zdHJ1Y3RvcigkKXt0aGlzLmRhdGE9JH1zdGF0aWMgYXN5bmMgZnJvbVJlc3BvbnNlKCQpe2xldCBaPWF3YWl0ICQuYXJyYXlCdWZmZXIoKSxKPW5ldyBVaW50OEFycmF5KFopO3JldHVybiBuZXcgZyhKKX1yZWFkQmlnSW50KCl7aWYodGhpcy5wb3MrOD50aGlzLmRhdGEubGVuZ3RoKXJldHVybiBHKDcpO2xldCAkPW5ldyBEYXRhVmlldyh0aGlzLmRhdGEuYnVmZmVyLHRoaXMuZGF0YS5ieXRlT2Zmc2V0K3RoaXMucG9zKS5nZXRCaWdVaW50NjQoMCwhMSk7cmV0dXJuIHRoaXMucG9zKz04LFIoJCl9cmVhZERhdGUoKXtsZXRbJCxaXT10aGlzLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gUihuZXcgRGF0ZSgkKSl9cmVhZFZhckludCgpe2xldFskLFpdPWVRKHRoaXMuZGF0YSx0aGlzLnBvcyk7aWYoWiE9PTApcmV0dXJuIEcoWik7dGhpcy5wb3MrPSQuYnl0ZXNSZWFkO2xldCBKPSQudmFsdWU7cmV0dXJuIFIodHlwZW9mIEo9PT0iYmlnaW50Ij9OdW1iZXIoSik6Sil9cmVhZFZhclN0cmluZygpe2xldFskLFpdPXRoaXMucmVhZFZhckludCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtKLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBWPW5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShKKTtyZXR1cm4gUihWKX1yZWFkQnl0ZXMoJCl7aWYoJDwwKXJldHVybiBHKDEwKTtpZih0aGlzLnBvcyskPnRoaXMuZGF0YS5sZW5ndGgpcmV0dXJuIEcoMjMpO2xldCBaPXRoaXMuZGF0YS5zbGljZSh0aGlzLnBvcyx0aGlzLnBvcyskKTtyZXR1cm4gdGhpcy5wb3MrPSQsUihaKX1yZWFkVmFyQnl0ZXMoKXtsZXRbJCxaXT10aGlzLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gdGhpcy5yZWFkQnl0ZXMoJCl9cmVhZFN0cnVjdCgkKXtyZXR1cm4gJC5kZWNvZGUodGhpcyl9cmVhZFN0cnVjdHMoJCl7bGV0IFo9W107d2hpbGUoIXRoaXMuZG9uZSgpKXtsZXRbSixRXT10aGlzLnJlYWRTdHJ1Y3QoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7Wi5wdXNoKEopfXJldHVybiBSKFopfXJlYWRCeXRlc1NlcSgkKXtsZXQgWj1bXTt3aGlsZSghdGhpcy5kb25lKCkpe2xldFtKLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO1oucHVzaChKKX1yZXR1cm4gUihaKX1kb25lKCl7cmV0dXJuIHRoaXMucG9zPj10aGlzLmRhdGEubGVuZ3RofWNvbnN1bWVkKCl7cmV0dXJuIHRoaXMucG9zfX1jbGFzcyBTe3BhcnRzPVtdO3dyaXRlQmlnSW50KCQpe2xldCBaPW5ldyBVaW50OEFycmF5KDgpO25ldyBEYXRhVmlldyhaLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsJCwhMSksdGhpcy5wYXJ0cy5wdXNoKFopfXdyaXRlRGF0ZSgkKXtsZXQgWj0kLmdldFRpbWUoKTtyZXR1cm4gdGhpcy53cml0ZVZhckludChaKX13cml0ZVZhckludCgkKXtsZXRbWixKXT10USgkKTtpZihKIT09MClyZXR1cm4gSjtyZXR1cm4gdGhpcy5wYXJ0cy5wdXNoKFopLDB9d3JpdGVWYXJTdHJpbmcoJCl7bGV0IFo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpLEo9dGhpcy53cml0ZVZhckludChaLmxlbmd0aCk7aWYoSiE9PTApcmV0dXJuIEo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcyhaKSwwfXByZXBlbmRCeXRlcygkKXt0aGlzLnBhcnRzLnVuc2hpZnQoJCl9d3JpdGVCeXRlcygkKXt0aGlzLnBhcnRzLnB1c2goJCl9d3JpdGVWYXJCeXRlcygkKXtsZXQgWj10aGlzLndyaXRlVmFySW50KCQubGVuZ3RoKTtpZihaIT09MClyZXR1cm4gWjtyZXR1cm4gdGhpcy53cml0ZUJ5dGVzKCQpLDB9d3JpdGVTdHJ1Y3QoJCxaKXtyZXR1cm4gJC5lbmNvZGUodGhpcyxaKX13cml0ZVN0cnVjdHMoJCxaKXtmb3IobGV0IEogb2YgWil7bGV0IFE9dGhpcy53cml0ZVN0cnVjdCgkLEopO2lmKFEhPT0wKXJldHVybiBRfXJldHVybiAwfXdyaXRlQnl0ZXNTZXEoJCl7Zm9yKGxldCBaIG9mICQpdGhpcy53cml0ZUJ5dGVzKFopfXJlc3VsdCgpe2xldCAkPXRoaXMucGFydHMucmVkdWNlKChRLFYpPT5RK1YubGVuZ3RoLDApLFo9bmV3IFVpbnQ4QXJyYXkoJCksSj0wO2ZvcihsZXQgUSBvZiB0aGlzLnBhcnRzKVouc2V0KFEsSiksSis9US5sZW5ndGg7cmV0dXJuIFp9KnNjYW4oKXtmb3IobGV0ICQgb2YgdGhpcy5wYXJ0cyl5aWVsZCAkfX1hc3luYyBmdW5jdGlvbiBWWigkLFope2xldCBKPW5ldyBTLFE9Si53cml0ZURhdGUoWik7aWYoUSE9PTApcmV0dXJuIEcoUSk7bGV0IFY9Si5yZXN1bHQoKSxZPWF3YWl0ICQuc2lnbihWKTtyZXR1cm4gUih7cHViS2V5OiQucHVibGljS2V5LHNpZzpZLHRpbWVzdGFtcDpafSl9YXN5bmMgZnVuY3Rpb24gRDAoJCxaLEope2xldCBRPUoubm93KCkuZ2V0VGltZSgpLFY9JC50aW1lc3RhbXAuZ2V0VGltZSgpO2lmKE1hdGguYWJzKFEtVik+V0opcmV0dXJuIDQ7bGV0IFg9bmV3IFM7WC53cml0ZURhdGUoJC50aW1lc3RhbXApO2xldCBXPVgucmVzdWx0KCk7aWYoIWF3YWl0IFouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLFcsJC5wdWJLZXkpKXJldHVybiAzO3JldHVybiAwfXZhciBRMD17ZW5jb2RlKCQsWil7bGV0IEo9JC53cml0ZVZhckJ5dGVzKFouaWQpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVEYXRlKFoudHMpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFyQnl0ZXMoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWREYXRlKCk7aWYoViE9PTApcmV0dXJuIEcoVik7cmV0dXJuIFIoe2lkOlosdHM6UX0pfX07ZnVuY3Rpb24gVCQoJCl7bGV0IFo9bmV3IFMsSj1aLndyaXRlU3RydWN0KFEwLCQpO2lmKEohPT0wKXJldHVybiBHKEopO2xldCBRPVoucmVzdWx0KCk7cmV0dXJuIFIoUSl9dmFyIFgwPXtlbmNvZGUoJCxaKXtsZXQgSj0kLndyaXRlVmFyQnl0ZXMoWi5laWQpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJJbnQoWi5vZmYpO2lmKFEhPT0wKXJldHVybiBRO2xldCBWPSQud3JpdGVWYXJJbnQoWi5jdHIpO2lmKFYhPT0wKXJldHVybiBWO2xldCBZPSQud3JpdGVWYXJJbnQoWi5sZW4pO2lmKFkhPT0wKXJldHVybiBZO2lmKFouaHNoKSQud3JpdGVCeXRlcyhaLmhzaCk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJCeXRlcygpO2lmKEohPT0wKXJldHVybiBHKEopO2xldCBRPW5ldyBnKFopLFssVl09UTAuZGVjb2RlKFEpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtZLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtXLHpdPSQucmVhZFZhckludCgpO2lmKHohPT0wKXJldHVybiBHKHopO2xldFtLLEZdPSQucmVhZFZhckludCgpO2lmKEYhPT0wKXJldHVybiBHKEYpO2xldCBOO2lmKEs+MCl7bGV0W1UsT109JC5yZWFkQnl0ZXMoSSQpO2lmKE8hPT0wKXJldHVybiBHKE8pO049VX1yZXR1cm4gUih7ZWlkOlosb2ZmOlksY3RyOlcsbGVuOkssaHNoOk59KX19O2Z1bmN0aW9uIE4wKCQpe3JldHVybiBBcnJheS5mcm9tKCQpLm1hcCgoSik9PkoudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIjAiKSkuam9pbigiIil9ZnVuY3Rpb24gRCQoJCl7aWYoJC5sZW5ndGglMiE9PTApdGhyb3cgRXJyb3IoIkludmFsaWQgaGV4IHN0cmluZyIpO2xldCBaPW5ldyBVaW50OEFycmF5KCQubGVuZ3RoLzIpO2ZvcihsZXQgSj0wO0o8JC5sZW5ndGg7Sis9MilaW0ovMl09TnVtYmVyLnBhcnNlSW50KCQuc3Vic3RyKEosMiksMTYpO3JldHVybiBafWZ1bmN0aW9uIFYwKCQsWil7aWYoJD09PVopcmV0dXJuITA7aWYoJC5ieXRlTGVuZ3RoIT09Wi5ieXRlTGVuZ3RoKXJldHVybiExO3JldHVybiAkLmV2ZXJ5KChKLFEpPT5KPT09WltRXSl9dmFyIGY7aWYodHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLnRvQmFzZTY0PT09ImZ1bmN0aW9uIilmPSgkKT0+JC50b0Jhc2U2NCgpO2Vsc2UgZj0oJCk9PmJ0b2EoU3RyaW5nLmZyb21DaGFyQ29kZSguLi4kKSk7dmFyIEYwO2lmKHR5cGVvZiBVaW50OEFycmF5LmZyb21CYXNlNjQ9PT0iZnVuY3Rpb24iKUYwPSgkKT0+VWludDhBcnJheS5mcm9tQmFzZTY0KCQpO2Vsc2UgRjA9KCQpPT5VaW50OEFycmF5LmZyb20oYXRvYigkKSwoWik9PlouY2hhckNvZGVBdCgwKSk7ZnVuY3Rpb24gVyQoJCxaKXtsZXQgSj1uZXcgVWludDhBcnJheSgkLmxlbmd0aCtaLmxlbmd0aCk7cmV0dXJuIEouc2V0KCQsMCksSi5zZXQoWiwkLmxlbmd0aCksSn1mdW5jdGlvbiBNSigkLFosSil7cmV0dXJuIEouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLCQuaGVhZENwaCxaKX1hc3luYyBmdW5jdGlvbiBDSigkLFosSixRKXtsZXQgVjtpZigkLmJvZCYmJC5sZW4+MClWPWF3YWl0IEouYmxha2UzKCQuYm9kKTtsZXQgWT1uZXcgUyxYPVgwLmVuY29kZShZLHsuLi4kLGhzaDpWfSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFc9WS5yZXN1bHQoKSx6PWF3YWl0IFoua2RtRm9yKFcpLEs9US5kZXJpdmVDaXBoZXIoeiwiZW5jcnlwdCIpLEY9YXdhaXQgSy5lbmNyeXB0KFcpLE49JC5ib2Q/YXdhaXQgSy5lbmNyeXB0KCQuYm9kKTpuZXcgVWludDhBcnJheSgwKSxVPWF3YWl0IFouc2lnbihGKTtyZXR1cm4gUih7c2lnOlUsa2RtOnosaGVhZENwaDpGLGJvZHlDcGg6Tn0pfWFzeW5jIGZ1bmN0aW9uIFlaKCQsWixKLFEsVil7bGV0IFk9bmV3IGcoJCksW1gsV109WDAuZGVjb2RlKFkpO2lmKFchPT0wKXJldHVybiBHKDE0KTtsZXQgejt0cnl7ej1aJiZaLmxlbmd0aD4wP2F3YWl0IEouZGVjcnlwdChaKTp2b2lkIDB9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldCBLPVguaHNoJiZ6PT09dm9pZCAwLEY9WC5oc2g9PT12b2lkIDAmJnohPT12b2lkIDA7aWYoS3x8RilyZXR1cm4gRygxOSk7aWYoWC5oc2gmJnope2xldCBVPWF3YWl0IFEuYmxha2UzKHopO2lmKCFWMChVLFguaHNoKSlyZXR1cm4gRygxOSl9bGV0IE49Vj8/YXdhaXQgUS5ibGFrZTMoJCk7cmV0dXJuIFIoe21zZ0hlYWQ6WCxib2Q6eixoZWFkSGFzaDpOfSl9Y2xhc3MgWFp7bm93KCl7cmV0dXJuIG5ldyBEYXRlfX1mdW5jdGlvbiBQSigkLFosSixRKXtsZXQgVj1aLmdldFRpbWUoKS0kLmdldFRpbWUoKSxZPUouZ2V0VGltZSgpLVEuZ2V0VGltZSgpO3JldHVybihWK1kpLzJ9dmFyIEckPXtlbmNvZGUoJCxaKXtpZigkLndyaXRlVmFySW50KFoucXVvdGEpLFoucXVvdGE+MCl7aWYoWi51c2FnZT09PXZvaWQgMClyZXR1cm4gOTskLndyaXRlVmFySW50KFoudXNhZ2UpfXJldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0IFE7aWYoWj4wKXtsZXRbVixZXT0kLnJlYWRWYXJJbnQoKTtpZihZIT09MClyZXR1cm4gRyhZKTtRPVZ9cmV0dXJuIFIoe3F1b3RhOlosdXNhZ2U6UX0pfX07dmFyIFdaPXtlbmNvZGUoJCxaKXskLndyaXRlQnl0ZXMobmV3IFVpbnQ4QXJyYXkoW1ouc3RhdHVzXSkpO2xldCBKPSQud3JpdGVEYXRlKFoudGltZVJjdmQpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVEYXRlKFoudGltZVNlbnQpO2lmKFEhPT0wKXJldHVybiBRO2xldCBWPSQud3JpdGVWYXJJbnQoWi5zdWJzY3JpcHRpb24udGVybSk7aWYoViE9PTApcmV0dXJuIFY7bGV0IFk9JC53cml0ZVZhckludChaLnN1YnNjcmlwdGlvbi5lbGFwc2VkKTtpZihZIT09MClyZXR1cm4gWTtsZXQgWD0kLndyaXRlU3RydWN0KEckLFouc3Vic2NyaXB0aW9uLnN0YXQpO2lmKFghPT0wKXJldHVybiBYO2xldCBXPSQud3JpdGVTdHJ1Y3QoRyQsWi5zdWJzY3JpcHRpb24uZHluKTtpZihXIT09MClyZXR1cm4gVztyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZEJ5dGVzKDEpO2lmKEohPT0wKXJldHVybiBHKEopO2xldCBRPVpbMF0sW1YsWV09JC5yZWFkRGF0ZSgpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtYLFddPSQucmVhZERhdGUoKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXRbeixLXT0kLnJlYWRWYXJJbnQoKTtpZihLIT09MClyZXR1cm4gRyhLKTtsZXRbRixOXT0kLnJlYWRWYXJJbnQoKTtpZihOIT09MClyZXR1cm4gRyhOKTtsZXRbVSxPXT0kLnJlYWRTdHJ1Y3QoRyQpO2lmKE8hPT0wKXJldHVybiBHKE8pO2xldFtxLEldPSQucmVhZFN0cnVjdChHJCk7aWYoSSE9PTApcmV0dXJuIEcoSSk7cmV0dXJuIFIoe3N0YXR1czpRLHRpbWVSY3ZkOlYsdGltZVNlbnQ6WCxzdWJzY3JpcHRpb246e3Rlcm06eixlbGFwc2VkOkYsc3RhdDpVLGR5bjpxfX0pfX07dmFyIEdaPXtlbmNvZGUoJCxaKXtsZXQgSj0kLndyaXRlVmFyQnl0ZXMoWi5oZWFkQ3BoKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFySW50KFouc2VxKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZFZhckJ5dGVzKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsVl09JC5yZWFkVmFySW50KCk7aWYoViE9PTApcmV0dXJuIEcoVik7cmV0dXJuIFIoe2hlYWRDcGg6WixzZXE6UX0pfX07dmFyIFkwPXtlbmNvZGUoJCxaKXskLndyaXRlQnl0ZXMoWi5wdWJLZXkpLCQud3JpdGVCeXRlcyhaLnNpZyk7bGV0IEo9JC53cml0ZURhdGUoWi50aW1lc3RhbXApO2lmKEohPT0wKXJldHVybiBKO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkQnl0ZXMoWEopO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFZdPSQucmVhZEJ5dGVzKHcwKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXRbWSxYXT0kLnJlYWREYXRlKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIFIoe3B1YktleTpaLHNpZzpRLHRpbWVzdGFtcDpZfSl9fTt2YXIgd0o9e2FzeW5jIGVuY29kZVJlcSgkLFosSixRLFYpe2xldCBZPVYud3JpdGVTdHJ1Y3QoWTAsSik7aWYoWSE9PTApcmV0dXJuIFk7Zm9yKGxldCBYIG9mIFEpVi53cml0ZVZhckludChYKTtyZXR1cm4gMH0sYXN5bmMgaGFuZGxlUmVxKCQsWixKKXtsZXR7Y2xvY2s6USxjcnlwdG86VixzdG9yYWdlOll9PSQsW1gsV109Wi5yZWFkU3RydWN0KFkwKTtpZihXIT09MClyZXR1cm4gVztsZXQgej1hd2FpdCBEMChYLFYsUSk7aWYoeiE9PTApcmV0dXJuIHo7bGV0e3B1YktleTpLfT1YLFtGLE5dPWF3YWl0IFkuaGFzVXNlcihLKTtpZihOIT09MClyZXR1cm4gTjtpZighRilyZXR1cm4gNTtsZXRbVSxPXT1aLnJlYWRWYXJJbnQoKTtpZihPIT09MClyZXR1cm4gTztpZighWi5kb25lKCkpcmV0dXJuIDg7bGV0W3EsSV09YXdhaXQgWS5saXN0SGVhZHMoSyxVKTtpZihJIT09MClyZXR1cm4gSTtyZXR1cm4gSi53cml0ZVN0cnVjdHMoR1oscSl9LGRlY29kZVJlc3AoJCl7cmV0dXJuICQucmVhZFN0cnVjdHMoR1opfX07dmFyIHpaPXtlbmNvZGUoJCxaKXskLndyaXRlVmFySW50KFouc2VxKTtsZXQgSj0kLndyaXRlVmFyQnl0ZXMoWi5ib2R5Q3BoKTtpZihKIT09MClyZXR1cm4gSjtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZFZhckludCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFZdPSQucmVhZFZhckJ5dGVzKCk7aWYoViE9PTApcmV0dXJuIEcoVik7cmV0dXJuIFIoe3NlcTpaLGJvZHlDcGg6UX0pfX07dmFyIFRKPXthc3luYyBlbmNvZGVSZXEoJCxaLEosUSxWKXtsZXQgWT1WLndyaXRlU3RydWN0KFkwLEopO2lmKFkhPT0wKXJldHVybiBZO2ZvcihsZXQgWCBvZiBRKXtsZXQgVz1WLndyaXRlVmFySW50KFgpO2lmKFchPT0wKXJldHVybiBXfXJldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxaLEope2xldHtjbG9jazpRLGNyeXB0bzpWLHN0b3JhZ2U6WX09JCxbWCxXXT1aLnJlYWRTdHJ1Y3QoWTApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEQwKFgsVixRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVgsW0YsTl09YXdhaXQgWS5oYXNVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO2lmKCFGKXJldHVybiA1O2xldCBVPVtdO3doaWxlKCFaLmRvbmUoKSl7bGV0W0ksSF09Wi5yZWFkVmFySW50KCk7aWYoSCE9PTApcmV0dXJuIEg7VS5wdXNoKEkpfWNvbnNvbGUuaW5mbyhgUFVMTDogJHtVLmxlbmd0aH0gYmFnc2ApO2xldFtPLHFdPWF3YWl0IFkuZ2V0Qm9kaWVzKEssVSk7aWYocSE9PTApcmV0dXJuIHE7aWYoIU8pcmV0dXJuIDE3O2ZvcihsZXR7c2VxOkksYm9keUNwaDpIfW9mIE8pe2xldCBQPXtzZXE6SSxib2R5Q3BoOkh9LEM9Si53cml0ZVN0cnVjdCh6WixQKTtpZihDIT09MClyZXR1cm4gQ31yZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyh6Wil9fTt2YXIgS1o9e2VuY29kZSgkLFopeyQud3JpdGVCeXRlcyhaLnNpZyksJC53cml0ZUJ5dGVzKFoua2RtKTtsZXQgSj0kLndyaXRlVmFyQnl0ZXMoWi5oZWFkQ3BoKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFyQnl0ZXMoWi5ib2R5Q3BoKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZEJ5dGVzKHcwKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWRCeXRlcyhUMCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1ksWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbVyx6XT0kLnJlYWRWYXJCeXRlcygpO2lmKHohPT0wKXJldHVybiBHKHopO3JldHVybiBSKHtzaWc6WixrZG06USxoZWFkQ3BoOlksYm9keUNwaDpXfSl9fTt2YXIgaiQ9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVWYXJJbnQoWi5zZXEpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJCeXRlcyhaLmhlYWRDcGgpO2lmKFEhPT0wKXJldHVybiBRO2xldCBWPVouYm9keUNwaD9aLmJvZHlDcGgubGVuZ3RoOjAsWT0kLndyaXRlVmFySW50KFYpO2lmKFkhPT0wKXJldHVybiBZO2lmKFY+MCl7aWYoIVouYm9keUNwaClyZXR1cm4gMTA7JC53cml0ZUJ5dGVzKFouYm9keUNwaCl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWRWYXJCeXRlcygpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtZLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldCBXO2lmKFk+MCl7bGV0W3osS109JC5yZWFkQnl0ZXMoWSk7aWYoSyE9PTApcmV0dXJuIEcoSyk7Vz16fXJldHVybiBSKHtzZXE6WixoZWFkQ3BoOlEsYm9keUNwaDpXfSl9fTt2YXIgQSQ9e2VuY29kZSgkLFopeyQud3JpdGVCeXRlcyhaLnNpZyksJC53cml0ZUJ5dGVzKFoua2RtKTtsZXQgSj0kLndyaXRlVmFyQnl0ZXMoWi5oZWFkQ3BoKTtpZihKIT09MClyZXR1cm4gSjtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZEJ5dGVzKHcwKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWRCeXRlcyhUMCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1ksWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gUih7c2lnOlosa2RtOlEsaGVhZENwaDpZfSl9fTt2YXIgXyQ9e2VuY29kZSgkLFope2lmKCQud3JpdGVWYXJJbnQoWi5pZHgpLCQud3JpdGVCeXRlcyhuZXcgVWludDhBcnJheShbWi5zdGF0dXNdKSksWi5zdGF0dXM9PT0wKSQud3JpdGVWYXJJbnQoWi5zZXEpO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsVl09JC5yZWFkQnl0ZXMoMSk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0IFk9UVswXTtpZihZIT09MClyZXR1cm4gUih7aWR4Olosc3RhdHVzOll9KTtsZXRbWCxXXT0kLnJlYWRWYXJJbnQoKTtpZihXIT09MClyZXR1cm4gRyhXKTtyZXR1cm4gUih7aWR4Olosc3RhdHVzOlksc2VxOlh9KX19O3ZhciBESj17YXN5bmMgZW5jb2RlUmVxKCQsWixKLFEsVil7bGV0IFk9Vi53cml0ZVN0cnVjdChZMCxKKTtpZihZIT09MClyZXR1cm4gWTtsZXQgWD1WLndyaXRlU3RydWN0cyhLWixRKTtpZihYIT09MClyZXR1cm4gWDtyZXR1cm4gMH0sYXN5bmMgaGFuZGxlUmVxKCQsWixKKXtsZXR7Y2xvY2s6USxjcnlwdG86VixzdG9yYWdlOlksbm90aWZpZXI6WH09JCxbVyx6XT1aLnJlYWRTdHJ1Y3QoWTApO2lmKHohPT0wKXJldHVybiB6O2xldCBLPWF3YWl0IEQwKFcsVixRKTtpZihLIT09MClyZXR1cm4gSztsZXR7cHViS2V5OkZ9PVcsW04sVV09YXdhaXQgWS5oYXNVc2VyKEYpO2lmKFUhPT0wKXJldHVybiBVO2lmKCFOKXJldHVybiA1O2xldFtPLHFdPVoucmVhZFN0cnVjdHMoS1opO2lmKHEhPT0wKXJldHVybiBxO2NvbnNvbGUuaW5mbyhgUFVTSDogJHtPLmxlbmd0aH0gYmFnc2ApO2xldCBJPVtdLEg9W107Zm9yKGxldCBNPTA7TTxPLmxlbmd0aDtNKyspe2xldCBBPU9bTV07aWYoIWF3YWl0IE1KKEEsRixWKSl7bGV0IG09e2lkeDpNLHN0YXR1czozfSxFPUoud3JpdGVTdHJ1Y3QoXyQsbSk7aWYoRSE9PTApcmV0dXJuIEU7Y29udGludWV9SS5wdXNoKE0pLEgucHVzaChBKX1sZXRbUCxDXT1hd2FpdCBZLnNldEJhZ3MoRixIKTtpZihDIT09MClyZXR1cm4gQztpZighUHx8UC5sZW5ndGghPT1ILmxlbmd0aClyZXR1cm4gMTc7bGV0IFQ9W107Zm9yKGxldCBNPTA7TTxILmxlbmd0aDtNKyspe2xldCBBPUhbTV0seD1JW01dLG09UFtNXSxFPW5ldyBTLGs9RS53cml0ZVN0cnVjdChBJCxBKTtpZihrIT09MClyZXR1cm4gaztsZXQgYj1FLnJlc3VsdCgpLHc9e3NlcTptLGhlYWRDcGg6Yn07aWYoTy5sZW5ndGg9PT0xJiZBLmJvZHlDcGgubGVuZ3RoPD1HSil3LmJvZHlDcGg9QS5ib2R5Q3BoO1QucHVzaCh3KTtsZXQgaD17aWR4Ongsc3RhdHVzOjAsc2VxOm19LGw9Si53cml0ZVN0cnVjdChfJCxoKTtpZihsIT09MClyZXR1cm4gbH1pZihULmxlbmd0aD4wKXtsZXQgTT1uZXcgUyxBPU0ud3JpdGVTdHJ1Y3RzKGokLFQpO2lmKEEhPT0wKXJldHVybiBBO2xldCB4PU0ucmVzdWx0KCk7YXdhaXQgUHJvbWlzZS5yZXNvbHZlKFgucHVzaChGLHgpKX1yZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyhfJCl9fTt2YXIgako9e2FzeW5jIGVuY29kZVJlcSgkLFosSixRLFYpe3JldHVybiBWLndyaXRlU3RydWN0KFkwLEopfSxhc3luYyBoYW5kbGVSZXEoJCxaLEope2xldHtjbG9jazpRLGNyeXB0bzpWLHN0b3JhZ2U6WX09JCxbWCxXXT1aLnJlYWRTdHJ1Y3QoWTApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEQwKFgsVixRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVg7aWYoIVouZG9uZSgpKXJldHVybiA4O2xldFtGLE5dPWF3YWl0IFkuYWRkVXNlcihLKTtpZihOIT09MClyZXR1cm4gTjtyZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gUih2b2lkIDApfX07Y2xhc3MgRlp7dXJsO3dlYnNvY2tldDtjb25zdHJ1Y3RvcigkKXt0aGlzLnVybD0kfWNvbm5lY3RlZCgpe3JldHVybiB0aGlzLndlYnNvY2tldCE9PXZvaWQgMCYmdGhpcy53ZWJzb2NrZXQucmVhZHlTdGF0ZT09PVdlYlNvY2tldC5PUEVOfWFzeW5jIGNvbm5lY3QoJCxaLEo9KCk9Pnt9LFE9KCk9Pnt9KXtsZXR7dXJsOlZ9PXRoaXM7aWYodGhpcy53ZWJzb2NrZXQpdGhpcy53ZWJzb2NrZXQuY2xvc2UoKSx0aGlzLndlYnNvY2tldD12b2lkIDA7bGV0IFk9bmV3IFM7WS53cml0ZVN0cnVjdChZMCwkKTtsZXQgWD1ZLnJlc3VsdCgpLFc9TjAoWCk7cmV0dXJuIFYuc2VhcmNoUGFyYW1zLnNldCgidCIsVyksdGhpcy53ZWJzb2NrZXQ9bmV3IFdlYlNvY2tldChWKSx0aGlzLndlYnNvY2tldC5iaW5hcnlUeXBlPSJhcnJheWJ1ZmZlciIsdGhpcy53ZWJzb2NrZXQub25vcGVuPSgpPT57Y29uc29sZS5sb2coIkNPTk5FQ1RFRCIpLFEoKX0sdGhpcy53ZWJzb2NrZXQub25jbG9zZT0oKT0+e2NvbnNvbGUubG9nKCJESVNDT05ORUNURUQiKSx0aGlzLndlYnNvY2tldD12b2lkIDAsSigpfSx0aGlzLndlYnNvY2tldC5vbm1lc3NhZ2U9KHopPT57bGV0IEs9bmV3IFVpbnQ4QXJyYXkoei5kYXRhKTtaKEspfSx0aGlzLndlYnNvY2tldC5vbmVycm9yPSh6KT0+e2NvbnNvbGUubG9nKGBFUlJPUjogJHtKU09OLnN0cmluZ2lmeSh6KX1gKSx0aGlzLndlYnNvY2tldD12b2lkIDAsSigpfSxQcm9taXNlLnJlc29sdmUoMCl9ZGlzY29ubmVjdCgpe3RoaXMud2Vic29ja2V0Py5jbG9zZSgpLHRoaXMud2Vic29ja2V0PXZvaWQgMH19dmFyIHI9e3VzZXI6e3BhdGg6Ii91c2VyIixlbmRwb2ludDpqSixuYW1lOjB9LHB1c2g6e3BhdGg6Ii9wdXNoIixlbmRwb2ludDpESixuYW1lOjJ9LHBlZWs6e3BhdGg6Ii9wZWVrIixlbmRwb2ludDp3SixuYW1lOjF9LHB1bGw6e3BhdGg6Ii9wdWxsIixlbmRwb2ludDpUSixuYW1lOjN9fSwkVj17MDpyLnVzZXIsMjpyLnB1c2gsMTpyLnBlZWssMzpyLnB1bGx9LFZXPXtbci51c2VyLnBhdGhdOnIudXNlcixbci5wdXNoLnBhdGhdOnIucHVzaCxbci5wZWVrLnBhdGhdOnIucGVlayxbci5wdWxsLnBhdGhdOnIucHVsbH07Y2xhc3MgQUp7dXJsO2xpc3RlbmVyO2NvbnN0cnVjdG9yKCQpe3RoaXMudXJsPSQ7dGhpcy5saXN0ZW5lcj1uZXcgRlooJCl9YXN5bmMgY2FsbCgkLFope2xldHtwYXRoOkp9PSRWWyRdLFE9bmV3IFVSTChKLHRoaXMudXJsKTt0cnl7cmV0dXJuIGF3YWl0IFpWKFEsWil9Y2F0Y2h7cmV0dXJuIEcoMjUpfX19dmFyIF9KPSgkKT0+e3JldHVybiBuZXcgQUooJC5oYW5kbGUpfTthc3luYyBmdW5jdGlvbiBaVigkLFope2xldCBKPWF3YWl0IGZldGNoKCQse21ldGhvZDoiUE9TVCIsYm9keTpaLnJlc3VsdCgpLnNsaWNlKCl9KTtpZighSi5vaylyZXR1cm4gRygyNCk7bGV0IFE9YXdhaXQgZy5mcm9tUmVzcG9uc2UoSik7cmV0dXJuIFIoUSl9Y2xhc3MgTCR7ZW5jbGF2ZTtjcnlwdG87aG9zdDtjbG9jazt0cmFuc3BvcnQ7dXBkYXRlSG9zdE1ldGE7Y29uc3RydWN0b3IoJCxaLEosUSxWLFkpe3RoaXMuZW5jbGF2ZT0kO3RoaXMuY3J5cHRvPVo7dGhpcy5ob3N0PUo7dGhpcy5jbG9jaz1RO3RoaXMudHJhbnNwb3J0PVY7dGhpcy51cGRhdGVIb3N0TWV0YT1ZfWFzeW5jIGNhbGwoJCxaKXtsZXR7Y2xvY2s6Six0cmFuc3BvcnQ6UX09dGhpcyx7ZW5kcG9pbnQ6VixuYW1lOll9PSQsWD1hd2FpdCB0aGlzLmlkZW50aXR5KCksVz1KLm5vdygpLFt6LEtdPWF3YWl0IFZaKFgsVyk7aWYoSyE9PTApcmV0dXJuIEcoSyk7bGV0IEY9bmV3IFMsTj1hd2FpdCBWLmVuY29kZVJlcSh0aGlzLFgseixaLEYpO2lmKE4hPT0wKXJldHVybiBHKE4pO2xldCBVPUoubm93KCksW08scV09YXdhaXQgUS5jYWxsKFksRiksST1KLm5vdygpO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldFtILFBdPU8ucmVhZFN0cnVjdChXWik7aWYoUCE9PTApcmV0dXJuIEcoUCk7aWYoSC5zdGF0dXMhPT0wKXJldHVybiBHKEguc3RhdHVzKTtsZXQgVD17Y2xvY2tPZmZzZXQ6UEooVSxILnRpbWVSY3ZkLEgudGltZVNlbnQsSSksc3Vic2NyaXB0aW9uOkguc3Vic2NyaXB0aW9ufSxNPWF3YWl0IHRoaXMudXBkYXRlSG9zdE1ldGEoVCk7aWYoTSE9PTApcmV0dXJuIEcoTSk7cmV0dXJuIFYuZGVjb2RlUmVzcChPKX1pZGVudGl0eT0oKT0+e2xldHtob3N0OiQsZW5jbGF2ZTpafT10aGlzO3JldHVybiBaLmRlcml2ZUlkZW50aXR5KCQubGFiZWwsJC5pZHg/PzApfTtzZWFsPWFzeW5jKCQpPT57bGV0e2NyeXB0bzpaLGVuY2xhdmU6Sn09dGhpcyxRPWF3YWl0IHRoaXMuaWRlbnRpdHkoKTtyZXR1cm4gQ0ooJCxRLFosSil9O3JlZ2lzdGVyPSgpPT50aGlzLmNhbGwoci51c2VyLFtdKTtwZWVrPSgkKT0+dGhpcy5jYWxsKHIucGVlayxbJF0pO3B1c2g9KCQpPT50aGlzLmNhbGwoci5wdXNoLCQpO3B1bGw9KCQpPT50aGlzLmNhbGwoci5wdWxsLCQpO2xpc3Rlbj1hc3luYygkLFosSik9PntsZXR7Y2xvY2s6USx0cmFuc3BvcnQ6Vn09dGhpcyx7bGlzdGVuZXI6WX09VixYPWF3YWl0IHRoaXMuaWRlbnRpdHkoKSxXPVEubm93KCksW3osS109YXdhaXQgVlooWCxXKTtpZihLIT09MClyZXR1cm4gSztyZXR1cm4gYXdhaXQgWS5jb25uZWN0KHosJCxaLEopfTtpc0Nvbm5lY3RlZCgpe2xldCAkPXRoaXMudHJhbnNwb3J0Py5saXN0ZW5lcjtpZigkJiZ0eXBlb2YgJC5jb25uZWN0ZWQ9PT0iZnVuY3Rpb24iKXJldHVybiAkLmNvbm5lY3RlZCgpO3JldHVybiEwfWNsb3NlTGlzdGVuZXIoKXt0aGlzLnRyYW5zcG9ydD8ubGlzdGVuZXI/LmRpc2Nvbm5lY3QoKX19dmFyIE5aPXtlbmNvZGUoJCxaKXtsZXQgSj0kLndyaXRlVmFyU3RyaW5nKFoubGJsKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFySW50KFouaWR4KTtpZihRIT09MClyZXR1cm4gUTtsZXQgVj0kLndyaXRlVmFySW50KFoubnVtKTtpZihWIT09MClyZXR1cm4gVjtyZXR1cm4gJC53cml0ZUJ5dGVzKFouaHNoKSwkLndyaXRlQnl0ZXMoWi5zaWcpLDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWRWYXJJbnQoKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXRbWSxYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbVyx6XT0kLnJlYWRCeXRlcyhJJCk7aWYoeiE9PTApcmV0dXJuIEcoeik7bGV0W0ssRl09JC5yZWFkQnl0ZXModzApO2lmKEYhPT0wKXJldHVybiBHKEYpO3JldHVybiBSKHtsYmw6WixpZHg6USxudW06WSxoc2g6VyxzaWc6S30pfX07dmFyIFJaPXtlbmNvZGUoJCxaKXtsZXQgSj0kLndyaXRlU3RydWN0KE5aLFouaGVhZCk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZVZhckJ5dGVzKFouaW5kZXhFbmMpO2lmKFEhPT0wKXJldHVybiBRO2xldCBWPSQud3JpdGVWYXJCeXRlcyhaLmJvZHlFbmMpO2lmKFYhPT0wKXJldHVybiBWO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkU3RydWN0KE5aKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWRWYXJCeXRlcygpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtZLFhdPSQucmVhZFZhckJ5dGVzKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIFIoe2hlYWQ6WixpbmRleEVuYzpRLGJvZHlFbmM6WX0pfX07dmFyIFVaPXtlbmNvZGUoJCxaKXskLndyaXRlQnl0ZXMoWi5rZG0pO2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmhlYWRDcGgpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJJbnQoWi5sZW5Cb2R5KTtpZihRIT09MClyZXR1cm4gUTtpZihaLmxlbkJvZHk+MCYmWi5vZmZCb2R5IT09dm9pZCAwKXtsZXQgVj0kLndyaXRlVmFySW50KFoub2ZmQm9keSk7aWYoViE9PTApcmV0dXJuIFZ9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRCeXRlcyhUMCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsVl09JC5yZWFkVmFyQnl0ZXMoKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXRbWSxYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXQgVztpZihZPjApe2xldFt6LEtdPSQucmVhZFZhckludCgpO2lmKEshPT0wKXJldHVybiBHKEspO1c9en1yZXR1cm4gUih7a2RtOlosaGVhZENwaDpRLGxlbkJvZHk6WSxvZmZCb2R5Old9KX19O2FzeW5jIGZ1bmN0aW9uIExKKCQsWixKLFEsVil7bGV0IFk9YXdhaXQgVi5kZXJpdmVJZGVudGl0eSgkLFopLFg9bmV3IFMsVz1uZXcgUyx6PTAsSz0wO2ZvcihsZXQgUCBvZiBKKXtsZXQgQz1uZXcgUyxUPUMud3JpdGVTdHJ1Y3QoWDAsUC5oZWFkKTtpZihUIT09MClyZXR1cm4gRyhUKTtsZXQgTT1DLnJlc3VsdCgpLEE9YXdhaXQgWS5rZG1Gb3IoTSkseD1WLmRlcml2ZUNpcGhlcihBLCJlbmNyeXB0IiksbT1hd2FpdCB4LmVuY3J5cHQoTSksRT1QLmJvZHk/YXdhaXQgeC5lbmNyeXB0KFAuYm9keSk6bmV3IFVpbnQ4QXJyYXkoMCksaz1QLmhlYWQubGVuPjAmJlAuaGVhZC5oc2ghPT12b2lkIDA/RS5sZW5ndGg6MCxiPXtrZG06QSxoZWFkQ3BoOm0sbGVuQm9keTprLG9mZkJvZHk6az4wP0s6dm9pZCAwfSx3PVgud3JpdGVTdHJ1Y3QoVVosYik7aWYodyE9PTApcmV0dXJuIEcodyk7aWYoUC5ib2R5KVcud3JpdGVCeXRlcyhFKSxLKz1FLmxlbmd0aDt6Kyt9bGV0IEY9Vy5yZXN1bHQoKSxOPVgucmVzdWx0KCksVT1hd2FpdCBRLmJsYWtlMyhOKSxPPWF3YWl0IFkuc2lnbihVKSxxPXtsYmw6JCxpZHg6WixudW06eixoc2g6VSxzaWc6T30sST1uZXcgUztJLndyaXRlU3RydWN0KFJaLHtoZWFkOnEsaW5kZXhFbmM6Tixib2R5RW5jOkZ9KTtsZXQgSD1JLnJlc3VsdCgpO3JldHVybiBSKEgpfWFzeW5jIGZ1bmN0aW9uIHhKKCQsWixKKXtsZXRbUSxWXT1SWi5kZWNvZGUobmV3IGcoJCkpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldHtoZWFkOlksaW5kZXhFbmM6WCxib2R5RW5jOld9PVEsej1hd2FpdCBKLmRlcml2ZUlkZW50aXR5KFkubGJsLFkuaWR4KTtpZighYXdhaXQgWi5jaGVja1NpZ0VkMjU1MTkoWS5zaWcsWS5oc2gsei5wdWJsaWNLZXkpKXJldHVybiBHKDMpO2xldCBGPWF3YWl0IFouYmxha2UzKFgpO2lmKCFWMChGLFkuaHNoKSlyZXR1cm4gRygxOSk7bGV0IE49bmV3IGcoWCksVT1bXTtmb3IobGV0IHE9MDtxPFkubnVtO3ErKyl7bGV0W0ksSF09Ti5yZWFkU3RydWN0KFVaKTtpZihIIT09MClyZXR1cm4gRyhIKTtVLnB1c2goSSl9aWYoVS5sZW5ndGghPT1ZLm51bSlyZXR1cm4gRygxNCk7bGV0IE89W107Zm9yKGxldCBxIG9mIFUpe2xldCBJPUouZGVyaXZlQ2lwaGVyKHEua2RtLCJkZWNyeXB0IiksSDt0cnl7SD1hd2FpdCBJLmRlY3J5cHQocS5oZWFkQ3BoKX1jYXRjaHtyZXR1cm4gRygyMCl9bGV0W1AsQ109WDAuZGVjb2RlKG5ldyBnKEgpKTtpZihDIT09MClyZXR1cm4gRyhDKTtsZXQgVDtpZihxLmxlbkJvZHk+MCYmcS5vZmZCb2R5IT09dm9pZCAwKXtpZihQLmhzaD09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0IE09Vy5zbGljZShxLm9mZkJvZHkscS5vZmZCb2R5K3EubGVuQm9keSk7dHJ5e1Q9YXdhaXQgSS5kZWNyeXB0KE0pfWNhdGNoe3JldHVybiBHKDIwKX1sZXQgQT1hd2FpdCBaLmJsYWtlMyhUKTtpZighVjAoQSxQLmhzaCkpcmV0dXJuIEcoMTkpfU8ucHVzaCh7aGVhZDpQLGJvZHk6VH0pfXJldHVybiBSKE8pfWFzeW5jIGZ1bmN0aW9uIGZKKHtub3c6JCxib2Q6WixjcnlwdG86Sn0pe2xldCBRPWF3YWl0IEouZ2VuUmFuZG9tQnl0ZXMoOCksVj1uZXcgUyxZPVYud3JpdGVTdHJ1Y3QoUTAse2lkOlEsdHM6JH0pO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBYPVYucmVzdWx0KCk7cmV0dXJuIHgkKHtub3c6JCxlaWQ6WCxjdHI6MCxib2Q6WixjcnlwdG86Sn0pfWFzeW5jIGZ1bmN0aW9uIHgkKHtub3c6JCxlaWQ6WixjdHI6Sixib2Q6USxjcnlwdG86Vn0pe2xldCBZPW5ldyBnKFopLFtYLFddPVEwLmRlY29kZShZKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXQgej0kLmdldFRpbWUoKS1YLnRzLmdldFRpbWUoKSxLLEY9UT8ubGVuZ3RoPz8wO2lmKFEmJkY+MClLPWF3YWl0IFYuYmxha2UzKFEpO3JldHVybiBSKHtlaWQ6WixvZmY6eixjdHI6SixsZW46Rixoc2g6S30pfWZ1bmN0aW9uIEpWKCQsWil7bGV0IEo9JC5sZW5ndGg8Wi5sZW5ndGg/JC5sZW5ndGg6Wi5sZW5ndGg7Zm9yKGxldCBRPTA7UTxKO1ErKylpZigkW1FdIT09WltRXSlyZXR1cm4gJFtRXS1aW1FdO3JldHVybiAkLmxlbmd0aC1aLmxlbmd0aH1hc3luYyBmdW5jdGlvbiB6JCgkLFope2xldCBKPUFycmF5LmZyb20oJCk7Si5zb3J0KEpWKTtsZXQgUT0wO2ZvcihsZXQgWCBvZiBKKVErPVgubGVuZ3RoO2xldCBWPW5ldyBVaW50OEFycmF5KFEpLFk9MDtmb3IobGV0IFggb2YgSilWLnNldChYLFkpLFkrPVgubGVuZ3RoO3JldHVybiBaLmJsYWtlMyhWKX1mdW5jdGlvbiBRVigkKXtsZXQgWj1uZXcgUyxKPVoud3JpdGVWYXJCeXRlcygkLmVpZCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0IFE9Wi53cml0ZURhdGUoJC51cGRhdGVkQXQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBWPVoud3JpdGVWYXJJbnQoJC5jdHIpO2lmKFYhPT0wKXJldHVybiBHKFYpO3JldHVybiBSKFoucmVzdWx0KCkpfWFzeW5jIGZ1bmN0aW9uIGYkKCQsWil7bGV0IEo9W107Zm9yKGxldCBRIG9mICQpe2xldFtWLFldPVFWKFEpO2lmKFkhPT0wfHwhVilyZXR1cm4gRyhZKTtKLnB1c2goVil9cmV0dXJuIFIoYXdhaXQgeiQoSixaKSl9dmFyIHNXPVN5bWJvbCgiTWFzdGVyU2VlZCIpLHRXPVN5bWJvbCgiU2VhbGVkTWFzdGVyS2V5IiksUjA9MzIsa0o9MjQrUjArMTY7ZnVuY3Rpb24gdCgkKXtpZigkLmJ5dGVMZW5ndGghPT1SMClyZXR1cm4gRygxMCk7cmV0dXJuIFIoJCl9ZnVuY3Rpb24gajAoJCl7aWYoJC5ieXRlTGVuZ3RoIT09a0opcmV0dXJuIEcoMTApO3JldHVybiBSKCQpfXZhciAkRz1TeW1ib2woIkVudGl0eUlEIik7ZnVuY3Rpb24gQkooJCl7cmV0dXJuInR5cGUiaW4gJH12YXIgWkc9U3ltYm9sKCJEZXJpdmF0aW9uU2VlZCIpLEpHPVN5bWJvbCgiUHVibGljS2V5IiksUUc9U3ltYm9sKCJQcml2YXRlS2V5IiksVkc9U3ltYm9sKCJIb3N0U3BlY2lmaWNLZXlQYWlyIiksWUc9U3ltYm9sKCJIYXNoIik7ZnVuY3Rpb24gVlYoJCl7aWYoISQpcmV0dXJuITE7aWYodHlwZW9mICQhPT0ib2JqZWN0IilyZXR1cm4hMTtpZigiYm9keSJpbiAkPT09ITEpcmV0dXJuITE7aWYoInR5cGUiaW4gJD09PSExKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIFlWKCQpe2lmKCEkLmJvZHx8JC5ib2QubGVuZ3RoPT09MCl7bGV0IFE9e29mZjokLm9mZixjdHI6JC5jdHIsZWlkOiQuZWlkfTtyZXR1cm4gUihRKX1sZXQgWj1RWigkLmJvZCk7aWYoVlYoWik9PT0hMSlyZXR1cm4gY29uc29sZS53YXJuKCJtc2cgYm9keSBpbnZhbGlkIixaKSxHKDE0KTtsZXQgSj17b2ZmOiQub2ZmLGN0cjokLmN0cixlaWQ6JC5laWQsZ2lkOlouZ2lkLHBpZDpaLnBpZCx0YWdzOloudGFncyx0eXBlOloudHlwZSxib2R5OlouYm9keX07cmV0dXJuIFIoSil9Y2xhc3MgayR7YXBwbGllcjtlbWl0dGVyPW5ldyBYJDtjbGVhcmVyO29uRGlydHlFaWRzO2NhY2hlRHJpdmVuO3BlZXJJbmdlc3Q7Y29uc3RydWN0b3IoJCxaLEosUSl7dGhpcy5hcHBsaWVyPSQ7dGhpcy5jbGVhcmVyPVosdGhpcy5vbkRpcnR5RWlkcz1KLHRoaXMuY2FjaGVEcml2ZW49UT8uY2FjaGVEcml2ZW4/PyExLHRoaXMucGVlckluZ2VzdD1RPy5wZWVySW5nZXN0fWFwcGx5PWFzeW5jKCQpPT57bGV0IFo9W10sSj1bXTtmb3IobGV0IFcgb2YgJCl7bGV0W3osS109WVYoVyk7aWYoSi5wdXNoKEspLEshPT0wKWNvbnRpbnVlO1oucHVzaCh6KX1sZXR7c3RhdHM6USx0eXBlczpWLGVpZHM6WX09YXdhaXQgdGhpcy5hcHBsaWVyKFopLFg9W107Zm9yKGxldCBXPTA7VzwkLmxlbmd0aDtXKyspe2xldCB6PUpbV10sSz1RW1ddO2lmKHohPT0wKXtYLnB1c2goeik7Y29udGludWV9aWYoSyE9PTApe1gucHVzaChLKTtjb250aW51ZX1YLnB1c2goMCl9aWYoIXRoaXMuY2FjaGVEcml2ZW4pZm9yKGxldCBXIG9mIFYpdGhpcy5lbWl0dGVyLmVtaXQoVyxudWxsKTtpZihZLmxlbmd0aD4wKXRoaXMub25EaXJ0eUVpZHM/LihZKTtyZXR1cm4gWH07Y2xlYXI9YXN5bmMoKT0+e2xldCAkPWF3YWl0IHRoaXMuY2xlYXJlcigpO2lmKCQhPT0wKXJldHVybiAkO3JldHVybiB0aGlzLmVtaXR0ZXIuZW1pdEFsbChudWxsKSwkfTtub3RpZnk9KCQpPT57Zm9yKGxldCBaIG9mICQpdGhpcy5lbWl0dGVyLmVtaXQoWixudWxsKX07cmVmcmVzaD1hc3luYygkKT0+e2lmKHRoaXMucGVlckluZ2VzdCl7YXdhaXQgdGhpcy5wZWVySW5nZXN0KCQpO3JldHVybn19O29uPSgkLFopPT57dGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoJCxaKX07b2ZmPSgkLFopPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJCxaKX19dmFyIG49ImVudGl0aWVzIixCJD0iZW50aXR5X3R5cGVfY3JlYXRlZF9hdCIscVo9ImVudGl0eV90eXBlX3VwZGF0ZWRfYXQiLElaPSJlbnRpdHlfdHlwZV9ncm91cF9pZCIsSFo9ImVudGl0eV90eXBlX3BhcmVudF9pZCIsbjA9ImVudGl0eV90YWdzIixFSj0iZGIiLG1KPTEzO2Z1bmN0aW9uIFhWKCQpe3JldHVybiJ0eXAiaW4gJH1mdW5jdGlvbiBXVigkKXtsZXQgWj17Ym9kOiQuYm9keSxjcmQ6JC5jcmVhdGVkQXQsLi4uJC5jdHIhPT0wP3tjdHI6JC5jdHJ9Ont9LGVpZDpmKCQuZWlkKSxnaWQ6JC5naWQscGlkOiQucGlkP2YoJC5waWQpOnZvaWQgMCx0Z3M6JC50YWdzLHR5cDokLnR5cGUsdXBkOiQudXBkYXRlZEF0fTtpZihaLmdpZD09PXZvaWQgMClkZWxldGUgWi5naWQ7aWYoWi5waWQ9PT12b2lkIDApZGVsZXRlIFoucGlkO2lmKFoudGdzPT09dm9pZCAwKWRlbGV0ZSBaLnRncztpZihaLmN0cj09PXZvaWQgMClkZWxldGUgWi5jdHI7cmV0dXJuIFp9ZnVuY3Rpb24gR1YoJCl7aWYoIWkoJCkpcmV0dXJue2VpZDpmKCQuZWlkKSx1cGQ6JC51cGRhdGVkQXQsLi4uJC5jdHIhPT0wP3tjdHI6JC5jdHJ9Ont9fTtyZXR1cm4gV1YoJCl9ZnVuY3Rpb24gYzAoJCl7cmV0dXJue2JvZHk6JC5ib2QsY3JlYXRlZEF0OiQuY3JkLHVwZGF0ZWRBdDokLnVwZCxjdHI6JC5jdHI/PzAsdHlwZTokLnR5cCxlaWQ6RjAoJC5laWQpLGdpZDokLmdpZCxwaWQ6JC5waWQ/RjAoJC5waWQpOnZvaWQgMCwuLi4kLnRncyE9PXZvaWQgMD97dGFnczokLnRnc306e319fWZ1bmN0aW9uIE9aKCQpe2lmKFhWKCQpKXJldHVybiBjMCgkKTtyZXR1cm57ZWlkOkYwKCQuZWlkKSx1cGRhdGVkQXQ6JC51cGQsY3RyOiQuY3RyPz8wfX1jbGFzcyBnSntkYjtvcGVuaW5nO2FzeW5jIGluaXQoKXthd2FpdCB0aGlzLmVuc3VyZURiKCl9YXN5bmMgZW5zdXJlRGIoKXtpZih0aGlzLmRiKXJldHVybiB0aGlzLmRiO2lmKHRoaXMub3BlbmluZylyZXR1cm4gdGhpcy5vcGVuaW5nO3JldHVybiB0aGlzLm9wZW5pbmc9S1YoKS50aGVuKCgkKT0+e3JldHVybiAkLm9udmVyc2lvbmNoYW5nZT0oKT0+e2lmKCQuY2xvc2UoKSx0aGlzLmRiPT09JCl0aGlzLmRiPXZvaWQgMH0sdGhpcy5kYj0kLHRoaXMub3BlbmluZz12b2lkIDAsJH0sKCQpPT57dGhyb3cgdGhpcy5vcGVuaW5nPXZvaWQgMCwkfSksdGhpcy5vcGVuaW5nfWFwcGx5PWFzeW5jKCQpPT57bGV0IFo9bmV3IFNldCxKPVtdLFE7dHJ5e1E9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybntzdGF0czokLm1hcCgoKT0+MTYpLHR5cGVzOlosZWlkczpKfX1sZXQgVj1RLnRyYW5zYWN0aW9uKG4sInJlYWR3cml0ZSIpLFk9Vi5vYmplY3RTdG9yZShuKTtyZXR1cm4gbmV3IFByb21pc2UoKFgpPT57bGV0IFc9QXJyYXkoJC5sZW5ndGgpLmZpbGwoMCk7aWYoJC5sZW5ndGg8MSl7WCh7c3RhdHM6W10sdHlwZXM6WixlaWRzOkp9KTtyZXR1cm59Vi5vbmNvbXBsZXRlPSgpPT57WCh7c3RhdHM6Vyx0eXBlczpaLGVpZHM6Sn0pfSxWLm9uZXJyb3I9KCk9Pntmb3IobGV0IEs9MDtLPFcubGVuZ3RoO0srKylpZihXW0tdPT09dm9pZCAwKVdbS109MTg7WCh7c3RhdHM6Vyx0eXBlczpaLGVpZHM6Sn0pfTtsZXQgej1uZXcgTWFwO2ZvcihsZXQgSz0wO0s8JC5sZW5ndGg7SysrKXtsZXQgRj0kW0tdLE49ZihGLmVpZCksVT17b3A6RixpbmRleDpLfSxPPXouZ2V0KE4pO2lmKE8pTy5wdXNoKFUpO2Vsc2Ugei5zZXQoTixbVV0pfWZvcihsZXRbSyxGXW9mIHope2lmKEYubGVuZ3RoPDEpY29udGludWU7bGV0IE49WS5nZXQoSyk7Ti5vbnN1Y2Nlc3M9KCk9PntsZXQgVT1OLnJlc3VsdCxPPVU/T1ooVSk6dm9pZCAwLHE9ITE7Zm9yKGxldHtvcDpJLGluZGV4Okh9b2YgRil7bGV0W1AsQ109ZDAoTyxJKTtpZihDIT09MCl7V1tIXT1DO2NvbnRpbnVlfWlmKFA9PT12b2lkIDApe1dbSF09MTI7Y29udGludWV9cT0hMDtmb3IobGV0IFQgb2YgcjAoTyxQKSlaLmFkZChUKTtPPVB9aWYocSlKLnB1c2goRlswXS5vcC5laWQpO2lmKE8pe2xldCBJPVkucHV0KEdWKE8pKTtJLm9uZXJyb3I9KEgpPT57SC5wcmV2ZW50RGVmYXVsdCgpO2ZvcihsZXR7aW5kZXg6UH1vZiBGKVdbUF09MTh9fX0sTi5vbmVycm9yPSgpPT57Zm9yKGxldHtpbmRleDpVfW9mIEYpV1tVXT0xOH19fSl9O2FzeW5jIGNsZWFyKCl7bGV0ICQ7dHJ5eyQ9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiAxNn1sZXQgWj0kLnRyYW5zYWN0aW9uKG4sInJlYWR3cml0ZSIpLEo9Wi5vYmplY3RTdG9yZShuKTtyZXR1cm4gbmV3IFByb21pc2UoKFEpPT57Wi5vbmNvbXBsZXRlPSgpPT5RKDApLFoub25lcnJvcj0oKT0+USgxOCksSi5jbGVhcigpfSl9YXN5bmMgZ2V0Um93KCQpe2xldCBaO3RyeXtaPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IEo9ZigkKSxWPVoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFg9Vi5nZXQoSik7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1YLnJlc3VsdDtpZighVylZKFIodm9pZCAwKSk7ZWxzZSBZKFIoT1ooVykpKX0sWC5vbmVycm9yPSgpPT5ZKEcoMTgpKX0pfWFzeW5jIGdldEVudCgkKXtsZXRbWixKXT1hd2FpdCB0aGlzLmdldFJvdygkKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwfHwhaShaKSlyZXR1cm4gUih2b2lkIDApO3JldHVybiBSKFopfWFzeW5jIGdldEFsbE9mVHlwZVVwZGF0ZWRCZXR3ZWVuKCQsWixKKXtsZXQgUTt0cnl7UT1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBZPVEudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChxWik7cmV0dXJuIG5ldyBQcm9taXNlKChYKT0+e2xldCBXPVkuZ2V0QWxsKElEQktleVJhbmdlLmJvdW5kKFskLFpdLFskLEpdKSk7Vy5vbnN1Y2Nlc3M9KCk9PntsZXQgej1XLnJlc3VsdDtYKFIoei5tYXAoYzApKSl9LFcub25lcnJvcj0oKT0+WChHKDE4KSl9KX1hc3luYyBnZXRHcm91cE1lbWJlcnMoJCxaKXtsZXQgSjt0cnl7Sj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBWPUoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChJWik7cmV0dXJuIG5ldyBQcm9taXNlKChZKT0+e2xldCBYPVYuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoWyQsWl0pKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0O1koUihXLm1hcChjMCkpKX0sWC5vbmVycm9yPSgpPT5ZKEcoMTgpKX0pfWFzeW5jIGdldEFsbE9mVHlwZSgkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBRPVoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChCJCk7cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBZPVEuZ2V0QWxsKElEQktleVJhbmdlLmJvdW5kKFskXSxbJCxbXV0pKTtZLm9uc3VjY2Vzcz0oKT0+e2xldCBYPVkucmVzdWx0O1YoUihYLm1hcChjMCkpKX0sWS5vbmVycm9yPSgpPT5WKEcoMTgpKX0pfWFzeW5jIGdldEJ5VGFnKCQsWil7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgVj1KLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgobjApO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgWD1WLmdldEFsbChJREJLZXlSYW5nZS5vbmx5KFopKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCB6PVgucmVzdWx0LmZpbHRlcigoSyk9PksudHlwPT09JCkubWFwKGMwKTtZKFIoeikpfSxYLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9YXN5bmMgZ2V0QWxsRW50aXRpZXMoJCl7aWYoInBpZCJpbiAkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBKPWYoJC5waWQpLFY9Wi50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KEhaKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFg9Vi5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShbJC50eXBlLEpdKSk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgej1YLnJlc3VsdC5tYXAoYzApO1koUih6KSl9LFgub25lcnJvcj0oKT0+WShHKDE4KSl9KX1lbHNlIGlmKCJnaWQiaW4gJClyZXR1cm4gYXdhaXQgdGhpcy5nZXRHcm91cE1lbWJlcnMoJC50eXBlLCQuZ2lkKTtlbHNlIGlmKCJ0YWciaW4gJClyZXR1cm4gYXdhaXQgdGhpcy5nZXRCeVRhZygkLnR5cGUsJC50YWcpO2Vsc2UgaWYoInVwZGF0ZWRCZXR3ZWVuImluICQpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0QWxsT2ZUeXBlVXBkYXRlZEJldHdlZW4oJC50eXBlLCQudXBkYXRlZEJldHdlZW4uc3RhcnQsJC51cGRhdGVkQmV0d2Vlbi5lbmQpO3JldHVybiBhd2FpdCB0aGlzLmdldEFsbE9mVHlwZSgkLnR5cGUpfWFzeW5jIGdldEVudGl0aWVzKCQpe2xldFtaLEpdPWF3YWl0IHRoaXMuZ2V0QWxsRW50aXRpZXMoJCk7aWYoSiE9PTApcmV0dXJuIEcoSik7cmV0dXJuIFIoWil9YXN5bmMgY291bnRFbnRpdGllcyh7dHlwZTokfSl7bGV0IFo7dHJ5e1o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgUT1aLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgoQiQpO3JldHVybiBuZXcgUHJvbWlzZSgoVik9PntsZXQgWT1JREJLZXlSYW5nZS5ib3VuZChbJF0sWyQsW11dKSxYPVEuY291bnQoWSk7WC5vbnN1Y2Nlc3M9KCk9PlYoUihYLnJlc3VsdCkpLFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBjaGVja3N1bSgkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBRPVoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKSxWPVtdO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgWD1RLm9wZW5DdXJzb3IoKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0O2lmKFcpe2xldCB6PVcudmFsdWU7Vi5wdXNoKEUkKE9aKHopKSksVy5jb250aW51ZSgpfWVsc2UgZiQoViwkKS50aGVuKFkpfSxYLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9fWZ1bmN0aW9uIHpWKCQsWil7aWYoISQub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhuKSkkLmNyZWF0ZU9iamVjdFN0b3JlKG4se2tleVBhdGg6ImVpZCIsYXV0b0luY3JlbWVudDohMX0pO2xldCBKPVoub2JqZWN0U3RvcmUobik7aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhCJCkpSi5jcmVhdGVJbmRleChCJCxbInR5cCIsImNyZCJdLHt1bmlxdWU6ITF9KTtpZighSi5pbmRleE5hbWVzLmNvbnRhaW5zKHFaKSlKLmNyZWF0ZUluZGV4KHFaLFsidHlwIiwidXBkIl0se3VuaXF1ZTohMX0pO2lmKCFKLmluZGV4TmFtZXMuY29udGFpbnMoSVopKUouY3JlYXRlSW5kZXgoSVosWyJ0eXAiLCJnaWQiXSx7dW5pcXVlOiExfSk7aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhIWikpSi5jcmVhdGVJbmRleChIWixbInR5cCIsInBpZCJdLHt1bmlxdWU6ITF9KTtpZihKLmluZGV4TmFtZXMuY29udGFpbnMobjApKXtpZihKLmluZGV4KG4wKS5rZXlQYXRoIT09InRncyIpSi5kZWxldGVJbmRleChuMCl9aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhuMCkpSi5jcmVhdGVJbmRleChuMCwidGdzIix7dW5pcXVlOiExLG11bHRpRW50cnk6ITB9KX1mdW5jdGlvbiBLVigpe3JldHVybiBuZXcgUHJvbWlzZSgoJCxaKT0+e2xldCBKPWluZGV4ZWREQi5vcGVuKEVKLG1KKTtKLm9udXBncmFkZW5lZWRlZD0oKT0+e2xldHtyZXN1bHQ6USx0cmFuc2FjdGlvbjpWfT1KO2lmKCFWKXtaKEVycm9yKCJUcmFuc2FjdGlvbiBpcyBudWxsIGR1cmluZyBFbnREQiB1cGdyYWRlIikpO3JldHVybn10cnl7elYoUSxWKX1jYXRjaChZKXtaKFkgaW5zdGFuY2VvZiBFcnJvcj9ZOkVycm9yKFN0cmluZyhZKSkpfX0sSi5vbmJsb2NrZWQ9KCk9Pntjb25zb2xlLndhcm4oYFtESVBMT01BVElDXSBFbnREQiBJREIgdXBncmFkZSBibG9ja2VkICgke0VKfSDihpIgdiR7bUp9KTsgd2FpdGluZyBmb3Igb3RoZXIgY29ubmVjdGlvbnMgdG8gY2xvc2VgKX0sSi5vbnN1Y2Nlc3M9KCk9PiQoSi5yZXN1bHQpLEoub25lcnJvcj0oKT0+WihKLmVycm9yPz9FcnJvcigiRW50REIgSW5kZXhlZERCIG9wZW4gZmFpbGVkIikpfSl9YXN5bmMgZnVuY3Rpb24gU0ooKXtsZXQgJD1uZXcgZ0o7cmV0dXJuIGF3YWl0ICQuaW5pdCgpLCR9Y2xhc3MgTVp7ZW50cz1uZXcgTWFwO3VzZUluZGV4O2J5VHlwZT1uZXcgTWFwO2J5VHlwZVBpZD1uZXcgTWFwO2J5VHlwZUdpZD1uZXcgTWFwO2J5VHlwZVRhZz1uZXcgTWFwO2NvbnN0cnVjdG9yKCQ9W10sWil7dGhpcy51c2VJbmRleD1aPy5pbmRleGVzIT09ITE7Zm9yKGxldCBKIG9mICQpdGhpcy5wdXQoSil9cHV0KCQpe2xldCBaPWYoJC5laWQpLEo9dGhpcy5lbnRzLmdldChaKTtpZihKIT09dm9pZCAwJiZpKEopKXRoaXMudW5pbmRleChaLEopO2lmKHRoaXMuZW50cy5zZXQoWiwkKSxpKCQpKXRoaXMuaW5kZXgoWiwkKX1kZWwoJCl7bGV0IFo9dGhpcy5lbnRzLmdldCgkKTtpZihaPT09dm9pZCAwKXJldHVybjtpZihpKFopKXRoaXMudW5pbmRleCgkLFopO3RoaXMuZW50cy5kZWxldGUoJCl9aW5kZXgoJCxaKXtpZighdGhpcy51c2VJbmRleClyZXR1cm47bGV0IEo9dGhpcy5ieVR5cGUuZ2V0KFoudHlwZSk7aWYoIUopSj1uZXcgTWFwLHRoaXMuYnlUeXBlLnNldChaLnR5cGUsSik7aWYoSi5zZXQoJCxaKSxaLnBpZCl7bGV0IFE9ZihaLnBpZCksVj10aGlzLmJ5VHlwZVBpZC5nZXQoWi50eXBlKTtpZighVilWPW5ldyBNYXAsdGhpcy5ieVR5cGVQaWQuc2V0KFoudHlwZSxWKTtsZXQgWT1WLmdldChRKTtpZighWSlZPW5ldyBNYXAsVi5zZXQoUSxZKTtZLnNldCgkLFopfWlmKHR5cGVvZiBaLmdpZD09PSJzdHJpbmciKXtsZXQgUT10aGlzLmJ5VHlwZUdpZC5nZXQoWi50eXBlKTtpZighUSlRPW5ldyBNYXAsdGhpcy5ieVR5cGVHaWQuc2V0KFoudHlwZSxRKTtsZXQgVj1RLmdldChaLmdpZCk7aWYoIVYpVj1uZXcgTWFwLFEuc2V0KFouZ2lkLFYpO1Yuc2V0KCQsWil9aWYoWi50YWdzKXtsZXQgUT10aGlzLmJ5VHlwZVRhZy5nZXQoWi50eXBlKTtpZighUSlRPW5ldyBNYXAsdGhpcy5ieVR5cGVUYWcuc2V0KFoudHlwZSxRKTtmb3IobGV0IFYgb2YgWi50YWdzKXtsZXQgWT1RLmdldChWKTtpZighWSlZPW5ldyBNYXAsUS5zZXQoVixZKTtZLnNldCgkLFopfX19dW5pbmRleCgkLFope2lmKCF0aGlzLnVzZUluZGV4KXJldHVybjtsZXQgSj10aGlzLmJ5VHlwZS5nZXQoWi50eXBlKTtpZihKKXtpZihKLmRlbGV0ZSgkKSxKLnNpemU9PT0wKXRoaXMuYnlUeXBlLmRlbGV0ZShaLnR5cGUpfWlmKFoucGlkKXtsZXQgUT1mKFoucGlkKSxWPXRoaXMuYnlUeXBlUGlkLmdldChaLnR5cGUpLFk9Vj8uZ2V0KFEpO2lmKFkpe2lmKFkuZGVsZXRlKCQpLFkuc2l6ZT09PTApVj8uZGVsZXRlKFEpfWlmKFYmJlYuc2l6ZT09PTApdGhpcy5ieVR5cGVQaWQuZGVsZXRlKFoudHlwZSl9aWYodHlwZW9mIFouZ2lkPT09InN0cmluZyIpe2xldCBRPXRoaXMuYnlUeXBlR2lkLmdldChaLnR5cGUpLFY9UT8uZ2V0KFouZ2lkKTtpZihWKXtpZihWLmRlbGV0ZSgkKSxWLnNpemU9PT0wKVE/LmRlbGV0ZShaLmdpZCl9aWYoUSYmUS5zaXplPT09MCl0aGlzLmJ5VHlwZUdpZC5kZWxldGUoWi50eXBlKX1pZihaLnRhZ3Mpe2xldCBRPXRoaXMuYnlUeXBlVGFnLmdldChaLnR5cGUpO2lmKFEpe2ZvcihsZXQgViBvZiBaLnRhZ3Mpe2xldCBZPVEuZ2V0KFYpO2lmKFkpe2lmKFkuZGVsZXRlKCQpLFkuc2l6ZT09PTApUS5kZWxldGUoVil9fWlmKFEuc2l6ZT09PTApdGhpcy5ieVR5cGVUYWcuZGVsZXRlKFoudHlwZSl9fX1jbGVhckluZGV4ZXMoKXt0aGlzLmJ5VHlwZS5jbGVhcigpLHRoaXMuYnlUeXBlUGlkLmNsZWFyKCksdGhpcy5ieVR5cGVHaWQuY2xlYXIoKSx0aGlzLmJ5VHlwZVRhZy5jbGVhcigpfWJ1Y2tldExpc3QoJCl7aWYoISR8fCQuc2l6ZT09PTApcmV0dXJuW107bGV0IFo9W107Zm9yKGxldCBKIG9mICQudmFsdWVzKCkpWi5wdXNoKEopO3JldHVybiBafWFzeW5jIGFwcGx5KCQpe2xldCBaPW5ldyBTZXQsSj1bXSxRPVtdO2ZvcihsZXQgViBvZiAkKXtsZXQgWT1mKFYuZWlkKSxYPXRoaXMuZW50cy5nZXQoWSksW1csel09ZDAoWCxWKTtpZih6IT09MCl7US5wdXNoKHopO2NvbnRpbnVlfWlmKFc9PT12b2lkIDApe1EucHVzaCgxMik7Y29udGludWV9Zm9yKGxldCBLIG9mIHIwKFgsVykpWi5hZGQoSyk7dGhpcy5wdXQoVyksSi5wdXNoKFYuZWlkKSxRLnB1c2goMCl9cmV0dXJue3N0YXRzOlEsdHlwZXM6WixlaWRzOkp9fWFzeW5jIGNsZWFyKCl7cmV0dXJuIHRoaXMuZW50cy5jbGVhcigpLHRoaXMuY2xlYXJJbmRleGVzKCksMH1hc3luYyBnZXRSb3coJCl7bGV0IFo9ZigkKSxKPXRoaXMuZW50cy5nZXQoWik7cmV0dXJuIFIoSil9YXN5bmMgZ2V0RW50KCQpe2xldFtaLEpdPWF3YWl0IHRoaXMuZ2V0Um93KCQpO2lmKEohPT0wKXJldHVybiBHKEopO2lmKFo9PT12b2lkIDB8fCFpKFopKXJldHVybiBSKHZvaWQgMCk7cmV0dXJuIFIoWil9YXN5bmMgZ2V0QWxsRW50aXRpZXMoe3R5cGU6JCxnaWQ6WixwaWQ6Six0YWc6USx1cGRhdGVkQmV0d2VlbjpWfSl7aWYodGhpcy51c2VJbmRleCl7aWYoSiE9PXZvaWQgMCl7bGV0IFg9ZihKKTtyZXR1cm4gUih0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGVQaWQuZ2V0KCQpPy5nZXQoWCkpKX1pZihaIT09dm9pZCAwKXJldHVybiBSKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZUdpZC5nZXQoJCk/LmdldChaKSkpO2lmKFEhPT12b2lkIDApcmV0dXJuIFIodGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlVGFnLmdldCgkKT8uZ2V0KFEpKSk7aWYoViE9PXZvaWQgMCl7bGV0IFg9W10sVz10aGlzLmJ5VHlwZS5nZXQoJCk7aWYoVyl7Zm9yKGxldCB6IG9mIFcudmFsdWVzKCkpaWYoei51cGRhdGVkQXQ+PVYuc3RhcnQmJnoudXBkYXRlZEF0PD1WLmVuZClYLnB1c2goeil9cmV0dXJuIFIoWCl9cmV0dXJuIFIodGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlLmdldCgkKSkpfWxldCBZPVtdO2lmKEohPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaShYKSYmWC50eXBlPT09JCYmWC5waWQmJlYwKFgucGlkLEopKVkucHVzaChYKX1lbHNlIGlmKFohPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaShYKSYmWC50eXBlPT09JCYmKHR5cGVvZiBYLmdpZD09PSJzdHJpbmciJiZYLmdpZD09PVopKVkucHVzaChYKX1lbHNlIGlmKFEhPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaShYKSYmWC50eXBlPT09JCYmWC50YWdzJiZYLnRhZ3MuaW5jbHVkZXMoUSkpWS5wdXNoKFgpfWVsc2UgaWYoViE9PXZvaWQgMCl7Zm9yKGxldCBYIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihpKFgpJiZYLnR5cGU9PT0kJiZYLnVwZGF0ZWRBdD49Vi5zdGFydCYmWC51cGRhdGVkQXQ8PVYuZW5kKVkucHVzaChYKX1lbHNlIGZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaShYKSYmWC50eXBlPT09JClZLnB1c2goWCk7cmV0dXJuIFIoWSl9YXN5bmMgZ2V0RW50aXRpZXMoJCl7bGV0W1osSl09YXdhaXQgdGhpcy5nZXRBbGxFbnRpdGllcygkKTtpZihKIT09MClyZXR1cm4gRyhKKTtyZXR1cm4gUihaKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtpZih0aGlzLnVzZUluZGV4KXJldHVybiBSKHRoaXMuYnlUeXBlLmdldCgkKT8uc2l6ZT8/MCk7bGV0IFo9MDtmb3IobGV0IEogb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGkoSikmJkoudHlwZT09PSQpWis9MTtyZXR1cm4gUihaKX1hc3luYyBjaGVja3N1bSgkKXtsZXQgWj1bXTtmb3IobGV0IEogb2YgdGhpcy5lbnRzLnZhbHVlcygpKVoucHVzaChFJChKKSk7cmV0dXJuIGYkKFosJCl9fWFzeW5jIGZ1bmN0aW9uIHZKKCQpe2xldCBaPWF3YWl0IFNKKCk7aWYoJD8uY2FjaGU9PT0hMSlyZXR1cm4gWjtyZXR1cm4gbmV3IENaKFosdm9pZCAwLHtpbmRleGVzOiQ/LmluZGV4ZXN9KX1jbGFzcyBDWnttZW07ZHVyYWJsZTt3YXJtZWQ9bmV3IFNldDtsaXN0ZW5lcnM9bmV3IFNldDtjaGFpbj1Qcm9taXNlLnJlc29sdmUoKTtjb25zdHJ1Y3RvcigkLFosSil7aWYodGhpcy5kdXJhYmxlPSQsdGhpcy5tZW09bmV3IE1aKFo/P1tdLHtpbmRleGVzOko/LmluZGV4ZXN9KSxaKWZvcihsZXQgUSBvZiBaKXRoaXMud2FybWVkLmFkZChRLnR5cGUpfXN1YnNjcmliZSgkKXtyZXR1cm4gdGhpcy5saXN0ZW5lcnMuYWRkKCQpLCgpPT57dGhpcy5saXN0ZW5lcnMuZGVsZXRlKCQpfX1lbWl0KCQpe2lmKCQuc2l6ZTwxKXJldHVybjtmb3IobGV0IFogb2YgdGhpcy5saXN0ZW5lcnMpWigkKX1ydW4oJCl7bGV0IFo9dGhpcy5jaGFpbi50aGVuKCQsJCk7cmV0dXJuIHRoaXMuY2hhaW49Wi50aGVuKCgpPT57cmV0dXJufSwoKT0+e3JldHVybn0pLFp9YXBwbHkoJCl7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9Pnthd2FpdCB0aGlzLnB1bGxFaWRzKCQubWFwKChZKT0+WS5laWQpKTtsZXQgWj1xVih0aGlzLm1lbSwkKTt0aGlzLmVtaXQoWi50eXBlcyk7bGV0IEo9YXdhaXQgdGhpcy5kdXJhYmxlLmFwcGx5KCQpLHtjaGFuZ2VkOlEsc3RhdHVzOlZ9PWF3YWl0IHRoaXMucHVsbEVpZHMoJC5tYXAoKFkpPT5ZLmVpZCkpO2lmKHRoaXMuZW1pdChRKSxWIT09MClyZXR1cm57c3RhdHM6JC5tYXAoKCk9PlYpLHR5cGVzOkoudHlwZXMsZWlkczpKLmVpZHN9O3JldHVybiBKfSl9Y2xlYXIoKXtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2xldCAkPWF3YWl0IHRoaXMuZHVyYWJsZS5jbGVhcigpO2lmKCQhPT0wKXJldHVybiAkO2xldCBaPXRoaXMubWVtLmVudHMuc2l6ZT4wO3JldHVybiBhd2FpdCB0aGlzLm1lbS5jbGVhcigpLHRoaXMud2FybWVkLmNsZWFyKCksMH0pfWluZ2VzdEZyb21EdXJhYmxlKCQpe3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57bGV0e2NoYW5nZWQ6WixzdGF0dXM6Sn09YXdhaXQgdGhpcy5wdWxsRWlkcygkKTtyZXR1cm4gdGhpcy5lbWl0KFopLEp9KX1hc3luYyBwdWxsRWlkcygkKXtsZXQgWj1uZXcgU2V0LEo9bmV3IFNldDtmb3IobGV0IFEgb2YgJCl7bGV0IFY9ZihRKTtpZihKLmhhcyhWKSljb250aW51ZTtKLmFkZChWKTtsZXQgWT10aGlzLm1lbS5lbnRzLmdldChWKSxbWCxXXT1hd2FpdCB0aGlzLmR1cmFibGUuZ2V0Um93KFEpO2lmKFchPT0wKXJldHVybntjaGFuZ2VkOlosc3RhdHVzOld9O2lmKFgpe2lmKHRoaXMubWVtLnB1dChYKSwhWXx8IUZWKFksWCkpe2lmKGkoWCkpWi5hZGQoWC50eXBlKTtpZihZIT09dm9pZCAwJiZpKFkpKVouYWRkKFkudHlwZSl9fWVsc2UgaWYoWSE9PXZvaWQgMCl7aWYodGhpcy5tZW0uZGVsKFYpLGkoWSkpWi5hZGQoWS50eXBlKX19cmV0dXJue2NoYW5nZWQ6WixzdGF0dXM6MH19YXN5bmMgd2FybVR5cGUoJCl7aWYodGhpcy53YXJtZWQuaGFzKCQpKXJldHVybiAwO2xldFtaLEpdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRFbnRpdGllcyh7dHlwZTokfSk7aWYoSiE9PTApcmV0dXJuIEo7aWYoWilmb3IobGV0IFEgb2YgWil7bGV0IFY9ZihRLmVpZCksWT10aGlzLm1lbS5lbnRzLmdldChWKTtpZighWXx8T1YoUSxZKSl0aGlzLm1lbS5wdXQoUSl9cmV0dXJuIHRoaXMud2FybWVkLmFkZCgkKSwwfWFzeW5jIGdldFJvdygkKXtsZXQgWj1mKCQpO2lmKHRoaXMubWVtLmVudHMuaGFzKFopKXJldHVybiB0aGlzLm1lbS5nZXRSb3coJCk7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9PntpZih0aGlzLm1lbS5lbnRzLmhhcyhaKSlyZXR1cm4gdGhpcy5tZW0uZ2V0Um93KCQpO2xldFtKLFFdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRSb3coJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSil0aGlzLm1lbS5wdXQoSik7cmV0dXJuIFIoSil9KX1hc3luYyBnZXRFbnQoJCl7bGV0W1osSl09YXdhaXQgdGhpcy5nZXRSb3coJCk7aWYoSiE9PTApcmV0dXJuIEcoSik7aWYoWj09PXZvaWQgMHx8IWkoWikpcmV0dXJuIFIodm9pZCAwKTtyZXR1cm4gUihaKX1hc3luYyBnZXRFbnRpdGllcygkKXtpZighdGhpcy53YXJtZWQuaGFzKCQudHlwZSkpe2xldCBaPWF3YWl0IHRoaXMucnVuKCgpPT50aGlzLndhcm1UeXBlKCQudHlwZSkpO2lmKFohPT0wKXJldHVybiBHKFopfXJldHVybiB0aGlzLm1lbS5nZXRFbnRpdGllcygkKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtpZighdGhpcy53YXJtZWQuaGFzKCQpKXtsZXQgWj1hd2FpdCB0aGlzLnJ1bigoKT0+dGhpcy53YXJtVHlwZSgkKSk7aWYoWiE9PTApcmV0dXJuIEcoWil9cmV0dXJuIHRoaXMubWVtLmNvdW50RW50aXRpZXMoe3R5cGU6JH0pfWFzeW5jIGNoZWNrc3VtKCQpe3JldHVybiB0aGlzLmR1cmFibGUuY2hlY2tzdW0oJCl9fWZ1bmN0aW9uIEZWKCQsWil7aWYoaSgkKSE9PWkoWikpcmV0dXJuITE7aWYoJC5jdHIhPT1aLmN0cilyZXR1cm4hMTtpZigkLnVwZGF0ZWRBdC5nZXRUaW1lKCkhPT1aLnVwZGF0ZWRBdC5nZXRUaW1lKCkpcmV0dXJuITE7aWYoIVYwKCQuZWlkLFouZWlkKSlyZXR1cm4hMTtpZighaSgkKXx8IWkoWikpcmV0dXJuITA7aWYoJC5jcmVhdGVkQXQuZ2V0VGltZSgpIT09Wi5jcmVhdGVkQXQuZ2V0VGltZSgpKXJldHVybiExO2lmKCQudHlwZSE9PVoudHlwZSlyZXR1cm4hMTtpZigkLmdpZCE9PVouZ2lkKXJldHVybiExO2lmKCFSVigkLnBpZCxaLnBpZCkpcmV0dXJuITE7aWYoIU5WKCQudGFncyxaLnRhZ3MpKXJldHVybiExO3JldHVybiBVVigkLmJvZHksWi5ib2R5KX1mdW5jdGlvbiBOVigkLFope2lmKCQ9PT1aKXJldHVybiEwO2lmKCQ9PT12b2lkIDB8fFo9PT12b2lkIDApcmV0dXJuITE7aWYoJC5sZW5ndGghPT1aLmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IEo9MDtKPCQubGVuZ3RoO0orKylpZigkW0pdIT09WltKXSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBSVigkLFope2lmKCQ9PT12b2lkIDAmJlo9PT12b2lkIDApcmV0dXJuITA7aWYoJD09PXZvaWQgMHx8Wj09PXZvaWQgMClyZXR1cm4hMTtyZXR1cm4gVjAoJCxaKX1mdW5jdGlvbiBVVigkLFope2lmKE9iamVjdC5pcygkLFopKXJldHVybiEwO2lmKCQgaW5zdGFuY2VvZiBVaW50OEFycmF5JiZaIGluc3RhbmNlb2YgVWludDhBcnJheSlyZXR1cm4gVjAoJCxaKTtpZigkIGluc3RhbmNlb2YgRGF0ZSYmWiBpbnN0YW5jZW9mIERhdGUpcmV0dXJuICQuZ2V0VGltZSgpPT09Wi5nZXRUaW1lKCk7dHJ5e3JldHVybiBWMChfMCgkKSxfMChaKSl9Y2F0Y2h7cmV0dXJuITF9fWZ1bmN0aW9uIE9WKCQsWil7bGV0IEo9JC51cGRhdGVkQXQuZ2V0VGltZSgpLFE9Wi51cGRhdGVkQXQuZ2V0VGltZSgpO2lmKEohPT1RKXJldHVybiBKPlE7cmV0dXJuICQuY3RyPlouY3RyfWZ1bmN0aW9uIHFWKCQsWil7bGV0IEo9bmV3IFNldCxRPVtdO2ZvcihsZXQgViBvZiBaKXtsZXQgWT1mKFYuZWlkKSxYPSQuZW50cy5nZXQoWSksW1csel09ZDAoWCxWKTtpZih6IT09MCl7US5wdXNoKHopO2NvbnRpbnVlfWlmKFc9PT12b2lkIDApe1EucHVzaCgxMik7Y29udGludWV9Zm9yKGxldCBLIG9mIHIwKFgsVykpSi5hZGQoSyk7JC5wdXQoVyksUS5wdXNoKDApfXJldHVybntzdGF0czpRLHR5cGVzOkp9fWZ1bmN0aW9uIGkoJCl7cmV0dXJuInR5cGUiaW4gJH1mdW5jdGlvbiBJVigkKXtpZighQXJyYXkuaXNBcnJheSgkKXx8JC5sZW5ndGg9PT0wKXJldHVybjtsZXQgWj1uZXcgU2V0LEo9W107Zm9yKGxldCBRIG9mICQpe2lmKHR5cGVvZiBRIT09InN0cmluZyJ8fFEubGVuZ3RoPT09MCljb250aW51ZTtpZihaLmhhcyhRKSljb250aW51ZTtaLmFkZChRKSxKLnB1c2goUSl9cmV0dXJuIEoubGVuZ3RoPjA/Sjp2b2lkIDB9ZnVuY3Rpb24gRSQoJCl7cmV0dXJue2VpZDokLmVpZCxjdHI6JC5jdHIsdXBkYXRlZEF0OiQudXBkYXRlZEF0fX1mdW5jdGlvbiBiSigkKXtsZXQgWj1uZXcgZygkLmVpZCksW0osUV09Wi5yZWFkU3RydWN0KFEwKTtpZihRIT09MClyZXR1cm4gRyhRKTtyZXR1cm4gUih7ZWlkOiQuZWlkLGN0cjokLmN0cix1cGRhdGVkQXQ6bmV3IERhdGUoSi50cy5nZXRUaW1lKCkrJC5vZmYpfSl9ZnVuY3Rpb24gZDAoJCxaKXtsZXQgSj1uZXcgZyhaLmVpZCksW1EsVl09Si5yZWFkU3RydWN0KFEwKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXQgWT1uZXcgRGF0ZShRLnRzLmdldFRpbWUoKStaLm9mZik7aWYoJCE9PXZvaWQgMCYmWTw9JC51cGRhdGVkQXQpcmV0dXJuIEcoMTUpO2lmKEJKKFopKXtsZXQgWD1JVihaLnRhZ3MpO3JldHVybiBSKHtlaWQ6Wi5laWQsZ2lkOlouZ2lkLHBpZDpaLnBpZCwuLi5YIT09dm9pZCAwP3t0YWdzOlh9Ont9LHR5cGU6Wi50eXBlLGNyZWF0ZWRBdDpRLnRzLHVwZGF0ZWRBdDpZLGN0cjpaLmN0cixib2R5OlouYm9keX0pfXJldHVybiBSKHtlaWQ6Wi5laWQsdXBkYXRlZEF0OlksY3RyOlouY3RyfSl9ZnVuY3Rpb24gcjAoJCxaKXtsZXQgSj1uZXcgU2V0O2lmKCQhPT12b2lkIDAmJmkoJCkpSi5hZGQoJC50eXBlKTtpZihpKFopKUouYWRkKFoudHlwZSk7cmV0dXJuWy4uLkpdfWNsYXNzIG0ke2luZmxpZ2h0PW51bGw7YWdhaW49ITE7cnVuKCQpe2lmKHRoaXMuYWdhaW49ITAsdGhpcy5pbmZsaWdodClyZXR1cm4gdGhpcy5pbmZsaWdodDtyZXR1cm4gdGhpcy5pbmZsaWdodD10aGlzLmRyYWluKCQpLHRoaXMuaW5mbGlnaHR9YXN5bmMgZmx1c2goKXtpZighdGhpcy5pbmZsaWdodClyZXR1cm47dHJ5e2F3YWl0IHRoaXMuaW5mbGlnaHR9Y2F0Y2h7fX1hc3luYyBkcmFpbigkKXt0cnl7dGhpcy5hZ2Fpbj0hMTtsZXQgWj1hd2FpdCAkKCk7d2hpbGUodGhpcy5hZ2Fpbil0aGlzLmFnYWluPSExLFo9YXdhaXQgJCgpO3JldHVybiBafWZpbmFsbHl7dGhpcy5pbmZsaWdodD1udWxsfX19dmFyIHlKPTEwMDtjbGFzcyBQWnt0aW1lcj1udWxsO2RlbGF5TXM7d29yazt0YWlsPW5ldyBtJDtjb25zdHJ1Y3RvcigkLFope3RoaXMuZGVsYXlNcz0kPDA/MDokLHRoaXMud29yaz1afXNjaGVkdWxlKCl7aWYodGhpcy5kZWxheU1zPD0wKXt0aGlzLmZpcmUoKTtyZXR1cm59aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpO3RoaXMudGltZXI9c2V0VGltZW91dCgoKT0+e3RoaXMudGltZXI9bnVsbCx0aGlzLmZpcmUoKX0sdGhpcy5kZWxheU1zKX1hc3luYyBmbHVzaCgpe2lmKHRoaXMudGltZXIhPT1udWxsKWNsZWFyVGltZW91dCh0aGlzLnRpbWVyKSx0aGlzLnRpbWVyPW51bGwsdGhpcy5maXJlKCk7YXdhaXQgdGhpcy50YWlsLmZsdXNoKCl9Y2FuY2VsKCl7aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLHRoaXMudGltZXI9bnVsbH1maXJlKCl7cmV0dXJuIHRoaXMudGFpbC5ydW4odGhpcy53b3JrKX19ZnVuY3Rpb24gaUooJCl7bGV0IFo9bmV3IGcoJC5laWQpLFtKLFFdPVEwLmRlY29kZShaKTtpZihRIT09MClyZXR1cm47cmV0dXJuIEoudHMuZ2V0VGltZSgpKyQub2ZmfWZ1bmN0aW9uIEhWKCQsWil7bGV0IEo9aUooJCksUT1pSihaKTtpZihKPT09dm9pZCAwJiZRPT09dm9pZCAwKXJldHVybiAwO2lmKEo9PT12b2lkIDApcmV0dXJuIDE7aWYoUT09PXZvaWQgMClyZXR1cm4tMTtpZihRIT09SilyZXR1cm4gUS1KO3JldHVybiBaLmN0ci0kLmN0cn1mdW5jdGlvbiBvMCgkLFope3JldHVybiAkLnNsaWNlKCkuc29ydCgoSixRKT0+SFYoWihKKSxaKFEpKSl9dmFyIHdaPXtwaGFzZToiaWRsZSJ9LEskPTUwO2Z1bmN0aW9uIFRaKCQsWixKKXtpZigkPD0wfHxaPD0wKXJldHVybiExO2lmKCQ9PT0xfHwkPT09WilyZXR1cm4hMDtyZXR1cm4gJCVKPT09MH1mdW5jdGlvbiBoSigkLFope2lmKHR5cGVvZiBuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYj09PSJmdW5jdGlvbiIpe25hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iKCQsWik7cmV0dXJufWxldCBKPVVSTC5jcmVhdGVPYmplY3RVUkwoJCksUT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7US5ocmVmPUosUS5kb3dubG9hZD1aLGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoUSksUS5jbGljaygpLGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoUSksVVJMLnJldm9rZU9iamVjdFVSTChKKX1mdW5jdGlvbiB1SigkLFosSil7bGV0IFE9W10sVj1bXSxZPTA7Zm9yKGxldCBYIG9mICQpe2xldCBXPVooWCk7aWYoVi5sZW5ndGg+MCYmWStXPkopUS5wdXNoKFYpLFY9W10sWT0wO2lmKFYucHVzaChYKSxZKz1XLFk+PUopUS5wdXNoKFYpLFY9W10sWT0wfWlmKFYubGVuZ3RoPjApUS5wdXNoKFYpO3JldHVybiBRfWFzeW5jIGZ1bmN0aW9uIERaKCQsWixKKXtsZXQgUT0kLmxlbmd0aDtpZihRPDEpcmV0dXJuW107bGV0IFY9QXJyYXkoUSksWT0wLFg9TWF0aC5taW4oTWF0aC5tYXgoMSxaKSxRKSxXPWFzeW5jKCk9Pnt3aGlsZSghMCl7bGV0IEs9WTtpZihZKz0xLEs+PVEpcmV0dXJuO1ZbS109YXdhaXQgSigkW0tdLEspfX0sej1bXTtmb3IobGV0IEs9MDtLPFg7SysrKXoucHVzaChXKCkpO3JldHVybiBhd2FpdCBQcm9taXNlLmFsbCh6KSxWfWFzeW5jIGZ1bmN0aW9uIGckKCQsWixKLFEpe2xldCBWPW5ldyBnKCQuaGVhZENwaCksW1ksWF09Vi5yZWFkU3RydWN0KEEkKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXR7c2lnOlcsa2RtOnosaGVhZENwaDpLfT1ZO2lmKCFhd2FpdCBRLmNoZWNrU2lnRWQyNTUxOShXLEssWikpcmV0dXJuIEcoMyk7bGV0IE49Si5kZXJpdmVDaXBoZXIoeiwiZGVjcnlwdCIpLFU7dHJ5e1U9YXdhaXQgTi5kZWNyeXB0KEspfWNhdGNoe3JldHVybiBHKDIwKX1yZXR1cm4gUih7a2RtOnosaGVhZEVuYzpVfSl9dmFyIHMwPSJmIixTJD0idCIsYTA9ImUiO2Z1bmN0aW9uIE1WKCQpe2lmKCQ9PT0hMHx8JD09PVMkKXJldHVybiBTJDtpZigkPT09YTApcmV0dXJuIGEwO3JldHVybiBzMH1mdW5jdGlvbiBsSigkKXtyZXR1cm4gJCE9PTAmJiQhPT0xNSYmJCE9PTE4JiYkIT09MTd9ZnVuY3Rpb24galooJCxaLEope2lmKCQuYXBsZD1aLFo9PT1hMCYmSiE9PXZvaWQgMCkkLmVycj1KO2Vsc2UgZGVsZXRlICQuZXJyfWFzeW5jIGZ1bmN0aW9uIHYkKCQsWixKLFEpe2xldCBWPVE/LmJvZHkhPT0hMSxZPU1WKFouYXBsZCksWD1aLmJvZHksVz1YPy5sZW5ndGg/PzAsejtpZihWJiZYJiZXPjApej1hd2FpdCBKLmJsYWtlMyhYKTtsZXQgSz17ZWlkOlouZWlkLG9mZjpaLm9mZj8/MCxjdHI6Wi5jdHI/PzAsbGVuOlcsaHNoOnp9LEY9e2hhc2g6JCxoZWFkOkssYXBsZDpZfTtpZihWJiZYIT09dm9pZCAwKUYuYm9keT1YO2lmKFk9PT1hMCYmWi5lcnIhPT12b2lkIDApRi5lcnI9Wi5lcnI7cmV0dXJuIEZ9dmFyIEFaPTEwNDg1NzYsX1o9MTA0ODU3NixuSj02NDtmdW5jdGlvbiBDVigkKXtyZXR1cm4gJC5zaWcubGVuZ3RoKyQua2RtLmxlbmd0aCskLmhlYWRDcGgubGVuZ3RoKyQuYm9keUNwaC5sZW5ndGh9YXN5bmMgZnVuY3Rpb24gUFYoJCxaLEosUSxWKXtpZihRLmxlbmd0aDwxKXJldHVybiAwO2xldFtZLFhdPWF3YWl0ICQucHVzaChRKTtpZihYIT09MClyZXR1cm4gWDtpZighWSlyZXR1cm4gMjc7Zm9yKGxldCB6IG9mIFkpe2lmKHouc3RhdHVzIT09MCl7Y29uc29sZS5lcnJvcigicHVzaCBlcnIiLHopO2NvbnRpbnVlfWxldCBLPVZbei5pZHhdO2lmKCFLKXtjb25zb2xlLmVycm9yKCJubyBoYXNoIix6KTtjb250aW51ZX1hd2FpdCBaLnVwbG9hZHMuZGVxKEosW0tdKX1sZXQgVz1hd2FpdCBaLmhvc3RzLmdldChKKTtpZihXKXtsZXQgej1XLmxhc3RTZXEsSz16LEY9W107Zm9yKGxldCBOIG9mIFkpaWYoTi5zdGF0dXM9PT0wKUYucHVzaChOLnNlcSk7Ri5zb3J0KChOLFUpPT5OLVUpO2ZvcihsZXQgTiBvZiBGKWlmKE49PT16KzEpej1OO2lmKHo+Sylhd2FpdCBaLmhvc3RzLnRvdWNoKEoseil9cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gcEooJCxaKXtpZihaLmxlbmd0aDwxKXJldHVybiBSKFtdKTtsZXQgSj1uZXcgTWFwLFE9W107Zm9yKGxldCBXIG9mIFopSi5zZXQoVy5zZXEsVyksUS5wdXNoKFcuc2VxKTtsZXRbVixZXT1hd2FpdCAkLnB1bGwoUSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoIVYpcmV0dXJuIEcoMjcpO2xldCBYPVtdO2ZvcihsZXR7c2VxOlcsYm9keUNwaDp6fW9mIFYpe2xldCBLPUouZ2V0KFcpO2lmKCFLKWNvbnRpbnVlO1gucHVzaCh7ZGw6Syxib2R5Q3BoOnp9KX1yZXR1cm4gUihYKX1hc3luYyBmdW5jdGlvbiB3VigkLFosSixRKXtpZihRLmxlbmd0aDwxKXJldHVybiBSKHtwYXJ0czpbXSxoYXNoZXM6W119KTtsZXQgVj1bXSxZPVtdLFg9W10sVz1uZXcgTWFwO2ZvcihsZXR7ZGw6Syxib2R5Q3BoOkZ9b2YgUSl7bGV0e2hlYWQ6TixrZG06VSxzZXE6Tyxob3N0OnF9PUssW0ksSF09YXdhaXQgY0ooSyxKKTtpZihIIT09MHx8IUkpe2xldCBrPVcuZ2V0KHEpPz9bXTtrLnB1c2goTyksVy5zZXQocSxrKTtjb250aW51ZX1sZXR7aGVhZEVuYzpQLGhlYWRFbmNIYXNoOkN9PUksVD1aLmRlcml2ZUNpcGhlcihVLCJkZWNyeXB0IiksW00sQV09YXdhaXQgWVooUCxGLFQsSixDKTtpZihBIT09MHx8IU0pe2xldCBrPVcuZ2V0KHEpPz9bXTtrLnB1c2goTyksVy5zZXQocSxrKTtjb250aW51ZX1sZXQgeD17aGVhZDpOLGJvZHk6TS5ib2R9LG09TS5oZWFkSGFzaDtYLnB1c2goe2tleTptLGRhdGE6b0ooeCl9KSxWLnB1c2goeCksWS5wdXNoKG0pO2xldCBFPVcuZ2V0KHEpPz9bXTtFLnB1c2goTyksVy5zZXQocSxFKX1sZXQgej1hd2FpdCAkLm1lc3NhZ2VzLmFkZChYKTtmb3IobGV0W0ssRl1vZiBXKWF3YWl0ICQuZG93bmxvYWRzLmRlcShLLEYpO2ZvcihsZXQgSz0wO0s8ei5sZW5ndGg7SysrKXtsZXQgRj16W0tdO2lmKEYhPT0wJiZGIT09MTUpY29uc29sZS5lcnJvcigiRVJSIHN0b3JpbmciLGpbRl0sImZvciBtZXNzYWdlIixLKX1yZXR1cm4gUih7cGFydHM6VixoYXNoZXM6WX0pfWFzeW5jIGZ1bmN0aW9uIGNKKCQsWil7bGV0IEo9JC5oZWFkRW5jO2lmKCFKKXtsZXQgVj1uZXcgUyxZPVYud3JpdGVTdHJ1Y3QoWDAsJC5oZWFkKTtpZihZIT09MClyZXR1cm4gRyhZKTtKPVYucmVzdWx0KCl9aWYoJC5oZWFkRW5jSGFzaClyZXR1cm4gUih7aGVhZEVuYzpKLGhlYWRFbmNIYXNoOiQuaGVhZEVuY0hhc2h9KTtsZXQgUT1hd2FpdCBaLmJsYWtlMyhKKTtyZXR1cm4gUih7aGVhZEVuYzpKLGhlYWRFbmNIYXNoOlF9KX1hc3luYyBmdW5jdGlvbiBkSigkLFosSil7bGV0IFE9bmV3IFNldDtmb3IobGV0IFggb2YgWilRLmFkZChmKFgpKTtpZihRLnNpemU8MSlyZXR1cm47bGV0IFY9QXJyYXkuZnJvbShhd2FpdCAkLmRvd25sb2Fkcy5saXN0KCkpO2lmKFYubGVuZ3RoPDEpcmV0dXJuO2xldCBZPW5ldyBNYXA7Zm9yKGxldCBYIG9mIFYpe2xldCBXO2lmKFguaGVhZEVuY0hhc2gpVz1mKFguaGVhZEVuY0hhc2gpO2Vsc2V7bGV0W0ssRl09YXdhaXQgY0ooWCxKKTtpZihGIT09MHx8IUspY29udGludWU7Vz1mKEsuaGVhZEVuY0hhc2gpfWlmKCFRLmhhcyhXKSljb250aW51ZTtsZXQgej1ZLmdldChYLmhvc3QpPz9bXTt6LnB1c2goWC5zZXEpLFkuc2V0KFguaG9zdCx6KX1mb3IobGV0W1gsV11vZiBZKWF3YWl0ICQuZG93bmxvYWRzLmRlcShYLFcpfWFzeW5jIGZ1bmN0aW9uIExaKHtjb25uOiQsc3RvcmU6WixlbmNsYXZlOkosaG9zdDpRLGNyeXB0bzpWLG9uUHJvZ3Jlc3M6WSxwZWVrUHJvZ3Jlc3NFdmVyeTpYLHBlZWtDb25jdXJyZW5jeTpXfSl7bGV0IHo9YXdhaXQgJC5pZGVudGl0eSgpLEs9W10sW0YsTl09YXdhaXQgJC5wZWVrKFEubGFzdFNlcSk7aWYoTiE9PTApcmV0dXJuIE47bGV0IFU9Ri5sZW5ndGgsTz1YPz9LJCxxPVc/P25KO2lmKFkmJlU+MClZKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6MCx0b3RhbDpVfSk7bGV0IEk9MCxIPWF3YWl0IERaKEYscSxhc3luYyhDKT0+e2xldFtULE1dPWF3YWl0IGckKEMsei5wdWJsaWNLZXksSixWKSxBO2lmKE0hPT0wfHwhVClBPXtvazohMSxzZXE6Qy5zZXEsc3RhdDpNfTtlbHNle2xldCB4PWF3YWl0IFYuYmxha2UzKFQuaGVhZEVuYyk7QT17b2s6ITAsc2VxOkMuc2VxLGtkbTpULmtkbSxoZWFkRW5jOlQuaGVhZEVuYyxoZWFkRW5jSGFzaDp4fX1pZihJKz0xLFkmJlRaKEksVSxPKSlZKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6SSx0b3RhbDpVfSk7cmV0dXJuIEF9KSxQPW5ldyBTZXQ7Zm9yKGxldCBDIG9mIEgpe2lmKCFDLm9rKXtjb25zb2xlLmVycm9yKCJwZWVrOiBkZWNyeXB0aW5nIGl0ZW0gaGVhZCIsQy5zdGF0KTtjb250aW51ZX1sZXQgVD1mKEMuaGVhZEVuY0hhc2gpO2lmKGF3YWl0IFoubWVzc2FnZXMuaGFzKEMuaGVhZEVuY0hhc2gpKXtjb25zb2xlLmluZm8oInBlZWs6IGxvY2FsIG1zZzsgc2tpcCBkb3dubG9hZCwgZGVxIHVwbG9hZCIpLGF3YWl0IFoudXBsb2Fkcy5kZXEoUS5sYWJlbCxbQy5oZWFkRW5jSGFzaF0pLGF3YWl0IFouZG93bmxvYWRzLmRlcShRLmxhYmVsLFtDLnNlcV0pO2NvbnRpbnVlfWlmKFAuaGFzKFQpKXthd2FpdCBaLmRvd25sb2Fkcy5kZXEoUS5sYWJlbCxbQy5zZXFdKTtjb250aW51ZX1sZXQgQT1uZXcgZyhDLmhlYWRFbmMpLFt4LG1dPUEucmVhZFN0cnVjdChYMCk7aWYobSE9PTApe2NvbnNvbGUuZXJyb3IoInBlZWs6IHJlYWRpbmcgaXRlbSBoZWFkIixtKTtjb250aW51ZX1QLmFkZChUKSxLLnB1c2goe2tkbTpDLmtkbSxoZWFkOngsc2VxOkMuc2VxLGhvc3Q6US5sYWJlbCxoZWFkRW5jOkMuaGVhZEVuYyxoZWFkRW5jSGFzaDpDLmhlYWRFbmNIYXNofSl9aWYoYXdhaXQgWi5kb3dubG9hZHMuZW5xKEspLEYubGVuZ3RoPjApe2xldCBDPU1hdGgubWF4KC4uLkYubWFwKChUKT0+VC5zZXEpKTthd2FpdCBaLmhvc3RzLnJlY29yZFN0YXRzKFEubGFiZWwse2xhc3RTZXE6Q30pfWlmKFkpWSh7cGhhc2U6InBlZWsiLGhvc3Q6US5sYWJlbCxkb25lOlUsdG90YWw6VX0pO3JldHVybiAwfWFzeW5jIGZ1bmN0aW9uIHJKKHtjb25uOiQsc3RvcmU6Wixob3N0OkosbWF4UHVzaEJ5dGVzOlEsb25Qcm9ncmVzczpWfSl7bGV0IFk9UT8/QVosWD1hd2FpdCBaLnVwbG9hZHMubGlzdChKLmxhYmVsKSxXPVgubGVuZ3RoLHo9MDtpZihWJiZXPjApVih7cGhhc2U6InB1c2giLGhvc3Q6Si5sYWJlbCxkb25lOjAsdG90YWw6V30pO2xldCBLPVtdLEY9W10sTj0wLFU9YXN5bmMoKT0+e2lmKEsubGVuZ3RoPDEpcmV0dXJuIDA7bGV0IE89Sy5sZW5ndGgscT1hd2FpdCBQVigkLFosSi5sYWJlbCxLLEYpO2lmKEs9W10sRj1bXSxOPTAscT09PTApe2lmKHorPU8sVilWKHtwaGFzZToicHVzaCIsaG9zdDpKLmxhYmVsLGRvbmU6eix0b3RhbDpXfSl9cmV0dXJuIHF9O2ZvcihsZXQgTyBvZiBYKXtsZXQgcT1hd2FpdCBaLm1lc3NhZ2VzLmdldChPKTtpZighcSl7eis9MTtjb250aW51ZX1sZXQgST17Li4ucS5oZWFkLGJvZDpxLmJvZHl9LFtILFBdPWF3YWl0ICQuc2VhbChJKTtpZihQIT09MClyZXR1cm4gUDtpZighSClyZXR1cm4gMTI7bGV0IEM9Q1YoSCk7aWYoSy5sZW5ndGg+MCYmTitDPlkpe2xldCBUPWF3YWl0IFUoKTtpZihUIT09MClyZXR1cm4gVH1pZihLLnB1c2goSCksRi5wdXNoKE8pLE4rPUMsTj49WSl7bGV0IFQ9YXdhaXQgVSgpO2lmKFQhPT0wKXJldHVybiBUfX1yZXR1cm4gVSgpfWFzeW5jIGZ1bmN0aW9uIHhaKHtjb25uOiQsc3RvcmU6WixlbmNsYXZlOkosaG9zdDpRLGNyeXB0bzpWLG1heFB1bGxCeXRlczpZLG9uUHJvZ3Jlc3M6WH0sVyl7bGV0IHo9WT8/X1osSz1hd2FpdCBaLmRvd25sb2Fkcy5saXN0KCksRj1BcnJheS5mcm9tKEspLmZpbHRlcigoSCk9PkguaG9zdD09PVEubGFiZWwpO2lmKEYubGVuZ3RoPDEpcmV0dXJuIDE1O2xldCBOPW8wKEYsKEgpPT5ILmhlYWQpLFU9dUooTiwoSCk9PkguaGVhZC5sZW4seiksTz1OLmxlbmd0aCxxPTA7aWYoWClYKHtwaGFzZToicHVsbCIsaG9zdDpRLmxhYmVsLGRvbmU6MCx0b3RhbDpPfSk7bGV0IEk9cEooJCxVWzBdKTtmb3IobGV0IEg9MDtIPFUubGVuZ3RoO0grKyl7bGV0W1AsQ109YXdhaXQgSTtpZihDIT09MHx8IVApcmV0dXJuIEM7aWYocSs9VVtIXS5sZW5ndGgsWClYKHtwaGFzZToicHVsbCIsaG9zdDpRLmxhYmVsLGRvbmU6cSx0b3RhbDpPfSk7bGV0IFQ9VVtIKzFdO2lmKFQpST1wSigkLFQpO2lmKFgpWCh7cGhhc2U6Im9wZW4iLGhvc3Q6US5sYWJlbCxkb25lOnEsdG90YWw6T30pO2xldCBNPW8wKFAsKHgpPT54LmRsLmhlYWQpLFssQV09YXdhaXQgd1YoWixKLFYsTSk7aWYoQSE9PTApcmV0dXJuIEE7aWYoVyl7aWYoWClYKHtwaGFzZToiZXhlYyIsaG9zdDpRLmxhYmVsLGRvbmU6cSx0b3RhbDpPfSk7YXdhaXQgVygpfX1yZXR1cm4gMH1mdW5jdGlvbiBvSih7aGVhZDokLGJvZHk6Wn0pe2xldCBKPXtlaWQ6JC5laWQsYm9keTpaLGFwbGQ6czB9O2lmKCQub2ZmIT09MClKLm9mZj0kLm9mZjtpZigkLmN0ciE9PTApSi5jdHI9JC5jdHI7cmV0dXJuIEp9YXN5bmMgZnVuY3Rpb24gYUooJCx7Y29ubjpaLHN0b3JlOkosZW5jbGF2ZTpRLGhvc3Q6VixjcnlwdG86WSxvblByb2dyZXNzOlh9LFcpe2xldCB6PVYubGFiZWwsSz1hd2FpdCBaLmlkZW50aXR5KCksRj1uZXcgZygkKSxbTixVXT1GLnJlYWRTdHJ1Y3RzKGokKTtpZihVIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIGRlY29kaW5nIG5vdGlmIixqW1VdKTtyZXR1cm59bGV0IE89ITEsST0oYXdhaXQgSi5ob3N0cy5nZXQoeikpPy5sYXN0U2VxLEg9W10sUD0hMTtmb3IobGV0IE0gb2YgTil7bGV0W0EseF09YXdhaXQgZyQoe3NlcTpNLnNlcSxoZWFkQ3BoOk0uaGVhZENwaH0sSy5wdWJsaWNLZXksUSxZKTtpZih4IT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIGRlY3J5cHRpbmcgbm90aWYiLGpbeF0pO2NvbnRpbnVlfWxldCBtPWF3YWl0IFkuYmxha2UzKEEuaGVhZEVuYyk7aWYoYXdhaXQgSi5tZXNzYWdlcy5oYXMobSkpY29udGludWU7bGV0IEU9bmV3IGcoQS5oZWFkRW5jKSxbayxiXT1FLnJlYWRTdHJ1Y3QoWDApO2lmKGIhPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgdG8gcGFyc2UgaGVhZCIsaltiXSk7Y29udGludWV9aWYoIU0uYm9keUNwaCYmay5sZW4+MClQPSEwLGF3YWl0IEouZG93bmxvYWRzLmVucShbe3NlcTpNLnNlcSxob3N0Onosa2RtOkEua2RtLGhlYWQ6ayxoZWFkRW5jOkEuaGVhZEVuYyxoZWFkRW5jSGFzaDptfV0pO2Vsc2UgSC5wdXNoKHsuLi5BLGhlYWQ6ayxib2R5Q3BoOk0uYm9keUNwaCxoZWFkRW5jSGFzaDptfSk7aWYoST09PXZvaWQgMHx8TS5zZXEhPT1JKzEpY29uc29sZS5sb2coIm91dCBvZiBzZXEiLE0uc2VxLEkpLE89ITA7ZWxzZSBJPU0uc2VxfWlmKEkhPT12b2lkIDApYXdhaXQgSi5ob3N0cy50b3VjaChWLmxhYmVsLEkpO2xldCBDPVtdO2ZvcihsZXQgTSBvZiBIKXtsZXQgQT1RLmRlcml2ZUNpcGhlcihNLmtkbSwiZGVjcnlwdCIpLFt4LG1dPWF3YWl0IFlaKE0uaGVhZEVuYyxNLmJvZHlDcGgsQSxZKTtpZihtIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIHRvIG9wZW4gYm9keSIsalttXSk7Y29udGludWV9Qy5wdXNoKHtrZXk6TS5oZWFkRW5jSGFzaCxkYXRhOm9KKHtoZWFkOk0uaGVhZCxib2R5OnguYm9kfSl9KX1sZXQgVD1hd2FpdCBKLm1lc3NhZ2VzLmFkZChDKTtmb3IobGV0IE09MDtNPFQubGVuZ3RoO00rKyl7bGV0IEE9VFtNXTtpZihBIT09MCYmQSE9PTE1KWNvbnNvbGUuZXJyb3IoIkVSUiBzdG9yaW5nIixqW0FdLCJmb3IgbWVzc2FnZSIsTSl9aWYoWCYmQy5sZW5ndGg+MClYKHtwaGFzZToib3BlbiIsaG9zdDpWLmxhYmVsLGRvbmU6Qy5sZW5ndGgsdG90YWw6Qy5sZW5ndGh9KTtpZihPfHxQfHxDLmxlbmd0aD4wKVcoKX1hc3luYyBmdW5jdGlvbiBmWigkLFo9e30pe2xldCBKPVoucHVsbCE9PSExLFE9Wi5wdXNoPT09ITAse2Nvbm46VixzdG9yZTpZLGVuY2xhdmU6WCxob3N0OlcsY3J5cHRvOnosb25Qcm9ncmVzczpLLHBlZWtQcm9ncmVzc0V2ZXJ5OkYscGVla0NvbmN1cnJlbmN5Ok59PSQsVT1hd2FpdCBWLmlkZW50aXR5KCksW08scV09YXdhaXQgVi5wZWVrKDApO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldCBJPU8ubGVuZ3RoLEg9Rj8/SyQsUD1OPz9uSjtpZihLJiZJPjApSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOjAsdG90YWw6SX0pO2xldCBDPTAsVD1hd2FpdCBEWihPLFAsYXN5bmMoTCk9PntsZXRbdixCXT1hd2FpdCBnJChMLFUucHVibGljS2V5LFgseikseTtpZihCIT09MHx8IXYpeT17b2s6ITEsc2VxOkwuc2VxLHN0YXQ6Qn07ZWxzZXtsZXQgXz1hd2FpdCB6LmJsYWtlMyh2LmhlYWRFbmMpO3k9e29rOiEwLHNlcTpMLnNlcSxrZG06di5rZG0saGVhZEVuYzp2LmhlYWRFbmMsaGVhZEVuY0hhc2g6X319aWYoQys9MSxLJiZUWihDLEksSCkpSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOkMsdG90YWw6SX0pO3JldHVybiB5fSksTT1uZXcgTWFwO2ZvcihsZXQgTCBvZiBUKXtpZighTC5vayljb250aW51ZTtsZXQgdj1mKEwuaGVhZEVuY0hhc2gpLEI9TS5nZXQodik7aWYoQilCLmNvdW50Kz0xO2Vsc2UgTS5zZXQodix7aGFzaDpMLmhlYWRFbmNIYXNoLGNvdW50OjEsc2FtcGxlOkx9KX1sZXQgQT0wLHg9W107Zm9yKGxldCBMIG9mIE0udmFsdWVzKCkpe2lmKEwuY291bnQ+MSlBKz1MLmNvdW50LTE7eC5wdXNoKEwuaGFzaCl9bGV0IG09Ty5sZW5ndGgsRT1NLnNpemUsaz1hd2FpdCB6JCh4LHopLGI9W10sdz0wO2ZvcihsZXQgTCBvZiBNLnZhbHVlcygpKXtpZihhd2FpdCBZLm1lc3NhZ2VzLmhhcyhMLmhhc2gpKXthd2FpdCBZLnVwbG9hZHMuZGVxKFcubGFiZWwsW0wuaGFzaF0pO2NvbnRpbnVlfWlmKHcrPTEsIUopY29udGludWU7bGV0IEI9TC5zYW1wbGUseT1uZXcgZyhCLmhlYWRFbmMpLFtfLGNdPXkucmVhZFN0cnVjdChYMCk7aWYoYyE9PTApe2NvbnNvbGUuZXJyb3IoInJlY29uY2lsZTogcmVhZGluZyBtc2cgaGVhZGVyIixjKTtjb250aW51ZX1iLnB1c2goe2tkbTpCLmtkbSxoZWFkOl8sc2VxOkIuc2VxLGhvc3Q6Vy5sYWJlbCxoZWFkRW5jOkIuaGVhZEVuYyxoZWFkRW5jSGFzaDpCLmhlYWRFbmNIYXNofSl9aWYoYi5sZW5ndGg+MClhd2FpdCBZLmRvd25sb2Fkcy5lbnEoYik7bGV0IGg9MDtpZihRKXtsZXQgTD1hd2FpdCBZLm1lc3NhZ2VzLmxpc3RLZXlzKCksdj1uZXcgU2V0KE0ua2V5cygpKSxCPVtdO2ZvcihsZXQgeSBvZiBMKWlmKCF2LmhhcyhmKHkpKSloKz0xLEIucHVzaCh5KTtpZihCLmxlbmd0aD4wKWF3YWl0IFkudXBsb2Fkcy5lbnEoVy5sYWJlbCxCKX1lbHNle2xldCBMPWF3YWl0IFkubWVzc2FnZXMubGlzdEtleXMoKSx2PW5ldyBTZXQoTS5rZXlzKCkpO2ZvcihsZXQgQiBvZiBMKWlmKCF2LmhhcyhmKEIpKSloKz0xfWxldCBsPU8ubGVuZ3RoPjA/TWF0aC5tYXgoLi4uTy5tYXAoKEwpPT5MLnNlcSkpOjA7aWYoYXdhaXQgWS5ob3N0cy5yZWNvcmRTdGF0cyhXLmxhYmVsLHtzZXRMYXN0U2VxOmx9KSxLKUsoe3BoYXNlOiJwZWVrIixob3N0OlcubGFiZWwsZG9uZTpJLHRvdGFsOkl9KTtyZXR1cm4gUih7bXNnY2hlY2s6ayxudW1CYWdzOm0sdW5pcXVlTXNnczpFLG51bUR1cGVzOkEsbWlzc2luZ0xvY2FsOncsbWlzc2luZ0hvc3Q6aH0pfWNsYXNzIGtae2Nsb2NrO3N0YXRlO3N0b3JlO3RyYW5zcG9ydDtjcnlwdG87Zm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQ7b25TY2hlZHVsZVN5bmM7Y29ubmVjdGlvbnM9bmV3IE1hcDthcHBseUNoYWluPVByb21pc2UucmVzb2x2ZSgpO3N5bmNSdW5zPW5ldyBtJDtjbGllbnRTdGF0ZTt4ZmVyU3RhdGU7bWF4UHVzaEJ5dGVzO21heFB1bGxCeXRlcztwZWVrUHJvZ3Jlc3NFdmVyeT1LJDtsYXN0UHJvZ3Jlc3M9d1o7c2NoZWR1bGVkU3luYztjb25zdHJ1Y3RvcigkLFosSixRLFYsWT0hMCxYPUFaLFc9X1oseil7dGhpcy5jbG9jaz0kO3RoaXMuc3RhdGU9Wjt0aGlzLnN0b3JlPUo7dGhpcy50cmFuc3BvcnQ9UTt0aGlzLmNyeXB0bz1WO3RoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQ9WTt0aGlzLm9uU2NoZWR1bGVTeW5jPXo7dGhpcy5tYXhQdXNoQnl0ZXM9WCx0aGlzLm1heFB1bGxCeXRlcz1XLHRoaXMuY2xpZW50U3RhdGU9bmV3IEwwKCgpPT50aGlzLmdldENsaWVudFN0YXRlKCkpLHRoaXMueGZlclN0YXRlPW5ldyBMMCgoKT0+dGhpcy5nZXRYZmVyU3RhdGUoKSksdGhpcy5zY2hlZHVsZWRTeW5jPW5ldyBQWih5Sixhc3luYygpPT57dHJ5e2NvbnNvbGUuaW5mbygiUnVubmluZyBzY2hlZHVsZWQgc3luYyIpLGF3YWl0IHRoaXMuc3luYygpfWNhdGNoKEspe2NvbnNvbGUuZXJyb3IoIkRlYm91bmNlZCBzeW5jIGZhaWxlZDoiLEspfX0pfWVtaXRQcm9ncmVzcz0oJCk9Pnt0aGlzLmxhc3RQcm9ncmVzcz0kLHRoaXMueGZlclN0YXRlLmVtaXQoKX07YXN5bmMgc2V0U2VlZCgkLFope2F3YWl0IHRoaXMuc3RvcmUuc2VlZC5zYXZlKCQsWiksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9YXN5bmMgZ2V0Q2xpZW50U3RhdGUoKXtsZXR7c3RvcmU6JCxjb25uZWN0aW9uczpafT10aGlzLEo9YXdhaXQgJC5zZWVkLmxvYWQoKSxRPWF3YWl0ICQuaG9zdHMubGlzdCgpLFY9ITE7Zm9yKGxldCBZIG9mIFoudmFsdWVzKCkpaWYoWS5pc0Nvbm5lY3RlZCgpKXtWPSEwO2JyZWFrfXJldHVybntoYXNTZWVkOkohPT12b2lkIDAsaGFzSG9zdDpBcnJheS5mcm9tKFEpLmxlbmd0aD4wLGNvbm5lY3RlZDpWfX1hc3luYyBnZXRYZmVyU3RhdGUoKXtsZXR7dXBsb2FkczokLGRvd25sb2FkczpafT10aGlzLnN0b3JlLEo9YXdhaXQgJC5jb3VudCgpO3JldHVybntudW1Eb3dubG9hZHM6YXdhaXQgWi5jb3VudCgpLG51bVVwbG9hZHM6Sixwcm9ncmVzczp0aGlzLmxhc3RQcm9ncmVzc319YXBwbHk9KCQsWik9PntyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMuZG9BcHBseSgkLFopKX07YXN5bmMgZG9BcHBseSgkLFo9e2VucXVldWVVcGxvYWQ6ITAsdHJpZ2dlclVwbG9hZDohMH0pe2xldCBKPVtdLFE9W107Zm9yKGxldHtoZWFkOlksYm9keTpYfW9mICQpe2xldCBXPW5ldyBTO1cud3JpdGVTdHJ1Y3QoWDAsWSk7bGV0IHo9Vy5yZXN1bHQoKSxLPWF3YWl0IHRoaXMuY3J5cHRvLmJsYWtlMyh6KSxGPXtlaWQ6WS5laWQsYm9keTpYLGFwbGQ6czB9O2lmKFkub2ZmIT09MClGLm9mZj1ZLm9mZjtpZihZLmN0ciE9PTApRi5jdHI9WS5jdHI7Si5wdXNoKEspLFEucHVzaCh7a2V5OkssZGF0YTpGfSl9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5hZGQoUSksYXdhaXQgZEoodGhpcy5zdG9yZSxKLHRoaXMuY3J5cHRvKTtsZXQgVj1hd2FpdCB0aGlzLmRvQXBwbHlIYXNoZXMoSik7aWYoWi5lbnF1ZXVlVXBsb2FkKXtsZXQgWT1bXTtmb3IobGV0IFg9MDtYPEoubGVuZ3RoO1grKyl7bGV0IFc9VltYXTtpZihXPT09MHx8Vz09PTE1KVkucHVzaChKW1hdKX1pZihZLmxlbmd0aD4wKXtsZXQgWD1hd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmxpc3QoKTtmb3IobGV0IFcgb2YgWClhd2FpdCB0aGlzLnN0b3JlLnVwbG9hZHMuZW5xKFcubGFiZWwsWSk7dGhpcy54ZmVyU3RhdGUuZW1pdCgpfX1pZihaLnRyaWdnZXJVcGxvYWQpdGhpcy5zY2hlZHVsZVN5bmMoKTtyZXR1cm4gVn1lbnF1ZXVlQXBwbHlKb2IoJCl7bGV0IFo9dGhpcy5hcHBseUNoYWluLnRoZW4oJCwkKTtyZXR1cm4gdGhpcy5hcHBseUNoYWluPVoudGhlbigoKT0+e3JldHVybn0sKCk9PntyZXR1cm59KSxafWRyYWluQXBwbHlRdWV1ZSgpe3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5kb0RyYWluQXBwbHlRdWV1ZSgpKX1hc3luYyBkb0RyYWluQXBwbHlRdWV1ZSgpe2xldCAkPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdCh7YXBsZDpzMH0pO2lmKCQubGVuZ3RoPDEpcmV0dXJuW107bGV0IFo9bzAoJCwoSik9PkouaGVhZCk7cmV0dXJuIHRoaXMuYXBwbHlTdG9yZWQoWil9YXBwbHlIYXNoZXM9KCQpPT57cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvQXBwbHlIYXNoZXMoJCkpfTthc3luYyBkb0FwcGx5SGFzaGVzKCQpe2xldCBaPVtdO2ZvcihsZXQgViBvZiAkKXtsZXQgWT1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmdldChWKTtpZihZKVoucHVzaChZKX1sZXQgSj1hd2FpdCB0aGlzLmFwcGx5U3RvcmVkKFopLFE9bmV3IE1hcDtmb3IobGV0IFY9MDtWPFoubGVuZ3RoO1YrKylRLnNldChmKFpbVl0uaGFzaCksSltWXT8/MTIpO3JldHVybiAkLm1hcCgoVik9PlEuZ2V0KGYoVikpPz8xMyl9YXN5bmMgYXBwbHlTdG9yZWQoJCl7aWYoJC5sZW5ndGg8MSlyZXR1cm5bXTtsZXQgWj0kLm1hcCgoWSk9Pih7Li4uWS5oZWFkLGJvZDpZLmJvZHl9KSksSj1hd2FpdCB0aGlzLnN0YXRlLmFwcGx5KFopLFE9W10sVj1bXTtmb3IobGV0IFk9MDtZPCQubGVuZ3RoO1krKyl7bGV0IFg9SltZXTtpZihYPT09MHx8WD09PTE1KVEucHVzaCgkW1ldLmhhc2gpO2Vsc2UgaWYoWCE9PXZvaWQgMCYmbEooWCkpVi5wdXNoKHtrZXk6JFtZXS5oYXNoLGVycjpYfSl9aWYoUS5sZW5ndGg+MClhd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLm1hcmtBcHBsaWVkKFEpO2lmKFYubGVuZ3RoPjApYXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5tYXJrRmFpbGVkKFYpO3JldHVybiBKfWFzeW5jIGluc2VydFJhdygkKXtsZXR7Y2xvY2s6WixjcnlwdG86Sn09dGhpcyxbUSxWXT1hd2FpdCBmSih7bm93Oloubm93KCksYm9kOiQsY3J5cHRvOkp9KTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXQgWD0oYXdhaXQgdGhpcy5hcHBseShbe2hlYWQ6USxib2R5OiR9XSkpWzBdO2lmKFghPT0wJiZYIT09MTUpcmV0dXJuIEcoWD8/MTIpO3JldHVybiBSKFEpfWFzeW5jIG1ha2VVcGRhdGUoJCxaKXtsZXR7Y2xvY2s6SixjcnlwdG86UX09dGhpcyxWPUoubm93KCk7aWYoJC51cGRhdGVkQXQuZ2V0VGltZSgpPlYuZ2V0VGltZSgpKXJldHVybiBHKDQpO2xldCBZPSQuY3RyKzEsW1gsV109YXdhaXQgeCQoe25vdzpWLGVpZDokLmVpZCxjdHI6WSxib2Q6WixjcnlwdG86UX0pO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBSKHtoZWFkOlgsYm9keTpafSl9YXN5bmMgdXBkYXRlV2l0aFNrZXcoJCxaLEope2lmKEo9PT0hMSlyZXR1cm4gRyg0KTtsZXR7Y2xvY2s6USxjcnlwdG86Vn09dGhpcyxZPVEubm93KCksWD1uZXcgZygkLmVpZCksW1csel09WC5yZWFkU3RydWN0KFEwKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXQgSz0kLnVwZGF0ZWRBdC5nZXRUaW1lKCktVy50cy5nZXRUaW1lKCksRj17ZWlkOiQuZWlkLG9mZjpLKzEsY3RyOiQuY3RyKzEsbGVuOjB9LFU9KGF3YWl0IHRoaXMuYXBwbHkoW3toZWFkOkYsYm9keTp2b2lkIDB9XSkpWzBdO2lmKFUhPT0wJiZVIT09MTUpcmV0dXJuIEcoVT8/MTIpO2lmKFo9PT12b2lkIDApcmV0dXJuIFIoRik7bGV0W08scV09VCQoe2lkOlcuaWQsdHM6WX0pO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldFtJLEhdPWF3YWl0IHgkKHtub3c6WSxlaWQ6TyxjdHI6MCxib2Q6WixjcnlwdG86Vn0pO2lmKEghPT0wKXJldHVybiBHKEgpO2xldCBDPShhd2FpdCB0aGlzLmFwcGx5KFt7aGVhZDpJLGJvZHk6Wn1dKSlbMF07aWYoQyE9PTAmJkMhPT0xNSlyZXR1cm4gRyhDPz8xMik7cmV0dXJuIFIoSSl9YXN5bmMgdXBkYXRlUmF3KCQsWixKPXRoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQpe2lmKCQudXBkYXRlZEF0LmdldFRpbWUoKT50aGlzLmNsb2NrLm5vdygpLmdldFRpbWUoKSlyZXR1cm4gdGhpcy51cGRhdGVXaXRoU2tldygkLFosSik7cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKGFzeW5jKCk9PntsZXRbUSxWXT1hd2FpdCB0aGlzLm1ha2VVcGRhdGUoJCxaKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXQgWD0oYXdhaXQgdGhpcy5kb0FwcGx5KFtRXSkpWzBdO2lmKFghPT0wJiZYIT09MTUpcmV0dXJuIEcoWD8/MTIpO3JldHVybiBSKFEuaGVhZCl9KX1hc3luYyBpbnNlcnQoJCl7bGV0e2JvZHk6Wix0eXBlOkosZ2lkOlEscGlkOlYsdGFnczpZfT0kLFc9XzAoe2JvZHk6Wix0eXBlOkosZ2lkOlEscGlkOlYsdGFnczpZfSk7cmV0dXJuIHRoaXMuaW5zZXJ0UmF3KFcpfWFzeW5jIHVwZGF0ZSgkKXtsZXR7cHJpb3I6Wixib2R5OkosdHlwZTpRLGdpZDpWLHBpZDpZLHRhZ3M6WCxmb3JjZTpXfT0kLEs9XzAoe2JvZHk6Six0eXBlOlEsZ2lkOlYscGlkOlksdGFnczpYfSk7cmV0dXJuIHRoaXMudXBkYXRlUmF3KFosSyxXPz90aGlzLmZvcmNlU2tld0hhbmRsaW5nQnlEZWZhdWx0KX1hc3luYyBkZWxldGUoJCl7bGV0IFo9JC5mb3JjZT8/ITA7aWYoInByaW9yImluICQpcmV0dXJuIHRoaXMudXBkYXRlUmF3KCQucHJpb3Isdm9pZCAwLFopO2xldFtKLFFdPWF3YWl0IHRoaXMucmV2RnJvbUFyY2hpdmUoJC5laWQpO2lmKFEhPT0wKXJldHVybiBHKFEpO3JldHVybiB0aGlzLnVwZGF0ZVJhdyhKLHZvaWQgMCxaKX1hc3luYyByZXZGcm9tQXJjaGl2ZSgkKXtsZXQgWj1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxhc3QoJCk7aWYoWilyZXR1cm4gYkooWi5oZWFkKTtsZXQgSj1uZXcgZygkKSxbUSxWXT1KLnJlYWRTdHJ1Y3QoUTApO2lmKFYhPT0wKXJldHVybiBHKFYpO3JldHVybiBSKHtlaWQ6JCxjdHI6LTEsdXBkYXRlZEF0OlEudHN9KX1hc3luYyBnZW5FSUQoJCl7bGV0e2Nsb2NrOlosY3J5cHRvOkp9PXRoaXMsUT1aLm5vdygpO2lmKCQhPT12b2lkIDApcmV0dXJuIFQkKHtpZDokLHRzOlF9KTtsZXQgVj1hd2FpdCBKLmdlblJhbmRvbUJ5dGVzKDgpO3JldHVybiBUJCh7aWQ6Vix0czpRfSl9c3luYygpe3JldHVybiB0aGlzLnN5bmNSdW5zLnJ1bigoKT0+dGhpcy5kb1N5bmMoKSl9YXN5bmMgZG9TeW5jKCl7bGV0e2Nvbm5lY3Rpb25zOiQsY3J5cHRvOlosc3RvcmU6Sn09dGhpcyxRPWF3YWl0IEouc2VlZC5sb2FkKCk7aWYoIVEpcmV0dXJuIDIyO2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCk7Zm9yKGxldFtWLFldb2YgJCl7bGV0IFg9YXdhaXQgSi5ob3N0cy5nZXQoVik7aWYoIVgpY29udGludWU7bGV0IFc9e2Nvbm46WSxzdG9yZTpKLGVuY2xhdmU6USxob3N0OlgsY3J5cHRvOlosbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LHo9YXdhaXQgTFooVyk7aWYoeiE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwZWVrOiAke3p9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLHo7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBLPWF3YWl0IHJKKFcpO2lmKEshPT0wKXJldHVybiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcHVzaDogJHtLfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxLO3RoaXMueGZlclN0YXRlLmVtaXQoKTtsZXQgRj1hd2FpdCB4WihXLGFzeW5jKCk9Pnthd2FpdCB0aGlzLmRyYWluQXBwbHlRdWV1ZSgpfSk7aWYoRiE9PTAmJkYhPT0xNSlyZXR1cm4gY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHB1bGw6ICR7Rn1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRjt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHJlYnVpbGQoJCl7aWYodGhpcy5zY2hlZHVsZWRTeW5jLmNhbmNlbCgpLGF3YWl0IHRoaXMuc3luY1J1bnMuZmx1c2goKSwkPy5jaGVja0hvc3Q/PyEwKXtsZXQgSj1hd2FpdCB0aGlzLnJlcHVsbCgpO2lmKEohPT0wKXJldHVybiBKfXJldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5yZXBsYXkoKSl9YXN5bmMgbXNnY2hlY2soKXtsZXQgJD1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3RLZXlzKCk7cmV0dXJuIHokKCQsdGhpcy5jcnlwdG8pfWxpc3RNc2dzKCQpe3JldHVybiB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3QoJCl9Y291bnRNc2dzKCQpe3JldHVybiB0aGlzLnN0b3JlLm1lc3NhZ2VzLmNvdW50KCQpfWFzeW5jIHJlY29uY2lsZSgkLFope3RoaXMuc2NoZWR1bGVkU3luYy5jYW5jZWwoKSxhd2FpdCB0aGlzLnN5bmNSdW5zLmZsdXNoKCk7bGV0e2Nvbm5lY3Rpb25zOkosY3J5cHRvOlEsc3RvcmU6Vn09dGhpcyxZPWF3YWl0IFYuc2VlZC5sb2FkKCk7aWYoIVkpcmV0dXJuIEcoMjIpO2xldCBYPWF3YWl0IFYuaG9zdHMuZ2V0KCQpO2lmKCFYKXJldHVybiBHKDEzKTtsZXQgVz1KLmdldCgkKTtpZighV3x8IVcuaXNDb25uZWN0ZWQoKSl7aWYoYXdhaXQgdGhpcy5jb25uZWN0VG9Ib3N0KFgsITEsITEpLFg9YXdhaXQgVi5ob3N0cy5nZXQoJCksIVgpcmV0dXJuIEcoMTMpO1c9Si5nZXQoJCl9aWYoIVcpcmV0dXJuIEcoMTIpO2xldCB6PXtjb25uOlcsc3RvcmU6VixlbmNsYXZlOlksY3J5cHRvOlEsbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LFtLLEZdPWF3YWl0IGZaKHsuLi56LGhvc3Q6WH0sWik7aWYodGhpcy54ZmVyU3RhdGUuZW1pdCgpLEYhPT0wKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRyhGKTtpZighSylyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEcoMTIpO2lmKFo/LnN5bmM9PT0hMSlyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLFIoSyk7bGV0IE49YXdhaXQgdGhpcy5zeW5jKCk7aWYoTiE9PTApcmV0dXJuIEcoTik7bGV0IFU9YXdhaXQgVi5ob3N0cy5nZXQoJCk7aWYoIVUpcmV0dXJuIEcoMTMpO2xldFtPLHFdPWF3YWl0IGZaKHsuLi56LGhvc3Q6VX0se3B1bGw6ITEscHVzaDohMX0pO2lmKHRoaXMueGZlclN0YXRlLmVtaXQoKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSkscSE9PTApcmV0dXJuIEcocSk7aWYoIU8pcmV0dXJuIEcoMTIpO3JldHVybiBSKE8pfWFzeW5jIHJlcHVsbCgpe2xldHtjb25uZWN0aW9uczokLGNyeXB0bzpaLHN0b3JlOkp9PXRoaXMsUT1hd2FpdCBKLnNlZWQubG9hZCgpO2lmKCFRKXJldHVybiAyMjtsZXQgVj1BcnJheS5mcm9tKGF3YWl0IEouaG9zdHMubGlzdCgpKTtpZihWLmxlbmd0aDwxKXJldHVybiAwO2ZvcihsZXQgWSBvZiBWKXtsZXQgWD0kLmdldChZLmxhYmVsKTtpZighWHx8IVguaXNDb25uZWN0ZWQoKSlhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QoWSwhMSwhMSl9Zm9yKGxldFtZLFhdb2YgJCl7bGV0IFc9YXdhaXQgSi5ob3N0cy5nZXQoWSk7aWYoIVcpY29udGludWU7bGV0IHo9e2Nvbm46WCxzdG9yZTpKLGVuY2xhdmU6USxob3N0OnsuLi5XLGxhc3RTZXE6MH0sY3J5cHRvOlosbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LEs9YXdhaXQgTFooeik7aWYoSyE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYHJlYnVpbGQ6IGZhaWxlZCB0byBwZWVrOiAke0t9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEs7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBGPWF3YWl0IHhaKHopO2lmKEYhPT0wJiZGIT09MTUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoYHJlYnVpbGQ6IGZhaWxlZCB0byBwdWxsOiAke0Z9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEY7dGhpcy54ZmVyU3RhdGUuZW1pdCgpfXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH1hc3luYyByZXBsYXkoKXtsZXQgJD1hd2FpdCB0aGlzLnN0YXRlLmNsZWFyKCk7aWYoJCE9PTApcmV0dXJuICQ7bGV0IFo9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0KCksSj1vMChaLChZKT0+WS5oZWFkKSxRPUoubGVuZ3RoO2lmKFE8MSlyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDA7bGV0IFY9MDt3aGlsZShWPEoubGVuZ3RoKXtsZXQgWT0wLFg9MCxXPVY7Zm9yKGxldCBLPVY7SzxKLmxlbmd0aCYmWDwxMDAmJlk8MTAyNDAwO0srKylZKz1KW0tdLmhlYWQubGVuLFgrKyxXPUsrMTtsZXQgej1KLnNsaWNlKFYsVyk7YXdhaXQgdGhpcy5hcHBseVN0b3JlZCh6KSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImV4ZWMiLGRvbmU6Vyx0b3RhbDpRfSksVj1XfXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH1hc3luYyB3aXBlKCQpe2xldCBaPSQ/Lm1zZ3MhPT0hMSxKPSQ/LmVudHMhPT0hMSxRPSQ/Lm1ldGEhPT0hMSxWPSQ/LnNlZWQ9PT0hMDt0aGlzLnNjaGVkdWxlZFN5bmMuY2FuY2VsKCksYXdhaXQgdGhpcy5kaXNjb25uZWN0KCksYXdhaXQgdGhpcy5zeW5jUnVucy5mbHVzaCgpO2xldHtzdG9yZTpZfT10aGlzO2lmKFEpYXdhaXQgWS5ob3N0cy53aXBlKCksYXdhaXQgWS51cGxvYWRzLndpcGUoKSxhd2FpdCBZLmRvd25sb2Fkcy53aXBlKCk7aWYoWilhd2FpdCBZLm1lc3NhZ2VzLndpcGUoKTtpZihWKWF3YWl0IFkuc2VlZC53aXBlKCk7aWYoSilhd2FpdCB0aGlzLnN0YXRlLmNsZWFyKCk7dGhpcy5sYXN0UHJvZ3Jlc3M9d1osdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksdGhpcy54ZmVyU3RhdGUuZW1pdCgpfWltcG9ydD1hc3luYygkLFopPT57bGV0e2NyeXB0bzpKLHN0b3JlOlF9PXRoaXMsVj1aPy5vblByb2dyZXNzLFk9YXdhaXQgUS5zZWVkLmxvYWQoKTtpZighWSlyZXR1cm4gMjI7Y29uc29sZS50aW1lKCJpbXBvcnQ6IGRlY29kaW5nIGZpbGUuLi4iKTtsZXQgWD1hd2FpdCAkLmJ5dGVzKCksW1csel09YXdhaXQgeEooWCxKLFkpO2lmKHohPT0wKXJldHVybiB6O2NvbnNvbGUudGltZUVuZCgiaW1wb3J0OiBkZWNvZGluZyBmaWxlLi4uIik7bGV0IEs9MDt3aGlsZShLPFcubGVuZ3RoKXtsZXQgRj0wLE49MCxVPUs7Zm9yKGxldCBJPUs7STxXLmxlbmd0aCYmTjwxMDAmJkY8MTAyNDAwO0krKylGKz1XW0ldLmhlYWQubGVuLE4rKyxVPUkrMTtsZXQgTz1XLnNsaWNlKEssVSk7Y29uc29sZS50aW1lKGBpbXBvcnQ6IGFwcGx5aW5nIFske0t9LCAke1V9XWApO2xldCBxPWF3YWl0IHRoaXMuYXBwbHkoTyx7ZW5xdWV1ZVVwbG9hZDohMCx0cmlnZ2VyVXBsb2FkOiExfSk7Y29uc29sZS50aW1lRW5kKGBpbXBvcnQ6IGFwcGx5aW5nIFske0t9LCAke1V9XWApO2ZvcihsZXQgST0wO0k8Ty5sZW5ndGg7SSsrKXtsZXQgSD1xW0ldO2lmKEghPT0wJiZIIT09MTUpY29uc29sZS53YXJuKGBmYWlsZWQgdG8gaW1wb3J0IG1zZyAke0srSX06ICR7altIXX1gKX1pZihWKXF1ZXVlTWljcm90YXNrKCgpPT5WKFUsVy5sZW5ndGgsMCkpO3RoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaW1wb3J0Iixkb25lOlUsdG90YWw6Vy5sZW5ndGh9KSxLPVV9cmV0dXJuIHRoaXMuc2NoZWR1bGVTeW5jKCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9O3NjaGVkdWxlU3luYz0oKT0+e2lmKHRoaXMub25TY2hlZHVsZVN5bmMpe3RoaXMub25TY2hlZHVsZVN5bmMoKTtyZXR1cm59dGhpcy5zY2hlZHVsZWRTeW5jLnNjaGVkdWxlKCl9O2FzeW5jIGV4cG9ydEJ5dGVzKCl7bGV0e2NyeXB0bzokLHN0b3JlOlp9PXRoaXMsSj1hd2FpdCBaLnNlZWQubG9hZCgpO2lmKCFKKXJldHVybiBHKDIyKTtsZXQgUT1hd2FpdCBaLm1lc3NhZ2VzLmxpc3QoKTtyZXR1cm4gTEooImV4cG9ydCIsMCxRLCQsSil9YXN5bmMgZXhwb3J0KCQpe2xldFtaLEpdPWF3YWl0IHRoaXMuZXhwb3J0Qnl0ZXMoKTtpZihKIT09MClyZXR1cm4gSjtpZighWilyZXR1cm4gMTI7bGV0IFE9bmV3IEJsb2IoW1ouc2xpY2UoKV0pO3JldHVybiBoSihRLCQpLDB9YXN5bmMgbGluaygkLFo9ITApe2lmKGF3YWl0IHRoaXMuc3RvcmUuaG9zdHMuYWRkKCQpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLFope2xldCBKPWF3YWl0IHRoaXMuc3RvcmUuaG9zdHMuZ2V0KCQubGFiZWwpO2lmKEopYXdhaXQgdGhpcy5jb25uZWN0VG9Ib3N0KEopfX1hc3luYyB1bmxpbmsoJCl7YXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5kZWwoJCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9YXN5bmMgaG9zdHMoKXtyZXR1cm4gQXJyYXkuZnJvbShhd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmxpc3QoKSl9Y29ubmVjdFRvSG9zdD1hc3luYygkLFo9ITAsSj0hMCk9PntsZXR7Y2xvY2s6USxjb25uZWN0aW9uczpWLGNyeXB0bzpZLHN0b3JlOlgsdHJhbnNwb3J0Old9PXRoaXMsej1WLmdldCgkLmxhYmVsKTtpZih6KXtpZih6LmlzQ29ubmVjdGVkKCkpcmV0dXJuO3RyeXt6LmNsb3NlTGlzdGVuZXIoKX1jYXRjaHt9Vi5kZWxldGUoJC5sYWJlbCl9bGV0IEs9YXdhaXQgWC5zZWVkLmxvYWQoKTtpZighSylyZXR1cm47Y29uc29sZS5pbmZvKGBDb25uZWN0aW5nIHRvICR7JC5oYW5kbGV9ICgkeyQubGFiZWx9KWApO2xldCBGPW5ldyBMJChLLFksJCxRLFcoJCksKE4pPT5YLmhvc3RzLnNldCgkLmxhYmVsLE4pKTtpZihhd2FpdCBGLnJlZ2lzdGVyKCksWilhd2FpdCBGLmxpc3Rlbihhc3luYyhOKT0+e2xldCBVPXtjb25uOkYsc3RvcmU6WCxlbmNsYXZlOkssaG9zdDokLGNyeXB0bzpZLG1heFB1c2hCeXRlczp0aGlzLm1heFB1c2hCeXRlcyxtYXhQdWxsQnl0ZXM6dGhpcy5tYXhQdWxsQnl0ZXMsb25Qcm9ncmVzczp0aGlzLmVtaXRQcm9ncmVzcyxwZWVrUHJvZ3Jlc3NFdmVyeTp0aGlzLnBlZWtQcm9ncmVzc0V2ZXJ5fTtyZXR1cm4gYUooTixVLHRoaXMuc2NoZWR1bGVTeW5jKX0sKCk9PnRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLCgpPT50aGlzLmNsaWVudFN0YXRlLmVtaXQoKSk7aWYoVi5zZXQoJC5sYWJlbCxGKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKSxKKXRoaXMuc2NoZWR1bGVTeW5jKCl9O2FzeW5jIGNvbm5lY3QoJD0hMCxaPSEwKXtsZXR7Y29ubmVjdFRvSG9zdDpKLHNjaGVkdWxlU3luYzpRLHN0b3JlOlZ9PXRoaXM7aWYoIWF3YWl0IFYuc2VlZC5sb2FkKCkpcmV0dXJuO2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCk7bGV0IFg9YXdhaXQgVi5ob3N0cy5saXN0KCk7Zm9yKGxldCBXIG9mIFgpYXdhaXQgSihXLCQsITEpO2lmKFopUSgpfWRpc2Nvbm5lY3Q9YXN5bmMoKT0+e2ZvcihsZXQgJCBvZiB0aGlzLmNvbm5lY3Rpb25zLnZhbHVlcygpKXRyeXskLmNsb3NlTGlzdGVuZXIoKX1jYXRjaHt9dGhpcy5jb25uZWN0aW9ucy5jbGVhcigpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpfX12YXIgeDA9dHlwZW9mIGdsb2JhbFRoaXM9PT0ib2JqZWN0IiYmImNyeXB0byJpbiBnbG9iYWxUaGlzP2dsb2JhbFRoaXMuY3J5cHRvOnZvaWQgMDtmdW5jdGlvbiBiJCgkKXtpZighTnVtYmVyLmlzU2FmZUludGVnZXIoJCl8fCQ8MCl0aHJvdyBFcnJvcigicG9zaXRpdmUgaW50ZWdlciBleHBlY3RlZCwgZ290ICIrJCl9ZnVuY3Rpb24gQlooJCl7cmV0dXJuICQgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxBcnJheUJ1ZmZlci5pc1ZpZXcoJCkmJiQuY29uc3RydWN0b3IubmFtZT09PSJVaW50OEFycmF5In1mdW5jdGlvbiBkKCQsLi4uWil7aWYoIUJaKCQpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIik7aWYoWi5sZW5ndGg+MCYmIVouaW5jbHVkZXMoJC5sZW5ndGgpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIG9mIGxlbmd0aCAiK1orIiwgZ290IGxlbmd0aD0iKyQubGVuZ3RoKX1mdW5jdGlvbiBFWigkLFo9ITApe2lmKCQuZGVzdHJveWVkKXRocm93IEVycm9yKCJIYXNoIGluc3RhbmNlIGhhcyBiZWVuIGRlc3Ryb3llZCIpO2lmKFomJiQuZmluaXNoZWQpdGhyb3cgRXJyb3IoIkhhc2gjZGlnZXN0KCkgaGFzIGFscmVhZHkgYmVlbiBjYWxsZWQiKX1mdW5jdGlvbiBzSigkLFope2QoJCk7bGV0IEo9Wi5vdXRwdXRMZW47aWYoJC5sZW5ndGg8Sil0aHJvdyBFcnJvcigiZGlnZXN0SW50bygpIGV4cGVjdHMgb3V0cHV0IGJ1ZmZlciBvZiBsZW5ndGggYXQgbGVhc3QgIitKKX1mdW5jdGlvbiBtWigkKXtpZih0eXBlb2YgJCE9PSJib29sZWFuIil0aHJvdyBFcnJvcihgYm9vbGVhbiBleHBlY3RlZCwgbm90ICR7JH1gKX0vKiEgbm9ibGUtY2lwaGVycyAtIE1JVCBMaWNlbnNlIChjKSAyMDIzIFBhdWwgTWlsbGVyIChwYXVsbWlsbHIuY29tKSAqL3ZhciBJMD0oJCk9Pm5ldyBVaW50MzJBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsTWF0aC5mbG9vcigkLmJ5dGVMZW5ndGgvNCkpO3ZhciBUVj1uZXcgVWludDhBcnJheShuZXcgVWludDMyQXJyYXkoWzI4NzQ1NDAyMF0pLmJ1ZmZlcilbMF09PT02ODtpZighVFYpdGhyb3cgRXJyb3IoIk5vbiBsaXR0bGUtZW5kaWFuIGhhcmR3YXJlIGlzIG5vdCBzdXBwb3J0ZWQiKTtmdW5jdGlvbiBEVigkKXtpZih0eXBlb2YgJCE9PSJzdHJpbmciKXRocm93IEVycm9yKCJzdHJpbmcgZXhwZWN0ZWQiKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkobmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpKX1mdW5jdGlvbiB5JCgkKXtpZih0eXBlb2YgJD09PSJzdHJpbmciKSQ9RFYoJCk7ZWxzZSBpZihCWigkKSkkPWkkKCQpO2Vsc2UgdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQsIGdvdCAiK3R5cGVvZiAkKTtyZXR1cm4gJH1mdW5jdGlvbiB0SigkLFope2lmKFo9PW51bGx8fHR5cGVvZiBaIT09Im9iamVjdCIpdGhyb3cgRXJyb3IoIm9wdGlvbnMgbXVzdCBiZSBkZWZpbmVkIik7cmV0dXJuIE9iamVjdC5hc3NpZ24oJCxaKX1mdW5jdGlvbiBlSigkLFope2lmKCQubGVuZ3RoIT09Wi5sZW5ndGgpcmV0dXJuITE7bGV0IEo9MDtmb3IobGV0IFE9MDtRPCQubGVuZ3RoO1ErKylKfD0kW1FdXlpbUV07cmV0dXJuIEo9PT0wfXZhciAkUT0oJCxaKT0+e2Z1bmN0aW9uIEooUSwuLi5WKXtpZihkKFEpLCQubm9uY2VMZW5ndGghPT12b2lkIDApe2xldCBGPVZbMF07aWYoIUYpdGhyb3cgRXJyb3IoIm5vbmNlIC8gaXYgcmVxdWlyZWQiKTtpZigkLnZhclNpemVOb25jZSlkKEYpO2Vsc2UgZChGLCQubm9uY2VMZW5ndGgpfWxldCBZPSQudGFnTGVuZ3RoO2lmKFkmJlZbMV0hPT12b2lkIDApZChWWzFdKTtsZXQgWD1aKFEsLi4uViksVz0oRixOKT0+e2lmKE4hPT12b2lkIDApe2lmKEYhPT0yKXRocm93IEVycm9yKCJjaXBoZXIgb3V0cHV0IG5vdCBzdXBwb3J0ZWQiKTtkKE4pfX0sej0hMTtyZXR1cm57ZW5jcnlwdChGLE4pe2lmKHopdGhyb3cgRXJyb3IoImNhbm5vdCBlbmNyeXB0KCkgdHdpY2Ugd2l0aCBzYW1lIGtleSArIG5vbmNlIik7cmV0dXJuIHo9ITAsZChGKSxXKFguZW5jcnlwdC5sZW5ndGgsTiksWC5lbmNyeXB0KEYsTil9LGRlY3J5cHQoRixOKXtpZihkKEYpLFkmJkYubGVuZ3RoPFkpdGhyb3cgRXJyb3IoImludmFsaWQgY2lwaGVydGV4dCBsZW5ndGg6IHNtYWxsZXIgdGhhbiB0YWdMZW5ndGg9IitZKTtyZXR1cm4gVyhYLmRlY3J5cHQubGVuZ3RoLE4pLFguZGVjcnlwdChGLE4pfX19cmV0dXJuIE9iamVjdC5hc3NpZ24oSiwkKSxKfTtmdW5jdGlvbiBnWigkLFosSj0hMCl7aWYoWj09PXZvaWQgMClyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJCk7aWYoWi5sZW5ndGghPT0kKXRocm93IEVycm9yKCJpbnZhbGlkIG91dHB1dCBsZW5ndGgsIGV4cGVjdGVkICIrJCsiLCBnb3Q6ICIrWi5sZW5ndGgpO2lmKEomJiFqVihaKSl0aHJvdyBFcnJvcigiaW52YWxpZCBvdXRwdXQsIG11c3QgYmUgYWxpZ25lZCIpO3JldHVybiBafWZ1bmN0aW9uIGpWKCQpe3JldHVybiAkLmJ5dGVPZmZzZXQlND09PTB9ZnVuY3Rpb24gaSQoJCl7cmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX1mdW5jdGlvbiBVMCguLi4kKXtmb3IobGV0IFo9MDtaPCQubGVuZ3RoO1orKykkW1pdLmZpbGwoMCl9ZnVuY3Rpb24gaCQoJD0zMil7aWYoeDAmJnR5cGVvZiB4MC5nZXRSYW5kb21WYWx1ZXM9PT0iZnVuY3Rpb24iKXJldHVybiB4MC5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQ4QXJyYXkoJCkpO2lmKHgwJiZ0eXBlb2YgeDAucmFuZG9tQnl0ZXM9PT0iZnVuY3Rpb24iKXJldHVybiB4MC5yYW5kb21CeXRlcygkKTt0aHJvdyBFcnJvcigiY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBtdXN0IGJlIGRlZmluZWQiKX12YXIgSlE9KCQpPT5VaW50OEFycmF5LmZyb20oJC5zcGxpdCgiIikubWFwKChaKT0+Wi5jaGFyQ29kZUF0KDApKSksQVY9SlEoImV4cGFuZCAxNi1ieXRlIGsiKSxfVj1KUSgiZXhwYW5kIDMyLWJ5dGUgayIpLExWPUkwKEFWKSx4Vj1JMChfVik7ZnVuY3Rpb24gRCgkLFope3JldHVybiAkPDxafCQ+Pj4zMi1afWZ1bmN0aW9uIFNaKCQpe3JldHVybiAkLmJ5dGVPZmZzZXQlND09PTB9dmFyIHUkPTY0LGZWPTE2LFFRPTQyOTQ5NjcyOTUsWlE9bmV3IFVpbnQzMkFycmF5O2Z1bmN0aW9uIGtWKCQsWixKLFEsVixZLFgsVyl7bGV0IHo9Vi5sZW5ndGgsSz1uZXcgVWludDhBcnJheSh1JCksRj1JMChLKSxOPVNaKFYpJiZTWihZKSxVPU4/STAoVik6WlEsTz1OP0kwKFkpOlpRO2ZvcihsZXQgcT0wO3E8ejtYKyspe2lmKCQoWixKLFEsRixYLFcpLFg+PVFRKXRocm93IEVycm9yKCJhcng6IGNvdW50ZXIgb3ZlcmZsb3ciKTtsZXQgST1NYXRoLm1pbih1JCx6LXEpO2lmKE4mJkk9PT11JCl7bGV0IEg9cS80O2lmKHElNCE9PTApdGhyb3cgRXJyb3IoImFyeDogaW52YWxpZCBibG9jayBwb3NpdGlvbiIpO2ZvcihsZXQgUD0wLEM7UDxmVjtQKyspQz1IK1AsT1tDXT1VW0NdXkZbUF07cSs9dSQ7Y29udGludWV9Zm9yKGxldCBIPTAsUDtIPEk7SCsrKVA9cStILFlbUF09VltQXV5LW0hdO3ErPUl9fWZ1bmN0aW9uIFZRKCQsWil7bGV0e2FsbG93U2hvcnRLZXlzOkosZXh0ZW5kTm9uY2VGbjpRLGNvdW50ZXJMZW5ndGg6Vixjb3VudGVyUmlnaHQ6WSxyb3VuZHM6WH09dEooe2FsbG93U2hvcnRLZXlzOiExLGNvdW50ZXJMZW5ndGg6OCxjb3VudGVyUmlnaHQ6ITEscm91bmRzOjIwfSxaKTtpZih0eXBlb2YgJCE9PSJmdW5jdGlvbiIpdGhyb3cgRXJyb3IoImNvcmUgbXVzdCBiZSBhIGZ1bmN0aW9uIik7cmV0dXJuIGIkKFYpLGIkKFgpLG1aKFkpLG1aKEopLChXLHosSyxGLE49MCk9PntkKFcpLGQoeiksZChLKTtsZXQgVT1LLmxlbmd0aDtpZihGPT09dm9pZCAwKUY9bmV3IFVpbnQ4QXJyYXkoVSk7aWYoZChGKSxiJChOKSxOPDB8fE4+PVFRKXRocm93IEVycm9yKCJhcng6IGNvdW50ZXIgb3ZlcmZsb3ciKTtpZihGLmxlbmd0aDxVKXRocm93IEVycm9yKGBhcng6IG91dHB1dCAoJHtGLmxlbmd0aH0pIGlzIHNob3J0ZXIgdGhhbiBkYXRhICgke1V9KWApO2xldCBPPVtdLHE9Vy5sZW5ndGgsSSxIO2lmKHE9PT0zMilPLnB1c2goST1pJChXKSksSD14VjtlbHNlIGlmKHE9PT0xNiYmSilJPW5ldyBVaW50OEFycmF5KDMyKSxJLnNldChXKSxJLnNldChXLDE2KSxIPUxWLE8ucHVzaChJKTtlbHNlIHRocm93IEVycm9yKGBhcng6IGludmFsaWQgMzItYnl0ZSBrZXksIGdvdCBsZW5ndGg9JHtxfWApO2lmKCFTWih6KSlPLnB1c2goej1pJCh6KSk7bGV0IFA9STAoSSk7aWYoUSl7aWYoei5sZW5ndGghPT0yNCl0aHJvdyBFcnJvcigiYXJ4OiBleHRlbmRlZCBub25jZSBtdXN0IGJlIDI0IGJ5dGVzIik7UShILFAsSTAoei5zdWJhcnJheSgwLDE2KSksUCksej16LnN1YmFycmF5KDE2KX1sZXQgQz0xNi1WO2lmKEMhPT16Lmxlbmd0aCl0aHJvdyBFcnJvcihgYXJ4OiBub25jZSBtdXN0IGJlICR7Q30gb3IgMTYgYnl0ZXNgKTtpZihDIT09MTIpe2xldCBNPW5ldyBVaW50OEFycmF5KDEyKTtNLnNldCh6LFk/MDoxMi16Lmxlbmd0aCksej1NLE8ucHVzaCh6KX1sZXQgVD1JMCh6KTtyZXR1cm4ga1YoJCxILFAsVCxLLEYsTixYKSxVMCguLi5PKSxGfX12YXIgbz0oJCxaKT0+JFtaKytdJjI1NXwoJFtaKytdJjI1NSk8PDg7Y2xhc3MgWVF7Y29uc3RydWN0b3IoJCl7dGhpcy5ibG9ja0xlbj0xNix0aGlzLm91dHB1dExlbj0xNix0aGlzLmJ1ZmZlcj1uZXcgVWludDhBcnJheSgxNiksdGhpcy5yPW5ldyBVaW50MTZBcnJheSgxMCksdGhpcy5oPW5ldyBVaW50MTZBcnJheSgxMCksdGhpcy5wYWQ9bmV3IFVpbnQxNkFycmF5KDgpLHRoaXMucG9zPTAsdGhpcy5maW5pc2hlZD0hMSwkPXkkKCQpLGQoJCwzMik7bGV0IFo9bygkLDApLEo9bygkLDIpLFE9bygkLDQpLFY9bygkLDYpLFk9bygkLDgpLFg9bygkLDEwKSxXPW8oJCwxMiksej1vKCQsMTQpO3RoaXMuclswXT1aJjgxOTEsdGhpcy5yWzFdPShaPj4+MTN8Sjw8MykmODE5MSx0aGlzLnJbMl09KEo+Pj4xMHxRPDw2KSY3OTM5LHRoaXMuclszXT0oUT4+Pjd8Vjw8OSkmODE5MSx0aGlzLnJbNF09KFY+Pj40fFk8PDEyKSYyNTUsdGhpcy5yWzVdPVk+Pj4xJjgxOTAsdGhpcy5yWzZdPShZPj4+MTR8WDw8MikmODE5MSx0aGlzLnJbN109KFg+Pj4xMXxXPDw1KSY4MDY1LHRoaXMucls4XT0oVz4+Pjh8ejw8OCkmODE5MSx0aGlzLnJbOV09ej4+PjUmMTI3O2ZvcihsZXQgSz0wO0s8ODtLKyspdGhpcy5wYWRbS109bygkLDE2KzIqSyl9cHJvY2VzcygkLFosSj0hMSl7bGV0IFE9Sj8wOjIwNDgse2g6VixyOll9PXRoaXMsWD1ZWzBdLFc9WVsxXSx6PVlbMl0sSz1ZWzNdLEY9WVs0XSxOPVlbNV0sVT1ZWzZdLE89WVs3XSxxPVlbOF0sST1ZWzldLEg9bygkLForMCksUD1vKCQsWisyKSxDPW8oJCxaKzQpLFQ9bygkLForNiksTT1vKCQsWis4KSxBPW8oJCxaKzEwKSx4PW8oJCxaKzEyKSxtPW8oJCxaKzE0KSxFPVZbMF0rKEgmODE5MSksaz1WWzFdKygoSD4+PjEzfFA8PDMpJjgxOTEpLGI9VlsyXSsoKFA+Pj4xMHxDPDw2KSY4MTkxKSx3PVZbM10rKChDPj4+N3xUPDw5KSY4MTkxKSxoPVZbNF0rKChUPj4+NHxNPDwxMikmODE5MSksbD1WWzVdKyhNPj4+MSY4MTkxKSxMPVZbNl0rKChNPj4+MTR8QTw8MikmODE5MSksdj1WWzddKygoQT4+PjExfHg8PDUpJjgxOTEpLEI9Vls4XSsoKHg+Pj44fG08PDgpJjgxOTEpLHk9Vls5XSsobT4+PjV8USksXz0wLGM9XytFKlgrayooNSpJKStiKig1KnEpK3cqKDUqTykraCooNSpVKTtfPWM+Pj4xMyxjJj04MTkxLGMrPWwqKDUqTikrTCooNSpGKSt2Kig1KkspK0IqKDUqeikreSooNSpXKSxfKz1jPj4+MTMsYyY9ODE5MTtsZXQgYT1fK0UqVytrKlgrYiooNSpJKSt3Kig1KnEpK2gqKDUqTyk7Xz1hPj4+MTMsYSY9ODE5MSxhKz1sKig1KlUpK0wqKDUqTikrdiooNSpGKStCKig1KkspK3kqKDUqeiksXys9YT4+PjEzLGEmPTgxOTE7bGV0IEowPV8rRSp6K2sqVytiKlgrdyooNSpJKStoKig1KnEpO189SjA+Pj4xMyxKMCY9ODE5MSxKMCs9bCooNSpPKStMKig1KlUpK3YqKDUqTikrQiooNSpGKSt5Kig1KkspLF8rPUowPj4+MTMsSjAmPTgxOTE7bGV0IHA9XytFKksrayp6K2IqVyt3KlgraCooNSpJKTtfPXA+Pj4xMyxwJj04MTkxLHArPWwqKDUqcSkrTCooNSpPKSt2Kig1KlUpK0IqKDUqTikreSooNSpGKSxfKz1wPj4+MTMscCY9ODE5MTtsZXQgcTA9XytFKkYraypLK2Iqeit3KlcraCpYO189cTA+Pj4xMyxxMCY9ODE5MSxxMCs9bCooNSpJKStMKig1KnEpK3YqKDUqTykrQiooNSpVKSt5Kig1Kk4pLF8rPXEwPj4+MTMscTAmPTgxOTE7bGV0IHYwPV8rRSpOK2sqRitiKksrdyp6K2gqVztfPXYwPj4+MTMsdjAmPTgxOTEsdjArPWwqWCtMKig1KkkpK3YqKDUqcSkrQiooNSpPKSt5Kig1KlUpLF8rPXYwPj4+MTMsdjAmPTgxOTE7bGV0IGIwPV8rRSpVK2sqTitiKkYrdypLK2gqejtfPWIwPj4+MTMsYjAmPTgxOTEsYjArPWwqVytMKlgrdiooNSpJKStCKig1KnEpK3kqKDUqTyksXys9YjA+Pj4xMyxiMCY9ODE5MTtsZXQgeTA9XytFKk8raypVK2IqTit3KkYraCpLO189eTA+Pj4xMyx5MCY9ODE5MSx5MCs9bCp6K0wqVyt2KlgrQiooNSpJKSt5Kig1KnEpLF8rPXkwPj4+MTMseTAmPTgxOTE7bGV0IGkwPV8rRSpxK2sqTytiKlUrdypOK2gqRjtfPWkwPj4+MTMsaTAmPTgxOTEsaTArPWwqSytMKnordipXK0IqWCt5Kig1KkkpLF8rPWkwPj4+MTMsaTAmPTgxOTE7bGV0IGgwPV8rRSpJK2sqcStiKk8rdypVK2gqTjtfPWgwPj4+MTMsaDAmPTgxOTEsaDArPWwqRitMKksrdip6K0IqVyt5KlgsXys9aDA+Pj4xMyxoMCY9ODE5MSxfPShfPDwyKStffDAsXz1fK2N8MCxjPV8mODE5MSxfPV8+Pj4xMyxhKz1fLFZbMF09YyxWWzFdPWEsVlsyXT1KMCxWWzNdPXAsVls0XT1xMCxWWzVdPXYwLFZbNl09YjAsVls3XT15MCxWWzhdPWkwLFZbOV09aDB9ZmluYWxpemUoKXtsZXR7aDokLHBhZDpafT10aGlzLEo9bmV3IFVpbnQxNkFycmF5KDEwKSxRPSRbMV0+Pj4xMzskWzFdJj04MTkxO2ZvcihsZXQgWD0yO1g8MTA7WCsrKSRbWF0rPVEsUT0kW1hdPj4+MTMsJFtYXSY9ODE5MTskWzBdKz1RKjUsUT0kWzBdPj4+MTMsJFswXSY9ODE5MSwkWzFdKz1RLFE9JFsxXT4+PjEzLCRbMV0mPTgxOTEsJFsyXSs9USxKWzBdPSRbMF0rNSxRPUpbMF0+Pj4xMyxKWzBdJj04MTkxO2ZvcihsZXQgWD0xO1g8MTA7WCsrKUpbWF09JFtYXStRLFE9SltYXT4+PjEzLEpbWF0mPTgxOTE7Sls5XS09ODE5MjtsZXQgVj0oUV4xKS0xO2ZvcihsZXQgWD0wO1g8MTA7WCsrKUpbWF0mPVY7Vj1+Vjtmb3IobGV0IFg9MDtYPDEwO1grKykkW1hdPSRbWF0mVnxKW1hdOyRbMF09KCRbMF18JFsxXTw8MTMpJjY1NTM1LCRbMV09KCRbMV0+Pj4zfCRbMl08PDEwKSY2NTUzNSwkWzJdPSgkWzJdPj4+NnwkWzNdPDw3KSY2NTUzNSwkWzNdPSgkWzNdPj4+OXwkWzRdPDw0KSY2NTUzNSwkWzRdPSgkWzRdPj4+MTJ8JFs1XTw8MXwkWzZdPDwxNCkmNjU1MzUsJFs1XT0oJFs2XT4+PjJ8JFs3XTw8MTEpJjY1NTM1LCRbNl09KCRbN10+Pj41fCRbOF08PDgpJjY1NTM1LCRbN109KCRbOF0+Pj44fCRbOV08PDUpJjY1NTM1O2xldCBZPSRbMF0rWlswXTskWzBdPVkmNjU1MzU7Zm9yKGxldCBYPTE7WDw4O1grKylZPSgkW1hdK1pbWF18MCkrKFk+Pj4xNil8MCwkW1hdPVkmNjU1MzU7VTAoSil9dXBkYXRlKCQpe0VaKHRoaXMpO2xldHtidWZmZXI6WixibG9ja0xlbjpKfT10aGlzOyQ9eSQoJCk7bGV0IFE9JC5sZW5ndGg7Zm9yKGxldCBWPTA7VjxROyl7bGV0IFk9TWF0aC5taW4oSi10aGlzLnBvcyxRLVYpO2lmKFk9PT1KKXtmb3IoO0o8PVEtVjtWKz1KKXRoaXMucHJvY2VzcygkLFYpO2NvbnRpbnVlfWlmKFouc2V0KCQuc3ViYXJyYXkoVixWK1kpLHRoaXMucG9zKSx0aGlzLnBvcys9WSxWKz1ZLHRoaXMucG9zPT09Sil0aGlzLnByb2Nlc3MoWiwwLCExKSx0aGlzLnBvcz0wfXJldHVybiB0aGlzfWRlc3Ryb3koKXtVMCh0aGlzLmgsdGhpcy5yLHRoaXMuYnVmZmVyLHRoaXMucGFkKX1kaWdlc3RJbnRvKCQpe0VaKHRoaXMpLHNKKCQsdGhpcyksdGhpcy5maW5pc2hlZD0hMDtsZXR7YnVmZmVyOlosaDpKfT10aGlzLHtwb3M6UX09dGhpcztpZihRKXtaW1ErK109MTtmb3IoO1E8MTY7USsrKVpbUV09MDt0aGlzLnByb2Nlc3MoWiwwLCEwKX10aGlzLmZpbmFsaXplKCk7bGV0IFY9MDtmb3IobGV0IFk9MDtZPDg7WSsrKSRbVisrXT1KW1ldPj4+MCwkW1YrK109SltZXT4+Pjg7cmV0dXJuICR9ZGlnZXN0KCl7bGV0e2J1ZmZlcjokLG91dHB1dExlbjpafT10aGlzO3RoaXMuZGlnZXN0SW50bygkKTtsZXQgSj0kLnNsaWNlKDAsWik7cmV0dXJuIHRoaXMuZGVzdHJveSgpLEp9fWZ1bmN0aW9uIEJWKCQpe2xldCBaPShRLFYpPT4kKFYpLnVwZGF0ZSh5JChRKSkuZGlnZXN0KCksSj0kKG5ldyBVaW50OEFycmF5KDMyKSk7cmV0dXJuIFoub3V0cHV0TGVuPUoub3V0cHV0TGVuLFouYmxvY2tMZW49Si5ibG9ja0xlbixaLmNyZWF0ZT0oUSk9PiQoUSksWn12YXIgdlo9QlYoKCQpPT5uZXcgWVEoJCkpO2Z1bmN0aW9uIEVWKCQsWixKLFEsVixZPTIwKXtsZXQgWD0kWzBdLFc9WlswXSx6PVpbMV0sSz1aWzJdLEY9WlszXSxOPSRbMV0sVT1KWzBdLE89SlsxXSxxPVYsST0wLEg9JFsyXSxQPVpbNF0sQz1aWzVdLFQ9Wls2XSxNPVpbN10sQT0kWzNdLHg9WCxtPVcsRT16LGs9SyxiPUYsdz1OLGg9VSxsPU8sTD1xLHY9SSxCPUgseT1QLF89QyxjPVQsYT1NLEowPUE7Zm9yKGxldCBxMD0wO3EwPFk7cTArPTIpYl49RCh4K198MCw3KSxMXj1EKGIreHwwLDkpLF9ePUQoTCtifDAsMTMpLHhePUQoXytMfDAsMTgpLHZePUQodyttfDAsNyksY149RCh2K3d8MCw5KSxtXj1EKGMrdnwwLDEzKSx3Xj1EKG0rY3wwLDE4KSxhXj1EKEIraHwwLDcpLEVePUQoYStCfDAsOSksaF49RChFK2F8MCwxMyksQl49RChoK0V8MCwxOCksa149RChKMCt5fDAsNyksbF49RChrK0owfDAsOSkseV49RChsK2t8MCwxMyksSjBePUQoeStsfDAsMTgpLG1ePUQoeCtrfDAsNyksRV49RChtK3h8MCw5KSxrXj1EKEUrbXwwLDEzKSx4Xj1EKGsrRXwwLDE4KSxoXj1EKHcrYnwwLDcpLGxePUQoaCt3fDAsOSksYl49RChsK2h8MCwxMyksd149RChiK2x8MCwxOCkseV49RChCK3Z8MCw3KSxMXj1EKHkrQnwwLDkpLHZePUQoTCt5fDAsMTMpLEJePUQoditMfDAsMTgpLF9ePUQoSjArYXwwLDcpLGNePUQoXytKMHwwLDkpLGFePUQoYytffDAsMTMpLEowXj1EKGErY3wwLDE4KTtsZXQgcD0wO1FbcCsrXT1YK3h8MCxRW3ArK109VyttfDAsUVtwKytdPXorRXwwLFFbcCsrXT1LK2t8MCxRW3ArK109RitifDAsUVtwKytdPU4rd3wwLFFbcCsrXT1VK2h8MCxRW3ArK109TytsfDAsUVtwKytdPXErTHwwLFFbcCsrXT1JK3Z8MCxRW3ArK109SCtCfDAsUVtwKytdPVAreXwwLFFbcCsrXT1DK198MCxRW3ArK109VCtjfDAsUVtwKytdPU0rYXwwLFFbcCsrXT1BK0owfDB9ZnVuY3Rpb24gbVYoJCxaLEosUSl7bGV0IFY9JFswXSxZPVpbMF0sWD1aWzFdLFc9WlsyXSx6PVpbM10sSz0kWzFdLEY9SlswXSxOPUpbMV0sVT1KWzJdLE89SlszXSxxPSRbMl0sST1aWzRdLEg9Wls1XSxQPVpbNl0sQz1aWzddLFQ9JFszXTtmb3IobGV0IEE9MDtBPDIwO0ErPTIpel49RChWK0h8MCw3KSxVXj1EKHorVnwwLDkpLEhePUQoVSt6fDAsMTMpLFZePUQoSCtVfDAsMTgpLE9ePUQoSytZfDAsNyksUF49RChPK0t8MCw5KSxZXj1EKFArT3wwLDEzKSxLXj1EKFkrUHwwLDE4KSxDXj1EKHErRnwwLDcpLFhePUQoQytxfDAsOSksRl49RChYK0N8MCwxMykscV49RChGK1h8MCwxOCksV149RChUK0l8MCw3KSxOXj1EKFcrVHwwLDkpLElePUQoTitXfDAsMTMpLFRePUQoSStOfDAsMTgpLFlePUQoVitXfDAsNyksWF49RChZK1Z8MCw5KSxXXj1EKFgrWXwwLDEzKSxWXj1EKFcrWHwwLDE4KSxGXj1EKEsrenwwLDcpLE5ePUQoRitLfDAsOSksel49RChOK0Z8MCwxMyksS149RCh6K058MCwxOCksSV49RChxK098MCw3KSxVXj1EKEkrcXwwLDkpLE9ePUQoVStJfDAsMTMpLHFePUQoTytVfDAsMTgpLEhePUQoVCtDfDAsNyksUF49RChIK1R8MCw5KSxDXj1EKFArSHwwLDEzKSxUXj1EKEMrUHwwLDE4KTtsZXQgTT0wO1FbTSsrXT1WLFFbTSsrXT1LLFFbTSsrXT1xLFFbTSsrXT1ULFFbTSsrXT1GLFFbTSsrXT1OLFFbTSsrXT1VLFFbTSsrXT1PfXZhciBiWj1WUShFVix7Y291bnRlclJpZ2h0OiEwLGV4dGVuZE5vbmNlRm46bVZ9KSx5Wj0kUSh7YmxvY2tTaXplOjY0LG5vbmNlTGVuZ3RoOjI0LHRhZ0xlbmd0aDoxNn0sKCQsWik9PntyZXR1cm57ZW5jcnlwdChKLFEpe1E9Z1ooSi5sZW5ndGgrMzIsUSwhMSk7bGV0IFY9US5zdWJhcnJheSgwLDMyKSxZPVEuc3ViYXJyYXkoMzIpO1Euc2V0KEosMzIpLFUwKFYpLGJaKCQsWixRLFEpO2xldCBYPXZaKFksVik7cmV0dXJuIFEuc2V0KFgsMTYpLFUwKFEuc3ViYXJyYXkoMCwxNiksWCksUS5zdWJhcnJheSgxNil9LGRlY3J5cHQoSixRKXtkKEopLFE9Z1ooSi5sZW5ndGgrMzIsUSwhMSk7bGV0IFY9US5zdWJhcnJheSgwLDMyKSxZPVEuc3ViYXJyYXkoMzIsNDgpLFg9US5zdWJhcnJheSg0OCk7US5zZXQoSiwzMiksVTAoVik7bGV0IFc9YlooJCxaLFYsViksej12WihYLFcpO2lmKCFlSihZLHopKXRocm93IEVycm9yKCJpbnZhbGlkIHRhZyIpO3JldHVybiBiWigkLFosUS5zdWJhcnJheSgxNiksUS5zdWJhcnJheSgxNikpLFUwKFYsWSx6KSxYfX19KTsvKiEgbm9ibGUtaGFzaGVzIC0gTUlUIExpY2Vuc2UgKGMpIDIwMjIgUGF1bCBNaWxsZXIgKHBhdWxtaWxsci5jb20pICovZnVuY3Rpb24gZ1YoJCl7cmV0dXJuICQgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxBcnJheUJ1ZmZlci5pc1ZpZXcoJCkmJiQuY29uc3RydWN0b3IubmFtZT09PSJVaW50OEFycmF5In1mdW5jdGlvbiBGJCgkKXtpZighTnVtYmVyLmlzU2FmZUludGVnZXIoJCl8fCQ8MCl0aHJvdyBFcnJvcigicG9zaXRpdmUgaW50ZWdlciBleHBlY3RlZCwgZ290ICIrJCl9ZnVuY3Rpb24gZjAoJCwuLi5aKXtpZighZ1YoJCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQiKTtpZihaLmxlbmd0aD4wJiYhWi5pbmNsdWRlcygkLmxlbmd0aCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQgb2YgbGVuZ3RoICIrWisiLCBnb3QgbGVuZ3RoPSIrJC5sZW5ndGgpfWZ1bmN0aW9uIE4kKCQsWj0hMCl7aWYoJC5kZXN0cm95ZWQpdGhyb3cgRXJyb3IoIkhhc2ggaW5zdGFuY2UgaGFzIGJlZW4gZGVzdHJveWVkIik7aWYoWiYmJC5maW5pc2hlZCl0aHJvdyBFcnJvcigiSGFzaCNkaWdlc3QoKSBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZCIpfWZ1bmN0aW9uIGwkKCQsWil7ZjAoJCk7bGV0IEo9Wi5vdXRwdXRMZW47aWYoJC5sZW5ndGg8Sil0aHJvdyBFcnJvcigiZGlnZXN0SW50bygpIGV4cGVjdHMgb3V0cHV0IGJ1ZmZlciBvZiBsZW5ndGggYXQgbGVhc3QgIitKKX1mdW5jdGlvbiBYUSgkKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LCQuYnl0ZUxlbmd0aCl9ZnVuY3Rpb24gdDAoJCl7cmV0dXJuIG5ldyBVaW50MzJBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsTWF0aC5mbG9vcigkLmJ5dGVMZW5ndGgvNCkpfWZ1bmN0aW9uIGUwKC4uLiQpe2ZvcihsZXQgWj0wO1o8JC5sZW5ndGg7WisrKSRbWl0uZmlsbCgwKX1mdW5jdGlvbiBSJCgkLFope3JldHVybiAkPDwzMi1afCQ+Pj5afXZhciBXUT0oKCk9Pm5ldyBVaW50OEFycmF5KG5ldyBVaW50MzJBcnJheShbMjg3NDU0MDIwXSkuYnVmZmVyKVswXT09PTY4KSgpO2Z1bmN0aW9uIEdRKCQpe3JldHVybiAkPDwyNCY0Mjc4MTkwMDgwfCQ8PDgmMTY3MTE2ODB8JD4+PjgmNjUyODB8JD4+PjI0JjI1NX12YXIgelE9V1E/KCQpPT4kOigkKT0+R1EoJCk7ZnVuY3Rpb24gU1YoJCl7Zm9yKGxldCBaPTA7WjwkLmxlbmd0aDtaKyspJFtaXT1HUSgkW1pdKTtyZXR1cm4gJH12YXIgZT1XUT8oJCk9PiQ6U1Y7ZnVuY3Rpb24gdlYoJCl7aWYodHlwZW9mICQhPT0ic3RyaW5nIil0aHJvdyBFcnJvcigic3RyaW5nIGV4cGVjdGVkIik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSl9ZnVuY3Rpb24gJCQoJCl7aWYodHlwZW9mICQ9PT0ic3RyaW5nIikkPXZWKCQpO3JldHVybiBmMCgkKSwkfWNsYXNzIGlae31mdW5jdGlvbiBLUSgkKXtsZXQgWj0oUSxWKT0+JChWKS51cGRhdGUoJCQoUSkpLmRpZ2VzdCgpLEo9JCh7fSk7cmV0dXJuIFoub3V0cHV0TGVuPUoub3V0cHV0TGVuLFouYmxvY2tMZW49Si5ibG9ja0xlbixaLmNyZWF0ZT0oUSk9PiQoUSksWn12YXIgRlE9VWludDMyQXJyYXkuZnJvbShbMTc3OTAzMzcwMywzMTQ0MTM0Mjc3LDEwMTM5MDQyNDIsMjc3MzQ4MDc2MiwxMzU5ODkzMTE5LDI2MDA4MjI5MjQsNTI4NzM0NjM1LDE1NDE0NTkyMjVdKTt2YXIgcCQ9QmlnSW50KDQyOTQ5NjcyOTUpLE5RPUJpZ0ludCgzMik7ZnVuY3Rpb24gaFooJCxaPSExKXtpZihaKXJldHVybntoOk51bWJlcigkJnAkKSxsOk51bWJlcigkPj5OUSZwJCl9O3JldHVybntoOk51bWJlcigkPj5OUSZwJCl8MCxsOk51bWJlcigkJnAkKXwwfX1mdW5jdGlvbiBIMCgkLFosSixRLFYpe3JldHVybiAkPSQrWitWfDAsUT1SJChRXiQsMTYpLEo9SitRfDAsWj1SJChaXkosMTIpLHthOiQsYjpaLGM6SixkOlF9fWZ1bmN0aW9uIE0wKCQsWixKLFEsVil7cmV0dXJuICQ9JCtaK1Z8MCxRPVIkKFFeJCw4KSxKPUorUXwwLFo9UiQoWl5KLDcpLHthOiQsYjpaLGM6SixkOlF9fWNsYXNzIHVaIGV4dGVuZHMgaVp7Y29uc3RydWN0b3IoJCxaKXtzdXBlcigpO3RoaXMuZmluaXNoZWQ9ITEsdGhpcy5kZXN0cm95ZWQ9ITEsdGhpcy5sZW5ndGg9MCx0aGlzLnBvcz0wLEYkKCQpLEYkKFopLHRoaXMuYmxvY2tMZW49JCx0aGlzLm91dHB1dExlbj1aLHRoaXMuYnVmZmVyPW5ldyBVaW50OEFycmF5KCQpLHRoaXMuYnVmZmVyMzI9dDAodGhpcy5idWZmZXIpfXVwZGF0ZSgkKXtOJCh0aGlzKSwkPSQkKCQpLGYwKCQpO2xldHtibG9ja0xlbjpaLGJ1ZmZlcjpKLGJ1ZmZlcjMyOlF9PXRoaXMsVj0kLmxlbmd0aCxZPSQuYnl0ZU9mZnNldCxYPSQuYnVmZmVyO2ZvcihsZXQgVz0wO1c8Vjspe2lmKHRoaXMucG9zPT09WillKFEpLHRoaXMuY29tcHJlc3MoUSwwLCExKSxlKFEpLHRoaXMucG9zPTA7bGV0IHo9TWF0aC5taW4oWi10aGlzLnBvcyxWLVcpLEs9WStXO2lmKHo9PT1aJiYhKEslNCkmJlcrejxWKXtsZXQgRj1uZXcgVWludDMyQXJyYXkoWCxLLE1hdGguZmxvb3IoKFYtVykvNCkpO2UoRik7Zm9yKGxldCBOPTA7VytaPFY7Tis9US5sZW5ndGgsVys9Wil0aGlzLmxlbmd0aCs9Wix0aGlzLmNvbXByZXNzKEYsTiwhMSk7ZShGKTtjb250aW51ZX1KLnNldCgkLnN1YmFycmF5KFcsVyt6KSx0aGlzLnBvcyksdGhpcy5wb3MrPXosdGhpcy5sZW5ndGgrPXosVys9en1yZXR1cm4gdGhpc31kaWdlc3RJbnRvKCQpe04kKHRoaXMpLGwkKCQsdGhpcyk7bGV0e3BvczpaLGJ1ZmZlcjMyOkp9PXRoaXM7dGhpcy5maW5pc2hlZD0hMCxlMCh0aGlzLmJ1ZmZlci5zdWJhcnJheShaKSksZShKKSx0aGlzLmNvbXByZXNzKEosMCwhMCksZShKKTtsZXQgUT10MCgkKTt0aGlzLmdldCgpLmZvckVhY2goKFYsWSk9PlFbWV09elEoVikpfWRpZ2VzdCgpe2xldHtidWZmZXI6JCxvdXRwdXRMZW46Wn09dGhpczt0aGlzLmRpZ2VzdEludG8oJCk7bGV0IEo9JC5zbGljZSgwLFopO3JldHVybiB0aGlzLmRlc3Ryb3koKSxKfV9jbG9uZUludG8oJCl7bGV0e2J1ZmZlcjpaLGxlbmd0aDpKLGZpbmlzaGVkOlEsZGVzdHJveWVkOlYsb3V0cHV0TGVuOlkscG9zOlh9PXRoaXM7cmV0dXJuICR8fCgkPW5ldyB0aGlzLmNvbnN0cnVjdG9yKHtka0xlbjpZfSkpLCQuc2V0KC4uLnRoaXMuZ2V0KCkpLCQuYnVmZmVyLnNldChaKSwkLmRlc3Ryb3llZD1WLCQuZmluaXNoZWQ9USwkLmxlbmd0aD1KLCQucG9zPVgsJC5vdXRwdXRMZW49WSwkfWNsb25lKCl7cmV0dXJuIHRoaXMuX2Nsb25lSW50bygpfX1mdW5jdGlvbiBsWigkLFosSixRLFYsWSxYLFcseixLLEYsTixVLE8scSxJLEgsUCxDLFQpe2xldCBNPTA7Zm9yKGxldCBBPTA7QTxRO0ErKykoe2E6VixiOnosYzpVLGQ6SH09SDAoVix6LFUsSCxKW1orJFtNKytdXSkpLHthOlYsYjp6LGM6VSxkOkh9PU0wKFYseixVLEgsSltaKyRbTSsrXV0pLHthOlksYjpLLGM6TyxkOlB9PUgwKFksSyxPLFAsSltaKyRbTSsrXV0pLHthOlksYjpLLGM6TyxkOlB9PU0wKFksSyxPLFAsSltaKyRbTSsrXV0pLHthOlgsYjpGLGM6cSxkOkN9PUgwKFgsRixxLEMsSltaKyRbTSsrXV0pLHthOlgsYjpGLGM6cSxkOkN9PU0wKFgsRixxLEMsSltaKyRbTSsrXV0pLHthOlcsYjpOLGM6SSxkOlR9PUgwKFcsTixJLFQsSltaKyRbTSsrXV0pLHthOlcsYjpOLGM6SSxkOlR9PU0wKFcsTixJLFQsSltaKyRbTSsrXV0pLHthOlYsYjpLLGM6cSxkOlR9PUgwKFYsSyxxLFQsSltaKyRbTSsrXV0pLHthOlYsYjpLLGM6cSxkOlR9PU0wKFYsSyxxLFQsSltaKyRbTSsrXV0pLHthOlksYjpGLGM6SSxkOkh9PUgwKFksRixJLEgsSltaKyRbTSsrXV0pLHthOlksYjpGLGM6SSxkOkh9PU0wKFksRixJLEgsSltaKyRbTSsrXV0pLHthOlgsYjpOLGM6VSxkOlB9PUgwKFgsTixVLFAsSltaKyRbTSsrXV0pLHthOlgsYjpOLGM6VSxkOlB9PU0wKFgsTixVLFAsSltaKyRbTSsrXV0pLHthOlcsYjp6LGM6TyxkOkN9PUgwKFcseixPLEMsSltaKyRbTSsrXV0pLHthOlcsYjp6LGM6TyxkOkN9PU0wKFcseixPLEMsSltaKyRbTSsrXV0pO3JldHVybnt2MDpWLHYxOlksdjI6WCx2MzpXLHY0OnosdjU6Syx2NjpGLHY3Ok4sdjg6VSx2OTpPLHYxMDpxLHYxMTpJLHYxMjpILHYxMzpQLHYxNDpDLHYxNTpUfX12YXIgTzA9e0NIVU5LX1NUQVJUOjEsQ0hVTktfRU5EOjIsUEFSRU5UOjQsUk9PVDo4LEtFWUVEX0hBU0g6MTYsREVSSVZFX0tFWV9DT05URVhUOjMyLERFUklWRV9LRVlfTUFURVJJQUw6NjR9LEMwPUZRLnNsaWNlKCksUlE9KCgpPT57bGV0ICQ9QXJyYXkuZnJvbSh7bGVuZ3RoOjE2fSwoUSxWKT0+ViksWj0oUSk9PlsyLDYsMywxMCw3LDAsNCwxMywxLDExLDEyLDUsOSwxNCwxNSw4XS5tYXAoKFYpPT5RW1ZdKSxKPVtdO2ZvcihsZXQgUT0wLFY9JDtRPDc7USsrLFY9WihWKSlKLnB1c2goLi4uVik7cmV0dXJuIFVpbnQ4QXJyYXkuZnJvbShKKX0pKCk7Y2xhc3MgcFogZXh0ZW5kcyB1Wntjb25zdHJ1Y3RvcigkPXt9LFo9MCl7c3VwZXIoNjQsJC5ka0xlbj09PXZvaWQgMD8zMjokLmRrTGVuKTt0aGlzLmNodW5rUG9zPTAsdGhpcy5jaHVua3NEb25lPTAsdGhpcy5mbGFncz0wLHRoaXMuc3RhY2s9W10sdGhpcy5wb3NPdXQ9MCx0aGlzLmJ1ZmZlck91dDMyPW5ldyBVaW50MzJBcnJheSgxNiksdGhpcy5jaHVua091dD0wLHRoaXMuZW5hYmxlWE9GPSEwO2xldHtrZXk6Sixjb250ZXh0OlF9PSQsVj1RIT09dm9pZCAwO2lmKEohPT12b2lkIDApe2lmKFYpdGhyb3cgRXJyb3IoJ09ubHkgImtleSIgb3IgImNvbnRleHQiIGNhbiBiZSBzcGVjaWZpZWQgYXQgc2FtZSB0aW1lJyk7bGV0IFk9JCQoSikuc2xpY2UoKTtmMChZLDMyKSx0aGlzLklWPXQwKFkpLGUodGhpcy5JViksdGhpcy5mbGFncz1afE8wLktFWUVEX0hBU0h9ZWxzZSBpZihWKXtsZXQgWT0kJChRKSxYPW5ldyBwWih7ZGtMZW46MzJ9LE8wLkRFUklWRV9LRVlfQ09OVEVYVCkudXBkYXRlKFkpLmRpZ2VzdCgpO3RoaXMuSVY9dDAoWCksZSh0aGlzLklWKSx0aGlzLmZsYWdzPVp8TzAuREVSSVZFX0tFWV9NQVRFUklBTH1lbHNlIHRoaXMuSVY9QzAuc2xpY2UoKSx0aGlzLmZsYWdzPVo7dGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCksdGhpcy5idWZmZXJPdXQ9WFEodGhpcy5idWZmZXJPdXQzMil9Z2V0KCl7cmV0dXJuW119c2V0KCl7fWIyQ29tcHJlc3MoJCxaLEosUT0wKXtsZXR7c3RhdGU6Vixwb3M6WX09dGhpcyx7aDpYLGw6V309aFooQmlnSW50KCQpLCEwKSx7djA6eix2MTpLLHYyOkYsdjM6Tix2NDpVLHY1Ok8sdjY6cSx2NzpJLHY4Okgsdjk6UCx2MTA6Qyx2MTE6VCx2MTI6TSx2MTM6QSx2MTQ6eCx2MTU6bX09bFooUlEsUSxKLDcsVlswXSxWWzFdLFZbMl0sVlszXSxWWzRdLFZbNV0sVls2XSxWWzddLEMwWzBdLEMwWzFdLEMwWzJdLEMwWzNdLFgsVyxZLFopO1ZbMF09el5ILFZbMV09S15QLFZbMl09Rl5DLFZbM109Tl5ULFZbNF09VV5NLFZbNV09T15BLFZbNl09cV54LFZbN109SV5tfWNvbXByZXNzKCQsWj0wLEo9ITEpe2xldCBRPXRoaXMuZmxhZ3M7aWYoIXRoaXMuY2h1bmtQb3MpUXw9TzAuQ0hVTktfU1RBUlQ7aWYodGhpcy5jaHVua1Bvcz09PTE1fHxKKVF8PU8wLkNIVU5LX0VORDtpZighSil0aGlzLnBvcz10aGlzLmJsb2NrTGVuO2lmKHRoaXMuYjJDb21wcmVzcyh0aGlzLmNodW5rc0RvbmUsUSwkLFopLHRoaXMuY2h1bmtQb3MrPTEsdGhpcy5jaHVua1Bvcz09PTE2fHxKKXtsZXQgVj10aGlzLnN0YXRlO3RoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpO2ZvcihsZXQgWSxYPXRoaXMuY2h1bmtzRG9uZSsxO0p8fCEoWCYxKTtYPj49MSl7aWYoIShZPXRoaXMuc3RhY2sucG9wKCkpKWJyZWFrO3RoaXMuYnVmZmVyMzIuc2V0KFksMCksdGhpcy5idWZmZXIzMi5zZXQoViw4KSx0aGlzLnBvcz10aGlzLmJsb2NrTGVuLHRoaXMuYjJDb21wcmVzcygwLHRoaXMuZmxhZ3N8TzAuUEFSRU5ULHRoaXMuYnVmZmVyMzIsMCksVj10aGlzLnN0YXRlLHRoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpfXRoaXMuY2h1bmtzRG9uZSsrLHRoaXMuY2h1bmtQb3M9MCx0aGlzLnN0YWNrLnB1c2goVil9dGhpcy5wb3M9MH1fY2xvbmVJbnRvKCQpeyQ9c3VwZXIuX2Nsb25lSW50bygkKTtsZXR7SVY6WixmbGFnczpKLHN0YXRlOlEsY2h1bmtQb3M6Vixwb3NPdXQ6WSxjaHVua091dDpYLHN0YWNrOlcsY2h1bmtzRG9uZTp6fT10aGlzO3JldHVybiAkLnN0YXRlLnNldChRLnNsaWNlKCkpLCQuc3RhY2s9Vy5tYXAoKEspPT5VaW50MzJBcnJheS5mcm9tKEspKSwkLklWLnNldChaKSwkLmZsYWdzPUosJC5jaHVua1Bvcz1WLCQuY2h1bmtzRG9uZT16LCQucG9zT3V0PVksJC5jaHVua091dD1YLCQuZW5hYmxlWE9GPXRoaXMuZW5hYmxlWE9GLCQuYnVmZmVyT3V0MzIuc2V0KHRoaXMuYnVmZmVyT3V0MzIpLCR9ZGVzdHJveSgpe3RoaXMuZGVzdHJveWVkPSEwLGUwKHRoaXMuc3RhdGUsdGhpcy5idWZmZXIzMix0aGlzLklWLHRoaXMuYnVmZmVyT3V0MzIpLGUwKC4uLnRoaXMuc3RhY2spfWIyQ29tcHJlc3NPdXQoKXtsZXR7c3RhdGU6JCxwb3M6WixmbGFnczpKLGJ1ZmZlcjMyOlEsYnVmZmVyT3V0MzI6Vn09dGhpcyx7aDpZLGw6WH09aFooQmlnSW50KHRoaXMuY2h1bmtPdXQrKykpO2UoUSk7bGV0e3YwOlcsdjE6eix2MjpLLHYzOkYsdjQ6Tix2NTpVLHY2Ok8sdjc6cSx2ODpJLHY5OkgsdjEwOlAsdjExOkMsdjEyOlQsdjEzOk0sdjE0OkEsdjE1Onh9PWxaKFJRLDAsUSw3LCRbMF0sJFsxXSwkWzJdLCRbM10sJFs0XSwkWzVdLCRbNl0sJFs3XSxDMFswXSxDMFsxXSxDMFsyXSxDMFszXSxYLFksWixKKTtWWzBdPVdeSSxWWzFdPXpeSCxWWzJdPUteUCxWWzNdPUZeQyxWWzRdPU5eVCxWWzVdPVVeTSxWWzZdPU9eQSxWWzddPXFeeCxWWzhdPSRbMF1eSSxWWzldPSRbMV1eSCxWWzEwXT0kWzJdXlAsVlsxMV09JFszXV5DLFZbMTJdPSRbNF1eVCxWWzEzXT0kWzVdXk0sVlsxNF09JFs2XV5BLFZbMTVdPSRbN11eeCxlKFEpLGUoViksdGhpcy5wb3NPdXQ9MH1maW5pc2goKXtpZih0aGlzLmZpbmlzaGVkKXJldHVybjt0aGlzLmZpbmlzaGVkPSEwLGUwKHRoaXMuYnVmZmVyLnN1YmFycmF5KHRoaXMucG9zKSk7bGV0ICQ9dGhpcy5mbGFnc3xPMC5ST09UO2lmKHRoaXMuc3RhY2subGVuZ3RoKSR8PU8wLlBBUkVOVCxlKHRoaXMuYnVmZmVyMzIpLHRoaXMuY29tcHJlc3ModGhpcy5idWZmZXIzMiwwLCEwKSxlKHRoaXMuYnVmZmVyMzIpLHRoaXMuY2h1bmtzRG9uZT0wLHRoaXMucG9zPXRoaXMuYmxvY2tMZW47ZWxzZSAkfD0oIXRoaXMuY2h1bmtQb3M/TzAuQ0hVTktfU1RBUlQ6MCl8TzAuQ0hVTktfRU5EO3RoaXMuZmxhZ3M9JCx0aGlzLmIyQ29tcHJlc3NPdXQoKX13cml0ZUludG8oJCl7TiQodGhpcywhMSksZjAoJCksdGhpcy5maW5pc2goKTtsZXR7YmxvY2tMZW46WixidWZmZXJPdXQ6Sn09dGhpcztmb3IobGV0IFE9MCxWPSQubGVuZ3RoO1E8Vjspe2lmKHRoaXMucG9zT3V0Pj1aKXRoaXMuYjJDb21wcmVzc091dCgpO2xldCBZPU1hdGgubWluKFotdGhpcy5wb3NPdXQsVi1RKTskLnNldChKLnN1YmFycmF5KHRoaXMucG9zT3V0LHRoaXMucG9zT3V0K1kpLFEpLHRoaXMucG9zT3V0Kz1ZLFErPVl9cmV0dXJuICR9eG9mSW50bygkKXtpZighdGhpcy5lbmFibGVYT0YpdGhyb3cgRXJyb3IoIlhPRiBpcyBub3QgcG9zc2libGUgYWZ0ZXIgZGlnZXN0IGNhbGwiKTtyZXR1cm4gdGhpcy53cml0ZUludG8oJCl9eG9mKCQpe3JldHVybiBGJCgkKSx0aGlzLnhvZkludG8obmV3IFVpbnQ4QXJyYXkoJCkpfWRpZ2VzdEludG8oJCl7aWYobCQoJCx0aGlzKSx0aGlzLmZpbmlzaGVkKXRocm93IEVycm9yKCJkaWdlc3QoKSB3YXMgYWxyZWFkeSBjYWxsZWQiKTtyZXR1cm4gdGhpcy5lbmFibGVYT0Y9ITEsdGhpcy53cml0ZUludG8oJCksdGhpcy5kZXN0cm95KCksJH1kaWdlc3QoKXtyZXR1cm4gdGhpcy5kaWdlc3RJbnRvKG5ldyBVaW50OEFycmF5KHRoaXMub3V0cHV0TGVuKSl9fXZhciBVUT1LUSgoJCk9Pm5ldyBwWigkKSk7dmFyIG5aPW5ldyBVaW50OEFycmF5KFs0OCw0NiwyLDEsMCw0OCw1LDYsMyw0MywxMDEsMTEyLDQsMzQsNCwzMl0pO2Z1bmN0aW9uIE9RKCQpe2xldCBaPW5ldyBVaW50OEFycmF5KG5aLmxlbmd0aCszMik7cmV0dXJuIFouc2V0KG5aKSxaLnNldCgkLnN1YmFycmF5KDAsMzIpLG5aLmxlbmd0aCksWn1mdW5jdGlvbiBxUSgkKXtyZXR1cm4gdHlwZW9mICQ9PT0ic3RyaW5nIj9uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCk6JH1mdW5jdGlvbiBaJCgkKXtsZXQgWj1uZXcgQXJyYXlCdWZmZXIoJC5ieXRlTGVuZ3RoKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWikuc2V0KCQpLFp9Y2xhc3MgY1p7dmVyaWZ5S2V5cz1uZXcgTWFwO3NpZ25LZXlzPW5ldyBNYXA7YXN5bmMgZ2VuUmFuZG9tQnl0ZXMoJCl7cmV0dXJuIGgkKCQpfWFzeW5jIGdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKXtyZXR1cm4gaCQoMzIpfWFzeW5jIGVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoJCxaKXtsZXQgSj1oJCgyNCksVj15WihaLEopLmVuY3J5cHQoJCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KFsuLi5KLC4uLlZdKX1hc3luYyBkZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKCQsWil7bGV0IEo9JC5zbGljZSgwLDI0KSxRPSQuc2xpY2UoMjQpO3JldHVybiB5WihaLEopLmRlY3J5cHQoUSl9YXN5bmMgZGVyaXZlRWQyNTUxOUtleVBhaXIoJCl7bGV0IFo9JCxKPU9RKFopLFE9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLFokKEopLHtuYW1lOiJFZDI1NTE5In0sITAsWyJzaWduIl0pLFY9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgiandrIixRKTtpZih0eXBlb2YgVi54IT09InN0cmluZyIpdGhyb3cgRXJyb3IoIkVkMjU1MTkgSldLIG1pc3NpbmcgeCIpO2xldCBZPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoImp3ayIse2t0eToiT0tQIixjcnY6IkVkMjU1MTkiLHg6Vi54fSx7bmFtZToiRWQyNTUxOSJ9LCEwLFsidmVyaWZ5Il0pLFg9bmV3IFVpbnQ4QXJyYXkoYXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgicmF3IixZKSksVz1uZXcgVWludDhBcnJheSg2NCk7cmV0dXJuIFcuc2V0KFosMCksVy5zZXQoWCwzMiksdGhpcy5zaWduS2V5cy5zZXQoTjAoWiksUSksdGhpcy52ZXJpZnlLZXlzLnNldChOMChYKSxZKSx7a2V5VHlwZToiZWQyNTUxOSIscHJpdmF0ZUtleTpXLHB1YmxpY0tleTpYfX1hc3luYyBpbXBvcnRTaWduS2V5KCQpe2xldCBaPSQuc3ViYXJyYXkoMCwzMiksSj1OMChaKSxRPXRoaXMuc2lnbktleXMuZ2V0KEopO2lmKFEpcmV0dXJuIFE7bGV0IFY9T1EoWiksWT1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsWiQoVikse25hbWU6IkVkMjU1MTkifSwhMSxbInNpZ24iXSk7cmV0dXJuIHRoaXMuc2lnbktleXMuc2V0KEosWSksWX1hc3luYyBpbXBvcnRWZXJpZnlLZXkoJCl7bGV0IFo9TjAoJCksSj10aGlzLnZlcmlmeUtleXMuZ2V0KFopO2lmKEopcmV0dXJuIEo7bGV0IFE9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicmF3IixaJCgkKSx7bmFtZToiRWQyNTUxOSJ9LCExLFsidmVyaWZ5Il0pO3JldHVybiB0aGlzLnZlcmlmeUtleXMuc2V0KFosUSksUX1hc3luYyBzaWduRWQyNTUxOSgkLFope2xldCBKPXFRKCQpLFE9YXdhaXQgdGhpcy5pbXBvcnRTaWduS2V5KFopLFY9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLnNpZ24oe25hbWU6IkVkMjU1MTkifSxRLFokKEopKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoVil9YXN5bmMgY2hlY2tTaWdFZDI1NTE5KCQsWixKKXtsZXQgUT1xUShaKTt0cnl7bGV0IFY9YXdhaXQgdGhpcy5pbXBvcnRWZXJpZnlLZXkoSik7cmV0dXJuIGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS52ZXJpZnkoe25hbWU6IkVkMjU1MTkifSxWLFokKCQpLFokKFEpKX1jYXRjaHtyZXR1cm4hMX19YXN5bmMgYmxha2UzKCQpe3JldHVybiBVUSgkKX19dmFyIGJWPW5ldyBjWixVJD1iVjt2YXIgazA9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVWYXJTdHJpbmcoWi5oYW5kbGUpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJTdHJpbmcoWi5sYWJlbCk7aWYoUSE9PTApcmV0dXJuIFE7cmV0dXJuICQud3JpdGVWYXJJbnQoWi5pZHg/PzApfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFyU3RyaW5nKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsVl09JC5yZWFkVmFyU3RyaW5nKCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1ksWF09JC5yZWFkVmFySW50KCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIFIoe2hhbmRsZTpaLGxhYmVsOlEsaWR4Oll9KX19O3ZhciBuJD0xLGRaPXtlbmNvZGUoJCxaKXtpZihaLnYhPT1uJClyZXR1cm4gMTA7bGV0WyxKXT10KFoubWFzdGVyU2VlZCk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZVZhckludChaLnYpO2lmKFEhPT0wKXJldHVybiBROyQud3JpdGVCeXRlcyhaLm1hc3RlclNlZWQpO2xldCBWPSQud3JpdGVWYXJJbnQoWi5ob3N0cy5sZW5ndGgpO2lmKFYhPT0wKXJldHVybiBWO2ZvcihsZXQgWSBvZiBaLmhvc3RzKXtsZXQgWD0kLndyaXRlU3RydWN0KGswLFkpO2lmKFghPT0wKXJldHVybiBYfXJldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7aWYoWiE9PW4kKXJldHVybiBHKDE0KTtsZXRbUSxWXT0kLnJlYWRCeXRlcyhSMCk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1ksWF09dChRKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbVyx6XT0kLnJlYWRWYXJJbnQoKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwfHxXPDApcmV0dXJuIEcoMTApO2xldCBLPVtdO2ZvcihsZXQgRj0wO0Y8VztGKyspe2xldFtOLFVdPSQucmVhZFN0cnVjdChrMCk7aWYoVSE9PTApcmV0dXJuIEcoVSk7aWYoTj09PXZvaWQgMClyZXR1cm4gRygxNCk7Sy5wdXNoKE4pfXJldHVybiBSKHt2Om4kLG1hc3RlclNlZWQ6WSxob3N0czpLfSl9fTtmdW5jdGlvbiBJUSgkLFope2xldFtKLFFdPXQoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxMCk7bGV0W1YsWV09dChKLnNsaWNlKCkpO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMTApO3JldHVybiBSKHt2Om4kLG1hc3RlclNlZWQ6Vixob3N0czpaLm1hcCgoWCk9Pih7aGFuZGxlOlguaGFuZGxlLGxhYmVsOlgubGFiZWwsaWR4OlguaWR4Pz8wfSkpfSl9dmFyIHJaPXtlbmNvZGUoJCxaKXtsZXRbLEpdPXQoWi5tYXN0ZXJTZWVkKTtpZihKIT09MClyZXR1cm4gSjskLndyaXRlQnl0ZXMoWi5tYXN0ZXJTZWVkKTtsZXQgUT0kLndyaXRlVmFySW50KFouaG9zdHMubGVuZ3RoKTtpZihRIT09MClyZXR1cm4gUTtmb3IobGV0IFYgb2YgWi5ob3N0cyl7bGV0IFk9JC53cml0ZVN0cnVjdChrMCxWKTtpZihZIT09MClyZXR1cm4gWX1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZEJ5dGVzKFIwKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbUSxWXT10KFopO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldFtZLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFk9PT12b2lkIDB8fFk8MClyZXR1cm4gRygxMCk7bGV0IFc9W107Zm9yKGxldCB6PTA7ejxZO3orKyl7bGV0W0ssRl09JC5yZWFkU3RydWN0KGswKTtpZihGIT09MClyZXR1cm4gRyhGKTtpZihLPT09dm9pZCAwKXJldHVybiBHKDE0KTtXLnB1c2goSyl9cmV0dXJuIFIoe21hc3RlclNlZWQ6USxob3N0czpXfSl9fTtmdW5jdGlvbiBQMCgkKXtsZXQgWj1uZXcgVWludDhBcnJheSgkKTtpZigkPjApY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhaKTtyZXR1cm4gWn12YXIgQjA9MzIseVY9LTcsaVY9LTgsaFY9LTI1NyxjJD1be3R5cGU6InB1YmxpYy1rZXkiLGFsZzp5Vn0se3R5cGU6InB1YmxpYy1rZXkiLGFsZzppVn0se3R5cGU6InB1YmxpYy1rZXkiLGFsZzpoVn1dO2Z1bmN0aW9uIHVWKCQpe3JldHVybiAkLnRyaW0oKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1wuJC8sIiIpfHwibG9jYWxob3N0In1mdW5jdGlvbiBFMCgkKXtsZXQgWj1uZXcgVWludDhBcnJheSgkLmJ5dGVMZW5ndGgpO3JldHVybiBaLnNldCgkKSxafWZ1bmN0aW9uIG0wKCQpe2lmKCQ/LnJwSWQhPT12b2lkIDApcmV0dXJuIFIoJC5ycElkKTtpZih0eXBlb2YgbG9jYXRpb24+InUiKXJldHVybiBHKDkpO3JldHVybiBSKHVWKGxvY2F0aW9uLmhvc3RuYW1lKSl9ZnVuY3Rpb24gZzAoKXtpZih0eXBlb2YgbmF2aWdhdG9yPiJ1Inx8IW5hdmlnYXRvci5jcmVkZW50aWFsc3x8dHlwZW9mIFB1YmxpY0tleUNyZWRlbnRpYWw+InUiKXJldHVybiAyNDtyZXR1cm4gMH1mdW5jdGlvbiBTMCgkKXtpZigkPT09bnVsbHx8JC50eXBlIT09InB1YmxpYy1rZXkifHwhKCJyYXdJZCJpbiAkKXx8dHlwZW9mICQuZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cyE9PSJmdW5jdGlvbiIpcmV0dXJuIEcoMjcpO3JldHVybiBSKCQpfWFzeW5jIGZ1bmN0aW9uIEhRKCQpe2xldCBaPWcwKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W0osUV09bTAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgVj0kPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtc2VlZCIsWT17cmVzaWRlbnRLZXk6InJlcXVpcmVkIixyZXF1aXJlUmVzaWRlbnRLZXk6ITAsdXNlclZlcmlmaWNhdGlvbjoicmVxdWlyZWQifTtpZigkPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCE9PXZvaWQgMClZLmF1dGhlbnRpY2F0b3JBdHRhY2htZW50PSQuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ7bGV0IFg9e2xhcmdlQmxvYjp7c3VwcG9ydDoicmVxdWlyZWQifX0sVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpQMChCMCkscnA6e2lkOkosbmFtZTokPy5ycE5hbWU/PyJESVBMT01BVElDIn0sdXNlcjp7aWQ6UDAoMTYpLG5hbWU6VixkaXNwbGF5TmFtZTpWfSxwdWJLZXlDcmVkUGFyYW1zOmMkLGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246WSxleHRlbnNpb25zOlh9fSl9Y2F0Y2h7cmV0dXJuIEcoMjQpfWxldFt6LEtdPVMwKFcpO2lmKEshPT0wKXJldHVybiBHKEspO2lmKHo9PT12b2lkIDApcmV0dXJuIEcoMjcpO2lmKHouZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLmxhcmdlQmxvYj8uc3VwcG9ydGVkIT09ITApcmV0dXJuIEcoMjQpO3JldHVybiBSKG5ldyBVaW50OEFycmF5KHoucmF3SWQpKX1hc3luYyBmdW5jdGlvbiBvWigkLFosSil7bGV0IFE9ZzAoKTtpZihRIT09MClyZXR1cm4gUTtsZXRbVixZXT1tMChKKTtpZihZIT09MClyZXR1cm4gWTtpZihWPT09dm9pZCAwKXJldHVybiA5O2xldCBYPXtsYXJnZUJsb2I6e3dyaXRlOkUwKFopfX0sVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpQMChCMCkscnBJZDpWLGFsbG93Q3JlZGVudGlhbHM6W3t0eXBlOiJwdWJsaWMta2V5IixpZDpFMCgkKX1dLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixleHRlbnNpb25zOlh9fSl9Y2F0Y2h7cmV0dXJuIDI0fWxldFt6LEtdPVMwKFcpO2lmKEshPT0wKXJldHVybiBLO2lmKHo9PT12b2lkIDApcmV0dXJuIDI3O2lmKHouZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLmxhcmdlQmxvYj8ud3JpdHRlbiE9PSEwKXJldHVybiAyNDtyZXR1cm4gMH1hc3luYyBmdW5jdGlvbiBNUSgkLFope2xldCBKPWcwKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsVl09bTAoWik7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoUT09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgWT17bGFyZ2VCbG9iOntyZWFkOiEwfX0sWDt0cnl7bGV0IE49e2NoYWxsZW5nZTpQMChCMCkscnBJZDpRLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixleHRlbnNpb25zOll9O2lmKCQhPT12b2lkIDApTi5hbGxvd0NyZWRlbnRpYWxzPVt7dHlwZToicHVibGljLWtleSIsaWQ6RTAoJCl9XTtYPWF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5nZXQoe3B1YmxpY0tleTpOfSl9Y2F0Y2h7cmV0dXJuIEcoMjQpfWxldFtXLHpdPVMwKFgpO2lmKHohPT0wKXJldHVybiBHKHopO2lmKFc9PT12b2lkIDApcmV0dXJuIEcoMjcpO2xldCBGPVcuZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLmxhcmdlQmxvYj8uYmxvYjtpZihGPT09dm9pZCAwKXJldHVybiBHKDcpO3JldHVybiBSKHtibG9iOm5ldyBVaW50OEFycmF5KEYpLGNyZWRJZDpuZXcgVWludDhBcnJheShXLnJhd0lkKX0pfXZhciBkJD1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMucHJmLnYxIiksYVo9MzI7YXN5bmMgZnVuY3Rpb24gQ1EoJCl7bGV0IFo9ZzAoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbSixRXT1tMCgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDkpO2xldCBWPSQ/LnVzZXJOYW1lPz8iZGlwbG9tYXRpYy1wcmYiLFk9e3Jlc2lkZW50S2V5OiJyZXF1aXJlZCIscmVxdWlyZVJlc2lkZW50S2V5OiEwLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixhdXRoZW50aWNhdG9yQXR0YWNobWVudDokPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudD8/InBsYXRmb3JtIn0sWDt0cnl7WD1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpQMChCMCkscnA6e2lkOkosbmFtZTokPy5ycE5hbWU/PyJESVBMT01BVElDIn0sdXNlcjp7aWQ6UDAoMTYpLG5hbWU6VixkaXNwbGF5TmFtZTpWfSxwdWJLZXlDcmVkUGFyYW1zOmMkLGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246WSxleHRlbnNpb25zOntwcmY6e319fX0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbVyx6XT1TMChYKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgSz1XLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKTtyZXR1cm4gUih7Y3JlZElkOm5ldyBVaW50OEFycmF5KFcucmF3SWQpLHByZkVuYWJsZWQ6Sy5wcmY/LmVuYWJsZWQ9PT0hMH0pfWFzeW5jIGZ1bmN0aW9uIE8kKCQpe2xldCBaPWcwKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W0osUV09bTAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgVj0kPy5zYWx0Pz9kJCxZPUUwKFYpLFg9e2NoYWxsZW5nZTpQMChCMCkscnBJZDpKLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixleHRlbnNpb25zOntwcmY6e2V2YWw6e2ZpcnN0Oll9fX19O2lmKCQ/LmNyZWRJZCE9PXZvaWQgMClYLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOiJwdWJsaWMta2V5IixpZDpFMCgkLmNyZWRJZCl9XTtsZXQgVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6WH0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbeixLXT1TMChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgRj16LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5wcmY/LnJlc3VsdHM7aWYoRj8uZmlyc3Q9PT12b2lkIDApcmV0dXJuIEcoNyk7bGV0IE49Ri5maXJzdCxVPU4gaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcj9uZXcgVWludDhBcnJheShOKTpuZXcgVWludDhBcnJheShOLmJ1ZmZlcixOLmJ5dGVPZmZzZXQsTi5ieXRlTGVuZ3RoKSxPPVUuYnl0ZUxlbmd0aD49YVo/VS5zbGljZSgwLGFaKTpVO2lmKE8uYnl0ZUxlbmd0aCE9PWFaKXJldHVybiBHKDI3KTtyZXR1cm4gUih7cHJmOk8sY3JlZElkOm5ldyBVaW50OEFycmF5KHoucmF3SWQpfSl9dmFyIHIkPSIiO3ZhciBvJDtmdW5jdGlvbiBwVigpe2lmKHR5cGVvZiByJCE9PSJzdHJpbmcifHxyJC5sZW5ndGg9PT0wKXRocm93IEVycm9yKCJbRElQTE9NQVRJQ10gd29ya2VyIHNvdXJjZSBub3QgZW1iZWRkZWQ7IHJ1biBwa2cgYnVpbGQgYmVmb3JlIHNwYXduIik7cmV0dXJuIGF0b2IociQpfWZ1bmN0aW9uIG5WKCl7aWYobyQhPT12b2lkIDApcmV0dXJuIG8kO2xldCAkPW5ldyBCbG9iKFtwVigpXSx7dHlwZToidGV4dC9qYXZhc2NyaXB0In0pO3JldHVybiBvJD1VUkwuY3JlYXRlT2JqZWN0VVJMKCQpLG8kfWZ1bmN0aW9uIFBRKCl7aWYodHlwZW9mIFdvcmtlcj4idSIpdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSBXb3JrZXIgQVBJIHVuYXZhaWxhYmxlOyBjYW5ub3Qgc3Bhd24gc3luYyB3b3JrZXIiKTtyZXR1cm4gbmV3IFdvcmtlcihuVigpLHt0eXBlOiJtb2R1bGUifSl9dmFyIGNWPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgiZGlwbG9tYXRpYy53cmFwLnYxIiksZFY9MzIsclY9MTY7Y2xhc3MgJDB7I0o7IyQ7Y29uc3RydWN0b3IoJCxaKXt0aGlzLiNKPSQsdGhpcy4jJD1afXN0YXRpYyBhc3luYyBmcm9tUmFuZG9tKCQpe2xldCBaPWF3YWl0ICQuZ2VuMjU2Qml0U2VjdXJlUmFuZG9tU2VlZCgpLFtKLFFdPXQoWik7aWYoUSE9PTB8fEo9PT12b2lkIDApdGhyb3cgRXJyb3IoYGVuY2xhdmU6IGludmFsaWQgcmFuZG9tIHNlZWQgKCR7UX0pYCk7cmV0dXJuIG5ldyAkMChKLCQpfXN0YXRpYyBmcm9tQnl0ZXMoJCxaKXtsZXRbSixRXT10KFopO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtWLFldPXQoSi5zbGljZSgpKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEwKTtyZXR1cm4gUihuZXcgJDAoViwkKSl9YXN5bmMgc2VhbFdpdGhQYXNza2V5KCQpe2xldCBaPSQ/LnNhbHQ/P2QkLEo9JD8uY3JlZElkO2lmKEo9PT12b2lkIDAmJiQ/LmNyZWF0ZUNyZWRJZk5lZWRlZD09PSEwKXtsZXRbWSxYXT1hd2FpdCBDUSh7cnBJZDokPy5ycElkLHJwTmFtZTokPy5ycE5hbWUsdXNlck5hbWU6JD8udXNlck5hbWU/PyJkaXBsb21hdGljLXByZiJ9KTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDI0KTtpZighWS5wcmZFbmFibGVkKXJldHVybiBHKDI0KTtKPVkuY3JlZElkfWxldFtRLFZdPWF3YWl0IE8kKHtycElkOiQ/LnJwSWQscnBOYW1lOiQ/LnJwTmFtZSxjcmVkSWQ6SixzYWx0Olp9KTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbWSxYXT1hd2FpdCB0aGlzLiNaKFEucHJmKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gUih7c2VhbGVkTWFzdGVyOlksc2FsdDpaLnNsaWNlKCksY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXN0YXRpYyBhc3luYyB1bnNlYWxXaXRoUGFzc2tleSgkLFosSil7bGV0W1EsVl09YXdhaXQgTyQoe3JwSWQ6Si5ycElkLHJwTmFtZTpKLnJwTmFtZSxjcmVkSWQ6Si5jcmVkSWQsc2FsdDpKLnNhbHR9KTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtyZXR1cm4gYXdhaXQgJDAuI1YoJCxaLFEucHJmKX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fWFzeW5jIHBlcnNpc3RUb0xhcmdlQmxvYigkPVtdLFope2xldCBKPVo/LmNyZWRJZDtpZihKPT09dm9pZCAwKXtsZXRbWSxYXT1hd2FpdCBIUShaKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDI0KTtKPVl9bGV0W1EsVl09dGhpcy4jUSgkKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFk9YXdhaXQgb1ooSixRLFopO2lmKFkhPT0wKXJldHVybiBHKFkpO3JldHVybiBSKEopfWZpbmFsbHl7US5maWxsKDApfX1zdGF0aWMgYXN5bmMgZnJvbUxhcmdlQmxvYigkLFope2xldFtKLFFdPWF3YWl0IE1RKFo/LmNyZWRJZCxaKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtyZXR1cm4gJDAuI1coJCxKLmJsb2IsSi5jcmVkSWQpfWZpbmFsbHl7Si5ibG9iLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBjbGVhckxhcmdlQmxvYigkLFope3JldHVybiBvWigkLG5ldyBVaW50OEFycmF5KFIwKSxaKX1hc3luYyBzZWFsUGFpclBhY2thZ2VCb2R5KCQsWil7bGV0IEo9Wj8uc2FsdD8/ZCQsW1EsVl09YXdhaXQgTyQoe3JwSWQ6Wj8ucnBJZCxycE5hbWU6Wj8ucnBOYW1lLGNyZWRJZDpaPy5jcmVkSWQsc2FsdDpKfSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoUT09PXZvaWQgMClyZXR1cm4gRyg3KTt0cnl7bGV0W1ksWF09YXdhaXQgYSQodGhpcy4jJCxRLnByZik7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoWT09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0W1csel09dCh0aGlzLiNKLnNsaWNlKCkpO2lmKHohPT0wKXJldHVybiBHKHopO2lmKFc9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldCBLPXttYXN0ZXJTZWVkOlcsaG9zdHM6JC5tYXAoKHEpPT4oe2hhbmRsZTpxLmhhbmRsZSxsYWJlbDpxLmxhYmVsLGlkeDpxLmlkeD8/MH0pKX0sRj1uZXcgUyxOPUYud3JpdGVTdHJ1Y3QoclosSyk7aWYoTiE9PTApcmV0dXJuIFcuZmlsbCgwKSxHKE4pO2xldCBVPUYucmVzdWx0KCk7Vy5maWxsKDApO2xldCBPO3RyeXtPPWF3YWl0IHRoaXMuIyQuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChVLFkpfWNhdGNoe3JldHVybiBVLmZpbGwoMCksRygxMil9cmV0dXJuIFUuZmlsbCgwKSxSKHtib2R5Ok8sc2FsdDpKLnNsaWNlKCksY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBvcGVuUGFpclBhY2thZ2VCb2R5KCQsWixKKXtsZXRbUSxWXT1hd2FpdCBPJCh7cnBJZDpKLnJwSWQscnBOYW1lOkoucnBOYW1lLGNyZWRJZDpKLmNyZWRJZCxzYWx0Okouc2FsdH0pO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoNyk7dHJ5e2xldFtZLFhdPWF3YWl0IGEkKCQsUS5wcmYpO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFk9PT12b2lkIDApcmV0dXJuIEcoMTIpO2xldCBXO3RyeXtXPWF3YWl0ICQuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChaLFkpfWNhdGNoe3JldHVybiBHKDIwKX1sZXQgej1uZXcgZyhXKSxbSyxGXT16LnJlYWRTdHJ1Y3QoclopO2lmKFcuZmlsbCgwKSxGIT09MClyZXR1cm4gRyhGKTtpZihLPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbTixVXT0kMC5mcm9tQnl0ZXMoJCxLLm1hc3RlclNlZWQpO2lmKEsubWFzdGVyU2VlZC5maWxsKDApLFUhPT0wKXJldHVybiBHKFUpO2lmKE49PT12b2lkIDApcmV0dXJuIEcoMTIpO2xldFtPLHFdPWF3YWl0IE4uI1ooUS5wcmYpO2lmKHEhPT0wKXJldHVybiBHKHEpO2lmKE89PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBSKHtlbmNsYXZlOk4saG9zdHM6Sy5ob3N0cy5tYXAoKEkpPT4oey4uLkl9KSksc2VhbGVkTWFzdGVyOk8sY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXNwYXduU3luY1dvcmtlcigkKXtsZXQgWj1QUSgpLEo9dGhpcy4jSi5zbGljZSgpO3JldHVybiBaLnBvc3RNZXNzYWdlKHtpZDokLmlkLG9wOiJzZXRTZWVkIixzZWVkOkoscGVyc2lzdDokLnBlcnNpc3R9LFtKLmJ1ZmZlcl0pLFp9ZGVyaXZlQ2lwaGVyKCQsWil7bGV0IEo9JC5zbGljZSgpLFE9KFgpPT50aGlzLiNHKEosWCksVj0oWCk9PnRoaXMuI3ooSixYKTtyZXR1cm57ZW5jcnlwdDpPYmplY3QuZnJlZXplKHtlbmNyeXB0OlF9KSxkZWNyeXB0Ok9iamVjdC5mcmVlemUoe2RlY3J5cHQ6Vn0pLGJvdGg6T2JqZWN0LmZyZWV6ZSh7ZW5jcnlwdDpRLGRlY3J5cHQ6Vn0pfVtaXX1hc3luYyBkZXJpdmVJZGVudGl0eSgkLFo9MCl7bGV0IEo9JCxRPVosVj1hd2FpdCB0aGlzLiNYKEosUSk7cmV0dXJuIE9iamVjdC5mcmVlemUoe3B1YmxpY0tleTpWLnB1YmxpY0tleSxzaWduOihZKT0+dGhpcy4jRihKLFEsWSksa2RtRm9yOihZKT0+dGhpcy4jTihKLFEsWSl9KX1hc3luYyNaKCQpe2xldFtaLEpdPWF3YWl0IGEkKHRoaXMuIyQsJCk7aWYoSiE9PTApcmV0dXJuIEcoSik7aWYoWj09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBRPWF3YWl0IHRoaXMuIyQuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCh0aGlzLiNKLFopO3JldHVybiBqMChRKX1jYXRjaHtyZXR1cm4gRygxMil9fXN0YXRpYyBhc3luYyNWKCQsWixKKXtsZXRbLFFdPWowKFopO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldFtWLFldPWF3YWl0IGEkKCQsSik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBYPWF3YWl0ICQuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChaLFYpO3JldHVybiAkMC5mcm9tQnl0ZXMoJCxYKX1jYXRjaHtyZXR1cm4gRygyMCl9fSNRKCQpe2xldFtaLEpdPXQodGhpcy4jSi5zbGljZSgpKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDEwKTtsZXRbUSxWXT1JUShaLCQpO2lmKFYhPT0wKXJldHVybiBaLmZpbGwoMCksRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBaLmZpbGwoMCksRygxMik7Wi5maWxsKDApO2xldCBZPW5ldyBTLFg9WS53cml0ZVN0cnVjdChkWixRKTtpZihRLm1hc3RlclNlZWQuZmlsbCgwKSxYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gUihZLnJlc3VsdCgpKX1zdGF0aWMjVygkLFosSil7aWYoWi5ieXRlTGVuZ3RoPT09MHx8Wi5ldmVyeSgoeik9Pno9PT0wKSlyZXR1cm4gRygyMik7aWYoWi5ieXRlTGVuZ3RoPT09UjApe2xldFt6LEtdPSQwLmZyb21CeXRlcygkLFopO2lmKEshPT0wKXJldHVybiBHKEspO2lmKHo9PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBSKHtlbmNsYXZlOnosaG9zdHM6W10sY3JlZElkOkp9KX1sZXQgUT1uZXcgZyhaKSxbVixZXT1RLnJlYWRTdHJ1Y3QoZFopO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldFtYLFddPSQwLmZyb21CeXRlcygkLFYubWFzdGVyU2VlZCk7aWYoVi5tYXN0ZXJTZWVkLmZpbGwoMCksVyE9PTApcmV0dXJuIEcoVyk7aWYoWD09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIFIoe2VuY2xhdmU6WCxob3N0czpWLmhvc3RzLm1hcCgoeik9Pih7Li4uen0pKSxjcmVkSWQ6Sn0pfWFzeW5jI0coJCxaKXtsZXQgSj1hd2FpdCB0aGlzLiNZKCQpO3JldHVybiB0aGlzLiMkLmVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoWixKKX1hc3luYyN6KCQsWil7bGV0IEo9YXdhaXQgdGhpcy4jWSgkKTtyZXR1cm4gdGhpcy4jJC5kZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKFosSil9YXN5bmMjWSgkKXtyZXR1cm4gdGhpcy4jJC5ibGFrZTMoVyQodGhpcy4jSiwkKSl9YXN5bmMjSygkLFope2xldCBKPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSxRPW5ldyBVaW50OEFycmF5KDgpO3JldHVybiBuZXcgRGF0YVZpZXcoUS5idWZmZXIpLnNldEJpZ1VpbnQ2NCgwLEJpZ0ludChaKSwhMSksYXdhaXQgdGhpcy4jWShXJChKLFEpKX1hc3luYyNYKCQsWil7bGV0IEo9YXdhaXQgdGhpcy4jSygkLFopO3JldHVybiB0aGlzLiMkLmRlcml2ZUVkMjU1MTlLZXlQYWlyKEopfWFzeW5jI0YoJCxaLEope2xldCBRPWF3YWl0IHRoaXMuI1goJCxaKTtyZXR1cm4gdGhpcy4jJC5zaWduRWQyNTUxOShKLFEucHJpdmF0ZUtleSl9YXN5bmMjTigkLFosSil7bGV0IFE9YXdhaXQgdGhpcy4jWCgkLFopLFY9VyQoUS5wcml2YXRlS2V5LEopO3JldHVybihhd2FpdCB0aGlzLiMkLmJsYWtlMyhWKSkuc2xpY2UoMCxUMCl9fWFzeW5jIGZ1bmN0aW9uIGEkKCQsWil7aWYoWi5ieXRlTGVuZ3RoPHJWKXJldHVybiBHKDEwKTtsZXQgSj1hd2FpdCAkLmJsYWtlMyhXJChaLGNWKSk7cmV0dXJuIFIoSi5zbGljZSgwLGRWKSl9Y2xhc3Mgc1p7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGVucSgkKXtsZXQgWj1bLi4uJF07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFcwLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUoVzApO3JldHVybiBuZXcgUHJvbWlzZSgoVixZKT0+e0oub25jb21wbGV0ZT0oKT0+VigpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtmb3IobGV0IFggb2YgWil7bGV0IFc9YCR7WC5ob3N0fToke1guc2VxfWA7US5wdXQoWCxXKX19KX1hc3luYyBkZXEoJCxaKXtsZXQgSj1bLi4uWl07aWYoSi5sZW5ndGg9PT0wKXJldHVybjtsZXQgUT10aGlzLmRiLnRyYW5zYWN0aW9uKFcwLCJyZWFkd3JpdGUiKSxWPVEub2JqZWN0U3RvcmUoVzApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxYKT0+e1Eub25jb21wbGV0ZT0oKT0+WSgpLFEub25lcnJvcj0oKT0+WChRLmVycm9yKTtmb3IobGV0IFcgb2YgSil7bGV0IHo9YCR7JH06JHtXfWA7Vi5kZWxldGUoeil9fSl9YXN5bmMgbGlzdCgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oVzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoVzApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBWPVouZ2V0QWxsKCk7Vi5vbnN1Y2Nlc3M9KCk9PkooVi5yZXN1bHQpLFYub25lcnJvcj0oKT0+UShWLmVycm9yKX0pfWFzeW5jIGNvdW50KCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihXMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShXMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57bGV0IFY9Wi5jb3VudCgpO1Yub25zdWNjZXNzPSgpPT5KKFYucmVzdWx0KSxWLm9uZXJyb3I9KCk9PlEoVi5lcnJvcil9KX1hc3luYyB3aXBlKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihXMCwicmVhZHdyaXRlIiksWj0kLm9iamVjdFN0b3JlKFcwKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PnskLm9uY29tcGxldGU9KCk9PkooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksWi5jbGVhcigpfSl9fWZ1bmN0aW9uIHdRKCQpe3JldHVybntsYWJlbDokLmxhYmVsLGhhbmRsZTpuZXcgVVJMKCQuaGFuZGxlKSxpZHg6JC5pZHgsbGFzdFNlcTokLmxhc3RTZXF8fDAsY2xvY2tPZmZzZXQ6JC5jbG9ja09mZnNldCxzdWJzY3JpcHRpb246JC5zdWJzY3JpcHRpb259fWZ1bmN0aW9uIG9WKCQsWil7bGV0IEo9ey4uLiR9O2lmKFouc2V0TGFzdFNlcSE9PXZvaWQgMClKLmxhc3RTZXE9Wi5zZXRMYXN0U2VxO2Vsc2UgaWYoWi5sYXN0U2VxIT09dm9pZCAwKXtsZXQgUT1KLmxhc3RTZXF8fDA7aWYoWi5sYXN0U2VxPlEpSi5sYXN0U2VxPVoubGFzdFNlcX1yZXR1cm4gZGVsZXRlIEoubnVtQmFncyxkZWxldGUgSi5udW1EdXBlcyxKfWNsYXNzIHRae2RiO2NvbnN0cnVjdG9yKCQpe3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7cmV0dXJuIHRoaXMucHV0KHsuLi4kLGxhc3RTZXE6MH0pfWFzeW5jIHB1dCgkKXtsZXQgWj17Li4uJCxoYW5kbGU6JC5oYW5kbGUudG9TdHJpbmcoKSxsYXN0U2VxOiQubGFzdFNlcT8/MH0sSj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoVixZKT0+e0oub25jb21wbGV0ZT0oKT0+VigpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKSxRLnB1dChaKX0pfWFzeW5jIHRvdWNoKCQsWil7cmV0dXJuIHRoaXMucmVjb3JkU3RhdHMoJCx7bGFzdFNlcTpafSl9YXN5bmMgcmVjb3JkU3RhdHMoJCxaKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoVixZKT0+e0oub25jb21wbGV0ZT0oKT0+VigpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtsZXQgWD1RLmdldCgkKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0O2lmKCFXKXJldHVybjtRLnB1dChvVihXLFopKX19KX1hc3luYyBnZXQoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFYpPT57bGV0IFk9Si5nZXQoJCk7WS5vbnN1Y2Nlc3M9KCk9PntsZXQgWD1ZLnJlc3VsdDtpZighWClRKHZvaWQgMCk7ZWxzZSBRKHdRKFgpKX0sWS5vbmVycm9yPSgpPT5WKFkuZXJyb3IpfSl9YXN5bmMgc2V0KCQsWil7bGV0IEo9YXdhaXQgdGhpcy5nZXQoJCk7aWYoIUopcmV0dXJuIDEzO3RyeXtyZXR1cm4gYXdhaXQgdGhpcy5wdXQoey4uLkosLi4uWn0pLDB9Y2F0Y2h7cmV0dXJuIDE4fX1hc3luYyBkZWwoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZHdyaXRlIiksSj1aLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsVik9PntaLm9uY29tcGxldGU9KCk9PlEoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvciksSi5kZWxldGUoJCl9KX1hc3luYyBsaXN0KCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57bGV0IFY9Wi5nZXRBbGwoKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBZPVYucmVzdWx0O0ooWS5tYXAod1EpKX0sVi5vbmVycm9yPSgpPT5RKFYuZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5KKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLFouY2xlYXIoKX0pfX1jbGFzcyBlWntjcnlwdG87ZGI7Y29uc3RydWN0b3IoJCxaKXt0aGlzLmNyeXB0bz1aO3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkd3JpdGUiKSxKPVoub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChRKT0+e2lmKCQubGVuZ3RoPT09MCl7UShbXSk7cmV0dXJufWxldCBWPUFycmF5KCQubGVuZ3RoKS5maWxsKDApO1oub25jb21wbGV0ZT0oKT0+UShWKSxaLm9uZXJyb3I9KCk9Pntmb3IobGV0IFk9MDtZPFYubGVuZ3RoO1krKylWW1ldPTE4O1EoVil9O2ZvcihsZXQgWT0wO1k8JC5sZW5ndGg7WSsrKXtsZXR7a2V5OlgsZGF0YTpXfT0kW1ldLHo9ZihYKSxLPUoucHV0KFcseik7Sy5vbmVycm9yPShGKT0+e0YucHJldmVudERlZmF1bHQoKSxWW1ldPTE4fX19KX1hc3luYyBkZWwoJCl7bGV0IFo9Wy4uLiRdO2lmKFoubGVuZ3RoPT09MClyZXR1cm47bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChWLFkpPT57Si5vbmNvbXBsZXRlPSgpPT5WKCksSi5vbmVycm9yPSgpPT5ZKEouZXJyb3IpO2ZvcihsZXQgWCBvZiBaKXtsZXQgVz1mKFgpO1EuZGVsZXRlKFcpfX0pfWFzeW5jIGdldCgkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFYpPT57bGV0IFk9ZigkKSxYPUouZ2V0KFkpO1gub25zdWNjZXNzPWFzeW5jKCk9PntsZXQgVz1YLnJlc3VsdDtpZihXKVEoYXdhaXQgdiQoJCxXLHRoaXMuY3J5cHRvKSk7ZWxzZSBRKHZvaWQgMCl9LFgub25lcnJvcj0oKT0+VihYLmVycm9yKX0pfWFzeW5jIGhhcygkKXtyZXR1cm4gYXdhaXQgdGhpcy5nZXQoJCkhPT12b2lkIDB9YXN5bmMgbGlzdCgkKXtsZXQgWj0kPy5hcGxkLEo9JD8uYm9keSE9PSExLFY9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoWSxYKT0+e2xldCBXPVtdLHo9Wj09PXZvaWQgMD9WLm9wZW5DdXJzb3IoKTpWLmluZGV4KHEkKS5vcGVuQ3Vyc29yKElEQktleVJhbmdlLm9ubHkoWikpO3oub25zdWNjZXNzPShLKT0+e2xldCBGPUsudGFyZ2V0LnJlc3VsdDtpZihGKXtsZXQgTj1aPT09dm9pZCAwP0Yua2V5OkYucHJpbWFyeUtleSxVPUYudmFsdWU7Vy5wdXNoKHtoYXNoOkYwKE4pLGRhdGE6VX0pLEYuY29udGludWUoKX1lbHNlIFByb21pc2UuYWxsKFcubWFwKCh7aGFzaDpOLGRhdGE6VX0pPT52JChOLFUsdGhpcy5jcnlwdG8se2JvZHk6Sn0pKSkudGhlbihZKS5jYXRjaChYKX0sei5vbmVycm9yPSgpPT5YKHouZXJyb3IpfSl9YXN5bmMgY291bnQoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoUSxWKT0+e2xldCBZPSQ9PT12b2lkIDA/Si5jb3VudCgpOkouaW5kZXgocSQpLmNvdW50KElEQktleVJhbmdlLm9ubHkoJCkpO1kub25zdWNjZXNzPSgpPT5RKFkucmVzdWx0KSxZLm9uZXJyb3I9KCk9PlYoWS5lcnJvcil9KX1hc3luYyBsaXN0S2V5cygpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZG9ubHkiKS5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PntsZXQgVj1bXSxZPVoub3BlbktleUN1cnNvcigpO1kub25zdWNjZXNzPShYKT0+e2xldCBXPVgudGFyZ2V0LnJlc3VsdDtpZihXKVYucHVzaChGMChXLmtleSkpLFcuY29udGludWUoKTtlbHNlIEooVil9LFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfWFzeW5jIGxhc3QoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoUSxWKT0+e2xldCBZLFg9Si5vcGVuQ3Vyc29yKCk7WC5vbnN1Y2Nlc3M9YXN5bmMoVyk9PntsZXQgej1XLnRhcmdldC5yZXN1bHQ7aWYoeil7bGV0e2tleTpLLHZhbHVlOkZ9PXo7aWYoVjAoJCxGLmVpZCkpe2lmKCFZfHwoRi5jdHI/PzApPihZLmRhdGEuY3RyPz8wKXx8KEYuY3RyPz8wKT09PShZLmRhdGEuY3RyPz8wKSYmKEYub2ZmPz8wKT4oWS5kYXRhLm9mZj8/MCkpWT17a2V5OkssZGF0YTpGfX16LmNvbnRpbnVlKCl9ZWxzZSBpZihZKXtsZXQgSz1GMChZLmtleSk7UShhd2FpdCB2JChLLFkuZGF0YSx0aGlzLmNyeXB0bykpfWVsc2UgUSh2b2lkIDApfSxYLm9uZXJyb3I9KCk9PlYoWC5lcnJvcil9KX1hc3luYyBtYXJrQXBwbGllZCgkKXtsZXQgWj1bLi4uJF07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWR3cml0ZSIpLFE9Si5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFYsWSk9PntKLm9uY29tcGxldGU9KCk9PlYoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvcik7Zm9yKGxldCBYIG9mIFope2xldCBXPWYoWCksej1RLmdldChXKTt6Lm9uc3VjY2Vzcz0oKT0+e2xldCBLPXoucmVzdWx0O2lmKCFLKXJldHVybjtqWihLLFMkKSxRLnB1dChLLFcpfSx6Lm9uZXJyb3I9KEspPT57Sy5wcmV2ZW50RGVmYXVsdCgpfX19KX1hc3luYyBtYXJrRmFpbGVkKCQpe2xldCBaPVsuLi4kXTtpZihaLmxlbmd0aD09PTApcmV0dXJuO2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZHdyaXRlIiksUT1KLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoVixZKT0+e0oub25jb21wbGV0ZT0oKT0+VigpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtmb3IobGV0e2tleTpYLGVycjpXfW9mIFope2xldCB6PWYoWCksSz1RLmdldCh6KTtLLm9uc3VjY2Vzcz0oKT0+e2xldCBGPUsucmVzdWx0O2lmKCFGKXJldHVybjtqWihGLGEwLFcpLFEucHV0KEYseil9LEsub25lcnJvcj0oRik9PntGLnByZXZlbnREZWZhdWx0KCl9fX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PnskLm9uY29tcGxldGU9KCk9PkooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksWi5jbGVhcigpfSl9fWNsYXNzICRKeyNKOyMkOyNaOyNWOyNRO2NvbnN0cnVjdG9yKCQpe2lmKHRoaXMuI0o9JC5jcnlwdG8sdGhpcy4jUT0kLnBlcnNpc3RNZXRhLHRoaXMuI1Y9e3JwSWQ6JC5ycElkLHJwTmFtZTokLnJwTmFtZX0sJC5tZXRhIT09dm9pZCAwKXRoaXMuI1o9SiQoJC5tZXRhKX1nZXQgbWV0YSgpe3JldHVybiB0aGlzLiNaPT09dm9pZCAwP3ZvaWQgMDpKJCh0aGlzLiNaKX1zZXRNZXRhKCQpe3RoaXMuI1o9JD09PXZvaWQgMD92b2lkIDA6SiQoJCl9YXN5bmMgc2F2ZSgkLFope2lmKFo/LnBlcnNpc3Q9PT0hMClyZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoInByZi1zdG9yZTogdXNlIHdyYXBBbmRTYXZlKGVuY2xhdmUpIHRvIHBlcnNpc3Qgc2VhbGVkIG1hc3RlciIpKTtyZXR1cm4gdGhpcy4jJD0kLHRoaXMuIyR9YXN5bmMgd3JhcEFuZFNhdmUoJCxaKXtsZXRbSixRXT1hd2FpdCAkLnNlYWxXaXRoUGFzc2tleSh7Li4udGhpcy4jVixzYWx0Olo/LnNhbHQsY3JlZElkOlo/LmNyZWRJZD8/dGhpcy4jWj8uY3JlZElkLGNyZWF0ZUNyZWRJZk5lZWRlZDpaPy5jcmVhdGVDcmVkSWZOZWVkZWQ/P1o/LmNyZWRJZD09PXZvaWQgMCx1c2VyTmFtZToiZGlwbG9tYXRpYy1wcmYifSk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0IFY9e3NlYWxlZE1hc3RlcjpKLnNlYWxlZE1hc3RlcixzYWx0Okouc2FsdCxjcmVkSWQ6Si5jcmVkSWR9O3JldHVybiB0aGlzLiNaPVYsdGhpcy4jJD0kLGF3YWl0IHRoaXMuI1EoSiQoVikpLFIodGhpcy4jJCl9YXN5bmMgbG9hZCgpe3JldHVybiB0aGlzLiMkfWFzeW5jIHVubG9jaygpe2xldCAkPXRoaXMuI1o7aWYoJD09PXZvaWQgMClyZXR1cm4gRygyMik7bGV0W1osSl09YXdhaXQgJDAudW5zZWFsV2l0aFBhc3NrZXkodGhpcy4jSiwkLnNlYWxlZE1hc3Rlcix7Li4udGhpcy4jVixzYWx0OiQuc2FsdCxjcmVkSWQ6JC5jcmVkSWR9KTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gdGhpcy4jJD1aLFIoWil9YXN5bmMgYWRvcHRTZWFsZWQoJCxaKXtyZXR1cm4gdGhpcy4jWj1KJChaKSx0aGlzLiMkPSQsYXdhaXQgdGhpcy4jUShKJChaKSksUih0aGlzLiMkKX1hc3luYyB3aXBlKCl7dGhpcy4jJD12b2lkIDAsdGhpcy4jWj12b2lkIDAsYXdhaXQgdGhpcy4jUSh2b2lkIDApfX1mdW5jdGlvbiBKJCgkKXtsZXRbWixKXT1qMCgkLnNlYWxlZE1hc3Rlci5zbGljZSgpKTtyZXR1cm57c2VhbGVkTWFzdGVyOko9PT0wJiZaIT09dm9pZCAwP1o6JC5zZWFsZWRNYXN0ZXIsc2FsdDokLnNhbHQuc2xpY2UoKSxjcmVkSWQ6JC5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9fXZhciBaSj0ic2VlZCIscyQ9InByZk1ldGEiO2NsYXNzIEpKe2VuY2xhdmU7ZGI7I0o7Y29uc3RydWN0b3IoJCxaKXt0aGlzLmRiPSQsdGhpcy4jSj1afWFzeW5jIHNhdmUoJCxaKXtyZXR1cm4gdGhpcy5lbmNsYXZlPSQsdGhpcy5lbmNsYXZlfWFzeW5jIGxvYWQoKXtpZih0aGlzLmVuY2xhdmUpcmV0dXJuIHRoaXMuZW5jbGF2ZTtsZXQgJD1hd2FpdCB0aGlzLiMkKCk7aWYoJD09PXZvaWQgMHx8JD09PSIiKXJldHVybjtsZXQgWj1EJCgkKSxbSixRXT0kMC5mcm9tQnl0ZXModGhpcy4jSixaKTtpZihaLmZpbGwoMCksYXdhaXQgdGhpcy4jWigpLFEhPT0wfHxKPT09dm9pZCAwKXJldHVybjtyZXR1cm4gdGhpcy5lbmNsYXZlPUosdGhpcy5lbmNsYXZlfWFzeW5jIGNsZWFyU2Vzc2lvbigpe3RoaXMuZW5jbGF2ZT12b2lkIDAsYXdhaXQgdGhpcy4jWigpfWFzeW5jIHdpcGUoKXt0aGlzLmVuY2xhdmU9dm9pZCAwO2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oRzAsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZShHMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5KKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLFouZGVsZXRlKFpKKSxaLmRlbGV0ZShzJCl9KX1hc3luYyBsb2FkUHJmTWV0YSgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oRzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoRzApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBWPVouZ2V0KHMkKTtWLm9uc3VjY2Vzcz0oKT0+e0ooYVYoVi5yZXN1bHQpKX0sVi5vbmVycm9yPSgpPT5RKFYuZXJyb3IpfSl9YXN5bmMgcGVyc2lzdFByZk1ldGEoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihHMCwicmVhZHdyaXRlIiksSj1aLm9iamVjdFN0b3JlKEcwKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsVik9PntpZihaLm9uY29tcGxldGU9KCk9PlEoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvciksJD09PXZvaWQgMCl7Si5kZWxldGUocyQpO3JldHVybn1sZXQgWT17c2VhbGVkTWFzdGVyOiQuc2VhbGVkTWFzdGVyLnNsaWNlKCksc2FsdDokLnNhbHQuc2xpY2UoKSxjcmVkSWQ6JC5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9O0oucHV0KFkscyQpfSl9YXN5bmMgaGFzUHJmTWV0YSgpe3JldHVybiBhd2FpdCB0aGlzLmxvYWRQcmZNZXRhKCkhPT12b2lkIDB9YXN5bmMgb3BlblByZlN0b3JlKCQpe2xldCBaPWF3YWl0IHRoaXMubG9hZFByZk1ldGEoKTtyZXR1cm4gbmV3ICRKKHtjcnlwdG86JC5jcnlwdG8/P3RoaXMuI0oscnBJZDokLnJwSWQscnBOYW1lOiQucnBOYW1lLG1ldGE6WixwZXJzaXN0TWV0YTooSik9PnRoaXMucGVyc2lzdFByZk1ldGEoSil9KX0jJCgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oRzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoRzApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBWPVouZ2V0KFpKKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBZPVYucmVzdWx0O0oodHlwZW9mIFk9PT0ic3RyaW5nIiYmWS5sZW5ndGg+MD9ZOnZvaWQgMCl9LFYub25lcnJvcj0oKT0+UShWLmVycm9yKX0pfSNaKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihHMCwicmVhZHdyaXRlIiksWj0kLm9iamVjdFN0b3JlKEcwKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PnskLm9uY29tcGxldGU9KCk9PkooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksWi5kZWxldGUoWkopfSl9fWZ1bmN0aW9uIGFWKCQpe2lmKCQ9PT12b2lkIDB8fCQ9PT1udWxsfHx0eXBlb2YgJCE9PSJvYmplY3QiKXJldHVybjtsZXQgWj0kO2lmKCEoWi5zZWFsZWRNYXN0ZXIgaW5zdGFuY2VvZiBVaW50OEFycmF5KXx8IShaLnNhbHQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSlyZXR1cm47bGV0W0osUV09ajAoWi5zZWFsZWRNYXN0ZXIpO2lmKFEhPT0wfHxKPT09dm9pZCAwKXJldHVybjtyZXR1cm57c2VhbGVkTWFzdGVyOkosc2FsdDpaLnNhbHQuc2xpY2UoKSxjcmVkSWQ6Wi5jcmVkSWQgaW5zdGFuY2VvZiBVaW50OEFycmF5P1ouY3JlZElkLnNsaWNlKCk6dm9pZCAwfX1jbGFzcyBRSntkYjtjb25zdHJ1Y3RvcigkKXt0aGlzLmRiPSR9YXN5bmMgZW5xKCQsWil7bGV0IEo9Wy4uLlpdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFE9dGhpcy5kYi50cmFuc2FjdGlvbih6MCwicmVhZHdyaXRlIiksVj1RLm9iamVjdFN0b3JlKHowKTtyZXR1cm4gbmV3IFByb21pc2UoKFksWCk9PntRLm9uY29tcGxldGU9KCk9PlkoKSxRLm9uZXJyb3I9KCk9PlgoUS5lcnJvcik7Zm9yKGxldCBXIG9mIEope2xldCB6PU4wKFcpO1YucHV0KHtob3N0OiQsaGFzaDp6fSl9fSl9YXN5bmMgZGVxKCQsWil7bGV0IEo9Wy4uLlpdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFE9dGhpcy5kYi50cmFuc2FjdGlvbih6MCwicmVhZHdyaXRlIiksVj1RLm9iamVjdFN0b3JlKHowKTtyZXR1cm4gbmV3IFByb21pc2UoKFksWCk9PntRLm9uY29tcGxldGU9KCk9PlkoKSxRLm9uZXJyb3I9KCk9PlgoUS5lcnJvcik7Zm9yKGxldCBXIG9mIEope2xldCB6PU4wKFcpO1YuZGVsZXRlKFskLHpdKX19KX1hc3luYyBsaXN0KCQpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oejAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoejApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxWKT0+e2xldCBZPUouZ2V0QWxsKCk7WS5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1ZLnJlc3VsdC5maWx0ZXIoKHopPT56Lmhvc3Q9PT0kKS5tYXAoKHopPT56Lmhhc2gpO1EoVy5tYXAoKHopPT5EJCh6KSkpfSxZLm9uZXJyb3I9KCk9PlYoWS5lcnJvcil9KX1hc3luYyBjb3VudCgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oejAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoejApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBWPVouY291bnQoKTtWLm9uc3VjY2Vzcz0oKT0+SihWLnJlc3VsdCksVi5vbmVycm9yPSgpPT5RKFYuZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oejAsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZSh6MCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5KKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLFouY2xlYXIoKX0pfX12YXIgRzA9InNlZWRNZXRhIixaMD0iaG9zdHMiLHowPSJ1cGxvYWRRdWV1ZSIsVzA9ImRvd25sb2FkUXVldWUiLHU9Im1lc3NhZ2VzIixxJD0iYXBsZCIsVFE9MyxEUT0iZGlwbG9tYXRpYy1zdG9yZS1kYiI7Y2xhc3MgalF7c2VlZDtob3N0czt1cGxvYWRzO2Rvd25sb2FkczttZXNzYWdlcztkYjtjb25zdHJ1Y3RvcigkLFope3RoaXMuZGI9JCx0aGlzLnNlZWQ9bmV3IEpKKCQsWiksdGhpcy5ob3N0cz1uZXcgdFooJCksdGhpcy51cGxvYWRzPW5ldyBRSigkKSx0aGlzLmRvd25sb2Fkcz1uZXcgc1ooJCksdGhpcy5tZXNzYWdlcz1uZXcgZVooJCxaKX1hc3luYyB3aXBlKCl7YXdhaXQgdGhpcy5ob3N0cy53aXBlKCksYXdhaXQgdGhpcy51cGxvYWRzLndpcGUoKSxhd2FpdCB0aGlzLmRvd25sb2Fkcy53aXBlKCksYXdhaXQgdGhpcy5tZXNzYWdlcy53aXBlKCl9fWFzeW5jIGZ1bmN0aW9uIHNWKCl7cmV0dXJuIG5ldyBQcm9taXNlKCgkLFopPT57bGV0IEo9aW5kZXhlZERCLm9wZW4oRFEsVFEpO0oub251cGdyYWRlbmVlZGVkPSgpPT57bGV0e3Jlc3VsdDpRLHRyYW5zYWN0aW9uOlZ9PUo7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhHMCkpUS5jcmVhdGVPYmplY3RTdG9yZShHMCk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhaMCkpUS5jcmVhdGVPYmplY3RTdG9yZShaMCx7a2V5UGF0aDoibGFiZWwifSk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyh6MCkpUS5jcmVhdGVPYmplY3RTdG9yZSh6MCx7a2V5UGF0aDpbImhvc3QiLCJoYXNoIl19KTtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKFcwKSlRLmNyZWF0ZU9iamVjdFN0b3JlKFcwKTtsZXQgWTtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKHUpKVk9US5jcmVhdGVPYmplY3RTdG9yZSh1KTtlbHNle2lmKCFWKXRocm93IEVycm9yKCJtaXNzaW5nIHVwZ3JhZGUgdHJhbnNhY3Rpb24gZm9yIG1lc3NhZ2VzIHN0b3JlIik7WT1WLm9iamVjdFN0b3JlKHUpfWlmKCFZLmluZGV4TmFtZXMuY29udGFpbnMocSQpKVkuY3JlYXRlSW5kZXgocSQsImFwbGQiLHt1bmlxdWU6ITF9KX0sSi5vbmJsb2NrZWQ9KCk9Pntjb25zb2xlLndhcm4oYFtESVBMT01BVElDXSBwcm90b2NvbCBzdG9yZSBJREIgdXBncmFkZSBibG9ja2VkICgke0RRfSDihpIgdiR7VFF9KTsgd2FpdGluZyBmb3Igb3RoZXIgY29ubmVjdGlvbnMgdG8gY2xvc2VgKX0sSi5vbnN1Y2Nlc3M9KCk9PntsZXQgUT1KLnJlc3VsdDtRLm9udmVyc2lvbmNoYW5nZT0oKT0+e1EuY2xvc2UoKX0sJChRKX0sSi5vbmVycm9yPSgpPT5aKEouZXJyb3I/P0Vycm9yKCJwcm90b2NvbCBzdG9yZSBJbmRleGVkREIgb3BlbiBmYWlsZWQiKSl9KX1hc3luYyBmdW5jdGlvbiBBUSgkKXtsZXQgWj1hd2FpdCBzVigpO2lmKHR5cGVvZiBuYXZpZ2F0b3I8InUiJiZuYXZpZ2F0b3Iuc3RvcmFnZT8ucGVyc2lzdCl0cnl7YXdhaXQgUHJvbWlzZS5yYWNlKFtuYXZpZ2F0b3Iuc3RvcmFnZS5wZXJzaXN0KCksbmV3IFByb21pc2UoKEopPT57c2V0VGltZW91dCgoKT0+SighMSksMjAwMCl9KV0pfWNhdGNoe31yZXR1cm4gbmV3IGpRKFosJCl9Y2xhc3MgVkp7Y2xpZW50O2VudERCO3Bvc3Q7d2hlblJlYWR5O3Jlc29sdmVSZWFkeTtyZWplY3RSZWFkeTtjb25zdHJ1Y3RvcigkKXt0aGlzLnBvc3Q9JCx0aGlzLndoZW5SZWFkeT1uZXcgUHJvbWlzZSgoWixKKT0+e3RoaXMucmVzb2x2ZVJlYWR5PVosdGhpcy5yZWplY3RSZWFkeT1KfSl9YXN5bmMgaW5pdCgpe3RyeXtsZXQgJD1hd2FpdCBBUShVJCksWj1hd2FpdCB2Sih7Y2FjaGU6ITF9KSxKPW5ldyBrJChaLmFwcGx5LCgpPT5aLmNsZWFyKCksKFkpPT57aWYoWS5sZW5ndGg8MSlyZXR1cm47dGhpcy5wb3N0KHtraW5kOiJkaXJ0eSIsZWlkczpZLm1hcCgoWCk9Plguc2xpY2UoKSl9KX0pLFE9Si5jbGVhcjtKLmNsZWFyPWFzeW5jKCk9PntsZXQgWT1hd2FpdCBRKCk7aWYoWT09PTApdGhpcy5wb3N0KHtraW5kOiJ3aXBlZCJ9KTtyZXR1cm4gWX07bGV0IFY9bmV3IGtaKG5ldyBYWixKLCQsX0osVSQpO3RoaXMuY2xpZW50PVYsdGhpcy5lbnREQj1aLFYuY2xpZW50U3RhdGUubGlzdGVuKCgpPT57dGhpcy5lbWl0Q2xpZW50U3RhdGUoKX0pLFYueGZlclN0YXRlLmxpc3RlbigoKT0+e3RoaXMuZW1pdFhmZXJTdGF0ZSgpfSksYXdhaXQgdGhpcy5lbWl0Q2xpZW50U3RhdGUoKSxhd2FpdCB0aGlzLmVtaXRYZmVyU3RhdGUoKSx0aGlzLnBvc3Qoe2tpbmQ6InJlYWR5In0pLHRoaXMubWFya1JlYWR5KCl9Y2F0Y2goJCl7bGV0IFo9JCBpbnN0YW5jZW9mIEVycm9yPyQ6RXJyb3IoU3RyaW5nKCQpKTt0aHJvdyB0aGlzLnBvc3Qoe2tpbmQ6ImluaXRFcnJvciIsbWVzc2FnZTpaLm1lc3NhZ2V9KSx0aGlzLmZhaWxSZWFkeShaKSxafX1tYXJrUmVhZHkoKXtsZXQgJD10aGlzLnJlc29sdmVSZWFkeTtpZih0aGlzLnJlc29sdmVSZWFkeT12b2lkIDAsdGhpcy5yZWplY3RSZWFkeT12b2lkIDAsJCkkKCl9ZmFpbFJlYWR5KCQpe2xldCBaPXRoaXMucmVqZWN0UmVhZHk7aWYodGhpcy5yZXNvbHZlUmVhZHk9dm9pZCAwLHRoaXMucmVqZWN0UmVhZHk9dm9pZCAwLFopWigkKX1yZXF1aXJlQ2xpZW50KCl7aWYoIXRoaXMuY2xpZW50KXRocm93IEVycm9yKCJXb3JrZXJSdW50aW1lIG5vdCBpbml0aWFsaXplZCIpO3JldHVybiB0aGlzLmNsaWVudH1hc3luYyBlbWl0Q2xpZW50U3RhdGUoKXtsZXQgJD10aGlzLmNsaWVudDtpZighJClyZXR1cm47bGV0IFo9YXdhaXQgJC5jbGllbnRTdGF0ZS5nZXQoKTt0aGlzLnBvc3Qoe2tpbmQ6ImNsaWVudFN0YXRlIixzdGF0ZTpafSl9YXN5bmMgZW1pdFhmZXJTdGF0ZSgpe2xldCAkPXRoaXMuY2xpZW50O2lmKCEkKXJldHVybjtsZXQgWj1hd2FpdCAkLnhmZXJTdGF0ZS5nZXQoKTt0aGlzLnBvc3Qoe2tpbmQ6InhmZXJTdGF0ZSIsc3RhdGU6Wn0pfWhvc3RGcm9tU2VyaWFsaXplZCgkKXtyZXR1cm57aGFuZGxlOm5ldyBVUkwoJC5oYW5kbGUpLGxhYmVsOiQubGFiZWwsaWR4OiQuaWR4fX1hc3luYyBoYW5kbGUoJCl7YXdhaXQgdGhpcy53aGVuUmVhZHk7bGV0IFo9dGhpcy5yZXF1aXJlQ2xpZW50KCk7c3dpdGNoKCQub3Ape2Nhc2UicGluZyI6cmV0dXJuInBvbmciO2Nhc2Uic2V0U2VlZCI6e2xldFtKLFFdPSQwLmZyb21CeXRlcyhVJCwkLnNlZWQpO2lmKFEhPT0wfHxKPT09dm9pZCAwKXRocm93IG5ldyBLMChRKTthd2FpdCBaLnNldFNlZWQoSix7cGVyc2lzdDokLnBlcnNpc3R9KTtyZXR1cm59Y2FzZSJsaW5rIjp7YXdhaXQgWi5saW5rKHRoaXMuaG9zdEZyb21TZXJpYWxpemVkKCQuaG9zdCksJC5jb25uZWN0Pz8hMCk7cmV0dXJufWNhc2UidW5saW5rIjp7YXdhaXQgWi51bmxpbmsoJC5sYWJlbCk7cmV0dXJufWNhc2UiY29ubmVjdCI6e2F3YWl0IFouY29ubmVjdCgkLmxpc3Rlbj8/ITAsJC5zeW5jPz8hMCk7cmV0dXJufWNhc2UiZGlzY29ubmVjdCI6e2F3YWl0IFouZGlzY29ubmVjdCgpO3JldHVybn1jYXNlInN5bmMiOnJldHVybiBhd2FpdCBaLnN5bmMoKTtjYXNlInJlYnVpbGQiOnJldHVybiBhd2FpdCBaLnJlYnVpbGQoe2NoZWNrSG9zdDokLmNoZWNrSG9zdD8/ITB9KTtjYXNlInJlY29uY2lsZSI6e2xldFtKLFFdPWF3YWl0IFoucmVjb25jaWxlKCQuaG9zdExhYmVsLHtwdWxsOiQucHVsbCxwdXNoOiQucHVzaCxzeW5jOiQuc3luY30pO2lmKFEhPT0wKXRocm93IG5ldyBLMChRKTtpZighSil0aHJvdyBuZXcgSzAoMTIpO3JldHVybiBKfWNhc2UibXNnY2hlY2siOnJldHVybiBhd2FpdCBaLm1zZ2NoZWNrKCk7Y2FzZSJlbnRjaGVjayI6e2xldCBKPXRoaXMuZW50REI7aWYoIUopdGhyb3cgbmV3IEswKDEyKTtsZXRbUSxWXT1hd2FpdCBKLmNoZWNrc3VtKFUkKTtpZihWIT09MCl0aHJvdyBuZXcgSzAoVik7aWYoIVEpdGhyb3cgbmV3IEswKDEyKTtyZXR1cm4gUX1jYXNlIndpcGUiOnthd2FpdCBaLndpcGUoe21zZ3M6JC5tc2dzLGVudHM6JC5lbnRzLG1ldGE6JC5tZXRhLHNlZWQ6JC5zZWVkfSk7cmV0dXJufWNhc2UiaW1wb3J0Ijp7bGV0IEo9JC5ieXRlcy5zbGljZSgpLFE9bmV3IEJsb2IoW0pdKSxWPW5ldyBGaWxlKFtRXSwiaW1wb3J0LmRpcCIpO3JldHVybiBhd2FpdCBaLmltcG9ydChWKX1jYXNlImV4cG9ydCI6e2xldFtKLFFdPWF3YWl0IFouZXhwb3J0Qnl0ZXMoKTtpZihRIT09MCl0aHJvdyBuZXcgSzAoUSk7aWYoIUopdGhyb3cgbmV3IEswKDEyKTtyZXR1cm4gSn1jYXNlImdldENsaWVudFN0YXRlIjpyZXR1cm4gYXdhaXQgWi5jbGllbnRTdGF0ZS5nZXQoKTtjYXNlImdldFhmZXJTdGF0ZSI6cmV0dXJuIGF3YWl0IFoueGZlclN0YXRlLmdldCgpO2RlZmF1bHQ6e2xldCBKPSQ7dGhyb3cgRXJyb3IoInVua25vd24gd29ya2VyIGNvbW1hbmQiKX19fX1jbGFzcyBLMCBleHRlbmRzIEVycm9ye3N0YXR1cztjb25zdHJ1Y3RvcigkKXtzdXBlcihgV29ya2VyU3RhdHVzRXJyb3I6ICR7alskXX1gKTt0aGlzLnN0YXR1cz0kO3RoaXMubmFtZT0iV29ya2VyU3RhdHVzRXJyb3IifX1mdW5jdGlvbiB0JCgkLFope3JldHVybntraW5kOiJyZXBseSIsaWQ6JCxvazohMCxyZXN1bHQ6Wn19ZnVuY3Rpb24gWUooJCxaKXtyZXR1cm57a2luZDoicmVwbHkiLGlkOiQsb2s6ITEsc3RhdHVzOlp9fXZhciBBMD1nbG9iYWxUaGlzLF9RPW5ldyBWSigoJCxaKT0+e2lmKFomJloubGVuZ3RoPjApQTAucG9zdE1lc3NhZ2UoJCxaKTtlbHNlIEEwLnBvc3RNZXNzYWdlKCQpfSk7QTAub25tZXNzYWdlPSgkKT0+e2xldCBaPSQuZGF0YTtpZighekooWikpcmV0dXJuO3RWKFopfTthc3luYyBmdW5jdGlvbiB0VigkKXt0cnl7bGV0IFo9YXdhaXQgX1EuaGFuZGxlKCQpO2lmKCgkLm9wPT09ImV4cG9ydCJ8fCQub3A9PT0ibXNnY2hlY2sifHwkLm9wPT09ImVudGNoZWNrIikmJlogaW5zdGFuY2VvZiBVaW50OEFycmF5KXtsZXQgSj1aLnNsaWNlKCk7QTAucG9zdE1lc3NhZ2UodCQoJC5pZCxKKSxbSi5idWZmZXJdKTtyZXR1cm59aWYoJC5vcD09PSJyZWNvbmNpbGUiJiZaJiZ0eXBlb2YgWj09PSJvYmplY3QiJiYibXNnY2hlY2siaW4gWiYmWi5tc2djaGVjayBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpe2xldCBKPVoubXNnY2hlY2suc2xpY2UoKSxRPXsuLi5aLG1zZ2NoZWNrOkp9O0EwLnBvc3RNZXNzYWdlKHQkKCQuaWQsUSksW0ouYnVmZmVyXSk7cmV0dXJufUEwLnBvc3RNZXNzYWdlKHQkKCQuaWQsWikpfWNhdGNoKFope2lmKFogaW5zdGFuY2VvZiBLMCl7QTAucG9zdE1lc3NhZ2UoWUooJC5pZCxaLnN0YXR1cykpO3JldHVybn1jb25zb2xlLmVycm9yKCJ3b3JrZXIgY29tbWFuZCBmYWlsZWQiLFopLEEwLnBvc3RNZXNzYWdlKFlKKCQuaWQsMTIpKX19X1EuaW5pdCgpLmNhdGNoKCgkKT0+e2NvbnNvbGUuZXJyb3IoIndvcmtlciBpbml0IGZhaWxlZCIsJCl9KTsK";var LW;function QK(){if(typeof pW!=="string"||pW.length===0)throw Error("[DIPLOMATIC] worker source not embedded; run pkg build before spawn");return atob(pW)}function MK(){if(LW!==void 0)return LW;let Z=new Blob([QK()],{type:"text/javascript"});return LW=URL.createObjectURL(Z),LW}function ql(){if(typeof Worker>"u")throw Error("[DIPLOMATIC] Worker API unavailable; cannot spawn sync worker");return new Worker(MK(),{type:"module"})}var zK=new TextEncoder().encode("diplomatic.wrap.v1"),hK=32,SK=16;class ${#W;#Z;constructor(Z,X){this.#W=Z,this.#Z=X}static async fromRandom(Z){let X=await Z.gen256BitSecureRandomSeed(),[W,V]=ZZ(X);if(V!==0||W===void 0)throw Error(`enclave: invalid random seed (${V})`);return new $(W,Z)}static fromBytes(Z,X){let[W,V]=ZZ(X);if(V!==0)return Y(V);if(W===void 0)return Y(10);let[l,K]=ZZ(W.slice());if(K!==0)return Y(K);if(l===void 0)return Y(10);return d(new $(l,Z))}async sealWithPasskey(Z){let X=Z?.salt??jX,W=Z?.credId;if(W===void 0&&Z?.createCredIfNeeded===!0){let[K,G]=await gV({rpId:Z?.rpId,rpName:Z?.rpName,userName:Z?.userName??"diplomatic-prf"});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 bX({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.#X(V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);return d({sealedMaster:K,salt:X.slice(),credId:V.credId.slice()})}finally{V.prf.fill(0)}}static async unsealWithPasskey(Z,X,W){let[V,l]=await bX({rpId:W.rpId,rpName:W.rpName,credId:W.credId,salt:W.salt});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{return await $.#V(Z,X,V.prf)}finally{V.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 BX(W,V,X);if(K!==0)return Y(K);return d(W)}finally{V.fill(0)}}static async fromLargeBlob(Z,X){let[W,V]=await IW(X?.credId,X);if(V!==0)return Y(V);if(W===void 0)return Y(7);try{return $.#m(Z,W.blob,W.credId)}finally{W.blob.fill(0)}}static async clearLargeBlob(Z,X){return BX(Z,new Uint8Array(dZ),X)}async sealPairPackageBody(Z,X){let W=X?.salt??jX,[V,l]=await bX({rpId:X?.rpId,rpName:X?.rpName,credId:X?.credId,salt:W});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await EX(this.#Z,V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);let[m,R]=ZZ(this.#W.slice());if(R!==0)return Y(R);if(m===void 0)return Y(10);let J={masterSeed:m,hosts:Z.map((k)=>({handle:k.handle,label:k.label,idx:k.idx??0}))},C=new i,F=C.writeStruct(UX,J);if(F!==0)return m.fill(0),Y(F);let b=C.result();m.fill(0);let c;try{c=await this.#Z.encryptXSalsa20Poly1305Combined(b,K)}catch{return b.fill(0),Y(12)}return b.fill(0),d({body:c,salt:W.slice(),credId:V.credId.slice()})}finally{V.prf.fill(0)}}static async openPairPackageBody(Z,X,W){let[V,l]=await bX({rpId:W.rpId,rpName:W.rpName,credId:W.credId,salt:W.salt});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await EX(Z,V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);let m;try{m=await Z.decryptXSalsa20Poly1305Combined(X,K)}catch{return Y(20)}let R=new P(m),[J,C]=R.readStruct(UX);if(m.fill(0),C!==0)return Y(C);if(J===void 0)return Y(14);let[F,b]=$.fromBytes(Z,J.masterSeed);if(J.masterSeed.fill(0),b!==0)return Y(b);if(F===void 0)return Y(12);let[c,k]=await F.#X(V.prf);if(k!==0)return Y(k);if(c===void 0)return Y(12);return d({enclave:F,hosts:J.hosts.map((T)=>({...T})),sealedMaster:c,credId:V.credId.slice()})}finally{V.prf.fill(0)}}spawnSyncWorker(Z){let X=ql(),W=this.#W.slice();return X.postMessage({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.#G(W,V);return Object.freeze({publicKey:l.publicKey,sign:(K)=>this.#C(W,V,K),kdmFor:(K)=>this.#F(W,V,K)})}async#X(Z){let[X,W]=await EX(this.#Z,Z);if(W!==0)return Y(W);if(X===void 0)return Y(12);try{let V=await this.#Z.encryptXSalsa20Poly1305Combined(this.#W,X);return LZ(V)}catch{return Y(12)}}static async#V(Z,X,W){let[,V]=LZ(X);if(V!==0)return Y(V);let[l,K]=await EX(Z,W);if(K!==0)return Y(K);if(l===void 0)return Y(12);try{let G=await Z.decryptXSalsa20Poly1305Combined(X,l);return $.fromBytes(Z,G)}catch{return Y(20)}}#l(Z){let[X,W]=ZZ(this.#W.slice());if(W!==0)return Y(W);if(X===void 0)return Y(10);let[V,l]=SV(X,Z);if(l!==0)return X.fill(0),Y(l);if(V===void 0)return X.fill(0),Y(12);X.fill(0);let K=new i,G=K.writeStruct(cW,V);if(V.masterSeed.fill(0),G!==0)return Y(G);return d(K.result())}static#m(Z,X,W){if(X.byteLength===0||X.every((R)=>R===0))return Y(22);if(X.byteLength===dZ){let[R,J]=$.fromBytes(Z,X);if(J!==0)return Y(J);if(R===void 0)return Y(12);return d({enclave:R,hosts:[],credId:W})}let V=new P(X),[l,K]=V.readStruct(cW);if(K!==0)return Y(K);if(l===void 0)return Y(14);let[G,m]=$.fromBytes(Z,l.masterSeed);if(l.masterSeed.fill(0),m!==0)return Y(m);if(G===void 0)return Y(12);return d({enclave:G,hosts:l.hosts.map((R)=>({...R})),credId:W})}async#Y(Z,X){let W=await this.#K(Z);return this.#Z.encryptXSalsa20Poly1305Combined(X,W)}async#R(Z,X){let W=await this.#K(Z);return this.#Z.decryptXSalsa20Poly1305Combined(X,W)}async#K(Z){return this.#Z.blake3(yX(this.#W,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.#K(yX(W,V))}async#G(Z,X){let W=await this.#J(Z,X);return this.#Z.deriveEd25519KeyPair(W)}async#C(Z,X,W){let V=await this.#G(Z,X);return this.#Z.signEd25519(W,V.privateKey)}async#F(Z,X,W){let V=await this.#G(Z,X),l=yX(V.privateKey,W);return(await this.#Z.blake3(l)).slice(0,HZ)}}async function EX(Z,X){if(X.byteLength<SK)return Y(10);let W=await Z.blake3(yX(X,zK));return d(W.slice(0,hK))}class yW{#W;#Z;#X;#V;#l;constructor(Z){if(this.#W=Z.crypto,this.#l=Z.persistMeta,this.#V={rpId:Z.rpId,rpName:Z.rpName},Z.meta!==void 0)this.#X=cX(Z.meta)}get meta(){return this.#X===void 0?void 0:cX(this.#X)}setMeta(Z){this.#X=Z===void 0?void 0:cX(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.#V,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.#l(cX(l)),d(this.#Z)}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await $.unsealWithPasskey(this.#W,Z.sealedMaster,{...this.#V,salt:Z.salt,credId:Z.credId});if(W!==0)return Y(W);if(X===void 0)return Y(12);return this.#Z=X,d(X)}async adoptSealed(Z,X){return this.#X=cX(X),this.#Z=Z,await this.#l(cX(X)),d(this.#Z)}async wipe(){this.#Z=void 0,this.#X=void 0,await this.#l(void 0)}}function cX(Z){let[X,W]=LZ(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 xV="seed",QW="prfMeta";class MW{enclave;db;#W;constructor(Z,X){this.db=Z,this.#W=X}async save(Z,X){return this.enclave=Z,this.enclave}async load(){if(this.enclave)return this.enclave;let Z=await this.#Z();if(Z===void 0||Z==="")return;let X=iZ(Z),[W,V]=$.fromBytes(this.#W,X);if(X.fill(0),await this.#X(),V!==0||W===void 0)return;return this.enclave=W,this.enclave}async clearSession(){this.enclave=void 0,await this.#X()}async wipe(){this.enclave=void 0;let Z=this.db.transaction(JZ,"readwrite"),X=Z.objectStore(JZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.delete(xV),X.delete(QW)})}async loadPrfMeta(){let X=this.db.transaction(JZ,"readonly").objectStore(JZ);return new Promise((W,V)=>{let l=X.get(QW);l.onsuccess=()=>{W(NK(l.result))},l.onerror=()=>V(l.error)})}async persistPrfMeta(Z){let X=this.db.transaction(JZ,"readwrite"),W=X.objectStore(JZ);return new Promise((V,l)=>{if(X.oncomplete=()=>V(),X.onerror=()=>l(X.error),Z===void 0){W.delete(QW);return}let K={sealedMaster:Z.sealedMaster.slice(),salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()};W.put(K,QW)})}async hasPrfMeta(){return await this.loadPrfMeta()!==void 0}async openPrfStore(Z){let X=await this.loadPrfMeta();return new yW({crypto:Z.crypto??this.#W,rpId:Z.rpId,rpName:Z.rpName,meta:X,persistMeta:(W)=>this.persistPrfMeta(W)})}#Z(){let X=this.db.transaction(JZ,"readonly").objectStore(JZ);return new Promise((W,V)=>{let l=X.get(xV);l.onsuccess=()=>{let K=l.result;W(typeof K==="string"&&K.length>0?K:void 0)},l.onerror=()=>V(l.error)})}#X(){let Z=this.db.transaction(JZ,"readwrite"),X=Z.objectStore(JZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.delete(xV)})}}function NK(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]=LZ(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 HV{db;constructor(Z){this.db=Z}async enq(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=GZ(m);l.put({host:Z,hash:R})}})}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=GZ(m);l.delete([Z,R])}})}async list(Z){let W=this.db.transaction(CZ,"readonly").objectStore(CZ);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)=>iZ(R)))},K.onerror=()=>l(K.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()})}}var JZ="seedMeta",lZ="hosts",CZ="uploadQueue",RZ="downloadQueue",o="messages",PX="apld",al=3,_l="diplomatic-store-db";class PV{seed;hosts;uploads;downloads;messages;db;constructor(Z,X){this.db=Z,this.seed=new MW(Z,X),this.hosts=new zV(Z),this.uploads=new HV(Z),this.downloads=new MV(Z),this.messages=new hV(Z,X)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}async function gK(){return new Promise((Z,X)=>{let W=indexedDB.open(_l,al);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!V.objectStoreNames.contains(JZ))V.createObjectStore(JZ);if(!V.objectStoreNames.contains(lZ))V.createObjectStore(lZ,{keyPath:"label"});if(!V.objectStoreNames.contains(CZ))V.createObjectStore(CZ,{keyPath:["host","hash"]});if(!V.objectStoreNames.contains(RZ))V.createObjectStore(RZ);let K;if(!V.objectStoreNames.contains(o))K=V.createObjectStore(o);else{if(!l)throw Error("missing upgrade transaction for messages store");K=l.objectStore(o)}if(!K.indexNames.contains(PX))K.createIndex(PX,"apld",{unique:!1})},W.onblocked=()=>{console.warn(`[DIPLOMATIC] protocol store IDB upgrade blocked (${_l} → v${al}); 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 zW(Z){let X=await gK();if(typeof navigator<"u"&&navigator.storage?.persist)try{await Promise.race([navigator.storage.persist(),new Promise((W)=>{setTimeout(()=>W(!1),2000)})])}catch{}return new PV(X,Z)}function sl(Z){if(!Z||typeof Z!=="object")return!1;if(!("kind"in Z))return!1;return typeof Z.kind==="string"}function rl(Z){if(typeof Z!=="number")return;return Z}function tl(Z){if(!Z||typeof Z!=="object")return;if(!("hasSeed"in Z)||!("hasHost"in Z)||!("connected"in Z))return;if(typeof Z.hasSeed!=="boolean"||typeof Z.hasHost!=="boolean"||typeof Z.connected!=="boolean")return;return{hasSeed:Z.hasSeed,hasHost:Z.hasHost,connected:Z.connected}}function xK(Z){if(!Z||typeof Z!=="object")return;if(!("phase"in Z))return;let X=HK(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 HK(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 el(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=xK(Z.progress);if(W===void 0)return;X=W}return{numUploads:Z.numUploads,numDownloads:Z.numDownloads,progress:X}}var FZ="[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:oZ};clientState;xferState;constructor(Z,X,W,V,l){this.state=Z,this.store=X,this.readyTimeoutMs=l,this.clientState=new bZ(async()=>this.cachedClientState),this.xferState=new bZ(async()=>this.cachedXferState),this.scheduledSync=new NX(V,async()=>{if(!this.worker)return;try{await this.request({id:this.allocId(),op:"sync"})}catch(K){console.error(`${FZ} worker sync after local write failed`,K)}}),this.local=new vZ(W,Z,X,()=>{throw Error(`${FZ} local writer has no transport (use worker for network)`)},SZ,!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(`${FZ} worker error`,W),this.failPending(Error(`${FZ} worker failed to load`))},Z.onmessageerror=()=>{this.failPending(Error(`${FZ} 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 pZ,l=W.syncDebounceMs??lW,K=W.readyTimeoutMs??15000,G=new DX(Z,X,V,l,K);return await G.hydrateStateFromStore(X),G}async hydrateStateFromStore(Z){let X=await Z.seed.load(),W=await Z.hosts.list();this.cachedClientState={hasSeed:X!==void 0,hasHost:Array.from(W).length>0,connected:!1};let V=await Z.uploads.count(),l=await Z.downloads.count();this.cachedXferState={numUploads:V,numDownloads:l,progress:oZ}}async pullRemoteState(){let Z=await this.request({id:this.allocId(),op:"getClientState"}),X=tl(Z);if(X!==void 0)this.cachedClientState=X;let W=await this.request({id:this.allocId(),op:"getXferState"}),V=el(W);if(V!==void 0)this.cachedXferState=V}requireWorker(){if(!this.worker)throw Error(`${FZ} no sync worker; call setSeed first`);return this.worker}async ping(){if(await this.request({id:this.allocId(),op:"ping"})!=="pong")throw Error(`${FZ} worker ping failed`)}terminate(){this.scheduledSync.cancel();let Z=this.worker;if(this.worker=void 0,Z)try{Z.terminate()}catch{}this.failPending(Error(`${FZ} worker terminated`))}onMessage(Z){if(!sl(Z))return;let X=Z;switch(X.kind){case"ready":return;case"initError":{this.failPending(Error(`${FZ} worker init failed: ${X.message}`));return}case"clientState":{this.cachedClientState=X.state,this.clientState.emit();return}case"xferState":{this.cachedXferState=X.state,this.xferState.emit();return}case"dirty":{this.state.refresh(X.eids.map(iK));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=rl(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),this.cachedClientState={...this.cachedClientState,hasSeed:!0},this.clientState.emit();let W=this.allocId(),V=this.readyTimeoutMs;await new Promise((l,K)=>{let G,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(`${FZ} 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.pullRemoteState()}catch{}}async link(Z,X=!0){await this.local.link(Z,!1),await this.request({id:this.allocId(),op:"link",host:this.serializeHost(Z),connect:X})}async unlink(Z){if(await this.local.unlink(Z),!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(!PK(W))return Y(12);return d(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(`${FZ} msgcheck: expected Uint8Array`);return Z}async entcheck(){let Z=await this.request({id:this.allocId(),op:"entcheck"});if(!(Z instanceof Uint8Array))throw Error(`${FZ} 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 GW(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 PK(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 iK(Z){return Z}var kX="[DIPLOMATIC]";async function hW(Z){let X=Z.clock??new pZ;if(Z.worker===!0&&UK(Z)!==void 0)throw Error(`${kX} worker path requires IndexedDB on both sides; do not pass store (got a custom store)`);if(Z.worker!==!0){console.info(`${kX} sync on main thread `+"(no worker — app did not request a worker)");let l=await Z0(Z.store);return uK(X,Z.state,l)}if(typeof Worker>"u")throw Error(`${kX} worker: true but Worker API is unavailable`);let W=await Z0(void 0),V=await DX.open(Z.state,W,{readyTimeoutMs:Z.readyTimeoutMs,clock:X,syncDebounceMs:Z.syncDebounceMs});return console.info(`${kX} worker-mode client open (sync Worker starts on setSeed via Enclave)`),{client:V,mode:"worker",dispose:()=>{console.info(`${kX} terminating sync worker`),V.terminate()}}}function UK(Z){if("store"in Z)return Z.store;return}async function uK(Z,X,W){let V=new vZ(Z,X,W,rX,SZ);return{client:V,mode:"main",dispose:()=>{V.disconnect()}}}async function Z0(Z){if(Z!==void 0)return Z;if(typeof indexedDB>"u")throw Error(`${kX} IndexedDB is unavailable; pass store explicitly (e.g. new MemoryStore(crypto))`);return zW(SZ)}function OK(Z){let[X,W]=iV();return SW(()=>{async function V(){let K=await Z.clientState.get();W(K)}let l=Z.clientState.listen(V);return V(),()=>{l()}},[Z]),X}function BK(Z){let[X,W]=iV();return SW(()=>{async function V(){let K=await Z.xferState.get();W(K)}let l=Z.xferState.listen(V);return V(),()=>{l()}},[Z]),X}function jK(Z){SW(()=>{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 EK(Z={}){let X=Z.clock??new pZ,{seed:W,host:V,readyTimeoutMs:l}=Z,K=Z.worker===!0,G="store"in Z?Z.store:void 0,[m,R]=iV({stateMgr:qW});return SW(()=>{let J=!1,C;return(async()=>{let F=await eW();if(J)return;let b=WW(F),c=K?await hW({state:b,clock:X,worker:!0,readyTimeoutMs:l}):await hW({state:b,clock:X,store:G,readyTimeoutMs:l});if(J){c.dispose();return}C=c.dispose;let{client:k,mode:T}=c;if(W)await k.setSeed(W);if(V)await k.link(V);if(J){C();return}R({client:k,entDB:F,stateMgr:b,mode:T,error:void 0})})().catch((F)=>{let b=F instanceof Error?F:Error(String(F));if(console.error("[DIPLOMATIC] useClient init failed",b),!J)R((c)=>({...c,client:void 0,error:b}))}),()=>{J=!0,C?.()}},[X,W,V,K,G,l]),m}import{use as wK,useEffect as X0,useRef as DK,useState as AK}from"react";function W0(Z,X,W){let[V,l]=AK();return X0(()=>{async function K(){let G=await W();l(G)}return K(),Z.on(X,K),()=>{Z.off(X,K)}},[Z,X,W]),V}function oK(Z,X,W){let V=DK(W());return X0(()=>{async function l(){V.current=W()}return Z.on(X,l),()=>{Z.off(X,l)}},[Z,X,W]),wK(V.current)}function V0(Z,X){return`${Z}:${X}`}class UV{queue=new Map;async enq(Z){for(let X of Z){let W=V0(X.host,X.seq);this.queue.set(W,X)}}async deq(Z,X){for(let W of X){let V=V0(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 nK(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 uV{hosts=new Map;async add(Z){let X={...Z,lastSeq:0};this.hosts.set(Z.label,X)}async touch(Z,X){await this.recordStats(Z,{lastSeq:X})}async recordStats(Z,X){let W=this.hosts.get(Z);if(!W)return;nK(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 OV{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 uZ(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&&RX(K.apld)!==X)continue;let G=t(l);V.push(await uZ(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(RX(W.apld)===Z)X++;return X}async listKeys(){let Z=[];for(let X of this.messages.keys())Z.push(t(X));return Z}async last(Z){let X;for(let[W,V]of this.messages){if(e(Z,V.eid)===!1)continue;let l=t(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 uZ(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;nZ(W,UZ)}}async markFailed(Z){for(let{key:X,err:W}of Z){let V=this.messages.get(g(X));if(!V)continue;nZ(V,cZ,W)}}async wipe(){this.messages.clear()}}class BV{enclave;async save(Z,X){return this.enclave=Z,this.enclave}async load(){return this.enclave}async wipe(){this.enclave=void 0}}class jV{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(GZ(V))}async deq(Z,X){let W=this.queue.get(Z);if(W)for(let V of X)W.delete(GZ(V))}async list(Z){let X=this.queue.get(Z);if(!X)return[];let W=[];for(let V of X)W.push(iZ(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 l0{seed=new BV;hosts=new uV;uploads=new jV;downloads=new UV;messages;constructor(Z){this.messages=new OV(Z)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}class K0{singletonType;latest;latestOff=-1;emitter=new gZ;constructor(Z){this.singletonType=Z}async apply(Z){for(let X of Z){let W=new P(X.eid),[V,l]=W.readStruct(_);if(l!==0)continue;let K=new i;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 G0={capable(){return $l()},async createCred(Z){return TW(Z)},async write(Z,X,W){return BX(Z,X,W)},async read(Z,X){let[W,V]=await IW(Z,X);if(V!==0||W===void 0)return Y(V);return d(W.blob)}};class m0{#W;#Z;#X;#V;#l;constructor(Z){if(this.#W=Z.crypto,this.#V=Z.rpId,this.#l=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.#V,rpName:this.#l,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 $.fromLargeBlob(this.#W,{rpId:this.#V,rpName:this.#l,credId:Z});if(W!==0||X===void 0)return Y(W);return this.#Z=X.enclave,d(X.enclave)}async wipe(){let Z=this.#X;if(Z!==void 0){let X=await $.clearLargeBlob(Z,{rpId:this.#V});if(X!==0)return Promise.reject(Error(`clearLargeBlob status ${X}`))}this.#Z=void 0,this.#X=void 0}}var TX=1,AX={encode(Z,X){let W=Z.writeVarInt(X.v);if(W!==0)return W;let V=Z.writeVarBytes(X.salt);if(V!==0)return V;let l=Z.writeVarBytes(X.credId);if(l!==0)return l;return Z.writeVarBytes(X.body)},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);if(K===void 0)return Y(14);let[m,R]=Z.readVarBytes();if(R!==0)return Y(R);if(m===void 0)return Y(14);return d({v:X,salt:V,credId:K,body:m})}};var NW={PREFIX:"dip1:",VERSION:TX,async seal(Z,X,W,V){let[l,K]=await X.sealPairPackageBody(W,V);if(K!==0)return Y(K);if(l===void 0)return Y(12);let G=new i,m=G.writeStruct(AX,{v:TX,salt:l.salt,credId:l.credId,body:l.body});if(m!==0)return Y(m);return d(NW.PREFIX+uW(G.result()))},async open(Z,X,W){let V=X.trim();if(!V.startsWith(NW.PREFIX))return Y(10);let l;try{l=OW(V.slice(NW.PREFIX.length))}catch{return Y(10)}let K=new P(l),[G,m]=K.readStruct(AX);if(m!==0)return Y(m);if(G===void 0)return Y(14);if(G.v!==TX)return Y(14);let[R,J]=await $.openPairPackageBody(Z,G.body,{...W,salt:G.salt,credId:G.credId.byteLength>0?G.credId:void 0});if(J!==0)return Y(J);if(R===void 0)return Y(12);return d({enclave:R.enclave,hosts:R.hosts,salt:G.salt.slice(),credId:R.credId,sealedMaster:R.sealedMaster})}};async function k2(Z,X){let W=await zW(SZ),V=new vZ(new pZ,Z,W,rX,SZ);return{client:V,setSeed:async(K)=>{let[G,m]=$.fromBytes(SZ,iZ(K));if(m!==0||G===void 0)throw Error(`invalid seed (${m})`);await W.seed.save(G),await W.hosts.add({handle:X,label:"host",idx:0}),await V.connect()}}}export{jK as useSyncOnResume,oK as useStateWatcherSuspense,W0 as useStateWatcher,BK as useClientXferState,OK as useClientState,EK as useClient,KW as shouldEmitItemProgress,nZ as setApld,EX as sealKeyFromPrf,ZV as revFromHead,hX as revFromEntity,yK as prfCapable,UX as pairPackagePlainCodec,AX as pairPackageEnvelopeCodec,zW as openIDBStore,eW as openEntDB,hW as openDiplomaticClient,qW as nullStateManager,r0 as nullEntDB,Fl as normalizeTags,s0 as isTombstone,WV as isTerminalApplyFailure,ZK as isPendingApply,D as isLiveEnt,e0 as isApldState,oZ as idleProgress,cW as identityBundleCodec,iZ as htob,rX as hostHTTPTransport,k2 as genWebClient,u0 as genSingletonEID,bX as evalPrf,WW as entStateManager,ml as encodeEntRev,_ as eidCodec,kW as defaultWebAuthnRpId,YX as defaultPeekProgressEvery,SZ as crypto,gV as createPrfCred,SV as createIdentityBundle,Gl as cmpBytes,WX as checksumSet,MX as checksumEntRevs,OZ as bundleHostCodec,GZ as btoh,uW as btob64url,g as btob64,OW as b64urltob,t as b64tob,LZ as asSealedMasterKey,ZZ as asMasterSeed,RX as apldFromStored,DX as WorkerClient,gZ as TypedEventEmitter,vZ as SyncClient,z as Status,zX as StateManager,K0 as SingletonStateManager,$W as SEALED_MASTER_KEY_LEN,yW as PrfSeedStore,m0 as PasskeySeedStore,NW as PairPackage,TX as PAIR_PACKAGE_VERSION,l0 as MemoryStore,dZ as MASTER_SEED_LEN,G0 as LargeBlob,iX as IDENTITY_BUNDLE_VERSION,PV as IDBStore,MW as IDBSeedStore,oW as HTTPTransport,tW as EntIDB,XW as EntDBMemory,i as Encoder,$ as Enclave,P as Decoder,jX as DEFAULT_PRF_SALT,pZ as Clock,SX as CachedEntDB,yZ as APLD_PENDING,cZ as APLD_ERROR,UZ as APLD_APPLIED};
|
|
1
|
+
function EV(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 Y0(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 R0=new TextEncoder,J0=50;function C0(Z,X,W){R0.encodeInto(Z,X.subarray(W))}function wV(Z,X,W){if(Z.length>J0)C0(Z,X,W);else Y0(Z,X,W)}var F0=4096;function gW(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>=F0)G+=String.fromCharCode(...K),K.length=0}if(K.length>0)G+=String.fromCharCode(...K);return G}var d0=new TextDecoder,b0=200;function c0(Z,X,W){let V=Z.subarray(X,X+W);return d0.decode(V)}function DV(Z,X,W){if(W>b0)return c0(Z,X,W);else return gW(Z,X,W)}class tZ{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 eZ=4294967295;function AV(Z,X,W){let V=W/4294967296,l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function oX(Z,X,W){let V=Math.floor(W/4294967296),l=W;Z.setUint32(X,V),Z.setUint32(X+4,l)}function nX(Z,X){let W=Z.getInt32(X),V=Z.getUint32(X+4);return W*4294967296+V}function oV(Z,X){let W=Z.getUint32(X),V=Z.getUint32(X+4);return W*4294967296+V}var k0=-1,T0=4294967295,I0=17179869183;function p0({sec:Z,nsec:X}){if(Z>=0&&X>=0&&Z<=I0)if(X===0&&Z<=T0){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),oX(V,4,Z),W}}function L0(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 Q0(Z){if(Z instanceof Date){let X=L0(Z);return p0(X)}else return null}function y0(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=nX(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 M0(Z){let X=y0(Z);return new Date(X.sec*1000+X.nsec/1e6)}var nV={type:k0,encode:Q0,decode:M0};class ZX{static defaultCodec=new ZX;__brand;builtInEncoders=[];builtInDecoders=[];encoders=[];decoders=[];constructor(){this.register(nV)}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 tZ(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 tZ(W,l)}}if(Z instanceof tZ)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 tZ(X,Z)}}function z0(Z){return Z instanceof ArrayBuffer||typeof SharedArrayBuffer<"u"&&Z instanceof SharedArrayBuffer}function IX(Z){if(Z instanceof Uint8Array)return Z;else if(ArrayBuffer.isView(Z))return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength);else if(z0(Z))return new Uint8Array(Z);else return Uint8Array.from(Z)}var h0=100,S0=2048;class vX{extensionCodec;context;useBigInt64;maxDepth;initialBufferSize;sortKeys;forceFloat32;ignoreUndefined;forceIntegerToFloat;pos;view;bytes;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??ZX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.maxDepth=Z?.maxDepth??h0,this.initialBufferSize=Z?.initialBufferSize??S0,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 vX({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=EV(Z);this.ensureBufferSizeToWrite(5+W),this.writeStringHeader(W),wV(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=IX(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),AV(this.view,this.pos,Z),this.pos+=8}writeI64(Z){this.ensureBufferSizeToWrite(8),oX(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 AZ(Z,X){return new vX(X).encodeSharedRef(Z)}function fX(Z){return`${Z<0?"-":""}0x${Math.abs(Z).toString(16).padStart(2,"0")}`}var N0=16,g0=16;class xW{hit=0;miss=0;caches;maxKeyLength;maxLengthPerKey;constructor(Z=N0,X=g0){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=gW(Z,X,W),K=Uint8Array.prototype.slice.call(Z,X,X+W);return this.store(K,l),l}}var HW="array",LX="map_key",fV="map_value",x0=(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 $V{stack=[];stackHeadPosition=-1;get length(){return this.stackHeadPosition+1}top(){return this.stack[this.stackHeadPosition]}pushArrayState(Z){let X=this.getUninitializedStateFromPool();X.type=HW,X.position=0,X.size=Z,X.array=Array(Z)}pushMapState(Z){let X=this.getUninitializedStateFromPool();X.type=LX,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===HW){let W=Z;W.size=0,W.array=void 0,W.position=0,W.type=void 0}if(Z.type===LX||Z.type===fV){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 pX=-1,PW=new DataView(new ArrayBuffer(0)),H0=new Uint8Array(PW.buffer);try{PW.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 vV=RangeError("Insufficient data"),P0=new xW;class $X{extensionCodec;context;useBigInt64;rawStrings;maxStrLength;maxBinLength;maxArrayLength;maxMapLength;maxExtLength;keyDecoder;mapKeyConverter;totalPos=0;pos=0;view=PW;bytes=H0;headByte=pX;stack=new $V;entered=!1;constructor(Z){this.extensionCodec=Z?.extensionCodec??ZX.defaultCodec,this.context=Z?.context,this.useBigInt64=Z?.useBigInt64??!1,this.rawStrings=Z?.rawStrings??!1,this.maxStrLength=Z?.maxStrLength??eZ,this.maxBinLength=Z?.maxBinLength??eZ,this.maxArrayLength=Z?.maxArrayLength??eZ,this.maxMapLength=Z?.maxMapLength??eZ,this.maxExtLength=Z?.maxExtLength??eZ,this.keyDecoder=Z?.keyDecoder!==void 0?Z.keyDecoder:P0,this.mapKeyConverter=Z?.mapKeyConverter??x0}clone(){return new $X({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=pX,this.stack.reset()}setBuffer(Z){let X=IX(Z);this.bytes=X,this.view=new DataView(X.buffer,X.byteOffset,X.byteLength),this.pos=0}appendBuffer(Z){if(this.headByte===pX&&!this.hasRemaining(1))this.setBuffer(Z);else{let X=this.bytes.subarray(this.pos),W=IX(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 ${fX(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: ${fX(Z)}`);this.complete();let W=this.stack;while(W.length>0){let V=W.top();if(V.type===HW)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===LX){if(X==="__proto__")throw new WZ("The key __proto__ is not allowed");V.key=this.mapKeyConverter(X),V.type=fV;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=LX;continue Z}}return X}}readHeadByte(){if(this.headByte===pX)this.headByte=this.readU8();return this.headByte}complete(){this.headByte=pX}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: ${fX(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 vV;let W=this.pos+X,V;if(this.stateIsMapKey()&&this.keyDecoder?.canBeCached(Z))V=this.keyDecoder.decode(this.bytes,W,Z);else V=DV(this.bytes,W,Z);return this.pos+=X+Z,V}stateIsMapKey(){if(this.stack.length>0)return this.stack.top().type===LX;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 vV;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=oV(this.view,this.pos);return this.pos+=8,Z}readI64(){let Z=nX(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 iW(Z,X){return new $X(X).decode(Z)}class gZ{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 bZ{getter;static eventName="update";emitter;constructor(Z){this.getter=Z;this.emitter=new gZ}get=()=>this.getter();async emit(){let Z=await this.getter();queueMicrotask(()=>this.emitter.emit(bZ.eventName,Z))}listen(Z){return this.emitter.addEventListener(bZ.eventName,Z),()=>{this.emitter.removeEventListener(bZ.eventName,Z)}}}var xZ=64;var qV=32,HZ=8;var qX=32;var aV=30000,_V=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"})(z||={});function d(Z){return[Z,0]}function Y(Z){return[void 0,Z]}function i0(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 d(new Uint8Array([0]));if(X.length>8)return Y(26);return d(new Uint8Array(X))}function U0(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 d({value:W>0x1fffffffffffffn?W:Number(W),bytesRead:l-X})}if(V+=7,V>=56)return Y(26)}}class P{data;pos=0;constructor(Z){this.data=Z}static async fromResponse(Z){let X=await Z.arrayBuffer(),W=new Uint8Array(X);return new P(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,d(Z)}readDate(){let[Z,X]=this.readVarInt();if(X!==0)return Y(X);return d(new Date(Z))}readVarInt(){let[Z,X]=U0(this.data,this.pos);if(X!==0)return Y(X);this.pos+=Z.bytesRead;let W=Z.value;return d(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 d(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,d(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 d(X)}readBytesSeq(Z){let X=[];while(!this.done()){let[W,V]=this.readBytes(Z);if(V!==0)return Y(V);X.push(W)}return d(X)}done(){return this.pos>=this.data.length}consumed(){return this.pos}}class i{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]=i0(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)}writeBytes(Z){this.parts.push(Z)}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}*scan(){for(let Z of this.parts)yield Z}}async function UW(Z,X){let W=new i,V=W.writeDate(X);if(V!==0)return Y(V);let l=W.result(),K=await Z.sign(l);return d({pubKey:Z.publicKey,sig:K,timestamp:X})}async function PZ(Z,X,W){let V=W.now().getTime(),l=Z.timestamp.getTime();if(Math.abs(V-l)>aV)return 4;let G=new i;G.writeDate(Z.timestamp);let m=G.result();if(!await X.checkSigEd25519(Z.sig,m,Z.pubKey))return 3;return 0}var _={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 d({id:X,ts:V})}};function XX(Z){let X=new i,W=X.writeStruct(_,Z);if(W!==0)return Y(W);let V=X.result();return d(V)}async function u0(Z){return XX({id:Z,ts:new Date(0)})}var YZ={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 P(X),[,l]=_.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[b,c]=Z.readBytes(qX);if(c!==0)return Y(c);F=b}return d({eid:X,off:K,ctr:m,len:J,hsh:F})}};function GZ(Z){return Array.from(Z).map((W)=>W.toString(16).padStart(2,"0")).join("")}function iZ(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 e(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 t;if(typeof Uint8Array.fromBase64==="function")t=(Z)=>Uint8Array.fromBase64(Z);else t=(Z)=>Uint8Array.from(atob(Z),(X)=>X.charCodeAt(0));function uW(Z){return g(Z).replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function OW(Z){let X=Z.length%4===0?"":"=".repeat(4-Z.length%4),W=Z.replace(/-/g,"+").replace(/_/g,"/")+X;return t(W)}function QX(Z,X){let W=new Uint8Array(Z.length+X.length);return W.set(Z,0),W.set(X,Z.length),W}function sV(Z,X,W){return W.checkSigEd25519(Z.sig,Z.headCph,X)}async function rV(Z,X,W,V){let l;if(Z.bod&&Z.len>0)l=await W.blake3(Z.bod);let K=new i,G=YZ.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),b=await X.sign(C);return d({sig:b,kdm:R,headCph:C,bodyCph:F})}async function jW(Z,X,W,V,l){let K=new P(Z),[G,m]=YZ.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 b=await V.blake3(R);if(!e(b,G.hsh))return Y(19)}let F=l??await V.blake3(Z);return d({msgHead:G,bod:R,headHash:F})}class pZ{now(){return new Date}}function tV(Z,X,W,V){let l=X.getTime()-Z.getTime(),K=W.getTime()-V.getTime();return(l+K)/2}var yX={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 d({quota:X,usage:V})}};var BW={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(yX,X.subscription.stat);if(G!==0)return G;let m=Z.writeStruct(yX,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[b,c]=Z.readStruct(yX);if(c!==0)return Y(c);let[k,T]=Z.readStruct(yX);if(T!==0)return Y(T);return d({status:V,timeRcvd:l,timeSent:G,subscription:{term:R,elapsed:C,stat:b,dyn:k}})}};var EW={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 d({headCph:X,seq:V})}};var mZ={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(qV);if(W!==0)return Y(W);let[V,l]=Z.readBytes(xZ);if(l!==0)return Y(l);let[K,G]=Z.readDate();if(G!==0)return Y(G);return d({pubKey:X,sig:V,timestamp:K})}};var eV={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(mZ,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(mZ);if(m!==0)return m;let R=await PZ(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[b,c]=X.readVarInt();if(c!==0)return c;if(!X.done())return 8;let[k,T]=await K.listHeads(J,b);if(T!==0)return T;return W.writeStructs(EW,k)},decodeResp(Z){return Z.readStructs(EW)}};var wW={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 d({seq:X,bodyCph:V})}};var Zl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(mZ,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(mZ);if(m!==0)return m;let R=await PZ(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 b=[];while(!X.done()){let[T,I]=X.readVarInt();if(I!==0)return I;b.push(T)}console.info(`PULL: ${b.length} bags`);let[c,k]=await K.getBodies(J,b);if(k!==0)return k;if(!c)return 17;for(let{seq:T,bodyCph:I}of c){let Q={seq:T,bodyCph:I},L=W.writeStruct(wW,Q);if(L!==0)return L}return 0},decodeResp(Z){return Z.readStructs(wW)}};var DW={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(xZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(HZ);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 d({sig:X,kdm:V,headCph:K,bodyCph:m})}};var aX={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 d({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(xZ);if(W!==0)return Y(W);let[V,l]=Z.readBytes(HZ);if(l!==0)return Y(l);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);return d({sig:X,kdm:V,headCph:K})}};var sX={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 d({idx:X,status:K});let[G,m]=Z.readVarInt();if(m!==0)return Y(m);return d({idx:X,status:K,seq:G})}};var Xl={async encodeReq(Z,X,W,V,l){let K=l.writeStruct(mZ,W);if(K!==0)return K;let G=l.writeStructs(DW,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(mZ);if(R!==0)return R;let J=await PZ(m,l,V);if(J!==0)return J;let{pubKey:C}=m,[F,b]=await K.hasUser(C);if(b!==0)return b;if(!F)return 5;let[c,k]=X.readStructs(DW);if(k!==0)return k;console.info(`PUSH: ${c.length} bags`);let T=[],I=[];for(let p=0;p<c.length;p++){let S=c[p];if(!await sV(S,C,l)){let j={idx:p,status:3},O=W.writeStruct(sX,j);if(O!==0)return O;continue}T.push(p),I.push(S)}let[Q,L]=await K.setBags(C,I);if(L!==0)return L;if(!Q||Q.length!==I.length)return 17;let M=[];for(let p=0;p<I.length;p++){let S=I[p],H=T[p],j=Q[p],O=new i,U=O.writeStruct(_X,S);if(U!==0)return U;let E=O.result(),y={seq:j,headCph:E};if(c.length===1&&S.bodyCph.length<=_V)y.bodyCph=S.bodyCph;M.push(y);let A={idx:H,status:0,seq:j},n=W.writeStruct(sX,A);if(n!==0)return n}if(M.length>0){let p=new i,S=p.writeStructs(aX,M);if(S!==0)return S;let H=p.result();await Promise.resolve(G.push(C,H))}return 0},decodeResp(Z){return Z.readStructs(sX)}};var Wl={async encodeReq(Z,X,W,V,l){return l.writeStruct(mZ,W)},async handleReq(Z,X,W){let{clock:V,crypto:l,storage:K}=Z,[G,m]=X.readStruct(mZ);if(m!==0)return m;let R=await PZ(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 d(void 0)}};class AW{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 i;K.writeStruct(mZ,Z);let G=K.result(),m=GZ(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 s={user:{path:"/user",endpoint:Wl,name:0},push:{path:"/push",endpoint:Xl,name:2},peek:{path:"/peek",endpoint:eV,name:1},pull:{path:"/pull",endpoint:Zl,name:3}},O0={0:s.user,2:s.push,1:s.peek,3:s.pull},aY={[s.user.path]:s.user,[s.push.path]:s.push,[s.peek.path]:s.peek,[s.pull.path]:s.pull};class oW{url;listener;constructor(Z){this.url=Z;this.listener=new AW(Z)}async call(Z,X){let{path:W}=O0[Z],V=new URL(W,this.url);try{return await j0(V,X)}catch{return Y(25)}}}var rX=(Z)=>{return new oW(Z.handle)};async function j0(Z,X){let W=await fetch(Z,{method:"POST",body:X.result().slice()});if(!W.ok)return Y(24);let V=await P.fromResponse(W);return d(V)}class tX{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 UW(G,m);if(J!==0)return Y(J);let C=new i,F=await l.encodeReq(this,G,R,X,C);if(F!==0)return Y(F);let b=W.now(),[c,k]=await V.call(K,C),T=W.now();if(k!==0)return Y(k);let[I,Q]=c.readStruct(BW);if(Q!==0)return Y(Q);if(I.status!==0)return Y(I.status);let M={clockOffset:tV(b,I.timeRcvd,I.timeSent,T),subscription:I.subscription},p=await this.updateHostMeta(M);if(p!==0)return Y(p);return l.decodeResp(c)}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 rV(Z,V,X,W)};register=()=>this.call(s.user,[]);peek=(Z)=>this.call(s.peek,[Z]);push=(Z)=>this.call(s.push,Z);pull=(Z)=>this.call(s.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 UW(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 nW={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(xZ);if(C!==0)return Y(C);return d({lbl:X,idx:V,num:K,hsh:m,sig:J})}};var vW={encode(Z,X){let W=Z.writeStruct(nW,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(nW);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 d({head:X,indexEnc:V,bodyEnc:K})}};var fW={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(HZ);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 d({kdm:X,headCph:V,lenBody:K,offBody:m})}};async function Vl(Z,X,W,V,l){let K=await l.deriveIdentity(Z,X),G=new i,m=new i,R=0,J=0;for(let Q of W){let L=new i,M=L.writeStruct(YZ,Q.head);if(M!==0)return Y(M);let p=L.result(),S=await K.kdmFor(p),H=l.deriveCipher(S,"encrypt"),j=await H.encrypt(p),O=Q.body?await H.encrypt(Q.body):new Uint8Array(0),U=Q.head.len>0&&Q.head.hsh!==void 0?O.length:0,E={kdm:S,headCph:j,lenBody:U,offBody:U>0?J:void 0},y=G.writeStruct(fW,E);if(y!==0)return Y(y);if(Q.body)m.writeBytes(O),J+=O.length;R++}let C=m.result(),F=G.result(),b=await V.blake3(F),c=await K.sign(b),k={lbl:Z,idx:X,num:R,hsh:b,sig:c},T=new i;T.writeStruct(vW,{head:k,indexEnc:F,bodyEnc:C});let I=T.result();return d(I)}async function ll(Z,X,W){let[V,l]=vW.decode(new P(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(!e(C,K.hsh))return Y(19);let F=new P(G),b=[];for(let k=0;k<K.num;k++){let[T,I]=F.readStruct(fW);if(I!==0)return Y(I);b.push(T)}if(b.length!==K.num)return Y(14);let c=[];for(let k of b){let T=W.deriveCipher(k.kdm,"decrypt"),I;try{I=await T.decrypt(k.headCph)}catch{return Y(20)}let[Q,L]=YZ.decode(new P(I));if(L!==0)return Y(L);let M;if(k.lenBody>0&&k.offBody!==void 0){if(Q.hsh===void 0)return Y(14);let p=m.slice(k.offBody,k.offBody+k.lenBody);try{M=await T.decrypt(p)}catch{return Y(20)}let S=await X.blake3(M);if(!e(S,Q.hsh))return Y(19)}c.push({head:Q,body:M})}return d(c)}async function Kl({now:Z,bod:X,crypto:W}){let V=await W.genRandomBytes(8),l=new i,K=l.writeStruct(_,{id:V,ts:Z});if(K!==0)return Y(K);let G=l.result();return eX({now:Z,eid:G,ctr:0,bod:X,crypto:W})}async function eX({now:Z,eid:X,ctr:W,bod:V,crypto:l}){let K=new P(X),[G,m]=_.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 d({eid:X,off:R,ctr:W,len:C,hsh:J})}function Gl(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 WX(Z,X){let W=Array.from(Z);W.sort(Gl);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 ml(Z){let X=new i,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 d(X.result())}async function MX(Z,X){let W=[];for(let V of Z){let[l,K]=ml(V);if(K!==0||!l)return Y(K);W.push(l)}return d(await WX(W,X))}var AR=Symbol("MasterSeed"),oR=Symbol("SealedMasterKey"),dZ=32,$W=24+dZ+16;function ZZ(Z){if(Z.byteLength!==dZ)return Y(10);return d(Z)}function LZ(Z){if(Z.byteLength!==$W)return Y(10);return d(Z)}var vR=Symbol("EntityID");function Yl(Z){return"type"in Z}var fR=Symbol("DerivationSeed"),$R=Symbol("PublicKey"),qR=Symbol("PrivateKey"),aR=Symbol("HostSpecificKeyPair"),_R=Symbol("Hash");function B0(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 E0(Z){if(!Z.bod||Z.bod.length===0){let V={off:Z.off,ctr:Z.ctr,eid:Z.eid};return d(V)}let X=iW(Z.bod);if(B0(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 d(W)}class zX{applier;emitter=new gZ;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]=E0(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 qW={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 f="entities",ZW="entity_type_created_at",_W="entity_type_updated_at",sW="entity_type_group_id",rW="entity_type_parent_id",VX="entity_tags",Rl="db",Jl=13;function w0(Z){return"typ"in Z}function D0(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 A0(Z){if(!D(Z))return{eid:g(Z.eid),upd:Z.updatedAt,...Z.ctr!==0?{ctr:Z.ctr}:{}};return D0(Z)}function lX(Z){return{body:Z.bod,createdAt:Z.crd,updatedAt:Z.upd,ctr:Z.ctr??0,type:Z.typ,eid:t(Z.eid),gid:Z.gid,pid:Z.pid?t(Z.pid):void 0,...Z.tgs!==void 0?{tags:Z.tgs}:{}}}function aW(Z){if(w0(Z))return lX(Z);return{eid:t(Z.eid),updatedAt:Z.upd,ctr:Z.ctr??0}}class tW{db;opening;async init(){await this.ensureDb()}async ensureDb(){if(this.db)return this.db;if(this.opening)return this.opening;return this.opening=n0().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(f,"readwrite"),K=l.objectStore(f);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),b={op:C,index:J},c=R.get(F);if(c)c.push(b);else R.set(F,[b])}for(let[J,C]of R){if(C.length<1)continue;let F=K.get(J);F.onsuccess=()=>{let b=F.result,c=b?aW(b):void 0,k=!1;for(let{op:T,index:I}of C){let[Q,L]=KX(c,T);if(L!==0){m[I]=L;continue}if(Q===void 0){m[I]=12;continue}k=!0;for(let M of GX(c,Q))X.add(M);c=Q}if(k)W.push(C[0].op.eid);if(c){let T=K.put(A0(c));T.onerror=(I)=>{I.preventDefault();for(let{index:Q}of C)m[Q]=18}}},F.onerror=()=>{for(let{index:b}of C)m[b]=18}}})};async clear(){let Z;try{Z=await this.ensureDb()}catch{return 16}let X=Z.transaction(f,"readwrite"),W=X.objectStore(f);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(f,"readonly").objectStore(f);return new Promise((K)=>{let G=l.get(W);G.onsuccess=()=>{let m=G.result;if(!m)K(d(void 0));else K(d(aW(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||!D(X))return d(void 0);return d(X)}async getAllOfTypeUpdatedBetween(Z,X,W){let V;try{V=await this.ensureDb()}catch{return Y(16)}let K=V.transaction(f,"readonly").objectStore(f).index(_W);return new Promise((G)=>{let m=K.getAll(IDBKeyRange.bound([Z,X],[Z,W]));m.onsuccess=()=>{let R=m.result;G(d(R.map(lX)))},m.onerror=()=>G(Y(18))})}async getGroupMembers(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(f,"readonly").objectStore(f).index(sW);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z,X]));G.onsuccess=()=>{let m=G.result;K(d(m.map(lX)))},G.onerror=()=>K(Y(18))})}async getAllOfType(Z){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(f,"readonly").objectStore(f).index(ZW);return new Promise((l)=>{let K=V.getAll(IDBKeyRange.bound([Z],[Z,[]]));K.onsuccess=()=>{let G=K.result;l(d(G.map(lX)))},K.onerror=()=>l(Y(18))})}async getByTag(Z,X){let W;try{W=await this.ensureDb()}catch{return Y(16)}let l=W.transaction(f,"readonly").objectStore(f).index(VX);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only(X));G.onsuccess=()=>{let R=G.result.filter((J)=>J.typ===Z).map(lX);K(d(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(f,"readonly").objectStore(f).index(rW);return new Promise((K)=>{let G=l.getAll(IDBKeyRange.only([Z.type,W]));G.onsuccess=()=>{let R=G.result.map(lX);K(d(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 d(X)}async countEntities({type:Z}){let X;try{X=await this.ensureDb()}catch{return Y(16)}let V=X.transaction(f,"readonly").objectStore(f).index(ZW);return new Promise((l)=>{let K=IDBKeyRange.bound([Z],[Z,[]]),G=V.count(K);G.onsuccess=()=>l(d(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(f,"readonly").objectStore(f),l=[];return new Promise((K)=>{let G=V.openCursor();G.onsuccess=()=>{let m=G.result;if(m){let R=m.value;l.push(hX(aW(R))),m.continue()}else MX(l,Z).then(K)},G.onerror=()=>K(Y(18))})}}function o0(Z,X){if(!Z.objectStoreNames.contains(f))Z.createObjectStore(f,{keyPath:"eid",autoIncrement:!1});let W=X.objectStore(f);if(!W.indexNames.contains(ZW))W.createIndex(ZW,["typ","crd"],{unique:!1});if(!W.indexNames.contains(_W))W.createIndex(_W,["typ","upd"],{unique:!1});if(!W.indexNames.contains(sW))W.createIndex(sW,["typ","gid"],{unique:!1});if(!W.indexNames.contains(rW))W.createIndex(rW,["typ","pid"],{unique:!1});if(W.indexNames.contains(VX)){if(W.index(VX).keyPath!=="tgs")W.deleteIndex(VX)}if(!W.indexNames.contains(VX))W.createIndex(VX,"tgs",{unique:!1,multiEntry:!0})}function n0(){return new Promise((Z,X)=>{let W=indexedDB.open(Rl,Jl);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!l){X(Error("Transaction is null during EntDB upgrade"));return}try{o0(V,l)}catch(K){X(K instanceof Error?K:Error(String(K)))}},W.onblocked=()=>{console.warn(`[DIPLOMATIC] EntDB IDB upgrade blocked (${Rl} → v${Jl}); waiting for other connections to close`)},W.onsuccess=()=>Z(W.result),W.onerror=()=>X(W.error??Error("EntDB IndexedDB open failed"))})}async function Cl(){let Z=new tW;return await Z.init(),Z}class XW{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&&D(W))this.unindex(X,W);if(this.ents.set(X,Z),D(Z))this.index(X,Z)}del(Z){let X=this.ents.get(Z);if(X===void 0)return;if(D(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]=KX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of GX(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 d(W)}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!D(X))return d(void 0);return d(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 d(this.bucketList(this.byTypePid.get(Z)?.get(G)))}if(X!==void 0)return d(this.bucketList(this.byTypeGid.get(Z)?.get(X)));if(V!==void 0)return d(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 d(G)}return d(this.bucketList(this.byType.get(Z)))}let K=[];if(W!==void 0){for(let G of this.ents.values())if(D(G)&&G.type===Z&&G.pid&&e(G.pid,W))K.push(G)}else if(X!==void 0){for(let G of this.ents.values())if(D(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(D(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(D(G)&&G.type===Z&&G.updatedAt>=l.start&&G.updatedAt<=l.end)K.push(G)}else for(let G of this.ents.values())if(D(G)&&G.type===Z)K.push(G);return d(K)}async getEntities(Z){let[X,W]=await this.getAllEntities(Z);if(W!==0)return Y(W);return d(X)}async countEntities({type:Z}){if(this.useIndex)return d(this.byType.get(Z)?.size??0);let X=0;for(let W of this.ents.values())if(D(W)&&W.type===Z)X+=1;return d(X)}async checksum(Z){let X=[];for(let W of this.ents.values())X.push(hX(W));return MX(X,Z)}}async function eW(Z){let X=await Cl();if(Z?.cache===!1)return X;return new SX(X,void 0,{indexes:Z?.indexes})}class SX{mem;durable;warmed=new Set;listeners=new Set;chain=Promise.resolve();constructor(Z,X,W){if(this.durable=Z,this.mem=new XW(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=_0(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||!v0(K,G)){if(D(G))X.add(G.type);if(K!==void 0&&D(K))X.add(K.type)}}else if(K!==void 0){if(this.mem.del(l),D(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||a0(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 d(W)})}async getEnt(Z){let[X,W]=await this.getRow(Z);if(W!==0)return Y(W);if(X===void 0||!D(X))return d(void 0);return d(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 v0(Z,X){if(D(Z)!==D(X))return!1;if(Z.ctr!==X.ctr)return!1;if(Z.updatedAt.getTime()!==X.updatedAt.getTime())return!1;if(!e(Z.eid,X.eid))return!1;if(!D(Z)||!D(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(!$0(Z.pid,X.pid))return!1;if(!f0(Z.tags,X.tags))return!1;return q0(Z.body,X.body)}function f0(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 $0(Z,X){if(Z===void 0&&X===void 0)return!0;if(Z===void 0||X===void 0)return!1;return e(Z,X)}function q0(Z,X){if(Object.is(Z,X))return!0;if(Z instanceof Uint8Array&&X instanceof Uint8Array)return e(Z,X);if(Z instanceof Date&&X instanceof Date)return Z.getTime()===X.getTime();try{return e(AZ(Z),AZ(X))}catch{return!1}}function a0(Z,X){let W=Z.updatedAt.getTime(),V=X.updatedAt.getTime();if(W!==V)return W>V;return Z.ctr>X.ctr}function _0(Z,X){let W=new Set,V=[];for(let l of X){let K=g(l.eid),G=Z.ents.get(K),[m,R]=KX(G,l);if(R!==0){V.push(R);continue}if(m===void 0){V.push(12);continue}for(let J of GX(G,m))W.add(J);Z.put(m),V.push(0)}return{stats:V,types:W}}function WW(Z){if(Z instanceof SX){let X=new zX((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 zX((X)=>Z.apply(X),()=>Z.clear())}function D(Z){return"type"in Z}function s0(Z){return!D(Z)}function Fl(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 hX(Z){return{eid:Z.eid,ctr:Z.ctr,updatedAt:Z.updatedAt}}function ZV(Z){let X=new P(Z.eid),[W,V]=X.readStruct(_);if(V!==0)return Y(V);return d({eid:Z.eid,ctr:Z.ctr,updatedAt:new Date(W.ts.getTime()+Z.off)})}function KX(Z,X){let W=new P(X.eid),[V,l]=W.readStruct(_);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(Yl(X)){let G=Fl(X.tags);return d({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 d({eid:X.eid,updatedAt:K,ctr:X.ctr})}function GX(Z,X){let W=new Set;if(Z!==void 0&&D(Z))W.add(Z.type);if(D(X))W.add(X.type);return[...W]}var r0={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 VW{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 lW=100;class NX{timer=null;delayMs;work;tail=new VW;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 dl(Z){let X=new P(Z.eid),[W,V]=_.decode(X);if(V!==0)return;return W.ts.getTime()+Z.off}function t0(Z,X){let W=dl(Z),V=dl(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 mX(Z,X){return Z.slice().sort((W,V)=>t0(X(W),X(V)))}var oZ={phase:"idle"},YX=50;function KW(Z,X,W){if(Z<=0||X<=0)return!1;if(Z===1||Z===X)return!0;return Z%W===0}function GW(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 bl(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 XV(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 mW(Z,X,W,V){let l=new P(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"),b;try{b=await F.decrypt(J)}catch{return Y(20)}return d({kdm:R,headEnc:b})}var QZ="f",UZ="t",cZ="e";function e0(Z){return Z===QZ||Z===UZ||Z===cZ}function RX(Z){if(Z===!0||Z===UZ)return UZ;if(Z===cZ)return cZ;return QZ}function ZK(Z){return RX(Z.apld)===QZ}function WV(Z){return Z!==0&&Z!==15&&Z!==18&&Z!==17}function nZ(Z,X,W){if(Z.apld=X,X===cZ&&W!==void 0)Z.err=W;else delete Z.err}async function uZ(Z,X,W,V){let l=V?.body!==!1,K=RX(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===cZ&&X.err!==void 0)C.err=X.err;return C}var VV=1048576,lV=1048576,kl=64;function XK(Z){return Z.sig.length+Z.kdm.length+Z.headCph.length+Z.bodyCph.length}async function WK(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,b)=>F-b);for(let F of C)if(F===R+1)R=F;if(R>J)await X.hosts.touch(W,R)}return 0}async function cl(Z,X){if(X.length<1)return d([]);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 d(G)}async function VK(Z,X,W,V){if(V.length<1)return d({parts:[],hashes:[]});let l=[],K=[],G=[],m=new Map;for(let{dl:J,bodyCph:C}of V){let{head:F,kdm:b,seq:c,host:k}=J,[T,I]=await Tl(J,W);if(I!==0||!T){let U=m.get(k)??[];U.push(c),m.set(k,U);continue}let{headEnc:Q,headEncHash:L}=T,M=X.deriveCipher(b,"decrypt"),[p,S]=await jW(Q,C,M,W,L);if(S!==0||!p){let U=m.get(k)??[];U.push(c),m.set(k,U);continue}let H={head:F,body:p.bod},j=p.headHash;G.push({key:j,data:Ll(H)}),l.push(H),K.push(j);let O=m.get(k)??[];O.push(c),m.set(k,O)}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 d({parts:l,hashes:K})}async function Tl(Z,X){let W=Z.headEnc;if(!W){let l=new i,K=l.writeStruct(YZ,Z.head);if(K!==0)return Y(K);W=l.result()}if(Z.headEncHash)return d({headEnc:W,headEncHash:Z.headEncHash});let V=await X.blake3(W);return d({headEnc:W,headEncHash:V})}async function Il(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 Tl(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 KV({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 b=C.length,c=G??YX,k=m??kl;if(K&&b>0)K({phase:"peek",host:V.label,done:0,total:b});let T=0,I=await XV(C,k,async(L)=>{let[M,p]=await mW(L,R.publicKey,W,l),S;if(p!==0||!M)S={ok:!1,seq:L.seq,stat:p};else{let H=await l.blake3(M.headEnc);S={ok:!0,seq:L.seq,kdm:M.kdm,headEnc:M.headEnc,headEncHash:H}}if(T+=1,K&&KW(T,b,c))K({phase:"peek",host:V.label,done:T,total:b});return S}),Q=new Set;for(let L of I){if(!L.ok){console.error("peek: decrypting item head",L.stat);continue}let M=g(L.headEncHash);if(await X.messages.has(L.headEncHash)){console.info("peek: local msg; skip download, deq upload"),await X.uploads.deq(V.label,[L.headEncHash]),await X.downloads.deq(V.label,[L.seq]);continue}if(Q.has(M)){await X.downloads.deq(V.label,[L.seq]);continue}let S=new P(L.headEnc),[H,j]=S.readStruct(YZ);if(j!==0){console.error("peek: reading item head",j);continue}Q.add(M),J.push({kdm:L.kdm,head:H,seq:L.seq,host:V.label,headEnc:L.headEnc,headEncHash:L.headEncHash})}if(await X.downloads.enq(J),C.length>0){let L=Math.max(...C.map((M)=>M.seq));await X.hosts.recordStats(V.label,{lastSeq:L})}if(K)K({phase:"peek",host:V.label,done:b,total:b});return 0}async function pl({conn:Z,store:X,host:W,maxPushBytes:V,onProgress:l}){let K=V??VV,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,b=async()=>{if(J.length<1)return 0;let c=J.length,k=await WK(Z,X,W.label,J,C);if(J=[],C=[],F=0,k===0){if(R+=c,l)l({phase:"push",host:W.label,done:R,total:m})}return k};for(let c of G){let k=await X.messages.get(c);if(!k){R+=1;continue}let T={...k.head,bod:k.body},[I,Q]=await Z.seal(T);if(Q!==0)return Q;if(!I)return 12;let L=XK(I);if(J.length>0&&F+L>K){let M=await b();if(M!==0)return M}if(J.push(I),C.push(c),F+=L,F>=K){let M=await b();if(M!==0)return M}}return b()}async function GV({conn:Z,store:X,enclave:W,host:V,crypto:l,maxPullBytes:K,onProgress:G},m){let R=K??lV,J=await X.downloads.list(),C=Array.from(J).filter((I)=>I.host===V.label);if(C.length<1)return 15;let F=mX(C,(I)=>I.head),b=bl(F,(I)=>I.head.len,R),c=F.length,k=0;if(G)G({phase:"pull",host:V.label,done:0,total:c});let T=cl(Z,b[0]);for(let I=0;I<b.length;I++){let[Q,L]=await T;if(L!==0||!Q)return L;if(k+=b[I].length,G)G({phase:"pull",host:V.label,done:k,total:c});let M=b[I+1];if(M)T=cl(Z,M);if(G)G({phase:"open",host:V.label,done:k,total:c});let p=mX(Q,(H)=>H.dl.head),[,S]=await VK(X,W,l,p);if(S!==0)return S;if(m){if(G)G({phase:"exec",host:V.label,done:k,total:c});await m()}}return 0}function Ll({head:Z,body:X}){let W={eid:Z.eid,body:X,apld:QZ};if(Z.off!==0)W.off=Z.off;if(Z.ctr!==0)W.ctr=Z.ctr;return W}async function Ql(Z,{conn:X,store:W,enclave:V,host:l,crypto:K,onProgress:G},m){let R=l.label,J=await X.identity(),C=new P(Z),[F,b]=C.readStructs(aX);if(b!==0){console.error("Failed decoding notif",z[b]);return}let c=!1,T=(await W.hosts.get(R))?.lastSeq,I=[],Q=!1;for(let p of F){let[S,H]=await mW({seq:p.seq,headCph:p.headCph},J.publicKey,V,K);if(H!==0){console.error("Failed decrypting notif",z[H]);continue}let j=await K.blake3(S.headEnc);if(await W.messages.has(j))continue;let O=new P(S.headEnc),[U,E]=O.readStruct(YZ);if(E!==0){console.error("Failed to parse head",z[E]);continue}if(!p.bodyCph&&U.len>0)Q=!0,await W.downloads.enq([{seq:p.seq,host:R,kdm:S.kdm,head:U,headEnc:S.headEnc,headEncHash:j}]);else I.push({...S,head:U,bodyCph:p.bodyCph,headEncHash:j});if(T===void 0||p.seq!==T+1)console.log("out of seq",p.seq,T),c=!0;else T=p.seq}if(T!==void 0)await W.hosts.touch(l.label,T);let L=[];for(let p of I){let S=V.deriveCipher(p.kdm,"decrypt"),[H,j]=await jW(p.headEnc,p.bodyCph,S,K);if(j!==0){console.error("Failed to open body",z[j]);continue}L.push({key:p.headEncHash,data:Ll({head:p.head,body:H.bod})})}let M=await W.messages.add(L);for(let p=0;p<M.length;p++){let S=M[p];if(S!==0&&S!==15)console.error("ERR storing",z[S],"for message",p)}if(G&&L.length>0)G({phase:"open",host:l.label,done:L.length,total:L.length});if(c||Q||L.length>0)m()}async function mV(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,b=await l.identity(),[c,k]=await l.peek(0);if(k!==0)return Y(k);let T=c.length,I=C??YX,Q=F??kl;if(J&&T>0)J({phase:"peek",host:m.label,done:0,total:T});let L=0,M=await XV(c,Q,async(x)=>{let[B,u]=await mW(x,b.publicKey,G,R),w;if(u!==0||!B)w={ok:!1,seq:x.seq,stat:u};else{let N=await R.blake3(B.headEnc);w={ok:!0,seq:x.seq,kdm:B.kdm,headEnc:B.headEnc,headEncHash:N}}if(L+=1,J&&KW(L,T,I))J({phase:"peek",host:m.label,done:L,total:T});return w}),p=new Map;for(let x of M){if(!x.ok)continue;let B=g(x.headEncHash),u=p.get(B);if(u)u.count+=1;else p.set(B,{hash:x.headEncHash,count:1,sample:x})}let S=0,H=[];for(let x of p.values()){if(x.count>1)S+=x.count-1;H.push(x.hash)}let j=c.length,O=p.size,U=await WX(H,R),E=[],y=0;for(let x of p.values()){if(await K.messages.has(x.hash)){await K.uploads.deq(m.label,[x.hash]);continue}if(y+=1,!W)continue;let u=x.sample,w=new P(u.headEnc),[N,q]=w.readStruct(YZ);if(q!==0){console.error("reconcile: reading msg header",q);continue}E.push({kdm:u.kdm,head:N,seq:u.seq,host:m.label,headEnc:u.headEnc,headEncHash:u.headEncHash})}if(E.length>0)await K.downloads.enq(E);let A=0;if(V){let x=await K.messages.listKeys(),B=new Set(p.keys()),u=[];for(let w of x)if(!B.has(g(w)))A+=1,u.push(w);if(u.length>0)await K.uploads.enq(m.label,u)}else{let x=await K.messages.listKeys(),B=new Set(p.keys());for(let u of x)if(!B.has(g(u)))A+=1}let n=c.length>0?Math.max(...c.map((x)=>x.seq)):0;if(await K.hosts.recordStats(m.label,{setLastSeq:n}),J)J({phase:"peek",host:m.label,done:T,total:T});return d({msgcheck:U,numBags:j,uniqueMsgs:O,numDupes:S,missingLocal:y,missingHost:A})}class vZ{clock;state;store;transport;crypto;forceSkewHandlingByDefault;onScheduleSync;connections=new Map;applyChain=Promise.resolve();syncRuns=new VW;clientState;xferState;maxPushBytes;maxPullBytes;peekProgressEvery=YX;lastProgress=oZ;scheduledSync;constructor(Z,X,W,V,l,K=!0,G=VV,m=lV,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 bZ(()=>this.getClientState()),this.xferState=new bZ(()=>this.getXferState()),this.scheduledSync=new NX(lW,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 i;m.writeStruct(YZ,K);let R=m.result(),J=await this.crypto.blake3(R),C={eid:K.eid,body:G,apld:QZ};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 Il(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:QZ});if(Z.length<1)return[];let X=mX(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&&WV(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 Kl({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 d(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 eX({now:l,eid:Z.eid,ctr:K,bod:X,crypto:V});if(m!==0)return Y(m);return d({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 P(Z.eid),[m,R]=G.readStruct(_);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},b=(await this.apply([{head:C,body:void 0}]))[0];if(b!==0&&b!==15)return Y(b??12);if(X===void 0)return d(C);let[c,k]=XX({id:m.id,ts:K});if(k!==0)return Y(k);let[T,I]=await eX({now:K,eid:c,ctr:0,bod:X,crypto:l});if(I!==0)return Y(I);let L=(await this.apply([{head:T,body:X}]))[0];if(L!==0&&L!==15)return Y(L??12);return d(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 d(V.head)})}async insert(Z){let{body:X,type:W,gid:V,pid:l,tags:K}=Z,m=AZ({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=AZ({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 ZV(X.head);let W=new P(Z),[V,l]=W.readStruct(_);if(l!==0)return Y(l);return d({eid:Z,ctr:-1,updatedAt:V.ts})}async genEID(Z){let{clock:X,crypto:W}=this,V=X.now();if(Z!==void 0)return XX({id:Z,ts:V});let l=await W.genRandomBytes(8);return XX({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 KV(m);if(R!==0)return console.error(`Failed to peek: ${R}`),this.emitProgress({phase:"idle"}),R;this.xferState.emit();let J=await pl(m);if(J!==0)return console.error(`Failed to push: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await GV(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 WX(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 mV({...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"}),d(J);let F=await this.sync();if(F!==0)return Y(F);let b=await l.hosts.get(Z);if(!b)return Y(13);let[c,k]=await mV({...R,host:b},{pull:!1,push:!1});if(this.xferState.emit(),this.emitProgress({phase:"idle"}),k!==0)return Y(k);if(!c)return Y(12);return d(c)}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 KV(R);if(J!==0)return console.error(`rebuild: failed to peek: ${J}`),this.emitProgress({phase:"idle"}),J;this.xferState.emit();let C=await GV(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=mX(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=oZ,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 ll(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,b=J;for(let T=J;T<m.length&&F<100&&C<102400;T++)C+=m[T].head.len,F++,b=T+1;let c=m.slice(J,b);console.time(`import: applying [${J}, ${b}]`);let k=await this.apply(c,{enqueueUpload:!0,triggerUpload:!1});console.timeEnd(`import: applying [${J}, ${b}]`);for(let T=0;T<c.length;T++){let I=k[T];if(I!==0&&I!==15)console.warn(`failed to import msg ${J+T}: ${z[I]}`)}if(l)queueMicrotask(()=>l(b,m.length,0));this.emitProgress({phase:"import",done:b,total:m.length}),J=b}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 Vl("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 GW(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 tX(J,K,Z,V,m(Z),(F)=>G.hosts.set(Z.label,F));if(await C.register(),X)await C.listen(async(F)=>{let b={conn:C,store:G,enclave:J,host:Z,crypto:K,maxPushBytes:this.maxPushBytes,maxPullBytes:this.maxPullBytes,onProgress:this.emitProgress,peekProgressEvery:this.peekProgressEvery};return Ql(F,b,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 YW(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function YV(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function a(Z,...X){if(!YV(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 RV(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 yl(Z,X){a(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function JV(Z){if(typeof Z!=="boolean")throw Error(`boolean expected, not ${Z}`)}/*! noble-ciphers - MIT License (c) 2023 Paul Miller (paulmillr.com) */var yZ=(Z)=>new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4));var lK=new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68;if(!lK)throw Error("Non little-endian hardware is not supported");function KK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function RW(Z){if(typeof Z==="string")Z=KK(Z);else if(YV(Z))Z=JW(Z);else throw Error("Uint8Array expected, got "+typeof Z);return Z}function Ml(Z,X){if(X==null||typeof X!=="object")throw Error("options must be defined");return Object.assign(Z,X)}function zl(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 hl=(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 CV(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 JW(Z){return Uint8Array.from(Z)}function kZ(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function CW(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 Nl=(Z)=>Uint8Array.from(Z.split("").map((X)=>X.charCodeAt(0))),mK=Nl("expand 16-byte k"),YK=Nl("expand 32-byte k"),RK=yZ(mK),JK=yZ(YK);function h(Z,X){return Z<<X|Z>>>32-X}function FV(Z){return Z.byteOffset%4===0}var FW=64,CK=16,gl=4294967295,Sl=new Uint32Array;function FK(Z,X,W,V,l,K,G,m){let R=l.length,J=new Uint8Array(FW),C=yZ(J),F=FV(l)&&FV(K),b=F?yZ(l):Sl,c=F?yZ(K):Sl;for(let k=0;k<R;G++){if(Z(X,W,V,C,G,m),G>=gl)throw Error("arx: counter overflow");let T=Math.min(FW,R-k);if(F&&T===FW){let I=k/4;if(k%4!==0)throw Error("arx: invalid block position");for(let Q=0,L;Q<CK;Q++)L=I+Q,c[L]=b[L]^C[Q];k+=FW;continue}for(let I=0,Q;I<T;I++)Q=k+I,K[Q]=l[Q]^J[I];k+=T}}function xl(Z,X){let{allowShortKeys:W,extendNonceFn:V,counterLength:l,counterRight:K,rounds:G}=Ml({allowShortKeys:!1,counterLength:8,counterRight:!1,rounds:20},X);if(typeof Z!=="function")throw Error("core must be a function");return YW(l),YW(G),JV(K),JV(W),(m,R,J,C,F=0)=>{a(m),a(R),a(J);let b=J.length;if(C===void 0)C=new Uint8Array(b);if(a(C),YW(F),F<0||F>=gl)throw Error("arx: counter overflow");if(C.length<b)throw Error(`arx: output (${C.length}) is shorter than data (${b})`);let c=[],k=m.length,T,I;if(k===32)c.push(T=JW(m)),I=JK;else if(k===16&&W)T=new Uint8Array(32),T.set(m),T.set(m,16),I=RK,c.push(T);else throw Error(`arx: invalid 32-byte key, got length=${k}`);if(!FV(R))c.push(R=JW(R));let Q=yZ(T);if(V){if(R.length!==24)throw Error("arx: extended nonce must be 24 bytes");V(I,Q,yZ(R.subarray(0,16)),Q),R=R.subarray(16)}let L=16-l;if(L!==R.length)throw Error(`arx: nonce must be ${L} or 16 bytes`);if(L!==12){let p=new Uint8Array(12);p.set(R,K?0:12-R.length),R=p,c.push(R)}let M=yZ(R);return FK(Z,I,Q,M,J,C,F,G),kZ(...c),C}}var r=(Z,X)=>Z[X++]&255|(Z[X++]&255)<<8;class Hl{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=RW(Z),a(Z,32);let X=r(Z,0),W=r(Z,2),V=r(Z,4),l=r(Z,6),K=r(Z,8),G=r(Z,10),m=r(Z,12),R=r(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]=r(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],b=K[6],c=K[7],k=K[8],T=K[9],I=r(Z,X+0),Q=r(Z,X+2),L=r(Z,X+4),M=r(Z,X+6),p=r(Z,X+8),S=r(Z,X+10),H=r(Z,X+12),j=r(Z,X+14),O=l[0]+(I&8191),U=l[1]+((I>>>13|Q<<3)&8191),E=l[2]+((Q>>>10|L<<6)&8191),y=l[3]+((L>>>7|M<<9)&8191),A=l[4]+((M>>>4|p<<12)&8191),n=l[5]+(p>>>1&8191),x=l[6]+((p>>>14|S<<2)&8191),B=l[7]+((S>>>11|H<<5)&8191),u=l[8]+((H>>>8|j<<8)&8191),w=l[9]+(j>>>5|V),N=0,q=N+O*G+U*(5*T)+E*(5*k)+y*(5*c)+A*(5*b);N=q>>>13,q&=8191,q+=n*(5*F)+x*(5*C)+B*(5*J)+u*(5*R)+w*(5*m),N+=q>>>13,q&=8191;let XZ=N+O*m+U*G+E*(5*T)+y*(5*k)+A*(5*c);N=XZ>>>13,XZ&=8191,XZ+=n*(5*b)+x*(5*F)+B*(5*C)+u*(5*J)+w*(5*R),N+=XZ>>>13,XZ&=8191;let KZ=N+O*R+U*m+E*G+y*(5*T)+A*(5*k);N=KZ>>>13,KZ&=8191,KZ+=n*(5*c)+x*(5*b)+B*(5*F)+u*(5*C)+w*(5*J),N+=KZ>>>13,KZ&=8191;let v=N+O*J+U*R+E*m+y*G+A*(5*T);N=v>>>13,v&=8191,v+=n*(5*k)+x*(5*c)+B*(5*b)+u*(5*F)+w*(5*C),N+=v>>>13,v&=8191;let IZ=N+O*C+U*J+E*R+y*m+A*G;N=IZ>>>13,IZ&=8191,IZ+=n*(5*T)+x*(5*k)+B*(5*c)+u*(5*b)+w*(5*F),N+=IZ>>>13,IZ&=8191;let qZ=N+O*F+U*C+E*J+y*R+A*m;N=qZ>>>13,qZ&=8191,qZ+=n*G+x*(5*T)+B*(5*k)+u*(5*c)+w*(5*b),N+=qZ>>>13,qZ&=8191;let aZ=N+O*b+U*F+E*C+y*J+A*R;N=aZ>>>13,aZ&=8191,aZ+=n*m+x*G+B*(5*T)+u*(5*k)+w*(5*c),N+=aZ>>>13,aZ&=8191;let _Z=N+O*c+U*b+E*F+y*C+A*J;N=_Z>>>13,_Z&=8191,_Z+=n*R+x*m+B*G+u*(5*T)+w*(5*k),N+=_Z>>>13,_Z&=8191;let sZ=N+O*k+U*c+E*b+y*F+A*C;N=sZ>>>13,sZ&=8191,sZ+=n*J+x*R+B*m+u*G+w*(5*T),N+=sZ>>>13,sZ&=8191;let rZ=N+O*T+U*k+E*c+y*b+A*F;N=rZ>>>13,rZ&=8191,rZ+=n*C+x*J+B*R+u*m+w*G,N+=rZ>>>13,rZ&=8191,N=(N<<2)+N|0,N=N+q|0,q=N&8191,N=N>>>13,XZ+=N,l[0]=q,l[1]=XZ,l[2]=KZ,l[3]=v,l[4]=IZ,l[5]=qZ,l[6]=aZ,l[7]=_Z,l[8]=sZ,l[9]=rZ}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;kZ(W)}update(Z){RV(this);let{buffer:X,blockLen:W}=this;Z=RW(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(){kZ(this.h,this.r,this.buffer,this.pad)}digestInto(Z){RV(this),yl(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 dK(Z){let X=(V,l)=>Z(l).update(RW(V)).digest(),W=Z(new Uint8Array(32));return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var dV=dK((Z)=>new Hl(Z));function bK(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],b=W[0],c=W[1],k=l,T=0,I=Z[2],Q=X[4],L=X[5],M=X[6],p=X[7],S=Z[3],H=G,j=m,O=R,U=J,E=C,y=F,A=b,n=c,x=k,B=T,u=I,w=Q,N=L,q=M,XZ=p,KZ=S;for(let IZ=0;IZ<K;IZ+=2)E^=h(H+N|0,7),x^=h(E+H|0,9),N^=h(x+E|0,13),H^=h(N+x|0,18),B^=h(y+j|0,7),q^=h(B+y|0,9),j^=h(q+B|0,13),y^=h(j+q|0,18),XZ^=h(u+A|0,7),O^=h(XZ+u|0,9),A^=h(O+XZ|0,13),u^=h(A+O|0,18),U^=h(KZ+w|0,7),n^=h(U+KZ|0,9),w^=h(n+U|0,13),KZ^=h(w+n|0,18),j^=h(H+U|0,7),O^=h(j+H|0,9),U^=h(O+j|0,13),H^=h(U+O|0,18),A^=h(y+E|0,7),n^=h(A+y|0,9),E^=h(n+A|0,13),y^=h(E+n|0,18),w^=h(u+B|0,7),x^=h(w+u|0,9),B^=h(x+w|0,13),u^=h(B+x|0,18),N^=h(KZ+XZ|0,7),q^=h(N+KZ|0,9),XZ^=h(q+N|0,13),KZ^=h(XZ+q|0,18);let v=0;V[v++]=G+H|0,V[v++]=m+j|0,V[v++]=R+O|0,V[v++]=J+U|0,V[v++]=C+E|0,V[v++]=F+y|0,V[v++]=b+A|0,V[v++]=c+n|0,V[v++]=k+x|0,V[v++]=T+B|0,V[v++]=I+u|0,V[v++]=Q+w|0,V[v++]=L+N|0,V[v++]=M+q|0,V[v++]=p+XZ|0,V[v++]=S+KZ|0}function cK(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],b=W[2],c=W[3],k=Z[2],T=X[4],I=X[5],Q=X[6],L=X[7],M=Z[3];for(let S=0;S<20;S+=2)R^=h(l+I|0,7),b^=h(R+l|0,9),I^=h(b+R|0,13),l^=h(I+b|0,18),c^=h(J+K|0,7),Q^=h(c+J|0,9),K^=h(Q+c|0,13),J^=h(K+Q|0,18),L^=h(k+C|0,7),G^=h(L+k|0,9),C^=h(G+L|0,13),k^=h(C+G|0,18),m^=h(M+T|0,7),F^=h(m+M|0,9),T^=h(F+m|0,13),M^=h(T+F|0,18),K^=h(l+m|0,7),G^=h(K+l|0,9),m^=h(G+K|0,13),l^=h(m+G|0,18),C^=h(J+R|0,7),F^=h(C+J|0,9),R^=h(F+C|0,13),J^=h(R+F|0,18),T^=h(k+c|0,7),b^=h(T+k|0,9),c^=h(b+T|0,13),k^=h(c+b|0,18),I^=h(M+L|0,7),Q^=h(I+M|0,9),L^=h(Q+I|0,13),M^=h(L+Q|0,18);let p=0;V[p++]=l,V[p++]=J,V[p++]=k,V[p++]=M,V[p++]=C,V[p++]=F,V[p++]=b,V[p++]=c}var bV=xl(bK,{counterRight:!0,extendNonceFn:cK}),cV=hl({blockSize:64,nonceLength:24,tagLength:16},(Z,X)=>{return{encrypt(W,V){V=CV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32);V.set(W,32),kZ(l),bV(Z,X,V,V);let G=dV(K,l);return V.set(G,16),kZ(V.subarray(0,16),G),V.subarray(16)},decrypt(W,V){a(W),V=CV(W.length+32,V,!1);let l=V.subarray(0,32),K=V.subarray(32,48),G=V.subarray(48);V.set(W,32),kZ(l);let m=bV(Z,X,l,l),R=dV(G,m);if(!zl(K,R))throw Error("invalid tag");return bV(Z,X,V.subarray(16),V.subarray(16)),kZ(l,K,R),G}}});/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */function kK(Z){return Z instanceof Uint8Array||ArrayBuffer.isView(Z)&&Z.constructor.name==="Uint8Array"}function gX(Z){if(!Number.isSafeInteger(Z)||Z<0)throw Error("positive integer expected, got "+Z)}function $Z(Z,...X){if(!kK(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 xX(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 dW(Z,X){$Z(Z);let W=X.outputLen;if(Z.length<W)throw Error("digestInto() expects output buffer of length at least "+W)}function Pl(Z){return new Uint8Array(Z.buffer,Z.byteOffset,Z.byteLength)}function JX(Z){return new Uint32Array(Z.buffer,Z.byteOffset,Math.floor(Z.byteLength/4))}function CX(...Z){for(let X=0;X<Z.length;X++)Z[X].fill(0)}function HX(Z,X){return Z<<32-X|Z>>>X}var il=(()=>new Uint8Array(new Uint32Array([287454020]).buffer)[0]===68)();function Ul(Z){return Z<<24&4278190080|Z<<8&16711680|Z>>>8&65280|Z>>>24&255}var ul=il?(Z)=>Z:(Z)=>Ul(Z);function TK(Z){for(let X=0;X<Z.length;X++)Z[X]=Ul(Z[X]);return Z}var VZ=il?(Z)=>Z:TK;function IK(Z){if(typeof Z!=="string")throw Error("string expected");return new Uint8Array(new TextEncoder().encode(Z))}function FX(Z){if(typeof Z==="string")Z=IK(Z);return $Z(Z),Z}class kV{}function Ol(Z){let X=(V,l)=>Z(l).update(FX(V)).digest(),W=Z({});return X.outputLen=W.outputLen,X.blockLen=W.blockLen,X.create=(V)=>Z(V),X}var jl=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var bW=BigInt(4294967295),Bl=BigInt(32);function TV(Z,X=!1){if(X)return{h:Number(Z&bW),l:Number(Z>>Bl&bW)};return{h:Number(Z>>Bl&bW)|0,l:Number(Z&bW)|0}}function MZ(Z,X,W,V,l){return Z=Z+X+l|0,V=HX(V^Z,16),W=W+V|0,X=HX(X^W,12),{a:Z,b:X,c:W,d:V}}function zZ(Z,X,W,V,l){return Z=Z+X+l|0,V=HX(V^Z,8),W=W+V|0,X=HX(X^W,7),{a:Z,b:X,c:W,d:V}}class IV extends kV{constructor(Z,X){super();this.finished=!1,this.destroyed=!1,this.length=0,this.pos=0,gX(Z),gX(X),this.blockLen=Z,this.outputLen=X,this.buffer=new Uint8Array(Z),this.buffer32=JX(this.buffer)}update(Z){xX(this),Z=FX(Z),$Z(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)VZ(V),this.compress(V,0,!1),VZ(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));VZ(C);for(let F=0;m+X<l;F+=V.length,m+=X)this.length+=X,this.compress(C,F,!1);VZ(C);continue}W.set(Z.subarray(m,m+R),this.pos),this.pos+=R,this.length+=R,m+=R}return this}digestInto(Z){xX(this),dW(Z,this);let{pos:X,buffer32:W}=this;this.finished=!0,CX(this.buffer.subarray(X)),VZ(W),this.compress(W,0,!0),VZ(W);let V=JX(Z);this.get().forEach((l,K)=>V[K]=ul(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 pV(Z,X,W,V,l,K,G,m,R,J,C,F,b,c,k,T,I,Q,L,M){let p=0;for(let S=0;S<V;S++)({a:l,b:R,c:b,d:I}=MZ(l,R,b,I,W[X+Z[p++]])),{a:l,b:R,c:b,d:I}=zZ(l,R,b,I,W[X+Z[p++]]),{a:K,b:J,c,d:Q}=MZ(K,J,c,Q,W[X+Z[p++]]),{a:K,b:J,c,d:Q}=zZ(K,J,c,Q,W[X+Z[p++]]),{a:G,b:C,c:k,d:L}=MZ(G,C,k,L,W[X+Z[p++]]),{a:G,b:C,c:k,d:L}=zZ(G,C,k,L,W[X+Z[p++]]),{a:m,b:F,c:T,d:M}=MZ(m,F,T,M,W[X+Z[p++]]),{a:m,b:F,c:T,d:M}=zZ(m,F,T,M,W[X+Z[p++]]),{a:l,b:J,c:k,d:M}=MZ(l,J,k,M,W[X+Z[p++]]),{a:l,b:J,c:k,d:M}=zZ(l,J,k,M,W[X+Z[p++]]),{a:K,b:C,c:T,d:I}=MZ(K,C,T,I,W[X+Z[p++]]),{a:K,b:C,c:T,d:I}=zZ(K,C,T,I,W[X+Z[p++]]),{a:G,b:F,c:b,d:Q}=MZ(G,F,b,Q,W[X+Z[p++]]),{a:G,b:F,c:b,d:Q}=zZ(G,F,b,Q,W[X+Z[p++]]),{a:m,b:R,c,d:L}=MZ(m,R,c,L,W[X+Z[p++]]),{a:m,b:R,c,d:L}=zZ(m,R,c,L,W[X+Z[p++]]);return{v0:l,v1:K,v2:G,v3:m,v4:R,v5:J,v6:C,v7:F,v8:b,v9:c,v10:k,v11:T,v12:I,v13:Q,v14:L,v15:M}}var TZ={CHUNK_START:1,CHUNK_END:2,PARENT:4,ROOT:8,KEYED_HASH:16,DERIVE_KEY_CONTEXT:32,DERIVE_KEY_MATERIAL:64},hZ=jl.slice(),El=(()=>{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 LV extends IV{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=FX(W).slice();$Z(K,32),this.IV=JX(K),VZ(this.IV),this.flags=X|TZ.KEYED_HASH}else if(l){let K=FX(V),G=new LV({dkLen:32},TZ.DERIVE_KEY_CONTEXT).update(K).digest();this.IV=JX(G),VZ(this.IV),this.flags=X|TZ.DERIVE_KEY_MATERIAL}else this.IV=hZ.slice(),this.flags=X;this.state=this.IV.slice(),this.bufferOut=Pl(this.bufferOut32)}get(){return[]}set(){}b2Compress(Z,X,W,V=0){let{state:l,pos:K}=this,{h:G,l:m}=TV(BigInt(Z),!0),{v0:R,v1:J,v2:C,v3:F,v4:b,v5:c,v6:k,v7:T,v8:I,v9:Q,v10:L,v11:M,v12:p,v13:S,v14:H,v15:j}=pV(El,V,W,7,l[0],l[1],l[2],l[3],l[4],l[5],l[6],l[7],hZ[0],hZ[1],hZ[2],hZ[3],G,m,K,X);l[0]=R^I,l[1]=J^Q,l[2]=C^L,l[3]=F^M,l[4]=b^p,l[5]=c^S,l[6]=k^H,l[7]=T^j}compress(Z,X=0,W=!1){let V=this.flags;if(!this.chunkPos)V|=TZ.CHUNK_START;if(this.chunkPos===15||W)V|=TZ.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|TZ.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,CX(this.state,this.buffer32,this.IV,this.bufferOut32),CX(...this.stack)}b2CompressOut(){let{state:Z,pos:X,flags:W,buffer32:V,bufferOut32:l}=this,{h:K,l:G}=TV(BigInt(this.chunkOut++));VZ(V);let{v0:m,v1:R,v2:J,v3:C,v4:F,v5:b,v6:c,v7:k,v8:T,v9:I,v10:Q,v11:L,v12:M,v13:p,v14:S,v15:H}=pV(El,0,V,7,Z[0],Z[1],Z[2],Z[3],Z[4],Z[5],Z[6],Z[7],hZ[0],hZ[1],hZ[2],hZ[3],G,K,X,W);l[0]=m^T,l[1]=R^I,l[2]=J^Q,l[3]=C^L,l[4]=F^M,l[5]=b^p,l[6]=c^S,l[7]=k^H,l[8]=Z[0]^T,l[9]=Z[1]^I,l[10]=Z[2]^Q,l[11]=Z[3]^L,l[12]=Z[4]^M,l[13]=Z[5]^p,l[14]=Z[6]^S,l[15]=Z[7]^H,VZ(V),VZ(l),this.posOut=0}finish(){if(this.finished)return;this.finished=!0,CX(this.buffer.subarray(this.pos));let Z=this.flags|TZ.ROOT;if(this.stack.length)Z|=TZ.PARENT,VZ(this.buffer32),this.compress(this.buffer32,0,!0),VZ(this.buffer32),this.chunksDone=0,this.pos=this.blockLen;else Z|=(!this.chunkPos?TZ.CHUNK_START:0)|TZ.CHUNK_END;this.flags=Z,this.b2CompressOut()}writeInto(Z){xX(this,!1),$Z(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 gX(Z),this.xofInto(new Uint8Array(Z))}digestInto(Z){if(dW(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 wl=Ol((Z)=>new LV(Z));var QV=new Uint8Array([48,46,2,1,0,48,5,6,3,43,101,112,4,34,4,32]);function Dl(Z){let X=new Uint8Array(QV.length+32);return X.set(QV),X.set(Z.subarray(0,32),QV.length),X}function Al(Z){return typeof Z==="string"?new TextEncoder().encode(Z):Z}function dX(Z){let X=new ArrayBuffer(Z.byteLength);return new Uint8Array(X).set(Z),X}class yV{verifyKeys=new Map;signKeys=new Map;async genRandomBytes(Z){return CW(Z)}async gen256BitSecureRandomSeed(){return CW(32)}async encryptXSalsa20Poly1305Combined(Z,X){let W=CW(24),l=cV(X,W).encrypt(Z);return new Uint8Array([...W,...l])}async decryptXSalsa20Poly1305Combined(Z,X){let W=Z.slice(0,24),V=Z.slice(24);return cV(X,W).decrypt(V)}async deriveEd25519KeyPair(Z){let X=Z,W=Dl(X),V=await globalThis.crypto.subtle.importKey("pkcs8",dX(W),{name:"Ed25519"},!0,["sign"]),l=await globalThis.crypto.subtle.exportKey("jwk",V);if(typeof l.x!=="string")throw Error("Ed25519 JWK missing x");let K=await globalThis.crypto.subtle.importKey("jwk",{kty:"OKP",crv:"Ed25519",x:l.x},{name:"Ed25519"},!0,["verify"]),G=new Uint8Array(await globalThis.crypto.subtle.exportKey("raw",K)),m=new Uint8Array(64);return m.set(X,0),m.set(G,32),this.signKeys.set(GZ(X),V),this.verifyKeys.set(GZ(G),K),{keyType:"ed25519",privateKey:m,publicKey:G}}async importSignKey(Z){let X=Z.subarray(0,32),W=GZ(X),V=this.signKeys.get(W);if(V)return V;let l=Dl(X),K=await globalThis.crypto.subtle.importKey("pkcs8",dX(l),{name:"Ed25519"},!1,["sign"]);return this.signKeys.set(W,K),K}async importVerifyKey(Z){let X=GZ(Z),W=this.verifyKeys.get(X);if(W)return W;let V=await globalThis.crypto.subtle.importKey("raw",dX(Z),{name:"Ed25519"},!1,["verify"]);return this.verifyKeys.set(X,V),V}async signEd25519(Z,X){let W=Al(Z),V=await this.importSignKey(X),l=await globalThis.crypto.subtle.sign({name:"Ed25519"},V,dX(W));return new Uint8Array(l)}async checkSigEd25519(Z,X,W){let V=Al(X);try{let l=await this.importVerifyKey(W);return await globalThis.crypto.subtle.verify({name:"Ed25519"},l,dX(Z),dX(V))}catch{return!1}}async blake3(Z){return wl(Z)}}var pK=new yV,SZ=pK;import{useEffect as SW,useState as iV}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(RZ,"readwrite"),V=W.objectStore(RZ);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(RZ,"readwrite"),l=V.objectStore(RZ);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(RZ,"readonly").objectStore(RZ);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(RZ,"readonly").objectStore(RZ);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(RZ,"readwrite"),X=Z.objectStore(RZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}function ol(Z){return{label:Z.label,handle:new URL(Z.handle),idx:Z.idx,lastSeq:Z.lastSeq||0,clockOffset:Z.clockOffset,subscription:Z.subscription}}function LK(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 zV{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(lZ,"readwrite"),V=W.objectStore(lZ);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(lZ,"readwrite"),V=W.objectStore(lZ);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(LK(m,X))}})}async get(Z){let W=this.db.transaction(lZ,"readonly").objectStore(lZ);return new Promise((V,l)=>{let K=W.get(Z);K.onsuccess=()=>{let G=K.result;if(!G)V(void 0);else V(ol(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(lZ,"readwrite"),W=X.objectStore(lZ);return new Promise((V,l)=>{X.oncomplete=()=>V(),X.onerror=()=>l(X.error),W.delete(Z)})}async list(){let X=this.db.transaction(lZ,"readonly").objectStore(lZ);return new Promise((W,V)=>{let l=X.getAll();l.onsuccess=()=>{let K=l.result;W(K.map(ol))},l.onerror=()=>V(l.error)})}async wipe(){let Z=this.db.transaction(lZ,"readwrite"),X=Z.objectStore(lZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}class hV{crypto;db;constructor(Z,X){this.crypto=X;this.db=Z}async add(Z){let X=this.db.transaction(o,"readwrite"),W=X.objectStore(o);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(o,"readwrite"),V=W.objectStore(o);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(o,"readonly").objectStore(o);return new Promise((V,l)=>{let K=g(Z),G=W.get(K);G.onsuccess=async()=>{let m=G.result;if(m)V(await uZ(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(o,"readonly").objectStore(o);return new Promise((K,G)=>{let m=[],R=X===void 0?l.openCursor():l.index(PX).openCursor(IDBKeyRange.only(X));R.onsuccess=(J)=>{let C=J.target.result;if(C){let F=X===void 0?C.key:C.primaryKey,b=C.value;m.push({hash:t(F),data:b}),C.continue()}else Promise.all(m.map(({hash:F,data:b})=>uZ(F,b,this.crypto,{body:W}))).then(K).catch(G)},R.onerror=()=>G(R.error)})}async count(Z){let W=this.db.transaction(o,"readonly").objectStore(o);return new Promise((V,l)=>{let K=Z===void 0?W.count():W.index(PX).count(IDBKeyRange.only(Z));K.onsuccess=()=>V(K.result),K.onerror=()=>l(K.error)})}async listKeys(){let X=this.db.transaction(o,"readonly").objectStore(o);return new Promise((W,V)=>{let l=[],K=X.openKeyCursor();K.onsuccess=(G)=>{let m=G.target.result;if(m)l.push(t(m.key)),m.continue();else W(l)},K.onerror=()=>V(K.error)})}async last(Z){let W=this.db.transaction(o,"readonly").objectStore(o);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(e(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=t(K.key);V(await uZ(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(o,"readwrite"),V=W.objectStore(o);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;nZ(J,UZ),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(o,"readwrite"),V=W.objectStore(o);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;nZ(C,cZ,m),V.put(C,R)},J.onerror=(C)=>{C.preventDefault()}}})}async wipe(){let Z=this.db.transaction(o,"readwrite"),X=Z.objectStore(o);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.clear()})}}var OZ={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 d({handle:X,label:V,idx:K})}};var iX=1,cW={encode(Z,X){if(X.v!==iX)return 10;let[,W]=ZZ(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(OZ,K);if(G!==0)return G}return 0},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X!==iX)return Y(14);let[V,l]=Z.readBytes(dZ);if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=ZZ(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,b]=Z.readStruct(OZ);if(b!==0)return Y(b);if(F===void 0)return Y(14);J.push(F)}return d({v:iX,masterSeed:K,hosts:J})}};function SV(Z,X){let[W,V]=ZZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(10);let[l,K]=ZZ(W.slice());if(K!==0)return Y(K);if(l===void 0)return Y(10);return d({v:iX,masterSeed:l,hosts:X.map((G)=>({handle:G.handle,label:G.label,idx:G.idx??0}))})}var UX={encode(Z,X){let[,W]=ZZ(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(OZ,l);if(K!==0)return K}return 0},decode(Z){let[X,W]=Z.readBytes(dZ);if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=ZZ(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(OZ);if(C!==0)return Y(C);if(J===void 0)return Y(14);m.push(J)}return d({masterSeed:V,hosts:m})}};function NZ(Z){let X=new Uint8Array(Z);if(Z>0)crypto.getRandomValues(X);return X}var jZ=32,nl=-7,vl=-8,fl=-257,uX=[{type:"public-key",alg:nl},{type:"public-key",alg:vl},{type:"public-key",alg:fl}];function kW(Z){return Z.trim().toLowerCase().replace(/\.$/,"")||"localhost"}function BZ(Z){let X=new Uint8Array(Z.byteLength);return X.set(Z),X}function EZ(Z){if(Z?.rpId!==void 0)return d(Z.rpId);if(typeof location>"u")return Y(9);return d(kW(location.hostname))}function wZ(){if(typeof navigator>"u"||!navigator.credentials||typeof PublicKeyCredential>"u")return 24;return 0}function DZ(Z){if(Z===null||Z.type!=="public-key"||!("rawId"in Z)||typeof Z.getClientExtensionResults!=="function")return Y(27);return d(Z)}async function OX(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 $l(){return OX("extension:largeBlob")}async function TW(Z){let X=wZ();if(X!==0)return Y(X);let[W,V]=EZ(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:NZ(jZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:NZ(16),name:l,displayName:l},pubKeyCredParams:uX,authenticatorSelection:K,extensions:G}})}catch{return Y(24)}let[R,J]=DZ(m);if(J!==0)return Y(J);if(R===void 0)return Y(27);if(R.getClientExtensionResults().largeBlob?.supported!==!0)return Y(24);return d(new Uint8Array(R.rawId))}async function jX(Z,X,W){let V=wZ();if(V!==0)return V;let[l,K]=EZ(W);if(K!==0)return K;if(l===void 0)return 9;let G={largeBlob:{write:BZ(X)}},m;try{m=await navigator.credentials.get({publicKey:{challenge:NZ(jZ),rpId:l,allowCredentials:[{type:"public-key",id:BZ(Z)}],userVerification:"required",extensions:G}})}catch{return 24}let[R,J]=DZ(m);if(J!==0)return J;if(R===void 0)return 27;if(R.getClientExtensionResults().largeBlob?.written!==!0)return 24;return 0}async function IW(Z,X){let W=wZ();if(W!==0)return Y(W);let[V,l]=EZ(X);if(l!==0)return Y(l);if(V===void 0)return Y(9);let K={largeBlob:{read:!0}},G;try{let F={challenge:NZ(jZ),rpId:V,userVerification:"required",extensions:K};if(Z!==void 0)F.allowCredentials=[{type:"public-key",id:BZ(Z)}];G=await navigator.credentials.get({publicKey:F})}catch{return Y(24)}let[m,R]=DZ(G);if(R!==0)return Y(R);if(m===void 0)return Y(27);let C=m.getClientExtensionResults().largeBlob?.blob;if(C===void 0)return Y(7);return d({blob:new Uint8Array(C),credId:new Uint8Array(m.rawId)})}var BX=new TextEncoder().encode("diplomatic.prf.v1"),NV=32;async function QK(){return OX("extension:prf")}async function gV(Z){let X=wZ();if(X!==0)return Y(X);let[W,V]=EZ(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",authenticatorAttachment:Z?.authenticatorAttachment??"platform"},G;try{G=await navigator.credentials.create({publicKey:{challenge:NZ(jZ),rp:{id:W,name:Z?.rpName??"DIPLOMATIC"},user:{id:NZ(16),name:l,displayName:l},pubKeyCredParams:uX,authenticatorSelection:K,extensions:{prf:{}}}})}catch{return Y(24)}let[m,R]=DZ(G);if(R!==0)return Y(R);if(m===void 0)return Y(27);let J=m.getClientExtensionResults();return d({credId:new Uint8Array(m.rawId),prfEnabled:J.prf?.enabled===!0})}async function bX(Z){let X=wZ();if(X!==0)return Y(X);let[W,V]=EZ(Z);if(V!==0)return Y(V);if(W===void 0)return Y(9);let l=Z?.salt??BX,K=BZ(l),G={challenge:NZ(jZ),rpId:W,userVerification:"required",extensions:{prf:{eval:{first:K}}}};if(Z?.credId!==void 0)G.allowCredentials=[{type:"public-key",id:BZ(Z.credId)}];let m;try{m=await navigator.credentials.get({publicKey:G})}catch{return Y(24)}let[R,J]=DZ(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,b=F instanceof ArrayBuffer?new Uint8Array(F):new Uint8Array(F.buffer,F.byteOffset,F.byteLength),c=b.byteLength>=NV?b.slice(0,NV):b;if(c.byteLength!==NV)return Y(27);return d({prf:c,credId:new Uint8Array(R.rawId)})}var pW="dmFyIHcwPTY0O3ZhciBYSj0zMixUMD04O3ZhciBJJD0zMjt2YXIgV0o9MzAwMDAsR0o9NTEyLGo7KCh3KT0+e3dbdy5TdWNjZXNzPTBdPSJTdWNjZXNzIjt3W3cuSW52YWxpZFNpZ25hdHVyZT0zXT0iSW52YWxpZFNpZ25hdHVyZSI7d1t3LkNsb2NrT3V0T2ZTeW5jPTRdPSJDbG9ja091dE9mU3luYyI7d1t3LlVzZXJOb3RSZWdpc3RlcmVkPTVdPSJVc2VyTm90UmVnaXN0ZXJlZCI7d1t3LlNlcnZlck1pc2NvbmZpZ3VyZWQ9Nl09IlNlcnZlck1pc2NvbmZpZ3VyZWQiO3dbdy5NaXNzaW5nQm9keT03XT0iTWlzc2luZ0JvZHkiO3dbdy5FeHRyYUJvZHlDb250ZW50PThdPSJFeHRyYUJvZHlDb250ZW50Ijt3W3cuTWlzc2luZ1BhcmFtPTldPSJNaXNzaW5nUGFyYW0iO3dbdy5JbnZhbGlkUGFyYW09MTBdPSJJbnZhbGlkUGFyYW0iO3dbdy5JbnZhbGlkUmVxdWVzdD0xMV09IkludmFsaWRSZXF1ZXN0Ijt3W3cuSW50ZXJuYWxFcnJvcj0xMl09IkludGVybmFsRXJyb3IiO3dbdy5Ob3RGb3VuZD0xM109Ik5vdEZvdW5kIjt3W3cuSW52YWxpZE1lc3NhZ2U9MTRdPSJJbnZhbGlkTWVzc2FnZSI7d1t3Lk5vQ2hhbmdlPTE1XT0iTm9DaGFuZ2UiO3dbdy5EYXRhYmFzZUNsb3NlZD0xNl09IkRhdGFiYXNlQ2xvc2VkIjt3W3cuU3RvcmFnZUVycm9yPTE3XT0iU3RvcmFnZUVycm9yIjt3W3cuRGF0YWJhc2VFcnJvcj0xOF09IkRhdGFiYXNlRXJyb3IiO3dbdy5IYXNoTWlzbWF0Y2g9MTldPSJIYXNoTWlzbWF0Y2giO3dbdy5EZWNyeXB0aW9uRXJyb3I9MjBdPSJEZWNyeXB0aW9uRXJyb3IiO3dbdy5Ob3RJbXBsZW1lbnRlZD0yMV09Ik5vdEltcGxlbWVudGVkIjt3W3cuTWlzc2luZ1NlZWQ9MjJdPSJNaXNzaW5nU2VlZCI7d1t3Lk91dE9mQm91bmRzPTIzXT0iT3V0T2ZCb3VuZHMiO3dbdy5Ib3N0RXJyb3I9MjRdPSJIb3N0RXJyb3IiO3dbdy5Db21tdW5pY2F0aW9uRXJyb3I9MjVdPSJDb21tdW5pY2F0aW9uRXJyb3IiO3dbdy5WYXJMaW1pdEV4Y2VlZGVkPTI2XT0iVmFyTGltaXRFeGNlZWRlZCI7d1t3LkludmFsaWRSZXNwb25zZT0yN109IkludmFsaWRSZXNwb25zZSI7d1t3LkNvbm5lY3Rpb25DbG9zZWQ9MjhdPSJDb25uZWN0aW9uQ2xvc2VkIn0pKGp8fD17fSk7ZnVuY3Rpb24gekooJCl7aWYoISR8fHR5cGVvZiAkIT09Im9iamVjdCIpcmV0dXJuITE7aWYoISgib3AiaW4gJCl8fCEoImlkImluICQpKXJldHVybiExO3JldHVybiB0eXBlb2YgJC5vcD09PSJzdHJpbmciJiZ0eXBlb2YgJC5pZD09PSJudW1iZXIifWZ1bmN0aW9uIEtKKCQpe2xldCBaPSQubGVuZ3RoLEo9MCxRPTA7d2hpbGUoUTxaKXtsZXQgVj0kLmNoYXJDb2RlQXQoUSsrKTtpZigoViY0Mjk0OTY3MTY4KT09PTApe0orKztjb250aW51ZX1lbHNlIGlmKChWJjQyOTQ5NjUyNDgpPT09MClKKz0yO2Vsc2V7aWYoVj49NTUyOTYmJlY8PTU2MzE5KXtpZihRPFope2xldCBZPSQuY2hhckNvZGVBdChRKTtpZigoWSY2NDUxMik9PT01NjMyMCkrK1EsVj0oKFYmMTAyMyk8PDEwKSsoWSYxMDIzKSs2NTUzNn19aWYoKFYmNDI5NDkwMTc2MCk9PT0wKUorPTM7ZWxzZSBKKz00fX1yZXR1cm4gSn1mdW5jdGlvbiBMUSgkLFosSil7bGV0IFE9JC5sZW5ndGgsVj1KLFk9MDt3aGlsZShZPFEpe2xldCBYPSQuY2hhckNvZGVBdChZKyspO2lmKChYJjQyOTQ5NjcxNjgpPT09MCl7WltWKytdPVg7Y29udGludWV9ZWxzZSBpZigoWCY0Mjk0OTY1MjQ4KT09PTApWltWKytdPVg+PjYmMzF8MTkyO2Vsc2V7aWYoWD49NTUyOTYmJlg8PTU2MzE5KXtpZihZPFEpe2xldCBXPSQuY2hhckNvZGVBdChZKTtpZigoVyY2NDUxMik9PT01NjMyMCkrK1ksWD0oKFgmMTAyMyk8PDEwKSsoVyYxMDIzKSs2NTUzNn19aWYoKFgmNDI5NDkwMTc2MCk9PT0wKVpbVisrXT1YPj4xMiYxNXwyMjQsWltWKytdPVg+PjYmNjN8MTI4O2Vsc2UgWltWKytdPVg+PjE4Jjd8MjQwLFpbVisrXT1YPj4xMiY2M3wxMjgsWltWKytdPVg+PjYmNjN8MTI4fVpbVisrXT1YJjYzfDEyOH19dmFyIHhRPW5ldyBUZXh0RW5jb2RlcixmUT01MDtmdW5jdGlvbiBrUSgkLFosSil7eFEuZW5jb2RlSW50bygkLFouc3ViYXJyYXkoSikpfWZ1bmN0aW9uIEZKKCQsWixKKXtpZigkLmxlbmd0aD5mUSlrUSgkLFosSik7ZWxzZSBMUSgkLFosSil9dmFyIEJRPTQwOTY7ZnVuY3Rpb24gZSQoJCxaLEope2xldCBRPVosVj1RK0osWT1bXSxYPSIiO3doaWxlKFE8Vil7bGV0IFc9JFtRKytdO2lmKChXJjEyOCk9PT0wKVkucHVzaChXKTtlbHNlIGlmKChXJjIyNCk9PT0xOTIpe2xldCB6PSRbUSsrXSY2MztZLnB1c2goKFcmMzEpPDw2fHopfWVsc2UgaWYoKFcmMjQwKT09PTIyNCl7bGV0IHo9JFtRKytdJjYzLEs9JFtRKytdJjYzO1kucHVzaCgoVyYzMSk8PDEyfHo8PDZ8Syl9ZWxzZSBpZigoVyYyNDgpPT09MjQwKXtsZXQgej0kW1ErK10mNjMsSz0kW1ErK10mNjMsRj0kW1ErK10mNjMsTj0oVyY3KTw8MTh8ejw8MTJ8Szw8NnxGO2lmKE4+NjU1MzUpTi09NjU1MzYsWS5wdXNoKE4+Pj4xMCYxMDIzfDU1Mjk2KSxOPTU2MzIwfE4mMTAyMztZLnB1c2goTil9ZWxzZSBZLnB1c2goVyk7aWYoWS5sZW5ndGg+PUJRKVgrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uWSksWS5sZW5ndGg9MH1pZihZLmxlbmd0aD4wKVgrPVN0cmluZy5mcm9tQ2hhckNvZGUoLi4uWSk7cmV0dXJuIFh9dmFyIEVRPW5ldyBUZXh0RGVjb2RlcixtUT0yMDA7ZnVuY3Rpb24gZ1EoJCxaLEope2xldCBRPSQuc3ViYXJyYXkoWixaK0opO3JldHVybiBFUS5kZWNvZGUoUSl9ZnVuY3Rpb24gTkooJCxaLEope2lmKEo+bVEpcmV0dXJuIGdRKCQsWixKKTtlbHNlIHJldHVybiBlJCgkLFosSil9Y2xhc3MgdTB7dHlwZTtkYXRhO2NvbnN0cnVjdG9yKCQsWil7dGhpcy50eXBlPSQsdGhpcy5kYXRhPVp9fWNsYXNzIHMgZXh0ZW5kcyBFcnJvcntjb25zdHJ1Y3RvcigkKXtzdXBlcigkKTtsZXQgWj1PYmplY3QuY3JlYXRlKHMucHJvdG90eXBlKTtPYmplY3Quc2V0UHJvdG90eXBlT2YodGhpcyxaKSxPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywibmFtZSIse2NvbmZpZ3VyYWJsZTohMCxlbnVtZXJhYmxlOiExLHZhbHVlOnMubmFtZX0pfX12YXIgbDA9NDI5NDk2NzI5NTtmdW5jdGlvbiBSSigkLFosSil7bGV0IFE9Si80Mjk0OTY3Mjk2LFY9SjskLnNldFVpbnQzMihaLFEpLCQuc2V0VWludDMyKForNCxWKX1mdW5jdGlvbiBIJCgkLFosSil7bGV0IFE9TWF0aC5mbG9vcihKLzQyOTQ5NjcyOTYpLFY9SjskLnNldFVpbnQzMihaLFEpLCQuc2V0VWludDMyKForNCxWKX1mdW5jdGlvbiBNJCgkLFope2xldCBKPSQuZ2V0SW50MzIoWiksUT0kLmdldFVpbnQzMihaKzQpO3JldHVybiBKKjQyOTQ5NjcyOTYrUX1mdW5jdGlvbiBVSigkLFope2xldCBKPSQuZ2V0VWludDMyKFopLFE9JC5nZXRVaW50MzIoWis0KTtyZXR1cm4gSio0Mjk0OTY3Mjk2K1F9dmFyIFNRPS0xLHZRPTQyOTQ5NjcyOTUsYlE9MTcxNzk4NjkxODM7ZnVuY3Rpb24geVEoe3NlYzokLG5zZWM6Wn0pe2lmKCQ+PTAmJlo+PTAmJiQ8PWJRKWlmKFo9PT0wJiYkPD12USl7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoNCk7cmV0dXJuIG5ldyBEYXRhVmlldyhKLmJ1ZmZlcikuc2V0VWludDMyKDAsJCksSn1lbHNle2xldCBKPSQvNDI5NDk2NzI5NixRPSQmNDI5NDk2NzI5NSxWPW5ldyBVaW50OEFycmF5KDgpLFk9bmV3IERhdGFWaWV3KFYuYnVmZmVyKTtyZXR1cm4gWS5zZXRVaW50MzIoMCxaPDwyfEomMyksWS5zZXRVaW50MzIoNCxRKSxWfWVsc2V7bGV0IEo9bmV3IFVpbnQ4QXJyYXkoMTIpLFE9bmV3IERhdGFWaWV3KEouYnVmZmVyKTtyZXR1cm4gUS5zZXRVaW50MzIoMCxaKSxIJChRLDQsJCksSn19ZnVuY3Rpb24gaVEoJCl7bGV0IFo9JC5nZXRUaW1lKCksSj1NYXRoLmZsb29yKFovMTAwMCksUT0oWi1KKjEwMDApKjFlNixWPU1hdGguZmxvb3IoUS8xZTkpO3JldHVybntzZWM6SitWLG5zZWM6US1WKjFlOX19ZnVuY3Rpb24gaFEoJCl7aWYoJCBpbnN0YW5jZW9mIERhdGUpe2xldCBaPWlRKCQpO3JldHVybiB5UShaKX1lbHNlIHJldHVybiBudWxsfWZ1bmN0aW9uIHVRKCQpe2xldCBaPW5ldyBEYXRhVmlldygkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsJC5ieXRlTGVuZ3RoKTtzd2l0Y2goJC5ieXRlTGVuZ3RoKXtjYXNlIDQ6e2xldCBKPVouZ2V0VWludDMyKDApLFE9MDtyZXR1cm57c2VjOkosbnNlYzowfX1jYXNlIDg6e2xldCBKPVouZ2V0VWludDMyKDApLFE9Wi5nZXRVaW50MzIoNCksVj0oSiYzKSo0Mjk0OTY3Mjk2K1EsWT1KPj4+MjtyZXR1cm57c2VjOlYsbnNlYzpZfX1jYXNlIDEyOntsZXQgSj1NJChaLDQpLFE9Wi5nZXRVaW50MzIoMCk7cmV0dXJue3NlYzpKLG5zZWM6UX19ZGVmYXVsdDp0aHJvdyBuZXcgcyhgVW5yZWNvZ25pemVkIGRhdGEgc2l6ZSBmb3IgdGltZXN0YW1wIChleHBlY3RlZCA0LCA4LCBvciAxMik6ICR7JC5sZW5ndGh9YCl9fWZ1bmN0aW9uIGxRKCQpe2xldCBaPXVRKCQpO3JldHVybiBuZXcgRGF0ZShaLnNlYyoxMDAwK1oubnNlYy8xZTYpfXZhciBPSj17dHlwZTpTUSxlbmNvZGU6aFEsZGVjb2RlOmxRfTtjbGFzcyBwMHtzdGF0aWMgZGVmYXVsdENvZGVjPW5ldyBwMDtfX2JyYW5kO2J1aWx0SW5FbmNvZGVycz1bXTtidWlsdEluRGVjb2RlcnM9W107ZW5jb2RlcnM9W107ZGVjb2RlcnM9W107Y29uc3RydWN0b3IoKXt0aGlzLnJlZ2lzdGVyKE9KKX1yZWdpc3Rlcih7dHlwZTokLGVuY29kZTpaLGRlY29kZTpKfSl7aWYoJD49MCl0aGlzLmVuY29kZXJzWyRdPVosdGhpcy5kZWNvZGVyc1skXT1KO2Vsc2V7bGV0IFE9LTEtJDt0aGlzLmJ1aWx0SW5FbmNvZGVyc1tRXT1aLHRoaXMuYnVpbHRJbkRlY29kZXJzW1FdPUp9fXRyeVRvRW5jb2RlKCQsWil7Zm9yKGxldCBKPTA7Sjx0aGlzLmJ1aWx0SW5FbmNvZGVycy5sZW5ndGg7SisrKXtsZXQgUT10aGlzLmJ1aWx0SW5FbmNvZGVyc1tKXTtpZihRIT1udWxsKXtsZXQgVj1RKCQsWik7aWYoViE9bnVsbCl7bGV0IFk9LTEtSjtyZXR1cm4gbmV3IHUwKFksVil9fX1mb3IobGV0IEo9MDtKPHRoaXMuZW5jb2RlcnMubGVuZ3RoO0orKyl7bGV0IFE9dGhpcy5lbmNvZGVyc1tKXTtpZihRIT1udWxsKXtsZXQgVj1RKCQsWik7aWYoViE9bnVsbClyZXR1cm4gbmV3IHUwKEosVil9fWlmKCQgaW5zdGFuY2VvZiB1MClyZXR1cm4gJDtyZXR1cm4gbnVsbH1kZWNvZGUoJCxaLEope2xldCBRPVo8MD90aGlzLmJ1aWx0SW5EZWNvZGVyc1stMS1aXTp0aGlzLmRlY29kZXJzW1pdO2lmKFEpcmV0dXJuIFEoJCxaLEopO2Vsc2UgcmV0dXJuIG5ldyB1MChaLCQpfX1mdW5jdGlvbiBwUSgkKXtyZXR1cm4gJCBpbnN0YW5jZW9mIEFycmF5QnVmZmVyfHx0eXBlb2YgU2hhcmVkQXJyYXlCdWZmZXI8InUiJiYkIGluc3RhbmNlb2YgU2hhcmVkQXJyYXlCdWZmZXJ9ZnVuY3Rpb24gUSQoJCl7aWYoJCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuICQ7ZWxzZSBpZihBcnJheUJ1ZmZlci5pc1ZpZXcoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQuYnVmZmVyLCQuYnl0ZU9mZnNldCwkLmJ5dGVMZW5ndGgpO2Vsc2UgaWYocFEoJCkpcmV0dXJuIG5ldyBVaW50OEFycmF5KCQpO2Vsc2UgcmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX12YXIgblE9MTAwLGNRPTIwNDg7Y2xhc3MgQyR7ZXh0ZW5zaW9uQ29kZWM7Y29udGV4dDt1c2VCaWdJbnQ2NDttYXhEZXB0aDtpbml0aWFsQnVmZmVyU2l6ZTtzb3J0S2V5cztmb3JjZUZsb2F0MzI7aWdub3JlVW5kZWZpbmVkO2ZvcmNlSW50ZWdlclRvRmxvYXQ7cG9zO3ZpZXc7Ynl0ZXM7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9wMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5tYXhEZXB0aD0kPy5tYXhEZXB0aD8/blEsdGhpcy5pbml0aWFsQnVmZmVyU2l6ZT0kPy5pbml0aWFsQnVmZmVyU2l6ZT8/Y1EsdGhpcy5zb3J0S2V5cz0kPy5zb3J0S2V5cz8/ITEsdGhpcy5mb3JjZUZsb2F0MzI9JD8uZm9yY2VGbG9hdDMyPz8hMSx0aGlzLmlnbm9yZVVuZGVmaW5lZD0kPy5pZ25vcmVVbmRlZmluZWQ/PyExLHRoaXMuZm9yY2VJbnRlZ2VyVG9GbG9hdD0kPy5mb3JjZUludGVnZXJUb0Zsb2F0Pz8hMSx0aGlzLnBvcz0wLHRoaXMudmlldz1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKHRoaXMuaW5pdGlhbEJ1ZmZlclNpemUpKSx0aGlzLmJ5dGVzPW5ldyBVaW50OEFycmF5KHRoaXMudmlldy5idWZmZXIpfWNsb25lKCl7cmV0dXJuIG5ldyBDJCh7ZXh0ZW5zaW9uQ29kZWM6dGhpcy5leHRlbnNpb25Db2RlYyxjb250ZXh0OnRoaXMuY29udGV4dCx1c2VCaWdJbnQ2NDp0aGlzLnVzZUJpZ0ludDY0LG1heERlcHRoOnRoaXMubWF4RGVwdGgsaW5pdGlhbEJ1ZmZlclNpemU6dGhpcy5pbml0aWFsQnVmZmVyU2l6ZSxzb3J0S2V5czp0aGlzLnNvcnRLZXlzLGZvcmNlRmxvYXQzMjp0aGlzLmZvcmNlRmxvYXQzMixpZ25vcmVVbmRlZmluZWQ6dGhpcy5pZ25vcmVVbmRlZmluZWQsZm9yY2VJbnRlZ2VyVG9GbG9hdDp0aGlzLmZvcmNlSW50ZWdlclRvRmxvYXR9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMucG9zPTB9ZW5jb2RlU2hhcmVkUmVmKCQpe2lmKHRoaXMuZW50ZXJlZClyZXR1cm4gdGhpcy5jbG9uZSgpLmVuY29kZVNoYXJlZFJlZigkKTt0cnl7cmV0dXJuIHRoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5kb0VuY29kZSgkLDEpLHRoaXMuYnl0ZXMuc3ViYXJyYXkoMCx0aGlzLnBvcyl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWVuY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5lbmNvZGUoJCk7dHJ5e3JldHVybiB0aGlzLmVudGVyZWQ9ITAsdGhpcy5yZWluaXRpYWxpemVTdGF0ZSgpLHRoaXMuZG9FbmNvZGUoJCwxKSx0aGlzLmJ5dGVzLnNsaWNlKDAsdGhpcy5wb3MpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1kb0VuY29kZSgkLFope2lmKFo+dGhpcy5tYXhEZXB0aCl0aHJvdyBFcnJvcihgVG9vIGRlZXAgb2JqZWN0cyBpbiBkZXB0aCAke1p9YCk7aWYoJD09bnVsbCl0aGlzLmVuY29kZU5pbCgpO2Vsc2UgaWYodHlwZW9mICQ9PT0iYm9vbGVhbiIpdGhpcy5lbmNvZGVCb29sZWFuKCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ibnVtYmVyIilpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0KXRoaXMuZW5jb2RlTnVtYmVyKCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ic3RyaW5nIil0aGlzLmVuY29kZVN0cmluZygkKTtlbHNlIGlmKHRoaXMudXNlQmlnSW50NjQmJnR5cGVvZiAkPT09ImJpZ2ludCIpdGhpcy5lbmNvZGVCaWdJbnQ2NCgkKTtlbHNlIHRoaXMuZW5jb2RlT2JqZWN0KCQsWil9ZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoJCl7bGV0IFo9dGhpcy5wb3MrJDtpZih0aGlzLnZpZXcuYnl0ZUxlbmd0aDxaKXRoaXMucmVzaXplQnVmZmVyKFoqMil9cmVzaXplQnVmZmVyKCQpe2xldCBaPW5ldyBBcnJheUJ1ZmZlcigkKSxKPW5ldyBVaW50OEFycmF5KFopLFE9bmV3IERhdGFWaWV3KFopO0ouc2V0KHRoaXMuYnl0ZXMpLHRoaXMudmlldz1RLHRoaXMuYnl0ZXM9Sn1lbmNvZGVOaWwoKXt0aGlzLndyaXRlVTgoMTkyKX1lbmNvZGVCb29sZWFuKCQpe2lmKCQ9PT0hMSl0aGlzLndyaXRlVTgoMTk0KTtlbHNlIHRoaXMud3JpdGVVOCgxOTUpfWVuY29kZU51bWJlcigkKXtpZighdGhpcy5mb3JjZUludGVnZXJUb0Zsb2F0JiZOdW1iZXIuaXNTYWZlSW50ZWdlcigkKSlpZigkPj0wKWlmKCQ8MTI4KXRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8MjU2KXRoaXMud3JpdGVVOCgyMDQpLHRoaXMud3JpdGVVOCgkKTtlbHNlIGlmKCQ8NjU1MzYpdGhpcy53cml0ZVU4KDIwNSksdGhpcy53cml0ZVUxNigkKTtlbHNlIGlmKCQ8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjA2KSx0aGlzLndyaXRlVTMyKCQpO2Vsc2UgaWYoIXRoaXMudXNlQmlnSW50NjQpdGhpcy53cml0ZVU4KDIwNyksdGhpcy53cml0ZVU2NCgkKTtlbHNlIHRoaXMuZW5jb2RlTnVtYmVyQXNGbG9hdCgkKTtlbHNlIGlmKCQ+PS0zMil0aGlzLndyaXRlVTgoMjI0fCQrMzIpO2Vsc2UgaWYoJD49LTEyOCl0aGlzLndyaXRlVTgoMjA4KSx0aGlzLndyaXRlSTgoJCk7ZWxzZSBpZigkPj0tMzI3NjgpdGhpcy53cml0ZVU4KDIwOSksdGhpcy53cml0ZUkxNigkKTtlbHNlIGlmKCQ+PS0yMTQ3NDgzNjQ4KXRoaXMud3JpdGVVOCgyMTApLHRoaXMud3JpdGVJMzIoJCk7ZWxzZSBpZighdGhpcy51c2VCaWdJbnQ2NCl0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlSTY0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpO2Vsc2UgdGhpcy5lbmNvZGVOdW1iZXJBc0Zsb2F0KCQpfWVuY29kZU51bWJlckFzRmxvYXQoJCl7aWYodGhpcy5mb3JjZUZsb2F0MzIpdGhpcy53cml0ZVU4KDIwMiksdGhpcy53cml0ZUYzMigkKTtlbHNlIHRoaXMud3JpdGVVOCgyMDMpLHRoaXMud3JpdGVGNjQoJCl9ZW5jb2RlQmlnSW50NjQoJCl7aWYoJD49QmlnSW50KDApKXRoaXMud3JpdGVVOCgyMDcpLHRoaXMud3JpdGVCaWdVaW50NjQoJCk7ZWxzZSB0aGlzLndyaXRlVTgoMjExKSx0aGlzLndyaXRlQmlnSW50NjQoJCl9d3JpdGVTdHJpbmdIZWFkZXIoJCl7aWYoJDwzMil0aGlzLndyaXRlVTgoMTYwKyQpO2Vsc2UgaWYoJDwyNTYpdGhpcy53cml0ZVU4KDIxNyksdGhpcy53cml0ZVU4KCQpO2Vsc2UgaWYoJDw2NTUzNil0aGlzLndyaXRlVTgoMjE4KSx0aGlzLndyaXRlVTE2KCQpO2Vsc2UgaWYoJDw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMTkpLHRoaXMud3JpdGVVMzIoJCk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxvbmcgc3RyaW5nOiAkeyR9IGJ5dGVzIGluIFVURi04YCl9ZW5jb2RlU3RyaW5nKCQpe2xldCBKPUtKKCQpO3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoNStKKSx0aGlzLndyaXRlU3RyaW5nSGVhZGVyKEopLEZKKCQsdGhpcy5ieXRlcyx0aGlzLnBvcyksdGhpcy5wb3MrPUp9ZW5jb2RlT2JqZWN0KCQsWil7bGV0IEo9dGhpcy5leHRlbnNpb25Db2RlYy50cnlUb0VuY29kZSgkLHRoaXMuY29udGV4dCk7aWYoSiE9bnVsbCl0aGlzLmVuY29kZUV4dGVuc2lvbihKKTtlbHNlIGlmKEFycmF5LmlzQXJyYXkoJCkpdGhpcy5lbmNvZGVBcnJheSgkLFopO2Vsc2UgaWYoQXJyYXlCdWZmZXIuaXNWaWV3KCQpKXRoaXMuZW5jb2RlQmluYXJ5KCQpO2Vsc2UgaWYodHlwZW9mICQ9PT0ib2JqZWN0Iil0aGlzLmVuY29kZU1hcCgkLFopO2Vsc2UgdGhyb3cgRXJyb3IoYFVucmVjb2duaXplZCBvYmplY3Q6ICR7T2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5hcHBseSgkKX1gKX1lbmNvZGVCaW5hcnkoJCl7bGV0IFo9JC5ieXRlTGVuZ3RoO2lmKFo8MjU2KXRoaXMud3JpdGVVOCgxOTYpLHRoaXMud3JpdGVVOChaKTtlbHNlIGlmKFo8NjU1MzYpdGhpcy53cml0ZVU4KDE5NyksdGhpcy53cml0ZVUxNihaKTtlbHNlIGlmKFo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMTk4KSx0aGlzLndyaXRlVTMyKFopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBiaW5hcnk6ICR7Wn1gKTtsZXQgSj1RJCgkKTt0aGlzLndyaXRlVThhKEopfWVuY29kZUFycmF5KCQsWil7bGV0IEo9JC5sZW5ndGg7aWYoSjwxNil0aGlzLndyaXRlVTgoMTQ0K0opO2Vsc2UgaWYoSjw2NTUzNil0aGlzLndyaXRlVTgoMjIwKSx0aGlzLndyaXRlVTE2KEopO2Vsc2UgaWYoSjw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjEpLHRoaXMud3JpdGVVMzIoSik7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIGFycmF5OiAke0p9YCk7Zm9yKGxldCBRIG9mICQpdGhpcy5kb0VuY29kZShRLForMSl9Y291bnRXaXRob3V0VW5kZWZpbmVkKCQsWil7bGV0IEo9MDtmb3IobGV0IFEgb2YgWilpZigkW1FdIT09dm9pZCAwKUorKztyZXR1cm4gSn1lbmNvZGVNYXAoJCxaKXtsZXQgSj1PYmplY3Qua2V5cygkKTtpZih0aGlzLnNvcnRLZXlzKUouc29ydCgpO2xldCBRPXRoaXMuaWdub3JlVW5kZWZpbmVkP3RoaXMuY291bnRXaXRob3V0VW5kZWZpbmVkKCQsSik6Si5sZW5ndGg7aWYoUTwxNil0aGlzLndyaXRlVTgoMTI4K1EpO2Vsc2UgaWYoUTw2NTUzNil0aGlzLndyaXRlVTgoMjIyKSx0aGlzLndyaXRlVTE2KFEpO2Vsc2UgaWYoUTw0Mjk0OTY3Mjk2KXRoaXMud3JpdGVVOCgyMjMpLHRoaXMud3JpdGVVMzIoUSk7ZWxzZSB0aHJvdyBFcnJvcihgVG9vIGxhcmdlIG1hcCBvYmplY3Q6ICR7UX1gKTtmb3IobGV0IFYgb2YgSil7bGV0IFk9JFtWXTtpZighKHRoaXMuaWdub3JlVW5kZWZpbmVkJiZZPT09dm9pZCAwKSl0aGlzLmVuY29kZVN0cmluZyhWKSx0aGlzLmRvRW5jb2RlKFksWisxKX19ZW5jb2RlRXh0ZW5zaW9uKCQpe2lmKHR5cGVvZiAkLmRhdGE9PT0iZnVuY3Rpb24iKXtsZXQgSj0kLmRhdGEodGhpcy5wb3MrNiksUT1KLmxlbmd0aDtpZihRPj00Mjk0OTY3Mjk2KXRocm93IEVycm9yKGBUb28gbGFyZ2UgZXh0ZW5zaW9uIG9iamVjdDogJHtRfWApO3RoaXMud3JpdGVVOCgyMDEpLHRoaXMud3JpdGVVMzIoUSksdGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YShKKTtyZXR1cm59bGV0IFo9JC5kYXRhLmxlbmd0aDtpZihaPT09MSl0aGlzLndyaXRlVTgoMjEyKTtlbHNlIGlmKFo9PT0yKXRoaXMud3JpdGVVOCgyMTMpO2Vsc2UgaWYoWj09PTQpdGhpcy53cml0ZVU4KDIxNCk7ZWxzZSBpZihaPT09OCl0aGlzLndyaXRlVTgoMjE1KTtlbHNlIGlmKFo9PT0xNil0aGlzLndyaXRlVTgoMjE2KTtlbHNlIGlmKFo8MjU2KXRoaXMud3JpdGVVOCgxOTkpLHRoaXMud3JpdGVVOChaKTtlbHNlIGlmKFo8NjU1MzYpdGhpcy53cml0ZVU4KDIwMCksdGhpcy53cml0ZVUxNihaKTtlbHNlIGlmKFo8NDI5NDk2NzI5Nil0aGlzLndyaXRlVTgoMjAxKSx0aGlzLndyaXRlVTMyKFopO2Vsc2UgdGhyb3cgRXJyb3IoYFRvbyBsYXJnZSBleHRlbnNpb24gb2JqZWN0OiAke1p9YCk7dGhpcy53cml0ZUk4KCQudHlwZSksdGhpcy53cml0ZVU4YSgkLmRhdGEpfXdyaXRlVTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0VWludDgodGhpcy5wb3MsJCksdGhpcy5wb3MrK313cml0ZVU4YSgkKXtsZXQgWj0kLmxlbmd0aDt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKFopLHRoaXMuYnl0ZXMuc2V0KCQsdGhpcy5wb3MpLHRoaXMucG9zKz1afXdyaXRlSTgoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSgxKSx0aGlzLnZpZXcuc2V0SW50OCh0aGlzLnBvcywkKSx0aGlzLnBvcysrfXdyaXRlVTE2KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoMiksdGhpcy52aWV3LnNldFVpbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZUkxNigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDIpLHRoaXMudmlldy5zZXRJbnQxNih0aGlzLnBvcywkKSx0aGlzLnBvcys9Mn13cml0ZVUzMigkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDQpLHRoaXMudmlldy5zZXRVaW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVJMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0SW50MzIodGhpcy5wb3MsJCksdGhpcy5wb3MrPTR9d3JpdGVGMzIoJCl7dGhpcy5lbnN1cmVCdWZmZXJTaXplVG9Xcml0ZSg0KSx0aGlzLnZpZXcuc2V0RmxvYXQzMih0aGlzLnBvcywkKSx0aGlzLnBvcys9NH13cml0ZUY2NCgkKXt0aGlzLmVuc3VyZUJ1ZmZlclNpemVUb1dyaXRlKDgpLHRoaXMudmlldy5zZXRGbG9hdDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlVTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksUkoodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlSTY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksSCQodGhpcy52aWV3LHRoaXMucG9zLCQpLHRoaXMucG9zKz04fXdyaXRlQmlnVWludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ1VpbnQ2NCh0aGlzLnBvcywkKSx0aGlzLnBvcys9OH13cml0ZUJpZ0ludDY0KCQpe3RoaXMuZW5zdXJlQnVmZmVyU2l6ZVRvV3JpdGUoOCksdGhpcy52aWV3LnNldEJpZ0ludDY0KHRoaXMucG9zLCQpLHRoaXMucG9zKz04fX1mdW5jdGlvbiBfMCgkLFope3JldHVybiBuZXcgQyQoWikuZW5jb2RlU2hhcmVkUmVmKCQpfWZ1bmN0aW9uIFAkKCQpe3JldHVybmAkeyQ8MD8iLSI6IiJ9MHgke01hdGguYWJzKCQpLnRvU3RyaW5nKDE2KS5wYWRTdGFydCgyLCIwIil9YH12YXIgZFE9MTYsclE9MTY7Y2xhc3MgJFp7aGl0PTA7bWlzcz0wO2NhY2hlczttYXhLZXlMZW5ndGg7bWF4TGVuZ3RoUGVyS2V5O2NvbnN0cnVjdG9yKCQ9ZFEsWj1yUSl7dGhpcy5tYXhLZXlMZW5ndGg9JCx0aGlzLm1heExlbmd0aFBlcktleT1aLHRoaXMuY2FjaGVzPVtdO2ZvcihsZXQgSj0wO0o8dGhpcy5tYXhLZXlMZW5ndGg7SisrKXRoaXMuY2FjaGVzLnB1c2goW10pfWNhbkJlQ2FjaGVkKCQpe3JldHVybiAkPjAmJiQ8PXRoaXMubWF4S2V5TGVuZ3RofWZpbmQoJCxaLEope2xldCBRPXRoaXMuY2FjaGVzW0otMV07JDpmb3IobGV0IFYgb2YgUSl7bGV0IFk9Vi5ieXRlcztmb3IobGV0IFg9MDtYPEo7WCsrKWlmKFlbWF0hPT0kW1orWF0pY29udGludWUgJDtyZXR1cm4gVi5zdHJ9cmV0dXJuIG51bGx9c3RvcmUoJCxaKXtsZXQgSj10aGlzLmNhY2hlc1skLmxlbmd0aC0xXSxRPXtieXRlczokLHN0cjpafTtpZihKLmxlbmd0aD49dGhpcy5tYXhMZW5ndGhQZXJLZXkpSltNYXRoLnJhbmRvbSgpKkoubGVuZ3RofDBdPVE7ZWxzZSBKLnB1c2goUSl9ZGVjb2RlKCQsWixKKXtsZXQgUT10aGlzLmZpbmQoJCxaLEopO2lmKFEhPW51bGwpcmV0dXJuIHRoaXMuaGl0KyssUTt0aGlzLm1pc3MrKztsZXQgVj1lJCgkLFosSiksWT1VaW50OEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKCQsWixaK0opO3JldHVybiB0aGlzLnN0b3JlKFksViksVn19dmFyIFpaPSJhcnJheSIsWSQ9Im1hcF9rZXkiLElKPSJtYXBfdmFsdWUiLG9RPSgkKT0+e2lmKHR5cGVvZiAkPT09InN0cmluZyJ8fHR5cGVvZiAkPT09Im51bWJlciIpcmV0dXJuICQ7dGhyb3cgbmV3IHMoIlRoZSB0eXBlIG9mIGtleSBtdXN0IGJlIHN0cmluZyBvciBudW1iZXIgYnV0ICIrdHlwZW9mICQpfTtjbGFzcyBISntzdGFjaz1bXTtzdGFja0hlYWRQb3NpdGlvbj0tMTtnZXQgbGVuZ3RoKCl7cmV0dXJuIHRoaXMuc3RhY2tIZWFkUG9zaXRpb24rMX10b3AoKXtyZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1wdXNoQXJyYXlTdGF0ZSgkKXtsZXQgWj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Wi50eXBlPVpaLFoucG9zaXRpb249MCxaLnNpemU9JCxaLmFycmF5PUFycmF5KCQpfXB1c2hNYXBTdGF0ZSgkKXtsZXQgWj10aGlzLmdldFVuaW5pdGlhbGl6ZWRTdGF0ZUZyb21Qb29sKCk7Wi50eXBlPVkkLFoucmVhZENvdW50PTAsWi5zaXplPSQsWi5tYXA9e319Z2V0VW5pbml0aWFsaXplZFN0YXRlRnJvbVBvb2woKXtpZih0aGlzLnN0YWNrSGVhZFBvc2l0aW9uKyssdGhpcy5zdGFja0hlYWRQb3NpdGlvbj09PXRoaXMuc3RhY2subGVuZ3RoKXtsZXQgJD17dHlwZTp2b2lkIDAsc2l6ZTowLGFycmF5OnZvaWQgMCxwb3NpdGlvbjowLHJlYWRDb3VudDowLG1hcDp2b2lkIDAsa2V5Om51bGx9O3RoaXMuc3RhY2sucHVzaCgkKX1yZXR1cm4gdGhpcy5zdGFja1t0aGlzLnN0YWNrSGVhZFBvc2l0aW9uXX1yZWxlYXNlKCQpe2lmKHRoaXMuc3RhY2tbdGhpcy5zdGFja0hlYWRQb3NpdGlvbl0hPT0kKXRocm93IEVycm9yKCJJbnZhbGlkIHN0YWNrIHN0YXRlLiBSZWxlYXNlZCBzdGF0ZSBpcyBub3Qgb24gdG9wIG9mIHRoZSBzdGFjay4iKTtpZigkLnR5cGU9PT1aWil7bGV0IEo9JDtKLnNpemU9MCxKLmFycmF5PXZvaWQgMCxKLnBvc2l0aW9uPTAsSi50eXBlPXZvaWQgMH1pZigkLnR5cGU9PT1ZJHx8JC50eXBlPT09SUope2xldCBKPSQ7Si5zaXplPTAsSi5tYXA9dm9pZCAwLEoucmVhZENvdW50PTAsSi50eXBlPXZvaWQgMH10aGlzLnN0YWNrSGVhZFBvc2l0aW9uLS19cmVzZXQoKXt0aGlzLnN0YWNrLmxlbmd0aD0wLHRoaXMuc3RhY2tIZWFkUG9zaXRpb249LTF9fXZhciBWJD0tMSxKWj1uZXcgRGF0YVZpZXcobmV3IEFycmF5QnVmZmVyKDApKSxhUT1uZXcgVWludDhBcnJheShKWi5idWZmZXIpO3RyeXtKWi5nZXRJbnQ4KDApfWNhdGNoKCQpe2lmKCEoJCBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IEVycm9yKCJUaGlzIG1vZHVsZSBpcyBub3Qgc3VwcG9ydGVkIGluIHRoZSBjdXJyZW50IEphdmFTY3JpcHQgZW5naW5lIGJlY2F1c2UgRGF0YVZpZXcgZG9lcyBub3QgdGhyb3cgUmFuZ2VFcnJvciBvbiBvdXQtb2YtYm91bmRzIGFjY2VzcyIpfXZhciBxSj1SYW5nZUVycm9yKCJJbnN1ZmZpY2llbnQgZGF0YSIpLHNRPW5ldyAkWjtjbGFzcyB3JHtleHRlbnNpb25Db2RlYztjb250ZXh0O3VzZUJpZ0ludDY0O3Jhd1N0cmluZ3M7bWF4U3RyTGVuZ3RoO21heEJpbkxlbmd0aDttYXhBcnJheUxlbmd0aDttYXhNYXBMZW5ndGg7bWF4RXh0TGVuZ3RoO2tleURlY29kZXI7bWFwS2V5Q29udmVydGVyO3RvdGFsUG9zPTA7cG9zPTA7dmlldz1KWjtieXRlcz1hUTtoZWFkQnl0ZT1WJDtzdGFjaz1uZXcgSEo7ZW50ZXJlZD0hMTtjb25zdHJ1Y3RvcigkKXt0aGlzLmV4dGVuc2lvbkNvZGVjPSQ/LmV4dGVuc2lvbkNvZGVjPz9wMC5kZWZhdWx0Q29kZWMsdGhpcy5jb250ZXh0PSQ/LmNvbnRleHQsdGhpcy51c2VCaWdJbnQ2ND0kPy51c2VCaWdJbnQ2ND8/ITEsdGhpcy5yYXdTdHJpbmdzPSQ/LnJhd1N0cmluZ3M/PyExLHRoaXMubWF4U3RyTGVuZ3RoPSQ/Lm1heFN0ckxlbmd0aD8/bDAsdGhpcy5tYXhCaW5MZW5ndGg9JD8ubWF4QmluTGVuZ3RoPz9sMCx0aGlzLm1heEFycmF5TGVuZ3RoPSQ/Lm1heEFycmF5TGVuZ3RoPz9sMCx0aGlzLm1heE1hcExlbmd0aD0kPy5tYXhNYXBMZW5ndGg/P2wwLHRoaXMubWF4RXh0TGVuZ3RoPSQ/Lm1heEV4dExlbmd0aD8/bDAsdGhpcy5rZXlEZWNvZGVyPSQ/LmtleURlY29kZXIhPT12b2lkIDA/JC5rZXlEZWNvZGVyOnNRLHRoaXMubWFwS2V5Q29udmVydGVyPSQ/Lm1hcEtleUNvbnZlcnRlcj8/b1F9Y2xvbmUoKXtyZXR1cm4gbmV3IHckKHtleHRlbnNpb25Db2RlYzp0aGlzLmV4dGVuc2lvbkNvZGVjLGNvbnRleHQ6dGhpcy5jb250ZXh0LHVzZUJpZ0ludDY0OnRoaXMudXNlQmlnSW50NjQscmF3U3RyaW5nczp0aGlzLnJhd1N0cmluZ3MsbWF4U3RyTGVuZ3RoOnRoaXMubWF4U3RyTGVuZ3RoLG1heEJpbkxlbmd0aDp0aGlzLm1heEJpbkxlbmd0aCxtYXhBcnJheUxlbmd0aDp0aGlzLm1heEFycmF5TGVuZ3RoLG1heE1hcExlbmd0aDp0aGlzLm1heE1hcExlbmd0aCxtYXhFeHRMZW5ndGg6dGhpcy5tYXhFeHRMZW5ndGgsa2V5RGVjb2Rlcjp0aGlzLmtleURlY29kZXJ9KX1yZWluaXRpYWxpemVTdGF0ZSgpe3RoaXMudG90YWxQb3M9MCx0aGlzLmhlYWRCeXRlPVYkLHRoaXMuc3RhY2sucmVzZXQoKX1zZXRCdWZmZXIoJCl7bGV0IFo9USQoJCk7dGhpcy5ieXRlcz1aLHRoaXMudmlldz1uZXcgRGF0YVZpZXcoWi5idWZmZXIsWi5ieXRlT2Zmc2V0LFouYnl0ZUxlbmd0aCksdGhpcy5wb3M9MH1hcHBlbmRCdWZmZXIoJCl7aWYodGhpcy5oZWFkQnl0ZT09PVYkJiYhdGhpcy5oYXNSZW1haW5pbmcoMSkpdGhpcy5zZXRCdWZmZXIoJCk7ZWxzZXtsZXQgWj10aGlzLmJ5dGVzLnN1YmFycmF5KHRoaXMucG9zKSxKPVEkKCQpLFE9bmV3IFVpbnQ4QXJyYXkoWi5sZW5ndGgrSi5sZW5ndGgpO1Euc2V0KFopLFEuc2V0KEosWi5sZW5ndGgpLHRoaXMuc2V0QnVmZmVyKFEpfX1oYXNSZW1haW5pbmcoJCl7cmV0dXJuIHRoaXMudmlldy5ieXRlTGVuZ3RoLXRoaXMucG9zPj0kfWNyZWF0ZUV4dHJhQnl0ZUVycm9yKCQpe2xldHt2aWV3OloscG9zOkp9PXRoaXM7cmV0dXJuIFJhbmdlRXJyb3IoYEV4dHJhICR7Wi5ieXRlTGVuZ3RoLUp9IG9mICR7Wi5ieXRlTGVuZ3RofSBieXRlKHMpIGZvdW5kIGF0IGJ1ZmZlclskeyR9XWApfWRlY29kZSgkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGUoJCk7dHJ5e3RoaXMuZW50ZXJlZD0hMCx0aGlzLnJlaW5pdGlhbGl6ZVN0YXRlKCksdGhpcy5zZXRCdWZmZXIoJCk7bGV0IFo9dGhpcy5kb0RlY29kZVN5bmMoKTtpZih0aGlzLmhhc1JlbWFpbmluZygxKSl0aHJvdyB0aGlzLmNyZWF0ZUV4dHJhQnl0ZUVycm9yKHRoaXMucG9zKTtyZXR1cm4gWn1maW5hbGx5e3RoaXMuZW50ZXJlZD0hMX19KmRlY29kZU11bHRpKCQpe2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpKCQpO3JldHVybn10cnl7dGhpcy5lbnRlcmVkPSEwLHRoaXMucmVpbml0aWFsaXplU3RhdGUoKSx0aGlzLnNldEJ1ZmZlcigkKTt3aGlsZSh0aGlzLmhhc1JlbWFpbmluZygxKSl5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpfWZpbmFsbHl7dGhpcy5lbnRlcmVkPSExfX1hc3luYyBkZWNvZGVBc3luYygkKXtpZih0aGlzLmVudGVyZWQpcmV0dXJuIHRoaXMuY2xvbmUoKS5kZWNvZGVBc3luYygkKTt0cnl7dGhpcy5lbnRlcmVkPSEwO2xldCBaPSExLEo7Zm9yIGF3YWl0KGxldCBYIG9mICQpe2lmKFopdGhyb3cgdGhpcy5lbnRlcmVkPSExLHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7dGhpcy5hcHBlbmRCdWZmZXIoWCk7dHJ5e0o9dGhpcy5kb0RlY29kZVN5bmMoKSxaPSEwfWNhdGNoKFcpe2lmKCEoVyBpbnN0YW5jZW9mIFJhbmdlRXJyb3IpKXRocm93IFd9dGhpcy50b3RhbFBvcys9dGhpcy5wb3N9aWYoWil7aWYodGhpcy5oYXNSZW1haW5pbmcoMSkpdGhyb3cgdGhpcy5jcmVhdGVFeHRyYUJ5dGVFcnJvcih0aGlzLnRvdGFsUG9zKTtyZXR1cm4gSn1sZXR7aGVhZEJ5dGU6USxwb3M6Vix0b3RhbFBvczpZfT10aGlzO3Rocm93IFJhbmdlRXJyb3IoYEluc3VmZmljaWVudCBkYXRhIGluIHBhcnNpbmcgJHtQJChRKX0gYXQgJHtZfSAoJHtWfSBpbiB0aGUgY3VycmVudCBidWZmZXIpYCl9ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRlY29kZUFycmF5U3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMCl9ZGVjb2RlU3RyZWFtKCQpe3JldHVybiB0aGlzLmRlY29kZU11bHRpQXN5bmMoJCwhMSl9YXN5bmMqZGVjb2RlTXVsdGlBc3luYygkLFope2lmKHRoaXMuZW50ZXJlZCl7eWllbGQqdGhpcy5jbG9uZSgpLmRlY29kZU11bHRpQXN5bmMoJCxaKTtyZXR1cm59dHJ5e3RoaXMuZW50ZXJlZD0hMDtsZXQgSj1aLFE9LTE7Zm9yIGF3YWl0KGxldCBWIG9mICQpe2lmKFomJlE9PT0wKXRocm93IHRoaXMuY3JlYXRlRXh0cmFCeXRlRXJyb3IodGhpcy50b3RhbFBvcyk7aWYodGhpcy5hcHBlbmRCdWZmZXIoViksSilRPXRoaXMucmVhZEFycmF5U2l6ZSgpLEo9ITEsdGhpcy5jb21wbGV0ZSgpO3RyeXt3aGlsZSghMClpZih5aWVsZCB0aGlzLmRvRGVjb2RlU3luYygpLC0tUT09PTApYnJlYWt9Y2F0Y2goWSl7aWYoIShZIGluc3RhbmNlb2YgUmFuZ2VFcnJvcikpdGhyb3cgWX10aGlzLnRvdGFsUG9zKz10aGlzLnBvc319ZmluYWxseXt0aGlzLmVudGVyZWQ9ITF9fWRvRGVjb2RlU3luYygpeyQ6d2hpbGUoITApe2xldCAkPXRoaXMucmVhZEhlYWRCeXRlKCksWjtpZigkPj0yMjQpWj0kLTI1NjtlbHNlIGlmKCQ8MTkyKWlmKCQ8MTI4KVo9JDtlbHNlIGlmKCQ8MTQ0KXtsZXQgUT0kLTEyODtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBaPXt9fWVsc2UgaWYoJDwxNjApe2xldCBRPSQtMTQ0O2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNle2xldCBRPSQtMTYwO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwwKX1lbHNlIGlmKCQ9PT0xOTIpWj1udWxsO2Vsc2UgaWYoJD09PTE5NClaPSExO2Vsc2UgaWYoJD09PTE5NSlaPSEwO2Vsc2UgaWYoJD09PTIwMilaPXRoaXMucmVhZEYzMigpO2Vsc2UgaWYoJD09PTIwMylaPXRoaXMucmVhZEY2NCgpO2Vsc2UgaWYoJD09PTIwNClaPXRoaXMucmVhZFU4KCk7ZWxzZSBpZigkPT09MjA1KVo9dGhpcy5yZWFkVTE2KCk7ZWxzZSBpZigkPT09MjA2KVo9dGhpcy5yZWFkVTMyKCk7ZWxzZSBpZigkPT09MjA3KWlmKHRoaXMudXNlQmlnSW50NjQpWj10aGlzLnJlYWRVNjRBc0JpZ0ludCgpO2Vsc2UgWj10aGlzLnJlYWRVNjQoKTtlbHNlIGlmKCQ9PT0yMDgpWj10aGlzLnJlYWRJOCgpO2Vsc2UgaWYoJD09PTIwOSlaPXRoaXMucmVhZEkxNigpO2Vsc2UgaWYoJD09PTIxMClaPXRoaXMucmVhZEkzMigpO2Vsc2UgaWYoJD09PTIxMSlpZih0aGlzLnVzZUJpZ0ludDY0KVo9dGhpcy5yZWFkSTY0QXNCaWdJbnQoKTtlbHNlIFo9dGhpcy5yZWFkSTY0KCk7ZWxzZSBpZigkPT09MjE3KXtsZXQgUT10aGlzLmxvb2tVOCgpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwxKX1lbHNlIGlmKCQ9PT0yMTgpe2xldCBRPXRoaXMubG9va1UxNigpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSwyKX1lbHNlIGlmKCQ9PT0yMTkpe2xldCBRPXRoaXMubG9va1UzMigpO1o9dGhpcy5kZWNvZGVTdHJpbmcoUSw0KX1lbHNlIGlmKCQ9PT0yMjApe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNlIGlmKCQ9PT0yMjEpe2xldCBRPXRoaXMucmVhZFUzMigpO2lmKFEhPT0wKXt0aGlzLnB1c2hBcnJheVN0YXRlKFEpLHRoaXMuY29tcGxldGUoKTtjb250aW51ZSAkfWVsc2UgWj1bXX1lbHNlIGlmKCQ9PT0yMjIpe2xldCBRPXRoaXMucmVhZFUxNigpO2lmKFEhPT0wKXt0aGlzLnB1c2hNYXBTdGF0ZShRKSx0aGlzLmNvbXBsZXRlKCk7Y29udGludWUgJH1lbHNlIFo9e319ZWxzZSBpZigkPT09MjIzKXtsZXQgUT10aGlzLnJlYWRVMzIoKTtpZihRIT09MCl7dGhpcy5wdXNoTWFwU3RhdGUoUSksdGhpcy5jb21wbGV0ZSgpO2NvbnRpbnVlICR9ZWxzZSBaPXt9fWVsc2UgaWYoJD09PTE5Nil7bGV0IFE9dGhpcy5sb29rVTgoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsMSl9ZWxzZSBpZigkPT09MTk3KXtsZXQgUT10aGlzLmxvb2tVMTYoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsMil9ZWxzZSBpZigkPT09MTk4KXtsZXQgUT10aGlzLmxvb2tVMzIoKTtaPXRoaXMuZGVjb2RlQmluYXJ5KFEsNCl9ZWxzZSBpZigkPT09MjEyKVo9dGhpcy5kZWNvZGVFeHRlbnNpb24oMSwwKTtlbHNlIGlmKCQ9PT0yMTMpWj10aGlzLmRlY29kZUV4dGVuc2lvbigyLDApO2Vsc2UgaWYoJD09PTIxNClaPXRoaXMuZGVjb2RlRXh0ZW5zaW9uKDQsMCk7ZWxzZSBpZigkPT09MjE1KVo9dGhpcy5kZWNvZGVFeHRlbnNpb24oOCwwKTtlbHNlIGlmKCQ9PT0yMTYpWj10aGlzLmRlY29kZUV4dGVuc2lvbigxNiwwKTtlbHNlIGlmKCQ9PT0xOTkpe2xldCBRPXRoaXMubG9va1U4KCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDEpfWVsc2UgaWYoJD09PTIwMCl7bGV0IFE9dGhpcy5sb29rVTE2KCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDIpfWVsc2UgaWYoJD09PTIwMSl7bGV0IFE9dGhpcy5sb29rVTMyKCk7Wj10aGlzLmRlY29kZUV4dGVuc2lvbihRLDQpfWVsc2UgdGhyb3cgbmV3IHMoYFVucmVjb2duaXplZCB0eXBlIGJ5dGU6ICR7UCQoJCl9YCk7dGhpcy5jb21wbGV0ZSgpO2xldCBKPXRoaXMuc3RhY2s7d2hpbGUoSi5sZW5ndGg+MCl7bGV0IFE9Si50b3AoKTtpZihRLnR5cGU9PT1aWilpZihRLmFycmF5W1EucG9zaXRpb25dPVosUS5wb3NpdGlvbisrLFEucG9zaXRpb249PT1RLnNpemUpWj1RLmFycmF5LEoucmVsZWFzZShRKTtlbHNlIGNvbnRpbnVlICQ7ZWxzZSBpZihRLnR5cGU9PT1ZJCl7aWYoWj09PSJfX3Byb3RvX18iKXRocm93IG5ldyBzKCJUaGUga2V5IF9fcHJvdG9fXyBpcyBub3QgYWxsb3dlZCIpO1Eua2V5PXRoaXMubWFwS2V5Q29udmVydGVyKFopLFEudHlwZT1JSjtjb250aW51ZSAkfWVsc2UgaWYoUS5tYXBbUS5rZXldPVosUS5yZWFkQ291bnQrKyxRLnJlYWRDb3VudD09PVEuc2l6ZSlaPVEubWFwLEoucmVsZWFzZShRKTtlbHNle1Eua2V5PW51bGwsUS50eXBlPVkkO2NvbnRpbnVlICR9fXJldHVybiBafX1yZWFkSGVhZEJ5dGUoKXtpZih0aGlzLmhlYWRCeXRlPT09ViQpdGhpcy5oZWFkQnl0ZT10aGlzLnJlYWRVOCgpO3JldHVybiB0aGlzLmhlYWRCeXRlfWNvbXBsZXRlKCl7dGhpcy5oZWFkQnl0ZT1WJH1yZWFkQXJyYXlTaXplKCl7bGV0ICQ9dGhpcy5yZWFkSGVhZEJ5dGUoKTtzd2l0Y2goJCl7Y2FzZSAyMjA6cmV0dXJuIHRoaXMucmVhZFUxNigpO2Nhc2UgMjIxOnJldHVybiB0aGlzLnJlYWRVMzIoKTtkZWZhdWx0OmlmKCQ8MTYwKXJldHVybiAkLTE0NDtlbHNlIHRocm93IG5ldyBzKGBVbnJlY29nbml6ZWQgYXJyYXkgdHlwZSBieXRlOiAke1AkKCQpfWApfX1wdXNoTWFwU3RhdGUoJCl7aWYoJD50aGlzLm1heE1hcExlbmd0aCl0aHJvdyBuZXcgcyhgTWF4IGxlbmd0aCBleGNlZWRlZDogbWFwIGxlbmd0aCAoJHskfSkgPiBtYXhNYXBMZW5ndGhMZW5ndGggKCR7dGhpcy5tYXhNYXBMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaE1hcFN0YXRlKCQpfXB1c2hBcnJheVN0YXRlKCQpe2lmKCQ+dGhpcy5tYXhBcnJheUxlbmd0aCl0aHJvdyBuZXcgcyhgTWF4IGxlbmd0aCBleGNlZWRlZDogYXJyYXkgbGVuZ3RoICgkeyR9KSA+IG1heEFycmF5TGVuZ3RoICgke3RoaXMubWF4QXJyYXlMZW5ndGh9KWApO3RoaXMuc3RhY2sucHVzaEFycmF5U3RhdGUoJCl9ZGVjb2RlU3RyaW5nKCQsWil7aWYoIXRoaXMucmF3U3RyaW5nc3x8dGhpcy5zdGF0ZUlzTWFwS2V5KCkpcmV0dXJuIHRoaXMuZGVjb2RlVXRmOFN0cmluZygkLFopO3JldHVybiB0aGlzLmRlY29kZUJpbmFyeSgkLFopfWRlY29kZVV0ZjhTdHJpbmcoJCxaKXtpZigkPnRoaXMubWF4U3RyTGVuZ3RoKXRocm93IG5ldyBzKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBVVEYtOCBieXRlIGxlbmd0aCAoJHskfSkgPiBtYXhTdHJMZW5ndGggKCR7dGhpcy5tYXhTdHJMZW5ndGh9KWApO2lmKHRoaXMuYnl0ZXMuYnl0ZUxlbmd0aDx0aGlzLnBvcytaKyQpdGhyb3cgcUo7bGV0IEo9dGhpcy5wb3MrWixRO2lmKHRoaXMuc3RhdGVJc01hcEtleSgpJiZ0aGlzLmtleURlY29kZXI/LmNhbkJlQ2FjaGVkKCQpKVE9dGhpcy5rZXlEZWNvZGVyLmRlY29kZSh0aGlzLmJ5dGVzLEosJCk7ZWxzZSBRPU5KKHRoaXMuYnl0ZXMsSiwkKTtyZXR1cm4gdGhpcy5wb3MrPVorJCxRfXN0YXRlSXNNYXBLZXkoKXtpZih0aGlzLnN0YWNrLmxlbmd0aD4wKXJldHVybiB0aGlzLnN0YWNrLnRvcCgpLnR5cGU9PT1ZJDtyZXR1cm4hMX1kZWNvZGVCaW5hcnkoJCxaKXtpZigkPnRoaXMubWF4QmluTGVuZ3RoKXRocm93IG5ldyBzKGBNYXggbGVuZ3RoIGV4Y2VlZGVkOiBiaW4gbGVuZ3RoICgkeyR9KSA+IG1heEJpbkxlbmd0aCAoJHt0aGlzLm1heEJpbkxlbmd0aH0pYCk7aWYoIXRoaXMuaGFzUmVtYWluaW5nKCQrWikpdGhyb3cgcUo7bGV0IEo9dGhpcy5wb3MrWixRPXRoaXMuYnl0ZXMuc3ViYXJyYXkoSixKKyQpO3JldHVybiB0aGlzLnBvcys9WiskLFF9ZGVjb2RlRXh0ZW5zaW9uKCQsWil7aWYoJD50aGlzLm1heEV4dExlbmd0aCl0aHJvdyBuZXcgcyhgTWF4IGxlbmd0aCBleGNlZWRlZDogZXh0IGxlbmd0aCAoJHskfSkgPiBtYXhFeHRMZW5ndGggKCR7dGhpcy5tYXhFeHRMZW5ndGh9KWApO2xldCBKPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zK1opLFE9dGhpcy5kZWNvZGVCaW5hcnkoJCxaKzEpO3JldHVybiB0aGlzLmV4dGVuc2lvbkNvZGVjLmRlY29kZShRLEosdGhpcy5jb250ZXh0KX1sb29rVTgoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKX1sb29rVTE2KCl7cmV0dXJuIHRoaXMudmlldy5nZXRVaW50MTYodGhpcy5wb3MpfWxvb2tVMzIoKXtyZXR1cm4gdGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyl9cmVhZFU4KCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRJOCgpe2xldCAkPXRoaXMudmlldy5nZXRJbnQ4KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrKywkfXJlYWRVMTYoKXtsZXQgJD10aGlzLnZpZXcuZ2V0VWludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkSTE2KCl7bGV0ICQ9dGhpcy52aWV3LmdldEludDE2KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTIsJH1yZWFkVTMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldFVpbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZEkzMigpe2xldCAkPXRoaXMudmlldy5nZXRJbnQzMih0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz00LCR9cmVhZFU2NCgpe2xldCAkPVVKKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NCgpe2xldCAkPU0kKHRoaXMudmlldyx0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZFU2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ1VpbnQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9cmVhZEk2NEFzQmlnSW50KCl7bGV0ICQ9dGhpcy52aWV3LmdldEJpZ0ludDY0KHRoaXMucG9zKTtyZXR1cm4gdGhpcy5wb3MrPTgsJH1yZWFkRjMyKCl7bGV0ICQ9dGhpcy52aWV3LmdldEZsb2F0MzIodGhpcy5wb3MpO3JldHVybiB0aGlzLnBvcys9NCwkfXJlYWRGNjQoKXtsZXQgJD10aGlzLnZpZXcuZ2V0RmxvYXQ2NCh0aGlzLnBvcyk7cmV0dXJuIHRoaXMucG9zKz04LCR9fWZ1bmN0aW9uIFFaKCQsWil7cmV0dXJuIG5ldyB3JChaKS5kZWNvZGUoJCl9Y2xhc3MgWCR7bGlzdGVuZXJzPW5ldyBNYXA7YWRkRXZlbnRMaXN0ZW5lcigkLFope2xldCBKPXRoaXMubGlzdGVuZXJzLmdldCgkKTtpZighSilKPW5ldyBTZXQsdGhpcy5saXN0ZW5lcnMuc2V0KCQsSik7cmV0dXJuIEouYWRkKFopLCgpPT57dGhpcy5yZW1vdmVFdmVudExpc3RlbmVyKCQsWil9fXJlbW92ZUV2ZW50TGlzdGVuZXIoJCxaKXtsZXQgSj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoSil7aWYoSi5kZWxldGUoWiksSi5zaXplPT09MCl0aGlzLmxpc3RlbmVycy5kZWxldGUoJCl9fWVtaXQoJCxaKXtsZXQgSj10aGlzLmxpc3RlbmVycy5nZXQoJCk7aWYoSil7bGV0IFE9QXJyYXkuZnJvbShKKTtmb3IobGV0IFYgb2YgUSlWKFopfX1lbWl0QWxsKCQpe2xldCBaPUFycmF5LmZyb20odGhpcy5saXN0ZW5lcnMua2V5cygpKTtmb3IobGV0IEogb2YgWil0aGlzLmVtaXQoSiwkKX19Y2xhc3MgTDB7Z2V0dGVyO3N0YXRpYyBldmVudE5hbWU9InVwZGF0ZSI7ZW1pdHRlcjtjb25zdHJ1Y3RvcigkKXt0aGlzLmdldHRlcj0kO3RoaXMuZW1pdHRlcj1uZXcgWCR9Z2V0PSgpPT50aGlzLmdldHRlcigpO2FzeW5jIGVtaXQoKXtsZXQgJD1hd2FpdCB0aGlzLmdldHRlcigpO3F1ZXVlTWljcm90YXNrKCgpPT50aGlzLmVtaXR0ZXIuZW1pdChMMC5ldmVudE5hbWUsJCkpfWxpc3RlbigkKXtyZXR1cm4gdGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoTDAuZXZlbnROYW1lLCQpLCgpPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoTDAuZXZlbnROYW1lLCQpfX19ZnVuY3Rpb24gUigkKXtyZXR1cm5bJCwwXX1mdW5jdGlvbiBHKCQpe3JldHVyblt2b2lkIDAsJF19ZnVuY3Rpb24gdFEoJCl7aWYoJDwwKWNvbnNvbGUuaW5mbygiTiIsJCksY29uc29sZS50cmFjZSgpO2lmKHR5cGVvZiAkIT09ImJpZ2ludCIpJD1CaWdJbnQoJCk7aWYoJDwwbilyZXR1cm4gRygxMCk7bGV0IFo9W107d2hpbGUoJD4wbil7bGV0IEo9TnVtYmVyKCQmMHg3Zm4pO2lmKCQ+Pj03biwkPjBuKVoucHVzaChKfDEyOCk7ZWxzZSBaLnB1c2goSil9aWYoWi5sZW5ndGg9PT0wKXJldHVybiBSKG5ldyBVaW50OEFycmF5KFswXSkpO2lmKFoubGVuZ3RoPjgpcmV0dXJuIEcoMjYpO3JldHVybiBSKG5ldyBVaW50OEFycmF5KFopKX1mdW5jdGlvbiBlUSgkLFo9MCl7bGV0IEo9MG4sUT0wLFY9Wjt3aGlsZSghMCl7aWYoVj49JC5sZW5ndGgpcmV0dXJuIEcoMTQpO2xldCBZPSRbVisrXTtpZihZPT09dm9pZCAwKXJldHVybiBHKDE0KTtpZihKfD1CaWdJbnQoWSYxMjcpPDxCaWdJbnQoUSksKFkmMTI4KT09PTApe2lmKFYtWj44KXJldHVybiBHKDI2KTtyZXR1cm4gUih7dmFsdWU6Sj4weDFmZmZmZmZmZmZmZmZmbj9KOk51bWJlcihKKSxieXRlc1JlYWQ6Vi1afSl9aWYoUSs9NyxRPj01NilyZXR1cm4gRygyNil9fWNsYXNzIGd7ZGF0YTtwb3M9MDtjb25zdHJ1Y3RvcigkKXt0aGlzLmRhdGE9JH1zdGF0aWMgYXN5bmMgZnJvbVJlc3BvbnNlKCQpe2xldCBaPWF3YWl0ICQuYXJyYXlCdWZmZXIoKSxKPW5ldyBVaW50OEFycmF5KFopO3JldHVybiBuZXcgZyhKKX1yZWFkQmlnSW50KCl7aWYodGhpcy5wb3MrOD50aGlzLmRhdGEubGVuZ3RoKXJldHVybiBHKDcpO2xldCAkPW5ldyBEYXRhVmlldyh0aGlzLmRhdGEuYnVmZmVyLHRoaXMuZGF0YS5ieXRlT2Zmc2V0K3RoaXMucG9zKS5nZXRCaWdVaW50NjQoMCwhMSk7cmV0dXJuIHRoaXMucG9zKz04LFIoJCl9cmVhZERhdGUoKXtsZXRbJCxaXT10aGlzLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gUihuZXcgRGF0ZSgkKSl9cmVhZFZhckludCgpe2xldFskLFpdPWVRKHRoaXMuZGF0YSx0aGlzLnBvcyk7aWYoWiE9PTApcmV0dXJuIEcoWik7dGhpcy5wb3MrPSQuYnl0ZXNSZWFkO2xldCBKPSQudmFsdWU7cmV0dXJuIFIodHlwZW9mIEo9PT0iYmlnaW50Ij9OdW1iZXIoSik6Sil9cmVhZFZhclN0cmluZygpe2xldFskLFpdPXRoaXMucmVhZFZhckludCgpO2lmKFohPT0wKXJldHVybiBHKFopO2xldFtKLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBWPW5ldyBUZXh0RGVjb2RlcigpLmRlY29kZShKKTtyZXR1cm4gUihWKX1yZWFkQnl0ZXMoJCl7aWYoJDwwKXJldHVybiBHKDEwKTtpZih0aGlzLnBvcyskPnRoaXMuZGF0YS5sZW5ndGgpcmV0dXJuIEcoMjMpO2xldCBaPXRoaXMuZGF0YS5zbGljZSh0aGlzLnBvcyx0aGlzLnBvcyskKTtyZXR1cm4gdGhpcy5wb3MrPSQsUihaKX1yZWFkVmFyQnl0ZXMoKXtsZXRbJCxaXT10aGlzLnJlYWRWYXJJbnQoKTtpZihaIT09MClyZXR1cm4gRyhaKTtyZXR1cm4gdGhpcy5yZWFkQnl0ZXMoJCl9cmVhZFN0cnVjdCgkKXtyZXR1cm4gJC5kZWNvZGUodGhpcyl9cmVhZFN0cnVjdHMoJCl7bGV0IFo9W107d2hpbGUoIXRoaXMuZG9uZSgpKXtsZXRbSixRXT10aGlzLnJlYWRTdHJ1Y3QoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7Wi5wdXNoKEopfXJldHVybiBSKFopfXJlYWRCeXRlc1NlcSgkKXtsZXQgWj1bXTt3aGlsZSghdGhpcy5kb25lKCkpe2xldFtKLFFdPXRoaXMucmVhZEJ5dGVzKCQpO2lmKFEhPT0wKXJldHVybiBHKFEpO1oucHVzaChKKX1yZXR1cm4gUihaKX1kb25lKCl7cmV0dXJuIHRoaXMucG9zPj10aGlzLmRhdGEubGVuZ3RofWNvbnN1bWVkKCl7cmV0dXJuIHRoaXMucG9zfX1jbGFzcyBTe3BhcnRzPVtdO3dyaXRlQmlnSW50KCQpe2xldCBaPW5ldyBVaW50OEFycmF5KDgpO25ldyBEYXRhVmlldyhaLmJ1ZmZlcikuc2V0QmlnVWludDY0KDAsJCwhMSksdGhpcy5wYXJ0cy5wdXNoKFopfXdyaXRlRGF0ZSgkKXtsZXQgWj0kLmdldFRpbWUoKTtyZXR1cm4gdGhpcy53cml0ZVZhckludChaKX13cml0ZVZhckludCgkKXtsZXRbWixKXT10USgkKTtpZihKIT09MClyZXR1cm4gSjtyZXR1cm4gdGhpcy5wYXJ0cy5wdXNoKFopLDB9d3JpdGVWYXJTdHJpbmcoJCl7bGV0IFo9bmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpLEo9dGhpcy53cml0ZVZhckludChaLmxlbmd0aCk7aWYoSiE9PTApcmV0dXJuIEo7cmV0dXJuIHRoaXMud3JpdGVCeXRlcyhaKSwwfXByZXBlbmRCeXRlcygkKXt0aGlzLnBhcnRzLnVuc2hpZnQoJCl9d3JpdGVCeXRlcygkKXt0aGlzLnBhcnRzLnB1c2goJCl9d3JpdGVWYXJCeXRlcygkKXtsZXQgWj10aGlzLndyaXRlVmFySW50KCQubGVuZ3RoKTtpZihaIT09MClyZXR1cm4gWjtyZXR1cm4gdGhpcy53cml0ZUJ5dGVzKCQpLDB9d3JpdGVTdHJ1Y3QoJCxaKXtyZXR1cm4gJC5lbmNvZGUodGhpcyxaKX13cml0ZVN0cnVjdHMoJCxaKXtmb3IobGV0IEogb2YgWil7bGV0IFE9dGhpcy53cml0ZVN0cnVjdCgkLEopO2lmKFEhPT0wKXJldHVybiBRfXJldHVybiAwfXdyaXRlQnl0ZXNTZXEoJCl7Zm9yKGxldCBaIG9mICQpdGhpcy53cml0ZUJ5dGVzKFopfXJlc3VsdCgpe2xldCAkPXRoaXMucGFydHMucmVkdWNlKChRLFYpPT5RK1YubGVuZ3RoLDApLFo9bmV3IFVpbnQ4QXJyYXkoJCksSj0wO2ZvcihsZXQgUSBvZiB0aGlzLnBhcnRzKVouc2V0KFEsSiksSis9US5sZW5ndGg7cmV0dXJuIFp9KnNjYW4oKXtmb3IobGV0ICQgb2YgdGhpcy5wYXJ0cyl5aWVsZCAkfX1hc3luYyBmdW5jdGlvbiBWWigkLFope2xldCBKPW5ldyBTLFE9Si53cml0ZURhdGUoWik7aWYoUSE9PTApcmV0dXJuIEcoUSk7bGV0IFY9Si5yZXN1bHQoKSxZPWF3YWl0ICQuc2lnbihWKTtyZXR1cm4gUih7cHViS2V5OiQucHVibGljS2V5LHNpZzpZLHRpbWVzdGFtcDpafSl9YXN5bmMgZnVuY3Rpb24gRDAoJCxaLEope2xldCBRPUoubm93KCkuZ2V0VGltZSgpLFY9JC50aW1lc3RhbXAuZ2V0VGltZSgpO2lmKE1hdGguYWJzKFEtVik+V0opcmV0dXJuIDQ7bGV0IFg9bmV3IFM7WC53cml0ZURhdGUoJC50aW1lc3RhbXApO2xldCBXPVgucmVzdWx0KCk7aWYoIWF3YWl0IFouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLFcsJC5wdWJLZXkpKXJldHVybiAzO3JldHVybiAwfXZhciBRMD17ZW5jb2RlKCQsWil7bGV0IEo9JC53cml0ZVZhckJ5dGVzKFouaWQpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVEYXRlKFoudHMpO2lmKFEhPT0wKXJldHVybiBRO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFyQnl0ZXMoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWREYXRlKCk7aWYoViE9PTApcmV0dXJuIEcoVik7cmV0dXJuIFIoe2lkOlosdHM6UX0pfX07ZnVuY3Rpb24gVCQoJCl7bGV0IFo9bmV3IFMsSj1aLndyaXRlU3RydWN0KFEwLCQpO2lmKEohPT0wKXJldHVybiBHKEopO2xldCBRPVoucmVzdWx0KCk7cmV0dXJuIFIoUSl9dmFyIFgwPXtlbmNvZGUoJCxaKXtsZXQgSj0kLndyaXRlVmFyQnl0ZXMoWi5laWQpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJJbnQoWi5vZmYpO2lmKFEhPT0wKXJldHVybiBRO2xldCBWPSQud3JpdGVWYXJJbnQoWi5jdHIpO2lmKFYhPT0wKXJldHVybiBWO2xldCBZPSQud3JpdGVWYXJJbnQoWi5sZW4pO2lmKFkhPT0wKXJldHVybiBZO2lmKFouaHNoKSQud3JpdGVCeXRlcyhaLmhzaCk7cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJCeXRlcygpO2lmKEohPT0wKXJldHVybiBHKEopO2xldCBRPW5ldyBnKFopLFssVl09UTAuZGVjb2RlKFEpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtZLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldFtXLHpdPSQucmVhZFZhckludCgpO2lmKHohPT0wKXJldHVybiBHKHopO2xldFtLLEZdPSQucmVhZFZhckludCgpO2lmKEYhPT0wKXJldHVybiBHKEYpO2xldCBOO2lmKEs+MCl7bGV0W1UsT109JC5yZWFkQnl0ZXMoSSQpO2lmKE8hPT0wKXJldHVybiBHKE8pO049VX1yZXR1cm4gUih7ZWlkOlosb2ZmOlksY3RyOlcsbGVuOkssaHNoOk59KX19O2Z1bmN0aW9uIE4wKCQpe3JldHVybiBBcnJheS5mcm9tKCQpLm1hcCgoSik9PkoudG9TdHJpbmcoMTYpLnBhZFN0YXJ0KDIsIjAiKSkuam9pbigiIil9ZnVuY3Rpb24gRCQoJCl7aWYoJC5sZW5ndGglMiE9PTApdGhyb3cgRXJyb3IoIkludmFsaWQgaGV4IHN0cmluZyIpO2xldCBaPW5ldyBVaW50OEFycmF5KCQubGVuZ3RoLzIpO2ZvcihsZXQgSj0wO0o8JC5sZW5ndGg7Sis9MilaW0ovMl09TnVtYmVyLnBhcnNlSW50KCQuc3Vic3RyKEosMiksMTYpO3JldHVybiBafWZ1bmN0aW9uIFYwKCQsWil7aWYoJD09PVopcmV0dXJuITA7aWYoJC5ieXRlTGVuZ3RoIT09Wi5ieXRlTGVuZ3RoKXJldHVybiExO3JldHVybiAkLmV2ZXJ5KChKLFEpPT5KPT09WltRXSl9dmFyIGY7aWYodHlwZW9mIFVpbnQ4QXJyYXkucHJvdG90eXBlLnRvQmFzZTY0PT09ImZ1bmN0aW9uIilmPSgkKT0+JC50b0Jhc2U2NCgpO2Vsc2UgZj0oJCk9PmJ0b2EoU3RyaW5nLmZyb21DaGFyQ29kZSguLi4kKSk7dmFyIEYwO2lmKHR5cGVvZiBVaW50OEFycmF5LmZyb21CYXNlNjQ9PT0iZnVuY3Rpb24iKUYwPSgkKT0+VWludDhBcnJheS5mcm9tQmFzZTY0KCQpO2Vsc2UgRjA9KCQpPT5VaW50OEFycmF5LmZyb20oYXRvYigkKSwoWik9PlouY2hhckNvZGVBdCgwKSk7ZnVuY3Rpb24gVyQoJCxaKXtsZXQgSj1uZXcgVWludDhBcnJheSgkLmxlbmd0aCtaLmxlbmd0aCk7cmV0dXJuIEouc2V0KCQsMCksSi5zZXQoWiwkLmxlbmd0aCksSn1mdW5jdGlvbiBNSigkLFosSil7cmV0dXJuIEouY2hlY2tTaWdFZDI1NTE5KCQuc2lnLCQuaGVhZENwaCxaKX1hc3luYyBmdW5jdGlvbiBDSigkLFosSixRKXtsZXQgVjtpZigkLmJvZCYmJC5sZW4+MClWPWF3YWl0IEouYmxha2UzKCQuYm9kKTtsZXQgWT1uZXcgUyxYPVgwLmVuY29kZShZLHsuLi4kLGhzaDpWfSk7aWYoWCE9PTApcmV0dXJuIEcoWCk7bGV0IFc9WS5yZXN1bHQoKSx6PWF3YWl0IFoua2RtRm9yKFcpLEs9US5kZXJpdmVDaXBoZXIoeiwiZW5jcnlwdCIpLEY9YXdhaXQgSy5lbmNyeXB0KFcpLE49JC5ib2Q/YXdhaXQgSy5lbmNyeXB0KCQuYm9kKTpuZXcgVWludDhBcnJheSgwKSxVPWF3YWl0IFouc2lnbihGKTtyZXR1cm4gUih7c2lnOlUsa2RtOnosaGVhZENwaDpGLGJvZHlDcGg6Tn0pfWFzeW5jIGZ1bmN0aW9uIFlaKCQsWixKLFEsVil7bGV0IFk9bmV3IGcoJCksW1gsV109WDAuZGVjb2RlKFkpO2lmKFchPT0wKXJldHVybiBHKDE0KTtsZXQgejt0cnl7ej1aJiZaLmxlbmd0aD4wP2F3YWl0IEouZGVjcnlwdChaKTp2b2lkIDB9Y2F0Y2h7cmV0dXJuIEcoMjApfWxldCBLPVguaHNoJiZ6PT09dm9pZCAwLEY9WC5oc2g9PT12b2lkIDAmJnohPT12b2lkIDA7aWYoS3x8RilyZXR1cm4gRygxOSk7aWYoWC5oc2gmJnope2xldCBVPWF3YWl0IFEuYmxha2UzKHopO2lmKCFWMChVLFguaHNoKSlyZXR1cm4gRygxOSl9bGV0IE49Vj8/YXdhaXQgUS5ibGFrZTMoJCk7cmV0dXJuIFIoe21zZ0hlYWQ6WCxib2Q6eixoZWFkSGFzaDpOfSl9Y2xhc3MgWFp7bm93KCl7cmV0dXJuIG5ldyBEYXRlfX1mdW5jdGlvbiBQSigkLFosSixRKXtsZXQgVj1aLmdldFRpbWUoKS0kLmdldFRpbWUoKSxZPUouZ2V0VGltZSgpLVEuZ2V0VGltZSgpO3JldHVybihWK1kpLzJ9dmFyIEckPXtlbmNvZGUoJCxaKXtpZigkLndyaXRlVmFySW50KFoucXVvdGEpLFoucXVvdGE+MCl7aWYoWi51c2FnZT09PXZvaWQgMClyZXR1cm4gOTskLndyaXRlVmFySW50KFoudXNhZ2UpfXJldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0IFE7aWYoWj4wKXtsZXRbVixZXT0kLnJlYWRWYXJJbnQoKTtpZihZIT09MClyZXR1cm4gRyhZKTtRPVZ9cmV0dXJuIFIoe3F1b3RhOlosdXNhZ2U6UX0pfX07dmFyIFdaPXtlbmNvZGUoJCxaKXskLndyaXRlQnl0ZXMobmV3IFVpbnQ4QXJyYXkoW1ouc3RhdHVzXSkpO2xldCBKPSQud3JpdGVEYXRlKFoudGltZVJjdmQpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVEYXRlKFoudGltZVNlbnQpO2lmKFEhPT0wKXJldHVybiBRO2xldCBWPSQud3JpdGVWYXJJbnQoWi5zdWJzY3JpcHRpb24udGVybSk7aWYoViE9PTApcmV0dXJuIFY7bGV0IFk9JC53cml0ZVZhckludChaLnN1YnNjcmlwdGlvbi5lbGFwc2VkKTtpZihZIT09MClyZXR1cm4gWTtsZXQgWD0kLndyaXRlU3RydWN0KEckLFouc3Vic2NyaXB0aW9uLnN0YXQpO2lmKFghPT0wKXJldHVybiBYO2xldCBXPSQud3JpdGVTdHJ1Y3QoRyQsWi5zdWJzY3JpcHRpb24uZHluKTtpZihXIT09MClyZXR1cm4gVztyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZEJ5dGVzKDEpO2lmKEohPT0wKXJldHVybiBHKEopO2xldCBRPVpbMF0sW1YsWV09JC5yZWFkRGF0ZSgpO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldFtYLFddPSQucmVhZERhdGUoKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXRbeixLXT0kLnJlYWRWYXJJbnQoKTtpZihLIT09MClyZXR1cm4gRyhLKTtsZXRbRixOXT0kLnJlYWRWYXJJbnQoKTtpZihOIT09MClyZXR1cm4gRyhOKTtsZXRbVSxPXT0kLnJlYWRTdHJ1Y3QoRyQpO2lmKE8hPT0wKXJldHVybiBHKE8pO2xldFtxLEldPSQucmVhZFN0cnVjdChHJCk7aWYoSSE9PTApcmV0dXJuIEcoSSk7cmV0dXJuIFIoe3N0YXR1czpRLHRpbWVSY3ZkOlYsdGltZVNlbnQ6WCxzdWJzY3JpcHRpb246e3Rlcm06eixlbGFwc2VkOkYsc3RhdDpVLGR5bjpxfX0pfX07dmFyIEdaPXtlbmNvZGUoJCxaKXtsZXQgSj0kLndyaXRlVmFyQnl0ZXMoWi5oZWFkQ3BoKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFySW50KFouc2VxKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZFZhckJ5dGVzKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsVl09JC5yZWFkVmFySW50KCk7aWYoViE9PTApcmV0dXJuIEcoVik7cmV0dXJuIFIoe2hlYWRDcGg6WixzZXE6UX0pfX07dmFyIFkwPXtlbmNvZGUoJCxaKXskLndyaXRlQnl0ZXMoWi5wdWJLZXkpLCQud3JpdGVCeXRlcyhaLnNpZyk7bGV0IEo9JC53cml0ZURhdGUoWi50aW1lc3RhbXApO2lmKEohPT0wKXJldHVybiBKO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkQnl0ZXMoWEopO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFZdPSQucmVhZEJ5dGVzKHcwKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXRbWSxYXT0kLnJlYWREYXRlKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIFIoe3B1YktleTpaLHNpZzpRLHRpbWVzdGFtcDpZfSl9fTt2YXIgd0o9e2FzeW5jIGVuY29kZVJlcSgkLFosSixRLFYpe2xldCBZPVYud3JpdGVTdHJ1Y3QoWTAsSik7aWYoWSE9PTApcmV0dXJuIFk7Zm9yKGxldCBYIG9mIFEpVi53cml0ZVZhckludChYKTtyZXR1cm4gMH0sYXN5bmMgaGFuZGxlUmVxKCQsWixKKXtsZXR7Y2xvY2s6USxjcnlwdG86VixzdG9yYWdlOll9PSQsW1gsV109Wi5yZWFkU3RydWN0KFkwKTtpZihXIT09MClyZXR1cm4gVztsZXQgej1hd2FpdCBEMChYLFYsUSk7aWYoeiE9PTApcmV0dXJuIHo7bGV0e3B1YktleTpLfT1YLFtGLE5dPWF3YWl0IFkuaGFzVXNlcihLKTtpZihOIT09MClyZXR1cm4gTjtpZighRilyZXR1cm4gNTtsZXRbVSxPXT1aLnJlYWRWYXJJbnQoKTtpZihPIT09MClyZXR1cm4gTztpZighWi5kb25lKCkpcmV0dXJuIDg7bGV0W3EsSV09YXdhaXQgWS5saXN0SGVhZHMoSyxVKTtpZihJIT09MClyZXR1cm4gSTtyZXR1cm4gSi53cml0ZVN0cnVjdHMoR1oscSl9LGRlY29kZVJlc3AoJCl7cmV0dXJuICQucmVhZFN0cnVjdHMoR1opfX07dmFyIHpaPXtlbmNvZGUoJCxaKXskLndyaXRlVmFySW50KFouc2VxKTtsZXQgSj0kLndyaXRlVmFyQnl0ZXMoWi5ib2R5Q3BoKTtpZihKIT09MClyZXR1cm4gSjtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZFZhckludCgpO2lmKEohPT0wKXJldHVybiBHKEopO2xldFtRLFZdPSQucmVhZFZhckJ5dGVzKCk7aWYoViE9PTApcmV0dXJuIEcoVik7cmV0dXJuIFIoe3NlcTpaLGJvZHlDcGg6UX0pfX07dmFyIFRKPXthc3luYyBlbmNvZGVSZXEoJCxaLEosUSxWKXtsZXQgWT1WLndyaXRlU3RydWN0KFkwLEopO2lmKFkhPT0wKXJldHVybiBZO2ZvcihsZXQgWCBvZiBRKXtsZXQgVz1WLndyaXRlVmFySW50KFgpO2lmKFchPT0wKXJldHVybiBXfXJldHVybiAwfSxhc3luYyBoYW5kbGVSZXEoJCxaLEope2xldHtjbG9jazpRLGNyeXB0bzpWLHN0b3JhZ2U6WX09JCxbWCxXXT1aLnJlYWRTdHJ1Y3QoWTApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEQwKFgsVixRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVgsW0YsTl09YXdhaXQgWS5oYXNVc2VyKEspO2lmKE4hPT0wKXJldHVybiBOO2lmKCFGKXJldHVybiA1O2xldCBVPVtdO3doaWxlKCFaLmRvbmUoKSl7bGV0W0ksSF09Wi5yZWFkVmFySW50KCk7aWYoSCE9PTApcmV0dXJuIEg7VS5wdXNoKEkpfWNvbnNvbGUuaW5mbyhgUFVMTDogJHtVLmxlbmd0aH0gYmFnc2ApO2xldFtPLHFdPWF3YWl0IFkuZ2V0Qm9kaWVzKEssVSk7aWYocSE9PTApcmV0dXJuIHE7aWYoIU8pcmV0dXJuIDE3O2ZvcihsZXR7c2VxOkksYm9keUNwaDpIfW9mIE8pe2xldCBQPXtzZXE6SSxib2R5Q3BoOkh9LEM9Si53cml0ZVN0cnVjdCh6WixQKTtpZihDIT09MClyZXR1cm4gQ31yZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyh6Wil9fTt2YXIgS1o9e2VuY29kZSgkLFopeyQud3JpdGVCeXRlcyhaLnNpZyksJC53cml0ZUJ5dGVzKFoua2RtKTtsZXQgSj0kLndyaXRlVmFyQnl0ZXMoWi5oZWFkQ3BoKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFyQnl0ZXMoWi5ib2R5Q3BoKTtpZihRIT09MClyZXR1cm4gUTtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZEJ5dGVzKHcwKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWRCeXRlcyhUMCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1ksWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbVyx6XT0kLnJlYWRWYXJCeXRlcygpO2lmKHohPT0wKXJldHVybiBHKHopO3JldHVybiBSKHtzaWc6WixrZG06USxoZWFkQ3BoOlksYm9keUNwaDpXfSl9fTt2YXIgaiQ9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVWYXJJbnQoWi5zZXEpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJCeXRlcyhaLmhlYWRDcGgpO2lmKFEhPT0wKXJldHVybiBRO2xldCBWPVouYm9keUNwaD9aLmJvZHlDcGgubGVuZ3RoOjAsWT0kLndyaXRlVmFySW50KFYpO2lmKFkhPT0wKXJldHVybiBZO2lmKFY+MCl7aWYoIVouYm9keUNwaClyZXR1cm4gMTA7JC53cml0ZUJ5dGVzKFouYm9keUNwaCl9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJJbnQoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWRWYXJCeXRlcygpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtZLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2xldCBXO2lmKFk+MCl7bGV0W3osS109JC5yZWFkQnl0ZXMoWSk7aWYoSyE9PTApcmV0dXJuIEcoSyk7Vz16fXJldHVybiBSKHtzZXE6WixoZWFkQ3BoOlEsYm9keUNwaDpXfSl9fTt2YXIgQSQ9e2VuY29kZSgkLFopeyQud3JpdGVCeXRlcyhaLnNpZyksJC53cml0ZUJ5dGVzKFoua2RtKTtsZXQgSj0kLndyaXRlVmFyQnl0ZXMoWi5oZWFkQ3BoKTtpZihKIT09MClyZXR1cm4gSjtyZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZEJ5dGVzKHcwKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWRCeXRlcyhUMCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1ksWF09JC5yZWFkVmFyQnl0ZXMoKTtpZihYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gUih7c2lnOlosa2RtOlEsaGVhZENwaDpZfSl9fTt2YXIgXyQ9e2VuY29kZSgkLFope2lmKCQud3JpdGVWYXJJbnQoWi5pZHgpLCQud3JpdGVCeXRlcyhuZXcgVWludDhBcnJheShbWi5zdGF0dXNdKSksWi5zdGF0dXM9PT0wKSQud3JpdGVWYXJJbnQoWi5zZXEpO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsVl09JC5yZWFkQnl0ZXMoMSk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0IFk9UVswXTtpZihZIT09MClyZXR1cm4gUih7aWR4Olosc3RhdHVzOll9KTtsZXRbWCxXXT0kLnJlYWRWYXJJbnQoKTtpZihXIT09MClyZXR1cm4gRyhXKTtyZXR1cm4gUih7aWR4Olosc3RhdHVzOlksc2VxOlh9KX19O3ZhciBESj17YXN5bmMgZW5jb2RlUmVxKCQsWixKLFEsVil7bGV0IFk9Vi53cml0ZVN0cnVjdChZMCxKKTtpZihZIT09MClyZXR1cm4gWTtsZXQgWD1WLndyaXRlU3RydWN0cyhLWixRKTtpZihYIT09MClyZXR1cm4gWDtyZXR1cm4gMH0sYXN5bmMgaGFuZGxlUmVxKCQsWixKKXtsZXR7Y2xvY2s6USxjcnlwdG86VixzdG9yYWdlOlksbm90aWZpZXI6WH09JCxbVyx6XT1aLnJlYWRTdHJ1Y3QoWTApO2lmKHohPT0wKXJldHVybiB6O2xldCBLPWF3YWl0IEQwKFcsVixRKTtpZihLIT09MClyZXR1cm4gSztsZXR7cHViS2V5OkZ9PVcsW04sVV09YXdhaXQgWS5oYXNVc2VyKEYpO2lmKFUhPT0wKXJldHVybiBVO2lmKCFOKXJldHVybiA1O2xldFtPLHFdPVoucmVhZFN0cnVjdHMoS1opO2lmKHEhPT0wKXJldHVybiBxO2NvbnNvbGUuaW5mbyhgUFVTSDogJHtPLmxlbmd0aH0gYmFnc2ApO2xldCBJPVtdLEg9W107Zm9yKGxldCBNPTA7TTxPLmxlbmd0aDtNKyspe2xldCBBPU9bTV07aWYoIWF3YWl0IE1KKEEsRixWKSl7bGV0IG09e2lkeDpNLHN0YXR1czozfSxFPUoud3JpdGVTdHJ1Y3QoXyQsbSk7aWYoRSE9PTApcmV0dXJuIEU7Y29udGludWV9SS5wdXNoKE0pLEgucHVzaChBKX1sZXRbUCxDXT1hd2FpdCBZLnNldEJhZ3MoRixIKTtpZihDIT09MClyZXR1cm4gQztpZighUHx8UC5sZW5ndGghPT1ILmxlbmd0aClyZXR1cm4gMTc7bGV0IFQ9W107Zm9yKGxldCBNPTA7TTxILmxlbmd0aDtNKyspe2xldCBBPUhbTV0seD1JW01dLG09UFtNXSxFPW5ldyBTLGs9RS53cml0ZVN0cnVjdChBJCxBKTtpZihrIT09MClyZXR1cm4gaztsZXQgYj1FLnJlc3VsdCgpLHc9e3NlcTptLGhlYWRDcGg6Yn07aWYoTy5sZW5ndGg9PT0xJiZBLmJvZHlDcGgubGVuZ3RoPD1HSil3LmJvZHlDcGg9QS5ib2R5Q3BoO1QucHVzaCh3KTtsZXQgaD17aWR4Ongsc3RhdHVzOjAsc2VxOm19LGw9Si53cml0ZVN0cnVjdChfJCxoKTtpZihsIT09MClyZXR1cm4gbH1pZihULmxlbmd0aD4wKXtsZXQgTT1uZXcgUyxBPU0ud3JpdGVTdHJ1Y3RzKGokLFQpO2lmKEEhPT0wKXJldHVybiBBO2xldCB4PU0ucmVzdWx0KCk7YXdhaXQgUHJvbWlzZS5yZXNvbHZlKFgucHVzaChGLHgpKX1yZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gJC5yZWFkU3RydWN0cyhfJCl9fTt2YXIgako9e2FzeW5jIGVuY29kZVJlcSgkLFosSixRLFYpe3JldHVybiBWLndyaXRlU3RydWN0KFkwLEopfSxhc3luYyBoYW5kbGVSZXEoJCxaLEope2xldHtjbG9jazpRLGNyeXB0bzpWLHN0b3JhZ2U6WX09JCxbWCxXXT1aLnJlYWRTdHJ1Y3QoWTApO2lmKFchPT0wKXJldHVybiBXO2xldCB6PWF3YWl0IEQwKFgsVixRKTtpZih6IT09MClyZXR1cm4gejtsZXR7cHViS2V5Okt9PVg7aWYoIVouZG9uZSgpKXJldHVybiA4O2xldFtGLE5dPWF3YWl0IFkuYWRkVXNlcihLKTtpZihOIT09MClyZXR1cm4gTjtyZXR1cm4gMH0sZGVjb2RlUmVzcCgkKXtyZXR1cm4gUih2b2lkIDApfX07Y2xhc3MgRlp7dXJsO3dlYnNvY2tldDtjb25zdHJ1Y3RvcigkKXt0aGlzLnVybD0kfWNvbm5lY3RlZCgpe3JldHVybiB0aGlzLndlYnNvY2tldCE9PXZvaWQgMCYmdGhpcy53ZWJzb2NrZXQucmVhZHlTdGF0ZT09PVdlYlNvY2tldC5PUEVOfWFzeW5jIGNvbm5lY3QoJCxaLEo9KCk9Pnt9LFE9KCk9Pnt9KXtsZXR7dXJsOlZ9PXRoaXM7aWYodGhpcy53ZWJzb2NrZXQpdGhpcy53ZWJzb2NrZXQuY2xvc2UoKSx0aGlzLndlYnNvY2tldD12b2lkIDA7bGV0IFk9bmV3IFM7WS53cml0ZVN0cnVjdChZMCwkKTtsZXQgWD1ZLnJlc3VsdCgpLFc9TjAoWCk7cmV0dXJuIFYuc2VhcmNoUGFyYW1zLnNldCgidCIsVyksdGhpcy53ZWJzb2NrZXQ9bmV3IFdlYlNvY2tldChWKSx0aGlzLndlYnNvY2tldC5iaW5hcnlUeXBlPSJhcnJheWJ1ZmZlciIsdGhpcy53ZWJzb2NrZXQub25vcGVuPSgpPT57Y29uc29sZS5sb2coIkNPTk5FQ1RFRCIpLFEoKX0sdGhpcy53ZWJzb2NrZXQub25jbG9zZT0oKT0+e2NvbnNvbGUubG9nKCJESVNDT05ORUNURUQiKSx0aGlzLndlYnNvY2tldD12b2lkIDAsSigpfSx0aGlzLndlYnNvY2tldC5vbm1lc3NhZ2U9KHopPT57bGV0IEs9bmV3IFVpbnQ4QXJyYXkoei5kYXRhKTtaKEspfSx0aGlzLndlYnNvY2tldC5vbmVycm9yPSh6KT0+e2NvbnNvbGUubG9nKGBFUlJPUjogJHtKU09OLnN0cmluZ2lmeSh6KX1gKSx0aGlzLndlYnNvY2tldD12b2lkIDAsSigpfSxQcm9taXNlLnJlc29sdmUoMCl9ZGlzY29ubmVjdCgpe3RoaXMud2Vic29ja2V0Py5jbG9zZSgpLHRoaXMud2Vic29ja2V0PXZvaWQgMH19dmFyIHI9e3VzZXI6e3BhdGg6Ii91c2VyIixlbmRwb2ludDpqSixuYW1lOjB9LHB1c2g6e3BhdGg6Ii9wdXNoIixlbmRwb2ludDpESixuYW1lOjJ9LHBlZWs6e3BhdGg6Ii9wZWVrIixlbmRwb2ludDp3SixuYW1lOjF9LHB1bGw6e3BhdGg6Ii9wdWxsIixlbmRwb2ludDpUSixuYW1lOjN9fSwkVj17MDpyLnVzZXIsMjpyLnB1c2gsMTpyLnBlZWssMzpyLnB1bGx9LFZXPXtbci51c2VyLnBhdGhdOnIudXNlcixbci5wdXNoLnBhdGhdOnIucHVzaCxbci5wZWVrLnBhdGhdOnIucGVlayxbci5wdWxsLnBhdGhdOnIucHVsbH07Y2xhc3MgQUp7dXJsO2xpc3RlbmVyO2NvbnN0cnVjdG9yKCQpe3RoaXMudXJsPSQ7dGhpcy5saXN0ZW5lcj1uZXcgRlooJCl9YXN5bmMgY2FsbCgkLFope2xldHtwYXRoOkp9PSRWWyRdLFE9bmV3IFVSTChKLHRoaXMudXJsKTt0cnl7cmV0dXJuIGF3YWl0IFpWKFEsWil9Y2F0Y2h7cmV0dXJuIEcoMjUpfX19dmFyIF9KPSgkKT0+e3JldHVybiBuZXcgQUooJC5oYW5kbGUpfTthc3luYyBmdW5jdGlvbiBaVigkLFope2xldCBKPWF3YWl0IGZldGNoKCQse21ldGhvZDoiUE9TVCIsYm9keTpaLnJlc3VsdCgpLnNsaWNlKCl9KTtpZighSi5vaylyZXR1cm4gRygyNCk7bGV0IFE9YXdhaXQgZy5mcm9tUmVzcG9uc2UoSik7cmV0dXJuIFIoUSl9Y2xhc3MgTCR7ZW5jbGF2ZTtjcnlwdG87aG9zdDtjbG9jazt0cmFuc3BvcnQ7dXBkYXRlSG9zdE1ldGE7Y29uc3RydWN0b3IoJCxaLEosUSxWLFkpe3RoaXMuZW5jbGF2ZT0kO3RoaXMuY3J5cHRvPVo7dGhpcy5ob3N0PUo7dGhpcy5jbG9jaz1RO3RoaXMudHJhbnNwb3J0PVY7dGhpcy51cGRhdGVIb3N0TWV0YT1ZfWFzeW5jIGNhbGwoJCxaKXtsZXR7Y2xvY2s6Six0cmFuc3BvcnQ6UX09dGhpcyx7ZW5kcG9pbnQ6VixuYW1lOll9PSQsWD1hd2FpdCB0aGlzLmlkZW50aXR5KCksVz1KLm5vdygpLFt6LEtdPWF3YWl0IFZaKFgsVyk7aWYoSyE9PTApcmV0dXJuIEcoSyk7bGV0IEY9bmV3IFMsTj1hd2FpdCBWLmVuY29kZVJlcSh0aGlzLFgseixaLEYpO2lmKE4hPT0wKXJldHVybiBHKE4pO2xldCBVPUoubm93KCksW08scV09YXdhaXQgUS5jYWxsKFksRiksST1KLm5vdygpO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldFtILFBdPU8ucmVhZFN0cnVjdChXWik7aWYoUCE9PTApcmV0dXJuIEcoUCk7aWYoSC5zdGF0dXMhPT0wKXJldHVybiBHKEguc3RhdHVzKTtsZXQgVD17Y2xvY2tPZmZzZXQ6UEooVSxILnRpbWVSY3ZkLEgudGltZVNlbnQsSSksc3Vic2NyaXB0aW9uOkguc3Vic2NyaXB0aW9ufSxNPWF3YWl0IHRoaXMudXBkYXRlSG9zdE1ldGEoVCk7aWYoTSE9PTApcmV0dXJuIEcoTSk7cmV0dXJuIFYuZGVjb2RlUmVzcChPKX1pZGVudGl0eT0oKT0+e2xldHtob3N0OiQsZW5jbGF2ZTpafT10aGlzO3JldHVybiBaLmRlcml2ZUlkZW50aXR5KCQubGFiZWwsJC5pZHg/PzApfTtzZWFsPWFzeW5jKCQpPT57bGV0e2NyeXB0bzpaLGVuY2xhdmU6Sn09dGhpcyxRPWF3YWl0IHRoaXMuaWRlbnRpdHkoKTtyZXR1cm4gQ0ooJCxRLFosSil9O3JlZ2lzdGVyPSgpPT50aGlzLmNhbGwoci51c2VyLFtdKTtwZWVrPSgkKT0+dGhpcy5jYWxsKHIucGVlayxbJF0pO3B1c2g9KCQpPT50aGlzLmNhbGwoci5wdXNoLCQpO3B1bGw9KCQpPT50aGlzLmNhbGwoci5wdWxsLCQpO2xpc3Rlbj1hc3luYygkLFosSik9PntsZXR7Y2xvY2s6USx0cmFuc3BvcnQ6Vn09dGhpcyx7bGlzdGVuZXI6WX09VixYPWF3YWl0IHRoaXMuaWRlbnRpdHkoKSxXPVEubm93KCksW3osS109YXdhaXQgVlooWCxXKTtpZihLIT09MClyZXR1cm4gSztyZXR1cm4gYXdhaXQgWS5jb25uZWN0KHosJCxaLEopfTtpc0Nvbm5lY3RlZCgpe2xldCAkPXRoaXMudHJhbnNwb3J0Py5saXN0ZW5lcjtpZigkJiZ0eXBlb2YgJC5jb25uZWN0ZWQ9PT0iZnVuY3Rpb24iKXJldHVybiAkLmNvbm5lY3RlZCgpO3JldHVybiEwfWNsb3NlTGlzdGVuZXIoKXt0aGlzLnRyYW5zcG9ydD8ubGlzdGVuZXI/LmRpc2Nvbm5lY3QoKX19dmFyIE5aPXtlbmNvZGUoJCxaKXtsZXQgSj0kLndyaXRlVmFyU3RyaW5nKFoubGJsKTtpZihKIT09MClyZXR1cm4gSjtsZXQgUT0kLndyaXRlVmFySW50KFouaWR4KTtpZihRIT09MClyZXR1cm4gUTtsZXQgVj0kLndyaXRlVmFySW50KFoubnVtKTtpZihWIT09MClyZXR1cm4gVjtyZXR1cm4gJC53cml0ZUJ5dGVzKFouaHNoKSwkLndyaXRlQnl0ZXMoWi5zaWcpLDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRWYXJTdHJpbmcoKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWRWYXJJbnQoKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXRbWSxYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXRbVyx6XT0kLnJlYWRCeXRlcyhJJCk7aWYoeiE9PTApcmV0dXJuIEcoeik7bGV0W0ssRl09JC5yZWFkQnl0ZXModzApO2lmKEYhPT0wKXJldHVybiBHKEYpO3JldHVybiBSKHtsYmw6WixpZHg6USxudW06WSxoc2g6VyxzaWc6S30pfX07dmFyIFJaPXtlbmNvZGUoJCxaKXtsZXQgSj0kLndyaXRlU3RydWN0KE5aLFouaGVhZCk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZVZhckJ5dGVzKFouaW5kZXhFbmMpO2lmKFEhPT0wKXJldHVybiBRO2xldCBWPSQud3JpdGVWYXJCeXRlcyhaLmJvZHlFbmMpO2lmKFYhPT0wKXJldHVybiBWO3JldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkU3RydWN0KE5aKTtpZihKIT09MClyZXR1cm4gRyhKKTtsZXRbUSxWXT0kLnJlYWRWYXJCeXRlcygpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldFtZLFhdPSQucmVhZFZhckJ5dGVzKCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIFIoe2hlYWQ6WixpbmRleEVuYzpRLGJvZHlFbmM6WX0pfX07dmFyIFVaPXtlbmNvZGUoJCxaKXskLndyaXRlQnl0ZXMoWi5rZG0pO2xldCBKPSQud3JpdGVWYXJCeXRlcyhaLmhlYWRDcGgpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJJbnQoWi5sZW5Cb2R5KTtpZihRIT09MClyZXR1cm4gUTtpZihaLmxlbkJvZHk+MCYmWi5vZmZCb2R5IT09dm9pZCAwKXtsZXQgVj0kLndyaXRlVmFySW50KFoub2ZmQm9keSk7aWYoViE9PTApcmV0dXJuIFZ9cmV0dXJuIDB9LGRlY29kZSgkKXtsZXRbWixKXT0kLnJlYWRCeXRlcyhUMCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsVl09JC5yZWFkVmFyQnl0ZXMoKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXRbWSxYXT0kLnJlYWRWYXJJbnQoKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXQgVztpZihZPjApe2xldFt6LEtdPSQucmVhZFZhckludCgpO2lmKEshPT0wKXJldHVybiBHKEspO1c9en1yZXR1cm4gUih7a2RtOlosaGVhZENwaDpRLGxlbkJvZHk6WSxvZmZCb2R5Old9KX19O2FzeW5jIGZ1bmN0aW9uIExKKCQsWixKLFEsVil7bGV0IFk9YXdhaXQgVi5kZXJpdmVJZGVudGl0eSgkLFopLFg9bmV3IFMsVz1uZXcgUyx6PTAsSz0wO2ZvcihsZXQgUCBvZiBKKXtsZXQgQz1uZXcgUyxUPUMud3JpdGVTdHJ1Y3QoWDAsUC5oZWFkKTtpZihUIT09MClyZXR1cm4gRyhUKTtsZXQgTT1DLnJlc3VsdCgpLEE9YXdhaXQgWS5rZG1Gb3IoTSkseD1WLmRlcml2ZUNpcGhlcihBLCJlbmNyeXB0IiksbT1hd2FpdCB4LmVuY3J5cHQoTSksRT1QLmJvZHk/YXdhaXQgeC5lbmNyeXB0KFAuYm9keSk6bmV3IFVpbnQ4QXJyYXkoMCksaz1QLmhlYWQubGVuPjAmJlAuaGVhZC5oc2ghPT12b2lkIDA/RS5sZW5ndGg6MCxiPXtrZG06QSxoZWFkQ3BoOm0sbGVuQm9keTprLG9mZkJvZHk6az4wP0s6dm9pZCAwfSx3PVgud3JpdGVTdHJ1Y3QoVVosYik7aWYodyE9PTApcmV0dXJuIEcodyk7aWYoUC5ib2R5KVcud3JpdGVCeXRlcyhFKSxLKz1FLmxlbmd0aDt6Kyt9bGV0IEY9Vy5yZXN1bHQoKSxOPVgucmVzdWx0KCksVT1hd2FpdCBRLmJsYWtlMyhOKSxPPWF3YWl0IFkuc2lnbihVKSxxPXtsYmw6JCxpZHg6WixudW06eixoc2g6VSxzaWc6T30sST1uZXcgUztJLndyaXRlU3RydWN0KFJaLHtoZWFkOnEsaW5kZXhFbmM6Tixib2R5RW5jOkZ9KTtsZXQgSD1JLnJlc3VsdCgpO3JldHVybiBSKEgpfWFzeW5jIGZ1bmN0aW9uIHhKKCQsWixKKXtsZXRbUSxWXT1SWi5kZWNvZGUobmV3IGcoJCkpO2lmKFYhPT0wKXJldHVybiBHKFYpO2xldHtoZWFkOlksaW5kZXhFbmM6WCxib2R5RW5jOld9PVEsej1hd2FpdCBKLmRlcml2ZUlkZW50aXR5KFkubGJsLFkuaWR4KTtpZighYXdhaXQgWi5jaGVja1NpZ0VkMjU1MTkoWS5zaWcsWS5oc2gsei5wdWJsaWNLZXkpKXJldHVybiBHKDMpO2xldCBGPWF3YWl0IFouYmxha2UzKFgpO2lmKCFWMChGLFkuaHNoKSlyZXR1cm4gRygxOSk7bGV0IE49bmV3IGcoWCksVT1bXTtmb3IobGV0IHE9MDtxPFkubnVtO3ErKyl7bGV0W0ksSF09Ti5yZWFkU3RydWN0KFVaKTtpZihIIT09MClyZXR1cm4gRyhIKTtVLnB1c2goSSl9aWYoVS5sZW5ndGghPT1ZLm51bSlyZXR1cm4gRygxNCk7bGV0IE89W107Zm9yKGxldCBxIG9mIFUpe2xldCBJPUouZGVyaXZlQ2lwaGVyKHEua2RtLCJkZWNyeXB0IiksSDt0cnl7SD1hd2FpdCBJLmRlY3J5cHQocS5oZWFkQ3BoKX1jYXRjaHtyZXR1cm4gRygyMCl9bGV0W1AsQ109WDAuZGVjb2RlKG5ldyBnKEgpKTtpZihDIT09MClyZXR1cm4gRyhDKTtsZXQgVDtpZihxLmxlbkJvZHk+MCYmcS5vZmZCb2R5IT09dm9pZCAwKXtpZihQLmhzaD09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0IE09Vy5zbGljZShxLm9mZkJvZHkscS5vZmZCb2R5K3EubGVuQm9keSk7dHJ5e1Q9YXdhaXQgSS5kZWNyeXB0KE0pfWNhdGNoe3JldHVybiBHKDIwKX1sZXQgQT1hd2FpdCBaLmJsYWtlMyhUKTtpZighVjAoQSxQLmhzaCkpcmV0dXJuIEcoMTkpfU8ucHVzaCh7aGVhZDpQLGJvZHk6VH0pfXJldHVybiBSKE8pfWFzeW5jIGZ1bmN0aW9uIGZKKHtub3c6JCxib2Q6WixjcnlwdG86Sn0pe2xldCBRPWF3YWl0IEouZ2VuUmFuZG9tQnl0ZXMoOCksVj1uZXcgUyxZPVYud3JpdGVTdHJ1Y3QoUTAse2lkOlEsdHM6JH0pO2lmKFkhPT0wKXJldHVybiBHKFkpO2xldCBYPVYucmVzdWx0KCk7cmV0dXJuIHgkKHtub3c6JCxlaWQ6WCxjdHI6MCxib2Q6WixjcnlwdG86Sn0pfWFzeW5jIGZ1bmN0aW9uIHgkKHtub3c6JCxlaWQ6WixjdHI6Sixib2Q6USxjcnlwdG86Vn0pe2xldCBZPW5ldyBnKFopLFtYLFddPVEwLmRlY29kZShZKTtpZihXIT09MClyZXR1cm4gRyhXKTtsZXQgej0kLmdldFRpbWUoKS1YLnRzLmdldFRpbWUoKSxLLEY9UT8ubGVuZ3RoPz8wO2lmKFEmJkY+MClLPWF3YWl0IFYuYmxha2UzKFEpO3JldHVybiBSKHtlaWQ6WixvZmY6eixjdHI6SixsZW46Rixoc2g6S30pfWZ1bmN0aW9uIEpWKCQsWil7bGV0IEo9JC5sZW5ndGg8Wi5sZW5ndGg/JC5sZW5ndGg6Wi5sZW5ndGg7Zm9yKGxldCBRPTA7UTxKO1ErKylpZigkW1FdIT09WltRXSlyZXR1cm4gJFtRXS1aW1FdO3JldHVybiAkLmxlbmd0aC1aLmxlbmd0aH1hc3luYyBmdW5jdGlvbiB6JCgkLFope2xldCBKPUFycmF5LmZyb20oJCk7Si5zb3J0KEpWKTtsZXQgUT0wO2ZvcihsZXQgWCBvZiBKKVErPVgubGVuZ3RoO2xldCBWPW5ldyBVaW50OEFycmF5KFEpLFk9MDtmb3IobGV0IFggb2YgSilWLnNldChYLFkpLFkrPVgubGVuZ3RoO3JldHVybiBaLmJsYWtlMyhWKX1mdW5jdGlvbiBRVigkKXtsZXQgWj1uZXcgUyxKPVoud3JpdGVWYXJCeXRlcygkLmVpZCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0IFE9Wi53cml0ZURhdGUoJC51cGRhdGVkQXQpO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldCBWPVoud3JpdGVWYXJJbnQoJC5jdHIpO2lmKFYhPT0wKXJldHVybiBHKFYpO3JldHVybiBSKFoucmVzdWx0KCkpfWFzeW5jIGZ1bmN0aW9uIGYkKCQsWil7bGV0IEo9W107Zm9yKGxldCBRIG9mICQpe2xldFtWLFldPVFWKFEpO2lmKFkhPT0wfHwhVilyZXR1cm4gRyhZKTtKLnB1c2goVil9cmV0dXJuIFIoYXdhaXQgeiQoSixaKSl9dmFyIHNXPVN5bWJvbCgiTWFzdGVyU2VlZCIpLHRXPVN5bWJvbCgiU2VhbGVkTWFzdGVyS2V5IiksUjA9MzIsa0o9MjQrUjArMTY7ZnVuY3Rpb24gdCgkKXtpZigkLmJ5dGVMZW5ndGghPT1SMClyZXR1cm4gRygxMCk7cmV0dXJuIFIoJCl9ZnVuY3Rpb24gajAoJCl7aWYoJC5ieXRlTGVuZ3RoIT09a0opcmV0dXJuIEcoMTApO3JldHVybiBSKCQpfXZhciAkRz1TeW1ib2woIkVudGl0eUlEIik7ZnVuY3Rpb24gQkooJCl7cmV0dXJuInR5cGUiaW4gJH12YXIgWkc9U3ltYm9sKCJEZXJpdmF0aW9uU2VlZCIpLEpHPVN5bWJvbCgiUHVibGljS2V5IiksUUc9U3ltYm9sKCJQcml2YXRlS2V5IiksVkc9U3ltYm9sKCJIb3N0U3BlY2lmaWNLZXlQYWlyIiksWUc9U3ltYm9sKCJIYXNoIik7ZnVuY3Rpb24gVlYoJCl7aWYoISQpcmV0dXJuITE7aWYodHlwZW9mICQhPT0ib2JqZWN0IilyZXR1cm4hMTtpZigiYm9keSJpbiAkPT09ITEpcmV0dXJuITE7aWYoInR5cGUiaW4gJD09PSExKXJldHVybiExO3JldHVybiEwfWZ1bmN0aW9uIFlWKCQpe2lmKCEkLmJvZHx8JC5ib2QubGVuZ3RoPT09MCl7bGV0IFE9e29mZjokLm9mZixjdHI6JC5jdHIsZWlkOiQuZWlkfTtyZXR1cm4gUihRKX1sZXQgWj1RWigkLmJvZCk7aWYoVlYoWik9PT0hMSlyZXR1cm4gY29uc29sZS53YXJuKCJtc2cgYm9keSBpbnZhbGlkIixaKSxHKDE0KTtsZXQgSj17b2ZmOiQub2ZmLGN0cjokLmN0cixlaWQ6JC5laWQsZ2lkOlouZ2lkLHBpZDpaLnBpZCx0YWdzOloudGFncyx0eXBlOloudHlwZSxib2R5OlouYm9keX07cmV0dXJuIFIoSil9Y2xhc3MgayR7YXBwbGllcjtlbWl0dGVyPW5ldyBYJDtjbGVhcmVyO29uRGlydHlFaWRzO2NhY2hlRHJpdmVuO3BlZXJJbmdlc3Q7Y29uc3RydWN0b3IoJCxaLEosUSl7dGhpcy5hcHBsaWVyPSQ7dGhpcy5jbGVhcmVyPVosdGhpcy5vbkRpcnR5RWlkcz1KLHRoaXMuY2FjaGVEcml2ZW49UT8uY2FjaGVEcml2ZW4/PyExLHRoaXMucGVlckluZ2VzdD1RPy5wZWVySW5nZXN0fWFwcGx5PWFzeW5jKCQpPT57bGV0IFo9W10sSj1bXTtmb3IobGV0IFcgb2YgJCl7bGV0W3osS109WVYoVyk7aWYoSi5wdXNoKEspLEshPT0wKWNvbnRpbnVlO1oucHVzaCh6KX1sZXR7c3RhdHM6USx0eXBlczpWLGVpZHM6WX09YXdhaXQgdGhpcy5hcHBsaWVyKFopLFg9W107Zm9yKGxldCBXPTA7VzwkLmxlbmd0aDtXKyspe2xldCB6PUpbV10sSz1RW1ddO2lmKHohPT0wKXtYLnB1c2goeik7Y29udGludWV9aWYoSyE9PTApe1gucHVzaChLKTtjb250aW51ZX1YLnB1c2goMCl9aWYoIXRoaXMuY2FjaGVEcml2ZW4pZm9yKGxldCBXIG9mIFYpdGhpcy5lbWl0dGVyLmVtaXQoVyxudWxsKTtpZihZLmxlbmd0aD4wKXRoaXMub25EaXJ0eUVpZHM/LihZKTtyZXR1cm4gWH07Y2xlYXI9YXN5bmMoKT0+e2xldCAkPWF3YWl0IHRoaXMuY2xlYXJlcigpO2lmKCQhPT0wKXJldHVybiAkO3JldHVybiB0aGlzLmVtaXR0ZXIuZW1pdEFsbChudWxsKSwkfTtub3RpZnk9KCQpPT57Zm9yKGxldCBaIG9mICQpdGhpcy5lbWl0dGVyLmVtaXQoWixudWxsKX07cmVmcmVzaD1hc3luYygkKT0+e2lmKHRoaXMucGVlckluZ2VzdCl7YXdhaXQgdGhpcy5wZWVySW5nZXN0KCQpO3JldHVybn19O29uPSgkLFopPT57dGhpcy5lbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIoJCxaKX07b2ZmPSgkLFopPT57dGhpcy5lbWl0dGVyLnJlbW92ZUV2ZW50TGlzdGVuZXIoJCxaKX19dmFyIG49ImVudGl0aWVzIixCJD0iZW50aXR5X3R5cGVfY3JlYXRlZF9hdCIscVo9ImVudGl0eV90eXBlX3VwZGF0ZWRfYXQiLElaPSJlbnRpdHlfdHlwZV9ncm91cF9pZCIsSFo9ImVudGl0eV90eXBlX3BhcmVudF9pZCIsbjA9ImVudGl0eV90YWdzIixFSj0iZGIiLG1KPTEzO2Z1bmN0aW9uIFhWKCQpe3JldHVybiJ0eXAiaW4gJH1mdW5jdGlvbiBXVigkKXtsZXQgWj17Ym9kOiQuYm9keSxjcmQ6JC5jcmVhdGVkQXQsLi4uJC5jdHIhPT0wP3tjdHI6JC5jdHJ9Ont9LGVpZDpmKCQuZWlkKSxnaWQ6JC5naWQscGlkOiQucGlkP2YoJC5waWQpOnZvaWQgMCx0Z3M6JC50YWdzLHR5cDokLnR5cGUsdXBkOiQudXBkYXRlZEF0fTtpZihaLmdpZD09PXZvaWQgMClkZWxldGUgWi5naWQ7aWYoWi5waWQ9PT12b2lkIDApZGVsZXRlIFoucGlkO2lmKFoudGdzPT09dm9pZCAwKWRlbGV0ZSBaLnRncztpZihaLmN0cj09PXZvaWQgMClkZWxldGUgWi5jdHI7cmV0dXJuIFp9ZnVuY3Rpb24gR1YoJCl7aWYoIWkoJCkpcmV0dXJue2VpZDpmKCQuZWlkKSx1cGQ6JC51cGRhdGVkQXQsLi4uJC5jdHIhPT0wP3tjdHI6JC5jdHJ9Ont9fTtyZXR1cm4gV1YoJCl9ZnVuY3Rpb24gYzAoJCl7cmV0dXJue2JvZHk6JC5ib2QsY3JlYXRlZEF0OiQuY3JkLHVwZGF0ZWRBdDokLnVwZCxjdHI6JC5jdHI/PzAsdHlwZTokLnR5cCxlaWQ6RjAoJC5laWQpLGdpZDokLmdpZCxwaWQ6JC5waWQ/RjAoJC5waWQpOnZvaWQgMCwuLi4kLnRncyE9PXZvaWQgMD97dGFnczokLnRnc306e319fWZ1bmN0aW9uIE9aKCQpe2lmKFhWKCQpKXJldHVybiBjMCgkKTtyZXR1cm57ZWlkOkYwKCQuZWlkKSx1cGRhdGVkQXQ6JC51cGQsY3RyOiQuY3RyPz8wfX1jbGFzcyBnSntkYjtvcGVuaW5nO2FzeW5jIGluaXQoKXthd2FpdCB0aGlzLmVuc3VyZURiKCl9YXN5bmMgZW5zdXJlRGIoKXtpZih0aGlzLmRiKXJldHVybiB0aGlzLmRiO2lmKHRoaXMub3BlbmluZylyZXR1cm4gdGhpcy5vcGVuaW5nO3JldHVybiB0aGlzLm9wZW5pbmc9S1YoKS50aGVuKCgkKT0+e3JldHVybiAkLm9udmVyc2lvbmNoYW5nZT0oKT0+e2lmKCQuY2xvc2UoKSx0aGlzLmRiPT09JCl0aGlzLmRiPXZvaWQgMH0sdGhpcy5kYj0kLHRoaXMub3BlbmluZz12b2lkIDAsJH0sKCQpPT57dGhyb3cgdGhpcy5vcGVuaW5nPXZvaWQgMCwkfSksdGhpcy5vcGVuaW5nfWFwcGx5PWFzeW5jKCQpPT57bGV0IFo9bmV3IFNldCxKPVtdLFE7dHJ5e1E9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybntzdGF0czokLm1hcCgoKT0+MTYpLHR5cGVzOlosZWlkczpKfX1sZXQgVj1RLnRyYW5zYWN0aW9uKG4sInJlYWR3cml0ZSIpLFk9Vi5vYmplY3RTdG9yZShuKTtyZXR1cm4gbmV3IFByb21pc2UoKFgpPT57bGV0IFc9QXJyYXkoJC5sZW5ndGgpLmZpbGwoMCk7aWYoJC5sZW5ndGg8MSl7WCh7c3RhdHM6W10sdHlwZXM6WixlaWRzOkp9KTtyZXR1cm59Vi5vbmNvbXBsZXRlPSgpPT57WCh7c3RhdHM6Vyx0eXBlczpaLGVpZHM6Sn0pfSxWLm9uZXJyb3I9KCk9Pntmb3IobGV0IEs9MDtLPFcubGVuZ3RoO0srKylpZihXW0tdPT09dm9pZCAwKVdbS109MTg7WCh7c3RhdHM6Vyx0eXBlczpaLGVpZHM6Sn0pfTtsZXQgej1uZXcgTWFwO2ZvcihsZXQgSz0wO0s8JC5sZW5ndGg7SysrKXtsZXQgRj0kW0tdLE49ZihGLmVpZCksVT17b3A6RixpbmRleDpLfSxPPXouZ2V0KE4pO2lmKE8pTy5wdXNoKFUpO2Vsc2Ugei5zZXQoTixbVV0pfWZvcihsZXRbSyxGXW9mIHope2lmKEYubGVuZ3RoPDEpY29udGludWU7bGV0IE49WS5nZXQoSyk7Ti5vbnN1Y2Nlc3M9KCk9PntsZXQgVT1OLnJlc3VsdCxPPVU/T1ooVSk6dm9pZCAwLHE9ITE7Zm9yKGxldHtvcDpJLGluZGV4Okh9b2YgRil7bGV0W1AsQ109ZDAoTyxJKTtpZihDIT09MCl7V1tIXT1DO2NvbnRpbnVlfWlmKFA9PT12b2lkIDApe1dbSF09MTI7Y29udGludWV9cT0hMDtmb3IobGV0IFQgb2YgcjAoTyxQKSlaLmFkZChUKTtPPVB9aWYocSlKLnB1c2goRlswXS5vcC5laWQpO2lmKE8pe2xldCBJPVkucHV0KEdWKE8pKTtJLm9uZXJyb3I9KEgpPT57SC5wcmV2ZW50RGVmYXVsdCgpO2ZvcihsZXR7aW5kZXg6UH1vZiBGKVdbUF09MTh9fX0sTi5vbmVycm9yPSgpPT57Zm9yKGxldHtpbmRleDpVfW9mIEYpV1tVXT0xOH19fSl9O2FzeW5jIGNsZWFyKCl7bGV0ICQ7dHJ5eyQ9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiAxNn1sZXQgWj0kLnRyYW5zYWN0aW9uKG4sInJlYWR3cml0ZSIpLEo9Wi5vYmplY3RTdG9yZShuKTtyZXR1cm4gbmV3IFByb21pc2UoKFEpPT57Wi5vbmNvbXBsZXRlPSgpPT5RKDApLFoub25lcnJvcj0oKT0+USgxOCksSi5jbGVhcigpfSl9YXN5bmMgZ2V0Um93KCQpe2xldCBaO3RyeXtaPWF3YWl0IHRoaXMuZW5zdXJlRGIoKX1jYXRjaHtyZXR1cm4gRygxNil9bGV0IEo9ZigkKSxWPVoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFg9Vi5nZXQoSik7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1YLnJlc3VsdDtpZighVylZKFIodm9pZCAwKSk7ZWxzZSBZKFIoT1ooVykpKX0sWC5vbmVycm9yPSgpPT5ZKEcoMTgpKX0pfWFzeW5jIGdldEVudCgkKXtsZXRbWixKXT1hd2FpdCB0aGlzLmdldFJvdygkKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwfHwhaShaKSlyZXR1cm4gUih2b2lkIDApO3JldHVybiBSKFopfWFzeW5jIGdldEFsbE9mVHlwZVVwZGF0ZWRCZXR3ZWVuKCQsWixKKXtsZXQgUTt0cnl7UT1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBZPVEudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChxWik7cmV0dXJuIG5ldyBQcm9taXNlKChYKT0+e2xldCBXPVkuZ2V0QWxsKElEQktleVJhbmdlLmJvdW5kKFskLFpdLFskLEpdKSk7Vy5vbnN1Y2Nlc3M9KCk9PntsZXQgej1XLnJlc3VsdDtYKFIoei5tYXAoYzApKSl9LFcub25lcnJvcj0oKT0+WChHKDE4KSl9KX1hc3luYyBnZXRHcm91cE1lbWJlcnMoJCxaKXtsZXQgSjt0cnl7Sj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBWPUoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChJWik7cmV0dXJuIG5ldyBQcm9taXNlKChZKT0+e2xldCBYPVYuZ2V0QWxsKElEQktleVJhbmdlLm9ubHkoWyQsWl0pKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0O1koUihXLm1hcChjMCkpKX0sWC5vbmVycm9yPSgpPT5ZKEcoMTgpKX0pfWFzeW5jIGdldEFsbE9mVHlwZSgkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBRPVoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKS5pbmRleChCJCk7cmV0dXJuIG5ldyBQcm9taXNlKChWKT0+e2xldCBZPVEuZ2V0QWxsKElEQktleVJhbmdlLmJvdW5kKFskXSxbJCxbXV0pKTtZLm9uc3VjY2Vzcz0oKT0+e2xldCBYPVkucmVzdWx0O1YoUihYLm1hcChjMCkpKX0sWS5vbmVycm9yPSgpPT5WKEcoMTgpKX0pfWFzeW5jIGdldEJ5VGFnKCQsWil7bGV0IEo7dHJ5e0o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgVj1KLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgobjApO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgWD1WLmdldEFsbChJREJLZXlSYW5nZS5vbmx5KFopKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCB6PVgucmVzdWx0LmZpbHRlcigoSyk9PksudHlwPT09JCkubWFwKGMwKTtZKFIoeikpfSxYLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9YXN5bmMgZ2V0QWxsRW50aXRpZXMoJCl7aWYoInBpZCJpbiAkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBKPWYoJC5waWQpLFY9Wi50cmFuc2FjdGlvbihuLCJyZWFkb25seSIpLm9iamVjdFN0b3JlKG4pLmluZGV4KEhaKTtyZXR1cm4gbmV3IFByb21pc2UoKFkpPT57bGV0IFg9Vi5nZXRBbGwoSURCS2V5UmFuZ2Uub25seShbJC50eXBlLEpdKSk7WC5vbnN1Y2Nlc3M9KCk9PntsZXQgej1YLnJlc3VsdC5tYXAoYzApO1koUih6KSl9LFgub25lcnJvcj0oKT0+WShHKDE4KSl9KX1lbHNlIGlmKCJnaWQiaW4gJClyZXR1cm4gYXdhaXQgdGhpcy5nZXRHcm91cE1lbWJlcnMoJC50eXBlLCQuZ2lkKTtlbHNlIGlmKCJ0YWciaW4gJClyZXR1cm4gYXdhaXQgdGhpcy5nZXRCeVRhZygkLnR5cGUsJC50YWcpO2Vsc2UgaWYoInVwZGF0ZWRCZXR3ZWVuImluICQpcmV0dXJuIGF3YWl0IHRoaXMuZ2V0QWxsT2ZUeXBlVXBkYXRlZEJldHdlZW4oJC50eXBlLCQudXBkYXRlZEJldHdlZW4uc3RhcnQsJC51cGRhdGVkQmV0d2Vlbi5lbmQpO3JldHVybiBhd2FpdCB0aGlzLmdldEFsbE9mVHlwZSgkLnR5cGUpfWFzeW5jIGdldEVudGl0aWVzKCQpe2xldFtaLEpdPWF3YWl0IHRoaXMuZ2V0QWxsRW50aXRpZXMoJCk7aWYoSiE9PTApcmV0dXJuIEcoSik7cmV0dXJuIFIoWil9YXN5bmMgY291bnRFbnRpdGllcyh7dHlwZTokfSl7bGV0IFo7dHJ5e1o9YXdhaXQgdGhpcy5lbnN1cmVEYigpfWNhdGNoe3JldHVybiBHKDE2KX1sZXQgUT1aLnRyYW5zYWN0aW9uKG4sInJlYWRvbmx5Iikub2JqZWN0U3RvcmUobikuaW5kZXgoQiQpO3JldHVybiBuZXcgUHJvbWlzZSgoVik9PntsZXQgWT1JREJLZXlSYW5nZS5ib3VuZChbJF0sWyQsW11dKSxYPVEuY291bnQoWSk7WC5vbnN1Y2Nlc3M9KCk9PlYoUihYLnJlc3VsdCkpLFgub25lcnJvcj0oKT0+VihHKDE4KSl9KX1hc3luYyBjaGVja3N1bSgkKXtsZXQgWjt0cnl7Wj1hd2FpdCB0aGlzLmVuc3VyZURiKCl9Y2F0Y2h7cmV0dXJuIEcoMTYpfWxldCBRPVoudHJhbnNhY3Rpb24obiwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShuKSxWPVtdO3JldHVybiBuZXcgUHJvbWlzZSgoWSk9PntsZXQgWD1RLm9wZW5DdXJzb3IoKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0O2lmKFcpe2xldCB6PVcudmFsdWU7Vi5wdXNoKEUkKE9aKHopKSksVy5jb250aW51ZSgpfWVsc2UgZiQoViwkKS50aGVuKFkpfSxYLm9uZXJyb3I9KCk9PlkoRygxOCkpfSl9fWZ1bmN0aW9uIHpWKCQsWil7aWYoISQub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhuKSkkLmNyZWF0ZU9iamVjdFN0b3JlKG4se2tleVBhdGg6ImVpZCIsYXV0b0luY3JlbWVudDohMX0pO2xldCBKPVoub2JqZWN0U3RvcmUobik7aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhCJCkpSi5jcmVhdGVJbmRleChCJCxbInR5cCIsImNyZCJdLHt1bmlxdWU6ITF9KTtpZighSi5pbmRleE5hbWVzLmNvbnRhaW5zKHFaKSlKLmNyZWF0ZUluZGV4KHFaLFsidHlwIiwidXBkIl0se3VuaXF1ZTohMX0pO2lmKCFKLmluZGV4TmFtZXMuY29udGFpbnMoSVopKUouY3JlYXRlSW5kZXgoSVosWyJ0eXAiLCJnaWQiXSx7dW5pcXVlOiExfSk7aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhIWikpSi5jcmVhdGVJbmRleChIWixbInR5cCIsInBpZCJdLHt1bmlxdWU6ITF9KTtpZihKLmluZGV4TmFtZXMuY29udGFpbnMobjApKXtpZihKLmluZGV4KG4wKS5rZXlQYXRoIT09InRncyIpSi5kZWxldGVJbmRleChuMCl9aWYoIUouaW5kZXhOYW1lcy5jb250YWlucyhuMCkpSi5jcmVhdGVJbmRleChuMCwidGdzIix7dW5pcXVlOiExLG11bHRpRW50cnk6ITB9KX1mdW5jdGlvbiBLVigpe3JldHVybiBuZXcgUHJvbWlzZSgoJCxaKT0+e2xldCBKPWluZGV4ZWREQi5vcGVuKEVKLG1KKTtKLm9udXBncmFkZW5lZWRlZD0oKT0+e2xldHtyZXN1bHQ6USx0cmFuc2FjdGlvbjpWfT1KO2lmKCFWKXtaKEVycm9yKCJUcmFuc2FjdGlvbiBpcyBudWxsIGR1cmluZyBFbnREQiB1cGdyYWRlIikpO3JldHVybn10cnl7elYoUSxWKX1jYXRjaChZKXtaKFkgaW5zdGFuY2VvZiBFcnJvcj9ZOkVycm9yKFN0cmluZyhZKSkpfX0sSi5vbmJsb2NrZWQ9KCk9Pntjb25zb2xlLndhcm4oYFtESVBMT01BVElDXSBFbnREQiBJREIgdXBncmFkZSBibG9ja2VkICgke0VKfSDihpIgdiR7bUp9KTsgd2FpdGluZyBmb3Igb3RoZXIgY29ubmVjdGlvbnMgdG8gY2xvc2VgKX0sSi5vbnN1Y2Nlc3M9KCk9PiQoSi5yZXN1bHQpLEoub25lcnJvcj0oKT0+WihKLmVycm9yPz9FcnJvcigiRW50REIgSW5kZXhlZERCIG9wZW4gZmFpbGVkIikpfSl9YXN5bmMgZnVuY3Rpb24gU0ooKXtsZXQgJD1uZXcgZ0o7cmV0dXJuIGF3YWl0ICQuaW5pdCgpLCR9Y2xhc3MgTVp7ZW50cz1uZXcgTWFwO3VzZUluZGV4O2J5VHlwZT1uZXcgTWFwO2J5VHlwZVBpZD1uZXcgTWFwO2J5VHlwZUdpZD1uZXcgTWFwO2J5VHlwZVRhZz1uZXcgTWFwO2NvbnN0cnVjdG9yKCQ9W10sWil7dGhpcy51c2VJbmRleD1aPy5pbmRleGVzIT09ITE7Zm9yKGxldCBKIG9mICQpdGhpcy5wdXQoSil9cHV0KCQpe2xldCBaPWYoJC5laWQpLEo9dGhpcy5lbnRzLmdldChaKTtpZihKIT09dm9pZCAwJiZpKEopKXRoaXMudW5pbmRleChaLEopO2lmKHRoaXMuZW50cy5zZXQoWiwkKSxpKCQpKXRoaXMuaW5kZXgoWiwkKX1kZWwoJCl7bGV0IFo9dGhpcy5lbnRzLmdldCgkKTtpZihaPT09dm9pZCAwKXJldHVybjtpZihpKFopKXRoaXMudW5pbmRleCgkLFopO3RoaXMuZW50cy5kZWxldGUoJCl9aW5kZXgoJCxaKXtpZighdGhpcy51c2VJbmRleClyZXR1cm47bGV0IEo9dGhpcy5ieVR5cGUuZ2V0KFoudHlwZSk7aWYoIUopSj1uZXcgTWFwLHRoaXMuYnlUeXBlLnNldChaLnR5cGUsSik7aWYoSi5zZXQoJCxaKSxaLnBpZCl7bGV0IFE9ZihaLnBpZCksVj10aGlzLmJ5VHlwZVBpZC5nZXQoWi50eXBlKTtpZighVilWPW5ldyBNYXAsdGhpcy5ieVR5cGVQaWQuc2V0KFoudHlwZSxWKTtsZXQgWT1WLmdldChRKTtpZighWSlZPW5ldyBNYXAsVi5zZXQoUSxZKTtZLnNldCgkLFopfWlmKHR5cGVvZiBaLmdpZD09PSJzdHJpbmciKXtsZXQgUT10aGlzLmJ5VHlwZUdpZC5nZXQoWi50eXBlKTtpZighUSlRPW5ldyBNYXAsdGhpcy5ieVR5cGVHaWQuc2V0KFoudHlwZSxRKTtsZXQgVj1RLmdldChaLmdpZCk7aWYoIVYpVj1uZXcgTWFwLFEuc2V0KFouZ2lkLFYpO1Yuc2V0KCQsWil9aWYoWi50YWdzKXtsZXQgUT10aGlzLmJ5VHlwZVRhZy5nZXQoWi50eXBlKTtpZighUSlRPW5ldyBNYXAsdGhpcy5ieVR5cGVUYWcuc2V0KFoudHlwZSxRKTtmb3IobGV0IFYgb2YgWi50YWdzKXtsZXQgWT1RLmdldChWKTtpZighWSlZPW5ldyBNYXAsUS5zZXQoVixZKTtZLnNldCgkLFopfX19dW5pbmRleCgkLFope2lmKCF0aGlzLnVzZUluZGV4KXJldHVybjtsZXQgSj10aGlzLmJ5VHlwZS5nZXQoWi50eXBlKTtpZihKKXtpZihKLmRlbGV0ZSgkKSxKLnNpemU9PT0wKXRoaXMuYnlUeXBlLmRlbGV0ZShaLnR5cGUpfWlmKFoucGlkKXtsZXQgUT1mKFoucGlkKSxWPXRoaXMuYnlUeXBlUGlkLmdldChaLnR5cGUpLFk9Vj8uZ2V0KFEpO2lmKFkpe2lmKFkuZGVsZXRlKCQpLFkuc2l6ZT09PTApVj8uZGVsZXRlKFEpfWlmKFYmJlYuc2l6ZT09PTApdGhpcy5ieVR5cGVQaWQuZGVsZXRlKFoudHlwZSl9aWYodHlwZW9mIFouZ2lkPT09InN0cmluZyIpe2xldCBRPXRoaXMuYnlUeXBlR2lkLmdldChaLnR5cGUpLFY9UT8uZ2V0KFouZ2lkKTtpZihWKXtpZihWLmRlbGV0ZSgkKSxWLnNpemU9PT0wKVE/LmRlbGV0ZShaLmdpZCl9aWYoUSYmUS5zaXplPT09MCl0aGlzLmJ5VHlwZUdpZC5kZWxldGUoWi50eXBlKX1pZihaLnRhZ3Mpe2xldCBRPXRoaXMuYnlUeXBlVGFnLmdldChaLnR5cGUpO2lmKFEpe2ZvcihsZXQgViBvZiBaLnRhZ3Mpe2xldCBZPVEuZ2V0KFYpO2lmKFkpe2lmKFkuZGVsZXRlKCQpLFkuc2l6ZT09PTApUS5kZWxldGUoVil9fWlmKFEuc2l6ZT09PTApdGhpcy5ieVR5cGVUYWcuZGVsZXRlKFoudHlwZSl9fX1jbGVhckluZGV4ZXMoKXt0aGlzLmJ5VHlwZS5jbGVhcigpLHRoaXMuYnlUeXBlUGlkLmNsZWFyKCksdGhpcy5ieVR5cGVHaWQuY2xlYXIoKSx0aGlzLmJ5VHlwZVRhZy5jbGVhcigpfWJ1Y2tldExpc3QoJCl7aWYoISR8fCQuc2l6ZT09PTApcmV0dXJuW107bGV0IFo9W107Zm9yKGxldCBKIG9mICQudmFsdWVzKCkpWi5wdXNoKEopO3JldHVybiBafWFzeW5jIGFwcGx5KCQpe2xldCBaPW5ldyBTZXQsSj1bXSxRPVtdO2ZvcihsZXQgViBvZiAkKXtsZXQgWT1mKFYuZWlkKSxYPXRoaXMuZW50cy5nZXQoWSksW1csel09ZDAoWCxWKTtpZih6IT09MCl7US5wdXNoKHopO2NvbnRpbnVlfWlmKFc9PT12b2lkIDApe1EucHVzaCgxMik7Y29udGludWV9Zm9yKGxldCBLIG9mIHIwKFgsVykpWi5hZGQoSyk7dGhpcy5wdXQoVyksSi5wdXNoKFYuZWlkKSxRLnB1c2goMCl9cmV0dXJue3N0YXRzOlEsdHlwZXM6WixlaWRzOkp9fWFzeW5jIGNsZWFyKCl7cmV0dXJuIHRoaXMuZW50cy5jbGVhcigpLHRoaXMuY2xlYXJJbmRleGVzKCksMH1hc3luYyBnZXRSb3coJCl7bGV0IFo9ZigkKSxKPXRoaXMuZW50cy5nZXQoWik7cmV0dXJuIFIoSil9YXN5bmMgZ2V0RW50KCQpe2xldFtaLEpdPWF3YWl0IHRoaXMuZ2V0Um93KCQpO2lmKEohPT0wKXJldHVybiBHKEopO2lmKFo9PT12b2lkIDB8fCFpKFopKXJldHVybiBSKHZvaWQgMCk7cmV0dXJuIFIoWil9YXN5bmMgZ2V0QWxsRW50aXRpZXMoe3R5cGU6JCxnaWQ6WixwaWQ6Six0YWc6USx1cGRhdGVkQmV0d2VlbjpWfSl7aWYodGhpcy51c2VJbmRleCl7aWYoSiE9PXZvaWQgMCl7bGV0IFg9ZihKKTtyZXR1cm4gUih0aGlzLmJ1Y2tldExpc3QodGhpcy5ieVR5cGVQaWQuZ2V0KCQpPy5nZXQoWCkpKX1pZihaIT09dm9pZCAwKXJldHVybiBSKHRoaXMuYnVja2V0TGlzdCh0aGlzLmJ5VHlwZUdpZC5nZXQoJCk/LmdldChaKSkpO2lmKFEhPT12b2lkIDApcmV0dXJuIFIodGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlVGFnLmdldCgkKT8uZ2V0KFEpKSk7aWYoViE9PXZvaWQgMCl7bGV0IFg9W10sVz10aGlzLmJ5VHlwZS5nZXQoJCk7aWYoVyl7Zm9yKGxldCB6IG9mIFcudmFsdWVzKCkpaWYoei51cGRhdGVkQXQ+PVYuc3RhcnQmJnoudXBkYXRlZEF0PD1WLmVuZClYLnB1c2goeil9cmV0dXJuIFIoWCl9cmV0dXJuIFIodGhpcy5idWNrZXRMaXN0KHRoaXMuYnlUeXBlLmdldCgkKSkpfWxldCBZPVtdO2lmKEohPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaShYKSYmWC50eXBlPT09JCYmWC5waWQmJlYwKFgucGlkLEopKVkucHVzaChYKX1lbHNlIGlmKFohPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaShYKSYmWC50eXBlPT09JCYmKHR5cGVvZiBYLmdpZD09PSJzdHJpbmciJiZYLmdpZD09PVopKVkucHVzaChYKX1lbHNlIGlmKFEhPT12b2lkIDApe2ZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaShYKSYmWC50eXBlPT09JCYmWC50YWdzJiZYLnRhZ3MuaW5jbHVkZXMoUSkpWS5wdXNoKFgpfWVsc2UgaWYoViE9PXZvaWQgMCl7Zm9yKGxldCBYIG9mIHRoaXMuZW50cy52YWx1ZXMoKSlpZihpKFgpJiZYLnR5cGU9PT0kJiZYLnVwZGF0ZWRBdD49Vi5zdGFydCYmWC51cGRhdGVkQXQ8PVYuZW5kKVkucHVzaChYKX1lbHNlIGZvcihsZXQgWCBvZiB0aGlzLmVudHMudmFsdWVzKCkpaWYoaShYKSYmWC50eXBlPT09JClZLnB1c2goWCk7cmV0dXJuIFIoWSl9YXN5bmMgZ2V0RW50aXRpZXMoJCl7bGV0W1osSl09YXdhaXQgdGhpcy5nZXRBbGxFbnRpdGllcygkKTtpZihKIT09MClyZXR1cm4gRyhKKTtyZXR1cm4gUihaKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtpZih0aGlzLnVzZUluZGV4KXJldHVybiBSKHRoaXMuYnlUeXBlLmdldCgkKT8uc2l6ZT8/MCk7bGV0IFo9MDtmb3IobGV0IEogb2YgdGhpcy5lbnRzLnZhbHVlcygpKWlmKGkoSikmJkoudHlwZT09PSQpWis9MTtyZXR1cm4gUihaKX1hc3luYyBjaGVja3N1bSgkKXtsZXQgWj1bXTtmb3IobGV0IEogb2YgdGhpcy5lbnRzLnZhbHVlcygpKVoucHVzaChFJChKKSk7cmV0dXJuIGYkKFosJCl9fWFzeW5jIGZ1bmN0aW9uIHZKKCQpe2xldCBaPWF3YWl0IFNKKCk7aWYoJD8uY2FjaGU9PT0hMSlyZXR1cm4gWjtyZXR1cm4gbmV3IENaKFosdm9pZCAwLHtpbmRleGVzOiQ/LmluZGV4ZXN9KX1jbGFzcyBDWnttZW07ZHVyYWJsZTt3YXJtZWQ9bmV3IFNldDtsaXN0ZW5lcnM9bmV3IFNldDtjaGFpbj1Qcm9taXNlLnJlc29sdmUoKTtjb25zdHJ1Y3RvcigkLFosSil7aWYodGhpcy5kdXJhYmxlPSQsdGhpcy5tZW09bmV3IE1aKFo/P1tdLHtpbmRleGVzOko/LmluZGV4ZXN9KSxaKWZvcihsZXQgUSBvZiBaKXRoaXMud2FybWVkLmFkZChRLnR5cGUpfXN1YnNjcmliZSgkKXtyZXR1cm4gdGhpcy5saXN0ZW5lcnMuYWRkKCQpLCgpPT57dGhpcy5saXN0ZW5lcnMuZGVsZXRlKCQpfX1lbWl0KCQpe2lmKCQuc2l6ZTwxKXJldHVybjtmb3IobGV0IFogb2YgdGhpcy5saXN0ZW5lcnMpWigkKX1ydW4oJCl7bGV0IFo9dGhpcy5jaGFpbi50aGVuKCQsJCk7cmV0dXJuIHRoaXMuY2hhaW49Wi50aGVuKCgpPT57cmV0dXJufSwoKT0+e3JldHVybn0pLFp9YXBwbHkoJCl7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9Pnthd2FpdCB0aGlzLnB1bGxFaWRzKCQubWFwKChZKT0+WS5laWQpKTtsZXQgWj1xVih0aGlzLm1lbSwkKTt0aGlzLmVtaXQoWi50eXBlcyk7bGV0IEo9YXdhaXQgdGhpcy5kdXJhYmxlLmFwcGx5KCQpLHtjaGFuZ2VkOlEsc3RhdHVzOlZ9PWF3YWl0IHRoaXMucHVsbEVpZHMoJC5tYXAoKFkpPT5ZLmVpZCkpO2lmKHRoaXMuZW1pdChRKSxWIT09MClyZXR1cm57c3RhdHM6JC5tYXAoKCk9PlYpLHR5cGVzOkoudHlwZXMsZWlkczpKLmVpZHN9O3JldHVybiBKfSl9Y2xlYXIoKXtyZXR1cm4gdGhpcy5ydW4oYXN5bmMoKT0+e2xldCAkPWF3YWl0IHRoaXMuZHVyYWJsZS5jbGVhcigpO2lmKCQhPT0wKXJldHVybiAkO2xldCBaPXRoaXMubWVtLmVudHMuc2l6ZT4wO3JldHVybiBhd2FpdCB0aGlzLm1lbS5jbGVhcigpLHRoaXMud2FybWVkLmNsZWFyKCksMH0pfWluZ2VzdEZyb21EdXJhYmxlKCQpe3JldHVybiB0aGlzLnJ1bihhc3luYygpPT57bGV0e2NoYW5nZWQ6WixzdGF0dXM6Sn09YXdhaXQgdGhpcy5wdWxsRWlkcygkKTtyZXR1cm4gdGhpcy5lbWl0KFopLEp9KX1hc3luYyBwdWxsRWlkcygkKXtsZXQgWj1uZXcgU2V0LEo9bmV3IFNldDtmb3IobGV0IFEgb2YgJCl7bGV0IFY9ZihRKTtpZihKLmhhcyhWKSljb250aW51ZTtKLmFkZChWKTtsZXQgWT10aGlzLm1lbS5lbnRzLmdldChWKSxbWCxXXT1hd2FpdCB0aGlzLmR1cmFibGUuZ2V0Um93KFEpO2lmKFchPT0wKXJldHVybntjaGFuZ2VkOlosc3RhdHVzOld9O2lmKFgpe2lmKHRoaXMubWVtLnB1dChYKSwhWXx8IUZWKFksWCkpe2lmKGkoWCkpWi5hZGQoWC50eXBlKTtpZihZIT09dm9pZCAwJiZpKFkpKVouYWRkKFkudHlwZSl9fWVsc2UgaWYoWSE9PXZvaWQgMCl7aWYodGhpcy5tZW0uZGVsKFYpLGkoWSkpWi5hZGQoWS50eXBlKX19cmV0dXJue2NoYW5nZWQ6WixzdGF0dXM6MH19YXN5bmMgd2FybVR5cGUoJCl7aWYodGhpcy53YXJtZWQuaGFzKCQpKXJldHVybiAwO2xldFtaLEpdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRFbnRpdGllcyh7dHlwZTokfSk7aWYoSiE9PTApcmV0dXJuIEo7aWYoWilmb3IobGV0IFEgb2YgWil7bGV0IFY9ZihRLmVpZCksWT10aGlzLm1lbS5lbnRzLmdldChWKTtpZighWXx8T1YoUSxZKSl0aGlzLm1lbS5wdXQoUSl9cmV0dXJuIHRoaXMud2FybWVkLmFkZCgkKSwwfWFzeW5jIGdldFJvdygkKXtsZXQgWj1mKCQpO2lmKHRoaXMubWVtLmVudHMuaGFzKFopKXJldHVybiB0aGlzLm1lbS5nZXRSb3coJCk7cmV0dXJuIHRoaXMucnVuKGFzeW5jKCk9PntpZih0aGlzLm1lbS5lbnRzLmhhcyhaKSlyZXR1cm4gdGhpcy5tZW0uZ2V0Um93KCQpO2xldFtKLFFdPWF3YWl0IHRoaXMuZHVyYWJsZS5nZXRSb3coJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSil0aGlzLm1lbS5wdXQoSik7cmV0dXJuIFIoSil9KX1hc3luYyBnZXRFbnQoJCl7bGV0W1osSl09YXdhaXQgdGhpcy5nZXRSb3coJCk7aWYoSiE9PTApcmV0dXJuIEcoSik7aWYoWj09PXZvaWQgMHx8IWkoWikpcmV0dXJuIFIodm9pZCAwKTtyZXR1cm4gUihaKX1hc3luYyBnZXRFbnRpdGllcygkKXtpZighdGhpcy53YXJtZWQuaGFzKCQudHlwZSkpe2xldCBaPWF3YWl0IHRoaXMucnVuKCgpPT50aGlzLndhcm1UeXBlKCQudHlwZSkpO2lmKFohPT0wKXJldHVybiBHKFopfXJldHVybiB0aGlzLm1lbS5nZXRFbnRpdGllcygkKX1hc3luYyBjb3VudEVudGl0aWVzKHt0eXBlOiR9KXtpZighdGhpcy53YXJtZWQuaGFzKCQpKXtsZXQgWj1hd2FpdCB0aGlzLnJ1bigoKT0+dGhpcy53YXJtVHlwZSgkKSk7aWYoWiE9PTApcmV0dXJuIEcoWil9cmV0dXJuIHRoaXMubWVtLmNvdW50RW50aXRpZXMoe3R5cGU6JH0pfWFzeW5jIGNoZWNrc3VtKCQpe3JldHVybiB0aGlzLmR1cmFibGUuY2hlY2tzdW0oJCl9fWZ1bmN0aW9uIEZWKCQsWil7aWYoaSgkKSE9PWkoWikpcmV0dXJuITE7aWYoJC5jdHIhPT1aLmN0cilyZXR1cm4hMTtpZigkLnVwZGF0ZWRBdC5nZXRUaW1lKCkhPT1aLnVwZGF0ZWRBdC5nZXRUaW1lKCkpcmV0dXJuITE7aWYoIVYwKCQuZWlkLFouZWlkKSlyZXR1cm4hMTtpZighaSgkKXx8IWkoWikpcmV0dXJuITA7aWYoJC5jcmVhdGVkQXQuZ2V0VGltZSgpIT09Wi5jcmVhdGVkQXQuZ2V0VGltZSgpKXJldHVybiExO2lmKCQudHlwZSE9PVoudHlwZSlyZXR1cm4hMTtpZigkLmdpZCE9PVouZ2lkKXJldHVybiExO2lmKCFSVigkLnBpZCxaLnBpZCkpcmV0dXJuITE7aWYoIU5WKCQudGFncyxaLnRhZ3MpKXJldHVybiExO3JldHVybiBVVigkLmJvZHksWi5ib2R5KX1mdW5jdGlvbiBOVigkLFope2lmKCQ9PT1aKXJldHVybiEwO2lmKCQ9PT12b2lkIDB8fFo9PT12b2lkIDApcmV0dXJuITE7aWYoJC5sZW5ndGghPT1aLmxlbmd0aClyZXR1cm4hMTtmb3IobGV0IEo9MDtKPCQubGVuZ3RoO0orKylpZigkW0pdIT09WltKXSlyZXR1cm4hMTtyZXR1cm4hMH1mdW5jdGlvbiBSVigkLFope2lmKCQ9PT12b2lkIDAmJlo9PT12b2lkIDApcmV0dXJuITA7aWYoJD09PXZvaWQgMHx8Wj09PXZvaWQgMClyZXR1cm4hMTtyZXR1cm4gVjAoJCxaKX1mdW5jdGlvbiBVVigkLFope2lmKE9iamVjdC5pcygkLFopKXJldHVybiEwO2lmKCQgaW5zdGFuY2VvZiBVaW50OEFycmF5JiZaIGluc3RhbmNlb2YgVWludDhBcnJheSlyZXR1cm4gVjAoJCxaKTtpZigkIGluc3RhbmNlb2YgRGF0ZSYmWiBpbnN0YW5jZW9mIERhdGUpcmV0dXJuICQuZ2V0VGltZSgpPT09Wi5nZXRUaW1lKCk7dHJ5e3JldHVybiBWMChfMCgkKSxfMChaKSl9Y2F0Y2h7cmV0dXJuITF9fWZ1bmN0aW9uIE9WKCQsWil7bGV0IEo9JC51cGRhdGVkQXQuZ2V0VGltZSgpLFE9Wi51cGRhdGVkQXQuZ2V0VGltZSgpO2lmKEohPT1RKXJldHVybiBKPlE7cmV0dXJuICQuY3RyPlouY3RyfWZ1bmN0aW9uIHFWKCQsWil7bGV0IEo9bmV3IFNldCxRPVtdO2ZvcihsZXQgViBvZiBaKXtsZXQgWT1mKFYuZWlkKSxYPSQuZW50cy5nZXQoWSksW1csel09ZDAoWCxWKTtpZih6IT09MCl7US5wdXNoKHopO2NvbnRpbnVlfWlmKFc9PT12b2lkIDApe1EucHVzaCgxMik7Y29udGludWV9Zm9yKGxldCBLIG9mIHIwKFgsVykpSi5hZGQoSyk7JC5wdXQoVyksUS5wdXNoKDApfXJldHVybntzdGF0czpRLHR5cGVzOkp9fWZ1bmN0aW9uIGkoJCl7cmV0dXJuInR5cGUiaW4gJH1mdW5jdGlvbiBJVigkKXtpZighQXJyYXkuaXNBcnJheSgkKXx8JC5sZW5ndGg9PT0wKXJldHVybjtsZXQgWj1uZXcgU2V0LEo9W107Zm9yKGxldCBRIG9mICQpe2lmKHR5cGVvZiBRIT09InN0cmluZyJ8fFEubGVuZ3RoPT09MCljb250aW51ZTtpZihaLmhhcyhRKSljb250aW51ZTtaLmFkZChRKSxKLnB1c2goUSl9cmV0dXJuIEoubGVuZ3RoPjA/Sjp2b2lkIDB9ZnVuY3Rpb24gRSQoJCl7cmV0dXJue2VpZDokLmVpZCxjdHI6JC5jdHIsdXBkYXRlZEF0OiQudXBkYXRlZEF0fX1mdW5jdGlvbiBiSigkKXtsZXQgWj1uZXcgZygkLmVpZCksW0osUV09Wi5yZWFkU3RydWN0KFEwKTtpZihRIT09MClyZXR1cm4gRyhRKTtyZXR1cm4gUih7ZWlkOiQuZWlkLGN0cjokLmN0cix1cGRhdGVkQXQ6bmV3IERhdGUoSi50cy5nZXRUaW1lKCkrJC5vZmYpfSl9ZnVuY3Rpb24gZDAoJCxaKXtsZXQgSj1uZXcgZyhaLmVpZCksW1EsVl09Si5yZWFkU3RydWN0KFEwKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXQgWT1uZXcgRGF0ZShRLnRzLmdldFRpbWUoKStaLm9mZik7aWYoJCE9PXZvaWQgMCYmWTw9JC51cGRhdGVkQXQpcmV0dXJuIEcoMTUpO2lmKEJKKFopKXtsZXQgWD1JVihaLnRhZ3MpO3JldHVybiBSKHtlaWQ6Wi5laWQsZ2lkOlouZ2lkLHBpZDpaLnBpZCwuLi5YIT09dm9pZCAwP3t0YWdzOlh9Ont9LHR5cGU6Wi50eXBlLGNyZWF0ZWRBdDpRLnRzLHVwZGF0ZWRBdDpZLGN0cjpaLmN0cixib2R5OlouYm9keX0pfXJldHVybiBSKHtlaWQ6Wi5laWQsdXBkYXRlZEF0OlksY3RyOlouY3RyfSl9ZnVuY3Rpb24gcjAoJCxaKXtsZXQgSj1uZXcgU2V0O2lmKCQhPT12b2lkIDAmJmkoJCkpSi5hZGQoJC50eXBlKTtpZihpKFopKUouYWRkKFoudHlwZSk7cmV0dXJuWy4uLkpdfWNsYXNzIG0ke2luZmxpZ2h0PW51bGw7YWdhaW49ITE7cnVuKCQpe2lmKHRoaXMuYWdhaW49ITAsdGhpcy5pbmZsaWdodClyZXR1cm4gdGhpcy5pbmZsaWdodDtyZXR1cm4gdGhpcy5pbmZsaWdodD10aGlzLmRyYWluKCQpLHRoaXMuaW5mbGlnaHR9YXN5bmMgZmx1c2goKXtpZighdGhpcy5pbmZsaWdodClyZXR1cm47dHJ5e2F3YWl0IHRoaXMuaW5mbGlnaHR9Y2F0Y2h7fX1hc3luYyBkcmFpbigkKXt0cnl7dGhpcy5hZ2Fpbj0hMTtsZXQgWj1hd2FpdCAkKCk7d2hpbGUodGhpcy5hZ2Fpbil0aGlzLmFnYWluPSExLFo9YXdhaXQgJCgpO3JldHVybiBafWZpbmFsbHl7dGhpcy5pbmZsaWdodD1udWxsfX19dmFyIHlKPTEwMDtjbGFzcyBQWnt0aW1lcj1udWxsO2RlbGF5TXM7d29yazt0YWlsPW5ldyBtJDtjb25zdHJ1Y3RvcigkLFope3RoaXMuZGVsYXlNcz0kPDA/MDokLHRoaXMud29yaz1afXNjaGVkdWxlKCl7aWYodGhpcy5kZWxheU1zPD0wKXt0aGlzLmZpcmUoKTtyZXR1cm59aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpO3RoaXMudGltZXI9c2V0VGltZW91dCgoKT0+e3RoaXMudGltZXI9bnVsbCx0aGlzLmZpcmUoKX0sdGhpcy5kZWxheU1zKX1hc3luYyBmbHVzaCgpe2lmKHRoaXMudGltZXIhPT1udWxsKWNsZWFyVGltZW91dCh0aGlzLnRpbWVyKSx0aGlzLnRpbWVyPW51bGwsdGhpcy5maXJlKCk7YXdhaXQgdGhpcy50YWlsLmZsdXNoKCl9Y2FuY2VsKCl7aWYodGhpcy50aW1lciE9PW51bGwpY2xlYXJUaW1lb3V0KHRoaXMudGltZXIpLHRoaXMudGltZXI9bnVsbH1maXJlKCl7cmV0dXJuIHRoaXMudGFpbC5ydW4odGhpcy53b3JrKX19ZnVuY3Rpb24gaUooJCl7bGV0IFo9bmV3IGcoJC5laWQpLFtKLFFdPVEwLmRlY29kZShaKTtpZihRIT09MClyZXR1cm47cmV0dXJuIEoudHMuZ2V0VGltZSgpKyQub2ZmfWZ1bmN0aW9uIEhWKCQsWil7bGV0IEo9aUooJCksUT1pSihaKTtpZihKPT09dm9pZCAwJiZRPT09dm9pZCAwKXJldHVybiAwO2lmKEo9PT12b2lkIDApcmV0dXJuIDE7aWYoUT09PXZvaWQgMClyZXR1cm4tMTtpZihRIT09SilyZXR1cm4gUS1KO3JldHVybiBaLmN0ci0kLmN0cn1mdW5jdGlvbiBvMCgkLFope3JldHVybiAkLnNsaWNlKCkuc29ydCgoSixRKT0+SFYoWihKKSxaKFEpKSl9dmFyIHdaPXtwaGFzZToiaWRsZSJ9LEskPTUwO2Z1bmN0aW9uIFRaKCQsWixKKXtpZigkPD0wfHxaPD0wKXJldHVybiExO2lmKCQ9PT0xfHwkPT09WilyZXR1cm4hMDtyZXR1cm4gJCVKPT09MH1mdW5jdGlvbiBoSigkLFope2lmKHR5cGVvZiBuYXZpZ2F0b3IubXNTYXZlT3JPcGVuQmxvYj09PSJmdW5jdGlvbiIpe25hdmlnYXRvci5tc1NhdmVPck9wZW5CbG9iKCQsWik7cmV0dXJufWxldCBKPVVSTC5jcmVhdGVPYmplY3RVUkwoJCksUT1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIik7US5ocmVmPUosUS5kb3dubG9hZD1aLGRvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQoUSksUS5jbGljaygpLGRvY3VtZW50LmJvZHkucmVtb3ZlQ2hpbGQoUSksVVJMLnJldm9rZU9iamVjdFVSTChKKX1mdW5jdGlvbiB1SigkLFosSil7bGV0IFE9W10sVj1bXSxZPTA7Zm9yKGxldCBYIG9mICQpe2xldCBXPVooWCk7aWYoVi5sZW5ndGg+MCYmWStXPkopUS5wdXNoKFYpLFY9W10sWT0wO2lmKFYucHVzaChYKSxZKz1XLFk+PUopUS5wdXNoKFYpLFY9W10sWT0wfWlmKFYubGVuZ3RoPjApUS5wdXNoKFYpO3JldHVybiBRfWFzeW5jIGZ1bmN0aW9uIERaKCQsWixKKXtsZXQgUT0kLmxlbmd0aDtpZihRPDEpcmV0dXJuW107bGV0IFY9QXJyYXkoUSksWT0wLFg9TWF0aC5taW4oTWF0aC5tYXgoMSxaKSxRKSxXPWFzeW5jKCk9Pnt3aGlsZSghMCl7bGV0IEs9WTtpZihZKz0xLEs+PVEpcmV0dXJuO1ZbS109YXdhaXQgSigkW0tdLEspfX0sej1bXTtmb3IobGV0IEs9MDtLPFg7SysrKXoucHVzaChXKCkpO3JldHVybiBhd2FpdCBQcm9taXNlLmFsbCh6KSxWfWFzeW5jIGZ1bmN0aW9uIGckKCQsWixKLFEpe2xldCBWPW5ldyBnKCQuaGVhZENwaCksW1ksWF09Vi5yZWFkU3RydWN0KEEkKTtpZihYIT09MClyZXR1cm4gRyhYKTtsZXR7c2lnOlcsa2RtOnosaGVhZENwaDpLfT1ZO2lmKCFhd2FpdCBRLmNoZWNrU2lnRWQyNTUxOShXLEssWikpcmV0dXJuIEcoMyk7bGV0IE49Si5kZXJpdmVDaXBoZXIoeiwiZGVjcnlwdCIpLFU7dHJ5e1U9YXdhaXQgTi5kZWNyeXB0KEspfWNhdGNoe3JldHVybiBHKDIwKX1yZXR1cm4gUih7a2RtOnosaGVhZEVuYzpVfSl9dmFyIHMwPSJmIixTJD0idCIsYTA9ImUiO2Z1bmN0aW9uIE1WKCQpe2lmKCQ9PT0hMHx8JD09PVMkKXJldHVybiBTJDtpZigkPT09YTApcmV0dXJuIGEwO3JldHVybiBzMH1mdW5jdGlvbiBsSigkKXtyZXR1cm4gJCE9PTAmJiQhPT0xNSYmJCE9PTE4JiYkIT09MTd9ZnVuY3Rpb24galooJCxaLEope2lmKCQuYXBsZD1aLFo9PT1hMCYmSiE9PXZvaWQgMCkkLmVycj1KO2Vsc2UgZGVsZXRlICQuZXJyfWFzeW5jIGZ1bmN0aW9uIHYkKCQsWixKLFEpe2xldCBWPVE/LmJvZHkhPT0hMSxZPU1WKFouYXBsZCksWD1aLmJvZHksVz1YPy5sZW5ndGg/PzAsejtpZihWJiZYJiZXPjApej1hd2FpdCBKLmJsYWtlMyhYKTtsZXQgSz17ZWlkOlouZWlkLG9mZjpaLm9mZj8/MCxjdHI6Wi5jdHI/PzAsbGVuOlcsaHNoOnp9LEY9e2hhc2g6JCxoZWFkOkssYXBsZDpZfTtpZihWJiZYIT09dm9pZCAwKUYuYm9keT1YO2lmKFk9PT1hMCYmWi5lcnIhPT12b2lkIDApRi5lcnI9Wi5lcnI7cmV0dXJuIEZ9dmFyIEFaPTEwNDg1NzYsX1o9MTA0ODU3NixuSj02NDtmdW5jdGlvbiBDVigkKXtyZXR1cm4gJC5zaWcubGVuZ3RoKyQua2RtLmxlbmd0aCskLmhlYWRDcGgubGVuZ3RoKyQuYm9keUNwaC5sZW5ndGh9YXN5bmMgZnVuY3Rpb24gUFYoJCxaLEosUSxWKXtpZihRLmxlbmd0aDwxKXJldHVybiAwO2xldFtZLFhdPWF3YWl0ICQucHVzaChRKTtpZihYIT09MClyZXR1cm4gWDtpZighWSlyZXR1cm4gMjc7Zm9yKGxldCB6IG9mIFkpe2lmKHouc3RhdHVzIT09MCl7Y29uc29sZS5lcnJvcigicHVzaCBlcnIiLHopO2NvbnRpbnVlfWxldCBLPVZbei5pZHhdO2lmKCFLKXtjb25zb2xlLmVycm9yKCJubyBoYXNoIix6KTtjb250aW51ZX1hd2FpdCBaLnVwbG9hZHMuZGVxKEosW0tdKX1sZXQgVz1hd2FpdCBaLmhvc3RzLmdldChKKTtpZihXKXtsZXQgej1XLmxhc3RTZXEsSz16LEY9W107Zm9yKGxldCBOIG9mIFkpaWYoTi5zdGF0dXM9PT0wKUYucHVzaChOLnNlcSk7Ri5zb3J0KChOLFUpPT5OLVUpO2ZvcihsZXQgTiBvZiBGKWlmKE49PT16KzEpej1OO2lmKHo+Sylhd2FpdCBaLmhvc3RzLnRvdWNoKEoseil9cmV0dXJuIDB9YXN5bmMgZnVuY3Rpb24gcEooJCxaKXtpZihaLmxlbmd0aDwxKXJldHVybiBSKFtdKTtsZXQgSj1uZXcgTWFwLFE9W107Zm9yKGxldCBXIG9mIFopSi5zZXQoVy5zZXEsVyksUS5wdXNoKFcuc2VxKTtsZXRbVixZXT1hd2FpdCAkLnB1bGwoUSk7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoIVYpcmV0dXJuIEcoMjcpO2xldCBYPVtdO2ZvcihsZXR7c2VxOlcsYm9keUNwaDp6fW9mIFYpe2xldCBLPUouZ2V0KFcpO2lmKCFLKWNvbnRpbnVlO1gucHVzaCh7ZGw6Syxib2R5Q3BoOnp9KX1yZXR1cm4gUihYKX1hc3luYyBmdW5jdGlvbiB3VigkLFosSixRKXtpZihRLmxlbmd0aDwxKXJldHVybiBSKHtwYXJ0czpbXSxoYXNoZXM6W119KTtsZXQgVj1bXSxZPVtdLFg9W10sVz1uZXcgTWFwO2ZvcihsZXR7ZGw6Syxib2R5Q3BoOkZ9b2YgUSl7bGV0e2hlYWQ6TixrZG06VSxzZXE6Tyxob3N0OnF9PUssW0ksSF09YXdhaXQgY0ooSyxKKTtpZihIIT09MHx8IUkpe2xldCBrPVcuZ2V0KHEpPz9bXTtrLnB1c2goTyksVy5zZXQocSxrKTtjb250aW51ZX1sZXR7aGVhZEVuYzpQLGhlYWRFbmNIYXNoOkN9PUksVD1aLmRlcml2ZUNpcGhlcihVLCJkZWNyeXB0IiksW00sQV09YXdhaXQgWVooUCxGLFQsSixDKTtpZihBIT09MHx8IU0pe2xldCBrPVcuZ2V0KHEpPz9bXTtrLnB1c2goTyksVy5zZXQocSxrKTtjb250aW51ZX1sZXQgeD17aGVhZDpOLGJvZHk6TS5ib2R9LG09TS5oZWFkSGFzaDtYLnB1c2goe2tleTptLGRhdGE6b0ooeCl9KSxWLnB1c2goeCksWS5wdXNoKG0pO2xldCBFPVcuZ2V0KHEpPz9bXTtFLnB1c2goTyksVy5zZXQocSxFKX1sZXQgej1hd2FpdCAkLm1lc3NhZ2VzLmFkZChYKTtmb3IobGV0W0ssRl1vZiBXKWF3YWl0ICQuZG93bmxvYWRzLmRlcShLLEYpO2ZvcihsZXQgSz0wO0s8ei5sZW5ndGg7SysrKXtsZXQgRj16W0tdO2lmKEYhPT0wJiZGIT09MTUpY29uc29sZS5lcnJvcigiRVJSIHN0b3JpbmciLGpbRl0sImZvciBtZXNzYWdlIixLKX1yZXR1cm4gUih7cGFydHM6VixoYXNoZXM6WX0pfWFzeW5jIGZ1bmN0aW9uIGNKKCQsWil7bGV0IEo9JC5oZWFkRW5jO2lmKCFKKXtsZXQgVj1uZXcgUyxZPVYud3JpdGVTdHJ1Y3QoWDAsJC5oZWFkKTtpZihZIT09MClyZXR1cm4gRyhZKTtKPVYucmVzdWx0KCl9aWYoJC5oZWFkRW5jSGFzaClyZXR1cm4gUih7aGVhZEVuYzpKLGhlYWRFbmNIYXNoOiQuaGVhZEVuY0hhc2h9KTtsZXQgUT1hd2FpdCBaLmJsYWtlMyhKKTtyZXR1cm4gUih7aGVhZEVuYzpKLGhlYWRFbmNIYXNoOlF9KX1hc3luYyBmdW5jdGlvbiBkSigkLFosSil7bGV0IFE9bmV3IFNldDtmb3IobGV0IFggb2YgWilRLmFkZChmKFgpKTtpZihRLnNpemU8MSlyZXR1cm47bGV0IFY9QXJyYXkuZnJvbShhd2FpdCAkLmRvd25sb2Fkcy5saXN0KCkpO2lmKFYubGVuZ3RoPDEpcmV0dXJuO2xldCBZPW5ldyBNYXA7Zm9yKGxldCBYIG9mIFYpe2xldCBXO2lmKFguaGVhZEVuY0hhc2gpVz1mKFguaGVhZEVuY0hhc2gpO2Vsc2V7bGV0W0ssRl09YXdhaXQgY0ooWCxKKTtpZihGIT09MHx8IUspY29udGludWU7Vz1mKEsuaGVhZEVuY0hhc2gpfWlmKCFRLmhhcyhXKSljb250aW51ZTtsZXQgej1ZLmdldChYLmhvc3QpPz9bXTt6LnB1c2goWC5zZXEpLFkuc2V0KFguaG9zdCx6KX1mb3IobGV0W1gsV11vZiBZKWF3YWl0ICQuZG93bmxvYWRzLmRlcShYLFcpfWFzeW5jIGZ1bmN0aW9uIExaKHtjb25uOiQsc3RvcmU6WixlbmNsYXZlOkosaG9zdDpRLGNyeXB0bzpWLG9uUHJvZ3Jlc3M6WSxwZWVrUHJvZ3Jlc3NFdmVyeTpYLHBlZWtDb25jdXJyZW5jeTpXfSl7bGV0IHo9YXdhaXQgJC5pZGVudGl0eSgpLEs9W10sW0YsTl09YXdhaXQgJC5wZWVrKFEubGFzdFNlcSk7aWYoTiE9PTApcmV0dXJuIE47bGV0IFU9Ri5sZW5ndGgsTz1YPz9LJCxxPVc/P25KO2lmKFkmJlU+MClZKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6MCx0b3RhbDpVfSk7bGV0IEk9MCxIPWF3YWl0IERaKEYscSxhc3luYyhDKT0+e2xldFtULE1dPWF3YWl0IGckKEMsei5wdWJsaWNLZXksSixWKSxBO2lmKE0hPT0wfHwhVClBPXtvazohMSxzZXE6Qy5zZXEsc3RhdDpNfTtlbHNle2xldCB4PWF3YWl0IFYuYmxha2UzKFQuaGVhZEVuYyk7QT17b2s6ITAsc2VxOkMuc2VxLGtkbTpULmtkbSxoZWFkRW5jOlQuaGVhZEVuYyxoZWFkRW5jSGFzaDp4fX1pZihJKz0xLFkmJlRaKEksVSxPKSlZKHtwaGFzZToicGVlayIsaG9zdDpRLmxhYmVsLGRvbmU6SSx0b3RhbDpVfSk7cmV0dXJuIEF9KSxQPW5ldyBTZXQ7Zm9yKGxldCBDIG9mIEgpe2lmKCFDLm9rKXtjb25zb2xlLmVycm9yKCJwZWVrOiBkZWNyeXB0aW5nIGl0ZW0gaGVhZCIsQy5zdGF0KTtjb250aW51ZX1sZXQgVD1mKEMuaGVhZEVuY0hhc2gpO2lmKGF3YWl0IFoubWVzc2FnZXMuaGFzKEMuaGVhZEVuY0hhc2gpKXtjb25zb2xlLmluZm8oInBlZWs6IGxvY2FsIG1zZzsgc2tpcCBkb3dubG9hZCwgZGVxIHVwbG9hZCIpLGF3YWl0IFoudXBsb2Fkcy5kZXEoUS5sYWJlbCxbQy5oZWFkRW5jSGFzaF0pLGF3YWl0IFouZG93bmxvYWRzLmRlcShRLmxhYmVsLFtDLnNlcV0pO2NvbnRpbnVlfWlmKFAuaGFzKFQpKXthd2FpdCBaLmRvd25sb2Fkcy5kZXEoUS5sYWJlbCxbQy5zZXFdKTtjb250aW51ZX1sZXQgQT1uZXcgZyhDLmhlYWRFbmMpLFt4LG1dPUEucmVhZFN0cnVjdChYMCk7aWYobSE9PTApe2NvbnNvbGUuZXJyb3IoInBlZWs6IHJlYWRpbmcgaXRlbSBoZWFkIixtKTtjb250aW51ZX1QLmFkZChUKSxLLnB1c2goe2tkbTpDLmtkbSxoZWFkOngsc2VxOkMuc2VxLGhvc3Q6US5sYWJlbCxoZWFkRW5jOkMuaGVhZEVuYyxoZWFkRW5jSGFzaDpDLmhlYWRFbmNIYXNofSl9aWYoYXdhaXQgWi5kb3dubG9hZHMuZW5xKEspLEYubGVuZ3RoPjApe2xldCBDPU1hdGgubWF4KC4uLkYubWFwKChUKT0+VC5zZXEpKTthd2FpdCBaLmhvc3RzLnJlY29yZFN0YXRzKFEubGFiZWwse2xhc3RTZXE6Q30pfWlmKFkpWSh7cGhhc2U6InBlZWsiLGhvc3Q6US5sYWJlbCxkb25lOlUsdG90YWw6VX0pO3JldHVybiAwfWFzeW5jIGZ1bmN0aW9uIHJKKHtjb25uOiQsc3RvcmU6Wixob3N0OkosbWF4UHVzaEJ5dGVzOlEsb25Qcm9ncmVzczpWfSl7bGV0IFk9UT8/QVosWD1hd2FpdCBaLnVwbG9hZHMubGlzdChKLmxhYmVsKSxXPVgubGVuZ3RoLHo9MDtpZihWJiZXPjApVih7cGhhc2U6InB1c2giLGhvc3Q6Si5sYWJlbCxkb25lOjAsdG90YWw6V30pO2xldCBLPVtdLEY9W10sTj0wLFU9YXN5bmMoKT0+e2lmKEsubGVuZ3RoPDEpcmV0dXJuIDA7bGV0IE89Sy5sZW5ndGgscT1hd2FpdCBQVigkLFosSi5sYWJlbCxLLEYpO2lmKEs9W10sRj1bXSxOPTAscT09PTApe2lmKHorPU8sVilWKHtwaGFzZToicHVzaCIsaG9zdDpKLmxhYmVsLGRvbmU6eix0b3RhbDpXfSl9cmV0dXJuIHF9O2ZvcihsZXQgTyBvZiBYKXtsZXQgcT1hd2FpdCBaLm1lc3NhZ2VzLmdldChPKTtpZighcSl7eis9MTtjb250aW51ZX1sZXQgST17Li4ucS5oZWFkLGJvZDpxLmJvZHl9LFtILFBdPWF3YWl0ICQuc2VhbChJKTtpZihQIT09MClyZXR1cm4gUDtpZighSClyZXR1cm4gMTI7bGV0IEM9Q1YoSCk7aWYoSy5sZW5ndGg+MCYmTitDPlkpe2xldCBUPWF3YWl0IFUoKTtpZihUIT09MClyZXR1cm4gVH1pZihLLnB1c2goSCksRi5wdXNoKE8pLE4rPUMsTj49WSl7bGV0IFQ9YXdhaXQgVSgpO2lmKFQhPT0wKXJldHVybiBUfX1yZXR1cm4gVSgpfWFzeW5jIGZ1bmN0aW9uIHhaKHtjb25uOiQsc3RvcmU6WixlbmNsYXZlOkosaG9zdDpRLGNyeXB0bzpWLG1heFB1bGxCeXRlczpZLG9uUHJvZ3Jlc3M6WH0sVyl7bGV0IHo9WT8/X1osSz1hd2FpdCBaLmRvd25sb2Fkcy5saXN0KCksRj1BcnJheS5mcm9tKEspLmZpbHRlcigoSCk9PkguaG9zdD09PVEubGFiZWwpO2lmKEYubGVuZ3RoPDEpcmV0dXJuIDE1O2xldCBOPW8wKEYsKEgpPT5ILmhlYWQpLFU9dUooTiwoSCk9PkguaGVhZC5sZW4seiksTz1OLmxlbmd0aCxxPTA7aWYoWClYKHtwaGFzZToicHVsbCIsaG9zdDpRLmxhYmVsLGRvbmU6MCx0b3RhbDpPfSk7bGV0IEk9cEooJCxVWzBdKTtmb3IobGV0IEg9MDtIPFUubGVuZ3RoO0grKyl7bGV0W1AsQ109YXdhaXQgSTtpZihDIT09MHx8IVApcmV0dXJuIEM7aWYocSs9VVtIXS5sZW5ndGgsWClYKHtwaGFzZToicHVsbCIsaG9zdDpRLmxhYmVsLGRvbmU6cSx0b3RhbDpPfSk7bGV0IFQ9VVtIKzFdO2lmKFQpST1wSigkLFQpO2lmKFgpWCh7cGhhc2U6Im9wZW4iLGhvc3Q6US5sYWJlbCxkb25lOnEsdG90YWw6T30pO2xldCBNPW8wKFAsKHgpPT54LmRsLmhlYWQpLFssQV09YXdhaXQgd1YoWixKLFYsTSk7aWYoQSE9PTApcmV0dXJuIEE7aWYoVyl7aWYoWClYKHtwaGFzZToiZXhlYyIsaG9zdDpRLmxhYmVsLGRvbmU6cSx0b3RhbDpPfSk7YXdhaXQgVygpfX1yZXR1cm4gMH1mdW5jdGlvbiBvSih7aGVhZDokLGJvZHk6Wn0pe2xldCBKPXtlaWQ6JC5laWQsYm9keTpaLGFwbGQ6czB9O2lmKCQub2ZmIT09MClKLm9mZj0kLm9mZjtpZigkLmN0ciE9PTApSi5jdHI9JC5jdHI7cmV0dXJuIEp9YXN5bmMgZnVuY3Rpb24gYUooJCx7Y29ubjpaLHN0b3JlOkosZW5jbGF2ZTpRLGhvc3Q6VixjcnlwdG86WSxvblByb2dyZXNzOlh9LFcpe2xldCB6PVYubGFiZWwsSz1hd2FpdCBaLmlkZW50aXR5KCksRj1uZXcgZygkKSxbTixVXT1GLnJlYWRTdHJ1Y3RzKGokKTtpZihVIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIGRlY29kaW5nIG5vdGlmIixqW1VdKTtyZXR1cm59bGV0IE89ITEsST0oYXdhaXQgSi5ob3N0cy5nZXQoeikpPy5sYXN0U2VxLEg9W10sUD0hMTtmb3IobGV0IE0gb2YgTil7bGV0W0EseF09YXdhaXQgZyQoe3NlcTpNLnNlcSxoZWFkQ3BoOk0uaGVhZENwaH0sSy5wdWJsaWNLZXksUSxZKTtpZih4IT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIGRlY3J5cHRpbmcgbm90aWYiLGpbeF0pO2NvbnRpbnVlfWxldCBtPWF3YWl0IFkuYmxha2UzKEEuaGVhZEVuYyk7aWYoYXdhaXQgSi5tZXNzYWdlcy5oYXMobSkpY29udGludWU7bGV0IEU9bmV3IGcoQS5oZWFkRW5jKSxbayxiXT1FLnJlYWRTdHJ1Y3QoWDApO2lmKGIhPT0wKXtjb25zb2xlLmVycm9yKCJGYWlsZWQgdG8gcGFyc2UgaGVhZCIsaltiXSk7Y29udGludWV9aWYoIU0uYm9keUNwaCYmay5sZW4+MClQPSEwLGF3YWl0IEouZG93bmxvYWRzLmVucShbe3NlcTpNLnNlcSxob3N0Onosa2RtOkEua2RtLGhlYWQ6ayxoZWFkRW5jOkEuaGVhZEVuYyxoZWFkRW5jSGFzaDptfV0pO2Vsc2UgSC5wdXNoKHsuLi5BLGhlYWQ6ayxib2R5Q3BoOk0uYm9keUNwaCxoZWFkRW5jSGFzaDptfSk7aWYoST09PXZvaWQgMHx8TS5zZXEhPT1JKzEpY29uc29sZS5sb2coIm91dCBvZiBzZXEiLE0uc2VxLEkpLE89ITA7ZWxzZSBJPU0uc2VxfWlmKEkhPT12b2lkIDApYXdhaXQgSi5ob3N0cy50b3VjaChWLmxhYmVsLEkpO2xldCBDPVtdO2ZvcihsZXQgTSBvZiBIKXtsZXQgQT1RLmRlcml2ZUNpcGhlcihNLmtkbSwiZGVjcnlwdCIpLFt4LG1dPWF3YWl0IFlaKE0uaGVhZEVuYyxNLmJvZHlDcGgsQSxZKTtpZihtIT09MCl7Y29uc29sZS5lcnJvcigiRmFpbGVkIHRvIG9wZW4gYm9keSIsalttXSk7Y29udGludWV9Qy5wdXNoKHtrZXk6TS5oZWFkRW5jSGFzaCxkYXRhOm9KKHtoZWFkOk0uaGVhZCxib2R5OnguYm9kfSl9KX1sZXQgVD1hd2FpdCBKLm1lc3NhZ2VzLmFkZChDKTtmb3IobGV0IE09MDtNPFQubGVuZ3RoO00rKyl7bGV0IEE9VFtNXTtpZihBIT09MCYmQSE9PTE1KWNvbnNvbGUuZXJyb3IoIkVSUiBzdG9yaW5nIixqW0FdLCJmb3IgbWVzc2FnZSIsTSl9aWYoWCYmQy5sZW5ndGg+MClYKHtwaGFzZToib3BlbiIsaG9zdDpWLmxhYmVsLGRvbmU6Qy5sZW5ndGgsdG90YWw6Qy5sZW5ndGh9KTtpZihPfHxQfHxDLmxlbmd0aD4wKVcoKX1hc3luYyBmdW5jdGlvbiBmWigkLFo9e30pe2xldCBKPVoucHVsbCE9PSExLFE9Wi5wdXNoPT09ITAse2Nvbm46VixzdG9yZTpZLGVuY2xhdmU6WCxob3N0OlcsY3J5cHRvOnosb25Qcm9ncmVzczpLLHBlZWtQcm9ncmVzc0V2ZXJ5OkYscGVla0NvbmN1cnJlbmN5Ok59PSQsVT1hd2FpdCBWLmlkZW50aXR5KCksW08scV09YXdhaXQgVi5wZWVrKDApO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldCBJPU8ubGVuZ3RoLEg9Rj8/SyQsUD1OPz9uSjtpZihLJiZJPjApSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOjAsdG90YWw6SX0pO2xldCBDPTAsVD1hd2FpdCBEWihPLFAsYXN5bmMoTCk9PntsZXRbdixCXT1hd2FpdCBnJChMLFUucHVibGljS2V5LFgseikseTtpZihCIT09MHx8IXYpeT17b2s6ITEsc2VxOkwuc2VxLHN0YXQ6Qn07ZWxzZXtsZXQgXz1hd2FpdCB6LmJsYWtlMyh2LmhlYWRFbmMpO3k9e29rOiEwLHNlcTpMLnNlcSxrZG06di5rZG0saGVhZEVuYzp2LmhlYWRFbmMsaGVhZEVuY0hhc2g6X319aWYoQys9MSxLJiZUWihDLEksSCkpSyh7cGhhc2U6InBlZWsiLGhvc3Q6Vy5sYWJlbCxkb25lOkMsdG90YWw6SX0pO3JldHVybiB5fSksTT1uZXcgTWFwO2ZvcihsZXQgTCBvZiBUKXtpZighTC5vayljb250aW51ZTtsZXQgdj1mKEwuaGVhZEVuY0hhc2gpLEI9TS5nZXQodik7aWYoQilCLmNvdW50Kz0xO2Vsc2UgTS5zZXQodix7aGFzaDpMLmhlYWRFbmNIYXNoLGNvdW50OjEsc2FtcGxlOkx9KX1sZXQgQT0wLHg9W107Zm9yKGxldCBMIG9mIE0udmFsdWVzKCkpe2lmKEwuY291bnQ+MSlBKz1MLmNvdW50LTE7eC5wdXNoKEwuaGFzaCl9bGV0IG09Ty5sZW5ndGgsRT1NLnNpemUsaz1hd2FpdCB6JCh4LHopLGI9W10sdz0wO2ZvcihsZXQgTCBvZiBNLnZhbHVlcygpKXtpZihhd2FpdCBZLm1lc3NhZ2VzLmhhcyhMLmhhc2gpKXthd2FpdCBZLnVwbG9hZHMuZGVxKFcubGFiZWwsW0wuaGFzaF0pO2NvbnRpbnVlfWlmKHcrPTEsIUopY29udGludWU7bGV0IEI9TC5zYW1wbGUseT1uZXcgZyhCLmhlYWRFbmMpLFtfLGNdPXkucmVhZFN0cnVjdChYMCk7aWYoYyE9PTApe2NvbnNvbGUuZXJyb3IoInJlY29uY2lsZTogcmVhZGluZyBtc2cgaGVhZGVyIixjKTtjb250aW51ZX1iLnB1c2goe2tkbTpCLmtkbSxoZWFkOl8sc2VxOkIuc2VxLGhvc3Q6Vy5sYWJlbCxoZWFkRW5jOkIuaGVhZEVuYyxoZWFkRW5jSGFzaDpCLmhlYWRFbmNIYXNofSl9aWYoYi5sZW5ndGg+MClhd2FpdCBZLmRvd25sb2Fkcy5lbnEoYik7bGV0IGg9MDtpZihRKXtsZXQgTD1hd2FpdCBZLm1lc3NhZ2VzLmxpc3RLZXlzKCksdj1uZXcgU2V0KE0ua2V5cygpKSxCPVtdO2ZvcihsZXQgeSBvZiBMKWlmKCF2LmhhcyhmKHkpKSloKz0xLEIucHVzaCh5KTtpZihCLmxlbmd0aD4wKWF3YWl0IFkudXBsb2Fkcy5lbnEoVy5sYWJlbCxCKX1lbHNle2xldCBMPWF3YWl0IFkubWVzc2FnZXMubGlzdEtleXMoKSx2PW5ldyBTZXQoTS5rZXlzKCkpO2ZvcihsZXQgQiBvZiBMKWlmKCF2LmhhcyhmKEIpKSloKz0xfWxldCBsPU8ubGVuZ3RoPjA/TWF0aC5tYXgoLi4uTy5tYXAoKEwpPT5MLnNlcSkpOjA7aWYoYXdhaXQgWS5ob3N0cy5yZWNvcmRTdGF0cyhXLmxhYmVsLHtzZXRMYXN0U2VxOmx9KSxLKUsoe3BoYXNlOiJwZWVrIixob3N0OlcubGFiZWwsZG9uZTpJLHRvdGFsOkl9KTtyZXR1cm4gUih7bXNnY2hlY2s6ayxudW1CYWdzOm0sdW5pcXVlTXNnczpFLG51bUR1cGVzOkEsbWlzc2luZ0xvY2FsOncsbWlzc2luZ0hvc3Q6aH0pfWNsYXNzIGtae2Nsb2NrO3N0YXRlO3N0b3JlO3RyYW5zcG9ydDtjcnlwdG87Zm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQ7b25TY2hlZHVsZVN5bmM7Y29ubmVjdGlvbnM9bmV3IE1hcDthcHBseUNoYWluPVByb21pc2UucmVzb2x2ZSgpO3N5bmNSdW5zPW5ldyBtJDtjbGllbnRTdGF0ZTt4ZmVyU3RhdGU7bWF4UHVzaEJ5dGVzO21heFB1bGxCeXRlcztwZWVrUHJvZ3Jlc3NFdmVyeT1LJDtsYXN0UHJvZ3Jlc3M9d1o7c2NoZWR1bGVkU3luYztjb25zdHJ1Y3RvcigkLFosSixRLFYsWT0hMCxYPUFaLFc9X1oseil7dGhpcy5jbG9jaz0kO3RoaXMuc3RhdGU9Wjt0aGlzLnN0b3JlPUo7dGhpcy50cmFuc3BvcnQ9UTt0aGlzLmNyeXB0bz1WO3RoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQ9WTt0aGlzLm9uU2NoZWR1bGVTeW5jPXo7dGhpcy5tYXhQdXNoQnl0ZXM9WCx0aGlzLm1heFB1bGxCeXRlcz1XLHRoaXMuY2xpZW50U3RhdGU9bmV3IEwwKCgpPT50aGlzLmdldENsaWVudFN0YXRlKCkpLHRoaXMueGZlclN0YXRlPW5ldyBMMCgoKT0+dGhpcy5nZXRYZmVyU3RhdGUoKSksdGhpcy5zY2hlZHVsZWRTeW5jPW5ldyBQWih5Sixhc3luYygpPT57dHJ5e2NvbnNvbGUuaW5mbygiUnVubmluZyBzY2hlZHVsZWQgc3luYyIpLGF3YWl0IHRoaXMuc3luYygpfWNhdGNoKEspe2NvbnNvbGUuZXJyb3IoIkRlYm91bmNlZCBzeW5jIGZhaWxlZDoiLEspfX0pfWVtaXRQcm9ncmVzcz0oJCk9Pnt0aGlzLmxhc3RQcm9ncmVzcz0kLHRoaXMueGZlclN0YXRlLmVtaXQoKX07YXN5bmMgc2V0U2VlZCgkLFope2F3YWl0IHRoaXMuc3RvcmUuc2VlZC5zYXZlKCQsWiksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9YXN5bmMgZ2V0Q2xpZW50U3RhdGUoKXtsZXR7c3RvcmU6JCxjb25uZWN0aW9uczpafT10aGlzLEo9YXdhaXQgJC5zZWVkLmxvYWQoKSxRPWF3YWl0ICQuaG9zdHMubGlzdCgpLFY9ITE7Zm9yKGxldCBZIG9mIFoudmFsdWVzKCkpaWYoWS5pc0Nvbm5lY3RlZCgpKXtWPSEwO2JyZWFrfXJldHVybntoYXNTZWVkOkohPT12b2lkIDAsaGFzSG9zdDpBcnJheS5mcm9tKFEpLmxlbmd0aD4wLGNvbm5lY3RlZDpWfX1hc3luYyBnZXRYZmVyU3RhdGUoKXtsZXR7dXBsb2FkczokLGRvd25sb2FkczpafT10aGlzLnN0b3JlLEo9YXdhaXQgJC5jb3VudCgpO3JldHVybntudW1Eb3dubG9hZHM6YXdhaXQgWi5jb3VudCgpLG51bVVwbG9hZHM6Sixwcm9ncmVzczp0aGlzLmxhc3RQcm9ncmVzc319YXBwbHk9KCQsWik9PntyZXR1cm4gdGhpcy5lbnF1ZXVlQXBwbHlKb2IoKCk9PnRoaXMuZG9BcHBseSgkLFopKX07YXN5bmMgZG9BcHBseSgkLFo9e2VucXVldWVVcGxvYWQ6ITAsdHJpZ2dlclVwbG9hZDohMH0pe2xldCBKPVtdLFE9W107Zm9yKGxldHtoZWFkOlksYm9keTpYfW9mICQpe2xldCBXPW5ldyBTO1cud3JpdGVTdHJ1Y3QoWDAsWSk7bGV0IHo9Vy5yZXN1bHQoKSxLPWF3YWl0IHRoaXMuY3J5cHRvLmJsYWtlMyh6KSxGPXtlaWQ6WS5laWQsYm9keTpYLGFwbGQ6czB9O2lmKFkub2ZmIT09MClGLm9mZj1ZLm9mZjtpZihZLmN0ciE9PTApRi5jdHI9WS5jdHI7Si5wdXNoKEspLFEucHVzaCh7a2V5OkssZGF0YTpGfSl9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5hZGQoUSksYXdhaXQgZEoodGhpcy5zdG9yZSxKLHRoaXMuY3J5cHRvKTtsZXQgVj1hd2FpdCB0aGlzLmRvQXBwbHlIYXNoZXMoSik7aWYoWi5lbnF1ZXVlVXBsb2FkKXtsZXQgWT1bXTtmb3IobGV0IFg9MDtYPEoubGVuZ3RoO1grKyl7bGV0IFc9VltYXTtpZihXPT09MHx8Vz09PTE1KVkucHVzaChKW1hdKX1pZihZLmxlbmd0aD4wKXtsZXQgWD1hd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmxpc3QoKTtmb3IobGV0IFcgb2YgWClhd2FpdCB0aGlzLnN0b3JlLnVwbG9hZHMuZW5xKFcubGFiZWwsWSk7dGhpcy54ZmVyU3RhdGUuZW1pdCgpfX1pZihaLnRyaWdnZXJVcGxvYWQpdGhpcy5zY2hlZHVsZVN5bmMoKTtyZXR1cm4gVn1lbnF1ZXVlQXBwbHlKb2IoJCl7bGV0IFo9dGhpcy5hcHBseUNoYWluLnRoZW4oJCwkKTtyZXR1cm4gdGhpcy5hcHBseUNoYWluPVoudGhlbigoKT0+e3JldHVybn0sKCk9PntyZXR1cm59KSxafWRyYWluQXBwbHlRdWV1ZSgpe3JldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5kb0RyYWluQXBwbHlRdWV1ZSgpKX1hc3luYyBkb0RyYWluQXBwbHlRdWV1ZSgpe2xldCAkPWF3YWl0IHRoaXMuc3RvcmUubWVzc2FnZXMubGlzdCh7YXBsZDpzMH0pO2lmKCQubGVuZ3RoPDEpcmV0dXJuW107bGV0IFo9bzAoJCwoSik9PkouaGVhZCk7cmV0dXJuIHRoaXMuYXBwbHlTdG9yZWQoWil9YXBwbHlIYXNoZXM9KCQpPT57cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKCgpPT50aGlzLmRvQXBwbHlIYXNoZXMoJCkpfTthc3luYyBkb0FwcGx5SGFzaGVzKCQpe2xldCBaPVtdO2ZvcihsZXQgViBvZiAkKXtsZXQgWT1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmdldChWKTtpZihZKVoucHVzaChZKX1sZXQgSj1hd2FpdCB0aGlzLmFwcGx5U3RvcmVkKFopLFE9bmV3IE1hcDtmb3IobGV0IFY9MDtWPFoubGVuZ3RoO1YrKylRLnNldChmKFpbVl0uaGFzaCksSltWXT8/MTIpO3JldHVybiAkLm1hcCgoVik9PlEuZ2V0KGYoVikpPz8xMyl9YXN5bmMgYXBwbHlTdG9yZWQoJCl7aWYoJC5sZW5ndGg8MSlyZXR1cm5bXTtsZXQgWj0kLm1hcCgoWSk9Pih7Li4uWS5oZWFkLGJvZDpZLmJvZHl9KSksSj1hd2FpdCB0aGlzLnN0YXRlLmFwcGx5KFopLFE9W10sVj1bXTtmb3IobGV0IFk9MDtZPCQubGVuZ3RoO1krKyl7bGV0IFg9SltZXTtpZihYPT09MHx8WD09PTE1KVEucHVzaCgkW1ldLmhhc2gpO2Vsc2UgaWYoWCE9PXZvaWQgMCYmbEooWCkpVi5wdXNoKHtrZXk6JFtZXS5oYXNoLGVycjpYfSl9aWYoUS5sZW5ndGg+MClhd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLm1hcmtBcHBsaWVkKFEpO2lmKFYubGVuZ3RoPjApYXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5tYXJrRmFpbGVkKFYpO3JldHVybiBKfWFzeW5jIGluc2VydFJhdygkKXtsZXR7Y2xvY2s6WixjcnlwdG86Sn09dGhpcyxbUSxWXT1hd2FpdCBmSih7bm93Oloubm93KCksYm9kOiQsY3J5cHRvOkp9KTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXQgWD0oYXdhaXQgdGhpcy5hcHBseShbe2hlYWQ6USxib2R5OiR9XSkpWzBdO2lmKFghPT0wJiZYIT09MTUpcmV0dXJuIEcoWD8/MTIpO3JldHVybiBSKFEpfWFzeW5jIG1ha2VVcGRhdGUoJCxaKXtsZXR7Y2xvY2s6SixjcnlwdG86UX09dGhpcyxWPUoubm93KCk7aWYoJC51cGRhdGVkQXQuZ2V0VGltZSgpPlYuZ2V0VGltZSgpKXJldHVybiBHKDQpO2xldCBZPSQuY3RyKzEsW1gsV109YXdhaXQgeCQoe25vdzpWLGVpZDokLmVpZCxjdHI6WSxib2Q6WixjcnlwdG86UX0pO2lmKFchPT0wKXJldHVybiBHKFcpO3JldHVybiBSKHtoZWFkOlgsYm9keTpafSl9YXN5bmMgdXBkYXRlV2l0aFNrZXcoJCxaLEope2lmKEo9PT0hMSlyZXR1cm4gRyg0KTtsZXR7Y2xvY2s6USxjcnlwdG86Vn09dGhpcyxZPVEubm93KCksWD1uZXcgZygkLmVpZCksW1csel09WC5yZWFkU3RydWN0KFEwKTtpZih6IT09MClyZXR1cm4gRyh6KTtsZXQgSz0kLnVwZGF0ZWRBdC5nZXRUaW1lKCktVy50cy5nZXRUaW1lKCksRj17ZWlkOiQuZWlkLG9mZjpLKzEsY3RyOiQuY3RyKzEsbGVuOjB9LFU9KGF3YWl0IHRoaXMuYXBwbHkoW3toZWFkOkYsYm9keTp2b2lkIDB9XSkpWzBdO2lmKFUhPT0wJiZVIT09MTUpcmV0dXJuIEcoVT8/MTIpO2lmKFo9PT12b2lkIDApcmV0dXJuIFIoRik7bGV0W08scV09VCQoe2lkOlcuaWQsdHM6WX0pO2lmKHEhPT0wKXJldHVybiBHKHEpO2xldFtJLEhdPWF3YWl0IHgkKHtub3c6WSxlaWQ6TyxjdHI6MCxib2Q6WixjcnlwdG86Vn0pO2lmKEghPT0wKXJldHVybiBHKEgpO2xldCBDPShhd2FpdCB0aGlzLmFwcGx5KFt7aGVhZDpJLGJvZHk6Wn1dKSlbMF07aWYoQyE9PTAmJkMhPT0xNSlyZXR1cm4gRyhDPz8xMik7cmV0dXJuIFIoSSl9YXN5bmMgdXBkYXRlUmF3KCQsWixKPXRoaXMuZm9yY2VTa2V3SGFuZGxpbmdCeURlZmF1bHQpe2lmKCQudXBkYXRlZEF0LmdldFRpbWUoKT50aGlzLmNsb2NrLm5vdygpLmdldFRpbWUoKSlyZXR1cm4gdGhpcy51cGRhdGVXaXRoU2tldygkLFosSik7cmV0dXJuIHRoaXMuZW5xdWV1ZUFwcGx5Sm9iKGFzeW5jKCk9PntsZXRbUSxWXT1hd2FpdCB0aGlzLm1ha2VVcGRhdGUoJCxaKTtpZihWIT09MClyZXR1cm4gRyhWKTtsZXQgWD0oYXdhaXQgdGhpcy5kb0FwcGx5KFtRXSkpWzBdO2lmKFghPT0wJiZYIT09MTUpcmV0dXJuIEcoWD8/MTIpO3JldHVybiBSKFEuaGVhZCl9KX1hc3luYyBpbnNlcnQoJCl7bGV0e2JvZHk6Wix0eXBlOkosZ2lkOlEscGlkOlYsdGFnczpZfT0kLFc9XzAoe2JvZHk6Wix0eXBlOkosZ2lkOlEscGlkOlYsdGFnczpZfSk7cmV0dXJuIHRoaXMuaW5zZXJ0UmF3KFcpfWFzeW5jIHVwZGF0ZSgkKXtsZXR7cHJpb3I6Wixib2R5OkosdHlwZTpRLGdpZDpWLHBpZDpZLHRhZ3M6WCxmb3JjZTpXfT0kLEs9XzAoe2JvZHk6Six0eXBlOlEsZ2lkOlYscGlkOlksdGFnczpYfSk7cmV0dXJuIHRoaXMudXBkYXRlUmF3KFosSyxXPz90aGlzLmZvcmNlU2tld0hhbmRsaW5nQnlEZWZhdWx0KX1hc3luYyBkZWxldGUoJCl7bGV0IFo9JC5mb3JjZT8/ITA7aWYoInByaW9yImluICQpcmV0dXJuIHRoaXMudXBkYXRlUmF3KCQucHJpb3Isdm9pZCAwLFopO2xldFtKLFFdPWF3YWl0IHRoaXMucmV2RnJvbUFyY2hpdmUoJC5laWQpO2lmKFEhPT0wKXJldHVybiBHKFEpO3JldHVybiB0aGlzLnVwZGF0ZVJhdyhKLHZvaWQgMCxaKX1hc3luYyByZXZGcm9tQXJjaGl2ZSgkKXtsZXQgWj1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxhc3QoJCk7aWYoWilyZXR1cm4gYkooWi5oZWFkKTtsZXQgSj1uZXcgZygkKSxbUSxWXT1KLnJlYWRTdHJ1Y3QoUTApO2lmKFYhPT0wKXJldHVybiBHKFYpO3JldHVybiBSKHtlaWQ6JCxjdHI6LTEsdXBkYXRlZEF0OlEudHN9KX1hc3luYyBnZW5FSUQoJCl7bGV0e2Nsb2NrOlosY3J5cHRvOkp9PXRoaXMsUT1aLm5vdygpO2lmKCQhPT12b2lkIDApcmV0dXJuIFQkKHtpZDokLHRzOlF9KTtsZXQgVj1hd2FpdCBKLmdlblJhbmRvbUJ5dGVzKDgpO3JldHVybiBUJCh7aWQ6Vix0czpRfSl9c3luYygpe3JldHVybiB0aGlzLnN5bmNSdW5zLnJ1bigoKT0+dGhpcy5kb1N5bmMoKSl9YXN5bmMgZG9TeW5jKCl7bGV0e2Nvbm5lY3Rpb25zOiQsY3J5cHRvOlosc3RvcmU6Sn09dGhpcyxRPWF3YWl0IEouc2VlZC5sb2FkKCk7aWYoIVEpcmV0dXJuIDIyO2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCk7Zm9yKGxldFtWLFldb2YgJCl7bGV0IFg9YXdhaXQgSi5ob3N0cy5nZXQoVik7aWYoIVgpY29udGludWU7bGV0IFc9e2Nvbm46WSxzdG9yZTpKLGVuY2xhdmU6USxob3N0OlgsY3J5cHRvOlosbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LHo9YXdhaXQgTFooVyk7aWYoeiE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYEZhaWxlZCB0byBwZWVrOiAke3p9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLHo7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBLPWF3YWl0IHJKKFcpO2lmKEshPT0wKXJldHVybiBjb25zb2xlLmVycm9yKGBGYWlsZWQgdG8gcHVzaDogJHtLfWApLHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSxLO3RoaXMueGZlclN0YXRlLmVtaXQoKTtsZXQgRj1hd2FpdCB4WihXLGFzeW5jKCk9Pnthd2FpdCB0aGlzLmRyYWluQXBwbHlRdWV1ZSgpfSk7aWYoRiE9PTAmJkYhPT0xNSlyZXR1cm4gY29uc29sZS5lcnJvcihgRmFpbGVkIHRvIHB1bGw6ICR7Rn1gKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRjt0aGlzLnhmZXJTdGF0ZS5lbWl0KCl9cmV0dXJuIHRoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaWRsZSJ9KSwwfWFzeW5jIHJlYnVpbGQoJCl7aWYodGhpcy5zY2hlZHVsZWRTeW5jLmNhbmNlbCgpLGF3YWl0IHRoaXMuc3luY1J1bnMuZmx1c2goKSwkPy5jaGVja0hvc3Q/PyEwKXtsZXQgSj1hd2FpdCB0aGlzLnJlcHVsbCgpO2lmKEohPT0wKXJldHVybiBKfXJldHVybiB0aGlzLmVucXVldWVBcHBseUpvYigoKT0+dGhpcy5yZXBsYXkoKSl9YXN5bmMgbXNnY2hlY2soKXtsZXQgJD1hd2FpdCB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3RLZXlzKCk7cmV0dXJuIHokKCQsdGhpcy5jcnlwdG8pfWxpc3RNc2dzKCQpe3JldHVybiB0aGlzLnN0b3JlLm1lc3NhZ2VzLmxpc3QoJCl9Y291bnRNc2dzKCQpe3JldHVybiB0aGlzLnN0b3JlLm1lc3NhZ2VzLmNvdW50KCQpfWFzeW5jIHJlY29uY2lsZSgkLFope3RoaXMuc2NoZWR1bGVkU3luYy5jYW5jZWwoKSxhd2FpdCB0aGlzLnN5bmNSdW5zLmZsdXNoKCk7bGV0e2Nvbm5lY3Rpb25zOkosY3J5cHRvOlEsc3RvcmU6Vn09dGhpcyxZPWF3YWl0IFYuc2VlZC5sb2FkKCk7aWYoIVkpcmV0dXJuIEcoMjIpO2xldCBYPWF3YWl0IFYuaG9zdHMuZ2V0KCQpO2lmKCFYKXJldHVybiBHKDEzKTtsZXQgVz1KLmdldCgkKTtpZighV3x8IVcuaXNDb25uZWN0ZWQoKSl7aWYoYXdhaXQgdGhpcy5jb25uZWN0VG9Ib3N0KFgsITEsITEpLFg9YXdhaXQgVi5ob3N0cy5nZXQoJCksIVgpcmV0dXJuIEcoMTMpO1c9Si5nZXQoJCl9aWYoIVcpcmV0dXJuIEcoMTIpO2xldCB6PXtjb25uOlcsc3RvcmU6VixlbmNsYXZlOlksY3J5cHRvOlEsbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LFtLLEZdPWF3YWl0IGZaKHsuLi56LGhvc3Q6WH0sWik7aWYodGhpcy54ZmVyU3RhdGUuZW1pdCgpLEYhPT0wKXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksRyhGKTtpZighSylyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEcoMTIpO2lmKFo/LnN5bmM9PT0hMSlyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLFIoSyk7bGV0IE49YXdhaXQgdGhpcy5zeW5jKCk7aWYoTiE9PTApcmV0dXJuIEcoTik7bGV0IFU9YXdhaXQgVi5ob3N0cy5nZXQoJCk7aWYoIVUpcmV0dXJuIEcoMTMpO2xldFtPLHFdPWF3YWl0IGZaKHsuLi56LGhvc3Q6VX0se3B1bGw6ITEscHVzaDohMX0pO2lmKHRoaXMueGZlclN0YXRlLmVtaXQoKSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSkscSE9PTApcmV0dXJuIEcocSk7aWYoIU8pcmV0dXJuIEcoMTIpO3JldHVybiBSKE8pfWFzeW5jIHJlcHVsbCgpe2xldHtjb25uZWN0aW9uczokLGNyeXB0bzpaLHN0b3JlOkp9PXRoaXMsUT1hd2FpdCBKLnNlZWQubG9hZCgpO2lmKCFRKXJldHVybiAyMjtsZXQgVj1BcnJheS5mcm9tKGF3YWl0IEouaG9zdHMubGlzdCgpKTtpZihWLmxlbmd0aDwxKXJldHVybiAwO2ZvcihsZXQgWSBvZiBWKXtsZXQgWD0kLmdldChZLmxhYmVsKTtpZighWHx8IVguaXNDb25uZWN0ZWQoKSlhd2FpdCB0aGlzLmNvbm5lY3RUb0hvc3QoWSwhMSwhMSl9Zm9yKGxldFtZLFhdb2YgJCl7bGV0IFc9YXdhaXQgSi5ob3N0cy5nZXQoWSk7aWYoIVcpY29udGludWU7bGV0IHo9e2Nvbm46WCxzdG9yZTpKLGVuY2xhdmU6USxob3N0OnsuLi5XLGxhc3RTZXE6MH0sY3J5cHRvOlosbWF4UHVzaEJ5dGVzOnRoaXMubWF4UHVzaEJ5dGVzLG1heFB1bGxCeXRlczp0aGlzLm1heFB1bGxCeXRlcyxvblByb2dyZXNzOnRoaXMuZW1pdFByb2dyZXNzLHBlZWtQcm9ncmVzc0V2ZXJ5OnRoaXMucGVla1Byb2dyZXNzRXZlcnl9LEs9YXdhaXQgTFooeik7aWYoSyE9PTApcmV0dXJuIGNvbnNvbGUuZXJyb3IoYHJlYnVpbGQ6IGZhaWxlZCB0byBwZWVrOiAke0t9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEs7dGhpcy54ZmVyU3RhdGUuZW1pdCgpO2xldCBGPWF3YWl0IHhaKHopO2lmKEYhPT0wJiZGIT09MTUpcmV0dXJuIGNvbnNvbGUuZXJyb3IoYHJlYnVpbGQ6IGZhaWxlZCB0byBwdWxsOiAke0Z9YCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLEY7dGhpcy54ZmVyU3RhdGUuZW1pdCgpfXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH1hc3luYyByZXBsYXkoKXtsZXQgJD1hd2FpdCB0aGlzLnN0YXRlLmNsZWFyKCk7aWYoJCE9PTApcmV0dXJuICQ7bGV0IFo9YXdhaXQgdGhpcy5zdG9yZS5tZXNzYWdlcy5saXN0KCksSj1vMChaLChZKT0+WS5oZWFkKSxRPUoubGVuZ3RoO2lmKFE8MSlyZXR1cm4gdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDA7bGV0IFY9MDt3aGlsZShWPEoubGVuZ3RoKXtsZXQgWT0wLFg9MCxXPVY7Zm9yKGxldCBLPVY7SzxKLmxlbmd0aCYmWDwxMDAmJlk8MTAyNDAwO0srKylZKz1KW0tdLmhlYWQubGVuLFgrKyxXPUsrMTtsZXQgej1KLnNsaWNlKFYsVyk7YXdhaXQgdGhpcy5hcHBseVN0b3JlZCh6KSx0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImV4ZWMiLGRvbmU6Vyx0b3RhbDpRfSksVj1XfXJldHVybiB0aGlzLmVtaXRQcm9ncmVzcyh7cGhhc2U6ImlkbGUifSksMH1hc3luYyB3aXBlKCQpe2xldCBaPSQ/Lm1zZ3MhPT0hMSxKPSQ/LmVudHMhPT0hMSxRPSQ/Lm1ldGEhPT0hMSxWPSQ/LnNlZWQ9PT0hMDt0aGlzLnNjaGVkdWxlZFN5bmMuY2FuY2VsKCksYXdhaXQgdGhpcy5kaXNjb25uZWN0KCksYXdhaXQgdGhpcy5zeW5jUnVucy5mbHVzaCgpO2xldHtzdG9yZTpZfT10aGlzO2lmKFEpYXdhaXQgWS5ob3N0cy53aXBlKCksYXdhaXQgWS51cGxvYWRzLndpcGUoKSxhd2FpdCBZLmRvd25sb2Fkcy53aXBlKCk7aWYoWilhd2FpdCBZLm1lc3NhZ2VzLndpcGUoKTtpZihWKWF3YWl0IFkuc2VlZC53aXBlKCk7aWYoSilhd2FpdCB0aGlzLnN0YXRlLmNsZWFyKCk7dGhpcy5sYXN0UHJvZ3Jlc3M9d1osdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCksdGhpcy54ZmVyU3RhdGUuZW1pdCgpfWltcG9ydD1hc3luYygkLFopPT57bGV0e2NyeXB0bzpKLHN0b3JlOlF9PXRoaXMsVj1aPy5vblByb2dyZXNzLFk9YXdhaXQgUS5zZWVkLmxvYWQoKTtpZighWSlyZXR1cm4gMjI7Y29uc29sZS50aW1lKCJpbXBvcnQ6IGRlY29kaW5nIGZpbGUuLi4iKTtsZXQgWD1hd2FpdCAkLmJ5dGVzKCksW1csel09YXdhaXQgeEooWCxKLFkpO2lmKHohPT0wKXJldHVybiB6O2NvbnNvbGUudGltZUVuZCgiaW1wb3J0OiBkZWNvZGluZyBmaWxlLi4uIik7bGV0IEs9MDt3aGlsZShLPFcubGVuZ3RoKXtsZXQgRj0wLE49MCxVPUs7Zm9yKGxldCBJPUs7STxXLmxlbmd0aCYmTjwxMDAmJkY8MTAyNDAwO0krKylGKz1XW0ldLmhlYWQubGVuLE4rKyxVPUkrMTtsZXQgTz1XLnNsaWNlKEssVSk7Y29uc29sZS50aW1lKGBpbXBvcnQ6IGFwcGx5aW5nIFske0t9LCAke1V9XWApO2xldCBxPWF3YWl0IHRoaXMuYXBwbHkoTyx7ZW5xdWV1ZVVwbG9hZDohMCx0cmlnZ2VyVXBsb2FkOiExfSk7Y29uc29sZS50aW1lRW5kKGBpbXBvcnQ6IGFwcGx5aW5nIFske0t9LCAke1V9XWApO2ZvcihsZXQgST0wO0k8Ty5sZW5ndGg7SSsrKXtsZXQgSD1xW0ldO2lmKEghPT0wJiZIIT09MTUpY29uc29sZS53YXJuKGBmYWlsZWQgdG8gaW1wb3J0IG1zZyAke0srSX06ICR7altIXX1gKX1pZihWKXF1ZXVlTWljcm90YXNrKCgpPT5WKFUsVy5sZW5ndGgsMCkpO3RoaXMuZW1pdFByb2dyZXNzKHtwaGFzZToiaW1wb3J0Iixkb25lOlUsdG90YWw6Vy5sZW5ndGh9KSxLPVV9cmV0dXJuIHRoaXMuc2NoZWR1bGVTeW5jKCksdGhpcy5lbWl0UHJvZ3Jlc3Moe3BoYXNlOiJpZGxlIn0pLDB9O3NjaGVkdWxlU3luYz0oKT0+e2lmKHRoaXMub25TY2hlZHVsZVN5bmMpe3RoaXMub25TY2hlZHVsZVN5bmMoKTtyZXR1cm59dGhpcy5zY2hlZHVsZWRTeW5jLnNjaGVkdWxlKCl9O2FzeW5jIGV4cG9ydEJ5dGVzKCl7bGV0e2NyeXB0bzokLHN0b3JlOlp9PXRoaXMsSj1hd2FpdCBaLnNlZWQubG9hZCgpO2lmKCFKKXJldHVybiBHKDIyKTtsZXQgUT1hd2FpdCBaLm1lc3NhZ2VzLmxpc3QoKTtyZXR1cm4gTEooImV4cG9ydCIsMCxRLCQsSil9YXN5bmMgZXhwb3J0KCQpe2xldFtaLEpdPWF3YWl0IHRoaXMuZXhwb3J0Qnl0ZXMoKTtpZihKIT09MClyZXR1cm4gSjtpZighWilyZXR1cm4gMTI7bGV0IFE9bmV3IEJsb2IoW1ouc2xpY2UoKV0pO3JldHVybiBoSihRLCQpLDB9YXN5bmMgbGluaygkLFo9ITApe2lmKGF3YWl0IHRoaXMuc3RvcmUuaG9zdHMuYWRkKCQpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLFope2xldCBKPWF3YWl0IHRoaXMuc3RvcmUuaG9zdHMuZ2V0KCQubGFiZWwpO2lmKEopYXdhaXQgdGhpcy5jb25uZWN0VG9Ib3N0KEopfX1hc3luYyB1bmxpbmsoJCl7YXdhaXQgdGhpcy5zdG9yZS5ob3N0cy5kZWwoJCksdGhpcy5jbGllbnRTdGF0ZS5lbWl0KCl9YXN5bmMgaG9zdHMoKXtyZXR1cm4gQXJyYXkuZnJvbShhd2FpdCB0aGlzLnN0b3JlLmhvc3RzLmxpc3QoKSl9Y29ubmVjdFRvSG9zdD1hc3luYygkLFo9ITAsSj0hMCk9PntsZXR7Y2xvY2s6USxjb25uZWN0aW9uczpWLGNyeXB0bzpZLHN0b3JlOlgsdHJhbnNwb3J0Old9PXRoaXMsej1WLmdldCgkLmxhYmVsKTtpZih6KXtpZih6LmlzQ29ubmVjdGVkKCkpcmV0dXJuO3RyeXt6LmNsb3NlTGlzdGVuZXIoKX1jYXRjaHt9Vi5kZWxldGUoJC5sYWJlbCl9bGV0IEs9YXdhaXQgWC5zZWVkLmxvYWQoKTtpZighSylyZXR1cm47Y29uc29sZS5pbmZvKGBDb25uZWN0aW5nIHRvICR7JC5oYW5kbGV9ICgkeyQubGFiZWx9KWApO2xldCBGPW5ldyBMJChLLFksJCxRLFcoJCksKE4pPT5YLmhvc3RzLnNldCgkLmxhYmVsLE4pKTtpZihhd2FpdCBGLnJlZ2lzdGVyKCksWilhd2FpdCBGLmxpc3Rlbihhc3luYyhOKT0+e2xldCBVPXtjb25uOkYsc3RvcmU6WCxlbmNsYXZlOkssaG9zdDokLGNyeXB0bzpZLG1heFB1c2hCeXRlczp0aGlzLm1heFB1c2hCeXRlcyxtYXhQdWxsQnl0ZXM6dGhpcy5tYXhQdWxsQnl0ZXMsb25Qcm9ncmVzczp0aGlzLmVtaXRQcm9ncmVzcyxwZWVrUHJvZ3Jlc3NFdmVyeTp0aGlzLnBlZWtQcm9ncmVzc0V2ZXJ5fTtyZXR1cm4gYUooTixVLHRoaXMuc2NoZWR1bGVTeW5jKX0sKCk9PnRoaXMuY2xpZW50U3RhdGUuZW1pdCgpLCgpPT50aGlzLmNsaWVudFN0YXRlLmVtaXQoKSk7aWYoVi5zZXQoJC5sYWJlbCxGKSx0aGlzLmNsaWVudFN0YXRlLmVtaXQoKSxKKXRoaXMuc2NoZWR1bGVTeW5jKCl9O2FzeW5jIGNvbm5lY3QoJD0hMCxaPSEwKXtsZXR7Y29ubmVjdFRvSG9zdDpKLHNjaGVkdWxlU3luYzpRLHN0b3JlOlZ9PXRoaXM7aWYoIWF3YWl0IFYuc2VlZC5sb2FkKCkpcmV0dXJuO2F3YWl0IHRoaXMuZHJhaW5BcHBseVF1ZXVlKCk7bGV0IFg9YXdhaXQgVi5ob3N0cy5saXN0KCk7Zm9yKGxldCBXIG9mIFgpYXdhaXQgSihXLCQsITEpO2lmKFopUSgpfWRpc2Nvbm5lY3Q9YXN5bmMoKT0+e2ZvcihsZXQgJCBvZiB0aGlzLmNvbm5lY3Rpb25zLnZhbHVlcygpKXRyeXskLmNsb3NlTGlzdGVuZXIoKX1jYXRjaHt9dGhpcy5jb25uZWN0aW9ucy5jbGVhcigpLHRoaXMuY2xpZW50U3RhdGUuZW1pdCgpfX12YXIgeDA9dHlwZW9mIGdsb2JhbFRoaXM9PT0ib2JqZWN0IiYmImNyeXB0byJpbiBnbG9iYWxUaGlzP2dsb2JhbFRoaXMuY3J5cHRvOnZvaWQgMDtmdW5jdGlvbiBiJCgkKXtpZighTnVtYmVyLmlzU2FmZUludGVnZXIoJCl8fCQ8MCl0aHJvdyBFcnJvcigicG9zaXRpdmUgaW50ZWdlciBleHBlY3RlZCwgZ290ICIrJCl9ZnVuY3Rpb24gQlooJCl7cmV0dXJuICQgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxBcnJheUJ1ZmZlci5pc1ZpZXcoJCkmJiQuY29uc3RydWN0b3IubmFtZT09PSJVaW50OEFycmF5In1mdW5jdGlvbiBkKCQsLi4uWil7aWYoIUJaKCQpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIik7aWYoWi5sZW5ndGg+MCYmIVouaW5jbHVkZXMoJC5sZW5ndGgpKXRocm93IEVycm9yKCJVaW50OEFycmF5IGV4cGVjdGVkIG9mIGxlbmd0aCAiK1orIiwgZ290IGxlbmd0aD0iKyQubGVuZ3RoKX1mdW5jdGlvbiBFWigkLFo9ITApe2lmKCQuZGVzdHJveWVkKXRocm93IEVycm9yKCJIYXNoIGluc3RhbmNlIGhhcyBiZWVuIGRlc3Ryb3llZCIpO2lmKFomJiQuZmluaXNoZWQpdGhyb3cgRXJyb3IoIkhhc2gjZGlnZXN0KCkgaGFzIGFscmVhZHkgYmVlbiBjYWxsZWQiKX1mdW5jdGlvbiBzSigkLFope2QoJCk7bGV0IEo9Wi5vdXRwdXRMZW47aWYoJC5sZW5ndGg8Sil0aHJvdyBFcnJvcigiZGlnZXN0SW50bygpIGV4cGVjdHMgb3V0cHV0IGJ1ZmZlciBvZiBsZW5ndGggYXQgbGVhc3QgIitKKX1mdW5jdGlvbiBtWigkKXtpZih0eXBlb2YgJCE9PSJib29sZWFuIil0aHJvdyBFcnJvcihgYm9vbGVhbiBleHBlY3RlZCwgbm90ICR7JH1gKX0vKiEgbm9ibGUtY2lwaGVycyAtIE1JVCBMaWNlbnNlIChjKSAyMDIzIFBhdWwgTWlsbGVyIChwYXVsbWlsbHIuY29tKSAqL3ZhciBJMD0oJCk9Pm5ldyBVaW50MzJBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsTWF0aC5mbG9vcigkLmJ5dGVMZW5ndGgvNCkpO3ZhciBUVj1uZXcgVWludDhBcnJheShuZXcgVWludDMyQXJyYXkoWzI4NzQ1NDAyMF0pLmJ1ZmZlcilbMF09PT02ODtpZighVFYpdGhyb3cgRXJyb3IoIk5vbiBsaXR0bGUtZW5kaWFuIGhhcmR3YXJlIGlzIG5vdCBzdXBwb3J0ZWQiKTtmdW5jdGlvbiBEVigkKXtpZih0eXBlb2YgJCE9PSJzdHJpbmciKXRocm93IEVycm9yKCJzdHJpbmcgZXhwZWN0ZWQiKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkobmV3IFRleHRFbmNvZGVyKCkuZW5jb2RlKCQpKX1mdW5jdGlvbiB5JCgkKXtpZih0eXBlb2YgJD09PSJzdHJpbmciKSQ9RFYoJCk7ZWxzZSBpZihCWigkKSkkPWkkKCQpO2Vsc2UgdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQsIGdvdCAiK3R5cGVvZiAkKTtyZXR1cm4gJH1mdW5jdGlvbiB0SigkLFope2lmKFo9PW51bGx8fHR5cGVvZiBaIT09Im9iamVjdCIpdGhyb3cgRXJyb3IoIm9wdGlvbnMgbXVzdCBiZSBkZWZpbmVkIik7cmV0dXJuIE9iamVjdC5hc3NpZ24oJCxaKX1mdW5jdGlvbiBlSigkLFope2lmKCQubGVuZ3RoIT09Wi5sZW5ndGgpcmV0dXJuITE7bGV0IEo9MDtmb3IobGV0IFE9MDtRPCQubGVuZ3RoO1ErKylKfD0kW1FdXlpbUV07cmV0dXJuIEo9PT0wfXZhciAkUT0oJCxaKT0+e2Z1bmN0aW9uIEooUSwuLi5WKXtpZihkKFEpLCQubm9uY2VMZW5ndGghPT12b2lkIDApe2xldCBGPVZbMF07aWYoIUYpdGhyb3cgRXJyb3IoIm5vbmNlIC8gaXYgcmVxdWlyZWQiKTtpZigkLnZhclNpemVOb25jZSlkKEYpO2Vsc2UgZChGLCQubm9uY2VMZW5ndGgpfWxldCBZPSQudGFnTGVuZ3RoO2lmKFkmJlZbMV0hPT12b2lkIDApZChWWzFdKTtsZXQgWD1aKFEsLi4uViksVz0oRixOKT0+e2lmKE4hPT12b2lkIDApe2lmKEYhPT0yKXRocm93IEVycm9yKCJjaXBoZXIgb3V0cHV0IG5vdCBzdXBwb3J0ZWQiKTtkKE4pfX0sej0hMTtyZXR1cm57ZW5jcnlwdChGLE4pe2lmKHopdGhyb3cgRXJyb3IoImNhbm5vdCBlbmNyeXB0KCkgdHdpY2Ugd2l0aCBzYW1lIGtleSArIG5vbmNlIik7cmV0dXJuIHo9ITAsZChGKSxXKFguZW5jcnlwdC5sZW5ndGgsTiksWC5lbmNyeXB0KEYsTil9LGRlY3J5cHQoRixOKXtpZihkKEYpLFkmJkYubGVuZ3RoPFkpdGhyb3cgRXJyb3IoImludmFsaWQgY2lwaGVydGV4dCBsZW5ndGg6IHNtYWxsZXIgdGhhbiB0YWdMZW5ndGg9IitZKTtyZXR1cm4gVyhYLmRlY3J5cHQubGVuZ3RoLE4pLFguZGVjcnlwdChGLE4pfX19cmV0dXJuIE9iamVjdC5hc3NpZ24oSiwkKSxKfTtmdW5jdGlvbiBnWigkLFosSj0hMCl7aWYoWj09PXZvaWQgMClyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJCk7aWYoWi5sZW5ndGghPT0kKXRocm93IEVycm9yKCJpbnZhbGlkIG91dHB1dCBsZW5ndGgsIGV4cGVjdGVkICIrJCsiLCBnb3Q6ICIrWi5sZW5ndGgpO2lmKEomJiFqVihaKSl0aHJvdyBFcnJvcigiaW52YWxpZCBvdXRwdXQsIG11c3QgYmUgYWxpZ25lZCIpO3JldHVybiBafWZ1bmN0aW9uIGpWKCQpe3JldHVybiAkLmJ5dGVPZmZzZXQlND09PTB9ZnVuY3Rpb24gaSQoJCl7cmV0dXJuIFVpbnQ4QXJyYXkuZnJvbSgkKX1mdW5jdGlvbiBVMCguLi4kKXtmb3IobGV0IFo9MDtaPCQubGVuZ3RoO1orKykkW1pdLmZpbGwoMCl9ZnVuY3Rpb24gaCQoJD0zMil7aWYoeDAmJnR5cGVvZiB4MC5nZXRSYW5kb21WYWx1ZXM9PT0iZnVuY3Rpb24iKXJldHVybiB4MC5nZXRSYW5kb21WYWx1ZXMobmV3IFVpbnQ4QXJyYXkoJCkpO2lmKHgwJiZ0eXBlb2YgeDAucmFuZG9tQnl0ZXM9PT0iZnVuY3Rpb24iKXJldHVybiB4MC5yYW5kb21CeXRlcygkKTt0aHJvdyBFcnJvcigiY3J5cHRvLmdldFJhbmRvbVZhbHVlcyBtdXN0IGJlIGRlZmluZWQiKX12YXIgSlE9KCQpPT5VaW50OEFycmF5LmZyb20oJC5zcGxpdCgiIikubWFwKChaKT0+Wi5jaGFyQ29kZUF0KDApKSksQVY9SlEoImV4cGFuZCAxNi1ieXRlIGsiKSxfVj1KUSgiZXhwYW5kIDMyLWJ5dGUgayIpLExWPUkwKEFWKSx4Vj1JMChfVik7ZnVuY3Rpb24gRCgkLFope3JldHVybiAkPDxafCQ+Pj4zMi1afWZ1bmN0aW9uIFNaKCQpe3JldHVybiAkLmJ5dGVPZmZzZXQlND09PTB9dmFyIHUkPTY0LGZWPTE2LFFRPTQyOTQ5NjcyOTUsWlE9bmV3IFVpbnQzMkFycmF5O2Z1bmN0aW9uIGtWKCQsWixKLFEsVixZLFgsVyl7bGV0IHo9Vi5sZW5ndGgsSz1uZXcgVWludDhBcnJheSh1JCksRj1JMChLKSxOPVNaKFYpJiZTWihZKSxVPU4/STAoVik6WlEsTz1OP0kwKFkpOlpRO2ZvcihsZXQgcT0wO3E8ejtYKyspe2lmKCQoWixKLFEsRixYLFcpLFg+PVFRKXRocm93IEVycm9yKCJhcng6IGNvdW50ZXIgb3ZlcmZsb3ciKTtsZXQgST1NYXRoLm1pbih1JCx6LXEpO2lmKE4mJkk9PT11JCl7bGV0IEg9cS80O2lmKHElNCE9PTApdGhyb3cgRXJyb3IoImFyeDogaW52YWxpZCBibG9jayBwb3NpdGlvbiIpO2ZvcihsZXQgUD0wLEM7UDxmVjtQKyspQz1IK1AsT1tDXT1VW0NdXkZbUF07cSs9dSQ7Y29udGludWV9Zm9yKGxldCBIPTAsUDtIPEk7SCsrKVA9cStILFlbUF09VltQXV5LW0hdO3ErPUl9fWZ1bmN0aW9uIFZRKCQsWil7bGV0e2FsbG93U2hvcnRLZXlzOkosZXh0ZW5kTm9uY2VGbjpRLGNvdW50ZXJMZW5ndGg6Vixjb3VudGVyUmlnaHQ6WSxyb3VuZHM6WH09dEooe2FsbG93U2hvcnRLZXlzOiExLGNvdW50ZXJMZW5ndGg6OCxjb3VudGVyUmlnaHQ6ITEscm91bmRzOjIwfSxaKTtpZih0eXBlb2YgJCE9PSJmdW5jdGlvbiIpdGhyb3cgRXJyb3IoImNvcmUgbXVzdCBiZSBhIGZ1bmN0aW9uIik7cmV0dXJuIGIkKFYpLGIkKFgpLG1aKFkpLG1aKEopLChXLHosSyxGLE49MCk9PntkKFcpLGQoeiksZChLKTtsZXQgVT1LLmxlbmd0aDtpZihGPT09dm9pZCAwKUY9bmV3IFVpbnQ4QXJyYXkoVSk7aWYoZChGKSxiJChOKSxOPDB8fE4+PVFRKXRocm93IEVycm9yKCJhcng6IGNvdW50ZXIgb3ZlcmZsb3ciKTtpZihGLmxlbmd0aDxVKXRocm93IEVycm9yKGBhcng6IG91dHB1dCAoJHtGLmxlbmd0aH0pIGlzIHNob3J0ZXIgdGhhbiBkYXRhICgke1V9KWApO2xldCBPPVtdLHE9Vy5sZW5ndGgsSSxIO2lmKHE9PT0zMilPLnB1c2goST1pJChXKSksSD14VjtlbHNlIGlmKHE9PT0xNiYmSilJPW5ldyBVaW50OEFycmF5KDMyKSxJLnNldChXKSxJLnNldChXLDE2KSxIPUxWLE8ucHVzaChJKTtlbHNlIHRocm93IEVycm9yKGBhcng6IGludmFsaWQgMzItYnl0ZSBrZXksIGdvdCBsZW5ndGg9JHtxfWApO2lmKCFTWih6KSlPLnB1c2goej1pJCh6KSk7bGV0IFA9STAoSSk7aWYoUSl7aWYoei5sZW5ndGghPT0yNCl0aHJvdyBFcnJvcigiYXJ4OiBleHRlbmRlZCBub25jZSBtdXN0IGJlIDI0IGJ5dGVzIik7UShILFAsSTAoei5zdWJhcnJheSgwLDE2KSksUCksej16LnN1YmFycmF5KDE2KX1sZXQgQz0xNi1WO2lmKEMhPT16Lmxlbmd0aCl0aHJvdyBFcnJvcihgYXJ4OiBub25jZSBtdXN0IGJlICR7Q30gb3IgMTYgYnl0ZXNgKTtpZihDIT09MTIpe2xldCBNPW5ldyBVaW50OEFycmF5KDEyKTtNLnNldCh6LFk/MDoxMi16Lmxlbmd0aCksej1NLE8ucHVzaCh6KX1sZXQgVD1JMCh6KTtyZXR1cm4ga1YoJCxILFAsVCxLLEYsTixYKSxVMCguLi5PKSxGfX12YXIgbz0oJCxaKT0+JFtaKytdJjI1NXwoJFtaKytdJjI1NSk8PDg7Y2xhc3MgWVF7Y29uc3RydWN0b3IoJCl7dGhpcy5ibG9ja0xlbj0xNix0aGlzLm91dHB1dExlbj0xNix0aGlzLmJ1ZmZlcj1uZXcgVWludDhBcnJheSgxNiksdGhpcy5yPW5ldyBVaW50MTZBcnJheSgxMCksdGhpcy5oPW5ldyBVaW50MTZBcnJheSgxMCksdGhpcy5wYWQ9bmV3IFVpbnQxNkFycmF5KDgpLHRoaXMucG9zPTAsdGhpcy5maW5pc2hlZD0hMSwkPXkkKCQpLGQoJCwzMik7bGV0IFo9bygkLDApLEo9bygkLDIpLFE9bygkLDQpLFY9bygkLDYpLFk9bygkLDgpLFg9bygkLDEwKSxXPW8oJCwxMiksej1vKCQsMTQpO3RoaXMuclswXT1aJjgxOTEsdGhpcy5yWzFdPShaPj4+MTN8Sjw8MykmODE5MSx0aGlzLnJbMl09KEo+Pj4xMHxRPDw2KSY3OTM5LHRoaXMuclszXT0oUT4+Pjd8Vjw8OSkmODE5MSx0aGlzLnJbNF09KFY+Pj40fFk8PDEyKSYyNTUsdGhpcy5yWzVdPVk+Pj4xJjgxOTAsdGhpcy5yWzZdPShZPj4+MTR8WDw8MikmODE5MSx0aGlzLnJbN109KFg+Pj4xMXxXPDw1KSY4MDY1LHRoaXMucls4XT0oVz4+Pjh8ejw8OCkmODE5MSx0aGlzLnJbOV09ej4+PjUmMTI3O2ZvcihsZXQgSz0wO0s8ODtLKyspdGhpcy5wYWRbS109bygkLDE2KzIqSyl9cHJvY2VzcygkLFosSj0hMSl7bGV0IFE9Sj8wOjIwNDgse2g6VixyOll9PXRoaXMsWD1ZWzBdLFc9WVsxXSx6PVlbMl0sSz1ZWzNdLEY9WVs0XSxOPVlbNV0sVT1ZWzZdLE89WVs3XSxxPVlbOF0sST1ZWzldLEg9bygkLForMCksUD1vKCQsWisyKSxDPW8oJCxaKzQpLFQ9bygkLForNiksTT1vKCQsWis4KSxBPW8oJCxaKzEwKSx4PW8oJCxaKzEyKSxtPW8oJCxaKzE0KSxFPVZbMF0rKEgmODE5MSksaz1WWzFdKygoSD4+PjEzfFA8PDMpJjgxOTEpLGI9VlsyXSsoKFA+Pj4xMHxDPDw2KSY4MTkxKSx3PVZbM10rKChDPj4+N3xUPDw5KSY4MTkxKSxoPVZbNF0rKChUPj4+NHxNPDwxMikmODE5MSksbD1WWzVdKyhNPj4+MSY4MTkxKSxMPVZbNl0rKChNPj4+MTR8QTw8MikmODE5MSksdj1WWzddKygoQT4+PjExfHg8PDUpJjgxOTEpLEI9Vls4XSsoKHg+Pj44fG08PDgpJjgxOTEpLHk9Vls5XSsobT4+PjV8USksXz0wLGM9XytFKlgrayooNSpJKStiKig1KnEpK3cqKDUqTykraCooNSpVKTtfPWM+Pj4xMyxjJj04MTkxLGMrPWwqKDUqTikrTCooNSpGKSt2Kig1KkspK0IqKDUqeikreSooNSpXKSxfKz1jPj4+MTMsYyY9ODE5MTtsZXQgYT1fK0UqVytrKlgrYiooNSpJKSt3Kig1KnEpK2gqKDUqTyk7Xz1hPj4+MTMsYSY9ODE5MSxhKz1sKig1KlUpK0wqKDUqTikrdiooNSpGKStCKig1KkspK3kqKDUqeiksXys9YT4+PjEzLGEmPTgxOTE7bGV0IEowPV8rRSp6K2sqVytiKlgrdyooNSpJKStoKig1KnEpO189SjA+Pj4xMyxKMCY9ODE5MSxKMCs9bCooNSpPKStMKig1KlUpK3YqKDUqTikrQiooNSpGKSt5Kig1KkspLF8rPUowPj4+MTMsSjAmPTgxOTE7bGV0IHA9XytFKksrayp6K2IqVyt3KlgraCooNSpJKTtfPXA+Pj4xMyxwJj04MTkxLHArPWwqKDUqcSkrTCooNSpPKSt2Kig1KlUpK0IqKDUqTikreSooNSpGKSxfKz1wPj4+MTMscCY9ODE5MTtsZXQgcTA9XytFKkYraypLK2Iqeit3KlcraCpYO189cTA+Pj4xMyxxMCY9ODE5MSxxMCs9bCooNSpJKStMKig1KnEpK3YqKDUqTykrQiooNSpVKSt5Kig1Kk4pLF8rPXEwPj4+MTMscTAmPTgxOTE7bGV0IHYwPV8rRSpOK2sqRitiKksrdyp6K2gqVztfPXYwPj4+MTMsdjAmPTgxOTEsdjArPWwqWCtMKig1KkkpK3YqKDUqcSkrQiooNSpPKSt5Kig1KlUpLF8rPXYwPj4+MTMsdjAmPTgxOTE7bGV0IGIwPV8rRSpVK2sqTitiKkYrdypLK2gqejtfPWIwPj4+MTMsYjAmPTgxOTEsYjArPWwqVytMKlgrdiooNSpJKStCKig1KnEpK3kqKDUqTyksXys9YjA+Pj4xMyxiMCY9ODE5MTtsZXQgeTA9XytFKk8raypVK2IqTit3KkYraCpLO189eTA+Pj4xMyx5MCY9ODE5MSx5MCs9bCp6K0wqVyt2KlgrQiooNSpJKSt5Kig1KnEpLF8rPXkwPj4+MTMseTAmPTgxOTE7bGV0IGkwPV8rRSpxK2sqTytiKlUrdypOK2gqRjtfPWkwPj4+MTMsaTAmPTgxOTEsaTArPWwqSytMKnordipXK0IqWCt5Kig1KkkpLF8rPWkwPj4+MTMsaTAmPTgxOTE7bGV0IGgwPV8rRSpJK2sqcStiKk8rdypVK2gqTjtfPWgwPj4+MTMsaDAmPTgxOTEsaDArPWwqRitMKksrdip6K0IqVyt5KlgsXys9aDA+Pj4xMyxoMCY9ODE5MSxfPShfPDwyKStffDAsXz1fK2N8MCxjPV8mODE5MSxfPV8+Pj4xMyxhKz1fLFZbMF09YyxWWzFdPWEsVlsyXT1KMCxWWzNdPXAsVls0XT1xMCxWWzVdPXYwLFZbNl09YjAsVls3XT15MCxWWzhdPWkwLFZbOV09aDB9ZmluYWxpemUoKXtsZXR7aDokLHBhZDpafT10aGlzLEo9bmV3IFVpbnQxNkFycmF5KDEwKSxRPSRbMV0+Pj4xMzskWzFdJj04MTkxO2ZvcihsZXQgWD0yO1g8MTA7WCsrKSRbWF0rPVEsUT0kW1hdPj4+MTMsJFtYXSY9ODE5MTskWzBdKz1RKjUsUT0kWzBdPj4+MTMsJFswXSY9ODE5MSwkWzFdKz1RLFE9JFsxXT4+PjEzLCRbMV0mPTgxOTEsJFsyXSs9USxKWzBdPSRbMF0rNSxRPUpbMF0+Pj4xMyxKWzBdJj04MTkxO2ZvcihsZXQgWD0xO1g8MTA7WCsrKUpbWF09JFtYXStRLFE9SltYXT4+PjEzLEpbWF0mPTgxOTE7Sls5XS09ODE5MjtsZXQgVj0oUV4xKS0xO2ZvcihsZXQgWD0wO1g8MTA7WCsrKUpbWF0mPVY7Vj1+Vjtmb3IobGV0IFg9MDtYPDEwO1grKykkW1hdPSRbWF0mVnxKW1hdOyRbMF09KCRbMF18JFsxXTw8MTMpJjY1NTM1LCRbMV09KCRbMV0+Pj4zfCRbMl08PDEwKSY2NTUzNSwkWzJdPSgkWzJdPj4+NnwkWzNdPDw3KSY2NTUzNSwkWzNdPSgkWzNdPj4+OXwkWzRdPDw0KSY2NTUzNSwkWzRdPSgkWzRdPj4+MTJ8JFs1XTw8MXwkWzZdPDwxNCkmNjU1MzUsJFs1XT0oJFs2XT4+PjJ8JFs3XTw8MTEpJjY1NTM1LCRbNl09KCRbN10+Pj41fCRbOF08PDgpJjY1NTM1LCRbN109KCRbOF0+Pj44fCRbOV08PDUpJjY1NTM1O2xldCBZPSRbMF0rWlswXTskWzBdPVkmNjU1MzU7Zm9yKGxldCBYPTE7WDw4O1grKylZPSgkW1hdK1pbWF18MCkrKFk+Pj4xNil8MCwkW1hdPVkmNjU1MzU7VTAoSil9dXBkYXRlKCQpe0VaKHRoaXMpO2xldHtidWZmZXI6WixibG9ja0xlbjpKfT10aGlzOyQ9eSQoJCk7bGV0IFE9JC5sZW5ndGg7Zm9yKGxldCBWPTA7VjxROyl7bGV0IFk9TWF0aC5taW4oSi10aGlzLnBvcyxRLVYpO2lmKFk9PT1KKXtmb3IoO0o8PVEtVjtWKz1KKXRoaXMucHJvY2VzcygkLFYpO2NvbnRpbnVlfWlmKFouc2V0KCQuc3ViYXJyYXkoVixWK1kpLHRoaXMucG9zKSx0aGlzLnBvcys9WSxWKz1ZLHRoaXMucG9zPT09Sil0aGlzLnByb2Nlc3MoWiwwLCExKSx0aGlzLnBvcz0wfXJldHVybiB0aGlzfWRlc3Ryb3koKXtVMCh0aGlzLmgsdGhpcy5yLHRoaXMuYnVmZmVyLHRoaXMucGFkKX1kaWdlc3RJbnRvKCQpe0VaKHRoaXMpLHNKKCQsdGhpcyksdGhpcy5maW5pc2hlZD0hMDtsZXR7YnVmZmVyOlosaDpKfT10aGlzLHtwb3M6UX09dGhpcztpZihRKXtaW1ErK109MTtmb3IoO1E8MTY7USsrKVpbUV09MDt0aGlzLnByb2Nlc3MoWiwwLCEwKX10aGlzLmZpbmFsaXplKCk7bGV0IFY9MDtmb3IobGV0IFk9MDtZPDg7WSsrKSRbVisrXT1KW1ldPj4+MCwkW1YrK109SltZXT4+Pjg7cmV0dXJuICR9ZGlnZXN0KCl7bGV0e2J1ZmZlcjokLG91dHB1dExlbjpafT10aGlzO3RoaXMuZGlnZXN0SW50bygkKTtsZXQgSj0kLnNsaWNlKDAsWik7cmV0dXJuIHRoaXMuZGVzdHJveSgpLEp9fWZ1bmN0aW9uIEJWKCQpe2xldCBaPShRLFYpPT4kKFYpLnVwZGF0ZSh5JChRKSkuZGlnZXN0KCksSj0kKG5ldyBVaW50OEFycmF5KDMyKSk7cmV0dXJuIFoub3V0cHV0TGVuPUoub3V0cHV0TGVuLFouYmxvY2tMZW49Si5ibG9ja0xlbixaLmNyZWF0ZT0oUSk9PiQoUSksWn12YXIgdlo9QlYoKCQpPT5uZXcgWVEoJCkpO2Z1bmN0aW9uIEVWKCQsWixKLFEsVixZPTIwKXtsZXQgWD0kWzBdLFc9WlswXSx6PVpbMV0sSz1aWzJdLEY9WlszXSxOPSRbMV0sVT1KWzBdLE89SlsxXSxxPVYsST0wLEg9JFsyXSxQPVpbNF0sQz1aWzVdLFQ9Wls2XSxNPVpbN10sQT0kWzNdLHg9WCxtPVcsRT16LGs9SyxiPUYsdz1OLGg9VSxsPU8sTD1xLHY9SSxCPUgseT1QLF89QyxjPVQsYT1NLEowPUE7Zm9yKGxldCBxMD0wO3EwPFk7cTArPTIpYl49RCh4K198MCw3KSxMXj1EKGIreHwwLDkpLF9ePUQoTCtifDAsMTMpLHhePUQoXytMfDAsMTgpLHZePUQodyttfDAsNyksY149RCh2K3d8MCw5KSxtXj1EKGMrdnwwLDEzKSx3Xj1EKG0rY3wwLDE4KSxhXj1EKEIraHwwLDcpLEVePUQoYStCfDAsOSksaF49RChFK2F8MCwxMyksQl49RChoK0V8MCwxOCksa149RChKMCt5fDAsNyksbF49RChrK0owfDAsOSkseV49RChsK2t8MCwxMyksSjBePUQoeStsfDAsMTgpLG1ePUQoeCtrfDAsNyksRV49RChtK3h8MCw5KSxrXj1EKEUrbXwwLDEzKSx4Xj1EKGsrRXwwLDE4KSxoXj1EKHcrYnwwLDcpLGxePUQoaCt3fDAsOSksYl49RChsK2h8MCwxMyksd149RChiK2x8MCwxOCkseV49RChCK3Z8MCw3KSxMXj1EKHkrQnwwLDkpLHZePUQoTCt5fDAsMTMpLEJePUQoditMfDAsMTgpLF9ePUQoSjArYXwwLDcpLGNePUQoXytKMHwwLDkpLGFePUQoYytffDAsMTMpLEowXj1EKGErY3wwLDE4KTtsZXQgcD0wO1FbcCsrXT1YK3h8MCxRW3ArK109VyttfDAsUVtwKytdPXorRXwwLFFbcCsrXT1LK2t8MCxRW3ArK109RitifDAsUVtwKytdPU4rd3wwLFFbcCsrXT1VK2h8MCxRW3ArK109TytsfDAsUVtwKytdPXErTHwwLFFbcCsrXT1JK3Z8MCxRW3ArK109SCtCfDAsUVtwKytdPVAreXwwLFFbcCsrXT1DK198MCxRW3ArK109VCtjfDAsUVtwKytdPU0rYXwwLFFbcCsrXT1BK0owfDB9ZnVuY3Rpb24gbVYoJCxaLEosUSl7bGV0IFY9JFswXSxZPVpbMF0sWD1aWzFdLFc9WlsyXSx6PVpbM10sSz0kWzFdLEY9SlswXSxOPUpbMV0sVT1KWzJdLE89SlszXSxxPSRbMl0sST1aWzRdLEg9Wls1XSxQPVpbNl0sQz1aWzddLFQ9JFszXTtmb3IobGV0IEE9MDtBPDIwO0ErPTIpel49RChWK0h8MCw3KSxVXj1EKHorVnwwLDkpLEhePUQoVSt6fDAsMTMpLFZePUQoSCtVfDAsMTgpLE9ePUQoSytZfDAsNyksUF49RChPK0t8MCw5KSxZXj1EKFArT3wwLDEzKSxLXj1EKFkrUHwwLDE4KSxDXj1EKHErRnwwLDcpLFhePUQoQytxfDAsOSksRl49RChYK0N8MCwxMykscV49RChGK1h8MCwxOCksV149RChUK0l8MCw3KSxOXj1EKFcrVHwwLDkpLElePUQoTitXfDAsMTMpLFRePUQoSStOfDAsMTgpLFlePUQoVitXfDAsNyksWF49RChZK1Z8MCw5KSxXXj1EKFgrWXwwLDEzKSxWXj1EKFcrWHwwLDE4KSxGXj1EKEsrenwwLDcpLE5ePUQoRitLfDAsOSksel49RChOK0Z8MCwxMyksS149RCh6K058MCwxOCksSV49RChxK098MCw3KSxVXj1EKEkrcXwwLDkpLE9ePUQoVStJfDAsMTMpLHFePUQoTytVfDAsMTgpLEhePUQoVCtDfDAsNyksUF49RChIK1R8MCw5KSxDXj1EKFArSHwwLDEzKSxUXj1EKEMrUHwwLDE4KTtsZXQgTT0wO1FbTSsrXT1WLFFbTSsrXT1LLFFbTSsrXT1xLFFbTSsrXT1ULFFbTSsrXT1GLFFbTSsrXT1OLFFbTSsrXT1VLFFbTSsrXT1PfXZhciBiWj1WUShFVix7Y291bnRlclJpZ2h0OiEwLGV4dGVuZE5vbmNlRm46bVZ9KSx5Wj0kUSh7YmxvY2tTaXplOjY0LG5vbmNlTGVuZ3RoOjI0LHRhZ0xlbmd0aDoxNn0sKCQsWik9PntyZXR1cm57ZW5jcnlwdChKLFEpe1E9Z1ooSi5sZW5ndGgrMzIsUSwhMSk7bGV0IFY9US5zdWJhcnJheSgwLDMyKSxZPVEuc3ViYXJyYXkoMzIpO1Euc2V0KEosMzIpLFUwKFYpLGJaKCQsWixRLFEpO2xldCBYPXZaKFksVik7cmV0dXJuIFEuc2V0KFgsMTYpLFUwKFEuc3ViYXJyYXkoMCwxNiksWCksUS5zdWJhcnJheSgxNil9LGRlY3J5cHQoSixRKXtkKEopLFE9Z1ooSi5sZW5ndGgrMzIsUSwhMSk7bGV0IFY9US5zdWJhcnJheSgwLDMyKSxZPVEuc3ViYXJyYXkoMzIsNDgpLFg9US5zdWJhcnJheSg0OCk7US5zZXQoSiwzMiksVTAoVik7bGV0IFc9YlooJCxaLFYsViksej12WihYLFcpO2lmKCFlSihZLHopKXRocm93IEVycm9yKCJpbnZhbGlkIHRhZyIpO3JldHVybiBiWigkLFosUS5zdWJhcnJheSgxNiksUS5zdWJhcnJheSgxNikpLFUwKFYsWSx6KSxYfX19KTsvKiEgbm9ibGUtaGFzaGVzIC0gTUlUIExpY2Vuc2UgKGMpIDIwMjIgUGF1bCBNaWxsZXIgKHBhdWxtaWxsci5jb20pICovZnVuY3Rpb24gZ1YoJCl7cmV0dXJuICQgaW5zdGFuY2VvZiBVaW50OEFycmF5fHxBcnJheUJ1ZmZlci5pc1ZpZXcoJCkmJiQuY29uc3RydWN0b3IubmFtZT09PSJVaW50OEFycmF5In1mdW5jdGlvbiBGJCgkKXtpZighTnVtYmVyLmlzU2FmZUludGVnZXIoJCl8fCQ8MCl0aHJvdyBFcnJvcigicG9zaXRpdmUgaW50ZWdlciBleHBlY3RlZCwgZ290ICIrJCl9ZnVuY3Rpb24gZjAoJCwuLi5aKXtpZighZ1YoJCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQiKTtpZihaLmxlbmd0aD4wJiYhWi5pbmNsdWRlcygkLmxlbmd0aCkpdGhyb3cgRXJyb3IoIlVpbnQ4QXJyYXkgZXhwZWN0ZWQgb2YgbGVuZ3RoICIrWisiLCBnb3QgbGVuZ3RoPSIrJC5sZW5ndGgpfWZ1bmN0aW9uIE4kKCQsWj0hMCl7aWYoJC5kZXN0cm95ZWQpdGhyb3cgRXJyb3IoIkhhc2ggaW5zdGFuY2UgaGFzIGJlZW4gZGVzdHJveWVkIik7aWYoWiYmJC5maW5pc2hlZCl0aHJvdyBFcnJvcigiSGFzaCNkaWdlc3QoKSBoYXMgYWxyZWFkeSBiZWVuIGNhbGxlZCIpfWZ1bmN0aW9uIGwkKCQsWil7ZjAoJCk7bGV0IEo9Wi5vdXRwdXRMZW47aWYoJC5sZW5ndGg8Sil0aHJvdyBFcnJvcigiZGlnZXN0SW50bygpIGV4cGVjdHMgb3V0cHV0IGJ1ZmZlciBvZiBsZW5ndGggYXQgbGVhc3QgIitKKX1mdW5jdGlvbiBYUSgkKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoJC5idWZmZXIsJC5ieXRlT2Zmc2V0LCQuYnl0ZUxlbmd0aCl9ZnVuY3Rpb24gdDAoJCl7cmV0dXJuIG5ldyBVaW50MzJBcnJheSgkLmJ1ZmZlciwkLmJ5dGVPZmZzZXQsTWF0aC5mbG9vcigkLmJ5dGVMZW5ndGgvNCkpfWZ1bmN0aW9uIGUwKC4uLiQpe2ZvcihsZXQgWj0wO1o8JC5sZW5ndGg7WisrKSRbWl0uZmlsbCgwKX1mdW5jdGlvbiBSJCgkLFope3JldHVybiAkPDwzMi1afCQ+Pj5afXZhciBXUT0oKCk9Pm5ldyBVaW50OEFycmF5KG5ldyBVaW50MzJBcnJheShbMjg3NDU0MDIwXSkuYnVmZmVyKVswXT09PTY4KSgpO2Z1bmN0aW9uIEdRKCQpe3JldHVybiAkPDwyNCY0Mjc4MTkwMDgwfCQ8PDgmMTY3MTE2ODB8JD4+PjgmNjUyODB8JD4+PjI0JjI1NX12YXIgelE9V1E/KCQpPT4kOigkKT0+R1EoJCk7ZnVuY3Rpb24gU1YoJCl7Zm9yKGxldCBaPTA7WjwkLmxlbmd0aDtaKyspJFtaXT1HUSgkW1pdKTtyZXR1cm4gJH12YXIgZT1XUT8oJCk9PiQ6U1Y7ZnVuY3Rpb24gdlYoJCl7aWYodHlwZW9mICQhPT0ic3RyaW5nIil0aHJvdyBFcnJvcigic3RyaW5nIGV4cGVjdGVkIik7cmV0dXJuIG5ldyBVaW50OEFycmF5KG5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSl9ZnVuY3Rpb24gJCQoJCl7aWYodHlwZW9mICQ9PT0ic3RyaW5nIikkPXZWKCQpO3JldHVybiBmMCgkKSwkfWNsYXNzIGlae31mdW5jdGlvbiBLUSgkKXtsZXQgWj0oUSxWKT0+JChWKS51cGRhdGUoJCQoUSkpLmRpZ2VzdCgpLEo9JCh7fSk7cmV0dXJuIFoub3V0cHV0TGVuPUoub3V0cHV0TGVuLFouYmxvY2tMZW49Si5ibG9ja0xlbixaLmNyZWF0ZT0oUSk9PiQoUSksWn12YXIgRlE9VWludDMyQXJyYXkuZnJvbShbMTc3OTAzMzcwMywzMTQ0MTM0Mjc3LDEwMTM5MDQyNDIsMjc3MzQ4MDc2MiwxMzU5ODkzMTE5LDI2MDA4MjI5MjQsNTI4NzM0NjM1LDE1NDE0NTkyMjVdKTt2YXIgcCQ9QmlnSW50KDQyOTQ5NjcyOTUpLE5RPUJpZ0ludCgzMik7ZnVuY3Rpb24gaFooJCxaPSExKXtpZihaKXJldHVybntoOk51bWJlcigkJnAkKSxsOk51bWJlcigkPj5OUSZwJCl9O3JldHVybntoOk51bWJlcigkPj5OUSZwJCl8MCxsOk51bWJlcigkJnAkKXwwfX1mdW5jdGlvbiBIMCgkLFosSixRLFYpe3JldHVybiAkPSQrWitWfDAsUT1SJChRXiQsMTYpLEo9SitRfDAsWj1SJChaXkosMTIpLHthOiQsYjpaLGM6SixkOlF9fWZ1bmN0aW9uIE0wKCQsWixKLFEsVil7cmV0dXJuICQ9JCtaK1Z8MCxRPVIkKFFeJCw4KSxKPUorUXwwLFo9UiQoWl5KLDcpLHthOiQsYjpaLGM6SixkOlF9fWNsYXNzIHVaIGV4dGVuZHMgaVp7Y29uc3RydWN0b3IoJCxaKXtzdXBlcigpO3RoaXMuZmluaXNoZWQ9ITEsdGhpcy5kZXN0cm95ZWQ9ITEsdGhpcy5sZW5ndGg9MCx0aGlzLnBvcz0wLEYkKCQpLEYkKFopLHRoaXMuYmxvY2tMZW49JCx0aGlzLm91dHB1dExlbj1aLHRoaXMuYnVmZmVyPW5ldyBVaW50OEFycmF5KCQpLHRoaXMuYnVmZmVyMzI9dDAodGhpcy5idWZmZXIpfXVwZGF0ZSgkKXtOJCh0aGlzKSwkPSQkKCQpLGYwKCQpO2xldHtibG9ja0xlbjpaLGJ1ZmZlcjpKLGJ1ZmZlcjMyOlF9PXRoaXMsVj0kLmxlbmd0aCxZPSQuYnl0ZU9mZnNldCxYPSQuYnVmZmVyO2ZvcihsZXQgVz0wO1c8Vjspe2lmKHRoaXMucG9zPT09WillKFEpLHRoaXMuY29tcHJlc3MoUSwwLCExKSxlKFEpLHRoaXMucG9zPTA7bGV0IHo9TWF0aC5taW4oWi10aGlzLnBvcyxWLVcpLEs9WStXO2lmKHo9PT1aJiYhKEslNCkmJlcrejxWKXtsZXQgRj1uZXcgVWludDMyQXJyYXkoWCxLLE1hdGguZmxvb3IoKFYtVykvNCkpO2UoRik7Zm9yKGxldCBOPTA7VytaPFY7Tis9US5sZW5ndGgsVys9Wil0aGlzLmxlbmd0aCs9Wix0aGlzLmNvbXByZXNzKEYsTiwhMSk7ZShGKTtjb250aW51ZX1KLnNldCgkLnN1YmFycmF5KFcsVyt6KSx0aGlzLnBvcyksdGhpcy5wb3MrPXosdGhpcy5sZW5ndGgrPXosVys9en1yZXR1cm4gdGhpc31kaWdlc3RJbnRvKCQpe04kKHRoaXMpLGwkKCQsdGhpcyk7bGV0e3BvczpaLGJ1ZmZlcjMyOkp9PXRoaXM7dGhpcy5maW5pc2hlZD0hMCxlMCh0aGlzLmJ1ZmZlci5zdWJhcnJheShaKSksZShKKSx0aGlzLmNvbXByZXNzKEosMCwhMCksZShKKTtsZXQgUT10MCgkKTt0aGlzLmdldCgpLmZvckVhY2goKFYsWSk9PlFbWV09elEoVikpfWRpZ2VzdCgpe2xldHtidWZmZXI6JCxvdXRwdXRMZW46Wn09dGhpczt0aGlzLmRpZ2VzdEludG8oJCk7bGV0IEo9JC5zbGljZSgwLFopO3JldHVybiB0aGlzLmRlc3Ryb3koKSxKfV9jbG9uZUludG8oJCl7bGV0e2J1ZmZlcjpaLGxlbmd0aDpKLGZpbmlzaGVkOlEsZGVzdHJveWVkOlYsb3V0cHV0TGVuOlkscG9zOlh9PXRoaXM7cmV0dXJuICR8fCgkPW5ldyB0aGlzLmNvbnN0cnVjdG9yKHtka0xlbjpZfSkpLCQuc2V0KC4uLnRoaXMuZ2V0KCkpLCQuYnVmZmVyLnNldChaKSwkLmRlc3Ryb3llZD1WLCQuZmluaXNoZWQ9USwkLmxlbmd0aD1KLCQucG9zPVgsJC5vdXRwdXRMZW49WSwkfWNsb25lKCl7cmV0dXJuIHRoaXMuX2Nsb25lSW50bygpfX1mdW5jdGlvbiBsWigkLFosSixRLFYsWSxYLFcseixLLEYsTixVLE8scSxJLEgsUCxDLFQpe2xldCBNPTA7Zm9yKGxldCBBPTA7QTxRO0ErKykoe2E6VixiOnosYzpVLGQ6SH09SDAoVix6LFUsSCxKW1orJFtNKytdXSkpLHthOlYsYjp6LGM6VSxkOkh9PU0wKFYseixVLEgsSltaKyRbTSsrXV0pLHthOlksYjpLLGM6TyxkOlB9PUgwKFksSyxPLFAsSltaKyRbTSsrXV0pLHthOlksYjpLLGM6TyxkOlB9PU0wKFksSyxPLFAsSltaKyRbTSsrXV0pLHthOlgsYjpGLGM6cSxkOkN9PUgwKFgsRixxLEMsSltaKyRbTSsrXV0pLHthOlgsYjpGLGM6cSxkOkN9PU0wKFgsRixxLEMsSltaKyRbTSsrXV0pLHthOlcsYjpOLGM6SSxkOlR9PUgwKFcsTixJLFQsSltaKyRbTSsrXV0pLHthOlcsYjpOLGM6SSxkOlR9PU0wKFcsTixJLFQsSltaKyRbTSsrXV0pLHthOlYsYjpLLGM6cSxkOlR9PUgwKFYsSyxxLFQsSltaKyRbTSsrXV0pLHthOlYsYjpLLGM6cSxkOlR9PU0wKFYsSyxxLFQsSltaKyRbTSsrXV0pLHthOlksYjpGLGM6SSxkOkh9PUgwKFksRixJLEgsSltaKyRbTSsrXV0pLHthOlksYjpGLGM6SSxkOkh9PU0wKFksRixJLEgsSltaKyRbTSsrXV0pLHthOlgsYjpOLGM6VSxkOlB9PUgwKFgsTixVLFAsSltaKyRbTSsrXV0pLHthOlgsYjpOLGM6VSxkOlB9PU0wKFgsTixVLFAsSltaKyRbTSsrXV0pLHthOlcsYjp6LGM6TyxkOkN9PUgwKFcseixPLEMsSltaKyRbTSsrXV0pLHthOlcsYjp6LGM6TyxkOkN9PU0wKFcseixPLEMsSltaKyRbTSsrXV0pO3JldHVybnt2MDpWLHYxOlksdjI6WCx2MzpXLHY0OnosdjU6Syx2NjpGLHY3Ok4sdjg6VSx2OTpPLHYxMDpxLHYxMTpJLHYxMjpILHYxMzpQLHYxNDpDLHYxNTpUfX12YXIgTzA9e0NIVU5LX1NUQVJUOjEsQ0hVTktfRU5EOjIsUEFSRU5UOjQsUk9PVDo4LEtFWUVEX0hBU0g6MTYsREVSSVZFX0tFWV9DT05URVhUOjMyLERFUklWRV9LRVlfTUFURVJJQUw6NjR9LEMwPUZRLnNsaWNlKCksUlE9KCgpPT57bGV0ICQ9QXJyYXkuZnJvbSh7bGVuZ3RoOjE2fSwoUSxWKT0+ViksWj0oUSk9PlsyLDYsMywxMCw3LDAsNCwxMywxLDExLDEyLDUsOSwxNCwxNSw4XS5tYXAoKFYpPT5RW1ZdKSxKPVtdO2ZvcihsZXQgUT0wLFY9JDtRPDc7USsrLFY9WihWKSlKLnB1c2goLi4uVik7cmV0dXJuIFVpbnQ4QXJyYXkuZnJvbShKKX0pKCk7Y2xhc3MgcFogZXh0ZW5kcyB1Wntjb25zdHJ1Y3RvcigkPXt9LFo9MCl7c3VwZXIoNjQsJC5ka0xlbj09PXZvaWQgMD8zMjokLmRrTGVuKTt0aGlzLmNodW5rUG9zPTAsdGhpcy5jaHVua3NEb25lPTAsdGhpcy5mbGFncz0wLHRoaXMuc3RhY2s9W10sdGhpcy5wb3NPdXQ9MCx0aGlzLmJ1ZmZlck91dDMyPW5ldyBVaW50MzJBcnJheSgxNiksdGhpcy5jaHVua091dD0wLHRoaXMuZW5hYmxlWE9GPSEwO2xldHtrZXk6Sixjb250ZXh0OlF9PSQsVj1RIT09dm9pZCAwO2lmKEohPT12b2lkIDApe2lmKFYpdGhyb3cgRXJyb3IoJ09ubHkgImtleSIgb3IgImNvbnRleHQiIGNhbiBiZSBzcGVjaWZpZWQgYXQgc2FtZSB0aW1lJyk7bGV0IFk9JCQoSikuc2xpY2UoKTtmMChZLDMyKSx0aGlzLklWPXQwKFkpLGUodGhpcy5JViksdGhpcy5mbGFncz1afE8wLktFWUVEX0hBU0h9ZWxzZSBpZihWKXtsZXQgWT0kJChRKSxYPW5ldyBwWih7ZGtMZW46MzJ9LE8wLkRFUklWRV9LRVlfQ09OVEVYVCkudXBkYXRlKFkpLmRpZ2VzdCgpO3RoaXMuSVY9dDAoWCksZSh0aGlzLklWKSx0aGlzLmZsYWdzPVp8TzAuREVSSVZFX0tFWV9NQVRFUklBTH1lbHNlIHRoaXMuSVY9QzAuc2xpY2UoKSx0aGlzLmZsYWdzPVo7dGhpcy5zdGF0ZT10aGlzLklWLnNsaWNlKCksdGhpcy5idWZmZXJPdXQ9WFEodGhpcy5idWZmZXJPdXQzMil9Z2V0KCl7cmV0dXJuW119c2V0KCl7fWIyQ29tcHJlc3MoJCxaLEosUT0wKXtsZXR7c3RhdGU6Vixwb3M6WX09dGhpcyx7aDpYLGw6V309aFooQmlnSW50KCQpLCEwKSx7djA6eix2MTpLLHYyOkYsdjM6Tix2NDpVLHY1Ok8sdjY6cSx2NzpJLHY4Okgsdjk6UCx2MTA6Qyx2MTE6VCx2MTI6TSx2MTM6QSx2MTQ6eCx2MTU6bX09bFooUlEsUSxKLDcsVlswXSxWWzFdLFZbMl0sVlszXSxWWzRdLFZbNV0sVls2XSxWWzddLEMwWzBdLEMwWzFdLEMwWzJdLEMwWzNdLFgsVyxZLFopO1ZbMF09el5ILFZbMV09S15QLFZbMl09Rl5DLFZbM109Tl5ULFZbNF09VV5NLFZbNV09T15BLFZbNl09cV54LFZbN109SV5tfWNvbXByZXNzKCQsWj0wLEo9ITEpe2xldCBRPXRoaXMuZmxhZ3M7aWYoIXRoaXMuY2h1bmtQb3MpUXw9TzAuQ0hVTktfU1RBUlQ7aWYodGhpcy5jaHVua1Bvcz09PTE1fHxKKVF8PU8wLkNIVU5LX0VORDtpZighSil0aGlzLnBvcz10aGlzLmJsb2NrTGVuO2lmKHRoaXMuYjJDb21wcmVzcyh0aGlzLmNodW5rc0RvbmUsUSwkLFopLHRoaXMuY2h1bmtQb3MrPTEsdGhpcy5jaHVua1Bvcz09PTE2fHxKKXtsZXQgVj10aGlzLnN0YXRlO3RoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpO2ZvcihsZXQgWSxYPXRoaXMuY2h1bmtzRG9uZSsxO0p8fCEoWCYxKTtYPj49MSl7aWYoIShZPXRoaXMuc3RhY2sucG9wKCkpKWJyZWFrO3RoaXMuYnVmZmVyMzIuc2V0KFksMCksdGhpcy5idWZmZXIzMi5zZXQoViw4KSx0aGlzLnBvcz10aGlzLmJsb2NrTGVuLHRoaXMuYjJDb21wcmVzcygwLHRoaXMuZmxhZ3N8TzAuUEFSRU5ULHRoaXMuYnVmZmVyMzIsMCksVj10aGlzLnN0YXRlLHRoaXMuc3RhdGU9dGhpcy5JVi5zbGljZSgpfXRoaXMuY2h1bmtzRG9uZSsrLHRoaXMuY2h1bmtQb3M9MCx0aGlzLnN0YWNrLnB1c2goVil9dGhpcy5wb3M9MH1fY2xvbmVJbnRvKCQpeyQ9c3VwZXIuX2Nsb25lSW50bygkKTtsZXR7SVY6WixmbGFnczpKLHN0YXRlOlEsY2h1bmtQb3M6Vixwb3NPdXQ6WSxjaHVua091dDpYLHN0YWNrOlcsY2h1bmtzRG9uZTp6fT10aGlzO3JldHVybiAkLnN0YXRlLnNldChRLnNsaWNlKCkpLCQuc3RhY2s9Vy5tYXAoKEspPT5VaW50MzJBcnJheS5mcm9tKEspKSwkLklWLnNldChaKSwkLmZsYWdzPUosJC5jaHVua1Bvcz1WLCQuY2h1bmtzRG9uZT16LCQucG9zT3V0PVksJC5jaHVua091dD1YLCQuZW5hYmxlWE9GPXRoaXMuZW5hYmxlWE9GLCQuYnVmZmVyT3V0MzIuc2V0KHRoaXMuYnVmZmVyT3V0MzIpLCR9ZGVzdHJveSgpe3RoaXMuZGVzdHJveWVkPSEwLGUwKHRoaXMuc3RhdGUsdGhpcy5idWZmZXIzMix0aGlzLklWLHRoaXMuYnVmZmVyT3V0MzIpLGUwKC4uLnRoaXMuc3RhY2spfWIyQ29tcHJlc3NPdXQoKXtsZXR7c3RhdGU6JCxwb3M6WixmbGFnczpKLGJ1ZmZlcjMyOlEsYnVmZmVyT3V0MzI6Vn09dGhpcyx7aDpZLGw6WH09aFooQmlnSW50KHRoaXMuY2h1bmtPdXQrKykpO2UoUSk7bGV0e3YwOlcsdjE6eix2MjpLLHYzOkYsdjQ6Tix2NTpVLHY2Ok8sdjc6cSx2ODpJLHY5OkgsdjEwOlAsdjExOkMsdjEyOlQsdjEzOk0sdjE0OkEsdjE1Onh9PWxaKFJRLDAsUSw3LCRbMF0sJFsxXSwkWzJdLCRbM10sJFs0XSwkWzVdLCRbNl0sJFs3XSxDMFswXSxDMFsxXSxDMFsyXSxDMFszXSxYLFksWixKKTtWWzBdPVdeSSxWWzFdPXpeSCxWWzJdPUteUCxWWzNdPUZeQyxWWzRdPU5eVCxWWzVdPVVeTSxWWzZdPU9eQSxWWzddPXFeeCxWWzhdPSRbMF1eSSxWWzldPSRbMV1eSCxWWzEwXT0kWzJdXlAsVlsxMV09JFszXV5DLFZbMTJdPSRbNF1eVCxWWzEzXT0kWzVdXk0sVlsxNF09JFs2XV5BLFZbMTVdPSRbN11eeCxlKFEpLGUoViksdGhpcy5wb3NPdXQ9MH1maW5pc2goKXtpZih0aGlzLmZpbmlzaGVkKXJldHVybjt0aGlzLmZpbmlzaGVkPSEwLGUwKHRoaXMuYnVmZmVyLnN1YmFycmF5KHRoaXMucG9zKSk7bGV0ICQ9dGhpcy5mbGFnc3xPMC5ST09UO2lmKHRoaXMuc3RhY2subGVuZ3RoKSR8PU8wLlBBUkVOVCxlKHRoaXMuYnVmZmVyMzIpLHRoaXMuY29tcHJlc3ModGhpcy5idWZmZXIzMiwwLCEwKSxlKHRoaXMuYnVmZmVyMzIpLHRoaXMuY2h1bmtzRG9uZT0wLHRoaXMucG9zPXRoaXMuYmxvY2tMZW47ZWxzZSAkfD0oIXRoaXMuY2h1bmtQb3M/TzAuQ0hVTktfU1RBUlQ6MCl8TzAuQ0hVTktfRU5EO3RoaXMuZmxhZ3M9JCx0aGlzLmIyQ29tcHJlc3NPdXQoKX13cml0ZUludG8oJCl7TiQodGhpcywhMSksZjAoJCksdGhpcy5maW5pc2goKTtsZXR7YmxvY2tMZW46WixidWZmZXJPdXQ6Sn09dGhpcztmb3IobGV0IFE9MCxWPSQubGVuZ3RoO1E8Vjspe2lmKHRoaXMucG9zT3V0Pj1aKXRoaXMuYjJDb21wcmVzc091dCgpO2xldCBZPU1hdGgubWluKFotdGhpcy5wb3NPdXQsVi1RKTskLnNldChKLnN1YmFycmF5KHRoaXMucG9zT3V0LHRoaXMucG9zT3V0K1kpLFEpLHRoaXMucG9zT3V0Kz1ZLFErPVl9cmV0dXJuICR9eG9mSW50bygkKXtpZighdGhpcy5lbmFibGVYT0YpdGhyb3cgRXJyb3IoIlhPRiBpcyBub3QgcG9zc2libGUgYWZ0ZXIgZGlnZXN0IGNhbGwiKTtyZXR1cm4gdGhpcy53cml0ZUludG8oJCl9eG9mKCQpe3JldHVybiBGJCgkKSx0aGlzLnhvZkludG8obmV3IFVpbnQ4QXJyYXkoJCkpfWRpZ2VzdEludG8oJCl7aWYobCQoJCx0aGlzKSx0aGlzLmZpbmlzaGVkKXRocm93IEVycm9yKCJkaWdlc3QoKSB3YXMgYWxyZWFkeSBjYWxsZWQiKTtyZXR1cm4gdGhpcy5lbmFibGVYT0Y9ITEsdGhpcy53cml0ZUludG8oJCksdGhpcy5kZXN0cm95KCksJH1kaWdlc3QoKXtyZXR1cm4gdGhpcy5kaWdlc3RJbnRvKG5ldyBVaW50OEFycmF5KHRoaXMub3V0cHV0TGVuKSl9fXZhciBVUT1LUSgoJCk9Pm5ldyBwWigkKSk7dmFyIG5aPW5ldyBVaW50OEFycmF5KFs0OCw0NiwyLDEsMCw0OCw1LDYsMyw0MywxMDEsMTEyLDQsMzQsNCwzMl0pO2Z1bmN0aW9uIE9RKCQpe2xldCBaPW5ldyBVaW50OEFycmF5KG5aLmxlbmd0aCszMik7cmV0dXJuIFouc2V0KG5aKSxaLnNldCgkLnN1YmFycmF5KDAsMzIpLG5aLmxlbmd0aCksWn1mdW5jdGlvbiBxUSgkKXtyZXR1cm4gdHlwZW9mICQ9PT0ic3RyaW5nIj9uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoJCk6JH1mdW5jdGlvbiBaJCgkKXtsZXQgWj1uZXcgQXJyYXlCdWZmZXIoJC5ieXRlTGVuZ3RoKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoWikuc2V0KCQpLFp9Y2xhc3MgY1p7dmVyaWZ5S2V5cz1uZXcgTWFwO3NpZ25LZXlzPW5ldyBNYXA7YXN5bmMgZ2VuUmFuZG9tQnl0ZXMoJCl7cmV0dXJuIGgkKCQpfWFzeW5jIGdlbjI1NkJpdFNlY3VyZVJhbmRvbVNlZWQoKXtyZXR1cm4gaCQoMzIpfWFzeW5jIGVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoJCxaKXtsZXQgSj1oJCgyNCksVj15WihaLEopLmVuY3J5cHQoJCk7cmV0dXJuIG5ldyBVaW50OEFycmF5KFsuLi5KLC4uLlZdKX1hc3luYyBkZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKCQsWil7bGV0IEo9JC5zbGljZSgwLDI0KSxRPSQuc2xpY2UoMjQpO3JldHVybiB5WihaLEopLmRlY3J5cHQoUSl9YXN5bmMgZGVyaXZlRWQyNTUxOUtleVBhaXIoJCl7bGV0IFo9JCxKPU9RKFopLFE9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicGtjczgiLFokKEopLHtuYW1lOiJFZDI1NTE5In0sITAsWyJzaWduIl0pLFY9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgiandrIixRKTtpZih0eXBlb2YgVi54IT09InN0cmluZyIpdGhyb3cgRXJyb3IoIkVkMjU1MTkgSldLIG1pc3NpbmcgeCIpO2xldCBZPWF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS5pbXBvcnRLZXkoImp3ayIse2t0eToiT0tQIixjcnY6IkVkMjU1MTkiLHg6Vi54fSx7bmFtZToiRWQyNTUxOSJ9LCEwLFsidmVyaWZ5Il0pLFg9bmV3IFVpbnQ4QXJyYXkoYXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmV4cG9ydEtleSgicmF3IixZKSksVz1uZXcgVWludDhBcnJheSg2NCk7cmV0dXJuIFcuc2V0KFosMCksVy5zZXQoWCwzMiksdGhpcy5zaWduS2V5cy5zZXQoTjAoWiksUSksdGhpcy52ZXJpZnlLZXlzLnNldChOMChYKSxZKSx7a2V5VHlwZToiZWQyNTUxOSIscHJpdmF0ZUtleTpXLHB1YmxpY0tleTpYfX1hc3luYyBpbXBvcnRTaWduS2V5KCQpe2xldCBaPSQuc3ViYXJyYXkoMCwzMiksSj1OMChaKSxRPXRoaXMuc2lnbktleXMuZ2V0KEopO2lmKFEpcmV0dXJuIFE7bGV0IFY9T1EoWiksWT1hd2FpdCBnbG9iYWxUaGlzLmNyeXB0by5zdWJ0bGUuaW1wb3J0S2V5KCJwa2NzOCIsWiQoVikse25hbWU6IkVkMjU1MTkifSwhMSxbInNpZ24iXSk7cmV0dXJuIHRoaXMuc2lnbktleXMuc2V0KEosWSksWX1hc3luYyBpbXBvcnRWZXJpZnlLZXkoJCl7bGV0IFo9TjAoJCksSj10aGlzLnZlcmlmeUtleXMuZ2V0KFopO2lmKEopcmV0dXJuIEo7bGV0IFE9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLmltcG9ydEtleSgicmF3IixaJCgkKSx7bmFtZToiRWQyNTUxOSJ9LCExLFsidmVyaWZ5Il0pO3JldHVybiB0aGlzLnZlcmlmeUtleXMuc2V0KFosUSksUX1hc3luYyBzaWduRWQyNTUxOSgkLFope2xldCBKPXFRKCQpLFE9YXdhaXQgdGhpcy5pbXBvcnRTaWduS2V5KFopLFY9YXdhaXQgZ2xvYmFsVGhpcy5jcnlwdG8uc3VidGxlLnNpZ24oe25hbWU6IkVkMjU1MTkifSxRLFokKEopKTtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoVil9YXN5bmMgY2hlY2tTaWdFZDI1NTE5KCQsWixKKXtsZXQgUT1xUShaKTt0cnl7bGV0IFY9YXdhaXQgdGhpcy5pbXBvcnRWZXJpZnlLZXkoSik7cmV0dXJuIGF3YWl0IGdsb2JhbFRoaXMuY3J5cHRvLnN1YnRsZS52ZXJpZnkoe25hbWU6IkVkMjU1MTkifSxWLFokKCQpLFokKFEpKX1jYXRjaHtyZXR1cm4hMX19YXN5bmMgYmxha2UzKCQpe3JldHVybiBVUSgkKX19dmFyIGJWPW5ldyBjWixVJD1iVjt2YXIgazA9e2VuY29kZSgkLFope2xldCBKPSQud3JpdGVWYXJTdHJpbmcoWi5oYW5kbGUpO2lmKEohPT0wKXJldHVybiBKO2xldCBRPSQud3JpdGVWYXJTdHJpbmcoWi5sYWJlbCk7aWYoUSE9PTApcmV0dXJuIFE7cmV0dXJuICQud3JpdGVWYXJJbnQoWi5pZHg/PzApfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFyU3RyaW5nKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsVl09JC5yZWFkVmFyU3RyaW5nKCk7aWYoViE9PTApcmV0dXJuIEcoVik7bGV0W1ksWF09JC5yZWFkVmFySW50KCk7aWYoWCE9PTApcmV0dXJuIEcoWCk7cmV0dXJuIFIoe2hhbmRsZTpaLGxhYmVsOlEsaWR4Oll9KX19O3ZhciBuJD0xLGRaPXtlbmNvZGUoJCxaKXtpZihaLnYhPT1uJClyZXR1cm4gMTA7bGV0WyxKXT10KFoubWFzdGVyU2VlZCk7aWYoSiE9PTApcmV0dXJuIEo7bGV0IFE9JC53cml0ZVZhckludChaLnYpO2lmKFEhPT0wKXJldHVybiBROyQud3JpdGVCeXRlcyhaLm1hc3RlclNlZWQpO2xldCBWPSQud3JpdGVWYXJJbnQoWi5ob3N0cy5sZW5ndGgpO2lmKFYhPT0wKXJldHVybiBWO2ZvcihsZXQgWSBvZiBaLmhvc3RzKXtsZXQgWD0kLndyaXRlU3RydWN0KGswLFkpO2lmKFghPT0wKXJldHVybiBYfXJldHVybiAwfSxkZWNvZGUoJCl7bGV0W1osSl09JC5yZWFkVmFySW50KCk7aWYoSiE9PTApcmV0dXJuIEcoSik7aWYoWiE9PW4kKXJldHVybiBHKDE0KTtsZXRbUSxWXT0kLnJlYWRCeXRlcyhSMCk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoUT09PXZvaWQgMClyZXR1cm4gRygxNCk7bGV0W1ksWF09dChRKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbVyx6XT0kLnJlYWRWYXJJbnQoKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwfHxXPDApcmV0dXJuIEcoMTApO2xldCBLPVtdO2ZvcihsZXQgRj0wO0Y8VztGKyspe2xldFtOLFVdPSQucmVhZFN0cnVjdChrMCk7aWYoVSE9PTApcmV0dXJuIEcoVSk7aWYoTj09PXZvaWQgMClyZXR1cm4gRygxNCk7Sy5wdXNoKE4pfXJldHVybiBSKHt2Om4kLG1hc3RlclNlZWQ6WSxob3N0czpLfSl9fTtmdW5jdGlvbiBJUSgkLFope2xldFtKLFFdPXQoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxMCk7bGV0W1YsWV09dChKLnNsaWNlKCkpO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMTApO3JldHVybiBSKHt2Om4kLG1hc3RlclNlZWQ6Vixob3N0czpaLm1hcCgoWCk9Pih7aGFuZGxlOlguaGFuZGxlLGxhYmVsOlgubGFiZWwsaWR4OlguaWR4Pz8wfSkpfSl9dmFyIHJaPXtlbmNvZGUoJCxaKXtsZXRbLEpdPXQoWi5tYXN0ZXJTZWVkKTtpZihKIT09MClyZXR1cm4gSjskLndyaXRlQnl0ZXMoWi5tYXN0ZXJTZWVkKTtsZXQgUT0kLndyaXRlVmFySW50KFouaG9zdHMubGVuZ3RoKTtpZihRIT09MClyZXR1cm4gUTtmb3IobGV0IFYgb2YgWi5ob3N0cyl7bGV0IFk9JC53cml0ZVN0cnVjdChrMCxWKTtpZihZIT09MClyZXR1cm4gWX1yZXR1cm4gMH0sZGVjb2RlKCQpe2xldFtaLEpdPSQucmVhZEJ5dGVzKFIwKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbUSxWXT10KFopO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldFtZLFhdPSQucmVhZFZhckludCgpO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFk9PT12b2lkIDB8fFk8MClyZXR1cm4gRygxMCk7bGV0IFc9W107Zm9yKGxldCB6PTA7ejxZO3orKyl7bGV0W0ssRl09JC5yZWFkU3RydWN0KGswKTtpZihGIT09MClyZXR1cm4gRyhGKTtpZihLPT09dm9pZCAwKXJldHVybiBHKDE0KTtXLnB1c2goSyl9cmV0dXJuIFIoe21hc3RlclNlZWQ6USxob3N0czpXfSl9fTtmdW5jdGlvbiBQMCgkKXtsZXQgWj1uZXcgVWludDhBcnJheSgkKTtpZigkPjApY3J5cHRvLmdldFJhbmRvbVZhbHVlcyhaKTtyZXR1cm4gWn12YXIgQjA9MzIseVY9LTcsaVY9LTgsaFY9LTI1NyxjJD1be3R5cGU6InB1YmxpYy1rZXkiLGFsZzp5Vn0se3R5cGU6InB1YmxpYy1rZXkiLGFsZzppVn0se3R5cGU6InB1YmxpYy1rZXkiLGFsZzpoVn1dO2Z1bmN0aW9uIHVWKCQpe3JldHVybiAkLnRyaW0oKS50b0xvd2VyQ2FzZSgpLnJlcGxhY2UoL1wuJC8sIiIpfHwibG9jYWxob3N0In1mdW5jdGlvbiBFMCgkKXtsZXQgWj1uZXcgVWludDhBcnJheSgkLmJ5dGVMZW5ndGgpO3JldHVybiBaLnNldCgkKSxafWZ1bmN0aW9uIG0wKCQpe2lmKCQ/LnJwSWQhPT12b2lkIDApcmV0dXJuIFIoJC5ycElkKTtpZih0eXBlb2YgbG9jYXRpb24+InUiKXJldHVybiBHKDkpO3JldHVybiBSKHVWKGxvY2F0aW9uLmhvc3RuYW1lKSl9ZnVuY3Rpb24gZzAoKXtpZih0eXBlb2YgbmF2aWdhdG9yPiJ1Inx8IW5hdmlnYXRvci5jcmVkZW50aWFsc3x8dHlwZW9mIFB1YmxpY0tleUNyZWRlbnRpYWw+InUiKXJldHVybiAyNDtyZXR1cm4gMH1mdW5jdGlvbiBTMCgkKXtpZigkPT09bnVsbHx8JC50eXBlIT09InB1YmxpYy1rZXkifHwhKCJyYXdJZCJpbiAkKXx8dHlwZW9mICQuZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cyE9PSJmdW5jdGlvbiIpcmV0dXJuIEcoMjcpO3JldHVybiBSKCQpfWFzeW5jIGZ1bmN0aW9uIEhRKCQpe2xldCBaPWcwKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W0osUV09bTAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgVj0kPy51c2VyTmFtZT8/ImRpcGxvbWF0aWMtc2VlZCIsWT17cmVzaWRlbnRLZXk6InJlcXVpcmVkIixyZXF1aXJlUmVzaWRlbnRLZXk6ITAsdXNlclZlcmlmaWNhdGlvbjoicmVxdWlyZWQifTtpZigkPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudCE9PXZvaWQgMClZLmF1dGhlbnRpY2F0b3JBdHRhY2htZW50PSQuYXV0aGVudGljYXRvckF0dGFjaG1lbnQ7bGV0IFg9e2xhcmdlQmxvYjp7c3VwcG9ydDoicmVxdWlyZWQifX0sVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpQMChCMCkscnA6e2lkOkosbmFtZTokPy5ycE5hbWU/PyJESVBMT01BVElDIn0sdXNlcjp7aWQ6UDAoMTYpLG5hbWU6VixkaXNwbGF5TmFtZTpWfSxwdWJLZXlDcmVkUGFyYW1zOmMkLGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246WSxleHRlbnNpb25zOlh9fSl9Y2F0Y2h7cmV0dXJuIEcoMjQpfWxldFt6LEtdPVMwKFcpO2lmKEshPT0wKXJldHVybiBHKEspO2lmKHo9PT12b2lkIDApcmV0dXJuIEcoMjcpO2lmKHouZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLmxhcmdlQmxvYj8uc3VwcG9ydGVkIT09ITApcmV0dXJuIEcoMjQpO3JldHVybiBSKG5ldyBVaW50OEFycmF5KHoucmF3SWQpKX1hc3luYyBmdW5jdGlvbiBvWigkLFosSil7bGV0IFE9ZzAoKTtpZihRIT09MClyZXR1cm4gUTtsZXRbVixZXT1tMChKKTtpZihZIT09MClyZXR1cm4gWTtpZihWPT09dm9pZCAwKXJldHVybiA5O2xldCBYPXtsYXJnZUJsb2I6e3dyaXRlOkUwKFopfX0sVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpQMChCMCkscnBJZDpWLGFsbG93Q3JlZGVudGlhbHM6W3t0eXBlOiJwdWJsaWMta2V5IixpZDpFMCgkKX1dLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixleHRlbnNpb25zOlh9fSl9Y2F0Y2h7cmV0dXJuIDI0fWxldFt6LEtdPVMwKFcpO2lmKEshPT0wKXJldHVybiBLO2lmKHo9PT12b2lkIDApcmV0dXJuIDI3O2lmKHouZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLmxhcmdlQmxvYj8ud3JpdHRlbiE9PSEwKXJldHVybiAyNDtyZXR1cm4gMH1hc3luYyBmdW5jdGlvbiBNUSgkLFope2xldCBKPWcwKCk7aWYoSiE9PTApcmV0dXJuIEcoSik7bGV0W1EsVl09bTAoWik7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoUT09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgWT17bGFyZ2VCbG9iOntyZWFkOiEwfX0sWDt0cnl7bGV0IE49e2NoYWxsZW5nZTpQMChCMCkscnBJZDpRLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixleHRlbnNpb25zOll9O2lmKCQhPT12b2lkIDApTi5hbGxvd0NyZWRlbnRpYWxzPVt7dHlwZToicHVibGljLWtleSIsaWQ6RTAoJCl9XTtYPWF3YWl0IG5hdmlnYXRvci5jcmVkZW50aWFscy5nZXQoe3B1YmxpY0tleTpOfSl9Y2F0Y2h7cmV0dXJuIEcoMjQpfWxldFtXLHpdPVMwKFgpO2lmKHohPT0wKXJldHVybiBHKHopO2lmKFc9PT12b2lkIDApcmV0dXJuIEcoMjcpO2xldCBGPVcuZ2V0Q2xpZW50RXh0ZW5zaW9uUmVzdWx0cygpLmxhcmdlQmxvYj8uYmxvYjtpZihGPT09dm9pZCAwKXJldHVybiBHKDcpO3JldHVybiBSKHtibG9iOm5ldyBVaW50OEFycmF5KEYpLGNyZWRJZDpuZXcgVWludDhBcnJheShXLnJhd0lkKX0pfXZhciBkJD1uZXcgVGV4dEVuY29kZXIoKS5lbmNvZGUoImRpcGxvbWF0aWMucHJmLnYxIiksYVo9MzI7YXN5bmMgZnVuY3Rpb24gQ1EoJCl7bGV0IFo9ZzAoKTtpZihaIT09MClyZXR1cm4gRyhaKTtsZXRbSixRXT1tMCgkKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDkpO2xldCBWPSQ/LnVzZXJOYW1lPz8iZGlwbG9tYXRpYy1wcmYiLFk9e3Jlc2lkZW50S2V5OiJyZXF1aXJlZCIscmVxdWlyZVJlc2lkZW50S2V5OiEwLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixhdXRoZW50aWNhdG9yQXR0YWNobWVudDokPy5hdXRoZW50aWNhdG9yQXR0YWNobWVudD8/InBsYXRmb3JtIn0sWDt0cnl7WD1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuY3JlYXRlKHtwdWJsaWNLZXk6e2NoYWxsZW5nZTpQMChCMCkscnA6e2lkOkosbmFtZTokPy5ycE5hbWU/PyJESVBMT01BVElDIn0sdXNlcjp7aWQ6UDAoMTYpLG5hbWU6VixkaXNwbGF5TmFtZTpWfSxwdWJLZXlDcmVkUGFyYW1zOmMkLGF1dGhlbnRpY2F0b3JTZWxlY3Rpb246WSxleHRlbnNpb25zOntwcmY6e319fX0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbVyx6XT1TMChYKTtpZih6IT09MClyZXR1cm4gRyh6KTtpZihXPT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgSz1XLmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKTtyZXR1cm4gUih7Y3JlZElkOm5ldyBVaW50OEFycmF5KFcucmF3SWQpLHByZkVuYWJsZWQ6Sy5wcmY/LmVuYWJsZWQ9PT0hMH0pfWFzeW5jIGZ1bmN0aW9uIE8kKCQpe2xldCBaPWcwKCk7aWYoWiE9PTApcmV0dXJuIEcoWik7bGV0W0osUV09bTAoJCk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRyg5KTtsZXQgVj0kPy5zYWx0Pz9kJCxZPUUwKFYpLFg9e2NoYWxsZW5nZTpQMChCMCkscnBJZDpKLHVzZXJWZXJpZmljYXRpb246InJlcXVpcmVkIixleHRlbnNpb25zOntwcmY6e2V2YWw6e2ZpcnN0Oll9fX19O2lmKCQ/LmNyZWRJZCE9PXZvaWQgMClYLmFsbG93Q3JlZGVudGlhbHM9W3t0eXBlOiJwdWJsaWMta2V5IixpZDpFMCgkLmNyZWRJZCl9XTtsZXQgVzt0cnl7Vz1hd2FpdCBuYXZpZ2F0b3IuY3JlZGVudGlhbHMuZ2V0KHtwdWJsaWNLZXk6WH0pfWNhdGNoe3JldHVybiBHKDI0KX1sZXRbeixLXT1TMChXKTtpZihLIT09MClyZXR1cm4gRyhLKTtpZih6PT09dm9pZCAwKXJldHVybiBHKDI3KTtsZXQgRj16LmdldENsaWVudEV4dGVuc2lvblJlc3VsdHMoKS5wcmY/LnJlc3VsdHM7aWYoRj8uZmlyc3Q9PT12b2lkIDApcmV0dXJuIEcoNyk7bGV0IE49Ri5maXJzdCxVPU4gaW5zdGFuY2VvZiBBcnJheUJ1ZmZlcj9uZXcgVWludDhBcnJheShOKTpuZXcgVWludDhBcnJheShOLmJ1ZmZlcixOLmJ5dGVPZmZzZXQsTi5ieXRlTGVuZ3RoKSxPPVUuYnl0ZUxlbmd0aD49YVo/VS5zbGljZSgwLGFaKTpVO2lmKE8uYnl0ZUxlbmd0aCE9PWFaKXJldHVybiBHKDI3KTtyZXR1cm4gUih7cHJmOk8sY3JlZElkOm5ldyBVaW50OEFycmF5KHoucmF3SWQpfSl9dmFyIHIkPSIiO3ZhciBvJDtmdW5jdGlvbiBwVigpe2lmKHR5cGVvZiByJCE9PSJzdHJpbmcifHxyJC5sZW5ndGg9PT0wKXRocm93IEVycm9yKCJbRElQTE9NQVRJQ10gd29ya2VyIHNvdXJjZSBub3QgZW1iZWRkZWQ7IHJ1biBwa2cgYnVpbGQgYmVmb3JlIHNwYXduIik7cmV0dXJuIGF0b2IociQpfWZ1bmN0aW9uIG5WKCl7aWYobyQhPT12b2lkIDApcmV0dXJuIG8kO2xldCAkPW5ldyBCbG9iKFtwVigpXSx7dHlwZToidGV4dC9qYXZhc2NyaXB0In0pO3JldHVybiBvJD1VUkwuY3JlYXRlT2JqZWN0VVJMKCQpLG8kfWZ1bmN0aW9uIFBRKCl7aWYodHlwZW9mIFdvcmtlcj4idSIpdGhyb3cgRXJyb3IoIltESVBMT01BVElDXSBXb3JrZXIgQVBJIHVuYXZhaWxhYmxlOyBjYW5ub3Qgc3Bhd24gc3luYyB3b3JrZXIiKTtyZXR1cm4gbmV3IFdvcmtlcihuVigpLHt0eXBlOiJtb2R1bGUifSl9dmFyIGNWPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgiZGlwbG9tYXRpYy53cmFwLnYxIiksZFY9MzIsclY9MTY7Y2xhc3MgJDB7I0o7IyQ7Y29uc3RydWN0b3IoJCxaKXt0aGlzLiNKPSQsdGhpcy4jJD1afXN0YXRpYyBhc3luYyBmcm9tUmFuZG9tKCQpe2xldCBaPWF3YWl0ICQuZ2VuMjU2Qml0U2VjdXJlUmFuZG9tU2VlZCgpLFtKLFFdPXQoWik7aWYoUSE9PTB8fEo9PT12b2lkIDApdGhyb3cgRXJyb3IoYGVuY2xhdmU6IGludmFsaWQgcmFuZG9tIHNlZWQgKCR7UX0pYCk7cmV0dXJuIG5ldyAkMChKLCQpfXN0YXRpYyBmcm9tQnl0ZXMoJCxaKXtsZXRbSixRXT10KFopO2lmKFEhPT0wKXJldHVybiBHKFEpO2lmKEo9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldFtWLFldPXQoSi5zbGljZSgpKTtpZihZIT09MClyZXR1cm4gRyhZKTtpZihWPT09dm9pZCAwKXJldHVybiBHKDEwKTtyZXR1cm4gUihuZXcgJDAoViwkKSl9YXN5bmMgc2VhbFdpdGhQYXNza2V5KCQpe2xldCBaPSQ/LnNhbHQ/P2QkLEo9JD8uY3JlZElkO2lmKEo9PT12b2lkIDAmJiQ/LmNyZWF0ZUNyZWRJZk5lZWRlZD09PSEwKXtsZXRbWSxYXT1hd2FpdCBDUSh7cnBJZDokPy5ycElkLHJwTmFtZTokPy5ycE5hbWUsdXNlck5hbWU6JD8udXNlck5hbWU/PyJkaXBsb21hdGljLXByZiJ9KTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDI0KTtpZighWS5wcmZFbmFibGVkKXJldHVybiBHKDI0KTtKPVkuY3JlZElkfWxldFtRLFZdPWF3YWl0IE8kKHtycElkOiQ/LnJwSWQscnBOYW1lOiQ/LnJwTmFtZSxjcmVkSWQ6SixzYWx0Olp9KTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtsZXRbWSxYXT1hd2FpdCB0aGlzLiNaKFEucHJmKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gUih7c2VhbGVkTWFzdGVyOlksc2FsdDpaLnNsaWNlKCksY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXN0YXRpYyBhc3luYyB1bnNlYWxXaXRoUGFzc2tleSgkLFosSil7bGV0W1EsVl09YXdhaXQgTyQoe3JwSWQ6Si5ycElkLHJwTmFtZTpKLnJwTmFtZSxjcmVkSWQ6Si5jcmVkSWQsc2FsdDpKLnNhbHR9KTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtyZXR1cm4gYXdhaXQgJDAuI1YoJCxaLFEucHJmKX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fWFzeW5jIHBlcnNpc3RUb0xhcmdlQmxvYigkPVtdLFope2xldCBKPVo/LmNyZWRJZDtpZihKPT09dm9pZCAwKXtsZXRbWSxYXT1hd2FpdCBIUShaKTtpZihYIT09MClyZXR1cm4gRyhYKTtpZihZPT09dm9pZCAwKXJldHVybiBHKDI0KTtKPVl9bGV0W1EsVl09dGhpcy4jUSgkKTtpZihWIT09MClyZXR1cm4gRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBHKDEyKTt0cnl7bGV0IFk9YXdhaXQgb1ooSixRLFopO2lmKFkhPT0wKXJldHVybiBHKFkpO3JldHVybiBSKEopfWZpbmFsbHl7US5maWxsKDApfX1zdGF0aWMgYXN5bmMgZnJvbUxhcmdlQmxvYigkLFope2xldFtKLFFdPWF3YWl0IE1RKFo/LmNyZWRJZCxaKTtpZihRIT09MClyZXR1cm4gRyhRKTtpZihKPT09dm9pZCAwKXJldHVybiBHKDcpO3RyeXtyZXR1cm4gJDAuI1coJCxKLmJsb2IsSi5jcmVkSWQpfWZpbmFsbHl7Si5ibG9iLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBjbGVhckxhcmdlQmxvYigkLFope3JldHVybiBvWigkLG5ldyBVaW50OEFycmF5KFIwKSxaKX1hc3luYyBzZWFsUGFpclBhY2thZ2VCb2R5KCQsWil7bGV0IEo9Wj8uc2FsdD8/ZCQsW1EsVl09YXdhaXQgTyQoe3JwSWQ6Wj8ucnBJZCxycE5hbWU6Wj8ucnBOYW1lLGNyZWRJZDpaPy5jcmVkSWQsc2FsdDpKfSk7aWYoViE9PTApcmV0dXJuIEcoVik7aWYoUT09PXZvaWQgMClyZXR1cm4gRyg3KTt0cnl7bGV0W1ksWF09YXdhaXQgYSQodGhpcy4jJCxRLnByZik7aWYoWCE9PTApcmV0dXJuIEcoWCk7aWYoWT09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0W1csel09dCh0aGlzLiNKLnNsaWNlKCkpO2lmKHohPT0wKXJldHVybiBHKHopO2lmKFc9PT12b2lkIDApcmV0dXJuIEcoMTApO2xldCBLPXttYXN0ZXJTZWVkOlcsaG9zdHM6JC5tYXAoKHEpPT4oe2hhbmRsZTpxLmhhbmRsZSxsYWJlbDpxLmxhYmVsLGlkeDpxLmlkeD8/MH0pKX0sRj1uZXcgUyxOPUYud3JpdGVTdHJ1Y3QoclosSyk7aWYoTiE9PTApcmV0dXJuIFcuZmlsbCgwKSxHKE4pO2xldCBVPUYucmVzdWx0KCk7Vy5maWxsKDApO2xldCBPO3RyeXtPPWF3YWl0IHRoaXMuIyQuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChVLFkpfWNhdGNoe3JldHVybiBVLmZpbGwoMCksRygxMil9cmV0dXJuIFUuZmlsbCgwKSxSKHtib2R5Ok8sc2FsdDpKLnNsaWNlKCksY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXN0YXRpYyBhc3luYyBvcGVuUGFpclBhY2thZ2VCb2R5KCQsWixKKXtsZXRbUSxWXT1hd2FpdCBPJCh7cnBJZDpKLnJwSWQscnBOYW1lOkoucnBOYW1lLGNyZWRJZDpKLmNyZWRJZCxzYWx0Okouc2FsdH0pO2lmKFYhPT0wKXJldHVybiBHKFYpO2lmKFE9PT12b2lkIDApcmV0dXJuIEcoNyk7dHJ5e2xldFtZLFhdPWF3YWl0IGEkKCQsUS5wcmYpO2lmKFghPT0wKXJldHVybiBHKFgpO2lmKFk9PT12b2lkIDApcmV0dXJuIEcoMTIpO2xldCBXO3RyeXtXPWF3YWl0ICQuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChaLFkpfWNhdGNoe3JldHVybiBHKDIwKX1sZXQgej1uZXcgZyhXKSxbSyxGXT16LnJlYWRTdHJ1Y3QoclopO2lmKFcuZmlsbCgwKSxGIT09MClyZXR1cm4gRyhGKTtpZihLPT09dm9pZCAwKXJldHVybiBHKDE0KTtsZXRbTixVXT0kMC5mcm9tQnl0ZXMoJCxLLm1hc3RlclNlZWQpO2lmKEsubWFzdGVyU2VlZC5maWxsKDApLFUhPT0wKXJldHVybiBHKFUpO2lmKE49PT12b2lkIDApcmV0dXJuIEcoMTIpO2xldFtPLHFdPWF3YWl0IE4uI1ooUS5wcmYpO2lmKHEhPT0wKXJldHVybiBHKHEpO2lmKE89PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBSKHtlbmNsYXZlOk4saG9zdHM6Sy5ob3N0cy5tYXAoKEkpPT4oey4uLkl9KSksc2VhbGVkTWFzdGVyOk8sY3JlZElkOlEuY3JlZElkLnNsaWNlKCl9KX1maW5hbGx5e1EucHJmLmZpbGwoMCl9fXNwYXduU3luY1dvcmtlcigkKXtsZXQgWj1QUSgpLEo9dGhpcy4jSi5zbGljZSgpO3JldHVybiBaLnBvc3RNZXNzYWdlKHtpZDokLmlkLG9wOiJzZXRTZWVkIixzZWVkOkoscGVyc2lzdDokLnBlcnNpc3R9LFtKLmJ1ZmZlcl0pLFp9ZGVyaXZlQ2lwaGVyKCQsWil7bGV0IEo9JC5zbGljZSgpLFE9KFgpPT50aGlzLiNHKEosWCksVj0oWCk9PnRoaXMuI3ooSixYKTtyZXR1cm57ZW5jcnlwdDpPYmplY3QuZnJlZXplKHtlbmNyeXB0OlF9KSxkZWNyeXB0Ok9iamVjdC5mcmVlemUoe2RlY3J5cHQ6Vn0pLGJvdGg6T2JqZWN0LmZyZWV6ZSh7ZW5jcnlwdDpRLGRlY3J5cHQ6Vn0pfVtaXX1hc3luYyBkZXJpdmVJZGVudGl0eSgkLFo9MCl7bGV0IEo9JCxRPVosVj1hd2FpdCB0aGlzLiNYKEosUSk7cmV0dXJuIE9iamVjdC5mcmVlemUoe3B1YmxpY0tleTpWLnB1YmxpY0tleSxzaWduOihZKT0+dGhpcy4jRihKLFEsWSksa2RtRm9yOihZKT0+dGhpcy4jTihKLFEsWSl9KX1hc3luYyNaKCQpe2xldFtaLEpdPWF3YWl0IGEkKHRoaXMuIyQsJCk7aWYoSiE9PTApcmV0dXJuIEcoSik7aWYoWj09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBRPWF3YWl0IHRoaXMuIyQuZW5jcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZCh0aGlzLiNKLFopO3JldHVybiBqMChRKX1jYXRjaHtyZXR1cm4gRygxMil9fXN0YXRpYyBhc3luYyNWKCQsWixKKXtsZXRbLFFdPWowKFopO2lmKFEhPT0wKXJldHVybiBHKFEpO2xldFtWLFldPWF3YWl0IGEkKCQsSik7aWYoWSE9PTApcmV0dXJuIEcoWSk7aWYoVj09PXZvaWQgMClyZXR1cm4gRygxMik7dHJ5e2xldCBYPWF3YWl0ICQuZGVjcnlwdFhTYWxzYTIwUG9seTEzMDVDb21iaW5lZChaLFYpO3JldHVybiAkMC5mcm9tQnl0ZXMoJCxYKX1jYXRjaHtyZXR1cm4gRygyMCl9fSNRKCQpe2xldFtaLEpdPXQodGhpcy4jSi5zbGljZSgpKTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDEwKTtsZXRbUSxWXT1JUShaLCQpO2lmKFYhPT0wKXJldHVybiBaLmZpbGwoMCksRyhWKTtpZihRPT09dm9pZCAwKXJldHVybiBaLmZpbGwoMCksRygxMik7Wi5maWxsKDApO2xldCBZPW5ldyBTLFg9WS53cml0ZVN0cnVjdChkWixRKTtpZihRLm1hc3RlclNlZWQuZmlsbCgwKSxYIT09MClyZXR1cm4gRyhYKTtyZXR1cm4gUihZLnJlc3VsdCgpKX1zdGF0aWMjVygkLFosSil7aWYoWi5ieXRlTGVuZ3RoPT09MHx8Wi5ldmVyeSgoeik9Pno9PT0wKSlyZXR1cm4gRygyMik7aWYoWi5ieXRlTGVuZ3RoPT09UjApe2xldFt6LEtdPSQwLmZyb21CeXRlcygkLFopO2lmKEshPT0wKXJldHVybiBHKEspO2lmKHo9PT12b2lkIDApcmV0dXJuIEcoMTIpO3JldHVybiBSKHtlbmNsYXZlOnosaG9zdHM6W10sY3JlZElkOkp9KX1sZXQgUT1uZXcgZyhaKSxbVixZXT1RLnJlYWRTdHJ1Y3QoZFopO2lmKFkhPT0wKXJldHVybiBHKFkpO2lmKFY9PT12b2lkIDApcmV0dXJuIEcoMTQpO2xldFtYLFddPSQwLmZyb21CeXRlcygkLFYubWFzdGVyU2VlZCk7aWYoVi5tYXN0ZXJTZWVkLmZpbGwoMCksVyE9PTApcmV0dXJuIEcoVyk7aWYoWD09PXZvaWQgMClyZXR1cm4gRygxMik7cmV0dXJuIFIoe2VuY2xhdmU6WCxob3N0czpWLmhvc3RzLm1hcCgoeik9Pih7Li4uen0pKSxjcmVkSWQ6Sn0pfWFzeW5jI0coJCxaKXtsZXQgSj1hd2FpdCB0aGlzLiNZKCQpO3JldHVybiB0aGlzLiMkLmVuY3J5cHRYU2Fsc2EyMFBvbHkxMzA1Q29tYmluZWQoWixKKX1hc3luYyN6KCQsWil7bGV0IEo9YXdhaXQgdGhpcy4jWSgkKTtyZXR1cm4gdGhpcy4jJC5kZWNyeXB0WFNhbHNhMjBQb2x5MTMwNUNvbWJpbmVkKFosSil9YXN5bmMjWSgkKXtyZXR1cm4gdGhpcy4jJC5ibGFrZTMoVyQodGhpcy4jSiwkKSl9YXN5bmMjSygkLFope2xldCBKPW5ldyBUZXh0RW5jb2RlcigpLmVuY29kZSgkKSxRPW5ldyBVaW50OEFycmF5KDgpO3JldHVybiBuZXcgRGF0YVZpZXcoUS5idWZmZXIpLnNldEJpZ1VpbnQ2NCgwLEJpZ0ludChaKSwhMSksYXdhaXQgdGhpcy4jWShXJChKLFEpKX1hc3luYyNYKCQsWil7bGV0IEo9YXdhaXQgdGhpcy4jSygkLFopO3JldHVybiB0aGlzLiMkLmRlcml2ZUVkMjU1MTlLZXlQYWlyKEopfWFzeW5jI0YoJCxaLEope2xldCBRPWF3YWl0IHRoaXMuI1goJCxaKTtyZXR1cm4gdGhpcy4jJC5zaWduRWQyNTUxOShKLFEucHJpdmF0ZUtleSl9YXN5bmMjTigkLFosSil7bGV0IFE9YXdhaXQgdGhpcy4jWCgkLFopLFY9VyQoUS5wcml2YXRlS2V5LEopO3JldHVybihhd2FpdCB0aGlzLiMkLmJsYWtlMyhWKSkuc2xpY2UoMCxUMCl9fWFzeW5jIGZ1bmN0aW9uIGEkKCQsWil7aWYoWi5ieXRlTGVuZ3RoPHJWKXJldHVybiBHKDEwKTtsZXQgSj1hd2FpdCAkLmJsYWtlMyhXJChaLGNWKSk7cmV0dXJuIFIoSi5zbGljZSgwLGRWKSl9Y2xhc3Mgc1p7ZGI7Y29uc3RydWN0b3IoJCl7dGhpcy5kYj0kfWFzeW5jIGVucSgkKXtsZXQgWj1bLi4uJF07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFcwLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUoVzApO3JldHVybiBuZXcgUHJvbWlzZSgoVixZKT0+e0oub25jb21wbGV0ZT0oKT0+VigpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtmb3IobGV0IFggb2YgWil7bGV0IFc9YCR7WC5ob3N0fToke1guc2VxfWA7US5wdXQoWCxXKX19KX1hc3luYyBkZXEoJCxaKXtsZXQgSj1bLi4uWl07aWYoSi5sZW5ndGg9PT0wKXJldHVybjtsZXQgUT10aGlzLmRiLnRyYW5zYWN0aW9uKFcwLCJyZWFkd3JpdGUiKSxWPVEub2JqZWN0U3RvcmUoVzApO3JldHVybiBuZXcgUHJvbWlzZSgoWSxYKT0+e1Eub25jb21wbGV0ZT0oKT0+WSgpLFEub25lcnJvcj0oKT0+WChRLmVycm9yKTtmb3IobGV0IFcgb2YgSil7bGV0IHo9YCR7JH06JHtXfWA7Vi5kZWxldGUoeil9fSl9YXN5bmMgbGlzdCgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oVzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoVzApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBWPVouZ2V0QWxsKCk7Vi5vbnN1Y2Nlc3M9KCk9PkooVi5yZXN1bHQpLFYub25lcnJvcj0oKT0+UShWLmVycm9yKX0pfWFzeW5jIGNvdW50KCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihXMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShXMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57bGV0IFY9Wi5jb3VudCgpO1Yub25zdWNjZXNzPSgpPT5KKFYucmVzdWx0KSxWLm9uZXJyb3I9KCk9PlEoVi5lcnJvcil9KX1hc3luYyB3aXBlKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihXMCwicmVhZHdyaXRlIiksWj0kLm9iamVjdFN0b3JlKFcwKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PnskLm9uY29tcGxldGU9KCk9PkooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksWi5jbGVhcigpfSl9fWZ1bmN0aW9uIHdRKCQpe3JldHVybntsYWJlbDokLmxhYmVsLGhhbmRsZTpuZXcgVVJMKCQuaGFuZGxlKSxpZHg6JC5pZHgsbGFzdFNlcTokLmxhc3RTZXF8fDAsY2xvY2tPZmZzZXQ6JC5jbG9ja09mZnNldCxzdWJzY3JpcHRpb246JC5zdWJzY3JpcHRpb259fWZ1bmN0aW9uIG9WKCQsWil7bGV0IEo9ey4uLiR9O2lmKFouc2V0TGFzdFNlcSE9PXZvaWQgMClKLmxhc3RTZXE9Wi5zZXRMYXN0U2VxO2Vsc2UgaWYoWi5sYXN0U2VxIT09dm9pZCAwKXtsZXQgUT1KLmxhc3RTZXF8fDA7aWYoWi5sYXN0U2VxPlEpSi5sYXN0U2VxPVoubGFzdFNlcX1yZXR1cm4gZGVsZXRlIEoubnVtQmFncyxkZWxldGUgSi5udW1EdXBlcyxKfWNsYXNzIHRae2RiO2NvbnN0cnVjdG9yKCQpe3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IFo9YXdhaXQgdGhpcy5nZXQoJC5sYWJlbCksSj1aIT09dm9pZCAwJiZaLmhhbmRsZS5ocmVmPT09JC5oYW5kbGUuaHJlZiYmKFouaWR4Pz8wKT09PSgkLmlkeD8/MCk7cmV0dXJuIHRoaXMucHV0KHsuLi4kLGxhc3RTZXE6Sj9aLmxhc3RTZXE6MCxjbG9ja09mZnNldDpKP1ouY2xvY2tPZmZzZXQ6dm9pZCAwLHN1YnNjcmlwdGlvbjpKP1ouc3Vic2NyaXB0aW9uOnZvaWQgMH0pfWFzeW5jIHB1dCgkKXtsZXQgWj17Li4uJCxoYW5kbGU6JC5oYW5kbGUudG9TdHJpbmcoKSxsYXN0U2VxOiQubGFzdFNlcT8/MH0sSj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoVixZKT0+e0oub25jb21wbGV0ZT0oKT0+VigpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKSxRLnB1dChaKX0pfWFzeW5jIHRvdWNoKCQsWil7cmV0dXJuIHRoaXMucmVjb3JkU3RhdHMoJCx7bGFzdFNlcTpafSl9YXN5bmMgcmVjb3JkU3RhdHMoJCxaKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKFowLCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUoWjApO3JldHVybiBuZXcgUHJvbWlzZSgoVixZKT0+e0oub25jb21wbGV0ZT0oKT0+VigpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtsZXQgWD1RLmdldCgkKTtYLm9uc3VjY2Vzcz0oKT0+e2xldCBXPVgucmVzdWx0O2lmKCFXKXJldHVybjtRLnB1dChvVihXLFopKX19KX1hc3luYyBnZXQoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFYpPT57bGV0IFk9Si5nZXQoJCk7WS5vbnN1Y2Nlc3M9KCk9PntsZXQgWD1ZLnJlc3VsdDtpZighWClRKHZvaWQgMCk7ZWxzZSBRKHdRKFgpKX0sWS5vbmVycm9yPSgpPT5WKFkuZXJyb3IpfSl9YXN5bmMgc2V0KCQsWil7bGV0IEo9YXdhaXQgdGhpcy5nZXQoJCk7aWYoIUopcmV0dXJuIDEzO3RyeXtyZXR1cm4gYXdhaXQgdGhpcy5wdXQoey4uLkosLi4uWn0pLDB9Y2F0Y2h7cmV0dXJuIDE4fX1hc3luYyBkZWwoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZHdyaXRlIiksSj1aLm9iamVjdFN0b3JlKFowKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsVik9PntaLm9uY29tcGxldGU9KCk9PlEoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvciksSi5kZWxldGUoJCl9KX1hc3luYyBsaXN0KCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihaMCwicmVhZG9ubHkiKS5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57bGV0IFY9Wi5nZXRBbGwoKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBZPVYucmVzdWx0O0ooWS5tYXAod1EpKX0sVi5vbmVycm9yPSgpPT5RKFYuZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oWjAsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZShaMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5KKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLFouY2xlYXIoKX0pfX1jbGFzcyBlWntjcnlwdG87ZGI7Y29uc3RydWN0b3IoJCxaKXt0aGlzLmNyeXB0bz1aO3RoaXMuZGI9JH1hc3luYyBhZGQoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkd3JpdGUiKSxKPVoub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChRKT0+e2lmKCQubGVuZ3RoPT09MCl7UShbXSk7cmV0dXJufWxldCBWPUFycmF5KCQubGVuZ3RoKS5maWxsKDApO1oub25jb21wbGV0ZT0oKT0+UShWKSxaLm9uZXJyb3I9KCk9Pntmb3IobGV0IFk9MDtZPFYubGVuZ3RoO1krKylWW1ldPTE4O1EoVil9O2ZvcihsZXQgWT0wO1k8JC5sZW5ndGg7WSsrKXtsZXR7a2V5OlgsZGF0YTpXfT0kW1ldLHo9ZihYKSxLPUoucHV0KFcseik7Sy5vbmVycm9yPShGKT0+e0YucHJldmVudERlZmF1bHQoKSxWW1ldPTE4fX19KX1hc3luYyBkZWwoJCl7bGV0IFo9Wy4uLiRdO2lmKFoubGVuZ3RoPT09MClyZXR1cm47bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkd3JpdGUiKSxRPUoub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChWLFkpPT57Si5vbmNvbXBsZXRlPSgpPT5WKCksSi5vbmVycm9yPSgpPT5ZKEouZXJyb3IpO2ZvcihsZXQgWCBvZiBaKXtsZXQgVz1mKFgpO1EuZGVsZXRlKFcpfX0pfWFzeW5jIGdldCgkKXtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUodSk7cmV0dXJuIG5ldyBQcm9taXNlKChRLFYpPT57bGV0IFk9ZigkKSxYPUouZ2V0KFkpO1gub25zdWNjZXNzPWFzeW5jKCk9PntsZXQgVz1YLnJlc3VsdDtpZihXKVEoYXdhaXQgdiQoJCxXLHRoaXMuY3J5cHRvKSk7ZWxzZSBRKHZvaWQgMCl9LFgub25lcnJvcj0oKT0+VihYLmVycm9yKX0pfWFzeW5jIGhhcygkKXtyZXR1cm4gYXdhaXQgdGhpcy5nZXQoJCkhPT12b2lkIDB9YXN5bmMgbGlzdCgkKXtsZXQgWj0kPy5hcGxkLEo9JD8uYm9keSE9PSExLFY9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoWSxYKT0+e2xldCBXPVtdLHo9Wj09PXZvaWQgMD9WLm9wZW5DdXJzb3IoKTpWLmluZGV4KHEkKS5vcGVuQ3Vyc29yKElEQktleVJhbmdlLm9ubHkoWikpO3oub25zdWNjZXNzPShLKT0+e2xldCBGPUsudGFyZ2V0LnJlc3VsdDtpZihGKXtsZXQgTj1aPT09dm9pZCAwP0Yua2V5OkYucHJpbWFyeUtleSxVPUYudmFsdWU7Vy5wdXNoKHtoYXNoOkYwKE4pLGRhdGE6VX0pLEYuY29udGludWUoKX1lbHNlIFByb21pc2UuYWxsKFcubWFwKCh7aGFzaDpOLGRhdGE6VX0pPT52JChOLFUsdGhpcy5jcnlwdG8se2JvZHk6Sn0pKSkudGhlbihZKS5jYXRjaChYKX0sei5vbmVycm9yPSgpPT5YKHouZXJyb3IpfSl9YXN5bmMgY291bnQoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoUSxWKT0+e2xldCBZPSQ9PT12b2lkIDA/Si5jb3VudCgpOkouaW5kZXgocSQpLmNvdW50KElEQktleVJhbmdlLm9ubHkoJCkpO1kub25zdWNjZXNzPSgpPT5RKFkucmVzdWx0KSxZLm9uZXJyb3I9KCk9PlYoWS5lcnJvcil9KX1hc3luYyBsaXN0S2V5cygpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZG9ubHkiKS5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PntsZXQgVj1bXSxZPVoub3BlbktleUN1cnNvcigpO1kub25zdWNjZXNzPShYKT0+e2xldCBXPVgudGFyZ2V0LnJlc3VsdDtpZihXKVYucHVzaChGMChXLmtleSkpLFcuY29udGludWUoKTtlbHNlIEooVil9LFkub25lcnJvcj0oKT0+UShZLmVycm9yKX0pfWFzeW5jIGxhc3QoJCl7bGV0IEo9dGhpcy5kYi50cmFuc2FjdGlvbih1LCJyZWFkb25seSIpLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoUSxWKT0+e2xldCBZLFg9Si5vcGVuQ3Vyc29yKCk7WC5vbnN1Y2Nlc3M9YXN5bmMoVyk9PntsZXQgej1XLnRhcmdldC5yZXN1bHQ7aWYoeil7bGV0e2tleTpLLHZhbHVlOkZ9PXo7aWYoVjAoJCxGLmVpZCkpe2lmKCFZfHwoRi5jdHI/PzApPihZLmRhdGEuY3RyPz8wKXx8KEYuY3RyPz8wKT09PShZLmRhdGEuY3RyPz8wKSYmKEYub2ZmPz8wKT4oWS5kYXRhLm9mZj8/MCkpWT17a2V5OkssZGF0YTpGfX16LmNvbnRpbnVlKCl9ZWxzZSBpZihZKXtsZXQgSz1GMChZLmtleSk7UShhd2FpdCB2JChLLFkuZGF0YSx0aGlzLmNyeXB0bykpfWVsc2UgUSh2b2lkIDApfSxYLm9uZXJyb3I9KCk9PlYoWC5lcnJvcil9KX1hc3luYyBtYXJrQXBwbGllZCgkKXtsZXQgWj1bLi4uJF07aWYoWi5sZW5ndGg9PT0wKXJldHVybjtsZXQgSj10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWR3cml0ZSIpLFE9Si5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKFYsWSk9PntKLm9uY29tcGxldGU9KCk9PlYoKSxKLm9uZXJyb3I9KCk9PlkoSi5lcnJvcik7Zm9yKGxldCBYIG9mIFope2xldCBXPWYoWCksej1RLmdldChXKTt6Lm9uc3VjY2Vzcz0oKT0+e2xldCBLPXoucmVzdWx0O2lmKCFLKXJldHVybjtqWihLLFMkKSxRLnB1dChLLFcpfSx6Lm9uZXJyb3I9KEspPT57Sy5wcmV2ZW50RGVmYXVsdCgpfX19KX1hc3luYyBtYXJrRmFpbGVkKCQpe2xldCBaPVsuLi4kXTtpZihaLmxlbmd0aD09PTApcmV0dXJuO2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24odSwicmVhZHdyaXRlIiksUT1KLm9iamVjdFN0b3JlKHUpO3JldHVybiBuZXcgUHJvbWlzZSgoVixZKT0+e0oub25jb21wbGV0ZT0oKT0+VigpLEoub25lcnJvcj0oKT0+WShKLmVycm9yKTtmb3IobGV0e2tleTpYLGVycjpXfW9mIFope2xldCB6PWYoWCksSz1RLmdldCh6KTtLLm9uc3VjY2Vzcz0oKT0+e2xldCBGPUsucmVzdWx0O2lmKCFGKXJldHVybjtqWihGLGEwLFcpLFEucHV0KEYseil9LEsub25lcnJvcj0oRik9PntGLnByZXZlbnREZWZhdWx0KCl9fX0pfWFzeW5jIHdpcGUoKXtsZXQgJD10aGlzLmRiLnRyYW5zYWN0aW9uKHUsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZSh1KTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PnskLm9uY29tcGxldGU9KCk9PkooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksWi5jbGVhcigpfSl9fWNsYXNzICRKeyNKOyMkOyNaOyNWOyNRO2NvbnN0cnVjdG9yKCQpe2lmKHRoaXMuI0o9JC5jcnlwdG8sdGhpcy4jUT0kLnBlcnNpc3RNZXRhLHRoaXMuI1Y9e3JwSWQ6JC5ycElkLHJwTmFtZTokLnJwTmFtZX0sJC5tZXRhIT09dm9pZCAwKXRoaXMuI1o9SiQoJC5tZXRhKX1nZXQgbWV0YSgpe3JldHVybiB0aGlzLiNaPT09dm9pZCAwP3ZvaWQgMDpKJCh0aGlzLiNaKX1zZXRNZXRhKCQpe3RoaXMuI1o9JD09PXZvaWQgMD92b2lkIDA6SiQoJCl9YXN5bmMgc2F2ZSgkLFope2lmKFo/LnBlcnNpc3Q9PT0hMClyZXR1cm4gUHJvbWlzZS5yZWplY3QoRXJyb3IoInByZi1zdG9yZTogdXNlIHdyYXBBbmRTYXZlKGVuY2xhdmUpIHRvIHBlcnNpc3Qgc2VhbGVkIG1hc3RlciIpKTtyZXR1cm4gdGhpcy4jJD0kLHRoaXMuIyR9YXN5bmMgd3JhcEFuZFNhdmUoJCxaKXtsZXRbSixRXT1hd2FpdCAkLnNlYWxXaXRoUGFzc2tleSh7Li4udGhpcy4jVixzYWx0Olo/LnNhbHQsY3JlZElkOlo/LmNyZWRJZD8/dGhpcy4jWj8uY3JlZElkLGNyZWF0ZUNyZWRJZk5lZWRlZDpaPy5jcmVhdGVDcmVkSWZOZWVkZWQ/P1o/LmNyZWRJZD09PXZvaWQgMCx1c2VyTmFtZToiZGlwbG9tYXRpYy1wcmYifSk7aWYoUSE9PTApcmV0dXJuIEcoUSk7aWYoSj09PXZvaWQgMClyZXR1cm4gRygxMik7bGV0IFY9e3NlYWxlZE1hc3RlcjpKLnNlYWxlZE1hc3RlcixzYWx0Okouc2FsdCxjcmVkSWQ6Si5jcmVkSWR9O3JldHVybiB0aGlzLiNaPVYsdGhpcy4jJD0kLGF3YWl0IHRoaXMuI1EoSiQoVikpLFIodGhpcy4jJCl9YXN5bmMgbG9hZCgpe3JldHVybiB0aGlzLiMkfWFzeW5jIHVubG9jaygpe2xldCAkPXRoaXMuI1o7aWYoJD09PXZvaWQgMClyZXR1cm4gRygyMik7bGV0W1osSl09YXdhaXQgJDAudW5zZWFsV2l0aFBhc3NrZXkodGhpcy4jSiwkLnNlYWxlZE1hc3Rlcix7Li4udGhpcy4jVixzYWx0OiQuc2FsdCxjcmVkSWQ6JC5jcmVkSWR9KTtpZihKIT09MClyZXR1cm4gRyhKKTtpZihaPT09dm9pZCAwKXJldHVybiBHKDEyKTtyZXR1cm4gdGhpcy4jJD1aLFIoWil9YXN5bmMgYWRvcHRTZWFsZWQoJCxaKXtyZXR1cm4gdGhpcy4jWj1KJChaKSx0aGlzLiMkPSQsYXdhaXQgdGhpcy4jUShKJChaKSksUih0aGlzLiMkKX1hc3luYyB3aXBlKCl7dGhpcy4jJD12b2lkIDAsdGhpcy4jWj12b2lkIDAsYXdhaXQgdGhpcy4jUSh2b2lkIDApfX1mdW5jdGlvbiBKJCgkKXtsZXRbWixKXT1qMCgkLnNlYWxlZE1hc3Rlci5zbGljZSgpKTtyZXR1cm57c2VhbGVkTWFzdGVyOko9PT0wJiZaIT09dm9pZCAwP1o6JC5zZWFsZWRNYXN0ZXIsc2FsdDokLnNhbHQuc2xpY2UoKSxjcmVkSWQ6JC5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9fXZhciBaSj0ic2VlZCIscyQ9InByZk1ldGEiO2NsYXNzIEpKe2VuY2xhdmU7ZGI7I0o7Y29uc3RydWN0b3IoJCxaKXt0aGlzLmRiPSQsdGhpcy4jSj1afWFzeW5jIHNhdmUoJCxaKXtyZXR1cm4gdGhpcy5lbmNsYXZlPSQsdGhpcy5lbmNsYXZlfWFzeW5jIGxvYWQoKXtpZih0aGlzLmVuY2xhdmUpcmV0dXJuIHRoaXMuZW5jbGF2ZTtsZXQgJD1hd2FpdCB0aGlzLiMkKCk7aWYoJD09PXZvaWQgMHx8JD09PSIiKXJldHVybjtsZXQgWj1EJCgkKSxbSixRXT0kMC5mcm9tQnl0ZXModGhpcy4jSixaKTtpZihaLmZpbGwoMCksYXdhaXQgdGhpcy4jWigpLFEhPT0wfHxKPT09dm9pZCAwKXJldHVybjtyZXR1cm4gdGhpcy5lbmNsYXZlPUosdGhpcy5lbmNsYXZlfWFzeW5jIGNsZWFyU2Vzc2lvbigpe3RoaXMuZW5jbGF2ZT12b2lkIDAsYXdhaXQgdGhpcy4jWigpfWFzeW5jIHdpcGUoKXt0aGlzLmVuY2xhdmU9dm9pZCAwO2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oRzAsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZShHMCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5KKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLFouZGVsZXRlKFpKKSxaLmRlbGV0ZShzJCl9KX1hc3luYyBsb2FkUHJmTWV0YSgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oRzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoRzApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBWPVouZ2V0KHMkKTtWLm9uc3VjY2Vzcz0oKT0+e0ooYVYoVi5yZXN1bHQpKX0sVi5vbmVycm9yPSgpPT5RKFYuZXJyb3IpfSl9YXN5bmMgcGVyc2lzdFByZk1ldGEoJCl7bGV0IFo9dGhpcy5kYi50cmFuc2FjdGlvbihHMCwicmVhZHdyaXRlIiksSj1aLm9iamVjdFN0b3JlKEcwKTtyZXR1cm4gbmV3IFByb21pc2UoKFEsVik9PntpZihaLm9uY29tcGxldGU9KCk9PlEoKSxaLm9uZXJyb3I9KCk9PlYoWi5lcnJvciksJD09PXZvaWQgMCl7Si5kZWxldGUocyQpO3JldHVybn1sZXQgWT17c2VhbGVkTWFzdGVyOiQuc2VhbGVkTWFzdGVyLnNsaWNlKCksc2FsdDokLnNhbHQuc2xpY2UoKSxjcmVkSWQ6JC5jcmVkSWQ9PT12b2lkIDA/dm9pZCAwOiQuY3JlZElkLnNsaWNlKCl9O0oucHV0KFkscyQpfSl9YXN5bmMgaGFzUHJmTWV0YSgpe3JldHVybiBhd2FpdCB0aGlzLmxvYWRQcmZNZXRhKCkhPT12b2lkIDB9YXN5bmMgb3BlblByZlN0b3JlKCQpe2xldCBaPWF3YWl0IHRoaXMubG9hZFByZk1ldGEoKTtyZXR1cm4gbmV3ICRKKHtjcnlwdG86JC5jcnlwdG8/P3RoaXMuI0oscnBJZDokLnJwSWQscnBOYW1lOiQucnBOYW1lLG1ldGE6WixwZXJzaXN0TWV0YTooSik9PnRoaXMucGVyc2lzdFByZk1ldGEoSil9KX0jJCgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oRzAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoRzApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBWPVouZ2V0KFpKKTtWLm9uc3VjY2Vzcz0oKT0+e2xldCBZPVYucmVzdWx0O0oodHlwZW9mIFk9PT0ic3RyaW5nIiYmWS5sZW5ndGg+MD9ZOnZvaWQgMCl9LFYub25lcnJvcj0oKT0+UShWLmVycm9yKX0pfSNaKCl7bGV0ICQ9dGhpcy5kYi50cmFuc2FjdGlvbihHMCwicmVhZHdyaXRlIiksWj0kLm9iamVjdFN0b3JlKEcwKTtyZXR1cm4gbmV3IFByb21pc2UoKEosUSk9PnskLm9uY29tcGxldGU9KCk9PkooKSwkLm9uZXJyb3I9KCk9PlEoJC5lcnJvciksWi5kZWxldGUoWkopfSl9fWZ1bmN0aW9uIGFWKCQpe2lmKCQ9PT12b2lkIDB8fCQ9PT1udWxsfHx0eXBlb2YgJCE9PSJvYmplY3QiKXJldHVybjtsZXQgWj0kO2lmKCEoWi5zZWFsZWRNYXN0ZXIgaW5zdGFuY2VvZiBVaW50OEFycmF5KXx8IShaLnNhbHQgaW5zdGFuY2VvZiBVaW50OEFycmF5KSlyZXR1cm47bGV0W0osUV09ajAoWi5zZWFsZWRNYXN0ZXIpO2lmKFEhPT0wfHxKPT09dm9pZCAwKXJldHVybjtyZXR1cm57c2VhbGVkTWFzdGVyOkosc2FsdDpaLnNhbHQuc2xpY2UoKSxjcmVkSWQ6Wi5jcmVkSWQgaW5zdGFuY2VvZiBVaW50OEFycmF5P1ouY3JlZElkLnNsaWNlKCk6dm9pZCAwfX1jbGFzcyBRSntkYjtjb25zdHJ1Y3RvcigkKXt0aGlzLmRiPSR9YXN5bmMgZW5xKCQsWil7bGV0IEo9Wy4uLlpdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFE9dGhpcy5kYi50cmFuc2FjdGlvbih6MCwicmVhZHdyaXRlIiksVj1RLm9iamVjdFN0b3JlKHowKTtyZXR1cm4gbmV3IFByb21pc2UoKFksWCk9PntRLm9uY29tcGxldGU9KCk9PlkoKSxRLm9uZXJyb3I9KCk9PlgoUS5lcnJvcik7Zm9yKGxldCBXIG9mIEope2xldCB6PU4wKFcpO1YucHV0KHtob3N0OiQsaGFzaDp6fSl9fSl9YXN5bmMgZGVxKCQsWil7bGV0IEo9Wy4uLlpdO2lmKEoubGVuZ3RoPT09MClyZXR1cm47bGV0IFE9dGhpcy5kYi50cmFuc2FjdGlvbih6MCwicmVhZHdyaXRlIiksVj1RLm9iamVjdFN0b3JlKHowKTtyZXR1cm4gbmV3IFByb21pc2UoKFksWCk9PntRLm9uY29tcGxldGU9KCk9PlkoKSxRLm9uZXJyb3I9KCk9PlgoUS5lcnJvcik7Zm9yKGxldCBXIG9mIEope2xldCB6PU4wKFcpO1YuZGVsZXRlKFskLHpdKX19KX1hc3luYyBsaXN0KCQpe2xldCBKPXRoaXMuZGIudHJhbnNhY3Rpb24oejAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoejApO3JldHVybiBuZXcgUHJvbWlzZSgoUSxWKT0+e2xldCBZPUouZ2V0QWxsKCk7WS5vbnN1Y2Nlc3M9KCk9PntsZXQgVz1ZLnJlc3VsdC5maWx0ZXIoKHopPT56Lmhvc3Q9PT0kKS5tYXAoKHopPT56Lmhhc2gpO1EoVy5tYXAoKHopPT5EJCh6KSkpfSxZLm9uZXJyb3I9KCk9PlYoWS5lcnJvcil9KX1hc3luYyBjb3VudCgpe2xldCBaPXRoaXMuZGIudHJhbnNhY3Rpb24oejAsInJlYWRvbmx5Iikub2JqZWN0U3RvcmUoejApO3JldHVybiBuZXcgUHJvbWlzZSgoSixRKT0+e2xldCBWPVouY291bnQoKTtWLm9uc3VjY2Vzcz0oKT0+SihWLnJlc3VsdCksVi5vbmVycm9yPSgpPT5RKFYuZXJyb3IpfSl9YXN5bmMgd2lwZSgpe2xldCAkPXRoaXMuZGIudHJhbnNhY3Rpb24oejAsInJlYWR3cml0ZSIpLFo9JC5vYmplY3RTdG9yZSh6MCk7cmV0dXJuIG5ldyBQcm9taXNlKChKLFEpPT57JC5vbmNvbXBsZXRlPSgpPT5KKCksJC5vbmVycm9yPSgpPT5RKCQuZXJyb3IpLFouY2xlYXIoKX0pfX12YXIgRzA9InNlZWRNZXRhIixaMD0iaG9zdHMiLHowPSJ1cGxvYWRRdWV1ZSIsVzA9ImRvd25sb2FkUXVldWUiLHU9Im1lc3NhZ2VzIixxJD0iYXBsZCIsVFE9MyxEUT0iZGlwbG9tYXRpYy1zdG9yZS1kYiI7Y2xhc3MgalF7c2VlZDtob3N0czt1cGxvYWRzO2Rvd25sb2FkczttZXNzYWdlcztkYjtjb25zdHJ1Y3RvcigkLFope3RoaXMuZGI9JCx0aGlzLnNlZWQ9bmV3IEpKKCQsWiksdGhpcy5ob3N0cz1uZXcgdFooJCksdGhpcy51cGxvYWRzPW5ldyBRSigkKSx0aGlzLmRvd25sb2Fkcz1uZXcgc1ooJCksdGhpcy5tZXNzYWdlcz1uZXcgZVooJCxaKX1hc3luYyB3aXBlKCl7YXdhaXQgdGhpcy5ob3N0cy53aXBlKCksYXdhaXQgdGhpcy51cGxvYWRzLndpcGUoKSxhd2FpdCB0aGlzLmRvd25sb2Fkcy53aXBlKCksYXdhaXQgdGhpcy5tZXNzYWdlcy53aXBlKCl9fWFzeW5jIGZ1bmN0aW9uIHNWKCl7cmV0dXJuIG5ldyBQcm9taXNlKCgkLFopPT57bGV0IEo9aW5kZXhlZERCLm9wZW4oRFEsVFEpO0oub251cGdyYWRlbmVlZGVkPSgpPT57bGV0e3Jlc3VsdDpRLHRyYW5zYWN0aW9uOlZ9PUo7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhHMCkpUS5jcmVhdGVPYmplY3RTdG9yZShHMCk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyhaMCkpUS5jcmVhdGVPYmplY3RTdG9yZShaMCx7a2V5UGF0aDoibGFiZWwifSk7aWYoIVEub2JqZWN0U3RvcmVOYW1lcy5jb250YWlucyh6MCkpUS5jcmVhdGVPYmplY3RTdG9yZSh6MCx7a2V5UGF0aDpbImhvc3QiLCJoYXNoIl19KTtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKFcwKSlRLmNyZWF0ZU9iamVjdFN0b3JlKFcwKTtsZXQgWTtpZighUS5vYmplY3RTdG9yZU5hbWVzLmNvbnRhaW5zKHUpKVk9US5jcmVhdGVPYmplY3RTdG9yZSh1KTtlbHNle2lmKCFWKXRocm93IEVycm9yKCJtaXNzaW5nIHVwZ3JhZGUgdHJhbnNhY3Rpb24gZm9yIG1lc3NhZ2VzIHN0b3JlIik7WT1WLm9iamVjdFN0b3JlKHUpfWlmKCFZLmluZGV4TmFtZXMuY29udGFpbnMocSQpKVkuY3JlYXRlSW5kZXgocSQsImFwbGQiLHt1bmlxdWU6ITF9KX0sSi5vbmJsb2NrZWQ9KCk9Pntjb25zb2xlLndhcm4oYFtESVBMT01BVElDXSBwcm90b2NvbCBzdG9yZSBJREIgdXBncmFkZSBibG9ja2VkICgke0RRfSDihpIgdiR7VFF9KTsgd2FpdGluZyBmb3Igb3RoZXIgY29ubmVjdGlvbnMgdG8gY2xvc2VgKX0sSi5vbnN1Y2Nlc3M9KCk9PntsZXQgUT1KLnJlc3VsdDtRLm9udmVyc2lvbmNoYW5nZT0oKT0+e1EuY2xvc2UoKX0sJChRKX0sSi5vbmVycm9yPSgpPT5aKEouZXJyb3I/P0Vycm9yKCJwcm90b2NvbCBzdG9yZSBJbmRleGVkREIgb3BlbiBmYWlsZWQiKSl9KX1hc3luYyBmdW5jdGlvbiBBUSgkKXtsZXQgWj1hd2FpdCBzVigpO2lmKHR5cGVvZiBuYXZpZ2F0b3I8InUiJiZuYXZpZ2F0b3Iuc3RvcmFnZT8ucGVyc2lzdCl0cnl7YXdhaXQgUHJvbWlzZS5yYWNlKFtuYXZpZ2F0b3Iuc3RvcmFnZS5wZXJzaXN0KCksbmV3IFByb21pc2UoKEopPT57c2V0VGltZW91dCgoKT0+SighMSksMjAwMCl9KV0pfWNhdGNoe31yZXR1cm4gbmV3IGpRKFosJCl9Y2xhc3MgVkp7Y2xpZW50O2VudERCO3Bvc3Q7d2hlblJlYWR5O3Jlc29sdmVSZWFkeTtyZWplY3RSZWFkeTtjb25zdHJ1Y3RvcigkKXt0aGlzLnBvc3Q9JCx0aGlzLndoZW5SZWFkeT1uZXcgUHJvbWlzZSgoWixKKT0+e3RoaXMucmVzb2x2ZVJlYWR5PVosdGhpcy5yZWplY3RSZWFkeT1KfSl9YXN5bmMgaW5pdCgpe3RyeXtsZXQgJD1hd2FpdCBBUShVJCksWj1hd2FpdCB2Sih7Y2FjaGU6ITF9KSxKPW5ldyBrJChaLmFwcGx5LCgpPT5aLmNsZWFyKCksKFkpPT57aWYoWS5sZW5ndGg8MSlyZXR1cm47dGhpcy5wb3N0KHtraW5kOiJkaXJ0eSIsZWlkczpZLm1hcCgoWCk9Plguc2xpY2UoKSl9KX0pLFE9Si5jbGVhcjtKLmNsZWFyPWFzeW5jKCk9PntsZXQgWT1hd2FpdCBRKCk7aWYoWT09PTApdGhpcy5wb3N0KHtraW5kOiJ3aXBlZCJ9KTtyZXR1cm4gWX07bGV0IFY9bmV3IGtaKG5ldyBYWixKLCQsX0osVSQpO3RoaXMuY2xpZW50PVYsdGhpcy5lbnREQj1aLFYuY2xpZW50U3RhdGUubGlzdGVuKCgpPT57dGhpcy5lbWl0Q2xpZW50U3RhdGUoKX0pLFYueGZlclN0YXRlLmxpc3RlbigoKT0+e3RoaXMuZW1pdFhmZXJTdGF0ZSgpfSksYXdhaXQgdGhpcy5lbWl0Q2xpZW50U3RhdGUoKSxhd2FpdCB0aGlzLmVtaXRYZmVyU3RhdGUoKSx0aGlzLnBvc3Qoe2tpbmQ6InJlYWR5In0pLHRoaXMubWFya1JlYWR5KCl9Y2F0Y2goJCl7bGV0IFo9JCBpbnN0YW5jZW9mIEVycm9yPyQ6RXJyb3IoU3RyaW5nKCQpKTt0aHJvdyB0aGlzLnBvc3Qoe2tpbmQ6ImluaXRFcnJvciIsbWVzc2FnZTpaLm1lc3NhZ2V9KSx0aGlzLmZhaWxSZWFkeShaKSxafX1tYXJrUmVhZHkoKXtsZXQgJD10aGlzLnJlc29sdmVSZWFkeTtpZih0aGlzLnJlc29sdmVSZWFkeT12b2lkIDAsdGhpcy5yZWplY3RSZWFkeT12b2lkIDAsJCkkKCl9ZmFpbFJlYWR5KCQpe2xldCBaPXRoaXMucmVqZWN0UmVhZHk7aWYodGhpcy5yZXNvbHZlUmVhZHk9dm9pZCAwLHRoaXMucmVqZWN0UmVhZHk9dm9pZCAwLFopWigkKX1yZXF1aXJlQ2xpZW50KCl7aWYoIXRoaXMuY2xpZW50KXRocm93IEVycm9yKCJXb3JrZXJSdW50aW1lIG5vdCBpbml0aWFsaXplZCIpO3JldHVybiB0aGlzLmNsaWVudH1hc3luYyBlbWl0Q2xpZW50U3RhdGUoKXtsZXQgJD10aGlzLmNsaWVudDtpZighJClyZXR1cm47bGV0IFo9YXdhaXQgJC5jbGllbnRTdGF0ZS5nZXQoKTt0aGlzLnBvc3Qoe2tpbmQ6ImNsaWVudFN0YXRlIixzdGF0ZTpafSl9YXN5bmMgZW1pdFhmZXJTdGF0ZSgpe2xldCAkPXRoaXMuY2xpZW50O2lmKCEkKXJldHVybjtsZXQgWj1hd2FpdCAkLnhmZXJTdGF0ZS5nZXQoKTt0aGlzLnBvc3Qoe2tpbmQ6InhmZXJTdGF0ZSIsc3RhdGU6Wn0pfWhvc3RGcm9tU2VyaWFsaXplZCgkKXtyZXR1cm57aGFuZGxlOm5ldyBVUkwoJC5oYW5kbGUpLGxhYmVsOiQubGFiZWwsaWR4OiQuaWR4fX1hc3luYyBoYW5kbGUoJCl7YXdhaXQgdGhpcy53aGVuUmVhZHk7bGV0IFo9dGhpcy5yZXF1aXJlQ2xpZW50KCk7c3dpdGNoKCQub3Ape2Nhc2UicGluZyI6cmV0dXJuInBvbmciO2Nhc2Uic2V0U2VlZCI6e2xldFtKLFFdPSQwLmZyb21CeXRlcyhVJCwkLnNlZWQpO2lmKFEhPT0wfHxKPT09dm9pZCAwKXRocm93IG5ldyBLMChRKTthd2FpdCBaLnNldFNlZWQoSix7cGVyc2lzdDokLnBlcnNpc3R9KTtyZXR1cm59Y2FzZSJsaW5rIjp7YXdhaXQgWi5saW5rKHRoaXMuaG9zdEZyb21TZXJpYWxpemVkKCQuaG9zdCksJC5jb25uZWN0Pz8hMCk7cmV0dXJufWNhc2UidW5saW5rIjp7YXdhaXQgWi51bmxpbmsoJC5sYWJlbCk7cmV0dXJufWNhc2UiY29ubmVjdCI6e2F3YWl0IFouY29ubmVjdCgkLmxpc3Rlbj8/ITAsJC5zeW5jPz8hMCk7cmV0dXJufWNhc2UiZGlzY29ubmVjdCI6e2F3YWl0IFouZGlzY29ubmVjdCgpO3JldHVybn1jYXNlInN5bmMiOnJldHVybiBhd2FpdCBaLnN5bmMoKTtjYXNlInJlYnVpbGQiOnJldHVybiBhd2FpdCBaLnJlYnVpbGQoe2NoZWNrSG9zdDokLmNoZWNrSG9zdD8/ITB9KTtjYXNlInJlY29uY2lsZSI6e2xldFtKLFFdPWF3YWl0IFoucmVjb25jaWxlKCQuaG9zdExhYmVsLHtwdWxsOiQucHVsbCxwdXNoOiQucHVzaCxzeW5jOiQuc3luY30pO2lmKFEhPT0wKXRocm93IG5ldyBLMChRKTtpZighSil0aHJvdyBuZXcgSzAoMTIpO3JldHVybiBKfWNhc2UibXNnY2hlY2siOnJldHVybiBhd2FpdCBaLm1zZ2NoZWNrKCk7Y2FzZSJlbnRjaGVjayI6e2xldCBKPXRoaXMuZW50REI7aWYoIUopdGhyb3cgbmV3IEswKDEyKTtsZXRbUSxWXT1hd2FpdCBKLmNoZWNrc3VtKFUkKTtpZihWIT09MCl0aHJvdyBuZXcgSzAoVik7aWYoIVEpdGhyb3cgbmV3IEswKDEyKTtyZXR1cm4gUX1jYXNlIndpcGUiOnthd2FpdCBaLndpcGUoe21zZ3M6JC5tc2dzLGVudHM6JC5lbnRzLG1ldGE6JC5tZXRhLHNlZWQ6JC5zZWVkfSk7cmV0dXJufWNhc2UiaW1wb3J0Ijp7bGV0IEo9JC5ieXRlcy5zbGljZSgpLFE9bmV3IEJsb2IoW0pdKSxWPW5ldyBGaWxlKFtRXSwiaW1wb3J0LmRpcCIpO3JldHVybiBhd2FpdCBaLmltcG9ydChWKX1jYXNlImV4cG9ydCI6e2xldFtKLFFdPWF3YWl0IFouZXhwb3J0Qnl0ZXMoKTtpZihRIT09MCl0aHJvdyBuZXcgSzAoUSk7aWYoIUopdGhyb3cgbmV3IEswKDEyKTtyZXR1cm4gSn1jYXNlImdldENsaWVudFN0YXRlIjpyZXR1cm4gYXdhaXQgWi5jbGllbnRTdGF0ZS5nZXQoKTtjYXNlImdldFhmZXJTdGF0ZSI6cmV0dXJuIGF3YWl0IFoueGZlclN0YXRlLmdldCgpO2RlZmF1bHQ6e2xldCBKPSQ7dGhyb3cgRXJyb3IoInVua25vd24gd29ya2VyIGNvbW1hbmQiKX19fX1jbGFzcyBLMCBleHRlbmRzIEVycm9ye3N0YXR1cztjb25zdHJ1Y3RvcigkKXtzdXBlcihgV29ya2VyU3RhdHVzRXJyb3I6ICR7alskXX1gKTt0aGlzLnN0YXR1cz0kO3RoaXMubmFtZT0iV29ya2VyU3RhdHVzRXJyb3IifX1mdW5jdGlvbiB0JCgkLFope3JldHVybntraW5kOiJyZXBseSIsaWQ6JCxvazohMCxyZXN1bHQ6Wn19ZnVuY3Rpb24gWUooJCxaKXtyZXR1cm57a2luZDoicmVwbHkiLGlkOiQsb2s6ITEsc3RhdHVzOlp9fXZhciBBMD1nbG9iYWxUaGlzLF9RPW5ldyBWSigoJCxaKT0+e2lmKFomJloubGVuZ3RoPjApQTAucG9zdE1lc3NhZ2UoJCxaKTtlbHNlIEEwLnBvc3RNZXNzYWdlKCQpfSk7QTAub25tZXNzYWdlPSgkKT0+e2xldCBaPSQuZGF0YTtpZighekooWikpcmV0dXJuO3RWKFopfTthc3luYyBmdW5jdGlvbiB0VigkKXt0cnl7bGV0IFo9YXdhaXQgX1EuaGFuZGxlKCQpO2lmKCgkLm9wPT09ImV4cG9ydCJ8fCQub3A9PT0ibXNnY2hlY2sifHwkLm9wPT09ImVudGNoZWNrIikmJlogaW5zdGFuY2VvZiBVaW50OEFycmF5KXtsZXQgSj1aLnNsaWNlKCk7QTAucG9zdE1lc3NhZ2UodCQoJC5pZCxKKSxbSi5idWZmZXJdKTtyZXR1cm59aWYoJC5vcD09PSJyZWNvbmNpbGUiJiZaJiZ0eXBlb2YgWj09PSJvYmplY3QiJiYibXNnY2hlY2siaW4gWiYmWi5tc2djaGVjayBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpe2xldCBKPVoubXNnY2hlY2suc2xpY2UoKSxRPXsuLi5aLG1zZ2NoZWNrOkp9O0EwLnBvc3RNZXNzYWdlKHQkKCQuaWQsUSksW0ouYnVmZmVyXSk7cmV0dXJufUEwLnBvc3RNZXNzYWdlKHQkKCQuaWQsWikpfWNhdGNoKFope2lmKFogaW5zdGFuY2VvZiBLMCl7QTAucG9zdE1lc3NhZ2UoWUooJC5pZCxaLnN0YXR1cykpO3JldHVybn1jb25zb2xlLmVycm9yKCJ3b3JrZXIgY29tbWFuZCBmYWlsZWQiLFopLEEwLnBvc3RNZXNzYWdlKFlKKCQuaWQsMTIpKX19X1EuaW5pdCgpLmNhdGNoKCgkKT0+e2NvbnNvbGUuZXJyb3IoIndvcmtlciBpbml0IGZhaWxlZCIsJCl9KTsK";var LW;function yK(){if(typeof pW!=="string"||pW.length===0)throw Error("[DIPLOMATIC] worker source not embedded; run pkg build before spawn");return atob(pW)}function MK(){if(LW!==void 0)return LW;let Z=new Blob([yK()],{type:"text/javascript"});return LW=URL.createObjectURL(Z),LW}function ql(){if(typeof Worker>"u")throw Error("[DIPLOMATIC] Worker API unavailable; cannot spawn sync worker");return new Worker(MK(),{type:"module"})}var zK=new TextEncoder().encode("diplomatic.wrap.v1"),hK=32,SK=16;class ${#W;#Z;constructor(Z,X){this.#W=Z,this.#Z=X}static async fromRandom(Z){let X=await Z.gen256BitSecureRandomSeed(),[W,V]=ZZ(X);if(V!==0||W===void 0)throw Error(`enclave: invalid random seed (${V})`);return new $(W,Z)}static fromBytes(Z,X){let[W,V]=ZZ(X);if(V!==0)return Y(V);if(W===void 0)return Y(10);let[l,K]=ZZ(W.slice());if(K!==0)return Y(K);if(l===void 0)return Y(10);return d(new $(l,Z))}async sealWithPasskey(Z){let X=Z?.salt??BX,W=Z?.credId;if(W===void 0&&Z?.createCredIfNeeded===!0){let[K,G]=await gV({rpId:Z?.rpId,rpName:Z?.rpName,userName:Z?.userName??"diplomatic-prf"});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 bX({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.#X(V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);return d({sealedMaster:K,salt:X.slice(),credId:V.credId.slice()})}finally{V.prf.fill(0)}}static async unsealWithPasskey(Z,X,W){let[V,l]=await bX({rpId:W.rpId,rpName:W.rpName,credId:W.credId,salt:W.salt});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{return await $.#V(Z,X,V.prf)}finally{V.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 jX(W,V,X);if(K!==0)return Y(K);return d(W)}finally{V.fill(0)}}static async fromLargeBlob(Z,X){let[W,V]=await IW(X?.credId,X);if(V!==0)return Y(V);if(W===void 0)return Y(7);try{return $.#m(Z,W.blob,W.credId)}finally{W.blob.fill(0)}}static async clearLargeBlob(Z,X){return jX(Z,new Uint8Array(dZ),X)}async sealPairPackageBody(Z,X){let W=X?.salt??BX,[V,l]=await bX({rpId:X?.rpId,rpName:X?.rpName,credId:X?.credId,salt:W});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await EX(this.#Z,V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);let[m,R]=ZZ(this.#W.slice());if(R!==0)return Y(R);if(m===void 0)return Y(10);let J={masterSeed:m,hosts:Z.map((k)=>({handle:k.handle,label:k.label,idx:k.idx??0}))},C=new i,F=C.writeStruct(UX,J);if(F!==0)return m.fill(0),Y(F);let b=C.result();m.fill(0);let c;try{c=await this.#Z.encryptXSalsa20Poly1305Combined(b,K)}catch{return b.fill(0),Y(12)}return b.fill(0),d({body:c,salt:W.slice(),credId:V.credId.slice()})}finally{V.prf.fill(0)}}static async openPairPackageBody(Z,X,W){let[V,l]=await bX({rpId:W.rpId,rpName:W.rpName,credId:W.credId,salt:W.salt});if(l!==0)return Y(l);if(V===void 0)return Y(7);try{let[K,G]=await EX(Z,V.prf);if(G!==0)return Y(G);if(K===void 0)return Y(12);let m;try{m=await Z.decryptXSalsa20Poly1305Combined(X,K)}catch{return Y(20)}let R=new P(m),[J,C]=R.readStruct(UX);if(m.fill(0),C!==0)return Y(C);if(J===void 0)return Y(14);let[F,b]=$.fromBytes(Z,J.masterSeed);if(J.masterSeed.fill(0),b!==0)return Y(b);if(F===void 0)return Y(12);let[c,k]=await F.#X(V.prf);if(k!==0)return Y(k);if(c===void 0)return Y(12);return d({enclave:F,hosts:J.hosts.map((T)=>({...T})),sealedMaster:c,credId:V.credId.slice()})}finally{V.prf.fill(0)}}spawnSyncWorker(Z){let X=ql(),W=this.#W.slice();return X.postMessage({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.#G(W,V);return Object.freeze({publicKey:l.publicKey,sign:(K)=>this.#C(W,V,K),kdmFor:(K)=>this.#F(W,V,K)})}async#X(Z){let[X,W]=await EX(this.#Z,Z);if(W!==0)return Y(W);if(X===void 0)return Y(12);try{let V=await this.#Z.encryptXSalsa20Poly1305Combined(this.#W,X);return LZ(V)}catch{return Y(12)}}static async#V(Z,X,W){let[,V]=LZ(X);if(V!==0)return Y(V);let[l,K]=await EX(Z,W);if(K!==0)return Y(K);if(l===void 0)return Y(12);try{let G=await Z.decryptXSalsa20Poly1305Combined(X,l);return $.fromBytes(Z,G)}catch{return Y(20)}}#l(Z){let[X,W]=ZZ(this.#W.slice());if(W!==0)return Y(W);if(X===void 0)return Y(10);let[V,l]=SV(X,Z);if(l!==0)return X.fill(0),Y(l);if(V===void 0)return X.fill(0),Y(12);X.fill(0);let K=new i,G=K.writeStruct(cW,V);if(V.masterSeed.fill(0),G!==0)return Y(G);return d(K.result())}static#m(Z,X,W){if(X.byteLength===0||X.every((R)=>R===0))return Y(22);if(X.byteLength===dZ){let[R,J]=$.fromBytes(Z,X);if(J!==0)return Y(J);if(R===void 0)return Y(12);return d({enclave:R,hosts:[],credId:W})}let V=new P(X),[l,K]=V.readStruct(cW);if(K!==0)return Y(K);if(l===void 0)return Y(14);let[G,m]=$.fromBytes(Z,l.masterSeed);if(l.masterSeed.fill(0),m!==0)return Y(m);if(G===void 0)return Y(12);return d({enclave:G,hosts:l.hosts.map((R)=>({...R})),credId:W})}async#Y(Z,X){let W=await this.#K(Z);return this.#Z.encryptXSalsa20Poly1305Combined(X,W)}async#R(Z,X){let W=await this.#K(Z);return this.#Z.decryptXSalsa20Poly1305Combined(X,W)}async#K(Z){return this.#Z.blake3(QX(this.#W,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.#K(QX(W,V))}async#G(Z,X){let W=await this.#J(Z,X);return this.#Z.deriveEd25519KeyPair(W)}async#C(Z,X,W){let V=await this.#G(Z,X);return this.#Z.signEd25519(W,V.privateKey)}async#F(Z,X,W){let V=await this.#G(Z,X),l=QX(V.privateKey,W);return(await this.#Z.blake3(l)).slice(0,HZ)}}async function EX(Z,X){if(X.byteLength<SK)return Y(10);let W=await Z.blake3(QX(X,zK));return d(W.slice(0,hK))}class QW{#W;#Z;#X;#V;#l;constructor(Z){if(this.#W=Z.crypto,this.#l=Z.persistMeta,this.#V={rpId:Z.rpId,rpName:Z.rpName},Z.meta!==void 0)this.#X=cX(Z.meta)}get meta(){return this.#X===void 0?void 0:cX(this.#X)}setMeta(Z){this.#X=Z===void 0?void 0:cX(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.#V,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.#l(cX(l)),d(this.#Z)}async load(){return this.#Z}async unlock(){let Z=this.#X;if(Z===void 0)return Y(22);let[X,W]=await $.unsealWithPasskey(this.#W,Z.sealedMaster,{...this.#V,salt:Z.salt,credId:Z.credId});if(W!==0)return Y(W);if(X===void 0)return Y(12);return this.#Z=X,d(X)}async adoptSealed(Z,X){return this.#X=cX(X),this.#Z=Z,await this.#l(cX(X)),d(this.#Z)}async wipe(){this.#Z=void 0,this.#X=void 0,await this.#l(void 0)}}function cX(Z){let[X,W]=LZ(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 xV="seed",yW="prfMeta";class MW{enclave;db;#W;constructor(Z,X){this.db=Z,this.#W=X}async save(Z,X){return this.enclave=Z,this.enclave}async load(){if(this.enclave)return this.enclave;let Z=await this.#Z();if(Z===void 0||Z==="")return;let X=iZ(Z),[W,V]=$.fromBytes(this.#W,X);if(X.fill(0),await this.#X(),V!==0||W===void 0)return;return this.enclave=W,this.enclave}async clearSession(){this.enclave=void 0,await this.#X()}async wipe(){this.enclave=void 0;let Z=this.db.transaction(JZ,"readwrite"),X=Z.objectStore(JZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.delete(xV),X.delete(yW)})}async loadPrfMeta(){let X=this.db.transaction(JZ,"readonly").objectStore(JZ);return new Promise((W,V)=>{let l=X.get(yW);l.onsuccess=()=>{W(NK(l.result))},l.onerror=()=>V(l.error)})}async persistPrfMeta(Z){let X=this.db.transaction(JZ,"readwrite"),W=X.objectStore(JZ);return new Promise((V,l)=>{if(X.oncomplete=()=>V(),X.onerror=()=>l(X.error),Z===void 0){W.delete(yW);return}let K={sealedMaster:Z.sealedMaster.slice(),salt:Z.salt.slice(),credId:Z.credId===void 0?void 0:Z.credId.slice()};W.put(K,yW)})}async hasPrfMeta(){return await this.loadPrfMeta()!==void 0}async openPrfStore(Z){let X=await this.loadPrfMeta();return new QW({crypto:Z.crypto??this.#W,rpId:Z.rpId,rpName:Z.rpName,meta:X,persistMeta:(W)=>this.persistPrfMeta(W)})}#Z(){let X=this.db.transaction(JZ,"readonly").objectStore(JZ);return new Promise((W,V)=>{let l=X.get(xV);l.onsuccess=()=>{let K=l.result;W(typeof K==="string"&&K.length>0?K:void 0)},l.onerror=()=>V(l.error)})}#X(){let Z=this.db.transaction(JZ,"readwrite"),X=Z.objectStore(JZ);return new Promise((W,V)=>{Z.oncomplete=()=>W(),Z.onerror=()=>V(Z.error),X.delete(xV)})}}function NK(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]=LZ(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 HV{db;constructor(Z){this.db=Z}async enq(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=GZ(m);l.put({host:Z,hash:R})}})}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=GZ(m);l.delete([Z,R])}})}async list(Z){let W=this.db.transaction(CZ,"readonly").objectStore(CZ);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)=>iZ(R)))},K.onerror=()=>l(K.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()})}}var JZ="seedMeta",lZ="hosts",CZ="uploadQueue",RZ="downloadQueue",o="messages",PX="apld",al=3,_l="diplomatic-store-db";class PV{seed;hosts;uploads;downloads;messages;db;constructor(Z,X){this.db=Z,this.seed=new MW(Z,X),this.hosts=new zV(Z),this.uploads=new HV(Z),this.downloads=new MV(Z),this.messages=new hV(Z,X)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}async function gK(){return new Promise((Z,X)=>{let W=indexedDB.open(_l,al);W.onupgradeneeded=()=>{let{result:V,transaction:l}=W;if(!V.objectStoreNames.contains(JZ))V.createObjectStore(JZ);if(!V.objectStoreNames.contains(lZ))V.createObjectStore(lZ,{keyPath:"label"});if(!V.objectStoreNames.contains(CZ))V.createObjectStore(CZ,{keyPath:["host","hash"]});if(!V.objectStoreNames.contains(RZ))V.createObjectStore(RZ);let K;if(!V.objectStoreNames.contains(o))K=V.createObjectStore(o);else{if(!l)throw Error("missing upgrade transaction for messages store");K=l.objectStore(o)}if(!K.indexNames.contains(PX))K.createIndex(PX,"apld",{unique:!1})},W.onblocked=()=>{console.warn(`[DIPLOMATIC] protocol store IDB upgrade blocked (${_l} → v${al}); 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 zW(Z){let X=await gK();if(typeof navigator<"u"&&navigator.storage?.persist)try{await Promise.race([navigator.storage.persist(),new Promise((W)=>{setTimeout(()=>W(!1),2000)})])}catch{}return new PV(X,Z)}function sl(Z){if(!Z||typeof Z!=="object")return!1;if(!("kind"in Z))return!1;return typeof Z.kind==="string"}function rl(Z){if(typeof Z!=="number")return;return Z}function tl(Z){if(!Z||typeof Z!=="object")return;if(!("hasSeed"in Z)||!("hasHost"in Z)||!("connected"in Z))return;if(typeof Z.hasSeed!=="boolean"||typeof Z.hasHost!=="boolean"||typeof Z.connected!=="boolean")return;return{hasSeed:Z.hasSeed,hasHost:Z.hasHost,connected:Z.connected}}function xK(Z){if(!Z||typeof Z!=="object")return;if(!("phase"in Z))return;let X=HK(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 HK(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 el(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=xK(Z.progress);if(W===void 0)return;X=W}return{numUploads:Z.numUploads,numDownloads:Z.numDownloads,progress:X}}var FZ="[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:oZ};clientState;xferState;constructor(Z,X,W,V,l){this.state=Z,this.store=X,this.readyTimeoutMs=l,this.clientState=new bZ(async()=>this.cachedClientState),this.xferState=new bZ(async()=>this.cachedXferState),this.scheduledSync=new NX(V,async()=>{if(!this.worker)return;try{await this.request({id:this.allocId(),op:"sync"})}catch(K){console.error(`${FZ} worker sync after local write failed`,K)}}),this.local=new vZ(W,Z,X,()=>{throw Error(`${FZ} local writer has no transport (use worker for network)`)},SZ,!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(`${FZ} worker error`,W),this.failPending(Error(`${FZ} worker failed to load`))},Z.onmessageerror=()=>{this.failPending(Error(`${FZ} 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 pZ,l=W.syncDebounceMs??lW,K=W.readyTimeoutMs??15000,G=new DX(Z,X,V,l,K);return await G.hydrateStateFromStore(X),G}async hydrateStateFromStore(Z){let X=await Z.seed.load(),W=await Z.hosts.list();this.cachedClientState={hasSeed:X!==void 0,hasHost:Array.from(W).length>0,connected:!1};let V=await Z.uploads.count(),l=await Z.downloads.count();this.cachedXferState={numUploads:V,numDownloads:l,progress:oZ}}async pullRemoteState(){let Z=await this.request({id:this.allocId(),op:"getClientState"}),X=tl(Z);if(X!==void 0)this.cachedClientState=X;let W=await this.request({id:this.allocId(),op:"getXferState"}),V=el(W);if(V!==void 0)this.cachedXferState=V}requireWorker(){if(!this.worker)throw Error(`${FZ} no sync worker; call setSeed first`);return this.worker}async ping(){if(await this.request({id:this.allocId(),op:"ping"})!=="pong")throw Error(`${FZ} worker ping failed`)}terminate(){this.scheduledSync.cancel();let Z=this.worker;if(this.worker=void 0,Z)try{Z.terminate()}catch{}this.failPending(Error(`${FZ} worker terminated`))}onMessage(Z){if(!sl(Z))return;let X=Z;switch(X.kind){case"ready":return;case"initError":{this.failPending(Error(`${FZ} worker init failed: ${X.message}`));return}case"clientState":{this.cachedClientState=X.state,this.clientState.emit();return}case"xferState":{this.cachedXferState=X.state,this.xferState.emit();return}case"dirty":{this.state.refresh(X.eids.map(iK));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=rl(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),this.cachedClientState={...this.cachedClientState,hasSeed:!0},this.clientState.emit();let W=this.allocId(),V=this.readyTimeoutMs;await new Promise((l,K)=>{let G,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(`${FZ} 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.pullRemoteState()}catch{}}async link(Z,X=!0){await this.local.link(Z,!1),await this.request({id:this.allocId(),op:"link",host:this.serializeHost(Z),connect:X})}async unlink(Z){if(await this.local.unlink(Z),!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(!PK(W))return Y(12);return d(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(`${FZ} msgcheck: expected Uint8Array`);return Z}async entcheck(){let Z=await this.request({id:this.allocId(),op:"entcheck"});if(!(Z instanceof Uint8Array))throw Error(`${FZ} 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 GW(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 PK(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 iK(Z){return Z}var kX="[DIPLOMATIC]";async function hW(Z){let X=Z.clock??new pZ;if(Z.worker===!0&&UK(Z)!==void 0)throw Error(`${kX} worker path requires IndexedDB on both sides; do not pass store (got a custom store)`);if(Z.worker!==!0){console.info(`${kX} sync on main thread `+"(no worker — app did not request a worker)");let l=await Z0(Z.store);return uK(X,Z.state,l)}if(typeof Worker>"u")throw Error(`${kX} worker: true but Worker API is unavailable`);let W=await Z0(void 0),V=await DX.open(Z.state,W,{readyTimeoutMs:Z.readyTimeoutMs,clock:X,syncDebounceMs:Z.syncDebounceMs});return console.info(`${kX} worker-mode client open (sync Worker starts on setSeed via Enclave)`),{client:V,mode:"worker",dispose:()=>{console.info(`${kX} terminating sync worker`),V.terminate()}}}function UK(Z){if("store"in Z)return Z.store;return}async function uK(Z,X,W){let V=new vZ(Z,X,W,rX,SZ);return{client:V,mode:"main",dispose:()=>{V.disconnect()}}}async function Z0(Z){if(Z!==void 0)return Z;if(typeof indexedDB>"u")throw Error(`${kX} IndexedDB is unavailable; pass store explicitly (e.g. new MemoryStore(crypto))`);return zW(SZ)}function OK(Z){let[X,W]=iV();return SW(()=>{async function V(){let K=await Z.clientState.get();W(K)}let l=Z.clientState.listen(V);return V(),()=>{l()}},[Z]),X}function jK(Z){let[X,W]=iV();return SW(()=>{async function V(){let K=await Z.xferState.get();W(K)}let l=Z.xferState.listen(V);return V(),()=>{l()}},[Z]),X}function BK(Z){SW(()=>{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 EK(Z={}){let X=Z.clock??new pZ,{seed:W,host:V,readyTimeoutMs:l}=Z,K=Z.worker===!0,G="store"in Z?Z.store:void 0,[m,R]=iV({stateMgr:qW});return SW(()=>{let J=!1,C;return(async()=>{let F=await eW();if(J)return;let b=WW(F),c=K?await hW({state:b,clock:X,worker:!0,readyTimeoutMs:l}):await hW({state:b,clock:X,store:G,readyTimeoutMs:l});if(J){c.dispose();return}C=c.dispose;let{client:k,mode:T}=c;if(W)await k.setSeed(W);if(V)await k.link(V);if(J){C();return}R({client:k,entDB:F,stateMgr:b,mode:T,error:void 0})})().catch((F)=>{let b=F instanceof Error?F:Error(String(F));if(console.error("[DIPLOMATIC] useClient init failed",b),!J)R((c)=>({...c,client:void 0,error:b}))}),()=>{J=!0,C?.()}},[X,W,V,K,G,l]),m}import{use as wK,useEffect as X0,useRef as DK,useState as AK}from"react";function W0(Z,X,W){let[V,l]=AK();return X0(()=>{async function K(){let G=await W();l(G)}return K(),Z.on(X,K),()=>{Z.off(X,K)}},[Z,X,W]),V}function oK(Z,X,W){let V=DK(W());return X0(()=>{async function l(){V.current=W()}return Z.on(X,l),()=>{Z.off(X,l)}},[Z,X,W]),wK(V.current)}function V0(Z,X){return`${Z}:${X}`}class UV{queue=new Map;async enq(Z){for(let X of Z){let W=V0(X.host,X.seq);this.queue.set(W,X)}}async deq(Z,X){for(let W of X){let V=V0(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 nK(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 uV{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;nK(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 OV{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 uZ(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&&RX(K.apld)!==X)continue;let G=t(l);V.push(await uZ(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(RX(W.apld)===Z)X++;return X}async listKeys(){let Z=[];for(let X of this.messages.keys())Z.push(t(X));return Z}async last(Z){let X;for(let[W,V]of this.messages){if(e(Z,V.eid)===!1)continue;let l=t(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 uZ(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;nZ(W,UZ)}}async markFailed(Z){for(let{key:X,err:W}of Z){let V=this.messages.get(g(X));if(!V)continue;nZ(V,cZ,W)}}async wipe(){this.messages.clear()}}class jV{enclave;async save(Z,X){return this.enclave=Z,this.enclave}async load(){return this.enclave}async wipe(){this.enclave=void 0}}class BV{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(GZ(V))}async deq(Z,X){let W=this.queue.get(Z);if(W)for(let V of X)W.delete(GZ(V))}async list(Z){let X=this.queue.get(Z);if(!X)return[];let W=[];for(let V of X)W.push(iZ(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 l0{seed=new jV;hosts=new uV;uploads=new BV;downloads=new UV;messages;constructor(Z){this.messages=new OV(Z)}async wipe(){await this.hosts.wipe(),await this.uploads.wipe(),await this.downloads.wipe(),await this.messages.wipe()}}class K0{singletonType;latest;latestOff=-1;emitter=new gZ;constructor(Z){this.singletonType=Z}async apply(Z){for(let X of Z){let W=new P(X.eid),[V,l]=W.readStruct(_);if(l!==0)continue;let K=new i;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 G0={capable(){return $l()},async createCred(Z){return TW(Z)},async write(Z,X,W){return jX(Z,X,W)},async read(Z,X){let[W,V]=await IW(Z,X);if(V!==0||W===void 0)return Y(V);return d(W.blob)}};class m0{#W;#Z;#X;#V;#l;constructor(Z){if(this.#W=Z.crypto,this.#V=Z.rpId,this.#l=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.#V,rpName:this.#l,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 $.fromLargeBlob(this.#W,{rpId:this.#V,rpName:this.#l,credId:Z});if(W!==0||X===void 0)return Y(W);return this.#Z=X.enclave,d(X.enclave)}async wipe(){let Z=this.#X;if(Z!==void 0){let X=await $.clearLargeBlob(Z,{rpId:this.#V});if(X!==0)return Promise.reject(Error(`clearLargeBlob status ${X}`))}this.#Z=void 0,this.#X=void 0}}var TX=1,AX={encode(Z,X){let W=Z.writeVarInt(X.v);if(W!==0)return W;let V=Z.writeVarBytes(X.salt);if(V!==0)return V;let l=Z.writeVarBytes(X.credId);if(l!==0)return l;return Z.writeVarBytes(X.body)},decode(Z){let[X,W]=Z.readVarInt();if(W!==0)return Y(W);if(X===void 0)return Y(14);let[V,l]=Z.readVarBytes();if(l!==0)return Y(l);if(V===void 0)return Y(14);let[K,G]=Z.readVarBytes();if(G!==0)return Y(G);if(K===void 0)return Y(14);let[m,R]=Z.readVarBytes();if(R!==0)return Y(R);if(m===void 0)return Y(14);return d({v:X,salt:V,credId:K,body:m})}};var NW={PREFIX:"dip1:",VERSION:TX,async seal(Z,X,W,V){let[l,K]=await X.sealPairPackageBody(W,V);if(K!==0)return Y(K);if(l===void 0)return Y(12);let G=new i,m=G.writeStruct(AX,{v:TX,salt:l.salt,credId:l.credId,body:l.body});if(m!==0)return Y(m);return d(NW.PREFIX+uW(G.result()))},async open(Z,X,W){let V=X.trim();if(!V.startsWith(NW.PREFIX))return Y(10);let l;try{l=OW(V.slice(NW.PREFIX.length))}catch{return Y(10)}let K=new P(l),[G,m]=K.readStruct(AX);if(m!==0)return Y(m);if(G===void 0)return Y(14);if(G.v!==TX)return Y(14);let[R,J]=await $.openPairPackageBody(Z,G.body,{...W,salt:G.salt,credId:G.credId.byteLength>0?G.credId:void 0});if(J!==0)return Y(J);if(R===void 0)return Y(12);return d({enclave:R.enclave,hosts:R.hosts,salt:G.salt.slice(),credId:R.credId,sealedMaster:R.sealedMaster})}};async function k2(Z,X){let W=await zW(SZ),V=new vZ(new pZ,Z,W,rX,SZ);return{client:V,setSeed:async(K)=>{let[G,m]=$.fromBytes(SZ,iZ(K));if(m!==0||G===void 0)throw Error(`invalid seed (${m})`);await W.seed.save(G),await W.hosts.add({handle:X,label:"host",idx:0}),await V.connect()}}}export{BK as useSyncOnResume,oK as useStateWatcherSuspense,W0 as useStateWatcher,jK as useClientXferState,OK as useClientState,EK as useClient,KW as shouldEmitItemProgress,nZ as setApld,EX as sealKeyFromPrf,ZV as revFromHead,hX as revFromEntity,QK as prfCapable,UX as pairPackagePlainCodec,AX as pairPackageEnvelopeCodec,zW as openIDBStore,eW as openEntDB,hW as openDiplomaticClient,qW as nullStateManager,r0 as nullEntDB,Fl as normalizeTags,s0 as isTombstone,WV as isTerminalApplyFailure,ZK as isPendingApply,D as isLiveEnt,e0 as isApldState,oZ as idleProgress,cW as identityBundleCodec,iZ as htob,rX as hostHTTPTransport,k2 as genWebClient,u0 as genSingletonEID,bX as evalPrf,WW as entStateManager,ml as encodeEntRev,_ as eidCodec,kW as defaultWebAuthnRpId,YX as defaultPeekProgressEvery,SZ as crypto,gV as createPrfCred,SV as createIdentityBundle,Gl as cmpBytes,WX as checksumSet,MX as checksumEntRevs,OZ as bundleHostCodec,GZ as btoh,uW as btob64url,g as btob64,OW as b64urltob,t as b64tob,LZ as asSealedMasterKey,ZZ as asMasterSeed,RX as apldFromStored,DX as WorkerClient,gZ as TypedEventEmitter,vZ as SyncClient,z as Status,zX as StateManager,K0 as SingletonStateManager,$W as SEALED_MASTER_KEY_LEN,QW as PrfSeedStore,m0 as PasskeySeedStore,NW as PairPackage,TX as PAIR_PACKAGE_VERSION,l0 as MemoryStore,dZ as MASTER_SEED_LEN,G0 as LargeBlob,iX as IDENTITY_BUNDLE_VERSION,PV as IDBStore,MW as IDBSeedStore,oW as HTTPTransport,tW as EntIDB,XW as EntDBMemory,i as Encoder,$ as Enclave,P as Decoder,BX as DEFAULT_PRF_SALT,pZ as Clock,SX as CachedEntDB,QZ as APLD_PENDING,cZ as APLD_ERROR,UZ as APLD_APPLIED};
|