{"version":3,"sources":["node_modules/browserify/node_modules/browser-pack/_prelude.js","src/entry.js","yasqe.bundled.min.js","lib/deparam.js","lib/grammar/_tokenizer-table.js","lib/grammar/tokenizer.js","lib/trie.js","node_modules/codemirror/addon/display/fullscreen.js","node_modules/codemirror/addon/edit/matchbrackets.js","node_modules/codemirror/addon/fold/brace-fold.js","node_modules/codemirror/addon/fold/foldcode.js","node_modules/codemirror/addon/fold/foldgutter.js","node_modules/codemirror/addon/fold/xml-fold.js","node_modules/codemirror/addon/hint/show-hint.js","node_modules/codemirror/addon/runmode/runmode.js","node_modules/codemirror/addon/search/searchcursor.js","node_modules/codemirror/lib/codemirror.js","node_modules/jquery/dist/jquery.js","node_modules/yasgui-utils/node_modules/store/store.js","node_modules/yasgui-utils/package.json","node_modules/yasgui-utils/src/main.js","node_modules/yasgui-utils/src/storage.js","node_modules/yasgui-utils/src/svg.js","package.json","src/autocompleters/autocompleterBase.js","src/autocompleters/classes.js","src/autocompleters/prefixes.js","src/autocompleters/properties.js","src/autocompleters/utils.js","src/autocompleters/variables.js","src/curl.js","src/defaults.js","src/imgs.js","src/main.js","src/prefixFold.js","src/prefixUtils.js","src/sparql.js","src/tokenUtils.js","src/tooltip.js","src/utils.js"],"names":["e","exports","module","define","amd","f","window","global","self","YASQE","t","n","r","s","o","u","a","require","i","Error","code","l","call","length",1,"./main.js",2,"$","deparam","params","coerce","obj","coerce_types","true","false","null","each","replace","split","j","v","val","param","key","decodeURIComponent","cur","keys","keys_last","test","shift","concat","isNaN","undefined","isArray","push","jquery",3,"table","*[&&,valueLogical]","&&","AS",")",",","||",";","*[,,expression]","*[,,objectPath]",".","]","{","OPTIONAL","MINUS","GRAPH","SERVICE","FILTER","BIND","VALUES","}","*[,,object]","*[/,pathEltOrInverse]","/","|","(","[","VAR1","VAR2","NIL","IRI_REF","TRUE","FALSE","BLANK_NODE_LABEL","ANON","PNAME_LN","PNAME_NS","STRING_LITERAL1","STRING_LITERAL2","STRING_LITERAL_LONG1","STRING_LITERAL_LONG2","INTEGER","DECIMAL","DOUBLE","INTEGER_POSITIVE","DECIMAL_POSITIVE","DOUBLE_POSITIVE","INTEGER_NEGATIVE","DECIMAL_NEGATIVE","DOUBLE_NEGATIVE","*[;,?[or([verbPath,verbSimple]),objectList]]","*[;,?[verb,objectList]]","*[UNION,groupGraphPattern]","UNION","*[graphPatternNotTriples,?.,?triplesBlock]","*[quadsNotTriples,?.,?triplesTemplate]","*[|,pathOneInPropertySet]","*[|,pathSequence]","*[||,conditionalAndExpression]","*dataBlockValue","UNDEF","*datasetClause","FROM","WHERE","*describeDatasetClause","ORDER","HAVING","GROUP","LIMIT","OFFSET","*graphNode","*graphNodePath","*groupCondition","STR","LANG","LANGMATCHES","DATATYPE","BOUND","IRI","URI","BNODE","RAND","ABS","CEIL","FLOOR","ROUND","CONCAT","STRLEN","UCASE","LCASE","ENCODE_FOR_URI","CONTAINS","STRSTARTS","STRENDS","STRBEFORE","STRAFTER","YEAR","MONTH","DAY","HOURS","MINUTES","SECONDS","TIMEZONE","TZ","NOW","UUID","STRUUID","MD5","SHA1","SHA256","SHA384","SHA512","COALESCE","IF","STRLANG","STRDT","SAMETERM","ISIRI","ISURI","ISBLANK","ISLITERAL","ISNUMERIC","SUBSTR","REPLACE","REGEX","EXISTS","NOT","*havingCondition","*or([[ (,*dataBlockValue,)],NIL])","*or([[*,unaryExpression],[/,unaryExpression]])","*","=","!=","<",">","<=",">=","IN","+","-","*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])","*or([baseDecl,prefixDecl])","BASE","PREFIX","CONSTRUCT","DESCRIBE","ASK","INSERT","DELETE","SELECT","LOAD","CLEAR","DROP","ADD","MOVE","COPY","CREATE","WITH","*or([var,[ (,expression,AS,var,)]])","*orderCondition","ASC","DESC","*usingClause","USING","*var","*varOrIRIref","+graphNode","+graphNodePath","+groupCondition","+havingCondition","+or([var,[ (,expression,AS,var,)]])","+orderCondition","+varOrIRIref","?.","?DISTINCT","DISTINCT","!","COUNT","SUM","MIN","MAX","AVG","SAMPLE","GROUP_CONCAT","?GRAPH","?SILENT","SILENT","?SILENT_1","?SILENT_2","DEFAULT","NAMED","ALL","?SILENT_3","?SILENT_4","?WHERE","?[,,expression]","?[.,?constructTriples]","?[.,?triplesBlock]","?[.,?triplesTemplate]","?[;,SEPARATOR,=,string]","?[;,update]","?[AS,var]","?[INTO,graphRef]","INTO","?[or([verbPath,verbSimple]),objectList]","^","?[pathOneInPropertySet,*[|,pathOneInPropertySet]]","?[update1,?[;,update]]","?[verb,objectList]","?argList","?constructTriples","?groupClause","?havingClause","?insertClause","?limitClause","?limitOffsetClauses","?offsetClause","?or([DISTINCT,REDUCED])","REDUCED","?or([LANGTAG,[^^,iriRef]])","LANGTAG","^^","?or([[*,unaryExpression],[/,unaryExpression]])","?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])","?orderClause","?pathMod","?","?triplesBlock","?triplesTemplate","?whereClause","[ (,*dataBlockValue,)]","[ (,*var,)]","[ (,expression,)]","[ (,expression,AS,var,)]","[!=,numericExpression]","[&&,valueLogical]","[*,unaryExpression]","[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]","[+,multiplicativeExpression]","[,,expression]","[,,integer,}]","[,,objectPath]","[,,object]","[,,or([},[integer,}]])]","[-,multiplicativeExpression]","[.,?constructTriples]","[.,?triplesBlock]","[.,?triplesTemplate]","[/,pathEltOrInverse]","[/,unaryExpression]","[;,?[or([verbPath,verbSimple]),objectList]]","[;,?[verb,objectList]]","[;,SEPARATOR,=,string]","[;,update]","[<,numericExpression]","[<=,numericExpression]","[=,numericExpression]","[>,numericExpression]","[>=,numericExpression]","[AS,var]","[IN,expressionList]","[INTO,graphRef]","[NAMED,iriRef]","[NOT,IN,expressionList]","[UNION,groupGraphPattern]","[^^,iriRef]","[constructTemplate,*datasetClause,whereClause,solutionModifier]","[deleteClause,?insertClause]","[graphPatternNotTriples,?.,?triplesBlock]","[integer,or([[,,or([},[integer,}]])],}])]","[integer,}]","[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]","[or([verbPath,verbSimple]),objectList]","[pathOneInPropertySet,*[|,pathOneInPropertySet]]","[quadsNotTriples,?.,?triplesTemplate]","[update1,?[;,update]]","[verb,objectList]","[|,pathOneInPropertySet]","[|,pathSequence]","[||,conditionalAndExpression]","add","additiveExpression","aggregate","allowBnodes","allowVars","argList","askQuery","baseDecl","bind","blankNode","blankNodePropertyList","blankNodePropertyListPath","booleanLiteral","brackettedExpression","builtInCall","clear","collection","collectionPath","conditionalAndExpression","conditionalOrExpression","constraint","constructQuery","constructTemplate","constructTriples","copy","create","dataBlock","dataBlockValue","datasetClause","defaultGraphClause","delete1","DATA","deleteClause","describeDatasetClause","describeQuery","disallowBnodes","disallowVars","drop","existsFunc","expression","expressionList","filter","functionCall","graphGraphPattern","graphNode","graphNodePath","graphOrDefault","graphPatternNotTriples","graphRef","graphRefAll","graphTerm","groupClause","groupCondition","groupGraphPattern","groupGraphPatternSub","groupOrUnionGraphPattern","havingClause","havingCondition","inlineData","inlineDataFull","inlineDataOneVar","insert1","insertClause","integer","iriRef","iriRefOrFunction","limitClause","limitOffsetClauses","load","minusGraphPattern","modify","move","multiplicativeExpression","namedGraphClause","notExistsFunc","numericExpression","numericLiteral","numericLiteralNegative","numericLiteralPositive","numericLiteralUnsigned","object","objectList","objectListPath","objectPath","offsetClause","optionalGraphPattern","or([*,expression])","or([+or([var,[ (,expression,AS,var,)]]),*])","or([+varOrIRIref,*])","or([ASC,DESC])","or([DISTINCT,REDUCED])","or([LANGTAG,[^^,iriRef]])","or([NIL,[ (,*var,)]])","or([[ (,*dataBlockValue,)],NIL])","or([[ (,expression,)],NIL])","or([[*,unaryExpression],[/,unaryExpression]])","or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])","or([[,,or([},[integer,}]])],}])","or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])","or([[constructTemplate,*datasetClause,whereClause,solutionModifier],[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]])","or([[deleteClause,?insertClause],insertClause])","or([[integer,or([[,,or([},[integer,}]])],}])],[,,integer,}]])","or([baseDecl,prefixDecl])","or([defaultGraphClause,namedGraphClause])","or([inlineDataOneVar,inlineDataFull])","or([iriRef,[NAMED,iriRef]])","or([iriRef,a])","or([numericLiteralPositive,numericLiteralNegative])","or([queryAll,updateAll])","or([selectQuery,constructQuery,describeQuery,askQuery])","or([subSelect,groupGraphPatternSub])","or([var,[ (,expression,AS,var,)]])","or([verbPath,verbSimple])","or([},[integer,}]])","orderClause","orderCondition","path","pathAlternative","pathElt","pathEltOrInverse","pathMod","pathNegatedPropertySet","pathOneInPropertySet","pathPrimary","pathSequence","prefixDecl","prefixedName","primaryExpression","prologue","propertyList","propertyListNotEmpty","propertyListPath","propertyListPathNotEmpty","quadData","quadDataNoBnodes","quadPattern","quadPatternNoBnodes","quads","quadsNotTriples","queryAll","rdfLiteral","regexExpression","relationalExpression","selectClause","selectQuery","serviceGraphPattern","solutionModifier","sourceSelector","sparql11","storeProperty","strReplaceExpression","string","subSelect","substringExpression","triplesBlock","triplesNode","triplesNodePath","triplesSameSubject","triplesSameSubjectPath","triplesTemplate","unaryExpression","update","update1","updateAll","usingClause","valueLogical","valuesClause","var","varOrIRIref","varOrTerm","verb","verbPath","verbSimple","whereClause","keywords","punct","startSymbol","acceptEmpty",4,"CodeMirror","defineMode","config","getPossibles","symbol","possibles","possiblesOb","ll1_table","property","toString","tokenBase","stream","state","nextToken","consumed","inLiteral","closingQuotes","match","stringLiteralLongRegex","contents","regex","closing","returnObj","quotePos","cat","STRING_LITERAL_LONG","CAT","style","complete","text","start","quoteType","quotes","terminals","name","grammar","current","toUpperCase","recordFailurePos","col","column","errorStartPos","errorEndPos","tokenOb","setQueryType","queryType","setSideConditions","topSymbol","checkSideConditions","pos","possibleCurrent","possibleNext","OK","finished","token","stack","pop","nextSymbols","allNillable","sp","item","lastProperty","indexOf","lastPredicateOffset","indent","textAfter","closeBracket","substr","dn","indentTop","indentTable","indentUnit","PN_CHARS_BASE","PN_CHARS_U","PN_CHARS","VARNAME","PN_PREFIX","HEX","PERCENT","PN_LOCAL_ESC","PLX","PN_LOCAL","EXPONENT","ECHAR","hex4","unicode","SINGLE","QUOTES","CONTENTS","COMPLETE","RegExp","WS","COMMENT","WS_OR_COMMENT_STAR","*[,, object]","*[(,),object]","*[(,),objectPath]","startState","tokenize","electricChars","defineMIME","./_tokenizer-table.js","codemirror",5,"Trie","this","words","prefixes","children","prototype","insert","str","k","child","T","remove","strOld","strNew","countWord","ret","countPrefix","find","getAllWords","autoComplete",6,"mod","setFullscreen","cm","wrap","getWrapperElement","fullScreenRestore","scrollTop","pageYOffset","scrollLeft","pageXOffset","width","height","className","document","documentElement","overflow","refresh","setNormal","info","scrollTo","defineOption","old","Init","../../lib/codemirror",7,"findMatchingBracket","where","strict","line","getLineHandle","ch","matching","charAt","dir","getTokenTypeAt","Pos","found","scanForBracket","from","to","forward","maxScanLen","maxScanLineLength","maxScanLines","re","bracketRegex","lineEnd","Math","min","lastLine","max","firstLine","lineNo","getLine","end","matchBrackets","autoclear","maxHighlightLen","maxHighlightLineLength","marks","ranges","listSelections","empty","head","markText","ie_lt8","focused","display","input","focus","operation","setTimeout","doMatchBrackets","currentlyHighlighted","navigator","userAgent","documentMode","off","on","defineExtension",8,"registerHelper","findOpening","openCh","at","pass","lineText","lastIndexOf","tokenType","startCh","startToken","endToken","endCh","count","outer","nextOpen","nextClose","hasImport","getTokenAt","type","semi","prev","has","next","clipPos","hasInclude","slice",9,"doFold","options","force","getRange","allowFolded","range","finder","minSize","findMarksAt","__isFold","cleared","getOption","myWidget","makeWidget","myRange","e_preventDefault","replacedWith","clearOnEnter","signal","widget","createTextNode","createElement","appendChild","editorOptions","foldOptions","defaultOptions","newFoldFunction","rangeFinder","commands","toggleFold","foldCode","getCursor","fold","unfold","foldAll","unfoldAll","funcs","Array","arguments","helpers","getHelpers","auto","minFoldSize","scanUp",10,"State","parseOptions","opts","gutter","indicatorOpen","indicatorFolded","isFolded","marker","spec","elt","cloneNode","updateFoldInfo","foldGutter","foldOption","func","eachLine","mark","setGutterMarker","updateInViewport","vp","getViewport","onGutterClick","onChange","clearTimeout","changeUpdate","foldOnChangeTimeSpan","onViewportChange","updateViewportTimeSpan","onFold","clearGutter","./foldcode",11,"cmp","b","Iter","tagAt","iter","nextLine","prevLine","toTagEnd","gt","lastSlash","selfClose","toTagStart","lt","xmlTagStart","lastIndex","exec","index","toNextTag","toPrevTag","findMatchingClose","tag","startLine","findMatchingOpen","endLine","nameStartChar","nameChar","openTag","close","findMatchingTag","here","open","findEnclosingTag","scanForClosingTag",12,"Completion","buildOptions","onClose","getText","completion","buildKeyMap","handle","addBinding","bound","baseMap","hasOwnProperty","ourMap","Up","moveFocus","Down","PageUp","menuSize","PageDown","Home","setFocus","End","Enter","pick","Tab","Esc","custom","customKeys","extra","extraKeys","getHintElement","hintsElement","el","nodeName","parentNode","Widget","data","hints","selectedHint","completions","list","HINT_ELEMENT_CLASS","ACTIVE_HINT_ELEMENT_CLASS","render","displayText","hintId","cursorCoords","alignWithWord","left","top","bottom","below","winW","innerWidth","body","offsetWidth","winH","innerHeight","offsetHeight","container","box","getBoundingClientRect","overlapY","curTop","cursor","overlapX","right","addKeyMap","keyMap","avoidWrap","changeActive","screenAmount","closeOnUnfocus","closingOnBlur","onBlur","onFocus","startScroll","getScrollInfo","onScroll","curScroll","editor","newTop","point","target","srcElement","completeOnSingleClick","firstChild","showHint","getHints","async","newOpts","hint","prop","somethingSelected","completionActive","showHints","active","replaceRange","completeSingle","showWidget","done","activity","finishUpdate","data_","clearDebounce","debounce","cancelAnimationFrame","startPos","startLen","closeOn","requestAnimationFrame","closeCharacters","fn","hintOptions","out","removeChild","removeKeyMap","node","childNodes","offsetTop","clientHeight","floor","getHelper","fromList","anyword","word","autocomplete",13,"runMode","modespec","callback","mode","getMode","defaults","ie","ie_lt9","nodeType","tabSize","innerHTML","content","idx","size","lines","splitLines","StringStream","blankLine","eol",14,"SearchCursor","doc","query","caseFold","atOccurrence","source","ignoreCase","matches","reverse","cutOff","newMatch","matchLen","origQuery","toLowerCase","orig","adjustPos","origTarget","last","ln","cut","folded","pos1","len1","findNext","findPrevious","savePosAndFail","maxLine","lineCount","newText","defineDocExtension","getSearchCursor","cmpPos","anchor","setSelections",15,"place","copyObj","setGuttersForLineNumbers","value","Doc","Display","wrapper","updateGutters","themeChanged","lineWrapping","autofocus","mobile","focusInput","initScrollbars","keyMaps","overlays","modeGen","overwrite","suppressEdits","pasteIncoming","cutIncoming","draggingText","highlight","Delayed","keySeq","ie_version","resetInput","registerEventHandlers","ensureGlobalHandlers","startOperation","curOp","forceUpdate","attachDoc","activeElt","opt","optionHandlers","maybeUpdateLineNumberWidth","initHooks","endOperation","webkit","getComputedStyle","lineDiv","textRendering","d","setAttribute","ios","border","inputDiv","scrollbarFiller","gutterFiller","selectionDiv","cursorDiv","measure","lineMeasure","lineSpace","mover","sizer","sizerWidth","heightForcer","scrollerGap","gutters","lineGutter","scroller","zIndex","paddingRight","draggable","khtml","position","viewFrom","viewTo","first","reportedViewFrom","reportedViewTo","view","renderedView","externalMeasured","viewOffset","lastWrapHeight","lastWrapWidth","updateLineNumbers","nativeBarWidth","barHeight","barWidth","scrollbarsClipped","lineNumWidth","lineNumInnerWidth","lineNumChars","prevInput","alignWidgets","pollingFast","poll","cachedCharWidth","cachedTextHeight","cachedPaddingH","inaccurateSelection","maxLineLength","maxLineChanged","wheelDX","wheelDY","wheelStartX","wheelStartY","selForContextMenu","loadMode","modeOption","resetModeState","stateAfter","styles","frontier","startWorker","regChange","wrappingChanged","addClass","minWidth","rmClass","findMaxLine","estimateLineHeights","clearCaches","updateScrollbars","estimateHeight","th","textHeight","wrapping","perLine","clientWidth","charWidth","lineIsHidden","widgetsHeight","widgets","ceil","est","estHeight","updateLineHeight","theme","guttersChanged","alignHorizontally","specs","removeChildren","gutterClass","gElt","updateGutterSpace","marginLeft","lineLength","merged","len","collapsedSpanAtStart","collapsedSpanAtEnd","lineNumbers","splice","measureForScrollbars","gutterW","docH","round","paddingVert","viewHeight","scrollWidth","viewWidth","barLeft","fixedGutter","docHeight","scrollHeight","scrollGap","gutterWidth","NativeScrollbars","scroll","vert","horiz","checkedOverlay","minHeight","NullScrollbars","scrollbars","scrollbarModel","scrollbarStyle","insertBefore","axis","setScrollLeft","setScrollTop","startWidth","startHeight","updateScrollbarsInner","updateHeightsInViewport","sizes","paddingBottom","coverGutterNextToScrollbar","visibleLines","viewport","paddingTop","lineAtHeight","ensure","ensureFrom","ensureTo","heightAtLine","comp","compensateForHScroll","hidden","align","alignable","lineNumberFor","innerW","padding","String","lineNumberFormatter","firstLineNumber","DisplayUpdate","visible","editorIsHidden","wrapperHeight","wrapperWidth","oldDisplayWidth","displayWidth","dims","getDimensions","maybeClipScrollbars","marginBottom","borderRightWidth","updateDisplayIfNeeded","resetView","countDirtyView","viewportMargin","sawCollapsedSpans","visualLineNo","visualLineEndNo","different","adjustView","toUpdate","patchDisplay","postUpdateDisplay","displayHeight","barMeasure","updateSelection","setDocumentHeight","signalLater","updateDisplaySimple","total","prevBottom","bot","diff","updateWidgetHeight","rest","gutterLeft","clientLeft","nextSibling","offsetLeft","fixedPos","gutterTotalWidth","updateNumbersFrom","rm","mac","currentWheelTarget","lineN","lineView","updateNumber","lineNumber","changes","updateLineForChanges","buildLineElement","updateLineText","updateLineGutter","updateLineClasses","updateLineWidgets","ensureLineWrapped","replaceChild","updateLineBackground","cls","bgClass","background","getLineContent","ext","built","buildLineContent","pre","textClass","wrapClass","markers","gutterMarkers","gutterWrap","id","insertLineWidgets","insertLineWidgetsFor","allowAbove","ws","handleMouseEvents","positionLineWidget","above","noHScroll","coverGutter","paddingLeft","copyPos","x","maxPos","minPos","Selection","primIndex","Range","normalizeSelection","prim","sort","inv","simpleSelection","clipLine","clipToLen","linelen","isLine","clipPosArray","array","extendRange","other","extend","posBefore","extendSelection","setSelection","sel","primary","extendSelections","heads","newSel","replaceOneSelection","setSimpleSelection","filterSelectionChange","setSelectionReplaceHistory","history","lst","setSelectionNoUndo","addSelectionToHistory","NaN","hasHandler","bias","setSelectionInner","skipAtomicInSelection","ensureCursorVisible","equals","updateInput","selectionChanged","signalCursorActivity","reCheckSelection","sel_dontScroll","mayClear","newAnchor","skipAtomic","newHead","flipped","curPos","cantEdit","search","markedSpans","m","inclusiveLeft","inclusiveRight","explicitlyCleared","atomic","newPos","drawSelection","result","curFragment","cursors","createDocumentFragment","selFragment","selection","collapsed","showCursorWhenSelecting","drawSelectionCursor","drawSelectionRange","moveInputWithCursor","headPos","wrapOff","lineOff","teTop","teLeft","showSelection","drawn","removeChildrenAndAdd","output","singleCursorHeightPerLine","cursorHeight","otherCursor","fragment","rightSide","drawForLine","fromArg","toArg","coords","charCoords","lineObj","lineLen","iterateBidiSections","getOrder","rightPos","leftPos","tmp","leftSide","paddingH","sFrom","sTo","fromLine","toLine","singleVLine","visualLine","leftEnd","rightStart","restartBlink","clearInterval","blinker","visibility","cursorBlinkRate","setInterval","time","set","highlightWorker","Date","workTime","copyState","getStateBefore","changedLines","oldStyles","highlighted","highlightLine","oldCls","styleClasses","newCls","classes","ischange","processLine","workDelay","runInOp","regLineChange","findStartLine","precise","minindent","minline","lim","innerMode","indented","countColumn","save","currentStyle","parseInt","ensureLineHeights","rect","curWidth","heights","rects","getClientRects","abs","mapFromLineView","map","cache","maps","caches","before","updateExternalMeasurement","LineView","measureChar","measureCharPrepared","prepareMeasureForLine","findViewForLine","findViewIndex","hasHeights","prepared","varHeight","measureCharInner","bogus","rtop","rbottom","collapse","mStart","mEnd","insertLeft","isExtendingChar","nullRect","maybeUpdateRectForZooming","rSpan","rbot","mid","screen","logicalXDPI","deviceXDPI","hasBadZoomedRects","scaleX","scaleY","logicalYDPI","deviceYDPI","clearLineMeasurementCacheFor","clearLineMeasurementCache","externalMeasure","pageScrollX","pageScrollY","intoCoordSystem","context","widgetHeight","yOff","lOff","xOff","fromCoordSystem","localBox","lineSpaceBox","preparedMeasure","get","getBidi","partPos","part","order","level","bidiLeft","bidiRight","getBidiPartAt","bidiOther","estimateCoords","PosWithInfo","outside","xRel","coordsChar","y","coordsCharInner","mergedPos","getX","wrongLine","innerOff","adjust","bidi","dist","lineLeft","lineRight","fromX","fromOutside","toX","toOutside","moveVisually","xDiff","step","middle","middleX","measureText","viewChanged","typing","changeObjs","cursorActivityHandlers","cursorActivityCalled","updateMaxLine","scrollToPos","nextOpId","operationGroup","ops","ownsGroup","delayedCallbacks","fireCallbacksForOps","group","callbacks","op","endOperations","endOperation_R1","endOperation_W1","endOperation_R2","endOperation_W2","endOperation_finish","mustUpdate","updatedDisplay","adjustWidthTo","maxScrollLeft","newSelectionNodes","forceScroll","scrollPosIntoView","margin","isCursor","maybeScrollWindow","maybeHiddenMarkers","unhidden","maybeUnhiddenMarkers","apply","methodOp","docMethodOp","visualLineContinued","buildViewArray","nextPos","lendiff","viewCuttingPoint","cutTop","cutBot","arr","oldN","newN","dirty","slowPoll","pollInterval","readInput","fastPoll","p","changed","missed","hasSelection","isReadOnly","disableInput","fakedLastChar","substring","inputHasSelection","withOp","charCodeAt","same","inserted","textLines","multiPaste","lastCopied","join","changeEvent","origin","makeChange","smartIndent","getModeAt","changeEnd","indentLine","electricInput","contextMenuPending","minimal","selected","hasCopyEvent","getSelection","selectInput","readOnly","ensureFocus","drag_","signalDOMEvent","e_stop","prepareCopyCut","getSelections","lineRange","onMouseDown","posFromMouse","clickInGutter","eventInWidget","findWordAt","captureRightClick","onContextMenu","onScrollWheel","onKeyUp","onKeyDown","onKeyPress","dragDrop","onDragStart","onDrop","lastMiddleDown","selectionStart","selectionEnd","blur","onResize","setSize","e_target","getAttribute","liberal","forRect","space","clientX","clientY","colDiff","shiftKey","e_button","leftButtonDown","now","lastDoubleClick","lastClick","contained","modifier","metaKey","ctrlKey","dragAndDrop","contains","leftButtonStartDrag","leftButtonSelect","dragEnd","e2","addNew","extendTo","lastPos","startCol","posCol","findColumn","startSel","ourIndex","scrollIntoView","oldRange","ourRange","sel_mouse","curCount","counter","editorSize","Infinity","up","lastSelOrigin","altKey","gutterEvent","prevent","signalfn","mX","mY","lineBox","e_defaultPrevented","g","lastDrop","files","dataTransfer","FileReader","File","read","loadFile","file","reader","onload","change","readAsText","getData","replaceSelection","setData","setDragImage","safari","img","src","presto","_top","gecko","isScroller","delta","wheelEventDelta","dx","dy","wheelPixelsPerUnit","pixels","wheelSamples","movedX","movedY","sample","doHandleBinding","dropShift","prevShift","Pass","lookupKeyForEditor","lookupKey","dispatchKey","seq","isModifierKey","stopSeq","handleKeyBinding","keyName","motion","handleCharBinding","keyCode","returnValue","handled","lastStoppedKey","showCrossHair","charCode","which","fromCharCode","prepareSelectAllHack","extval","rehide","cssText","oldCSS","scrollPos","selectAll","detectingSelectAll","contextMenuInGutter","reset","resetSelectionOnContextMenu","oldScrollY","scrollY","mouseup","adjustForChange","computeSelAfterChange","offsetPos","nw","computeReplacedSel","oldPrev","newPrev","filterChange","canceled","cancel","ignoreReadOnly","sawReadOnlySpans","removeReadOnlyRanges","makeChangeInner","selAfter","addChangeToHistory","makeChangeSingleDoc","stretchSpansOverChange","rebased","linkedDocs","sharedHist","rebaseHist","makeChangeFromHistory","allowSelectionOnly","event","hist","undone","dest","lastOrigin","pushSelectionToHistory","clearRedo","antiChanges","generation","maxGeneration","historyChangeFromChange","after","mergeOldSpans","shiftDoc","distance","spans","removed","getBetween","makeChangeSingleDocInEditor","updateDoc","recomputeMaxLength","checkWidthStart","full","isWholeLineUpdate","changesHandler","changeHandler","doScroll","phantom","scrollNode","limit","endCoords","calculateScrollPos","startTop","startLeft","x1","y1","x2","y2","snapMargin","screentop","docBottom","atTop","atBottom","screenleft","screenw","tooWide","addToScrollPos","resolveScrollToPos","cursorScrollMargin","sPos","how","aggressive","curSpace","indentation","curSpaceString","indentString","indentWithTabs","spaceStr","changeLine","changeType","no","deleteNearSelection","compute","kill","toKill","replaced","findPosH","unit","visually","findNextLine","possible","moveOnce","boundToLine","moveLogically","origDir","sawType","helper","isWordChar","hitSide","findPosV","pageSize","option","deflt","notOnInit","normalizeKeyName","alt","ctrl","cmd","parts","getKeyMap","shared","markTextShared","TextMarker","clearWhenEmpty","widgetNode","conflictingCollapsedRange","addToHistory","curLine","addMarkedSpan","MarkedSpan","clearHistory","nextMarkerId","title","startStyle","endStyle","css","linked","isParent","SharedTextMarker","findSharedMarkers","findMarks","parent","copySharedMarkers","mFrom","mTo","subMark","detachSharedMarkers","subMarker","getMarkedSpanFor","span","removeMarkedSpan","attachLine","markedSpansBefore","isInsert","startsBefore","endsAfter","markedSpansAfter","oldFirst","oldLast","sameLine","offset","clearEmptySpans","newMarkers","gapMarkers","gap","getOldSpans","stretched","oldCur","stretchCur","mk","newParts","dfrom","dto","detachMarkedSpans","detachLine","attachMarkedSpans","extraLeft","extraRight","compareCollapsedMarkers","lenDiff","aPos","bPos","fromCmp","toCmp","collapsedSpanAtSide","sps","vis","lineIsHiddenInner","adjustScrollWhenAboveVisible","parentStyle","addLineWidget","LineWidget","insertAt","aboveVisible","updateLine","cleanUpLine","extractLineClasses","lineClass","callBlankLine","inner","readToken","takeToken","asArray","getObj","tokens","lineClasses","forceToEnd","flattenSpans","curStart","curStyle","addModeClass","maxHighlightLength","mName","st","overlay","i_end","opaque","getLineStyles","updateFrontier","startAt","interpretTokenStyle","styleToClassCacheWithMode","styleToClassCache","builder","addToken","buildToken","buildTokenSplitSpaces","hasBadBidiRects","buildTokenBadBidi","allowFrontierUpdate","insertLineContent","joinClasses","zeroWidthElement","lastChild","defaultSpecialCharPlaceholder","special","specialChars","mustWrap","skipped","txt","tabWidth","specialCharPlaceholder","fullStyle","buildCollapsedSpan","ignoreWidget","allText","spanStyle","spanEndStyle","spanStartStyle","nextChange","foundBookmarks","upto","tokenText","wholeLineUpdateBefore","spansFor","linesFor","Line","lastText","lastSpans","nlines","added","LeafChunk","BranchChunk","chunkSize","sharedHistOnly","propagate","skip","rel","chunk","sz","getLines","h","lh","bidiOrdering","History","startGen","undoDepth","lastModTime","lastSelTime","lastOp","lastSelOp","histChange","attachLocalSpans","clearSelectionEvents","lastChangeEvent","opId","historyEventDelay","selectionEventCanBeMerged","existing","removeClearedSpans","copyHistoryArray","events","newGroup","instantiateSel","deepCopy","newChanges","Number","rebaseHistSelSingle","rebaseHistArray","sub","ok","copied","defaultPrevented","button","emitter","bnd","args","_handlers","orphanDelayedCallbacks","fireOrphanDelayed","delayed","override","preventDefault","codemirrorIgnore","cursorActivity","eventMixin","ctor","goal","nextTab","spaceStrs","createObj","base","props","inst","Object","isWordCharBasic","isEmpty","extendingChars","activeElement","classTest","as","forEachCodeMirror","getElementsByClassName","byClass","globalsRegistered","registerGlobalHandlers","resizeTimer","zwspSupported","badBidiRects","r0","r1","badZoomedRects","normal","fromRange","lineStart","visual","lineStartSmart","firstNonWS","inWS","compareBidiLevel","linedir","moveInLine","byUnit","ie_upto10","ie_11up","qtwebkit","chrome","vendor","mac_geMountainLion","platform","windows","presto_version","flipCtrlCmd","needsH","needsV","sWidth","totalHeight","totalWidth","overlayHack","w","barMouseDown","native","there","wheelDeltaX","wheelDeltaY","detail","HORIZONTAL_AXIS","VERTICAL_AXIS","wheelDelta","wheelEventPixels","constructor","setOption","getDoc","addOverlay","modeSpec","removeOverlay","indentSelection","newRanges","getLineTokens","help","helperType","_global","pred","getStateAfter","defaultTextHeight","defaultCharWidth","gutterID","removeLineWidget","lineInfo","addWidget","vspace","hspace","triggerOnKeyDown","triggerOnKeyPress","triggerOnKeyUp","execCommand","amount","moveH","extendSelectionsBy","rtlMoveVisually","sel_move","deleteH","goalColumn","moveV","goals","startChar","check","toggleOverwrite","hasFocus","interpret","oldHeight","swapDoc","getInputField","getScrollerElement","getGutterElement","setValue","detach","attach","disabled","tabIndex","modes","mimeModes","dependencies","mime","resolveMode","mfactory","modeObj","modeExtensions","exts","modeProps","skipToEnd","extendMode","properties","defineInitHook","registerGlobalHelper","predicate","nstate","a1","a2","singleSelection","killLine","deleteLine","delLineLeft","delWrappedLineLeft","delWrappedLineRight","undo","redo","undoSelection","redoSelection","goDocStart","goDocEnd","goLineStart","goLineStartSmart","goLineEnd","goLineRight","goLineLeft","goLineLeftSmart","goLineUp","goLineDown","goPageUp","goPageDown","goCharLeft","goCharRight","goColumnLeft","goColumnRight","goWordLeft","goGroupRight","goGroupLeft","goWordRight","delCharBefore","delCharAfter","delWordBefore","delWordAfter","delGroupBefore","delGroupAfter","indentAuto","indentMore","indentLess","insertTab","insertSoftTab","spaces","replaceSelections","defaultTab","transposeChars","newlineAndIndent","basic","Left","Right","Delete","Backspace","Shift-Backspace","Shift-Tab","Insert","pcDefault","Ctrl-A","Ctrl-D","Ctrl-Z","Shift-Ctrl-Z","Ctrl-Y","Ctrl-Home","Ctrl-End","Ctrl-Up","Ctrl-Down","Ctrl-Left","Ctrl-Right","Alt-Left","Alt-Right","Ctrl-Backspace","Ctrl-Delete","Ctrl-S","Ctrl-F","Ctrl-G","Shift-Ctrl-G","Shift-Ctrl-F","Shift-Ctrl-R","Ctrl-[","Ctrl-]","Ctrl-U","Shift-Ctrl-U","Alt-U","fallthrough","emacsy","Ctrl-B","Ctrl-P","Ctrl-N","Alt-F","Alt-B","Ctrl-E","Ctrl-V","Shift-Ctrl-V","Ctrl-H","Alt-D","Alt-Backspace","Ctrl-K","Ctrl-T","macDefault","Cmd-A","Cmd-D","Cmd-Z","Shift-Cmd-Z","Cmd-Y","Cmd-Home","Cmd-Up","Cmd-End","Cmd-Down","Cmd-Left","Cmd-Right","Ctrl-Alt-Backspace","Alt-Delete","Cmd-S","Cmd-F","Cmd-G","Shift-Cmd-G","Cmd-Alt-F","Shift-Cmd-Alt-F","Cmd-[","Cmd-]","Cmd-Backspace","Cmd-Delete","Cmd-U","Shift-Cmd-U","normalizeKeyMap","keymap","keyname","keyNames","noShift","altGraphKey","fromTextArea","textarea","getValue","tabindex","placeholder","form","leaveSubmitMethodAlone","realSubmit","submit","wrappedSubmit","getTextArea","toTextArea","lastColumnPos","lastColumnValue","sol","peek","eat","eatWhile","eatSpace","skipTo","backUp","pattern","consume","caseInsensitive","cased","hideFirstChars","side","dHeight","oldH","removeInner","insertInner","iterN","spilled","newleaf","maybeSpill","me","sibling","myIndex","used","nextDocId","cleanGeneration","lineSep","getLineNumber","getLineHandleVisualStart","setCursor","addSelection","dup","setExtending","getExtending","historySize","markClean","changeGeneration","forceSplit","isClean","gen","getHistory","setHistory","histData","addLineClass","removeLineClass","setBookmark","realOpts","getAllMarks","posFromIndex","indexFromPos","copyHistory","linkedDoc","unlinkDoc","link","splitIds","iterLinkedDocs","getEditor","dontDelegate","method","e_stopPropagation","stopPropagation","cancelBubble","addEventListener","attachEvent","removeEventListener","detachEvent","ms","startIndex","startValue","select","_e","nonASCIISingleCaseWordChar","createRange","setEnd","setStart","createTextRange","moveToElementText","moveEnd","moveStart","div","nl","rt","te","ownerDocument","parentElement","compareEndPoints","oncopy",16,17,18,19,20,27,32,33,34,35,36,37,38,39,40,44,45,46,59,61,91,92,93,107,109,127,173,186,187,188,189,190,191,192,219,220,221,222,63232,63233,63234,63235,63272,63273,63275,63276,63277,63302,"charType","lowTypes","arabicTypes","BidiSpan","bidiRE","isNeutral","isStrong","countsAsLeft","countsAsNum","outerType","types","nstart","unshift","version","factory","noGlobal","isArraylike","jQuery","isWindow","winnow","elements","qualifier","not","isFunction","grep","elem","risSimple","inArray","createOptions","optionsCache","rnotwhite","_","flag","completed","readyState","ready","dataAttr","rmultiDash","rbrace","parseJSON","isEmptyDataObject","isEmptyObject","internalData","pvt","acceptData","thisCache","internalKey","expando","isNode","deletedIds","guid","toJSON","noop","camelCase","internalRemoveData","cleanData","support","deleteExpando","returnTrue","returnFalse","safeActiveElement","err","createSafeFragment","nodeNames","safeFrag","getAll","elems","getElementsByTagName","strundefined","querySelectorAll","merge","fixDefaultChecked","rcheckableType","defaultChecked","checked","manipulationTarget","disableScript","attr","restoreScript","rscriptTypeMasked","removeAttribute","setGlobalEval","refElements","_data","cloneCopyEvent","hasData","oldData","curData","fixCloneNodeIssues","noCloneEvent","removeEvent","outerHTML","html5Clone","trim","defaultSelected","defaultValue","actualDisplay","appendTo","getDefaultComputedStyle","defaultDisplay","elemdisplay","iframe","contentWindow","contentDocument","write","addGetHookIf","conditionFn","hookFn","condition","vendorPropName","capName","origName","cssPrefixes","showHide","show","values","isHidden","setPositiveNumber","subtract","rnumsplit","augmentWidthOrHeight","isBorderBox","cssExpand","getWidthOrHeight","valueIsBorderBox","getStyles","boxSizing","curCSS","rnumnonpx","boxSizingReliable","parseFloat","Tween","easing","init","createFxNow","fxNow","genFx","includeWidth","attrs","opacity","createTween","animation","tween","tweeners","defaultPrefilter","toggle","hooks","oldfire","checkDisplay","anim","dataShow","queue","_queueHooks","unqueued","fire","always","overflowX","overflowY","inlineBlockNeedsLayout","zoom","shrinkWrapBlocks","rfxtypes","hide","_removeData","propFilter","specialEasing","cssHooks","expand","Animation","stopped","animationPrefilters","deferred","Deferred","tick","currentTime","remaining","startTime","duration","temp","percent","tweens","run","notifyWith","resolveWith","promise","originalProperties","originalOptions","stop","gotoEnd","rejectWith","fx","timer","progress","fail","addToPrefiltersOrTransports","structure","dataTypeExpression","dataType","dataTypes","inspectPrefiltersOrTransports","jqXHR","inspect","inspected","prefilterOrFactory","dataTypeOrTransport","seekingTransport","transports","ajaxExtend","deep","flatOptions","ajaxSettings","ajaxHandleResponses","responses","firstDataType","ct","finalDataType","mimeType","getResponseHeader","converters","ajaxConvert","response","isSuccess","conv2","conv","responseFields","dataFilter","error","buildParams","prefix","traditional","rbracket","createStandardXHR","XMLHttpRequest","createActiveXHR","ActiveXObject","getWindow","defaultView","parentWindow","class2type","hasOwn","selector","rtrim","rmsPrefix","rdashAlpha","fcamelCase","all","letter","toArray","num","pushStack","prevObject","eq","copyIsArray","clone","isPlainObject","random","isReady","msg","isNumeric","ownLast","globalEval","execScript","makeArray","results","second","invert","callbackInverse","callbackExpect","arg","proxy","Sizzle","seed","groups","nid","newContext","newSelector","preferredDoc","setDocument","documentIsHTML","rquickExpr","getElementById","qsa","rbuggyQSA","rescape","toSelector","rsibling","testContext","qsaError","createCache","Expr","cacheLength","markFunction","assert","addHandle","handler","attrHandle","siblingCheck","sourceIndex","MAX_NEGATIVE","createInputPseudo","createButtonPseudo","createPositionalPseudo","argument","matchIndexes","setFilters","addCombinator","matcher","combinator","checkNonElements","doneName","xml","oldCache","outerCache","newCache","dirruns","elementMatcher","matchers","multipleContexts","contexts","condense","unmatched","newUnmatched","mapped","setMatcher","preFilter","postFilter","postFinder","postSelector","preMap","postMap","preexisting","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","relative","implicitRelative","matchContext","matchAnyContext","outermostContext","matcherFromGroupMatchers","elementMatchers","setMatchers","bySet","byElement","superMatcher","outermost","matchedCount","setMatched","contextBackup","dirrunsUnique","uniqueSort","isXML","compile","sortInput","hasDuplicate","docElem","rbuggyMatches","classCache","tokenCache","compilerCache","sortOrder","push_native","booleans","whitespace","characterEncoding","identifier","attributes","pseudos","rwhitespace","rcomma","rcombinators","rattributeQuotes","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rinputs","rheader","rnative","runescape","funescape","escaped","escapedWhitespace","high","unloadHandler","els","hasCompare","createComment","getById","getElementsByName","attrId","getAttributeNode","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","expr","specified","duplicates","detectDuplicates","sortStable","textContent","nodeValue","selectors","createPseudo"," ","~","excess","unquoted","nodeNameSelector","operator","what","simple","ofType","nodeIndex","useCache","pseudo","matched","innerText","lang","elemLang","hash","location","root","href","enabled","selectedIndex","header","even","odd","radio","checkbox","password","image","filters","parseOnly","soFar","preFilters","cached","compiled","div1","unique","isXMLDoc","rneedsContext","rsingleTag","is","rootjQuery","parseHTML","rparentsprev","guaranteedUnique","until","targets","closest","prevAll","addBack","parents","parentsUntil","nextAll","nextUntil","prevUntil","siblings","Callbacks","firing","memory","fired","firingLength","firingIndex","firingStart","once","stopOnFalse","disable","lock","locked","fireWith","tuples","then","fns","newDefer","tuple","returned","resolve","reject","notify","pipe","stateString","when","subordinate","progressValues","progressContexts","resolveContexts","resolveValues","updateFunc","readyList","readyWait","holdReady","hold","wait","triggerHandler","frameElement","doScrollCheck","noData","applet ","embed ","object ","removeData","dequeue","startLength","setter","clearQueue","defer","pnum","access","chainable","emptyGet","raw","bulk","leadingWhitespace","tbody","htmlSerialize","appendChecked","noCloneChecked","checkClone","click","eventName","focusin","rformElems","rkeyEvent","rmouseEvent","rfocusMorph","rtypenamespace","handleObjIn","eventHandle","handleObj","handlers","namespaces","origType","elemData","triggered","dispatch","delegateType","bindType","namespace","delegateCount","setup","mappedTypes","origCount","teardown","trigger","onlyHandlers","ontype","bubbleType","eventPath","Event","isTrigger","namespace_re","noBubble","isPropagationStopped","isDefaultPrevented","_default","fix","handlerQueue","delegateTarget","preDispatch","currentTarget","isImmediatePropagationStopped","postDispatch","originalEvent","fixHook","fixHooks","mouseHooks","keyHooks","original","eventDoc","fromElement","pageX","pageY","clientTop","relatedTarget","toElement","beforeunload","simulate","bubble","isSimulated","timeStamp","stopImmediatePropagation","mouseenter","mouseleave","pointerenter","pointerleave","related","submitBubbles","_submit_bubble","changeBubbles","propertyName","_just_changed","focusinBubbles","attaches","one","origFn","rinlinejQuery","rnoshimcache","rleadingWhitespace","rxhtmlTag","rtagName","rtbody","rhtml","rnoInnerhtml","rchecked","rscriptType","rcleanScript","wrapMap","legend","area","thead","tr","td","safeFragment","fragmentDiv","optgroup","tfoot","colgroup","caption","dataAndEvents","deepDataAndEvents","destElements","srcElements","inPage","buildFragment","scripts","safe","nodes","append","domManip","prepend","keepData","html","replaceWith","hasScripts","iNoClone","_evalUrl","prependTo","insertAfter","replaceAll","shrinkWrapBlocksVal","rmargin","rposition","opener","computed","maxWidth","getPropertyValue","rs","rsLeft","runtimeStyle","pixelLeft","computeStyleTests","pixelPositionVal","boxSizingReliableVal","reliableMarginRightVal","marginRight","reliableHiddenOffsetsVal","cssFloat","backgroundClip","clearCloneStyle","MozBoxSizing","WebkitBoxSizing","reliableHiddenOffsets","pixelPosition","reliableMarginRight","swap","ralpha","ropacity","rdisplayswap","rrelNum","cssShow","cssNormalTransform","letterSpacing","fontWeight","cssNumber","columnCount","fillOpacity","flexGrow","flexShrink","lineHeight","orphans","widows","cssProps","float","$1","suffix","expanded","propHooks","eased","linear","swing","cos","PI","timerId","rfxnum","rrun","scale","maxIterations","tweener","prefilter","speed","speeds","fadeTo","animate","optall","doAnimation","finish","stopQueue","timers","cssFn","slideDown","slideUp","slideToggle","fadeIn","fadeOut","fadeToggle","interval","slow","fast","delay","timeout","getSetAttribute","hrefNormalized","checkOn","optSelected","enctype","optDisabled","radioValue","rreturn","valHooks","optionSet","nodeHook","boolHook","ruseDefault","getSetInput","removeAttr","nType","attrHooks","propName","attrNames","propFix","getter","setAttributeNode","createAttribute","contenteditable","rfocusable","rclickable","removeProp","for","class","notxml","rclass","clazz","finalValue","proceed","removeClass","toggleClass","stateVal","classNames","hasClass","hover","fnOver","fnOut","unbind","delegate","undelegate","nonce","rquery","rvalidtokens","JSON","parse","requireNonComma","depth","comma","Function","parseXML","DOMParser","parseFromString","loadXML","ajaxLocParts","ajaxLocation","rhash","rts","rheaders","rlocalProtocol","rnoContent","rprotocol","rurl","prefilters","allTypes","lastModified","etag","url","isLocal","processData","contentType","accepts","json","* text","text html","text json","text xml","ajaxSetup","settings","ajaxPrefilter","ajaxTransport","ajax","status","nativeStatusText","headers","success","modified","statusText","timeoutTimer","transport","responseHeadersString","ifModified","cacheURL","callbackContext","statusCode","fireGlobals","globalEventContext","completeDeferred","responseHeaders","requestHeaders","requestHeadersNames","strAbort","getAllResponseHeaders","setRequestHeader","lname","overrideMimeType","abort","finalText","crossDomain","hasContent","beforeSend","send","getJSON","getScript","throws","wrapAll","wrapInner","unwrap","r20","rCRLF","rsubmitterTypes","rsubmittable","encodeURIComponent","serialize","serializeArray","xhr","xhrId","xhrCallbacks","xhrSupported","cors","username","xhrFields","isAbort","onreadystatechange","responseText","script","text script","scriptCharset","charset","oldCallbacks","rjsonp","jsonp","jsonpCallback","originalSettings","callbackName","overwritten","responseContainer","jsonProp","keepScripts","parsed","_load","animated","setOffset","curPosition","curLeft","curCSSTop","curOffset","curCSSLeft","calculatePosition","curElem","using","win","offsetParent","parentOffset","Height","Width","defaultExtra","funcName","andSelf","_jQuery","_$","noConflict","isLocalStorageNameSupported","localStorageName","ieKeyFix","forbiddenCharsRegex","storage","store","scriptTag","transact","defaultVal","transactionFn","forEach","stringify","deserialize","setItem","getItem","removeItem","addBehavior","storageOwner","storageContainer","frames","withIEStorage","storeFunction","XMLDocument","testKey","description","main","repository","licenses","author","maintainers","email","web","bugs","homepage","console","log","svg","yasgui-utils","nestedExists","../package.json","./storage.js","./svg.js","times","day","month","year","exp","XMLSerializer","serializeToString","getTime","removeAll",21,"draw","svgString","getElement","parser","dom","svgContainer",22,"license","devDependencies","bootstrap-sass","browserify","browserify-transform-tools","exorcist","gulp","gulp-autoprefixer","gulp-bump","gulp-concat","gulp-connect","gulp-cssimport","gulp-embedlr","gulp-filter","gulp-git","gulp-jsvalidate","gulp-livereload","gulp-minify-css","gulp-notify","gulp-rename","gulp-sass","gulp-sourcemaps","gulp-streamify","gulp-tag-version","gulp-uglify","require-dir","run-sequence","vinyl-buffer","vinyl-source-stream","vinyl-transform","watchify","optionalShim",23,"utils","yutils","yasqe","completionNotifications","completers","tries","needPossibleAdjustment","notificationName","scrollBar","outerWidth","notification","storeBulkCompletions","completer","storageId","getPersistencyId","persistent","initCompleter","completionInit","storeArrayAsBulk","suggestions","completionsFromStorage","persistencyIdentifier","fromAutoShow","tryHintType","autoShow","hintConfig","wrappedHintCallback","getCompletionHintsObject","completerName","autocompleters","isValidCompletionPosition","validPosition","invalidPosition","getSuggestionsFromToken","partialToken","stringToAutocomplete","autocompletionString","partialTokenLength","getSuggestionsAsHintObject","getCompleteToken","preProcessToken","wrappedCallback","hintList","suggestedString","postProcessToken","selectHint","completionToken","notifications","getEl","autoshow","getTrie","../../lib/trie.js","../main.js","../utils.js",24,"fetchFromLov","previousToken","getPreviousNonWsToken","preprocessResourceTokenForCompletion","postprocessResourceTokenForCompletion","./utils","./utils.js",25,"tokenTypes","string-2","atom","appendPrefixIfNeeded","prefixArray","completeString","preprocessPrefixTokenForCompletion","collapsePrefixes","colonIndex","lastNonWsTokenString","currentPrefix","queryPrefixes","getPrefixesFromQuery","addPrefixes",26,"tokenPrefix","tokenPrefixUri","maxResults","q","page","updateUrl","increasePage","doRequests","uri","total_results","loader","../imgs.js",28,"distinctVars","variable","nextEl","nextElClass","variables",29,"sparql","quote","createCurlString","ajaxConfig","getAjaxConfig","endpoint","requestMethod","cmds","./sparql.js",30,"highlightSelectionMatches","showToken","tabMode","backdrop","combine","brace","collapsePrefixesOnLoad","syntaxErrorCheck","Ctrl-Space","Cmd-Space","Cmd-K","Ctrl-/","commentLines","Cmd-/","Ctrl-Alt-Down","copyLineDown","Ctrl-Alt-Up","copyLineUp","Cmd-Alt-Down","Cmd-Alt-Up","doAutoFormat","Shift-Cmd-F","storeQuery","Ctrl-Enter","executeQuery","Cmd-Enter","F11","createShareLink","createShortLink","consumeShareLink","showQueryButton","acceptHeaderGraph","acceptHeaderSelect","acceptHeaderUpdate","namedGraphs","defaultGraphs","getQueryForAjax",31,"queryInvalid","download","share","warning","fullscreen","smallscreen","imgs","rootEl","extendConfig","extendCmInstance","postProcessCmElement","extendedConfig","Autocompleters","lastQueryDuration","getNextNonWsToken","charNumber","findFirstPrefixLine","animateSpeed","setBackdrop","callbackOrConfig","getUrlArguments","removePrefixes","getValueWithoutComments","cleanedQuery","stringVal","getQueryType","getQueryMode","setCheckSyntaxErrors","isEnabled","checkSyntax","enableCompleter","addCompleterToSettings","disableCompleter","removeCompleterFromSettings","valueFromStorage","drawButtons","updateQueryButton","positionButtons","updateButtonsTransparency","prevQueryValid","matchText","getUrlParams","urlParams","buttons","elementsOverlap","deepcheck","queryValid","warningEl","expectedEncoded","expected","marginTop","registerAutocompleter","getAsCurl","curl","svgShare","popup","$input","protocol","host","pathname","$this","errString","shortLink","positions","outerHeight","toggleFullscreen","queryButtonIds","busy","valid","queryButton","queryStatus","c","textAreaEl","linesAreCommented","autoFormatRange","totalLines","totalChars","absStart","absEnd","res","autoFormatLineBreaks","breakAfterArray","breakAfterCharacters","breakBeforeCharacters","getBreakType","stackTrace","valueOf","currentLine","formattedQuery","breakType","../lib/deparam.js","../lib/grammar/tokenizer.js","./autocompleters/autocompleterBase.js","./autocompleters/classes.js","./autocompleters/prefixes.js","./autocompleters/properties.js","./autocompleters/variables.js","./curl.js","./defaults.js","./imgs.js","./prefixFold.js","./prefixUtils.js","./tokenUtils.js","./tooltip","codemirror/addon/display/fullscreen.js","codemirror/addon/edit/matchbrackets.js","codemirror/addon/fold/brace-fold.js","codemirror/addon/fold/foldcode.js","codemirror/addon/fold/foldgutter.js","codemirror/addon/fold/xml-fold.js","codemirror/addon/hint/show-hint.js","codemirror/addon/runmode/runmode.js","codemirror/addon/search/searchcursor.js","findFirstPrefix","lookFor","tokenUtils","hasPreviousPrefix","getLastPrefixPos","prefixKeywordToken","prefixShortname","prefixUri","prefixStart","stopAt","stopAtNextLine","prefixEndChar","prefixEndLine","nextPrefixDeclaration","existingPrefixes","addPrefixAsString","pref","prefixString","lastPrefix","lastPrefixLine","numLines","firstToken","previousIndent","getIndentFromLine","escapeRegex","shouldContinue","getPrefixesFromLine","lineOffset","colOffset","uriString","Accept","getAcceptHeader","handlerDefined","queryStart","updateYasqe","completeCallbacks","queryMode","argName","acceptHeader","qType","prevToken","tooltip","repositionTooltip","keyExists","objectToTest","exists","persistentIdCreator","persistencyId","getPositions","comparePositions","p1","p2","r2","pos2"],"mappings":"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OACAC,OACAC,YACAC,SACAC,SACAC,WACAC,UACAC,QACAC,UACAC,QACA+B,2BACA5C,KAAA,yBAAA,2BACAG,OACAC,OACAS,OACAL,SACAH,OACAC,YACAC,SACAE,WACAC,UACAC,QACAC,WACAiC,8BACAC,OAAA,4BAAA,8BACA1B,QACAC,QACAC,OACAJ,OACAC,OACAI,WACAC,QACAC,SACAC,oBACAC,QACAC,YACAC,YACAC,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACAvC,OACAE,OACAC,YACAC,SACAC,SACAC,WACAC,UACAC,QACAC,UACAC,QACAkC,8CACA1C,KAAA,4CAAA,8CACAC,UAAA,4CAAA,8CACAC,OAAA,4CAAA,8CACAC,OAAA,4CAAA,8CACAC,SAAA,4CAAA,8CACAC,QAAA,4CAAA,8CACAC,MAAA,4CAAA,8CACAC,QAAA,4CAAA,8CACAC,QACAmC,0CACAxC,OAAA,wCAAA,0CACAK,QACAoC,6BACAhC,KAAA,2BAAA,6BACApB,QACAqD,qBACAjC,KAAA,mBAAA,qBACApB,OACAqB,OACAC,OACAC,QACAC,QACAC,OACAC,WACAC,QACAC,SACAC,oBACAC,QACAC,YACAC,YACAC,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,oBACAS,kCACApD,MAAA,gCAAA,kCACAH,MACAC,OACAC,OACAE,QACAoD,mBACAC,OAAA,iBAAA,mBACA9B,SAAA,iBAAA,mBACAC,MAAA,iBAAA,mBACAC,OAAA,iBAAA,mBACAG,UAAA,iBAAA,mBACAC,UAAA,iBAAA,mBACAC,iBAAA,iBAAA,mBACAC,iBAAA,iBAAA,mBACAC,sBAAA,iBAAA,mBACAC,sBAAA,iBAAA,mBACAC,SAAA,iBAAA,mBACAC,SAAA,iBAAA,mBACAC,QAAA,iBAAA,mBACAC,kBAAA,iBAAA,mBACAC,kBAAA,iBAAA,mBACAC,iBAAA,iBAAA,mBACAC,kBAAA,iBAAA,mBACAC,kBA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BACAK,UAAA,iBAAA,mBACAC,UAAA,iBAAA,oBACAwI,gBACAjJ,MAAA,cAAA,gBACAC,MAAA,cAAA,gBACAE,SAAA,cAAA,gBACAK,UAAA,cAAA,gBACAC,UAAA,cAAA,iBACAyI,MACAnK,KAAA,KACAiB,QACAC,QACAC,OACAJ,OACAC,OACAI,WACAC,QACAC,SACAC,oBACAC,QACAC,YACAC,YACAC,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACAlC,SACAH,OACAC,YACAC,SACAE,WACAC,UACAC,QACAC,UACAC,QACA0J,aACAC,UAAA,YACAC,OACAtC,OACAC,OACAhH,QACAC,QACAH,OACAgD,OACAC,QACAC,eACAC,YACAC,SACAC,OACAC,OACAC,SACAC,QACAC,OACAC,QACAC,SACAC,SACAC,UACAC,UACAC,SACAC,SACAC,kBACAC,YACAC,aACAC,WACAC,aACAC,YACAC,QACAC,SACAC,OACAC,SACAC,WACAC,WACAC,YACAC,MACAC,OACAC,QACAC,WACAC,OACAC,QACAC,UACAC,UACAC,UACAC,YACAC,MACAC,WACAC,SACAC,YACAC,SACAC,SACAC,WACAC,aACAC,aACA1F,QACAC,SACAiJ,SACAC,OACAC,OACAC,OACAC,OACAC,UACAC,gBACA7D,UACAC,WACAC,SACAC,UACAC,OACAhG,WACAO,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACAd,YACAC,YACA8F,QACAsD,UACAzK,OAAA,SACAe,WACAK,YACAC,aACAqJ,WACAC,QAAA,UACA/J,QACAC,QACAE,WACAK,YACAC,aACAuJ,aACAD,QAAA,UACA5J,WACAK,YACAC,aACAwJ,aACAF,QAAA,UACA3K,SACA8K,WACAC,SACAC,QACAC,aACAN,QAAA,UACA3K,UACAkL,aACAP,QAAA,UACAG,WACA9K,SACAe,WACAK,YACAC,aACA8J,UACAnI,OAAA,SACAnD,QACAuL,mBACA9L,KAAA,kBACAD,QACAgM,0BACA1L,KAAA,yBACAU,QACAiL,sBACA3L,KAAA,qBACAE,OACAC,YACAC,SACAC,SACAC,WACAC,UACAC,QACAC,UACAC,QACAkL,yBACA5L,KAAA,wBACAU,OACAL,UACAwL,2BACAhM,KAAA,0BACAH,QACAoM,eACAjM,KAAA,cACArC,MACAuO,aACAtM,IAAA,YACAC,QACAsM,oBACAC,MAAA,mBACApM,OACArC,MACA0O,2CACAjL,MAAA,0CACAC,MAAA,0CACAiL,KAAA,0CACAtP,GAAA,0CACAyN,KAAA,0CACAvJ,KAAA,0CACAK,SAAA,0CACAK,UAAA,0CACAC,UAAA,0CACA7B,OACAG,OACAC,OACAC,OACAC,YACAC,SACAC,SACAC,WACAC,UACAC,QACAC,UACAC,QACA0L,qDACAvP,GAAA,oDACAsP,KAAA,oDACA/K,SAAA,oDACAK,UAAA,oDACAC,UAAA,oDACAhC,QACA2M,0BACA5D,QAAA,yBACAC,QAAA,yBACAE,MAAA,yBACAC,OAAA,yBACAC,MAAA,yBACAC,KAAA,yBACAC,MAAA,yBACAC,MAAA,yBACAC,QAAA,yBACAC,MAAA,yBACA3L,MACA8O,sBACAzP,GAAA,qBACAoE,MAAA,qBACAC,MAAA,qBACAE,SAAA,qBACAK,UAAA,qBACAC,UAAA,qBACA7B,OACAG,OACAC,OACAS,OACAL,SACAH,OACAC,YACAC,SACAE,WACAC,UACAC,QACAC,WACA8L,YACApL,KAAA,WACAJ,KAAA,WACAtB,MACAC,OACAC,OACAC,QACAJ,QACAiI,OACAC,QACAC,OACAC,OACAC,QACAC,QACAC,MACAX,OACAY,OACAC,OACA/F,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACAiF,OACA3G,OACAhB,QACA2M,qBACAvL,MAAA,oBACAC,MAAA,oBACAC,KAAA,oBACAJ,KAAA,oBACAC,KAAA,oBACAI,SAAA,oBACAC,MAAA,oBACAC,OAAA,oBACAC,kBAAA,oBACAC,MAAA,oBACAC,UAAA,oBACAC,UAAA,oBACAC,iBAAA,oBACAC,iBAAA,oBACAC,sBAAA,oBACAC,sBAAA,oBACAC,SAAA,oBACAC,SAAA,oBACAC,QAAA,oBACAC,kBAAA,oBACAC,kBAAA,oBACAC,iBAAA,oBACAC,kBAAA,oBACAC,kBAAA,oBACAC,iBAAA,oBACA7B,QACA+L,gBACAhJ,OAAA,eACAhD,UACAiD,SACAC,UACAJ,SACAC,UACAhG,KACAkD,QACAgM,iBACAlJ,QAAA,gBACA/C,UACAiD,SACAC,UACAJ,SACA/F,KACAkD,QACAiM,iBACAlE,QAAA,gBACApF,SACAoG,UACAmD,gBACAlJ,OAAA,eACAjD,UACAjD,KACAkD,QACAmM,uBACAnJ,OAAA,sBACAC,QAAA,sBACAlD,UACAjD,KACAkD,QACAoM,iBACAnJ,QAAA,gBACAlD,UACAjD,KACAkD,QACAqM,2BACA1C,UAAA,0BACA2C,SAAA,0BACAxF,OACAzG,OACAE,QACAC,SACA+L,8BACAC,SAAA,6BACAC,MAAA,6BACAjK,SACA9B,WACAC,QACAC,SACAG,YACAC,YACAC,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACA1F,KACAoE,QACAC,QACAiL,OACA7B,OACAvJ,OACAf,OACAH,OACAF,OACAF,MACAC,OACAE,QACAJ,QACAiI,OACAC,QACAC,OACAC,OACAC,QACAC,QACAC,MACAX,OACAY,OACAC,OACAT,OACA3G,OACAH,OACAM,OACAG,OACAI,oBACAC,QACAvB,OACAI,SACAH,OACAC,YACAC,SACAE,WACAC,UACAC,QACAC,WACA2M,kDACA5F,KAAA,iDACA3G,KAAA,iDACAmH,OACAC,OACA/F,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,mBACA9C,MACAC,OACAC,OACAC,QACAJ,QACAiI,OACAC,QACAC,OACAC,OACAC,QACAC,QACAC,MACAX,OACAvH,QACAwN,6LACA5F,KAAA,4LACAC,MAAA,4LACAC,KAAA,4LACAC,KAAA,4LACAC,MAAA,4LACAC,MAAA,4LACAC,IAAA,4LACAX,KAAA,4LACA3H,MACAC,OACAC,OACAC,QACAJ,QACAK,QACAyN,gBACA/J,OAAA,eACA9C,UACAiD,SACAC,UACAnG,KACAkD,QACA6M,YACA/F,KAAA,WACAgG,KAAA,WACAxF,KAAA,WACA9H,KAAA,WACAY,OACAD,OACAnB,OACAqB,OACAC,OACAC,QACAC,QACAC,OACAC,WACAC,QACAC,SACAC,oBACAC,QACAC,YACAC,YACAC,mBACAC,mBACAC,wBACAC,wBACAC,WACAC,WACAC,UACAC,oBACAC,oBACAC,mBACAC,oBACAC,oBACAC,oBACAkL,iBACAxM,MAAA,gBACAC,MAAA,gBACAC,KAAA,gBACAJ,KAAA,gBACAC,KAAA,gBACAI,SAAA,gBACAC,MAAA,gBACAC,OAAA,gBACAC,kBAAA,gBACAC,MAAA,gBACAC,UAAA,gBACAC,UAAA,gBACAC,iBAAA,gBACAC,iBAAA,gBACAC,sBAAA,gBACAC,sBAAA,gBACAC,SAAA,gBACAC,SAAA,gBACAC,QAAA,gBACAC,kBAAA,gBACAC,kBAAA,gBACAC,iBAAA,gBACAC,kBAAA,gBACAC,kBAAA,gBACAC,iBAAA,gBACArC,OACAC,YACAC,SACAC,SACAC,WACAC,UACAC,QACAC,UACAC,QACAgN,oBACAzM,MAAA,mBACAC,MAAA,mBACAC,KAAA,mBACAJ,KAAA,mBACAC,KAAA,mBACAI,SAAA,mBACAC,MAAA,mBACAC,OAAA,mBACAC,kBAAA,mBACAC,MAAA,mBACAC,UAAA,mBACAC,UAAA,mBACAC,iBAAA,mBACAC,iBAAA,mBACAC,sBAAA,mBACAC,sBAAA,mBACAC,SAAA,mBACAC,SAAA,mBACAC,QAAA,mBACAC,kBAAA,mBACAC,kBAAA,mBACAC,iBAAA,mBACAC,kBAAA,mBACAC,kBAAA,mBACAC,iBAAA,mBACA7B,OACAL,UACAsN,gBACAtK,OAAA,eACAnD,KAAA,eACAqD,SACAC,UACAC,SACAC,SACAC,UACAlD,UACAjD,MACAoQ,0BACA7M,KAAA,IAAA,kBAAA,MACA8M,eACA9M,KAAA,IAAA,OAAA,MACA+M,qBACA/M,KAAA,IAAA,aAAA,MACAgN,4BACAhN,KAAA,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","file":"yasqe.bundled.min.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \"+\": [], \n \"-\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \";\": []}, \n \"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\" : {\n \"+\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"-\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_POSITIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_POSITIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_POSITIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_NEGATIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_NEGATIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_NEGATIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \";\": []}, \n \"*or([baseDecl,prefixDecl])\" : {\n \"BASE\": [\"or([baseDecl,prefixDecl])\",\"*or([baseDecl,prefixDecl])\"], \n \"PREFIX\": [\"or([baseDecl,prefixDecl])\",\"*or([baseDecl,prefixDecl])\"], \n \"$\": [], \n \"CONSTRUCT\": [], \n \"DESCRIBE\": [], \n \"ASK\": [], \n \"INSERT\": [], \n \"DELETE\": [], \n \"SELECT\": [], \n \"LOAD\": [], \n \"CLEAR\": [], \n \"DROP\": [], \n \"ADD\": [], \n \"MOVE\": [], \n \"COPY\": [], \n \"CREATE\": [], \n \"WITH\": []}, \n \"*or([var,[ (,expression,AS,var,)]])\" : {\n \"(\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR1\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR2\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"WHERE\": [], \n \"{\": [], \n \"FROM\": []}, \n \"*orderCondition\" : {\n \"ASC\": [\"orderCondition\",\"*orderCondition\"], \n \"DESC\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR1\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR2\": [\"orderCondition\",\"*orderCondition\"], \n \"(\": [\"orderCondition\",\"*orderCondition\"], \n \"STR\": [\"orderCondition\",\"*orderCondition\"], \n \"LANG\": [\"orderCondition\",\"*orderCondition\"], \n \"LANGMATCHES\": [\"orderCondition\",\"*orderCondition\"], \n \"DATATYPE\": [\"orderCondition\",\"*orderCondition\"], \n \"BOUND\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI\": [\"orderCondition\",\"*orderCondition\"], \n \"URI\": [\"orderCondition\",\"*orderCondition\"], \n \"BNODE\": [\"orderCondition\",\"*orderCondition\"], \n \"RAND\": [\"orderCondition\",\"*orderCondition\"], \n \"ABS\": [\"orderCondition\",\"*orderCondition\"], \n \"CEIL\": [\"orderCondition\",\"*orderCondition\"], \n \"FLOOR\": [\"orderCondition\",\"*orderCondition\"], \n \"ROUND\": [\"orderCondition\",\"*orderCondition\"], \n \"CONCAT\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLEN\": [\"orderCondition\",\"*orderCondition\"], \n \"UCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"LCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"ENCODE_FOR_URI\": [\"orderCondition\",\"*orderCondition\"], \n \"CONTAINS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRSTARTS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRENDS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRBEFORE\": [\"orderCondition\",\"*orderCondition\"], \n \"STRAFTER\": [\"orderCondition\",\"*orderCondition\"], \n \"YEAR\": [\"orderCondition\",\"*orderCondition\"], \n \"MONTH\": [\"orderCondition\",\"*orderCondition\"], \n \"DAY\": [\"orderCondition\",\"*orderCondition\"], \n \"HOURS\": [\"orderCondition\",\"*orderCondition\"], \n \"MINUTES\": [\"orderCondition\",\"*orderCondition\"], \n \"SECONDS\": [\"orderCondition\",\"*orderCondition\"], \n \"TIMEZONE\": [\"orderCondition\",\"*orderCondition\"], \n \"TZ\": [\"orderCondition\",\"*orderCondition\"], \n \"NOW\": [\"orderCondition\",\"*orderCondition\"], \n \"UUID\": [\"orderCondition\",\"*orderCondition\"], \n \"STRUUID\": [\"orderCondition\",\"*orderCondition\"], \n \"MD5\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA1\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA256\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA384\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA512\": [\"orderCondition\",\"*orderCondition\"], \n \"COALESCE\": [\"orderCondition\",\"*orderCondition\"], \n \"IF\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLANG\": [\"orderCondition\",\"*orderCondition\"], \n \"STRDT\": [\"orderCondition\",\"*orderCondition\"], \n \"SAMETERM\": [\"orderCondition\",\"*orderCondition\"], \n \"ISIRI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISURI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISBLANK\": [\"orderCondition\",\"*orderCondition\"], \n \"ISLITERAL\": [\"orderCondition\",\"*orderCondition\"], \n \"ISNUMERIC\": [\"orderCondition\",\"*orderCondition\"], \n \"SUBSTR\": [\"orderCondition\",\"*orderCondition\"], \n \"REPLACE\": [\"orderCondition\",\"*orderCondition\"], \n \"REGEX\": [\"orderCondition\",\"*orderCondition\"], \n \"EXISTS\": [\"orderCondition\",\"*orderCondition\"], \n \"NOT\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI_REF\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_LN\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_NS\": [\"orderCondition\",\"*orderCondition\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"$\": [], \n \"}\": []}, \n \"*usingClause\" : {\n \"USING\": [\"usingClause\",\"*usingClause\"], \n \"WHERE\": []}, \n \"*var\" : {\n \"VAR1\": [\"var\",\"*var\"], \n \"VAR2\": [\"var\",\"*var\"], \n \")\": []}, \n \"*varOrIRIref\" : {\n \"VAR1\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"VAR2\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"IRI_REF\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_LN\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_NS\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"ORDER\": [], \n \"HAVING\": [], \n \"GROUP\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"WHERE\": [], \n \"{\": [], \n \"FROM\": [], \n \"VALUES\": [], \n \"$\": []}, \n \"+graphNode\" : {\n \"(\": [\"graphNode\",\"*graphNode\"], \n \"[\": [\"graphNode\",\"*graphNode\"], \n \"VAR1\": [\"graphNode\",\"*graphNode\"], \n \"VAR2\": [\"graphNode\",\"*graphNode\"], \n \"NIL\": [\"graphNode\",\"*graphNode\"], \n \"IRI_REF\": [\"graphNode\",\"*graphNode\"], \n \"TRUE\": [\"graphNode\",\"*graphNode\"], \n \"FALSE\": [\"graphNode\",\"*graphNode\"], \n \"BLANK_NODE_LABEL\": [\"graphNode\",\"*graphNode\"], \n \"ANON\": [\"graphNode\",\"*graphNode\"], \n \"PNAME_LN\": [\"graphNode\",\"*graphNode\"], \n \"PNAME_NS\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL1\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL2\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL_LONG1\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL_LONG2\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER_NEGATIVE\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL_NEGATIVE\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE_NEGATIVE\": [\"graphNode\",\"*graphNode\"]}, \n \"+graphNodePath\" : {\n \"(\": [\"graphNodePath\",\"*graphNodePath\"], \n \"[\": [\"graphNodePath\",\"*graphNodePath\"], \n \"VAR1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"VAR2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"NIL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"IRI_REF\": [\"graphNodePath\",\"*graphNodePath\"], \n \"TRUE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"FALSE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"BLANK_NODE_LABEL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"ANON\": [\"graphNodePath\",\"*graphNodePath\"], \n \"PNAME_LN\": [\"graphNodePath\",\"*graphNodePath\"], \n \"PNAME_NS\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL_LONG1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL_LONG2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"]}, \n \"+groupCondition\" : {\n \"(\": [\"groupCondition\",\"*groupCondition\"], \n \"STR\": [\"groupCondition\",\"*groupCondition\"], \n \"LANG\": [\"groupCondition\",\"*groupCondition\"], \n \"LANGMATCHES\": [\"groupCondition\",\"*groupCondition\"], \n \"DATATYPE\": [\"groupCondition\",\"*groupCondition\"], \n \"BOUND\": [\"groupCondition\",\"*groupCondition\"], \n \"IRI\": [\"groupCondition\",\"*groupCondition\"], \n \"URI\": [\"groupCondition\",\"*groupCondition\"], \n \"BNODE\": [\"groupCondition\",\"*groupCondition\"], \n \"RAND\": [\"groupCondition\",\"*groupCondition\"], \n \"ABS\": [\"groupCondition\",\"*groupCondition\"], \n \"CEIL\": [\"groupCondition\",\"*groupCondition\"], \n \"FLOOR\": [\"groupCondition\",\"*groupCondition\"], \n \"ROUND\": [\"groupCondition\",\"*groupCondition\"], \n \"CONCAT\": [\"groupCondition\",\"*groupCondition\"], \n \"STRLEN\": [\"groupCondition\",\"*groupCondition\"], \n \"UCASE\": [\"groupCondition\",\"*groupCondition\"], \n \"LCASE\": [\"groupCondition\",\"*groupCondition\"], \n \"ENCODE_FOR_URI\": [\"groupCondition\",\"*groupCondition\"], \n \"CONTAINS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRSTARTS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRENDS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRBEFORE\": [\"groupCondition\",\"*groupCondition\"], \n \"STRAFTER\": [\"groupCondition\",\"*groupCondition\"], \n \"YEAR\": [\"groupCondition\",\"*groupCondition\"], \n \"MONTH\": [\"groupCondition\",\"*groupCondition\"], \n \"DAY\": [\"groupCondition\",\"*groupCondition\"], \n \"HOURS\": [\"groupCondition\",\"*groupCondition\"], \n \"MINUTES\": [\"groupCondition\",\"*groupCondition\"], \n \"SECONDS\": [\"groupCondition\",\"*groupCondition\"], \n \"TIMEZONE\": [\"groupCondition\",\"*groupCondition\"], \n \"TZ\": [\"groupCondition\",\"*groupCondition\"], \n \"NOW\": [\"groupCondition\",\"*groupCondition\"], \n \"UUID\": [\"groupCondition\",\"*groupCondition\"], \n \"STRUUID\": [\"groupCondition\",\"*groupCondition\"], \n \"MD5\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA1\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA256\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA384\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA512\": [\"groupCondition\",\"*groupCondition\"], \n \"COALESCE\": [\"groupCondition\",\"*groupCondition\"], \n \"IF\": [\"groupCondition\",\"*groupCondition\"], \n \"STRLANG\": [\"groupCondition\",\"*groupCondition\"], \n \"STRDT\": [\"groupCondition\",\"*groupCondition\"], \n \"SAMETERM\": [\"groupCondition\",\"*groupCondition\"], \n \"ISIRI\": [\"groupCondition\",\"*groupCondition\"], \n \"ISURI\": [\"groupCondition\",\"*groupCondition\"], \n \"ISBLANK\": [\"groupCondition\",\"*groupCondition\"], \n \"ISLITERAL\": [\"groupCondition\",\"*groupCondition\"], \n \"ISNUMERIC\": [\"groupCondition\",\"*groupCondition\"], \n \"VAR1\": [\"groupCondition\",\"*groupCondition\"], \n \"VAR2\": [\"groupCondition\",\"*groupCondition\"], \n \"SUBSTR\": [\"groupCondition\",\"*groupCondition\"], \n \"REPLACE\": [\"groupCondition\",\"*groupCondition\"], \n \"REGEX\": [\"groupCondition\",\"*groupCondition\"], \n \"EXISTS\": [\"groupCondition\",\"*groupCondition\"], \n \"NOT\": [\"groupCondition\",\"*groupCondition\"], \n \"IRI_REF\": [\"groupCondition\",\"*groupCondition\"], \n \"PNAME_LN\": [\"groupCondition\",\"*groupCondition\"], \n \"PNAME_NS\": [\"groupCondition\",\"*groupCondition\"]}, \n \"+havingCondition\" : {\n \"(\": [\"havingCondition\",\"*havingCondition\"], \n \"STR\": [\"havingCondition\",\"*havingCondition\"], \n \"LANG\": [\"havingCondition\",\"*havingCondition\"], \n \"LANGMATCHES\": [\"havingCondition\",\"*havingCondition\"], \n \"DATATYPE\": [\"havingCondition\",\"*havingCondition\"], \n \"BOUND\": [\"havingCondition\",\"*havingCondition\"], \n \"IRI\": [\"havingCondition\",\"*havingCondition\"], \n \"URI\": [\"havingCondition\",\"*havingCondition\"], \n \"BNODE\": [\"havingCondition\",\"*havingCondition\"], \n \"RAND\": [\"havingCondition\",\"*havingCondition\"], \n \"ABS\": [\"havingCondition\",\"*havingCondition\"], \n \"CEIL\": [\"havingCondition\",\"*havingCondition\"], \n \"FLOOR\": [\"havingCondition\",\"*havingCondition\"], \n \"ROUND\": [\"havingCondition\",\"*havingCondition\"], \n \"CONCAT\": [\"havingCondition\",\"*havingCondition\"], \n \"STRLEN\": [\"havingCondition\",\"*havingCondition\"], \n \"UCASE\": [\"havingCondition\",\"*havingCondition\"], \n \"LCASE\": [\"havingCondition\",\"*havingCondition\"], \n \"ENCODE_FOR_URI\": [\"havingCondition\",\"*havingCondition\"], \n \"CONTAINS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRSTARTS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRENDS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRBEFORE\": [\"havingCondition\",\"*havingCondition\"], \n \"STRAFTER\": [\"havingCondition\",\"*havingCondition\"], \n \"YEAR\": [\"havingCondition\",\"*havingCondition\"], \n \"MONTH\": [\"havingCondition\",\"*havingCondition\"], \n \"DAY\": [\"havingCondition\",\"*havingCondition\"], \n \"HOURS\": [\"havingCondition\",\"*havingCondition\"], \n \"MINUTES\": [\"havingCondition\",\"*havingCondition\"], \n \"SECONDS\": [\"havingCondition\",\"*havingCondition\"], \n \"TIMEZONE\": [\"havingCondition\",\"*havingCondition\"], \n \"TZ\": [\"havingCondition\",\"*havingCondition\"], \n \"NOW\": [\"havingCondition\",\"*havingCondition\"], \n \"UUID\": [\"havingCondition\",\"*havingCondition\"], \n \"STRUUID\": [\"havingCondition\",\"*havingCondition\"], \n \"MD5\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA1\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA256\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA384\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA512\": [\"havingCondition\",\"*havingCondition\"], \n \"COALESCE\": [\"havingCondition\",\"*havingCondition\"], \n \"IF\": [\"havingCondition\",\"*havingCondition\"], \n \"STRLANG\": [\"havingCondition\",\"*havingCondition\"], \n \"STRDT\": [\"havingCondition\",\"*havingCondition\"], \n \"SAMETERM\": [\"havingCondition\",\"*havingCondition\"], \n \"ISIRI\": [\"havingCondition\",\"*havingCondition\"], \n \"ISURI\": [\"havingCondition\",\"*havingCondition\"], \n \"ISBLANK\": [\"havingCondition\",\"*havingCondition\"], \n \"ISLITERAL\": [\"havingCondition\",\"*havingCondition\"], \n \"ISNUMERIC\": [\"havingCondition\",\"*havingCondition\"], \n \"SUBSTR\": [\"havingCondition\",\"*havingCondition\"], \n \"REPLACE\": [\"havingCondition\",\"*havingCondition\"], \n \"REGEX\": [\"havingCondition\",\"*havingCondition\"], \n \"EXISTS\": [\"havingCondition\",\"*havingCondition\"], \n \"NOT\": [\"havingCondition\",\"*havingCondition\"], \n \"IRI_REF\": [\"havingCondition\",\"*havingCondition\"], \n \"PNAME_LN\": [\"havingCondition\",\"*havingCondition\"], \n \"PNAME_NS\": [\"havingCondition\",\"*havingCondition\"]}, \n \"+or([var,[ (,expression,AS,var,)]])\" : {\n \"(\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR1\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR2\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"]}, \n \"+orderCondition\" : {\n \"ASC\": [\"orderCondition\",\"*orderCondition\"], \n \"DESC\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR1\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR2\": [\"orderCondition\",\"*orderCondition\"], \n \"(\": [\"orderCondition\",\"*orderCondition\"], \n \"STR\": [\"orderCondition\",\"*orderCondition\"], \n \"LANG\": [\"orderCondition\",\"*orderCondition\"], \n \"LANGMATCHES\": [\"orderCondition\",\"*orderCondition\"], \n \"DATATYPE\": [\"orderCondition\",\"*orderCondition\"], \n \"BOUND\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI\": [\"orderCondition\",\"*orderCondition\"], \n \"URI\": [\"orderCondition\",\"*orderCondition\"], \n \"BNODE\": [\"orderCondition\",\"*orderCondition\"], \n \"RAND\": [\"orderCondition\",\"*orderCondition\"], \n \"ABS\": [\"orderCondition\",\"*orderCondition\"], \n \"CEIL\": [\"orderCondition\",\"*orderCondition\"], \n \"FLOOR\": [\"orderCondition\",\"*orderCondition\"], \n \"ROUND\": [\"orderCondition\",\"*orderCondition\"], \n \"CONCAT\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLEN\": [\"orderCondition\",\"*orderCondition\"], \n \"UCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"LCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"ENCODE_FOR_URI\": [\"orderCondition\",\"*orderCondition\"], \n \"CONTAINS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRSTARTS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRENDS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRBEFORE\": [\"orderCondition\",\"*orderCondition\"], \n \"STRAFTER\": [\"orderCondition\",\"*orderCondition\"], \n \"YEAR\": [\"orderCondition\",\"*orderCondition\"], \n \"MONTH\": [\"orderCondition\",\"*orderCondition\"], \n \"DAY\": [\"orderCondition\",\"*orderCondition\"], \n \"HOURS\": [\"orderCondition\",\"*orderCondition\"], \n \"MINUTES\": [\"orderCondition\",\"*orderCondition\"], \n \"SECONDS\": [\"orderCondition\",\"*orderCondition\"], \n \"TIMEZONE\": [\"orderCondition\",\"*orderCondition\"], \n \"TZ\": [\"orderCondition\",\"*orderCondition\"], \n \"NOW\": [\"orderCondition\",\"*orderCondition\"], \n \"UUID\": [\"orderCondition\",\"*orderCondition\"], \n \"STRUUID\": [\"orderCondition\",\"*orderCondition\"], \n \"MD5\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA1\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA256\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA384\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA512\": [\"orderCondition\",\"*orderCondition\"], \n \"COALESCE\": [\"orderCondition\",\"*orderCondition\"], \n \"IF\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLANG\": [\"orderCondition\",\"*orderCondition\"], \n \"STRDT\": [\"orderCondition\",\"*orderCondition\"], \n \"SAMETERM\": [\"orderCondition\",\"*orderCondition\"], \n \"ISIRI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISURI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISBLANK\": [\"orderCondition\",\"*orderCondition\"], \n \"ISLITERAL\": [\"orderCondition\",\"*orderCondition\"], \n \"ISNUMERIC\": [\"orderCondition\",\"*orderCondition\"], \n \"SUBSTR\": [\"orderCondition\",\"*orderCondition\"], \n \"REPLACE\": [\"orderCondition\",\"*orderCondition\"], \n \"REGEX\": [\"orderCondition\",\"*orderCondition\"], \n \"EXISTS\": [\"orderCondition\",\"*orderCondition\"], \n \"NOT\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI_REF\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_LN\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_NS\": [\"orderCondition\",\"*orderCondition\"]}, \n \"+varOrIRIref\" : {\n \"VAR1\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"VAR2\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"IRI_REF\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_LN\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_NS\": [\"varOrIRIref\",\"*varOrIRIref\"]}, \n \"?.\" : {\n \".\": [\".\"], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"(\": [], \n \"[\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?DISTINCT\" : {\n \"DISTINCT\": [\"DISTINCT\"], \n \"!\": [], \n \"+\": [], \n \"-\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"(\": [], \n \"STR\": [], \n \"LANG\": [], \n \"LANGMATCHES\": [], \n \"DATATYPE\": [], \n \"BOUND\": [], \n \"IRI\": [], \n \"URI\": [], \n \"BNODE\": [], \n \"RAND\": [], \n \"ABS\": [], \n \"CEIL\": [], \n \"FLOOR\": [], \n \"ROUND\": [], \n \"CONCAT\": [], \n \"STRLEN\": [], \n \"UCASE\": [], \n \"LCASE\": [], \n \"ENCODE_FOR_URI\": [], \n \"CONTAINS\": [], \n \"STRSTARTS\": [], \n \"STRENDS\": [], \n \"STRBEFORE\": [], \n \"STRAFTER\": [], \n \"YEAR\": [], \n \"MONTH\": [], \n \"DAY\": [], \n \"HOURS\": [], \n \"MINUTES\": [], \n \"SECONDS\": [], \n \"TIMEZONE\": [], \n \"TZ\": [], \n \"NOW\": [], \n \"UUID\": [], \n \"STRUUID\": [], \n \"MD5\": [], \n \"SHA1\": [], \n \"SHA256\": [], \n \"SHA384\": [], \n \"SHA512\": [], \n \"COALESCE\": [], \n \"IF\": [], \n \"STRLANG\": [], \n \"STRDT\": [], \n \"SAMETERM\": [], \n \"ISIRI\": [], \n \"ISURI\": [], \n \"ISBLANK\": [], \n \"ISLITERAL\": [], \n \"ISNUMERIC\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"COUNT\": [], \n \"SUM\": [], \n \"MIN\": [], \n \"MAX\": [], \n \"AVG\": [], \n \"SAMPLE\": [], \n \"GROUP_CONCAT\": [], \n \"SUBSTR\": [], \n \"REPLACE\": [], \n \"REGEX\": [], \n \"EXISTS\": [], \n \"NOT\": [], \n \"IRI_REF\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"*\": []}, \n \"?GRAPH\" : {\n \"GRAPH\": [\"GRAPH\"], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?SILENT\" : {\n \"SILENT\": [\"SILENT\"], \n \"VAR1\": [], \n \"VAR2\": [], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?SILENT_1\" : {\n \"SILENT\": [\"SILENT\"], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?SILENT_2\" : {\n \"SILENT\": [\"SILENT\"], \n \"GRAPH\": [], \n \"DEFAULT\": [], \n \"NAMED\": [], \n \"ALL\": []}, \n \"?SILENT_3\" : {\n \"SILENT\": [\"SILENT\"], \n \"GRAPH\": []}, \n \"?SILENT_4\" : {\n \"SILENT\": [\"SILENT\"], \n \"DEFAULT\": [], \n \"GRAPH\": [], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?WHERE\" : {\n \"WHERE\": [\"WHERE\"], \n \"{\": []}, \n \"?[,,expression]\" : {\n \",\": [\"[,,expression]\"], \n \")\": []}, \n \"?[.,?constructTriples]\" : {\n \".\": [\"[.,?constructTriples]\"], \n \"}\": []}, \n \"?[.,?triplesBlock]\" : {\n \".\": [\"[.,?triplesBlock]\"], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?[.,?triplesTemplate]\" : {\n \".\": [\"[.,?triplesTemplate]\"], \n \"}\": [], \n \"GRAPH\": []}, \n \"?[;,SEPARATOR,=,string]\" : {\n \";\": [\"[;,SEPARATOR,=,string]\"], \n \")\": []}, \n \"?[;,update]\" : {\n \";\": [\"[;,update]\"], \n \"$\": []}, \n \"?[AS,var]\" : {\n \"AS\": [\"[AS,var]\"], \n \")\": []}, \n \"?[INTO,graphRef]\" : {\n \"INTO\": [\"[INTO,graphRef]\"], \n \";\": [], \n \"$\": []}, \n \"?[or([verbPath,verbSimple]),objectList]\" : {\n \"VAR1\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"VAR2\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"^\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"a\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"!\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"(\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"IRI_REF\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"PNAME_LN\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"PNAME_NS\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \";\": [], \n \".\": [], \n \"]\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?[pathOneInPropertySet,*[|,pathOneInPropertySet]]\" : {\n \"a\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"^\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"IRI_REF\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"PNAME_LN\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"PNAME_NS\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \")\": []}, \n \"?[update1,?[;,update]]\" : {\n \"INSERT\": [\"[update1,?[;,update]]\"], \n \"DELETE\": [\"[update1,?[;,update]]\"], \n \"LOAD\": [\"[update1,?[;,update]]\"], \n \"CLEAR\": [\"[update1,?[;,update]]\"], \n \"DROP\": [\"[update1,?[;,update]]\"], \n \"ADD\": [\"[update1,?[;,update]]\"], \n \"MOVE\": [\"[update1,?[;,update]]\"], \n \"COPY\": [\"[update1,?[;,update]]\"], \n \"CREATE\": [\"[update1,?[;,update]]\"], \n \"WITH\": [\"[update1,?[;,update]]\"], \n \"$\": []}, \n \"?[verb,objectList]\" : {\n \"a\": [\"[verb,objectList]\"], \n \"VAR1\": [\"[verb,objectList]\"], \n \"VAR2\": [\"[verb,objectList]\"], \n \"IRI_REF\": [\"[verb,objectList]\"], \n \"PNAME_LN\": [\"[verb,objectList]\"], \n \"PNAME_NS\": [\"[verb,objectList]\"], \n \";\": [], \n \".\": [], \n \"]\": [], \n \"}\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": []}, \n \"?argList\" : {\n \"NIL\": [\"argList\"], \n \"(\": [\"argList\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \"+\": [], \n \"-\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"*\": [], \n \"/\": [], \n \";\": []}, \n \"?constructTriples\" : {\n \"VAR1\": [\"constructTriples\"], \n \"VAR2\": [\"constructTriples\"], \n \"NIL\": [\"constructTriples\"], \n \"(\": [\"constructTriples\"], \n \"[\": [\"constructTriples\"], \n \"IRI_REF\": [\"constructTriples\"], \n \"TRUE\": [\"constructTriples\"], \n \"FALSE\": [\"constructTriples\"], \n \"BLANK_NODE_LABEL\": [\"constructTriples\"], \n \"ANON\": [\"constructTriples\"], \n \"PNAME_LN\": [\"constructTriples\"], \n \"PNAME_NS\": [\"constructTriples\"], \n \"STRING_LITERAL1\": [\"constructTriples\"], \n \"STRING_LITERAL2\": [\"constructTriples\"], \n \"STRING_LITERAL_LONG1\": [\"constructTriples\"], \n \"STRING_LITERAL_LONG2\": [\"constructTriples\"], \n \"INTEGER\": [\"constructTriples\"], \n \"DECIMAL\": [\"constructTriples\"], \n \"DOUBLE\": [\"constructTriples\"], \n \"INTEGER_POSITIVE\": [\"constructTriples\"], \n \"DECIMAL_POSITIVE\": [\"constructTriples\"], \n \"DOUBLE_POSITIVE\": [\"constructTriples\"], \n \"INTEGER_NEGATIVE\": [\"constructTriples\"], \n \"DECIMAL_NEGATIVE\": [\"constructTriples\"], \n \"DOUBLE_NEGATIVE\": [\"constructTriples\"], \n \"}\": []}, \n \"?groupClause\" : {\n \"GROUP\": [\"groupClause\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"ORDER\": [], \n \"HAVING\": [], \n \"$\": [], \n \"}\": []}, \n \"?havingClause\" : {\n \"HAVING\": [\"havingClause\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"ORDER\": [], \n \"$\": [], \n \"}\": []}, \n \"?insertClause\" : {\n \"INSERT\": [\"insertClause\"], \n \"WHERE\": [], \n \"USING\": []}, \n \"?limitClause\" : {\n \"LIMIT\": [\"limitClause\"], \n \"VALUES\": [], \n \"$\": [], \n \"}\": []}, \n \"?limitOffsetClauses\" : {\n \"LIMIT\": [\"limitOffsetClauses\"], \n \"OFFSET\": [\"limitOffsetClauses\"], \n \"VALUES\": [], \n \"$\": [], \n \"}\": []}, \n \"?offsetClause\" : {\n \"OFFSET\": [\"offsetClause\"], \n \"VALUES\": [], \n \"$\": [], \n \"}\": []}, \n \"?or([DISTINCT,REDUCED])\" : {\n \"DISTINCT\": [\"or([DISTINCT,REDUCED])\"], \n \"REDUCED\": [\"or([DISTINCT,REDUCED])\"], \n \"*\": [], \n \"(\": [], \n \"VAR1\": [], \n \"VAR2\": []}, \n \"?or([LANGTAG,[^^,iriRef]])\" : {\n \"LANGTAG\": [\"or([LANGTAG,[^^,iriRef]])\"], \n \"^^\": [\"or([LANGTAG,[^^,iriRef]])\"], \n \"UNDEF\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"a\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"^\": [], \n \"!\": [], \n \"(\": [], \n \".\": [], \n \";\": [], \n \",\": [], \n \"AS\": [], \n \")\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \"+\": [], \n \"-\": [], \n \"*\": [], \n \"/\": [], \n \"}\": [], \n \"[\": [], \n \"NIL\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"]\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": []}, \n \"?or([[*,unaryExpression],[/,unaryExpression]])\" : {\n \"*\": [\"or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"/\": [\"or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"+\": [], \n \"-\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \";\": []}, \n \"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\" : {\n \"=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"!=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"<\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \">\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"<=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \">=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IN\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"NOT\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \";\": []}, \n \"?orderClause\" : {\n \"ORDER\": [\"orderClause\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"$\": [], \n \"}\": []}, \n \"?pathMod\" : {\n \"*\": [\"pathMod\"], \n \"?\": [\"pathMod\"], \n \"+\": [\"pathMod\"], \n \"{\": [\"pathMod\"], \n \"|\": [], \n \"/\": [], \n \")\": [], \n \"(\": [], \n \"[\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"?triplesBlock\" : {\n \"VAR1\": [\"triplesBlock\"], \n \"VAR2\": [\"triplesBlock\"], \n \"NIL\": [\"triplesBlock\"], \n \"(\": [\"triplesBlock\"], \n \"[\": [\"triplesBlock\"], \n \"IRI_REF\": [\"triplesBlock\"], \n \"TRUE\": [\"triplesBlock\"], \n \"FALSE\": [\"triplesBlock\"], \n \"BLANK_NODE_LABEL\": [\"triplesBlock\"], \n \"ANON\": [\"triplesBlock\"], \n \"PNAME_LN\": [\"triplesBlock\"], \n \"PNAME_NS\": [\"triplesBlock\"], \n \"STRING_LITERAL1\": [\"triplesBlock\"], \n \"STRING_LITERAL2\": [\"triplesBlock\"], \n \"STRING_LITERAL_LONG1\": [\"triplesBlock\"], \n \"STRING_LITERAL_LONG2\": [\"triplesBlock\"], \n \"INTEGER\": [\"triplesBlock\"], \n \"DECIMAL\": [\"triplesBlock\"], \n \"DOUBLE\": [\"triplesBlock\"], \n \"INTEGER_POSITIVE\": [\"triplesBlock\"], \n \"DECIMAL_POSITIVE\": [\"triplesBlock\"], \n \"DOUBLE_POSITIVE\": [\"triplesBlock\"], \n \"INTEGER_NEGATIVE\": [\"triplesBlock\"], \n \"DECIMAL_NEGATIVE\": [\"triplesBlock\"], \n \"DOUBLE_NEGATIVE\": [\"triplesBlock\"], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?triplesTemplate\" : {\n \"VAR1\": [\"triplesTemplate\"], \n \"VAR2\": [\"triplesTemplate\"], \n \"NIL\": [\"triplesTemplate\"], \n \"(\": [\"triplesTemplate\"], \n \"[\": [\"triplesTemplate\"], \n \"IRI_REF\": [\"triplesTemplate\"], \n \"TRUE\": [\"triplesTemplate\"], \n \"FALSE\": [\"triplesTemplate\"], \n \"BLANK_NODE_LABEL\": [\"triplesTemplate\"], \n \"ANON\": [\"triplesTemplate\"], \n \"PNAME_LN\": [\"triplesTemplate\"], \n \"PNAME_NS\": [\"triplesTemplate\"], \n \"STRING_LITERAL1\": [\"triplesTemplate\"], \n \"STRING_LITERAL2\": [\"triplesTemplate\"], \n \"STRING_LITERAL_LONG1\": [\"triplesTemplate\"], \n \"STRING_LITERAL_LONG2\": [\"triplesTemplate\"], \n \"INTEGER\": [\"triplesTemplate\"], \n \"DECIMAL\": [\"triplesTemplate\"], \n \"DOUBLE\": [\"triplesTemplate\"], \n \"INTEGER_POSITIVE\": [\"triplesTemplate\"], \n \"DECIMAL_POSITIVE\": [\"triplesTemplate\"], \n \"DOUBLE_POSITIVE\": [\"triplesTemplate\"], \n \"INTEGER_NEGATIVE\": [\"triplesTemplate\"], \n \"DECIMAL_NEGATIVE\": [\"triplesTemplate\"], \n \"DOUBLE_NEGATIVE\": [\"triplesTemplate\"], \n \"}\": [], \n \"GRAPH\": []}, \n \"?whereClause\" : {\n \"WHERE\": [\"whereClause\"], \n \"{\": [\"whereClause\"], \n \"ORDER\": [], \n \"HAVING\": [], \n \"GROUP\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"VALUES\": [], \n \"$\": []}, \n \"[ (,*dataBlockValue,)]\" : {\n \"(\": [\"(\",\"*dataBlockValue\",\")\"]}, \n \"[ (,*var,)]\" : {\n \"(\": [\"(\",\"*var\",\")\"]}, \n \"[ (,expression,)]\" : {\n \"(\": [\"(\",\"expression\",\")\"]}, \n \"[ (,expression,AS,var,)]\" : {\n \"(\": [\"(\",\"expression\",\"AS\",\"var\",\")\"]}, \n \"[!=,numericExpression]\" : {\n \"!=\": [\"!=\",\"numericExpression\"]}, \n \"[&&,valueLogical]\" : {\n \"&&\": [\"&&\",\"valueLogical\"]}, \n \"[*,unaryExpression]\" : {\n \"*\": [\"*\",\"unaryExpression\"]}, \n \"[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]\" : {\n \"WHERE\": [\"*datasetClause\",\"WHERE\",\"{\",\"?triplesTemplate\",\"}\",\"solutionModifier\"], \n \"FROM\": [\"*datasetClause\",\"WHERE\",\"{\",\"?triplesTemplate\",\"}\",\"solutionModifier\"]}, \n \"[+,multiplicativeExpression]\" : {\n \"+\": [\"+\",\"multiplicativeExpression\"]}, \n \"[,,expression]\" : {\n \",\": [\",\",\"expression\"]}, \n \"[,,integer,}]\" : {\n \",\": [\",\",\"integer\",\"}\"]}, \n \"[,,objectPath]\" : {\n \",\": [\",\",\"objectPath\"]}, \n \"[,,object]\" : {\n \",\": [\",\",\"object\"]}, \n \"[,,or([},[integer,}]])]\" : {\n \",\": [\",\",\"or([},[integer,}]])\"]}, \n \"[-,multiplicativeExpression]\" : {\n \"-\": [\"-\",\"multiplicativeExpression\"]}, \n \"[.,?constructTriples]\" : {\n \".\": [\".\",\"?constructTriples\"]}, \n \"[.,?triplesBlock]\" : {\n \".\": [\".\",\"?triplesBlock\"]}, \n \"[.,?triplesTemplate]\" : {\n \".\": [\".\",\"?triplesTemplate\"]}, \n \"[/,pathEltOrInverse]\" : {\n \"/\": [\"/\",\"pathEltOrInverse\"]}, \n \"[/,unaryExpression]\" : {\n \"/\": [\"/\",\"unaryExpression\"]}, \n \"[;,?[or([verbPath,verbSimple]),objectList]]\" : {\n \";\": [\";\",\"?[or([verbPath,verbSimple]),objectList]\"]}, \n \"[;,?[verb,objectList]]\" : {\n \";\": [\";\",\"?[verb,objectList]\"]}, \n \"[;,SEPARATOR,=,string]\" : {\n \";\": [\";\",\"SEPARATOR\",\"=\",\"string\"]}, \n \"[;,update]\" : {\n \";\": [\";\",\"update\"]}, \n \"[<,numericExpression]\" : {\n \"<\": [\"<\",\"numericExpression\"]}, \n \"[<=,numericExpression]\" : {\n \"<=\": [\"<=\",\"numericExpression\"]}, \n \"[=,numericExpression]\" : {\n \"=\": [\"=\",\"numericExpression\"]}, \n \"[>,numericExpression]\" : {\n \">\": [\">\",\"numericExpression\"]}, \n \"[>=,numericExpression]\" : {\n \">=\": [\">=\",\"numericExpression\"]}, \n \"[AS,var]\" : {\n \"AS\": [\"AS\",\"var\"]}, \n \"[IN,expressionList]\" : {\n \"IN\": [\"IN\",\"expressionList\"]}, \n \"[INTO,graphRef]\" : {\n \"INTO\": [\"INTO\",\"graphRef\"]}, \n \"[NAMED,iriRef]\" : {\n \"NAMED\": [\"NAMED\",\"iriRef\"]}, \n \"[NOT,IN,expressionList]\" : {\n \"NOT\": [\"NOT\",\"IN\",\"expressionList\"]}, \n \"[UNION,groupGraphPattern]\" : {\n \"UNION\": [\"UNION\",\"groupGraphPattern\"]}, \n \"[^^,iriRef]\" : {\n \"^^\": [\"^^\",\"iriRef\"]}, \n \"[constructTemplate,*datasetClause,whereClause,solutionModifier]\" : {\n \"{\": [\"constructTemplate\",\"*datasetClause\",\"whereClause\",\"solutionModifier\"]}, \n \"[deleteClause,?insertClause]\" : {\n \"DELETE\": [\"deleteClause\",\"?insertClause\"]}, \n \"[graphPatternNotTriples,?.,?triplesBlock]\" : {\n \"{\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"OPTIONAL\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"MINUS\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"GRAPH\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"SERVICE\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"FILTER\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"BIND\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"VALUES\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"]}, \n \"[integer,or([[,,or([},[integer,}]])],}])]\" : {\n \"INTEGER\": [\"integer\",\"or([[,,or([},[integer,}]])],}])\"]}, \n \"[integer,}]\" : {\n \"INTEGER\": [\"integer\",\"}\"]}, \n \"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\" : {\n \"INTEGER_POSITIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_POSITIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_POSITIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER_NEGATIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_NEGATIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_NEGATIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"]}, \n \"[or([verbPath,verbSimple]),objectList]\" : {\n \"VAR1\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"VAR2\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"^\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"a\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"!\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"(\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"IRI_REF\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"PNAME_LN\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"PNAME_NS\": [\"or([verbPath,verbSimple])\",\"objectList\"]}, \n \"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\" : {\n \"a\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"^\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"IRI_REF\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"PNAME_LN\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"PNAME_NS\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"]}, \n \"[quadsNotTriples,?.,?triplesTemplate]\" : {\n \"GRAPH\": [\"quadsNotTriples\",\"?.\",\"?triplesTemplate\"]}, \n \"[update1,?[;,update]]\" : {\n \"INSERT\": [\"update1\",\"?[;,update]\"], \n \"DELETE\": [\"update1\",\"?[;,update]\"], \n \"LOAD\": [\"update1\",\"?[;,update]\"], \n \"CLEAR\": [\"update1\",\"?[;,update]\"], \n \"DROP\": [\"update1\",\"?[;,update]\"], \n \"ADD\": [\"update1\",\"?[;,update]\"], \n \"MOVE\": [\"update1\",\"?[;,update]\"], \n \"COPY\": [\"update1\",\"?[;,update]\"], \n \"CREATE\": [\"update1\",\"?[;,update]\"], \n \"WITH\": [\"update1\",\"?[;,update]\"]}, \n \"[verb,objectList]\" : {\n \"a\": [\"verb\",\"objectList\"], \n \"VAR1\": [\"verb\",\"objectList\"], \n \"VAR2\": [\"verb\",\"objectList\"], \n \"IRI_REF\": [\"verb\",\"objectList\"], \n \"PNAME_LN\": [\"verb\",\"objectList\"], \n \"PNAME_NS\": [\"verb\",\"objectList\"]}, \n \"[|,pathOneInPropertySet]\" : {\n \"|\": [\"|\",\"pathOneInPropertySet\"]}, \n \"[|,pathSequence]\" : {\n \"|\": [\"|\",\"pathSequence\"]}, \n \"[||,conditionalAndExpression]\" : {\n \"||\": [\"||\",\"conditionalAndExpression\"]}, \n \"add\" : {\n \"ADD\": [\"ADD\",\"?SILENT_4\",\"graphOrDefault\",\"TO\",\"graphOrDefault\"]}, \n \"additiveExpression\" : {\n \"!\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"+\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"-\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"VAR1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"VAR2\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"(\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"LANG\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"LANGMATCHES\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DATATYPE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"BOUND\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"IRI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"URI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"BNODE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"RAND\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ABS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"CEIL\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"FLOOR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ROUND\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"CONCAT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRLEN\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"UCASE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"LCASE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ENCODE_FOR_URI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"CONTAINS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRSTARTS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRENDS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRBEFORE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRAFTER\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"YEAR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MONTH\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DAY\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"HOURS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MINUTES\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SECONDS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"TIMEZONE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"TZ\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"NOW\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"UUID\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRUUID\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MD5\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA256\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA384\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA512\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"COALESCE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"IF\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRLANG\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRDT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SAMETERM\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISIRI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISURI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISBLANK\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISLITERAL\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISNUMERIC\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"TRUE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"FALSE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"COUNT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SUM\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MIN\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MAX\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"AVG\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SAMPLE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"GROUP_CONCAT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SUBSTR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"REPLACE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"REGEX\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"EXISTS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"NOT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"IRI_REF\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL2\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL_LONG1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL_LONG2\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_POSITIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_POSITIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_POSITIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_NEGATIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_NEGATIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_NEGATIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"PNAME_LN\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"PNAME_NS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"]}, \n \"aggregate\" : {\n \"COUNT\": [\"COUNT\",\"(\",\"?DISTINCT\",\"or([*,expression])\",\")\"], \n \"SUM\": [\"SUM\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"MIN\": [\"MIN\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"MAX\": [\"MAX\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"AVG\": [\"AVG\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"SAMPLE\": [\"SAMPLE\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"GROUP_CONCAT\": [\"GROUP_CONCAT\",\"(\",\"?DISTINCT\",\"expression\",\"?[;,SEPARATOR,=,string]\",\")\"]}, \n \"allowBnodes\" : {\n \"}\": []}, \n \"allowVars\" : {\n \"}\": []}, \n \"argList\" : {\n \"NIL\": [\"NIL\"], \n \"(\": [\"(\",\"?DISTINCT\",\"expression\",\"*[,,expression]\",\")\"]}, \n \"askQuery\" : {\n \"ASK\": [\"ASK\",\"*datasetClause\",\"whereClause\",\"solutionModifier\"]}, \n \"baseDecl\" : {\n \"BASE\": [\"BASE\",\"IRI_REF\"]}, \n \"bind\" : {\n \"BIND\": [\"BIND\",\"(\",\"expression\",\"AS\",\"var\",\")\"]}, \n \"blankNode\" : {\n \"BLANK_NODE_LABEL\": [\"BLANK_NODE_LABEL\"], \n \"ANON\": [\"ANON\"]}, \n \"blankNodePropertyList\" : {\n \"[\": [\"[\",\"propertyListNotEmpty\",\"]\"]}, \n \"blankNodePropertyListPath\" : {\n \"[\": [\"[\",\"propertyListPathNotEmpty\",\"]\"]}, \n \"booleanLiteral\" : {\n \"TRUE\": [\"TRUE\"], \n \"FALSE\": [\"FALSE\"]}, \n \"brackettedExpression\" : {\n \"(\": [\"(\",\"expression\",\")\"]}, \n \"builtInCall\" : {\n \"STR\": [\"STR\",\"(\",\"expression\",\")\"], \n \"LANG\": [\"LANG\",\"(\",\"expression\",\")\"], \n \"LANGMATCHES\": [\"LANGMATCHES\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"DATATYPE\": [\"DATATYPE\",\"(\",\"expression\",\")\"], \n \"BOUND\": [\"BOUND\",\"(\",\"var\",\")\"], \n \"IRI\": [\"IRI\",\"(\",\"expression\",\")\"], \n \"URI\": [\"URI\",\"(\",\"expression\",\")\"], \n \"BNODE\": [\"BNODE\",\"or([[ (,expression,)],NIL])\"], \n \"RAND\": [\"RAND\",\"NIL\"], \n \"ABS\": [\"ABS\",\"(\",\"expression\",\")\"], \n \"CEIL\": [\"CEIL\",\"(\",\"expression\",\")\"], \n \"FLOOR\": [\"FLOOR\",\"(\",\"expression\",\")\"], \n \"ROUND\": [\"ROUND\",\"(\",\"expression\",\")\"], \n \"CONCAT\": [\"CONCAT\",\"expressionList\"], \n \"SUBSTR\": [\"substringExpression\"], \n \"STRLEN\": [\"STRLEN\",\"(\",\"expression\",\")\"], \n \"REPLACE\": [\"strReplaceExpression\"], \n \"UCASE\": [\"UCASE\",\"(\",\"expression\",\")\"], \n \"LCASE\": [\"LCASE\",\"(\",\"expression\",\")\"], \n \"ENCODE_FOR_URI\": [\"ENCODE_FOR_URI\",\"(\",\"expression\",\")\"], \n \"CONTAINS\": [\"CONTAINS\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRSTARTS\": [\"STRSTARTS\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRENDS\": [\"STRENDS\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRBEFORE\": [\"STRBEFORE\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRAFTER\": [\"STRAFTER\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"YEAR\": [\"YEAR\",\"(\",\"expression\",\")\"], \n \"MONTH\": [\"MONTH\",\"(\",\"expression\",\")\"], \n \"DAY\": [\"DAY\",\"(\",\"expression\",\")\"], \n \"HOURS\": [\"HOURS\",\"(\",\"expression\",\")\"], \n \"MINUTES\": [\"MINUTES\",\"(\",\"expression\",\")\"], \n \"SECONDS\": [\"SECONDS\",\"(\",\"expression\",\")\"], \n \"TIMEZONE\": [\"TIMEZONE\",\"(\",\"expression\",\")\"], \n \"TZ\": [\"TZ\",\"(\",\"expression\",\")\"], \n \"NOW\": [\"NOW\",\"NIL\"], \n \"UUID\": [\"UUID\",\"NIL\"], \n \"STRUUID\": [\"STRUUID\",\"NIL\"], \n \"MD5\": [\"MD5\",\"(\",\"expression\",\")\"], \n \"SHA1\": [\"SHA1\",\"(\",\"expression\",\")\"], \n \"SHA256\": [\"SHA256\",\"(\",\"expression\",\")\"], \n \"SHA384\": [\"SHA384\",\"(\",\"expression\",\")\"], \n \"SHA512\": [\"SHA512\",\"(\",\"expression\",\")\"], \n \"COALESCE\": [\"COALESCE\",\"expressionList\"], \n \"IF\": [\"IF\",\"(\",\"expression\",\",\",\"expression\",\",\",\"expression\",\")\"], \n \"STRLANG\": [\"STRLANG\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRDT\": [\"STRDT\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"SAMETERM\": [\"SAMETERM\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"ISIRI\": [\"ISIRI\",\"(\",\"expression\",\")\"], \n \"ISURI\": [\"ISURI\",\"(\",\"expression\",\")\"], \n \"ISBLANK\": [\"ISBLANK\",\"(\",\"expression\",\")\"], \n \"ISLITERAL\": [\"ISLITERAL\",\"(\",\"expression\",\")\"], \n \"ISNUMERIC\": [\"ISNUMERIC\",\"(\",\"expression\",\")\"], \n \"REGEX\": [\"regexExpression\"], \n \"EXISTS\": [\"existsFunc\"], \n \"NOT\": [\"notExistsFunc\"]}, \n \"clear\" : {\n \"CLEAR\": [\"CLEAR\",\"?SILENT_2\",\"graphRefAll\"]}, \n \"collection\" : {\n \"(\": [\"(\",\"+graphNode\",\")\"]}, \n \"collectionPath\" : {\n \"(\": [\"(\",\"+graphNodePath\",\")\"]}, \n \"conditionalAndExpression\" : {\n \"!\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"+\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"-\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"VAR1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"VAR2\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"(\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"LANG\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"LANGMATCHES\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DATATYPE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"BOUND\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"IRI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"URI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"BNODE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"RAND\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ABS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"CEIL\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"FLOOR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ROUND\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"CONCAT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRLEN\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"UCASE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"LCASE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ENCODE_FOR_URI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"CONTAINS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRSTARTS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRENDS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRBEFORE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRAFTER\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"YEAR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MONTH\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DAY\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"HOURS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MINUTES\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SECONDS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"TIMEZONE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"TZ\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"NOW\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"UUID\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRUUID\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MD5\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA256\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA384\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA512\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"COALESCE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"IF\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRLANG\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRDT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SAMETERM\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISIRI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISURI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISBLANK\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISLITERAL\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISNUMERIC\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"TRUE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"FALSE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"COUNT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SUM\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MIN\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MAX\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"AVG\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SAMPLE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"GROUP_CONCAT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SUBSTR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"REPLACE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"REGEX\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"EXISTS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"NOT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"IRI_REF\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL2\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL_LONG1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL_LONG2\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"INTEGER\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DECIMAL\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DOUBLE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"INTEGER_POSITIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DECIMAL_POSITIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DOUBLE_POSITIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"INTEGER_NEGATIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DECIMAL_NEGATIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DOUBLE_NEGATIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"PNAME_LN\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"PNAME_NS\": [\"valueLogical\",\"*[&&,valueLogical]\"]}, \n \"conditionalOrExpression\" : {\n \"!\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"+\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"-\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"VAR1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"VAR2\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"(\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"LANG\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"LANGMATCHES\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DATATYPE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"BOUND\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"IRI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"URI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"BNODE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"RAND\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ABS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"CEIL\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"FLOOR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ROUND\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"CONCAT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRLEN\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"UCASE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"LCASE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ENCODE_FOR_URI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"CONTAINS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRSTARTS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRENDS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRBEFORE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRAFTER\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"YEAR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MONTH\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DAY\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"HOURS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MINUTES\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SECONDS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"TIMEZONE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"TZ\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"NOW\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"UUID\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRUUID\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MD5\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA256\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA384\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA512\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"COALESCE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"IF\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRLANG\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRDT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SAMETERM\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISIRI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISURI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISBLANK\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISLITERAL\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISNUMERIC\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"TRUE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"FALSE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"COUNT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SUM\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MIN\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MAX\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"AVG\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SAMPLE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"GROUP_CONCAT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SUBSTR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"REPLACE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"REGEX\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"EXISTS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"NOT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"IRI_REF\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL2\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL_LONG1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL_LONG2\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"INTEGER\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DECIMAL\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DOUBLE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"INTEGER_POSITIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DECIMAL_POSITIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DOUBLE_POSITIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"INTEGER_NEGATIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DECIMAL_NEGATIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DOUBLE_NEGATIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"PNAME_LN\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"PNAME_NS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"]}, \n \"constraint\" : {\n \"(\": [\"brackettedExpression\"], \n \"STR\": [\"builtInCall\"], \n \"LANG\": [\"builtInCall\"], \n \"LANGMATCHES\": [\"builtInCall\"], \n \"DATATYPE\": [\"builtInCall\"], \n \"BOUND\": [\"builtInCall\"], \n \"IRI\": [\"builtInCall\"], \n \"URI\": [\"builtInCall\"], \n \"BNODE\": [\"builtInCall\"], \n \"RAND\": [\"builtInCall\"], \n \"ABS\": [\"builtInCall\"], \n \"CEIL\": [\"builtInCall\"], \n \"FLOOR\": [\"builtInCall\"], \n \"ROUND\": [\"builtInCall\"], \n \"CONCAT\": [\"builtInCall\"], \n \"STRLEN\": [\"builtInCall\"], \n \"UCASE\": [\"builtInCall\"], \n \"LCASE\": [\"builtInCall\"], \n \"ENCODE_FOR_URI\": [\"builtInCall\"], \n \"CONTAINS\": [\"builtInCall\"], \n \"STRSTARTS\": [\"builtInCall\"], \n \"STRENDS\": [\"builtInCall\"], \n \"STRBEFORE\": [\"builtInCall\"], \n \"STRAFTER\": [\"builtInCall\"], \n \"YEAR\": [\"builtInCall\"], \n \"MONTH\": [\"builtInCall\"], \n \"DAY\": [\"builtInCall\"], \n \"HOURS\": [\"builtInCall\"], \n \"MINUTES\": [\"builtInCall\"], \n \"SECONDS\": [\"builtInCall\"], \n \"TIMEZONE\": [\"builtInCall\"], \n \"TZ\": [\"builtInCall\"], \n \"NOW\": [\"builtInCall\"], \n \"UUID\": [\"builtInCall\"], \n \"STRUUID\": [\"builtInCall\"], \n \"MD5\": [\"builtInCall\"], \n \"SHA1\": [\"builtInCall\"], \n \"SHA256\": [\"builtInCall\"], \n \"SHA384\": [\"builtInCall\"], \n \"SHA512\": [\"builtInCall\"], \n \"COALESCE\": [\"builtInCall\"], \n \"IF\": [\"builtInCall\"], \n \"STRLANG\": [\"builtInCall\"], \n \"STRDT\": [\"builtInCall\"], \n \"SAMETERM\": [\"builtInCall\"], \n \"ISIRI\": [\"builtInCall\"], \n \"ISURI\": [\"builtInCall\"], \n \"ISBLANK\": [\"builtInCall\"], \n \"ISLITERAL\": [\"builtInCall\"], \n \"ISNUMERIC\": [\"builtInCall\"], \n \"SUBSTR\": [\"builtInCall\"], \n \"REPLACE\": [\"builtInCall\"], \n \"REGEX\": [\"builtInCall\"], \n \"EXISTS\": [\"builtInCall\"], \n \"NOT\": [\"builtInCall\"], \n \"IRI_REF\": [\"functionCall\"], \n \"PNAME_LN\": [\"functionCall\"], \n \"PNAME_NS\": [\"functionCall\"]}, \n \"constructQuery\" : {\n \"CONSTRUCT\": [\"CONSTRUCT\",\"or([[constructTemplate,*datasetClause,whereClause,solutionModifier],[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]])\"]}, \n \"constructTemplate\" : {\n \"{\": [\"{\",\"?constructTriples\",\"}\"]}, \n \"constructTriples\" : {\n \"VAR1\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"VAR2\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"NIL\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"(\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"[\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"IRI_REF\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"TRUE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"FALSE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"BLANK_NODE_LABEL\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"ANON\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"PNAME_LN\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"PNAME_NS\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL1\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL2\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL_LONG1\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL_LONG2\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"INTEGER\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DECIMAL\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DOUBLE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"INTEGER_POSITIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DECIMAL_POSITIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DOUBLE_POSITIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"INTEGER_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DECIMAL_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DOUBLE_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"]}, \n \"copy\" : {\n \"COPY\": [\"COPY\",\"?SILENT_4\",\"graphOrDefault\",\"TO\",\"graphOrDefault\"]}, \n \"create\" : {\n \"CREATE\": [\"CREATE\",\"?SILENT_3\",\"graphRef\"]}, \n \"dataBlock\" : {\n \"NIL\": [\"or([inlineDataOneVar,inlineDataFull])\"], \n \"(\": [\"or([inlineDataOneVar,inlineDataFull])\"], \n \"VAR1\": [\"or([inlineDataOneVar,inlineDataFull])\"], \n \"VAR2\": [\"or([inlineDataOneVar,inlineDataFull])\"]}, \n \"dataBlockValue\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"STRING_LITERAL1\": [\"rdfLiteral\"], \n \"STRING_LITERAL2\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG1\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG2\": [\"rdfLiteral\"], \n \"INTEGER\": [\"numericLiteral\"], \n \"DECIMAL\": [\"numericLiteral\"], \n \"DOUBLE\": [\"numericLiteral\"], \n \"INTEGER_POSITIVE\": [\"numericLiteral\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteral\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteral\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteral\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteral\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteral\"], \n \"TRUE\": [\"booleanLiteral\"], \n \"FALSE\": [\"booleanLiteral\"], \n \"UNDEF\": [\"UNDEF\"]}, \n \"datasetClause\" : {\n \"FROM\": [\"FROM\",\"or([defaultGraphClause,namedGraphClause])\"]}, \n \"defaultGraphClause\" : {\n \"IRI_REF\": [\"sourceSelector\"], \n \"PNAME_LN\": [\"sourceSelector\"], \n \"PNAME_NS\": [\"sourceSelector\"]}, \n \"delete1\" : {\n \"DATA\": [\"DATA\",\"quadDataNoBnodes\"], \n \"WHERE\": [\"WHERE\",\"quadPatternNoBnodes\"], \n \"{\": [\"quadPatternNoBnodes\",\"?insertClause\",\"*usingClause\",\"WHERE\",\"groupGraphPattern\"]}, \n \"deleteClause\" : {\n \"DELETE\": [\"DELETE\",\"quadPattern\"]}, \n \"describeDatasetClause\" : {\n \"FROM\": [\"FROM\",\"or([defaultGraphClause,namedGraphClause])\"]}, \n \"describeQuery\" : {\n \"DESCRIBE\": [\"DESCRIBE\",\"or([+varOrIRIref,*])\",\"*describeDatasetClause\",\"?whereClause\",\"solutionModifier\"]}, \n \"disallowBnodes\" : {\n \"}\": [], \n \"GRAPH\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"(\": [], \n \"[\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"disallowVars\" : {\n \"}\": [], \n \"GRAPH\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"(\": [], \n \"[\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"drop\" : {\n \"DROP\": [\"DROP\",\"?SILENT_2\",\"graphRefAll\"]}, \n \"existsFunc\" : {\n \"EXISTS\": [\"EXISTS\",\"groupGraphPattern\"]}, \n \"expression\" : {\n \"!\": [\"conditionalOrExpression\"], \n \"+\": [\"conditionalOrExpression\"], \n \"-\": [\"conditionalOrExpression\"], \n \"VAR1\": [\"conditionalOrExpression\"], \n \"VAR2\": [\"conditionalOrExpression\"], \n \"(\": [\"conditionalOrExpression\"], \n \"STR\": [\"conditionalOrExpression\"], \n \"LANG\": [\"conditionalOrExpression\"], \n \"LANGMATCHES\": [\"conditionalOrExpression\"], \n \"DATATYPE\": [\"conditionalOrExpression\"], \n \"BOUND\": [\"conditionalOrExpression\"], \n \"IRI\": [\"conditionalOrExpression\"], \n \"URI\": [\"conditionalOrExpression\"], \n \"BNODE\": [\"conditionalOrExpression\"], \n \"RAND\": [\"conditionalOrExpression\"], \n \"ABS\": [\"conditionalOrExpression\"], \n \"CEIL\": [\"conditionalOrExpression\"], \n \"FLOOR\": [\"conditionalOrExpression\"], \n \"ROUND\": [\"conditionalOrExpression\"], \n \"CONCAT\": [\"conditionalOrExpression\"], \n \"STRLEN\": [\"conditionalOrExpression\"], \n \"UCASE\": [\"conditionalOrExpression\"], \n \"LCASE\": [\"conditionalOrExpression\"], \n \"ENCODE_FOR_URI\": [\"conditionalOrExpression\"], \n \"CONTAINS\": [\"conditionalOrExpression\"], \n \"STRSTARTS\": [\"conditionalOrExpression\"], \n \"STRENDS\": [\"conditionalOrExpression\"], \n \"STRBEFORE\": [\"conditionalOrExpression\"], \n \"STRAFTER\": [\"conditionalOrExpression\"], \n \"YEAR\": [\"conditionalOrExpression\"], \n \"MONTH\": [\"conditionalOrExpression\"], \n \"DAY\": [\"conditionalOrExpression\"], \n \"HOURS\": [\"conditionalOrExpression\"], \n \"MINUTES\": [\"conditionalOrExpression\"], \n \"SECONDS\": [\"conditionalOrExpression\"], \n \"TIMEZONE\": [\"conditionalOrExpression\"], \n \"TZ\": [\"conditionalOrExpression\"], \n \"NOW\": [\"conditionalOrExpression\"], \n \"UUID\": [\"conditionalOrExpression\"], \n \"STRUUID\": [\"conditionalOrExpression\"], \n \"MD5\": [\"conditionalOrExpression\"], \n \"SHA1\": [\"conditionalOrExpression\"], \n \"SHA256\": [\"conditionalOrExpression\"], \n \"SHA384\": [\"conditionalOrExpression\"], \n \"SHA512\": [\"conditionalOrExpression\"], \n \"COALESCE\": [\"conditionalOrExpression\"], \n \"IF\": [\"conditionalOrExpression\"], \n \"STRLANG\": [\"conditionalOrExpression\"], \n \"STRDT\": [\"conditionalOrExpression\"], \n \"SAMETERM\": [\"conditionalOrExpression\"], \n \"ISIRI\": [\"conditionalOrExpression\"], \n \"ISURI\": [\"conditionalOrExpression\"], \n \"ISBLANK\": [\"conditionalOrExpression\"], \n \"ISLITERAL\": [\"conditionalOrExpression\"], \n \"ISNUMERIC\": [\"conditionalOrExpression\"], \n \"TRUE\": [\"conditionalOrExpression\"], \n \"FALSE\": [\"conditionalOrExpression\"], \n \"COUNT\": [\"conditionalOrExpression\"], \n \"SUM\": [\"conditionalOrExpression\"], \n \"MIN\": [\"conditionalOrExpression\"], \n \"MAX\": [\"conditionalOrExpression\"], \n \"AVG\": [\"conditionalOrExpression\"], \n \"SAMPLE\": [\"conditionalOrExpression\"], \n \"GROUP_CONCAT\": [\"conditionalOrExpression\"], \n \"SUBSTR\": [\"conditionalOrExpression\"], \n \"REPLACE\": [\"conditionalOrExpression\"], \n \"REGEX\": [\"conditionalOrExpression\"], \n \"EXISTS\": [\"conditionalOrExpression\"], \n \"NOT\": [\"conditionalOrExpression\"], \n \"IRI_REF\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL1\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL2\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL_LONG1\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL_LONG2\": [\"conditionalOrExpression\"], \n \"INTEGER\": [\"conditionalOrExpression\"], \n \"DECIMAL\": [\"conditionalOrExpression\"], \n \"DOUBLE\": [\"conditionalOrExpression\"], \n \"INTEGER_POSITIVE\": [\"conditionalOrExpression\"], \n \"DECIMAL_POSITIVE\": [\"conditionalOrExpression\"], \n \"DOUBLE_POSITIVE\": [\"conditionalOrExpression\"], \n \"INTEGER_NEGATIVE\": [\"conditionalOrExpression\"], \n \"DECIMAL_NEGATIVE\": [\"conditionalOrExpression\"], \n \"DOUBLE_NEGATIVE\": [\"conditionalOrExpression\"], \n \"PNAME_LN\": [\"conditionalOrExpression\"], \n \"PNAME_NS\": [\"conditionalOrExpression\"]}, \n \"expressionList\" : {\n \"NIL\": [\"NIL\"], \n \"(\": [\"(\",\"expression\",\"*[,,expression]\",\")\"]}, \n \"filter\" : {\n \"FILTER\": [\"FILTER\",\"constraint\"]}, \n \"functionCall\" : {\n \"IRI_REF\": [\"iriRef\",\"argList\"], \n \"PNAME_LN\": [\"iriRef\",\"argList\"], \n \"PNAME_NS\": [\"iriRef\",\"argList\"]}, \n \"graphGraphPattern\" : {\n \"GRAPH\": [\"GRAPH\",\"varOrIRIref\",\"groupGraphPattern\"]}, \n \"graphNode\" : {\n \"VAR1\": [\"varOrTerm\"], \n \"VAR2\": [\"varOrTerm\"], \n \"NIL\": [\"varOrTerm\"], \n \"IRI_REF\": [\"varOrTerm\"], \n \"TRUE\": [\"varOrTerm\"], \n \"FALSE\": [\"varOrTerm\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\"], \n \"ANON\": [\"varOrTerm\"], \n \"PNAME_LN\": [\"varOrTerm\"], \n \"PNAME_NS\": [\"varOrTerm\"], \n \"STRING_LITERAL1\": [\"varOrTerm\"], \n \"STRING_LITERAL2\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\"], \n \"INTEGER\": [\"varOrTerm\"], \n \"DECIMAL\": [\"varOrTerm\"], \n \"DOUBLE\": [\"varOrTerm\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\"], \n \"(\": [\"triplesNode\"], \n \"[\": [\"triplesNode\"]}, \n \"graphNodePath\" : {\n \"VAR1\": [\"varOrTerm\"], \n \"VAR2\": [\"varOrTerm\"], \n \"NIL\": [\"varOrTerm\"], \n \"IRI_REF\": [\"varOrTerm\"], \n \"TRUE\": [\"varOrTerm\"], \n \"FALSE\": [\"varOrTerm\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\"], \n \"ANON\": [\"varOrTerm\"], \n \"PNAME_LN\": [\"varOrTerm\"], \n \"PNAME_NS\": [\"varOrTerm\"], \n \"STRING_LITERAL1\": [\"varOrTerm\"], \n \"STRING_LITERAL2\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\"], \n \"INTEGER\": [\"varOrTerm\"], \n \"DECIMAL\": [\"varOrTerm\"], \n \"DOUBLE\": [\"varOrTerm\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\"], \n \"(\": [\"triplesNodePath\"], \n \"[\": [\"triplesNodePath\"]}, \n \"graphOrDefault\" : {\n \"DEFAULT\": [\"DEFAULT\"], \n \"IRI_REF\": [\"?GRAPH\",\"iriRef\"], \n \"PNAME_LN\": [\"?GRAPH\",\"iriRef\"], \n \"PNAME_NS\": [\"?GRAPH\",\"iriRef\"], \n \"GRAPH\": [\"?GRAPH\",\"iriRef\"]}, \n \"graphPatternNotTriples\" : {\n \"{\": [\"groupOrUnionGraphPattern\"], \n \"OPTIONAL\": [\"optionalGraphPattern\"], \n \"MINUS\": [\"minusGraphPattern\"], \n \"GRAPH\": [\"graphGraphPattern\"], \n \"SERVICE\": [\"serviceGraphPattern\"], \n \"FILTER\": [\"filter\"], \n \"BIND\": [\"bind\"], \n \"VALUES\": [\"inlineData\"]}, \n \"graphRef\" : {\n \"GRAPH\": [\"GRAPH\",\"iriRef\"]}, \n \"graphRefAll\" : {\n \"GRAPH\": [\"graphRef\"], \n \"DEFAULT\": [\"DEFAULT\"], \n \"NAMED\": [\"NAMED\"], \n \"ALL\": [\"ALL\"]}, \n \"graphTerm\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"STRING_LITERAL1\": [\"rdfLiteral\"], \n \"STRING_LITERAL2\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG1\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG2\": [\"rdfLiteral\"], \n \"INTEGER\": [\"numericLiteral\"], \n \"DECIMAL\": [\"numericLiteral\"], \n \"DOUBLE\": [\"numericLiteral\"], \n \"INTEGER_POSITIVE\": [\"numericLiteral\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteral\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteral\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteral\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteral\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteral\"], \n \"TRUE\": [\"booleanLiteral\"], \n \"FALSE\": [\"booleanLiteral\"], \n \"BLANK_NODE_LABEL\": [\"blankNode\"], \n \"ANON\": [\"blankNode\"], \n \"NIL\": [\"NIL\"]}, \n \"groupClause\" : {\n \"GROUP\": [\"GROUP\",\"BY\",\"+groupCondition\"]}, \n \"groupCondition\" : {\n \"STR\": [\"builtInCall\"], \n \"LANG\": [\"builtInCall\"], \n \"LANGMATCHES\": [\"builtInCall\"], \n \"DATATYPE\": [\"builtInCall\"], \n \"BOUND\": [\"builtInCall\"], \n \"IRI\": [\"builtInCall\"], \n \"URI\": [\"builtInCall\"], \n \"BNODE\": [\"builtInCall\"], \n \"RAND\": [\"builtInCall\"], \n \"ABS\": [\"builtInCall\"], \n \"CEIL\": [\"builtInCall\"], \n \"FLOOR\": [\"builtInCall\"], \n \"ROUND\": [\"builtInCall\"], \n \"CONCAT\": [\"builtInCall\"], \n \"STRLEN\": [\"builtInCall\"], \n \"UCASE\": [\"builtInCall\"], \n \"LCASE\": [\"builtInCall\"], \n \"ENCODE_FOR_URI\": [\"builtInCall\"], \n \"CONTAINS\": [\"builtInCall\"], \n \"STRSTARTS\": [\"builtInCall\"], \n \"STRENDS\": [\"builtInCall\"], \n \"STRBEFORE\": [\"builtInCall\"], \n \"STRAFTER\": [\"builtInCall\"], \n \"YEAR\": [\"builtInCall\"], \n \"MONTH\": [\"builtInCall\"], \n \"DAY\": [\"builtInCall\"], \n \"HOURS\": [\"builtInCall\"], \n \"MINUTES\": [\"builtInCall\"], \n \"SECONDS\": [\"builtInCall\"], \n \"TIMEZONE\": [\"builtInCall\"], \n \"TZ\": [\"builtInCall\"], \n \"NOW\": [\"builtInCall\"], \n \"UUID\": [\"builtInCall\"], \n \"STRUUID\": [\"builtInCall\"], \n \"MD5\": [\"builtInCall\"], \n \"SHA1\": [\"builtInCall\"], \n \"SHA256\": [\"builtInCall\"], \n \"SHA384\": [\"builtInCall\"], \n \"SHA512\": [\"builtInCall\"], \n \"COALESCE\": [\"builtInCall\"], \n \"IF\": [\"builtInCall\"], \n \"STRLANG\": [\"builtInCall\"], \n \"STRDT\": [\"builtInCall\"], \n \"SAMETERM\": [\"builtInCall\"], \n \"ISIRI\": [\"builtInCall\"], \n \"ISURI\": [\"builtInCall\"], \n \"ISBLANK\": [\"builtInCall\"], \n \"ISLITERAL\": [\"builtInCall\"], \n \"ISNUMERIC\": [\"builtInCall\"], \n \"SUBSTR\": [\"builtInCall\"], \n \"REPLACE\": [\"builtInCall\"], \n \"REGEX\": [\"builtInCall\"], \n \"EXISTS\": [\"builtInCall\"], \n \"NOT\": [\"builtInCall\"], \n \"IRI_REF\": [\"functionCall\"], \n \"PNAME_LN\": [\"functionCall\"], \n \"PNAME_NS\": [\"functionCall\"], \n \"(\": [\"(\",\"expression\",\"?[AS,var]\",\")\"], \n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"]}, \n \"groupGraphPattern\" : {\n \"{\": [\"{\",\"or([subSelect,groupGraphPatternSub])\",\"}\"]}, \n \"groupGraphPatternSub\" : {\n \"{\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"OPTIONAL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"MINUS\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"GRAPH\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"SERVICE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"FILTER\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"BIND\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"VALUES\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"VAR1\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"VAR2\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"NIL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"(\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"[\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"IRI_REF\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"TRUE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"FALSE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"BLANK_NODE_LABEL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"ANON\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"PNAME_LN\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"PNAME_NS\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL1\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL2\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG1\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG2\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"INTEGER\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DECIMAL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DOUBLE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"INTEGER_POSITIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DECIMAL_POSITIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DOUBLE_POSITIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"INTEGER_NEGATIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DECIMAL_NEGATIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DOUBLE_NEGATIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"}\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"]}, \n \"groupOrUnionGraphPattern\" : {\n \"{\": [\"groupGraphPattern\",\"*[UNION,groupGraphPattern]\"]}, \n \"havingClause\" : {\n \"HAVING\": [\"HAVING\",\"+havingCondition\"]}, \n \"havingCondition\" : {\n \"(\": [\"constraint\"], \n \"STR\": [\"constraint\"], \n \"LANG\": [\"constraint\"], \n \"LANGMATCHES\": [\"constraint\"], \n \"DATATYPE\": [\"constraint\"], \n \"BOUND\": [\"constraint\"], \n \"IRI\": [\"constraint\"], \n \"URI\": [\"constraint\"], \n \"BNODE\": [\"constraint\"], \n \"RAND\": [\"constraint\"], \n \"ABS\": [\"constraint\"], \n \"CEIL\": [\"constraint\"], \n \"FLOOR\": [\"constraint\"], \n \"ROUND\": [\"constraint\"], \n \"CONCAT\": [\"constraint\"], \n \"STRLEN\": [\"constraint\"], \n \"UCASE\": [\"constraint\"], \n \"LCASE\": [\"constraint\"], \n \"ENCODE_FOR_URI\": [\"constraint\"], \n \"CONTAINS\": [\"constraint\"], \n \"STRSTARTS\": [\"constraint\"], \n \"STRENDS\": [\"constraint\"], \n \"STRBEFORE\": [\"constraint\"], \n \"STRAFTER\": [\"constraint\"], \n \"YEAR\": [\"constraint\"], \n \"MONTH\": [\"constraint\"], \n \"DAY\": [\"constraint\"], \n \"HOURS\": [\"constraint\"], \n \"MINUTES\": [\"constraint\"], \n \"SECONDS\": [\"constraint\"], \n \"TIMEZONE\": [\"constraint\"], \n \"TZ\": [\"constraint\"], \n \"NOW\": [\"constraint\"], \n \"UUID\": [\"constraint\"], \n \"STRUUID\": [\"constraint\"], \n \"MD5\": [\"constraint\"], \n \"SHA1\": [\"constraint\"], \n \"SHA256\": [\"constraint\"], \n \"SHA384\": [\"constraint\"], \n \"SHA512\": [\"constraint\"], \n \"COALESCE\": [\"constraint\"], \n \"IF\": [\"constraint\"], \n \"STRLANG\": [\"constraint\"], \n \"STRDT\": [\"constraint\"], \n \"SAMETERM\": [\"constraint\"], \n \"ISIRI\": [\"constraint\"], \n \"ISURI\": [\"constraint\"], \n \"ISBLANK\": [\"constraint\"], \n \"ISLITERAL\": [\"constraint\"], \n \"ISNUMERIC\": [\"constraint\"], \n \"SUBSTR\": [\"constraint\"], \n \"REPLACE\": [\"constraint\"], \n \"REGEX\": [\"constraint\"], \n \"EXISTS\": [\"constraint\"], \n \"NOT\": [\"constraint\"], \n \"IRI_REF\": [\"constraint\"], \n \"PNAME_LN\": [\"constraint\"], \n \"PNAME_NS\": [\"constraint\"]}, \n \"inlineData\" : {\n \"VALUES\": [\"VALUES\",\"dataBlock\"]}, \n \"inlineDataFull\" : {\n \"NIL\": [\"or([NIL,[ (,*var,)]])\",\"{\",\"*or([[ (,*dataBlockValue,)],NIL])\",\"}\"], \n \"(\": [\"or([NIL,[ (,*var,)]])\",\"{\",\"*or([[ (,*dataBlockValue,)],NIL])\",\"}\"]}, \n \"inlineDataOneVar\" : {\n \"VAR1\": [\"var\",\"{\",\"*dataBlockValue\",\"}\"], \n \"VAR2\": [\"var\",\"{\",\"*dataBlockValue\",\"}\"]}, \n \"insert1\" : {\n \"DATA\": [\"DATA\",\"quadData\"], \n \"{\": [\"quadPattern\",\"*usingClause\",\"WHERE\",\"groupGraphPattern\"]}, \n \"insertClause\" : {\n \"INSERT\": [\"INSERT\",\"quadPattern\"]}, \n \"integer\" : {\n \"INTEGER\": [\"INTEGER\"]}, \n \"iriRef\" : {\n \"IRI_REF\": [\"IRI_REF\"], \n \"PNAME_LN\": [\"prefixedName\"], \n \"PNAME_NS\": [\"prefixedName\"]}, \n \"iriRefOrFunction\" : {\n \"IRI_REF\": [\"iriRef\",\"?argList\"], \n \"PNAME_LN\": [\"iriRef\",\"?argList\"], \n \"PNAME_NS\": [\"iriRef\",\"?argList\"]}, \n \"limitClause\" : {\n \"LIMIT\": [\"LIMIT\",\"INTEGER\"]}, \n \"limitOffsetClauses\" : {\n \"LIMIT\": [\"limitClause\",\"?offsetClause\"], \n \"OFFSET\": [\"offsetClause\",\"?limitClause\"]}, \n \"load\" : {\n \"LOAD\": [\"LOAD\",\"?SILENT_1\",\"iriRef\",\"?[INTO,graphRef]\"]}, \n \"minusGraphPattern\" : {\n \"MINUS\": [\"MINUS\",\"groupGraphPattern\"]}, \n \"modify\" : {\n \"WITH\": [\"WITH\",\"iriRef\",\"or([[deleteClause,?insertClause],insertClause])\",\"*usingClause\",\"WHERE\",\"groupGraphPattern\"]}, \n \"move\" : {\n \"MOVE\": [\"MOVE\",\"?SILENT_4\",\"graphOrDefault\",\"TO\",\"graphOrDefault\"]}, \n \"multiplicativeExpression\" : {\n \"!\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"+\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"-\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"VAR1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"VAR2\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"(\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"LANG\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"LANGMATCHES\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DATATYPE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"BOUND\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"IRI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"URI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"BNODE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"RAND\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ABS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"CEIL\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"FLOOR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ROUND\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"CONCAT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRLEN\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"UCASE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"LCASE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ENCODE_FOR_URI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"CONTAINS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRSTARTS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRENDS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRBEFORE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRAFTER\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"YEAR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MONTH\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DAY\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"HOURS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MINUTES\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SECONDS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"TIMEZONE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"TZ\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"NOW\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"UUID\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRUUID\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MD5\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA256\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA384\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA512\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"COALESCE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"IF\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRLANG\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRDT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SAMETERM\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISIRI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISURI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISBLANK\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISLITERAL\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISNUMERIC\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"TRUE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"FALSE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"COUNT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SUM\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MIN\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MAX\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"AVG\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SAMPLE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"GROUP_CONCAT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SUBSTR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"REPLACE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"REGEX\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"EXISTS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"NOT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"IRI_REF\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL2\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL_LONG1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL_LONG2\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER_POSITIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_POSITIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_POSITIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER_NEGATIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_NEGATIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_NEGATIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"PNAME_LN\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"PNAME_NS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"]}, \n \"namedGraphClause\" : {\n \"NAMED\": [\"NAMED\",\"sourceSelector\"]}, \n \"notExistsFunc\" : {\n \"NOT\": [\"NOT\",\"EXISTS\",\"groupGraphPattern\"]}, \n \"numericExpression\" : {\n \"!\": [\"additiveExpression\"], \n \"+\": [\"additiveExpression\"], \n \"-\": [\"additiveExpression\"], \n \"VAR1\": [\"additiveExpression\"], \n \"VAR2\": [\"additiveExpression\"], \n \"(\": [\"additiveExpression\"], \n \"STR\": [\"additiveExpression\"], \n \"LANG\": [\"additiveExpression\"], \n \"LANGMATCHES\": [\"additiveExpression\"], \n \"DATATYPE\": [\"additiveExpression\"], \n \"BOUND\": [\"additiveExpression\"], \n \"IRI\": [\"additiveExpression\"], \n \"URI\": [\"additiveExpression\"], \n \"BNODE\": [\"additiveExpression\"], \n \"RAND\": [\"additiveExpression\"], \n \"ABS\": [\"additiveExpression\"], \n \"CEIL\": [\"additiveExpression\"], \n \"FLOOR\": [\"additiveExpression\"], \n \"ROUND\": [\"additiveExpression\"], \n \"CONCAT\": [\"additiveExpression\"], \n \"STRLEN\": [\"additiveExpression\"], \n \"UCASE\": [\"additiveExpression\"], \n \"LCASE\": [\"additiveExpression\"], \n \"ENCODE_FOR_URI\": [\"additiveExpression\"], \n \"CONTAINS\": [\"additiveExpression\"], \n \"STRSTARTS\": [\"additiveExpression\"], \n \"STRENDS\": [\"additiveExpression\"], \n \"STRBEFORE\": [\"additiveExpression\"], \n \"STRAFTER\": [\"additiveExpression\"], \n \"YEAR\": [\"additiveExpression\"], \n \"MONTH\": [\"additiveExpression\"], \n \"DAY\": [\"additiveExpression\"], \n \"HOURS\": [\"additiveExpression\"], \n \"MINUTES\": [\"additiveExpression\"], \n \"SECONDS\": [\"additiveExpression\"], \n \"TIMEZONE\": [\"additiveExpression\"], \n \"TZ\": [\"additiveExpression\"], \n \"NOW\": [\"additiveExpression\"], \n \"UUID\": [\"additiveExpression\"], \n \"STRUUID\": [\"additiveExpression\"], \n \"MD5\": [\"additiveExpression\"], \n \"SHA1\": [\"additiveExpression\"], \n \"SHA256\": [\"additiveExpression\"], \n \"SHA384\": [\"additiveExpression\"], \n \"SHA512\": [\"additiveExpression\"], \n \"COALESCE\": [\"additiveExpression\"], \n \"IF\": [\"additiveExpression\"], \n \"STRLANG\": [\"additiveExpression\"], \n \"STRDT\": [\"additiveExpression\"], \n \"SAMETERM\": [\"additiveExpression\"], \n \"ISIRI\": [\"additiveExpression\"], \n \"ISURI\": [\"additiveExpression\"], \n \"ISBLANK\": [\"additiveExpression\"], \n \"ISLITERAL\": [\"additiveExpression\"], \n \"ISNUMERIC\": [\"additiveExpression\"], \n \"TRUE\": [\"additiveExpression\"], \n \"FALSE\": [\"additiveExpression\"], \n \"COUNT\": [\"additiveExpression\"], \n \"SUM\": [\"additiveExpression\"], \n \"MIN\": [\"additiveExpression\"], \n \"MAX\": [\"additiveExpression\"], \n \"AVG\": [\"additiveExpression\"], \n \"SAMPLE\": [\"additiveExpression\"], \n \"GROUP_CONCAT\": [\"additiveExpression\"], \n \"SUBSTR\": [\"additiveExpression\"], \n \"REPLACE\": [\"additiveExpression\"], \n \"REGEX\": [\"additiveExpression\"], \n \"EXISTS\": [\"additiveExpression\"], \n \"NOT\": [\"additiveExpression\"], \n \"IRI_REF\": [\"additiveExpression\"], \n \"STRING_LITERAL1\": [\"additiveExpression\"], \n \"STRING_LITERAL2\": [\"additiveExpression\"], \n \"STRING_LITERAL_LONG1\": [\"additiveExpression\"], \n \"STRING_LITERAL_LONG2\": [\"additiveExpression\"], \n \"INTEGER\": [\"additiveExpression\"], \n \"DECIMAL\": [\"additiveExpression\"], \n \"DOUBLE\": [\"additiveExpression\"], \n \"INTEGER_POSITIVE\": [\"additiveExpression\"], \n \"DECIMAL_POSITIVE\": [\"additiveExpression\"], \n \"DOUBLE_POSITIVE\": [\"additiveExpression\"], \n \"INTEGER_NEGATIVE\": [\"additiveExpression\"], \n \"DECIMAL_NEGATIVE\": [\"additiveExpression\"], \n \"DOUBLE_NEGATIVE\": [\"additiveExpression\"], \n \"PNAME_LN\": [\"additiveExpression\"], \n \"PNAME_NS\": [\"additiveExpression\"]}, \n \"numericLiteral\" : {\n \"INTEGER\": [\"numericLiteralUnsigned\"], \n \"DECIMAL\": [\"numericLiteralUnsigned\"], \n \"DOUBLE\": [\"numericLiteralUnsigned\"], \n \"INTEGER_POSITIVE\": [\"numericLiteralPositive\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteralPositive\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteralPositive\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteralNegative\"]}, \n \"numericLiteralNegative\" : {\n \"INTEGER_NEGATIVE\": [\"INTEGER_NEGATIVE\"], \n \"DECIMAL_NEGATIVE\": [\"DECIMAL_NEGATIVE\"], \n \"DOUBLE_NEGATIVE\": [\"DOUBLE_NEGATIVE\"]}, \n \"numericLiteralPositive\" : {\n \"INTEGER_POSITIVE\": [\"INTEGER_POSITIVE\"], \n \"DECIMAL_POSITIVE\": [\"DECIMAL_POSITIVE\"], \n \"DOUBLE_POSITIVE\": [\"DOUBLE_POSITIVE\"]}, \n \"numericLiteralUnsigned\" : {\n \"INTEGER\": [\"INTEGER\"], \n \"DECIMAL\": [\"DECIMAL\"], \n \"DOUBLE\": [\"DOUBLE\"]}, \n \"object\" : {\n \"(\": [\"graphNode\"], \n \"[\": [\"graphNode\"], \n \"VAR1\": [\"graphNode\"], \n \"VAR2\": [\"graphNode\"], \n \"NIL\": [\"graphNode\"], \n \"IRI_REF\": [\"graphNode\"], \n \"TRUE\": [\"graphNode\"], \n \"FALSE\": [\"graphNode\"], \n \"BLANK_NODE_LABEL\": [\"graphNode\"], \n \"ANON\": [\"graphNode\"], \n \"PNAME_LN\": [\"graphNode\"], \n \"PNAME_NS\": [\"graphNode\"], \n \"STRING_LITERAL1\": [\"graphNode\"], \n \"STRING_LITERAL2\": [\"graphNode\"], \n \"STRING_LITERAL_LONG1\": [\"graphNode\"], \n \"STRING_LITERAL_LONG2\": [\"graphNode\"], \n \"INTEGER\": [\"graphNode\"], \n \"DECIMAL\": [\"graphNode\"], \n \"DOUBLE\": [\"graphNode\"], \n \"INTEGER_POSITIVE\": [\"graphNode\"], \n \"DECIMAL_POSITIVE\": [\"graphNode\"], \n \"DOUBLE_POSITIVE\": [\"graphNode\"], \n \"INTEGER_NEGATIVE\": [\"graphNode\"], \n \"DECIMAL_NEGATIVE\": [\"graphNode\"], \n \"DOUBLE_NEGATIVE\": [\"graphNode\"]}, \n \"objectList\" : {\n \"(\": [\"object\",\"*[,,object]\"], \n \"[\": [\"object\",\"*[,,object]\"], \n \"VAR1\": [\"object\",\"*[,,object]\"], \n \"VAR2\": [\"object\",\"*[,,object]\"], \n \"NIL\": [\"object\",\"*[,,object]\"], \n \"IRI_REF\": [\"object\",\"*[,,object]\"], \n \"TRUE\": [\"object\",\"*[,,object]\"], \n \"FALSE\": [\"object\",\"*[,,object]\"], \n \"BLANK_NODE_LABEL\": [\"object\",\"*[,,object]\"], \n \"ANON\": [\"object\",\"*[,,object]\"], \n \"PNAME_LN\": [\"object\",\"*[,,object]\"], \n \"PNAME_NS\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL1\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL2\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL_LONG1\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL_LONG2\": [\"object\",\"*[,,object]\"], \n \"INTEGER\": [\"object\",\"*[,,object]\"], \n \"DECIMAL\": [\"object\",\"*[,,object]\"], \n \"DOUBLE\": [\"object\",\"*[,,object]\"], \n \"INTEGER_POSITIVE\": [\"object\",\"*[,,object]\"], \n \"DECIMAL_POSITIVE\": [\"object\",\"*[,,object]\"], \n \"DOUBLE_POSITIVE\": [\"object\",\"*[,,object]\"], \n \"INTEGER_NEGATIVE\": [\"object\",\"*[,,object]\"], \n \"DECIMAL_NEGATIVE\": [\"object\",\"*[,,object]\"], \n \"DOUBLE_NEGATIVE\": [\"object\",\"*[,,object]\"]}, \n \"objectListPath\" : {\n \"(\": [\"objectPath\",\"*[,,objectPath]\"], \n \"[\": [\"objectPath\",\"*[,,objectPath]\"], \n \"VAR1\": [\"objectPath\",\"*[,,objectPath]\"], \n \"VAR2\": [\"objectPath\",\"*[,,objectPath]\"], \n \"NIL\": [\"objectPath\",\"*[,,objectPath]\"], \n \"IRI_REF\": [\"objectPath\",\"*[,,objectPath]\"], \n \"TRUE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"FALSE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"BLANK_NODE_LABEL\": [\"objectPath\",\"*[,,objectPath]\"], \n \"ANON\": [\"objectPath\",\"*[,,objectPath]\"], \n \"PNAME_LN\": [\"objectPath\",\"*[,,objectPath]\"], \n \"PNAME_NS\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL1\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL2\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL_LONG1\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL_LONG2\": [\"objectPath\",\"*[,,objectPath]\"], \n \"INTEGER\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DECIMAL\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DOUBLE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"INTEGER_POSITIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DECIMAL_POSITIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DOUBLE_POSITIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"INTEGER_NEGATIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DECIMAL_NEGATIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DOUBLE_NEGATIVE\": [\"objectPath\",\"*[,,objectPath]\"]}, \n \"objectPath\" : {\n \"(\": [\"graphNodePath\"], \n \"[\": [\"graphNodePath\"], \n \"VAR1\": [\"graphNodePath\"], \n \"VAR2\": [\"graphNodePath\"], \n \"NIL\": [\"graphNodePath\"], \n \"IRI_REF\": [\"graphNodePath\"], \n \"TRUE\": [\"graphNodePath\"], \n \"FALSE\": [\"graphNodePath\"], \n \"BLANK_NODE_LABEL\": [\"graphNodePath\"], \n \"ANON\": [\"graphNodePath\"], \n \"PNAME_LN\": [\"graphNodePath\"], \n \"PNAME_NS\": [\"graphNodePath\"], \n \"STRING_LITERAL1\": [\"graphNodePath\"], \n \"STRING_LITERAL2\": [\"graphNodePath\"], \n \"STRING_LITERAL_LONG1\": [\"graphNodePath\"], \n \"STRING_LITERAL_LONG2\": [\"graphNodePath\"], \n \"INTEGER\": [\"graphNodePath\"], \n \"DECIMAL\": [\"graphNodePath\"], \n \"DOUBLE\": [\"graphNodePath\"], \n \"INTEGER_POSITIVE\": [\"graphNodePath\"], \n \"DECIMAL_POSITIVE\": [\"graphNodePath\"], \n \"DOUBLE_POSITIVE\": [\"graphNodePath\"], \n \"INTEGER_NEGATIVE\": [\"graphNodePath\"], \n \"DECIMAL_NEGATIVE\": [\"graphNodePath\"], \n \"DOUBLE_NEGATIVE\": [\"graphNodePath\"]}, \n \"offsetClause\" : {\n \"OFFSET\": [\"OFFSET\",\"INTEGER\"]}, \n \"optionalGraphPattern\" : {\n \"OPTIONAL\": [\"OPTIONAL\",\"groupGraphPattern\"]}, \n \"or([*,expression])\" : {\n \"*\": [\"*\"], \n \"!\": [\"expression\"], \n \"+\": [\"expression\"], \n \"-\": [\"expression\"], \n \"VAR1\": [\"expression\"], \n \"VAR2\": [\"expression\"], \n \"(\": [\"expression\"], \n \"STR\": [\"expression\"], \n \"LANG\": [\"expression\"], \n \"LANGMATCHES\": [\"expression\"], \n \"DATATYPE\": [\"expression\"], \n \"BOUND\": [\"expression\"], \n \"IRI\": [\"expression\"], \n \"URI\": [\"expression\"], \n \"BNODE\": [\"expression\"], \n \"RAND\": [\"expression\"], \n \"ABS\": [\"expression\"], \n \"CEIL\": [\"expression\"], \n \"FLOOR\": [\"expression\"], \n \"ROUND\": [\"expression\"], \n \"CONCAT\": [\"expression\"], \n \"STRLEN\": [\"expression\"], \n \"UCASE\": [\"expression\"], \n \"LCASE\": [\"expression\"], \n \"ENCODE_FOR_URI\": [\"expression\"], \n \"CONTAINS\": [\"expression\"], \n \"STRSTARTS\": [\"expression\"], \n \"STRENDS\": [\"expression\"], \n \"STRBEFORE\": [\"expression\"], \n \"STRAFTER\": [\"expression\"], \n \"YEAR\": [\"expression\"], \n \"MONTH\": [\"expression\"], \n \"DAY\": [\"expression\"], \n \"HOURS\": [\"expression\"], \n \"MINUTES\": [\"expression\"], \n \"SECONDS\": [\"expression\"], \n \"TIMEZONE\": [\"expression\"], \n \"TZ\": [\"expression\"], \n \"NOW\": [\"expression\"], \n \"UUID\": [\"expression\"], \n \"STRUUID\": [\"expression\"], \n \"MD5\": [\"expression\"], \n \"SHA1\": [\"expression\"], \n \"SHA256\": [\"expression\"], \n \"SHA384\": [\"expression\"], \n \"SHA512\": [\"expression\"], \n \"COALESCE\": [\"expression\"], \n \"IF\": [\"expression\"], \n \"STRLANG\": [\"expression\"], \n \"STRDT\": [\"expression\"], \n \"SAMETERM\": [\"expression\"], \n \"ISIRI\": [\"expression\"], \n \"ISURI\": [\"expression\"], \n \"ISBLANK\": [\"expression\"], \n \"ISLITERAL\": [\"expression\"], \n \"ISNUMERIC\": [\"expression\"], \n \"TRUE\": [\"expression\"], \n \"FALSE\": [\"expression\"], \n \"COUNT\": [\"expression\"], \n \"SUM\": [\"expression\"], \n \"MIN\": [\"expression\"], \n \"MAX\": [\"expression\"], \n \"AVG\": [\"expression\"], \n \"SAMPLE\": [\"expression\"], \n \"GROUP_CONCAT\": [\"expression\"], \n \"SUBSTR\": [\"expression\"], \n \"REPLACE\": [\"expression\"], \n \"REGEX\": [\"expression\"], \n \"EXISTS\": [\"expression\"], \n \"NOT\": [\"expression\"], \n \"IRI_REF\": [\"expression\"], \n \"STRING_LITERAL1\": [\"expression\"], \n \"STRING_LITERAL2\": [\"expression\"], \n \"STRING_LITERAL_LONG1\": [\"expression\"], \n \"STRING_LITERAL_LONG2\": [\"expression\"], \n \"INTEGER\": [\"expression\"], \n \"DECIMAL\": [\"expression\"], \n \"DOUBLE\": [\"expression\"], \n \"INTEGER_POSITIVE\": [\"expression\"], \n \"DECIMAL_POSITIVE\": [\"expression\"], \n \"DOUBLE_POSITIVE\": [\"expression\"], \n \"INTEGER_NEGATIVE\": [\"expression\"], \n \"DECIMAL_NEGATIVE\": [\"expression\"], \n \"DOUBLE_NEGATIVE\": [\"expression\"], \n \"PNAME_LN\": [\"expression\"], \n \"PNAME_NS\": [\"expression\"]}, \n \"or([+or([var,[ (,expression,AS,var,)]]),*])\" : {\n \"(\": [\"+or([var,[ (,expression,AS,var,)]])\"], \n \"VAR1\": [\"+or([var,[ (,expression,AS,var,)]])\"], \n \"VAR2\": [\"+or([var,[ (,expression,AS,var,)]])\"], \n \"*\": [\"*\"]}, \n \"or([+varOrIRIref,*])\" : {\n \"VAR1\": [\"+varOrIRIref\"], \n \"VAR2\": [\"+varOrIRIref\"], \n \"IRI_REF\": [\"+varOrIRIref\"], \n \"PNAME_LN\": [\"+varOrIRIref\"], \n \"PNAME_NS\": [\"+varOrIRIref\"], \n \"*\": [\"*\"]}, \n \"or([ASC,DESC])\" : {\n \"ASC\": [\"ASC\"], \n \"DESC\": [\"DESC\"]}, \n \"or([DISTINCT,REDUCED])\" : {\n \"DISTINCT\": [\"DISTINCT\"], \n \"REDUCED\": [\"REDUCED\"]}, \n \"or([LANGTAG,[^^,iriRef]])\" : {\n \"LANGTAG\": [\"LANGTAG\"], \n \"^^\": [\"[^^,iriRef]\"]}, \n \"or([NIL,[ (,*var,)]])\" : {\n \"NIL\": [\"NIL\"], \n \"(\": [\"[ (,*var,)]\"]}, \n \"or([[ (,*dataBlockValue,)],NIL])\" : {\n \"(\": [\"[ (,*dataBlockValue,)]\"], \n \"NIL\": [\"NIL\"]}, \n \"or([[ (,expression,)],NIL])\" : {\n \"(\": [\"[ (,expression,)]\"], \n \"NIL\": [\"NIL\"]}, \n \"or([[*,unaryExpression],[/,unaryExpression]])\" : {\n \"*\": [\"[*,unaryExpression]\"], \n \"/\": [\"[/,unaryExpression]\"]}, \n \"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\" : {\n \"+\": [\"[+,multiplicativeExpression]\"], \n \"-\": [\"[-,multiplicativeExpression]\"], \n \"INTEGER_POSITIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DECIMAL_POSITIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DOUBLE_POSITIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"INTEGER_NEGATIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DECIMAL_NEGATIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DOUBLE_NEGATIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"]}, \n \"or([[,,or([},[integer,}]])],}])\" : {\n \",\": [\"[,,or([},[integer,}]])]\"], \n \"}\": [\"}\"]}, \n \"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\" : {\n \"=\": [\"[=,numericExpression]\"], \n \"!=\": [\"[!=,numericExpression]\"], \n \"<\": [\"[<,numericExpression]\"], \n \">\": [\"[>,numericExpression]\"], \n \"<=\": [\"[<=,numericExpression]\"], \n \">=\": [\"[>=,numericExpression]\"], \n \"IN\": [\"[IN,expressionList]\"], \n \"NOT\": [\"[NOT,IN,expressionList]\"]}, \n \"or([[constructTemplate,*datasetClause,whereClause,solutionModifier],[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]])\" : {\n \"{\": [\"[constructTemplate,*datasetClause,whereClause,solutionModifier]\"], \n \"WHERE\": [\"[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]\"], \n \"FROM\": [\"[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]\"]}, \n \"or([[deleteClause,?insertClause],insertClause])\" : {\n \"DELETE\": [\"[deleteClause,?insertClause]\"], \n \"INSERT\": [\"insertClause\"]}, \n \"or([[integer,or([[,,or([},[integer,}]])],}])],[,,integer,}]])\" : {\n \"INTEGER\": [\"[integer,or([[,,or([},[integer,}]])],}])]\"], \n \",\": [\"[,,integer,}]\"]}, \n \"or([baseDecl,prefixDecl])\" : {\n \"BASE\": [\"baseDecl\"], \n \"PREFIX\": [\"prefixDecl\"]}, \n \"or([defaultGraphClause,namedGraphClause])\" : {\n \"IRI_REF\": [\"defaultGraphClause\"], \n \"PNAME_LN\": [\"defaultGraphClause\"], \n \"PNAME_NS\": [\"defaultGraphClause\"], \n \"NAMED\": [\"namedGraphClause\"]}, \n \"or([inlineDataOneVar,inlineDataFull])\" : {\n \"VAR1\": [\"inlineDataOneVar\"], \n \"VAR2\": [\"inlineDataOneVar\"], \n \"NIL\": [\"inlineDataFull\"], \n \"(\": [\"inlineDataFull\"]}, \n \"or([iriRef,[NAMED,iriRef]])\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"NAMED\": [\"[NAMED,iriRef]\"]}, \n \"or([iriRef,a])\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"a\": [\"a\"]}, \n \"or([numericLiteralPositive,numericLiteralNegative])\" : {\n \"INTEGER_POSITIVE\": [\"numericLiteralPositive\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteralPositive\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteralPositive\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteralNegative\"]}, \n \"or([queryAll,updateAll])\" : {\n \"CONSTRUCT\": [\"queryAll\"], \n \"DESCRIBE\": [\"queryAll\"], \n \"ASK\": [\"queryAll\"], \n \"SELECT\": [\"queryAll\"], \n \"INSERT\": [\"updateAll\"], \n \"DELETE\": [\"updateAll\"], \n \"LOAD\": [\"updateAll\"], \n \"CLEAR\": [\"updateAll\"], \n \"DROP\": [\"updateAll\"], \n \"ADD\": [\"updateAll\"], \n \"MOVE\": [\"updateAll\"], \n \"COPY\": [\"updateAll\"], \n \"CREATE\": [\"updateAll\"], \n \"WITH\": [\"updateAll\"], \n \"$\": [\"updateAll\"]}, \n \"or([selectQuery,constructQuery,describeQuery,askQuery])\" : {\n \"SELECT\": [\"selectQuery\"], \n \"CONSTRUCT\": [\"constructQuery\"], \n \"DESCRIBE\": [\"describeQuery\"], \n \"ASK\": [\"askQuery\"]}, \n \"or([subSelect,groupGraphPatternSub])\" : {\n \"SELECT\": [\"subSelect\"], \n \"{\": [\"groupGraphPatternSub\"], \n \"OPTIONAL\": [\"groupGraphPatternSub\"], \n \"MINUS\": [\"groupGraphPatternSub\"], \n \"GRAPH\": [\"groupGraphPatternSub\"], \n \"SERVICE\": [\"groupGraphPatternSub\"], \n \"FILTER\": [\"groupGraphPatternSub\"], \n \"BIND\": [\"groupGraphPatternSub\"], \n \"VALUES\": [\"groupGraphPatternSub\"], \n \"VAR1\": [\"groupGraphPatternSub\"], \n \"VAR2\": [\"groupGraphPatternSub\"], \n \"NIL\": [\"groupGraphPatternSub\"], \n \"(\": [\"groupGraphPatternSub\"], \n \"[\": [\"groupGraphPatternSub\"], \n \"IRI_REF\": [\"groupGraphPatternSub\"], \n \"TRUE\": [\"groupGraphPatternSub\"], \n \"FALSE\": [\"groupGraphPatternSub\"], \n \"BLANK_NODE_LABEL\": [\"groupGraphPatternSub\"], \n \"ANON\": [\"groupGraphPatternSub\"], \n \"PNAME_LN\": [\"groupGraphPatternSub\"], \n \"PNAME_NS\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL1\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL2\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL_LONG1\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL_LONG2\": [\"groupGraphPatternSub\"], \n \"INTEGER\": [\"groupGraphPatternSub\"], \n \"DECIMAL\": [\"groupGraphPatternSub\"], \n \"DOUBLE\": [\"groupGraphPatternSub\"], \n \"INTEGER_POSITIVE\": [\"groupGraphPatternSub\"], \n \"DECIMAL_POSITIVE\": [\"groupGraphPatternSub\"], \n \"DOUBLE_POSITIVE\": [\"groupGraphPatternSub\"], \n \"INTEGER_NEGATIVE\": [\"groupGraphPatternSub\"], \n \"DECIMAL_NEGATIVE\": [\"groupGraphPatternSub\"], \n \"DOUBLE_NEGATIVE\": [\"groupGraphPatternSub\"], \n \"}\": [\"groupGraphPatternSub\"]}, \n \"or([var,[ (,expression,AS,var,)]])\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"(\": [\"[ (,expression,AS,var,)]\"]}, \n \"or([verbPath,verbSimple])\" : {\n \"^\": [\"verbPath\"], \n \"a\": [\"verbPath\"], \n \"!\": [\"verbPath\"], \n \"(\": [\"verbPath\"], \n \"IRI_REF\": [\"verbPath\"], \n \"PNAME_LN\": [\"verbPath\"], \n \"PNAME_NS\": [\"verbPath\"], \n \"VAR1\": [\"verbSimple\"], \n \"VAR2\": [\"verbSimple\"]}, \n \"or([},[integer,}]])\" : {\n \"}\": [\"}\"], \n \"INTEGER\": [\"[integer,}]\"]}, \n \"orderClause\" : {\n \"ORDER\": [\"ORDER\",\"BY\",\"+orderCondition\"]}, \n \"orderCondition\" : {\n \"ASC\": [\"or([ASC,DESC])\",\"brackettedExpression\"], \n \"DESC\": [\"or([ASC,DESC])\",\"brackettedExpression\"], \n \"(\": [\"constraint\"], \n \"STR\": [\"constraint\"], \n \"LANG\": [\"constraint\"], \n \"LANGMATCHES\": [\"constraint\"], \n \"DATATYPE\": [\"constraint\"], \n \"BOUND\": [\"constraint\"], \n \"IRI\": [\"constraint\"], \n \"URI\": [\"constraint\"], \n \"BNODE\": [\"constraint\"], \n \"RAND\": [\"constraint\"], \n \"ABS\": [\"constraint\"], \n \"CEIL\": [\"constraint\"], \n \"FLOOR\": [\"constraint\"], \n \"ROUND\": [\"constraint\"], \n \"CONCAT\": [\"constraint\"], \n \"STRLEN\": [\"constraint\"], \n \"UCASE\": [\"constraint\"], \n \"LCASE\": [\"constraint\"], \n \"ENCODE_FOR_URI\": [\"constraint\"], \n \"CONTAINS\": [\"constraint\"], \n \"STRSTARTS\": [\"constraint\"], \n \"STRENDS\": [\"constraint\"], \n \"STRBEFORE\": [\"constraint\"], \n \"STRAFTER\": [\"constraint\"], \n \"YEAR\": [\"constraint\"], \n \"MONTH\": [\"constraint\"], \n \"DAY\": [\"constraint\"], \n \"HOURS\": [\"constraint\"], \n \"MINUTES\": [\"constraint\"], \n \"SECONDS\": [\"constraint\"], \n \"TIMEZONE\": [\"constraint\"], \n \"TZ\": [\"constraint\"], \n \"NOW\": [\"constraint\"], \n \"UUID\": [\"constraint\"], \n \"STRUUID\": [\"constraint\"], \n \"MD5\": [\"constraint\"], \n \"SHA1\": [\"constraint\"], \n \"SHA256\": [\"constraint\"], \n \"SHA384\": [\"constraint\"], \n \"SHA512\": [\"constraint\"], \n \"COALESCE\": [\"constraint\"], \n \"IF\": [\"constraint\"], \n \"STRLANG\": [\"constraint\"], \n \"STRDT\": [\"constraint\"], \n \"SAMETERM\": [\"constraint\"], \n \"ISIRI\": [\"constraint\"], \n \"ISURI\": [\"constraint\"], \n \"ISBLANK\": [\"constraint\"], \n \"ISLITERAL\": [\"constraint\"], \n \"ISNUMERIC\": [\"constraint\"], \n \"SUBSTR\": [\"constraint\"], \n \"REPLACE\": [\"constraint\"], \n \"REGEX\": [\"constraint\"], \n \"EXISTS\": [\"constraint\"], \n \"NOT\": [\"constraint\"], \n \"IRI_REF\": [\"constraint\"], \n \"PNAME_LN\": [\"constraint\"], \n \"PNAME_NS\": [\"constraint\"], \n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"]}, \n \"path\" : {\n \"^\": [\"pathAlternative\"], \n \"a\": [\"pathAlternative\"], \n \"!\": [\"pathAlternative\"], \n \"(\": [\"pathAlternative\"], \n \"IRI_REF\": [\"pathAlternative\"], \n \"PNAME_LN\": [\"pathAlternative\"], \n \"PNAME_NS\": [\"pathAlternative\"]}, \n \"pathAlternative\" : {\n \"^\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"a\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"!\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"(\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"IRI_REF\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"PNAME_LN\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"PNAME_NS\": [\"pathSequence\",\"*[|,pathSequence]\"]}, \n \"pathElt\" : {\n \"a\": [\"pathPrimary\",\"?pathMod\"], \n \"!\": [\"pathPrimary\",\"?pathMod\"], \n \"(\": [\"pathPrimary\",\"?pathMod\"], \n \"IRI_REF\": [\"pathPrimary\",\"?pathMod\"], \n \"PNAME_LN\": [\"pathPrimary\",\"?pathMod\"], \n \"PNAME_NS\": [\"pathPrimary\",\"?pathMod\"]}, \n \"pathEltOrInverse\" : {\n \"a\": [\"pathElt\"], \n \"!\": [\"pathElt\"], \n \"(\": [\"pathElt\"], \n \"IRI_REF\": [\"pathElt\"], \n \"PNAME_LN\": [\"pathElt\"], \n \"PNAME_NS\": [\"pathElt\"], \n \"^\": [\"^\",\"pathElt\"]}, \n \"pathMod\" : {\n \"*\": [\"*\"], \n \"?\": [\"?\"], \n \"+\": [\"+\"], \n \"{\": [\"{\",\"or([[integer,or([[,,or([},[integer,}]])],}])],[,,integer,}]])\"]}, \n \"pathNegatedPropertySet\" : {\n \"a\": [\"pathOneInPropertySet\"], \n \"^\": [\"pathOneInPropertySet\"], \n \"IRI_REF\": [\"pathOneInPropertySet\"], \n \"PNAME_LN\": [\"pathOneInPropertySet\"], \n \"PNAME_NS\": [\"pathOneInPropertySet\"], \n \"(\": [\"(\",\"?[pathOneInPropertySet,*[|,pathOneInPropertySet]]\",\")\"]}, \n \"pathOneInPropertySet\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"a\": [\"a\"], \n \"^\": [\"^\",\"or([iriRef,a])\"]}, \n \"pathPrimary\" : {\n \"IRI_REF\": [\"storeProperty\",\"iriRef\"], \n \"PNAME_LN\": [\"storeProperty\",\"iriRef\"], \n \"PNAME_NS\": [\"storeProperty\",\"iriRef\"], \n \"a\": [\"storeProperty\",\"a\"], \n \"!\": [\"!\",\"pathNegatedPropertySet\"], \n \"(\": [\"(\",\"path\",\")\"]}, \n \"pathSequence\" : {\n \"^\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"a\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"!\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"(\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"IRI_REF\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"PNAME_LN\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"PNAME_NS\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"]}, \n \"prefixDecl\" : {\n \"PREFIX\": [\"PREFIX\",\"PNAME_NS\",\"IRI_REF\"]}, \n \"prefixedName\" : {\n \"PNAME_LN\": [\"PNAME_LN\"], \n \"PNAME_NS\": [\"PNAME_NS\"]}, \n \"primaryExpression\" : {\n \"(\": [\"brackettedExpression\"], \n \"STR\": [\"builtInCall\"], \n \"LANG\": [\"builtInCall\"], \n \"LANGMATCHES\": [\"builtInCall\"], \n \"DATATYPE\": [\"builtInCall\"], \n \"BOUND\": [\"builtInCall\"], \n \"IRI\": [\"builtInCall\"], \n \"URI\": [\"builtInCall\"], \n \"BNODE\": [\"builtInCall\"], \n \"RAND\": [\"builtInCall\"], \n \"ABS\": [\"builtInCall\"], \n \"CEIL\": [\"builtInCall\"], \n \"FLOOR\": [\"builtInCall\"], \n \"ROUND\": [\"builtInCall\"], \n \"CONCAT\": [\"builtInCall\"], \n \"STRLEN\": [\"builtInCall\"], \n \"UCASE\": [\"builtInCall\"], \n \"LCASE\": [\"builtInCall\"], \n \"ENCODE_FOR_URI\": [\"builtInCall\"], \n \"CONTAINS\": [\"builtInCall\"], \n \"STRSTARTS\": [\"builtInCall\"], \n \"STRENDS\": [\"builtInCall\"], \n \"STRBEFORE\": [\"builtInCall\"], \n \"STRAFTER\": [\"builtInCall\"], \n \"YEAR\": [\"builtInCall\"], \n \"MONTH\": [\"builtInCall\"], \n \"DAY\": [\"builtInCall\"], \n \"HOURS\": [\"builtInCall\"], \n \"MINUTES\": [\"builtInCall\"], \n \"SECONDS\": [\"builtInCall\"], \n \"TIMEZONE\": [\"builtInCall\"], \n \"TZ\": [\"builtInCall\"], \n \"NOW\": [\"builtInCall\"], \n \"UUID\": [\"builtInCall\"], \n \"STRUUID\": [\"builtInCall\"], \n \"MD5\": [\"builtInCall\"], \n \"SHA1\": [\"builtInCall\"], \n \"SHA256\": [\"builtInCall\"], \n \"SHA384\": [\"builtInCall\"], \n \"SHA512\": [\"builtInCall\"], \n \"COALESCE\": [\"builtInCall\"], \n \"IF\": [\"builtInCall\"], \n \"STRLANG\": [\"builtInCall\"], \n \"STRDT\": [\"builtInCall\"], \n \"SAMETERM\": [\"builtInCall\"], \n \"ISIRI\": [\"builtInCall\"], \n \"ISURI\": [\"builtInCall\"], \n \"ISBLANK\": [\"builtInCall\"], \n \"ISLITERAL\": [\"builtInCall\"], \n \"ISNUMERIC\": [\"builtInCall\"], \n \"SUBSTR\": [\"builtInCall\"], \n \"REPLACE\": [\"builtInCall\"], \n \"REGEX\": [\"builtInCall\"], \n \"EXISTS\": [\"builtInCall\"], \n \"NOT\": [\"builtInCall\"], \n \"IRI_REF\": [\"iriRefOrFunction\"], \n \"PNAME_LN\": [\"iriRefOrFunction\"], \n \"PNAME_NS\": [\"iriRefOrFunction\"], \n \"STRING_LITERAL1\": [\"rdfLiteral\"], \n \"STRING_LITERAL2\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG1\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG2\": [\"rdfLiteral\"], \n \"INTEGER\": [\"numericLiteral\"], \n \"DECIMAL\": [\"numericLiteral\"], \n \"DOUBLE\": [\"numericLiteral\"], \n \"INTEGER_POSITIVE\": [\"numericLiteral\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteral\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteral\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteral\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteral\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteral\"], \n \"TRUE\": [\"booleanLiteral\"], \n \"FALSE\": [\"booleanLiteral\"], \n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"COUNT\": [\"aggregate\"], \n \"SUM\": [\"aggregate\"], \n \"MIN\": [\"aggregate\"], \n \"MAX\": [\"aggregate\"], \n \"AVG\": [\"aggregate\"], \n \"SAMPLE\": [\"aggregate\"], \n \"GROUP_CONCAT\": [\"aggregate\"]}, \n \"prologue\" : {\n \"BASE\": [\"*or([baseDecl,prefixDecl])\"], \n \"PREFIX\": [\"*or([baseDecl,prefixDecl])\"], \n \"$\": [\"*or([baseDecl,prefixDecl])\"], \n \"CONSTRUCT\": [\"*or([baseDecl,prefixDecl])\"], \n \"DESCRIBE\": [\"*or([baseDecl,prefixDecl])\"], \n \"ASK\": [\"*or([baseDecl,prefixDecl])\"], \n \"INSERT\": [\"*or([baseDecl,prefixDecl])\"], \n \"DELETE\": [\"*or([baseDecl,prefixDecl])\"], \n \"SELECT\": [\"*or([baseDecl,prefixDecl])\"], \n \"LOAD\": [\"*or([baseDecl,prefixDecl])\"], \n \"CLEAR\": [\"*or([baseDecl,prefixDecl])\"], \n \"DROP\": [\"*or([baseDecl,prefixDecl])\"], \n \"ADD\": [\"*or([baseDecl,prefixDecl])\"], \n \"MOVE\": [\"*or([baseDecl,prefixDecl])\"], \n \"COPY\": [\"*or([baseDecl,prefixDecl])\"], \n \"CREATE\": [\"*or([baseDecl,prefixDecl])\"], \n \"WITH\": [\"*or([baseDecl,prefixDecl])\"]}, \n \"propertyList\" : {\n \"a\": [\"propertyListNotEmpty\"], \n \"VAR1\": [\"propertyListNotEmpty\"], \n \"VAR2\": [\"propertyListNotEmpty\"], \n \"IRI_REF\": [\"propertyListNotEmpty\"], \n \"PNAME_LN\": [\"propertyListNotEmpty\"], \n \"PNAME_NS\": [\"propertyListNotEmpty\"], \n \".\": [], \n \"}\": [], \n \"GRAPH\": []}, \n \"propertyListNotEmpty\" : {\n \"a\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"VAR1\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"VAR2\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"IRI_REF\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"PNAME_LN\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"PNAME_NS\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"]}, \n \"propertyListPath\" : {\n \"a\": [\"propertyListNotEmpty\"], \n \"VAR1\": [\"propertyListNotEmpty\"], \n \"VAR2\": [\"propertyListNotEmpty\"], \n \"IRI_REF\": [\"propertyListNotEmpty\"], \n \"PNAME_LN\": [\"propertyListNotEmpty\"], \n \"PNAME_NS\": [\"propertyListNotEmpty\"], \n \".\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"propertyListPathNotEmpty\" : {\n \"VAR1\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"VAR2\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"^\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"a\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"!\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"(\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"IRI_REF\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"PNAME_LN\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"PNAME_NS\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"]}, \n \"quadData\" : {\n \"{\": [\"{\",\"disallowVars\",\"quads\",\"allowVars\",\"}\"]}, \n \"quadDataNoBnodes\" : {\n \"{\": [\"{\",\"disallowBnodes\",\"disallowVars\",\"quads\",\"allowVars\",\"allowBnodes\",\"}\"]}, \n \"quadPattern\" : {\n \"{\": [\"{\",\"quads\",\"}\"]}, \n \"quadPatternNoBnodes\" : {\n \"{\": [\"{\",\"disallowBnodes\",\"quads\",\"allowBnodes\",\"}\"]}, \n \"quads\" : {\n \"GRAPH\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"VAR1\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"VAR2\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"NIL\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"(\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"[\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"IRI_REF\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"TRUE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"FALSE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"BLANK_NODE_LABEL\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"ANON\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"PNAME_LN\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"PNAME_NS\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL1\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL2\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG1\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG2\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"INTEGER\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DECIMAL\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DOUBLE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"INTEGER_POSITIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DECIMAL_POSITIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DOUBLE_POSITIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"INTEGER_NEGATIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DECIMAL_NEGATIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DOUBLE_NEGATIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"}\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"]}, \n \"quadsNotTriples\" : {\n \"GRAPH\": [\"GRAPH\",\"varOrIRIref\",\"{\",\"?triplesTemplate\",\"}\"]}, \n \"queryAll\" : {\n \"CONSTRUCT\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"], \n \"DESCRIBE\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"], \n \"ASK\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"], \n \"SELECT\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"]}, \n \"rdfLiteral\" : {\n \"STRING_LITERAL1\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"], \n \"STRING_LITERAL2\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"], \n \"STRING_LITERAL_LONG1\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"], \n \"STRING_LITERAL_LONG2\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"]}, \n \"regexExpression\" : {\n \"REGEX\": [\"REGEX\",\"(\",\"expression\",\",\",\"expression\",\"?[,,expression]\",\")\"]}, \n \"relationalExpression\" : {\n \"!\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"+\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"-\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"VAR1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"VAR2\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"(\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"LANG\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"LANGMATCHES\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DATATYPE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"BOUND\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IRI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"URI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"BNODE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"RAND\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ABS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"CEIL\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"FLOOR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ROUND\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"CONCAT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRLEN\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"UCASE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"LCASE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ENCODE_FOR_URI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"CONTAINS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRSTARTS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRENDS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRBEFORE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRAFTER\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"YEAR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MONTH\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DAY\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"HOURS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MINUTES\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SECONDS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"TIMEZONE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"TZ\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"NOW\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"UUID\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRUUID\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MD5\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA256\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA384\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA512\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"COALESCE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IF\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRLANG\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRDT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SAMETERM\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISIRI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISURI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISBLANK\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISLITERAL\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISNUMERIC\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"TRUE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"FALSE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"COUNT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SUM\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MIN\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MAX\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"AVG\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SAMPLE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"GROUP_CONCAT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SUBSTR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"REPLACE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"REGEX\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"EXISTS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"NOT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IRI_REF\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL2\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL_LONG1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL_LONG2\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"INTEGER\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DECIMAL\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DOUBLE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"INTEGER_POSITIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DECIMAL_POSITIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DOUBLE_POSITIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"INTEGER_NEGATIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DECIMAL_NEGATIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DOUBLE_NEGATIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"PNAME_LN\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"PNAME_NS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"]}, \n \"selectClause\" : {\n \"SELECT\": [\"SELECT\",\"?or([DISTINCT,REDUCED])\",\"or([+or([var,[ (,expression,AS,var,)]]),*])\"]}, \n \"selectQuery\" : {\n \"SELECT\": [\"selectClause\",\"*datasetClause\",\"whereClause\",\"solutionModifier\"]}, \n \"serviceGraphPattern\" : {\n \"SERVICE\": [\"SERVICE\",\"?SILENT\",\"varOrIRIref\",\"groupGraphPattern\"]}, \n \"solutionModifier\" : {\n \"LIMIT\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"OFFSET\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"ORDER\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"HAVING\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"GROUP\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"VALUES\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"$\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"}\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"]}, \n \"sourceSelector\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"]}, \n \"sparql11\" : {\n \"$\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"CONSTRUCT\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"DESCRIBE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"ASK\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"INSERT\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"DELETE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"SELECT\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"LOAD\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"CLEAR\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"DROP\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"ADD\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"MOVE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"COPY\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"CREATE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"WITH\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"BASE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"PREFIX\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"]}, \n \"storeProperty\" : {\n \"VAR1\": [], \n \"VAR2\": [], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"a\": []}, \n \"strReplaceExpression\" : {\n \"REPLACE\": [\"REPLACE\",\"(\",\"expression\",\",\",\"expression\",\",\",\"expression\",\"?[,,expression]\",\")\"]}, \n \"string\" : {\n \"STRING_LITERAL1\": [\"STRING_LITERAL1\"], \n \"STRING_LITERAL2\": [\"STRING_LITERAL2\"], \n \"STRING_LITERAL_LONG1\": [\"STRING_LITERAL_LONG1\"], \n \"STRING_LITERAL_LONG2\": [\"STRING_LITERAL_LONG2\"]}, \n \"subSelect\" : {\n \"SELECT\": [\"selectClause\",\"whereClause\",\"solutionModifier\",\"valuesClause\"]}, \n \"substringExpression\" : {\n \"SUBSTR\": [\"SUBSTR\",\"(\",\"expression\",\",\",\"expression\",\"?[,,expression]\",\")\"]}, \n \"triplesBlock\" : {\n \"VAR1\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"VAR2\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"NIL\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"(\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"[\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"IRI_REF\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"TRUE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"FALSE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"BLANK_NODE_LABEL\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"ANON\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"PNAME_LN\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"PNAME_NS\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL1\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL2\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG1\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG2\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"INTEGER\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DECIMAL\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DOUBLE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"INTEGER_POSITIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DECIMAL_POSITIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DOUBLE_POSITIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"INTEGER_NEGATIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DECIMAL_NEGATIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DOUBLE_NEGATIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"]}, \n \"triplesNode\" : {\n \"(\": [\"collection\"], \n \"[\": [\"blankNodePropertyList\"]}, \n \"triplesNodePath\" : {\n \"(\": [\"collectionPath\"], \n \"[\": [\"blankNodePropertyListPath\"]}, \n \"triplesSameSubject\" : {\n \"VAR1\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"VAR2\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"NIL\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"IRI_REF\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"TRUE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"FALSE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"ANON\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"PNAME_LN\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"PNAME_NS\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL1\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL2\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"INTEGER\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DECIMAL\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DOUBLE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"(\": [\"triplesNode\",\"propertyList\"], \n \"[\": [\"triplesNode\",\"propertyList\"]}, \n \"triplesSameSubjectPath\" : {\n \"VAR1\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"VAR2\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"NIL\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"IRI_REF\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"TRUE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"FALSE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"ANON\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"PNAME_LN\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"PNAME_NS\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL1\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL2\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"INTEGER\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DECIMAL\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DOUBLE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"(\": [\"triplesNodePath\",\"propertyListPath\"], \n \"[\": [\"triplesNodePath\",\"propertyListPath\"]}, \n \"triplesTemplate\" : {\n \"VAR1\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"VAR2\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"NIL\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"(\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"[\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"IRI_REF\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"TRUE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"FALSE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"BLANK_NODE_LABEL\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"ANON\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"PNAME_LN\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"PNAME_NS\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL1\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL2\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG1\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG2\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"INTEGER\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DECIMAL\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DOUBLE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"INTEGER_POSITIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DECIMAL_POSITIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DOUBLE_POSITIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"INTEGER_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DECIMAL_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DOUBLE_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"]}, \n \"unaryExpression\" : {\n \"!\": [\"!\",\"primaryExpression\"], \n \"+\": [\"+\",\"primaryExpression\"], \n \"-\": [\"-\",\"primaryExpression\"], \n \"VAR1\": [\"primaryExpression\"], \n \"VAR2\": [\"primaryExpression\"], \n \"(\": [\"primaryExpression\"], \n \"STR\": [\"primaryExpression\"], \n \"LANG\": [\"primaryExpression\"], \n \"LANGMATCHES\": [\"primaryExpression\"], \n \"DATATYPE\": [\"primaryExpression\"], \n \"BOUND\": [\"primaryExpression\"], \n \"IRI\": [\"primaryExpression\"], \n \"URI\": [\"primaryExpression\"], \n \"BNODE\": [\"primaryExpression\"], \n \"RAND\": [\"primaryExpression\"], \n \"ABS\": [\"primaryExpression\"], \n \"CEIL\": [\"primaryExpression\"], \n \"FLOOR\": [\"primaryExpression\"], \n \"ROUND\": [\"primaryExpression\"], \n \"CONCAT\": [\"primaryExpression\"], \n \"STRLEN\": [\"primaryExpression\"], \n \"UCASE\": [\"primaryExpression\"], \n \"LCASE\": [\"primaryExpression\"], \n \"ENCODE_FOR_URI\": [\"primaryExpression\"], \n \"CONTAINS\": [\"primaryExpression\"], \n \"STRSTARTS\": [\"primaryExpression\"], \n \"STRENDS\": [\"primaryExpression\"], \n \"STRBEFORE\": [\"primaryExpression\"], \n \"STRAFTER\": [\"primaryExpression\"], \n \"YEAR\": [\"primaryExpression\"], \n \"MONTH\": [\"primaryExpression\"], \n \"DAY\": [\"primaryExpression\"], \n \"HOURS\": [\"primaryExpression\"], \n \"MINUTES\": [\"primaryExpression\"], \n \"SECONDS\": [\"primaryExpression\"], \n \"TIMEZONE\": [\"primaryExpression\"], \n \"TZ\": [\"primaryExpression\"], \n \"NOW\": [\"primaryExpression\"], \n \"UUID\": [\"primaryExpression\"], \n \"STRUUID\": [\"primaryExpression\"], \n \"MD5\": [\"primaryExpression\"], \n \"SHA1\": [\"primaryExpression\"], \n \"SHA256\": [\"primaryExpression\"], \n \"SHA384\": [\"primaryExpression\"], \n \"SHA512\": [\"primaryExpression\"], \n \"COALESCE\": [\"primaryExpression\"], \n \"IF\": [\"primaryExpression\"], \n \"STRLANG\": [\"primaryExpression\"], \n \"STRDT\": [\"primaryExpression\"], \n \"SAMETERM\": [\"primaryExpression\"], \n \"ISIRI\": [\"primaryExpression\"], \n \"ISURI\": [\"primaryExpression\"], \n \"ISBLANK\": [\"primaryExpression\"], \n \"ISLITERAL\": [\"primaryExpression\"], \n \"ISNUMERIC\": [\"primaryExpression\"], \n \"TRUE\": [\"primaryExpression\"], \n \"FALSE\": [\"primaryExpression\"], \n \"COUNT\": [\"primaryExpression\"], \n \"SUM\": [\"primaryExpression\"], \n \"MIN\": [\"primaryExpression\"], \n \"MAX\": [\"primaryExpression\"], \n \"AVG\": [\"primaryExpression\"], \n \"SAMPLE\": [\"primaryExpression\"], \n \"GROUP_CONCAT\": [\"primaryExpression\"], \n \"SUBSTR\": [\"primaryExpression\"], \n \"REPLACE\": [\"primaryExpression\"], \n \"REGEX\": [\"primaryExpression\"], \n \"EXISTS\": [\"primaryExpression\"], \n \"NOT\": [\"primaryExpression\"], \n \"IRI_REF\": [\"primaryExpression\"], \n \"STRING_LITERAL1\": [\"primaryExpression\"], \n \"STRING_LITERAL2\": [\"primaryExpression\"], \n \"STRING_LITERAL_LONG1\": [\"primaryExpression\"], \n \"STRING_LITERAL_LONG2\": [\"primaryExpression\"], \n \"INTEGER\": [\"primaryExpression\"], \n \"DECIMAL\": [\"primaryExpression\"], \n \"DOUBLE\": [\"primaryExpression\"], \n \"INTEGER_POSITIVE\": [\"primaryExpression\"], \n \"DECIMAL_POSITIVE\": [\"primaryExpression\"], \n \"DOUBLE_POSITIVE\": [\"primaryExpression\"], \n \"INTEGER_NEGATIVE\": [\"primaryExpression\"], \n \"DECIMAL_NEGATIVE\": [\"primaryExpression\"], \n \"DOUBLE_NEGATIVE\": [\"primaryExpression\"], \n \"PNAME_LN\": [\"primaryExpression\"], \n \"PNAME_NS\": [\"primaryExpression\"]}, \n \"update\" : {\n \"INSERT\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"DELETE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"LOAD\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"CLEAR\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"DROP\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"ADD\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"MOVE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"COPY\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"CREATE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"WITH\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"BASE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"PREFIX\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"$\": [\"prologue\",\"?[update1,?[;,update]]\"]}, \n \"update1\" : {\n \"LOAD\": [\"load\"], \n \"CLEAR\": [\"clear\"], \n \"DROP\": [\"drop\"], \n \"ADD\": [\"add\"], \n \"MOVE\": [\"move\"], \n \"COPY\": [\"copy\"], \n \"CREATE\": [\"create\"], \n \"INSERT\": [\"INSERT\",\"insert1\"], \n \"DELETE\": [\"DELETE\",\"delete1\"], \n \"WITH\": [\"modify\"]}, \n \"updateAll\" : {\n \"INSERT\": [\"?[update1,?[;,update]]\"], \n \"DELETE\": [\"?[update1,?[;,update]]\"], \n \"LOAD\": [\"?[update1,?[;,update]]\"], \n \"CLEAR\": [\"?[update1,?[;,update]]\"], \n \"DROP\": [\"?[update1,?[;,update]]\"], \n \"ADD\": [\"?[update1,?[;,update]]\"], \n \"MOVE\": [\"?[update1,?[;,update]]\"], \n \"COPY\": [\"?[update1,?[;,update]]\"], \n \"CREATE\": [\"?[update1,?[;,update]]\"], \n \"WITH\": [\"?[update1,?[;,update]]\"], \n \"$\": [\"?[update1,?[;,update]]\"]}, \n \"usingClause\" : {\n \"USING\": [\"USING\",\"or([iriRef,[NAMED,iriRef]])\"]}, \n \"valueLogical\" : {\n \"!\": [\"relationalExpression\"], \n \"+\": [\"relationalExpression\"], \n \"-\": [\"relationalExpression\"], \n \"VAR1\": [\"relationalExpression\"], \n \"VAR2\": [\"relationalExpression\"], \n \"(\": [\"relationalExpression\"], \n \"STR\": [\"relationalExpression\"], \n \"LANG\": [\"relationalExpression\"], \n \"LANGMATCHES\": [\"relationalExpression\"], \n \"DATATYPE\": [\"relationalExpression\"], \n \"BOUND\": [\"relationalExpression\"], \n \"IRI\": [\"relationalExpression\"], \n \"URI\": [\"relationalExpression\"], \n \"BNODE\": [\"relationalExpression\"], \n \"RAND\": [\"relationalExpression\"], \n \"ABS\": [\"relationalExpression\"], \n \"CEIL\": [\"relationalExpression\"], \n \"FLOOR\": [\"relationalExpression\"], \n \"ROUND\": [\"relationalExpression\"], \n \"CONCAT\": [\"relationalExpression\"], \n \"STRLEN\": [\"relationalExpression\"], \n \"UCASE\": [\"relationalExpression\"], \n \"LCASE\": [\"relationalExpression\"], \n \"ENCODE_FOR_URI\": [\"relationalExpression\"], \n \"CONTAINS\": [\"relationalExpression\"], \n \"STRSTARTS\": [\"relationalExpression\"], \n \"STRENDS\": [\"relationalExpression\"], \n \"STRBEFORE\": [\"relationalExpression\"], \n \"STRAFTER\": [\"relationalExpression\"], \n \"YEAR\": [\"relationalExpression\"], \n \"MONTH\": [\"relationalExpression\"], \n \"DAY\": [\"relationalExpression\"], \n \"HOURS\": [\"relationalExpression\"], \n \"MINUTES\": [\"relationalExpression\"], \n \"SECONDS\": [\"relationalExpression\"], \n \"TIMEZONE\": [\"relationalExpression\"], \n \"TZ\": [\"relationalExpression\"], \n \"NOW\": [\"relationalExpression\"], \n \"UUID\": [\"relationalExpression\"], \n \"STRUUID\": [\"relationalExpression\"], \n \"MD5\": [\"relationalExpression\"], \n \"SHA1\": [\"relationalExpression\"], \n \"SHA256\": [\"relationalExpression\"], \n \"SHA384\": [\"relationalExpression\"], \n \"SHA512\": [\"relationalExpression\"], \n \"COALESCE\": [\"relationalExpression\"], \n \"IF\": [\"relationalExpression\"], \n \"STRLANG\": [\"relationalExpression\"], \n \"STRDT\": [\"relationalExpression\"], \n \"SAMETERM\": [\"relationalExpression\"], \n \"ISIRI\": [\"relationalExpression\"], \n \"ISURI\": [\"relationalExpression\"], \n \"ISBLANK\": [\"relationalExpression\"], \n \"ISLITERAL\": [\"relationalExpression\"], \n \"ISNUMERIC\": [\"relationalExpression\"], \n \"TRUE\": [\"relationalExpression\"], \n \"FALSE\": [\"relationalExpression\"], \n \"COUNT\": [\"relationalExpression\"], \n \"SUM\": [\"relationalExpression\"], \n \"MIN\": [\"relationalExpression\"], \n \"MAX\": [\"relationalExpression\"], \n \"AVG\": [\"relationalExpression\"], \n \"SAMPLE\": [\"relationalExpression\"], \n \"GROUP_CONCAT\": [\"relationalExpression\"], \n \"SUBSTR\": [\"relationalExpression\"], \n \"REPLACE\": [\"relationalExpression\"], \n \"REGEX\": [\"relationalExpression\"], \n \"EXISTS\": [\"relationalExpression\"], \n \"NOT\": [\"relationalExpression\"], \n \"IRI_REF\": [\"relationalExpression\"], \n \"STRING_LITERAL1\": [\"relationalExpression\"], \n \"STRING_LITERAL2\": [\"relationalExpression\"], \n \"STRING_LITERAL_LONG1\": [\"relationalExpression\"], \n \"STRING_LITERAL_LONG2\": [\"relationalExpression\"], \n \"INTEGER\": [\"relationalExpression\"], \n \"DECIMAL\": [\"relationalExpression\"], \n \"DOUBLE\": [\"relationalExpression\"], \n \"INTEGER_POSITIVE\": [\"relationalExpression\"], \n \"DECIMAL_POSITIVE\": [\"relationalExpression\"], \n \"DOUBLE_POSITIVE\": [\"relationalExpression\"], \n \"INTEGER_NEGATIVE\": [\"relationalExpression\"], \n \"DECIMAL_NEGATIVE\": [\"relationalExpression\"], \n \"DOUBLE_NEGATIVE\": [\"relationalExpression\"], \n \"PNAME_LN\": [\"relationalExpression\"], \n \"PNAME_NS\": [\"relationalExpression\"]}, \n \"valuesClause\" : {\n \"VALUES\": [\"VALUES\",\"dataBlock\"], \n \"$\": [], \n \"}\": []}, \n \"var\" : {\n \"VAR1\": [\"VAR1\"], \n \"VAR2\": [\"VAR2\"]}, \n \"varOrIRIref\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"]}, \n \"varOrTerm\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"NIL\": [\"graphTerm\"], \n \"IRI_REF\": [\"graphTerm\"], \n \"TRUE\": [\"graphTerm\"], \n \"FALSE\": [\"graphTerm\"], \n \"BLANK_NODE_LABEL\": [\"graphTerm\"], \n \"ANON\": [\"graphTerm\"], \n \"PNAME_LN\": [\"graphTerm\"], \n \"PNAME_NS\": [\"graphTerm\"], \n \"STRING_LITERAL1\": [\"graphTerm\"], \n \"STRING_LITERAL2\": [\"graphTerm\"], \n \"STRING_LITERAL_LONG1\": [\"graphTerm\"], \n \"STRING_LITERAL_LONG2\": [\"graphTerm\"], \n \"INTEGER\": [\"graphTerm\"], \n \"DECIMAL\": [\"graphTerm\"], \n \"DOUBLE\": [\"graphTerm\"], \n \"INTEGER_POSITIVE\": [\"graphTerm\"], \n \"DECIMAL_POSITIVE\": [\"graphTerm\"], \n \"DOUBLE_POSITIVE\": [\"graphTerm\"], \n \"INTEGER_NEGATIVE\": [\"graphTerm\"], \n \"DECIMAL_NEGATIVE\": [\"graphTerm\"], \n \"DOUBLE_NEGATIVE\": [\"graphTerm\"]}, \n \"verb\" : {\n \"VAR1\": [\"storeProperty\",\"varOrIRIref\"], \n \"VAR2\": [\"storeProperty\",\"varOrIRIref\"], \n \"IRI_REF\": [\"storeProperty\",\"varOrIRIref\"], \n \"PNAME_LN\": [\"storeProperty\",\"varOrIRIref\"], \n \"PNAME_NS\": [\"storeProperty\",\"varOrIRIref\"], \n \"a\": [\"storeProperty\",\"a\"]}, \n \"verbPath\" : {\n \"^\": [\"path\"], \n \"a\": [\"path\"], \n \"!\": [\"path\"], \n \"(\": [\"path\"], \n \"IRI_REF\": [\"path\"], \n \"PNAME_LN\": [\"path\"], \n \"PNAME_NS\": [\"path\"]}, \n \"verbSimple\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"]}, \n \"whereClause\" : {\n \"{\": [\"?WHERE\",\"groupGraphPattern\"], \n \"WHERE\": [\"?WHERE\",\"groupGraphPattern\"]}\n},\n\nkeywords:/^(GROUP_CONCAT|DATATYPE|BASE|PREFIX|SELECT|CONSTRUCT|DESCRIBE|ASK|FROM|NAMED|ORDER|BY|LIMIT|ASC|DESC|OFFSET|DISTINCT|REDUCED|WHERE|GRAPH|OPTIONAL|UNION|FILTER|GROUP|HAVING|AS|VALUES|LOAD|CLEAR|DROP|CREATE|MOVE|COPY|SILENT|INSERT|DELETE|DATA|WITH|TO|USING|NAMED|MINUS|BIND|LANGMATCHES|LANG|BOUND|SAMETERM|ISIRI|ISURI|ISBLANK|ISLITERAL|REGEX|TRUE|FALSE|UNDEF|ADD|DEFAULT|ALL|SERVICE|INTO|IN|NOT|IRI|URI|BNODE|RAND|ABS|CEIL|FLOOR|ROUND|CONCAT|STRLEN|UCASE|LCASE|ENCODE_FOR_URI|CONTAINS|STRSTARTS|STRENDS|STRBEFORE|STRAFTER|YEAR|MONTH|DAY|HOURS|MINUTES|SECONDS|TIMEZONE|TZ|NOW|UUID|STRUUID|MD5|SHA1|SHA256|SHA384|SHA512|COALESCE|IF|STRLANG|STRDT|ISNUMERIC|SUBSTR|REPLACE|EXISTS|COUNT|SUM|MIN|MAX|AVG|SAMPLE|SEPARATOR|STR)/i ,\n\npunct:/^(\\*|a|\\.|\\{|\\}|,|\\(|\\)|;|\\[|\\]|\\|\\||&&|=|!=|!|<=|>=|<|>|\\+|-|\\/|\\^\\^|\\?|\\||\\^)/ ,\n\nstartSymbol:\"sparql11\",\nacceptEmpty:true,\n}\n},{}],4:[function(require,module,exports){\n\"use strict\";\nvar CodeMirror = require('codemirror');\nCodeMirror.defineMode(\"sparql11\", function(config, parserConfig) {\n\n\tvar indentUnit = config.indentUnit;\n\n\tvar grammar = require('./_tokenizer-table.js');\n\tvar ll1_table = grammar.table;\n\n\tvar IRI_REF = '<[^<>\\\"\\'\\|\\{\\}\\^\\\\\\x00-\\x20]*>';\n\t/*\n\t * PN_CHARS_BASE =\n\t * '[A-Z]|[a-z]|[\\\\u00C0-\\\\u00D6]|[\\\\u00D8-\\\\u00F6]|[\\\\u00F8-\\\\u02FF]|[\\\\u0370-\\\\u037D]|[\\\\u037F-\\\\u1FFF]|[\\\\u200C-\\\\u200D]|[\\\\u2070-\\\\u218F]|[\\\\u2C00-\\\\u2FEF]|[\\\\u3001-\\\\uD7FF]|[\\\\uF900-\\\\uFDCF]|[\\\\uFDF0-\\\\uFFFD]|[\\\\u10000-\\\\uEFFFF]';\n\t */\n\n\tvar PN_CHARS_BASE =\n\t\t'[A-Za-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD]';\n\tvar PN_CHARS_U = PN_CHARS_BASE+'|_';\n\n\tvar PN_CHARS= '('+PN_CHARS_U+'|-|[0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040])';\n\tvar VARNAME = '('+PN_CHARS_U+'|[0-9])'+\n\t\t'('+PN_CHARS_U+'|[0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040])*';\n\tvar VAR1 = '\\\\?'+VARNAME;\n\tvar VAR2 = '\\\\$'+VARNAME;\n\n\tvar PN_PREFIX= '('+PN_CHARS_BASE+')((('+PN_CHARS+')|\\\\.)*('+PN_CHARS+'))?';\n\n\tvar HEX= '[0-9A-Fa-f]';\n\tvar PERCENT='(%'+HEX+HEX+')';\n\tvar PN_LOCAL_ESC='(\\\\\\\\[_~\\\\.\\\\-!\\\\$&\\'\\\\(\\\\)\\\\*\\\\+,;=/\\\\?#@%])';\n\tvar PLX= '('+PERCENT+'|'+PN_LOCAL_ESC+')';\n\tvar PN_LOCAL= '('+PN_CHARS_U+'|:|[0-9]|'+PLX+')(('+PN_CHARS+'|\\\\.|:|'+PLX+')*('+PN_CHARS+'|:|'+PLX+'))?';\n\tvar BLANK_NODE_LABEL = '_:('+PN_CHARS_U+'|[0-9])(('+PN_CHARS+'|\\\\.)*'+PN_CHARS+')?';\n\tvar PNAME_NS = '('+PN_PREFIX+')?:';\n\tvar PNAME_LN = PNAME_NS+PN_LOCAL;\n\tvar LANGTAG = '@[a-zA-Z]+(-[a-zA-Z0-9]+)*';\n\n\tvar EXPONENT = '[eE][\\\\+-]?[0-9]+';\n\tvar INTEGER = '[0-9]+';\n\tvar DECIMAL = '(([0-9]+\\\\.[0-9]*)|(\\\\.[0-9]+))';\n\tvar DOUBLE =\n\t\t'(([0-9]+\\\\.[0-9]*'+EXPONENT+')|'+\n\t\t'(\\\\.[0-9]+'+EXPONENT+')|'+\n\t\t'([0-9]+'+EXPONENT+'))';\n\n\tvar INTEGER_POSITIVE = '\\\\+' + INTEGER;\n\tvar DECIMAL_POSITIVE = '\\\\+' + DECIMAL;\n\tvar DOUBLE_POSITIVE = '\\\\+' + DOUBLE;\n\tvar INTEGER_NEGATIVE = '-' + INTEGER;\n\tvar DECIMAL_NEGATIVE = '-' + DECIMAL;\n\tvar DOUBLE_NEGATIVE = '-' + DOUBLE;\n\n\tvar ECHAR = '\\\\\\\\[tbnrf\\\\\\\\\"\\']';\n\t\n\t\n\t //IMPORTANT: this unicode rule is not in the official grammar.\n //Reason: https://github.com/YASGUI/YASQE/issues/49\n //unicode escape sequences (which the sparql spec considers part of the pre-processing of sparql queries)\n //are marked as invalid. We have little choice (other than adding a layer of complixity) than to modify the grammar accordingly\n //however, for now only allow these escape sequences in literals (where actually, this should be allows in e.g. prefixes as well)\n\tvar hex4 = HEX + '{4}'\n\tvar unicode = '(\\\\\\\\u' + hex4 +'|\\\\\\\\U00(10|0' + HEX + ')'+ hex4 + ')';\n\tvar LINE_BREAK = \"\\n\";\n\tvar STRING_LITERAL1 = \"'(([^\\\\x27\\\\x5C\\\\x0A\\\\x0D])|\"+ECHAR+\"|\" + unicode + \")*'\";\n\tvar STRING_LITERAL2 = '\"(([^\\\\x22\\\\x5C\\\\x0A\\\\x0D])|'+ECHAR+'|' + unicode + ')*\"';\n\t\n\tvar STRING_LITERAL_LONG = {\n\t\tSINGLE: {\n\t\t\tCAT: \"STRING_LITERAL_LONG1\",\n\t\t\tQUOTES: \"'''\",\n\t\t\tCONTENTS: \"(('|'')?([^'\\\\\\\\]|\"+ECHAR+\"|\"+unicode+\"))*\",\n\t\t\t\n\t\t},\n\t\tDOUBLE: {\n\t\t\tCAT: \"STRING_LITERAL_LONG2\",\n\t\t\tQUOTES: '\"\"\"',\n\t\t\tCONTENTS: '((\"|\"\")?([^\"\\\\\\\\]|'+ECHAR+'|'+unicode+'))*',\n\t\t}\n\t};\n\tfor (var key in STRING_LITERAL_LONG) {\n\t\tSTRING_LITERAL_LONG[key].COMPLETE = STRING_LITERAL_LONG[key].QUOTES + STRING_LITERAL_LONG[key].CONTENTS + STRING_LITERAL_LONG[key].QUOTES;\n\t}\n//\tvar STRING_LITERAL_LONG_QUOTES = {\n//\t\t\"STRING_LITERAL_LONG_QUOTES1\": \"'''\",\n//\t\t\"STRING_LITERAL_LONG_QUOTES2\": '\"\"\"',\n//\t}\n//\tvar STRING_LITERAL_LONG_CONTENTS = {\n//\t\t\"STRING_LITERAL_LONG_QUOTES1\": \"(('|'')?([^'\\\\\\\\]|\"+ECHAR+\"|\"+unicode+\"))*\",\n//\t\t\"STRING_LITERAL_LONG_QUOTES2\": '((\"|\"\")?([^\"\\\\\\\\]|'+ECHAR+'|'+unicode+'))*'\n//\t};\n//\tvar STRING_LITERAL_LONG1 = STRING_LITERAL_LONG['SINGLE'].QUOTES + STRING_LITERAL_LONG['SINGLE'].CONTENTS + STRING_LITERAL_LONG['SINGLE'].QUOTES;\n//\tvar STRING_LITERAL_LONG2 = STRING_LITERAL_LONG['DOUBLE'].QUOTES + STRING_LITERAL_LONG['DOUBLE'].CONTENTS + STRING_LITERAL_LONG['DOUBLE'].QUOTES;\n\t\n//\tvar stringLiteralLongContentTerminals = {};\n//\tfor (var key in STRING_LITERAL_LONG) {\n//\t\tstringLiteralLongContentTerminals[key] = {\n//\t\t\tname: key,\n//\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG_CONTENTS[key]),\n//\t\t\tstyle:\"string\"\n//\t\t};\n//\t}\n\t//some regular expressions not used in regular terminals, because this is used accross lines\n\tvar stringLiteralLongRegex = {};\n\tfor (var key in STRING_LITERAL_LONG) {\n\t\tstringLiteralLongRegex[key] = {\n\t\t\tcomplete: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].COMPLETE),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\tcontents: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].CONTENTS),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\tclosing: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].CONTENTS + STRING_LITERAL_LONG[key].QUOTES),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\tquotes: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_QUOTES_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].QUOTES),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\n\t\t}\n\t}\n\t\n\tvar WS = '[\\\\x20\\\\x09\\\\x0D\\\\x0A]';\n\t// Careful! Code mirror feeds one line at a time with no \\n\n\t// ... but otherwise comment is terminated by \\n\n\tvar COMMENT = '#([^\\\\n\\\\r]*[\\\\n\\\\r]|[^\\\\n\\\\r]*$)';\n\tvar WS_OR_COMMENT_STAR = '('+WS+'|('+COMMENT+'))*';\n\tvar NIL = '\\\\('+WS_OR_COMMENT_STAR+'\\\\)';\n\tvar ANON = '\\\\['+WS_OR_COMMENT_STAR+'\\\\]';\n\tvar terminals= [\n\t\t{ name: \"WS\",\n\t\t\tregex:new RegExp(\"^\"+WS+\"+\"),\n\t\t\tstyle:\"ws\" },\n\n\t\t{ name: \"COMMENT\",\n\t\t\tregex:new RegExp(\"^\"+COMMENT),\n\t\t\tstyle:\"comment\" },\n\n\t\t{ name: \"IRI_REF\",\n\t\t\tregex:new RegExp(\"^\"+IRI_REF),\n\t\t\tstyle:\"variable-3\" },\n\n\t\t{ name: \"VAR1\",\n\t\t\tregex:new RegExp(\"^\"+VAR1),\n\t\t\tstyle:\"atom\"},\n\n\t\t{ name: \"VAR2\",\n\t\t\tregex:new RegExp(\"^\"+VAR2),\n\t\t\tstyle:\"atom\"},\n\n\t\t{ name: \"LANGTAG\",\n\t\t\tregex:new RegExp(\"^\"+LANGTAG),\n\t\t\tstyle:\"meta\"},\n\n\t\t{ name: \"DOUBLE\",\n\t\t\tregex:new RegExp(\"^\"+DOUBLE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DECIMAL\",\n\t\t\tregex:new RegExp(\"^\"+DECIMAL),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"INTEGER\",\n\t\t\tregex:new RegExp(\"^\"+INTEGER),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DOUBLE_POSITIVE\",\n\t\t\tregex:new RegExp(\"^\"+DOUBLE_POSITIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DECIMAL_POSITIVE\",\n\t\t\tregex:new RegExp(\"^\"+DECIMAL_POSITIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"INTEGER_POSITIVE\",\n\t\t\tregex:new RegExp(\"^\"+INTEGER_POSITIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DOUBLE_NEGATIVE\",\n\t\t\tregex:new RegExp(\"^\"+DOUBLE_NEGATIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DECIMAL_NEGATIVE\",\n\t\t\tregex:new RegExp(\"^\"+DECIMAL_NEGATIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"INTEGER_NEGATIVE\",\n\t\t\tregex:new RegExp(\"^\"+INTEGER_NEGATIVE),\n\t\t\tstyle:\"number\" },\n//\t\tstringLiteralLongRegex.SINGLE.complete,\n//\t\tstringLiteralLongRegex.DOUBLE.complete,\n//\t\tstringLiteralLongRegex.SINGLE.quotes,\n//\t\tstringLiteralLongRegex.DOUBLE.quotes,\n\t\t\n\t\t{ name: \"STRING_LITERAL1\",\n\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL1),\n\t\t\tstyle:\"string\" },\n\n\t\t{ name: \"STRING_LITERAL2\",\n\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL2),\n\t\t\tstyle:\"string\" },\n\n\t\t// Enclosed comments won't be highlighted\n\t\t{ name: \"NIL\",\n\t\t\tregex:new RegExp(\"^\"+NIL),\n\t\t\tstyle:\"punc\" },\n\n\t\t// Enclosed comments won't be highlighted\n\t\t{ name: \"ANON\",\n\t\t\tregex:new RegExp(\"^\"+ANON),\n\t\t\tstyle:\"punc\" },\n\n\t\t{ name: \"PNAME_LN\",\n\t\t\tregex:new RegExp(\"^\"+PNAME_LN),\n\t\t\tstyle:\"string-2\" },\n\n\t\t{ name: \"PNAME_NS\",\n\t\t\tregex:new RegExp(\"^\"+PNAME_NS),\n\t\t\tstyle:\"string-2\" },\n\n\t\t{ name: \"BLANK_NODE_LABEL\",\n\t\t\tregex:new RegExp(\"^\"+BLANK_NODE_LABEL),\n\t\t\tstyle:\"string-2\" }\n\t];\n\n\tfunction getPossibles(symbol) {\n\t\tvar possibles=[], possiblesOb=ll1_table[symbol];\n\t\tif (possiblesOb!=undefined) {\n\t\t\tfor (var property in possiblesOb) {\n\t\t\t\tpossibles.push(property.toString());\n\t\t\t}\n\t\t} else {\n\t\t\tpossibles.push(symbol);\n\t\t}\n\t\treturn possibles;\n\t}\n\n\n\tfunction tokenBase(stream, state) {\n\n\t\tfunction nextToken() {\n\t\t\tvar consumed=null;\n\t\t\tif (state.inLiteral) {\n\t\t\t\t\n\t\t\t\tvar closingQuotes = false;\n\t\t\t\t//multi-line literal. try to parse contents.\n\t\t\t\tconsumed = stream.match(stringLiteralLongRegex[state.inLiteral].contents.regex, true, false);\n\t\t\t\tif (consumed && consumed[0].length == 0) {\n\t\t\t\t\t//try seeing whether we can consume closing quotes, to avoid stopping\n\t\t\t\t\tconsumed = stream.match(stringLiteralLongRegex[state.inLiteral].closing.regex, true, false);\n\t\t\t\t\tclosingQuotes = true;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (consumed && consumed[0].length > 0) {\n\t\t\t\t\t//some string content here. \n\t\t\t\t\t var returnObj = {\n\t\t\t\t\t\tquotePos: (closingQuotes? 'end': 'content'),\n\t\t\t\t\t\tcat: STRING_LITERAL_LONG[state.inLiteral].CAT,\n\t\t\t\t\t\tstyle: stringLiteralLongRegex[state.inLiteral].complete.style,\n\t\t\t\t\t\ttext: consumed[0],\n\t\t\t\t\t\tstart: stream.start\n\t\t\t\t\t};\n\t\t\t\t\t if (closingQuotes) state.inLiteral = false;\n\t\t\t\t\t return returnObj;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t//Multiline literals\n\t\t\tfor (var quoteType in stringLiteralLongRegex) {\n\t\t\t\tconsumed= stream.match(stringLiteralLongRegex[quoteType].quotes.regex,true,false);\n\t\t\t\tif (consumed) {\n\t\t\t\t\tvar quotePos;\n\t\t\t\t\tif (state.inLiteral) {\n\t\t\t\t\t\t//end of literal. everything is fine\n\t\t\t\t\t\tstate.inLiteral = false;\n\t\t\t\t\t\tquotePos = 'end';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate.inLiteral = quoteType;\n\t\t\t\t\t\tquotePos = 'start';\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcat: STRING_LITERAL_LONG[quoteType].CAT,\n\t\t\t\t\t\tstyle: stringLiteralLongRegex[quoteType].quotes.style,\n\t\t\t\t\t\ttext: consumed[0],\n\t\t\t\t\t\tquotePos: quotePos,\n\t\t\t\t\t\tstart: stream.start\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t// Tokens defined by individual regular expressions\n\t\t\tfor (var i=0; i\",\n\t\t\t\t\t\t\t style: \"error\",\n\t\t\t\t\t\t\t text: consumed[0],\n\t\t\t\t\t\t\t start: stream.start\n\t\t\t\t\t\t };\n\t\t}\n\n\t\tfunction recordFailurePos() {\n\t\t\t// tokenOb.style= \"sp-invalid\";\n\t\t\tvar col= stream.column();\n\t\t\tstate.errorStartPos= col;\n\t\t\tstate.errorEndPos= col+tokenOb.text.length;\n\t\t};\n\n\t\tfunction setQueryType(s) {\n\t\t\tif (state.queryType==null) {\n\t\t\t\tif (s ==\"SELECT\" || s==\"CONSTRUCT\" || s==\"ASK\" || s==\"DESCRIBE\" || s==\"INSERT\" || s==\"DELETE\" || s==\"LOAD\" || s==\"CLEAR\" || s==\"CREATE\" || s==\"DROP\" || s==\"COPY\" || s==\"MOVE\" || s==\"ADD\")\n\t\t\t\t\tstate.queryType=s;\n\t\t\t}\n\t\t}\n\n\t\t// Some fake non-terminals are just there to have side-effect on state\n\t\t// - i.e. allow or disallow variables and bnodes in certain non-nesting\n\t\t// contexts\n\t\tfunction setSideConditions(topSymbol) {\n\t\t\tif (topSymbol==\"disallowVars\") state.allowVars=false;\n\t\t\telse if (topSymbol==\"allowVars\") state.allowVars=true;\n\t\t\telse if (topSymbol==\"disallowBnodes\") state.allowBnodes=false;\n\t\t\telse if (topSymbol==\"allowBnodes\") state.allowBnodes=true;\n\t\t\telse if (topSymbol==\"storeProperty\") state.storeProperty=true;\n\t\t}\n\n\t\tfunction checkSideConditions(topSymbol) {\n\t\t\treturn(\n\t\t\t\t(state.allowVars || topSymbol!=\"var\") &&\n\t\t\t\t\t(state.allowBnodes ||\n\t\t\t\t\t (topSymbol!=\"blankNode\" &&\n\t\t\t\t\t\ttopSymbol!=\"blankNodePropertyList\" &&\n\t\t\t\t\t\ttopSymbol!=\"blankNodePropertyListPath\")));\n\t\t}\n\n\t\t// CodeMirror works with one line at a time,\n\t\t// but newline should behave like whitespace\n\t\t// - i.e. a definite break between tokens (for autocompleter)\n\t\tif (stream.pos==0)\n\t\t\tstate.possibleCurrent= state.possibleNext;\n\n\t\tvar tokenOb= nextToken();\n\n\n\t\tif (tokenOb.cat==\"\") {\n\t\t\t// set error state, and\n\t\t\tif (state.OK==true) {\n\t\t\t\tstate.OK=false;\n\t\t\t\trecordFailurePos();\n\t\t\t}\n\t\t\tstate.complete=false;\n\t\t\t// alert(\"Invalid:\"+tokenOb.text);\n\t\t\treturn tokenOb.style;\n\t\t}\n\n\t\tif (tokenOb.cat == \"WS\" || tokenOb.cat == \"COMMENT\" || (tokenOb.quotePos && tokenOb.quotePos != 'end')) {\n\t\t\tstate.possibleCurrent = state.possibleNext;\n\t\t\treturn(tokenOb.style);\n\t\t}\n\t\t// Otherwise, run the parser until the token is digested\n\t\t// or failure\n\t\tvar finished= false;\n\t\tvar topSymbol;\n\t\tvar token= tokenOb.cat;\n\t\t\n\t\tif (!tokenOb.quotePos || tokenOb.quotePos == 'end') {\n\t\t// Incremental LL1 parse\n\t\t\twhile(state.stack.length>0 && token && state.OK && !finished ) {\n\t\t\t\ttopSymbol= state.stack.pop();\n\t\n\t\t\t\tif (!ll1_table[topSymbol]) {\n\t\t\t\t\t// Top symbol is a terminal\n\t\t\t\t\tif (topSymbol == token) {\n\t\t\t\t\t\t// Matching terminals\n\t\t\t\t\t\t// - consume token from input stream\n\t\t\t\t\t\tfinished=true;\n\t\t\t\t\t\tsetQueryType(topSymbol);\n\t\t\t\t\t\t// Check whether $ (end of input token) is poss next\n\t\t\t\t\t\t// for everything on stack\n\t\t\t\t\t\tvar allNillable=true;\n\t\t\t\t\t\tfor(var sp=state.stack.length;sp>0;--sp) {\n\t\t\t\t\t\t\tvar item=ll1_table[state.stack[sp-1]];\n\t\t\t\t\t\t\tif (!item || !item[\"$\"])\n\t\t\t\t\t\t\t\tallNillable=false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate.complete= allNillable;\n\t\t\t\t\t\tif (state.storeProperty && token.cat != \"punc\") {\n\t\t\t\t\t\t\tstate.lastProperty = tokenOb.text;\n\t\t\t\t\t\t\tstate.storeProperty = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate.OK=false;\n\t\t\t\t\t\tstate.complete=false;\n\t\t\t\t\t\trecordFailurePos();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// topSymbol is nonterminal\n\t\t\t\t\t// - see if there is an entry for topSymbol\n\t\t\t\t\t// and nextToken in table\n\t\t\t\t\tvar nextSymbols= ll1_table[topSymbol][token];\n\t\t\t\t\tif (nextSymbols!=undefined && checkSideConditions(topSymbol)) {\n\t\t\t\t\t\t// Match - copy RHS of rule to stack\n\t\t\t\t\t\tfor (var i=nextSymbols.length-1; i>=0; --i) {\n\t\t\t\t\t\t\tstate.stack.push(nextSymbols[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Peform any non-grammatical side-effects\n\t\t\t\t\t\tsetSideConditions(topSymbol);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// No match in table - fail\n\t\t\t\t\t\tstate.OK=false;\n\t\t\t\t\t\tstate.complete=false;\n\t\t\t\t\t\trecordFailurePos();\n\t\t\t\t\t\tstate.stack.push(topSymbol); // Shove topSymbol back on stack\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!finished && state.OK) { \n\t\t\tstate.OK=false; state.complete=false; recordFailurePos(); \n\t\t}\n\t\t\n\t\tif (state.possibleCurrent.indexOf('a') >= 0){\n\t\t\tstate.lastPredicateOffset = tokenOb.start;\n\t\t}\n\t\tstate.possibleCurrent = state.possibleNext;\n\t\t\n\t\tstate.possibleNext = getPossibles(state.stack[state.stack.length-1]);\n\n\t\treturn tokenOb.style;\n\t}\n\n\tvar indentTop={\n\t\t\"*[,, object]\": 3,\n\t\t\"*[(,),object]\": 3,\n\t\t\"*[(,),objectPath]\": 3,\n\t\t\"*[/,pathEltOrInverse]\": 2,\n\t\t\"object\": 2,\n\t\t\"objectPath\": 2,\n\t\t\"objectList\": 2,\n\t\t\"objectListPath\": 2,\n\t\t\"storeProperty\": 2,\n\t\t\"pathMod\": 2,\n\t\t\"?pathMod\": 2,\n\t\t\"propertyListNotEmpty\": 1,\n\t\t\"propertyList\": 1,\n\t\t\"propertyListPath\": 1,\n\t\t\"propertyListPathNotEmpty\": 1,\n\t\t\"?[verb,objectList]\": 1,\n//\t\t\"?[or([verbPath, verbSimple]),objectList]\": 1,\n\t};\n\n\tvar indentTable={\n\t\t\"}\":1,\n\t\t\"]\":0,\n\t\t\")\":1,\n\t\t\"{\":-1,\n\t\t\"(\":-1,\n//\t\t\"*[;,?[or([verbPath,verbSimple]),objectList]]\": 1,\n\t};\n\t\n\n\tfunction indent(state, textAfter) {\n\t\t//just avoid we don't indent multi-line literals\n\t\tif (state.inLiteral) return 0;\n\t\tif (state.stack.length && state.stack[state.stack.length-1] == \"?[or([verbPath,verbSimple]),objectList]\") {\n\t\t\t//we are after a semi-colon. I.e., nicely align this line with predicate position of previous line\n\t\t\treturn state.lastPredicateOffset;\n\t\t} else {\n\t\t\tvar n = 0; // indent level\n\t\t\tvar i = state.stack.length-1;\n\t\t\tif (/^[\\}\\]\\)]/.test(textAfter)) {\n\t\t\t\t// Skip stack items until after matching bracket\n\t\t\t\tvar closeBracket=textAfter.substr(0,1);\n\t\t\t\tfor( ;i>=0;--i)\t{\n\t\t\t\t\tif (state.stack[i]==closeBracket) {\n\t\t\t\t\t\t--i; \n\t\t\t\t\t\tbreak;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Consider nullable non-terminals if at top of stack\n\t\t\t\tvar dn = indentTop[state.stack[i]];\n\t\t\t\tif (dn) { \n\t\t\t\t\tn += dn; \n\t\t\t\t\t--i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor( ;i>=0;--i)\t{\n\t\t\t\tvar dn = indentTable[state.stack[i]];\n\t\t\t\tif (dn) {\n\t\t\t\t\tn+=dn;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn n * config.indentUnit;\n\t\t}\n\t};\n\n\treturn {\n\t\ttoken: tokenBase,\n\t\tstartState: function(base) {\n\t\t\treturn {\n\t\t\t\ttokenize: tokenBase,\n\t\t\t\tOK: true,\n\t\t\t\tcomplete: grammar.acceptEmpty,\n\t\t\t\terrorStartPos: null,\n\t\t\t\terrorEndPos: null,\n\t\t\t\tqueryType: null,\n\t\t\t\tpossibleCurrent: getPossibles(grammar.startSymbol),\n\t\t\t\tpossibleNext: getPossibles(grammar.startSymbol),\n\t\t\t\tallowVars : true,\n\t\t\t\tallowBnodes : true,\n\t\t\t\tstoreProperty : false,\n\t\t\t\tlastProperty : \"\",\n\t\t\t\tinLiteral: false,\n\t\t\t\tstack: [grammar.startSymbol],\n\t\t\t\tlastPredicateOffset: config.indentUnit,\n\t\t\t}; \n\t\t},\n\t\tindent: indent,\n\t\telectricChars: \"}])\"\n\t};\n}\n);\nCodeMirror.defineMIME(\"application/x-sparql-query\", \"sparql11\");\n\n},{\"./_tokenizer-table.js\":3,\"codemirror\":15}],5:[function(require,module,exports){\n/*\n* TRIE implementation in Javascript\n* Copyright (c) 2010 Saurabh Odhyan | http://odhyan.com\n* \n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n* \n* The above copyright notice and this permission notice shall be included in\n* all copies or substantial portions of the Software.\n* \n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n* THE SOFTWARE.\n*\n* Date: Nov 7, 2010\n*/\n\n/*\n* A trie, or prefix tree, is a multi-way tree structure useful for storing strings over an alphabet. \n* It has been used to store large dictionaries of English (say) words in spell-checking programs \n* and in natural-language \"understanding\" programs. \n* @see http://en.wikipedia.org/wiki/Trie\n* @see http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/Trie/\n/*\n\n* @class Trie\n* @constructor\n*/ \nvar Trie = module.exports = function() {\n this.words = 0;\n this.prefixes = 0;\n this.children = [];\n};\n\nTrie.prototype = {\n \n /*\n * Insert a word into the dictionary. \n * Recursively traverse through the trie nodes, and create new node if does not already exist.\n *\n * @method insert\n * @param {String} str Word to insert in the dictionary\n * @param {Integer} pos Current index of the string to be inserted\n * @return {Void}\n */\n insert: function(str, pos) {\n if(str.length == 0) { //blank string cannot be inserted\n return;\n }\n \n var T = this,\n k,\n child;\n \n if(pos === undefined) {\n pos = 0;\n }\n if(pos === str.length) {\n T.words ++;\n return;\n }\n T.prefixes ++;\n k = str[pos];\n if(T.children[k] === undefined) { //if node for this char doesn't exist, create one\n T.children[k] = new Trie();\n }\n child = T.children[k];\n child.insert(str, pos + 1);\n },\n \n /*\n * Remove a word from the dictionary.\n *\n * @method remove\n * @param {String} str Word to be removed\n * @param {Integer} pos Current index of the string to be removed\n * @return {Void}\n */\n remove: function(str, pos) {\n if(str.length == 0) {\n return;\n }\n \n var T = this,\n k,\n child;\n \n if(pos === undefined) {\n pos = 0;\n } \n if(T === undefined) {\n return;\n }\n if(pos === str.length) {\n T.words --;\n return;\n }\n T.prefixes --;\n k = str[pos];\n child = T.children[k];\n child.remove(str, pos + 1);\n },\n \n /*\n * Update an existing word in the dictionary. \n * This method removes the old word from the dictionary and inserts the new word.\n *\n * @method update\n * @param {String} strOld The old word to be replaced\n * @param {String} strNew The new word to be inserted\n * @return {Void}\n */\n update: function(strOld, strNew) {\n if(strOld.length == 0 || strNew.length == 0) {\n return;\n }\n this.remove(strOld);\n this.insert(strNew);\n },\n \n /*\n * Count the number of times a given word has been inserted into the dictionary\n *\n * @method countWord\n * @param {String} str Word to get count of\n * @param {Integer} pos Current index of the given word\n * @return {Integer} The number of times a given word exists in the dictionary\n */\n countWord: function(str, pos) {\n if(str.length == 0) {\n return 0;\n }\n \n var T = this,\n k,\n child,\n ret = 0;\n \n if(pos === undefined) {\n pos = 0;\n } \n if(pos === str.length) {\n return T.words;\n }\n k = str[pos];\n child = T.children[k];\n if(child !== undefined) { //node exists\n ret = child.countWord(str, pos + 1);\n }\n return ret;\n },\n \n /*\n * Count the number of times a given prefix exists in the dictionary\n *\n * @method countPrefix\n * @param {String} str Prefix to get count of\n * @param {Integer} pos Current index of the given prefix\n * @return {Integer} The number of times a given prefix exists in the dictionary\n */\n countPrefix: function(str, pos) {\n if(str.length == 0) {\n return 0;\n }\n \n var T = this,\n k,\n child,\n ret = 0;\n\n if(pos === undefined) {\n pos = 0;\n }\n if(pos === str.length) {\n return T.prefixes;\n }\n var k = str[pos];\n child = T.children[k];\n if(child !== undefined) { //node exists\n ret = child.countPrefix(str, pos + 1); \n }\n return ret; \n },\n \n /*\n * Find a word in the dictionary\n *\n * @method find\n * @param {String} str The word to find in the dictionary\n * @return {Boolean} True if the word exists in the dictionary, else false\n */\n find: function(str) {\n if(str.length == 0) {\n return false;\n }\n \n if(this.countWord(str) > 0) {\n return true;\n } else {\n return false;\n }\n },\n \n /*\n * Get all words in the dictionary\n *\n * @method getAllWords\n * @param {String} str Prefix of current word\n * @return {Array} Array of words in the dictionary\n */\n getAllWords: function(str) {\n var T = this,\n k,\n child,\n ret = [];\n if(str === undefined) {\n str = \"\";\n }\n if(T === undefined) {\n return [];\n }\n if(T.words > 0) {\n ret.push(str);\n }\n for(k in T.children) {\n child = T.children[k];\n ret = ret.concat(child.getAllWords(str + k));\n }\n return ret;\n },\n \n /*\n * Autocomplete a given prefix\n *\n * @method autoComplete\n * @param {String} str Prefix to be completed based on dictionary entries\n * @param {Integer} pos Current index of the prefix\n * @return {Array} Array of possible suggestions\n */\n autoComplete: function(str, pos) {\n \n \n var T = this,\n k,\n child;\n if(str.length == 0) {\n\t\t\tif (pos === undefined) {\n\t\t\t\treturn T.getAllWords(str);\n\t\t\t} else {\n\t\t\t\treturn [];\n\t\t\t}\n }\n if(pos === undefined) {\n pos = 0;\n } \n k = str[pos];\n child = T.children[k];\n if(child === undefined) { //node doesn't exist\n return [];\n }\n if(pos === str.length - 1) {\n return child.getAllWords(str);\n }\n return child.autoComplete(str, pos + 1);\n }\n};\n\n},{}],6:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n CodeMirror.defineOption(\"fullScreen\", false, function(cm, val, old) {\n if (old == CodeMirror.Init) old = false;\n if (!old == !val) return;\n if (val) setFullscreen(cm);\n else setNormal(cm);\n });\n\n function setFullscreen(cm) {\n var wrap = cm.getWrapperElement();\n cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,\n width: wrap.style.width, height: wrap.style.height};\n wrap.style.width = \"\";\n wrap.style.height = \"auto\";\n wrap.className += \" CodeMirror-fullscreen\";\n document.documentElement.style.overflow = \"hidden\";\n cm.refresh();\n }\n\n function setNormal(cm) {\n var wrap = cm.getWrapperElement();\n wrap.className = wrap.className.replace(/\\s*CodeMirror-fullscreen\\b/, \"\");\n document.documentElement.style.overflow = \"\";\n var info = cm.state.fullScreenRestore;\n wrap.style.width = info.width; wrap.style.height = info.height;\n window.scrollTo(info.scrollLeft, info.scrollTop);\n cm.refresh();\n }\n});\n\n},{\"../../lib/codemirror\":15}],7:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n var ie_lt8 = /MSIE \\d/.test(navigator.userAgent) &&\n (document.documentMode == null || document.documentMode < 8);\n\n var Pos = CodeMirror.Pos;\n\n var matching = {\"(\": \")>\", \")\": \"(<\", \"[\": \"]>\", \"]\": \"[<\", \"{\": \"}>\", \"}\": \"{<\"};\n\n function findMatchingBracket(cm, where, strict, config) {\n var line = cm.getLineHandle(where.line), pos = where.ch - 1;\n var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];\n if (!match) return null;\n var dir = match.charAt(1) == \">\" ? 1 : -1;\n if (strict && (dir > 0) != (pos == where.ch)) return null;\n var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));\n\n var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);\n if (found == null) return null;\n return {from: Pos(where.line, pos), to: found && found.pos,\n match: found && found.ch == match.charAt(0), forward: dir > 0};\n }\n\n // bracketRegex is used to specify which type of bracket to scan\n // should be a regexp, e.g. /[[\\]]/\n //\n // Note: If \"where\" is on an open bracket, then this bracket is ignored.\n //\n // Returns false when no bracket was found, null when it reached\n // maxScanLines and gave up\n function scanForBracket(cm, where, dir, style, config) {\n var maxScanLen = (config && config.maxScanLineLength) || 10000;\n var maxScanLines = (config && config.maxScanLines) || 1000;\n\n var stack = [];\n var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\\]]/;\n var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)\n : Math.max(cm.firstLine() - 1, where.line - maxScanLines);\n for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {\n var line = cm.getLine(lineNo);\n if (!line) continue;\n var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;\n if (line.length > maxScanLen) continue;\n if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);\n for (; pos != end; pos += dir) {\n var ch = line.charAt(pos);\n if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {\n var match = matching[ch];\n if ((match.charAt(1) == \">\") == (dir > 0)) stack.push(ch);\n else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};\n else stack.pop();\n }\n }\n }\n return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;\n }\n\n function matchBrackets(cm, autoclear, config) {\n // Disable brace matching in long lines, since it'll cause hugely slow updates\n var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;\n var marks = [], ranges = cm.listSelections();\n for (var i = 0; i < ranges.length; i++) {\n var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config);\n if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {\n var style = match.match ? \"CodeMirror-matchingbracket\" : \"CodeMirror-nonmatchingbracket\";\n marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));\n if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)\n marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));\n }\n }\n\n if (marks.length) {\n // Kludge to work around the IE bug from issue #1193, where text\n // input stops going to the textare whever this fires.\n if (ie_lt8 && cm.state.focused) cm.display.input.focus();\n\n var clear = function() {\n cm.operation(function() {\n for (var i = 0; i < marks.length; i++) marks[i].clear();\n });\n };\n if (autoclear) setTimeout(clear, 800);\n else return clear;\n }\n }\n\n var currentlyHighlighted = null;\n function doMatchBrackets(cm) {\n cm.operation(function() {\n if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}\n currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);\n });\n }\n\n CodeMirror.defineOption(\"matchBrackets\", false, function(cm, val, old) {\n if (old && old != CodeMirror.Init)\n cm.off(\"cursorActivity\", doMatchBrackets);\n if (val) {\n cm.state.matchBrackets = typeof val == \"object\" ? val : {};\n cm.on(\"cursorActivity\", doMatchBrackets);\n }\n });\n\n CodeMirror.defineExtension(\"matchBrackets\", function() {matchBrackets(this, true);});\n CodeMirror.defineExtension(\"findMatchingBracket\", function(pos, strict, config){\n return findMatchingBracket(this, pos, strict, config);\n });\n CodeMirror.defineExtension(\"scanForBracket\", function(pos, dir, style, config){\n return scanForBracket(this, pos, dir, style, config);\n });\n});\n\n},{\"../../lib/codemirror\":15}],8:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nCodeMirror.registerHelper(\"fold\", \"brace\", function(cm, start) {\n var line = start.line, lineText = cm.getLine(line);\n var startCh, tokenType;\n\n function findOpening(openCh) {\n for (var at = start.ch, pass = 0;;) {\n var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);\n if (found == -1) {\n if (pass == 1) break;\n pass = 1;\n at = lineText.length;\n continue;\n }\n if (pass == 1 && found < start.ch) break;\n tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));\n if (!/^(comment|string)/.test(tokenType)) return found + 1;\n at = found - 1;\n }\n }\n\n var startToken = \"{\", endToken = \"}\", startCh = findOpening(\"{\");\n if (startCh == null) {\n startToken = \"[\", endToken = \"]\";\n startCh = findOpening(\"[\");\n }\n\n if (startCh == null) return;\n var count = 1, lastLine = cm.lastLine(), end, endCh;\n outer: for (var i = line; i <= lastLine; ++i) {\n var text = cm.getLine(i), pos = i == line ? startCh : 0;\n for (;;) {\n var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);\n if (nextOpen < 0) nextOpen = text.length;\n if (nextClose < 0) nextClose = text.length;\n pos = Math.min(nextOpen, nextClose);\n if (pos == text.length) break;\n if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {\n if (pos == nextOpen) ++count;\n else if (!--count) { end = i; endCh = pos; break outer; }\n }\n ++pos;\n }\n }\n if (end == null || line == end && endCh == startCh) return;\n return {from: CodeMirror.Pos(line, startCh),\n to: CodeMirror.Pos(end, endCh)};\n});\n\nCodeMirror.registerHelper(\"fold\", \"import\", function(cm, start) {\n function hasImport(line) {\n if (line < cm.firstLine() || line > cm.lastLine()) return null;\n var start = cm.getTokenAt(CodeMirror.Pos(line, 1));\n if (!/\\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));\n if (start.type != \"keyword\" || start.string != \"import\") return null;\n // Now find closing semicolon, return its position\n for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {\n var text = cm.getLine(i), semi = text.indexOf(\";\");\n if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};\n }\n }\n\n var start = start.line, has = hasImport(start), prev;\n if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1))\n return null;\n for (var end = has.end;;) {\n var next = hasImport(end.line + 1);\n if (next == null) break;\n end = next.end;\n }\n return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end};\n});\n\nCodeMirror.registerHelper(\"fold\", \"include\", function(cm, start) {\n function hasInclude(line) {\n if (line < cm.firstLine() || line > cm.lastLine()) return null;\n var start = cm.getTokenAt(CodeMirror.Pos(line, 1));\n if (!/\\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));\n if (start.type == \"meta\" && start.string.slice(0, 8) == \"#include\") return start.start + 8;\n }\n\n var start = start.line, has = hasInclude(start);\n if (has == null || hasInclude(start - 1) != null) return null;\n for (var end = start;;) {\n var next = hasInclude(end + 1);\n if (next == null) break;\n ++end;\n }\n return {from: CodeMirror.Pos(start, has + 1),\n to: cm.clipPos(CodeMirror.Pos(end))};\n});\n\n});\n\n},{\"../../lib/codemirror\":15}],9:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n function doFold(cm, pos, options, force) {\n if (options && options.call) {\n var finder = options;\n options = null;\n } else {\n var finder = getOption(cm, options, \"rangeFinder\");\n }\n if (typeof pos == \"number\") pos = CodeMirror.Pos(pos, 0);\n var minSize = getOption(cm, options, \"minFoldSize\");\n\n function getRange(allowFolded) {\n var range = finder(cm, pos);\n if (!range || range.to.line - range.from.line < minSize) return null;\n var marks = cm.findMarksAt(range.from);\n for (var i = 0; i < marks.length; ++i) {\n if (marks[i].__isFold && force !== \"fold\") {\n if (!allowFolded) return null;\n range.cleared = true;\n marks[i].clear();\n }\n }\n return range;\n }\n\n var range = getRange(true);\n if (getOption(cm, options, \"scanUp\")) while (!range && pos.line > cm.firstLine()) {\n pos = CodeMirror.Pos(pos.line - 1, 0);\n range = getRange(false);\n }\n if (!range || range.cleared || force === \"unfold\") return;\n\n var myWidget = makeWidget(cm, options);\n CodeMirror.on(myWidget, \"mousedown\", function(e) {\n myRange.clear();\n CodeMirror.e_preventDefault(e);\n });\n var myRange = cm.markText(range.from, range.to, {\n replacedWith: myWidget,\n clearOnEnter: true,\n __isFold: true\n });\n myRange.on(\"clear\", function(from, to) {\n CodeMirror.signal(cm, \"unfold\", cm, from, to);\n });\n CodeMirror.signal(cm, \"fold\", cm, range.from, range.to);\n }\n\n function makeWidget(cm, options) {\n var widget = getOption(cm, options, \"widget\");\n if (typeof widget == \"string\") {\n var text = document.createTextNode(widget);\n widget = document.createElement(\"span\");\n widget.appendChild(text);\n widget.className = \"CodeMirror-foldmarker\";\n }\n return widget;\n }\n\n // Clumsy backwards-compatible interface\n CodeMirror.newFoldFunction = function(rangeFinder, widget) {\n return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };\n };\n\n // New-style interface\n CodeMirror.defineExtension(\"foldCode\", function(pos, options, force) {\n doFold(this, pos, options, force);\n });\n\n CodeMirror.defineExtension(\"isFolded\", function(pos) {\n var marks = this.findMarksAt(pos);\n for (var i = 0; i < marks.length; ++i)\n if (marks[i].__isFold) return true;\n });\n\n CodeMirror.commands.toggleFold = function(cm) {\n cm.foldCode(cm.getCursor());\n };\n CodeMirror.commands.fold = function(cm) {\n cm.foldCode(cm.getCursor(), null, \"fold\");\n };\n CodeMirror.commands.unfold = function(cm) {\n cm.foldCode(cm.getCursor(), null, \"unfold\");\n };\n CodeMirror.commands.foldAll = function(cm) {\n cm.operation(function() {\n for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)\n cm.foldCode(CodeMirror.Pos(i, 0), null, \"fold\");\n });\n };\n CodeMirror.commands.unfoldAll = function(cm) {\n cm.operation(function() {\n for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)\n cm.foldCode(CodeMirror.Pos(i, 0), null, \"unfold\");\n });\n };\n\n CodeMirror.registerHelper(\"fold\", \"combine\", function() {\n var funcs = Array.prototype.slice.call(arguments, 0);\n return function(cm, start) {\n for (var i = 0; i < funcs.length; ++i) {\n var found = funcs[i](cm, start);\n if (found) return found;\n }\n };\n });\n\n CodeMirror.registerHelper(\"fold\", \"auto\", function(cm, start) {\n var helpers = cm.getHelpers(start, \"fold\");\n for (var i = 0; i < helpers.length; i++) {\n var cur = helpers[i](cm, start);\n if (cur) return cur;\n }\n });\n\n var defaultOptions = {\n rangeFinder: CodeMirror.fold.auto,\n widget: \"\\u2194\",\n minFoldSize: 0,\n scanUp: false\n };\n\n CodeMirror.defineOption(\"foldOptions\", null);\n\n function getOption(cm, options, name) {\n if (options && options[name] !== undefined)\n return options[name];\n var editorOptions = cm.options.foldOptions;\n if (editorOptions && editorOptions[name] !== undefined)\n return editorOptions[name];\n return defaultOptions[name];\n }\n\n CodeMirror.defineExtension(\"foldOption\", function(options, name) {\n return getOption(this, options, name);\n });\n});\n\n},{\"../../lib/codemirror\":15}],10:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"), require(\"./foldcode\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\", \"./foldcode\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n CodeMirror.defineOption(\"foldGutter\", false, function(cm, val, old) {\n if (old && old != CodeMirror.Init) {\n cm.clearGutter(cm.state.foldGutter.options.gutter);\n cm.state.foldGutter = null;\n cm.off(\"gutterClick\", onGutterClick);\n cm.off(\"change\", onChange);\n cm.off(\"viewportChange\", onViewportChange);\n cm.off(\"fold\", onFold);\n cm.off(\"unfold\", onFold);\n cm.off(\"swapDoc\", updateInViewport);\n }\n if (val) {\n cm.state.foldGutter = new State(parseOptions(val));\n updateInViewport(cm);\n cm.on(\"gutterClick\", onGutterClick);\n cm.on(\"change\", onChange);\n cm.on(\"viewportChange\", onViewportChange);\n cm.on(\"fold\", onFold);\n cm.on(\"unfold\", onFold);\n cm.on(\"swapDoc\", updateInViewport);\n }\n });\n\n var Pos = CodeMirror.Pos;\n\n function State(options) {\n this.options = options;\n this.from = this.to = 0;\n }\n\n function parseOptions(opts) {\n if (opts === true) opts = {};\n if (opts.gutter == null) opts.gutter = \"CodeMirror-foldgutter\";\n if (opts.indicatorOpen == null) opts.indicatorOpen = \"CodeMirror-foldgutter-open\";\n if (opts.indicatorFolded == null) opts.indicatorFolded = \"CodeMirror-foldgutter-folded\";\n return opts;\n }\n\n function isFolded(cm, line) {\n var marks = cm.findMarksAt(Pos(line));\n for (var i = 0; i < marks.length; ++i)\n if (marks[i].__isFold && marks[i].find().from.line == line) return true;\n }\n\n function marker(spec) {\n if (typeof spec == \"string\") {\n var elt = document.createElement(\"div\");\n elt.className = spec + \" CodeMirror-guttermarker-subtle\";\n return elt;\n } else {\n return spec.cloneNode(true);\n }\n }\n\n function updateFoldInfo(cm, from, to) {\n var opts = cm.state.foldGutter.options, cur = from;\n var minSize = cm.foldOption(opts, \"minFoldSize\");\n var func = cm.foldOption(opts, \"rangeFinder\");\n cm.eachLine(from, to, function(line) {\n var mark = null;\n if (isFolded(cm, cur)) {\n mark = marker(opts.indicatorFolded);\n } else {\n var pos = Pos(cur, 0);\n var range = func && func(cm, pos);\n if (range && range.to.line - range.from.line >= minSize)\n mark = marker(opts.indicatorOpen);\n }\n cm.setGutterMarker(line, opts.gutter, mark);\n ++cur;\n });\n }\n\n function updateInViewport(cm) {\n var vp = cm.getViewport(), state = cm.state.foldGutter;\n if (!state) return;\n cm.operation(function() {\n updateFoldInfo(cm, vp.from, vp.to);\n });\n state.from = vp.from; state.to = vp.to;\n }\n\n function onGutterClick(cm, line, gutter) {\n var opts = cm.state.foldGutter.options;\n if (gutter != opts.gutter) return;\n cm.foldCode(Pos(line, 0), opts.rangeFinder);\n }\n\n function onChange(cm) {\n var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;\n state.from = state.to = 0;\n clearTimeout(state.changeUpdate);\n state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);\n }\n\n function onViewportChange(cm) {\n var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;\n clearTimeout(state.changeUpdate);\n state.changeUpdate = setTimeout(function() {\n var vp = cm.getViewport();\n if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {\n updateInViewport(cm);\n } else {\n cm.operation(function() {\n if (vp.from < state.from) {\n updateFoldInfo(cm, vp.from, state.from);\n state.from = vp.from;\n }\n if (vp.to > state.to) {\n updateFoldInfo(cm, state.to, vp.to);\n state.to = vp.to;\n }\n });\n }\n }, opts.updateViewportTimeSpan || 400);\n }\n\n function onFold(cm, from) {\n var state = cm.state.foldGutter, line = from.line;\n if (line >= state.from && line < state.to)\n updateFoldInfo(cm, line, line + 1);\n }\n});\n\n},{\"../../lib/codemirror\":15,\"./foldcode\":9}],11:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n var Pos = CodeMirror.Pos;\n function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }\n\n var nameStartChar = \"A-Z_a-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD\";\n var nameChar = nameStartChar + \"\\-\\:\\.0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040\";\n var xmlTagStart = new RegExp(\"<(/?)([\" + nameStartChar + \"][\" + nameChar + \"]*)\", \"g\");\n\n function Iter(cm, line, ch, range) {\n this.line = line; this.ch = ch;\n this.cm = cm; this.text = cm.getLine(line);\n this.min = range ? range.from : cm.firstLine();\n this.max = range ? range.to - 1 : cm.lastLine();\n }\n\n function tagAt(iter, ch) {\n var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch));\n return type && /\\btag\\b/.test(type);\n }\n\n function nextLine(iter) {\n if (iter.line >= iter.max) return;\n iter.ch = 0;\n iter.text = iter.cm.getLine(++iter.line);\n return true;\n }\n function prevLine(iter) {\n if (iter.line <= iter.min) return;\n iter.text = iter.cm.getLine(--iter.line);\n iter.ch = iter.text.length;\n return true;\n }\n\n function toTagEnd(iter) {\n for (;;) {\n var gt = iter.text.indexOf(\">\", iter.ch);\n if (gt == -1) { if (nextLine(iter)) continue; else return; }\n if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; }\n var lastSlash = iter.text.lastIndexOf(\"/\", gt);\n var selfClose = lastSlash > -1 && !/\\S/.test(iter.text.slice(lastSlash + 1, gt));\n iter.ch = gt + 1;\n return selfClose ? \"selfClose\" : \"regular\";\n }\n }\n function toTagStart(iter) {\n for (;;) {\n var lt = iter.ch ? iter.text.lastIndexOf(\"<\", iter.ch - 1) : -1;\n if (lt == -1) { if (prevLine(iter)) continue; else return; }\n if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; }\n xmlTagStart.lastIndex = lt;\n iter.ch = lt;\n var match = xmlTagStart.exec(iter.text);\n if (match && match.index == lt) return match;\n }\n }\n\n function toNextTag(iter) {\n for (;;) {\n xmlTagStart.lastIndex = iter.ch;\n var found = xmlTagStart.exec(iter.text);\n if (!found) { if (nextLine(iter)) continue; else return; }\n if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; }\n iter.ch = found.index + found[0].length;\n return found;\n }\n }\n function toPrevTag(iter) {\n for (;;) {\n var gt = iter.ch ? iter.text.lastIndexOf(\">\", iter.ch - 1) : -1;\n if (gt == -1) { if (prevLine(iter)) continue; else return; }\n if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; }\n var lastSlash = iter.text.lastIndexOf(\"/\", gt);\n var selfClose = lastSlash > -1 && !/\\S/.test(iter.text.slice(lastSlash + 1, gt));\n iter.ch = gt + 1;\n return selfClose ? \"selfClose\" : \"regular\";\n }\n }\n\n function findMatchingClose(iter, tag) {\n var stack = [];\n for (;;) {\n var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0);\n if (!next || !(end = toTagEnd(iter))) return;\n if (end == \"selfClose\") continue;\n if (next[1]) { // closing tag\n for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {\n stack.length = i;\n break;\n }\n if (i < 0 && (!tag || tag == next[2])) return {\n tag: next[2],\n from: Pos(startLine, startCh),\n to: Pos(iter.line, iter.ch)\n };\n } else { // opening tag\n stack.push(next[2]);\n }\n }\n }\n function findMatchingOpen(iter, tag) {\n var stack = [];\n for (;;) {\n var prev = toPrevTag(iter);\n if (!prev) return;\n if (prev == \"selfClose\") { toTagStart(iter); continue; }\n var endLine = iter.line, endCh = iter.ch;\n var start = toTagStart(iter);\n if (!start) return;\n if (start[1]) { // closing tag\n stack.push(start[2]);\n } else { // opening tag\n for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) {\n stack.length = i;\n break;\n }\n if (i < 0 && (!tag || tag == start[2])) return {\n tag: start[2],\n from: Pos(iter.line, iter.ch),\n to: Pos(endLine, endCh)\n };\n }\n }\n }\n\n CodeMirror.registerHelper(\"fold\", \"xml\", function(cm, start) {\n var iter = new Iter(cm, start.line, 0);\n for (;;) {\n var openTag = toNextTag(iter), end;\n if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return;\n if (!openTag[1] && end != \"selfClose\") {\n var start = Pos(iter.line, iter.ch);\n var close = findMatchingClose(iter, openTag[2]);\n return close && {from: start, to: close.from};\n }\n }\n });\n CodeMirror.findMatchingTag = function(cm, pos, range) {\n var iter = new Iter(cm, pos.line, pos.ch, range);\n if (iter.text.indexOf(\">\") == -1 && iter.text.indexOf(\"<\") == -1) return;\n var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);\n var start = end && toTagStart(iter);\n if (!end || !start || cmp(iter, pos) > 0) return;\n var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};\n if (end == \"selfClose\") return {open: here, close: null, at: \"open\"};\n\n if (start[1]) { // closing tag\n return {open: findMatchingOpen(iter, start[2]), close: here, at: \"close\"};\n } else { // opening tag\n iter = new Iter(cm, to.line, to.ch, range);\n return {open: here, close: findMatchingClose(iter, start[2]), at: \"open\"};\n }\n };\n\n CodeMirror.findEnclosingTag = function(cm, pos, range) {\n var iter = new Iter(cm, pos.line, pos.ch, range);\n for (;;) {\n var open = findMatchingOpen(iter);\n if (!open) break;\n var forward = new Iter(cm, pos.line, pos.ch, range);\n var close = findMatchingClose(forward, open.tag);\n if (close) return {open: open, close: close};\n }\n };\n\n // Used by addon/edit/closetag.js\n CodeMirror.scanForClosingTag = function(cm, pos, name, end) {\n var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null);\n return findMatchingClose(iter, name);\n };\n});\n\n},{\"../../lib/codemirror\":15}],12:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n var HINT_ELEMENT_CLASS = \"CodeMirror-hint\";\n var ACTIVE_HINT_ELEMENT_CLASS = \"CodeMirror-hint-active\";\n\n // This is the old interface, kept around for now to stay\n // backwards-compatible.\n CodeMirror.showHint = function(cm, getHints, options) {\n if (!getHints) return cm.showHint(options);\n if (options && options.async) getHints.async = true;\n var newOpts = {hint: getHints};\n if (options) for (var prop in options) newOpts[prop] = options[prop];\n return cm.showHint(newOpts);\n };\n\n CodeMirror.defineExtension(\"showHint\", function(options) {\n // We want a single cursor position.\n if (this.listSelections().length > 1 || this.somethingSelected()) return;\n\n if (this.state.completionActive) this.state.completionActive.close();\n var completion = this.state.completionActive = new Completion(this, options);\n var getHints = completion.options.hint;\n if (!getHints) return;\n\n CodeMirror.signal(this, \"startCompletion\", this);\n if (getHints.async)\n getHints(this, function(hints) { completion.showHints(hints); }, completion.options);\n else\n return completion.showHints(getHints(this, completion.options));\n });\n\n function Completion(cm, options) {\n this.cm = cm;\n this.options = this.buildOptions(options);\n this.widget = this.onClose = null;\n }\n\n Completion.prototype = {\n close: function() {\n if (!this.active()) return;\n this.cm.state.completionActive = null;\n\n if (this.widget) this.widget.close();\n if (this.onClose) this.onClose();\n CodeMirror.signal(this.cm, \"endCompletion\", this.cm);\n },\n\n active: function() {\n return this.cm.state.completionActive == this;\n },\n\n pick: function(data, i) {\n var completion = data.list[i];\n if (completion.hint) completion.hint(this.cm, data, completion);\n else this.cm.replaceRange(getText(completion), completion.from || data.from,\n completion.to || data.to, \"complete\");\n CodeMirror.signal(data, \"pick\", completion);\n this.close();\n },\n\n showHints: function(data) {\n if (!data || !data.list.length || !this.active()) return this.close();\n\n if (this.options.completeSingle && data.list.length == 1)\n this.pick(data, 0);\n else\n this.showWidget(data);\n },\n\n showWidget: function(data) {\n this.widget = new Widget(this, data);\n CodeMirror.signal(data, \"shown\");\n\n var debounce = 0, completion = this, finished;\n var closeOn = this.options.closeCharacters;\n var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length;\n\n var requestAnimationFrame = window.requestAnimationFrame || function(fn) {\n return setTimeout(fn, 1000/60);\n };\n var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;\n\n function done() {\n if (finished) return;\n finished = true;\n completion.close();\n completion.cm.off(\"cursorActivity\", activity);\n if (data) CodeMirror.signal(data, \"close\");\n }\n\n function update() {\n if (finished) return;\n CodeMirror.signal(data, \"update\");\n var getHints = completion.options.hint;\n if (getHints.async)\n getHints(completion.cm, finishUpdate, completion.options);\n else\n finishUpdate(getHints(completion.cm, completion.options));\n }\n function finishUpdate(data_) {\n data = data_;\n if (finished) return;\n if (!data || !data.list.length) return done();\n if (completion.widget) completion.widget.close();\n completion.widget = new Widget(completion, data);\n }\n\n function clearDebounce() {\n if (debounce) {\n cancelAnimationFrame(debounce);\n debounce = 0;\n }\n }\n\n function activity() {\n clearDebounce();\n var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line);\n if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch ||\n pos.ch < startPos.ch || completion.cm.somethingSelected() ||\n (pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) {\n completion.close();\n } else {\n debounce = requestAnimationFrame(update);\n if (completion.widget) completion.widget.close();\n }\n }\n this.cm.on(\"cursorActivity\", activity);\n this.onClose = done;\n },\n\n buildOptions: function(options) {\n var editor = this.cm.options.hintOptions;\n var out = {};\n for (var prop in defaultOptions) out[prop] = defaultOptions[prop];\n if (editor) for (var prop in editor)\n if (editor[prop] !== undefined) out[prop] = editor[prop];\n if (options) for (var prop in options)\n if (options[prop] !== undefined) out[prop] = options[prop];\n return out;\n }\n };\n\n function getText(completion) {\n if (typeof completion == \"string\") return completion;\n else return completion.text;\n }\n\n function buildKeyMap(completion, handle) {\n var baseMap = {\n Up: function() {handle.moveFocus(-1);},\n Down: function() {handle.moveFocus(1);},\n PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},\n PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},\n Home: function() {handle.setFocus(0);},\n End: function() {handle.setFocus(handle.length - 1);},\n Enter: handle.pick,\n Tab: handle.pick,\n Esc: handle.close\n };\n var custom = completion.options.customKeys;\n var ourMap = custom ? {} : baseMap;\n function addBinding(key, val) {\n var bound;\n if (typeof val != \"string\")\n bound = function(cm) { return val(cm, handle); };\n // This mechanism is deprecated\n else if (baseMap.hasOwnProperty(val))\n bound = baseMap[val];\n else\n bound = val;\n ourMap[key] = bound;\n }\n if (custom)\n for (var key in custom) if (custom.hasOwnProperty(key))\n addBinding(key, custom[key]);\n var extra = completion.options.extraKeys;\n if (extra)\n for (var key in extra) if (extra.hasOwnProperty(key))\n addBinding(key, extra[key]);\n return ourMap;\n }\n\n function getHintElement(hintsElement, el) {\n while (el && el != hintsElement) {\n if (el.nodeName.toUpperCase() === \"LI\" && el.parentNode == hintsElement) return el;\n el = el.parentNode;\n }\n }\n\n function Widget(completion, data) {\n this.completion = completion;\n this.data = data;\n var widget = this, cm = completion.cm;\n\n var hints = this.hints = document.createElement(\"ul\");\n hints.className = \"CodeMirror-hints\";\n this.selectedHint = data.selectedHint || 0;\n\n var completions = data.list;\n for (var i = 0; i < completions.length; ++i) {\n var elt = hints.appendChild(document.createElement(\"li\")), cur = completions[i];\n var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? \"\" : \" \" + ACTIVE_HINT_ELEMENT_CLASS);\n if (cur.className != null) className = cur.className + \" \" + className;\n elt.className = className;\n if (cur.render) cur.render(elt, data, cur);\n else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));\n elt.hintId = i;\n }\n\n var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);\n var left = pos.left, top = pos.bottom, below = true;\n hints.style.left = left + \"px\";\n hints.style.top = top + \"px\";\n // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.\n var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);\n var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);\n (completion.options.container || document.body).appendChild(hints);\n var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;\n if (overlapY > 0) {\n var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);\n if (curTop - height > 0) { // Fits above cursor\n hints.style.top = (top = pos.top - height) + \"px\";\n below = false;\n } else if (height > winH) {\n hints.style.height = (winH - 5) + \"px\";\n hints.style.top = (top = pos.bottom - box.top) + \"px\";\n var cursor = cm.getCursor();\n if (data.from.ch != cursor.ch) {\n pos = cm.cursorCoords(cursor);\n hints.style.left = (left = pos.left) + \"px\";\n box = hints.getBoundingClientRect();\n }\n }\n }\n var overlapX = box.right - winW;\n if (overlapX > 0) {\n if (box.right - box.left > winW) {\n hints.style.width = (winW - 5) + \"px\";\n overlapX -= (box.right - box.left) - winW;\n }\n hints.style.left = (left = pos.left - overlapX) + \"px\";\n }\n\n cm.addKeyMap(this.keyMap = buildKeyMap(completion, {\n moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },\n setFocus: function(n) { widget.changeActive(n); },\n menuSize: function() { return widget.screenAmount(); },\n length: completions.length,\n close: function() { completion.close(); },\n pick: function() { widget.pick(); },\n data: data\n }));\n\n if (completion.options.closeOnUnfocus) {\n var closingOnBlur;\n cm.on(\"blur\", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });\n cm.on(\"focus\", this.onFocus = function() { clearTimeout(closingOnBlur); });\n }\n\n var startScroll = cm.getScrollInfo();\n cm.on(\"scroll\", this.onScroll = function() {\n var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();\n var newTop = top + startScroll.top - curScroll.top;\n var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);\n if (!below) point += hints.offsetHeight;\n if (point <= editor.top || point >= editor.bottom) return completion.close();\n hints.style.top = newTop + \"px\";\n hints.style.left = (left + startScroll.left - curScroll.left) + \"px\";\n });\n\n CodeMirror.on(hints, \"dblclick\", function(e) {\n var t = getHintElement(hints, e.target || e.srcElement);\n if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}\n });\n\n CodeMirror.on(hints, \"click\", function(e) {\n var t = getHintElement(hints, e.target || e.srcElement);\n if (t && t.hintId != null) {\n widget.changeActive(t.hintId);\n if (completion.options.completeOnSingleClick) widget.pick();\n }\n });\n\n CodeMirror.on(hints, \"mousedown\", function() {\n setTimeout(function(){cm.focus();}, 20);\n });\n\n CodeMirror.signal(data, \"select\", completions[0], hints.firstChild);\n return true;\n }\n\n Widget.prototype = {\n close: function() {\n if (this.completion.widget != this) return;\n this.completion.widget = null;\n this.hints.parentNode.removeChild(this.hints);\n this.completion.cm.removeKeyMap(this.keyMap);\n\n var cm = this.completion.cm;\n if (this.completion.options.closeOnUnfocus) {\n cm.off(\"blur\", this.onBlur);\n cm.off(\"focus\", this.onFocus);\n }\n cm.off(\"scroll\", this.onScroll);\n },\n\n pick: function() {\n this.completion.pick(this.data, this.selectedHint);\n },\n\n changeActive: function(i, avoidWrap) {\n if (i >= this.data.list.length)\n i = avoidWrap ? this.data.list.length - 1 : 0;\n else if (i < 0)\n i = avoidWrap ? 0 : this.data.list.length - 1;\n if (this.selectedHint == i) return;\n var node = this.hints.childNodes[this.selectedHint];\n node.className = node.className.replace(\" \" + ACTIVE_HINT_ELEMENT_CLASS, \"\");\n node = this.hints.childNodes[this.selectedHint = i];\n node.className += \" \" + ACTIVE_HINT_ELEMENT_CLASS;\n if (node.offsetTop < this.hints.scrollTop)\n this.hints.scrollTop = node.offsetTop - 3;\n else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)\n this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;\n CodeMirror.signal(this.data, \"select\", this.data.list[this.selectedHint], node);\n },\n\n screenAmount: function() {\n return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;\n }\n };\n\n CodeMirror.registerHelper(\"hint\", \"auto\", function(cm, options) {\n var helpers = cm.getHelpers(cm.getCursor(), \"hint\"), words;\n if (helpers.length) {\n for (var i = 0; i < helpers.length; i++) {\n var cur = helpers[i](cm, options);\n if (cur && cur.list.length) return cur;\n }\n } else if (words = cm.getHelper(cm.getCursor(), \"hintWords\")) {\n if (words) return CodeMirror.hint.fromList(cm, {words: words});\n } else if (CodeMirror.hint.anyword) {\n return CodeMirror.hint.anyword(cm, options);\n }\n });\n\n CodeMirror.registerHelper(\"hint\", \"fromList\", function(cm, options) {\n var cur = cm.getCursor(), token = cm.getTokenAt(cur);\n var found = [];\n for (var i = 0; i < options.words.length; i++) {\n var word = options.words[i];\n if (word.slice(0, token.string.length) == token.string)\n found.push(word);\n }\n\n if (found.length) return {\n list: found,\n from: CodeMirror.Pos(cur.line, token.start),\n to: CodeMirror.Pos(cur.line, token.end)\n };\n });\n\n CodeMirror.commands.autocomplete = CodeMirror.showHint;\n\n var defaultOptions = {\n hint: CodeMirror.hint.auto,\n completeSingle: true,\n alignWithWord: true,\n closeCharacters: /[\\s()\\[\\]{};:>,]/,\n closeOnUnfocus: true,\n completeOnSingleClick: false,\n container: null,\n customKeys: null,\n extraKeys: null\n };\n\n CodeMirror.defineOption(\"hintOptions\", null);\n});\n\n},{\"../../lib/codemirror\":15}],13:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nCodeMirror.runMode = function(string, modespec, callback, options) {\n var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);\n var ie = /MSIE \\d/.test(navigator.userAgent);\n var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);\n\n if (callback.nodeType == 1) {\n var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;\n var node = callback, col = 0;\n node.innerHTML = \"\";\n callback = function(text, style) {\n if (text == \"\\n\") {\n // Emitting LF or CRLF on IE8 or earlier results in an incorrect display.\n // Emitting a carriage return makes everything ok.\n node.appendChild(document.createTextNode(ie_lt9 ? '\\r' : text));\n col = 0;\n return;\n }\n var content = \"\";\n // replace tabs\n for (var pos = 0;;) {\n var idx = text.indexOf(\"\\t\", pos);\n if (idx == -1) {\n content += text.slice(pos);\n col += text.length - pos;\n break;\n } else {\n col += idx - pos;\n content += text.slice(pos, idx);\n var size = tabSize - col % tabSize;\n col += size;\n for (var i = 0; i < size; ++i) content += \" \";\n pos = idx + 1;\n }\n }\n\n if (style) {\n var sp = node.appendChild(document.createElement(\"span\"));\n sp.className = \"cm-\" + style.replace(/ +/g, \" cm-\");\n sp.appendChild(document.createTextNode(content));\n } else {\n node.appendChild(document.createTextNode(content));\n }\n };\n }\n\n var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);\n for (var i = 0, e = lines.length; i < e; ++i) {\n if (i) callback(\"\\n\");\n var stream = new CodeMirror.StringStream(lines[i]);\n if (!stream.string && mode.blankLine) mode.blankLine(state);\n while (!stream.eol()) {\n var style = mode.token(stream, state);\n callback(stream.current(), style, i, stream.start, state);\n stream.start = stream.pos;\n }\n }\n};\n\n});\n\n},{\"../../lib/codemirror\":15}],14:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n var Pos = CodeMirror.Pos;\n\n function SearchCursor(doc, query, pos, caseFold) {\n this.atOccurrence = false; this.doc = doc;\n if (caseFold == null && typeof query == \"string\") caseFold = false;\n\n pos = pos ? doc.clipPos(pos) : Pos(0, 0);\n this.pos = {from: pos, to: pos};\n\n // The matches method is filled in based on the type of query.\n // It takes a position and a direction, and returns an object\n // describing the next occurrence of the query, or null if no\n // more matches were found.\n if (typeof query != \"string\") { // Regexp match\n if (!query.global) query = new RegExp(query.source, query.ignoreCase ? \"ig\" : \"g\");\n this.matches = function(reverse, pos) {\n if (reverse) {\n query.lastIndex = 0;\n var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start;\n for (;;) {\n query.lastIndex = cutOff;\n var newMatch = query.exec(line);\n if (!newMatch) break;\n match = newMatch;\n start = match.index;\n cutOff = match.index + (match[0].length || 1);\n if (cutOff == line.length) break;\n }\n var matchLen = (match && match[0].length) || 0;\n if (!matchLen) {\n if (start == 0 && line.length == 0) {match = undefined;}\n else if (start != doc.getLine(pos.line).length) {\n matchLen++;\n }\n }\n } else {\n query.lastIndex = pos.ch;\n var line = doc.getLine(pos.line), match = query.exec(line);\n var matchLen = (match && match[0].length) || 0;\n var start = match && match.index;\n if (start + matchLen != line.length && !matchLen) matchLen = 1;\n }\n if (match && matchLen)\n return {from: Pos(pos.line, start),\n to: Pos(pos.line, start + matchLen),\n match: match};\n };\n } else { // String query\n var origQuery = query;\n if (caseFold) query = query.toLowerCase();\n var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};\n var target = query.split(\"\\n\");\n // Different methods for single-line and multi-line queries\n if (target.length == 1) {\n if (!query.length) {\n // Empty string would match anything and never progress, so\n // we define it to match nothing instead.\n this.matches = function() {};\n } else {\n this.matches = function(reverse, pos) {\n if (reverse) {\n var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig);\n var match = line.lastIndexOf(query);\n if (match > -1) {\n match = adjustPos(orig, line, match);\n return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};\n }\n } else {\n var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig);\n var match = line.indexOf(query);\n if (match > -1) {\n match = adjustPos(orig, line, match) + pos.ch;\n return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};\n }\n }\n };\n }\n } else {\n var origTarget = origQuery.split(\"\\n\");\n this.matches = function(reverse, pos) {\n var last = target.length - 1;\n if (reverse) {\n if (pos.line - (target.length - 1) < doc.firstLine()) return;\n if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return;\n var to = Pos(pos.line, origTarget[last].length);\n for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln)\n if (target[i] != fold(doc.getLine(ln))) return;\n var line = doc.getLine(ln), cut = line.length - origTarget[0].length;\n if (fold(line.slice(cut)) != target[0]) return;\n return {from: Pos(ln, cut), to: to};\n } else {\n if (pos.line + (target.length - 1) > doc.lastLine()) return;\n var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length;\n if (fold(line.slice(cut)) != target[0]) return;\n var from = Pos(pos.line, cut);\n for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)\n if (target[i] != fold(doc.getLine(ln))) return;\n if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return;\n return {from: from, to: Pos(ln, origTarget[last].length)};\n }\n };\n }\n }\n }\n\n SearchCursor.prototype = {\n findNext: function() {return this.find(false);},\n findPrevious: function() {return this.find(true);},\n\n find: function(reverse) {\n var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);\n function savePosAndFail(line) {\n var pos = Pos(line, 0);\n self.pos = {from: pos, to: pos};\n self.atOccurrence = false;\n return false;\n }\n\n for (;;) {\n if (this.pos = this.matches(reverse, pos)) {\n this.atOccurrence = true;\n return this.pos.match || true;\n }\n if (reverse) {\n if (!pos.line) return savePosAndFail(0);\n pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length);\n }\n else {\n var maxLine = this.doc.lineCount();\n if (pos.line == maxLine - 1) return savePosAndFail(maxLine);\n pos = Pos(pos.line + 1, 0);\n }\n }\n },\n\n from: function() {if (this.atOccurrence) return this.pos.from;},\n to: function() {if (this.atOccurrence) return this.pos.to;},\n\n replace: function(newText) {\n if (!this.atOccurrence) return;\n var lines = CodeMirror.splitLines(newText);\n this.doc.replaceRange(lines, this.pos.from, this.pos.to);\n this.pos.to = Pos(this.pos.from.line + lines.length - 1,\n lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));\n }\n };\n\n // Maps a position in a case-folded line back to a position in the original line\n // (compensating for codepoints increasing in number during folding)\n function adjustPos(orig, folded, pos) {\n if (orig.length == folded.length) return pos;\n for (var pos1 = Math.min(pos, orig.length);;) {\n var len1 = orig.slice(0, pos1).toLowerCase().length;\n if (len1 < pos) ++pos1;\n else if (len1 > pos) --pos1;\n else return pos1;\n }\n }\n\n CodeMirror.defineExtension(\"getSearchCursor\", function(query, pos, caseFold) {\n return new SearchCursor(this.doc, query, pos, caseFold);\n });\n CodeMirror.defineDocExtension(\"getSearchCursor\", function(query, pos, caseFold) {\n return new SearchCursor(this, query, pos, caseFold);\n });\n\n CodeMirror.defineExtension(\"selectMatches\", function(query, caseFold) {\n var ranges = [], next;\n var cur = this.getSearchCursor(query, this.getCursor(\"from\"), caseFold);\n while (next = cur.findNext()) {\n if (CodeMirror.cmpPos(cur.to(), this.getCursor(\"to\")) > 0) break;\n ranges.push({anchor: cur.from(), head: cur.to()});\n }\n if (ranges.length)\n this.setSelections(ranges, 0);\n });\n});\n\n},{\"../../lib/codemirror\":15}],15:[function(require,module,exports){\n// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n// This is CodeMirror (http://codemirror.net), a code editor\n// implemented in JavaScript on top of the browser's DOM.\n//\n// You can find some technical background for some of the code below\n// at http://marijnhaverbeke.nl/blog/#cm-internals .\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n module.exports = mod();\n else if (typeof define == \"function\" && define.amd) // AMD\n return define([], mod);\n else // Plain browser env\n this.CodeMirror = mod();\n})(function() {\n \"use strict\";\n\n // BROWSER SNIFFING\n\n // Kludges for bugs and behavior differences that can't be feature\n // detected are enabled based on userAgent etc sniffing.\n\n var gecko = /gecko\\/\\d/i.test(navigator.userAgent);\n // ie_uptoN means Internet Explorer version N or lower\n var ie_upto10 = /MSIE \\d/.test(navigator.userAgent);\n var ie_11up = /Trident\\/(?:[7-9]|\\d{2,})\\..*rv:(\\d+)/.exec(navigator.userAgent);\n var ie = ie_upto10 || ie_11up;\n var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);\n var webkit = /WebKit\\//.test(navigator.userAgent);\n var qtwebkit = webkit && /Qt\\/\\d+\\.\\d+/.test(navigator.userAgent);\n var chrome = /Chrome\\//.test(navigator.userAgent);\n var presto = /Opera\\//.test(navigator.userAgent);\n var safari = /Apple Computer/.test(navigator.vendor);\n var khtml = /KHTML\\//.test(navigator.userAgent);\n var mac_geMountainLion = /Mac OS X 1\\d\\D([8-9]|\\d\\d)\\D/.test(navigator.userAgent);\n var phantom = /PhantomJS/.test(navigator.userAgent);\n\n var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\\/\\w+/.test(navigator.userAgent);\n // This is woefully incomplete. Suggestions for alternative methods welcome.\n var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);\n var mac = ios || /Mac/.test(navigator.platform);\n var windows = /win/i.test(navigator.platform);\n\n var presto_version = presto && navigator.userAgent.match(/Version\\/(\\d*\\.\\d*)/);\n if (presto_version) presto_version = Number(presto_version[1]);\n if (presto_version && presto_version >= 15) { presto = false; webkit = true; }\n // Some browsers use the wrong event properties to signal cmd/ctrl on OS X\n var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));\n var captureRightClick = gecko || (ie && ie_version >= 9);\n\n // Optimize some code when these features are not used.\n var sawReadOnlySpans = false, sawCollapsedSpans = false;\n\n // EDITOR CONSTRUCTOR\n\n // A CodeMirror instance represents an editor. This is the object\n // that user code is usually dealing with.\n\n function CodeMirror(place, options) {\n if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);\n\n this.options = options = options ? copyObj(options) : {};\n // Determine effective options based on given values and defaults.\n copyObj(defaults, options, false);\n setGuttersForLineNumbers(options);\n\n var doc = options.value;\n if (typeof doc == \"string\") doc = new Doc(doc, options.mode);\n this.doc = doc;\n\n var display = this.display = new Display(place, doc);\n display.wrapper.CodeMirror = this;\n updateGutters(this);\n themeChanged(this);\n if (options.lineWrapping)\n this.display.wrapper.className += \" CodeMirror-wrap\";\n if (options.autofocus && !mobile) focusInput(this);\n initScrollbars(this);\n\n this.state = {\n keyMaps: [], // stores maps added by addKeyMap\n overlays: [], // highlighting overlays, as added by addOverlay\n modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info\n overwrite: false, focused: false,\n suppressEdits: false, // used to disable editing during key handlers when in readOnly mode\n pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput\n draggingText: false,\n highlight: new Delayed(), // stores highlight worker timeout\n keySeq: null // Unfinished key sequence\n };\n\n // Override magic textarea content restore that IE sometimes does\n // on our hidden textarea on reload\n if (ie && ie_version < 11) setTimeout(bind(resetInput, this, true), 20);\n\n registerEventHandlers(this);\n ensureGlobalHandlers();\n\n startOperation(this);\n this.curOp.forceUpdate = true;\n attachDoc(this, doc);\n\n if ((options.autofocus && !mobile) || activeElt() == display.input)\n setTimeout(bind(onFocus, this), 20);\n else\n onBlur(this);\n\n for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))\n optionHandlers[opt](this, options[opt], Init);\n maybeUpdateLineNumberWidth(this);\n for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);\n endOperation(this);\n // Suppress optimizelegibility in Webkit, since it breaks text\n // measuring on line wrapping boundaries.\n if (webkit && options.lineWrapping &&\n getComputedStyle(display.lineDiv).textRendering == \"optimizelegibility\")\n display.lineDiv.style.textRendering = \"auto\";\n }\n\n // DISPLAY CONSTRUCTOR\n\n // The display handles the DOM integration, both for input reading\n // and content drawing. It holds references to DOM nodes and\n // display-related state.\n\n function Display(place, doc) {\n var d = this;\n\n // The semihidden textarea that is focused when the editor is\n // focused, and receives input.\n var input = d.input = elt(\"textarea\", null, null, \"position: absolute; padding: 0; width: 1px; height: 1em; outline: none\");\n // The textarea is kept positioned near the cursor to prevent the\n // fact that it'll be scrolled into view on input from scrolling\n // our fake cursor out of view. On webkit, when wrap=off, paste is\n // very slow. So make the area wide instead.\n if (webkit) input.style.width = \"1000px\";\n else input.setAttribute(\"wrap\", \"off\");\n // If border: 0; -- iOS fails to open keyboard (issue #1287)\n if (ios) input.style.border = \"1px solid black\";\n input.setAttribute(\"autocorrect\", \"off\"); input.setAttribute(\"autocapitalize\", \"off\"); input.setAttribute(\"spellcheck\", \"false\");\n\n // Wraps and hides input textarea\n d.inputDiv = elt(\"div\", [input], null, \"overflow: hidden; position: relative; width: 3px; height: 0px;\");\n // Covers bottom-right square when both scrollbars are present.\n d.scrollbarFiller = elt(\"div\", null, \"CodeMirror-scrollbar-filler\");\n d.scrollbarFiller.setAttribute(\"not-content\", \"true\");\n // Covers bottom of gutter when coverGutterNextToScrollbar is on\n // and h scrollbar is present.\n d.gutterFiller = elt(\"div\", null, \"CodeMirror-gutter-filler\");\n d.gutterFiller.setAttribute(\"not-content\", \"true\");\n // Will contain the actual code, positioned to cover the viewport.\n d.lineDiv = elt(\"div\", null, \"CodeMirror-code\");\n // Elements are added to these to represent selection and cursors.\n d.selectionDiv = elt(\"div\", null, null, \"position: relative; z-index: 1\");\n d.cursorDiv = elt(\"div\", null, \"CodeMirror-cursors\");\n // A visibility: hidden element used to find the size of things.\n d.measure = elt(\"div\", null, \"CodeMirror-measure\");\n // When lines outside of the viewport are measured, they are drawn in this.\n d.lineMeasure = elt(\"div\", null, \"CodeMirror-measure\");\n // Wraps everything that needs to exist inside the vertically-padded coordinate system\n d.lineSpace = elt(\"div\", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],\n null, \"position: relative; outline: none\");\n // Moved around its parent to cover visible view.\n d.mover = elt(\"div\", [elt(\"div\", [d.lineSpace], \"CodeMirror-lines\")], null, \"position: relative\");\n // Set to the height of the document, allowing scrolling.\n d.sizer = elt(\"div\", [d.mover], \"CodeMirror-sizer\");\n d.sizerWidth = null;\n // Behavior of elts with overflow: auto and padding is\n // inconsistent across browsers. This is used to ensure the\n // scrollable area is big enough.\n d.heightForcer = elt(\"div\", null, null, \"position: absolute; height: \" + scrollerGap + \"px; width: 1px;\");\n // Will contain the gutters, if any.\n d.gutters = elt(\"div\", null, \"CodeMirror-gutters\");\n d.lineGutter = null;\n // Actual scrollable element.\n d.scroller = elt(\"div\", [d.sizer, d.heightForcer, d.gutters], \"CodeMirror-scroll\");\n d.scroller.setAttribute(\"tabIndex\", \"-1\");\n // The element in which the editor lives.\n d.wrapper = elt(\"div\", [d.inputDiv, d.scrollbarFiller, d.gutterFiller, d.scroller], \"CodeMirror\");\n\n // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)\n if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }\n // Needed to hide big blue blinking cursor on Mobile Safari\n if (ios) input.style.width = \"0px\";\n if (!webkit) d.scroller.draggable = true;\n // Needed to handle Tab key in KHTML\n if (khtml) { d.inputDiv.style.height = \"1px\"; d.inputDiv.style.position = \"absolute\"; }\n\n if (place) {\n if (place.appendChild) place.appendChild(d.wrapper);\n else place(d.wrapper);\n }\n\n // Current rendered range (may be bigger than the view window).\n d.viewFrom = d.viewTo = doc.first;\n d.reportedViewFrom = d.reportedViewTo = doc.first;\n // Information about the rendered lines.\n d.view = [];\n d.renderedView = null;\n // Holds info about a single rendered line when it was rendered\n // for measurement, while not in view.\n d.externalMeasured = null;\n // Empty space (in pixels) above the view\n d.viewOffset = 0;\n d.lastWrapHeight = d.lastWrapWidth = 0;\n d.updateLineNumbers = null;\n\n d.nativeBarWidth = d.barHeight = d.barWidth = 0;\n d.scrollbarsClipped = false;\n\n // Used to only resize the line number gutter when necessary (when\n // the amount of lines crosses a boundary that makes its width change)\n d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;\n // See readInput and resetInput\n d.prevInput = \"\";\n // Set to true when a non-horizontal-scrolling line widget is\n // added. As an optimization, line widget aligning is skipped when\n // this is false.\n d.alignWidgets = false;\n // Flag that indicates whether we expect input to appear real soon\n // now (after some event like 'keypress' or 'input') and are\n // polling intensively.\n d.pollingFast = false;\n // Self-resetting timeout for the poller\n d.poll = new Delayed();\n\n d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;\n\n // Tracks when resetInput has punted to just putting a short\n // string into the textarea instead of the full selection.\n d.inaccurateSelection = false;\n\n // Tracks the maximum line length so that the horizontal scrollbar\n // can be kept static when scrolling.\n d.maxLine = null;\n d.maxLineLength = 0;\n d.maxLineChanged = false;\n\n // Used for measuring wheel scrolling granularity\n d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;\n\n // True when shift is held down.\n d.shift = false;\n\n // Used to track whether anything happened since the context menu\n // was opened.\n d.selForContextMenu = null;\n }\n\n // STATE UPDATES\n\n // Used to get the editor into a consistent state again when options change.\n\n function loadMode(cm) {\n cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);\n resetModeState(cm);\n }\n\n function resetModeState(cm) {\n cm.doc.iter(function(line) {\n if (line.stateAfter) line.stateAfter = null;\n if (line.styles) line.styles = null;\n });\n cm.doc.frontier = cm.doc.first;\n startWorker(cm, 100);\n cm.state.modeGen++;\n if (cm.curOp) regChange(cm);\n }\n\n function wrappingChanged(cm) {\n if (cm.options.lineWrapping) {\n addClass(cm.display.wrapper, \"CodeMirror-wrap\");\n cm.display.sizer.style.minWidth = \"\";\n cm.display.sizerWidth = null;\n } else {\n rmClass(cm.display.wrapper, \"CodeMirror-wrap\");\n findMaxLine(cm);\n }\n estimateLineHeights(cm);\n regChange(cm);\n clearCaches(cm);\n setTimeout(function(){updateScrollbars(cm);}, 100);\n }\n\n // Returns a function that estimates the height of a line, to use as\n // first approximation until the line becomes visible (and is thus\n // properly measurable).\n function estimateHeight(cm) {\n var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;\n var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);\n return function(line) {\n if (lineIsHidden(cm.doc, line)) return 0;\n\n var widgetsHeight = 0;\n if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {\n if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;\n }\n\n if (wrapping)\n return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;\n else\n return widgetsHeight + th;\n };\n }\n\n function estimateLineHeights(cm) {\n var doc = cm.doc, est = estimateHeight(cm);\n doc.iter(function(line) {\n var estHeight = est(line);\n if (estHeight != line.height) updateLineHeight(line, estHeight);\n });\n }\n\n function themeChanged(cm) {\n cm.display.wrapper.className = cm.display.wrapper.className.replace(/\\s*cm-s-\\S+/g, \"\") +\n cm.options.theme.replace(/(^|\\s)\\s*/g, \" cm-s-\");\n clearCaches(cm);\n }\n\n function guttersChanged(cm) {\n updateGutters(cm);\n regChange(cm);\n setTimeout(function(){alignHorizontally(cm);}, 20);\n }\n\n // Rebuild the gutter elements, ensure the margin to the left of the\n // code matches their width.\n function updateGutters(cm) {\n var gutters = cm.display.gutters, specs = cm.options.gutters;\n removeChildren(gutters);\n for (var i = 0; i < specs.length; ++i) {\n var gutterClass = specs[i];\n var gElt = gutters.appendChild(elt(\"div\", null, \"CodeMirror-gutter \" + gutterClass));\n if (gutterClass == \"CodeMirror-linenumbers\") {\n cm.display.lineGutter = gElt;\n gElt.style.width = (cm.display.lineNumWidth || 1) + \"px\";\n }\n }\n gutters.style.display = i ? \"\" : \"none\";\n updateGutterSpace(cm);\n }\n\n function updateGutterSpace(cm) {\n var width = cm.display.gutters.offsetWidth;\n cm.display.sizer.style.marginLeft = width + \"px\";\n }\n\n // Compute the character length of a line, taking into account\n // collapsed ranges (see markText) that might hide parts, and join\n // other lines onto it.\n function lineLength(line) {\n if (line.height == 0) return 0;\n var len = line.text.length, merged, cur = line;\n while (merged = collapsedSpanAtStart(cur)) {\n var found = merged.find(0, true);\n cur = found.from.line;\n len += found.from.ch - found.to.ch;\n }\n cur = line;\n while (merged = collapsedSpanAtEnd(cur)) {\n var found = merged.find(0, true);\n len -= cur.text.length - found.from.ch;\n cur = found.to.line;\n len += cur.text.length - found.to.ch;\n }\n return len;\n }\n\n // Find the longest line in the document.\n function findMaxLine(cm) {\n var d = cm.display, doc = cm.doc;\n d.maxLine = getLine(doc, doc.first);\n d.maxLineLength = lineLength(d.maxLine);\n d.maxLineChanged = true;\n doc.iter(function(line) {\n var len = lineLength(line);\n if (len > d.maxLineLength) {\n d.maxLineLength = len;\n d.maxLine = line;\n }\n });\n }\n\n // Make sure the gutters options contains the element\n // \"CodeMirror-linenumbers\" when the lineNumbers option is true.\n function setGuttersForLineNumbers(options) {\n var found = indexOf(options.gutters, \"CodeMirror-linenumbers\");\n if (found == -1 && options.lineNumbers) {\n options.gutters = options.gutters.concat([\"CodeMirror-linenumbers\"]);\n } else if (found > -1 && !options.lineNumbers) {\n options.gutters = options.gutters.slice(0);\n options.gutters.splice(found, 1);\n }\n }\n\n // SCROLLBARS\n\n // Prepare DOM reads needed to update the scrollbars. Done in one\n // shot to minimize update/measure roundtrips.\n function measureForScrollbars(cm) {\n var d = cm.display, gutterW = d.gutters.offsetWidth;\n var docH = Math.round(cm.doc.height + paddingVert(cm.display));\n return {\n clientHeight: d.scroller.clientHeight,\n viewHeight: d.wrapper.clientHeight,\n scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,\n viewWidth: d.wrapper.clientWidth,\n barLeft: cm.options.fixedGutter ? gutterW : 0,\n docHeight: docH,\n scrollHeight: docH + scrollGap(cm) + d.barHeight,\n nativeBarWidth: d.nativeBarWidth,\n gutterWidth: gutterW\n };\n }\n\n function NativeScrollbars(place, scroll, cm) {\n this.cm = cm;\n var vert = this.vert = elt(\"div\", [elt(\"div\", null, null, \"min-width: 1px\")], \"CodeMirror-vscrollbar\");\n var horiz = this.horiz = elt(\"div\", [elt(\"div\", null, null, \"height: 100%; min-height: 1px\")], \"CodeMirror-hscrollbar\");\n place(vert); place(horiz);\n\n on(vert, \"scroll\", function() {\n if (vert.clientHeight) scroll(vert.scrollTop, \"vertical\");\n });\n on(horiz, \"scroll\", function() {\n if (horiz.clientWidth) scroll(horiz.scrollLeft, \"horizontal\");\n });\n\n this.checkedOverlay = false;\n // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).\n if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = \"18px\";\n }\n\n NativeScrollbars.prototype = copyObj({\n update: function(measure) {\n var needsH = measure.scrollWidth > measure.clientWidth + 1;\n var needsV = measure.scrollHeight > measure.clientHeight + 1;\n var sWidth = measure.nativeBarWidth;\n\n if (needsV) {\n this.vert.style.display = \"block\";\n this.vert.style.bottom = needsH ? sWidth + \"px\" : \"0\";\n var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);\n // A bug in IE8 can cause this value to be negative, so guard it.\n this.vert.firstChild.style.height =\n Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + \"px\";\n } else {\n this.vert.style.display = \"\";\n this.vert.firstChild.style.height = \"0\";\n }\n\n if (needsH) {\n this.horiz.style.display = \"block\";\n this.horiz.style.right = needsV ? sWidth + \"px\" : \"0\";\n this.horiz.style.left = measure.barLeft + \"px\";\n var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);\n this.horiz.firstChild.style.width =\n (measure.scrollWidth - measure.clientWidth + totalWidth) + \"px\";\n } else {\n this.horiz.style.display = \"\";\n this.horiz.firstChild.style.width = \"0\";\n }\n\n if (!this.checkedOverlay && measure.clientHeight > 0) {\n if (sWidth == 0) this.overlayHack();\n this.checkedOverlay = true;\n }\n\n return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};\n },\n setScrollLeft: function(pos) {\n if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;\n },\n setScrollTop: function(pos) {\n if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;\n },\n overlayHack: function() {\n var w = mac && !mac_geMountainLion ? \"12px\" : \"18px\";\n this.horiz.style.minHeight = this.vert.style.minWidth = w;\n var self = this;\n var barMouseDown = function(e) {\n if (e_target(e) != self.vert && e_target(e) != self.horiz)\n operation(self.cm, onMouseDown)(e);\n };\n on(this.vert, \"mousedown\", barMouseDown);\n on(this.horiz, \"mousedown\", barMouseDown);\n },\n clear: function() {\n var parent = this.horiz.parentNode;\n parent.removeChild(this.horiz);\n parent.removeChild(this.vert);\n }\n }, NativeScrollbars.prototype);\n\n function NullScrollbars() {}\n\n NullScrollbars.prototype = copyObj({\n update: function() { return {bottom: 0, right: 0}; },\n setScrollLeft: function() {},\n setScrollTop: function() {},\n clear: function() {}\n }, NullScrollbars.prototype);\n\n CodeMirror.scrollbarModel = {\"native\": NativeScrollbars, \"null\": NullScrollbars};\n\n function initScrollbars(cm) {\n if (cm.display.scrollbars) {\n cm.display.scrollbars.clear();\n if (cm.display.scrollbars.addClass)\n rmClass(cm.display.wrapper, cm.display.scrollbars.addClass);\n }\n\n cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) {\n cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);\n on(node, \"mousedown\", function() {\n if (cm.state.focused) setTimeout(bind(focusInput, cm), 0);\n });\n node.setAttribute(\"not-content\", \"true\");\n }, function(pos, axis) {\n if (axis == \"horizontal\") setScrollLeft(cm, pos);\n else setScrollTop(cm, pos);\n }, cm);\n if (cm.display.scrollbars.addClass)\n addClass(cm.display.wrapper, cm.display.scrollbars.addClass);\n }\n\n function updateScrollbars(cm, measure) {\n if (!measure) measure = measureForScrollbars(cm);\n var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;\n updateScrollbarsInner(cm, measure);\n for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {\n if (startWidth != cm.display.barWidth && cm.options.lineWrapping)\n updateHeightsInViewport(cm);\n updateScrollbarsInner(cm, measureForScrollbars(cm));\n startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;\n }\n }\n\n // Re-synchronize the fake scrollbars with the actual size of the\n // content.\n function updateScrollbarsInner(cm, measure) {\n var d = cm.display;\n var sizes = d.scrollbars.update(measure);\n\n d.sizer.style.paddingRight = (d.barWidth = sizes.right) + \"px\";\n d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + \"px\";\n\n if (sizes.right && sizes.bottom) {\n d.scrollbarFiller.style.display = \"block\";\n d.scrollbarFiller.style.height = sizes.bottom + \"px\";\n d.scrollbarFiller.style.width = sizes.right + \"px\";\n } else d.scrollbarFiller.style.display = \"\";\n if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {\n d.gutterFiller.style.display = \"block\";\n d.gutterFiller.style.height = sizes.bottom + \"px\";\n d.gutterFiller.style.width = measure.gutterWidth + \"px\";\n } else d.gutterFiller.style.display = \"\";\n }\n\n // Compute the lines that are visible in a given viewport (defaults\n // the the current scroll position). viewport may contain top,\n // height, and ensure (see op.scrollToPos) properties.\n function visibleLines(display, doc, viewport) {\n var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;\n top = Math.floor(top - paddingTop(display));\n var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;\n\n var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);\n // Ensure is a {from: {line, ch}, to: {line, ch}} object, and\n // forces those lines into the viewport (if possible).\n if (viewport && viewport.ensure) {\n var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;\n if (ensureFrom < from) {\n from = ensureFrom;\n to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);\n } else if (Math.min(ensureTo, doc.lastLine()) >= to) {\n from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);\n to = ensureTo;\n }\n }\n return {from: from, to: Math.max(to, from + 1)};\n }\n\n // LINE NUMBERS\n\n // Re-align line numbers and gutter marks to compensate for\n // horizontal scrolling.\n function alignHorizontally(cm) {\n var display = cm.display, view = display.view;\n if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;\n var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;\n var gutterW = display.gutters.offsetWidth, left = comp + \"px\";\n for (var i = 0; i < view.length; i++) if (!view[i].hidden) {\n if (cm.options.fixedGutter && view[i].gutter)\n view[i].gutter.style.left = left;\n var align = view[i].alignable;\n if (align) for (var j = 0; j < align.length; j++)\n align[j].style.left = left;\n }\n if (cm.options.fixedGutter)\n display.gutters.style.left = (comp + gutterW) + \"px\";\n }\n\n // Used to ensure that the line number gutter is still the right\n // size for the current document size. Returns true when an update\n // is needed.\n function maybeUpdateLineNumberWidth(cm) {\n if (!cm.options.lineNumbers) return false;\n var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;\n if (last.length != display.lineNumChars) {\n var test = display.measure.appendChild(elt(\"div\", [elt(\"div\", last)],\n \"CodeMirror-linenumber CodeMirror-gutter-elt\"));\n var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;\n display.lineGutter.style.width = \"\";\n display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);\n display.lineNumWidth = display.lineNumInnerWidth + padding;\n display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;\n display.lineGutter.style.width = display.lineNumWidth + \"px\";\n updateGutterSpace(cm);\n return true;\n }\n return false;\n }\n\n function lineNumberFor(options, i) {\n return String(options.lineNumberFormatter(i + options.firstLineNumber));\n }\n\n // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,\n // but using getBoundingClientRect to get a sub-pixel-accurate\n // result.\n function compensateForHScroll(display) {\n return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;\n }\n\n // DISPLAY DRAWING\n\n function DisplayUpdate(cm, viewport, force) {\n var display = cm.display;\n\n this.viewport = viewport;\n // Store some values that we'll need later (but don't want to force a relayout for)\n this.visible = visibleLines(display, cm.doc, viewport);\n this.editorIsHidden = !display.wrapper.offsetWidth;\n this.wrapperHeight = display.wrapper.clientHeight;\n this.wrapperWidth = display.wrapper.clientWidth;\n this.oldDisplayWidth = displayWidth(cm);\n this.force = force;\n this.dims = getDimensions(cm);\n }\n\n function maybeClipScrollbars(cm) {\n var display = cm.display;\n if (!display.scrollbarsClipped && display.scroller.offsetWidth) {\n display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;\n display.heightForcer.style.height = scrollGap(cm) + \"px\";\n display.sizer.style.marginBottom = -display.nativeBarWidth + \"px\";\n display.sizer.style.borderRightWidth = scrollGap(cm) + \"px\";\n display.scrollbarsClipped = true;\n }\n }\n\n // Does the actual updating of the line display. Bails out\n // (returning false) when there is nothing to be done and forced is\n // false.\n function updateDisplayIfNeeded(cm, update) {\n var display = cm.display, doc = cm.doc;\n\n if (update.editorIsHidden) {\n resetView(cm);\n return false;\n }\n\n // Bail out if the visible area is already rendered and nothing changed.\n if (!update.force &&\n update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&\n (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&\n display.renderedView == display.view && countDirtyView(cm) == 0)\n return false;\n\n if (maybeUpdateLineNumberWidth(cm)) {\n resetView(cm);\n update.dims = getDimensions(cm);\n }\n\n // Compute a suitable new viewport (from & to)\n var end = doc.first + doc.size;\n var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);\n var to = Math.min(end, update.visible.to + cm.options.viewportMargin);\n if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);\n if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);\n if (sawCollapsedSpans) {\n from = visualLineNo(cm.doc, from);\n to = visualLineEndNo(cm.doc, to);\n }\n\n var different = from != display.viewFrom || to != display.viewTo ||\n display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;\n adjustView(cm, from, to);\n\n display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));\n // Position the mover div to align with the current scroll position\n cm.display.mover.style.top = display.viewOffset + \"px\";\n\n var toUpdate = countDirtyView(cm);\n if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&\n (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))\n return false;\n\n // For big changes, we hide the enclosing element during the\n // update, since that speeds up the operations on most browsers.\n var focused = activeElt();\n if (toUpdate > 4) display.lineDiv.style.display = \"none\";\n patchDisplay(cm, display.updateLineNumbers, update.dims);\n if (toUpdate > 4) display.lineDiv.style.display = \"\";\n display.renderedView = display.view;\n // There might have been a widget with a focused element that got\n // hidden or updated, if so re-focus it.\n if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();\n\n // Prevent selection and cursors from interfering with the scroll\n // width and height.\n removeChildren(display.cursorDiv);\n removeChildren(display.selectionDiv);\n display.gutters.style.height = 0;\n\n if (different) {\n display.lastWrapHeight = update.wrapperHeight;\n display.lastWrapWidth = update.wrapperWidth;\n startWorker(cm, 400);\n }\n\n display.updateLineNumbers = null;\n\n return true;\n }\n\n function postUpdateDisplay(cm, update) {\n var force = update.force, viewport = update.viewport;\n for (var first = true;; first = false) {\n if (first && cm.options.lineWrapping && update.oldDisplayWidth != displayWidth(cm)) {\n force = true;\n } else {\n force = false;\n // Clip forced viewport to actual scrollable area.\n if (viewport && viewport.top != null)\n viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};\n // Updated line heights might result in the drawn area not\n // actually covering the viewport. Keep looping until it does.\n update.visible = visibleLines(cm.display, cm.doc, viewport);\n if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)\n break;\n }\n if (!updateDisplayIfNeeded(cm, update)) break;\n updateHeightsInViewport(cm);\n var barMeasure = measureForScrollbars(cm);\n updateSelection(cm);\n setDocumentHeight(cm, barMeasure);\n updateScrollbars(cm, barMeasure);\n }\n\n signalLater(cm, \"update\", cm);\n if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {\n signalLater(cm, \"viewportChange\", cm, cm.display.viewFrom, cm.display.viewTo);\n cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;\n }\n }\n\n function updateDisplaySimple(cm, viewport) {\n var update = new DisplayUpdate(cm, viewport);\n if (updateDisplayIfNeeded(cm, update)) {\n updateHeightsInViewport(cm);\n postUpdateDisplay(cm, update);\n var barMeasure = measureForScrollbars(cm);\n updateSelection(cm);\n setDocumentHeight(cm, barMeasure);\n updateScrollbars(cm, barMeasure);\n }\n }\n\n function setDocumentHeight(cm, measure) {\n cm.display.sizer.style.minHeight = measure.docHeight + \"px\";\n var total = measure.docHeight + cm.display.barHeight;\n cm.display.heightForcer.style.top = total + \"px\";\n cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + \"px\";\n }\n\n // Read the actual heights of the rendered lines, and update their\n // stored heights to match.\n function updateHeightsInViewport(cm) {\n var display = cm.display;\n var prevBottom = display.lineDiv.offsetTop;\n for (var i = 0; i < display.view.length; i++) {\n var cur = display.view[i], height;\n if (cur.hidden) continue;\n if (ie && ie_version < 8) {\n var bot = cur.node.offsetTop + cur.node.offsetHeight;\n height = bot - prevBottom;\n prevBottom = bot;\n } else {\n var box = cur.node.getBoundingClientRect();\n height = box.bottom - box.top;\n }\n var diff = cur.line.height - height;\n if (height < 2) height = textHeight(display);\n if (diff > .001 || diff < -.001) {\n updateLineHeight(cur.line, height);\n updateWidgetHeight(cur.line);\n if (cur.rest) for (var j = 0; j < cur.rest.length; j++)\n updateWidgetHeight(cur.rest[j]);\n }\n }\n }\n\n // Read and store the height of line widgets associated with the\n // given line.\n function updateWidgetHeight(line) {\n if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)\n line.widgets[i].height = line.widgets[i].node.offsetHeight;\n }\n\n // Do a bulk-read of the DOM positions and sizes needed to draw the\n // view, so that we don't interleave reading and writing to the DOM.\n function getDimensions(cm) {\n var d = cm.display, left = {}, width = {};\n var gutterLeft = d.gutters.clientLeft;\n for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {\n left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;\n width[cm.options.gutters[i]] = n.clientWidth;\n }\n return {fixedPos: compensateForHScroll(d),\n gutterTotalWidth: d.gutters.offsetWidth,\n gutterLeft: left,\n gutterWidth: width,\n wrapperWidth: d.wrapper.clientWidth};\n }\n\n // Sync the actual display DOM structure with display.view, removing\n // nodes for lines that are no longer in view, and creating the ones\n // that are not there yet, and updating the ones that are out of\n // date.\n function patchDisplay(cm, updateNumbersFrom, dims) {\n var display = cm.display, lineNumbers = cm.options.lineNumbers;\n var container = display.lineDiv, cur = container.firstChild;\n\n function rm(node) {\n var next = node.nextSibling;\n // Works around a throw-scroll bug in OS X Webkit\n if (webkit && mac && cm.display.currentWheelTarget == node)\n node.style.display = \"none\";\n else\n node.parentNode.removeChild(node);\n return next;\n }\n\n var view = display.view, lineN = display.viewFrom;\n // Loop over the elements in the view, syncing cur (the DOM nodes\n // in display.lineDiv) with the view as we go.\n for (var i = 0; i < view.length; i++) {\n var lineView = view[i];\n if (lineView.hidden) {\n } else if (!lineView.node) { // Not drawn yet\n var node = buildLineElement(cm, lineView, lineN, dims);\n container.insertBefore(node, cur);\n } else { // Already drawn\n while (cur != lineView.node) cur = rm(cur);\n var updateNumber = lineNumbers && updateNumbersFrom != null &&\n updateNumbersFrom <= lineN && lineView.lineNumber;\n if (lineView.changes) {\n if (indexOf(lineView.changes, \"gutter\") > -1) updateNumber = false;\n updateLineForChanges(cm, lineView, lineN, dims);\n }\n if (updateNumber) {\n removeChildren(lineView.lineNumber);\n lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));\n }\n cur = lineView.node.nextSibling;\n }\n lineN += lineView.size;\n }\n while (cur) cur = rm(cur);\n }\n\n // When an aspect of a line changes, a string is added to\n // lineView.changes. This updates the relevant part of the line's\n // DOM structure.\n function updateLineForChanges(cm, lineView, lineN, dims) {\n for (var j = 0; j < lineView.changes.length; j++) {\n var type = lineView.changes[j];\n if (type == \"text\") updateLineText(cm, lineView);\n else if (type == \"gutter\") updateLineGutter(cm, lineView, lineN, dims);\n else if (type == \"class\") updateLineClasses(lineView);\n else if (type == \"widget\") updateLineWidgets(lineView, dims);\n }\n lineView.changes = null;\n }\n\n // Lines with gutter elements, widgets or a background class need to\n // be wrapped, and have the extra elements added to the wrapper div\n function ensureLineWrapped(lineView) {\n if (lineView.node == lineView.text) {\n lineView.node = elt(\"div\", null, null, \"position: relative\");\n if (lineView.text.parentNode)\n lineView.text.parentNode.replaceChild(lineView.node, lineView.text);\n lineView.node.appendChild(lineView.text);\n if (ie && ie_version < 8) lineView.node.style.zIndex = 2;\n }\n return lineView.node;\n }\n\n function updateLineBackground(lineView) {\n var cls = lineView.bgClass ? lineView.bgClass + \" \" + (lineView.line.bgClass || \"\") : lineView.line.bgClass;\n if (cls) cls += \" CodeMirror-linebackground\";\n if (lineView.background) {\n if (cls) lineView.background.className = cls;\n else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }\n } else if (cls) {\n var wrap = ensureLineWrapped(lineView);\n lineView.background = wrap.insertBefore(elt(\"div\", null, cls), wrap.firstChild);\n }\n }\n\n // Wrapper around buildLineContent which will reuse the structure\n // in display.externalMeasured when possible.\n function getLineContent(cm, lineView) {\n var ext = cm.display.externalMeasured;\n if (ext && ext.line == lineView.line) {\n cm.display.externalMeasured = null;\n lineView.measure = ext.measure;\n return ext.built;\n }\n return buildLineContent(cm, lineView);\n }\n\n // Redraw the line's text. Interacts with the background and text\n // classes because the mode may output tokens that influence these\n // classes.\n function updateLineText(cm, lineView) {\n var cls = lineView.text.className;\n var built = getLineContent(cm, lineView);\n if (lineView.text == lineView.node) lineView.node = built.pre;\n lineView.text.parentNode.replaceChild(built.pre, lineView.text);\n lineView.text = built.pre;\n if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {\n lineView.bgClass = built.bgClass;\n lineView.textClass = built.textClass;\n updateLineClasses(lineView);\n } else if (cls) {\n lineView.text.className = cls;\n }\n }\n\n function updateLineClasses(lineView) {\n updateLineBackground(lineView);\n if (lineView.line.wrapClass)\n ensureLineWrapped(lineView).className = lineView.line.wrapClass;\n else if (lineView.node != lineView.text)\n lineView.node.className = \"\";\n var textClass = lineView.textClass ? lineView.textClass + \" \" + (lineView.line.textClass || \"\") : lineView.line.textClass;\n lineView.text.className = textClass || \"\";\n }\n\n function updateLineGutter(cm, lineView, lineN, dims) {\n if (lineView.gutter) {\n lineView.node.removeChild(lineView.gutter);\n lineView.gutter = null;\n }\n var markers = lineView.line.gutterMarkers;\n if (cm.options.lineNumbers || markers) {\n var wrap = ensureLineWrapped(lineView);\n var gutterWrap = lineView.gutter =\n wrap.insertBefore(elt(\"div\", null, \"CodeMirror-gutter-wrapper\", \"left: \" +\n (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +\n \"px; width: \" + dims.gutterTotalWidth + \"px\"),\n lineView.text);\n if (lineView.line.gutterClass)\n gutterWrap.className += \" \" + lineView.line.gutterClass;\n if (cm.options.lineNumbers && (!markers || !markers[\"CodeMirror-linenumbers\"]))\n lineView.lineNumber = gutterWrap.appendChild(\n elt(\"div\", lineNumberFor(cm.options, lineN),\n \"CodeMirror-linenumber CodeMirror-gutter-elt\",\n \"left: \" + dims.gutterLeft[\"CodeMirror-linenumbers\"] + \"px; width: \"\n + cm.display.lineNumInnerWidth + \"px\"));\n if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {\n var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];\n if (found)\n gutterWrap.appendChild(elt(\"div\", [found], \"CodeMirror-gutter-elt\", \"left: \" +\n dims.gutterLeft[id] + \"px; width: \" + dims.gutterWidth[id] + \"px\"));\n }\n }\n }\n\n function updateLineWidgets(lineView, dims) {\n if (lineView.alignable) lineView.alignable = null;\n for (var node = lineView.node.firstChild, next; node; node = next) {\n var next = node.nextSibling;\n if (node.className == \"CodeMirror-linewidget\")\n lineView.node.removeChild(node);\n }\n insertLineWidgets(lineView, dims);\n }\n\n // Build a line's DOM representation from scratch\n function buildLineElement(cm, lineView, lineN, dims) {\n var built = getLineContent(cm, lineView);\n lineView.text = lineView.node = built.pre;\n if (built.bgClass) lineView.bgClass = built.bgClass;\n if (built.textClass) lineView.textClass = built.textClass;\n\n updateLineClasses(lineView);\n updateLineGutter(cm, lineView, lineN, dims);\n insertLineWidgets(lineView, dims);\n return lineView.node;\n }\n\n // A lineView may contain multiple logical lines (when merged by\n // collapsed spans). The widgets for all of them need to be drawn.\n function insertLineWidgets(lineView, dims) {\n insertLineWidgetsFor(lineView.line, lineView, dims, true);\n if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)\n insertLineWidgetsFor(lineView.rest[i], lineView, dims, false);\n }\n\n function insertLineWidgetsFor(line, lineView, dims, allowAbove) {\n if (!line.widgets) return;\n var wrap = ensureLineWrapped(lineView);\n for (var i = 0, ws = line.widgets; i < ws.length; ++i) {\n var widget = ws[i], node = elt(\"div\", [widget.node], \"CodeMirror-linewidget\");\n if (!widget.handleMouseEvents) node.setAttribute(\"cm-ignore-events\", \"true\");\n positionLineWidget(widget, node, lineView, dims);\n if (allowAbove && widget.above)\n wrap.insertBefore(node, lineView.gutter || lineView.text);\n else\n wrap.appendChild(node);\n signalLater(widget, \"redraw\");\n }\n }\n\n function positionLineWidget(widget, node, lineView, dims) {\n if (widget.noHScroll) {\n (lineView.alignable || (lineView.alignable = [])).push(node);\n var width = dims.wrapperWidth;\n node.style.left = dims.fixedPos + \"px\";\n if (!widget.coverGutter) {\n width -= dims.gutterTotalWidth;\n node.style.paddingLeft = dims.gutterTotalWidth + \"px\";\n }\n node.style.width = width + \"px\";\n }\n if (widget.coverGutter) {\n node.style.zIndex = 5;\n node.style.position = \"relative\";\n if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + \"px\";\n }\n }\n\n // POSITION OBJECT\n\n // A Pos instance represents a position within the text.\n var Pos = CodeMirror.Pos = function(line, ch) {\n if (!(this instanceof Pos)) return new Pos(line, ch);\n this.line = line; this.ch = ch;\n };\n\n // Compare two positions, return 0 if they are the same, a negative\n // number when a is less, and a positive number otherwise.\n var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };\n\n function copyPos(x) {return Pos(x.line, x.ch);}\n function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }\n function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }\n\n // SELECTION / CURSOR\n\n // Selection objects are immutable. A new one is created every time\n // the selection changes. A selection is one or more non-overlapping\n // (and non-touching) ranges, sorted, and an integer that indicates\n // which one is the primary selection (the one that's scrolled into\n // view, that getCursor returns, etc).\n function Selection(ranges, primIndex) {\n this.ranges = ranges;\n this.primIndex = primIndex;\n }\n\n Selection.prototype = {\n primary: function() { return this.ranges[this.primIndex]; },\n equals: function(other) {\n if (other == this) return true;\n if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;\n for (var i = 0; i < this.ranges.length; i++) {\n var here = this.ranges[i], there = other.ranges[i];\n if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;\n }\n return true;\n },\n deepCopy: function() {\n for (var out = [], i = 0; i < this.ranges.length; i++)\n out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));\n return new Selection(out, this.primIndex);\n },\n somethingSelected: function() {\n for (var i = 0; i < this.ranges.length; i++)\n if (!this.ranges[i].empty()) return true;\n return false;\n },\n contains: function(pos, end) {\n if (!end) end = pos;\n for (var i = 0; i < this.ranges.length; i++) {\n var range = this.ranges[i];\n if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)\n return i;\n }\n return -1;\n }\n };\n\n function Range(anchor, head) {\n this.anchor = anchor; this.head = head;\n }\n\n Range.prototype = {\n from: function() { return minPos(this.anchor, this.head); },\n to: function() { return maxPos(this.anchor, this.head); },\n empty: function() {\n return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;\n }\n };\n\n // Take an unsorted, potentially overlapping set of ranges, and\n // build a selection out of it. 'Consumes' ranges array (modifying\n // it).\n function normalizeSelection(ranges, primIndex) {\n var prim = ranges[primIndex];\n ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });\n primIndex = indexOf(ranges, prim);\n for (var i = 1; i < ranges.length; i++) {\n var cur = ranges[i], prev = ranges[i - 1];\n if (cmp(prev.to(), cur.from()) >= 0) {\n var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());\n var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;\n if (i <= primIndex) --primIndex;\n ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));\n }\n }\n return new Selection(ranges, primIndex);\n }\n\n function simpleSelection(anchor, head) {\n return new Selection([new Range(anchor, head || anchor)], 0);\n }\n\n // Most of the external API clips given positions to make sure they\n // actually exist within the document.\n function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}\n function clipPos(doc, pos) {\n if (pos.line < doc.first) return Pos(doc.first, 0);\n var last = doc.first + doc.size - 1;\n if (pos.line > last) return Pos(last, getLine(doc, last).text.length);\n return clipToLen(pos, getLine(doc, pos.line).text.length);\n }\n function clipToLen(pos, linelen) {\n var ch = pos.ch;\n if (ch == null || ch > linelen) return Pos(pos.line, linelen);\n else if (ch < 0) return Pos(pos.line, 0);\n else return pos;\n }\n function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}\n function clipPosArray(doc, array) {\n for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);\n return out;\n }\n\n // SELECTION UPDATES\n\n // The 'scroll' parameter given to many of these indicated whether\n // the new cursor position should be scrolled into view after\n // modifying the selection.\n\n // If shift is held or the extend flag is set, extends a range to\n // include a given position (and optionally a second position).\n // Otherwise, simply returns the range between the given positions.\n // Used for cursor motion and such.\n function extendRange(doc, range, head, other) {\n if (doc.cm && doc.cm.display.shift || doc.extend) {\n var anchor = range.anchor;\n if (other) {\n var posBefore = cmp(head, anchor) < 0;\n if (posBefore != (cmp(other, anchor) < 0)) {\n anchor = head;\n head = other;\n } else if (posBefore != (cmp(head, other) < 0)) {\n head = other;\n }\n }\n return new Range(anchor, head);\n } else {\n return new Range(other || head, head);\n }\n }\n\n // Extend the primary selection range, discard the rest.\n function extendSelection(doc, head, other, options) {\n setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);\n }\n\n // Extend all selections (pos is an array of selections with length\n // equal the number of selections)\n function extendSelections(doc, heads, options) {\n for (var out = [], i = 0; i < doc.sel.ranges.length; i++)\n out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);\n var newSel = normalizeSelection(out, doc.sel.primIndex);\n setSelection(doc, newSel, options);\n }\n\n // Updates a single range in the selection.\n function replaceOneSelection(doc, i, range, options) {\n var ranges = doc.sel.ranges.slice(0);\n ranges[i] = range;\n setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);\n }\n\n // Reset the selection to a single range.\n function setSimpleSelection(doc, anchor, head, options) {\n setSelection(doc, simpleSelection(anchor, head), options);\n }\n\n // Give beforeSelectionChange handlers a change to influence a\n // selection update.\n function filterSelectionChange(doc, sel) {\n var obj = {\n ranges: sel.ranges,\n update: function(ranges) {\n this.ranges = [];\n for (var i = 0; i < ranges.length; i++)\n this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),\n clipPos(doc, ranges[i].head));\n }\n };\n signal(doc, \"beforeSelectionChange\", doc, obj);\n if (doc.cm) signal(doc.cm, \"beforeSelectionChange\", doc.cm, obj);\n if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);\n else return sel;\n }\n\n function setSelectionReplaceHistory(doc, sel, options) {\n var done = doc.history.done, last = lst(done);\n if (last && last.ranges) {\n done[done.length - 1] = sel;\n setSelectionNoUndo(doc, sel, options);\n } else {\n setSelection(doc, sel, options);\n }\n }\n\n // Set a new selection.\n function setSelection(doc, sel, options) {\n setSelectionNoUndo(doc, sel, options);\n addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);\n }\n\n function setSelectionNoUndo(doc, sel, options) {\n if (hasHandler(doc, \"beforeSelectionChange\") || doc.cm && hasHandler(doc.cm, \"beforeSelectionChange\"))\n sel = filterSelectionChange(doc, sel);\n\n var bias = options && options.bias ||\n (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);\n setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));\n\n if (!(options && options.scroll === false) && doc.cm)\n ensureCursorVisible(doc.cm);\n }\n\n function setSelectionInner(doc, sel) {\n if (sel.equals(doc.sel)) return;\n\n doc.sel = sel;\n\n if (doc.cm) {\n doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;\n signalCursorActivity(doc.cm);\n }\n signalLater(doc, \"cursorActivity\", doc);\n }\n\n // Verify that the selection does not partially select any atomic\n // marked ranges.\n function reCheckSelection(doc) {\n setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);\n }\n\n // Return a selection that does not partially select any atomic\n // ranges.\n function skipAtomicInSelection(doc, sel, bias, mayClear) {\n var out;\n for (var i = 0; i < sel.ranges.length; i++) {\n var range = sel.ranges[i];\n var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);\n var newHead = skipAtomic(doc, range.head, bias, mayClear);\n if (out || newAnchor != range.anchor || newHead != range.head) {\n if (!out) out = sel.ranges.slice(0, i);\n out[i] = new Range(newAnchor, newHead);\n }\n }\n return out ? normalizeSelection(out, sel.primIndex) : sel;\n }\n\n // Ensure a given position is not inside an atomic range.\n function skipAtomic(doc, pos, bias, mayClear) {\n var flipped = false, curPos = pos;\n var dir = bias || 1;\n doc.cantEdit = false;\n search: for (;;) {\n var line = getLine(doc, curPos.line);\n if (line.markedSpans) {\n for (var i = 0; i < line.markedSpans.length; ++i) {\n var sp = line.markedSpans[i], m = sp.marker;\n if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&\n (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {\n if (mayClear) {\n signal(m, \"beforeCursorEnter\");\n if (m.explicitlyCleared) {\n if (!line.markedSpans) break;\n else {--i; continue;}\n }\n }\n if (!m.atomic) continue;\n var newPos = m.find(dir < 0 ? -1 : 1);\n if (cmp(newPos, curPos) == 0) {\n newPos.ch += dir;\n if (newPos.ch < 0) {\n if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));\n else newPos = null;\n } else if (newPos.ch > line.text.length) {\n if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);\n else newPos = null;\n }\n if (!newPos) {\n if (flipped) {\n // Driven in a corner -- no valid cursor position found at all\n // -- try again *with* clearing, if we didn't already\n if (!mayClear) return skipAtomic(doc, pos, bias, true);\n // Otherwise, turn off editing until further notice, and return the start of the doc\n doc.cantEdit = true;\n return Pos(doc.first, 0);\n }\n flipped = true; newPos = pos; dir = -dir;\n }\n }\n curPos = newPos;\n continue search;\n }\n }\n }\n return curPos;\n }\n }\n\n // SELECTION DRAWING\n\n // Redraw the selection and/or cursor\n function drawSelection(cm) {\n var display = cm.display, doc = cm.doc, result = {};\n var curFragment = result.cursors = document.createDocumentFragment();\n var selFragment = result.selection = document.createDocumentFragment();\n\n for (var i = 0; i < doc.sel.ranges.length; i++) {\n var range = doc.sel.ranges[i];\n var collapsed = range.empty();\n if (collapsed || cm.options.showCursorWhenSelecting)\n drawSelectionCursor(cm, range, curFragment);\n if (!collapsed)\n drawSelectionRange(cm, range, selFragment);\n }\n\n // Move the hidden textarea near the cursor to prevent scrolling artifacts\n if (cm.options.moveInputWithCursor) {\n var headPos = cursorCoords(cm, doc.sel.primary().head, \"div\");\n var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();\n result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,\n headPos.top + lineOff.top - wrapOff.top));\n result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,\n headPos.left + lineOff.left - wrapOff.left));\n }\n\n return result;\n }\n\n function showSelection(cm, drawn) {\n removeChildrenAndAdd(cm.display.cursorDiv, drawn.cursors);\n removeChildrenAndAdd(cm.display.selectionDiv, drawn.selection);\n if (drawn.teTop != null) {\n cm.display.inputDiv.style.top = drawn.teTop + \"px\";\n cm.display.inputDiv.style.left = drawn.teLeft + \"px\";\n }\n }\n\n function updateSelection(cm) {\n showSelection(cm, drawSelection(cm));\n }\n\n // Draws a cursor for the given range\n function drawSelectionCursor(cm, range, output) {\n var pos = cursorCoords(cm, range.head, \"div\", null, null, !cm.options.singleCursorHeightPerLine);\n\n var cursor = output.appendChild(elt(\"div\", \"\\u00a0\", \"CodeMirror-cursor\"));\n cursor.style.left = pos.left + \"px\";\n cursor.style.top = pos.top + \"px\";\n cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + \"px\";\n\n if (pos.other) {\n // Secondary cursor, shown when on a 'jump' in bi-directional text\n var otherCursor = output.appendChild(elt(\"div\", \"\\u00a0\", \"CodeMirror-cursor CodeMirror-secondarycursor\"));\n otherCursor.style.display = \"\";\n otherCursor.style.left = pos.other.left + \"px\";\n otherCursor.style.top = pos.other.top + \"px\";\n otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + \"px\";\n }\n }\n\n // Draws the given range as a highlighted selection\n function drawSelectionRange(cm, range, output) {\n var display = cm.display, doc = cm.doc;\n var fragment = document.createDocumentFragment();\n var padding = paddingH(cm.display), leftSide = padding.left;\n var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;\n\n function add(left, top, width, bottom) {\n if (top < 0) top = 0;\n top = Math.round(top);\n bottom = Math.round(bottom);\n fragment.appendChild(elt(\"div\", null, \"CodeMirror-selected\", \"position: absolute; left: \" + left +\n \"px; top: \" + top + \"px; width: \" + (width == null ? rightSide - left : width) +\n \"px; height: \" + (bottom - top) + \"px\"));\n }\n\n function drawForLine(line, fromArg, toArg) {\n var lineObj = getLine(doc, line);\n var lineLen = lineObj.text.length;\n var start, end;\n function coords(ch, bias) {\n return charCoords(cm, Pos(line, ch), \"div\", lineObj, bias);\n }\n\n iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {\n var leftPos = coords(from, \"left\"), rightPos, left, right;\n if (from == to) {\n rightPos = leftPos;\n left = right = leftPos.left;\n } else {\n rightPos = coords(to - 1, \"right\");\n if (dir == \"rtl\") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }\n left = leftPos.left;\n right = rightPos.right;\n }\n if (fromArg == null && from == 0) left = leftSide;\n if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part\n add(left, leftPos.top, null, leftPos.bottom);\n left = leftSide;\n if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);\n }\n if (toArg == null && to == lineLen) right = rightSide;\n if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)\n start = leftPos;\n if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)\n end = rightPos;\n if (left < leftSide + 1) left = leftSide;\n add(left, rightPos.top, right - left, rightPos.bottom);\n });\n return {start: start, end: end};\n }\n\n var sFrom = range.from(), sTo = range.to();\n if (sFrom.line == sTo.line) {\n drawForLine(sFrom.line, sFrom.ch, sTo.ch);\n } else {\n var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);\n var singleVLine = visualLine(fromLine) == visualLine(toLine);\n var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;\n var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;\n if (singleVLine) {\n if (leftEnd.top < rightStart.top - 2) {\n add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);\n add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);\n } else {\n add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);\n }\n }\n if (leftEnd.bottom < rightStart.top)\n add(leftSide, leftEnd.bottom, null, rightStart.top);\n }\n\n output.appendChild(fragment);\n }\n\n // Cursor-blinking\n function restartBlink(cm) {\n if (!cm.state.focused) return;\n var display = cm.display;\n clearInterval(display.blinker);\n var on = true;\n display.cursorDiv.style.visibility = \"\";\n if (cm.options.cursorBlinkRate > 0)\n display.blinker = setInterval(function() {\n display.cursorDiv.style.visibility = (on = !on) ? \"\" : \"hidden\";\n }, cm.options.cursorBlinkRate);\n else if (cm.options.cursorBlinkRate < 0)\n display.cursorDiv.style.visibility = \"hidden\";\n }\n\n // HIGHLIGHT WORKER\n\n function startWorker(cm, time) {\n if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)\n cm.state.highlight.set(time, bind(highlightWorker, cm));\n }\n\n function highlightWorker(cm) {\n var doc = cm.doc;\n if (doc.frontier < doc.first) doc.frontier = doc.first;\n if (doc.frontier >= cm.display.viewTo) return;\n var end = +new Date + cm.options.workTime;\n var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));\n var changedLines = [];\n\n doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {\n if (doc.frontier >= cm.display.viewFrom) { // Visible\n var oldStyles = line.styles;\n var highlighted = highlightLine(cm, line, state, true);\n line.styles = highlighted.styles;\n var oldCls = line.styleClasses, newCls = highlighted.classes;\n if (newCls) line.styleClasses = newCls;\n else if (oldCls) line.styleClasses = null;\n var ischange = !oldStyles || oldStyles.length != line.styles.length ||\n oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);\n for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];\n if (ischange) changedLines.push(doc.frontier);\n line.stateAfter = copyState(doc.mode, state);\n } else {\n processLine(cm, line.text, state);\n line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;\n }\n ++doc.frontier;\n if (+new Date > end) {\n startWorker(cm, cm.options.workDelay);\n return true;\n }\n });\n if (changedLines.length) runInOp(cm, function() {\n for (var i = 0; i < changedLines.length; i++)\n regLineChange(cm, changedLines[i], \"text\");\n });\n }\n\n // Finds the line to start with when starting a parse. Tries to\n // find a line with a stateAfter, so that it can start with a\n // valid state. If that fails, it returns the line with the\n // smallest indentation, which tends to need the least context to\n // parse correctly.\n function findStartLine(cm, n, precise) {\n var minindent, minline, doc = cm.doc;\n var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);\n for (var search = n; search > lim; --search) {\n if (search <= doc.first) return doc.first;\n var line = getLine(doc, search - 1);\n if (line.stateAfter && (!precise || search <= doc.frontier)) return search;\n var indented = countColumn(line.text, null, cm.options.tabSize);\n if (minline == null || minindent > indented) {\n minline = search - 1;\n minindent = indented;\n }\n }\n return minline;\n }\n\n function getStateBefore(cm, n, precise) {\n var doc = cm.doc, display = cm.display;\n if (!doc.mode.startState) return true;\n var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;\n if (!state) state = startState(doc.mode);\n else state = copyState(doc.mode, state);\n doc.iter(pos, n, function(line) {\n processLine(cm, line.text, state);\n var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo;\n line.stateAfter = save ? copyState(doc.mode, state) : null;\n ++pos;\n });\n if (precise) doc.frontier = pos;\n return state;\n }\n\n // POSITION MEASUREMENT\n\n function paddingTop(display) {return display.lineSpace.offsetTop;}\n function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}\n function paddingH(display) {\n if (display.cachedPaddingH) return display.cachedPaddingH;\n var e = removeChildrenAndAdd(display.measure, elt(\"pre\", \"x\"));\n var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;\n var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};\n if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data;\n return data;\n }\n\n function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; }\n function displayWidth(cm) {\n return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth;\n }\n function displayHeight(cm) {\n return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight;\n }\n\n // Ensure the lineView.wrapping.heights array is populated. This is\n // an array of bottom offsets for the lines that make up a drawn\n // line. When lineWrapping is on, there might be more than one\n // height.\n function ensureLineHeights(cm, lineView, rect) {\n var wrapping = cm.options.lineWrapping;\n var curWidth = wrapping && displayWidth(cm);\n if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {\n var heights = lineView.measure.heights = [];\n if (wrapping) {\n lineView.measure.width = curWidth;\n var rects = lineView.text.firstChild.getClientRects();\n for (var i = 0; i < rects.length - 1; i++) {\n var cur = rects[i], next = rects[i + 1];\n if (Math.abs(cur.bottom - next.bottom) > 2)\n heights.push((cur.bottom + next.top) / 2 - rect.top);\n }\n }\n heights.push(rect.bottom - rect.top);\n }\n }\n\n // Find a line map (mapping character offsets to text nodes) and a\n // measurement cache for the given line number. (A line view might\n // contain multiple lines when collapsed ranges are present.)\n function mapFromLineView(lineView, line, lineN) {\n if (lineView.line == line)\n return {map: lineView.measure.map, cache: lineView.measure.cache};\n for (var i = 0; i < lineView.rest.length; i++)\n if (lineView.rest[i] == line)\n return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]};\n for (var i = 0; i < lineView.rest.length; i++)\n if (lineNo(lineView.rest[i]) > lineN)\n return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true};\n }\n\n // Render a line into the hidden node display.externalMeasured. Used\n // when measurement is needed for a line that's not in the viewport.\n function updateExternalMeasurement(cm, line) {\n line = visualLine(line);\n var lineN = lineNo(line);\n var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);\n view.lineN = lineN;\n var built = view.built = buildLineContent(cm, view);\n view.text = built.pre;\n removeChildrenAndAdd(cm.display.lineMeasure, built.pre);\n return view;\n }\n\n // Get a {top, bottom, left, right} box (in line-local coordinates)\n // for a given character.\n function measureChar(cm, line, ch, bias) {\n return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias);\n }\n\n // Find a line view that corresponds to the given line number.\n function findViewForLine(cm, lineN) {\n if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)\n return cm.display.view[findViewIndex(cm, lineN)];\n var ext = cm.display.externalMeasured;\n if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)\n return ext;\n }\n\n // Measurement can be split in two steps, the set-up work that\n // applies to the whole line, and the measurement of the actual\n // character. Functions like coordsChar, that need to do a lot of\n // measurements in a row, can thus ensure that the set-up work is\n // only done once.\n function prepareMeasureForLine(cm, line) {\n var lineN = lineNo(line);\n var view = findViewForLine(cm, lineN);\n if (view && !view.text)\n view = null;\n else if (view && view.changes)\n updateLineForChanges(cm, view, lineN, getDimensions(cm));\n if (!view)\n view = updateExternalMeasurement(cm, line);\n\n var info = mapFromLineView(view, line, lineN);\n return {\n line: line, view: view, rect: null,\n map: info.map, cache: info.cache, before: info.before,\n hasHeights: false\n };\n }\n\n // Given a prepared measurement object, measures the position of an\n // actual character (or fetches it from the cache).\n function measureCharPrepared(cm, prepared, ch, bias, varHeight) {\n if (prepared.before) ch = -1;\n var key = ch + (bias || \"\"), found;\n if (prepared.cache.hasOwnProperty(key)) {\n found = prepared.cache[key];\n } else {\n if (!prepared.rect)\n prepared.rect = prepared.view.text.getBoundingClientRect();\n if (!prepared.hasHeights) {\n ensureLineHeights(cm, prepared.view, prepared.rect);\n prepared.hasHeights = true;\n }\n found = measureCharInner(cm, prepared, ch, bias);\n if (!found.bogus) prepared.cache[key] = found;\n }\n return {left: found.left, right: found.right,\n top: varHeight ? found.rtop : found.top,\n bottom: varHeight ? found.rbottom : found.bottom};\n }\n\n var nullRect = {left: 0, right: 0, top: 0, bottom: 0};\n\n function measureCharInner(cm, prepared, ch, bias) {\n var map = prepared.map;\n\n var node, start, end, collapse;\n // First, search the line map for the text node corresponding to,\n // or closest to, the target character.\n for (var i = 0; i < map.length; i += 3) {\n var mStart = map[i], mEnd = map[i + 1];\n if (ch < mStart) {\n start = 0; end = 1;\n collapse = \"left\";\n } else if (ch < mEnd) {\n start = ch - mStart;\n end = start + 1;\n } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {\n end = mEnd - mStart;\n start = end - 1;\n if (ch >= mEnd) collapse = \"right\";\n }\n if (start != null) {\n node = map[i + 2];\n if (mStart == mEnd && bias == (node.insertLeft ? \"left\" : \"right\"))\n collapse = bias;\n if (bias == \"left\" && start == 0)\n while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {\n node = map[(i -= 3) + 2];\n collapse = \"left\";\n }\n if (bias == \"right\" && start == mEnd - mStart)\n while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {\n node = map[(i += 3) + 2];\n collapse = \"right\";\n }\n break;\n }\n }\n\n var rect;\n if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.\n for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned\n while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;\n while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;\n if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) {\n rect = node.parentNode.getBoundingClientRect();\n } else if (ie && cm.options.lineWrapping) {\n var rects = range(node, start, end).getClientRects();\n if (rects.length)\n rect = rects[bias == \"right\" ? rects.length - 1 : 0];\n else\n rect = nullRect;\n } else {\n rect = range(node, start, end).getBoundingClientRect() || nullRect;\n }\n if (rect.left || rect.right || start == 0) break;\n end = start;\n start = start - 1;\n collapse = \"right\";\n }\n if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect);\n } else { // If it is a widget, simply get the box for the whole widget.\n if (start > 0) collapse = bias = \"right\";\n var rects;\n if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)\n rect = rects[bias == \"right\" ? rects.length - 1 : 0];\n else\n rect = node.getBoundingClientRect();\n }\n if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {\n var rSpan = node.parentNode.getClientRects()[0];\n if (rSpan)\n rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom};\n else\n rect = nullRect;\n }\n\n var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;\n var mid = (rtop + rbot) / 2;\n var heights = prepared.view.measure.heights;\n for (var i = 0; i < heights.length - 1; i++)\n if (mid < heights[i]) break;\n var top = i ? heights[i - 1] : 0, bot = heights[i];\n var result = {left: (collapse == \"right\" ? rect.right : rect.left) - prepared.rect.left,\n right: (collapse == \"left\" ? rect.left : rect.right) - prepared.rect.left,\n top: top, bottom: bot};\n if (!rect.left && !rect.right) result.bogus = true;\n if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }\n\n return result;\n }\n\n // Work around problem with bounding client rects on ranges being\n // returned incorrectly when zoomed on IE10 and below.\n function maybeUpdateRectForZooming(measure, rect) {\n if (!window.screen || screen.logicalXDPI == null ||\n screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))\n return rect;\n var scaleX = screen.logicalXDPI / screen.deviceXDPI;\n var scaleY = screen.logicalYDPI / screen.deviceYDPI;\n return {left: rect.left * scaleX, right: rect.right * scaleX,\n top: rect.top * scaleY, bottom: rect.bottom * scaleY};\n }\n\n function clearLineMeasurementCacheFor(lineView) {\n if (lineView.measure) {\n lineView.measure.cache = {};\n lineView.measure.heights = null;\n if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)\n lineView.measure.caches[i] = {};\n }\n }\n\n function clearLineMeasurementCache(cm) {\n cm.display.externalMeasure = null;\n removeChildren(cm.display.lineMeasure);\n for (var i = 0; i < cm.display.view.length; i++)\n clearLineMeasurementCacheFor(cm.display.view[i]);\n }\n\n function clearCaches(cm) {\n clearLineMeasurementCache(cm);\n cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;\n if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;\n cm.display.lineNumChars = null;\n }\n\n function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }\n function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }\n\n // Converts a {top, bottom, left, right} box from line-local\n // coordinates into another coordinate system. Context may be one of\n // \"line\", \"div\" (display.lineDiv), \"local\"/null (editor), \"window\",\n // or \"page\".\n function intoCoordSystem(cm, lineObj, rect, context) {\n if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {\n var size = widgetHeight(lineObj.widgets[i]);\n rect.top += size; rect.bottom += size;\n }\n if (context == \"line\") return rect;\n if (!context) context = \"local\";\n var yOff = heightAtLine(lineObj);\n if (context == \"local\") yOff += paddingTop(cm.display);\n else yOff -= cm.display.viewOffset;\n if (context == \"page\" || context == \"window\") {\n var lOff = cm.display.lineSpace.getBoundingClientRect();\n yOff += lOff.top + (context == \"window\" ? 0 : pageScrollY());\n var xOff = lOff.left + (context == \"window\" ? 0 : pageScrollX());\n rect.left += xOff; rect.right += xOff;\n }\n rect.top += yOff; rect.bottom += yOff;\n return rect;\n }\n\n // Coverts a box from \"div\" coords to another coordinate system.\n // Context may be \"window\", \"page\", \"div\", or \"local\"/null.\n function fromCoordSystem(cm, coords, context) {\n if (context == \"div\") return coords;\n var left = coords.left, top = coords.top;\n // First move into \"page\" coordinate system\n if (context == \"page\") {\n left -= pageScrollX();\n top -= pageScrollY();\n } else if (context == \"local\" || !context) {\n var localBox = cm.display.sizer.getBoundingClientRect();\n left += localBox.left;\n top += localBox.top;\n }\n\n var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();\n return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};\n }\n\n function charCoords(cm, pos, context, lineObj, bias) {\n if (!lineObj) lineObj = getLine(cm.doc, pos.line);\n return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context);\n }\n\n // Returns a box for a given cursor position, which may have an\n // 'other' property containing the position of the secondary cursor\n // on a bidi boundary.\n function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {\n lineObj = lineObj || getLine(cm.doc, pos.line);\n if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj);\n function get(ch, right) {\n var m = measureCharPrepared(cm, preparedMeasure, ch, right ? \"right\" : \"left\", varHeight);\n if (right) m.left = m.right; else m.right = m.left;\n return intoCoordSystem(cm, lineObj, m, context);\n }\n function getBidi(ch, partPos) {\n var part = order[partPos], right = part.level % 2;\n if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {\n part = order[--partPos];\n ch = bidiRight(part) - (part.level % 2 ? 0 : 1);\n right = true;\n } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {\n part = order[++partPos];\n ch = bidiLeft(part) - part.level % 2;\n right = false;\n }\n if (right && ch == part.to && ch > part.from) return get(ch - 1);\n return get(ch, right);\n }\n var order = getOrder(lineObj), ch = pos.ch;\n if (!order) return get(ch);\n var partPos = getBidiPartAt(order, ch);\n var val = getBidi(ch, partPos);\n if (bidiOther != null) val.other = getBidi(ch, bidiOther);\n return val;\n }\n\n // Used to cheaply estimate the coordinates for a position. Used for\n // intermediate scroll updates.\n function estimateCoords(cm, pos) {\n var left = 0, pos = clipPos(cm.doc, pos);\n if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch;\n var lineObj = getLine(cm.doc, pos.line);\n var top = heightAtLine(lineObj) + paddingTop(cm.display);\n return {left: left, right: left, top: top, bottom: top + lineObj.height};\n }\n\n // Positions returned by coordsChar contain some extra information.\n // xRel is the relative x position of the input coordinates compared\n // to the found position (so xRel > 0 means the coordinates are to\n // the right of the character position, for example). When outside\n // is true, that means the coordinates lie outside the line's\n // vertical range.\n function PosWithInfo(line, ch, outside, xRel) {\n var pos = Pos(line, ch);\n pos.xRel = xRel;\n if (outside) pos.outside = true;\n return pos;\n }\n\n // Compute the character position closest to the given coordinates.\n // Input must be lineSpace-local (\"div\" coordinate system).\n function coordsChar(cm, x, y) {\n var doc = cm.doc;\n y += cm.display.viewOffset;\n if (y < 0) return PosWithInfo(doc.first, 0, true, -1);\n var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;\n if (lineN > last)\n return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);\n if (x < 0) x = 0;\n\n var lineObj = getLine(doc, lineN);\n for (;;) {\n var found = coordsCharInner(cm, lineObj, lineN, x, y);\n var merged = collapsedSpanAtEnd(lineObj);\n var mergedPos = merged && merged.find(0, true);\n if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))\n lineN = lineNo(lineObj = mergedPos.to.line);\n else\n return found;\n }\n }\n\n function coordsCharInner(cm, lineObj, lineNo, x, y) {\n var innerOff = y - heightAtLine(lineObj);\n var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;\n var preparedMeasure = prepareMeasureForLine(cm, lineObj);\n\n function getX(ch) {\n var sp = cursorCoords(cm, Pos(lineNo, ch), \"line\", lineObj, preparedMeasure);\n wrongLine = true;\n if (innerOff > sp.bottom) return sp.left - adjust;\n else if (innerOff < sp.top) return sp.left + adjust;\n else wrongLine = false;\n return sp.left;\n }\n\n var bidi = getOrder(lineObj), dist = lineObj.text.length;\n var from = lineLeft(lineObj), to = lineRight(lineObj);\n var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;\n\n if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);\n // Do a binary search between these bounds.\n for (;;) {\n if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {\n var ch = x < fromX || x - fromX <= toX - x ? from : to;\n var xDiff = x - (ch == from ? fromX : toX);\n while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;\n var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,\n xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);\n return pos;\n }\n var step = Math.ceil(dist / 2), middle = from + step;\n if (bidi) {\n middle = from;\n for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);\n }\n var middleX = getX(middle);\n if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}\n else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}\n }\n }\n\n var measureText;\n // Compute the default text height.\n function textHeight(display) {\n if (display.cachedTextHeight != null) return display.cachedTextHeight;\n if (measureText == null) {\n measureText = elt(\"pre\");\n // Measure a bunch of lines, for browsers that compute\n // fractional heights.\n for (var i = 0; i < 49; ++i) {\n measureText.appendChild(document.createTextNode(\"x\"));\n measureText.appendChild(elt(\"br\"));\n }\n measureText.appendChild(document.createTextNode(\"x\"));\n }\n removeChildrenAndAdd(display.measure, measureText);\n var height = measureText.offsetHeight / 50;\n if (height > 3) display.cachedTextHeight = height;\n removeChildren(display.measure);\n return height || 1;\n }\n\n // Compute the default character width.\n function charWidth(display) {\n if (display.cachedCharWidth != null) return display.cachedCharWidth;\n var anchor = elt(\"span\", \"xxxxxxxxxx\");\n var pre = elt(\"pre\", [anchor]);\n removeChildrenAndAdd(display.measure, pre);\n var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;\n if (width > 2) display.cachedCharWidth = width;\n return width || 10;\n }\n\n // OPERATIONS\n\n // Operations are used to wrap a series of changes to the editor\n // state in such a way that each change won't have to update the\n // cursor and display (which would be awkward, slow, and\n // error-prone). Instead, display updates are batched and then all\n // combined and executed at once.\n\n var operationGroup = null;\n\n var nextOpId = 0;\n // Start a new operation.\n function startOperation(cm) {\n cm.curOp = {\n cm: cm,\n viewChanged: false, // Flag that indicates that lines might need to be redrawn\n startHeight: cm.doc.height, // Used to detect need to update scrollbar\n forceUpdate: false, // Used to force a redraw\n updateInput: null, // Whether to reset the input textarea\n typing: false, // Whether this reset should be careful to leave existing text (for compositing)\n changeObjs: null, // Accumulated changes, for firing change events\n cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on\n cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already\n selectionChanged: false, // Whether the selection needs to be redrawn\n updateMaxLine: false, // Set when the widest line needs to be determined anew\n scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet\n scrollToPos: null, // Used to scroll to a specific position\n id: ++nextOpId // Unique ID\n };\n if (operationGroup) {\n operationGroup.ops.push(cm.curOp);\n } else {\n cm.curOp.ownsGroup = operationGroup = {\n ops: [cm.curOp],\n delayedCallbacks: []\n };\n }\n }\n\n function fireCallbacksForOps(group) {\n // Calls delayed callbacks and cursorActivity handlers until no\n // new ones appear\n var callbacks = group.delayedCallbacks, i = 0;\n do {\n for (; i < callbacks.length; i++)\n callbacks[i]();\n for (var j = 0; j < group.ops.length; j++) {\n var op = group.ops[j];\n if (op.cursorActivityHandlers)\n while (op.cursorActivityCalled < op.cursorActivityHandlers.length)\n op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm);\n }\n } while (i < callbacks.length);\n }\n\n // Finish an operation, updating the display and signalling delayed events\n function endOperation(cm) {\n var op = cm.curOp, group = op.ownsGroup;\n if (!group) return;\n\n try { fireCallbacksForOps(group); }\n finally {\n operationGroup = null;\n for (var i = 0; i < group.ops.length; i++)\n group.ops[i].cm.curOp = null;\n endOperations(group);\n }\n }\n\n // The DOM updates done when an operation finishes are batched so\n // that the minimum number of relayouts are required.\n function endOperations(group) {\n var ops = group.ops;\n for (var i = 0; i < ops.length; i++) // Read DOM\n endOperation_R1(ops[i]);\n for (var i = 0; i < ops.length; i++) // Write DOM (maybe)\n endOperation_W1(ops[i]);\n for (var i = 0; i < ops.length; i++) // Read DOM\n endOperation_R2(ops[i]);\n for (var i = 0; i < ops.length; i++) // Write DOM (maybe)\n endOperation_W2(ops[i]);\n for (var i = 0; i < ops.length; i++) // Read DOM\n endOperation_finish(ops[i]);\n }\n\n function endOperation_R1(op) {\n var cm = op.cm, display = cm.display;\n maybeClipScrollbars(cm);\n if (op.updateMaxLine) findMaxLine(cm);\n\n op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||\n op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||\n op.scrollToPos.to.line >= display.viewTo) ||\n display.maxLineChanged && cm.options.lineWrapping;\n op.update = op.mustUpdate &&\n new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);\n }\n\n function endOperation_W1(op) {\n op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);\n }\n\n function endOperation_R2(op) {\n var cm = op.cm, display = cm.display;\n if (op.updatedDisplay) updateHeightsInViewport(cm);\n\n op.barMeasure = measureForScrollbars(cm);\n\n // If the max line changed since it was last measured, measure it,\n // and ensure the document's width matches it.\n // updateDisplay_W2 will use these properties to do the actual resizing\n if (display.maxLineChanged && !cm.options.lineWrapping) {\n op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;\n cm.display.sizerWidth = op.adjustWidthTo;\n op.barMeasure.scrollWidth =\n Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);\n op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));\n }\n\n if (op.updatedDisplay || op.selectionChanged)\n op.newSelectionNodes = drawSelection(cm);\n }\n\n function endOperation_W2(op) {\n var cm = op.cm;\n\n if (op.adjustWidthTo != null) {\n cm.display.sizer.style.minWidth = op.adjustWidthTo + \"px\";\n if (op.maxScrollLeft < cm.doc.scrollLeft)\n setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true);\n cm.display.maxLineChanged = false;\n }\n\n if (op.newSelectionNodes)\n showSelection(cm, op.newSelectionNodes);\n if (op.updatedDisplay)\n setDocumentHeight(cm, op.barMeasure);\n if (op.updatedDisplay || op.startHeight != cm.doc.height)\n updateScrollbars(cm, op.barMeasure);\n\n if (op.selectionChanged) restartBlink(cm);\n\n if (cm.state.focused && op.updateInput)\n resetInput(cm, op.typing);\n }\n\n function endOperation_finish(op) {\n var cm = op.cm, display = cm.display, doc = cm.doc;\n\n if (op.updatedDisplay) postUpdateDisplay(cm, op.update);\n\n // Abort mouse wheel delta measurement, when scrolling explicitly\n if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))\n display.wheelStartX = display.wheelStartY = null;\n\n // Propagate the scroll position to the actual DOM scroller\n if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {\n doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));\n display.scrollbars.setScrollTop(doc.scrollTop);\n display.scroller.scrollTop = doc.scrollTop;\n }\n if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {\n doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - displayWidth(cm), op.scrollLeft));\n display.scrollbars.setScrollLeft(doc.scrollLeft);\n display.scroller.scrollLeft = doc.scrollLeft;\n alignHorizontally(cm);\n }\n // If we need to scroll a specific position into view, do so.\n if (op.scrollToPos) {\n var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),\n clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);\n if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);\n }\n\n // Fire events for markers that are hidden/unidden by editing or\n // undoing\n var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;\n if (hidden) for (var i = 0; i < hidden.length; ++i)\n if (!hidden[i].lines.length) signal(hidden[i], \"hide\");\n if (unhidden) for (var i = 0; i < unhidden.length; ++i)\n if (unhidden[i].lines.length) signal(unhidden[i], \"unhide\");\n\n if (display.wrapper.offsetHeight)\n doc.scrollTop = cm.display.scroller.scrollTop;\n\n // Fire change events, and delayed event handlers\n if (op.changeObjs)\n signal(cm, \"changes\", cm, op.changeObjs);\n }\n\n // Run the given function in an operation\n function runInOp(cm, f) {\n if (cm.curOp) return f();\n startOperation(cm);\n try { return f(); }\n finally { endOperation(cm); }\n }\n // Wraps a function in an operation. Returns the wrapped function.\n function operation(cm, f) {\n return function() {\n if (cm.curOp) return f.apply(cm, arguments);\n startOperation(cm);\n try { return f.apply(cm, arguments); }\n finally { endOperation(cm); }\n };\n }\n // Used to add methods to editor and doc instances, wrapping them in\n // operations.\n function methodOp(f) {\n return function() {\n if (this.curOp) return f.apply(this, arguments);\n startOperation(this);\n try { return f.apply(this, arguments); }\n finally { endOperation(this); }\n };\n }\n function docMethodOp(f) {\n return function() {\n var cm = this.cm;\n if (!cm || cm.curOp) return f.apply(this, arguments);\n startOperation(cm);\n try { return f.apply(this, arguments); }\n finally { endOperation(cm); }\n };\n }\n\n // VIEW TRACKING\n\n // These objects are used to represent the visible (currently drawn)\n // part of the document. A LineView may correspond to multiple\n // logical lines, if those are connected by collapsed ranges.\n function LineView(doc, line, lineN) {\n // The starting line\n this.line = line;\n // Continuing lines, if any\n this.rest = visualLineContinued(line);\n // Number of logical lines in this visual line\n this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;\n this.node = this.text = null;\n this.hidden = lineIsHidden(doc, line);\n }\n\n // Create a range of LineView objects for the given lines.\n function buildViewArray(cm, from, to) {\n var array = [], nextPos;\n for (var pos = from; pos < to; pos = nextPos) {\n var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);\n nextPos = pos + view.size;\n array.push(view);\n }\n return array;\n }\n\n // Updates the display.view data structure for a given change to the\n // document. From and to are in pre-change coordinates. Lendiff is\n // the amount of lines added or subtracted by the change. This is\n // used for changes that span multiple lines, or change the way\n // lines are divided into visual lines. regLineChange (below)\n // registers single-line changes.\n function regChange(cm, from, to, lendiff) {\n if (from == null) from = cm.doc.first;\n if (to == null) to = cm.doc.first + cm.doc.size;\n if (!lendiff) lendiff = 0;\n\n var display = cm.display;\n if (lendiff && to < display.viewTo &&\n (display.updateLineNumbers == null || display.updateLineNumbers > from))\n display.updateLineNumbers = from;\n\n cm.curOp.viewChanged = true;\n\n if (from >= display.viewTo) { // Change after\n if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)\n resetView(cm);\n } else if (to <= display.viewFrom) { // Change before\n if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {\n resetView(cm);\n } else {\n display.viewFrom += lendiff;\n display.viewTo += lendiff;\n }\n } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap\n resetView(cm);\n } else if (from <= display.viewFrom) { // Top overlap\n var cut = viewCuttingPoint(cm, to, to + lendiff, 1);\n if (cut) {\n display.view = display.view.slice(cut.index);\n display.viewFrom = cut.lineN;\n display.viewTo += lendiff;\n } else {\n resetView(cm);\n }\n } else if (to >= display.viewTo) { // Bottom overlap\n var cut = viewCuttingPoint(cm, from, from, -1);\n if (cut) {\n display.view = display.view.slice(0, cut.index);\n display.viewTo = cut.lineN;\n } else {\n resetView(cm);\n }\n } else { // Gap in the middle\n var cutTop = viewCuttingPoint(cm, from, from, -1);\n var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);\n if (cutTop && cutBot) {\n display.view = display.view.slice(0, cutTop.index)\n .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))\n .concat(display.view.slice(cutBot.index));\n display.viewTo += lendiff;\n } else {\n resetView(cm);\n }\n }\n\n var ext = display.externalMeasured;\n if (ext) {\n if (to < ext.lineN)\n ext.lineN += lendiff;\n else if (from < ext.lineN + ext.size)\n display.externalMeasured = null;\n }\n }\n\n // Register a change to a single line. Type must be one of \"text\",\n // \"gutter\", \"class\", \"widget\"\n function regLineChange(cm, line, type) {\n cm.curOp.viewChanged = true;\n var display = cm.display, ext = cm.display.externalMeasured;\n if (ext && line >= ext.lineN && line < ext.lineN + ext.size)\n display.externalMeasured = null;\n\n if (line < display.viewFrom || line >= display.viewTo) return;\n var lineView = display.view[findViewIndex(cm, line)];\n if (lineView.node == null) return;\n var arr = lineView.changes || (lineView.changes = []);\n if (indexOf(arr, type) == -1) arr.push(type);\n }\n\n // Clear the view.\n function resetView(cm) {\n cm.display.viewFrom = cm.display.viewTo = cm.doc.first;\n cm.display.view = [];\n cm.display.viewOffset = 0;\n }\n\n // Find the view element corresponding to a given line. Return null\n // when the line isn't visible.\n function findViewIndex(cm, n) {\n if (n >= cm.display.viewTo) return null;\n n -= cm.display.viewFrom;\n if (n < 0) return null;\n var view = cm.display.view;\n for (var i = 0; i < view.length; i++) {\n n -= view[i].size;\n if (n < 0) return i;\n }\n }\n\n function viewCuttingPoint(cm, oldN, newN, dir) {\n var index = findViewIndex(cm, oldN), diff, view = cm.display.view;\n if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)\n return {index: index, lineN: newN};\n for (var i = 0, n = cm.display.viewFrom; i < index; i++)\n n += view[i].size;\n if (n != oldN) {\n if (dir > 0) {\n if (index == view.length - 1) return null;\n diff = (n + view[index].size) - oldN;\n index++;\n } else {\n diff = n - oldN;\n }\n oldN += diff; newN += diff;\n }\n while (visualLineNo(cm.doc, newN) != newN) {\n if (index == (dir < 0 ? 0 : view.length - 1)) return null;\n newN += dir * view[index - (dir < 0 ? 1 : 0)].size;\n index += dir;\n }\n return {index: index, lineN: newN};\n }\n\n // Force the view to cover a given range, adding empty view element\n // or clipping off existing ones as needed.\n function adjustView(cm, from, to) {\n var display = cm.display, view = display.view;\n if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {\n display.view = buildViewArray(cm, from, to);\n display.viewFrom = from;\n } else {\n if (display.viewFrom > from)\n display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view);\n else if (display.viewFrom < from)\n display.view = display.view.slice(findViewIndex(cm, from));\n display.viewFrom = from;\n if (display.viewTo < to)\n display.view = display.view.concat(buildViewArray(cm, display.viewTo, to));\n else if (display.viewTo > to)\n display.view = display.view.slice(0, findViewIndex(cm, to));\n }\n display.viewTo = to;\n }\n\n // Count the number of lines in the view whose DOM representation is\n // out of date (or nonexistent).\n function countDirtyView(cm) {\n var view = cm.display.view, dirty = 0;\n for (var i = 0; i < view.length; i++) {\n var lineView = view[i];\n if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty;\n }\n return dirty;\n }\n\n // INPUT HANDLING\n\n // Poll for input changes, using the normal rate of polling. This\n // runs as long as the editor is focused.\n function slowPoll(cm) {\n if (cm.display.pollingFast) return;\n cm.display.poll.set(cm.options.pollInterval, function() {\n readInput(cm);\n if (cm.state.focused) slowPoll(cm);\n });\n }\n\n // When an event has just come in that is likely to add or change\n // something in the input textarea, we poll faster, to ensure that\n // the change appears on the screen quickly.\n function fastPoll(cm) {\n var missed = false;\n cm.display.pollingFast = true;\n function p() {\n var changed = readInput(cm);\n if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}\n else {cm.display.pollingFast = false; slowPoll(cm);}\n }\n cm.display.poll.set(20, p);\n }\n\n // This will be set to an array of strings when copying, so that,\n // when pasting, we know what kind of selections the copied text\n // was made out of.\n var lastCopied = null;\n\n // Read input from the textarea, and update the document to match.\n // When something is selected, it is present in the textarea, and\n // selected (unless it is huge, in which case a placeholder is\n // used). When nothing is selected, the cursor sits after previously\n // seen text (can be empty), which is stored in prevInput (we must\n // not reset the textarea when typing, because that breaks IME).\n function readInput(cm) {\n var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc;\n // Since this is called a *lot*, try to bail out as cheaply as\n // possible when it is clear that nothing happened. hasSelection\n // will be the case when there is a lot of text in the textarea,\n // in which case reading its value would be expensive.\n if (!cm.state.focused || (hasSelection(input) && !prevInput) || isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq)\n return false;\n // See paste handler for more on the fakedLastChar kludge\n if (cm.state.pasteIncoming && cm.state.fakedLastChar) {\n input.value = input.value.substring(0, input.value.length - 1);\n cm.state.fakedLastChar = false;\n }\n var text = input.value;\n // If nothing changed, bail.\n if (text == prevInput && !cm.somethingSelected()) return false;\n // Work around nonsensical selection resetting in IE9/10, and\n // inexplicable appearance of private area unicode characters on\n // some key combos in Mac (#2689).\n if (ie && ie_version >= 9 && cm.display.inputHasSelection === text ||\n mac && /[\\uf700-\\uf7ff]/.test(text)) {\n resetInput(cm);\n return false;\n }\n\n var withOp = !cm.curOp;\n if (withOp) startOperation(cm);\n cm.display.shift = false;\n\n if (text.charCodeAt(0) == 0x200b && doc.sel == cm.display.selForContextMenu && !prevInput)\n prevInput = \"\\u200b\";\n // Find the part of the input that is actually new\n var same = 0, l = Math.min(prevInput.length, text.length);\n while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;\n var inserted = text.slice(same), textLines = splitLines(inserted);\n\n // When pasing N lines into N selections, insert one line per selection\n var multiPaste = null;\n if (cm.state.pasteIncoming && doc.sel.ranges.length > 1) {\n if (lastCopied && lastCopied.join(\"\\n\") == inserted)\n multiPaste = doc.sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines);\n else if (textLines.length == doc.sel.ranges.length)\n multiPaste = map(textLines, function(l) { return [l]; });\n }\n\n // Normal behavior is to insert the new text into every selection\n for (var i = doc.sel.ranges.length - 1; i >= 0; i--) {\n var range = doc.sel.ranges[i];\n var from = range.from(), to = range.to();\n // Handle deletion\n if (same < prevInput.length)\n from = Pos(from.line, from.ch - (prevInput.length - same));\n // Handle overwrite\n else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming)\n to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));\n var updateInput = cm.curOp.updateInput;\n var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,\n origin: cm.state.pasteIncoming ? \"paste\" : cm.state.cutIncoming ? \"cut\" : \"+input\"};\n makeChange(cm.doc, changeEvent);\n signalLater(cm, \"inputRead\", cm, changeEvent);\n // When an 'electric' character is inserted, immediately trigger a reindent\n if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&\n cm.options.smartIndent && range.head.ch < 100 &&\n (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) {\n var mode = cm.getModeAt(range.head);\n var end = changeEnd(changeEvent);\n if (mode.electricChars) {\n for (var j = 0; j < mode.electricChars.length; j++)\n if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {\n indentLine(cm, end.line, \"smart\");\n break;\n }\n } else if (mode.electricInput) {\n if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch)))\n indentLine(cm, end.line, \"smart\");\n }\n }\n }\n ensureCursorVisible(cm);\n cm.curOp.updateInput = updateInput;\n cm.curOp.typing = true;\n\n // Don't leave long text in the textarea, since it makes further polling slow\n if (text.length > 1000 || text.indexOf(\"\\n\") > -1) input.value = cm.display.prevInput = \"\";\n else cm.display.prevInput = text;\n if (withOp) endOperation(cm);\n cm.state.pasteIncoming = cm.state.cutIncoming = false;\n return true;\n }\n\n // Reset the input to correspond to the selection (or to be empty,\n // when not typing and nothing is selected)\n function resetInput(cm, typing) {\n if (cm.display.contextMenuPending) return;\n var minimal, selected, doc = cm.doc;\n if (cm.somethingSelected()) {\n cm.display.prevInput = \"\";\n var range = doc.sel.primary();\n minimal = hasCopyEvent &&\n (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);\n var content = minimal ? \"-\" : selected || cm.getSelection();\n cm.display.input.value = content;\n if (cm.state.focused) selectInput(cm.display.input);\n if (ie && ie_version >= 9) cm.display.inputHasSelection = content;\n } else if (!typing) {\n cm.display.prevInput = cm.display.input.value = \"\";\n if (ie && ie_version >= 9) cm.display.inputHasSelection = null;\n }\n cm.display.inaccurateSelection = minimal;\n }\n\n function focusInput(cm) {\n if (cm.options.readOnly != \"nocursor\" && (!mobile || activeElt() != cm.display.input))\n cm.display.input.focus();\n }\n\n function ensureFocus(cm) {\n if (!cm.state.focused) { focusInput(cm); onFocus(cm); }\n }\n\n function isReadOnly(cm) {\n return cm.options.readOnly || cm.doc.cantEdit;\n }\n\n // EVENT HANDLERS\n\n // Attach the necessary event handlers when initializing the editor\n function registerEventHandlers(cm) {\n var d = cm.display;\n on(d.scroller, \"mousedown\", operation(cm, onMouseDown));\n // Older IE's will not fire a second mousedown for a double click\n if (ie && ie_version < 11)\n on(d.scroller, \"dblclick\", operation(cm, function(e) {\n if (signalDOMEvent(cm, e)) return;\n var pos = posFromMouse(cm, e);\n if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;\n e_preventDefault(e);\n var word = cm.findWordAt(pos);\n extendSelection(cm.doc, word.anchor, word.head);\n }));\n else\n on(d.scroller, \"dblclick\", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });\n // Prevent normal selection in the editor (we handle our own)\n on(d.lineSpace, \"selectstart\", function(e) {\n if (!eventInWidget(d, e)) e_preventDefault(e);\n });\n // Some browsers fire contextmenu *after* opening the menu, at\n // which point we can't mess with it anymore. Context menu is\n // handled in onMouseDown for these browsers.\n if (!captureRightClick) on(d.scroller, \"contextmenu\", function(e) {onContextMenu(cm, e);});\n\n // Sync scrolling between fake scrollbars and real scrollable\n // area, ensure viewport is updated when scrolling.\n on(d.scroller, \"scroll\", function() {\n if (d.scroller.clientHeight) {\n setScrollTop(cm, d.scroller.scrollTop);\n setScrollLeft(cm, d.scroller.scrollLeft, true);\n signal(cm, \"scroll\", cm);\n }\n });\n\n // Listen to wheel events in order to try and update the viewport on time.\n on(d.scroller, \"mousewheel\", function(e){onScrollWheel(cm, e);});\n on(d.scroller, \"DOMMouseScroll\", function(e){onScrollWheel(cm, e);});\n\n // Prevent wrapper from ever scrolling\n on(d.wrapper, \"scroll\", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });\n\n on(d.input, \"keyup\", function(e) { onKeyUp.call(cm, e); });\n on(d.input, \"input\", function() {\n if (ie && ie_version >= 9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;\n readInput(cm);\n });\n on(d.input, \"keydown\", operation(cm, onKeyDown));\n on(d.input, \"keypress\", operation(cm, onKeyPress));\n on(d.input, \"focus\", bind(onFocus, cm));\n on(d.input, \"blur\", bind(onBlur, cm));\n\n function drag_(e) {\n if (!signalDOMEvent(cm, e)) e_stop(e);\n }\n if (cm.options.dragDrop) {\n on(d.scroller, \"dragstart\", function(e){onDragStart(cm, e);});\n on(d.scroller, \"dragenter\", drag_);\n on(d.scroller, \"dragover\", drag_);\n on(d.scroller, \"drop\", operation(cm, onDrop));\n }\n on(d.scroller, \"paste\", function(e) {\n if (eventInWidget(d, e)) return;\n cm.state.pasteIncoming = true;\n focusInput(cm);\n fastPoll(cm);\n });\n on(d.input, \"paste\", function() {\n // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206\n // Add a char to the end of textarea before paste occur so that\n // selection doesn't span to the end of textarea.\n if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {\n var start = d.input.selectionStart, end = d.input.selectionEnd;\n d.input.value += \"$\";\n // The selection end needs to be set before the start, otherwise there\n // can be an intermediate non-empty selection between the two, which\n // can override the middle-click paste buffer on linux and cause the\n // wrong thing to get pasted.\n d.input.selectionEnd = end;\n d.input.selectionStart = start;\n cm.state.fakedLastChar = true;\n }\n cm.state.pasteIncoming = true;\n fastPoll(cm);\n });\n\n function prepareCopyCut(e) {\n if (cm.somethingSelected()) {\n lastCopied = cm.getSelections();\n if (d.inaccurateSelection) {\n d.prevInput = \"\";\n d.inaccurateSelection = false;\n d.input.value = lastCopied.join(\"\\n\");\n selectInput(d.input);\n }\n } else {\n var text = [], ranges = [];\n for (var i = 0; i < cm.doc.sel.ranges.length; i++) {\n var line = cm.doc.sel.ranges[i].head.line;\n var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};\n ranges.push(lineRange);\n text.push(cm.getRange(lineRange.anchor, lineRange.head));\n }\n if (e.type == \"cut\") {\n cm.setSelections(ranges, null, sel_dontScroll);\n } else {\n d.prevInput = \"\";\n d.input.value = text.join(\"\\n\");\n selectInput(d.input);\n }\n lastCopied = text;\n }\n if (e.type == \"cut\") cm.state.cutIncoming = true;\n }\n on(d.input, \"cut\", prepareCopyCut);\n on(d.input, \"copy\", prepareCopyCut);\n\n // Needed to handle Tab key in KHTML\n if (khtml) on(d.sizer, \"mouseup\", function() {\n if (activeElt() == d.input) d.input.blur();\n focusInput(cm);\n });\n }\n\n // Called when the window resizes\n function onResize(cm) {\n var d = cm.display;\n if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)\n return;\n // Might be a text scaling operation, clear size caches.\n d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;\n d.scrollbarsClipped = false;\n cm.setSize();\n }\n\n // MOUSE EVENTS\n\n // Return true when the given mouse event happened in a widget\n function eventInWidget(display, e) {\n for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {\n if (!n || (n.nodeType == 1 && n.getAttribute(\"cm-ignore-events\") == \"true\") ||\n (n.parentNode == display.sizer && n != display.mover))\n return true;\n }\n }\n\n // Given a mouse event, find the corresponding position. If liberal\n // is false, it checks whether a gutter or scrollbar was clicked,\n // and returns null if it was. forRect is used by rectangular\n // selections, and tries to estimate a character position even for\n // coordinates beyond the right of the text.\n function posFromMouse(cm, e, liberal, forRect) {\n var display = cm.display;\n if (!liberal && e_target(e).getAttribute(\"not-content\") == \"true\") return null;\n\n var x, y, space = display.lineSpace.getBoundingClientRect();\n // Fails unpredictably on IE[67] when mouse is dragged around quickly.\n try { x = e.clientX - space.left; y = e.clientY - space.top; }\n catch (e) { return null; }\n var coords = coordsChar(cm, x, y), line;\n if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {\n var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;\n coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));\n }\n return coords;\n }\n\n // A mouse down can be a single click, double click, triple click,\n // start of selection drag, start of text drag, new cursor\n // (ctrl-click), rectangle drag (alt-drag), or xwin\n // middle-click-paste. Or it might be a click on something we should\n // not interfere with, such as a scrollbar or widget.\n function onMouseDown(e) {\n if (signalDOMEvent(this, e)) return;\n var cm = this, display = cm.display;\n display.shift = e.shiftKey;\n\n if (eventInWidget(display, e)) {\n if (!webkit) {\n // Briefly turn off draggability, to allow widgets to do\n // normal dragging things.\n display.scroller.draggable = false;\n setTimeout(function(){display.scroller.draggable = true;}, 100);\n }\n return;\n }\n if (clickInGutter(cm, e)) return;\n var start = posFromMouse(cm, e);\n window.focus();\n\n switch (e_button(e)) {\n case 1:\n if (start)\n leftButtonDown(cm, e, start);\n else if (e_target(e) == display.scroller)\n e_preventDefault(e);\n break;\n case 2:\n if (webkit) cm.state.lastMiddleDown = +new Date;\n if (start) extendSelection(cm.doc, start);\n setTimeout(bind(focusInput, cm), 20);\n e_preventDefault(e);\n break;\n case 3:\n if (captureRightClick) onContextMenu(cm, e);\n break;\n }\n }\n\n var lastClick, lastDoubleClick;\n function leftButtonDown(cm, e, start) {\n setTimeout(bind(ensureFocus, cm), 0);\n\n var now = +new Date, type;\n if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {\n type = \"triple\";\n } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {\n type = \"double\";\n lastDoubleClick = {time: now, pos: start};\n } else {\n type = \"single\";\n lastClick = {time: now, pos: start};\n }\n\n var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained;\n if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&\n type == \"single\" && (contained = sel.contains(start)) > -1 &&\n !sel.ranges[contained].empty())\n leftButtonStartDrag(cm, e, start, modifier);\n else\n leftButtonSelect(cm, e, start, type, modifier);\n }\n\n // Start a text drag. When it ends, see if any dragging actually\n // happen, and treat as a click if it didn't.\n function leftButtonStartDrag(cm, e, start, modifier) {\n var display = cm.display;\n var dragEnd = operation(cm, function(e2) {\n if (webkit) display.scroller.draggable = false;\n cm.state.draggingText = false;\n off(document, \"mouseup\", dragEnd);\n off(display.scroller, \"drop\", dragEnd);\n if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {\n e_preventDefault(e2);\n if (!modifier)\n extendSelection(cm.doc, start);\n focusInput(cm);\n // Work around unexplainable focus problem in IE9 (#2127)\n if (ie && ie_version == 9)\n setTimeout(function() {document.body.focus(); focusInput(cm);}, 20);\n }\n });\n // Let the drag handler handle this.\n if (webkit) display.scroller.draggable = true;\n cm.state.draggingText = dragEnd;\n // IE's approach to draggable\n if (display.scroller.dragDrop) display.scroller.dragDrop();\n on(document, \"mouseup\", dragEnd);\n on(display.scroller, \"drop\", dragEnd);\n }\n\n // Normal selection, as opposed to text dragging.\n function leftButtonSelect(cm, e, start, type, addNew) {\n var display = cm.display, doc = cm.doc;\n e_preventDefault(e);\n\n var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;\n if (addNew && !e.shiftKey) {\n ourIndex = doc.sel.contains(start);\n if (ourIndex > -1)\n ourRange = ranges[ourIndex];\n else\n ourRange = new Range(start, start);\n } else {\n ourRange = doc.sel.primary();\n }\n\n if (e.altKey) {\n type = \"rect\";\n if (!addNew) ourRange = new Range(start, start);\n start = posFromMouse(cm, e, true, true);\n ourIndex = -1;\n } else if (type == \"double\") {\n var word = cm.findWordAt(start);\n if (cm.display.shift || doc.extend)\n ourRange = extendRange(doc, ourRange, word.anchor, word.head);\n else\n ourRange = word;\n } else if (type == \"triple\") {\n var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)));\n if (cm.display.shift || doc.extend)\n ourRange = extendRange(doc, ourRange, line.anchor, line.head);\n else\n ourRange = line;\n } else {\n ourRange = extendRange(doc, ourRange, start);\n }\n\n if (!addNew) {\n ourIndex = 0;\n setSelection(doc, new Selection([ourRange], 0), sel_mouse);\n startSel = doc.sel;\n } else if (ourIndex == -1) {\n ourIndex = ranges.length;\n setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),\n {scroll: false, origin: \"*mouse\"});\n } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == \"single\") {\n setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0));\n startSel = doc.sel;\n } else {\n replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);\n }\n\n var lastPos = start;\n function extendTo(pos) {\n if (cmp(lastPos, pos) == 0) return;\n lastPos = pos;\n\n if (type == \"rect\") {\n var ranges = [], tabSize = cm.options.tabSize;\n var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);\n var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);\n var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);\n for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));\n line <= end; line++) {\n var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);\n if (left == right)\n ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos)));\n else if (text.length > leftPos)\n ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));\n }\n if (!ranges.length) ranges.push(new Range(start, start));\n setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),\n {origin: \"*mouse\", scroll: false});\n cm.scrollIntoView(pos);\n } else {\n var oldRange = ourRange;\n var anchor = oldRange.anchor, head = pos;\n if (type != \"single\") {\n if (type == \"double\")\n var range = cm.findWordAt(pos);\n else\n var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));\n if (cmp(range.anchor, anchor) > 0) {\n head = range.head;\n anchor = minPos(oldRange.from(), range.anchor);\n } else {\n head = range.anchor;\n anchor = maxPos(oldRange.to(), range.head);\n }\n }\n var ranges = startSel.ranges.slice(0);\n ranges[ourIndex] = new Range(clipPos(doc, anchor), head);\n setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse);\n }\n }\n\n var editorSize = display.wrapper.getBoundingClientRect();\n // Used to ensure timeout re-tries don't fire when another extend\n // happened in the meantime (clearTimeout isn't reliable -- at\n // least on Chrome, the timeouts still happen even when cleared,\n // if the clear happens after their scheduled firing time).\n var counter = 0;\n\n function extend(e) {\n var curCount = ++counter;\n var cur = posFromMouse(cm, e, true, type == \"rect\");\n if (!cur) return;\n if (cmp(cur, lastPos) != 0) {\n ensureFocus(cm);\n extendTo(cur);\n var visible = visibleLines(display, doc);\n if (cur.line >= visible.to || cur.line < visible.from)\n setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);\n } else {\n var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;\n if (outside) setTimeout(operation(cm, function() {\n if (counter != curCount) return;\n display.scroller.scrollTop += outside;\n extend(e);\n }), 50);\n }\n }\n\n function done(e) {\n counter = Infinity;\n e_preventDefault(e);\n focusInput(cm);\n off(document, \"mousemove\", move);\n off(document, \"mouseup\", up);\n doc.history.lastSelOrigin = null;\n }\n\n var move = operation(cm, function(e) {\n if (!e_button(e)) done(e);\n else extend(e);\n });\n var up = operation(cm, done);\n on(document, \"mousemove\", move);\n on(document, \"mouseup\", up);\n }\n\n // Determines whether an event happened in the gutter, and fires the\n // handlers for the corresponding event.\n function gutterEvent(cm, e, type, prevent, signalfn) {\n try { var mX = e.clientX, mY = e.clientY; }\n catch(e) { return false; }\n if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;\n if (prevent) e_preventDefault(e);\n\n var display = cm.display;\n var lineBox = display.lineDiv.getBoundingClientRect();\n\n if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);\n mY -= lineBox.top - display.viewOffset;\n\n for (var i = 0; i < cm.options.gutters.length; ++i) {\n var g = display.gutters.childNodes[i];\n if (g && g.getBoundingClientRect().right >= mX) {\n var line = lineAtHeight(cm.doc, mY);\n var gutter = cm.options.gutters[i];\n signalfn(cm, type, cm, line, gutter, e);\n return e_defaultPrevented(e);\n }\n }\n }\n\n function clickInGutter(cm, e) {\n return gutterEvent(cm, e, \"gutterClick\", true, signalLater);\n }\n\n // Kludge to work around strange IE behavior where it'll sometimes\n // re-fire a series of drag-related events right after the drop (#1551)\n var lastDrop = 0;\n\n function onDrop(e) {\n var cm = this;\n if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))\n return;\n e_preventDefault(e);\n if (ie) lastDrop = +new Date;\n var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;\n if (!pos || isReadOnly(cm)) return;\n // Might be a file drop, in which case we simply extract the text\n // and insert it.\n if (files && files.length && window.FileReader && window.File) {\n var n = files.length, text = Array(n), read = 0;\n var loadFile = function(file, i) {\n var reader = new FileReader;\n reader.onload = operation(cm, function() {\n text[i] = reader.result;\n if (++read == n) {\n pos = clipPos(cm.doc, pos);\n var change = {from: pos, to: pos, text: splitLines(text.join(\"\\n\")), origin: \"paste\"};\n makeChange(cm.doc, change);\n setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));\n }\n });\n reader.readAsText(file);\n };\n for (var i = 0; i < n; ++i) loadFile(files[i], i);\n } else { // Normal drop\n // Don't do a replace if the drop happened inside of the selected text.\n if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {\n cm.state.draggingText(e);\n // Ensure the editor is re-focused\n setTimeout(bind(focusInput, cm), 20);\n return;\n }\n try {\n var text = e.dataTransfer.getData(\"Text\");\n if (text) {\n if (cm.state.draggingText && !(mac ? e.metaKey : e.ctrlKey))\n var selected = cm.listSelections();\n setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));\n if (selected) for (var i = 0; i < selected.length; ++i)\n replaceRange(cm.doc, \"\", selected[i].anchor, selected[i].head, \"drag\");\n cm.replaceSelection(text, \"around\", \"paste\");\n focusInput(cm);\n }\n }\n catch(e){}\n }\n }\n\n function onDragStart(cm, e) {\n if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }\n if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;\n\n e.dataTransfer.setData(\"Text\", cm.getSelection());\n\n // Use dummy image instead of default browsers image.\n // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.\n if (e.dataTransfer.setDragImage && !safari) {\n var img = elt(\"img\", null, null, \"position: fixed; left: 0; top: 0;\");\n img.src = \"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\";\n if (presto) {\n img.width = img.height = 1;\n cm.display.wrapper.appendChild(img);\n // Force a relayout, or Opera won't use our image for some obscure reason\n img._top = img.offsetTop;\n }\n e.dataTransfer.setDragImage(img, 0, 0);\n if (presto) img.parentNode.removeChild(img);\n }\n }\n\n // SCROLL EVENTS\n\n // Sync the scrollable area and scrollbars, ensure the viewport\n // covers the visible area.\n function setScrollTop(cm, val) {\n if (Math.abs(cm.doc.scrollTop - val) < 2) return;\n cm.doc.scrollTop = val;\n if (!gecko) updateDisplaySimple(cm, {top: val});\n if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;\n cm.display.scrollbars.setScrollTop(val);\n if (gecko) updateDisplaySimple(cm);\n startWorker(cm, 100);\n }\n // Sync scroller and scrollbar, ensure the gutter elements are\n // aligned.\n function setScrollLeft(cm, val, isScroller) {\n if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;\n val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);\n cm.doc.scrollLeft = val;\n alignHorizontally(cm);\n if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;\n cm.display.scrollbars.setScrollLeft(val);\n }\n\n // Since the delta values reported on mouse wheel events are\n // unstandardized between browsers and even browser versions, and\n // generally horribly unpredictable, this code starts by measuring\n // the scroll effect that the first few mouse wheel events have,\n // and, from that, detects the way it can convert deltas to pixel\n // offsets afterwards.\n //\n // The reason we want to know the amount a wheel event will scroll\n // is that it gives us a chance to update the display before the\n // actual scrolling happens, reducing flickering.\n\n var wheelSamples = 0, wheelPixelsPerUnit = null;\n // Fill in a browser-detected starting value on browsers where we\n // know one. These don't have to be accurate -- the result of them\n // being wrong would just be a slight flicker on the first wheel\n // scroll (if it is large enough).\n if (ie) wheelPixelsPerUnit = -.53;\n else if (gecko) wheelPixelsPerUnit = 15;\n else if (chrome) wheelPixelsPerUnit = -.7;\n else if (safari) wheelPixelsPerUnit = -1/3;\n\n var wheelEventDelta = function(e) {\n var dx = e.wheelDeltaX, dy = e.wheelDeltaY;\n if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;\n if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;\n else if (dy == null) dy = e.wheelDelta;\n return {x: dx, y: dy};\n };\n CodeMirror.wheelEventPixels = function(e) {\n var delta = wheelEventDelta(e);\n delta.x *= wheelPixelsPerUnit;\n delta.y *= wheelPixelsPerUnit;\n return delta;\n };\n\n function onScrollWheel(cm, e) {\n var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;\n\n var display = cm.display, scroll = display.scroller;\n // Quit if there's nothing to scroll here\n if (!(dx && scroll.scrollWidth > scroll.clientWidth ||\n dy && scroll.scrollHeight > scroll.clientHeight)) return;\n\n // Webkit browsers on OS X abort momentum scrolls when the target\n // of the scroll event is removed from the scrollable element.\n // This hack (see related code in patchDisplay) makes sure the\n // element is kept around.\n if (dy && mac && webkit) {\n outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {\n for (var i = 0; i < view.length; i++) {\n if (view[i].node == cur) {\n cm.display.currentWheelTarget = cur;\n break outer;\n }\n }\n }\n }\n\n // On some browsers, horizontal scrolling will cause redraws to\n // happen before the gutter has been realigned, causing it to\n // wriggle around in a most unseemly way. When we have an\n // estimated pixels/delta value, we just handle horizontal\n // scrolling entirely here. It'll be slightly off from native, but\n // better than glitching out.\n if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {\n if (dy)\n setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));\n setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));\n e_preventDefault(e);\n display.wheelStartX = null; // Abort measurement, if in progress\n return;\n }\n\n // 'Project' the visible viewport to cover the area that is being\n // scrolled into view (if we know enough to estimate it).\n if (dy && wheelPixelsPerUnit != null) {\n var pixels = dy * wheelPixelsPerUnit;\n var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;\n if (pixels < 0) top = Math.max(0, top + pixels - 50);\n else bot = Math.min(cm.doc.height, bot + pixels + 50);\n updateDisplaySimple(cm, {top: top, bottom: bot});\n }\n\n if (wheelSamples < 20) {\n if (display.wheelStartX == null) {\n display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;\n display.wheelDX = dx; display.wheelDY = dy;\n setTimeout(function() {\n if (display.wheelStartX == null) return;\n var movedX = scroll.scrollLeft - display.wheelStartX;\n var movedY = scroll.scrollTop - display.wheelStartY;\n var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||\n (movedX && display.wheelDX && movedX / display.wheelDX);\n display.wheelStartX = display.wheelStartY = null;\n if (!sample) return;\n wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);\n ++wheelSamples;\n }, 200);\n } else {\n display.wheelDX += dx; display.wheelDY += dy;\n }\n }\n }\n\n // KEY EVENTS\n\n // Run a handler that was bound to a key.\n function doHandleBinding(cm, bound, dropShift) {\n if (typeof bound == \"string\") {\n bound = commands[bound];\n if (!bound) return false;\n }\n // Ensure previous input has been read, so that the handler sees a\n // consistent view of the document\n if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;\n var prevShift = cm.display.shift, done = false;\n try {\n if (isReadOnly(cm)) cm.state.suppressEdits = true;\n if (dropShift) cm.display.shift = false;\n done = bound(cm) != Pass;\n } finally {\n cm.display.shift = prevShift;\n cm.state.suppressEdits = false;\n }\n return done;\n }\n\n function lookupKeyForEditor(cm, name, handle) {\n for (var i = 0; i < cm.state.keyMaps.length; i++) {\n var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);\n if (result) return result;\n }\n return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))\n || lookupKey(name, cm.options.keyMap, handle, cm);\n }\n\n var stopSeq = new Delayed;\n function dispatchKey(cm, name, e, handle) {\n var seq = cm.state.keySeq;\n if (seq) {\n if (isModifierKey(name)) return \"handled\";\n stopSeq.set(50, function() {\n if (cm.state.keySeq == seq) {\n cm.state.keySeq = null;\n resetInput(cm);\n }\n });\n name = seq + \" \" + name;\n }\n var result = lookupKeyForEditor(cm, name, handle);\n\n if (result == \"multi\")\n cm.state.keySeq = name;\n if (result == \"handled\")\n signalLater(cm, \"keyHandled\", cm, name, e);\n\n if (result == \"handled\" || result == \"multi\") {\n e_preventDefault(e);\n restartBlink(cm);\n }\n\n if (seq && !result && /\\'$/.test(name)) {\n e_preventDefault(e);\n return true;\n }\n return !!result;\n }\n\n // Handle a key from the keydown event.\n function handleKeyBinding(cm, e) {\n var name = keyName(e, true);\n if (!name) return false;\n\n if (e.shiftKey && !cm.state.keySeq) {\n // First try to resolve full name (including 'Shift-'). Failing\n // that, see if there is a cursor-motion command (starting with\n // 'go') bound to the keyname without 'Shift-'.\n return dispatchKey(cm, \"Shift-\" + name, e, function(b) {return doHandleBinding(cm, b, true);})\n || dispatchKey(cm, name, e, function(b) {\n if (typeof b == \"string\" ? /^go[A-Z]/.test(b) : b.motion)\n return doHandleBinding(cm, b);\n });\n } else {\n return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); });\n }\n }\n\n // Handle a key from the keypress event\n function handleCharBinding(cm, e, ch) {\n return dispatchKey(cm, \"'\" + ch + \"'\", e,\n function(b) { return doHandleBinding(cm, b, true); });\n }\n\n var lastStoppedKey = null;\n function onKeyDown(e) {\n var cm = this;\n ensureFocus(cm);\n if (signalDOMEvent(cm, e)) return;\n // IE does strange things with escape.\n if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false;\n var code = e.keyCode;\n cm.display.shift = code == 16 || e.shiftKey;\n var handled = handleKeyBinding(cm, e);\n if (presto) {\n lastStoppedKey = handled ? code : null;\n // Opera has no cut event... we try to at least catch the key combo\n if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))\n cm.replaceSelection(\"\", null, \"cut\");\n }\n\n // Turn mouse into crosshair when Alt is held on Mac.\n if (code == 18 && !/\\bCodeMirror-crosshair\\b/.test(cm.display.lineDiv.className))\n showCrossHair(cm);\n }\n\n function showCrossHair(cm) {\n var lineDiv = cm.display.lineDiv;\n addClass(lineDiv, \"CodeMirror-crosshair\");\n\n function up(e) {\n if (e.keyCode == 18 || !e.altKey) {\n rmClass(lineDiv, \"CodeMirror-crosshair\");\n off(document, \"keyup\", up);\n off(document, \"mouseover\", up);\n }\n }\n on(document, \"keyup\", up);\n on(document, \"mouseover\", up);\n }\n\n function onKeyUp(e) {\n if (e.keyCode == 16) this.doc.sel.shift = false;\n signalDOMEvent(this, e);\n }\n\n function onKeyPress(e) {\n var cm = this;\n if (signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return;\n var keyCode = e.keyCode, charCode = e.charCode;\n if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}\n if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;\n var ch = String.fromCharCode(charCode == null ? keyCode : charCode);\n if (handleCharBinding(cm, e, ch)) return;\n if (ie && ie_version >= 9) cm.display.inputHasSelection = null;\n fastPoll(cm);\n }\n\n // FOCUS/BLUR EVENTS\n\n function onFocus(cm) {\n if (cm.options.readOnly == \"nocursor\") return;\n if (!cm.state.focused) {\n signal(cm, \"focus\", cm);\n cm.state.focused = true;\n addClass(cm.display.wrapper, \"CodeMirror-focused\");\n // The prevInput test prevents this from firing when a context\n // menu is closed (since the resetInput would kill the\n // select-all detection hack)\n if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {\n resetInput(cm);\n if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730\n }\n }\n slowPoll(cm);\n restartBlink(cm);\n }\n function onBlur(cm) {\n if (cm.state.focused) {\n signal(cm, \"blur\", cm);\n cm.state.focused = false;\n rmClass(cm.display.wrapper, \"CodeMirror-focused\");\n }\n clearInterval(cm.display.blinker);\n setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150);\n }\n\n // CONTEXT MENU HANDLING\n\n // To make the context menu work, we need to briefly unhide the\n // textarea (making it as unobtrusive as possible) to let the\n // right-click take effect on it.\n function onContextMenu(cm, e) {\n if (signalDOMEvent(cm, e, \"contextmenu\")) return;\n var display = cm.display;\n if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return;\n\n var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;\n if (!pos || presto) return; // Opera is difficult.\n\n // Reset the current text selection only if the click is done outside of the selection\n // and 'resetSelectionOnContextMenu' option is true.\n var reset = cm.options.resetSelectionOnContextMenu;\n if (reset && cm.doc.sel.contains(pos) == -1)\n operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);\n\n var oldCSS = display.input.style.cssText;\n display.inputDiv.style.position = \"absolute\";\n display.input.style.cssText = \"position: fixed; width: 30px; height: 30px; top: \" + (e.clientY - 5) +\n \"px; left: \" + (e.clientX - 5) + \"px; z-index: 1000; background: \" +\n (ie ? \"rgba(255, 255, 255, .05)\" : \"transparent\") +\n \"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);\";\n if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)\n focusInput(cm);\n if (webkit) window.scrollTo(null, oldScrollY);\n resetInput(cm);\n // Adds \"Select all\" to context menu in FF\n if (!cm.somethingSelected()) display.input.value = display.prevInput = \" \";\n display.contextMenuPending = true;\n display.selForContextMenu = cm.doc.sel;\n clearTimeout(display.detectingSelectAll);\n\n // Select-all will be greyed out if there's nothing to select, so\n // this adds a zero-width space so that we can later check whether\n // it got selected.\n function prepareSelectAllHack() {\n if (display.input.selectionStart != null) {\n var selected = cm.somethingSelected();\n var extval = display.input.value = \"\\u200b\" + (selected ? display.input.value : \"\");\n display.prevInput = selected ? \"\" : \"\\u200b\";\n display.input.selectionStart = 1; display.input.selectionEnd = extval.length;\n // Re-set this, in case some other handler touched the\n // selection in the meantime.\n display.selForContextMenu = cm.doc.sel;\n }\n }\n function rehide() {\n display.contextMenuPending = false;\n display.inputDiv.style.position = \"relative\";\n display.input.style.cssText = oldCSS;\n if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos);\n slowPoll(cm);\n\n // Try to detect the user choosing select-all\n if (display.input.selectionStart != null) {\n if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();\n var i = 0, poll = function() {\n if (display.selForContextMenu == cm.doc.sel && display.input.selectionStart == 0)\n operation(cm, commands.selectAll)(cm);\n else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);\n else resetInput(cm);\n };\n display.detectingSelectAll = setTimeout(poll, 200);\n }\n }\n\n if (ie && ie_version >= 9) prepareSelectAllHack();\n if (captureRightClick) {\n e_stop(e);\n var mouseup = function() {\n off(window, \"mouseup\", mouseup);\n setTimeout(rehide, 20);\n };\n on(window, \"mouseup\", mouseup);\n } else {\n setTimeout(rehide, 50);\n }\n }\n\n function contextMenuInGutter(cm, e) {\n if (!hasHandler(cm, \"gutterContextMenu\")) return false;\n return gutterEvent(cm, e, \"gutterContextMenu\", false, signal);\n }\n\n // UPDATING\n\n // Compute the position of the end of a change (its 'to' property\n // refers to the pre-change end).\n var changeEnd = CodeMirror.changeEnd = function(change) {\n if (!change.text) return change.to;\n return Pos(change.from.line + change.text.length - 1,\n lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));\n };\n\n // Adjust a position to refer to the post-change position of the\n // same text, or the end of the change if the change covers it.\n function adjustForChange(pos, change) {\n if (cmp(pos, change.from) < 0) return pos;\n if (cmp(pos, change.to) <= 0) return changeEnd(change);\n\n var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;\n if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch;\n return Pos(line, ch);\n }\n\n function computeSelAfterChange(doc, change) {\n var out = [];\n for (var i = 0; i < doc.sel.ranges.length; i++) {\n var range = doc.sel.ranges[i];\n out.push(new Range(adjustForChange(range.anchor, change),\n adjustForChange(range.head, change)));\n }\n return normalizeSelection(out, doc.sel.primIndex);\n }\n\n function offsetPos(pos, old, nw) {\n if (pos.line == old.line)\n return Pos(nw.line, pos.ch - old.ch + nw.ch);\n else\n return Pos(nw.line + (pos.line - old.line), pos.ch);\n }\n\n // Used by replaceSelections to allow moving the selection to the\n // start or around the replaced test. Hint may be \"start\" or \"around\".\n function computeReplacedSel(doc, changes, hint) {\n var out = [];\n var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;\n for (var i = 0; i < changes.length; i++) {\n var change = changes[i];\n var from = offsetPos(change.from, oldPrev, newPrev);\n var to = offsetPos(changeEnd(change), oldPrev, newPrev);\n oldPrev = change.to;\n newPrev = to;\n if (hint == \"around\") {\n var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;\n out[i] = new Range(inv ? to : from, inv ? from : to);\n } else {\n out[i] = new Range(from, from);\n }\n }\n return new Selection(out, doc.sel.primIndex);\n }\n\n // Allow \"beforeChange\" event handlers to influence a change\n function filterChange(doc, change, update) {\n var obj = {\n canceled: false,\n from: change.from,\n to: change.to,\n text: change.text,\n origin: change.origin,\n cancel: function() { this.canceled = true; }\n };\n if (update) obj.update = function(from, to, text, origin) {\n if (from) this.from = clipPos(doc, from);\n if (to) this.to = clipPos(doc, to);\n if (text) this.text = text;\n if (origin !== undefined) this.origin = origin;\n };\n signal(doc, \"beforeChange\", doc, obj);\n if (doc.cm) signal(doc.cm, \"beforeChange\", doc.cm, obj);\n\n if (obj.canceled) return null;\n return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};\n }\n\n // Apply a change to a document, and add it to the document's\n // history, and propagating it to all linked documents.\n function makeChange(doc, change, ignoreReadOnly) {\n if (doc.cm) {\n if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly);\n if (doc.cm.state.suppressEdits) return;\n }\n\n if (hasHandler(doc, \"beforeChange\") || doc.cm && hasHandler(doc.cm, \"beforeChange\")) {\n change = filterChange(doc, change, true);\n if (!change) return;\n }\n\n // Possibly split or suppress the update based on the presence\n // of read-only spans in its range.\n var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);\n if (split) {\n for (var i = split.length - 1; i >= 0; --i)\n makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [\"\"] : change.text});\n } else {\n makeChangeInner(doc, change);\n }\n }\n\n function makeChangeInner(doc, change) {\n if (change.text.length == 1 && change.text[0] == \"\" && cmp(change.from, change.to) == 0) return;\n var selAfter = computeSelAfterChange(doc, change);\n addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);\n\n makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));\n var rebased = [];\n\n linkedDocs(doc, function(doc, sharedHist) {\n if (!sharedHist && indexOf(rebased, doc.history) == -1) {\n rebaseHist(doc.history, change);\n rebased.push(doc.history);\n }\n makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));\n });\n }\n\n // Revert a change stored in a document's history.\n function makeChangeFromHistory(doc, type, allowSelectionOnly) {\n if (doc.cm && doc.cm.state.suppressEdits) return;\n\n var hist = doc.history, event, selAfter = doc.sel;\n var source = type == \"undo\" ? hist.done : hist.undone, dest = type == \"undo\" ? hist.undone : hist.done;\n\n // Verify that there is a useable event (so that ctrl-z won't\n // needlessly clear selection events)\n for (var i = 0; i < source.length; i++) {\n event = source[i];\n if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)\n break;\n }\n if (i == source.length) return;\n hist.lastOrigin = hist.lastSelOrigin = null;\n\n for (;;) {\n event = source.pop();\n if (event.ranges) {\n pushSelectionToHistory(event, dest);\n if (allowSelectionOnly && !event.equals(doc.sel)) {\n setSelection(doc, event, {clearRedo: false});\n return;\n }\n selAfter = event;\n }\n else break;\n }\n\n // Build up a reverse change object to add to the opposite history\n // stack (redo when undoing, and vice versa).\n var antiChanges = [];\n pushSelectionToHistory(selAfter, dest);\n dest.push({changes: antiChanges, generation: hist.generation});\n hist.generation = event.generation || ++hist.maxGeneration;\n\n var filter = hasHandler(doc, \"beforeChange\") || doc.cm && hasHandler(doc.cm, \"beforeChange\");\n\n for (var i = event.changes.length - 1; i >= 0; --i) {\n var change = event.changes[i];\n change.origin = type;\n if (filter && !filterChange(doc, change, false)) {\n source.length = 0;\n return;\n }\n\n antiChanges.push(historyChangeFromChange(doc, change));\n\n var after = i ? computeSelAfterChange(doc, change) : lst(source);\n makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));\n if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)});\n var rebased = [];\n\n // Propagate to the linked documents\n linkedDocs(doc, function(doc, sharedHist) {\n if (!sharedHist && indexOf(rebased, doc.history) == -1) {\n rebaseHist(doc.history, change);\n rebased.push(doc.history);\n }\n makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));\n });\n }\n }\n\n // Sub-views need their line numbers shifted when text is added\n // above or below them in the parent document.\n function shiftDoc(doc, distance) {\n if (distance == 0) return;\n doc.first += distance;\n doc.sel = new Selection(map(doc.sel.ranges, function(range) {\n return new Range(Pos(range.anchor.line + distance, range.anchor.ch),\n Pos(range.head.line + distance, range.head.ch));\n }), doc.sel.primIndex);\n if (doc.cm) {\n regChange(doc.cm, doc.first, doc.first - distance, distance);\n for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)\n regLineChange(doc.cm, l, \"gutter\");\n }\n }\n\n // More lower-level change function, handling only a single document\n // (not linked ones).\n function makeChangeSingleDoc(doc, change, selAfter, spans) {\n if (doc.cm && !doc.cm.curOp)\n return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);\n\n if (change.to.line < doc.first) {\n shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));\n return;\n }\n if (change.from.line > doc.lastLine()) return;\n\n // Clip the change to the size of this doc\n if (change.from.line < doc.first) {\n var shift = change.text.length - 1 - (doc.first - change.from.line);\n shiftDoc(doc, shift);\n change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),\n text: [lst(change.text)], origin: change.origin};\n }\n var last = doc.lastLine();\n if (change.to.line > last) {\n change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),\n text: [change.text[0]], origin: change.origin};\n }\n\n change.removed = getBetween(doc, change.from, change.to);\n\n if (!selAfter) selAfter = computeSelAfterChange(doc, change);\n if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans);\n else updateDoc(doc, change, spans);\n setSelectionNoUndo(doc, selAfter, sel_dontScroll);\n }\n\n // Handle the interaction of a change to a document with the editor\n // that this document is part of.\n function makeChangeSingleDocInEditor(cm, change, spans) {\n var doc = cm.doc, display = cm.display, from = change.from, to = change.to;\n\n var recomputeMaxLength = false, checkWidthStart = from.line;\n if (!cm.options.lineWrapping) {\n checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));\n doc.iter(checkWidthStart, to.line + 1, function(line) {\n if (line == display.maxLine) {\n recomputeMaxLength = true;\n return true;\n }\n });\n }\n\n if (doc.sel.contains(change.from, change.to) > -1)\n signalCursorActivity(cm);\n\n updateDoc(doc, change, spans, estimateHeight(cm));\n\n if (!cm.options.lineWrapping) {\n doc.iter(checkWidthStart, from.line + change.text.length, function(line) {\n var len = lineLength(line);\n if (len > display.maxLineLength) {\n display.maxLine = line;\n display.maxLineLength = len;\n display.maxLineChanged = true;\n recomputeMaxLength = false;\n }\n });\n if (recomputeMaxLength) cm.curOp.updateMaxLine = true;\n }\n\n // Adjust frontier, schedule worker\n doc.frontier = Math.min(doc.frontier, from.line);\n startWorker(cm, 400);\n\n var lendiff = change.text.length - (to.line - from.line) - 1;\n // Remember that these lines changed, for updating the display\n if (change.full)\n regChange(cm);\n else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))\n regLineChange(cm, from.line, \"text\");\n else\n regChange(cm, from.line, to.line + 1, lendiff);\n\n var changesHandler = hasHandler(cm, \"changes\"), changeHandler = hasHandler(cm, \"change\");\n if (changeHandler || changesHandler) {\n var obj = {\n from: from, to: to,\n text: change.text,\n removed: change.removed,\n origin: change.origin\n };\n if (changeHandler) signalLater(cm, \"change\", cm, obj);\n if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj);\n }\n cm.display.selForContextMenu = null;\n }\n\n function replaceRange(doc, code, from, to, origin) {\n if (!to) to = from;\n if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }\n if (typeof code == \"string\") code = splitLines(code);\n makeChange(doc, {from: from, to: to, text: code, origin: origin});\n }\n\n // SCROLLING THINGS INTO VIEW\n\n // If an editor sits on the top or bottom of the window, partially\n // scrolled out of view, this ensures that the cursor is visible.\n function maybeScrollWindow(cm, coords) {\n if (signalDOMEvent(cm, \"scrollCursorIntoView\")) return;\n\n var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;\n if (coords.top + box.top < 0) doScroll = true;\n else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;\n if (doScroll != null && !phantom) {\n var scrollNode = elt(\"div\", \"\\u200b\", null, \"position: absolute; top: \" +\n (coords.top - display.viewOffset - paddingTop(cm.display)) + \"px; height: \" +\n (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + \"px; left: \" +\n coords.left + \"px; width: 2px;\");\n cm.display.lineSpace.appendChild(scrollNode);\n scrollNode.scrollIntoView(doScroll);\n cm.display.lineSpace.removeChild(scrollNode);\n }\n }\n\n // Scroll a given position into view (immediately), verifying that\n // it actually became visible (as line heights are accurately\n // measured, the position of something may 'drift' during drawing).\n function scrollPosIntoView(cm, pos, end, margin) {\n if (margin == null) margin = 0;\n for (var limit = 0; limit < 5; limit++) {\n var changed = false, coords = cursorCoords(cm, pos);\n var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);\n var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),\n Math.min(coords.top, endCoords.top) - margin,\n Math.max(coords.left, endCoords.left),\n Math.max(coords.bottom, endCoords.bottom) + margin);\n var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;\n if (scrollPos.scrollTop != null) {\n setScrollTop(cm, scrollPos.scrollTop);\n if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;\n }\n if (scrollPos.scrollLeft != null) {\n setScrollLeft(cm, scrollPos.scrollLeft);\n if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;\n }\n if (!changed) break;\n }\n return coords;\n }\n\n // Scroll a given set of coordinates into view (immediately).\n function scrollIntoView(cm, x1, y1, x2, y2) {\n var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);\n if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);\n if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);\n }\n\n // Calculate a new scroll position needed to scroll the given\n // rectangle into view. Returns an object with scrollTop and\n // scrollLeft properties. When these are undefined, the\n // vertical/horizontal position does not need to be adjusted.\n function calculateScrollPos(cm, x1, y1, x2, y2) {\n var display = cm.display, snapMargin = textHeight(cm.display);\n if (y1 < 0) y1 = 0;\n var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;\n var screen = displayHeight(cm), result = {};\n if (y2 - y1 > screen) y2 = y1 + screen;\n var docBottom = cm.doc.height + paddingVert(display);\n var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;\n if (y1 < screentop) {\n result.scrollTop = atTop ? 0 : y1;\n } else if (y2 > screentop + screen) {\n var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);\n if (newTop != screentop) result.scrollTop = newTop;\n }\n\n var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;\n var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);\n var tooWide = x2 - x1 > screenw;\n if (tooWide) x2 = x1 + screenw;\n if (x1 < 10)\n result.scrollLeft = 0;\n else if (x1 < screenleft)\n result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));\n else if (x2 > screenw + screenleft - 3)\n result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw;\n return result;\n }\n\n // Store a relative adjustment to the scroll position in the current\n // operation (to be applied when the operation finishes).\n function addToScrollPos(cm, left, top) {\n if (left != null || top != null) resolveScrollToPos(cm);\n if (left != null)\n cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left;\n if (top != null)\n cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;\n }\n\n // Make sure that at the end of the operation the current cursor is\n // shown.\n function ensureCursorVisible(cm) {\n resolveScrollToPos(cm);\n var cur = cm.getCursor(), from = cur, to = cur;\n if (!cm.options.lineWrapping) {\n from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur;\n to = Pos(cur.line, cur.ch + 1);\n }\n cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true};\n }\n\n // When an operation has its scrollToPos property set, and another\n // scroll action is applied before the end of the operation, this\n // 'simulates' scrolling that position into view in a cheap way, so\n // that the effect of intermediate scroll commands is not ignored.\n function resolveScrollToPos(cm) {\n var range = cm.curOp.scrollToPos;\n if (range) {\n cm.curOp.scrollToPos = null;\n var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);\n var sPos = calculateScrollPos(cm, Math.min(from.left, to.left),\n Math.min(from.top, to.top) - range.margin,\n Math.max(from.right, to.right),\n Math.max(from.bottom, to.bottom) + range.margin);\n cm.scrollTo(sPos.scrollLeft, sPos.scrollTop);\n }\n }\n\n // API UTILITIES\n\n // Indent the given line. The how parameter can be \"smart\",\n // \"add\"/null, \"subtract\", or \"prev\". When aggressive is false\n // (typically set to true for forced single-line indents), empty\n // lines are not indented, and places where the mode returns Pass\n // are left alone.\n function indentLine(cm, n, how, aggressive) {\n var doc = cm.doc, state;\n if (how == null) how = \"add\";\n if (how == \"smart\") {\n // Fall back to \"prev\" when the mode doesn't have an indentation\n // method.\n if (!doc.mode.indent) how = \"prev\";\n else state = getStateBefore(cm, n);\n }\n\n var tabSize = cm.options.tabSize;\n var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);\n if (line.stateAfter) line.stateAfter = null;\n var curSpaceString = line.text.match(/^\\s*/)[0], indentation;\n if (!aggressive && !/\\S/.test(line.text)) {\n indentation = 0;\n how = \"not\";\n } else if (how == \"smart\") {\n indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);\n if (indentation == Pass || indentation > 150) {\n if (!aggressive) return;\n how = \"prev\";\n }\n }\n if (how == \"prev\") {\n if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);\n else indentation = 0;\n } else if (how == \"add\") {\n indentation = curSpace + cm.options.indentUnit;\n } else if (how == \"subtract\") {\n indentation = curSpace - cm.options.indentUnit;\n } else if (typeof how == \"number\") {\n indentation = curSpace + how;\n }\n indentation = Math.max(0, indentation);\n\n var indentString = \"\", pos = 0;\n if (cm.options.indentWithTabs)\n for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += \"\\t\";}\n if (pos < indentation) indentString += spaceStr(indentation - pos);\n\n if (indentString != curSpaceString) {\n replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), \"+input\");\n } else {\n // Ensure that, if the cursor was in the whitespace at the start\n // of the line, it is moved to the end of that space.\n for (var i = 0; i < doc.sel.ranges.length; i++) {\n var range = doc.sel.ranges[i];\n if (range.head.line == n && range.head.ch < curSpaceString.length) {\n var pos = Pos(n, curSpaceString.length);\n replaceOneSelection(doc, i, new Range(pos, pos));\n break;\n }\n }\n }\n line.stateAfter = null;\n }\n\n // Utility for applying a change to a line by handle or number,\n // returning the number and optionally registering the line as\n // changed.\n function changeLine(doc, handle, changeType, op) {\n var no = handle, line = handle;\n if (typeof handle == \"number\") line = getLine(doc, clipLine(doc, handle));\n else no = lineNo(handle);\n if (no == null) return null;\n if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType);\n return line;\n }\n\n // Helper for deleting text near the selection(s), used to implement\n // backspace, delete, and similar functionality.\n function deleteNearSelection(cm, compute) {\n var ranges = cm.doc.sel.ranges, kill = [];\n // Build up a set of ranges to kill first, merging overlapping\n // ranges.\n for (var i = 0; i < ranges.length; i++) {\n var toKill = compute(ranges[i]);\n while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {\n var replaced = kill.pop();\n if (cmp(replaced.from, toKill.from) < 0) {\n toKill.from = replaced.from;\n break;\n }\n }\n kill.push(toKill);\n }\n // Next, remove those actual ranges.\n runInOp(cm, function() {\n for (var i = kill.length - 1; i >= 0; i--)\n replaceRange(cm.doc, \"\", kill[i].from, kill[i].to, \"+delete\");\n ensureCursorVisible(cm);\n });\n }\n\n // Used for horizontal relative motion. Dir is -1 or 1 (left or\n // right), unit can be \"char\", \"column\" (like char, but doesn't\n // cross line boundaries), \"word\" (across next word), or \"group\" (to\n // the start of next group of word or non-word-non-whitespace\n // chars). The visually param controls whether, in right-to-left\n // text, direction 1 means to move towards the next index in the\n // string, or towards the character to the right of the current\n // position. The resulting position will have a hitSide=true\n // property if it reached the end of the document.\n function findPosH(doc, pos, dir, unit, visually) {\n var line = pos.line, ch = pos.ch, origDir = dir;\n var lineObj = getLine(doc, line);\n var possible = true;\n function findNextLine() {\n var l = line + dir;\n if (l < doc.first || l >= doc.first + doc.size) return (possible = false);\n line = l;\n return lineObj = getLine(doc, l);\n }\n function moveOnce(boundToLine) {\n var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);\n if (next == null) {\n if (!boundToLine && findNextLine()) {\n if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);\n else ch = dir < 0 ? lineObj.text.length : 0;\n } else return (possible = false);\n } else ch = next;\n return true;\n }\n\n if (unit == \"char\") moveOnce();\n else if (unit == \"column\") moveOnce(true);\n else if (unit == \"word\" || unit == \"group\") {\n var sawType = null, group = unit == \"group\";\n var helper = doc.cm && doc.cm.getHelper(pos, \"wordChars\");\n for (var first = true;; first = false) {\n if (dir < 0 && !moveOnce(!first)) break;\n var cur = lineObj.text.charAt(ch) || \"\\n\";\n var type = isWordChar(cur, helper) ? \"w\"\n : group && cur == \"\\n\" ? \"n\"\n : !group || /\\s/.test(cur) ? null\n : \"p\";\n if (group && !first && !type) type = \"s\";\n if (sawType && sawType != type) {\n if (dir < 0) {dir = 1; moveOnce();}\n break;\n }\n\n if (type) sawType = type;\n if (dir > 0 && !moveOnce(!first)) break;\n }\n }\n var result = skipAtomic(doc, Pos(line, ch), origDir, true);\n if (!possible) result.hitSide = true;\n return result;\n }\n\n // For relative vertical movement. Dir may be -1 or 1. Unit can be\n // \"page\" or \"line\". The resulting position will have a hitSide=true\n // property if it reached the end of the document.\n function findPosV(cm, pos, dir, unit) {\n var doc = cm.doc, x = pos.left, y;\n if (unit == \"page\") {\n var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);\n y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));\n } else if (unit == \"line\") {\n y = dir > 0 ? pos.bottom + 3 : pos.top - 3;\n }\n for (;;) {\n var target = coordsChar(cm, x, y);\n if (!target.outside) break;\n if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }\n y += dir * 5;\n }\n return target;\n }\n\n // EDITOR METHODS\n\n // The publicly visible API. Note that methodOp(f) means\n // 'wrap f in an operation, performed on its `this` parameter'.\n\n // This is not the complete set of editor methods. Most of the\n // methods defined on the Doc type are also injected into\n // CodeMirror.prototype, for backwards compatibility and\n // convenience.\n\n CodeMirror.prototype = {\n constructor: CodeMirror,\n focus: function(){window.focus(); focusInput(this); fastPoll(this);},\n\n setOption: function(option, value) {\n var options = this.options, old = options[option];\n if (options[option] == value && option != \"mode\") return;\n options[option] = value;\n if (optionHandlers.hasOwnProperty(option))\n operation(this, optionHandlers[option])(this, value, old);\n },\n\n getOption: function(option) {return this.options[option];},\n getDoc: function() {return this.doc;},\n\n addKeyMap: function(map, bottom) {\n this.state.keyMaps[bottom ? \"push\" : \"unshift\"](getKeyMap(map));\n },\n removeKeyMap: function(map) {\n var maps = this.state.keyMaps;\n for (var i = 0; i < maps.length; ++i)\n if (maps[i] == map || maps[i].name == map) {\n maps.splice(i, 1);\n return true;\n }\n },\n\n addOverlay: methodOp(function(spec, options) {\n var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);\n if (mode.startState) throw new Error(\"Overlays may not be stateful.\");\n this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});\n this.state.modeGen++;\n regChange(this);\n }),\n removeOverlay: methodOp(function(spec) {\n var overlays = this.state.overlays;\n for (var i = 0; i < overlays.length; ++i) {\n var cur = overlays[i].modeSpec;\n if (cur == spec || typeof spec == \"string\" && cur.name == spec) {\n overlays.splice(i, 1);\n this.state.modeGen++;\n regChange(this);\n return;\n }\n }\n }),\n\n indentLine: methodOp(function(n, dir, aggressive) {\n if (typeof dir != \"string\" && typeof dir != \"number\") {\n if (dir == null) dir = this.options.smartIndent ? \"smart\" : \"prev\";\n else dir = dir ? \"add\" : \"subtract\";\n }\n if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);\n }),\n indentSelection: methodOp(function(how) {\n var ranges = this.doc.sel.ranges, end = -1;\n for (var i = 0; i < ranges.length; i++) {\n var range = ranges[i];\n if (!range.empty()) {\n var from = range.from(), to = range.to();\n var start = Math.max(end, from.line);\n end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;\n for (var j = start; j < end; ++j)\n indentLine(this, j, how);\n var newRanges = this.doc.sel.ranges;\n if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)\n replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll);\n } else if (range.head.line > end) {\n indentLine(this, range.head.line, how, true);\n end = range.head.line;\n if (i == this.doc.sel.primIndex) ensureCursorVisible(this);\n }\n }\n }),\n\n // Fetch the parser token for a given character. Useful for hacks\n // that want to inspect the mode state (say, for completion).\n getTokenAt: function(pos, precise) {\n return takeToken(this, pos, precise);\n },\n\n getLineTokens: function(line, precise) {\n return takeToken(this, Pos(line), precise, true);\n },\n\n getTokenTypeAt: function(pos) {\n pos = clipPos(this.doc, pos);\n var styles = getLineStyles(this, getLine(this.doc, pos.line));\n var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;\n var type;\n if (ch == 0) type = styles[2];\n else for (;;) {\n var mid = (before + after) >> 1;\n if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;\n else if (styles[mid * 2 + 1] < ch) before = mid + 1;\n else { type = styles[mid * 2 + 2]; break; }\n }\n var cut = type ? type.indexOf(\"cm-overlay \") : -1;\n return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1);\n },\n\n getModeAt: function(pos) {\n var mode = this.doc.mode;\n if (!mode.innerMode) return mode;\n return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;\n },\n\n getHelper: function(pos, type) {\n return this.getHelpers(pos, type)[0];\n },\n\n getHelpers: function(pos, type) {\n var found = [];\n if (!helpers.hasOwnProperty(type)) return helpers;\n var help = helpers[type], mode = this.getModeAt(pos);\n if (typeof mode[type] == \"string\") {\n if (help[mode[type]]) found.push(help[mode[type]]);\n } else if (mode[type]) {\n for (var i = 0; i < mode[type].length; i++) {\n var val = help[mode[type][i]];\n if (val) found.push(val);\n }\n } else if (mode.helperType && help[mode.helperType]) {\n found.push(help[mode.helperType]);\n } else if (help[mode.name]) {\n found.push(help[mode.name]);\n }\n for (var i = 0; i < help._global.length; i++) {\n var cur = help._global[i];\n if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)\n found.push(cur.val);\n }\n return found;\n },\n\n getStateAfter: function(line, precise) {\n var doc = this.doc;\n line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);\n return getStateBefore(this, line + 1, precise);\n },\n\n cursorCoords: function(start, mode) {\n var pos, range = this.doc.sel.primary();\n if (start == null) pos = range.head;\n else if (typeof start == \"object\") pos = clipPos(this.doc, start);\n else pos = start ? range.from() : range.to();\n return cursorCoords(this, pos, mode || \"page\");\n },\n\n charCoords: function(pos, mode) {\n return charCoords(this, clipPos(this.doc, pos), mode || \"page\");\n },\n\n coordsChar: function(coords, mode) {\n coords = fromCoordSystem(this, coords, mode || \"page\");\n return coordsChar(this, coords.left, coords.top);\n },\n\n lineAtHeight: function(height, mode) {\n height = fromCoordSystem(this, {top: height, left: 0}, mode || \"page\").top;\n return lineAtHeight(this.doc, height + this.display.viewOffset);\n },\n heightAtLine: function(line, mode) {\n var end = false, last = this.doc.first + this.doc.size - 1;\n if (line < this.doc.first) line = this.doc.first;\n else if (line > last) { line = last; end = true; }\n var lineObj = getLine(this.doc, line);\n return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || \"page\").top +\n (end ? this.doc.height - heightAtLine(lineObj) : 0);\n },\n\n defaultTextHeight: function() { return textHeight(this.display); },\n defaultCharWidth: function() { return charWidth(this.display); },\n\n setGutterMarker: methodOp(function(line, gutterID, value) {\n return changeLine(this.doc, line, \"gutter\", function(line) {\n var markers = line.gutterMarkers || (line.gutterMarkers = {});\n markers[gutterID] = value;\n if (!value && isEmpty(markers)) line.gutterMarkers = null;\n return true;\n });\n }),\n\n clearGutter: methodOp(function(gutterID) {\n var cm = this, doc = cm.doc, i = doc.first;\n doc.iter(function(line) {\n if (line.gutterMarkers && line.gutterMarkers[gutterID]) {\n line.gutterMarkers[gutterID] = null;\n regLineChange(cm, i, \"gutter\");\n if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;\n }\n ++i;\n });\n }),\n\n addLineWidget: methodOp(function(handle, node, options) {\n return addLineWidget(this, handle, node, options);\n }),\n\n removeLineWidget: function(widget) { widget.clear(); },\n\n lineInfo: function(line) {\n if (typeof line == \"number\") {\n if (!isLine(this.doc, line)) return null;\n var n = line;\n line = getLine(this.doc, line);\n if (!line) return null;\n } else {\n var n = lineNo(line);\n if (n == null) return null;\n }\n return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,\n textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,\n widgets: line.widgets};\n },\n\n getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};},\n\n addWidget: function(pos, node, scroll, vert, horiz) {\n var display = this.display;\n pos = cursorCoords(this, clipPos(this.doc, pos));\n var top = pos.bottom, left = pos.left;\n node.style.position = \"absolute\";\n node.setAttribute(\"cm-ignore-events\", \"true\");\n display.sizer.appendChild(node);\n if (vert == \"over\") {\n top = pos.top;\n } else if (vert == \"above\" || vert == \"near\") {\n var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),\n hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);\n // Default to positioning above (if specified and possible); otherwise default to positioning below\n if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)\n top = pos.top - node.offsetHeight;\n else if (pos.bottom + node.offsetHeight <= vspace)\n top = pos.bottom;\n if (left + node.offsetWidth > hspace)\n left = hspace - node.offsetWidth;\n }\n node.style.top = top + \"px\";\n node.style.left = node.style.right = \"\";\n if (horiz == \"right\") {\n left = display.sizer.clientWidth - node.offsetWidth;\n node.style.right = \"0px\";\n } else {\n if (horiz == \"left\") left = 0;\n else if (horiz == \"middle\") left = (display.sizer.clientWidth - node.offsetWidth) / 2;\n node.style.left = left + \"px\";\n }\n if (scroll)\n scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);\n },\n\n triggerOnKeyDown: methodOp(onKeyDown),\n triggerOnKeyPress: methodOp(onKeyPress),\n triggerOnKeyUp: onKeyUp,\n\n execCommand: function(cmd) {\n if (commands.hasOwnProperty(cmd))\n return commands[cmd](this);\n },\n\n findPosH: function(from, amount, unit, visually) {\n var dir = 1;\n if (amount < 0) { dir = -1; amount = -amount; }\n for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {\n cur = findPosH(this.doc, cur, dir, unit, visually);\n if (cur.hitSide) break;\n }\n return cur;\n },\n\n moveH: methodOp(function(dir, unit) {\n var cm = this;\n cm.extendSelectionsBy(function(range) {\n if (cm.display.shift || cm.doc.extend || range.empty())\n return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually);\n else\n return dir < 0 ? range.from() : range.to();\n }, sel_move);\n }),\n\n deleteH: methodOp(function(dir, unit) {\n var sel = this.doc.sel, doc = this.doc;\n if (sel.somethingSelected())\n doc.replaceSelection(\"\", null, \"+delete\");\n else\n deleteNearSelection(this, function(range) {\n var other = findPosH(doc, range.head, dir, unit, false);\n return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};\n });\n }),\n\n findPosV: function(from, amount, unit, goalColumn) {\n var dir = 1, x = goalColumn;\n if (amount < 0) { dir = -1; amount = -amount; }\n for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {\n var coords = cursorCoords(this, cur, \"div\");\n if (x == null) x = coords.left;\n else coords.left = x;\n cur = findPosV(this, coords, dir, unit);\n if (cur.hitSide) break;\n }\n return cur;\n },\n\n moveV: methodOp(function(dir, unit) {\n var cm = this, doc = this.doc, goals = [];\n var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected();\n doc.extendSelectionsBy(function(range) {\n if (collapse)\n return dir < 0 ? range.from() : range.to();\n var headPos = cursorCoords(cm, range.head, \"div\");\n if (range.goalColumn != null) headPos.left = range.goalColumn;\n goals.push(headPos.left);\n var pos = findPosV(cm, headPos, dir, unit);\n if (unit == \"page\" && range == doc.sel.primary())\n addToScrollPos(cm, null, charCoords(cm, pos, \"div\").top - headPos.top);\n return pos;\n }, sel_move);\n if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++)\n doc.sel.ranges[i].goalColumn = goals[i];\n }),\n\n // Find the word at the given position (as returned by coordsChar).\n findWordAt: function(pos) {\n var doc = this.doc, line = getLine(doc, pos.line).text;\n var start = pos.ch, end = pos.ch;\n if (line) {\n var helper = this.getHelper(pos, \"wordChars\");\n if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;\n var startChar = line.charAt(start);\n var check = isWordChar(startChar, helper)\n ? function(ch) { return isWordChar(ch, helper); }\n : /\\s/.test(startChar) ? function(ch) {return /\\s/.test(ch);}\n : function(ch) {return !/\\s/.test(ch) && !isWordChar(ch);};\n while (start > 0 && check(line.charAt(start - 1))) --start;\n while (end < line.length && check(line.charAt(end))) ++end;\n }\n return new Range(Pos(pos.line, start), Pos(pos.line, end));\n },\n\n toggleOverwrite: function(value) {\n if (value != null && value == this.state.overwrite) return;\n if (this.state.overwrite = !this.state.overwrite)\n addClass(this.display.cursorDiv, \"CodeMirror-overwrite\");\n else\n rmClass(this.display.cursorDiv, \"CodeMirror-overwrite\");\n\n signal(this, \"overwriteToggle\", this, this.state.overwrite);\n },\n hasFocus: function() { return activeElt() == this.display.input; },\n\n scrollTo: methodOp(function(x, y) {\n if (x != null || y != null) resolveScrollToPos(this);\n if (x != null) this.curOp.scrollLeft = x;\n if (y != null) this.curOp.scrollTop = y;\n }),\n getScrollInfo: function() {\n var scroller = this.display.scroller;\n return {left: scroller.scrollLeft, top: scroller.scrollTop,\n height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,\n width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,\n clientHeight: displayHeight(this), clientWidth: displayWidth(this)};\n },\n\n scrollIntoView: methodOp(function(range, margin) {\n if (range == null) {\n range = {from: this.doc.sel.primary().head, to: null};\n if (margin == null) margin = this.options.cursorScrollMargin;\n } else if (typeof range == \"number\") {\n range = {from: Pos(range, 0), to: null};\n } else if (range.from == null) {\n range = {from: range, to: null};\n }\n if (!range.to) range.to = range.from;\n range.margin = margin || 0;\n\n if (range.from.line != null) {\n resolveScrollToPos(this);\n this.curOp.scrollToPos = range;\n } else {\n var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left),\n Math.min(range.from.top, range.to.top) - range.margin,\n Math.max(range.from.right, range.to.right),\n Math.max(range.from.bottom, range.to.bottom) + range.margin);\n this.scrollTo(sPos.scrollLeft, sPos.scrollTop);\n }\n }),\n\n setSize: methodOp(function(width, height) {\n var cm = this;\n function interpret(val) {\n return typeof val == \"number\" || /^\\d+$/.test(String(val)) ? val + \"px\" : val;\n }\n if (width != null) cm.display.wrapper.style.width = interpret(width);\n if (height != null) cm.display.wrapper.style.height = interpret(height);\n if (cm.options.lineWrapping) clearLineMeasurementCache(this);\n var lineNo = cm.display.viewFrom;\n cm.doc.iter(lineNo, cm.display.viewTo, function(line) {\n if (line.widgets) for (var i = 0; i < line.widgets.length; i++)\n if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, \"widget\"); break; }\n ++lineNo;\n });\n cm.curOp.forceUpdate = true;\n signal(cm, \"refresh\", this);\n }),\n\n operation: function(f){return runInOp(this, f);},\n\n refresh: methodOp(function() {\n var oldHeight = this.display.cachedTextHeight;\n regChange(this);\n this.curOp.forceUpdate = true;\n clearCaches(this);\n this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop);\n updateGutterSpace(this);\n if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)\n estimateLineHeights(this);\n signal(this, \"refresh\", this);\n }),\n\n swapDoc: methodOp(function(doc) {\n var old = this.doc;\n old.cm = null;\n attachDoc(this, doc);\n clearCaches(this);\n resetInput(this);\n this.scrollTo(doc.scrollLeft, doc.scrollTop);\n this.curOp.forceScroll = true;\n signalLater(this, \"swapDoc\", this, old);\n return old;\n }),\n\n getInputField: function(){return this.display.input;},\n getWrapperElement: function(){return this.display.wrapper;},\n getScrollerElement: function(){return this.display.scroller;},\n getGutterElement: function(){return this.display.gutters;}\n };\n eventMixin(CodeMirror);\n\n // OPTION DEFAULTS\n\n // The default configuration options.\n var defaults = CodeMirror.defaults = {};\n // Functions to run when options are changed.\n var optionHandlers = CodeMirror.optionHandlers = {};\n\n function option(name, deflt, handle, notOnInit) {\n CodeMirror.defaults[name] = deflt;\n if (handle) optionHandlers[name] =\n notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;\n }\n\n // Passed to option handlers when there is no old value.\n var Init = CodeMirror.Init = {toString: function(){return \"CodeMirror.Init\";}};\n\n // These two are, on init, called from the constructor because they\n // have to be initialized before the editor can start at all.\n option(\"value\", \"\", function(cm, val) {\n cm.setValue(val);\n }, true);\n option(\"mode\", null, function(cm, val) {\n cm.doc.modeOption = val;\n loadMode(cm);\n }, true);\n\n option(\"indentUnit\", 2, loadMode, true);\n option(\"indentWithTabs\", false);\n option(\"smartIndent\", true);\n option(\"tabSize\", 4, function(cm) {\n resetModeState(cm);\n clearCaches(cm);\n regChange(cm);\n }, true);\n option(\"specialChars\", /[\\t\\u0000-\\u0019\\u00ad\\u200b-\\u200f\\u2028\\u2029\\ufeff]/g, function(cm, val) {\n cm.options.specialChars = new RegExp(val.source + (val.test(\"\\t\") ? \"\" : \"|\\t\"), \"g\");\n cm.refresh();\n }, true);\n option(\"specialCharPlaceholder\", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);\n option(\"electricChars\", true);\n option(\"rtlMoveVisually\", !windows);\n option(\"wholeLineUpdateBefore\", true);\n\n option(\"theme\", \"default\", function(cm) {\n themeChanged(cm);\n guttersChanged(cm);\n }, true);\n option(\"keyMap\", \"default\", function(cm, val, old) {\n var next = getKeyMap(val);\n var prev = old != CodeMirror.Init && getKeyMap(old);\n if (prev && prev.detach) prev.detach(cm, next);\n if (next.attach) next.attach(cm, prev || null);\n });\n option(\"extraKeys\", null);\n\n option(\"lineWrapping\", false, wrappingChanged, true);\n option(\"gutters\", [], function(cm) {\n setGuttersForLineNumbers(cm.options);\n guttersChanged(cm);\n }, true);\n option(\"fixedGutter\", true, function(cm, val) {\n cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + \"px\" : \"0\";\n cm.refresh();\n }, true);\n option(\"coverGutterNextToScrollbar\", false, function(cm) {updateScrollbars(cm);}, true);\n option(\"scrollbarStyle\", \"native\", function(cm) {\n initScrollbars(cm);\n updateScrollbars(cm);\n cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);\n cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);\n }, true);\n option(\"lineNumbers\", false, function(cm) {\n setGuttersForLineNumbers(cm.options);\n guttersChanged(cm);\n }, true);\n option(\"firstLineNumber\", 1, guttersChanged, true);\n option(\"lineNumberFormatter\", function(integer) {return integer;}, guttersChanged, true);\n option(\"showCursorWhenSelecting\", false, updateSelection, true);\n\n option(\"resetSelectionOnContextMenu\", true);\n\n option(\"readOnly\", false, function(cm, val) {\n if (val == \"nocursor\") {\n onBlur(cm);\n cm.display.input.blur();\n cm.display.disabled = true;\n } else {\n cm.display.disabled = false;\n if (!val) resetInput(cm);\n }\n });\n option(\"disableInput\", false, function(cm, val) {if (!val) resetInput(cm);}, true);\n option(\"dragDrop\", true);\n\n option(\"cursorBlinkRate\", 530);\n option(\"cursorScrollMargin\", 0);\n option(\"cursorHeight\", 1, updateSelection, true);\n option(\"singleCursorHeightPerLine\", true, updateSelection, true);\n option(\"workTime\", 100);\n option(\"workDelay\", 100);\n option(\"flattenSpans\", true, resetModeState, true);\n option(\"addModeClass\", false, resetModeState, true);\n option(\"pollInterval\", 100);\n option(\"undoDepth\", 200, function(cm, val){cm.doc.history.undoDepth = val;});\n option(\"historyEventDelay\", 1250);\n option(\"viewportMargin\", 10, function(cm){cm.refresh();}, true);\n option(\"maxHighlightLength\", 10000, resetModeState, true);\n option(\"moveInputWithCursor\", true, function(cm, val) {\n if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;\n });\n\n option(\"tabindex\", null, function(cm, val) {\n cm.display.input.tabIndex = val || \"\";\n });\n option(\"autofocus\", null);\n\n // MODE DEFINITION AND QUERYING\n\n // Known modes, by name and by MIME\n var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};\n\n // Extra arguments are stored as the mode's dependencies, which is\n // used by (legacy) mechanisms like loadmode.js to automatically\n // load a mode. (Preferred mechanism is the require/define calls.)\n CodeMirror.defineMode = function(name, mode) {\n if (!CodeMirror.defaults.mode && name != \"null\") CodeMirror.defaults.mode = name;\n if (arguments.length > 2)\n mode.dependencies = Array.prototype.slice.call(arguments, 2);\n modes[name] = mode;\n };\n\n CodeMirror.defineMIME = function(mime, spec) {\n mimeModes[mime] = spec;\n };\n\n // Given a MIME type, a {name, ...options} config object, or a name\n // string, return a mode config object.\n CodeMirror.resolveMode = function(spec) {\n if (typeof spec == \"string\" && mimeModes.hasOwnProperty(spec)) {\n spec = mimeModes[spec];\n } else if (spec && typeof spec.name == \"string\" && mimeModes.hasOwnProperty(spec.name)) {\n var found = mimeModes[spec.name];\n if (typeof found == \"string\") found = {name: found};\n spec = createObj(found, spec);\n spec.name = found.name;\n } else if (typeof spec == \"string\" && /^[\\w\\-]+\\/[\\w\\-]+\\+xml$/.test(spec)) {\n return CodeMirror.resolveMode(\"application/xml\");\n }\n if (typeof spec == \"string\") return {name: spec};\n else return spec || {name: \"null\"};\n };\n\n // Given a mode spec (anything that resolveMode accepts), find and\n // initialize an actual mode object.\n CodeMirror.getMode = function(options, spec) {\n var spec = CodeMirror.resolveMode(spec);\n var mfactory = modes[spec.name];\n if (!mfactory) return CodeMirror.getMode(options, \"text/plain\");\n var modeObj = mfactory(options, spec);\n if (modeExtensions.hasOwnProperty(spec.name)) {\n var exts = modeExtensions[spec.name];\n for (var prop in exts) {\n if (!exts.hasOwnProperty(prop)) continue;\n if (modeObj.hasOwnProperty(prop)) modeObj[\"_\" + prop] = modeObj[prop];\n modeObj[prop] = exts[prop];\n }\n }\n modeObj.name = spec.name;\n if (spec.helperType) modeObj.helperType = spec.helperType;\n if (spec.modeProps) for (var prop in spec.modeProps)\n modeObj[prop] = spec.modeProps[prop];\n\n return modeObj;\n };\n\n // Minimal default mode.\n CodeMirror.defineMode(\"null\", function() {\n return {token: function(stream) {stream.skipToEnd();}};\n });\n CodeMirror.defineMIME(\"text/plain\", \"null\");\n\n // This can be used to attach properties to mode objects from\n // outside the actual mode definition.\n var modeExtensions = CodeMirror.modeExtensions = {};\n CodeMirror.extendMode = function(mode, properties) {\n var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});\n copyObj(properties, exts);\n };\n\n // EXTENSIONS\n\n CodeMirror.defineExtension = function(name, func) {\n CodeMirror.prototype[name] = func;\n };\n CodeMirror.defineDocExtension = function(name, func) {\n Doc.prototype[name] = func;\n };\n CodeMirror.defineOption = option;\n\n var initHooks = [];\n CodeMirror.defineInitHook = function(f) {initHooks.push(f);};\n\n var helpers = CodeMirror.helpers = {};\n CodeMirror.registerHelper = function(type, name, value) {\n if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};\n helpers[type][name] = value;\n };\n CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {\n CodeMirror.registerHelper(type, name, value);\n helpers[type]._global.push({pred: predicate, val: value});\n };\n\n // MODE STATE HANDLING\n\n // Utility functions for working with state. Exported because nested\n // modes need to do this for their inner modes.\n\n var copyState = CodeMirror.copyState = function(mode, state) {\n if (state === true) return state;\n if (mode.copyState) return mode.copyState(state);\n var nstate = {};\n for (var n in state) {\n var val = state[n];\n if (val instanceof Array) val = val.concat([]);\n nstate[n] = val;\n }\n return nstate;\n };\n\n var startState = CodeMirror.startState = function(mode, a1, a2) {\n return mode.startState ? mode.startState(a1, a2) : true;\n };\n\n // Given a mode and a state (for that mode), find the inner mode and\n // state at the position that the state refers to.\n CodeMirror.innerMode = function(mode, state) {\n while (mode.innerMode) {\n var info = mode.innerMode(state);\n if (!info || info.mode == mode) break;\n state = info.state;\n mode = info.mode;\n }\n return info || {mode: mode, state: state};\n };\n\n // STANDARD COMMANDS\n\n // Commands are parameter-less actions that can be performed on an\n // editor, mostly used for keybindings.\n var commands = CodeMirror.commands = {\n selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);},\n singleSelection: function(cm) {\n cm.setSelection(cm.getCursor(\"anchor\"), cm.getCursor(\"head\"), sel_dontScroll);\n },\n killLine: function(cm) {\n deleteNearSelection(cm, function(range) {\n if (range.empty()) {\n var len = getLine(cm.doc, range.head.line).text.length;\n if (range.head.ch == len && range.head.line < cm.lastLine())\n return {from: range.head, to: Pos(range.head.line + 1, 0)};\n else\n return {from: range.head, to: Pos(range.head.line, len)};\n } else {\n return {from: range.from(), to: range.to()};\n }\n });\n },\n deleteLine: function(cm) {\n deleteNearSelection(cm, function(range) {\n return {from: Pos(range.from().line, 0),\n to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};\n });\n },\n delLineLeft: function(cm) {\n deleteNearSelection(cm, function(range) {\n return {from: Pos(range.from().line, 0), to: range.from()};\n });\n },\n delWrappedLineLeft: function(cm) {\n deleteNearSelection(cm, function(range) {\n var top = cm.charCoords(range.head, \"div\").top + 5;\n var leftPos = cm.coordsChar({left: 0, top: top}, \"div\");\n return {from: leftPos, to: range.from()};\n });\n },\n delWrappedLineRight: function(cm) {\n deleteNearSelection(cm, function(range) {\n var top = cm.charCoords(range.head, \"div\").top + 5;\n var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, \"div\");\n return {from: range.from(), to: rightPos };\n });\n },\n undo: function(cm) {cm.undo();},\n redo: function(cm) {cm.redo();},\n undoSelection: function(cm) {cm.undoSelection();},\n redoSelection: function(cm) {cm.redoSelection();},\n goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},\n goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},\n goLineStart: function(cm) {\n cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); },\n {origin: \"+move\", bias: 1});\n },\n goLineStartSmart: function(cm) {\n cm.extendSelectionsBy(function(range) {\n return lineStartSmart(cm, range.head);\n }, {origin: \"+move\", bias: 1});\n },\n goLineEnd: function(cm) {\n cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); },\n {origin: \"+move\", bias: -1});\n },\n goLineRight: function(cm) {\n cm.extendSelectionsBy(function(range) {\n var top = cm.charCoords(range.head, \"div\").top + 5;\n return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, \"div\");\n }, sel_move);\n },\n goLineLeft: function(cm) {\n cm.extendSelectionsBy(function(range) {\n var top = cm.charCoords(range.head, \"div\").top + 5;\n return cm.coordsChar({left: 0, top: top}, \"div\");\n }, sel_move);\n },\n goLineLeftSmart: function(cm) {\n cm.extendSelectionsBy(function(range) {\n var top = cm.charCoords(range.head, \"div\").top + 5;\n var pos = cm.coordsChar({left: 0, top: top}, \"div\");\n if (pos.ch < cm.getLine(pos.line).search(/\\S/)) return lineStartSmart(cm, range.head);\n return pos;\n }, sel_move);\n },\n goLineUp: function(cm) {cm.moveV(-1, \"line\");},\n goLineDown: function(cm) {cm.moveV(1, \"line\");},\n goPageUp: function(cm) {cm.moveV(-1, \"page\");},\n goPageDown: function(cm) {cm.moveV(1, \"page\");},\n goCharLeft: function(cm) {cm.moveH(-1, \"char\");},\n goCharRight: function(cm) {cm.moveH(1, \"char\");},\n goColumnLeft: function(cm) {cm.moveH(-1, \"column\");},\n goColumnRight: function(cm) {cm.moveH(1, \"column\");},\n goWordLeft: function(cm) {cm.moveH(-1, \"word\");},\n goGroupRight: function(cm) {cm.moveH(1, \"group\");},\n goGroupLeft: function(cm) {cm.moveH(-1, \"group\");},\n goWordRight: function(cm) {cm.moveH(1, \"word\");},\n delCharBefore: function(cm) {cm.deleteH(-1, \"char\");},\n delCharAfter: function(cm) {cm.deleteH(1, \"char\");},\n delWordBefore: function(cm) {cm.deleteH(-1, \"word\");},\n delWordAfter: function(cm) {cm.deleteH(1, \"word\");},\n delGroupBefore: function(cm) {cm.deleteH(-1, \"group\");},\n delGroupAfter: function(cm) {cm.deleteH(1, \"group\");},\n indentAuto: function(cm) {cm.indentSelection(\"smart\");},\n indentMore: function(cm) {cm.indentSelection(\"add\");},\n indentLess: function(cm) {cm.indentSelection(\"subtract\");},\n insertTab: function(cm) {cm.replaceSelection(\"\\t\");},\n insertSoftTab: function(cm) {\n var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;\n for (var i = 0; i < ranges.length; i++) {\n var pos = ranges[i].from();\n var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);\n spaces.push(new Array(tabSize - col % tabSize + 1).join(\" \"));\n }\n cm.replaceSelections(spaces);\n },\n defaultTab: function(cm) {\n if (cm.somethingSelected()) cm.indentSelection(\"add\");\n else cm.execCommand(\"insertTab\");\n },\n transposeChars: function(cm) {\n runInOp(cm, function() {\n var ranges = cm.listSelections(), newSel = [];\n for (var i = 0; i < ranges.length; i++) {\n var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;\n if (line) {\n if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);\n if (cur.ch > 0) {\n cur = new Pos(cur.line, cur.ch + 1);\n cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),\n Pos(cur.line, cur.ch - 2), cur, \"+transpose\");\n } else if (cur.line > cm.doc.first) {\n var prev = getLine(cm.doc, cur.line - 1).text;\n if (prev)\n cm.replaceRange(line.charAt(0) + \"\\n\" + prev.charAt(prev.length - 1),\n Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), \"+transpose\");\n }\n }\n newSel.push(new Range(cur, cur));\n }\n cm.setSelections(newSel);\n });\n },\n newlineAndIndent: function(cm) {\n runInOp(cm, function() {\n var len = cm.listSelections().length;\n for (var i = 0; i < len; i++) {\n var range = cm.listSelections()[i];\n cm.replaceRange(\"\\n\", range.anchor, range.head, \"+input\");\n cm.indentLine(range.from().line + 1, null, true);\n ensureCursorVisible(cm);\n }\n });\n },\n toggleOverwrite: function(cm) {cm.toggleOverwrite();}\n };\n\n\n // STANDARD KEYMAPS\n\n var keyMap = CodeMirror.keyMap = {};\n\n keyMap.basic = {\n \"Left\": \"goCharLeft\", \"Right\": \"goCharRight\", \"Up\": \"goLineUp\", \"Down\": \"goLineDown\",\n \"End\": \"goLineEnd\", \"Home\": \"goLineStartSmart\", \"PageUp\": \"goPageUp\", \"PageDown\": \"goPageDown\",\n \"Delete\": \"delCharAfter\", \"Backspace\": \"delCharBefore\", \"Shift-Backspace\": \"delCharBefore\",\n \"Tab\": \"defaultTab\", \"Shift-Tab\": \"indentAuto\",\n \"Enter\": \"newlineAndIndent\", \"Insert\": \"toggleOverwrite\",\n \"Esc\": \"singleSelection\"\n };\n // Note that the save and find-related commands aren't defined by\n // default. User code or addons can define them. Unknown commands\n // are simply ignored.\n keyMap.pcDefault = {\n \"Ctrl-A\": \"selectAll\", \"Ctrl-D\": \"deleteLine\", \"Ctrl-Z\": \"undo\", \"Shift-Ctrl-Z\": \"redo\", \"Ctrl-Y\": \"redo\",\n \"Ctrl-Home\": \"goDocStart\", \"Ctrl-End\": \"goDocEnd\", \"Ctrl-Up\": \"goLineUp\", \"Ctrl-Down\": \"goLineDown\",\n \"Ctrl-Left\": \"goGroupLeft\", \"Ctrl-Right\": \"goGroupRight\", \"Alt-Left\": \"goLineStart\", \"Alt-Right\": \"goLineEnd\",\n \"Ctrl-Backspace\": \"delGroupBefore\", \"Ctrl-Delete\": \"delGroupAfter\", \"Ctrl-S\": \"save\", \"Ctrl-F\": \"find\",\n \"Ctrl-G\": \"findNext\", \"Shift-Ctrl-G\": \"findPrev\", \"Shift-Ctrl-F\": \"replace\", \"Shift-Ctrl-R\": \"replaceAll\",\n \"Ctrl-[\": \"indentLess\", \"Ctrl-]\": \"indentMore\",\n \"Ctrl-U\": \"undoSelection\", \"Shift-Ctrl-U\": \"redoSelection\", \"Alt-U\": \"redoSelection\",\n fallthrough: \"basic\"\n };\n // Very basic readline/emacs-style bindings, which are standard on Mac.\n keyMap.emacsy = {\n \"Ctrl-F\": \"goCharRight\", \"Ctrl-B\": \"goCharLeft\", \"Ctrl-P\": \"goLineUp\", \"Ctrl-N\": \"goLineDown\",\n \"Alt-F\": \"goWordRight\", \"Alt-B\": \"goWordLeft\", \"Ctrl-A\": \"goLineStart\", \"Ctrl-E\": \"goLineEnd\",\n \"Ctrl-V\": \"goPageDown\", \"Shift-Ctrl-V\": \"goPageUp\", \"Ctrl-D\": \"delCharAfter\", \"Ctrl-H\": \"delCharBefore\",\n \"Alt-D\": \"delWordAfter\", \"Alt-Backspace\": \"delWordBefore\", \"Ctrl-K\": \"killLine\", \"Ctrl-T\": \"transposeChars\"\n };\n keyMap.macDefault = {\n \"Cmd-A\": \"selectAll\", \"Cmd-D\": \"deleteLine\", \"Cmd-Z\": \"undo\", \"Shift-Cmd-Z\": \"redo\", \"Cmd-Y\": \"redo\",\n \"Cmd-Home\": \"goDocStart\", \"Cmd-Up\": \"goDocStart\", \"Cmd-End\": \"goDocEnd\", \"Cmd-Down\": \"goDocEnd\", \"Alt-Left\": \"goGroupLeft\",\n \"Alt-Right\": \"goGroupRight\", \"Cmd-Left\": \"goLineLeft\", \"Cmd-Right\": \"goLineRight\", \"Alt-Backspace\": \"delGroupBefore\",\n \"Ctrl-Alt-Backspace\": \"delGroupAfter\", \"Alt-Delete\": \"delGroupAfter\", \"Cmd-S\": \"save\", \"Cmd-F\": \"find\",\n \"Cmd-G\": \"findNext\", \"Shift-Cmd-G\": \"findPrev\", \"Cmd-Alt-F\": \"replace\", \"Shift-Cmd-Alt-F\": \"replaceAll\",\n \"Cmd-[\": \"indentLess\", \"Cmd-]\": \"indentMore\", \"Cmd-Backspace\": \"delWrappedLineLeft\", \"Cmd-Delete\": \"delWrappedLineRight\",\n \"Cmd-U\": \"undoSelection\", \"Shift-Cmd-U\": \"redoSelection\", \"Ctrl-Up\": \"goDocStart\", \"Ctrl-Down\": \"goDocEnd\",\n fallthrough: [\"basic\", \"emacsy\"]\n };\n keyMap[\"default\"] = mac ? keyMap.macDefault : keyMap.pcDefault;\n\n // KEYMAP DISPATCH\n\n function normalizeKeyName(name) {\n var parts = name.split(/-(?!$)/), name = parts[parts.length - 1];\n var alt, ctrl, shift, cmd;\n for (var i = 0; i < parts.length - 1; i++) {\n var mod = parts[i];\n if (/^(cmd|meta|m)$/i.test(mod)) cmd = true;\n else if (/^a(lt)?$/i.test(mod)) alt = true;\n else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;\n else if (/^s(hift)$/i.test(mod)) shift = true;\n else throw new Error(\"Unrecognized modifier name: \" + mod);\n }\n if (alt) name = \"Alt-\" + name;\n if (ctrl) name = \"Ctrl-\" + name;\n if (cmd) name = \"Cmd-\" + name;\n if (shift) name = \"Shift-\" + name;\n return name;\n }\n\n // This is a kludge to keep keymaps mostly working as raw objects\n // (backwards compatibility) while at the same time support features\n // like normalization and multi-stroke key bindings. It compiles a\n // new normalized keymap, and then updates the old object to reflect\n // this.\n CodeMirror.normalizeKeyMap = function(keymap) {\n var copy = {};\n for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) {\n var value = keymap[keyname];\n if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue;\n if (value == \"...\") { delete keymap[keyname]; continue; }\n\n var keys = map(keyname.split(\" \"), normalizeKeyName);\n for (var i = 0; i < keys.length; i++) {\n var val, name;\n if (i == keys.length - 1) {\n name = keyname;\n val = value;\n } else {\n name = keys.slice(0, i + 1).join(\" \");\n val = \"...\";\n }\n var prev = copy[name];\n if (!prev) copy[name] = val;\n else if (prev != val) throw new Error(\"Inconsistent bindings for \" + name);\n }\n delete keymap[keyname];\n }\n for (var prop in copy) keymap[prop] = copy[prop];\n return keymap;\n };\n\n var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) {\n map = getKeyMap(map);\n var found = map.call ? map.call(key, context) : map[key];\n if (found === false) return \"nothing\";\n if (found === \"...\") return \"multi\";\n if (found != null && handle(found)) return \"handled\";\n\n if (map.fallthrough) {\n if (Object.prototype.toString.call(map.fallthrough) != \"[object Array]\")\n return lookupKey(key, map.fallthrough, handle, context);\n for (var i = 0; i < map.fallthrough.length; i++) {\n var result = lookupKey(key, map.fallthrough[i], handle, context);\n if (result) return result;\n }\n }\n };\n\n // Modifier key presses don't count as 'real' key presses for the\n // purpose of keymap fallthrough.\n var isModifierKey = CodeMirror.isModifierKey = function(value) {\n var name = typeof value == \"string\" ? value : keyNames[value.keyCode];\n return name == \"Ctrl\" || name == \"Alt\" || name == \"Shift\" || name == \"Mod\";\n };\n\n // Look up the name of a key as indicated by an event object.\n var keyName = CodeMirror.keyName = function(event, noShift) {\n if (presto && event.keyCode == 34 && event[\"char\"]) return false;\n var base = keyNames[event.keyCode], name = base;\n if (name == null || event.altGraphKey) return false;\n if (event.altKey && base != \"Alt\") name = \"Alt-\" + name;\n if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != \"Ctrl\") name = \"Ctrl-\" + name;\n if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != \"Cmd\") name = \"Cmd-\" + name;\n if (!noShift && event.shiftKey && base != \"Shift\") name = \"Shift-\" + name;\n return name;\n };\n\n function getKeyMap(val) {\n return typeof val == \"string\" ? keyMap[val] : val;\n }\n\n // FROMTEXTAREA\n\n CodeMirror.fromTextArea = function(textarea, options) {\n if (!options) options = {};\n options.value = textarea.value;\n if (!options.tabindex && textarea.tabindex)\n options.tabindex = textarea.tabindex;\n if (!options.placeholder && textarea.placeholder)\n options.placeholder = textarea.placeholder;\n // Set autofocus to true if this textarea is focused, or if it has\n // autofocus and no other element is focused.\n if (options.autofocus == null) {\n var hasFocus = activeElt();\n options.autofocus = hasFocus == textarea ||\n textarea.getAttribute(\"autofocus\") != null && hasFocus == document.body;\n }\n\n function save() {textarea.value = cm.getValue();}\n if (textarea.form) {\n on(textarea.form, \"submit\", save);\n // Deplorable hack to make the submit method do the right thing.\n if (!options.leaveSubmitMethodAlone) {\n var form = textarea.form, realSubmit = form.submit;\n try {\n var wrappedSubmit = form.submit = function() {\n save();\n form.submit = realSubmit;\n form.submit();\n form.submit = wrappedSubmit;\n };\n } catch(e) {}\n }\n }\n\n textarea.style.display = \"none\";\n var cm = CodeMirror(function(node) {\n textarea.parentNode.insertBefore(node, textarea.nextSibling);\n }, options);\n cm.save = save;\n cm.getTextArea = function() { return textarea; };\n cm.toTextArea = function() {\n cm.toTextArea = isNaN; // Prevent this from being ran twice\n save();\n textarea.parentNode.removeChild(cm.getWrapperElement());\n textarea.style.display = \"\";\n if (textarea.form) {\n off(textarea.form, \"submit\", save);\n if (typeof textarea.form.submit == \"function\")\n textarea.form.submit = realSubmit;\n }\n };\n return cm;\n };\n\n // STRING STREAM\n\n // Fed to the mode parsers, provides helper functions to make\n // parsers more succinct.\n\n var StringStream = CodeMirror.StringStream = function(string, tabSize) {\n this.pos = this.start = 0;\n this.string = string;\n this.tabSize = tabSize || 8;\n this.lastColumnPos = this.lastColumnValue = 0;\n this.lineStart = 0;\n };\n\n StringStream.prototype = {\n eol: function() {return this.pos >= this.string.length;},\n sol: function() {return this.pos == this.lineStart;},\n peek: function() {return this.string.charAt(this.pos) || undefined;},\n next: function() {\n if (this.pos < this.string.length)\n return this.string.charAt(this.pos++);\n },\n eat: function(match) {\n var ch = this.string.charAt(this.pos);\n if (typeof match == \"string\") var ok = ch == match;\n else var ok = ch && (match.test ? match.test(ch) : match(ch));\n if (ok) {++this.pos; return ch;}\n },\n eatWhile: function(match) {\n var start = this.pos;\n while (this.eat(match)){}\n return this.pos > start;\n },\n eatSpace: function() {\n var start = this.pos;\n while (/[\\s\\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;\n return this.pos > start;\n },\n skipToEnd: function() {this.pos = this.string.length;},\n skipTo: function(ch) {\n var found = this.string.indexOf(ch, this.pos);\n if (found > -1) {this.pos = found; return true;}\n },\n backUp: function(n) {this.pos -= n;},\n column: function() {\n if (this.lastColumnPos < this.start) {\n this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);\n this.lastColumnPos = this.start;\n }\n return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);\n },\n indentation: function() {\n return countColumn(this.string, null, this.tabSize) -\n (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);\n },\n match: function(pattern, consume, caseInsensitive) {\n if (typeof pattern == \"string\") {\n var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};\n var substr = this.string.substr(this.pos, pattern.length);\n if (cased(substr) == cased(pattern)) {\n if (consume !== false) this.pos += pattern.length;\n return true;\n }\n } else {\n var match = this.string.slice(this.pos).match(pattern);\n if (match && match.index > 0) return null;\n if (match && consume !== false) this.pos += match[0].length;\n return match;\n }\n },\n current: function(){return this.string.slice(this.start, this.pos);},\n hideFirstChars: function(n, inner) {\n this.lineStart += n;\n try { return inner(); }\n finally { this.lineStart -= n; }\n }\n };\n\n // TEXTMARKERS\n\n // Created with markText and setBookmark methods. A TextMarker is a\n // handle that can be used to clear or find a marked position in the\n // document. Line objects hold arrays (markedSpans) containing\n // {from, to, marker} object pointing to such marker objects, and\n // indicating that such a marker is present on that line. Multiple\n // lines may point to the same marker when it spans across lines.\n // The spans will have null for their from/to properties when the\n // marker continues beyond the start/end of the line. Markers have\n // links back to the lines they currently touch.\n\n var TextMarker = CodeMirror.TextMarker = function(doc, type) {\n this.lines = [];\n this.type = type;\n this.doc = doc;\n };\n eventMixin(TextMarker);\n\n // Clear the marker.\n TextMarker.prototype.clear = function() {\n if (this.explicitlyCleared) return;\n var cm = this.doc.cm, withOp = cm && !cm.curOp;\n if (withOp) startOperation(cm);\n if (hasHandler(this, \"clear\")) {\n var found = this.find();\n if (found) signalLater(this, \"clear\", found.from, found.to);\n }\n var min = null, max = null;\n for (var i = 0; i < this.lines.length; ++i) {\n var line = this.lines[i];\n var span = getMarkedSpanFor(line.markedSpans, this);\n if (cm && !this.collapsed) regLineChange(cm, lineNo(line), \"text\");\n else if (cm) {\n if (span.to != null) max = lineNo(line);\n if (span.from != null) min = lineNo(line);\n }\n line.markedSpans = removeMarkedSpan(line.markedSpans, span);\n if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)\n updateLineHeight(line, textHeight(cm.display));\n }\n if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {\n var visual = visualLine(this.lines[i]), len = lineLength(visual);\n if (len > cm.display.maxLineLength) {\n cm.display.maxLine = visual;\n cm.display.maxLineLength = len;\n cm.display.maxLineChanged = true;\n }\n }\n\n if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);\n this.lines.length = 0;\n this.explicitlyCleared = true;\n if (this.atomic && this.doc.cantEdit) {\n this.doc.cantEdit = false;\n if (cm) reCheckSelection(cm.doc);\n }\n if (cm) signalLater(cm, \"markerCleared\", cm, this);\n if (withOp) endOperation(cm);\n if (this.parent) this.parent.clear();\n };\n\n // Find the position of the marker in the document. Returns a {from,\n // to} object by default. Side can be passed to get a specific side\n // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the\n // Pos objects returned contain a line object, rather than a line\n // number (used to prevent looking up the same line twice).\n TextMarker.prototype.find = function(side, lineObj) {\n if (side == null && this.type == \"bookmark\") side = 1;\n var from, to;\n for (var i = 0; i < this.lines.length; ++i) {\n var line = this.lines[i];\n var span = getMarkedSpanFor(line.markedSpans, this);\n if (span.from != null) {\n from = Pos(lineObj ? line : lineNo(line), span.from);\n if (side == -1) return from;\n }\n if (span.to != null) {\n to = Pos(lineObj ? line : lineNo(line), span.to);\n if (side == 1) return to;\n }\n }\n return from && {from: from, to: to};\n };\n\n // Signals that the marker's widget changed, and surrounding layout\n // should be recomputed.\n TextMarker.prototype.changed = function() {\n var pos = this.find(-1, true), widget = this, cm = this.doc.cm;\n if (!pos || !cm) return;\n runInOp(cm, function() {\n var line = pos.line, lineN = lineNo(pos.line);\n var view = findViewForLine(cm, lineN);\n if (view) {\n clearLineMeasurementCacheFor(view);\n cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;\n }\n cm.curOp.updateMaxLine = true;\n if (!lineIsHidden(widget.doc, line) && widget.height != null) {\n var oldHeight = widget.height;\n widget.height = null;\n var dHeight = widgetHeight(widget) - oldHeight;\n if (dHeight)\n updateLineHeight(line, line.height + dHeight);\n }\n });\n };\n\n TextMarker.prototype.attachLine = function(line) {\n if (!this.lines.length && this.doc.cm) {\n var op = this.doc.cm.curOp;\n if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)\n (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);\n }\n this.lines.push(line);\n };\n TextMarker.prototype.detachLine = function(line) {\n this.lines.splice(indexOf(this.lines, line), 1);\n if (!this.lines.length && this.doc.cm) {\n var op = this.doc.cm.curOp;\n (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);\n }\n };\n\n // Collapsed markers have unique ids, in order to be able to order\n // them, which is needed for uniquely determining an outer marker\n // when they overlap (they may nest, but not partially overlap).\n var nextMarkerId = 0;\n\n // Create a marker, wire it up to the right lines, and\n function markText(doc, from, to, options, type) {\n // Shared markers (across linked documents) are handled separately\n // (markTextShared will call out to this again, once per\n // document).\n if (options && options.shared) return markTextShared(doc, from, to, options, type);\n // Ensure we are in an operation.\n if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);\n\n var marker = new TextMarker(doc, type), diff = cmp(from, to);\n if (options) copyObj(options, marker, false);\n // Don't connect empty markers unless clearWhenEmpty is false\n if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)\n return marker;\n if (marker.replacedWith) {\n // Showing up as a widget implies collapsed (widget replaces text)\n marker.collapsed = true;\n marker.widgetNode = elt(\"span\", [marker.replacedWith], \"CodeMirror-widget\");\n if (!options.handleMouseEvents) marker.widgetNode.setAttribute(\"cm-ignore-events\", \"true\");\n if (options.insertLeft) marker.widgetNode.insertLeft = true;\n }\n if (marker.collapsed) {\n if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||\n from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))\n throw new Error(\"Inserting collapsed marker partially overlapping an existing one\");\n sawCollapsedSpans = true;\n }\n\n if (marker.addToHistory)\n addChangeToHistory(doc, {from: from, to: to, origin: \"markText\"}, doc.sel, NaN);\n\n var curLine = from.line, cm = doc.cm, updateMaxLine;\n doc.iter(curLine, to.line + 1, function(line) {\n if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)\n updateMaxLine = true;\n if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);\n addMarkedSpan(line, new MarkedSpan(marker,\n curLine == from.line ? from.ch : null,\n curLine == to.line ? to.ch : null));\n ++curLine;\n });\n // lineIsHidden depends on the presence of the spans, so needs a second pass\n if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {\n if (lineIsHidden(doc, line)) updateLineHeight(line, 0);\n });\n\n if (marker.clearOnEnter) on(marker, \"beforeCursorEnter\", function() { marker.clear(); });\n\n if (marker.readOnly) {\n sawReadOnlySpans = true;\n if (doc.history.done.length || doc.history.undone.length)\n doc.clearHistory();\n }\n if (marker.collapsed) {\n marker.id = ++nextMarkerId;\n marker.atomic = true;\n }\n if (cm) {\n // Sync editor state\n if (updateMaxLine) cm.curOp.updateMaxLine = true;\n if (marker.collapsed)\n regChange(cm, from.line, to.line + 1);\n else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)\n for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, \"text\");\n if (marker.atomic) reCheckSelection(cm.doc);\n signalLater(cm, \"markerAdded\", cm, marker);\n }\n return marker;\n }\n\n // SHARED TEXTMARKERS\n\n // A shared marker spans multiple linked documents. It is\n // implemented as a meta-marker-object controlling multiple normal\n // markers.\n var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) {\n this.markers = markers;\n this.primary = primary;\n for (var i = 0; i < markers.length; ++i)\n markers[i].parent = this;\n };\n eventMixin(SharedTextMarker);\n\n SharedTextMarker.prototype.clear = function() {\n if (this.explicitlyCleared) return;\n this.explicitlyCleared = true;\n for (var i = 0; i < this.markers.length; ++i)\n this.markers[i].clear();\n signalLater(this, \"clear\");\n };\n SharedTextMarker.prototype.find = function(side, lineObj) {\n return this.primary.find(side, lineObj);\n };\n\n function markTextShared(doc, from, to, options, type) {\n options = copyObj(options);\n options.shared = false;\n var markers = [markText(doc, from, to, options, type)], primary = markers[0];\n var widget = options.widgetNode;\n linkedDocs(doc, function(doc) {\n if (widget) options.widgetNode = widget.cloneNode(true);\n markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));\n for (var i = 0; i < doc.linked.length; ++i)\n if (doc.linked[i].isParent) return;\n primary = lst(markers);\n });\n return new SharedTextMarker(markers, primary);\n }\n\n function findSharedMarkers(doc) {\n return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),\n function(m) { return m.parent; });\n }\n\n function copySharedMarkers(doc, markers) {\n for (var i = 0; i < markers.length; i++) {\n var marker = markers[i], pos = marker.find();\n var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);\n if (cmp(mFrom, mTo)) {\n var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);\n marker.markers.push(subMark);\n subMark.parent = marker;\n }\n }\n }\n\n function detachSharedMarkers(markers) {\n for (var i = 0; i < markers.length; i++) {\n var marker = markers[i], linked = [marker.primary.doc];;\n linkedDocs(marker.primary.doc, function(d) { linked.push(d); });\n for (var j = 0; j < marker.markers.length; j++) {\n var subMarker = marker.markers[j];\n if (indexOf(linked, subMarker.doc) == -1) {\n subMarker.parent = null;\n marker.markers.splice(j--, 1);\n }\n }\n }\n }\n\n // TEXTMARKER SPANS\n\n function MarkedSpan(marker, from, to) {\n this.marker = marker;\n this.from = from; this.to = to;\n }\n\n // Search an array of spans for a span matching the given marker.\n function getMarkedSpanFor(spans, marker) {\n if (spans) for (var i = 0; i < spans.length; ++i) {\n var span = spans[i];\n if (span.marker == marker) return span;\n }\n }\n // Remove a span from an array, returning undefined if no spans are\n // left (we don't store arrays for lines without spans).\n function removeMarkedSpan(spans, span) {\n for (var r, i = 0; i < spans.length; ++i)\n if (spans[i] != span) (r || (r = [])).push(spans[i]);\n return r;\n }\n // Add a span to a line.\n function addMarkedSpan(line, span) {\n line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];\n span.marker.attachLine(line);\n }\n\n // Used for the algorithm that adjusts markers for a change in the\n // document. These functions cut an array of spans at a given\n // character position, returning an array of remaining chunks (or\n // undefined if nothing remains).\n function markedSpansBefore(old, startCh, isInsert) {\n if (old) for (var i = 0, nw; i < old.length; ++i) {\n var span = old[i], marker = span.marker;\n var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);\n if (startsBefore || span.from == startCh && marker.type == \"bookmark\" && (!isInsert || !span.marker.insertLeft)) {\n var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);\n (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));\n }\n }\n return nw;\n }\n function markedSpansAfter(old, endCh, isInsert) {\n if (old) for (var i = 0, nw; i < old.length; ++i) {\n var span = old[i], marker = span.marker;\n var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);\n if (endsAfter || span.from == endCh && marker.type == \"bookmark\" && (!isInsert || span.marker.insertLeft)) {\n var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);\n (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,\n span.to == null ? null : span.to - endCh));\n }\n }\n return nw;\n }\n\n // Given a change object, compute the new set of marker spans that\n // cover the line in which the change took place. Removes spans\n // entirely within the change, reconnects spans belonging to the\n // same marker that appear on both sides of the change, and cuts off\n // spans partially within the change. Returns an array of span\n // arrays with one element for each line in (after) the change.\n function stretchSpansOverChange(doc, change) {\n if (change.full) return null;\n var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;\n var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;\n if (!oldFirst && !oldLast) return null;\n\n var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;\n // Get the spans that 'stick out' on both sides\n var first = markedSpansBefore(oldFirst, startCh, isInsert);\n var last = markedSpansAfter(oldLast, endCh, isInsert);\n\n // Next, merge those two ends\n var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);\n if (first) {\n // Fix up .to properties of first\n for (var i = 0; i < first.length; ++i) {\n var span = first[i];\n if (span.to == null) {\n var found = getMarkedSpanFor(last, span.marker);\n if (!found) span.to = startCh;\n else if (sameLine) span.to = found.to == null ? null : found.to + offset;\n }\n }\n }\n if (last) {\n // Fix up .from in last (or move them into first in case of sameLine)\n for (var i = 0; i < last.length; ++i) {\n var span = last[i];\n if (span.to != null) span.to += offset;\n if (span.from == null) {\n var found = getMarkedSpanFor(first, span.marker);\n if (!found) {\n span.from = offset;\n if (sameLine) (first || (first = [])).push(span);\n }\n } else {\n span.from += offset;\n if (sameLine) (first || (first = [])).push(span);\n }\n }\n }\n // Make sure we didn't create any zero-length spans\n if (first) first = clearEmptySpans(first);\n if (last && last != first) last = clearEmptySpans(last);\n\n var newMarkers = [first];\n if (!sameLine) {\n // Fill gap with whole-line-spans\n var gap = change.text.length - 2, gapMarkers;\n if (gap > 0 && first)\n for (var i = 0; i < first.length; ++i)\n if (first[i].to == null)\n (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));\n for (var i = 0; i < gap; ++i)\n newMarkers.push(gapMarkers);\n newMarkers.push(last);\n }\n return newMarkers;\n }\n\n // Remove spans that are empty and don't have a clearWhenEmpty\n // option of false.\n function clearEmptySpans(spans) {\n for (var i = 0; i < spans.length; ++i) {\n var span = spans[i];\n if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)\n spans.splice(i--, 1);\n }\n if (!spans.length) return null;\n return spans;\n }\n\n // Used for un/re-doing changes from the history. Combines the\n // result of computing the existing spans with the set of spans that\n // existed in the history (so that deleting around a span and then\n // undoing brings back the span).\n function mergeOldSpans(doc, change) {\n var old = getOldSpans(doc, change);\n var stretched = stretchSpansOverChange(doc, change);\n if (!old) return stretched;\n if (!stretched) return old;\n\n for (var i = 0; i < old.length; ++i) {\n var oldCur = old[i], stretchCur = stretched[i];\n if (oldCur && stretchCur) {\n spans: for (var j = 0; j < stretchCur.length; ++j) {\n var span = stretchCur[j];\n for (var k = 0; k < oldCur.length; ++k)\n if (oldCur[k].marker == span.marker) continue spans;\n oldCur.push(span);\n }\n } else if (stretchCur) {\n old[i] = stretchCur;\n }\n }\n return old;\n }\n\n // Used to 'clip' out readOnly ranges when making a change.\n function removeReadOnlyRanges(doc, from, to) {\n var markers = null;\n doc.iter(from.line, to.line + 1, function(line) {\n if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {\n var mark = line.markedSpans[i].marker;\n if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))\n (markers || (markers = [])).push(mark);\n }\n });\n if (!markers) return null;\n var parts = [{from: from, to: to}];\n for (var i = 0; i < markers.length; ++i) {\n var mk = markers[i], m = mk.find(0);\n for (var j = 0; j < parts.length; ++j) {\n var p = parts[j];\n if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue;\n var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);\n if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)\n newParts.push({from: p.from, to: m.from});\n if (dto > 0 || !mk.inclusiveRight && !dto)\n newParts.push({from: m.to, to: p.to});\n parts.splice.apply(parts, newParts);\n j += newParts.length - 1;\n }\n }\n return parts;\n }\n\n // Connect or disconnect spans from a line.\n function detachMarkedSpans(line) {\n var spans = line.markedSpans;\n if (!spans) return;\n for (var i = 0; i < spans.length; ++i)\n spans[i].marker.detachLine(line);\n line.markedSpans = null;\n }\n function attachMarkedSpans(line, spans) {\n if (!spans) return;\n for (var i = 0; i < spans.length; ++i)\n spans[i].marker.attachLine(line);\n line.markedSpans = spans;\n }\n\n // Helpers used when computing which overlapping collapsed span\n // counts as the larger one.\n function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }\n function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }\n\n // Returns a number indicating which of two overlapping collapsed\n // spans is larger (and thus includes the other). Falls back to\n // comparing ids when the spans cover exactly the same range.\n function compareCollapsedMarkers(a, b) {\n var lenDiff = a.lines.length - b.lines.length;\n if (lenDiff != 0) return lenDiff;\n var aPos = a.find(), bPos = b.find();\n var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);\n if (fromCmp) return -fromCmp;\n var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);\n if (toCmp) return toCmp;\n return b.id - a.id;\n }\n\n // Find out whether a line ends or starts in a collapsed span. If\n // so, return the marker for that span.\n function collapsedSpanAtSide(line, start) {\n var sps = sawCollapsedSpans && line.markedSpans, found;\n if (sps) for (var sp, i = 0; i < sps.length; ++i) {\n sp = sps[i];\n if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&\n (!found || compareCollapsedMarkers(found, sp.marker) < 0))\n found = sp.marker;\n }\n return found;\n }\n function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }\n function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }\n\n // Test whether there exists a collapsed span that partially\n // overlaps (covers the start or end, but not both) of a new span.\n // Such overlap is not allowed.\n function conflictingCollapsedRange(doc, lineNo, from, to, marker) {\n var line = getLine(doc, lineNo);\n var sps = sawCollapsedSpans && line.markedSpans;\n if (sps) for (var i = 0; i < sps.length; ++i) {\n var sp = sps[i];\n if (!sp.marker.collapsed) continue;\n var found = sp.marker.find(0);\n var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);\n var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);\n if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue;\n if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) ||\n fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight)))\n return true;\n }\n }\n\n // A visual line is a line as drawn on the screen. Folding, for\n // example, can cause multiple logical lines to appear on the same\n // visual line. This finds the start of the visual line that the\n // given line is part of (usually that is the line itself).\n function visualLine(line) {\n var merged;\n while (merged = collapsedSpanAtStart(line))\n line = merged.find(-1, true).line;\n return line;\n }\n\n // Returns an array of logical lines that continue the visual line\n // started by the argument, or undefined if there are no such lines.\n function visualLineContinued(line) {\n var merged, lines;\n while (merged = collapsedSpanAtEnd(line)) {\n line = merged.find(1, true).line;\n (lines || (lines = [])).push(line);\n }\n return lines;\n }\n\n // Get the line number of the start of the visual line that the\n // given line number is part of.\n function visualLineNo(doc, lineN) {\n var line = getLine(doc, lineN), vis = visualLine(line);\n if (line == vis) return lineN;\n return lineNo(vis);\n }\n // Get the line number of the start of the next visual line after\n // the given line.\n function visualLineEndNo(doc, lineN) {\n if (lineN > doc.lastLine()) return lineN;\n var line = getLine(doc, lineN), merged;\n if (!lineIsHidden(doc, line)) return lineN;\n while (merged = collapsedSpanAtEnd(line))\n line = merged.find(1, true).line;\n return lineNo(line) + 1;\n }\n\n // Compute whether a line is hidden. Lines count as hidden when they\n // are part of a visual line that starts with another line, or when\n // they are entirely covered by collapsed, non-widget span.\n function lineIsHidden(doc, line) {\n var sps = sawCollapsedSpans && line.markedSpans;\n if (sps) for (var sp, i = 0; i < sps.length; ++i) {\n sp = sps[i];\n if (!sp.marker.collapsed) continue;\n if (sp.from == null) return true;\n if (sp.marker.widgetNode) continue;\n if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))\n return true;\n }\n }\n function lineIsHiddenInner(doc, line, span) {\n if (span.to == null) {\n var end = span.marker.find(1, true);\n return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker));\n }\n if (span.marker.inclusiveRight && span.to == line.text.length)\n return true;\n for (var sp, i = 0; i < line.markedSpans.length; ++i) {\n sp = line.markedSpans[i];\n if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&\n (sp.to == null || sp.to != span.from) &&\n (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&\n lineIsHiddenInner(doc, line, sp)) return true;\n }\n }\n\n // LINE WIDGETS\n\n // Line widgets are block elements displayed above or below a line.\n\n var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {\n if (options) for (var opt in options) if (options.hasOwnProperty(opt))\n this[opt] = options[opt];\n this.cm = cm;\n this.node = node;\n };\n eventMixin(LineWidget);\n\n function adjustScrollWhenAboveVisible(cm, line, diff) {\n if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))\n addToScrollPos(cm, null, diff);\n }\n\n LineWidget.prototype.clear = function() {\n var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);\n if (no == null || !ws) return;\n for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);\n if (!ws.length) line.widgets = null;\n var height = widgetHeight(this);\n runInOp(cm, function() {\n adjustScrollWhenAboveVisible(cm, line, -height);\n regLineChange(cm, no, \"widget\");\n updateLineHeight(line, Math.max(0, line.height - height));\n });\n };\n LineWidget.prototype.changed = function() {\n var oldH = this.height, cm = this.cm, line = this.line;\n this.height = null;\n var diff = widgetHeight(this) - oldH;\n if (!diff) return;\n runInOp(cm, function() {\n cm.curOp.forceUpdate = true;\n adjustScrollWhenAboveVisible(cm, line, diff);\n updateLineHeight(line, line.height + diff);\n });\n };\n\n function widgetHeight(widget) {\n if (widget.height != null) return widget.height;\n if (!contains(document.body, widget.node)) {\n var parentStyle = \"position: relative;\";\n if (widget.coverGutter)\n parentStyle += \"margin-left: -\" + widget.cm.display.gutters.offsetWidth + \"px;\";\n if (widget.noHScroll)\n parentStyle += \"width: \" + widget.cm.display.wrapper.clientWidth + \"px;\";\n removeChildrenAndAdd(widget.cm.display.measure, elt(\"div\", [widget.node], null, parentStyle));\n }\n return widget.height = widget.node.offsetHeight;\n }\n\n function addLineWidget(cm, handle, node, options) {\n var widget = new LineWidget(cm, node, options);\n if (widget.noHScroll) cm.display.alignWidgets = true;\n changeLine(cm.doc, handle, \"widget\", function(line) {\n var widgets = line.widgets || (line.widgets = []);\n if (widget.insertAt == null) widgets.push(widget);\n else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);\n widget.line = line;\n if (!lineIsHidden(cm.doc, line)) {\n var aboveVisible = heightAtLine(line) < cm.doc.scrollTop;\n updateLineHeight(line, line.height + widgetHeight(widget));\n if (aboveVisible) addToScrollPos(cm, null, widget.height);\n cm.curOp.forceUpdate = true;\n }\n return true;\n });\n return widget;\n }\n\n // LINE DATA STRUCTURE\n\n // Line objects. These hold state related to a line, including\n // highlighting info (the styles array).\n var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {\n this.text = text;\n attachMarkedSpans(this, markedSpans);\n this.height = estimateHeight ? estimateHeight(this) : 1;\n };\n eventMixin(Line);\n Line.prototype.lineNo = function() { return lineNo(this); };\n\n // Change the content (text, markers) of a line. Automatically\n // invalidates cached information and tries to re-estimate the\n // line's height.\n function updateLine(line, text, markedSpans, estimateHeight) {\n line.text = text;\n if (line.stateAfter) line.stateAfter = null;\n if (line.styles) line.styles = null;\n if (line.order != null) line.order = null;\n detachMarkedSpans(line);\n attachMarkedSpans(line, markedSpans);\n var estHeight = estimateHeight ? estimateHeight(line) : 1;\n if (estHeight != line.height) updateLineHeight(line, estHeight);\n }\n\n // Detach a line from the document tree and its markers.\n function cleanUpLine(line) {\n line.parent = null;\n detachMarkedSpans(line);\n }\n\n function extractLineClasses(type, output) {\n if (type) for (;;) {\n var lineClass = type.match(/(?:^|\\s+)line-(background-)?(\\S+)/);\n if (!lineClass) break;\n type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);\n var prop = lineClass[1] ? \"bgClass\" : \"textClass\";\n if (output[prop] == null)\n output[prop] = lineClass[2];\n else if (!(new RegExp(\"(?:^|\\s)\" + lineClass[2] + \"(?:$|\\s)\")).test(output[prop]))\n output[prop] += \" \" + lineClass[2];\n }\n return type;\n }\n\n function callBlankLine(mode, state) {\n if (mode.blankLine) return mode.blankLine(state);\n if (!mode.innerMode) return;\n var inner = CodeMirror.innerMode(mode, state);\n if (inner.mode.blankLine) return inner.mode.blankLine(inner.state);\n }\n\n function readToken(mode, stream, state, inner) {\n for (var i = 0; i < 10; i++) {\n if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode;\n var style = mode.token(stream, state);\n if (stream.pos > stream.start) return style;\n }\n throw new Error(\"Mode \" + mode.name + \" failed to advance stream.\");\n }\n\n // Utility for getTokenAt and getLineTokens\n function takeToken(cm, pos, precise, asArray) {\n function getObj(copy) {\n return {start: stream.start, end: stream.pos,\n string: stream.current(),\n type: style || null,\n state: copy ? copyState(doc.mode, state) : state};\n }\n\n var doc = cm.doc, mode = doc.mode, style;\n pos = clipPos(doc, pos);\n var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise);\n var stream = new StringStream(line.text, cm.options.tabSize), tokens;\n if (asArray) tokens = [];\n while ((asArray || stream.pos < pos.ch) && !stream.eol()) {\n stream.start = stream.pos;\n style = readToken(mode, stream, state);\n if (asArray) tokens.push(getObj(true));\n }\n return asArray ? tokens : getObj();\n }\n\n // Run the given mode's parser over a line, calling f for each token.\n function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {\n var flattenSpans = mode.flattenSpans;\n if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;\n var curStart = 0, curStyle = null;\n var stream = new StringStream(text, cm.options.tabSize), style;\n var inner = cm.options.addModeClass && [null];\n if (text == \"\") extractLineClasses(callBlankLine(mode, state), lineClasses);\n while (!stream.eol()) {\n if (stream.pos > cm.options.maxHighlightLength) {\n flattenSpans = false;\n if (forceToEnd) processLine(cm, text, state, stream.pos);\n stream.pos = text.length;\n style = null;\n } else {\n style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses);\n }\n if (inner) {\n var mName = inner[0].name;\n if (mName) style = \"m-\" + (style ? mName + \" \" + style : mName);\n }\n if (!flattenSpans || curStyle != style) {\n while (curStart < stream.start) {\n curStart = Math.min(stream.start, curStart + 50000);\n f(curStart, curStyle);\n }\n curStyle = style;\n }\n stream.start = stream.pos;\n }\n while (curStart < stream.pos) {\n // Webkit seems to refuse to render text nodes longer than 57444 characters\n var pos = Math.min(stream.pos, curStart + 50000);\n f(pos, curStyle);\n curStart = pos;\n }\n }\n\n // Compute a style array (an array starting with a mode generation\n // -- for invalidation -- followed by pairs of end positions and\n // style strings), which is used to highlight the tokens on the\n // line.\n function highlightLine(cm, line, state, forceToEnd) {\n // A styles array always starts with a number identifying the\n // mode/overlays that it is based on (for easy invalidation).\n var st = [cm.state.modeGen], lineClasses = {};\n // Compute the base array of styles\n runMode(cm, line.text, cm.doc.mode, state, function(end, style) {\n st.push(end, style);\n }, lineClasses, forceToEnd);\n\n // Run overlays, adjust style array.\n for (var o = 0; o < cm.state.overlays.length; ++o) {\n var overlay = cm.state.overlays[o], i = 1, at = 0;\n runMode(cm, line.text, overlay.mode, true, function(end, style) {\n var start = i;\n // Ensure there's a token end at the current position, and that i points at it\n while (at < end) {\n var i_end = st[i];\n if (i_end > end)\n st.splice(i, 1, end, st[i+1], i_end);\n i += 2;\n at = Math.min(end, i_end);\n }\n if (!style) return;\n if (overlay.opaque) {\n st.splice(start, i - start, end, \"cm-overlay \" + style);\n i = start + 2;\n } else {\n for (; start < i; start += 2) {\n var cur = st[start+1];\n st[start+1] = (cur ? cur + \" \" : \"\") + \"cm-overlay \" + style;\n }\n }\n }, lineClasses);\n }\n\n return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null};\n }\n\n function getLineStyles(cm, line, updateFrontier) {\n if (!line.styles || line.styles[0] != cm.state.modeGen) {\n var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));\n line.styles = result.styles;\n if (result.classes) line.styleClasses = result.classes;\n else if (line.styleClasses) line.styleClasses = null;\n if (updateFrontier === cm.doc.frontier) cm.doc.frontier++;\n }\n return line.styles;\n }\n\n // Lightweight form of highlight -- proceed over this line and\n // update state, but don't save a style array. Used for lines that\n // aren't currently visible.\n function processLine(cm, text, state, startAt) {\n var mode = cm.doc.mode;\n var stream = new StringStream(text, cm.options.tabSize);\n stream.start = stream.pos = startAt || 0;\n if (text == \"\") callBlankLine(mode, state);\n while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {\n readToken(mode, stream, state);\n stream.start = stream.pos;\n }\n }\n\n // Convert a style as returned by a mode (either null, or a string\n // containing one or more styles) to a CSS style. This is cached,\n // and also looks for line-wide styles.\n var styleToClassCache = {}, styleToClassCacheWithMode = {};\n function interpretTokenStyle(style, options) {\n if (!style || /^\\s*$/.test(style)) return null;\n var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;\n return cache[style] ||\n (cache[style] = style.replace(/\\S+/g, \"cm-$&\"));\n }\n\n // Render the DOM representation of the text of a line. Also builds\n // up a 'line map', which points at the DOM nodes that represent\n // specific stretches of text, and is used by the measuring code.\n // The returned object contains the DOM node, this map, and\n // information about line-wide styles that were set by the mode.\n function buildLineContent(cm, lineView) {\n // The padding-right forces the element to have a 'border', which\n // is needed on Webkit to be able to get line-level bounding\n // rectangles for it (in measureChar).\n var content = elt(\"span\", null, null, webkit ? \"padding-right: .1px\" : null);\n var builder = {pre: elt(\"pre\", [content]), content: content, col: 0, pos: 0, cm: cm};\n lineView.measure = {};\n\n // Iterate over the logical lines that make up this visual line.\n for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {\n var line = i ? lineView.rest[i - 1] : lineView.line, order;\n builder.pos = 0;\n builder.addToken = buildToken;\n // Optionally wire in some hacks into the token-rendering\n // algorithm, to deal with browser quirks.\n if ((ie || webkit) && cm.getOption(\"lineWrapping\"))\n builder.addToken = buildTokenSplitSpaces(builder.addToken);\n if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))\n builder.addToken = buildTokenBadBidi(builder.addToken, order);\n builder.map = [];\n var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);\n insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));\n if (line.styleClasses) {\n if (line.styleClasses.bgClass)\n builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || \"\");\n if (line.styleClasses.textClass)\n builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || \"\");\n }\n\n // Ensure at least a single node is present, for measuring.\n if (builder.map.length == 0)\n builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure)));\n\n // Store the map and a cache object for the current logical line\n if (i == 0) {\n lineView.measure.map = builder.map;\n lineView.measure.cache = {};\n } else {\n (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map);\n (lineView.measure.caches || (lineView.measure.caches = [])).push({});\n }\n }\n\n // See issue #2901\n if (webkit && /\\bcm-tab\\b/.test(builder.content.lastChild.className))\n builder.content.className = \"cm-tab-wrap-hack\";\n\n signal(cm, \"renderLine\", cm, lineView.line, builder.pre);\n if (builder.pre.className)\n builder.textClass = joinClasses(builder.pre.className, builder.textClass || \"\");\n\n return builder;\n }\n\n function defaultSpecialCharPlaceholder(ch) {\n var token = elt(\"span\", \"\\u2022\", \"cm-invalidchar\");\n token.title = \"\\\\u\" + ch.charCodeAt(0).toString(16);\n return token;\n }\n\n // Build up the DOM representation for a single token, and add it to\n // the line map. Takes care to render special characters separately.\n function buildToken(builder, text, style, startStyle, endStyle, title, css) {\n if (!text) return;\n var special = builder.cm.options.specialChars, mustWrap = false;\n if (!special.test(text)) {\n builder.col += text.length;\n var content = document.createTextNode(text);\n builder.map.push(builder.pos, builder.pos + text.length, content);\n if (ie && ie_version < 9) mustWrap = true;\n builder.pos += text.length;\n } else {\n var content = document.createDocumentFragment(), pos = 0;\n while (true) {\n special.lastIndex = pos;\n var m = special.exec(text);\n var skipped = m ? m.index - pos : text.length - pos;\n if (skipped) {\n var txt = document.createTextNode(text.slice(pos, pos + skipped));\n if (ie && ie_version < 9) content.appendChild(elt(\"span\", [txt]));\n else content.appendChild(txt);\n builder.map.push(builder.pos, builder.pos + skipped, txt);\n builder.col += skipped;\n builder.pos += skipped;\n }\n if (!m) break;\n pos += skipped + 1;\n if (m[0] == \"\\t\") {\n var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;\n var txt = content.appendChild(elt(\"span\", spaceStr(tabWidth), \"cm-tab\"));\n builder.col += tabWidth;\n } else {\n var txt = builder.cm.options.specialCharPlaceholder(m[0]);\n if (ie && ie_version < 9) content.appendChild(elt(\"span\", [txt]));\n else content.appendChild(txt);\n builder.col += 1;\n }\n builder.map.push(builder.pos, builder.pos + 1, txt);\n builder.pos++;\n }\n }\n if (style || startStyle || endStyle || mustWrap || css) {\n var fullStyle = style || \"\";\n if (startStyle) fullStyle += startStyle;\n if (endStyle) fullStyle += endStyle;\n var token = elt(\"span\", [content], fullStyle, css);\n if (title) token.title = title;\n return builder.content.appendChild(token);\n }\n builder.content.appendChild(content);\n }\n\n function buildTokenSplitSpaces(inner) {\n function split(old) {\n var out = \" \";\n for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? \" \" : \"\\u00a0\";\n out += \" \";\n return out;\n }\n return function(builder, text, style, startStyle, endStyle, title) {\n inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title);\n };\n }\n\n // Work around nonsense dimensions being reported for stretches of\n // right-to-left text.\n function buildTokenBadBidi(inner, order) {\n return function(builder, text, style, startStyle, endStyle, title) {\n style = style ? style + \" cm-force-border\" : \"cm-force-border\";\n var start = builder.pos, end = start + text.length;\n for (;;) {\n // Find the part that overlaps with the start of this text\n for (var i = 0; i < order.length; i++) {\n var part = order[i];\n if (part.to > start && part.from <= start) break;\n }\n if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title);\n inner(builder, text.slice(0, part.to - start), style, startStyle, null, title);\n startStyle = null;\n text = text.slice(part.to - start);\n start = part.to;\n }\n };\n }\n\n function buildCollapsedSpan(builder, size, marker, ignoreWidget) {\n var widget = !ignoreWidget && marker.widgetNode;\n if (widget) {\n builder.map.push(builder.pos, builder.pos + size, widget);\n builder.content.appendChild(widget);\n }\n builder.pos += size;\n }\n\n // Outputs a number of spans to make up a line, taking highlighting\n // and marked text into account.\n function insertLineContent(line, builder, styles) {\n var spans = line.markedSpans, allText = line.text, at = 0;\n if (!spans) {\n for (var i = 1; i < styles.length; i+=2)\n builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options));\n return;\n }\n\n var len = allText.length, pos = 0, i = 1, text = \"\", style, css;\n var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;\n for (;;) {\n if (nextChange == pos) { // Update current marker set\n spanStyle = spanEndStyle = spanStartStyle = title = css = \"\";\n collapsed = null; nextChange = Infinity;\n var foundBookmarks = [];\n for (var j = 0; j < spans.length; ++j) {\n var sp = spans[j], m = sp.marker;\n if (sp.from <= pos && (sp.to == null || sp.to > pos)) {\n if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = \"\"; }\n if (m.className) spanStyle += \" \" + m.className;\n if (m.css) css = m.css;\n if (m.startStyle && sp.from == pos) spanStartStyle += \" \" + m.startStyle;\n if (m.endStyle && sp.to == nextChange) spanEndStyle += \" \" + m.endStyle;\n if (m.title && !title) title = m.title;\n if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))\n collapsed = sp;\n } else if (sp.from > pos && nextChange > sp.from) {\n nextChange = sp.from;\n }\n if (m.type == \"bookmark\" && sp.from == pos && m.widgetNode) foundBookmarks.push(m);\n }\n if (collapsed && (collapsed.from || 0) == pos) {\n buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,\n collapsed.marker, collapsed.from == null);\n if (collapsed.to == null) return;\n }\n if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)\n buildCollapsedSpan(builder, 0, foundBookmarks[j]);\n }\n if (pos >= len) break;\n\n var upto = Math.min(len, nextChange);\n while (true) {\n if (text) {\n var end = pos + text.length;\n if (!collapsed) {\n var tokenText = end > upto ? text.slice(0, upto - pos) : text;\n builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,\n spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : \"\", title, css);\n }\n if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}\n pos = end;\n spanStartStyle = \"\";\n }\n text = allText.slice(at, at = styles[i++]);\n style = interpretTokenStyle(styles[i++], builder.cm.options);\n }\n }\n }\n\n // DOCUMENT DATA STRUCTURE\n\n // By default, updates that start and end at the beginning of a line\n // are treated specially, in order to make the association of line\n // widgets and marker elements with the text behave more intuitive.\n function isWholeLineUpdate(doc, change) {\n return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == \"\" &&\n (!doc.cm || doc.cm.options.wholeLineUpdateBefore);\n }\n\n // Perform a change on the document data structure.\n function updateDoc(doc, change, markedSpans, estimateHeight) {\n function spansFor(n) {return markedSpans ? markedSpans[n] : null;}\n function update(line, text, spans) {\n updateLine(line, text, spans, estimateHeight);\n signalLater(line, \"change\", line, change);\n }\n function linesFor(start, end) {\n for (var i = start, result = []; i < end; ++i)\n result.push(new Line(text[i], spansFor(i), estimateHeight));\n return result;\n }\n\n var from = change.from, to = change.to, text = change.text;\n var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);\n var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;\n\n // Adjust the line structure\n if (change.full) {\n doc.insert(0, linesFor(0, text.length));\n doc.remove(text.length, doc.size - text.length);\n } else if (isWholeLineUpdate(doc, change)) {\n // This is a whole-line replace. Treated specially to make\n // sure line objects move the way they are supposed to.\n var added = linesFor(0, text.length - 1);\n update(lastLine, lastLine.text, lastSpans);\n if (nlines) doc.remove(from.line, nlines);\n if (added.length) doc.insert(from.line, added);\n } else if (firstLine == lastLine) {\n if (text.length == 1) {\n update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);\n } else {\n var added = linesFor(1, text.length - 1);\n added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));\n update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));\n doc.insert(from.line + 1, added);\n }\n } else if (text.length == 1) {\n update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));\n doc.remove(from.line + 1, nlines);\n } else {\n update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));\n update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);\n var added = linesFor(1, text.length - 1);\n if (nlines > 1) doc.remove(from.line + 1, nlines - 1);\n doc.insert(from.line + 1, added);\n }\n\n signalLater(doc, \"change\", doc, change);\n }\n\n // The document is represented as a BTree consisting of leaves, with\n // chunk of lines in them, and branches, with up to ten leaves or\n // other branch nodes below them. The top node is always a branch\n // node, and is the document object itself (meaning it has\n // additional methods and properties).\n //\n // All nodes have parent links. The tree is used both to go from\n // line numbers to line objects, and to go from objects to numbers.\n // It also indexes by height, and is used to convert between height\n // and line object, and to find the total height of the document.\n //\n // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html\n\n function LeafChunk(lines) {\n this.lines = lines;\n this.parent = null;\n for (var i = 0, height = 0; i < lines.length; ++i) {\n lines[i].parent = this;\n height += lines[i].height;\n }\n this.height = height;\n }\n\n LeafChunk.prototype = {\n chunkSize: function() { return this.lines.length; },\n // Remove the n lines at offset 'at'.\n removeInner: function(at, n) {\n for (var i = at, e = at + n; i < e; ++i) {\n var line = this.lines[i];\n this.height -= line.height;\n cleanUpLine(line);\n signalLater(line, \"delete\");\n }\n this.lines.splice(at, n);\n },\n // Helper used to collapse a small branch into a single leaf.\n collapse: function(lines) {\n lines.push.apply(lines, this.lines);\n },\n // Insert the given array of lines at offset 'at', count them as\n // having the given height.\n insertInner: function(at, lines, height) {\n this.height += height;\n this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));\n for (var i = 0; i < lines.length; ++i) lines[i].parent = this;\n },\n // Used to iterate over a part of the tree.\n iterN: function(at, n, op) {\n for (var e = at + n; at < e; ++at)\n if (op(this.lines[at])) return true;\n }\n };\n\n function BranchChunk(children) {\n this.children = children;\n var size = 0, height = 0;\n for (var i = 0; i < children.length; ++i) {\n var ch = children[i];\n size += ch.chunkSize(); height += ch.height;\n ch.parent = this;\n }\n this.size = size;\n this.height = height;\n this.parent = null;\n }\n\n BranchChunk.prototype = {\n chunkSize: function() { return this.size; },\n removeInner: function(at, n) {\n this.size -= n;\n for (var i = 0; i < this.children.length; ++i) {\n var child = this.children[i], sz = child.chunkSize();\n if (at < sz) {\n var rm = Math.min(n, sz - at), oldHeight = child.height;\n child.removeInner(at, rm);\n this.height -= oldHeight - child.height;\n if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }\n if ((n -= rm) == 0) break;\n at = 0;\n } else at -= sz;\n }\n // If the result is smaller than 25 lines, ensure that it is a\n // single leaf node.\n if (this.size - n < 25 &&\n (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {\n var lines = [];\n this.collapse(lines);\n this.children = [new LeafChunk(lines)];\n this.children[0].parent = this;\n }\n },\n collapse: function(lines) {\n for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines);\n },\n insertInner: function(at, lines, height) {\n this.size += lines.length;\n this.height += height;\n for (var i = 0; i < this.children.length; ++i) {\n var child = this.children[i], sz = child.chunkSize();\n if (at <= sz) {\n child.insertInner(at, lines, height);\n if (child.lines && child.lines.length > 50) {\n while (child.lines.length > 50) {\n var spilled = child.lines.splice(child.lines.length - 25, 25);\n var newleaf = new LeafChunk(spilled);\n child.height -= newleaf.height;\n this.children.splice(i + 1, 0, newleaf);\n newleaf.parent = this;\n }\n this.maybeSpill();\n }\n break;\n }\n at -= sz;\n }\n },\n // When a node has grown, check whether it should be split.\n maybeSpill: function() {\n if (this.children.length <= 10) return;\n var me = this;\n do {\n var spilled = me.children.splice(me.children.length - 5, 5);\n var sibling = new BranchChunk(spilled);\n if (!me.parent) { // Become the parent node\n var copy = new BranchChunk(me.children);\n copy.parent = me;\n me.children = [copy, sibling];\n me = copy;\n } else {\n me.size -= sibling.size;\n me.height -= sibling.height;\n var myIndex = indexOf(me.parent.children, me);\n me.parent.children.splice(myIndex + 1, 0, sibling);\n }\n sibling.parent = me.parent;\n } while (me.children.length > 10);\n me.parent.maybeSpill();\n },\n iterN: function(at, n, op) {\n for (var i = 0; i < this.children.length; ++i) {\n var child = this.children[i], sz = child.chunkSize();\n if (at < sz) {\n var used = Math.min(n, sz - at);\n if (child.iterN(at, used, op)) return true;\n if ((n -= used) == 0) break;\n at = 0;\n } else at -= sz;\n }\n }\n };\n\n var nextDocId = 0;\n var Doc = CodeMirror.Doc = function(text, mode, firstLine) {\n if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);\n if (firstLine == null) firstLine = 0;\n\n BranchChunk.call(this, [new LeafChunk([new Line(\"\", null)])]);\n this.first = firstLine;\n this.scrollTop = this.scrollLeft = 0;\n this.cantEdit = false;\n this.cleanGeneration = 1;\n this.frontier = firstLine;\n var start = Pos(firstLine, 0);\n this.sel = simpleSelection(start);\n this.history = new History(null);\n this.id = ++nextDocId;\n this.modeOption = mode;\n\n if (typeof text == \"string\") text = splitLines(text);\n updateDoc(this, {from: start, to: start, text: text});\n setSelection(this, simpleSelection(start), sel_dontScroll);\n };\n\n Doc.prototype = createObj(BranchChunk.prototype, {\n constructor: Doc,\n // Iterate over the document. Supports two forms -- with only one\n // argument, it calls that for each line in the document. With\n // three, it iterates over the range given by the first two (with\n // the second being non-inclusive).\n iter: function(from, to, op) {\n if (op) this.iterN(from - this.first, to - from, op);\n else this.iterN(this.first, this.first + this.size, from);\n },\n\n // Non-public interface for adding and removing lines.\n insert: function(at, lines) {\n var height = 0;\n for (var i = 0; i < lines.length; ++i) height += lines[i].height;\n this.insertInner(at - this.first, lines, height);\n },\n remove: function(at, n) { this.removeInner(at - this.first, n); },\n\n // From here, the methods are part of the public interface. Most\n // are also available from CodeMirror (editor) instances.\n\n getValue: function(lineSep) {\n var lines = getLines(this, this.first, this.first + this.size);\n if (lineSep === false) return lines;\n return lines.join(lineSep || \"\\n\");\n },\n setValue: docMethodOp(function(code) {\n var top = Pos(this.first, 0), last = this.first + this.size - 1;\n makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),\n text: splitLines(code), origin: \"setValue\", full: true}, true);\n setSelection(this, simpleSelection(top));\n }),\n replaceRange: function(code, from, to, origin) {\n from = clipPos(this, from);\n to = to ? clipPos(this, to) : from;\n replaceRange(this, code, from, to, origin);\n },\n getRange: function(from, to, lineSep) {\n var lines = getBetween(this, clipPos(this, from), clipPos(this, to));\n if (lineSep === false) return lines;\n return lines.join(lineSep || \"\\n\");\n },\n\n getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},\n\n getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},\n getLineNumber: function(line) {return lineNo(line);},\n\n getLineHandleVisualStart: function(line) {\n if (typeof line == \"number\") line = getLine(this, line);\n return visualLine(line);\n },\n\n lineCount: function() {return this.size;},\n firstLine: function() {return this.first;},\n lastLine: function() {return this.first + this.size - 1;},\n\n clipPos: function(pos) {return clipPos(this, pos);},\n\n getCursor: function(start) {\n var range = this.sel.primary(), pos;\n if (start == null || start == \"head\") pos = range.head;\n else if (start == \"anchor\") pos = range.anchor;\n else if (start == \"end\" || start == \"to\" || start === false) pos = range.to();\n else pos = range.from();\n return pos;\n },\n listSelections: function() { return this.sel.ranges; },\n somethingSelected: function() {return this.sel.somethingSelected();},\n\n setCursor: docMethodOp(function(line, ch, options) {\n setSimpleSelection(this, clipPos(this, typeof line == \"number\" ? Pos(line, ch || 0) : line), null, options);\n }),\n setSelection: docMethodOp(function(anchor, head, options) {\n setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);\n }),\n extendSelection: docMethodOp(function(head, other, options) {\n extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);\n }),\n extendSelections: docMethodOp(function(heads, options) {\n extendSelections(this, clipPosArray(this, heads, options));\n }),\n extendSelectionsBy: docMethodOp(function(f, options) {\n extendSelections(this, map(this.sel.ranges, f), options);\n }),\n setSelections: docMethodOp(function(ranges, primary, options) {\n if (!ranges.length) return;\n for (var i = 0, out = []; i < ranges.length; i++)\n out[i] = new Range(clipPos(this, ranges[i].anchor),\n clipPos(this, ranges[i].head));\n if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex);\n setSelection(this, normalizeSelection(out, primary), options);\n }),\n addSelection: docMethodOp(function(anchor, head, options) {\n var ranges = this.sel.ranges.slice(0);\n ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));\n setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);\n }),\n\n getSelection: function(lineSep) {\n var ranges = this.sel.ranges, lines;\n for (var i = 0; i < ranges.length; i++) {\n var sel = getBetween(this, ranges[i].from(), ranges[i].to());\n lines = lines ? lines.concat(sel) : sel;\n }\n if (lineSep === false) return lines;\n else return lines.join(lineSep || \"\\n\");\n },\n getSelections: function(lineSep) {\n var parts = [], ranges = this.sel.ranges;\n for (var i = 0; i < ranges.length; i++) {\n var sel = getBetween(this, ranges[i].from(), ranges[i].to());\n if (lineSep !== false) sel = sel.join(lineSep || \"\\n\");\n parts[i] = sel;\n }\n return parts;\n },\n replaceSelection: function(code, collapse, origin) {\n var dup = [];\n for (var i = 0; i < this.sel.ranges.length; i++)\n dup[i] = code;\n this.replaceSelections(dup, collapse, origin || \"+input\");\n },\n replaceSelections: docMethodOp(function(code, collapse, origin) {\n var changes = [], sel = this.sel;\n for (var i = 0; i < sel.ranges.length; i++) {\n var range = sel.ranges[i];\n changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};\n }\n var newSel = collapse && collapse != \"end\" && computeReplacedSel(this, changes, collapse);\n for (var i = changes.length - 1; i >= 0; i--)\n makeChange(this, changes[i]);\n if (newSel) setSelectionReplaceHistory(this, newSel);\n else if (this.cm) ensureCursorVisible(this.cm);\n }),\n undo: docMethodOp(function() {makeChangeFromHistory(this, \"undo\");}),\n redo: docMethodOp(function() {makeChangeFromHistory(this, \"redo\");}),\n undoSelection: docMethodOp(function() {makeChangeFromHistory(this, \"undo\", true);}),\n redoSelection: docMethodOp(function() {makeChangeFromHistory(this, \"redo\", true);}),\n\n setExtending: function(val) {this.extend = val;},\n getExtending: function() {return this.extend;},\n\n historySize: function() {\n var hist = this.history, done = 0, undone = 0;\n for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done;\n for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone;\n return {undo: done, redo: undone};\n },\n clearHistory: function() {this.history = new History(this.history.maxGeneration);},\n\n markClean: function() {\n this.cleanGeneration = this.changeGeneration(true);\n },\n changeGeneration: function(forceSplit) {\n if (forceSplit)\n this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null;\n return this.history.generation;\n },\n isClean: function (gen) {\n return this.history.generation == (gen || this.cleanGeneration);\n },\n\n getHistory: function() {\n return {done: copyHistoryArray(this.history.done),\n undone: copyHistoryArray(this.history.undone)};\n },\n setHistory: function(histData) {\n var hist = this.history = new History(this.history.maxGeneration);\n hist.done = copyHistoryArray(histData.done.slice(0), null, true);\n hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);\n },\n\n addLineClass: docMethodOp(function(handle, where, cls) {\n return changeLine(this, handle, where == \"gutter\" ? \"gutter\" : \"class\", function(line) {\n var prop = where == \"text\" ? \"textClass\"\n : where == \"background\" ? \"bgClass\"\n : where == \"gutter\" ? \"gutterClass\" : \"wrapClass\";\n if (!line[prop]) line[prop] = cls;\n else if (classTest(cls).test(line[prop])) return false;\n else line[prop] += \" \" + cls;\n return true;\n });\n }),\n removeLineClass: docMethodOp(function(handle, where, cls) {\n return changeLine(this, handle, where == \"gutter\" ? \"gutter\" : \"class\", function(line) {\n var prop = where == \"text\" ? \"textClass\"\n : where == \"background\" ? \"bgClass\"\n : where == \"gutter\" ? \"gutterClass\" : \"wrapClass\";\n var cur = line[prop];\n if (!cur) return false;\n else if (cls == null) line[prop] = null;\n else {\n var found = cur.match(classTest(cls));\n if (!found) return false;\n var end = found.index + found[0].length;\n line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? \"\" : \" \") + cur.slice(end) || null;\n }\n return true;\n });\n }),\n\n markText: function(from, to, options) {\n return markText(this, clipPos(this, from), clipPos(this, to), options, \"range\");\n },\n setBookmark: function(pos, options) {\n var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),\n insertLeft: options && options.insertLeft,\n clearWhenEmpty: false, shared: options && options.shared};\n pos = clipPos(this, pos);\n return markText(this, pos, pos, realOpts, \"bookmark\");\n },\n findMarksAt: function(pos) {\n pos = clipPos(this, pos);\n var markers = [], spans = getLine(this, pos.line).markedSpans;\n if (spans) for (var i = 0; i < spans.length; ++i) {\n var span = spans[i];\n if ((span.from == null || span.from <= pos.ch) &&\n (span.to == null || span.to >= pos.ch))\n markers.push(span.marker.parent || span.marker);\n }\n return markers;\n },\n findMarks: function(from, to, filter) {\n from = clipPos(this, from); to = clipPos(this, to);\n var found = [], lineNo = from.line;\n this.iter(from.line, to.line + 1, function(line) {\n var spans = line.markedSpans;\n if (spans) for (var i = 0; i < spans.length; i++) {\n var span = spans[i];\n if (!(lineNo == from.line && from.ch > span.to ||\n span.from == null && lineNo != from.line||\n lineNo == to.line && span.from > to.ch) &&\n (!filter || filter(span.marker)))\n found.push(span.marker.parent || span.marker);\n }\n ++lineNo;\n });\n return found;\n },\n getAllMarks: function() {\n var markers = [];\n this.iter(function(line) {\n var sps = line.markedSpans;\n if (sps) for (var i = 0; i < sps.length; ++i)\n if (sps[i].from != null) markers.push(sps[i].marker);\n });\n return markers;\n },\n\n posFromIndex: function(off) {\n var ch, lineNo = this.first;\n this.iter(function(line) {\n var sz = line.text.length + 1;\n if (sz > off) { ch = off; return true; }\n off -= sz;\n ++lineNo;\n });\n return clipPos(this, Pos(lineNo, ch));\n },\n indexFromPos: function (coords) {\n coords = clipPos(this, coords);\n var index = coords.ch;\n if (coords.line < this.first || coords.ch < 0) return 0;\n this.iter(this.first, coords.line, function (line) {\n index += line.text.length + 1;\n });\n return index;\n },\n\n copy: function(copyHistory) {\n var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);\n doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;\n doc.sel = this.sel;\n doc.extend = false;\n if (copyHistory) {\n doc.history.undoDepth = this.history.undoDepth;\n doc.setHistory(this.getHistory());\n }\n return doc;\n },\n\n linkedDoc: function(options) {\n if (!options) options = {};\n var from = this.first, to = this.first + this.size;\n if (options.from != null && options.from > from) from = options.from;\n if (options.to != null && options.to < to) to = options.to;\n var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);\n if (options.sharedHist) copy.history = this.history;\n (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});\n copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];\n copySharedMarkers(copy, findSharedMarkers(this));\n return copy;\n },\n unlinkDoc: function(other) {\n if (other instanceof CodeMirror) other = other.doc;\n if (this.linked) for (var i = 0; i < this.linked.length; ++i) {\n var link = this.linked[i];\n if (link.doc != other) continue;\n this.linked.splice(i, 1);\n other.unlinkDoc(this);\n detachSharedMarkers(findSharedMarkers(this));\n break;\n }\n // If the histories were shared, split them again\n if (other.history == this.history) {\n var splitIds = [other.id];\n linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);\n other.history = new History(null);\n other.history.done = copyHistoryArray(this.history.done, splitIds);\n other.history.undone = copyHistoryArray(this.history.undone, splitIds);\n }\n },\n iterLinkedDocs: function(f) {linkedDocs(this, f);},\n\n getMode: function() {return this.mode;},\n getEditor: function() {return this.cm;}\n });\n\n // Public alias.\n Doc.prototype.eachLine = Doc.prototype.iter;\n\n // Set up methods on CodeMirror's prototype to redirect to the editor's document.\n var dontDelegate = \"iter insert remove copy getEditor\".split(\" \");\n for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)\n CodeMirror.prototype[prop] = (function(method) {\n return function() {return method.apply(this.doc, arguments);};\n })(Doc.prototype[prop]);\n\n eventMixin(Doc);\n\n // Call f for all linked documents.\n function linkedDocs(doc, f, sharedHistOnly) {\n function propagate(doc, skip, sharedHist) {\n if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {\n var rel = doc.linked[i];\n if (rel.doc == skip) continue;\n var shared = sharedHist && rel.sharedHist;\n if (sharedHistOnly && !shared) continue;\n f(rel.doc, shared);\n propagate(rel.doc, doc, shared);\n }\n }\n propagate(doc, null, true);\n }\n\n // Attach a document to an editor.\n function attachDoc(cm, doc) {\n if (doc.cm) throw new Error(\"This document is already in use.\");\n cm.doc = doc;\n doc.cm = cm;\n estimateLineHeights(cm);\n loadMode(cm);\n if (!cm.options.lineWrapping) findMaxLine(cm);\n cm.options.mode = doc.modeOption;\n regChange(cm);\n }\n\n // LINE UTILITIES\n\n // Find the line object corresponding to the given line number.\n function getLine(doc, n) {\n n -= doc.first;\n if (n < 0 || n >= doc.size) throw new Error(\"There is no line \" + (n + doc.first) + \" in the document.\");\n for (var chunk = doc; !chunk.lines;) {\n for (var i = 0;; ++i) {\n var child = chunk.children[i], sz = child.chunkSize();\n if (n < sz) { chunk = child; break; }\n n -= sz;\n }\n }\n return chunk.lines[n];\n }\n\n // Get the part of a document between two positions, as an array of\n // strings.\n function getBetween(doc, start, end) {\n var out = [], n = start.line;\n doc.iter(start.line, end.line + 1, function(line) {\n var text = line.text;\n if (n == end.line) text = text.slice(0, end.ch);\n if (n == start.line) text = text.slice(start.ch);\n out.push(text);\n ++n;\n });\n return out;\n }\n // Get the lines between from and to, as array of strings.\n function getLines(doc, from, to) {\n var out = [];\n doc.iter(from, to, function(line) { out.push(line.text); });\n return out;\n }\n\n // Update the height of a line, propagating the height change\n // upwards to parent nodes.\n function updateLineHeight(line, height) {\n var diff = height - line.height;\n if (diff) for (var n = line; n; n = n.parent) n.height += diff;\n }\n\n // Given a line object, find its line number by walking up through\n // its parent links.\n function lineNo(line) {\n if (line.parent == null) return null;\n var cur = line.parent, no = indexOf(cur.lines, line);\n for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {\n for (var i = 0;; ++i) {\n if (chunk.children[i] == cur) break;\n no += chunk.children[i].chunkSize();\n }\n }\n return no + cur.first;\n }\n\n // Find the line at the given vertical position, using the height\n // information in the document tree.\n function lineAtHeight(chunk, h) {\n var n = chunk.first;\n outer: do {\n for (var i = 0; i < chunk.children.length; ++i) {\n var child = chunk.children[i], ch = child.height;\n if (h < ch) { chunk = child; continue outer; }\n h -= ch;\n n += child.chunkSize();\n }\n return n;\n } while (!chunk.lines);\n for (var i = 0; i < chunk.lines.length; ++i) {\n var line = chunk.lines[i], lh = line.height;\n if (h < lh) break;\n h -= lh;\n }\n return n + i;\n }\n\n\n // Find the height above the given line.\n function heightAtLine(lineObj) {\n lineObj = visualLine(lineObj);\n\n var h = 0, chunk = lineObj.parent;\n for (var i = 0; i < chunk.lines.length; ++i) {\n var line = chunk.lines[i];\n if (line == lineObj) break;\n else h += line.height;\n }\n for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {\n for (var i = 0; i < p.children.length; ++i) {\n var cur = p.children[i];\n if (cur == chunk) break;\n else h += cur.height;\n }\n }\n return h;\n }\n\n // Get the bidi ordering for the given line (and cache it). Returns\n // false for lines that are fully left-to-right, and an array of\n // BidiSpan objects otherwise.\n function getOrder(line) {\n var order = line.order;\n if (order == null) order = line.order = bidiOrdering(line.text);\n return order;\n }\n\n // HISTORY\n\n function History(startGen) {\n // Arrays of change events and selections. Doing something adds an\n // event to done and clears undo. Undoing moves events from done\n // to undone, redoing moves them in the other direction.\n this.done = []; this.undone = [];\n this.undoDepth = Infinity;\n // Used to track when changes can be merged into a single undo\n // event\n this.lastModTime = this.lastSelTime = 0;\n this.lastOp = this.lastSelOp = null;\n this.lastOrigin = this.lastSelOrigin = null;\n // Used by the isClean() method\n this.generation = this.maxGeneration = startGen || 1;\n }\n\n // Create a history change event from an updateDoc-style change\n // object.\n function historyChangeFromChange(doc, change) {\n var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};\n attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);\n linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);\n return histChange;\n }\n\n // Pop all selection events off the end of a history array. Stop at\n // a change event.\n function clearSelectionEvents(array) {\n while (array.length) {\n var last = lst(array);\n if (last.ranges) array.pop();\n else break;\n }\n }\n\n // Find the top change event in the history. Pop off selection\n // events that are in the way.\n function lastChangeEvent(hist, force) {\n if (force) {\n clearSelectionEvents(hist.done);\n return lst(hist.done);\n } else if (hist.done.length && !lst(hist.done).ranges) {\n return lst(hist.done);\n } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {\n hist.done.pop();\n return lst(hist.done);\n }\n }\n\n // Register a change in the history. Merges changes that are within\n // a single operation, ore are close together with an origin that\n // allows merging (starting with \"+\") into a single event.\n function addChangeToHistory(doc, change, selAfter, opId) {\n var hist = doc.history;\n hist.undone.length = 0;\n var time = +new Date, cur;\n\n if ((hist.lastOp == opId ||\n hist.lastOrigin == change.origin && change.origin &&\n ((change.origin.charAt(0) == \"+\" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||\n change.origin.charAt(0) == \"*\")) &&\n (cur = lastChangeEvent(hist, hist.lastOp == opId))) {\n // Merge this change into the last event\n var last = lst(cur.changes);\n if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {\n // Optimized case for simple insertion -- don't want to add\n // new changesets for every character typed\n last.to = changeEnd(change);\n } else {\n // Add new sub-event\n cur.changes.push(historyChangeFromChange(doc, change));\n }\n } else {\n // Can not be merged, start a new event.\n var before = lst(hist.done);\n if (!before || !before.ranges)\n pushSelectionToHistory(doc.sel, hist.done);\n cur = {changes: [historyChangeFromChange(doc, change)],\n generation: hist.generation};\n hist.done.push(cur);\n while (hist.done.length > hist.undoDepth) {\n hist.done.shift();\n if (!hist.done[0].ranges) hist.done.shift();\n }\n }\n hist.done.push(selAfter);\n hist.generation = ++hist.maxGeneration;\n hist.lastModTime = hist.lastSelTime = time;\n hist.lastOp = hist.lastSelOp = opId;\n hist.lastOrigin = hist.lastSelOrigin = change.origin;\n\n if (!last) signal(doc, \"historyAdded\");\n }\n\n function selectionEventCanBeMerged(doc, origin, prev, sel) {\n var ch = origin.charAt(0);\n return ch == \"*\" ||\n ch == \"+\" &&\n prev.ranges.length == sel.ranges.length &&\n prev.somethingSelected() == sel.somethingSelected() &&\n new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500);\n }\n\n // Called whenever the selection changes, sets the new selection as\n // the pending selection in the history, and pushes the old pending\n // selection into the 'done' array when it was significantly\n // different (in number of selected ranges, emptiness, or time).\n function addSelectionToHistory(doc, sel, opId, options) {\n var hist = doc.history, origin = options && options.origin;\n\n // A new event is started when the previous origin does not match\n // the current, or the origins don't allow matching. Origins\n // starting with * are always merged, those starting with + are\n // merged when similar and close together in time.\n if (opId == hist.lastSelOp ||\n (origin && hist.lastSelOrigin == origin &&\n (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||\n selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))\n hist.done[hist.done.length - 1] = sel;\n else\n pushSelectionToHistory(sel, hist.done);\n\n hist.lastSelTime = +new Date;\n hist.lastSelOrigin = origin;\n hist.lastSelOp = opId;\n if (options && options.clearRedo !== false)\n clearSelectionEvents(hist.undone);\n }\n\n function pushSelectionToHistory(sel, dest) {\n var top = lst(dest);\n if (!(top && top.ranges && top.equals(sel)))\n dest.push(sel);\n }\n\n // Used to store marked span information in the history.\n function attachLocalSpans(doc, change, from, to) {\n var existing = change[\"spans_\" + doc.id], n = 0;\n doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {\n if (line.markedSpans)\n (existing || (existing = change[\"spans_\" + doc.id] = {}))[n] = line.markedSpans;\n ++n;\n });\n }\n\n // When un/re-doing restores text containing marked spans, those\n // that have been explicitly cleared should not be restored.\n function removeClearedSpans(spans) {\n if (!spans) return null;\n for (var i = 0, out; i < spans.length; ++i) {\n if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }\n else if (out) out.push(spans[i]);\n }\n return !out ? spans : out.length ? out : null;\n }\n\n // Retrieve and filter the old marked spans stored in a change event.\n function getOldSpans(doc, change) {\n var found = change[\"spans_\" + doc.id];\n if (!found) return null;\n for (var i = 0, nw = []; i < change.text.length; ++i)\n nw.push(removeClearedSpans(found[i]));\n return nw;\n }\n\n // Used both to provide a JSON-safe object in .getHistory, and, when\n // detaching a document, to split the history in two\n function copyHistoryArray(events, newGroup, instantiateSel) {\n for (var i = 0, copy = []; i < events.length; ++i) {\n var event = events[i];\n if (event.ranges) {\n copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);\n continue;\n }\n var changes = event.changes, newChanges = [];\n copy.push({changes: newChanges});\n for (var j = 0; j < changes.length; ++j) {\n var change = changes[j], m;\n newChanges.push({from: change.from, to: change.to, text: change.text});\n if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\\d+)$/)) {\n if (indexOf(newGroup, Number(m[1])) > -1) {\n lst(newChanges)[prop] = change[prop];\n delete change[prop];\n }\n }\n }\n }\n return copy;\n }\n\n // Rebasing/resetting history to deal with externally-sourced changes\n\n function rebaseHistSelSingle(pos, from, to, diff) {\n if (to < pos.line) {\n pos.line += diff;\n } else if (from < pos.line) {\n pos.line = from;\n pos.ch = 0;\n }\n }\n\n // Tries to rebase an array of history events given a change in the\n // document. If the change touches the same lines as the event, the\n // event, and everything 'behind' it, is discarded. If the change is\n // before the event, the event's positions are updated. Uses a\n // copy-on-write scheme for the positions, to avoid having to\n // reallocate them all on every rebase, but also avoid problems with\n // shared position objects being unsafely updated.\n function rebaseHistArray(array, from, to, diff) {\n for (var i = 0; i < array.length; ++i) {\n var sub = array[i], ok = true;\n if (sub.ranges) {\n if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }\n for (var j = 0; j < sub.ranges.length; j++) {\n rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);\n rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);\n }\n continue;\n }\n for (var j = 0; j < sub.changes.length; ++j) {\n var cur = sub.changes[j];\n if (to < cur.from.line) {\n cur.from = Pos(cur.from.line + diff, cur.from.ch);\n cur.to = Pos(cur.to.line + diff, cur.to.ch);\n } else if (from <= cur.to.line) {\n ok = false;\n break;\n }\n }\n if (!ok) {\n array.splice(0, i + 1);\n i = 0;\n }\n }\n }\n\n function rebaseHist(hist, change) {\n var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;\n rebaseHistArray(hist.done, from, to, diff);\n rebaseHistArray(hist.undone, from, to, diff);\n }\n\n // EVENT UTILITIES\n\n // Due to the fact that we still support jurassic IE versions, some\n // compatibility wrappers are needed.\n\n var e_preventDefault = CodeMirror.e_preventDefault = function(e) {\n if (e.preventDefault) e.preventDefault();\n else e.returnValue = false;\n };\n var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) {\n if (e.stopPropagation) e.stopPropagation();\n else e.cancelBubble = true;\n };\n function e_defaultPrevented(e) {\n return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;\n }\n var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);};\n\n function e_target(e) {return e.target || e.srcElement;}\n function e_button(e) {\n var b = e.which;\n if (b == null) {\n if (e.button & 1) b = 1;\n else if (e.button & 2) b = 3;\n else if (e.button & 4) b = 2;\n }\n if (mac && e.ctrlKey && b == 1) b = 3;\n return b;\n }\n\n // EVENT HANDLING\n\n // Lightweight event framework. on/off also work on DOM nodes,\n // registering native DOM handlers.\n\n var on = CodeMirror.on = function(emitter, type, f) {\n if (emitter.addEventListener)\n emitter.addEventListener(type, f, false);\n else if (emitter.attachEvent)\n emitter.attachEvent(\"on\" + type, f);\n else {\n var map = emitter._handlers || (emitter._handlers = {});\n var arr = map[type] || (map[type] = []);\n arr.push(f);\n }\n };\n\n var off = CodeMirror.off = function(emitter, type, f) {\n if (emitter.removeEventListener)\n emitter.removeEventListener(type, f, false);\n else if (emitter.detachEvent)\n emitter.detachEvent(\"on\" + type, f);\n else {\n var arr = emitter._handlers && emitter._handlers[type];\n if (!arr) return;\n for (var i = 0; i < arr.length; ++i)\n if (arr[i] == f) { arr.splice(i, 1); break; }\n }\n };\n\n var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {\n var arr = emitter._handlers && emitter._handlers[type];\n if (!arr) return;\n var args = Array.prototype.slice.call(arguments, 2);\n for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);\n };\n\n var orphanDelayedCallbacks = null;\n\n // Often, we want to signal events at a point where we are in the\n // middle of some work, but don't want the handler to start calling\n // other methods on the editor, which might be in an inconsistent\n // state or simply not expect any other events to happen.\n // signalLater looks whether there are any handlers, and schedules\n // them to be executed when the last operation ends, or, if no\n // operation is active, when a timeout fires.\n function signalLater(emitter, type /*, values...*/) {\n var arr = emitter._handlers && emitter._handlers[type];\n if (!arr) return;\n var args = Array.prototype.slice.call(arguments, 2), list;\n if (operationGroup) {\n list = operationGroup.delayedCallbacks;\n } else if (orphanDelayedCallbacks) {\n list = orphanDelayedCallbacks;\n } else {\n list = orphanDelayedCallbacks = [];\n setTimeout(fireOrphanDelayed, 0);\n }\n function bnd(f) {return function(){f.apply(null, args);};};\n for (var i = 0; i < arr.length; ++i)\n list.push(bnd(arr[i]));\n }\n\n function fireOrphanDelayed() {\n var delayed = orphanDelayedCallbacks;\n orphanDelayedCallbacks = null;\n for (var i = 0; i < delayed.length; ++i) delayed[i]();\n }\n\n // The DOM events that CodeMirror handles can be overridden by\n // registering a (non-DOM) handler on the editor for the event name,\n // and preventDefault-ing the event in that handler.\n function signalDOMEvent(cm, e, override) {\n if (typeof e == \"string\")\n e = {type: e, preventDefault: function() { this.defaultPrevented = true; }};\n signal(cm, override || e.type, cm, e);\n return e_defaultPrevented(e) || e.codemirrorIgnore;\n }\n\n function signalCursorActivity(cm) {\n var arr = cm._handlers && cm._handlers.cursorActivity;\n if (!arr) return;\n var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);\n for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1)\n set.push(arr[i]);\n }\n\n function hasHandler(emitter, type) {\n var arr = emitter._handlers && emitter._handlers[type];\n return arr && arr.length > 0;\n }\n\n // Add on and off methods to a constructor's prototype, to make\n // registering events on such objects more convenient.\n function eventMixin(ctor) {\n ctor.prototype.on = function(type, f) {on(this, type, f);};\n ctor.prototype.off = function(type, f) {off(this, type, f);};\n }\n\n // MISC UTILITIES\n\n // Number of pixels added to scroller and sizer to hide scrollbar\n var scrollerGap = 30;\n\n // Returned or thrown by various protocols to signal 'I'm not\n // handling this'.\n var Pass = CodeMirror.Pass = {toString: function(){return \"CodeMirror.Pass\";}};\n\n // Reused option objects for setSelection & friends\n var sel_dontScroll = {scroll: false}, sel_mouse = {origin: \"*mouse\"}, sel_move = {origin: \"+move\"};\n\n function Delayed() {this.id = null;}\n Delayed.prototype.set = function(ms, f) {\n clearTimeout(this.id);\n this.id = setTimeout(f, ms);\n };\n\n // Counts the column offset in a string, taking tabs into account.\n // Used mostly to find indentation.\n var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) {\n if (end == null) {\n end = string.search(/[^\\s\\u00a0]/);\n if (end == -1) end = string.length;\n }\n for (var i = startIndex || 0, n = startValue || 0;;) {\n var nextTab = string.indexOf(\"\\t\", i);\n if (nextTab < 0 || nextTab >= end)\n return n + (end - i);\n n += nextTab - i;\n n += tabSize - (n % tabSize);\n i = nextTab + 1;\n }\n };\n\n // The inverse of countColumn -- find the offset that corresponds to\n // a particular column.\n function findColumn(string, goal, tabSize) {\n for (var pos = 0, col = 0;;) {\n var nextTab = string.indexOf(\"\\t\", pos);\n if (nextTab == -1) nextTab = string.length;\n var skipped = nextTab - pos;\n if (nextTab == string.length || col + skipped >= goal)\n return pos + Math.min(skipped, goal - col);\n col += nextTab - pos;\n col += tabSize - (col % tabSize);\n pos = nextTab + 1;\n if (col >= goal) return pos;\n }\n }\n\n var spaceStrs = [\"\"];\n function spaceStr(n) {\n while (spaceStrs.length <= n)\n spaceStrs.push(lst(spaceStrs) + \" \");\n return spaceStrs[n];\n }\n\n function lst(arr) { return arr[arr.length-1]; }\n\n var selectInput = function(node) { node.select(); };\n if (ios) // Mobile Safari apparently has a bug where select() is broken.\n selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; };\n else if (ie) // Suppress mysterious IE10 errors\n selectInput = function(node) { try { node.select(); } catch(_e) {} };\n\n function indexOf(array, elt) {\n for (var i = 0; i < array.length; ++i)\n if (array[i] == elt) return i;\n return -1;\n }\n function map(array, f) {\n var out = [];\n for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);\n return out;\n }\n\n function createObj(base, props) {\n var inst;\n if (Object.create) {\n inst = Object.create(base);\n } else {\n var ctor = function() {};\n ctor.prototype = base;\n inst = new ctor();\n }\n if (props) copyObj(props, inst);\n return inst;\n };\n\n function copyObj(obj, target, overwrite) {\n if (!target) target = {};\n for (var prop in obj)\n if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))\n target[prop] = obj[prop];\n return target;\n }\n\n function bind(f) {\n var args = Array.prototype.slice.call(arguments, 1);\n return function(){return f.apply(null, args);};\n }\n\n var nonASCIISingleCaseWordChar = /[\\u00df\\u0590-\\u05f4\\u0600-\\u06ff\\u3040-\\u309f\\u30a0-\\u30ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\uac00-\\ud7af]/;\n var isWordCharBasic = CodeMirror.isWordChar = function(ch) {\n return /\\w/.test(ch) || ch > \"\\x80\" &&\n (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));\n };\n function isWordChar(ch, helper) {\n if (!helper) return isWordCharBasic(ch);\n if (helper.source.indexOf(\"\\\\w\") > -1 && isWordCharBasic(ch)) return true;\n return helper.test(ch);\n }\n\n function isEmpty(obj) {\n for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;\n return true;\n }\n\n // Extending unicode characters. A series of a non-extending char +\n // any number of extending chars is treated as a single unit as far\n // as editing and measuring is concerned. This is not fully correct,\n // since some scripts/fonts/browsers also treat other configurations\n // of code points as a group.\n var extendingChars = /[\\u0300-\\u036f\\u0483-\\u0489\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u064b-\\u065e\\u0670\\u06d6-\\u06dc\\u06de-\\u06e4\\u06e7\\u06e8\\u06ea-\\u06ed\\u0711\\u0730-\\u074a\\u07a6-\\u07b0\\u07eb-\\u07f3\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0900-\\u0902\\u093c\\u0941-\\u0948\\u094d\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09bc\\u09be\\u09c1-\\u09c4\\u09cd\\u09d7\\u09e2\\u09e3\\u0a01\\u0a02\\u0a3c\\u0a41\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a70\\u0a71\\u0a75\\u0a81\\u0a82\\u0abc\\u0ac1-\\u0ac5\\u0ac7\\u0ac8\\u0acd\\u0ae2\\u0ae3\\u0b01\\u0b3c\\u0b3e\\u0b3f\\u0b41-\\u0b44\\u0b4d\\u0b56\\u0b57\\u0b62\\u0b63\\u0b82\\u0bbe\\u0bc0\\u0bcd\\u0bd7\\u0c3e-\\u0c40\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62\\u0c63\\u0cbc\\u0cbf\\u0cc2\\u0cc6\\u0ccc\\u0ccd\\u0cd5\\u0cd6\\u0ce2\\u0ce3\\u0d3e\\u0d41-\\u0d44\\u0d4d\\u0d57\\u0d62\\u0d63\\u0dca\\u0dcf\\u0dd2-\\u0dd4\\u0dd6\\u0ddf\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0eb1\\u0eb4-\\u0eb9\\u0ebb\\u0ebc\\u0ec8-\\u0ecd\\u0f18\\u0f19\\u0f35\\u0f37\\u0f39\\u0f71-\\u0f7e\\u0f80-\\u0f84\\u0f86\\u0f87\\u0f90-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u102d-\\u1030\\u1032-\\u1037\\u1039\\u103a\\u103d\\u103e\\u1058\\u1059\\u105e-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108d\\u109d\\u135f\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17b7-\\u17bd\\u17c6\\u17c9-\\u17d3\\u17dd\\u180b-\\u180d\\u18a9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193b\\u1a17\\u1a18\\u1a56\\u1a58-\\u1a5e\\u1a60\\u1a62\\u1a65-\\u1a6c\\u1a73-\\u1a7c\\u1a7f\\u1b00-\\u1b03\\u1b34\\u1b36-\\u1b3a\\u1b3c\\u1b42\\u1b6b-\\u1b73\\u1b80\\u1b81\\u1ba2-\\u1ba5\\u1ba8\\u1ba9\\u1c2c-\\u1c33\\u1c36\\u1c37\\u1cd0-\\u1cd2\\u1cd4-\\u1ce0\\u1ce2-\\u1ce8\\u1ced\\u1dc0-\\u1de6\\u1dfd-\\u1dff\\u200c\\u200d\\u20d0-\\u20f0\\u2cef-\\u2cf1\\u2de0-\\u2dff\\u302a-\\u302f\\u3099\\u309a\\ua66f-\\ua672\\ua67c\\ua67d\\ua6f0\\ua6f1\\ua802\\ua806\\ua80b\\ua825\\ua826\\ua8c4\\ua8e0-\\ua8f1\\ua926-\\ua92d\\ua947-\\ua951\\ua980-\\ua982\\ua9b3\\ua9b6-\\ua9b9\\ua9bc\\uaa29-\\uaa2e\\uaa31\\uaa32\\uaa35\\uaa36\\uaa43\\uaa4c\\uaab0\\uaab2-\\uaab4\\uaab7\\uaab8\\uaabe\\uaabf\\uaac1\\uabe5\\uabe8\\uabed\\udc00-\\udfff\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe26\\uff9e\\uff9f]/;\n function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }\n\n // DOM UTILITIES\n\n function elt(tag, content, className, style) {\n var e = document.createElement(tag);\n if (className) e.className = className;\n if (style) e.style.cssText = style;\n if (typeof content == \"string\") e.appendChild(document.createTextNode(content));\n else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);\n return e;\n }\n\n var range;\n if (document.createRange) range = function(node, start, end) {\n var r = document.createRange();\n r.setEnd(node, end);\n r.setStart(node, start);\n return r;\n };\n else range = function(node, start, end) {\n var r = document.body.createTextRange();\n try { r.moveToElementText(node.parentNode); }\n catch(e) { return r; }\n r.collapse(true);\n r.moveEnd(\"character\", end);\n r.moveStart(\"character\", start);\n return r;\n };\n\n function removeChildren(e) {\n for (var count = e.childNodes.length; count > 0; --count)\n e.removeChild(e.firstChild);\n return e;\n }\n\n function removeChildrenAndAdd(parent, e) {\n return removeChildren(parent).appendChild(e);\n }\n\n function contains(parent, child) {\n if (parent.contains)\n return parent.contains(child);\n while (child = child.parentNode)\n if (child == parent) return true;\n }\n\n function activeElt() { return document.activeElement; }\n // Older versions of IE throws unspecified error when touching\n // document.activeElement in some cases (during loading, in iframe)\n if (ie && ie_version < 11) activeElt = function() {\n try { return document.activeElement; }\n catch(e) { return document.body; }\n };\n\n function classTest(cls) { return new RegExp(\"(^|\\\\s)\" + cls + \"(?:$|\\\\s)\\\\s*\"); }\n var rmClass = CodeMirror.rmClass = function(node, cls) {\n var current = node.className;\n var match = classTest(cls).exec(current);\n if (match) {\n var after = current.slice(match.index + match[0].length);\n node.className = current.slice(0, match.index) + (after ? match[1] + after : \"\");\n }\n };\n var addClass = CodeMirror.addClass = function(node, cls) {\n var current = node.className;\n if (!classTest(cls).test(current)) node.className += (current ? \" \" : \"\") + cls;\n };\n function joinClasses(a, b) {\n var as = a.split(\" \");\n for (var i = 0; i < as.length; i++)\n if (as[i] && !classTest(as[i]).test(b)) b += \" \" + as[i];\n return b;\n }\n\n // WINDOW-WIDE EVENTS\n\n // These must be handled carefully, because naively registering a\n // handler for each editor will cause the editors to never be\n // garbage collected.\n\n function forEachCodeMirror(f) {\n if (!document.body.getElementsByClassName) return;\n var byClass = document.body.getElementsByClassName(\"CodeMirror\");\n for (var i = 0; i < byClass.length; i++) {\n var cm = byClass[i].CodeMirror;\n if (cm) f(cm);\n }\n }\n\n var globalsRegistered = false;\n function ensureGlobalHandlers() {\n if (globalsRegistered) return;\n registerGlobalHandlers();\n globalsRegistered = true;\n }\n function registerGlobalHandlers() {\n // When the window resizes, we need to refresh active editors.\n var resizeTimer;\n on(window, \"resize\", function() {\n if (resizeTimer == null) resizeTimer = setTimeout(function() {\n resizeTimer = null;\n forEachCodeMirror(onResize);\n }, 100);\n });\n // When the window loses focus, we want to show the editor as blurred\n on(window, \"blur\", function() {\n forEachCodeMirror(onBlur);\n });\n }\n\n // FEATURE DETECTION\n\n // Detect drag-and-drop\n var dragAndDrop = function() {\n // There is *some* kind of drag-and-drop support in IE6-8, but I\n // couldn't get it to work yet.\n if (ie && ie_version < 9) return false;\n var div = elt('div');\n return \"draggable\" in div || \"dragDrop\" in div;\n }();\n\n var zwspSupported;\n function zeroWidthElement(measure) {\n if (zwspSupported == null) {\n var test = elt(\"span\", \"\\u200b\");\n removeChildrenAndAdd(measure, elt(\"span\", [test, document.createTextNode(\"x\")]));\n if (measure.firstChild.offsetHeight != 0)\n zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8);\n }\n if (zwspSupported) return elt(\"span\", \"\\u200b\");\n else return elt(\"span\", \"\\u00a0\", null, \"display: inline-block; width: 1px; margin-right: -1px\");\n }\n\n // Feature-detect IE's crummy client rect reporting for bidi text\n var badBidiRects;\n function hasBadBidiRects(measure) {\n if (badBidiRects != null) return badBidiRects;\n var txt = removeChildrenAndAdd(measure, document.createTextNode(\"A\\u062eA\"));\n var r0 = range(txt, 0, 1).getBoundingClientRect();\n if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780)\n var r1 = range(txt, 1, 2).getBoundingClientRect();\n return badBidiRects = (r1.right - r0.right < 3);\n }\n\n // See if \"\".split is the broken IE version, if so, provide an\n // alternative way to split lines.\n var splitLines = CodeMirror.splitLines = \"\\n\\nb\".split(/\\n/).length != 3 ? function(string) {\n var pos = 0, result = [], l = string.length;\n while (pos <= l) {\n var nl = string.indexOf(\"\\n\", pos);\n if (nl == -1) nl = string.length;\n var line = string.slice(pos, string.charAt(nl - 1) == \"\\r\" ? nl - 1 : nl);\n var rt = line.indexOf(\"\\r\");\n if (rt != -1) {\n result.push(line.slice(0, rt));\n pos += rt + 1;\n } else {\n result.push(line);\n pos = nl + 1;\n }\n }\n return result;\n } : function(string){return string.split(/\\r\\n?|\\n/);};\n\n var hasSelection = window.getSelection ? function(te) {\n try { return te.selectionStart != te.selectionEnd; }\n catch(e) { return false; }\n } : function(te) {\n try {var range = te.ownerDocument.selection.createRange();}\n catch(e) {}\n if (!range || range.parentElement() != te) return false;\n return range.compareEndPoints(\"StartToEnd\", range) != 0;\n };\n\n var hasCopyEvent = (function() {\n var e = elt(\"div\");\n if (\"oncopy\" in e) return true;\n e.setAttribute(\"oncopy\", \"return;\");\n return typeof e.oncopy == \"function\";\n })();\n\n var badZoomedRects = null;\n function hasBadZoomedRects(measure) {\n if (badZoomedRects != null) return badZoomedRects;\n var node = removeChildrenAndAdd(measure, elt(\"span\", \"x\"));\n var normal = node.getBoundingClientRect();\n var fromRange = range(node, 0, 1).getBoundingClientRect();\n return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1;\n }\n\n // KEY NAMES\n\n var keyNames = {3: \"Enter\", 8: \"Backspace\", 9: \"Tab\", 13: \"Enter\", 16: \"Shift\", 17: \"Ctrl\", 18: \"Alt\",\n 19: \"Pause\", 20: \"CapsLock\", 27: \"Esc\", 32: \"Space\", 33: \"PageUp\", 34: \"PageDown\", 35: \"End\",\n 36: \"Home\", 37: \"Left\", 38: \"Up\", 39: \"Right\", 40: \"Down\", 44: \"PrintScrn\", 45: \"Insert\",\n 46: \"Delete\", 59: \";\", 61: \"=\", 91: \"Mod\", 92: \"Mod\", 93: \"Mod\", 107: \"=\", 109: \"-\", 127: \"Delete\",\n 173: \"-\", 186: \";\", 187: \"=\", 188: \",\", 189: \"-\", 190: \".\", 191: \"/\", 192: \"`\", 219: \"[\", 220: \"\\\\\",\n 221: \"]\", 222: \"'\", 63232: \"Up\", 63233: \"Down\", 63234: \"Left\", 63235: \"Right\", 63272: \"Delete\",\n 63273: \"Home\", 63275: \"End\", 63276: \"PageUp\", 63277: \"PageDown\", 63302: \"Insert\"};\n CodeMirror.keyNames = keyNames;\n (function() {\n // Number keys\n for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);\n // Alphabetic keys\n for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);\n // Function keys\n for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = \"F\" + i;\n })();\n\n // BIDI HELPERS\n\n function iterateBidiSections(order, from, to, f) {\n if (!order) return f(from, to, \"ltr\");\n var found = false;\n for (var i = 0; i < order.length; ++i) {\n var part = order[i];\n if (part.from < to && part.to > from || from == to && part.to == from) {\n f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? \"rtl\" : \"ltr\");\n found = true;\n }\n }\n if (!found) f(from, to, \"ltr\");\n }\n\n function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }\n function bidiRight(part) { return part.level % 2 ? part.from : part.to; }\n\n function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }\n function lineRight(line) {\n var order = getOrder(line);\n if (!order) return line.text.length;\n return bidiRight(lst(order));\n }\n\n function lineStart(cm, lineN) {\n var line = getLine(cm.doc, lineN);\n var visual = visualLine(line);\n if (visual != line) lineN = lineNo(visual);\n var order = getOrder(visual);\n var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);\n return Pos(lineN, ch);\n }\n function lineEnd(cm, lineN) {\n var merged, line = getLine(cm.doc, lineN);\n while (merged = collapsedSpanAtEnd(line)) {\n line = merged.find(1, true).line;\n lineN = null;\n }\n var order = getOrder(line);\n var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);\n return Pos(lineN == null ? lineNo(line) : lineN, ch);\n }\n function lineStartSmart(cm, pos) {\n var start = lineStart(cm, pos.line);\n var line = getLine(cm.doc, start.line);\n var order = getOrder(line);\n if (!order || order[0].level == 0) {\n var firstNonWS = Math.max(0, line.text.search(/\\S/));\n var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;\n return Pos(start.line, inWS ? 0 : firstNonWS);\n }\n return start;\n }\n\n function compareBidiLevel(order, a, b) {\n var linedir = order[0].level;\n if (a == linedir) return true;\n if (b == linedir) return false;\n return a < b;\n }\n var bidiOther;\n function getBidiPartAt(order, pos) {\n bidiOther = null;\n for (var i = 0, found; i < order.length; ++i) {\n var cur = order[i];\n if (cur.from < pos && cur.to > pos) return i;\n if ((cur.from == pos || cur.to == pos)) {\n if (found == null) {\n found = i;\n } else if (compareBidiLevel(order, cur.level, order[found].level)) {\n if (cur.from != cur.to) bidiOther = found;\n return i;\n } else {\n if (cur.from != cur.to) bidiOther = i;\n return found;\n }\n }\n }\n return found;\n }\n\n function moveInLine(line, pos, dir, byUnit) {\n if (!byUnit) return pos + dir;\n do pos += dir;\n while (pos > 0 && isExtendingChar(line.text.charAt(pos)));\n return pos;\n }\n\n // This is needed in order to move 'visually' through bi-directional\n // text -- i.e., pressing left should make the cursor go left, even\n // when in RTL text. The tricky part is the 'jumps', where RTL and\n // LTR text touch each other. This often requires the cursor offset\n // to move more than one unit, in order to visually move one unit.\n function moveVisually(line, start, dir, byUnit) {\n var bidi = getOrder(line);\n if (!bidi) return moveLogically(line, start, dir, byUnit);\n var pos = getBidiPartAt(bidi, start), part = bidi[pos];\n var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);\n\n for (;;) {\n if (target > part.from && target < part.to) return target;\n if (target == part.from || target == part.to) {\n if (getBidiPartAt(bidi, target) == pos) return target;\n part = bidi[pos += dir];\n return (dir > 0) == part.level % 2 ? part.to : part.from;\n } else {\n part = bidi[pos += dir];\n if (!part) return null;\n if ((dir > 0) == part.level % 2)\n target = moveInLine(line, part.to, -1, byUnit);\n else\n target = moveInLine(line, part.from, 1, byUnit);\n }\n }\n }\n\n function moveLogically(line, start, dir, byUnit) {\n var target = start + dir;\n if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;\n return target < 0 || target > line.text.length ? null : target;\n }\n\n // Bidirectional ordering algorithm\n // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm\n // that this (partially) implements.\n\n // One-char codes used for character types:\n // L (L): Left-to-Right\n // R (R): Right-to-Left\n // r (AL): Right-to-Left Arabic\n // 1 (EN): European Number\n // + (ES): European Number Separator\n // % (ET): European Number Terminator\n // n (AN): Arabic Number\n // , (CS): Common Number Separator\n // m (NSM): Non-Spacing Mark\n // b (BN): Boundary Neutral\n // s (B): Paragraph Separator\n // t (S): Segment Separator\n // w (WS): Whitespace\n // N (ON): Other Neutrals\n\n // Returns null if characters are ordered as they appear\n // (left-to-right), or an array of sections ({from, to, level}\n // objects) in the order in which they occur visually.\n var bidiOrdering = (function() {\n // Character types for codepoints 0 to 0xff\n var lowTypes = \"bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN\";\n // Character types for codepoints 0x600 to 0x6ff\n var arabicTypes = \"rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm\";\n function charType(code) {\n if (code <= 0xf7) return lowTypes.charAt(code);\n else if (0x590 <= code && code <= 0x5f4) return \"R\";\n else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600);\n else if (0x6ee <= code && code <= 0x8ac) return \"r\";\n else if (0x2000 <= code && code <= 0x200b) return \"w\";\n else if (code == 0x200c) return \"b\";\n else return \"L\";\n }\n\n var bidiRE = /[\\u0590-\\u05f4\\u0600-\\u06ff\\u0700-\\u08ac]/;\n var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;\n // Browsers seem to always treat the boundaries of block elements as being L.\n var outerType = \"L\";\n\n function BidiSpan(level, from, to) {\n this.level = level;\n this.from = from; this.to = to;\n }\n\n return function(str) {\n if (!bidiRE.test(str)) return false;\n var len = str.length, types = [];\n for (var i = 0, type; i < len; ++i)\n types.push(type = charType(str.charCodeAt(i)));\n\n // W1. Examine each non-spacing mark (NSM) in the level run, and\n // change the type of the NSM to the type of the previous\n // character. If the NSM is at the start of the level run, it will\n // get the type of sor.\n for (var i = 0, prev = outerType; i < len; ++i) {\n var type = types[i];\n if (type == \"m\") types[i] = prev;\n else prev = type;\n }\n\n // W2. Search backwards from each instance of a European number\n // until the first strong type (R, L, AL, or sor) is found. If an\n // AL is found, change the type of the European number to Arabic\n // number.\n // W3. Change all ALs to R.\n for (var i = 0, cur = outerType; i < len; ++i) {\n var type = types[i];\n if (type == \"1\" && cur == \"r\") types[i] = \"n\";\n else if (isStrong.test(type)) { cur = type; if (type == \"r\") types[i] = \"R\"; }\n }\n\n // W4. A single European separator between two European numbers\n // changes to a European number. A single common separator between\n // two numbers of the same type changes to that type.\n for (var i = 1, prev = types[0]; i < len - 1; ++i) {\n var type = types[i];\n if (type == \"+\" && prev == \"1\" && types[i+1] == \"1\") types[i] = \"1\";\n else if (type == \",\" && prev == types[i+1] &&\n (prev == \"1\" || prev == \"n\")) types[i] = prev;\n prev = type;\n }\n\n // W5. A sequence of European terminators adjacent to European\n // numbers changes to all European numbers.\n // W6. Otherwise, separators and terminators change to Other\n // Neutral.\n for (var i = 0; i < len; ++i) {\n var type = types[i];\n if (type == \",\") types[i] = \"N\";\n else if (type == \"%\") {\n for (var end = i + 1; end < len && types[end] == \"%\"; ++end) {}\n var replace = (i && types[i-1] == \"!\") || (end < len && types[end] == \"1\") ? \"1\" : \"N\";\n for (var j = i; j < end; ++j) types[j] = replace;\n i = end - 1;\n }\n }\n\n // W7. Search backwards from each instance of a European number\n // until the first strong type (R, L, or sor) is found. If an L is\n // found, then change the type of the European number to L.\n for (var i = 0, cur = outerType; i < len; ++i) {\n var type = types[i];\n if (cur == \"L\" && type == \"1\") types[i] = \"L\";\n else if (isStrong.test(type)) cur = type;\n }\n\n // N1. A sequence of neutrals takes the direction of the\n // surrounding strong text if the text on both sides has the same\n // direction. European and Arabic numbers act as if they were R in\n // terms of their influence on neutrals. Start-of-level-run (sor)\n // and end-of-level-run (eor) are used at level run boundaries.\n // N2. Any remaining neutrals take the embedding direction.\n for (var i = 0; i < len; ++i) {\n if (isNeutral.test(types[i])) {\n for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}\n var before = (i ? types[i-1] : outerType) == \"L\";\n var after = (end < len ? types[end] : outerType) == \"L\";\n var replace = before || after ? \"L\" : \"R\";\n for (var j = i; j < end; ++j) types[j] = replace;\n i = end - 1;\n }\n }\n\n // Here we depart from the documented algorithm, in order to avoid\n // building up an actual levels array. Since there are only three\n // levels (0, 1, 2) in an implementation that doesn't take\n // explicit embedding into account, we can build up the order on\n // the fly, without following the level-based algorithm.\n var order = [], m;\n for (var i = 0; i < len;) {\n if (countsAsLeft.test(types[i])) {\n var start = i;\n for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}\n order.push(new BidiSpan(0, start, i));\n } else {\n var pos = i, at = order.length;\n for (++i; i < len && types[i] != \"L\"; ++i) {}\n for (var j = pos; j < i;) {\n if (countsAsNum.test(types[j])) {\n if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j));\n var nstart = j;\n for (++j; j < i && countsAsNum.test(types[j]); ++j) {}\n order.splice(at, 0, new BidiSpan(2, nstart, j));\n pos = j;\n } else ++j;\n }\n if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i));\n }\n }\n if (order[0].level == 1 && (m = str.match(/^\\s+/))) {\n order[0].from = m[0].length;\n order.unshift(new BidiSpan(0, 0, m[0].length));\n }\n if (lst(order).level == 1 && (m = str.match(/\\s+$/))) {\n lst(order).to -= m[0].length;\n order.push(new BidiSpan(0, len - m[0].length, len));\n }\n if (order[0].level != lst(order).level)\n order.push(new BidiSpan(order[0].level, len, len));\n\n return order;\n };\n })();\n\n // THE END\n\n CodeMirror.version = \"4.12.0\";\n\n return CodeMirror;\n});\n\n},{}],16:[function(require,module,exports){\n/*!\n * jQuery JavaScript Library v1.11.2\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-17T15:27Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper window is present,\n\t\t// execute the factory and get jQuery\n\t\t// For environments that do not inherently posses a window with a document\n\t\t// (such as Node.js), expose a jQuery-making factory as module.exports\n\t\t// This accentuates the need for the creation of a real window\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\n\nvar deletedIds = [];\n\nvar slice = deletedIds.slice;\n\nvar concat = deletedIds.concat;\n\nvar push = deletedIds.push;\n\nvar indexOf = deletedIds.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"1.11.2\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1, IE<9\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\treturn !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Handle iteration over inherited properties before own properties.\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1, IE<9\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\tvar length = obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.0-pre\n * http://sizzlejs.com/\n *\n * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-16\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\tnodeType = context.nodeType;\n\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\tif ( !seed && documentIsHTML ) {\n\n\t\t// Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType !== 1 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tparent = doc.defaultView;\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Support tests\n\t---------------------------------------------------------------------- */\n\tdocumentIsHTML = !isXML( doc );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"\" +\n\t\t\t\t\"\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t// but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: ) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n * selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n * selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is no seed and only one group\n\tif ( match.length === 1 ) {\n\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\t// Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\n/**\n * Clean-up method for dom ready events\n */\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\t// readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", completed );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// detach all dom ready events\n\t\t\t\t\t\tdetach();\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n\nvar strundefined = typeof undefined;\n\n\n\n// Support: IE<9\n// Iteration over object's inherited properties before its own\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\n\n// Note: most support tests are defined in their respective modules.\n// false until the test is run\nsupport.inlineBlockNeedsLayout = false;\n\n// Execute ASAP in case we need to set body.style.zoom\njQuery(function() {\n\t// Minified: var a,b,c,d\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\t// Return for frameset docs that don't have a body\n\t\treturn;\n\t}\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t// Support: IE<8\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\t// Prevent IE 6 from affecting layout for positioned elements #11048\n\t\t\t// Prevent IE from shrinking the body in IE 7 mode #12869\n\t\t\t// Support: IE<8\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n\n\n\n(function() {\n\tvar div = document.createElement( \"div\" );\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( elem ) {\n\tvar noData = jQuery.noData[ (elem.nodeName + \" \").toLowerCase() ],\n\t\tnodeType = +elem.nodeType || 1;\n\n\t// Do not set data on non-element DOM nodes because it will not be cleared (#8335).\n\treturn nodeType !== 1 && nodeType !== 9 ?\n\t\tfalse :\n\n\t\t// Nodes accept data unless otherwise specified; rejection can be conditional\n\t\t!noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n};\n\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\n\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t// can't GC object references properly across the DOM-JS boundary\n\t\tisNode = elem.nodeType,\n\n\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t// attached directly to the object so GC can occur automatically\n\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t// Avoid doing any more work than we need to when trying to get data on an\n\t// object that has no data at all\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t// ends up in the global cache\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\t// Avoid exposing jQuery metadata on plain JS objects when the object\n\t\t// is serialized using JSON.stringify\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\n\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t// shallow copied over onto the existing cache\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\n\t// jQuery data() is stored in a separate object inside the object's internal data\n\t// cache in order to avoid key collisions between internal data and user-defined\n\t// data.\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\n\t// Check for both converted-to-camel and non-converted data property names\n\t// If a data property was specified\n\tif ( typeof name === \"string\" ) {\n\n\t\t// First Try to find as-is property data\n\t\tret = thisCache[ name ];\n\n\t\t// Test for null|undefined property data\n\t\tif ( ret == null ) {\n\n\t\t\t// Try to find the camelCased property\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\n\t\t// See jQuery.data for more information\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t// If there is already no cache entry for this object, there is no\n\t// purpose in continuing\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\n\t\t\t// Support array or space separated string names for data keys\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\n\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t// and let the cache object itself get destroyed\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// See jQuery.data for more information\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\n\t\t// Don't destroy the parent cache unless the internal data object\n\t\t// had been the only thing left in it\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Destroy the cache\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\n\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\n\t// When all else fails, null\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\n\t// The following elements (space-suffixed to avoid Object.prototype collisions)\n\t// throw uncatchable exceptions if you attempt to set expando properties\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t// ...but Flash objects (which have this classid) *can* handle expandos\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Special expections of .data basically thwart jQuery.access,\n\t\t// so implement the relevant behavior ourselves\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\n\t\t\t// Sets one value\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\n\t\t\t// Gets one value\n\t\t\t// Try to fetch any internally stored data first\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\t// Minified: var a,b,c\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\n\t// Setup\n\tdiv.innerHTML = \"
a\";\n\n\t// IE strips leading whitespace when .innerHTML is used\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\n\t// Make sure that tbody elements aren't automatically inserted\n\t// IE will insert them into empty tables\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\n\t// Make sure that link elements get serialized correctly by innerHTML\n\t// This requires a wrapper element in IE\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\n\t// Makes sure cloning an html5 element does not cause problems\n\t// Where outerHTML is undefined, this still works\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav>\";\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\t// Support: IE6-IE11+\n\tdiv.innerHTML = \"\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<9\n\t// Opera does not clone events (and typeof div.attachEvent === undefined).\n\t// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486,#12518)\n\t\t\t\t\t\t// only reproducible on winXP IE8 native, not IE9 in IE8 mode\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Fix target property (#1925)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Support: Chrome 23+, Safari?\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// If we error on focus to hidden element (#1486, #12518),\n\t\t\t\t\t\t// let .trigger() run the handlers\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\t// Support: IE < 9, Android < 4.0\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If preventDefault exists, run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// Support: IE\n\t\t// Otherwise set the returnValue property of the original event to false\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// If stopPropagation exists, run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\t// Support: IE\n\t\t// Set the cancelBubble property of the original event to true\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tjQuery._data( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tjQuery._removeData( doc, fix );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery._data( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event ) dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\t\toption: [ 1, \"\" ],\n\t\tlegend: [ 1, \"
\", \"
\" ],\n\t\tarea: [ 1, \"\", \"\" ],\n\t\tparam: [ 1, \"\", \"\" ],\n\t\tthead: [ 1, \"\", \"
\" ],\n\t\ttr: [ 2, \"\", \"
\" ],\n\t\tcol: [ 2, \"\", \"
\" ],\n\t\ttd: [ 3, \"\", \"
\" ],\n\n\t\t// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n\t\t// unless wrapped in a div with non-breaking characters in front of it.\n\t\t_default: support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X
\", \"
\" ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\n\n// Used in buildFragment, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\n// Support: IE<8\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 copies events bound via attachEvent when using cloneNode.\n\tif ( !support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\n\t\t// Event data gets referenced instead of copied if the expando gets copied too\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\n\t// IE blanks contents when cloning scripts, and tries to evaluate newly-set text\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\n\t// IE6-10 improperly clones children of object elements using classid.\n\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!support.noCloneEvent || !support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\t// Fix all IE cloning issues\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\n\t\t\t// Ensure a safe fragment\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = (rtagName.exec( elem ) || [ \"\", \"\" ])[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1>\" ) + wrap[2];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Manually add leading whitespace removed by IE\n\t\t\t\t\tif ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted from table fragments\n\t\t\t\t\tif ( !support.tbody ) {\n\n\t\t\t\t\t\t// String was a , *may* have spurious \n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\n\t\t\t\t\t\t\t// String was a bare or \n\t\t\t\t\t\t\twrap[1] === \"
\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Fix #12392 for WebKit and IE > 9\n\t\t\t\t\ttmp.textContent = \"\";\n\n\t\t\t\t\t// Fix #12392 for oldIE\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remember the top-level container for proper cleanup\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from fragment\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\n\t\t\t// If this is a select, ensure that it displays empty (#12336)\n\t\t\t// Support: IE<9\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( support.htmlSerialize || !rnoshimcache.test( value ) ) &&\n\t\t\t\t( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ (rtagName.exec( value ) || [ \"\", \"\" ])[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\n\t\t\t// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\t// getDefaultComputedStyle might be reliably used only on attached element\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\n\t\t\t// Use of this method is a temporary fix (more like optmization) until something better comes along,\n\t\t\t// since it was removed from specification and supported only in FF\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = (iframe || jQuery( \"')\n\t\t\tstorageContainer.close()\n\t\t\tstorageOwner = storageContainer.w.frames[0].document\n\t\t\tstorage = storageOwner.createElement('div')\n\t\t} catch(e) {\n\t\t\t// somehow ActiveXObject instantiation failed (perhaps some special\n\t\t\t// security settings or otherwse), fall back to per-path storage\n\t\t\tstorage = doc.createElement('div')\n\t\t\tstorageOwner = doc.body\n\t\t}\n\t\tvar withIEStorage = function(storeFunction) {\n\t\t\treturn function() {\n\t\t\t\tvar args = Array.prototype.slice.call(arguments, 0)\n\t\t\t\targs.unshift(storage)\n\t\t\t\t// See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx\n\t\t\t\t// and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx\n\t\t\t\tstorageOwner.appendChild(storage)\n\t\t\t\tstorage.addBehavior('#default#userData')\n\t\t\t\tstorage.load(localStorageName)\n\t\t\t\tvar result = storeFunction.apply(store, args)\n\t\t\t\tstorageOwner.removeChild(storage)\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\n\t\t// In IE7, keys cannot start with a digit or contain certain chars.\n\t\t// See https://github.com/marcuswestin/store.js/issues/40\n\t\t// See https://github.com/marcuswestin/store.js/issues/83\n\t\tvar forbiddenCharsRegex = new RegExp(\"[!\\\"#$%&'()*+,/\\\\\\\\:;<=>?@[\\\\]^`{|}~]\", \"g\")\n\t\tfunction ieKeyFix(key) {\n\t\t\treturn key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')\n\t\t}\n\t\tstore.set = withIEStorage(function(storage, key, val) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tif (val === undefined) { return store.remove(key) }\n\t\t\tstorage.setAttribute(key, store.serialize(val))\n\t\t\tstorage.save(localStorageName)\n\t\t\treturn val\n\t\t})\n\t\tstore.get = withIEStorage(function(storage, key, defaultVal) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tvar val = store.deserialize(storage.getAttribute(key))\n\t\t\treturn (val === undefined ? defaultVal : val)\n\t\t})\n\t\tstore.remove = withIEStorage(function(storage, key) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tstorage.removeAttribute(key)\n\t\t\tstorage.save(localStorageName)\n\t\t})\n\t\tstore.clear = withIEStorage(function(storage) {\n\t\t\tvar attributes = storage.XMLDocument.documentElement.attributes\n\t\t\tstorage.load(localStorageName)\n\t\t\tfor (var i=0, attr; attr=attributes[i]; i++) {\n\t\t\t\tstorage.removeAttribute(attr.name)\n\t\t\t}\n\t\t\tstorage.save(localStorageName)\n\t\t})\n\t\tstore.getAll = function(storage) {\n\t\t\tvar ret = {}\n\t\t\tstore.forEach(function(key, val) {\n\t\t\t\tret[key] = val\n\t\t\t})\n\t\t\treturn ret\n\t\t}\n\t\tstore.forEach = withIEStorage(function(storage, callback) {\n\t\t\tvar attributes = storage.XMLDocument.documentElement.attributes\n\t\t\tfor (var i=0, attr; attr=attributes[i]; ++i) {\n\t\t\t\tcallback(attr.name, store.deserialize(storage.getAttribute(attr.name)))\n\t\t\t}\n\t\t})\n\t}\n\n\ttry {\n\t\tvar testKey = '__storejs__'\n\t\tstore.set(testKey, testKey)\n\t\tif (store.get(testKey) != testKey) { store.disabled = true }\n\t\tstore.remove(testKey)\n\t} catch(e) {\n\t\tstore.disabled = true\n\t}\n\tstore.enabled = !store.disabled\n\n\tif (typeof module != 'undefined' && module.exports && this.module !== module) { module.exports = store }\n\telse if (typeof define === 'function' && define.amd) { define(store) }\n\telse { win.store = store }\n\n})(Function('return this')());\n\n},{}],18:[function(require,module,exports){\nmodule.exports={\n \"name\": \"yasgui-utils\",\n \"version\": \"1.6.0\",\n \"description\": \"Utils for YASGUI libs\",\n \"main\": \"src/main.js\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/YASGUI/Utils.git\"\n },\n \"licenses\": [\n {\n \"type\": \"MIT\",\n \"url\": \"http://yasgui.github.io/license.txt\"\n }\n ],\n \"author\": \"Laurens Rietveld\",\n \"maintainers\": [\n {\n \"name\": \"Laurens Rietveld\",\n \"email\": \"laurens.rietveld@gmail.com\",\n \"web\": \"http://laurensrietveld.nl\"\n }\n ],\n \"bugs\": {\n \"url\": \"https://github.com/YASGUI/Utils/issues\"\n },\n \"homepage\": \"https://github.com/YASGUI/Utils\",\n \"dependencies\": {\n \"store\": \"^1.3.14\"\n }\n}\n\n},{}],19:[function(require,module,exports){\nwindow.console = window.console || {\"log\":function(){}};//make sure any console statements don't break IE\nmodule.exports = {\n\tstorage: require(\"./storage.js\"),\n\tsvg: require(\"./svg.js\"),\n\tversion: {\n\t\t\"yasgui-utils\" : require(\"../package.json\").version,\n\t},\n\tnestedExists : function(obj) {\n\t\tvar args = Array.prototype.slice.call(arguments, 1);\n\n\t\tfor (var i = 0; i < args.length; i++) {\n\t\t\tif (!obj || !obj.hasOwnProperty(args[i])) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tobj = obj[args[i]];\n\t\t}\n\t\treturn true;\n\t}\n};\n\n},{\"../package.json\":18,\"./storage.js\":20,\"./svg.js\":21}],20:[function(require,module,exports){\nvar store = require(\"store\");\nvar times = {\n\tday: function() {\n\t\treturn 1000 * 3600 * 24;//millis to day\n\t},\n\tmonth: function() {\n\t\ttimes.day() * 30;\n\t},\n\tyear: function() {\n\t\ttimes.month() * 12;\n\t}\n};\n\nvar root = module.exports = {\n\tset : function(key, val, exp) {\n if (!store.enabled) return;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (key && val !== undefined) {\n\t\t\tif (typeof exp == \"string\") {\n\t\t\t\texp = times[exp]();\n\t\t\t}\n\t\t\t//try to store string for dom objects (e.g. XML result). Otherwise, we might get a circular reference error when stringifying this\n\t\t\tif (val.documentElement) val = new XMLSerializer().serializeToString(val.documentElement);\n\t\t\tstore.set(key, {\n\t\t\t\tval : val,\n\t\t\t\texp : exp,\n\t\t\t\ttime : new Date().getTime()\n\t\t\t});\n\t\t}\n\t},\n\tremove: function(key) {\n\t\tif (!store.enabled) return;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (key) store.remove(key)\n\t},\n\tremoveAll: function(filter) {\n\t\tif (!store.enabled) return;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (typeof filter === 'function') {\n\t\t\tfor (var key in store.getAll()) {\n\t\t\t\tif (filter(key, root.get(key))) root.remove(key);\n\t\t\t}\n\t\t}\n\t},\n\tget : function(key) {\n if (!store.enabled) return null;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (key) {\n\t\t\tvar info = store.get(key);\n\t\t\tif (!info) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (info.exp && new Date().getTime() - info.time > info.exp) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn info.val;\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n};\n\n},{\"store\":17}],21:[function(require,module,exports){\nmodule.exports = {\n\tdraw: function(parent, svgString) {\n\t\tif (!parent) return;\n\t\tvar el = module.exports.getElement(svgString);\n\t\tif (el) {\n\t\t\tif (parent.append) {\n\t\t\t\tparent.append(el);\n\t\t\t} else {\n\t\t\t\t//regular dom doc\n\t\t\t\tparent.appendChild(el);\n\t\t\t}\n\t\t}\n\t},\n\tgetElement: function(svgString) {\n\t\tif (svgString && svgString.indexOf(\" 0) {\n\t\t\t//position completion notifications\n\t\t\tvar scrollBar = $(yasqe.getWrapperElement()).find(\".CodeMirror-vscrollbar\");\n\t\t\tvar offset = 0;\n\t\t\tif (scrollBar.is(\":visible\")) {\n\t\t\t\toffset = scrollBar.outerWidth();\n\t\t\t}\n\t\t\tneedPossibleAdjustment.forEach(function(notification) {\n\t\t\t\tnotification.css(\"right\", offset)\n\t\t\t});\n\t\t}\n\t});\n\n\n\n\t/**\n\t * Store bulk completions in memory as trie, and store these in localstorage as well (if enabled)\n\t * \n\t * @method doc.storeBulkCompletions\n\t * @param completions {array}\n\t */\n\tvar storeBulkCompletions = function(completer, completions) {\n\t\t// store array as trie\n\t\ttries[completer.name] = new Trie();\n\t\tfor (var i = 0; i < completions.length; i++) {\n\t\t\ttries[completer.name].insert(completions[i]);\n\t\t}\n\t\t// store in localstorage as well\n\t\tvar storageId = utils.getPersistencyId(yasqe, completer.persistent);\n\t\tif (storageId) yutils.storage.set(storageId, completions, \"month\");\n\t};\n\n\tvar initCompleter = function(name, completionInit) {\n\t\tvar completer = completers[name] = new completionInit(yasqe, name);\n\t\tcompleter.name = name;\n\t\tif (completer.bulk) {\n\t\t\tvar storeArrayAsBulk = function(suggestions) {\n\t\t\t\tif (suggestions && suggestions instanceof Array && suggestions.length > 0) {\n\t\t\t\t\tstoreBulkCompletions(completer, suggestions);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (completer.get instanceof Array) {\n\t\t\t\t// we don't care whether the completions are already stored in\n\t\t\t\t// localstorage. just use this one\n\t\t\t\tstoreArrayAsBulk(completer.get);\n\t\t\t} else {\n\t\t\t\t// if completions are defined in localstorage, use those! (calling the\n\t\t\t\t// function may come with overhead (e.g. async calls))\n\t\t\t\tvar completionsFromStorage = null;\n\t\t\t\tvar persistencyIdentifier = utils.getPersistencyId(yasqe, completer.persistent);\n\t\t\t\tif (persistencyIdentifier)\n\t\t\t\t\tcompletionsFromStorage = yutils.storage.get(persistencyIdentifier);\n\t\t\t\tif (completionsFromStorage && completionsFromStorage.length > 0) {\n\t\t\t\t\tstoreArrayAsBulk(completionsFromStorage);\n\t\t\t\t} else {\n\t\t\t\t\t// nothing in storage. check whether we have a function via which we\n\t\t\t\t\t// can get our prefixes\n\t\t\t\t\tif (completer.get instanceof Function) {\n\t\t\t\t\t\tif (completer.async) {\n\t\t\t\t\t\t\tcompleter.get(null, storeArrayAsBulk);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstoreArrayAsBulk(completer.get());\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tvar autoComplete = function(fromAutoShow) {\n\t\tif (yasqe.somethingSelected())\n\t\t\treturn;\n\t\tvar tryHintType = function(completer) {\n\t\t\tif (fromAutoShow // from autoShow, i.e. this gets called each time the editor content changes\n\t\t\t\t&& (!completer.autoShow // autoshow for this particular type of autocompletion is -not- enabled\n\t\t\t\t\t|| (!completer.bulk && completer.async)) // async is enabled (don't want to re-do ajax-like request for every editor change)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar hintConfig = {\n\t\t\t\tcloseCharacters: /(?=a)b/,\n\t\t\t\tcompleteSingle: false\n\t\t\t};\n\t\t\tif (!completer.bulk && completer.async) {\n\t\t\t\thintConfig.async = true;\n\t\t\t}\n\t\t\tvar wrappedHintCallback = function(yasqe, callback) {\n\t\t\t\treturn getCompletionHintsObject(completer, callback);\n\t\t\t};\n\t\t\tvar result = YASQE.showHint(yasqe, wrappedHintCallback, hintConfig);\n\t\t\treturn true;\n\t\t};\n\t\tfor (var completerName in completers) {\n\t\t\tif ($.inArray(completerName, yasqe.options.autocompleters) == -1) continue; //this completer is disabled\n\t\t\tvar completer = completers[completerName];\n\t\t\tif (!completer.isValidCompletionPosition) continue; //no way to check whether we are in a valid position\n\n\t\t\tif (!completer.isValidCompletionPosition()) {\n\t\t\t\t//if needed, fire callbacks for when we are -not- in valid completion position\n\t\t\t\tif (completer.callbacks && completer.callbacks.invalidPosition) {\n\t\t\t\t\tcompleter.callbacks.invalidPosition(yasqe, completer);\n\t\t\t\t}\n\t\t\t\t//not in a valid position, so continue to next completion candidate type\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// run valid position handler, if there is one (if it returns false, stop the autocompletion!)\n\t\t\tif (completer.callbacks && completer.callbacks.validPosition) {\n\t\t\t\tif (completer.callbacks.validPosition(yasqe, completer) === false)\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar success = tryHintType(completer);\n\t\t\tif (success)\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\n\n\tvar getCompletionHintsObject = function(completer, callback) {\n\t\tvar getSuggestionsFromToken = function(partialToken) {\n\t\t\tvar stringToAutocomplete = partialToken.autocompletionString || partialToken.string;\n\t\t\tvar suggestions = [];\n\t\t\tif (tries[completer.name]) {\n\t\t\t\tsuggestions = tries[completer.name].autoComplete(stringToAutocomplete);\n\t\t\t} else if (typeof completer.get == \"function\" && completer.async == false) {\n\t\t\t\tsuggestions = completer.get(stringToAutocomplete);\n\t\t\t} else if (typeof completer.get == \"object\") {\n\t\t\t\tvar partialTokenLength = stringToAutocomplete.length;\n\t\t\t\tfor (var i = 0; i < completer.get.length; i++) {\n\t\t\t\t\tvar completion = completer.get[i];\n\t\t\t\t\tif (completion.slice(0, partialTokenLength) == stringToAutocomplete) {\n\t\t\t\t\t\tsuggestions.push(completion);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn getSuggestionsAsHintObject(suggestions, completer, partialToken);\n\n\t\t};\n\n\n\t\tvar token = yasqe.getCompleteToken();\n\t\tif (completer.preProcessToken) {\n\t\t\ttoken = completer.preProcessToken(token);\n\t\t}\n\n\t\tif (token) {\n\t\t\t// use custom completionhint function, to avoid reaching a loop when the\n\t\t\t// completionhint is the same as the current token\n\t\t\t// regular behaviour would keep changing the codemirror dom, hence\n\t\t\t// constantly calling this callback\n\t\t\tif (!completer.bulk && completer.async) {\n\t\t\t\tvar wrappedCallback = function(suggestions) {\n\t\t\t\t\tcallback(getSuggestionsAsHintObject(suggestions, completer, token));\n\t\t\t\t};\n\t\t\t\tcompleter.get(token, wrappedCallback);\n\t\t\t} else {\n\t\t\t\treturn getSuggestionsFromToken(token);\n\n\t\t\t}\n\t\t}\n\t};\n\n\n\t/**\n\t * get our array of suggestions (strings) in the codemirror hint format\n\t */\n\tvar getSuggestionsAsHintObject = function(suggestions, completer, token) {\n\t\tvar hintList = [];\n\t\tfor (var i = 0; i < suggestions.length; i++) {\n\t\t\tvar suggestedString = suggestions[i];\n\t\t\tif (completer.postProcessToken) {\n\t\t\t\tsuggestedString = completer.postProcessToken(token, suggestedString);\n\t\t\t}\n\t\t\thintList.push({\n\t\t\t\ttext: suggestedString,\n\t\t\t\tdisplayText: suggestedString,\n\t\t\t\thint: selectHint,\n\t\t\t});\n\t\t}\n\n\t\tvar cur = yasqe.getCursor();\n\t\tvar returnObj = {\n\t\t\tcompletionToken: token.string,\n\t\t\tlist: hintList,\n\t\t\tfrom: {\n\t\t\t\tline: cur.line,\n\t\t\t\tch: token.start\n\t\t\t},\n\t\t\tto: {\n\t\t\t\tline: cur.line,\n\t\t\t\tch: token.end\n\t\t\t}\n\t\t};\n\t\t//if we have some autocompletion handlers specified, add these these to the object. Codemirror will take care of firing these\n\t\tif (completer.callbacks) {\n\t\t\tfor (var callbackName in completer.callbacks) {\n\t\t\t\tif (completer.callbacks[callbackName]) {\n\t\t\t\t\tYASQE.on(returnObj, callbackName, completer.callbacks[callbackName]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn returnObj;\n\t};\n\n\treturn {\n\t\tinit: initCompleter,\n\t\tcompleters: completers,\n\t\tnotifications: {\n\t\t\tgetEl: function(completer) {\n\t\t\t\treturn $(completionNotifications[completer.name]);\n\t\t\t},\n\t\t\tshow: function(yasqe, completer) {\n\t\t\t\t//only draw when the user needs to use a keypress to summon autocompletions\n\t\t\t\tif (!completer.autoshow) {\n\t\t\t\t\tif (!completionNotifications[completer.name]) completionNotifications[completer.name] = $(\"
\");\n\t\t\t\t\tcompletionNotifications[completer.name]\n\t\t\t\t\t\t.show()\n\t\t\t\t\t\t.text(\"Press \" + (navigator.userAgent.indexOf('Mac OS X') != -1 ? \"CMD\" : \"CTRL\") + \" - to autocomplete\")\n\t\t\t\t\t\t.appendTo($(yasqe.getWrapperElement()));\n\t\t\t\t}\n\t\t\t},\n\t\t\thide: function(yasqe, completer) {\n\t\t\t\tif (completionNotifications[completer.name]) {\n\t\t\t\t\tcompletionNotifications[completer.name].hide();\n\t\t\t\t}\n\t\t\t}\n\n\t\t},\n\t\tautoComplete: autoComplete,\n\t\tgetTrie: function(completer) {\n\t\t\treturn (typeof completer == \"string\" ? tries[completer] : tries[completer.name]);\n\t\t}\n\t}\n};\n\n\n\n\n\n\n\n\n\n/**\n * function which fires after the user selects a completion. this function checks whether we actually need to store this one (if completion is same as current token, don't do anything)\n */\nvar selectHint = function(yasqe, data, completion) {\n\tif (completion.text != yasqe.getTokenAt(yasqe.getCursor()).string) {\n\t\tyasqe.replaceRange(completion.text, data.from, data.to);\n\t}\n};\n\n\n\n\n\n//\n//module.exports = {\n//\tpreprocessPrefixTokenForCompletion: preprocessPrefixTokenForCompletion,\n//\tpostprocessResourceTokenForCompletion: postprocessResourceTokenForCompletion,\n//\tpreprocessResourceTokenForCompletion: preprocessResourceTokenForCompletion,\n//\tshowCompletionNotification: showCompletionNotification,\n//\thideCompletionNotification: hideCompletionNotification,\n//\tautoComplete: autoComplete,\n//\tautocompleteVariables: autocompleteVariables,\n//\tfetchFromPrefixCc: fetchFromPrefixCc,\n//\tfetchFromLov: fetchFromLov,\n////\tstoreBulkCompletions: storeBulkCompletions,\n//\tloadBulkCompletions: loadBulkCompletions,\n//};\n},{\"../../lib/trie.js\":5,\"../main.js\":31,\"../utils.js\":37,\"jquery\":16,\"yasgui-utils\":19}],24:[function(require,module,exports){\n'use strict';\nvar $ = require('jquery');\nmodule.exports = function(yasqe, name) {\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\treturn module.exports.isValidCompletionPosition(yasqe);\n\t\t},\n\t\tget: function(token, callback) {\n\t\t\treturn require('./utils').fetchFromLov(yasqe, this, token, callback);\n\t\t},\n\t\tpreProcessToken: function(token) {\n\t\t\treturn module.exports.preProcessToken(yasqe, token)\n\t\t},\n\t\tpostProcessToken: function(token, suggestedString) {\n\t\t\treturn module.exports.postProcessToken(yasqe, token, suggestedString);\n\t\t},\n\t\tasync: true,\n\t\tbulk: false,\n\t\tautoShow: false,\n\t\tpersistent: name,\n\t\tcallbacks: {\n\t\t\tvalidPosition: yasqe.autocompleters.notifications.show,\n\t\t\tinvalidPosition: yasqe.autocompleters.notifications.hide,\n\t\t}\n\t}\n};\n\nmodule.exports.isValidCompletionPosition = function(yasqe) {\n\tvar token = yasqe.getCompleteToken();\n\tif (token.string.indexOf(\"?\") == 0)\n\t\treturn false;\n\tvar cur = yasqe.getCursor();\n\tvar previousToken = yasqe.getPreviousNonWsToken(cur.line, token);\n\tif (previousToken.string == \"a\")\n\t\treturn true;\n\tif (previousToken.string == \"rdf:type\")\n\t\treturn true;\n\tif (previousToken.string == \"rdfs:domain\")\n\t\treturn true;\n\tif (previousToken.string == \"rdfs:range\")\n\t\treturn true;\n\treturn false;\n};\nmodule.exports.preProcessToken = function(yasqe, token) {\n\treturn require('./utils.js').preprocessResourceTokenForCompletion(yasqe, token);\n};\nmodule.exports.postProcessToken = function(yasqe, token, suggestedString) {\n\treturn require('./utils.js').postprocessResourceTokenForCompletion(yasqe, token, suggestedString)\n};\n},{\"./utils\":27,\"./utils.js\":27,\"jquery\":16}],25:[function(require,module,exports){\n'use strict';\nvar $ = require('jquery');\n//this is a mapping from the class names (generic ones, for compatability with codemirror themes), to what they -actually- represent\nvar tokenTypes = {\n\t\"string-2\": \"prefixed\",\n\t\"atom\": \"var\"\n};\n\nmodule.exports = function(yasqe, completerName) {\n\t//this autocompleter also fires on-change!\n\tyasqe.on(\"change\", function() {\n\t\tmodule.exports.appendPrefixIfNeeded(yasqe, completerName);\n\t});\n\n\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\treturn module.exports.isValidCompletionPosition(yasqe);\n\t\t},\n\t\tget: function(token, callback) {\n\t\t\t$.get(\"http://prefix.cc/popular/all.file.json\", function(data) {\n\t\t\t\tvar prefixArray = [];\n\t\t\t\tfor (var prefix in data) {\n\t\t\t\t\tif (prefix == \"bif\")\n\t\t\t\t\t\tcontinue; // skip this one! see #231\n\t\t\t\t\tvar completeString = prefix + \": <\" + data[prefix] + \">\";\n\t\t\t\t\tprefixArray.push(completeString); // the array we want to store in localstorage\n\t\t\t\t}\n\n\t\t\t\tprefixArray.sort();\n\t\t\t\tcallback(prefixArray);\n\t\t\t});\n\t\t},\n\t\tpreProcessToken: function(token) {\n\t\t\treturn module.exports.preprocessPrefixTokenForCompletion(yasqe, token)\n\t\t},\n\t\tasync: true,\n\t\tbulk: true,\n\t\tautoShow: true,\n\t\tpersistent: completerName,\n\t\tcallbacks: {\n\t\t\tpick: function() {\n\t\t\t\tyasqe.collapsePrefixes(false);\n\t\t\t}\n\t\t}\n\t};\n};\nmodule.exports.isValidCompletionPosition = function(yasqe) {\n\tvar cur = yasqe.getCursor(),\n\t\ttoken = yasqe.getTokenAt(cur);\n\n\t// not at end of line\n\tif (yasqe.getLine(cur.line).length > cur.ch)\n\t\treturn false;\n\n\tif (token.type != \"ws\") {\n\t\t// we want to complete token, e.g. when the prefix starts with an a\n\t\t// (treated as a token in itself..)\n\t\t// but we to avoid including the PREFIX tag. So when we have just\n\t\t// typed a space after the prefix tag, don't get the complete token\n\t\ttoken = yasqe.getCompleteToken();\n\t}\n\n\t// we shouldnt be at the uri part the prefix declaration\n\t// also check whether current token isnt 'a' (that makes codemirror\n\t// thing a namespace is a possiblecurrent\n\tif (!token.string.indexOf(\"a\") == 0 && $.inArray(\"PNAME_NS\", token.state.possibleCurrent) == -1)\n\t\treturn false;\n\n\t// First token of line needs to be PREFIX,\n\t// there should be no trailing text (otherwise, text is wrongly inserted\n\t// in between)\n\tvar previousToken = yasqe.getPreviousNonWsToken(cur.line, token);\n\tif (!previousToken || previousToken.string.toUpperCase() != \"PREFIX\") return false;\n\treturn true;\n};\nmodule.exports.preprocessPrefixTokenForCompletion = function(yasqe, token) {\n\tvar previousToken = yasqe.getPreviousNonWsToken(yasqe.getCursor().line, token);\n\tif (previousToken && previousToken.string && previousToken.string.slice(-1) == \":\") {\n\t\t//combine both tokens! In this case we have the cursor at the end of line \"PREFIX bla: <\".\n\t\t//we want the token to be \"bla: <\", en not \"<\"\n\t\ttoken = {\n\t\t\tstart: previousToken.start,\n\t\t\tend: token.end,\n\t\t\tstring: previousToken.string + \" \" + token.string,\n\t\t\tstate: token.state\n\t\t};\n\t}\n\treturn token;\n};\n/**\n * Check whether typed prefix is declared. If not, automatically add declaration\n * using list from prefix.cc\n * \n * @param yasqe\n */\nmodule.exports.appendPrefixIfNeeded = function(yasqe, completerName) {\n\tif (!yasqe.autocompleters.getTrie(completerName))\n\t\treturn; // no prefixed defined. just stop\n\tif (!yasqe.options.autocompleters || yasqe.options.autocompleters.indexOf(completerName) == -1) return; //this autocompleter is disabled\n\tvar cur = yasqe.getCursor();\n\n\tvar token = yasqe.getTokenAt(cur);\n\tif (tokenTypes[token.type] == \"prefixed\") {\n\t\tvar colonIndex = token.string.indexOf(\":\");\n\t\tif (colonIndex !== -1) {\n\t\t\t// check previous token isnt PREFIX, or a '<'(which would mean we are in a uri)\n\t\t\t//\t\t\tvar firstTokenString = yasqe.getNextNonWsToken(cur.line).string.toUpperCase();\n\t\t\tvar lastNonWsTokenString = yasqe.getPreviousNonWsToken(cur.line, token).string.toUpperCase();\n\t\t\tvar previousToken = yasqe.getTokenAt({\n\t\t\t\tline: cur.line,\n\t\t\t\tch: token.start\n\t\t\t}); // needs to be null (beginning of line), or whitespace\n\t\t\tif (lastNonWsTokenString != \"PREFIX\" && (previousToken.type == \"ws\" || previousToken.type == null)) {\n\t\t\t\t// check whether it isnt defined already (saves us from looping\n\t\t\t\t// through the array)\n\t\t\t\tvar currentPrefix = token.string.substring(0, colonIndex + 1);\n\t\t\t\tvar queryPrefixes = yasqe.getPrefixesFromQuery();\n\t\t\t\tif (queryPrefixes[currentPrefix.slice(0, -1)] == null) {\n\t\t\t\t\t// ok, so it isnt added yet!\n\t\t\t\t\tvar completions = yasqe.autocompleters.getTrie(completerName).autoComplete(currentPrefix);\n\t\t\t\t\tif (completions.length > 0) {\n\t\t\t\t\t\tyasqe.addPrefixes(completions[0]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n},{\"jquery\":16}],26:[function(require,module,exports){\n'use strict';\nvar $ = require('jquery');\nmodule.exports = function(yasqe, name) {\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\treturn module.exports.isValidCompletionPosition(yasqe);\n\t\t},\n\t\tget: function(token, callback) {\n\t\t\treturn require('./utils').fetchFromLov(yasqe, this, token, callback);\n\t\t},\n\t\tpreProcessToken: function(token) {\n\t\t\treturn module.exports.preProcessToken(yasqe, token)\n\t\t},\n\t\tpostProcessToken: function(token, suggestedString) {\n\t\t\treturn module.exports.postProcessToken(yasqe, token, suggestedString);\n\t\t},\n\t\tasync: true,\n\t\tbulk: false,\n\t\tautoShow: false,\n\t\tpersistent: name,\n\t\tcallbacks: {\n\t\t\tvalidPosition: yasqe.autocompleters.notifications.show,\n\t\t\tinvalidPosition: yasqe.autocompleters.notifications.hide,\n\t\t}\n\t}\n};\n\nmodule.exports.isValidCompletionPosition = function(yasqe) {\n\tvar token = yasqe.getCompleteToken();\n\tif (token.string.length == 0)\n\t\treturn false; //we want -something- to autocomplete\n\tif (token.string.indexOf(\"?\") == 0)\n\t\treturn false; // we are typing a var\n\tif ($.inArray(\"a\", token.state.possibleCurrent) >= 0)\n\t\treturn true; // predicate pos\n\tvar cur = yasqe.getCursor();\n\tvar previousToken = yasqe.getPreviousNonWsToken(cur.line, token);\n\tif (previousToken.string == \"rdfs:subPropertyOf\")\n\t\treturn true;\n\n\t// hmm, we would like -better- checks here, e.g. checking whether we are\n\t// in a subject, and whether next item is a rdfs:subpropertyof.\n\t// difficult though... the grammar we use is unreliable when the query\n\t// is invalid (i.e. during typing), and often the predicate is not typed\n\t// yet, when we are busy writing the subject...\n\treturn false;\n};\nmodule.exports.preProcessToken = function(yasqe, token) {\n\treturn require('./utils.js').preprocessResourceTokenForCompletion(yasqe, token);\n};\nmodule.exports.postProcessToken = function(yasqe, token, suggestedString) {\n\treturn require('./utils.js').postprocessResourceTokenForCompletion(yasqe, token, suggestedString)\n};\n},{\"./utils\":27,\"./utils.js\":27,\"jquery\":16}],27:[function(require,module,exports){\n'use strict';\nvar $ = require('jquery'),\n\tutils = require('./utils.js'),\n\tyutils = require('yasgui-utils');\n/**\n * Where the base class only contains functionality related to -all- completions, this class contains some utils used here and there in our autocompletions\n */\n\n\n\n/**\n * Converts rdf:type to http://.../type and converts to http://...\n * Stores additional info such as the used namespace and prefix in the token object\n */\nvar preprocessResourceTokenForCompletion = function(yasqe, token) {\n\tvar queryPrefixes = yasqe.getPrefixesFromQuery();\n\tif (!token.string.indexOf(\"<\") == 0) {\n\t\ttoken.tokenPrefix = token.string.substring(0, token.string.indexOf(\":\") + 1);\n\n\t\tif (queryPrefixes[token.tokenPrefix.slice(0, -1)] != null) {\n\t\t\ttoken.tokenPrefixUri = queryPrefixes[token.tokenPrefix.slice(0, -1)];\n\t\t}\n\t}\n\n\ttoken.autocompletionString = token.string.trim();\n\tif (!token.string.indexOf(\"<\") == 0 && token.string.indexOf(\":\") > -1) {\n\t\t// hmm, the token is prefixed. We still need the complete uri for autocompletions. generate this!\n\t\tfor (var prefix in queryPrefixes) {\n\t\t\tif (token.string.indexOf(prefix) == 0) {\n\t\t\t\ttoken.autocompletionString = queryPrefixes[prefix];\n\t\t\t\ttoken.autocompletionString += token.string.substring(prefix.length + 1);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (token.autocompletionString.indexOf(\"<\") == 0) token.autocompletionString = token.autocompletionString.substring(1);\n\tif (token.autocompletionString.indexOf(\">\", token.length - 1) !== -1) token.autocompletionString = token.autocompletionString.substring(0, token.autocompletionString.length - 1);\n\treturn token;\n};\n\nvar postprocessResourceTokenForCompletion = function(yasqe, token, suggestedString) {\n\tif (token.tokenPrefix && token.autocompletionString && token.tokenPrefixUri) {\n\t\t// we need to get the suggested string back to prefixed form\n\t\tsuggestedString = token.tokenPrefix + suggestedString.substring(token.tokenPrefixUri.length);\n\t} else {\n\t\t// it is a regular uri. add '<' and '>' to string\n\t\tsuggestedString = \"<\" + suggestedString + \">\";\n\t}\n\treturn suggestedString;\n};\n\nvar fetchFromLov = function(yasqe, completer, token, callback) {\n\tif (!token || !token.string || token.string.trim().length == 0) {\n\t\tyasqe.autocompleters.notifications.getEl(completer)\n\t\t\t.empty()\n\t\t\t.append(\"Nothing to autocomplete yet!\");\n\t\treturn false;\n\t}\n\tvar maxResults = 50;\n\n\tvar args = {\n\t\tq: token.autocompletionString,\n\t\tpage: 1\n\t};\n\tif (completer.name == \"classes\") {\n\t\targs.type = \"class\";\n\t} else {\n\t\targs.type = \"property\";\n\t}\n\tvar results = [];\n\tvar url = \"\";\n\tvar updateUrl = function() {\n\t\turl = \"http://lov.okfn.org/dataset/lov/api/v2/autocomplete/terms?\" + $.param(args);\n\t};\n\tupdateUrl();\n\tvar increasePage = function() {\n\t\targs.page++;\n\t\tupdateUrl();\n\t};\n\tvar doRequests = function() {\n\t\t$.get(\n\t\t\turl,\n\t\t\tfunction(data) {\n\t\t\t\tfor (var i = 0; i < data.results.length; i++) {\n\t\t\t\t\tif ($.isArray(data.results[i].uri) && data.results[i].uri.length > 0) {\n\t\t\t\t\t\tresults.push(data.results[i].uri[0]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresults.push(data.results[i].uri);\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\tif (results.length < data.total_results && results.length < maxResults) {\n\t\t\t\t\tincreasePage();\n\t\t\t\t\tdoRequests();\n\t\t\t\t} else {\n\t\t\t\t\t//if notification bar is there, show feedback, or close\n\t\t\t\t\tif (results.length > 0) {\n\t\t\t\t\t\tyasqe.autocompleters.notifications.hide(yasqe, completer)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tyasqe.autocompleters.notifications.getEl(completer).text(\"0 matches found...\");\n\t\t\t\t\t}\n\t\t\t\t\tcallback(results);\n\t\t\t\t\t// requests done! Don't call this function again\n\t\t\t\t}\n\t\t\t}).fail(function(jqXHR, textStatus, errorThrown) {\n\t\t\tyasqe.autocompleters.notifications.getEl(completer)\n\t\t\t\t.empty()\n\t\t\t\t.append(\"Failed fetching suggestions..\");\n\n\t\t});\n\t};\n\t//if notification bar is there, show a loader\n\tyasqe.autocompleters.notifications.getEl(completer)\n\t\t.empty()\n\t\t.append($(\"Fetchting autocompletions  \"))\n\t\t.append($(yutils.svg.getElement(require('../imgs.js').loader)).addClass(\"notificationLoader\"));\n\tdoRequests();\n};\n\n\n\nmodule.exports = {\n\tfetchFromLov: fetchFromLov,\n\tpreprocessResourceTokenForCompletion: preprocessResourceTokenForCompletion,\n\tpostprocessResourceTokenForCompletion: postprocessResourceTokenForCompletion,\n};\n},{\"../imgs.js\":30,\"./utils.js\":27,\"jquery\":16,\"yasgui-utils\":19}],28:[function(require,module,exports){\n'use strict';\nvar $ = require('jquery');\nmodule.exports = function(yasqe) {\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\tvar token = yasqe.getTokenAt(yasqe.getCursor());\n\t\t\tif (token.type != \"ws\") {\n\t\t\t\ttoken = yasqe.getCompleteToken(token);\n\t\t\t\tif (token && token.string.indexOf(\"?\") == 0) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tget: function(token) {\n\t\t\tif (token.trim().length == 0) return []; //nothing to autocomplete\n\t\t\tvar distinctVars = {};\n\t\t\t//do this outside of codemirror. I expect jquery to be faster here (just finding dom elements with classnames)\n\t\t\t$(yasqe.getWrapperElement()).find(\".cm-atom\").each(function() {\n\t\t\t\tvar variable = this.innerHTML;\n\t\t\t\tif (variable.indexOf(\"?\") == 0) {\n\t\t\t\t\t//ok, lets check if the next element in the div is an atom as well. In that case, they belong together (may happen sometimes when query is not syntactically valid)\n\t\t\t\t\tvar nextEl = $(this).next();\n\t\t\t\t\tvar nextElClass = nextEl.attr('class');\n\t\t\t\t\tif (nextElClass && nextEl.attr('class').indexOf(\"cm-atom\") >= 0) {\n\t\t\t\t\t\tvariable += nextEl.text();\n\t\t\t\t\t}\n\n\t\t\t\t\t//skip single questionmarks\n\t\t\t\t\tif (variable.length <= 1) return;\n\n\t\t\t\t\t//it should match our token ofcourse\n\t\t\t\t\tif (variable.indexOf(token) !== 0) return;\n\n\t\t\t\t\t//skip exact matches\n\t\t\t\t\tif (variable == token) return;\n\n\t\t\t\t\t//store in map so we have a unique list \n\t\t\t\t\tdistinctVars[variable] = true;\n\n\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar variables = [];\n\t\t\tfor (var variable in distinctVars) {\n\t\t\t\tvariables.push(variable);\n\t\t\t}\n\t\t\tvariables.sort();\n\t\t\treturn variables;\n\t\t},\n\t\tasync: false,\n\t\tbulk: false,\n\t\tautoShow: true,\n\t}\n};\n},{\"jquery\":16}],29:[function(require,module,exports){\n/**\n * The default options of YASQE (check the CodeMirror documentation for even\n * more options, such as disabling line numbers, or changing keyboard shortcut\n * keys). Either change the default options by setting YASQE.defaults, or by\n * passing your own options as second argument to the YASQE constructor\n */\nvar $ = require('jquery'),\n\tYASQE = require('./main.js');\nYASQE.defaults = $.extend(true, {}, YASQE.defaults, {\n\tmode: \"sparql11\",\n\t/**\n\t * Query string\n\t */\n\tvalue: \"PREFIX rdf: \\nPREFIX rdfs: \\nSELECT * WHERE {\\n ?sub ?pred ?obj .\\n} \\nLIMIT 10\",\n\thighlightSelectionMatches: {\n\t\tshowToken: /\\w/\n\t},\n\ttabMode: \"indent\",\n\tlineNumbers: true,\n\tlineWrapping: true,\n\tbackdrop: false,\n\tfoldGutter: {\n\t\trangeFinder: new YASQE.fold.combine(YASQE.fold.brace, YASQE.fold.prefix)\n\t},\n\tcollapsePrefixesOnLoad: false,\n\tgutters: [\"gutterErrorBar\", \"CodeMirror-linenumbers\", \"CodeMirror-foldgutter\"],\n\tmatchBrackets: true,\n\tfixedGutter: true,\n\tsyntaxErrorCheck: true,\n\t/**\n\t * Extra shortcut keys. Check the CodeMirror manual on how to add your own\n\t *\n\t * @property extraKeys\n\t * @type object\n\t */\n\textraKeys: {\n\t\t//\t\t\t\t\t\"Ctrl-Space\" : function(yasqe) {\n\t\t//\t\t\t\t\t\tYASQE.autoComplete(yasqe);\n\t\t//\t\t\t\t\t},\n\t\t\"Ctrl-Space\": YASQE.autoComplete,\n\n\t\t\"Cmd-Space\": YASQE.autoComplete,\n\t\t\"Ctrl-D\": YASQE.deleteLine,\n\t\t\"Ctrl-K\": YASQE.deleteLine,\n\t\t\"Cmd-D\": YASQE.deleteLine,\n\t\t\"Cmd-K\": YASQE.deleteLine,\n\t\t\"Ctrl-/\": YASQE.commentLines,\n\t\t\"Cmd-/\": YASQE.commentLines,\n\t\t\"Ctrl-Alt-Down\": YASQE.copyLineDown,\n\t\t\"Ctrl-Alt-Up\": YASQE.copyLineUp,\n\t\t\"Cmd-Alt-Down\": YASQE.copyLineDown,\n\t\t\"Cmd-Alt-Up\": YASQE.copyLineUp,\n\t\t\"Shift-Ctrl-F\": YASQE.doAutoFormat,\n\t\t\"Shift-Cmd-F\": YASQE.doAutoFormat,\n\t\t\"Ctrl-]\": YASQE.indentMore,\n\t\t\"Cmd-]\": YASQE.indentMore,\n\t\t\"Ctrl-[\": YASQE.indentLess,\n\t\t\"Cmd-[\": YASQE.indentLess,\n\t\t\"Ctrl-S\": YASQE.storeQuery,\n\t\t\"Cmd-S\": YASQE.storeQuery,\n\t\t\"Ctrl-Enter\": YASQE.executeQuery,\n\t\t\"Cmd-Enter\": YASQE.executeQuery,\n\t\t\"F11\": function(yasqe) {\n\t\t\tyasqe.setOption(\"fullScreen\", !yasqe.getOption(\"fullScreen\"));\n\t\t},\n\t\t\"Esc\": function(yasqe) {\n\t\t\tif (yasqe.getOption(\"fullScreen\")) yasqe.setOption(\"fullScreen\", false);\n\t\t}\n\t},\n\tcursorHeight: 0.9,\n\n\n\t/**\n\t * Show a button with which users can create a link to this query. Set this value to null to disable this functionality.\n\t * By default, this feature is enabled, and the only the query value is appended to the link.\n\t * ps. This function should return an object which is parseable by jQuery.param (http://api.jquery.com/jQuery.param/)\n\t */\n\tcreateShareLink: YASQE.createShareLink,\n\n\tcreateShortLink: null,\n\n\t/**\n\t * Consume links shared by others, by checking the url for arguments coming from a query link. Defaults by only checking the 'query=' argument in the url\n\t */\n\tconsumeShareLink: YASQE.consumeShareLink,\n\n\n\n\n\t/**\n\t * Change persistency settings for the YASQE query value. Setting the values\n\t * to null, will disable persistancy: nothing is stored between browser\n\t * sessions Setting the values to a string (or a function which returns a\n\t * string), will store the query in localstorage using the specified string.\n\t * By default, the ID is dynamically generated using the closest dom ID, to avoid collissions when using multiple YASQE items on one\n\t * page\n\t *\n\t * @type function|string\n\t */\n\tpersistent: function(yasqe) {\n\t\treturn \"yasqe_\" + $(yasqe.getWrapperElement()).closest('[id]').attr('id') + \"_queryVal\";\n\t},\n\n\n\t/**\n\t * Settings for querying sparql endpoints\n\t */\n\tsparql: {\n\t\tshowQueryButton: false,\n\n\t\t/**f\n\t\t * Endpoint to query\n\t\t *\n\t\t * @property sparql.endpoint\n\t\t * @type String|function\n\t\t */\n\t\tendpoint: \"http://dbpedia.org/sparql\",\n\t\t/**\n\t\t * Request method via which to access SPARQL endpoint\n\t\t *\n\t\t * @property sparql.requestMethod\n\t\t * @type String|function\n\t\t */\n\t\trequestMethod: \"POST\",\n\n\t\t/**\n\t\t * @type String|function\n\t\t */\n\t\tacceptHeaderGraph: \"text/turtle,*/*;q=0.9\",\n\t\t/**\n\t\t * @type String|function\n\t\t */\n\t\tacceptHeaderSelect: \"application/sparql-results+json,*/*;q=0.9\",\n\t\t/**\n\t\t * @type String|function\n\t\t */\n\t\tacceptHeaderUpdate: \"text/plain,*/*;q=0.9\",\n\n\t\t/**\n\t\t * Named graphs to query.\n\t\t */\n\t\tnamedGraphs: [],\n\t\t/**\n\t\t * Default graphs to query.\n\t\t */\n\t\tdefaultGraphs: [],\n\n\t\t/**\n\t\t * Additional request arguments. Add them in the form: {name: \"name\", value: \"value\"}\n\t\t */\n\t\targs: [],\n\n\t\t/**\n\t\t * Additional request headers\n\t\t */\n\t\theaders: {},\n\n\t\tgetQueryForAjax: null,\n\t\t/**\n\t\t * Set of ajax callbacks\n\t\t */\n\t\tcallbacks: {\n\t\t\tbeforeSend: null,\n\t\t\tcomplete: null,\n\t\t\terror: null,\n\t\t\tsuccess: null\n\t\t},\n\t\thandlers: {} //keep here for backwards compatability\n\t},\n});\n\n},{\"./main.js\":31,\"jquery\":16}],30:[function(require,module,exports){\n'use strict';\nmodule.exports = {\n\tquery: '\t',\n\tqueryInvalid: 'image/svg+xml',\n\tdownload: '\t',\n\tshare: '',\n\twarning: '',\n\tfullscreen: 'image/svg+xml',\n\tsmallscreen: 'image/svg+xml',\n};\n\n},{}],31:[function(require,module,exports){\n'use strict';\n//make sure any console statements\nwindow.console = window.console || {\n\t\"log\": function() {}\n};\n\n/**\n * Load libraries\n */\nvar $ = require(\"jquery\"),\n\tCodeMirror = require(\"codemirror\"),\n\tutils = require('./utils.js'),\n\tyutils = require('yasgui-utils'),\n\timgs = require('./imgs.js');\n\nrequire(\"../lib/deparam.js\");\nrequire('codemirror/addon/fold/foldcode.js');\nrequire('codemirror/addon/fold/foldgutter.js');\nrequire('codemirror/addon/fold/xml-fold.js');\nrequire('codemirror/addon/fold/brace-fold.js');\nrequire('./prefixFold.js');\nrequire('codemirror/addon/hint/show-hint.js');\nrequire('codemirror/addon/search/searchcursor.js');\nrequire('codemirror/addon/edit/matchbrackets.js');\nrequire('codemirror/addon/runmode/runmode.js');\nrequire('codemirror/addon/display/fullscreen.js');\nrequire('../lib/grammar/tokenizer.js');\n\n\n\n/**\n * Main YASQE constructor. Pass a DOM element as argument to append the editor to, and (optionally) pass along config settings (see the YASQE.defaults object below, as well as the regular CodeMirror documentation, for more information on configurability)\n *\n * @constructor\n * @param {DOM-Element} parent element to append editor to.\n * @param {object} settings\n * @class YASQE\n * @return {doc} YASQE document\n */\nvar root = module.exports = function(parent, config) {\n\tvar rootEl = $(\"
\", {\n\t\tclass: 'yasqe'\n\t}).appendTo($(parent));\n\tconfig = extendConfig(config);\n\tvar yasqe = extendCmInstance(CodeMirror(rootEl[0], config));\n\tpostProcessCmElement(yasqe);\n\treturn yasqe;\n};\n\n/**\n * Extend config object, which we will pass on to the CM constructor later on.\n * Need this, to make sure our own 'onBlur' etc events do not get overwritten by\n * people who add their own onblur events to the config Additionally, need this\n * to include the CM defaults ourselves. CodeMirror has a method for including\n * defaults, but we can't rely on that one: it assumes flat config object, where\n * we have nested objects (e.g. the persistency option)\n *\n * @private\n */\nvar extendConfig = function(config) {\n\tvar extendedConfig = $.extend(true, {}, root.defaults, config);\n\n\t// I know, codemirror deals with default options as well.\n\t//However, it does not do this recursively (i.e. the persistency option)\n\n\n\treturn extendedConfig;\n};\n/**\n * Add extra functions to the CM document (i.e. the codemirror instantiated\n * object)\n *\n * @private\n */\nvar extendCmInstance = function(yasqe) {\n\t//instantiate autocompleters\n\tyasqe.autocompleters = require('./autocompleters/autocompleterBase.js')(root, yasqe);\n\tif (yasqe.options.autocompleters) {\n\t\tyasqe.options.autocompleters.forEach(function(name) {\n\t\t\tif (root.Autocompleters[name]) yasqe.autocompleters.init(name, root.Autocompleters[name]);\n\t\t})\n\t}\n\tyasqe.lastQueryDuration = null;\n\tyasqe.getCompleteToken = function(token, cur) {\n\t\treturn require('./tokenUtils.js').getCompleteToken(yasqe, token, cur);\n\t};\n\tyasqe.getPreviousNonWsToken = function(line, token) {\n\t\treturn require('./tokenUtils.js').getPreviousNonWsToken(yasqe, line, token);\n\t};\n\tyasqe.getNextNonWsToken = function(lineNumber, charNumber) {\n\t\treturn require('./tokenUtils.js').getNextNonWsToken(yasqe, lineNumber, charNumber);\n\t};\n\tyasqe.collapsePrefixes = function(collapse) {\n\t\tyasqe.foldCode(require('./prefixFold.js').findFirstPrefixLine(yasqe), YASQE.fold.prefix, (collapse ? \"fold\" : \"unfold\"));\n\t};\n\tvar backdrop = null;\n\tvar animateSpeed = null;\n\tyasqe.setBackdrop = function(show) {\n\n\n\t\tif (yasqe.options.backdrop || yasqe.options.backdrop === 0 || yasqe.options.backdrop === '0') {\n\t\t\tif (animateSpeed === null) {\n\t\t\t\tanimateSpeed = +yasqe.options.backdrop;\n\t\t\t\tif (animateSpeed === 1) {\n\t\t\t\t\t//ah, yasqe.options.backdrop was 'true'. Set this to default animate speed 400\n\t\t\t\t\tanimateSpeed = 400;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tif (!backdrop) {\n\t\t\t\tbackdrop = $('
', {\n\t\t\t\t\t\tclass: 'backdrop'\n\t\t\t\t\t})\n\t\t\t\t\t.click(function() {\n\t\t\t\t\t\t$(this).hide();\n\t\t\t\t\t})\n\t\t\t\t\t.insertAfter($(yasqe.getWrapperElement()));\n\t\t\t}\n\t\t\tif (show) {\n\t\t\t\tbackdrop.show(animateSpeed);\n\t\t\t} else {\n\t\t\t\tbackdrop.hide(animateSpeed);\n\t\t\t}\n\t\t}\n\t};\n\t/**\n\t * Execute query. Pass a callback function, or a configuration object (see\n\t * default settings below for possible values) I.e., you can change the\n\t * query configuration by either changing the default settings, changing the\n\t * settings of this document, or by passing query settings to this function\n\t *\n\t * @method doc.query\n\t * @param function|object\n\t */\n\tyasqe.query = function(callbackOrConfig) {\n\t\troot.executeQuery(yasqe, callbackOrConfig);\n\t};\n\n\tyasqe.getUrlArguments = function(config) {\n\t\treturn root.getUrlArguments(yasqe, config);\n\t};\n\n\t/**\n\t * Fetch defined prefixes from query string\n\t *\n\t * @method doc.getPrefixesFromQuery\n\t * @return object\n\t */\n\tyasqe.getPrefixesFromQuery = function() {\n\t\treturn require('./prefixUtils.js').getPrefixesFromQuery(yasqe);\n\t};\n\n\tyasqe.addPrefixes = function(prefixes) {\n\t\treturn require('./prefixUtils.js').addPrefixes(yasqe, prefixes);\n\t};\n\tyasqe.removePrefixes = function(prefixes) {\n\t\treturn require('./prefixUtils.js').removePrefixes(yasqe, prefixes);\n\t};\n\n\tyasqe.getValueWithoutComments = function() {\n\t\tvar cleanedQuery = \"\";\n\t\troot.runMode(yasqe.getValue(), \"sparql11\", function(stringVal, className) {\n\t\t\tif (className != \"comment\") {\n\t\t\t\tcleanedQuery += stringVal;\n\t\t\t}\n\t\t});\n\t\treturn cleanedQuery;\n\t};\n\t/**\n\t * Fetch the query type (e.g., SELECT||DESCRIBE||INSERT||DELETE||ASK||CONSTRUCT)\n\t *\n\t * @method doc.getQueryType\n\t * @return string\n\t *\n\t */\n\tyasqe.getQueryType = function() {\n\t\treturn yasqe.queryType;\n\t};\n\t/**\n\t * Fetch the query mode: 'query' or 'update'\n\t *\n\t * @method doc.getQueryMode\n\t * @return string\n\t *\n\t */\n\tyasqe.getQueryMode = function() {\n\t\tvar type = yasqe.getQueryType();\n\t\tif (type == \"INSERT\" || type == \"DELETE\" || type == \"LOAD\" || type == \"CLEAR\" || type == \"CREATE\" || type == \"DROP\" || type == \"COPY\" || type == \"MOVE\" || type == \"ADD\") {\n\t\t\treturn \"update\";\n\t\t} else {\n\t\t\treturn \"query\";\n\t\t}\n\n\t};\n\n\tyasqe.setCheckSyntaxErrors = function(isEnabled) {\n\t\tyasqe.options.syntaxErrorCheck = isEnabled;\n\t\tcheckSyntax(yasqe);\n\t};\n\n\tyasqe.enableCompleter = function(name) {\n\t\taddCompleterToSettings(yasqe.options, name);\n\t\tif (root.Autocompleters[name]) yasqe.autocompleters.init(name, root.Autocompleters[name]);\n\t};\n\tyasqe.disableCompleter = function(name) {\n\t\tremoveCompleterFromSettings(yasqe.options, name);\n\t};\n\treturn yasqe;\n};\n\nvar addCompleterToSettings = function(settings, name) {\n\tif (!settings.autocompleters) settings.autocompleters = [];\n\tsettings.autocompleters.push(name);\n};\nvar removeCompleterFromSettings = function(settings, name) {\n\tif (typeof settings.autocompleters == \"object\") {\n\t\tvar index = $.inArray(name, settings.autocompleters);\n\t\tif (index >= 0) {\n\t\t\tsettings.autocompleters.splice(index, 1);\n\t\t\tremoveCompleterFromSettings(settings, name); //just in case. suppose 1 completer is listed twice\n\t\t}\n\t}\n};\nvar postProcessCmElement = function(yasqe) {\n\t/**\n\t * Set doc value\n\t */\n\tvar storageId = utils.getPersistencyId(yasqe, yasqe.options.persistent);\n\tif (storageId) {\n\t\tvar valueFromStorage = yutils.storage.get(storageId);\n\t\tif (valueFromStorage)\n\t\t\tyasqe.setValue(valueFromStorage);\n\t}\n\n\troot.drawButtons(yasqe);\n\n\t/**\n\t * Add event handlers\n\t */\n\tyasqe.on('blur', function(yasqe, eventInfo) {\n\t\troot.storeQuery(yasqe);\n\t});\n\tyasqe.on('change', function(yasqe, eventInfo) {\n\t\tcheckSyntax(yasqe);\n\t\troot.updateQueryButton(yasqe);\n\t\troot.positionButtons(yasqe);\n\t});\n\tyasqe.on('changes', function() {\n\t\t//e.g. on paste\n\t\tcheckSyntax(yasqe);\n\t\troot.updateQueryButton(yasqe);\n\t\troot.positionButtons(yasqe);\n\t});\n\n\tyasqe.on('cursorActivity', function(yasqe, eventInfo) {\n\t\tupdateButtonsTransparency(yasqe);\n\t});\n\tyasqe.prevQueryValid = false;\n\tcheckSyntax(yasqe); // on first load, check as well (our stored or default query might be incorrect)\n\troot.positionButtons(yasqe);\n\n\t$(yasqe.getWrapperElement()).on('mouseenter', '.cm-atom', function() {\n\t\tvar matchText = $(this).text();\n\t\t$(yasqe.getWrapperElement()).find('.cm-atom').filter(function() {\n\t\t\treturn $(this).text() === matchText;\n\t\t}).addClass('matchingVar');\n\t}).on('mouseleave', '.cm-atom', function() {\n\t\t$(yasqe.getWrapperElement()).find('.matchingVar').removeClass('matchingVar');\n\t});\n\t/**\n\t * check url args and modify yasqe settings if needed\n\t */\n\tif (yasqe.options.consumeShareLink) {\n\t\tyasqe.options.consumeShareLink(yasqe, getUrlParams());\n\t\t//and: add a hash listener!\n\t\twindow.addEventListener(\"hashchange\", function() {\n\t\t\tyasqe.options.consumeShareLink(yasqe, getUrlParams());\n\t\t});\n\t}\n\tif (yasqe.options.collapsePrefixesOnLoad) yasqe.collapsePrefixes(true);\n};\n\n/**\n * get url params. first try fetching using hash. If it fails, try the regular query parameters (for backwards compatability)\n */\nvar getUrlParams = function() {\n\t//first try hash\n\tvar urlParams = null;\n\tif (window.location.hash.length > 1) {\n\t\t//firefox does some decoding if we're using window.location.hash (e.g. the + sign in contentType settings)\n\t\t//Don't want this. So simply get the hash string ourselves\n\t\turlParams = $.deparam(location.href.split(\"#\")[1])\n\t}\n\tif ((!urlParams || !('query' in urlParams)) && window.location.search.length > 1) {\n\t\t//ok, then just try regular url params\n\t\turlParams = $.deparam(window.location.search.substring(1));\n\t}\n\treturn urlParams;\n};\n\n\n\n/**\n * Update transparency of buttons. Increase transparency when cursor is below buttons\n */\n\nvar updateButtonsTransparency = function(yasqe) {\n\tyasqe.cursor = $(\".CodeMirror-cursor\");\n\tif (yasqe.buttons && yasqe.buttons.is(\":visible\") && yasqe.cursor.length > 0) {\n\t\tif (utils.elementsOverlap(yasqe.cursor, yasqe.buttons)) {\n\t\t\tyasqe.buttons.find(\"svg\").attr(\"opacity\", \"0.2\");\n\t\t} else {\n\t\t\tyasqe.buttons.find(\"svg\").attr(\"opacity\", \"1.0\");\n\t\t}\n\t}\n};\n\n\n\n\n\n\n\n\n\nvar clearError = null;\nvar checkSyntax = function(yasqe, deepcheck) {\n\n\tyasqe.queryValid = true;\n\n\tyasqe.clearGutter(\"gutterErrorBar\");\n\n\tvar state = null;\n\tfor (var l = 0; l < yasqe.lineCount(); ++l) {\n\t\tvar precise = false;\n\t\tif (!yasqe.prevQueryValid) {\n\t\t\t// we don't want cached information in this case, otherwise the\n\t\t\t// previous error sign might still show up,\n\t\t\t// even though the syntax error might be gone already\n\t\t\tprecise = true;\n\t\t}\n\n\t\tvar token = yasqe.getTokenAt({\n\t\t\tline: l,\n\t\t\tch: yasqe.getLine(l).length\n\t\t}, precise);\n\t\tvar state = token.state;\n\t\tyasqe.queryType = state.queryType;\n\t\tif (state.OK == false) {\n\t\t\tif (!yasqe.options.syntaxErrorCheck) {\n\t\t\t\t//the library we use already marks everything as being an error. Overwrite this class attribute.\n\t\t\t\t$(yasqe.getWrapperElement).find(\".sp-error\").css(\"color\", \"black\");\n\t\t\t\t//we don't want to gutter error, so return\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar warningEl = yutils.svg.getElement(imgs.warning);\n\t\t\tif (state.possibleCurrent && state.possibleCurrent.length > 0) {\n\t\t\t\t//\t\t\t\twarningEl.style.zIndex = \"99999999\";\n\t\t\t\trequire('./tooltip')(yasqe, warningEl, function() {\n\t\t\t\t\tvar expectedEncoded = [];\n\t\t\t\t\tstate.possibleCurrent.forEach(function(expected) {\n\t\t\t\t\t\texpectedEncoded.push(\"\" + $(\"
\").text(expected).html() + \"\");\n\t\t\t\t\t});\n\t\t\t\t\treturn \"This line is invalid. Expected: \" + expectedEncoded.join(\", \");\n\t\t\t\t});\n\t\t\t}\n\t\t\twarningEl.style.marginTop = \"2px\";\n\t\t\twarningEl.style.marginLeft = \"2px\";\n\t\t\twarningEl.className = 'parseErrorIcon';\n\t\t\tyasqe.setGutterMarker(l, \"gutterErrorBar\", warningEl);\n\n\t\t\tyasqe.queryValid = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tyasqe.prevQueryValid = yasqe.queryValid;\n\tif (deepcheck) {\n\t\tif (state != null && state.stack != undefined) {\n\t\t\tvar stack = state.stack,\n\t\t\t\tlen = state.stack.length;\n\t\t\t// Because incremental parser doesn't receive end-of-input\n\t\t\t// it can't clear stack, so we have to check that whatever\n\t\t\t// is left on the stack is nillable\n\t\t\tif (len > 1)\n\t\t\t\tyasqe.queryValid = false;\n\t\t\telse if (len == 1) {\n\t\t\t\tif (stack[0] != \"solutionModifier\" && stack[0] != \"?limitOffsetClauses\" && stack[0] != \"?offsetClause\")\n\t\t\t\t\tyasqe.queryValid = false;\n\t\t\t}\n\t\t}\n\t}\n};\n/**\n * Static Utils\n */\n// first take all CodeMirror references and store them in the YASQE object\n$.extend(root, CodeMirror);\n\n\n//add registrar for autocompleters\nroot.Autocompleters = {};\nroot.registerAutocompleter = function(name, constructor) {\n\troot.Autocompleters[name] = constructor;\n\taddCompleterToSettings(root.defaults, name);\n}\n\nroot.autoComplete = function(yasqe) {\n\t//this function gets called when pressing the keyboard shortcut. I.e., autoShow = false\n\tyasqe.autocompleters.autoComplete(false);\n};\n//include the autocompleters we provide out-of-the-box\nroot.registerAutocompleter(\"prefixes\", require(\"./autocompleters/prefixes.js\"));\nroot.registerAutocompleter(\"properties\", require(\"./autocompleters/properties.js\"));\nroot.registerAutocompleter(\"classes\", require(\"./autocompleters/classes.js\"));\nroot.registerAutocompleter(\"variables\", require(\"./autocompleters/variables.js\"));\n\n\nroot.positionButtons = function(yasqe) {\n\tvar scrollBar = $(yasqe.getWrapperElement()).find(\".CodeMirror-vscrollbar\");\n\tvar offset = 0;\n\tif (scrollBar.is(\":visible\")) {\n\t\toffset = scrollBar.outerWidth();\n\t}\n\tif (yasqe.buttons.is(\":visible\")) yasqe.buttons.css(\"right\", offset + 4);\n};\n\n/**\n * Create a share link\n *\n * @method YASQE.createShareLink\n * @param {doc} YASQE document\n * @default {query: doc.getValue()}\n * @return object\n */\nroot.createShareLink = function(yasqe) {\n\t//extend existing link, so first fetch current arguments\n\tvar urlParams = {};\n\tif (window.location.hash.length > 1) urlParams = $.deparam(window.location.hash.substring(1));\n\turlParams['query'] = yasqe.getValue();\n\treturn urlParams;\n};\n\n/**\n * Consume the share link, by parsing the document URL for possible yasqe arguments, and setting the appropriate values in the YASQE doc\n *\n * @method YASQE.consumeShareLink\n * @param {doc} YASQE document\n */\nroot.consumeShareLink = function(yasqe, urlParams) {\n\tif (urlParams && urlParams.query) {\n\t\tyasqe.setValue(urlParams.query);\n\t}\n};\nroot.drawButtons = function(yasqe) {\n\tyasqe.buttons = $(\"
\").appendTo($(yasqe.getWrapperElement()));\n\n\t/**\n\t * draw share link button\n\t */\n\tif (yasqe.options.createShareLink) {\n\n\t\tvar svgShare = $(yutils.svg.getElement(imgs.share));\n\t\tsvgShare.click(function(event) {\n\t\t\t\tevent.stopPropagation();\n\t\t\t\tvar popup = $(\"
\").appendTo(yasqe.buttons);\n\t\t\t\t$('html').click(function() {\n\t\t\t\t\tif (popup) popup.remove();\n\t\t\t\t});\n\n\t\t\t\tpopup.click(function(event) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t});\n\t\t\t\tvar $input = $(\"\").val(location.protocol + '//' + location.host + location.pathname + location.search + \"#\" + $.param(yasqe.options.createShareLink(yasqe)));\n\n\t\t\t\t$input.focus(function() {\n\t\t\t\t\tvar $this = $(this);\n\t\t\t\t\t$this.select();\n\n\t\t\t\t\t// Work around Chrome's little problem\n\t\t\t\t\t$this.mouseup(function() {\n\t\t\t\t\t\t// Prevent further mouseup intervention\n\t\t\t\t\t\t$this.unbind(\"mouseup\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tpopup.empty().append($('
', {class:'inputWrapper'}).append($input));\n\t\t\t\tif (yasqe.options.createShortLink) {\n\t\t\t\t\tpopup.addClass('enableShort');\n\t\t\t\t\t$('')\n\t\t\t\t\t\t.addClass('yasqe_btn yasqe_btn-sm yasqe_btn-primary')\n\t\t\t\t\t\t.click(function() {\n\t\t\t\t\t\t\t$(this).attr('disabled', 'disabled');\n\t\t\t\t\t\t\tyasqe.options.createShortLink($input.val(), function(errString, shortLink) {\n\t\t\t\t\t\t\t\tif (errString) {\n\t\t\t\t\t\t\t\t\t$input.remove();\n\t\t\t\t\t\t\t\t\tpopup.find('.inputWrapper').append($('', {class:\"shortlinkErr\"}).text(errString));\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$input.val(shortLink).focus();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}).appendTo(popup);\n\t\t\t\t}\n\t\t\t\tvar positions = svgShare.position();\n\t\t\t\tpopup.css(\"top\", (positions.top + svgShare.outerHeight() + parseInt(popup.css('padding-top')) ) + \"px\").css(\"left\", ((positions.left + svgShare.outerWidth()) - popup.outerWidth()) + \"px\");\n\t\t\t\t$input.focus();\n\t\t\t})\n\t\t\t.addClass(\"yasqe_share\")\n\t\t\t.attr(\"title\", \"Share your query\")\n\t\t\t.appendTo(yasqe.buttons);\n\n\t}\n\n\n\t/**\n\t * draw fullscreen button\n\t */\n\n\tvar toggleFullscreen = $('
', {\n\t\t\tclass: 'fullscreenToggleBtns'\n\t\t})\n\t\t.append($(yutils.svg.getElement(imgs.fullscreen))\n\t\t\t.addClass(\"yasqe_fullscreenBtn\")\n\t\t\t.attr(\"title\", \"Set editor full screen\")\n\t\t\t.click(function() {\n\t\t\t\tyasqe.setOption(\"fullScreen\", true);\n\t\t\t}))\n\t\t.append($(yutils.svg.getElement(imgs.smallscreen))\n\t\t\t.addClass(\"yasqe_smallscreenBtn\")\n\t\t\t.attr(\"title\", \"Set editor to normale size\")\n\t\t\t.click(function() {\n\t\t\t\tyasqe.setOption(\"fullScreen\", false);\n\t\t\t}))\n\tyasqe.buttons.append(toggleFullscreen);\n\n\n\tif (yasqe.options.sparql.showQueryButton) {\n\t\t$(\"
\", {\n\t\t\t\tclass: 'yasqe_queryButton'\n\t\t\t})\n\t\t\t.click(function() {\n\t\t\t\tif ($(this).hasClass(\"query_busy\")) {\n\t\t\t\t\tif (yasqe.xhr) yasqe.xhr.abort();\n\t\t\t\t\troot.updateQueryButton(yasqe);\n\t\t\t\t} else {\n\t\t\t\t\tyasqe.query();\n\t\t\t\t}\n\t\t\t})\n\t\t\t.appendTo(yasqe.buttons);\n\t\troot.updateQueryButton(yasqe);\n\t}\n\n};\n\n\nvar queryButtonIds = {\n\t\"busy\": \"loader\",\n\t\"valid\": \"query\",\n\t\"error\": \"queryInvalid\"\n};\n\n/**\n * Update the query button depending on current query status. If no query status is passed via the parameter, it auto-detects the current query status\n *\n * @param {doc} YASQE document\n * @param status {string|null, \"busy\"|\"valid\"|\"error\"}\n */\nroot.updateQueryButton = function(yasqe, status) {\n\tvar queryButton = $(yasqe.getWrapperElement()).find(\".yasqe_queryButton\");\n\tif (queryButton.length == 0) return; //no query button drawn\n\n\t//detect status\n\tif (!status) {\n\t\tstatus = \"valid\";\n\t\tif (yasqe.queryValid === false) status = \"error\";\n\t}\n\n\tif (status != yasqe.queryStatus) {\n\t\tqueryButton\n\t\t\t.empty()\n\t\t\t.removeClass(function(index, classNames) {\n\t\t\t\treturn classNames.split(\" \").filter(function(c) {\n\t\t\t\t\t//remove classname from previous status\n\t\t\t\t\treturn c.indexOf(\"query_\") == 0;\n\t\t\t\t}).join(\" \");\n\t\t\t});\n\n\t\tif (status == \"busy\") {\n\t\t\tqueryButton.append($('
', {\n\t\t\t\tclass: 'loader',\n\t\t\t}));\n\t\t\tyasqe.queryStatus = status;\n\t\t} else if (status == \"valid\" || status == \"error\") {\n\t\t\tqueryButton.addClass(\"query_\" + status);\n\t\t\tyutils.svg.draw(queryButton, imgs[queryButtonIds[status]]);\n\t\t\tyasqe.queryStatus = status;\n\t\t}\n\t}\n};\n/**\n * Initialize YASQE from an existing text area (see http://codemirror.net/doc/manual.html#fromTextArea for more info)\n *\n * @method YASQE.fromTextArea\n * @param textArea {DOM element}\n * @param config {object}\n * @returns {doc} YASQE document\n */\nroot.fromTextArea = function(textAreaEl, config) {\n\tconfig = extendConfig(config);\n\t//add yasqe div as parent (needed for styles to be manageable and scoped).\n\t//In this case, I -also- put it as parent el of the text area. This is wrapped in a div now\n\tvar rootEl = $(\"
\", {\n\t\tclass: 'yasqe'\n\t}).insertBefore($(textAreaEl)).append($(textAreaEl));\n\tvar yasqe = extendCmInstance(CodeMirror.fromTextArea(textAreaEl, config));\n\tpostProcessCmElement(yasqe);\n\treturn yasqe;\n};\n\n\nroot.storeQuery = function(yasqe) {\n\tvar storageId = utils.getPersistencyId(yasqe, yasqe.options.persistent);\n\tif (storageId) {\n\t\tyutils.storage.set(storageId, yasqe.getValue(), \"month\");\n\t}\n};\nroot.commentLines = function(yasqe) {\n\tvar startLine = yasqe.getCursor(true).line;\n\tvar endLine = yasqe.getCursor(false).line;\n\tvar min = Math.min(startLine, endLine);\n\tvar max = Math.max(startLine, endLine);\n\n\t// if all lines start with #, remove this char. Otherwise add this char\n\tvar linesAreCommented = true;\n\tfor (var i = min; i <= max; i++) {\n\t\tvar line = yasqe.getLine(i);\n\t\tif (line.length == 0 || line.substring(0, 1) != \"#\") {\n\t\t\tlinesAreCommented = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tfor (var i = min; i <= max; i++) {\n\t\tif (linesAreCommented) {\n\t\t\t// lines are commented, so remove comments\n\t\t\tyasqe.replaceRange(\"\", {\n\t\t\t\tline: i,\n\t\t\t\tch: 0\n\t\t\t}, {\n\t\t\t\tline: i,\n\t\t\t\tch: 1\n\t\t\t});\n\t\t} else {\n\t\t\t// Not all lines are commented, so add comments\n\t\t\tyasqe.replaceRange(\"#\", {\n\t\t\t\tline: i,\n\t\t\t\tch: 0\n\t\t\t});\n\t\t}\n\n\t}\n};\n\nroot.copyLineUp = function(yasqe) {\n\tvar cursor = yasqe.getCursor();\n\tvar lineCount = yasqe.lineCount();\n\t// First create new empty line at end of text\n\tyasqe.replaceRange(\"\\n\", {\n\t\tline: lineCount - 1,\n\t\tch: yasqe.getLine(lineCount - 1).length\n\t});\n\t// Copy all lines to their next line\n\tfor (var i = lineCount; i > cursor.line; i--) {\n\t\tvar line = yasqe.getLine(i - 1);\n\t\tyasqe.replaceRange(line, {\n\t\t\tline: i,\n\t\t\tch: 0\n\t\t}, {\n\t\t\tline: i,\n\t\t\tch: yasqe.getLine(i).length\n\t\t});\n\t}\n};\nroot.copyLineDown = function(yasqe) {\n\troot.copyLineUp(yasqe);\n\t// Make sure cursor goes one down (we are copying downwards)\n\tvar cursor = yasqe.getCursor();\n\tcursor.line++;\n\tyasqe.setCursor(cursor);\n};\nroot.doAutoFormat = function(yasqe) {\n\tif (yasqe.somethingSelected()) {\n\t\tvar to = {\n\t\t\tline: yasqe.getCursor(false).line,\n\t\t\tch: yasqe.getSelection().length\n\t\t};\n\t\tautoFormatRange(yasqe, yasqe.getCursor(true), to);\n\t} else {\n\t\tvar totalLines = yasqe.lineCount();\n\t\tvar totalChars = yasqe.getTextArea().value.length;\n\t\tautoFormatRange(yasqe, {\n\t\t\tline: 0,\n\t\t\tch: 0\n\t\t}, {\n\t\t\tline: totalLines,\n\t\t\tch: totalChars\n\t\t});\n\t}\n\n};\n\n\nvar autoFormatRange = function(yasqe, from, to) {\n\tvar absStart = yasqe.indexFromPos(from);\n\tvar absEnd = yasqe.indexFromPos(to);\n\t// Insert additional line breaks where necessary according to the\n\t// mode's syntax\n\tvar res = autoFormatLineBreaks(yasqe.getValue(), absStart, absEnd);\n\n\t// Replace and auto-indent the range\n\tyasqe.operation(function() {\n\t\tyasqe.replaceRange(res, from, to);\n\t\tvar startLine = yasqe.posFromIndex(absStart).line;\n\t\tvar endLine = yasqe.posFromIndex(absStart + res.length).line;\n\t\tfor (var i = startLine; i <= endLine; i++) {\n\t\t\tyasqe.indentLine(i, \"smart\");\n\t\t}\n\t});\n};\n\nvar autoFormatLineBreaks = function(text, start, end) {\n\ttext = text.substring(start, end);\n\tvar breakAfterArray = [\n\t\t[\"keyword\", \"ws\", \"prefixed\", \"ws\", \"uri\"], // i.e. prefix declaration\n\t\t[\"keyword\", \"ws\", \"uri\"] // i.e. base\n\t];\n\tvar breakAfterCharacters = [\"{\", \".\", \";\"];\n\tvar breakBeforeCharacters = [\"}\"];\n\tvar getBreakType = function(stringVal, type) {\n\t\tfor (var i = 0; i < breakAfterArray.length; i++) {\n\t\t\tif (stackTrace.valueOf().toString() == breakAfterArray[i].valueOf()\n\t\t\t\t.toString()) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tfor (var i = 0; i < breakAfterCharacters.length; i++) {\n\t\t\tif (stringVal == breakAfterCharacters[i]) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tfor (var i = 0; i < breakBeforeCharacters.length; i++) {\n\t\t\t// don't want to issue 'breakbefore' AND 'breakafter', so check\n\t\t\t// current line\n\t\t\tif ($.trim(currentLine) != '' && stringVal == breakBeforeCharacters[i]) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t};\n\tvar formattedQuery = \"\";\n\tvar currentLine = \"\";\n\tvar stackTrace = [];\n\tCodeMirror.runMode(text, \"sparql11\", function(stringVal, type) {\n\t\tstackTrace.push(type);\n\t\tvar breakType = getBreakType(stringVal, type);\n\t\tif (breakType != 0) {\n\t\t\tif (breakType == 1) {\n\t\t\t\tformattedQuery += stringVal + \"\\n\";\n\t\t\t\tcurrentLine = \"\";\n\t\t\t} else { // (-1)\n\t\t\t\tformattedQuery += \"\\n\" + stringVal;\n\t\t\t\tcurrentLine = stringVal;\n\t\t\t}\n\t\t\tstackTrace = [];\n\t\t} else {\n\t\t\tcurrentLine += stringVal;\n\t\t\tformattedQuery += stringVal;\n\t\t}\n\t\tif (stackTrace.length == 1 && stackTrace[0] == \"sp-ws\")\n\t\t\tstackTrace = [];\n\t});\n\treturn $.trim(formattedQuery.replace(/\\n\\s*\\n/g, '\\n'));\n};\n\nrequire('./sparql.js'),\n\trequire('./defaults.js');\nroot.$ = $;\nroot.version = {\n\t\"CodeMirror\": CodeMirror.version,\n\t\"YASQE\": require(\"../package.json\").version,\n\t\"jquery\": $.fn.jquery,\n\t\"yasgui-utils\": yutils.version\n};\n\n},{\"../lib/deparam.js\":2,\"../lib/grammar/tokenizer.js\":4,\"../package.json\":22,\"./autocompleters/autocompleterBase.js\":23,\"./autocompleters/classes.js\":24,\"./autocompleters/prefixes.js\":25,\"./autocompleters/properties.js\":26,\"./autocompleters/variables.js\":28,\"./defaults.js\":29,\"./imgs.js\":30,\"./prefixFold.js\":32,\"./prefixUtils.js\":33,\"./sparql.js\":34,\"./tokenUtils.js\":35,\"./tooltip\":36,\"./utils.js\":37,\"codemirror\":15,\"codemirror/addon/display/fullscreen.js\":6,\"codemirror/addon/edit/matchbrackets.js\":7,\"codemirror/addon/fold/brace-fold.js\":8,\"codemirror/addon/fold/foldcode.js\":9,\"codemirror/addon/fold/foldgutter.js\":10,\"codemirror/addon/fold/xml-fold.js\":11,\"codemirror/addon/hint/show-hint.js\":12,\"codemirror/addon/runmode/runmode.js\":13,\"codemirror/addon/search/searchcursor.js\":14,\"jquery\":16,\"yasgui-utils\":19}],32:[function(require,module,exports){\nvar CodeMirror = require('codemirror'),\n\ttokenUtils = require('./tokenUtils.js');\n\n\"use strict\";\nvar lookFor = \"PREFIX\";\nmodule.exports = {\n\tfindFirstPrefixLine: function(cm) {\n\t\tvar lastLine = cm.lastLine();\n\t\tfor (var i = 0; i <= lastLine; ++i) {\n\t\t\tif (findFirstPrefix(cm, i) >= 0) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction findFirstPrefix(cm, line, ch, lineText) {\n\tif (!ch) ch = 0;\n\tif (!lineText) lineText = cm.getLine(line);\n\tlineText = lineText.toUpperCase();\n\tfor (var at = ch, pass = 0;;) {\n\t\tvar found = lineText.indexOf(lookFor, at);\n\t\tif (found == -1) {\n\t\t\tif (pass == 1)\n\t\t\t\tbreak;\n\t\t\tpass = 1;\n\t\t\tat = lineText.length;\n\t\t\tcontinue;\n\t\t}\n\t\tif (pass == 1 && found < ch)\n\t\t\tbreak;\n\t\ttokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));\n\t\tif (!/^(comment|string)/.test(tokenType))\n\t\t\treturn found + 1;\n\t\tat = found - 1;\n\t}\n}\n\nCodeMirror.registerHelper(\"fold\", \"prefix\", function(cm, start) {\n\tvar line = start.line,\n\t\tlineText = cm.getLine(line);\n\n\tvar startCh, tokenType;\n\n\tfunction hasPreviousPrefix() {\n\t\tvar hasPreviousPrefix = false;\n\t\tfor (var i = line - 1; i >= 0; i--) {\n\t\t\tif (cm.getLine(i).toUpperCase().indexOf(lookFor) >= 0) {\n\t\t\t\thasPreviousPrefix = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn hasPreviousPrefix;\n\t}\n\n\n\tfunction findOpening(openCh) {\n\t\tfor (var at = start.ch, pass = 0;;) {\n\t\t\tvar found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);\n\t\t\tif (found == -1) {\n\t\t\t\tif (pass == 1)\n\t\t\t\t\tbreak;\n\t\t\t\tpass = 1;\n\t\t\t\tat = lineText.length;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (pass == 1 && found < start.ch)\n\t\t\t\tbreak;\n\t\t\ttokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));\n\t\t\tif (!/^(comment|string)/.test(tokenType))\n\t\t\t\treturn found + 1;\n\t\t\tat = found - 1;\n\t\t}\n\t}\n\tvar getLastPrefixPos = function(line, ch) {\n\t\tvar prefixKeywordToken = cm.getTokenAt(CodeMirror.Pos(line, ch + 1));\n\t\tif (!prefixKeywordToken || prefixKeywordToken.type != \"keyword\") return -1;\n\t\tvar prefixShortname = tokenUtils.getNextNonWsToken(cm, line, prefixKeywordToken.end + 1);\n\t\tif (!prefixShortname || prefixShortname.type != \"string-2\") return -1; //missing prefix keyword shortname\n\t\tvar prefixUri = tokenUtils.getNextNonWsToken(cm, line, prefixShortname.end + 1);\n\t\tif (!prefixUri || prefixUri.type != \"variable-3\") return -1; //missing prefix uri\n\t\treturn prefixUri.end;\n\t}\n\n\t//only use opening prefix declaration\n\tif (hasPreviousPrefix())\n\t\treturn;\n\tvar prefixStart = findFirstPrefix(cm, line, start.ch, lineText);\n\n\tif (prefixStart == null)\n\t\treturn;\n\tvar stopAt = '{'; //if this char is there, we won't have a chance of finding more prefixes\n\tvar stopAtNextLine = false;\n\tvar count = 1,\n\t\tlastLine = cm.lastLine(),\n\t\tend, endCh;\n\tvar prefixEndChar = getLastPrefixPos(line, prefixStart);\n\tvar prefixEndLine = line;\n\n\touter: for (var i = line; i <= lastLine; ++i) {\n\t\tif (stopAtNextLine)\n\t\t\tbreak;\n\t\tvar text = cm.getLine(i),\n\t\t\tpos = i == line ? prefixStart + 1 : 0;\n\n\t\tfor (;;) {\n\t\t\tif (!stopAtNextLine && text.indexOf(stopAt) >= 0)\n\t\t\t\tstopAtNextLine = true;\n\n\t\t\tvar nextPrefixDeclaration = text.toUpperCase()\n\t\t\t\t.indexOf(lookFor, pos);\n\n\t\t\tif (nextPrefixDeclaration >= 0) {\n\t\t\t\tif ((endCh = getLastPrefixPos(i, nextPrefixDeclaration)) > 0) {\n\t\t\t\t\tprefixEndChar = endCh;\n\t\t\t\t\tprefixEndLine = i;\n\t\t\t\t\tpos = prefixEndChar;\n\t\t\t\t}\n\t\t\t\tpos++;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn {\n\t\tfrom: CodeMirror.Pos(line, prefixStart + lookFor.length),\n\t\tto: CodeMirror.Pos(prefixEndLine, prefixEndChar)\n\t};\n});\n},{\"./tokenUtils.js\":35,\"codemirror\":15}],33:[function(require,module,exports){\n'use strict';\n/**\n * Append prefix declaration to list of prefixes in query window.\n * \n * @param yasqe\n * @param prefix\n */\nvar addPrefixes = function(yasqe, prefixes) {\n\tvar existingPrefixes = yasqe.getPrefixesFromQuery();\n\t//for backwards compatability, we stil support prefixes value as string (e.g. 'rdf: '\n\tif (typeof prefixes == \"string\") {\n\t\taddPrefixAsString(yasqe, prefixes);\n\t} else {\n\t\tfor (var pref in prefixes) {\n\t\t\tif (!(pref in existingPrefixes))\n\t\t\t\taddPrefixAsString(yasqe, pref + \": <\" + prefixes[pref] + \">\");\n\t\t}\n\t}\n\tyasqe.collapsePrefixes(false);\n};\n\nvar addPrefixAsString = function(yasqe, prefixString) {\n\tvar lastPrefix = null;\n\tvar lastPrefixLine = 0;\n\tvar numLines = yasqe.lineCount();\n\tfor (var i = 0; i < numLines; i++) {\n\t\tvar firstToken = yasqe.getNextNonWsToken(i);\n\t\tif (firstToken != null && (firstToken.string == \"PREFIX\" || firstToken.string == \"BASE\")) {\n\t\t\tlastPrefix = firstToken;\n\t\t\tlastPrefixLine = i;\n\t\t}\n\t}\n\n\tif (lastPrefix == null) {\n\t\tyasqe.replaceRange(\"PREFIX \" + prefixString + \"\\n\", {\n\t\t\tline: 0,\n\t\t\tch: 0\n\t\t});\n\t} else {\n\t\tvar previousIndent = getIndentFromLine(yasqe, lastPrefixLine);\n\t\tyasqe.replaceRange(\"\\n\" + previousIndent + \"PREFIX \" + prefixString, {\n\t\t\tline: lastPrefixLine\n\t\t});\n\t}\n\tyasqe.collapsePrefixes(false);\n};\nvar removePrefixes = function(yasqe, prefixes) {\n\tvar escapeRegex = function(string) {\n\t\t//taken from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript/3561711#3561711\n\t\treturn string.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\t}\n\tfor (var pref in prefixes) {\n\t\tyasqe.setValue(yasqe.getValue().replace(new RegExp(\"PREFIX\\\\s*\" + pref + \":\\\\s*\" + escapeRegex(\"<\" + prefixes[pref] + \">\") + \"\\\\s*\", \"ig\"), ''));\n\t}\n\tyasqe.collapsePrefixes(false);\n\n};\n\n/**\n * Get defined prefixes from query as array, in format {\"prefix:\" \"uri\"}\n * \n * @param cm\n * @returns {Array}\n */\nvar getPrefixesFromQuery = function(yasqe) {\n\tvar queryPrefixes = {};\n\tvar shouldContinue = true;\n\tvar getPrefixesFromLine = function(lineOffset, colOffset) {\n\t\tif (!shouldContinue) return;\n\t\tif (!colOffset) colOffset = 1;\n\t\tvar token = yasqe.getNextNonWsToken(i, colOffset);\n\t\tif (token) {\n\t\t\tif (token.state.possibleCurrent.indexOf(\"PREFIX\") == -1 && token.state.possibleNext.indexOf(\"PREFIX\") == -1) shouldContinue = false; //we are beyond the place in the query where we can enter prefixes\n\t\t\tif (token.string.toUpperCase() == \"PREFIX\") {\n\t\t\t\tvar prefix = yasqe.getNextNonWsToken(i, token.end + 1);\n\t\t\t\tif (prefix) {\n\t\t\t\t\tvar uri = yasqe.getNextNonWsToken(i, prefix.end + 1);\n\t\t\t\t\tif (uri) {\n\t\t\t\t\t\tvar uriString = uri.string;\n\t\t\t\t\t\tif (uriString.indexOf(\"<\") == 0)\n\t\t\t\t\t\t\turiString = uriString.substring(1);\n\t\t\t\t\t\tif (uriString.slice(-1) == \">\")\n\t\t\t\t\t\t\turiString = uriString\n\t\t\t\t\t\t\t.substring(0, uriString.length - 1);\n\t\t\t\t\t\tqueryPrefixes[prefix.string.slice(0, -1)] = uriString;\n\n\t\t\t\t\t\tgetPrefixesFromLine(lineOffset, uri.end + 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgetPrefixesFromLine(lineOffset, prefix.end + 1);\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\tgetPrefixesFromLine(lineOffset, token.end + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tgetPrefixesFromLine(lineOffset, token.end + 1);\n\t\t\t}\n\t\t}\n\t};\n\n\n\tvar numLines = yasqe.lineCount();\n\tfor (var i = 0; i < numLines; i++) {\n\t\tif (!shouldContinue) break;\n\t\tgetPrefixesFromLine(i);\n\n\t}\n\treturn queryPrefixes;\n};\n\n/**\n * Get the used indentation for a certain line\n * \n * @param yasqe\n * @param line\n * @param charNumber\n * @returns\n */\nvar getIndentFromLine = function(yasqe, line, charNumber) {\n\tif (charNumber == undefined)\n\t\tcharNumber = 1;\n\tvar token = yasqe.getTokenAt({\n\t\tline: line,\n\t\tch: charNumber\n\t});\n\tif (token == null || token == undefined || token.type != \"ws\") {\n\t\treturn \"\";\n\t} else {\n\t\treturn token.string + getIndentFromLine(yasqe, line, token.end + 1);\n\t};\n};\n\nmodule.exports = {\n\taddPrefixes: addPrefixes,\n\tgetPrefixesFromQuery: getPrefixesFromQuery,\n\tremovePrefixes: removePrefixes\n};\n},{}],34:[function(require,module,exports){\n'use strict';\nvar $ = require('jquery'),\n\tYASQE = require('./main.js');\nYASQE.executeQuery = function(yasqe, callbackOrConfig) {\n\tYASQE.signal(yasqe, 'query', yasqe, callbackOrConfig);\n\tvar callback = (typeof callbackOrConfig == \"function\" ? callbackOrConfig : null);\n\tvar config = (typeof callbackOrConfig == \"object\" ? callbackOrConfig : {});\n\n\tif (yasqe.options.sparql)\n\t\tconfig = $.extend({}, yasqe.options.sparql, config);\n\n\t//for backwards compatability, make sure we copy sparql handlers to sparql callbacks\n\tif (config.handlers)\n\t\t$.extend(true, config.callbacks, config.handlers);\n\n\n\tif (!config.endpoint || config.endpoint.length == 0)\n\t\treturn; // nothing to query!\n\n\t/**\n\t * initialize ajax config\n\t */\n\tvar ajaxConfig = {\n\t\turl: (typeof config.endpoint == \"function\" ? config.endpoint(yasqe) : config.endpoint),\n\t\ttype: (typeof config.requestMethod == \"function\" ? config.requestMethod(yasqe) : config.requestMethod),\n\t\theaders: {\n\t\t\tAccept: getAcceptHeader(yasqe, config),\n\t\t}\n\t};\n\tif (config.xhrFields) ajaxConfig.xhrFields = config.xhrFields;\n\t/**\n\t * add complete, beforesend, etc callbacks (if specified)\n\t */\n\tvar handlerDefined = false;\n\tif (config.callbacks) {\n\t\tfor (var handler in config.callbacks) {\n\t\t\tif (config.callbacks[handler]) {\n\t\t\t\thandlerDefined = true;\n\t\t\t\tajaxConfig[handler] = config.callbacks[handler];\n\t\t\t}\n\t\t}\n\t}\n\tajaxConfig.data = yasqe.getUrlArguments(config);\n\tif (!handlerDefined && !callback)\n\t\treturn; // ok, we can query, but have no callbacks. just stop now\n\n\t// if only callback is passed as arg, add that on as 'onComplete' callback\n\tif (callback)\n\t\tajaxConfig.complete = callback;\n\n\n\n\t/**\n\t * merge additional request headers\n\t */\n\tif (config.headers && !$.isEmptyObject(config.headers))\n\t\t$.extend(ajaxConfig.headers, config.headers);\n\n\tYASQE.updateQueryButton(yasqe, \"busy\");\n\tyasqe.setBackdrop(true);\n\tvar queryStart = new Date();\n\tvar updateYasqe = function() {\n\t\tyasqe.lastQueryDuration = new Date() - queryStart;\n\t\tYASQE.updateQueryButton(yasqe);\n\t\tyasqe.setBackdrop(false);\n\t};\n\t//Make sure the query button is updated again on complete\n\tvar completeCallbacks = [\n\t\tfunction(){require('./main.js').signal(yasqe, 'queryFinish', arguments)},\n\t\tupdateYasqe\n\t];\n\n\tif (ajaxConfig.complete) {\n\t\tcompleteCallbacks.push(ajaxConfig.complete);\n\t}\n\tajaxConfig.complete = completeCallbacks;\n\n\tyasqe.xhr = $.ajax(ajaxConfig);\n};\n\n\nYASQE.getUrlArguments = function(yasqe, config) {\n\tvar queryMode = yasqe.getQueryMode();\n\tvar data = [{\n\t\tname: yasqe.getQueryMode(), //either 'update' or 'query'\n\t\tvalue: (config.getQueryForAjax? config.getQueryForAjax(yasqe): yasqe.getValue())\n\t}];\n\n\t/**\n\t * add named graphs to ajax config\n\t */\n\tif (config.namedGraphs && config.namedGraphs.length > 0) {\n\t\tvar argName = (queryMode == \"query\" ? \"named-graph-uri\" : \"using-named-graph-uri \");\n\t\tfor (var i = 0; i < config.namedGraphs.length; i++)\n\t\t\tdata.push({\n\t\t\t\tname: argName,\n\t\t\t\tvalue: config.namedGraphs[i]\n\t\t\t});\n\t}\n\t/**\n\t * add default graphs to ajax config\n\t */\n\tif (config.defaultGraphs && config.defaultGraphs.length > 0) {\n\t\tvar argName = (queryMode == \"query\" ? \"default-graph-uri\" : \"using-graph-uri \");\n\t\tfor (var i = 0; i < config.defaultGraphs.length; i++)\n\t\t\tdata.push({\n\t\t\t\tname: argName,\n\t\t\t\tvalue: config.defaultGraphs[i]\n\t\t\t});\n\t}\n\n\t/**\n\t * add additional request args\n\t */\n\tif (config.args && config.args.length > 0) $.merge(data, config.args);\n\n\treturn data;\n}\nvar getAcceptHeader = function(yasqe, config) {\n\tvar acceptHeader = null;\n\tif (config.acceptHeader && !config.acceptHeaderGraph && !config.acceptHeaderSelect && !config.acceptHeaderUpdate) {\n\t\t//this is the old config. For backwards compatability, keep supporting it\n\t\tif (typeof config.acceptHeader == \"function\") {\n\t\t\tacceptHeader = config.acceptHeader(yasqe);\n\t\t} else {\n\t\t\tacceptHeader = config.acceptHeader;\n\t\t}\n\t} else {\n\t\tif (yasqe.getQueryMode() == \"update\") {\n\t\t\tacceptHeader = (typeof config.acceptHeader == \"function\" ? config.acceptHeaderUpdate(yasqe) : config.acceptHeaderUpdate);\n\t\t} else {\n\t\t\tvar qType = yasqe.getQueryType();\n\t\t\tif (qType == \"DESCRIBE\" || qType == \"CONSTRUCT\") {\n\t\t\t\tacceptHeader = (typeof config.acceptHeaderGraph == \"function\" ? config.acceptHeaderGraph(yasqe) : config.acceptHeaderGraph);\n\t\t\t} else {\n\t\t\t\tacceptHeader = (typeof config.acceptHeaderSelect == \"function\" ? config.acceptHeaderSelect(yasqe) : config.acceptHeaderSelect);\n\t\t\t}\n\t\t}\n\t}\n\treturn acceptHeader;\n};\n\n},{\"./main.js\":31,\"jquery\":16}],35:[function(require,module,exports){\n'use strict';\n/**\n * When typing a query, this query is sometimes syntactically invalid, causing\n * the current tokens to be incorrect This causes problem for autocompletion.\n * http://bla might result in two tokens: http:// and bla. We'll want to combine\n * these\n * \n * @param yasqe {doc}\n * @param token {object}\n * @param cursor {object}\n * @return token {object}\n * @method YASQE.getCompleteToken\n */\nvar getCompleteToken = function(yasqe, token, cur) {\n\tif (!cur) {\n\t\tcur = yasqe.getCursor();\n\t}\n\tif (!token) {\n\t\ttoken = yasqe.getTokenAt(cur);\n\t}\n\tvar prevToken = yasqe.getTokenAt({\n\t\tline: cur.line,\n\t\tch: token.start\n\t});\n\t// not start of line, and not whitespace\n\tif (\n\t\tprevToken.type != null && prevToken.type != \"ws\" && token.type != null && token.type != \"ws\"\n\t) {\n\t\ttoken.start = prevToken.start;\n\t\ttoken.string = prevToken.string + token.string;\n\t\treturn getCompleteToken(yasqe, token, {\n\t\t\tline: cur.line,\n\t\t\tch: prevToken.start\n\t\t}); // recursively, might have multiple tokens which it should include\n\t} else if (token.type != null && token.type == \"ws\") {\n\t\t//always keep 1 char of whitespace between tokens. Otherwise, autocompletions might end up next to the previous node, without whitespace between them\n\t\ttoken.start = token.start + 1;\n\t\ttoken.string = token.string.substring(1);\n\t\treturn token;\n\t} else {\n\t\treturn token;\n\t}\n};\nvar getPreviousNonWsToken = function(yasqe, line, token) {\n\tvar previousToken = yasqe.getTokenAt({\n\t\tline: line,\n\t\tch: token.start\n\t});\n\tif (previousToken != null && previousToken.type == \"ws\") {\n\t\tpreviousToken = getPreviousNonWsToken(yasqe, line, previousToken);\n\t}\n\treturn previousToken;\n}\nvar getNextNonWsToken = function(yasqe, lineNumber, charNumber) {\n\tif (charNumber == undefined)\n\t\tcharNumber = 1;\n\tvar token = yasqe.getTokenAt({\n\t\tline: lineNumber,\n\t\tch: charNumber\n\t});\n\tif (token == null || token == undefined || token.end < charNumber) {\n\t\treturn null;\n\t}\n\tif (token.type == \"ws\") {\n\t\treturn getNextNonWsToken(yasqe, lineNumber, token.end + 1);\n\t}\n\treturn token;\n};\n\nmodule.exports = {\n\tgetPreviousNonWsToken: getPreviousNonWsToken,\n\tgetCompleteToken: getCompleteToken,\n\tgetNextNonWsToken: getNextNonWsToken,\n};\n},{}],36:[function(require,module,exports){\n'use strict';\nvar $ = require('jquery'),\n\tutils = require('./utils.js');\n\n/**\n * Write our own tooltip, to avoid loading another library for just this functionality. For now, we only use tooltip for showing parse errors, so this is quite a tailored solution\n * Requirements: \n * \t\tposition tooltip within codemirror frame as much as possible, to avoid z-index issues with external things on page\n * \t\tuse html as content\n */\nmodule.exports = function(yasqe, parent, html) {\n\tvar parent = $(parent);\n\tvar tooltip;\n\tparent.hover(function() {\n\t\t\tif (typeof html == \"function\") html = html();\n\t\t\ttooltip = $(\"
\").addClass('yasqe_tooltip').html(html).appendTo(parent);\n\t\t\trepositionTooltip();\n\t\t},\n\t\tfunction() {\n\t\t\t$(\".yasqe_tooltip\").remove();\n\t\t});\n\n\n\n\t/**\n\t * only need to take into account top and bottom offset for this usecase\n\t */\n\tvar repositionTooltip = function() {\n\t\tif ($(yasqe.getWrapperElement()).offset().top >= tooltip.offset().top) {\n\t\t\t//shit, move the tooltip down. The tooltip now hovers over the top edge of the yasqe instance\n\t\t\ttooltip.css('bottom', 'auto');\n\t\t\ttooltip.css('top', '26px');\n\t\t}\n\t};\n};\n},{\"./utils.js\":37,\"jquery\":16}],37:[function(require,module,exports){\n'use strict';\nvar $ = require('jquery');\n\nvar keyExists = function(objectToTest, key) {\n\tvar exists = false;\n\ttry {\n\t\tif (objectToTest[key] !== undefined)\n\t\t\texists = true;\n\t} catch (e) {}\n\treturn exists;\n};\n\nvar getPersistencyId = function(yasqe, persistentIdCreator) {\n\tvar persistencyId = null;\n\n\tif (persistentIdCreator) {\n\t\tif (typeof persistentIdCreator == \"string\") {\n\t\t\tpersistencyId = persistentIdCreator;\n\t\t} else {\n\t\t\tpersistencyId = persistentIdCreator(yasqe);\n\t\t}\n\t}\n\treturn persistencyId;\n};\n\nvar elementsOverlap = (function() {\n\tfunction getPositions(elem) {\n\t\tvar pos, width, height;\n\t\tpos = $(elem).offset();\n\t\twidth = $(elem).width();\n\t\theight = $(elem).height();\n\t\treturn [\n\t\t\t[pos.left, pos.left + width],\n\t\t\t[pos.top, pos.top + height]\n\t\t];\n\t}\n\n\tfunction comparePositions(p1, p2) {\n\t\tvar r1, r2;\n\t\tr1 = p1[0] < p2[0] ? p1 : p2;\n\t\tr2 = p1[0] < p2[0] ? p2 : p1;\n\t\treturn r1[1] > r2[0] || r1[0] === r2[0];\n\t}\n\n\treturn function(a, b) {\n\t\tvar pos1 = getPositions(a),\n\t\t\tpos2 = getPositions(b);\n\t\treturn comparePositions(pos1[0], pos2[0]) && comparePositions(pos1[1], pos2[1]);\n\t};\n})();\n\nmodule.exports = {\n\tkeyExists: keyExists,\n\tgetPersistencyId: getPersistencyId,\n\telementsOverlap: elementsOverlap,\n};\n},{\"jquery\":16}]},{},[1])(1)\n});\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyaWZ5L25vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJzcmMvZW50cnkuanMiLCJsaWIvZGVwYXJhbS5qcyIsImxpYi9ncmFtbWFyL190b2tlbml6ZXItdGFibGUuanMiLCJsaWIvZ3JhbW1hci90b2tlbml6ZXIuanMiLCJsaWIvdHJpZS5qcyIsIm5vZGVfbW9kdWxlcy9jb2RlbWlycm9yL2FkZG9uL2Rpc3BsYXkvZnVsbHNjcmVlbi5qcyIsIm5vZGVfbW9kdWxlcy9jb2RlbWlycm9yL2FkZG9uL2VkaXQvbWF0Y2hicmFja2V0cy5qcyIsIm5vZGVfbW9kdWxlcy9jb2RlbWlycm9yL2FkZG9uL2ZvbGQvYnJhY2UtZm9sZC5qcyIsIm5vZGVfbW9kdWxlcy9jb2RlbWlycm9yL2FkZG9uL2ZvbGQvZm9sZGNvZGUuanMiLCJub2RlX21vZHVsZXMvY29kZW1pcnJvci9hZGRvbi9mb2xkL2ZvbGRndXR0ZXIuanMiLCJub2RlX21vZHVsZXMvY29kZW1pcnJvci9hZGRvbi9mb2xkL3htbC1mb2xkLmpzIiwibm9kZV9tb2R1bGVzL2NvZGVtaXJyb3IvYWRkb24vaGludC9zaG93LWhpbnQuanMiLCJub2RlX21vZHVsZXMvY29kZW1pcnJvci9hZGRvbi9ydW5tb2RlL3J1bm1vZGUuanMiLCJub2RlX21vZHVsZXMvY29kZW1pcnJvci9hZGRvbi9zZWFyY2gvc2VhcmNoY3Vyc29yLmpzIiwibm9kZV9tb2R1bGVzL2NvZGVtaXJyb3IvbGliL2NvZGVtaXJyb3IuanMiLCJub2RlX21vZHVsZXMvanF1ZXJ5L2Rpc3QvanF1ZXJ5LmpzIiwibm9kZV9tb2R1bGVzL3lhc2d1aS11dGlscy9ub2RlX21vZHVsZXMvc3RvcmUvc3RvcmUuanMiLCJub2RlX21vZHVsZXMveWFzZ3VpLXV0aWxzL3BhY2thZ2UuanNvbiIsIm5vZGVfbW9kdWxlcy95YXNndWktdXRpbHMvc3JjL21haW4uanMiLCJub2RlX21vZHVsZXMveWFzZ3VpLXV0aWxzL3NyYy9zdG9yYWdlLmpzIiwibm9kZV9tb2R1bGVzL3lhc2d1aS11dGlscy9zcmMvc3ZnLmpzIiwicGFja2FnZS5qc29uIiwic3JjL2F1dG9jb21wbGV0ZXJzL2F1dG9jb21wbGV0ZXJCYXNlLmpzIiwic3JjL2F1dG9jb21wbGV0ZXJzL2NsYXNzZXMuanMiLCJzcmMvYXV0b2NvbXBsZXRlcnMvcHJlZml4ZXMuanMiLCJzcmMvYXV0b2NvbXBsZXRlcnMvcHJvcGVydGllcy5qcyIsInNyYy9hdXRvY29tcGxldGVycy91dGlscy5qcyIsInNyYy9hdXRvY29tcGxldGVycy92YXJpYWJsZXMuanMiLCJzcmMvZGVmYXVsdHMuanMiLCJzcmMvaW1ncy5qcyIsInNyYy9tYWluLmpzIiwic3JjL3ByZWZpeEZvbGQuanMiLCJzcmMvcHJlZml4VXRpbHMuanMiLCJzcmMvc3BhcnFsLmpzIiwic3JjL3Rva2VuVXRpbHMuanMiLCJzcmMvdG9vbHRpcC5qcyIsInNyYy91dGlscy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQ0FBO0FBQ0E7QUFDQTtBQUNBOztBQ0hBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDakdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzF5SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ25qQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsUkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3pDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDekdBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNySkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN4SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3RMQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDcllBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3TEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzcyUEE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFtVUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvS0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMvQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNuQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUMxREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDM0JBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwU0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDaERBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNoSUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNwREE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDOUhBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3REQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDMUtBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FDVkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzF4QkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ2hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hJQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUM3SUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUN6RUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTs7QUNsQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlc0NvbnRlbnQiOlsiKGZ1bmN0aW9uIGUodCxuLHIpe2Z1bmN0aW9uIHMobyx1KXtpZighbltvXSl7aWYoIXRbb10pe3ZhciBhPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7aWYoIXUmJmEpcmV0dXJuIGEobywhMCk7aWYoaSlyZXR1cm4gaShvLCEwKTt2YXIgZj1uZXcgRXJyb3IoXCJDYW5ub3QgZmluZCBtb2R1bGUgJ1wiK28rXCInXCIpO3Rocm93IGYuY29kZT1cIk1PRFVMRV9OT1RfRk9VTkRcIixmfXZhciBsPW5bb109e2V4cG9ydHM6e319O3Rbb11bMF0uY2FsbChsLmV4cG9ydHMsZnVuY3Rpb24oZSl7dmFyIG49dFtvXVsxXVtlXTtyZXR1cm4gcyhuP246ZSl9LGwsbC5leHBvcnRzLGUsdCxuLHIpfXJldHVybiBuW29dLmV4cG9ydHN9dmFyIGk9dHlwZW9mIHJlcXVpcmU9PVwiZnVuY3Rpb25cIiYmcmVxdWlyZTtmb3IodmFyIG89MDtvPHIubGVuZ3RoO28rKylzKHJbb10pO3JldHVybiBzfSkiLCIvL3RoaXMgaXMgdGhlIGVudHJ5LXBvaW50IGZvciBicm93c2VyaWZ5LlxuLy90aGUgY3VycmVudCBicm93c2VyaWZ5IHZlcnNpb24gZG9lcyBub3Qgc3VwcG9ydCByZXF1aXJlLWluZyBqcyBmaWxlcyB3aGljaCBhcmUgdXNlZCBhcyBlbnRyeS1wb2ludFxuLy90aGlzIHdheSwgd2UgY2FuIHN0aWxsIHJlcXVpcmUgb3VyIG1haW4uanMgZmlsZVxubW9kdWxlLmV4cG9ydHMgPSByZXF1aXJlKCcuL21haW4uanMnKTsiLCIndXNlIHN0cmljdCc7XG4vKlxuICBqUXVlcnkgZGVwYXJhbSBpcyBhbiBleHRyYWN0aW9uIG9mIHRoZSBkZXBhcmFtIG1ldGhvZCBmcm9tIEJlbiBBbG1hbidzIGpRdWVyeSBCQlFcbiAgaHR0cDovL2JlbmFsbWFuLmNvbS9wcm9qZWN0cy9qcXVlcnktYmJxLXBsdWdpbi9cbiovXG52YXIgJCA9IHJlcXVpcmUoXCJqcXVlcnlcIik7XG4kLmRlcGFyYW0gPSBmdW5jdGlvbiAocGFyYW1zLCBjb2VyY2UpIHtcbnZhciBvYmogPSB7fSxcblx0Y29lcmNlX3R5cGVzID0geyAndHJ1ZSc6ICEwLCAnZmFsc2UnOiAhMSwgJ251bGwnOiBudWxsIH07XG4gIFxuLy8gSXRlcmF0ZSBvdmVyIGFsbCBuYW1lPXZhbHVlIHBhaXJzLlxuJC5lYWNoKHBhcmFtcy5yZXBsYWNlKC9cXCsvZywgJyAnKS5zcGxpdCgnJicpLCBmdW5jdGlvbiAoaix2KSB7XG4gIHZhciBwYXJhbSA9IHYuc3BsaXQoJz0nKSxcblx0ICBrZXkgPSBkZWNvZGVVUklDb21wb25lbnQocGFyYW1bMF0pLFxuXHQgIHZhbCxcblx0ICBjdXIgPSBvYmosXG5cdCAgaSA9IDAsXG5cdFx0XG5cdCAgLy8gSWYga2V5IGlzIG1vcmUgY29tcGxleCB0aGFuICdmb28nLCBsaWtlICdhW10nIG9yICdhW2JdW2NdJywgc3BsaXQgaXRcblx0ICAvLyBpbnRvIGl0cyBjb21wb25lbnQgcGFydHMuXG5cdCAga2V5cyA9IGtleS5zcGxpdCgnXVsnKSxcblx0ICBrZXlzX2xhc3QgPSBrZXlzLmxlbmd0aCAtIDE7XG5cdFxuICAvLyBJZiB0aGUgZmlyc3Qga2V5cyBwYXJ0IGNvbnRhaW5zIFsgYW5kIHRoZSBsYXN0IGVuZHMgd2l0aCBdLCB0aGVuIFtdXG4gIC8vIGFyZSBjb3JyZWN0bHkgYmFsYW5jZWQuXG4gIGlmICgvXFxbLy50ZXN0KGtleXNbMF0pICYmIC9cXF0kLy50ZXN0KGtleXNba2V5c19sYXN0XSkpIHtcblx0Ly8gUmVtb3ZlIHRoZSB0cmFpbGluZyBdIGZyb20gdGhlIGxhc3Qga2V5cyBwYXJ0LlxuXHRrZXlzW2tleXNfbGFzdF0gPSBrZXlzW2tleXNfbGFzdF0ucmVwbGFjZSgvXFxdJC8sICcnKTtcblx0ICBcblx0Ly8gU3BsaXQgZmlyc3Qga2V5cyBwYXJ0IGludG8gdHdvIHBhcnRzIG9uIHRoZSBbIGFuZCBhZGQgdGhlbSBiYWNrIG9udG9cblx0Ly8gdGhlIGJlZ2lubmluZyBvZiB0aGUga2V5cyBhcnJheS5cblx0a2V5cyA9IGtleXMuc2hpZnQoKS5zcGxpdCgnWycpLmNvbmNhdChrZXlzKTtcblx0ICBcblx0a2V5c19sYXN0ID0ga2V5cy5sZW5ndGggLSAxO1xuICB9IGVsc2Uge1xuXHQvLyBCYXNpYyAnZm9vJyBzdHlsZSBrZXkuXG5cdGtleXNfbGFzdCA9IDA7XG4gIH1cblx0XG4gIC8vIEFyZSB3ZSBkZWFsaW5nIHdpdGggYSBuYW1lPXZhbHVlIHBhaXIsIG9yIGp1c3QgYSBuYW1lP1xuICBpZiAocGFyYW0ubGVuZ3RoID09PSAyKSB7XG5cdHZhbCA9IGRlY29kZVVSSUNvbXBvbmVudChwYXJhbVsxXSk7XG5cdCAgXG5cdC8vIENvZXJjZSB2YWx1ZXMuXG5cdGlmIChjb2VyY2UpIHtcblx0ICB2YWwgPSB2YWwgJiYgIWlzTmFOKHZhbCkgICAgICAgICAgICAgID8gK3ZhbCAgICAgICAgICAgICAgLy8gbnVtYmVyXG5cdFx0ICA6IHZhbCA9PT0gJ3VuZGVmaW5lZCcgICAgICAgICAgICAgPyB1bmRlZmluZWQgICAgICAgICAvLyB1bmRlZmluZWRcblx0XHQgIDogY29lcmNlX3R5cGVzW3ZhbF0gIT09IHVuZGVmaW5lZCA/IGNvZXJjZV90eXBlc1t2YWxdIC8vIHRydWUsIGZhbHNlLCBudWxsXG5cdFx0ICA6IHZhbDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdHJpbmdcblx0fVxuXHQgIFxuXHRpZiAoIGtleXNfbGFzdCApIHtcblx0ICAvLyBDb21wbGV4IGtleSwgYnVpbGQgZGVlcCBvYmplY3Qgc3RydWN0dXJlIGJhc2VkIG9uIGEgZmV3IHJ1bGVzOlxuXHQgIC8vICogVGhlICdjdXInIHBvaW50ZXIgc3RhcnRzIGF0IHRoZSBvYmplY3QgdG9wLWxldmVsLlxuXHQgIC8vICogW10gPSBhcnJheSBwdXNoIChuIGlzIHNldCB0byBhcnJheSBsZW5ndGgpLCBbbl0gPSBhcnJheSBpZiBuIGlzIFxuXHQgIC8vICAgbnVtZXJpYywgb3RoZXJ3aXNlIG9iamVjdC5cblx0ICAvLyAqIElmIGF0IHRoZSBsYXN0IGtleXMgcGFydCwgc2V0IHRoZSB2YWx1ZS5cblx0ICAvLyAqIEZvciBlYWNoIGtleXMgcGFydCwgaWYgdGhlIGN1cnJlbnQgbGV2ZWwgaXMgdW5kZWZpbmVkIGNyZWF0ZSBhblxuXHQgIC8vICAgb2JqZWN0IG9yIGFycmF5IGJhc2VkIG9uIHRoZSB0eXBlIG9mIHRoZSBuZXh0IGtleXMgcGFydC5cblx0ICAvLyAqIE1vdmUgdGhlICdjdXInIHBvaW50ZXIgdG8gdGhlIG5leHQgbGV2ZWwuXG5cdCAgLy8gKiBSaW5zZSAmIHJlcGVhdC5cblx0ICBmb3IgKDsgaSA8PSBrZXlzX2xhc3Q7IGkrKykge1xuXHRcdGtleSA9IGtleXNbaV0gPT09ICcnID8gY3VyLmxlbmd0aCA6IGtleXNbaV07XG5cdFx0Y3VyID0gY3VyW2tleV0gPSBpIDwga2V5c19sYXN0XG5cdFx0ICA/IGN1cltrZXldIHx8IChrZXlzW2krMV0gJiYgaXNOYU4oa2V5c1tpKzFdKSA/IHt9IDogW10pXG5cdFx0ICA6IHZhbDtcblx0ICB9XG5cdFx0XG5cdH0gZWxzZSB7XG5cdCAgLy8gU2ltcGxlIGtleSwgZXZlbiBzaW1wbGVyIHJ1bGVzLCBzaW5jZSBvbmx5IHNjYWxhcnMgYW5kIHNoYWxsb3dcblx0ICAvLyBhcnJheXMgYXJlIGFsbG93ZWQuXG5cdFx0XG5cdCAgaWYgKCQuaXNBcnJheShvYmpba2V5XSkpIHtcblx0XHQvLyB2YWwgaXMgYWxyZWFkeSBhbiBhcnJheSwgc28gcHVzaCBvbiB0aGUgbmV4dCB2YWx1ZS5cblx0XHRvYmpba2V5XS5wdXNoKCB2YWwgKTtcblx0XHQgIFxuXHQgIH0gZWxzZSBpZiAob2JqW2tleV0gIT09IHVuZGVmaW5lZCkge1xuXHRcdC8vIHZhbCBpc24ndCBhbiBhcnJheSwgYnV0IHNpbmNlIGEgc2Vjb25kIHZhbHVlIGhhcyBiZWVuIHNwZWNpZmllZCxcblx0XHQvLyBjb252ZXJ0IHZhbCBpbnRvIGFuIGFycmF5LlxuXHRcdG9ialtrZXldID0gW29ialtrZXldLCB2YWxdO1xuXHRcdCAgXG5cdCAgfSBlbHNlIHtcblx0XHQvLyB2YWwgaXMgYSBzY2FsYXIuXG5cdFx0b2JqW2tleV0gPSB2YWw7XG5cdCAgfVxuXHR9XG5cdCAgXG4gIH0gZWxzZSBpZiAoa2V5KSB7XG5cdC8vIE5vIHZhbHVlIHdhcyBkZWZpbmVkLCBzbyBzZXQgc29tZXRoaW5nIG1lYW5pbmdmdWwuXG5cdG9ialtrZXldID0gY29lcmNlXG5cdCAgPyB1bmRlZmluZWRcblx0ICA6ICcnO1xuICB9XG59KTtcbiAgXG5yZXR1cm4gb2JqO1xufTtcbiIsIm1vZHVsZS5leHBvcnRzID0ge3RhYmxlOlxue1xuICBcIipbJiYsdmFsdWVMb2dpY2FsXVwiIDoge1xuICAgICBcIiYmXCI6IFtcIlsmJix2YWx1ZUxvZ2ljYWxdXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIkFTXCI6IFtdLCBcbiAgICAgXCIpXCI6IFtdLCBcbiAgICAgXCIsXCI6IFtdLCBcbiAgICAgXCJ8fFwiOiBbXSwgXG4gICAgIFwiO1wiOiBbXX0sIFxuICBcIipbLCxleHByZXNzaW9uXVwiIDoge1xuICAgICBcIixcIjogW1wiWywsZXhwcmVzc2lvbl1cIixcIipbLCxleHByZXNzaW9uXVwiXSwgXG4gICAgIFwiKVwiOiBbXX0sIFxuICBcIipbLCxvYmplY3RQYXRoXVwiIDoge1xuICAgICBcIixcIjogW1wiWywsb2JqZWN0UGF0aF1cIixcIipbLCxvYmplY3RQYXRoXVwiXSwgXG4gICAgIFwiLlwiOiBbXSwgXG4gICAgIFwiO1wiOiBbXSwgXG4gICAgIFwiXVwiOiBbXSwgXG4gICAgIFwie1wiOiBbXSwgXG4gICAgIFwiT1BUSU9OQUxcIjogW10sIFxuICAgICBcIk1JTlVTXCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXSwgXG4gICAgIFwiU0VSVklDRVwiOiBbXSwgXG4gICAgIFwiRklMVEVSXCI6IFtdLCBcbiAgICAgXCJCSU5EXCI6IFtdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCIqWywsb2JqZWN0XVwiIDoge1xuICAgICBcIixcIjogW1wiWywsb2JqZWN0XVwiLFwiKlssLG9iamVjdF1cIl0sIFxuICAgICBcIi5cIjogW10sIFxuICAgICBcIjtcIjogW10sIFxuICAgICBcIl1cIjogW10sIFxuICAgICBcIn1cIjogW10sIFxuICAgICBcIkdSQVBIXCI6IFtdLCBcbiAgICAgXCJ7XCI6IFtdLCBcbiAgICAgXCJPUFRJT05BTFwiOiBbXSwgXG4gICAgIFwiTUlOVVNcIjogW10sIFxuICAgICBcIlNFUlZJQ0VcIjogW10sIFxuICAgICBcIkZJTFRFUlwiOiBbXSwgXG4gICAgIFwiQklORFwiOiBbXSwgXG4gICAgIFwiVkFMVUVTXCI6IFtdfSwgXG4gIFwiKlsvLHBhdGhFbHRPckludmVyc2VdXCIgOiB7XG4gICAgIFwiL1wiOiBbXCJbLyxwYXRoRWx0T3JJbnZlcnNlXVwiLFwiKlsvLHBhdGhFbHRPckludmVyc2VdXCJdLCBcbiAgICAgXCJ8XCI6IFtdLCBcbiAgICAgXCIpXCI6IFtdLCBcbiAgICAgXCIoXCI6IFtdLCBcbiAgICAgXCJbXCI6IFtdLCBcbiAgICAgXCJWQVIxXCI6IFtdLCBcbiAgICAgXCJWQVIyXCI6IFtdLCBcbiAgICAgXCJOSUxcIjogW10sIFxuICAgICBcIklSSV9SRUZcIjogW10sIFxuICAgICBcIlRSVUVcIjogW10sIFxuICAgICBcIkZBTFNFXCI6IFtdLCBcbiAgICAgXCJCTEFOS19OT0RFX0xBQkVMXCI6IFtdLCBcbiAgICAgXCJBTk9OXCI6IFtdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW10sIFxuICAgICBcIklOVEVHRVJcIjogW10sIFxuICAgICBcIkRFQ0lNQUxcIjogW10sIFxuICAgICBcIkRPVUJMRVwiOiBbXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW119LCBcbiAgXCIqWzssP1tvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pLG9iamVjdExpc3RdXVwiIDoge1xuICAgICBcIjtcIjogW1wiWzssP1tvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pLG9iamVjdExpc3RdXVwiLFwiKls7LD9bb3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKSxvYmplY3RMaXN0XV1cIl0sIFxuICAgICBcIi5cIjogW10sIFxuICAgICBcIl1cIjogW10sIFxuICAgICBcIntcIjogW10sIFxuICAgICBcIk9QVElPTkFMXCI6IFtdLCBcbiAgICAgXCJNSU5VU1wiOiBbXSwgXG4gICAgIFwiR1JBUEhcIjogW10sIFxuICAgICBcIlNFUlZJQ0VcIjogW10sIFxuICAgICBcIkZJTFRFUlwiOiBbXSwgXG4gICAgIFwiQklORFwiOiBbXSwgXG4gICAgIFwiVkFMVUVTXCI6IFtdLCBcbiAgICAgXCJ9XCI6IFtdfSwgXG4gIFwiKls7LD9bdmVyYixvYmplY3RMaXN0XV1cIiA6IHtcbiAgICAgXCI7XCI6IFtcIls7LD9bdmVyYixvYmplY3RMaXN0XV1cIixcIipbOyw/W3ZlcmIsb2JqZWN0TGlzdF1dXCJdLCBcbiAgICAgXCIuXCI6IFtdLCBcbiAgICAgXCJdXCI6IFtdLCBcbiAgICAgXCJ9XCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXSwgXG4gICAgIFwie1wiOiBbXSwgXG4gICAgIFwiT1BUSU9OQUxcIjogW10sIFxuICAgICBcIk1JTlVTXCI6IFtdLCBcbiAgICAgXCJTRVJWSUNFXCI6IFtdLCBcbiAgICAgXCJGSUxURVJcIjogW10sIFxuICAgICBcIkJJTkRcIjogW10sIFxuICAgICBcIlZBTFVFU1wiOiBbXX0sIFxuICBcIipbVU5JT04sZ3JvdXBHcmFwaFBhdHRlcm5dXCIgOiB7XG4gICAgIFwiVU5JT05cIjogW1wiW1VOSU9OLGdyb3VwR3JhcGhQYXR0ZXJuXVwiLFwiKltVTklPTixncm91cEdyYXBoUGF0dGVybl1cIl0sIFxuICAgICBcIlZBUjFcIjogW10sIFxuICAgICBcIlZBUjJcIjogW10sIFxuICAgICBcIk5JTFwiOiBbXSwgXG4gICAgIFwiKFwiOiBbXSwgXG4gICAgIFwiW1wiOiBbXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXSwgXG4gICAgIFwiVFJVRVwiOiBbXSwgXG4gICAgIFwiRkFMU0VcIjogW10sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW10sIFxuICAgICBcIkFOT05cIjogW10sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW10sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW10sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiLlwiOiBbXSwgXG4gICAgIFwie1wiOiBbXSwgXG4gICAgIFwiT1BUSU9OQUxcIjogW10sIFxuICAgICBcIk1JTlVTXCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXSwgXG4gICAgIFwiU0VSVklDRVwiOiBbXSwgXG4gICAgIFwiRklMVEVSXCI6IFtdLCBcbiAgICAgXCJCSU5EXCI6IFtdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIiA6IHtcbiAgICAgXCJ7XCI6IFtcIltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIk9QVElPTkFMXCI6IFtcIltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIk1JTlVTXCI6IFtcIltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIkdSQVBIXCI6IFtcIltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIlNFUlZJQ0VcIjogW1wiW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiRklMVEVSXCI6IFtcIltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIkJJTkRcIjogW1wiW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiVkFMVUVTXCI6IFtcIltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiIDoge1xuICAgICBcIkdSQVBIXCI6IFtcIltxdWFkc05vdFRyaXBsZXMsPy4sP3RyaXBsZXNUZW1wbGF0ZV1cIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJ9XCI6IFtdfSwgXG4gIFwiKlt8LHBhdGhPbmVJblByb3BlcnR5U2V0XVwiIDoge1xuICAgICBcInxcIjogW1wiW3wscGF0aE9uZUluUHJvcGVydHlTZXRdXCIsXCIqW3wscGF0aE9uZUluUHJvcGVydHlTZXRdXCJdLCBcbiAgICAgXCIpXCI6IFtdfSwgXG4gIFwiKlt8LHBhdGhTZXF1ZW5jZV1cIiA6IHtcbiAgICAgXCJ8XCI6IFtcIlt8LHBhdGhTZXF1ZW5jZV1cIixcIipbfCxwYXRoU2VxdWVuY2VdXCJdLCBcbiAgICAgXCIpXCI6IFtdLCBcbiAgICAgXCIoXCI6IFtdLCBcbiAgICAgXCJbXCI6IFtdLCBcbiAgICAgXCJWQVIxXCI6IFtdLCBcbiAgICAgXCJWQVIyXCI6IFtdLCBcbiAgICAgXCJOSUxcIjogW10sIFxuICAgICBcIklSSV9SRUZcIjogW10sIFxuICAgICBcIlRSVUVcIjogW10sIFxuICAgICBcIkZBTFNFXCI6IFtdLCBcbiAgICAgXCJCTEFOS19OT0RFX0xBQkVMXCI6IFtdLCBcbiAgICAgXCJBTk9OXCI6IFtdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW10sIFxuICAgICBcIklOVEVHRVJcIjogW10sIFxuICAgICBcIkRFQ0lNQUxcIjogW10sIFxuICAgICBcIkRPVUJMRVwiOiBbXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW119LCBcbiAgXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIiA6IHtcbiAgICAgXCJ8fFwiOiBbXCJbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJBU1wiOiBbXSwgXG4gICAgIFwiKVwiOiBbXSwgXG4gICAgIFwiLFwiOiBbXSwgXG4gICAgIFwiO1wiOiBbXX0sIFxuICBcIipkYXRhQmxvY2tWYWx1ZVwiIDoge1xuICAgICBcIlVOREVGXCI6IFtcImRhdGFCbG9ja1ZhbHVlXCIsXCIqZGF0YUJsb2NrVmFsdWVcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wiZGF0YUJsb2NrVmFsdWVcIixcIipkYXRhQmxvY2tWYWx1ZVwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJkYXRhQmxvY2tWYWx1ZVwiLFwiKmRhdGFCbG9ja1ZhbHVlXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJkYXRhQmxvY2tWYWx1ZVwiLFwiKmRhdGFCbG9ja1ZhbHVlXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJkYXRhQmxvY2tWYWx1ZVwiLFwiKmRhdGFCbG9ja1ZhbHVlXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJkYXRhQmxvY2tWYWx1ZVwiLFwiKmRhdGFCbG9ja1ZhbHVlXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW1wiZGF0YUJsb2NrVmFsdWVcIixcIipkYXRhQmxvY2tWYWx1ZVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcImRhdGFCbG9ja1ZhbHVlXCIsXCIqZGF0YUJsb2NrVmFsdWVcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcImRhdGFCbG9ja1ZhbHVlXCIsXCIqZGF0YUJsb2NrVmFsdWVcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtcImRhdGFCbG9ja1ZhbHVlXCIsXCIqZGF0YUJsb2NrVmFsdWVcIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1wiZGF0YUJsb2NrVmFsdWVcIixcIipkYXRhQmxvY2tWYWx1ZVwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJkYXRhQmxvY2tWYWx1ZVwiLFwiKmRhdGFCbG9ja1ZhbHVlXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wiZGF0YUJsb2NrVmFsdWVcIixcIipkYXRhQmxvY2tWYWx1ZVwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJkYXRhQmxvY2tWYWx1ZVwiLFwiKmRhdGFCbG9ja1ZhbHVlXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcImRhdGFCbG9ja1ZhbHVlXCIsXCIqZGF0YUJsb2NrVmFsdWVcIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJkYXRhQmxvY2tWYWx1ZVwiLFwiKmRhdGFCbG9ja1ZhbHVlXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcImRhdGFCbG9ja1ZhbHVlXCIsXCIqZGF0YUJsb2NrVmFsdWVcIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wiZGF0YUJsb2NrVmFsdWVcIixcIipkYXRhQmxvY2tWYWx1ZVwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcImRhdGFCbG9ja1ZhbHVlXCIsXCIqZGF0YUJsb2NrVmFsdWVcIl0sIFxuICAgICBcIn1cIjogW10sIFxuICAgICBcIilcIjogW119LCBcbiAgXCIqZGF0YXNldENsYXVzZVwiIDoge1xuICAgICBcIkZST01cIjogW1wiZGF0YXNldENsYXVzZVwiLFwiKmRhdGFzZXRDbGF1c2VcIl0sIFxuICAgICBcIldIRVJFXCI6IFtdLCBcbiAgICAgXCJ7XCI6IFtdfSwgXG4gIFwiKmRlc2NyaWJlRGF0YXNldENsYXVzZVwiIDoge1xuICAgICBcIkZST01cIjogW1wiZGVzY3JpYmVEYXRhc2V0Q2xhdXNlXCIsXCIqZGVzY3JpYmVEYXRhc2V0Q2xhdXNlXCJdLCBcbiAgICAgXCJPUkRFUlwiOiBbXSwgXG4gICAgIFwiSEFWSU5HXCI6IFtdLCBcbiAgICAgXCJHUk9VUFwiOiBbXSwgXG4gICAgIFwiTElNSVRcIjogW10sIFxuICAgICBcIk9GRlNFVFwiOiBbXSwgXG4gICAgIFwiV0hFUkVcIjogW10sIFxuICAgICBcIntcIjogW10sIFxuICAgICBcIlZBTFVFU1wiOiBbXSwgXG4gICAgIFwiJFwiOiBbXX0sIFxuICBcIipncmFwaE5vZGVcIiA6IHtcbiAgICAgXCIoXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiW1wiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIlZBUjFcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiTklMXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIlRSVUVcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJBTk9OXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCIpXCI6IFtdfSwgXG4gIFwiKmdyYXBoTm9kZVBhdGhcIiA6IHtcbiAgICAgXCIoXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJbXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJOSUxcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIlRSVUVcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJCTEFOS19OT0RFX0xBQkVMXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJBTk9OXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIilcIjogW119LCBcbiAgXCIqZ3JvdXBDb25kaXRpb25cIiA6IHtcbiAgICAgXCIoXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUlwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJMQU5HXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIkxBTkdNQVRDSEVTXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIkRBVEFUWVBFXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIkJPVU5EXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIklSSVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJVUklcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiQk5PREVcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiUkFORFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJBQlNcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiQ0VJTFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJGTE9PUlwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJST1VORFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJDT05DQVRcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSTEVOXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlVDQVNFXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIkxDQVNFXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIkVOQ09ERV9GT1JfVVJJXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIkNPTlRBSU5TXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJFTkRTXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUkJFRk9SRVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJBRlRFUlwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJZRUFSXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIk1PTlRIXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIkRBWVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJIT1VSU1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJNSU5VVEVTXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNFQ09ORFNcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiVElNRVpPTkVcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiVFpcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiTk9XXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlVVSURcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSVVVJRFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJNRDVcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiU0hBMVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTSEEyNTZcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiU0hBMzg0XCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNIQTUxMlwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJDT0FMRVNDRVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJRlwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJMQU5HXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUkRUXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNBTUVURVJNXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIklTSVJJXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIklTVVJJXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIklTQkxBTktcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiSVNMSVRFUkFMXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIklTTlVNRVJJQ1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlZBUjJcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiU1VCU1RSXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlJFUExBQ0VcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiUkVHRVhcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiRVhJU1RTXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIk5PVFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlZBTFVFU1wiOiBbXSwgXG4gICAgIFwiTElNSVRcIjogW10sIFxuICAgICBcIk9GRlNFVFwiOiBbXSwgXG4gICAgIFwiT1JERVJcIjogW10sIFxuICAgICBcIkhBVklOR1wiOiBbXSwgXG4gICAgIFwiJFwiOiBbXSwgXG4gICAgIFwifVwiOiBbXX0sIFxuICBcIipoYXZpbmdDb25kaXRpb25cIiA6IHtcbiAgICAgXCIoXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiTEFOR1wiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkxBTkdNQVRDSEVTXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiREFUQVRZUEVcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJCT1VORFwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIklSSVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlVSSVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkJOT0RFXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiUkFORFwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkFCU1wiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkNFSUxcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJGTE9PUlwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlJPVU5EXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiQ09OQ0FUXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSTEVOXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiVUNBU0VcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJMQ0FTRVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkVOQ09ERV9GT1JfVVJJXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiQ09OVEFJTlNcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJTVEFSVFNcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJFTkRTXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSQkVGT1JFXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSQUZURVJcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJZRUFSXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiTU9OVEhcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJEQVlcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJIT1VSU1wiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIk1JTlVURVNcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTRUNPTkRTXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiVElNRVpPTkVcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJUWlwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIk5PV1wiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlVVSURcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJVVUlEXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiTUQ1XCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiU0hBMVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlNIQTI1NlwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlNIQTM4NFwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlNIQTUxMlwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkNPQUxFU0NFXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiSUZcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJMQU5HXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSRFRcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTQU1FVEVSTVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIklTSVJJXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiSVNVUklcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU0JMQU5LXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiSVNMSVRFUkFMXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiSVNOVU1FUklDXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiU1VCU1RSXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiUkVQTEFDRVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlJFR0VYXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiRVhJU1RTXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiTk9UXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIkxJTUlUXCI6IFtdLCBcbiAgICAgXCJPRkZTRVRcIjogW10sIFxuICAgICBcIk9SREVSXCI6IFtdLCBcbiAgICAgXCIkXCI6IFtdLCBcbiAgICAgXCJ9XCI6IFtdfSwgXG4gIFwiKm9yKFtbICgsKmRhdGFCbG9ja1ZhbHVlLCldLE5JTF0pXCIgOiB7XG4gICAgIFwiKFwiOiBbXCJvcihbWyAoLCpkYXRhQmxvY2tWYWx1ZSwpXSxOSUxdKVwiLFwiKm9yKFtbICgsKmRhdGFCbG9ja1ZhbHVlLCldLE5JTF0pXCJdLCBcbiAgICAgXCJOSUxcIjogW1wib3IoW1sgKCwqZGF0YUJsb2NrVmFsdWUsKV0sTklMXSlcIixcIipvcihbWyAoLCpkYXRhQmxvY2tWYWx1ZSwpXSxOSUxdKVwiXSwgXG4gICAgIFwifVwiOiBbXX0sIFxuICBcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIiA6IHtcbiAgICAgXCIqXCI6IFtcIm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiL1wiOiBbXCJvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkFTXCI6IFtdLCBcbiAgICAgXCIpXCI6IFtdLCBcbiAgICAgXCIsXCI6IFtdLCBcbiAgICAgXCJ8fFwiOiBbXSwgXG4gICAgIFwiJiZcIjogW10sIFxuICAgICBcIj1cIjogW10sIFxuICAgICBcIiE9XCI6IFtdLCBcbiAgICAgXCI8XCI6IFtdLCBcbiAgICAgXCI+XCI6IFtdLCBcbiAgICAgXCI8PVwiOiBbXSwgXG4gICAgIFwiPj1cIjogW10sIFxuICAgICBcIklOXCI6IFtdLCBcbiAgICAgXCJOT1RcIjogW10sIFxuICAgICBcIitcIjogW10sIFxuICAgICBcIi1cIjogW10sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtdLCBcbiAgICAgXCI7XCI6IFtdfSwgXG4gIFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCIgOiB7XG4gICAgIFwiK1wiOiBbXCJvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCItXCI6IFtcIm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wib3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wib3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcIm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJBU1wiOiBbXSwgXG4gICAgIFwiKVwiOiBbXSwgXG4gICAgIFwiLFwiOiBbXSwgXG4gICAgIFwifHxcIjogW10sIFxuICAgICBcIiYmXCI6IFtdLCBcbiAgICAgXCI9XCI6IFtdLCBcbiAgICAgXCIhPVwiOiBbXSwgXG4gICAgIFwiPFwiOiBbXSwgXG4gICAgIFwiPlwiOiBbXSwgXG4gICAgIFwiPD1cIjogW10sIFxuICAgICBcIj49XCI6IFtdLCBcbiAgICAgXCJJTlwiOiBbXSwgXG4gICAgIFwiTk9UXCI6IFtdLCBcbiAgICAgXCI7XCI6IFtdfSwgXG4gIFwiKm9yKFtiYXNlRGVjbCxwcmVmaXhEZWNsXSlcIiA6IHtcbiAgICAgXCJCQVNFXCI6IFtcIm9yKFtiYXNlRGVjbCxwcmVmaXhEZWNsXSlcIixcIipvcihbYmFzZURlY2wscHJlZml4RGVjbF0pXCJdLCBcbiAgICAgXCJQUkVGSVhcIjogW1wib3IoW2Jhc2VEZWNsLHByZWZpeERlY2xdKVwiLFwiKm9yKFtiYXNlRGVjbCxwcmVmaXhEZWNsXSlcIl0sIFxuICAgICBcIiRcIjogW10sIFxuICAgICBcIkNPTlNUUlVDVFwiOiBbXSwgXG4gICAgIFwiREVTQ1JJQkVcIjogW10sIFxuICAgICBcIkFTS1wiOiBbXSwgXG4gICAgIFwiSU5TRVJUXCI6IFtdLCBcbiAgICAgXCJERUxFVEVcIjogW10sIFxuICAgICBcIlNFTEVDVFwiOiBbXSwgXG4gICAgIFwiTE9BRFwiOiBbXSwgXG4gICAgIFwiQ0xFQVJcIjogW10sIFxuICAgICBcIkRST1BcIjogW10sIFxuICAgICBcIkFERFwiOiBbXSwgXG4gICAgIFwiTU9WRVwiOiBbXSwgXG4gICAgIFwiQ09QWVwiOiBbXSwgXG4gICAgIFwiQ1JFQVRFXCI6IFtdLCBcbiAgICAgXCJXSVRIXCI6IFtdfSwgXG4gIFwiKm9yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIiA6IHtcbiAgICAgXCIoXCI6IFtcIm9yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIixcIipvcihbdmFyLFsgKCxleHByZXNzaW9uLEFTLHZhciwpXV0pXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcIm9yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIixcIipvcihbdmFyLFsgKCxleHByZXNzaW9uLEFTLHZhciwpXV0pXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcIm9yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIixcIipvcihbdmFyLFsgKCxleHByZXNzaW9uLEFTLHZhciwpXV0pXCJdLCBcbiAgICAgXCJXSEVSRVwiOiBbXSwgXG4gICAgIFwie1wiOiBbXSwgXG4gICAgIFwiRlJPTVwiOiBbXX0sIFxuICBcIipvcmRlckNvbmRpdGlvblwiIDoge1xuICAgICBcIkFTQ1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJERVNDXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlZBUjFcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCIoXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUlwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJMQU5HXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIkxBTkdNQVRDSEVTXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIkRBVEFUWVBFXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIkJPVU5EXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIklSSVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJVUklcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiQk5PREVcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiUkFORFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJBQlNcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiQ0VJTFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJGTE9PUlwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJST1VORFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJDT05DQVRcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSTEVOXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlVDQVNFXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIkxDQVNFXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIkVOQ09ERV9GT1JfVVJJXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIkNPTlRBSU5TXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJFTkRTXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUkJFRk9SRVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJBRlRFUlwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJZRUFSXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIk1PTlRIXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIkRBWVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJIT1VSU1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJNSU5VVEVTXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNFQ09ORFNcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiVElNRVpPTkVcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiVFpcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiTk9XXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlVVSURcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSVVVJRFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJNRDVcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiU0hBMVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTSEEyNTZcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiU0hBMzg0XCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNIQTUxMlwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJDT0FMRVNDRVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJRlwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJMQU5HXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUkRUXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNBTUVURVJNXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIklTSVJJXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIklTVVJJXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIklTQkxBTktcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiSVNMSVRFUkFMXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIklTTlVNRVJJQ1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiUkVQTEFDRVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJSRUdFWFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJFWElTVFNcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiTk9UXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiVkFMVUVTXCI6IFtdLCBcbiAgICAgXCJMSU1JVFwiOiBbXSwgXG4gICAgIFwiT0ZGU0VUXCI6IFtdLCBcbiAgICAgXCIkXCI6IFtdLCBcbiAgICAgXCJ9XCI6IFtdfSwgXG4gIFwiKnVzaW5nQ2xhdXNlXCIgOiB7XG4gICAgIFwiVVNJTkdcIjogW1widXNpbmdDbGF1c2VcIixcIip1c2luZ0NsYXVzZVwiXSwgXG4gICAgIFwiV0hFUkVcIjogW119LCBcbiAgXCIqdmFyXCIgOiB7XG4gICAgIFwiVkFSMVwiOiBbXCJ2YXJcIixcIip2YXJcIl0sIFxuICAgICBcIlZBUjJcIjogW1widmFyXCIsXCIqdmFyXCJdLCBcbiAgICAgXCIpXCI6IFtdfSwgXG4gIFwiKnZhck9ySVJJcmVmXCIgOiB7XG4gICAgIFwiVkFSMVwiOiBbXCJ2YXJPcklSSXJlZlwiLFwiKnZhck9ySVJJcmVmXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInZhck9ySVJJcmVmXCIsXCIqdmFyT3JJUklyZWZcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1widmFyT3JJUklyZWZcIixcIip2YXJPcklSSXJlZlwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1widmFyT3JJUklyZWZcIixcIip2YXJPcklSSXJlZlwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1widmFyT3JJUklyZWZcIixcIip2YXJPcklSSXJlZlwiXSwgXG4gICAgIFwiT1JERVJcIjogW10sIFxuICAgICBcIkhBVklOR1wiOiBbXSwgXG4gICAgIFwiR1JPVVBcIjogW10sIFxuICAgICBcIkxJTUlUXCI6IFtdLCBcbiAgICAgXCJPRkZTRVRcIjogW10sIFxuICAgICBcIldIRVJFXCI6IFtdLCBcbiAgICAgXCJ7XCI6IFtdLCBcbiAgICAgXCJGUk9NXCI6IFtdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIiRcIjogW119LCBcbiAgXCIrZ3JhcGhOb2RlXCIgOiB7XG4gICAgIFwiKFwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIltcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIk5JTFwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJUUlVFXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiRkFMU0VcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJCTEFOS19OT0RFX0xBQkVMXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiQU5PTlwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJncmFwaE5vZGVcIixcIipncmFwaE5vZGVcIl0sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW1wiZ3JhcGhOb2RlXCIsXCIqZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcImdyYXBoTm9kZVwiLFwiKmdyYXBoTm9kZVwiXX0sIFxuICBcIitncmFwaE5vZGVQYXRoXCIgOiB7XG4gICAgIFwiKFwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiW1wiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiTklMXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJUUlVFXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiQkxBTktfTk9ERV9MQUJFTFwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiQU5PTlwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1wiZ3JhcGhOb2RlUGF0aFwiLFwiKmdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJncmFwaE5vZGVQYXRoXCIsXCIqZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcImdyYXBoTm9kZVBhdGhcIixcIipncmFwaE5vZGVQYXRoXCJdfSwgXG4gIFwiK2dyb3VwQ29uZGl0aW9uXCIgOiB7XG4gICAgIFwiKFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiTEFOR1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJMQU5HTUFUQ0hFU1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJEQVRBVFlQRVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJCT1VORFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJUklcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiVVJJXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIkJOT0RFXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlJBTkRcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiQUJTXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIkNFSUxcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiRkxPT1JcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiUk9VTkRcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiQ09OQ0FUXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUkxFTlwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJVQ0FTRVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJMQ0FTRVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJFTkNPREVfRk9SX1VSSVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJDT05UQUlOU1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJTVEFSVFNcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSRU5EU1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJCRUZPUkVcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSQUZURVJcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiWUVBUlwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJNT05USFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJEQVlcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiSE9VUlNcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiTUlOVVRFU1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTRUNPTkRTXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlRJTUVaT05FXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlRaXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIk5PV1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJVVUlEXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUlVVSURcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiTUQ1XCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNIQTFcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiU0hBMjU2XCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNIQTM4NFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTSEE1MTJcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiQ09BTEVTQ0VcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiSUZcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSTEFOR1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJEVFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTQU1FVEVSTVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU0lSSVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU1VSSVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU0JMQU5LXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIklTTElURVJBTFwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU05VTUVSSUNcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlNVQlNUUlwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJSRVBMQUNFXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIlJFR0VYXCI6IFtcImdyb3VwQ29uZGl0aW9uXCIsXCIqZ3JvdXBDb25kaXRpb25cIl0sIFxuICAgICBcIkVYSVNUU1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJOT1RcIjogW1wiZ3JvdXBDb25kaXRpb25cIixcIipncm91cENvbmRpdGlvblwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJncm91cENvbmRpdGlvblwiLFwiKmdyb3VwQ29uZGl0aW9uXCJdfSwgXG4gIFwiK2hhdmluZ0NvbmRpdGlvblwiIDoge1xuICAgICBcIihcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJMQU5HXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiTEFOR01BVENIRVNcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJEQVRBVFlQRVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkJPVU5EXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiSVJJXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiVVJJXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiQk5PREVcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJSQU5EXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiQUJTXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiQ0VJTFwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkZMT09SXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiUk9VTkRcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJDT05DQVRcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJMRU5cIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJVQ0FTRVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkxDQVNFXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiRU5DT0RFX0ZPUl9VUklcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJDT05UQUlOU1wiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUkVORFNcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJCRUZPUkVcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJBRlRFUlwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIllFQVJcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJNT05USFwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkRBWVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIkhPVVJTXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiTUlOVVRFU1wiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlNFQ09ORFNcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJUSU1FWk9ORVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlRaXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiTk9XXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiVVVJRFwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUlVVSURcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJNRDVcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTSEExXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiU0hBMjU2XCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiU0hBMzg0XCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiU0hBNTEyXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiQ09BTEVTQ0VcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJRlwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUkxBTkdcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJEVFwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIlNBTUVURVJNXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiSVNJUklcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU1VSSVwiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl0sIFxuICAgICBcIklTQkxBTktcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU0xJVEVSQUxcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU05VTUVSSUNcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJSRVBMQUNFXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiUkVHRVhcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJFWElTVFNcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJOT1RcIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcImhhdmluZ0NvbmRpdGlvblwiLFwiKmhhdmluZ0NvbmRpdGlvblwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiaGF2aW5nQ29uZGl0aW9uXCIsXCIqaGF2aW5nQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJoYXZpbmdDb25kaXRpb25cIixcIipoYXZpbmdDb25kaXRpb25cIl19LCBcbiAgXCIrb3IoW3ZhcixbICgsZXhwcmVzc2lvbixBUyx2YXIsKV1dKVwiIDoge1xuICAgICBcIihcIjogW1wib3IoW3ZhcixbICgsZXhwcmVzc2lvbixBUyx2YXIsKV1dKVwiLFwiKm9yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIl0sIFxuICAgICBcIlZBUjFcIjogW1wib3IoW3ZhcixbICgsZXhwcmVzc2lvbixBUyx2YXIsKV1dKVwiLFwiKm9yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIl0sIFxuICAgICBcIlZBUjJcIjogW1wib3IoW3ZhcixbICgsZXhwcmVzc2lvbixBUyx2YXIsKV1dKVwiLFwiKm9yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIl19LCBcbiAgXCIrb3JkZXJDb25kaXRpb25cIiA6IHtcbiAgICAgXCJBU0NcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiREVTQ1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlZBUjJcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiKFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiTEFOR1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJMQU5HTUFUQ0hFU1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJEQVRBVFlQRVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJCT1VORFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJUklcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiVVJJXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIkJOT0RFXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlJBTkRcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiQUJTXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIkNFSUxcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiRkxPT1JcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiUk9VTkRcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiQ09OQ0FUXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUkxFTlwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJVQ0FTRVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJMQ0FTRVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJFTkNPREVfRk9SX1VSSVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJDT05UQUlOU1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJTVEFSVFNcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSRU5EU1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJCRUZPUkVcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSQUZURVJcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiWUVBUlwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJNT05USFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJEQVlcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiSE9VUlNcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiTUlOVVRFU1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTRUNPTkRTXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlRJTUVaT05FXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlRaXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIk5PV1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJVVUlEXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNUUlVVSURcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiTUQ1XCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNIQTFcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiU0hBMjU2XCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlNIQTM4NFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTSEE1MTJcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiQ09BTEVTQ0VcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiSUZcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiU1RSTEFOR1wiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTVFJEVFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJTQU1FVEVSTVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU0lSSVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU1VSSVwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU0JMQU5LXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIklTTElURVJBTFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJU05VTUVSSUNcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiU1VCU1RSXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlJFUExBQ0VcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiUkVHRVhcIjogW1wib3JkZXJDb25kaXRpb25cIixcIipvcmRlckNvbmRpdGlvblwiXSwgXG4gICAgIFwiRVhJU1RTXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIk5PVFwiOiBbXCJvcmRlckNvbmRpdGlvblwiLFwiKm9yZGVyQ29uZGl0aW9uXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcIm9yZGVyQ29uZGl0aW9uXCIsXCIqb3JkZXJDb25kaXRpb25cIl19LCBcbiAgXCIrdmFyT3JJUklyZWZcIiA6IHtcbiAgICAgXCJWQVIxXCI6IFtcInZhck9ySVJJcmVmXCIsXCIqdmFyT3JJUklyZWZcIl0sIFxuICAgICBcIlZBUjJcIjogW1widmFyT3JJUklyZWZcIixcIip2YXJPcklSSXJlZlwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJ2YXJPcklSSXJlZlwiLFwiKnZhck9ySVJJcmVmXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJ2YXJPcklSSXJlZlwiLFwiKnZhck9ySVJJcmVmXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJ2YXJPcklSSXJlZlwiLFwiKnZhck9ySVJJcmVmXCJdfSwgXG4gIFwiPy5cIiA6IHtcbiAgICAgXCIuXCI6IFtcIi5cIl0sIFxuICAgICBcIlZBUjFcIjogW10sIFxuICAgICBcIlZBUjJcIjogW10sIFxuICAgICBcIk5JTFwiOiBbXSwgXG4gICAgIFwiKFwiOiBbXSwgXG4gICAgIFwiW1wiOiBbXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXSwgXG4gICAgIFwiVFJVRVwiOiBbXSwgXG4gICAgIFwiRkFMU0VcIjogW10sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW10sIFxuICAgICBcIkFOT05cIjogW10sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW10sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW10sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiR1JBUEhcIjogW10sIFxuICAgICBcIntcIjogW10sIFxuICAgICBcIk9QVElPTkFMXCI6IFtdLCBcbiAgICAgXCJNSU5VU1wiOiBbXSwgXG4gICAgIFwiU0VSVklDRVwiOiBbXSwgXG4gICAgIFwiRklMVEVSXCI6IFtdLCBcbiAgICAgXCJCSU5EXCI6IFtdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCI/RElTVElOQ1RcIiA6IHtcbiAgICAgXCJESVNUSU5DVFwiOiBbXCJESVNUSU5DVFwiXSwgXG4gICAgIFwiIVwiOiBbXSwgXG4gICAgIFwiK1wiOiBbXSwgXG4gICAgIFwiLVwiOiBbXSwgXG4gICAgIFwiVkFSMVwiOiBbXSwgXG4gICAgIFwiVkFSMlwiOiBbXSwgXG4gICAgIFwiKFwiOiBbXSwgXG4gICAgIFwiU1RSXCI6IFtdLCBcbiAgICAgXCJMQU5HXCI6IFtdLCBcbiAgICAgXCJMQU5HTUFUQ0hFU1wiOiBbXSwgXG4gICAgIFwiREFUQVRZUEVcIjogW10sIFxuICAgICBcIkJPVU5EXCI6IFtdLCBcbiAgICAgXCJJUklcIjogW10sIFxuICAgICBcIlVSSVwiOiBbXSwgXG4gICAgIFwiQk5PREVcIjogW10sIFxuICAgICBcIlJBTkRcIjogW10sIFxuICAgICBcIkFCU1wiOiBbXSwgXG4gICAgIFwiQ0VJTFwiOiBbXSwgXG4gICAgIFwiRkxPT1JcIjogW10sIFxuICAgICBcIlJPVU5EXCI6IFtdLCBcbiAgICAgXCJDT05DQVRcIjogW10sIFxuICAgICBcIlNUUkxFTlwiOiBbXSwgXG4gICAgIFwiVUNBU0VcIjogW10sIFxuICAgICBcIkxDQVNFXCI6IFtdLCBcbiAgICAgXCJFTkNPREVfRk9SX1VSSVwiOiBbXSwgXG4gICAgIFwiQ09OVEFJTlNcIjogW10sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXSwgXG4gICAgIFwiU1RSRU5EU1wiOiBbXSwgXG4gICAgIFwiU1RSQkVGT1JFXCI6IFtdLCBcbiAgICAgXCJTVFJBRlRFUlwiOiBbXSwgXG4gICAgIFwiWUVBUlwiOiBbXSwgXG4gICAgIFwiTU9OVEhcIjogW10sIFxuICAgICBcIkRBWVwiOiBbXSwgXG4gICAgIFwiSE9VUlNcIjogW10sIFxuICAgICBcIk1JTlVURVNcIjogW10sIFxuICAgICBcIlNFQ09ORFNcIjogW10sIFxuICAgICBcIlRJTUVaT05FXCI6IFtdLCBcbiAgICAgXCJUWlwiOiBbXSwgXG4gICAgIFwiTk9XXCI6IFtdLCBcbiAgICAgXCJVVUlEXCI6IFtdLCBcbiAgICAgXCJTVFJVVUlEXCI6IFtdLCBcbiAgICAgXCJNRDVcIjogW10sIFxuICAgICBcIlNIQTFcIjogW10sIFxuICAgICBcIlNIQTI1NlwiOiBbXSwgXG4gICAgIFwiU0hBMzg0XCI6IFtdLCBcbiAgICAgXCJTSEE1MTJcIjogW10sIFxuICAgICBcIkNPQUxFU0NFXCI6IFtdLCBcbiAgICAgXCJJRlwiOiBbXSwgXG4gICAgIFwiU1RSTEFOR1wiOiBbXSwgXG4gICAgIFwiU1RSRFRcIjogW10sIFxuICAgICBcIlNBTUVURVJNXCI6IFtdLCBcbiAgICAgXCJJU0lSSVwiOiBbXSwgXG4gICAgIFwiSVNVUklcIjogW10sIFxuICAgICBcIklTQkxBTktcIjogW10sIFxuICAgICBcIklTTElURVJBTFwiOiBbXSwgXG4gICAgIFwiSVNOVU1FUklDXCI6IFtdLCBcbiAgICAgXCJUUlVFXCI6IFtdLCBcbiAgICAgXCJGQUxTRVwiOiBbXSwgXG4gICAgIFwiQ09VTlRcIjogW10sIFxuICAgICBcIlNVTVwiOiBbXSwgXG4gICAgIFwiTUlOXCI6IFtdLCBcbiAgICAgXCJNQVhcIjogW10sIFxuICAgICBcIkFWR1wiOiBbXSwgXG4gICAgIFwiU0FNUExFXCI6IFtdLCBcbiAgICAgXCJHUk9VUF9DT05DQVRcIjogW10sIFxuICAgICBcIlNVQlNUUlwiOiBbXSwgXG4gICAgIFwiUkVQTEFDRVwiOiBbXSwgXG4gICAgIFwiUkVHRVhcIjogW10sIFxuICAgICBcIkVYSVNUU1wiOiBbXSwgXG4gICAgIFwiTk9UXCI6IFtdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtdLCBcbiAgICAgXCJET1VCTEVcIjogW10sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW10sIFxuICAgICBcIipcIjogW119LCBcbiAgXCI/R1JBUEhcIiA6IHtcbiAgICAgXCJHUkFQSFwiOiBbXCJHUkFQSFwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW10sIFxuICAgICBcIlBOQU1FX05TXCI6IFtdfSwgXG4gIFwiP1NJTEVOVFwiIDoge1xuICAgICBcIlNJTEVOVFwiOiBbXCJTSUxFTlRcIl0sIFxuICAgICBcIlZBUjFcIjogW10sIFxuICAgICBcIlZBUjJcIjogW10sIFxuICAgICBcIklSSV9SRUZcIjogW10sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXX0sIFxuICBcIj9TSUxFTlRfMVwiIDoge1xuICAgICBcIlNJTEVOVFwiOiBbXCJTSUxFTlRcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW10sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXX0sIFxuICBcIj9TSUxFTlRfMlwiIDoge1xuICAgICBcIlNJTEVOVFwiOiBbXCJTSUxFTlRcIl0sIFxuICAgICBcIkdSQVBIXCI6IFtdLCBcbiAgICAgXCJERUZBVUxUXCI6IFtdLCBcbiAgICAgXCJOQU1FRFwiOiBbXSwgXG4gICAgIFwiQUxMXCI6IFtdfSwgXG4gIFwiP1NJTEVOVF8zXCIgOiB7XG4gICAgIFwiU0lMRU5UXCI6IFtcIlNJTEVOVFwiXSwgXG4gICAgIFwiR1JBUEhcIjogW119LCBcbiAgXCI/U0lMRU5UXzRcIiA6IHtcbiAgICAgXCJTSUxFTlRcIjogW1wiU0lMRU5UXCJdLCBcbiAgICAgXCJERUZBVUxUXCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW10sIFxuICAgICBcIlBOQU1FX05TXCI6IFtdfSwgXG4gIFwiP1dIRVJFXCIgOiB7XG4gICAgIFwiV0hFUkVcIjogW1wiV0hFUkVcIl0sIFxuICAgICBcIntcIjogW119LCBcbiAgXCI/WywsZXhwcmVzc2lvbl1cIiA6IHtcbiAgICAgXCIsXCI6IFtcIlssLGV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCIpXCI6IFtdfSwgXG4gIFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiIDoge1xuICAgICBcIi5cIjogW1wiWy4sP2NvbnN0cnVjdFRyaXBsZXNdXCJdLCBcbiAgICAgXCJ9XCI6IFtdfSwgXG4gIFwiP1suLD90cmlwbGVzQmxvY2tdXCIgOiB7XG4gICAgIFwiLlwiOiBbXCJbLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwie1wiOiBbXSwgXG4gICAgIFwiT1BUSU9OQUxcIjogW10sIFxuICAgICBcIk1JTlVTXCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXSwgXG4gICAgIFwiU0VSVklDRVwiOiBbXSwgXG4gICAgIFwiRklMVEVSXCI6IFtdLCBcbiAgICAgXCJCSU5EXCI6IFtdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCI/Wy4sP3RyaXBsZXNUZW1wbGF0ZV1cIiA6IHtcbiAgICAgXCIuXCI6IFtcIlsuLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJ9XCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXX0sIFxuICBcIj9bOyxTRVBBUkFUT1IsPSxzdHJpbmddXCIgOiB7XG4gICAgIFwiO1wiOiBbXCJbOyxTRVBBUkFUT1IsPSxzdHJpbmddXCJdLCBcbiAgICAgXCIpXCI6IFtdfSwgXG4gIFwiP1s7LHVwZGF0ZV1cIiA6IHtcbiAgICAgXCI7XCI6IFtcIls7LHVwZGF0ZV1cIl0sIFxuICAgICBcIiRcIjogW119LCBcbiAgXCI/W0FTLHZhcl1cIiA6IHtcbiAgICAgXCJBU1wiOiBbXCJbQVMsdmFyXVwiXSwgXG4gICAgIFwiKVwiOiBbXX0sIFxuICBcIj9bSU5UTyxncmFwaFJlZl1cIiA6IHtcbiAgICAgXCJJTlRPXCI6IFtcIltJTlRPLGdyYXBoUmVmXVwiXSwgXG4gICAgIFwiO1wiOiBbXSwgXG4gICAgIFwiJFwiOiBbXX0sIFxuICBcIj9bb3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKSxvYmplY3RMaXN0XVwiIDoge1xuICAgICBcIlZBUjFcIjogW1wiW29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1cIl0sIFxuICAgICBcIlZBUjJcIjogW1wiW29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1cIl0sIFxuICAgICBcIl5cIjogW1wiW29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1cIl0sIFxuICAgICBcImFcIjogW1wiW29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1cIl0sIFxuICAgICBcIiFcIjogW1wiW29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1cIl0sIFxuICAgICBcIihcIjogW1wiW29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1cIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wiW29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcIltvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pLG9iamVjdExpc3RdXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJbb3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKSxvYmplY3RMaXN0XVwiXSwgXG4gICAgIFwiO1wiOiBbXSwgXG4gICAgIFwiLlwiOiBbXSwgXG4gICAgIFwiXVwiOiBbXSwgXG4gICAgIFwie1wiOiBbXSwgXG4gICAgIFwiT1BUSU9OQUxcIjogW10sIFxuICAgICBcIk1JTlVTXCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXSwgXG4gICAgIFwiU0VSVklDRVwiOiBbXSwgXG4gICAgIFwiRklMVEVSXCI6IFtdLCBcbiAgICAgXCJCSU5EXCI6IFtdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCI/W3BhdGhPbmVJblByb3BlcnR5U2V0LCpbfCxwYXRoT25lSW5Qcm9wZXJ0eVNldF1dXCIgOiB7XG4gICAgIFwiYVwiOiBbXCJbcGF0aE9uZUluUHJvcGVydHlTZXQsKlt8LHBhdGhPbmVJblByb3BlcnR5U2V0XV1cIl0sIFxuICAgICBcIl5cIjogW1wiW3BhdGhPbmVJblByb3BlcnR5U2V0LCpbfCxwYXRoT25lSW5Qcm9wZXJ0eVNldF1dXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcIltwYXRoT25lSW5Qcm9wZXJ0eVNldCwqW3wscGF0aE9uZUluUHJvcGVydHlTZXRdXVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiW3BhdGhPbmVJblByb3BlcnR5U2V0LCpbfCxwYXRoT25lSW5Qcm9wZXJ0eVNldF1dXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJbcGF0aE9uZUluUHJvcGVydHlTZXQsKlt8LHBhdGhPbmVJblByb3BlcnR5U2V0XV1cIl0sIFxuICAgICBcIilcIjogW119LCBcbiAgXCI/W3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCIgOiB7XG4gICAgIFwiSU5TRVJUXCI6IFtcIlt1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiREVMRVRFXCI6IFtcIlt1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiTE9BRFwiOiBbXCJbdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIkNMRUFSXCI6IFtcIlt1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiRFJPUFwiOiBbXCJbdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIkFERFwiOiBbXCJbdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIk1PVkVcIjogW1wiW3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCJdLCBcbiAgICAgXCJDT1BZXCI6IFtcIlt1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiQ1JFQVRFXCI6IFtcIlt1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiV0lUSFwiOiBbXCJbdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIiRcIjogW119LCBcbiAgXCI/W3ZlcmIsb2JqZWN0TGlzdF1cIiA6IHtcbiAgICAgXCJhXCI6IFtcIlt2ZXJiLG9iamVjdExpc3RdXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcIlt2ZXJiLG9iamVjdExpc3RdXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcIlt2ZXJiLG9iamVjdExpc3RdXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcIlt2ZXJiLG9iamVjdExpc3RdXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJbdmVyYixvYmplY3RMaXN0XVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiW3ZlcmIsb2JqZWN0TGlzdF1cIl0sIFxuICAgICBcIjtcIjogW10sIFxuICAgICBcIi5cIjogW10sIFxuICAgICBcIl1cIjogW10sIFxuICAgICBcIn1cIjogW10sIFxuICAgICBcIkdSQVBIXCI6IFtdLCBcbiAgICAgXCJ7XCI6IFtdLCBcbiAgICAgXCJPUFRJT05BTFwiOiBbXSwgXG4gICAgIFwiTUlOVVNcIjogW10sIFxuICAgICBcIlNFUlZJQ0VcIjogW10sIFxuICAgICBcIkZJTFRFUlwiOiBbXSwgXG4gICAgIFwiQklORFwiOiBbXSwgXG4gICAgIFwiVkFMVUVTXCI6IFtdfSwgXG4gIFwiP2FyZ0xpc3RcIiA6IHtcbiAgICAgXCJOSUxcIjogW1wiYXJnTGlzdFwiXSwgXG4gICAgIFwiKFwiOiBbXCJhcmdMaXN0XCJdLCBcbiAgICAgXCJBU1wiOiBbXSwgXG4gICAgIFwiKVwiOiBbXSwgXG4gICAgIFwiLFwiOiBbXSwgXG4gICAgIFwifHxcIjogW10sIFxuICAgICBcIiYmXCI6IFtdLCBcbiAgICAgXCI9XCI6IFtdLCBcbiAgICAgXCIhPVwiOiBbXSwgXG4gICAgIFwiPFwiOiBbXSwgXG4gICAgIFwiPlwiOiBbXSwgXG4gICAgIFwiPD1cIjogW10sIFxuICAgICBcIj49XCI6IFtdLCBcbiAgICAgXCJJTlwiOiBbXSwgXG4gICAgIFwiTk9UXCI6IFtdLCBcbiAgICAgXCIrXCI6IFtdLCBcbiAgICAgXCItXCI6IFtdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW10sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW10sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiKlwiOiBbXSwgXG4gICAgIFwiL1wiOiBbXSwgXG4gICAgIFwiO1wiOiBbXX0sIFxuICBcIj9jb25zdHJ1Y3RUcmlwbGVzXCIgOiB7XG4gICAgIFwiVkFSMVwiOiBbXCJjb25zdHJ1Y3RUcmlwbGVzXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcImNvbnN0cnVjdFRyaXBsZXNcIl0sIFxuICAgICBcIk5JTFwiOiBbXCJjb25zdHJ1Y3RUcmlwbGVzXCJdLCBcbiAgICAgXCIoXCI6IFtcImNvbnN0cnVjdFRyaXBsZXNcIl0sIFxuICAgICBcIltcIjogW1wiY29uc3RydWN0VHJpcGxlc1wiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJjb25zdHJ1Y3RUcmlwbGVzXCJdLCBcbiAgICAgXCJUUlVFXCI6IFtcImNvbnN0cnVjdFRyaXBsZXNcIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcImNvbnN0cnVjdFRyaXBsZXNcIl0sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW1wiY29uc3RydWN0VHJpcGxlc1wiXSwgXG4gICAgIFwiQU5PTlwiOiBbXCJjb25zdHJ1Y3RUcmlwbGVzXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJjb25zdHJ1Y3RUcmlwbGVzXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJjb25zdHJ1Y3RUcmlwbGVzXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW1wiY29uc3RydWN0VHJpcGxlc1wiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcImNvbnN0cnVjdFRyaXBsZXNcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcImNvbnN0cnVjdFRyaXBsZXNcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtcImNvbnN0cnVjdFRyaXBsZXNcIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1wiY29uc3RydWN0VHJpcGxlc1wiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJjb25zdHJ1Y3RUcmlwbGVzXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wiY29uc3RydWN0VHJpcGxlc1wiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJjb25zdHJ1Y3RUcmlwbGVzXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcImNvbnN0cnVjdFRyaXBsZXNcIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJjb25zdHJ1Y3RUcmlwbGVzXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcImNvbnN0cnVjdFRyaXBsZXNcIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wiY29uc3RydWN0VHJpcGxlc1wiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcImNvbnN0cnVjdFRyaXBsZXNcIl0sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCI/Z3JvdXBDbGF1c2VcIiA6IHtcbiAgICAgXCJHUk9VUFwiOiBbXCJncm91cENsYXVzZVwiXSwgXG4gICAgIFwiVkFMVUVTXCI6IFtdLCBcbiAgICAgXCJMSU1JVFwiOiBbXSwgXG4gICAgIFwiT0ZGU0VUXCI6IFtdLCBcbiAgICAgXCJPUkRFUlwiOiBbXSwgXG4gICAgIFwiSEFWSU5HXCI6IFtdLCBcbiAgICAgXCIkXCI6IFtdLCBcbiAgICAgXCJ9XCI6IFtdfSwgXG4gIFwiP2hhdmluZ0NsYXVzZVwiIDoge1xuICAgICBcIkhBVklOR1wiOiBbXCJoYXZpbmdDbGF1c2VcIl0sIFxuICAgICBcIlZBTFVFU1wiOiBbXSwgXG4gICAgIFwiTElNSVRcIjogW10sIFxuICAgICBcIk9GRlNFVFwiOiBbXSwgXG4gICAgIFwiT1JERVJcIjogW10sIFxuICAgICBcIiRcIjogW10sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCI/aW5zZXJ0Q2xhdXNlXCIgOiB7XG4gICAgIFwiSU5TRVJUXCI6IFtcImluc2VydENsYXVzZVwiXSwgXG4gICAgIFwiV0hFUkVcIjogW10sIFxuICAgICBcIlVTSU5HXCI6IFtdfSwgXG4gIFwiP2xpbWl0Q2xhdXNlXCIgOiB7XG4gICAgIFwiTElNSVRcIjogW1wibGltaXRDbGF1c2VcIl0sIFxuICAgICBcIlZBTFVFU1wiOiBbXSwgXG4gICAgIFwiJFwiOiBbXSwgXG4gICAgIFwifVwiOiBbXX0sIFxuICBcIj9saW1pdE9mZnNldENsYXVzZXNcIiA6IHtcbiAgICAgXCJMSU1JVFwiOiBbXCJsaW1pdE9mZnNldENsYXVzZXNcIl0sIFxuICAgICBcIk9GRlNFVFwiOiBbXCJsaW1pdE9mZnNldENsYXVzZXNcIl0sIFxuICAgICBcIlZBTFVFU1wiOiBbXSwgXG4gICAgIFwiJFwiOiBbXSwgXG4gICAgIFwifVwiOiBbXX0sIFxuICBcIj9vZmZzZXRDbGF1c2VcIiA6IHtcbiAgICAgXCJPRkZTRVRcIjogW1wib2Zmc2V0Q2xhdXNlXCJdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIiRcIjogW10sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCI/b3IoW0RJU1RJTkNULFJFRFVDRURdKVwiIDoge1xuICAgICBcIkRJU1RJTkNUXCI6IFtcIm9yKFtESVNUSU5DVCxSRURVQ0VEXSlcIl0sIFxuICAgICBcIlJFRFVDRURcIjogW1wib3IoW0RJU1RJTkNULFJFRFVDRURdKVwiXSwgXG4gICAgIFwiKlwiOiBbXSwgXG4gICAgIFwiKFwiOiBbXSwgXG4gICAgIFwiVkFSMVwiOiBbXSwgXG4gICAgIFwiVkFSMlwiOiBbXX0sIFxuICBcIj9vcihbTEFOR1RBRyxbXl4saXJpUmVmXV0pXCIgOiB7XG4gICAgIFwiTEFOR1RBR1wiOiBbXCJvcihbTEFOR1RBRyxbXl4saXJpUmVmXV0pXCJdLCBcbiAgICAgXCJeXlwiOiBbXCJvcihbTEFOR1RBRyxbXl4saXJpUmVmXV0pXCJdLCBcbiAgICAgXCJVTkRFRlwiOiBbXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXSwgXG4gICAgIFwiVFJVRVwiOiBbXSwgXG4gICAgIFwiRkFMU0VcIjogW10sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW10sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW10sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiYVwiOiBbXSwgXG4gICAgIFwiVkFSMVwiOiBbXSwgXG4gICAgIFwiVkFSMlwiOiBbXSwgXG4gICAgIFwiXlwiOiBbXSwgXG4gICAgIFwiIVwiOiBbXSwgXG4gICAgIFwiKFwiOiBbXSwgXG4gICAgIFwiLlwiOiBbXSwgXG4gICAgIFwiO1wiOiBbXSwgXG4gICAgIFwiLFwiOiBbXSwgXG4gICAgIFwiQVNcIjogW10sIFxuICAgICBcIilcIjogW10sIFxuICAgICBcInx8XCI6IFtdLCBcbiAgICAgXCImJlwiOiBbXSwgXG4gICAgIFwiPVwiOiBbXSwgXG4gICAgIFwiIT1cIjogW10sIFxuICAgICBcIjxcIjogW10sIFxuICAgICBcIj5cIjogW10sIFxuICAgICBcIjw9XCI6IFtdLCBcbiAgICAgXCI+PVwiOiBbXSwgXG4gICAgIFwiSU5cIjogW10sIFxuICAgICBcIk5PVFwiOiBbXSwgXG4gICAgIFwiK1wiOiBbXSwgXG4gICAgIFwiLVwiOiBbXSwgXG4gICAgIFwiKlwiOiBbXSwgXG4gICAgIFwiL1wiOiBbXSwgXG4gICAgIFwifVwiOiBbXSwgXG4gICAgIFwiW1wiOiBbXSwgXG4gICAgIFwiTklMXCI6IFtdLCBcbiAgICAgXCJCTEFOS19OT0RFX0xBQkVMXCI6IFtdLCBcbiAgICAgXCJBTk9OXCI6IFtdLCBcbiAgICAgXCJdXCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXSwgXG4gICAgIFwie1wiOiBbXSwgXG4gICAgIFwiT1BUSU9OQUxcIjogW10sIFxuICAgICBcIk1JTlVTXCI6IFtdLCBcbiAgICAgXCJTRVJWSUNFXCI6IFtdLCBcbiAgICAgXCJGSUxURVJcIjogW10sIFxuICAgICBcIkJJTkRcIjogW10sIFxuICAgICBcIlZBTFVFU1wiOiBbXX0sIFxuICBcIj9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIiA6IHtcbiAgICAgXCIqXCI6IFtcIm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiL1wiOiBbXCJvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIitcIjogW10sIFxuICAgICBcIi1cIjogW10sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtdLCBcbiAgICAgXCJBU1wiOiBbXSwgXG4gICAgIFwiKVwiOiBbXSwgXG4gICAgIFwiLFwiOiBbXSwgXG4gICAgIFwifHxcIjogW10sIFxuICAgICBcIiYmXCI6IFtdLCBcbiAgICAgXCI9XCI6IFtdLCBcbiAgICAgXCIhPVwiOiBbXSwgXG4gICAgIFwiPFwiOiBbXSwgXG4gICAgIFwiPlwiOiBbXSwgXG4gICAgIFwiPD1cIjogW10sIFxuICAgICBcIj49XCI6IFtdLCBcbiAgICAgXCJJTlwiOiBbXSwgXG4gICAgIFwiTk9UXCI6IFtdLCBcbiAgICAgXCI7XCI6IFtdfSwgXG4gIFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIiA6IHtcbiAgICAgXCI9XCI6IFtcIm9yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIiE9XCI6IFtcIm9yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIjxcIjogW1wib3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiPlwiOiBbXCJvcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCI8PVwiOiBbXCJvcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCI+PVwiOiBbXCJvcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJJTlwiOiBbXCJvcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJOT1RcIjogW1wib3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiQVNcIjogW10sIFxuICAgICBcIilcIjogW10sIFxuICAgICBcIixcIjogW10sIFxuICAgICBcInx8XCI6IFtdLCBcbiAgICAgXCImJlwiOiBbXSwgXG4gICAgIFwiO1wiOiBbXX0sIFxuICBcIj9vcmRlckNsYXVzZVwiIDoge1xuICAgICBcIk9SREVSXCI6IFtcIm9yZGVyQ2xhdXNlXCJdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIkxJTUlUXCI6IFtdLCBcbiAgICAgXCJPRkZTRVRcIjogW10sIFxuICAgICBcIiRcIjogW10sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCI/cGF0aE1vZFwiIDoge1xuICAgICBcIipcIjogW1wicGF0aE1vZFwiXSwgXG4gICAgIFwiP1wiOiBbXCJwYXRoTW9kXCJdLCBcbiAgICAgXCIrXCI6IFtcInBhdGhNb2RcIl0sIFxuICAgICBcIntcIjogW1wicGF0aE1vZFwiXSwgXG4gICAgIFwifFwiOiBbXSwgXG4gICAgIFwiL1wiOiBbXSwgXG4gICAgIFwiKVwiOiBbXSwgXG4gICAgIFwiKFwiOiBbXSwgXG4gICAgIFwiW1wiOiBbXSwgXG4gICAgIFwiVkFSMVwiOiBbXSwgXG4gICAgIFwiVkFSMlwiOiBbXSwgXG4gICAgIFwiTklMXCI6IFtdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtdLCBcbiAgICAgXCJUUlVFXCI6IFtdLCBcbiAgICAgXCJGQUxTRVwiOiBbXSwgXG4gICAgIFwiQkxBTktfTk9ERV9MQUJFTFwiOiBbXSwgXG4gICAgIFwiQU5PTlwiOiBbXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW10sIFxuICAgICBcIlBOQU1FX05TXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtdLCBcbiAgICAgXCJET1VCTEVcIjogW10sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtdfSwgXG4gIFwiP3RyaXBsZXNCbG9ja1wiIDoge1xuICAgICBcIlZBUjFcIjogW1widHJpcGxlc0Jsb2NrXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInRyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiTklMXCI6IFtcInRyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiKFwiOiBbXCJ0cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIltcIjogW1widHJpcGxlc0Jsb2NrXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcInRyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJ0cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcInRyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiQkxBTktfTk9ERV9MQUJFTFwiOiBbXCJ0cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIkFOT05cIjogW1widHJpcGxlc0Jsb2NrXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJ0cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInRyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInRyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcInRyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1widHJpcGxlc0Jsb2NrXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJ0cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1widHJpcGxlc0Jsb2NrXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcInRyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcInRyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJ0cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1widHJpcGxlc0Jsb2NrXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1widHJpcGxlc0Jsb2NrXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcInRyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJ0cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJ0cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIntcIjogW10sIFxuICAgICBcIk9QVElPTkFMXCI6IFtdLCBcbiAgICAgXCJNSU5VU1wiOiBbXSwgXG4gICAgIFwiR1JBUEhcIjogW10sIFxuICAgICBcIlNFUlZJQ0VcIjogW10sIFxuICAgICBcIkZJTFRFUlwiOiBbXSwgXG4gICAgIFwiQklORFwiOiBbXSwgXG4gICAgIFwiVkFMVUVTXCI6IFtdLCBcbiAgICAgXCJ9XCI6IFtdfSwgXG4gIFwiP3RyaXBsZXNUZW1wbGF0ZVwiIDoge1xuICAgICBcIlZBUjFcIjogW1widHJpcGxlc1RlbXBsYXRlXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInRyaXBsZXNUZW1wbGF0ZVwiXSwgXG4gICAgIFwiTklMXCI6IFtcInRyaXBsZXNUZW1wbGF0ZVwiXSwgXG4gICAgIFwiKFwiOiBbXCJ0cmlwbGVzVGVtcGxhdGVcIl0sIFxuICAgICBcIltcIjogW1widHJpcGxlc1RlbXBsYXRlXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcInRyaXBsZXNUZW1wbGF0ZVwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJ0cmlwbGVzVGVtcGxhdGVcIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcInRyaXBsZXNUZW1wbGF0ZVwiXSwgXG4gICAgIFwiQkxBTktfTk9ERV9MQUJFTFwiOiBbXCJ0cmlwbGVzVGVtcGxhdGVcIl0sIFxuICAgICBcIkFOT05cIjogW1widHJpcGxlc1RlbXBsYXRlXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJ0cmlwbGVzVGVtcGxhdGVcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInRyaXBsZXNUZW1wbGF0ZVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInRyaXBsZXNUZW1wbGF0ZVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcInRyaXBsZXNUZW1wbGF0ZVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1widHJpcGxlc1RlbXBsYXRlXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJ0cmlwbGVzVGVtcGxhdGVcIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1widHJpcGxlc1RlbXBsYXRlXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcInRyaXBsZXNUZW1wbGF0ZVwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcInRyaXBsZXNUZW1wbGF0ZVwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJ0cmlwbGVzVGVtcGxhdGVcIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1widHJpcGxlc1RlbXBsYXRlXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1widHJpcGxlc1RlbXBsYXRlXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcInRyaXBsZXNUZW1wbGF0ZVwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJ0cmlwbGVzVGVtcGxhdGVcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJ0cmlwbGVzVGVtcGxhdGVcIl0sIFxuICAgICBcIn1cIjogW10sIFxuICAgICBcIkdSQVBIXCI6IFtdfSwgXG4gIFwiP3doZXJlQ2xhdXNlXCIgOiB7XG4gICAgIFwiV0hFUkVcIjogW1wid2hlcmVDbGF1c2VcIl0sIFxuICAgICBcIntcIjogW1wid2hlcmVDbGF1c2VcIl0sIFxuICAgICBcIk9SREVSXCI6IFtdLCBcbiAgICAgXCJIQVZJTkdcIjogW10sIFxuICAgICBcIkdST1VQXCI6IFtdLCBcbiAgICAgXCJMSU1JVFwiOiBbXSwgXG4gICAgIFwiT0ZGU0VUXCI6IFtdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIiRcIjogW119LCBcbiAgXCJbICgsKmRhdGFCbG9ja1ZhbHVlLCldXCIgOiB7XG4gICAgIFwiKFwiOiBbXCIoXCIsXCIqZGF0YUJsb2NrVmFsdWVcIixcIilcIl19LCBcbiAgXCJbICgsKnZhciwpXVwiIDoge1xuICAgICBcIihcIjogW1wiKFwiLFwiKnZhclwiLFwiKVwiXX0sIFxuICBcIlsgKCxleHByZXNzaW9uLCldXCIgOiB7XG4gICAgIFwiKFwiOiBbXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdfSwgXG4gIFwiWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXCIgOiB7XG4gICAgIFwiKFwiOiBbXCIoXCIsXCJleHByZXNzaW9uXCIsXCJBU1wiLFwidmFyXCIsXCIpXCJdfSwgXG4gIFwiWyE9LG51bWVyaWNFeHByZXNzaW9uXVwiIDoge1xuICAgICBcIiE9XCI6IFtcIiE9XCIsXCJudW1lcmljRXhwcmVzc2lvblwiXX0sIFxuICBcIlsmJix2YWx1ZUxvZ2ljYWxdXCIgOiB7XG4gICAgIFwiJiZcIjogW1wiJiZcIixcInZhbHVlTG9naWNhbFwiXX0sIFxuICBcIlsqLHVuYXJ5RXhwcmVzc2lvbl1cIiA6IHtcbiAgICAgXCIqXCI6IFtcIipcIixcInVuYXJ5RXhwcmVzc2lvblwiXX0sIFxuICBcIlsqZGF0YXNldENsYXVzZSxXSEVSRSx7LD90cmlwbGVzVGVtcGxhdGUsfSxzb2x1dGlvbk1vZGlmaWVyXVwiIDoge1xuICAgICBcIldIRVJFXCI6IFtcIipkYXRhc2V0Q2xhdXNlXCIsXCJXSEVSRVwiLFwie1wiLFwiP3RyaXBsZXNUZW1wbGF0ZVwiLFwifVwiLFwic29sdXRpb25Nb2RpZmllclwiXSwgXG4gICAgIFwiRlJPTVwiOiBbXCIqZGF0YXNldENsYXVzZVwiLFwiV0hFUkVcIixcIntcIixcIj90cmlwbGVzVGVtcGxhdGVcIixcIn1cIixcInNvbHV0aW9uTW9kaWZpZXJcIl19LCBcbiAgXCJbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dXCIgOiB7XG4gICAgIFwiK1wiOiBbXCIrXCIsXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIl19LCBcbiAgXCJbLCxleHByZXNzaW9uXVwiIDoge1xuICAgICBcIixcIjogW1wiLFwiLFwiZXhwcmVzc2lvblwiXX0sIFxuICBcIlssLGludGVnZXIsfV1cIiA6IHtcbiAgICAgXCIsXCI6IFtcIixcIixcImludGVnZXJcIixcIn1cIl19LCBcbiAgXCJbLCxvYmplY3RQYXRoXVwiIDoge1xuICAgICBcIixcIjogW1wiLFwiLFwib2JqZWN0UGF0aFwiXX0sIFxuICBcIlssLG9iamVjdF1cIiA6IHtcbiAgICAgXCIsXCI6IFtcIixcIixcIm9iamVjdFwiXX0sIFxuICBcIlssLG9yKFt9LFtpbnRlZ2VyLH1dXSldXCIgOiB7XG4gICAgIFwiLFwiOiBbXCIsXCIsXCJvcihbfSxbaW50ZWdlcix9XV0pXCJdfSwgXG4gIFwiWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXVwiIDoge1xuICAgICBcIi1cIjogW1wiLVwiLFwibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCJdfSwgXG4gIFwiWy4sP2NvbnN0cnVjdFRyaXBsZXNdXCIgOiB7XG4gICAgIFwiLlwiOiBbXCIuXCIsXCI/Y29uc3RydWN0VHJpcGxlc1wiXX0sIFxuICBcIlsuLD90cmlwbGVzQmxvY2tdXCIgOiB7XG4gICAgIFwiLlwiOiBbXCIuXCIsXCI/dHJpcGxlc0Jsb2NrXCJdfSwgXG4gIFwiWy4sP3RyaXBsZXNUZW1wbGF0ZV1cIiA6IHtcbiAgICAgXCIuXCI6IFtcIi5cIixcIj90cmlwbGVzVGVtcGxhdGVcIl19LCBcbiAgXCJbLyxwYXRoRWx0T3JJbnZlcnNlXVwiIDoge1xuICAgICBcIi9cIjogW1wiL1wiLFwicGF0aEVsdE9ySW52ZXJzZVwiXX0sIFxuICBcIlsvLHVuYXJ5RXhwcmVzc2lvbl1cIiA6IHtcbiAgICAgXCIvXCI6IFtcIi9cIixcInVuYXJ5RXhwcmVzc2lvblwiXX0sIFxuICBcIls7LD9bb3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKSxvYmplY3RMaXN0XV1cIiA6IHtcbiAgICAgXCI7XCI6IFtcIjtcIixcIj9bb3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKSxvYmplY3RMaXN0XVwiXX0sIFxuICBcIls7LD9bdmVyYixvYmplY3RMaXN0XV1cIiA6IHtcbiAgICAgXCI7XCI6IFtcIjtcIixcIj9bdmVyYixvYmplY3RMaXN0XVwiXX0sIFxuICBcIls7LFNFUEFSQVRPUiw9LHN0cmluZ11cIiA6IHtcbiAgICAgXCI7XCI6IFtcIjtcIixcIlNFUEFSQVRPUlwiLFwiPVwiLFwic3RyaW5nXCJdfSwgXG4gIFwiWzssdXBkYXRlXVwiIDoge1xuICAgICBcIjtcIjogW1wiO1wiLFwidXBkYXRlXCJdfSwgXG4gIFwiWzwsbnVtZXJpY0V4cHJlc3Npb25dXCIgOiB7XG4gICAgIFwiPFwiOiBbXCI8XCIsXCJudW1lcmljRXhwcmVzc2lvblwiXX0sIFxuICBcIls8PSxudW1lcmljRXhwcmVzc2lvbl1cIiA6IHtcbiAgICAgXCI8PVwiOiBbXCI8PVwiLFwibnVtZXJpY0V4cHJlc3Npb25cIl19LCBcbiAgXCJbPSxudW1lcmljRXhwcmVzc2lvbl1cIiA6IHtcbiAgICAgXCI9XCI6IFtcIj1cIixcIm51bWVyaWNFeHByZXNzaW9uXCJdfSwgXG4gIFwiWz4sbnVtZXJpY0V4cHJlc3Npb25dXCIgOiB7XG4gICAgIFwiPlwiOiBbXCI+XCIsXCJudW1lcmljRXhwcmVzc2lvblwiXX0sIFxuICBcIls+PSxudW1lcmljRXhwcmVzc2lvbl1cIiA6IHtcbiAgICAgXCI+PVwiOiBbXCI+PVwiLFwibnVtZXJpY0V4cHJlc3Npb25cIl19LCBcbiAgXCJbQVMsdmFyXVwiIDoge1xuICAgICBcIkFTXCI6IFtcIkFTXCIsXCJ2YXJcIl19LCBcbiAgXCJbSU4sZXhwcmVzc2lvbkxpc3RdXCIgOiB7XG4gICAgIFwiSU5cIjogW1wiSU5cIixcImV4cHJlc3Npb25MaXN0XCJdfSwgXG4gIFwiW0lOVE8sZ3JhcGhSZWZdXCIgOiB7XG4gICAgIFwiSU5UT1wiOiBbXCJJTlRPXCIsXCJncmFwaFJlZlwiXX0sIFxuICBcIltOQU1FRCxpcmlSZWZdXCIgOiB7XG4gICAgIFwiTkFNRURcIjogW1wiTkFNRURcIixcImlyaVJlZlwiXX0sIFxuICBcIltOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXCIgOiB7XG4gICAgIFwiTk9UXCI6IFtcIk5PVFwiLFwiSU5cIixcImV4cHJlc3Npb25MaXN0XCJdfSwgXG4gIFwiW1VOSU9OLGdyb3VwR3JhcGhQYXR0ZXJuXVwiIDoge1xuICAgICBcIlVOSU9OXCI6IFtcIlVOSU9OXCIsXCJncm91cEdyYXBoUGF0dGVyblwiXX0sIFxuICBcIlteXixpcmlSZWZdXCIgOiB7XG4gICAgIFwiXl5cIjogW1wiXl5cIixcImlyaVJlZlwiXX0sIFxuICBcIltjb25zdHJ1Y3RUZW1wbGF0ZSwqZGF0YXNldENsYXVzZSx3aGVyZUNsYXVzZSxzb2x1dGlvbk1vZGlmaWVyXVwiIDoge1xuICAgICBcIntcIjogW1wiY29uc3RydWN0VGVtcGxhdGVcIixcIipkYXRhc2V0Q2xhdXNlXCIsXCJ3aGVyZUNsYXVzZVwiLFwic29sdXRpb25Nb2RpZmllclwiXX0sIFxuICBcIltkZWxldGVDbGF1c2UsP2luc2VydENsYXVzZV1cIiA6IHtcbiAgICAgXCJERUxFVEVcIjogW1wiZGVsZXRlQ2xhdXNlXCIsXCI/aW5zZXJ0Q2xhdXNlXCJdfSwgXG4gIFwiW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIiA6IHtcbiAgICAgXCJ7XCI6IFtcImdyYXBoUGF0dGVybk5vdFRyaXBsZXNcIixcIj8uXCIsXCI/dHJpcGxlc0Jsb2NrXCJdLCBcbiAgICAgXCJPUFRJT05BTFwiOiBbXCJncmFwaFBhdHRlcm5Ob3RUcmlwbGVzXCIsXCI/LlwiLFwiP3RyaXBsZXNCbG9ja1wiXSwgXG4gICAgIFwiTUlOVVNcIjogW1wiZ3JhcGhQYXR0ZXJuTm90VHJpcGxlc1wiLFwiPy5cIixcIj90cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIkdSQVBIXCI6IFtcImdyYXBoUGF0dGVybk5vdFRyaXBsZXNcIixcIj8uXCIsXCI/dHJpcGxlc0Jsb2NrXCJdLCBcbiAgICAgXCJTRVJWSUNFXCI6IFtcImdyYXBoUGF0dGVybk5vdFRyaXBsZXNcIixcIj8uXCIsXCI/dHJpcGxlc0Jsb2NrXCJdLCBcbiAgICAgXCJGSUxURVJcIjogW1wiZ3JhcGhQYXR0ZXJuTm90VHJpcGxlc1wiLFwiPy5cIixcIj90cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIkJJTkRcIjogW1wiZ3JhcGhQYXR0ZXJuTm90VHJpcGxlc1wiLFwiPy5cIixcIj90cmlwbGVzQmxvY2tcIl0sIFxuICAgICBcIlZBTFVFU1wiOiBbXCJncmFwaFBhdHRlcm5Ob3RUcmlwbGVzXCIsXCI/LlwiLFwiP3RyaXBsZXNCbG9ja1wiXX0sIFxuICBcIltpbnRlZ2VyLG9yKFtbLCxvcihbfSxbaW50ZWdlcix9XV0pXSx9XSldXCIgOiB7XG4gICAgIFwiSU5URUdFUlwiOiBbXCJpbnRlZ2VyXCIsXCJvcihbWywsb3IoW30sW2ludGVnZXIsfV1dKV0sfV0pXCJdfSwgXG4gIFwiW2ludGVnZXIsfV1cIiA6IHtcbiAgICAgXCJJTlRFR0VSXCI6IFtcImludGVnZXJcIixcIn1cIl19LCBcbiAgXCJbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXCIgOiB7XG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSlcIixcIj9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1wib3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pXCIsXCI/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wib3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pXCIsXCI/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcIm9yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKVwiLFwiP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSlcIixcIj9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSlcIixcIj9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl19LCBcbiAgXCJbb3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKSxvYmplY3RMaXN0XVwiIDoge1xuICAgICBcIlZBUjFcIjogW1wib3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKVwiLFwib2JqZWN0TGlzdFwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pXCIsXCJvYmplY3RMaXN0XCJdLCBcbiAgICAgXCJeXCI6IFtcIm9yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSlcIixcIm9iamVjdExpc3RcIl0sIFxuICAgICBcImFcIjogW1wib3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKVwiLFwib2JqZWN0TGlzdFwiXSwgXG4gICAgIFwiIVwiOiBbXCJvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pXCIsXCJvYmplY3RMaXN0XCJdLCBcbiAgICAgXCIoXCI6IFtcIm9yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSlcIixcIm9iamVjdExpc3RcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wib3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKVwiLFwib2JqZWN0TGlzdFwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wib3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKVwiLFwib2JqZWN0TGlzdFwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wib3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKVwiLFwib2JqZWN0TGlzdFwiXX0sIFxuICBcIltwYXRoT25lSW5Qcm9wZXJ0eVNldCwqW3wscGF0aE9uZUluUHJvcGVydHlTZXRdXVwiIDoge1xuICAgICBcImFcIjogW1wicGF0aE9uZUluUHJvcGVydHlTZXRcIixcIipbfCxwYXRoT25lSW5Qcm9wZXJ0eVNldF1cIl0sIFxuICAgICBcIl5cIjogW1wicGF0aE9uZUluUHJvcGVydHlTZXRcIixcIipbfCxwYXRoT25lSW5Qcm9wZXJ0eVNldF1cIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wicGF0aE9uZUluUHJvcGVydHlTZXRcIixcIipbfCxwYXRoT25lSW5Qcm9wZXJ0eVNldF1cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInBhdGhPbmVJblByb3BlcnR5U2V0XCIsXCIqW3wscGF0aE9uZUluUHJvcGVydHlTZXRdXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJwYXRoT25lSW5Qcm9wZXJ0eVNldFwiLFwiKlt8LHBhdGhPbmVJblByb3BlcnR5U2V0XVwiXX0sIFxuICBcIltxdWFkc05vdFRyaXBsZXMsPy4sP3RyaXBsZXNUZW1wbGF0ZV1cIiA6IHtcbiAgICAgXCJHUkFQSFwiOiBbXCJxdWFkc05vdFRyaXBsZXNcIixcIj8uXCIsXCI/dHJpcGxlc1RlbXBsYXRlXCJdfSwgXG4gIFwiW3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCIgOiB7XG4gICAgIFwiSU5TRVJUXCI6IFtcInVwZGF0ZTFcIixcIj9bOyx1cGRhdGVdXCJdLCBcbiAgICAgXCJERUxFVEVcIjogW1widXBkYXRlMVwiLFwiP1s7LHVwZGF0ZV1cIl0sIFxuICAgICBcIkxPQURcIjogW1widXBkYXRlMVwiLFwiP1s7LHVwZGF0ZV1cIl0sIFxuICAgICBcIkNMRUFSXCI6IFtcInVwZGF0ZTFcIixcIj9bOyx1cGRhdGVdXCJdLCBcbiAgICAgXCJEUk9QXCI6IFtcInVwZGF0ZTFcIixcIj9bOyx1cGRhdGVdXCJdLCBcbiAgICAgXCJBRERcIjogW1widXBkYXRlMVwiLFwiP1s7LHVwZGF0ZV1cIl0sIFxuICAgICBcIk1PVkVcIjogW1widXBkYXRlMVwiLFwiP1s7LHVwZGF0ZV1cIl0sIFxuICAgICBcIkNPUFlcIjogW1widXBkYXRlMVwiLFwiP1s7LHVwZGF0ZV1cIl0sIFxuICAgICBcIkNSRUFURVwiOiBbXCJ1cGRhdGUxXCIsXCI/WzssdXBkYXRlXVwiXSwgXG4gICAgIFwiV0lUSFwiOiBbXCJ1cGRhdGUxXCIsXCI/WzssdXBkYXRlXVwiXX0sIFxuICBcIlt2ZXJiLG9iamVjdExpc3RdXCIgOiB7XG4gICAgIFwiYVwiOiBbXCJ2ZXJiXCIsXCJvYmplY3RMaXN0XCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcInZlcmJcIixcIm9iamVjdExpc3RcIl0sIFxuICAgICBcIlZBUjJcIjogW1widmVyYlwiLFwib2JqZWN0TGlzdFwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJ2ZXJiXCIsXCJvYmplY3RMaXN0XCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJ2ZXJiXCIsXCJvYmplY3RMaXN0XCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJ2ZXJiXCIsXCJvYmplY3RMaXN0XCJdfSwgXG4gIFwiW3wscGF0aE9uZUluUHJvcGVydHlTZXRdXCIgOiB7XG4gICAgIFwifFwiOiBbXCJ8XCIsXCJwYXRoT25lSW5Qcm9wZXJ0eVNldFwiXX0sIFxuICBcIlt8LHBhdGhTZXF1ZW5jZV1cIiA6IHtcbiAgICAgXCJ8XCI6IFtcInxcIixcInBhdGhTZXF1ZW5jZVwiXX0sIFxuICBcIlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCIgOiB7XG4gICAgIFwifHxcIjogW1wifHxcIixcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiXX0sIFxuICBcImFkZFwiIDoge1xuICAgICBcIkFERFwiOiBbXCJBRERcIixcIj9TSUxFTlRfNFwiLFwiZ3JhcGhPckRlZmF1bHRcIixcIlRPXCIsXCJncmFwaE9yRGVmYXVsdFwiXX0sIFxuICBcImFkZGl0aXZlRXhwcmVzc2lvblwiIDoge1xuICAgICBcIiFcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIitcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIi1cIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlZBUjFcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlZBUjJcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIihcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlNUUlwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiTEFOR1wiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiTEFOR01BVENIRVNcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIkRBVEFUWVBFXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJCT1VORFwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiSVJJXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJVUklcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIkJOT0RFXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJSQU5EXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJBQlNcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIkNFSUxcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIkZMT09SXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJST1VORFwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiQ09OQ0FUXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJTVFJMRU5cIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlVDQVNFXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJMQ0FTRVwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiRU5DT0RFX0ZPUl9VUklcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIkNPTlRBSU5TXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJTVFJTVEFSVFNcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlNUUkVORFNcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlNUUkJFRk9SRVwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiU1RSQUZURVJcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIllFQVJcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIk1PTlRIXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJEQVlcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIkhPVVJTXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJNSU5VVEVTXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJTRUNPTkRTXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJUSU1FWk9ORVwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiVFpcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIk5PV1wiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiVVVJRFwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiU1RSVVVJRFwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiTUQ1XCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJTSEExXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJTSEEyNTZcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlNIQTM4NFwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiU0hBNTEyXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJDT0FMRVNDRVwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiSUZcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlNUUkxBTkdcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlNUUkRUXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJTQU1FVEVSTVwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiSVNJUklcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIklTVVJJXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJJU0JMQU5LXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJJU0xJVEVSQUxcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIklTTlVNRVJJQ1wiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiRkFMU0VcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIkNPVU5UXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJTVU1cIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIk1JTlwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiTUFYXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJBVkdcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlNBTVBMRVwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiR1JPVVBfQ09OQ0FUXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlJFUExBQ0VcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlJFR0VYXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJFWElTVFNcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIk5PVFwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25cIixcIipvcihbWyssbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbLSxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFtvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1dKVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIsXCIqb3IoW1srLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sWy0sbXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXSxbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXSlcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcIm11bHRpcGxpY2F0aXZlRXhwcmVzc2lvblwiLFwiKm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCJdfSwgXG4gIFwiYWdncmVnYXRlXCIgOiB7XG4gICAgIFwiQ09VTlRcIjogW1wiQ09VTlRcIixcIihcIixcIj9ESVNUSU5DVFwiLFwib3IoWyosZXhwcmVzc2lvbl0pXCIsXCIpXCJdLCBcbiAgICAgXCJTVU1cIjogW1wiU1VNXCIsXCIoXCIsXCI/RElTVElOQ1RcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIk1JTlwiOiBbXCJNSU5cIixcIihcIixcIj9ESVNUSU5DVFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiTUFYXCI6IFtcIk1BWFwiLFwiKFwiLFwiP0RJU1RJTkNUXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJBVkdcIjogW1wiQVZHXCIsXCIoXCIsXCI/RElTVElOQ1RcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIlNBTVBMRVwiOiBbXCJTQU1QTEVcIixcIihcIixcIj9ESVNUSU5DVFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiR1JPVVBfQ09OQ0FUXCI6IFtcIkdST1VQX0NPTkNBVFwiLFwiKFwiLFwiP0RJU1RJTkNUXCIsXCJleHByZXNzaW9uXCIsXCI/WzssU0VQQVJBVE9SLD0sc3RyaW5nXVwiLFwiKVwiXX0sIFxuICBcImFsbG93Qm5vZGVzXCIgOiB7XG4gICAgIFwifVwiOiBbXX0sIFxuICBcImFsbG93VmFyc1wiIDoge1xuICAgICBcIn1cIjogW119LCBcbiAgXCJhcmdMaXN0XCIgOiB7XG4gICAgIFwiTklMXCI6IFtcIk5JTFwiXSwgXG4gICAgIFwiKFwiOiBbXCIoXCIsXCI/RElTVElOQ1RcIixcImV4cHJlc3Npb25cIixcIipbLCxleHByZXNzaW9uXVwiLFwiKVwiXX0sIFxuICBcImFza1F1ZXJ5XCIgOiB7XG4gICAgIFwiQVNLXCI6IFtcIkFTS1wiLFwiKmRhdGFzZXRDbGF1c2VcIixcIndoZXJlQ2xhdXNlXCIsXCJzb2x1dGlvbk1vZGlmaWVyXCJdfSwgXG4gIFwiYmFzZURlY2xcIiA6IHtcbiAgICAgXCJCQVNFXCI6IFtcIkJBU0VcIixcIklSSV9SRUZcIl19LCBcbiAgXCJiaW5kXCIgOiB7XG4gICAgIFwiQklORFwiOiBbXCJCSU5EXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCJBU1wiLFwidmFyXCIsXCIpXCJdfSwgXG4gIFwiYmxhbmtOb2RlXCIgOiB7XG4gICAgIFwiQkxBTktfTk9ERV9MQUJFTFwiOiBbXCJCTEFOS19OT0RFX0xBQkVMXCJdLCBcbiAgICAgXCJBTk9OXCI6IFtcIkFOT05cIl19LCBcbiAgXCJibGFua05vZGVQcm9wZXJ0eUxpc3RcIiA6IHtcbiAgICAgXCJbXCI6IFtcIltcIixcInByb3BlcnR5TGlzdE5vdEVtcHR5XCIsXCJdXCJdfSwgXG4gIFwiYmxhbmtOb2RlUHJvcGVydHlMaXN0UGF0aFwiIDoge1xuICAgICBcIltcIjogW1wiW1wiLFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCIsXCJdXCJdfSwgXG4gIFwiYm9vbGVhbkxpdGVyYWxcIiA6IHtcbiAgICAgXCJUUlVFXCI6IFtcIlRSVUVcIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcIkZBTFNFXCJdfSwgXG4gIFwiYnJhY2tldHRlZEV4cHJlc3Npb25cIiA6IHtcbiAgICAgXCIoXCI6IFtcIihcIixcImV4cHJlc3Npb25cIixcIilcIl19LCBcbiAgXCJidWlsdEluQ2FsbFwiIDoge1xuICAgICBcIlNUUlwiOiBbXCJTVFJcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIkxBTkdcIjogW1wiTEFOR1wiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiTEFOR01BVENIRVNcIjogW1wiTEFOR01BVENIRVNcIixcIihcIixcImV4cHJlc3Npb25cIixcIixcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIkRBVEFUWVBFXCI6IFtcIkRBVEFUWVBFXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJCT1VORFwiOiBbXCJCT1VORFwiLFwiKFwiLFwidmFyXCIsXCIpXCJdLCBcbiAgICAgXCJJUklcIjogW1wiSVJJXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJVUklcIjogW1wiVVJJXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJCTk9ERVwiOiBbXCJCTk9ERVwiLFwib3IoW1sgKCxleHByZXNzaW9uLCldLE5JTF0pXCJdLCBcbiAgICAgXCJSQU5EXCI6IFtcIlJBTkRcIixcIk5JTFwiXSwgXG4gICAgIFwiQUJTXCI6IFtcIkFCU1wiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiQ0VJTFwiOiBbXCJDRUlMXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJGTE9PUlwiOiBbXCJGTE9PUlwiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiUk9VTkRcIjogW1wiUk9VTkRcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIkNPTkNBVFwiOiBbXCJDT05DQVRcIixcImV4cHJlc3Npb25MaXN0XCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1wic3Vic3RyaW5nRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSTEVOXCI6IFtcIlNUUkxFTlwiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiUkVQTEFDRVwiOiBbXCJzdHJSZXBsYWNlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVUNBU0VcIjogW1wiVUNBU0VcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIkxDQVNFXCI6IFtcIkxDQVNFXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJFTkNPREVfRk9SX1VSSVwiOiBbXCJFTkNPREVfRk9SX1VSSVwiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiQ09OVEFJTlNcIjogW1wiQ09OVEFJTlNcIixcIihcIixcImV4cHJlc3Npb25cIixcIixcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXCJTVFJTVEFSVFNcIixcIihcIixcImV4cHJlc3Npb25cIixcIixcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIlNUUkVORFNcIjogW1wiU1RSRU5EU1wiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiLFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiU1RSQkVGT1JFXCI6IFtcIlNUUkJFRk9SRVwiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiLFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiU1RSQUZURVJcIjogW1wiU1RSQUZURVJcIixcIihcIixcImV4cHJlc3Npb25cIixcIixcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIllFQVJcIjogW1wiWUVBUlwiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiTU9OVEhcIjogW1wiTU9OVEhcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIkRBWVwiOiBbXCJEQVlcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIkhPVVJTXCI6IFtcIkhPVVJTXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJNSU5VVEVTXCI6IFtcIk1JTlVURVNcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIlNFQ09ORFNcIjogW1wiU0VDT05EU1wiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiVElNRVpPTkVcIjogW1wiVElNRVpPTkVcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIlRaXCI6IFtcIlRaXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJOT1dcIjogW1wiTk9XXCIsXCJOSUxcIl0sIFxuICAgICBcIlVVSURcIjogW1wiVVVJRFwiLFwiTklMXCJdLCBcbiAgICAgXCJTVFJVVUlEXCI6IFtcIlNUUlVVSURcIixcIk5JTFwiXSwgXG4gICAgIFwiTUQ1XCI6IFtcIk1ENVwiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiU0hBMVwiOiBbXCJTSEExXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJTSEEyNTZcIjogW1wiU0hBMjU2XCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJTSEEzODRcIjogW1wiU0hBMzg0XCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJTSEE1MTJcIjogW1wiU0hBNTEyXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJDT0FMRVNDRVwiOiBbXCJDT0FMRVNDRVwiLFwiZXhwcmVzc2lvbkxpc3RcIl0sIFxuICAgICBcIklGXCI6IFtcIklGXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIsXCIsXCJleHByZXNzaW9uXCIsXCIsXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJTVFJMQU5HXCI6IFtcIlNUUkxBTkdcIixcIihcIixcImV4cHJlc3Npb25cIixcIixcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIlNUUkRUXCI6IFtcIlNUUkRUXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIsXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJTQU1FVEVSTVwiOiBbXCJTQU1FVEVSTVwiLFwiKFwiLFwiZXhwcmVzc2lvblwiLFwiLFwiLFwiZXhwcmVzc2lvblwiLFwiKVwiXSwgXG4gICAgIFwiSVNJUklcIjogW1wiSVNJUklcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIklTVVJJXCI6IFtcIklTVVJJXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIpXCJdLCBcbiAgICAgXCJJU0JMQU5LXCI6IFtcIklTQkxBTktcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIklTTElURVJBTFwiOiBbXCJJU0xJVEVSQUxcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIklTTlVNRVJJQ1wiOiBbXCJJU05VTUVSSUNcIixcIihcIixcImV4cHJlc3Npb25cIixcIilcIl0sIFxuICAgICBcIlJFR0VYXCI6IFtcInJlZ2V4RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRVhJU1RTXCI6IFtcImV4aXN0c0Z1bmNcIl0sIFxuICAgICBcIk5PVFwiOiBbXCJub3RFeGlzdHNGdW5jXCJdfSwgXG4gIFwiY2xlYXJcIiA6IHtcbiAgICAgXCJDTEVBUlwiOiBbXCJDTEVBUlwiLFwiP1NJTEVOVF8yXCIsXCJncmFwaFJlZkFsbFwiXX0sIFxuICBcImNvbGxlY3Rpb25cIiA6IHtcbiAgICAgXCIoXCI6IFtcIihcIixcIitncmFwaE5vZGVcIixcIilcIl19LCBcbiAgXCJjb2xsZWN0aW9uUGF0aFwiIDoge1xuICAgICBcIihcIjogW1wiKFwiLFwiK2dyYXBoTm9kZVBhdGhcIixcIilcIl19LCBcbiAgXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIiA6IHtcbiAgICAgXCIhXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCIrXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCItXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCIoXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJTVFJcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIkxBTkdcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIkxBTkdNQVRDSEVTXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJEQVRBVFlQRVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiQk9VTkRcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIklSSVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiVVJJXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJCTk9ERVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiUkFORFwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiQUJTXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJDRUlMXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJGTE9PUlwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiUk9VTkRcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIkNPTkNBVFwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiU1RSTEVOXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJVQ0FTRVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiTENBU0VcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIkVOQ09ERV9GT1JfVVJJXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJDT05UQUlOU1wiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiU1RSU1RBUlRTXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJTVFJFTkRTXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJTVFJCRUZPUkVcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIlNUUkFGVEVSXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJZRUFSXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJNT05USFwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiREFZXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJIT1VSU1wiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiTUlOVVRFU1wiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiU0VDT05EU1wiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiVElNRVpPTkVcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIlRaXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJOT1dcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIlVVSURcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIlNUUlVVSURcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIk1ENVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiU0hBMVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiU0hBMjU2XCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJTSEEzODRcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIlNIQTUxMlwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiQ09BTEVTQ0VcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIklGXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJTVFJMQU5HXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJTVFJEVFwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiU0FNRVRFUk1cIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIklTSVJJXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJJU1VSSVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiSVNCTEFOS1wiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiSVNMSVRFUkFMXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJJU05VTUVSSUNcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIlRSVUVcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJDT1VOVFwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiU1VNXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJNSU5cIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIk1BWFwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiQVZHXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJTQU1QTEVcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIkdST1VQX0NPTkNBVFwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiU1VCU1RSXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJSRVBMQUNFXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJSRUdFWFwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiRVhJU1RTXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJOT1RcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW1widmFsdWVMb2dpY2FsXCIsXCIqWyYmLHZhbHVlTG9naWNhbF1cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInZhbHVlTG9naWNhbFwiLFwiKlsmJix2YWx1ZUxvZ2ljYWxdXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJ2YWx1ZUxvZ2ljYWxcIixcIipbJiYsdmFsdWVMb2dpY2FsXVwiXX0sIFxuICBcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCIgOiB7XG4gICAgIFwiIVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiK1wiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiLVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiKFwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiU1RSXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJMQU5HXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJMQU5HTUFUQ0hFU1wiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiREFUQVRZUEVcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIkJPVU5EXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJJUklcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlVSSVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiQk5PREVcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlJBTkRcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIkFCU1wiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiQ0VJTFwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiRkxPT1JcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlJPVU5EXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJDT05DQVRcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlNUUkxFTlwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiVUNBU0VcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIkxDQVNFXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJFTkNPREVfRk9SX1VSSVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiQ09OVEFJTlNcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiU1RSRU5EU1wiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiU1RSQkVGT1JFXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJTVFJBRlRFUlwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiWUVBUlwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiTU9OVEhcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIkRBWVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiSE9VUlNcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIk1JTlVURVNcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlNFQ09ORFNcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlRJTUVaT05FXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJUWlwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiTk9XXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJVVUlEXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJTVFJVVUlEXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJNRDVcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlNIQTFcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlNIQTI1NlwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiU0hBMzg0XCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJTSEE1MTJcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIkNPQUxFU0NFXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJJRlwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiU1RSTEFOR1wiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiU1RSRFRcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlNBTUVURVJNXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJJU0lSSVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiSVNVUklcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIklTQkxBTktcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIklTTElURVJBTFwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiSVNOVU1FUklDXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJUUlVFXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiQ09VTlRcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlNVTVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiTUlOXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJNQVhcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIkFWR1wiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiU0FNUExFXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJHUk9VUF9DT05DQVRcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlNVQlNUUlwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiUkVQTEFDRVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiUkVHRVhcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIkVYSVNUU1wiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiTk9UXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcImNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvblwiLFwiKlt8fCxjb25kaXRpb25hbEFuZEV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJjb25kaXRpb25hbEFuZEV4cHJlc3Npb25cIixcIipbfHwsY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiY29uZGl0aW9uYWxBbmRFeHByZXNzaW9uXCIsXCIqW3x8LGNvbmRpdGlvbmFsQW5kRXhwcmVzc2lvbl1cIl19LCBcbiAgXCJjb25zdHJhaW50XCIgOiB7XG4gICAgIFwiKFwiOiBbXCJicmFja2V0dGVkRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJMQU5HXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJMQU5HTUFUQ0hFU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiREFUQVRZUEVcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkJPVU5EXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJJUklcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlVSSVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiQk5PREVcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlJBTkRcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkFCU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiQ0VJTFwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiRkxPT1JcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlJPVU5EXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJDT05DQVRcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNUUkxFTlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiVUNBU0VcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkxDQVNFXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJFTkNPREVfRk9SX1VSSVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiQ09OVEFJTlNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU1RSRU5EU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU1RSQkVGT1JFXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTVFJBRlRFUlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiWUVBUlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiTU9OVEhcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkRBWVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiSE9VUlNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIk1JTlVURVNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNFQ09ORFNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlRJTUVaT05FXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJUWlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiTk9XXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJVVUlEXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTVFJVVUlEXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJNRDVcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNIQTFcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNIQTI1NlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU0hBMzg0XCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTSEE1MTJcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkNPQUxFU0NFXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJJRlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU1RSTEFOR1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU1RSRFRcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNBTUVURVJNXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJJU0lSSVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiSVNVUklcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIklTQkxBTktcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIklTTElURVJBTFwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiSVNOVU1FUklDXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlJFUExBQ0VcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlJFR0VYXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJFWElTVFNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIk5PVFwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJmdW5jdGlvbkNhbGxcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcImZ1bmN0aW9uQ2FsbFwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiZnVuY3Rpb25DYWxsXCJdfSwgXG4gIFwiY29uc3RydWN0UXVlcnlcIiA6IHtcbiAgICAgXCJDT05TVFJVQ1RcIjogW1wiQ09OU1RSVUNUXCIsXCJvcihbW2NvbnN0cnVjdFRlbXBsYXRlLCpkYXRhc2V0Q2xhdXNlLHdoZXJlQ2xhdXNlLHNvbHV0aW9uTW9kaWZpZXJdLFsqZGF0YXNldENsYXVzZSxXSEVSRSx7LD90cmlwbGVzVGVtcGxhdGUsfSxzb2x1dGlvbk1vZGlmaWVyXV0pXCJdfSwgXG4gIFwiY29uc3RydWN0VGVtcGxhdGVcIiA6IHtcbiAgICAgXCJ7XCI6IFtcIntcIixcIj9jb25zdHJ1Y3RUcmlwbGVzXCIsXCJ9XCJdfSwgXG4gIFwiY29uc3RydWN0VHJpcGxlc1wiIDoge1xuICAgICBcIlZBUjFcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP2NvbnN0cnVjdFRyaXBsZXNdXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiXSwgXG4gICAgIFwiTklMXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiXSwgXG4gICAgIFwiKFwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/Y29uc3RydWN0VHJpcGxlc11cIl0sIFxuICAgICBcIltcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP2NvbnN0cnVjdFRyaXBsZXNdXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/Y29uc3RydWN0VHJpcGxlc11cIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiXSwgXG4gICAgIFwiQkxBTktfTk9ERV9MQUJFTFwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/Y29uc3RydWN0VHJpcGxlc11cIl0sIFxuICAgICBcIkFOT05cIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP2NvbnN0cnVjdFRyaXBsZXNdXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/Y29uc3RydWN0VHJpcGxlc11cIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP2NvbnN0cnVjdFRyaXBsZXNdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/Y29uc3RydWN0VHJpcGxlc11cIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP2NvbnN0cnVjdFRyaXBsZXNdXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/Y29uc3RydWN0VHJpcGxlc11cIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP2NvbnN0cnVjdFRyaXBsZXNdXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP2NvbnN0cnVjdFRyaXBsZXNdXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD9jb25zdHJ1Y3RUcmlwbGVzXVwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/Y29uc3RydWN0VHJpcGxlc11cIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/Y29uc3RydWN0VHJpcGxlc11cIl19LCBcbiAgXCJjb3B5XCIgOiB7XG4gICAgIFwiQ09QWVwiOiBbXCJDT1BZXCIsXCI/U0lMRU5UXzRcIixcImdyYXBoT3JEZWZhdWx0XCIsXCJUT1wiLFwiZ3JhcGhPckRlZmF1bHRcIl19LCBcbiAgXCJjcmVhdGVcIiA6IHtcbiAgICAgXCJDUkVBVEVcIjogW1wiQ1JFQVRFXCIsXCI/U0lMRU5UXzNcIixcImdyYXBoUmVmXCJdfSwgXG4gIFwiZGF0YUJsb2NrXCIgOiB7XG4gICAgIFwiTklMXCI6IFtcIm9yKFtpbmxpbmVEYXRhT25lVmFyLGlubGluZURhdGFGdWxsXSlcIl0sIFxuICAgICBcIihcIjogW1wib3IoW2lubGluZURhdGFPbmVWYXIsaW5saW5lRGF0YUZ1bGxdKVwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJvcihbaW5saW5lRGF0YU9uZVZhcixpbmxpbmVEYXRhRnVsbF0pXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcIm9yKFtpbmxpbmVEYXRhT25lVmFyLGlubGluZURhdGFGdWxsXSlcIl19LCBcbiAgXCJkYXRhQmxvY2tWYWx1ZVwiIDoge1xuICAgICBcIklSSV9SRUZcIjogW1wiaXJpUmVmXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJpcmlSZWZcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcImlyaVJlZlwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInJkZkxpdGVyYWxcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJyZGZMaXRlcmFsXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJyZGZMaXRlcmFsXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJyZGZMaXRlcmFsXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcIm51bWVyaWNMaXRlcmFsXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcIm51bWVyaWNMaXRlcmFsXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wibnVtZXJpY0xpdGVyYWxcIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wibnVtZXJpY0xpdGVyYWxcIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1wibnVtZXJpY0xpdGVyYWxcIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbFwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbFwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbFwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcIm51bWVyaWNMaXRlcmFsXCJdLCBcbiAgICAgXCJUUlVFXCI6IFtcImJvb2xlYW5MaXRlcmFsXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJib29sZWFuTGl0ZXJhbFwiXSwgXG4gICAgIFwiVU5ERUZcIjogW1wiVU5ERUZcIl19LCBcbiAgXCJkYXRhc2V0Q2xhdXNlXCIgOiB7XG4gICAgIFwiRlJPTVwiOiBbXCJGUk9NXCIsXCJvcihbZGVmYXVsdEdyYXBoQ2xhdXNlLG5hbWVkR3JhcGhDbGF1c2VdKVwiXX0sIFxuICBcImRlZmF1bHRHcmFwaENsYXVzZVwiIDoge1xuICAgICBcIklSSV9SRUZcIjogW1wic291cmNlU2VsZWN0b3JcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInNvdXJjZVNlbGVjdG9yXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJzb3VyY2VTZWxlY3RvclwiXX0sIFxuICBcImRlbGV0ZTFcIiA6IHtcbiAgICAgXCJEQVRBXCI6IFtcIkRBVEFcIixcInF1YWREYXRhTm9Cbm9kZXNcIl0sIFxuICAgICBcIldIRVJFXCI6IFtcIldIRVJFXCIsXCJxdWFkUGF0dGVybk5vQm5vZGVzXCJdLCBcbiAgICAgXCJ7XCI6IFtcInF1YWRQYXR0ZXJuTm9Cbm9kZXNcIixcIj9pbnNlcnRDbGF1c2VcIixcIip1c2luZ0NsYXVzZVwiLFwiV0hFUkVcIixcImdyb3VwR3JhcGhQYXR0ZXJuXCJdfSwgXG4gIFwiZGVsZXRlQ2xhdXNlXCIgOiB7XG4gICAgIFwiREVMRVRFXCI6IFtcIkRFTEVURVwiLFwicXVhZFBhdHRlcm5cIl19LCBcbiAgXCJkZXNjcmliZURhdGFzZXRDbGF1c2VcIiA6IHtcbiAgICAgXCJGUk9NXCI6IFtcIkZST01cIixcIm9yKFtkZWZhdWx0R3JhcGhDbGF1c2UsbmFtZWRHcmFwaENsYXVzZV0pXCJdfSwgXG4gIFwiZGVzY3JpYmVRdWVyeVwiIDoge1xuICAgICBcIkRFU0NSSUJFXCI6IFtcIkRFU0NSSUJFXCIsXCJvcihbK3Zhck9ySVJJcmVmLCpdKVwiLFwiKmRlc2NyaWJlRGF0YXNldENsYXVzZVwiLFwiP3doZXJlQ2xhdXNlXCIsXCJzb2x1dGlvbk1vZGlmaWVyXCJdfSwgXG4gIFwiZGlzYWxsb3dCbm9kZXNcIiA6IHtcbiAgICAgXCJ9XCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXSwgXG4gICAgIFwiVkFSMVwiOiBbXSwgXG4gICAgIFwiVkFSMlwiOiBbXSwgXG4gICAgIFwiTklMXCI6IFtdLCBcbiAgICAgXCIoXCI6IFtdLCBcbiAgICAgXCJbXCI6IFtdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtdLCBcbiAgICAgXCJUUlVFXCI6IFtdLCBcbiAgICAgXCJGQUxTRVwiOiBbXSwgXG4gICAgIFwiQkxBTktfTk9ERV9MQUJFTFwiOiBbXSwgXG4gICAgIFwiQU5PTlwiOiBbXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW10sIFxuICAgICBcIlBOQU1FX05TXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtdLCBcbiAgICAgXCJET1VCTEVcIjogW10sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtdfSwgXG4gIFwiZGlzYWxsb3dWYXJzXCIgOiB7XG4gICAgIFwifVwiOiBbXSwgXG4gICAgIFwiR1JBUEhcIjogW10sIFxuICAgICBcIlZBUjFcIjogW10sIFxuICAgICBcIlZBUjJcIjogW10sIFxuICAgICBcIk5JTFwiOiBbXSwgXG4gICAgIFwiKFwiOiBbXSwgXG4gICAgIFwiW1wiOiBbXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXSwgXG4gICAgIFwiVFJVRVwiOiBbXSwgXG4gICAgIFwiRkFMU0VcIjogW10sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW10sIFxuICAgICBcIkFOT05cIjogW10sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW10sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW10sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW10sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW10sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXX0sIFxuICBcImRyb3BcIiA6IHtcbiAgICAgXCJEUk9QXCI6IFtcIkRST1BcIixcIj9TSUxFTlRfMlwiLFwiZ3JhcGhSZWZBbGxcIl19LCBcbiAgXCJleGlzdHNGdW5jXCIgOiB7XG4gICAgIFwiRVhJU1RTXCI6IFtcIkVYSVNUU1wiLFwiZ3JvdXBHcmFwaFBhdHRlcm5cIl19LCBcbiAgXCJleHByZXNzaW9uXCIgOiB7XG4gICAgIFwiIVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiK1wiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiLVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiKFwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJMQU5HXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJMQU5HTUFUQ0hFU1wiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiREFUQVRZUEVcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIkJPVU5EXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJUklcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlVSSVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQk5PREVcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlJBTkRcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIkFCU1wiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQ0VJTFwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRkxPT1JcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlJPVU5EXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJDT05DQVRcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUkxFTlwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVUNBU0VcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIkxDQVNFXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJFTkNPREVfRk9SX1VSSVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQ09OVEFJTlNcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSRU5EU1wiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSQkVGT1JFXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJBRlRFUlwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiWUVBUlwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTU9OVEhcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRBWVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSE9VUlNcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIk1JTlVURVNcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNFQ09ORFNcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlRJTUVaT05FXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJUWlwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTk9XXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJVVUlEXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJVVUlEXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJNRDVcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNIQTFcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNIQTI1NlwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0hBMzg0XCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTSEE1MTJcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIkNPQUxFU0NFXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJRlwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSTEFOR1wiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSRFRcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNBTUVURVJNXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU0lSSVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSVNVUklcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIklTQkxBTktcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIklTTElURVJBTFwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSVNOVU1FUklDXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJUUlVFXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQ09VTlRcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNVTVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTUlOXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJNQVhcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIkFWR1wiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0FNUExFXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJHUk9VUF9DT05DQVRcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNVQlNUUlwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiUkVQTEFDRVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiUkVHRVhcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIkVYSVNUU1wiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTk9UXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcImNvbmRpdGlvbmFsT3JFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJjb25kaXRpb25hbE9yRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiY29uZGl0aW9uYWxPckV4cHJlc3Npb25cIl19LCBcbiAgXCJleHByZXNzaW9uTGlzdFwiIDoge1xuICAgICBcIk5JTFwiOiBbXCJOSUxcIl0sIFxuICAgICBcIihcIjogW1wiKFwiLFwiZXhwcmVzc2lvblwiLFwiKlssLGV4cHJlc3Npb25dXCIsXCIpXCJdfSwgXG4gIFwiZmlsdGVyXCIgOiB7XG4gICAgIFwiRklMVEVSXCI6IFtcIkZJTFRFUlwiLFwiY29uc3RyYWludFwiXX0sIFxuICBcImZ1bmN0aW9uQ2FsbFwiIDoge1xuICAgICBcIklSSV9SRUZcIjogW1wiaXJpUmVmXCIsXCJhcmdMaXN0XCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJpcmlSZWZcIixcImFyZ0xpc3RcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcImlyaVJlZlwiLFwiYXJnTGlzdFwiXX0sIFxuICBcImdyYXBoR3JhcGhQYXR0ZXJuXCIgOiB7XG4gICAgIFwiR1JBUEhcIjogW1wiR1JBUEhcIixcInZhck9ySVJJcmVmXCIsXCJncm91cEdyYXBoUGF0dGVyblwiXX0sIFxuICBcImdyYXBoTm9kZVwiIDoge1xuICAgICBcIlZBUjFcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiTklMXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIlRSVUVcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJBTk9OXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCIoXCI6IFtcInRyaXBsZXNOb2RlXCJdLCBcbiAgICAgXCJbXCI6IFtcInRyaXBsZXNOb2RlXCJdfSwgXG4gIFwiZ3JhcGhOb2RlUGF0aFwiIDoge1xuICAgICBcIlZBUjFcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiTklMXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIlRSVUVcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJBTk9OXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtcInZhck9yVGVybVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJ2YXJPclRlcm1cIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW1widmFyT3JUZXJtXCJdLCBcbiAgICAgXCIoXCI6IFtcInRyaXBsZXNOb2RlUGF0aFwiXSwgXG4gICAgIFwiW1wiOiBbXCJ0cmlwbGVzTm9kZVBhdGhcIl19LCBcbiAgXCJncmFwaE9yRGVmYXVsdFwiIDoge1xuICAgICBcIkRFRkFVTFRcIjogW1wiREVGQVVMVFwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCI/R1JBUEhcIixcImlyaVJlZlwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiP0dSQVBIXCIsXCJpcmlSZWZcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcIj9HUkFQSFwiLFwiaXJpUmVmXCJdLCBcbiAgICAgXCJHUkFQSFwiOiBbXCI/R1JBUEhcIixcImlyaVJlZlwiXX0sIFxuICBcImdyYXBoUGF0dGVybk5vdFRyaXBsZXNcIiA6IHtcbiAgICAgXCJ7XCI6IFtcImdyb3VwT3JVbmlvbkdyYXBoUGF0dGVyblwiXSwgXG4gICAgIFwiT1BUSU9OQUxcIjogW1wib3B0aW9uYWxHcmFwaFBhdHRlcm5cIl0sIFxuICAgICBcIk1JTlVTXCI6IFtcIm1pbnVzR3JhcGhQYXR0ZXJuXCJdLCBcbiAgICAgXCJHUkFQSFwiOiBbXCJncmFwaEdyYXBoUGF0dGVyblwiXSwgXG4gICAgIFwiU0VSVklDRVwiOiBbXCJzZXJ2aWNlR3JhcGhQYXR0ZXJuXCJdLCBcbiAgICAgXCJGSUxURVJcIjogW1wiZmlsdGVyXCJdLCBcbiAgICAgXCJCSU5EXCI6IFtcImJpbmRcIl0sIFxuICAgICBcIlZBTFVFU1wiOiBbXCJpbmxpbmVEYXRhXCJdfSwgXG4gIFwiZ3JhcGhSZWZcIiA6IHtcbiAgICAgXCJHUkFQSFwiOiBbXCJHUkFQSFwiLFwiaXJpUmVmXCJdfSwgXG4gIFwiZ3JhcGhSZWZBbGxcIiA6IHtcbiAgICAgXCJHUkFQSFwiOiBbXCJncmFwaFJlZlwiXSwgXG4gICAgIFwiREVGQVVMVFwiOiBbXCJERUZBVUxUXCJdLCBcbiAgICAgXCJOQU1FRFwiOiBbXCJOQU1FRFwiXSwgXG4gICAgIFwiQUxMXCI6IFtcIkFMTFwiXX0sIFxuICBcImdyYXBoVGVybVwiIDoge1xuICAgICBcIklSSV9SRUZcIjogW1wiaXJpUmVmXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJpcmlSZWZcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcImlyaVJlZlwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInJkZkxpdGVyYWxcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJyZGZMaXRlcmFsXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJyZGZMaXRlcmFsXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJyZGZMaXRlcmFsXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcIm51bWVyaWNMaXRlcmFsXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcIm51bWVyaWNMaXRlcmFsXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wibnVtZXJpY0xpdGVyYWxcIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wibnVtZXJpY0xpdGVyYWxcIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1wibnVtZXJpY0xpdGVyYWxcIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbFwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbFwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbFwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcIm51bWVyaWNMaXRlcmFsXCJdLCBcbiAgICAgXCJUUlVFXCI6IFtcImJvb2xlYW5MaXRlcmFsXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJib29sZWFuTGl0ZXJhbFwiXSwgXG4gICAgIFwiQkxBTktfTk9ERV9MQUJFTFwiOiBbXCJibGFua05vZGVcIl0sIFxuICAgICBcIkFOT05cIjogW1wiYmxhbmtOb2RlXCJdLCBcbiAgICAgXCJOSUxcIjogW1wiTklMXCJdfSwgXG4gIFwiZ3JvdXBDbGF1c2VcIiA6IHtcbiAgICAgXCJHUk9VUFwiOiBbXCJHUk9VUFwiLFwiQllcIixcIitncm91cENvbmRpdGlvblwiXX0sIFxuICBcImdyb3VwQ29uZGl0aW9uXCIgOiB7XG4gICAgIFwiU1RSXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJMQU5HXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJMQU5HTUFUQ0hFU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiREFUQVRZUEVcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkJPVU5EXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJJUklcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlVSSVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiQk5PREVcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlJBTkRcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkFCU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiQ0VJTFwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiRkxPT1JcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlJPVU5EXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJDT05DQVRcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNUUkxFTlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiVUNBU0VcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkxDQVNFXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJFTkNPREVfRk9SX1VSSVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiQ09OVEFJTlNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU1RSRU5EU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU1RSQkVGT1JFXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTVFJBRlRFUlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiWUVBUlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiTU9OVEhcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkRBWVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiSE9VUlNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIk1JTlVURVNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNFQ09ORFNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlRJTUVaT05FXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJUWlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiTk9XXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJVVUlEXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTVFJVVUlEXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJNRDVcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNIQTFcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNIQTI1NlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU0hBMzg0XCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTSEE1MTJcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkNPQUxFU0NFXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJJRlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU1RSTEFOR1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU1RSRFRcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNBTUVURVJNXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJJU0lSSVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiSVNVUklcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIklTQkxBTktcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIklTTElURVJBTFwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiSVNOVU1FUklDXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlJFUExBQ0VcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlJFR0VYXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJFWElTVFNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIk5PVFwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJmdW5jdGlvbkNhbGxcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcImZ1bmN0aW9uQ2FsbFwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiZnVuY3Rpb25DYWxsXCJdLCBcbiAgICAgXCIoXCI6IFtcIihcIixcImV4cHJlc3Npb25cIixcIj9bQVMsdmFyXVwiLFwiKVwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJ2YXJcIl0sIFxuICAgICBcIlZBUjJcIjogW1widmFyXCJdfSwgXG4gIFwiZ3JvdXBHcmFwaFBhdHRlcm5cIiA6IHtcbiAgICAgXCJ7XCI6IFtcIntcIixcIm9yKFtzdWJTZWxlY3QsZ3JvdXBHcmFwaFBhdHRlcm5TdWJdKVwiLFwifVwiXX0sIFxuICBcImdyb3VwR3JhcGhQYXR0ZXJuU3ViXCIgOiB7XG4gICAgIFwie1wiOiBbXCI/dHJpcGxlc0Jsb2NrXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIk9QVElPTkFMXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiTUlOVVNcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJHUkFQSFwiOiBbXCI/dHJpcGxlc0Jsb2NrXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIlNFUlZJQ0VcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJGSUxURVJcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJCSU5EXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiVkFMVUVTXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCI/dHJpcGxlc0Jsb2NrXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIlZBUjJcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJOSUxcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCIoXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiW1wiOiBbXCI/dHJpcGxlc0Jsb2NrXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJUUlVFXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiRkFMU0VcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJCTEFOS19OT0RFX0xBQkVMXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiQU5PTlwiOiBbXCI/dHJpcGxlc0Jsb2NrXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCI/dHJpcGxlc0Jsb2NrXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXCI/dHJpcGxlc0Jsb2NrXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCI/dHJpcGxlc0Jsb2NrXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCI/dHJpcGxlc0Jsb2NrXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW1wiP3RyaXBsZXNCbG9ja1wiLFwiKltncmFwaFBhdHRlcm5Ob3RUcmlwbGVzLD8uLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcIj90cmlwbGVzQmxvY2tcIixcIipbZ3JhcGhQYXR0ZXJuTm90VHJpcGxlcyw/Liw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwifVwiOiBbXCI/dHJpcGxlc0Jsb2NrXCIsXCIqW2dyYXBoUGF0dGVybk5vdFRyaXBsZXMsPy4sP3RyaXBsZXNCbG9ja11cIl19LCBcbiAgXCJncm91cE9yVW5pb25HcmFwaFBhdHRlcm5cIiA6IHtcbiAgICAgXCJ7XCI6IFtcImdyb3VwR3JhcGhQYXR0ZXJuXCIsXCIqW1VOSU9OLGdyb3VwR3JhcGhQYXR0ZXJuXVwiXX0sIFxuICBcImhhdmluZ0NsYXVzZVwiIDoge1xuICAgICBcIkhBVklOR1wiOiBbXCJIQVZJTkdcIixcIitoYXZpbmdDb25kaXRpb25cIl19LCBcbiAgXCJoYXZpbmdDb25kaXRpb25cIiA6IHtcbiAgICAgXCIoXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNUUlwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJMQU5HXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkxBTkdNQVRDSEVTXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkRBVEFUWVBFXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkJPVU5EXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIklSSVwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJVUklcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiQk5PREVcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiUkFORFwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJBQlNcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiQ0VJTFwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJGTE9PUlwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJST1VORFwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJDT05DQVRcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU1RSTEVOXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlVDQVNFXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkxDQVNFXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkVOQ09ERV9GT1JfVVJJXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkNPTlRBSU5TXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJTVFJFTkRTXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNUUkJFRk9SRVwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJTVFJBRlRFUlwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJZRUFSXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIk1PTlRIXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkRBWVwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJIT1VSU1wiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJNSU5VVEVTXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNFQ09ORFNcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiVElNRVpPTkVcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiVFpcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiTk9XXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlVVSURcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU1RSVVVJRFwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJNRDVcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU0hBMVwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJTSEEyNTZcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU0hBMzg0XCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNIQTUxMlwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJDT0FMRVNDRVwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJJRlwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJTVFJMQU5HXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNUUkRUXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNBTUVURVJNXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIklTSVJJXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIklTVVJJXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIklTQkxBTktcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiSVNMSVRFUkFMXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIklTTlVNRVJJQ1wiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiUkVQTEFDRVwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJSRUdFWFwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJFWElTVFNcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiTk9UXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiY29uc3RyYWludFwiXX0sIFxuICBcImlubGluZURhdGFcIiA6IHtcbiAgICAgXCJWQUxVRVNcIjogW1wiVkFMVUVTXCIsXCJkYXRhQmxvY2tcIl19LCBcbiAgXCJpbmxpbmVEYXRhRnVsbFwiIDoge1xuICAgICBcIk5JTFwiOiBbXCJvcihbTklMLFsgKCwqdmFyLCldXSlcIixcIntcIixcIipvcihbWyAoLCpkYXRhQmxvY2tWYWx1ZSwpXSxOSUxdKVwiLFwifVwiXSwgXG4gICAgIFwiKFwiOiBbXCJvcihbTklMLFsgKCwqdmFyLCldXSlcIixcIntcIixcIipvcihbWyAoLCpkYXRhQmxvY2tWYWx1ZSwpXSxOSUxdKVwiLFwifVwiXX0sIFxuICBcImlubGluZURhdGFPbmVWYXJcIiA6IHtcbiAgICAgXCJWQVIxXCI6IFtcInZhclwiLFwie1wiLFwiKmRhdGFCbG9ja1ZhbHVlXCIsXCJ9XCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInZhclwiLFwie1wiLFwiKmRhdGFCbG9ja1ZhbHVlXCIsXCJ9XCJdfSwgXG4gIFwiaW5zZXJ0MVwiIDoge1xuICAgICBcIkRBVEFcIjogW1wiREFUQVwiLFwicXVhZERhdGFcIl0sIFxuICAgICBcIntcIjogW1wicXVhZFBhdHRlcm5cIixcIip1c2luZ0NsYXVzZVwiLFwiV0hFUkVcIixcImdyb3VwR3JhcGhQYXR0ZXJuXCJdfSwgXG4gIFwiaW5zZXJ0Q2xhdXNlXCIgOiB7XG4gICAgIFwiSU5TRVJUXCI6IFtcIklOU0VSVFwiLFwicXVhZFBhdHRlcm5cIl19LCBcbiAgXCJpbnRlZ2VyXCIgOiB7XG4gICAgIFwiSU5URUdFUlwiOiBbXCJJTlRFR0VSXCJdfSwgXG4gIFwiaXJpUmVmXCIgOiB7XG4gICAgIFwiSVJJX1JFRlwiOiBbXCJJUklfUkVGXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJwcmVmaXhlZE5hbWVcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInByZWZpeGVkTmFtZVwiXX0sIFxuICBcImlyaVJlZk9yRnVuY3Rpb25cIiA6IHtcbiAgICAgXCJJUklfUkVGXCI6IFtcImlyaVJlZlwiLFwiP2FyZ0xpc3RcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcImlyaVJlZlwiLFwiP2FyZ0xpc3RcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcImlyaVJlZlwiLFwiP2FyZ0xpc3RcIl19LCBcbiAgXCJsaW1pdENsYXVzZVwiIDoge1xuICAgICBcIkxJTUlUXCI6IFtcIkxJTUlUXCIsXCJJTlRFR0VSXCJdfSwgXG4gIFwibGltaXRPZmZzZXRDbGF1c2VzXCIgOiB7XG4gICAgIFwiTElNSVRcIjogW1wibGltaXRDbGF1c2VcIixcIj9vZmZzZXRDbGF1c2VcIl0sIFxuICAgICBcIk9GRlNFVFwiOiBbXCJvZmZzZXRDbGF1c2VcIixcIj9saW1pdENsYXVzZVwiXX0sIFxuICBcImxvYWRcIiA6IHtcbiAgICAgXCJMT0FEXCI6IFtcIkxPQURcIixcIj9TSUxFTlRfMVwiLFwiaXJpUmVmXCIsXCI/W0lOVE8sZ3JhcGhSZWZdXCJdfSwgXG4gIFwibWludXNHcmFwaFBhdHRlcm5cIiA6IHtcbiAgICAgXCJNSU5VU1wiOiBbXCJNSU5VU1wiLFwiZ3JvdXBHcmFwaFBhdHRlcm5cIl19LCBcbiAgXCJtb2RpZnlcIiA6IHtcbiAgICAgXCJXSVRIXCI6IFtcIldJVEhcIixcImlyaVJlZlwiLFwib3IoW1tkZWxldGVDbGF1c2UsP2luc2VydENsYXVzZV0saW5zZXJ0Q2xhdXNlXSlcIixcIip1c2luZ0NsYXVzZVwiLFwiV0hFUkVcIixcImdyb3VwR3JhcGhQYXR0ZXJuXCJdfSwgXG4gIFwibW92ZVwiIDoge1xuICAgICBcIk1PVkVcIjogW1wiTU9WRVwiLFwiP1NJTEVOVF80XCIsXCJncmFwaE9yRGVmYXVsdFwiLFwiVE9cIixcImdyYXBoT3JEZWZhdWx0XCJdfSwgXG4gIFwibXVsdGlwbGljYXRpdmVFeHByZXNzaW9uXCIgOiB7XG4gICAgIFwiIVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIitcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCItXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIlZBUjJcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCIoXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiU1RSXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiTEFOR1wiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkxBTkdNQVRDSEVTXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiREFUQVRZUEVcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJCT1VORFwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIklSSVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIlVSSVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkJOT0RFXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiUkFORFwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkFCU1wiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkNFSUxcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJGTE9PUlwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIlJPVU5EXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiQ09OQ0FUXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiU1RSTEVOXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiVUNBU0VcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJMQ0FTRVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkVOQ09ERV9GT1JfVVJJXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiQ09OVEFJTlNcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJTVFJTVEFSVFNcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJTVFJFTkRTXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiU1RSQkVGT1JFXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiU1RSQUZURVJcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJZRUFSXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiTU9OVEhcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJEQVlcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJIT1VSU1wiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIk1JTlVURVNcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJTRUNPTkRTXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiVElNRVpPTkVcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJUWlwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIk5PV1wiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIlVVSURcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJTVFJVVUlEXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiTUQ1XCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiU0hBMVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIlNIQTI1NlwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIlNIQTM4NFwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIlNIQTUxMlwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkNPQUxFU0NFXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiSUZcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJTVFJMQU5HXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiU1RSRFRcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJTQU1FVEVSTVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIklTSVJJXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiSVNVUklcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJJU0JMQU5LXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiSVNMSVRFUkFMXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiSVNOVU1FUklDXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiQ09VTlRcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJTVU1cIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJNSU5cIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJNQVhcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJBVkdcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJTQU1QTEVcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJHUk9VUF9DT05DQVRcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJSRVBMQUNFXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiUkVHRVhcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJFWElTVFNcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJOT1RcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJ1bmFyeUV4cHJlc3Npb25cIixcIipvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInVuYXJ5RXhwcmVzc2lvblwiLFwiKm9yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1widW5hcnlFeHByZXNzaW9uXCIsXCIqb3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXCJdfSwgXG4gIFwibmFtZWRHcmFwaENsYXVzZVwiIDoge1xuICAgICBcIk5BTUVEXCI6IFtcIk5BTUVEXCIsXCJzb3VyY2VTZWxlY3RvclwiXX0sIFxuICBcIm5vdEV4aXN0c0Z1bmNcIiA6IHtcbiAgICAgXCJOT1RcIjogW1wiTk9UXCIsXCJFWElTVFNcIixcImdyb3VwR3JhcGhQYXR0ZXJuXCJdfSwgXG4gIFwibnVtZXJpY0V4cHJlc3Npb25cIiA6IHtcbiAgICAgXCIhXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiK1wiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIi1cIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIihcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJMQU5HXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTEFOR01BVENIRVNcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJEQVRBVFlQRVwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkJPVU5EXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSVJJXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVVJJXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQk5PREVcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJSQU5EXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQUJTXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQ0VJTFwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkZMT09SXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiUk9VTkRcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJDT05DQVRcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJMRU5cIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJVQ0FTRVwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkxDQVNFXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRU5DT0RFX0ZPUl9VUklcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJDT05UQUlOU1wiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUlNUQVJUU1wiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUkVORFNcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJCRUZPUkVcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJBRlRFUlwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIllFQVJcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJNT05USFwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRBWVwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkhPVVJTXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTUlOVVRFU1wiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNFQ09ORFNcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJUSU1FWk9ORVwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlRaXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTk9XXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVVVJRFwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUlVVSURcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJNRDVcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTSEExXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0hBMjU2XCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0hBMzg0XCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0hBNTEyXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQ09BTEVTQ0VcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJRlwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUkxBTkdcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJEVFwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNBTUVURVJNXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSVNJUklcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU1VSSVwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIklTQkxBTktcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU0xJVEVSQUxcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU05VTUVSSUNcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJUUlVFXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRkFMU0VcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJDT1VOVFwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNVTVwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIk1JTlwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIk1BWFwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkFWR1wiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNBTVBMRVwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkdST1VQX0NPTkNBVFwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNVQlNUUlwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlJFUExBQ0VcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJSRUdFWFwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkVYSVNUU1wiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIk5PVFwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl0sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcImFkZGl0aXZlRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiYWRkaXRpdmVFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJhZGRpdGl2ZUV4cHJlc3Npb25cIl19LCBcbiAgXCJudW1lcmljTGl0ZXJhbFwiIDoge1xuICAgICBcIklOVEVHRVJcIjogW1wibnVtZXJpY0xpdGVyYWxVbnNpZ25lZFwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJudW1lcmljTGl0ZXJhbFVuc2lnbmVkXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wibnVtZXJpY0xpdGVyYWxVbnNpZ25lZFwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbFBvc2l0aXZlXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcIm51bWVyaWNMaXRlcmFsUG9zaXRpdmVcIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbFBvc2l0aXZlXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcIm51bWVyaWNMaXRlcmFsTmVnYXRpdmVcIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wibnVtZXJpY0xpdGVyYWxOZWdhdGl2ZVwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcIm51bWVyaWNMaXRlcmFsTmVnYXRpdmVcIl19LCBcbiAgXCJudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXCIgOiB7XG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJJTlRFR0VSX05FR0FUSVZFXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcIkRFQ0lNQUxfTkVHQVRJVkVcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJET1VCTEVfTkVHQVRJVkVcIl19LCBcbiAgXCJudW1lcmljTGl0ZXJhbFBvc2l0aXZlXCIgOiB7XG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJJTlRFR0VSX1BPU0lUSVZFXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcIkRFQ0lNQUxfUE9TSVRJVkVcIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCJET1VCTEVfUE9TSVRJVkVcIl19LCBcbiAgXCJudW1lcmljTGl0ZXJhbFVuc2lnbmVkXCIgOiB7XG4gICAgIFwiSU5URUdFUlwiOiBbXCJJTlRFR0VSXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcIkRFQ0lNQUxcIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJET1VCTEVcIl19LCBcbiAgXCJvYmplY3RcIiA6IHtcbiAgICAgXCIoXCI6IFtcImdyYXBoTm9kZVwiXSwgXG4gICAgIFwiW1wiOiBbXCJncmFwaE5vZGVcIl0sIFxuICAgICBcIlZBUjFcIjogW1wiZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcImdyYXBoTm9kZVwiXSwgXG4gICAgIFwiTklMXCI6IFtcImdyYXBoTm9kZVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJncmFwaE5vZGVcIl0sIFxuICAgICBcIlRSVUVcIjogW1wiZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJncmFwaE5vZGVcIl0sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW1wiZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJBTk9OXCI6IFtcImdyYXBoTm9kZVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJncmFwaE5vZGVcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJncmFwaE5vZGVcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJncmFwaE5vZGVcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcImdyYXBoTm9kZVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1wiZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcImdyYXBoTm9kZVwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJncmFwaE5vZGVcIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJncmFwaE5vZGVcIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wiZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcImdyYXBoTm9kZVwiXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtcImdyYXBoTm9kZVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJncmFwaE5vZGVcIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wiZ3JhcGhOb2RlXCJdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW1wiZ3JhcGhOb2RlXCJdfSwgXG4gIFwib2JqZWN0TGlzdFwiIDoge1xuICAgICBcIihcIjogW1wib2JqZWN0XCIsXCIqWywsb2JqZWN0XVwiXSwgXG4gICAgIFwiW1wiOiBbXCJvYmplY3RcIixcIipbLCxvYmplY3RdXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcIm9iamVjdFwiLFwiKlssLG9iamVjdF1cIl0sIFxuICAgICBcIlZBUjJcIjogW1wib2JqZWN0XCIsXCIqWywsb2JqZWN0XVwiXSwgXG4gICAgIFwiTklMXCI6IFtcIm9iamVjdFwiLFwiKlssLG9iamVjdF1cIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wib2JqZWN0XCIsXCIqWywsb2JqZWN0XVwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJvYmplY3RcIixcIipbLCxvYmplY3RdXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJvYmplY3RcIixcIipbLCxvYmplY3RdXCJdLCBcbiAgICAgXCJCTEFOS19OT0RFX0xBQkVMXCI6IFtcIm9iamVjdFwiLFwiKlssLG9iamVjdF1cIl0sIFxuICAgICBcIkFOT05cIjogW1wib2JqZWN0XCIsXCIqWywsb2JqZWN0XVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wib2JqZWN0XCIsXCIqWywsb2JqZWN0XVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wib2JqZWN0XCIsXCIqWywsb2JqZWN0XVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcIm9iamVjdFwiLFwiKlssLG9iamVjdF1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJvYmplY3RcIixcIipbLCxvYmplY3RdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJvYmplY3RcIixcIipbLCxvYmplY3RdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJvYmplY3RcIixcIipbLCxvYmplY3RdXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcIm9iamVjdFwiLFwiKlssLG9iamVjdF1cIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1wib2JqZWN0XCIsXCIqWywsb2JqZWN0XVwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcIm9iamVjdFwiLFwiKlssLG9iamVjdF1cIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wib2JqZWN0XCIsXCIqWywsb2JqZWN0XVwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJvYmplY3RcIixcIipbLCxvYmplY3RdXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wib2JqZWN0XCIsXCIqWywsb2JqZWN0XVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJvYmplY3RcIixcIipbLCxvYmplY3RdXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcIm9iamVjdFwiLFwiKlssLG9iamVjdF1cIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJvYmplY3RcIixcIipbLCxvYmplY3RdXCJdfSwgXG4gIFwib2JqZWN0TGlzdFBhdGhcIiA6IHtcbiAgICAgXCIoXCI6IFtcIm9iamVjdFBhdGhcIixcIipbLCxvYmplY3RQYXRoXVwiXSwgXG4gICAgIFwiW1wiOiBbXCJvYmplY3RQYXRoXCIsXCIqWywsb2JqZWN0UGF0aF1cIl0sIFxuICAgICBcIlZBUjFcIjogW1wib2JqZWN0UGF0aFwiLFwiKlssLG9iamVjdFBhdGhdXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcIm9iamVjdFBhdGhcIixcIipbLCxvYmplY3RQYXRoXVwiXSwgXG4gICAgIFwiTklMXCI6IFtcIm9iamVjdFBhdGhcIixcIipbLCxvYmplY3RQYXRoXVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJvYmplY3RQYXRoXCIsXCIqWywsb2JqZWN0UGF0aF1cIl0sIFxuICAgICBcIlRSVUVcIjogW1wib2JqZWN0UGF0aFwiLFwiKlssLG9iamVjdFBhdGhdXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJvYmplY3RQYXRoXCIsXCIqWywsb2JqZWN0UGF0aF1cIl0sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW1wib2JqZWN0UGF0aFwiLFwiKlssLG9iamVjdFBhdGhdXCJdLCBcbiAgICAgXCJBTk9OXCI6IFtcIm9iamVjdFBhdGhcIixcIipbLCxvYmplY3RQYXRoXVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wib2JqZWN0UGF0aFwiLFwiKlssLG9iamVjdFBhdGhdXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJvYmplY3RQYXRoXCIsXCIqWywsb2JqZWN0UGF0aF1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJvYmplY3RQYXRoXCIsXCIqWywsb2JqZWN0UGF0aF1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJvYmplY3RQYXRoXCIsXCIqWywsb2JqZWN0UGF0aF1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcIm9iamVjdFBhdGhcIixcIipbLCxvYmplY3RQYXRoXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1wib2JqZWN0UGF0aFwiLFwiKlssLG9iamVjdFBhdGhdXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcIm9iamVjdFBhdGhcIixcIipbLCxvYmplY3RQYXRoXVwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJvYmplY3RQYXRoXCIsXCIqWywsb2JqZWN0UGF0aF1cIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJvYmplY3RQYXRoXCIsXCIqWywsb2JqZWN0UGF0aF1cIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wib2JqZWN0UGF0aFwiLFwiKlssLG9iamVjdFBhdGhdXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcIm9iamVjdFBhdGhcIixcIipbLCxvYmplY3RQYXRoXVwiXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtcIm9iamVjdFBhdGhcIixcIipbLCxvYmplY3RQYXRoXVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJvYmplY3RQYXRoXCIsXCIqWywsb2JqZWN0UGF0aF1cIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wib2JqZWN0UGF0aFwiLFwiKlssLG9iamVjdFBhdGhdXCJdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW1wib2JqZWN0UGF0aFwiLFwiKlssLG9iamVjdFBhdGhdXCJdfSwgXG4gIFwib2JqZWN0UGF0aFwiIDoge1xuICAgICBcIihcIjogW1wiZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiW1wiOiBbXCJncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcImdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIlZBUjJcIjogW1wiZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiTklMXCI6IFtcImdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wiZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJCTEFOS19OT0RFX0xBQkVMXCI6IFtcImdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIkFOT05cIjogW1wiZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcImdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcImdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1wiZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcImdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wiZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wiZ3JhcGhOb2RlUGF0aFwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJncmFwaE5vZGVQYXRoXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcImdyYXBoTm9kZVBhdGhcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJncmFwaE5vZGVQYXRoXCJdfSwgXG4gIFwib2Zmc2V0Q2xhdXNlXCIgOiB7XG4gICAgIFwiT0ZGU0VUXCI6IFtcIk9GRlNFVFwiLFwiSU5URUdFUlwiXX0sIFxuICBcIm9wdGlvbmFsR3JhcGhQYXR0ZXJuXCIgOiB7XG4gICAgIFwiT1BUSU9OQUxcIjogW1wiT1BUSU9OQUxcIixcImdyb3VwR3JhcGhQYXR0ZXJuXCJdfSwgXG4gIFwib3IoWyosZXhwcmVzc2lvbl0pXCIgOiB7XG4gICAgIFwiKlwiOiBbXCIqXCJdLCBcbiAgICAgXCIhXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIitcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiLVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIlZBUjJcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiKFwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTEFOR1wiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJMQU5HTUFUQ0hFU1wiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJEQVRBVFlQRVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJCT1VORFwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJJUklcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVVJJXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIkJOT0RFXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIlJBTkRcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQUJTXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIkNFSUxcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRkxPT1JcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiUk9VTkRcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQ09OQ0FUXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUkxFTlwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJVQ0FTRVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJMQ0FTRVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJFTkNPREVfRk9SX1VSSVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJDT05UQUlOU1wiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJTVEFSVFNcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSRU5EU1wiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJCRUZPUkVcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSQUZURVJcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiWUVBUlwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJNT05USFwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJEQVlcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSE9VUlNcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTUlOVVRFU1wiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTRUNPTkRTXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIlRJTUVaT05FXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIlRaXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIk5PV1wiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJVVUlEXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUlVVSURcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTUQ1XCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNIQTFcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0hBMjU2XCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNIQTM4NFwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTSEE1MTJcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQ09BTEVTQ0VcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSUZcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSTEFOR1wiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJEVFwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTQU1FVEVSTVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU0lSSVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU1VSSVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU0JMQU5LXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIklTTElURVJBTFwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU05VTUVSSUNcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJDT1VOVFwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVU1cIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTUlOXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIk1BWFwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJBVkdcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0FNUExFXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIkdST1VQX0NPTkNBVFwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiUkVQTEFDRVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJSRUdFWFwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJFWElTVFNcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTk9UXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wiZXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcImV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJleHByZXNzaW9uXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJleHByZXNzaW9uXCJdfSwgXG4gIFwib3IoWytvcihbdmFyLFsgKCxleHByZXNzaW9uLEFTLHZhciwpXV0pLCpdKVwiIDoge1xuICAgICBcIihcIjogW1wiK29yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIl0sIFxuICAgICBcIlZBUjFcIjogW1wiK29yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIl0sIFxuICAgICBcIlZBUjJcIjogW1wiK29yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIl0sIFxuICAgICBcIipcIjogW1wiKlwiXX0sIFxuICBcIm9yKFsrdmFyT3JJUklyZWYsKl0pXCIgOiB7XG4gICAgIFwiVkFSMVwiOiBbXCIrdmFyT3JJUklyZWZcIl0sIFxuICAgICBcIlZBUjJcIjogW1wiK3Zhck9ySVJJcmVmXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcIit2YXJPcklSSXJlZlwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiK3Zhck9ySVJJcmVmXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCIrdmFyT3JJUklyZWZcIl0sIFxuICAgICBcIipcIjogW1wiKlwiXX0sIFxuICBcIm9yKFtBU0MsREVTQ10pXCIgOiB7XG4gICAgIFwiQVNDXCI6IFtcIkFTQ1wiXSwgXG4gICAgIFwiREVTQ1wiOiBbXCJERVNDXCJdfSwgXG4gIFwib3IoW0RJU1RJTkNULFJFRFVDRURdKVwiIDoge1xuICAgICBcIkRJU1RJTkNUXCI6IFtcIkRJU1RJTkNUXCJdLCBcbiAgICAgXCJSRURVQ0VEXCI6IFtcIlJFRFVDRURcIl19LCBcbiAgXCJvcihbTEFOR1RBRyxbXl4saXJpUmVmXV0pXCIgOiB7XG4gICAgIFwiTEFOR1RBR1wiOiBbXCJMQU5HVEFHXCJdLCBcbiAgICAgXCJeXlwiOiBbXCJbXl4saXJpUmVmXVwiXX0sIFxuICBcIm9yKFtOSUwsWyAoLCp2YXIsKV1dKVwiIDoge1xuICAgICBcIk5JTFwiOiBbXCJOSUxcIl0sIFxuICAgICBcIihcIjogW1wiWyAoLCp2YXIsKV1cIl19LCBcbiAgXCJvcihbWyAoLCpkYXRhQmxvY2tWYWx1ZSwpXSxOSUxdKVwiIDoge1xuICAgICBcIihcIjogW1wiWyAoLCpkYXRhQmxvY2tWYWx1ZSwpXVwiXSwgXG4gICAgIFwiTklMXCI6IFtcIk5JTFwiXX0sIFxuICBcIm9yKFtbICgsZXhwcmVzc2lvbiwpXSxOSUxdKVwiIDoge1xuICAgICBcIihcIjogW1wiWyAoLGV4cHJlc3Npb24sKV1cIl0sIFxuICAgICBcIk5JTFwiOiBbXCJOSUxcIl19LCBcbiAgXCJvcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSlcIiA6IHtcbiAgICAgXCIqXCI6IFtcIlsqLHVuYXJ5RXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIi9cIjogW1wiWy8sdW5hcnlFeHByZXNzaW9uXVwiXX0sIFxuICBcIm9yKFtbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dLFstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl0sW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXV0pXCIgOiB7XG4gICAgIFwiK1wiOiBbXCJbKyxtdWx0aXBsaWNhdGl2ZUV4cHJlc3Npb25dXCJdLCBcbiAgICAgXCItXCI6IFtcIlstLG11bHRpcGxpY2F0aXZlRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wiW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXVwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wiW29yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKSw/b3IoW1sqLHVuYXJ5RXhwcmVzc2lvbl0sWy8sdW5hcnlFeHByZXNzaW9uXV0pXVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcIltvcihbbnVtZXJpY0xpdGVyYWxQb3NpdGl2ZSxudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXSksP29yKFtbKix1bmFyeUV4cHJlc3Npb25dLFsvLHVuYXJ5RXhwcmVzc2lvbl1dKV1cIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJbb3IoW251bWVyaWNMaXRlcmFsUG9zaXRpdmUsbnVtZXJpY0xpdGVyYWxOZWdhdGl2ZV0pLD9vcihbWyosdW5hcnlFeHByZXNzaW9uXSxbLyx1bmFyeUV4cHJlc3Npb25dXSldXCJdfSwgXG4gIFwib3IoW1ssLG9yKFt9LFtpbnRlZ2VyLH1dXSldLH1dKVwiIDoge1xuICAgICBcIixcIjogW1wiWywsb3IoW30sW2ludGVnZXIsfV1dKV1cIl0sIFxuICAgICBcIn1cIjogW1wifVwiXX0sIFxuICBcIm9yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIiA6IHtcbiAgICAgXCI9XCI6IFtcIls9LG51bWVyaWNFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiIT1cIjogW1wiWyE9LG51bWVyaWNFeHByZXNzaW9uXVwiXSwgXG4gICAgIFwiPFwiOiBbXCJbPCxudW1lcmljRXhwcmVzc2lvbl1cIl0sIFxuICAgICBcIj5cIjogW1wiWz4sbnVtZXJpY0V4cHJlc3Npb25dXCJdLCBcbiAgICAgXCI8PVwiOiBbXCJbPD0sbnVtZXJpY0V4cHJlc3Npb25dXCJdLCBcbiAgICAgXCI+PVwiOiBbXCJbPj0sbnVtZXJpY0V4cHJlc3Npb25dXCJdLCBcbiAgICAgXCJJTlwiOiBbXCJbSU4sZXhwcmVzc2lvbkxpc3RdXCJdLCBcbiAgICAgXCJOT1RcIjogW1wiW05PVCxJTixleHByZXNzaW9uTGlzdF1cIl19LCBcbiAgXCJvcihbW2NvbnN0cnVjdFRlbXBsYXRlLCpkYXRhc2V0Q2xhdXNlLHdoZXJlQ2xhdXNlLHNvbHV0aW9uTW9kaWZpZXJdLFsqZGF0YXNldENsYXVzZSxXSEVSRSx7LD90cmlwbGVzVGVtcGxhdGUsfSxzb2x1dGlvbk1vZGlmaWVyXV0pXCIgOiB7XG4gICAgIFwie1wiOiBbXCJbY29uc3RydWN0VGVtcGxhdGUsKmRhdGFzZXRDbGF1c2Usd2hlcmVDbGF1c2Usc29sdXRpb25Nb2RpZmllcl1cIl0sIFxuICAgICBcIldIRVJFXCI6IFtcIlsqZGF0YXNldENsYXVzZSxXSEVSRSx7LD90cmlwbGVzVGVtcGxhdGUsfSxzb2x1dGlvbk1vZGlmaWVyXVwiXSwgXG4gICAgIFwiRlJPTVwiOiBbXCJbKmRhdGFzZXRDbGF1c2UsV0hFUkUseyw/dHJpcGxlc1RlbXBsYXRlLH0sc29sdXRpb25Nb2RpZmllcl1cIl19LCBcbiAgXCJvcihbW2RlbGV0ZUNsYXVzZSw/aW5zZXJ0Q2xhdXNlXSxpbnNlcnRDbGF1c2VdKVwiIDoge1xuICAgICBcIkRFTEVURVwiOiBbXCJbZGVsZXRlQ2xhdXNlLD9pbnNlcnRDbGF1c2VdXCJdLCBcbiAgICAgXCJJTlNFUlRcIjogW1wiaW5zZXJ0Q2xhdXNlXCJdfSwgXG4gIFwib3IoW1tpbnRlZ2VyLG9yKFtbLCxvcihbfSxbaW50ZWdlcix9XV0pXSx9XSldLFssLGludGVnZXIsfV1dKVwiIDoge1xuICAgICBcIklOVEVHRVJcIjogW1wiW2ludGVnZXIsb3IoW1ssLG9yKFt9LFtpbnRlZ2VyLH1dXSldLH1dKV1cIl0sIFxuICAgICBcIixcIjogW1wiWywsaW50ZWdlcix9XVwiXX0sIFxuICBcIm9yKFtiYXNlRGVjbCxwcmVmaXhEZWNsXSlcIiA6IHtcbiAgICAgXCJCQVNFXCI6IFtcImJhc2VEZWNsXCJdLCBcbiAgICAgXCJQUkVGSVhcIjogW1wicHJlZml4RGVjbFwiXX0sIFxuICBcIm9yKFtkZWZhdWx0R3JhcGhDbGF1c2UsbmFtZWRHcmFwaENsYXVzZV0pXCIgOiB7XG4gICAgIFwiSVJJX1JFRlwiOiBbXCJkZWZhdWx0R3JhcGhDbGF1c2VcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcImRlZmF1bHRHcmFwaENsYXVzZVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wiZGVmYXVsdEdyYXBoQ2xhdXNlXCJdLCBcbiAgICAgXCJOQU1FRFwiOiBbXCJuYW1lZEdyYXBoQ2xhdXNlXCJdfSwgXG4gIFwib3IoW2lubGluZURhdGFPbmVWYXIsaW5saW5lRGF0YUZ1bGxdKVwiIDoge1xuICAgICBcIlZBUjFcIjogW1wiaW5saW5lRGF0YU9uZVZhclwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJpbmxpbmVEYXRhT25lVmFyXCJdLCBcbiAgICAgXCJOSUxcIjogW1wiaW5saW5lRGF0YUZ1bGxcIl0sIFxuICAgICBcIihcIjogW1wiaW5saW5lRGF0YUZ1bGxcIl19LCBcbiAgXCJvcihbaXJpUmVmLFtOQU1FRCxpcmlSZWZdXSlcIiA6IHtcbiAgICAgXCJJUklfUkVGXCI6IFtcImlyaVJlZlwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiaXJpUmVmXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJpcmlSZWZcIl0sIFxuICAgICBcIk5BTUVEXCI6IFtcIltOQU1FRCxpcmlSZWZdXCJdfSwgXG4gIFwib3IoW2lyaVJlZixhXSlcIiA6IHtcbiAgICAgXCJJUklfUkVGXCI6IFtcImlyaVJlZlwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiaXJpUmVmXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJpcmlSZWZcIl0sIFxuICAgICBcImFcIjogW1wiYVwiXX0sIFxuICBcIm9yKFtudW1lcmljTGl0ZXJhbFBvc2l0aXZlLG51bWVyaWNMaXRlcmFsTmVnYXRpdmVdKVwiIDoge1xuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wibnVtZXJpY0xpdGVyYWxQb3NpdGl2ZVwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbFBvc2l0aXZlXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wibnVtZXJpY0xpdGVyYWxQb3NpdGl2ZVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcIm51bWVyaWNMaXRlcmFsTmVnYXRpdmVcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbE5lZ2F0aXZlXCJdfSwgXG4gIFwib3IoW3F1ZXJ5QWxsLHVwZGF0ZUFsbF0pXCIgOiB7XG4gICAgIFwiQ09OU1RSVUNUXCI6IFtcInF1ZXJ5QWxsXCJdLCBcbiAgICAgXCJERVNDUklCRVwiOiBbXCJxdWVyeUFsbFwiXSwgXG4gICAgIFwiQVNLXCI6IFtcInF1ZXJ5QWxsXCJdLCBcbiAgICAgXCJTRUxFQ1RcIjogW1wicXVlcnlBbGxcIl0sIFxuICAgICBcIklOU0VSVFwiOiBbXCJ1cGRhdGVBbGxcIl0sIFxuICAgICBcIkRFTEVURVwiOiBbXCJ1cGRhdGVBbGxcIl0sIFxuICAgICBcIkxPQURcIjogW1widXBkYXRlQWxsXCJdLCBcbiAgICAgXCJDTEVBUlwiOiBbXCJ1cGRhdGVBbGxcIl0sIFxuICAgICBcIkRST1BcIjogW1widXBkYXRlQWxsXCJdLCBcbiAgICAgXCJBRERcIjogW1widXBkYXRlQWxsXCJdLCBcbiAgICAgXCJNT1ZFXCI6IFtcInVwZGF0ZUFsbFwiXSwgXG4gICAgIFwiQ09QWVwiOiBbXCJ1cGRhdGVBbGxcIl0sIFxuICAgICBcIkNSRUFURVwiOiBbXCJ1cGRhdGVBbGxcIl0sIFxuICAgICBcIldJVEhcIjogW1widXBkYXRlQWxsXCJdLCBcbiAgICAgXCIkXCI6IFtcInVwZGF0ZUFsbFwiXX0sIFxuICBcIm9yKFtzZWxlY3RRdWVyeSxjb25zdHJ1Y3RRdWVyeSxkZXNjcmliZVF1ZXJ5LGFza1F1ZXJ5XSlcIiA6IHtcbiAgICAgXCJTRUxFQ1RcIjogW1wic2VsZWN0UXVlcnlcIl0sIFxuICAgICBcIkNPTlNUUlVDVFwiOiBbXCJjb25zdHJ1Y3RRdWVyeVwiXSwgXG4gICAgIFwiREVTQ1JJQkVcIjogW1wiZGVzY3JpYmVRdWVyeVwiXSwgXG4gICAgIFwiQVNLXCI6IFtcImFza1F1ZXJ5XCJdfSwgXG4gIFwib3IoW3N1YlNlbGVjdCxncm91cEdyYXBoUGF0dGVyblN1Yl0pXCIgOiB7XG4gICAgIFwiU0VMRUNUXCI6IFtcInN1YlNlbGVjdFwiXSwgXG4gICAgIFwie1wiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiT1BUSU9OQUxcIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIk1JTlVTXCI6IFtcImdyb3VwR3JhcGhQYXR0ZXJuU3ViXCJdLCBcbiAgICAgXCJHUkFQSFwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiU0VSVklDRVwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiRklMVEVSXCI6IFtcImdyb3VwR3JhcGhQYXR0ZXJuU3ViXCJdLCBcbiAgICAgXCJCSU5EXCI6IFtcImdyb3VwR3JhcGhQYXR0ZXJuU3ViXCJdLCBcbiAgICAgXCJWQUxVRVNcIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIlZBUjFcIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIlZBUjJcIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIk5JTFwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiKFwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiW1wiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiRkFMU0VcIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIkFOT05cIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcImdyb3VwR3JhcGhQYXR0ZXJuU3ViXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcImdyb3VwR3JhcGhQYXR0ZXJuU3ViXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcImdyb3VwR3JhcGhQYXR0ZXJuU3ViXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcImdyb3VwR3JhcGhQYXR0ZXJuU3ViXCJdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtcImdyb3VwR3JhcGhQYXR0ZXJuU3ViXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcImdyb3VwR3JhcGhQYXR0ZXJuU3ViXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wiZ3JvdXBHcmFwaFBhdHRlcm5TdWJcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXSwgXG4gICAgIFwifVwiOiBbXCJncm91cEdyYXBoUGF0dGVyblN1YlwiXX0sIFxuICBcIm9yKFt2YXIsWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXSlcIiA6IHtcbiAgICAgXCJWQVIxXCI6IFtcInZhclwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJ2YXJcIl0sIFxuICAgICBcIihcIjogW1wiWyAoLGV4cHJlc3Npb24sQVMsdmFyLCldXCJdfSwgXG4gIFwib3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKVwiIDoge1xuICAgICBcIl5cIjogW1widmVyYlBhdGhcIl0sIFxuICAgICBcImFcIjogW1widmVyYlBhdGhcIl0sIFxuICAgICBcIiFcIjogW1widmVyYlBhdGhcIl0sIFxuICAgICBcIihcIjogW1widmVyYlBhdGhcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1widmVyYlBhdGhcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInZlcmJQYXRoXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJ2ZXJiUGF0aFwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJ2ZXJiU2ltcGxlXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInZlcmJTaW1wbGVcIl19LCBcbiAgXCJvcihbfSxbaW50ZWdlcix9XV0pXCIgOiB7XG4gICAgIFwifVwiOiBbXCJ9XCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcIltpbnRlZ2VyLH1dXCJdfSwgXG4gIFwib3JkZXJDbGF1c2VcIiA6IHtcbiAgICAgXCJPUkRFUlwiOiBbXCJPUkRFUlwiLFwiQllcIixcIitvcmRlckNvbmRpdGlvblwiXX0sIFxuICBcIm9yZGVyQ29uZGl0aW9uXCIgOiB7XG4gICAgIFwiQVNDXCI6IFtcIm9yKFtBU0MsREVTQ10pXCIsXCJicmFja2V0dGVkRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiREVTQ1wiOiBbXCJvcihbQVNDLERFU0NdKVwiLFwiYnJhY2tldHRlZEV4cHJlc3Npb25cIl0sIFxuICAgICBcIihcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU1RSXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkxBTkdcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiTEFOR01BVENIRVNcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiREFUQVRZUEVcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiQk9VTkRcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiSVJJXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlVSSVwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJCTk9ERVwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJSQU5EXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkFCU1wiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJDRUlMXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkZMT09SXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlJPVU5EXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkNPTkNBVFwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJTVFJMRU5cIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiVUNBU0VcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiTENBU0VcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiRU5DT0RFX0ZPUl9VUklcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiQ09OVEFJTlNcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU1RSU1RBUlRTXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNUUkVORFNcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU1RSQkVGT1JFXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNUUkFGVEVSXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIllFQVJcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiTU9OVEhcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiREFZXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkhPVVJTXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIk1JTlVURVNcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU0VDT05EU1wiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJUSU1FWk9ORVwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJUWlwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJOT1dcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiVVVJRFwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJTVFJVVUlEXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIk1ENVwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJTSEExXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNIQTI1NlwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJTSEEzODRcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU0hBNTEyXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkNPQUxFU0NFXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIklGXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNUUkxBTkdcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU1RSRFRcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiU0FNRVRFUk1cIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiSVNJUklcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiSVNVUklcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiSVNCTEFOS1wiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJJU0xJVEVSQUxcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiSVNOVU1FUklDXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlNVQlNUUlwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJSRVBMQUNFXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIlJFR0VYXCI6IFtcImNvbnN0cmFpbnRcIl0sIFxuICAgICBcIkVYSVNUU1wiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJOT1RcIjogW1wiY29uc3RyYWludFwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJjb25zdHJhaW50XCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcInZhclwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJ2YXJcIl19LCBcbiAgXCJwYXRoXCIgOiB7XG4gICAgIFwiXlwiOiBbXCJwYXRoQWx0ZXJuYXRpdmVcIl0sIFxuICAgICBcImFcIjogW1wicGF0aEFsdGVybmF0aXZlXCJdLCBcbiAgICAgXCIhXCI6IFtcInBhdGhBbHRlcm5hdGl2ZVwiXSwgXG4gICAgIFwiKFwiOiBbXCJwYXRoQWx0ZXJuYXRpdmVcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wicGF0aEFsdGVybmF0aXZlXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJwYXRoQWx0ZXJuYXRpdmVcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInBhdGhBbHRlcm5hdGl2ZVwiXX0sIFxuICBcInBhdGhBbHRlcm5hdGl2ZVwiIDoge1xuICAgICBcIl5cIjogW1wicGF0aFNlcXVlbmNlXCIsXCIqW3wscGF0aFNlcXVlbmNlXVwiXSwgXG4gICAgIFwiYVwiOiBbXCJwYXRoU2VxdWVuY2VcIixcIipbfCxwYXRoU2VxdWVuY2VdXCJdLCBcbiAgICAgXCIhXCI6IFtcInBhdGhTZXF1ZW5jZVwiLFwiKlt8LHBhdGhTZXF1ZW5jZV1cIl0sIFxuICAgICBcIihcIjogW1wicGF0aFNlcXVlbmNlXCIsXCIqW3wscGF0aFNlcXVlbmNlXVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJwYXRoU2VxdWVuY2VcIixcIipbfCxwYXRoU2VxdWVuY2VdXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJwYXRoU2VxdWVuY2VcIixcIipbfCxwYXRoU2VxdWVuY2VdXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJwYXRoU2VxdWVuY2VcIixcIipbfCxwYXRoU2VxdWVuY2VdXCJdfSwgXG4gIFwicGF0aEVsdFwiIDoge1xuICAgICBcImFcIjogW1wicGF0aFByaW1hcnlcIixcIj9wYXRoTW9kXCJdLCBcbiAgICAgXCIhXCI6IFtcInBhdGhQcmltYXJ5XCIsXCI/cGF0aE1vZFwiXSwgXG4gICAgIFwiKFwiOiBbXCJwYXRoUHJpbWFyeVwiLFwiP3BhdGhNb2RcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wicGF0aFByaW1hcnlcIixcIj9wYXRoTW9kXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJwYXRoUHJpbWFyeVwiLFwiP3BhdGhNb2RcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInBhdGhQcmltYXJ5XCIsXCI/cGF0aE1vZFwiXX0sIFxuICBcInBhdGhFbHRPckludmVyc2VcIiA6IHtcbiAgICAgXCJhXCI6IFtcInBhdGhFbHRcIl0sIFxuICAgICBcIiFcIjogW1wicGF0aEVsdFwiXSwgXG4gICAgIFwiKFwiOiBbXCJwYXRoRWx0XCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcInBhdGhFbHRcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInBhdGhFbHRcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInBhdGhFbHRcIl0sIFxuICAgICBcIl5cIjogW1wiXlwiLFwicGF0aEVsdFwiXX0sIFxuICBcInBhdGhNb2RcIiA6IHtcbiAgICAgXCIqXCI6IFtcIipcIl0sIFxuICAgICBcIj9cIjogW1wiP1wiXSwgXG4gICAgIFwiK1wiOiBbXCIrXCJdLCBcbiAgICAgXCJ7XCI6IFtcIntcIixcIm9yKFtbaW50ZWdlcixvcihbWywsb3IoW30sW2ludGVnZXIsfV1dKV0sfV0pXSxbLCxpbnRlZ2VyLH1dXSlcIl19LCBcbiAgXCJwYXRoTmVnYXRlZFByb3BlcnR5U2V0XCIgOiB7XG4gICAgIFwiYVwiOiBbXCJwYXRoT25lSW5Qcm9wZXJ0eVNldFwiXSwgXG4gICAgIFwiXlwiOiBbXCJwYXRoT25lSW5Qcm9wZXJ0eVNldFwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJwYXRoT25lSW5Qcm9wZXJ0eVNldFwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wicGF0aE9uZUluUHJvcGVydHlTZXRcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInBhdGhPbmVJblByb3BlcnR5U2V0XCJdLCBcbiAgICAgXCIoXCI6IFtcIihcIixcIj9bcGF0aE9uZUluUHJvcGVydHlTZXQsKlt8LHBhdGhPbmVJblByb3BlcnR5U2V0XV1cIixcIilcIl19LCBcbiAgXCJwYXRoT25lSW5Qcm9wZXJ0eVNldFwiIDoge1xuICAgICBcIklSSV9SRUZcIjogW1wiaXJpUmVmXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJpcmlSZWZcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcImlyaVJlZlwiXSwgXG4gICAgIFwiYVwiOiBbXCJhXCJdLCBcbiAgICAgXCJeXCI6IFtcIl5cIixcIm9yKFtpcmlSZWYsYV0pXCJdfSwgXG4gIFwicGF0aFByaW1hcnlcIiA6IHtcbiAgICAgXCJJUklfUkVGXCI6IFtcInN0b3JlUHJvcGVydHlcIixcImlyaVJlZlwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wic3RvcmVQcm9wZXJ0eVwiLFwiaXJpUmVmXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJzdG9yZVByb3BlcnR5XCIsXCJpcmlSZWZcIl0sIFxuICAgICBcImFcIjogW1wic3RvcmVQcm9wZXJ0eVwiLFwiYVwiXSwgXG4gICAgIFwiIVwiOiBbXCIhXCIsXCJwYXRoTmVnYXRlZFByb3BlcnR5U2V0XCJdLCBcbiAgICAgXCIoXCI6IFtcIihcIixcInBhdGhcIixcIilcIl19LCBcbiAgXCJwYXRoU2VxdWVuY2VcIiA6IHtcbiAgICAgXCJeXCI6IFtcInBhdGhFbHRPckludmVyc2VcIixcIipbLyxwYXRoRWx0T3JJbnZlcnNlXVwiXSwgXG4gICAgIFwiYVwiOiBbXCJwYXRoRWx0T3JJbnZlcnNlXCIsXCIqWy8scGF0aEVsdE9ySW52ZXJzZV1cIl0sIFxuICAgICBcIiFcIjogW1wicGF0aEVsdE9ySW52ZXJzZVwiLFwiKlsvLHBhdGhFbHRPckludmVyc2VdXCJdLCBcbiAgICAgXCIoXCI6IFtcInBhdGhFbHRPckludmVyc2VcIixcIipbLyxwYXRoRWx0T3JJbnZlcnNlXVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJwYXRoRWx0T3JJbnZlcnNlXCIsXCIqWy8scGF0aEVsdE9ySW52ZXJzZV1cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInBhdGhFbHRPckludmVyc2VcIixcIipbLyxwYXRoRWx0T3JJbnZlcnNlXVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wicGF0aEVsdE9ySW52ZXJzZVwiLFwiKlsvLHBhdGhFbHRPckludmVyc2VdXCJdfSwgXG4gIFwicHJlZml4RGVjbFwiIDoge1xuICAgICBcIlBSRUZJWFwiOiBbXCJQUkVGSVhcIixcIlBOQU1FX05TXCIsXCJJUklfUkVGXCJdfSwgXG4gIFwicHJlZml4ZWROYW1lXCIgOiB7XG4gICAgIFwiUE5BTUVfTE5cIjogW1wiUE5BTUVfTE5cIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcIlBOQU1FX05TXCJdfSwgXG4gIFwicHJpbWFyeUV4cHJlc3Npb25cIiA6IHtcbiAgICAgXCIoXCI6IFtcImJyYWNrZXR0ZWRFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkxBTkdcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkxBTkdNQVRDSEVTXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJEQVRBVFlQRVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiQk9VTkRcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIklSSVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiVVJJXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJCTk9ERVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiUkFORFwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiQUJTXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJDRUlMXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJGTE9PUlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiUk9VTkRcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkNPTkNBVFwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU1RSTEVOXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJVQ0FTRVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiTENBU0VcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkVOQ09ERV9GT1JfVVJJXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJDT05UQUlOU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU1RSU1RBUlRTXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTVFJFTkRTXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTVFJCRUZPUkVcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNUUkFGVEVSXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJZRUFSXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJNT05USFwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiREFZXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJIT1VSU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiTUlOVVRFU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU0VDT05EU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiVElNRVpPTkVcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlRaXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJOT1dcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlVVSURcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNUUlVVSURcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIk1ENVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU0hBMVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU0hBMjU2XCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTSEEzODRcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNIQTUxMlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiQ09BTEVTQ0VcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIklGXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTVFJMQU5HXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJTVFJEVFwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiU0FNRVRFUk1cIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIklTSVJJXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJJU1VSSVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiSVNCTEFOS1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiSVNMSVRFUkFMXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJJU05VTUVSSUNcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIlNVQlNUUlwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiUkVQTEFDRVwiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiUkVHRVhcIjogW1wiYnVpbHRJbkNhbGxcIl0sIFxuICAgICBcIkVYSVNUU1wiOiBbXCJidWlsdEluQ2FsbFwiXSwgXG4gICAgIFwiTk9UXCI6IFtcImJ1aWx0SW5DYWxsXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcImlyaVJlZk9yRnVuY3Rpb25cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcImlyaVJlZk9yRnVuY3Rpb25cIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcImlyaVJlZk9yRnVuY3Rpb25cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJyZGZMaXRlcmFsXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW1wicmRmTGl0ZXJhbFwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1wicmRmTGl0ZXJhbFwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1wicmRmTGl0ZXJhbFwiXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXCJudW1lcmljTGl0ZXJhbFwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJudW1lcmljTGl0ZXJhbFwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcIm51bWVyaWNMaXRlcmFsXCJdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtcIm51bWVyaWNMaXRlcmFsXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcIm51bWVyaWNMaXRlcmFsXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wibnVtZXJpY0xpdGVyYWxcIl0sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW1wibnVtZXJpY0xpdGVyYWxcIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wibnVtZXJpY0xpdGVyYWxcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJudW1lcmljTGl0ZXJhbFwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJib29sZWFuTGl0ZXJhbFwiXSwgXG4gICAgIFwiRkFMU0VcIjogW1wiYm9vbGVhbkxpdGVyYWxcIl0sIFxuICAgICBcIlZBUjFcIjogW1widmFyXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInZhclwiXSwgXG4gICAgIFwiQ09VTlRcIjogW1wiYWdncmVnYXRlXCJdLCBcbiAgICAgXCJTVU1cIjogW1wiYWdncmVnYXRlXCJdLCBcbiAgICAgXCJNSU5cIjogW1wiYWdncmVnYXRlXCJdLCBcbiAgICAgXCJNQVhcIjogW1wiYWdncmVnYXRlXCJdLCBcbiAgICAgXCJBVkdcIjogW1wiYWdncmVnYXRlXCJdLCBcbiAgICAgXCJTQU1QTEVcIjogW1wiYWdncmVnYXRlXCJdLCBcbiAgICAgXCJHUk9VUF9DT05DQVRcIjogW1wiYWdncmVnYXRlXCJdfSwgXG4gIFwicHJvbG9ndWVcIiA6IHtcbiAgICAgXCJCQVNFXCI6IFtcIipvcihbYmFzZURlY2wscHJlZml4RGVjbF0pXCJdLCBcbiAgICAgXCJQUkVGSVhcIjogW1wiKm9yKFtiYXNlRGVjbCxwcmVmaXhEZWNsXSlcIl0sIFxuICAgICBcIiRcIjogW1wiKm9yKFtiYXNlRGVjbCxwcmVmaXhEZWNsXSlcIl0sIFxuICAgICBcIkNPTlNUUlVDVFwiOiBbXCIqb3IoW2Jhc2VEZWNsLHByZWZpeERlY2xdKVwiXSwgXG4gICAgIFwiREVTQ1JJQkVcIjogW1wiKm9yKFtiYXNlRGVjbCxwcmVmaXhEZWNsXSlcIl0sIFxuICAgICBcIkFTS1wiOiBbXCIqb3IoW2Jhc2VEZWNsLHByZWZpeERlY2xdKVwiXSwgXG4gICAgIFwiSU5TRVJUXCI6IFtcIipvcihbYmFzZURlY2wscHJlZml4RGVjbF0pXCJdLCBcbiAgICAgXCJERUxFVEVcIjogW1wiKm9yKFtiYXNlRGVjbCxwcmVmaXhEZWNsXSlcIl0sIFxuICAgICBcIlNFTEVDVFwiOiBbXCIqb3IoW2Jhc2VEZWNsLHByZWZpeERlY2xdKVwiXSwgXG4gICAgIFwiTE9BRFwiOiBbXCIqb3IoW2Jhc2VEZWNsLHByZWZpeERlY2xdKVwiXSwgXG4gICAgIFwiQ0xFQVJcIjogW1wiKm9yKFtiYXNlRGVjbCxwcmVmaXhEZWNsXSlcIl0sIFxuICAgICBcIkRST1BcIjogW1wiKm9yKFtiYXNlRGVjbCxwcmVmaXhEZWNsXSlcIl0sIFxuICAgICBcIkFERFwiOiBbXCIqb3IoW2Jhc2VEZWNsLHByZWZpeERlY2xdKVwiXSwgXG4gICAgIFwiTU9WRVwiOiBbXCIqb3IoW2Jhc2VEZWNsLHByZWZpeERlY2xdKVwiXSwgXG4gICAgIFwiQ09QWVwiOiBbXCIqb3IoW2Jhc2VEZWNsLHByZWZpeERlY2xdKVwiXSwgXG4gICAgIFwiQ1JFQVRFXCI6IFtcIipvcihbYmFzZURlY2wscHJlZml4RGVjbF0pXCJdLCBcbiAgICAgXCJXSVRIXCI6IFtcIipvcihbYmFzZURlY2wscHJlZml4RGVjbF0pXCJdfSwgXG4gIFwicHJvcGVydHlMaXN0XCIgOiB7XG4gICAgIFwiYVwiOiBbXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInByb3BlcnR5TGlzdE5vdEVtcHR5XCJdLCBcbiAgICAgXCIuXCI6IFtdLCBcbiAgICAgXCJ9XCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXX0sIFxuICBcInByb3BlcnR5TGlzdE5vdEVtcHR5XCIgOiB7XG4gICAgIFwiYVwiOiBbXCJ2ZXJiXCIsXCJvYmplY3RMaXN0XCIsXCIqWzssP1t2ZXJiLG9iamVjdExpc3RdXVwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJ2ZXJiXCIsXCJvYmplY3RMaXN0XCIsXCIqWzssP1t2ZXJiLG9iamVjdExpc3RdXVwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJ2ZXJiXCIsXCJvYmplY3RMaXN0XCIsXCIqWzssP1t2ZXJiLG9iamVjdExpc3RdXVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJ2ZXJiXCIsXCJvYmplY3RMaXN0XCIsXCIqWzssP1t2ZXJiLG9iamVjdExpc3RdXVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1widmVyYlwiLFwib2JqZWN0TGlzdFwiLFwiKls7LD9bdmVyYixvYmplY3RMaXN0XV1cIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInZlcmJcIixcIm9iamVjdExpc3RcIixcIipbOyw/W3ZlcmIsb2JqZWN0TGlzdF1dXCJdfSwgXG4gIFwicHJvcGVydHlMaXN0UGF0aFwiIDoge1xuICAgICBcImFcIjogW1wicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIlZBUjFcIjogW1wicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIlZBUjJcIjogW1wicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInByb3BlcnR5TGlzdE5vdEVtcHR5XCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiLlwiOiBbXSwgXG4gICAgIFwie1wiOiBbXSwgXG4gICAgIFwiT1BUSU9OQUxcIjogW10sIFxuICAgICBcIk1JTlVTXCI6IFtdLCBcbiAgICAgXCJHUkFQSFwiOiBbXSwgXG4gICAgIFwiU0VSVklDRVwiOiBbXSwgXG4gICAgIFwiRklMVEVSXCI6IFtdLCBcbiAgICAgXCJCSU5EXCI6IFtdLCBcbiAgICAgXCJWQUxVRVNcIjogW10sIFxuICAgICBcIn1cIjogW119LCBcbiAgXCJwcm9wZXJ0eUxpc3RQYXRoTm90RW1wdHlcIiA6IHtcbiAgICAgXCJWQVIxXCI6IFtcIm9yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSlcIixcIm9iamVjdExpc3RQYXRoXCIsXCIqWzssP1tvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pLG9iamVjdExpc3RdXVwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pXCIsXCJvYmplY3RMaXN0UGF0aFwiLFwiKls7LD9bb3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKSxvYmplY3RMaXN0XV1cIl0sIFxuICAgICBcIl5cIjogW1wib3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKVwiLFwib2JqZWN0TGlzdFBhdGhcIixcIipbOyw/W29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1dXCJdLCBcbiAgICAgXCJhXCI6IFtcIm9yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSlcIixcIm9iamVjdExpc3RQYXRoXCIsXCIqWzssP1tvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pLG9iamVjdExpc3RdXVwiXSwgXG4gICAgIFwiIVwiOiBbXCJvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pXCIsXCJvYmplY3RMaXN0UGF0aFwiLFwiKls7LD9bb3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKSxvYmplY3RMaXN0XV1cIl0sIFxuICAgICBcIihcIjogW1wib3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKVwiLFwib2JqZWN0TGlzdFBhdGhcIixcIipbOyw/W29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1dXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcIm9yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSlcIixcIm9iamVjdExpc3RQYXRoXCIsXCIqWzssP1tvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pLG9iamVjdExpc3RdXVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wib3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKVwiLFwib2JqZWN0TGlzdFBhdGhcIixcIipbOyw/W29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1dXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pXCIsXCJvYmplY3RMaXN0UGF0aFwiLFwiKls7LD9bb3IoW3ZlcmJQYXRoLHZlcmJTaW1wbGVdKSxvYmplY3RMaXN0XV1cIl19LCBcbiAgXCJxdWFkRGF0YVwiIDoge1xuICAgICBcIntcIjogW1wie1wiLFwiZGlzYWxsb3dWYXJzXCIsXCJxdWFkc1wiLFwiYWxsb3dWYXJzXCIsXCJ9XCJdfSwgXG4gIFwicXVhZERhdGFOb0Jub2Rlc1wiIDoge1xuICAgICBcIntcIjogW1wie1wiLFwiZGlzYWxsb3dCbm9kZXNcIixcImRpc2FsbG93VmFyc1wiLFwicXVhZHNcIixcImFsbG93VmFyc1wiLFwiYWxsb3dCbm9kZXNcIixcIn1cIl19LCBcbiAgXCJxdWFkUGF0dGVyblwiIDoge1xuICAgICBcIntcIjogW1wie1wiLFwicXVhZHNcIixcIn1cIl19LCBcbiAgXCJxdWFkUGF0dGVybk5vQm5vZGVzXCIgOiB7XG4gICAgIFwie1wiOiBbXCJ7XCIsXCJkaXNhbGxvd0Jub2Rlc1wiLFwicXVhZHNcIixcImFsbG93Qm5vZGVzXCIsXCJ9XCJdfSwgXG4gIFwicXVhZHNcIiA6IHtcbiAgICAgXCJHUkFQSFwiOiBbXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiTklMXCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCIoXCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJbXCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJUUlVFXCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiQkxBTktfTk9ERV9MQUJFTFwiOiBbXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiQU5PTlwiOiBbXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiP3RyaXBsZXNUZW1wbGF0ZVwiLFwiKltxdWFkc05vdFRyaXBsZXMsPy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW1wiP3RyaXBsZXNUZW1wbGF0ZVwiLFwiKltxdWFkc05vdFRyaXBsZXMsPy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1wiP3RyaXBsZXNUZW1wbGF0ZVwiLFwiKltxdWFkc05vdFRyaXBsZXMsPy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcyXCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJET1VCTEVcIjogW1wiP3RyaXBsZXNUZW1wbGF0ZVwiLFwiKltxdWFkc05vdFRyaXBsZXMsPy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wiP3RyaXBsZXNUZW1wbGF0ZVwiLFwiKltxdWFkc05vdFRyaXBsZXMsPy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1wiP3RyaXBsZXNUZW1wbGF0ZVwiLFwiKltxdWFkc05vdFRyaXBsZXMsPy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIkRPVUJMRV9QT1NJVElWRVwiOiBbXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCIqW3F1YWRzTm90VHJpcGxlcyw/Liw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiRE9VQkxFX05FR0FUSVZFXCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJ9XCI6IFtcIj90cmlwbGVzVGVtcGxhdGVcIixcIipbcXVhZHNOb3RUcmlwbGVzLD8uLD90cmlwbGVzVGVtcGxhdGVdXCJdfSwgXG4gIFwicXVhZHNOb3RUcmlwbGVzXCIgOiB7XG4gICAgIFwiR1JBUEhcIjogW1wiR1JBUEhcIixcInZhck9ySVJJcmVmXCIsXCJ7XCIsXCI/dHJpcGxlc1RlbXBsYXRlXCIsXCJ9XCJdfSwgXG4gIFwicXVlcnlBbGxcIiA6IHtcbiAgICAgXCJDT05TVFJVQ1RcIjogW1wib3IoW3NlbGVjdFF1ZXJ5LGNvbnN0cnVjdFF1ZXJ5LGRlc2NyaWJlUXVlcnksYXNrUXVlcnldKVwiLFwidmFsdWVzQ2xhdXNlXCJdLCBcbiAgICAgXCJERVNDUklCRVwiOiBbXCJvcihbc2VsZWN0UXVlcnksY29uc3RydWN0UXVlcnksZGVzY3JpYmVRdWVyeSxhc2tRdWVyeV0pXCIsXCJ2YWx1ZXNDbGF1c2VcIl0sIFxuICAgICBcIkFTS1wiOiBbXCJvcihbc2VsZWN0UXVlcnksY29uc3RydWN0UXVlcnksZGVzY3JpYmVRdWVyeSxhc2tRdWVyeV0pXCIsXCJ2YWx1ZXNDbGF1c2VcIl0sIFxuICAgICBcIlNFTEVDVFwiOiBbXCJvcihbc2VsZWN0UXVlcnksY29uc3RydWN0UXVlcnksZGVzY3JpYmVRdWVyeSxhc2tRdWVyeV0pXCIsXCJ2YWx1ZXNDbGF1c2VcIl19LCBcbiAgXCJyZGZMaXRlcmFsXCIgOiB7XG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInN0cmluZ1wiLFwiP29yKFtMQU5HVEFHLFteXixpcmlSZWZdXSlcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJzdHJpbmdcIixcIj9vcihbTEFOR1RBRyxbXl4saXJpUmVmXV0pXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJzdHJpbmdcIixcIj9vcihbTEFOR1RBRyxbXl4saXJpUmVmXV0pXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJzdHJpbmdcIixcIj9vcihbTEFOR1RBRyxbXl4saXJpUmVmXV0pXCJdfSwgXG4gIFwicmVnZXhFeHByZXNzaW9uXCIgOiB7XG4gICAgIFwiUkVHRVhcIjogW1wiUkVHRVhcIixcIihcIixcImV4cHJlc3Npb25cIixcIixcIixcImV4cHJlc3Npb25cIixcIj9bLCxleHByZXNzaW9uXVwiLFwiKVwiXX0sIFxuICBcInJlbGF0aW9uYWxFeHByZXNzaW9uXCIgOiB7XG4gICAgIFwiIVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIitcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCItXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiVkFSMVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIlZBUjJcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCIoXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiU1RSXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiTEFOR1wiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIkxBTkdNQVRDSEVTXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiREFUQVRZUEVcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJCT1VORFwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIklSSVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIlVSSVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIkJOT0RFXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiUkFORFwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIkFCU1wiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIkNFSUxcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJGTE9PUlwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIlJPVU5EXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiQ09OQ0FUXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiU1RSTEVOXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiVUNBU0VcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJMQ0FTRVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIkVOQ09ERV9GT1JfVVJJXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiQ09OVEFJTlNcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJTVFJTVEFSVFNcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJTVFJFTkRTXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiU1RSQkVGT1JFXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiU1RSQUZURVJcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJZRUFSXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiTU9OVEhcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJEQVlcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJIT1VSU1wiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIk1JTlVURVNcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJTRUNPTkRTXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiVElNRVpPTkVcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJUWlwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIk5PV1wiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIlVVSURcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJTVFJVVUlEXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiTUQ1XCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiU0hBMVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIlNIQTI1NlwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIlNIQTM4NFwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIlNIQTUxMlwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIkNPQUxFU0NFXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiSUZcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJTVFJMQU5HXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiU1RSRFRcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJTQU1FVEVSTVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIklTSVJJXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiSVNVUklcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJJU0JMQU5LXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiSVNMSVRFUkFMXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiSVNOVU1FUklDXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiQ09VTlRcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJTVU1cIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJNSU5cIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJNQVhcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJBVkdcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJTQU1QTEVcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJHUk9VUF9DT05DQVRcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJSRVBMQUNFXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiUkVHRVhcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJFWElTVFNcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJOT1RcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJudW1lcmljRXhwcmVzc2lvblwiLFwiP29yKFtbPSxudW1lcmljRXhwcmVzc2lvbl0sWyE9LG51bWVyaWNFeHByZXNzaW9uXSxbPCxudW1lcmljRXhwcmVzc2lvbl0sWz4sbnVtZXJpY0V4cHJlc3Npb25dLFs8PSxudW1lcmljRXhwcmVzc2lvbl0sWz49LG51bWVyaWNFeHByZXNzaW9uXSxbSU4sZXhwcmVzc2lvbkxpc3RdLFtOT1QsSU4sZXhwcmVzc2lvbkxpc3RdXSlcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcIm51bWVyaWNFeHByZXNzaW9uXCIsXCI/b3IoW1s9LG51bWVyaWNFeHByZXNzaW9uXSxbIT0sbnVtZXJpY0V4cHJlc3Npb25dLFs8LG51bWVyaWNFeHByZXNzaW9uXSxbPixudW1lcmljRXhwcmVzc2lvbl0sWzw9LG51bWVyaWNFeHByZXNzaW9uXSxbPj0sbnVtZXJpY0V4cHJlc3Npb25dLFtJTixleHByZXNzaW9uTGlzdF0sW05PVCxJTixleHByZXNzaW9uTGlzdF1dKVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wibnVtZXJpY0V4cHJlc3Npb25cIixcIj9vcihbWz0sbnVtZXJpY0V4cHJlc3Npb25dLFshPSxudW1lcmljRXhwcmVzc2lvbl0sWzwsbnVtZXJpY0V4cHJlc3Npb25dLFs+LG51bWVyaWNFeHByZXNzaW9uXSxbPD0sbnVtZXJpY0V4cHJlc3Npb25dLFs+PSxudW1lcmljRXhwcmVzc2lvbl0sW0lOLGV4cHJlc3Npb25MaXN0XSxbTk9ULElOLGV4cHJlc3Npb25MaXN0XV0pXCJdfSwgXG4gIFwic2VsZWN0Q2xhdXNlXCIgOiB7XG4gICAgIFwiU0VMRUNUXCI6IFtcIlNFTEVDVFwiLFwiP29yKFtESVNUSU5DVCxSRURVQ0VEXSlcIixcIm9yKFsrb3IoW3ZhcixbICgsZXhwcmVzc2lvbixBUyx2YXIsKV1dKSwqXSlcIl19LCBcbiAgXCJzZWxlY3RRdWVyeVwiIDoge1xuICAgICBcIlNFTEVDVFwiOiBbXCJzZWxlY3RDbGF1c2VcIixcIipkYXRhc2V0Q2xhdXNlXCIsXCJ3aGVyZUNsYXVzZVwiLFwic29sdXRpb25Nb2RpZmllclwiXX0sIFxuICBcInNlcnZpY2VHcmFwaFBhdHRlcm5cIiA6IHtcbiAgICAgXCJTRVJWSUNFXCI6IFtcIlNFUlZJQ0VcIixcIj9TSUxFTlRcIixcInZhck9ySVJJcmVmXCIsXCJncm91cEdyYXBoUGF0dGVyblwiXX0sIFxuICBcInNvbHV0aW9uTW9kaWZpZXJcIiA6IHtcbiAgICAgXCJMSU1JVFwiOiBbXCI/Z3JvdXBDbGF1c2VcIixcIj9oYXZpbmdDbGF1c2VcIixcIj9vcmRlckNsYXVzZVwiLFwiP2xpbWl0T2Zmc2V0Q2xhdXNlc1wiXSwgXG4gICAgIFwiT0ZGU0VUXCI6IFtcIj9ncm91cENsYXVzZVwiLFwiP2hhdmluZ0NsYXVzZVwiLFwiP29yZGVyQ2xhdXNlXCIsXCI/bGltaXRPZmZzZXRDbGF1c2VzXCJdLCBcbiAgICAgXCJPUkRFUlwiOiBbXCI/Z3JvdXBDbGF1c2VcIixcIj9oYXZpbmdDbGF1c2VcIixcIj9vcmRlckNsYXVzZVwiLFwiP2xpbWl0T2Zmc2V0Q2xhdXNlc1wiXSwgXG4gICAgIFwiSEFWSU5HXCI6IFtcIj9ncm91cENsYXVzZVwiLFwiP2hhdmluZ0NsYXVzZVwiLFwiP29yZGVyQ2xhdXNlXCIsXCI/bGltaXRPZmZzZXRDbGF1c2VzXCJdLCBcbiAgICAgXCJHUk9VUFwiOiBbXCI/Z3JvdXBDbGF1c2VcIixcIj9oYXZpbmdDbGF1c2VcIixcIj9vcmRlckNsYXVzZVwiLFwiP2xpbWl0T2Zmc2V0Q2xhdXNlc1wiXSwgXG4gICAgIFwiVkFMVUVTXCI6IFtcIj9ncm91cENsYXVzZVwiLFwiP2hhdmluZ0NsYXVzZVwiLFwiP29yZGVyQ2xhdXNlXCIsXCI/bGltaXRPZmZzZXRDbGF1c2VzXCJdLCBcbiAgICAgXCIkXCI6IFtcIj9ncm91cENsYXVzZVwiLFwiP2hhdmluZ0NsYXVzZVwiLFwiP29yZGVyQ2xhdXNlXCIsXCI/bGltaXRPZmZzZXRDbGF1c2VzXCJdLCBcbiAgICAgXCJ9XCI6IFtcIj9ncm91cENsYXVzZVwiLFwiP2hhdmluZ0NsYXVzZVwiLFwiP29yZGVyQ2xhdXNlXCIsXCI/bGltaXRPZmZzZXRDbGF1c2VzXCJdfSwgXG4gIFwic291cmNlU2VsZWN0b3JcIiA6IHtcbiAgICAgXCJJUklfUkVGXCI6IFtcImlyaVJlZlwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiaXJpUmVmXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJpcmlSZWZcIl19LCBcbiAgXCJzcGFycWwxMVwiIDoge1xuICAgICBcIiRcIjogW1wicHJvbG9ndWVcIixcIm9yKFtxdWVyeUFsbCx1cGRhdGVBbGxdKVwiLFwiJFwiXSwgXG4gICAgIFwiQ09OU1RSVUNUXCI6IFtcInByb2xvZ3VlXCIsXCJvcihbcXVlcnlBbGwsdXBkYXRlQWxsXSlcIixcIiRcIl0sIFxuICAgICBcIkRFU0NSSUJFXCI6IFtcInByb2xvZ3VlXCIsXCJvcihbcXVlcnlBbGwsdXBkYXRlQWxsXSlcIixcIiRcIl0sIFxuICAgICBcIkFTS1wiOiBbXCJwcm9sb2d1ZVwiLFwib3IoW3F1ZXJ5QWxsLHVwZGF0ZUFsbF0pXCIsXCIkXCJdLCBcbiAgICAgXCJJTlNFUlRcIjogW1wicHJvbG9ndWVcIixcIm9yKFtxdWVyeUFsbCx1cGRhdGVBbGxdKVwiLFwiJFwiXSwgXG4gICAgIFwiREVMRVRFXCI6IFtcInByb2xvZ3VlXCIsXCJvcihbcXVlcnlBbGwsdXBkYXRlQWxsXSlcIixcIiRcIl0sIFxuICAgICBcIlNFTEVDVFwiOiBbXCJwcm9sb2d1ZVwiLFwib3IoW3F1ZXJ5QWxsLHVwZGF0ZUFsbF0pXCIsXCIkXCJdLCBcbiAgICAgXCJMT0FEXCI6IFtcInByb2xvZ3VlXCIsXCJvcihbcXVlcnlBbGwsdXBkYXRlQWxsXSlcIixcIiRcIl0sIFxuICAgICBcIkNMRUFSXCI6IFtcInByb2xvZ3VlXCIsXCJvcihbcXVlcnlBbGwsdXBkYXRlQWxsXSlcIixcIiRcIl0sIFxuICAgICBcIkRST1BcIjogW1wicHJvbG9ndWVcIixcIm9yKFtxdWVyeUFsbCx1cGRhdGVBbGxdKVwiLFwiJFwiXSwgXG4gICAgIFwiQUREXCI6IFtcInByb2xvZ3VlXCIsXCJvcihbcXVlcnlBbGwsdXBkYXRlQWxsXSlcIixcIiRcIl0sIFxuICAgICBcIk1PVkVcIjogW1wicHJvbG9ndWVcIixcIm9yKFtxdWVyeUFsbCx1cGRhdGVBbGxdKVwiLFwiJFwiXSwgXG4gICAgIFwiQ09QWVwiOiBbXCJwcm9sb2d1ZVwiLFwib3IoW3F1ZXJ5QWxsLHVwZGF0ZUFsbF0pXCIsXCIkXCJdLCBcbiAgICAgXCJDUkVBVEVcIjogW1wicHJvbG9ndWVcIixcIm9yKFtxdWVyeUFsbCx1cGRhdGVBbGxdKVwiLFwiJFwiXSwgXG4gICAgIFwiV0lUSFwiOiBbXCJwcm9sb2d1ZVwiLFwib3IoW3F1ZXJ5QWxsLHVwZGF0ZUFsbF0pXCIsXCIkXCJdLCBcbiAgICAgXCJCQVNFXCI6IFtcInByb2xvZ3VlXCIsXCJvcihbcXVlcnlBbGwsdXBkYXRlQWxsXSlcIixcIiRcIl0sIFxuICAgICBcIlBSRUZJWFwiOiBbXCJwcm9sb2d1ZVwiLFwib3IoW3F1ZXJ5QWxsLHVwZGF0ZUFsbF0pXCIsXCIkXCJdfSwgXG4gIFwic3RvcmVQcm9wZXJ0eVwiIDoge1xuICAgICBcIlZBUjFcIjogW10sIFxuICAgICBcIlZBUjJcIjogW10sIFxuICAgICBcIklSSV9SRUZcIjogW10sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXSwgXG4gICAgIFwiYVwiOiBbXX0sIFxuICBcInN0clJlcGxhY2VFeHByZXNzaW9uXCIgOiB7XG4gICAgIFwiUkVQTEFDRVwiOiBbXCJSRVBMQUNFXCIsXCIoXCIsXCJleHByZXNzaW9uXCIsXCIsXCIsXCJleHByZXNzaW9uXCIsXCIsXCIsXCJleHByZXNzaW9uXCIsXCI/WywsZXhwcmVzc2lvbl1cIixcIilcIl19LCBcbiAgXCJzdHJpbmdcIiA6IHtcbiAgICAgXCJTVFJJTkdfTElURVJBTDFcIjogW1wiU1RSSU5HX0xJVEVSQUwxXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW1wiU1RSSU5HX0xJVEVSQUwyXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJTVFJJTkdfTElURVJBTF9MT05HMVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1wiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIl19LCBcbiAgXCJzdWJTZWxlY3RcIiA6IHtcbiAgICAgXCJTRUxFQ1RcIjogW1wic2VsZWN0Q2xhdXNlXCIsXCJ3aGVyZUNsYXVzZVwiLFwic29sdXRpb25Nb2RpZmllclwiLFwidmFsdWVzQ2xhdXNlXCJdfSwgXG4gIFwic3Vic3RyaW5nRXhwcmVzc2lvblwiIDoge1xuICAgICBcIlNVQlNUUlwiOiBbXCJTVUJTVFJcIixcIihcIixcImV4cHJlc3Npb25cIixcIixcIixcImV4cHJlc3Npb25cIixcIj9bLCxleHByZXNzaW9uXVwiLFwiKVwiXX0sIFxuICBcInRyaXBsZXNCbG9ja1wiIDoge1xuICAgICBcIlZBUjFcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0UGF0aFwiLFwiP1suLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIixcIj9bLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiTklMXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIixcIj9bLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiKFwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RQYXRoXCIsXCI/Wy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIltcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0UGF0aFwiLFwiP1suLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJJUklfUkVGXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIixcIj9bLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RQYXRoXCIsXCI/Wy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIixcIj9bLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiQkxBTktfTk9ERV9MQUJFTFwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RQYXRoXCIsXCI/Wy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIkFOT05cIjogW1widHJpcGxlc1NhbWVTdWJqZWN0UGF0aFwiLFwiP1suLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RQYXRoXCIsXCI/Wy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIixcIj9bLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIixcIj9bLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIixcIj9bLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzFcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0UGF0aFwiLFwiP1suLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RQYXRoXCIsXCI/Wy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0UGF0aFwiLFwiP1suLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJERUNJTUFMXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIixcIj9bLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIixcIj9bLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RQYXRoXCIsXCI/Wy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIkRFQ0lNQUxfUE9TSVRJVkVcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0UGF0aFwiLFwiP1suLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0UGF0aFwiLFwiP1suLD90cmlwbGVzQmxvY2tdXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIixcIj9bLiw/dHJpcGxlc0Jsb2NrXVwiXSwgXG4gICAgIFwiREVDSU1BTF9ORUdBVElWRVwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RQYXRoXCIsXCI/Wy4sP3RyaXBsZXNCbG9ja11cIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RQYXRoXCIsXCI/Wy4sP3RyaXBsZXNCbG9ja11cIl19LCBcbiAgXCJ0cmlwbGVzTm9kZVwiIDoge1xuICAgICBcIihcIjogW1wiY29sbGVjdGlvblwiXSwgXG4gICAgIFwiW1wiOiBbXCJibGFua05vZGVQcm9wZXJ0eUxpc3RcIl19LCBcbiAgXCJ0cmlwbGVzTm9kZVBhdGhcIiA6IHtcbiAgICAgXCIoXCI6IFtcImNvbGxlY3Rpb25QYXRoXCJdLCBcbiAgICAgXCJbXCI6IFtcImJsYW5rTm9kZVByb3BlcnR5TGlzdFBhdGhcIl19LCBcbiAgXCJ0cmlwbGVzU2FtZVN1YmplY3RcIiA6IHtcbiAgICAgXCJWQVIxXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIlZBUjJcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiTklMXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdE5vdEVtcHR5XCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdE5vdEVtcHR5XCJdLCBcbiAgICAgXCJCTEFOS19OT0RFX0xBQkVMXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIkFOT05cIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdE5vdEVtcHR5XCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdE5vdEVtcHR5XCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdE5vdEVtcHR5XCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdE5vdEVtcHR5XCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3ROb3RFbXB0eVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdE5vdEVtcHR5XCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0Tm90RW1wdHlcIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdE5vdEVtcHR5XCJdLCBcbiAgICAgXCIoXCI6IFtcInRyaXBsZXNOb2RlXCIsXCJwcm9wZXJ0eUxpc3RcIl0sIFxuICAgICBcIltcIjogW1widHJpcGxlc05vZGVcIixcInByb3BlcnR5TGlzdFwiXX0sIFxuICBcInRyaXBsZXNTYW1lU3ViamVjdFBhdGhcIiA6IHtcbiAgICAgXCJWQVIxXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCJdLCBcbiAgICAgXCJOSUxcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3RQYXRoTm90RW1wdHlcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3RQYXRoTm90RW1wdHlcIl0sIFxuICAgICBcIlRSVUVcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3RQYXRoTm90RW1wdHlcIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCJdLCBcbiAgICAgXCJCTEFOS19OT0RFX0xBQkVMXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCJdLCBcbiAgICAgXCJBTk9OXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdFBhdGhOb3RFbXB0eVwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3RQYXRoTm90RW1wdHlcIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdFBhdGhOb3RFbXB0eVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdFBhdGhOb3RFbXB0eVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3RQYXRoTm90RW1wdHlcIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3RQYXRoTm90RW1wdHlcIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3RQYXRoTm90RW1wdHlcIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdFBhdGhOb3RFbXB0eVwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdFBhdGhOb3RFbXB0eVwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJ2YXJPclRlcm1cIixcInByb3BlcnR5TGlzdFBhdGhOb3RFbXB0eVwiXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcInZhck9yVGVybVwiLFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCJdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW1widmFyT3JUZXJtXCIsXCJwcm9wZXJ0eUxpc3RQYXRoTm90RW1wdHlcIl0sIFxuICAgICBcIihcIjogW1widHJpcGxlc05vZGVQYXRoXCIsXCJwcm9wZXJ0eUxpc3RQYXRoXCJdLCBcbiAgICAgXCJbXCI6IFtcInRyaXBsZXNOb2RlUGF0aFwiLFwicHJvcGVydHlMaXN0UGF0aFwiXX0sIFxuICBcInRyaXBsZXNUZW1wbGF0ZVwiIDoge1xuICAgICBcIlZBUjFcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIlZBUjJcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIk5JTFwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiKFwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiW1wiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiRkFMU0VcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIkFOT05cIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/dHJpcGxlc1RlbXBsYXRlXVwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcInRyaXBsZXNTYW1lU3ViamVjdFwiLFwiP1suLD90cmlwbGVzVGVtcGxhdGVdXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1widHJpcGxlc1NhbWVTdWJqZWN0XCIsXCI/Wy4sP3RyaXBsZXNUZW1wbGF0ZV1cIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJ0cmlwbGVzU2FtZVN1YmplY3RcIixcIj9bLiw/dHJpcGxlc1RlbXBsYXRlXVwiXX0sIFxuICBcInVuYXJ5RXhwcmVzc2lvblwiIDoge1xuICAgICBcIiFcIjogW1wiIVwiLFwicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIitcIjogW1wiK1wiLFwicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIi1cIjogW1wiLVwiLFwicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlZBUjFcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlZBUjJcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIihcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUlwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTEFOR1wiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTEFOR01BVENIRVNcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRBVEFUWVBFXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJCT1VORFwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSVJJXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJVUklcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkJOT0RFXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJSQU5EXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJBQlNcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkNFSUxcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkZMT09SXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJST1VORFwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQ09OQ0FUXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJMRU5cIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlVDQVNFXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJMQ0FTRVwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRU5DT0RFX0ZPUl9VUklcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkNPTlRBSU5TXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJTVEFSVFNcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUkVORFNcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUkJFRk9SRVwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSQUZURVJcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIllFQVJcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIk1PTlRIXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJEQVlcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkhPVVJTXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJNSU5VVEVTXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTRUNPTkRTXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJUSU1FWk9ORVwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVFpcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIk5PV1wiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVVVJRFwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSVVVJRFwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTUQ1XCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTSEExXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTSEEyNTZcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNIQTM4NFwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0hBNTEyXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJDT0FMRVNDRVwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSUZcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUkxBTkdcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUkRUXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTQU1FVEVSTVwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSVNJUklcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIklTVVJJXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU0JMQU5LXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU0xJVEVSQUxcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIklTTlVNRVJJQ1wiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVFJVRVwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRkFMU0VcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkNPVU5UXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVU1cIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIk1JTlwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTUFYXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJBVkdcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNBTVBMRVwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiR1JPVVBfQ09OQ0FUXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVUJTVFJcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlJFUExBQ0VcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlJFR0VYXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJFWElTVFNcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIk5PVFwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwxXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTDJcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMlwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSU5URUdFUlwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRE9VQkxFXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJTlRFR0VSX1BPU0lUSVZFXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJET1VCTEVfUE9TSVRJVkVcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIklOVEVHRVJfTkVHQVRJVkVcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRPVUJMRV9ORUdBVElWRVwiOiBbXCJwcmltYXJ5RXhwcmVzc2lvblwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wicHJpbWFyeUV4cHJlc3Npb25cIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcInByaW1hcnlFeHByZXNzaW9uXCJdfSwgXG4gIFwidXBkYXRlXCIgOiB7XG4gICAgIFwiSU5TRVJUXCI6IFtcInByb2xvZ3VlXCIsXCI/W3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCJdLCBcbiAgICAgXCJERUxFVEVcIjogW1wicHJvbG9ndWVcIixcIj9bdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIkxPQURcIjogW1wicHJvbG9ndWVcIixcIj9bdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIkNMRUFSXCI6IFtcInByb2xvZ3VlXCIsXCI/W3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCJdLCBcbiAgICAgXCJEUk9QXCI6IFtcInByb2xvZ3VlXCIsXCI/W3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCJdLCBcbiAgICAgXCJBRERcIjogW1wicHJvbG9ndWVcIixcIj9bdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIk1PVkVcIjogW1wicHJvbG9ndWVcIixcIj9bdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIkNPUFlcIjogW1wicHJvbG9ndWVcIixcIj9bdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIkNSRUFURVwiOiBbXCJwcm9sb2d1ZVwiLFwiP1t1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiV0lUSFwiOiBbXCJwcm9sb2d1ZVwiLFwiP1t1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiQkFTRVwiOiBbXCJwcm9sb2d1ZVwiLFwiP1t1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiUFJFRklYXCI6IFtcInByb2xvZ3VlXCIsXCI/W3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCJdLCBcbiAgICAgXCIkXCI6IFtcInByb2xvZ3VlXCIsXCI/W3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCJdfSwgXG4gIFwidXBkYXRlMVwiIDoge1xuICAgICBcIkxPQURcIjogW1wibG9hZFwiXSwgXG4gICAgIFwiQ0xFQVJcIjogW1wiY2xlYXJcIl0sIFxuICAgICBcIkRST1BcIjogW1wiZHJvcFwiXSwgXG4gICAgIFwiQUREXCI6IFtcImFkZFwiXSwgXG4gICAgIFwiTU9WRVwiOiBbXCJtb3ZlXCJdLCBcbiAgICAgXCJDT1BZXCI6IFtcImNvcHlcIl0sIFxuICAgICBcIkNSRUFURVwiOiBbXCJjcmVhdGVcIl0sIFxuICAgICBcIklOU0VSVFwiOiBbXCJJTlNFUlRcIixcImluc2VydDFcIl0sIFxuICAgICBcIkRFTEVURVwiOiBbXCJERUxFVEVcIixcImRlbGV0ZTFcIl0sIFxuICAgICBcIldJVEhcIjogW1wibW9kaWZ5XCJdfSwgXG4gIFwidXBkYXRlQWxsXCIgOiB7XG4gICAgIFwiSU5TRVJUXCI6IFtcIj9bdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIkRFTEVURVwiOiBbXCI/W3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCJdLCBcbiAgICAgXCJMT0FEXCI6IFtcIj9bdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIkNMRUFSXCI6IFtcIj9bdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIkRST1BcIjogW1wiP1t1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiQUREXCI6IFtcIj9bdXBkYXRlMSw/WzssdXBkYXRlXV1cIl0sIFxuICAgICBcIk1PVkVcIjogW1wiP1t1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiQ09QWVwiOiBbXCI/W3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCJdLCBcbiAgICAgXCJDUkVBVEVcIjogW1wiP1t1cGRhdGUxLD9bOyx1cGRhdGVdXVwiXSwgXG4gICAgIFwiV0lUSFwiOiBbXCI/W3VwZGF0ZTEsP1s7LHVwZGF0ZV1dXCJdLCBcbiAgICAgXCIkXCI6IFtcIj9bdXBkYXRlMSw/WzssdXBkYXRlXV1cIl19LCBcbiAgXCJ1c2luZ0NsYXVzZVwiIDoge1xuICAgICBcIlVTSU5HXCI6IFtcIlVTSU5HXCIsXCJvcihbaXJpUmVmLFtOQU1FRCxpcmlSZWZdXSlcIl19LCBcbiAgXCJ2YWx1ZUxvZ2ljYWxcIiA6IHtcbiAgICAgXCIhXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCIrXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCItXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJWQVIxXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCIoXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIkxBTkdcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIkxBTkdNQVRDSEVTXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJEQVRBVFlQRVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQk9VTkRcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIklSSVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVVJJXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJCTk9ERVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiUkFORFwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQUJTXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJDRUlMXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJGTE9PUlwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiUk9VTkRcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIkNPTkNBVFwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSTEVOXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJVQ0FTRVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTENBU0VcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIkVOQ09ERV9GT1JfVVJJXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJDT05UQUlOU1wiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSU1RBUlRTXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJFTkRTXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJCRUZPUkVcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUkFGVEVSXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJZRUFSXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJNT05USFwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiREFZXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJIT1VSU1wiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiTUlOVVRFU1wiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0VDT05EU1wiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiVElNRVpPTkVcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIlRaXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJOT1dcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIlVVSURcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUlVVSURcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIk1ENVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0hBMVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0hBMjU2XCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTSEEzODRcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNIQTUxMlwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQ09BTEVTQ0VcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIklGXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJMQU5HXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJEVFwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU0FNRVRFUk1cIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIklTSVJJXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU1VSSVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSVNCTEFOS1wiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSVNMSVRFUkFMXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJU05VTUVSSUNcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIlRSVUVcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIkZBTFNFXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJDT1VOVFwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1VNXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJNSU5cIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIk1BWFwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiQVZHXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTQU1QTEVcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIkdST1VQX0NPTkNBVFwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1VCU1RSXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJSRVBMQUNFXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJSRUdFWFwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRVhJU1RTXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJOT1RcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUwyXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJTVFJJTkdfTElURVJBTF9MT05HMVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIklOVEVHRVJcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRFQ0lNQUxcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiSU5URUdFUl9QT1NJVElWRVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiREVDSU1BTF9QT1NJVElWRVwiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJJTlRFR0VSX05FR0FUSVZFXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJERUNJTUFMX05FR0FUSVZFXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW1wicmVsYXRpb25hbEV4cHJlc3Npb25cIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInJlbGF0aW9uYWxFeHByZXNzaW9uXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJyZWxhdGlvbmFsRXhwcmVzc2lvblwiXX0sIFxuICBcInZhbHVlc0NsYXVzZVwiIDoge1xuICAgICBcIlZBTFVFU1wiOiBbXCJWQUxVRVNcIixcImRhdGFCbG9ja1wiXSwgXG4gICAgIFwiJFwiOiBbXSwgXG4gICAgIFwifVwiOiBbXX0sIFxuICBcInZhclwiIDoge1xuICAgICBcIlZBUjFcIjogW1wiVkFSMVwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJWQVIyXCJdfSwgXG4gIFwidmFyT3JJUklyZWZcIiA6IHtcbiAgICAgXCJWQVIxXCI6IFtcInZhclwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJ2YXJcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wiaXJpUmVmXCJdLCBcbiAgICAgXCJQTkFNRV9MTlwiOiBbXCJpcmlSZWZcIl0sIFxuICAgICBcIlBOQU1FX05TXCI6IFtcImlyaVJlZlwiXX0sIFxuICBcInZhck9yVGVybVwiIDoge1xuICAgICBcIlZBUjFcIjogW1widmFyXCJdLCBcbiAgICAgXCJWQVIyXCI6IFtcInZhclwiXSwgXG4gICAgIFwiTklMXCI6IFtcImdyYXBoVGVybVwiXSwgXG4gICAgIFwiSVJJX1JFRlwiOiBbXCJncmFwaFRlcm1cIl0sIFxuICAgICBcIlRSVUVcIjogW1wiZ3JhcGhUZXJtXCJdLCBcbiAgICAgXCJGQUxTRVwiOiBbXCJncmFwaFRlcm1cIl0sIFxuICAgICBcIkJMQU5LX05PREVfTEFCRUxcIjogW1wiZ3JhcGhUZXJtXCJdLCBcbiAgICAgXCJBTk9OXCI6IFtcImdyYXBoVGVybVwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wiZ3JhcGhUZXJtXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJncmFwaFRlcm1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMVwiOiBbXCJncmFwaFRlcm1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMMlwiOiBbXCJncmFwaFRlcm1cIl0sIFxuICAgICBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCI6IFtcImdyYXBoVGVybVwiXSwgXG4gICAgIFwiU1RSSU5HX0xJVEVSQUxfTE9ORzJcIjogW1wiZ3JhcGhUZXJtXCJdLCBcbiAgICAgXCJJTlRFR0VSXCI6IFtcImdyYXBoVGVybVwiXSwgXG4gICAgIFwiREVDSU1BTFwiOiBbXCJncmFwaFRlcm1cIl0sIFxuICAgICBcIkRPVUJMRVwiOiBbXCJncmFwaFRlcm1cIl0sIFxuICAgICBcIklOVEVHRVJfUE9TSVRJVkVcIjogW1wiZ3JhcGhUZXJtXCJdLCBcbiAgICAgXCJERUNJTUFMX1BPU0lUSVZFXCI6IFtcImdyYXBoVGVybVwiXSwgXG4gICAgIFwiRE9VQkxFX1BPU0lUSVZFXCI6IFtcImdyYXBoVGVybVwiXSwgXG4gICAgIFwiSU5URUdFUl9ORUdBVElWRVwiOiBbXCJncmFwaFRlcm1cIl0sIFxuICAgICBcIkRFQ0lNQUxfTkVHQVRJVkVcIjogW1wiZ3JhcGhUZXJtXCJdLCBcbiAgICAgXCJET1VCTEVfTkVHQVRJVkVcIjogW1wiZ3JhcGhUZXJtXCJdfSwgXG4gIFwidmVyYlwiIDoge1xuICAgICBcIlZBUjFcIjogW1wic3RvcmVQcm9wZXJ0eVwiLFwidmFyT3JJUklyZWZcIl0sIFxuICAgICBcIlZBUjJcIjogW1wic3RvcmVQcm9wZXJ0eVwiLFwidmFyT3JJUklyZWZcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wic3RvcmVQcm9wZXJ0eVwiLFwidmFyT3JJUklyZWZcIl0sIFxuICAgICBcIlBOQU1FX0xOXCI6IFtcInN0b3JlUHJvcGVydHlcIixcInZhck9ySVJJcmVmXCJdLCBcbiAgICAgXCJQTkFNRV9OU1wiOiBbXCJzdG9yZVByb3BlcnR5XCIsXCJ2YXJPcklSSXJlZlwiXSwgXG4gICAgIFwiYVwiOiBbXCJzdG9yZVByb3BlcnR5XCIsXCJhXCJdfSwgXG4gIFwidmVyYlBhdGhcIiA6IHtcbiAgICAgXCJeXCI6IFtcInBhdGhcIl0sIFxuICAgICBcImFcIjogW1wicGF0aFwiXSwgXG4gICAgIFwiIVwiOiBbXCJwYXRoXCJdLCBcbiAgICAgXCIoXCI6IFtcInBhdGhcIl0sIFxuICAgICBcIklSSV9SRUZcIjogW1wicGF0aFwiXSwgXG4gICAgIFwiUE5BTUVfTE5cIjogW1wicGF0aFwiXSwgXG4gICAgIFwiUE5BTUVfTlNcIjogW1wicGF0aFwiXX0sIFxuICBcInZlcmJTaW1wbGVcIiA6IHtcbiAgICAgXCJWQVIxXCI6IFtcInZhclwiXSwgXG4gICAgIFwiVkFSMlwiOiBbXCJ2YXJcIl19LCBcbiAgXCJ3aGVyZUNsYXVzZVwiIDoge1xuICAgICBcIntcIjogW1wiP1dIRVJFXCIsXCJncm91cEdyYXBoUGF0dGVyblwiXSwgXG4gICAgIFwiV0hFUkVcIjogW1wiP1dIRVJFXCIsXCJncm91cEdyYXBoUGF0dGVyblwiXX1cbn0sXG5cbmtleXdvcmRzOi9eKEdST1VQX0NPTkNBVHxEQVRBVFlQRXxCQVNFfFBSRUZJWHxTRUxFQ1R8Q09OU1RSVUNUfERFU0NSSUJFfEFTS3xGUk9NfE5BTUVEfE9SREVSfEJZfExJTUlUfEFTQ3xERVNDfE9GRlNFVHxESVNUSU5DVHxSRURVQ0VEfFdIRVJFfEdSQVBIfE9QVElPTkFMfFVOSU9OfEZJTFRFUnxHUk9VUHxIQVZJTkd8QVN8VkFMVUVTfExPQUR8Q0xFQVJ8RFJPUHxDUkVBVEV8TU9WRXxDT1BZfFNJTEVOVHxJTlNFUlR8REVMRVRFfERBVEF8V0lUSHxUT3xVU0lOR3xOQU1FRHxNSU5VU3xCSU5EfExBTkdNQVRDSEVTfExBTkd8Qk9VTkR8U0FNRVRFUk18SVNJUkl8SVNVUkl8SVNCTEFOS3xJU0xJVEVSQUx8UkVHRVh8VFJVRXxGQUxTRXxVTkRFRnxBRER8REVGQVVMVHxBTEx8U0VSVklDRXxJTlRPfElOfE5PVHxJUkl8VVJJfEJOT0RFfFJBTkR8QUJTfENFSUx8RkxPT1J8Uk9VTkR8Q09OQ0FUfFNUUkxFTnxVQ0FTRXxMQ0FTRXxFTkNPREVfRk9SX1VSSXxDT05UQUlOU3xTVFJTVEFSVFN8U1RSRU5EU3xTVFJCRUZPUkV8U1RSQUZURVJ8WUVBUnxNT05USHxEQVl8SE9VUlN8TUlOVVRFU3xTRUNPTkRTfFRJTUVaT05FfFRafE5PV3xVVUlEfFNUUlVVSUR8TUQ1fFNIQTF8U0hBMjU2fFNIQTM4NHxTSEE1MTJ8Q09BTEVTQ0V8SUZ8U1RSTEFOR3xTVFJEVHxJU05VTUVSSUN8U1VCU1RSfFJFUExBQ0V8RVhJU1RTfENPVU5UfFNVTXxNSU58TUFYfEFWR3xTQU1QTEV8U0VQQVJBVE9SfFNUUikvaSAsXG5cbnB1bmN0Oi9eKFxcKnxhfFxcLnxcXHt8XFx9fCx8XFwofFxcKXw7fFxcW3xcXF18XFx8XFx8fCYmfD18IT18IXw8PXw+PXw8fD58XFwrfC18XFwvfFxcXlxcXnxcXD98XFx8fFxcXikvICxcblxuc3RhcnRTeW1ib2w6XCJzcGFycWwxMVwiLFxuYWNjZXB0RW1wdHk6dHJ1ZSxcbn0iLCJcInVzZSBzdHJpY3RcIjtcbnZhciBDb2RlTWlycm9yID0gcmVxdWlyZSgnY29kZW1pcnJvcicpO1xuQ29kZU1pcnJvci5kZWZpbmVNb2RlKFwic3BhcnFsMTFcIiwgZnVuY3Rpb24oY29uZmlnLCBwYXJzZXJDb25maWcpIHtcblxuXHR2YXIgaW5kZW50VW5pdCA9IGNvbmZpZy5pbmRlbnRVbml0O1xuXG5cdHZhciBncmFtbWFyID0gcmVxdWlyZSgnLi9fdG9rZW5pemVyLXRhYmxlLmpzJyk7XG5cdHZhciBsbDFfdGFibGUgPSBncmFtbWFyLnRhYmxlO1xuXG5cdHZhciBJUklfUkVGID0gJzxbXjw+XFxcIlxcJ1xcfFxce1xcfVxcXlxcXFxcXHgwMC1cXHgyMF0qPic7XG5cdC8qXG5cdCAqIFBOX0NIQVJTX0JBU0UgPVxuXHQgKiAnW0EtWl18W2Etel18W1xcXFx1MDBDMC1cXFxcdTAwRDZdfFtcXFxcdTAwRDgtXFxcXHUwMEY2XXxbXFxcXHUwMEY4LVxcXFx1MDJGRl18W1xcXFx1MDM3MC1cXFxcdTAzN0RdfFtcXFxcdTAzN0YtXFxcXHUxRkZGXXxbXFxcXHUyMDBDLVxcXFx1MjAwRF18W1xcXFx1MjA3MC1cXFxcdTIxOEZdfFtcXFxcdTJDMDAtXFxcXHUyRkVGXXxbXFxcXHUzMDAxLVxcXFx1RDdGRl18W1xcXFx1RjkwMC1cXFxcdUZEQ0ZdfFtcXFxcdUZERjAtXFxcXHVGRkZEXXxbXFxcXHUxMDAwMC1cXFxcdUVGRkZGXSc7XG5cdCAqL1xuXG5cdHZhciBQTl9DSEFSU19CQVNFID1cblx0XHQnW0EtWmEtelxcXFx1MDBDMC1cXFxcdTAwRDZcXFxcdTAwRDgtXFxcXHUwMEY2XFxcXHUwMEY4LVxcXFx1MDJGRlxcXFx1MDM3MC1cXFxcdTAzN0RcXFxcdTAzN0YtXFxcXHUxRkZGXFxcXHUyMDBDLVxcXFx1MjAwRFxcXFx1MjA3MC1cXFxcdTIxOEZcXFxcdTJDMDAtXFxcXHUyRkVGXFxcXHUzMDAxLVxcXFx1RDdGRlxcXFx1RjkwMC1cXFxcdUZEQ0ZcXFxcdUZERjAtXFxcXHVGRkZEXSc7XG5cdHZhciBQTl9DSEFSU19VID0gUE5fQ0hBUlNfQkFTRSsnfF8nO1xuXG5cdHZhciBQTl9DSEFSUz0gJygnK1BOX0NIQVJTX1UrJ3wtfFswLTlcXFxcdTAwQjdcXFxcdTAzMDAtXFxcXHUwMzZGXFxcXHUyMDNGLVxcXFx1MjA0MF0pJztcblx0dmFyIFZBUk5BTUUgPSAnKCcrUE5fQ0hBUlNfVSsnfFswLTldKScrXG5cdFx0JygnK1BOX0NIQVJTX1UrJ3xbMC05XFxcXHUwMEI3XFxcXHUwMzAwLVxcXFx1MDM2RlxcXFx1MjAzRi1cXFxcdTIwNDBdKSonO1xuXHR2YXIgVkFSMSA9ICdcXFxcPycrVkFSTkFNRTtcblx0dmFyIFZBUjIgPSAnXFxcXCQnK1ZBUk5BTUU7XG5cblx0dmFyIFBOX1BSRUZJWD0gJygnK1BOX0NIQVJTX0JBU0UrJykoKCgnK1BOX0NIQVJTKycpfFxcXFwuKSooJytQTl9DSEFSUysnKSk/JztcblxuXHR2YXIgSEVYPSAnWzAtOUEtRmEtZl0nO1xuXHR2YXIgUEVSQ0VOVD0nKCUnK0hFWCtIRVgrJyknO1xuXHR2YXIgUE5fTE9DQUxfRVNDPScoXFxcXFxcXFxbX35cXFxcLlxcXFwtIVxcXFwkJlxcJ1xcXFwoXFxcXClcXFxcKlxcXFwrLDs9L1xcXFw/I0AlXSknO1xuXHR2YXIgUExYPSAnKCcrUEVSQ0VOVCsnfCcrUE5fTE9DQUxfRVNDKycpJztcblx0dmFyIFBOX0xPQ0FMPSAnKCcrUE5fQ0hBUlNfVSsnfDp8WzAtOV18JytQTFgrJykoKCcrUE5fQ0hBUlMrJ3xcXFxcLnw6fCcrUExYKycpKignK1BOX0NIQVJTKyd8OnwnK1BMWCsnKSk/Jztcblx0dmFyIEJMQU5LX05PREVfTEFCRUwgPSAnXzooJytQTl9DSEFSU19VKyd8WzAtOV0pKCgnK1BOX0NIQVJTKyd8XFxcXC4pKicrUE5fQ0hBUlMrJyk/Jztcblx0dmFyIFBOQU1FX05TID0gJygnK1BOX1BSRUZJWCsnKT86Jztcblx0dmFyIFBOQU1FX0xOID0gUE5BTUVfTlMrUE5fTE9DQUw7XG5cdHZhciBMQU5HVEFHID0gJ0BbYS16QS1aXSsoLVthLXpBLVowLTldKykqJztcblxuXHR2YXIgRVhQT05FTlQgPSAnW2VFXVtcXFxcKy1dP1swLTldKyc7XG5cdHZhciBJTlRFR0VSID0gJ1swLTldKyc7XG5cdHZhciBERUNJTUFMID0gJygoWzAtOV0rXFxcXC5bMC05XSopfChcXFxcLlswLTldKykpJztcblx0dmFyIERPVUJMRSA9XG5cdFx0JygoWzAtOV0rXFxcXC5bMC05XSonK0VYUE9ORU5UKycpfCcrXG5cdFx0JyhcXFxcLlswLTldKycrRVhQT05FTlQrJyl8Jytcblx0XHQnKFswLTldKycrRVhQT05FTlQrJykpJztcblxuXHR2YXIgSU5URUdFUl9QT1NJVElWRSA9ICdcXFxcKycgKyBJTlRFR0VSO1xuXHR2YXIgREVDSU1BTF9QT1NJVElWRSA9ICdcXFxcKycgKyBERUNJTUFMO1xuXHR2YXIgRE9VQkxFX1BPU0lUSVZFICA9ICdcXFxcKycgKyBET1VCTEU7XG5cdHZhciBJTlRFR0VSX05FR0FUSVZFID0gJy0nICsgSU5URUdFUjtcblx0dmFyIERFQ0lNQUxfTkVHQVRJVkUgPSAnLScgKyBERUNJTUFMO1xuXHR2YXIgRE9VQkxFX05FR0FUSVZFICA9ICctJyArIERPVUJMRTtcblxuXHR2YXIgRUNIQVIgPSAnXFxcXFxcXFxbdGJucmZcXFxcXFxcXFwiXFwnXSc7XG5cdFxuXHRcblx0IC8vSU1QT1JUQU5UOiB0aGlzIHVuaWNvZGUgcnVsZSBpcyBub3QgaW4gdGhlIG9mZmljaWFsIGdyYW1tYXIuXG4gICAgICAvL1JlYXNvbjogaHR0cHM6Ly9naXRodWIuY29tL1lBU0dVSS9ZQVNRRS9pc3N1ZXMvNDlcbiAgICAgIC8vdW5pY29kZSBlc2NhcGUgc2VxdWVuY2VzICh3aGljaCB0aGUgc3BhcnFsIHNwZWMgY29uc2lkZXJzIHBhcnQgb2YgdGhlIHByZS1wcm9jZXNzaW5nIG9mIHNwYXJxbCBxdWVyaWVzKVxuICAgICAgLy9hcmUgbWFya2VkIGFzIGludmFsaWQuIFdlIGhhdmUgbGl0dGxlIGNob2ljZSAob3RoZXIgdGhhbiBhZGRpbmcgYSBsYXllciBvZiBjb21wbGl4aXR5KSB0aGFuIHRvIG1vZGlmeSB0aGUgZ3JhbW1hciBhY2NvcmRpbmdseVxuICAgICAgLy9ob3dldmVyLCBmb3Igbm93IG9ubHkgYWxsb3cgdGhlc2UgZXNjYXBlIHNlcXVlbmNlcyBpbiBsaXRlcmFscyAod2hlcmUgYWN0dWFsbHksIHRoaXMgc2hvdWxkIGJlIGFsbG93cyBpbiBlLmcuIHByZWZpeGVzIGFzIHdlbGwpXG5cdHZhciBoZXg0ID0gSEVYICsgJ3s0fSdcblx0dmFyIHVuaWNvZGUgPSAnKFxcXFxcXFxcdScgKyBoZXg0ICsnfFxcXFxcXFxcVTAwKDEwfDAnICsgSEVYICsgJyknKyBoZXg0ICsgJyknO1xuXHR2YXIgTElORV9CUkVBSyA9IFwiXFxuXCI7XG5cdHZhciBTVFJJTkdfTElURVJBTDEgPSBcIicoKFteXFxcXHgyN1xcXFx4NUNcXFxceDBBXFxcXHgwRF0pfFwiK0VDSEFSK1wifFwiICsgdW5pY29kZSArIFwiKSonXCI7XG5cdHZhciBTVFJJTkdfTElURVJBTDIgPSAnXCIoKFteXFxcXHgyMlxcXFx4NUNcXFxceDBBXFxcXHgwRF0pfCcrRUNIQVIrJ3wnICsgdW5pY29kZSArICcpKlwiJztcblx0XG5cdHZhciBTVFJJTkdfTElURVJBTF9MT05HID0ge1xuXHRcdFNJTkdMRToge1xuXHRcdFx0Q0FUOiBcIlNUUklOR19MSVRFUkFMX0xPTkcxXCIsXG5cdFx0XHRRVU9URVM6IFwiJycnXCIsXG5cdFx0XHRDT05URU5UUzogXCIoKCd8JycpPyhbXidcXFxcXFxcXF18XCIrRUNIQVIrXCJ8XCIrdW5pY29kZStcIikpKlwiLFxuXHRcdFx0XG5cdFx0fSxcblx0XHRET1VCTEU6IHtcblx0XHRcdENBVDogXCJTVFJJTkdfTElURVJBTF9MT05HMlwiLFxuXHRcdFx0UVVPVEVTOiAnXCJcIlwiJyxcblx0XHRcdENPTlRFTlRTOiAnKChcInxcIlwiKT8oW15cIlxcXFxcXFxcXXwnK0VDSEFSKyd8Jyt1bmljb2RlKycpKSonLFxuXHRcdH1cblx0fTtcblx0Zm9yICh2YXIga2V5IGluIFNUUklOR19MSVRFUkFMX0xPTkcpIHtcblx0XHRTVFJJTkdfTElURVJBTF9MT05HW2tleV0uQ09NUExFVEUgPSBTVFJJTkdfTElURVJBTF9MT05HW2tleV0uUVVPVEVTICsgU1RSSU5HX0xJVEVSQUxfTE9OR1trZXldLkNPTlRFTlRTICsgU1RSSU5HX0xJVEVSQUxfTE9OR1trZXldLlFVT1RFUztcblx0fVxuLy9cdHZhciBTVFJJTkdfTElURVJBTF9MT05HX1FVT1RFUyA9IHtcbi8vXHRcdFwiU1RSSU5HX0xJVEVSQUxfTE9OR19RVU9URVMxXCI6IFwiJycnXCIsXG4vL1x0XHRcIlNUUklOR19MSVRFUkFMX0xPTkdfUVVPVEVTMlwiOiAnXCJcIlwiJyxcbi8vXHR9XG4vL1x0dmFyIFNUUklOR19MSVRFUkFMX0xPTkdfQ09OVEVOVFMgPSB7XG4vL1x0XHRcIlNUUklOR19MSVRFUkFMX0xPTkdfUVVPVEVTMVwiOiBcIigoJ3wnJyk/KFteJ1xcXFxcXFxcXXxcIitFQ0hBUitcInxcIit1bmljb2RlK1wiKSkqXCIsXG4vL1x0XHRcIlNUUklOR19MSVRFUkFMX0xPTkdfUVVPVEVTMlwiOiAnKChcInxcIlwiKT8oW15cIlxcXFxcXFxcXXwnK0VDSEFSKyd8Jyt1bmljb2RlKycpKSonXG4vL1x0fTtcbi8vXHR2YXIgU1RSSU5HX0xJVEVSQUxfTE9ORzEgPSBTVFJJTkdfTElURVJBTF9MT05HWydTSU5HTEUnXS5RVU9URVMgKyBTVFJJTkdfTElURVJBTF9MT05HWydTSU5HTEUnXS5DT05URU5UUyArIFNUUklOR19MSVRFUkFMX0xPTkdbJ1NJTkdMRSddLlFVT1RFUztcbi8vXHR2YXIgU1RSSU5HX0xJVEVSQUxfTE9ORzIgPSBTVFJJTkdfTElURVJBTF9MT05HWydET1VCTEUnXS5RVU9URVMgKyBTVFJJTkdfTElURVJBTF9MT05HWydET1VCTEUnXS5DT05URU5UUyArIFNUUklOR19MSVRFUkFMX0xPTkdbJ0RPVUJMRSddLlFVT1RFUztcblx0XG4vL1x0dmFyIHN0cmluZ0xpdGVyYWxMb25nQ29udGVudFRlcm1pbmFscyA9IHt9O1xuLy9cdGZvciAodmFyIGtleSBpbiBTVFJJTkdfTElURVJBTF9MT05HKSB7XG4vL1x0XHRzdHJpbmdMaXRlcmFsTG9uZ0NvbnRlbnRUZXJtaW5hbHNba2V5XSA9IHtcbi8vXHRcdFx0bmFtZToga2V5LFxuLy9cdFx0XHRyZWdleDpuZXcgUmVnRXhwKFwiXlwiK1NUUklOR19MSVRFUkFMX0xPTkdfQ09OVEVOVFNba2V5XSksXG4vL1x0XHRcdHN0eWxlOlwic3RyaW5nXCJcbi8vXHRcdH07XG4vL1x0fVxuXHQvL3NvbWUgcmVndWxhciBleHByZXNzaW9ucyBub3QgdXNlZCBpbiByZWd1bGFyIHRlcm1pbmFscywgYmVjYXVzZSB0aGlzIGlzIHVzZWQgYWNjcm9zcyBsaW5lc1xuXHR2YXIgc3RyaW5nTGl0ZXJhbExvbmdSZWdleCA9IHt9O1xuXHRmb3IgKHZhciBrZXkgaW4gU1RSSU5HX0xJVEVSQUxfTE9ORykge1xuXHRcdHN0cmluZ0xpdGVyYWxMb25nUmVnZXhba2V5XSA9IHtcblx0XHRcdGNvbXBsZXRlOiB7XG5cdFx0XHRcdG5hbWU6IFwiU1RSSU5HX0xJVEVSQUxfTE9OR19cIiArIGtleSxcblx0XHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitTVFJJTkdfTElURVJBTF9MT05HW2tleV0uQ09NUExFVEUpLFxuXHRcdFx0XHRzdHlsZTpcInN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFx0Y29udGVudHM6IHtcblx0XHRcdFx0bmFtZTogXCJTVFJJTkdfTElURVJBTF9MT05HX1wiICsga2V5LFxuXHRcdFx0XHRyZWdleDpuZXcgUmVnRXhwKFwiXlwiK1NUUklOR19MSVRFUkFMX0xPTkdba2V5XS5DT05URU5UUyksXG5cdFx0XHRcdHN0eWxlOlwic3RyaW5nXCJcblx0XHRcdH0sXG5cdFx0XHRjbG9zaW5nOiB7XG5cdFx0XHRcdG5hbWU6IFwiU1RSSU5HX0xJVEVSQUxfTE9OR19cIiArIGtleSxcblx0XHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitTVFJJTkdfTElURVJBTF9MT05HW2tleV0uQ09OVEVOVFMgKyBTVFJJTkdfTElURVJBTF9MT05HW2tleV0uUVVPVEVTKSxcblx0XHRcdFx0c3R5bGU6XCJzdHJpbmdcIlxuXHRcdFx0fSxcblx0XHRcdHF1b3Rlczoge1xuXHRcdFx0XHRuYW1lOiBcIlNUUklOR19MSVRFUkFMX0xPTkdfUVVPVEVTX1wiICsga2V5LFxuXHRcdFx0XHRyZWdleDpuZXcgUmVnRXhwKFwiXlwiK1NUUklOR19MSVRFUkFMX0xPTkdba2V5XS5RVU9URVMpLFxuXHRcdFx0XHRzdHlsZTpcInN0cmluZ1wiXG5cdFx0XHR9LFxuXHRcdFxuXHRcdH1cblx0fVxuXHRcblx0dmFyIFdTICAgID0gICAgICAgICdbXFxcXHgyMFxcXFx4MDlcXFxceDBEXFxcXHgwQV0nO1xuXHQvLyBDYXJlZnVsISBDb2RlIG1pcnJvciBmZWVkcyBvbmUgbGluZSBhdCBhIHRpbWUgd2l0aCBubyBcXG5cblx0Ly8gLi4uIGJ1dCBvdGhlcndpc2UgY29tbWVudCBpcyB0ZXJtaW5hdGVkIGJ5IFxcblxuXHR2YXIgQ09NTUVOVCA9ICcjKFteXFxcXG5cXFxccl0qW1xcXFxuXFxcXHJdfFteXFxcXG5cXFxccl0qJCknO1xuXHR2YXIgV1NfT1JfQ09NTUVOVF9TVEFSID0gJygnK1dTKyd8KCcrQ09NTUVOVCsnKSkqJztcblx0dmFyIE5JTCAgID0gJ1xcXFwoJytXU19PUl9DT01NRU5UX1NUQVIrJ1xcXFwpJztcblx0dmFyIEFOT04gID0gJ1xcXFxbJytXU19PUl9DT01NRU5UX1NUQVIrJ1xcXFxdJztcblx0dmFyIHRlcm1pbmFscz0gW1xuXHRcdHsgbmFtZTogXCJXU1wiLFxuXHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitXUytcIitcIiksXG5cdFx0XHRzdHlsZTpcIndzXCIgfSxcblxuXHRcdHsgbmFtZTogXCJDT01NRU5UXCIsXG5cdFx0XHRyZWdleDpuZXcgUmVnRXhwKFwiXlwiK0NPTU1FTlQpLFxuXHRcdFx0c3R5bGU6XCJjb21tZW50XCIgfSxcblxuXHRcdHsgbmFtZTogXCJJUklfUkVGXCIsXG5cdFx0XHRyZWdleDpuZXcgUmVnRXhwKFwiXlwiK0lSSV9SRUYpLFxuXHRcdFx0c3R5bGU6XCJ2YXJpYWJsZS0zXCIgfSxcblxuXHRcdHsgbmFtZTogXCJWQVIxXCIsXG5cdFx0XHRyZWdleDpuZXcgUmVnRXhwKFwiXlwiK1ZBUjEpLFxuXHRcdFx0c3R5bGU6XCJhdG9tXCJ9LFxuXG5cdFx0eyBuYW1lOiBcIlZBUjJcIixcblx0XHRcdHJlZ2V4Om5ldyBSZWdFeHAoXCJeXCIrVkFSMiksXG5cdFx0XHRzdHlsZTpcImF0b21cIn0sXG5cblx0XHR7IG5hbWU6IFwiTEFOR1RBR1wiLFxuXHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitMQU5HVEFHKSxcblx0XHRcdHN0eWxlOlwibWV0YVwifSxcblxuXHRcdHsgbmFtZTogXCJET1VCTEVcIixcblx0XHRcdHJlZ2V4Om5ldyBSZWdFeHAoXCJeXCIrRE9VQkxFKSxcblx0XHRcdHN0eWxlOlwibnVtYmVyXCIgfSxcblxuXHRcdHsgbmFtZTogXCJERUNJTUFMXCIsXG5cdFx0XHRyZWdleDpuZXcgUmVnRXhwKFwiXlwiK0RFQ0lNQUwpLFxuXHRcdFx0c3R5bGU6XCJudW1iZXJcIiB9LFxuXG5cdFx0eyBuYW1lOiBcIklOVEVHRVJcIixcblx0XHRcdHJlZ2V4Om5ldyBSZWdFeHAoXCJeXCIrSU5URUdFUiksXG5cdFx0XHRzdHlsZTpcIm51bWJlclwiIH0sXG5cblx0XHR7IG5hbWU6IFwiRE9VQkxFX1BPU0lUSVZFXCIsXG5cdFx0XHRyZWdleDpuZXcgUmVnRXhwKFwiXlwiK0RPVUJMRV9QT1NJVElWRSksXG5cdFx0XHRzdHlsZTpcIm51bWJlclwiIH0sXG5cblx0XHR7IG5hbWU6IFwiREVDSU1BTF9QT1NJVElWRVwiLFxuXHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitERUNJTUFMX1BPU0lUSVZFKSxcblx0XHRcdHN0eWxlOlwibnVtYmVyXCIgfSxcblxuXHRcdHsgbmFtZTogXCJJTlRFR0VSX1BPU0lUSVZFXCIsXG5cdFx0XHRyZWdleDpuZXcgUmVnRXhwKFwiXlwiK0lOVEVHRVJfUE9TSVRJVkUpLFxuXHRcdFx0c3R5bGU6XCJudW1iZXJcIiB9LFxuXG5cdFx0eyBuYW1lOiBcIkRPVUJMRV9ORUdBVElWRVwiLFxuXHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitET1VCTEVfTkVHQVRJVkUpLFxuXHRcdFx0c3R5bGU6XCJudW1iZXJcIiB9LFxuXG5cdFx0eyBuYW1lOiBcIkRFQ0lNQUxfTkVHQVRJVkVcIixcblx0XHRcdHJlZ2V4Om5ldyBSZWdFeHAoXCJeXCIrREVDSU1BTF9ORUdBVElWRSksXG5cdFx0XHRzdHlsZTpcIm51bWJlclwiIH0sXG5cblx0XHR7IG5hbWU6IFwiSU5URUdFUl9ORUdBVElWRVwiLFxuXHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitJTlRFR0VSX05FR0FUSVZFKSxcblx0XHRcdHN0eWxlOlwibnVtYmVyXCIgfSxcbi8vXHRcdHN0cmluZ0xpdGVyYWxMb25nUmVnZXguU0lOR0xFLmNvbXBsZXRlLFxuLy9cdFx0c3RyaW5nTGl0ZXJhbExvbmdSZWdleC5ET1VCTEUuY29tcGxldGUsXG4vL1x0XHRzdHJpbmdMaXRlcmFsTG9uZ1JlZ2V4LlNJTkdMRS5xdW90ZXMsXG4vL1x0XHRzdHJpbmdMaXRlcmFsTG9uZ1JlZ2V4LkRPVUJMRS5xdW90ZXMsXG5cdFx0XG5cdFx0eyBuYW1lOiBcIlNUUklOR19MSVRFUkFMMVwiLFxuXHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitTVFJJTkdfTElURVJBTDEpLFxuXHRcdFx0c3R5bGU6XCJzdHJpbmdcIiB9LFxuXG5cdFx0eyBuYW1lOiBcIlNUUklOR19MSVRFUkFMMlwiLFxuXHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitTVFJJTkdfTElURVJBTDIpLFxuXHRcdFx0c3R5bGU6XCJzdHJpbmdcIiB9LFxuXG5cdFx0Ly8gRW5jbG9zZWQgY29tbWVudHMgd29uJ3QgYmUgaGlnaGxpZ2h0ZWRcblx0XHR7IG5hbWU6IFwiTklMXCIsXG5cdFx0XHRyZWdleDpuZXcgUmVnRXhwKFwiXlwiK05JTCksXG5cdFx0XHRzdHlsZTpcInB1bmNcIiB9LFxuXG5cdFx0Ly8gRW5jbG9zZWQgY29tbWVudHMgd29uJ3QgYmUgaGlnaGxpZ2h0ZWRcblx0XHR7IG5hbWU6IFwiQU5PTlwiLFxuXHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitBTk9OKSxcblx0XHRcdHN0eWxlOlwicHVuY1wiIH0sXG5cblx0XHR7IG5hbWU6IFwiUE5BTUVfTE5cIixcblx0XHRcdHJlZ2V4Om5ldyBSZWdFeHAoXCJeXCIrUE5BTUVfTE4pLFxuXHRcdFx0c3R5bGU6XCJzdHJpbmctMlwiIH0sXG5cblx0XHR7IG5hbWU6IFwiUE5BTUVfTlNcIixcblx0XHRcdHJlZ2V4Om5ldyBSZWdFeHAoXCJeXCIrUE5BTUVfTlMpLFxuXHRcdFx0c3R5bGU6XCJzdHJpbmctMlwiIH0sXG5cblx0XHR7IG5hbWU6IFwiQkxBTktfTk9ERV9MQUJFTFwiLFxuXHRcdFx0cmVnZXg6bmV3IFJlZ0V4cChcIl5cIitCTEFOS19OT0RFX0xBQkVMKSxcblx0XHRcdHN0eWxlOlwic3RyaW5nLTJcIiB9XG5cdF07XG5cblx0ZnVuY3Rpb24gZ2V0UG9zc2libGVzKHN5bWJvbCkge1xuXHRcdHZhciBwb3NzaWJsZXM9W10sIHBvc3NpYmxlc09iPWxsMV90YWJsZVtzeW1ib2xdO1xuXHRcdGlmIChwb3NzaWJsZXNPYiE9dW5kZWZpbmVkKSB7XG5cdFx0XHRmb3IgKHZhciBwcm9wZXJ0eSBpbiBwb3NzaWJsZXNPYikge1xuXHRcdFx0XHRwb3NzaWJsZXMucHVzaChwcm9wZXJ0eS50b1N0cmluZygpKTtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0cG9zc2libGVzLnB1c2goc3ltYm9sKTtcblx0XHR9XG5cdFx0cmV0dXJuIHBvc3NpYmxlcztcblx0fVxuXG5cblx0ZnVuY3Rpb24gdG9rZW5CYXNlKHN0cmVhbSwgc3RhdGUpIHtcblxuXHRcdGZ1bmN0aW9uIG5leHRUb2tlbigpIHtcblx0XHRcdHZhciBjb25zdW1lZD1udWxsO1xuXHRcdFx0aWYgKHN0YXRlLmluTGl0ZXJhbCkge1xuXHRcdFx0XHRcblx0XHRcdFx0dmFyIGNsb3NpbmdRdW90ZXMgPSBmYWxzZTtcblx0XHRcdFx0Ly9tdWx0aS1saW5lIGxpdGVyYWwuIHRyeSB0byBwYXJzZSBjb250ZW50cy5cblx0XHRcdFx0Y29uc3VtZWQgPSBzdHJlYW0ubWF0Y2goc3RyaW5nTGl0ZXJhbExvbmdSZWdleFtzdGF0ZS5pbkxpdGVyYWxdLmNvbnRlbnRzLnJlZ2V4LCB0cnVlLCBmYWxzZSk7XG5cdFx0XHRcdGlmIChjb25zdW1lZCAmJiBjb25zdW1lZFswXS5sZW5ndGggPT0gMCkge1xuXHRcdFx0XHRcdC8vdHJ5IHNlZWluZyB3aGV0aGVyIHdlIGNhbiBjb25zdW1lIGNsb3NpbmcgcXVvdGVzLCB0byBhdm9pZCBzdG9wcGluZ1xuXHRcdFx0XHRcdGNvbnN1bWVkID0gc3RyZWFtLm1hdGNoKHN0cmluZ0xpdGVyYWxMb25nUmVnZXhbc3RhdGUuaW5MaXRlcmFsXS5jbG9zaW5nLnJlZ2V4LCB0cnVlLCBmYWxzZSk7XG5cdFx0XHRcdFx0Y2xvc2luZ1F1b3RlcyA9IHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdFx0XG5cdFx0XHRcdGlmIChjb25zdW1lZCAmJiBjb25zdW1lZFswXS5sZW5ndGggPiAwKSB7XG5cdFx0XHRcdFx0Ly9zb21lIHN0cmluZyBjb250ZW50IGhlcmUuIFxuXHRcdFx0XHRcdCB2YXIgcmV0dXJuT2JqID0ge1xuXHRcdFx0XHRcdFx0cXVvdGVQb3M6IChjbG9zaW5nUXVvdGVzPyAnZW5kJzogJ2NvbnRlbnQnKSxcblx0XHRcdFx0XHRcdGNhdDogU1RSSU5HX0xJVEVSQUxfTE9OR1tzdGF0ZS5pbkxpdGVyYWxdLkNBVCxcblx0XHRcdFx0XHRcdHN0eWxlOiBzdHJpbmdMaXRlcmFsTG9uZ1JlZ2V4W3N0YXRlLmluTGl0ZXJhbF0uY29tcGxldGUuc3R5bGUsXG5cdFx0XHRcdFx0XHR0ZXh0OiBjb25zdW1lZFswXSxcblx0XHRcdFx0XHRcdHN0YXJ0OiBzdHJlYW0uc3RhcnRcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdCBpZiAoY2xvc2luZ1F1b3Rlcykgc3RhdGUuaW5MaXRlcmFsID0gZmFsc2U7XG5cdFx0XHRcdFx0IHJldHVybiByZXR1cm5PYmo7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdFxuXHRcdFx0Ly9NdWx0aWxpbmUgbGl0ZXJhbHNcblx0XHRcdGZvciAodmFyIHF1b3RlVHlwZSBpbiBzdHJpbmdMaXRlcmFsTG9uZ1JlZ2V4KSB7XG5cdFx0XHRcdGNvbnN1bWVkPSBzdHJlYW0ubWF0Y2goc3RyaW5nTGl0ZXJhbExvbmdSZWdleFtxdW90ZVR5cGVdLnF1b3Rlcy5yZWdleCx0cnVlLGZhbHNlKTtcblx0XHRcdFx0aWYgKGNvbnN1bWVkKSB7XG5cdFx0XHRcdFx0dmFyIHF1b3RlUG9zO1xuXHRcdFx0XHRcdGlmIChzdGF0ZS5pbkxpdGVyYWwpIHtcblx0XHRcdFx0XHRcdC8vZW5kIG9mIGxpdGVyYWwuIGV2ZXJ5dGhpbmcgaXMgZmluZVxuXHRcdFx0XHRcdFx0c3RhdGUuaW5MaXRlcmFsID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRxdW90ZVBvcyA9ICdlbmQnO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRzdGF0ZS5pbkxpdGVyYWwgPSBxdW90ZVR5cGU7XG5cdFx0XHRcdFx0XHRxdW90ZVBvcyA9ICdzdGFydCc7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRjYXQ6IFNUUklOR19MSVRFUkFMX0xPTkdbcXVvdGVUeXBlXS5DQVQsXG5cdFx0XHRcdFx0XHRzdHlsZTogc3RyaW5nTGl0ZXJhbExvbmdSZWdleFtxdW90ZVR5cGVdLnF1b3Rlcy5zdHlsZSxcblx0XHRcdFx0XHRcdHRleHQ6IGNvbnN1bWVkWzBdLFxuXHRcdFx0XHRcdFx0cXVvdGVQb3M6IHF1b3RlUG9zLFxuXHRcdFx0XHRcdFx0c3RhcnQ6IHN0cmVhbS5zdGFydFxuXHRcdFx0XHRcdH07XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdFxuXHRcdFx0XG5cdFx0XHRcblx0XHRcdC8vIFRva2VucyBkZWZpbmVkIGJ5IGluZGl2aWR1YWwgcmVndWxhciBleHByZXNzaW9uc1xuXHRcdFx0Zm9yICh2YXIgaT0wOyBpPHRlcm1pbmFscy5sZW5ndGg7ICsraSkge1xuXHRcdFx0XHRjb25zdW1lZD0gc3RyZWFtLm1hdGNoKHRlcm1pbmFsc1tpXS5yZWdleCx0cnVlLGZhbHNlKTtcblx0XHRcdFx0aWYgKGNvbnN1bWVkKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdGNhdDogdGVybWluYWxzW2ldLm5hbWUsXG5cdFx0XHRcdFx0XHRzdHlsZTogdGVybWluYWxzW2ldLnN0eWxlLFxuXHRcdFx0XHRcdFx0dGV4dDogY29uc3VtZWRbMF0sXG5cdFx0XHRcdFx0XHRzdGFydDogc3RyZWFtLnN0YXJ0XG5cdFx0XHRcdFx0fTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBLZXl3b3Jkc1xuXHRcdFx0Y29uc3VtZWQ9IHN0cmVhbS5tYXRjaChncmFtbWFyLmtleXdvcmRzLHRydWUsZmFsc2UpO1xuXHRcdFx0aWYgKGNvbnN1bWVkKVxuXHRcdFx0XHRyZXR1cm4geyBjYXQ6IHN0cmVhbS5jdXJyZW50KCkudG9VcHBlckNhc2UoKSxcblx0XHRcdFx0XHRcdFx0XHQgc3R5bGU6IFwia2V5d29yZFwiLFxuXHRcdFx0XHRcdFx0XHRcdCB0ZXh0OiBjb25zdW1lZFswXSxcblx0XHRcdFx0XHRcdFx0XHQgc3RhcnQ6IHN0cmVhbS5zdGFydFxuXHRcdFx0XHRcdFx0XHQgfTtcblxuXHRcdFx0Ly8gUHVuY3R1YXRpb25cblx0XHRcdGNvbnN1bWVkPSBzdHJlYW0ubWF0Y2goZ3JhbW1hci5wdW5jdCx0cnVlLGZhbHNlKTtcblx0XHRcdGlmIChjb25zdW1lZClcblx0XHRcdFx0cmV0dXJuIHsgY2F0OiBzdHJlYW0uY3VycmVudCgpLFxuXHRcdFx0XHRcdFx0XHRcdCBzdHlsZTogXCJwdW5jXCIsXG5cdFx0XHRcdFx0XHRcdFx0IHRleHQ6IGNvbnN1bWVkWzBdLFxuXHRcdFx0XHRcdFx0XHRcdCBzdGFydDogc3RyZWFtLnN0YXJ0XG5cdFx0XHRcdFx0XHRcdCB9O1xuXG5cdFx0XHQvLyBUb2tlbiBpcyBpbnZhbGlkXG5cdFx0XHQvLyBiZXR0ZXIgY29uc3VtZSBzb21ldGhpbmcgYW55d2F5LCBvciBlbHNlIHdlJ3JlIHN0dWNrXG5cdFx0XHRjb25zdW1lZD0gc3RyZWFtLm1hdGNoKC9eLltBLVphLXowLTldKi8sdHJ1ZSxmYWxzZSk7XG5cdFx0XHRyZXR1cm4geyBjYXQ6XCI8aW52YWxpZF90b2tlbj5cIixcblx0XHRcdFx0XHRcdFx0IHN0eWxlOiBcImVycm9yXCIsXG5cdFx0XHRcdFx0XHRcdCB0ZXh0OiBjb25zdW1lZFswXSxcblx0XHRcdFx0XHRcdFx0IHN0YXJ0OiBzdHJlYW0uc3RhcnRcblx0XHRcdFx0XHRcdCB9O1xuXHRcdH1cblxuXHRcdGZ1bmN0aW9uIHJlY29yZEZhaWx1cmVQb3MoKSB7XG5cdFx0XHQvLyB0b2tlbk9iLnN0eWxlPSBcInNwLWludmFsaWRcIjtcblx0XHRcdHZhciBjb2w9IHN0cmVhbS5jb2x1bW4oKTtcblx0XHRcdHN0YXRlLmVycm9yU3RhcnRQb3M9IGNvbDtcblx0XHRcdHN0YXRlLmVycm9yRW5kUG9zPSBjb2wrdG9rZW5PYi50ZXh0Lmxlbmd0aDtcblx0XHR9O1xuXG5cdFx0ZnVuY3Rpb24gc2V0UXVlcnlUeXBlKHMpIHtcblx0XHRcdGlmIChzdGF0ZS5xdWVyeVR5cGU9PW51bGwpIHtcblx0XHRcdFx0aWYgKHMgPT1cIlNFTEVDVFwiIHx8IHM9PVwiQ09OU1RSVUNUXCIgfHwgcz09XCJBU0tcIiB8fCBzPT1cIkRFU0NSSUJFXCIgfHwgcz09XCJJTlNFUlRcIiB8fCBzPT1cIkRFTEVURVwiIHx8IHM9PVwiTE9BRFwiIHx8IHM9PVwiQ0xFQVJcIiB8fCBzPT1cIkNSRUFURVwiIHx8IHM9PVwiRFJPUFwiIHx8IHM9PVwiQ09QWVwiIHx8IHM9PVwiTU9WRVwiIHx8IHM9PVwiQUREXCIpXG5cdFx0XHRcdFx0c3RhdGUucXVlcnlUeXBlPXM7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU29tZSBmYWtlIG5vbi10ZXJtaW5hbHMgYXJlIGp1c3QgdGhlcmUgdG8gaGF2ZSBzaWRlLWVmZmVjdCBvbiBzdGF0ZVxuXHRcdC8vIC0gaS5lLiBhbGxvdyBvciBkaXNhbGxvdyB2YXJpYWJsZXMgYW5kIGJub2RlcyBpbiBjZXJ0YWluIG5vbi1uZXN0aW5nXG5cdFx0Ly8gY29udGV4dHNcblx0XHRmdW5jdGlvbiBzZXRTaWRlQ29uZGl0aW9ucyh0b3BTeW1ib2wpIHtcblx0XHRcdGlmICh0b3BTeW1ib2w9PVwiZGlzYWxsb3dWYXJzXCIpIHN0YXRlLmFsbG93VmFycz1mYWxzZTtcblx0XHRcdGVsc2UgaWYgKHRvcFN5bWJvbD09XCJhbGxvd1ZhcnNcIikgc3RhdGUuYWxsb3dWYXJzPXRydWU7XG5cdFx0XHRlbHNlIGlmICh0b3BTeW1ib2w9PVwiZGlzYWxsb3dCbm9kZXNcIikgc3RhdGUuYWxsb3dCbm9kZXM9ZmFsc2U7XG5cdFx0XHRlbHNlIGlmICh0b3BTeW1ib2w9PVwiYWxsb3dCbm9kZXNcIikgc3RhdGUuYWxsb3dCbm9kZXM9dHJ1ZTtcblx0XHRcdGVsc2UgaWYgKHRvcFN5bWJvbD09XCJzdG9yZVByb3BlcnR5XCIpIHN0YXRlLnN0b3JlUHJvcGVydHk9dHJ1ZTtcblx0XHR9XG5cblx0XHRmdW5jdGlvbiBjaGVja1NpZGVDb25kaXRpb25zKHRvcFN5bWJvbCkge1xuXHRcdFx0cmV0dXJuKFxuXHRcdFx0XHQoc3RhdGUuYWxsb3dWYXJzIHx8IHRvcFN5bWJvbCE9XCJ2YXJcIikgJiZcblx0XHRcdFx0XHQoc3RhdGUuYWxsb3dCbm9kZXMgfHxcblx0XHRcdFx0XHQgKHRvcFN5bWJvbCE9XCJibGFua05vZGVcIiAmJlxuXHRcdFx0XHRcdFx0dG9wU3ltYm9sIT1cImJsYW5rTm9kZVByb3BlcnR5TGlzdFwiICYmXG5cdFx0XHRcdFx0XHR0b3BTeW1ib2whPVwiYmxhbmtOb2RlUHJvcGVydHlMaXN0UGF0aFwiKSkpO1xuXHRcdH1cblxuXHRcdC8vIENvZGVNaXJyb3Igd29ya3Mgd2l0aCBvbmUgbGluZSBhdCBhIHRpbWUsXG5cdFx0Ly8gYnV0IG5ld2xpbmUgc2hvdWxkIGJlaGF2ZSBsaWtlIHdoaXRlc3BhY2Vcblx0XHQvLyAtIGkuZS4gYSBkZWZpbml0ZSBicmVhayBiZXR3ZWVuIHRva2VucyAoZm9yIGF1dG9jb21wbGV0ZXIpXG5cdFx0aWYgKHN0cmVhbS5wb3M9PTApXG5cdFx0XHRzdGF0ZS5wb3NzaWJsZUN1cnJlbnQ9IHN0YXRlLnBvc3NpYmxlTmV4dDtcblxuXHRcdHZhciB0b2tlbk9iPSBuZXh0VG9rZW4oKTtcblxuXG5cdFx0aWYgKHRva2VuT2IuY2F0PT1cIjxpbnZhbGlkX3Rva2VuPlwiKSB7XG5cdFx0XHQvLyBzZXQgZXJyb3Igc3RhdGUsIGFuZFxuXHRcdFx0aWYgKHN0YXRlLk9LPT10cnVlKSB7XG5cdFx0XHRcdHN0YXRlLk9LPWZhbHNlO1xuXHRcdFx0XHRyZWNvcmRGYWlsdXJlUG9zKCk7XG5cdFx0XHR9XG5cdFx0XHRzdGF0ZS5jb21wbGV0ZT1mYWxzZTtcblx0XHRcdC8vIGFsZXJ0KFwiSW52YWxpZDpcIit0b2tlbk9iLnRleHQpO1xuXHRcdFx0cmV0dXJuIHRva2VuT2Iuc3R5bGU7XG5cdFx0fVxuXG5cdFx0aWYgKHRva2VuT2IuY2F0ID09IFwiV1NcIiB8fCB0b2tlbk9iLmNhdCA9PSBcIkNPTU1FTlRcIiB8fCAodG9rZW5PYi5xdW90ZVBvcyAmJiB0b2tlbk9iLnF1b3RlUG9zICE9ICdlbmQnKSkge1xuXHRcdFx0c3RhdGUucG9zc2libGVDdXJyZW50ID0gc3RhdGUucG9zc2libGVOZXh0O1xuXHRcdFx0cmV0dXJuKHRva2VuT2Iuc3R5bGUpO1xuXHRcdH1cblx0XHQvLyBPdGhlcndpc2UsIHJ1biB0aGUgcGFyc2VyIHVudGlsIHRoZSB0b2tlbiBpcyBkaWdlc3RlZFxuXHRcdC8vIG9yIGZhaWx1cmVcblx0XHR2YXIgZmluaXNoZWQ9IGZhbHNlO1xuXHRcdHZhciB0b3BTeW1ib2w7XG5cdFx0dmFyIHRva2VuPSB0b2tlbk9iLmNhdDtcblx0XHRcblx0XHRpZiAoIXRva2VuT2IucXVvdGVQb3MgfHwgdG9rZW5PYi5xdW90ZVBvcyA9PSAnZW5kJykge1xuXHRcdC8vIEluY3JlbWVudGFsIExMMSBwYXJzZVxuXHRcdFx0d2hpbGUoc3RhdGUuc3RhY2subGVuZ3RoPjAgJiYgdG9rZW4gJiYgc3RhdGUuT0sgJiYgIWZpbmlzaGVkICkge1xuXHRcdFx0XHR0b3BTeW1ib2w9IHN0YXRlLnN0YWNrLnBvcCgpO1xuXHRcblx0XHRcdFx0aWYgKCFsbDFfdGFibGVbdG9wU3ltYm9sXSkge1xuXHRcdFx0XHRcdC8vIFRvcCBzeW1ib2wgaXMgYSB0ZXJtaW5hbFxuXHRcdFx0XHRcdGlmICh0b3BTeW1ib2wgPT0gdG9rZW4pIHtcblx0XHRcdFx0XHRcdC8vIE1hdGNoaW5nIHRlcm1pbmFsc1xuXHRcdFx0XHRcdFx0Ly8gLSBjb25zdW1lIHRva2VuIGZyb20gaW5wdXQgc3RyZWFtXG5cdFx0XHRcdFx0XHRmaW5pc2hlZD10cnVlO1xuXHRcdFx0XHRcdFx0c2V0UXVlcnlUeXBlKHRvcFN5bWJvbCk7XG5cdFx0XHRcdFx0XHQvLyBDaGVjayB3aGV0aGVyICQgKGVuZCBvZiBpbnB1dCB0b2tlbikgaXMgcG9zcyBuZXh0XG5cdFx0XHRcdFx0XHQvLyBmb3IgZXZlcnl0aGluZyBvbiBzdGFja1xuXHRcdFx0XHRcdFx0dmFyIGFsbE5pbGxhYmxlPXRydWU7XG5cdFx0XHRcdFx0XHRmb3IodmFyIHNwPXN0YXRlLnN0YWNrLmxlbmd0aDtzcD4wOy0tc3ApIHtcblx0XHRcdFx0XHRcdFx0dmFyIGl0ZW09bGwxX3RhYmxlW3N0YXRlLnN0YWNrW3NwLTFdXTtcblx0XHRcdFx0XHRcdFx0aWYgKCFpdGVtIHx8ICFpdGVtW1wiJFwiXSlcblx0XHRcdFx0XHRcdFx0XHRhbGxOaWxsYWJsZT1mYWxzZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdHN0YXRlLmNvbXBsZXRlPSBhbGxOaWxsYWJsZTtcblx0XHRcdFx0XHRcdGlmIChzdGF0ZS5zdG9yZVByb3BlcnR5ICYmIHRva2VuLmNhdCAhPSBcInB1bmNcIikge1xuXHRcdFx0XHRcdFx0XHRzdGF0ZS5sYXN0UHJvcGVydHkgPSB0b2tlbk9iLnRleHQ7XG5cdFx0XHRcdFx0XHRcdHN0YXRlLnN0b3JlUHJvcGVydHkgPSBmYWxzZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0c3RhdGUuT0s9ZmFsc2U7XG5cdFx0XHRcdFx0XHRzdGF0ZS5jb21wbGV0ZT1mYWxzZTtcblx0XHRcdFx0XHRcdHJlY29yZEZhaWx1cmVQb3MoKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly8gdG9wU3ltYm9sIGlzIG5vbnRlcm1pbmFsXG5cdFx0XHRcdFx0Ly8gLSBzZWUgaWYgdGhlcmUgaXMgYW4gZW50cnkgZm9yIHRvcFN5bWJvbFxuXHRcdFx0XHRcdC8vIGFuZCBuZXh0VG9rZW4gaW4gdGFibGVcblx0XHRcdFx0XHR2YXIgbmV4dFN5bWJvbHM9IGxsMV90YWJsZVt0b3BTeW1ib2xdW3Rva2VuXTtcblx0XHRcdFx0XHRpZiAobmV4dFN5bWJvbHMhPXVuZGVmaW5lZCAmJiBjaGVja1NpZGVDb25kaXRpb25zKHRvcFN5bWJvbCkpIHtcblx0XHRcdFx0XHRcdC8vIE1hdGNoIC0gY29weSBSSFMgb2YgcnVsZSB0byBzdGFja1xuXHRcdFx0XHRcdFx0Zm9yICh2YXIgaT1uZXh0U3ltYm9scy5sZW5ndGgtMTsgaT49MDsgLS1pKSB7XG5cdFx0XHRcdFx0XHRcdHN0YXRlLnN0YWNrLnB1c2gobmV4dFN5bWJvbHNbaV0pO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0Ly8gUGVmb3JtIGFueSBub24tZ3JhbW1hdGljYWwgc2lkZS1lZmZlY3RzXG5cdFx0XHRcdFx0XHRzZXRTaWRlQ29uZGl0aW9ucyh0b3BTeW1ib2wpO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHQvLyBObyBtYXRjaCBpbiB0YWJsZSAtIGZhaWxcblx0XHRcdFx0XHRcdHN0YXRlLk9LPWZhbHNlO1xuXHRcdFx0XHRcdFx0c3RhdGUuY29tcGxldGU9ZmFsc2U7XG5cdFx0XHRcdFx0XHRyZWNvcmRGYWlsdXJlUG9zKCk7XG5cdFx0XHRcdFx0XHRzdGF0ZS5zdGFjay5wdXNoKHRvcFN5bWJvbCk7ICAvLyBTaG92ZSB0b3BTeW1ib2wgYmFjayBvbiBzdGFja1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRpZiAoIWZpbmlzaGVkICYmIHN0YXRlLk9LKSB7IFxuXHRcdFx0c3RhdGUuT0s9ZmFsc2U7IHN0YXRlLmNvbXBsZXRlPWZhbHNlOyByZWNvcmRGYWlsdXJlUG9zKCk7IFxuXHRcdH1cblx0XHRcblx0XHRpZiAoc3RhdGUucG9zc2libGVDdXJyZW50LmluZGV4T2YoJ2EnKSA+PSAwKXtcblx0XHRcdHN0YXRlLmxhc3RQcmVkaWNhdGVPZmZzZXQgPSB0b2tlbk9iLnN0YXJ0O1xuXHRcdH1cblx0XHRzdGF0ZS5wb3NzaWJsZUN1cnJlbnQgPSBzdGF0ZS5wb3NzaWJsZU5leHQ7XG5cdFx0XG5cdFx0c3RhdGUucG9zc2libGVOZXh0ID0gZ2V0UG9zc2libGVzKHN0YXRlLnN0YWNrW3N0YXRlLnN0YWNrLmxlbmd0aC0xXSk7XG5cblx0XHRyZXR1cm4gdG9rZW5PYi5zdHlsZTtcblx0fVxuXG5cdHZhciBpbmRlbnRUb3A9e1xuXHRcdFwiKlssLCBvYmplY3RdXCI6IDMsXG5cdFx0XCIqWygsKSxvYmplY3RdXCI6IDMsXG5cdFx0XCIqWygsKSxvYmplY3RQYXRoXVwiOiAzLFxuXHRcdFwiKlsvLHBhdGhFbHRPckludmVyc2VdXCI6IDIsXG5cdFx0XCJvYmplY3RcIjogMixcblx0XHRcIm9iamVjdFBhdGhcIjogMixcblx0XHRcIm9iamVjdExpc3RcIjogMixcblx0XHRcIm9iamVjdExpc3RQYXRoXCI6IDIsXG5cdFx0XCJzdG9yZVByb3BlcnR5XCI6IDIsXG5cdFx0XCJwYXRoTW9kXCI6IDIsXG5cdFx0XCI/cGF0aE1vZFwiOiAyLFxuXHRcdFwicHJvcGVydHlMaXN0Tm90RW1wdHlcIjogMSxcblx0XHRcInByb3BlcnR5TGlzdFwiOiAxLFxuXHRcdFwicHJvcGVydHlMaXN0UGF0aFwiOiAxLFxuXHRcdFwicHJvcGVydHlMaXN0UGF0aE5vdEVtcHR5XCI6IDEsXG5cdFx0XCI/W3ZlcmIsb2JqZWN0TGlzdF1cIjogMSxcbi8vXHRcdFwiP1tvcihbdmVyYlBhdGgsIHZlcmJTaW1wbGVdKSxvYmplY3RMaXN0XVwiOiAxLFxuXHR9O1xuXG5cdHZhciBpbmRlbnRUYWJsZT17XG5cdFx0XCJ9XCI6MSxcblx0XHRcIl1cIjowLFxuXHRcdFwiKVwiOjEsXG5cdFx0XCJ7XCI6LTEsXG5cdFx0XCIoXCI6LTEsXG4vL1x0XHRcIipbOyw/W29yKFt2ZXJiUGF0aCx2ZXJiU2ltcGxlXSksb2JqZWN0TGlzdF1dXCI6IDEsXG5cdH07XG5cdFxuXG5cdGZ1bmN0aW9uIGluZGVudChzdGF0ZSwgdGV4dEFmdGVyKSB7XG5cdFx0Ly9qdXN0IGF2b2lkIHdlIGRvbid0IGluZGVudCBtdWx0aS1saW5lICBsaXRlcmFsc1xuXHRcdGlmIChzdGF0ZS5pbkxpdGVyYWwpIHJldHVybiAwO1xuXHRcdGlmIChzdGF0ZS5zdGFjay5sZW5ndGggJiYgc3RhdGUuc3RhY2tbc3RhdGUuc3RhY2subGVuZ3RoLTFdID09IFwiP1tvcihbdmVyYlBhdGgsdmVyYlNpbXBsZV0pLG9iamVjdExpc3RdXCIpIHtcblx0XHRcdC8vd2UgYXJlIGFmdGVyIGEgc2VtaS1jb2xvbi4gSS5lLiwgbmljZWx5IGFsaWduIHRoaXMgbGluZSB3aXRoIHByZWRpY2F0ZSBwb3NpdGlvbiBvZiBwcmV2aW91cyBsaW5lXG5cdFx0XHRyZXR1cm4gc3RhdGUubGFzdFByZWRpY2F0ZU9mZnNldDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dmFyIG4gPSAwOyAvLyBpbmRlbnQgbGV2ZWxcblx0XHRcdHZhciBpID0gc3RhdGUuc3RhY2subGVuZ3RoLTE7XG5cdFx0XHRpZiAoL15bXFx9XFxdXFwpXS8udGVzdCh0ZXh0QWZ0ZXIpKSB7XG5cdFx0XHRcdC8vIFNraXAgc3RhY2sgaXRlbXMgdW50aWwgYWZ0ZXIgbWF0Y2hpbmcgYnJhY2tldFxuXHRcdFx0XHR2YXIgY2xvc2VCcmFja2V0PXRleHRBZnRlci5zdWJzdHIoMCwxKTtcblx0XHRcdFx0Zm9yKCA7aT49MDstLWkpXHR7XG5cdFx0XHRcdFx0aWYgKHN0YXRlLnN0YWNrW2ldPT1jbG9zZUJyYWNrZXQpIHtcblx0XHRcdFx0XHRcdC0taTsgXG5cdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBDb25zaWRlciBudWxsYWJsZSBub24tdGVybWluYWxzIGlmIGF0IHRvcCBvZiBzdGFja1xuXHRcdFx0XHR2YXIgZG4gPSBpbmRlbnRUb3Bbc3RhdGUuc3RhY2tbaV1dO1xuXHRcdFx0XHRpZiAoZG4pIHsgXG5cdFx0XHRcdFx0biArPSBkbjsgXG5cdFx0XHRcdFx0LS1pO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRmb3IoIDtpPj0wOy0taSlcdHtcblx0XHRcdFx0dmFyIGRuID0gaW5kZW50VGFibGVbc3RhdGUuc3RhY2tbaV1dO1xuXHRcdFx0XHRpZiAoZG4pIHtcblx0XHRcdFx0XHRuKz1kbjtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG4gKiBjb25maWcuaW5kZW50VW5pdDtcblx0XHR9XG5cdH07XG5cblx0cmV0dXJuIHtcblx0XHR0b2tlbjogdG9rZW5CYXNlLFxuXHRcdHN0YXJ0U3RhdGU6IGZ1bmN0aW9uKGJhc2UpIHtcblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHRva2VuaXplOiB0b2tlbkJhc2UsXG5cdFx0XHRcdE9LOiB0cnVlLFxuXHRcdFx0XHRjb21wbGV0ZTogZ3JhbW1hci5hY2NlcHRFbXB0eSxcblx0XHRcdFx0ZXJyb3JTdGFydFBvczogbnVsbCxcblx0XHRcdFx0ZXJyb3JFbmRQb3M6IG51bGwsXG5cdFx0XHRcdHF1ZXJ5VHlwZTogbnVsbCxcblx0XHRcdFx0cG9zc2libGVDdXJyZW50OiBnZXRQb3NzaWJsZXMoZ3JhbW1hci5zdGFydFN5bWJvbCksXG5cdFx0XHRcdHBvc3NpYmxlTmV4dDogZ2V0UG9zc2libGVzKGdyYW1tYXIuc3RhcnRTeW1ib2wpLFxuXHRcdFx0XHRhbGxvd1ZhcnMgOiB0cnVlLFxuXHRcdFx0XHRhbGxvd0Jub2RlcyA6IHRydWUsXG5cdFx0XHRcdHN0b3JlUHJvcGVydHkgOiBmYWxzZSxcblx0XHRcdFx0bGFzdFByb3BlcnR5IDogXCJcIixcblx0XHRcdFx0aW5MaXRlcmFsOiBmYWxzZSxcblx0XHRcdFx0c3RhY2s6IFtncmFtbWFyLnN0YXJ0U3ltYm9sXSxcblx0XHRcdFx0bGFzdFByZWRpY2F0ZU9mZnNldDogY29uZmlnLmluZGVudFVuaXQsXG5cdFx0XHR9OyBcblx0XHR9LFxuXHRcdGluZGVudDogaW5kZW50LFxuXHRcdGVsZWN0cmljQ2hhcnM6IFwifV0pXCJcblx0fTtcbn1cbik7XG5Db2RlTWlycm9yLmRlZmluZU1JTUUoXCJhcHBsaWNhdGlvbi94LXNwYXJxbC1xdWVyeVwiLCBcInNwYXJxbDExXCIpO1xuIiwiLypcbiogVFJJRSBpbXBsZW1lbnRhdGlvbiBpbiBKYXZhc2NyaXB0XG4qIENvcHlyaWdodCAoYykgMjAxMCBTYXVyYWJoIE9kaHlhbiB8IGh0dHA6Ly9vZGh5YW4uY29tXG4qIFxuKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4qIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlIFwiU29mdHdhcmVcIiksIHRvIGRlYWxcbiogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0c1xuKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsXG4qIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpc1xuKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOlxuKiBcbiogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW5cbiogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuXG4qIFxuKiBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgXCJBUyBJU1wiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SXG4qIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLFxuKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbiogQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUlxuKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLFxuKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4qIFRIRSBTT0ZUV0FSRS5cbipcbiogRGF0ZTogTm92IDcsIDIwMTBcbiovXG5cbi8qXG4qIEEgdHJpZSwgb3IgcHJlZml4IHRyZWUsIGlzIGEgbXVsdGktd2F5IHRyZWUgc3RydWN0dXJlIHVzZWZ1bCBmb3Igc3RvcmluZyBzdHJpbmdzIG92ZXIgYW4gYWxwaGFiZXQuIFxuKiBJdCBoYXMgYmVlbiB1c2VkIHRvIHN0b3JlIGxhcmdlIGRpY3Rpb25hcmllcyBvZiBFbmdsaXNoIChzYXkpIHdvcmRzIGluIHNwZWxsLWNoZWNraW5nIHByb2dyYW1zIFxuKiBhbmQgaW4gbmF0dXJhbC1sYW5ndWFnZSBcInVuZGVyc3RhbmRpbmdcIiBwcm9ncmFtcy4gICAgXG4qIEBzZWUgaHR0cDovL2VuLndpa2lwZWRpYS5vcmcvd2lraS9UcmllXG4qIEBzZWUgaHR0cDovL3d3dy5jc3NlLm1vbmFzaC5lZHUuYXUvfmxsb3lkL3RpbGRlQWxnRFMvVHJlZS9UcmllL1xuLypcblxuKiBAY2xhc3MgVHJpZVxuKiBAY29uc3RydWN0b3JcbiovICBcbnZhciBUcmllID0gbW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbigpIHtcbiAgICB0aGlzLndvcmRzID0gMDtcbiAgICB0aGlzLnByZWZpeGVzID0gMDtcbiAgICB0aGlzLmNoaWxkcmVuID0gW107XG59O1xuXG5UcmllLnByb3RvdHlwZSA9IHtcbiAgICBcbiAgICAvKlxuICAgICogSW5zZXJ0IGEgd29yZCBpbnRvIHRoZSBkaWN0aW9uYXJ5LiBcbiAgICAqIFJlY3Vyc2l2ZWx5IHRyYXZlcnNlIHRocm91Z2ggdGhlIHRyaWUgbm9kZXMsIGFuZCBjcmVhdGUgbmV3IG5vZGUgaWYgZG9lcyBub3QgYWxyZWFkeSBleGlzdC5cbiAgICAqXG4gICAgKiBAbWV0aG9kIGluc2VydFxuICAgICogQHBhcmFtIHtTdHJpbmd9IHN0ciBXb3JkIHRvIGluc2VydCBpbiB0aGUgZGljdGlvbmFyeVxuICAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3MgQ3VycmVudCBpbmRleCBvZiB0aGUgc3RyaW5nIHRvIGJlIGluc2VydGVkXG4gICAgKiBAcmV0dXJuIHtWb2lkfVxuICAgICovXG4gICAgaW5zZXJ0OiBmdW5jdGlvbihzdHIsIHBvcykge1xuICAgICAgICBpZihzdHIubGVuZ3RoID09IDApIHsgLy9ibGFuayBzdHJpbmcgY2Fubm90IGJlIGluc2VydGVkXG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIHZhciBUID0gdGhpcyxcbiAgICAgICAgICAgIGssXG4gICAgICAgICAgICBjaGlsZDtcbiAgICAgICAgICAgIFxuICAgICAgICBpZihwb3MgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcG9zID0gMDtcbiAgICAgICAgfVxuICAgICAgICBpZihwb3MgPT09IHN0ci5sZW5ndGgpIHtcbiAgICAgICAgICAgIFQud29yZHMgKys7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgVC5wcmVmaXhlcyArKztcbiAgICAgICAgayA9IHN0cltwb3NdO1xuICAgICAgICBpZihULmNoaWxkcmVuW2tdID09PSB1bmRlZmluZWQpIHsgLy9pZiBub2RlIGZvciB0aGlzIGNoYXIgZG9lc24ndCBleGlzdCwgY3JlYXRlIG9uZVxuICAgICAgICAgICAgVC5jaGlsZHJlbltrXSA9IG5ldyBUcmllKCk7XG4gICAgICAgIH1cbiAgICAgICAgY2hpbGQgPSBULmNoaWxkcmVuW2tdO1xuICAgICAgICBjaGlsZC5pbnNlcnQoc3RyLCBwb3MgKyAxKTtcbiAgICB9LFxuICAgIFxuICAgIC8qXG4gICAgKiBSZW1vdmUgYSB3b3JkIGZyb20gdGhlIGRpY3Rpb25hcnkuXG4gICAgKlxuICAgICogQG1ldGhvZCByZW1vdmVcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgV29yZCB0byBiZSByZW1vdmVkXG4gICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvcyBDdXJyZW50IGluZGV4IG9mIHRoZSBzdHJpbmcgdG8gYmUgcmVtb3ZlZFxuICAgICogQHJldHVybiB7Vm9pZH1cbiAgICAqL1xuICAgIHJlbW92ZTogZnVuY3Rpb24oc3RyLCBwb3MpIHtcbiAgICAgICAgaWYoc3RyLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIHZhciBUID0gdGhpcyxcbiAgICAgICAgICAgIGssXG4gICAgICAgICAgICBjaGlsZDtcbiAgICAgICAgXG4gICAgICAgIGlmKHBvcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBwb3MgPSAwO1xuICAgICAgICB9ICAgXG4gICAgICAgIGlmKFQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGlmKHBvcyA9PT0gc3RyLmxlbmd0aCkge1xuICAgICAgICAgICAgVC53b3JkcyAtLTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBULnByZWZpeGVzIC0tO1xuICAgICAgICBrID0gc3RyW3Bvc107XG4gICAgICAgIGNoaWxkID0gVC5jaGlsZHJlbltrXTtcbiAgICAgICAgY2hpbGQucmVtb3ZlKHN0ciwgcG9zICsgMSk7XG4gICAgfSxcbiAgICBcbiAgICAvKlxuICAgICogVXBkYXRlIGFuIGV4aXN0aW5nIHdvcmQgaW4gdGhlIGRpY3Rpb25hcnkuIFxuICAgICogVGhpcyBtZXRob2QgcmVtb3ZlcyB0aGUgb2xkIHdvcmQgZnJvbSB0aGUgZGljdGlvbmFyeSBhbmQgaW5zZXJ0cyB0aGUgbmV3IHdvcmQuXG4gICAgKlxuICAgICogQG1ldGhvZCB1cGRhdGVcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHJPbGQgVGhlIG9sZCB3b3JkIHRvIGJlIHJlcGxhY2VkXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyTmV3IFRoZSBuZXcgd29yZCB0byBiZSBpbnNlcnRlZFxuICAgICogQHJldHVybiB7Vm9pZH1cbiAgICAqL1xuICAgIHVwZGF0ZTogZnVuY3Rpb24oc3RyT2xkLCBzdHJOZXcpIHtcbiAgICAgICAgaWYoc3RyT2xkLmxlbmd0aCA9PSAwIHx8IHN0ck5ldy5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMucmVtb3ZlKHN0ck9sZCk7XG4gICAgICAgIHRoaXMuaW5zZXJ0KHN0ck5ldyk7XG4gICAgfSxcbiAgICBcbiAgICAvKlxuICAgICogQ291bnQgdGhlIG51bWJlciBvZiB0aW1lcyBhIGdpdmVuIHdvcmQgaGFzIGJlZW4gaW5zZXJ0ZWQgaW50byB0aGUgZGljdGlvbmFyeVxuICAgICpcbiAgICAqIEBtZXRob2QgY291bnRXb3JkXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFdvcmQgdG8gZ2V0IGNvdW50IG9mXG4gICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvcyBDdXJyZW50IGluZGV4IG9mIHRoZSBnaXZlbiB3b3JkXG4gICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBUaGUgbnVtYmVyIG9mIHRpbWVzIGEgZ2l2ZW4gd29yZCBleGlzdHMgaW4gdGhlIGRpY3Rpb25hcnlcbiAgICAqL1xuICAgIGNvdW50V29yZDogZnVuY3Rpb24oc3RyLCBwb3MpIHtcbiAgICAgICAgaWYoc3RyLmxlbmd0aCA9PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4gMDtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgdmFyIFQgPSB0aGlzLFxuICAgICAgICAgICAgayxcbiAgICAgICAgICAgIGNoaWxkLFxuICAgICAgICAgICAgcmV0ID0gMDtcbiAgICAgICAgXG4gICAgICAgIGlmKHBvcyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICBwb3MgPSAwO1xuICAgICAgICB9ICAgXG4gICAgICAgIGlmKHBvcyA9PT0gc3RyLmxlbmd0aCkge1xuICAgICAgICAgICAgcmV0dXJuIFQud29yZHM7XG4gICAgICAgIH1cbiAgICAgICAgayA9IHN0cltwb3NdO1xuICAgICAgICBjaGlsZCA9IFQuY2hpbGRyZW5ba107XG4gICAgICAgIGlmKGNoaWxkICE9PSB1bmRlZmluZWQpIHsgLy9ub2RlIGV4aXN0c1xuICAgICAgICAgICAgcmV0ID0gY2hpbGQuY291bnRXb3JkKHN0ciwgcG9zICsgMSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldDtcbiAgICB9LFxuICAgIFxuICAgIC8qXG4gICAgKiBDb3VudCB0aGUgbnVtYmVyIG9mIHRpbWVzIGEgZ2l2ZW4gcHJlZml4IGV4aXN0cyBpbiB0aGUgZGljdGlvbmFyeVxuICAgICpcbiAgICAqIEBtZXRob2QgY291bnRQcmVmaXhcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgUHJlZml4IHRvIGdldCBjb3VudCBvZlxuICAgICogQHBhcmFtIHtJbnRlZ2VyfSBwb3MgQ3VycmVudCBpbmRleCBvZiB0aGUgZ2l2ZW4gcHJlZml4XG4gICAgKiBAcmV0dXJuIHtJbnRlZ2VyfSBUaGUgbnVtYmVyIG9mIHRpbWVzIGEgZ2l2ZW4gcHJlZml4IGV4aXN0cyBpbiB0aGUgZGljdGlvbmFyeVxuICAgICovXG4gICAgY291bnRQcmVmaXg6IGZ1bmN0aW9uKHN0ciwgcG9zKSB7XG4gICAgICAgIGlmKHN0ci5sZW5ndGggPT0gMCkge1xuICAgICAgICAgICAgcmV0dXJuIDA7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIHZhciBUID0gdGhpcyxcbiAgICAgICAgICAgIGssXG4gICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgICAgIHJldCA9IDA7XG5cbiAgICAgICAgaWYocG9zID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHBvcyA9IDA7XG4gICAgICAgIH1cbiAgICAgICAgaWYocG9zID09PSBzdHIubGVuZ3RoKSB7XG4gICAgICAgICAgICByZXR1cm4gVC5wcmVmaXhlcztcbiAgICAgICAgfVxuICAgICAgICB2YXIgayA9IHN0cltwb3NdO1xuICAgICAgICBjaGlsZCA9IFQuY2hpbGRyZW5ba107XG4gICAgICAgIGlmKGNoaWxkICE9PSB1bmRlZmluZWQpIHsgLy9ub2RlIGV4aXN0c1xuICAgICAgICAgICAgcmV0ID0gY2hpbGQuY291bnRQcmVmaXgoc3RyLCBwb3MgKyAxKTsgXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJldDsgXG4gICAgfSxcbiAgICBcbiAgICAvKlxuICAgICogRmluZCBhIHdvcmQgaW4gdGhlIGRpY3Rpb25hcnlcbiAgICAqXG4gICAgKiBAbWV0aG9kIGZpbmRcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgVGhlIHdvcmQgdG8gZmluZCBpbiB0aGUgZGljdGlvbmFyeVxuICAgICogQHJldHVybiB7Qm9vbGVhbn0gVHJ1ZSBpZiB0aGUgd29yZCBleGlzdHMgaW4gdGhlIGRpY3Rpb25hcnksIGVsc2UgZmFsc2VcbiAgICAqL1xuICAgIGZpbmQ6IGZ1bmN0aW9uKHN0cikge1xuICAgICAgICBpZihzdHIubGVuZ3RoID09IDApIHtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgaWYodGhpcy5jb3VudFdvcmQoc3RyKSA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICB9XG4gICAgfSxcbiAgICBcbiAgICAvKlxuICAgICogR2V0IGFsbCB3b3JkcyBpbiB0aGUgZGljdGlvbmFyeVxuICAgICpcbiAgICAqIEBtZXRob2QgZ2V0QWxsV29yZHNcbiAgICAqIEBwYXJhbSB7U3RyaW5nfSBzdHIgUHJlZml4IG9mIGN1cnJlbnQgd29yZFxuICAgICogQHJldHVybiB7QXJyYXl9IEFycmF5IG9mIHdvcmRzIGluIHRoZSBkaWN0aW9uYXJ5XG4gICAgKi9cbiAgICBnZXRBbGxXb3JkczogZnVuY3Rpb24oc3RyKSB7XG4gICAgICAgIHZhciBUID0gdGhpcyxcbiAgICAgICAgICAgIGssXG4gICAgICAgICAgICBjaGlsZCxcbiAgICAgICAgICAgIHJldCA9IFtdO1xuICAgICAgICBpZihzdHIgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgc3RyID0gXCJcIjtcbiAgICAgICAgfVxuICAgICAgICBpZihUID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuICAgICAgICBpZihULndvcmRzID4gMCkge1xuICAgICAgICAgICAgcmV0LnB1c2goc3RyKTtcbiAgICAgICAgfVxuICAgICAgICBmb3IoayBpbiBULmNoaWxkcmVuKSB7XG4gICAgICAgICAgICBjaGlsZCA9IFQuY2hpbGRyZW5ba107XG4gICAgICAgICAgICByZXQgPSByZXQuY29uY2F0KGNoaWxkLmdldEFsbFdvcmRzKHN0ciArIGspKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmV0O1xuICAgIH0sXG4gICAgXG4gICAgLypcbiAgICAqIEF1dG9jb21wbGV0ZSBhIGdpdmVuIHByZWZpeFxuICAgICpcbiAgICAqIEBtZXRob2QgYXV0b0NvbXBsZXRlXG4gICAgKiBAcGFyYW0ge1N0cmluZ30gc3RyIFByZWZpeCB0byBiZSBjb21wbGV0ZWQgYmFzZWQgb24gZGljdGlvbmFyeSBlbnRyaWVzXG4gICAgKiBAcGFyYW0ge0ludGVnZXJ9IHBvcyBDdXJyZW50IGluZGV4IG9mIHRoZSBwcmVmaXhcbiAgICAqIEByZXR1cm4ge0FycmF5fSBBcnJheSBvZiBwb3NzaWJsZSBzdWdnZXN0aW9uc1xuICAgICovXG4gICAgYXV0b0NvbXBsZXRlOiBmdW5jdGlvbihzdHIsIHBvcykge1xuICAgICAgICBcbiAgICAgICAgXG4gICAgICAgIHZhciBUID0gdGhpcyxcbiAgICAgICAgICAgIGssXG4gICAgICAgICAgICBjaGlsZDtcbiAgICAgICAgaWYoc3RyLmxlbmd0aCA9PSAwKSB7XG5cdFx0XHRpZiAocG9zID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0cmV0dXJuIFQuZ2V0QWxsV29yZHMoc3RyKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiBbXTtcblx0XHRcdH1cbiAgICAgICAgfVxuICAgICAgICBpZihwb3MgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcG9zID0gMDtcbiAgICAgICAgfSAgIFxuICAgICAgICBrID0gc3RyW3Bvc107XG4gICAgICAgIGNoaWxkID0gVC5jaGlsZHJlbltrXTtcbiAgICAgICAgaWYoY2hpbGQgPT09IHVuZGVmaW5lZCkgeyAvL25vZGUgZG9lc24ndCBleGlzdFxuICAgICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG4gICAgICAgIGlmKHBvcyA9PT0gc3RyLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICAgIHJldHVybiBjaGlsZC5nZXRBbGxXb3JkcyhzdHIpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjaGlsZC5hdXRvQ29tcGxldGUoc3RyLCBwb3MgKyAxKTtcbiAgICB9XG59O1xuIiwiLy8gQ29kZU1pcnJvciwgY29weXJpZ2h0IChjKSBieSBNYXJpam4gSGF2ZXJiZWtlIGFuZCBvdGhlcnNcbi8vIERpc3RyaWJ1dGVkIHVuZGVyIGFuIE1JVCBsaWNlbnNlOiBodHRwOi8vY29kZW1pcnJvci5uZXQvTElDRU5TRVxuXG4oZnVuY3Rpb24obW9kKSB7XG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT0gXCJvYmplY3RcIikgLy8gQ29tbW9uSlNcbiAgICBtb2QocmVxdWlyZShcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICBDb2RlTWlycm9yLmRlZmluZU9wdGlvbihcImZ1bGxTY3JlZW5cIiwgZmFsc2UsIGZ1bmN0aW9uKGNtLCB2YWwsIG9sZCkge1xuICAgIGlmIChvbGQgPT0gQ29kZU1pcnJvci5Jbml0KSBvbGQgPSBmYWxzZTtcbiAgICBpZiAoIW9sZCA9PSAhdmFsKSByZXR1cm47XG4gICAgaWYgKHZhbCkgc2V0RnVsbHNjcmVlbihjbSk7XG4gICAgZWxzZSBzZXROb3JtYWwoY20pO1xuICB9KTtcblxuICBmdW5jdGlvbiBzZXRGdWxsc2NyZWVuKGNtKSB7XG4gICAgdmFyIHdyYXAgPSBjbS5nZXRXcmFwcGVyRWxlbWVudCgpO1xuICAgIGNtLnN0YXRlLmZ1bGxTY3JlZW5SZXN0b3JlID0ge3Njcm9sbFRvcDogd2luZG93LnBhZ2VZT2Zmc2V0LCBzY3JvbGxMZWZ0OiB3aW5kb3cucGFnZVhPZmZzZXQsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2lkdGg6IHdyYXAuc3R5bGUud2lkdGgsIGhlaWdodDogd3JhcC5zdHlsZS5oZWlnaHR9O1xuICAgIHdyYXAuc3R5bGUud2lkdGggPSBcIlwiO1xuICAgIHdyYXAuc3R5bGUuaGVpZ2h0ID0gXCJhdXRvXCI7XG4gICAgd3JhcC5jbGFzc05hbWUgKz0gXCIgQ29kZU1pcnJvci1mdWxsc2NyZWVuXCI7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLm92ZXJmbG93ID0gXCJoaWRkZW5cIjtcbiAgICBjbS5yZWZyZXNoKCk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXROb3JtYWwoY20pIHtcbiAgICB2YXIgd3JhcCA9IGNtLmdldFdyYXBwZXJFbGVtZW50KCk7XG4gICAgd3JhcC5jbGFzc05hbWUgPSB3cmFwLmNsYXNzTmFtZS5yZXBsYWNlKC9cXHMqQ29kZU1pcnJvci1mdWxsc2NyZWVuXFxiLywgXCJcIik7XG4gICAgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnN0eWxlLm92ZXJmbG93ID0gXCJcIjtcbiAgICB2YXIgaW5mbyA9IGNtLnN0YXRlLmZ1bGxTY3JlZW5SZXN0b3JlO1xuICAgIHdyYXAuc3R5bGUud2lkdGggPSBpbmZvLndpZHRoOyB3cmFwLnN0eWxlLmhlaWdodCA9IGluZm8uaGVpZ2h0O1xuICAgIHdpbmRvdy5zY3JvbGxUbyhpbmZvLnNjcm9sbExlZnQsIGluZm8uc2Nyb2xsVG9wKTtcbiAgICBjbS5yZWZyZXNoKCk7XG4gIH1cbn0pO1xuIiwiLy8gQ29kZU1pcnJvciwgY29weXJpZ2h0IChjKSBieSBNYXJpam4gSGF2ZXJiZWtlIGFuZCBvdGhlcnNcbi8vIERpc3RyaWJ1dGVkIHVuZGVyIGFuIE1JVCBsaWNlbnNlOiBodHRwOi8vY29kZW1pcnJvci5uZXQvTElDRU5TRVxuXG4oZnVuY3Rpb24obW9kKSB7XG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT0gXCJvYmplY3RcIikgLy8gQ29tbW9uSlNcbiAgICBtb2QocmVxdWlyZShcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuICB2YXIgaWVfbHQ4ID0gL01TSUUgXFxkLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpICYmXG4gICAgKGRvY3VtZW50LmRvY3VtZW50TW9kZSA9PSBudWxsIHx8IGRvY3VtZW50LmRvY3VtZW50TW9kZSA8IDgpO1xuXG4gIHZhciBQb3MgPSBDb2RlTWlycm9yLlBvcztcblxuICB2YXIgbWF0Y2hpbmcgPSB7XCIoXCI6IFwiKT5cIiwgXCIpXCI6IFwiKDxcIiwgXCJbXCI6IFwiXT5cIiwgXCJdXCI6IFwiWzxcIiwgXCJ7XCI6IFwifT5cIiwgXCJ9XCI6IFwiezxcIn07XG5cbiAgZnVuY3Rpb24gZmluZE1hdGNoaW5nQnJhY2tldChjbSwgd2hlcmUsIHN0cmljdCwgY29uZmlnKSB7XG4gICAgdmFyIGxpbmUgPSBjbS5nZXRMaW5lSGFuZGxlKHdoZXJlLmxpbmUpLCBwb3MgPSB3aGVyZS5jaCAtIDE7XG4gICAgdmFyIG1hdGNoID0gKHBvcyA+PSAwICYmIG1hdGNoaW5nW2xpbmUudGV4dC5jaGFyQXQocG9zKV0pIHx8IG1hdGNoaW5nW2xpbmUudGV4dC5jaGFyQXQoKytwb3MpXTtcbiAgICBpZiAoIW1hdGNoKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgZGlyID0gbWF0Y2guY2hhckF0KDEpID09IFwiPlwiID8gMSA6IC0xO1xuICAgIGlmIChzdHJpY3QgJiYgKGRpciA+IDApICE9IChwb3MgPT0gd2hlcmUuY2gpKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgc3R5bGUgPSBjbS5nZXRUb2tlblR5cGVBdChQb3Mod2hlcmUubGluZSwgcG9zICsgMSkpO1xuXG4gICAgdmFyIGZvdW5kID0gc2NhbkZvckJyYWNrZXQoY20sIFBvcyh3aGVyZS5saW5lLCBwb3MgKyAoZGlyID4gMCA/IDEgOiAwKSksIGRpciwgc3R5bGUgfHwgbnVsbCwgY29uZmlnKTtcbiAgICBpZiAoZm91bmQgPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHtmcm9tOiBQb3Mod2hlcmUubGluZSwgcG9zKSwgdG86IGZvdW5kICYmIGZvdW5kLnBvcyxcbiAgICAgICAgICAgIG1hdGNoOiBmb3VuZCAmJiBmb3VuZC5jaCA9PSBtYXRjaC5jaGFyQXQoMCksIGZvcndhcmQ6IGRpciA+IDB9O1xuICB9XG5cbiAgLy8gYnJhY2tldFJlZ2V4IGlzIHVzZWQgdG8gc3BlY2lmeSB3aGljaCB0eXBlIG9mIGJyYWNrZXQgdG8gc2NhblxuICAvLyBzaG91bGQgYmUgYSByZWdleHAsIGUuZy4gL1tbXFxdXS9cbiAgLy9cbiAgLy8gTm90ZTogSWYgXCJ3aGVyZVwiIGlzIG9uIGFuIG9wZW4gYnJhY2tldCwgdGhlbiB0aGlzIGJyYWNrZXQgaXMgaWdub3JlZC5cbiAgLy9cbiAgLy8gUmV0dXJucyBmYWxzZSB3aGVuIG5vIGJyYWNrZXQgd2FzIGZvdW5kLCBudWxsIHdoZW4gaXQgcmVhY2hlZFxuICAvLyBtYXhTY2FuTGluZXMgYW5kIGdhdmUgdXBcbiAgZnVuY3Rpb24gc2NhbkZvckJyYWNrZXQoY20sIHdoZXJlLCBkaXIsIHN0eWxlLCBjb25maWcpIHtcbiAgICB2YXIgbWF4U2NhbkxlbiA9IChjb25maWcgJiYgY29uZmlnLm1heFNjYW5MaW5lTGVuZ3RoKSB8fCAxMDAwMDtcbiAgICB2YXIgbWF4U2NhbkxpbmVzID0gKGNvbmZpZyAmJiBjb25maWcubWF4U2NhbkxpbmVzKSB8fCAxMDAwO1xuXG4gICAgdmFyIHN0YWNrID0gW107XG4gICAgdmFyIHJlID0gY29uZmlnICYmIGNvbmZpZy5icmFja2V0UmVnZXggPyBjb25maWcuYnJhY2tldFJlZ2V4IDogL1soKXt9W1xcXV0vO1xuICAgIHZhciBsaW5lRW5kID0gZGlyID4gMCA/IE1hdGgubWluKHdoZXJlLmxpbmUgKyBtYXhTY2FuTGluZXMsIGNtLmxhc3RMaW5lKCkgKyAxKVxuICAgICAgICAgICAgICAgICAgICAgICAgICA6IE1hdGgubWF4KGNtLmZpcnN0TGluZSgpIC0gMSwgd2hlcmUubGluZSAtIG1heFNjYW5MaW5lcyk7XG4gICAgZm9yICh2YXIgbGluZU5vID0gd2hlcmUubGluZTsgbGluZU5vICE9IGxpbmVFbmQ7IGxpbmVObyArPSBkaXIpIHtcbiAgICAgIHZhciBsaW5lID0gY20uZ2V0TGluZShsaW5lTm8pO1xuICAgICAgaWYgKCFsaW5lKSBjb250aW51ZTtcbiAgICAgIHZhciBwb3MgPSBkaXIgPiAwID8gMCA6IGxpbmUubGVuZ3RoIC0gMSwgZW5kID0gZGlyID4gMCA/IGxpbmUubGVuZ3RoIDogLTE7XG4gICAgICBpZiAobGluZS5sZW5ndGggPiBtYXhTY2FuTGVuKSBjb250aW51ZTtcbiAgICAgIGlmIChsaW5lTm8gPT0gd2hlcmUubGluZSkgcG9zID0gd2hlcmUuY2ggLSAoZGlyIDwgMCA/IDEgOiAwKTtcbiAgICAgIGZvciAoOyBwb3MgIT0gZW5kOyBwb3MgKz0gZGlyKSB7XG4gICAgICAgIHZhciBjaCA9IGxpbmUuY2hhckF0KHBvcyk7XG4gICAgICAgIGlmIChyZS50ZXN0KGNoKSAmJiAoc3R5bGUgPT09IHVuZGVmaW5lZCB8fCBjbS5nZXRUb2tlblR5cGVBdChQb3MobGluZU5vLCBwb3MgKyAxKSkgPT0gc3R5bGUpKSB7XG4gICAgICAgICAgdmFyIG1hdGNoID0gbWF0Y2hpbmdbY2hdO1xuICAgICAgICAgIGlmICgobWF0Y2guY2hhckF0KDEpID09IFwiPlwiKSA9PSAoZGlyID4gMCkpIHN0YWNrLnB1c2goY2gpO1xuICAgICAgICAgIGVsc2UgaWYgKCFzdGFjay5sZW5ndGgpIHJldHVybiB7cG9zOiBQb3MobGluZU5vLCBwb3MpLCBjaDogY2h9O1xuICAgICAgICAgIGVsc2Ugc3RhY2sucG9wKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxpbmVObyAtIGRpciA9PSAoZGlyID4gMCA/IGNtLmxhc3RMaW5lKCkgOiBjbS5maXJzdExpbmUoKSkgPyBmYWxzZSA6IG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiBtYXRjaEJyYWNrZXRzKGNtLCBhdXRvY2xlYXIsIGNvbmZpZykge1xuICAgIC8vIERpc2FibGUgYnJhY2UgbWF0Y2hpbmcgaW4gbG9uZyBsaW5lcywgc2luY2UgaXQnbGwgY2F1c2UgaHVnZWx5IHNsb3cgdXBkYXRlc1xuICAgIHZhciBtYXhIaWdobGlnaHRMZW4gPSBjbS5zdGF0ZS5tYXRjaEJyYWNrZXRzLm1heEhpZ2hsaWdodExpbmVMZW5ndGggfHwgMTAwMDtcbiAgICB2YXIgbWFya3MgPSBbXSwgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIG1hdGNoID0gcmFuZ2VzW2ldLmVtcHR5KCkgJiYgZmluZE1hdGNoaW5nQnJhY2tldChjbSwgcmFuZ2VzW2ldLmhlYWQsIGZhbHNlLCBjb25maWcpO1xuICAgICAgaWYgKG1hdGNoICYmIGNtLmdldExpbmUobWF0Y2guZnJvbS5saW5lKS5sZW5ndGggPD0gbWF4SGlnaGxpZ2h0TGVuKSB7XG4gICAgICAgIHZhciBzdHlsZSA9IG1hdGNoLm1hdGNoID8gXCJDb2RlTWlycm9yLW1hdGNoaW5nYnJhY2tldFwiIDogXCJDb2RlTWlycm9yLW5vbm1hdGNoaW5nYnJhY2tldFwiO1xuICAgICAgICBtYXJrcy5wdXNoKGNtLm1hcmtUZXh0KG1hdGNoLmZyb20sIFBvcyhtYXRjaC5mcm9tLmxpbmUsIG1hdGNoLmZyb20uY2ggKyAxKSwge2NsYXNzTmFtZTogc3R5bGV9KSk7XG4gICAgICAgIGlmIChtYXRjaC50byAmJiBjbS5nZXRMaW5lKG1hdGNoLnRvLmxpbmUpLmxlbmd0aCA8PSBtYXhIaWdobGlnaHRMZW4pXG4gICAgICAgICAgbWFya3MucHVzaChjbS5tYXJrVGV4dChtYXRjaC50bywgUG9zKG1hdGNoLnRvLmxpbmUsIG1hdGNoLnRvLmNoICsgMSksIHtjbGFzc05hbWU6IHN0eWxlfSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtYXJrcy5sZW5ndGgpIHtcbiAgICAgIC8vIEtsdWRnZSB0byB3b3JrIGFyb3VuZCB0aGUgSUUgYnVnIGZyb20gaXNzdWUgIzExOTMsIHdoZXJlIHRleHRcbiAgICAgIC8vIGlucHV0IHN0b3BzIGdvaW5nIHRvIHRoZSB0ZXh0YXJlIHdoZXZlciB0aGlzIGZpcmVzLlxuICAgICAgaWYgKGllX2x0OCAmJiBjbS5zdGF0ZS5mb2N1c2VkKSBjbS5kaXNwbGF5LmlucHV0LmZvY3VzKCk7XG5cbiAgICAgIHZhciBjbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgICAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7IGkrKykgbWFya3NbaV0uY2xlYXIoKTtcbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgICAgaWYgKGF1dG9jbGVhcikgc2V0VGltZW91dChjbGVhciwgODAwKTtcbiAgICAgIGVsc2UgcmV0dXJuIGNsZWFyO1xuICAgIH1cbiAgfVxuXG4gIHZhciBjdXJyZW50bHlIaWdobGlnaHRlZCA9IG51bGw7XG4gIGZ1bmN0aW9uIGRvTWF0Y2hCcmFja2V0cyhjbSkge1xuICAgIGNtLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgIGlmIChjdXJyZW50bHlIaWdobGlnaHRlZCkge2N1cnJlbnRseUhpZ2hsaWdodGVkKCk7IGN1cnJlbnRseUhpZ2hsaWdodGVkID0gbnVsbDt9XG4gICAgICBjdXJyZW50bHlIaWdobGlnaHRlZCA9IG1hdGNoQnJhY2tldHMoY20sIGZhbHNlLCBjbS5zdGF0ZS5tYXRjaEJyYWNrZXRzKTtcbiAgICB9KTtcbiAgfVxuXG4gIENvZGVNaXJyb3IuZGVmaW5lT3B0aW9uKFwibWF0Y2hCcmFja2V0c1wiLCBmYWxzZSwgZnVuY3Rpb24oY20sIHZhbCwgb2xkKSB7XG4gICAgaWYgKG9sZCAmJiBvbGQgIT0gQ29kZU1pcnJvci5Jbml0KVxuICAgICAgY20ub2ZmKFwiY3Vyc29yQWN0aXZpdHlcIiwgZG9NYXRjaEJyYWNrZXRzKTtcbiAgICBpZiAodmFsKSB7XG4gICAgICBjbS5zdGF0ZS5tYXRjaEJyYWNrZXRzID0gdHlwZW9mIHZhbCA9PSBcIm9iamVjdFwiID8gdmFsIDoge307XG4gICAgICBjbS5vbihcImN1cnNvckFjdGl2aXR5XCIsIGRvTWF0Y2hCcmFja2V0cyk7XG4gICAgfVxuICB9KTtcblxuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbihcIm1hdGNoQnJhY2tldHNcIiwgZnVuY3Rpb24oKSB7bWF0Y2hCcmFja2V0cyh0aGlzLCB0cnVlKTt9KTtcbiAgQ29kZU1pcnJvci5kZWZpbmVFeHRlbnNpb24oXCJmaW5kTWF0Y2hpbmdCcmFja2V0XCIsIGZ1bmN0aW9uKHBvcywgc3RyaWN0LCBjb25maWcpe1xuICAgIHJldHVybiBmaW5kTWF0Y2hpbmdCcmFja2V0KHRoaXMsIHBvcywgc3RyaWN0LCBjb25maWcpO1xuICB9KTtcbiAgQ29kZU1pcnJvci5kZWZpbmVFeHRlbnNpb24oXCJzY2FuRm9yQnJhY2tldFwiLCBmdW5jdGlvbihwb3MsIGRpciwgc3R5bGUsIGNvbmZpZyl7XG4gICAgcmV0dXJuIHNjYW5Gb3JCcmFja2V0KHRoaXMsIHBvcywgZGlyLCBzdHlsZSwgY29uZmlnKTtcbiAgfSk7XG59KTtcbiIsIi8vIENvZGVNaXJyb3IsIGNvcHlyaWdodCAoYykgYnkgTWFyaWpuIEhhdmVyYmVrZSBhbmQgb3RoZXJzXG4vLyBEaXN0cmlidXRlZCB1bmRlciBhbiBNSVQgbGljZW5zZTogaHR0cDovL2NvZGVtaXJyb3IubmV0L0xJQ0VOU0VcblxuKGZ1bmN0aW9uKG1vZCkge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09IFwib2JqZWN0XCIpIC8vIENvbW1vbkpTXG4gICAgbW9kKHJlcXVpcmUoXCIuLi8uLi9saWIvY29kZW1pcnJvclwiKSk7XG4gIGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIC8vIEFNRFxuICAgIGRlZmluZShbXCIuLi8uLi9saWIvY29kZW1pcnJvclwiXSwgbW9kKTtcbiAgZWxzZSAvLyBQbGFpbiBicm93c2VyIGVudlxuICAgIG1vZChDb2RlTWlycm9yKTtcbn0pKGZ1bmN0aW9uKENvZGVNaXJyb3IpIHtcblwidXNlIHN0cmljdFwiO1xuXG5Db2RlTWlycm9yLnJlZ2lzdGVySGVscGVyKFwiZm9sZFwiLCBcImJyYWNlXCIsIGZ1bmN0aW9uKGNtLCBzdGFydCkge1xuICB2YXIgbGluZSA9IHN0YXJ0LmxpbmUsIGxpbmVUZXh0ID0gY20uZ2V0TGluZShsaW5lKTtcbiAgdmFyIHN0YXJ0Q2gsIHRva2VuVHlwZTtcblxuICBmdW5jdGlvbiBmaW5kT3BlbmluZyhvcGVuQ2gpIHtcbiAgICBmb3IgKHZhciBhdCA9IHN0YXJ0LmNoLCBwYXNzID0gMDs7KSB7XG4gICAgICB2YXIgZm91bmQgPSBhdCA8PSAwID8gLTEgOiBsaW5lVGV4dC5sYXN0SW5kZXhPZihvcGVuQ2gsIGF0IC0gMSk7XG4gICAgICBpZiAoZm91bmQgPT0gLTEpIHtcbiAgICAgICAgaWYgKHBhc3MgPT0gMSkgYnJlYWs7XG4gICAgICAgIHBhc3MgPSAxO1xuICAgICAgICBhdCA9IGxpbmVUZXh0Lmxlbmd0aDtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAocGFzcyA9PSAxICYmIGZvdW5kIDwgc3RhcnQuY2gpIGJyZWFrO1xuICAgICAgdG9rZW5UeXBlID0gY20uZ2V0VG9rZW5UeXBlQXQoQ29kZU1pcnJvci5Qb3MobGluZSwgZm91bmQgKyAxKSk7XG4gICAgICBpZiAoIS9eKGNvbW1lbnR8c3RyaW5nKS8udGVzdCh0b2tlblR5cGUpKSByZXR1cm4gZm91bmQgKyAxO1xuICAgICAgYXQgPSBmb3VuZCAtIDE7XG4gICAgfVxuICB9XG5cbiAgdmFyIHN0YXJ0VG9rZW4gPSBcIntcIiwgZW5kVG9rZW4gPSBcIn1cIiwgc3RhcnRDaCA9IGZpbmRPcGVuaW5nKFwie1wiKTtcbiAgaWYgKHN0YXJ0Q2ggPT0gbnVsbCkge1xuICAgIHN0YXJ0VG9rZW4gPSBcIltcIiwgZW5kVG9rZW4gPSBcIl1cIjtcbiAgICBzdGFydENoID0gZmluZE9wZW5pbmcoXCJbXCIpO1xuICB9XG5cbiAgaWYgKHN0YXJ0Q2ggPT0gbnVsbCkgcmV0dXJuO1xuICB2YXIgY291bnQgPSAxLCBsYXN0TGluZSA9IGNtLmxhc3RMaW5lKCksIGVuZCwgZW5kQ2g7XG4gIG91dGVyOiBmb3IgKHZhciBpID0gbGluZTsgaSA8PSBsYXN0TGluZTsgKytpKSB7XG4gICAgdmFyIHRleHQgPSBjbS5nZXRMaW5lKGkpLCBwb3MgPSBpID09IGxpbmUgPyBzdGFydENoIDogMDtcbiAgICBmb3IgKDs7KSB7XG4gICAgICB2YXIgbmV4dE9wZW4gPSB0ZXh0LmluZGV4T2Yoc3RhcnRUb2tlbiwgcG9zKSwgbmV4dENsb3NlID0gdGV4dC5pbmRleE9mKGVuZFRva2VuLCBwb3MpO1xuICAgICAgaWYgKG5leHRPcGVuIDwgMCkgbmV4dE9wZW4gPSB0ZXh0Lmxlbmd0aDtcbiAgICAgIGlmIChuZXh0Q2xvc2UgPCAwKSBuZXh0Q2xvc2UgPSB0ZXh0Lmxlbmd0aDtcbiAgICAgIHBvcyA9IE1hdGgubWluKG5leHRPcGVuLCBuZXh0Q2xvc2UpO1xuICAgICAgaWYgKHBvcyA9PSB0ZXh0Lmxlbmd0aCkgYnJlYWs7XG4gICAgICBpZiAoY20uZ2V0VG9rZW5UeXBlQXQoQ29kZU1pcnJvci5Qb3MoaSwgcG9zICsgMSkpID09IHRva2VuVHlwZSkge1xuICAgICAgICBpZiAocG9zID09IG5leHRPcGVuKSArK2NvdW50O1xuICAgICAgICBlbHNlIGlmICghLS1jb3VudCkgeyBlbmQgPSBpOyBlbmRDaCA9IHBvczsgYnJlYWsgb3V0ZXI7IH1cbiAgICAgIH1cbiAgICAgICsrcG9zO1xuICAgIH1cbiAgfVxuICBpZiAoZW5kID09IG51bGwgfHwgbGluZSA9PSBlbmQgJiYgZW5kQ2ggPT0gc3RhcnRDaCkgcmV0dXJuO1xuICByZXR1cm4ge2Zyb206IENvZGVNaXJyb3IuUG9zKGxpbmUsIHN0YXJ0Q2gpLFxuICAgICAgICAgIHRvOiBDb2RlTWlycm9yLlBvcyhlbmQsIGVuZENoKX07XG59KTtcblxuQ29kZU1pcnJvci5yZWdpc3RlckhlbHBlcihcImZvbGRcIiwgXCJpbXBvcnRcIiwgZnVuY3Rpb24oY20sIHN0YXJ0KSB7XG4gIGZ1bmN0aW9uIGhhc0ltcG9ydChsaW5lKSB7XG4gICAgaWYgKGxpbmUgPCBjbS5maXJzdExpbmUoKSB8fCBsaW5lID4gY20ubGFzdExpbmUoKSkgcmV0dXJuIG51bGw7XG4gICAgdmFyIHN0YXJ0ID0gY20uZ2V0VG9rZW5BdChDb2RlTWlycm9yLlBvcyhsaW5lLCAxKSk7XG4gICAgaWYgKCEvXFxTLy50ZXN0KHN0YXJ0LnN0cmluZykpIHN0YXJ0ID0gY20uZ2V0VG9rZW5BdChDb2RlTWlycm9yLlBvcyhsaW5lLCBzdGFydC5lbmQgKyAxKSk7XG4gICAgaWYgKHN0YXJ0LnR5cGUgIT0gXCJrZXl3b3JkXCIgfHwgc3RhcnQuc3RyaW5nICE9IFwiaW1wb3J0XCIpIHJldHVybiBudWxsO1xuICAgIC8vIE5vdyBmaW5kIGNsb3Npbmcgc2VtaWNvbG9uLCByZXR1cm4gaXRzIHBvc2l0aW9uXG4gICAgZm9yICh2YXIgaSA9IGxpbmUsIGUgPSBNYXRoLm1pbihjbS5sYXN0TGluZSgpLCBsaW5lICsgMTApOyBpIDw9IGU7ICsraSkge1xuICAgICAgdmFyIHRleHQgPSBjbS5nZXRMaW5lKGkpLCBzZW1pID0gdGV4dC5pbmRleE9mKFwiO1wiKTtcbiAgICAgIGlmIChzZW1pICE9IC0xKSByZXR1cm4ge3N0YXJ0Q2g6IHN0YXJ0LmVuZCwgZW5kOiBDb2RlTWlycm9yLlBvcyhpLCBzZW1pKX07XG4gICAgfVxuICB9XG5cbiAgdmFyIHN0YXJ0ID0gc3RhcnQubGluZSwgaGFzID0gaGFzSW1wb3J0KHN0YXJ0KSwgcHJldjtcbiAgaWYgKCFoYXMgfHwgaGFzSW1wb3J0KHN0YXJ0IC0gMSkgfHwgKChwcmV2ID0gaGFzSW1wb3J0KHN0YXJ0IC0gMikpICYmIHByZXYuZW5kLmxpbmUgPT0gc3RhcnQgLSAxKSlcbiAgICByZXR1cm4gbnVsbDtcbiAgZm9yICh2YXIgZW5kID0gaGFzLmVuZDs7KSB7XG4gICAgdmFyIG5leHQgPSBoYXNJbXBvcnQoZW5kLmxpbmUgKyAxKTtcbiAgICBpZiAobmV4dCA9PSBudWxsKSBicmVhaztcbiAgICBlbmQgPSBuZXh0LmVuZDtcbiAgfVxuICByZXR1cm4ge2Zyb206IGNtLmNsaXBQb3MoQ29kZU1pcnJvci5Qb3Moc3RhcnQsIGhhcy5zdGFydENoICsgMSkpLCB0bzogZW5kfTtcbn0pO1xuXG5Db2RlTWlycm9yLnJlZ2lzdGVySGVscGVyKFwiZm9sZFwiLCBcImluY2x1ZGVcIiwgZnVuY3Rpb24oY20sIHN0YXJ0KSB7XG4gIGZ1bmN0aW9uIGhhc0luY2x1ZGUobGluZSkge1xuICAgIGlmIChsaW5lIDwgY20uZmlyc3RMaW5lKCkgfHwgbGluZSA+IGNtLmxhc3RMaW5lKCkpIHJldHVybiBudWxsO1xuICAgIHZhciBzdGFydCA9IGNtLmdldFRva2VuQXQoQ29kZU1pcnJvci5Qb3MobGluZSwgMSkpO1xuICAgIGlmICghL1xcUy8udGVzdChzdGFydC5zdHJpbmcpKSBzdGFydCA9IGNtLmdldFRva2VuQXQoQ29kZU1pcnJvci5Qb3MobGluZSwgc3RhcnQuZW5kICsgMSkpO1xuICAgIGlmIChzdGFydC50eXBlID09IFwibWV0YVwiICYmIHN0YXJ0LnN0cmluZy5zbGljZSgwLCA4KSA9PSBcIiNpbmNsdWRlXCIpIHJldHVybiBzdGFydC5zdGFydCArIDg7XG4gIH1cblxuICB2YXIgc3RhcnQgPSBzdGFydC5saW5lLCBoYXMgPSBoYXNJbmNsdWRlKHN0YXJ0KTtcbiAgaWYgKGhhcyA9PSBudWxsIHx8IGhhc0luY2x1ZGUoc3RhcnQgLSAxKSAhPSBudWxsKSByZXR1cm4gbnVsbDtcbiAgZm9yICh2YXIgZW5kID0gc3RhcnQ7Oykge1xuICAgIHZhciBuZXh0ID0gaGFzSW5jbHVkZShlbmQgKyAxKTtcbiAgICBpZiAobmV4dCA9PSBudWxsKSBicmVhaztcbiAgICArK2VuZDtcbiAgfVxuICByZXR1cm4ge2Zyb206IENvZGVNaXJyb3IuUG9zKHN0YXJ0LCBoYXMgKyAxKSxcbiAgICAgICAgICB0bzogY20uY2xpcFBvcyhDb2RlTWlycm9yLlBvcyhlbmQpKX07XG59KTtcblxufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbihmdW5jdGlvbihtb2QpIHtcbiAgaWYgKHR5cGVvZiBleHBvcnRzID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PSBcIm9iamVjdFwiKSAvLyBDb21tb25KU1xuICAgIG1vZChyZXF1aXJlKFwiLi4vLi4vbGliL2NvZGVtaXJyb3JcIikpO1xuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSAvLyBBTURcbiAgICBkZWZpbmUoW1wiLi4vLi4vbGliL2NvZGVtaXJyb3JcIl0sIG1vZCk7XG4gIGVsc2UgLy8gUGxhaW4gYnJvd3NlciBlbnZcbiAgICBtb2QoQ29kZU1pcnJvcik7XG59KShmdW5jdGlvbihDb2RlTWlycm9yKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuXG4gIGZ1bmN0aW9uIGRvRm9sZChjbSwgcG9zLCBvcHRpb25zLCBmb3JjZSkge1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuY2FsbCkge1xuICAgICAgdmFyIGZpbmRlciA9IG9wdGlvbnM7XG4gICAgICBvcHRpb25zID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIGZpbmRlciA9IGdldE9wdGlvbihjbSwgb3B0aW9ucywgXCJyYW5nZUZpbmRlclwiKTtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBwb3MgPT0gXCJudW1iZXJcIikgcG9zID0gQ29kZU1pcnJvci5Qb3MocG9zLCAwKTtcbiAgICB2YXIgbWluU2l6ZSA9IGdldE9wdGlvbihjbSwgb3B0aW9ucywgXCJtaW5Gb2xkU2l6ZVwiKTtcblxuICAgIGZ1bmN0aW9uIGdldFJhbmdlKGFsbG93Rm9sZGVkKSB7XG4gICAgICB2YXIgcmFuZ2UgPSBmaW5kZXIoY20sIHBvcyk7XG4gICAgICBpZiAoIXJhbmdlIHx8IHJhbmdlLnRvLmxpbmUgLSByYW5nZS5mcm9tLmxpbmUgPCBtaW5TaXplKSByZXR1cm4gbnVsbDtcbiAgICAgIHZhciBtYXJrcyA9IGNtLmZpbmRNYXJrc0F0KHJhbmdlLmZyb20pO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7ICsraSkge1xuICAgICAgICBpZiAobWFya3NbaV0uX19pc0ZvbGQgJiYgZm9yY2UgIT09IFwiZm9sZFwiKSB7XG4gICAgICAgICAgaWYgKCFhbGxvd0ZvbGRlZCkgcmV0dXJuIG51bGw7XG4gICAgICAgICAgcmFuZ2UuY2xlYXJlZCA9IHRydWU7XG4gICAgICAgICAgbWFya3NbaV0uY2xlYXIoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIHJhbmdlO1xuICAgIH1cblxuICAgIHZhciByYW5nZSA9IGdldFJhbmdlKHRydWUpO1xuICAgIGlmIChnZXRPcHRpb24oY20sIG9wdGlvbnMsIFwic2NhblVwXCIpKSB3aGlsZSAoIXJhbmdlICYmIHBvcy5saW5lID4gY20uZmlyc3RMaW5lKCkpIHtcbiAgICAgIHBvcyA9IENvZGVNaXJyb3IuUG9zKHBvcy5saW5lIC0gMSwgMCk7XG4gICAgICByYW5nZSA9IGdldFJhbmdlKGZhbHNlKTtcbiAgICB9XG4gICAgaWYgKCFyYW5nZSB8fCByYW5nZS5jbGVhcmVkIHx8IGZvcmNlID09PSBcInVuZm9sZFwiKSByZXR1cm47XG5cbiAgICB2YXIgbXlXaWRnZXQgPSBtYWtlV2lkZ2V0KGNtLCBvcHRpb25zKTtcbiAgICBDb2RlTWlycm9yLm9uKG15V2lkZ2V0LCBcIm1vdXNlZG93blwiLCBmdW5jdGlvbihlKSB7XG4gICAgICBteVJhbmdlLmNsZWFyKCk7XG4gICAgICBDb2RlTWlycm9yLmVfcHJldmVudERlZmF1bHQoZSk7XG4gICAgfSk7XG4gICAgdmFyIG15UmFuZ2UgPSBjbS5tYXJrVGV4dChyYW5nZS5mcm9tLCByYW5nZS50bywge1xuICAgICAgcmVwbGFjZWRXaXRoOiBteVdpZGdldCxcbiAgICAgIGNsZWFyT25FbnRlcjogdHJ1ZSxcbiAgICAgIF9faXNGb2xkOiB0cnVlXG4gICAgfSk7XG4gICAgbXlSYW5nZS5vbihcImNsZWFyXCIsIGZ1bmN0aW9uKGZyb20sIHRvKSB7XG4gICAgICBDb2RlTWlycm9yLnNpZ25hbChjbSwgXCJ1bmZvbGRcIiwgY20sIGZyb20sIHRvKTtcbiAgICB9KTtcbiAgICBDb2RlTWlycm9yLnNpZ25hbChjbSwgXCJmb2xkXCIsIGNtLCByYW5nZS5mcm9tLCByYW5nZS50byk7XG4gIH1cblxuICBmdW5jdGlvbiBtYWtlV2lkZ2V0KGNtLCBvcHRpb25zKSB7XG4gICAgdmFyIHdpZGdldCA9IGdldE9wdGlvbihjbSwgb3B0aW9ucywgXCJ3aWRnZXRcIik7XG4gICAgaWYgKHR5cGVvZiB3aWRnZXQgPT0gXCJzdHJpbmdcIikge1xuICAgICAgdmFyIHRleHQgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh3aWRnZXQpO1xuICAgICAgd2lkZ2V0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIik7XG4gICAgICB3aWRnZXQuYXBwZW5kQ2hpbGQodGV4dCk7XG4gICAgICB3aWRnZXQuY2xhc3NOYW1lID0gXCJDb2RlTWlycm9yLWZvbGRtYXJrZXJcIjtcbiAgICB9XG4gICAgcmV0dXJuIHdpZGdldDtcbiAgfVxuXG4gIC8vIENsdW1zeSBiYWNrd2FyZHMtY29tcGF0aWJsZSBpbnRlcmZhY2VcbiAgQ29kZU1pcnJvci5uZXdGb2xkRnVuY3Rpb24gPSBmdW5jdGlvbihyYW5nZUZpbmRlciwgd2lkZ2V0KSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGNtLCBwb3MpIHsgZG9Gb2xkKGNtLCBwb3MsIHtyYW5nZUZpbmRlcjogcmFuZ2VGaW5kZXIsIHdpZGdldDogd2lkZ2V0fSk7IH07XG4gIH07XG5cbiAgLy8gTmV3LXN0eWxlIGludGVyZmFjZVxuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbihcImZvbGRDb2RlXCIsIGZ1bmN0aW9uKHBvcywgb3B0aW9ucywgZm9yY2UpIHtcbiAgICBkb0ZvbGQodGhpcywgcG9zLCBvcHRpb25zLCBmb3JjZSk7XG4gIH0pO1xuXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwiaXNGb2xkZWRcIiwgZnVuY3Rpb24ocG9zKSB7XG4gICAgdmFyIG1hcmtzID0gdGhpcy5maW5kTWFya3NBdChwb3MpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFya3MubGVuZ3RoOyArK2kpXG4gICAgICBpZiAobWFya3NbaV0uX19pc0ZvbGQpIHJldHVybiB0cnVlO1xuICB9KTtcblxuICBDb2RlTWlycm9yLmNvbW1hbmRzLnRvZ2dsZUZvbGQgPSBmdW5jdGlvbihjbSkge1xuICAgIGNtLmZvbGRDb2RlKGNtLmdldEN1cnNvcigpKTtcbiAgfTtcbiAgQ29kZU1pcnJvci5jb21tYW5kcy5mb2xkID0gZnVuY3Rpb24oY20pIHtcbiAgICBjbS5mb2xkQ29kZShjbS5nZXRDdXJzb3IoKSwgbnVsbCwgXCJmb2xkXCIpO1xuICB9O1xuICBDb2RlTWlycm9yLmNvbW1hbmRzLnVuZm9sZCA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgY20uZm9sZENvZGUoY20uZ2V0Q3Vyc29yKCksIG51bGwsIFwidW5mb2xkXCIpO1xuICB9O1xuICBDb2RlTWlycm9yLmNvbW1hbmRzLmZvbGRBbGwgPSBmdW5jdGlvbihjbSkge1xuICAgIGNtLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgIGZvciAodmFyIGkgPSBjbS5maXJzdExpbmUoKSwgZSA9IGNtLmxhc3RMaW5lKCk7IGkgPD0gZTsgaSsrKVxuICAgICAgICBjbS5mb2xkQ29kZShDb2RlTWlycm9yLlBvcyhpLCAwKSwgbnVsbCwgXCJmb2xkXCIpO1xuICAgIH0pO1xuICB9O1xuICBDb2RlTWlycm9yLmNvbW1hbmRzLnVuZm9sZEFsbCA9IGZ1bmN0aW9uKGNtKSB7XG4gICAgY20ub3BlcmF0aW9uKGZ1bmN0aW9uKCkge1xuICAgICAgZm9yICh2YXIgaSA9IGNtLmZpcnN0TGluZSgpLCBlID0gY20ubGFzdExpbmUoKTsgaSA8PSBlOyBpKyspXG4gICAgICAgIGNtLmZvbGRDb2RlKENvZGVNaXJyb3IuUG9zKGksIDApLCBudWxsLCBcInVuZm9sZFwiKTtcbiAgICB9KTtcbiAgfTtcblxuICBDb2RlTWlycm9yLnJlZ2lzdGVySGVscGVyKFwiZm9sZFwiLCBcImNvbWJpbmVcIiwgZnVuY3Rpb24oKSB7XG4gICAgdmFyIGZ1bmNzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAwKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oY20sIHN0YXJ0KSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZ1bmNzLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBmb3VuZCA9IGZ1bmNzW2ldKGNtLCBzdGFydCk7XG4gICAgICAgIGlmIChmb3VuZCkgcmV0dXJuIGZvdW5kO1xuICAgICAgfVxuICAgIH07XG4gIH0pO1xuXG4gIENvZGVNaXJyb3IucmVnaXN0ZXJIZWxwZXIoXCJmb2xkXCIsIFwiYXV0b1wiLCBmdW5jdGlvbihjbSwgc3RhcnQpIHtcbiAgICB2YXIgaGVscGVycyA9IGNtLmdldEhlbHBlcnMoc3RhcnQsIFwiZm9sZFwiKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGhlbHBlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBjdXIgPSBoZWxwZXJzW2ldKGNtLCBzdGFydCk7XG4gICAgICBpZiAoY3VyKSByZXR1cm4gY3VyO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIGRlZmF1bHRPcHRpb25zID0ge1xuICAgIHJhbmdlRmluZGVyOiBDb2RlTWlycm9yLmZvbGQuYXV0byxcbiAgICB3aWRnZXQ6IFwiXFx1MjE5NFwiLFxuICAgIG1pbkZvbGRTaXplOiAwLFxuICAgIHNjYW5VcDogZmFsc2VcbiAgfTtcblxuICBDb2RlTWlycm9yLmRlZmluZU9wdGlvbihcImZvbGRPcHRpb25zXCIsIG51bGwpO1xuXG4gIGZ1bmN0aW9uIGdldE9wdGlvbihjbSwgb3B0aW9ucywgbmFtZSkge1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnNbbmFtZV0gIT09IHVuZGVmaW5lZClcbiAgICAgIHJldHVybiBvcHRpb25zW25hbWVdO1xuICAgIHZhciBlZGl0b3JPcHRpb25zID0gY20ub3B0aW9ucy5mb2xkT3B0aW9ucztcbiAgICBpZiAoZWRpdG9yT3B0aW9ucyAmJiBlZGl0b3JPcHRpb25zW25hbWVdICE9PSB1bmRlZmluZWQpXG4gICAgICByZXR1cm4gZWRpdG9yT3B0aW9uc1tuYW1lXTtcbiAgICByZXR1cm4gZGVmYXVsdE9wdGlvbnNbbmFtZV07XG4gIH1cblxuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbihcImZvbGRPcHRpb25cIiwgZnVuY3Rpb24ob3B0aW9ucywgbmFtZSkge1xuICAgIHJldHVybiBnZXRPcHRpb24odGhpcywgb3B0aW9ucywgbmFtZSk7XG4gIH0pO1xufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbihmdW5jdGlvbihtb2QpIHtcbiAgaWYgKHR5cGVvZiBleHBvcnRzID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PSBcIm9iamVjdFwiKSAvLyBDb21tb25KU1xuICAgIG1vZChyZXF1aXJlKFwiLi4vLi4vbGliL2NvZGVtaXJyb3JcIiksIHJlcXVpcmUoXCIuL2ZvbGRjb2RlXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIsIFwiLi9mb2xkY29kZVwiXSwgbW9kKTtcbiAgZWxzZSAvLyBQbGFpbiBicm93c2VyIGVudlxuICAgIG1vZChDb2RlTWlycm9yKTtcbn0pKGZ1bmN0aW9uKENvZGVNaXJyb3IpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG5cbiAgQ29kZU1pcnJvci5kZWZpbmVPcHRpb24oXCJmb2xkR3V0dGVyXCIsIGZhbHNlLCBmdW5jdGlvbihjbSwgdmFsLCBvbGQpIHtcbiAgICBpZiAob2xkICYmIG9sZCAhPSBDb2RlTWlycm9yLkluaXQpIHtcbiAgICAgIGNtLmNsZWFyR3V0dGVyKGNtLnN0YXRlLmZvbGRHdXR0ZXIub3B0aW9ucy5ndXR0ZXIpO1xuICAgICAgY20uc3RhdGUuZm9sZEd1dHRlciA9IG51bGw7XG4gICAgICBjbS5vZmYoXCJndXR0ZXJDbGlja1wiLCBvbkd1dHRlckNsaWNrKTtcbiAgICAgIGNtLm9mZihcImNoYW5nZVwiLCBvbkNoYW5nZSk7XG4gICAgICBjbS5vZmYoXCJ2aWV3cG9ydENoYW5nZVwiLCBvblZpZXdwb3J0Q2hhbmdlKTtcbiAgICAgIGNtLm9mZihcImZvbGRcIiwgb25Gb2xkKTtcbiAgICAgIGNtLm9mZihcInVuZm9sZFwiLCBvbkZvbGQpO1xuICAgICAgY20ub2ZmKFwic3dhcERvY1wiLCB1cGRhdGVJblZpZXdwb3J0KTtcbiAgICB9XG4gICAgaWYgKHZhbCkge1xuICAgICAgY20uc3RhdGUuZm9sZEd1dHRlciA9IG5ldyBTdGF0ZShwYXJzZU9wdGlvbnModmFsKSk7XG4gICAgICB1cGRhdGVJblZpZXdwb3J0KGNtKTtcbiAgICAgIGNtLm9uKFwiZ3V0dGVyQ2xpY2tcIiwgb25HdXR0ZXJDbGljayk7XG4gICAgICBjbS5vbihcImNoYW5nZVwiLCBvbkNoYW5nZSk7XG4gICAgICBjbS5vbihcInZpZXdwb3J0Q2hhbmdlXCIsIG9uVmlld3BvcnRDaGFuZ2UpO1xuICAgICAgY20ub24oXCJmb2xkXCIsIG9uRm9sZCk7XG4gICAgICBjbS5vbihcInVuZm9sZFwiLCBvbkZvbGQpO1xuICAgICAgY20ub24oXCJzd2FwRG9jXCIsIHVwZGF0ZUluVmlld3BvcnQpO1xuICAgIH1cbiAgfSk7XG5cbiAgdmFyIFBvcyA9IENvZGVNaXJyb3IuUG9zO1xuXG4gIGZ1bmN0aW9uIFN0YXRlKG9wdGlvbnMpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuICAgIHRoaXMuZnJvbSA9IHRoaXMudG8gPSAwO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VPcHRpb25zKG9wdHMpIHtcbiAgICBpZiAob3B0cyA9PT0gdHJ1ZSkgb3B0cyA9IHt9O1xuICAgIGlmIChvcHRzLmd1dHRlciA9PSBudWxsKSBvcHRzLmd1dHRlciA9IFwiQ29kZU1pcnJvci1mb2xkZ3V0dGVyXCI7XG4gICAgaWYgKG9wdHMuaW5kaWNhdG9yT3BlbiA9PSBudWxsKSBvcHRzLmluZGljYXRvck9wZW4gPSBcIkNvZGVNaXJyb3ItZm9sZGd1dHRlci1vcGVuXCI7XG4gICAgaWYgKG9wdHMuaW5kaWNhdG9yRm9sZGVkID09IG51bGwpIG9wdHMuaW5kaWNhdG9yRm9sZGVkID0gXCJDb2RlTWlycm9yLWZvbGRndXR0ZXItZm9sZGVkXCI7XG4gICAgcmV0dXJuIG9wdHM7XG4gIH1cblxuICBmdW5jdGlvbiBpc0ZvbGRlZChjbSwgbGluZSkge1xuICAgIHZhciBtYXJrcyA9IGNtLmZpbmRNYXJrc0F0KFBvcyhsaW5lKSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrcy5sZW5ndGg7ICsraSlcbiAgICAgIGlmIChtYXJrc1tpXS5fX2lzRm9sZCAmJiBtYXJrc1tpXS5maW5kKCkuZnJvbS5saW5lID09IGxpbmUpIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gbWFya2VyKHNwZWMpIHtcbiAgICBpZiAodHlwZW9mIHNwZWMgPT0gXCJzdHJpbmdcIikge1xuICAgICAgdmFyIGVsdCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIik7XG4gICAgICBlbHQuY2xhc3NOYW1lID0gc3BlYyArIFwiIENvZGVNaXJyb3ItZ3V0dGVybWFya2VyLXN1YnRsZVwiO1xuICAgICAgcmV0dXJuIGVsdDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHNwZWMuY2xvbmVOb2RlKHRydWUpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZUZvbGRJbmZvKGNtLCBmcm9tLCB0bykge1xuICAgIHZhciBvcHRzID0gY20uc3RhdGUuZm9sZEd1dHRlci5vcHRpb25zLCBjdXIgPSBmcm9tO1xuICAgIHZhciBtaW5TaXplID0gY20uZm9sZE9wdGlvbihvcHRzLCBcIm1pbkZvbGRTaXplXCIpO1xuICAgIHZhciBmdW5jID0gY20uZm9sZE9wdGlvbihvcHRzLCBcInJhbmdlRmluZGVyXCIpO1xuICAgIGNtLmVhY2hMaW5lKGZyb20sIHRvLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICB2YXIgbWFyayA9IG51bGw7XG4gICAgICBpZiAoaXNGb2xkZWQoY20sIGN1cikpIHtcbiAgICAgICAgbWFyayA9IG1hcmtlcihvcHRzLmluZGljYXRvckZvbGRlZCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgcG9zID0gUG9zKGN1ciwgMCk7XG4gICAgICAgIHZhciByYW5nZSA9IGZ1bmMgJiYgZnVuYyhjbSwgcG9zKTtcbiAgICAgICAgaWYgKHJhbmdlICYmIHJhbmdlLnRvLmxpbmUgLSByYW5nZS5mcm9tLmxpbmUgPj0gbWluU2l6ZSlcbiAgICAgICAgICBtYXJrID0gbWFya2VyKG9wdHMuaW5kaWNhdG9yT3Blbik7XG4gICAgICB9XG4gICAgICBjbS5zZXRHdXR0ZXJNYXJrZXIobGluZSwgb3B0cy5ndXR0ZXIsIG1hcmspO1xuICAgICAgKytjdXI7XG4gICAgfSk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVJblZpZXdwb3J0KGNtKSB7XG4gICAgdmFyIHZwID0gY20uZ2V0Vmlld3BvcnQoKSwgc3RhdGUgPSBjbS5zdGF0ZS5mb2xkR3V0dGVyO1xuICAgIGlmICghc3RhdGUpIHJldHVybjtcbiAgICBjbS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG4gICAgICB1cGRhdGVGb2xkSW5mbyhjbSwgdnAuZnJvbSwgdnAudG8pO1xuICAgIH0pO1xuICAgIHN0YXRlLmZyb20gPSB2cC5mcm9tOyBzdGF0ZS50byA9IHZwLnRvO1xuICB9XG5cbiAgZnVuY3Rpb24gb25HdXR0ZXJDbGljayhjbSwgbGluZSwgZ3V0dGVyKSB7XG4gICAgdmFyIG9wdHMgPSBjbS5zdGF0ZS5mb2xkR3V0dGVyLm9wdGlvbnM7XG4gICAgaWYgKGd1dHRlciAhPSBvcHRzLmd1dHRlcikgcmV0dXJuO1xuICAgIGNtLmZvbGRDb2RlKFBvcyhsaW5lLCAwKSwgb3B0cy5yYW5nZUZpbmRlcik7XG4gIH1cblxuICBmdW5jdGlvbiBvbkNoYW5nZShjbSkge1xuICAgIHZhciBzdGF0ZSA9IGNtLnN0YXRlLmZvbGRHdXR0ZXIsIG9wdHMgPSBjbS5zdGF0ZS5mb2xkR3V0dGVyLm9wdGlvbnM7XG4gICAgc3RhdGUuZnJvbSA9IHN0YXRlLnRvID0gMDtcbiAgICBjbGVhclRpbWVvdXQoc3RhdGUuY2hhbmdlVXBkYXRlKTtcbiAgICBzdGF0ZS5jaGFuZ2VVcGRhdGUgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyB1cGRhdGVJblZpZXdwb3J0KGNtKTsgfSwgb3B0cy5mb2xkT25DaGFuZ2VUaW1lU3BhbiB8fCA2MDApO1xuICB9XG5cbiAgZnVuY3Rpb24gb25WaWV3cG9ydENoYW5nZShjbSkge1xuICAgIHZhciBzdGF0ZSA9IGNtLnN0YXRlLmZvbGRHdXR0ZXIsIG9wdHMgPSBjbS5zdGF0ZS5mb2xkR3V0dGVyLm9wdGlvbnM7XG4gICAgY2xlYXJUaW1lb3V0KHN0YXRlLmNoYW5nZVVwZGF0ZSk7XG4gICAgc3RhdGUuY2hhbmdlVXBkYXRlID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgIHZhciB2cCA9IGNtLmdldFZpZXdwb3J0KCk7XG4gICAgICBpZiAoc3RhdGUuZnJvbSA9PSBzdGF0ZS50byB8fCB2cC5mcm9tIC0gc3RhdGUudG8gPiAyMCB8fCBzdGF0ZS5mcm9tIC0gdnAudG8gPiAyMCkge1xuICAgICAgICB1cGRhdGVJblZpZXdwb3J0KGNtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNtLm9wZXJhdGlvbihmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAodnAuZnJvbSA8IHN0YXRlLmZyb20pIHtcbiAgICAgICAgICAgIHVwZGF0ZUZvbGRJbmZvKGNtLCB2cC5mcm9tLCBzdGF0ZS5mcm9tKTtcbiAgICAgICAgICAgIHN0YXRlLmZyb20gPSB2cC5mcm9tO1xuICAgICAgICAgIH1cbiAgICAgICAgICBpZiAodnAudG8gPiBzdGF0ZS50bykge1xuICAgICAgICAgICAgdXBkYXRlRm9sZEluZm8oY20sIHN0YXRlLnRvLCB2cC50byk7XG4gICAgICAgICAgICBzdGF0ZS50byA9IHZwLnRvO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfSwgb3B0cy51cGRhdGVWaWV3cG9ydFRpbWVTcGFuIHx8IDQwMCk7XG4gIH1cblxuICBmdW5jdGlvbiBvbkZvbGQoY20sIGZyb20pIHtcbiAgICB2YXIgc3RhdGUgPSBjbS5zdGF0ZS5mb2xkR3V0dGVyLCBsaW5lID0gZnJvbS5saW5lO1xuICAgIGlmIChsaW5lID49IHN0YXRlLmZyb20gJiYgbGluZSA8IHN0YXRlLnRvKVxuICAgICAgdXBkYXRlRm9sZEluZm8oY20sIGxpbmUsIGxpbmUgKyAxKTtcbiAgfVxufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbihmdW5jdGlvbihtb2QpIHtcbiAgaWYgKHR5cGVvZiBleHBvcnRzID09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZSA9PSBcIm9iamVjdFwiKSAvLyBDb21tb25KU1xuICAgIG1vZChyZXF1aXJlKFwiLi4vLi4vbGliL2NvZGVtaXJyb3JcIikpO1xuICBlbHNlIGlmICh0eXBlb2YgZGVmaW5lID09IFwiZnVuY3Rpb25cIiAmJiBkZWZpbmUuYW1kKSAvLyBBTURcbiAgICBkZWZpbmUoW1wiLi4vLi4vbGliL2NvZGVtaXJyb3JcIl0sIG1vZCk7XG4gIGVsc2UgLy8gUGxhaW4gYnJvd3NlciBlbnZcbiAgICBtb2QoQ29kZU1pcnJvcik7XG59KShmdW5jdGlvbihDb2RlTWlycm9yKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuXG4gIHZhciBQb3MgPSBDb2RlTWlycm9yLlBvcztcbiAgZnVuY3Rpb24gY21wKGEsIGIpIHsgcmV0dXJuIGEubGluZSAtIGIubGluZSB8fCBhLmNoIC0gYi5jaDsgfVxuXG4gIHZhciBuYW1lU3RhcnRDaGFyID0gXCJBLVpfYS16XFxcXHUwMEMwLVxcXFx1MDBENlxcXFx1MDBEOC1cXFxcdTAwRjZcXFxcdTAwRjgtXFxcXHUwMkZGXFxcXHUwMzcwLVxcXFx1MDM3RFxcXFx1MDM3Ri1cXFxcdTFGRkZcXFxcdTIwMEMtXFxcXHUyMDBEXFxcXHUyMDcwLVxcXFx1MjE4RlxcXFx1MkMwMC1cXFxcdTJGRUZcXFxcdTMwMDEtXFxcXHVEN0ZGXFxcXHVGOTAwLVxcXFx1RkRDRlxcXFx1RkRGMC1cXFxcdUZGRkRcIjtcbiAgdmFyIG5hbWVDaGFyID0gbmFtZVN0YXJ0Q2hhciArIFwiXFwtXFw6XFwuMC05XFxcXHUwMEI3XFxcXHUwMzAwLVxcXFx1MDM2RlxcXFx1MjAzRi1cXFxcdTIwNDBcIjtcbiAgdmFyIHhtbFRhZ1N0YXJ0ID0gbmV3IFJlZ0V4cChcIjwoLz8pKFtcIiArIG5hbWVTdGFydENoYXIgKyBcIl1bXCIgKyBuYW1lQ2hhciArIFwiXSopXCIsIFwiZ1wiKTtcblxuICBmdW5jdGlvbiBJdGVyKGNtLCBsaW5lLCBjaCwgcmFuZ2UpIHtcbiAgICB0aGlzLmxpbmUgPSBsaW5lOyB0aGlzLmNoID0gY2g7XG4gICAgdGhpcy5jbSA9IGNtOyB0aGlzLnRleHQgPSBjbS5nZXRMaW5lKGxpbmUpO1xuICAgIHRoaXMubWluID0gcmFuZ2UgPyByYW5nZS5mcm9tIDogY20uZmlyc3RMaW5lKCk7XG4gICAgdGhpcy5tYXggPSByYW5nZSA/IHJhbmdlLnRvIC0gMSA6IGNtLmxhc3RMaW5lKCk7XG4gIH1cblxuICBmdW5jdGlvbiB0YWdBdChpdGVyLCBjaCkge1xuICAgIHZhciB0eXBlID0gaXRlci5jbS5nZXRUb2tlblR5cGVBdChQb3MoaXRlci5saW5lLCBjaCkpO1xuICAgIHJldHVybiB0eXBlICYmIC9cXGJ0YWdcXGIvLnRlc3QodHlwZSk7XG4gIH1cblxuICBmdW5jdGlvbiBuZXh0TGluZShpdGVyKSB7XG4gICAgaWYgKGl0ZXIubGluZSA+PSBpdGVyLm1heCkgcmV0dXJuO1xuICAgIGl0ZXIuY2ggPSAwO1xuICAgIGl0ZXIudGV4dCA9IGl0ZXIuY20uZ2V0TGluZSgrK2l0ZXIubGluZSk7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cbiAgZnVuY3Rpb24gcHJldkxpbmUoaXRlcikge1xuICAgIGlmIChpdGVyLmxpbmUgPD0gaXRlci5taW4pIHJldHVybjtcbiAgICBpdGVyLnRleHQgPSBpdGVyLmNtLmdldExpbmUoLS1pdGVyLmxpbmUpO1xuICAgIGl0ZXIuY2ggPSBpdGVyLnRleHQubGVuZ3RoO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gdG9UYWdFbmQoaXRlcikge1xuICAgIGZvciAoOzspIHtcbiAgICAgIHZhciBndCA9IGl0ZXIudGV4dC5pbmRleE9mKFwiPlwiLCBpdGVyLmNoKTtcbiAgICAgIGlmIChndCA9PSAtMSkgeyBpZiAobmV4dExpbmUoaXRlcikpIGNvbnRpbnVlOyBlbHNlIHJldHVybjsgfVxuICAgICAgaWYgKCF0YWdBdChpdGVyLCBndCArIDEpKSB7IGl0ZXIuY2ggPSBndCArIDE7IGNvbnRpbnVlOyB9XG4gICAgICB2YXIgbGFzdFNsYXNoID0gaXRlci50ZXh0Lmxhc3RJbmRleE9mKFwiL1wiLCBndCk7XG4gICAgICB2YXIgc2VsZkNsb3NlID0gbGFzdFNsYXNoID4gLTEgJiYgIS9cXFMvLnRlc3QoaXRlci50ZXh0LnNsaWNlKGxhc3RTbGFzaCArIDEsIGd0KSk7XG4gICAgICBpdGVyLmNoID0gZ3QgKyAxO1xuICAgICAgcmV0dXJuIHNlbGZDbG9zZSA/IFwic2VsZkNsb3NlXCIgOiBcInJlZ3VsYXJcIjtcbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gdG9UYWdTdGFydChpdGVyKSB7XG4gICAgZm9yICg7Oykge1xuICAgICAgdmFyIGx0ID0gaXRlci5jaCA/IGl0ZXIudGV4dC5sYXN0SW5kZXhPZihcIjxcIiwgaXRlci5jaCAtIDEpIDogLTE7XG4gICAgICBpZiAobHQgPT0gLTEpIHsgaWYgKHByZXZMaW5lKGl0ZXIpKSBjb250aW51ZTsgZWxzZSByZXR1cm47IH1cbiAgICAgIGlmICghdGFnQXQoaXRlciwgbHQgKyAxKSkgeyBpdGVyLmNoID0gbHQ7IGNvbnRpbnVlOyB9XG4gICAgICB4bWxUYWdTdGFydC5sYXN0SW5kZXggPSBsdDtcbiAgICAgIGl0ZXIuY2ggPSBsdDtcbiAgICAgIHZhciBtYXRjaCA9IHhtbFRhZ1N0YXJ0LmV4ZWMoaXRlci50ZXh0KTtcbiAgICAgIGlmIChtYXRjaCAmJiBtYXRjaC5pbmRleCA9PSBsdCkgcmV0dXJuIG1hdGNoO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHRvTmV4dFRhZyhpdGVyKSB7XG4gICAgZm9yICg7Oykge1xuICAgICAgeG1sVGFnU3RhcnQubGFzdEluZGV4ID0gaXRlci5jaDtcbiAgICAgIHZhciBmb3VuZCA9IHhtbFRhZ1N0YXJ0LmV4ZWMoaXRlci50ZXh0KTtcbiAgICAgIGlmICghZm91bmQpIHsgaWYgKG5leHRMaW5lKGl0ZXIpKSBjb250aW51ZTsgZWxzZSByZXR1cm47IH1cbiAgICAgIGlmICghdGFnQXQoaXRlciwgZm91bmQuaW5kZXggKyAxKSkgeyBpdGVyLmNoID0gZm91bmQuaW5kZXggKyAxOyBjb250aW51ZTsgfVxuICAgICAgaXRlci5jaCA9IGZvdW5kLmluZGV4ICsgZm91bmRbMF0ubGVuZ3RoO1xuICAgICAgcmV0dXJuIGZvdW5kO1xuICAgIH1cbiAgfVxuICBmdW5jdGlvbiB0b1ByZXZUYWcoaXRlcikge1xuICAgIGZvciAoOzspIHtcbiAgICAgIHZhciBndCA9IGl0ZXIuY2ggPyBpdGVyLnRleHQubGFzdEluZGV4T2YoXCI+XCIsIGl0ZXIuY2ggLSAxKSA6IC0xO1xuICAgICAgaWYgKGd0ID09IC0xKSB7IGlmIChwcmV2TGluZShpdGVyKSkgY29udGludWU7IGVsc2UgcmV0dXJuOyB9XG4gICAgICBpZiAoIXRhZ0F0KGl0ZXIsIGd0ICsgMSkpIHsgaXRlci5jaCA9IGd0OyBjb250aW51ZTsgfVxuICAgICAgdmFyIGxhc3RTbGFzaCA9IGl0ZXIudGV4dC5sYXN0SW5kZXhPZihcIi9cIiwgZ3QpO1xuICAgICAgdmFyIHNlbGZDbG9zZSA9IGxhc3RTbGFzaCA+IC0xICYmICEvXFxTLy50ZXN0KGl0ZXIudGV4dC5zbGljZShsYXN0U2xhc2ggKyAxLCBndCkpO1xuICAgICAgaXRlci5jaCA9IGd0ICsgMTtcbiAgICAgIHJldHVybiBzZWxmQ2xvc2UgPyBcInNlbGZDbG9zZVwiIDogXCJyZWd1bGFyXCI7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZmluZE1hdGNoaW5nQ2xvc2UoaXRlciwgdGFnKSB7XG4gICAgdmFyIHN0YWNrID0gW107XG4gICAgZm9yICg7Oykge1xuICAgICAgdmFyIG5leHQgPSB0b05leHRUYWcoaXRlciksIGVuZCwgc3RhcnRMaW5lID0gaXRlci5saW5lLCBzdGFydENoID0gaXRlci5jaCAtIChuZXh0ID8gbmV4dFswXS5sZW5ndGggOiAwKTtcbiAgICAgIGlmICghbmV4dCB8fCAhKGVuZCA9IHRvVGFnRW5kKGl0ZXIpKSkgcmV0dXJuO1xuICAgICAgaWYgKGVuZCA9PSBcInNlbGZDbG9zZVwiKSBjb250aW51ZTtcbiAgICAgIGlmIChuZXh0WzFdKSB7IC8vIGNsb3NpbmcgdGFnXG4gICAgICAgIGZvciAodmFyIGkgPSBzdGFjay5sZW5ndGggLSAxOyBpID49IDA7IC0taSkgaWYgKHN0YWNrW2ldID09IG5leHRbMl0pIHtcbiAgICAgICAgICBzdGFjay5sZW5ndGggPSBpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGlmIChpIDwgMCAmJiAoIXRhZyB8fCB0YWcgPT0gbmV4dFsyXSkpIHJldHVybiB7XG4gICAgICAgICAgdGFnOiBuZXh0WzJdLFxuICAgICAgICAgIGZyb206IFBvcyhzdGFydExpbmUsIHN0YXJ0Q2gpLFxuICAgICAgICAgIHRvOiBQb3MoaXRlci5saW5lLCBpdGVyLmNoKVxuICAgICAgICB9O1xuICAgICAgfSBlbHNlIHsgLy8gb3BlbmluZyB0YWdcbiAgICAgICAgc3RhY2sucHVzaChuZXh0WzJdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gZmluZE1hdGNoaW5nT3BlbihpdGVyLCB0YWcpIHtcbiAgICB2YXIgc3RhY2sgPSBbXTtcbiAgICBmb3IgKDs7KSB7XG4gICAgICB2YXIgcHJldiA9IHRvUHJldlRhZyhpdGVyKTtcbiAgICAgIGlmICghcHJldikgcmV0dXJuO1xuICAgICAgaWYgKHByZXYgPT0gXCJzZWxmQ2xvc2VcIikgeyB0b1RhZ1N0YXJ0KGl0ZXIpOyBjb250aW51ZTsgfVxuICAgICAgdmFyIGVuZExpbmUgPSBpdGVyLmxpbmUsIGVuZENoID0gaXRlci5jaDtcbiAgICAgIHZhciBzdGFydCA9IHRvVGFnU3RhcnQoaXRlcik7XG4gICAgICBpZiAoIXN0YXJ0KSByZXR1cm47XG4gICAgICBpZiAoc3RhcnRbMV0pIHsgLy8gY2xvc2luZyB0YWdcbiAgICAgICAgc3RhY2sucHVzaChzdGFydFsyXSk7XG4gICAgICB9IGVsc2UgeyAvLyBvcGVuaW5nIHRhZ1xuICAgICAgICBmb3IgKHZhciBpID0gc3RhY2subGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpIGlmIChzdGFja1tpXSA9PSBzdGFydFsyXSkge1xuICAgICAgICAgIHN0YWNrLmxlbmd0aCA9IGk7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGkgPCAwICYmICghdGFnIHx8IHRhZyA9PSBzdGFydFsyXSkpIHJldHVybiB7XG4gICAgICAgICAgdGFnOiBzdGFydFsyXSxcbiAgICAgICAgICBmcm9tOiBQb3MoaXRlci5saW5lLCBpdGVyLmNoKSxcbiAgICAgICAgICB0bzogUG9zKGVuZExpbmUsIGVuZENoKVxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIENvZGVNaXJyb3IucmVnaXN0ZXJIZWxwZXIoXCJmb2xkXCIsIFwieG1sXCIsIGZ1bmN0aW9uKGNtLCBzdGFydCkge1xuICAgIHZhciBpdGVyID0gbmV3IEl0ZXIoY20sIHN0YXJ0LmxpbmUsIDApO1xuICAgIGZvciAoOzspIHtcbiAgICAgIHZhciBvcGVuVGFnID0gdG9OZXh0VGFnKGl0ZXIpLCBlbmQ7XG4gICAgICBpZiAoIW9wZW5UYWcgfHwgaXRlci5saW5lICE9IHN0YXJ0LmxpbmUgfHwgIShlbmQgPSB0b1RhZ0VuZChpdGVyKSkpIHJldHVybjtcbiAgICAgIGlmICghb3BlblRhZ1sxXSAmJiBlbmQgIT0gXCJzZWxmQ2xvc2VcIikge1xuICAgICAgICB2YXIgc3RhcnQgPSBQb3MoaXRlci5saW5lLCBpdGVyLmNoKTtcbiAgICAgICAgdmFyIGNsb3NlID0gZmluZE1hdGNoaW5nQ2xvc2UoaXRlciwgb3BlblRhZ1syXSk7XG4gICAgICAgIHJldHVybiBjbG9zZSAmJiB7ZnJvbTogc3RhcnQsIHRvOiBjbG9zZS5mcm9tfTtcbiAgICAgIH1cbiAgICB9XG4gIH0pO1xuICBDb2RlTWlycm9yLmZpbmRNYXRjaGluZ1RhZyA9IGZ1bmN0aW9uKGNtLCBwb3MsIHJhbmdlKSB7XG4gICAgdmFyIGl0ZXIgPSBuZXcgSXRlcihjbSwgcG9zLmxpbmUsIHBvcy5jaCwgcmFuZ2UpO1xuICAgIGlmIChpdGVyLnRleHQuaW5kZXhPZihcIj5cIikgPT0gLTEgJiYgaXRlci50ZXh0LmluZGV4T2YoXCI8XCIpID09IC0xKSByZXR1cm47XG4gICAgdmFyIGVuZCA9IHRvVGFnRW5kKGl0ZXIpLCB0byA9IGVuZCAmJiBQb3MoaXRlci5saW5lLCBpdGVyLmNoKTtcbiAgICB2YXIgc3RhcnQgPSBlbmQgJiYgdG9UYWdTdGFydChpdGVyKTtcbiAgICBpZiAoIWVuZCB8fCAhc3RhcnQgfHwgY21wKGl0ZXIsIHBvcykgPiAwKSByZXR1cm47XG4gICAgdmFyIGhlcmUgPSB7ZnJvbTogUG9zKGl0ZXIubGluZSwgaXRlci5jaCksIHRvOiB0bywgdGFnOiBzdGFydFsyXX07XG4gICAgaWYgKGVuZCA9PSBcInNlbGZDbG9zZVwiKSByZXR1cm4ge29wZW46IGhlcmUsIGNsb3NlOiBudWxsLCBhdDogXCJvcGVuXCJ9O1xuXG4gICAgaWYgKHN0YXJ0WzFdKSB7IC8vIGNsb3NpbmcgdGFnXG4gICAgICByZXR1cm4ge29wZW46IGZpbmRNYXRjaGluZ09wZW4oaXRlciwgc3RhcnRbMl0pLCBjbG9zZTogaGVyZSwgYXQ6IFwiY2xvc2VcIn07XG4gICAgfSBlbHNlIHsgLy8gb3BlbmluZyB0YWdcbiAgICAgIGl0ZXIgPSBuZXcgSXRlcihjbSwgdG8ubGluZSwgdG8uY2gsIHJhbmdlKTtcbiAgICAgIHJldHVybiB7b3BlbjogaGVyZSwgY2xvc2U6IGZpbmRNYXRjaGluZ0Nsb3NlKGl0ZXIsIHN0YXJ0WzJdKSwgYXQ6IFwib3BlblwifTtcbiAgICB9XG4gIH07XG5cbiAgQ29kZU1pcnJvci5maW5kRW5jbG9zaW5nVGFnID0gZnVuY3Rpb24oY20sIHBvcywgcmFuZ2UpIHtcbiAgICB2YXIgaXRlciA9IG5ldyBJdGVyKGNtLCBwb3MubGluZSwgcG9zLmNoLCByYW5nZSk7XG4gICAgZm9yICg7Oykge1xuICAgICAgdmFyIG9wZW4gPSBmaW5kTWF0Y2hpbmdPcGVuKGl0ZXIpO1xuICAgICAgaWYgKCFvcGVuKSBicmVhaztcbiAgICAgIHZhciBmb3J3YXJkID0gbmV3IEl0ZXIoY20sIHBvcy5saW5lLCBwb3MuY2gsIHJhbmdlKTtcbiAgICAgIHZhciBjbG9zZSA9IGZpbmRNYXRjaGluZ0Nsb3NlKGZvcndhcmQsIG9wZW4udGFnKTtcbiAgICAgIGlmIChjbG9zZSkgcmV0dXJuIHtvcGVuOiBvcGVuLCBjbG9zZTogY2xvc2V9O1xuICAgIH1cbiAgfTtcblxuICAvLyBVc2VkIGJ5IGFkZG9uL2VkaXQvY2xvc2V0YWcuanNcbiAgQ29kZU1pcnJvci5zY2FuRm9yQ2xvc2luZ1RhZyA9IGZ1bmN0aW9uKGNtLCBwb3MsIG5hbWUsIGVuZCkge1xuICAgIHZhciBpdGVyID0gbmV3IEl0ZXIoY20sIHBvcy5saW5lLCBwb3MuY2gsIGVuZCA/IHtmcm9tOiAwLCB0bzogZW5kfSA6IG51bGwpO1xuICAgIHJldHVybiBmaW5kTWF0Y2hpbmdDbG9zZShpdGVyLCBuYW1lKTtcbiAgfTtcbn0pO1xuIiwiLy8gQ29kZU1pcnJvciwgY29weXJpZ2h0IChjKSBieSBNYXJpam4gSGF2ZXJiZWtlIGFuZCBvdGhlcnNcbi8vIERpc3RyaWJ1dGVkIHVuZGVyIGFuIE1JVCBsaWNlbnNlOiBodHRwOi8vY29kZW1pcnJvci5uZXQvTElDRU5TRVxuXG4oZnVuY3Rpb24obW9kKSB7XG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT0gXCJvYmplY3RcIikgLy8gQ29tbW9uSlNcbiAgICBtb2QocmVxdWlyZShcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuICBcInVzZSBzdHJpY3RcIjtcblxuICB2YXIgSElOVF9FTEVNRU5UX0NMQVNTICAgICAgICA9IFwiQ29kZU1pcnJvci1oaW50XCI7XG4gIHZhciBBQ1RJVkVfSElOVF9FTEVNRU5UX0NMQVNTID0gXCJDb2RlTWlycm9yLWhpbnQtYWN0aXZlXCI7XG5cbiAgLy8gVGhpcyBpcyB0aGUgb2xkIGludGVyZmFjZSwga2VwdCBhcm91bmQgZm9yIG5vdyB0byBzdGF5XG4gIC8vIGJhY2t3YXJkcy1jb21wYXRpYmxlLlxuICBDb2RlTWlycm9yLnNob3dIaW50ID0gZnVuY3Rpb24oY20sIGdldEhpbnRzLCBvcHRpb25zKSB7XG4gICAgaWYgKCFnZXRIaW50cykgcmV0dXJuIGNtLnNob3dIaW50KG9wdGlvbnMpO1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuYXN5bmMpIGdldEhpbnRzLmFzeW5jID0gdHJ1ZTtcbiAgICB2YXIgbmV3T3B0cyA9IHtoaW50OiBnZXRIaW50c307XG4gICAgaWYgKG9wdGlvbnMpIGZvciAodmFyIHByb3AgaW4gb3B0aW9ucykgbmV3T3B0c1twcm9wXSA9IG9wdGlvbnNbcHJvcF07XG4gICAgcmV0dXJuIGNtLnNob3dIaW50KG5ld09wdHMpO1xuICB9O1xuXG4gIENvZGVNaXJyb3IuZGVmaW5lRXh0ZW5zaW9uKFwic2hvd0hpbnRcIiwgZnVuY3Rpb24ob3B0aW9ucykge1xuICAgIC8vIFdlIHdhbnQgYSBzaW5nbGUgY3Vyc29yIHBvc2l0aW9uLlxuICAgIGlmICh0aGlzLmxpc3RTZWxlY3Rpb25zKCkubGVuZ3RoID4gMSB8fCB0aGlzLnNvbWV0aGluZ1NlbGVjdGVkKCkpIHJldHVybjtcblxuICAgIGlmICh0aGlzLnN0YXRlLmNvbXBsZXRpb25BY3RpdmUpIHRoaXMuc3RhdGUuY29tcGxldGlvbkFjdGl2ZS5jbG9zZSgpO1xuICAgIHZhciBjb21wbGV0aW9uID0gdGhpcy5zdGF0ZS5jb21wbGV0aW9uQWN0aXZlID0gbmV3IENvbXBsZXRpb24odGhpcywgb3B0aW9ucyk7XG4gICAgdmFyIGdldEhpbnRzID0gY29tcGxldGlvbi5vcHRpb25zLmhpbnQ7XG4gICAgaWYgKCFnZXRIaW50cykgcmV0dXJuO1xuXG4gICAgQ29kZU1pcnJvci5zaWduYWwodGhpcywgXCJzdGFydENvbXBsZXRpb25cIiwgdGhpcyk7XG4gICAgaWYgKGdldEhpbnRzLmFzeW5jKVxuICAgICAgZ2V0SGludHModGhpcywgZnVuY3Rpb24oaGludHMpIHsgY29tcGxldGlvbi5zaG93SGludHMoaGludHMpOyB9LCBjb21wbGV0aW9uLm9wdGlvbnMpO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiBjb21wbGV0aW9uLnNob3dIaW50cyhnZXRIaW50cyh0aGlzLCBjb21wbGV0aW9uLm9wdGlvbnMpKTtcbiAgfSk7XG5cbiAgZnVuY3Rpb24gQ29tcGxldGlvbihjbSwgb3B0aW9ucykge1xuICAgIHRoaXMuY20gPSBjbTtcbiAgICB0aGlzLm9wdGlvbnMgPSB0aGlzLmJ1aWxkT3B0aW9ucyhvcHRpb25zKTtcbiAgICB0aGlzLndpZGdldCA9IHRoaXMub25DbG9zZSA9IG51bGw7XG4gIH1cblxuICBDb21wbGV0aW9uLnByb3RvdHlwZSA9IHtcbiAgICBjbG9zZTogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoIXRoaXMuYWN0aXZlKCkpIHJldHVybjtcbiAgICAgIHRoaXMuY20uc3RhdGUuY29tcGxldGlvbkFjdGl2ZSA9IG51bGw7XG5cbiAgICAgIGlmICh0aGlzLndpZGdldCkgdGhpcy53aWRnZXQuY2xvc2UoKTtcbiAgICAgIGlmICh0aGlzLm9uQ2xvc2UpIHRoaXMub25DbG9zZSgpO1xuICAgICAgQ29kZU1pcnJvci5zaWduYWwodGhpcy5jbSwgXCJlbmRDb21wbGV0aW9uXCIsIHRoaXMuY20pO1xuICAgIH0sXG5cbiAgICBhY3RpdmU6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuY20uc3RhdGUuY29tcGxldGlvbkFjdGl2ZSA9PSB0aGlzO1xuICAgIH0sXG5cbiAgICBwaWNrOiBmdW5jdGlvbihkYXRhLCBpKSB7XG4gICAgICB2YXIgY29tcGxldGlvbiA9IGRhdGEubGlzdFtpXTtcbiAgICAgIGlmIChjb21wbGV0aW9uLmhpbnQpIGNvbXBsZXRpb24uaGludCh0aGlzLmNtLCBkYXRhLCBjb21wbGV0aW9uKTtcbiAgICAgIGVsc2UgdGhpcy5jbS5yZXBsYWNlUmFuZ2UoZ2V0VGV4dChjb21wbGV0aW9uKSwgY29tcGxldGlvbi5mcm9tIHx8IGRhdGEuZnJvbSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tcGxldGlvbi50byB8fCBkYXRhLnRvLCBcImNvbXBsZXRlXCIpO1xuICAgICAgQ29kZU1pcnJvci5zaWduYWwoZGF0YSwgXCJwaWNrXCIsIGNvbXBsZXRpb24pO1xuICAgICAgdGhpcy5jbG9zZSgpO1xuICAgIH0sXG5cbiAgICBzaG93SGludHM6IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICAgIGlmICghZGF0YSB8fCAhZGF0YS5saXN0Lmxlbmd0aCB8fCAhdGhpcy5hY3RpdmUoKSkgcmV0dXJuIHRoaXMuY2xvc2UoKTtcblxuICAgICAgaWYgKHRoaXMub3B0aW9ucy5jb21wbGV0ZVNpbmdsZSAmJiBkYXRhLmxpc3QubGVuZ3RoID09IDEpXG4gICAgICAgIHRoaXMucGljayhkYXRhLCAwKTtcbiAgICAgIGVsc2VcbiAgICAgICAgdGhpcy5zaG93V2lkZ2V0KGRhdGEpO1xuICAgIH0sXG5cbiAgICBzaG93V2lkZ2V0OiBmdW5jdGlvbihkYXRhKSB7XG4gICAgICB0aGlzLndpZGdldCA9IG5ldyBXaWRnZXQodGhpcywgZGF0YSk7XG4gICAgICBDb2RlTWlycm9yLnNpZ25hbChkYXRhLCBcInNob3duXCIpO1xuXG4gICAgICB2YXIgZGVib3VuY2UgPSAwLCBjb21wbGV0aW9uID0gdGhpcywgZmluaXNoZWQ7XG4gICAgICB2YXIgY2xvc2VPbiA9IHRoaXMub3B0aW9ucy5jbG9zZUNoYXJhY3RlcnM7XG4gICAgICB2YXIgc3RhcnRQb3MgPSB0aGlzLmNtLmdldEN1cnNvcigpLCBzdGFydExlbiA9IHRoaXMuY20uZ2V0TGluZShzdGFydFBvcy5saW5lKS5sZW5ndGg7XG5cbiAgICAgIHZhciByZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPSB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lIHx8IGZ1bmN0aW9uKGZuKSB7XG4gICAgICAgIHJldHVybiBzZXRUaW1lb3V0KGZuLCAxMDAwLzYwKTtcbiAgICAgIH07XG4gICAgICB2YXIgY2FuY2VsQW5pbWF0aW9uRnJhbWUgPSB3aW5kb3cuY2FuY2VsQW5pbWF0aW9uRnJhbWUgfHwgY2xlYXJUaW1lb3V0O1xuXG4gICAgICBmdW5jdGlvbiBkb25lKCkge1xuICAgICAgICBpZiAoZmluaXNoZWQpIHJldHVybjtcbiAgICAgICAgZmluaXNoZWQgPSB0cnVlO1xuICAgICAgICBjb21wbGV0aW9uLmNsb3NlKCk7XG4gICAgICAgIGNvbXBsZXRpb24uY20ub2ZmKFwiY3Vyc29yQWN0aXZpdHlcIiwgYWN0aXZpdHkpO1xuICAgICAgICBpZiAoZGF0YSkgQ29kZU1pcnJvci5zaWduYWwoZGF0YSwgXCJjbG9zZVwiKTtcbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gdXBkYXRlKCkge1xuICAgICAgICBpZiAoZmluaXNoZWQpIHJldHVybjtcbiAgICAgICAgQ29kZU1pcnJvci5zaWduYWwoZGF0YSwgXCJ1cGRhdGVcIik7XG4gICAgICAgIHZhciBnZXRIaW50cyA9IGNvbXBsZXRpb24ub3B0aW9ucy5oaW50O1xuICAgICAgICBpZiAoZ2V0SGludHMuYXN5bmMpXG4gICAgICAgICAgZ2V0SGludHMoY29tcGxldGlvbi5jbSwgZmluaXNoVXBkYXRlLCBjb21wbGV0aW9uLm9wdGlvbnMpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgZmluaXNoVXBkYXRlKGdldEhpbnRzKGNvbXBsZXRpb24uY20sIGNvbXBsZXRpb24ub3B0aW9ucykpO1xuICAgICAgfVxuICAgICAgZnVuY3Rpb24gZmluaXNoVXBkYXRlKGRhdGFfKSB7XG4gICAgICAgIGRhdGEgPSBkYXRhXztcbiAgICAgICAgaWYgKGZpbmlzaGVkKSByZXR1cm47XG4gICAgICAgIGlmICghZGF0YSB8fCAhZGF0YS5saXN0Lmxlbmd0aCkgcmV0dXJuIGRvbmUoKTtcbiAgICAgICAgaWYgKGNvbXBsZXRpb24ud2lkZ2V0KSBjb21wbGV0aW9uLndpZGdldC5jbG9zZSgpO1xuICAgICAgICBjb21wbGV0aW9uLndpZGdldCA9IG5ldyBXaWRnZXQoY29tcGxldGlvbiwgZGF0YSk7XG4gICAgICB9XG5cbiAgICAgIGZ1bmN0aW9uIGNsZWFyRGVib3VuY2UoKSB7XG4gICAgICAgIGlmIChkZWJvdW5jZSkge1xuICAgICAgICAgIGNhbmNlbEFuaW1hdGlvbkZyYW1lKGRlYm91bmNlKTtcbiAgICAgICAgICBkZWJvdW5jZSA9IDA7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgZnVuY3Rpb24gYWN0aXZpdHkoKSB7XG4gICAgICAgIGNsZWFyRGVib3VuY2UoKTtcbiAgICAgICAgdmFyIHBvcyA9IGNvbXBsZXRpb24uY20uZ2V0Q3Vyc29yKCksIGxpbmUgPSBjb21wbGV0aW9uLmNtLmdldExpbmUocG9zLmxpbmUpO1xuICAgICAgICBpZiAocG9zLmxpbmUgIT0gc3RhcnRQb3MubGluZSB8fCBsaW5lLmxlbmd0aCAtIHBvcy5jaCAhPSBzdGFydExlbiAtIHN0YXJ0UG9zLmNoIHx8XG4gICAgICAgICAgICBwb3MuY2ggPCBzdGFydFBvcy5jaCB8fCBjb21wbGV0aW9uLmNtLnNvbWV0aGluZ1NlbGVjdGVkKCkgfHxcbiAgICAgICAgICAgIChwb3MuY2ggJiYgY2xvc2VPbi50ZXN0KGxpbmUuY2hhckF0KHBvcy5jaCAtIDEpKSkpIHtcbiAgICAgICAgICBjb21wbGV0aW9uLmNsb3NlKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGVib3VuY2UgPSByZXF1ZXN0QW5pbWF0aW9uRnJhbWUodXBkYXRlKTtcbiAgICAgICAgICBpZiAoY29tcGxldGlvbi53aWRnZXQpIGNvbXBsZXRpb24ud2lkZ2V0LmNsb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuY20ub24oXCJjdXJzb3JBY3Rpdml0eVwiLCBhY3Rpdml0eSk7XG4gICAgICB0aGlzLm9uQ2xvc2UgPSBkb25lO1xuICAgIH0sXG5cbiAgICBidWlsZE9wdGlvbnM6IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgICAgIHZhciBlZGl0b3IgPSB0aGlzLmNtLm9wdGlvbnMuaGludE9wdGlvbnM7XG4gICAgICB2YXIgb3V0ID0ge307XG4gICAgICBmb3IgKHZhciBwcm9wIGluIGRlZmF1bHRPcHRpb25zKSBvdXRbcHJvcF0gPSBkZWZhdWx0T3B0aW9uc1twcm9wXTtcbiAgICAgIGlmIChlZGl0b3IpIGZvciAodmFyIHByb3AgaW4gZWRpdG9yKVxuICAgICAgICBpZiAoZWRpdG9yW3Byb3BdICE9PSB1bmRlZmluZWQpIG91dFtwcm9wXSA9IGVkaXRvcltwcm9wXTtcbiAgICAgIGlmIChvcHRpb25zKSBmb3IgKHZhciBwcm9wIGluIG9wdGlvbnMpXG4gICAgICAgIGlmIChvcHRpb25zW3Byb3BdICE9PSB1bmRlZmluZWQpIG91dFtwcm9wXSA9IG9wdGlvbnNbcHJvcF07XG4gICAgICByZXR1cm4gb3V0O1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBnZXRUZXh0KGNvbXBsZXRpb24pIHtcbiAgICBpZiAodHlwZW9mIGNvbXBsZXRpb24gPT0gXCJzdHJpbmdcIikgcmV0dXJuIGNvbXBsZXRpb247XG4gICAgZWxzZSByZXR1cm4gY29tcGxldGlvbi50ZXh0O1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRLZXlNYXAoY29tcGxldGlvbiwgaGFuZGxlKSB7XG4gICAgdmFyIGJhc2VNYXAgPSB7XG4gICAgICBVcDogZnVuY3Rpb24oKSB7aGFuZGxlLm1vdmVGb2N1cygtMSk7fSxcbiAgICAgIERvd246IGZ1bmN0aW9uKCkge2hhbmRsZS5tb3ZlRm9jdXMoMSk7fSxcbiAgICAgIFBhZ2VVcDogZnVuY3Rpb24oKSB7aGFuZGxlLm1vdmVGb2N1cygtaGFuZGxlLm1lbnVTaXplKCkgKyAxLCB0cnVlKTt9LFxuICAgICAgUGFnZURvd246IGZ1bmN0aW9uKCkge2hhbmRsZS5tb3ZlRm9jdXMoaGFuZGxlLm1lbnVTaXplKCkgLSAxLCB0cnVlKTt9LFxuICAgICAgSG9tZTogZnVuY3Rpb24oKSB7aGFuZGxlLnNldEZvY3VzKDApO30sXG4gICAgICBFbmQ6IGZ1bmN0aW9uKCkge2hhbmRsZS5zZXRGb2N1cyhoYW5kbGUubGVuZ3RoIC0gMSk7fSxcbiAgICAgIEVudGVyOiBoYW5kbGUucGljayxcbiAgICAgIFRhYjogaGFuZGxlLnBpY2ssXG4gICAgICBFc2M6IGhhbmRsZS5jbG9zZVxuICAgIH07XG4gICAgdmFyIGN1c3RvbSA9IGNvbXBsZXRpb24ub3B0aW9ucy5jdXN0b21LZXlzO1xuICAgIHZhciBvdXJNYXAgPSBjdXN0b20gPyB7fSA6IGJhc2VNYXA7XG4gICAgZnVuY3Rpb24gYWRkQmluZGluZyhrZXksIHZhbCkge1xuICAgICAgdmFyIGJvdW5kO1xuICAgICAgaWYgKHR5cGVvZiB2YWwgIT0gXCJzdHJpbmdcIilcbiAgICAgICAgYm91bmQgPSBmdW5jdGlvbihjbSkgeyByZXR1cm4gdmFsKGNtLCBoYW5kbGUpOyB9O1xuICAgICAgLy8gVGhpcyBtZWNoYW5pc20gaXMgZGVwcmVjYXRlZFxuICAgICAgZWxzZSBpZiAoYmFzZU1hcC5oYXNPd25Qcm9wZXJ0eSh2YWwpKVxuICAgICAgICBib3VuZCA9IGJhc2VNYXBbdmFsXTtcbiAgICAgIGVsc2VcbiAgICAgICAgYm91bmQgPSB2YWw7XG4gICAgICBvdXJNYXBba2V5XSA9IGJvdW5kO1xuICAgIH1cbiAgICBpZiAoY3VzdG9tKVxuICAgICAgZm9yICh2YXIga2V5IGluIGN1c3RvbSkgaWYgKGN1c3RvbS5oYXNPd25Qcm9wZXJ0eShrZXkpKVxuICAgICAgICBhZGRCaW5kaW5nKGtleSwgY3VzdG9tW2tleV0pO1xuICAgIHZhciBleHRyYSA9IGNvbXBsZXRpb24ub3B0aW9ucy5leHRyYUtleXM7XG4gICAgaWYgKGV4dHJhKVxuICAgICAgZm9yICh2YXIga2V5IGluIGV4dHJhKSBpZiAoZXh0cmEuaGFzT3duUHJvcGVydHkoa2V5KSlcbiAgICAgICAgYWRkQmluZGluZyhrZXksIGV4dHJhW2tleV0pO1xuICAgIHJldHVybiBvdXJNYXA7XG4gIH1cblxuICBmdW5jdGlvbiBnZXRIaW50RWxlbWVudChoaW50c0VsZW1lbnQsIGVsKSB7XG4gICAgd2hpbGUgKGVsICYmIGVsICE9IGhpbnRzRWxlbWVudCkge1xuICAgICAgaWYgKGVsLm5vZGVOYW1lLnRvVXBwZXJDYXNlKCkgPT09IFwiTElcIiAmJiBlbC5wYXJlbnROb2RlID09IGhpbnRzRWxlbWVudCkgcmV0dXJuIGVsO1xuICAgICAgZWwgPSBlbC5wYXJlbnROb2RlO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIFdpZGdldChjb21wbGV0aW9uLCBkYXRhKSB7XG4gICAgdGhpcy5jb21wbGV0aW9uID0gY29tcGxldGlvbjtcbiAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgIHZhciB3aWRnZXQgPSB0aGlzLCBjbSA9IGNvbXBsZXRpb24uY207XG5cbiAgICB2YXIgaGludHMgPSB0aGlzLmhpbnRzID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInVsXCIpO1xuICAgIGhpbnRzLmNsYXNzTmFtZSA9IFwiQ29kZU1pcnJvci1oaW50c1wiO1xuICAgIHRoaXMuc2VsZWN0ZWRIaW50ID0gZGF0YS5zZWxlY3RlZEhpbnQgfHwgMDtcblxuICAgIHZhciBjb21wbGV0aW9ucyA9IGRhdGEubGlzdDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNvbXBsZXRpb25zLmxlbmd0aDsgKytpKSB7XG4gICAgICB2YXIgZWx0ID0gaGludHMuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImxpXCIpKSwgY3VyID0gY29tcGxldGlvbnNbaV07XG4gICAgICB2YXIgY2xhc3NOYW1lID0gSElOVF9FTEVNRU5UX0NMQVNTICsgKGkgIT0gdGhpcy5zZWxlY3RlZEhpbnQgPyBcIlwiIDogXCIgXCIgKyBBQ1RJVkVfSElOVF9FTEVNRU5UX0NMQVNTKTtcbiAgICAgIGlmIChjdXIuY2xhc3NOYW1lICE9IG51bGwpIGNsYXNzTmFtZSA9IGN1ci5jbGFzc05hbWUgKyBcIiBcIiArIGNsYXNzTmFtZTtcbiAgICAgIGVsdC5jbGFzc05hbWUgPSBjbGFzc05hbWU7XG4gICAgICBpZiAoY3VyLnJlbmRlcikgY3VyLnJlbmRlcihlbHQsIGRhdGEsIGN1cik7XG4gICAgICBlbHNlIGVsdC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShjdXIuZGlzcGxheVRleHQgfHwgZ2V0VGV4dChjdXIpKSk7XG4gICAgICBlbHQuaGludElkID0gaTtcbiAgICB9XG5cbiAgICB2YXIgcG9zID0gY20uY3Vyc29yQ29vcmRzKGNvbXBsZXRpb24ub3B0aW9ucy5hbGlnbldpdGhXb3JkID8gZGF0YS5mcm9tIDogbnVsbCk7XG4gICAgdmFyIGxlZnQgPSBwb3MubGVmdCwgdG9wID0gcG9zLmJvdHRvbSwgYmVsb3cgPSB0cnVlO1xuICAgIGhpbnRzLnN0eWxlLmxlZnQgPSBsZWZ0ICsgXCJweFwiO1xuICAgIGhpbnRzLnN0eWxlLnRvcCA9IHRvcCArIFwicHhcIjtcbiAgICAvLyBJZiB3ZSdyZSBhdCB0aGUgZWRnZSBvZiB0aGUgc2NyZWVuLCB0aGVuIHdlIHdhbnQgdGhlIG1lbnUgdG8gYXBwZWFyIG9uIHRoZSBsZWZ0IG9mIHRoZSBjdXJzb3IuXG4gICAgdmFyIHdpblcgPSB3aW5kb3cuaW5uZXJXaWR0aCB8fCBNYXRoLm1heChkb2N1bWVudC5ib2R5Lm9mZnNldFdpZHRoLCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQub2Zmc2V0V2lkdGgpO1xuICAgIHZhciB3aW5IID0gd2luZG93LmlubmVySGVpZ2h0IHx8IE1hdGgubWF4KGRvY3VtZW50LmJvZHkub2Zmc2V0SGVpZ2h0LCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQub2Zmc2V0SGVpZ2h0KTtcbiAgICAoY29tcGxldGlvbi5vcHRpb25zLmNvbnRhaW5lciB8fCBkb2N1bWVudC5ib2R5KS5hcHBlbmRDaGlsZChoaW50cyk7XG4gICAgdmFyIGJveCA9IGhpbnRzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBvdmVybGFwWSA9IGJveC5ib3R0b20gLSB3aW5IO1xuICAgIGlmIChvdmVybGFwWSA+IDApIHtcbiAgICAgIHZhciBoZWlnaHQgPSBib3guYm90dG9tIC0gYm94LnRvcCwgY3VyVG9wID0gcG9zLnRvcCAtIChwb3MuYm90dG9tIC0gYm94LnRvcCk7XG4gICAgICBpZiAoY3VyVG9wIC0gaGVpZ2h0ID4gMCkgeyAvLyBGaXRzIGFib3ZlIGN1cnNvclxuICAgICAgICBoaW50cy5zdHlsZS50b3AgPSAodG9wID0gcG9zLnRvcCAtIGhlaWdodCkgKyBcInB4XCI7XG4gICAgICAgIGJlbG93ID0gZmFsc2U7XG4gICAgICB9IGVsc2UgaWYgKGhlaWdodCA+IHdpbkgpIHtcbiAgICAgICAgaGludHMuc3R5bGUuaGVpZ2h0ID0gKHdpbkggLSA1KSArIFwicHhcIjtcbiAgICAgICAgaGludHMuc3R5bGUudG9wID0gKHRvcCA9IHBvcy5ib3R0b20gLSBib3gudG9wKSArIFwicHhcIjtcbiAgICAgICAgdmFyIGN1cnNvciA9IGNtLmdldEN1cnNvcigpO1xuICAgICAgICBpZiAoZGF0YS5mcm9tLmNoICE9IGN1cnNvci5jaCkge1xuICAgICAgICAgIHBvcyA9IGNtLmN1cnNvckNvb3JkcyhjdXJzb3IpO1xuICAgICAgICAgIGhpbnRzLnN0eWxlLmxlZnQgPSAobGVmdCA9IHBvcy5sZWZ0KSArIFwicHhcIjtcbiAgICAgICAgICBib3ggPSBoaW50cy5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICB2YXIgb3ZlcmxhcFggPSBib3gucmlnaHQgLSB3aW5XO1xuICAgIGlmIChvdmVybGFwWCA+IDApIHtcbiAgICAgIGlmIChib3gucmlnaHQgLSBib3gubGVmdCA+IHdpblcpIHtcbiAgICAgICAgaGludHMuc3R5bGUud2lkdGggPSAod2luVyAtIDUpICsgXCJweFwiO1xuICAgICAgICBvdmVybGFwWCAtPSAoYm94LnJpZ2h0IC0gYm94LmxlZnQpIC0gd2luVztcbiAgICAgIH1cbiAgICAgIGhpbnRzLnN0eWxlLmxlZnQgPSAobGVmdCA9IHBvcy5sZWZ0IC0gb3ZlcmxhcFgpICsgXCJweFwiO1xuICAgIH1cblxuICAgIGNtLmFkZEtleU1hcCh0aGlzLmtleU1hcCA9IGJ1aWxkS2V5TWFwKGNvbXBsZXRpb24sIHtcbiAgICAgIG1vdmVGb2N1czogZnVuY3Rpb24obiwgYXZvaWRXcmFwKSB7IHdpZGdldC5jaGFuZ2VBY3RpdmUod2lkZ2V0LnNlbGVjdGVkSGludCArIG4sIGF2b2lkV3JhcCk7IH0sXG4gICAgICBzZXRGb2N1czogZnVuY3Rpb24obikgeyB3aWRnZXQuY2hhbmdlQWN0aXZlKG4pOyB9LFxuICAgICAgbWVudVNpemU6IGZ1bmN0aW9uKCkgeyByZXR1cm4gd2lkZ2V0LnNjcmVlbkFtb3VudCgpOyB9LFxuICAgICAgbGVuZ3RoOiBjb21wbGV0aW9ucy5sZW5ndGgsXG4gICAgICBjbG9zZTogZnVuY3Rpb24oKSB7IGNvbXBsZXRpb24uY2xvc2UoKTsgfSxcbiAgICAgIHBpY2s6IGZ1bmN0aW9uKCkgeyB3aWRnZXQucGljaygpOyB9LFxuICAgICAgZGF0YTogZGF0YVxuICAgIH0pKTtcblxuICAgIGlmIChjb21wbGV0aW9uLm9wdGlvbnMuY2xvc2VPblVuZm9jdXMpIHtcbiAgICAgIHZhciBjbG9zaW5nT25CbHVyO1xuICAgICAgY20ub24oXCJibHVyXCIsIHRoaXMub25CbHVyID0gZnVuY3Rpb24oKSB7IGNsb3NpbmdPbkJsdXIgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgeyBjb21wbGV0aW9uLmNsb3NlKCk7IH0sIDEwMCk7IH0pO1xuICAgICAgY20ub24oXCJmb2N1c1wiLCB0aGlzLm9uRm9jdXMgPSBmdW5jdGlvbigpIHsgY2xlYXJUaW1lb3V0KGNsb3NpbmdPbkJsdXIpOyB9KTtcbiAgICB9XG5cbiAgICB2YXIgc3RhcnRTY3JvbGwgPSBjbS5nZXRTY3JvbGxJbmZvKCk7XG4gICAgY20ub24oXCJzY3JvbGxcIiwgdGhpcy5vblNjcm9sbCA9IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIGN1clNjcm9sbCA9IGNtLmdldFNjcm9sbEluZm8oKSwgZWRpdG9yID0gY20uZ2V0V3JhcHBlckVsZW1lbnQoKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHZhciBuZXdUb3AgPSB0b3AgKyBzdGFydFNjcm9sbC50b3AgLSBjdXJTY3JvbGwudG9wO1xuICAgICAgdmFyIHBvaW50ID0gbmV3VG9wIC0gKHdpbmRvdy5wYWdlWU9mZnNldCB8fCAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IHx8IGRvY3VtZW50LmJvZHkpLnNjcm9sbFRvcCk7XG4gICAgICBpZiAoIWJlbG93KSBwb2ludCArPSBoaW50cy5vZmZzZXRIZWlnaHQ7XG4gICAgICBpZiAocG9pbnQgPD0gZWRpdG9yLnRvcCB8fCBwb2ludCA+PSBlZGl0b3IuYm90dG9tKSByZXR1cm4gY29tcGxldGlvbi5jbG9zZSgpO1xuICAgICAgaGludHMuc3R5bGUudG9wID0gbmV3VG9wICsgXCJweFwiO1xuICAgICAgaGludHMuc3R5bGUubGVmdCA9IChsZWZ0ICsgc3RhcnRTY3JvbGwubGVmdCAtIGN1clNjcm9sbC5sZWZ0KSArIFwicHhcIjtcbiAgICB9KTtcblxuICAgIENvZGVNaXJyb3Iub24oaGludHMsIFwiZGJsY2xpY2tcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgdmFyIHQgPSBnZXRIaW50RWxlbWVudChoaW50cywgZS50YXJnZXQgfHwgZS5zcmNFbGVtZW50KTtcbiAgICAgIGlmICh0ICYmIHQuaGludElkICE9IG51bGwpIHt3aWRnZXQuY2hhbmdlQWN0aXZlKHQuaGludElkKTsgd2lkZ2V0LnBpY2soKTt9XG4gICAgfSk7XG5cbiAgICBDb2RlTWlycm9yLm9uKGhpbnRzLCBcImNsaWNrXCIsIGZ1bmN0aW9uKGUpIHtcbiAgICAgIHZhciB0ID0gZ2V0SGludEVsZW1lbnQoaGludHMsIGUudGFyZ2V0IHx8IGUuc3JjRWxlbWVudCk7XG4gICAgICBpZiAodCAmJiB0LmhpbnRJZCAhPSBudWxsKSB7XG4gICAgICAgIHdpZGdldC5jaGFuZ2VBY3RpdmUodC5oaW50SWQpO1xuICAgICAgICBpZiAoY29tcGxldGlvbi5vcHRpb25zLmNvbXBsZXRlT25TaW5nbGVDbGljaykgd2lkZ2V0LnBpY2soKTtcbiAgICAgIH1cbiAgICB9KTtcblxuICAgIENvZGVNaXJyb3Iub24oaGludHMsIFwibW91c2Vkb3duXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpe2NtLmZvY3VzKCk7fSwgMjApO1xuICAgIH0pO1xuXG4gICAgQ29kZU1pcnJvci5zaWduYWwoZGF0YSwgXCJzZWxlY3RcIiwgY29tcGxldGlvbnNbMF0sIGhpbnRzLmZpcnN0Q2hpbGQpO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgV2lkZ2V0LnByb3RvdHlwZSA9IHtcbiAgICBjbG9zZTogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5jb21wbGV0aW9uLndpZGdldCAhPSB0aGlzKSByZXR1cm47XG4gICAgICB0aGlzLmNvbXBsZXRpb24ud2lkZ2V0ID0gbnVsbDtcbiAgICAgIHRoaXMuaGludHMucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLmhpbnRzKTtcbiAgICAgIHRoaXMuY29tcGxldGlvbi5jbS5yZW1vdmVLZXlNYXAodGhpcy5rZXlNYXApO1xuXG4gICAgICB2YXIgY20gPSB0aGlzLmNvbXBsZXRpb24uY207XG4gICAgICBpZiAodGhpcy5jb21wbGV0aW9uLm9wdGlvbnMuY2xvc2VPblVuZm9jdXMpIHtcbiAgICAgICAgY20ub2ZmKFwiYmx1clwiLCB0aGlzLm9uQmx1cik7XG4gICAgICAgIGNtLm9mZihcImZvY3VzXCIsIHRoaXMub25Gb2N1cyk7XG4gICAgICB9XG4gICAgICBjbS5vZmYoXCJzY3JvbGxcIiwgdGhpcy5vblNjcm9sbCk7XG4gICAgfSxcblxuICAgIHBpY2s6IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5jb21wbGV0aW9uLnBpY2sodGhpcy5kYXRhLCB0aGlzLnNlbGVjdGVkSGludCk7XG4gICAgfSxcblxuICAgIGNoYW5nZUFjdGl2ZTogZnVuY3Rpb24oaSwgYXZvaWRXcmFwKSB7XG4gICAgICBpZiAoaSA+PSB0aGlzLmRhdGEubGlzdC5sZW5ndGgpXG4gICAgICAgIGkgPSBhdm9pZFdyYXAgPyB0aGlzLmRhdGEubGlzdC5sZW5ndGggLSAxIDogMDtcbiAgICAgIGVsc2UgaWYgKGkgPCAwKVxuICAgICAgICBpID0gYXZvaWRXcmFwID8gMCAgOiB0aGlzLmRhdGEubGlzdC5sZW5ndGggLSAxO1xuICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRIaW50ID09IGkpIHJldHVybjtcbiAgICAgIHZhciBub2RlID0gdGhpcy5oaW50cy5jaGlsZE5vZGVzW3RoaXMuc2VsZWN0ZWRIaW50XTtcbiAgICAgIG5vZGUuY2xhc3NOYW1lID0gbm9kZS5jbGFzc05hbWUucmVwbGFjZShcIiBcIiArIEFDVElWRV9ISU5UX0VMRU1FTlRfQ0xBU1MsIFwiXCIpO1xuICAgICAgbm9kZSA9IHRoaXMuaGludHMuY2hpbGROb2Rlc1t0aGlzLnNlbGVjdGVkSGludCA9IGldO1xuICAgICAgbm9kZS5jbGFzc05hbWUgKz0gXCIgXCIgKyBBQ1RJVkVfSElOVF9FTEVNRU5UX0NMQVNTO1xuICAgICAgaWYgKG5vZGUub2Zmc2V0VG9wIDwgdGhpcy5oaW50cy5zY3JvbGxUb3ApXG4gICAgICAgIHRoaXMuaGludHMuc2Nyb2xsVG9wID0gbm9kZS5vZmZzZXRUb3AgLSAzO1xuICAgICAgZWxzZSBpZiAobm9kZS5vZmZzZXRUb3AgKyBub2RlLm9mZnNldEhlaWdodCA+IHRoaXMuaGludHMuc2Nyb2xsVG9wICsgdGhpcy5oaW50cy5jbGllbnRIZWlnaHQpXG4gICAgICAgIHRoaXMuaGludHMuc2Nyb2xsVG9wID0gbm9kZS5vZmZzZXRUb3AgKyBub2RlLm9mZnNldEhlaWdodCAtIHRoaXMuaGludHMuY2xpZW50SGVpZ2h0ICsgMztcbiAgICAgIENvZGVNaXJyb3Iuc2lnbmFsKHRoaXMuZGF0YSwgXCJzZWxlY3RcIiwgdGhpcy5kYXRhLmxpc3RbdGhpcy5zZWxlY3RlZEhpbnRdLCBub2RlKTtcbiAgICB9LFxuXG4gICAgc2NyZWVuQW1vdW50OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBNYXRoLmZsb29yKHRoaXMuaGludHMuY2xpZW50SGVpZ2h0IC8gdGhpcy5oaW50cy5maXJzdENoaWxkLm9mZnNldEhlaWdodCkgfHwgMTtcbiAgICB9XG4gIH07XG5cbiAgQ29kZU1pcnJvci5yZWdpc3RlckhlbHBlcihcImhpbnRcIiwgXCJhdXRvXCIsIGZ1bmN0aW9uKGNtLCBvcHRpb25zKSB7XG4gICAgdmFyIGhlbHBlcnMgPSBjbS5nZXRIZWxwZXJzKGNtLmdldEN1cnNvcigpLCBcImhpbnRcIiksIHdvcmRzO1xuICAgIGlmIChoZWxwZXJzLmxlbmd0aCkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZWxwZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBjdXIgPSBoZWxwZXJzW2ldKGNtLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKGN1ciAmJiBjdXIubGlzdC5sZW5ndGgpIHJldHVybiBjdXI7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh3b3JkcyA9IGNtLmdldEhlbHBlcihjbS5nZXRDdXJzb3IoKSwgXCJoaW50V29yZHNcIikpIHtcbiAgICAgIGlmICh3b3JkcykgcmV0dXJuIENvZGVNaXJyb3IuaGludC5mcm9tTGlzdChjbSwge3dvcmRzOiB3b3Jkc30pO1xuICAgIH0gZWxzZSBpZiAoQ29kZU1pcnJvci5oaW50LmFueXdvcmQpIHtcbiAgICAgIHJldHVybiBDb2RlTWlycm9yLmhpbnQuYW55d29yZChjbSwgb3B0aW9ucyk7XG4gICAgfVxuICB9KTtcblxuICBDb2RlTWlycm9yLnJlZ2lzdGVySGVscGVyKFwiaGludFwiLCBcImZyb21MaXN0XCIsIGZ1bmN0aW9uKGNtLCBvcHRpb25zKSB7XG4gICAgdmFyIGN1ciA9IGNtLmdldEN1cnNvcigpLCB0b2tlbiA9IGNtLmdldFRva2VuQXQoY3VyKTtcbiAgICB2YXIgZm91bmQgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wdGlvbnMud29yZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciB3b3JkID0gb3B0aW9ucy53b3Jkc1tpXTtcbiAgICAgIGlmICh3b3JkLnNsaWNlKDAsIHRva2VuLnN0cmluZy5sZW5ndGgpID09IHRva2VuLnN0cmluZylcbiAgICAgICAgZm91bmQucHVzaCh3b3JkKTtcbiAgICB9XG5cbiAgICBpZiAoZm91bmQubGVuZ3RoKSByZXR1cm4ge1xuICAgICAgbGlzdDogZm91bmQsXG4gICAgICBmcm9tOiBDb2RlTWlycm9yLlBvcyhjdXIubGluZSwgdG9rZW4uc3RhcnQpLFxuICAgICAgICAgICAgdG86IENvZGVNaXJyb3IuUG9zKGN1ci5saW5lLCB0b2tlbi5lbmQpXG4gICAgfTtcbiAgfSk7XG5cbiAgQ29kZU1pcnJvci5jb21tYW5kcy5hdXRvY29tcGxldGUgPSBDb2RlTWlycm9yLnNob3dIaW50O1xuXG4gIHZhciBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICBoaW50OiBDb2RlTWlycm9yLmhpbnQuYXV0byxcbiAgICBjb21wbGV0ZVNpbmdsZTogdHJ1ZSxcbiAgICBhbGlnbldpdGhXb3JkOiB0cnVlLFxuICAgIGNsb3NlQ2hhcmFjdGVyczogL1tcXHMoKVxcW1xcXXt9Ozo+LF0vLFxuICAgIGNsb3NlT25VbmZvY3VzOiB0cnVlLFxuICAgIGNvbXBsZXRlT25TaW5nbGVDbGljazogZmFsc2UsXG4gICAgY29udGFpbmVyOiBudWxsLFxuICAgIGN1c3RvbUtleXM6IG51bGwsXG4gICAgZXh0cmFLZXlzOiBudWxsXG4gIH07XG5cbiAgQ29kZU1pcnJvci5kZWZpbmVPcHRpb24oXCJoaW50T3B0aW9uc1wiLCBudWxsKTtcbn0pO1xuIiwiLy8gQ29kZU1pcnJvciwgY29weXJpZ2h0IChjKSBieSBNYXJpam4gSGF2ZXJiZWtlIGFuZCBvdGhlcnNcbi8vIERpc3RyaWJ1dGVkIHVuZGVyIGFuIE1JVCBsaWNlbnNlOiBodHRwOi8vY29kZW1pcnJvci5uZXQvTElDRU5TRVxuXG4oZnVuY3Rpb24obW9kKSB7XG4gIGlmICh0eXBlb2YgZXhwb3J0cyA9PSBcIm9iamVjdFwiICYmIHR5cGVvZiBtb2R1bGUgPT0gXCJvYmplY3RcIikgLy8gQ29tbW9uSlNcbiAgICBtb2QocmVxdWlyZShcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCIpKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgZGVmaW5lKFtcIi4uLy4uL2xpYi9jb2RlbWlycm9yXCJdLCBtb2QpO1xuICBlbHNlIC8vIFBsYWluIGJyb3dzZXIgZW52XG4gICAgbW9kKENvZGVNaXJyb3IpO1xufSkoZnVuY3Rpb24oQ29kZU1pcnJvcikge1xuXCJ1c2Ugc3RyaWN0XCI7XG5cbkNvZGVNaXJyb3IucnVuTW9kZSA9IGZ1bmN0aW9uKHN0cmluZywgbW9kZXNwZWMsIGNhbGxiYWNrLCBvcHRpb25zKSB7XG4gIHZhciBtb2RlID0gQ29kZU1pcnJvci5nZXRNb2RlKENvZGVNaXJyb3IuZGVmYXVsdHMsIG1vZGVzcGVjKTtcbiAgdmFyIGllID0gL01TSUUgXFxkLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICB2YXIgaWVfbHQ5ID0gaWUgJiYgKGRvY3VtZW50LmRvY3VtZW50TW9kZSA9PSBudWxsIHx8IGRvY3VtZW50LmRvY3VtZW50TW9kZSA8IDkpO1xuXG4gIGlmIChjYWxsYmFjay5ub2RlVHlwZSA9PSAxKSB7XG4gICAgdmFyIHRhYlNpemUgPSAob3B0aW9ucyAmJiBvcHRpb25zLnRhYlNpemUpIHx8IENvZGVNaXJyb3IuZGVmYXVsdHMudGFiU2l6ZTtcbiAgICB2YXIgbm9kZSA9IGNhbGxiYWNrLCBjb2wgPSAwO1xuICAgIG5vZGUuaW5uZXJIVE1MID0gXCJcIjtcbiAgICBjYWxsYmFjayA9IGZ1bmN0aW9uKHRleHQsIHN0eWxlKSB7XG4gICAgICBpZiAodGV4dCA9PSBcIlxcblwiKSB7XG4gICAgICAgIC8vIEVtaXR0aW5nIExGIG9yIENSTEYgb24gSUU4IG9yIGVhcmxpZXIgcmVzdWx0cyBpbiBhbiBpbmNvcnJlY3QgZGlzcGxheS5cbiAgICAgICAgLy8gRW1pdHRpbmcgYSBjYXJyaWFnZSByZXR1cm4gbWFrZXMgZXZlcnl0aGluZyBvay5cbiAgICAgICAgbm9kZS5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShpZV9sdDkgPyAnXFxyJyA6IHRleHQpKTtcbiAgICAgICAgY29sID0gMDtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdmFyIGNvbnRlbnQgPSBcIlwiO1xuICAgICAgLy8gcmVwbGFjZSB0YWJzXG4gICAgICBmb3IgKHZhciBwb3MgPSAwOzspIHtcbiAgICAgICAgdmFyIGlkeCA9IHRleHQuaW5kZXhPZihcIlxcdFwiLCBwb3MpO1xuICAgICAgICBpZiAoaWR4ID09IC0xKSB7XG4gICAgICAgICAgY29udGVudCArPSB0ZXh0LnNsaWNlKHBvcyk7XG4gICAgICAgICAgY29sICs9IHRleHQubGVuZ3RoIC0gcG9zO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbCArPSBpZHggLSBwb3M7XG4gICAgICAgICAgY29udGVudCArPSB0ZXh0LnNsaWNlKHBvcywgaWR4KTtcbiAgICAgICAgICB2YXIgc2l6ZSA9IHRhYlNpemUgLSBjb2wgJSB0YWJTaXplO1xuICAgICAgICAgIGNvbCArPSBzaXplO1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2l6ZTsgKytpKSBjb250ZW50ICs9IFwiIFwiO1xuICAgICAgICAgIHBvcyA9IGlkeCArIDE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgaWYgKHN0eWxlKSB7XG4gICAgICAgIHZhciBzcCA9IG5vZGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNwYW5cIikpO1xuICAgICAgICBzcC5jbGFzc05hbWUgPSBcImNtLVwiICsgc3R5bGUucmVwbGFjZSgvICsvZywgXCIgY20tXCIpO1xuICAgICAgICBzcC5hcHBlbmRDaGlsZChkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShjb250ZW50KSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub2RlLmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKGNvbnRlbnQpKTtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgdmFyIGxpbmVzID0gQ29kZU1pcnJvci5zcGxpdExpbmVzKHN0cmluZyksIHN0YXRlID0gKG9wdGlvbnMgJiYgb3B0aW9ucy5zdGF0ZSkgfHwgQ29kZU1pcnJvci5zdGFydFN0YXRlKG1vZGUpO1xuICBmb3IgKHZhciBpID0gMCwgZSA9IGxpbmVzLmxlbmd0aDsgaSA8IGU7ICsraSkge1xuICAgIGlmIChpKSBjYWxsYmFjayhcIlxcblwiKTtcbiAgICB2YXIgc3RyZWFtID0gbmV3IENvZGVNaXJyb3IuU3RyaW5nU3RyZWFtKGxpbmVzW2ldKTtcbiAgICBpZiAoIXN0cmVhbS5zdHJpbmcgJiYgbW9kZS5ibGFua0xpbmUpIG1vZGUuYmxhbmtMaW5lKHN0YXRlKTtcbiAgICB3aGlsZSAoIXN0cmVhbS5lb2woKSkge1xuICAgICAgdmFyIHN0eWxlID0gbW9kZS50b2tlbihzdHJlYW0sIHN0YXRlKTtcbiAgICAgIGNhbGxiYWNrKHN0cmVhbS5jdXJyZW50KCksIHN0eWxlLCBpLCBzdHJlYW0uc3RhcnQsIHN0YXRlKTtcbiAgICAgIHN0cmVhbS5zdGFydCA9IHN0cmVhbS5wb3M7XG4gICAgfVxuICB9XG59O1xuXG59KTtcbiIsIi8vIENvZGVNaXJyb3IsIGNvcHlyaWdodCAoYykgYnkgTWFyaWpuIEhhdmVyYmVrZSBhbmQgb3RoZXJzXG4vLyBEaXN0cmlidXRlZCB1bmRlciBhbiBNSVQgbGljZW5zZTogaHR0cDovL2NvZGVtaXJyb3IubmV0L0xJQ0VOU0VcblxuKGZ1bmN0aW9uKG1vZCkge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09IFwib2JqZWN0XCIpIC8vIENvbW1vbkpTXG4gICAgbW9kKHJlcXVpcmUoXCIuLi8uLi9saWIvY29kZW1pcnJvclwiKSk7XG4gIGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT0gXCJmdW5jdGlvblwiICYmIGRlZmluZS5hbWQpIC8vIEFNRFxuICAgIGRlZmluZShbXCIuLi8uLi9saWIvY29kZW1pcnJvclwiXSwgbW9kKTtcbiAgZWxzZSAvLyBQbGFpbiBicm93c2VyIGVudlxuICAgIG1vZChDb2RlTWlycm9yKTtcbn0pKGZ1bmN0aW9uKENvZGVNaXJyb3IpIHtcbiAgXCJ1c2Ugc3RyaWN0XCI7XG4gIHZhciBQb3MgPSBDb2RlTWlycm9yLlBvcztcblxuICBmdW5jdGlvbiBTZWFyY2hDdXJzb3IoZG9jLCBxdWVyeSwgcG9zLCBjYXNlRm9sZCkge1xuICAgIHRoaXMuYXRPY2N1cnJlbmNlID0gZmFsc2U7IHRoaXMuZG9jID0gZG9jO1xuICAgIGlmIChjYXNlRm9sZCA9PSBudWxsICYmIHR5cGVvZiBxdWVyeSA9PSBcInN0cmluZ1wiKSBjYXNlRm9sZCA9IGZhbHNlO1xuXG4gICAgcG9zID0gcG9zID8gZG9jLmNsaXBQb3MocG9zKSA6IFBvcygwLCAwKTtcbiAgICB0aGlzLnBvcyA9IHtmcm9tOiBwb3MsIHRvOiBwb3N9O1xuXG4gICAgLy8gVGhlIG1hdGNoZXMgbWV0aG9kIGlzIGZpbGxlZCBpbiBiYXNlZCBvbiB0aGUgdHlwZSBvZiBxdWVyeS5cbiAgICAvLyBJdCB0YWtlcyBhIHBvc2l0aW9uIGFuZCBhIGRpcmVjdGlvbiwgYW5kIHJldHVybnMgYW4gb2JqZWN0XG4gICAgLy8gZGVzY3JpYmluZyB0aGUgbmV4dCBvY2N1cnJlbmNlIG9mIHRoZSBxdWVyeSwgb3IgbnVsbCBpZiBub1xuICAgIC8vIG1vcmUgbWF0Y2hlcyB3ZXJlIGZvdW5kLlxuICAgIGlmICh0eXBlb2YgcXVlcnkgIT0gXCJzdHJpbmdcIikgeyAvLyBSZWdleHAgbWF0Y2hcbiAgICAgIGlmICghcXVlcnkuZ2xvYmFsKSBxdWVyeSA9IG5ldyBSZWdFeHAocXVlcnkuc291cmNlLCBxdWVyeS5pZ25vcmVDYXNlID8gXCJpZ1wiIDogXCJnXCIpO1xuICAgICAgdGhpcy5tYXRjaGVzID0gZnVuY3Rpb24ocmV2ZXJzZSwgcG9zKSB7XG4gICAgICAgIGlmIChyZXZlcnNlKSB7XG4gICAgICAgICAgcXVlcnkubGFzdEluZGV4ID0gMDtcbiAgICAgICAgICB2YXIgbGluZSA9IGRvYy5nZXRMaW5lKHBvcy5saW5lKS5zbGljZSgwLCBwb3MuY2gpLCBjdXRPZmYgPSAwLCBtYXRjaCwgc3RhcnQ7XG4gICAgICAgICAgZm9yICg7Oykge1xuICAgICAgICAgICAgcXVlcnkubGFzdEluZGV4ID0gY3V0T2ZmO1xuICAgICAgICAgICAgdmFyIG5ld01hdGNoID0gcXVlcnkuZXhlYyhsaW5lKTtcbiAgICAgICAgICAgIGlmICghbmV3TWF0Y2gpIGJyZWFrO1xuICAgICAgICAgICAgbWF0Y2ggPSBuZXdNYXRjaDtcbiAgICAgICAgICAgIHN0YXJ0ID0gbWF0Y2guaW5kZXg7XG4gICAgICAgICAgICBjdXRPZmYgPSBtYXRjaC5pbmRleCArIChtYXRjaFswXS5sZW5ndGggfHwgMSk7XG4gICAgICAgICAgICBpZiAoY3V0T2ZmID09IGxpbmUubGVuZ3RoKSBicmVhaztcbiAgICAgICAgICB9XG4gICAgICAgICAgdmFyIG1hdGNoTGVuID0gKG1hdGNoICYmIG1hdGNoWzBdLmxlbmd0aCkgfHwgMDtcbiAgICAgICAgICBpZiAoIW1hdGNoTGVuKSB7XG4gICAgICAgICAgICBpZiAoc3RhcnQgPT0gMCAmJiBsaW5lLmxlbmd0aCA9PSAwKSB7bWF0Y2ggPSB1bmRlZmluZWQ7fVxuICAgICAgICAgICAgZWxzZSBpZiAoc3RhcnQgIT0gZG9jLmdldExpbmUocG9zLmxpbmUpLmxlbmd0aCkge1xuICAgICAgICAgICAgICBtYXRjaExlbisrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBxdWVyeS5sYXN0SW5kZXggPSBwb3MuY2g7XG4gICAgICAgICAgdmFyIGxpbmUgPSBkb2MuZ2V0TGluZShwb3MubGluZSksIG1hdGNoID0gcXVlcnkuZXhlYyhsaW5lKTtcbiAgICAgICAgICB2YXIgbWF0Y2hMZW4gPSAobWF0Y2ggJiYgbWF0Y2hbMF0ubGVuZ3RoKSB8fCAwO1xuICAgICAgICAgIHZhciBzdGFydCA9IG1hdGNoICYmIG1hdGNoLmluZGV4O1xuICAgICAgICAgIGlmIChzdGFydCArIG1hdGNoTGVuICE9IGxpbmUubGVuZ3RoICYmICFtYXRjaExlbikgbWF0Y2hMZW4gPSAxO1xuICAgICAgICB9XG4gICAgICAgIGlmIChtYXRjaCAmJiBtYXRjaExlbilcbiAgICAgICAgICByZXR1cm4ge2Zyb206IFBvcyhwb3MubGluZSwgc3RhcnQpLFxuICAgICAgICAgICAgICAgICAgdG86IFBvcyhwb3MubGluZSwgc3RhcnQgKyBtYXRjaExlbiksXG4gICAgICAgICAgICAgICAgICBtYXRjaDogbWF0Y2h9O1xuICAgICAgfTtcbiAgICB9IGVsc2UgeyAvLyBTdHJpbmcgcXVlcnlcbiAgICAgIHZhciBvcmlnUXVlcnkgPSBxdWVyeTtcbiAgICAgIGlmIChjYXNlRm9sZCkgcXVlcnkgPSBxdWVyeS50b0xvd2VyQ2FzZSgpO1xuICAgICAgdmFyIGZvbGQgPSBjYXNlRm9sZCA/IGZ1bmN0aW9uKHN0cil7cmV0dXJuIHN0ci50b0xvd2VyQ2FzZSgpO30gOiBmdW5jdGlvbihzdHIpe3JldHVybiBzdHI7fTtcbiAgICAgIHZhciB0YXJnZXQgPSBxdWVyeS5zcGxpdChcIlxcblwiKTtcbiAgICAgIC8vIERpZmZlcmVudCBtZXRob2RzIGZvciBzaW5nbGUtbGluZSBhbmQgbXVsdGktbGluZSBxdWVyaWVzXG4gICAgICBpZiAodGFyZ2V0Lmxlbmd0aCA9PSAxKSB7XG4gICAgICAgIGlmICghcXVlcnkubGVuZ3RoKSB7XG4gICAgICAgICAgLy8gRW1wdHkgc3RyaW5nIHdvdWxkIG1hdGNoIGFueXRoaW5nIGFuZCBuZXZlciBwcm9ncmVzcywgc29cbiAgICAgICAgICAvLyB3ZSBkZWZpbmUgaXQgdG8gbWF0Y2ggbm90aGluZyBpbnN0ZWFkLlxuICAgICAgICAgIHRoaXMubWF0Y2hlcyA9IGZ1bmN0aW9uKCkge307XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5tYXRjaGVzID0gZnVuY3Rpb24ocmV2ZXJzZSwgcG9zKSB7XG4gICAgICAgICAgICBpZiAocmV2ZXJzZSkge1xuICAgICAgICAgICAgICB2YXIgb3JpZyA9IGRvYy5nZXRMaW5lKHBvcy5saW5lKS5zbGljZSgwLCBwb3MuY2gpLCBsaW5lID0gZm9sZChvcmlnKTtcbiAgICAgICAgICAgICAgdmFyIG1hdGNoID0gbGluZS5sYXN0SW5kZXhPZihxdWVyeSk7XG4gICAgICAgICAgICAgIGlmIChtYXRjaCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgbWF0Y2ggPSBhZGp1c3RQb3Mob3JpZywgbGluZSwgbWF0Y2gpO1xuICAgICAgICAgICAgICAgIHJldHVybiB7ZnJvbTogUG9zKHBvcy5saW5lLCBtYXRjaCksIHRvOiBQb3MocG9zLmxpbmUsIG1hdGNoICsgb3JpZ1F1ZXJ5Lmxlbmd0aCl9O1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgIHZhciBvcmlnID0gZG9jLmdldExpbmUocG9zLmxpbmUpLnNsaWNlKHBvcy5jaCksIGxpbmUgPSBmb2xkKG9yaWcpO1xuICAgICAgICAgICAgICAgdmFyIG1hdGNoID0gbGluZS5pbmRleE9mKHF1ZXJ5KTtcbiAgICAgICAgICAgICAgIGlmIChtYXRjaCA+IC0xKSB7XG4gICAgICAgICAgICAgICAgIG1hdGNoID0gYWRqdXN0UG9zKG9yaWcsIGxpbmUsIG1hdGNoKSArIHBvcy5jaDtcbiAgICAgICAgICAgICAgICAgcmV0dXJuIHtmcm9tOiBQb3MocG9zLmxpbmUsIG1hdGNoKSwgdG86IFBvcyhwb3MubGluZSwgbWF0Y2ggKyBvcmlnUXVlcnkubGVuZ3RoKX07XG4gICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIG9yaWdUYXJnZXQgPSBvcmlnUXVlcnkuc3BsaXQoXCJcXG5cIik7XG4gICAgICAgIHRoaXMubWF0Y2hlcyA9IGZ1bmN0aW9uKHJldmVyc2UsIHBvcykge1xuICAgICAgICAgIHZhciBsYXN0ID0gdGFyZ2V0Lmxlbmd0aCAtIDE7XG4gICAgICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgICAgIGlmIChwb3MubGluZSAtICh0YXJnZXQubGVuZ3RoIC0gMSkgPCBkb2MuZmlyc3RMaW5lKCkpIHJldHVybjtcbiAgICAgICAgICAgIGlmIChmb2xkKGRvYy5nZXRMaW5lKHBvcy5saW5lKS5zbGljZSgwLCBvcmlnVGFyZ2V0W2xhc3RdLmxlbmd0aCkpICE9IHRhcmdldFt0YXJnZXQubGVuZ3RoIC0gMV0pIHJldHVybjtcbiAgICAgICAgICAgIHZhciB0byA9IFBvcyhwb3MubGluZSwgb3JpZ1RhcmdldFtsYXN0XS5sZW5ndGgpO1xuICAgICAgICAgICAgZm9yICh2YXIgbG4gPSBwb3MubGluZSAtIDEsIGkgPSBsYXN0IC0gMTsgaSA+PSAxOyAtLWksIC0tbG4pXG4gICAgICAgICAgICAgIGlmICh0YXJnZXRbaV0gIT0gZm9sZChkb2MuZ2V0TGluZShsbikpKSByZXR1cm47XG4gICAgICAgICAgICB2YXIgbGluZSA9IGRvYy5nZXRMaW5lKGxuKSwgY3V0ID0gbGluZS5sZW5ndGggLSBvcmlnVGFyZ2V0WzBdLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChmb2xkKGxpbmUuc2xpY2UoY3V0KSkgIT0gdGFyZ2V0WzBdKSByZXR1cm47XG4gICAgICAgICAgICByZXR1cm4ge2Zyb206IFBvcyhsbiwgY3V0KSwgdG86IHRvfTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKHBvcy5saW5lICsgKHRhcmdldC5sZW5ndGggLSAxKSA+IGRvYy5sYXN0TGluZSgpKSByZXR1cm47XG4gICAgICAgICAgICB2YXIgbGluZSA9IGRvYy5nZXRMaW5lKHBvcy5saW5lKSwgY3V0ID0gbGluZS5sZW5ndGggLSBvcmlnVGFyZ2V0WzBdLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChmb2xkKGxpbmUuc2xpY2UoY3V0KSkgIT0gdGFyZ2V0WzBdKSByZXR1cm47XG4gICAgICAgICAgICB2YXIgZnJvbSA9IFBvcyhwb3MubGluZSwgY3V0KTtcbiAgICAgICAgICAgIGZvciAodmFyIGxuID0gcG9zLmxpbmUgKyAxLCBpID0gMTsgaSA8IGxhc3Q7ICsraSwgKytsbilcbiAgICAgICAgICAgICAgaWYgKHRhcmdldFtpXSAhPSBmb2xkKGRvYy5nZXRMaW5lKGxuKSkpIHJldHVybjtcbiAgICAgICAgICAgIGlmIChmb2xkKGRvYy5nZXRMaW5lKGxuKS5zbGljZSgwLCBvcmlnVGFyZ2V0W2xhc3RdLmxlbmd0aCkpICE9IHRhcmdldFtsYXN0XSkgcmV0dXJuO1xuICAgICAgICAgICAgcmV0dXJuIHtmcm9tOiBmcm9tLCB0bzogUG9zKGxuLCBvcmlnVGFyZ2V0W2xhc3RdLmxlbmd0aCl9O1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBTZWFyY2hDdXJzb3IucHJvdG90eXBlID0ge1xuICAgIGZpbmROZXh0OiBmdW5jdGlvbigpIHtyZXR1cm4gdGhpcy5maW5kKGZhbHNlKTt9LFxuICAgIGZpbmRQcmV2aW91czogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMuZmluZCh0cnVlKTt9LFxuXG4gICAgZmluZDogZnVuY3Rpb24ocmV2ZXJzZSkge1xuICAgICAgdmFyIHNlbGYgPSB0aGlzLCBwb3MgPSB0aGlzLmRvYy5jbGlwUG9zKHJldmVyc2UgPyB0aGlzLnBvcy5mcm9tIDogdGhpcy5wb3MudG8pO1xuICAgICAgZnVuY3Rpb24gc2F2ZVBvc0FuZEZhaWwobGluZSkge1xuICAgICAgICB2YXIgcG9zID0gUG9zKGxpbmUsIDApO1xuICAgICAgICBzZWxmLnBvcyA9IHtmcm9tOiBwb3MsIHRvOiBwb3N9O1xuICAgICAgICBzZWxmLmF0T2NjdXJyZW5jZSA9IGZhbHNlO1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGZvciAoOzspIHtcbiAgICAgICAgaWYgKHRoaXMucG9zID0gdGhpcy5tYXRjaGVzKHJldmVyc2UsIHBvcykpIHtcbiAgICAgICAgICB0aGlzLmF0T2NjdXJyZW5jZSA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuIHRoaXMucG9zLm1hdGNoIHx8IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHJldmVyc2UpIHtcbiAgICAgICAgICBpZiAoIXBvcy5saW5lKSByZXR1cm4gc2F2ZVBvc0FuZEZhaWwoMCk7XG4gICAgICAgICAgcG9zID0gUG9zKHBvcy5saW5lLTEsIHRoaXMuZG9jLmdldExpbmUocG9zLmxpbmUtMSkubGVuZ3RoKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB2YXIgbWF4TGluZSA9IHRoaXMuZG9jLmxpbmVDb3VudCgpO1xuICAgICAgICAgIGlmIChwb3MubGluZSA9PSBtYXhMaW5lIC0gMSkgcmV0dXJuIHNhdmVQb3NBbmRGYWlsKG1heExpbmUpO1xuICAgICAgICAgIHBvcyA9IFBvcyhwb3MubGluZSArIDEsIDApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSxcblxuICAgIGZyb206IGZ1bmN0aW9uKCkge2lmICh0aGlzLmF0T2NjdXJyZW5jZSkgcmV0dXJuIHRoaXMucG9zLmZyb207fSxcbiAgICB0bzogZnVuY3Rpb24oKSB7aWYgKHRoaXMuYXRPY2N1cnJlbmNlKSByZXR1cm4gdGhpcy5wb3MudG87fSxcblxuICAgIHJlcGxhY2U6IGZ1bmN0aW9uKG5ld1RleHQpIHtcbiAgICAgIGlmICghdGhpcy5hdE9jY3VycmVuY2UpIHJldHVybjtcbiAgICAgIHZhciBsaW5lcyA9IENvZGVNaXJyb3Iuc3BsaXRMaW5lcyhuZXdUZXh0KTtcbiAgICAgIHRoaXMuZG9jLnJlcGxhY2VSYW5nZShsaW5lcywgdGhpcy5wb3MuZnJvbSwgdGhpcy5wb3MudG8pO1xuICAgICAgdGhpcy5wb3MudG8gPSBQb3ModGhpcy5wb3MuZnJvbS5saW5lICsgbGluZXMubGVuZ3RoIC0gMSxcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmVzW2xpbmVzLmxlbmd0aCAtIDFdLmxlbmd0aCArIChsaW5lcy5sZW5ndGggPT0gMSA/IHRoaXMucG9zLmZyb20uY2ggOiAwKSk7XG4gICAgfVxuICB9O1xuXG4gIC8vIE1hcHMgYSBwb3NpdGlvbiBpbiBhIGNhc2UtZm9sZGVkIGxpbmUgYmFjayB0byBhIHBvc2l0aW9uIGluIHRoZSBvcmlnaW5hbCBsaW5lXG4gIC8vIChjb21wZW5zYXRpbmcgZm9yIGNvZGVwb2ludHMgaW5jcmVhc2luZyBpbiBudW1iZXIgZHVyaW5nIGZvbGRpbmcpXG4gIGZ1bmN0aW9uIGFkanVzdFBvcyhvcmlnLCBmb2xkZWQsIHBvcykge1xuICAgIGlmIChvcmlnLmxlbmd0aCA9PSBmb2xkZWQubGVuZ3RoKSByZXR1cm4gcG9zO1xuICAgIGZvciAodmFyIHBvczEgPSBNYXRoLm1pbihwb3MsIG9yaWcubGVuZ3RoKTs7KSB7XG4gICAgICB2YXIgbGVuMSA9IG9yaWcuc2xpY2UoMCwgcG9zMSkudG9Mb3dlckNhc2UoKS5sZW5ndGg7XG4gICAgICBpZiAobGVuMSA8IHBvcykgKytwb3MxO1xuICAgICAgZWxzZSBpZiAobGVuMSA+IHBvcykgLS1wb3MxO1xuICAgICAgZWxzZSByZXR1cm4gcG9zMTtcbiAgICB9XG4gIH1cblxuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbihcImdldFNlYXJjaEN1cnNvclwiLCBmdW5jdGlvbihxdWVyeSwgcG9zLCBjYXNlRm9sZCkge1xuICAgIHJldHVybiBuZXcgU2VhcmNoQ3Vyc29yKHRoaXMuZG9jLCBxdWVyeSwgcG9zLCBjYXNlRm9sZCk7XG4gIH0pO1xuICBDb2RlTWlycm9yLmRlZmluZURvY0V4dGVuc2lvbihcImdldFNlYXJjaEN1cnNvclwiLCBmdW5jdGlvbihxdWVyeSwgcG9zLCBjYXNlRm9sZCkge1xuICAgIHJldHVybiBuZXcgU2VhcmNoQ3Vyc29yKHRoaXMsIHF1ZXJ5LCBwb3MsIGNhc2VGb2xkKTtcbiAgfSk7XG5cbiAgQ29kZU1pcnJvci5kZWZpbmVFeHRlbnNpb24oXCJzZWxlY3RNYXRjaGVzXCIsIGZ1bmN0aW9uKHF1ZXJ5LCBjYXNlRm9sZCkge1xuICAgIHZhciByYW5nZXMgPSBbXSwgbmV4dDtcbiAgICB2YXIgY3VyID0gdGhpcy5nZXRTZWFyY2hDdXJzb3IocXVlcnksIHRoaXMuZ2V0Q3Vyc29yKFwiZnJvbVwiKSwgY2FzZUZvbGQpO1xuICAgIHdoaWxlIChuZXh0ID0gY3VyLmZpbmROZXh0KCkpIHtcbiAgICAgIGlmIChDb2RlTWlycm9yLmNtcFBvcyhjdXIudG8oKSwgdGhpcy5nZXRDdXJzb3IoXCJ0b1wiKSkgPiAwKSBicmVhaztcbiAgICAgIHJhbmdlcy5wdXNoKHthbmNob3I6IGN1ci5mcm9tKCksIGhlYWQ6IGN1ci50bygpfSk7XG4gICAgfVxuICAgIGlmIChyYW5nZXMubGVuZ3RoKVxuICAgICAgdGhpcy5zZXRTZWxlY3Rpb25zKHJhbmdlcywgMCk7XG4gIH0pO1xufSk7XG4iLCIvLyBDb2RlTWlycm9yLCBjb3B5cmlnaHQgKGMpIGJ5IE1hcmlqbiBIYXZlcmJla2UgYW5kIG90aGVyc1xuLy8gRGlzdHJpYnV0ZWQgdW5kZXIgYW4gTUlUIGxpY2Vuc2U6IGh0dHA6Ly9jb2RlbWlycm9yLm5ldC9MSUNFTlNFXG5cbi8vIFRoaXMgaXMgQ29kZU1pcnJvciAoaHR0cDovL2NvZGVtaXJyb3IubmV0KSwgYSBjb2RlIGVkaXRvclxuLy8gaW1wbGVtZW50ZWQgaW4gSmF2YVNjcmlwdCBvbiB0b3Agb2YgdGhlIGJyb3dzZXIncyBET00uXG4vL1xuLy8gWW91IGNhbiBmaW5kIHNvbWUgdGVjaG5pY2FsIGJhY2tncm91bmQgZm9yIHNvbWUgb2YgdGhlIGNvZGUgYmVsb3dcbi8vIGF0IGh0dHA6Ly9tYXJpam5oYXZlcmJla2UubmwvYmxvZy8jY20taW50ZXJuYWxzIC5cblxuKGZ1bmN0aW9uKG1vZCkge1xuICBpZiAodHlwZW9mIGV4cG9ydHMgPT0gXCJvYmplY3RcIiAmJiB0eXBlb2YgbW9kdWxlID09IFwib2JqZWN0XCIpIC8vIENvbW1vbkpTXG4gICAgbW9kdWxlLmV4cG9ydHMgPSBtb2QoKTtcbiAgZWxzZSBpZiAodHlwZW9mIGRlZmluZSA9PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCkgLy8gQU1EXG4gICAgcmV0dXJuIGRlZmluZShbXSwgbW9kKTtcbiAgZWxzZSAvLyBQbGFpbiBicm93c2VyIGVudlxuICAgIHRoaXMuQ29kZU1pcnJvciA9IG1vZCgpO1xufSkoZnVuY3Rpb24oKSB7XG4gIFwidXNlIHN0cmljdFwiO1xuXG4gIC8vIEJST1dTRVIgU05JRkZJTkdcblxuICAvLyBLbHVkZ2VzIGZvciBidWdzIGFuZCBiZWhhdmlvciBkaWZmZXJlbmNlcyB0aGF0IGNhbid0IGJlIGZlYXR1cmVcbiAgLy8gZGV0ZWN0ZWQgYXJlIGVuYWJsZWQgYmFzZWQgb24gdXNlckFnZW50IGV0YyBzbmlmZmluZy5cblxuICB2YXIgZ2Vja28gPSAvZ2Vja29cXC9cXGQvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICAvLyBpZV91cHRvTiBtZWFucyBJbnRlcm5ldCBFeHBsb3JlciB2ZXJzaW9uIE4gb3IgbG93ZXJcbiAgdmFyIGllX3VwdG8xMCA9IC9NU0lFIFxcZC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgdmFyIGllXzExdXAgPSAvVHJpZGVudFxcLyg/Ols3LTldfFxcZHsyLH0pXFwuLipydjooXFxkKykvLmV4ZWMobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gIHZhciBpZSA9IGllX3VwdG8xMCB8fCBpZV8xMXVwO1xuICB2YXIgaWVfdmVyc2lvbiA9IGllICYmIChpZV91cHRvMTAgPyBkb2N1bWVudC5kb2N1bWVudE1vZGUgfHwgNiA6IGllXzExdXBbMV0pO1xuICB2YXIgd2Via2l0ID0gL1dlYktpdFxcLy8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgdmFyIHF0d2Via2l0ID0gd2Via2l0ICYmIC9RdFxcL1xcZCtcXC5cXGQrLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICB2YXIgY2hyb21lID0gL0Nocm9tZVxcLy8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgdmFyIHByZXN0byA9IC9PcGVyYVxcLy8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgdmFyIHNhZmFyaSA9IC9BcHBsZSBDb21wdXRlci8udGVzdChuYXZpZ2F0b3IudmVuZG9yKTtcbiAgdmFyIGtodG1sID0gL0tIVE1MXFwvLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuICB2YXIgbWFjX2dlTW91bnRhaW5MaW9uID0gL01hYyBPUyBYIDFcXGRcXEQoWzgtOV18XFxkXFxkKVxcRC8udGVzdChuYXZpZ2F0b3IudXNlckFnZW50KTtcbiAgdmFyIHBoYW50b20gPSAvUGhhbnRvbUpTLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG4gIHZhciBpb3MgPSAvQXBwbGVXZWJLaXQvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCkgJiYgL01vYmlsZVxcL1xcdysvLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gIC8vIFRoaXMgaXMgd29lZnVsbHkgaW5jb21wbGV0ZS4gU3VnZ2VzdGlvbnMgZm9yIGFsdGVybmF0aXZlIG1ldGhvZHMgd2VsY29tZS5cbiAgdmFyIG1vYmlsZSA9IGlvcyB8fCAvQW5kcm9pZHx3ZWJPU3xCbGFja0JlcnJ5fE9wZXJhIE1pbml8T3BlcmEgTW9iaXxJRU1vYmlsZS9pLnRlc3QobmF2aWdhdG9yLnVzZXJBZ2VudCk7XG4gIHZhciBtYWMgPSBpb3MgfHwgL01hYy8udGVzdChuYXZpZ2F0b3IucGxhdGZvcm0pO1xuICB2YXIgd2luZG93cyA9IC93aW4vaS50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7XG5cbiAgdmFyIHByZXN0b192ZXJzaW9uID0gcHJlc3RvICYmIG5hdmlnYXRvci51c2VyQWdlbnQubWF0Y2goL1ZlcnNpb25cXC8oXFxkKlxcLlxcZCopLyk7XG4gIGlmIChwcmVzdG9fdmVyc2lvbikgcHJlc3RvX3ZlcnNpb24gPSBOdW1iZXIocHJlc3RvX3ZlcnNpb25bMV0pO1xuICBpZiAocHJlc3RvX3ZlcnNpb24gJiYgcHJlc3RvX3ZlcnNpb24gPj0gMTUpIHsgcHJlc3RvID0gZmFsc2U7IHdlYmtpdCA9IHRydWU7IH1cbiAgLy8gU29tZSBicm93c2VycyB1c2UgdGhlIHdyb25nIGV2ZW50IHByb3BlcnRpZXMgdG8gc2lnbmFsIGNtZC9jdHJsIG9uIE9TIFhcbiAgdmFyIGZsaXBDdHJsQ21kID0gbWFjICYmIChxdHdlYmtpdCB8fCBwcmVzdG8gJiYgKHByZXN0b192ZXJzaW9uID09IG51bGwgfHwgcHJlc3RvX3ZlcnNpb24gPCAxMi4xMSkpO1xuICB2YXIgY2FwdHVyZVJpZ2h0Q2xpY2sgPSBnZWNrbyB8fCAoaWUgJiYgaWVfdmVyc2lvbiA+PSA5KTtcblxuICAvLyBPcHRpbWl6ZSBzb21lIGNvZGUgd2hlbiB0aGVzZSBmZWF0dXJlcyBhcmUgbm90IHVzZWQuXG4gIHZhciBzYXdSZWFkT25seVNwYW5zID0gZmFsc2UsIHNhd0NvbGxhcHNlZFNwYW5zID0gZmFsc2U7XG5cbiAgLy8gRURJVE9SIENPTlNUUlVDVE9SXG5cbiAgLy8gQSBDb2RlTWlycm9yIGluc3RhbmNlIHJlcHJlc2VudHMgYW4gZWRpdG9yLiBUaGlzIGlzIHRoZSBvYmplY3RcbiAgLy8gdGhhdCB1c2VyIGNvZGUgaXMgdXN1YWxseSBkZWFsaW5nIHdpdGguXG5cbiAgZnVuY3Rpb24gQ29kZU1pcnJvcihwbGFjZSwgb3B0aW9ucykge1xuICAgIGlmICghKHRoaXMgaW5zdGFuY2VvZiBDb2RlTWlycm9yKSkgcmV0dXJuIG5ldyBDb2RlTWlycm9yKHBsYWNlLCBvcHRpb25zKTtcblxuICAgIHRoaXMub3B0aW9ucyA9IG9wdGlvbnMgPSBvcHRpb25zID8gY29weU9iaihvcHRpb25zKSA6IHt9O1xuICAgIC8vIERldGVybWluZSBlZmZlY3RpdmUgb3B0aW9ucyBiYXNlZCBvbiBnaXZlbiB2YWx1ZXMgYW5kIGRlZmF1bHRzLlxuICAgIGNvcHlPYmooZGVmYXVsdHMsIG9wdGlvbnMsIGZhbHNlKTtcbiAgICBzZXRHdXR0ZXJzRm9yTGluZU51bWJlcnMob3B0aW9ucyk7XG5cbiAgICB2YXIgZG9jID0gb3B0aW9ucy52YWx1ZTtcbiAgICBpZiAodHlwZW9mIGRvYyA9PSBcInN0cmluZ1wiKSBkb2MgPSBuZXcgRG9jKGRvYywgb3B0aW9ucy5tb2RlKTtcbiAgICB0aGlzLmRvYyA9IGRvYztcblxuICAgIHZhciBkaXNwbGF5ID0gdGhpcy5kaXNwbGF5ID0gbmV3IERpc3BsYXkocGxhY2UsIGRvYyk7XG4gICAgZGlzcGxheS53cmFwcGVyLkNvZGVNaXJyb3IgPSB0aGlzO1xuICAgIHVwZGF0ZUd1dHRlcnModGhpcyk7XG4gICAgdGhlbWVDaGFuZ2VkKHRoaXMpO1xuICAgIGlmIChvcHRpb25zLmxpbmVXcmFwcGluZylcbiAgICAgIHRoaXMuZGlzcGxheS53cmFwcGVyLmNsYXNzTmFtZSArPSBcIiBDb2RlTWlycm9yLXdyYXBcIjtcbiAgICBpZiAob3B0aW9ucy5hdXRvZm9jdXMgJiYgIW1vYmlsZSkgZm9jdXNJbnB1dCh0aGlzKTtcbiAgICBpbml0U2Nyb2xsYmFycyh0aGlzKTtcblxuICAgIHRoaXMuc3RhdGUgPSB7XG4gICAgICBrZXlNYXBzOiBbXSwgIC8vIHN0b3JlcyBtYXBzIGFkZGVkIGJ5IGFkZEtleU1hcFxuICAgICAgb3ZlcmxheXM6IFtdLCAvLyBoaWdobGlnaHRpbmcgb3ZlcmxheXMsIGFzIGFkZGVkIGJ5IGFkZE92ZXJsYXlcbiAgICAgIG1vZGVHZW46IDAsICAgLy8gYnVtcGVkIHdoZW4gbW9kZS9vdmVybGF5IGNoYW5nZXMsIHVzZWQgdG8gaW52YWxpZGF0ZSBoaWdobGlnaHRpbmcgaW5mb1xuICAgICAgb3ZlcndyaXRlOiBmYWxzZSwgZm9jdXNlZDogZmFsc2UsXG4gICAgICBzdXBwcmVzc0VkaXRzOiBmYWxzZSwgLy8gdXNlZCB0byBkaXNhYmxlIGVkaXRpbmcgZHVyaW5nIGtleSBoYW5kbGVycyB3aGVuIGluIHJlYWRPbmx5IG1vZGVcbiAgICAgIHBhc3RlSW5jb21pbmc6IGZhbHNlLCBjdXRJbmNvbWluZzogZmFsc2UsIC8vIGhlbHAgcmVjb2duaXplIHBhc3RlL2N1dCBlZGl0cyBpbiByZWFkSW5wdXRcbiAgICAgIGRyYWdnaW5nVGV4dDogZmFsc2UsXG4gICAgICBoaWdobGlnaHQ6IG5ldyBEZWxheWVkKCksIC8vIHN0b3JlcyBoaWdobGlnaHQgd29ya2VyIHRpbWVvdXRcbiAgICAgIGtleVNlcTogbnVsbCAgLy8gVW5maW5pc2hlZCBrZXkgc2VxdWVuY2VcbiAgICB9O1xuXG4gICAgLy8gT3ZlcnJpZGUgbWFnaWMgdGV4dGFyZWEgY29udGVudCByZXN0b3JlIHRoYXQgSUUgc29tZXRpbWVzIGRvZXNcbiAgICAvLyBvbiBvdXIgaGlkZGVuIHRleHRhcmVhIG9uIHJlbG9hZFxuICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDwgMTEpIHNldFRpbWVvdXQoYmluZChyZXNldElucHV0LCB0aGlzLCB0cnVlKSwgMjApO1xuXG4gICAgcmVnaXN0ZXJFdmVudEhhbmRsZXJzKHRoaXMpO1xuICAgIGVuc3VyZUdsb2JhbEhhbmRsZXJzKCk7XG5cbiAgICBzdGFydE9wZXJhdGlvbih0aGlzKTtcbiAgICB0aGlzLmN1ck9wLmZvcmNlVXBkYXRlID0gdHJ1ZTtcbiAgICBhdHRhY2hEb2ModGhpcywgZG9jKTtcblxuICAgIGlmICgob3B0aW9ucy5hdXRvZm9jdXMgJiYgIW1vYmlsZSkgfHwgYWN0aXZlRWx0KCkgPT0gZGlzcGxheS5pbnB1dClcbiAgICAgIHNldFRpbWVvdXQoYmluZChvbkZvY3VzLCB0aGlzKSwgMjApO1xuICAgIGVsc2VcbiAgICAgIG9uQmx1cih0aGlzKTtcblxuICAgIGZvciAodmFyIG9wdCBpbiBvcHRpb25IYW5kbGVycykgaWYgKG9wdGlvbkhhbmRsZXJzLmhhc093blByb3BlcnR5KG9wdCkpXG4gICAgICBvcHRpb25IYW5kbGVyc1tvcHRdKHRoaXMsIG9wdGlvbnNbb3B0XSwgSW5pdCk7XG4gICAgbWF5YmVVcGRhdGVMaW5lTnVtYmVyV2lkdGgodGhpcyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBpbml0SG9va3MubGVuZ3RoOyArK2kpIGluaXRIb29rc1tpXSh0aGlzKTtcbiAgICBlbmRPcGVyYXRpb24odGhpcyk7XG4gICAgLy8gU3VwcHJlc3Mgb3B0aW1pemVsZWdpYmlsaXR5IGluIFdlYmtpdCwgc2luY2UgaXQgYnJlYWtzIHRleHRcbiAgICAvLyBtZWFzdXJpbmcgb24gbGluZSB3cmFwcGluZyBib3VuZGFyaWVzLlxuICAgIGlmICh3ZWJraXQgJiYgb3B0aW9ucy5saW5lV3JhcHBpbmcgJiZcbiAgICAgICAgZ2V0Q29tcHV0ZWRTdHlsZShkaXNwbGF5LmxpbmVEaXYpLnRleHRSZW5kZXJpbmcgPT0gXCJvcHRpbWl6ZWxlZ2liaWxpdHlcIilcbiAgICAgIGRpc3BsYXkubGluZURpdi5zdHlsZS50ZXh0UmVuZGVyaW5nID0gXCJhdXRvXCI7XG4gIH1cblxuICAvLyBESVNQTEFZIENPTlNUUlVDVE9SXG5cbiAgLy8gVGhlIGRpc3BsYXkgaGFuZGxlcyB0aGUgRE9NIGludGVncmF0aW9uLCBib3RoIGZvciBpbnB1dCByZWFkaW5nXG4gIC8vIGFuZCBjb250ZW50IGRyYXdpbmcuIEl0IGhvbGRzIHJlZmVyZW5jZXMgdG8gRE9NIG5vZGVzIGFuZFxuICAvLyBkaXNwbGF5LXJlbGF0ZWQgc3RhdGUuXG5cbiAgZnVuY3Rpb24gRGlzcGxheShwbGFjZSwgZG9jKSB7XG4gICAgdmFyIGQgPSB0aGlzO1xuXG4gICAgLy8gVGhlIHNlbWloaWRkZW4gdGV4dGFyZWEgdGhhdCBpcyBmb2N1c2VkIHdoZW4gdGhlIGVkaXRvciBpc1xuICAgIC8vIGZvY3VzZWQsIGFuZCByZWNlaXZlcyBpbnB1dC5cbiAgICB2YXIgaW5wdXQgPSBkLmlucHV0ID0gZWx0KFwidGV4dGFyZWFcIiwgbnVsbCwgbnVsbCwgXCJwb3NpdGlvbjogYWJzb2x1dGU7IHBhZGRpbmc6IDA7IHdpZHRoOiAxcHg7IGhlaWdodDogMWVtOyBvdXRsaW5lOiBub25lXCIpO1xuICAgIC8vIFRoZSB0ZXh0YXJlYSBpcyBrZXB0IHBvc2l0aW9uZWQgbmVhciB0aGUgY3Vyc29yIHRvIHByZXZlbnQgdGhlXG4gICAgLy8gZmFjdCB0aGF0IGl0J2xsIGJlIHNjcm9sbGVkIGludG8gdmlldyBvbiBpbnB1dCBmcm9tIHNjcm9sbGluZ1xuICAgIC8vIG91ciBmYWtlIGN1cnNvciBvdXQgb2Ygdmlldy4gT24gd2Via2l0LCB3aGVuIHdyYXA9b2ZmLCBwYXN0ZSBpc1xuICAgIC8vIHZlcnkgc2xvdy4gU28gbWFrZSB0aGUgYXJlYSB3aWRlIGluc3RlYWQuXG4gICAgaWYgKHdlYmtpdCkgaW5wdXQuc3R5bGUud2lkdGggPSBcIjEwMDBweFwiO1xuICAgIGVsc2UgaW5wdXQuc2V0QXR0cmlidXRlKFwid3JhcFwiLCBcIm9mZlwiKTtcbiAgICAvLyBJZiBib3JkZXI6IDA7IC0tIGlPUyBmYWlscyB0byBvcGVuIGtleWJvYXJkIChpc3N1ZSAjMTI4NylcbiAgICBpZiAoaW9zKSBpbnB1dC5zdHlsZS5ib3JkZXIgPSBcIjFweCBzb2xpZCBibGFja1wiO1xuICAgIGlucHV0LnNldEF0dHJpYnV0ZShcImF1dG9jb3JyZWN0XCIsIFwib2ZmXCIpOyBpbnB1dC5zZXRBdHRyaWJ1dGUoXCJhdXRvY2FwaXRhbGl6ZVwiLCBcIm9mZlwiKTsgaW5wdXQuc2V0QXR0cmlidXRlKFwic3BlbGxjaGVja1wiLCBcImZhbHNlXCIpO1xuXG4gICAgLy8gV3JhcHMgYW5kIGhpZGVzIGlucHV0IHRleHRhcmVhXG4gICAgZC5pbnB1dERpdiA9IGVsdChcImRpdlwiLCBbaW5wdXRdLCBudWxsLCBcIm92ZXJmbG93OiBoaWRkZW47IHBvc2l0aW9uOiByZWxhdGl2ZTsgd2lkdGg6IDNweDsgaGVpZ2h0OiAwcHg7XCIpO1xuICAgIC8vIENvdmVycyBib3R0b20tcmlnaHQgc3F1YXJlIHdoZW4gYm90aCBzY3JvbGxiYXJzIGFyZSBwcmVzZW50LlxuICAgIGQuc2Nyb2xsYmFyRmlsbGVyID0gZWx0KFwiZGl2XCIsIG51bGwsIFwiQ29kZU1pcnJvci1zY3JvbGxiYXItZmlsbGVyXCIpO1xuICAgIGQuc2Nyb2xsYmFyRmlsbGVyLnNldEF0dHJpYnV0ZShcIm5vdC1jb250ZW50XCIsIFwidHJ1ZVwiKTtcbiAgICAvLyBDb3ZlcnMgYm90dG9tIG9mIGd1dHRlciB3aGVuIGNvdmVyR3V0dGVyTmV4dFRvU2Nyb2xsYmFyIGlzIG9uXG4gICAgLy8gYW5kIGggc2Nyb2xsYmFyIGlzIHByZXNlbnQuXG4gICAgZC5ndXR0ZXJGaWxsZXIgPSBlbHQoXCJkaXZcIiwgbnVsbCwgXCJDb2RlTWlycm9yLWd1dHRlci1maWxsZXJcIik7XG4gICAgZC5ndXR0ZXJGaWxsZXIuc2V0QXR0cmlidXRlKFwibm90LWNvbnRlbnRcIiwgXCJ0cnVlXCIpO1xuICAgIC8vIFdpbGwgY29udGFpbiB0aGUgYWN0dWFsIGNvZGUsIHBvc2l0aW9uZWQgdG8gY292ZXIgdGhlIHZpZXdwb3J0LlxuICAgIGQubGluZURpdiA9IGVsdChcImRpdlwiLCBudWxsLCBcIkNvZGVNaXJyb3ItY29kZVwiKTtcbiAgICAvLyBFbGVtZW50cyBhcmUgYWRkZWQgdG8gdGhlc2UgdG8gcmVwcmVzZW50IHNlbGVjdGlvbiBhbmQgY3Vyc29ycy5cbiAgICBkLnNlbGVjdGlvbkRpdiA9IGVsdChcImRpdlwiLCBudWxsLCBudWxsLCBcInBvc2l0aW9uOiByZWxhdGl2ZTsgei1pbmRleDogMVwiKTtcbiAgICBkLmN1cnNvckRpdiA9IGVsdChcImRpdlwiLCBudWxsLCBcIkNvZGVNaXJyb3ItY3Vyc29yc1wiKTtcbiAgICAvLyBBIHZpc2liaWxpdHk6IGhpZGRlbiBlbGVtZW50IHVzZWQgdG8gZmluZCB0aGUgc2l6ZSBvZiB0aGluZ3MuXG4gICAgZC5tZWFzdXJlID0gZWx0KFwiZGl2XCIsIG51bGwsIFwiQ29kZU1pcnJvci1tZWFzdXJlXCIpO1xuICAgIC8vIFdoZW4gbGluZXMgb3V0c2lkZSBvZiB0aGUgdmlld3BvcnQgYXJlIG1lYXN1cmVkLCB0aGV5IGFyZSBkcmF3biBpbiB0aGlzLlxuICAgIGQubGluZU1lYXN1cmUgPSBlbHQoXCJkaXZcIiwgbnVsbCwgXCJDb2RlTWlycm9yLW1lYXN1cmVcIik7XG4gICAgLy8gV3JhcHMgZXZlcnl0aGluZyB0aGF0IG5lZWRzIHRvIGV4aXN0IGluc2lkZSB0aGUgdmVydGljYWxseS1wYWRkZWQgY29vcmRpbmF0ZSBzeXN0ZW1cbiAgICBkLmxpbmVTcGFjZSA9IGVsdChcImRpdlwiLCBbZC5tZWFzdXJlLCBkLmxpbmVNZWFzdXJlLCBkLnNlbGVjdGlvbkRpdiwgZC5jdXJzb3JEaXYsIGQubGluZURpdl0sXG4gICAgICAgICAgICAgICAgICAgICAgbnVsbCwgXCJwb3NpdGlvbjogcmVsYXRpdmU7IG91dGxpbmU6IG5vbmVcIik7XG4gICAgLy8gTW92ZWQgYXJvdW5kIGl0cyBwYXJlbnQgdG8gY292ZXIgdmlzaWJsZSB2aWV3LlxuICAgIGQubW92ZXIgPSBlbHQoXCJkaXZcIiwgW2VsdChcImRpdlwiLCBbZC5saW5lU3BhY2VdLCBcIkNvZGVNaXJyb3ItbGluZXNcIildLCBudWxsLCBcInBvc2l0aW9uOiByZWxhdGl2ZVwiKTtcbiAgICAvLyBTZXQgdG8gdGhlIGhlaWdodCBvZiB0aGUgZG9jdW1lbnQsIGFsbG93aW5nIHNjcm9sbGluZy5cbiAgICBkLnNpemVyID0gZWx0KFwiZGl2XCIsIFtkLm1vdmVyXSwgXCJDb2RlTWlycm9yLXNpemVyXCIpO1xuICAgIGQuc2l6ZXJXaWR0aCA9IG51bGw7XG4gICAgLy8gQmVoYXZpb3Igb2YgZWx0cyB3aXRoIG92ZXJmbG93OiBhdXRvIGFuZCBwYWRkaW5nIGlzXG4gICAgLy8gaW5jb25zaXN0ZW50IGFjcm9zcyBicm93c2Vycy4gVGhpcyBpcyB1c2VkIHRvIGVuc3VyZSB0aGVcbiAgICAvLyBzY3JvbGxhYmxlIGFyZWEgaXMgYmlnIGVub3VnaC5cbiAgICBkLmhlaWdodEZvcmNlciA9IGVsdChcImRpdlwiLCBudWxsLCBudWxsLCBcInBvc2l0aW9uOiBhYnNvbHV0ZTsgaGVpZ2h0OiBcIiArIHNjcm9sbGVyR2FwICsgXCJweDsgd2lkdGg6IDFweDtcIik7XG4gICAgLy8gV2lsbCBjb250YWluIHRoZSBndXR0ZXJzLCBpZiBhbnkuXG4gICAgZC5ndXR0ZXJzID0gZWx0KFwiZGl2XCIsIG51bGwsIFwiQ29kZU1pcnJvci1ndXR0ZXJzXCIpO1xuICAgIGQubGluZUd1dHRlciA9IG51bGw7XG4gICAgLy8gQWN0dWFsIHNjcm9sbGFibGUgZWxlbWVudC5cbiAgICBkLnNjcm9sbGVyID0gZWx0KFwiZGl2XCIsIFtkLnNpemVyLCBkLmhlaWdodEZvcmNlciwgZC5ndXR0ZXJzXSwgXCJDb2RlTWlycm9yLXNjcm9sbFwiKTtcbiAgICBkLnNjcm9sbGVyLnNldEF0dHJpYnV0ZShcInRhYkluZGV4XCIsIFwiLTFcIik7XG4gICAgLy8gVGhlIGVsZW1lbnQgaW4gd2hpY2ggdGhlIGVkaXRvciBsaXZlcy5cbiAgICBkLndyYXBwZXIgPSBlbHQoXCJkaXZcIiwgW2QuaW5wdXREaXYsIGQuc2Nyb2xsYmFyRmlsbGVyLCBkLmd1dHRlckZpbGxlciwgZC5zY3JvbGxlcl0sIFwiQ29kZU1pcnJvclwiKTtcblxuICAgIC8vIFdvcmsgYXJvdW5kIElFNyB6LWluZGV4IGJ1ZyAobm90IHBlcmZlY3QsIGhlbmNlIElFNyBub3QgcmVhbGx5IGJlaW5nIHN1cHBvcnRlZClcbiAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDgpIHsgZC5ndXR0ZXJzLnN0eWxlLnpJbmRleCA9IC0xOyBkLnNjcm9sbGVyLnN0eWxlLnBhZGRpbmdSaWdodCA9IDA7IH1cbiAgICAvLyBOZWVkZWQgdG8gaGlkZSBiaWcgYmx1ZSBibGlua2luZyBjdXJzb3Igb24gTW9iaWxlIFNhZmFyaVxuICAgIGlmIChpb3MpIGlucHV0LnN0eWxlLndpZHRoID0gXCIwcHhcIjtcbiAgICBpZiAoIXdlYmtpdCkgZC5zY3JvbGxlci5kcmFnZ2FibGUgPSB0cnVlO1xuICAgIC8vIE5lZWRlZCB0byBoYW5kbGUgVGFiIGtleSBpbiBLSFRNTFxuICAgIGlmIChraHRtbCkgeyBkLmlucHV0RGl2LnN0eWxlLmhlaWdodCA9IFwiMXB4XCI7IGQuaW5wdXREaXYuc3R5bGUucG9zaXRpb24gPSBcImFic29sdXRlXCI7IH1cblxuICAgIGlmIChwbGFjZSkge1xuICAgICAgaWYgKHBsYWNlLmFwcGVuZENoaWxkKSBwbGFjZS5hcHBlbmRDaGlsZChkLndyYXBwZXIpO1xuICAgICAgZWxzZSBwbGFjZShkLndyYXBwZXIpO1xuICAgIH1cblxuICAgIC8vIEN1cnJlbnQgcmVuZGVyZWQgcmFuZ2UgKG1heSBiZSBiaWdnZXIgdGhhbiB0aGUgdmlldyB3aW5kb3cpLlxuICAgIGQudmlld0Zyb20gPSBkLnZpZXdUbyA9IGRvYy5maXJzdDtcbiAgICBkLnJlcG9ydGVkVmlld0Zyb20gPSBkLnJlcG9ydGVkVmlld1RvID0gZG9jLmZpcnN0O1xuICAgIC8vIEluZm9ybWF0aW9uIGFib3V0IHRoZSByZW5kZXJlZCBsaW5lcy5cbiAgICBkLnZpZXcgPSBbXTtcbiAgICBkLnJlbmRlcmVkVmlldyA9IG51bGw7XG4gICAgLy8gSG9sZHMgaW5mbyBhYm91dCBhIHNpbmdsZSByZW5kZXJlZCBsaW5lIHdoZW4gaXQgd2FzIHJlbmRlcmVkXG4gICAgLy8gZm9yIG1lYXN1cmVtZW50LCB3aGlsZSBub3QgaW4gdmlldy5cbiAgICBkLmV4dGVybmFsTWVhc3VyZWQgPSBudWxsO1xuICAgIC8vIEVtcHR5IHNwYWNlIChpbiBwaXhlbHMpIGFib3ZlIHRoZSB2aWV3XG4gICAgZC52aWV3T2Zmc2V0ID0gMDtcbiAgICBkLmxhc3RXcmFwSGVpZ2h0ID0gZC5sYXN0V3JhcFdpZHRoID0gMDtcbiAgICBkLnVwZGF0ZUxpbmVOdW1iZXJzID0gbnVsbDtcblxuICAgIGQubmF0aXZlQmFyV2lkdGggPSBkLmJhckhlaWdodCA9IGQuYmFyV2lkdGggPSAwO1xuICAgIGQuc2Nyb2xsYmFyc0NsaXBwZWQgPSBmYWxzZTtcblxuICAgIC8vIFVzZWQgdG8gb25seSByZXNpemUgdGhlIGxpbmUgbnVtYmVyIGd1dHRlciB3aGVuIG5lY2Vzc2FyeSAod2hlblxuICAgIC8vIHRoZSBhbW91bnQgb2YgbGluZXMgY3Jvc3NlcyBhIGJvdW5kYXJ5IHRoYXQgbWFrZXMgaXRzIHdpZHRoIGNoYW5nZSlcbiAgICBkLmxpbmVOdW1XaWR0aCA9IGQubGluZU51bUlubmVyV2lkdGggPSBkLmxpbmVOdW1DaGFycyA9IG51bGw7XG4gICAgLy8gU2VlIHJlYWRJbnB1dCBhbmQgcmVzZXRJbnB1dFxuICAgIGQucHJldklucHV0ID0gXCJcIjtcbiAgICAvLyBTZXQgdG8gdHJ1ZSB3aGVuIGEgbm9uLWhvcml6b250YWwtc2Nyb2xsaW5nIGxpbmUgd2lkZ2V0IGlzXG4gICAgLy8gYWRkZWQuIEFzIGFuIG9wdGltaXphdGlvbiwgbGluZSB3aWRnZXQgYWxpZ25pbmcgaXMgc2tpcHBlZCB3aGVuXG4gICAgLy8gdGhpcyBpcyBmYWxzZS5cbiAgICBkLmFsaWduV2lkZ2V0cyA9IGZhbHNlO1xuICAgIC8vIEZsYWcgdGhhdCBpbmRpY2F0ZXMgd2hldGhlciB3ZSBleHBlY3QgaW5wdXQgdG8gYXBwZWFyIHJlYWwgc29vblxuICAgIC8vIG5vdyAoYWZ0ZXIgc29tZSBldmVudCBsaWtlICdrZXlwcmVzcycgb3IgJ2lucHV0JykgYW5kIGFyZVxuICAgIC8vIHBvbGxpbmcgaW50ZW5zaXZlbHkuXG4gICAgZC5wb2xsaW5nRmFzdCA9IGZhbHNlO1xuICAgIC8vIFNlbGYtcmVzZXR0aW5nIHRpbWVvdXQgZm9yIHRoZSBwb2xsZXJcbiAgICBkLnBvbGwgPSBuZXcgRGVsYXllZCgpO1xuXG4gICAgZC5jYWNoZWRDaGFyV2lkdGggPSBkLmNhY2hlZFRleHRIZWlnaHQgPSBkLmNhY2hlZFBhZGRpbmdIID0gbnVsbDtcblxuICAgIC8vIFRyYWNrcyB3aGVuIHJlc2V0SW5wdXQgaGFzIHB1bnRlZCB0byBqdXN0IHB1dHRpbmcgYSBzaG9ydFxuICAgIC8vIHN0cmluZyBpbnRvIHRoZSB0ZXh0YXJlYSBpbnN0ZWFkIG9mIHRoZSBmdWxsIHNlbGVjdGlvbi5cbiAgICBkLmluYWNjdXJhdGVTZWxlY3Rpb24gPSBmYWxzZTtcblxuICAgIC8vIFRyYWNrcyB0aGUgbWF4aW11bSBsaW5lIGxlbmd0aCBzbyB0aGF0IHRoZSBob3Jpem9udGFsIHNjcm9sbGJhclxuICAgIC8vIGNhbiBiZSBrZXB0IHN0YXRpYyB3aGVuIHNjcm9sbGluZy5cbiAgICBkLm1heExpbmUgPSBudWxsO1xuICAgIGQubWF4TGluZUxlbmd0aCA9IDA7XG4gICAgZC5tYXhMaW5lQ2hhbmdlZCA9IGZhbHNlO1xuXG4gICAgLy8gVXNlZCBmb3IgbWVhc3VyaW5nIHdoZWVsIHNjcm9sbGluZyBncmFudWxhcml0eVxuICAgIGQud2hlZWxEWCA9IGQud2hlZWxEWSA9IGQud2hlZWxTdGFydFggPSBkLndoZWVsU3RhcnRZID0gbnVsbDtcblxuICAgIC8vIFRydWUgd2hlbiBzaGlmdCBpcyBoZWxkIGRvd24uXG4gICAgZC5zaGlmdCA9IGZhbHNlO1xuXG4gICAgLy8gVXNlZCB0byB0cmFjayB3aGV0aGVyIGFueXRoaW5nIGhhcHBlbmVkIHNpbmNlIHRoZSBjb250ZXh0IG1lbnVcbiAgICAvLyB3YXMgb3BlbmVkLlxuICAgIGQuc2VsRm9yQ29udGV4dE1lbnUgPSBudWxsO1xuICB9XG5cbiAgLy8gU1RBVEUgVVBEQVRFU1xuXG4gIC8vIFVzZWQgdG8gZ2V0IHRoZSBlZGl0b3IgaW50byBhIGNvbnNpc3RlbnQgc3RhdGUgYWdhaW4gd2hlbiBvcHRpb25zIGNoYW5nZS5cblxuICBmdW5jdGlvbiBsb2FkTW9kZShjbSkge1xuICAgIGNtLmRvYy5tb2RlID0gQ29kZU1pcnJvci5nZXRNb2RlKGNtLm9wdGlvbnMsIGNtLmRvYy5tb2RlT3B0aW9uKTtcbiAgICByZXNldE1vZGVTdGF0ZShjbSk7XG4gIH1cblxuICBmdW5jdGlvbiByZXNldE1vZGVTdGF0ZShjbSkge1xuICAgIGNtLmRvYy5pdGVyKGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgIGlmIChsaW5lLnN0YXRlQWZ0ZXIpIGxpbmUuc3RhdGVBZnRlciA9IG51bGw7XG4gICAgICBpZiAobGluZS5zdHlsZXMpIGxpbmUuc3R5bGVzID0gbnVsbDtcbiAgICB9KTtcbiAgICBjbS5kb2MuZnJvbnRpZXIgPSBjbS5kb2MuZmlyc3Q7XG4gICAgc3RhcnRXb3JrZXIoY20sIDEwMCk7XG4gICAgY20uc3RhdGUubW9kZUdlbisrO1xuICAgIGlmIChjbS5jdXJPcCkgcmVnQ2hhbmdlKGNtKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHdyYXBwaW5nQ2hhbmdlZChjbSkge1xuICAgIGlmIChjbS5vcHRpb25zLmxpbmVXcmFwcGluZykge1xuICAgICAgYWRkQ2xhc3MoY20uZGlzcGxheS53cmFwcGVyLCBcIkNvZGVNaXJyb3Itd3JhcFwiKTtcbiAgICAgIGNtLmRpc3BsYXkuc2l6ZXIuc3R5bGUubWluV2lkdGggPSBcIlwiO1xuICAgICAgY20uZGlzcGxheS5zaXplcldpZHRoID0gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcm1DbGFzcyhjbS5kaXNwbGF5LndyYXBwZXIsIFwiQ29kZU1pcnJvci13cmFwXCIpO1xuICAgICAgZmluZE1heExpbmUoY20pO1xuICAgIH1cbiAgICBlc3RpbWF0ZUxpbmVIZWlnaHRzKGNtKTtcbiAgICByZWdDaGFuZ2UoY20pO1xuICAgIGNsZWFyQ2FjaGVzKGNtKTtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7dXBkYXRlU2Nyb2xsYmFycyhjbSk7fSwgMTAwKTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYSBmdW5jdGlvbiB0aGF0IGVzdGltYXRlcyB0aGUgaGVpZ2h0IG9mIGEgbGluZSwgdG8gdXNlIGFzXG4gIC8vIGZpcnN0IGFwcHJveGltYXRpb24gdW50aWwgdGhlIGxpbmUgYmVjb21lcyB2aXNpYmxlIChhbmQgaXMgdGh1c1xuICAvLyBwcm9wZXJseSBtZWFzdXJhYmxlKS5cbiAgZnVuY3Rpb24gZXN0aW1hdGVIZWlnaHQoY20pIHtcbiAgICB2YXIgdGggPSB0ZXh0SGVpZ2h0KGNtLmRpc3BsYXkpLCB3cmFwcGluZyA9IGNtLm9wdGlvbnMubGluZVdyYXBwaW5nO1xuICAgIHZhciBwZXJMaW5lID0gd3JhcHBpbmcgJiYgTWF0aC5tYXgoNSwgY20uZGlzcGxheS5zY3JvbGxlci5jbGllbnRXaWR0aCAvIGNoYXJXaWR0aChjbS5kaXNwbGF5KSAtIDMpO1xuICAgIHJldHVybiBmdW5jdGlvbihsaW5lKSB7XG4gICAgICBpZiAobGluZUlzSGlkZGVuKGNtLmRvYywgbGluZSkpIHJldHVybiAwO1xuXG4gICAgICB2YXIgd2lkZ2V0c0hlaWdodCA9IDA7XG4gICAgICBpZiAobGluZS53aWRnZXRzKSBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmUud2lkZ2V0cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAobGluZS53aWRnZXRzW2ldLmhlaWdodCkgd2lkZ2V0c0hlaWdodCArPSBsaW5lLndpZGdldHNbaV0uaGVpZ2h0O1xuICAgICAgfVxuXG4gICAgICBpZiAod3JhcHBpbmcpXG4gICAgICAgIHJldHVybiB3aWRnZXRzSGVpZ2h0ICsgKE1hdGguY2VpbChsaW5lLnRleHQubGVuZ3RoIC8gcGVyTGluZSkgfHwgMSkgKiB0aDtcbiAgICAgIGVsc2VcbiAgICAgICAgcmV0dXJuIHdpZGdldHNIZWlnaHQgKyB0aDtcbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gZXN0aW1hdGVMaW5lSGVpZ2h0cyhjbSkge1xuICAgIHZhciBkb2MgPSBjbS5kb2MsIGVzdCA9IGVzdGltYXRlSGVpZ2h0KGNtKTtcbiAgICBkb2MuaXRlcihmdW5jdGlvbihsaW5lKSB7XG4gICAgICB2YXIgZXN0SGVpZ2h0ID0gZXN0KGxpbmUpO1xuICAgICAgaWYgKGVzdEhlaWdodCAhPSBsaW5lLmhlaWdodCkgdXBkYXRlTGluZUhlaWdodChsaW5lLCBlc3RIZWlnaHQpO1xuICAgIH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gdGhlbWVDaGFuZ2VkKGNtKSB7XG4gICAgY20uZGlzcGxheS53cmFwcGVyLmNsYXNzTmFtZSA9IGNtLmRpc3BsYXkud3JhcHBlci5jbGFzc05hbWUucmVwbGFjZSgvXFxzKmNtLXMtXFxTKy9nLCBcIlwiKSArXG4gICAgICBjbS5vcHRpb25zLnRoZW1lLnJlcGxhY2UoLyhefFxccylcXHMqL2csIFwiIGNtLXMtXCIpO1xuICAgIGNsZWFyQ2FjaGVzKGNtKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGd1dHRlcnNDaGFuZ2VkKGNtKSB7XG4gICAgdXBkYXRlR3V0dGVycyhjbSk7XG4gICAgcmVnQ2hhbmdlKGNtKTtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7YWxpZ25Ib3Jpem9udGFsbHkoY20pO30sIDIwKTtcbiAgfVxuXG4gIC8vIFJlYnVpbGQgdGhlIGd1dHRlciBlbGVtZW50cywgZW5zdXJlIHRoZSBtYXJnaW4gdG8gdGhlIGxlZnQgb2YgdGhlXG4gIC8vIGNvZGUgbWF0Y2hlcyB0aGVpciB3aWR0aC5cbiAgZnVuY3Rpb24gdXBkYXRlR3V0dGVycyhjbSkge1xuICAgIHZhciBndXR0ZXJzID0gY20uZGlzcGxheS5ndXR0ZXJzLCBzcGVjcyA9IGNtLm9wdGlvbnMuZ3V0dGVycztcbiAgICByZW1vdmVDaGlsZHJlbihndXR0ZXJzKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNwZWNzLmxlbmd0aDsgKytpKSB7XG4gICAgICB2YXIgZ3V0dGVyQ2xhc3MgPSBzcGVjc1tpXTtcbiAgICAgIHZhciBnRWx0ID0gZ3V0dGVycy5hcHBlbmRDaGlsZChlbHQoXCJkaXZcIiwgbnVsbCwgXCJDb2RlTWlycm9yLWd1dHRlciBcIiArIGd1dHRlckNsYXNzKSk7XG4gICAgICBpZiAoZ3V0dGVyQ2xhc3MgPT0gXCJDb2RlTWlycm9yLWxpbmVudW1iZXJzXCIpIHtcbiAgICAgICAgY20uZGlzcGxheS5saW5lR3V0dGVyID0gZ0VsdDtcbiAgICAgICAgZ0VsdC5zdHlsZS53aWR0aCA9IChjbS5kaXNwbGF5LmxpbmVOdW1XaWR0aCB8fCAxKSArIFwicHhcIjtcbiAgICAgIH1cbiAgICB9XG4gICAgZ3V0dGVycy5zdHlsZS5kaXNwbGF5ID0gaSA/IFwiXCIgOiBcIm5vbmVcIjtcbiAgICB1cGRhdGVHdXR0ZXJTcGFjZShjbSk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVHdXR0ZXJTcGFjZShjbSkge1xuICAgIHZhciB3aWR0aCA9IGNtLmRpc3BsYXkuZ3V0dGVycy5vZmZzZXRXaWR0aDtcbiAgICBjbS5kaXNwbGF5LnNpemVyLnN0eWxlLm1hcmdpbkxlZnQgPSB3aWR0aCArIFwicHhcIjtcbiAgfVxuXG4gIC8vIENvbXB1dGUgdGhlIGNoYXJhY3RlciBsZW5ndGggb2YgYSBsaW5lLCB0YWtpbmcgaW50byBhY2NvdW50XG4gIC8vIGNvbGxhcHNlZCByYW5nZXMgKHNlZSBtYXJrVGV4dCkgdGhhdCBtaWdodCBoaWRlIHBhcnRzLCBhbmQgam9pblxuICAvLyBvdGhlciBsaW5lcyBvbnRvIGl0LlxuICBmdW5jdGlvbiBsaW5lTGVuZ3RoKGxpbmUpIHtcbiAgICBpZiAobGluZS5oZWlnaHQgPT0gMCkgcmV0dXJuIDA7XG4gICAgdmFyIGxlbiA9IGxpbmUudGV4dC5sZW5ndGgsIG1lcmdlZCwgY3VyID0gbGluZTtcbiAgICB3aGlsZSAobWVyZ2VkID0gY29sbGFwc2VkU3BhbkF0U3RhcnQoY3VyKSkge1xuICAgICAgdmFyIGZvdW5kID0gbWVyZ2VkLmZpbmQoMCwgdHJ1ZSk7XG4gICAgICBjdXIgPSBmb3VuZC5mcm9tLmxpbmU7XG4gICAgICBsZW4gKz0gZm91bmQuZnJvbS5jaCAtIGZvdW5kLnRvLmNoO1xuICAgIH1cbiAgICBjdXIgPSBsaW5lO1xuICAgIHdoaWxlIChtZXJnZWQgPSBjb2xsYXBzZWRTcGFuQXRFbmQoY3VyKSkge1xuICAgICAgdmFyIGZvdW5kID0gbWVyZ2VkLmZpbmQoMCwgdHJ1ZSk7XG4gICAgICBsZW4gLT0gY3VyLnRleHQubGVuZ3RoIC0gZm91bmQuZnJvbS5jaDtcbiAgICAgIGN1ciA9IGZvdW5kLnRvLmxpbmU7XG4gICAgICBsZW4gKz0gY3VyLnRleHQubGVuZ3RoIC0gZm91bmQudG8uY2g7XG4gICAgfVxuICAgIHJldHVybiBsZW47XG4gIH1cblxuICAvLyBGaW5kIHRoZSBsb25nZXN0IGxpbmUgaW4gdGhlIGRvY3VtZW50LlxuICBmdW5jdGlvbiBmaW5kTWF4TGluZShjbSkge1xuICAgIHZhciBkID0gY20uZGlzcGxheSwgZG9jID0gY20uZG9jO1xuICAgIGQubWF4TGluZSA9IGdldExpbmUoZG9jLCBkb2MuZmlyc3QpO1xuICAgIGQubWF4TGluZUxlbmd0aCA9IGxpbmVMZW5ndGgoZC5tYXhMaW5lKTtcbiAgICBkLm1heExpbmVDaGFuZ2VkID0gdHJ1ZTtcbiAgICBkb2MuaXRlcihmdW5jdGlvbihsaW5lKSB7XG4gICAgICB2YXIgbGVuID0gbGluZUxlbmd0aChsaW5lKTtcbiAgICAgIGlmIChsZW4gPiBkLm1heExpbmVMZW5ndGgpIHtcbiAgICAgICAgZC5tYXhMaW5lTGVuZ3RoID0gbGVuO1xuICAgICAgICBkLm1heExpbmUgPSBsaW5lO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLy8gTWFrZSBzdXJlIHRoZSBndXR0ZXJzIG9wdGlvbnMgY29udGFpbnMgdGhlIGVsZW1lbnRcbiAgLy8gXCJDb2RlTWlycm9yLWxpbmVudW1iZXJzXCIgd2hlbiB0aGUgbGluZU51bWJlcnMgb3B0aW9uIGlzIHRydWUuXG4gIGZ1bmN0aW9uIHNldEd1dHRlcnNGb3JMaW5lTnVtYmVycyhvcHRpb25zKSB7XG4gICAgdmFyIGZvdW5kID0gaW5kZXhPZihvcHRpb25zLmd1dHRlcnMsIFwiQ29kZU1pcnJvci1saW5lbnVtYmVyc1wiKTtcbiAgICBpZiAoZm91bmQgPT0gLTEgJiYgb3B0aW9ucy5saW5lTnVtYmVycykge1xuICAgICAgb3B0aW9ucy5ndXR0ZXJzID0gb3B0aW9ucy5ndXR0ZXJzLmNvbmNhdChbXCJDb2RlTWlycm9yLWxpbmVudW1iZXJzXCJdKTtcbiAgICB9IGVsc2UgaWYgKGZvdW5kID4gLTEgJiYgIW9wdGlvbnMubGluZU51bWJlcnMpIHtcbiAgICAgIG9wdGlvbnMuZ3V0dGVycyA9IG9wdGlvbnMuZ3V0dGVycy5zbGljZSgwKTtcbiAgICAgIG9wdGlvbnMuZ3V0dGVycy5zcGxpY2UoZm91bmQsIDEpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNDUk9MTEJBUlNcblxuICAvLyBQcmVwYXJlIERPTSByZWFkcyBuZWVkZWQgdG8gdXBkYXRlIHRoZSBzY3JvbGxiYXJzLiBEb25lIGluIG9uZVxuICAvLyBzaG90IHRvIG1pbmltaXplIHVwZGF0ZS9tZWFzdXJlIHJvdW5kdHJpcHMuXG4gIGZ1bmN0aW9uIG1lYXN1cmVGb3JTY3JvbGxiYXJzKGNtKSB7XG4gICAgdmFyIGQgPSBjbS5kaXNwbGF5LCBndXR0ZXJXID0gZC5ndXR0ZXJzLm9mZnNldFdpZHRoO1xuICAgIHZhciBkb2NIID0gTWF0aC5yb3VuZChjbS5kb2MuaGVpZ2h0ICsgcGFkZGluZ1ZlcnQoY20uZGlzcGxheSkpO1xuICAgIHJldHVybiB7XG4gICAgICBjbGllbnRIZWlnaHQ6IGQuc2Nyb2xsZXIuY2xpZW50SGVpZ2h0LFxuICAgICAgdmlld0hlaWdodDogZC53cmFwcGVyLmNsaWVudEhlaWdodCxcbiAgICAgIHNjcm9sbFdpZHRoOiBkLnNjcm9sbGVyLnNjcm9sbFdpZHRoLCBjbGllbnRXaWR0aDogZC5zY3JvbGxlci5jbGllbnRXaWR0aCxcbiAgICAgIHZpZXdXaWR0aDogZC53cmFwcGVyLmNsaWVudFdpZHRoLFxuICAgICAgYmFyTGVmdDogY20ub3B0aW9ucy5maXhlZEd1dHRlciA/IGd1dHRlclcgOiAwLFxuICAgICAgZG9jSGVpZ2h0OiBkb2NILFxuICAgICAgc2Nyb2xsSGVpZ2h0OiBkb2NIICsgc2Nyb2xsR2FwKGNtKSArIGQuYmFySGVpZ2h0LFxuICAgICAgbmF0aXZlQmFyV2lkdGg6IGQubmF0aXZlQmFyV2lkdGgsXG4gICAgICBndXR0ZXJXaWR0aDogZ3V0dGVyV1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBOYXRpdmVTY3JvbGxiYXJzKHBsYWNlLCBzY3JvbGwsIGNtKSB7XG4gICAgdGhpcy5jbSA9IGNtO1xuICAgIHZhciB2ZXJ0ID0gdGhpcy52ZXJ0ID0gZWx0KFwiZGl2XCIsIFtlbHQoXCJkaXZcIiwgbnVsbCwgbnVsbCwgXCJtaW4td2lkdGg6IDFweFwiKV0sIFwiQ29kZU1pcnJvci12c2Nyb2xsYmFyXCIpO1xuICAgIHZhciBob3JpeiA9IHRoaXMuaG9yaXogPSBlbHQoXCJkaXZcIiwgW2VsdChcImRpdlwiLCBudWxsLCBudWxsLCBcImhlaWdodDogMTAwJTsgbWluLWhlaWdodDogMXB4XCIpXSwgXCJDb2RlTWlycm9yLWhzY3JvbGxiYXJcIik7XG4gICAgcGxhY2UodmVydCk7IHBsYWNlKGhvcml6KTtcblxuICAgIG9uKHZlcnQsIFwic2Nyb2xsXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHZlcnQuY2xpZW50SGVpZ2h0KSBzY3JvbGwodmVydC5zY3JvbGxUb3AsIFwidmVydGljYWxcIik7XG4gICAgfSk7XG4gICAgb24oaG9yaXosIFwic2Nyb2xsXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGhvcml6LmNsaWVudFdpZHRoKSBzY3JvbGwoaG9yaXouc2Nyb2xsTGVmdCwgXCJob3Jpem9udGFsXCIpO1xuICAgIH0pO1xuXG4gICAgdGhpcy5jaGVja2VkT3ZlcmxheSA9IGZhbHNlO1xuICAgIC8vIE5lZWQgdG8gc2V0IGEgbWluaW11bSB3aWR0aCB0byBzZWUgdGhlIHNjcm9sbGJhciBvbiBJRTcgKGJ1dCBtdXN0IG5vdCBzZXQgaXQgb24gSUU4KS5cbiAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDgpIHRoaXMuaG9yaXouc3R5bGUubWluSGVpZ2h0ID0gdGhpcy52ZXJ0LnN0eWxlLm1pbldpZHRoID0gXCIxOHB4XCI7XG4gIH1cblxuICBOYXRpdmVTY3JvbGxiYXJzLnByb3RvdHlwZSA9IGNvcHlPYmooe1xuICAgIHVwZGF0ZTogZnVuY3Rpb24obWVhc3VyZSkge1xuICAgICAgdmFyIG5lZWRzSCA9IG1lYXN1cmUuc2Nyb2xsV2lkdGggPiBtZWFzdXJlLmNsaWVudFdpZHRoICsgMTtcbiAgICAgIHZhciBuZWVkc1YgPSBtZWFzdXJlLnNjcm9sbEhlaWdodCA+IG1lYXN1cmUuY2xpZW50SGVpZ2h0ICsgMTtcbiAgICAgIHZhciBzV2lkdGggPSBtZWFzdXJlLm5hdGl2ZUJhcldpZHRoO1xuXG4gICAgICBpZiAobmVlZHNWKSB7XG4gICAgICAgIHRoaXMudmVydC5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgICAgICB0aGlzLnZlcnQuc3R5bGUuYm90dG9tID0gbmVlZHNIID8gc1dpZHRoICsgXCJweFwiIDogXCIwXCI7XG4gICAgICAgIHZhciB0b3RhbEhlaWdodCA9IG1lYXN1cmUudmlld0hlaWdodCAtIChuZWVkc0ggPyBzV2lkdGggOiAwKTtcbiAgICAgICAgLy8gQSBidWcgaW4gSUU4IGNhbiBjYXVzZSB0aGlzIHZhbHVlIHRvIGJlIG5lZ2F0aXZlLCBzbyBndWFyZCBpdC5cbiAgICAgICAgdGhpcy52ZXJ0LmZpcnN0Q2hpbGQuc3R5bGUuaGVpZ2h0ID1cbiAgICAgICAgICBNYXRoLm1heCgwLCBtZWFzdXJlLnNjcm9sbEhlaWdodCAtIG1lYXN1cmUuY2xpZW50SGVpZ2h0ICsgdG90YWxIZWlnaHQpICsgXCJweFwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy52ZXJ0LnN0eWxlLmRpc3BsYXkgPSBcIlwiO1xuICAgICAgICB0aGlzLnZlcnQuZmlyc3RDaGlsZC5zdHlsZS5oZWlnaHQgPSBcIjBcIjtcbiAgICAgIH1cblxuICAgICAgaWYgKG5lZWRzSCkge1xuICAgICAgICB0aGlzLmhvcml6LnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG4gICAgICAgIHRoaXMuaG9yaXouc3R5bGUucmlnaHQgPSBuZWVkc1YgPyBzV2lkdGggKyBcInB4XCIgOiBcIjBcIjtcbiAgICAgICAgdGhpcy5ob3Jpei5zdHlsZS5sZWZ0ID0gbWVhc3VyZS5iYXJMZWZ0ICsgXCJweFwiO1xuICAgICAgICB2YXIgdG90YWxXaWR0aCA9IG1lYXN1cmUudmlld1dpZHRoIC0gbWVhc3VyZS5iYXJMZWZ0IC0gKG5lZWRzViA/IHNXaWR0aCA6IDApO1xuICAgICAgICB0aGlzLmhvcml6LmZpcnN0Q2hpbGQuc3R5bGUud2lkdGggPVxuICAgICAgICAgIChtZWFzdXJlLnNjcm9sbFdpZHRoIC0gbWVhc3VyZS5jbGllbnRXaWR0aCArIHRvdGFsV2lkdGgpICsgXCJweFwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5ob3Jpei5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcbiAgICAgICAgdGhpcy5ob3Jpei5maXJzdENoaWxkLnN0eWxlLndpZHRoID0gXCIwXCI7XG4gICAgICB9XG5cbiAgICAgIGlmICghdGhpcy5jaGVja2VkT3ZlcmxheSAmJiBtZWFzdXJlLmNsaWVudEhlaWdodCA+IDApIHtcbiAgICAgICAgaWYgKHNXaWR0aCA9PSAwKSB0aGlzLm92ZXJsYXlIYWNrKCk7XG4gICAgICAgIHRoaXMuY2hlY2tlZE92ZXJsYXkgPSB0cnVlO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge3JpZ2h0OiBuZWVkc1YgPyBzV2lkdGggOiAwLCBib3R0b206IG5lZWRzSCA/IHNXaWR0aCA6IDB9O1xuICAgIH0sXG4gICAgc2V0U2Nyb2xsTGVmdDogZnVuY3Rpb24ocG9zKSB7XG4gICAgICBpZiAodGhpcy5ob3Jpei5zY3JvbGxMZWZ0ICE9IHBvcykgdGhpcy5ob3Jpei5zY3JvbGxMZWZ0ID0gcG9zO1xuICAgIH0sXG4gICAgc2V0U2Nyb2xsVG9wOiBmdW5jdGlvbihwb3MpIHtcbiAgICAgIGlmICh0aGlzLnZlcnQuc2Nyb2xsVG9wICE9IHBvcykgdGhpcy52ZXJ0LnNjcm9sbFRvcCA9IHBvcztcbiAgICB9LFxuICAgIG92ZXJsYXlIYWNrOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciB3ID0gbWFjICYmICFtYWNfZ2VNb3VudGFpbkxpb24gPyBcIjEycHhcIiA6IFwiMThweFwiO1xuICAgICAgdGhpcy5ob3Jpei5zdHlsZS5taW5IZWlnaHQgPSB0aGlzLnZlcnQuc3R5bGUubWluV2lkdGggPSB3O1xuICAgICAgdmFyIHNlbGYgPSB0aGlzO1xuICAgICAgdmFyIGJhck1vdXNlRG93biA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgaWYgKGVfdGFyZ2V0KGUpICE9IHNlbGYudmVydCAmJiBlX3RhcmdldChlKSAhPSBzZWxmLmhvcml6KVxuICAgICAgICAgIG9wZXJhdGlvbihzZWxmLmNtLCBvbk1vdXNlRG93bikoZSk7XG4gICAgICB9O1xuICAgICAgb24odGhpcy52ZXJ0LCBcIm1vdXNlZG93blwiLCBiYXJNb3VzZURvd24pO1xuICAgICAgb24odGhpcy5ob3JpeiwgXCJtb3VzZWRvd25cIiwgYmFyTW91c2VEb3duKTtcbiAgICB9LFxuICAgIGNsZWFyOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBwYXJlbnQgPSB0aGlzLmhvcml6LnBhcmVudE5vZGU7XG4gICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcy5ob3Jpeik7XG4gICAgICBwYXJlbnQucmVtb3ZlQ2hpbGQodGhpcy52ZXJ0KTtcbiAgICB9XG4gIH0sIE5hdGl2ZVNjcm9sbGJhcnMucHJvdG90eXBlKTtcblxuICBmdW5jdGlvbiBOdWxsU2Nyb2xsYmFycygpIHt9XG5cbiAgTnVsbFNjcm9sbGJhcnMucHJvdG90eXBlID0gY29weU9iaih7XG4gICAgdXBkYXRlOiBmdW5jdGlvbigpIHsgcmV0dXJuIHtib3R0b206IDAsIHJpZ2h0OiAwfTsgfSxcbiAgICBzZXRTY3JvbGxMZWZ0OiBmdW5jdGlvbigpIHt9LFxuICAgIHNldFNjcm9sbFRvcDogZnVuY3Rpb24oKSB7fSxcbiAgICBjbGVhcjogZnVuY3Rpb24oKSB7fVxuICB9LCBOdWxsU2Nyb2xsYmFycy5wcm90b3R5cGUpO1xuXG4gIENvZGVNaXJyb3Iuc2Nyb2xsYmFyTW9kZWwgPSB7XCJuYXRpdmVcIjogTmF0aXZlU2Nyb2xsYmFycywgXCJudWxsXCI6IE51bGxTY3JvbGxiYXJzfTtcblxuICBmdW5jdGlvbiBpbml0U2Nyb2xsYmFycyhjbSkge1xuICAgIGlmIChjbS5kaXNwbGF5LnNjcm9sbGJhcnMpIHtcbiAgICAgIGNtLmRpc3BsYXkuc2Nyb2xsYmFycy5jbGVhcigpO1xuICAgICAgaWYgKGNtLmRpc3BsYXkuc2Nyb2xsYmFycy5hZGRDbGFzcylcbiAgICAgICAgcm1DbGFzcyhjbS5kaXNwbGF5LndyYXBwZXIsIGNtLmRpc3BsYXkuc2Nyb2xsYmFycy5hZGRDbGFzcyk7XG4gICAgfVxuXG4gICAgY20uZGlzcGxheS5zY3JvbGxiYXJzID0gbmV3IENvZGVNaXJyb3Iuc2Nyb2xsYmFyTW9kZWxbY20ub3B0aW9ucy5zY3JvbGxiYXJTdHlsZV0oZnVuY3Rpb24obm9kZSkge1xuICAgICAgY20uZGlzcGxheS53cmFwcGVyLmluc2VydEJlZm9yZShub2RlLCBjbS5kaXNwbGF5LnNjcm9sbGJhckZpbGxlcik7XG4gICAgICBvbihub2RlLCBcIm1vdXNlZG93blwiLCBmdW5jdGlvbigpIHtcbiAgICAgICAgaWYgKGNtLnN0YXRlLmZvY3VzZWQpIHNldFRpbWVvdXQoYmluZChmb2N1c0lucHV0LCBjbSksIDApO1xuICAgICAgfSk7XG4gICAgICBub2RlLnNldEF0dHJpYnV0ZShcIm5vdC1jb250ZW50XCIsIFwidHJ1ZVwiKTtcbiAgICB9LCBmdW5jdGlvbihwb3MsIGF4aXMpIHtcbiAgICAgIGlmIChheGlzID09IFwiaG9yaXpvbnRhbFwiKSBzZXRTY3JvbGxMZWZ0KGNtLCBwb3MpO1xuICAgICAgZWxzZSBzZXRTY3JvbGxUb3AoY20sIHBvcyk7XG4gICAgfSwgY20pO1xuICAgIGlmIChjbS5kaXNwbGF5LnNjcm9sbGJhcnMuYWRkQ2xhc3MpXG4gICAgICBhZGRDbGFzcyhjbS5kaXNwbGF5LndyYXBwZXIsIGNtLmRpc3BsYXkuc2Nyb2xsYmFycy5hZGRDbGFzcyk7XG4gIH1cblxuICBmdW5jdGlvbiB1cGRhdGVTY3JvbGxiYXJzKGNtLCBtZWFzdXJlKSB7XG4gICAgaWYgKCFtZWFzdXJlKSBtZWFzdXJlID0gbWVhc3VyZUZvclNjcm9sbGJhcnMoY20pO1xuICAgIHZhciBzdGFydFdpZHRoID0gY20uZGlzcGxheS5iYXJXaWR0aCwgc3RhcnRIZWlnaHQgPSBjbS5kaXNwbGF5LmJhckhlaWdodDtcbiAgICB1cGRhdGVTY3JvbGxiYXJzSW5uZXIoY20sIG1lYXN1cmUpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgNCAmJiBzdGFydFdpZHRoICE9IGNtLmRpc3BsYXkuYmFyV2lkdGggfHwgc3RhcnRIZWlnaHQgIT0gY20uZGlzcGxheS5iYXJIZWlnaHQ7IGkrKykge1xuICAgICAgaWYgKHN0YXJ0V2lkdGggIT0gY20uZGlzcGxheS5iYXJXaWR0aCAmJiBjbS5vcHRpb25zLmxpbmVXcmFwcGluZylcbiAgICAgICAgdXBkYXRlSGVpZ2h0c0luVmlld3BvcnQoY20pO1xuICAgICAgdXBkYXRlU2Nyb2xsYmFyc0lubmVyKGNtLCBtZWFzdXJlRm9yU2Nyb2xsYmFycyhjbSkpO1xuICAgICAgc3RhcnRXaWR0aCA9IGNtLmRpc3BsYXkuYmFyV2lkdGg7IHN0YXJ0SGVpZ2h0ID0gY20uZGlzcGxheS5iYXJIZWlnaHQ7XG4gICAgfVxuICB9XG5cbiAgLy8gUmUtc3luY2hyb25pemUgdGhlIGZha2Ugc2Nyb2xsYmFycyB3aXRoIHRoZSBhY3R1YWwgc2l6ZSBvZiB0aGVcbiAgLy8gY29udGVudC5cbiAgZnVuY3Rpb24gdXBkYXRlU2Nyb2xsYmFyc0lubmVyKGNtLCBtZWFzdXJlKSB7XG4gICAgdmFyIGQgPSBjbS5kaXNwbGF5O1xuICAgIHZhciBzaXplcyA9IGQuc2Nyb2xsYmFycy51cGRhdGUobWVhc3VyZSk7XG5cbiAgICBkLnNpemVyLnN0eWxlLnBhZGRpbmdSaWdodCA9IChkLmJhcldpZHRoID0gc2l6ZXMucmlnaHQpICsgXCJweFwiO1xuICAgIGQuc2l6ZXIuc3R5bGUucGFkZGluZ0JvdHRvbSA9IChkLmJhckhlaWdodCA9IHNpemVzLmJvdHRvbSkgKyBcInB4XCI7XG5cbiAgICBpZiAoc2l6ZXMucmlnaHQgJiYgc2l6ZXMuYm90dG9tKSB7XG4gICAgICBkLnNjcm9sbGJhckZpbGxlci5zdHlsZS5kaXNwbGF5ID0gXCJibG9ja1wiO1xuICAgICAgZC5zY3JvbGxiYXJGaWxsZXIuc3R5bGUuaGVpZ2h0ID0gc2l6ZXMuYm90dG9tICsgXCJweFwiO1xuICAgICAgZC5zY3JvbGxiYXJGaWxsZXIuc3R5bGUud2lkdGggPSBzaXplcy5yaWdodCArIFwicHhcIjtcbiAgICB9IGVsc2UgZC5zY3JvbGxiYXJGaWxsZXIuc3R5bGUuZGlzcGxheSA9IFwiXCI7XG4gICAgaWYgKHNpemVzLmJvdHRvbSAmJiBjbS5vcHRpb25zLmNvdmVyR3V0dGVyTmV4dFRvU2Nyb2xsYmFyICYmIGNtLm9wdGlvbnMuZml4ZWRHdXR0ZXIpIHtcbiAgICAgIGQuZ3V0dGVyRmlsbGVyLnN0eWxlLmRpc3BsYXkgPSBcImJsb2NrXCI7XG4gICAgICBkLmd1dHRlckZpbGxlci5zdHlsZS5oZWlnaHQgPSBzaXplcy5ib3R0b20gKyBcInB4XCI7XG4gICAgICBkLmd1dHRlckZpbGxlci5zdHlsZS53aWR0aCA9IG1lYXN1cmUuZ3V0dGVyV2lkdGggKyBcInB4XCI7XG4gICAgfSBlbHNlIGQuZ3V0dGVyRmlsbGVyLnN0eWxlLmRpc3BsYXkgPSBcIlwiO1xuICB9XG5cbiAgLy8gQ29tcHV0ZSB0aGUgbGluZXMgdGhhdCBhcmUgdmlzaWJsZSBpbiBhIGdpdmVuIHZpZXdwb3J0IChkZWZhdWx0c1xuICAvLyB0aGUgdGhlIGN1cnJlbnQgc2Nyb2xsIHBvc2l0aW9uKS4gdmlld3BvcnQgbWF5IGNvbnRhaW4gdG9wLFxuICAvLyBoZWlnaHQsIGFuZCBlbnN1cmUgKHNlZSBvcC5zY3JvbGxUb1BvcykgcHJvcGVydGllcy5cbiAgZnVuY3Rpb24gdmlzaWJsZUxpbmVzKGRpc3BsYXksIGRvYywgdmlld3BvcnQpIHtcbiAgICB2YXIgdG9wID0gdmlld3BvcnQgJiYgdmlld3BvcnQudG9wICE9IG51bGwgPyBNYXRoLm1heCgwLCB2aWV3cG9ydC50b3ApIDogZGlzcGxheS5zY3JvbGxlci5zY3JvbGxUb3A7XG4gICAgdG9wID0gTWF0aC5mbG9vcih0b3AgLSBwYWRkaW5nVG9wKGRpc3BsYXkpKTtcbiAgICB2YXIgYm90dG9tID0gdmlld3BvcnQgJiYgdmlld3BvcnQuYm90dG9tICE9IG51bGwgPyB2aWV3cG9ydC5ib3R0b20gOiB0b3AgKyBkaXNwbGF5LndyYXBwZXIuY2xpZW50SGVpZ2h0O1xuXG4gICAgdmFyIGZyb20gPSBsaW5lQXRIZWlnaHQoZG9jLCB0b3ApLCB0byA9IGxpbmVBdEhlaWdodChkb2MsIGJvdHRvbSk7XG4gICAgLy8gRW5zdXJlIGlzIGEge2Zyb206IHtsaW5lLCBjaH0sIHRvOiB7bGluZSwgY2h9fSBvYmplY3QsIGFuZFxuICAgIC8vIGZvcmNlcyB0aG9zZSBsaW5lcyBpbnRvIHRoZSB2aWV3cG9ydCAoaWYgcG9zc2libGUpLlxuICAgIGlmICh2aWV3cG9ydCAmJiB2aWV3cG9ydC5lbnN1cmUpIHtcbiAgICAgIHZhciBlbnN1cmVGcm9tID0gdmlld3BvcnQuZW5zdXJlLmZyb20ubGluZSwgZW5zdXJlVG8gPSB2aWV3cG9ydC5lbnN1cmUudG8ubGluZTtcbiAgICAgIGlmIChlbnN1cmVGcm9tIDwgZnJvbSkge1xuICAgICAgICBmcm9tID0gZW5zdXJlRnJvbTtcbiAgICAgICAgdG8gPSBsaW5lQXRIZWlnaHQoZG9jLCBoZWlnaHRBdExpbmUoZ2V0TGluZShkb2MsIGVuc3VyZUZyb20pKSArIGRpc3BsYXkud3JhcHBlci5jbGllbnRIZWlnaHQpO1xuICAgICAgfSBlbHNlIGlmIChNYXRoLm1pbihlbnN1cmVUbywgZG9jLmxhc3RMaW5lKCkpID49IHRvKSB7XG4gICAgICAgIGZyb20gPSBsaW5lQXRIZWlnaHQoZG9jLCBoZWlnaHRBdExpbmUoZ2V0TGluZShkb2MsIGVuc3VyZVRvKSkgLSBkaXNwbGF5LndyYXBwZXIuY2xpZW50SGVpZ2h0KTtcbiAgICAgICAgdG8gPSBlbnN1cmVUbztcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHtmcm9tOiBmcm9tLCB0bzogTWF0aC5tYXgodG8sIGZyb20gKyAxKX07XG4gIH1cblxuICAvLyBMSU5FIE5VTUJFUlNcblxuICAvLyBSZS1hbGlnbiBsaW5lIG51bWJlcnMgYW5kIGd1dHRlciBtYXJrcyB0byBjb21wZW5zYXRlIGZvclxuICAvLyBob3Jpem9udGFsIHNjcm9sbGluZy5cbiAgZnVuY3Rpb24gYWxpZ25Ib3Jpem9udGFsbHkoY20pIHtcbiAgICB2YXIgZGlzcGxheSA9IGNtLmRpc3BsYXksIHZpZXcgPSBkaXNwbGF5LnZpZXc7XG4gICAgaWYgKCFkaXNwbGF5LmFsaWduV2lkZ2V0cyAmJiAoIWRpc3BsYXkuZ3V0dGVycy5maXJzdENoaWxkIHx8ICFjbS5vcHRpb25zLmZpeGVkR3V0dGVyKSkgcmV0dXJuO1xuICAgIHZhciBjb21wID0gY29tcGVuc2F0ZUZvckhTY3JvbGwoZGlzcGxheSkgLSBkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbExlZnQgKyBjbS5kb2Muc2Nyb2xsTGVmdDtcbiAgICB2YXIgZ3V0dGVyVyA9IGRpc3BsYXkuZ3V0dGVycy5vZmZzZXRXaWR0aCwgbGVmdCA9IGNvbXAgKyBcInB4XCI7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2aWV3Lmxlbmd0aDsgaSsrKSBpZiAoIXZpZXdbaV0uaGlkZGVuKSB7XG4gICAgICBpZiAoY20ub3B0aW9ucy5maXhlZEd1dHRlciAmJiB2aWV3W2ldLmd1dHRlcilcbiAgICAgICAgdmlld1tpXS5ndXR0ZXIuc3R5bGUubGVmdCA9IGxlZnQ7XG4gICAgICB2YXIgYWxpZ24gPSB2aWV3W2ldLmFsaWduYWJsZTtcbiAgICAgIGlmIChhbGlnbikgZm9yICh2YXIgaiA9IDA7IGogPCBhbGlnbi5sZW5ndGg7IGorKylcbiAgICAgICAgYWxpZ25bal0uc3R5bGUubGVmdCA9IGxlZnQ7XG4gICAgfVxuICAgIGlmIChjbS5vcHRpb25zLmZpeGVkR3V0dGVyKVxuICAgICAgZGlzcGxheS5ndXR0ZXJzLnN0eWxlLmxlZnQgPSAoY29tcCArIGd1dHRlclcpICsgXCJweFwiO1xuICB9XG5cbiAgLy8gVXNlZCB0byBlbnN1cmUgdGhhdCB0aGUgbGluZSBudW1iZXIgZ3V0dGVyIGlzIHN0aWxsIHRoZSByaWdodFxuICAvLyBzaXplIGZvciB0aGUgY3VycmVudCBkb2N1bWVudCBzaXplLiBSZXR1cm5zIHRydWUgd2hlbiBhbiB1cGRhdGVcbiAgLy8gaXMgbmVlZGVkLlxuICBmdW5jdGlvbiBtYXliZVVwZGF0ZUxpbmVOdW1iZXJXaWR0aChjbSkge1xuICAgIGlmICghY20ub3B0aW9ucy5saW5lTnVtYmVycykgcmV0dXJuIGZhbHNlO1xuICAgIHZhciBkb2MgPSBjbS5kb2MsIGxhc3QgPSBsaW5lTnVtYmVyRm9yKGNtLm9wdGlvbnMsIGRvYy5maXJzdCArIGRvYy5zaXplIC0gMSksIGRpc3BsYXkgPSBjbS5kaXNwbGF5O1xuICAgIGlmIChsYXN0Lmxlbmd0aCAhPSBkaXNwbGF5LmxpbmVOdW1DaGFycykge1xuICAgICAgdmFyIHRlc3QgPSBkaXNwbGF5Lm1lYXN1cmUuYXBwZW5kQ2hpbGQoZWx0KFwiZGl2XCIsIFtlbHQoXCJkaXZcIiwgbGFzdCldLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwiQ29kZU1pcnJvci1saW5lbnVtYmVyIENvZGVNaXJyb3ItZ3V0dGVyLWVsdFwiKSk7XG4gICAgICB2YXIgaW5uZXJXID0gdGVzdC5maXJzdENoaWxkLm9mZnNldFdpZHRoLCBwYWRkaW5nID0gdGVzdC5vZmZzZXRXaWR0aCAtIGlubmVyVztcbiAgICAgIGRpc3BsYXkubGluZUd1dHRlci5zdHlsZS53aWR0aCA9IFwiXCI7XG4gICAgICBkaXNwbGF5LmxpbmVOdW1Jbm5lcldpZHRoID0gTWF0aC5tYXgoaW5uZXJXLCBkaXNwbGF5LmxpbmVHdXR0ZXIub2Zmc2V0V2lkdGggLSBwYWRkaW5nKTtcbiAgICAgIGRpc3BsYXkubGluZU51bVdpZHRoID0gZGlzcGxheS5saW5lTnVtSW5uZXJXaWR0aCArIHBhZGRpbmc7XG4gICAgICBkaXNwbGF5LmxpbmVOdW1DaGFycyA9IGRpc3BsYXkubGluZU51bUlubmVyV2lkdGggPyBsYXN0Lmxlbmd0aCA6IC0xO1xuICAgICAgZGlzcGxheS5saW5lR3V0dGVyLnN0eWxlLndpZHRoID0gZGlzcGxheS5saW5lTnVtV2lkdGggKyBcInB4XCI7XG4gICAgICB1cGRhdGVHdXR0ZXJTcGFjZShjbSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgZnVuY3Rpb24gbGluZU51bWJlckZvcihvcHRpb25zLCBpKSB7XG4gICAgcmV0dXJuIFN0cmluZyhvcHRpb25zLmxpbmVOdW1iZXJGb3JtYXR0ZXIoaSArIG9wdGlvbnMuZmlyc3RMaW5lTnVtYmVyKSk7XG4gIH1cblxuICAvLyBDb21wdXRlcyBkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbExlZnQgKyBkaXNwbGF5Lmd1dHRlcnMub2Zmc2V0V2lkdGgsXG4gIC8vIGJ1dCB1c2luZyBnZXRCb3VuZGluZ0NsaWVudFJlY3QgdG8gZ2V0IGEgc3ViLXBpeGVsLWFjY3VyYXRlXG4gIC8vIHJlc3VsdC5cbiAgZnVuY3Rpb24gY29tcGVuc2F0ZUZvckhTY3JvbGwoZGlzcGxheSkge1xuICAgIHJldHVybiBkaXNwbGF5LnNjcm9sbGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQgLSBkaXNwbGF5LnNpemVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLmxlZnQ7XG4gIH1cblxuICAvLyBESVNQTEFZIERSQVdJTkdcblxuICBmdW5jdGlvbiBEaXNwbGF5VXBkYXRlKGNtLCB2aWV3cG9ydCwgZm9yY2UpIHtcbiAgICB2YXIgZGlzcGxheSA9IGNtLmRpc3BsYXk7XG5cbiAgICB0aGlzLnZpZXdwb3J0ID0gdmlld3BvcnQ7XG4gICAgLy8gU3RvcmUgc29tZSB2YWx1ZXMgdGhhdCB3ZSdsbCBuZWVkIGxhdGVyIChidXQgZG9uJ3Qgd2FudCB0byBmb3JjZSBhIHJlbGF5b3V0IGZvcilcbiAgICB0aGlzLnZpc2libGUgPSB2aXNpYmxlTGluZXMoZGlzcGxheSwgY20uZG9jLCB2aWV3cG9ydCk7XG4gICAgdGhpcy5lZGl0b3JJc0hpZGRlbiA9ICFkaXNwbGF5LndyYXBwZXIub2Zmc2V0V2lkdGg7XG4gICAgdGhpcy53cmFwcGVySGVpZ2h0ID0gZGlzcGxheS53cmFwcGVyLmNsaWVudEhlaWdodDtcbiAgICB0aGlzLndyYXBwZXJXaWR0aCA9IGRpc3BsYXkud3JhcHBlci5jbGllbnRXaWR0aDtcbiAgICB0aGlzLm9sZERpc3BsYXlXaWR0aCA9IGRpc3BsYXlXaWR0aChjbSk7XG4gICAgdGhpcy5mb3JjZSA9IGZvcmNlO1xuICAgIHRoaXMuZGltcyA9IGdldERpbWVuc2lvbnMoY20pO1xuICB9XG5cbiAgZnVuY3Rpb24gbWF5YmVDbGlwU2Nyb2xsYmFycyhjbSkge1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheTtcbiAgICBpZiAoIWRpc3BsYXkuc2Nyb2xsYmFyc0NsaXBwZWQgJiYgZGlzcGxheS5zY3JvbGxlci5vZmZzZXRXaWR0aCkge1xuICAgICAgZGlzcGxheS5uYXRpdmVCYXJXaWR0aCA9IGRpc3BsYXkuc2Nyb2xsZXIub2Zmc2V0V2lkdGggLSBkaXNwbGF5LnNjcm9sbGVyLmNsaWVudFdpZHRoO1xuICAgICAgZGlzcGxheS5oZWlnaHRGb3JjZXIuc3R5bGUuaGVpZ2h0ID0gc2Nyb2xsR2FwKGNtKSArIFwicHhcIjtcbiAgICAgIGRpc3BsYXkuc2l6ZXIuc3R5bGUubWFyZ2luQm90dG9tID0gLWRpc3BsYXkubmF0aXZlQmFyV2lkdGggKyBcInB4XCI7XG4gICAgICBkaXNwbGF5LnNpemVyLnN0eWxlLmJvcmRlclJpZ2h0V2lkdGggPSBzY3JvbGxHYXAoY20pICsgXCJweFwiO1xuICAgICAgZGlzcGxheS5zY3JvbGxiYXJzQ2xpcHBlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLy8gRG9lcyB0aGUgYWN0dWFsIHVwZGF0aW5nIG9mIHRoZSBsaW5lIGRpc3BsYXkuIEJhaWxzIG91dFxuICAvLyAocmV0dXJuaW5nIGZhbHNlKSB3aGVuIHRoZXJlIGlzIG5vdGhpbmcgdG8gYmUgZG9uZSBhbmQgZm9yY2VkIGlzXG4gIC8vIGZhbHNlLlxuICBmdW5jdGlvbiB1cGRhdGVEaXNwbGF5SWZOZWVkZWQoY20sIHVwZGF0ZSkge1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheSwgZG9jID0gY20uZG9jO1xuXG4gICAgaWYgKHVwZGF0ZS5lZGl0b3JJc0hpZGRlbikge1xuICAgICAgcmVzZXRWaWV3KGNtKTtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICAvLyBCYWlsIG91dCBpZiB0aGUgdmlzaWJsZSBhcmVhIGlzIGFscmVhZHkgcmVuZGVyZWQgYW5kIG5vdGhpbmcgY2hhbmdlZC5cbiAgICBpZiAoIXVwZGF0ZS5mb3JjZSAmJlxuICAgICAgICB1cGRhdGUudmlzaWJsZS5mcm9tID49IGRpc3BsYXkudmlld0Zyb20gJiYgdXBkYXRlLnZpc2libGUudG8gPD0gZGlzcGxheS52aWV3VG8gJiZcbiAgICAgICAgKGRpc3BsYXkudXBkYXRlTGluZU51bWJlcnMgPT0gbnVsbCB8fCBkaXNwbGF5LnVwZGF0ZUxpbmVOdW1iZXJzID49IGRpc3BsYXkudmlld1RvKSAmJlxuICAgICAgICBkaXNwbGF5LnJlbmRlcmVkVmlldyA9PSBkaXNwbGF5LnZpZXcgJiYgY291bnREaXJ0eVZpZXcoY20pID09IDApXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICBpZiAobWF5YmVVcGRhdGVMaW5lTnVtYmVyV2lkdGgoY20pKSB7XG4gICAgICByZXNldFZpZXcoY20pO1xuICAgICAgdXBkYXRlLmRpbXMgPSBnZXREaW1lbnNpb25zKGNtKTtcbiAgICB9XG5cbiAgICAvLyBDb21wdXRlIGEgc3VpdGFibGUgbmV3IHZpZXdwb3J0IChmcm9tICYgdG8pXG4gICAgdmFyIGVuZCA9IGRvYy5maXJzdCArIGRvYy5zaXplO1xuICAgIHZhciBmcm9tID0gTWF0aC5tYXgodXBkYXRlLnZpc2libGUuZnJvbSAtIGNtLm9wdGlvbnMudmlld3BvcnRNYXJnaW4sIGRvYy5maXJzdCk7XG4gICAgdmFyIHRvID0gTWF0aC5taW4oZW5kLCB1cGRhdGUudmlzaWJsZS50byArIGNtLm9wdGlvbnMudmlld3BvcnRNYXJnaW4pO1xuICAgIGlmIChkaXNwbGF5LnZpZXdGcm9tIDwgZnJvbSAmJiBmcm9tIC0gZGlzcGxheS52aWV3RnJvbSA8IDIwKSBmcm9tID0gTWF0aC5tYXgoZG9jLmZpcnN0LCBkaXNwbGF5LnZpZXdGcm9tKTtcbiAgICBpZiAoZGlzcGxheS52aWV3VG8gPiB0byAmJiBkaXNwbGF5LnZpZXdUbyAtIHRvIDwgMjApIHRvID0gTWF0aC5taW4oZW5kLCBkaXNwbGF5LnZpZXdUbyk7XG4gICAgaWYgKHNhd0NvbGxhcHNlZFNwYW5zKSB7XG4gICAgICBmcm9tID0gdmlzdWFsTGluZU5vKGNtLmRvYywgZnJvbSk7XG4gICAgICB0byA9IHZpc3VhbExpbmVFbmRObyhjbS5kb2MsIHRvKTtcbiAgICB9XG5cbiAgICB2YXIgZGlmZmVyZW50ID0gZnJvbSAhPSBkaXNwbGF5LnZpZXdGcm9tIHx8IHRvICE9IGRpc3BsYXkudmlld1RvIHx8XG4gICAgICBkaXNwbGF5Lmxhc3RXcmFwSGVpZ2h0ICE9IHVwZGF0ZS53cmFwcGVySGVpZ2h0IHx8IGRpc3BsYXkubGFzdFdyYXBXaWR0aCAhPSB1cGRhdGUud3JhcHBlcldpZHRoO1xuICAgIGFkanVzdFZpZXcoY20sIGZyb20sIHRvKTtcblxuICAgIGRpc3BsYXkudmlld09mZnNldCA9IGhlaWdodEF0TGluZShnZXRMaW5lKGNtLmRvYywgZGlzcGxheS52aWV3RnJvbSkpO1xuICAgIC8vIFBvc2l0aW9uIHRoZSBtb3ZlciBkaXYgdG8gYWxpZ24gd2l0aCB0aGUgY3VycmVudCBzY3JvbGwgcG9zaXRpb25cbiAgICBjbS5kaXNwbGF5Lm1vdmVyLnN0eWxlLnRvcCA9IGRpc3BsYXkudmlld09mZnNldCArIFwicHhcIjtcblxuICAgIHZhciB0b1VwZGF0ZSA9IGNvdW50RGlydHlWaWV3KGNtKTtcbiAgICBpZiAoIWRpZmZlcmVudCAmJiB0b1VwZGF0ZSA9PSAwICYmICF1cGRhdGUuZm9yY2UgJiYgZGlzcGxheS5yZW5kZXJlZFZpZXcgPT0gZGlzcGxheS52aWV3ICYmXG4gICAgICAgIChkaXNwbGF5LnVwZGF0ZUxpbmVOdW1iZXJzID09IG51bGwgfHwgZGlzcGxheS51cGRhdGVMaW5lTnVtYmVycyA+PSBkaXNwbGF5LnZpZXdUbykpXG4gICAgICByZXR1cm4gZmFsc2U7XG5cbiAgICAvLyBGb3IgYmlnIGNoYW5nZXMsIHdlIGhpZGUgdGhlIGVuY2xvc2luZyBlbGVtZW50IGR1cmluZyB0aGVcbiAgICAvLyB1cGRhdGUsIHNpbmNlIHRoYXQgc3BlZWRzIHVwIHRoZSBvcGVyYXRpb25zIG9uIG1vc3QgYnJvd3NlcnMuXG4gICAgdmFyIGZvY3VzZWQgPSBhY3RpdmVFbHQoKTtcbiAgICBpZiAodG9VcGRhdGUgPiA0KSBkaXNwbGF5LmxpbmVEaXYuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgIHBhdGNoRGlzcGxheShjbSwgZGlzcGxheS51cGRhdGVMaW5lTnVtYmVycywgdXBkYXRlLmRpbXMpO1xuICAgIGlmICh0b1VwZGF0ZSA+IDQpIGRpc3BsYXkubGluZURpdi5zdHlsZS5kaXNwbGF5ID0gXCJcIjtcbiAgICBkaXNwbGF5LnJlbmRlcmVkVmlldyA9IGRpc3BsYXkudmlldztcbiAgICAvLyBUaGVyZSBtaWdodCBoYXZlIGJlZW4gYSB3aWRnZXQgd2l0aCBhIGZvY3VzZWQgZWxlbWVudCB0aGF0IGdvdFxuICAgIC8vIGhpZGRlbiBvciB1cGRhdGVkLCBpZiBzbyByZS1mb2N1cyBpdC5cbiAgICBpZiAoZm9jdXNlZCAmJiBhY3RpdmVFbHQoKSAhPSBmb2N1c2VkICYmIGZvY3VzZWQub2Zmc2V0SGVpZ2h0KSBmb2N1c2VkLmZvY3VzKCk7XG5cbiAgICAvLyBQcmV2ZW50IHNlbGVjdGlvbiBhbmQgY3Vyc29ycyBmcm9tIGludGVyZmVyaW5nIHdpdGggdGhlIHNjcm9sbFxuICAgIC8vIHdpZHRoIGFuZCBoZWlnaHQuXG4gICAgcmVtb3ZlQ2hpbGRyZW4oZGlzcGxheS5jdXJzb3JEaXYpO1xuICAgIHJlbW92ZUNoaWxkcmVuKGRpc3BsYXkuc2VsZWN0aW9uRGl2KTtcbiAgICBkaXNwbGF5Lmd1dHRlcnMuc3R5bGUuaGVpZ2h0ID0gMDtcblxuICAgIGlmIChkaWZmZXJlbnQpIHtcbiAgICAgIGRpc3BsYXkubGFzdFdyYXBIZWlnaHQgPSB1cGRhdGUud3JhcHBlckhlaWdodDtcbiAgICAgIGRpc3BsYXkubGFzdFdyYXBXaWR0aCA9IHVwZGF0ZS53cmFwcGVyV2lkdGg7XG4gICAgICBzdGFydFdvcmtlcihjbSwgNDAwKTtcbiAgICB9XG5cbiAgICBkaXNwbGF5LnVwZGF0ZUxpbmVOdW1iZXJzID0gbnVsbDtcblxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgZnVuY3Rpb24gcG9zdFVwZGF0ZURpc3BsYXkoY20sIHVwZGF0ZSkge1xuICAgIHZhciBmb3JjZSA9IHVwZGF0ZS5mb3JjZSwgdmlld3BvcnQgPSB1cGRhdGUudmlld3BvcnQ7XG4gICAgZm9yICh2YXIgZmlyc3QgPSB0cnVlOzsgZmlyc3QgPSBmYWxzZSkge1xuICAgICAgaWYgKGZpcnN0ICYmIGNtLm9wdGlvbnMubGluZVdyYXBwaW5nICYmIHVwZGF0ZS5vbGREaXNwbGF5V2lkdGggIT0gZGlzcGxheVdpZHRoKGNtKSkge1xuICAgICAgICBmb3JjZSA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmb3JjZSA9IGZhbHNlO1xuICAgICAgICAvLyBDbGlwIGZvcmNlZCB2aWV3cG9ydCB0byBhY3R1YWwgc2Nyb2xsYWJsZSBhcmVhLlxuICAgICAgICBpZiAodmlld3BvcnQgJiYgdmlld3BvcnQudG9wICE9IG51bGwpXG4gICAgICAgICAgdmlld3BvcnQgPSB7dG9wOiBNYXRoLm1pbihjbS5kb2MuaGVpZ2h0ICsgcGFkZGluZ1ZlcnQoY20uZGlzcGxheSkgLSBkaXNwbGF5SGVpZ2h0KGNtKSwgdmlld3BvcnQudG9wKX07XG4gICAgICAgIC8vIFVwZGF0ZWQgbGluZSBoZWlnaHRzIG1pZ2h0IHJlc3VsdCBpbiB0aGUgZHJhd24gYXJlYSBub3RcbiAgICAgICAgLy8gYWN0dWFsbHkgY292ZXJpbmcgdGhlIHZpZXdwb3J0LiBLZWVwIGxvb3BpbmcgdW50aWwgaXQgZG9lcy5cbiAgICAgICAgdXBkYXRlLnZpc2libGUgPSB2aXNpYmxlTGluZXMoY20uZGlzcGxheSwgY20uZG9jLCB2aWV3cG9ydCk7XG4gICAgICAgIGlmICh1cGRhdGUudmlzaWJsZS5mcm9tID49IGNtLmRpc3BsYXkudmlld0Zyb20gJiYgdXBkYXRlLnZpc2libGUudG8gPD0gY20uZGlzcGxheS52aWV3VG8pXG4gICAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoIXVwZGF0ZURpc3BsYXlJZk5lZWRlZChjbSwgdXBkYXRlKSkgYnJlYWs7XG4gICAgICB1cGRhdGVIZWlnaHRzSW5WaWV3cG9ydChjbSk7XG4gICAgICB2YXIgYmFyTWVhc3VyZSA9IG1lYXN1cmVGb3JTY3JvbGxiYXJzKGNtKTtcbiAgICAgIHVwZGF0ZVNlbGVjdGlvbihjbSk7XG4gICAgICBzZXREb2N1bWVudEhlaWdodChjbSwgYmFyTWVhc3VyZSk7XG4gICAgICB1cGRhdGVTY3JvbGxiYXJzKGNtLCBiYXJNZWFzdXJlKTtcbiAgICB9XG5cbiAgICBzaWduYWxMYXRlcihjbSwgXCJ1cGRhdGVcIiwgY20pO1xuICAgIGlmIChjbS5kaXNwbGF5LnZpZXdGcm9tICE9IGNtLmRpc3BsYXkucmVwb3J0ZWRWaWV3RnJvbSB8fCBjbS5kaXNwbGF5LnZpZXdUbyAhPSBjbS5kaXNwbGF5LnJlcG9ydGVkVmlld1RvKSB7XG4gICAgICBzaWduYWxMYXRlcihjbSwgXCJ2aWV3cG9ydENoYW5nZVwiLCBjbSwgY20uZGlzcGxheS52aWV3RnJvbSwgY20uZGlzcGxheS52aWV3VG8pO1xuICAgICAgY20uZGlzcGxheS5yZXBvcnRlZFZpZXdGcm9tID0gY20uZGlzcGxheS52aWV3RnJvbTsgY20uZGlzcGxheS5yZXBvcnRlZFZpZXdUbyA9IGNtLmRpc3BsYXkudmlld1RvO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZURpc3BsYXlTaW1wbGUoY20sIHZpZXdwb3J0KSB7XG4gICAgdmFyIHVwZGF0ZSA9IG5ldyBEaXNwbGF5VXBkYXRlKGNtLCB2aWV3cG9ydCk7XG4gICAgaWYgKHVwZGF0ZURpc3BsYXlJZk5lZWRlZChjbSwgdXBkYXRlKSkge1xuICAgICAgdXBkYXRlSGVpZ2h0c0luVmlld3BvcnQoY20pO1xuICAgICAgcG9zdFVwZGF0ZURpc3BsYXkoY20sIHVwZGF0ZSk7XG4gICAgICB2YXIgYmFyTWVhc3VyZSA9IG1lYXN1cmVGb3JTY3JvbGxiYXJzKGNtKTtcbiAgICAgIHVwZGF0ZVNlbGVjdGlvbihjbSk7XG4gICAgICBzZXREb2N1bWVudEhlaWdodChjbSwgYmFyTWVhc3VyZSk7XG4gICAgICB1cGRhdGVTY3JvbGxiYXJzKGNtLCBiYXJNZWFzdXJlKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBzZXREb2N1bWVudEhlaWdodChjbSwgbWVhc3VyZSkge1xuICAgIGNtLmRpc3BsYXkuc2l6ZXIuc3R5bGUubWluSGVpZ2h0ID0gbWVhc3VyZS5kb2NIZWlnaHQgKyBcInB4XCI7XG4gICAgdmFyIHRvdGFsID0gbWVhc3VyZS5kb2NIZWlnaHQgKyBjbS5kaXNwbGF5LmJhckhlaWdodDtcbiAgICBjbS5kaXNwbGF5LmhlaWdodEZvcmNlci5zdHlsZS50b3AgPSB0b3RhbCArIFwicHhcIjtcbiAgICBjbS5kaXNwbGF5Lmd1dHRlcnMuc3R5bGUuaGVpZ2h0ID0gTWF0aC5tYXgodG90YWwgKyBzY3JvbGxHYXAoY20pLCBtZWFzdXJlLmNsaWVudEhlaWdodCkgKyBcInB4XCI7XG4gIH1cblxuICAvLyBSZWFkIHRoZSBhY3R1YWwgaGVpZ2h0cyBvZiB0aGUgcmVuZGVyZWQgbGluZXMsIGFuZCB1cGRhdGUgdGhlaXJcbiAgLy8gc3RvcmVkIGhlaWdodHMgdG8gbWF0Y2guXG4gIGZ1bmN0aW9uIHVwZGF0ZUhlaWdodHNJblZpZXdwb3J0KGNtKSB7XG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5O1xuICAgIHZhciBwcmV2Qm90dG9tID0gZGlzcGxheS5saW5lRGl2Lm9mZnNldFRvcDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRpc3BsYXkudmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGN1ciA9IGRpc3BsYXkudmlld1tpXSwgaGVpZ2h0O1xuICAgICAgaWYgKGN1ci5oaWRkZW4pIGNvbnRpbnVlO1xuICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCA4KSB7XG4gICAgICAgIHZhciBib3QgPSBjdXIubm9kZS5vZmZzZXRUb3AgKyBjdXIubm9kZS5vZmZzZXRIZWlnaHQ7XG4gICAgICAgIGhlaWdodCA9IGJvdCAtIHByZXZCb3R0b207XG4gICAgICAgIHByZXZCb3R0b20gPSBib3Q7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgYm94ID0gY3VyLm5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIGhlaWdodCA9IGJveC5ib3R0b20gLSBib3gudG9wO1xuICAgICAgfVxuICAgICAgdmFyIGRpZmYgPSBjdXIubGluZS5oZWlnaHQgLSBoZWlnaHQ7XG4gICAgICBpZiAoaGVpZ2h0IDwgMikgaGVpZ2h0ID0gdGV4dEhlaWdodChkaXNwbGF5KTtcbiAgICAgIGlmIChkaWZmID4gLjAwMSB8fCBkaWZmIDwgLS4wMDEpIHtcbiAgICAgICAgdXBkYXRlTGluZUhlaWdodChjdXIubGluZSwgaGVpZ2h0KTtcbiAgICAgICAgdXBkYXRlV2lkZ2V0SGVpZ2h0KGN1ci5saW5lKTtcbiAgICAgICAgaWYgKGN1ci5yZXN0KSBmb3IgKHZhciBqID0gMDsgaiA8IGN1ci5yZXN0Lmxlbmd0aDsgaisrKVxuICAgICAgICAgIHVwZGF0ZVdpZGdldEhlaWdodChjdXIucmVzdFtqXSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gUmVhZCBhbmQgc3RvcmUgdGhlIGhlaWdodCBvZiBsaW5lIHdpZGdldHMgYXNzb2NpYXRlZCB3aXRoIHRoZVxuICAvLyBnaXZlbiBsaW5lLlxuICBmdW5jdGlvbiB1cGRhdGVXaWRnZXRIZWlnaHQobGluZSkge1xuICAgIGlmIChsaW5lLndpZGdldHMpIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZS53aWRnZXRzLmxlbmd0aDsgKytpKVxuICAgICAgbGluZS53aWRnZXRzW2ldLmhlaWdodCA9IGxpbmUud2lkZ2V0c1tpXS5ub2RlLm9mZnNldEhlaWdodDtcbiAgfVxuXG4gIC8vIERvIGEgYnVsay1yZWFkIG9mIHRoZSBET00gcG9zaXRpb25zIGFuZCBzaXplcyBuZWVkZWQgdG8gZHJhdyB0aGVcbiAgLy8gdmlldywgc28gdGhhdCB3ZSBkb24ndCBpbnRlcmxlYXZlIHJlYWRpbmcgYW5kIHdyaXRpbmcgdG8gdGhlIERPTS5cbiAgZnVuY3Rpb24gZ2V0RGltZW5zaW9ucyhjbSkge1xuICAgIHZhciBkID0gY20uZGlzcGxheSwgbGVmdCA9IHt9LCB3aWR0aCA9IHt9O1xuICAgIHZhciBndXR0ZXJMZWZ0ID0gZC5ndXR0ZXJzLmNsaWVudExlZnQ7XG4gICAgZm9yICh2YXIgbiA9IGQuZ3V0dGVycy5maXJzdENoaWxkLCBpID0gMDsgbjsgbiA9IG4ubmV4dFNpYmxpbmcsICsraSkge1xuICAgICAgbGVmdFtjbS5vcHRpb25zLmd1dHRlcnNbaV1dID0gbi5vZmZzZXRMZWZ0ICsgbi5jbGllbnRMZWZ0ICsgZ3V0dGVyTGVmdDtcbiAgICAgIHdpZHRoW2NtLm9wdGlvbnMuZ3V0dGVyc1tpXV0gPSBuLmNsaWVudFdpZHRoO1xuICAgIH1cbiAgICByZXR1cm4ge2ZpeGVkUG9zOiBjb21wZW5zYXRlRm9ySFNjcm9sbChkKSxcbiAgICAgICAgICAgIGd1dHRlclRvdGFsV2lkdGg6IGQuZ3V0dGVycy5vZmZzZXRXaWR0aCxcbiAgICAgICAgICAgIGd1dHRlckxlZnQ6IGxlZnQsXG4gICAgICAgICAgICBndXR0ZXJXaWR0aDogd2lkdGgsXG4gICAgICAgICAgICB3cmFwcGVyV2lkdGg6IGQud3JhcHBlci5jbGllbnRXaWR0aH07XG4gIH1cblxuICAvLyBTeW5jIHRoZSBhY3R1YWwgZGlzcGxheSBET00gc3RydWN0dXJlIHdpdGggZGlzcGxheS52aWV3LCByZW1vdmluZ1xuICAvLyBub2RlcyBmb3IgbGluZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHZpZXcsIGFuZCBjcmVhdGluZyB0aGUgb25lc1xuICAvLyB0aGF0IGFyZSBub3QgdGhlcmUgeWV0LCBhbmQgdXBkYXRpbmcgdGhlIG9uZXMgdGhhdCBhcmUgb3V0IG9mXG4gIC8vIGRhdGUuXG4gIGZ1bmN0aW9uIHBhdGNoRGlzcGxheShjbSwgdXBkYXRlTnVtYmVyc0Zyb20sIGRpbXMpIHtcbiAgICB2YXIgZGlzcGxheSA9IGNtLmRpc3BsYXksIGxpbmVOdW1iZXJzID0gY20ub3B0aW9ucy5saW5lTnVtYmVycztcbiAgICB2YXIgY29udGFpbmVyID0gZGlzcGxheS5saW5lRGl2LCBjdXIgPSBjb250YWluZXIuZmlyc3RDaGlsZDtcblxuICAgIGZ1bmN0aW9uIHJtKG5vZGUpIHtcbiAgICAgIHZhciBuZXh0ID0gbm9kZS5uZXh0U2libGluZztcbiAgICAgIC8vIFdvcmtzIGFyb3VuZCBhIHRocm93LXNjcm9sbCBidWcgaW4gT1MgWCBXZWJraXRcbiAgICAgIGlmICh3ZWJraXQgJiYgbWFjICYmIGNtLmRpc3BsYXkuY3VycmVudFdoZWVsVGFyZ2V0ID09IG5vZGUpXG4gICAgICAgIG5vZGUuc3R5bGUuZGlzcGxheSA9IFwibm9uZVwiO1xuICAgICAgZWxzZVxuICAgICAgICBub2RlLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQobm9kZSk7XG4gICAgICByZXR1cm4gbmV4dDtcbiAgICB9XG5cbiAgICB2YXIgdmlldyA9IGRpc3BsYXkudmlldywgbGluZU4gPSBkaXNwbGF5LnZpZXdGcm9tO1xuICAgIC8vIExvb3Agb3ZlciB0aGUgZWxlbWVudHMgaW4gdGhlIHZpZXcsIHN5bmNpbmcgY3VyICh0aGUgRE9NIG5vZGVzXG4gICAgLy8gaW4gZGlzcGxheS5saW5lRGl2KSB3aXRoIHRoZSB2aWV3IGFzIHdlIGdvLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIGxpbmVWaWV3ID0gdmlld1tpXTtcbiAgICAgIGlmIChsaW5lVmlldy5oaWRkZW4pIHtcbiAgICAgIH0gZWxzZSBpZiAoIWxpbmVWaWV3Lm5vZGUpIHsgLy8gTm90IGRyYXduIHlldFxuICAgICAgICB2YXIgbm9kZSA9IGJ1aWxkTGluZUVsZW1lbnQoY20sIGxpbmVWaWV3LCBsaW5lTiwgZGltcyk7XG4gICAgICAgIGNvbnRhaW5lci5pbnNlcnRCZWZvcmUobm9kZSwgY3VyKTtcbiAgICAgIH0gZWxzZSB7IC8vIEFscmVhZHkgZHJhd25cbiAgICAgICAgd2hpbGUgKGN1ciAhPSBsaW5lVmlldy5ub2RlKSBjdXIgPSBybShjdXIpO1xuICAgICAgICB2YXIgdXBkYXRlTnVtYmVyID0gbGluZU51bWJlcnMgJiYgdXBkYXRlTnVtYmVyc0Zyb20gIT0gbnVsbCAmJlxuICAgICAgICAgIHVwZGF0ZU51bWJlcnNGcm9tIDw9IGxpbmVOICYmIGxpbmVWaWV3LmxpbmVOdW1iZXI7XG4gICAgICAgIGlmIChsaW5lVmlldy5jaGFuZ2VzKSB7XG4gICAgICAgICAgaWYgKGluZGV4T2YobGluZVZpZXcuY2hhbmdlcywgXCJndXR0ZXJcIikgPiAtMSkgdXBkYXRlTnVtYmVyID0gZmFsc2U7XG4gICAgICAgICAgdXBkYXRlTGluZUZvckNoYW5nZXMoY20sIGxpbmVWaWV3LCBsaW5lTiwgZGltcyk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHVwZGF0ZU51bWJlcikge1xuICAgICAgICAgIHJlbW92ZUNoaWxkcmVuKGxpbmVWaWV3LmxpbmVOdW1iZXIpO1xuICAgICAgICAgIGxpbmVWaWV3LmxpbmVOdW1iZXIuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUobGluZU51bWJlckZvcihjbS5vcHRpb25zLCBsaW5lTikpKTtcbiAgICAgICAgfVxuICAgICAgICBjdXIgPSBsaW5lVmlldy5ub2RlLm5leHRTaWJsaW5nO1xuICAgICAgfVxuICAgICAgbGluZU4gKz0gbGluZVZpZXcuc2l6ZTtcbiAgICB9XG4gICAgd2hpbGUgKGN1cikgY3VyID0gcm0oY3VyKTtcbiAgfVxuXG4gIC8vIFdoZW4gYW4gYXNwZWN0IG9mIGEgbGluZSBjaGFuZ2VzLCBhIHN0cmluZyBpcyBhZGRlZCB0b1xuICAvLyBsaW5lVmlldy5jaGFuZ2VzLiBUaGlzIHVwZGF0ZXMgdGhlIHJlbGV2YW50IHBhcnQgb2YgdGhlIGxpbmUnc1xuICAvLyBET00gc3RydWN0dXJlLlxuICBmdW5jdGlvbiB1cGRhdGVMaW5lRm9yQ2hhbmdlcyhjbSwgbGluZVZpZXcsIGxpbmVOLCBkaW1zKSB7XG4gICAgZm9yICh2YXIgaiA9IDA7IGogPCBsaW5lVmlldy5jaGFuZ2VzLmxlbmd0aDsgaisrKSB7XG4gICAgICB2YXIgdHlwZSA9IGxpbmVWaWV3LmNoYW5nZXNbal07XG4gICAgICBpZiAodHlwZSA9PSBcInRleHRcIikgdXBkYXRlTGluZVRleHQoY20sIGxpbmVWaWV3KTtcbiAgICAgIGVsc2UgaWYgKHR5cGUgPT0gXCJndXR0ZXJcIikgdXBkYXRlTGluZUd1dHRlcihjbSwgbGluZVZpZXcsIGxpbmVOLCBkaW1zKTtcbiAgICAgIGVsc2UgaWYgKHR5cGUgPT0gXCJjbGFzc1wiKSB1cGRhdGVMaW5lQ2xhc3NlcyhsaW5lVmlldyk7XG4gICAgICBlbHNlIGlmICh0eXBlID09IFwid2lkZ2V0XCIpIHVwZGF0ZUxpbmVXaWRnZXRzKGxpbmVWaWV3LCBkaW1zKTtcbiAgICB9XG4gICAgbGluZVZpZXcuY2hhbmdlcyA9IG51bGw7XG4gIH1cblxuICAvLyBMaW5lcyB3aXRoIGd1dHRlciBlbGVtZW50cywgd2lkZ2V0cyBvciBhIGJhY2tncm91bmQgY2xhc3MgbmVlZCB0b1xuICAvLyBiZSB3cmFwcGVkLCBhbmQgaGF2ZSB0aGUgZXh0cmEgZWxlbWVudHMgYWRkZWQgdG8gdGhlIHdyYXBwZXIgZGl2XG4gIGZ1bmN0aW9uIGVuc3VyZUxpbmVXcmFwcGVkKGxpbmVWaWV3KSB7XG4gICAgaWYgKGxpbmVWaWV3Lm5vZGUgPT0gbGluZVZpZXcudGV4dCkge1xuICAgICAgbGluZVZpZXcubm9kZSA9IGVsdChcImRpdlwiLCBudWxsLCBudWxsLCBcInBvc2l0aW9uOiByZWxhdGl2ZVwiKTtcbiAgICAgIGlmIChsaW5lVmlldy50ZXh0LnBhcmVudE5vZGUpXG4gICAgICAgIGxpbmVWaWV3LnRleHQucGFyZW50Tm9kZS5yZXBsYWNlQ2hpbGQobGluZVZpZXcubm9kZSwgbGluZVZpZXcudGV4dCk7XG4gICAgICBsaW5lVmlldy5ub2RlLmFwcGVuZENoaWxkKGxpbmVWaWV3LnRleHQpO1xuICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCA4KSBsaW5lVmlldy5ub2RlLnN0eWxlLnpJbmRleCA9IDI7XG4gICAgfVxuICAgIHJldHVybiBsaW5lVmlldy5ub2RlO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTGluZUJhY2tncm91bmQobGluZVZpZXcpIHtcbiAgICB2YXIgY2xzID0gbGluZVZpZXcuYmdDbGFzcyA/IGxpbmVWaWV3LmJnQ2xhc3MgKyBcIiBcIiArIChsaW5lVmlldy5saW5lLmJnQ2xhc3MgfHwgXCJcIikgOiBsaW5lVmlldy5saW5lLmJnQ2xhc3M7XG4gICAgaWYgKGNscykgY2xzICs9IFwiIENvZGVNaXJyb3ItbGluZWJhY2tncm91bmRcIjtcbiAgICBpZiAobGluZVZpZXcuYmFja2dyb3VuZCkge1xuICAgICAgaWYgKGNscykgbGluZVZpZXcuYmFja2dyb3VuZC5jbGFzc05hbWUgPSBjbHM7XG4gICAgICBlbHNlIHsgbGluZVZpZXcuYmFja2dyb3VuZC5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGxpbmVWaWV3LmJhY2tncm91bmQpOyBsaW5lVmlldy5iYWNrZ3JvdW5kID0gbnVsbDsgfVxuICAgIH0gZWxzZSBpZiAoY2xzKSB7XG4gICAgICB2YXIgd3JhcCA9IGVuc3VyZUxpbmVXcmFwcGVkKGxpbmVWaWV3KTtcbiAgICAgIGxpbmVWaWV3LmJhY2tncm91bmQgPSB3cmFwLmluc2VydEJlZm9yZShlbHQoXCJkaXZcIiwgbnVsbCwgY2xzKSwgd3JhcC5maXJzdENoaWxkKTtcbiAgICB9XG4gIH1cblxuICAvLyBXcmFwcGVyIGFyb3VuZCBidWlsZExpbmVDb250ZW50IHdoaWNoIHdpbGwgcmV1c2UgdGhlIHN0cnVjdHVyZVxuICAvLyBpbiBkaXNwbGF5LmV4dGVybmFsTWVhc3VyZWQgd2hlbiBwb3NzaWJsZS5cbiAgZnVuY3Rpb24gZ2V0TGluZUNvbnRlbnQoY20sIGxpbmVWaWV3KSB7XG4gICAgdmFyIGV4dCA9IGNtLmRpc3BsYXkuZXh0ZXJuYWxNZWFzdXJlZDtcbiAgICBpZiAoZXh0ICYmIGV4dC5saW5lID09IGxpbmVWaWV3LmxpbmUpIHtcbiAgICAgIGNtLmRpc3BsYXkuZXh0ZXJuYWxNZWFzdXJlZCA9IG51bGw7XG4gICAgICBsaW5lVmlldy5tZWFzdXJlID0gZXh0Lm1lYXN1cmU7XG4gICAgICByZXR1cm4gZXh0LmJ1aWx0O1xuICAgIH1cbiAgICByZXR1cm4gYnVpbGRMaW5lQ29udGVudChjbSwgbGluZVZpZXcpO1xuICB9XG5cbiAgLy8gUmVkcmF3IHRoZSBsaW5lJ3MgdGV4dC4gSW50ZXJhY3RzIHdpdGggdGhlIGJhY2tncm91bmQgYW5kIHRleHRcbiAgLy8gY2xhc3NlcyBiZWNhdXNlIHRoZSBtb2RlIG1heSBvdXRwdXQgdG9rZW5zIHRoYXQgaW5mbHVlbmNlIHRoZXNlXG4gIC8vIGNsYXNzZXMuXG4gIGZ1bmN0aW9uIHVwZGF0ZUxpbmVUZXh0KGNtLCBsaW5lVmlldykge1xuICAgIHZhciBjbHMgPSBsaW5lVmlldy50ZXh0LmNsYXNzTmFtZTtcbiAgICB2YXIgYnVpbHQgPSBnZXRMaW5lQ29udGVudChjbSwgbGluZVZpZXcpO1xuICAgIGlmIChsaW5lVmlldy50ZXh0ID09IGxpbmVWaWV3Lm5vZGUpIGxpbmVWaWV3Lm5vZGUgPSBidWlsdC5wcmU7XG4gICAgbGluZVZpZXcudGV4dC5wYXJlbnROb2RlLnJlcGxhY2VDaGlsZChidWlsdC5wcmUsIGxpbmVWaWV3LnRleHQpO1xuICAgIGxpbmVWaWV3LnRleHQgPSBidWlsdC5wcmU7XG4gICAgaWYgKGJ1aWx0LmJnQ2xhc3MgIT0gbGluZVZpZXcuYmdDbGFzcyB8fCBidWlsdC50ZXh0Q2xhc3MgIT0gbGluZVZpZXcudGV4dENsYXNzKSB7XG4gICAgICBsaW5lVmlldy5iZ0NsYXNzID0gYnVpbHQuYmdDbGFzcztcbiAgICAgIGxpbmVWaWV3LnRleHRDbGFzcyA9IGJ1aWx0LnRleHRDbGFzcztcbiAgICAgIHVwZGF0ZUxpbmVDbGFzc2VzKGxpbmVWaWV3KTtcbiAgICB9IGVsc2UgaWYgKGNscykge1xuICAgICAgbGluZVZpZXcudGV4dC5jbGFzc05hbWUgPSBjbHM7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTGluZUNsYXNzZXMobGluZVZpZXcpIHtcbiAgICB1cGRhdGVMaW5lQmFja2dyb3VuZChsaW5lVmlldyk7XG4gICAgaWYgKGxpbmVWaWV3LmxpbmUud3JhcENsYXNzKVxuICAgICAgZW5zdXJlTGluZVdyYXBwZWQobGluZVZpZXcpLmNsYXNzTmFtZSA9IGxpbmVWaWV3LmxpbmUud3JhcENsYXNzO1xuICAgIGVsc2UgaWYgKGxpbmVWaWV3Lm5vZGUgIT0gbGluZVZpZXcudGV4dClcbiAgICAgIGxpbmVWaWV3Lm5vZGUuY2xhc3NOYW1lID0gXCJcIjtcbiAgICB2YXIgdGV4dENsYXNzID0gbGluZVZpZXcudGV4dENsYXNzID8gbGluZVZpZXcudGV4dENsYXNzICsgXCIgXCIgKyAobGluZVZpZXcubGluZS50ZXh0Q2xhc3MgfHwgXCJcIikgOiBsaW5lVmlldy5saW5lLnRleHRDbGFzcztcbiAgICBsaW5lVmlldy50ZXh0LmNsYXNzTmFtZSA9IHRleHRDbGFzcyB8fCBcIlwiO1xuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTGluZUd1dHRlcihjbSwgbGluZVZpZXcsIGxpbmVOLCBkaW1zKSB7XG4gICAgaWYgKGxpbmVWaWV3Lmd1dHRlcikge1xuICAgICAgbGluZVZpZXcubm9kZS5yZW1vdmVDaGlsZChsaW5lVmlldy5ndXR0ZXIpO1xuICAgICAgbGluZVZpZXcuZ3V0dGVyID0gbnVsbDtcbiAgICB9XG4gICAgdmFyIG1hcmtlcnMgPSBsaW5lVmlldy5saW5lLmd1dHRlck1hcmtlcnM7XG4gICAgaWYgKGNtLm9wdGlvbnMubGluZU51bWJlcnMgfHwgbWFya2Vycykge1xuICAgICAgdmFyIHdyYXAgPSBlbnN1cmVMaW5lV3JhcHBlZChsaW5lVmlldyk7XG4gICAgICB2YXIgZ3V0dGVyV3JhcCA9IGxpbmVWaWV3Lmd1dHRlciA9XG4gICAgICAgIHdyYXAuaW5zZXJ0QmVmb3JlKGVsdChcImRpdlwiLCBudWxsLCBcIkNvZGVNaXJyb3ItZ3V0dGVyLXdyYXBwZXJcIiwgXCJsZWZ0OiBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY20ub3B0aW9ucy5maXhlZEd1dHRlciA/IGRpbXMuZml4ZWRQb3MgOiAtZGltcy5ndXR0ZXJUb3RhbFdpZHRoKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcInB4OyB3aWR0aDogXCIgKyBkaW1zLmd1dHRlclRvdGFsV2lkdGggKyBcInB4XCIpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBsaW5lVmlldy50ZXh0KTtcbiAgICAgIGlmIChsaW5lVmlldy5saW5lLmd1dHRlckNsYXNzKVxuICAgICAgICBndXR0ZXJXcmFwLmNsYXNzTmFtZSArPSBcIiBcIiArIGxpbmVWaWV3LmxpbmUuZ3V0dGVyQ2xhc3M7XG4gICAgICBpZiAoY20ub3B0aW9ucy5saW5lTnVtYmVycyAmJiAoIW1hcmtlcnMgfHwgIW1hcmtlcnNbXCJDb2RlTWlycm9yLWxpbmVudW1iZXJzXCJdKSlcbiAgICAgICAgbGluZVZpZXcubGluZU51bWJlciA9IGd1dHRlcldyYXAuYXBwZW5kQ2hpbGQoXG4gICAgICAgICAgZWx0KFwiZGl2XCIsIGxpbmVOdW1iZXJGb3IoY20ub3B0aW9ucywgbGluZU4pLFxuICAgICAgICAgICAgICBcIkNvZGVNaXJyb3ItbGluZW51bWJlciBDb2RlTWlycm9yLWd1dHRlci1lbHRcIixcbiAgICAgICAgICAgICAgXCJsZWZ0OiBcIiArIGRpbXMuZ3V0dGVyTGVmdFtcIkNvZGVNaXJyb3ItbGluZW51bWJlcnNcIl0gKyBcInB4OyB3aWR0aDogXCJcbiAgICAgICAgICAgICAgKyBjbS5kaXNwbGF5LmxpbmVOdW1Jbm5lcldpZHRoICsgXCJweFwiKSk7XG4gICAgICBpZiAobWFya2VycykgZm9yICh2YXIgayA9IDA7IGsgPCBjbS5vcHRpb25zLmd1dHRlcnMubGVuZ3RoOyArK2spIHtcbiAgICAgICAgdmFyIGlkID0gY20ub3B0aW9ucy5ndXR0ZXJzW2tdLCBmb3VuZCA9IG1hcmtlcnMuaGFzT3duUHJvcGVydHkoaWQpICYmIG1hcmtlcnNbaWRdO1xuICAgICAgICBpZiAoZm91bmQpXG4gICAgICAgICAgZ3V0dGVyV3JhcC5hcHBlbmRDaGlsZChlbHQoXCJkaXZcIiwgW2ZvdW5kXSwgXCJDb2RlTWlycm9yLWd1dHRlci1lbHRcIiwgXCJsZWZ0OiBcIiArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGltcy5ndXR0ZXJMZWZ0W2lkXSArIFwicHg7IHdpZHRoOiBcIiArIGRpbXMuZ3V0dGVyV2lkdGhbaWRdICsgXCJweFwiKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlTGluZVdpZGdldHMobGluZVZpZXcsIGRpbXMpIHtcbiAgICBpZiAobGluZVZpZXcuYWxpZ25hYmxlKSBsaW5lVmlldy5hbGlnbmFibGUgPSBudWxsO1xuICAgIGZvciAodmFyIG5vZGUgPSBsaW5lVmlldy5ub2RlLmZpcnN0Q2hpbGQsIG5leHQ7IG5vZGU7IG5vZGUgPSBuZXh0KSB7XG4gICAgICB2YXIgbmV4dCA9IG5vZGUubmV4dFNpYmxpbmc7XG4gICAgICBpZiAobm9kZS5jbGFzc05hbWUgPT0gXCJDb2RlTWlycm9yLWxpbmV3aWRnZXRcIilcbiAgICAgICAgbGluZVZpZXcubm9kZS5yZW1vdmVDaGlsZChub2RlKTtcbiAgICB9XG4gICAgaW5zZXJ0TGluZVdpZGdldHMobGluZVZpZXcsIGRpbXMpO1xuICB9XG5cbiAgLy8gQnVpbGQgYSBsaW5lJ3MgRE9NIHJlcHJlc2VudGF0aW9uIGZyb20gc2NyYXRjaFxuICBmdW5jdGlvbiBidWlsZExpbmVFbGVtZW50KGNtLCBsaW5lVmlldywgbGluZU4sIGRpbXMpIHtcbiAgICB2YXIgYnVpbHQgPSBnZXRMaW5lQ29udGVudChjbSwgbGluZVZpZXcpO1xuICAgIGxpbmVWaWV3LnRleHQgPSBsaW5lVmlldy5ub2RlID0gYnVpbHQucHJlO1xuICAgIGlmIChidWlsdC5iZ0NsYXNzKSBsaW5lVmlldy5iZ0NsYXNzID0gYnVpbHQuYmdDbGFzcztcbiAgICBpZiAoYnVpbHQudGV4dENsYXNzKSBsaW5lVmlldy50ZXh0Q2xhc3MgPSBidWlsdC50ZXh0Q2xhc3M7XG5cbiAgICB1cGRhdGVMaW5lQ2xhc3NlcyhsaW5lVmlldyk7XG4gICAgdXBkYXRlTGluZUd1dHRlcihjbSwgbGluZVZpZXcsIGxpbmVOLCBkaW1zKTtcbiAgICBpbnNlcnRMaW5lV2lkZ2V0cyhsaW5lVmlldywgZGltcyk7XG4gICAgcmV0dXJuIGxpbmVWaWV3Lm5vZGU7XG4gIH1cblxuICAvLyBBIGxpbmVWaWV3IG1heSBjb250YWluIG11bHRpcGxlIGxvZ2ljYWwgbGluZXMgKHdoZW4gbWVyZ2VkIGJ5XG4gIC8vIGNvbGxhcHNlZCBzcGFucykuIFRoZSB3aWRnZXRzIGZvciBhbGwgb2YgdGhlbSBuZWVkIHRvIGJlIGRyYXduLlxuICBmdW5jdGlvbiBpbnNlcnRMaW5lV2lkZ2V0cyhsaW5lVmlldywgZGltcykge1xuICAgIGluc2VydExpbmVXaWRnZXRzRm9yKGxpbmVWaWV3LmxpbmUsIGxpbmVWaWV3LCBkaW1zLCB0cnVlKTtcbiAgICBpZiAobGluZVZpZXcucmVzdCkgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lVmlldy5yZXN0Lmxlbmd0aDsgaSsrKVxuICAgICAgaW5zZXJ0TGluZVdpZGdldHNGb3IobGluZVZpZXcucmVzdFtpXSwgbGluZVZpZXcsIGRpbXMsIGZhbHNlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluc2VydExpbmVXaWRnZXRzRm9yKGxpbmUsIGxpbmVWaWV3LCBkaW1zLCBhbGxvd0Fib3ZlKSB7XG4gICAgaWYgKCFsaW5lLndpZGdldHMpIHJldHVybjtcbiAgICB2YXIgd3JhcCA9IGVuc3VyZUxpbmVXcmFwcGVkKGxpbmVWaWV3KTtcbiAgICBmb3IgKHZhciBpID0gMCwgd3MgPSBsaW5lLndpZGdldHM7IGkgPCB3cy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIHdpZGdldCA9IHdzW2ldLCBub2RlID0gZWx0KFwiZGl2XCIsIFt3aWRnZXQubm9kZV0sIFwiQ29kZU1pcnJvci1saW5ld2lkZ2V0XCIpO1xuICAgICAgaWYgKCF3aWRnZXQuaGFuZGxlTW91c2VFdmVudHMpIG5vZGUuc2V0QXR0cmlidXRlKFwiY20taWdub3JlLWV2ZW50c1wiLCBcInRydWVcIik7XG4gICAgICBwb3NpdGlvbkxpbmVXaWRnZXQod2lkZ2V0LCBub2RlLCBsaW5lVmlldywgZGltcyk7XG4gICAgICBpZiAoYWxsb3dBYm92ZSAmJiB3aWRnZXQuYWJvdmUpXG4gICAgICAgIHdyYXAuaW5zZXJ0QmVmb3JlKG5vZGUsIGxpbmVWaWV3Lmd1dHRlciB8fCBsaW5lVmlldy50ZXh0KTtcbiAgICAgIGVsc2VcbiAgICAgICAgd3JhcC5hcHBlbmRDaGlsZChub2RlKTtcbiAgICAgIHNpZ25hbExhdGVyKHdpZGdldCwgXCJyZWRyYXdcIik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcG9zaXRpb25MaW5lV2lkZ2V0KHdpZGdldCwgbm9kZSwgbGluZVZpZXcsIGRpbXMpIHtcbiAgICBpZiAod2lkZ2V0Lm5vSFNjcm9sbCkge1xuICAgICAgKGxpbmVWaWV3LmFsaWduYWJsZSB8fCAobGluZVZpZXcuYWxpZ25hYmxlID0gW10pKS5wdXNoKG5vZGUpO1xuICAgICAgdmFyIHdpZHRoID0gZGltcy53cmFwcGVyV2lkdGg7XG4gICAgICBub2RlLnN0eWxlLmxlZnQgPSBkaW1zLmZpeGVkUG9zICsgXCJweFwiO1xuICAgICAgaWYgKCF3aWRnZXQuY292ZXJHdXR0ZXIpIHtcbiAgICAgICAgd2lkdGggLT0gZGltcy5ndXR0ZXJUb3RhbFdpZHRoO1xuICAgICAgICBub2RlLnN0eWxlLnBhZGRpbmdMZWZ0ID0gZGltcy5ndXR0ZXJUb3RhbFdpZHRoICsgXCJweFwiO1xuICAgICAgfVxuICAgICAgbm9kZS5zdHlsZS53aWR0aCA9IHdpZHRoICsgXCJweFwiO1xuICAgIH1cbiAgICBpZiAod2lkZ2V0LmNvdmVyR3V0dGVyKSB7XG4gICAgICBub2RlLnN0eWxlLnpJbmRleCA9IDU7XG4gICAgICBub2RlLnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuICAgICAgaWYgKCF3aWRnZXQubm9IU2Nyb2xsKSBub2RlLnN0eWxlLm1hcmdpbkxlZnQgPSAtZGltcy5ndXR0ZXJUb3RhbFdpZHRoICsgXCJweFwiO1xuICAgIH1cbiAgfVxuXG4gIC8vIFBPU0lUSU9OIE9CSkVDVFxuXG4gIC8vIEEgUG9zIGluc3RhbmNlIHJlcHJlc2VudHMgYSBwb3NpdGlvbiB3aXRoaW4gdGhlIHRleHQuXG4gIHZhciBQb3MgPSBDb2RlTWlycm9yLlBvcyA9IGZ1bmN0aW9uKGxpbmUsIGNoKSB7XG4gICAgaWYgKCEodGhpcyBpbnN0YW5jZW9mIFBvcykpIHJldHVybiBuZXcgUG9zKGxpbmUsIGNoKTtcbiAgICB0aGlzLmxpbmUgPSBsaW5lOyB0aGlzLmNoID0gY2g7XG4gIH07XG5cbiAgLy8gQ29tcGFyZSB0d28gcG9zaXRpb25zLCByZXR1cm4gMCBpZiB0aGV5IGFyZSB0aGUgc2FtZSwgYSBuZWdhdGl2ZVxuICAvLyBudW1iZXIgd2hlbiBhIGlzIGxlc3MsIGFuZCBhIHBvc2l0aXZlIG51bWJlciBvdGhlcndpc2UuXG4gIHZhciBjbXAgPSBDb2RlTWlycm9yLmNtcFBvcyA9IGZ1bmN0aW9uKGEsIGIpIHsgcmV0dXJuIGEubGluZSAtIGIubGluZSB8fCBhLmNoIC0gYi5jaDsgfTtcblxuICBmdW5jdGlvbiBjb3B5UG9zKHgpIHtyZXR1cm4gUG9zKHgubGluZSwgeC5jaCk7fVxuICBmdW5jdGlvbiBtYXhQb3MoYSwgYikgeyByZXR1cm4gY21wKGEsIGIpIDwgMCA/IGIgOiBhOyB9XG4gIGZ1bmN0aW9uIG1pblBvcyhhLCBiKSB7IHJldHVybiBjbXAoYSwgYikgPCAwID8gYSA6IGI7IH1cblxuICAvLyBTRUxFQ1RJT04gLyBDVVJTT1JcblxuICAvLyBTZWxlY3Rpb24gb2JqZWN0cyBhcmUgaW1tdXRhYmxlLiBBIG5ldyBvbmUgaXMgY3JlYXRlZCBldmVyeSB0aW1lXG4gIC8vIHRoZSBzZWxlY3Rpb24gY2hhbmdlcy4gQSBzZWxlY3Rpb24gaXMgb25lIG9yIG1vcmUgbm9uLW92ZXJsYXBwaW5nXG4gIC8vIChhbmQgbm9uLXRvdWNoaW5nKSByYW5nZXMsIHNvcnRlZCwgYW5kIGFuIGludGVnZXIgdGhhdCBpbmRpY2F0ZXNcbiAgLy8gd2hpY2ggb25lIGlzIHRoZSBwcmltYXJ5IHNlbGVjdGlvbiAodGhlIG9uZSB0aGF0J3Mgc2Nyb2xsZWQgaW50b1xuICAvLyB2aWV3LCB0aGF0IGdldEN1cnNvciByZXR1cm5zLCBldGMpLlxuICBmdW5jdGlvbiBTZWxlY3Rpb24ocmFuZ2VzLCBwcmltSW5kZXgpIHtcbiAgICB0aGlzLnJhbmdlcyA9IHJhbmdlcztcbiAgICB0aGlzLnByaW1JbmRleCA9IHByaW1JbmRleDtcbiAgfVxuXG4gIFNlbGVjdGlvbi5wcm90b3R5cGUgPSB7XG4gICAgcHJpbWFyeTogZnVuY3Rpb24oKSB7IHJldHVybiB0aGlzLnJhbmdlc1t0aGlzLnByaW1JbmRleF07IH0sXG4gICAgZXF1YWxzOiBmdW5jdGlvbihvdGhlcikge1xuICAgICAgaWYgKG90aGVyID09IHRoaXMpIHJldHVybiB0cnVlO1xuICAgICAgaWYgKG90aGVyLnByaW1JbmRleCAhPSB0aGlzLnByaW1JbmRleCB8fCBvdGhlci5yYW5nZXMubGVuZ3RoICE9IHRoaXMucmFuZ2VzLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgaGVyZSA9IHRoaXMucmFuZ2VzW2ldLCB0aGVyZSA9IG90aGVyLnJhbmdlc1tpXTtcbiAgICAgICAgaWYgKGNtcChoZXJlLmFuY2hvciwgdGhlcmUuYW5jaG9yKSAhPSAwIHx8IGNtcChoZXJlLmhlYWQsIHRoZXJlLmhlYWQpICE9IDApIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG4gICAgZGVlcENvcHk6IGZ1bmN0aW9uKCkge1xuICAgICAgZm9yICh2YXIgb3V0ID0gW10sIGkgPSAwOyBpIDwgdGhpcy5yYW5nZXMubGVuZ3RoOyBpKyspXG4gICAgICAgIG91dFtpXSA9IG5ldyBSYW5nZShjb3B5UG9zKHRoaXMucmFuZ2VzW2ldLmFuY2hvciksIGNvcHlQb3ModGhpcy5yYW5nZXNbaV0uaGVhZCkpO1xuICAgICAgcmV0dXJuIG5ldyBTZWxlY3Rpb24ob3V0LCB0aGlzLnByaW1JbmRleCk7XG4gICAgfSxcbiAgICBzb21ldGhpbmdTZWxlY3RlZDogZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMucmFuZ2VzLmxlbmd0aDsgaSsrKVxuICAgICAgICBpZiAoIXRoaXMucmFuZ2VzW2ldLmVtcHR5KCkpIHJldHVybiB0cnVlO1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH0sXG4gICAgY29udGFpbnM6IGZ1bmN0aW9uKHBvcywgZW5kKSB7XG4gICAgICBpZiAoIWVuZCkgZW5kID0gcG9zO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgcmFuZ2UgPSB0aGlzLnJhbmdlc1tpXTtcbiAgICAgICAgaWYgKGNtcChlbmQsIHJhbmdlLmZyb20oKSkgPj0gMCAmJiBjbXAocG9zLCByYW5nZS50bygpKSA8PSAwKVxuICAgICAgICAgIHJldHVybiBpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIC0xO1xuICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBSYW5nZShhbmNob3IsIGhlYWQpIHtcbiAgICB0aGlzLmFuY2hvciA9IGFuY2hvcjsgdGhpcy5oZWFkID0gaGVhZDtcbiAgfVxuXG4gIFJhbmdlLnByb3RvdHlwZSA9IHtcbiAgICBmcm9tOiBmdW5jdGlvbigpIHsgcmV0dXJuIG1pblBvcyh0aGlzLmFuY2hvciwgdGhpcy5oZWFkKTsgfSxcbiAgICB0bzogZnVuY3Rpb24oKSB7IHJldHVybiBtYXhQb3ModGhpcy5hbmNob3IsIHRoaXMuaGVhZCk7IH0sXG4gICAgZW1wdHk6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHRoaXMuaGVhZC5saW5lID09IHRoaXMuYW5jaG9yLmxpbmUgJiYgdGhpcy5oZWFkLmNoID09IHRoaXMuYW5jaG9yLmNoO1xuICAgIH1cbiAgfTtcblxuICAvLyBUYWtlIGFuIHVuc29ydGVkLCBwb3RlbnRpYWxseSBvdmVybGFwcGluZyBzZXQgb2YgcmFuZ2VzLCBhbmRcbiAgLy8gYnVpbGQgYSBzZWxlY3Rpb24gb3V0IG9mIGl0LiAnQ29uc3VtZXMnIHJhbmdlcyBhcnJheSAobW9kaWZ5aW5nXG4gIC8vIGl0KS5cbiAgZnVuY3Rpb24gbm9ybWFsaXplU2VsZWN0aW9uKHJhbmdlcywgcHJpbUluZGV4KSB7XG4gICAgdmFyIHByaW0gPSByYW5nZXNbcHJpbUluZGV4XTtcbiAgICByYW5nZXMuc29ydChmdW5jdGlvbihhLCBiKSB7IHJldHVybiBjbXAoYS5mcm9tKCksIGIuZnJvbSgpKTsgfSk7XG4gICAgcHJpbUluZGV4ID0gaW5kZXhPZihyYW5nZXMsIHByaW0pO1xuICAgIGZvciAodmFyIGkgPSAxOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgY3VyID0gcmFuZ2VzW2ldLCBwcmV2ID0gcmFuZ2VzW2kgLSAxXTtcbiAgICAgIGlmIChjbXAocHJldi50bygpLCBjdXIuZnJvbSgpKSA+PSAwKSB7XG4gICAgICAgIHZhciBmcm9tID0gbWluUG9zKHByZXYuZnJvbSgpLCBjdXIuZnJvbSgpKSwgdG8gPSBtYXhQb3MocHJldi50bygpLCBjdXIudG8oKSk7XG4gICAgICAgIHZhciBpbnYgPSBwcmV2LmVtcHR5KCkgPyBjdXIuZnJvbSgpID09IGN1ci5oZWFkIDogcHJldi5mcm9tKCkgPT0gcHJldi5oZWFkO1xuICAgICAgICBpZiAoaSA8PSBwcmltSW5kZXgpIC0tcHJpbUluZGV4O1xuICAgICAgICByYW5nZXMuc3BsaWNlKC0taSwgMiwgbmV3IFJhbmdlKGludiA/IHRvIDogZnJvbSwgaW52ID8gZnJvbSA6IHRvKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBuZXcgU2VsZWN0aW9uKHJhbmdlcywgcHJpbUluZGV4KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNpbXBsZVNlbGVjdGlvbihhbmNob3IsIGhlYWQpIHtcbiAgICByZXR1cm4gbmV3IFNlbGVjdGlvbihbbmV3IFJhbmdlKGFuY2hvciwgaGVhZCB8fCBhbmNob3IpXSwgMCk7XG4gIH1cblxuICAvLyBNb3N0IG9mIHRoZSBleHRlcm5hbCBBUEkgY2xpcHMgZ2l2ZW4gcG9zaXRpb25zIHRvIG1ha2Ugc3VyZSB0aGV5XG4gIC8vIGFjdHVhbGx5IGV4aXN0IHdpdGhpbiB0aGUgZG9jdW1lbnQuXG4gIGZ1bmN0aW9uIGNsaXBMaW5lKGRvYywgbikge3JldHVybiBNYXRoLm1heChkb2MuZmlyc3QsIE1hdGgubWluKG4sIGRvYy5maXJzdCArIGRvYy5zaXplIC0gMSkpO31cbiAgZnVuY3Rpb24gY2xpcFBvcyhkb2MsIHBvcykge1xuICAgIGlmIChwb3MubGluZSA8IGRvYy5maXJzdCkgcmV0dXJuIFBvcyhkb2MuZmlyc3QsIDApO1xuICAgIHZhciBsYXN0ID0gZG9jLmZpcnN0ICsgZG9jLnNpemUgLSAxO1xuICAgIGlmIChwb3MubGluZSA+IGxhc3QpIHJldHVybiBQb3MobGFzdCwgZ2V0TGluZShkb2MsIGxhc3QpLnRleHQubGVuZ3RoKTtcbiAgICByZXR1cm4gY2xpcFRvTGVuKHBvcywgZ2V0TGluZShkb2MsIHBvcy5saW5lKS50ZXh0Lmxlbmd0aCk7XG4gIH1cbiAgZnVuY3Rpb24gY2xpcFRvTGVuKHBvcywgbGluZWxlbikge1xuICAgIHZhciBjaCA9IHBvcy5jaDtcbiAgICBpZiAoY2ggPT0gbnVsbCB8fCBjaCA+IGxpbmVsZW4pIHJldHVybiBQb3MocG9zLmxpbmUsIGxpbmVsZW4pO1xuICAgIGVsc2UgaWYgKGNoIDwgMCkgcmV0dXJuIFBvcyhwb3MubGluZSwgMCk7XG4gICAgZWxzZSByZXR1cm4gcG9zO1xuICB9XG4gIGZ1bmN0aW9uIGlzTGluZShkb2MsIGwpIHtyZXR1cm4gbCA+PSBkb2MuZmlyc3QgJiYgbCA8IGRvYy5maXJzdCArIGRvYy5zaXplO31cbiAgZnVuY3Rpb24gY2xpcFBvc0FycmF5KGRvYywgYXJyYXkpIHtcbiAgICBmb3IgKHZhciBvdXQgPSBbXSwgaSA9IDA7IGkgPCBhcnJheS5sZW5ndGg7IGkrKykgb3V0W2ldID0gY2xpcFBvcyhkb2MsIGFycmF5W2ldKTtcbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgLy8gU0VMRUNUSU9OIFVQREFURVNcblxuICAvLyBUaGUgJ3Njcm9sbCcgcGFyYW1ldGVyIGdpdmVuIHRvIG1hbnkgb2YgdGhlc2UgaW5kaWNhdGVkIHdoZXRoZXJcbiAgLy8gdGhlIG5ldyBjdXJzb3IgcG9zaXRpb24gc2hvdWxkIGJlIHNjcm9sbGVkIGludG8gdmlldyBhZnRlclxuICAvLyBtb2RpZnlpbmcgdGhlIHNlbGVjdGlvbi5cblxuICAvLyBJZiBzaGlmdCBpcyBoZWxkIG9yIHRoZSBleHRlbmQgZmxhZyBpcyBzZXQsIGV4dGVuZHMgYSByYW5nZSB0b1xuICAvLyBpbmNsdWRlIGEgZ2l2ZW4gcG9zaXRpb24gKGFuZCBvcHRpb25hbGx5IGEgc2Vjb25kIHBvc2l0aW9uKS5cbiAgLy8gT3RoZXJ3aXNlLCBzaW1wbHkgcmV0dXJucyB0aGUgcmFuZ2UgYmV0d2VlbiB0aGUgZ2l2ZW4gcG9zaXRpb25zLlxuICAvLyBVc2VkIGZvciBjdXJzb3IgbW90aW9uIGFuZCBzdWNoLlxuICBmdW5jdGlvbiBleHRlbmRSYW5nZShkb2MsIHJhbmdlLCBoZWFkLCBvdGhlcikge1xuICAgIGlmIChkb2MuY20gJiYgZG9jLmNtLmRpc3BsYXkuc2hpZnQgfHwgZG9jLmV4dGVuZCkge1xuICAgICAgdmFyIGFuY2hvciA9IHJhbmdlLmFuY2hvcjtcbiAgICAgIGlmIChvdGhlcikge1xuICAgICAgICB2YXIgcG9zQmVmb3JlID0gY21wKGhlYWQsIGFuY2hvcikgPCAwO1xuICAgICAgICBpZiAocG9zQmVmb3JlICE9IChjbXAob3RoZXIsIGFuY2hvcikgPCAwKSkge1xuICAgICAgICAgIGFuY2hvciA9IGhlYWQ7XG4gICAgICAgICAgaGVhZCA9IG90aGVyO1xuICAgICAgICB9IGVsc2UgaWYgKHBvc0JlZm9yZSAhPSAoY21wKGhlYWQsIG90aGVyKSA8IDApKSB7XG4gICAgICAgICAgaGVhZCA9IG90aGVyO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gbmV3IFJhbmdlKGFuY2hvciwgaGVhZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBuZXcgUmFuZ2Uob3RoZXIgfHwgaGVhZCwgaGVhZCk7XG4gICAgfVxuICB9XG5cbiAgLy8gRXh0ZW5kIHRoZSBwcmltYXJ5IHNlbGVjdGlvbiByYW5nZSwgZGlzY2FyZCB0aGUgcmVzdC5cbiAgZnVuY3Rpb24gZXh0ZW5kU2VsZWN0aW9uKGRvYywgaGVhZCwgb3RoZXIsIG9wdGlvbnMpIHtcbiAgICBzZXRTZWxlY3Rpb24oZG9jLCBuZXcgU2VsZWN0aW9uKFtleHRlbmRSYW5nZShkb2MsIGRvYy5zZWwucHJpbWFyeSgpLCBoZWFkLCBvdGhlcildLCAwKSwgb3B0aW9ucyk7XG4gIH1cblxuICAvLyBFeHRlbmQgYWxsIHNlbGVjdGlvbnMgKHBvcyBpcyBhbiBhcnJheSBvZiBzZWxlY3Rpb25zIHdpdGggbGVuZ3RoXG4gIC8vIGVxdWFsIHRoZSBudW1iZXIgb2Ygc2VsZWN0aW9ucylcbiAgZnVuY3Rpb24gZXh0ZW5kU2VsZWN0aW9ucyhkb2MsIGhlYWRzLCBvcHRpb25zKSB7XG4gICAgZm9yICh2YXIgb3V0ID0gW10sIGkgPSAwOyBpIDwgZG9jLnNlbC5yYW5nZXMubGVuZ3RoOyBpKyspXG4gICAgICBvdXRbaV0gPSBleHRlbmRSYW5nZShkb2MsIGRvYy5zZWwucmFuZ2VzW2ldLCBoZWFkc1tpXSwgbnVsbCk7XG4gICAgdmFyIG5ld1NlbCA9IG5vcm1hbGl6ZVNlbGVjdGlvbihvdXQsIGRvYy5zZWwucHJpbUluZGV4KTtcbiAgICBzZXRTZWxlY3Rpb24oZG9jLCBuZXdTZWwsIG9wdGlvbnMpO1xuICB9XG5cbiAgLy8gVXBkYXRlcyBhIHNpbmdsZSByYW5nZSBpbiB0aGUgc2VsZWN0aW9uLlxuICBmdW5jdGlvbiByZXBsYWNlT25lU2VsZWN0aW9uKGRvYywgaSwgcmFuZ2UsIG9wdGlvbnMpIHtcbiAgICB2YXIgcmFuZ2VzID0gZG9jLnNlbC5yYW5nZXMuc2xpY2UoMCk7XG4gICAgcmFuZ2VzW2ldID0gcmFuZ2U7XG4gICAgc2V0U2VsZWN0aW9uKGRvYywgbm9ybWFsaXplU2VsZWN0aW9uKHJhbmdlcywgZG9jLnNlbC5wcmltSW5kZXgpLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8vIFJlc2V0IHRoZSBzZWxlY3Rpb24gdG8gYSBzaW5nbGUgcmFuZ2UuXG4gIGZ1bmN0aW9uIHNldFNpbXBsZVNlbGVjdGlvbihkb2MsIGFuY2hvciwgaGVhZCwgb3B0aW9ucykge1xuICAgIHNldFNlbGVjdGlvbihkb2MsIHNpbXBsZVNlbGVjdGlvbihhbmNob3IsIGhlYWQpLCBvcHRpb25zKTtcbiAgfVxuXG4gIC8vIEdpdmUgYmVmb3JlU2VsZWN0aW9uQ2hhbmdlIGhhbmRsZXJzIGEgY2hhbmdlIHRvIGluZmx1ZW5jZSBhXG4gIC8vIHNlbGVjdGlvbiB1cGRhdGUuXG4gIGZ1bmN0aW9uIGZpbHRlclNlbGVjdGlvbkNoYW5nZShkb2MsIHNlbCkge1xuICAgIHZhciBvYmogPSB7XG4gICAgICByYW5nZXM6IHNlbC5yYW5nZXMsXG4gICAgICB1cGRhdGU6IGZ1bmN0aW9uKHJhbmdlcykge1xuICAgICAgICB0aGlzLnJhbmdlcyA9IFtdO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKylcbiAgICAgICAgICB0aGlzLnJhbmdlc1tpXSA9IG5ldyBSYW5nZShjbGlwUG9zKGRvYywgcmFuZ2VzW2ldLmFuY2hvciksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xpcFBvcyhkb2MsIHJhbmdlc1tpXS5oZWFkKSk7XG4gICAgICB9XG4gICAgfTtcbiAgICBzaWduYWwoZG9jLCBcImJlZm9yZVNlbGVjdGlvbkNoYW5nZVwiLCBkb2MsIG9iaik7XG4gICAgaWYgKGRvYy5jbSkgc2lnbmFsKGRvYy5jbSwgXCJiZWZvcmVTZWxlY3Rpb25DaGFuZ2VcIiwgZG9jLmNtLCBvYmopO1xuICAgIGlmIChvYmoucmFuZ2VzICE9IHNlbC5yYW5nZXMpIHJldHVybiBub3JtYWxpemVTZWxlY3Rpb24ob2JqLnJhbmdlcywgb2JqLnJhbmdlcy5sZW5ndGggLSAxKTtcbiAgICBlbHNlIHJldHVybiBzZWw7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRTZWxlY3Rpb25SZXBsYWNlSGlzdG9yeShkb2MsIHNlbCwgb3B0aW9ucykge1xuICAgIHZhciBkb25lID0gZG9jLmhpc3RvcnkuZG9uZSwgbGFzdCA9IGxzdChkb25lKTtcbiAgICBpZiAobGFzdCAmJiBsYXN0LnJhbmdlcykge1xuICAgICAgZG9uZVtkb25lLmxlbmd0aCAtIDFdID0gc2VsO1xuICAgICAgc2V0U2VsZWN0aW9uTm9VbmRvKGRvYywgc2VsLCBvcHRpb25zKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2V0U2VsZWN0aW9uKGRvYywgc2VsLCBvcHRpb25zKTtcbiAgICB9XG4gIH1cblxuICAvLyBTZXQgYSBuZXcgc2VsZWN0aW9uLlxuICBmdW5jdGlvbiBzZXRTZWxlY3Rpb24oZG9jLCBzZWwsIG9wdGlvbnMpIHtcbiAgICBzZXRTZWxlY3Rpb25Ob1VuZG8oZG9jLCBzZWwsIG9wdGlvbnMpO1xuICAgIGFkZFNlbGVjdGlvblRvSGlzdG9yeShkb2MsIGRvYy5zZWwsIGRvYy5jbSA/IGRvYy5jbS5jdXJPcC5pZCA6IE5hTiwgb3B0aW9ucyk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRTZWxlY3Rpb25Ob1VuZG8oZG9jLCBzZWwsIG9wdGlvbnMpIHtcbiAgICBpZiAoaGFzSGFuZGxlcihkb2MsIFwiYmVmb3JlU2VsZWN0aW9uQ2hhbmdlXCIpIHx8IGRvYy5jbSAmJiBoYXNIYW5kbGVyKGRvYy5jbSwgXCJiZWZvcmVTZWxlY3Rpb25DaGFuZ2VcIikpXG4gICAgICBzZWwgPSBmaWx0ZXJTZWxlY3Rpb25DaGFuZ2UoZG9jLCBzZWwpO1xuXG4gICAgdmFyIGJpYXMgPSBvcHRpb25zICYmIG9wdGlvbnMuYmlhcyB8fFxuICAgICAgKGNtcChzZWwucHJpbWFyeSgpLmhlYWQsIGRvYy5zZWwucHJpbWFyeSgpLmhlYWQpIDwgMCA/IC0xIDogMSk7XG4gICAgc2V0U2VsZWN0aW9uSW5uZXIoZG9jLCBza2lwQXRvbWljSW5TZWxlY3Rpb24oZG9jLCBzZWwsIGJpYXMsIHRydWUpKTtcblxuICAgIGlmICghKG9wdGlvbnMgJiYgb3B0aW9ucy5zY3JvbGwgPT09IGZhbHNlKSAmJiBkb2MuY20pXG4gICAgICBlbnN1cmVDdXJzb3JWaXNpYmxlKGRvYy5jbSk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXRTZWxlY3Rpb25Jbm5lcihkb2MsIHNlbCkge1xuICAgIGlmIChzZWwuZXF1YWxzKGRvYy5zZWwpKSByZXR1cm47XG5cbiAgICBkb2Muc2VsID0gc2VsO1xuXG4gICAgaWYgKGRvYy5jbSkge1xuICAgICAgZG9jLmNtLmN1ck9wLnVwZGF0ZUlucHV0ID0gZG9jLmNtLmN1ck9wLnNlbGVjdGlvbkNoYW5nZWQgPSB0cnVlO1xuICAgICAgc2lnbmFsQ3Vyc29yQWN0aXZpdHkoZG9jLmNtKTtcbiAgICB9XG4gICAgc2lnbmFsTGF0ZXIoZG9jLCBcImN1cnNvckFjdGl2aXR5XCIsIGRvYyk7XG4gIH1cblxuICAvLyBWZXJpZnkgdGhhdCB0aGUgc2VsZWN0aW9uIGRvZXMgbm90IHBhcnRpYWxseSBzZWxlY3QgYW55IGF0b21pY1xuICAvLyBtYXJrZWQgcmFuZ2VzLlxuICBmdW5jdGlvbiByZUNoZWNrU2VsZWN0aW9uKGRvYykge1xuICAgIHNldFNlbGVjdGlvbklubmVyKGRvYywgc2tpcEF0b21pY0luU2VsZWN0aW9uKGRvYywgZG9jLnNlbCwgbnVsbCwgZmFsc2UpLCBzZWxfZG9udFNjcm9sbCk7XG4gIH1cblxuICAvLyBSZXR1cm4gYSBzZWxlY3Rpb24gdGhhdCBkb2VzIG5vdCBwYXJ0aWFsbHkgc2VsZWN0IGFueSBhdG9taWNcbiAgLy8gcmFuZ2VzLlxuICBmdW5jdGlvbiBza2lwQXRvbWljSW5TZWxlY3Rpb24oZG9jLCBzZWwsIGJpYXMsIG1heUNsZWFyKSB7XG4gICAgdmFyIG91dDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNlbC5yYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciByYW5nZSA9IHNlbC5yYW5nZXNbaV07XG4gICAgICB2YXIgbmV3QW5jaG9yID0gc2tpcEF0b21pYyhkb2MsIHJhbmdlLmFuY2hvciwgYmlhcywgbWF5Q2xlYXIpO1xuICAgICAgdmFyIG5ld0hlYWQgPSBza2lwQXRvbWljKGRvYywgcmFuZ2UuaGVhZCwgYmlhcywgbWF5Q2xlYXIpO1xuICAgICAgaWYgKG91dCB8fCBuZXdBbmNob3IgIT0gcmFuZ2UuYW5jaG9yIHx8IG5ld0hlYWQgIT0gcmFuZ2UuaGVhZCkge1xuICAgICAgICBpZiAoIW91dCkgb3V0ID0gc2VsLnJhbmdlcy5zbGljZSgwLCBpKTtcbiAgICAgICAgb3V0W2ldID0gbmV3IFJhbmdlKG5ld0FuY2hvciwgbmV3SGVhZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvdXQgPyBub3JtYWxpemVTZWxlY3Rpb24ob3V0LCBzZWwucHJpbUluZGV4KSA6IHNlbDtcbiAgfVxuXG4gIC8vIEVuc3VyZSBhIGdpdmVuIHBvc2l0aW9uIGlzIG5vdCBpbnNpZGUgYW4gYXRvbWljIHJhbmdlLlxuICBmdW5jdGlvbiBza2lwQXRvbWljKGRvYywgcG9zLCBiaWFzLCBtYXlDbGVhcikge1xuICAgIHZhciBmbGlwcGVkID0gZmFsc2UsIGN1clBvcyA9IHBvcztcbiAgICB2YXIgZGlyID0gYmlhcyB8fCAxO1xuICAgIGRvYy5jYW50RWRpdCA9IGZhbHNlO1xuICAgIHNlYXJjaDogZm9yICg7Oykge1xuICAgICAgdmFyIGxpbmUgPSBnZXRMaW5lKGRvYywgY3VyUG9zLmxpbmUpO1xuICAgICAgaWYgKGxpbmUubWFya2VkU3BhbnMpIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lLm1hcmtlZFNwYW5zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgICAgdmFyIHNwID0gbGluZS5tYXJrZWRTcGFuc1tpXSwgbSA9IHNwLm1hcmtlcjtcbiAgICAgICAgICBpZiAoKHNwLmZyb20gPT0gbnVsbCB8fCAobS5pbmNsdXNpdmVMZWZ0ID8gc3AuZnJvbSA8PSBjdXJQb3MuY2ggOiBzcC5mcm9tIDwgY3VyUG9zLmNoKSkgJiZcbiAgICAgICAgICAgICAgKHNwLnRvID09IG51bGwgfHwgKG0uaW5jbHVzaXZlUmlnaHQgPyBzcC50byA+PSBjdXJQb3MuY2ggOiBzcC50byA+IGN1clBvcy5jaCkpKSB7XG4gICAgICAgICAgICBpZiAobWF5Q2xlYXIpIHtcbiAgICAgICAgICAgICAgc2lnbmFsKG0sIFwiYmVmb3JlQ3Vyc29yRW50ZXJcIik7XG4gICAgICAgICAgICAgIGlmIChtLmV4cGxpY2l0bHlDbGVhcmVkKSB7XG4gICAgICAgICAgICAgICAgaWYgKCFsaW5lLm1hcmtlZFNwYW5zKSBicmVhaztcbiAgICAgICAgICAgICAgICBlbHNlIHstLWk7IGNvbnRpbnVlO31cbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKCFtLmF0b21pYykgY29udGludWU7XG4gICAgICAgICAgICB2YXIgbmV3UG9zID0gbS5maW5kKGRpciA8IDAgPyAtMSA6IDEpO1xuICAgICAgICAgICAgaWYgKGNtcChuZXdQb3MsIGN1clBvcykgPT0gMCkge1xuICAgICAgICAgICAgICBuZXdQb3MuY2ggKz0gZGlyO1xuICAgICAgICAgICAgICBpZiAobmV3UG9zLmNoIDwgMCkge1xuICAgICAgICAgICAgICAgIGlmIChuZXdQb3MubGluZSA+IGRvYy5maXJzdCkgbmV3UG9zID0gY2xpcFBvcyhkb2MsIFBvcyhuZXdQb3MubGluZSAtIDEpKTtcbiAgICAgICAgICAgICAgICBlbHNlIG5ld1BvcyA9IG51bGw7XG4gICAgICAgICAgICAgIH0gZWxzZSBpZiAobmV3UG9zLmNoID4gbGluZS50ZXh0Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgIGlmIChuZXdQb3MubGluZSA8IGRvYy5maXJzdCArIGRvYy5zaXplIC0gMSkgbmV3UG9zID0gUG9zKG5ld1Bvcy5saW5lICsgMSwgMCk7XG4gICAgICAgICAgICAgICAgZWxzZSBuZXdQb3MgPSBudWxsO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIGlmICghbmV3UG9zKSB7XG4gICAgICAgICAgICAgICAgaWYgKGZsaXBwZWQpIHtcbiAgICAgICAgICAgICAgICAgIC8vIERyaXZlbiBpbiBhIGNvcm5lciAtLSBubyB2YWxpZCBjdXJzb3IgcG9zaXRpb24gZm91bmQgYXQgYWxsXG4gICAgICAgICAgICAgICAgICAvLyAtLSB0cnkgYWdhaW4gKndpdGgqIGNsZWFyaW5nLCBpZiB3ZSBkaWRuJ3QgYWxyZWFkeVxuICAgICAgICAgICAgICAgICAgaWYgKCFtYXlDbGVhcikgcmV0dXJuIHNraXBBdG9taWMoZG9jLCBwb3MsIGJpYXMsIHRydWUpO1xuICAgICAgICAgICAgICAgICAgLy8gT3RoZXJ3aXNlLCB0dXJuIG9mZiBlZGl0aW5nIHVudGlsIGZ1cnRoZXIgbm90aWNlLCBhbmQgcmV0dXJuIHRoZSBzdGFydCBvZiB0aGUgZG9jXG4gICAgICAgICAgICAgICAgICBkb2MuY2FudEVkaXQgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgcmV0dXJuIFBvcyhkb2MuZmlyc3QsIDApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBmbGlwcGVkID0gdHJ1ZTsgbmV3UG9zID0gcG9zOyBkaXIgPSAtZGlyO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjdXJQb3MgPSBuZXdQb3M7XG4gICAgICAgICAgICBjb250aW51ZSBzZWFyY2g7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gY3VyUG9zO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNFTEVDVElPTiBEUkFXSU5HXG5cbiAgLy8gUmVkcmF3IHRoZSBzZWxlY3Rpb24gYW5kL29yIGN1cnNvclxuICBmdW5jdGlvbiBkcmF3U2VsZWN0aW9uKGNtKSB7XG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBkb2MgPSBjbS5kb2MsIHJlc3VsdCA9IHt9O1xuICAgIHZhciBjdXJGcmFnbWVudCA9IHJlc3VsdC5jdXJzb3JzID0gZG9jdW1lbnQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpO1xuICAgIHZhciBzZWxGcmFnbWVudCA9IHJlc3VsdC5zZWxlY3Rpb24gPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRvYy5zZWwucmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcmFuZ2UgPSBkb2Muc2VsLnJhbmdlc1tpXTtcbiAgICAgIHZhciBjb2xsYXBzZWQgPSByYW5nZS5lbXB0eSgpO1xuICAgICAgaWYgKGNvbGxhcHNlZCB8fCBjbS5vcHRpb25zLnNob3dDdXJzb3JXaGVuU2VsZWN0aW5nKVxuICAgICAgICBkcmF3U2VsZWN0aW9uQ3Vyc29yKGNtLCByYW5nZSwgY3VyRnJhZ21lbnQpO1xuICAgICAgaWYgKCFjb2xsYXBzZWQpXG4gICAgICAgIGRyYXdTZWxlY3Rpb25SYW5nZShjbSwgcmFuZ2UsIHNlbEZyYWdtZW50KTtcbiAgICB9XG5cbiAgICAvLyBNb3ZlIHRoZSBoaWRkZW4gdGV4dGFyZWEgbmVhciB0aGUgY3Vyc29yIHRvIHByZXZlbnQgc2Nyb2xsaW5nIGFydGlmYWN0c1xuICAgIGlmIChjbS5vcHRpb25zLm1vdmVJbnB1dFdpdGhDdXJzb3IpIHtcbiAgICAgIHZhciBoZWFkUG9zID0gY3Vyc29yQ29vcmRzKGNtLCBkb2Muc2VsLnByaW1hcnkoKS5oZWFkLCBcImRpdlwiKTtcbiAgICAgIHZhciB3cmFwT2ZmID0gZGlzcGxheS53cmFwcGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBsaW5lT2ZmID0gZGlzcGxheS5saW5lRGl2LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgcmVzdWx0LnRlVG9wID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oZGlzcGxheS53cmFwcGVyLmNsaWVudEhlaWdodCAtIDEwLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZFBvcy50b3AgKyBsaW5lT2ZmLnRvcCAtIHdyYXBPZmYudG9wKSk7XG4gICAgICByZXN1bHQudGVMZWZ0ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oZGlzcGxheS53cmFwcGVyLmNsaWVudFdpZHRoIC0gMTAsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVhZFBvcy5sZWZ0ICsgbGluZU9mZi5sZWZ0IC0gd3JhcE9mZi5sZWZ0KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNob3dTZWxlY3Rpb24oY20sIGRyYXduKSB7XG4gICAgcmVtb3ZlQ2hpbGRyZW5BbmRBZGQoY20uZGlzcGxheS5jdXJzb3JEaXYsIGRyYXduLmN1cnNvcnMpO1xuICAgIHJlbW92ZUNoaWxkcmVuQW5kQWRkKGNtLmRpc3BsYXkuc2VsZWN0aW9uRGl2LCBkcmF3bi5zZWxlY3Rpb24pO1xuICAgIGlmIChkcmF3bi50ZVRvcCAhPSBudWxsKSB7XG4gICAgICBjbS5kaXNwbGF5LmlucHV0RGl2LnN0eWxlLnRvcCA9IGRyYXduLnRlVG9wICsgXCJweFwiO1xuICAgICAgY20uZGlzcGxheS5pbnB1dERpdi5zdHlsZS5sZWZ0ID0gZHJhd24udGVMZWZ0ICsgXCJweFwiO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHVwZGF0ZVNlbGVjdGlvbihjbSkge1xuICAgIHNob3dTZWxlY3Rpb24oY20sIGRyYXdTZWxlY3Rpb24oY20pKTtcbiAgfVxuXG4gIC8vIERyYXdzIGEgY3Vyc29yIGZvciB0aGUgZ2l2ZW4gcmFuZ2VcbiAgZnVuY3Rpb24gZHJhd1NlbGVjdGlvbkN1cnNvcihjbSwgcmFuZ2UsIG91dHB1dCkge1xuICAgIHZhciBwb3MgPSBjdXJzb3JDb29yZHMoY20sIHJhbmdlLmhlYWQsIFwiZGl2XCIsIG51bGwsIG51bGwsICFjbS5vcHRpb25zLnNpbmdsZUN1cnNvckhlaWdodFBlckxpbmUpO1xuXG4gICAgdmFyIGN1cnNvciA9IG91dHB1dC5hcHBlbmRDaGlsZChlbHQoXCJkaXZcIiwgXCJcXHUwMGEwXCIsIFwiQ29kZU1pcnJvci1jdXJzb3JcIikpO1xuICAgIGN1cnNvci5zdHlsZS5sZWZ0ID0gcG9zLmxlZnQgKyBcInB4XCI7XG4gICAgY3Vyc29yLnN0eWxlLnRvcCA9IHBvcy50b3AgKyBcInB4XCI7XG4gICAgY3Vyc29yLnN0eWxlLmhlaWdodCA9IE1hdGgubWF4KDAsIHBvcy5ib3R0b20gLSBwb3MudG9wKSAqIGNtLm9wdGlvbnMuY3Vyc29ySGVpZ2h0ICsgXCJweFwiO1xuXG4gICAgaWYgKHBvcy5vdGhlcikge1xuICAgICAgLy8gU2Vjb25kYXJ5IGN1cnNvciwgc2hvd24gd2hlbiBvbiBhICdqdW1wJyBpbiBiaS1kaXJlY3Rpb25hbCB0ZXh0XG4gICAgICB2YXIgb3RoZXJDdXJzb3IgPSBvdXRwdXQuYXBwZW5kQ2hpbGQoZWx0KFwiZGl2XCIsIFwiXFx1MDBhMFwiLCBcIkNvZGVNaXJyb3ItY3Vyc29yIENvZGVNaXJyb3Itc2Vjb25kYXJ5Y3Vyc29yXCIpKTtcbiAgICAgIG90aGVyQ3Vyc29yLnN0eWxlLmRpc3BsYXkgPSBcIlwiO1xuICAgICAgb3RoZXJDdXJzb3Iuc3R5bGUubGVmdCA9IHBvcy5vdGhlci5sZWZ0ICsgXCJweFwiO1xuICAgICAgb3RoZXJDdXJzb3Iuc3R5bGUudG9wID0gcG9zLm90aGVyLnRvcCArIFwicHhcIjtcbiAgICAgIG90aGVyQ3Vyc29yLnN0eWxlLmhlaWdodCA9IChwb3Mub3RoZXIuYm90dG9tIC0gcG9zLm90aGVyLnRvcCkgKiAuODUgKyBcInB4XCI7XG4gICAgfVxuICB9XG5cbiAgLy8gRHJhd3MgdGhlIGdpdmVuIHJhbmdlIGFzIGEgaGlnaGxpZ2h0ZWQgc2VsZWN0aW9uXG4gIGZ1bmN0aW9uIGRyYXdTZWxlY3Rpb25SYW5nZShjbSwgcmFuZ2UsIG91dHB1dCkge1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheSwgZG9jID0gY20uZG9jO1xuICAgIHZhciBmcmFnbWVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcbiAgICB2YXIgcGFkZGluZyA9IHBhZGRpbmdIKGNtLmRpc3BsYXkpLCBsZWZ0U2lkZSA9IHBhZGRpbmcubGVmdDtcbiAgICB2YXIgcmlnaHRTaWRlID0gTWF0aC5tYXgoZGlzcGxheS5zaXplcldpZHRoLCBkaXNwbGF5V2lkdGgoY20pIC0gZGlzcGxheS5zaXplci5vZmZzZXRMZWZ0KSAtIHBhZGRpbmcucmlnaHQ7XG5cbiAgICBmdW5jdGlvbiBhZGQobGVmdCwgdG9wLCB3aWR0aCwgYm90dG9tKSB7XG4gICAgICBpZiAodG9wIDwgMCkgdG9wID0gMDtcbiAgICAgIHRvcCA9IE1hdGgucm91bmQodG9wKTtcbiAgICAgIGJvdHRvbSA9IE1hdGgucm91bmQoYm90dG9tKTtcbiAgICAgIGZyYWdtZW50LmFwcGVuZENoaWxkKGVsdChcImRpdlwiLCBudWxsLCBcIkNvZGVNaXJyb3Itc2VsZWN0ZWRcIiwgXCJwb3NpdGlvbjogYWJzb2x1dGU7IGxlZnQ6IFwiICsgbGVmdCArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJweDsgdG9wOiBcIiArIHRvcCArIFwicHg7IHdpZHRoOiBcIiArICh3aWR0aCA9PSBudWxsID8gcmlnaHRTaWRlIC0gbGVmdCA6IHdpZHRoKSArXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXCJweDsgaGVpZ2h0OiBcIiArIChib3R0b20gLSB0b3ApICsgXCJweFwiKSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZHJhd0ZvckxpbmUobGluZSwgZnJvbUFyZywgdG9BcmcpIHtcbiAgICAgIHZhciBsaW5lT2JqID0gZ2V0TGluZShkb2MsIGxpbmUpO1xuICAgICAgdmFyIGxpbmVMZW4gPSBsaW5lT2JqLnRleHQubGVuZ3RoO1xuICAgICAgdmFyIHN0YXJ0LCBlbmQ7XG4gICAgICBmdW5jdGlvbiBjb29yZHMoY2gsIGJpYXMpIHtcbiAgICAgICAgcmV0dXJuIGNoYXJDb29yZHMoY20sIFBvcyhsaW5lLCBjaCksIFwiZGl2XCIsIGxpbmVPYmosIGJpYXMpO1xuICAgICAgfVxuXG4gICAgICBpdGVyYXRlQmlkaVNlY3Rpb25zKGdldE9yZGVyKGxpbmVPYmopLCBmcm9tQXJnIHx8IDAsIHRvQXJnID09IG51bGwgPyBsaW5lTGVuIDogdG9BcmcsIGZ1bmN0aW9uKGZyb20sIHRvLCBkaXIpIHtcbiAgICAgICAgdmFyIGxlZnRQb3MgPSBjb29yZHMoZnJvbSwgXCJsZWZ0XCIpLCByaWdodFBvcywgbGVmdCwgcmlnaHQ7XG4gICAgICAgIGlmIChmcm9tID09IHRvKSB7XG4gICAgICAgICAgcmlnaHRQb3MgPSBsZWZ0UG9zO1xuICAgICAgICAgIGxlZnQgPSByaWdodCA9IGxlZnRQb3MubGVmdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByaWdodFBvcyA9IGNvb3Jkcyh0byAtIDEsIFwicmlnaHRcIik7XG4gICAgICAgICAgaWYgKGRpciA9PSBcInJ0bFwiKSB7IHZhciB0bXAgPSBsZWZ0UG9zOyBsZWZ0UG9zID0gcmlnaHRQb3M7IHJpZ2h0UG9zID0gdG1wOyB9XG4gICAgICAgICAgbGVmdCA9IGxlZnRQb3MubGVmdDtcbiAgICAgICAgICByaWdodCA9IHJpZ2h0UG9zLnJpZ2h0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChmcm9tQXJnID09IG51bGwgJiYgZnJvbSA9PSAwKSBsZWZ0ID0gbGVmdFNpZGU7XG4gICAgICAgIGlmIChyaWdodFBvcy50b3AgLSBsZWZ0UG9zLnRvcCA+IDMpIHsgLy8gRGlmZmVyZW50IGxpbmVzLCBkcmF3IHRvcCBwYXJ0XG4gICAgICAgICAgYWRkKGxlZnQsIGxlZnRQb3MudG9wLCBudWxsLCBsZWZ0UG9zLmJvdHRvbSk7XG4gICAgICAgICAgbGVmdCA9IGxlZnRTaWRlO1xuICAgICAgICAgIGlmIChsZWZ0UG9zLmJvdHRvbSA8IHJpZ2h0UG9zLnRvcCkgYWRkKGxlZnQsIGxlZnRQb3MuYm90dG9tLCBudWxsLCByaWdodFBvcy50b3ApO1xuICAgICAgICB9XG4gICAgICAgIGlmICh0b0FyZyA9PSBudWxsICYmIHRvID09IGxpbmVMZW4pIHJpZ2h0ID0gcmlnaHRTaWRlO1xuICAgICAgICBpZiAoIXN0YXJ0IHx8IGxlZnRQb3MudG9wIDwgc3RhcnQudG9wIHx8IGxlZnRQb3MudG9wID09IHN0YXJ0LnRvcCAmJiBsZWZ0UG9zLmxlZnQgPCBzdGFydC5sZWZ0KVxuICAgICAgICAgIHN0YXJ0ID0gbGVmdFBvcztcbiAgICAgICAgaWYgKCFlbmQgfHwgcmlnaHRQb3MuYm90dG9tID4gZW5kLmJvdHRvbSB8fCByaWdodFBvcy5ib3R0b20gPT0gZW5kLmJvdHRvbSAmJiByaWdodFBvcy5yaWdodCA+IGVuZC5yaWdodClcbiAgICAgICAgICBlbmQgPSByaWdodFBvcztcbiAgICAgICAgaWYgKGxlZnQgPCBsZWZ0U2lkZSArIDEpIGxlZnQgPSBsZWZ0U2lkZTtcbiAgICAgICAgYWRkKGxlZnQsIHJpZ2h0UG9zLnRvcCwgcmlnaHQgLSBsZWZ0LCByaWdodFBvcy5ib3R0b20pO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4ge3N0YXJ0OiBzdGFydCwgZW5kOiBlbmR9O1xuICAgIH1cblxuICAgIHZhciBzRnJvbSA9IHJhbmdlLmZyb20oKSwgc1RvID0gcmFuZ2UudG8oKTtcbiAgICBpZiAoc0Zyb20ubGluZSA9PSBzVG8ubGluZSkge1xuICAgICAgZHJhd0ZvckxpbmUoc0Zyb20ubGluZSwgc0Zyb20uY2gsIHNUby5jaCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciBmcm9tTGluZSA9IGdldExpbmUoZG9jLCBzRnJvbS5saW5lKSwgdG9MaW5lID0gZ2V0TGluZShkb2MsIHNUby5saW5lKTtcbiAgICAgIHZhciBzaW5nbGVWTGluZSA9IHZpc3VhbExpbmUoZnJvbUxpbmUpID09IHZpc3VhbExpbmUodG9MaW5lKTtcbiAgICAgIHZhciBsZWZ0RW5kID0gZHJhd0ZvckxpbmUoc0Zyb20ubGluZSwgc0Zyb20uY2gsIHNpbmdsZVZMaW5lID8gZnJvbUxpbmUudGV4dC5sZW5ndGggKyAxIDogbnVsbCkuZW5kO1xuICAgICAgdmFyIHJpZ2h0U3RhcnQgPSBkcmF3Rm9yTGluZShzVG8ubGluZSwgc2luZ2xlVkxpbmUgPyAwIDogbnVsbCwgc1RvLmNoKS5zdGFydDtcbiAgICAgIGlmIChzaW5nbGVWTGluZSkge1xuICAgICAgICBpZiAobGVmdEVuZC50b3AgPCByaWdodFN0YXJ0LnRvcCAtIDIpIHtcbiAgICAgICAgICBhZGQobGVmdEVuZC5yaWdodCwgbGVmdEVuZC50b3AsIG51bGwsIGxlZnRFbmQuYm90dG9tKTtcbiAgICAgICAgICBhZGQobGVmdFNpZGUsIHJpZ2h0U3RhcnQudG9wLCByaWdodFN0YXJ0LmxlZnQsIHJpZ2h0U3RhcnQuYm90dG9tKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBhZGQobGVmdEVuZC5yaWdodCwgbGVmdEVuZC50b3AsIHJpZ2h0U3RhcnQubGVmdCAtIGxlZnRFbmQucmlnaHQsIGxlZnRFbmQuYm90dG9tKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGxlZnRFbmQuYm90dG9tIDwgcmlnaHRTdGFydC50b3ApXG4gICAgICAgIGFkZChsZWZ0U2lkZSwgbGVmdEVuZC5ib3R0b20sIG51bGwsIHJpZ2h0U3RhcnQudG9wKTtcbiAgICB9XG5cbiAgICBvdXRwdXQuYXBwZW5kQ2hpbGQoZnJhZ21lbnQpO1xuICB9XG5cbiAgLy8gQ3Vyc29yLWJsaW5raW5nXG4gIGZ1bmN0aW9uIHJlc3RhcnRCbGluayhjbSkge1xuICAgIGlmICghY20uc3RhdGUuZm9jdXNlZCkgcmV0dXJuO1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheTtcbiAgICBjbGVhckludGVydmFsKGRpc3BsYXkuYmxpbmtlcik7XG4gICAgdmFyIG9uID0gdHJ1ZTtcbiAgICBkaXNwbGF5LmN1cnNvckRpdi5zdHlsZS52aXNpYmlsaXR5ID0gXCJcIjtcbiAgICBpZiAoY20ub3B0aW9ucy5jdXJzb3JCbGlua1JhdGUgPiAwKVxuICAgICAgZGlzcGxheS5ibGlua2VyID0gc2V0SW50ZXJ2YWwoZnVuY3Rpb24oKSB7XG4gICAgICAgIGRpc3BsYXkuY3Vyc29yRGl2LnN0eWxlLnZpc2liaWxpdHkgPSAob24gPSAhb24pID8gXCJcIiA6IFwiaGlkZGVuXCI7XG4gICAgICB9LCBjbS5vcHRpb25zLmN1cnNvckJsaW5rUmF0ZSk7XG4gICAgZWxzZSBpZiAoY20ub3B0aW9ucy5jdXJzb3JCbGlua1JhdGUgPCAwKVxuICAgICAgZGlzcGxheS5jdXJzb3JEaXYuc3R5bGUudmlzaWJpbGl0eSA9IFwiaGlkZGVuXCI7XG4gIH1cblxuICAvLyBISUdITElHSFQgV09SS0VSXG5cbiAgZnVuY3Rpb24gc3RhcnRXb3JrZXIoY20sIHRpbWUpIHtcbiAgICBpZiAoY20uZG9jLm1vZGUuc3RhcnRTdGF0ZSAmJiBjbS5kb2MuZnJvbnRpZXIgPCBjbS5kaXNwbGF5LnZpZXdUbylcbiAgICAgIGNtLnN0YXRlLmhpZ2hsaWdodC5zZXQodGltZSwgYmluZChoaWdobGlnaHRXb3JrZXIsIGNtKSk7XG4gIH1cblxuICBmdW5jdGlvbiBoaWdobGlnaHRXb3JrZXIoY20pIHtcbiAgICB2YXIgZG9jID0gY20uZG9jO1xuICAgIGlmIChkb2MuZnJvbnRpZXIgPCBkb2MuZmlyc3QpIGRvYy5mcm9udGllciA9IGRvYy5maXJzdDtcbiAgICBpZiAoZG9jLmZyb250aWVyID49IGNtLmRpc3BsYXkudmlld1RvKSByZXR1cm47XG4gICAgdmFyIGVuZCA9ICtuZXcgRGF0ZSArIGNtLm9wdGlvbnMud29ya1RpbWU7XG4gICAgdmFyIHN0YXRlID0gY29weVN0YXRlKGRvYy5tb2RlLCBnZXRTdGF0ZUJlZm9yZShjbSwgZG9jLmZyb250aWVyKSk7XG4gICAgdmFyIGNoYW5nZWRMaW5lcyA9IFtdO1xuXG4gICAgZG9jLml0ZXIoZG9jLmZyb250aWVyLCBNYXRoLm1pbihkb2MuZmlyc3QgKyBkb2Muc2l6ZSwgY20uZGlzcGxheS52aWV3VG8gKyA1MDApLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICBpZiAoZG9jLmZyb250aWVyID49IGNtLmRpc3BsYXkudmlld0Zyb20pIHsgLy8gVmlzaWJsZVxuICAgICAgICB2YXIgb2xkU3R5bGVzID0gbGluZS5zdHlsZXM7XG4gICAgICAgIHZhciBoaWdobGlnaHRlZCA9IGhpZ2hsaWdodExpbmUoY20sIGxpbmUsIHN0YXRlLCB0cnVlKTtcbiAgICAgICAgbGluZS5zdHlsZXMgPSBoaWdobGlnaHRlZC5zdHlsZXM7XG4gICAgICAgIHZhciBvbGRDbHMgPSBsaW5lLnN0eWxlQ2xhc3NlcywgbmV3Q2xzID0gaGlnaGxpZ2h0ZWQuY2xhc3NlcztcbiAgICAgICAgaWYgKG5ld0NscykgbGluZS5zdHlsZUNsYXNzZXMgPSBuZXdDbHM7XG4gICAgICAgIGVsc2UgaWYgKG9sZENscykgbGluZS5zdHlsZUNsYXNzZXMgPSBudWxsO1xuICAgICAgICB2YXIgaXNjaGFuZ2UgPSAhb2xkU3R5bGVzIHx8IG9sZFN0eWxlcy5sZW5ndGggIT0gbGluZS5zdHlsZXMubGVuZ3RoIHx8XG4gICAgICAgICAgb2xkQ2xzICE9IG5ld0NscyAmJiAoIW9sZENscyB8fCAhbmV3Q2xzIHx8IG9sZENscy5iZ0NsYXNzICE9IG5ld0Nscy5iZ0NsYXNzIHx8IG9sZENscy50ZXh0Q2xhc3MgIT0gbmV3Q2xzLnRleHRDbGFzcyk7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyAhaXNjaGFuZ2UgJiYgaSA8IG9sZFN0eWxlcy5sZW5ndGg7ICsraSkgaXNjaGFuZ2UgPSBvbGRTdHlsZXNbaV0gIT0gbGluZS5zdHlsZXNbaV07XG4gICAgICAgIGlmIChpc2NoYW5nZSkgY2hhbmdlZExpbmVzLnB1c2goZG9jLmZyb250aWVyKTtcbiAgICAgICAgbGluZS5zdGF0ZUFmdGVyID0gY29weVN0YXRlKGRvYy5tb2RlLCBzdGF0ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcm9jZXNzTGluZShjbSwgbGluZS50ZXh0LCBzdGF0ZSk7XG4gICAgICAgIGxpbmUuc3RhdGVBZnRlciA9IGRvYy5mcm9udGllciAlIDUgPT0gMCA/IGNvcHlTdGF0ZShkb2MubW9kZSwgc3RhdGUpIDogbnVsbDtcbiAgICAgIH1cbiAgICAgICsrZG9jLmZyb250aWVyO1xuICAgICAgaWYgKCtuZXcgRGF0ZSA+IGVuZCkge1xuICAgICAgICBzdGFydFdvcmtlcihjbSwgY20ub3B0aW9ucy53b3JrRGVsYXkpO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoY2hhbmdlZExpbmVzLmxlbmd0aCkgcnVuSW5PcChjbSwgZnVuY3Rpb24oKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoYW5nZWRMaW5lcy5sZW5ndGg7IGkrKylcbiAgICAgICAgcmVnTGluZUNoYW5nZShjbSwgY2hhbmdlZExpbmVzW2ldLCBcInRleHRcIik7XG4gICAgfSk7XG4gIH1cblxuICAvLyBGaW5kcyB0aGUgbGluZSB0byBzdGFydCB3aXRoIHdoZW4gc3RhcnRpbmcgYSBwYXJzZS4gVHJpZXMgdG9cbiAgLy8gZmluZCBhIGxpbmUgd2l0aCBhIHN0YXRlQWZ0ZXIsIHNvIHRoYXQgaXQgY2FuIHN0YXJ0IHdpdGggYVxuICAvLyB2YWxpZCBzdGF0ZS4gSWYgdGhhdCBmYWlscywgaXQgcmV0dXJucyB0aGUgbGluZSB3aXRoIHRoZVxuICAvLyBzbWFsbGVzdCBpbmRlbnRhdGlvbiwgd2hpY2ggdGVuZHMgdG8gbmVlZCB0aGUgbGVhc3QgY29udGV4dCB0b1xuICAvLyBwYXJzZSBjb3JyZWN0bHkuXG4gIGZ1bmN0aW9uIGZpbmRTdGFydExpbmUoY20sIG4sIHByZWNpc2UpIHtcbiAgICB2YXIgbWluaW5kZW50LCBtaW5saW5lLCBkb2MgPSBjbS5kb2M7XG4gICAgdmFyIGxpbSA9IHByZWNpc2UgPyAtMSA6IG4gLSAoY20uZG9jLm1vZGUuaW5uZXJNb2RlID8gMTAwMCA6IDEwMCk7XG4gICAgZm9yICh2YXIgc2VhcmNoID0gbjsgc2VhcmNoID4gbGltOyAtLXNlYXJjaCkge1xuICAgICAgaWYgKHNlYXJjaCA8PSBkb2MuZmlyc3QpIHJldHVybiBkb2MuZmlyc3Q7XG4gICAgICB2YXIgbGluZSA9IGdldExpbmUoZG9jLCBzZWFyY2ggLSAxKTtcbiAgICAgIGlmIChsaW5lLnN0YXRlQWZ0ZXIgJiYgKCFwcmVjaXNlIHx8IHNlYXJjaCA8PSBkb2MuZnJvbnRpZXIpKSByZXR1cm4gc2VhcmNoO1xuICAgICAgdmFyIGluZGVudGVkID0gY291bnRDb2x1bW4obGluZS50ZXh0LCBudWxsLCBjbS5vcHRpb25zLnRhYlNpemUpO1xuICAgICAgaWYgKG1pbmxpbmUgPT0gbnVsbCB8fCBtaW5pbmRlbnQgPiBpbmRlbnRlZCkge1xuICAgICAgICBtaW5saW5lID0gc2VhcmNoIC0gMTtcbiAgICAgICAgbWluaW5kZW50ID0gaW5kZW50ZWQ7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtaW5saW5lO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2V0U3RhdGVCZWZvcmUoY20sIG4sIHByZWNpc2UpIHtcbiAgICB2YXIgZG9jID0gY20uZG9jLCBkaXNwbGF5ID0gY20uZGlzcGxheTtcbiAgICBpZiAoIWRvYy5tb2RlLnN0YXJ0U3RhdGUpIHJldHVybiB0cnVlO1xuICAgIHZhciBwb3MgPSBmaW5kU3RhcnRMaW5lKGNtLCBuLCBwcmVjaXNlKSwgc3RhdGUgPSBwb3MgPiBkb2MuZmlyc3QgJiYgZ2V0TGluZShkb2MsIHBvcy0xKS5zdGF0ZUFmdGVyO1xuICAgIGlmICghc3RhdGUpIHN0YXRlID0gc3RhcnRTdGF0ZShkb2MubW9kZSk7XG4gICAgZWxzZSBzdGF0ZSA9IGNvcHlTdGF0ZShkb2MubW9kZSwgc3RhdGUpO1xuICAgIGRvYy5pdGVyKHBvcywgbiwgZnVuY3Rpb24obGluZSkge1xuICAgICAgcHJvY2Vzc0xpbmUoY20sIGxpbmUudGV4dCwgc3RhdGUpO1xuICAgICAgdmFyIHNhdmUgPSBwb3MgPT0gbiAtIDEgfHwgcG9zICUgNSA9PSAwIHx8IHBvcyA+PSBkaXNwbGF5LnZpZXdGcm9tICYmIHBvcyA8IGRpc3BsYXkudmlld1RvO1xuICAgICAgbGluZS5zdGF0ZUFmdGVyID0gc2F2ZSA/IGNvcHlTdGF0ZShkb2MubW9kZSwgc3RhdGUpIDogbnVsbDtcbiAgICAgICsrcG9zO1xuICAgIH0pO1xuICAgIGlmIChwcmVjaXNlKSBkb2MuZnJvbnRpZXIgPSBwb3M7XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgLy8gUE9TSVRJT04gTUVBU1VSRU1FTlRcblxuICBmdW5jdGlvbiBwYWRkaW5nVG9wKGRpc3BsYXkpIHtyZXR1cm4gZGlzcGxheS5saW5lU3BhY2Uub2Zmc2V0VG9wO31cbiAgZnVuY3Rpb24gcGFkZGluZ1ZlcnQoZGlzcGxheSkge3JldHVybiBkaXNwbGF5Lm1vdmVyLm9mZnNldEhlaWdodCAtIGRpc3BsYXkubGluZVNwYWNlLm9mZnNldEhlaWdodDt9XG4gIGZ1bmN0aW9uIHBhZGRpbmdIKGRpc3BsYXkpIHtcbiAgICBpZiAoZGlzcGxheS5jYWNoZWRQYWRkaW5nSCkgcmV0dXJuIGRpc3BsYXkuY2FjaGVkUGFkZGluZ0g7XG4gICAgdmFyIGUgPSByZW1vdmVDaGlsZHJlbkFuZEFkZChkaXNwbGF5Lm1lYXN1cmUsIGVsdChcInByZVwiLCBcInhcIikpO1xuICAgIHZhciBzdHlsZSA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlID8gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZSkgOiBlLmN1cnJlbnRTdHlsZTtcbiAgICB2YXIgZGF0YSA9IHtsZWZ0OiBwYXJzZUludChzdHlsZS5wYWRkaW5nTGVmdCksIHJpZ2h0OiBwYXJzZUludChzdHlsZS5wYWRkaW5nUmlnaHQpfTtcbiAgICBpZiAoIWlzTmFOKGRhdGEubGVmdCkgJiYgIWlzTmFOKGRhdGEucmlnaHQpKSBkaXNwbGF5LmNhY2hlZFBhZGRpbmdIID0gZGF0YTtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNjcm9sbEdhcChjbSkgeyByZXR1cm4gc2Nyb2xsZXJHYXAgLSBjbS5kaXNwbGF5Lm5hdGl2ZUJhcldpZHRoOyB9XG4gIGZ1bmN0aW9uIGRpc3BsYXlXaWR0aChjbSkge1xuICAgIHJldHVybiBjbS5kaXNwbGF5LnNjcm9sbGVyLmNsaWVudFdpZHRoIC0gc2Nyb2xsR2FwKGNtKSAtIGNtLmRpc3BsYXkuYmFyV2lkdGg7XG4gIH1cbiAgZnVuY3Rpb24gZGlzcGxheUhlaWdodChjbSkge1xuICAgIHJldHVybiBjbS5kaXNwbGF5LnNjcm9sbGVyLmNsaWVudEhlaWdodCAtIHNjcm9sbEdhcChjbSkgLSBjbS5kaXNwbGF5LmJhckhlaWdodDtcbiAgfVxuXG4gIC8vIEVuc3VyZSB0aGUgbGluZVZpZXcud3JhcHBpbmcuaGVpZ2h0cyBhcnJheSBpcyBwb3B1bGF0ZWQuIFRoaXMgaXNcbiAgLy8gYW4gYXJyYXkgb2YgYm90dG9tIG9mZnNldHMgZm9yIHRoZSBsaW5lcyB0aGF0IG1ha2UgdXAgYSBkcmF3blxuICAvLyBsaW5lLiBXaGVuIGxpbmVXcmFwcGluZyBpcyBvbiwgdGhlcmUgbWlnaHQgYmUgbW9yZSB0aGFuIG9uZVxuICAvLyBoZWlnaHQuXG4gIGZ1bmN0aW9uIGVuc3VyZUxpbmVIZWlnaHRzKGNtLCBsaW5lVmlldywgcmVjdCkge1xuICAgIHZhciB3cmFwcGluZyA9IGNtLm9wdGlvbnMubGluZVdyYXBwaW5nO1xuICAgIHZhciBjdXJXaWR0aCA9IHdyYXBwaW5nICYmIGRpc3BsYXlXaWR0aChjbSk7XG4gICAgaWYgKCFsaW5lVmlldy5tZWFzdXJlLmhlaWdodHMgfHwgd3JhcHBpbmcgJiYgbGluZVZpZXcubWVhc3VyZS53aWR0aCAhPSBjdXJXaWR0aCkge1xuICAgICAgdmFyIGhlaWdodHMgPSBsaW5lVmlldy5tZWFzdXJlLmhlaWdodHMgPSBbXTtcbiAgICAgIGlmICh3cmFwcGluZykge1xuICAgICAgICBsaW5lVmlldy5tZWFzdXJlLndpZHRoID0gY3VyV2lkdGg7XG4gICAgICAgIHZhciByZWN0cyA9IGxpbmVWaWV3LnRleHQuZmlyc3RDaGlsZC5nZXRDbGllbnRSZWN0cygpO1xuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJlY3RzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICAgIHZhciBjdXIgPSByZWN0c1tpXSwgbmV4dCA9IHJlY3RzW2kgKyAxXTtcbiAgICAgICAgICBpZiAoTWF0aC5hYnMoY3VyLmJvdHRvbSAtIG5leHQuYm90dG9tKSA+IDIpXG4gICAgICAgICAgICBoZWlnaHRzLnB1c2goKGN1ci5ib3R0b20gKyBuZXh0LnRvcCkgLyAyIC0gcmVjdC50b3ApO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBoZWlnaHRzLnB1c2gocmVjdC5ib3R0b20gLSByZWN0LnRvcCk7XG4gICAgfVxuICB9XG5cbiAgLy8gRmluZCBhIGxpbmUgbWFwIChtYXBwaW5nIGNoYXJhY3RlciBvZmZzZXRzIHRvIHRleHQgbm9kZXMpIGFuZCBhXG4gIC8vIG1lYXN1cmVtZW50IGNhY2hlIGZvciB0aGUgZ2l2ZW4gbGluZSBudW1iZXIuIChBIGxpbmUgdmlldyBtaWdodFxuICAvLyBjb250YWluIG11bHRpcGxlIGxpbmVzIHdoZW4gY29sbGFwc2VkIHJhbmdlcyBhcmUgcHJlc2VudC4pXG4gIGZ1bmN0aW9uIG1hcEZyb21MaW5lVmlldyhsaW5lVmlldywgbGluZSwgbGluZU4pIHtcbiAgICBpZiAobGluZVZpZXcubGluZSA9PSBsaW5lKVxuICAgICAgcmV0dXJuIHttYXA6IGxpbmVWaWV3Lm1lYXN1cmUubWFwLCBjYWNoZTogbGluZVZpZXcubWVhc3VyZS5jYWNoZX07XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lVmlldy5yZXN0Lmxlbmd0aDsgaSsrKVxuICAgICAgaWYgKGxpbmVWaWV3LnJlc3RbaV0gPT0gbGluZSlcbiAgICAgICAgcmV0dXJuIHttYXA6IGxpbmVWaWV3Lm1lYXN1cmUubWFwc1tpXSwgY2FjaGU6IGxpbmVWaWV3Lm1lYXN1cmUuY2FjaGVzW2ldfTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVWaWV3LnJlc3QubGVuZ3RoOyBpKyspXG4gICAgICBpZiAobGluZU5vKGxpbmVWaWV3LnJlc3RbaV0pID4gbGluZU4pXG4gICAgICAgIHJldHVybiB7bWFwOiBsaW5lVmlldy5tZWFzdXJlLm1hcHNbaV0sIGNhY2hlOiBsaW5lVmlldy5tZWFzdXJlLmNhY2hlc1tpXSwgYmVmb3JlOiB0cnVlfTtcbiAgfVxuXG4gIC8vIFJlbmRlciBhIGxpbmUgaW50byB0aGUgaGlkZGVuIG5vZGUgZGlzcGxheS5leHRlcm5hbE1lYXN1cmVkLiBVc2VkXG4gIC8vIHdoZW4gbWVhc3VyZW1lbnQgaXMgbmVlZGVkIGZvciBhIGxpbmUgdGhhdCdzIG5vdCBpbiB0aGUgdmlld3BvcnQuXG4gIGZ1bmN0aW9uIHVwZGF0ZUV4dGVybmFsTWVhc3VyZW1lbnQoY20sIGxpbmUpIHtcbiAgICBsaW5lID0gdmlzdWFsTGluZShsaW5lKTtcbiAgICB2YXIgbGluZU4gPSBsaW5lTm8obGluZSk7XG4gICAgdmFyIHZpZXcgPSBjbS5kaXNwbGF5LmV4dGVybmFsTWVhc3VyZWQgPSBuZXcgTGluZVZpZXcoY20uZG9jLCBsaW5lLCBsaW5lTik7XG4gICAgdmlldy5saW5lTiA9IGxpbmVOO1xuICAgIHZhciBidWlsdCA9IHZpZXcuYnVpbHQgPSBidWlsZExpbmVDb250ZW50KGNtLCB2aWV3KTtcbiAgICB2aWV3LnRleHQgPSBidWlsdC5wcmU7XG4gICAgcmVtb3ZlQ2hpbGRyZW5BbmRBZGQoY20uZGlzcGxheS5saW5lTWVhc3VyZSwgYnVpbHQucHJlKTtcbiAgICByZXR1cm4gdmlldztcbiAgfVxuXG4gIC8vIEdldCBhIHt0b3AsIGJvdHRvbSwgbGVmdCwgcmlnaHR9IGJveCAoaW4gbGluZS1sb2NhbCBjb29yZGluYXRlcylcbiAgLy8gZm9yIGEgZ2l2ZW4gY2hhcmFjdGVyLlxuICBmdW5jdGlvbiBtZWFzdXJlQ2hhcihjbSwgbGluZSwgY2gsIGJpYXMpIHtcbiAgICByZXR1cm4gbWVhc3VyZUNoYXJQcmVwYXJlZChjbSwgcHJlcGFyZU1lYXN1cmVGb3JMaW5lKGNtLCBsaW5lKSwgY2gsIGJpYXMpO1xuICB9XG5cbiAgLy8gRmluZCBhIGxpbmUgdmlldyB0aGF0IGNvcnJlc3BvbmRzIHRvIHRoZSBnaXZlbiBsaW5lIG51bWJlci5cbiAgZnVuY3Rpb24gZmluZFZpZXdGb3JMaW5lKGNtLCBsaW5lTikge1xuICAgIGlmIChsaW5lTiA+PSBjbS5kaXNwbGF5LnZpZXdGcm9tICYmIGxpbmVOIDwgY20uZGlzcGxheS52aWV3VG8pXG4gICAgICByZXR1cm4gY20uZGlzcGxheS52aWV3W2ZpbmRWaWV3SW5kZXgoY20sIGxpbmVOKV07XG4gICAgdmFyIGV4dCA9IGNtLmRpc3BsYXkuZXh0ZXJuYWxNZWFzdXJlZDtcbiAgICBpZiAoZXh0ICYmIGxpbmVOID49IGV4dC5saW5lTiAmJiBsaW5lTiA8IGV4dC5saW5lTiArIGV4dC5zaXplKVxuICAgICAgcmV0dXJuIGV4dDtcbiAgfVxuXG4gIC8vIE1lYXN1cmVtZW50IGNhbiBiZSBzcGxpdCBpbiB0d28gc3RlcHMsIHRoZSBzZXQtdXAgd29yayB0aGF0XG4gIC8vIGFwcGxpZXMgdG8gdGhlIHdob2xlIGxpbmUsIGFuZCB0aGUgbWVhc3VyZW1lbnQgb2YgdGhlIGFjdHVhbFxuICAvLyBjaGFyYWN0ZXIuIEZ1bmN0aW9ucyBsaWtlIGNvb3Jkc0NoYXIsIHRoYXQgbmVlZCB0byBkbyBhIGxvdCBvZlxuICAvLyBtZWFzdXJlbWVudHMgaW4gYSByb3csIGNhbiB0aHVzIGVuc3VyZSB0aGF0IHRoZSBzZXQtdXAgd29yayBpc1xuICAvLyBvbmx5IGRvbmUgb25jZS5cbiAgZnVuY3Rpb24gcHJlcGFyZU1lYXN1cmVGb3JMaW5lKGNtLCBsaW5lKSB7XG4gICAgdmFyIGxpbmVOID0gbGluZU5vKGxpbmUpO1xuICAgIHZhciB2aWV3ID0gZmluZFZpZXdGb3JMaW5lKGNtLCBsaW5lTik7XG4gICAgaWYgKHZpZXcgJiYgIXZpZXcudGV4dClcbiAgICAgIHZpZXcgPSBudWxsO1xuICAgIGVsc2UgaWYgKHZpZXcgJiYgdmlldy5jaGFuZ2VzKVxuICAgICAgdXBkYXRlTGluZUZvckNoYW5nZXMoY20sIHZpZXcsIGxpbmVOLCBnZXREaW1lbnNpb25zKGNtKSk7XG4gICAgaWYgKCF2aWV3KVxuICAgICAgdmlldyA9IHVwZGF0ZUV4dGVybmFsTWVhc3VyZW1lbnQoY20sIGxpbmUpO1xuXG4gICAgdmFyIGluZm8gPSBtYXBGcm9tTGluZVZpZXcodmlldywgbGluZSwgbGluZU4pO1xuICAgIHJldHVybiB7XG4gICAgICBsaW5lOiBsaW5lLCB2aWV3OiB2aWV3LCByZWN0OiBudWxsLFxuICAgICAgbWFwOiBpbmZvLm1hcCwgY2FjaGU6IGluZm8uY2FjaGUsIGJlZm9yZTogaW5mby5iZWZvcmUsXG4gICAgICBoYXNIZWlnaHRzOiBmYWxzZVxuICAgIH07XG4gIH1cblxuICAvLyBHaXZlbiBhIHByZXBhcmVkIG1lYXN1cmVtZW50IG9iamVjdCwgbWVhc3VyZXMgdGhlIHBvc2l0aW9uIG9mIGFuXG4gIC8vIGFjdHVhbCBjaGFyYWN0ZXIgKG9yIGZldGNoZXMgaXQgZnJvbSB0aGUgY2FjaGUpLlxuICBmdW5jdGlvbiBtZWFzdXJlQ2hhclByZXBhcmVkKGNtLCBwcmVwYXJlZCwgY2gsIGJpYXMsIHZhckhlaWdodCkge1xuICAgIGlmIChwcmVwYXJlZC5iZWZvcmUpIGNoID0gLTE7XG4gICAgdmFyIGtleSA9IGNoICsgKGJpYXMgfHwgXCJcIiksIGZvdW5kO1xuICAgIGlmIChwcmVwYXJlZC5jYWNoZS5oYXNPd25Qcm9wZXJ0eShrZXkpKSB7XG4gICAgICBmb3VuZCA9IHByZXBhcmVkLmNhY2hlW2tleV07XG4gICAgfSBlbHNlIHtcbiAgICAgIGlmICghcHJlcGFyZWQucmVjdClcbiAgICAgICAgcHJlcGFyZWQucmVjdCA9IHByZXBhcmVkLnZpZXcudGV4dC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGlmICghcHJlcGFyZWQuaGFzSGVpZ2h0cykge1xuICAgICAgICBlbnN1cmVMaW5lSGVpZ2h0cyhjbSwgcHJlcGFyZWQudmlldywgcHJlcGFyZWQucmVjdCk7XG4gICAgICAgIHByZXBhcmVkLmhhc0hlaWdodHMgPSB0cnVlO1xuICAgICAgfVxuICAgICAgZm91bmQgPSBtZWFzdXJlQ2hhcklubmVyKGNtLCBwcmVwYXJlZCwgY2gsIGJpYXMpO1xuICAgICAgaWYgKCFmb3VuZC5ib2d1cykgcHJlcGFyZWQuY2FjaGVba2V5XSA9IGZvdW5kO1xuICAgIH1cbiAgICByZXR1cm4ge2xlZnQ6IGZvdW5kLmxlZnQsIHJpZ2h0OiBmb3VuZC5yaWdodCxcbiAgICAgICAgICAgIHRvcDogdmFySGVpZ2h0ID8gZm91bmQucnRvcCA6IGZvdW5kLnRvcCxcbiAgICAgICAgICAgIGJvdHRvbTogdmFySGVpZ2h0ID8gZm91bmQucmJvdHRvbSA6IGZvdW5kLmJvdHRvbX07XG4gIH1cblxuICB2YXIgbnVsbFJlY3QgPSB7bGVmdDogMCwgcmlnaHQ6IDAsIHRvcDogMCwgYm90dG9tOiAwfTtcblxuICBmdW5jdGlvbiBtZWFzdXJlQ2hhcklubmVyKGNtLCBwcmVwYXJlZCwgY2gsIGJpYXMpIHtcbiAgICB2YXIgbWFwID0gcHJlcGFyZWQubWFwO1xuXG4gICAgdmFyIG5vZGUsIHN0YXJ0LCBlbmQsIGNvbGxhcHNlO1xuICAgIC8vIEZpcnN0LCBzZWFyY2ggdGhlIGxpbmUgbWFwIGZvciB0aGUgdGV4dCBub2RlIGNvcnJlc3BvbmRpbmcgdG8sXG4gICAgLy8gb3IgY2xvc2VzdCB0bywgdGhlIHRhcmdldCBjaGFyYWN0ZXIuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXAubGVuZ3RoOyBpICs9IDMpIHtcbiAgICAgIHZhciBtU3RhcnQgPSBtYXBbaV0sIG1FbmQgPSBtYXBbaSArIDFdO1xuICAgICAgaWYgKGNoIDwgbVN0YXJ0KSB7XG4gICAgICAgIHN0YXJ0ID0gMDsgZW5kID0gMTtcbiAgICAgICAgY29sbGFwc2UgPSBcImxlZnRcIjtcbiAgICAgIH0gZWxzZSBpZiAoY2ggPCBtRW5kKSB7XG4gICAgICAgIHN0YXJ0ID0gY2ggLSBtU3RhcnQ7XG4gICAgICAgIGVuZCA9IHN0YXJ0ICsgMTtcbiAgICAgIH0gZWxzZSBpZiAoaSA9PSBtYXAubGVuZ3RoIC0gMyB8fCBjaCA9PSBtRW5kICYmIG1hcFtpICsgM10gPiBjaCkge1xuICAgICAgICBlbmQgPSBtRW5kIC0gbVN0YXJ0O1xuICAgICAgICBzdGFydCA9IGVuZCAtIDE7XG4gICAgICAgIGlmIChjaCA+PSBtRW5kKSBjb2xsYXBzZSA9IFwicmlnaHRcIjtcbiAgICAgIH1cbiAgICAgIGlmIChzdGFydCAhPSBudWxsKSB7XG4gICAgICAgIG5vZGUgPSBtYXBbaSArIDJdO1xuICAgICAgICBpZiAobVN0YXJ0ID09IG1FbmQgJiYgYmlhcyA9PSAobm9kZS5pbnNlcnRMZWZ0ID8gXCJsZWZ0XCIgOiBcInJpZ2h0XCIpKVxuICAgICAgICAgIGNvbGxhcHNlID0gYmlhcztcbiAgICAgICAgaWYgKGJpYXMgPT0gXCJsZWZ0XCIgJiYgc3RhcnQgPT0gMClcbiAgICAgICAgICB3aGlsZSAoaSAmJiBtYXBbaSAtIDJdID09IG1hcFtpIC0gM10gJiYgbWFwW2kgLSAxXS5pbnNlcnRMZWZ0KSB7XG4gICAgICAgICAgICBub2RlID0gbWFwWyhpIC09IDMpICsgMl07XG4gICAgICAgICAgICBjb2xsYXBzZSA9IFwibGVmdFwiO1xuICAgICAgICAgIH1cbiAgICAgICAgaWYgKGJpYXMgPT0gXCJyaWdodFwiICYmIHN0YXJ0ID09IG1FbmQgLSBtU3RhcnQpXG4gICAgICAgICAgd2hpbGUgKGkgPCBtYXAubGVuZ3RoIC0gMyAmJiBtYXBbaSArIDNdID09IG1hcFtpICsgNF0gJiYgIW1hcFtpICsgNV0uaW5zZXJ0TGVmdCkge1xuICAgICAgICAgICAgbm9kZSA9IG1hcFsoaSArPSAzKSArIDJdO1xuICAgICAgICAgICAgY29sbGFwc2UgPSBcInJpZ2h0XCI7XG4gICAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG5cbiAgICB2YXIgcmVjdDtcbiAgICBpZiAobm9kZS5ub2RlVHlwZSA9PSAzKSB7IC8vIElmIGl0IGlzIGEgdGV4dCBub2RlLCB1c2UgYSByYW5nZSB0byByZXRyaWV2ZSB0aGUgY29vcmRpbmF0ZXMuXG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7IGkrKykgeyAvLyBSZXRyeSBhIG1heGltdW0gb2YgNCB0aW1lcyB3aGVuIG5vbnNlbnNlIHJlY3RhbmdsZXMgYXJlIHJldHVybmVkXG4gICAgICAgIHdoaWxlIChzdGFydCAmJiBpc0V4dGVuZGluZ0NoYXIocHJlcGFyZWQubGluZS50ZXh0LmNoYXJBdChtU3RhcnQgKyBzdGFydCkpKSAtLXN0YXJ0O1xuICAgICAgICB3aGlsZSAobVN0YXJ0ICsgZW5kIDwgbUVuZCAmJiBpc0V4dGVuZGluZ0NoYXIocHJlcGFyZWQubGluZS50ZXh0LmNoYXJBdChtU3RhcnQgKyBlbmQpKSkgKytlbmQ7XG4gICAgICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDwgOSAmJiBzdGFydCA9PSAwICYmIGVuZCA9PSBtRW5kIC0gbVN0YXJ0KSB7XG4gICAgICAgICAgcmVjdCA9IG5vZGUucGFyZW50Tm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgfSBlbHNlIGlmIChpZSAmJiBjbS5vcHRpb25zLmxpbmVXcmFwcGluZykge1xuICAgICAgICAgIHZhciByZWN0cyA9IHJhbmdlKG5vZGUsIHN0YXJ0LCBlbmQpLmdldENsaWVudFJlY3RzKCk7XG4gICAgICAgICAgaWYgKHJlY3RzLmxlbmd0aClcbiAgICAgICAgICAgIHJlY3QgPSByZWN0c1tiaWFzID09IFwicmlnaHRcIiA/IHJlY3RzLmxlbmd0aCAtIDEgOiAwXTtcbiAgICAgICAgICBlbHNlXG4gICAgICAgICAgICByZWN0ID0gbnVsbFJlY3Q7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVjdCA9IHJhbmdlKG5vZGUsIHN0YXJ0LCBlbmQpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIHx8IG51bGxSZWN0O1xuICAgICAgICB9XG4gICAgICAgIGlmIChyZWN0LmxlZnQgfHwgcmVjdC5yaWdodCB8fCBzdGFydCA9PSAwKSBicmVhaztcbiAgICAgICAgZW5kID0gc3RhcnQ7XG4gICAgICAgIHN0YXJ0ID0gc3RhcnQgLSAxO1xuICAgICAgICBjb2xsYXBzZSA9IFwicmlnaHRcIjtcbiAgICAgIH1cbiAgICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDwgMTEpIHJlY3QgPSBtYXliZVVwZGF0ZVJlY3RGb3Jab29taW5nKGNtLmRpc3BsYXkubWVhc3VyZSwgcmVjdCk7XG4gICAgfSBlbHNlIHsgLy8gSWYgaXQgaXMgYSB3aWRnZXQsIHNpbXBseSBnZXQgdGhlIGJveCBmb3IgdGhlIHdob2xlIHdpZGdldC5cbiAgICAgIGlmIChzdGFydCA+IDApIGNvbGxhcHNlID0gYmlhcyA9IFwicmlnaHRcIjtcbiAgICAgIHZhciByZWN0cztcbiAgICAgIGlmIChjbS5vcHRpb25zLmxpbmVXcmFwcGluZyAmJiAocmVjdHMgPSBub2RlLmdldENsaWVudFJlY3RzKCkpLmxlbmd0aCA+IDEpXG4gICAgICAgIHJlY3QgPSByZWN0c1tiaWFzID09IFwicmlnaHRcIiA/IHJlY3RzLmxlbmd0aCAtIDEgOiAwXTtcbiAgICAgIGVsc2VcbiAgICAgICAgcmVjdCA9IG5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDwgOSAmJiAhc3RhcnQgJiYgKCFyZWN0IHx8ICFyZWN0LmxlZnQgJiYgIXJlY3QucmlnaHQpKSB7XG4gICAgICB2YXIgclNwYW4gPSBub2RlLnBhcmVudE5vZGUuZ2V0Q2xpZW50UmVjdHMoKVswXTtcbiAgICAgIGlmIChyU3BhbilcbiAgICAgICAgcmVjdCA9IHtsZWZ0OiByU3Bhbi5sZWZ0LCByaWdodDogclNwYW4ubGVmdCArIGNoYXJXaWR0aChjbS5kaXNwbGF5KSwgdG9wOiByU3Bhbi50b3AsIGJvdHRvbTogclNwYW4uYm90dG9tfTtcbiAgICAgIGVsc2VcbiAgICAgICAgcmVjdCA9IG51bGxSZWN0O1xuICAgIH1cblxuICAgIHZhciBydG9wID0gcmVjdC50b3AgLSBwcmVwYXJlZC5yZWN0LnRvcCwgcmJvdCA9IHJlY3QuYm90dG9tIC0gcHJlcGFyZWQucmVjdC50b3A7XG4gICAgdmFyIG1pZCA9IChydG9wICsgcmJvdCkgLyAyO1xuICAgIHZhciBoZWlnaHRzID0gcHJlcGFyZWQudmlldy5tZWFzdXJlLmhlaWdodHM7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZWlnaHRzLmxlbmd0aCAtIDE7IGkrKylcbiAgICAgIGlmIChtaWQgPCBoZWlnaHRzW2ldKSBicmVhaztcbiAgICB2YXIgdG9wID0gaSA/IGhlaWdodHNbaSAtIDFdIDogMCwgYm90ID0gaGVpZ2h0c1tpXTtcbiAgICB2YXIgcmVzdWx0ID0ge2xlZnQ6IChjb2xsYXBzZSA9PSBcInJpZ2h0XCIgPyByZWN0LnJpZ2h0IDogcmVjdC5sZWZ0KSAtIHByZXBhcmVkLnJlY3QubGVmdCxcbiAgICAgICAgICAgICAgICAgIHJpZ2h0OiAoY29sbGFwc2UgPT0gXCJsZWZ0XCIgPyByZWN0LmxlZnQgOiByZWN0LnJpZ2h0KSAtIHByZXBhcmVkLnJlY3QubGVmdCxcbiAgICAgICAgICAgICAgICAgIHRvcDogdG9wLCBib3R0b206IGJvdH07XG4gICAgaWYgKCFyZWN0LmxlZnQgJiYgIXJlY3QucmlnaHQpIHJlc3VsdC5ib2d1cyA9IHRydWU7XG4gICAgaWYgKCFjbS5vcHRpb25zLnNpbmdsZUN1cnNvckhlaWdodFBlckxpbmUpIHsgcmVzdWx0LnJ0b3AgPSBydG9wOyByZXN1bHQucmJvdHRvbSA9IHJib3Q7IH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvLyBXb3JrIGFyb3VuZCBwcm9ibGVtIHdpdGggYm91bmRpbmcgY2xpZW50IHJlY3RzIG9uIHJhbmdlcyBiZWluZ1xuICAvLyByZXR1cm5lZCBpbmNvcnJlY3RseSB3aGVuIHpvb21lZCBvbiBJRTEwIGFuZCBiZWxvdy5cbiAgZnVuY3Rpb24gbWF5YmVVcGRhdGVSZWN0Rm9yWm9vbWluZyhtZWFzdXJlLCByZWN0KSB7XG4gICAgaWYgKCF3aW5kb3cuc2NyZWVuIHx8IHNjcmVlbi5sb2dpY2FsWERQSSA9PSBudWxsIHx8XG4gICAgICAgIHNjcmVlbi5sb2dpY2FsWERQSSA9PSBzY3JlZW4uZGV2aWNlWERQSSB8fCAhaGFzQmFkWm9vbWVkUmVjdHMobWVhc3VyZSkpXG4gICAgICByZXR1cm4gcmVjdDtcbiAgICB2YXIgc2NhbGVYID0gc2NyZWVuLmxvZ2ljYWxYRFBJIC8gc2NyZWVuLmRldmljZVhEUEk7XG4gICAgdmFyIHNjYWxlWSA9IHNjcmVlbi5sb2dpY2FsWURQSSAvIHNjcmVlbi5kZXZpY2VZRFBJO1xuICAgIHJldHVybiB7bGVmdDogcmVjdC5sZWZ0ICogc2NhbGVYLCByaWdodDogcmVjdC5yaWdodCAqIHNjYWxlWCxcbiAgICAgICAgICAgIHRvcDogcmVjdC50b3AgKiBzY2FsZVksIGJvdHRvbTogcmVjdC5ib3R0b20gKiBzY2FsZVl9O1xuICB9XG5cbiAgZnVuY3Rpb24gY2xlYXJMaW5lTWVhc3VyZW1lbnRDYWNoZUZvcihsaW5lVmlldykge1xuICAgIGlmIChsaW5lVmlldy5tZWFzdXJlKSB7XG4gICAgICBsaW5lVmlldy5tZWFzdXJlLmNhY2hlID0ge307XG4gICAgICBsaW5lVmlldy5tZWFzdXJlLmhlaWdodHMgPSBudWxsO1xuICAgICAgaWYgKGxpbmVWaWV3LnJlc3QpIGZvciAodmFyIGkgPSAwOyBpIDwgbGluZVZpZXcucmVzdC5sZW5ndGg7IGkrKylcbiAgICAgICAgbGluZVZpZXcubWVhc3VyZS5jYWNoZXNbaV0gPSB7fTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjbGVhckxpbmVNZWFzdXJlbWVudENhY2hlKGNtKSB7XG4gICAgY20uZGlzcGxheS5leHRlcm5hbE1lYXN1cmUgPSBudWxsO1xuICAgIHJlbW92ZUNoaWxkcmVuKGNtLmRpc3BsYXkubGluZU1lYXN1cmUpO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgY20uZGlzcGxheS52aWV3Lmxlbmd0aDsgaSsrKVxuICAgICAgY2xlYXJMaW5lTWVhc3VyZW1lbnRDYWNoZUZvcihjbS5kaXNwbGF5LnZpZXdbaV0pO1xuICB9XG5cbiAgZnVuY3Rpb24gY2xlYXJDYWNoZXMoY20pIHtcbiAgICBjbGVhckxpbmVNZWFzdXJlbWVudENhY2hlKGNtKTtcbiAgICBjbS5kaXNwbGF5LmNhY2hlZENoYXJXaWR0aCA9IGNtLmRpc3BsYXkuY2FjaGVkVGV4dEhlaWdodCA9IGNtLmRpc3BsYXkuY2FjaGVkUGFkZGluZ0ggPSBudWxsO1xuICAgIGlmICghY20ub3B0aW9ucy5saW5lV3JhcHBpbmcpIGNtLmRpc3BsYXkubWF4TGluZUNoYW5nZWQgPSB0cnVlO1xuICAgIGNtLmRpc3BsYXkubGluZU51bUNoYXJzID0gbnVsbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhZ2VTY3JvbGxYKCkgeyByZXR1cm4gd2luZG93LnBhZ2VYT2Zmc2V0IHx8IChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQgfHwgZG9jdW1lbnQuYm9keSkuc2Nyb2xsTGVmdDsgfVxuICBmdW5jdGlvbiBwYWdlU2Nyb2xsWSgpIHsgcmV0dXJuIHdpbmRvdy5wYWdlWU9mZnNldCB8fCAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IHx8IGRvY3VtZW50LmJvZHkpLnNjcm9sbFRvcDsgfVxuXG4gIC8vIENvbnZlcnRzIGEge3RvcCwgYm90dG9tLCBsZWZ0LCByaWdodH0gYm94IGZyb20gbGluZS1sb2NhbFxuICAvLyBjb29yZGluYXRlcyBpbnRvIGFub3RoZXIgY29vcmRpbmF0ZSBzeXN0ZW0uIENvbnRleHQgbWF5IGJlIG9uZSBvZlxuICAvLyBcImxpbmVcIiwgXCJkaXZcIiAoZGlzcGxheS5saW5lRGl2KSwgXCJsb2NhbFwiL251bGwgKGVkaXRvciksIFwid2luZG93XCIsXG4gIC8vIG9yIFwicGFnZVwiLlxuICBmdW5jdGlvbiBpbnRvQ29vcmRTeXN0ZW0oY20sIGxpbmVPYmosIHJlY3QsIGNvbnRleHQpIHtcbiAgICBpZiAobGluZU9iai53aWRnZXRzKSBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVPYmoud2lkZ2V0cy5sZW5ndGg7ICsraSkgaWYgKGxpbmVPYmoud2lkZ2V0c1tpXS5hYm92ZSkge1xuICAgICAgdmFyIHNpemUgPSB3aWRnZXRIZWlnaHQobGluZU9iai53aWRnZXRzW2ldKTtcbiAgICAgIHJlY3QudG9wICs9IHNpemU7IHJlY3QuYm90dG9tICs9IHNpemU7XG4gICAgfVxuICAgIGlmIChjb250ZXh0ID09IFwibGluZVwiKSByZXR1cm4gcmVjdDtcbiAgICBpZiAoIWNvbnRleHQpIGNvbnRleHQgPSBcImxvY2FsXCI7XG4gICAgdmFyIHlPZmYgPSBoZWlnaHRBdExpbmUobGluZU9iaik7XG4gICAgaWYgKGNvbnRleHQgPT0gXCJsb2NhbFwiKSB5T2ZmICs9IHBhZGRpbmdUb3AoY20uZGlzcGxheSk7XG4gICAgZWxzZSB5T2ZmIC09IGNtLmRpc3BsYXkudmlld09mZnNldDtcbiAgICBpZiAoY29udGV4dCA9PSBcInBhZ2VcIiB8fCBjb250ZXh0ID09IFwid2luZG93XCIpIHtcbiAgICAgIHZhciBsT2ZmID0gY20uZGlzcGxheS5saW5lU3BhY2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICB5T2ZmICs9IGxPZmYudG9wICsgKGNvbnRleHQgPT0gXCJ3aW5kb3dcIiA/IDAgOiBwYWdlU2Nyb2xsWSgpKTtcbiAgICAgIHZhciB4T2ZmID0gbE9mZi5sZWZ0ICsgKGNvbnRleHQgPT0gXCJ3aW5kb3dcIiA/IDAgOiBwYWdlU2Nyb2xsWCgpKTtcbiAgICAgIHJlY3QubGVmdCArPSB4T2ZmOyByZWN0LnJpZ2h0ICs9IHhPZmY7XG4gICAgfVxuICAgIHJlY3QudG9wICs9IHlPZmY7IHJlY3QuYm90dG9tICs9IHlPZmY7XG4gICAgcmV0dXJuIHJlY3Q7XG4gIH1cblxuICAvLyBDb3ZlcnRzIGEgYm94IGZyb20gXCJkaXZcIiBjb29yZHMgdG8gYW5vdGhlciBjb29yZGluYXRlIHN5c3RlbS5cbiAgLy8gQ29udGV4dCBtYXkgYmUgXCJ3aW5kb3dcIiwgXCJwYWdlXCIsIFwiZGl2XCIsIG9yIFwibG9jYWxcIi9udWxsLlxuICBmdW5jdGlvbiBmcm9tQ29vcmRTeXN0ZW0oY20sIGNvb3JkcywgY29udGV4dCkge1xuICAgIGlmIChjb250ZXh0ID09IFwiZGl2XCIpIHJldHVybiBjb29yZHM7XG4gICAgdmFyIGxlZnQgPSBjb29yZHMubGVmdCwgdG9wID0gY29vcmRzLnRvcDtcbiAgICAvLyBGaXJzdCBtb3ZlIGludG8gXCJwYWdlXCIgY29vcmRpbmF0ZSBzeXN0ZW1cbiAgICBpZiAoY29udGV4dCA9PSBcInBhZ2VcIikge1xuICAgICAgbGVmdCAtPSBwYWdlU2Nyb2xsWCgpO1xuICAgICAgdG9wIC09IHBhZ2VTY3JvbGxZKCk7XG4gICAgfSBlbHNlIGlmIChjb250ZXh0ID09IFwibG9jYWxcIiB8fCAhY29udGV4dCkge1xuICAgICAgdmFyIGxvY2FsQm94ID0gY20uZGlzcGxheS5zaXplci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIGxlZnQgKz0gbG9jYWxCb3gubGVmdDtcbiAgICAgIHRvcCArPSBsb2NhbEJveC50b3A7XG4gICAgfVxuXG4gICAgdmFyIGxpbmVTcGFjZUJveCA9IGNtLmRpc3BsYXkubGluZVNwYWNlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiB7bGVmdDogbGVmdCAtIGxpbmVTcGFjZUJveC5sZWZ0LCB0b3A6IHRvcCAtIGxpbmVTcGFjZUJveC50b3B9O1xuICB9XG5cbiAgZnVuY3Rpb24gY2hhckNvb3JkcyhjbSwgcG9zLCBjb250ZXh0LCBsaW5lT2JqLCBiaWFzKSB7XG4gICAgaWYgKCFsaW5lT2JqKSBsaW5lT2JqID0gZ2V0TGluZShjbS5kb2MsIHBvcy5saW5lKTtcbiAgICByZXR1cm4gaW50b0Nvb3JkU3lzdGVtKGNtLCBsaW5lT2JqLCBtZWFzdXJlQ2hhcihjbSwgbGluZU9iaiwgcG9zLmNoLCBiaWFzKSwgY29udGV4dCk7XG4gIH1cblxuICAvLyBSZXR1cm5zIGEgYm94IGZvciBhIGdpdmVuIGN1cnNvciBwb3NpdGlvbiwgd2hpY2ggbWF5IGhhdmUgYW5cbiAgLy8gJ290aGVyJyBwcm9wZXJ0eSBjb250YWluaW5nIHRoZSBwb3NpdGlvbiBvZiB0aGUgc2Vjb25kYXJ5IGN1cnNvclxuICAvLyBvbiBhIGJpZGkgYm91bmRhcnkuXG4gIGZ1bmN0aW9uIGN1cnNvckNvb3JkcyhjbSwgcG9zLCBjb250ZXh0LCBsaW5lT2JqLCBwcmVwYXJlZE1lYXN1cmUsIHZhckhlaWdodCkge1xuICAgIGxpbmVPYmogPSBsaW5lT2JqIHx8IGdldExpbmUoY20uZG9jLCBwb3MubGluZSk7XG4gICAgaWYgKCFwcmVwYXJlZE1lYXN1cmUpIHByZXBhcmVkTWVhc3VyZSA9IHByZXBhcmVNZWFzdXJlRm9yTGluZShjbSwgbGluZU9iaik7XG4gICAgZnVuY3Rpb24gZ2V0KGNoLCByaWdodCkge1xuICAgICAgdmFyIG0gPSBtZWFzdXJlQ2hhclByZXBhcmVkKGNtLCBwcmVwYXJlZE1lYXN1cmUsIGNoLCByaWdodCA/IFwicmlnaHRcIiA6IFwibGVmdFwiLCB2YXJIZWlnaHQpO1xuICAgICAgaWYgKHJpZ2h0KSBtLmxlZnQgPSBtLnJpZ2h0OyBlbHNlIG0ucmlnaHQgPSBtLmxlZnQ7XG4gICAgICByZXR1cm4gaW50b0Nvb3JkU3lzdGVtKGNtLCBsaW5lT2JqLCBtLCBjb250ZXh0KTtcbiAgICB9XG4gICAgZnVuY3Rpb24gZ2V0QmlkaShjaCwgcGFydFBvcykge1xuICAgICAgdmFyIHBhcnQgPSBvcmRlcltwYXJ0UG9zXSwgcmlnaHQgPSBwYXJ0LmxldmVsICUgMjtcbiAgICAgIGlmIChjaCA9PSBiaWRpTGVmdChwYXJ0KSAmJiBwYXJ0UG9zICYmIHBhcnQubGV2ZWwgPCBvcmRlcltwYXJ0UG9zIC0gMV0ubGV2ZWwpIHtcbiAgICAgICAgcGFydCA9IG9yZGVyWy0tcGFydFBvc107XG4gICAgICAgIGNoID0gYmlkaVJpZ2h0KHBhcnQpIC0gKHBhcnQubGV2ZWwgJSAyID8gMCA6IDEpO1xuICAgICAgICByaWdodCA9IHRydWU7XG4gICAgICB9IGVsc2UgaWYgKGNoID09IGJpZGlSaWdodChwYXJ0KSAmJiBwYXJ0UG9zIDwgb3JkZXIubGVuZ3RoIC0gMSAmJiBwYXJ0LmxldmVsIDwgb3JkZXJbcGFydFBvcyArIDFdLmxldmVsKSB7XG4gICAgICAgIHBhcnQgPSBvcmRlclsrK3BhcnRQb3NdO1xuICAgICAgICBjaCA9IGJpZGlMZWZ0KHBhcnQpIC0gcGFydC5sZXZlbCAlIDI7XG4gICAgICAgIHJpZ2h0ID0gZmFsc2U7XG4gICAgICB9XG4gICAgICBpZiAocmlnaHQgJiYgY2ggPT0gcGFydC50byAmJiBjaCA+IHBhcnQuZnJvbSkgcmV0dXJuIGdldChjaCAtIDEpO1xuICAgICAgcmV0dXJuIGdldChjaCwgcmlnaHQpO1xuICAgIH1cbiAgICB2YXIgb3JkZXIgPSBnZXRPcmRlcihsaW5lT2JqKSwgY2ggPSBwb3MuY2g7XG4gICAgaWYgKCFvcmRlcikgcmV0dXJuIGdldChjaCk7XG4gICAgdmFyIHBhcnRQb3MgPSBnZXRCaWRpUGFydEF0KG9yZGVyLCBjaCk7XG4gICAgdmFyIHZhbCA9IGdldEJpZGkoY2gsIHBhcnRQb3MpO1xuICAgIGlmIChiaWRpT3RoZXIgIT0gbnVsbCkgdmFsLm90aGVyID0gZ2V0QmlkaShjaCwgYmlkaU90aGVyKTtcbiAgICByZXR1cm4gdmFsO1xuICB9XG5cbiAgLy8gVXNlZCB0byBjaGVhcGx5IGVzdGltYXRlIHRoZSBjb29yZGluYXRlcyBmb3IgYSBwb3NpdGlvbi4gVXNlZCBmb3JcbiAgLy8gaW50ZXJtZWRpYXRlIHNjcm9sbCB1cGRhdGVzLlxuICBmdW5jdGlvbiBlc3RpbWF0ZUNvb3JkcyhjbSwgcG9zKSB7XG4gICAgdmFyIGxlZnQgPSAwLCBwb3MgPSBjbGlwUG9zKGNtLmRvYywgcG9zKTtcbiAgICBpZiAoIWNtLm9wdGlvbnMubGluZVdyYXBwaW5nKSBsZWZ0ID0gY2hhcldpZHRoKGNtLmRpc3BsYXkpICogcG9zLmNoO1xuICAgIHZhciBsaW5lT2JqID0gZ2V0TGluZShjbS5kb2MsIHBvcy5saW5lKTtcbiAgICB2YXIgdG9wID0gaGVpZ2h0QXRMaW5lKGxpbmVPYmopICsgcGFkZGluZ1RvcChjbS5kaXNwbGF5KTtcbiAgICByZXR1cm4ge2xlZnQ6IGxlZnQsIHJpZ2h0OiBsZWZ0LCB0b3A6IHRvcCwgYm90dG9tOiB0b3AgKyBsaW5lT2JqLmhlaWdodH07XG4gIH1cblxuICAvLyBQb3NpdGlvbnMgcmV0dXJuZWQgYnkgY29vcmRzQ2hhciBjb250YWluIHNvbWUgZXh0cmEgaW5mb3JtYXRpb24uXG4gIC8vIHhSZWwgaXMgdGhlIHJlbGF0aXZlIHggcG9zaXRpb24gb2YgdGhlIGlucHV0IGNvb3JkaW5hdGVzIGNvbXBhcmVkXG4gIC8vIHRvIHRoZSBmb3VuZCBwb3NpdGlvbiAoc28geFJlbCA+IDAgbWVhbnMgdGhlIGNvb3JkaW5hdGVzIGFyZSB0b1xuICAvLyB0aGUgcmlnaHQgb2YgdGhlIGNoYXJhY3RlciBwb3NpdGlvbiwgZm9yIGV4YW1wbGUpLiBXaGVuIG91dHNpZGVcbiAgLy8gaXMgdHJ1ZSwgdGhhdCBtZWFucyB0aGUgY29vcmRpbmF0ZXMgbGllIG91dHNpZGUgdGhlIGxpbmUnc1xuICAvLyB2ZXJ0aWNhbCByYW5nZS5cbiAgZnVuY3Rpb24gUG9zV2l0aEluZm8obGluZSwgY2gsIG91dHNpZGUsIHhSZWwpIHtcbiAgICB2YXIgcG9zID0gUG9zKGxpbmUsIGNoKTtcbiAgICBwb3MueFJlbCA9IHhSZWw7XG4gICAgaWYgKG91dHNpZGUpIHBvcy5vdXRzaWRlID0gdHJ1ZTtcbiAgICByZXR1cm4gcG9zO1xuICB9XG5cbiAgLy8gQ29tcHV0ZSB0aGUgY2hhcmFjdGVyIHBvc2l0aW9uIGNsb3Nlc3QgdG8gdGhlIGdpdmVuIGNvb3JkaW5hdGVzLlxuICAvLyBJbnB1dCBtdXN0IGJlIGxpbmVTcGFjZS1sb2NhbCAoXCJkaXZcIiBjb29yZGluYXRlIHN5c3RlbSkuXG4gIGZ1bmN0aW9uIGNvb3Jkc0NoYXIoY20sIHgsIHkpIHtcbiAgICB2YXIgZG9jID0gY20uZG9jO1xuICAgIHkgKz0gY20uZGlzcGxheS52aWV3T2Zmc2V0O1xuICAgIGlmICh5IDwgMCkgcmV0dXJuIFBvc1dpdGhJbmZvKGRvYy5maXJzdCwgMCwgdHJ1ZSwgLTEpO1xuICAgIHZhciBsaW5lTiA9IGxpbmVBdEhlaWdodChkb2MsIHkpLCBsYXN0ID0gZG9jLmZpcnN0ICsgZG9jLnNpemUgLSAxO1xuICAgIGlmIChsaW5lTiA+IGxhc3QpXG4gICAgICByZXR1cm4gUG9zV2l0aEluZm8oZG9jLmZpcnN0ICsgZG9jLnNpemUgLSAxLCBnZXRMaW5lKGRvYywgbGFzdCkudGV4dC5sZW5ndGgsIHRydWUsIDEpO1xuICAgIGlmICh4IDwgMCkgeCA9IDA7XG5cbiAgICB2YXIgbGluZU9iaiA9IGdldExpbmUoZG9jLCBsaW5lTik7XG4gICAgZm9yICg7Oykge1xuICAgICAgdmFyIGZvdW5kID0gY29vcmRzQ2hhcklubmVyKGNtLCBsaW5lT2JqLCBsaW5lTiwgeCwgeSk7XG4gICAgICB2YXIgbWVyZ2VkID0gY29sbGFwc2VkU3BhbkF0RW5kKGxpbmVPYmopO1xuICAgICAgdmFyIG1lcmdlZFBvcyA9IG1lcmdlZCAmJiBtZXJnZWQuZmluZCgwLCB0cnVlKTtcbiAgICAgIGlmIChtZXJnZWQgJiYgKGZvdW5kLmNoID4gbWVyZ2VkUG9zLmZyb20uY2ggfHwgZm91bmQuY2ggPT0gbWVyZ2VkUG9zLmZyb20uY2ggJiYgZm91bmQueFJlbCA+IDApKVxuICAgICAgICBsaW5lTiA9IGxpbmVObyhsaW5lT2JqID0gbWVyZ2VkUG9zLnRvLmxpbmUpO1xuICAgICAgZWxzZVxuICAgICAgICByZXR1cm4gZm91bmQ7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY29vcmRzQ2hhcklubmVyKGNtLCBsaW5lT2JqLCBsaW5lTm8sIHgsIHkpIHtcbiAgICB2YXIgaW5uZXJPZmYgPSB5IC0gaGVpZ2h0QXRMaW5lKGxpbmVPYmopO1xuICAgIHZhciB3cm9uZ0xpbmUgPSBmYWxzZSwgYWRqdXN0ID0gMiAqIGNtLmRpc3BsYXkud3JhcHBlci5jbGllbnRXaWR0aDtcbiAgICB2YXIgcHJlcGFyZWRNZWFzdXJlID0gcHJlcGFyZU1lYXN1cmVGb3JMaW5lKGNtLCBsaW5lT2JqKTtcblxuICAgIGZ1bmN0aW9uIGdldFgoY2gpIHtcbiAgICAgIHZhciBzcCA9IGN1cnNvckNvb3JkcyhjbSwgUG9zKGxpbmVObywgY2gpLCBcImxpbmVcIiwgbGluZU9iaiwgcHJlcGFyZWRNZWFzdXJlKTtcbiAgICAgIHdyb25nTGluZSA9IHRydWU7XG4gICAgICBpZiAoaW5uZXJPZmYgPiBzcC5ib3R0b20pIHJldHVybiBzcC5sZWZ0IC0gYWRqdXN0O1xuICAgICAgZWxzZSBpZiAoaW5uZXJPZmYgPCBzcC50b3ApIHJldHVybiBzcC5sZWZ0ICsgYWRqdXN0O1xuICAgICAgZWxzZSB3cm9uZ0xpbmUgPSBmYWxzZTtcbiAgICAgIHJldHVybiBzcC5sZWZ0O1xuICAgIH1cblxuICAgIHZhciBiaWRpID0gZ2V0T3JkZXIobGluZU9iaiksIGRpc3QgPSBsaW5lT2JqLnRleHQubGVuZ3RoO1xuICAgIHZhciBmcm9tID0gbGluZUxlZnQobGluZU9iaiksIHRvID0gbGluZVJpZ2h0KGxpbmVPYmopO1xuICAgIHZhciBmcm9tWCA9IGdldFgoZnJvbSksIGZyb21PdXRzaWRlID0gd3JvbmdMaW5lLCB0b1ggPSBnZXRYKHRvKSwgdG9PdXRzaWRlID0gd3JvbmdMaW5lO1xuXG4gICAgaWYgKHggPiB0b1gpIHJldHVybiBQb3NXaXRoSW5mbyhsaW5lTm8sIHRvLCB0b091dHNpZGUsIDEpO1xuICAgIC8vIERvIGEgYmluYXJ5IHNlYXJjaCBiZXR3ZWVuIHRoZXNlIGJvdW5kcy5cbiAgICBmb3IgKDs7KSB7XG4gICAgICBpZiAoYmlkaSA/IHRvID09IGZyb20gfHwgdG8gPT0gbW92ZVZpc3VhbGx5KGxpbmVPYmosIGZyb20sIDEpIDogdG8gLSBmcm9tIDw9IDEpIHtcbiAgICAgICAgdmFyIGNoID0geCA8IGZyb21YIHx8IHggLSBmcm9tWCA8PSB0b1ggLSB4ID8gZnJvbSA6IHRvO1xuICAgICAgICB2YXIgeERpZmYgPSB4IC0gKGNoID09IGZyb20gPyBmcm9tWCA6IHRvWCk7XG4gICAgICAgIHdoaWxlIChpc0V4dGVuZGluZ0NoYXIobGluZU9iai50ZXh0LmNoYXJBdChjaCkpKSArK2NoO1xuICAgICAgICB2YXIgcG9zID0gUG9zV2l0aEluZm8obGluZU5vLCBjaCwgY2ggPT0gZnJvbSA/IGZyb21PdXRzaWRlIDogdG9PdXRzaWRlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeERpZmYgPCAtMSA/IC0xIDogeERpZmYgPiAxID8gMSA6IDApO1xuICAgICAgICByZXR1cm4gcG9zO1xuICAgICAgfVxuICAgICAgdmFyIHN0ZXAgPSBNYXRoLmNlaWwoZGlzdCAvIDIpLCBtaWRkbGUgPSBmcm9tICsgc3RlcDtcbiAgICAgIGlmIChiaWRpKSB7XG4gICAgICAgIG1pZGRsZSA9IGZyb207XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3RlcDsgKytpKSBtaWRkbGUgPSBtb3ZlVmlzdWFsbHkobGluZU9iaiwgbWlkZGxlLCAxKTtcbiAgICAgIH1cbiAgICAgIHZhciBtaWRkbGVYID0gZ2V0WChtaWRkbGUpO1xuICAgICAgaWYgKG1pZGRsZVggPiB4KSB7dG8gPSBtaWRkbGU7IHRvWCA9IG1pZGRsZVg7IGlmICh0b091dHNpZGUgPSB3cm9uZ0xpbmUpIHRvWCArPSAxMDAwOyBkaXN0ID0gc3RlcDt9XG4gICAgICBlbHNlIHtmcm9tID0gbWlkZGxlOyBmcm9tWCA9IG1pZGRsZVg7IGZyb21PdXRzaWRlID0gd3JvbmdMaW5lOyBkaXN0IC09IHN0ZXA7fVxuICAgIH1cbiAgfVxuXG4gIHZhciBtZWFzdXJlVGV4dDtcbiAgLy8gQ29tcHV0ZSB0aGUgZGVmYXVsdCB0ZXh0IGhlaWdodC5cbiAgZnVuY3Rpb24gdGV4dEhlaWdodChkaXNwbGF5KSB7XG4gICAgaWYgKGRpc3BsYXkuY2FjaGVkVGV4dEhlaWdodCAhPSBudWxsKSByZXR1cm4gZGlzcGxheS5jYWNoZWRUZXh0SGVpZ2h0O1xuICAgIGlmIChtZWFzdXJlVGV4dCA9PSBudWxsKSB7XG4gICAgICBtZWFzdXJlVGV4dCA9IGVsdChcInByZVwiKTtcbiAgICAgIC8vIE1lYXN1cmUgYSBidW5jaCBvZiBsaW5lcywgZm9yIGJyb3dzZXJzIHRoYXQgY29tcHV0ZVxuICAgICAgLy8gZnJhY3Rpb25hbCBoZWlnaHRzLlxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCA0OTsgKytpKSB7XG4gICAgICAgIG1lYXN1cmVUZXh0LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFwieFwiKSk7XG4gICAgICAgIG1lYXN1cmVUZXh0LmFwcGVuZENoaWxkKGVsdChcImJyXCIpKTtcbiAgICAgIH1cbiAgICAgIG1lYXN1cmVUZXh0LmFwcGVuZENoaWxkKGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKFwieFwiKSk7XG4gICAgfVxuICAgIHJlbW92ZUNoaWxkcmVuQW5kQWRkKGRpc3BsYXkubWVhc3VyZSwgbWVhc3VyZVRleHQpO1xuICAgIHZhciBoZWlnaHQgPSBtZWFzdXJlVGV4dC5vZmZzZXRIZWlnaHQgLyA1MDtcbiAgICBpZiAoaGVpZ2h0ID4gMykgZGlzcGxheS5jYWNoZWRUZXh0SGVpZ2h0ID0gaGVpZ2h0O1xuICAgIHJlbW92ZUNoaWxkcmVuKGRpc3BsYXkubWVhc3VyZSk7XG4gICAgcmV0dXJuIGhlaWdodCB8fCAxO1xuICB9XG5cbiAgLy8gQ29tcHV0ZSB0aGUgZGVmYXVsdCBjaGFyYWN0ZXIgd2lkdGguXG4gIGZ1bmN0aW9uIGNoYXJXaWR0aChkaXNwbGF5KSB7XG4gICAgaWYgKGRpc3BsYXkuY2FjaGVkQ2hhcldpZHRoICE9IG51bGwpIHJldHVybiBkaXNwbGF5LmNhY2hlZENoYXJXaWR0aDtcbiAgICB2YXIgYW5jaG9yID0gZWx0KFwic3BhblwiLCBcInh4eHh4eHh4eHhcIik7XG4gICAgdmFyIHByZSA9IGVsdChcInByZVwiLCBbYW5jaG9yXSk7XG4gICAgcmVtb3ZlQ2hpbGRyZW5BbmRBZGQoZGlzcGxheS5tZWFzdXJlLCBwcmUpO1xuICAgIHZhciByZWN0ID0gYW5jaG9yLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCB3aWR0aCA9IChyZWN0LnJpZ2h0IC0gcmVjdC5sZWZ0KSAvIDEwO1xuICAgIGlmICh3aWR0aCA+IDIpIGRpc3BsYXkuY2FjaGVkQ2hhcldpZHRoID0gd2lkdGg7XG4gICAgcmV0dXJuIHdpZHRoIHx8IDEwO1xuICB9XG5cbiAgLy8gT1BFUkFUSU9OU1xuXG4gIC8vIE9wZXJhdGlvbnMgYXJlIHVzZWQgdG8gd3JhcCBhIHNlcmllcyBvZiBjaGFuZ2VzIHRvIHRoZSBlZGl0b3JcbiAgLy8gc3RhdGUgaW4gc3VjaCBhIHdheSB0aGF0IGVhY2ggY2hhbmdlIHdvbid0IGhhdmUgdG8gdXBkYXRlIHRoZVxuICAvLyBjdXJzb3IgYW5kIGRpc3BsYXkgKHdoaWNoIHdvdWxkIGJlIGF3a3dhcmQsIHNsb3csIGFuZFxuICAvLyBlcnJvci1wcm9uZSkuIEluc3RlYWQsIGRpc3BsYXkgdXBkYXRlcyBhcmUgYmF0Y2hlZCBhbmQgdGhlbiBhbGxcbiAgLy8gY29tYmluZWQgYW5kIGV4ZWN1dGVkIGF0IG9uY2UuXG5cbiAgdmFyIG9wZXJhdGlvbkdyb3VwID0gbnVsbDtcblxuICB2YXIgbmV4dE9wSWQgPSAwO1xuICAvLyBTdGFydCBhIG5ldyBvcGVyYXRpb24uXG4gIGZ1bmN0aW9uIHN0YXJ0T3BlcmF0aW9uKGNtKSB7XG4gICAgY20uY3VyT3AgPSB7XG4gICAgICBjbTogY20sXG4gICAgICB2aWV3Q2hhbmdlZDogZmFsc2UsICAgICAgLy8gRmxhZyB0aGF0IGluZGljYXRlcyB0aGF0IGxpbmVzIG1pZ2h0IG5lZWQgdG8gYmUgcmVkcmF3blxuICAgICAgc3RhcnRIZWlnaHQ6IGNtLmRvYy5oZWlnaHQsIC8vIFVzZWQgdG8gZGV0ZWN0IG5lZWQgdG8gdXBkYXRlIHNjcm9sbGJhclxuICAgICAgZm9yY2VVcGRhdGU6IGZhbHNlLCAgICAgIC8vIFVzZWQgdG8gZm9yY2UgYSByZWRyYXdcbiAgICAgIHVwZGF0ZUlucHV0OiBudWxsLCAgICAgICAvLyBXaGV0aGVyIHRvIHJlc2V0IHRoZSBpbnB1dCB0ZXh0YXJlYVxuICAgICAgdHlwaW5nOiBmYWxzZSwgICAgICAgICAgIC8vIFdoZXRoZXIgdGhpcyByZXNldCBzaG91bGQgYmUgY2FyZWZ1bCB0byBsZWF2ZSBleGlzdGluZyB0ZXh0IChmb3IgY29tcG9zaXRpbmcpXG4gICAgICBjaGFuZ2VPYmpzOiBudWxsLCAgICAgICAgLy8gQWNjdW11bGF0ZWQgY2hhbmdlcywgZm9yIGZpcmluZyBjaGFuZ2UgZXZlbnRzXG4gICAgICBjdXJzb3JBY3Rpdml0eUhhbmRsZXJzOiBudWxsLCAvLyBTZXQgb2YgaGFuZGxlcnMgdG8gZmlyZSBjdXJzb3JBY3Rpdml0eSBvblxuICAgICAgY3Vyc29yQWN0aXZpdHlDYWxsZWQ6IDAsIC8vIFRyYWNrcyB3aGljaCBjdXJzb3JBY3Rpdml0eSBoYW5kbGVycyBoYXZlIGJlZW4gY2FsbGVkIGFscmVhZHlcbiAgICAgIHNlbGVjdGlvbkNoYW5nZWQ6IGZhbHNlLCAvLyBXaGV0aGVyIHRoZSBzZWxlY3Rpb24gbmVlZHMgdG8gYmUgcmVkcmF3blxuICAgICAgdXBkYXRlTWF4TGluZTogZmFsc2UsICAgIC8vIFNldCB3aGVuIHRoZSB3aWRlc3QgbGluZSBuZWVkcyB0byBiZSBkZXRlcm1pbmVkIGFuZXdcbiAgICAgIHNjcm9sbExlZnQ6IG51bGwsIHNjcm9sbFRvcDogbnVsbCwgLy8gSW50ZXJtZWRpYXRlIHNjcm9sbCBwb3NpdGlvbiwgbm90IHB1c2hlZCB0byBET00geWV0XG4gICAgICBzY3JvbGxUb1BvczogbnVsbCwgICAgICAgLy8gVXNlZCB0byBzY3JvbGwgdG8gYSBzcGVjaWZpYyBwb3NpdGlvblxuICAgICAgaWQ6ICsrbmV4dE9wSWQgICAgICAgICAgIC8vIFVuaXF1ZSBJRFxuICAgIH07XG4gICAgaWYgKG9wZXJhdGlvbkdyb3VwKSB7XG4gICAgICBvcGVyYXRpb25Hcm91cC5vcHMucHVzaChjbS5jdXJPcCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNtLmN1ck9wLm93bnNHcm91cCA9IG9wZXJhdGlvbkdyb3VwID0ge1xuICAgICAgICBvcHM6IFtjbS5jdXJPcF0sXG4gICAgICAgIGRlbGF5ZWRDYWxsYmFja3M6IFtdXG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGZpcmVDYWxsYmFja3NGb3JPcHMoZ3JvdXApIHtcbiAgICAvLyBDYWxscyBkZWxheWVkIGNhbGxiYWNrcyBhbmQgY3Vyc29yQWN0aXZpdHkgaGFuZGxlcnMgdW50aWwgbm9cbiAgICAvLyBuZXcgb25lcyBhcHBlYXJcbiAgICB2YXIgY2FsbGJhY2tzID0gZ3JvdXAuZGVsYXllZENhbGxiYWNrcywgaSA9IDA7XG4gICAgZG8ge1xuICAgICAgZm9yICg7IGkgPCBjYWxsYmFja3MubGVuZ3RoOyBpKyspXG4gICAgICAgIGNhbGxiYWNrc1tpXSgpO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBncm91cC5vcHMubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgdmFyIG9wID0gZ3JvdXAub3BzW2pdO1xuICAgICAgICBpZiAob3AuY3Vyc29yQWN0aXZpdHlIYW5kbGVycylcbiAgICAgICAgICB3aGlsZSAob3AuY3Vyc29yQWN0aXZpdHlDYWxsZWQgPCBvcC5jdXJzb3JBY3Rpdml0eUhhbmRsZXJzLmxlbmd0aClcbiAgICAgICAgICAgIG9wLmN1cnNvckFjdGl2aXR5SGFuZGxlcnNbb3AuY3Vyc29yQWN0aXZpdHlDYWxsZWQrK10ob3AuY20pO1xuICAgICAgfVxuICAgIH0gd2hpbGUgKGkgPCBjYWxsYmFja3MubGVuZ3RoKTtcbiAgfVxuXG4gIC8vIEZpbmlzaCBhbiBvcGVyYXRpb24sIHVwZGF0aW5nIHRoZSBkaXNwbGF5IGFuZCBzaWduYWxsaW5nIGRlbGF5ZWQgZXZlbnRzXG4gIGZ1bmN0aW9uIGVuZE9wZXJhdGlvbihjbSkge1xuICAgIHZhciBvcCA9IGNtLmN1ck9wLCBncm91cCA9IG9wLm93bnNHcm91cDtcbiAgICBpZiAoIWdyb3VwKSByZXR1cm47XG5cbiAgICB0cnkgeyBmaXJlQ2FsbGJhY2tzRm9yT3BzKGdyb3VwKTsgfVxuICAgIGZpbmFsbHkge1xuICAgICAgb3BlcmF0aW9uR3JvdXAgPSBudWxsO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBncm91cC5vcHMubGVuZ3RoOyBpKyspXG4gICAgICAgIGdyb3VwLm9wc1tpXS5jbS5jdXJPcCA9IG51bGw7XG4gICAgICBlbmRPcGVyYXRpb25zKGdyb3VwKTtcbiAgICB9XG4gIH1cblxuICAvLyBUaGUgRE9NIHVwZGF0ZXMgZG9uZSB3aGVuIGFuIG9wZXJhdGlvbiBmaW5pc2hlcyBhcmUgYmF0Y2hlZCBzb1xuICAvLyB0aGF0IHRoZSBtaW5pbXVtIG51bWJlciBvZiByZWxheW91dHMgYXJlIHJlcXVpcmVkLlxuICBmdW5jdGlvbiBlbmRPcGVyYXRpb25zKGdyb3VwKSB7XG4gICAgdmFyIG9wcyA9IGdyb3VwLm9wcztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wcy5sZW5ndGg7IGkrKykgLy8gUmVhZCBET01cbiAgICAgIGVuZE9wZXJhdGlvbl9SMShvcHNbaV0pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3BzLmxlbmd0aDsgaSsrKSAvLyBXcml0ZSBET00gKG1heWJlKVxuICAgICAgZW5kT3BlcmF0aW9uX1cxKG9wc1tpXSk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvcHMubGVuZ3RoOyBpKyspIC8vIFJlYWQgRE9NXG4gICAgICBlbmRPcGVyYXRpb25fUjIob3BzW2ldKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9wcy5sZW5ndGg7IGkrKykgLy8gV3JpdGUgRE9NIChtYXliZSlcbiAgICAgIGVuZE9wZXJhdGlvbl9XMihvcHNbaV0pO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb3BzLmxlbmd0aDsgaSsrKSAvLyBSZWFkIERPTVxuICAgICAgZW5kT3BlcmF0aW9uX2ZpbmlzaChvcHNbaV0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5kT3BlcmF0aW9uX1IxKG9wKSB7XG4gICAgdmFyIGNtID0gb3AuY20sIGRpc3BsYXkgPSBjbS5kaXNwbGF5O1xuICAgIG1heWJlQ2xpcFNjcm9sbGJhcnMoY20pO1xuICAgIGlmIChvcC51cGRhdGVNYXhMaW5lKSBmaW5kTWF4TGluZShjbSk7XG5cbiAgICBvcC5tdXN0VXBkYXRlID0gb3Audmlld0NoYW5nZWQgfHwgb3AuZm9yY2VVcGRhdGUgfHwgb3Auc2Nyb2xsVG9wICE9IG51bGwgfHxcbiAgICAgIG9wLnNjcm9sbFRvUG9zICYmIChvcC5zY3JvbGxUb1Bvcy5mcm9tLmxpbmUgPCBkaXNwbGF5LnZpZXdGcm9tIHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgb3Auc2Nyb2xsVG9Qb3MudG8ubGluZSA+PSBkaXNwbGF5LnZpZXdUbykgfHxcbiAgICAgIGRpc3BsYXkubWF4TGluZUNoYW5nZWQgJiYgY20ub3B0aW9ucy5saW5lV3JhcHBpbmc7XG4gICAgb3AudXBkYXRlID0gb3AubXVzdFVwZGF0ZSAmJlxuICAgICAgbmV3IERpc3BsYXlVcGRhdGUoY20sIG9wLm11c3RVcGRhdGUgJiYge3RvcDogb3Auc2Nyb2xsVG9wLCBlbnN1cmU6IG9wLnNjcm9sbFRvUG9zfSwgb3AuZm9yY2VVcGRhdGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gZW5kT3BlcmF0aW9uX1cxKG9wKSB7XG4gICAgb3AudXBkYXRlZERpc3BsYXkgPSBvcC5tdXN0VXBkYXRlICYmIHVwZGF0ZURpc3BsYXlJZk5lZWRlZChvcC5jbSwgb3AudXBkYXRlKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVuZE9wZXJhdGlvbl9SMihvcCkge1xuICAgIHZhciBjbSA9IG9wLmNtLCBkaXNwbGF5ID0gY20uZGlzcGxheTtcbiAgICBpZiAob3AudXBkYXRlZERpc3BsYXkpIHVwZGF0ZUhlaWdodHNJblZpZXdwb3J0KGNtKTtcblxuICAgIG9wLmJhck1lYXN1cmUgPSBtZWFzdXJlRm9yU2Nyb2xsYmFycyhjbSk7XG5cbiAgICAvLyBJZiB0aGUgbWF4IGxpbmUgY2hhbmdlZCBzaW5jZSBpdCB3YXMgbGFzdCBtZWFzdXJlZCwgbWVhc3VyZSBpdCxcbiAgICAvLyBhbmQgZW5zdXJlIHRoZSBkb2N1bWVudCdzIHdpZHRoIG1hdGNoZXMgaXQuXG4gICAgLy8gdXBkYXRlRGlzcGxheV9XMiB3aWxsIHVzZSB0aGVzZSBwcm9wZXJ0aWVzIHRvIGRvIHRoZSBhY3R1YWwgcmVzaXppbmdcbiAgICBpZiAoZGlzcGxheS5tYXhMaW5lQ2hhbmdlZCAmJiAhY20ub3B0aW9ucy5saW5lV3JhcHBpbmcpIHtcbiAgICAgIG9wLmFkanVzdFdpZHRoVG8gPSBtZWFzdXJlQ2hhcihjbSwgZGlzcGxheS5tYXhMaW5lLCBkaXNwbGF5Lm1heExpbmUudGV4dC5sZW5ndGgpLmxlZnQgKyAzO1xuICAgICAgY20uZGlzcGxheS5zaXplcldpZHRoID0gb3AuYWRqdXN0V2lkdGhUbztcbiAgICAgIG9wLmJhck1lYXN1cmUuc2Nyb2xsV2lkdGggPVxuICAgICAgICBNYXRoLm1heChkaXNwbGF5LnNjcm9sbGVyLmNsaWVudFdpZHRoLCBkaXNwbGF5LnNpemVyLm9mZnNldExlZnQgKyBvcC5hZGp1c3RXaWR0aFRvICsgc2Nyb2xsR2FwKGNtKSArIGNtLmRpc3BsYXkuYmFyV2lkdGgpO1xuICAgICAgb3AubWF4U2Nyb2xsTGVmdCA9IE1hdGgubWF4KDAsIGRpc3BsYXkuc2l6ZXIub2Zmc2V0TGVmdCArIG9wLmFkanVzdFdpZHRoVG8gLSBkaXNwbGF5V2lkdGgoY20pKTtcbiAgICB9XG5cbiAgICBpZiAob3AudXBkYXRlZERpc3BsYXkgfHwgb3Auc2VsZWN0aW9uQ2hhbmdlZClcbiAgICAgIG9wLm5ld1NlbGVjdGlvbk5vZGVzID0gZHJhd1NlbGVjdGlvbihjbSk7XG4gIH1cblxuICBmdW5jdGlvbiBlbmRPcGVyYXRpb25fVzIob3ApIHtcbiAgICB2YXIgY20gPSBvcC5jbTtcblxuICAgIGlmIChvcC5hZGp1c3RXaWR0aFRvICE9IG51bGwpIHtcbiAgICAgIGNtLmRpc3BsYXkuc2l6ZXIuc3R5bGUubWluV2lkdGggPSBvcC5hZGp1c3RXaWR0aFRvICsgXCJweFwiO1xuICAgICAgaWYgKG9wLm1heFNjcm9sbExlZnQgPCBjbS5kb2Muc2Nyb2xsTGVmdClcbiAgICAgICAgc2V0U2Nyb2xsTGVmdChjbSwgTWF0aC5taW4oY20uZGlzcGxheS5zY3JvbGxlci5zY3JvbGxMZWZ0LCBvcC5tYXhTY3JvbGxMZWZ0KSwgdHJ1ZSk7XG4gICAgICBjbS5kaXNwbGF5Lm1heExpbmVDaGFuZ2VkID0gZmFsc2U7XG4gICAgfVxuXG4gICAgaWYgKG9wLm5ld1NlbGVjdGlvbk5vZGVzKVxuICAgICAgc2hvd1NlbGVjdGlvbihjbSwgb3AubmV3U2VsZWN0aW9uTm9kZXMpO1xuICAgIGlmIChvcC51cGRhdGVkRGlzcGxheSlcbiAgICAgIHNldERvY3VtZW50SGVpZ2h0KGNtLCBvcC5iYXJNZWFzdXJlKTtcbiAgICBpZiAob3AudXBkYXRlZERpc3BsYXkgfHwgb3Auc3RhcnRIZWlnaHQgIT0gY20uZG9jLmhlaWdodClcbiAgICAgIHVwZGF0ZVNjcm9sbGJhcnMoY20sIG9wLmJhck1lYXN1cmUpO1xuXG4gICAgaWYgKG9wLnNlbGVjdGlvbkNoYW5nZWQpIHJlc3RhcnRCbGluayhjbSk7XG5cbiAgICBpZiAoY20uc3RhdGUuZm9jdXNlZCAmJiBvcC51cGRhdGVJbnB1dClcbiAgICAgIHJlc2V0SW5wdXQoY20sIG9wLnR5cGluZyk7XG4gIH1cblxuICBmdW5jdGlvbiBlbmRPcGVyYXRpb25fZmluaXNoKG9wKSB7XG4gICAgdmFyIGNtID0gb3AuY20sIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBkb2MgPSBjbS5kb2M7XG5cbiAgICBpZiAob3AudXBkYXRlZERpc3BsYXkpIHBvc3RVcGRhdGVEaXNwbGF5KGNtLCBvcC51cGRhdGUpO1xuXG4gICAgLy8gQWJvcnQgbW91c2Ugd2hlZWwgZGVsdGEgbWVhc3VyZW1lbnQsIHdoZW4gc2Nyb2xsaW5nIGV4cGxpY2l0bHlcbiAgICBpZiAoZGlzcGxheS53aGVlbFN0YXJ0WCAhPSBudWxsICYmIChvcC5zY3JvbGxUb3AgIT0gbnVsbCB8fCBvcC5zY3JvbGxMZWZ0ICE9IG51bGwgfHwgb3Auc2Nyb2xsVG9Qb3MpKVxuICAgICAgZGlzcGxheS53aGVlbFN0YXJ0WCA9IGRpc3BsYXkud2hlZWxTdGFydFkgPSBudWxsO1xuXG4gICAgLy8gUHJvcGFnYXRlIHRoZSBzY3JvbGwgcG9zaXRpb24gdG8gdGhlIGFjdHVhbCBET00gc2Nyb2xsZXJcbiAgICBpZiAob3Auc2Nyb2xsVG9wICE9IG51bGwgJiYgKGRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsVG9wICE9IG9wLnNjcm9sbFRvcCB8fCBvcC5mb3JjZVNjcm9sbCkpIHtcbiAgICAgIGRvYy5zY3JvbGxUb3AgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbEhlaWdodCAtIGRpc3BsYXkuc2Nyb2xsZXIuY2xpZW50SGVpZ2h0LCBvcC5zY3JvbGxUb3ApKTtcbiAgICAgIGRpc3BsYXkuc2Nyb2xsYmFycy5zZXRTY3JvbGxUb3AoZG9jLnNjcm9sbFRvcCk7XG4gICAgICBkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbFRvcCA9IGRvYy5zY3JvbGxUb3A7XG4gICAgfVxuICAgIGlmIChvcC5zY3JvbGxMZWZ0ICE9IG51bGwgJiYgKGRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsTGVmdCAhPSBvcC5zY3JvbGxMZWZ0IHx8IG9wLmZvcmNlU2Nyb2xsKSkge1xuICAgICAgZG9jLnNjcm9sbExlZnQgPSBNYXRoLm1heCgwLCBNYXRoLm1pbihkaXNwbGF5LnNjcm9sbGVyLnNjcm9sbFdpZHRoIC0gZGlzcGxheVdpZHRoKGNtKSwgb3Auc2Nyb2xsTGVmdCkpO1xuICAgICAgZGlzcGxheS5zY3JvbGxiYXJzLnNldFNjcm9sbExlZnQoZG9jLnNjcm9sbExlZnQpO1xuICAgICAgZGlzcGxheS5zY3JvbGxlci5zY3JvbGxMZWZ0ID0gZG9jLnNjcm9sbExlZnQ7XG4gICAgICBhbGlnbkhvcml6b250YWxseShjbSk7XG4gICAgfVxuICAgIC8vIElmIHdlIG5lZWQgdG8gc2Nyb2xsIGEgc3BlY2lmaWMgcG9zaXRpb24gaW50byB2aWV3LCBkbyBzby5cbiAgICBpZiAob3Auc2Nyb2xsVG9Qb3MpIHtcbiAgICAgIHZhciBjb29yZHMgPSBzY3JvbGxQb3NJbnRvVmlldyhjbSwgY2xpcFBvcyhkb2MsIG9wLnNjcm9sbFRvUG9zLmZyb20pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsaXBQb3MoZG9jLCBvcC5zY3JvbGxUb1Bvcy50byksIG9wLnNjcm9sbFRvUG9zLm1hcmdpbik7XG4gICAgICBpZiAob3Auc2Nyb2xsVG9Qb3MuaXNDdXJzb3IgJiYgY20uc3RhdGUuZm9jdXNlZCkgbWF5YmVTY3JvbGxXaW5kb3coY20sIGNvb3Jkcyk7XG4gICAgfVxuXG4gICAgLy8gRmlyZSBldmVudHMgZm9yIG1hcmtlcnMgdGhhdCBhcmUgaGlkZGVuL3VuaWRkZW4gYnkgZWRpdGluZyBvclxuICAgIC8vIHVuZG9pbmdcbiAgICB2YXIgaGlkZGVuID0gb3AubWF5YmVIaWRkZW5NYXJrZXJzLCB1bmhpZGRlbiA9IG9wLm1heWJlVW5oaWRkZW5NYXJrZXJzO1xuICAgIGlmIChoaWRkZW4pIGZvciAodmFyIGkgPSAwOyBpIDwgaGlkZGVuLmxlbmd0aDsgKytpKVxuICAgICAgaWYgKCFoaWRkZW5baV0ubGluZXMubGVuZ3RoKSBzaWduYWwoaGlkZGVuW2ldLCBcImhpZGVcIik7XG4gICAgaWYgKHVuaGlkZGVuKSBmb3IgKHZhciBpID0gMDsgaSA8IHVuaGlkZGVuLmxlbmd0aDsgKytpKVxuICAgICAgaWYgKHVuaGlkZGVuW2ldLmxpbmVzLmxlbmd0aCkgc2lnbmFsKHVuaGlkZGVuW2ldLCBcInVuaGlkZVwiKTtcblxuICAgIGlmIChkaXNwbGF5LndyYXBwZXIub2Zmc2V0SGVpZ2h0KVxuICAgICAgZG9jLnNjcm9sbFRvcCA9IGNtLmRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsVG9wO1xuXG4gICAgLy8gRmlyZSBjaGFuZ2UgZXZlbnRzLCBhbmQgZGVsYXllZCBldmVudCBoYW5kbGVyc1xuICAgIGlmIChvcC5jaGFuZ2VPYmpzKVxuICAgICAgc2lnbmFsKGNtLCBcImNoYW5nZXNcIiwgY20sIG9wLmNoYW5nZU9ianMpO1xuICB9XG5cbiAgLy8gUnVuIHRoZSBnaXZlbiBmdW5jdGlvbiBpbiBhbiBvcGVyYXRpb25cbiAgZnVuY3Rpb24gcnVuSW5PcChjbSwgZikge1xuICAgIGlmIChjbS5jdXJPcCkgcmV0dXJuIGYoKTtcbiAgICBzdGFydE9wZXJhdGlvbihjbSk7XG4gICAgdHJ5IHsgcmV0dXJuIGYoKTsgfVxuICAgIGZpbmFsbHkgeyBlbmRPcGVyYXRpb24oY20pOyB9XG4gIH1cbiAgLy8gV3JhcHMgYSBmdW5jdGlvbiBpbiBhbiBvcGVyYXRpb24uIFJldHVybnMgdGhlIHdyYXBwZWQgZnVuY3Rpb24uXG4gIGZ1bmN0aW9uIG9wZXJhdGlvbihjbSwgZikge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChjbS5jdXJPcCkgcmV0dXJuIGYuYXBwbHkoY20sIGFyZ3VtZW50cyk7XG4gICAgICBzdGFydE9wZXJhdGlvbihjbSk7XG4gICAgICB0cnkgeyByZXR1cm4gZi5hcHBseShjbSwgYXJndW1lbnRzKTsgfVxuICAgICAgZmluYWxseSB7IGVuZE9wZXJhdGlvbihjbSk7IH1cbiAgICB9O1xuICB9XG4gIC8vIFVzZWQgdG8gYWRkIG1ldGhvZHMgdG8gZWRpdG9yIGFuZCBkb2MgaW5zdGFuY2VzLCB3cmFwcGluZyB0aGVtIGluXG4gIC8vIG9wZXJhdGlvbnMuXG4gIGZ1bmN0aW9uIG1ldGhvZE9wKGYpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5jdXJPcCkgcmV0dXJuIGYuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICAgIHN0YXJ0T3BlcmF0aW9uKHRoaXMpO1xuICAgICAgdHJ5IHsgcmV0dXJuIGYuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfVxuICAgICAgZmluYWxseSB7IGVuZE9wZXJhdGlvbih0aGlzKTsgfVxuICAgIH07XG4gIH1cbiAgZnVuY3Rpb24gZG9jTWV0aG9kT3AoZikge1xuICAgIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBjbSA9IHRoaXMuY207XG4gICAgICBpZiAoIWNtIHx8IGNtLmN1ck9wKSByZXR1cm4gZi5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgICAgc3RhcnRPcGVyYXRpb24oY20pO1xuICAgICAgdHJ5IHsgcmV0dXJuIGYuYXBwbHkodGhpcywgYXJndW1lbnRzKTsgfVxuICAgICAgZmluYWxseSB7IGVuZE9wZXJhdGlvbihjbSk7IH1cbiAgICB9O1xuICB9XG5cbiAgLy8gVklFVyBUUkFDS0lOR1xuXG4gIC8vIFRoZXNlIG9iamVjdHMgYXJlIHVzZWQgdG8gcmVwcmVzZW50IHRoZSB2aXNpYmxlIChjdXJyZW50bHkgZHJhd24pXG4gIC8vIHBhcnQgb2YgdGhlIGRvY3VtZW50LiBBIExpbmVWaWV3IG1heSBjb3JyZXNwb25kIHRvIG11bHRpcGxlXG4gIC8vIGxvZ2ljYWwgbGluZXMsIGlmIHRob3NlIGFyZSBjb25uZWN0ZWQgYnkgY29sbGFwc2VkIHJhbmdlcy5cbiAgZnVuY3Rpb24gTGluZVZpZXcoZG9jLCBsaW5lLCBsaW5lTikge1xuICAgIC8vIFRoZSBzdGFydGluZyBsaW5lXG4gICAgdGhpcy5saW5lID0gbGluZTtcbiAgICAvLyBDb250aW51aW5nIGxpbmVzLCBpZiBhbnlcbiAgICB0aGlzLnJlc3QgPSB2aXN1YWxMaW5lQ29udGludWVkKGxpbmUpO1xuICAgIC8vIE51bWJlciBvZiBsb2dpY2FsIGxpbmVzIGluIHRoaXMgdmlzdWFsIGxpbmVcbiAgICB0aGlzLnNpemUgPSB0aGlzLnJlc3QgPyBsaW5lTm8obHN0KHRoaXMucmVzdCkpIC0gbGluZU4gKyAxIDogMTtcbiAgICB0aGlzLm5vZGUgPSB0aGlzLnRleHQgPSBudWxsO1xuICAgIHRoaXMuaGlkZGVuID0gbGluZUlzSGlkZGVuKGRvYywgbGluZSk7XG4gIH1cblxuICAvLyBDcmVhdGUgYSByYW5nZSBvZiBMaW5lVmlldyBvYmplY3RzIGZvciB0aGUgZ2l2ZW4gbGluZXMuXG4gIGZ1bmN0aW9uIGJ1aWxkVmlld0FycmF5KGNtLCBmcm9tLCB0bykge1xuICAgIHZhciBhcnJheSA9IFtdLCBuZXh0UG9zO1xuICAgIGZvciAodmFyIHBvcyA9IGZyb207IHBvcyA8IHRvOyBwb3MgPSBuZXh0UG9zKSB7XG4gICAgICB2YXIgdmlldyA9IG5ldyBMaW5lVmlldyhjbS5kb2MsIGdldExpbmUoY20uZG9jLCBwb3MpLCBwb3MpO1xuICAgICAgbmV4dFBvcyA9IHBvcyArIHZpZXcuc2l6ZTtcbiAgICAgIGFycmF5LnB1c2godmlldyk7XG4gICAgfVxuICAgIHJldHVybiBhcnJheTtcbiAgfVxuXG4gIC8vIFVwZGF0ZXMgdGhlIGRpc3BsYXkudmlldyBkYXRhIHN0cnVjdHVyZSBmb3IgYSBnaXZlbiBjaGFuZ2UgdG8gdGhlXG4gIC8vIGRvY3VtZW50LiBGcm9tIGFuZCB0byBhcmUgaW4gcHJlLWNoYW5nZSBjb29yZGluYXRlcy4gTGVuZGlmZiBpc1xuICAvLyB0aGUgYW1vdW50IG9mIGxpbmVzIGFkZGVkIG9yIHN1YnRyYWN0ZWQgYnkgdGhlIGNoYW5nZS4gVGhpcyBpc1xuICAvLyB1c2VkIGZvciBjaGFuZ2VzIHRoYXQgc3BhbiBtdWx0aXBsZSBsaW5lcywgb3IgY2hhbmdlIHRoZSB3YXlcbiAgLy8gbGluZXMgYXJlIGRpdmlkZWQgaW50byB2aXN1YWwgbGluZXMuIHJlZ0xpbmVDaGFuZ2UgKGJlbG93KVxuICAvLyByZWdpc3RlcnMgc2luZ2xlLWxpbmUgY2hhbmdlcy5cbiAgZnVuY3Rpb24gcmVnQ2hhbmdlKGNtLCBmcm9tLCB0bywgbGVuZGlmZikge1xuICAgIGlmIChmcm9tID09IG51bGwpIGZyb20gPSBjbS5kb2MuZmlyc3Q7XG4gICAgaWYgKHRvID09IG51bGwpIHRvID0gY20uZG9jLmZpcnN0ICsgY20uZG9jLnNpemU7XG4gICAgaWYgKCFsZW5kaWZmKSBsZW5kaWZmID0gMDtcblxuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheTtcbiAgICBpZiAobGVuZGlmZiAmJiB0byA8IGRpc3BsYXkudmlld1RvICYmXG4gICAgICAgIChkaXNwbGF5LnVwZGF0ZUxpbmVOdW1iZXJzID09IG51bGwgfHwgZGlzcGxheS51cGRhdGVMaW5lTnVtYmVycyA+IGZyb20pKVxuICAgICAgZGlzcGxheS51cGRhdGVMaW5lTnVtYmVycyA9IGZyb207XG5cbiAgICBjbS5jdXJPcC52aWV3Q2hhbmdlZCA9IHRydWU7XG5cbiAgICBpZiAoZnJvbSA+PSBkaXNwbGF5LnZpZXdUbykgeyAvLyBDaGFuZ2UgYWZ0ZXJcbiAgICAgIGlmIChzYXdDb2xsYXBzZWRTcGFucyAmJiB2aXN1YWxMaW5lTm8oY20uZG9jLCBmcm9tKSA8IGRpc3BsYXkudmlld1RvKVxuICAgICAgICByZXNldFZpZXcoY20pO1xuICAgIH0gZWxzZSBpZiAodG8gPD0gZGlzcGxheS52aWV3RnJvbSkgeyAvLyBDaGFuZ2UgYmVmb3JlXG4gICAgICBpZiAoc2F3Q29sbGFwc2VkU3BhbnMgJiYgdmlzdWFsTGluZUVuZE5vKGNtLmRvYywgdG8gKyBsZW5kaWZmKSA+IGRpc3BsYXkudmlld0Zyb20pIHtcbiAgICAgICAgcmVzZXRWaWV3KGNtKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpc3BsYXkudmlld0Zyb20gKz0gbGVuZGlmZjtcbiAgICAgICAgZGlzcGxheS52aWV3VG8gKz0gbGVuZGlmZjtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKGZyb20gPD0gZGlzcGxheS52aWV3RnJvbSAmJiB0byA+PSBkaXNwbGF5LnZpZXdUbykgeyAvLyBGdWxsIG92ZXJsYXBcbiAgICAgIHJlc2V0VmlldyhjbSk7XG4gICAgfSBlbHNlIGlmIChmcm9tIDw9IGRpc3BsYXkudmlld0Zyb20pIHsgLy8gVG9wIG92ZXJsYXBcbiAgICAgIHZhciBjdXQgPSB2aWV3Q3V0dGluZ1BvaW50KGNtLCB0bywgdG8gKyBsZW5kaWZmLCAxKTtcbiAgICAgIGlmIChjdXQpIHtcbiAgICAgICAgZGlzcGxheS52aWV3ID0gZGlzcGxheS52aWV3LnNsaWNlKGN1dC5pbmRleCk7XG4gICAgICAgIGRpc3BsYXkudmlld0Zyb20gPSBjdXQubGluZU47XG4gICAgICAgIGRpc3BsYXkudmlld1RvICs9IGxlbmRpZmY7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXNldFZpZXcoY20pO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodG8gPj0gZGlzcGxheS52aWV3VG8pIHsgLy8gQm90dG9tIG92ZXJsYXBcbiAgICAgIHZhciBjdXQgPSB2aWV3Q3V0dGluZ1BvaW50KGNtLCBmcm9tLCBmcm9tLCAtMSk7XG4gICAgICBpZiAoY3V0KSB7XG4gICAgICAgIGRpc3BsYXkudmlldyA9IGRpc3BsYXkudmlldy5zbGljZSgwLCBjdXQuaW5kZXgpO1xuICAgICAgICBkaXNwbGF5LnZpZXdUbyA9IGN1dC5saW5lTjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc2V0VmlldyhjbSk7XG4gICAgICB9XG4gICAgfSBlbHNlIHsgLy8gR2FwIGluIHRoZSBtaWRkbGVcbiAgICAgIHZhciBjdXRUb3AgPSB2aWV3Q3V0dGluZ1BvaW50KGNtLCBmcm9tLCBmcm9tLCAtMSk7XG4gICAgICB2YXIgY3V0Qm90ID0gdmlld0N1dHRpbmdQb2ludChjbSwgdG8sIHRvICsgbGVuZGlmZiwgMSk7XG4gICAgICBpZiAoY3V0VG9wICYmIGN1dEJvdCkge1xuICAgICAgICBkaXNwbGF5LnZpZXcgPSBkaXNwbGF5LnZpZXcuc2xpY2UoMCwgY3V0VG9wLmluZGV4KVxuICAgICAgICAgIC5jb25jYXQoYnVpbGRWaWV3QXJyYXkoY20sIGN1dFRvcC5saW5lTiwgY3V0Qm90LmxpbmVOKSlcbiAgICAgICAgICAuY29uY2F0KGRpc3BsYXkudmlldy5zbGljZShjdXRCb3QuaW5kZXgpKTtcbiAgICAgICAgZGlzcGxheS52aWV3VG8gKz0gbGVuZGlmZjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJlc2V0VmlldyhjbSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFyIGV4dCA9IGRpc3BsYXkuZXh0ZXJuYWxNZWFzdXJlZDtcbiAgICBpZiAoZXh0KSB7XG4gICAgICBpZiAodG8gPCBleHQubGluZU4pXG4gICAgICAgIGV4dC5saW5lTiArPSBsZW5kaWZmO1xuICAgICAgZWxzZSBpZiAoZnJvbSA8IGV4dC5saW5lTiArIGV4dC5zaXplKVxuICAgICAgICBkaXNwbGF5LmV4dGVybmFsTWVhc3VyZWQgPSBudWxsO1xuICAgIH1cbiAgfVxuXG4gIC8vIFJlZ2lzdGVyIGEgY2hhbmdlIHRvIGEgc2luZ2xlIGxpbmUuIFR5cGUgbXVzdCBiZSBvbmUgb2YgXCJ0ZXh0XCIsXG4gIC8vIFwiZ3V0dGVyXCIsIFwiY2xhc3NcIiwgXCJ3aWRnZXRcIlxuICBmdW5jdGlvbiByZWdMaW5lQ2hhbmdlKGNtLCBsaW5lLCB0eXBlKSB7XG4gICAgY20uY3VyT3Audmlld0NoYW5nZWQgPSB0cnVlO1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheSwgZXh0ID0gY20uZGlzcGxheS5leHRlcm5hbE1lYXN1cmVkO1xuICAgIGlmIChleHQgJiYgbGluZSA+PSBleHQubGluZU4gJiYgbGluZSA8IGV4dC5saW5lTiArIGV4dC5zaXplKVxuICAgICAgZGlzcGxheS5leHRlcm5hbE1lYXN1cmVkID0gbnVsbDtcblxuICAgIGlmIChsaW5lIDwgZGlzcGxheS52aWV3RnJvbSB8fCBsaW5lID49IGRpc3BsYXkudmlld1RvKSByZXR1cm47XG4gICAgdmFyIGxpbmVWaWV3ID0gZGlzcGxheS52aWV3W2ZpbmRWaWV3SW5kZXgoY20sIGxpbmUpXTtcbiAgICBpZiAobGluZVZpZXcubm9kZSA9PSBudWxsKSByZXR1cm47XG4gICAgdmFyIGFyciA9IGxpbmVWaWV3LmNoYW5nZXMgfHwgKGxpbmVWaWV3LmNoYW5nZXMgPSBbXSk7XG4gICAgaWYgKGluZGV4T2YoYXJyLCB0eXBlKSA9PSAtMSkgYXJyLnB1c2godHlwZSk7XG4gIH1cblxuICAvLyBDbGVhciB0aGUgdmlldy5cbiAgZnVuY3Rpb24gcmVzZXRWaWV3KGNtKSB7XG4gICAgY20uZGlzcGxheS52aWV3RnJvbSA9IGNtLmRpc3BsYXkudmlld1RvID0gY20uZG9jLmZpcnN0O1xuICAgIGNtLmRpc3BsYXkudmlldyA9IFtdO1xuICAgIGNtLmRpc3BsYXkudmlld09mZnNldCA9IDA7XG4gIH1cblxuICAvLyBGaW5kIHRoZSB2aWV3IGVsZW1lbnQgY29ycmVzcG9uZGluZyB0byBhIGdpdmVuIGxpbmUuIFJldHVybiBudWxsXG4gIC8vIHdoZW4gdGhlIGxpbmUgaXNuJ3QgdmlzaWJsZS5cbiAgZnVuY3Rpb24gZmluZFZpZXdJbmRleChjbSwgbikge1xuICAgIGlmIChuID49IGNtLmRpc3BsYXkudmlld1RvKSByZXR1cm4gbnVsbDtcbiAgICBuIC09IGNtLmRpc3BsYXkudmlld0Zyb207XG4gICAgaWYgKG4gPCAwKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgdmlldyA9IGNtLmRpc3BsYXkudmlldztcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHZpZXcubGVuZ3RoOyBpKyspIHtcbiAgICAgIG4gLT0gdmlld1tpXS5zaXplO1xuICAgICAgaWYgKG4gPCAwKSByZXR1cm4gaTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiB2aWV3Q3V0dGluZ1BvaW50KGNtLCBvbGROLCBuZXdOLCBkaXIpIHtcbiAgICB2YXIgaW5kZXggPSBmaW5kVmlld0luZGV4KGNtLCBvbGROKSwgZGlmZiwgdmlldyA9IGNtLmRpc3BsYXkudmlldztcbiAgICBpZiAoIXNhd0NvbGxhcHNlZFNwYW5zIHx8IG5ld04gPT0gY20uZG9jLmZpcnN0ICsgY20uZG9jLnNpemUpXG4gICAgICByZXR1cm4ge2luZGV4OiBpbmRleCwgbGluZU46IG5ld059O1xuICAgIGZvciAodmFyIGkgPSAwLCBuID0gY20uZGlzcGxheS52aWV3RnJvbTsgaSA8IGluZGV4OyBpKyspXG4gICAgICBuICs9IHZpZXdbaV0uc2l6ZTtcbiAgICBpZiAobiAhPSBvbGROKSB7XG4gICAgICBpZiAoZGlyID4gMCkge1xuICAgICAgICBpZiAoaW5kZXggPT0gdmlldy5sZW5ndGggLSAxKSByZXR1cm4gbnVsbDtcbiAgICAgICAgZGlmZiA9IChuICsgdmlld1tpbmRleF0uc2l6ZSkgLSBvbGROO1xuICAgICAgICBpbmRleCsrO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZGlmZiA9IG4gLSBvbGROO1xuICAgICAgfVxuICAgICAgb2xkTiArPSBkaWZmOyBuZXdOICs9IGRpZmY7XG4gICAgfVxuICAgIHdoaWxlICh2aXN1YWxMaW5lTm8oY20uZG9jLCBuZXdOKSAhPSBuZXdOKSB7XG4gICAgICBpZiAoaW5kZXggPT0gKGRpciA8IDAgPyAwIDogdmlldy5sZW5ndGggLSAxKSkgcmV0dXJuIG51bGw7XG4gICAgICBuZXdOICs9IGRpciAqIHZpZXdbaW5kZXggLSAoZGlyIDwgMCA/IDEgOiAwKV0uc2l6ZTtcbiAgICAgIGluZGV4ICs9IGRpcjtcbiAgICB9XG4gICAgcmV0dXJuIHtpbmRleDogaW5kZXgsIGxpbmVOOiBuZXdOfTtcbiAgfVxuXG4gIC8vIEZvcmNlIHRoZSB2aWV3IHRvIGNvdmVyIGEgZ2l2ZW4gcmFuZ2UsIGFkZGluZyBlbXB0eSB2aWV3IGVsZW1lbnRcbiAgLy8gb3IgY2xpcHBpbmcgb2ZmIGV4aXN0aW5nIG9uZXMgYXMgbmVlZGVkLlxuICBmdW5jdGlvbiBhZGp1c3RWaWV3KGNtLCBmcm9tLCB0bykge1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheSwgdmlldyA9IGRpc3BsYXkudmlldztcbiAgICBpZiAodmlldy5sZW5ndGggPT0gMCB8fCBmcm9tID49IGRpc3BsYXkudmlld1RvIHx8IHRvIDw9IGRpc3BsYXkudmlld0Zyb20pIHtcbiAgICAgIGRpc3BsYXkudmlldyA9IGJ1aWxkVmlld0FycmF5KGNtLCBmcm9tLCB0byk7XG4gICAgICBkaXNwbGF5LnZpZXdGcm9tID0gZnJvbTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGRpc3BsYXkudmlld0Zyb20gPiBmcm9tKVxuICAgICAgICBkaXNwbGF5LnZpZXcgPSBidWlsZFZpZXdBcnJheShjbSwgZnJvbSwgZGlzcGxheS52aWV3RnJvbSkuY29uY2F0KGRpc3BsYXkudmlldyk7XG4gICAgICBlbHNlIGlmIChkaXNwbGF5LnZpZXdGcm9tIDwgZnJvbSlcbiAgICAgICAgZGlzcGxheS52aWV3ID0gZGlzcGxheS52aWV3LnNsaWNlKGZpbmRWaWV3SW5kZXgoY20sIGZyb20pKTtcbiAgICAgIGRpc3BsYXkudmlld0Zyb20gPSBmcm9tO1xuICAgICAgaWYgKGRpc3BsYXkudmlld1RvIDwgdG8pXG4gICAgICAgIGRpc3BsYXkudmlldyA9IGRpc3BsYXkudmlldy5jb25jYXQoYnVpbGRWaWV3QXJyYXkoY20sIGRpc3BsYXkudmlld1RvLCB0bykpO1xuICAgICAgZWxzZSBpZiAoZGlzcGxheS52aWV3VG8gPiB0bylcbiAgICAgICAgZGlzcGxheS52aWV3ID0gZGlzcGxheS52aWV3LnNsaWNlKDAsIGZpbmRWaWV3SW5kZXgoY20sIHRvKSk7XG4gICAgfVxuICAgIGRpc3BsYXkudmlld1RvID0gdG87XG4gIH1cblxuICAvLyBDb3VudCB0aGUgbnVtYmVyIG9mIGxpbmVzIGluIHRoZSB2aWV3IHdob3NlIERPTSByZXByZXNlbnRhdGlvbiBpc1xuICAvLyBvdXQgb2YgZGF0ZSAob3Igbm9uZXhpc3RlbnQpLlxuICBmdW5jdGlvbiBjb3VudERpcnR5VmlldyhjbSkge1xuICAgIHZhciB2aWV3ID0gY20uZGlzcGxheS52aWV3LCBkaXJ0eSA9IDA7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB2aWV3Lmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbGluZVZpZXcgPSB2aWV3W2ldO1xuICAgICAgaWYgKCFsaW5lVmlldy5oaWRkZW4gJiYgKCFsaW5lVmlldy5ub2RlIHx8IGxpbmVWaWV3LmNoYW5nZXMpKSArK2RpcnR5O1xuICAgIH1cbiAgICByZXR1cm4gZGlydHk7XG4gIH1cblxuICAvLyBJTlBVVCBIQU5ETElOR1xuXG4gIC8vIFBvbGwgZm9yIGlucHV0IGNoYW5nZXMsIHVzaW5nIHRoZSBub3JtYWwgcmF0ZSBvZiBwb2xsaW5nLiBUaGlzXG4gIC8vIHJ1bnMgYXMgbG9uZyBhcyB0aGUgZWRpdG9yIGlzIGZvY3VzZWQuXG4gIGZ1bmN0aW9uIHNsb3dQb2xsKGNtKSB7XG4gICAgaWYgKGNtLmRpc3BsYXkucG9sbGluZ0Zhc3QpIHJldHVybjtcbiAgICBjbS5kaXNwbGF5LnBvbGwuc2V0KGNtLm9wdGlvbnMucG9sbEludGVydmFsLCBmdW5jdGlvbigpIHtcbiAgICAgIHJlYWRJbnB1dChjbSk7XG4gICAgICBpZiAoY20uc3RhdGUuZm9jdXNlZCkgc2xvd1BvbGwoY20pO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gV2hlbiBhbiBldmVudCBoYXMganVzdCBjb21lIGluIHRoYXQgaXMgbGlrZWx5IHRvIGFkZCBvciBjaGFuZ2VcbiAgLy8gc29tZXRoaW5nIGluIHRoZSBpbnB1dCB0ZXh0YXJlYSwgd2UgcG9sbCBmYXN0ZXIsIHRvIGVuc3VyZSB0aGF0XG4gIC8vIHRoZSBjaGFuZ2UgYXBwZWFycyBvbiB0aGUgc2NyZWVuIHF1aWNrbHkuXG4gIGZ1bmN0aW9uIGZhc3RQb2xsKGNtKSB7XG4gICAgdmFyIG1pc3NlZCA9IGZhbHNlO1xuICAgIGNtLmRpc3BsYXkucG9sbGluZ0Zhc3QgPSB0cnVlO1xuICAgIGZ1bmN0aW9uIHAoKSB7XG4gICAgICB2YXIgY2hhbmdlZCA9IHJlYWRJbnB1dChjbSk7XG4gICAgICBpZiAoIWNoYW5nZWQgJiYgIW1pc3NlZCkge21pc3NlZCA9IHRydWU7IGNtLmRpc3BsYXkucG9sbC5zZXQoNjAsIHApO31cbiAgICAgIGVsc2Uge2NtLmRpc3BsYXkucG9sbGluZ0Zhc3QgPSBmYWxzZTsgc2xvd1BvbGwoY20pO31cbiAgICB9XG4gICAgY20uZGlzcGxheS5wb2xsLnNldCgyMCwgcCk7XG4gIH1cblxuICAvLyBUaGlzIHdpbGwgYmUgc2V0IHRvIGFuIGFycmF5IG9mIHN0cmluZ3Mgd2hlbiBjb3B5aW5nLCBzbyB0aGF0LFxuICAvLyB3aGVuIHBhc3RpbmcsIHdlIGtub3cgd2hhdCBraW5kIG9mIHNlbGVjdGlvbnMgdGhlIGNvcGllZCB0ZXh0XG4gIC8vIHdhcyBtYWRlIG91dCBvZi5cbiAgdmFyIGxhc3RDb3BpZWQgPSBudWxsO1xuXG4gIC8vIFJlYWQgaW5wdXQgZnJvbSB0aGUgdGV4dGFyZWEsIGFuZCB1cGRhdGUgdGhlIGRvY3VtZW50IHRvIG1hdGNoLlxuICAvLyBXaGVuIHNvbWV0aGluZyBpcyBzZWxlY3RlZCwgaXQgaXMgcHJlc2VudCBpbiB0aGUgdGV4dGFyZWEsIGFuZFxuICAvLyBzZWxlY3RlZCAodW5sZXNzIGl0IGlzIGh1Z2UsIGluIHdoaWNoIGNhc2UgYSBwbGFjZWhvbGRlciBpc1xuICAvLyB1c2VkKS4gV2hlbiBub3RoaW5nIGlzIHNlbGVjdGVkLCB0aGUgY3Vyc29yIHNpdHMgYWZ0ZXIgcHJldmlvdXNseVxuICAvLyBzZWVuIHRleHQgKGNhbiBiZSBlbXB0eSksIHdoaWNoIGlzIHN0b3JlZCBpbiBwcmV2SW5wdXQgKHdlIG11c3RcbiAgLy8gbm90IHJlc2V0IHRoZSB0ZXh0YXJlYSB3aGVuIHR5cGluZywgYmVjYXVzZSB0aGF0IGJyZWFrcyBJTUUpLlxuICBmdW5jdGlvbiByZWFkSW5wdXQoY20pIHtcbiAgICB2YXIgaW5wdXQgPSBjbS5kaXNwbGF5LmlucHV0LCBwcmV2SW5wdXQgPSBjbS5kaXNwbGF5LnByZXZJbnB1dCwgZG9jID0gY20uZG9jO1xuICAgIC8vIFNpbmNlIHRoaXMgaXMgY2FsbGVkIGEgKmxvdCosIHRyeSB0byBiYWlsIG91dCBhcyBjaGVhcGx5IGFzXG4gICAgLy8gcG9zc2libGUgd2hlbiBpdCBpcyBjbGVhciB0aGF0IG5vdGhpbmcgaGFwcGVuZWQuIGhhc1NlbGVjdGlvblxuICAgIC8vIHdpbGwgYmUgdGhlIGNhc2Ugd2hlbiB0aGVyZSBpcyBhIGxvdCBvZiB0ZXh0IGluIHRoZSB0ZXh0YXJlYSxcbiAgICAvLyBpbiB3aGljaCBjYXNlIHJlYWRpbmcgaXRzIHZhbHVlIHdvdWxkIGJlIGV4cGVuc2l2ZS5cbiAgICBpZiAoIWNtLnN0YXRlLmZvY3VzZWQgfHwgKGhhc1NlbGVjdGlvbihpbnB1dCkgJiYgIXByZXZJbnB1dCkgfHwgaXNSZWFkT25seShjbSkgfHwgY20ub3B0aW9ucy5kaXNhYmxlSW5wdXQgfHwgY20uc3RhdGUua2V5U2VxKVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIC8vIFNlZSBwYXN0ZSBoYW5kbGVyIGZvciBtb3JlIG9uIHRoZSBmYWtlZExhc3RDaGFyIGtsdWRnZVxuICAgIGlmIChjbS5zdGF0ZS5wYXN0ZUluY29taW5nICYmIGNtLnN0YXRlLmZha2VkTGFzdENoYXIpIHtcbiAgICAgIGlucHV0LnZhbHVlID0gaW5wdXQudmFsdWUuc3Vic3RyaW5nKDAsIGlucHV0LnZhbHVlLmxlbmd0aCAtIDEpO1xuICAgICAgY20uc3RhdGUuZmFrZWRMYXN0Q2hhciA9IGZhbHNlO1xuICAgIH1cbiAgICB2YXIgdGV4dCA9IGlucHV0LnZhbHVlO1xuICAgIC8vIElmIG5vdGhpbmcgY2hhbmdlZCwgYmFpbC5cbiAgICBpZiAodGV4dCA9PSBwcmV2SW5wdXQgJiYgIWNtLnNvbWV0aGluZ1NlbGVjdGVkKCkpIHJldHVybiBmYWxzZTtcbiAgICAvLyBXb3JrIGFyb3VuZCBub25zZW5zaWNhbCBzZWxlY3Rpb24gcmVzZXR0aW5nIGluIElFOS8xMCwgYW5kXG4gICAgLy8gaW5leHBsaWNhYmxlIGFwcGVhcmFuY2Ugb2YgcHJpdmF0ZSBhcmVhIHVuaWNvZGUgY2hhcmFjdGVycyBvblxuICAgIC8vIHNvbWUga2V5IGNvbWJvcyBpbiBNYWMgKCMyNjg5KS5cbiAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA+PSA5ICYmIGNtLmRpc3BsYXkuaW5wdXRIYXNTZWxlY3Rpb24gPT09IHRleHQgfHxcbiAgICAgICAgbWFjICYmIC9bXFx1ZjcwMC1cXHVmN2ZmXS8udGVzdCh0ZXh0KSkge1xuICAgICAgcmVzZXRJbnB1dChjbSk7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdmFyIHdpdGhPcCA9ICFjbS5jdXJPcDtcbiAgICBpZiAod2l0aE9wKSBzdGFydE9wZXJhdGlvbihjbSk7XG4gICAgY20uZGlzcGxheS5zaGlmdCA9IGZhbHNlO1xuXG4gICAgaWYgKHRleHQuY2hhckNvZGVBdCgwKSA9PSAweDIwMGIgJiYgZG9jLnNlbCA9PSBjbS5kaXNwbGF5LnNlbEZvckNvbnRleHRNZW51ICYmICFwcmV2SW5wdXQpXG4gICAgICBwcmV2SW5wdXQgPSBcIlxcdTIwMGJcIjtcbiAgICAvLyBGaW5kIHRoZSBwYXJ0IG9mIHRoZSBpbnB1dCB0aGF0IGlzIGFjdHVhbGx5IG5ld1xuICAgIHZhciBzYW1lID0gMCwgbCA9IE1hdGgubWluKHByZXZJbnB1dC5sZW5ndGgsIHRleHQubGVuZ3RoKTtcbiAgICB3aGlsZSAoc2FtZSA8IGwgJiYgcHJldklucHV0LmNoYXJDb2RlQXQoc2FtZSkgPT0gdGV4dC5jaGFyQ29kZUF0KHNhbWUpKSArK3NhbWU7XG4gICAgdmFyIGluc2VydGVkID0gdGV4dC5zbGljZShzYW1lKSwgdGV4dExpbmVzID0gc3BsaXRMaW5lcyhpbnNlcnRlZCk7XG5cbiAgICAvLyBXaGVuIHBhc2luZyBOIGxpbmVzIGludG8gTiBzZWxlY3Rpb25zLCBpbnNlcnQgb25lIGxpbmUgcGVyIHNlbGVjdGlvblxuICAgIHZhciBtdWx0aVBhc3RlID0gbnVsbDtcbiAgICBpZiAoY20uc3RhdGUucGFzdGVJbmNvbWluZyAmJiBkb2Muc2VsLnJhbmdlcy5sZW5ndGggPiAxKSB7XG4gICAgICBpZiAobGFzdENvcGllZCAmJiBsYXN0Q29waWVkLmpvaW4oXCJcXG5cIikgPT0gaW5zZXJ0ZWQpXG4gICAgICAgIG11bHRpUGFzdGUgPSBkb2Muc2VsLnJhbmdlcy5sZW5ndGggJSBsYXN0Q29waWVkLmxlbmd0aCA9PSAwICYmIG1hcChsYXN0Q29waWVkLCBzcGxpdExpbmVzKTtcbiAgICAgIGVsc2UgaWYgKHRleHRMaW5lcy5sZW5ndGggPT0gZG9jLnNlbC5yYW5nZXMubGVuZ3RoKVxuICAgICAgICBtdWx0aVBhc3RlID0gbWFwKHRleHRMaW5lcywgZnVuY3Rpb24obCkgeyByZXR1cm4gW2xdOyB9KTtcbiAgICB9XG5cbiAgICAvLyBOb3JtYWwgYmVoYXZpb3IgaXMgdG8gaW5zZXJ0IHRoZSBuZXcgdGV4dCBpbnRvIGV2ZXJ5IHNlbGVjdGlvblxuICAgIGZvciAodmFyIGkgPSBkb2Muc2VsLnJhbmdlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSkge1xuICAgICAgdmFyIHJhbmdlID0gZG9jLnNlbC5yYW5nZXNbaV07XG4gICAgICB2YXIgZnJvbSA9IHJhbmdlLmZyb20oKSwgdG8gPSByYW5nZS50bygpO1xuICAgICAgLy8gSGFuZGxlIGRlbGV0aW9uXG4gICAgICBpZiAoc2FtZSA8IHByZXZJbnB1dC5sZW5ndGgpXG4gICAgICAgIGZyb20gPSBQb3MoZnJvbS5saW5lLCBmcm9tLmNoIC0gKHByZXZJbnB1dC5sZW5ndGggLSBzYW1lKSk7XG4gICAgICAvLyBIYW5kbGUgb3ZlcndyaXRlXG4gICAgICBlbHNlIGlmIChjbS5zdGF0ZS5vdmVyd3JpdGUgJiYgcmFuZ2UuZW1wdHkoKSAmJiAhY20uc3RhdGUucGFzdGVJbmNvbWluZylcbiAgICAgICAgdG8gPSBQb3ModG8ubGluZSwgTWF0aC5taW4oZ2V0TGluZShkb2MsIHRvLmxpbmUpLnRleHQubGVuZ3RoLCB0by5jaCArIGxzdCh0ZXh0TGluZXMpLmxlbmd0aCkpO1xuICAgICAgdmFyIHVwZGF0ZUlucHV0ID0gY20uY3VyT3AudXBkYXRlSW5wdXQ7XG4gICAgICB2YXIgY2hhbmdlRXZlbnQgPSB7ZnJvbTogZnJvbSwgdG86IHRvLCB0ZXh0OiBtdWx0aVBhc3RlID8gbXVsdGlQYXN0ZVtpICUgbXVsdGlQYXN0ZS5sZW5ndGhdIDogdGV4dExpbmVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpbjogY20uc3RhdGUucGFzdGVJbmNvbWluZyA/IFwicGFzdGVcIiA6IGNtLnN0YXRlLmN1dEluY29taW5nID8gXCJjdXRcIiA6IFwiK2lucHV0XCJ9O1xuICAgICAgbWFrZUNoYW5nZShjbS5kb2MsIGNoYW5nZUV2ZW50KTtcbiAgICAgIHNpZ25hbExhdGVyKGNtLCBcImlucHV0UmVhZFwiLCBjbSwgY2hhbmdlRXZlbnQpO1xuICAgICAgLy8gV2hlbiBhbiAnZWxlY3RyaWMnIGNoYXJhY3RlciBpcyBpbnNlcnRlZCwgaW1tZWRpYXRlbHkgdHJpZ2dlciBhIHJlaW5kZW50XG4gICAgICBpZiAoaW5zZXJ0ZWQgJiYgIWNtLnN0YXRlLnBhc3RlSW5jb21pbmcgJiYgY20ub3B0aW9ucy5lbGVjdHJpY0NoYXJzICYmXG4gICAgICAgICAgY20ub3B0aW9ucy5zbWFydEluZGVudCAmJiByYW5nZS5oZWFkLmNoIDwgMTAwICYmXG4gICAgICAgICAgKCFpIHx8IGRvYy5zZWwucmFuZ2VzW2kgLSAxXS5oZWFkLmxpbmUgIT0gcmFuZ2UuaGVhZC5saW5lKSkge1xuICAgICAgICB2YXIgbW9kZSA9IGNtLmdldE1vZGVBdChyYW5nZS5oZWFkKTtcbiAgICAgICAgdmFyIGVuZCA9IGNoYW5nZUVuZChjaGFuZ2VFdmVudCk7XG4gICAgICAgIGlmIChtb2RlLmVsZWN0cmljQ2hhcnMpIHtcbiAgICAgICAgICBmb3IgKHZhciBqID0gMDsgaiA8IG1vZGUuZWxlY3RyaWNDaGFycy5sZW5ndGg7IGorKylcbiAgICAgICAgICAgIGlmIChpbnNlcnRlZC5pbmRleE9mKG1vZGUuZWxlY3RyaWNDaGFycy5jaGFyQXQoaikpID4gLTEpIHtcbiAgICAgICAgICAgICAgaW5kZW50TGluZShjbSwgZW5kLmxpbmUsIFwic21hcnRcIik7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKG1vZGUuZWxlY3RyaWNJbnB1dCkge1xuICAgICAgICAgIGlmIChtb2RlLmVsZWN0cmljSW5wdXQudGVzdChnZXRMaW5lKGRvYywgZW5kLmxpbmUpLnRleHQuc2xpY2UoMCwgZW5kLmNoKSkpXG4gICAgICAgICAgICBpbmRlbnRMaW5lKGNtLCBlbmQubGluZSwgXCJzbWFydFwiKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICBlbnN1cmVDdXJzb3JWaXNpYmxlKGNtKTtcbiAgICBjbS5jdXJPcC51cGRhdGVJbnB1dCA9IHVwZGF0ZUlucHV0O1xuICAgIGNtLmN1ck9wLnR5cGluZyA9IHRydWU7XG5cbiAgICAvLyBEb24ndCBsZWF2ZSBsb25nIHRleHQgaW4gdGhlIHRleHRhcmVhLCBzaW5jZSBpdCBtYWtlcyBmdXJ0aGVyIHBvbGxpbmcgc2xvd1xuICAgIGlmICh0ZXh0Lmxlbmd0aCA+IDEwMDAgfHwgdGV4dC5pbmRleE9mKFwiXFxuXCIpID4gLTEpIGlucHV0LnZhbHVlID0gY20uZGlzcGxheS5wcmV2SW5wdXQgPSBcIlwiO1xuICAgIGVsc2UgY20uZGlzcGxheS5wcmV2SW5wdXQgPSB0ZXh0O1xuICAgIGlmICh3aXRoT3ApIGVuZE9wZXJhdGlvbihjbSk7XG4gICAgY20uc3RhdGUucGFzdGVJbmNvbWluZyA9IGNtLnN0YXRlLmN1dEluY29taW5nID0gZmFsc2U7XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICAvLyBSZXNldCB0aGUgaW5wdXQgdG8gY29ycmVzcG9uZCB0byB0aGUgc2VsZWN0aW9uIChvciB0byBiZSBlbXB0eSxcbiAgLy8gd2hlbiBub3QgdHlwaW5nIGFuZCBub3RoaW5nIGlzIHNlbGVjdGVkKVxuICBmdW5jdGlvbiByZXNldElucHV0KGNtLCB0eXBpbmcpIHtcbiAgICBpZiAoY20uZGlzcGxheS5jb250ZXh0TWVudVBlbmRpbmcpIHJldHVybjtcbiAgICB2YXIgbWluaW1hbCwgc2VsZWN0ZWQsIGRvYyA9IGNtLmRvYztcbiAgICBpZiAoY20uc29tZXRoaW5nU2VsZWN0ZWQoKSkge1xuICAgICAgY20uZGlzcGxheS5wcmV2SW5wdXQgPSBcIlwiO1xuICAgICAgdmFyIHJhbmdlID0gZG9jLnNlbC5wcmltYXJ5KCk7XG4gICAgICBtaW5pbWFsID0gaGFzQ29weUV2ZW50ICYmXG4gICAgICAgIChyYW5nZS50bygpLmxpbmUgLSByYW5nZS5mcm9tKCkubGluZSA+IDEwMCB8fCAoc2VsZWN0ZWQgPSBjbS5nZXRTZWxlY3Rpb24oKSkubGVuZ3RoID4gMTAwMCk7XG4gICAgICB2YXIgY29udGVudCA9IG1pbmltYWwgPyBcIi1cIiA6IHNlbGVjdGVkIHx8IGNtLmdldFNlbGVjdGlvbigpO1xuICAgICAgY20uZGlzcGxheS5pbnB1dC52YWx1ZSA9IGNvbnRlbnQ7XG4gICAgICBpZiAoY20uc3RhdGUuZm9jdXNlZCkgc2VsZWN0SW5wdXQoY20uZGlzcGxheS5pbnB1dCk7XG4gICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA+PSA5KSBjbS5kaXNwbGF5LmlucHV0SGFzU2VsZWN0aW9uID0gY29udGVudDtcbiAgICB9IGVsc2UgaWYgKCF0eXBpbmcpIHtcbiAgICAgIGNtLmRpc3BsYXkucHJldklucHV0ID0gY20uZGlzcGxheS5pbnB1dC52YWx1ZSA9IFwiXCI7XG4gICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA+PSA5KSBjbS5kaXNwbGF5LmlucHV0SGFzU2VsZWN0aW9uID0gbnVsbDtcbiAgICB9XG4gICAgY20uZGlzcGxheS5pbmFjY3VyYXRlU2VsZWN0aW9uID0gbWluaW1hbDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvY3VzSW5wdXQoY20pIHtcbiAgICBpZiAoY20ub3B0aW9ucy5yZWFkT25seSAhPSBcIm5vY3Vyc29yXCIgJiYgKCFtb2JpbGUgfHwgYWN0aXZlRWx0KCkgIT0gY20uZGlzcGxheS5pbnB1dCkpXG4gICAgICBjbS5kaXNwbGF5LmlucHV0LmZvY3VzKCk7XG4gIH1cblxuICBmdW5jdGlvbiBlbnN1cmVGb2N1cyhjbSkge1xuICAgIGlmICghY20uc3RhdGUuZm9jdXNlZCkgeyBmb2N1c0lucHV0KGNtKTsgb25Gb2N1cyhjbSk7IH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGlzUmVhZE9ubHkoY20pIHtcbiAgICByZXR1cm4gY20ub3B0aW9ucy5yZWFkT25seSB8fCBjbS5kb2MuY2FudEVkaXQ7XG4gIH1cblxuICAvLyBFVkVOVCBIQU5ETEVSU1xuXG4gIC8vIEF0dGFjaCB0aGUgbmVjZXNzYXJ5IGV2ZW50IGhhbmRsZXJzIHdoZW4gaW5pdGlhbGl6aW5nIHRoZSBlZGl0b3JcbiAgZnVuY3Rpb24gcmVnaXN0ZXJFdmVudEhhbmRsZXJzKGNtKSB7XG4gICAgdmFyIGQgPSBjbS5kaXNwbGF5O1xuICAgIG9uKGQuc2Nyb2xsZXIsIFwibW91c2Vkb3duXCIsIG9wZXJhdGlvbihjbSwgb25Nb3VzZURvd24pKTtcbiAgICAvLyBPbGRlciBJRSdzIHdpbGwgbm90IGZpcmUgYSBzZWNvbmQgbW91c2Vkb3duIGZvciBhIGRvdWJsZSBjbGlja1xuICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDwgMTEpXG4gICAgICBvbihkLnNjcm9sbGVyLCBcImRibGNsaWNrXCIsIG9wZXJhdGlvbihjbSwgZnVuY3Rpb24oZSkge1xuICAgICAgICBpZiAoc2lnbmFsRE9NRXZlbnQoY20sIGUpKSByZXR1cm47XG4gICAgICAgIHZhciBwb3MgPSBwb3NGcm9tTW91c2UoY20sIGUpO1xuICAgICAgICBpZiAoIXBvcyB8fCBjbGlja0luR3V0dGVyKGNtLCBlKSB8fCBldmVudEluV2lkZ2V0KGNtLmRpc3BsYXksIGUpKSByZXR1cm47XG4gICAgICAgIGVfcHJldmVudERlZmF1bHQoZSk7XG4gICAgICAgIHZhciB3b3JkID0gY20uZmluZFdvcmRBdChwb3MpO1xuICAgICAgICBleHRlbmRTZWxlY3Rpb24oY20uZG9jLCB3b3JkLmFuY2hvciwgd29yZC5oZWFkKTtcbiAgICAgIH0pKTtcbiAgICBlbHNlXG4gICAgICBvbihkLnNjcm9sbGVyLCBcImRibGNsaWNrXCIsIGZ1bmN0aW9uKGUpIHsgc2lnbmFsRE9NRXZlbnQoY20sIGUpIHx8IGVfcHJldmVudERlZmF1bHQoZSk7IH0pO1xuICAgIC8vIFByZXZlbnQgbm9ybWFsIHNlbGVjdGlvbiBpbiB0aGUgZWRpdG9yICh3ZSBoYW5kbGUgb3VyIG93bilcbiAgICBvbihkLmxpbmVTcGFjZSwgXCJzZWxlY3RzdGFydFwiLCBmdW5jdGlvbihlKSB7XG4gICAgICBpZiAoIWV2ZW50SW5XaWRnZXQoZCwgZSkpIGVfcHJldmVudERlZmF1bHQoZSk7XG4gICAgfSk7XG4gICAgLy8gU29tZSBicm93c2VycyBmaXJlIGNvbnRleHRtZW51ICphZnRlciogb3BlbmluZyB0aGUgbWVudSwgYXRcbiAgICAvLyB3aGljaCBwb2ludCB3ZSBjYW4ndCBtZXNzIHdpdGggaXQgYW55bW9yZS4gQ29udGV4dCBtZW51IGlzXG4gICAgLy8gaGFuZGxlZCBpbiBvbk1vdXNlRG93biBmb3IgdGhlc2UgYnJvd3NlcnMuXG4gICAgaWYgKCFjYXB0dXJlUmlnaHRDbGljaykgb24oZC5zY3JvbGxlciwgXCJjb250ZXh0bWVudVwiLCBmdW5jdGlvbihlKSB7b25Db250ZXh0TWVudShjbSwgZSk7fSk7XG5cbiAgICAvLyBTeW5jIHNjcm9sbGluZyBiZXR3ZWVuIGZha2Ugc2Nyb2xsYmFycyBhbmQgcmVhbCBzY3JvbGxhYmxlXG4gICAgLy8gYXJlYSwgZW5zdXJlIHZpZXdwb3J0IGlzIHVwZGF0ZWQgd2hlbiBzY3JvbGxpbmcuXG4gICAgb24oZC5zY3JvbGxlciwgXCJzY3JvbGxcIiwgZnVuY3Rpb24oKSB7XG4gICAgICBpZiAoZC5zY3JvbGxlci5jbGllbnRIZWlnaHQpIHtcbiAgICAgICAgc2V0U2Nyb2xsVG9wKGNtLCBkLnNjcm9sbGVyLnNjcm9sbFRvcCk7XG4gICAgICAgIHNldFNjcm9sbExlZnQoY20sIGQuc2Nyb2xsZXIuc2Nyb2xsTGVmdCwgdHJ1ZSk7XG4gICAgICAgIHNpZ25hbChjbSwgXCJzY3JvbGxcIiwgY20pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gTGlzdGVuIHRvIHdoZWVsIGV2ZW50cyBpbiBvcmRlciB0byB0cnkgYW5kIHVwZGF0ZSB0aGUgdmlld3BvcnQgb24gdGltZS5cbiAgICBvbihkLnNjcm9sbGVyLCBcIm1vdXNld2hlZWxcIiwgZnVuY3Rpb24oZSl7b25TY3JvbGxXaGVlbChjbSwgZSk7fSk7XG4gICAgb24oZC5zY3JvbGxlciwgXCJET01Nb3VzZVNjcm9sbFwiLCBmdW5jdGlvbihlKXtvblNjcm9sbFdoZWVsKGNtLCBlKTt9KTtcblxuICAgIC8vIFByZXZlbnQgd3JhcHBlciBmcm9tIGV2ZXIgc2Nyb2xsaW5nXG4gICAgb24oZC53cmFwcGVyLCBcInNjcm9sbFwiLCBmdW5jdGlvbigpIHsgZC53cmFwcGVyLnNjcm9sbFRvcCA9IGQud3JhcHBlci5zY3JvbGxMZWZ0ID0gMDsgfSk7XG5cbiAgICBvbihkLmlucHV0LCBcImtleXVwXCIsIGZ1bmN0aW9uKGUpIHsgb25LZXlVcC5jYWxsKGNtLCBlKTsgfSk7XG4gICAgb24oZC5pbnB1dCwgXCJpbnB1dFwiLCBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uID49IDkgJiYgY20uZGlzcGxheS5pbnB1dEhhc1NlbGVjdGlvbikgY20uZGlzcGxheS5pbnB1dEhhc1NlbGVjdGlvbiA9IG51bGw7XG4gICAgICByZWFkSW5wdXQoY20pO1xuICAgIH0pO1xuICAgIG9uKGQuaW5wdXQsIFwia2V5ZG93blwiLCBvcGVyYXRpb24oY20sIG9uS2V5RG93bikpO1xuICAgIG9uKGQuaW5wdXQsIFwia2V5cHJlc3NcIiwgb3BlcmF0aW9uKGNtLCBvbktleVByZXNzKSk7XG4gICAgb24oZC5pbnB1dCwgXCJmb2N1c1wiLCBiaW5kKG9uRm9jdXMsIGNtKSk7XG4gICAgb24oZC5pbnB1dCwgXCJibHVyXCIsIGJpbmQob25CbHVyLCBjbSkpO1xuXG4gICAgZnVuY3Rpb24gZHJhZ18oZSkge1xuICAgICAgaWYgKCFzaWduYWxET01FdmVudChjbSwgZSkpIGVfc3RvcChlKTtcbiAgICB9XG4gICAgaWYgKGNtLm9wdGlvbnMuZHJhZ0Ryb3ApIHtcbiAgICAgIG9uKGQuc2Nyb2xsZXIsIFwiZHJhZ3N0YXJ0XCIsIGZ1bmN0aW9uKGUpe29uRHJhZ1N0YXJ0KGNtLCBlKTt9KTtcbiAgICAgIG9uKGQuc2Nyb2xsZXIsIFwiZHJhZ2VudGVyXCIsIGRyYWdfKTtcbiAgICAgIG9uKGQuc2Nyb2xsZXIsIFwiZHJhZ292ZXJcIiwgZHJhZ18pO1xuICAgICAgb24oZC5zY3JvbGxlciwgXCJkcm9wXCIsIG9wZXJhdGlvbihjbSwgb25Ecm9wKSk7XG4gICAgfVxuICAgIG9uKGQuc2Nyb2xsZXIsIFwicGFzdGVcIiwgZnVuY3Rpb24oZSkge1xuICAgICAgaWYgKGV2ZW50SW5XaWRnZXQoZCwgZSkpIHJldHVybjtcbiAgICAgIGNtLnN0YXRlLnBhc3RlSW5jb21pbmcgPSB0cnVlO1xuICAgICAgZm9jdXNJbnB1dChjbSk7XG4gICAgICBmYXN0UG9sbChjbSk7XG4gICAgfSk7XG4gICAgb24oZC5pbnB1dCwgXCJwYXN0ZVwiLCBmdW5jdGlvbigpIHtcbiAgICAgIC8vIFdvcmthcm91bmQgZm9yIHdlYmtpdCBidWcgaHR0cHM6Ly9idWdzLndlYmtpdC5vcmcvc2hvd19idWcuY2dpP2lkPTkwMjA2XG4gICAgICAvLyBBZGQgYSBjaGFyIHRvIHRoZSBlbmQgb2YgdGV4dGFyZWEgYmVmb3JlIHBhc3RlIG9jY3VyIHNvIHRoYXRcbiAgICAgIC8vIHNlbGVjdGlvbiBkb2Vzbid0IHNwYW4gdG8gdGhlIGVuZCBvZiB0ZXh0YXJlYS5cbiAgICAgIGlmICh3ZWJraXQgJiYgIWNtLnN0YXRlLmZha2VkTGFzdENoYXIgJiYgIShuZXcgRGF0ZSAtIGNtLnN0YXRlLmxhc3RNaWRkbGVEb3duIDwgMjAwKSkge1xuICAgICAgICB2YXIgc3RhcnQgPSBkLmlucHV0LnNlbGVjdGlvblN0YXJ0LCBlbmQgPSBkLmlucHV0LnNlbGVjdGlvbkVuZDtcbiAgICAgICAgZC5pbnB1dC52YWx1ZSArPSBcIiRcIjtcbiAgICAgICAgLy8gVGhlIHNlbGVjdGlvbiBlbmQgbmVlZHMgdG8gYmUgc2V0IGJlZm9yZSB0aGUgc3RhcnQsIG90aGVyd2lzZSB0aGVyZVxuICAgICAgICAvLyBjYW4gYmUgYW4gaW50ZXJtZWRpYXRlIG5vbi1lbXB0eSBzZWxlY3Rpb24gYmV0d2VlbiB0aGUgdHdvLCB3aGljaFxuICAgICAgICAvLyBjYW4gb3ZlcnJpZGUgdGhlIG1pZGRsZS1jbGljayBwYXN0ZSBidWZmZXIgb24gbGludXggYW5kIGNhdXNlIHRoZVxuICAgICAgICAvLyB3cm9uZyB0aGluZyB0byBnZXQgcGFzdGVkLlxuICAgICAgICBkLmlucHV0LnNlbGVjdGlvbkVuZCA9IGVuZDtcbiAgICAgICAgZC5pbnB1dC5zZWxlY3Rpb25TdGFydCA9IHN0YXJ0O1xuICAgICAgICBjbS5zdGF0ZS5mYWtlZExhc3RDaGFyID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGNtLnN0YXRlLnBhc3RlSW5jb21pbmcgPSB0cnVlO1xuICAgICAgZmFzdFBvbGwoY20pO1xuICAgIH0pO1xuXG4gICAgZnVuY3Rpb24gcHJlcGFyZUNvcHlDdXQoZSkge1xuICAgICAgaWYgKGNtLnNvbWV0aGluZ1NlbGVjdGVkKCkpIHtcbiAgICAgICAgbGFzdENvcGllZCA9IGNtLmdldFNlbGVjdGlvbnMoKTtcbiAgICAgICAgaWYgKGQuaW5hY2N1cmF0ZVNlbGVjdGlvbikge1xuICAgICAgICAgIGQucHJldklucHV0ID0gXCJcIjtcbiAgICAgICAgICBkLmluYWNjdXJhdGVTZWxlY3Rpb24gPSBmYWxzZTtcbiAgICAgICAgICBkLmlucHV0LnZhbHVlID0gbGFzdENvcGllZC5qb2luKFwiXFxuXCIpO1xuICAgICAgICAgIHNlbGVjdElucHV0KGQuaW5wdXQpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgdGV4dCA9IFtdLCByYW5nZXMgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjbS5kb2Muc2VsLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBsaW5lID0gY20uZG9jLnNlbC5yYW5nZXNbaV0uaGVhZC5saW5lO1xuICAgICAgICAgIHZhciBsaW5lUmFuZ2UgPSB7YW5jaG9yOiBQb3MobGluZSwgMCksIGhlYWQ6IFBvcyhsaW5lICsgMSwgMCl9O1xuICAgICAgICAgIHJhbmdlcy5wdXNoKGxpbmVSYW5nZSk7XG4gICAgICAgICAgdGV4dC5wdXNoKGNtLmdldFJhbmdlKGxpbmVSYW5nZS5hbmNob3IsIGxpbmVSYW5nZS5oZWFkKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGUudHlwZSA9PSBcImN1dFwiKSB7XG4gICAgICAgICAgY20uc2V0U2VsZWN0aW9ucyhyYW5nZXMsIG51bGwsIHNlbF9kb250U2Nyb2xsKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBkLnByZXZJbnB1dCA9IFwiXCI7XG4gICAgICAgICAgZC5pbnB1dC52YWx1ZSA9IHRleHQuam9pbihcIlxcblwiKTtcbiAgICAgICAgICBzZWxlY3RJbnB1dChkLmlucHV0KTtcbiAgICAgICAgfVxuICAgICAgICBsYXN0Q29waWVkID0gdGV4dDtcbiAgICAgIH1cbiAgICAgIGlmIChlLnR5cGUgPT0gXCJjdXRcIikgY20uc3RhdGUuY3V0SW5jb21pbmcgPSB0cnVlO1xuICAgIH1cbiAgICBvbihkLmlucHV0LCBcImN1dFwiLCBwcmVwYXJlQ29weUN1dCk7XG4gICAgb24oZC5pbnB1dCwgXCJjb3B5XCIsIHByZXBhcmVDb3B5Q3V0KTtcblxuICAgIC8vIE5lZWRlZCB0byBoYW5kbGUgVGFiIGtleSBpbiBLSFRNTFxuICAgIGlmIChraHRtbCkgb24oZC5zaXplciwgXCJtb3VzZXVwXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGFjdGl2ZUVsdCgpID09IGQuaW5wdXQpIGQuaW5wdXQuYmx1cigpO1xuICAgICAgZm9jdXNJbnB1dChjbSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBDYWxsZWQgd2hlbiB0aGUgd2luZG93IHJlc2l6ZXNcbiAgZnVuY3Rpb24gb25SZXNpemUoY20pIHtcbiAgICB2YXIgZCA9IGNtLmRpc3BsYXk7XG4gICAgaWYgKGQubGFzdFdyYXBIZWlnaHQgPT0gZC53cmFwcGVyLmNsaWVudEhlaWdodCAmJiBkLmxhc3RXcmFwV2lkdGggPT0gZC53cmFwcGVyLmNsaWVudFdpZHRoKVxuICAgICAgcmV0dXJuO1xuICAgIC8vIE1pZ2h0IGJlIGEgdGV4dCBzY2FsaW5nIG9wZXJhdGlvbiwgY2xlYXIgc2l6ZSBjYWNoZXMuXG4gICAgZC5jYWNoZWRDaGFyV2lkdGggPSBkLmNhY2hlZFRleHRIZWlnaHQgPSBkLmNhY2hlZFBhZGRpbmdIID0gbnVsbDtcbiAgICBkLnNjcm9sbGJhcnNDbGlwcGVkID0gZmFsc2U7XG4gICAgY20uc2V0U2l6ZSgpO1xuICB9XG5cbiAgLy8gTU9VU0UgRVZFTlRTXG5cbiAgLy8gUmV0dXJuIHRydWUgd2hlbiB0aGUgZ2l2ZW4gbW91c2UgZXZlbnQgaGFwcGVuZWQgaW4gYSB3aWRnZXRcbiAgZnVuY3Rpb24gZXZlbnRJbldpZGdldChkaXNwbGF5LCBlKSB7XG4gICAgZm9yICh2YXIgbiA9IGVfdGFyZ2V0KGUpOyBuICE9IGRpc3BsYXkud3JhcHBlcjsgbiA9IG4ucGFyZW50Tm9kZSkge1xuICAgICAgaWYgKCFuIHx8IChuLm5vZGVUeXBlID09IDEgJiYgbi5nZXRBdHRyaWJ1dGUoXCJjbS1pZ25vcmUtZXZlbnRzXCIpID09IFwidHJ1ZVwiKSB8fFxuICAgICAgICAgIChuLnBhcmVudE5vZGUgPT0gZGlzcGxheS5zaXplciAmJiBuICE9IGRpc3BsYXkubW92ZXIpKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvLyBHaXZlbiBhIG1vdXNlIGV2ZW50LCBmaW5kIHRoZSBjb3JyZXNwb25kaW5nIHBvc2l0aW9uLiBJZiBsaWJlcmFsXG4gIC8vIGlzIGZhbHNlLCBpdCBjaGVja3Mgd2hldGhlciBhIGd1dHRlciBvciBzY3JvbGxiYXIgd2FzIGNsaWNrZWQsXG4gIC8vIGFuZCByZXR1cm5zIG51bGwgaWYgaXQgd2FzLiBmb3JSZWN0IGlzIHVzZWQgYnkgcmVjdGFuZ3VsYXJcbiAgLy8gc2VsZWN0aW9ucywgYW5kIHRyaWVzIHRvIGVzdGltYXRlIGEgY2hhcmFjdGVyIHBvc2l0aW9uIGV2ZW4gZm9yXG4gIC8vIGNvb3JkaW5hdGVzIGJleW9uZCB0aGUgcmlnaHQgb2YgdGhlIHRleHQuXG4gIGZ1bmN0aW9uIHBvc0Zyb21Nb3VzZShjbSwgZSwgbGliZXJhbCwgZm9yUmVjdCkge1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheTtcbiAgICBpZiAoIWxpYmVyYWwgJiYgZV90YXJnZXQoZSkuZ2V0QXR0cmlidXRlKFwibm90LWNvbnRlbnRcIikgPT0gXCJ0cnVlXCIpIHJldHVybiBudWxsO1xuXG4gICAgdmFyIHgsIHksIHNwYWNlID0gZGlzcGxheS5saW5lU3BhY2UuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgLy8gRmFpbHMgdW5wcmVkaWN0YWJseSBvbiBJRVs2N10gd2hlbiBtb3VzZSBpcyBkcmFnZ2VkIGFyb3VuZCBxdWlja2x5LlxuICAgIHRyeSB7IHggPSBlLmNsaWVudFggLSBzcGFjZS5sZWZ0OyB5ID0gZS5jbGllbnRZIC0gc3BhY2UudG9wOyB9XG4gICAgY2F0Y2ggKGUpIHsgcmV0dXJuIG51bGw7IH1cbiAgICB2YXIgY29vcmRzID0gY29vcmRzQ2hhcihjbSwgeCwgeSksIGxpbmU7XG4gICAgaWYgKGZvclJlY3QgJiYgY29vcmRzLnhSZWwgPT0gMSAmJiAobGluZSA9IGdldExpbmUoY20uZG9jLCBjb29yZHMubGluZSkudGV4dCkubGVuZ3RoID09IGNvb3Jkcy5jaCkge1xuICAgICAgdmFyIGNvbERpZmYgPSBjb3VudENvbHVtbihsaW5lLCBsaW5lLmxlbmd0aCwgY20ub3B0aW9ucy50YWJTaXplKSAtIGxpbmUubGVuZ3RoO1xuICAgICAgY29vcmRzID0gUG9zKGNvb3Jkcy5saW5lLCBNYXRoLm1heCgwLCBNYXRoLnJvdW5kKCh4IC0gcGFkZGluZ0goY20uZGlzcGxheSkubGVmdCkgLyBjaGFyV2lkdGgoY20uZGlzcGxheSkpIC0gY29sRGlmZikpO1xuICAgIH1cbiAgICByZXR1cm4gY29vcmRzO1xuICB9XG5cbiAgLy8gQSBtb3VzZSBkb3duIGNhbiBiZSBhIHNpbmdsZSBjbGljaywgZG91YmxlIGNsaWNrLCB0cmlwbGUgY2xpY2ssXG4gIC8vIHN0YXJ0IG9mIHNlbGVjdGlvbiBkcmFnLCBzdGFydCBvZiB0ZXh0IGRyYWcsIG5ldyBjdXJzb3JcbiAgLy8gKGN0cmwtY2xpY2spLCByZWN0YW5nbGUgZHJhZyAoYWx0LWRyYWcpLCBvciB4d2luXG4gIC8vIG1pZGRsZS1jbGljay1wYXN0ZS4gT3IgaXQgbWlnaHQgYmUgYSBjbGljayBvbiBzb21ldGhpbmcgd2Ugc2hvdWxkXG4gIC8vIG5vdCBpbnRlcmZlcmUgd2l0aCwgc3VjaCBhcyBhIHNjcm9sbGJhciBvciB3aWRnZXQuXG4gIGZ1bmN0aW9uIG9uTW91c2VEb3duKGUpIHtcbiAgICBpZiAoc2lnbmFsRE9NRXZlbnQodGhpcywgZSkpIHJldHVybjtcbiAgICB2YXIgY20gPSB0aGlzLCBkaXNwbGF5ID0gY20uZGlzcGxheTtcbiAgICBkaXNwbGF5LnNoaWZ0ID0gZS5zaGlmdEtleTtcblxuICAgIGlmIChldmVudEluV2lkZ2V0KGRpc3BsYXksIGUpKSB7XG4gICAgICBpZiAoIXdlYmtpdCkge1xuICAgICAgICAvLyBCcmllZmx5IHR1cm4gb2ZmIGRyYWdnYWJpbGl0eSwgdG8gYWxsb3cgd2lkZ2V0cyB0byBkb1xuICAgICAgICAvLyBub3JtYWwgZHJhZ2dpbmcgdGhpbmdzLlxuICAgICAgICBkaXNwbGF5LnNjcm9sbGVyLmRyYWdnYWJsZSA9IGZhbHNlO1xuICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCl7ZGlzcGxheS5zY3JvbGxlci5kcmFnZ2FibGUgPSB0cnVlO30sIDEwMCk7XG4gICAgICB9XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjbGlja0luR3V0dGVyKGNtLCBlKSkgcmV0dXJuO1xuICAgIHZhciBzdGFydCA9IHBvc0Zyb21Nb3VzZShjbSwgZSk7XG4gICAgd2luZG93LmZvY3VzKCk7XG5cbiAgICBzd2l0Y2ggKGVfYnV0dG9uKGUpKSB7XG4gICAgY2FzZSAxOlxuICAgICAgaWYgKHN0YXJ0KVxuICAgICAgICBsZWZ0QnV0dG9uRG93bihjbSwgZSwgc3RhcnQpO1xuICAgICAgZWxzZSBpZiAoZV90YXJnZXQoZSkgPT0gZGlzcGxheS5zY3JvbGxlcilcbiAgICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgMjpcbiAgICAgIGlmICh3ZWJraXQpIGNtLnN0YXRlLmxhc3RNaWRkbGVEb3duID0gK25ldyBEYXRlO1xuICAgICAgaWYgKHN0YXJ0KSBleHRlbmRTZWxlY3Rpb24oY20uZG9jLCBzdGFydCk7XG4gICAgICBzZXRUaW1lb3V0KGJpbmQoZm9jdXNJbnB1dCwgY20pLCAyMCk7XG4gICAgICBlX3ByZXZlbnREZWZhdWx0KGUpO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAzOlxuICAgICAgaWYgKGNhcHR1cmVSaWdodENsaWNrKSBvbkNvbnRleHRNZW51KGNtLCBlKTtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHZhciBsYXN0Q2xpY2ssIGxhc3REb3VibGVDbGljaztcbiAgZnVuY3Rpb24gbGVmdEJ1dHRvbkRvd24oY20sIGUsIHN0YXJ0KSB7XG4gICAgc2V0VGltZW91dChiaW5kKGVuc3VyZUZvY3VzLCBjbSksIDApO1xuXG4gICAgdmFyIG5vdyA9ICtuZXcgRGF0ZSwgdHlwZTtcbiAgICBpZiAobGFzdERvdWJsZUNsaWNrICYmIGxhc3REb3VibGVDbGljay50aW1lID4gbm93IC0gNDAwICYmIGNtcChsYXN0RG91YmxlQ2xpY2sucG9zLCBzdGFydCkgPT0gMCkge1xuICAgICAgdHlwZSA9IFwidHJpcGxlXCI7XG4gICAgfSBlbHNlIGlmIChsYXN0Q2xpY2sgJiYgbGFzdENsaWNrLnRpbWUgPiBub3cgLSA0MDAgJiYgY21wKGxhc3RDbGljay5wb3MsIHN0YXJ0KSA9PSAwKSB7XG4gICAgICB0eXBlID0gXCJkb3VibGVcIjtcbiAgICAgIGxhc3REb3VibGVDbGljayA9IHt0aW1lOiBub3csIHBvczogc3RhcnR9O1xuICAgIH0gZWxzZSB7XG4gICAgICB0eXBlID0gXCJzaW5nbGVcIjtcbiAgICAgIGxhc3RDbGljayA9IHt0aW1lOiBub3csIHBvczogc3RhcnR9O1xuICAgIH1cblxuICAgIHZhciBzZWwgPSBjbS5kb2Muc2VsLCBtb2RpZmllciA9IG1hYyA/IGUubWV0YUtleSA6IGUuY3RybEtleSwgY29udGFpbmVkO1xuICAgIGlmIChjbS5vcHRpb25zLmRyYWdEcm9wICYmIGRyYWdBbmREcm9wICYmICFpc1JlYWRPbmx5KGNtKSAmJlxuICAgICAgICB0eXBlID09IFwic2luZ2xlXCIgJiYgKGNvbnRhaW5lZCA9IHNlbC5jb250YWlucyhzdGFydCkpID4gLTEgJiZcbiAgICAgICAgIXNlbC5yYW5nZXNbY29udGFpbmVkXS5lbXB0eSgpKVxuICAgICAgbGVmdEJ1dHRvblN0YXJ0RHJhZyhjbSwgZSwgc3RhcnQsIG1vZGlmaWVyKTtcbiAgICBlbHNlXG4gICAgICBsZWZ0QnV0dG9uU2VsZWN0KGNtLCBlLCBzdGFydCwgdHlwZSwgbW9kaWZpZXIpO1xuICB9XG5cbiAgLy8gU3RhcnQgYSB0ZXh0IGRyYWcuIFdoZW4gaXQgZW5kcywgc2VlIGlmIGFueSBkcmFnZ2luZyBhY3R1YWxseVxuICAvLyBoYXBwZW4sIGFuZCB0cmVhdCBhcyBhIGNsaWNrIGlmIGl0IGRpZG4ndC5cbiAgZnVuY3Rpb24gbGVmdEJ1dHRvblN0YXJ0RHJhZyhjbSwgZSwgc3RhcnQsIG1vZGlmaWVyKSB7XG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5O1xuICAgIHZhciBkcmFnRW5kID0gb3BlcmF0aW9uKGNtLCBmdW5jdGlvbihlMikge1xuICAgICAgaWYgKHdlYmtpdCkgZGlzcGxheS5zY3JvbGxlci5kcmFnZ2FibGUgPSBmYWxzZTtcbiAgICAgIGNtLnN0YXRlLmRyYWdnaW5nVGV4dCA9IGZhbHNlO1xuICAgICAgb2ZmKGRvY3VtZW50LCBcIm1vdXNldXBcIiwgZHJhZ0VuZCk7XG4gICAgICBvZmYoZGlzcGxheS5zY3JvbGxlciwgXCJkcm9wXCIsIGRyYWdFbmQpO1xuICAgICAgaWYgKE1hdGguYWJzKGUuY2xpZW50WCAtIGUyLmNsaWVudFgpICsgTWF0aC5hYnMoZS5jbGllbnRZIC0gZTIuY2xpZW50WSkgPCAxMCkge1xuICAgICAgICBlX3ByZXZlbnREZWZhdWx0KGUyKTtcbiAgICAgICAgaWYgKCFtb2RpZmllcilcbiAgICAgICAgICBleHRlbmRTZWxlY3Rpb24oY20uZG9jLCBzdGFydCk7XG4gICAgICAgIGZvY3VzSW5wdXQoY20pO1xuICAgICAgICAvLyBXb3JrIGFyb3VuZCB1bmV4cGxhaW5hYmxlIGZvY3VzIHByb2JsZW0gaW4gSUU5ICgjMjEyNylcbiAgICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPT0gOSlcbiAgICAgICAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge2RvY3VtZW50LmJvZHkuZm9jdXMoKTsgZm9jdXNJbnB1dChjbSk7fSwgMjApO1xuICAgICAgfVxuICAgIH0pO1xuICAgIC8vIExldCB0aGUgZHJhZyBoYW5kbGVyIGhhbmRsZSB0aGlzLlxuICAgIGlmICh3ZWJraXQpIGRpc3BsYXkuc2Nyb2xsZXIuZHJhZ2dhYmxlID0gdHJ1ZTtcbiAgICBjbS5zdGF0ZS5kcmFnZ2luZ1RleHQgPSBkcmFnRW5kO1xuICAgIC8vIElFJ3MgYXBwcm9hY2ggdG8gZHJhZ2dhYmxlXG4gICAgaWYgKGRpc3BsYXkuc2Nyb2xsZXIuZHJhZ0Ryb3ApIGRpc3BsYXkuc2Nyb2xsZXIuZHJhZ0Ryb3AoKTtcbiAgICBvbihkb2N1bWVudCwgXCJtb3VzZXVwXCIsIGRyYWdFbmQpO1xuICAgIG9uKGRpc3BsYXkuc2Nyb2xsZXIsIFwiZHJvcFwiLCBkcmFnRW5kKTtcbiAgfVxuXG4gIC8vIE5vcm1hbCBzZWxlY3Rpb24sIGFzIG9wcG9zZWQgdG8gdGV4dCBkcmFnZ2luZy5cbiAgZnVuY3Rpb24gbGVmdEJ1dHRvblNlbGVjdChjbSwgZSwgc3RhcnQsIHR5cGUsIGFkZE5ldykge1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheSwgZG9jID0gY20uZG9jO1xuICAgIGVfcHJldmVudERlZmF1bHQoZSk7XG5cbiAgICB2YXIgb3VyUmFuZ2UsIG91ckluZGV4LCBzdGFydFNlbCA9IGRvYy5zZWwsIHJhbmdlcyA9IHN0YXJ0U2VsLnJhbmdlcztcbiAgICBpZiAoYWRkTmV3ICYmICFlLnNoaWZ0S2V5KSB7XG4gICAgICBvdXJJbmRleCA9IGRvYy5zZWwuY29udGFpbnMoc3RhcnQpO1xuICAgICAgaWYgKG91ckluZGV4ID4gLTEpXG4gICAgICAgIG91clJhbmdlID0gcmFuZ2VzW291ckluZGV4XTtcbiAgICAgIGVsc2VcbiAgICAgICAgb3VyUmFuZ2UgPSBuZXcgUmFuZ2Uoc3RhcnQsIHN0YXJ0KTtcbiAgICB9IGVsc2Uge1xuICAgICAgb3VyUmFuZ2UgPSBkb2Muc2VsLnByaW1hcnkoKTtcbiAgICB9XG5cbiAgICBpZiAoZS5hbHRLZXkpIHtcbiAgICAgIHR5cGUgPSBcInJlY3RcIjtcbiAgICAgIGlmICghYWRkTmV3KSBvdXJSYW5nZSA9IG5ldyBSYW5nZShzdGFydCwgc3RhcnQpO1xuICAgICAgc3RhcnQgPSBwb3NGcm9tTW91c2UoY20sIGUsIHRydWUsIHRydWUpO1xuICAgICAgb3VySW5kZXggPSAtMTtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT0gXCJkb3VibGVcIikge1xuICAgICAgdmFyIHdvcmQgPSBjbS5maW5kV29yZEF0KHN0YXJ0KTtcbiAgICAgIGlmIChjbS5kaXNwbGF5LnNoaWZ0IHx8IGRvYy5leHRlbmQpXG4gICAgICAgIG91clJhbmdlID0gZXh0ZW5kUmFuZ2UoZG9jLCBvdXJSYW5nZSwgd29yZC5hbmNob3IsIHdvcmQuaGVhZCk7XG4gICAgICBlbHNlXG4gICAgICAgIG91clJhbmdlID0gd29yZDtcbiAgICB9IGVsc2UgaWYgKHR5cGUgPT0gXCJ0cmlwbGVcIikge1xuICAgICAgdmFyIGxpbmUgPSBuZXcgUmFuZ2UoUG9zKHN0YXJ0LmxpbmUsIDApLCBjbGlwUG9zKGRvYywgUG9zKHN0YXJ0LmxpbmUgKyAxLCAwKSkpO1xuICAgICAgaWYgKGNtLmRpc3BsYXkuc2hpZnQgfHwgZG9jLmV4dGVuZClcbiAgICAgICAgb3VyUmFuZ2UgPSBleHRlbmRSYW5nZShkb2MsIG91clJhbmdlLCBsaW5lLmFuY2hvciwgbGluZS5oZWFkKTtcbiAgICAgIGVsc2VcbiAgICAgICAgb3VyUmFuZ2UgPSBsaW5lO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdXJSYW5nZSA9IGV4dGVuZFJhbmdlKGRvYywgb3VyUmFuZ2UsIHN0YXJ0KTtcbiAgICB9XG5cbiAgICBpZiAoIWFkZE5ldykge1xuICAgICAgb3VySW5kZXggPSAwO1xuICAgICAgc2V0U2VsZWN0aW9uKGRvYywgbmV3IFNlbGVjdGlvbihbb3VyUmFuZ2VdLCAwKSwgc2VsX21vdXNlKTtcbiAgICAgIHN0YXJ0U2VsID0gZG9jLnNlbDtcbiAgICB9IGVsc2UgaWYgKG91ckluZGV4ID09IC0xKSB7XG4gICAgICBvdXJJbmRleCA9IHJhbmdlcy5sZW5ndGg7XG4gICAgICBzZXRTZWxlY3Rpb24oZG9jLCBub3JtYWxpemVTZWxlY3Rpb24ocmFuZ2VzLmNvbmNhdChbb3VyUmFuZ2VdKSwgb3VySW5kZXgpLFxuICAgICAgICAgICAgICAgICAgIHtzY3JvbGw6IGZhbHNlLCBvcmlnaW46IFwiKm1vdXNlXCJ9KTtcbiAgICB9IGVsc2UgaWYgKHJhbmdlcy5sZW5ndGggPiAxICYmIHJhbmdlc1tvdXJJbmRleF0uZW1wdHkoKSAmJiB0eXBlID09IFwic2luZ2xlXCIpIHtcbiAgICAgIHNldFNlbGVjdGlvbihkb2MsIG5vcm1hbGl6ZVNlbGVjdGlvbihyYW5nZXMuc2xpY2UoMCwgb3VySW5kZXgpLmNvbmNhdChyYW5nZXMuc2xpY2Uob3VySW5kZXggKyAxKSksIDApKTtcbiAgICAgIHN0YXJ0U2VsID0gZG9jLnNlbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmVwbGFjZU9uZVNlbGVjdGlvbihkb2MsIG91ckluZGV4LCBvdXJSYW5nZSwgc2VsX21vdXNlKTtcbiAgICB9XG5cbiAgICB2YXIgbGFzdFBvcyA9IHN0YXJ0O1xuICAgIGZ1bmN0aW9uIGV4dGVuZFRvKHBvcykge1xuICAgICAgaWYgKGNtcChsYXN0UG9zLCBwb3MpID09IDApIHJldHVybjtcbiAgICAgIGxhc3RQb3MgPSBwb3M7XG5cbiAgICAgIGlmICh0eXBlID09IFwicmVjdFwiKSB7XG4gICAgICAgIHZhciByYW5nZXMgPSBbXSwgdGFiU2l6ZSA9IGNtLm9wdGlvbnMudGFiU2l6ZTtcbiAgICAgICAgdmFyIHN0YXJ0Q29sID0gY291bnRDb2x1bW4oZ2V0TGluZShkb2MsIHN0YXJ0LmxpbmUpLnRleHQsIHN0YXJ0LmNoLCB0YWJTaXplKTtcbiAgICAgICAgdmFyIHBvc0NvbCA9IGNvdW50Q29sdW1uKGdldExpbmUoZG9jLCBwb3MubGluZSkudGV4dCwgcG9zLmNoLCB0YWJTaXplKTtcbiAgICAgICAgdmFyIGxlZnQgPSBNYXRoLm1pbihzdGFydENvbCwgcG9zQ29sKSwgcmlnaHQgPSBNYXRoLm1heChzdGFydENvbCwgcG9zQ29sKTtcbiAgICAgICAgZm9yICh2YXIgbGluZSA9IE1hdGgubWluKHN0YXJ0LmxpbmUsIHBvcy5saW5lKSwgZW5kID0gTWF0aC5taW4oY20ubGFzdExpbmUoKSwgTWF0aC5tYXgoc3RhcnQubGluZSwgcG9zLmxpbmUpKTtcbiAgICAgICAgICAgICBsaW5lIDw9IGVuZDsgbGluZSsrKSB7XG4gICAgICAgICAgdmFyIHRleHQgPSBnZXRMaW5lKGRvYywgbGluZSkudGV4dCwgbGVmdFBvcyA9IGZpbmRDb2x1bW4odGV4dCwgbGVmdCwgdGFiU2l6ZSk7XG4gICAgICAgICAgaWYgKGxlZnQgPT0gcmlnaHQpXG4gICAgICAgICAgICByYW5nZXMucHVzaChuZXcgUmFuZ2UoUG9zKGxpbmUsIGxlZnRQb3MpLCBQb3MobGluZSwgbGVmdFBvcykpKTtcbiAgICAgICAgICBlbHNlIGlmICh0ZXh0Lmxlbmd0aCA+IGxlZnRQb3MpXG4gICAgICAgICAgICByYW5nZXMucHVzaChuZXcgUmFuZ2UoUG9zKGxpbmUsIGxlZnRQb3MpLCBQb3MobGluZSwgZmluZENvbHVtbih0ZXh0LCByaWdodCwgdGFiU2l6ZSkpKSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFyYW5nZXMubGVuZ3RoKSByYW5nZXMucHVzaChuZXcgUmFuZ2Uoc3RhcnQsIHN0YXJ0KSk7XG4gICAgICAgIHNldFNlbGVjdGlvbihkb2MsIG5vcm1hbGl6ZVNlbGVjdGlvbihzdGFydFNlbC5yYW5nZXMuc2xpY2UoMCwgb3VySW5kZXgpLmNvbmNhdChyYW5nZXMpLCBvdXJJbmRleCksXG4gICAgICAgICAgICAgICAgICAgICB7b3JpZ2luOiBcIiptb3VzZVwiLCBzY3JvbGw6IGZhbHNlfSk7XG4gICAgICAgIGNtLnNjcm9sbEludG9WaWV3KHBvcyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgb2xkUmFuZ2UgPSBvdXJSYW5nZTtcbiAgICAgICAgdmFyIGFuY2hvciA9IG9sZFJhbmdlLmFuY2hvciwgaGVhZCA9IHBvcztcbiAgICAgICAgaWYgKHR5cGUgIT0gXCJzaW5nbGVcIikge1xuICAgICAgICAgIGlmICh0eXBlID09IFwiZG91YmxlXCIpXG4gICAgICAgICAgICB2YXIgcmFuZ2UgPSBjbS5maW5kV29yZEF0KHBvcyk7XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgdmFyIHJhbmdlID0gbmV3IFJhbmdlKFBvcyhwb3MubGluZSwgMCksIGNsaXBQb3MoZG9jLCBQb3MocG9zLmxpbmUgKyAxLCAwKSkpO1xuICAgICAgICAgIGlmIChjbXAocmFuZ2UuYW5jaG9yLCBhbmNob3IpID4gMCkge1xuICAgICAgICAgICAgaGVhZCA9IHJhbmdlLmhlYWQ7XG4gICAgICAgICAgICBhbmNob3IgPSBtaW5Qb3Mob2xkUmFuZ2UuZnJvbSgpLCByYW5nZS5hbmNob3IpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBoZWFkID0gcmFuZ2UuYW5jaG9yO1xuICAgICAgICAgICAgYW5jaG9yID0gbWF4UG9zKG9sZFJhbmdlLnRvKCksIHJhbmdlLmhlYWQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICB2YXIgcmFuZ2VzID0gc3RhcnRTZWwucmFuZ2VzLnNsaWNlKDApO1xuICAgICAgICByYW5nZXNbb3VySW5kZXhdID0gbmV3IFJhbmdlKGNsaXBQb3MoZG9jLCBhbmNob3IpLCBoZWFkKTtcbiAgICAgICAgc2V0U2VsZWN0aW9uKGRvYywgbm9ybWFsaXplU2VsZWN0aW9uKHJhbmdlcywgb3VySW5kZXgpLCBzZWxfbW91c2UpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHZhciBlZGl0b3JTaXplID0gZGlzcGxheS53cmFwcGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIC8vIFVzZWQgdG8gZW5zdXJlIHRpbWVvdXQgcmUtdHJpZXMgZG9uJ3QgZmlyZSB3aGVuIGFub3RoZXIgZXh0ZW5kXG4gICAgLy8gaGFwcGVuZWQgaW4gdGhlIG1lYW50aW1lIChjbGVhclRpbWVvdXQgaXNuJ3QgcmVsaWFibGUgLS0gYXRcbiAgICAvLyBsZWFzdCBvbiBDaHJvbWUsIHRoZSB0aW1lb3V0cyBzdGlsbCBoYXBwZW4gZXZlbiB3aGVuIGNsZWFyZWQsXG4gICAgLy8gaWYgdGhlIGNsZWFyIGhhcHBlbnMgYWZ0ZXIgdGhlaXIgc2NoZWR1bGVkIGZpcmluZyB0aW1lKS5cbiAgICB2YXIgY291bnRlciA9IDA7XG5cbiAgICBmdW5jdGlvbiBleHRlbmQoZSkge1xuICAgICAgdmFyIGN1ckNvdW50ID0gKytjb3VudGVyO1xuICAgICAgdmFyIGN1ciA9IHBvc0Zyb21Nb3VzZShjbSwgZSwgdHJ1ZSwgdHlwZSA9PSBcInJlY3RcIik7XG4gICAgICBpZiAoIWN1cikgcmV0dXJuO1xuICAgICAgaWYgKGNtcChjdXIsIGxhc3RQb3MpICE9IDApIHtcbiAgICAgICAgZW5zdXJlRm9jdXMoY20pO1xuICAgICAgICBleHRlbmRUbyhjdXIpO1xuICAgICAgICB2YXIgdmlzaWJsZSA9IHZpc2libGVMaW5lcyhkaXNwbGF5LCBkb2MpO1xuICAgICAgICBpZiAoY3VyLmxpbmUgPj0gdmlzaWJsZS50byB8fCBjdXIubGluZSA8IHZpc2libGUuZnJvbSlcbiAgICAgICAgICBzZXRUaW1lb3V0KG9wZXJhdGlvbihjbSwgZnVuY3Rpb24oKXtpZiAoY291bnRlciA9PSBjdXJDb3VudCkgZXh0ZW5kKGUpO30pLCAxNTApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIG91dHNpZGUgPSBlLmNsaWVudFkgPCBlZGl0b3JTaXplLnRvcCA/IC0yMCA6IGUuY2xpZW50WSA+IGVkaXRvclNpemUuYm90dG9tID8gMjAgOiAwO1xuICAgICAgICBpZiAob3V0c2lkZSkgc2V0VGltZW91dChvcGVyYXRpb24oY20sIGZ1bmN0aW9uKCkge1xuICAgICAgICAgIGlmIChjb3VudGVyICE9IGN1ckNvdW50KSByZXR1cm47XG4gICAgICAgICAgZGlzcGxheS5zY3JvbGxlci5zY3JvbGxUb3AgKz0gb3V0c2lkZTtcbiAgICAgICAgICBleHRlbmQoZSk7XG4gICAgICAgIH0pLCA1MCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZG9uZShlKSB7XG4gICAgICBjb3VudGVyID0gSW5maW5pdHk7XG4gICAgICBlX3ByZXZlbnREZWZhdWx0KGUpO1xuICAgICAgZm9jdXNJbnB1dChjbSk7XG4gICAgICBvZmYoZG9jdW1lbnQsIFwibW91c2Vtb3ZlXCIsIG1vdmUpO1xuICAgICAgb2ZmKGRvY3VtZW50LCBcIm1vdXNldXBcIiwgdXApO1xuICAgICAgZG9jLmhpc3RvcnkubGFzdFNlbE9yaWdpbiA9IG51bGw7XG4gICAgfVxuXG4gICAgdmFyIG1vdmUgPSBvcGVyYXRpb24oY20sIGZ1bmN0aW9uKGUpIHtcbiAgICAgIGlmICghZV9idXR0b24oZSkpIGRvbmUoZSk7XG4gICAgICBlbHNlIGV4dGVuZChlKTtcbiAgICB9KTtcbiAgICB2YXIgdXAgPSBvcGVyYXRpb24oY20sIGRvbmUpO1xuICAgIG9uKGRvY3VtZW50LCBcIm1vdXNlbW92ZVwiLCBtb3ZlKTtcbiAgICBvbihkb2N1bWVudCwgXCJtb3VzZXVwXCIsIHVwKTtcbiAgfVxuXG4gIC8vIERldGVybWluZXMgd2hldGhlciBhbiBldmVudCBoYXBwZW5lZCBpbiB0aGUgZ3V0dGVyLCBhbmQgZmlyZXMgdGhlXG4gIC8vIGhhbmRsZXJzIGZvciB0aGUgY29ycmVzcG9uZGluZyBldmVudC5cbiAgZnVuY3Rpb24gZ3V0dGVyRXZlbnQoY20sIGUsIHR5cGUsIHByZXZlbnQsIHNpZ25hbGZuKSB7XG4gICAgdHJ5IHsgdmFyIG1YID0gZS5jbGllbnRYLCBtWSA9IGUuY2xpZW50WTsgfVxuICAgIGNhdGNoKGUpIHsgcmV0dXJuIGZhbHNlOyB9XG4gICAgaWYgKG1YID49IE1hdGguZmxvb3IoY20uZGlzcGxheS5ndXR0ZXJzLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnJpZ2h0KSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChwcmV2ZW50KSBlX3ByZXZlbnREZWZhdWx0KGUpO1xuXG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5O1xuICAgIHZhciBsaW5lQm94ID0gZGlzcGxheS5saW5lRGl2LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgaWYgKG1ZID4gbGluZUJveC5ib3R0b20gfHwgIWhhc0hhbmRsZXIoY20sIHR5cGUpKSByZXR1cm4gZV9kZWZhdWx0UHJldmVudGVkKGUpO1xuICAgIG1ZIC09IGxpbmVCb3gudG9wIC0gZGlzcGxheS52aWV3T2Zmc2V0O1xuXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjbS5vcHRpb25zLmd1dHRlcnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBnID0gZGlzcGxheS5ndXR0ZXJzLmNoaWxkTm9kZXNbaV07XG4gICAgICBpZiAoZyAmJiBnLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnJpZ2h0ID49IG1YKSB7XG4gICAgICAgIHZhciBsaW5lID0gbGluZUF0SGVpZ2h0KGNtLmRvYywgbVkpO1xuICAgICAgICB2YXIgZ3V0dGVyID0gY20ub3B0aW9ucy5ndXR0ZXJzW2ldO1xuICAgICAgICBzaWduYWxmbihjbSwgdHlwZSwgY20sIGxpbmUsIGd1dHRlciwgZSk7XG4gICAgICAgIHJldHVybiBlX2RlZmF1bHRQcmV2ZW50ZWQoZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gY2xpY2tJbkd1dHRlcihjbSwgZSkge1xuICAgIHJldHVybiBndXR0ZXJFdmVudChjbSwgZSwgXCJndXR0ZXJDbGlja1wiLCB0cnVlLCBzaWduYWxMYXRlcik7XG4gIH1cblxuICAvLyBLbHVkZ2UgdG8gd29yayBhcm91bmQgc3RyYW5nZSBJRSBiZWhhdmlvciB3aGVyZSBpdCdsbCBzb21ldGltZXNcbiAgLy8gcmUtZmlyZSBhIHNlcmllcyBvZiBkcmFnLXJlbGF0ZWQgZXZlbnRzIHJpZ2h0IGFmdGVyIHRoZSBkcm9wICgjMTU1MSlcbiAgdmFyIGxhc3REcm9wID0gMDtcblxuICBmdW5jdGlvbiBvbkRyb3AoZSkge1xuICAgIHZhciBjbSA9IHRoaXM7XG4gICAgaWYgKHNpZ25hbERPTUV2ZW50KGNtLCBlKSB8fCBldmVudEluV2lkZ2V0KGNtLmRpc3BsYXksIGUpKVxuICAgICAgcmV0dXJuO1xuICAgIGVfcHJldmVudERlZmF1bHQoZSk7XG4gICAgaWYgKGllKSBsYXN0RHJvcCA9ICtuZXcgRGF0ZTtcbiAgICB2YXIgcG9zID0gcG9zRnJvbU1vdXNlKGNtLCBlLCB0cnVlKSwgZmlsZXMgPSBlLmRhdGFUcmFuc2Zlci5maWxlcztcbiAgICBpZiAoIXBvcyB8fCBpc1JlYWRPbmx5KGNtKSkgcmV0dXJuO1xuICAgIC8vIE1pZ2h0IGJlIGEgZmlsZSBkcm9wLCBpbiB3aGljaCBjYXNlIHdlIHNpbXBseSBleHRyYWN0IHRoZSB0ZXh0XG4gICAgLy8gYW5kIGluc2VydCBpdC5cbiAgICBpZiAoZmlsZXMgJiYgZmlsZXMubGVuZ3RoICYmIHdpbmRvdy5GaWxlUmVhZGVyICYmIHdpbmRvdy5GaWxlKSB7XG4gICAgICB2YXIgbiA9IGZpbGVzLmxlbmd0aCwgdGV4dCA9IEFycmF5KG4pLCByZWFkID0gMDtcbiAgICAgIHZhciBsb2FkRmlsZSA9IGZ1bmN0aW9uKGZpbGUsIGkpIHtcbiAgICAgICAgdmFyIHJlYWRlciA9IG5ldyBGaWxlUmVhZGVyO1xuICAgICAgICByZWFkZXIub25sb2FkID0gb3BlcmF0aW9uKGNtLCBmdW5jdGlvbigpIHtcbiAgICAgICAgICB0ZXh0W2ldID0gcmVhZGVyLnJlc3VsdDtcbiAgICAgICAgICBpZiAoKytyZWFkID09IG4pIHtcbiAgICAgICAgICAgIHBvcyA9IGNsaXBQb3MoY20uZG9jLCBwb3MpO1xuICAgICAgICAgICAgdmFyIGNoYW5nZSA9IHtmcm9tOiBwb3MsIHRvOiBwb3MsIHRleHQ6IHNwbGl0TGluZXModGV4dC5qb2luKFwiXFxuXCIpKSwgb3JpZ2luOiBcInBhc3RlXCJ9O1xuICAgICAgICAgICAgbWFrZUNoYW5nZShjbS5kb2MsIGNoYW5nZSk7XG4gICAgICAgICAgICBzZXRTZWxlY3Rpb25SZXBsYWNlSGlzdG9yeShjbS5kb2MsIHNpbXBsZVNlbGVjdGlvbihwb3MsIGNoYW5nZUVuZChjaGFuZ2UpKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgcmVhZGVyLnJlYWRBc1RleHQoZmlsZSk7XG4gICAgICB9O1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBuOyArK2kpIGxvYWRGaWxlKGZpbGVzW2ldLCBpKTtcbiAgICB9IGVsc2UgeyAvLyBOb3JtYWwgZHJvcFxuICAgICAgLy8gRG9uJ3QgZG8gYSByZXBsYWNlIGlmIHRoZSBkcm9wIGhhcHBlbmVkIGluc2lkZSBvZiB0aGUgc2VsZWN0ZWQgdGV4dC5cbiAgICAgIGlmIChjbS5zdGF0ZS5kcmFnZ2luZ1RleHQgJiYgY20uZG9jLnNlbC5jb250YWlucyhwb3MpID4gLTEpIHtcbiAgICAgICAgY20uc3RhdGUuZHJhZ2dpbmdUZXh0KGUpO1xuICAgICAgICAvLyBFbnN1cmUgdGhlIGVkaXRvciBpcyByZS1mb2N1c2VkXG4gICAgICAgIHNldFRpbWVvdXQoYmluZChmb2N1c0lucHV0LCBjbSksIDIwKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgdmFyIHRleHQgPSBlLmRhdGFUcmFuc2Zlci5nZXREYXRhKFwiVGV4dFwiKTtcbiAgICAgICAgaWYgKHRleHQpIHtcbiAgICAgICAgICBpZiAoY20uc3RhdGUuZHJhZ2dpbmdUZXh0ICYmICEobWFjID8gZS5tZXRhS2V5IDogZS5jdHJsS2V5KSlcbiAgICAgICAgICAgIHZhciBzZWxlY3RlZCA9IGNtLmxpc3RTZWxlY3Rpb25zKCk7XG4gICAgICAgICAgc2V0U2VsZWN0aW9uTm9VbmRvKGNtLmRvYywgc2ltcGxlU2VsZWN0aW9uKHBvcywgcG9zKSk7XG4gICAgICAgICAgaWYgKHNlbGVjdGVkKSBmb3IgKHZhciBpID0gMDsgaSA8IHNlbGVjdGVkLmxlbmd0aDsgKytpKVxuICAgICAgICAgICAgcmVwbGFjZVJhbmdlKGNtLmRvYywgXCJcIiwgc2VsZWN0ZWRbaV0uYW5jaG9yLCBzZWxlY3RlZFtpXS5oZWFkLCBcImRyYWdcIik7XG4gICAgICAgICAgY20ucmVwbGFjZVNlbGVjdGlvbih0ZXh0LCBcImFyb3VuZFwiLCBcInBhc3RlXCIpO1xuICAgICAgICAgIGZvY3VzSW5wdXQoY20pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBjYXRjaChlKXt9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gb25EcmFnU3RhcnQoY20sIGUpIHtcbiAgICBpZiAoaWUgJiYgKCFjbS5zdGF0ZS5kcmFnZ2luZ1RleHQgfHwgK25ldyBEYXRlIC0gbGFzdERyb3AgPCAxMDApKSB7IGVfc3RvcChlKTsgcmV0dXJuOyB9XG4gICAgaWYgKHNpZ25hbERPTUV2ZW50KGNtLCBlKSB8fCBldmVudEluV2lkZ2V0KGNtLmRpc3BsYXksIGUpKSByZXR1cm47XG5cbiAgICBlLmRhdGFUcmFuc2Zlci5zZXREYXRhKFwiVGV4dFwiLCBjbS5nZXRTZWxlY3Rpb24oKSk7XG5cbiAgICAvLyBVc2UgZHVtbXkgaW1hZ2UgaW5zdGVhZCBvZiBkZWZhdWx0IGJyb3dzZXJzIGltYWdlLlxuICAgIC8vIFJlY2VudCBTYWZhcmkgKH42LjAuMikgaGF2ZSBhIHRlbmRlbmN5IHRvIHNlZ2ZhdWx0IHdoZW4gdGhpcyBoYXBwZW5zLCBzbyB3ZSBkb24ndCBkbyBpdCB0aGVyZS5cbiAgICBpZiAoZS5kYXRhVHJhbnNmZXIuc2V0RHJhZ0ltYWdlICYmICFzYWZhcmkpIHtcbiAgICAgIHZhciBpbWcgPSBlbHQoXCJpbWdcIiwgbnVsbCwgbnVsbCwgXCJwb3NpdGlvbjogZml4ZWQ7IGxlZnQ6IDA7IHRvcDogMDtcIik7XG4gICAgICBpbWcuc3JjID0gXCJkYXRhOmltYWdlL2dpZjtiYXNlNjQsUjBsR09EbGhBUUFCQUFBQUFDSDVCQUVLQUFFQUxBQUFBQUFCQUFFQUFBSUNUQUVBT3c9PVwiO1xuICAgICAgaWYgKHByZXN0bykge1xuICAgICAgICBpbWcud2lkdGggPSBpbWcuaGVpZ2h0ID0gMTtcbiAgICAgICAgY20uZGlzcGxheS53cmFwcGVyLmFwcGVuZENoaWxkKGltZyk7XG4gICAgICAgIC8vIEZvcmNlIGEgcmVsYXlvdXQsIG9yIE9wZXJhIHdvbid0IHVzZSBvdXIgaW1hZ2UgZm9yIHNvbWUgb2JzY3VyZSByZWFzb25cbiAgICAgICAgaW1nLl90b3AgPSBpbWcub2Zmc2V0VG9wO1xuICAgICAgfVxuICAgICAgZS5kYXRhVHJhbnNmZXIuc2V0RHJhZ0ltYWdlKGltZywgMCwgMCk7XG4gICAgICBpZiAocHJlc3RvKSBpbWcucGFyZW50Tm9kZS5yZW1vdmVDaGlsZChpbWcpO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNDUk9MTCBFVkVOVFNcblxuICAvLyBTeW5jIHRoZSBzY3JvbGxhYmxlIGFyZWEgYW5kIHNjcm9sbGJhcnMsIGVuc3VyZSB0aGUgdmlld3BvcnRcbiAgLy8gY292ZXJzIHRoZSB2aXNpYmxlIGFyZWEuXG4gIGZ1bmN0aW9uIHNldFNjcm9sbFRvcChjbSwgdmFsKSB7XG4gICAgaWYgKE1hdGguYWJzKGNtLmRvYy5zY3JvbGxUb3AgLSB2YWwpIDwgMikgcmV0dXJuO1xuICAgIGNtLmRvYy5zY3JvbGxUb3AgPSB2YWw7XG4gICAgaWYgKCFnZWNrbykgdXBkYXRlRGlzcGxheVNpbXBsZShjbSwge3RvcDogdmFsfSk7XG4gICAgaWYgKGNtLmRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsVG9wICE9IHZhbCkgY20uZGlzcGxheS5zY3JvbGxlci5zY3JvbGxUb3AgPSB2YWw7XG4gICAgY20uZGlzcGxheS5zY3JvbGxiYXJzLnNldFNjcm9sbFRvcCh2YWwpO1xuICAgIGlmIChnZWNrbykgdXBkYXRlRGlzcGxheVNpbXBsZShjbSk7XG4gICAgc3RhcnRXb3JrZXIoY20sIDEwMCk7XG4gIH1cbiAgLy8gU3luYyBzY3JvbGxlciBhbmQgc2Nyb2xsYmFyLCBlbnN1cmUgdGhlIGd1dHRlciBlbGVtZW50cyBhcmVcbiAgLy8gYWxpZ25lZC5cbiAgZnVuY3Rpb24gc2V0U2Nyb2xsTGVmdChjbSwgdmFsLCBpc1Njcm9sbGVyKSB7XG4gICAgaWYgKGlzU2Nyb2xsZXIgPyB2YWwgPT0gY20uZG9jLnNjcm9sbExlZnQgOiBNYXRoLmFicyhjbS5kb2Muc2Nyb2xsTGVmdCAtIHZhbCkgPCAyKSByZXR1cm47XG4gICAgdmFsID0gTWF0aC5taW4odmFsLCBjbS5kaXNwbGF5LnNjcm9sbGVyLnNjcm9sbFdpZHRoIC0gY20uZGlzcGxheS5zY3JvbGxlci5jbGllbnRXaWR0aCk7XG4gICAgY20uZG9jLnNjcm9sbExlZnQgPSB2YWw7XG4gICAgYWxpZ25Ib3Jpem9udGFsbHkoY20pO1xuICAgIGlmIChjbS5kaXNwbGF5LnNjcm9sbGVyLnNjcm9sbExlZnQgIT0gdmFsKSBjbS5kaXNwbGF5LnNjcm9sbGVyLnNjcm9sbExlZnQgPSB2YWw7XG4gICAgY20uZGlzcGxheS5zY3JvbGxiYXJzLnNldFNjcm9sbExlZnQodmFsKTtcbiAgfVxuXG4gIC8vIFNpbmNlIHRoZSBkZWx0YSB2YWx1ZXMgcmVwb3J0ZWQgb24gbW91c2Ugd2hlZWwgZXZlbnRzIGFyZVxuICAvLyB1bnN0YW5kYXJkaXplZCBiZXR3ZWVuIGJyb3dzZXJzIGFuZCBldmVuIGJyb3dzZXIgdmVyc2lvbnMsIGFuZFxuICAvLyBnZW5lcmFsbHkgaG9ycmlibHkgdW5wcmVkaWN0YWJsZSwgdGhpcyBjb2RlIHN0YXJ0cyBieSBtZWFzdXJpbmdcbiAgLy8gdGhlIHNjcm9sbCBlZmZlY3QgdGhhdCB0aGUgZmlyc3QgZmV3IG1vdXNlIHdoZWVsIGV2ZW50cyBoYXZlLFxuICAvLyBhbmQsIGZyb20gdGhhdCwgZGV0ZWN0cyB0aGUgd2F5IGl0IGNhbiBjb252ZXJ0IGRlbHRhcyB0byBwaXhlbFxuICAvLyBvZmZzZXRzIGFmdGVyd2FyZHMuXG4gIC8vXG4gIC8vIFRoZSByZWFzb24gd2Ugd2FudCB0byBrbm93IHRoZSBhbW91bnQgYSB3aGVlbCBldmVudCB3aWxsIHNjcm9sbFxuICAvLyBpcyB0aGF0IGl0IGdpdmVzIHVzIGEgY2hhbmNlIHRvIHVwZGF0ZSB0aGUgZGlzcGxheSBiZWZvcmUgdGhlXG4gIC8vIGFjdHVhbCBzY3JvbGxpbmcgaGFwcGVucywgcmVkdWNpbmcgZmxpY2tlcmluZy5cblxuICB2YXIgd2hlZWxTYW1wbGVzID0gMCwgd2hlZWxQaXhlbHNQZXJVbml0ID0gbnVsbDtcbiAgLy8gRmlsbCBpbiBhIGJyb3dzZXItZGV0ZWN0ZWQgc3RhcnRpbmcgdmFsdWUgb24gYnJvd3NlcnMgd2hlcmUgd2VcbiAgLy8ga25vdyBvbmUuIFRoZXNlIGRvbid0IGhhdmUgdG8gYmUgYWNjdXJhdGUgLS0gdGhlIHJlc3VsdCBvZiB0aGVtXG4gIC8vIGJlaW5nIHdyb25nIHdvdWxkIGp1c3QgYmUgYSBzbGlnaHQgZmxpY2tlciBvbiB0aGUgZmlyc3Qgd2hlZWxcbiAgLy8gc2Nyb2xsIChpZiBpdCBpcyBsYXJnZSBlbm91Z2gpLlxuICBpZiAoaWUpIHdoZWVsUGl4ZWxzUGVyVW5pdCA9IC0uNTM7XG4gIGVsc2UgaWYgKGdlY2tvKSB3aGVlbFBpeGVsc1BlclVuaXQgPSAxNTtcbiAgZWxzZSBpZiAoY2hyb21lKSB3aGVlbFBpeGVsc1BlclVuaXQgPSAtLjc7XG4gIGVsc2UgaWYgKHNhZmFyaSkgd2hlZWxQaXhlbHNQZXJVbml0ID0gLTEvMztcblxuICB2YXIgd2hlZWxFdmVudERlbHRhID0gZnVuY3Rpb24oZSkge1xuICAgIHZhciBkeCA9IGUud2hlZWxEZWx0YVgsIGR5ID0gZS53aGVlbERlbHRhWTtcbiAgICBpZiAoZHggPT0gbnVsbCAmJiBlLmRldGFpbCAmJiBlLmF4aXMgPT0gZS5IT1JJWk9OVEFMX0FYSVMpIGR4ID0gZS5kZXRhaWw7XG4gICAgaWYgKGR5ID09IG51bGwgJiYgZS5kZXRhaWwgJiYgZS5heGlzID09IGUuVkVSVElDQUxfQVhJUykgZHkgPSBlLmRldGFpbDtcbiAgICBlbHNlIGlmIChkeSA9PSBudWxsKSBkeSA9IGUud2hlZWxEZWx0YTtcbiAgICByZXR1cm4ge3g6IGR4LCB5OiBkeX07XG4gIH07XG4gIENvZGVNaXJyb3Iud2hlZWxFdmVudFBpeGVscyA9IGZ1bmN0aW9uKGUpIHtcbiAgICB2YXIgZGVsdGEgPSB3aGVlbEV2ZW50RGVsdGEoZSk7XG4gICAgZGVsdGEueCAqPSB3aGVlbFBpeGVsc1BlclVuaXQ7XG4gICAgZGVsdGEueSAqPSB3aGVlbFBpeGVsc1BlclVuaXQ7XG4gICAgcmV0dXJuIGRlbHRhO1xuICB9O1xuXG4gIGZ1bmN0aW9uIG9uU2Nyb2xsV2hlZWwoY20sIGUpIHtcbiAgICB2YXIgZGVsdGEgPSB3aGVlbEV2ZW50RGVsdGEoZSksIGR4ID0gZGVsdGEueCwgZHkgPSBkZWx0YS55O1xuXG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBzY3JvbGwgPSBkaXNwbGF5LnNjcm9sbGVyO1xuICAgIC8vIFF1aXQgaWYgdGhlcmUncyBub3RoaW5nIHRvIHNjcm9sbCBoZXJlXG4gICAgaWYgKCEoZHggJiYgc2Nyb2xsLnNjcm9sbFdpZHRoID4gc2Nyb2xsLmNsaWVudFdpZHRoIHx8XG4gICAgICAgICAgZHkgJiYgc2Nyb2xsLnNjcm9sbEhlaWdodCA+IHNjcm9sbC5jbGllbnRIZWlnaHQpKSByZXR1cm47XG5cbiAgICAvLyBXZWJraXQgYnJvd3NlcnMgb24gT1MgWCBhYm9ydCBtb21lbnR1bSBzY3JvbGxzIHdoZW4gdGhlIHRhcmdldFxuICAgIC8vIG9mIHRoZSBzY3JvbGwgZXZlbnQgaXMgcmVtb3ZlZCBmcm9tIHRoZSBzY3JvbGxhYmxlIGVsZW1lbnQuXG4gICAgLy8gVGhpcyBoYWNrIChzZWUgcmVsYXRlZCBjb2RlIGluIHBhdGNoRGlzcGxheSkgbWFrZXMgc3VyZSB0aGVcbiAgICAvLyBlbGVtZW50IGlzIGtlcHQgYXJvdW5kLlxuICAgIGlmIChkeSAmJiBtYWMgJiYgd2Via2l0KSB7XG4gICAgICBvdXRlcjogZm9yICh2YXIgY3VyID0gZS50YXJnZXQsIHZpZXcgPSBkaXNwbGF5LnZpZXc7IGN1ciAhPSBzY3JvbGw7IGN1ciA9IGN1ci5wYXJlbnROb2RlKSB7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdmlldy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIGlmICh2aWV3W2ldLm5vZGUgPT0gY3VyKSB7XG4gICAgICAgICAgICBjbS5kaXNwbGF5LmN1cnJlbnRXaGVlbFRhcmdldCA9IGN1cjtcbiAgICAgICAgICAgIGJyZWFrIG91dGVyO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIC8vIE9uIHNvbWUgYnJvd3NlcnMsIGhvcml6b250YWwgc2Nyb2xsaW5nIHdpbGwgY2F1c2UgcmVkcmF3cyB0b1xuICAgIC8vIGhhcHBlbiBiZWZvcmUgdGhlIGd1dHRlciBoYXMgYmVlbiByZWFsaWduZWQsIGNhdXNpbmcgaXQgdG9cbiAgICAvLyB3cmlnZ2xlIGFyb3VuZCBpbiBhIG1vc3QgdW5zZWVtbHkgd2F5LiBXaGVuIHdlIGhhdmUgYW5cbiAgICAvLyBlc3RpbWF0ZWQgcGl4ZWxzL2RlbHRhIHZhbHVlLCB3ZSBqdXN0IGhhbmRsZSBob3Jpem9udGFsXG4gICAgLy8gc2Nyb2xsaW5nIGVudGlyZWx5IGhlcmUuIEl0J2xsIGJlIHNsaWdodGx5IG9mZiBmcm9tIG5hdGl2ZSwgYnV0XG4gICAgLy8gYmV0dGVyIHRoYW4gZ2xpdGNoaW5nIG91dC5cbiAgICBpZiAoZHggJiYgIWdlY2tvICYmICFwcmVzdG8gJiYgd2hlZWxQaXhlbHNQZXJVbml0ICE9IG51bGwpIHtcbiAgICAgIGlmIChkeSlcbiAgICAgICAgc2V0U2Nyb2xsVG9wKGNtLCBNYXRoLm1heCgwLCBNYXRoLm1pbihzY3JvbGwuc2Nyb2xsVG9wICsgZHkgKiB3aGVlbFBpeGVsc1BlclVuaXQsIHNjcm9sbC5zY3JvbGxIZWlnaHQgLSBzY3JvbGwuY2xpZW50SGVpZ2h0KSkpO1xuICAgICAgc2V0U2Nyb2xsTGVmdChjbSwgTWF0aC5tYXgoMCwgTWF0aC5taW4oc2Nyb2xsLnNjcm9sbExlZnQgKyBkeCAqIHdoZWVsUGl4ZWxzUGVyVW5pdCwgc2Nyb2xsLnNjcm9sbFdpZHRoIC0gc2Nyb2xsLmNsaWVudFdpZHRoKSkpO1xuICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIGRpc3BsYXkud2hlZWxTdGFydFggPSBudWxsOyAvLyBBYm9ydCBtZWFzdXJlbWVudCwgaWYgaW4gcHJvZ3Jlc3NcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyAnUHJvamVjdCcgdGhlIHZpc2libGUgdmlld3BvcnQgdG8gY292ZXIgdGhlIGFyZWEgdGhhdCBpcyBiZWluZ1xuICAgIC8vIHNjcm9sbGVkIGludG8gdmlldyAoaWYgd2Uga25vdyBlbm91Z2ggdG8gZXN0aW1hdGUgaXQpLlxuICAgIGlmIChkeSAmJiB3aGVlbFBpeGVsc1BlclVuaXQgIT0gbnVsbCkge1xuICAgICAgdmFyIHBpeGVscyA9IGR5ICogd2hlZWxQaXhlbHNQZXJVbml0O1xuICAgICAgdmFyIHRvcCA9IGNtLmRvYy5zY3JvbGxUb3AsIGJvdCA9IHRvcCArIGRpc3BsYXkud3JhcHBlci5jbGllbnRIZWlnaHQ7XG4gICAgICBpZiAocGl4ZWxzIDwgMCkgdG9wID0gTWF0aC5tYXgoMCwgdG9wICsgcGl4ZWxzIC0gNTApO1xuICAgICAgZWxzZSBib3QgPSBNYXRoLm1pbihjbS5kb2MuaGVpZ2h0LCBib3QgKyBwaXhlbHMgKyA1MCk7XG4gICAgICB1cGRhdGVEaXNwbGF5U2ltcGxlKGNtLCB7dG9wOiB0b3AsIGJvdHRvbTogYm90fSk7XG4gICAgfVxuXG4gICAgaWYgKHdoZWVsU2FtcGxlcyA8IDIwKSB7XG4gICAgICBpZiAoZGlzcGxheS53aGVlbFN0YXJ0WCA9PSBudWxsKSB7XG4gICAgICAgIGRpc3BsYXkud2hlZWxTdGFydFggPSBzY3JvbGwuc2Nyb2xsTGVmdDsgZGlzcGxheS53aGVlbFN0YXJ0WSA9IHNjcm9sbC5zY3JvbGxUb3A7XG4gICAgICAgIGRpc3BsYXkud2hlZWxEWCA9IGR4OyBkaXNwbGF5LndoZWVsRFkgPSBkeTtcbiAgICAgICAgc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgICBpZiAoZGlzcGxheS53aGVlbFN0YXJ0WCA9PSBudWxsKSByZXR1cm47XG4gICAgICAgICAgdmFyIG1vdmVkWCA9IHNjcm9sbC5zY3JvbGxMZWZ0IC0gZGlzcGxheS53aGVlbFN0YXJ0WDtcbiAgICAgICAgICB2YXIgbW92ZWRZID0gc2Nyb2xsLnNjcm9sbFRvcCAtIGRpc3BsYXkud2hlZWxTdGFydFk7XG4gICAgICAgICAgdmFyIHNhbXBsZSA9IChtb3ZlZFkgJiYgZGlzcGxheS53aGVlbERZICYmIG1vdmVkWSAvIGRpc3BsYXkud2hlZWxEWSkgfHxcbiAgICAgICAgICAgIChtb3ZlZFggJiYgZGlzcGxheS53aGVlbERYICYmIG1vdmVkWCAvIGRpc3BsYXkud2hlZWxEWCk7XG4gICAgICAgICAgZGlzcGxheS53aGVlbFN0YXJ0WCA9IGRpc3BsYXkud2hlZWxTdGFydFkgPSBudWxsO1xuICAgICAgICAgIGlmICghc2FtcGxlKSByZXR1cm47XG4gICAgICAgICAgd2hlZWxQaXhlbHNQZXJVbml0ID0gKHdoZWVsUGl4ZWxzUGVyVW5pdCAqIHdoZWVsU2FtcGxlcyArIHNhbXBsZSkgLyAod2hlZWxTYW1wbGVzICsgMSk7XG4gICAgICAgICAgKyt3aGVlbFNhbXBsZXM7XG4gICAgICAgIH0sIDIwMCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaXNwbGF5LndoZWVsRFggKz0gZHg7IGRpc3BsYXkud2hlZWxEWSArPSBkeTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBLRVkgRVZFTlRTXG5cbiAgLy8gUnVuIGEgaGFuZGxlciB0aGF0IHdhcyBib3VuZCB0byBhIGtleS5cbiAgZnVuY3Rpb24gZG9IYW5kbGVCaW5kaW5nKGNtLCBib3VuZCwgZHJvcFNoaWZ0KSB7XG4gICAgaWYgKHR5cGVvZiBib3VuZCA9PSBcInN0cmluZ1wiKSB7XG4gICAgICBib3VuZCA9IGNvbW1hbmRzW2JvdW5kXTtcbiAgICAgIGlmICghYm91bmQpIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgLy8gRW5zdXJlIHByZXZpb3VzIGlucHV0IGhhcyBiZWVuIHJlYWQsIHNvIHRoYXQgdGhlIGhhbmRsZXIgc2VlcyBhXG4gICAgLy8gY29uc2lzdGVudCB2aWV3IG9mIHRoZSBkb2N1bWVudFxuICAgIGlmIChjbS5kaXNwbGF5LnBvbGxpbmdGYXN0ICYmIHJlYWRJbnB1dChjbSkpIGNtLmRpc3BsYXkucG9sbGluZ0Zhc3QgPSBmYWxzZTtcbiAgICB2YXIgcHJldlNoaWZ0ID0gY20uZGlzcGxheS5zaGlmdCwgZG9uZSA9IGZhbHNlO1xuICAgIHRyeSB7XG4gICAgICBpZiAoaXNSZWFkT25seShjbSkpIGNtLnN0YXRlLnN1cHByZXNzRWRpdHMgPSB0cnVlO1xuICAgICAgaWYgKGRyb3BTaGlmdCkgY20uZGlzcGxheS5zaGlmdCA9IGZhbHNlO1xuICAgICAgZG9uZSA9IGJvdW5kKGNtKSAhPSBQYXNzO1xuICAgIH0gZmluYWxseSB7XG4gICAgICBjbS5kaXNwbGF5LnNoaWZ0ID0gcHJldlNoaWZ0O1xuICAgICAgY20uc3RhdGUuc3VwcHJlc3NFZGl0cyA9IGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gZG9uZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxvb2t1cEtleUZvckVkaXRvcihjbSwgbmFtZSwgaGFuZGxlKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjbS5zdGF0ZS5rZXlNYXBzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gbG9va3VwS2V5KG5hbWUsIGNtLnN0YXRlLmtleU1hcHNbaV0sIGhhbmRsZSwgY20pO1xuICAgICAgaWYgKHJlc3VsdCkgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gICAgcmV0dXJuIChjbS5vcHRpb25zLmV4dHJhS2V5cyAmJiBsb29rdXBLZXkobmFtZSwgY20ub3B0aW9ucy5leHRyYUtleXMsIGhhbmRsZSwgY20pKVxuICAgICAgfHwgbG9va3VwS2V5KG5hbWUsIGNtLm9wdGlvbnMua2V5TWFwLCBoYW5kbGUsIGNtKTtcbiAgfVxuXG4gIHZhciBzdG9wU2VxID0gbmV3IERlbGF5ZWQ7XG4gIGZ1bmN0aW9uIGRpc3BhdGNoS2V5KGNtLCBuYW1lLCBlLCBoYW5kbGUpIHtcbiAgICB2YXIgc2VxID0gY20uc3RhdGUua2V5U2VxO1xuICAgIGlmIChzZXEpIHtcbiAgICAgIGlmIChpc01vZGlmaWVyS2V5KG5hbWUpKSByZXR1cm4gXCJoYW5kbGVkXCI7XG4gICAgICBzdG9wU2VxLnNldCg1MCwgZnVuY3Rpb24oKSB7XG4gICAgICAgIGlmIChjbS5zdGF0ZS5rZXlTZXEgPT0gc2VxKSB7XG4gICAgICAgICAgY20uc3RhdGUua2V5U2VxID0gbnVsbDtcbiAgICAgICAgICByZXNldElucHV0KGNtKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBuYW1lID0gc2VxICsgXCIgXCIgKyBuYW1lO1xuICAgIH1cbiAgICB2YXIgcmVzdWx0ID0gbG9va3VwS2V5Rm9yRWRpdG9yKGNtLCBuYW1lLCBoYW5kbGUpO1xuXG4gICAgaWYgKHJlc3VsdCA9PSBcIm11bHRpXCIpXG4gICAgICBjbS5zdGF0ZS5rZXlTZXEgPSBuYW1lO1xuICAgIGlmIChyZXN1bHQgPT0gXCJoYW5kbGVkXCIpXG4gICAgICBzaWduYWxMYXRlcihjbSwgXCJrZXlIYW5kbGVkXCIsIGNtLCBuYW1lLCBlKTtcblxuICAgIGlmIChyZXN1bHQgPT0gXCJoYW5kbGVkXCIgfHwgcmVzdWx0ID09IFwibXVsdGlcIikge1xuICAgICAgZV9wcmV2ZW50RGVmYXVsdChlKTtcbiAgICAgIHJlc3RhcnRCbGluayhjbSk7XG4gICAgfVxuXG4gICAgaWYgKHNlcSAmJiAhcmVzdWx0ICYmIC9cXCckLy50ZXN0KG5hbWUpKSB7XG4gICAgICBlX3ByZXZlbnREZWZhdWx0KGUpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiAhIXJlc3VsdDtcbiAgfVxuXG4gIC8vIEhhbmRsZSBhIGtleSBmcm9tIHRoZSBrZXlkb3duIGV2ZW50LlxuICBmdW5jdGlvbiBoYW5kbGVLZXlCaW5kaW5nKGNtLCBlKSB7XG4gICAgdmFyIG5hbWUgPSBrZXlOYW1lKGUsIHRydWUpO1xuICAgIGlmICghbmFtZSkgcmV0dXJuIGZhbHNlO1xuXG4gICAgaWYgKGUuc2hpZnRLZXkgJiYgIWNtLnN0YXRlLmtleVNlcSkge1xuICAgICAgLy8gRmlyc3QgdHJ5IHRvIHJlc29sdmUgZnVsbCBuYW1lIChpbmNsdWRpbmcgJ1NoaWZ0LScpLiBGYWlsaW5nXG4gICAgICAvLyB0aGF0LCBzZWUgaWYgdGhlcmUgaXMgYSBjdXJzb3ItbW90aW9uIGNvbW1hbmQgKHN0YXJ0aW5nIHdpdGhcbiAgICAgIC8vICdnbycpIGJvdW5kIHRvIHRoZSBrZXluYW1lIHdpdGhvdXQgJ1NoaWZ0LScuXG4gICAgICByZXR1cm4gZGlzcGF0Y2hLZXkoY20sIFwiU2hpZnQtXCIgKyBuYW1lLCBlLCBmdW5jdGlvbihiKSB7cmV0dXJuIGRvSGFuZGxlQmluZGluZyhjbSwgYiwgdHJ1ZSk7fSlcbiAgICAgICAgICB8fCBkaXNwYXRjaEtleShjbSwgbmFtZSwgZSwgZnVuY3Rpb24oYikge1xuICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBiID09IFwic3RyaW5nXCIgPyAvXmdvW0EtWl0vLnRlc3QoYikgOiBiLm1vdGlvbilcbiAgICAgICAgICAgICAgICAgcmV0dXJuIGRvSGFuZGxlQmluZGluZyhjbSwgYik7XG4gICAgICAgICAgICAgfSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBkaXNwYXRjaEtleShjbSwgbmFtZSwgZSwgZnVuY3Rpb24oYikgeyByZXR1cm4gZG9IYW5kbGVCaW5kaW5nKGNtLCBiKTsgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gSGFuZGxlIGEga2V5IGZyb20gdGhlIGtleXByZXNzIGV2ZW50XG4gIGZ1bmN0aW9uIGhhbmRsZUNoYXJCaW5kaW5nKGNtLCBlLCBjaCkge1xuICAgIHJldHVybiBkaXNwYXRjaEtleShjbSwgXCInXCIgKyBjaCArIFwiJ1wiLCBlLFxuICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbihiKSB7IHJldHVybiBkb0hhbmRsZUJpbmRpbmcoY20sIGIsIHRydWUpOyB9KTtcbiAgfVxuXG4gIHZhciBsYXN0U3RvcHBlZEtleSA9IG51bGw7XG4gIGZ1bmN0aW9uIG9uS2V5RG93bihlKSB7XG4gICAgdmFyIGNtID0gdGhpcztcbiAgICBlbnN1cmVGb2N1cyhjbSk7XG4gICAgaWYgKHNpZ25hbERPTUV2ZW50KGNtLCBlKSkgcmV0dXJuO1xuICAgIC8vIElFIGRvZXMgc3RyYW5nZSB0aGluZ3Mgd2l0aCBlc2NhcGUuXG4gICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCAxMSAmJiBlLmtleUNvZGUgPT0gMjcpIGUucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgICB2YXIgY29kZSA9IGUua2V5Q29kZTtcbiAgICBjbS5kaXNwbGF5LnNoaWZ0ID0gY29kZSA9PSAxNiB8fCBlLnNoaWZ0S2V5O1xuICAgIHZhciBoYW5kbGVkID0gaGFuZGxlS2V5QmluZGluZyhjbSwgZSk7XG4gICAgaWYgKHByZXN0bykge1xuICAgICAgbGFzdFN0b3BwZWRLZXkgPSBoYW5kbGVkID8gY29kZSA6IG51bGw7XG4gICAgICAvLyBPcGVyYSBoYXMgbm8gY3V0IGV2ZW50Li4uIHdlIHRyeSB0byBhdCBsZWFzdCBjYXRjaCB0aGUga2V5IGNvbWJvXG4gICAgICBpZiAoIWhhbmRsZWQgJiYgY29kZSA9PSA4OCAmJiAhaGFzQ29weUV2ZW50ICYmIChtYWMgPyBlLm1ldGFLZXkgOiBlLmN0cmxLZXkpKVxuICAgICAgICBjbS5yZXBsYWNlU2VsZWN0aW9uKFwiXCIsIG51bGwsIFwiY3V0XCIpO1xuICAgIH1cblxuICAgIC8vIFR1cm4gbW91c2UgaW50byBjcm9zc2hhaXIgd2hlbiBBbHQgaXMgaGVsZCBvbiBNYWMuXG4gICAgaWYgKGNvZGUgPT0gMTggJiYgIS9cXGJDb2RlTWlycm9yLWNyb3NzaGFpclxcYi8udGVzdChjbS5kaXNwbGF5LmxpbmVEaXYuY2xhc3NOYW1lKSlcbiAgICAgIHNob3dDcm9zc0hhaXIoY20pO1xuICB9XG5cbiAgZnVuY3Rpb24gc2hvd0Nyb3NzSGFpcihjbSkge1xuICAgIHZhciBsaW5lRGl2ID0gY20uZGlzcGxheS5saW5lRGl2O1xuICAgIGFkZENsYXNzKGxpbmVEaXYsIFwiQ29kZU1pcnJvci1jcm9zc2hhaXJcIik7XG5cbiAgICBmdW5jdGlvbiB1cChlKSB7XG4gICAgICBpZiAoZS5rZXlDb2RlID09IDE4IHx8ICFlLmFsdEtleSkge1xuICAgICAgICBybUNsYXNzKGxpbmVEaXYsIFwiQ29kZU1pcnJvci1jcm9zc2hhaXJcIik7XG4gICAgICAgIG9mZihkb2N1bWVudCwgXCJrZXl1cFwiLCB1cCk7XG4gICAgICAgIG9mZihkb2N1bWVudCwgXCJtb3VzZW92ZXJcIiwgdXApO1xuICAgICAgfVxuICAgIH1cbiAgICBvbihkb2N1bWVudCwgXCJrZXl1cFwiLCB1cCk7XG4gICAgb24oZG9jdW1lbnQsIFwibW91c2VvdmVyXCIsIHVwKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIG9uS2V5VXAoZSkge1xuICAgIGlmIChlLmtleUNvZGUgPT0gMTYpIHRoaXMuZG9jLnNlbC5zaGlmdCA9IGZhbHNlO1xuICAgIHNpZ25hbERPTUV2ZW50KHRoaXMsIGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gb25LZXlQcmVzcyhlKSB7XG4gICAgdmFyIGNtID0gdGhpcztcbiAgICBpZiAoc2lnbmFsRE9NRXZlbnQoY20sIGUpIHx8IGUuY3RybEtleSAmJiAhZS5hbHRLZXkgfHwgbWFjICYmIGUubWV0YUtleSkgcmV0dXJuO1xuICAgIHZhciBrZXlDb2RlID0gZS5rZXlDb2RlLCBjaGFyQ29kZSA9IGUuY2hhckNvZGU7XG4gICAgaWYgKHByZXN0byAmJiBrZXlDb2RlID09IGxhc3RTdG9wcGVkS2V5KSB7bGFzdFN0b3BwZWRLZXkgPSBudWxsOyBlX3ByZXZlbnREZWZhdWx0KGUpOyByZXR1cm47fVxuICAgIGlmICgoKHByZXN0byAmJiAoIWUud2hpY2ggfHwgZS53aGljaCA8IDEwKSkgfHwga2h0bWwpICYmIGhhbmRsZUtleUJpbmRpbmcoY20sIGUpKSByZXR1cm47XG4gICAgdmFyIGNoID0gU3RyaW5nLmZyb21DaGFyQ29kZShjaGFyQ29kZSA9PSBudWxsID8ga2V5Q29kZSA6IGNoYXJDb2RlKTtcbiAgICBpZiAoaGFuZGxlQ2hhckJpbmRpbmcoY20sIGUsIGNoKSkgcmV0dXJuO1xuICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uID49IDkpIGNtLmRpc3BsYXkuaW5wdXRIYXNTZWxlY3Rpb24gPSBudWxsO1xuICAgIGZhc3RQb2xsKGNtKTtcbiAgfVxuXG4gIC8vIEZPQ1VTL0JMVVIgRVZFTlRTXG5cbiAgZnVuY3Rpb24gb25Gb2N1cyhjbSkge1xuICAgIGlmIChjbS5vcHRpb25zLnJlYWRPbmx5ID09IFwibm9jdXJzb3JcIikgcmV0dXJuO1xuICAgIGlmICghY20uc3RhdGUuZm9jdXNlZCkge1xuICAgICAgc2lnbmFsKGNtLCBcImZvY3VzXCIsIGNtKTtcbiAgICAgIGNtLnN0YXRlLmZvY3VzZWQgPSB0cnVlO1xuICAgICAgYWRkQ2xhc3MoY20uZGlzcGxheS53cmFwcGVyLCBcIkNvZGVNaXJyb3ItZm9jdXNlZFwiKTtcbiAgICAgIC8vIFRoZSBwcmV2SW5wdXQgdGVzdCBwcmV2ZW50cyB0aGlzIGZyb20gZmlyaW5nIHdoZW4gYSBjb250ZXh0XG4gICAgICAvLyBtZW51IGlzIGNsb3NlZCAoc2luY2UgdGhlIHJlc2V0SW5wdXQgd291bGQga2lsbCB0aGVcbiAgICAgIC8vIHNlbGVjdC1hbGwgZGV0ZWN0aW9uIGhhY2spXG4gICAgICBpZiAoIWNtLmN1ck9wICYmIGNtLmRpc3BsYXkuc2VsRm9yQ29udGV4dE1lbnUgIT0gY20uZG9jLnNlbCkge1xuICAgICAgICByZXNldElucHV0KGNtKTtcbiAgICAgICAgaWYgKHdlYmtpdCkgc2V0VGltZW91dChiaW5kKHJlc2V0SW5wdXQsIGNtLCB0cnVlKSwgMCk7IC8vIElzc3VlICMxNzMwXG4gICAgICB9XG4gICAgfVxuICAgIHNsb3dQb2xsKGNtKTtcbiAgICByZXN0YXJ0QmxpbmsoY20pO1xuICB9XG4gIGZ1bmN0aW9uIG9uQmx1cihjbSkge1xuICAgIGlmIChjbS5zdGF0ZS5mb2N1c2VkKSB7XG4gICAgICBzaWduYWwoY20sIFwiYmx1clwiLCBjbSk7XG4gICAgICBjbS5zdGF0ZS5mb2N1c2VkID0gZmFsc2U7XG4gICAgICBybUNsYXNzKGNtLmRpc3BsYXkud3JhcHBlciwgXCJDb2RlTWlycm9yLWZvY3VzZWRcIik7XG4gICAgfVxuICAgIGNsZWFySW50ZXJ2YWwoY20uZGlzcGxheS5ibGlua2VyKTtcbiAgICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge2lmICghY20uc3RhdGUuZm9jdXNlZCkgY20uZGlzcGxheS5zaGlmdCA9IGZhbHNlO30sIDE1MCk7XG4gIH1cblxuICAvLyBDT05URVhUIE1FTlUgSEFORExJTkdcblxuICAvLyBUbyBtYWtlIHRoZSBjb250ZXh0IG1lbnUgd29yaywgd2UgbmVlZCB0byBicmllZmx5IHVuaGlkZSB0aGVcbiAgLy8gdGV4dGFyZWEgKG1ha2luZyBpdCBhcyB1bm9idHJ1c2l2ZSBhcyBwb3NzaWJsZSkgdG8gbGV0IHRoZVxuICAvLyByaWdodC1jbGljayB0YWtlIGVmZmVjdCBvbiBpdC5cbiAgZnVuY3Rpb24gb25Db250ZXh0TWVudShjbSwgZSkge1xuICAgIGlmIChzaWduYWxET01FdmVudChjbSwgZSwgXCJjb250ZXh0bWVudVwiKSkgcmV0dXJuO1xuICAgIHZhciBkaXNwbGF5ID0gY20uZGlzcGxheTtcbiAgICBpZiAoZXZlbnRJbldpZGdldChkaXNwbGF5LCBlKSB8fCBjb250ZXh0TWVudUluR3V0dGVyKGNtLCBlKSkgcmV0dXJuO1xuXG4gICAgdmFyIHBvcyA9IHBvc0Zyb21Nb3VzZShjbSwgZSksIHNjcm9sbFBvcyA9IGRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsVG9wO1xuICAgIGlmICghcG9zIHx8IHByZXN0bykgcmV0dXJuOyAvLyBPcGVyYSBpcyBkaWZmaWN1bHQuXG5cbiAgICAvLyBSZXNldCB0aGUgY3VycmVudCB0ZXh0IHNlbGVjdGlvbiBvbmx5IGlmIHRoZSBjbGljayBpcyBkb25lIG91dHNpZGUgb2YgdGhlIHNlbGVjdGlvblxuICAgIC8vIGFuZCAncmVzZXRTZWxlY3Rpb25PbkNvbnRleHRNZW51JyBvcHRpb24gaXMgdHJ1ZS5cbiAgICB2YXIgcmVzZXQgPSBjbS5vcHRpb25zLnJlc2V0U2VsZWN0aW9uT25Db250ZXh0TWVudTtcbiAgICBpZiAocmVzZXQgJiYgY20uZG9jLnNlbC5jb250YWlucyhwb3MpID09IC0xKVxuICAgICAgb3BlcmF0aW9uKGNtLCBzZXRTZWxlY3Rpb24pKGNtLmRvYywgc2ltcGxlU2VsZWN0aW9uKHBvcyksIHNlbF9kb250U2Nyb2xsKTtcblxuICAgIHZhciBvbGRDU1MgPSBkaXNwbGF5LmlucHV0LnN0eWxlLmNzc1RleHQ7XG4gICAgZGlzcGxheS5pbnB1dERpdi5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICBkaXNwbGF5LmlucHV0LnN0eWxlLmNzc1RleHQgPSBcInBvc2l0aW9uOiBmaXhlZDsgd2lkdGg6IDMwcHg7IGhlaWdodDogMzBweDsgdG9wOiBcIiArIChlLmNsaWVudFkgLSA1KSArXG4gICAgICBcInB4OyBsZWZ0OiBcIiArIChlLmNsaWVudFggLSA1KSArIFwicHg7IHotaW5kZXg6IDEwMDA7IGJhY2tncm91bmQ6IFwiICtcbiAgICAgIChpZSA/IFwicmdiYSgyNTUsIDI1NSwgMjU1LCAuMDUpXCIgOiBcInRyYW5zcGFyZW50XCIpICtcbiAgICAgIFwiOyBvdXRsaW5lOiBub25lOyBib3JkZXItd2lkdGg6IDA7IG91dGxpbmU6IG5vbmU7IG92ZXJmbG93OiBoaWRkZW47IG9wYWNpdHk6IC4wNTsgZmlsdGVyOiBhbHBoYShvcGFjaXR5PTUpO1wiO1xuICAgIGlmICh3ZWJraXQpIHZhciBvbGRTY3JvbGxZID0gd2luZG93LnNjcm9sbFk7IC8vIFdvcmsgYXJvdW5kIENocm9tZSBpc3N1ZSAoIzI3MTIpXG4gICAgZm9jdXNJbnB1dChjbSk7XG4gICAgaWYgKHdlYmtpdCkgd2luZG93LnNjcm9sbFRvKG51bGwsIG9sZFNjcm9sbFkpO1xuICAgIHJlc2V0SW5wdXQoY20pO1xuICAgIC8vIEFkZHMgXCJTZWxlY3QgYWxsXCIgdG8gY29udGV4dCBtZW51IGluIEZGXG4gICAgaWYgKCFjbS5zb21ldGhpbmdTZWxlY3RlZCgpKSBkaXNwbGF5LmlucHV0LnZhbHVlID0gZGlzcGxheS5wcmV2SW5wdXQgPSBcIiBcIjtcbiAgICBkaXNwbGF5LmNvbnRleHRNZW51UGVuZGluZyA9IHRydWU7XG4gICAgZGlzcGxheS5zZWxGb3JDb250ZXh0TWVudSA9IGNtLmRvYy5zZWw7XG4gICAgY2xlYXJUaW1lb3V0KGRpc3BsYXkuZGV0ZWN0aW5nU2VsZWN0QWxsKTtcblxuICAgIC8vIFNlbGVjdC1hbGwgd2lsbCBiZSBncmV5ZWQgb3V0IGlmIHRoZXJlJ3Mgbm90aGluZyB0byBzZWxlY3QsIHNvXG4gICAgLy8gdGhpcyBhZGRzIGEgemVyby13aWR0aCBzcGFjZSBzbyB0aGF0IHdlIGNhbiBsYXRlciBjaGVjayB3aGV0aGVyXG4gICAgLy8gaXQgZ290IHNlbGVjdGVkLlxuICAgIGZ1bmN0aW9uIHByZXBhcmVTZWxlY3RBbGxIYWNrKCkge1xuICAgICAgaWYgKGRpc3BsYXkuaW5wdXQuc2VsZWN0aW9uU3RhcnQgIT0gbnVsbCkge1xuICAgICAgICB2YXIgc2VsZWN0ZWQgPSBjbS5zb21ldGhpbmdTZWxlY3RlZCgpO1xuICAgICAgICB2YXIgZXh0dmFsID0gZGlzcGxheS5pbnB1dC52YWx1ZSA9IFwiXFx1MjAwYlwiICsgKHNlbGVjdGVkID8gZGlzcGxheS5pbnB1dC52YWx1ZSA6IFwiXCIpO1xuICAgICAgICBkaXNwbGF5LnByZXZJbnB1dCA9IHNlbGVjdGVkID8gXCJcIiA6IFwiXFx1MjAwYlwiO1xuICAgICAgICBkaXNwbGF5LmlucHV0LnNlbGVjdGlvblN0YXJ0ID0gMTsgZGlzcGxheS5pbnB1dC5zZWxlY3Rpb25FbmQgPSBleHR2YWwubGVuZ3RoO1xuICAgICAgICAvLyBSZS1zZXQgdGhpcywgaW4gY2FzZSBzb21lIG90aGVyIGhhbmRsZXIgdG91Y2hlZCB0aGVcbiAgICAgICAgLy8gc2VsZWN0aW9uIGluIHRoZSBtZWFudGltZS5cbiAgICAgICAgZGlzcGxheS5zZWxGb3JDb250ZXh0TWVudSA9IGNtLmRvYy5zZWw7XG4gICAgICB9XG4gICAgfVxuICAgIGZ1bmN0aW9uIHJlaGlkZSgpIHtcbiAgICAgIGRpc3BsYXkuY29udGV4dE1lbnVQZW5kaW5nID0gZmFsc2U7XG4gICAgICBkaXNwbGF5LmlucHV0RGl2LnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuICAgICAgZGlzcGxheS5pbnB1dC5zdHlsZS5jc3NUZXh0ID0gb2xkQ1NTO1xuICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCA5KSBkaXNwbGF5LnNjcm9sbGJhcnMuc2V0U2Nyb2xsVG9wKGRpc3BsYXkuc2Nyb2xsZXIuc2Nyb2xsVG9wID0gc2Nyb2xsUG9zKTtcbiAgICAgIHNsb3dQb2xsKGNtKTtcblxuICAgICAgLy8gVHJ5IHRvIGRldGVjdCB0aGUgdXNlciBjaG9vc2luZyBzZWxlY3QtYWxsXG4gICAgICBpZiAoZGlzcGxheS5pbnB1dC5zZWxlY3Rpb25TdGFydCAhPSBudWxsKSB7XG4gICAgICAgIGlmICghaWUgfHwgKGllICYmIGllX3ZlcnNpb24gPCA5KSkgcHJlcGFyZVNlbGVjdEFsbEhhY2soKTtcbiAgICAgICAgdmFyIGkgPSAwLCBwb2xsID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgaWYgKGRpc3BsYXkuc2VsRm9yQ29udGV4dE1lbnUgPT0gY20uZG9jLnNlbCAmJiBkaXNwbGF5LmlucHV0LnNlbGVjdGlvblN0YXJ0ID09IDApXG4gICAgICAgICAgICBvcGVyYXRpb24oY20sIGNvbW1hbmRzLnNlbGVjdEFsbCkoY20pO1xuICAgICAgICAgIGVsc2UgaWYgKGkrKyA8IDEwKSBkaXNwbGF5LmRldGVjdGluZ1NlbGVjdEFsbCA9IHNldFRpbWVvdXQocG9sbCwgNTAwKTtcbiAgICAgICAgICBlbHNlIHJlc2V0SW5wdXQoY20pO1xuICAgICAgICB9O1xuICAgICAgICBkaXNwbGF5LmRldGVjdGluZ1NlbGVjdEFsbCA9IHNldFRpbWVvdXQocG9sbCwgMjAwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA+PSA5KSBwcmVwYXJlU2VsZWN0QWxsSGFjaygpO1xuICAgIGlmIChjYXB0dXJlUmlnaHRDbGljaykge1xuICAgICAgZV9zdG9wKGUpO1xuICAgICAgdmFyIG1vdXNldXAgPSBmdW5jdGlvbigpIHtcbiAgICAgICAgb2ZmKHdpbmRvdywgXCJtb3VzZXVwXCIsIG1vdXNldXApO1xuICAgICAgICBzZXRUaW1lb3V0KHJlaGlkZSwgMjApO1xuICAgICAgfTtcbiAgICAgIG9uKHdpbmRvdywgXCJtb3VzZXVwXCIsIG1vdXNldXApO1xuICAgIH0gZWxzZSB7XG4gICAgICBzZXRUaW1lb3V0KHJlaGlkZSwgNTApO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbnRleHRNZW51SW5HdXR0ZXIoY20sIGUpIHtcbiAgICBpZiAoIWhhc0hhbmRsZXIoY20sIFwiZ3V0dGVyQ29udGV4dE1lbnVcIikpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gZ3V0dGVyRXZlbnQoY20sIGUsIFwiZ3V0dGVyQ29udGV4dE1lbnVcIiwgZmFsc2UsIHNpZ25hbCk7XG4gIH1cblxuICAvLyBVUERBVElOR1xuXG4gIC8vIENvbXB1dGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBlbmQgb2YgYSBjaGFuZ2UgKGl0cyAndG8nIHByb3BlcnR5XG4gIC8vIHJlZmVycyB0byB0aGUgcHJlLWNoYW5nZSBlbmQpLlxuICB2YXIgY2hhbmdlRW5kID0gQ29kZU1pcnJvci5jaGFuZ2VFbmQgPSBmdW5jdGlvbihjaGFuZ2UpIHtcbiAgICBpZiAoIWNoYW5nZS50ZXh0KSByZXR1cm4gY2hhbmdlLnRvO1xuICAgIHJldHVybiBQb3MoY2hhbmdlLmZyb20ubGluZSArIGNoYW5nZS50ZXh0Lmxlbmd0aCAtIDEsXG4gICAgICAgICAgICAgICBsc3QoY2hhbmdlLnRleHQpLmxlbmd0aCArIChjaGFuZ2UudGV4dC5sZW5ndGggPT0gMSA/IGNoYW5nZS5mcm9tLmNoIDogMCkpO1xuICB9O1xuXG4gIC8vIEFkanVzdCBhIHBvc2l0aW9uIHRvIHJlZmVyIHRvIHRoZSBwb3N0LWNoYW5nZSBwb3NpdGlvbiBvZiB0aGVcbiAgLy8gc2FtZSB0ZXh0LCBvciB0aGUgZW5kIG9mIHRoZSBjaGFuZ2UgaWYgdGhlIGNoYW5nZSBjb3ZlcnMgaXQuXG4gIGZ1bmN0aW9uIGFkanVzdEZvckNoYW5nZShwb3MsIGNoYW5nZSkge1xuICAgIGlmIChjbXAocG9zLCBjaGFuZ2UuZnJvbSkgPCAwKSByZXR1cm4gcG9zO1xuICAgIGlmIChjbXAocG9zLCBjaGFuZ2UudG8pIDw9IDApIHJldHVybiBjaGFuZ2VFbmQoY2hhbmdlKTtcblxuICAgIHZhciBsaW5lID0gcG9zLmxpbmUgKyBjaGFuZ2UudGV4dC5sZW5ndGggLSAoY2hhbmdlLnRvLmxpbmUgLSBjaGFuZ2UuZnJvbS5saW5lKSAtIDEsIGNoID0gcG9zLmNoO1xuICAgIGlmIChwb3MubGluZSA9PSBjaGFuZ2UudG8ubGluZSkgY2ggKz0gY2hhbmdlRW5kKGNoYW5nZSkuY2ggLSBjaGFuZ2UudG8uY2g7XG4gICAgcmV0dXJuIFBvcyhsaW5lLCBjaCk7XG4gIH1cblxuICBmdW5jdGlvbiBjb21wdXRlU2VsQWZ0ZXJDaGFuZ2UoZG9jLCBjaGFuZ2UpIHtcbiAgICB2YXIgb3V0ID0gW107XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkb2Muc2VsLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgdmFyIHJhbmdlID0gZG9jLnNlbC5yYW5nZXNbaV07XG4gICAgICBvdXQucHVzaChuZXcgUmFuZ2UoYWRqdXN0Rm9yQ2hhbmdlKHJhbmdlLmFuY2hvciwgY2hhbmdlKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICBhZGp1c3RGb3JDaGFuZ2UocmFuZ2UuaGVhZCwgY2hhbmdlKSkpO1xuICAgIH1cbiAgICByZXR1cm4gbm9ybWFsaXplU2VsZWN0aW9uKG91dCwgZG9jLnNlbC5wcmltSW5kZXgpO1xuICB9XG5cbiAgZnVuY3Rpb24gb2Zmc2V0UG9zKHBvcywgb2xkLCBudykge1xuICAgIGlmIChwb3MubGluZSA9PSBvbGQubGluZSlcbiAgICAgIHJldHVybiBQb3MobncubGluZSwgcG9zLmNoIC0gb2xkLmNoICsgbncuY2gpO1xuICAgIGVsc2VcbiAgICAgIHJldHVybiBQb3MobncubGluZSArIChwb3MubGluZSAtIG9sZC5saW5lKSwgcG9zLmNoKTtcbiAgfVxuXG4gIC8vIFVzZWQgYnkgcmVwbGFjZVNlbGVjdGlvbnMgdG8gYWxsb3cgbW92aW5nIHRoZSBzZWxlY3Rpb24gdG8gdGhlXG4gIC8vIHN0YXJ0IG9yIGFyb3VuZCB0aGUgcmVwbGFjZWQgdGVzdC4gSGludCBtYXkgYmUgXCJzdGFydFwiIG9yIFwiYXJvdW5kXCIuXG4gIGZ1bmN0aW9uIGNvbXB1dGVSZXBsYWNlZFNlbChkb2MsIGNoYW5nZXMsIGhpbnQpIHtcbiAgICB2YXIgb3V0ID0gW107XG4gICAgdmFyIG9sZFByZXYgPSBQb3MoZG9jLmZpcnN0LCAwKSwgbmV3UHJldiA9IG9sZFByZXY7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaGFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgY2hhbmdlID0gY2hhbmdlc1tpXTtcbiAgICAgIHZhciBmcm9tID0gb2Zmc2V0UG9zKGNoYW5nZS5mcm9tLCBvbGRQcmV2LCBuZXdQcmV2KTtcbiAgICAgIHZhciB0byA9IG9mZnNldFBvcyhjaGFuZ2VFbmQoY2hhbmdlKSwgb2xkUHJldiwgbmV3UHJldik7XG4gICAgICBvbGRQcmV2ID0gY2hhbmdlLnRvO1xuICAgICAgbmV3UHJldiA9IHRvO1xuICAgICAgaWYgKGhpbnQgPT0gXCJhcm91bmRcIikge1xuICAgICAgICB2YXIgcmFuZ2UgPSBkb2Muc2VsLnJhbmdlc1tpXSwgaW52ID0gY21wKHJhbmdlLmhlYWQsIHJhbmdlLmFuY2hvcikgPCAwO1xuICAgICAgICBvdXRbaV0gPSBuZXcgUmFuZ2UoaW52ID8gdG8gOiBmcm9tLCBpbnYgPyBmcm9tIDogdG8pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0W2ldID0gbmV3IFJhbmdlKGZyb20sIGZyb20pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbmV3IFNlbGVjdGlvbihvdXQsIGRvYy5zZWwucHJpbUluZGV4KTtcbiAgfVxuXG4gIC8vIEFsbG93IFwiYmVmb3JlQ2hhbmdlXCIgZXZlbnQgaGFuZGxlcnMgdG8gaW5mbHVlbmNlIGEgY2hhbmdlXG4gIGZ1bmN0aW9uIGZpbHRlckNoYW5nZShkb2MsIGNoYW5nZSwgdXBkYXRlKSB7XG4gICAgdmFyIG9iaiA9IHtcbiAgICAgIGNhbmNlbGVkOiBmYWxzZSxcbiAgICAgIGZyb206IGNoYW5nZS5mcm9tLFxuICAgICAgdG86IGNoYW5nZS50byxcbiAgICAgIHRleHQ6IGNoYW5nZS50ZXh0LFxuICAgICAgb3JpZ2luOiBjaGFuZ2Uub3JpZ2luLFxuICAgICAgY2FuY2VsOiBmdW5jdGlvbigpIHsgdGhpcy5jYW5jZWxlZCA9IHRydWU7IH1cbiAgICB9O1xuICAgIGlmICh1cGRhdGUpIG9iai51cGRhdGUgPSBmdW5jdGlvbihmcm9tLCB0bywgdGV4dCwgb3JpZ2luKSB7XG4gICAgICBpZiAoZnJvbSkgdGhpcy5mcm9tID0gY2xpcFBvcyhkb2MsIGZyb20pO1xuICAgICAgaWYgKHRvKSB0aGlzLnRvID0gY2xpcFBvcyhkb2MsIHRvKTtcbiAgICAgIGlmICh0ZXh0KSB0aGlzLnRleHQgPSB0ZXh0O1xuICAgICAgaWYgKG9yaWdpbiAhPT0gdW5kZWZpbmVkKSB0aGlzLm9yaWdpbiA9IG9yaWdpbjtcbiAgICB9O1xuICAgIHNpZ25hbChkb2MsIFwiYmVmb3JlQ2hhbmdlXCIsIGRvYywgb2JqKTtcbiAgICBpZiAoZG9jLmNtKSBzaWduYWwoZG9jLmNtLCBcImJlZm9yZUNoYW5nZVwiLCBkb2MuY20sIG9iaik7XG5cbiAgICBpZiAob2JqLmNhbmNlbGVkKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4ge2Zyb206IG9iai5mcm9tLCB0bzogb2JqLnRvLCB0ZXh0OiBvYmoudGV4dCwgb3JpZ2luOiBvYmoub3JpZ2lufTtcbiAgfVxuXG4gIC8vIEFwcGx5IGEgY2hhbmdlIHRvIGEgZG9jdW1lbnQsIGFuZCBhZGQgaXQgdG8gdGhlIGRvY3VtZW50J3NcbiAgLy8gaGlzdG9yeSwgYW5kIHByb3BhZ2F0aW5nIGl0IHRvIGFsbCBsaW5rZWQgZG9jdW1lbnRzLlxuICBmdW5jdGlvbiBtYWtlQ2hhbmdlKGRvYywgY2hhbmdlLCBpZ25vcmVSZWFkT25seSkge1xuICAgIGlmIChkb2MuY20pIHtcbiAgICAgIGlmICghZG9jLmNtLmN1ck9wKSByZXR1cm4gb3BlcmF0aW9uKGRvYy5jbSwgbWFrZUNoYW5nZSkoZG9jLCBjaGFuZ2UsIGlnbm9yZVJlYWRPbmx5KTtcbiAgICAgIGlmIChkb2MuY20uc3RhdGUuc3VwcHJlc3NFZGl0cykgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChoYXNIYW5kbGVyKGRvYywgXCJiZWZvcmVDaGFuZ2VcIikgfHwgZG9jLmNtICYmIGhhc0hhbmRsZXIoZG9jLmNtLCBcImJlZm9yZUNoYW5nZVwiKSkge1xuICAgICAgY2hhbmdlID0gZmlsdGVyQ2hhbmdlKGRvYywgY2hhbmdlLCB0cnVlKTtcbiAgICAgIGlmICghY2hhbmdlKSByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gUG9zc2libHkgc3BsaXQgb3Igc3VwcHJlc3MgdGhlIHVwZGF0ZSBiYXNlZCBvbiB0aGUgcHJlc2VuY2VcbiAgICAvLyBvZiByZWFkLW9ubHkgc3BhbnMgaW4gaXRzIHJhbmdlLlxuICAgIHZhciBzcGxpdCA9IHNhd1JlYWRPbmx5U3BhbnMgJiYgIWlnbm9yZVJlYWRPbmx5ICYmIHJlbW92ZVJlYWRPbmx5UmFuZ2VzKGRvYywgY2hhbmdlLmZyb20sIGNoYW5nZS50byk7XG4gICAgaWYgKHNwbGl0KSB7XG4gICAgICBmb3IgKHZhciBpID0gc3BsaXQubGVuZ3RoIC0gMTsgaSA+PSAwOyAtLWkpXG4gICAgICAgIG1ha2VDaGFuZ2VJbm5lcihkb2MsIHtmcm9tOiBzcGxpdFtpXS5mcm9tLCB0bzogc3BsaXRbaV0udG8sIHRleHQ6IGkgPyBbXCJcIl0gOiBjaGFuZ2UudGV4dH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBtYWtlQ2hhbmdlSW5uZXIoZG9jLCBjaGFuZ2UpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIG1ha2VDaGFuZ2VJbm5lcihkb2MsIGNoYW5nZSkge1xuICAgIGlmIChjaGFuZ2UudGV4dC5sZW5ndGggPT0gMSAmJiBjaGFuZ2UudGV4dFswXSA9PSBcIlwiICYmIGNtcChjaGFuZ2UuZnJvbSwgY2hhbmdlLnRvKSA9PSAwKSByZXR1cm47XG4gICAgdmFyIHNlbEFmdGVyID0gY29tcHV0ZVNlbEFmdGVyQ2hhbmdlKGRvYywgY2hhbmdlKTtcbiAgICBhZGRDaGFuZ2VUb0hpc3RvcnkoZG9jLCBjaGFuZ2UsIHNlbEFmdGVyLCBkb2MuY20gPyBkb2MuY20uY3VyT3AuaWQgOiBOYU4pO1xuXG4gICAgbWFrZUNoYW5nZVNpbmdsZURvYyhkb2MsIGNoYW5nZSwgc2VsQWZ0ZXIsIHN0cmV0Y2hTcGFuc092ZXJDaGFuZ2UoZG9jLCBjaGFuZ2UpKTtcbiAgICB2YXIgcmViYXNlZCA9IFtdO1xuXG4gICAgbGlua2VkRG9jcyhkb2MsIGZ1bmN0aW9uKGRvYywgc2hhcmVkSGlzdCkge1xuICAgICAgaWYgKCFzaGFyZWRIaXN0ICYmIGluZGV4T2YocmViYXNlZCwgZG9jLmhpc3RvcnkpID09IC0xKSB7XG4gICAgICAgIHJlYmFzZUhpc3QoZG9jLmhpc3RvcnksIGNoYW5nZSk7XG4gICAgICAgIHJlYmFzZWQucHVzaChkb2MuaGlzdG9yeSk7XG4gICAgICB9XG4gICAgICBtYWtlQ2hhbmdlU2luZ2xlRG9jKGRvYywgY2hhbmdlLCBudWxsLCBzdHJldGNoU3BhbnNPdmVyQ2hhbmdlKGRvYywgY2hhbmdlKSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBSZXZlcnQgYSBjaGFuZ2Ugc3RvcmVkIGluIGEgZG9jdW1lbnQncyBoaXN0b3J5LlxuICBmdW5jdGlvbiBtYWtlQ2hhbmdlRnJvbUhpc3RvcnkoZG9jLCB0eXBlLCBhbGxvd1NlbGVjdGlvbk9ubHkpIHtcbiAgICBpZiAoZG9jLmNtICYmIGRvYy5jbS5zdGF0ZS5zdXBwcmVzc0VkaXRzKSByZXR1cm47XG5cbiAgICB2YXIgaGlzdCA9IGRvYy5oaXN0b3J5LCBldmVudCwgc2VsQWZ0ZXIgPSBkb2Muc2VsO1xuICAgIHZhciBzb3VyY2UgPSB0eXBlID09IFwidW5kb1wiID8gaGlzdC5kb25lIDogaGlzdC51bmRvbmUsIGRlc3QgPSB0eXBlID09IFwidW5kb1wiID8gaGlzdC51bmRvbmUgOiBoaXN0LmRvbmU7XG5cbiAgICAvLyBWZXJpZnkgdGhhdCB0aGVyZSBpcyBhIHVzZWFibGUgZXZlbnQgKHNvIHRoYXQgY3RybC16IHdvbid0XG4gICAgLy8gbmVlZGxlc3NseSBjbGVhciBzZWxlY3Rpb24gZXZlbnRzKVxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc291cmNlLmxlbmd0aDsgaSsrKSB7XG4gICAgICBldmVudCA9IHNvdXJjZVtpXTtcbiAgICAgIGlmIChhbGxvd1NlbGVjdGlvbk9ubHkgPyBldmVudC5yYW5nZXMgJiYgIWV2ZW50LmVxdWFscyhkb2Muc2VsKSA6ICFldmVudC5yYW5nZXMpXG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBpZiAoaSA9PSBzb3VyY2UubGVuZ3RoKSByZXR1cm47XG4gICAgaGlzdC5sYXN0T3JpZ2luID0gaGlzdC5sYXN0U2VsT3JpZ2luID0gbnVsbDtcblxuICAgIGZvciAoOzspIHtcbiAgICAgIGV2ZW50ID0gc291cmNlLnBvcCgpO1xuICAgICAgaWYgKGV2ZW50LnJhbmdlcykge1xuICAgICAgICBwdXNoU2VsZWN0aW9uVG9IaXN0b3J5KGV2ZW50LCBkZXN0KTtcbiAgICAgICAgaWYgKGFsbG93U2VsZWN0aW9uT25seSAmJiAhZXZlbnQuZXF1YWxzKGRvYy5zZWwpKSB7XG4gICAgICAgICAgc2V0U2VsZWN0aW9uKGRvYywgZXZlbnQsIHtjbGVhclJlZG86IGZhbHNlfSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHNlbEFmdGVyID0gZXZlbnQ7XG4gICAgICB9XG4gICAgICBlbHNlIGJyZWFrO1xuICAgIH1cblxuICAgIC8vIEJ1aWxkIHVwIGEgcmV2ZXJzZSBjaGFuZ2Ugb2JqZWN0IHRvIGFkZCB0byB0aGUgb3Bwb3NpdGUgaGlzdG9yeVxuICAgIC8vIHN0YWNrIChyZWRvIHdoZW4gdW5kb2luZywgYW5kIHZpY2UgdmVyc2EpLlxuICAgIHZhciBhbnRpQ2hhbmdlcyA9IFtdO1xuICAgIHB1c2hTZWxlY3Rpb25Ub0hpc3Rvcnkoc2VsQWZ0ZXIsIGRlc3QpO1xuICAgIGRlc3QucHVzaCh7Y2hhbmdlczogYW50aUNoYW5nZXMsIGdlbmVyYXRpb246IGhpc3QuZ2VuZXJhdGlvbn0pO1xuICAgIGhpc3QuZ2VuZXJhdGlvbiA9IGV2ZW50LmdlbmVyYXRpb24gfHwgKytoaXN0Lm1heEdlbmVyYXRpb247XG5cbiAgICB2YXIgZmlsdGVyID0gaGFzSGFuZGxlcihkb2MsIFwiYmVmb3JlQ2hhbmdlXCIpIHx8IGRvYy5jbSAmJiBoYXNIYW5kbGVyKGRvYy5jbSwgXCJiZWZvcmVDaGFuZ2VcIik7XG5cbiAgICBmb3IgKHZhciBpID0gZXZlbnQuY2hhbmdlcy5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgdmFyIGNoYW5nZSA9IGV2ZW50LmNoYW5nZXNbaV07XG4gICAgICBjaGFuZ2Uub3JpZ2luID0gdHlwZTtcbiAgICAgIGlmIChmaWx0ZXIgJiYgIWZpbHRlckNoYW5nZShkb2MsIGNoYW5nZSwgZmFsc2UpKSB7XG4gICAgICAgIHNvdXJjZS5sZW5ndGggPSAwO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGFudGlDaGFuZ2VzLnB1c2goaGlzdG9yeUNoYW5nZUZyb21DaGFuZ2UoZG9jLCBjaGFuZ2UpKTtcblxuICAgICAgdmFyIGFmdGVyID0gaSA/IGNvbXB1dGVTZWxBZnRlckNoYW5nZShkb2MsIGNoYW5nZSkgOiBsc3Qoc291cmNlKTtcbiAgICAgIG1ha2VDaGFuZ2VTaW5nbGVEb2MoZG9jLCBjaGFuZ2UsIGFmdGVyLCBtZXJnZU9sZFNwYW5zKGRvYywgY2hhbmdlKSk7XG4gICAgICBpZiAoIWkgJiYgZG9jLmNtKSBkb2MuY20uc2Nyb2xsSW50b1ZpZXcoe2Zyb206IGNoYW5nZS5mcm9tLCB0bzogY2hhbmdlRW5kKGNoYW5nZSl9KTtcbiAgICAgIHZhciByZWJhc2VkID0gW107XG5cbiAgICAgIC8vIFByb3BhZ2F0ZSB0byB0aGUgbGlua2VkIGRvY3VtZW50c1xuICAgICAgbGlua2VkRG9jcyhkb2MsIGZ1bmN0aW9uKGRvYywgc2hhcmVkSGlzdCkge1xuICAgICAgICBpZiAoIXNoYXJlZEhpc3QgJiYgaW5kZXhPZihyZWJhc2VkLCBkb2MuaGlzdG9yeSkgPT0gLTEpIHtcbiAgICAgICAgICByZWJhc2VIaXN0KGRvYy5oaXN0b3J5LCBjaGFuZ2UpO1xuICAgICAgICAgIHJlYmFzZWQucHVzaChkb2MuaGlzdG9yeSk7XG4gICAgICAgIH1cbiAgICAgICAgbWFrZUNoYW5nZVNpbmdsZURvYyhkb2MsIGNoYW5nZSwgbnVsbCwgbWVyZ2VPbGRTcGFucyhkb2MsIGNoYW5nZSkpO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLy8gU3ViLXZpZXdzIG5lZWQgdGhlaXIgbGluZSBudW1iZXJzIHNoaWZ0ZWQgd2hlbiB0ZXh0IGlzIGFkZGVkXG4gIC8vIGFib3ZlIG9yIGJlbG93IHRoZW0gaW4gdGhlIHBhcmVudCBkb2N1bWVudC5cbiAgZnVuY3Rpb24gc2hpZnREb2MoZG9jLCBkaXN0YW5jZSkge1xuICAgIGlmIChkaXN0YW5jZSA9PSAwKSByZXR1cm47XG4gICAgZG9jLmZpcnN0ICs9IGRpc3RhbmNlO1xuICAgIGRvYy5zZWwgPSBuZXcgU2VsZWN0aW9uKG1hcChkb2Muc2VsLnJhbmdlcywgZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgIHJldHVybiBuZXcgUmFuZ2UoUG9zKHJhbmdlLmFuY2hvci5saW5lICsgZGlzdGFuY2UsIHJhbmdlLmFuY2hvci5jaCksXG4gICAgICAgICAgICAgICAgICAgICAgIFBvcyhyYW5nZS5oZWFkLmxpbmUgKyBkaXN0YW5jZSwgcmFuZ2UuaGVhZC5jaCkpO1xuICAgIH0pLCBkb2Muc2VsLnByaW1JbmRleCk7XG4gICAgaWYgKGRvYy5jbSkge1xuICAgICAgcmVnQ2hhbmdlKGRvYy5jbSwgZG9jLmZpcnN0LCBkb2MuZmlyc3QgLSBkaXN0YW5jZSwgZGlzdGFuY2UpO1xuICAgICAgZm9yICh2YXIgZCA9IGRvYy5jbS5kaXNwbGF5LCBsID0gZC52aWV3RnJvbTsgbCA8IGQudmlld1RvOyBsKyspXG4gICAgICAgIHJlZ0xpbmVDaGFuZ2UoZG9jLmNtLCBsLCBcImd1dHRlclwiKTtcbiAgICB9XG4gIH1cblxuICAvLyBNb3JlIGxvd2VyLWxldmVsIGNoYW5nZSBmdW5jdGlvbiwgaGFuZGxpbmcgb25seSBhIHNpbmdsZSBkb2N1bWVudFxuICAvLyAobm90IGxpbmtlZCBvbmVzKS5cbiAgZnVuY3Rpb24gbWFrZUNoYW5nZVNpbmdsZURvYyhkb2MsIGNoYW5nZSwgc2VsQWZ0ZXIsIHNwYW5zKSB7XG4gICAgaWYgKGRvYy5jbSAmJiAhZG9jLmNtLmN1ck9wKVxuICAgICAgcmV0dXJuIG9wZXJhdGlvbihkb2MuY20sIG1ha2VDaGFuZ2VTaW5nbGVEb2MpKGRvYywgY2hhbmdlLCBzZWxBZnRlciwgc3BhbnMpO1xuXG4gICAgaWYgKGNoYW5nZS50by5saW5lIDwgZG9jLmZpcnN0KSB7XG4gICAgICBzaGlmdERvYyhkb2MsIGNoYW5nZS50ZXh0Lmxlbmd0aCAtIDEgLSAoY2hhbmdlLnRvLmxpbmUgLSBjaGFuZ2UuZnJvbS5saW5lKSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChjaGFuZ2UuZnJvbS5saW5lID4gZG9jLmxhc3RMaW5lKCkpIHJldHVybjtcblxuICAgIC8vIENsaXAgdGhlIGNoYW5nZSB0byB0aGUgc2l6ZSBvZiB0aGlzIGRvY1xuICAgIGlmIChjaGFuZ2UuZnJvbS5saW5lIDwgZG9jLmZpcnN0KSB7XG4gICAgICB2YXIgc2hpZnQgPSBjaGFuZ2UudGV4dC5sZW5ndGggLSAxIC0gKGRvYy5maXJzdCAtIGNoYW5nZS5mcm9tLmxpbmUpO1xuICAgICAgc2hpZnREb2MoZG9jLCBzaGlmdCk7XG4gICAgICBjaGFuZ2UgPSB7ZnJvbTogUG9zKGRvYy5maXJzdCwgMCksIHRvOiBQb3MoY2hhbmdlLnRvLmxpbmUgKyBzaGlmdCwgY2hhbmdlLnRvLmNoKSxcbiAgICAgICAgICAgICAgICB0ZXh0OiBbbHN0KGNoYW5nZS50ZXh0KV0sIG9yaWdpbjogY2hhbmdlLm9yaWdpbn07XG4gICAgfVxuICAgIHZhciBsYXN0ID0gZG9jLmxhc3RMaW5lKCk7XG4gICAgaWYgKGNoYW5nZS50by5saW5lID4gbGFzdCkge1xuICAgICAgY2hhbmdlID0ge2Zyb206IGNoYW5nZS5mcm9tLCB0bzogUG9zKGxhc3QsIGdldExpbmUoZG9jLCBsYXN0KS50ZXh0Lmxlbmd0aCksXG4gICAgICAgICAgICAgICAgdGV4dDogW2NoYW5nZS50ZXh0WzBdXSwgb3JpZ2luOiBjaGFuZ2Uub3JpZ2lufTtcbiAgICB9XG5cbiAgICBjaGFuZ2UucmVtb3ZlZCA9IGdldEJldHdlZW4oZG9jLCBjaGFuZ2UuZnJvbSwgY2hhbmdlLnRvKTtcblxuICAgIGlmICghc2VsQWZ0ZXIpIHNlbEFmdGVyID0gY29tcHV0ZVNlbEFmdGVyQ2hhbmdlKGRvYywgY2hhbmdlKTtcbiAgICBpZiAoZG9jLmNtKSBtYWtlQ2hhbmdlU2luZ2xlRG9jSW5FZGl0b3IoZG9jLmNtLCBjaGFuZ2UsIHNwYW5zKTtcbiAgICBlbHNlIHVwZGF0ZURvYyhkb2MsIGNoYW5nZSwgc3BhbnMpO1xuICAgIHNldFNlbGVjdGlvbk5vVW5kbyhkb2MsIHNlbEFmdGVyLCBzZWxfZG9udFNjcm9sbCk7XG4gIH1cblxuICAvLyBIYW5kbGUgdGhlIGludGVyYWN0aW9uIG9mIGEgY2hhbmdlIHRvIGEgZG9jdW1lbnQgd2l0aCB0aGUgZWRpdG9yXG4gIC8vIHRoYXQgdGhpcyBkb2N1bWVudCBpcyBwYXJ0IG9mLlxuICBmdW5jdGlvbiBtYWtlQ2hhbmdlU2luZ2xlRG9jSW5FZGl0b3IoY20sIGNoYW5nZSwgc3BhbnMpIHtcbiAgICB2YXIgZG9jID0gY20uZG9jLCBkaXNwbGF5ID0gY20uZGlzcGxheSwgZnJvbSA9IGNoYW5nZS5mcm9tLCB0byA9IGNoYW5nZS50bztcblxuICAgIHZhciByZWNvbXB1dGVNYXhMZW5ndGggPSBmYWxzZSwgY2hlY2tXaWR0aFN0YXJ0ID0gZnJvbS5saW5lO1xuICAgIGlmICghY20ub3B0aW9ucy5saW5lV3JhcHBpbmcpIHtcbiAgICAgIGNoZWNrV2lkdGhTdGFydCA9IGxpbmVObyh2aXN1YWxMaW5lKGdldExpbmUoZG9jLCBmcm9tLmxpbmUpKSk7XG4gICAgICBkb2MuaXRlcihjaGVja1dpZHRoU3RhcnQsIHRvLmxpbmUgKyAxLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIGlmIChsaW5lID09IGRpc3BsYXkubWF4TGluZSkge1xuICAgICAgICAgIHJlY29tcHV0ZU1heExlbmd0aCA9IHRydWU7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmIChkb2Muc2VsLmNvbnRhaW5zKGNoYW5nZS5mcm9tLCBjaGFuZ2UudG8pID4gLTEpXG4gICAgICBzaWduYWxDdXJzb3JBY3Rpdml0eShjbSk7XG5cbiAgICB1cGRhdGVEb2MoZG9jLCBjaGFuZ2UsIHNwYW5zLCBlc3RpbWF0ZUhlaWdodChjbSkpO1xuXG4gICAgaWYgKCFjbS5vcHRpb25zLmxpbmVXcmFwcGluZykge1xuICAgICAgZG9jLml0ZXIoY2hlY2tXaWR0aFN0YXJ0LCBmcm9tLmxpbmUgKyBjaGFuZ2UudGV4dC5sZW5ndGgsIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgdmFyIGxlbiA9IGxpbmVMZW5ndGgobGluZSk7XG4gICAgICAgIGlmIChsZW4gPiBkaXNwbGF5Lm1heExpbmVMZW5ndGgpIHtcbiAgICAgICAgICBkaXNwbGF5Lm1heExpbmUgPSBsaW5lO1xuICAgICAgICAgIGRpc3BsYXkubWF4TGluZUxlbmd0aCA9IGxlbjtcbiAgICAgICAgICBkaXNwbGF5Lm1heExpbmVDaGFuZ2VkID0gdHJ1ZTtcbiAgICAgICAgICByZWNvbXB1dGVNYXhMZW5ndGggPSBmYWxzZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgICBpZiAocmVjb21wdXRlTWF4TGVuZ3RoKSBjbS5jdXJPcC51cGRhdGVNYXhMaW5lID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBBZGp1c3QgZnJvbnRpZXIsIHNjaGVkdWxlIHdvcmtlclxuICAgIGRvYy5mcm9udGllciA9IE1hdGgubWluKGRvYy5mcm9udGllciwgZnJvbS5saW5lKTtcbiAgICBzdGFydFdvcmtlcihjbSwgNDAwKTtcblxuICAgIHZhciBsZW5kaWZmID0gY2hhbmdlLnRleHQubGVuZ3RoIC0gKHRvLmxpbmUgLSBmcm9tLmxpbmUpIC0gMTtcbiAgICAvLyBSZW1lbWJlciB0aGF0IHRoZXNlIGxpbmVzIGNoYW5nZWQsIGZvciB1cGRhdGluZyB0aGUgZGlzcGxheVxuICAgIGlmIChjaGFuZ2UuZnVsbClcbiAgICAgIHJlZ0NoYW5nZShjbSk7XG4gICAgZWxzZSBpZiAoZnJvbS5saW5lID09IHRvLmxpbmUgJiYgY2hhbmdlLnRleHQubGVuZ3RoID09IDEgJiYgIWlzV2hvbGVMaW5lVXBkYXRlKGNtLmRvYywgY2hhbmdlKSlcbiAgICAgIHJlZ0xpbmVDaGFuZ2UoY20sIGZyb20ubGluZSwgXCJ0ZXh0XCIpO1xuICAgIGVsc2VcbiAgICAgIHJlZ0NoYW5nZShjbSwgZnJvbS5saW5lLCB0by5saW5lICsgMSwgbGVuZGlmZik7XG5cbiAgICB2YXIgY2hhbmdlc0hhbmRsZXIgPSBoYXNIYW5kbGVyKGNtLCBcImNoYW5nZXNcIiksIGNoYW5nZUhhbmRsZXIgPSBoYXNIYW5kbGVyKGNtLCBcImNoYW5nZVwiKTtcbiAgICBpZiAoY2hhbmdlSGFuZGxlciB8fCBjaGFuZ2VzSGFuZGxlcikge1xuICAgICAgdmFyIG9iaiA9IHtcbiAgICAgICAgZnJvbTogZnJvbSwgdG86IHRvLFxuICAgICAgICB0ZXh0OiBjaGFuZ2UudGV4dCxcbiAgICAgICAgcmVtb3ZlZDogY2hhbmdlLnJlbW92ZWQsXG4gICAgICAgIG9yaWdpbjogY2hhbmdlLm9yaWdpblxuICAgICAgfTtcbiAgICAgIGlmIChjaGFuZ2VIYW5kbGVyKSBzaWduYWxMYXRlcihjbSwgXCJjaGFuZ2VcIiwgY20sIG9iaik7XG4gICAgICBpZiAoY2hhbmdlc0hhbmRsZXIpIChjbS5jdXJPcC5jaGFuZ2VPYmpzIHx8IChjbS5jdXJPcC5jaGFuZ2VPYmpzID0gW10pKS5wdXNoKG9iaik7XG4gICAgfVxuICAgIGNtLmRpc3BsYXkuc2VsRm9yQ29udGV4dE1lbnUgPSBudWxsO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVwbGFjZVJhbmdlKGRvYywgY29kZSwgZnJvbSwgdG8sIG9yaWdpbikge1xuICAgIGlmICghdG8pIHRvID0gZnJvbTtcbiAgICBpZiAoY21wKHRvLCBmcm9tKSA8IDApIHsgdmFyIHRtcCA9IHRvOyB0byA9IGZyb207IGZyb20gPSB0bXA7IH1cbiAgICBpZiAodHlwZW9mIGNvZGUgPT0gXCJzdHJpbmdcIikgY29kZSA9IHNwbGl0TGluZXMoY29kZSk7XG4gICAgbWFrZUNoYW5nZShkb2MsIHtmcm9tOiBmcm9tLCB0bzogdG8sIHRleHQ6IGNvZGUsIG9yaWdpbjogb3JpZ2lufSk7XG4gIH1cblxuICAvLyBTQ1JPTExJTkcgVEhJTkdTIElOVE8gVklFV1xuXG4gIC8vIElmIGFuIGVkaXRvciBzaXRzIG9uIHRoZSB0b3Agb3IgYm90dG9tIG9mIHRoZSB3aW5kb3csIHBhcnRpYWxseVxuICAvLyBzY3JvbGxlZCBvdXQgb2YgdmlldywgdGhpcyBlbnN1cmVzIHRoYXQgdGhlIGN1cnNvciBpcyB2aXNpYmxlLlxuICBmdW5jdGlvbiBtYXliZVNjcm9sbFdpbmRvdyhjbSwgY29vcmRzKSB7XG4gICAgaWYgKHNpZ25hbERPTUV2ZW50KGNtLCBcInNjcm9sbEN1cnNvckludG9WaWV3XCIpKSByZXR1cm47XG5cbiAgICB2YXIgZGlzcGxheSA9IGNtLmRpc3BsYXksIGJveCA9IGRpc3BsYXkuc2l6ZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCksIGRvU2Nyb2xsID0gbnVsbDtcbiAgICBpZiAoY29vcmRzLnRvcCArIGJveC50b3AgPCAwKSBkb1Njcm9sbCA9IHRydWU7XG4gICAgZWxzZSBpZiAoY29vcmRzLmJvdHRvbSArIGJveC50b3AgPiAod2luZG93LmlubmVySGVpZ2h0IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRIZWlnaHQpKSBkb1Njcm9sbCA9IGZhbHNlO1xuICAgIGlmIChkb1Njcm9sbCAhPSBudWxsICYmICFwaGFudG9tKSB7XG4gICAgICB2YXIgc2Nyb2xsTm9kZSA9IGVsdChcImRpdlwiLCBcIlxcdTIwMGJcIiwgbnVsbCwgXCJwb3NpdGlvbjogYWJzb2x1dGU7IHRvcDogXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvb3Jkcy50b3AgLSBkaXNwbGF5LnZpZXdPZmZzZXQgLSBwYWRkaW5nVG9wKGNtLmRpc3BsYXkpKSArIFwicHg7IGhlaWdodDogXCIgK1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvb3Jkcy5ib3R0b20gLSBjb29yZHMudG9wICsgc2Nyb2xsR2FwKGNtKSArIGRpc3BsYXkuYmFySGVpZ2h0KSArIFwicHg7IGxlZnQ6IFwiICtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvb3Jkcy5sZWZ0ICsgXCJweDsgd2lkdGg6IDJweDtcIik7XG4gICAgICBjbS5kaXNwbGF5LmxpbmVTcGFjZS5hcHBlbmRDaGlsZChzY3JvbGxOb2RlKTtcbiAgICAgIHNjcm9sbE5vZGUuc2Nyb2xsSW50b1ZpZXcoZG9TY3JvbGwpO1xuICAgICAgY20uZGlzcGxheS5saW5lU3BhY2UucmVtb3ZlQ2hpbGQoc2Nyb2xsTm9kZSk7XG4gICAgfVxuICB9XG5cbiAgLy8gU2Nyb2xsIGEgZ2l2ZW4gcG9zaXRpb24gaW50byB2aWV3IChpbW1lZGlhdGVseSksIHZlcmlmeWluZyB0aGF0XG4gIC8vIGl0IGFjdHVhbGx5IGJlY2FtZSB2aXNpYmxlIChhcyBsaW5lIGhlaWdodHMgYXJlIGFjY3VyYXRlbHlcbiAgLy8gbWVhc3VyZWQsIHRoZSBwb3NpdGlvbiBvZiBzb21ldGhpbmcgbWF5ICdkcmlmdCcgZHVyaW5nIGRyYXdpbmcpLlxuICBmdW5jdGlvbiBzY3JvbGxQb3NJbnRvVmlldyhjbSwgcG9zLCBlbmQsIG1hcmdpbikge1xuICAgIGlmIChtYXJnaW4gPT0gbnVsbCkgbWFyZ2luID0gMDtcbiAgICBmb3IgKHZhciBsaW1pdCA9IDA7IGxpbWl0IDwgNTsgbGltaXQrKykge1xuICAgICAgdmFyIGNoYW5nZWQgPSBmYWxzZSwgY29vcmRzID0gY3Vyc29yQ29vcmRzKGNtLCBwb3MpO1xuICAgICAgdmFyIGVuZENvb3JkcyA9ICFlbmQgfHwgZW5kID09IHBvcyA/IGNvb3JkcyA6IGN1cnNvckNvb3JkcyhjbSwgZW5kKTtcbiAgICAgIHZhciBzY3JvbGxQb3MgPSBjYWxjdWxhdGVTY3JvbGxQb3MoY20sIE1hdGgubWluKGNvb3Jkcy5sZWZ0LCBlbmRDb29yZHMubGVmdCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGgubWluKGNvb3Jkcy50b3AsIGVuZENvb3Jkcy50b3ApIC0gbWFyZ2luLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLm1heChjb29yZHMubGVmdCwgZW5kQ29vcmRzLmxlZnQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLm1heChjb29yZHMuYm90dG9tLCBlbmRDb29yZHMuYm90dG9tKSArIG1hcmdpbik7XG4gICAgICB2YXIgc3RhcnRUb3AgPSBjbS5kb2Muc2Nyb2xsVG9wLCBzdGFydExlZnQgPSBjbS5kb2Muc2Nyb2xsTGVmdDtcbiAgICAgIGlmIChzY3JvbGxQb3Muc2Nyb2xsVG9wICE9IG51bGwpIHtcbiAgICAgICAgc2V0U2Nyb2xsVG9wKGNtLCBzY3JvbGxQb3Muc2Nyb2xsVG9wKTtcbiAgICAgICAgaWYgKE1hdGguYWJzKGNtLmRvYy5zY3JvbGxUb3AgLSBzdGFydFRvcCkgPiAxKSBjaGFuZ2VkID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIGlmIChzY3JvbGxQb3Muc2Nyb2xsTGVmdCAhPSBudWxsKSB7XG4gICAgICAgIHNldFNjcm9sbExlZnQoY20sIHNjcm9sbFBvcy5zY3JvbGxMZWZ0KTtcbiAgICAgICAgaWYgKE1hdGguYWJzKGNtLmRvYy5zY3JvbGxMZWZ0IC0gc3RhcnRMZWZ0KSA+IDEpIGNoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgICAgaWYgKCFjaGFuZ2VkKSBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGNvb3JkcztcbiAgfVxuXG4gIC8vIFNjcm9sbCBhIGdpdmVuIHNldCBvZiBjb29yZGluYXRlcyBpbnRvIHZpZXcgKGltbWVkaWF0ZWx5KS5cbiAgZnVuY3Rpb24gc2Nyb2xsSW50b1ZpZXcoY20sIHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgdmFyIHNjcm9sbFBvcyA9IGNhbGN1bGF0ZVNjcm9sbFBvcyhjbSwgeDEsIHkxLCB4MiwgeTIpO1xuICAgIGlmIChzY3JvbGxQb3Muc2Nyb2xsVG9wICE9IG51bGwpIHNldFNjcm9sbFRvcChjbSwgc2Nyb2xsUG9zLnNjcm9sbFRvcCk7XG4gICAgaWYgKHNjcm9sbFBvcy5zY3JvbGxMZWZ0ICE9IG51bGwpIHNldFNjcm9sbExlZnQoY20sIHNjcm9sbFBvcy5zY3JvbGxMZWZ0KTtcbiAgfVxuXG4gIC8vIENhbGN1bGF0ZSBhIG5ldyBzY3JvbGwgcG9zaXRpb24gbmVlZGVkIHRvIHNjcm9sbCB0aGUgZ2l2ZW5cbiAgLy8gcmVjdGFuZ2xlIGludG8gdmlldy4gUmV0dXJucyBhbiBvYmplY3Qgd2l0aCBzY3JvbGxUb3AgYW5kXG4gIC8vIHNjcm9sbExlZnQgcHJvcGVydGllcy4gV2hlbiB0aGVzZSBhcmUgdW5kZWZpbmVkLCB0aGVcbiAgLy8gdmVydGljYWwvaG9yaXpvbnRhbCBwb3NpdGlvbiBkb2VzIG5vdCBuZWVkIHRvIGJlIGFkanVzdGVkLlxuICBmdW5jdGlvbiBjYWxjdWxhdGVTY3JvbGxQb3MoY20sIHgxLCB5MSwgeDIsIHkyKSB7XG4gICAgdmFyIGRpc3BsYXkgPSBjbS5kaXNwbGF5LCBzbmFwTWFyZ2luID0gdGV4dEhlaWdodChjbS5kaXNwbGF5KTtcbiAgICBpZiAoeTEgPCAwKSB5MSA9IDA7XG4gICAgdmFyIHNjcmVlbnRvcCA9IGNtLmN1ck9wICYmIGNtLmN1ck9wLnNjcm9sbFRvcCAhPSBudWxsID8gY20uY3VyT3Auc2Nyb2xsVG9wIDogZGlzcGxheS5zY3JvbGxlci5zY3JvbGxUb3A7XG4gICAgdmFyIHNjcmVlbiA9IGRpc3BsYXlIZWlnaHQoY20pLCByZXN1bHQgPSB7fTtcbiAgICBpZiAoeTIgLSB5MSA+IHNjcmVlbikgeTIgPSB5MSArIHNjcmVlbjtcbiAgICB2YXIgZG9jQm90dG9tID0gY20uZG9jLmhlaWdodCArIHBhZGRpbmdWZXJ0KGRpc3BsYXkpO1xuICAgIHZhciBhdFRvcCA9IHkxIDwgc25hcE1hcmdpbiwgYXRCb3R0b20gPSB5MiA+IGRvY0JvdHRvbSAtIHNuYXBNYXJnaW47XG4gICAgaWYgKHkxIDwgc2NyZWVudG9wKSB7XG4gICAgICByZXN1bHQuc2Nyb2xsVG9wID0gYXRUb3AgPyAwIDogeTE7XG4gICAgfSBlbHNlIGlmICh5MiA+IHNjcmVlbnRvcCArIHNjcmVlbikge1xuICAgICAgdmFyIG5ld1RvcCA9IE1hdGgubWluKHkxLCAoYXRCb3R0b20gPyBkb2NCb3R0b20gOiB5MikgLSBzY3JlZW4pO1xuICAgICAgaWYgKG5ld1RvcCAhPSBzY3JlZW50b3ApIHJlc3VsdC5zY3JvbGxUb3AgPSBuZXdUb3A7XG4gICAgfVxuXG4gICAgdmFyIHNjcmVlbmxlZnQgPSBjbS5jdXJPcCAmJiBjbS5jdXJPcC5zY3JvbGxMZWZ0ICE9IG51bGwgPyBjbS5jdXJPcC5zY3JvbGxMZWZ0IDogZGlzcGxheS5zY3JvbGxlci5zY3JvbGxMZWZ0O1xuICAgIHZhciBzY3JlZW53ID0gZGlzcGxheVdpZHRoKGNtKSAtIChjbS5vcHRpb25zLmZpeGVkR3V0dGVyID8gZGlzcGxheS5ndXR0ZXJzLm9mZnNldFdpZHRoIDogMCk7XG4gICAgdmFyIHRvb1dpZGUgPSB4MiAtIHgxID4gc2NyZWVudztcbiAgICBpZiAodG9vV2lkZSkgeDIgPSB4MSArIHNjcmVlbnc7XG4gICAgaWYgKHgxIDwgMTApXG4gICAgICByZXN1bHQuc2Nyb2xsTGVmdCA9IDA7XG4gICAgZWxzZSBpZiAoeDEgPCBzY3JlZW5sZWZ0KVxuICAgICAgcmVzdWx0LnNjcm9sbExlZnQgPSBNYXRoLm1heCgwLCB4MSAtICh0b29XaWRlID8gMCA6IDEwKSk7XG4gICAgZWxzZSBpZiAoeDIgPiBzY3JlZW53ICsgc2NyZWVubGVmdCAtIDMpXG4gICAgICByZXN1bHQuc2Nyb2xsTGVmdCA9IHgyICsgKHRvb1dpZGUgPyAwIDogMTApIC0gc2NyZWVudztcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gU3RvcmUgYSByZWxhdGl2ZSBhZGp1c3RtZW50IHRvIHRoZSBzY3JvbGwgcG9zaXRpb24gaW4gdGhlIGN1cnJlbnRcbiAgLy8gb3BlcmF0aW9uICh0byBiZSBhcHBsaWVkIHdoZW4gdGhlIG9wZXJhdGlvbiBmaW5pc2hlcykuXG4gIGZ1bmN0aW9uIGFkZFRvU2Nyb2xsUG9zKGNtLCBsZWZ0LCB0b3ApIHtcbiAgICBpZiAobGVmdCAhPSBudWxsIHx8IHRvcCAhPSBudWxsKSByZXNvbHZlU2Nyb2xsVG9Qb3MoY20pO1xuICAgIGlmIChsZWZ0ICE9IG51bGwpXG4gICAgICBjbS5jdXJPcC5zY3JvbGxMZWZ0ID0gKGNtLmN1ck9wLnNjcm9sbExlZnQgPT0gbnVsbCA/IGNtLmRvYy5zY3JvbGxMZWZ0IDogY20uY3VyT3Auc2Nyb2xsTGVmdCkgKyBsZWZ0O1xuICAgIGlmICh0b3AgIT0gbnVsbClcbiAgICAgIGNtLmN1ck9wLnNjcm9sbFRvcCA9IChjbS5jdXJPcC5zY3JvbGxUb3AgPT0gbnVsbCA/IGNtLmRvYy5zY3JvbGxUb3AgOiBjbS5jdXJPcC5zY3JvbGxUb3ApICsgdG9wO1xuICB9XG5cbiAgLy8gTWFrZSBzdXJlIHRoYXQgYXQgdGhlIGVuZCBvZiB0aGUgb3BlcmF0aW9uIHRoZSBjdXJyZW50IGN1cnNvciBpc1xuICAvLyBzaG93bi5cbiAgZnVuY3Rpb24gZW5zdXJlQ3Vyc29yVmlzaWJsZShjbSkge1xuICAgIHJlc29sdmVTY3JvbGxUb1BvcyhjbSk7XG4gICAgdmFyIGN1ciA9IGNtLmdldEN1cnNvcigpLCBmcm9tID0gY3VyLCB0byA9IGN1cjtcbiAgICBpZiAoIWNtLm9wdGlvbnMubGluZVdyYXBwaW5nKSB7XG4gICAgICBmcm9tID0gY3VyLmNoID8gUG9zKGN1ci5saW5lLCBjdXIuY2ggLSAxKSA6IGN1cjtcbiAgICAgIHRvID0gUG9zKGN1ci5saW5lLCBjdXIuY2ggKyAxKTtcbiAgICB9XG4gICAgY20uY3VyT3Auc2Nyb2xsVG9Qb3MgPSB7ZnJvbTogZnJvbSwgdG86IHRvLCBtYXJnaW46IGNtLm9wdGlvbnMuY3Vyc29yU2Nyb2xsTWFyZ2luLCBpc0N1cnNvcjogdHJ1ZX07XG4gIH1cblxuICAvLyBXaGVuIGFuIG9wZXJhdGlvbiBoYXMgaXRzIHNjcm9sbFRvUG9zIHByb3BlcnR5IHNldCwgYW5kIGFub3RoZXJcbiAgLy8gc2Nyb2xsIGFjdGlvbiBpcyBhcHBsaWVkIGJlZm9yZSB0aGUgZW5kIG9mIHRoZSBvcGVyYXRpb24sIHRoaXNcbiAgLy8gJ3NpbXVsYXRlcycgc2Nyb2xsaW5nIHRoYXQgcG9zaXRpb24gaW50byB2aWV3IGluIGEgY2hlYXAgd2F5LCBzb1xuICAvLyB0aGF0IHRoZSBlZmZlY3Qgb2YgaW50ZXJtZWRpYXRlIHNjcm9sbCBjb21tYW5kcyBpcyBub3QgaWdub3JlZC5cbiAgZnVuY3Rpb24gcmVzb2x2ZVNjcm9sbFRvUG9zKGNtKSB7XG4gICAgdmFyIHJhbmdlID0gY20uY3VyT3Auc2Nyb2xsVG9Qb3M7XG4gICAgaWYgKHJhbmdlKSB7XG4gICAgICBjbS5jdXJPcC5zY3JvbGxUb1BvcyA9IG51bGw7XG4gICAgICB2YXIgZnJvbSA9IGVzdGltYXRlQ29vcmRzKGNtLCByYW5nZS5mcm9tKSwgdG8gPSBlc3RpbWF0ZUNvb3JkcyhjbSwgcmFuZ2UudG8pO1xuICAgICAgdmFyIHNQb3MgPSBjYWxjdWxhdGVTY3JvbGxQb3MoY20sIE1hdGgubWluKGZyb20ubGVmdCwgdG8ubGVmdCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLm1pbihmcm9tLnRvcCwgdG8udG9wKSAtIHJhbmdlLm1hcmdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGgubWF4KGZyb20ucmlnaHQsIHRvLnJpZ2h0KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1hdGgubWF4KGZyb20uYm90dG9tLCB0by5ib3R0b20pICsgcmFuZ2UubWFyZ2luKTtcbiAgICAgIGNtLnNjcm9sbFRvKHNQb3Muc2Nyb2xsTGVmdCwgc1Bvcy5zY3JvbGxUb3ApO1xuICAgIH1cbiAgfVxuXG4gIC8vIEFQSSBVVElMSVRJRVNcblxuICAvLyBJbmRlbnQgdGhlIGdpdmVuIGxpbmUuIFRoZSBob3cgcGFyYW1ldGVyIGNhbiBiZSBcInNtYXJ0XCIsXG4gIC8vIFwiYWRkXCIvbnVsbCwgXCJzdWJ0cmFjdFwiLCBvciBcInByZXZcIi4gV2hlbiBhZ2dyZXNzaXZlIGlzIGZhbHNlXG4gIC8vICh0eXBpY2FsbHkgc2V0IHRvIHRydWUgZm9yIGZvcmNlZCBzaW5nbGUtbGluZSBpbmRlbnRzKSwgZW1wdHlcbiAgLy8gbGluZXMgYXJlIG5vdCBpbmRlbnRlZCwgYW5kIHBsYWNlcyB3aGVyZSB0aGUgbW9kZSByZXR1cm5zIFBhc3NcbiAgLy8gYXJlIGxlZnQgYWxvbmUuXG4gIGZ1bmN0aW9uIGluZGVudExpbmUoY20sIG4sIGhvdywgYWdncmVzc2l2ZSkge1xuICAgIHZhciBkb2MgPSBjbS5kb2MsIHN0YXRlO1xuICAgIGlmIChob3cgPT0gbnVsbCkgaG93ID0gXCJhZGRcIjtcbiAgICBpZiAoaG93ID09IFwic21hcnRcIikge1xuICAgICAgLy8gRmFsbCBiYWNrIHRvIFwicHJldlwiIHdoZW4gdGhlIG1vZGUgZG9lc24ndCBoYXZlIGFuIGluZGVudGF0aW9uXG4gICAgICAvLyBtZXRob2QuXG4gICAgICBpZiAoIWRvYy5tb2RlLmluZGVudCkgaG93ID0gXCJwcmV2XCI7XG4gICAgICBlbHNlIHN0YXRlID0gZ2V0U3RhdGVCZWZvcmUoY20sIG4pO1xuICAgIH1cblxuICAgIHZhciB0YWJTaXplID0gY20ub3B0aW9ucy50YWJTaXplO1xuICAgIHZhciBsaW5lID0gZ2V0TGluZShkb2MsIG4pLCBjdXJTcGFjZSA9IGNvdW50Q29sdW1uKGxpbmUudGV4dCwgbnVsbCwgdGFiU2l6ZSk7XG4gICAgaWYgKGxpbmUuc3RhdGVBZnRlcikgbGluZS5zdGF0ZUFmdGVyID0gbnVsbDtcbiAgICB2YXIgY3VyU3BhY2VTdHJpbmcgPSBsaW5lLnRleHQubWF0Y2goL15cXHMqLylbMF0sIGluZGVudGF0aW9uO1xuICAgIGlmICghYWdncmVzc2l2ZSAmJiAhL1xcUy8udGVzdChsaW5lLnRleHQpKSB7XG4gICAgICBpbmRlbnRhdGlvbiA9IDA7XG4gICAgICBob3cgPSBcIm5vdFwiO1xuICAgIH0gZWxzZSBpZiAoaG93ID09IFwic21hcnRcIikge1xuICAgICAgaW5kZW50YXRpb24gPSBkb2MubW9kZS5pbmRlbnQoc3RhdGUsIGxpbmUudGV4dC5zbGljZShjdXJTcGFjZVN0cmluZy5sZW5ndGgpLCBsaW5lLnRleHQpO1xuICAgICAgaWYgKGluZGVudGF0aW9uID09IFBhc3MgfHwgaW5kZW50YXRpb24gPiAxNTApIHtcbiAgICAgICAgaWYgKCFhZ2dyZXNzaXZlKSByZXR1cm47XG4gICAgICAgIGhvdyA9IFwicHJldlwiO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoaG93ID09IFwicHJldlwiKSB7XG4gICAgICBpZiAobiA+IGRvYy5maXJzdCkgaW5kZW50YXRpb24gPSBjb3VudENvbHVtbihnZXRMaW5lKGRvYywgbi0xKS50ZXh0LCBudWxsLCB0YWJTaXplKTtcbiAgICAgIGVsc2UgaW5kZW50YXRpb24gPSAwO1xuICAgIH0gZWxzZSBpZiAoaG93ID09IFwiYWRkXCIpIHtcbiAgICAgIGluZGVudGF0aW9uID0gY3VyU3BhY2UgKyBjbS5vcHRpb25zLmluZGVudFVuaXQ7XG4gICAgfSBlbHNlIGlmIChob3cgPT0gXCJzdWJ0cmFjdFwiKSB7XG4gICAgICBpbmRlbnRhdGlvbiA9IGN1clNwYWNlIC0gY20ub3B0aW9ucy5pbmRlbnRVbml0O1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIGhvdyA9PSBcIm51bWJlclwiKSB7XG4gICAgICBpbmRlbnRhdGlvbiA9IGN1clNwYWNlICsgaG93O1xuICAgIH1cbiAgICBpbmRlbnRhdGlvbiA9IE1hdGgubWF4KDAsIGluZGVudGF0aW9uKTtcblxuICAgIHZhciBpbmRlbnRTdHJpbmcgPSBcIlwiLCBwb3MgPSAwO1xuICAgIGlmIChjbS5vcHRpb25zLmluZGVudFdpdGhUYWJzKVxuICAgICAgZm9yICh2YXIgaSA9IE1hdGguZmxvb3IoaW5kZW50YXRpb24gLyB0YWJTaXplKTsgaTsgLS1pKSB7cG9zICs9IHRhYlNpemU7IGluZGVudFN0cmluZyArPSBcIlxcdFwiO31cbiAgICBpZiAocG9zIDwgaW5kZW50YXRpb24pIGluZGVudFN0cmluZyArPSBzcGFjZVN0cihpbmRlbnRhdGlvbiAtIHBvcyk7XG5cbiAgICBpZiAoaW5kZW50U3RyaW5nICE9IGN1clNwYWNlU3RyaW5nKSB7XG4gICAgICByZXBsYWNlUmFuZ2UoZG9jLCBpbmRlbnRTdHJpbmcsIFBvcyhuLCAwKSwgUG9zKG4sIGN1clNwYWNlU3RyaW5nLmxlbmd0aCksIFwiK2lucHV0XCIpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBFbnN1cmUgdGhhdCwgaWYgdGhlIGN1cnNvciB3YXMgaW4gdGhlIHdoaXRlc3BhY2UgYXQgdGhlIHN0YXJ0XG4gICAgICAvLyBvZiB0aGUgbGluZSwgaXQgaXMgbW92ZWQgdG8gdGhlIGVuZCBvZiB0aGF0IHNwYWNlLlxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkb2Muc2VsLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgcmFuZ2UgPSBkb2Muc2VsLnJhbmdlc1tpXTtcbiAgICAgICAgaWYgKHJhbmdlLmhlYWQubGluZSA9PSBuICYmIHJhbmdlLmhlYWQuY2ggPCBjdXJTcGFjZVN0cmluZy5sZW5ndGgpIHtcbiAgICAgICAgICB2YXIgcG9zID0gUG9zKG4sIGN1clNwYWNlU3RyaW5nLmxlbmd0aCk7XG4gICAgICAgICAgcmVwbGFjZU9uZVNlbGVjdGlvbihkb2MsIGksIG5ldyBSYW5nZShwb3MsIHBvcykpO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGxpbmUuc3RhdGVBZnRlciA9IG51bGw7XG4gIH1cblxuICAvLyBVdGlsaXR5IGZvciBhcHBseWluZyBhIGNoYW5nZSB0byBhIGxpbmUgYnkgaGFuZGxlIG9yIG51bWJlcixcbiAgLy8gcmV0dXJuaW5nIHRoZSBudW1iZXIgYW5kIG9wdGlvbmFsbHkgcmVnaXN0ZXJpbmcgdGhlIGxpbmUgYXNcbiAgLy8gY2hhbmdlZC5cbiAgZnVuY3Rpb24gY2hhbmdlTGluZShkb2MsIGhhbmRsZSwgY2hhbmdlVHlwZSwgb3ApIHtcbiAgICB2YXIgbm8gPSBoYW5kbGUsIGxpbmUgPSBoYW5kbGU7XG4gICAgaWYgKHR5cGVvZiBoYW5kbGUgPT0gXCJudW1iZXJcIikgbGluZSA9IGdldExpbmUoZG9jLCBjbGlwTGluZShkb2MsIGhhbmRsZSkpO1xuICAgIGVsc2Ugbm8gPSBsaW5lTm8oaGFuZGxlKTtcbiAgICBpZiAobm8gPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgaWYgKG9wKGxpbmUsIG5vKSAmJiBkb2MuY20pIHJlZ0xpbmVDaGFuZ2UoZG9jLmNtLCBubywgY2hhbmdlVHlwZSk7XG4gICAgcmV0dXJuIGxpbmU7XG4gIH1cblxuICAvLyBIZWxwZXIgZm9yIGRlbGV0aW5nIHRleHQgbmVhciB0aGUgc2VsZWN0aW9uKHMpLCB1c2VkIHRvIGltcGxlbWVudFxuICAvLyBiYWNrc3BhY2UsIGRlbGV0ZSwgYW5kIHNpbWlsYXIgZnVuY3Rpb25hbGl0eS5cbiAgZnVuY3Rpb24gZGVsZXRlTmVhclNlbGVjdGlvbihjbSwgY29tcHV0ZSkge1xuICAgIHZhciByYW5nZXMgPSBjbS5kb2Muc2VsLnJhbmdlcywga2lsbCA9IFtdO1xuICAgIC8vIEJ1aWxkIHVwIGEgc2V0IG9mIHJhbmdlcyB0byBraWxsIGZpcnN0LCBtZXJnaW5nIG92ZXJsYXBwaW5nXG4gICAgLy8gcmFuZ2VzLlxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgdG9LaWxsID0gY29tcHV0ZShyYW5nZXNbaV0pO1xuICAgICAgd2hpbGUgKGtpbGwubGVuZ3RoICYmIGNtcCh0b0tpbGwuZnJvbSwgbHN0KGtpbGwpLnRvKSA8PSAwKSB7XG4gICAgICAgIHZhciByZXBsYWNlZCA9IGtpbGwucG9wKCk7XG4gICAgICAgIGlmIChjbXAocmVwbGFjZWQuZnJvbSwgdG9LaWxsLmZyb20pIDwgMCkge1xuICAgICAgICAgIHRvS2lsbC5mcm9tID0gcmVwbGFjZWQuZnJvbTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAga2lsbC5wdXNoKHRvS2lsbCk7XG4gICAgfVxuICAgIC8vIE5leHQsIHJlbW92ZSB0aG9zZSBhY3R1YWwgcmFuZ2VzLlxuICAgIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkge1xuICAgICAgZm9yICh2YXIgaSA9IGtpbGwubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pXG4gICAgICAgIHJlcGxhY2VSYW5nZShjbS5kb2MsIFwiXCIsIGtpbGxbaV0uZnJvbSwga2lsbFtpXS50bywgXCIrZGVsZXRlXCIpO1xuICAgICAgZW5zdXJlQ3Vyc29yVmlzaWJsZShjbSk7XG4gICAgfSk7XG4gIH1cblxuICAvLyBVc2VkIGZvciBob3Jpem9udGFsIHJlbGF0aXZlIG1vdGlvbi4gRGlyIGlzIC0xIG9yIDEgKGxlZnQgb3JcbiAgLy8gcmlnaHQpLCB1bml0IGNhbiBiZSBcImNoYXJcIiwgXCJjb2x1bW5cIiAobGlrZSBjaGFyLCBidXQgZG9lc24ndFxuICAvLyBjcm9zcyBsaW5lIGJvdW5kYXJpZXMpLCBcIndvcmRcIiAoYWNyb3NzIG5leHQgd29yZCksIG9yIFwiZ3JvdXBcIiAodG9cbiAgLy8gdGhlIHN0YXJ0IG9mIG5leHQgZ3JvdXAgb2Ygd29yZCBvciBub24td29yZC1ub24td2hpdGVzcGFjZVxuICAvLyBjaGFycykuIFRoZSB2aXN1YWxseSBwYXJhbSBjb250cm9scyB3aGV0aGVyLCBpbiByaWdodC10by1sZWZ0XG4gIC8vIHRleHQsIGRpcmVjdGlvbiAxIG1lYW5zIHRvIG1vdmUgdG93YXJkcyB0aGUgbmV4dCBpbmRleCBpbiB0aGVcbiAgLy8gc3RyaW5nLCBvciB0b3dhcmRzIHRoZSBjaGFyYWN0ZXIgdG8gdGhlIHJpZ2h0IG9mIHRoZSBjdXJyZW50XG4gIC8vIHBvc2l0aW9uLiBUaGUgcmVzdWx0aW5nIHBvc2l0aW9uIHdpbGwgaGF2ZSBhIGhpdFNpZGU9dHJ1ZVxuICAvLyBwcm9wZXJ0eSBpZiBpdCByZWFjaGVkIHRoZSBlbmQgb2YgdGhlIGRvY3VtZW50LlxuICBmdW5jdGlvbiBmaW5kUG9zSChkb2MsIHBvcywgZGlyLCB1bml0LCB2aXN1YWxseSkge1xuICAgIHZhciBsaW5lID0gcG9zLmxpbmUsIGNoID0gcG9zLmNoLCBvcmlnRGlyID0gZGlyO1xuICAgIHZhciBsaW5lT2JqID0gZ2V0TGluZShkb2MsIGxpbmUpO1xuICAgIHZhciBwb3NzaWJsZSA9IHRydWU7XG4gICAgZnVuY3Rpb24gZmluZE5leHRMaW5lKCkge1xuICAgICAgdmFyIGwgPSBsaW5lICsgZGlyO1xuICAgICAgaWYgKGwgPCBkb2MuZmlyc3QgfHwgbCA+PSBkb2MuZmlyc3QgKyBkb2Muc2l6ZSkgcmV0dXJuIChwb3NzaWJsZSA9IGZhbHNlKTtcbiAgICAgIGxpbmUgPSBsO1xuICAgICAgcmV0dXJuIGxpbmVPYmogPSBnZXRMaW5lKGRvYywgbCk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIG1vdmVPbmNlKGJvdW5kVG9MaW5lKSB7XG4gICAgICB2YXIgbmV4dCA9ICh2aXN1YWxseSA/IG1vdmVWaXN1YWxseSA6IG1vdmVMb2dpY2FsbHkpKGxpbmVPYmosIGNoLCBkaXIsIHRydWUpO1xuICAgICAgaWYgKG5leHQgPT0gbnVsbCkge1xuICAgICAgICBpZiAoIWJvdW5kVG9MaW5lICYmIGZpbmROZXh0TGluZSgpKSB7XG4gICAgICAgICAgaWYgKHZpc3VhbGx5KSBjaCA9IChkaXIgPCAwID8gbGluZVJpZ2h0IDogbGluZUxlZnQpKGxpbmVPYmopO1xuICAgICAgICAgIGVsc2UgY2ggPSBkaXIgPCAwID8gbGluZU9iai50ZXh0Lmxlbmd0aCA6IDA7XG4gICAgICAgIH0gZWxzZSByZXR1cm4gKHBvc3NpYmxlID0gZmFsc2UpO1xuICAgICAgfSBlbHNlIGNoID0gbmV4dDtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIGlmICh1bml0ID09IFwiY2hhclwiKSBtb3ZlT25jZSgpO1xuICAgIGVsc2UgaWYgKHVuaXQgPT0gXCJjb2x1bW5cIikgbW92ZU9uY2UodHJ1ZSk7XG4gICAgZWxzZSBpZiAodW5pdCA9PSBcIndvcmRcIiB8fCB1bml0ID09IFwiZ3JvdXBcIikge1xuICAgICAgdmFyIHNhd1R5cGUgPSBudWxsLCBncm91cCA9IHVuaXQgPT0gXCJncm91cFwiO1xuICAgICAgdmFyIGhlbHBlciA9IGRvYy5jbSAmJiBkb2MuY20uZ2V0SGVscGVyKHBvcywgXCJ3b3JkQ2hhcnNcIik7XG4gICAgICBmb3IgKHZhciBmaXJzdCA9IHRydWU7OyBmaXJzdCA9IGZhbHNlKSB7XG4gICAgICAgIGlmIChkaXIgPCAwICYmICFtb3ZlT25jZSghZmlyc3QpKSBicmVhaztcbiAgICAgICAgdmFyIGN1ciA9IGxpbmVPYmoudGV4dC5jaGFyQXQoY2gpIHx8IFwiXFxuXCI7XG4gICAgICAgIHZhciB0eXBlID0gaXNXb3JkQ2hhcihjdXIsIGhlbHBlcikgPyBcIndcIlxuICAgICAgICAgIDogZ3JvdXAgJiYgY3VyID09IFwiXFxuXCIgPyBcIm5cIlxuICAgICAgICAgIDogIWdyb3VwIHx8IC9cXHMvLnRlc3QoY3VyKSA/IG51bGxcbiAgICAgICAgICA6IFwicFwiO1xuICAgICAgICBpZiAoZ3JvdXAgJiYgIWZpcnN0ICYmICF0eXBlKSB0eXBlID0gXCJzXCI7XG4gICAgICAgIGlmIChzYXdUeXBlICYmIHNhd1R5cGUgIT0gdHlwZSkge1xuICAgICAgICAgIGlmIChkaXIgPCAwKSB7ZGlyID0gMTsgbW92ZU9uY2UoKTt9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAodHlwZSkgc2F3VHlwZSA9IHR5cGU7XG4gICAgICAgIGlmIChkaXIgPiAwICYmICFtb3ZlT25jZSghZmlyc3QpKSBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgdmFyIHJlc3VsdCA9IHNraXBBdG9taWMoZG9jLCBQb3MobGluZSwgY2gpLCBvcmlnRGlyLCB0cnVlKTtcbiAgICBpZiAoIXBvc3NpYmxlKSByZXN1bHQuaGl0U2lkZSA9IHRydWU7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8vIEZvciByZWxhdGl2ZSB2ZXJ0aWNhbCBtb3ZlbWVudC4gRGlyIG1heSBiZSAtMSBvciAxLiBVbml0IGNhbiBiZVxuICAvLyBcInBhZ2VcIiBvciBcImxpbmVcIi4gVGhlIHJlc3VsdGluZyBwb3NpdGlvbiB3aWxsIGhhdmUgYSBoaXRTaWRlPXRydWVcbiAgLy8gcHJvcGVydHkgaWYgaXQgcmVhY2hlZCB0aGUgZW5kIG9mIHRoZSBkb2N1bWVudC5cbiAgZnVuY3Rpb24gZmluZFBvc1YoY20sIHBvcywgZGlyLCB1bml0KSB7XG4gICAgdmFyIGRvYyA9IGNtLmRvYywgeCA9IHBvcy5sZWZ0LCB5O1xuICAgIGlmICh1bml0ID09IFwicGFnZVwiKSB7XG4gICAgICB2YXIgcGFnZVNpemUgPSBNYXRoLm1pbihjbS5kaXNwbGF5LndyYXBwZXIuY2xpZW50SGVpZ2h0LCB3aW5kb3cuaW5uZXJIZWlnaHQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudEhlaWdodCk7XG4gICAgICB5ID0gcG9zLnRvcCArIGRpciAqIChwYWdlU2l6ZSAtIChkaXIgPCAwID8gMS41IDogLjUpICogdGV4dEhlaWdodChjbS5kaXNwbGF5KSk7XG4gICAgfSBlbHNlIGlmICh1bml0ID09IFwibGluZVwiKSB7XG4gICAgICB5ID0gZGlyID4gMCA/IHBvcy5ib3R0b20gKyAzIDogcG9zLnRvcCAtIDM7XG4gICAgfVxuICAgIGZvciAoOzspIHtcbiAgICAgIHZhciB0YXJnZXQgPSBjb29yZHNDaGFyKGNtLCB4LCB5KTtcbiAgICAgIGlmICghdGFyZ2V0Lm91dHNpZGUpIGJyZWFrO1xuICAgICAgaWYgKGRpciA8IDAgPyB5IDw9IDAgOiB5ID49IGRvYy5oZWlnaHQpIHsgdGFyZ2V0LmhpdFNpZGUgPSB0cnVlOyBicmVhazsgfVxuICAgICAgeSArPSBkaXIgKiA1O1xuICAgIH1cbiAgICByZXR1cm4gdGFyZ2V0O1xuICB9XG5cbiAgLy8gRURJVE9SIE1FVEhPRFNcblxuICAvLyBUaGUgcHVibGljbHkgdmlzaWJsZSBBUEkuIE5vdGUgdGhhdCBtZXRob2RPcChmKSBtZWFuc1xuICAvLyAnd3JhcCBmIGluIGFuIG9wZXJhdGlvbiwgcGVyZm9ybWVkIG9uIGl0cyBgdGhpc2AgcGFyYW1ldGVyJy5cblxuICAvLyBUaGlzIGlzIG5vdCB0aGUgY29tcGxldGUgc2V0IG9mIGVkaXRvciBtZXRob2RzLiBNb3N0IG9mIHRoZVxuICAvLyBtZXRob2RzIGRlZmluZWQgb24gdGhlIERvYyB0eXBlIGFyZSBhbHNvIGluamVjdGVkIGludG9cbiAgLy8gQ29kZU1pcnJvci5wcm90b3R5cGUsIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSBhbmRcbiAgLy8gY29udmVuaWVuY2UuXG5cbiAgQ29kZU1pcnJvci5wcm90b3R5cGUgPSB7XG4gICAgY29uc3RydWN0b3I6IENvZGVNaXJyb3IsXG4gICAgZm9jdXM6IGZ1bmN0aW9uKCl7d2luZG93LmZvY3VzKCk7IGZvY3VzSW5wdXQodGhpcyk7IGZhc3RQb2xsKHRoaXMpO30sXG5cbiAgICBzZXRPcHRpb246IGZ1bmN0aW9uKG9wdGlvbiwgdmFsdWUpIHtcbiAgICAgIHZhciBvcHRpb25zID0gdGhpcy5vcHRpb25zLCBvbGQgPSBvcHRpb25zW29wdGlvbl07XG4gICAgICBpZiAob3B0aW9uc1tvcHRpb25dID09IHZhbHVlICYmIG9wdGlvbiAhPSBcIm1vZGVcIikgcmV0dXJuO1xuICAgICAgb3B0aW9uc1tvcHRpb25dID0gdmFsdWU7XG4gICAgICBpZiAob3B0aW9uSGFuZGxlcnMuaGFzT3duUHJvcGVydHkob3B0aW9uKSlcbiAgICAgICAgb3BlcmF0aW9uKHRoaXMsIG9wdGlvbkhhbmRsZXJzW29wdGlvbl0pKHRoaXMsIHZhbHVlLCBvbGQpO1xuICAgIH0sXG5cbiAgICBnZXRPcHRpb246IGZ1bmN0aW9uKG9wdGlvbikge3JldHVybiB0aGlzLm9wdGlvbnNbb3B0aW9uXTt9LFxuICAgIGdldERvYzogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMuZG9jO30sXG5cbiAgICBhZGRLZXlNYXA6IGZ1bmN0aW9uKG1hcCwgYm90dG9tKSB7XG4gICAgICB0aGlzLnN0YXRlLmtleU1hcHNbYm90dG9tID8gXCJwdXNoXCIgOiBcInVuc2hpZnRcIl0oZ2V0S2V5TWFwKG1hcCkpO1xuICAgIH0sXG4gICAgcmVtb3ZlS2V5TWFwOiBmdW5jdGlvbihtYXApIHtcbiAgICAgIHZhciBtYXBzID0gdGhpcy5zdGF0ZS5rZXlNYXBzO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXBzLmxlbmd0aDsgKytpKVxuICAgICAgICBpZiAobWFwc1tpXSA9PSBtYXAgfHwgbWFwc1tpXS5uYW1lID09IG1hcCkge1xuICAgICAgICAgIG1hcHMuc3BsaWNlKGksIDEpO1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgfSxcblxuICAgIGFkZE92ZXJsYXk6IG1ldGhvZE9wKGZ1bmN0aW9uKHNwZWMsIG9wdGlvbnMpIHtcbiAgICAgIHZhciBtb2RlID0gc3BlYy50b2tlbiA/IHNwZWMgOiBDb2RlTWlycm9yLmdldE1vZGUodGhpcy5vcHRpb25zLCBzcGVjKTtcbiAgICAgIGlmIChtb2RlLnN0YXJ0U3RhdGUpIHRocm93IG5ldyBFcnJvcihcIk92ZXJsYXlzIG1heSBub3QgYmUgc3RhdGVmdWwuXCIpO1xuICAgICAgdGhpcy5zdGF0ZS5vdmVybGF5cy5wdXNoKHttb2RlOiBtb2RlLCBtb2RlU3BlYzogc3BlYywgb3BhcXVlOiBvcHRpb25zICYmIG9wdGlvbnMub3BhcXVlfSk7XG4gICAgICB0aGlzLnN0YXRlLm1vZGVHZW4rKztcbiAgICAgIHJlZ0NoYW5nZSh0aGlzKTtcbiAgICB9KSxcbiAgICByZW1vdmVPdmVybGF5OiBtZXRob2RPcChmdW5jdGlvbihzcGVjKSB7XG4gICAgICB2YXIgb3ZlcmxheXMgPSB0aGlzLnN0YXRlLm92ZXJsYXlzO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdmVybGF5cy5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgY3VyID0gb3ZlcmxheXNbaV0ubW9kZVNwZWM7XG4gICAgICAgIGlmIChjdXIgPT0gc3BlYyB8fCB0eXBlb2Ygc3BlYyA9PSBcInN0cmluZ1wiICYmIGN1ci5uYW1lID09IHNwZWMpIHtcbiAgICAgICAgICBvdmVybGF5cy5zcGxpY2UoaSwgMSk7XG4gICAgICAgICAgdGhpcy5zdGF0ZS5tb2RlR2VuKys7XG4gICAgICAgICAgcmVnQ2hhbmdlKHRoaXMpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0pLFxuXG4gICAgaW5kZW50TGluZTogbWV0aG9kT3AoZnVuY3Rpb24obiwgZGlyLCBhZ2dyZXNzaXZlKSB7XG4gICAgICBpZiAodHlwZW9mIGRpciAhPSBcInN0cmluZ1wiICYmIHR5cGVvZiBkaXIgIT0gXCJudW1iZXJcIikge1xuICAgICAgICBpZiAoZGlyID09IG51bGwpIGRpciA9IHRoaXMub3B0aW9ucy5zbWFydEluZGVudCA/IFwic21hcnRcIiA6IFwicHJldlwiO1xuICAgICAgICBlbHNlIGRpciA9IGRpciA/IFwiYWRkXCIgOiBcInN1YnRyYWN0XCI7XG4gICAgICB9XG4gICAgICBpZiAoaXNMaW5lKHRoaXMuZG9jLCBuKSkgaW5kZW50TGluZSh0aGlzLCBuLCBkaXIsIGFnZ3Jlc3NpdmUpO1xuICAgIH0pLFxuICAgIGluZGVudFNlbGVjdGlvbjogbWV0aG9kT3AoZnVuY3Rpb24oaG93KSB7XG4gICAgICB2YXIgcmFuZ2VzID0gdGhpcy5kb2Muc2VsLnJhbmdlcywgZW5kID0gLTE7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgcmFuZ2UgPSByYW5nZXNbaV07XG4gICAgICAgIGlmICghcmFuZ2UuZW1wdHkoKSkge1xuICAgICAgICAgIHZhciBmcm9tID0gcmFuZ2UuZnJvbSgpLCB0byA9IHJhbmdlLnRvKCk7XG4gICAgICAgICAgdmFyIHN0YXJ0ID0gTWF0aC5tYXgoZW5kLCBmcm9tLmxpbmUpO1xuICAgICAgICAgIGVuZCA9IE1hdGgubWluKHRoaXMubGFzdExpbmUoKSwgdG8ubGluZSAtICh0by5jaCA/IDAgOiAxKSkgKyAxO1xuICAgICAgICAgIGZvciAodmFyIGogPSBzdGFydDsgaiA8IGVuZDsgKytqKVxuICAgICAgICAgICAgaW5kZW50TGluZSh0aGlzLCBqLCBob3cpO1xuICAgICAgICAgIHZhciBuZXdSYW5nZXMgPSB0aGlzLmRvYy5zZWwucmFuZ2VzO1xuICAgICAgICAgIGlmIChmcm9tLmNoID09IDAgJiYgcmFuZ2VzLmxlbmd0aCA9PSBuZXdSYW5nZXMubGVuZ3RoICYmIG5ld1Jhbmdlc1tpXS5mcm9tKCkuY2ggPiAwKVxuICAgICAgICAgICAgcmVwbGFjZU9uZVNlbGVjdGlvbih0aGlzLmRvYywgaSwgbmV3IFJhbmdlKGZyb20sIG5ld1Jhbmdlc1tpXS50bygpKSwgc2VsX2RvbnRTY3JvbGwpO1xuICAgICAgICB9IGVsc2UgaWYgKHJhbmdlLmhlYWQubGluZSA+IGVuZCkge1xuICAgICAgICAgIGluZGVudExpbmUodGhpcywgcmFuZ2UuaGVhZC5saW5lLCBob3csIHRydWUpO1xuICAgICAgICAgIGVuZCA9IHJhbmdlLmhlYWQubGluZTtcbiAgICAgICAgICBpZiAoaSA9PSB0aGlzLmRvYy5zZWwucHJpbUluZGV4KSBlbnN1cmVDdXJzb3JWaXNpYmxlKHRoaXMpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSksXG5cbiAgICAvLyBGZXRjaCB0aGUgcGFyc2VyIHRva2VuIGZvciBhIGdpdmVuIGNoYXJhY3Rlci4gVXNlZnVsIGZvciBoYWNrc1xuICAgIC8vIHRoYXQgd2FudCB0byBpbnNwZWN0IHRoZSBtb2RlIHN0YXRlIChzYXksIGZvciBjb21wbGV0aW9uKS5cbiAgICBnZXRUb2tlbkF0OiBmdW5jdGlvbihwb3MsIHByZWNpc2UpIHtcbiAgICAgIHJldHVybiB0YWtlVG9rZW4odGhpcywgcG9zLCBwcmVjaXNlKTtcbiAgICB9LFxuXG4gICAgZ2V0TGluZVRva2VuczogZnVuY3Rpb24obGluZSwgcHJlY2lzZSkge1xuICAgICAgcmV0dXJuIHRha2VUb2tlbih0aGlzLCBQb3MobGluZSksIHByZWNpc2UsIHRydWUpO1xuICAgIH0sXG5cbiAgICBnZXRUb2tlblR5cGVBdDogZnVuY3Rpb24ocG9zKSB7XG4gICAgICBwb3MgPSBjbGlwUG9zKHRoaXMuZG9jLCBwb3MpO1xuICAgICAgdmFyIHN0eWxlcyA9IGdldExpbmVTdHlsZXModGhpcywgZ2V0TGluZSh0aGlzLmRvYywgcG9zLmxpbmUpKTtcbiAgICAgIHZhciBiZWZvcmUgPSAwLCBhZnRlciA9IChzdHlsZXMubGVuZ3RoIC0gMSkgLyAyLCBjaCA9IHBvcy5jaDtcbiAgICAgIHZhciB0eXBlO1xuICAgICAgaWYgKGNoID09IDApIHR5cGUgPSBzdHlsZXNbMl07XG4gICAgICBlbHNlIGZvciAoOzspIHtcbiAgICAgICAgdmFyIG1pZCA9IChiZWZvcmUgKyBhZnRlcikgPj4gMTtcbiAgICAgICAgaWYgKChtaWQgPyBzdHlsZXNbbWlkICogMiAtIDFdIDogMCkgPj0gY2gpIGFmdGVyID0gbWlkO1xuICAgICAgICBlbHNlIGlmIChzdHlsZXNbbWlkICogMiArIDFdIDwgY2gpIGJlZm9yZSA9IG1pZCArIDE7XG4gICAgICAgIGVsc2UgeyB0eXBlID0gc3R5bGVzW21pZCAqIDIgKyAyXTsgYnJlYWs7IH1cbiAgICAgIH1cbiAgICAgIHZhciBjdXQgPSB0eXBlID8gdHlwZS5pbmRleE9mKFwiY20tb3ZlcmxheSBcIikgOiAtMTtcbiAgICAgIHJldHVybiBjdXQgPCAwID8gdHlwZSA6IGN1dCA9PSAwID8gbnVsbCA6IHR5cGUuc2xpY2UoMCwgY3V0IC0gMSk7XG4gICAgfSxcblxuICAgIGdldE1vZGVBdDogZnVuY3Rpb24ocG9zKSB7XG4gICAgICB2YXIgbW9kZSA9IHRoaXMuZG9jLm1vZGU7XG4gICAgICBpZiAoIW1vZGUuaW5uZXJNb2RlKSByZXR1cm4gbW9kZTtcbiAgICAgIHJldHVybiBDb2RlTWlycm9yLmlubmVyTW9kZShtb2RlLCB0aGlzLmdldFRva2VuQXQocG9zKS5zdGF0ZSkubW9kZTtcbiAgICB9LFxuXG4gICAgZ2V0SGVscGVyOiBmdW5jdGlvbihwb3MsIHR5cGUpIHtcbiAgICAgIHJldHVybiB0aGlzLmdldEhlbHBlcnMocG9zLCB0eXBlKVswXTtcbiAgICB9LFxuXG4gICAgZ2V0SGVscGVyczogZnVuY3Rpb24ocG9zLCB0eXBlKSB7XG4gICAgICB2YXIgZm91bmQgPSBbXTtcbiAgICAgIGlmICghaGVscGVycy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkgcmV0dXJuIGhlbHBlcnM7XG4gICAgICB2YXIgaGVscCA9IGhlbHBlcnNbdHlwZV0sIG1vZGUgPSB0aGlzLmdldE1vZGVBdChwb3MpO1xuICAgICAgaWYgKHR5cGVvZiBtb2RlW3R5cGVdID09IFwic3RyaW5nXCIpIHtcbiAgICAgICAgaWYgKGhlbHBbbW9kZVt0eXBlXV0pIGZvdW5kLnB1c2goaGVscFttb2RlW3R5cGVdXSk7XG4gICAgICB9IGVsc2UgaWYgKG1vZGVbdHlwZV0pIHtcbiAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtb2RlW3R5cGVdLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIHZhbCA9IGhlbHBbbW9kZVt0eXBlXVtpXV07XG4gICAgICAgICAgaWYgKHZhbCkgZm91bmQucHVzaCh2YWwpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKG1vZGUuaGVscGVyVHlwZSAmJiBoZWxwW21vZGUuaGVscGVyVHlwZV0pIHtcbiAgICAgICAgZm91bmQucHVzaChoZWxwW21vZGUuaGVscGVyVHlwZV0pO1xuICAgICAgfSBlbHNlIGlmIChoZWxwW21vZGUubmFtZV0pIHtcbiAgICAgICAgZm91bmQucHVzaChoZWxwW21vZGUubmFtZV0pO1xuICAgICAgfVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBoZWxwLl9nbG9iYWwubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIGN1ciA9IGhlbHAuX2dsb2JhbFtpXTtcbiAgICAgICAgaWYgKGN1ci5wcmVkKG1vZGUsIHRoaXMpICYmIGluZGV4T2YoZm91bmQsIGN1ci52YWwpID09IC0xKVxuICAgICAgICAgIGZvdW5kLnB1c2goY3VyLnZhbCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gZm91bmQ7XG4gICAgfSxcblxuICAgIGdldFN0YXRlQWZ0ZXI6IGZ1bmN0aW9uKGxpbmUsIHByZWNpc2UpIHtcbiAgICAgIHZhciBkb2MgPSB0aGlzLmRvYztcbiAgICAgIGxpbmUgPSBjbGlwTGluZShkb2MsIGxpbmUgPT0gbnVsbCA/IGRvYy5maXJzdCArIGRvYy5zaXplIC0gMTogbGluZSk7XG4gICAgICByZXR1cm4gZ2V0U3RhdGVCZWZvcmUodGhpcywgbGluZSArIDEsIHByZWNpc2UpO1xuICAgIH0sXG5cbiAgICBjdXJzb3JDb29yZHM6IGZ1bmN0aW9uKHN0YXJ0LCBtb2RlKSB7XG4gICAgICB2YXIgcG9zLCByYW5nZSA9IHRoaXMuZG9jLnNlbC5wcmltYXJ5KCk7XG4gICAgICBpZiAoc3RhcnQgPT0gbnVsbCkgcG9zID0gcmFuZ2UuaGVhZDtcbiAgICAgIGVsc2UgaWYgKHR5cGVvZiBzdGFydCA9PSBcIm9iamVjdFwiKSBwb3MgPSBjbGlwUG9zKHRoaXMuZG9jLCBzdGFydCk7XG4gICAgICBlbHNlIHBvcyA9IHN0YXJ0ID8gcmFuZ2UuZnJvbSgpIDogcmFuZ2UudG8oKTtcbiAgICAgIHJldHVybiBjdXJzb3JDb29yZHModGhpcywgcG9zLCBtb2RlIHx8IFwicGFnZVwiKTtcbiAgICB9LFxuXG4gICAgY2hhckNvb3JkczogZnVuY3Rpb24ocG9zLCBtb2RlKSB7XG4gICAgICByZXR1cm4gY2hhckNvb3Jkcyh0aGlzLCBjbGlwUG9zKHRoaXMuZG9jLCBwb3MpLCBtb2RlIHx8IFwicGFnZVwiKTtcbiAgICB9LFxuXG4gICAgY29vcmRzQ2hhcjogZnVuY3Rpb24oY29vcmRzLCBtb2RlKSB7XG4gICAgICBjb29yZHMgPSBmcm9tQ29vcmRTeXN0ZW0odGhpcywgY29vcmRzLCBtb2RlIHx8IFwicGFnZVwiKTtcbiAgICAgIHJldHVybiBjb29yZHNDaGFyKHRoaXMsIGNvb3Jkcy5sZWZ0LCBjb29yZHMudG9wKTtcbiAgICB9LFxuXG4gICAgbGluZUF0SGVpZ2h0OiBmdW5jdGlvbihoZWlnaHQsIG1vZGUpIHtcbiAgICAgIGhlaWdodCA9IGZyb21Db29yZFN5c3RlbSh0aGlzLCB7dG9wOiBoZWlnaHQsIGxlZnQ6IDB9LCBtb2RlIHx8IFwicGFnZVwiKS50b3A7XG4gICAgICByZXR1cm4gbGluZUF0SGVpZ2h0KHRoaXMuZG9jLCBoZWlnaHQgKyB0aGlzLmRpc3BsYXkudmlld09mZnNldCk7XG4gICAgfSxcbiAgICBoZWlnaHRBdExpbmU6IGZ1bmN0aW9uKGxpbmUsIG1vZGUpIHtcbiAgICAgIHZhciBlbmQgPSBmYWxzZSwgbGFzdCA9IHRoaXMuZG9jLmZpcnN0ICsgdGhpcy5kb2Muc2l6ZSAtIDE7XG4gICAgICBpZiAobGluZSA8IHRoaXMuZG9jLmZpcnN0KSBsaW5lID0gdGhpcy5kb2MuZmlyc3Q7XG4gICAgICBlbHNlIGlmIChsaW5lID4gbGFzdCkgeyBsaW5lID0gbGFzdDsgZW5kID0gdHJ1ZTsgfVxuICAgICAgdmFyIGxpbmVPYmogPSBnZXRMaW5lKHRoaXMuZG9jLCBsaW5lKTtcbiAgICAgIHJldHVybiBpbnRvQ29vcmRTeXN0ZW0odGhpcywgbGluZU9iaiwge3RvcDogMCwgbGVmdDogMH0sIG1vZGUgfHwgXCJwYWdlXCIpLnRvcCArXG4gICAgICAgIChlbmQgPyB0aGlzLmRvYy5oZWlnaHQgLSBoZWlnaHRBdExpbmUobGluZU9iaikgOiAwKTtcbiAgICB9LFxuXG4gICAgZGVmYXVsdFRleHRIZWlnaHQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGV4dEhlaWdodCh0aGlzLmRpc3BsYXkpOyB9LFxuICAgIGRlZmF1bHRDaGFyV2lkdGg6IGZ1bmN0aW9uKCkgeyByZXR1cm4gY2hhcldpZHRoKHRoaXMuZGlzcGxheSk7IH0sXG5cbiAgICBzZXRHdXR0ZXJNYXJrZXI6IG1ldGhvZE9wKGZ1bmN0aW9uKGxpbmUsIGd1dHRlcklELCB2YWx1ZSkge1xuICAgICAgcmV0dXJuIGNoYW5nZUxpbmUodGhpcy5kb2MsIGxpbmUsIFwiZ3V0dGVyXCIsIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgdmFyIG1hcmtlcnMgPSBsaW5lLmd1dHRlck1hcmtlcnMgfHwgKGxpbmUuZ3V0dGVyTWFya2VycyA9IHt9KTtcbiAgICAgICAgbWFya2Vyc1tndXR0ZXJJRF0gPSB2YWx1ZTtcbiAgICAgICAgaWYgKCF2YWx1ZSAmJiBpc0VtcHR5KG1hcmtlcnMpKSBsaW5lLmd1dHRlck1hcmtlcnMgPSBudWxsO1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0pO1xuICAgIH0pLFxuXG4gICAgY2xlYXJHdXR0ZXI6IG1ldGhvZE9wKGZ1bmN0aW9uKGd1dHRlcklEKSB7XG4gICAgICB2YXIgY20gPSB0aGlzLCBkb2MgPSBjbS5kb2MsIGkgPSBkb2MuZmlyc3Q7XG4gICAgICBkb2MuaXRlcihmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIGlmIChsaW5lLmd1dHRlck1hcmtlcnMgJiYgbGluZS5ndXR0ZXJNYXJrZXJzW2d1dHRlcklEXSkge1xuICAgICAgICAgIGxpbmUuZ3V0dGVyTWFya2Vyc1tndXR0ZXJJRF0gPSBudWxsO1xuICAgICAgICAgIHJlZ0xpbmVDaGFuZ2UoY20sIGksIFwiZ3V0dGVyXCIpO1xuICAgICAgICAgIGlmIChpc0VtcHR5KGxpbmUuZ3V0dGVyTWFya2VycykpIGxpbmUuZ3V0dGVyTWFya2VycyA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgKytpO1xuICAgICAgfSk7XG4gICAgfSksXG5cbiAgICBhZGRMaW5lV2lkZ2V0OiBtZXRob2RPcChmdW5jdGlvbihoYW5kbGUsIG5vZGUsIG9wdGlvbnMpIHtcbiAgICAgIHJldHVybiBhZGRMaW5lV2lkZ2V0KHRoaXMsIGhhbmRsZSwgbm9kZSwgb3B0aW9ucyk7XG4gICAgfSksXG5cbiAgICByZW1vdmVMaW5lV2lkZ2V0OiBmdW5jdGlvbih3aWRnZXQpIHsgd2lkZ2V0LmNsZWFyKCk7IH0sXG5cbiAgICBsaW5lSW5mbzogZnVuY3Rpb24obGluZSkge1xuICAgICAgaWYgKHR5cGVvZiBsaW5lID09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgaWYgKCFpc0xpbmUodGhpcy5kb2MsIGxpbmUpKSByZXR1cm4gbnVsbDtcbiAgICAgICAgdmFyIG4gPSBsaW5lO1xuICAgICAgICBsaW5lID0gZ2V0TGluZSh0aGlzLmRvYywgbGluZSk7XG4gICAgICAgIGlmICghbGluZSkgcmV0dXJuIG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgbiA9IGxpbmVObyhsaW5lKTtcbiAgICAgICAgaWYgKG4gPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgICByZXR1cm4ge2xpbmU6IG4sIGhhbmRsZTogbGluZSwgdGV4dDogbGluZS50ZXh0LCBndXR0ZXJNYXJrZXJzOiBsaW5lLmd1dHRlck1hcmtlcnMsXG4gICAgICAgICAgICAgIHRleHRDbGFzczogbGluZS50ZXh0Q2xhc3MsIGJnQ2xhc3M6IGxpbmUuYmdDbGFzcywgd3JhcENsYXNzOiBsaW5lLndyYXBDbGFzcyxcbiAgICAgICAgICAgICAgd2lkZ2V0czogbGluZS53aWRnZXRzfTtcbiAgICB9LFxuXG4gICAgZ2V0Vmlld3BvcnQ6IGZ1bmN0aW9uKCkgeyByZXR1cm4ge2Zyb206IHRoaXMuZGlzcGxheS52aWV3RnJvbSwgdG86IHRoaXMuZGlzcGxheS52aWV3VG99O30sXG5cbiAgICBhZGRXaWRnZXQ6IGZ1bmN0aW9uKHBvcywgbm9kZSwgc2Nyb2xsLCB2ZXJ0LCBob3Jpeikge1xuICAgICAgdmFyIGRpc3BsYXkgPSB0aGlzLmRpc3BsYXk7XG4gICAgICBwb3MgPSBjdXJzb3JDb29yZHModGhpcywgY2xpcFBvcyh0aGlzLmRvYywgcG9zKSk7XG4gICAgICB2YXIgdG9wID0gcG9zLmJvdHRvbSwgbGVmdCA9IHBvcy5sZWZ0O1xuICAgICAgbm9kZS5zdHlsZS5wb3NpdGlvbiA9IFwiYWJzb2x1dGVcIjtcbiAgICAgIG5vZGUuc2V0QXR0cmlidXRlKFwiY20taWdub3JlLWV2ZW50c1wiLCBcInRydWVcIik7XG4gICAgICBkaXNwbGF5LnNpemVyLmFwcGVuZENoaWxkKG5vZGUpO1xuICAgICAgaWYgKHZlcnQgPT0gXCJvdmVyXCIpIHtcbiAgICAgICAgdG9wID0gcG9zLnRvcDtcbiAgICAgIH0gZWxzZSBpZiAodmVydCA9PSBcImFib3ZlXCIgfHwgdmVydCA9PSBcIm5lYXJcIikge1xuICAgICAgICB2YXIgdnNwYWNlID0gTWF0aC5tYXgoZGlzcGxheS53cmFwcGVyLmNsaWVudEhlaWdodCwgdGhpcy5kb2MuaGVpZ2h0KSxcbiAgICAgICAgaHNwYWNlID0gTWF0aC5tYXgoZGlzcGxheS5zaXplci5jbGllbnRXaWR0aCwgZGlzcGxheS5saW5lU3BhY2UuY2xpZW50V2lkdGgpO1xuICAgICAgICAvLyBEZWZhdWx0IHRvIHBvc2l0aW9uaW5nIGFib3ZlIChpZiBzcGVjaWZpZWQgYW5kIHBvc3NpYmxlKTsgb3RoZXJ3aXNlIGRlZmF1bHQgdG8gcG9zaXRpb25pbmcgYmVsb3dcbiAgICAgICAgaWYgKCh2ZXJ0ID09ICdhYm92ZScgfHwgcG9zLmJvdHRvbSArIG5vZGUub2Zmc2V0SGVpZ2h0ID4gdnNwYWNlKSAmJiBwb3MudG9wID4gbm9kZS5vZmZzZXRIZWlnaHQpXG4gICAgICAgICAgdG9wID0gcG9zLnRvcCAtIG5vZGUub2Zmc2V0SGVpZ2h0O1xuICAgICAgICBlbHNlIGlmIChwb3MuYm90dG9tICsgbm9kZS5vZmZzZXRIZWlnaHQgPD0gdnNwYWNlKVxuICAgICAgICAgIHRvcCA9IHBvcy5ib3R0b207XG4gICAgICAgIGlmIChsZWZ0ICsgbm9kZS5vZmZzZXRXaWR0aCA+IGhzcGFjZSlcbiAgICAgICAgICBsZWZ0ID0gaHNwYWNlIC0gbm9kZS5vZmZzZXRXaWR0aDtcbiAgICAgIH1cbiAgICAgIG5vZGUuc3R5bGUudG9wID0gdG9wICsgXCJweFwiO1xuICAgICAgbm9kZS5zdHlsZS5sZWZ0ID0gbm9kZS5zdHlsZS5yaWdodCA9IFwiXCI7XG4gICAgICBpZiAoaG9yaXogPT0gXCJyaWdodFwiKSB7XG4gICAgICAgIGxlZnQgPSBkaXNwbGF5LnNpemVyLmNsaWVudFdpZHRoIC0gbm9kZS5vZmZzZXRXaWR0aDtcbiAgICAgICAgbm9kZS5zdHlsZS5yaWdodCA9IFwiMHB4XCI7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaG9yaXogPT0gXCJsZWZ0XCIpIGxlZnQgPSAwO1xuICAgICAgICBlbHNlIGlmIChob3JpeiA9PSBcIm1pZGRsZVwiKSBsZWZ0ID0gKGRpc3BsYXkuc2l6ZXIuY2xpZW50V2lkdGggLSBub2RlLm9mZnNldFdpZHRoKSAvIDI7XG4gICAgICAgIG5vZGUuc3R5bGUubGVmdCA9IGxlZnQgKyBcInB4XCI7XG4gICAgICB9XG4gICAgICBpZiAoc2Nyb2xsKVxuICAgICAgICBzY3JvbGxJbnRvVmlldyh0aGlzLCBsZWZ0LCB0b3AsIGxlZnQgKyBub2RlLm9mZnNldFdpZHRoLCB0b3AgKyBub2RlLm9mZnNldEhlaWdodCk7XG4gICAgfSxcblxuICAgIHRyaWdnZXJPbktleURvd246IG1ldGhvZE9wKG9uS2V5RG93biksXG4gICAgdHJpZ2dlck9uS2V5UHJlc3M6IG1ldGhvZE9wKG9uS2V5UHJlc3MpLFxuICAgIHRyaWdnZXJPbktleVVwOiBvbktleVVwLFxuXG4gICAgZXhlY0NvbW1hbmQ6IGZ1bmN0aW9uKGNtZCkge1xuICAgICAgaWYgKGNvbW1hbmRzLmhhc093blByb3BlcnR5KGNtZCkpXG4gICAgICAgIHJldHVybiBjb21tYW5kc1tjbWRdKHRoaXMpO1xuICAgIH0sXG5cbiAgICBmaW5kUG9zSDogZnVuY3Rpb24oZnJvbSwgYW1vdW50LCB1bml0LCB2aXN1YWxseSkge1xuICAgICAgdmFyIGRpciA9IDE7XG4gICAgICBpZiAoYW1vdW50IDwgMCkgeyBkaXIgPSAtMTsgYW1vdW50ID0gLWFtb3VudDsgfVxuICAgICAgZm9yICh2YXIgaSA9IDAsIGN1ciA9IGNsaXBQb3ModGhpcy5kb2MsIGZyb20pOyBpIDwgYW1vdW50OyArK2kpIHtcbiAgICAgICAgY3VyID0gZmluZFBvc0godGhpcy5kb2MsIGN1ciwgZGlyLCB1bml0LCB2aXN1YWxseSk7XG4gICAgICAgIGlmIChjdXIuaGl0U2lkZSkgYnJlYWs7XG4gICAgICB9XG4gICAgICByZXR1cm4gY3VyO1xuICAgIH0sXG5cbiAgICBtb3ZlSDogbWV0aG9kT3AoZnVuY3Rpb24oZGlyLCB1bml0KSB7XG4gICAgICB2YXIgY20gPSB0aGlzO1xuICAgICAgY20uZXh0ZW5kU2VsZWN0aW9uc0J5KGZ1bmN0aW9uKHJhbmdlKSB7XG4gICAgICAgIGlmIChjbS5kaXNwbGF5LnNoaWZ0IHx8IGNtLmRvYy5leHRlbmQgfHwgcmFuZ2UuZW1wdHkoKSlcbiAgICAgICAgICByZXR1cm4gZmluZFBvc0goY20uZG9jLCByYW5nZS5oZWFkLCBkaXIsIHVuaXQsIGNtLm9wdGlvbnMucnRsTW92ZVZpc3VhbGx5KTtcbiAgICAgICAgZWxzZVxuICAgICAgICAgIHJldHVybiBkaXIgPCAwID8gcmFuZ2UuZnJvbSgpIDogcmFuZ2UudG8oKTtcbiAgICAgIH0sIHNlbF9tb3ZlKTtcbiAgICB9KSxcblxuICAgIGRlbGV0ZUg6IG1ldGhvZE9wKGZ1bmN0aW9uKGRpciwgdW5pdCkge1xuICAgICAgdmFyIHNlbCA9IHRoaXMuZG9jLnNlbCwgZG9jID0gdGhpcy5kb2M7XG4gICAgICBpZiAoc2VsLnNvbWV0aGluZ1NlbGVjdGVkKCkpXG4gICAgICAgIGRvYy5yZXBsYWNlU2VsZWN0aW9uKFwiXCIsIG51bGwsIFwiK2RlbGV0ZVwiKTtcbiAgICAgIGVsc2VcbiAgICAgICAgZGVsZXRlTmVhclNlbGVjdGlvbih0aGlzLCBmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICAgIHZhciBvdGhlciA9IGZpbmRQb3NIKGRvYywgcmFuZ2UuaGVhZCwgZGlyLCB1bml0LCBmYWxzZSk7XG4gICAgICAgICAgcmV0dXJuIGRpciA8IDAgPyB7ZnJvbTogb3RoZXIsIHRvOiByYW5nZS5oZWFkfSA6IHtmcm9tOiByYW5nZS5oZWFkLCB0bzogb3RoZXJ9O1xuICAgICAgICB9KTtcbiAgICB9KSxcblxuICAgIGZpbmRQb3NWOiBmdW5jdGlvbihmcm9tLCBhbW91bnQsIHVuaXQsIGdvYWxDb2x1bW4pIHtcbiAgICAgIHZhciBkaXIgPSAxLCB4ID0gZ29hbENvbHVtbjtcbiAgICAgIGlmIChhbW91bnQgPCAwKSB7IGRpciA9IC0xOyBhbW91bnQgPSAtYW1vdW50OyB9XG4gICAgICBmb3IgKHZhciBpID0gMCwgY3VyID0gY2xpcFBvcyh0aGlzLmRvYywgZnJvbSk7IGkgPCBhbW91bnQ7ICsraSkge1xuICAgICAgICB2YXIgY29vcmRzID0gY3Vyc29yQ29vcmRzKHRoaXMsIGN1ciwgXCJkaXZcIik7XG4gICAgICAgIGlmICh4ID09IG51bGwpIHggPSBjb29yZHMubGVmdDtcbiAgICAgICAgZWxzZSBjb29yZHMubGVmdCA9IHg7XG4gICAgICAgIGN1ciA9IGZpbmRQb3NWKHRoaXMsIGNvb3JkcywgZGlyLCB1bml0KTtcbiAgICAgICAgaWYgKGN1ci5oaXRTaWRlKSBicmVhaztcbiAgICAgIH1cbiAgICAgIHJldHVybiBjdXI7XG4gICAgfSxcblxuICAgIG1vdmVWOiBtZXRob2RPcChmdW5jdGlvbihkaXIsIHVuaXQpIHtcbiAgICAgIHZhciBjbSA9IHRoaXMsIGRvYyA9IHRoaXMuZG9jLCBnb2FscyA9IFtdO1xuICAgICAgdmFyIGNvbGxhcHNlID0gIWNtLmRpc3BsYXkuc2hpZnQgJiYgIWRvYy5leHRlbmQgJiYgZG9jLnNlbC5zb21ldGhpbmdTZWxlY3RlZCgpO1xuICAgICAgZG9jLmV4dGVuZFNlbGVjdGlvbnNCeShmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICBpZiAoY29sbGFwc2UpXG4gICAgICAgICAgcmV0dXJuIGRpciA8IDAgPyByYW5nZS5mcm9tKCkgOiByYW5nZS50bygpO1xuICAgICAgICB2YXIgaGVhZFBvcyA9IGN1cnNvckNvb3JkcyhjbSwgcmFuZ2UuaGVhZCwgXCJkaXZcIik7XG4gICAgICAgIGlmIChyYW5nZS5nb2FsQ29sdW1uICE9IG51bGwpIGhlYWRQb3MubGVmdCA9IHJhbmdlLmdvYWxDb2x1bW47XG4gICAgICAgIGdvYWxzLnB1c2goaGVhZFBvcy5sZWZ0KTtcbiAgICAgICAgdmFyIHBvcyA9IGZpbmRQb3NWKGNtLCBoZWFkUG9zLCBkaXIsIHVuaXQpO1xuICAgICAgICBpZiAodW5pdCA9PSBcInBhZ2VcIiAmJiByYW5nZSA9PSBkb2Muc2VsLnByaW1hcnkoKSlcbiAgICAgICAgICBhZGRUb1Njcm9sbFBvcyhjbSwgbnVsbCwgY2hhckNvb3JkcyhjbSwgcG9zLCBcImRpdlwiKS50b3AgLSBoZWFkUG9zLnRvcCk7XG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgICB9LCBzZWxfbW92ZSk7XG4gICAgICBpZiAoZ29hbHMubGVuZ3RoKSBmb3IgKHZhciBpID0gMDsgaSA8IGRvYy5zZWwucmFuZ2VzLmxlbmd0aDsgaSsrKVxuICAgICAgICBkb2Muc2VsLnJhbmdlc1tpXS5nb2FsQ29sdW1uID0gZ29hbHNbaV07XG4gICAgfSksXG5cbiAgICAvLyBGaW5kIHRoZSB3b3JkIGF0IHRoZSBnaXZlbiBwb3NpdGlvbiAoYXMgcmV0dXJuZWQgYnkgY29vcmRzQ2hhcikuXG4gICAgZmluZFdvcmRBdDogZnVuY3Rpb24ocG9zKSB7XG4gICAgICB2YXIgZG9jID0gdGhpcy5kb2MsIGxpbmUgPSBnZXRMaW5lKGRvYywgcG9zLmxpbmUpLnRleHQ7XG4gICAgICB2YXIgc3RhcnQgPSBwb3MuY2gsIGVuZCA9IHBvcy5jaDtcbiAgICAgIGlmIChsaW5lKSB7XG4gICAgICAgIHZhciBoZWxwZXIgPSB0aGlzLmdldEhlbHBlcihwb3MsIFwid29yZENoYXJzXCIpO1xuICAgICAgICBpZiAoKHBvcy54UmVsIDwgMCB8fCBlbmQgPT0gbGluZS5sZW5ndGgpICYmIHN0YXJ0KSAtLXN0YXJ0OyBlbHNlICsrZW5kO1xuICAgICAgICB2YXIgc3RhcnRDaGFyID0gbGluZS5jaGFyQXQoc3RhcnQpO1xuICAgICAgICB2YXIgY2hlY2sgPSBpc1dvcmRDaGFyKHN0YXJ0Q2hhciwgaGVscGVyKVxuICAgICAgICAgID8gZnVuY3Rpb24oY2gpIHsgcmV0dXJuIGlzV29yZENoYXIoY2gsIGhlbHBlcik7IH1cbiAgICAgICAgICA6IC9cXHMvLnRlc3Qoc3RhcnRDaGFyKSA/IGZ1bmN0aW9uKGNoKSB7cmV0dXJuIC9cXHMvLnRlc3QoY2gpO31cbiAgICAgICAgICA6IGZ1bmN0aW9uKGNoKSB7cmV0dXJuICEvXFxzLy50ZXN0KGNoKSAmJiAhaXNXb3JkQ2hhcihjaCk7fTtcbiAgICAgICAgd2hpbGUgKHN0YXJ0ID4gMCAmJiBjaGVjayhsaW5lLmNoYXJBdChzdGFydCAtIDEpKSkgLS1zdGFydDtcbiAgICAgICAgd2hpbGUgKGVuZCA8IGxpbmUubGVuZ3RoICYmIGNoZWNrKGxpbmUuY2hhckF0KGVuZCkpKSArK2VuZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgUmFuZ2UoUG9zKHBvcy5saW5lLCBzdGFydCksIFBvcyhwb3MubGluZSwgZW5kKSk7XG4gICAgfSxcblxuICAgIHRvZ2dsZU92ZXJ3cml0ZTogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGlmICh2YWx1ZSAhPSBudWxsICYmIHZhbHVlID09IHRoaXMuc3RhdGUub3ZlcndyaXRlKSByZXR1cm47XG4gICAgICBpZiAodGhpcy5zdGF0ZS5vdmVyd3JpdGUgPSAhdGhpcy5zdGF0ZS5vdmVyd3JpdGUpXG4gICAgICAgIGFkZENsYXNzKHRoaXMuZGlzcGxheS5jdXJzb3JEaXYsIFwiQ29kZU1pcnJvci1vdmVyd3JpdGVcIik7XG4gICAgICBlbHNlXG4gICAgICAgIHJtQ2xhc3ModGhpcy5kaXNwbGF5LmN1cnNvckRpdiwgXCJDb2RlTWlycm9yLW92ZXJ3cml0ZVwiKTtcblxuICAgICAgc2lnbmFsKHRoaXMsIFwib3ZlcndyaXRlVG9nZ2xlXCIsIHRoaXMsIHRoaXMuc3RhdGUub3ZlcndyaXRlKTtcbiAgICB9LFxuICAgIGhhc0ZvY3VzOiBmdW5jdGlvbigpIHsgcmV0dXJuIGFjdGl2ZUVsdCgpID09IHRoaXMuZGlzcGxheS5pbnB1dDsgfSxcblxuICAgIHNjcm9sbFRvOiBtZXRob2RPcChmdW5jdGlvbih4LCB5KSB7XG4gICAgICBpZiAoeCAhPSBudWxsIHx8IHkgIT0gbnVsbCkgcmVzb2x2ZVNjcm9sbFRvUG9zKHRoaXMpO1xuICAgICAgaWYgKHggIT0gbnVsbCkgdGhpcy5jdXJPcC5zY3JvbGxMZWZ0ID0geDtcbiAgICAgIGlmICh5ICE9IG51bGwpIHRoaXMuY3VyT3Auc2Nyb2xsVG9wID0geTtcbiAgICB9KSxcbiAgICBnZXRTY3JvbGxJbmZvOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBzY3JvbGxlciA9IHRoaXMuZGlzcGxheS5zY3JvbGxlcjtcbiAgICAgIHJldHVybiB7bGVmdDogc2Nyb2xsZXIuc2Nyb2xsTGVmdCwgdG9wOiBzY3JvbGxlci5zY3JvbGxUb3AsXG4gICAgICAgICAgICAgIGhlaWdodDogc2Nyb2xsZXIuc2Nyb2xsSGVpZ2h0IC0gc2Nyb2xsR2FwKHRoaXMpIC0gdGhpcy5kaXNwbGF5LmJhckhlaWdodCxcbiAgICAgICAgICAgICAgd2lkdGg6IHNjcm9sbGVyLnNjcm9sbFdpZHRoIC0gc2Nyb2xsR2FwKHRoaXMpIC0gdGhpcy5kaXNwbGF5LmJhcldpZHRoLFxuICAgICAgICAgICAgICBjbGllbnRIZWlnaHQ6IGRpc3BsYXlIZWlnaHQodGhpcyksIGNsaWVudFdpZHRoOiBkaXNwbGF5V2lkdGgodGhpcyl9O1xuICAgIH0sXG5cbiAgICBzY3JvbGxJbnRvVmlldzogbWV0aG9kT3AoZnVuY3Rpb24ocmFuZ2UsIG1hcmdpbikge1xuICAgICAgaWYgKHJhbmdlID09IG51bGwpIHtcbiAgICAgICAgcmFuZ2UgPSB7ZnJvbTogdGhpcy5kb2Muc2VsLnByaW1hcnkoKS5oZWFkLCB0bzogbnVsbH07XG4gICAgICAgIGlmIChtYXJnaW4gPT0gbnVsbCkgbWFyZ2luID0gdGhpcy5vcHRpb25zLmN1cnNvclNjcm9sbE1hcmdpbjtcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHJhbmdlID09IFwibnVtYmVyXCIpIHtcbiAgICAgICAgcmFuZ2UgPSB7ZnJvbTogUG9zKHJhbmdlLCAwKSwgdG86IG51bGx9O1xuICAgICAgfSBlbHNlIGlmIChyYW5nZS5mcm9tID09IG51bGwpIHtcbiAgICAgICAgcmFuZ2UgPSB7ZnJvbTogcmFuZ2UsIHRvOiBudWxsfTtcbiAgICAgIH1cbiAgICAgIGlmICghcmFuZ2UudG8pIHJhbmdlLnRvID0gcmFuZ2UuZnJvbTtcbiAgICAgIHJhbmdlLm1hcmdpbiA9IG1hcmdpbiB8fCAwO1xuXG4gICAgICBpZiAocmFuZ2UuZnJvbS5saW5lICE9IG51bGwpIHtcbiAgICAgICAgcmVzb2x2ZVNjcm9sbFRvUG9zKHRoaXMpO1xuICAgICAgICB0aGlzLmN1ck9wLnNjcm9sbFRvUG9zID0gcmFuZ2U7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB2YXIgc1BvcyA9IGNhbGN1bGF0ZVNjcm9sbFBvcyh0aGlzLCBNYXRoLm1pbihyYW5nZS5mcm9tLmxlZnQsIHJhbmdlLnRvLmxlZnQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLm1pbihyYW5nZS5mcm9tLnRvcCwgcmFuZ2UudG8udG9wKSAtIHJhbmdlLm1hcmdpbixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTWF0aC5tYXgocmFuZ2UuZnJvbS5yaWdodCwgcmFuZ2UudG8ucmlnaHQpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNYXRoLm1heChyYW5nZS5mcm9tLmJvdHRvbSwgcmFuZ2UudG8uYm90dG9tKSArIHJhbmdlLm1hcmdpbik7XG4gICAgICAgIHRoaXMuc2Nyb2xsVG8oc1Bvcy5zY3JvbGxMZWZ0LCBzUG9zLnNjcm9sbFRvcCk7XG4gICAgICB9XG4gICAgfSksXG5cbiAgICBzZXRTaXplOiBtZXRob2RPcChmdW5jdGlvbih3aWR0aCwgaGVpZ2h0KSB7XG4gICAgICB2YXIgY20gPSB0aGlzO1xuICAgICAgZnVuY3Rpb24gaW50ZXJwcmV0KHZhbCkge1xuICAgICAgICByZXR1cm4gdHlwZW9mIHZhbCA9PSBcIm51bWJlclwiIHx8IC9eXFxkKyQvLnRlc3QoU3RyaW5nKHZhbCkpID8gdmFsICsgXCJweFwiIDogdmFsO1xuICAgICAgfVxuICAgICAgaWYgKHdpZHRoICE9IG51bGwpIGNtLmRpc3BsYXkud3JhcHBlci5zdHlsZS53aWR0aCA9IGludGVycHJldCh3aWR0aCk7XG4gICAgICBpZiAoaGVpZ2h0ICE9IG51bGwpIGNtLmRpc3BsYXkud3JhcHBlci5zdHlsZS5oZWlnaHQgPSBpbnRlcnByZXQoaGVpZ2h0KTtcbiAgICAgIGlmIChjbS5vcHRpb25zLmxpbmVXcmFwcGluZykgY2xlYXJMaW5lTWVhc3VyZW1lbnRDYWNoZSh0aGlzKTtcbiAgICAgIHZhciBsaW5lTm8gPSBjbS5kaXNwbGF5LnZpZXdGcm9tO1xuICAgICAgY20uZG9jLml0ZXIobGluZU5vLCBjbS5kaXNwbGF5LnZpZXdUbywgZnVuY3Rpb24obGluZSkge1xuICAgICAgICBpZiAobGluZS53aWRnZXRzKSBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmUud2lkZ2V0cy5sZW5ndGg7IGkrKylcbiAgICAgICAgICBpZiAobGluZS53aWRnZXRzW2ldLm5vSFNjcm9sbCkgeyByZWdMaW5lQ2hhbmdlKGNtLCBsaW5lTm8sIFwid2lkZ2V0XCIpOyBicmVhazsgfVxuICAgICAgICArK2xpbmVObztcbiAgICAgIH0pO1xuICAgICAgY20uY3VyT3AuZm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgc2lnbmFsKGNtLCBcInJlZnJlc2hcIiwgdGhpcyk7XG4gICAgfSksXG5cbiAgICBvcGVyYXRpb246IGZ1bmN0aW9uKGYpe3JldHVybiBydW5Jbk9wKHRoaXMsIGYpO30sXG5cbiAgICByZWZyZXNoOiBtZXRob2RPcChmdW5jdGlvbigpIHtcbiAgICAgIHZhciBvbGRIZWlnaHQgPSB0aGlzLmRpc3BsYXkuY2FjaGVkVGV4dEhlaWdodDtcbiAgICAgIHJlZ0NoYW5nZSh0aGlzKTtcbiAgICAgIHRoaXMuY3VyT3AuZm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgY2xlYXJDYWNoZXModGhpcyk7XG4gICAgICB0aGlzLnNjcm9sbFRvKHRoaXMuZG9jLnNjcm9sbExlZnQsIHRoaXMuZG9jLnNjcm9sbFRvcCk7XG4gICAgICB1cGRhdGVHdXR0ZXJTcGFjZSh0aGlzKTtcbiAgICAgIGlmIChvbGRIZWlnaHQgPT0gbnVsbCB8fCBNYXRoLmFicyhvbGRIZWlnaHQgLSB0ZXh0SGVpZ2h0KHRoaXMuZGlzcGxheSkpID4gLjUpXG4gICAgICAgIGVzdGltYXRlTGluZUhlaWdodHModGhpcyk7XG4gICAgICBzaWduYWwodGhpcywgXCJyZWZyZXNoXCIsIHRoaXMpO1xuICAgIH0pLFxuXG4gICAgc3dhcERvYzogbWV0aG9kT3AoZnVuY3Rpb24oZG9jKSB7XG4gICAgICB2YXIgb2xkID0gdGhpcy5kb2M7XG4gICAgICBvbGQuY20gPSBudWxsO1xuICAgICAgYXR0YWNoRG9jKHRoaXMsIGRvYyk7XG4gICAgICBjbGVhckNhY2hlcyh0aGlzKTtcbiAgICAgIHJlc2V0SW5wdXQodGhpcyk7XG4gICAgICB0aGlzLnNjcm9sbFRvKGRvYy5zY3JvbGxMZWZ0LCBkb2Muc2Nyb2xsVG9wKTtcbiAgICAgIHRoaXMuY3VyT3AuZm9yY2VTY3JvbGwgPSB0cnVlO1xuICAgICAgc2lnbmFsTGF0ZXIodGhpcywgXCJzd2FwRG9jXCIsIHRoaXMsIG9sZCk7XG4gICAgICByZXR1cm4gb2xkO1xuICAgIH0pLFxuXG4gICAgZ2V0SW5wdXRGaWVsZDogZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kaXNwbGF5LmlucHV0O30sXG4gICAgZ2V0V3JhcHBlckVsZW1lbnQ6IGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZGlzcGxheS53cmFwcGVyO30sXG4gICAgZ2V0U2Nyb2xsZXJFbGVtZW50OiBmdW5jdGlvbigpe3JldHVybiB0aGlzLmRpc3BsYXkuc2Nyb2xsZXI7fSxcbiAgICBnZXRHdXR0ZXJFbGVtZW50OiBmdW5jdGlvbigpe3JldHVybiB0aGlzLmRpc3BsYXkuZ3V0dGVyczt9XG4gIH07XG4gIGV2ZW50TWl4aW4oQ29kZU1pcnJvcik7XG5cbiAgLy8gT1BUSU9OIERFRkFVTFRTXG5cbiAgLy8gVGhlIGRlZmF1bHQgY29uZmlndXJhdGlvbiBvcHRpb25zLlxuICB2YXIgZGVmYXVsdHMgPSBDb2RlTWlycm9yLmRlZmF1bHRzID0ge307XG4gIC8vIEZ1bmN0aW9ucyB0byBydW4gd2hlbiBvcHRpb25zIGFyZSBjaGFuZ2VkLlxuICB2YXIgb3B0aW9uSGFuZGxlcnMgPSBDb2RlTWlycm9yLm9wdGlvbkhhbmRsZXJzID0ge307XG5cbiAgZnVuY3Rpb24gb3B0aW9uKG5hbWUsIGRlZmx0LCBoYW5kbGUsIG5vdE9uSW5pdCkge1xuICAgIENvZGVNaXJyb3IuZGVmYXVsdHNbbmFtZV0gPSBkZWZsdDtcbiAgICBpZiAoaGFuZGxlKSBvcHRpb25IYW5kbGVyc1tuYW1lXSA9XG4gICAgICBub3RPbkluaXQgPyBmdW5jdGlvbihjbSwgdmFsLCBvbGQpIHtpZiAob2xkICE9IEluaXQpIGhhbmRsZShjbSwgdmFsLCBvbGQpO30gOiBoYW5kbGU7XG4gIH1cblxuICAvLyBQYXNzZWQgdG8gb3B0aW9uIGhhbmRsZXJzIHdoZW4gdGhlcmUgaXMgbm8gb2xkIHZhbHVlLlxuICB2YXIgSW5pdCA9IENvZGVNaXJyb3IuSW5pdCA9IHt0b1N0cmluZzogZnVuY3Rpb24oKXtyZXR1cm4gXCJDb2RlTWlycm9yLkluaXRcIjt9fTtcblxuICAvLyBUaGVzZSB0d28gYXJlLCBvbiBpbml0LCBjYWxsZWQgZnJvbSB0aGUgY29uc3RydWN0b3IgYmVjYXVzZSB0aGV5XG4gIC8vIGhhdmUgdG8gYmUgaW5pdGlhbGl6ZWQgYmVmb3JlIHRoZSBlZGl0b3IgY2FuIHN0YXJ0IGF0IGFsbC5cbiAgb3B0aW9uKFwidmFsdWVcIiwgXCJcIiwgZnVuY3Rpb24oY20sIHZhbCkge1xuICAgIGNtLnNldFZhbHVlKHZhbCk7XG4gIH0sIHRydWUpO1xuICBvcHRpb24oXCJtb2RlXCIsIG51bGwsIGZ1bmN0aW9uKGNtLCB2YWwpIHtcbiAgICBjbS5kb2MubW9kZU9wdGlvbiA9IHZhbDtcbiAgICBsb2FkTW9kZShjbSk7XG4gIH0sIHRydWUpO1xuXG4gIG9wdGlvbihcImluZGVudFVuaXRcIiwgMiwgbG9hZE1vZGUsIHRydWUpO1xuICBvcHRpb24oXCJpbmRlbnRXaXRoVGFic1wiLCBmYWxzZSk7XG4gIG9wdGlvbihcInNtYXJ0SW5kZW50XCIsIHRydWUpO1xuICBvcHRpb24oXCJ0YWJTaXplXCIsIDQsIGZ1bmN0aW9uKGNtKSB7XG4gICAgcmVzZXRNb2RlU3RhdGUoY20pO1xuICAgIGNsZWFyQ2FjaGVzKGNtKTtcbiAgICByZWdDaGFuZ2UoY20pO1xuICB9LCB0cnVlKTtcbiAgb3B0aW9uKFwic3BlY2lhbENoYXJzXCIsIC9bXFx0XFx1MDAwMC1cXHUwMDE5XFx1MDBhZFxcdTIwMGItXFx1MjAwZlxcdTIwMjhcXHUyMDI5XFx1ZmVmZl0vZywgZnVuY3Rpb24oY20sIHZhbCkge1xuICAgIGNtLm9wdGlvbnMuc3BlY2lhbENoYXJzID0gbmV3IFJlZ0V4cCh2YWwuc291cmNlICsgKHZhbC50ZXN0KFwiXFx0XCIpID8gXCJcIiA6IFwifFxcdFwiKSwgXCJnXCIpO1xuICAgIGNtLnJlZnJlc2goKTtcbiAgfSwgdHJ1ZSk7XG4gIG9wdGlvbihcInNwZWNpYWxDaGFyUGxhY2Vob2xkZXJcIiwgZGVmYXVsdFNwZWNpYWxDaGFyUGxhY2Vob2xkZXIsIGZ1bmN0aW9uKGNtKSB7Y20ucmVmcmVzaCgpO30sIHRydWUpO1xuICBvcHRpb24oXCJlbGVjdHJpY0NoYXJzXCIsIHRydWUpO1xuICBvcHRpb24oXCJydGxNb3ZlVmlzdWFsbHlcIiwgIXdpbmRvd3MpO1xuICBvcHRpb24oXCJ3aG9sZUxpbmVVcGRhdGVCZWZvcmVcIiwgdHJ1ZSk7XG5cbiAgb3B0aW9uKFwidGhlbWVcIiwgXCJkZWZhdWx0XCIsIGZ1bmN0aW9uKGNtKSB7XG4gICAgdGhlbWVDaGFuZ2VkKGNtKTtcbiAgICBndXR0ZXJzQ2hhbmdlZChjbSk7XG4gIH0sIHRydWUpO1xuICBvcHRpb24oXCJrZXlNYXBcIiwgXCJkZWZhdWx0XCIsIGZ1bmN0aW9uKGNtLCB2YWwsIG9sZCkge1xuICAgIHZhciBuZXh0ID0gZ2V0S2V5TWFwKHZhbCk7XG4gICAgdmFyIHByZXYgPSBvbGQgIT0gQ29kZU1pcnJvci5Jbml0ICYmIGdldEtleU1hcChvbGQpO1xuICAgIGlmIChwcmV2ICYmIHByZXYuZGV0YWNoKSBwcmV2LmRldGFjaChjbSwgbmV4dCk7XG4gICAgaWYgKG5leHQuYXR0YWNoKSBuZXh0LmF0dGFjaChjbSwgcHJldiB8fCBudWxsKTtcbiAgfSk7XG4gIG9wdGlvbihcImV4dHJhS2V5c1wiLCBudWxsKTtcblxuICBvcHRpb24oXCJsaW5lV3JhcHBpbmdcIiwgZmFsc2UsIHdyYXBwaW5nQ2hhbmdlZCwgdHJ1ZSk7XG4gIG9wdGlvbihcImd1dHRlcnNcIiwgW10sIGZ1bmN0aW9uKGNtKSB7XG4gICAgc2V0R3V0dGVyc0ZvckxpbmVOdW1iZXJzKGNtLm9wdGlvbnMpO1xuICAgIGd1dHRlcnNDaGFuZ2VkKGNtKTtcbiAgfSwgdHJ1ZSk7XG4gIG9wdGlvbihcImZpeGVkR3V0dGVyXCIsIHRydWUsIGZ1bmN0aW9uKGNtLCB2YWwpIHtcbiAgICBjbS5kaXNwbGF5Lmd1dHRlcnMuc3R5bGUubGVmdCA9IHZhbCA/IGNvbXBlbnNhdGVGb3JIU2Nyb2xsKGNtLmRpc3BsYXkpICsgXCJweFwiIDogXCIwXCI7XG4gICAgY20ucmVmcmVzaCgpO1xuICB9LCB0cnVlKTtcbiAgb3B0aW9uKFwiY292ZXJHdXR0ZXJOZXh0VG9TY3JvbGxiYXJcIiwgZmFsc2UsIGZ1bmN0aW9uKGNtKSB7dXBkYXRlU2Nyb2xsYmFycyhjbSk7fSwgdHJ1ZSk7XG4gIG9wdGlvbihcInNjcm9sbGJhclN0eWxlXCIsIFwibmF0aXZlXCIsIGZ1bmN0aW9uKGNtKSB7XG4gICAgaW5pdFNjcm9sbGJhcnMoY20pO1xuICAgIHVwZGF0ZVNjcm9sbGJhcnMoY20pO1xuICAgIGNtLmRpc3BsYXkuc2Nyb2xsYmFycy5zZXRTY3JvbGxUb3AoY20uZG9jLnNjcm9sbFRvcCk7XG4gICAgY20uZGlzcGxheS5zY3JvbGxiYXJzLnNldFNjcm9sbExlZnQoY20uZG9jLnNjcm9sbExlZnQpO1xuICB9LCB0cnVlKTtcbiAgb3B0aW9uKFwibGluZU51bWJlcnNcIiwgZmFsc2UsIGZ1bmN0aW9uKGNtKSB7XG4gICAgc2V0R3V0dGVyc0ZvckxpbmVOdW1iZXJzKGNtLm9wdGlvbnMpO1xuICAgIGd1dHRlcnNDaGFuZ2VkKGNtKTtcbiAgfSwgdHJ1ZSk7XG4gIG9wdGlvbihcImZpcnN0TGluZU51bWJlclwiLCAxLCBndXR0ZXJzQ2hhbmdlZCwgdHJ1ZSk7XG4gIG9wdGlvbihcImxpbmVOdW1iZXJGb3JtYXR0ZXJcIiwgZnVuY3Rpb24oaW50ZWdlcikge3JldHVybiBpbnRlZ2VyO30sIGd1dHRlcnNDaGFuZ2VkLCB0cnVlKTtcbiAgb3B0aW9uKFwic2hvd0N1cnNvcldoZW5TZWxlY3RpbmdcIiwgZmFsc2UsIHVwZGF0ZVNlbGVjdGlvbiwgdHJ1ZSk7XG5cbiAgb3B0aW9uKFwicmVzZXRTZWxlY3Rpb25PbkNvbnRleHRNZW51XCIsIHRydWUpO1xuXG4gIG9wdGlvbihcInJlYWRPbmx5XCIsIGZhbHNlLCBmdW5jdGlvbihjbSwgdmFsKSB7XG4gICAgaWYgKHZhbCA9PSBcIm5vY3Vyc29yXCIpIHtcbiAgICAgIG9uQmx1cihjbSk7XG4gICAgICBjbS5kaXNwbGF5LmlucHV0LmJsdXIoKTtcbiAgICAgIGNtLmRpc3BsYXkuZGlzYWJsZWQgPSB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICBjbS5kaXNwbGF5LmRpc2FibGVkID0gZmFsc2U7XG4gICAgICBpZiAoIXZhbCkgcmVzZXRJbnB1dChjbSk7XG4gICAgfVxuICB9KTtcbiAgb3B0aW9uKFwiZGlzYWJsZUlucHV0XCIsIGZhbHNlLCBmdW5jdGlvbihjbSwgdmFsKSB7aWYgKCF2YWwpIHJlc2V0SW5wdXQoY20pO30sIHRydWUpO1xuICBvcHRpb24oXCJkcmFnRHJvcFwiLCB0cnVlKTtcblxuICBvcHRpb24oXCJjdXJzb3JCbGlua1JhdGVcIiwgNTMwKTtcbiAgb3B0aW9uKFwiY3Vyc29yU2Nyb2xsTWFyZ2luXCIsIDApO1xuICBvcHRpb24oXCJjdXJzb3JIZWlnaHRcIiwgMSwgdXBkYXRlU2VsZWN0aW9uLCB0cnVlKTtcbiAgb3B0aW9uKFwic2luZ2xlQ3Vyc29ySGVpZ2h0UGVyTGluZVwiLCB0cnVlLCB1cGRhdGVTZWxlY3Rpb24sIHRydWUpO1xuICBvcHRpb24oXCJ3b3JrVGltZVwiLCAxMDApO1xuICBvcHRpb24oXCJ3b3JrRGVsYXlcIiwgMTAwKTtcbiAgb3B0aW9uKFwiZmxhdHRlblNwYW5zXCIsIHRydWUsIHJlc2V0TW9kZVN0YXRlLCB0cnVlKTtcbiAgb3B0aW9uKFwiYWRkTW9kZUNsYXNzXCIsIGZhbHNlLCByZXNldE1vZGVTdGF0ZSwgdHJ1ZSk7XG4gIG9wdGlvbihcInBvbGxJbnRlcnZhbFwiLCAxMDApO1xuICBvcHRpb24oXCJ1bmRvRGVwdGhcIiwgMjAwLCBmdW5jdGlvbihjbSwgdmFsKXtjbS5kb2MuaGlzdG9yeS51bmRvRGVwdGggPSB2YWw7fSk7XG4gIG9wdGlvbihcImhpc3RvcnlFdmVudERlbGF5XCIsIDEyNTApO1xuICBvcHRpb24oXCJ2aWV3cG9ydE1hcmdpblwiLCAxMCwgZnVuY3Rpb24oY20pe2NtLnJlZnJlc2goKTt9LCB0cnVlKTtcbiAgb3B0aW9uKFwibWF4SGlnaGxpZ2h0TGVuZ3RoXCIsIDEwMDAwLCByZXNldE1vZGVTdGF0ZSwgdHJ1ZSk7XG4gIG9wdGlvbihcIm1vdmVJbnB1dFdpdGhDdXJzb3JcIiwgdHJ1ZSwgZnVuY3Rpb24oY20sIHZhbCkge1xuICAgIGlmICghdmFsKSBjbS5kaXNwbGF5LmlucHV0RGl2LnN0eWxlLnRvcCA9IGNtLmRpc3BsYXkuaW5wdXREaXYuc3R5bGUubGVmdCA9IDA7XG4gIH0pO1xuXG4gIG9wdGlvbihcInRhYmluZGV4XCIsIG51bGwsIGZ1bmN0aW9uKGNtLCB2YWwpIHtcbiAgICBjbS5kaXNwbGF5LmlucHV0LnRhYkluZGV4ID0gdmFsIHx8IFwiXCI7XG4gIH0pO1xuICBvcHRpb24oXCJhdXRvZm9jdXNcIiwgbnVsbCk7XG5cbiAgLy8gTU9ERSBERUZJTklUSU9OIEFORCBRVUVSWUlOR1xuXG4gIC8vIEtub3duIG1vZGVzLCBieSBuYW1lIGFuZCBieSBNSU1FXG4gIHZhciBtb2RlcyA9IENvZGVNaXJyb3IubW9kZXMgPSB7fSwgbWltZU1vZGVzID0gQ29kZU1pcnJvci5taW1lTW9kZXMgPSB7fTtcblxuICAvLyBFeHRyYSBhcmd1bWVudHMgYXJlIHN0b3JlZCBhcyB0aGUgbW9kZSdzIGRlcGVuZGVuY2llcywgd2hpY2ggaXNcbiAgLy8gdXNlZCBieSAobGVnYWN5KSBtZWNoYW5pc21zIGxpa2UgbG9hZG1vZGUuanMgdG8gYXV0b21hdGljYWxseVxuICAvLyBsb2FkIGEgbW9kZS4gKFByZWZlcnJlZCBtZWNoYW5pc20gaXMgdGhlIHJlcXVpcmUvZGVmaW5lIGNhbGxzLilcbiAgQ29kZU1pcnJvci5kZWZpbmVNb2RlID0gZnVuY3Rpb24obmFtZSwgbW9kZSkge1xuICAgIGlmICghQ29kZU1pcnJvci5kZWZhdWx0cy5tb2RlICYmIG5hbWUgIT0gXCJudWxsXCIpIENvZGVNaXJyb3IuZGVmYXVsdHMubW9kZSA9IG5hbWU7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAyKVxuICAgICAgbW9kZS5kZXBlbmRlbmNpZXMgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpO1xuICAgIG1vZGVzW25hbWVdID0gbW9kZTtcbiAgfTtcblxuICBDb2RlTWlycm9yLmRlZmluZU1JTUUgPSBmdW5jdGlvbihtaW1lLCBzcGVjKSB7XG4gICAgbWltZU1vZGVzW21pbWVdID0gc3BlYztcbiAgfTtcblxuICAvLyBHaXZlbiBhIE1JTUUgdHlwZSwgYSB7bmFtZSwgLi4ub3B0aW9uc30gY29uZmlnIG9iamVjdCwgb3IgYSBuYW1lXG4gIC8vIHN0cmluZywgcmV0dXJuIGEgbW9kZSBjb25maWcgb2JqZWN0LlxuICBDb2RlTWlycm9yLnJlc29sdmVNb2RlID0gZnVuY3Rpb24oc3BlYykge1xuICAgIGlmICh0eXBlb2Ygc3BlYyA9PSBcInN0cmluZ1wiICYmIG1pbWVNb2Rlcy5oYXNPd25Qcm9wZXJ0eShzcGVjKSkge1xuICAgICAgc3BlYyA9IG1pbWVNb2Rlc1tzcGVjXTtcbiAgICB9IGVsc2UgaWYgKHNwZWMgJiYgdHlwZW9mIHNwZWMubmFtZSA9PSBcInN0cmluZ1wiICYmIG1pbWVNb2Rlcy5oYXNPd25Qcm9wZXJ0eShzcGVjLm5hbWUpKSB7XG4gICAgICB2YXIgZm91bmQgPSBtaW1lTW9kZXNbc3BlYy5uYW1lXTtcbiAgICAgIGlmICh0eXBlb2YgZm91bmQgPT0gXCJzdHJpbmdcIikgZm91bmQgPSB7bmFtZTogZm91bmR9O1xuICAgICAgc3BlYyA9IGNyZWF0ZU9iaihmb3VuZCwgc3BlYyk7XG4gICAgICBzcGVjLm5hbWUgPSBmb3VuZC5uYW1lO1xuICAgIH0gZWxzZSBpZiAodHlwZW9mIHNwZWMgPT0gXCJzdHJpbmdcIiAmJiAvXltcXHdcXC1dK1xcL1tcXHdcXC1dK1xcK3htbCQvLnRlc3Qoc3BlYykpIHtcbiAgICAgIHJldHVybiBDb2RlTWlycm9yLnJlc29sdmVNb2RlKFwiYXBwbGljYXRpb24veG1sXCIpO1xuICAgIH1cbiAgICBpZiAodHlwZW9mIHNwZWMgPT0gXCJzdHJpbmdcIikgcmV0dXJuIHtuYW1lOiBzcGVjfTtcbiAgICBlbHNlIHJldHVybiBzcGVjIHx8IHtuYW1lOiBcIm51bGxcIn07XG4gIH07XG5cbiAgLy8gR2l2ZW4gYSBtb2RlIHNwZWMgKGFueXRoaW5nIHRoYXQgcmVzb2x2ZU1vZGUgYWNjZXB0cyksIGZpbmQgYW5kXG4gIC8vIGluaXRpYWxpemUgYW4gYWN0dWFsIG1vZGUgb2JqZWN0LlxuICBDb2RlTWlycm9yLmdldE1vZGUgPSBmdW5jdGlvbihvcHRpb25zLCBzcGVjKSB7XG4gICAgdmFyIHNwZWMgPSBDb2RlTWlycm9yLnJlc29sdmVNb2RlKHNwZWMpO1xuICAgIHZhciBtZmFjdG9yeSA9IG1vZGVzW3NwZWMubmFtZV07XG4gICAgaWYgKCFtZmFjdG9yeSkgcmV0dXJuIENvZGVNaXJyb3IuZ2V0TW9kZShvcHRpb25zLCBcInRleHQvcGxhaW5cIik7XG4gICAgdmFyIG1vZGVPYmogPSBtZmFjdG9yeShvcHRpb25zLCBzcGVjKTtcbiAgICBpZiAobW9kZUV4dGVuc2lvbnMuaGFzT3duUHJvcGVydHkoc3BlYy5uYW1lKSkge1xuICAgICAgdmFyIGV4dHMgPSBtb2RlRXh0ZW5zaW9uc1tzcGVjLm5hbWVdO1xuICAgICAgZm9yICh2YXIgcHJvcCBpbiBleHRzKSB7XG4gICAgICAgIGlmICghZXh0cy5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgY29udGludWU7XG4gICAgICAgIGlmIChtb2RlT2JqLmhhc093blByb3BlcnR5KHByb3ApKSBtb2RlT2JqW1wiX1wiICsgcHJvcF0gPSBtb2RlT2JqW3Byb3BdO1xuICAgICAgICBtb2RlT2JqW3Byb3BdID0gZXh0c1twcm9wXTtcbiAgICAgIH1cbiAgICB9XG4gICAgbW9kZU9iai5uYW1lID0gc3BlYy5uYW1lO1xuICAgIGlmIChzcGVjLmhlbHBlclR5cGUpIG1vZGVPYmouaGVscGVyVHlwZSA9IHNwZWMuaGVscGVyVHlwZTtcbiAgICBpZiAoc3BlYy5tb2RlUHJvcHMpIGZvciAodmFyIHByb3AgaW4gc3BlYy5tb2RlUHJvcHMpXG4gICAgICBtb2RlT2JqW3Byb3BdID0gc3BlYy5tb2RlUHJvcHNbcHJvcF07XG5cbiAgICByZXR1cm4gbW9kZU9iajtcbiAgfTtcblxuICAvLyBNaW5pbWFsIGRlZmF1bHQgbW9kZS5cbiAgQ29kZU1pcnJvci5kZWZpbmVNb2RlKFwibnVsbFwiLCBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge3Rva2VuOiBmdW5jdGlvbihzdHJlYW0pIHtzdHJlYW0uc2tpcFRvRW5kKCk7fX07XG4gIH0pO1xuICBDb2RlTWlycm9yLmRlZmluZU1JTUUoXCJ0ZXh0L3BsYWluXCIsIFwibnVsbFwiKTtcblxuICAvLyBUaGlzIGNhbiBiZSB1c2VkIHRvIGF0dGFjaCBwcm9wZXJ0aWVzIHRvIG1vZGUgb2JqZWN0cyBmcm9tXG4gIC8vIG91dHNpZGUgdGhlIGFjdHVhbCBtb2RlIGRlZmluaXRpb24uXG4gIHZhciBtb2RlRXh0ZW5zaW9ucyA9IENvZGVNaXJyb3IubW9kZUV4dGVuc2lvbnMgPSB7fTtcbiAgQ29kZU1pcnJvci5leHRlbmRNb2RlID0gZnVuY3Rpb24obW9kZSwgcHJvcGVydGllcykge1xuICAgIHZhciBleHRzID0gbW9kZUV4dGVuc2lvbnMuaGFzT3duUHJvcGVydHkobW9kZSkgPyBtb2RlRXh0ZW5zaW9uc1ttb2RlXSA6IChtb2RlRXh0ZW5zaW9uc1ttb2RlXSA9IHt9KTtcbiAgICBjb3B5T2JqKHByb3BlcnRpZXMsIGV4dHMpO1xuICB9O1xuXG4gIC8vIEVYVEVOU0lPTlNcblxuICBDb2RlTWlycm9yLmRlZmluZUV4dGVuc2lvbiA9IGZ1bmN0aW9uKG5hbWUsIGZ1bmMpIHtcbiAgICBDb2RlTWlycm9yLnByb3RvdHlwZVtuYW1lXSA9IGZ1bmM7XG4gIH07XG4gIENvZGVNaXJyb3IuZGVmaW5lRG9jRXh0ZW5zaW9uID0gZnVuY3Rpb24obmFtZSwgZnVuYykge1xuICAgIERvYy5wcm90b3R5cGVbbmFtZV0gPSBmdW5jO1xuICB9O1xuICBDb2RlTWlycm9yLmRlZmluZU9wdGlvbiA9IG9wdGlvbjtcblxuICB2YXIgaW5pdEhvb2tzID0gW107XG4gIENvZGVNaXJyb3IuZGVmaW5lSW5pdEhvb2sgPSBmdW5jdGlvbihmKSB7aW5pdEhvb2tzLnB1c2goZik7fTtcblxuICB2YXIgaGVscGVycyA9IENvZGVNaXJyb3IuaGVscGVycyA9IHt9O1xuICBDb2RlTWlycm9yLnJlZ2lzdGVySGVscGVyID0gZnVuY3Rpb24odHlwZSwgbmFtZSwgdmFsdWUpIHtcbiAgICBpZiAoIWhlbHBlcnMuaGFzT3duUHJvcGVydHkodHlwZSkpIGhlbHBlcnNbdHlwZV0gPSBDb2RlTWlycm9yW3R5cGVdID0ge19nbG9iYWw6IFtdfTtcbiAgICBoZWxwZXJzW3R5cGVdW25hbWVdID0gdmFsdWU7XG4gIH07XG4gIENvZGVNaXJyb3IucmVnaXN0ZXJHbG9iYWxIZWxwZXIgPSBmdW5jdGlvbih0eXBlLCBuYW1lLCBwcmVkaWNhdGUsIHZhbHVlKSB7XG4gICAgQ29kZU1pcnJvci5yZWdpc3RlckhlbHBlcih0eXBlLCBuYW1lLCB2YWx1ZSk7XG4gICAgaGVscGVyc1t0eXBlXS5fZ2xvYmFsLnB1c2goe3ByZWQ6IHByZWRpY2F0ZSwgdmFsOiB2YWx1ZX0pO1xuICB9O1xuXG4gIC8vIE1PREUgU1RBVEUgSEFORExJTkdcblxuICAvLyBVdGlsaXR5IGZ1bmN0aW9ucyBmb3Igd29ya2luZyB3aXRoIHN0YXRlLiBFeHBvcnRlZCBiZWNhdXNlIG5lc3RlZFxuICAvLyBtb2RlcyBuZWVkIHRvIGRvIHRoaXMgZm9yIHRoZWlyIGlubmVyIG1vZGVzLlxuXG4gIHZhciBjb3B5U3RhdGUgPSBDb2RlTWlycm9yLmNvcHlTdGF0ZSA9IGZ1bmN0aW9uKG1vZGUsIHN0YXRlKSB7XG4gICAgaWYgKHN0YXRlID09PSB0cnVlKSByZXR1cm4gc3RhdGU7XG4gICAgaWYgKG1vZGUuY29weVN0YXRlKSByZXR1cm4gbW9kZS5jb3B5U3RhdGUoc3RhdGUpO1xuICAgIHZhciBuc3RhdGUgPSB7fTtcbiAgICBmb3IgKHZhciBuIGluIHN0YXRlKSB7XG4gICAgICB2YXIgdmFsID0gc3RhdGVbbl07XG4gICAgICBpZiAodmFsIGluc3RhbmNlb2YgQXJyYXkpIHZhbCA9IHZhbC5jb25jYXQoW10pO1xuICAgICAgbnN0YXRlW25dID0gdmFsO1xuICAgIH1cbiAgICByZXR1cm4gbnN0YXRlO1xuICB9O1xuXG4gIHZhciBzdGFydFN0YXRlID0gQ29kZU1pcnJvci5zdGFydFN0YXRlID0gZnVuY3Rpb24obW9kZSwgYTEsIGEyKSB7XG4gICAgcmV0dXJuIG1vZGUuc3RhcnRTdGF0ZSA/IG1vZGUuc3RhcnRTdGF0ZShhMSwgYTIpIDogdHJ1ZTtcbiAgfTtcblxuICAvLyBHaXZlbiBhIG1vZGUgYW5kIGEgc3RhdGUgKGZvciB0aGF0IG1vZGUpLCBmaW5kIHRoZSBpbm5lciBtb2RlIGFuZFxuICAvLyBzdGF0ZSBhdCB0aGUgcG9zaXRpb24gdGhhdCB0aGUgc3RhdGUgcmVmZXJzIHRvLlxuICBDb2RlTWlycm9yLmlubmVyTW9kZSA9IGZ1bmN0aW9uKG1vZGUsIHN0YXRlKSB7XG4gICAgd2hpbGUgKG1vZGUuaW5uZXJNb2RlKSB7XG4gICAgICB2YXIgaW5mbyA9IG1vZGUuaW5uZXJNb2RlKHN0YXRlKTtcbiAgICAgIGlmICghaW5mbyB8fCBpbmZvLm1vZGUgPT0gbW9kZSkgYnJlYWs7XG4gICAgICBzdGF0ZSA9IGluZm8uc3RhdGU7XG4gICAgICBtb2RlID0gaW5mby5tb2RlO1xuICAgIH1cbiAgICByZXR1cm4gaW5mbyB8fCB7bW9kZTogbW9kZSwgc3RhdGU6IHN0YXRlfTtcbiAgfTtcblxuICAvLyBTVEFOREFSRCBDT01NQU5EU1xuXG4gIC8vIENvbW1hbmRzIGFyZSBwYXJhbWV0ZXItbGVzcyBhY3Rpb25zIHRoYXQgY2FuIGJlIHBlcmZvcm1lZCBvbiBhblxuICAvLyBlZGl0b3IsIG1vc3RseSB1c2VkIGZvciBrZXliaW5kaW5ncy5cbiAgdmFyIGNvbW1hbmRzID0gQ29kZU1pcnJvci5jb21tYW5kcyA9IHtcbiAgICBzZWxlY3RBbGw6IGZ1bmN0aW9uKGNtKSB7Y20uc2V0U2VsZWN0aW9uKFBvcyhjbS5maXJzdExpbmUoKSwgMCksIFBvcyhjbS5sYXN0TGluZSgpKSwgc2VsX2RvbnRTY3JvbGwpO30sXG4gICAgc2luZ2xlU2VsZWN0aW9uOiBmdW5jdGlvbihjbSkge1xuICAgICAgY20uc2V0U2VsZWN0aW9uKGNtLmdldEN1cnNvcihcImFuY2hvclwiKSwgY20uZ2V0Q3Vyc29yKFwiaGVhZFwiKSwgc2VsX2RvbnRTY3JvbGwpO1xuICAgIH0sXG4gICAga2lsbExpbmU6IGZ1bmN0aW9uKGNtKSB7XG4gICAgICBkZWxldGVOZWFyU2VsZWN0aW9uKGNtLCBmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICBpZiAocmFuZ2UuZW1wdHkoKSkge1xuICAgICAgICAgIHZhciBsZW4gPSBnZXRMaW5lKGNtLmRvYywgcmFuZ2UuaGVhZC5saW5lKS50ZXh0Lmxlbmd0aDtcbiAgICAgICAgICBpZiAocmFuZ2UuaGVhZC5jaCA9PSBsZW4gJiYgcmFuZ2UuaGVhZC5saW5lIDwgY20ubGFzdExpbmUoKSlcbiAgICAgICAgICAgIHJldHVybiB7ZnJvbTogcmFuZ2UuaGVhZCwgdG86IFBvcyhyYW5nZS5oZWFkLmxpbmUgKyAxLCAwKX07XG4gICAgICAgICAgZWxzZVxuICAgICAgICAgICAgcmV0dXJuIHtmcm9tOiByYW5nZS5oZWFkLCB0bzogUG9zKHJhbmdlLmhlYWQubGluZSwgbGVuKX07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIHtmcm9tOiByYW5nZS5mcm9tKCksIHRvOiByYW5nZS50bygpfTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSxcbiAgICBkZWxldGVMaW5lOiBmdW5jdGlvbihjbSkge1xuICAgICAgZGVsZXRlTmVhclNlbGVjdGlvbihjbSwgZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIHtmcm9tOiBQb3MocmFuZ2UuZnJvbSgpLmxpbmUsIDApLFxuICAgICAgICAgICAgICAgIHRvOiBjbGlwUG9zKGNtLmRvYywgUG9zKHJhbmdlLnRvKCkubGluZSArIDEsIDApKX07XG4gICAgICB9KTtcbiAgICB9LFxuICAgIGRlbExpbmVMZWZ0OiBmdW5jdGlvbihjbSkge1xuICAgICAgZGVsZXRlTmVhclNlbGVjdGlvbihjbSwgZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgcmV0dXJuIHtmcm9tOiBQb3MocmFuZ2UuZnJvbSgpLmxpbmUsIDApLCB0bzogcmFuZ2UuZnJvbSgpfTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgZGVsV3JhcHBlZExpbmVMZWZ0OiBmdW5jdGlvbihjbSkge1xuICAgICAgZGVsZXRlTmVhclNlbGVjdGlvbihjbSwgZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgdmFyIHRvcCA9IGNtLmNoYXJDb29yZHMocmFuZ2UuaGVhZCwgXCJkaXZcIikudG9wICsgNTtcbiAgICAgICAgdmFyIGxlZnRQb3MgPSBjbS5jb29yZHNDaGFyKHtsZWZ0OiAwLCB0b3A6IHRvcH0sIFwiZGl2XCIpO1xuICAgICAgICByZXR1cm4ge2Zyb206IGxlZnRQb3MsIHRvOiByYW5nZS5mcm9tKCl9O1xuICAgICAgfSk7XG4gICAgfSxcbiAgICBkZWxXcmFwcGVkTGluZVJpZ2h0OiBmdW5jdGlvbihjbSkge1xuICAgICAgZGVsZXRlTmVhclNlbGVjdGlvbihjbSwgZnVuY3Rpb24ocmFuZ2UpIHtcbiAgICAgICAgdmFyIHRvcCA9IGNtLmNoYXJDb29yZHMocmFuZ2UuaGVhZCwgXCJkaXZcIikudG9wICsgNTtcbiAgICAgICAgdmFyIHJpZ2h0UG9zID0gY20uY29vcmRzQ2hhcih7bGVmdDogY20uZGlzcGxheS5saW5lRGl2Lm9mZnNldFdpZHRoICsgMTAwLCB0b3A6IHRvcH0sIFwiZGl2XCIpO1xuICAgICAgICByZXR1cm4ge2Zyb206IHJhbmdlLmZyb20oKSwgdG86IHJpZ2h0UG9zIH07XG4gICAgICB9KTtcbiAgICB9LFxuICAgIHVuZG86IGZ1bmN0aW9uKGNtKSB7Y20udW5kbygpO30sXG4gICAgcmVkbzogZnVuY3Rpb24oY20pIHtjbS5yZWRvKCk7fSxcbiAgICB1bmRvU2VsZWN0aW9uOiBmdW5jdGlvbihjbSkge2NtLnVuZG9TZWxlY3Rpb24oKTt9LFxuICAgIHJlZG9TZWxlY3Rpb246IGZ1bmN0aW9uKGNtKSB7Y20ucmVkb1NlbGVjdGlvbigpO30sXG4gICAgZ29Eb2NTdGFydDogZnVuY3Rpb24oY20pIHtjbS5leHRlbmRTZWxlY3Rpb24oUG9zKGNtLmZpcnN0TGluZSgpLCAwKSk7fSxcbiAgICBnb0RvY0VuZDogZnVuY3Rpb24oY20pIHtjbS5leHRlbmRTZWxlY3Rpb24oUG9zKGNtLmxhc3RMaW5lKCkpKTt9LFxuICAgIGdvTGluZVN0YXJ0OiBmdW5jdGlvbihjbSkge1xuICAgICAgY20uZXh0ZW5kU2VsZWN0aW9uc0J5KGZ1bmN0aW9uKHJhbmdlKSB7IHJldHVybiBsaW5lU3RhcnQoY20sIHJhbmdlLmhlYWQubGluZSk7IH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge29yaWdpbjogXCIrbW92ZVwiLCBiaWFzOiAxfSk7XG4gICAgfSxcbiAgICBnb0xpbmVTdGFydFNtYXJ0OiBmdW5jdGlvbihjbSkge1xuICAgICAgY20uZXh0ZW5kU2VsZWN0aW9uc0J5KGZ1bmN0aW9uKHJhbmdlKSB7XG4gICAgICAgIHJldHVybiBsaW5lU3RhcnRTbWFydChjbSwgcmFuZ2UuaGVhZCk7XG4gICAgICB9LCB7b3JpZ2luOiBcIittb3ZlXCIsIGJpYXM6IDF9KTtcbiAgICB9LFxuICAgIGdvTGluZUVuZDogZnVuY3Rpb24oY20pIHtcbiAgICAgIGNtLmV4dGVuZFNlbGVjdGlvbnNCeShmdW5jdGlvbihyYW5nZSkgeyByZXR1cm4gbGluZUVuZChjbSwgcmFuZ2UuaGVhZC5saW5lKTsgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7b3JpZ2luOiBcIittb3ZlXCIsIGJpYXM6IC0xfSk7XG4gICAgfSxcbiAgICBnb0xpbmVSaWdodDogZnVuY3Rpb24oY20pIHtcbiAgICAgIGNtLmV4dGVuZFNlbGVjdGlvbnNCeShmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICB2YXIgdG9wID0gY20uY2hhckNvb3JkcyhyYW5nZS5oZWFkLCBcImRpdlwiKS50b3AgKyA1O1xuICAgICAgICByZXR1cm4gY20uY29vcmRzQ2hhcih7bGVmdDogY20uZGlzcGxheS5saW5lRGl2Lm9mZnNldFdpZHRoICsgMTAwLCB0b3A6IHRvcH0sIFwiZGl2XCIpO1xuICAgICAgfSwgc2VsX21vdmUpO1xuICAgIH0sXG4gICAgZ29MaW5lTGVmdDogZnVuY3Rpb24oY20pIHtcbiAgICAgIGNtLmV4dGVuZFNlbGVjdGlvbnNCeShmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICB2YXIgdG9wID0gY20uY2hhckNvb3JkcyhyYW5nZS5oZWFkLCBcImRpdlwiKS50b3AgKyA1O1xuICAgICAgICByZXR1cm4gY20uY29vcmRzQ2hhcih7bGVmdDogMCwgdG9wOiB0b3B9LCBcImRpdlwiKTtcbiAgICAgIH0sIHNlbF9tb3ZlKTtcbiAgICB9LFxuICAgIGdvTGluZUxlZnRTbWFydDogZnVuY3Rpb24oY20pIHtcbiAgICAgIGNtLmV4dGVuZFNlbGVjdGlvbnNCeShmdW5jdGlvbihyYW5nZSkge1xuICAgICAgICB2YXIgdG9wID0gY20uY2hhckNvb3JkcyhyYW5nZS5oZWFkLCBcImRpdlwiKS50b3AgKyA1O1xuICAgICAgICB2YXIgcG9zID0gY20uY29vcmRzQ2hhcih7bGVmdDogMCwgdG9wOiB0b3B9LCBcImRpdlwiKTtcbiAgICAgICAgaWYgKHBvcy5jaCA8IGNtLmdldExpbmUocG9zLmxpbmUpLnNlYXJjaCgvXFxTLykpIHJldHVybiBsaW5lU3RhcnRTbWFydChjbSwgcmFuZ2UuaGVhZCk7XG4gICAgICAgIHJldHVybiBwb3M7XG4gICAgICB9LCBzZWxfbW92ZSk7XG4gICAgfSxcbiAgICBnb0xpbmVVcDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigtMSwgXCJsaW5lXCIpO30sXG4gICAgZ29MaW5lRG93bjogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigxLCBcImxpbmVcIik7fSxcbiAgICBnb1BhZ2VVcDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigtMSwgXCJwYWdlXCIpO30sXG4gICAgZ29QYWdlRG93bjogZnVuY3Rpb24oY20pIHtjbS5tb3ZlVigxLCBcInBhZ2VcIik7fSxcbiAgICBnb0NoYXJMZWZ0OiBmdW5jdGlvbihjbSkge2NtLm1vdmVIKC0xLCBcImNoYXJcIik7fSxcbiAgICBnb0NoYXJSaWdodDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgxLCBcImNoYXJcIik7fSxcbiAgICBnb0NvbHVtbkxlZnQ6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZUgoLTEsIFwiY29sdW1uXCIpO30sXG4gICAgZ29Db2x1bW5SaWdodDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgxLCBcImNvbHVtblwiKTt9LFxuICAgIGdvV29yZExlZnQ6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZUgoLTEsIFwid29yZFwiKTt9LFxuICAgIGdvR3JvdXBSaWdodDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgxLCBcImdyb3VwXCIpO30sXG4gICAgZ29Hcm91cExlZnQ6IGZ1bmN0aW9uKGNtKSB7Y20ubW92ZUgoLTEsIFwiZ3JvdXBcIik7fSxcbiAgICBnb1dvcmRSaWdodDogZnVuY3Rpb24oY20pIHtjbS5tb3ZlSCgxLCBcIndvcmRcIik7fSxcbiAgICBkZWxDaGFyQmVmb3JlOiBmdW5jdGlvbihjbSkge2NtLmRlbGV0ZUgoLTEsIFwiY2hhclwiKTt9LFxuICAgIGRlbENoYXJBZnRlcjogZnVuY3Rpb24oY20pIHtjbS5kZWxldGVIKDEsIFwiY2hhclwiKTt9LFxuICAgIGRlbFdvcmRCZWZvcmU6IGZ1bmN0aW9uKGNtKSB7Y20uZGVsZXRlSCgtMSwgXCJ3b3JkXCIpO30sXG4gICAgZGVsV29yZEFmdGVyOiBmdW5jdGlvbihjbSkge2NtLmRlbGV0ZUgoMSwgXCJ3b3JkXCIpO30sXG4gICAgZGVsR3JvdXBCZWZvcmU6IGZ1bmN0aW9uKGNtKSB7Y20uZGVsZXRlSCgtMSwgXCJncm91cFwiKTt9LFxuICAgIGRlbEdyb3VwQWZ0ZXI6IGZ1bmN0aW9uKGNtKSB7Y20uZGVsZXRlSCgxLCBcImdyb3VwXCIpO30sXG4gICAgaW5kZW50QXV0bzogZnVuY3Rpb24oY20pIHtjbS5pbmRlbnRTZWxlY3Rpb24oXCJzbWFydFwiKTt9LFxuICAgIGluZGVudE1vcmU6IGZ1bmN0aW9uKGNtKSB7Y20uaW5kZW50U2VsZWN0aW9uKFwiYWRkXCIpO30sXG4gICAgaW5kZW50TGVzczogZnVuY3Rpb24oY20pIHtjbS5pbmRlbnRTZWxlY3Rpb24oXCJzdWJ0cmFjdFwiKTt9LFxuICAgIGluc2VydFRhYjogZnVuY3Rpb24oY20pIHtjbS5yZXBsYWNlU2VsZWN0aW9uKFwiXFx0XCIpO30sXG4gICAgaW5zZXJ0U29mdFRhYjogZnVuY3Rpb24oY20pIHtcbiAgICAgIHZhciBzcGFjZXMgPSBbXSwgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKSwgdGFiU2l6ZSA9IGNtLm9wdGlvbnMudGFiU2l6ZTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBwb3MgPSByYW5nZXNbaV0uZnJvbSgpO1xuICAgICAgICB2YXIgY29sID0gY291bnRDb2x1bW4oY20uZ2V0TGluZShwb3MubGluZSksIHBvcy5jaCwgdGFiU2l6ZSk7XG4gICAgICAgIHNwYWNlcy5wdXNoKG5ldyBBcnJheSh0YWJTaXplIC0gY29sICUgdGFiU2l6ZSArIDEpLmpvaW4oXCIgXCIpKTtcbiAgICAgIH1cbiAgICAgIGNtLnJlcGxhY2VTZWxlY3Rpb25zKHNwYWNlcyk7XG4gICAgfSxcbiAgICBkZWZhdWx0VGFiOiBmdW5jdGlvbihjbSkge1xuICAgICAgaWYgKGNtLnNvbWV0aGluZ1NlbGVjdGVkKCkpIGNtLmluZGVudFNlbGVjdGlvbihcImFkZFwiKTtcbiAgICAgIGVsc2UgY20uZXhlY0NvbW1hbmQoXCJpbnNlcnRUYWJcIik7XG4gICAgfSxcbiAgICB0cmFuc3Bvc2VDaGFyczogZnVuY3Rpb24oY20pIHtcbiAgICAgIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgcmFuZ2VzID0gY20ubGlzdFNlbGVjdGlvbnMoKSwgbmV3U2VsID0gW107XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIGN1ciA9IHJhbmdlc1tpXS5oZWFkLCBsaW5lID0gZ2V0TGluZShjbS5kb2MsIGN1ci5saW5lKS50ZXh0O1xuICAgICAgICAgIGlmIChsaW5lKSB7XG4gICAgICAgICAgICBpZiAoY3VyLmNoID09IGxpbmUubGVuZ3RoKSBjdXIgPSBuZXcgUG9zKGN1ci5saW5lLCBjdXIuY2ggLSAxKTtcbiAgICAgICAgICAgIGlmIChjdXIuY2ggPiAwKSB7XG4gICAgICAgICAgICAgIGN1ciA9IG5ldyBQb3MoY3VyLmxpbmUsIGN1ci5jaCArIDEpO1xuICAgICAgICAgICAgICBjbS5yZXBsYWNlUmFuZ2UobGluZS5jaGFyQXQoY3VyLmNoIC0gMSkgKyBsaW5lLmNoYXJBdChjdXIuY2ggLSAyKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFBvcyhjdXIubGluZSwgY3VyLmNoIC0gMiksIGN1ciwgXCIrdHJhbnNwb3NlXCIpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjdXIubGluZSA+IGNtLmRvYy5maXJzdCkge1xuICAgICAgICAgICAgICB2YXIgcHJldiA9IGdldExpbmUoY20uZG9jLCBjdXIubGluZSAtIDEpLnRleHQ7XG4gICAgICAgICAgICAgIGlmIChwcmV2KVxuICAgICAgICAgICAgICAgIGNtLnJlcGxhY2VSYW5nZShsaW5lLmNoYXJBdCgwKSArIFwiXFxuXCIgKyBwcmV2LmNoYXJBdChwcmV2Lmxlbmd0aCAtIDEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQb3MoY3VyLmxpbmUgLSAxLCBwcmV2Lmxlbmd0aCAtIDEpLCBQb3MoY3VyLmxpbmUsIDEpLCBcIit0cmFuc3Bvc2VcIik7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIG5ld1NlbC5wdXNoKG5ldyBSYW5nZShjdXIsIGN1cikpO1xuICAgICAgICB9XG4gICAgICAgIGNtLnNldFNlbGVjdGlvbnMobmV3U2VsKTtcbiAgICAgIH0pO1xuICAgIH0sXG4gICAgbmV3bGluZUFuZEluZGVudDogZnVuY3Rpb24oY20pIHtcbiAgICAgIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkge1xuICAgICAgICB2YXIgbGVuID0gY20ubGlzdFNlbGVjdGlvbnMoKS5sZW5ndGg7XG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyBpKyspIHtcbiAgICAgICAgICB2YXIgcmFuZ2UgPSBjbS5saXN0U2VsZWN0aW9ucygpW2ldO1xuICAgICAgICAgIGNtLnJlcGxhY2VSYW5nZShcIlxcblwiLCByYW5nZS5hbmNob3IsIHJhbmdlLmhlYWQsIFwiK2lucHV0XCIpO1xuICAgICAgICAgIGNtLmluZGVudExpbmUocmFuZ2UuZnJvbSgpLmxpbmUgKyAxLCBudWxsLCB0cnVlKTtcbiAgICAgICAgICBlbnN1cmVDdXJzb3JWaXNpYmxlKGNtKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSxcbiAgICB0b2dnbGVPdmVyd3JpdGU6IGZ1bmN0aW9uKGNtKSB7Y20udG9nZ2xlT3ZlcndyaXRlKCk7fVxuICB9O1xuXG5cbiAgLy8gU1RBTkRBUkQgS0VZTUFQU1xuXG4gIHZhciBrZXlNYXAgPSBDb2RlTWlycm9yLmtleU1hcCA9IHt9O1xuXG4gIGtleU1hcC5iYXNpYyA9IHtcbiAgICBcIkxlZnRcIjogXCJnb0NoYXJMZWZ0XCIsIFwiUmlnaHRcIjogXCJnb0NoYXJSaWdodFwiLCBcIlVwXCI6IFwiZ29MaW5lVXBcIiwgXCJEb3duXCI6IFwiZ29MaW5lRG93blwiLFxuICAgIFwiRW5kXCI6IFwiZ29MaW5lRW5kXCIsIFwiSG9tZVwiOiBcImdvTGluZVN0YXJ0U21hcnRcIiwgXCJQYWdlVXBcIjogXCJnb1BhZ2VVcFwiLCBcIlBhZ2VEb3duXCI6IFwiZ29QYWdlRG93blwiLFxuICAgIFwiRGVsZXRlXCI6IFwiZGVsQ2hhckFmdGVyXCIsIFwiQmFja3NwYWNlXCI6IFwiZGVsQ2hhckJlZm9yZVwiLCBcIlNoaWZ0LUJhY2tzcGFjZVwiOiBcImRlbENoYXJCZWZvcmVcIixcbiAgICBcIlRhYlwiOiBcImRlZmF1bHRUYWJcIiwgXCJTaGlmdC1UYWJcIjogXCJpbmRlbnRBdXRvXCIsXG4gICAgXCJFbnRlclwiOiBcIm5ld2xpbmVBbmRJbmRlbnRcIiwgXCJJbnNlcnRcIjogXCJ0b2dnbGVPdmVyd3JpdGVcIixcbiAgICBcIkVzY1wiOiBcInNpbmdsZVNlbGVjdGlvblwiXG4gIH07XG4gIC8vIE5vdGUgdGhhdCB0aGUgc2F2ZSBhbmQgZmluZC1yZWxhdGVkIGNvbW1hbmRzIGFyZW4ndCBkZWZpbmVkIGJ5XG4gIC8vIGRlZmF1bHQuIFVzZXIgY29kZSBvciBhZGRvbnMgY2FuIGRlZmluZSB0aGVtLiBVbmtub3duIGNvbW1hbmRzXG4gIC8vIGFyZSBzaW1wbHkgaWdub3JlZC5cbiAga2V5TWFwLnBjRGVmYXVsdCA9IHtcbiAgICBcIkN0cmwtQVwiOiBcInNlbGVjdEFsbFwiLCBcIkN0cmwtRFwiOiBcImRlbGV0ZUxpbmVcIiwgXCJDdHJsLVpcIjogXCJ1bmRvXCIsIFwiU2hpZnQtQ3RybC1aXCI6IFwicmVkb1wiLCBcIkN0cmwtWVwiOiBcInJlZG9cIixcbiAgICBcIkN0cmwtSG9tZVwiOiBcImdvRG9jU3RhcnRcIiwgXCJDdHJsLUVuZFwiOiBcImdvRG9jRW5kXCIsIFwiQ3RybC1VcFwiOiBcImdvTGluZVVwXCIsIFwiQ3RybC1Eb3duXCI6IFwiZ29MaW5lRG93blwiLFxuICAgIFwiQ3RybC1MZWZ0XCI6IFwiZ29Hcm91cExlZnRcIiwgXCJDdHJsLVJpZ2h0XCI6IFwiZ29Hcm91cFJpZ2h0XCIsIFwiQWx0LUxlZnRcIjogXCJnb0xpbmVTdGFydFwiLCBcIkFsdC1SaWdodFwiOiBcImdvTGluZUVuZFwiLFxuICAgIFwiQ3RybC1CYWNrc3BhY2VcIjogXCJkZWxHcm91cEJlZm9yZVwiLCBcIkN0cmwtRGVsZXRlXCI6IFwiZGVsR3JvdXBBZnRlclwiLCBcIkN0cmwtU1wiOiBcInNhdmVcIiwgXCJDdHJsLUZcIjogXCJmaW5kXCIsXG4gICAgXCJDdHJsLUdcIjogXCJmaW5kTmV4dFwiLCBcIlNoaWZ0LUN0cmwtR1wiOiBcImZpbmRQcmV2XCIsIFwiU2hpZnQtQ3RybC1GXCI6IFwicmVwbGFjZVwiLCBcIlNoaWZ0LUN0cmwtUlwiOiBcInJlcGxhY2VBbGxcIixcbiAgICBcIkN0cmwtW1wiOiBcImluZGVudExlc3NcIiwgXCJDdHJsLV1cIjogXCJpbmRlbnRNb3JlXCIsXG4gICAgXCJDdHJsLVVcIjogXCJ1bmRvU2VsZWN0aW9uXCIsIFwiU2hpZnQtQ3RybC1VXCI6IFwicmVkb1NlbGVjdGlvblwiLCBcIkFsdC1VXCI6IFwicmVkb1NlbGVjdGlvblwiLFxuICAgIGZhbGx0aHJvdWdoOiBcImJhc2ljXCJcbiAgfTtcbiAgLy8gVmVyeSBiYXNpYyByZWFkbGluZS9lbWFjcy1zdHlsZSBiaW5kaW5ncywgd2hpY2ggYXJlIHN0YW5kYXJkIG9uIE1hYy5cbiAga2V5TWFwLmVtYWNzeSA9IHtcbiAgICBcIkN0cmwtRlwiOiBcImdvQ2hhclJpZ2h0XCIsIFwiQ3RybC1CXCI6IFwiZ29DaGFyTGVmdFwiLCBcIkN0cmwtUFwiOiBcImdvTGluZVVwXCIsIFwiQ3RybC1OXCI6IFwiZ29MaW5lRG93blwiLFxuICAgIFwiQWx0LUZcIjogXCJnb1dvcmRSaWdodFwiLCBcIkFsdC1CXCI6IFwiZ29Xb3JkTGVmdFwiLCBcIkN0cmwtQVwiOiBcImdvTGluZVN0YXJ0XCIsIFwiQ3RybC1FXCI6IFwiZ29MaW5lRW5kXCIsXG4gICAgXCJDdHJsLVZcIjogXCJnb1BhZ2VEb3duXCIsIFwiU2hpZnQtQ3RybC1WXCI6IFwiZ29QYWdlVXBcIiwgXCJDdHJsLURcIjogXCJkZWxDaGFyQWZ0ZXJcIiwgXCJDdHJsLUhcIjogXCJkZWxDaGFyQmVmb3JlXCIsXG4gICAgXCJBbHQtRFwiOiBcImRlbFdvcmRBZnRlclwiLCBcIkFsdC1CYWNrc3BhY2VcIjogXCJkZWxXb3JkQmVmb3JlXCIsIFwiQ3RybC1LXCI6IFwia2lsbExpbmVcIiwgXCJDdHJsLVRcIjogXCJ0cmFuc3Bvc2VDaGFyc1wiXG4gIH07XG4gIGtleU1hcC5tYWNEZWZhdWx0ID0ge1xuICAgIFwiQ21kLUFcIjogXCJzZWxlY3RBbGxcIiwgXCJDbWQtRFwiOiBcImRlbGV0ZUxpbmVcIiwgXCJDbWQtWlwiOiBcInVuZG9cIiwgXCJTaGlmdC1DbWQtWlwiOiBcInJlZG9cIiwgXCJDbWQtWVwiOiBcInJlZG9cIixcbiAgICBcIkNtZC1Ib21lXCI6IFwiZ29Eb2NTdGFydFwiLCBcIkNtZC1VcFwiOiBcImdvRG9jU3RhcnRcIiwgXCJDbWQtRW5kXCI6IFwiZ29Eb2NFbmRcIiwgXCJDbWQtRG93blwiOiBcImdvRG9jRW5kXCIsIFwiQWx0LUxlZnRcIjogXCJnb0dyb3VwTGVmdFwiLFxuICAgIFwiQWx0LVJpZ2h0XCI6IFwiZ29Hcm91cFJpZ2h0XCIsIFwiQ21kLUxlZnRcIjogXCJnb0xpbmVMZWZ0XCIsIFwiQ21kLVJpZ2h0XCI6IFwiZ29MaW5lUmlnaHRcIiwgXCJBbHQtQmFja3NwYWNlXCI6IFwiZGVsR3JvdXBCZWZvcmVcIixcbiAgICBcIkN0cmwtQWx0LUJhY2tzcGFjZVwiOiBcImRlbEdyb3VwQWZ0ZXJcIiwgXCJBbHQtRGVsZXRlXCI6IFwiZGVsR3JvdXBBZnRlclwiLCBcIkNtZC1TXCI6IFwic2F2ZVwiLCBcIkNtZC1GXCI6IFwiZmluZFwiLFxuICAgIFwiQ21kLUdcIjogXCJmaW5kTmV4dFwiLCBcIlNoaWZ0LUNtZC1HXCI6IFwiZmluZFByZXZcIiwgXCJDbWQtQWx0LUZcIjogXCJyZXBsYWNlXCIsIFwiU2hpZnQtQ21kLUFsdC1GXCI6IFwicmVwbGFjZUFsbFwiLFxuICAgIFwiQ21kLVtcIjogXCJpbmRlbnRMZXNzXCIsIFwiQ21kLV1cIjogXCJpbmRlbnRNb3JlXCIsIFwiQ21kLUJhY2tzcGFjZVwiOiBcImRlbFdyYXBwZWRMaW5lTGVmdFwiLCBcIkNtZC1EZWxldGVcIjogXCJkZWxXcmFwcGVkTGluZVJpZ2h0XCIsXG4gICAgXCJDbWQtVVwiOiBcInVuZG9TZWxlY3Rpb25cIiwgXCJTaGlmdC1DbWQtVVwiOiBcInJlZG9TZWxlY3Rpb25cIiwgXCJDdHJsLVVwXCI6IFwiZ29Eb2NTdGFydFwiLCBcIkN0cmwtRG93blwiOiBcImdvRG9jRW5kXCIsXG4gICAgZmFsbHRocm91Z2g6IFtcImJhc2ljXCIsIFwiZW1hY3N5XCJdXG4gIH07XG4gIGtleU1hcFtcImRlZmF1bHRcIl0gPSBtYWMgPyBrZXlNYXAubWFjRGVmYXVsdCA6IGtleU1hcC5wY0RlZmF1bHQ7XG5cbiAgLy8gS0VZTUFQIERJU1BBVENIXG5cbiAgZnVuY3Rpb24gbm9ybWFsaXplS2V5TmFtZShuYW1lKSB7XG4gICAgdmFyIHBhcnRzID0gbmFtZS5zcGxpdCgvLSg/ISQpLyksIG5hbWUgPSBwYXJ0c1twYXJ0cy5sZW5ndGggLSAxXTtcbiAgICB2YXIgYWx0LCBjdHJsLCBzaGlmdCwgY21kO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcGFydHMubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICB2YXIgbW9kID0gcGFydHNbaV07XG4gICAgICBpZiAoL14oY21kfG1ldGF8bSkkL2kudGVzdChtb2QpKSBjbWQgPSB0cnVlO1xuICAgICAgZWxzZSBpZiAoL15hKGx0KT8kL2kudGVzdChtb2QpKSBhbHQgPSB0cnVlO1xuICAgICAgZWxzZSBpZiAoL14oY3xjdHJsfGNvbnRyb2wpJC9pLnRlc3QobW9kKSkgY3RybCA9IHRydWU7XG4gICAgICBlbHNlIGlmICgvXnMoaGlmdCkkL2kudGVzdChtb2QpKSBzaGlmdCA9IHRydWU7XG4gICAgICBlbHNlIHRocm93IG5ldyBFcnJvcihcIlVucmVjb2duaXplZCBtb2RpZmllciBuYW1lOiBcIiArIG1vZCk7XG4gICAgfVxuICAgIGlmIChhbHQpIG5hbWUgPSBcIkFsdC1cIiArIG5hbWU7XG4gICAgaWYgKGN0cmwpIG5hbWUgPSBcIkN0cmwtXCIgKyBuYW1lO1xuICAgIGlmIChjbWQpIG5hbWUgPSBcIkNtZC1cIiArIG5hbWU7XG4gICAgaWYgKHNoaWZ0KSBuYW1lID0gXCJTaGlmdC1cIiArIG5hbWU7XG4gICAgcmV0dXJuIG5hbWU7XG4gIH1cblxuICAvLyBUaGlzIGlzIGEga2x1ZGdlIHRvIGtlZXAga2V5bWFwcyBtb3N0bHkgd29ya2luZyBhcyByYXcgb2JqZWN0c1xuICAvLyAoYmFja3dhcmRzIGNvbXBhdGliaWxpdHkpIHdoaWxlIGF0IHRoZSBzYW1lIHRpbWUgc3VwcG9ydCBmZWF0dXJlc1xuICAvLyBsaWtlIG5vcm1hbGl6YXRpb24gYW5kIG11bHRpLXN0cm9rZSBrZXkgYmluZGluZ3MuIEl0IGNvbXBpbGVzIGFcbiAgLy8gbmV3IG5vcm1hbGl6ZWQga2V5bWFwLCBhbmQgdGhlbiB1cGRhdGVzIHRoZSBvbGQgb2JqZWN0IHRvIHJlZmxlY3RcbiAgLy8gdGhpcy5cbiAgQ29kZU1pcnJvci5ub3JtYWxpemVLZXlNYXAgPSBmdW5jdGlvbihrZXltYXApIHtcbiAgICB2YXIgY29weSA9IHt9O1xuICAgIGZvciAodmFyIGtleW5hbWUgaW4ga2V5bWFwKSBpZiAoa2V5bWFwLmhhc093blByb3BlcnR5KGtleW5hbWUpKSB7XG4gICAgICB2YXIgdmFsdWUgPSBrZXltYXBba2V5bmFtZV07XG4gICAgICBpZiAoL14obmFtZXxmYWxsdGhyb3VnaHwoZGV8YXQpdGFjaCkkLy50ZXN0KGtleW5hbWUpKSBjb250aW51ZTtcbiAgICAgIGlmICh2YWx1ZSA9PSBcIi4uLlwiKSB7IGRlbGV0ZSBrZXltYXBba2V5bmFtZV07IGNvbnRpbnVlOyB9XG5cbiAgICAgIHZhciBrZXlzID0gbWFwKGtleW5hbWUuc3BsaXQoXCIgXCIpLCBub3JtYWxpemVLZXlOYW1lKTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgdmFsLCBuYW1lO1xuICAgICAgICBpZiAoaSA9PSBrZXlzLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgICBuYW1lID0ga2V5bmFtZTtcbiAgICAgICAgICB2YWwgPSB2YWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBuYW1lID0ga2V5cy5zbGljZSgwLCBpICsgMSkuam9pbihcIiBcIik7XG4gICAgICAgICAgdmFsID0gXCIuLi5cIjtcbiAgICAgICAgfVxuICAgICAgICB2YXIgcHJldiA9IGNvcHlbbmFtZV07XG4gICAgICAgIGlmICghcHJldikgY29weVtuYW1lXSA9IHZhbDtcbiAgICAgICAgZWxzZSBpZiAocHJldiAhPSB2YWwpIHRocm93IG5ldyBFcnJvcihcIkluY29uc2lzdGVudCBiaW5kaW5ncyBmb3IgXCIgKyBuYW1lKTtcbiAgICAgIH1cbiAgICAgIGRlbGV0ZSBrZXltYXBba2V5bmFtZV07XG4gICAgfVxuICAgIGZvciAodmFyIHByb3AgaW4gY29weSkga2V5bWFwW3Byb3BdID0gY29weVtwcm9wXTtcbiAgICByZXR1cm4ga2V5bWFwO1xuICB9O1xuXG4gIHZhciBsb29rdXBLZXkgPSBDb2RlTWlycm9yLmxvb2t1cEtleSA9IGZ1bmN0aW9uKGtleSwgbWFwLCBoYW5kbGUsIGNvbnRleHQpIHtcbiAgICBtYXAgPSBnZXRLZXlNYXAobWFwKTtcbiAgICB2YXIgZm91bmQgPSBtYXAuY2FsbCA/IG1hcC5jYWxsKGtleSwgY29udGV4dCkgOiBtYXBba2V5XTtcbiAgICBpZiAoZm91bmQgPT09IGZhbHNlKSByZXR1cm4gXCJub3RoaW5nXCI7XG4gICAgaWYgKGZvdW5kID09PSBcIi4uLlwiKSByZXR1cm4gXCJtdWx0aVwiO1xuICAgIGlmIChmb3VuZCAhPSBudWxsICYmIGhhbmRsZShmb3VuZCkpIHJldHVybiBcImhhbmRsZWRcIjtcblxuICAgIGlmIChtYXAuZmFsbHRocm91Z2gpIHtcbiAgICAgIGlmIChPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwobWFwLmZhbGx0aHJvdWdoKSAhPSBcIltvYmplY3QgQXJyYXldXCIpXG4gICAgICAgIHJldHVybiBsb29rdXBLZXkoa2V5LCBtYXAuZmFsbHRocm91Z2gsIGhhbmRsZSwgY29udGV4dCk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG1hcC5mYWxsdGhyb3VnaC5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgcmVzdWx0ID0gbG9va3VwS2V5KGtleSwgbWFwLmZhbGx0aHJvdWdoW2ldLCBoYW5kbGUsIGNvbnRleHQpO1xuICAgICAgICBpZiAocmVzdWx0KSByZXR1cm4gcmVzdWx0O1xuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICAvLyBNb2RpZmllciBrZXkgcHJlc3NlcyBkb24ndCBjb3VudCBhcyAncmVhbCcga2V5IHByZXNzZXMgZm9yIHRoZVxuICAvLyBwdXJwb3NlIG9mIGtleW1hcCBmYWxsdGhyb3VnaC5cbiAgdmFyIGlzTW9kaWZpZXJLZXkgPSBDb2RlTWlycm9yLmlzTW9kaWZpZXJLZXkgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHZhciBuYW1lID0gdHlwZW9mIHZhbHVlID09IFwic3RyaW5nXCIgPyB2YWx1ZSA6IGtleU5hbWVzW3ZhbHVlLmtleUNvZGVdO1xuICAgIHJldHVybiBuYW1lID09IFwiQ3RybFwiIHx8IG5hbWUgPT0gXCJBbHRcIiB8fCBuYW1lID09IFwiU2hpZnRcIiB8fCBuYW1lID09IFwiTW9kXCI7XG4gIH07XG5cbiAgLy8gTG9vayB1cCB0aGUgbmFtZSBvZiBhIGtleSBhcyBpbmRpY2F0ZWQgYnkgYW4gZXZlbnQgb2JqZWN0LlxuICB2YXIga2V5TmFtZSA9IENvZGVNaXJyb3Iua2V5TmFtZSA9IGZ1bmN0aW9uKGV2ZW50LCBub1NoaWZ0KSB7XG4gICAgaWYgKHByZXN0byAmJiBldmVudC5rZXlDb2RlID09IDM0ICYmIGV2ZW50W1wiY2hhclwiXSkgcmV0dXJuIGZhbHNlO1xuICAgIHZhciBiYXNlID0ga2V5TmFtZXNbZXZlbnQua2V5Q29kZV0sIG5hbWUgPSBiYXNlO1xuICAgIGlmIChuYW1lID09IG51bGwgfHwgZXZlbnQuYWx0R3JhcGhLZXkpIHJldHVybiBmYWxzZTtcbiAgICBpZiAoZXZlbnQuYWx0S2V5ICYmIGJhc2UgIT0gXCJBbHRcIikgbmFtZSA9IFwiQWx0LVwiICsgbmFtZTtcbiAgICBpZiAoKGZsaXBDdHJsQ21kID8gZXZlbnQubWV0YUtleSA6IGV2ZW50LmN0cmxLZXkpICYmIGJhc2UgIT0gXCJDdHJsXCIpIG5hbWUgPSBcIkN0cmwtXCIgKyBuYW1lO1xuICAgIGlmICgoZmxpcEN0cmxDbWQgPyBldmVudC5jdHJsS2V5IDogZXZlbnQubWV0YUtleSkgJiYgYmFzZSAhPSBcIkNtZFwiKSBuYW1lID0gXCJDbWQtXCIgKyBuYW1lO1xuICAgIGlmICghbm9TaGlmdCAmJiBldmVudC5zaGlmdEtleSAmJiBiYXNlICE9IFwiU2hpZnRcIikgbmFtZSA9IFwiU2hpZnQtXCIgKyBuYW1lO1xuICAgIHJldHVybiBuYW1lO1xuICB9O1xuXG4gIGZ1bmN0aW9uIGdldEtleU1hcCh2YWwpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbCA9PSBcInN0cmluZ1wiID8ga2V5TWFwW3ZhbF0gOiB2YWw7XG4gIH1cblxuICAvLyBGUk9NVEVYVEFSRUFcblxuICBDb2RlTWlycm9yLmZyb21UZXh0QXJlYSA9IGZ1bmN0aW9uKHRleHRhcmVhLCBvcHRpb25zKSB7XG4gICAgaWYgKCFvcHRpb25zKSBvcHRpb25zID0ge307XG4gICAgb3B0aW9ucy52YWx1ZSA9IHRleHRhcmVhLnZhbHVlO1xuICAgIGlmICghb3B0aW9ucy50YWJpbmRleCAmJiB0ZXh0YXJlYS50YWJpbmRleClcbiAgICAgIG9wdGlvbnMudGFiaW5kZXggPSB0ZXh0YXJlYS50YWJpbmRleDtcbiAgICBpZiAoIW9wdGlvbnMucGxhY2Vob2xkZXIgJiYgdGV4dGFyZWEucGxhY2Vob2xkZXIpXG4gICAgICBvcHRpb25zLnBsYWNlaG9sZGVyID0gdGV4dGFyZWEucGxhY2Vob2xkZXI7XG4gICAgLy8gU2V0IGF1dG9mb2N1cyB0byB0cnVlIGlmIHRoaXMgdGV4dGFyZWEgaXMgZm9jdXNlZCwgb3IgaWYgaXQgaGFzXG4gICAgLy8gYXV0b2ZvY3VzIGFuZCBubyBvdGhlciBlbGVtZW50IGlzIGZvY3VzZWQuXG4gICAgaWYgKG9wdGlvbnMuYXV0b2ZvY3VzID09IG51bGwpIHtcbiAgICAgIHZhciBoYXNGb2N1cyA9IGFjdGl2ZUVsdCgpO1xuICAgICAgb3B0aW9ucy5hdXRvZm9jdXMgPSBoYXNGb2N1cyA9PSB0ZXh0YXJlYSB8fFxuICAgICAgICB0ZXh0YXJlYS5nZXRBdHRyaWJ1dGUoXCJhdXRvZm9jdXNcIikgIT0gbnVsbCAmJiBoYXNGb2N1cyA9PSBkb2N1bWVudC5ib2R5O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHNhdmUoKSB7dGV4dGFyZWEudmFsdWUgPSBjbS5nZXRWYWx1ZSgpO31cbiAgICBpZiAodGV4dGFyZWEuZm9ybSkge1xuICAgICAgb24odGV4dGFyZWEuZm9ybSwgXCJzdWJtaXRcIiwgc2F2ZSk7XG4gICAgICAvLyBEZXBsb3JhYmxlIGhhY2sgdG8gbWFrZSB0aGUgc3VibWl0IG1ldGhvZCBkbyB0aGUgcmlnaHQgdGhpbmcuXG4gICAgICBpZiAoIW9wdGlvbnMubGVhdmVTdWJtaXRNZXRob2RBbG9uZSkge1xuICAgICAgICB2YXIgZm9ybSA9IHRleHRhcmVhLmZvcm0sIHJlYWxTdWJtaXQgPSBmb3JtLnN1Ym1pdDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICB2YXIgd3JhcHBlZFN1Ym1pdCA9IGZvcm0uc3VibWl0ID0gZnVuY3Rpb24oKSB7XG4gICAgICAgICAgICBzYXZlKCk7XG4gICAgICAgICAgICBmb3JtLnN1Ym1pdCA9IHJlYWxTdWJtaXQ7XG4gICAgICAgICAgICBmb3JtLnN1Ym1pdCgpO1xuICAgICAgICAgICAgZm9ybS5zdWJtaXQgPSB3cmFwcGVkU3VibWl0O1xuICAgICAgICAgIH07XG4gICAgICAgIH0gY2F0Y2goZSkge31cbiAgICAgIH1cbiAgICB9XG5cbiAgICB0ZXh0YXJlYS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG4gICAgdmFyIGNtID0gQ29kZU1pcnJvcihmdW5jdGlvbihub2RlKSB7XG4gICAgICB0ZXh0YXJlYS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShub2RlLCB0ZXh0YXJlYS5uZXh0U2libGluZyk7XG4gICAgfSwgb3B0aW9ucyk7XG4gICAgY20uc2F2ZSA9IHNhdmU7XG4gICAgY20uZ2V0VGV4dEFyZWEgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHRleHRhcmVhOyB9O1xuICAgIGNtLnRvVGV4dEFyZWEgPSBmdW5jdGlvbigpIHtcbiAgICAgIGNtLnRvVGV4dEFyZWEgPSBpc05hTjsgLy8gUHJldmVudCB0aGlzIGZyb20gYmVpbmcgcmFuIHR3aWNlXG4gICAgICBzYXZlKCk7XG4gICAgICB0ZXh0YXJlYS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKGNtLmdldFdyYXBwZXJFbGVtZW50KCkpO1xuICAgICAgdGV4dGFyZWEuc3R5bGUuZGlzcGxheSA9IFwiXCI7XG4gICAgICBpZiAodGV4dGFyZWEuZm9ybSkge1xuICAgICAgICBvZmYodGV4dGFyZWEuZm9ybSwgXCJzdWJtaXRcIiwgc2F2ZSk7XG4gICAgICAgIGlmICh0eXBlb2YgdGV4dGFyZWEuZm9ybS5zdWJtaXQgPT0gXCJmdW5jdGlvblwiKVxuICAgICAgICAgIHRleHRhcmVhLmZvcm0uc3VibWl0ID0gcmVhbFN1Ym1pdDtcbiAgICAgIH1cbiAgICB9O1xuICAgIHJldHVybiBjbTtcbiAgfTtcblxuICAvLyBTVFJJTkcgU1RSRUFNXG5cbiAgLy8gRmVkIHRvIHRoZSBtb2RlIHBhcnNlcnMsIHByb3ZpZGVzIGhlbHBlciBmdW5jdGlvbnMgdG8gbWFrZVxuICAvLyBwYXJzZXJzIG1vcmUgc3VjY2luY3QuXG5cbiAgdmFyIFN0cmluZ1N0cmVhbSA9IENvZGVNaXJyb3IuU3RyaW5nU3RyZWFtID0gZnVuY3Rpb24oc3RyaW5nLCB0YWJTaXplKSB7XG4gICAgdGhpcy5wb3MgPSB0aGlzLnN0YXJ0ID0gMDtcbiAgICB0aGlzLnN0cmluZyA9IHN0cmluZztcbiAgICB0aGlzLnRhYlNpemUgPSB0YWJTaXplIHx8IDg7XG4gICAgdGhpcy5sYXN0Q29sdW1uUG9zID0gdGhpcy5sYXN0Q29sdW1uVmFsdWUgPSAwO1xuICAgIHRoaXMubGluZVN0YXJ0ID0gMDtcbiAgfTtcblxuICBTdHJpbmdTdHJlYW0ucHJvdG90eXBlID0ge1xuICAgIGVvbDogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMucG9zID49IHRoaXMuc3RyaW5nLmxlbmd0aDt9LFxuICAgIHNvbDogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMucG9zID09IHRoaXMubGluZVN0YXJ0O30sXG4gICAgcGVlazogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMuc3RyaW5nLmNoYXJBdCh0aGlzLnBvcykgfHwgdW5kZWZpbmVkO30sXG4gICAgbmV4dDogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5wb3MgPCB0aGlzLnN0cmluZy5sZW5ndGgpXG4gICAgICAgIHJldHVybiB0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MrKyk7XG4gICAgfSxcbiAgICBlYXQ6IGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICB2YXIgY2ggPSB0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MpO1xuICAgICAgaWYgKHR5cGVvZiBtYXRjaCA9PSBcInN0cmluZ1wiKSB2YXIgb2sgPSBjaCA9PSBtYXRjaDtcbiAgICAgIGVsc2UgdmFyIG9rID0gY2ggJiYgKG1hdGNoLnRlc3QgPyBtYXRjaC50ZXN0KGNoKSA6IG1hdGNoKGNoKSk7XG4gICAgICBpZiAob2spIHsrK3RoaXMucG9zOyByZXR1cm4gY2g7fVxuICAgIH0sXG4gICAgZWF0V2hpbGU6IGZ1bmN0aW9uKG1hdGNoKSB7XG4gICAgICB2YXIgc3RhcnQgPSB0aGlzLnBvcztcbiAgICAgIHdoaWxlICh0aGlzLmVhdChtYXRjaCkpe31cbiAgICAgIHJldHVybiB0aGlzLnBvcyA+IHN0YXJ0O1xuICAgIH0sXG4gICAgZWF0U3BhY2U6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHN0YXJ0ID0gdGhpcy5wb3M7XG4gICAgICB3aGlsZSAoL1tcXHNcXHUwMGEwXS8udGVzdCh0aGlzLnN0cmluZy5jaGFyQXQodGhpcy5wb3MpKSkgKyt0aGlzLnBvcztcbiAgICAgIHJldHVybiB0aGlzLnBvcyA+IHN0YXJ0O1xuICAgIH0sXG4gICAgc2tpcFRvRW5kOiBmdW5jdGlvbigpIHt0aGlzLnBvcyA9IHRoaXMuc3RyaW5nLmxlbmd0aDt9LFxuICAgIHNraXBUbzogZnVuY3Rpb24oY2gpIHtcbiAgICAgIHZhciBmb3VuZCA9IHRoaXMuc3RyaW5nLmluZGV4T2YoY2gsIHRoaXMucG9zKTtcbiAgICAgIGlmIChmb3VuZCA+IC0xKSB7dGhpcy5wb3MgPSBmb3VuZDsgcmV0dXJuIHRydWU7fVxuICAgIH0sXG4gICAgYmFja1VwOiBmdW5jdGlvbihuKSB7dGhpcy5wb3MgLT0gbjt9LFxuICAgIGNvbHVtbjogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAodGhpcy5sYXN0Q29sdW1uUG9zIDwgdGhpcy5zdGFydCkge1xuICAgICAgICB0aGlzLmxhc3RDb2x1bW5WYWx1ZSA9IGNvdW50Q29sdW1uKHRoaXMuc3RyaW5nLCB0aGlzLnN0YXJ0LCB0aGlzLnRhYlNpemUsIHRoaXMubGFzdENvbHVtblBvcywgdGhpcy5sYXN0Q29sdW1uVmFsdWUpO1xuICAgICAgICB0aGlzLmxhc3RDb2x1bW5Qb3MgPSB0aGlzLnN0YXJ0O1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMubGFzdENvbHVtblZhbHVlIC0gKHRoaXMubGluZVN0YXJ0ID8gY291bnRDb2x1bW4odGhpcy5zdHJpbmcsIHRoaXMubGluZVN0YXJ0LCB0aGlzLnRhYlNpemUpIDogMCk7XG4gICAgfSxcbiAgICBpbmRlbnRhdGlvbjogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gY291bnRDb2x1bW4odGhpcy5zdHJpbmcsIG51bGwsIHRoaXMudGFiU2l6ZSkgLVxuICAgICAgICAodGhpcy5saW5lU3RhcnQgPyBjb3VudENvbHVtbih0aGlzLnN0cmluZywgdGhpcy5saW5lU3RhcnQsIHRoaXMudGFiU2l6ZSkgOiAwKTtcbiAgICB9LFxuICAgIG1hdGNoOiBmdW5jdGlvbihwYXR0ZXJuLCBjb25zdW1lLCBjYXNlSW5zZW5zaXRpdmUpIHtcbiAgICAgIGlmICh0eXBlb2YgcGF0dGVybiA9PSBcInN0cmluZ1wiKSB7XG4gICAgICAgIHZhciBjYXNlZCA9IGZ1bmN0aW9uKHN0cikge3JldHVybiBjYXNlSW5zZW5zaXRpdmUgPyBzdHIudG9Mb3dlckNhc2UoKSA6IHN0cjt9O1xuICAgICAgICB2YXIgc3Vic3RyID0gdGhpcy5zdHJpbmcuc3Vic3RyKHRoaXMucG9zLCBwYXR0ZXJuLmxlbmd0aCk7XG4gICAgICAgIGlmIChjYXNlZChzdWJzdHIpID09IGNhc2VkKHBhdHRlcm4pKSB7XG4gICAgICAgICAgaWYgKGNvbnN1bWUgIT09IGZhbHNlKSB0aGlzLnBvcyArPSBwYXR0ZXJuLmxlbmd0aDtcbiAgICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIG1hdGNoID0gdGhpcy5zdHJpbmcuc2xpY2UodGhpcy5wb3MpLm1hdGNoKHBhdHRlcm4pO1xuICAgICAgICBpZiAobWF0Y2ggJiYgbWF0Y2guaW5kZXggPiAwKSByZXR1cm4gbnVsbDtcbiAgICAgICAgaWYgKG1hdGNoICYmIGNvbnN1bWUgIT09IGZhbHNlKSB0aGlzLnBvcyArPSBtYXRjaFswXS5sZW5ndGg7XG4gICAgICAgIHJldHVybiBtYXRjaDtcbiAgICAgIH1cbiAgICB9LFxuICAgIGN1cnJlbnQ6IGZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuc3RyaW5nLnNsaWNlKHRoaXMuc3RhcnQsIHRoaXMucG9zKTt9LFxuICAgIGhpZGVGaXJzdENoYXJzOiBmdW5jdGlvbihuLCBpbm5lcikge1xuICAgICAgdGhpcy5saW5lU3RhcnQgKz0gbjtcbiAgICAgIHRyeSB7IHJldHVybiBpbm5lcigpOyB9XG4gICAgICBmaW5hbGx5IHsgdGhpcy5saW5lU3RhcnQgLT0gbjsgfVxuICAgIH1cbiAgfTtcblxuICAvLyBURVhUTUFSS0VSU1xuXG4gIC8vIENyZWF0ZWQgd2l0aCBtYXJrVGV4dCBhbmQgc2V0Qm9va21hcmsgbWV0aG9kcy4gQSBUZXh0TWFya2VyIGlzIGFcbiAgLy8gaGFuZGxlIHRoYXQgY2FuIGJlIHVzZWQgdG8gY2xlYXIgb3IgZmluZCBhIG1hcmtlZCBwb3NpdGlvbiBpbiB0aGVcbiAgLy8gZG9jdW1lbnQuIExpbmUgb2JqZWN0cyBob2xkIGFycmF5cyAobWFya2VkU3BhbnMpIGNvbnRhaW5pbmdcbiAgLy8ge2Zyb20sIHRvLCBtYXJrZXJ9IG9iamVjdCBwb2ludGluZyB0byBzdWNoIG1hcmtlciBvYmplY3RzLCBhbmRcbiAgLy8gaW5kaWNhdGluZyB0aGF0IHN1Y2ggYSBtYXJrZXIgaXMgcHJlc2VudCBvbiB0aGF0IGxpbmUuIE11bHRpcGxlXG4gIC8vIGxpbmVzIG1heSBwb2ludCB0byB0aGUgc2FtZSBtYXJrZXIgd2hlbiBpdCBzcGFucyBhY3Jvc3MgbGluZXMuXG4gIC8vIFRoZSBzcGFucyB3aWxsIGhhdmUgbnVsbCBmb3IgdGhlaXIgZnJvbS90byBwcm9wZXJ0aWVzIHdoZW4gdGhlXG4gIC8vIG1hcmtlciBjb250aW51ZXMgYmV5b25kIHRoZSBzdGFydC9lbmQgb2YgdGhlIGxpbmUuIE1hcmtlcnMgaGF2ZVxuICAvLyBsaW5rcyBiYWNrIHRvIHRoZSBsaW5lcyB0aGV5IGN1cnJlbnRseSB0b3VjaC5cblxuICB2YXIgVGV4dE1hcmtlciA9IENvZGVNaXJyb3IuVGV4dE1hcmtlciA9IGZ1bmN0aW9uKGRvYywgdHlwZSkge1xuICAgIHRoaXMubGluZXMgPSBbXTtcbiAgICB0aGlzLnR5cGUgPSB0eXBlO1xuICAgIHRoaXMuZG9jID0gZG9jO1xuICB9O1xuICBldmVudE1peGluKFRleHRNYXJrZXIpO1xuXG4gIC8vIENsZWFyIHRoZSBtYXJrZXIuXG4gIFRleHRNYXJrZXIucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuZXhwbGljaXRseUNsZWFyZWQpIHJldHVybjtcbiAgICB2YXIgY20gPSB0aGlzLmRvYy5jbSwgd2l0aE9wID0gY20gJiYgIWNtLmN1ck9wO1xuICAgIGlmICh3aXRoT3ApIHN0YXJ0T3BlcmF0aW9uKGNtKTtcbiAgICBpZiAoaGFzSGFuZGxlcih0aGlzLCBcImNsZWFyXCIpKSB7XG4gICAgICB2YXIgZm91bmQgPSB0aGlzLmZpbmQoKTtcbiAgICAgIGlmIChmb3VuZCkgc2lnbmFsTGF0ZXIodGhpcywgXCJjbGVhclwiLCBmb3VuZC5mcm9tLCBmb3VuZC50byk7XG4gICAgfVxuICAgIHZhciBtaW4gPSBudWxsLCBtYXggPSBudWxsO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5saW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIGxpbmUgPSB0aGlzLmxpbmVzW2ldO1xuICAgICAgdmFyIHNwYW4gPSBnZXRNYXJrZWRTcGFuRm9yKGxpbmUubWFya2VkU3BhbnMsIHRoaXMpO1xuICAgICAgaWYgKGNtICYmICF0aGlzLmNvbGxhcHNlZCkgcmVnTGluZUNoYW5nZShjbSwgbGluZU5vKGxpbmUpLCBcInRleHRcIik7XG4gICAgICBlbHNlIGlmIChjbSkge1xuICAgICAgICBpZiAoc3Bhbi50byAhPSBudWxsKSBtYXggPSBsaW5lTm8obGluZSk7XG4gICAgICAgIGlmIChzcGFuLmZyb20gIT0gbnVsbCkgbWluID0gbGluZU5vKGxpbmUpO1xuICAgICAgfVxuICAgICAgbGluZS5tYXJrZWRTcGFucyA9IHJlbW92ZU1hcmtlZFNwYW4obGluZS5tYXJrZWRTcGFucywgc3Bhbik7XG4gICAgICBpZiAoc3Bhbi5mcm9tID09IG51bGwgJiYgdGhpcy5jb2xsYXBzZWQgJiYgIWxpbmVJc0hpZGRlbih0aGlzLmRvYywgbGluZSkgJiYgY20pXG4gICAgICAgIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgdGV4dEhlaWdodChjbS5kaXNwbGF5KSk7XG4gICAgfVxuICAgIGlmIChjbSAmJiB0aGlzLmNvbGxhcHNlZCAmJiAhY20ub3B0aW9ucy5saW5lV3JhcHBpbmcpIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5saW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIHZpc3VhbCA9IHZpc3VhbExpbmUodGhpcy5saW5lc1tpXSksIGxlbiA9IGxpbmVMZW5ndGgodmlzdWFsKTtcbiAgICAgIGlmIChsZW4gPiBjbS5kaXNwbGF5Lm1heExpbmVMZW5ndGgpIHtcbiAgICAgICAgY20uZGlzcGxheS5tYXhMaW5lID0gdmlzdWFsO1xuICAgICAgICBjbS5kaXNwbGF5Lm1heExpbmVMZW5ndGggPSBsZW47XG4gICAgICAgIGNtLmRpc3BsYXkubWF4TGluZUNoYW5nZWQgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtaW4gIT0gbnVsbCAmJiBjbSAmJiB0aGlzLmNvbGxhcHNlZCkgcmVnQ2hhbmdlKGNtLCBtaW4sIG1heCArIDEpO1xuICAgIHRoaXMubGluZXMubGVuZ3RoID0gMDtcbiAgICB0aGlzLmV4cGxpY2l0bHlDbGVhcmVkID0gdHJ1ZTtcbiAgICBpZiAodGhpcy5hdG9taWMgJiYgdGhpcy5kb2MuY2FudEVkaXQpIHtcbiAgICAgIHRoaXMuZG9jLmNhbnRFZGl0ID0gZmFsc2U7XG4gICAgICBpZiAoY20pIHJlQ2hlY2tTZWxlY3Rpb24oY20uZG9jKTtcbiAgICB9XG4gICAgaWYgKGNtKSBzaWduYWxMYXRlcihjbSwgXCJtYXJrZXJDbGVhcmVkXCIsIGNtLCB0aGlzKTtcbiAgICBpZiAod2l0aE9wKSBlbmRPcGVyYXRpb24oY20pO1xuICAgIGlmICh0aGlzLnBhcmVudCkgdGhpcy5wYXJlbnQuY2xlYXIoKTtcbiAgfTtcblxuICAvLyBGaW5kIHRoZSBwb3NpdGlvbiBvZiB0aGUgbWFya2VyIGluIHRoZSBkb2N1bWVudC4gUmV0dXJucyBhIHtmcm9tLFxuICAvLyB0b30gb2JqZWN0IGJ5IGRlZmF1bHQuIFNpZGUgY2FuIGJlIHBhc3NlZCB0byBnZXQgYSBzcGVjaWZpYyBzaWRlXG4gIC8vIC0tIDAgKGJvdGgpLCAtMSAobGVmdCksIG9yIDEgKHJpZ2h0KS4gV2hlbiBsaW5lT2JqIGlzIHRydWUsIHRoZVxuICAvLyBQb3Mgb2JqZWN0cyByZXR1cm5lZCBjb250YWluIGEgbGluZSBvYmplY3QsIHJhdGhlciB0aGFuIGEgbGluZVxuICAvLyBudW1iZXIgKHVzZWQgdG8gcHJldmVudCBsb29raW5nIHVwIHRoZSBzYW1lIGxpbmUgdHdpY2UpLlxuICBUZXh0TWFya2VyLnByb3RvdHlwZS5maW5kID0gZnVuY3Rpb24oc2lkZSwgbGluZU9iaikge1xuICAgIGlmIChzaWRlID09IG51bGwgJiYgdGhpcy50eXBlID09IFwiYm9va21hcmtcIikgc2lkZSA9IDE7XG4gICAgdmFyIGZyb20sIHRvO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgdGhpcy5saW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIGxpbmUgPSB0aGlzLmxpbmVzW2ldO1xuICAgICAgdmFyIHNwYW4gPSBnZXRNYXJrZWRTcGFuRm9yKGxpbmUubWFya2VkU3BhbnMsIHRoaXMpO1xuICAgICAgaWYgKHNwYW4uZnJvbSAhPSBudWxsKSB7XG4gICAgICAgIGZyb20gPSBQb3MobGluZU9iaiA/IGxpbmUgOiBsaW5lTm8obGluZSksIHNwYW4uZnJvbSk7XG4gICAgICAgIGlmIChzaWRlID09IC0xKSByZXR1cm4gZnJvbTtcbiAgICAgIH1cbiAgICAgIGlmIChzcGFuLnRvICE9IG51bGwpIHtcbiAgICAgICAgdG8gPSBQb3MobGluZU9iaiA/IGxpbmUgOiBsaW5lTm8obGluZSksIHNwYW4udG8pO1xuICAgICAgICBpZiAoc2lkZSA9PSAxKSByZXR1cm4gdG87XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmcm9tICYmIHtmcm9tOiBmcm9tLCB0bzogdG99O1xuICB9O1xuXG4gIC8vIFNpZ25hbHMgdGhhdCB0aGUgbWFya2VyJ3Mgd2lkZ2V0IGNoYW5nZWQsIGFuZCBzdXJyb3VuZGluZyBsYXlvdXRcbiAgLy8gc2hvdWxkIGJlIHJlY29tcHV0ZWQuXG4gIFRleHRNYXJrZXIucHJvdG90eXBlLmNoYW5nZWQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgcG9zID0gdGhpcy5maW5kKC0xLCB0cnVlKSwgd2lkZ2V0ID0gdGhpcywgY20gPSB0aGlzLmRvYy5jbTtcbiAgICBpZiAoIXBvcyB8fCAhY20pIHJldHVybjtcbiAgICBydW5Jbk9wKGNtLCBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBsaW5lID0gcG9zLmxpbmUsIGxpbmVOID0gbGluZU5vKHBvcy5saW5lKTtcbiAgICAgIHZhciB2aWV3ID0gZmluZFZpZXdGb3JMaW5lKGNtLCBsaW5lTik7XG4gICAgICBpZiAodmlldykge1xuICAgICAgICBjbGVhckxpbmVNZWFzdXJlbWVudENhY2hlRm9yKHZpZXcpO1xuICAgICAgICBjbS5jdXJPcC5zZWxlY3Rpb25DaGFuZ2VkID0gY20uY3VyT3AuZm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgfVxuICAgICAgY20uY3VyT3AudXBkYXRlTWF4TGluZSA9IHRydWU7XG4gICAgICBpZiAoIWxpbmVJc0hpZGRlbih3aWRnZXQuZG9jLCBsaW5lKSAmJiB3aWRnZXQuaGVpZ2h0ICE9IG51bGwpIHtcbiAgICAgICAgdmFyIG9sZEhlaWdodCA9IHdpZGdldC5oZWlnaHQ7XG4gICAgICAgIHdpZGdldC5oZWlnaHQgPSBudWxsO1xuICAgICAgICB2YXIgZEhlaWdodCA9IHdpZGdldEhlaWdodCh3aWRnZXQpIC0gb2xkSGVpZ2h0O1xuICAgICAgICBpZiAoZEhlaWdodClcbiAgICAgICAgICB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIGxpbmUuaGVpZ2h0ICsgZEhlaWdodCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgVGV4dE1hcmtlci5wcm90b3R5cGUuYXR0YWNoTGluZSA9IGZ1bmN0aW9uKGxpbmUpIHtcbiAgICBpZiAoIXRoaXMubGluZXMubGVuZ3RoICYmIHRoaXMuZG9jLmNtKSB7XG4gICAgICB2YXIgb3AgPSB0aGlzLmRvYy5jbS5jdXJPcDtcbiAgICAgIGlmICghb3AubWF5YmVIaWRkZW5NYXJrZXJzIHx8IGluZGV4T2Yob3AubWF5YmVIaWRkZW5NYXJrZXJzLCB0aGlzKSA9PSAtMSlcbiAgICAgICAgKG9wLm1heWJlVW5oaWRkZW5NYXJrZXJzIHx8IChvcC5tYXliZVVuaGlkZGVuTWFya2VycyA9IFtdKSkucHVzaCh0aGlzKTtcbiAgICB9XG4gICAgdGhpcy5saW5lcy5wdXNoKGxpbmUpO1xuICB9O1xuICBUZXh0TWFya2VyLnByb3RvdHlwZS5kZXRhY2hMaW5lID0gZnVuY3Rpb24obGluZSkge1xuICAgIHRoaXMubGluZXMuc3BsaWNlKGluZGV4T2YodGhpcy5saW5lcywgbGluZSksIDEpO1xuICAgIGlmICghdGhpcy5saW5lcy5sZW5ndGggJiYgdGhpcy5kb2MuY20pIHtcbiAgICAgIHZhciBvcCA9IHRoaXMuZG9jLmNtLmN1ck9wO1xuICAgICAgKG9wLm1heWJlSGlkZGVuTWFya2VycyB8fCAob3AubWF5YmVIaWRkZW5NYXJrZXJzID0gW10pKS5wdXNoKHRoaXMpO1xuICAgIH1cbiAgfTtcblxuICAvLyBDb2xsYXBzZWQgbWFya2VycyBoYXZlIHVuaXF1ZSBpZHMsIGluIG9yZGVyIHRvIGJlIGFibGUgdG8gb3JkZXJcbiAgLy8gdGhlbSwgd2hpY2ggaXMgbmVlZGVkIGZvciB1bmlxdWVseSBkZXRlcm1pbmluZyBhbiBvdXRlciBtYXJrZXJcbiAgLy8gd2hlbiB0aGV5IG92ZXJsYXAgKHRoZXkgbWF5IG5lc3QsIGJ1dCBub3QgcGFydGlhbGx5IG92ZXJsYXApLlxuICB2YXIgbmV4dE1hcmtlcklkID0gMDtcblxuICAvLyBDcmVhdGUgYSBtYXJrZXIsIHdpcmUgaXQgdXAgdG8gdGhlIHJpZ2h0IGxpbmVzLCBhbmRcbiAgZnVuY3Rpb24gbWFya1RleHQoZG9jLCBmcm9tLCB0bywgb3B0aW9ucywgdHlwZSkge1xuICAgIC8vIFNoYXJlZCBtYXJrZXJzIChhY3Jvc3MgbGlua2VkIGRvY3VtZW50cykgYXJlIGhhbmRsZWQgc2VwYXJhdGVseVxuICAgIC8vIChtYXJrVGV4dFNoYXJlZCB3aWxsIGNhbGwgb3V0IHRvIHRoaXMgYWdhaW4sIG9uY2UgcGVyXG4gICAgLy8gZG9jdW1lbnQpLlxuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuc2hhcmVkKSByZXR1cm4gbWFya1RleHRTaGFyZWQoZG9jLCBmcm9tLCB0bywgb3B0aW9ucywgdHlwZSk7XG4gICAgLy8gRW5zdXJlIHdlIGFyZSBpbiBhbiBvcGVyYXRpb24uXG4gICAgaWYgKGRvYy5jbSAmJiAhZG9jLmNtLmN1ck9wKSByZXR1cm4gb3BlcmF0aW9uKGRvYy5jbSwgbWFya1RleHQpKGRvYywgZnJvbSwgdG8sIG9wdGlvbnMsIHR5cGUpO1xuXG4gICAgdmFyIG1hcmtlciA9IG5ldyBUZXh0TWFya2VyKGRvYywgdHlwZSksIGRpZmYgPSBjbXAoZnJvbSwgdG8pO1xuICAgIGlmIChvcHRpb25zKSBjb3B5T2JqKG9wdGlvbnMsIG1hcmtlciwgZmFsc2UpO1xuICAgIC8vIERvbid0IGNvbm5lY3QgZW1wdHkgbWFya2VycyB1bmxlc3MgY2xlYXJXaGVuRW1wdHkgaXMgZmFsc2VcbiAgICBpZiAoZGlmZiA+IDAgfHwgZGlmZiA9PSAwICYmIG1hcmtlci5jbGVhcldoZW5FbXB0eSAhPT0gZmFsc2UpXG4gICAgICByZXR1cm4gbWFya2VyO1xuICAgIGlmIChtYXJrZXIucmVwbGFjZWRXaXRoKSB7XG4gICAgICAvLyBTaG93aW5nIHVwIGFzIGEgd2lkZ2V0IGltcGxpZXMgY29sbGFwc2VkICh3aWRnZXQgcmVwbGFjZXMgdGV4dClcbiAgICAgIG1hcmtlci5jb2xsYXBzZWQgPSB0cnVlO1xuICAgICAgbWFya2VyLndpZGdldE5vZGUgPSBlbHQoXCJzcGFuXCIsIFttYXJrZXIucmVwbGFjZWRXaXRoXSwgXCJDb2RlTWlycm9yLXdpZGdldFwiKTtcbiAgICAgIGlmICghb3B0aW9ucy5oYW5kbGVNb3VzZUV2ZW50cykgbWFya2VyLndpZGdldE5vZGUuc2V0QXR0cmlidXRlKFwiY20taWdub3JlLWV2ZW50c1wiLCBcInRydWVcIik7XG4gICAgICBpZiAob3B0aW9ucy5pbnNlcnRMZWZ0KSBtYXJrZXIud2lkZ2V0Tm9kZS5pbnNlcnRMZWZ0ID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKG1hcmtlci5jb2xsYXBzZWQpIHtcbiAgICAgIGlmIChjb25mbGljdGluZ0NvbGxhcHNlZFJhbmdlKGRvYywgZnJvbS5saW5lLCBmcm9tLCB0bywgbWFya2VyKSB8fFxuICAgICAgICAgIGZyb20ubGluZSAhPSB0by5saW5lICYmIGNvbmZsaWN0aW5nQ29sbGFwc2VkUmFuZ2UoZG9jLCB0by5saW5lLCBmcm9tLCB0bywgbWFya2VyKSlcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSW5zZXJ0aW5nIGNvbGxhcHNlZCBtYXJrZXIgcGFydGlhbGx5IG92ZXJsYXBwaW5nIGFuIGV4aXN0aW5nIG9uZVwiKTtcbiAgICAgIHNhd0NvbGxhcHNlZFNwYW5zID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBpZiAobWFya2VyLmFkZFRvSGlzdG9yeSlcbiAgICAgIGFkZENoYW5nZVRvSGlzdG9yeShkb2MsIHtmcm9tOiBmcm9tLCB0bzogdG8sIG9yaWdpbjogXCJtYXJrVGV4dFwifSwgZG9jLnNlbCwgTmFOKTtcblxuICAgIHZhciBjdXJMaW5lID0gZnJvbS5saW5lLCBjbSA9IGRvYy5jbSwgdXBkYXRlTWF4TGluZTtcbiAgICBkb2MuaXRlcihjdXJMaW5lLCB0by5saW5lICsgMSwgZnVuY3Rpb24obGluZSkge1xuICAgICAgaWYgKGNtICYmIG1hcmtlci5jb2xsYXBzZWQgJiYgIWNtLm9wdGlvbnMubGluZVdyYXBwaW5nICYmIHZpc3VhbExpbmUobGluZSkgPT0gY20uZGlzcGxheS5tYXhMaW5lKVxuICAgICAgICB1cGRhdGVNYXhMaW5lID0gdHJ1ZTtcbiAgICAgIGlmIChtYXJrZXIuY29sbGFwc2VkICYmIGN1ckxpbmUgIT0gZnJvbS5saW5lKSB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIDApO1xuICAgICAgYWRkTWFya2VkU3BhbihsaW5lLCBuZXcgTWFya2VkU3BhbihtYXJrZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ckxpbmUgPT0gZnJvbS5saW5lID8gZnJvbS5jaCA6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1ckxpbmUgPT0gdG8ubGluZSA/IHRvLmNoIDogbnVsbCkpO1xuICAgICAgKytjdXJMaW5lO1xuICAgIH0pO1xuICAgIC8vIGxpbmVJc0hpZGRlbiBkZXBlbmRzIG9uIHRoZSBwcmVzZW5jZSBvZiB0aGUgc3BhbnMsIHNvIG5lZWRzIGEgc2Vjb25kIHBhc3NcbiAgICBpZiAobWFya2VyLmNvbGxhcHNlZCkgZG9jLml0ZXIoZnJvbS5saW5lLCB0by5saW5lICsgMSwgZnVuY3Rpb24obGluZSkge1xuICAgICAgaWYgKGxpbmVJc0hpZGRlbihkb2MsIGxpbmUpKSB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIDApO1xuICAgIH0pO1xuXG4gICAgaWYgKG1hcmtlci5jbGVhck9uRW50ZXIpIG9uKG1hcmtlciwgXCJiZWZvcmVDdXJzb3JFbnRlclwiLCBmdW5jdGlvbigpIHsgbWFya2VyLmNsZWFyKCk7IH0pO1xuXG4gICAgaWYgKG1hcmtlci5yZWFkT25seSkge1xuICAgICAgc2F3UmVhZE9ubHlTcGFucyA9IHRydWU7XG4gICAgICBpZiAoZG9jLmhpc3RvcnkuZG9uZS5sZW5ndGggfHwgZG9jLmhpc3RvcnkudW5kb25lLmxlbmd0aClcbiAgICAgICAgZG9jLmNsZWFySGlzdG9yeSgpO1xuICAgIH1cbiAgICBpZiAobWFya2VyLmNvbGxhcHNlZCkge1xuICAgICAgbWFya2VyLmlkID0gKytuZXh0TWFya2VySWQ7XG4gICAgICBtYXJrZXIuYXRvbWljID0gdHJ1ZTtcbiAgICB9XG4gICAgaWYgKGNtKSB7XG4gICAgICAvLyBTeW5jIGVkaXRvciBzdGF0ZVxuICAgICAgaWYgKHVwZGF0ZU1heExpbmUpIGNtLmN1ck9wLnVwZGF0ZU1heExpbmUgPSB0cnVlO1xuICAgICAgaWYgKG1hcmtlci5jb2xsYXBzZWQpXG4gICAgICAgIHJlZ0NoYW5nZShjbSwgZnJvbS5saW5lLCB0by5saW5lICsgMSk7XG4gICAgICBlbHNlIGlmIChtYXJrZXIuY2xhc3NOYW1lIHx8IG1hcmtlci50aXRsZSB8fCBtYXJrZXIuc3RhcnRTdHlsZSB8fCBtYXJrZXIuZW5kU3R5bGUgfHwgbWFya2VyLmNzcylcbiAgICAgICAgZm9yICh2YXIgaSA9IGZyb20ubGluZTsgaSA8PSB0by5saW5lOyBpKyspIHJlZ0xpbmVDaGFuZ2UoY20sIGksIFwidGV4dFwiKTtcbiAgICAgIGlmIChtYXJrZXIuYXRvbWljKSByZUNoZWNrU2VsZWN0aW9uKGNtLmRvYyk7XG4gICAgICBzaWduYWxMYXRlcihjbSwgXCJtYXJrZXJBZGRlZFwiLCBjbSwgbWFya2VyKTtcbiAgICB9XG4gICAgcmV0dXJuIG1hcmtlcjtcbiAgfVxuXG4gIC8vIFNIQVJFRCBURVhUTUFSS0VSU1xuXG4gIC8vIEEgc2hhcmVkIG1hcmtlciBzcGFucyBtdWx0aXBsZSBsaW5rZWQgZG9jdW1lbnRzLiBJdCBpc1xuICAvLyBpbXBsZW1lbnRlZCBhcyBhIG1ldGEtbWFya2VyLW9iamVjdCBjb250cm9sbGluZyBtdWx0aXBsZSBub3JtYWxcbiAgLy8gbWFya2Vycy5cbiAgdmFyIFNoYXJlZFRleHRNYXJrZXIgPSBDb2RlTWlycm9yLlNoYXJlZFRleHRNYXJrZXIgPSBmdW5jdGlvbihtYXJrZXJzLCBwcmltYXJ5KSB7XG4gICAgdGhpcy5tYXJrZXJzID0gbWFya2VycztcbiAgICB0aGlzLnByaW1hcnkgPSBwcmltYXJ5O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbWFya2Vycy5sZW5ndGg7ICsraSlcbiAgICAgIG1hcmtlcnNbaV0ucGFyZW50ID0gdGhpcztcbiAgfTtcbiAgZXZlbnRNaXhpbihTaGFyZWRUZXh0TWFya2VyKTtcblxuICBTaGFyZWRUZXh0TWFya2VyLnByb3RvdHlwZS5jbGVhciA9IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLmV4cGxpY2l0bHlDbGVhcmVkKSByZXR1cm47XG4gICAgdGhpcy5leHBsaWNpdGx5Q2xlYXJlZCA9IHRydWU7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLm1hcmtlcnMubGVuZ3RoOyArK2kpXG4gICAgICB0aGlzLm1hcmtlcnNbaV0uY2xlYXIoKTtcbiAgICBzaWduYWxMYXRlcih0aGlzLCBcImNsZWFyXCIpO1xuICB9O1xuICBTaGFyZWRUZXh0TWFya2VyLnByb3RvdHlwZS5maW5kID0gZnVuY3Rpb24oc2lkZSwgbGluZU9iaikge1xuICAgIHJldHVybiB0aGlzLnByaW1hcnkuZmluZChzaWRlLCBsaW5lT2JqKTtcbiAgfTtcblxuICBmdW5jdGlvbiBtYXJrVGV4dFNoYXJlZChkb2MsIGZyb20sIHRvLCBvcHRpb25zLCB0eXBlKSB7XG4gICAgb3B0aW9ucyA9IGNvcHlPYmoob3B0aW9ucyk7XG4gICAgb3B0aW9ucy5zaGFyZWQgPSBmYWxzZTtcbiAgICB2YXIgbWFya2VycyA9IFttYXJrVGV4dChkb2MsIGZyb20sIHRvLCBvcHRpb25zLCB0eXBlKV0sIHByaW1hcnkgPSBtYXJrZXJzWzBdO1xuICAgIHZhciB3aWRnZXQgPSBvcHRpb25zLndpZGdldE5vZGU7XG4gICAgbGlua2VkRG9jcyhkb2MsIGZ1bmN0aW9uKGRvYykge1xuICAgICAgaWYgKHdpZGdldCkgb3B0aW9ucy53aWRnZXROb2RlID0gd2lkZ2V0LmNsb25lTm9kZSh0cnVlKTtcbiAgICAgIG1hcmtlcnMucHVzaChtYXJrVGV4dChkb2MsIGNsaXBQb3MoZG9jLCBmcm9tKSwgY2xpcFBvcyhkb2MsIHRvKSwgb3B0aW9ucywgdHlwZSkpO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBkb2MubGlua2VkLmxlbmd0aDsgKytpKVxuICAgICAgICBpZiAoZG9jLmxpbmtlZFtpXS5pc1BhcmVudCkgcmV0dXJuO1xuICAgICAgcHJpbWFyeSA9IGxzdChtYXJrZXJzKTtcbiAgICB9KTtcbiAgICByZXR1cm4gbmV3IFNoYXJlZFRleHRNYXJrZXIobWFya2VycywgcHJpbWFyeSk7XG4gIH1cblxuICBmdW5jdGlvbiBmaW5kU2hhcmVkTWFya2Vycyhkb2MpIHtcbiAgICByZXR1cm4gZG9jLmZpbmRNYXJrcyhQb3MoZG9jLmZpcnN0LCAwKSwgZG9jLmNsaXBQb3MoUG9zKGRvYy5sYXN0TGluZSgpKSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgZnVuY3Rpb24obSkgeyByZXR1cm4gbS5wYXJlbnQ7IH0pO1xuICB9XG5cbiAgZnVuY3Rpb24gY29weVNoYXJlZE1hcmtlcnMoZG9jLCBtYXJrZXJzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbWFya2VyID0gbWFya2Vyc1tpXSwgcG9zID0gbWFya2VyLmZpbmQoKTtcbiAgICAgIHZhciBtRnJvbSA9IGRvYy5jbGlwUG9zKHBvcy5mcm9tKSwgbVRvID0gZG9jLmNsaXBQb3MocG9zLnRvKTtcbiAgICAgIGlmIChjbXAobUZyb20sIG1UbykpIHtcbiAgICAgICAgdmFyIHN1Yk1hcmsgPSBtYXJrVGV4dChkb2MsIG1Gcm9tLCBtVG8sIG1hcmtlci5wcmltYXJ5LCBtYXJrZXIucHJpbWFyeS50eXBlKTtcbiAgICAgICAgbWFya2VyLm1hcmtlcnMucHVzaChzdWJNYXJrKTtcbiAgICAgICAgc3ViTWFyay5wYXJlbnQgPSBtYXJrZXI7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZGV0YWNoU2hhcmVkTWFya2VycyhtYXJrZXJzKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICB2YXIgbWFya2VyID0gbWFya2Vyc1tpXSwgbGlua2VkID0gW21hcmtlci5wcmltYXJ5LmRvY107O1xuICAgICAgbGlua2VkRG9jcyhtYXJrZXIucHJpbWFyeS5kb2MsIGZ1bmN0aW9uKGQpIHsgbGlua2VkLnB1c2goZCk7IH0pO1xuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBtYXJrZXIubWFya2Vycy5sZW5ndGg7IGorKykge1xuICAgICAgICB2YXIgc3ViTWFya2VyID0gbWFya2VyLm1hcmtlcnNbal07XG4gICAgICAgIGlmIChpbmRleE9mKGxpbmtlZCwgc3ViTWFya2VyLmRvYykgPT0gLTEpIHtcbiAgICAgICAgICBzdWJNYXJrZXIucGFyZW50ID0gbnVsbDtcbiAgICAgICAgICBtYXJrZXIubWFya2Vycy5zcGxpY2Uoai0tLCAxKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIFRFWFRNQVJLRVIgU1BBTlNcblxuICBmdW5jdGlvbiBNYXJrZWRTcGFuKG1hcmtlciwgZnJvbSwgdG8pIHtcbiAgICB0aGlzLm1hcmtlciA9IG1hcmtlcjtcbiAgICB0aGlzLmZyb20gPSBmcm9tOyB0aGlzLnRvID0gdG87XG4gIH1cblxuICAvLyBTZWFyY2ggYW4gYXJyYXkgb2Ygc3BhbnMgZm9yIGEgc3BhbiBtYXRjaGluZyB0aGUgZ2l2ZW4gbWFya2VyLlxuICBmdW5jdGlvbiBnZXRNYXJrZWRTcGFuRm9yKHNwYW5zLCBtYXJrZXIpIHtcbiAgICBpZiAoc3BhbnMpIGZvciAodmFyIGkgPSAwOyBpIDwgc3BhbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBzcGFuID0gc3BhbnNbaV07XG4gICAgICBpZiAoc3Bhbi5tYXJrZXIgPT0gbWFya2VyKSByZXR1cm4gc3BhbjtcbiAgICB9XG4gIH1cbiAgLy8gUmVtb3ZlIGEgc3BhbiBmcm9tIGFuIGFycmF5LCByZXR1cm5pbmcgdW5kZWZpbmVkIGlmIG5vIHNwYW5zIGFyZVxuICAvLyBsZWZ0ICh3ZSBkb24ndCBzdG9yZSBhcnJheXMgZm9yIGxpbmVzIHdpdGhvdXQgc3BhbnMpLlxuICBmdW5jdGlvbiByZW1vdmVNYXJrZWRTcGFuKHNwYW5zLCBzcGFuKSB7XG4gICAgZm9yICh2YXIgciwgaSA9IDA7IGkgPCBzcGFucy5sZW5ndGg7ICsraSlcbiAgICAgIGlmIChzcGFuc1tpXSAhPSBzcGFuKSAociB8fCAociA9IFtdKSkucHVzaChzcGFuc1tpXSk7XG4gICAgcmV0dXJuIHI7XG4gIH1cbiAgLy8gQWRkIGEgc3BhbiB0byBhIGxpbmUuXG4gIGZ1bmN0aW9uIGFkZE1hcmtlZFNwYW4obGluZSwgc3Bhbikge1xuICAgIGxpbmUubWFya2VkU3BhbnMgPSBsaW5lLm1hcmtlZFNwYW5zID8gbGluZS5tYXJrZWRTcGFucy5jb25jYXQoW3NwYW5dKSA6IFtzcGFuXTtcbiAgICBzcGFuLm1hcmtlci5hdHRhY2hMaW5lKGxpbmUpO1xuICB9XG5cbiAgLy8gVXNlZCBmb3IgdGhlIGFsZ29yaXRobSB0aGF0IGFkanVzdHMgbWFya2VycyBmb3IgYSBjaGFuZ2UgaW4gdGhlXG4gIC8vIGRvY3VtZW50LiBUaGVzZSBmdW5jdGlvbnMgY3V0IGFuIGFycmF5IG9mIHNwYW5zIGF0IGEgZ2l2ZW5cbiAgLy8gY2hhcmFjdGVyIHBvc2l0aW9uLCByZXR1cm5pbmcgYW4gYXJyYXkgb2YgcmVtYWluaW5nIGNodW5rcyAob3JcbiAgLy8gdW5kZWZpbmVkIGlmIG5vdGhpbmcgcmVtYWlucykuXG4gIGZ1bmN0aW9uIG1hcmtlZFNwYW5zQmVmb3JlKG9sZCwgc3RhcnRDaCwgaXNJbnNlcnQpIHtcbiAgICBpZiAob2xkKSBmb3IgKHZhciBpID0gMCwgbnc7IGkgPCBvbGQubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBzcGFuID0gb2xkW2ldLCBtYXJrZXIgPSBzcGFuLm1hcmtlcjtcbiAgICAgIHZhciBzdGFydHNCZWZvcmUgPSBzcGFuLmZyb20gPT0gbnVsbCB8fCAobWFya2VyLmluY2x1c2l2ZUxlZnQgPyBzcGFuLmZyb20gPD0gc3RhcnRDaCA6IHNwYW4uZnJvbSA8IHN0YXJ0Q2gpO1xuICAgICAgaWYgKHN0YXJ0c0JlZm9yZSB8fCBzcGFuLmZyb20gPT0gc3RhcnRDaCAmJiBtYXJrZXIudHlwZSA9PSBcImJvb2ttYXJrXCIgJiYgKCFpc0luc2VydCB8fCAhc3Bhbi5tYXJrZXIuaW5zZXJ0TGVmdCkpIHtcbiAgICAgICAgdmFyIGVuZHNBZnRlciA9IHNwYW4udG8gPT0gbnVsbCB8fCAobWFya2VyLmluY2x1c2l2ZVJpZ2h0ID8gc3Bhbi50byA+PSBzdGFydENoIDogc3Bhbi50byA+IHN0YXJ0Q2gpO1xuICAgICAgICAobncgfHwgKG53ID0gW10pKS5wdXNoKG5ldyBNYXJrZWRTcGFuKG1hcmtlciwgc3Bhbi5mcm9tLCBlbmRzQWZ0ZXIgPyBudWxsIDogc3Bhbi50bykpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnc7XG4gIH1cbiAgZnVuY3Rpb24gbWFya2VkU3BhbnNBZnRlcihvbGQsIGVuZENoLCBpc0luc2VydCkge1xuICAgIGlmIChvbGQpIGZvciAodmFyIGkgPSAwLCBudzsgaSA8IG9sZC5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIHNwYW4gPSBvbGRbaV0sIG1hcmtlciA9IHNwYW4ubWFya2VyO1xuICAgICAgdmFyIGVuZHNBZnRlciA9IHNwYW4udG8gPT0gbnVsbCB8fCAobWFya2VyLmluY2x1c2l2ZVJpZ2h0ID8gc3Bhbi50byA+PSBlbmRDaCA6IHNwYW4udG8gPiBlbmRDaCk7XG4gICAgICBpZiAoZW5kc0FmdGVyIHx8IHNwYW4uZnJvbSA9PSBlbmRDaCAmJiBtYXJrZXIudHlwZSA9PSBcImJvb2ttYXJrXCIgJiYgKCFpc0luc2VydCB8fCBzcGFuLm1hcmtlci5pbnNlcnRMZWZ0KSkge1xuICAgICAgICB2YXIgc3RhcnRzQmVmb3JlID0gc3Bhbi5mcm9tID09IG51bGwgfHwgKG1hcmtlci5pbmNsdXNpdmVMZWZ0ID8gc3Bhbi5mcm9tIDw9IGVuZENoIDogc3Bhbi5mcm9tIDwgZW5kQ2gpO1xuICAgICAgICAobncgfHwgKG53ID0gW10pKS5wdXNoKG5ldyBNYXJrZWRTcGFuKG1hcmtlciwgc3RhcnRzQmVmb3JlID8gbnVsbCA6IHNwYW4uZnJvbSAtIGVuZENoLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW4udG8gPT0gbnVsbCA/IG51bGwgOiBzcGFuLnRvIC0gZW5kQ2gpKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG53O1xuICB9XG5cbiAgLy8gR2l2ZW4gYSBjaGFuZ2Ugb2JqZWN0LCBjb21wdXRlIHRoZSBuZXcgc2V0IG9mIG1hcmtlciBzcGFucyB0aGF0XG4gIC8vIGNvdmVyIHRoZSBsaW5lIGluIHdoaWNoIHRoZSBjaGFuZ2UgdG9vayBwbGFjZS4gUmVtb3ZlcyBzcGFuc1xuICAvLyBlbnRpcmVseSB3aXRoaW4gdGhlIGNoYW5nZSwgcmVjb25uZWN0cyBzcGFucyBiZWxvbmdpbmcgdG8gdGhlXG4gIC8vIHNhbWUgbWFya2VyIHRoYXQgYXBwZWFyIG9uIGJvdGggc2lkZXMgb2YgdGhlIGNoYW5nZSwgYW5kIGN1dHMgb2ZmXG4gIC8vIHNwYW5zIHBhcnRpYWxseSB3aXRoaW4gdGhlIGNoYW5nZS4gUmV0dXJucyBhbiBhcnJheSBvZiBzcGFuXG4gIC8vIGFycmF5cyB3aXRoIG9uZSBlbGVtZW50IGZvciBlYWNoIGxpbmUgaW4gKGFmdGVyKSB0aGUgY2hhbmdlLlxuICBmdW5jdGlvbiBzdHJldGNoU3BhbnNPdmVyQ2hhbmdlKGRvYywgY2hhbmdlKSB7XG4gICAgaWYgKGNoYW5nZS5mdWxsKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgb2xkRmlyc3QgPSBpc0xpbmUoZG9jLCBjaGFuZ2UuZnJvbS5saW5lKSAmJiBnZXRMaW5lKGRvYywgY2hhbmdlLmZyb20ubGluZSkubWFya2VkU3BhbnM7XG4gICAgdmFyIG9sZExhc3QgPSBpc0xpbmUoZG9jLCBjaGFuZ2UudG8ubGluZSkgJiYgZ2V0TGluZShkb2MsIGNoYW5nZS50by5saW5lKS5tYXJrZWRTcGFucztcbiAgICBpZiAoIW9sZEZpcnN0ICYmICFvbGRMYXN0KSByZXR1cm4gbnVsbDtcblxuICAgIHZhciBzdGFydENoID0gY2hhbmdlLmZyb20uY2gsIGVuZENoID0gY2hhbmdlLnRvLmNoLCBpc0luc2VydCA9IGNtcChjaGFuZ2UuZnJvbSwgY2hhbmdlLnRvKSA9PSAwO1xuICAgIC8vIEdldCB0aGUgc3BhbnMgdGhhdCAnc3RpY2sgb3V0JyBvbiBib3RoIHNpZGVzXG4gICAgdmFyIGZpcnN0ID0gbWFya2VkU3BhbnNCZWZvcmUob2xkRmlyc3QsIHN0YXJ0Q2gsIGlzSW5zZXJ0KTtcbiAgICB2YXIgbGFzdCA9IG1hcmtlZFNwYW5zQWZ0ZXIob2xkTGFzdCwgZW5kQ2gsIGlzSW5zZXJ0KTtcblxuICAgIC8vIE5leHQsIG1lcmdlIHRob3NlIHR3byBlbmRzXG4gICAgdmFyIHNhbWVMaW5lID0gY2hhbmdlLnRleHQubGVuZ3RoID09IDEsIG9mZnNldCA9IGxzdChjaGFuZ2UudGV4dCkubGVuZ3RoICsgKHNhbWVMaW5lID8gc3RhcnRDaCA6IDApO1xuICAgIGlmIChmaXJzdCkge1xuICAgICAgLy8gRml4IHVwIC50byBwcm9wZXJ0aWVzIG9mIGZpcnN0XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpcnN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBzcGFuID0gZmlyc3RbaV07XG4gICAgICAgIGlmIChzcGFuLnRvID09IG51bGwpIHtcbiAgICAgICAgICB2YXIgZm91bmQgPSBnZXRNYXJrZWRTcGFuRm9yKGxhc3QsIHNwYW4ubWFya2VyKTtcbiAgICAgICAgICBpZiAoIWZvdW5kKSBzcGFuLnRvID0gc3RhcnRDaDtcbiAgICAgICAgICBlbHNlIGlmIChzYW1lTGluZSkgc3Bhbi50byA9IGZvdW5kLnRvID09IG51bGwgPyBudWxsIDogZm91bmQudG8gKyBvZmZzZXQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIC8vIEZpeCB1cCAuZnJvbSBpbiBsYXN0IChvciBtb3ZlIHRoZW0gaW50byBmaXJzdCBpbiBjYXNlIG9mIHNhbWVMaW5lKVxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsYXN0Lmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBzcGFuID0gbGFzdFtpXTtcbiAgICAgICAgaWYgKHNwYW4udG8gIT0gbnVsbCkgc3Bhbi50byArPSBvZmZzZXQ7XG4gICAgICAgIGlmIChzcGFuLmZyb20gPT0gbnVsbCkge1xuICAgICAgICAgIHZhciBmb3VuZCA9IGdldE1hcmtlZFNwYW5Gb3IoZmlyc3QsIHNwYW4ubWFya2VyKTtcbiAgICAgICAgICBpZiAoIWZvdW5kKSB7XG4gICAgICAgICAgICBzcGFuLmZyb20gPSBvZmZzZXQ7XG4gICAgICAgICAgICBpZiAoc2FtZUxpbmUpIChmaXJzdCB8fCAoZmlyc3QgPSBbXSkpLnB1c2goc3Bhbik7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHNwYW4uZnJvbSArPSBvZmZzZXQ7XG4gICAgICAgICAgaWYgKHNhbWVMaW5lKSAoZmlyc3QgfHwgKGZpcnN0ID0gW10pKS5wdXNoKHNwYW4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8vIE1ha2Ugc3VyZSB3ZSBkaWRuJ3QgY3JlYXRlIGFueSB6ZXJvLWxlbmd0aCBzcGFuc1xuICAgIGlmIChmaXJzdCkgZmlyc3QgPSBjbGVhckVtcHR5U3BhbnMoZmlyc3QpO1xuICAgIGlmIChsYXN0ICYmIGxhc3QgIT0gZmlyc3QpIGxhc3QgPSBjbGVhckVtcHR5U3BhbnMobGFzdCk7XG5cbiAgICB2YXIgbmV3TWFya2VycyA9IFtmaXJzdF07XG4gICAgaWYgKCFzYW1lTGluZSkge1xuICAgICAgLy8gRmlsbCBnYXAgd2l0aCB3aG9sZS1saW5lLXNwYW5zXG4gICAgICB2YXIgZ2FwID0gY2hhbmdlLnRleHQubGVuZ3RoIC0gMiwgZ2FwTWFya2VycztcbiAgICAgIGlmIChnYXAgPiAwICYmIGZpcnN0KVxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGZpcnN0Lmxlbmd0aDsgKytpKVxuICAgICAgICAgIGlmIChmaXJzdFtpXS50byA9PSBudWxsKVxuICAgICAgICAgICAgKGdhcE1hcmtlcnMgfHwgKGdhcE1hcmtlcnMgPSBbXSkpLnB1c2gobmV3IE1hcmtlZFNwYW4oZmlyc3RbaV0ubWFya2VyLCBudWxsLCBudWxsKSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGdhcDsgKytpKVxuICAgICAgICBuZXdNYXJrZXJzLnB1c2goZ2FwTWFya2Vycyk7XG4gICAgICBuZXdNYXJrZXJzLnB1c2gobGFzdCk7XG4gICAgfVxuICAgIHJldHVybiBuZXdNYXJrZXJzO1xuICB9XG5cbiAgLy8gUmVtb3ZlIHNwYW5zIHRoYXQgYXJlIGVtcHR5IGFuZCBkb24ndCBoYXZlIGEgY2xlYXJXaGVuRW1wdHlcbiAgLy8gb3B0aW9uIG9mIGZhbHNlLlxuICBmdW5jdGlvbiBjbGVhckVtcHR5U3BhbnMoc3BhbnMpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IHNwYW5zLmxlbmd0aDsgKytpKSB7XG4gICAgICB2YXIgc3BhbiA9IHNwYW5zW2ldO1xuICAgICAgaWYgKHNwYW4uZnJvbSAhPSBudWxsICYmIHNwYW4uZnJvbSA9PSBzcGFuLnRvICYmIHNwYW4ubWFya2VyLmNsZWFyV2hlbkVtcHR5ICE9PSBmYWxzZSlcbiAgICAgICAgc3BhbnMuc3BsaWNlKGktLSwgMSk7XG4gICAgfVxuICAgIGlmICghc3BhbnMubGVuZ3RoKSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4gc3BhbnM7XG4gIH1cblxuICAvLyBVc2VkIGZvciB1bi9yZS1kb2luZyBjaGFuZ2VzIGZyb20gdGhlIGhpc3RvcnkuIENvbWJpbmVzIHRoZVxuICAvLyByZXN1bHQgb2YgY29tcHV0aW5nIHRoZSBleGlzdGluZyBzcGFucyB3aXRoIHRoZSBzZXQgb2Ygc3BhbnMgdGhhdFxuICAvLyBleGlzdGVkIGluIHRoZSBoaXN0b3J5IChzbyB0aGF0IGRlbGV0aW5nIGFyb3VuZCBhIHNwYW4gYW5kIHRoZW5cbiAgLy8gdW5kb2luZyBicmluZ3MgYmFjayB0aGUgc3BhbikuXG4gIGZ1bmN0aW9uIG1lcmdlT2xkU3BhbnMoZG9jLCBjaGFuZ2UpIHtcbiAgICB2YXIgb2xkID0gZ2V0T2xkU3BhbnMoZG9jLCBjaGFuZ2UpO1xuICAgIHZhciBzdHJldGNoZWQgPSBzdHJldGNoU3BhbnNPdmVyQ2hhbmdlKGRvYywgY2hhbmdlKTtcbiAgICBpZiAoIW9sZCkgcmV0dXJuIHN0cmV0Y2hlZDtcbiAgICBpZiAoIXN0cmV0Y2hlZCkgcmV0dXJuIG9sZDtcblxuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2xkLmxlbmd0aDsgKytpKSB7XG4gICAgICB2YXIgb2xkQ3VyID0gb2xkW2ldLCBzdHJldGNoQ3VyID0gc3RyZXRjaGVkW2ldO1xuICAgICAgaWYgKG9sZEN1ciAmJiBzdHJldGNoQ3VyKSB7XG4gICAgICAgIHNwYW5zOiBmb3IgKHZhciBqID0gMDsgaiA8IHN0cmV0Y2hDdXIubGVuZ3RoOyArK2opIHtcbiAgICAgICAgICB2YXIgc3BhbiA9IHN0cmV0Y2hDdXJbal07XG4gICAgICAgICAgZm9yICh2YXIgayA9IDA7IGsgPCBvbGRDdXIubGVuZ3RoOyArK2spXG4gICAgICAgICAgICBpZiAob2xkQ3VyW2tdLm1hcmtlciA9PSBzcGFuLm1hcmtlcikgY29udGludWUgc3BhbnM7XG4gICAgICAgICAgb2xkQ3VyLnB1c2goc3Bhbik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoc3RyZXRjaEN1cikge1xuICAgICAgICBvbGRbaV0gPSBzdHJldGNoQ3VyO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gb2xkO1xuICB9XG5cbiAgLy8gVXNlZCB0byAnY2xpcCcgb3V0IHJlYWRPbmx5IHJhbmdlcyB3aGVuIG1ha2luZyBhIGNoYW5nZS5cbiAgZnVuY3Rpb24gcmVtb3ZlUmVhZE9ubHlSYW5nZXMoZG9jLCBmcm9tLCB0bykge1xuICAgIHZhciBtYXJrZXJzID0gbnVsbDtcbiAgICBkb2MuaXRlcihmcm9tLmxpbmUsIHRvLmxpbmUgKyAxLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICBpZiAobGluZS5tYXJrZWRTcGFucykgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lLm1hcmtlZFNwYW5zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBtYXJrID0gbGluZS5tYXJrZWRTcGFuc1tpXS5tYXJrZXI7XG4gICAgICAgIGlmIChtYXJrLnJlYWRPbmx5ICYmICghbWFya2VycyB8fCBpbmRleE9mKG1hcmtlcnMsIG1hcmspID09IC0xKSlcbiAgICAgICAgICAobWFya2VycyB8fCAobWFya2VycyA9IFtdKSkucHVzaChtYXJrKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAoIW1hcmtlcnMpIHJldHVybiBudWxsO1xuICAgIHZhciBwYXJ0cyA9IFt7ZnJvbTogZnJvbSwgdG86IHRvfV07XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBtYXJrZXJzLmxlbmd0aDsgKytpKSB7XG4gICAgICB2YXIgbWsgPSBtYXJrZXJzW2ldLCBtID0gbWsuZmluZCgwKTtcbiAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgcGFydHMubGVuZ3RoOyArK2opIHtcbiAgICAgICAgdmFyIHAgPSBwYXJ0c1tqXTtcbiAgICAgICAgaWYgKGNtcChwLnRvLCBtLmZyb20pIDwgMCB8fCBjbXAocC5mcm9tLCBtLnRvKSA+IDApIGNvbnRpbnVlO1xuICAgICAgICB2YXIgbmV3UGFydHMgPSBbaiwgMV0sIGRmcm9tID0gY21wKHAuZnJvbSwgbS5mcm9tKSwgZHRvID0gY21wKHAudG8sIG0udG8pO1xuICAgICAgICBpZiAoZGZyb20gPCAwIHx8ICFtay5pbmNsdXNpdmVMZWZ0ICYmICFkZnJvbSlcbiAgICAgICAgICBuZXdQYXJ0cy5wdXNoKHtmcm9tOiBwLmZyb20sIHRvOiBtLmZyb219KTtcbiAgICAgICAgaWYgKGR0byA+IDAgfHwgIW1rLmluY2x1c2l2ZVJpZ2h0ICYmICFkdG8pXG4gICAgICAgICAgbmV3UGFydHMucHVzaCh7ZnJvbTogbS50bywgdG86IHAudG99KTtcbiAgICAgICAgcGFydHMuc3BsaWNlLmFwcGx5KHBhcnRzLCBuZXdQYXJ0cyk7XG4gICAgICAgIGogKz0gbmV3UGFydHMubGVuZ3RoIC0gMTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHBhcnRzO1xuICB9XG5cbiAgLy8gQ29ubmVjdCBvciBkaXNjb25uZWN0IHNwYW5zIGZyb20gYSBsaW5lLlxuICBmdW5jdGlvbiBkZXRhY2hNYXJrZWRTcGFucyhsaW5lKSB7XG4gICAgdmFyIHNwYW5zID0gbGluZS5tYXJrZWRTcGFucztcbiAgICBpZiAoIXNwYW5zKSByZXR1cm47XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBzcGFucy5sZW5ndGg7ICsraSlcbiAgICAgIHNwYW5zW2ldLm1hcmtlci5kZXRhY2hMaW5lKGxpbmUpO1xuICAgIGxpbmUubWFya2VkU3BhbnMgPSBudWxsO1xuICB9XG4gIGZ1bmN0aW9uIGF0dGFjaE1hcmtlZFNwYW5zKGxpbmUsIHNwYW5zKSB7XG4gICAgaWYgKCFzcGFucykgcmV0dXJuO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc3BhbnMubGVuZ3RoOyArK2kpXG4gICAgICBzcGFuc1tpXS5tYXJrZXIuYXR0YWNoTGluZShsaW5lKTtcbiAgICBsaW5lLm1hcmtlZFNwYW5zID0gc3BhbnM7XG4gIH1cblxuICAvLyBIZWxwZXJzIHVzZWQgd2hlbiBjb21wdXRpbmcgd2hpY2ggb3ZlcmxhcHBpbmcgY29sbGFwc2VkIHNwYW5cbiAgLy8gY291bnRzIGFzIHRoZSBsYXJnZXIgb25lLlxuICBmdW5jdGlvbiBleHRyYUxlZnQobWFya2VyKSB7IHJldHVybiBtYXJrZXIuaW5jbHVzaXZlTGVmdCA/IC0xIDogMDsgfVxuICBmdW5jdGlvbiBleHRyYVJpZ2h0KG1hcmtlcikgeyByZXR1cm4gbWFya2VyLmluY2x1c2l2ZVJpZ2h0ID8gMSA6IDA7IH1cblxuICAvLyBSZXR1cm5zIGEgbnVtYmVyIGluZGljYXRpbmcgd2hpY2ggb2YgdHdvIG92ZXJsYXBwaW5nIGNvbGxhcHNlZFxuICAvLyBzcGFucyBpcyBsYXJnZXIgKGFuZCB0aHVzIGluY2x1ZGVzIHRoZSBvdGhlcikuIEZhbGxzIGJhY2sgdG9cbiAgLy8gY29tcGFyaW5nIGlkcyB3aGVuIHRoZSBzcGFucyBjb3ZlciBleGFjdGx5IHRoZSBzYW1lIHJhbmdlLlxuICBmdW5jdGlvbiBjb21wYXJlQ29sbGFwc2VkTWFya2VycyhhLCBiKSB7XG4gICAgdmFyIGxlbkRpZmYgPSBhLmxpbmVzLmxlbmd0aCAtIGIubGluZXMubGVuZ3RoO1xuICAgIGlmIChsZW5EaWZmICE9IDApIHJldHVybiBsZW5EaWZmO1xuICAgIHZhciBhUG9zID0gYS5maW5kKCksIGJQb3MgPSBiLmZpbmQoKTtcbiAgICB2YXIgZnJvbUNtcCA9IGNtcChhUG9zLmZyb20sIGJQb3MuZnJvbSkgfHwgZXh0cmFMZWZ0KGEpIC0gZXh0cmFMZWZ0KGIpO1xuICAgIGlmIChmcm9tQ21wKSByZXR1cm4gLWZyb21DbXA7XG4gICAgdmFyIHRvQ21wID0gY21wKGFQb3MudG8sIGJQb3MudG8pIHx8IGV4dHJhUmlnaHQoYSkgLSBleHRyYVJpZ2h0KGIpO1xuICAgIGlmICh0b0NtcCkgcmV0dXJuIHRvQ21wO1xuICAgIHJldHVybiBiLmlkIC0gYS5pZDtcbiAgfVxuXG4gIC8vIEZpbmQgb3V0IHdoZXRoZXIgYSBsaW5lIGVuZHMgb3Igc3RhcnRzIGluIGEgY29sbGFwc2VkIHNwYW4uIElmXG4gIC8vIHNvLCByZXR1cm4gdGhlIG1hcmtlciBmb3IgdGhhdCBzcGFuLlxuICBmdW5jdGlvbiBjb2xsYXBzZWRTcGFuQXRTaWRlKGxpbmUsIHN0YXJ0KSB7XG4gICAgdmFyIHNwcyA9IHNhd0NvbGxhcHNlZFNwYW5zICYmIGxpbmUubWFya2VkU3BhbnMsIGZvdW5kO1xuICAgIGlmIChzcHMpIGZvciAodmFyIHNwLCBpID0gMDsgaSA8IHNwcy5sZW5ndGg7ICsraSkge1xuICAgICAgc3AgPSBzcHNbaV07XG4gICAgICBpZiAoc3AubWFya2VyLmNvbGxhcHNlZCAmJiAoc3RhcnQgPyBzcC5mcm9tIDogc3AudG8pID09IG51bGwgJiZcbiAgICAgICAgICAoIWZvdW5kIHx8IGNvbXBhcmVDb2xsYXBzZWRNYXJrZXJzKGZvdW5kLCBzcC5tYXJrZXIpIDwgMCkpXG4gICAgICAgIGZvdW5kID0gc3AubWFya2VyO1xuICAgIH1cbiAgICByZXR1cm4gZm91bmQ7XG4gIH1cbiAgZnVuY3Rpb24gY29sbGFwc2VkU3BhbkF0U3RhcnQobGluZSkgeyByZXR1cm4gY29sbGFwc2VkU3BhbkF0U2lkZShsaW5lLCB0cnVlKTsgfVxuICBmdW5jdGlvbiBjb2xsYXBzZWRTcGFuQXRFbmQobGluZSkgeyByZXR1cm4gY29sbGFwc2VkU3BhbkF0U2lkZShsaW5lLCBmYWxzZSk7IH1cblxuICAvLyBUZXN0IHdoZXRoZXIgdGhlcmUgZXhpc3RzIGEgY29sbGFwc2VkIHNwYW4gdGhhdCBwYXJ0aWFsbHlcbiAgLy8gb3ZlcmxhcHMgKGNvdmVycyB0aGUgc3RhcnQgb3IgZW5kLCBidXQgbm90IGJvdGgpIG9mIGEgbmV3IHNwYW4uXG4gIC8vIFN1Y2ggb3ZlcmxhcCBpcyBub3QgYWxsb3dlZC5cbiAgZnVuY3Rpb24gY29uZmxpY3RpbmdDb2xsYXBzZWRSYW5nZShkb2MsIGxpbmVObywgZnJvbSwgdG8sIG1hcmtlcikge1xuICAgIHZhciBsaW5lID0gZ2V0TGluZShkb2MsIGxpbmVObyk7XG4gICAgdmFyIHNwcyA9IHNhd0NvbGxhcHNlZFNwYW5zICYmIGxpbmUubWFya2VkU3BhbnM7XG4gICAgaWYgKHNwcykgZm9yICh2YXIgaSA9IDA7IGkgPCBzcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBzcCA9IHNwc1tpXTtcbiAgICAgIGlmICghc3AubWFya2VyLmNvbGxhcHNlZCkgY29udGludWU7XG4gICAgICB2YXIgZm91bmQgPSBzcC5tYXJrZXIuZmluZCgwKTtcbiAgICAgIHZhciBmcm9tQ21wID0gY21wKGZvdW5kLmZyb20sIGZyb20pIHx8IGV4dHJhTGVmdChzcC5tYXJrZXIpIC0gZXh0cmFMZWZ0KG1hcmtlcik7XG4gICAgICB2YXIgdG9DbXAgPSBjbXAoZm91bmQudG8sIHRvKSB8fCBleHRyYVJpZ2h0KHNwLm1hcmtlcikgLSBleHRyYVJpZ2h0KG1hcmtlcik7XG4gICAgICBpZiAoZnJvbUNtcCA+PSAwICYmIHRvQ21wIDw9IDAgfHwgZnJvbUNtcCA8PSAwICYmIHRvQ21wID49IDApIGNvbnRpbnVlO1xuICAgICAgaWYgKGZyb21DbXAgPD0gMCAmJiAoY21wKGZvdW5kLnRvLCBmcm9tKSA+IDAgfHwgKHNwLm1hcmtlci5pbmNsdXNpdmVSaWdodCAmJiBtYXJrZXIuaW5jbHVzaXZlTGVmdCkpIHx8XG4gICAgICAgICAgZnJvbUNtcCA+PSAwICYmIChjbXAoZm91bmQuZnJvbSwgdG8pIDwgMCB8fCAoc3AubWFya2VyLmluY2x1c2l2ZUxlZnQgJiYgbWFya2VyLmluY2x1c2l2ZVJpZ2h0KSkpXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8vIEEgdmlzdWFsIGxpbmUgaXMgYSBsaW5lIGFzIGRyYXduIG9uIHRoZSBzY3JlZW4uIEZvbGRpbmcsIGZvclxuICAvLyBleGFtcGxlLCBjYW4gY2F1c2UgbXVsdGlwbGUgbG9naWNhbCBsaW5lcyB0byBhcHBlYXIgb24gdGhlIHNhbWVcbiAgLy8gdmlzdWFsIGxpbmUuIFRoaXMgZmluZHMgdGhlIHN0YXJ0IG9mIHRoZSB2aXN1YWwgbGluZSB0aGF0IHRoZVxuICAvLyBnaXZlbiBsaW5lIGlzIHBhcnQgb2YgKHVzdWFsbHkgdGhhdCBpcyB0aGUgbGluZSBpdHNlbGYpLlxuICBmdW5jdGlvbiB2aXN1YWxMaW5lKGxpbmUpIHtcbiAgICB2YXIgbWVyZ2VkO1xuICAgIHdoaWxlIChtZXJnZWQgPSBjb2xsYXBzZWRTcGFuQXRTdGFydChsaW5lKSlcbiAgICAgIGxpbmUgPSBtZXJnZWQuZmluZCgtMSwgdHJ1ZSkubGluZTtcbiAgICByZXR1cm4gbGluZTtcbiAgfVxuXG4gIC8vIFJldHVybnMgYW4gYXJyYXkgb2YgbG9naWNhbCBsaW5lcyB0aGF0IGNvbnRpbnVlIHRoZSB2aXN1YWwgbGluZVxuICAvLyBzdGFydGVkIGJ5IHRoZSBhcmd1bWVudCwgb3IgdW5kZWZpbmVkIGlmIHRoZXJlIGFyZSBubyBzdWNoIGxpbmVzLlxuICBmdW5jdGlvbiB2aXN1YWxMaW5lQ29udGludWVkKGxpbmUpIHtcbiAgICB2YXIgbWVyZ2VkLCBsaW5lcztcbiAgICB3aGlsZSAobWVyZ2VkID0gY29sbGFwc2VkU3BhbkF0RW5kKGxpbmUpKSB7XG4gICAgICBsaW5lID0gbWVyZ2VkLmZpbmQoMSwgdHJ1ZSkubGluZTtcbiAgICAgIChsaW5lcyB8fCAobGluZXMgPSBbXSkpLnB1c2gobGluZSk7XG4gICAgfVxuICAgIHJldHVybiBsaW5lcztcbiAgfVxuXG4gIC8vIEdldCB0aGUgbGluZSBudW1iZXIgb2YgdGhlIHN0YXJ0IG9mIHRoZSB2aXN1YWwgbGluZSB0aGF0IHRoZVxuICAvLyBnaXZlbiBsaW5lIG51bWJlciBpcyBwYXJ0IG9mLlxuICBmdW5jdGlvbiB2aXN1YWxMaW5lTm8oZG9jLCBsaW5lTikge1xuICAgIHZhciBsaW5lID0gZ2V0TGluZShkb2MsIGxpbmVOKSwgdmlzID0gdmlzdWFsTGluZShsaW5lKTtcbiAgICBpZiAobGluZSA9PSB2aXMpIHJldHVybiBsaW5lTjtcbiAgICByZXR1cm4gbGluZU5vKHZpcyk7XG4gIH1cbiAgLy8gR2V0IHRoZSBsaW5lIG51bWJlciBvZiB0aGUgc3RhcnQgb2YgdGhlIG5leHQgdmlzdWFsIGxpbmUgYWZ0ZXJcbiAgLy8gdGhlIGdpdmVuIGxpbmUuXG4gIGZ1bmN0aW9uIHZpc3VhbExpbmVFbmRObyhkb2MsIGxpbmVOKSB7XG4gICAgaWYgKGxpbmVOID4gZG9jLmxhc3RMaW5lKCkpIHJldHVybiBsaW5lTjtcbiAgICB2YXIgbGluZSA9IGdldExpbmUoZG9jLCBsaW5lTiksIG1lcmdlZDtcbiAgICBpZiAoIWxpbmVJc0hpZGRlbihkb2MsIGxpbmUpKSByZXR1cm4gbGluZU47XG4gICAgd2hpbGUgKG1lcmdlZCA9IGNvbGxhcHNlZFNwYW5BdEVuZChsaW5lKSlcbiAgICAgIGxpbmUgPSBtZXJnZWQuZmluZCgxLCB0cnVlKS5saW5lO1xuICAgIHJldHVybiBsaW5lTm8obGluZSkgKyAxO1xuICB9XG5cbiAgLy8gQ29tcHV0ZSB3aGV0aGVyIGEgbGluZSBpcyBoaWRkZW4uIExpbmVzIGNvdW50IGFzIGhpZGRlbiB3aGVuIHRoZXlcbiAgLy8gYXJlIHBhcnQgb2YgYSB2aXN1YWwgbGluZSB0aGF0IHN0YXJ0cyB3aXRoIGFub3RoZXIgbGluZSwgb3Igd2hlblxuICAvLyB0aGV5IGFyZSBlbnRpcmVseSBjb3ZlcmVkIGJ5IGNvbGxhcHNlZCwgbm9uLXdpZGdldCBzcGFuLlxuICBmdW5jdGlvbiBsaW5lSXNIaWRkZW4oZG9jLCBsaW5lKSB7XG4gICAgdmFyIHNwcyA9IHNhd0NvbGxhcHNlZFNwYW5zICYmIGxpbmUubWFya2VkU3BhbnM7XG4gICAgaWYgKHNwcykgZm9yICh2YXIgc3AsIGkgPSAwOyBpIDwgc3BzLmxlbmd0aDsgKytpKSB7XG4gICAgICBzcCA9IHNwc1tpXTtcbiAgICAgIGlmICghc3AubWFya2VyLmNvbGxhcHNlZCkgY29udGludWU7XG4gICAgICBpZiAoc3AuZnJvbSA9PSBudWxsKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmIChzcC5tYXJrZXIud2lkZ2V0Tm9kZSkgY29udGludWU7XG4gICAgICBpZiAoc3AuZnJvbSA9PSAwICYmIHNwLm1hcmtlci5pbmNsdXNpdmVMZWZ0ICYmIGxpbmVJc0hpZGRlbklubmVyKGRvYywgbGluZSwgc3ApKVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cbiAgZnVuY3Rpb24gbGluZUlzSGlkZGVuSW5uZXIoZG9jLCBsaW5lLCBzcGFuKSB7XG4gICAgaWYgKHNwYW4udG8gPT0gbnVsbCkge1xuICAgICAgdmFyIGVuZCA9IHNwYW4ubWFya2VyLmZpbmQoMSwgdHJ1ZSk7XG4gICAgICByZXR1cm4gbGluZUlzSGlkZGVuSW5uZXIoZG9jLCBlbmQubGluZSwgZ2V0TWFya2VkU3BhbkZvcihlbmQubGluZS5tYXJrZWRTcGFucywgc3Bhbi5tYXJrZXIpKTtcbiAgICB9XG4gICAgaWYgKHNwYW4ubWFya2VyLmluY2x1c2l2ZVJpZ2h0ICYmIHNwYW4udG8gPT0gbGluZS50ZXh0Lmxlbmd0aClcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIGZvciAodmFyIHNwLCBpID0gMDsgaSA8IGxpbmUubWFya2VkU3BhbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIHNwID0gbGluZS5tYXJrZWRTcGFuc1tpXTtcbiAgICAgIGlmIChzcC5tYXJrZXIuY29sbGFwc2VkICYmICFzcC5tYXJrZXIud2lkZ2V0Tm9kZSAmJiBzcC5mcm9tID09IHNwYW4udG8gJiZcbiAgICAgICAgICAoc3AudG8gPT0gbnVsbCB8fCBzcC50byAhPSBzcGFuLmZyb20pICYmXG4gICAgICAgICAgKHNwLm1hcmtlci5pbmNsdXNpdmVMZWZ0IHx8IHNwYW4ubWFya2VyLmluY2x1c2l2ZVJpZ2h0KSAmJlxuICAgICAgICAgIGxpbmVJc0hpZGRlbklubmVyKGRvYywgbGluZSwgc3ApKSByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gIH1cblxuICAvLyBMSU5FIFdJREdFVFNcblxuICAvLyBMaW5lIHdpZGdldHMgYXJlIGJsb2NrIGVsZW1lbnRzIGRpc3BsYXllZCBhYm92ZSBvciBiZWxvdyBhIGxpbmUuXG5cbiAgdmFyIExpbmVXaWRnZXQgPSBDb2RlTWlycm9yLkxpbmVXaWRnZXQgPSBmdW5jdGlvbihjbSwgbm9kZSwgb3B0aW9ucykge1xuICAgIGlmIChvcHRpb25zKSBmb3IgKHZhciBvcHQgaW4gb3B0aW9ucykgaWYgKG9wdGlvbnMuaGFzT3duUHJvcGVydHkob3B0KSlcbiAgICAgIHRoaXNbb3B0XSA9IG9wdGlvbnNbb3B0XTtcbiAgICB0aGlzLmNtID0gY207XG4gICAgdGhpcy5ub2RlID0gbm9kZTtcbiAgfTtcbiAgZXZlbnRNaXhpbihMaW5lV2lkZ2V0KTtcblxuICBmdW5jdGlvbiBhZGp1c3RTY3JvbGxXaGVuQWJvdmVWaXNpYmxlKGNtLCBsaW5lLCBkaWZmKSB7XG4gICAgaWYgKGhlaWdodEF0TGluZShsaW5lKSA8ICgoY20uY3VyT3AgJiYgY20uY3VyT3Auc2Nyb2xsVG9wKSB8fCBjbS5kb2Muc2Nyb2xsVG9wKSlcbiAgICAgIGFkZFRvU2Nyb2xsUG9zKGNtLCBudWxsLCBkaWZmKTtcbiAgfVxuXG4gIExpbmVXaWRnZXQucHJvdG90eXBlLmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNtID0gdGhpcy5jbSwgd3MgPSB0aGlzLmxpbmUud2lkZ2V0cywgbGluZSA9IHRoaXMubGluZSwgbm8gPSBsaW5lTm8obGluZSk7XG4gICAgaWYgKG5vID09IG51bGwgfHwgIXdzKSByZXR1cm47XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCB3cy5sZW5ndGg7ICsraSkgaWYgKHdzW2ldID09IHRoaXMpIHdzLnNwbGljZShpLS0sIDEpO1xuICAgIGlmICghd3MubGVuZ3RoKSBsaW5lLndpZGdldHMgPSBudWxsO1xuICAgIHZhciBoZWlnaHQgPSB3aWRnZXRIZWlnaHQodGhpcyk7XG4gICAgcnVuSW5PcChjbSwgZnVuY3Rpb24oKSB7XG4gICAgICBhZGp1c3RTY3JvbGxXaGVuQWJvdmVWaXNpYmxlKGNtLCBsaW5lLCAtaGVpZ2h0KTtcbiAgICAgIHJlZ0xpbmVDaGFuZ2UoY20sIG5vLCBcIndpZGdldFwiKTtcbiAgICAgIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgTWF0aC5tYXgoMCwgbGluZS5oZWlnaHQgLSBoZWlnaHQpKTtcbiAgICB9KTtcbiAgfTtcbiAgTGluZVdpZGdldC5wcm90b3R5cGUuY2hhbmdlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciBvbGRIID0gdGhpcy5oZWlnaHQsIGNtID0gdGhpcy5jbSwgbGluZSA9IHRoaXMubGluZTtcbiAgICB0aGlzLmhlaWdodCA9IG51bGw7XG4gICAgdmFyIGRpZmYgPSB3aWRnZXRIZWlnaHQodGhpcykgLSBvbGRIO1xuICAgIGlmICghZGlmZikgcmV0dXJuO1xuICAgIHJ1bkluT3AoY20sIGZ1bmN0aW9uKCkge1xuICAgICAgY20uY3VyT3AuZm9yY2VVcGRhdGUgPSB0cnVlO1xuICAgICAgYWRqdXN0U2Nyb2xsV2hlbkFib3ZlVmlzaWJsZShjbSwgbGluZSwgZGlmZik7XG4gICAgICB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIGxpbmUuaGVpZ2h0ICsgZGlmZik7XG4gICAgfSk7XG4gIH07XG5cbiAgZnVuY3Rpb24gd2lkZ2V0SGVpZ2h0KHdpZGdldCkge1xuICAgIGlmICh3aWRnZXQuaGVpZ2h0ICE9IG51bGwpIHJldHVybiB3aWRnZXQuaGVpZ2h0O1xuICAgIGlmICghY29udGFpbnMoZG9jdW1lbnQuYm9keSwgd2lkZ2V0Lm5vZGUpKSB7XG4gICAgICB2YXIgcGFyZW50U3R5bGUgPSBcInBvc2l0aW9uOiByZWxhdGl2ZTtcIjtcbiAgICAgIGlmICh3aWRnZXQuY292ZXJHdXR0ZXIpXG4gICAgICAgIHBhcmVudFN0eWxlICs9IFwibWFyZ2luLWxlZnQ6IC1cIiArIHdpZGdldC5jbS5kaXNwbGF5Lmd1dHRlcnMub2Zmc2V0V2lkdGggKyBcInB4O1wiO1xuICAgICAgaWYgKHdpZGdldC5ub0hTY3JvbGwpXG4gICAgICAgIHBhcmVudFN0eWxlICs9IFwid2lkdGg6IFwiICsgd2lkZ2V0LmNtLmRpc3BsYXkud3JhcHBlci5jbGllbnRXaWR0aCArIFwicHg7XCI7XG4gICAgICByZW1vdmVDaGlsZHJlbkFuZEFkZCh3aWRnZXQuY20uZGlzcGxheS5tZWFzdXJlLCBlbHQoXCJkaXZcIiwgW3dpZGdldC5ub2RlXSwgbnVsbCwgcGFyZW50U3R5bGUpKTtcbiAgICB9XG4gICAgcmV0dXJuIHdpZGdldC5oZWlnaHQgPSB3aWRnZXQubm9kZS5vZmZzZXRIZWlnaHQ7XG4gIH1cblxuICBmdW5jdGlvbiBhZGRMaW5lV2lkZ2V0KGNtLCBoYW5kbGUsIG5vZGUsIG9wdGlvbnMpIHtcbiAgICB2YXIgd2lkZ2V0ID0gbmV3IExpbmVXaWRnZXQoY20sIG5vZGUsIG9wdGlvbnMpO1xuICAgIGlmICh3aWRnZXQubm9IU2Nyb2xsKSBjbS5kaXNwbGF5LmFsaWduV2lkZ2V0cyA9IHRydWU7XG4gICAgY2hhbmdlTGluZShjbS5kb2MsIGhhbmRsZSwgXCJ3aWRnZXRcIiwgZnVuY3Rpb24obGluZSkge1xuICAgICAgdmFyIHdpZGdldHMgPSBsaW5lLndpZGdldHMgfHwgKGxpbmUud2lkZ2V0cyA9IFtdKTtcbiAgICAgIGlmICh3aWRnZXQuaW5zZXJ0QXQgPT0gbnVsbCkgd2lkZ2V0cy5wdXNoKHdpZGdldCk7XG4gICAgICBlbHNlIHdpZGdldHMuc3BsaWNlKE1hdGgubWluKHdpZGdldHMubGVuZ3RoIC0gMSwgTWF0aC5tYXgoMCwgd2lkZ2V0Lmluc2VydEF0KSksIDAsIHdpZGdldCk7XG4gICAgICB3aWRnZXQubGluZSA9IGxpbmU7XG4gICAgICBpZiAoIWxpbmVJc0hpZGRlbihjbS5kb2MsIGxpbmUpKSB7XG4gICAgICAgIHZhciBhYm92ZVZpc2libGUgPSBoZWlnaHRBdExpbmUobGluZSkgPCBjbS5kb2Muc2Nyb2xsVG9wO1xuICAgICAgICB1cGRhdGVMaW5lSGVpZ2h0KGxpbmUsIGxpbmUuaGVpZ2h0ICsgd2lkZ2V0SGVpZ2h0KHdpZGdldCkpO1xuICAgICAgICBpZiAoYWJvdmVWaXNpYmxlKSBhZGRUb1Njcm9sbFBvcyhjbSwgbnVsbCwgd2lkZ2V0LmhlaWdodCk7XG4gICAgICAgIGNtLmN1ck9wLmZvcmNlVXBkYXRlID0gdHJ1ZTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0pO1xuICAgIHJldHVybiB3aWRnZXQ7XG4gIH1cblxuICAvLyBMSU5FIERBVEEgU1RSVUNUVVJFXG5cbiAgLy8gTGluZSBvYmplY3RzLiBUaGVzZSBob2xkIHN0YXRlIHJlbGF0ZWQgdG8gYSBsaW5lLCBpbmNsdWRpbmdcbiAgLy8gaGlnaGxpZ2h0aW5nIGluZm8gKHRoZSBzdHlsZXMgYXJyYXkpLlxuICB2YXIgTGluZSA9IENvZGVNaXJyb3IuTGluZSA9IGZ1bmN0aW9uKHRleHQsIG1hcmtlZFNwYW5zLCBlc3RpbWF0ZUhlaWdodCkge1xuICAgIHRoaXMudGV4dCA9IHRleHQ7XG4gICAgYXR0YWNoTWFya2VkU3BhbnModGhpcywgbWFya2VkU3BhbnMpO1xuICAgIHRoaXMuaGVpZ2h0ID0gZXN0aW1hdGVIZWlnaHQgPyBlc3RpbWF0ZUhlaWdodCh0aGlzKSA6IDE7XG4gIH07XG4gIGV2ZW50TWl4aW4oTGluZSk7XG4gIExpbmUucHJvdG90eXBlLmxpbmVObyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gbGluZU5vKHRoaXMpOyB9O1xuXG4gIC8vIENoYW5nZSB0aGUgY29udGVudCAodGV4dCwgbWFya2Vycykgb2YgYSBsaW5lLiBBdXRvbWF0aWNhbGx5XG4gIC8vIGludmFsaWRhdGVzIGNhY2hlZCBpbmZvcm1hdGlvbiBhbmQgdHJpZXMgdG8gcmUtZXN0aW1hdGUgdGhlXG4gIC8vIGxpbmUncyBoZWlnaHQuXG4gIGZ1bmN0aW9uIHVwZGF0ZUxpbmUobGluZSwgdGV4dCwgbWFya2VkU3BhbnMsIGVzdGltYXRlSGVpZ2h0KSB7XG4gICAgbGluZS50ZXh0ID0gdGV4dDtcbiAgICBpZiAobGluZS5zdGF0ZUFmdGVyKSBsaW5lLnN0YXRlQWZ0ZXIgPSBudWxsO1xuICAgIGlmIChsaW5lLnN0eWxlcykgbGluZS5zdHlsZXMgPSBudWxsO1xuICAgIGlmIChsaW5lLm9yZGVyICE9IG51bGwpIGxpbmUub3JkZXIgPSBudWxsO1xuICAgIGRldGFjaE1hcmtlZFNwYW5zKGxpbmUpO1xuICAgIGF0dGFjaE1hcmtlZFNwYW5zKGxpbmUsIG1hcmtlZFNwYW5zKTtcbiAgICB2YXIgZXN0SGVpZ2h0ID0gZXN0aW1hdGVIZWlnaHQgPyBlc3RpbWF0ZUhlaWdodChsaW5lKSA6IDE7XG4gICAgaWYgKGVzdEhlaWdodCAhPSBsaW5lLmhlaWdodCkgdXBkYXRlTGluZUhlaWdodChsaW5lLCBlc3RIZWlnaHQpO1xuICB9XG5cbiAgLy8gRGV0YWNoIGEgbGluZSBmcm9tIHRoZSBkb2N1bWVudCB0cmVlIGFuZCBpdHMgbWFya2Vycy5cbiAgZnVuY3Rpb24gY2xlYW5VcExpbmUobGluZSkge1xuICAgIGxpbmUucGFyZW50ID0gbnVsbDtcbiAgICBkZXRhY2hNYXJrZWRTcGFucyhsaW5lKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGV4dHJhY3RMaW5lQ2xhc3Nlcyh0eXBlLCBvdXRwdXQpIHtcbiAgICBpZiAodHlwZSkgZm9yICg7Oykge1xuICAgICAgdmFyIGxpbmVDbGFzcyA9IHR5cGUubWF0Y2goLyg/Ol58XFxzKylsaW5lLShiYWNrZ3JvdW5kLSk/KFxcUyspLyk7XG4gICAgICBpZiAoIWxpbmVDbGFzcykgYnJlYWs7XG4gICAgICB0eXBlID0gdHlwZS5zbGljZSgwLCBsaW5lQ2xhc3MuaW5kZXgpICsgdHlwZS5zbGljZShsaW5lQ2xhc3MuaW5kZXggKyBsaW5lQ2xhc3NbMF0ubGVuZ3RoKTtcbiAgICAgIHZhciBwcm9wID0gbGluZUNsYXNzWzFdID8gXCJiZ0NsYXNzXCIgOiBcInRleHRDbGFzc1wiO1xuICAgICAgaWYgKG91dHB1dFtwcm9wXSA9PSBudWxsKVxuICAgICAgICBvdXRwdXRbcHJvcF0gPSBsaW5lQ2xhc3NbMl07XG4gICAgICBlbHNlIGlmICghKG5ldyBSZWdFeHAoXCIoPzpefFxccylcIiArIGxpbmVDbGFzc1syXSArIFwiKD86JHxcXHMpXCIpKS50ZXN0KG91dHB1dFtwcm9wXSkpXG4gICAgICAgIG91dHB1dFtwcm9wXSArPSBcIiBcIiArIGxpbmVDbGFzc1syXTtcbiAgICB9XG4gICAgcmV0dXJuIHR5cGU7XG4gIH1cblxuICBmdW5jdGlvbiBjYWxsQmxhbmtMaW5lKG1vZGUsIHN0YXRlKSB7XG4gICAgaWYgKG1vZGUuYmxhbmtMaW5lKSByZXR1cm4gbW9kZS5ibGFua0xpbmUoc3RhdGUpO1xuICAgIGlmICghbW9kZS5pbm5lck1vZGUpIHJldHVybjtcbiAgICB2YXIgaW5uZXIgPSBDb2RlTWlycm9yLmlubmVyTW9kZShtb2RlLCBzdGF0ZSk7XG4gICAgaWYgKGlubmVyLm1vZGUuYmxhbmtMaW5lKSByZXR1cm4gaW5uZXIubW9kZS5ibGFua0xpbmUoaW5uZXIuc3RhdGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVhZFRva2VuKG1vZGUsIHN0cmVhbSwgc3RhdGUsIGlubmVyKSB7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxMDsgaSsrKSB7XG4gICAgICBpZiAoaW5uZXIpIGlubmVyWzBdID0gQ29kZU1pcnJvci5pbm5lck1vZGUobW9kZSwgc3RhdGUpLm1vZGU7XG4gICAgICB2YXIgc3R5bGUgPSBtb2RlLnRva2VuKHN0cmVhbSwgc3RhdGUpO1xuICAgICAgaWYgKHN0cmVhbS5wb3MgPiBzdHJlYW0uc3RhcnQpIHJldHVybiBzdHlsZTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiTW9kZSBcIiArIG1vZGUubmFtZSArIFwiIGZhaWxlZCB0byBhZHZhbmNlIHN0cmVhbS5cIik7XG4gIH1cblxuICAvLyBVdGlsaXR5IGZvciBnZXRUb2tlbkF0IGFuZCBnZXRMaW5lVG9rZW5zXG4gIGZ1bmN0aW9uIHRha2VUb2tlbihjbSwgcG9zLCBwcmVjaXNlLCBhc0FycmF5KSB7XG4gICAgZnVuY3Rpb24gZ2V0T2JqKGNvcHkpIHtcbiAgICAgIHJldHVybiB7c3RhcnQ6IHN0cmVhbS5zdGFydCwgZW5kOiBzdHJlYW0ucG9zLFxuICAgICAgICAgICAgICBzdHJpbmc6IHN0cmVhbS5jdXJyZW50KCksXG4gICAgICAgICAgICAgIHR5cGU6IHN0eWxlIHx8IG51bGwsXG4gICAgICAgICAgICAgIHN0YXRlOiBjb3B5ID8gY29weVN0YXRlKGRvYy5tb2RlLCBzdGF0ZSkgOiBzdGF0ZX07XG4gICAgfVxuXG4gICAgdmFyIGRvYyA9IGNtLmRvYywgbW9kZSA9IGRvYy5tb2RlLCBzdHlsZTtcbiAgICBwb3MgPSBjbGlwUG9zKGRvYywgcG9zKTtcbiAgICB2YXIgbGluZSA9IGdldExpbmUoZG9jLCBwb3MubGluZSksIHN0YXRlID0gZ2V0U3RhdGVCZWZvcmUoY20sIHBvcy5saW5lLCBwcmVjaXNlKTtcbiAgICB2YXIgc3RyZWFtID0gbmV3IFN0cmluZ1N0cmVhbShsaW5lLnRleHQsIGNtLm9wdGlvbnMudGFiU2l6ZSksIHRva2VucztcbiAgICBpZiAoYXNBcnJheSkgdG9rZW5zID0gW107XG4gICAgd2hpbGUgKChhc0FycmF5IHx8IHN0cmVhbS5wb3MgPCBwb3MuY2gpICYmICFzdHJlYW0uZW9sKCkpIHtcbiAgICAgIHN0cmVhbS5zdGFydCA9IHN0cmVhbS5wb3M7XG4gICAgICBzdHlsZSA9IHJlYWRUb2tlbihtb2RlLCBzdHJlYW0sIHN0YXRlKTtcbiAgICAgIGlmIChhc0FycmF5KSB0b2tlbnMucHVzaChnZXRPYmoodHJ1ZSkpO1xuICAgIH1cbiAgICByZXR1cm4gYXNBcnJheSA/IHRva2VucyA6IGdldE9iaigpO1xuICB9XG5cbiAgLy8gUnVuIHRoZSBnaXZlbiBtb2RlJ3MgcGFyc2VyIG92ZXIgYSBsaW5lLCBjYWxsaW5nIGYgZm9yIGVhY2ggdG9rZW4uXG4gIGZ1bmN0aW9uIHJ1bk1vZGUoY20sIHRleHQsIG1vZGUsIHN0YXRlLCBmLCBsaW5lQ2xhc3NlcywgZm9yY2VUb0VuZCkge1xuICAgIHZhciBmbGF0dGVuU3BhbnMgPSBtb2RlLmZsYXR0ZW5TcGFucztcbiAgICBpZiAoZmxhdHRlblNwYW5zID09IG51bGwpIGZsYXR0ZW5TcGFucyA9IGNtLm9wdGlvbnMuZmxhdHRlblNwYW5zO1xuICAgIHZhciBjdXJTdGFydCA9IDAsIGN1clN0eWxlID0gbnVsbDtcbiAgICB2YXIgc3RyZWFtID0gbmV3IFN0cmluZ1N0cmVhbSh0ZXh0LCBjbS5vcHRpb25zLnRhYlNpemUpLCBzdHlsZTtcbiAgICB2YXIgaW5uZXIgPSBjbS5vcHRpb25zLmFkZE1vZGVDbGFzcyAmJiBbbnVsbF07XG4gICAgaWYgKHRleHQgPT0gXCJcIikgZXh0cmFjdExpbmVDbGFzc2VzKGNhbGxCbGFua0xpbmUobW9kZSwgc3RhdGUpLCBsaW5lQ2xhc3Nlcyk7XG4gICAgd2hpbGUgKCFzdHJlYW0uZW9sKCkpIHtcbiAgICAgIGlmIChzdHJlYW0ucG9zID4gY20ub3B0aW9ucy5tYXhIaWdobGlnaHRMZW5ndGgpIHtcbiAgICAgICAgZmxhdHRlblNwYW5zID0gZmFsc2U7XG4gICAgICAgIGlmIChmb3JjZVRvRW5kKSBwcm9jZXNzTGluZShjbSwgdGV4dCwgc3RhdGUsIHN0cmVhbS5wb3MpO1xuICAgICAgICBzdHJlYW0ucG9zID0gdGV4dC5sZW5ndGg7XG4gICAgICAgIHN0eWxlID0gbnVsbDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0eWxlID0gZXh0cmFjdExpbmVDbGFzc2VzKHJlYWRUb2tlbihtb2RlLCBzdHJlYW0sIHN0YXRlLCBpbm5lciksIGxpbmVDbGFzc2VzKTtcbiAgICAgIH1cbiAgICAgIGlmIChpbm5lcikge1xuICAgICAgICB2YXIgbU5hbWUgPSBpbm5lclswXS5uYW1lO1xuICAgICAgICBpZiAobU5hbWUpIHN0eWxlID0gXCJtLVwiICsgKHN0eWxlID8gbU5hbWUgKyBcIiBcIiArIHN0eWxlIDogbU5hbWUpO1xuICAgICAgfVxuICAgICAgaWYgKCFmbGF0dGVuU3BhbnMgfHwgY3VyU3R5bGUgIT0gc3R5bGUpIHtcbiAgICAgICAgd2hpbGUgKGN1clN0YXJ0IDwgc3RyZWFtLnN0YXJ0KSB7XG4gICAgICAgICAgY3VyU3RhcnQgPSBNYXRoLm1pbihzdHJlYW0uc3RhcnQsIGN1clN0YXJ0ICsgNTAwMDApO1xuICAgICAgICAgIGYoY3VyU3RhcnQsIGN1clN0eWxlKTtcbiAgICAgICAgfVxuICAgICAgICBjdXJTdHlsZSA9IHN0eWxlO1xuICAgICAgfVxuICAgICAgc3RyZWFtLnN0YXJ0ID0gc3RyZWFtLnBvcztcbiAgICB9XG4gICAgd2hpbGUgKGN1clN0YXJ0IDwgc3RyZWFtLnBvcykge1xuICAgICAgLy8gV2Via2l0IHNlZW1zIHRvIHJlZnVzZSB0byByZW5kZXIgdGV4dCBub2RlcyBsb25nZXIgdGhhbiA1NzQ0NCBjaGFyYWN0ZXJzXG4gICAgICB2YXIgcG9zID0gTWF0aC5taW4oc3RyZWFtLnBvcywgY3VyU3RhcnQgKyA1MDAwMCk7XG4gICAgICBmKHBvcywgY3VyU3R5bGUpO1xuICAgICAgY3VyU3RhcnQgPSBwb3M7XG4gICAgfVxuICB9XG5cbiAgLy8gQ29tcHV0ZSBhIHN0eWxlIGFycmF5IChhbiBhcnJheSBzdGFydGluZyB3aXRoIGEgbW9kZSBnZW5lcmF0aW9uXG4gIC8vIC0tIGZvciBpbnZhbGlkYXRpb24gLS0gZm9sbG93ZWQgYnkgcGFpcnMgb2YgZW5kIHBvc2l0aW9ucyBhbmRcbiAgLy8gc3R5bGUgc3RyaW5ncyksIHdoaWNoIGlzIHVzZWQgdG8gaGlnaGxpZ2h0IHRoZSB0b2tlbnMgb24gdGhlXG4gIC8vIGxpbmUuXG4gIGZ1bmN0aW9uIGhpZ2hsaWdodExpbmUoY20sIGxpbmUsIHN0YXRlLCBmb3JjZVRvRW5kKSB7XG4gICAgLy8gQSBzdHlsZXMgYXJyYXkgYWx3YXlzIHN0YXJ0cyB3aXRoIGEgbnVtYmVyIGlkZW50aWZ5aW5nIHRoZVxuICAgIC8vIG1vZGUvb3ZlcmxheXMgdGhhdCBpdCBpcyBiYXNlZCBvbiAoZm9yIGVhc3kgaW52YWxpZGF0aW9uKS5cbiAgICB2YXIgc3QgPSBbY20uc3RhdGUubW9kZUdlbl0sIGxpbmVDbGFzc2VzID0ge307XG4gICAgLy8gQ29tcHV0ZSB0aGUgYmFzZSBhcnJheSBvZiBzdHlsZXNcbiAgICBydW5Nb2RlKGNtLCBsaW5lLnRleHQsIGNtLmRvYy5tb2RlLCBzdGF0ZSwgZnVuY3Rpb24oZW5kLCBzdHlsZSkge1xuICAgICAgc3QucHVzaChlbmQsIHN0eWxlKTtcbiAgICB9LCBsaW5lQ2xhc3NlcywgZm9yY2VUb0VuZCk7XG5cbiAgICAvLyBSdW4gb3ZlcmxheXMsIGFkanVzdCBzdHlsZSBhcnJheS5cbiAgICBmb3IgKHZhciBvID0gMDsgbyA8IGNtLnN0YXRlLm92ZXJsYXlzLmxlbmd0aDsgKytvKSB7XG4gICAgICB2YXIgb3ZlcmxheSA9IGNtLnN0YXRlLm92ZXJsYXlzW29dLCBpID0gMSwgYXQgPSAwO1xuICAgICAgcnVuTW9kZShjbSwgbGluZS50ZXh0LCBvdmVybGF5Lm1vZGUsIHRydWUsIGZ1bmN0aW9uKGVuZCwgc3R5bGUpIHtcbiAgICAgICAgdmFyIHN0YXJ0ID0gaTtcbiAgICAgICAgLy8gRW5zdXJlIHRoZXJlJ3MgYSB0b2tlbiBlbmQgYXQgdGhlIGN1cnJlbnQgcG9zaXRpb24sIGFuZCB0aGF0IGkgcG9pbnRzIGF0IGl0XG4gICAgICAgIHdoaWxlIChhdCA8IGVuZCkge1xuICAgICAgICAgIHZhciBpX2VuZCA9IHN0W2ldO1xuICAgICAgICAgIGlmIChpX2VuZCA+IGVuZClcbiAgICAgICAgICAgIHN0LnNwbGljZShpLCAxLCBlbmQsIHN0W2krMV0sIGlfZW5kKTtcbiAgICAgICAgICBpICs9IDI7XG4gICAgICAgICAgYXQgPSBNYXRoLm1pbihlbmQsIGlfZW5kKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIXN0eWxlKSByZXR1cm47XG4gICAgICAgIGlmIChvdmVybGF5Lm9wYXF1ZSkge1xuICAgICAgICAgIHN0LnNwbGljZShzdGFydCwgaSAtIHN0YXJ0LCBlbmQsIFwiY20tb3ZlcmxheSBcIiArIHN0eWxlKTtcbiAgICAgICAgICBpID0gc3RhcnQgKyAyO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZvciAoOyBzdGFydCA8IGk7IHN0YXJ0ICs9IDIpIHtcbiAgICAgICAgICAgIHZhciBjdXIgPSBzdFtzdGFydCsxXTtcbiAgICAgICAgICAgIHN0W3N0YXJ0KzFdID0gKGN1ciA/IGN1ciArIFwiIFwiIDogXCJcIikgKyBcImNtLW92ZXJsYXkgXCIgKyBzdHlsZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH0sIGxpbmVDbGFzc2VzKTtcbiAgICB9XG5cbiAgICByZXR1cm4ge3N0eWxlczogc3QsIGNsYXNzZXM6IGxpbmVDbGFzc2VzLmJnQ2xhc3MgfHwgbGluZUNsYXNzZXMudGV4dENsYXNzID8gbGluZUNsYXNzZXMgOiBudWxsfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGdldExpbmVTdHlsZXMoY20sIGxpbmUsIHVwZGF0ZUZyb250aWVyKSB7XG4gICAgaWYgKCFsaW5lLnN0eWxlcyB8fCBsaW5lLnN0eWxlc1swXSAhPSBjbS5zdGF0ZS5tb2RlR2VuKSB7XG4gICAgICB2YXIgcmVzdWx0ID0gaGlnaGxpZ2h0TGluZShjbSwgbGluZSwgbGluZS5zdGF0ZUFmdGVyID0gZ2V0U3RhdGVCZWZvcmUoY20sIGxpbmVObyhsaW5lKSkpO1xuICAgICAgbGluZS5zdHlsZXMgPSByZXN1bHQuc3R5bGVzO1xuICAgICAgaWYgKHJlc3VsdC5jbGFzc2VzKSBsaW5lLnN0eWxlQ2xhc3NlcyA9IHJlc3VsdC5jbGFzc2VzO1xuICAgICAgZWxzZSBpZiAobGluZS5zdHlsZUNsYXNzZXMpIGxpbmUuc3R5bGVDbGFzc2VzID0gbnVsbDtcbiAgICAgIGlmICh1cGRhdGVGcm9udGllciA9PT0gY20uZG9jLmZyb250aWVyKSBjbS5kb2MuZnJvbnRpZXIrKztcbiAgICB9XG4gICAgcmV0dXJuIGxpbmUuc3R5bGVzO1xuICB9XG5cbiAgLy8gTGlnaHR3ZWlnaHQgZm9ybSBvZiBoaWdobGlnaHQgLS0gcHJvY2VlZCBvdmVyIHRoaXMgbGluZSBhbmRcbiAgLy8gdXBkYXRlIHN0YXRlLCBidXQgZG9uJ3Qgc2F2ZSBhIHN0eWxlIGFycmF5LiBVc2VkIGZvciBsaW5lcyB0aGF0XG4gIC8vIGFyZW4ndCBjdXJyZW50bHkgdmlzaWJsZS5cbiAgZnVuY3Rpb24gcHJvY2Vzc0xpbmUoY20sIHRleHQsIHN0YXRlLCBzdGFydEF0KSB7XG4gICAgdmFyIG1vZGUgPSBjbS5kb2MubW9kZTtcbiAgICB2YXIgc3RyZWFtID0gbmV3IFN0cmluZ1N0cmVhbSh0ZXh0LCBjbS5vcHRpb25zLnRhYlNpemUpO1xuICAgIHN0cmVhbS5zdGFydCA9IHN0cmVhbS5wb3MgPSBzdGFydEF0IHx8IDA7XG4gICAgaWYgKHRleHQgPT0gXCJcIikgY2FsbEJsYW5rTGluZShtb2RlLCBzdGF0ZSk7XG4gICAgd2hpbGUgKCFzdHJlYW0uZW9sKCkgJiYgc3RyZWFtLnBvcyA8PSBjbS5vcHRpb25zLm1heEhpZ2hsaWdodExlbmd0aCkge1xuICAgICAgcmVhZFRva2VuKG1vZGUsIHN0cmVhbSwgc3RhdGUpO1xuICAgICAgc3RyZWFtLnN0YXJ0ID0gc3RyZWFtLnBvcztcbiAgICB9XG4gIH1cblxuICAvLyBDb252ZXJ0IGEgc3R5bGUgYXMgcmV0dXJuZWQgYnkgYSBtb2RlIChlaXRoZXIgbnVsbCwgb3IgYSBzdHJpbmdcbiAgLy8gY29udGFpbmluZyBvbmUgb3IgbW9yZSBzdHlsZXMpIHRvIGEgQ1NTIHN0eWxlLiBUaGlzIGlzIGNhY2hlZCxcbiAgLy8gYW5kIGFsc28gbG9va3MgZm9yIGxpbmUtd2lkZSBzdHlsZXMuXG4gIHZhciBzdHlsZVRvQ2xhc3NDYWNoZSA9IHt9LCBzdHlsZVRvQ2xhc3NDYWNoZVdpdGhNb2RlID0ge307XG4gIGZ1bmN0aW9uIGludGVycHJldFRva2VuU3R5bGUoc3R5bGUsIG9wdGlvbnMpIHtcbiAgICBpZiAoIXN0eWxlIHx8IC9eXFxzKiQvLnRlc3Qoc3R5bGUpKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgY2FjaGUgPSBvcHRpb25zLmFkZE1vZGVDbGFzcyA/IHN0eWxlVG9DbGFzc0NhY2hlV2l0aE1vZGUgOiBzdHlsZVRvQ2xhc3NDYWNoZTtcbiAgICByZXR1cm4gY2FjaGVbc3R5bGVdIHx8XG4gICAgICAoY2FjaGVbc3R5bGVdID0gc3R5bGUucmVwbGFjZSgvXFxTKy9nLCBcImNtLSQmXCIpKTtcbiAgfVxuXG4gIC8vIFJlbmRlciB0aGUgRE9NIHJlcHJlc2VudGF0aW9uIG9mIHRoZSB0ZXh0IG9mIGEgbGluZS4gQWxzbyBidWlsZHNcbiAgLy8gdXAgYSAnbGluZSBtYXAnLCB3aGljaCBwb2ludHMgYXQgdGhlIERPTSBub2RlcyB0aGF0IHJlcHJlc2VudFxuICAvLyBzcGVjaWZpYyBzdHJldGNoZXMgb2YgdGV4dCwgYW5kIGlzIHVzZWQgYnkgdGhlIG1lYXN1cmluZyBjb2RlLlxuICAvLyBUaGUgcmV0dXJuZWQgb2JqZWN0IGNvbnRhaW5zIHRoZSBET00gbm9kZSwgdGhpcyBtYXAsIGFuZFxuICAvLyBpbmZvcm1hdGlvbiBhYm91dCBsaW5lLXdpZGUgc3R5bGVzIHRoYXQgd2VyZSBzZXQgYnkgdGhlIG1vZGUuXG4gIGZ1bmN0aW9uIGJ1aWxkTGluZUNvbnRlbnQoY20sIGxpbmVWaWV3KSB7XG4gICAgLy8gVGhlIHBhZGRpbmctcmlnaHQgZm9yY2VzIHRoZSBlbGVtZW50IHRvIGhhdmUgYSAnYm9yZGVyJywgd2hpY2hcbiAgICAvLyBpcyBuZWVkZWQgb24gV2Via2l0IHRvIGJlIGFibGUgdG8gZ2V0IGxpbmUtbGV2ZWwgYm91bmRpbmdcbiAgICAvLyByZWN0YW5nbGVzIGZvciBpdCAoaW4gbWVhc3VyZUNoYXIpLlxuICAgIHZhciBjb250ZW50ID0gZWx0KFwic3BhblwiLCBudWxsLCBudWxsLCB3ZWJraXQgPyBcInBhZGRpbmctcmlnaHQ6IC4xcHhcIiA6IG51bGwpO1xuICAgIHZhciBidWlsZGVyID0ge3ByZTogZWx0KFwicHJlXCIsIFtjb250ZW50XSksIGNvbnRlbnQ6IGNvbnRlbnQsIGNvbDogMCwgcG9zOiAwLCBjbTogY219O1xuICAgIGxpbmVWaWV3Lm1lYXN1cmUgPSB7fTtcblxuICAgIC8vIEl0ZXJhdGUgb3ZlciB0aGUgbG9naWNhbCBsaW5lcyB0aGF0IG1ha2UgdXAgdGhpcyB2aXN1YWwgbGluZS5cbiAgICBmb3IgKHZhciBpID0gMDsgaSA8PSAobGluZVZpZXcucmVzdCA/IGxpbmVWaWV3LnJlc3QubGVuZ3RoIDogMCk7IGkrKykge1xuICAgICAgdmFyIGxpbmUgPSBpID8gbGluZVZpZXcucmVzdFtpIC0gMV0gOiBsaW5lVmlldy5saW5lLCBvcmRlcjtcbiAgICAgIGJ1aWxkZXIucG9zID0gMDtcbiAgICAgIGJ1aWxkZXIuYWRkVG9rZW4gPSBidWlsZFRva2VuO1xuICAgICAgLy8gT3B0aW9uYWxseSB3aXJlIGluIHNvbWUgaGFja3MgaW50byB0aGUgdG9rZW4tcmVuZGVyaW5nXG4gICAgICAvLyBhbGdvcml0aG0sIHRvIGRlYWwgd2l0aCBicm93c2VyIHF1aXJrcy5cbiAgICAgIGlmICgoaWUgfHwgd2Via2l0KSAmJiBjbS5nZXRPcHRpb24oXCJsaW5lV3JhcHBpbmdcIikpXG4gICAgICAgIGJ1aWxkZXIuYWRkVG9rZW4gPSBidWlsZFRva2VuU3BsaXRTcGFjZXMoYnVpbGRlci5hZGRUb2tlbik7XG4gICAgICBpZiAoaGFzQmFkQmlkaVJlY3RzKGNtLmRpc3BsYXkubWVhc3VyZSkgJiYgKG9yZGVyID0gZ2V0T3JkZXIobGluZSkpKVxuICAgICAgICBidWlsZGVyLmFkZFRva2VuID0gYnVpbGRUb2tlbkJhZEJpZGkoYnVpbGRlci5hZGRUb2tlbiwgb3JkZXIpO1xuICAgICAgYnVpbGRlci5tYXAgPSBbXTtcbiAgICAgIHZhciBhbGxvd0Zyb250aWVyVXBkYXRlID0gbGluZVZpZXcgIT0gY20uZGlzcGxheS5leHRlcm5hbE1lYXN1cmVkICYmIGxpbmVObyhsaW5lKTtcbiAgICAgIGluc2VydExpbmVDb250ZW50KGxpbmUsIGJ1aWxkZXIsIGdldExpbmVTdHlsZXMoY20sIGxpbmUsIGFsbG93RnJvbnRpZXJVcGRhdGUpKTtcbiAgICAgIGlmIChsaW5lLnN0eWxlQ2xhc3Nlcykge1xuICAgICAgICBpZiAobGluZS5zdHlsZUNsYXNzZXMuYmdDbGFzcylcbiAgICAgICAgICBidWlsZGVyLmJnQ2xhc3MgPSBqb2luQ2xhc3NlcyhsaW5lLnN0eWxlQ2xhc3Nlcy5iZ0NsYXNzLCBidWlsZGVyLmJnQ2xhc3MgfHwgXCJcIik7XG4gICAgICAgIGlmIChsaW5lLnN0eWxlQ2xhc3Nlcy50ZXh0Q2xhc3MpXG4gICAgICAgICAgYnVpbGRlci50ZXh0Q2xhc3MgPSBqb2luQ2xhc3NlcyhsaW5lLnN0eWxlQ2xhc3Nlcy50ZXh0Q2xhc3MsIGJ1aWxkZXIudGV4dENsYXNzIHx8IFwiXCIpO1xuICAgICAgfVxuXG4gICAgICAvLyBFbnN1cmUgYXQgbGVhc3QgYSBzaW5nbGUgbm9kZSBpcyBwcmVzZW50LCBmb3IgbWVhc3VyaW5nLlxuICAgICAgaWYgKGJ1aWxkZXIubWFwLmxlbmd0aCA9PSAwKVxuICAgICAgICBidWlsZGVyLm1hcC5wdXNoKDAsIDAsIGJ1aWxkZXIuY29udGVudC5hcHBlbmRDaGlsZCh6ZXJvV2lkdGhFbGVtZW50KGNtLmRpc3BsYXkubWVhc3VyZSkpKTtcblxuICAgICAgLy8gU3RvcmUgdGhlIG1hcCBhbmQgYSBjYWNoZSBvYmplY3QgZm9yIHRoZSBjdXJyZW50IGxvZ2ljYWwgbGluZVxuICAgICAgaWYgKGkgPT0gMCkge1xuICAgICAgICBsaW5lVmlldy5tZWFzdXJlLm1hcCA9IGJ1aWxkZXIubWFwO1xuICAgICAgICBsaW5lVmlldy5tZWFzdXJlLmNhY2hlID0ge307XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAobGluZVZpZXcubWVhc3VyZS5tYXBzIHx8IChsaW5lVmlldy5tZWFzdXJlLm1hcHMgPSBbXSkpLnB1c2goYnVpbGRlci5tYXApO1xuICAgICAgICAobGluZVZpZXcubWVhc3VyZS5jYWNoZXMgfHwgKGxpbmVWaWV3Lm1lYXN1cmUuY2FjaGVzID0gW10pKS5wdXNoKHt9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBTZWUgaXNzdWUgIzI5MDFcbiAgICBpZiAod2Via2l0ICYmIC9cXGJjbS10YWJcXGIvLnRlc3QoYnVpbGRlci5jb250ZW50Lmxhc3RDaGlsZC5jbGFzc05hbWUpKVxuICAgICAgYnVpbGRlci5jb250ZW50LmNsYXNzTmFtZSA9IFwiY20tdGFiLXdyYXAtaGFja1wiO1xuXG4gICAgc2lnbmFsKGNtLCBcInJlbmRlckxpbmVcIiwgY20sIGxpbmVWaWV3LmxpbmUsIGJ1aWxkZXIucHJlKTtcbiAgICBpZiAoYnVpbGRlci5wcmUuY2xhc3NOYW1lKVxuICAgICAgYnVpbGRlci50ZXh0Q2xhc3MgPSBqb2luQ2xhc3NlcyhidWlsZGVyLnByZS5jbGFzc05hbWUsIGJ1aWxkZXIudGV4dENsYXNzIHx8IFwiXCIpO1xuXG4gICAgcmV0dXJuIGJ1aWxkZXI7XG4gIH1cblxuICBmdW5jdGlvbiBkZWZhdWx0U3BlY2lhbENoYXJQbGFjZWhvbGRlcihjaCkge1xuICAgIHZhciB0b2tlbiA9IGVsdChcInNwYW5cIiwgXCJcXHUyMDIyXCIsIFwiY20taW52YWxpZGNoYXJcIik7XG4gICAgdG9rZW4udGl0bGUgPSBcIlxcXFx1XCIgKyBjaC5jaGFyQ29kZUF0KDApLnRvU3RyaW5nKDE2KTtcbiAgICByZXR1cm4gdG9rZW47XG4gIH1cblxuICAvLyBCdWlsZCB1cCB0aGUgRE9NIHJlcHJlc2VudGF0aW9uIGZvciBhIHNpbmdsZSB0b2tlbiwgYW5kIGFkZCBpdCB0b1xuICAvLyB0aGUgbGluZSBtYXAuIFRha2VzIGNhcmUgdG8gcmVuZGVyIHNwZWNpYWwgY2hhcmFjdGVycyBzZXBhcmF0ZWx5LlxuICBmdW5jdGlvbiBidWlsZFRva2VuKGJ1aWxkZXIsIHRleHQsIHN0eWxlLCBzdGFydFN0eWxlLCBlbmRTdHlsZSwgdGl0bGUsIGNzcykge1xuICAgIGlmICghdGV4dCkgcmV0dXJuO1xuICAgIHZhciBzcGVjaWFsID0gYnVpbGRlci5jbS5vcHRpb25zLnNwZWNpYWxDaGFycywgbXVzdFdyYXAgPSBmYWxzZTtcbiAgICBpZiAoIXNwZWNpYWwudGVzdCh0ZXh0KSkge1xuICAgICAgYnVpbGRlci5jb2wgKz0gdGV4dC5sZW5ndGg7XG4gICAgICB2YXIgY29udGVudCA9IGRvY3VtZW50LmNyZWF0ZVRleHROb2RlKHRleHQpO1xuICAgICAgYnVpbGRlci5tYXAucHVzaChidWlsZGVyLnBvcywgYnVpbGRlci5wb3MgKyB0ZXh0Lmxlbmd0aCwgY29udGVudCk7XG4gICAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDkpIG11c3RXcmFwID0gdHJ1ZTtcbiAgICAgIGJ1aWxkZXIucG9zICs9IHRleHQubGVuZ3RoO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgY29udGVudCA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKSwgcG9zID0gMDtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIHNwZWNpYWwubGFzdEluZGV4ID0gcG9zO1xuICAgICAgICB2YXIgbSA9IHNwZWNpYWwuZXhlYyh0ZXh0KTtcbiAgICAgICAgdmFyIHNraXBwZWQgPSBtID8gbS5pbmRleCAtIHBvcyA6IHRleHQubGVuZ3RoIC0gcG9zO1xuICAgICAgICBpZiAoc2tpcHBlZCkge1xuICAgICAgICAgIHZhciB0eHQgPSBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZSh0ZXh0LnNsaWNlKHBvcywgcG9zICsgc2tpcHBlZCkpO1xuICAgICAgICAgIGlmIChpZSAmJiBpZV92ZXJzaW9uIDwgOSkgY29udGVudC5hcHBlbmRDaGlsZChlbHQoXCJzcGFuXCIsIFt0eHRdKSk7XG4gICAgICAgICAgZWxzZSBjb250ZW50LmFwcGVuZENoaWxkKHR4dCk7XG4gICAgICAgICAgYnVpbGRlci5tYXAucHVzaChidWlsZGVyLnBvcywgYnVpbGRlci5wb3MgKyBza2lwcGVkLCB0eHQpO1xuICAgICAgICAgIGJ1aWxkZXIuY29sICs9IHNraXBwZWQ7XG4gICAgICAgICAgYnVpbGRlci5wb3MgKz0gc2tpcHBlZDtcbiAgICAgICAgfVxuICAgICAgICBpZiAoIW0pIGJyZWFrO1xuICAgICAgICBwb3MgKz0gc2tpcHBlZCArIDE7XG4gICAgICAgIGlmIChtWzBdID09IFwiXFx0XCIpIHtcbiAgICAgICAgICB2YXIgdGFiU2l6ZSA9IGJ1aWxkZXIuY20ub3B0aW9ucy50YWJTaXplLCB0YWJXaWR0aCA9IHRhYlNpemUgLSBidWlsZGVyLmNvbCAlIHRhYlNpemU7XG4gICAgICAgICAgdmFyIHR4dCA9IGNvbnRlbnQuYXBwZW5kQ2hpbGQoZWx0KFwic3BhblwiLCBzcGFjZVN0cih0YWJXaWR0aCksIFwiY20tdGFiXCIpKTtcbiAgICAgICAgICBidWlsZGVyLmNvbCArPSB0YWJXaWR0aDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YXIgdHh0ID0gYnVpbGRlci5jbS5vcHRpb25zLnNwZWNpYWxDaGFyUGxhY2Vob2xkZXIobVswXSk7XG4gICAgICAgICAgaWYgKGllICYmIGllX3ZlcnNpb24gPCA5KSBjb250ZW50LmFwcGVuZENoaWxkKGVsdChcInNwYW5cIiwgW3R4dF0pKTtcbiAgICAgICAgICBlbHNlIGNvbnRlbnQuYXBwZW5kQ2hpbGQodHh0KTtcbiAgICAgICAgICBidWlsZGVyLmNvbCArPSAxO1xuICAgICAgICB9XG4gICAgICAgIGJ1aWxkZXIubWFwLnB1c2goYnVpbGRlci5wb3MsIGJ1aWxkZXIucG9zICsgMSwgdHh0KTtcbiAgICAgICAgYnVpbGRlci5wb3MrKztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHN0eWxlIHx8IHN0YXJ0U3R5bGUgfHwgZW5kU3R5bGUgfHwgbXVzdFdyYXAgfHwgY3NzKSB7XG4gICAgICB2YXIgZnVsbFN0eWxlID0gc3R5bGUgfHwgXCJcIjtcbiAgICAgIGlmIChzdGFydFN0eWxlKSBmdWxsU3R5bGUgKz0gc3RhcnRTdHlsZTtcbiAgICAgIGlmIChlbmRTdHlsZSkgZnVsbFN0eWxlICs9IGVuZFN0eWxlO1xuICAgICAgdmFyIHRva2VuID0gZWx0KFwic3BhblwiLCBbY29udGVudF0sIGZ1bGxTdHlsZSwgY3NzKTtcbiAgICAgIGlmICh0aXRsZSkgdG9rZW4udGl0bGUgPSB0aXRsZTtcbiAgICAgIHJldHVybiBidWlsZGVyLmNvbnRlbnQuYXBwZW5kQ2hpbGQodG9rZW4pO1xuICAgIH1cbiAgICBidWlsZGVyLmNvbnRlbnQuYXBwZW5kQ2hpbGQoY29udGVudCk7XG4gIH1cblxuICBmdW5jdGlvbiBidWlsZFRva2VuU3BsaXRTcGFjZXMoaW5uZXIpIHtcbiAgICBmdW5jdGlvbiBzcGxpdChvbGQpIHtcbiAgICAgIHZhciBvdXQgPSBcIiBcIjtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgb2xkLmxlbmd0aCAtIDI7ICsraSkgb3V0ICs9IGkgJSAyID8gXCIgXCIgOiBcIlxcdTAwYTBcIjtcbiAgICAgIG91dCArPSBcIiBcIjtcbiAgICAgIHJldHVybiBvdXQ7XG4gICAgfVxuICAgIHJldHVybiBmdW5jdGlvbihidWlsZGVyLCB0ZXh0LCBzdHlsZSwgc3RhcnRTdHlsZSwgZW5kU3R5bGUsIHRpdGxlKSB7XG4gICAgICBpbm5lcihidWlsZGVyLCB0ZXh0LnJlcGxhY2UoLyB7Myx9L2csIHNwbGl0KSwgc3R5bGUsIHN0YXJ0U3R5bGUsIGVuZFN0eWxlLCB0aXRsZSk7XG4gICAgfTtcbiAgfVxuXG4gIC8vIFdvcmsgYXJvdW5kIG5vbnNlbnNlIGRpbWVuc2lvbnMgYmVpbmcgcmVwb3J0ZWQgZm9yIHN0cmV0Y2hlcyBvZlxuICAvLyByaWdodC10by1sZWZ0IHRleHQuXG4gIGZ1bmN0aW9uIGJ1aWxkVG9rZW5CYWRCaWRpKGlubmVyLCBvcmRlcikge1xuICAgIHJldHVybiBmdW5jdGlvbihidWlsZGVyLCB0ZXh0LCBzdHlsZSwgc3RhcnRTdHlsZSwgZW5kU3R5bGUsIHRpdGxlKSB7XG4gICAgICBzdHlsZSA9IHN0eWxlID8gc3R5bGUgKyBcIiBjbS1mb3JjZS1ib3JkZXJcIiA6IFwiY20tZm9yY2UtYm9yZGVyXCI7XG4gICAgICB2YXIgc3RhcnQgPSBidWlsZGVyLnBvcywgZW5kID0gc3RhcnQgKyB0ZXh0Lmxlbmd0aDtcbiAgICAgIGZvciAoOzspIHtcbiAgICAgICAgLy8gRmluZCB0aGUgcGFydCB0aGF0IG92ZXJsYXBzIHdpdGggdGhlIHN0YXJ0IG9mIHRoaXMgdGV4dFxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG9yZGVyLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgdmFyIHBhcnQgPSBvcmRlcltpXTtcbiAgICAgICAgICBpZiAocGFydC50byA+IHN0YXJ0ICYmIHBhcnQuZnJvbSA8PSBzdGFydCkgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHBhcnQudG8gPj0gZW5kKSByZXR1cm4gaW5uZXIoYnVpbGRlciwgdGV4dCwgc3R5bGUsIHN0YXJ0U3R5bGUsIGVuZFN0eWxlLCB0aXRsZSk7XG4gICAgICAgIGlubmVyKGJ1aWxkZXIsIHRleHQuc2xpY2UoMCwgcGFydC50byAtIHN0YXJ0KSwgc3R5bGUsIHN0YXJ0U3R5bGUsIG51bGwsIHRpdGxlKTtcbiAgICAgICAgc3RhcnRTdHlsZSA9IG51bGw7XG4gICAgICAgIHRleHQgPSB0ZXh0LnNsaWNlKHBhcnQudG8gLSBzdGFydCk7XG4gICAgICAgIHN0YXJ0ID0gcGFydC50bztcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgZnVuY3Rpb24gYnVpbGRDb2xsYXBzZWRTcGFuKGJ1aWxkZXIsIHNpemUsIG1hcmtlciwgaWdub3JlV2lkZ2V0KSB7XG4gICAgdmFyIHdpZGdldCA9ICFpZ25vcmVXaWRnZXQgJiYgbWFya2VyLndpZGdldE5vZGU7XG4gICAgaWYgKHdpZGdldCkge1xuICAgICAgYnVpbGRlci5tYXAucHVzaChidWlsZGVyLnBvcywgYnVpbGRlci5wb3MgKyBzaXplLCB3aWRnZXQpO1xuICAgICAgYnVpbGRlci5jb250ZW50LmFwcGVuZENoaWxkKHdpZGdldCk7XG4gICAgfVxuICAgIGJ1aWxkZXIucG9zICs9IHNpemU7XG4gIH1cblxuICAvLyBPdXRwdXRzIGEgbnVtYmVyIG9mIHNwYW5zIHRvIG1ha2UgdXAgYSBsaW5lLCB0YWtpbmcgaGlnaGxpZ2h0aW5nXG4gIC8vIGFuZCBtYXJrZWQgdGV4dCBpbnRvIGFjY291bnQuXG4gIGZ1bmN0aW9uIGluc2VydExpbmVDb250ZW50KGxpbmUsIGJ1aWxkZXIsIHN0eWxlcykge1xuICAgIHZhciBzcGFucyA9IGxpbmUubWFya2VkU3BhbnMsIGFsbFRleHQgPSBsaW5lLnRleHQsIGF0ID0gMDtcbiAgICBpZiAoIXNwYW5zKSB7XG4gICAgICBmb3IgKHZhciBpID0gMTsgaSA8IHN0eWxlcy5sZW5ndGg7IGkrPTIpXG4gICAgICAgIGJ1aWxkZXIuYWRkVG9rZW4oYnVpbGRlciwgYWxsVGV4dC5zbGljZShhdCwgYXQgPSBzdHlsZXNbaV0pLCBpbnRlcnByZXRUb2tlblN0eWxlKHN0eWxlc1tpKzFdLCBidWlsZGVyLmNtLm9wdGlvbnMpKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB2YXIgbGVuID0gYWxsVGV4dC5sZW5ndGgsIHBvcyA9IDAsIGkgPSAxLCB0ZXh0ID0gXCJcIiwgc3R5bGUsIGNzcztcbiAgICB2YXIgbmV4dENoYW5nZSA9IDAsIHNwYW5TdHlsZSwgc3BhbkVuZFN0eWxlLCBzcGFuU3RhcnRTdHlsZSwgdGl0bGUsIGNvbGxhcHNlZDtcbiAgICBmb3IgKDs7KSB7XG4gICAgICBpZiAobmV4dENoYW5nZSA9PSBwb3MpIHsgLy8gVXBkYXRlIGN1cnJlbnQgbWFya2VyIHNldFxuICAgICAgICBzcGFuU3R5bGUgPSBzcGFuRW5kU3R5bGUgPSBzcGFuU3RhcnRTdHlsZSA9IHRpdGxlID0gY3NzID0gXCJcIjtcbiAgICAgICAgY29sbGFwc2VkID0gbnVsbDsgbmV4dENoYW5nZSA9IEluZmluaXR5O1xuICAgICAgICB2YXIgZm91bmRCb29rbWFya3MgPSBbXTtcbiAgICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBzcGFucy5sZW5ndGg7ICsraikge1xuICAgICAgICAgIHZhciBzcCA9IHNwYW5zW2pdLCBtID0gc3AubWFya2VyO1xuICAgICAgICAgIGlmIChzcC5mcm9tIDw9IHBvcyAmJiAoc3AudG8gPT0gbnVsbCB8fCBzcC50byA+IHBvcykpIHtcbiAgICAgICAgICAgIGlmIChzcC50byAhPSBudWxsICYmIG5leHRDaGFuZ2UgPiBzcC50bykgeyBuZXh0Q2hhbmdlID0gc3AudG87IHNwYW5FbmRTdHlsZSA9IFwiXCI7IH1cbiAgICAgICAgICAgIGlmIChtLmNsYXNzTmFtZSkgc3BhblN0eWxlICs9IFwiIFwiICsgbS5jbGFzc05hbWU7XG4gICAgICAgICAgICBpZiAobS5jc3MpIGNzcyA9IG0uY3NzO1xuICAgICAgICAgICAgaWYgKG0uc3RhcnRTdHlsZSAmJiBzcC5mcm9tID09IHBvcykgc3BhblN0YXJ0U3R5bGUgKz0gXCIgXCIgKyBtLnN0YXJ0U3R5bGU7XG4gICAgICAgICAgICBpZiAobS5lbmRTdHlsZSAmJiBzcC50byA9PSBuZXh0Q2hhbmdlKSBzcGFuRW5kU3R5bGUgKz0gXCIgXCIgKyBtLmVuZFN0eWxlO1xuICAgICAgICAgICAgaWYgKG0udGl0bGUgJiYgIXRpdGxlKSB0aXRsZSA9IG0udGl0bGU7XG4gICAgICAgICAgICBpZiAobS5jb2xsYXBzZWQgJiYgKCFjb2xsYXBzZWQgfHwgY29tcGFyZUNvbGxhcHNlZE1hcmtlcnMoY29sbGFwc2VkLm1hcmtlciwgbSkgPCAwKSlcbiAgICAgICAgICAgICAgY29sbGFwc2VkID0gc3A7XG4gICAgICAgICAgfSBlbHNlIGlmIChzcC5mcm9tID4gcG9zICYmIG5leHRDaGFuZ2UgPiBzcC5mcm9tKSB7XG4gICAgICAgICAgICBuZXh0Q2hhbmdlID0gc3AuZnJvbTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKG0udHlwZSA9PSBcImJvb2ttYXJrXCIgJiYgc3AuZnJvbSA9PSBwb3MgJiYgbS53aWRnZXROb2RlKSBmb3VuZEJvb2ttYXJrcy5wdXNoKG0pO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjb2xsYXBzZWQgJiYgKGNvbGxhcHNlZC5mcm9tIHx8IDApID09IHBvcykge1xuICAgICAgICAgIGJ1aWxkQ29sbGFwc2VkU3BhbihidWlsZGVyLCAoY29sbGFwc2VkLnRvID09IG51bGwgPyBsZW4gKyAxIDogY29sbGFwc2VkLnRvKSAtIHBvcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbGFwc2VkLm1hcmtlciwgY29sbGFwc2VkLmZyb20gPT0gbnVsbCk7XG4gICAgICAgICAgaWYgKGNvbGxhcHNlZC50byA9PSBudWxsKSByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFjb2xsYXBzZWQgJiYgZm91bmRCb29rbWFya3MubGVuZ3RoKSBmb3IgKHZhciBqID0gMDsgaiA8IGZvdW5kQm9va21hcmtzLmxlbmd0aDsgKytqKVxuICAgICAgICAgIGJ1aWxkQ29sbGFwc2VkU3BhbihidWlsZGVyLCAwLCBmb3VuZEJvb2ttYXJrc1tqXSk7XG4gICAgICB9XG4gICAgICBpZiAocG9zID49IGxlbikgYnJlYWs7XG5cbiAgICAgIHZhciB1cHRvID0gTWF0aC5taW4obGVuLCBuZXh0Q2hhbmdlKTtcbiAgICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICAgIGlmICh0ZXh0KSB7XG4gICAgICAgICAgdmFyIGVuZCA9IHBvcyArIHRleHQubGVuZ3RoO1xuICAgICAgICAgIGlmICghY29sbGFwc2VkKSB7XG4gICAgICAgICAgICB2YXIgdG9rZW5UZXh0ID0gZW5kID4gdXB0byA/IHRleHQuc2xpY2UoMCwgdXB0byAtIHBvcykgOiB0ZXh0O1xuICAgICAgICAgICAgYnVpbGRlci5hZGRUb2tlbihidWlsZGVyLCB0b2tlblRleHQsIHN0eWxlID8gc3R5bGUgKyBzcGFuU3R5bGUgOiBzcGFuU3R5bGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYW5TdGFydFN0eWxlLCBwb3MgKyB0b2tlblRleHQubGVuZ3RoID09IG5leHRDaGFuZ2UgPyBzcGFuRW5kU3R5bGUgOiBcIlwiLCB0aXRsZSwgY3NzKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGVuZCA+PSB1cHRvKSB7dGV4dCA9IHRleHQuc2xpY2UodXB0byAtIHBvcyk7IHBvcyA9IHVwdG87IGJyZWFrO31cbiAgICAgICAgICBwb3MgPSBlbmQ7XG4gICAgICAgICAgc3BhblN0YXJ0U3R5bGUgPSBcIlwiO1xuICAgICAgICB9XG4gICAgICAgIHRleHQgPSBhbGxUZXh0LnNsaWNlKGF0LCBhdCA9IHN0eWxlc1tpKytdKTtcbiAgICAgICAgc3R5bGUgPSBpbnRlcnByZXRUb2tlblN0eWxlKHN0eWxlc1tpKytdLCBidWlsZGVyLmNtLm9wdGlvbnMpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIERPQ1VNRU5UIERBVEEgU1RSVUNUVVJFXG5cbiAgLy8gQnkgZGVmYXVsdCwgdXBkYXRlcyB0aGF0IHN0YXJ0IGFuZCBlbmQgYXQgdGhlIGJlZ2lubmluZyBvZiBhIGxpbmVcbiAgLy8gYXJlIHRyZWF0ZWQgc3BlY2lhbGx5LCBpbiBvcmRlciB0byBtYWtlIHRoZSBhc3NvY2lhdGlvbiBvZiBsaW5lXG4gIC8vIHdpZGdldHMgYW5kIG1hcmtlciBlbGVtZW50cyB3aXRoIHRoZSB0ZXh0IGJlaGF2ZSBtb3JlIGludHVpdGl2ZS5cbiAgZnVuY3Rpb24gaXNXaG9sZUxpbmVVcGRhdGUoZG9jLCBjaGFuZ2UpIHtcbiAgICByZXR1cm4gY2hhbmdlLmZyb20uY2ggPT0gMCAmJiBjaGFuZ2UudG8uY2ggPT0gMCAmJiBsc3QoY2hhbmdlLnRleHQpID09IFwiXCIgJiZcbiAgICAgICghZG9jLmNtIHx8IGRvYy5jbS5vcHRpb25zLndob2xlTGluZVVwZGF0ZUJlZm9yZSk7XG4gIH1cblxuICAvLyBQZXJmb3JtIGEgY2hhbmdlIG9uIHRoZSBkb2N1bWVudCBkYXRhIHN0cnVjdHVyZS5cbiAgZnVuY3Rpb24gdXBkYXRlRG9jKGRvYywgY2hhbmdlLCBtYXJrZWRTcGFucywgZXN0aW1hdGVIZWlnaHQpIHtcbiAgICBmdW5jdGlvbiBzcGFuc0ZvcihuKSB7cmV0dXJuIG1hcmtlZFNwYW5zID8gbWFya2VkU3BhbnNbbl0gOiBudWxsO31cbiAgICBmdW5jdGlvbiB1cGRhdGUobGluZSwgdGV4dCwgc3BhbnMpIHtcbiAgICAgIHVwZGF0ZUxpbmUobGluZSwgdGV4dCwgc3BhbnMsIGVzdGltYXRlSGVpZ2h0KTtcbiAgICAgIHNpZ25hbExhdGVyKGxpbmUsIFwiY2hhbmdlXCIsIGxpbmUsIGNoYW5nZSk7XG4gICAgfVxuICAgIGZ1bmN0aW9uIGxpbmVzRm9yKHN0YXJ0LCBlbmQpIHtcbiAgICAgIGZvciAodmFyIGkgPSBzdGFydCwgcmVzdWx0ID0gW107IGkgPCBlbmQ7ICsraSlcbiAgICAgICAgcmVzdWx0LnB1c2gobmV3IExpbmUodGV4dFtpXSwgc3BhbnNGb3IoaSksIGVzdGltYXRlSGVpZ2h0KSk7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cblxuICAgIHZhciBmcm9tID0gY2hhbmdlLmZyb20sIHRvID0gY2hhbmdlLnRvLCB0ZXh0ID0gY2hhbmdlLnRleHQ7XG4gICAgdmFyIGZpcnN0TGluZSA9IGdldExpbmUoZG9jLCBmcm9tLmxpbmUpLCBsYXN0TGluZSA9IGdldExpbmUoZG9jLCB0by5saW5lKTtcbiAgICB2YXIgbGFzdFRleHQgPSBsc3QodGV4dCksIGxhc3RTcGFucyA9IHNwYW5zRm9yKHRleHQubGVuZ3RoIC0gMSksIG5saW5lcyA9IHRvLmxpbmUgLSBmcm9tLmxpbmU7XG5cbiAgICAvLyBBZGp1c3QgdGhlIGxpbmUgc3RydWN0dXJlXG4gICAgaWYgKGNoYW5nZS5mdWxsKSB7XG4gICAgICBkb2MuaW5zZXJ0KDAsIGxpbmVzRm9yKDAsIHRleHQubGVuZ3RoKSk7XG4gICAgICBkb2MucmVtb3ZlKHRleHQubGVuZ3RoLCBkb2Muc2l6ZSAtIHRleHQubGVuZ3RoKTtcbiAgICB9IGVsc2UgaWYgKGlzV2hvbGVMaW5lVXBkYXRlKGRvYywgY2hhbmdlKSkge1xuICAgICAgLy8gVGhpcyBpcyBhIHdob2xlLWxpbmUgcmVwbGFjZS4gVHJlYXRlZCBzcGVjaWFsbHkgdG8gbWFrZVxuICAgICAgLy8gc3VyZSBsaW5lIG9iamVjdHMgbW92ZSB0aGUgd2F5IHRoZXkgYXJlIHN1cHBvc2VkIHRvLlxuICAgICAgdmFyIGFkZGVkID0gbGluZXNGb3IoMCwgdGV4dC5sZW5ndGggLSAxKTtcbiAgICAgIHVwZGF0ZShsYXN0TGluZSwgbGFzdExpbmUudGV4dCwgbGFzdFNwYW5zKTtcbiAgICAgIGlmIChubGluZXMpIGRvYy5yZW1vdmUoZnJvbS5saW5lLCBubGluZXMpO1xuICAgICAgaWYgKGFkZGVkLmxlbmd0aCkgZG9jLmluc2VydChmcm9tLmxpbmUsIGFkZGVkKTtcbiAgICB9IGVsc2UgaWYgKGZpcnN0TGluZSA9PSBsYXN0TGluZSkge1xuICAgICAgaWYgKHRleHQubGVuZ3RoID09IDEpIHtcbiAgICAgICAgdXBkYXRlKGZpcnN0TGluZSwgZmlyc3RMaW5lLnRleHQuc2xpY2UoMCwgZnJvbS5jaCkgKyBsYXN0VGV4dCArIGZpcnN0TGluZS50ZXh0LnNsaWNlKHRvLmNoKSwgbGFzdFNwYW5zKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhciBhZGRlZCA9IGxpbmVzRm9yKDEsIHRleHQubGVuZ3RoIC0gMSk7XG4gICAgICAgIGFkZGVkLnB1c2gobmV3IExpbmUobGFzdFRleHQgKyBmaXJzdExpbmUudGV4dC5zbGljZSh0by5jaCksIGxhc3RTcGFucywgZXN0aW1hdGVIZWlnaHQpKTtcbiAgICAgICAgdXBkYXRlKGZpcnN0TGluZSwgZmlyc3RMaW5lLnRleHQuc2xpY2UoMCwgZnJvbS5jaCkgKyB0ZXh0WzBdLCBzcGFuc0ZvcigwKSk7XG4gICAgICAgIGRvYy5pbnNlcnQoZnJvbS5saW5lICsgMSwgYWRkZWQpO1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAodGV4dC5sZW5ndGggPT0gMSkge1xuICAgICAgdXBkYXRlKGZpcnN0TGluZSwgZmlyc3RMaW5lLnRleHQuc2xpY2UoMCwgZnJvbS5jaCkgKyB0ZXh0WzBdICsgbGFzdExpbmUudGV4dC5zbGljZSh0by5jaCksIHNwYW5zRm9yKDApKTtcbiAgICAgIGRvYy5yZW1vdmUoZnJvbS5saW5lICsgMSwgbmxpbmVzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdXBkYXRlKGZpcnN0TGluZSwgZmlyc3RMaW5lLnRleHQuc2xpY2UoMCwgZnJvbS5jaCkgKyB0ZXh0WzBdLCBzcGFuc0ZvcigwKSk7XG4gICAgICB1cGRhdGUobGFzdExpbmUsIGxhc3RUZXh0ICsgbGFzdExpbmUudGV4dC5zbGljZSh0by5jaCksIGxhc3RTcGFucyk7XG4gICAgICB2YXIgYWRkZWQgPSBsaW5lc0ZvcigxLCB0ZXh0Lmxlbmd0aCAtIDEpO1xuICAgICAgaWYgKG5saW5lcyA+IDEpIGRvYy5yZW1vdmUoZnJvbS5saW5lICsgMSwgbmxpbmVzIC0gMSk7XG4gICAgICBkb2MuaW5zZXJ0KGZyb20ubGluZSArIDEsIGFkZGVkKTtcbiAgICB9XG5cbiAgICBzaWduYWxMYXRlcihkb2MsIFwiY2hhbmdlXCIsIGRvYywgY2hhbmdlKTtcbiAgfVxuXG4gIC8vIFRoZSBkb2N1bWVudCBpcyByZXByZXNlbnRlZCBhcyBhIEJUcmVlIGNvbnNpc3Rpbmcgb2YgbGVhdmVzLCB3aXRoXG4gIC8vIGNodW5rIG9mIGxpbmVzIGluIHRoZW0sIGFuZCBicmFuY2hlcywgd2l0aCB1cCB0byB0ZW4gbGVhdmVzIG9yXG4gIC8vIG90aGVyIGJyYW5jaCBub2RlcyBiZWxvdyB0aGVtLiBUaGUgdG9wIG5vZGUgaXMgYWx3YXlzIGEgYnJhbmNoXG4gIC8vIG5vZGUsIGFuZCBpcyB0aGUgZG9jdW1lbnQgb2JqZWN0IGl0c2VsZiAobWVhbmluZyBpdCBoYXNcbiAgLy8gYWRkaXRpb25hbCBtZXRob2RzIGFuZCBwcm9wZXJ0aWVzKS5cbiAgLy9cbiAgLy8gQWxsIG5vZGVzIGhhdmUgcGFyZW50IGxpbmtzLiBUaGUgdHJlZSBpcyB1c2VkIGJvdGggdG8gZ28gZnJvbVxuICAvLyBsaW5lIG51bWJlcnMgdG8gbGluZSBvYmplY3RzLCBhbmQgdG8gZ28gZnJvbSBvYmplY3RzIHRvIG51bWJlcnMuXG4gIC8vIEl0IGFsc28gaW5kZXhlcyBieSBoZWlnaHQsIGFuZCBpcyB1c2VkIHRvIGNvbnZlcnQgYmV0d2VlbiBoZWlnaHRcbiAgLy8gYW5kIGxpbmUgb2JqZWN0LCBhbmQgdG8gZmluZCB0aGUgdG90YWwgaGVpZ2h0IG9mIHRoZSBkb2N1bWVudC5cbiAgLy9cbiAgLy8gU2VlIGFsc28gaHR0cDovL21hcmlqbmhhdmVyYmVrZS5ubC9ibG9nL2NvZGVtaXJyb3ItbGluZS10cmVlLmh0bWxcblxuICBmdW5jdGlvbiBMZWFmQ2h1bmsobGluZXMpIHtcbiAgICB0aGlzLmxpbmVzID0gbGluZXM7XG4gICAgdGhpcy5wYXJlbnQgPSBudWxsO1xuICAgIGZvciAodmFyIGkgPSAwLCBoZWlnaHQgPSAwOyBpIDwgbGluZXMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGxpbmVzW2ldLnBhcmVudCA9IHRoaXM7XG4gICAgICBoZWlnaHQgKz0gbGluZXNbaV0uaGVpZ2h0O1xuICAgIH1cbiAgICB0aGlzLmhlaWdodCA9IGhlaWdodDtcbiAgfVxuXG4gIExlYWZDaHVuay5wcm90b3R5cGUgPSB7XG4gICAgY2h1bmtTaXplOiBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMubGluZXMubGVuZ3RoOyB9LFxuICAgIC8vIFJlbW92ZSB0aGUgbiBsaW5lcyBhdCBvZmZzZXQgJ2F0Jy5cbiAgICByZW1vdmVJbm5lcjogZnVuY3Rpb24oYXQsIG4pIHtcbiAgICAgIGZvciAodmFyIGkgPSBhdCwgZSA9IGF0ICsgbjsgaSA8IGU7ICsraSkge1xuICAgICAgICB2YXIgbGluZSA9IHRoaXMubGluZXNbaV07XG4gICAgICAgIHRoaXMuaGVpZ2h0IC09IGxpbmUuaGVpZ2h0O1xuICAgICAgICBjbGVhblVwTGluZShsaW5lKTtcbiAgICAgICAgc2lnbmFsTGF0ZXIobGluZSwgXCJkZWxldGVcIik7XG4gICAgICB9XG4gICAgICB0aGlzLmxpbmVzLnNwbGljZShhdCwgbik7XG4gICAgfSxcbiAgICAvLyBIZWxwZXIgdXNlZCB0byBjb2xsYXBzZSBhIHNtYWxsIGJyYW5jaCBpbnRvIGEgc2luZ2xlIGxlYWYuXG4gICAgY29sbGFwc2U6IGZ1bmN0aW9uKGxpbmVzKSB7XG4gICAgICBsaW5lcy5wdXNoLmFwcGx5KGxpbmVzLCB0aGlzLmxpbmVzKTtcbiAgICB9LFxuICAgIC8vIEluc2VydCB0aGUgZ2l2ZW4gYXJyYXkgb2YgbGluZXMgYXQgb2Zmc2V0ICdhdCcsIGNvdW50IHRoZW0gYXNcbiAgICAvLyBoYXZpbmcgdGhlIGdpdmVuIGhlaWdodC5cbiAgICBpbnNlcnRJbm5lcjogZnVuY3Rpb24oYXQsIGxpbmVzLCBoZWlnaHQpIHtcbiAgICAgIHRoaXMuaGVpZ2h0ICs9IGhlaWdodDtcbiAgICAgIHRoaXMubGluZXMgPSB0aGlzLmxpbmVzLnNsaWNlKDAsIGF0KS5jb25jYXQobGluZXMpLmNvbmNhdCh0aGlzLmxpbmVzLnNsaWNlKGF0KSk7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IGxpbmVzLmxlbmd0aDsgKytpKSBsaW5lc1tpXS5wYXJlbnQgPSB0aGlzO1xuICAgIH0sXG4gICAgLy8gVXNlZCB0byBpdGVyYXRlIG92ZXIgYSBwYXJ0IG9mIHRoZSB0cmVlLlxuICAgIGl0ZXJOOiBmdW5jdGlvbihhdCwgbiwgb3ApIHtcbiAgICAgIGZvciAodmFyIGUgPSBhdCArIG47IGF0IDwgZTsgKythdClcbiAgICAgICAgaWYgKG9wKHRoaXMubGluZXNbYXRdKSkgcmV0dXJuIHRydWU7XG4gICAgfVxuICB9O1xuXG4gIGZ1bmN0aW9uIEJyYW5jaENodW5rKGNoaWxkcmVuKSB7XG4gICAgdGhpcy5jaGlsZHJlbiA9IGNoaWxkcmVuO1xuICAgIHZhciBzaXplID0gMCwgaGVpZ2h0ID0gMDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGNoaWxkcmVuLmxlbmd0aDsgKytpKSB7XG4gICAgICB2YXIgY2ggPSBjaGlsZHJlbltpXTtcbiAgICAgIHNpemUgKz0gY2guY2h1bmtTaXplKCk7IGhlaWdodCArPSBjaC5oZWlnaHQ7XG4gICAgICBjaC5wYXJlbnQgPSB0aGlzO1xuICAgIH1cbiAgICB0aGlzLnNpemUgPSBzaXplO1xuICAgIHRoaXMuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIHRoaXMucGFyZW50ID0gbnVsbDtcbiAgfVxuXG4gIEJyYW5jaENodW5rLnByb3RvdHlwZSA9IHtcbiAgICBjaHVua1NpemU6IGZ1bmN0aW9uKCkgeyByZXR1cm4gdGhpcy5zaXplOyB9LFxuICAgIHJlbW92ZUlubmVyOiBmdW5jdGlvbihhdCwgbikge1xuICAgICAgdGhpcy5zaXplIC09IG47XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5jaGlsZHJlbltpXSwgc3ogPSBjaGlsZC5jaHVua1NpemUoKTtcbiAgICAgICAgaWYgKGF0IDwgc3opIHtcbiAgICAgICAgICB2YXIgcm0gPSBNYXRoLm1pbihuLCBzeiAtIGF0KSwgb2xkSGVpZ2h0ID0gY2hpbGQuaGVpZ2h0O1xuICAgICAgICAgIGNoaWxkLnJlbW92ZUlubmVyKGF0LCBybSk7XG4gICAgICAgICAgdGhpcy5oZWlnaHQgLT0gb2xkSGVpZ2h0IC0gY2hpbGQuaGVpZ2h0O1xuICAgICAgICAgIGlmIChzeiA9PSBybSkgeyB0aGlzLmNoaWxkcmVuLnNwbGljZShpLS0sIDEpOyBjaGlsZC5wYXJlbnQgPSBudWxsOyB9XG4gICAgICAgICAgaWYgKChuIC09IHJtKSA9PSAwKSBicmVhaztcbiAgICAgICAgICBhdCA9IDA7XG4gICAgICAgIH0gZWxzZSBhdCAtPSBzejtcbiAgICAgIH1cbiAgICAgIC8vIElmIHRoZSByZXN1bHQgaXMgc21hbGxlciB0aGFuIDI1IGxpbmVzLCBlbnN1cmUgdGhhdCBpdCBpcyBhXG4gICAgICAvLyBzaW5nbGUgbGVhZiBub2RlLlxuICAgICAgaWYgKHRoaXMuc2l6ZSAtIG4gPCAyNSAmJlxuICAgICAgICAgICh0aGlzLmNoaWxkcmVuLmxlbmd0aCA+IDEgfHwgISh0aGlzLmNoaWxkcmVuWzBdIGluc3RhbmNlb2YgTGVhZkNodW5rKSkpIHtcbiAgICAgICAgdmFyIGxpbmVzID0gW107XG4gICAgICAgIHRoaXMuY29sbGFwc2UobGluZXMpO1xuICAgICAgICB0aGlzLmNoaWxkcmVuID0gW25ldyBMZWFmQ2h1bmsobGluZXMpXTtcbiAgICAgICAgdGhpcy5jaGlsZHJlblswXS5wYXJlbnQgPSB0aGlzO1xuICAgICAgfVxuICAgIH0sXG4gICAgY29sbGFwc2U6IGZ1bmN0aW9uKGxpbmVzKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyArK2kpIHRoaXMuY2hpbGRyZW5baV0uY29sbGFwc2UobGluZXMpO1xuICAgIH0sXG4gICAgaW5zZXJ0SW5uZXI6IGZ1bmN0aW9uKGF0LCBsaW5lcywgaGVpZ2h0KSB7XG4gICAgICB0aGlzLnNpemUgKz0gbGluZXMubGVuZ3RoO1xuICAgICAgdGhpcy5oZWlnaHQgKz0gaGVpZ2h0O1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmNoaWxkcmVuLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBjaGlsZCA9IHRoaXMuY2hpbGRyZW5baV0sIHN6ID0gY2hpbGQuY2h1bmtTaXplKCk7XG4gICAgICAgIGlmIChhdCA8PSBzeikge1xuICAgICAgICAgIGNoaWxkLmluc2VydElubmVyKGF0LCBsaW5lcywgaGVpZ2h0KTtcbiAgICAgICAgICBpZiAoY2hpbGQubGluZXMgJiYgY2hpbGQubGluZXMubGVuZ3RoID4gNTApIHtcbiAgICAgICAgICAgIHdoaWxlIChjaGlsZC5saW5lcy5sZW5ndGggPiA1MCkge1xuICAgICAgICAgICAgICB2YXIgc3BpbGxlZCA9IGNoaWxkLmxpbmVzLnNwbGljZShjaGlsZC5saW5lcy5sZW5ndGggLSAyNSwgMjUpO1xuICAgICAgICAgICAgICB2YXIgbmV3bGVhZiA9IG5ldyBMZWFmQ2h1bmsoc3BpbGxlZCk7XG4gICAgICAgICAgICAgIGNoaWxkLmhlaWdodCAtPSBuZXdsZWFmLmhlaWdodDtcbiAgICAgICAgICAgICAgdGhpcy5jaGlsZHJlbi5zcGxpY2UoaSArIDEsIDAsIG5ld2xlYWYpO1xuICAgICAgICAgICAgICBuZXdsZWFmLnBhcmVudCA9IHRoaXM7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLm1heWJlU3BpbGwoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgYXQgLT0gc3o7XG4gICAgICB9XG4gICAgfSxcbiAgICAvLyBXaGVuIGEgbm9kZSBoYXMgZ3Jvd24sIGNoZWNrIHdoZXRoZXIgaXQgc2hvdWxkIGJlIHNwbGl0LlxuICAgIG1heWJlU3BpbGw6IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHRoaXMuY2hpbGRyZW4ubGVuZ3RoIDw9IDEwKSByZXR1cm47XG4gICAgICB2YXIgbWUgPSB0aGlzO1xuICAgICAgZG8ge1xuICAgICAgICB2YXIgc3BpbGxlZCA9IG1lLmNoaWxkcmVuLnNwbGljZShtZS5jaGlsZHJlbi5sZW5ndGggLSA1LCA1KTtcbiAgICAgICAgdmFyIHNpYmxpbmcgPSBuZXcgQnJhbmNoQ2h1bmsoc3BpbGxlZCk7XG4gICAgICAgIGlmICghbWUucGFyZW50KSB7IC8vIEJlY29tZSB0aGUgcGFyZW50IG5vZGVcbiAgICAgICAgICB2YXIgY29weSA9IG5ldyBCcmFuY2hDaHVuayhtZS5jaGlsZHJlbik7XG4gICAgICAgICAgY29weS5wYXJlbnQgPSBtZTtcbiAgICAgICAgICBtZS5jaGlsZHJlbiA9IFtjb3B5LCBzaWJsaW5nXTtcbiAgICAgICAgICBtZSA9IGNvcHk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWUuc2l6ZSAtPSBzaWJsaW5nLnNpemU7XG4gICAgICAgICAgbWUuaGVpZ2h0IC09IHNpYmxpbmcuaGVpZ2h0O1xuICAgICAgICAgIHZhciBteUluZGV4ID0gaW5kZXhPZihtZS5wYXJlbnQuY2hpbGRyZW4sIG1lKTtcbiAgICAgICAgICBtZS5wYXJlbnQuY2hpbGRyZW4uc3BsaWNlKG15SW5kZXggKyAxLCAwLCBzaWJsaW5nKTtcbiAgICAgICAgfVxuICAgICAgICBzaWJsaW5nLnBhcmVudCA9IG1lLnBhcmVudDtcbiAgICAgIH0gd2hpbGUgKG1lLmNoaWxkcmVuLmxlbmd0aCA+IDEwKTtcbiAgICAgIG1lLnBhcmVudC5tYXliZVNwaWxsKCk7XG4gICAgfSxcbiAgICBpdGVyTjogZnVuY3Rpb24oYXQsIG4sIG9wKSB7XG4gICAgICBmb3IgKHZhciBpID0gMDsgaSA8IHRoaXMuY2hpbGRyZW4ubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIGNoaWxkID0gdGhpcy5jaGlsZHJlbltpXSwgc3ogPSBjaGlsZC5jaHVua1NpemUoKTtcbiAgICAgICAgaWYgKGF0IDwgc3opIHtcbiAgICAgICAgICB2YXIgdXNlZCA9IE1hdGgubWluKG4sIHN6IC0gYXQpO1xuICAgICAgICAgIGlmIChjaGlsZC5pdGVyTihhdCwgdXNlZCwgb3ApKSByZXR1cm4gdHJ1ZTtcbiAgICAgICAgICBpZiAoKG4gLT0gdXNlZCkgPT0gMCkgYnJlYWs7XG4gICAgICAgICAgYXQgPSAwO1xuICAgICAgICB9IGVsc2UgYXQgLT0gc3o7XG4gICAgICB9XG4gICAgfVxuICB9O1xuXG4gIHZhciBuZXh0RG9jSWQgPSAwO1xuICB2YXIgRG9jID0gQ29kZU1pcnJvci5Eb2MgPSBmdW5jdGlvbih0ZXh0LCBtb2RlLCBmaXJzdExpbmUpIHtcbiAgICBpZiAoISh0aGlzIGluc3RhbmNlb2YgRG9jKSkgcmV0dXJuIG5ldyBEb2ModGV4dCwgbW9kZSwgZmlyc3RMaW5lKTtcbiAgICBpZiAoZmlyc3RMaW5lID09IG51bGwpIGZpcnN0TGluZSA9IDA7XG5cbiAgICBCcmFuY2hDaHVuay5jYWxsKHRoaXMsIFtuZXcgTGVhZkNodW5rKFtuZXcgTGluZShcIlwiLCBudWxsKV0pXSk7XG4gICAgdGhpcy5maXJzdCA9IGZpcnN0TGluZTtcbiAgICB0aGlzLnNjcm9sbFRvcCA9IHRoaXMuc2Nyb2xsTGVmdCA9IDA7XG4gICAgdGhpcy5jYW50RWRpdCA9IGZhbHNlO1xuICAgIHRoaXMuY2xlYW5HZW5lcmF0aW9uID0gMTtcbiAgICB0aGlzLmZyb250aWVyID0gZmlyc3RMaW5lO1xuICAgIHZhciBzdGFydCA9IFBvcyhmaXJzdExpbmUsIDApO1xuICAgIHRoaXMuc2VsID0gc2ltcGxlU2VsZWN0aW9uKHN0YXJ0KTtcbiAgICB0aGlzLmhpc3RvcnkgPSBuZXcgSGlzdG9yeShudWxsKTtcbiAgICB0aGlzLmlkID0gKytuZXh0RG9jSWQ7XG4gICAgdGhpcy5tb2RlT3B0aW9uID0gbW9kZTtcblxuICAgIGlmICh0eXBlb2YgdGV4dCA9PSBcInN0cmluZ1wiKSB0ZXh0ID0gc3BsaXRMaW5lcyh0ZXh0KTtcbiAgICB1cGRhdGVEb2ModGhpcywge2Zyb206IHN0YXJ0LCB0bzogc3RhcnQsIHRleHQ6IHRleHR9KTtcbiAgICBzZXRTZWxlY3Rpb24odGhpcywgc2ltcGxlU2VsZWN0aW9uKHN0YXJ0KSwgc2VsX2RvbnRTY3JvbGwpO1xuICB9O1xuXG4gIERvYy5wcm90b3R5cGUgPSBjcmVhdGVPYmooQnJhbmNoQ2h1bmsucHJvdG90eXBlLCB7XG4gICAgY29uc3RydWN0b3I6IERvYyxcbiAgICAvLyBJdGVyYXRlIG92ZXIgdGhlIGRvY3VtZW50LiBTdXBwb3J0cyB0d28gZm9ybXMgLS0gd2l0aCBvbmx5IG9uZVxuICAgIC8vIGFyZ3VtZW50LCBpdCBjYWxscyB0aGF0IGZvciBlYWNoIGxpbmUgaW4gdGhlIGRvY3VtZW50LiBXaXRoXG4gICAgLy8gdGhyZWUsIGl0IGl0ZXJhdGVzIG92ZXIgdGhlIHJhbmdlIGdpdmVuIGJ5IHRoZSBmaXJzdCB0d28gKHdpdGhcbiAgICAvLyB0aGUgc2Vjb25kIGJlaW5nIG5vbi1pbmNsdXNpdmUpLlxuICAgIGl0ZXI6IGZ1bmN0aW9uKGZyb20sIHRvLCBvcCkge1xuICAgICAgaWYgKG9wKSB0aGlzLml0ZXJOKGZyb20gLSB0aGlzLmZpcnN0LCB0byAtIGZyb20sIG9wKTtcbiAgICAgIGVsc2UgdGhpcy5pdGVyTih0aGlzLmZpcnN0LCB0aGlzLmZpcnN0ICsgdGhpcy5zaXplLCBmcm9tKTtcbiAgICB9LFxuXG4gICAgLy8gTm9uLXB1YmxpYyBpbnRlcmZhY2UgZm9yIGFkZGluZyBhbmQgcmVtb3ZpbmcgbGluZXMuXG4gICAgaW5zZXJ0OiBmdW5jdGlvbihhdCwgbGluZXMpIHtcbiAgICAgIHZhciBoZWlnaHQgPSAwO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsaW5lcy5sZW5ndGg7ICsraSkgaGVpZ2h0ICs9IGxpbmVzW2ldLmhlaWdodDtcbiAgICAgIHRoaXMuaW5zZXJ0SW5uZXIoYXQgLSB0aGlzLmZpcnN0LCBsaW5lcywgaGVpZ2h0KTtcbiAgICB9LFxuICAgIHJlbW92ZTogZnVuY3Rpb24oYXQsIG4pIHsgdGhpcy5yZW1vdmVJbm5lcihhdCAtIHRoaXMuZmlyc3QsIG4pOyB9LFxuXG4gICAgLy8gRnJvbSBoZXJlLCB0aGUgbWV0aG9kcyBhcmUgcGFydCBvZiB0aGUgcHVibGljIGludGVyZmFjZS4gTW9zdFxuICAgIC8vIGFyZSBhbHNvIGF2YWlsYWJsZSBmcm9tIENvZGVNaXJyb3IgKGVkaXRvcikgaW5zdGFuY2VzLlxuXG4gICAgZ2V0VmFsdWU6IGZ1bmN0aW9uKGxpbmVTZXApIHtcbiAgICAgIHZhciBsaW5lcyA9IGdldExpbmVzKHRoaXMsIHRoaXMuZmlyc3QsIHRoaXMuZmlyc3QgKyB0aGlzLnNpemUpO1xuICAgICAgaWYgKGxpbmVTZXAgPT09IGZhbHNlKSByZXR1cm4gbGluZXM7XG4gICAgICByZXR1cm4gbGluZXMuam9pbihsaW5lU2VwIHx8IFwiXFxuXCIpO1xuICAgIH0sXG4gICAgc2V0VmFsdWU6IGRvY01ldGhvZE9wKGZ1bmN0aW9uKGNvZGUpIHtcbiAgICAgIHZhciB0b3AgPSBQb3ModGhpcy5maXJzdCwgMCksIGxhc3QgPSB0aGlzLmZpcnN0ICsgdGhpcy5zaXplIC0gMTtcbiAgICAgIG1ha2VDaGFuZ2UodGhpcywge2Zyb206IHRvcCwgdG86IFBvcyhsYXN0LCBnZXRMaW5lKHRoaXMsIGxhc3QpLnRleHQubGVuZ3RoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRleHQ6IHNwbGl0TGluZXMoY29kZSksIG9yaWdpbjogXCJzZXRWYWx1ZVwiLCBmdWxsOiB0cnVlfSwgdHJ1ZSk7XG4gICAgICBzZXRTZWxlY3Rpb24odGhpcywgc2ltcGxlU2VsZWN0aW9uKHRvcCkpO1xuICAgIH0pLFxuICAgIHJlcGxhY2VSYW5nZTogZnVuY3Rpb24oY29kZSwgZnJvbSwgdG8sIG9yaWdpbikge1xuICAgICAgZnJvbSA9IGNsaXBQb3ModGhpcywgZnJvbSk7XG4gICAgICB0byA9IHRvID8gY2xpcFBvcyh0aGlzLCB0bykgOiBmcm9tO1xuICAgICAgcmVwbGFjZVJhbmdlKHRoaXMsIGNvZGUsIGZyb20sIHRvLCBvcmlnaW4pO1xuICAgIH0sXG4gICAgZ2V0UmFuZ2U6IGZ1bmN0aW9uKGZyb20sIHRvLCBsaW5lU2VwKSB7XG4gICAgICB2YXIgbGluZXMgPSBnZXRCZXR3ZWVuKHRoaXMsIGNsaXBQb3ModGhpcywgZnJvbSksIGNsaXBQb3ModGhpcywgdG8pKTtcbiAgICAgIGlmIChsaW5lU2VwID09PSBmYWxzZSkgcmV0dXJuIGxpbmVzO1xuICAgICAgcmV0dXJuIGxpbmVzLmpvaW4obGluZVNlcCB8fCBcIlxcblwiKTtcbiAgICB9LFxuXG4gICAgZ2V0TGluZTogZnVuY3Rpb24obGluZSkge3ZhciBsID0gdGhpcy5nZXRMaW5lSGFuZGxlKGxpbmUpOyByZXR1cm4gbCAmJiBsLnRleHQ7fSxcblxuICAgIGdldExpbmVIYW5kbGU6IGZ1bmN0aW9uKGxpbmUpIHtpZiAoaXNMaW5lKHRoaXMsIGxpbmUpKSByZXR1cm4gZ2V0TGluZSh0aGlzLCBsaW5lKTt9LFxuICAgIGdldExpbmVOdW1iZXI6IGZ1bmN0aW9uKGxpbmUpIHtyZXR1cm4gbGluZU5vKGxpbmUpO30sXG5cbiAgICBnZXRMaW5lSGFuZGxlVmlzdWFsU3RhcnQ6IGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgIGlmICh0eXBlb2YgbGluZSA9PSBcIm51bWJlclwiKSBsaW5lID0gZ2V0TGluZSh0aGlzLCBsaW5lKTtcbiAgICAgIHJldHVybiB2aXN1YWxMaW5lKGxpbmUpO1xuICAgIH0sXG5cbiAgICBsaW5lQ291bnQ6IGZ1bmN0aW9uKCkge3JldHVybiB0aGlzLnNpemU7fSxcbiAgICBmaXJzdExpbmU6IGZ1bmN0aW9uKCkge3JldHVybiB0aGlzLmZpcnN0O30sXG4gICAgbGFzdExpbmU6IGZ1bmN0aW9uKCkge3JldHVybiB0aGlzLmZpcnN0ICsgdGhpcy5zaXplIC0gMTt9LFxuXG4gICAgY2xpcFBvczogZnVuY3Rpb24ocG9zKSB7cmV0dXJuIGNsaXBQb3ModGhpcywgcG9zKTt9LFxuXG4gICAgZ2V0Q3Vyc29yOiBmdW5jdGlvbihzdGFydCkge1xuICAgICAgdmFyIHJhbmdlID0gdGhpcy5zZWwucHJpbWFyeSgpLCBwb3M7XG4gICAgICBpZiAoc3RhcnQgPT0gbnVsbCB8fCBzdGFydCA9PSBcImhlYWRcIikgcG9zID0gcmFuZ2UuaGVhZDtcbiAgICAgIGVsc2UgaWYgKHN0YXJ0ID09IFwiYW5jaG9yXCIpIHBvcyA9IHJhbmdlLmFuY2hvcjtcbiAgICAgIGVsc2UgaWYgKHN0YXJ0ID09IFwiZW5kXCIgfHwgc3RhcnQgPT0gXCJ0b1wiIHx8IHN0YXJ0ID09PSBmYWxzZSkgcG9zID0gcmFuZ2UudG8oKTtcbiAgICAgIGVsc2UgcG9zID0gcmFuZ2UuZnJvbSgpO1xuICAgICAgcmV0dXJuIHBvcztcbiAgICB9LFxuICAgIGxpc3RTZWxlY3Rpb25zOiBmdW5jdGlvbigpIHsgcmV0dXJuIHRoaXMuc2VsLnJhbmdlczsgfSxcbiAgICBzb21ldGhpbmdTZWxlY3RlZDogZnVuY3Rpb24oKSB7cmV0dXJuIHRoaXMuc2VsLnNvbWV0aGluZ1NlbGVjdGVkKCk7fSxcblxuICAgIHNldEN1cnNvcjogZG9jTWV0aG9kT3AoZnVuY3Rpb24obGluZSwgY2gsIG9wdGlvbnMpIHtcbiAgICAgIHNldFNpbXBsZVNlbGVjdGlvbih0aGlzLCBjbGlwUG9zKHRoaXMsIHR5cGVvZiBsaW5lID09IFwibnVtYmVyXCIgPyBQb3MobGluZSwgY2ggfHwgMCkgOiBsaW5lKSwgbnVsbCwgb3B0aW9ucyk7XG4gICAgfSksXG4gICAgc2V0U2VsZWN0aW9uOiBkb2NNZXRob2RPcChmdW5jdGlvbihhbmNob3IsIGhlYWQsIG9wdGlvbnMpIHtcbiAgICAgIHNldFNpbXBsZVNlbGVjdGlvbih0aGlzLCBjbGlwUG9zKHRoaXMsIGFuY2hvciksIGNsaXBQb3ModGhpcywgaGVhZCB8fCBhbmNob3IpLCBvcHRpb25zKTtcbiAgICB9KSxcbiAgICBleHRlbmRTZWxlY3Rpb246IGRvY01ldGhvZE9wKGZ1bmN0aW9uKGhlYWQsIG90aGVyLCBvcHRpb25zKSB7XG4gICAgICBleHRlbmRTZWxlY3Rpb24odGhpcywgY2xpcFBvcyh0aGlzLCBoZWFkKSwgb3RoZXIgJiYgY2xpcFBvcyh0aGlzLCBvdGhlciksIG9wdGlvbnMpO1xuICAgIH0pLFxuICAgIGV4dGVuZFNlbGVjdGlvbnM6IGRvY01ldGhvZE9wKGZ1bmN0aW9uKGhlYWRzLCBvcHRpb25zKSB7XG4gICAgICBleHRlbmRTZWxlY3Rpb25zKHRoaXMsIGNsaXBQb3NBcnJheSh0aGlzLCBoZWFkcywgb3B0aW9ucykpO1xuICAgIH0pLFxuICAgIGV4dGVuZFNlbGVjdGlvbnNCeTogZG9jTWV0aG9kT3AoZnVuY3Rpb24oZiwgb3B0aW9ucykge1xuICAgICAgZXh0ZW5kU2VsZWN0aW9ucyh0aGlzLCBtYXAodGhpcy5zZWwucmFuZ2VzLCBmKSwgb3B0aW9ucyk7XG4gICAgfSksXG4gICAgc2V0U2VsZWN0aW9uczogZG9jTWV0aG9kT3AoZnVuY3Rpb24ocmFuZ2VzLCBwcmltYXJ5LCBvcHRpb25zKSB7XG4gICAgICBpZiAoIXJhbmdlcy5sZW5ndGgpIHJldHVybjtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBvdXQgPSBbXTsgaSA8IHJhbmdlcy5sZW5ndGg7IGkrKylcbiAgICAgICAgb3V0W2ldID0gbmV3IFJhbmdlKGNsaXBQb3ModGhpcywgcmFuZ2VzW2ldLmFuY2hvciksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICBjbGlwUG9zKHRoaXMsIHJhbmdlc1tpXS5oZWFkKSk7XG4gICAgICBpZiAocHJpbWFyeSA9PSBudWxsKSBwcmltYXJ5ID0gTWF0aC5taW4ocmFuZ2VzLmxlbmd0aCAtIDEsIHRoaXMuc2VsLnByaW1JbmRleCk7XG4gICAgICBzZXRTZWxlY3Rpb24odGhpcywgbm9ybWFsaXplU2VsZWN0aW9uKG91dCwgcHJpbWFyeSksIG9wdGlvbnMpO1xuICAgIH0pLFxuICAgIGFkZFNlbGVjdGlvbjogZG9jTWV0aG9kT3AoZnVuY3Rpb24oYW5jaG9yLCBoZWFkLCBvcHRpb25zKSB7XG4gICAgICB2YXIgcmFuZ2VzID0gdGhpcy5zZWwucmFuZ2VzLnNsaWNlKDApO1xuICAgICAgcmFuZ2VzLnB1c2gobmV3IFJhbmdlKGNsaXBQb3ModGhpcywgYW5jaG9yKSwgY2xpcFBvcyh0aGlzLCBoZWFkIHx8IGFuY2hvcikpKTtcbiAgICAgIHNldFNlbGVjdGlvbih0aGlzLCBub3JtYWxpemVTZWxlY3Rpb24ocmFuZ2VzLCByYW5nZXMubGVuZ3RoIC0gMSksIG9wdGlvbnMpO1xuICAgIH0pLFxuXG4gICAgZ2V0U2VsZWN0aW9uOiBmdW5jdGlvbihsaW5lU2VwKSB7XG4gICAgICB2YXIgcmFuZ2VzID0gdGhpcy5zZWwucmFuZ2VzLCBsaW5lcztcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcmFuZ2VzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHZhciBzZWwgPSBnZXRCZXR3ZWVuKHRoaXMsIHJhbmdlc1tpXS5mcm9tKCksIHJhbmdlc1tpXS50bygpKTtcbiAgICAgICAgbGluZXMgPSBsaW5lcyA/IGxpbmVzLmNvbmNhdChzZWwpIDogc2VsO1xuICAgICAgfVxuICAgICAgaWYgKGxpbmVTZXAgPT09IGZhbHNlKSByZXR1cm4gbGluZXM7XG4gICAgICBlbHNlIHJldHVybiBsaW5lcy5qb2luKGxpbmVTZXAgfHwgXCJcXG5cIik7XG4gICAgfSxcbiAgICBnZXRTZWxlY3Rpb25zOiBmdW5jdGlvbihsaW5lU2VwKSB7XG4gICAgICB2YXIgcGFydHMgPSBbXSwgcmFuZ2VzID0gdGhpcy5zZWwucmFuZ2VzO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCByYW5nZXMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgdmFyIHNlbCA9IGdldEJldHdlZW4odGhpcywgcmFuZ2VzW2ldLmZyb20oKSwgcmFuZ2VzW2ldLnRvKCkpO1xuICAgICAgICBpZiAobGluZVNlcCAhPT0gZmFsc2UpIHNlbCA9IHNlbC5qb2luKGxpbmVTZXAgfHwgXCJcXG5cIik7XG4gICAgICAgIHBhcnRzW2ldID0gc2VsO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHBhcnRzO1xuICAgIH0sXG4gICAgcmVwbGFjZVNlbGVjdGlvbjogZnVuY3Rpb24oY29kZSwgY29sbGFwc2UsIG9yaWdpbikge1xuICAgICAgdmFyIGR1cCA9IFtdO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLnNlbC5yYW5nZXMubGVuZ3RoOyBpKyspXG4gICAgICAgIGR1cFtpXSA9IGNvZGU7XG4gICAgICB0aGlzLnJlcGxhY2VTZWxlY3Rpb25zKGR1cCwgY29sbGFwc2UsIG9yaWdpbiB8fCBcIitpbnB1dFwiKTtcbiAgICB9LFxuICAgIHJlcGxhY2VTZWxlY3Rpb25zOiBkb2NNZXRob2RPcChmdW5jdGlvbihjb2RlLCBjb2xsYXBzZSwgb3JpZ2luKSB7XG4gICAgICB2YXIgY2hhbmdlcyA9IFtdLCBzZWwgPSB0aGlzLnNlbDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgc2VsLnJhbmdlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YXIgcmFuZ2UgPSBzZWwucmFuZ2VzW2ldO1xuICAgICAgICBjaGFuZ2VzW2ldID0ge2Zyb206IHJhbmdlLmZyb20oKSwgdG86IHJhbmdlLnRvKCksIHRleHQ6IHNwbGl0TGluZXMoY29kZVtpXSksIG9yaWdpbjogb3JpZ2lufTtcbiAgICAgIH1cbiAgICAgIHZhciBuZXdTZWwgPSBjb2xsYXBzZSAmJiBjb2xsYXBzZSAhPSBcImVuZFwiICYmIGNvbXB1dGVSZXBsYWNlZFNlbCh0aGlzLCBjaGFuZ2VzLCBjb2xsYXBzZSk7XG4gICAgICBmb3IgKHZhciBpID0gY2hhbmdlcy5sZW5ndGggLSAxOyBpID49IDA7IGktLSlcbiAgICAgICAgbWFrZUNoYW5nZSh0aGlzLCBjaGFuZ2VzW2ldKTtcbiAgICAgIGlmIChuZXdTZWwpIHNldFNlbGVjdGlvblJlcGxhY2VIaXN0b3J5KHRoaXMsIG5ld1NlbCk7XG4gICAgICBlbHNlIGlmICh0aGlzLmNtKSBlbnN1cmVDdXJzb3JWaXNpYmxlKHRoaXMuY20pO1xuICAgIH0pLFxuICAgIHVuZG86IGRvY01ldGhvZE9wKGZ1bmN0aW9uKCkge21ha2VDaGFuZ2VGcm9tSGlzdG9yeSh0aGlzLCBcInVuZG9cIik7fSksXG4gICAgcmVkbzogZG9jTWV0aG9kT3AoZnVuY3Rpb24oKSB7bWFrZUNoYW5nZUZyb21IaXN0b3J5KHRoaXMsIFwicmVkb1wiKTt9KSxcbiAgICB1bmRvU2VsZWN0aW9uOiBkb2NNZXRob2RPcChmdW5jdGlvbigpIHttYWtlQ2hhbmdlRnJvbUhpc3RvcnkodGhpcywgXCJ1bmRvXCIsIHRydWUpO30pLFxuICAgIHJlZG9TZWxlY3Rpb246IGRvY01ldGhvZE9wKGZ1bmN0aW9uKCkge21ha2VDaGFuZ2VGcm9tSGlzdG9yeSh0aGlzLCBcInJlZG9cIiwgdHJ1ZSk7fSksXG5cbiAgICBzZXRFeHRlbmRpbmc6IGZ1bmN0aW9uKHZhbCkge3RoaXMuZXh0ZW5kID0gdmFsO30sXG4gICAgZ2V0RXh0ZW5kaW5nOiBmdW5jdGlvbigpIHtyZXR1cm4gdGhpcy5leHRlbmQ7fSxcblxuICAgIGhpc3RvcnlTaXplOiBmdW5jdGlvbigpIHtcbiAgICAgIHZhciBoaXN0ID0gdGhpcy5oaXN0b3J5LCBkb25lID0gMCwgdW5kb25lID0gMDtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGlzdC5kb25lLmxlbmd0aDsgaSsrKSBpZiAoIWhpc3QuZG9uZVtpXS5yYW5nZXMpICsrZG9uZTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgaGlzdC51bmRvbmUubGVuZ3RoOyBpKyspIGlmICghaGlzdC51bmRvbmVbaV0ucmFuZ2VzKSArK3VuZG9uZTtcbiAgICAgIHJldHVybiB7dW5kbzogZG9uZSwgcmVkbzogdW5kb25lfTtcbiAgICB9LFxuICAgIGNsZWFySGlzdG9yeTogZnVuY3Rpb24oKSB7dGhpcy5oaXN0b3J5ID0gbmV3IEhpc3RvcnkodGhpcy5oaXN0b3J5Lm1heEdlbmVyYXRpb24pO30sXG5cbiAgICBtYXJrQ2xlYW46IGZ1bmN0aW9uKCkge1xuICAgICAgdGhpcy5jbGVhbkdlbmVyYXRpb24gPSB0aGlzLmNoYW5nZUdlbmVyYXRpb24odHJ1ZSk7XG4gICAgfSxcbiAgICBjaGFuZ2VHZW5lcmF0aW9uOiBmdW5jdGlvbihmb3JjZVNwbGl0KSB7XG4gICAgICBpZiAoZm9yY2VTcGxpdClcbiAgICAgICAgdGhpcy5oaXN0b3J5Lmxhc3RPcCA9IHRoaXMuaGlzdG9yeS5sYXN0U2VsT3AgPSB0aGlzLmhpc3RvcnkubGFzdE9yaWdpbiA9IG51bGw7XG4gICAgICByZXR1cm4gdGhpcy5oaXN0b3J5LmdlbmVyYXRpb247XG4gICAgfSxcbiAgICBpc0NsZWFuOiBmdW5jdGlvbiAoZ2VuKSB7XG4gICAgICByZXR1cm4gdGhpcy5oaXN0b3J5LmdlbmVyYXRpb24gPT0gKGdlbiB8fCB0aGlzLmNsZWFuR2VuZXJhdGlvbik7XG4gICAgfSxcblxuICAgIGdldEhpc3Rvcnk6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHtkb25lOiBjb3B5SGlzdG9yeUFycmF5KHRoaXMuaGlzdG9yeS5kb25lKSxcbiAgICAgICAgICAgICAgdW5kb25lOiBjb3B5SGlzdG9yeUFycmF5KHRoaXMuaGlzdG9yeS51bmRvbmUpfTtcbiAgICB9LFxuICAgIHNldEhpc3Rvcnk6IGZ1bmN0aW9uKGhpc3REYXRhKSB7XG4gICAgICB2YXIgaGlzdCA9IHRoaXMuaGlzdG9yeSA9IG5ldyBIaXN0b3J5KHRoaXMuaGlzdG9yeS5tYXhHZW5lcmF0aW9uKTtcbiAgICAgIGhpc3QuZG9uZSA9IGNvcHlIaXN0b3J5QXJyYXkoaGlzdERhdGEuZG9uZS5zbGljZSgwKSwgbnVsbCwgdHJ1ZSk7XG4gICAgICBoaXN0LnVuZG9uZSA9IGNvcHlIaXN0b3J5QXJyYXkoaGlzdERhdGEudW5kb25lLnNsaWNlKDApLCBudWxsLCB0cnVlKTtcbiAgICB9LFxuXG4gICAgYWRkTGluZUNsYXNzOiBkb2NNZXRob2RPcChmdW5jdGlvbihoYW5kbGUsIHdoZXJlLCBjbHMpIHtcbiAgICAgIHJldHVybiBjaGFuZ2VMaW5lKHRoaXMsIGhhbmRsZSwgd2hlcmUgPT0gXCJndXR0ZXJcIiA/IFwiZ3V0dGVyXCIgOiBcImNsYXNzXCIsIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgdmFyIHByb3AgPSB3aGVyZSA9PSBcInRleHRcIiA/IFwidGV4dENsYXNzXCJcbiAgICAgICAgICAgICAgICAgOiB3aGVyZSA9PSBcImJhY2tncm91bmRcIiA/IFwiYmdDbGFzc1wiXG4gICAgICAgICAgICAgICAgIDogd2hlcmUgPT0gXCJndXR0ZXJcIiA/IFwiZ3V0dGVyQ2xhc3NcIiA6IFwid3JhcENsYXNzXCI7XG4gICAgICAgIGlmICghbGluZVtwcm9wXSkgbGluZVtwcm9wXSA9IGNscztcbiAgICAgICAgZWxzZSBpZiAoY2xhc3NUZXN0KGNscykudGVzdChsaW5lW3Byb3BdKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgICBlbHNlIGxpbmVbcHJvcF0gKz0gXCIgXCIgKyBjbHM7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSk7XG4gICAgfSksXG4gICAgcmVtb3ZlTGluZUNsYXNzOiBkb2NNZXRob2RPcChmdW5jdGlvbihoYW5kbGUsIHdoZXJlLCBjbHMpIHtcbiAgICAgIHJldHVybiBjaGFuZ2VMaW5lKHRoaXMsIGhhbmRsZSwgd2hlcmUgPT0gXCJndXR0ZXJcIiA/IFwiZ3V0dGVyXCIgOiBcImNsYXNzXCIsIGZ1bmN0aW9uKGxpbmUpIHtcbiAgICAgICAgdmFyIHByb3AgPSB3aGVyZSA9PSBcInRleHRcIiA/IFwidGV4dENsYXNzXCJcbiAgICAgICAgICAgICAgICAgOiB3aGVyZSA9PSBcImJhY2tncm91bmRcIiA/IFwiYmdDbGFzc1wiXG4gICAgICAgICAgICAgICAgIDogd2hlcmUgPT0gXCJndXR0ZXJcIiA/IFwiZ3V0dGVyQ2xhc3NcIiA6IFwid3JhcENsYXNzXCI7XG4gICAgICAgIHZhciBjdXIgPSBsaW5lW3Byb3BdO1xuICAgICAgICBpZiAoIWN1cikgcmV0dXJuIGZhbHNlO1xuICAgICAgICBlbHNlIGlmIChjbHMgPT0gbnVsbCkgbGluZVtwcm9wXSA9IG51bGw7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBmb3VuZCA9IGN1ci5tYXRjaChjbGFzc1Rlc3QoY2xzKSk7XG4gICAgICAgICAgaWYgKCFmb3VuZCkgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIHZhciBlbmQgPSBmb3VuZC5pbmRleCArIGZvdW5kWzBdLmxlbmd0aDtcbiAgICAgICAgICBsaW5lW3Byb3BdID0gY3VyLnNsaWNlKDAsIGZvdW5kLmluZGV4KSArICghZm91bmQuaW5kZXggfHwgZW5kID09IGN1ci5sZW5ndGggPyBcIlwiIDogXCIgXCIpICsgY3VyLnNsaWNlKGVuZCkgfHwgbnVsbDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0pO1xuICAgIH0pLFxuXG4gICAgbWFya1RleHQ6IGZ1bmN0aW9uKGZyb20sIHRvLCBvcHRpb25zKSB7XG4gICAgICByZXR1cm4gbWFya1RleHQodGhpcywgY2xpcFBvcyh0aGlzLCBmcm9tKSwgY2xpcFBvcyh0aGlzLCB0byksIG9wdGlvbnMsIFwicmFuZ2VcIik7XG4gICAgfSxcbiAgICBzZXRCb29rbWFyazogZnVuY3Rpb24ocG9zLCBvcHRpb25zKSB7XG4gICAgICB2YXIgcmVhbE9wdHMgPSB7cmVwbGFjZWRXaXRoOiBvcHRpb25zICYmIChvcHRpb25zLm5vZGVUeXBlID09IG51bGwgPyBvcHRpb25zLndpZGdldCA6IG9wdGlvbnMpLFxuICAgICAgICAgICAgICAgICAgICAgIGluc2VydExlZnQ6IG9wdGlvbnMgJiYgb3B0aW9ucy5pbnNlcnRMZWZ0LFxuICAgICAgICAgICAgICAgICAgICAgIGNsZWFyV2hlbkVtcHR5OiBmYWxzZSwgc2hhcmVkOiBvcHRpb25zICYmIG9wdGlvbnMuc2hhcmVkfTtcbiAgICAgIHBvcyA9IGNsaXBQb3ModGhpcywgcG9zKTtcbiAgICAgIHJldHVybiBtYXJrVGV4dCh0aGlzLCBwb3MsIHBvcywgcmVhbE9wdHMsIFwiYm9va21hcmtcIik7XG4gICAgfSxcbiAgICBmaW5kTWFya3NBdDogZnVuY3Rpb24ocG9zKSB7XG4gICAgICBwb3MgPSBjbGlwUG9zKHRoaXMsIHBvcyk7XG4gICAgICB2YXIgbWFya2VycyA9IFtdLCBzcGFucyA9IGdldExpbmUodGhpcywgcG9zLmxpbmUpLm1hcmtlZFNwYW5zO1xuICAgICAgaWYgKHNwYW5zKSBmb3IgKHZhciBpID0gMDsgaSA8IHNwYW5zLmxlbmd0aDsgKytpKSB7XG4gICAgICAgIHZhciBzcGFuID0gc3BhbnNbaV07XG4gICAgICAgIGlmICgoc3Bhbi5mcm9tID09IG51bGwgfHwgc3Bhbi5mcm9tIDw9IHBvcy5jaCkgJiZcbiAgICAgICAgICAgIChzcGFuLnRvID09IG51bGwgfHwgc3Bhbi50byA+PSBwb3MuY2gpKVxuICAgICAgICAgIG1hcmtlcnMucHVzaChzcGFuLm1hcmtlci5wYXJlbnQgfHwgc3Bhbi5tYXJrZXIpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIG1hcmtlcnM7XG4gICAgfSxcbiAgICBmaW5kTWFya3M6IGZ1bmN0aW9uKGZyb20sIHRvLCBmaWx0ZXIpIHtcbiAgICAgIGZyb20gPSBjbGlwUG9zKHRoaXMsIGZyb20pOyB0byA9IGNsaXBQb3ModGhpcywgdG8pO1xuICAgICAgdmFyIGZvdW5kID0gW10sIGxpbmVObyA9IGZyb20ubGluZTtcbiAgICAgIHRoaXMuaXRlcihmcm9tLmxpbmUsIHRvLmxpbmUgKyAxLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIHZhciBzcGFucyA9IGxpbmUubWFya2VkU3BhbnM7XG4gICAgICAgIGlmIChzcGFucykgZm9yICh2YXIgaSA9IDA7IGkgPCBzcGFucy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgIHZhciBzcGFuID0gc3BhbnNbaV07XG4gICAgICAgICAgaWYgKCEobGluZU5vID09IGZyb20ubGluZSAmJiBmcm9tLmNoID4gc3Bhbi50byB8fFxuICAgICAgICAgICAgICAgIHNwYW4uZnJvbSA9PSBudWxsICYmIGxpbmVObyAhPSBmcm9tLmxpbmV8fFxuICAgICAgICAgICAgICAgIGxpbmVObyA9PSB0by5saW5lICYmIHNwYW4uZnJvbSA+IHRvLmNoKSAmJlxuICAgICAgICAgICAgICAoIWZpbHRlciB8fCBmaWx0ZXIoc3Bhbi5tYXJrZXIpKSlcbiAgICAgICAgICAgIGZvdW5kLnB1c2goc3Bhbi5tYXJrZXIucGFyZW50IHx8IHNwYW4ubWFya2VyKTtcbiAgICAgICAgfVxuICAgICAgICArK2xpbmVObztcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGZvdW5kO1xuICAgIH0sXG4gICAgZ2V0QWxsTWFya3M6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIG1hcmtlcnMgPSBbXTtcbiAgICAgIHRoaXMuaXRlcihmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIHZhciBzcHMgPSBsaW5lLm1hcmtlZFNwYW5zO1xuICAgICAgICBpZiAoc3BzKSBmb3IgKHZhciBpID0gMDsgaSA8IHNwcy5sZW5ndGg7ICsraSlcbiAgICAgICAgICBpZiAoc3BzW2ldLmZyb20gIT0gbnVsbCkgbWFya2Vycy5wdXNoKHNwc1tpXS5tYXJrZXIpO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gbWFya2VycztcbiAgICB9LFxuXG4gICAgcG9zRnJvbUluZGV4OiBmdW5jdGlvbihvZmYpIHtcbiAgICAgIHZhciBjaCwgbGluZU5vID0gdGhpcy5maXJzdDtcbiAgICAgIHRoaXMuaXRlcihmdW5jdGlvbihsaW5lKSB7XG4gICAgICAgIHZhciBzeiA9IGxpbmUudGV4dC5sZW5ndGggKyAxO1xuICAgICAgICBpZiAoc3ogPiBvZmYpIHsgY2ggPSBvZmY7IHJldHVybiB0cnVlOyB9XG4gICAgICAgIG9mZiAtPSBzejtcbiAgICAgICAgKytsaW5lTm87XG4gICAgICB9KTtcbiAgICAgIHJldHVybiBjbGlwUG9zKHRoaXMsIFBvcyhsaW5lTm8sIGNoKSk7XG4gICAgfSxcbiAgICBpbmRleEZyb21Qb3M6IGZ1bmN0aW9uIChjb29yZHMpIHtcbiAgICAgIGNvb3JkcyA9IGNsaXBQb3ModGhpcywgY29vcmRzKTtcbiAgICAgIHZhciBpbmRleCA9IGNvb3Jkcy5jaDtcbiAgICAgIGlmIChjb29yZHMubGluZSA8IHRoaXMuZmlyc3QgfHwgY29vcmRzLmNoIDwgMCkgcmV0dXJuIDA7XG4gICAgICB0aGlzLml0ZXIodGhpcy5maXJzdCwgY29vcmRzLmxpbmUsIGZ1bmN0aW9uIChsaW5lKSB7XG4gICAgICAgIGluZGV4ICs9IGxpbmUudGV4dC5sZW5ndGggKyAxO1xuICAgICAgfSk7XG4gICAgICByZXR1cm4gaW5kZXg7XG4gICAgfSxcblxuICAgIGNvcHk6IGZ1bmN0aW9uKGNvcHlIaXN0b3J5KSB7XG4gICAgICB2YXIgZG9jID0gbmV3IERvYyhnZXRMaW5lcyh0aGlzLCB0aGlzLmZpcnN0LCB0aGlzLmZpcnN0ICsgdGhpcy5zaXplKSwgdGhpcy5tb2RlT3B0aW9uLCB0aGlzLmZpcnN0KTtcbiAgICAgIGRvYy5zY3JvbGxUb3AgPSB0aGlzLnNjcm9sbFRvcDsgZG9jLnNjcm9sbExlZnQgPSB0aGlzLnNjcm9sbExlZnQ7XG4gICAgICBkb2Muc2VsID0gdGhpcy5zZWw7XG4gICAgICBkb2MuZXh0ZW5kID0gZmFsc2U7XG4gICAgICBpZiAoY29weUhpc3RvcnkpIHtcbiAgICAgICAgZG9jLmhpc3RvcnkudW5kb0RlcHRoID0gdGhpcy5oaXN0b3J5LnVuZG9EZXB0aDtcbiAgICAgICAgZG9jLnNldEhpc3RvcnkodGhpcy5nZXRIaXN0b3J5KCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGRvYztcbiAgICB9LFxuXG4gICAgbGlua2VkRG9jOiBmdW5jdGlvbihvcHRpb25zKSB7XG4gICAgICBpZiAoIW9wdGlvbnMpIG9wdGlvbnMgPSB7fTtcbiAgICAgIHZhciBmcm9tID0gdGhpcy5maXJzdCwgdG8gPSB0aGlzLmZpcnN0ICsgdGhpcy5zaXplO1xuICAgICAgaWYgKG9wdGlvbnMuZnJvbSAhPSBudWxsICYmIG9wdGlvbnMuZnJvbSA+IGZyb20pIGZyb20gPSBvcHRpb25zLmZyb207XG4gICAgICBpZiAob3B0aW9ucy50byAhPSBudWxsICYmIG9wdGlvbnMudG8gPCB0bykgdG8gPSBvcHRpb25zLnRvO1xuICAgICAgdmFyIGNvcHkgPSBuZXcgRG9jKGdldExpbmVzKHRoaXMsIGZyb20sIHRvKSwgb3B0aW9ucy5tb2RlIHx8IHRoaXMubW9kZU9wdGlvbiwgZnJvbSk7XG4gICAgICBpZiAob3B0aW9ucy5zaGFyZWRIaXN0KSBjb3B5Lmhpc3RvcnkgPSB0aGlzLmhpc3Rvcnk7XG4gICAgICAodGhpcy5saW5rZWQgfHwgKHRoaXMubGlua2VkID0gW10pKS5wdXNoKHtkb2M6IGNvcHksIHNoYXJlZEhpc3Q6IG9wdGlvbnMuc2hhcmVkSGlzdH0pO1xuICAgICAgY29weS5saW5rZWQgPSBbe2RvYzogdGhpcywgaXNQYXJlbnQ6IHRydWUsIHNoYXJlZEhpc3Q6IG9wdGlvbnMuc2hhcmVkSGlzdH1dO1xuICAgICAgY29weVNoYXJlZE1hcmtlcnMoY29weSwgZmluZFNoYXJlZE1hcmtlcnModGhpcykpO1xuICAgICAgcmV0dXJuIGNvcHk7XG4gICAgfSxcbiAgICB1bmxpbmtEb2M6IGZ1bmN0aW9uKG90aGVyKSB7XG4gICAgICBpZiAob3RoZXIgaW5zdGFuY2VvZiBDb2RlTWlycm9yKSBvdGhlciA9IG90aGVyLmRvYztcbiAgICAgIGlmICh0aGlzLmxpbmtlZCkgZm9yICh2YXIgaSA9IDA7IGkgPCB0aGlzLmxpbmtlZC5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgbGluayA9IHRoaXMubGlua2VkW2ldO1xuICAgICAgICBpZiAobGluay5kb2MgIT0gb3RoZXIpIGNvbnRpbnVlO1xuICAgICAgICB0aGlzLmxpbmtlZC5zcGxpY2UoaSwgMSk7XG4gICAgICAgIG90aGVyLnVubGlua0RvYyh0aGlzKTtcbiAgICAgICAgZGV0YWNoU2hhcmVkTWFya2VycyhmaW5kU2hhcmVkTWFya2Vycyh0aGlzKSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgLy8gSWYgdGhlIGhpc3RvcmllcyB3ZXJlIHNoYXJlZCwgc3BsaXQgdGhlbSBhZ2FpblxuICAgICAgaWYgKG90aGVyLmhpc3RvcnkgPT0gdGhpcy5oaXN0b3J5KSB7XG4gICAgICAgIHZhciBzcGxpdElkcyA9IFtvdGhlci5pZF07XG4gICAgICAgIGxpbmtlZERvY3Mob3RoZXIsIGZ1bmN0aW9uKGRvYykge3NwbGl0SWRzLnB1c2goZG9jLmlkKTt9LCB0cnVlKTtcbiAgICAgICAgb3RoZXIuaGlzdG9yeSA9IG5ldyBIaXN0b3J5KG51bGwpO1xuICAgICAgICBvdGhlci5oaXN0b3J5LmRvbmUgPSBjb3B5SGlzdG9yeUFycmF5KHRoaXMuaGlzdG9yeS5kb25lLCBzcGxpdElkcyk7XG4gICAgICAgIG90aGVyLmhpc3RvcnkudW5kb25lID0gY29weUhpc3RvcnlBcnJheSh0aGlzLmhpc3RvcnkudW5kb25lLCBzcGxpdElkcyk7XG4gICAgICB9XG4gICAgfSxcbiAgICBpdGVyTGlua2VkRG9jczogZnVuY3Rpb24oZikge2xpbmtlZERvY3ModGhpcywgZik7fSxcblxuICAgIGdldE1vZGU6IGZ1bmN0aW9uKCkge3JldHVybiB0aGlzLm1vZGU7fSxcbiAgICBnZXRFZGl0b3I6IGZ1bmN0aW9uKCkge3JldHVybiB0aGlzLmNtO31cbiAgfSk7XG5cbiAgLy8gUHVibGljIGFsaWFzLlxuICBEb2MucHJvdG90eXBlLmVhY2hMaW5lID0gRG9jLnByb3RvdHlwZS5pdGVyO1xuXG4gIC8vIFNldCB1cCBtZXRob2RzIG9uIENvZGVNaXJyb3IncyBwcm90b3R5cGUgdG8gcmVkaXJlY3QgdG8gdGhlIGVkaXRvcidzIGRvY3VtZW50LlxuICB2YXIgZG9udERlbGVnYXRlID0gXCJpdGVyIGluc2VydCByZW1vdmUgY29weSBnZXRFZGl0b3JcIi5zcGxpdChcIiBcIik7XG4gIGZvciAodmFyIHByb3AgaW4gRG9jLnByb3RvdHlwZSkgaWYgKERvYy5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkocHJvcCkgJiYgaW5kZXhPZihkb250RGVsZWdhdGUsIHByb3ApIDwgMClcbiAgICBDb2RlTWlycm9yLnByb3RvdHlwZVtwcm9wXSA9IChmdW5jdGlvbihtZXRob2QpIHtcbiAgICAgIHJldHVybiBmdW5jdGlvbigpIHtyZXR1cm4gbWV0aG9kLmFwcGx5KHRoaXMuZG9jLCBhcmd1bWVudHMpO307XG4gICAgfSkoRG9jLnByb3RvdHlwZVtwcm9wXSk7XG5cbiAgZXZlbnRNaXhpbihEb2MpO1xuXG4gIC8vIENhbGwgZiBmb3IgYWxsIGxpbmtlZCBkb2N1bWVudHMuXG4gIGZ1bmN0aW9uIGxpbmtlZERvY3MoZG9jLCBmLCBzaGFyZWRIaXN0T25seSkge1xuICAgIGZ1bmN0aW9uIHByb3BhZ2F0ZShkb2MsIHNraXAsIHNoYXJlZEhpc3QpIHtcbiAgICAgIGlmIChkb2MubGlua2VkKSBmb3IgKHZhciBpID0gMDsgaSA8IGRvYy5saW5rZWQubGVuZ3RoOyArK2kpIHtcbiAgICAgICAgdmFyIHJlbCA9IGRvYy5saW5rZWRbaV07XG4gICAgICAgIGlmIChyZWwuZG9jID09IHNraXApIGNvbnRpbnVlO1xuICAgICAgICB2YXIgc2hhcmVkID0gc2hhcmVkSGlzdCAmJiByZWwuc2hhcmVkSGlzdDtcbiAgICAgICAgaWYgKHNoYXJlZEhpc3RPbmx5ICYmICFzaGFyZWQpIGNvbnRpbnVlO1xuICAgICAgICBmKHJlbC5kb2MsIHNoYXJlZCk7XG4gICAgICAgIHByb3BhZ2F0ZShyZWwuZG9jLCBkb2MsIHNoYXJlZCk7XG4gICAgICB9XG4gICAgfVxuICAgIHByb3BhZ2F0ZShkb2MsIG51bGwsIHRydWUpO1xuICB9XG5cbiAgLy8gQXR0YWNoIGEgZG9jdW1lbnQgdG8gYW4gZWRpdG9yLlxuICBmdW5jdGlvbiBhdHRhY2hEb2MoY20sIGRvYykge1xuICAgIGlmIChkb2MuY20pIHRocm93IG5ldyBFcnJvcihcIlRoaXMgZG9jdW1lbnQgaXMgYWxyZWFkeSBpbiB1c2UuXCIpO1xuICAgIGNtLmRvYyA9IGRvYztcbiAgICBkb2MuY20gPSBjbTtcbiAgICBlc3RpbWF0ZUxpbmVIZWlnaHRzKGNtKTtcbiAgICBsb2FkTW9kZShjbSk7XG4gICAgaWYgKCFjbS5vcHRpb25zLmxpbmVXcmFwcGluZykgZmluZE1heExpbmUoY20pO1xuICAgIGNtLm9wdGlvbnMubW9kZSA9IGRvYy5tb2RlT3B0aW9uO1xuICAgIHJlZ0NoYW5nZShjbSk7XG4gIH1cblxuICAvLyBMSU5FIFVUSUxJVElFU1xuXG4gIC8vIEZpbmQgdGhlIGxpbmUgb2JqZWN0IGNvcnJlc3BvbmRpbmcgdG8gdGhlIGdpdmVuIGxpbmUgbnVtYmVyLlxuICBmdW5jdGlvbiBnZXRMaW5lKGRvYywgbikge1xuICAgIG4gLT0gZG9jLmZpcnN0O1xuICAgIGlmIChuIDwgMCB8fCBuID49IGRvYy5zaXplKSB0aHJvdyBuZXcgRXJyb3IoXCJUaGVyZSBpcyBubyBsaW5lIFwiICsgKG4gKyBkb2MuZmlyc3QpICsgXCIgaW4gdGhlIGRvY3VtZW50LlwiKTtcbiAgICBmb3IgKHZhciBjaHVuayA9IGRvYzsgIWNodW5rLmxpbmVzOykge1xuICAgICAgZm9yICh2YXIgaSA9IDA7OyArK2kpIHtcbiAgICAgICAgdmFyIGNoaWxkID0gY2h1bmsuY2hpbGRyZW5baV0sIHN6ID0gY2hpbGQuY2h1bmtTaXplKCk7XG4gICAgICAgIGlmIChuIDwgc3opIHsgY2h1bmsgPSBjaGlsZDsgYnJlYWs7IH1cbiAgICAgICAgbiAtPSBzejtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGNodW5rLmxpbmVzW25dO1xuICB9XG5cbiAgLy8gR2V0IHRoZSBwYXJ0IG9mIGEgZG9jdW1lbnQgYmV0d2VlbiB0d28gcG9zaXRpb25zLCBhcyBhbiBhcnJheSBvZlxuICAvLyBzdHJpbmdzLlxuICBmdW5jdGlvbiBnZXRCZXR3ZWVuKGRvYywgc3RhcnQsIGVuZCkge1xuICAgIHZhciBvdXQgPSBbXSwgbiA9IHN0YXJ0LmxpbmU7XG4gICAgZG9jLml0ZXIoc3RhcnQubGluZSwgZW5kLmxpbmUgKyAxLCBmdW5jdGlvbihsaW5lKSB7XG4gICAgICB2YXIgdGV4dCA9IGxpbmUudGV4dDtcbiAgICAgIGlmIChuID09IGVuZC5saW5lKSB0ZXh0ID0gdGV4dC5zbGljZSgwLCBlbmQuY2gpO1xuICAgICAgaWYgKG4gPT0gc3RhcnQubGluZSkgdGV4dCA9IHRleHQuc2xpY2Uoc3RhcnQuY2gpO1xuICAgICAgb3V0LnB1c2godGV4dCk7XG4gICAgICArK247XG4gICAgfSk7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuICAvLyBHZXQgdGhlIGxpbmVzIGJldHdlZW4gZnJvbSBhbmQgdG8sIGFzIGFycmF5IG9mIHN0cmluZ3MuXG4gIGZ1bmN0aW9uIGdldExpbmVzKGRvYywgZnJvbSwgdG8pIHtcbiAgICB2YXIgb3V0ID0gW107XG4gICAgZG9jLml0ZXIoZnJvbSwgdG8sIGZ1bmN0aW9uKGxpbmUpIHsgb3V0LnB1c2gobGluZS50ZXh0KTsgfSk7XG4gICAgcmV0dXJuIG91dDtcbiAgfVxuXG4gIC8vIFVwZGF0ZSB0aGUgaGVpZ2h0IG9mIGEgbGluZSwgcHJvcGFnYXRpbmcgdGhlIGhlaWdodCBjaGFuZ2VcbiAgLy8gdXB3YXJkcyB0byBwYXJlbnQgbm9kZXMuXG4gIGZ1bmN0aW9uIHVwZGF0ZUxpbmVIZWlnaHQobGluZSwgaGVpZ2h0KSB7XG4gICAgdmFyIGRpZmYgPSBoZWlnaHQgLSBsaW5lLmhlaWdodDtcbiAgICBpZiAoZGlmZikgZm9yICh2YXIgbiA9IGxpbmU7IG47IG4gPSBuLnBhcmVudCkgbi5oZWlnaHQgKz0gZGlmZjtcbiAgfVxuXG4gIC8vIEdpdmVuIGEgbGluZSBvYmplY3QsIGZpbmQgaXRzIGxpbmUgbnVtYmVyIGJ5IHdhbGtpbmcgdXAgdGhyb3VnaFxuICAvLyBpdHMgcGFyZW50IGxpbmtzLlxuICBmdW5jdGlvbiBsaW5lTm8obGluZSkge1xuICAgIGlmIChsaW5lLnBhcmVudCA9PSBudWxsKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgY3VyID0gbGluZS5wYXJlbnQsIG5vID0gaW5kZXhPZihjdXIubGluZXMsIGxpbmUpO1xuICAgIGZvciAodmFyIGNodW5rID0gY3VyLnBhcmVudDsgY2h1bms7IGN1ciA9IGNodW5rLCBjaHVuayA9IGNodW5rLnBhcmVudCkge1xuICAgICAgZm9yICh2YXIgaSA9IDA7OyArK2kpIHtcbiAgICAgICAgaWYgKGNodW5rLmNoaWxkcmVuW2ldID09IGN1cikgYnJlYWs7XG4gICAgICAgIG5vICs9IGNodW5rLmNoaWxkcmVuW2ldLmNodW5rU2l6ZSgpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbm8gKyBjdXIuZmlyc3Q7XG4gIH1cblxuICAvLyBGaW5kIHRoZSBsaW5lIGF0IHRoZSBnaXZlbiB2ZXJ0aWNhbCBwb3NpdGlvbiwgdXNpbmcgdGhlIGhlaWdodFxuICAvLyBpbmZvcm1hdGlvbiBpbiB0aGUgZG9jdW1lbnQgdHJlZS5cbiAgZnVuY3Rpb24gbGluZUF0SGVpZ2h0KGNodW5rLCBoKSB7XG4gICAgdmFyIG4gPSBjaHVuay5maXJzdDtcbiAgICBvdXRlcjogZG8ge1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaHVuay5jaGlsZHJlbi5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgY2hpbGQgPSBjaHVuay5jaGlsZHJlbltpXSwgY2ggPSBjaGlsZC5oZWlnaHQ7XG4gICAgICAgIGlmIChoIDwgY2gpIHsgY2h1bmsgPSBjaGlsZDsgY29udGludWUgb3V0ZXI7IH1cbiAgICAgICAgaCAtPSBjaDtcbiAgICAgICAgbiArPSBjaGlsZC5jaHVua1NpemUoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuO1xuICAgIH0gd2hpbGUgKCFjaHVuay5saW5lcyk7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaHVuay5saW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIGxpbmUgPSBjaHVuay5saW5lc1tpXSwgbGggPSBsaW5lLmhlaWdodDtcbiAgICAgIGlmIChoIDwgbGgpIGJyZWFrO1xuICAgICAgaCAtPSBsaDtcbiAgICB9XG4gICAgcmV0dXJuIG4gKyBpO1xuICB9XG5cblxuICAvLyBGaW5kIHRoZSBoZWlnaHQgYWJvdmUgdGhlIGdpdmVuIGxpbmUuXG4gIGZ1bmN0aW9uIGhlaWdodEF0TGluZShsaW5lT2JqKSB7XG4gICAgbGluZU9iaiA9IHZpc3VhbExpbmUobGluZU9iaik7XG5cbiAgICB2YXIgaCA9IDAsIGNodW5rID0gbGluZU9iai5wYXJlbnQ7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBjaHVuay5saW5lcy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIGxpbmUgPSBjaHVuay5saW5lc1tpXTtcbiAgICAgIGlmIChsaW5lID09IGxpbmVPYmopIGJyZWFrO1xuICAgICAgZWxzZSBoICs9IGxpbmUuaGVpZ2h0O1xuICAgIH1cbiAgICBmb3IgKHZhciBwID0gY2h1bmsucGFyZW50OyBwOyBjaHVuayA9IHAsIHAgPSBjaHVuay5wYXJlbnQpIHtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgcC5jaGlsZHJlbi5sZW5ndGg7ICsraSkge1xuICAgICAgICB2YXIgY3VyID0gcC5jaGlsZHJlbltpXTtcbiAgICAgICAgaWYgKGN1ciA9PSBjaHVuaykgYnJlYWs7XG4gICAgICAgIGVsc2UgaCArPSBjdXIuaGVpZ2h0O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gaDtcbiAgfVxuXG4gIC8vIEdldCB0aGUgYmlkaSBvcmRlcmluZyBmb3IgdGhlIGdpdmVuIGxpbmUgKGFuZCBjYWNoZSBpdCkuIFJldHVybnNcbiAgLy8gZmFsc2UgZm9yIGxpbmVzIHRoYXQgYXJlIGZ1bGx5IGxlZnQtdG8tcmlnaHQsIGFuZCBhbiBhcnJheSBvZlxuICAvLyBCaWRpU3BhbiBvYmplY3RzIG90aGVyd2lzZS5cbiAgZnVuY3Rpb24gZ2V0T3JkZXIobGluZSkge1xuICAgIHZhciBvcmRlciA9IGxpbmUub3JkZXI7XG4gICAgaWYgKG9yZGVyID09IG51bGwpIG9yZGVyID0gbGluZS5vcmRlciA9IGJpZGlPcmRlcmluZyhsaW5lLnRleHQpO1xuICAgIHJldHVybiBvcmRlcjtcbiAgfVxuXG4gIC8vIEhJU1RPUllcblxuICBmdW5jdGlvbiBIaXN0b3J5KHN0YXJ0R2VuKSB7XG4gICAgLy8gQXJyYXlzIG9mIGNoYW5nZSBldmVudHMgYW5kIHNlbGVjdGlvbnMuIERvaW5nIHNvbWV0aGluZyBhZGRzIGFuXG4gICAgLy8gZXZlbnQgdG8gZG9uZSBhbmQgY2xlYXJzIHVuZG8uIFVuZG9pbmcgbW92ZXMgZXZlbnRzIGZyb20gZG9uZVxuICAgIC8vIHRvIHVuZG9uZSwgcmVkb2luZyBtb3ZlcyB0aGVtIGluIHRoZSBvdGhlciBkaXJlY3Rpb24uXG4gICAgdGhpcy5kb25lID0gW107IHRoaXMudW5kb25lID0gW107XG4gICAgdGhpcy51bmRvRGVwdGggPSBJbmZpbml0eTtcbiAgICAvLyBVc2VkIHRvIHRyYWNrIHdoZW4gY2hhbmdlcyBjYW4gYmUgbWVyZ2VkIGludG8gYSBzaW5nbGUgdW5kb1xuICAgIC8vIGV2ZW50XG4gICAgdGhpcy5sYXN0TW9kVGltZSA9IHRoaXMubGFzdFNlbFRpbWUgPSAwO1xuICAgIHRoaXMubGFzdE9wID0gdGhpcy5sYXN0U2VsT3AgPSBudWxsO1xuICAgIHRoaXMubGFzdE9yaWdpbiA9IHRoaXMubGFzdFNlbE9yaWdpbiA9IG51bGw7XG4gICAgLy8gVXNlZCBieSB0aGUgaXNDbGVhbigpIG1ldGhvZFxuICAgIHRoaXMuZ2VuZXJhdGlvbiA9IHRoaXMubWF4R2VuZXJhdGlvbiA9IHN0YXJ0R2VuIHx8IDE7XG4gIH1cblxuICAvLyBDcmVhdGUgYSBoaXN0b3J5IGNoYW5nZSBldmVudCBmcm9tIGFuIHVwZGF0ZURvYy1zdHlsZSBjaGFuZ2VcbiAgLy8gb2JqZWN0LlxuICBmdW5jdGlvbiBoaXN0b3J5Q2hhbmdlRnJvbUNoYW5nZShkb2MsIGNoYW5nZSkge1xuICAgIHZhciBoaXN0Q2hhbmdlID0ge2Zyb206IGNvcHlQb3MoY2hhbmdlLmZyb20pLCB0bzogY2hhbmdlRW5kKGNoYW5nZSksIHRleHQ6IGdldEJldHdlZW4oZG9jLCBjaGFuZ2UuZnJvbSwgY2hhbmdlLnRvKX07XG4gICAgYXR0YWNoTG9jYWxTcGFucyhkb2MsIGhpc3RDaGFuZ2UsIGNoYW5nZS5mcm9tLmxpbmUsIGNoYW5nZS50by5saW5lICsgMSk7XG4gICAgbGlua2VkRG9jcyhkb2MsIGZ1bmN0aW9uKGRvYykge2F0dGFjaExvY2FsU3BhbnMoZG9jLCBoaXN0Q2hhbmdlLCBjaGFuZ2UuZnJvbS5saW5lLCBjaGFuZ2UudG8ubGluZSArIDEpO30sIHRydWUpO1xuICAgIHJldHVybiBoaXN0Q2hhbmdlO1xuICB9XG5cbiAgLy8gUG9wIGFsbCBzZWxlY3Rpb24gZXZlbnRzIG9mZiB0aGUgZW5kIG9mIGEgaGlzdG9yeSBhcnJheS4gU3RvcCBhdFxuICAvLyBhIGNoYW5nZSBldmVudC5cbiAgZnVuY3Rpb24gY2xlYXJTZWxlY3Rpb25FdmVudHMoYXJyYXkpIHtcbiAgICB3aGlsZSAoYXJyYXkubGVuZ3RoKSB7XG4gICAgICB2YXIgbGFzdCA9IGxzdChhcnJheSk7XG4gICAgICBpZiAobGFzdC5yYW5nZXMpIGFycmF5LnBvcCgpO1xuICAgICAgZWxzZSBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyBGaW5kIHRoZSB0b3AgY2hhbmdlIGV2ZW50IGluIHRoZSBoaXN0b3J5LiBQb3Agb2ZmIHNlbGVjdGlvblxuICAvLyBldmVudHMgdGhhdCBhcmUgaW4gdGhlIHdheS5cbiAgZnVuY3Rpb24gbGFzdENoYW5nZUV2ZW50KGhpc3QsIGZvcmNlKSB7XG4gICAgaWYgKGZvcmNlKSB7XG4gICAgICBjbGVhclNlbGVjdGlvbkV2ZW50cyhoaXN0LmRvbmUpO1xuICAgICAgcmV0dXJuIGxzdChoaXN0LmRvbmUpO1xuICAgIH0gZWxzZSBpZiAoaGlzdC5kb25lLmxlbmd0aCAmJiAhbHN0KGhpc3QuZG9uZSkucmFuZ2VzKSB7XG4gICAgICByZXR1cm4gbHN0KGhpc3QuZG9uZSk7XG4gICAgfSBlbHNlIGlmIChoaXN0LmRvbmUubGVuZ3RoID4gMSAmJiAhaGlzdC5kb25lW2hpc3QuZG9uZS5sZW5ndGggLSAyXS5yYW5nZXMpIHtcbiAgICAgIGhpc3QuZG9uZS5wb3AoKTtcbiAgICAgIHJldHVybiBsc3QoaGlzdC5kb25lKTtcbiAgICB9XG4gIH1cblxuICAvLyBSZWdpc3RlciBhIGNoYW5nZSBpbiB0aGUgaGlzdG9yeS4gTWVyZ2VzIGNoYW5nZXMgdGhhdCBhcmUgd2l0aGluXG4gIC8vIGEgc2luZ2xlIG9wZXJhdGlvbiwgb3JlIGFyZSBjbG9zZSB0b2dldGhlciB3aXRoIGFuIG9yaWdpbiB0aGF0XG4gIC8vIGFsbG93cyBtZXJnaW5nIChzdGFydGluZyB3aXRoIFwiK1wiKSBpbnRvIGEgc2luZ2xlIGV2ZW50LlxuICBmdW5jdGlvbiBhZGRDaGFuZ2VUb0hpc3RvcnkoZG9jLCBjaGFuZ2UsIHNlbEFmdGVyLCBvcElkKSB7XG4gICAgdmFyIGhpc3QgPSBkb2MuaGlzdG9yeTtcbiAgICBoaXN0LnVuZG9uZS5sZW5ndGggPSAwO1xuICAgIHZhciB0aW1lID0gK25ldyBEYXRlLCBjdXI7XG5cbiAgICBpZiAoKGhpc3QubGFzdE9wID09IG9wSWQgfHxcbiAgICAgICAgIGhpc3QubGFzdE9yaWdpbiA9PSBjaGFuZ2Uub3JpZ2luICYmIGNoYW5nZS5vcmlnaW4gJiZcbiAgICAgICAgICgoY2hhbmdlLm9yaWdpbi5jaGFyQXQoMCkgPT0gXCIrXCIgJiYgZG9jLmNtICYmIGhpc3QubGFzdE1vZFRpbWUgPiB0aW1lIC0gZG9jLmNtLm9wdGlvbnMuaGlzdG9yeUV2ZW50RGVsYXkpIHx8XG4gICAgICAgICAgY2hhbmdlLm9yaWdpbi5jaGFyQXQoMCkgPT0gXCIqXCIpKSAmJlxuICAgICAgICAoY3VyID0gbGFzdENoYW5nZUV2ZW50KGhpc3QsIGhpc3QubGFzdE9wID09IG9wSWQpKSkge1xuICAgICAgLy8gTWVyZ2UgdGhpcyBjaGFuZ2UgaW50byB0aGUgbGFzdCBldmVudFxuICAgICAgdmFyIGxhc3QgPSBsc3QoY3VyLmNoYW5nZXMpO1xuICAgICAgaWYgKGNtcChjaGFuZ2UuZnJvbSwgY2hhbmdlLnRvKSA9PSAwICYmIGNtcChjaGFuZ2UuZnJvbSwgbGFzdC50bykgPT0gMCkge1xuICAgICAgICAvLyBPcHRpbWl6ZWQgY2FzZSBmb3Igc2ltcGxlIGluc2VydGlvbiAtLSBkb24ndCB3YW50IHRvIGFkZFxuICAgICAgICAvLyBuZXcgY2hhbmdlc2V0cyBmb3IgZXZlcnkgY2hhcmFjdGVyIHR5cGVkXG4gICAgICAgIGxhc3QudG8gPSBjaGFuZ2VFbmQoY2hhbmdlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEFkZCBuZXcgc3ViLWV2ZW50XG4gICAgICAgIGN1ci5jaGFuZ2VzLnB1c2goaGlzdG9yeUNoYW5nZUZyb21DaGFuZ2UoZG9jLCBjaGFuZ2UpKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgLy8gQ2FuIG5vdCBiZSBtZXJnZWQsIHN0YXJ0IGEgbmV3IGV2ZW50LlxuICAgICAgdmFyIGJlZm9yZSA9IGxzdChoaXN0LmRvbmUpO1xuICAgICAgaWYgKCFiZWZvcmUgfHwgIWJlZm9yZS5yYW5nZXMpXG4gICAgICAgIHB1c2hTZWxlY3Rpb25Ub0hpc3RvcnkoZG9jLnNlbCwgaGlzdC5kb25lKTtcbiAgICAgIGN1ciA9IHtjaGFuZ2VzOiBbaGlzdG9yeUNoYW5nZUZyb21DaGFuZ2UoZG9jLCBjaGFuZ2UpXSxcbiAgICAgICAgICAgICBnZW5lcmF0aW9uOiBoaXN0LmdlbmVyYXRpb259O1xuICAgICAgaGlzdC5kb25lLnB1c2goY3VyKTtcbiAgICAgIHdoaWxlIChoaXN0LmRvbmUubGVuZ3RoID4gaGlzdC51bmRvRGVwdGgpIHtcbiAgICAgICAgaGlzdC5kb25lLnNoaWZ0KCk7XG4gICAgICAgIGlmICghaGlzdC5kb25lWzBdLnJhbmdlcykgaGlzdC5kb25lLnNoaWZ0KCk7XG4gICAgICB9XG4gICAgfVxuICAgIGhpc3QuZG9uZS5wdXNoKHNlbEFmdGVyKTtcbiAgICBoaXN0LmdlbmVyYXRpb24gPSArK2hpc3QubWF4R2VuZXJhdGlvbjtcbiAgICBoaXN0Lmxhc3RNb2RUaW1lID0gaGlzdC5sYXN0U2VsVGltZSA9IHRpbWU7XG4gICAgaGlzdC5sYXN0T3AgPSBoaXN0Lmxhc3RTZWxPcCA9IG9wSWQ7XG4gICAgaGlzdC5sYXN0T3JpZ2luID0gaGlzdC5sYXN0U2VsT3JpZ2luID0gY2hhbmdlLm9yaWdpbjtcblxuICAgIGlmICghbGFzdCkgc2lnbmFsKGRvYywgXCJoaXN0b3J5QWRkZWRcIik7XG4gIH1cblxuICBmdW5jdGlvbiBzZWxlY3Rpb25FdmVudENhbkJlTWVyZ2VkKGRvYywgb3JpZ2luLCBwcmV2LCBzZWwpIHtcbiAgICB2YXIgY2ggPSBvcmlnaW4uY2hhckF0KDApO1xuICAgIHJldHVybiBjaCA9PSBcIipcIiB8fFxuICAgICAgY2ggPT0gXCIrXCIgJiZcbiAgICAgIHByZXYucmFuZ2VzLmxlbmd0aCA9PSBzZWwucmFuZ2VzLmxlbmd0aCAmJlxuICAgICAgcHJldi5zb21ldGhpbmdTZWxlY3RlZCgpID09IHNlbC5zb21ldGhpbmdTZWxlY3RlZCgpICYmXG4gICAgICBuZXcgRGF0ZSAtIGRvYy5oaXN0b3J5Lmxhc3RTZWxUaW1lIDw9IChkb2MuY20gPyBkb2MuY20ub3B0aW9ucy5oaXN0b3J5RXZlbnREZWxheSA6IDUwMCk7XG4gIH1cblxuICAvLyBDYWxsZWQgd2hlbmV2ZXIgdGhlIHNlbGVjdGlvbiBjaGFuZ2VzLCBzZXRzIHRoZSBuZXcgc2VsZWN0aW9uIGFzXG4gIC8vIHRoZSBwZW5kaW5nIHNlbGVjdGlvbiBpbiB0aGUgaGlzdG9yeSwgYW5kIHB1c2hlcyB0aGUgb2xkIHBlbmRpbmdcbiAgLy8gc2VsZWN0aW9uIGludG8gdGhlICdkb25lJyBhcnJheSB3aGVuIGl0IHdhcyBzaWduaWZpY2FudGx5XG4gIC8vIGRpZmZlcmVudCAoaW4gbnVtYmVyIG9mIHNlbGVjdGVkIHJhbmdlcywgZW1wdGluZXNzLCBvciB0aW1lKS5cbiAgZnVuY3Rpb24gYWRkU2VsZWN0aW9uVG9IaXN0b3J5KGRvYywgc2VsLCBvcElkLCBvcHRpb25zKSB7XG4gICAgdmFyIGhpc3QgPSBkb2MuaGlzdG9yeSwgb3JpZ2luID0gb3B0aW9ucyAmJiBvcHRpb25zLm9yaWdpbjtcblxuICAgIC8vIEEgbmV3IGV2ZW50IGlzIHN0YXJ0ZWQgd2hlbiB0aGUgcHJldmlvdXMgb3JpZ2luIGRvZXMgbm90IG1hdGNoXG4gICAgLy8gdGhlIGN1cnJlbnQsIG9yIHRoZSBvcmlnaW5zIGRvbid0IGFsbG93IG1hdGNoaW5nLiBPcmlnaW5zXG4gICAgLy8gc3RhcnRpbmcgd2l0aCAqIGFyZSBhbHdheXMgbWVyZ2VkLCB0aG9zZSBzdGFydGluZyB3aXRoICsgYXJlXG4gICAgLy8gbWVyZ2VkIHdoZW4gc2ltaWxhciBhbmQgY2xvc2UgdG9nZXRoZXIgaW4gdGltZS5cbiAgICBpZiAob3BJZCA9PSBoaXN0Lmxhc3RTZWxPcCB8fFxuICAgICAgICAob3JpZ2luICYmIGhpc3QubGFzdFNlbE9yaWdpbiA9PSBvcmlnaW4gJiZcbiAgICAgICAgIChoaXN0Lmxhc3RNb2RUaW1lID09IGhpc3QubGFzdFNlbFRpbWUgJiYgaGlzdC5sYXN0T3JpZ2luID09IG9yaWdpbiB8fFxuICAgICAgICAgIHNlbGVjdGlvbkV2ZW50Q2FuQmVNZXJnZWQoZG9jLCBvcmlnaW4sIGxzdChoaXN0LmRvbmUpLCBzZWwpKSkpXG4gICAgICBoaXN0LmRvbmVbaGlzdC5kb25lLmxlbmd0aCAtIDFdID0gc2VsO1xuICAgIGVsc2VcbiAgICAgIHB1c2hTZWxlY3Rpb25Ub0hpc3Rvcnkoc2VsLCBoaXN0LmRvbmUpO1xuXG4gICAgaGlzdC5sYXN0U2VsVGltZSA9ICtuZXcgRGF0ZTtcbiAgICBoaXN0Lmxhc3RTZWxPcmlnaW4gPSBvcmlnaW47XG4gICAgaGlzdC5sYXN0U2VsT3AgPSBvcElkO1xuICAgIGlmIChvcHRpb25zICYmIG9wdGlvbnMuY2xlYXJSZWRvICE9PSBmYWxzZSlcbiAgICAgIGNsZWFyU2VsZWN0aW9uRXZlbnRzKGhpc3QudW5kb25lKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHB1c2hTZWxlY3Rpb25Ub0hpc3Rvcnkoc2VsLCBkZXN0KSB7XG4gICAgdmFyIHRvcCA9IGxzdChkZXN0KTtcbiAgICBpZiAoISh0b3AgJiYgdG9wLnJhbmdlcyAmJiB0b3AuZXF1YWxzKHNlbCkpKVxuICAgICAgZGVzdC5wdXNoKHNlbCk7XG4gIH1cblxuICAvLyBVc2VkIHRvIHN0b3JlIG1hcmtlZCBzcGFuIGluZm9ybWF0aW9uIGluIHRoZSBoaXN0b3J5LlxuICBmdW5jdGlvbiBhdHRhY2hMb2NhbFNwYW5zKGRvYywgY2hhbmdlLCBmcm9tLCB0bykge1xuICAgIHZhciBleGlzdGluZyA9IGNoYW5nZVtcInNwYW5zX1wiICsgZG9jLmlkXSwgbiA9IDA7XG4gICAgZG9jLml0ZXIoTWF0aC5tYXgoZG9jLmZpcnN0LCBmcm9tKSwgTWF0aC5taW4oZG9jLmZpcnN0ICsgZG9jLnNpemUsIHRvKSwgZnVuY3Rpb24obGluZSkge1xuICAgICAgaWYgKGxpbmUubWFya2VkU3BhbnMpXG4gICAgICAgIChleGlzdGluZyB8fCAoZXhpc3RpbmcgPSBjaGFuZ2VbXCJzcGFuc19cIiArIGRvYy5pZF0gPSB7fSkpW25dID0gbGluZS5tYXJrZWRTcGFucztcbiAgICAgICsrbjtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIFdoZW4gdW4vcmUtZG9pbmcgcmVzdG9yZXMgdGV4dCBjb250YWluaW5nIG1hcmtlZCBzcGFucywgdGhvc2VcbiAgLy8gdGhhdCBoYXZlIGJlZW4gZXhwbGljaXRseSBjbGVhcmVkIHNob3VsZCBub3QgYmUgcmVzdG9yZWQuXG4gIGZ1bmN0aW9uIHJlbW92ZUNsZWFyZWRTcGFucyhzcGFucykge1xuICAgIGlmICghc3BhbnMpIHJldHVybiBudWxsO1xuICAgIGZvciAodmFyIGkgPSAwLCBvdXQ7IGkgPCBzcGFucy5sZW5ndGg7ICsraSkge1xuICAgICAgaWYgKHNwYW5zW2ldLm1hcmtlci5leHBsaWNpdGx5Q2xlYXJlZCkgeyBpZiAoIW91dCkgb3V0ID0gc3BhbnMuc2xpY2UoMCwgaSk7IH1cbiAgICAgIGVsc2UgaWYgKG91dCkgb3V0LnB1c2goc3BhbnNbaV0pO1xuICAgIH1cbiAgICByZXR1cm4gIW91dCA/IHNwYW5zIDogb3V0Lmxlbmd0aCA/IG91dCA6IG51bGw7XG4gIH1cblxuICAvLyBSZXRyaWV2ZSBhbmQgZmlsdGVyIHRoZSBvbGQgbWFya2VkIHNwYW5zIHN0b3JlZCBpbiBhIGNoYW5nZSBldmVudC5cbiAgZnVuY3Rpb24gZ2V0T2xkU3BhbnMoZG9jLCBjaGFuZ2UpIHtcbiAgICB2YXIgZm91bmQgPSBjaGFuZ2VbXCJzcGFuc19cIiArIGRvYy5pZF07XG4gICAgaWYgKCFmb3VuZCkgcmV0dXJuIG51bGw7XG4gICAgZm9yICh2YXIgaSA9IDAsIG53ID0gW107IGkgPCBjaGFuZ2UudGV4dC5sZW5ndGg7ICsraSlcbiAgICAgIG53LnB1c2gocmVtb3ZlQ2xlYXJlZFNwYW5zKGZvdW5kW2ldKSk7XG4gICAgcmV0dXJuIG53O1xuICB9XG5cbiAgLy8gVXNlZCBib3RoIHRvIHByb3ZpZGUgYSBKU09OLXNhZmUgb2JqZWN0IGluIC5nZXRIaXN0b3J5LCBhbmQsIHdoZW5cbiAgLy8gZGV0YWNoaW5nIGEgZG9jdW1lbnQsIHRvIHNwbGl0IHRoZSBoaXN0b3J5IGluIHR3b1xuICBmdW5jdGlvbiBjb3B5SGlzdG9yeUFycmF5KGV2ZW50cywgbmV3R3JvdXAsIGluc3RhbnRpYXRlU2VsKSB7XG4gICAgZm9yICh2YXIgaSA9IDAsIGNvcHkgPSBbXTsgaSA8IGV2ZW50cy5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIGV2ZW50ID0gZXZlbnRzW2ldO1xuICAgICAgaWYgKGV2ZW50LnJhbmdlcykge1xuICAgICAgICBjb3B5LnB1c2goaW5zdGFudGlhdGVTZWwgPyBTZWxlY3Rpb24ucHJvdG90eXBlLmRlZXBDb3B5LmNhbGwoZXZlbnQpIDogZXZlbnQpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHZhciBjaGFuZ2VzID0gZXZlbnQuY2hhbmdlcywgbmV3Q2hhbmdlcyA9IFtdO1xuICAgICAgY29weS5wdXNoKHtjaGFuZ2VzOiBuZXdDaGFuZ2VzfSk7XG4gICAgICBmb3IgKHZhciBqID0gMDsgaiA8IGNoYW5nZXMubGVuZ3RoOyArK2opIHtcbiAgICAgICAgdmFyIGNoYW5nZSA9IGNoYW5nZXNbal0sIG07XG4gICAgICAgIG5ld0NoYW5nZXMucHVzaCh7ZnJvbTogY2hhbmdlLmZyb20sIHRvOiBjaGFuZ2UudG8sIHRleHQ6IGNoYW5nZS50ZXh0fSk7XG4gICAgICAgIGlmIChuZXdHcm91cCkgZm9yICh2YXIgcHJvcCBpbiBjaGFuZ2UpIGlmIChtID0gcHJvcC5tYXRjaCgvXnNwYW5zXyhcXGQrKSQvKSkge1xuICAgICAgICAgIGlmIChpbmRleE9mKG5ld0dyb3VwLCBOdW1iZXIobVsxXSkpID4gLTEpIHtcbiAgICAgICAgICAgIGxzdChuZXdDaGFuZ2VzKVtwcm9wXSA9IGNoYW5nZVtwcm9wXTtcbiAgICAgICAgICAgIGRlbGV0ZSBjaGFuZ2VbcHJvcF07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBjb3B5O1xuICB9XG5cbiAgLy8gUmViYXNpbmcvcmVzZXR0aW5nIGhpc3RvcnkgdG8gZGVhbCB3aXRoIGV4dGVybmFsbHktc291cmNlZCBjaGFuZ2VzXG5cbiAgZnVuY3Rpb24gcmViYXNlSGlzdFNlbFNpbmdsZShwb3MsIGZyb20sIHRvLCBkaWZmKSB7XG4gICAgaWYgKHRvIDwgcG9zLmxpbmUpIHtcbiAgICAgIHBvcy5saW5lICs9IGRpZmY7XG4gICAgfSBlbHNlIGlmIChmcm9tIDwgcG9zLmxpbmUpIHtcbiAgICAgIHBvcy5saW5lID0gZnJvbTtcbiAgICAgIHBvcy5jaCA9IDA7XG4gICAgfVxuICB9XG5cbiAgLy8gVHJpZXMgdG8gcmViYXNlIGFuIGFycmF5IG9mIGhpc3RvcnkgZXZlbnRzIGdpdmVuIGEgY2hhbmdlIGluIHRoZVxuICAvLyBkb2N1bWVudC4gSWYgdGhlIGNoYW5nZSB0b3VjaGVzIHRoZSBzYW1lIGxpbmVzIGFzIHRoZSBldmVudCwgdGhlXG4gIC8vIGV2ZW50LCBhbmQgZXZlcnl0aGluZyAnYmVoaW5kJyBpdCwgaXMgZGlzY2FyZGVkLiBJZiB0aGUgY2hhbmdlIGlzXG4gIC8vIGJlZm9yZSB0aGUgZXZlbnQsIHRoZSBldmVudCdzIHBvc2l0aW9ucyBhcmUgdXBkYXRlZC4gVXNlcyBhXG4gIC8vIGNvcHktb24td3JpdGUgc2NoZW1lIGZvciB0aGUgcG9zaXRpb25zLCB0byBhdm9pZCBoYXZpbmcgdG9cbiAgLy8gcmVhbGxvY2F0ZSB0aGVtIGFsbCBvbiBldmVyeSByZWJhc2UsIGJ1dCBhbHNvIGF2b2lkIHByb2JsZW1zIHdpdGhcbiAgLy8gc2hhcmVkIHBvc2l0aW9uIG9iamVjdHMgYmVpbmcgdW5zYWZlbHkgdXBkYXRlZC5cbiAgZnVuY3Rpb24gcmViYXNlSGlzdEFycmF5KGFycmF5LCBmcm9tLCB0bywgZGlmZikge1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBzdWIgPSBhcnJheVtpXSwgb2sgPSB0cnVlO1xuICAgICAgaWYgKHN1Yi5yYW5nZXMpIHtcbiAgICAgICAgaWYgKCFzdWIuY29waWVkKSB7IHN1YiA9IGFycmF5W2ldID0gc3ViLmRlZXBDb3B5KCk7IHN1Yi5jb3BpZWQgPSB0cnVlOyB9XG4gICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgc3ViLnJhbmdlcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgIHJlYmFzZUhpc3RTZWxTaW5nbGUoc3ViLnJhbmdlc1tqXS5hbmNob3IsIGZyb20sIHRvLCBkaWZmKTtcbiAgICAgICAgICByZWJhc2VIaXN0U2VsU2luZ2xlKHN1Yi5yYW5nZXNbal0uaGVhZCwgZnJvbSwgdG8sIGRpZmYpO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgZm9yICh2YXIgaiA9IDA7IGogPCBzdWIuY2hhbmdlcy5sZW5ndGg7ICsraikge1xuICAgICAgICB2YXIgY3VyID0gc3ViLmNoYW5nZXNbal07XG4gICAgICAgIGlmICh0byA8IGN1ci5mcm9tLmxpbmUpIHtcbiAgICAgICAgICBjdXIuZnJvbSA9IFBvcyhjdXIuZnJvbS5saW5lICsgZGlmZiwgY3VyLmZyb20uY2gpO1xuICAgICAgICAgIGN1ci50byA9IFBvcyhjdXIudG8ubGluZSArIGRpZmYsIGN1ci50by5jaCk7XG4gICAgICAgIH0gZWxzZSBpZiAoZnJvbSA8PSBjdXIudG8ubGluZSkge1xuICAgICAgICAgIG9rID0gZmFsc2U7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghb2spIHtcbiAgICAgICAgYXJyYXkuc3BsaWNlKDAsIGkgKyAxKTtcbiAgICAgICAgaSA9IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gcmViYXNlSGlzdChoaXN0LCBjaGFuZ2UpIHtcbiAgICB2YXIgZnJvbSA9IGNoYW5nZS5mcm9tLmxpbmUsIHRvID0gY2hhbmdlLnRvLmxpbmUsIGRpZmYgPSBjaGFuZ2UudGV4dC5sZW5ndGggLSAodG8gLSBmcm9tKSAtIDE7XG4gICAgcmViYXNlSGlzdEFycmF5KGhpc3QuZG9uZSwgZnJvbSwgdG8sIGRpZmYpO1xuICAgIHJlYmFzZUhpc3RBcnJheShoaXN0LnVuZG9uZSwgZnJvbSwgdG8sIGRpZmYpO1xuICB9XG5cbiAgLy8gRVZFTlQgVVRJTElUSUVTXG5cbiAgLy8gRHVlIHRvIHRoZSBmYWN0IHRoYXQgd2Ugc3RpbGwgc3VwcG9ydCBqdXJhc3NpYyBJRSB2ZXJzaW9ucywgc29tZVxuICAvLyBjb21wYXRpYmlsaXR5IHdyYXBwZXJzIGFyZSBuZWVkZWQuXG5cbiAgdmFyIGVfcHJldmVudERlZmF1bHQgPSBDb2RlTWlycm9yLmVfcHJldmVudERlZmF1bHQgPSBmdW5jdGlvbihlKSB7XG4gICAgaWYgKGUucHJldmVudERlZmF1bHQpIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlbHNlIGUucmV0dXJuVmFsdWUgPSBmYWxzZTtcbiAgfTtcbiAgdmFyIGVfc3RvcFByb3BhZ2F0aW9uID0gQ29kZU1pcnJvci5lX3N0b3BQcm9wYWdhdGlvbiA9IGZ1bmN0aW9uKGUpIHtcbiAgICBpZiAoZS5zdG9wUHJvcGFnYXRpb24pIGUuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgZWxzZSBlLmNhbmNlbEJ1YmJsZSA9IHRydWU7XG4gIH07XG4gIGZ1bmN0aW9uIGVfZGVmYXVsdFByZXZlbnRlZChlKSB7XG4gICAgcmV0dXJuIGUuZGVmYXVsdFByZXZlbnRlZCAhPSBudWxsID8gZS5kZWZhdWx0UHJldmVudGVkIDogZS5yZXR1cm5WYWx1ZSA9PSBmYWxzZTtcbiAgfVxuICB2YXIgZV9zdG9wID0gQ29kZU1pcnJvci5lX3N0b3AgPSBmdW5jdGlvbihlKSB7ZV9wcmV2ZW50RGVmYXVsdChlKTsgZV9zdG9wUHJvcGFnYXRpb24oZSk7fTtcblxuICBmdW5jdGlvbiBlX3RhcmdldChlKSB7cmV0dXJuIGUudGFyZ2V0IHx8IGUuc3JjRWxlbWVudDt9XG4gIGZ1bmN0aW9uIGVfYnV0dG9uKGUpIHtcbiAgICB2YXIgYiA9IGUud2hpY2g7XG4gICAgaWYgKGIgPT0gbnVsbCkge1xuICAgICAgaWYgKGUuYnV0dG9uICYgMSkgYiA9IDE7XG4gICAgICBlbHNlIGlmIChlLmJ1dHRvbiAmIDIpIGIgPSAzO1xuICAgICAgZWxzZSBpZiAoZS5idXR0b24gJiA0KSBiID0gMjtcbiAgICB9XG4gICAgaWYgKG1hYyAmJiBlLmN0cmxLZXkgJiYgYiA9PSAxKSBiID0gMztcbiAgICByZXR1cm4gYjtcbiAgfVxuXG4gIC8vIEVWRU5UIEhBTkRMSU5HXG5cbiAgLy8gTGlnaHR3ZWlnaHQgZXZlbnQgZnJhbWV3b3JrLiBvbi9vZmYgYWxzbyB3b3JrIG9uIERPTSBub2RlcyxcbiAgLy8gcmVnaXN0ZXJpbmcgbmF0aXZlIERPTSBoYW5kbGVycy5cblxuICB2YXIgb24gPSBDb2RlTWlycm9yLm9uID0gZnVuY3Rpb24oZW1pdHRlciwgdHlwZSwgZikge1xuICAgIGlmIChlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIpXG4gICAgICBlbWl0dGVyLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZiwgZmFsc2UpO1xuICAgIGVsc2UgaWYgKGVtaXR0ZXIuYXR0YWNoRXZlbnQpXG4gICAgICBlbWl0dGVyLmF0dGFjaEV2ZW50KFwib25cIiArIHR5cGUsIGYpO1xuICAgIGVsc2Uge1xuICAgICAgdmFyIG1hcCA9IGVtaXR0ZXIuX2hhbmRsZXJzIHx8IChlbWl0dGVyLl9oYW5kbGVycyA9IHt9KTtcbiAgICAgIHZhciBhcnIgPSBtYXBbdHlwZV0gfHwgKG1hcFt0eXBlXSA9IFtdKTtcbiAgICAgIGFyci5wdXNoKGYpO1xuICAgIH1cbiAgfTtcblxuICB2YXIgb2ZmID0gQ29kZU1pcnJvci5vZmYgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlLCBmKSB7XG4gICAgaWYgKGVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcilcbiAgICAgIGVtaXR0ZXIucmVtb3ZlRXZlbnRMaXN0ZW5lcih0eXBlLCBmLCBmYWxzZSk7XG4gICAgZWxzZSBpZiAoZW1pdHRlci5kZXRhY2hFdmVudClcbiAgICAgIGVtaXR0ZXIuZGV0YWNoRXZlbnQoXCJvblwiICsgdHlwZSwgZik7XG4gICAgZWxzZSB7XG4gICAgICB2YXIgYXJyID0gZW1pdHRlci5faGFuZGxlcnMgJiYgZW1pdHRlci5faGFuZGxlcnNbdHlwZV07XG4gICAgICBpZiAoIWFycikgcmV0dXJuO1xuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcnIubGVuZ3RoOyArK2kpXG4gICAgICAgIGlmIChhcnJbaV0gPT0gZikgeyBhcnIuc3BsaWNlKGksIDEpOyBicmVhazsgfVxuICAgIH1cbiAgfTtcblxuICB2YXIgc2lnbmFsID0gQ29kZU1pcnJvci5zaWduYWwgPSBmdW5jdGlvbihlbWl0dGVyLCB0eXBlIC8qLCB2YWx1ZXMuLi4qLykge1xuICAgIHZhciBhcnIgPSBlbWl0dGVyLl9oYW5kbGVycyAmJiBlbWl0dGVyLl9oYW5kbGVyc1t0eXBlXTtcbiAgICBpZiAoIWFycikgcmV0dXJuO1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7ICsraSkgYXJyW2ldLmFwcGx5KG51bGwsIGFyZ3MpO1xuICB9O1xuXG4gIHZhciBvcnBoYW5EZWxheWVkQ2FsbGJhY2tzID0gbnVsbDtcblxuICAvLyBPZnRlbiwgd2Ugd2FudCB0byBzaWduYWwgZXZlbnRzIGF0IGEgcG9pbnQgd2hlcmUgd2UgYXJlIGluIHRoZVxuICAvLyBtaWRkbGUgb2Ygc29tZSB3b3JrLCBidXQgZG9uJ3Qgd2FudCB0aGUgaGFuZGxlciB0byBzdGFydCBjYWxsaW5nXG4gIC8vIG90aGVyIG1ldGhvZHMgb24gdGhlIGVkaXRvciwgd2hpY2ggbWlnaHQgYmUgaW4gYW4gaW5jb25zaXN0ZW50XG4gIC8vIHN0YXRlIG9yIHNpbXBseSBub3QgZXhwZWN0IGFueSBvdGhlciBldmVudHMgdG8gaGFwcGVuLlxuICAvLyBzaWduYWxMYXRlciBsb29rcyB3aGV0aGVyIHRoZXJlIGFyZSBhbnkgaGFuZGxlcnMsIGFuZCBzY2hlZHVsZXNcbiAgLy8gdGhlbSB0byBiZSBleGVjdXRlZCB3aGVuIHRoZSBsYXN0IG9wZXJhdGlvbiBlbmRzLCBvciwgaWYgbm9cbiAgLy8gb3BlcmF0aW9uIGlzIGFjdGl2ZSwgd2hlbiBhIHRpbWVvdXQgZmlyZXMuXG4gIGZ1bmN0aW9uIHNpZ25hbExhdGVyKGVtaXR0ZXIsIHR5cGUgLyosIHZhbHVlcy4uLiovKSB7XG4gICAgdmFyIGFyciA9IGVtaXR0ZXIuX2hhbmRsZXJzICYmIGVtaXR0ZXIuX2hhbmRsZXJzW3R5cGVdO1xuICAgIGlmICghYXJyKSByZXR1cm47XG4gICAgdmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDIpLCBsaXN0O1xuICAgIGlmIChvcGVyYXRpb25Hcm91cCkge1xuICAgICAgbGlzdCA9IG9wZXJhdGlvbkdyb3VwLmRlbGF5ZWRDYWxsYmFja3M7XG4gICAgfSBlbHNlIGlmIChvcnBoYW5EZWxheWVkQ2FsbGJhY2tzKSB7XG4gICAgICBsaXN0ID0gb3JwaGFuRGVsYXllZENhbGxiYWNrcztcbiAgICB9IGVsc2Uge1xuICAgICAgbGlzdCA9IG9ycGhhbkRlbGF5ZWRDYWxsYmFja3MgPSBbXTtcbiAgICAgIHNldFRpbWVvdXQoZmlyZU9ycGhhbkRlbGF5ZWQsIDApO1xuICAgIH1cbiAgICBmdW5jdGlvbiBibmQoZikge3JldHVybiBmdW5jdGlvbigpe2YuYXBwbHkobnVsbCwgYXJncyk7fTt9O1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXJyLmxlbmd0aDsgKytpKVxuICAgICAgbGlzdC5wdXNoKGJuZChhcnJbaV0pKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZpcmVPcnBoYW5EZWxheWVkKCkge1xuICAgIHZhciBkZWxheWVkID0gb3JwaGFuRGVsYXllZENhbGxiYWNrcztcbiAgICBvcnBoYW5EZWxheWVkQ2FsbGJhY2tzID0gbnVsbDtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGRlbGF5ZWQubGVuZ3RoOyArK2kpIGRlbGF5ZWRbaV0oKTtcbiAgfVxuXG4gIC8vIFRoZSBET00gZXZlbnRzIHRoYXQgQ29kZU1pcnJvciBoYW5kbGVzIGNhbiBiZSBvdmVycmlkZGVuIGJ5XG4gIC8vIHJlZ2lzdGVyaW5nIGEgKG5vbi1ET00pIGhhbmRsZXIgb24gdGhlIGVkaXRvciBmb3IgdGhlIGV2ZW50IG5hbWUsXG4gIC8vIGFuZCBwcmV2ZW50RGVmYXVsdC1pbmcgdGhlIGV2ZW50IGluIHRoYXQgaGFuZGxlci5cbiAgZnVuY3Rpb24gc2lnbmFsRE9NRXZlbnQoY20sIGUsIG92ZXJyaWRlKSB7XG4gICAgaWYgKHR5cGVvZiBlID09IFwic3RyaW5nXCIpXG4gICAgICBlID0ge3R5cGU6IGUsIHByZXZlbnREZWZhdWx0OiBmdW5jdGlvbigpIHsgdGhpcy5kZWZhdWx0UHJldmVudGVkID0gdHJ1ZTsgfX07XG4gICAgc2lnbmFsKGNtLCBvdmVycmlkZSB8fCBlLnR5cGUsIGNtLCBlKTtcbiAgICByZXR1cm4gZV9kZWZhdWx0UHJldmVudGVkKGUpIHx8IGUuY29kZW1pcnJvcklnbm9yZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNpZ25hbEN1cnNvckFjdGl2aXR5KGNtKSB7XG4gICAgdmFyIGFyciA9IGNtLl9oYW5kbGVycyAmJiBjbS5faGFuZGxlcnMuY3Vyc29yQWN0aXZpdHk7XG4gICAgaWYgKCFhcnIpIHJldHVybjtcbiAgICB2YXIgc2V0ID0gY20uY3VyT3AuY3Vyc29yQWN0aXZpdHlIYW5kbGVycyB8fCAoY20uY3VyT3AuY3Vyc29yQWN0aXZpdHlIYW5kbGVycyA9IFtdKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFyci5sZW5ndGg7ICsraSkgaWYgKGluZGV4T2Yoc2V0LCBhcnJbaV0pID09IC0xKVxuICAgICAgc2V0LnB1c2goYXJyW2ldKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGhhc0hhbmRsZXIoZW1pdHRlciwgdHlwZSkge1xuICAgIHZhciBhcnIgPSBlbWl0dGVyLl9oYW5kbGVycyAmJiBlbWl0dGVyLl9oYW5kbGVyc1t0eXBlXTtcbiAgICByZXR1cm4gYXJyICYmIGFyci5sZW5ndGggPiAwO1xuICB9XG5cbiAgLy8gQWRkIG9uIGFuZCBvZmYgbWV0aG9kcyB0byBhIGNvbnN0cnVjdG9yJ3MgcHJvdG90eXBlLCB0byBtYWtlXG4gIC8vIHJlZ2lzdGVyaW5nIGV2ZW50cyBvbiBzdWNoIG9iamVjdHMgbW9yZSBjb252ZW5pZW50LlxuICBmdW5jdGlvbiBldmVudE1peGluKGN0b3IpIHtcbiAgICBjdG9yLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uKHR5cGUsIGYpIHtvbih0aGlzLCB0eXBlLCBmKTt9O1xuICAgIGN0b3IucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uKHR5cGUsIGYpIHtvZmYodGhpcywgdHlwZSwgZik7fTtcbiAgfVxuXG4gIC8vIE1JU0MgVVRJTElUSUVTXG5cbiAgLy8gTnVtYmVyIG9mIHBpeGVscyBhZGRlZCB0byBzY3JvbGxlciBhbmQgc2l6ZXIgdG8gaGlkZSBzY3JvbGxiYXJcbiAgdmFyIHNjcm9sbGVyR2FwID0gMzA7XG5cbiAgLy8gUmV0dXJuZWQgb3IgdGhyb3duIGJ5IHZhcmlvdXMgcHJvdG9jb2xzIHRvIHNpZ25hbCAnSSdtIG5vdFxuICAvLyBoYW5kbGluZyB0aGlzJy5cbiAgdmFyIFBhc3MgPSBDb2RlTWlycm9yLlBhc3MgPSB7dG9TdHJpbmc6IGZ1bmN0aW9uKCl7cmV0dXJuIFwiQ29kZU1pcnJvci5QYXNzXCI7fX07XG5cbiAgLy8gUmV1c2VkIG9wdGlvbiBvYmplY3RzIGZvciBzZXRTZWxlY3Rpb24gJiBmcmllbmRzXG4gIHZhciBzZWxfZG9udFNjcm9sbCA9IHtzY3JvbGw6IGZhbHNlfSwgc2VsX21vdXNlID0ge29yaWdpbjogXCIqbW91c2VcIn0sIHNlbF9tb3ZlID0ge29yaWdpbjogXCIrbW92ZVwifTtcblxuICBmdW5jdGlvbiBEZWxheWVkKCkge3RoaXMuaWQgPSBudWxsO31cbiAgRGVsYXllZC5wcm90b3R5cGUuc2V0ID0gZnVuY3Rpb24obXMsIGYpIHtcbiAgICBjbGVhclRpbWVvdXQodGhpcy5pZCk7XG4gICAgdGhpcy5pZCA9IHNldFRpbWVvdXQoZiwgbXMpO1xuICB9O1xuXG4gIC8vIENvdW50cyB0aGUgY29sdW1uIG9mZnNldCBpbiBhIHN0cmluZywgdGFraW5nIHRhYnMgaW50byBhY2NvdW50LlxuICAvLyBVc2VkIG1vc3RseSB0byBmaW5kIGluZGVudGF0aW9uLlxuICB2YXIgY291bnRDb2x1bW4gPSBDb2RlTWlycm9yLmNvdW50Q29sdW1uID0gZnVuY3Rpb24oc3RyaW5nLCBlbmQsIHRhYlNpemUsIHN0YXJ0SW5kZXgsIHN0YXJ0VmFsdWUpIHtcbiAgICBpZiAoZW5kID09IG51bGwpIHtcbiAgICAgIGVuZCA9IHN0cmluZy5zZWFyY2goL1teXFxzXFx1MDBhMF0vKTtcbiAgICAgIGlmIChlbmQgPT0gLTEpIGVuZCA9IHN0cmluZy5sZW5ndGg7XG4gICAgfVxuICAgIGZvciAodmFyIGkgPSBzdGFydEluZGV4IHx8IDAsIG4gPSBzdGFydFZhbHVlIHx8IDA7Oykge1xuICAgICAgdmFyIG5leHRUYWIgPSBzdHJpbmcuaW5kZXhPZihcIlxcdFwiLCBpKTtcbiAgICAgIGlmIChuZXh0VGFiIDwgMCB8fCBuZXh0VGFiID49IGVuZClcbiAgICAgICAgcmV0dXJuIG4gKyAoZW5kIC0gaSk7XG4gICAgICBuICs9IG5leHRUYWIgLSBpO1xuICAgICAgbiArPSB0YWJTaXplIC0gKG4gJSB0YWJTaXplKTtcbiAgICAgIGkgPSBuZXh0VGFiICsgMTtcbiAgICB9XG4gIH07XG5cbiAgLy8gVGhlIGludmVyc2Ugb2YgY291bnRDb2x1bW4gLS0gZmluZCB0aGUgb2Zmc2V0IHRoYXQgY29ycmVzcG9uZHMgdG9cbiAgLy8gYSBwYXJ0aWN1bGFyIGNvbHVtbi5cbiAgZnVuY3Rpb24gZmluZENvbHVtbihzdHJpbmcsIGdvYWwsIHRhYlNpemUpIHtcbiAgICBmb3IgKHZhciBwb3MgPSAwLCBjb2wgPSAwOzspIHtcbiAgICAgIHZhciBuZXh0VGFiID0gc3RyaW5nLmluZGV4T2YoXCJcXHRcIiwgcG9zKTtcbiAgICAgIGlmIChuZXh0VGFiID09IC0xKSBuZXh0VGFiID0gc3RyaW5nLmxlbmd0aDtcbiAgICAgIHZhciBza2lwcGVkID0gbmV4dFRhYiAtIHBvcztcbiAgICAgIGlmIChuZXh0VGFiID09IHN0cmluZy5sZW5ndGggfHwgY29sICsgc2tpcHBlZCA+PSBnb2FsKVxuICAgICAgICByZXR1cm4gcG9zICsgTWF0aC5taW4oc2tpcHBlZCwgZ29hbCAtIGNvbCk7XG4gICAgICBjb2wgKz0gbmV4dFRhYiAtIHBvcztcbiAgICAgIGNvbCArPSB0YWJTaXplIC0gKGNvbCAlIHRhYlNpemUpO1xuICAgICAgcG9zID0gbmV4dFRhYiArIDE7XG4gICAgICBpZiAoY29sID49IGdvYWwpIHJldHVybiBwb3M7XG4gICAgfVxuICB9XG5cbiAgdmFyIHNwYWNlU3RycyA9IFtcIlwiXTtcbiAgZnVuY3Rpb24gc3BhY2VTdHIobikge1xuICAgIHdoaWxlIChzcGFjZVN0cnMubGVuZ3RoIDw9IG4pXG4gICAgICBzcGFjZVN0cnMucHVzaChsc3Qoc3BhY2VTdHJzKSArIFwiIFwiKTtcbiAgICByZXR1cm4gc3BhY2VTdHJzW25dO1xuICB9XG5cbiAgZnVuY3Rpb24gbHN0KGFycikgeyByZXR1cm4gYXJyW2Fyci5sZW5ndGgtMV07IH1cblxuICB2YXIgc2VsZWN0SW5wdXQgPSBmdW5jdGlvbihub2RlKSB7IG5vZGUuc2VsZWN0KCk7IH07XG4gIGlmIChpb3MpIC8vIE1vYmlsZSBTYWZhcmkgYXBwYXJlbnRseSBoYXMgYSBidWcgd2hlcmUgc2VsZWN0KCkgaXMgYnJva2VuLlxuICAgIHNlbGVjdElucHV0ID0gZnVuY3Rpb24obm9kZSkgeyBub2RlLnNlbGVjdGlvblN0YXJ0ID0gMDsgbm9kZS5zZWxlY3Rpb25FbmQgPSBub2RlLnZhbHVlLmxlbmd0aDsgfTtcbiAgZWxzZSBpZiAoaWUpIC8vIFN1cHByZXNzIG15c3RlcmlvdXMgSUUxMCBlcnJvcnNcbiAgICBzZWxlY3RJbnB1dCA9IGZ1bmN0aW9uKG5vZGUpIHsgdHJ5IHsgbm9kZS5zZWxlY3QoKTsgfSBjYXRjaChfZSkge30gfTtcblxuICBmdW5jdGlvbiBpbmRleE9mKGFycmF5LCBlbHQpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgKytpKVxuICAgICAgaWYgKGFycmF5W2ldID09IGVsdCkgcmV0dXJuIGk7XG4gICAgcmV0dXJuIC0xO1xuICB9XG4gIGZ1bmN0aW9uIG1hcChhcnJheSwgZikge1xuICAgIHZhciBvdXQgPSBbXTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGFycmF5Lmxlbmd0aDsgaSsrKSBvdXRbaV0gPSBmKGFycmF5W2ldLCBpKTtcbiAgICByZXR1cm4gb3V0O1xuICB9XG5cbiAgZnVuY3Rpb24gY3JlYXRlT2JqKGJhc2UsIHByb3BzKSB7XG4gICAgdmFyIGluc3Q7XG4gICAgaWYgKE9iamVjdC5jcmVhdGUpIHtcbiAgICAgIGluc3QgPSBPYmplY3QuY3JlYXRlKGJhc2UpO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgY3RvciA9IGZ1bmN0aW9uKCkge307XG4gICAgICBjdG9yLnByb3RvdHlwZSA9IGJhc2U7XG4gICAgICBpbnN0ID0gbmV3IGN0b3IoKTtcbiAgICB9XG4gICAgaWYgKHByb3BzKSBjb3B5T2JqKHByb3BzLCBpbnN0KTtcbiAgICByZXR1cm4gaW5zdDtcbiAgfTtcblxuICBmdW5jdGlvbiBjb3B5T2JqKG9iaiwgdGFyZ2V0LCBvdmVyd3JpdGUpIHtcbiAgICBpZiAoIXRhcmdldCkgdGFyZ2V0ID0ge307XG4gICAgZm9yICh2YXIgcHJvcCBpbiBvYmopXG4gICAgICBpZiAob2JqLmhhc093blByb3BlcnR5KHByb3ApICYmIChvdmVyd3JpdGUgIT09IGZhbHNlIHx8ICF0YXJnZXQuaGFzT3duUHJvcGVydHkocHJvcCkpKVxuICAgICAgICB0YXJnZXRbcHJvcF0gPSBvYmpbcHJvcF07XG4gICAgcmV0dXJuIHRhcmdldDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJpbmQoZikge1xuICAgIHZhciBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAxKTtcbiAgICByZXR1cm4gZnVuY3Rpb24oKXtyZXR1cm4gZi5hcHBseShudWxsLCBhcmdzKTt9O1xuICB9XG5cbiAgdmFyIG5vbkFTQ0lJU2luZ2xlQ2FzZVdvcmRDaGFyID0gL1tcXHUwMGRmXFx1MDU5MC1cXHUwNWY0XFx1MDYwMC1cXHUwNmZmXFx1MzA0MC1cXHUzMDlmXFx1MzBhMC1cXHUzMGZmXFx1MzQwMC1cXHU0ZGI1XFx1NGUwMC1cXHU5ZmNjXFx1YWMwMC1cXHVkN2FmXS87XG4gIHZhciBpc1dvcmRDaGFyQmFzaWMgPSBDb2RlTWlycm9yLmlzV29yZENoYXIgPSBmdW5jdGlvbihjaCkge1xuICAgIHJldHVybiAvXFx3Ly50ZXN0KGNoKSB8fCBjaCA+IFwiXFx4ODBcIiAmJlxuICAgICAgKGNoLnRvVXBwZXJDYXNlKCkgIT0gY2gudG9Mb3dlckNhc2UoKSB8fCBub25BU0NJSVNpbmdsZUNhc2VXb3JkQ2hhci50ZXN0KGNoKSk7XG4gIH07XG4gIGZ1bmN0aW9uIGlzV29yZENoYXIoY2gsIGhlbHBlcikge1xuICAgIGlmICghaGVscGVyKSByZXR1cm4gaXNXb3JkQ2hhckJhc2ljKGNoKTtcbiAgICBpZiAoaGVscGVyLnNvdXJjZS5pbmRleE9mKFwiXFxcXHdcIikgPiAtMSAmJiBpc1dvcmRDaGFyQmFzaWMoY2gpKSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gaGVscGVyLnRlc3QoY2gpO1xuICB9XG5cbiAgZnVuY3Rpb24gaXNFbXB0eShvYmopIHtcbiAgICBmb3IgKHZhciBuIGluIG9iaikgaWYgKG9iai5oYXNPd25Qcm9wZXJ0eShuKSAmJiBvYmpbbl0pIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIC8vIEV4dGVuZGluZyB1bmljb2RlIGNoYXJhY3RlcnMuIEEgc2VyaWVzIG9mIGEgbm9uLWV4dGVuZGluZyBjaGFyICtcbiAgLy8gYW55IG51bWJlciBvZiBleHRlbmRpbmcgY2hhcnMgaXMgdHJlYXRlZCBhcyBhIHNpbmdsZSB1bml0IGFzIGZhclxuICAvLyBhcyBlZGl0aW5nIGFuZCBtZWFzdXJpbmcgaXMgY29uY2VybmVkLiBUaGlzIGlzIG5vdCBmdWxseSBjb3JyZWN0LFxuICAvLyBzaW5jZSBzb21lIHNjcmlwdHMvZm9udHMvYnJvd3NlcnMgYWxzbyB0cmVhdCBvdGhlciBjb25maWd1cmF0aW9uc1xuICAvLyBvZiBjb2RlIHBvaW50cyBhcyBhIGdyb3VwLlxuICB2YXIgZXh0ZW5kaW5nQ2hhcnMgPSAvW1xcdTAzMDAtXFx1MDM2ZlxcdTA0ODMtXFx1MDQ4OVxcdTA1OTEtXFx1MDViZFxcdTA1YmZcXHUwNWMxXFx1MDVjMlxcdTA1YzRcXHUwNWM1XFx1MDVjN1xcdTA2MTAtXFx1MDYxYVxcdTA2NGItXFx1MDY1ZVxcdTA2NzBcXHUwNmQ2LVxcdTA2ZGNcXHUwNmRlLVxcdTA2ZTRcXHUwNmU3XFx1MDZlOFxcdTA2ZWEtXFx1MDZlZFxcdTA3MTFcXHUwNzMwLVxcdTA3NGFcXHUwN2E2LVxcdTA3YjBcXHUwN2ViLVxcdTA3ZjNcXHUwODE2LVxcdTA4MTlcXHUwODFiLVxcdTA4MjNcXHUwODI1LVxcdTA4MjdcXHUwODI5LVxcdTA4MmRcXHUwOTAwLVxcdTA5MDJcXHUwOTNjXFx1MDk0MS1cXHUwOTQ4XFx1MDk0ZFxcdTA5NTEtXFx1MDk1NVxcdTA5NjJcXHUwOTYzXFx1MDk4MVxcdTA5YmNcXHUwOWJlXFx1MDljMS1cXHUwOWM0XFx1MDljZFxcdTA5ZDdcXHUwOWUyXFx1MDllM1xcdTBhMDFcXHUwYTAyXFx1MGEzY1xcdTBhNDFcXHUwYTQyXFx1MGE0N1xcdTBhNDhcXHUwYTRiLVxcdTBhNGRcXHUwYTUxXFx1MGE3MFxcdTBhNzFcXHUwYTc1XFx1MGE4MVxcdTBhODJcXHUwYWJjXFx1MGFjMS1cXHUwYWM1XFx1MGFjN1xcdTBhYzhcXHUwYWNkXFx1MGFlMlxcdTBhZTNcXHUwYjAxXFx1MGIzY1xcdTBiM2VcXHUwYjNmXFx1MGI0MS1cXHUwYjQ0XFx1MGI0ZFxcdTBiNTZcXHUwYjU3XFx1MGI2MlxcdTBiNjNcXHUwYjgyXFx1MGJiZVxcdTBiYzBcXHUwYmNkXFx1MGJkN1xcdTBjM2UtXFx1MGM0MFxcdTBjNDYtXFx1MGM0OFxcdTBjNGEtXFx1MGM0ZFxcdTBjNTVcXHUwYzU2XFx1MGM2MlxcdTBjNjNcXHUwY2JjXFx1MGNiZlxcdTBjYzJcXHUwY2M2XFx1MGNjY1xcdTBjY2RcXHUwY2Q1XFx1MGNkNlxcdTBjZTJcXHUwY2UzXFx1MGQzZVxcdTBkNDEtXFx1MGQ0NFxcdTBkNGRcXHUwZDU3XFx1MGQ2MlxcdTBkNjNcXHUwZGNhXFx1MGRjZlxcdTBkZDItXFx1MGRkNFxcdTBkZDZcXHUwZGRmXFx1MGUzMVxcdTBlMzQtXFx1MGUzYVxcdTBlNDctXFx1MGU0ZVxcdTBlYjFcXHUwZWI0LVxcdTBlYjlcXHUwZWJiXFx1MGViY1xcdTBlYzgtXFx1MGVjZFxcdTBmMThcXHUwZjE5XFx1MGYzNVxcdTBmMzdcXHUwZjM5XFx1MGY3MS1cXHUwZjdlXFx1MGY4MC1cXHUwZjg0XFx1MGY4NlxcdTBmODdcXHUwZjkwLVxcdTBmOTdcXHUwZjk5LVxcdTBmYmNcXHUwZmM2XFx1MTAyZC1cXHUxMDMwXFx1MTAzMi1cXHUxMDM3XFx1MTAzOVxcdTEwM2FcXHUxMDNkXFx1MTAzZVxcdTEwNThcXHUxMDU5XFx1MTA1ZS1cXHUxMDYwXFx1MTA3MS1cXHUxMDc0XFx1MTA4MlxcdTEwODVcXHUxMDg2XFx1MTA4ZFxcdTEwOWRcXHUxMzVmXFx1MTcxMi1cXHUxNzE0XFx1MTczMi1cXHUxNzM0XFx1MTc1MlxcdTE3NTNcXHUxNzcyXFx1MTc3M1xcdTE3YjctXFx1MTdiZFxcdTE3YzZcXHUxN2M5LVxcdTE3ZDNcXHUxN2RkXFx1MTgwYi1cXHUxODBkXFx1MThhOVxcdTE5MjAtXFx1MTkyMlxcdTE5MjdcXHUxOTI4XFx1MTkzMlxcdTE5MzktXFx1MTkzYlxcdTFhMTdcXHUxYTE4XFx1MWE1NlxcdTFhNTgtXFx1MWE1ZVxcdTFhNjBcXHUxYTYyXFx1MWE2NS1cXHUxYTZjXFx1MWE3My1cXHUxYTdjXFx1MWE3ZlxcdTFiMDAtXFx1MWIwM1xcdTFiMzRcXHUxYjM2LVxcdTFiM2FcXHUxYjNjXFx1MWI0MlxcdTFiNmItXFx1MWI3M1xcdTFiODBcXHUxYjgxXFx1MWJhMi1cXHUxYmE1XFx1MWJhOFxcdTFiYTlcXHUxYzJjLVxcdTFjMzNcXHUxYzM2XFx1MWMzN1xcdTFjZDAtXFx1MWNkMlxcdTFjZDQtXFx1MWNlMFxcdTFjZTItXFx1MWNlOFxcdTFjZWRcXHUxZGMwLVxcdTFkZTZcXHUxZGZkLVxcdTFkZmZcXHUyMDBjXFx1MjAwZFxcdTIwZDAtXFx1MjBmMFxcdTJjZWYtXFx1MmNmMVxcdTJkZTAtXFx1MmRmZlxcdTMwMmEtXFx1MzAyZlxcdTMwOTlcXHUzMDlhXFx1YTY2Zi1cXHVhNjcyXFx1YTY3Y1xcdWE2N2RcXHVhNmYwXFx1YTZmMVxcdWE4MDJcXHVhODA2XFx1YTgwYlxcdWE4MjVcXHVhODI2XFx1YThjNFxcdWE4ZTAtXFx1YThmMVxcdWE5MjYtXFx1YTkyZFxcdWE5NDctXFx1YTk1MVxcdWE5ODAtXFx1YTk4MlxcdWE5YjNcXHVhOWI2LVxcdWE5YjlcXHVhOWJjXFx1YWEyOS1cXHVhYTJlXFx1YWEzMVxcdWFhMzJcXHVhYTM1XFx1YWEzNlxcdWFhNDNcXHVhYTRjXFx1YWFiMFxcdWFhYjItXFx1YWFiNFxcdWFhYjdcXHVhYWI4XFx1YWFiZVxcdWFhYmZcXHVhYWMxXFx1YWJlNVxcdWFiZThcXHVhYmVkXFx1ZGMwMC1cXHVkZmZmXFx1ZmIxZVxcdWZlMDAtXFx1ZmUwZlxcdWZlMjAtXFx1ZmUyNlxcdWZmOWVcXHVmZjlmXS87XG4gIGZ1bmN0aW9uIGlzRXh0ZW5kaW5nQ2hhcihjaCkgeyByZXR1cm4gY2guY2hhckNvZGVBdCgwKSA+PSA3NjggJiYgZXh0ZW5kaW5nQ2hhcnMudGVzdChjaCk7IH1cblxuICAvLyBET00gVVRJTElUSUVTXG5cbiAgZnVuY3Rpb24gZWx0KHRhZywgY29udGVudCwgY2xhc3NOYW1lLCBzdHlsZSkge1xuICAgIHZhciBlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpO1xuICAgIGlmIChjbGFzc05hbWUpIGUuY2xhc3NOYW1lID0gY2xhc3NOYW1lO1xuICAgIGlmIChzdHlsZSkgZS5zdHlsZS5jc3NUZXh0ID0gc3R5bGU7XG4gICAgaWYgKHR5cGVvZiBjb250ZW50ID09IFwic3RyaW5nXCIpIGUuYXBwZW5kQ2hpbGQoZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoY29udGVudCkpO1xuICAgIGVsc2UgaWYgKGNvbnRlbnQpIGZvciAodmFyIGkgPSAwOyBpIDwgY29udGVudC5sZW5ndGg7ICsraSkgZS5hcHBlbmRDaGlsZChjb250ZW50W2ldKTtcbiAgICByZXR1cm4gZTtcbiAgfVxuXG4gIHZhciByYW5nZTtcbiAgaWYgKGRvY3VtZW50LmNyZWF0ZVJhbmdlKSByYW5nZSA9IGZ1bmN0aW9uKG5vZGUsIHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgciA9IGRvY3VtZW50LmNyZWF0ZVJhbmdlKCk7XG4gICAgci5zZXRFbmQobm9kZSwgZW5kKTtcbiAgICByLnNldFN0YXJ0KG5vZGUsIHN0YXJ0KTtcbiAgICByZXR1cm4gcjtcbiAgfTtcbiAgZWxzZSByYW5nZSA9IGZ1bmN0aW9uKG5vZGUsIHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgciA9IGRvY3VtZW50LmJvZHkuY3JlYXRlVGV4dFJhbmdlKCk7XG4gICAgdHJ5IHsgci5tb3ZlVG9FbGVtZW50VGV4dChub2RlLnBhcmVudE5vZGUpOyB9XG4gICAgY2F0Y2goZSkgeyByZXR1cm4gcjsgfVxuICAgIHIuY29sbGFwc2UodHJ1ZSk7XG4gICAgci5tb3ZlRW5kKFwiY2hhcmFjdGVyXCIsIGVuZCk7XG4gICAgci5tb3ZlU3RhcnQoXCJjaGFyYWN0ZXJcIiwgc3RhcnQpO1xuICAgIHJldHVybiByO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHJlbW92ZUNoaWxkcmVuKGUpIHtcbiAgICBmb3IgKHZhciBjb3VudCA9IGUuY2hpbGROb2Rlcy5sZW5ndGg7IGNvdW50ID4gMDsgLS1jb3VudClcbiAgICAgIGUucmVtb3ZlQ2hpbGQoZS5maXJzdENoaWxkKTtcbiAgICByZXR1cm4gZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZUNoaWxkcmVuQW5kQWRkKHBhcmVudCwgZSkge1xuICAgIHJldHVybiByZW1vdmVDaGlsZHJlbihwYXJlbnQpLmFwcGVuZENoaWxkKGUpO1xuICB9XG5cbiAgZnVuY3Rpb24gY29udGFpbnMocGFyZW50LCBjaGlsZCkge1xuICAgIGlmIChwYXJlbnQuY29udGFpbnMpXG4gICAgICByZXR1cm4gcGFyZW50LmNvbnRhaW5zKGNoaWxkKTtcbiAgICB3aGlsZSAoY2hpbGQgPSBjaGlsZC5wYXJlbnROb2RlKVxuICAgICAgaWYgKGNoaWxkID09IHBhcmVudCkgcmV0dXJuIHRydWU7XG4gIH1cblxuICBmdW5jdGlvbiBhY3RpdmVFbHQoKSB7IHJldHVybiBkb2N1bWVudC5hY3RpdmVFbGVtZW50OyB9XG4gIC8vIE9sZGVyIHZlcnNpb25zIG9mIElFIHRocm93cyB1bnNwZWNpZmllZCBlcnJvciB3aGVuIHRvdWNoaW5nXG4gIC8vIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQgaW4gc29tZSBjYXNlcyAoZHVyaW5nIGxvYWRpbmcsIGluIGlmcmFtZSlcbiAgaWYgKGllICYmIGllX3ZlcnNpb24gPCAxMSkgYWN0aXZlRWx0ID0gZnVuY3Rpb24oKSB7XG4gICAgdHJ5IHsgcmV0dXJuIGRvY3VtZW50LmFjdGl2ZUVsZW1lbnQ7IH1cbiAgICBjYXRjaChlKSB7IHJldHVybiBkb2N1bWVudC5ib2R5OyB9XG4gIH07XG5cbiAgZnVuY3Rpb24gY2xhc3NUZXN0KGNscykgeyByZXR1cm4gbmV3IFJlZ0V4cChcIihefFxcXFxzKVwiICsgY2xzICsgXCIoPzokfFxcXFxzKVxcXFxzKlwiKTsgfVxuICB2YXIgcm1DbGFzcyA9IENvZGVNaXJyb3Iucm1DbGFzcyA9IGZ1bmN0aW9uKG5vZGUsIGNscykge1xuICAgIHZhciBjdXJyZW50ID0gbm9kZS5jbGFzc05hbWU7XG4gICAgdmFyIG1hdGNoID0gY2xhc3NUZXN0KGNscykuZXhlYyhjdXJyZW50KTtcbiAgICBpZiAobWF0Y2gpIHtcbiAgICAgIHZhciBhZnRlciA9IGN1cnJlbnQuc2xpY2UobWF0Y2guaW5kZXggKyBtYXRjaFswXS5sZW5ndGgpO1xuICAgICAgbm9kZS5jbGFzc05hbWUgPSBjdXJyZW50LnNsaWNlKDAsIG1hdGNoLmluZGV4KSArIChhZnRlciA/IG1hdGNoWzFdICsgYWZ0ZXIgOiBcIlwiKTtcbiAgICB9XG4gIH07XG4gIHZhciBhZGRDbGFzcyA9IENvZGVNaXJyb3IuYWRkQ2xhc3MgPSBmdW5jdGlvbihub2RlLCBjbHMpIHtcbiAgICB2YXIgY3VycmVudCA9IG5vZGUuY2xhc3NOYW1lO1xuICAgIGlmICghY2xhc3NUZXN0KGNscykudGVzdChjdXJyZW50KSkgbm9kZS5jbGFzc05hbWUgKz0gKGN1cnJlbnQgPyBcIiBcIiA6IFwiXCIpICsgY2xzO1xuICB9O1xuICBmdW5jdGlvbiBqb2luQ2xhc3NlcyhhLCBiKSB7XG4gICAgdmFyIGFzID0gYS5zcGxpdChcIiBcIik7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBhcy5sZW5ndGg7IGkrKylcbiAgICAgIGlmIChhc1tpXSAmJiAhY2xhc3NUZXN0KGFzW2ldKS50ZXN0KGIpKSBiICs9IFwiIFwiICsgYXNbaV07XG4gICAgcmV0dXJuIGI7XG4gIH1cblxuICAvLyBXSU5ET1ctV0lERSBFVkVOVFNcblxuICAvLyBUaGVzZSBtdXN0IGJlIGhhbmRsZWQgY2FyZWZ1bGx5LCBiZWNhdXNlIG5haXZlbHkgcmVnaXN0ZXJpbmcgYVxuICAvLyBoYW5kbGVyIGZvciBlYWNoIGVkaXRvciB3aWxsIGNhdXNlIHRoZSBlZGl0b3JzIHRvIG5ldmVyIGJlXG4gIC8vIGdhcmJhZ2UgY29sbGVjdGVkLlxuXG4gIGZ1bmN0aW9uIGZvckVhY2hDb2RlTWlycm9yKGYpIHtcbiAgICBpZiAoIWRvY3VtZW50LmJvZHkuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSkgcmV0dXJuO1xuICAgIHZhciBieUNsYXNzID0gZG9jdW1lbnQuYm9keS5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKFwiQ29kZU1pcnJvclwiKTtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IGJ5Q2xhc3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIHZhciBjbSA9IGJ5Q2xhc3NbaV0uQ29kZU1pcnJvcjtcbiAgICAgIGlmIChjbSkgZihjbSk7XG4gICAgfVxuICB9XG5cbiAgdmFyIGdsb2JhbHNSZWdpc3RlcmVkID0gZmFsc2U7XG4gIGZ1bmN0aW9uIGVuc3VyZUdsb2JhbEhhbmRsZXJzKCkge1xuICAgIGlmIChnbG9iYWxzUmVnaXN0ZXJlZCkgcmV0dXJuO1xuICAgIHJlZ2lzdGVyR2xvYmFsSGFuZGxlcnMoKTtcbiAgICBnbG9iYWxzUmVnaXN0ZXJlZCA9IHRydWU7XG4gIH1cbiAgZnVuY3Rpb24gcmVnaXN0ZXJHbG9iYWxIYW5kbGVycygpIHtcbiAgICAvLyBXaGVuIHRoZSB3aW5kb3cgcmVzaXplcywgd2UgbmVlZCB0byByZWZyZXNoIGFjdGl2ZSBlZGl0b3JzLlxuICAgIHZhciByZXNpemVUaW1lcjtcbiAgICBvbih3aW5kb3csIFwicmVzaXplXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKHJlc2l6ZVRpbWVyID09IG51bGwpIHJlc2l6ZVRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbigpIHtcbiAgICAgICAgcmVzaXplVGltZXIgPSBudWxsO1xuICAgICAgICBmb3JFYWNoQ29kZU1pcnJvcihvblJlc2l6ZSk7XG4gICAgICB9LCAxMDApO1xuICAgIH0pO1xuICAgIC8vIFdoZW4gdGhlIHdpbmRvdyBsb3NlcyBmb2N1cywgd2Ugd2FudCB0byBzaG93IHRoZSBlZGl0b3IgYXMgYmx1cnJlZFxuICAgIG9uKHdpbmRvdywgXCJibHVyXCIsIGZ1bmN0aW9uKCkge1xuICAgICAgZm9yRWFjaENvZGVNaXJyb3Iob25CbHVyKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEZFQVRVUkUgREVURUNUSU9OXG5cbiAgLy8gRGV0ZWN0IGRyYWctYW5kLWRyb3BcbiAgdmFyIGRyYWdBbmREcm9wID0gZnVuY3Rpb24oKSB7XG4gICAgLy8gVGhlcmUgaXMgKnNvbWUqIGtpbmQgb2YgZHJhZy1hbmQtZHJvcCBzdXBwb3J0IGluIElFNi04LCBidXQgSVxuICAgIC8vIGNvdWxkbid0IGdldCBpdCB0byB3b3JrIHlldC5cbiAgICBpZiAoaWUgJiYgaWVfdmVyc2lvbiA8IDkpIHJldHVybiBmYWxzZTtcbiAgICB2YXIgZGl2ID0gZWx0KCdkaXYnKTtcbiAgICByZXR1cm4gXCJkcmFnZ2FibGVcIiBpbiBkaXYgfHwgXCJkcmFnRHJvcFwiIGluIGRpdjtcbiAgfSgpO1xuXG4gIHZhciB6d3NwU3VwcG9ydGVkO1xuICBmdW5jdGlvbiB6ZXJvV2lkdGhFbGVtZW50KG1lYXN1cmUpIHtcbiAgICBpZiAoendzcFN1cHBvcnRlZCA9PSBudWxsKSB7XG4gICAgICB2YXIgdGVzdCA9IGVsdChcInNwYW5cIiwgXCJcXHUyMDBiXCIpO1xuICAgICAgcmVtb3ZlQ2hpbGRyZW5BbmRBZGQobWVhc3VyZSwgZWx0KFwic3BhblwiLCBbdGVzdCwgZG9jdW1lbnQuY3JlYXRlVGV4dE5vZGUoXCJ4XCIpXSkpO1xuICAgICAgaWYgKG1lYXN1cmUuZmlyc3RDaGlsZC5vZmZzZXRIZWlnaHQgIT0gMClcbiAgICAgICAgendzcFN1cHBvcnRlZCA9IHRlc3Qub2Zmc2V0V2lkdGggPD0gMSAmJiB0ZXN0Lm9mZnNldEhlaWdodCA+IDIgJiYgIShpZSAmJiBpZV92ZXJzaW9uIDwgOCk7XG4gICAgfVxuICAgIGlmICh6d3NwU3VwcG9ydGVkKSByZXR1cm4gZWx0KFwic3BhblwiLCBcIlxcdTIwMGJcIik7XG4gICAgZWxzZSByZXR1cm4gZWx0KFwic3BhblwiLCBcIlxcdTAwYTBcIiwgbnVsbCwgXCJkaXNwbGF5OiBpbmxpbmUtYmxvY2s7IHdpZHRoOiAxcHg7IG1hcmdpbi1yaWdodDogLTFweFwiKTtcbiAgfVxuXG4gIC8vIEZlYXR1cmUtZGV0ZWN0IElFJ3MgY3J1bW15IGNsaWVudCByZWN0IHJlcG9ydGluZyBmb3IgYmlkaSB0ZXh0XG4gIHZhciBiYWRCaWRpUmVjdHM7XG4gIGZ1bmN0aW9uIGhhc0JhZEJpZGlSZWN0cyhtZWFzdXJlKSB7XG4gICAgaWYgKGJhZEJpZGlSZWN0cyAhPSBudWxsKSByZXR1cm4gYmFkQmlkaVJlY3RzO1xuICAgIHZhciB0eHQgPSByZW1vdmVDaGlsZHJlbkFuZEFkZChtZWFzdXJlLCBkb2N1bWVudC5jcmVhdGVUZXh0Tm9kZShcIkFcXHUwNjJlQVwiKSk7XG4gICAgdmFyIHIwID0gcmFuZ2UodHh0LCAwLCAxKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBpZiAoIXIwIHx8IHIwLmxlZnQgPT0gcjAucmlnaHQpIHJldHVybiBmYWxzZTsgLy8gU2FmYXJpIHJldHVybnMgbnVsbCBpbiBzb21lIGNhc2VzICgjMjc4MClcbiAgICB2YXIgcjEgPSByYW5nZSh0eHQsIDEsIDIpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiBiYWRCaWRpUmVjdHMgPSAocjEucmlnaHQgLSByMC5yaWdodCA8IDMpO1xuICB9XG5cbiAgLy8gU2VlIGlmIFwiXCIuc3BsaXQgaXMgdGhlIGJyb2tlbiBJRSB2ZXJzaW9uLCBpZiBzbywgcHJvdmlkZSBhblxuICAvLyBhbHRlcm5hdGl2ZSB3YXkgdG8gc3BsaXQgbGluZXMuXG4gIHZhciBzcGxpdExpbmVzID0gQ29kZU1pcnJvci5zcGxpdExpbmVzID0gXCJcXG5cXG5iXCIuc3BsaXQoL1xcbi8pLmxlbmd0aCAhPSAzID8gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgdmFyIHBvcyA9IDAsIHJlc3VsdCA9IFtdLCBsID0gc3RyaW5nLmxlbmd0aDtcbiAgICB3aGlsZSAocG9zIDw9IGwpIHtcbiAgICAgIHZhciBubCA9IHN0cmluZy5pbmRleE9mKFwiXFxuXCIsIHBvcyk7XG4gICAgICBpZiAobmwgPT0gLTEpIG5sID0gc3RyaW5nLmxlbmd0aDtcbiAgICAgIHZhciBsaW5lID0gc3RyaW5nLnNsaWNlKHBvcywgc3RyaW5nLmNoYXJBdChubCAtIDEpID09IFwiXFxyXCIgPyBubCAtIDEgOiBubCk7XG4gICAgICB2YXIgcnQgPSBsaW5lLmluZGV4T2YoXCJcXHJcIik7XG4gICAgICBpZiAocnQgIT0gLTEpIHtcbiAgICAgICAgcmVzdWx0LnB1c2gobGluZS5zbGljZSgwLCBydCkpO1xuICAgICAgICBwb3MgKz0gcnQgKyAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzdWx0LnB1c2gobGluZSk7XG4gICAgICAgIHBvcyA9IG5sICsgMTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfSA6IGZ1bmN0aW9uKHN0cmluZyl7cmV0dXJuIHN0cmluZy5zcGxpdCgvXFxyXFxuP3xcXG4vKTt9O1xuXG4gIHZhciBoYXNTZWxlY3Rpb24gPSB3aW5kb3cuZ2V0U2VsZWN0aW9uID8gZnVuY3Rpb24odGUpIHtcbiAgICB0cnkgeyByZXR1cm4gdGUuc2VsZWN0aW9uU3RhcnQgIT0gdGUuc2VsZWN0aW9uRW5kOyB9XG4gICAgY2F0Y2goZSkgeyByZXR1cm4gZmFsc2U7IH1cbiAgfSA6IGZ1bmN0aW9uKHRlKSB7XG4gICAgdHJ5IHt2YXIgcmFuZ2UgPSB0ZS5vd25lckRvY3VtZW50LnNlbGVjdGlvbi5jcmVhdGVSYW5nZSgpO31cbiAgICBjYXRjaChlKSB7fVxuICAgIGlmICghcmFuZ2UgfHwgcmFuZ2UucGFyZW50RWxlbWVudCgpICE9IHRlKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIHJhbmdlLmNvbXBhcmVFbmRQb2ludHMoXCJTdGFydFRvRW5kXCIsIHJhbmdlKSAhPSAwO1xuICB9O1xuXG4gIHZhciBoYXNDb3B5RXZlbnQgPSAoZnVuY3Rpb24oKSB7XG4gICAgdmFyIGUgPSBlbHQoXCJkaXZcIik7XG4gICAgaWYgKFwib25jb3B5XCIgaW4gZSkgcmV0dXJuIHRydWU7XG4gICAgZS5zZXRBdHRyaWJ1dGUoXCJvbmNvcHlcIiwgXCJyZXR1cm47XCIpO1xuICAgIHJldHVybiB0eXBlb2YgZS5vbmNvcHkgPT0gXCJmdW5jdGlvblwiO1xuICB9KSgpO1xuXG4gIHZhciBiYWRab29tZWRSZWN0cyA9IG51bGw7XG4gIGZ1bmN0aW9uIGhhc0JhZFpvb21lZFJlY3RzKG1lYXN1cmUpIHtcbiAgICBpZiAoYmFkWm9vbWVkUmVjdHMgIT0gbnVsbCkgcmV0dXJuIGJhZFpvb21lZFJlY3RzO1xuICAgIHZhciBub2RlID0gcmVtb3ZlQ2hpbGRyZW5BbmRBZGQobWVhc3VyZSwgZWx0KFwic3BhblwiLCBcInhcIikpO1xuICAgIHZhciBub3JtYWwgPSBub2RlLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHZhciBmcm9tUmFuZ2UgPSByYW5nZShub2RlLCAwLCAxKS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICByZXR1cm4gYmFkWm9vbWVkUmVjdHMgPSBNYXRoLmFicyhub3JtYWwubGVmdCAtIGZyb21SYW5nZS5sZWZ0KSA+IDE7XG4gIH1cblxuICAvLyBLRVkgTkFNRVNcblxuICB2YXIga2V5TmFtZXMgPSB7MzogXCJFbnRlclwiLCA4OiBcIkJhY2tzcGFjZVwiLCA5OiBcIlRhYlwiLCAxMzogXCJFbnRlclwiLCAxNjogXCJTaGlmdFwiLCAxNzogXCJDdHJsXCIsIDE4OiBcIkFsdFwiLFxuICAgICAgICAgICAgICAgICAgMTk6IFwiUGF1c2VcIiwgMjA6IFwiQ2Fwc0xvY2tcIiwgMjc6IFwiRXNjXCIsIDMyOiBcIlNwYWNlXCIsIDMzOiBcIlBhZ2VVcFwiLCAzNDogXCJQYWdlRG93blwiLCAzNTogXCJFbmRcIixcbiAgICAgICAgICAgICAgICAgIDM2OiBcIkhvbWVcIiwgMzc6IFwiTGVmdFwiLCAzODogXCJVcFwiLCAzOTogXCJSaWdodFwiLCA0MDogXCJEb3duXCIsIDQ0OiBcIlByaW50U2NyblwiLCA0NTogXCJJbnNlcnRcIixcbiAgICAgICAgICAgICAgICAgIDQ2OiBcIkRlbGV0ZVwiLCA1OTogXCI7XCIsIDYxOiBcIj1cIiwgOTE6IFwiTW9kXCIsIDkyOiBcIk1vZFwiLCA5MzogXCJNb2RcIiwgMTA3OiBcIj1cIiwgMTA5OiBcIi1cIiwgMTI3OiBcIkRlbGV0ZVwiLFxuICAgICAgICAgICAgICAgICAgMTczOiBcIi1cIiwgMTg2OiBcIjtcIiwgMTg3OiBcIj1cIiwgMTg4OiBcIixcIiwgMTg5OiBcIi1cIiwgMTkwOiBcIi5cIiwgMTkxOiBcIi9cIiwgMTkyOiBcImBcIiwgMjE5OiBcIltcIiwgMjIwOiBcIlxcXFxcIixcbiAgICAgICAgICAgICAgICAgIDIyMTogXCJdXCIsIDIyMjogXCInXCIsIDYzMjMyOiBcIlVwXCIsIDYzMjMzOiBcIkRvd25cIiwgNjMyMzQ6IFwiTGVmdFwiLCA2MzIzNTogXCJSaWdodFwiLCA2MzI3MjogXCJEZWxldGVcIixcbiAgICAgICAgICAgICAgICAgIDYzMjczOiBcIkhvbWVcIiwgNjMyNzU6IFwiRW5kXCIsIDYzMjc2OiBcIlBhZ2VVcFwiLCA2MzI3NzogXCJQYWdlRG93blwiLCA2MzMwMjogXCJJbnNlcnRcIn07XG4gIENvZGVNaXJyb3Iua2V5TmFtZXMgPSBrZXlOYW1lcztcbiAgKGZ1bmN0aW9uKCkge1xuICAgIC8vIE51bWJlciBrZXlzXG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCAxMDsgaSsrKSBrZXlOYW1lc1tpICsgNDhdID0ga2V5TmFtZXNbaSArIDk2XSA9IFN0cmluZyhpKTtcbiAgICAvLyBBbHBoYWJldGljIGtleXNcbiAgICBmb3IgKHZhciBpID0gNjU7IGkgPD0gOTA7IGkrKykga2V5TmFtZXNbaV0gPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGkpO1xuICAgIC8vIEZ1bmN0aW9uIGtleXNcbiAgICBmb3IgKHZhciBpID0gMTsgaSA8PSAxMjsgaSsrKSBrZXlOYW1lc1tpICsgMTExXSA9IGtleU5hbWVzW2kgKyA2MzIzNV0gPSBcIkZcIiArIGk7XG4gIH0pKCk7XG5cbiAgLy8gQklESSBIRUxQRVJTXG5cbiAgZnVuY3Rpb24gaXRlcmF0ZUJpZGlTZWN0aW9ucyhvcmRlciwgZnJvbSwgdG8sIGYpIHtcbiAgICBpZiAoIW9yZGVyKSByZXR1cm4gZihmcm9tLCB0bywgXCJsdHJcIik7XG4gICAgdmFyIGZvdW5kID0gZmFsc2U7XG4gICAgZm9yICh2YXIgaSA9IDA7IGkgPCBvcmRlci5sZW5ndGg7ICsraSkge1xuICAgICAgdmFyIHBhcnQgPSBvcmRlcltpXTtcbiAgICAgIGlmIChwYXJ0LmZyb20gPCB0byAmJiBwYXJ0LnRvID4gZnJvbSB8fCBmcm9tID09IHRvICYmIHBhcnQudG8gPT0gZnJvbSkge1xuICAgICAgICBmKE1hdGgubWF4KHBhcnQuZnJvbSwgZnJvbSksIE1hdGgubWluKHBhcnQudG8sIHRvKSwgcGFydC5sZXZlbCA9PSAxID8gXCJydGxcIiA6IFwibHRyXCIpO1xuICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghZm91bmQpIGYoZnJvbSwgdG8sIFwibHRyXCIpO1xuICB9XG5cbiAgZnVuY3Rpb24gYmlkaUxlZnQocGFydCkgeyByZXR1cm4gcGFydC5sZXZlbCAlIDIgPyBwYXJ0LnRvIDogcGFydC5mcm9tOyB9XG4gIGZ1bmN0aW9uIGJpZGlSaWdodChwYXJ0KSB7IHJldHVybiBwYXJ0LmxldmVsICUgMiA/IHBhcnQuZnJvbSA6IHBhcnQudG87IH1cblxuICBmdW5jdGlvbiBsaW5lTGVmdChsaW5lKSB7IHZhciBvcmRlciA9IGdldE9yZGVyKGxpbmUpOyByZXR1cm4gb3JkZXIgPyBiaWRpTGVmdChvcmRlclswXSkgOiAwOyB9XG4gIGZ1bmN0aW9uIGxpbmVSaWdodChsaW5lKSB7XG4gICAgdmFyIG9yZGVyID0gZ2V0T3JkZXIobGluZSk7XG4gICAgaWYgKCFvcmRlcikgcmV0dXJuIGxpbmUudGV4dC5sZW5ndGg7XG4gICAgcmV0dXJuIGJpZGlSaWdodChsc3Qob3JkZXIpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGxpbmVTdGFydChjbSwgbGluZU4pIHtcbiAgICB2YXIgbGluZSA9IGdldExpbmUoY20uZG9jLCBsaW5lTik7XG4gICAgdmFyIHZpc3VhbCA9IHZpc3VhbExpbmUobGluZSk7XG4gICAgaWYgKHZpc3VhbCAhPSBsaW5lKSBsaW5lTiA9IGxpbmVObyh2aXN1YWwpO1xuICAgIHZhciBvcmRlciA9IGdldE9yZGVyKHZpc3VhbCk7XG4gICAgdmFyIGNoID0gIW9yZGVyID8gMCA6IG9yZGVyWzBdLmxldmVsICUgMiA/IGxpbmVSaWdodCh2aXN1YWwpIDogbGluZUxlZnQodmlzdWFsKTtcbiAgICByZXR1cm4gUG9zKGxpbmVOLCBjaCk7XG4gIH1cbiAgZnVuY3Rpb24gbGluZUVuZChjbSwgbGluZU4pIHtcbiAgICB2YXIgbWVyZ2VkLCBsaW5lID0gZ2V0TGluZShjbS5kb2MsIGxpbmVOKTtcbiAgICB3aGlsZSAobWVyZ2VkID0gY29sbGFwc2VkU3BhbkF0RW5kKGxpbmUpKSB7XG4gICAgICBsaW5lID0gbWVyZ2VkLmZpbmQoMSwgdHJ1ZSkubGluZTtcbiAgICAgIGxpbmVOID0gbnVsbDtcbiAgICB9XG4gICAgdmFyIG9yZGVyID0gZ2V0T3JkZXIobGluZSk7XG4gICAgdmFyIGNoID0gIW9yZGVyID8gbGluZS50ZXh0Lmxlbmd0aCA6IG9yZGVyWzBdLmxldmVsICUgMiA/IGxpbmVMZWZ0KGxpbmUpIDogbGluZVJpZ2h0KGxpbmUpO1xuICAgIHJldHVybiBQb3MobGluZU4gPT0gbnVsbCA/IGxpbmVObyhsaW5lKSA6IGxpbmVOLCBjaCk7XG4gIH1cbiAgZnVuY3Rpb24gbGluZVN0YXJ0U21hcnQoY20sIHBvcykge1xuICAgIHZhciBzdGFydCA9IGxpbmVTdGFydChjbSwgcG9zLmxpbmUpO1xuICAgIHZhciBsaW5lID0gZ2V0TGluZShjbS5kb2MsIHN0YXJ0LmxpbmUpO1xuICAgIHZhciBvcmRlciA9IGdldE9yZGVyKGxpbmUpO1xuICAgIGlmICghb3JkZXIgfHwgb3JkZXJbMF0ubGV2ZWwgPT0gMCkge1xuICAgICAgdmFyIGZpcnN0Tm9uV1MgPSBNYXRoLm1heCgwLCBsaW5lLnRleHQuc2VhcmNoKC9cXFMvKSk7XG4gICAgICB2YXIgaW5XUyA9IHBvcy5saW5lID09IHN0YXJ0LmxpbmUgJiYgcG9zLmNoIDw9IGZpcnN0Tm9uV1MgJiYgcG9zLmNoO1xuICAgICAgcmV0dXJuIFBvcyhzdGFydC5saW5lLCBpbldTID8gMCA6IGZpcnN0Tm9uV1MpO1xuICAgIH1cbiAgICByZXR1cm4gc3RhcnQ7XG4gIH1cblxuICBmdW5jdGlvbiBjb21wYXJlQmlkaUxldmVsKG9yZGVyLCBhLCBiKSB7XG4gICAgdmFyIGxpbmVkaXIgPSBvcmRlclswXS5sZXZlbDtcbiAgICBpZiAoYSA9PSBsaW5lZGlyKSByZXR1cm4gdHJ1ZTtcbiAgICBpZiAoYiA9PSBsaW5lZGlyKSByZXR1cm4gZmFsc2U7XG4gICAgcmV0dXJuIGEgPCBiO1xuICB9XG4gIHZhciBiaWRpT3RoZXI7XG4gIGZ1bmN0aW9uIGdldEJpZGlQYXJ0QXQob3JkZXIsIHBvcykge1xuICAgIGJpZGlPdGhlciA9IG51bGw7XG4gICAgZm9yICh2YXIgaSA9IDAsIGZvdW5kOyBpIDwgb3JkZXIubGVuZ3RoOyArK2kpIHtcbiAgICAgIHZhciBjdXIgPSBvcmRlcltpXTtcbiAgICAgIGlmIChjdXIuZnJvbSA8IHBvcyAmJiBjdXIudG8gPiBwb3MpIHJldHVybiBpO1xuICAgICAgaWYgKChjdXIuZnJvbSA9PSBwb3MgfHwgY3VyLnRvID09IHBvcykpIHtcbiAgICAgICAgaWYgKGZvdW5kID09IG51bGwpIHtcbiAgICAgICAgICBmb3VuZCA9IGk7XG4gICAgICAgIH0gZWxzZSBpZiAoY29tcGFyZUJpZGlMZXZlbChvcmRlciwgY3VyLmxldmVsLCBvcmRlcltmb3VuZF0ubGV2ZWwpKSB7XG4gICAgICAgICAgaWYgKGN1ci5mcm9tICE9IGN1ci50bykgYmlkaU90aGVyID0gZm91bmQ7XG4gICAgICAgICAgcmV0dXJuIGk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaWYgKGN1ci5mcm9tICE9IGN1ci50bykgYmlkaU90aGVyID0gaTtcbiAgICAgICAgICByZXR1cm4gZm91bmQ7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZvdW5kO1xuICB9XG5cbiAgZnVuY3Rpb24gbW92ZUluTGluZShsaW5lLCBwb3MsIGRpciwgYnlVbml0KSB7XG4gICAgaWYgKCFieVVuaXQpIHJldHVybiBwb3MgKyBkaXI7XG4gICAgZG8gcG9zICs9IGRpcjtcbiAgICB3aGlsZSAocG9zID4gMCAmJiBpc0V4dGVuZGluZ0NoYXIobGluZS50ZXh0LmNoYXJBdChwb3MpKSk7XG4gICAgcmV0dXJuIHBvcztcbiAgfVxuXG4gIC8vIFRoaXMgaXMgbmVlZGVkIGluIG9yZGVyIHRvIG1vdmUgJ3Zpc3VhbGx5JyB0aHJvdWdoIGJpLWRpcmVjdGlvbmFsXG4gIC8vIHRleHQgLS0gaS5lLiwgcHJlc3NpbmcgbGVmdCBzaG91bGQgbWFrZSB0aGUgY3Vyc29yIGdvIGxlZnQsIGV2ZW5cbiAgLy8gd2hlbiBpbiBSVEwgdGV4dC4gVGhlIHRyaWNreSBwYXJ0IGlzIHRoZSAnanVtcHMnLCB3aGVyZSBSVEwgYW5kXG4gIC8vIExUUiB0ZXh0IHRvdWNoIGVhY2ggb3RoZXIuIFRoaXMgb2Z0ZW4gcmVxdWlyZXMgdGhlIGN1cnNvciBvZmZzZXRcbiAgLy8gdG8gbW92ZSBtb3JlIHRoYW4gb25lIHVuaXQsIGluIG9yZGVyIHRvIHZpc3VhbGx5IG1vdmUgb25lIHVuaXQuXG4gIGZ1bmN0aW9uIG1vdmVWaXN1YWxseShsaW5lLCBzdGFydCwgZGlyLCBieVVuaXQpIHtcbiAgICB2YXIgYmlkaSA9IGdldE9yZGVyKGxpbmUpO1xuICAgIGlmICghYmlkaSkgcmV0dXJuIG1vdmVMb2dpY2FsbHkobGluZSwgc3RhcnQsIGRpciwgYnlVbml0KTtcbiAgICB2YXIgcG9zID0gZ2V0QmlkaVBhcnRBdChiaWRpLCBzdGFydCksIHBhcnQgPSBiaWRpW3Bvc107XG4gICAgdmFyIHRhcmdldCA9IG1vdmVJbkxpbmUobGluZSwgc3RhcnQsIHBhcnQubGV2ZWwgJSAyID8gLWRpciA6IGRpciwgYnlVbml0KTtcblxuICAgIGZvciAoOzspIHtcbiAgICAgIGlmICh0YXJnZXQgPiBwYXJ0LmZyb20gJiYgdGFyZ2V0IDwgcGFydC50bykgcmV0dXJuIHRhcmdldDtcbiAgICAgIGlmICh0YXJnZXQgPT0gcGFydC5mcm9tIHx8IHRhcmdldCA9PSBwYXJ0LnRvKSB7XG4gICAgICAgIGlmIChnZXRCaWRpUGFydEF0KGJpZGksIHRhcmdldCkgPT0gcG9zKSByZXR1cm4gdGFyZ2V0O1xuICAgICAgICBwYXJ0ID0gYmlkaVtwb3MgKz0gZGlyXTtcbiAgICAgICAgcmV0dXJuIChkaXIgPiAwKSA9PSBwYXJ0LmxldmVsICUgMiA/IHBhcnQudG8gOiBwYXJ0LmZyb207XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJ0ID0gYmlkaVtwb3MgKz0gZGlyXTtcbiAgICAgICAgaWYgKCFwYXJ0KSByZXR1cm4gbnVsbDtcbiAgICAgICAgaWYgKChkaXIgPiAwKSA9PSBwYXJ0LmxldmVsICUgMilcbiAgICAgICAgICB0YXJnZXQgPSBtb3ZlSW5MaW5lKGxpbmUsIHBhcnQudG8sIC0xLCBieVVuaXQpO1xuICAgICAgICBlbHNlXG4gICAgICAgICAgdGFyZ2V0ID0gbW92ZUluTGluZShsaW5lLCBwYXJ0LmZyb20sIDEsIGJ5VW5pdCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gbW92ZUxvZ2ljYWxseShsaW5lLCBzdGFydCwgZGlyLCBieVVuaXQpIHtcbiAgICB2YXIgdGFyZ2V0ID0gc3RhcnQgKyBkaXI7XG4gICAgaWYgKGJ5VW5pdCkgd2hpbGUgKHRhcmdldCA+IDAgJiYgaXNFeHRlbmRpbmdDaGFyKGxpbmUudGV4dC5jaGFyQXQodGFyZ2V0KSkpIHRhcmdldCArPSBkaXI7XG4gICAgcmV0dXJuIHRhcmdldCA8IDAgfHwgdGFyZ2V0ID4gbGluZS50ZXh0Lmxlbmd0aCA/IG51bGwgOiB0YXJnZXQ7XG4gIH1cblxuICAvLyBCaWRpcmVjdGlvbmFsIG9yZGVyaW5nIGFsZ29yaXRobVxuICAvLyBTZWUgaHR0cDovL3VuaWNvZGUub3JnL3JlcG9ydHMvdHI5L3RyOS0xMy5odG1sIGZvciB0aGUgYWxnb3JpdGhtXG4gIC8vIHRoYXQgdGhpcyAocGFydGlhbGx5KSBpbXBsZW1lbnRzLlxuXG4gIC8vIE9uZS1jaGFyIGNvZGVzIHVzZWQgZm9yIGNoYXJhY3RlciB0eXBlczpcbiAgLy8gTCAoTCk6ICAgTGVmdC10by1SaWdodFxuICAvLyBSIChSKTogICBSaWdodC10by1MZWZ0XG4gIC8vIHIgKEFMKTogIFJpZ2h0LXRvLUxlZnQgQXJhYmljXG4gIC8vIDEgKEVOKTogIEV1cm9wZWFuIE51bWJlclxuICAvLyArIChFUyk6ICBFdXJvcGVhbiBOdW1iZXIgU2VwYXJhdG9yXG4gIC8vICUgKEVUKTogIEV1cm9wZWFuIE51bWJlciBUZXJtaW5hdG9yXG4gIC8vIG4gKEFOKTogIEFyYWJpYyBOdW1iZXJcbiAgLy8gLCAoQ1MpOiAgQ29tbW9uIE51bWJlciBTZXBhcmF0b3JcbiAgLy8gbSAoTlNNKTogTm9uLVNwYWNpbmcgTWFya1xuICAvLyBiIChCTik6ICBCb3VuZGFyeSBOZXV0cmFsXG4gIC8vIHMgKEIpOiAgIFBhcmFncmFwaCBTZXBhcmF0b3JcbiAgLy8gdCAoUyk6ICAgU2VnbWVudCBTZXBhcmF0b3JcbiAgLy8gdyAoV1MpOiAgV2hpdGVzcGFjZVxuICAvLyBOIChPTik6ICBPdGhlciBOZXV0cmFsc1xuXG4gIC8vIFJldHVybnMgbnVsbCBpZiBjaGFyYWN0ZXJzIGFyZSBvcmRlcmVkIGFzIHRoZXkgYXBwZWFyXG4gIC8vIChsZWZ0LXRvLXJpZ2h0KSwgb3IgYW4gYXJyYXkgb2Ygc2VjdGlvbnMgKHtmcm9tLCB0bywgbGV2ZWx9XG4gIC8vIG9iamVjdHMpIGluIHRoZSBvcmRlciBpbiB3aGljaCB0aGV5IG9jY3VyIHZpc3VhbGx5LlxuICB2YXIgYmlkaU9yZGVyaW5nID0gKGZ1bmN0aW9uKCkge1xuICAgIC8vIENoYXJhY3RlciB0eXBlcyBmb3IgY29kZXBvaW50cyAwIHRvIDB4ZmZcbiAgICB2YXIgbG93VHlwZXMgPSBcImJiYmJiYmJiYnRzdHdzYmJiYmJiYmJiYmJiYmJzc3N0d05OJSUlTk5OTk5OLE4sTjExMTExMTExMTFOTk5OTk5OTExMTExMTExMTExMTExMTExMTExMTExMTExOTk5OTk5MTExMTExMTExMTExMTExMTExMTExMTExMTE5OTk5iYmJiYmJzYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmIsTiUlJSVOTk5OTE5OTk5OJSUxMU5MTk5OMUxOTk5OTkxMTExMTExMTExMTExMTExMTExMTExMTkxMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExOXCI7XG4gICAgLy8gQ2hhcmFjdGVyIHR5cGVzIGZvciBjb2RlcG9pbnRzIDB4NjAwIHRvIDB4NmZmXG4gICAgdmFyIGFyYWJpY1R5cGVzID0gXCJycnJycnJycnJycnIsck5ObW1tbW1tcnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJtbW1tbW1tbW1tbW1tbXJycnJycnJubm5ubm5ubm5uJW5ucnJybXJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJycnJybW1tbW1tbW1tbW1tbW1tbW1tbU5tbW1tXCI7XG4gICAgZnVuY3Rpb24gY2hhclR5cGUoY29kZSkge1xuICAgICAgaWYgKGNvZGUgPD0gMHhmNykgcmV0dXJuIGxvd1R5cGVzLmNoYXJBdChjb2RlKTtcbiAgICAgIGVsc2UgaWYgKDB4NTkwIDw9IGNvZGUgJiYgY29kZSA8PSAweDVmNCkgcmV0dXJuIFwiUlwiO1xuICAgICAgZWxzZSBpZiAoMHg2MDAgPD0gY29kZSAmJiBjb2RlIDw9IDB4NmVkKSByZXR1cm4gYXJhYmljVHlwZXMuY2hhckF0KGNvZGUgLSAweDYwMCk7XG4gICAgICBlbHNlIGlmICgweDZlZSA8PSBjb2RlICYmIGNvZGUgPD0gMHg4YWMpIHJldHVybiBcInJcIjtcbiAgICAgIGVsc2UgaWYgKDB4MjAwMCA8PSBjb2RlICYmIGNvZGUgPD0gMHgyMDBiKSByZXR1cm4gXCJ3XCI7XG4gICAgICBlbHNlIGlmIChjb2RlID09IDB4MjAwYykgcmV0dXJuIFwiYlwiO1xuICAgICAgZWxzZSByZXR1cm4gXCJMXCI7XG4gICAgfVxuXG4gICAgdmFyIGJpZGlSRSA9IC9bXFx1MDU5MC1cXHUwNWY0XFx1MDYwMC1cXHUwNmZmXFx1MDcwMC1cXHUwOGFjXS87XG4gICAgdmFyIGlzTmV1dHJhbCA9IC9bc3R3Tl0vLCBpc1N0cm9uZyA9IC9bTFJyXS8sIGNvdW50c0FzTGVmdCA9IC9bTGIxbl0vLCBjb3VudHNBc051bSA9IC9bMW5dLztcbiAgICAvLyBCcm93c2VycyBzZWVtIHRvIGFsd2F5cyB0cmVhdCB0aGUgYm91bmRhcmllcyBvZiBibG9jayBlbGVtZW50cyBhcyBiZWluZyBMLlxuICAgIHZhciBvdXRlclR5cGUgPSBcIkxcIjtcblxuICAgIGZ1bmN0aW9uIEJpZGlTcGFuKGxldmVsLCBmcm9tLCB0bykge1xuICAgICAgdGhpcy5sZXZlbCA9IGxldmVsO1xuICAgICAgdGhpcy5mcm9tID0gZnJvbTsgdGhpcy50byA9IHRvO1xuICAgIH1cblxuICAgIHJldHVybiBmdW5jdGlvbihzdHIpIHtcbiAgICAgIGlmICghYmlkaVJFLnRlc3Qoc3RyKSkgcmV0dXJuIGZhbHNlO1xuICAgICAgdmFyIGxlbiA9IHN0ci5sZW5ndGgsIHR5cGVzID0gW107XG4gICAgICBmb3IgKHZhciBpID0gMCwgdHlwZTsgaSA8IGxlbjsgKytpKVxuICAgICAgICB0eXBlcy5wdXNoKHR5cGUgPSBjaGFyVHlwZShzdHIuY2hhckNvZGVBdChpKSkpO1xuXG4gICAgICAvLyBXMS4gRXhhbWluZSBlYWNoIG5vbi1zcGFjaW5nIG1hcmsgKE5TTSkgaW4gdGhlIGxldmVsIHJ1biwgYW5kXG4gICAgICAvLyBjaGFuZ2UgdGhlIHR5cGUgb2YgdGhlIE5TTSB0byB0aGUgdHlwZSBvZiB0aGUgcHJldmlvdXNcbiAgICAgIC8vIGNoYXJhY3Rlci4gSWYgdGhlIE5TTSBpcyBhdCB0aGUgc3RhcnQgb2YgdGhlIGxldmVsIHJ1biwgaXQgd2lsbFxuICAgICAgLy8gZ2V0IHRoZSB0eXBlIG9mIHNvci5cbiAgICAgIGZvciAodmFyIGkgPSAwLCBwcmV2ID0gb3V0ZXJUeXBlOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1tpXTtcbiAgICAgICAgaWYgKHR5cGUgPT0gXCJtXCIpIHR5cGVzW2ldID0gcHJldjtcbiAgICAgICAgZWxzZSBwcmV2ID0gdHlwZTtcbiAgICAgIH1cblxuICAgICAgLy8gVzIuIFNlYXJjaCBiYWNrd2FyZHMgZnJvbSBlYWNoIGluc3RhbmNlIG9mIGEgRXVyb3BlYW4gbnVtYmVyXG4gICAgICAvLyB1bnRpbCB0aGUgZmlyc3Qgc3Ryb25nIHR5cGUgKFIsIEwsIEFMLCBvciBzb3IpIGlzIGZvdW5kLiBJZiBhblxuICAgICAgLy8gQUwgaXMgZm91bmQsIGNoYW5nZSB0aGUgdHlwZSBvZiB0aGUgRXVyb3BlYW4gbnVtYmVyIHRvIEFyYWJpY1xuICAgICAgLy8gbnVtYmVyLlxuICAgICAgLy8gVzMuIENoYW5nZSBhbGwgQUxzIHRvIFIuXG4gICAgICBmb3IgKHZhciBpID0gMCwgY3VyID0gb3V0ZXJUeXBlOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1tpXTtcbiAgICAgICAgaWYgKHR5cGUgPT0gXCIxXCIgJiYgY3VyID09IFwiclwiKSB0eXBlc1tpXSA9IFwiblwiO1xuICAgICAgICBlbHNlIGlmIChpc1N0cm9uZy50ZXN0KHR5cGUpKSB7IGN1ciA9IHR5cGU7IGlmICh0eXBlID09IFwiclwiKSB0eXBlc1tpXSA9IFwiUlwiOyB9XG4gICAgICB9XG5cbiAgICAgIC8vIFc0LiBBIHNpbmdsZSBFdXJvcGVhbiBzZXBhcmF0b3IgYmV0d2VlbiB0d28gRXVyb3BlYW4gbnVtYmVyc1xuICAgICAgLy8gY2hhbmdlcyB0byBhIEV1cm9wZWFuIG51bWJlci4gQSBzaW5nbGUgY29tbW9uIHNlcGFyYXRvciBiZXR3ZWVuXG4gICAgICAvLyB0d28gbnVtYmVycyBvZiB0aGUgc2FtZSB0eXBlIGNoYW5nZXMgdG8gdGhhdCB0eXBlLlxuICAgICAgZm9yICh2YXIgaSA9IDEsIHByZXYgPSB0eXBlc1swXTsgaSA8IGxlbiAtIDE7ICsraSkge1xuICAgICAgICB2YXIgdHlwZSA9IHR5cGVzW2ldO1xuICAgICAgICBpZiAodHlwZSA9PSBcIitcIiAmJiBwcmV2ID09IFwiMVwiICYmIHR5cGVzW2krMV0gPT0gXCIxXCIpIHR5cGVzW2ldID0gXCIxXCI7XG4gICAgICAgIGVsc2UgaWYgKHR5cGUgPT0gXCIsXCIgJiYgcHJldiA9PSB0eXBlc1tpKzFdICYmXG4gICAgICAgICAgICAgICAgIChwcmV2ID09IFwiMVwiIHx8IHByZXYgPT0gXCJuXCIpKSB0eXBlc1tpXSA9IHByZXY7XG4gICAgICAgIHByZXYgPSB0eXBlO1xuICAgICAgfVxuXG4gICAgICAvLyBXNS4gQSBzZXF1ZW5jZSBvZiBFdXJvcGVhbiB0ZXJtaW5hdG9ycyBhZGphY2VudCB0byBFdXJvcGVhblxuICAgICAgLy8gbnVtYmVycyBjaGFuZ2VzIHRvIGFsbCBFdXJvcGVhbiBudW1iZXJzLlxuICAgICAgLy8gVzYuIE90aGVyd2lzZSwgc2VwYXJhdG9ycyBhbmQgdGVybWluYXRvcnMgY2hhbmdlIHRvIE90aGVyXG4gICAgICAvLyBOZXV0cmFsLlxuICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBsZW47ICsraSkge1xuICAgICAgICB2YXIgdHlwZSA9IHR5cGVzW2ldO1xuICAgICAgICBpZiAodHlwZSA9PSBcIixcIikgdHlwZXNbaV0gPSBcIk5cIjtcbiAgICAgICAgZWxzZSBpZiAodHlwZSA9PSBcIiVcIikge1xuICAgICAgICAgIGZvciAodmFyIGVuZCA9IGkgKyAxOyBlbmQgPCBsZW4gJiYgdHlwZXNbZW5kXSA9PSBcIiVcIjsgKytlbmQpIHt9XG4gICAgICAgICAgdmFyIHJlcGxhY2UgPSAoaSAmJiB0eXBlc1tpLTFdID09IFwiIVwiKSB8fCAoZW5kIDwgbGVuICYmIHR5cGVzW2VuZF0gPT0gXCIxXCIpID8gXCIxXCIgOiBcIk5cIjtcbiAgICAgICAgICBmb3IgKHZhciBqID0gaTsgaiA8IGVuZDsgKytqKSB0eXBlc1tqXSA9IHJlcGxhY2U7XG4gICAgICAgICAgaSA9IGVuZCAtIDE7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gVzcuIFNlYXJjaCBiYWNrd2FyZHMgZnJvbSBlYWNoIGluc3RhbmNlIG9mIGEgRXVyb3BlYW4gbnVtYmVyXG4gICAgICAvLyB1bnRpbCB0aGUgZmlyc3Qgc3Ryb25nIHR5cGUgKFIsIEwsIG9yIHNvcikgaXMgZm91bmQuIElmIGFuIEwgaXNcbiAgICAgIC8vIGZvdW5kLCB0aGVuIGNoYW5nZSB0aGUgdHlwZSBvZiB0aGUgRXVyb3BlYW4gbnVtYmVyIHRvIEwuXG4gICAgICBmb3IgKHZhciBpID0gMCwgY3VyID0gb3V0ZXJUeXBlOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgdmFyIHR5cGUgPSB0eXBlc1tpXTtcbiAgICAgICAgaWYgKGN1ciA9PSBcIkxcIiAmJiB0eXBlID09IFwiMVwiKSB0eXBlc1tpXSA9IFwiTFwiO1xuICAgICAgICBlbHNlIGlmIChpc1N0cm9uZy50ZXN0KHR5cGUpKSBjdXIgPSB0eXBlO1xuICAgICAgfVxuXG4gICAgICAvLyBOMS4gQSBzZXF1ZW5jZSBvZiBuZXV0cmFscyB0YWtlcyB0aGUgZGlyZWN0aW9uIG9mIHRoZVxuICAgICAgLy8gc3Vycm91bmRpbmcgc3Ryb25nIHRleHQgaWYgdGhlIHRleHQgb24gYm90aCBzaWRlcyBoYXMgdGhlIHNhbWVcbiAgICAgIC8vIGRpcmVjdGlvbi4gRXVyb3BlYW4gYW5kIEFyYWJpYyBudW1iZXJzIGFjdCBhcyBpZiB0aGV5IHdlcmUgUiBpblxuICAgICAgLy8gdGVybXMgb2YgdGhlaXIgaW5mbHVlbmNlIG9uIG5ldXRyYWxzLiBTdGFydC1vZi1sZXZlbC1ydW4gKHNvcilcbiAgICAgIC8vIGFuZCBlbmQtb2YtbGV2ZWwtcnVuIChlb3IpIGFyZSB1c2VkIGF0IGxldmVsIHJ1biBib3VuZGFyaWVzLlxuICAgICAgLy8gTjIuIEFueSByZW1haW5pbmcgbmV1dHJhbHMgdGFrZSB0aGUgZW1iZWRkaW5nIGRpcmVjdGlvbi5cbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICAgICAgaWYgKGlzTmV1dHJhbC50ZXN0KHR5cGVzW2ldKSkge1xuICAgICAgICAgIGZvciAodmFyIGVuZCA9IGkgKyAxOyBlbmQgPCBsZW4gJiYgaXNOZXV0cmFsLnRlc3QodHlwZXNbZW5kXSk7ICsrZW5kKSB7fVxuICAgICAgICAgIHZhciBiZWZvcmUgPSAoaSA/IHR5cGVzW2ktMV0gOiBvdXRlclR5cGUpID09IFwiTFwiO1xuICAgICAgICAgIHZhciBhZnRlciA9IChlbmQgPCBsZW4gPyB0eXBlc1tlbmRdIDogb3V0ZXJUeXBlKSA9PSBcIkxcIjtcbiAgICAgICAgICB2YXIgcmVwbGFjZSA9IGJlZm9yZSB8fCBhZnRlciA/IFwiTFwiIDogXCJSXCI7XG4gICAgICAgICAgZm9yICh2YXIgaiA9IGk7IGogPCBlbmQ7ICsraikgdHlwZXNbal0gPSByZXBsYWNlO1xuICAgICAgICAgIGkgPSBlbmQgLSAxO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEhlcmUgd2UgZGVwYXJ0IGZyb20gdGhlIGRvY3VtZW50ZWQgYWxnb3JpdGhtLCBpbiBvcmRlciB0byBhdm9pZFxuICAgICAgLy8gYnVpbGRpbmcgdXAgYW4gYWN0dWFsIGxldmVscyBhcnJheS4gU2luY2UgdGhlcmUgYXJlIG9ubHkgdGhyZWVcbiAgICAgIC8vIGxldmVscyAoMCwgMSwgMikgaW4gYW4gaW1wbGVtZW50YXRpb24gdGhhdCBkb2Vzbid0IHRha2VcbiAgICAgIC8vIGV4cGxpY2l0IGVtYmVkZGluZyBpbnRvIGFjY291bnQsIHdlIGNhbiBidWlsZCB1cCB0aGUgb3JkZXIgb25cbiAgICAgIC8vIHRoZSBmbHksIHdpdGhvdXQgZm9sbG93aW5nIHRoZSBsZXZlbC1iYXNlZCBhbGdvcml0aG0uXG4gICAgICB2YXIgb3JkZXIgPSBbXSwgbTtcbiAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbGVuOykge1xuICAgICAgICBpZiAoY291bnRzQXNMZWZ0LnRlc3QodHlwZXNbaV0pKSB7XG4gICAgICAgICAgdmFyIHN0YXJ0ID0gaTtcbiAgICAgICAgICBmb3IgKCsraTsgaSA8IGxlbiAmJiBjb3VudHNBc0xlZnQudGVzdCh0eXBlc1tpXSk7ICsraSkge31cbiAgICAgICAgICBvcmRlci5wdXNoKG5ldyBCaWRpU3BhbigwLCBzdGFydCwgaSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHZhciBwb3MgPSBpLCBhdCA9IG9yZGVyLmxlbmd0aDtcbiAgICAgICAgICBmb3IgKCsraTsgaSA8IGxlbiAmJiB0eXBlc1tpXSAhPSBcIkxcIjsgKytpKSB7fVxuICAgICAgICAgIGZvciAodmFyIGogPSBwb3M7IGogPCBpOykge1xuICAgICAgICAgICAgaWYgKGNvdW50c0FzTnVtLnRlc3QodHlwZXNbal0pKSB7XG4gICAgICAgICAgICAgIGlmIChwb3MgPCBqKSBvcmRlci5zcGxpY2UoYXQsIDAsIG5ldyBCaWRpU3BhbigxLCBwb3MsIGopKTtcbiAgICAgICAgICAgICAgdmFyIG5zdGFydCA9IGo7XG4gICAgICAgICAgICAgIGZvciAoKytqOyBqIDwgaSAmJiBjb3VudHNBc051bS50ZXN0KHR5cGVzW2pdKTsgKytqKSB7fVxuICAgICAgICAgICAgICBvcmRlci5zcGxpY2UoYXQsIDAsIG5ldyBCaWRpU3BhbigyLCBuc3RhcnQsIGopKTtcbiAgICAgICAgICAgICAgcG9zID0gajtcbiAgICAgICAgICAgIH0gZWxzZSArK2o7XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChwb3MgPCBpKSBvcmRlci5zcGxpY2UoYXQsIDAsIG5ldyBCaWRpU3BhbigxLCBwb3MsIGkpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKG9yZGVyWzBdLmxldmVsID09IDEgJiYgKG0gPSBzdHIubWF0Y2goL15cXHMrLykpKSB7XG4gICAgICAgIG9yZGVyWzBdLmZyb20gPSBtWzBdLmxlbmd0aDtcbiAgICAgICAgb3JkZXIudW5zaGlmdChuZXcgQmlkaVNwYW4oMCwgMCwgbVswXS5sZW5ndGgpKTtcbiAgICAgIH1cbiAgICAgIGlmIChsc3Qob3JkZXIpLmxldmVsID09IDEgJiYgKG0gPSBzdHIubWF0Y2goL1xccyskLykpKSB7XG4gICAgICAgIGxzdChvcmRlcikudG8gLT0gbVswXS5sZW5ndGg7XG4gICAgICAgIG9yZGVyLnB1c2gobmV3IEJpZGlTcGFuKDAsIGxlbiAtIG1bMF0ubGVuZ3RoLCBsZW4pKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcmRlclswXS5sZXZlbCAhPSBsc3Qob3JkZXIpLmxldmVsKVxuICAgICAgICBvcmRlci5wdXNoKG5ldyBCaWRpU3BhbihvcmRlclswXS5sZXZlbCwgbGVuLCBsZW4pKTtcblxuICAgICAgcmV0dXJuIG9yZGVyO1xuICAgIH07XG4gIH0pKCk7XG5cbiAgLy8gVEhFIEVORFxuXG4gIENvZGVNaXJyb3IudmVyc2lvbiA9IFwiNC4xMi4wXCI7XG5cbiAgcmV0dXJuIENvZGVNaXJyb3I7XG59KTtcbiIsIi8qIVxuICogalF1ZXJ5IEphdmFTY3JpcHQgTGlicmFyeSB2MS4xMS4yXG4gKiBodHRwOi8vanF1ZXJ5LmNvbS9cbiAqXG4gKiBJbmNsdWRlcyBTaXp6bGUuanNcbiAqIGh0dHA6Ly9zaXp6bGVqcy5jb20vXG4gKlxuICogQ29weXJpZ2h0IDIwMDUsIDIwMTQgalF1ZXJ5IEZvdW5kYXRpb24sIEluYy4gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKiBodHRwOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogMjAxNC0xMi0xN1QxNToyN1pcbiAqL1xuXG4oZnVuY3Rpb24oIGdsb2JhbCwgZmFjdG9yeSApIHtcblxuXHRpZiAoIHR5cGVvZiBtb2R1bGUgPT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIG1vZHVsZS5leHBvcnRzID09PSBcIm9iamVjdFwiICkge1xuXHRcdC8vIEZvciBDb21tb25KUyBhbmQgQ29tbW9uSlMtbGlrZSBlbnZpcm9ubWVudHMgd2hlcmUgYSBwcm9wZXIgd2luZG93IGlzIHByZXNlbnQsXG5cdFx0Ly8gZXhlY3V0ZSB0aGUgZmFjdG9yeSBhbmQgZ2V0IGpRdWVyeVxuXHRcdC8vIEZvciBlbnZpcm9ubWVudHMgdGhhdCBkbyBub3QgaW5oZXJlbnRseSBwb3NzZXMgYSB3aW5kb3cgd2l0aCBhIGRvY3VtZW50XG5cdFx0Ly8gKHN1Y2ggYXMgTm9kZS5qcyksIGV4cG9zZSBhIGpRdWVyeS1tYWtpbmcgZmFjdG9yeSBhcyBtb2R1bGUuZXhwb3J0c1xuXHRcdC8vIFRoaXMgYWNjZW50dWF0ZXMgdGhlIG5lZWQgZm9yIHRoZSBjcmVhdGlvbiBvZiBhIHJlYWwgd2luZG93XG5cdFx0Ly8gZS5nLiB2YXIgalF1ZXJ5ID0gcmVxdWlyZShcImpxdWVyeVwiKSh3aW5kb3cpO1xuXHRcdC8vIFNlZSB0aWNrZXQgIzE0NTQ5IGZvciBtb3JlIGluZm9cblx0XHRtb2R1bGUuZXhwb3J0cyA9IGdsb2JhbC5kb2N1bWVudCA/XG5cdFx0XHRmYWN0b3J5KCBnbG9iYWwsIHRydWUgKSA6XG5cdFx0XHRmdW5jdGlvbiggdyApIHtcblx0XHRcdFx0aWYgKCAhdy5kb2N1bWVudCApIHtcblx0XHRcdFx0XHR0aHJvdyBuZXcgRXJyb3IoIFwialF1ZXJ5IHJlcXVpcmVzIGEgd2luZG93IHdpdGggYSBkb2N1bWVudFwiICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIGZhY3RvcnkoIHcgKTtcblx0XHRcdH07XG5cdH0gZWxzZSB7XG5cdFx0ZmFjdG9yeSggZ2xvYmFsICk7XG5cdH1cblxuLy8gUGFzcyB0aGlzIGlmIHdpbmRvdyBpcyBub3QgZGVmaW5lZCB5ZXRcbn0odHlwZW9mIHdpbmRvdyAhPT0gXCJ1bmRlZmluZWRcIiA/IHdpbmRvdyA6IHRoaXMsIGZ1bmN0aW9uKCB3aW5kb3csIG5vR2xvYmFsICkge1xuXG4vLyBDYW4ndCBkbyB0aGlzIGJlY2F1c2Ugc2V2ZXJhbCBhcHBzIGluY2x1ZGluZyBBU1AuTkVUIHRyYWNlXG4vLyB0aGUgc3RhY2sgdmlhIGFyZ3VtZW50cy5jYWxsZXIuY2FsbGVlIGFuZCBGaXJlZm94IGRpZXMgaWZcbi8vIHlvdSB0cnkgdG8gdHJhY2UgdGhyb3VnaCBcInVzZSBzdHJpY3RcIiBjYWxsIGNoYWlucy4gKCMxMzMzNSlcbi8vIFN1cHBvcnQ6IEZpcmVmb3ggMTgrXG4vL1xuXG52YXIgZGVsZXRlZElkcyA9IFtdO1xuXG52YXIgc2xpY2UgPSBkZWxldGVkSWRzLnNsaWNlO1xuXG52YXIgY29uY2F0ID0gZGVsZXRlZElkcy5jb25jYXQ7XG5cbnZhciBwdXNoID0gZGVsZXRlZElkcy5wdXNoO1xuXG52YXIgaW5kZXhPZiA9IGRlbGV0ZWRJZHMuaW5kZXhPZjtcblxudmFyIGNsYXNzMnR5cGUgPSB7fTtcblxudmFyIHRvU3RyaW5nID0gY2xhc3MydHlwZS50b1N0cmluZztcblxudmFyIGhhc093biA9IGNsYXNzMnR5cGUuaGFzT3duUHJvcGVydHk7XG5cbnZhciBzdXBwb3J0ID0ge307XG5cblxuXG52YXJcblx0dmVyc2lvbiA9IFwiMS4xMS4yXCIsXG5cblx0Ly8gRGVmaW5lIGEgbG9jYWwgY29weSBvZiBqUXVlcnlcblx0alF1ZXJ5ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0ICkge1xuXHRcdC8vIFRoZSBqUXVlcnkgb2JqZWN0IGlzIGFjdHVhbGx5IGp1c3QgdGhlIGluaXQgY29uc3RydWN0b3IgJ2VuaGFuY2VkJ1xuXHRcdC8vIE5lZWQgaW5pdCBpZiBqUXVlcnkgaXMgY2FsbGVkIChqdXN0IGFsbG93IGVycm9yIHRvIGJlIHRocm93biBpZiBub3QgaW5jbHVkZWQpXG5cdFx0cmV0dXJuIG5ldyBqUXVlcnkuZm4uaW5pdCggc2VsZWN0b3IsIGNvbnRleHQgKTtcblx0fSxcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMSwgSUU8OVxuXHQvLyBNYWtlIHN1cmUgd2UgdHJpbSBCT00gYW5kIE5CU1Bcblx0cnRyaW0gPSAvXltcXHNcXHVGRUZGXFx4QTBdK3xbXFxzXFx1RkVGRlxceEEwXSskL2csXG5cblx0Ly8gTWF0Y2hlcyBkYXNoZWQgc3RyaW5nIGZvciBjYW1lbGl6aW5nXG5cdHJtc1ByZWZpeCA9IC9eLW1zLS8sXG5cdHJkYXNoQWxwaGEgPSAvLShbXFxkYS16XSkvZ2ksXG5cblx0Ly8gVXNlZCBieSBqUXVlcnkuY2FtZWxDYXNlIGFzIGNhbGxiYWNrIHRvIHJlcGxhY2UoKVxuXHRmY2FtZWxDYXNlID0gZnVuY3Rpb24oIGFsbCwgbGV0dGVyICkge1xuXHRcdHJldHVybiBsZXR0ZXIudG9VcHBlckNhc2UoKTtcblx0fTtcblxualF1ZXJ5LmZuID0galF1ZXJ5LnByb3RvdHlwZSA9IHtcblx0Ly8gVGhlIGN1cnJlbnQgdmVyc2lvbiBvZiBqUXVlcnkgYmVpbmcgdXNlZFxuXHRqcXVlcnk6IHZlcnNpb24sXG5cblx0Y29uc3RydWN0b3I6IGpRdWVyeSxcblxuXHQvLyBTdGFydCB3aXRoIGFuIGVtcHR5IHNlbGVjdG9yXG5cdHNlbGVjdG9yOiBcIlwiLFxuXG5cdC8vIFRoZSBkZWZhdWx0IGxlbmd0aCBvZiBhIGpRdWVyeSBvYmplY3QgaXMgMFxuXHRsZW5ndGg6IDAsXG5cblx0dG9BcnJheTogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHNsaWNlLmNhbGwoIHRoaXMgKTtcblx0fSxcblxuXHQvLyBHZXQgdGhlIE50aCBlbGVtZW50IGluIHRoZSBtYXRjaGVkIGVsZW1lbnQgc2V0IE9SXG5cdC8vIEdldCB0aGUgd2hvbGUgbWF0Y2hlZCBlbGVtZW50IHNldCBhcyBhIGNsZWFuIGFycmF5XG5cdGdldDogZnVuY3Rpb24oIG51bSApIHtcblx0XHRyZXR1cm4gbnVtICE9IG51bGwgP1xuXG5cdFx0XHQvLyBSZXR1cm4ganVzdCB0aGUgb25lIGVsZW1lbnQgZnJvbSB0aGUgc2V0XG5cdFx0XHQoIG51bSA8IDAgPyB0aGlzWyBudW0gKyB0aGlzLmxlbmd0aCBdIDogdGhpc1sgbnVtIF0gKSA6XG5cblx0XHRcdC8vIFJldHVybiBhbGwgdGhlIGVsZW1lbnRzIGluIGEgY2xlYW4gYXJyYXlcblx0XHRcdHNsaWNlLmNhbGwoIHRoaXMgKTtcblx0fSxcblxuXHQvLyBUYWtlIGFuIGFycmF5IG9mIGVsZW1lbnRzIGFuZCBwdXNoIGl0IG9udG8gdGhlIHN0YWNrXG5cdC8vIChyZXR1cm5pbmcgdGhlIG5ldyBtYXRjaGVkIGVsZW1lbnQgc2V0KVxuXHRwdXNoU3RhY2s6IGZ1bmN0aW9uKCBlbGVtcyApIHtcblxuXHRcdC8vIEJ1aWxkIGEgbmV3IGpRdWVyeSBtYXRjaGVkIGVsZW1lbnQgc2V0XG5cdFx0dmFyIHJldCA9IGpRdWVyeS5tZXJnZSggdGhpcy5jb25zdHJ1Y3RvcigpLCBlbGVtcyApO1xuXG5cdFx0Ly8gQWRkIHRoZSBvbGQgb2JqZWN0IG9udG8gdGhlIHN0YWNrIChhcyBhIHJlZmVyZW5jZSlcblx0XHRyZXQucHJldk9iamVjdCA9IHRoaXM7XG5cdFx0cmV0LmNvbnRleHQgPSB0aGlzLmNvbnRleHQ7XG5cblx0XHQvLyBSZXR1cm4gdGhlIG5ld2x5LWZvcm1lZCBlbGVtZW50IHNldFxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0Ly8gRXhlY3V0ZSBhIGNhbGxiYWNrIGZvciBldmVyeSBlbGVtZW50IGluIHRoZSBtYXRjaGVkIHNldC5cblx0Ly8gKFlvdSBjYW4gc2VlZCB0aGUgYXJndW1lbnRzIHdpdGggYW4gYXJyYXkgb2YgYXJncywgYnV0IHRoaXMgaXNcblx0Ly8gb25seSB1c2VkIGludGVybmFsbHkuKVxuXHRlYWNoOiBmdW5jdGlvbiggY2FsbGJhY2ssIGFyZ3MgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5lYWNoKCB0aGlzLCBjYWxsYmFjaywgYXJncyApO1xuXHR9LFxuXG5cdG1hcDogZnVuY3Rpb24oIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5Lm1hcCh0aGlzLCBmdW5jdGlvbiggZWxlbSwgaSApIHtcblx0XHRcdHJldHVybiBjYWxsYmFjay5jYWxsKCBlbGVtLCBpLCBlbGVtICk7XG5cdFx0fSkpO1xuXHR9LFxuXG5cdHNsaWNlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHNsaWNlLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKSApO1xuXHR9LFxuXG5cdGZpcnN0OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5lcSggMCApO1xuXHR9LFxuXG5cdGxhc3Q6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmVxKCAtMSApO1xuXHR9LFxuXG5cdGVxOiBmdW5jdGlvbiggaSApIHtcblx0XHR2YXIgbGVuID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRqID0gK2kgKyAoIGkgPCAwID8gbGVuIDogMCApO1xuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggaiA+PSAwICYmIGogPCBsZW4gPyBbIHRoaXNbal0gXSA6IFtdICk7XG5cdH0sXG5cblx0ZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5wcmV2T2JqZWN0IHx8IHRoaXMuY29uc3RydWN0b3IobnVsbCk7XG5cdH0sXG5cblx0Ly8gRm9yIGludGVybmFsIHVzZSBvbmx5LlxuXHQvLyBCZWhhdmVzIGxpa2UgYW4gQXJyYXkncyBtZXRob2QsIG5vdCBsaWtlIGEgalF1ZXJ5IG1ldGhvZC5cblx0cHVzaDogcHVzaCxcblx0c29ydDogZGVsZXRlZElkcy5zb3J0LFxuXHRzcGxpY2U6IGRlbGV0ZWRJZHMuc3BsaWNlXG59O1xuXG5qUXVlcnkuZXh0ZW5kID0galF1ZXJ5LmZuLmV4dGVuZCA9IGZ1bmN0aW9uKCkge1xuXHR2YXIgc3JjLCBjb3B5SXNBcnJheSwgY29weSwgbmFtZSwgb3B0aW9ucywgY2xvbmUsXG5cdFx0dGFyZ2V0ID0gYXJndW1lbnRzWzBdIHx8IHt9LFxuXHRcdGkgPSAxLFxuXHRcdGxlbmd0aCA9IGFyZ3VtZW50cy5sZW5ndGgsXG5cdFx0ZGVlcCA9IGZhbHNlO1xuXG5cdC8vIEhhbmRsZSBhIGRlZXAgY29weSBzaXR1YXRpb25cblx0aWYgKCB0eXBlb2YgdGFyZ2V0ID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRkZWVwID0gdGFyZ2V0O1xuXG5cdFx0Ly8gc2tpcCB0aGUgYm9vbGVhbiBhbmQgdGhlIHRhcmdldFxuXHRcdHRhcmdldCA9IGFyZ3VtZW50c1sgaSBdIHx8IHt9O1xuXHRcdGkrKztcblx0fVxuXG5cdC8vIEhhbmRsZSBjYXNlIHdoZW4gdGFyZ2V0IGlzIGEgc3RyaW5nIG9yIHNvbWV0aGluZyAocG9zc2libGUgaW4gZGVlcCBjb3B5KVxuXHRpZiAoIHR5cGVvZiB0YXJnZXQgIT09IFwib2JqZWN0XCIgJiYgIWpRdWVyeS5pc0Z1bmN0aW9uKHRhcmdldCkgKSB7XG5cdFx0dGFyZ2V0ID0ge307XG5cdH1cblxuXHQvLyBleHRlbmQgalF1ZXJ5IGl0c2VsZiBpZiBvbmx5IG9uZSBhcmd1bWVudCBpcyBwYXNzZWRcblx0aWYgKCBpID09PSBsZW5ndGggKSB7XG5cdFx0dGFyZ2V0ID0gdGhpcztcblx0XHRpLS07XG5cdH1cblxuXHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHQvLyBPbmx5IGRlYWwgd2l0aCBub24tbnVsbC91bmRlZmluZWQgdmFsdWVzXG5cdFx0aWYgKCAob3B0aW9ucyA9IGFyZ3VtZW50c1sgaSBdKSAhPSBudWxsICkge1xuXHRcdFx0Ly8gRXh0ZW5kIHRoZSBiYXNlIG9iamVjdFxuXHRcdFx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdFx0XHRzcmMgPSB0YXJnZXRbIG5hbWUgXTtcblx0XHRcdFx0Y29weSA9IG9wdGlvbnNbIG5hbWUgXTtcblxuXHRcdFx0XHQvLyBQcmV2ZW50IG5ldmVyLWVuZGluZyBsb29wXG5cdFx0XHRcdGlmICggdGFyZ2V0ID09PSBjb3B5ICkge1xuXHRcdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gUmVjdXJzZSBpZiB3ZSdyZSBtZXJnaW5nIHBsYWluIG9iamVjdHMgb3IgYXJyYXlzXG5cdFx0XHRcdGlmICggZGVlcCAmJiBjb3B5ICYmICggalF1ZXJ5LmlzUGxhaW5PYmplY3QoY29weSkgfHwgKGNvcHlJc0FycmF5ID0galF1ZXJ5LmlzQXJyYXkoY29weSkpICkgKSB7XG5cdFx0XHRcdFx0aWYgKCBjb3B5SXNBcnJheSApIHtcblx0XHRcdFx0XHRcdGNvcHlJc0FycmF5ID0gZmFsc2U7XG5cdFx0XHRcdFx0XHRjbG9uZSA9IHNyYyAmJiBqUXVlcnkuaXNBcnJheShzcmMpID8gc3JjIDogW107XG5cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Y2xvbmUgPSBzcmMgJiYgalF1ZXJ5LmlzUGxhaW5PYmplY3Qoc3JjKSA/IHNyYyA6IHt9O1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE5ldmVyIG1vdmUgb3JpZ2luYWwgb2JqZWN0cywgY2xvbmUgdGhlbVxuXHRcdFx0XHRcdHRhcmdldFsgbmFtZSBdID0galF1ZXJ5LmV4dGVuZCggZGVlcCwgY2xvbmUsIGNvcHkgKTtcblxuXHRcdFx0XHQvLyBEb24ndCBicmluZyBpbiB1bmRlZmluZWQgdmFsdWVzXG5cdFx0XHRcdH0gZWxzZSBpZiAoIGNvcHkgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHR0YXJnZXRbIG5hbWUgXSA9IGNvcHk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBSZXR1cm4gdGhlIG1vZGlmaWVkIG9iamVjdFxuXHRyZXR1cm4gdGFyZ2V0O1xufTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdC8vIFVuaXF1ZSBmb3IgZWFjaCBjb3B5IG9mIGpRdWVyeSBvbiB0aGUgcGFnZVxuXHRleHBhbmRvOiBcImpRdWVyeVwiICsgKCB2ZXJzaW9uICsgTWF0aC5yYW5kb20oKSApLnJlcGxhY2UoIC9cXEQvZywgXCJcIiApLFxuXG5cdC8vIEFzc3VtZSBqUXVlcnkgaXMgcmVhZHkgd2l0aG91dCB0aGUgcmVhZHkgbW9kdWxlXG5cdGlzUmVhZHk6IHRydWUsXG5cblx0ZXJyb3I6IGZ1bmN0aW9uKCBtc2cgKSB7XG5cdFx0dGhyb3cgbmV3IEVycm9yKCBtc2cgKTtcblx0fSxcblxuXHRub29wOiBmdW5jdGlvbigpIHt9LFxuXG5cdC8vIFNlZSB0ZXN0L3VuaXQvY29yZS5qcyBmb3IgZGV0YWlscyBjb25jZXJuaW5nIGlzRnVuY3Rpb24uXG5cdC8vIFNpbmNlIHZlcnNpb24gMS4zLCBET00gbWV0aG9kcyBhbmQgZnVuY3Rpb25zIGxpa2UgYWxlcnRcblx0Ly8gYXJlbid0IHN1cHBvcnRlZC4gVGhleSByZXR1cm4gZmFsc2Ugb24gSUUgKCMyOTY4KS5cblx0aXNGdW5jdGlvbjogZnVuY3Rpb24oIG9iaiApIHtcblx0XHRyZXR1cm4galF1ZXJ5LnR5cGUob2JqKSA9PT0gXCJmdW5jdGlvblwiO1xuXHR9LFxuXG5cdGlzQXJyYXk6IEFycmF5LmlzQXJyYXkgfHwgZnVuY3Rpb24oIG9iaiApIHtcblx0XHRyZXR1cm4galF1ZXJ5LnR5cGUob2JqKSA9PT0gXCJhcnJheVwiO1xuXHR9LFxuXG5cdGlzV2luZG93OiBmdW5jdGlvbiggb2JqICkge1xuXHRcdC8qIGpzaGludCBlcWVxZXE6IGZhbHNlICovXG5cdFx0cmV0dXJuIG9iaiAhPSBudWxsICYmIG9iaiA9PSBvYmoud2luZG93O1xuXHR9LFxuXG5cdGlzTnVtZXJpYzogZnVuY3Rpb24oIG9iaiApIHtcblx0XHQvLyBwYXJzZUZsb2F0IE5hTnMgbnVtZXJpYy1jYXN0IGZhbHNlIHBvc2l0aXZlcyAobnVsbHx0cnVlfGZhbHNlfFwiXCIpXG5cdFx0Ly8gLi4uYnV0IG1pc2ludGVycHJldHMgbGVhZGluZy1udW1iZXIgc3RyaW5ncywgcGFydGljdWxhcmx5IGhleCBsaXRlcmFscyAoXCIweC4uLlwiKVxuXHRcdC8vIHN1YnRyYWN0aW9uIGZvcmNlcyBpbmZpbml0aWVzIHRvIE5hTlxuXHRcdC8vIGFkZGluZyAxIGNvcnJlY3RzIGxvc3Mgb2YgcHJlY2lzaW9uIGZyb20gcGFyc2VGbG9hdCAoIzE1MTAwKVxuXHRcdHJldHVybiAhalF1ZXJ5LmlzQXJyYXkoIG9iaiApICYmIChvYmogLSBwYXJzZUZsb2F0KCBvYmogKSArIDEpID49IDA7XG5cdH0sXG5cblx0aXNFbXB0eU9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcblx0XHR2YXIgbmFtZTtcblx0XHRmb3IgKCBuYW1lIGluIG9iaiApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cdFx0cmV0dXJuIHRydWU7XG5cdH0sXG5cblx0aXNQbGFpbk9iamVjdDogZnVuY3Rpb24oIG9iaiApIHtcblx0XHR2YXIga2V5O1xuXG5cdFx0Ly8gTXVzdCBiZSBhbiBPYmplY3QuXG5cdFx0Ly8gQmVjYXVzZSBvZiBJRSwgd2UgYWxzbyBoYXZlIHRvIGNoZWNrIHRoZSBwcmVzZW5jZSBvZiB0aGUgY29uc3RydWN0b3IgcHJvcGVydHkuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgRE9NIG5vZGVzIGFuZCB3aW5kb3cgb2JqZWN0cyBkb24ndCBwYXNzIHRocm91Z2gsIGFzIHdlbGxcblx0XHRpZiAoICFvYmogfHwgalF1ZXJ5LnR5cGUob2JqKSAhPT0gXCJvYmplY3RcIiB8fCBvYmoubm9kZVR5cGUgfHwgalF1ZXJ5LmlzV2luZG93KCBvYmogKSApIHtcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHR0cnkge1xuXHRcdFx0Ly8gTm90IG93biBjb25zdHJ1Y3RvciBwcm9wZXJ0eSBtdXN0IGJlIE9iamVjdFxuXHRcdFx0aWYgKCBvYmouY29uc3RydWN0b3IgJiZcblx0XHRcdFx0IWhhc093bi5jYWxsKG9iaiwgXCJjb25zdHJ1Y3RvclwiKSAmJlxuXHRcdFx0XHQhaGFzT3duLmNhbGwob2JqLmNvbnN0cnVjdG9yLnByb3RvdHlwZSwgXCJpc1Byb3RvdHlwZU9mXCIpICkge1xuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHQvLyBJRTgsOSBXaWxsIHRocm93IGV4Y2VwdGlvbnMgb24gY2VydGFpbiBob3N0IG9iamVjdHMgIzk4OTdcblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBJRTw5XG5cdFx0Ly8gSGFuZGxlIGl0ZXJhdGlvbiBvdmVyIGluaGVyaXRlZCBwcm9wZXJ0aWVzIGJlZm9yZSBvd24gcHJvcGVydGllcy5cblx0XHRpZiAoIHN1cHBvcnQub3duTGFzdCApIHtcblx0XHRcdGZvciAoIGtleSBpbiBvYmogKSB7XG5cdFx0XHRcdHJldHVybiBoYXNPd24uY2FsbCggb2JqLCBrZXkgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBPd24gcHJvcGVydGllcyBhcmUgZW51bWVyYXRlZCBmaXJzdGx5LCBzbyB0byBzcGVlZCB1cCxcblx0XHQvLyBpZiBsYXN0IG9uZSBpcyBvd24sIHRoZW4gYWxsIHByb3BlcnRpZXMgYXJlIG93bi5cblx0XHRmb3IgKCBrZXkgaW4gb2JqICkge31cblxuXHRcdHJldHVybiBrZXkgPT09IHVuZGVmaW5lZCB8fCBoYXNPd24uY2FsbCggb2JqLCBrZXkgKTtcblx0fSxcblxuXHR0eXBlOiBmdW5jdGlvbiggb2JqICkge1xuXHRcdGlmICggb2JqID09IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gb2JqICsgXCJcIjtcblx0XHR9XG5cdFx0cmV0dXJuIHR5cGVvZiBvYmogPT09IFwib2JqZWN0XCIgfHwgdHlwZW9mIG9iaiA9PT0gXCJmdW5jdGlvblwiID9cblx0XHRcdGNsYXNzMnR5cGVbIHRvU3RyaW5nLmNhbGwob2JqKSBdIHx8IFwib2JqZWN0XCIgOlxuXHRcdFx0dHlwZW9mIG9iajtcblx0fSxcblxuXHQvLyBFdmFsdWF0ZXMgYSBzY3JpcHQgaW4gYSBnbG9iYWwgY29udGV4dFxuXHQvLyBXb3JrYXJvdW5kcyBiYXNlZCBvbiBmaW5kaW5ncyBieSBKaW0gRHJpc2NvbGxcblx0Ly8gaHR0cDovL3dlYmxvZ3MuamF2YS5uZXQvYmxvZy9kcmlzY29sbC9hcmNoaXZlLzIwMDkvMDkvMDgvZXZhbC1qYXZhc2NyaXB0LWdsb2JhbC1jb250ZXh0XG5cdGdsb2JhbEV2YWw6IGZ1bmN0aW9uKCBkYXRhICkge1xuXHRcdGlmICggZGF0YSAmJiBqUXVlcnkudHJpbSggZGF0YSApICkge1xuXHRcdFx0Ly8gV2UgdXNlIGV4ZWNTY3JpcHQgb24gSW50ZXJuZXQgRXhwbG9yZXJcblx0XHRcdC8vIFdlIHVzZSBhbiBhbm9ueW1vdXMgZnVuY3Rpb24gc28gdGhhdCBjb250ZXh0IGlzIHdpbmRvd1xuXHRcdFx0Ly8gcmF0aGVyIHRoYW4galF1ZXJ5IGluIEZpcmVmb3hcblx0XHRcdCggd2luZG93LmV4ZWNTY3JpcHQgfHwgZnVuY3Rpb24oIGRhdGEgKSB7XG5cdFx0XHRcdHdpbmRvd1sgXCJldmFsXCIgXS5jYWxsKCB3aW5kb3csIGRhdGEgKTtcblx0XHRcdH0gKSggZGF0YSApO1xuXHRcdH1cblx0fSxcblxuXHQvLyBDb252ZXJ0IGRhc2hlZCB0byBjYW1lbENhc2U7IHVzZWQgYnkgdGhlIGNzcyBhbmQgZGF0YSBtb2R1bGVzXG5cdC8vIE1pY3Jvc29mdCBmb3Jnb3QgdG8gaHVtcCB0aGVpciB2ZW5kb3IgcHJlZml4ICgjOTU3Milcblx0Y2FtZWxDYXNlOiBmdW5jdGlvbiggc3RyaW5nICkge1xuXHRcdHJldHVybiBzdHJpbmcucmVwbGFjZSggcm1zUHJlZml4LCBcIm1zLVwiICkucmVwbGFjZSggcmRhc2hBbHBoYSwgZmNhbWVsQ2FzZSApO1xuXHR9LFxuXG5cdG5vZGVOYW1lOiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZSAmJiBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0fSxcblxuXHQvLyBhcmdzIGlzIGZvciBpbnRlcm5hbCB1c2FnZSBvbmx5XG5cdGVhY2g6IGZ1bmN0aW9uKCBvYmosIGNhbGxiYWNrLCBhcmdzICkge1xuXHRcdHZhciB2YWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuZ3RoID0gb2JqLmxlbmd0aCxcblx0XHRcdGlzQXJyYXkgPSBpc0FycmF5bGlrZSggb2JqICk7XG5cblx0XHRpZiAoIGFyZ3MgKSB7XG5cdFx0XHRpZiAoIGlzQXJyYXkgKSB7XG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRcdHZhbHVlID0gY2FsbGJhY2suYXBwbHkoIG9ialsgaSBdLCBhcmdzICk7XG5cblx0XHRcdFx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggaSBpbiBvYmogKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjay5hcHBseSggb2JqWyBpIF0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHQvLyBBIHNwZWNpYWwsIGZhc3QsIGNhc2UgZm9yIHRoZSBtb3N0IGNvbW1vbiB1c2Ugb2YgZWFjaFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRpZiAoIGlzQXJyYXkgKSB7XG5cdFx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRcdHZhbHVlID0gY2FsbGJhY2suY2FsbCggb2JqWyBpIF0sIGksIG9ialsgaSBdICk7XG5cblx0XHRcdFx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0Zm9yICggaSBpbiBvYmogKSB7XG5cdFx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjay5jYWxsKCBvYmpbIGkgXSwgaSwgb2JqWyBpIF0gKTtcblxuXHRcdFx0XHRcdGlmICggdmFsdWUgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIG9iajtcblx0fSxcblxuXHQvLyBTdXBwb3J0OiBBbmRyb2lkPDQuMSwgSUU8OVxuXHR0cmltOiBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRyZXR1cm4gdGV4dCA9PSBudWxsID9cblx0XHRcdFwiXCIgOlxuXHRcdFx0KCB0ZXh0ICsgXCJcIiApLnJlcGxhY2UoIHJ0cmltLCBcIlwiICk7XG5cdH0sXG5cblx0Ly8gcmVzdWx0cyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxuXHRtYWtlQXJyYXk6IGZ1bmN0aW9uKCBhcnIsIHJlc3VsdHMgKSB7XG5cdFx0dmFyIHJldCA9IHJlc3VsdHMgfHwgW107XG5cblx0XHRpZiAoIGFyciAhPSBudWxsICkge1xuXHRcdFx0aWYgKCBpc0FycmF5bGlrZSggT2JqZWN0KGFycikgKSApIHtcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCByZXQsXG5cdFx0XHRcdFx0dHlwZW9mIGFyciA9PT0gXCJzdHJpbmdcIiA/XG5cdFx0XHRcdFx0WyBhcnIgXSA6IGFyclxuXHRcdFx0XHQpO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cHVzaC5jYWxsKCByZXQsIGFyciApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiByZXQ7XG5cdH0sXG5cblx0aW5BcnJheTogZnVuY3Rpb24oIGVsZW0sIGFyciwgaSApIHtcblx0XHR2YXIgbGVuO1xuXG5cdFx0aWYgKCBhcnIgKSB7XG5cdFx0XHRpZiAoIGluZGV4T2YgKSB7XG5cdFx0XHRcdHJldHVybiBpbmRleE9mLmNhbGwoIGFyciwgZWxlbSwgaSApO1xuXHRcdFx0fVxuXG5cdFx0XHRsZW4gPSBhcnIubGVuZ3RoO1xuXHRcdFx0aSA9IGkgPyBpIDwgMCA/IE1hdGgubWF4KCAwLCBsZW4gKyBpICkgOiBpIDogMDtcblxuXHRcdFx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0XHRcdC8vIFNraXAgYWNjZXNzaW5nIGluIHNwYXJzZSBhcnJheXNcblx0XHRcdFx0aWYgKCBpIGluIGFyciAmJiBhcnJbIGkgXSA9PT0gZWxlbSApIHtcblx0XHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiAtMTtcblx0fSxcblxuXHRtZXJnZTogZnVuY3Rpb24oIGZpcnN0LCBzZWNvbmQgKSB7XG5cdFx0dmFyIGxlbiA9ICtzZWNvbmQubGVuZ3RoLFxuXHRcdFx0aiA9IDAsXG5cdFx0XHRpID0gZmlyc3QubGVuZ3RoO1xuXG5cdFx0d2hpbGUgKCBqIDwgbGVuICkge1xuXHRcdFx0Zmlyc3RbIGkrKyBdID0gc2Vjb25kWyBqKysgXTtcblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBJRTw5XG5cdFx0Ly8gV29ya2Fyb3VuZCBjYXN0aW5nIG9mIC5sZW5ndGggdG8gTmFOIG9uIG90aGVyd2lzZSBhcnJheWxpa2Ugb2JqZWN0cyAoZS5nLiwgTm9kZUxpc3RzKVxuXHRcdGlmICggbGVuICE9PSBsZW4gKSB7XG5cdFx0XHR3aGlsZSAoIHNlY29uZFtqXSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRmaXJzdFsgaSsrIF0gPSBzZWNvbmRbIGorKyBdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGZpcnN0Lmxlbmd0aCA9IGk7XG5cblx0XHRyZXR1cm4gZmlyc3Q7XG5cdH0sXG5cblx0Z3JlcDogZnVuY3Rpb24oIGVsZW1zLCBjYWxsYmFjaywgaW52ZXJ0ICkge1xuXHRcdHZhciBjYWxsYmFja0ludmVyc2UsXG5cdFx0XHRtYXRjaGVzID0gW10sXG5cdFx0XHRpID0gMCxcblx0XHRcdGxlbmd0aCA9IGVsZW1zLmxlbmd0aCxcblx0XHRcdGNhbGxiYWNrRXhwZWN0ID0gIWludmVydDtcblxuXHRcdC8vIEdvIHRocm91Z2ggdGhlIGFycmF5LCBvbmx5IHNhdmluZyB0aGUgaXRlbXNcblx0XHQvLyB0aGF0IHBhc3MgdGhlIHZhbGlkYXRvciBmdW5jdGlvblxuXHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0Y2FsbGJhY2tJbnZlcnNlID0gIWNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpICk7XG5cdFx0XHRpZiAoIGNhbGxiYWNrSW52ZXJzZSAhPT0gY2FsbGJhY2tFeHBlY3QgKSB7XG5cdFx0XHRcdG1hdGNoZXMucHVzaCggZWxlbXNbIGkgXSApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBtYXRjaGVzO1xuXHR9LFxuXG5cdC8vIGFyZyBpcyBmb3IgaW50ZXJuYWwgdXNhZ2Ugb25seVxuXHRtYXA6IGZ1bmN0aW9uKCBlbGVtcywgY2FsbGJhY2ssIGFyZyApIHtcblx0XHR2YXIgdmFsdWUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGxlbmd0aCA9IGVsZW1zLmxlbmd0aCxcblx0XHRcdGlzQXJyYXkgPSBpc0FycmF5bGlrZSggZWxlbXMgKSxcblx0XHRcdHJldCA9IFtdO1xuXG5cdFx0Ly8gR28gdGhyb3VnaCB0aGUgYXJyYXksIHRyYW5zbGF0aW5nIGVhY2ggb2YgdGhlIGl0ZW1zIHRvIHRoZWlyIG5ldyB2YWx1ZXNcblx0XHRpZiAoIGlzQXJyYXkgKSB7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0dmFsdWUgPSBjYWxsYmFjayggZWxlbXNbIGkgXSwgaSwgYXJnICk7XG5cblx0XHRcdFx0aWYgKCB2YWx1ZSAhPSBudWxsICkge1xuXHRcdFx0XHRcdHJldC5wdXNoKCB2YWx1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHQvLyBHbyB0aHJvdWdoIGV2ZXJ5IGtleSBvbiB0aGUgb2JqZWN0LFxuXHRcdH0gZWxzZSB7XG5cdFx0XHRmb3IgKCBpIGluIGVsZW1zICkge1xuXHRcdFx0XHR2YWx1ZSA9IGNhbGxiYWNrKCBlbGVtc1sgaSBdLCBpLCBhcmcgKTtcblxuXHRcdFx0XHRpZiAoIHZhbHVlICE9IG51bGwgKSB7XG5cdFx0XHRcdFx0cmV0LnB1c2goIHZhbHVlICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBGbGF0dGVuIGFueSBuZXN0ZWQgYXJyYXlzXG5cdFx0cmV0dXJuIGNvbmNhdC5hcHBseSggW10sIHJldCApO1xuXHR9LFxuXG5cdC8vIEEgZ2xvYmFsIEdVSUQgY291bnRlciBmb3Igb2JqZWN0c1xuXHRndWlkOiAxLFxuXG5cdC8vIEJpbmQgYSBmdW5jdGlvbiB0byBhIGNvbnRleHQsIG9wdGlvbmFsbHkgcGFydGlhbGx5IGFwcGx5aW5nIGFueVxuXHQvLyBhcmd1bWVudHMuXG5cdHByb3h5OiBmdW5jdGlvbiggZm4sIGNvbnRleHQgKSB7XG5cdFx0dmFyIGFyZ3MsIHByb3h5LCB0bXA7XG5cblx0XHRpZiAoIHR5cGVvZiBjb250ZXh0ID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0dG1wID0gZm5bIGNvbnRleHQgXTtcblx0XHRcdGNvbnRleHQgPSBmbjtcblx0XHRcdGZuID0gdG1wO1xuXHRcdH1cblxuXHRcdC8vIFF1aWNrIGNoZWNrIHRvIGRldGVybWluZSBpZiB0YXJnZXQgaXMgY2FsbGFibGUsIGluIHRoZSBzcGVjXG5cdFx0Ly8gdGhpcyB0aHJvd3MgYSBUeXBlRXJyb3IsIGJ1dCB3ZSB3aWxsIGp1c3QgcmV0dXJuIHVuZGVmaW5lZC5cblx0XHRpZiAoICFqUXVlcnkuaXNGdW5jdGlvbiggZm4gKSApIHtcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fVxuXG5cdFx0Ly8gU2ltdWxhdGVkIGJpbmRcblx0XHRhcmdzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzLCAyICk7XG5cdFx0cHJveHkgPSBmdW5jdGlvbigpIHtcblx0XHRcdHJldHVybiBmbi5hcHBseSggY29udGV4dCB8fCB0aGlzLCBhcmdzLmNvbmNhdCggc2xpY2UuY2FsbCggYXJndW1lbnRzICkgKSApO1xuXHRcdH07XG5cblx0XHQvLyBTZXQgdGhlIGd1aWQgb2YgdW5pcXVlIGhhbmRsZXIgdG8gdGhlIHNhbWUgb2Ygb3JpZ2luYWwgaGFuZGxlciwgc28gaXQgY2FuIGJlIHJlbW92ZWRcblx0XHRwcm94eS5ndWlkID0gZm4uZ3VpZCA9IGZuLmd1aWQgfHwgalF1ZXJ5Lmd1aWQrKztcblxuXHRcdHJldHVybiBwcm94eTtcblx0fSxcblxuXHRub3c6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiArKCBuZXcgRGF0ZSgpICk7XG5cdH0sXG5cblx0Ly8galF1ZXJ5LnN1cHBvcnQgaXMgbm90IHVzZWQgaW4gQ29yZSBidXQgb3RoZXIgcHJvamVjdHMgYXR0YWNoIHRoZWlyXG5cdC8vIHByb3BlcnRpZXMgdG8gaXQgc28gaXQgbmVlZHMgdG8gZXhpc3QuXG5cdHN1cHBvcnQ6IHN1cHBvcnRcbn0pO1xuXG4vLyBQb3B1bGF0ZSB0aGUgY2xhc3MydHlwZSBtYXBcbmpRdWVyeS5lYWNoKFwiQm9vbGVhbiBOdW1iZXIgU3RyaW5nIEZ1bmN0aW9uIEFycmF5IERhdGUgUmVnRXhwIE9iamVjdCBFcnJvclwiLnNwbGl0KFwiIFwiKSwgZnVuY3Rpb24oaSwgbmFtZSkge1xuXHRjbGFzczJ0eXBlWyBcIltvYmplY3QgXCIgKyBuYW1lICsgXCJdXCIgXSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcbn0pO1xuXG5mdW5jdGlvbiBpc0FycmF5bGlrZSggb2JqICkge1xuXHR2YXIgbGVuZ3RoID0gb2JqLmxlbmd0aCxcblx0XHR0eXBlID0galF1ZXJ5LnR5cGUoIG9iaiApO1xuXG5cdGlmICggdHlwZSA9PT0gXCJmdW5jdGlvblwiIHx8IGpRdWVyeS5pc1dpbmRvdyggb2JqICkgKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cblx0aWYgKCBvYmoubm9kZVR5cGUgPT09IDEgJiYgbGVuZ3RoICkge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cblx0cmV0dXJuIHR5cGUgPT09IFwiYXJyYXlcIiB8fCBsZW5ndGggPT09IDAgfHxcblx0XHR0eXBlb2YgbGVuZ3RoID09PSBcIm51bWJlclwiICYmIGxlbmd0aCA+IDAgJiYgKCBsZW5ndGggLSAxICkgaW4gb2JqO1xufVxudmFyIFNpenpsZSA9XG4vKiFcbiAqIFNpenpsZSBDU1MgU2VsZWN0b3IgRW5naW5lIHYyLjIuMC1wcmVcbiAqIGh0dHA6Ly9zaXp6bGVqcy5jb20vXG4gKlxuICogQ29weXJpZ2h0IDIwMDgsIDIwMTQgalF1ZXJ5IEZvdW5kYXRpb24sIEluYy4gYW5kIG90aGVyIGNvbnRyaWJ1dG9yc1xuICogUmVsZWFzZWQgdW5kZXIgdGhlIE1JVCBsaWNlbnNlXG4gKiBodHRwOi8vanF1ZXJ5Lm9yZy9saWNlbnNlXG4gKlxuICogRGF0ZTogMjAxNC0xMi0xNlxuICovXG4oZnVuY3Rpb24oIHdpbmRvdyApIHtcblxudmFyIGksXG5cdHN1cHBvcnQsXG5cdEV4cHIsXG5cdGdldFRleHQsXG5cdGlzWE1MLFxuXHR0b2tlbml6ZSxcblx0Y29tcGlsZSxcblx0c2VsZWN0LFxuXHRvdXRlcm1vc3RDb250ZXh0LFxuXHRzb3J0SW5wdXQsXG5cdGhhc0R1cGxpY2F0ZSxcblxuXHQvLyBMb2NhbCBkb2N1bWVudCB2YXJzXG5cdHNldERvY3VtZW50LFxuXHRkb2N1bWVudCxcblx0ZG9jRWxlbSxcblx0ZG9jdW1lbnRJc0hUTUwsXG5cdHJidWdneVFTQSxcblx0cmJ1Z2d5TWF0Y2hlcyxcblx0bWF0Y2hlcyxcblx0Y29udGFpbnMsXG5cblx0Ly8gSW5zdGFuY2Utc3BlY2lmaWMgZGF0YVxuXHRleHBhbmRvID0gXCJzaXp6bGVcIiArIDEgKiBuZXcgRGF0ZSgpLFxuXHRwcmVmZXJyZWREb2MgPSB3aW5kb3cuZG9jdW1lbnQsXG5cdGRpcnJ1bnMgPSAwLFxuXHRkb25lID0gMCxcblx0Y2xhc3NDYWNoZSA9IGNyZWF0ZUNhY2hlKCksXG5cdHRva2VuQ2FjaGUgPSBjcmVhdGVDYWNoZSgpLFxuXHRjb21waWxlckNhY2hlID0gY3JlYXRlQ2FjaGUoKSxcblx0c29ydE9yZGVyID0gZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHR9XG5cdFx0cmV0dXJuIDA7XG5cdH0sXG5cblx0Ly8gR2VuZXJhbC1wdXJwb3NlIGNvbnN0YW50c1xuXHRNQVhfTkVHQVRJVkUgPSAxIDw8IDMxLFxuXG5cdC8vIEluc3RhbmNlIG1ldGhvZHNcblx0aGFzT3duID0gKHt9KS5oYXNPd25Qcm9wZXJ0eSxcblx0YXJyID0gW10sXG5cdHBvcCA9IGFyci5wb3AsXG5cdHB1c2hfbmF0aXZlID0gYXJyLnB1c2gsXG5cdHB1c2ggPSBhcnIucHVzaCxcblx0c2xpY2UgPSBhcnIuc2xpY2UsXG5cdC8vIFVzZSBhIHN0cmlwcGVkLWRvd24gaW5kZXhPZiBhcyBpdCdzIGZhc3RlciB0aGFuIG5hdGl2ZVxuXHQvLyBodHRwOi8vanNwZXJmLmNvbS90aG9yLWluZGV4b2YtdnMtZm9yLzVcblx0aW5kZXhPZiA9IGZ1bmN0aW9uKCBsaXN0LCBlbGVtICkge1xuXHRcdHZhciBpID0gMCxcblx0XHRcdGxlbiA9IGxpc3QubGVuZ3RoO1xuXHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0aWYgKCBsaXN0W2ldID09PSBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIC0xO1xuXHR9LFxuXG5cdGJvb2xlYW5zID0gXCJjaGVja2VkfHNlbGVjdGVkfGFzeW5jfGF1dG9mb2N1c3xhdXRvcGxheXxjb250cm9sc3xkZWZlcnxkaXNhYmxlZHxoaWRkZW58aXNtYXB8bG9vcHxtdWx0aXBsZXxvcGVufHJlYWRvbmx5fHJlcXVpcmVkfHNjb3BlZFwiLFxuXG5cdC8vIFJlZ3VsYXIgZXhwcmVzc2lvbnNcblxuXHQvLyBXaGl0ZXNwYWNlIGNoYXJhY3RlcnMgaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1zZWxlY3RvcnMvI3doaXRlc3BhY2Vcblx0d2hpdGVzcGFjZSA9IFwiW1xcXFx4MjBcXFxcdFxcXFxyXFxcXG5cXFxcZl1cIixcblx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvY3NzMy1zeW50YXgvI2NoYXJhY3RlcnNcblx0Y2hhcmFjdGVyRW5jb2RpbmcgPSBcIig/OlxcXFxcXFxcLnxbXFxcXHctXXxbXlxcXFx4MDAtXFxcXHhhMF0pK1wiLFxuXG5cdC8vIExvb3NlbHkgbW9kZWxlZCBvbiBDU1MgaWRlbnRpZmllciBjaGFyYWN0ZXJzXG5cdC8vIEFuIHVucXVvdGVkIHZhbHVlIHNob3VsZCBiZSBhIENTUyBpZGVudGlmaWVyIGh0dHA6Ly93d3cudzMub3JnL1RSL2NzczMtc2VsZWN0b3JzLyNhdHRyaWJ1dGUtc2VsZWN0b3JzXG5cdC8vIFByb3BlciBzeW50YXg6IGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCN2YWx1ZS1kZWYtaWRlbnRpZmllclxuXHRpZGVudGlmaWVyID0gY2hhcmFjdGVyRW5jb2RpbmcucmVwbGFjZSggXCJ3XCIsIFwidyNcIiApLFxuXG5cdC8vIEF0dHJpYnV0ZSBzZWxlY3RvcnM6IGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jYXR0cmlidXRlLXNlbGVjdG9yc1xuXHRhdHRyaWJ1dGVzID0gXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKihcIiArIGNoYXJhY3RlckVuY29kaW5nICsgXCIpKD86XCIgKyB3aGl0ZXNwYWNlICtcblx0XHQvLyBPcGVyYXRvciAoY2FwdHVyZSAyKVxuXHRcdFwiKihbKl4kfCF+XT89KVwiICsgd2hpdGVzcGFjZSArXG5cdFx0Ly8gXCJBdHRyaWJ1dGUgdmFsdWVzIG11c3QgYmUgQ1NTIGlkZW50aWZpZXJzIFtjYXB0dXJlIDVdIG9yIHN0cmluZ3MgW2NhcHR1cmUgMyBvciBjYXB0dXJlIDRdXCJcblx0XHRcIiooPzonKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcJ10pKiknfFxcXCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFxcXFwiXSkqKVxcXCJ8KFwiICsgaWRlbnRpZmllciArIFwiKSl8KVwiICsgd2hpdGVzcGFjZSArXG5cdFx0XCIqXFxcXF1cIixcblxuXHRwc2V1ZG9zID0gXCI6KFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIikoPzpcXFxcKChcIiArXG5cdFx0Ly8gVG8gcmVkdWNlIHRoZSBudW1iZXIgb2Ygc2VsZWN0b3JzIG5lZWRpbmcgdG9rZW5pemUgaW4gdGhlIHByZUZpbHRlciwgcHJlZmVyIGFyZ3VtZW50czpcblx0XHQvLyAxLiBxdW90ZWQgKGNhcHR1cmUgMzsgY2FwdHVyZSA0IG9yIGNhcHR1cmUgNSlcblx0XHRcIignKCg/OlxcXFxcXFxcLnxbXlxcXFxcXFxcJ10pKiknfFxcXCIoKD86XFxcXFxcXFwufFteXFxcXFxcXFxcXFwiXSkqKVxcXCIpfFwiICtcblx0XHQvLyAyLiBzaW1wbGUgKGNhcHR1cmUgNilcblx0XHRcIigoPzpcXFxcXFxcXC58W15cXFxcXFxcXCgpW1xcXFxdXXxcIiArIGF0dHJpYnV0ZXMgKyBcIikqKXxcIiArXG5cdFx0Ly8gMy4gYW55dGhpbmcgZWxzZSAoY2FwdHVyZSAyKVxuXHRcdFwiLipcIiArXG5cdFx0XCIpXFxcXCl8KVwiLFxuXG5cdC8vIExlYWRpbmcgYW5kIG5vbi1lc2NhcGVkIHRyYWlsaW5nIHdoaXRlc3BhY2UsIGNhcHR1cmluZyBzb21lIG5vbi13aGl0ZXNwYWNlIGNoYXJhY3RlcnMgcHJlY2VkaW5nIHRoZSBsYXR0ZXJcblx0cndoaXRlc3BhY2UgPSBuZXcgUmVnRXhwKCB3aGl0ZXNwYWNlICsgXCIrXCIsIFwiZ1wiICksXG5cdHJ0cmltID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIrfCgoPzpefFteXFxcXFxcXFxdKSg/OlxcXFxcXFxcLikqKVwiICsgd2hpdGVzcGFjZSArIFwiKyRcIiwgXCJnXCIgKSxcblxuXHRyY29tbWEgPSBuZXcgUmVnRXhwKCBcIl5cIiArIHdoaXRlc3BhY2UgKyBcIiosXCIgKyB3aGl0ZXNwYWNlICsgXCIqXCIgKSxcblx0cmNvbWJpbmF0b3JzID0gbmV3IFJlZ0V4cCggXCJeXCIgKyB3aGl0ZXNwYWNlICsgXCIqKFs+K35dfFwiICsgd2hpdGVzcGFjZSArIFwiKVwiICsgd2hpdGVzcGFjZSArIFwiKlwiICksXG5cblx0cmF0dHJpYnV0ZVF1b3RlcyA9IG5ldyBSZWdFeHAoIFwiPVwiICsgd2hpdGVzcGFjZSArIFwiKihbXlxcXFxdJ1xcXCJdKj8pXCIgKyB3aGl0ZXNwYWNlICsgXCIqXFxcXF1cIiwgXCJnXCIgKSxcblxuXHRycHNldWRvID0gbmV3IFJlZ0V4cCggcHNldWRvcyApLFxuXHRyaWRlbnRpZmllciA9IG5ldyBSZWdFeHAoIFwiXlwiICsgaWRlbnRpZmllciArIFwiJFwiICksXG5cblx0bWF0Y2hFeHByID0ge1xuXHRcdFwiSURcIjogbmV3IFJlZ0V4cCggXCJeIyhcIiArIGNoYXJhY3RlckVuY29kaW5nICsgXCIpXCIgKSxcblx0XHRcIkNMQVNTXCI6IG5ldyBSZWdFeHAoIFwiXlxcXFwuKFwiICsgY2hhcmFjdGVyRW5jb2RpbmcgKyBcIilcIiApLFxuXHRcdFwiVEFHXCI6IG5ldyBSZWdFeHAoIFwiXihcIiArIGNoYXJhY3RlckVuY29kaW5nLnJlcGxhY2UoIFwid1wiLCBcIncqXCIgKSArIFwiKVwiICksXG5cdFx0XCJBVFRSXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgYXR0cmlidXRlcyApLFxuXHRcdFwiUFNFVURPXCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgcHNldWRvcyApLFxuXHRcdFwiQ0hJTERcIjogbmV3IFJlZ0V4cCggXCJeOihvbmx5fGZpcnN0fGxhc3R8bnRofG50aC1sYXN0KS0oY2hpbGR8b2YtdHlwZSkoPzpcXFxcKFwiICsgd2hpdGVzcGFjZSArXG5cdFx0XHRcIiooZXZlbnxvZGR8KChbKy1dfCkoXFxcXGQqKW58KVwiICsgd2hpdGVzcGFjZSArIFwiKig/OihbKy1dfClcIiArIHdoaXRlc3BhY2UgK1xuXHRcdFx0XCIqKFxcXFxkKyl8KSlcIiArIHdoaXRlc3BhY2UgKyBcIipcXFxcKXwpXCIsIFwiaVwiICksXG5cdFx0XCJib29sXCI6IG5ldyBSZWdFeHAoIFwiXig/OlwiICsgYm9vbGVhbnMgKyBcIikkXCIsIFwiaVwiICksXG5cdFx0Ly8gRm9yIHVzZSBpbiBsaWJyYXJpZXMgaW1wbGVtZW50aW5nIC5pcygpXG5cdFx0Ly8gV2UgdXNlIHRoaXMgZm9yIFBPUyBtYXRjaGluZyBpbiBgc2VsZWN0YFxuXHRcdFwibmVlZHNDb250ZXh0XCI6IG5ldyBSZWdFeHAoIFwiXlwiICsgd2hpdGVzcGFjZSArIFwiKls+K35dfDooZXZlbnxvZGR8ZXF8Z3R8bHR8bnRofGZpcnN0fGxhc3QpKD86XFxcXChcIiArXG5cdFx0XHR3aGl0ZXNwYWNlICsgXCIqKCg/Oi1cXFxcZCk/XFxcXGQqKVwiICsgd2hpdGVzcGFjZSArIFwiKlxcXFwpfCkoPz1bXi1dfCQpXCIsIFwiaVwiIClcblx0fSxcblxuXHRyaW5wdXRzID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9uKSQvaSxcblx0cmhlYWRlciA9IC9eaFxcZCQvaSxcblxuXHRybmF0aXZlID0gL15bXntdK1xce1xccypcXFtuYXRpdmUgXFx3LyxcblxuXHQvLyBFYXNpbHktcGFyc2VhYmxlL3JldHJpZXZhYmxlIElEIG9yIFRBRyBvciBDTEFTUyBzZWxlY3RvcnNcblx0cnF1aWNrRXhwciA9IC9eKD86IyhbXFx3LV0rKXwoXFx3Kyl8XFwuKFtcXHctXSspKSQvLFxuXG5cdHJzaWJsaW5nID0gL1srfl0vLFxuXHRyZXNjYXBlID0gLyd8XFxcXC9nLFxuXG5cdC8vIENTUyBlc2NhcGVzIGh0dHA6Ly93d3cudzMub3JnL1RSL0NTUzIxL3N5bmRhdGEuaHRtbCNlc2NhcGVkLWNoYXJhY3RlcnNcblx0cnVuZXNjYXBlID0gbmV3IFJlZ0V4cCggXCJcXFxcXFxcXChbXFxcXGRhLWZdezEsNn1cIiArIHdoaXRlc3BhY2UgKyBcIj98KFwiICsgd2hpdGVzcGFjZSArIFwiKXwuKVwiLCBcImlnXCIgKSxcblx0ZnVuZXNjYXBlID0gZnVuY3Rpb24oIF8sIGVzY2FwZWQsIGVzY2FwZWRXaGl0ZXNwYWNlICkge1xuXHRcdHZhciBoaWdoID0gXCIweFwiICsgZXNjYXBlZCAtIDB4MTAwMDA7XG5cdFx0Ly8gTmFOIG1lYW5zIG5vbi1jb2RlcG9pbnRcblx0XHQvLyBTdXBwb3J0OiBGaXJlZm94PDI0XG5cdFx0Ly8gV29ya2Fyb3VuZCBlcnJvbmVvdXMgbnVtZXJpYyBpbnRlcnByZXRhdGlvbiBvZiArXCIweFwiXG5cdFx0cmV0dXJuIGhpZ2ggIT09IGhpZ2ggfHwgZXNjYXBlZFdoaXRlc3BhY2UgP1xuXHRcdFx0ZXNjYXBlZCA6XG5cdFx0XHRoaWdoIDwgMCA/XG5cdFx0XHRcdC8vIEJNUCBjb2RlcG9pbnRcblx0XHRcdFx0U3RyaW5nLmZyb21DaGFyQ29kZSggaGlnaCArIDB4MTAwMDAgKSA6XG5cdFx0XHRcdC8vIFN1cHBsZW1lbnRhbCBQbGFuZSBjb2RlcG9pbnQgKHN1cnJvZ2F0ZSBwYWlyKVxuXHRcdFx0XHRTdHJpbmcuZnJvbUNoYXJDb2RlKCBoaWdoID4+IDEwIHwgMHhEODAwLCBoaWdoICYgMHgzRkYgfCAweERDMDAgKTtcblx0fSxcblxuXHQvLyBVc2VkIGZvciBpZnJhbWVzXG5cdC8vIFNlZSBzZXREb2N1bWVudCgpXG5cdC8vIFJlbW92aW5nIHRoZSBmdW5jdGlvbiB3cmFwcGVyIGNhdXNlcyBhIFwiUGVybWlzc2lvbiBEZW5pZWRcIlxuXHQvLyBlcnJvciBpbiBJRVxuXHR1bmxvYWRIYW5kbGVyID0gZnVuY3Rpb24oKSB7XG5cdFx0c2V0RG9jdW1lbnQoKTtcblx0fTtcblxuLy8gT3B0aW1pemUgZm9yIHB1c2guYXBwbHkoIF8sIE5vZGVMaXN0IClcbnRyeSB7XG5cdHB1c2guYXBwbHkoXG5cdFx0KGFyciA9IHNsaWNlLmNhbGwoIHByZWZlcnJlZERvYy5jaGlsZE5vZGVzICkpLFxuXHRcdHByZWZlcnJlZERvYy5jaGlsZE5vZGVzXG5cdCk7XG5cdC8vIFN1cHBvcnQ6IEFuZHJvaWQ8NC4wXG5cdC8vIERldGVjdCBzaWxlbnRseSBmYWlsaW5nIHB1c2guYXBwbHlcblx0YXJyWyBwcmVmZXJyZWREb2MuY2hpbGROb2Rlcy5sZW5ndGggXS5ub2RlVHlwZTtcbn0gY2F0Y2ggKCBlICkge1xuXHRwdXNoID0geyBhcHBseTogYXJyLmxlbmd0aCA/XG5cblx0XHQvLyBMZXZlcmFnZSBzbGljZSBpZiBwb3NzaWJsZVxuXHRcdGZ1bmN0aW9uKCB0YXJnZXQsIGVscyApIHtcblx0XHRcdHB1c2hfbmF0aXZlLmFwcGx5KCB0YXJnZXQsIHNsaWNlLmNhbGwoZWxzKSApO1xuXHRcdH0gOlxuXG5cdFx0Ly8gU3VwcG9ydDogSUU8OVxuXHRcdC8vIE90aGVyd2lzZSBhcHBlbmQgZGlyZWN0bHlcblx0XHRmdW5jdGlvbiggdGFyZ2V0LCBlbHMgKSB7XG5cdFx0XHR2YXIgaiA9IHRhcmdldC5sZW5ndGgsXG5cdFx0XHRcdGkgPSAwO1xuXHRcdFx0Ly8gQ2FuJ3QgdHJ1c3QgTm9kZUxpc3QubGVuZ3RoXG5cdFx0XHR3aGlsZSAoICh0YXJnZXRbaisrXSA9IGVsc1tpKytdKSApIHt9XG5cdFx0XHR0YXJnZXQubGVuZ3RoID0gaiAtIDE7XG5cdFx0fVxuXHR9O1xufVxuXG5mdW5jdGlvbiBTaXp6bGUoIHNlbGVjdG9yLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICkge1xuXHR2YXIgbWF0Y2gsIGVsZW0sIG0sIG5vZGVUeXBlLFxuXHRcdC8vIFFTQSB2YXJzXG5cdFx0aSwgZ3JvdXBzLCBvbGQsIG5pZCwgbmV3Q29udGV4dCwgbmV3U2VsZWN0b3I7XG5cblx0aWYgKCAoIGNvbnRleHQgPyBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCA6IHByZWZlcnJlZERvYyApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xuXHR9XG5cblx0Y29udGV4dCA9IGNvbnRleHQgfHwgZG9jdW1lbnQ7XG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXHRub2RlVHlwZSA9IGNvbnRleHQubm9kZVR5cGU7XG5cblx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09IFwic3RyaW5nXCIgfHwgIXNlbGVjdG9yIHx8XG5cdFx0bm9kZVR5cGUgIT09IDEgJiYgbm9kZVR5cGUgIT09IDkgJiYgbm9kZVR5cGUgIT09IDExICkge1xuXG5cdFx0cmV0dXJuIHJlc3VsdHM7XG5cdH1cblxuXHRpZiAoICFzZWVkICYmIGRvY3VtZW50SXNIVE1MICkge1xuXG5cdFx0Ly8gVHJ5IHRvIHNob3J0Y3V0IGZpbmQgb3BlcmF0aW9ucyB3aGVuIHBvc3NpYmxlIChlLmcuLCBub3QgdW5kZXIgRG9jdW1lbnRGcmFnbWVudClcblx0XHRpZiAoIG5vZGVUeXBlICE9PSAxMSAmJiAobWF0Y2ggPSBycXVpY2tFeHByLmV4ZWMoIHNlbGVjdG9yICkpICkge1xuXHRcdFx0Ly8gU3BlZWQtdXA6IFNpenpsZShcIiNJRFwiKVxuXHRcdFx0aWYgKCAobSA9IG1hdGNoWzFdKSApIHtcblx0XHRcdFx0aWYgKCBub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0XHRlbGVtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggbSApO1xuXHRcdFx0XHRcdC8vIENoZWNrIHBhcmVudE5vZGUgdG8gY2F0Y2ggd2hlbiBCbGFja2JlcnJ5IDQuNiByZXR1cm5zXG5cdFx0XHRcdFx0Ly8gbm9kZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHRoZSBkb2N1bWVudCAoalF1ZXJ5ICM2OTYzKVxuXHRcdFx0XHRcdGlmICggZWxlbSAmJiBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdFx0XHQvLyBIYW5kbGUgdGhlIGNhc2Ugd2hlcmUgSUUsIE9wZXJhLCBhbmQgV2Via2l0IHJldHVybiBpdGVtc1xuXHRcdFx0XHRcdFx0Ly8gYnkgbmFtZSBpbnN0ZWFkIG9mIElEXG5cdFx0XHRcdFx0XHRpZiAoIGVsZW0uaWQgPT09IG0gKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIENvbnRleHQgaXMgbm90IGEgZG9jdW1lbnRcblx0XHRcdFx0XHRpZiAoIGNvbnRleHQub3duZXJEb2N1bWVudCAmJiAoZWxlbSA9IGNvbnRleHQub3duZXJEb2N1bWVudC5nZXRFbGVtZW50QnlJZCggbSApKSAmJlxuXHRcdFx0XHRcdFx0Y29udGFpbnMoIGNvbnRleHQsIGVsZW0gKSAmJiBlbGVtLmlkID09PSBtICkge1xuXHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gU3BlZWQtdXA6IFNpenpsZShcIlRBR1wiKVxuXHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbMl0gKSB7XG5cdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHNlbGVjdG9yICkgKTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cblx0XHRcdC8vIFNwZWVkLXVwOiBTaXp6bGUoXCIuQ0xBU1NcIilcblx0XHRcdH0gZWxzZSBpZiAoIChtID0gbWF0Y2hbM10pICYmIHN1cHBvcnQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSApIHtcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgY29udGV4dC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lKCBtICkgKTtcblx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gUVNBIHBhdGhcblx0XHRpZiAoIHN1cHBvcnQucXNhICYmICghcmJ1Z2d5UVNBIHx8ICFyYnVnZ3lRU0EudGVzdCggc2VsZWN0b3IgKSkgKSB7XG5cdFx0XHRuaWQgPSBvbGQgPSBleHBhbmRvO1xuXHRcdFx0bmV3Q29udGV4dCA9IGNvbnRleHQ7XG5cdFx0XHRuZXdTZWxlY3RvciA9IG5vZGVUeXBlICE9PSAxICYmIHNlbGVjdG9yO1xuXG5cdFx0XHQvLyBxU0Egd29ya3Mgc3RyYW5nZWx5IG9uIEVsZW1lbnQtcm9vdGVkIHF1ZXJpZXNcblx0XHRcdC8vIFdlIGNhbiB3b3JrIGFyb3VuZCB0aGlzIGJ5IHNwZWNpZnlpbmcgYW4gZXh0cmEgSUQgb24gdGhlIHJvb3Rcblx0XHRcdC8vIGFuZCB3b3JraW5nIHVwIGZyb20gdGhlcmUgKFRoYW5rcyB0byBBbmRyZXcgRHVwb250IGZvciB0aGUgdGVjaG5pcXVlKVxuXHRcdFx0Ly8gSUUgOCBkb2Vzbid0IHdvcmsgb24gb2JqZWN0IGVsZW1lbnRzXG5cdFx0XHRpZiAoIG5vZGVUeXBlID09PSAxICYmIGNvbnRleHQubm9kZU5hbWUudG9Mb3dlckNhc2UoKSAhPT0gXCJvYmplY3RcIiApIHtcblx0XHRcdFx0Z3JvdXBzID0gdG9rZW5pemUoIHNlbGVjdG9yICk7XG5cblx0XHRcdFx0aWYgKCAob2xkID0gY29udGV4dC5nZXRBdHRyaWJ1dGUoXCJpZFwiKSkgKSB7XG5cdFx0XHRcdFx0bmlkID0gb2xkLnJlcGxhY2UoIHJlc2NhcGUsIFwiXFxcXCQmXCIgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjb250ZXh0LnNldEF0dHJpYnV0ZSggXCJpZFwiLCBuaWQgKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRuaWQgPSBcIltpZD0nXCIgKyBuaWQgKyBcIiddIFwiO1xuXG5cdFx0XHRcdGkgPSBncm91cHMubGVuZ3RoO1xuXHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRncm91cHNbaV0gPSBuaWQgKyB0b1NlbGVjdG9yKCBncm91cHNbaV0gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRuZXdDb250ZXh0ID0gcnNpYmxpbmcudGVzdCggc2VsZWN0b3IgKSAmJiB0ZXN0Q29udGV4dCggY29udGV4dC5wYXJlbnROb2RlICkgfHwgY29udGV4dDtcblx0XHRcdFx0bmV3U2VsZWN0b3IgPSBncm91cHMuam9pbihcIixcIik7XG5cdFx0XHR9XG5cblx0XHRcdGlmICggbmV3U2VsZWN0b3IgKSB7XG5cdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cyxcblx0XHRcdFx0XHRcdG5ld0NvbnRleHQucXVlcnlTZWxlY3RvckFsbCggbmV3U2VsZWN0b3IgKVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0cmV0dXJuIHJlc3VsdHM7XG5cdFx0XHRcdH0gY2F0Y2gocXNhRXJyb3IpIHtcblx0XHRcdFx0fSBmaW5hbGx5IHtcblx0XHRcdFx0XHRpZiAoICFvbGQgKSB7XG5cdFx0XHRcdFx0XHRjb250ZXh0LnJlbW92ZUF0dHJpYnV0ZShcImlkXCIpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8vIEFsbCBvdGhlcnNcblx0cmV0dXJuIHNlbGVjdCggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICk7XG59XG5cbi8qKlxuICogQ3JlYXRlIGtleS12YWx1ZSBjYWNoZXMgb2YgbGltaXRlZCBzaXplXG4gKiBAcmV0dXJucyB7RnVuY3Rpb24oc3RyaW5nLCBPYmplY3QpfSBSZXR1cm5zIHRoZSBPYmplY3QgZGF0YSBhZnRlciBzdG9yaW5nIGl0IG9uIGl0c2VsZiB3aXRoXG4gKlx0cHJvcGVydHkgbmFtZSB0aGUgKHNwYWNlLXN1ZmZpeGVkKSBzdHJpbmcgYW5kIChpZiB0aGUgY2FjaGUgaXMgbGFyZ2VyIHRoYW4gRXhwci5jYWNoZUxlbmd0aClcbiAqXHRkZWxldGluZyB0aGUgb2xkZXN0IGVudHJ5XG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZUNhY2hlKCkge1xuXHR2YXIga2V5cyA9IFtdO1xuXG5cdGZ1bmN0aW9uIGNhY2hlKCBrZXksIHZhbHVlICkge1xuXHRcdC8vIFVzZSAoa2V5ICsgXCIgXCIpIHRvIGF2b2lkIGNvbGxpc2lvbiB3aXRoIG5hdGl2ZSBwcm90b3R5cGUgcHJvcGVydGllcyAoc2VlIElzc3VlICMxNTcpXG5cdFx0aWYgKCBrZXlzLnB1c2goIGtleSArIFwiIFwiICkgPiBFeHByLmNhY2hlTGVuZ3RoICkge1xuXHRcdFx0Ly8gT25seSBrZWVwIHRoZSBtb3N0IHJlY2VudCBlbnRyaWVzXG5cdFx0XHRkZWxldGUgY2FjaGVbIGtleXMuc2hpZnQoKSBdO1xuXHRcdH1cblx0XHRyZXR1cm4gKGNhY2hlWyBrZXkgKyBcIiBcIiBdID0gdmFsdWUpO1xuXHR9XG5cdHJldHVybiBjYWNoZTtcbn1cblxuLyoqXG4gKiBNYXJrIGEgZnVuY3Rpb24gZm9yIHNwZWNpYWwgdXNlIGJ5IFNpenpsZVxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gVGhlIGZ1bmN0aW9uIHRvIG1hcmtcbiAqL1xuZnVuY3Rpb24gbWFya0Z1bmN0aW9uKCBmbiApIHtcblx0Zm5bIGV4cGFuZG8gXSA9IHRydWU7XG5cdHJldHVybiBmbjtcbn1cblxuLyoqXG4gKiBTdXBwb3J0IHRlc3RpbmcgdXNpbmcgYW4gZWxlbWVudFxuICogQHBhcmFtIHtGdW5jdGlvbn0gZm4gUGFzc2VkIHRoZSBjcmVhdGVkIGRpdiBhbmQgZXhwZWN0cyBhIGJvb2xlYW4gcmVzdWx0XG4gKi9cbmZ1bmN0aW9uIGFzc2VydCggZm4gKSB7XG5cdHZhciBkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXG5cdHRyeSB7XG5cdFx0cmV0dXJuICEhZm4oIGRpdiApO1xuXHR9IGNhdGNoIChlKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9IGZpbmFsbHkge1xuXHRcdC8vIFJlbW92ZSBmcm9tIGl0cyBwYXJlbnQgYnkgZGVmYXVsdFxuXHRcdGlmICggZGl2LnBhcmVudE5vZGUgKSB7XG5cdFx0XHRkaXYucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggZGl2ICk7XG5cdFx0fVxuXHRcdC8vIHJlbGVhc2UgbWVtb3J5IGluIElFXG5cdFx0ZGl2ID0gbnVsbDtcblx0fVxufVxuXG4vKipcbiAqIEFkZHMgdGhlIHNhbWUgaGFuZGxlciBmb3IgYWxsIG9mIHRoZSBzcGVjaWZpZWQgYXR0cnNcbiAqIEBwYXJhbSB7U3RyaW5nfSBhdHRycyBQaXBlLXNlcGFyYXRlZCBsaXN0IG9mIGF0dHJpYnV0ZXNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGhhbmRsZXIgVGhlIG1ldGhvZCB0aGF0IHdpbGwgYmUgYXBwbGllZFxuICovXG5mdW5jdGlvbiBhZGRIYW5kbGUoIGF0dHJzLCBoYW5kbGVyICkge1xuXHR2YXIgYXJyID0gYXR0cnMuc3BsaXQoXCJ8XCIpLFxuXHRcdGkgPSBhdHRycy5sZW5ndGg7XG5cblx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0RXhwci5hdHRySGFuZGxlWyBhcnJbaV0gXSA9IGhhbmRsZXI7XG5cdH1cbn1cblxuLyoqXG4gKiBDaGVja3MgZG9jdW1lbnQgb3JkZXIgb2YgdHdvIHNpYmxpbmdzXG4gKiBAcGFyYW0ge0VsZW1lbnR9IGFcbiAqIEBwYXJhbSB7RWxlbWVudH0gYlxuICogQHJldHVybnMge051bWJlcn0gUmV0dXJucyBsZXNzIHRoYW4gMCBpZiBhIHByZWNlZGVzIGIsIGdyZWF0ZXIgdGhhbiAwIGlmIGEgZm9sbG93cyBiXG4gKi9cbmZ1bmN0aW9uIHNpYmxpbmdDaGVjayggYSwgYiApIHtcblx0dmFyIGN1ciA9IGIgJiYgYSxcblx0XHRkaWZmID0gY3VyICYmIGEubm9kZVR5cGUgPT09IDEgJiYgYi5ub2RlVHlwZSA9PT0gMSAmJlxuXHRcdFx0KCB+Yi5zb3VyY2VJbmRleCB8fCBNQVhfTkVHQVRJVkUgKSAtXG5cdFx0XHQoIH5hLnNvdXJjZUluZGV4IHx8IE1BWF9ORUdBVElWRSApO1xuXG5cdC8vIFVzZSBJRSBzb3VyY2VJbmRleCBpZiBhdmFpbGFibGUgb24gYm90aCBub2Rlc1xuXHRpZiAoIGRpZmYgKSB7XG5cdFx0cmV0dXJuIGRpZmY7XG5cdH1cblxuXHQvLyBDaGVjayBpZiBiIGZvbGxvd3MgYVxuXHRpZiAoIGN1ciApIHtcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIubmV4dFNpYmxpbmcpICkge1xuXHRcdFx0aWYgKCBjdXIgPT09IGIgKSB7XG5cdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gYSA/IDEgOiAtMTtcbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdG8gdXNlIGluIHBzZXVkb3MgZm9yIGlucHV0IHR5cGVzXG4gKiBAcGFyYW0ge1N0cmluZ30gdHlwZVxuICovXG5mdW5jdGlvbiBjcmVhdGVJbnB1dFBzZXVkbyggdHlwZSApIHtcblx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdHJldHVybiBuYW1lID09PSBcImlucHV0XCIgJiYgZWxlbS50eXBlID09PSB0eXBlO1xuXHR9O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgYnV0dG9uc1xuICogQHBhcmFtIHtTdHJpbmd9IHR5cGVcbiAqL1xuZnVuY3Rpb24gY3JlYXRlQnV0dG9uUHNldWRvKCB0eXBlICkge1xuXHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0dmFyIG5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0cmV0dXJuIChuYW1lID09PSBcImlucHV0XCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIikgJiYgZWxlbS50eXBlID09PSB0eXBlO1xuXHR9O1xufVxuXG4vKipcbiAqIFJldHVybnMgYSBmdW5jdGlvbiB0byB1c2UgaW4gcHNldWRvcyBmb3IgcG9zaXRpb25hbHNcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGZuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oIGZuICkge1xuXHRyZXR1cm4gbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBhcmd1bWVudCApIHtcblx0XHRhcmd1bWVudCA9ICthcmd1bWVudDtcblx0XHRyZXR1cm4gbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWVkLCBtYXRjaGVzICkge1xuXHRcdFx0dmFyIGosXG5cdFx0XHRcdG1hdGNoSW5kZXhlcyA9IGZuKCBbXSwgc2VlZC5sZW5ndGgsIGFyZ3VtZW50ICksXG5cdFx0XHRcdGkgPSBtYXRjaEluZGV4ZXMubGVuZ3RoO1xuXG5cdFx0XHQvLyBNYXRjaCBlbGVtZW50cyBmb3VuZCBhdCB0aGUgc3BlY2lmaWVkIGluZGV4ZXNcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRpZiAoIHNlZWRbIChqID0gbWF0Y2hJbmRleGVzW2ldKSBdICkge1xuXHRcdFx0XHRcdHNlZWRbal0gPSAhKG1hdGNoZXNbal0gPSBzZWVkW2pdKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pO1xuXHR9KTtcbn1cblxuLyoqXG4gKiBDaGVja3MgYSBub2RlIGZvciB2YWxpZGl0eSBhcyBhIFNpenpsZSBjb250ZXh0XG4gKiBAcGFyYW0ge0VsZW1lbnR8T2JqZWN0PX0gY29udGV4dFxuICogQHJldHVybnMge0VsZW1lbnR8T2JqZWN0fEJvb2xlYW59IFRoZSBpbnB1dCBub2RlIGlmIGFjY2VwdGFibGUsIG90aGVyd2lzZSBhIGZhbHN5IHZhbHVlXG4gKi9cbmZ1bmN0aW9uIHRlc3RDb250ZXh0KCBjb250ZXh0ICkge1xuXHRyZXR1cm4gY29udGV4dCAmJiB0eXBlb2YgY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBjb250ZXh0O1xufVxuXG4vLyBFeHBvc2Ugc3VwcG9ydCB2YXJzIGZvciBjb252ZW5pZW5jZVxuc3VwcG9ydCA9IFNpenpsZS5zdXBwb3J0ID0ge307XG5cbi8qKlxuICogRGV0ZWN0cyBYTUwgbm9kZXNcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IGVsZW0gQW4gZWxlbWVudCBvciBhIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7Qm9vbGVhbn0gVHJ1ZSBpZmYgZWxlbSBpcyBhIG5vbi1IVE1MIFhNTCBub2RlXG4gKi9cbmlzWE1MID0gU2l6emxlLmlzWE1MID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdC8vIGRvY3VtZW50RWxlbWVudCBpcyB2ZXJpZmllZCBmb3IgY2FzZXMgd2hlcmUgaXQgZG9lc24ndCB5ZXQgZXhpc3Rcblx0Ly8gKHN1Y2ggYXMgbG9hZGluZyBpZnJhbWVzIGluIElFIC0gIzQ4MzMpXG5cdHZhciBkb2N1bWVudEVsZW1lbnQgPSBlbGVtICYmIChlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSkuZG9jdW1lbnRFbGVtZW50O1xuXHRyZXR1cm4gZG9jdW1lbnRFbGVtZW50ID8gZG9jdW1lbnRFbGVtZW50Lm5vZGVOYW1lICE9PSBcIkhUTUxcIiA6IGZhbHNlO1xufTtcblxuLyoqXG4gKiBTZXRzIGRvY3VtZW50LXJlbGF0ZWQgdmFyaWFibGVzIG9uY2UgYmFzZWQgb24gdGhlIGN1cnJlbnQgZG9jdW1lbnRcbiAqIEBwYXJhbSB7RWxlbWVudHxPYmplY3R9IFtkb2NdIEFuIGVsZW1lbnQgb3IgZG9jdW1lbnQgb2JqZWN0IHRvIHVzZSB0byBzZXQgdGhlIGRvY3VtZW50XG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIHRoZSBjdXJyZW50IGRvY3VtZW50XG4gKi9cbnNldERvY3VtZW50ID0gU2l6emxlLnNldERvY3VtZW50ID0gZnVuY3Rpb24oIG5vZGUgKSB7XG5cdHZhciBoYXNDb21wYXJlLCBwYXJlbnQsXG5cdFx0ZG9jID0gbm9kZSA/IG5vZGUub3duZXJEb2N1bWVudCB8fCBub2RlIDogcHJlZmVycmVkRG9jO1xuXG5cdC8vIElmIG5vIGRvY3VtZW50IGFuZCBkb2N1bWVudEVsZW1lbnQgaXMgYXZhaWxhYmxlLCByZXR1cm5cblx0aWYgKCBkb2MgPT09IGRvY3VtZW50IHx8IGRvYy5ub2RlVHlwZSAhPT0gOSB8fCAhZG9jLmRvY3VtZW50RWxlbWVudCApIHtcblx0XHRyZXR1cm4gZG9jdW1lbnQ7XG5cdH1cblxuXHQvLyBTZXQgb3VyIGRvY3VtZW50XG5cdGRvY3VtZW50ID0gZG9jO1xuXHRkb2NFbGVtID0gZG9jLmRvY3VtZW50RWxlbWVudDtcblx0cGFyZW50ID0gZG9jLmRlZmF1bHRWaWV3O1xuXG5cdC8vIFN1cHBvcnQ6IElFPjhcblx0Ly8gSWYgaWZyYW1lIGRvY3VtZW50IGlzIGFzc2lnbmVkIHRvIFwiZG9jdW1lbnRcIiB2YXJpYWJsZSBhbmQgaWYgaWZyYW1lIGhhcyBiZWVuIHJlbG9hZGVkLFxuXHQvLyBJRSB3aWxsIHRocm93IFwicGVybWlzc2lvbiBkZW5pZWRcIiBlcnJvciB3aGVuIGFjY2Vzc2luZyBcImRvY3VtZW50XCIgdmFyaWFibGUsIHNlZSBqUXVlcnkgIzEzOTM2XG5cdC8vIElFNi04IGRvIG5vdCBzdXBwb3J0IHRoZSBkZWZhdWx0VmlldyBwcm9wZXJ0eSBzbyBwYXJlbnQgd2lsbCBiZSB1bmRlZmluZWRcblx0aWYgKCBwYXJlbnQgJiYgcGFyZW50ICE9PSBwYXJlbnQudG9wICkge1xuXHRcdC8vIElFMTEgZG9lcyBub3QgaGF2ZSBhdHRhY2hFdmVudCwgc28gYWxsIG11c3Qgc3VmZmVyXG5cdFx0aWYgKCBwYXJlbnQuYWRkRXZlbnRMaXN0ZW5lciApIHtcblx0XHRcdHBhcmVudC5hZGRFdmVudExpc3RlbmVyKCBcInVubG9hZFwiLCB1bmxvYWRIYW5kbGVyLCBmYWxzZSApO1xuXHRcdH0gZWxzZSBpZiAoIHBhcmVudC5hdHRhY2hFdmVudCApIHtcblx0XHRcdHBhcmVudC5hdHRhY2hFdmVudCggXCJvbnVubG9hZFwiLCB1bmxvYWRIYW5kbGVyICk7XG5cdFx0fVxuXHR9XG5cblx0LyogU3VwcG9ydCB0ZXN0c1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cdGRvY3VtZW50SXNIVE1MID0gIWlzWE1MKCBkb2MgKTtcblxuXHQvKiBBdHRyaWJ1dGVzXG5cdC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi9cblxuXHQvLyBTdXBwb3J0OiBJRTw4XG5cdC8vIFZlcmlmeSB0aGF0IGdldEF0dHJpYnV0ZSByZWFsbHkgcmV0dXJucyBhdHRyaWJ1dGVzIGFuZCBub3QgcHJvcGVydGllc1xuXHQvLyAoZXhjZXB0aW5nIElFOCBib29sZWFucylcblx0c3VwcG9ydC5hdHRyaWJ1dGVzID0gYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0ZGl2LmNsYXNzTmFtZSA9IFwiaVwiO1xuXHRcdHJldHVybiAhZGl2LmdldEF0dHJpYnV0ZShcImNsYXNzTmFtZVwiKTtcblx0fSk7XG5cblx0LyogZ2V0RWxlbWVudChzKUJ5KlxuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gQ2hlY2sgaWYgZ2V0RWxlbWVudHNCeVRhZ05hbWUoXCIqXCIpIHJldHVybnMgb25seSBlbGVtZW50c1xuXHRzdXBwb3J0LmdldEVsZW1lbnRzQnlUYWdOYW1lID0gYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0ZGl2LmFwcGVuZENoaWxkKCBkb2MuY3JlYXRlQ29tbWVudChcIlwiKSApO1xuXHRcdHJldHVybiAhZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiKlwiKS5sZW5ndGg7XG5cdH0pO1xuXG5cdC8vIFN1cHBvcnQ6IElFPDlcblx0c3VwcG9ydC5nZXRFbGVtZW50c0J5Q2xhc3NOYW1lID0gcm5hdGl2ZS50ZXN0KCBkb2MuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSApO1xuXG5cdC8vIFN1cHBvcnQ6IElFPDEwXG5cdC8vIENoZWNrIGlmIGdldEVsZW1lbnRCeUlkIHJldHVybnMgZWxlbWVudHMgYnkgbmFtZVxuXHQvLyBUaGUgYnJva2VuIGdldEVsZW1lbnRCeUlkIG1ldGhvZHMgZG9uJ3QgcGljayB1cCBwcm9ncmFtYXRpY2FsbHktc2V0IG5hbWVzLFxuXHQvLyBzbyB1c2UgYSByb3VuZGFib3V0IGdldEVsZW1lbnRzQnlOYW1lIHRlc3Rcblx0c3VwcG9ydC5nZXRCeUlkID0gYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0ZG9jRWxlbS5hcHBlbmRDaGlsZCggZGl2ICkuaWQgPSBleHBhbmRvO1xuXHRcdHJldHVybiAhZG9jLmdldEVsZW1lbnRzQnlOYW1lIHx8ICFkb2MuZ2V0RWxlbWVudHNCeU5hbWUoIGV4cGFuZG8gKS5sZW5ndGg7XG5cdH0pO1xuXG5cdC8vIElEIGZpbmQgYW5kIGZpbHRlclxuXHRpZiAoIHN1cHBvcnQuZ2V0QnlJZCApIHtcblx0XHRFeHByLmZpbmRbXCJJRFwiXSA9IGZ1bmN0aW9uKCBpZCwgY29udGV4dCApIHtcblx0XHRcdGlmICggdHlwZW9mIGNvbnRleHQuZ2V0RWxlbWVudEJ5SWQgIT09IFwidW5kZWZpbmVkXCIgJiYgZG9jdW1lbnRJc0hUTUwgKSB7XG5cdFx0XHRcdHZhciBtID0gY29udGV4dC5nZXRFbGVtZW50QnlJZCggaWQgKTtcblx0XHRcdFx0Ly8gQ2hlY2sgcGFyZW50Tm9kZSB0byBjYXRjaCB3aGVuIEJsYWNrYmVycnkgNC42IHJldHVybnNcblx0XHRcdFx0Ly8gbm9kZXMgdGhhdCBhcmUgbm8gbG9uZ2VyIGluIHRoZSBkb2N1bWVudCAjNjk2M1xuXHRcdFx0XHRyZXR1cm4gbSAmJiBtLnBhcmVudE5vZGUgPyBbIG0gXSA6IFtdO1xuXHRcdFx0fVxuXHRcdH07XG5cdFx0RXhwci5maWx0ZXJbXCJJRFwiXSA9IGZ1bmN0aW9uKCBpZCApIHtcblx0XHRcdHZhciBhdHRySWQgPSBpZC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoXCJpZFwiKSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXHR9IGVsc2Uge1xuXHRcdC8vIFN1cHBvcnQ6IElFNi83XG5cdFx0Ly8gZ2V0RWxlbWVudEJ5SWQgaXMgbm90IHJlbGlhYmxlIGFzIGEgZmluZCBzaG9ydGN1dFxuXHRcdGRlbGV0ZSBFeHByLmZpbmRbXCJJRFwiXTtcblxuXHRcdEV4cHIuZmlsdGVyW1wiSURcIl0gPSAgZnVuY3Rpb24oIGlkICkge1xuXHRcdFx0dmFyIGF0dHJJZCA9IGlkLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICk7XG5cdFx0XHRyZXR1cm4gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciBub2RlID0gdHlwZW9mIGVsZW0uZ2V0QXR0cmlidXRlTm9kZSAhPT0gXCJ1bmRlZmluZWRcIiAmJiBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoXCJpZFwiKTtcblx0XHRcdFx0cmV0dXJuIG5vZGUgJiYgbm9kZS52YWx1ZSA9PT0gYXR0cklkO1xuXHRcdFx0fTtcblx0XHR9O1xuXHR9XG5cblx0Ly8gVGFnXG5cdEV4cHIuZmluZFtcIlRBR1wiXSA9IHN1cHBvcnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUgP1xuXHRcdGZ1bmN0aW9uKCB0YWcsIGNvbnRleHQgKSB7XG5cdFx0XHRpZiAoIHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBcInVuZGVmaW5lZFwiICkge1xuXHRcdFx0XHRyZXR1cm4gY29udGV4dC5nZXRFbGVtZW50c0J5VGFnTmFtZSggdGFnICk7XG5cblx0XHRcdC8vIERvY3VtZW50RnJhZ21lbnQgbm9kZXMgZG9uJ3QgaGF2ZSBnRUJUTlxuXHRcdFx0fSBlbHNlIGlmICggc3VwcG9ydC5xc2EgKSB7XG5cdFx0XHRcdHJldHVybiBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIHRhZyApO1xuXHRcdFx0fVxuXHRcdH0gOlxuXG5cdFx0ZnVuY3Rpb24oIHRhZywgY29udGV4dCApIHtcblx0XHRcdHZhciBlbGVtLFxuXHRcdFx0XHR0bXAgPSBbXSxcblx0XHRcdFx0aSA9IDAsXG5cdFx0XHRcdC8vIEJ5IGhhcHB5IGNvaW5jaWRlbmNlLCBhIChicm9rZW4pIGdFQlROIGFwcGVhcnMgb24gRG9jdW1lbnRGcmFnbWVudCBub2RlcyB0b29cblx0XHRcdFx0cmVzdWx0cyA9IGNvbnRleHQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIHRhZyApO1xuXG5cdFx0XHQvLyBGaWx0ZXIgb3V0IHBvc3NpYmxlIGNvbW1lbnRzXG5cdFx0XHRpZiAoIHRhZyA9PT0gXCIqXCIgKSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSByZXN1bHRzW2krK10pICkge1xuXHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdHRtcC5wdXNoKCBlbGVtICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0cmV0dXJuIHRtcDtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdH07XG5cblx0Ly8gQ2xhc3Ncblx0RXhwci5maW5kW1wiQ0xBU1NcIl0gPSBzdXBwb3J0LmdldEVsZW1lbnRzQnlDbGFzc05hbWUgJiYgZnVuY3Rpb24oIGNsYXNzTmFtZSwgY29udGV4dCApIHtcblx0XHRpZiAoIGRvY3VtZW50SXNIVE1MICkge1xuXHRcdFx0cmV0dXJuIGNvbnRleHQuZ2V0RWxlbWVudHNCeUNsYXNzTmFtZSggY2xhc3NOYW1lICk7XG5cdFx0fVxuXHR9O1xuXG5cdC8qIFFTQS9tYXRjaGVzU2VsZWN0b3Jcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXG5cdC8vIFFTQSBhbmQgbWF0Y2hlc1NlbGVjdG9yIHN1cHBvcnRcblxuXHQvLyBtYXRjaGVzU2VsZWN0b3IoOmFjdGl2ZSkgcmVwb3J0cyBmYWxzZSB3aGVuIHRydWUgKElFOS9PcGVyYSAxMS41KVxuXHRyYnVnZ3lNYXRjaGVzID0gW107XG5cblx0Ly8gcVNhKDpmb2N1cykgcmVwb3J0cyBmYWxzZSB3aGVuIHRydWUgKENocm9tZSAyMSlcblx0Ly8gV2UgYWxsb3cgdGhpcyBiZWNhdXNlIG9mIGEgYnVnIGluIElFOC85IHRoYXQgdGhyb3dzIGFuIGVycm9yXG5cdC8vIHdoZW5ldmVyIGBkb2N1bWVudC5hY3RpdmVFbGVtZW50YCBpcyBhY2Nlc3NlZCBvbiBhbiBpZnJhbWVcblx0Ly8gU28sIHdlIGFsbG93IDpmb2N1cyB0byBwYXNzIHRocm91Z2ggUVNBIGFsbCB0aGUgdGltZSB0byBhdm9pZCB0aGUgSUUgZXJyb3Jcblx0Ly8gU2VlIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEzMzc4XG5cdHJidWdneVFTQSA9IFtdO1xuXG5cdGlmICggKHN1cHBvcnQucXNhID0gcm5hdGl2ZS50ZXN0KCBkb2MucXVlcnlTZWxlY3RvckFsbCApKSApIHtcblx0XHQvLyBCdWlsZCBRU0EgcmVnZXhcblx0XHQvLyBSZWdleCBzdHJhdGVneSBhZG9wdGVkIGZyb20gRGllZ28gUGVyaW5pXG5cdFx0YXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0XHQvLyBTZWxlY3QgaXMgc2V0IHRvIGVtcHR5IHN0cmluZyBvbiBwdXJwb3NlXG5cdFx0XHQvLyBUaGlzIGlzIHRvIHRlc3QgSUUncyB0cmVhdG1lbnQgb2Ygbm90IGV4cGxpY2l0bHlcblx0XHRcdC8vIHNldHRpbmcgYSBib29sZWFuIGNvbnRlbnQgYXR0cmlidXRlLFxuXHRcdFx0Ly8gc2luY2UgaXRzIHByZXNlbmNlIHNob3VsZCBiZSBlbm91Z2hcblx0XHRcdC8vIGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEyMzU5XG5cdFx0XHRkb2NFbGVtLmFwcGVuZENoaWxkKCBkaXYgKS5pbm5lckhUTUwgPSBcIjxhIGlkPSdcIiArIGV4cGFuZG8gKyBcIic+PC9hPlwiICtcblx0XHRcdFx0XCI8c2VsZWN0IGlkPSdcIiArIGV4cGFuZG8gKyBcIi1cXGZdJyBtc2FsbG93Y2FwdHVyZT0nJz5cIiArXG5cdFx0XHRcdFwiPG9wdGlvbiBzZWxlY3RlZD0nJz48L29wdGlvbj48L3NlbGVjdD5cIjtcblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4LCBPcGVyYSAxMS0xMi4xNlxuXHRcdFx0Ly8gTm90aGluZyBzaG91bGQgYmUgc2VsZWN0ZWQgd2hlbiBlbXB0eSBzdHJpbmdzIGZvbGxvdyBePSBvciAkPSBvciAqPVxuXHRcdFx0Ly8gVGhlIHRlc3QgYXR0cmlidXRlIG11c3QgYmUgdW5rbm93biBpbiBPcGVyYSBidXQgXCJzYWZlXCIgZm9yIFdpblJUXG5cdFx0XHQvLyBodHRwOi8vbXNkbi5taWNyb3NvZnQuY29tL2VuLXVzL2xpYnJhcnkvaWUvaGg0NjUzODguYXNweCNhdHRyaWJ1dGVfc2VjdGlvblxuXHRcdFx0aWYgKCBkaXYucXVlcnlTZWxlY3RvckFsbChcIlttc2FsbG93Y2FwdHVyZV49JyddXCIpLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwiWypeJF09XCIgKyB3aGl0ZXNwYWNlICsgXCIqKD86Jyd8XFxcIlxcXCIpXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gU3VwcG9ydDogSUU4XG5cdFx0XHQvLyBCb29sZWFuIGF0dHJpYnV0ZXMgYW5kIFwidmFsdWVcIiBhcmUgbm90IHRyZWF0ZWQgY29ycmVjdGx5XG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbChcIltzZWxlY3RlZF1cIikubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCJcXFxcW1wiICsgd2hpdGVzcGFjZSArIFwiKig/OnZhbHVlfFwiICsgYm9vbGVhbnMgKyBcIilcIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdXBwb3J0OiBDaHJvbWU8MjksIEFuZHJvaWQ8NC4yKywgU2FmYXJpPDcuMCssIGlPUzw3LjArLCBQaGFudG9tSlM8MS45LjcrXG5cdFx0XHRpZiAoICFkaXYucXVlcnlTZWxlY3RvckFsbCggXCJbaWR+PVwiICsgZXhwYW5kbyArIFwiLV1cIiApLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goXCJ+PVwiKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gV2Via2l0L09wZXJhIC0gOmNoZWNrZWQgc2hvdWxkIHJldHVybiBzZWxlY3RlZCBvcHRpb24gZWxlbWVudHNcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXG5cdFx0XHQvLyBJRTggdGhyb3dzIGVycm9yIGhlcmUgYW5kIHdpbGwgbm90IHNlZSBsYXRlciB0ZXN0c1xuXHRcdFx0aWYgKCAhZGl2LnF1ZXJ5U2VsZWN0b3JBbGwoXCI6Y2hlY2tlZFwiKS5sZW5ndGggKSB7XG5cdFx0XHRcdHJidWdneVFTQS5wdXNoKFwiOmNoZWNrZWRcIik7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFN1cHBvcnQ6IFNhZmFyaSA4KywgaU9TIDgrXG5cdFx0XHQvLyBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTM2ODUxXG5cdFx0XHQvLyBJbi1wYWdlIGBzZWxlY3RvciNpZCBzaWJpbmctY29tYmluYXRvciBzZWxlY3RvcmAgZmFpbHNcblx0XHRcdGlmICggIWRpdi5xdWVyeVNlbGVjdG9yQWxsKCBcImEjXCIgKyBleHBhbmRvICsgXCIrKlwiICkubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaChcIi4jLitbK35dXCIpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXG5cdFx0YXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdFx0XHQvLyBTdXBwb3J0OiBXaW5kb3dzIDggTmF0aXZlIEFwcHNcblx0XHRcdC8vIFRoZSB0eXBlIGFuZCBuYW1lIGF0dHJpYnV0ZXMgYXJlIHJlc3RyaWN0ZWQgZHVyaW5nIC5pbm5lckhUTUwgYXNzaWdubWVudFxuXHRcdFx0dmFyIGlucHV0ID0gZG9jLmNyZWF0ZUVsZW1lbnQoXCJpbnB1dFwiKTtcblx0XHRcdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIFwiaGlkZGVuXCIgKTtcblx0XHRcdGRpdi5hcHBlbmRDaGlsZCggaW5wdXQgKS5zZXRBdHRyaWJ1dGUoIFwibmFtZVwiLCBcIkRcIiApO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBJRThcblx0XHRcdC8vIEVuZm9yY2UgY2FzZS1zZW5zaXRpdml0eSBvZiBuYW1lIGF0dHJpYnV0ZVxuXHRcdFx0aWYgKCBkaXYucXVlcnlTZWxlY3RvckFsbChcIltuYW1lPWRdXCIpLmxlbmd0aCApIHtcblx0XHRcdFx0cmJ1Z2d5UVNBLnB1c2goIFwibmFtZVwiICsgd2hpdGVzcGFjZSArIFwiKlsqXiR8IX5dPz1cIiApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBGRiAzLjUgLSA6ZW5hYmxlZC86ZGlzYWJsZWQgYW5kIGhpZGRlbiBlbGVtZW50cyAoaGlkZGVuIGVsZW1lbnRzIGFyZSBzdGlsbCBlbmFibGVkKVxuXHRcdFx0Ly8gSUU4IHRocm93cyBlcnJvciBoZXJlIGFuZCB3aWxsIG5vdCBzZWUgbGF0ZXIgdGVzdHNcblx0XHRcdGlmICggIWRpdi5xdWVyeVNlbGVjdG9yQWxsKFwiOmVuYWJsZWRcIikubGVuZ3RoICkge1xuXHRcdFx0XHRyYnVnZ3lRU0EucHVzaCggXCI6ZW5hYmxlZFwiLCBcIjpkaXNhYmxlZFwiICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIE9wZXJhIDEwLTExIGRvZXMgbm90IHRocm93IG9uIHBvc3QtY29tbWEgaW52YWxpZCBwc2V1ZG9zXG5cdFx0XHRkaXYucXVlcnlTZWxlY3RvckFsbChcIiosOnhcIik7XG5cdFx0XHRyYnVnZ3lRU0EucHVzaChcIiwuKjpcIik7XG5cdFx0fSk7XG5cdH1cblxuXHRpZiAoIChzdXBwb3J0Lm1hdGNoZXNTZWxlY3RvciA9IHJuYXRpdmUudGVzdCggKG1hdGNoZXMgPSBkb2NFbGVtLm1hdGNoZXMgfHxcblx0XHRkb2NFbGVtLndlYmtpdE1hdGNoZXNTZWxlY3RvciB8fFxuXHRcdGRvY0VsZW0ubW96TWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5vTWF0Y2hlc1NlbGVjdG9yIHx8XG5cdFx0ZG9jRWxlbS5tc01hdGNoZXNTZWxlY3RvcikgKSkgKSB7XG5cblx0XHRhc3NlcnQoZnVuY3Rpb24oIGRpdiApIHtcblx0XHRcdC8vIENoZWNrIHRvIHNlZSBpZiBpdCdzIHBvc3NpYmxlIHRvIGRvIG1hdGNoZXNTZWxlY3RvclxuXHRcdFx0Ly8gb24gYSBkaXNjb25uZWN0ZWQgbm9kZSAoSUUgOSlcblx0XHRcdHN1cHBvcnQuZGlzY29ubmVjdGVkTWF0Y2ggPSBtYXRjaGVzLmNhbGwoIGRpdiwgXCJkaXZcIiApO1xuXG5cdFx0XHQvLyBUaGlzIHNob3VsZCBmYWlsIHdpdGggYW4gZXhjZXB0aW9uXG5cdFx0XHQvLyBHZWNrbyBkb2VzIG5vdCBlcnJvciwgcmV0dXJucyBmYWxzZSBpbnN0ZWFkXG5cdFx0XHRtYXRjaGVzLmNhbGwoIGRpdiwgXCJbcyE9JyddOnhcIiApO1xuXHRcdFx0cmJ1Z2d5TWF0Y2hlcy5wdXNoKCBcIiE9XCIsIHBzZXVkb3MgKTtcblx0XHR9KTtcblx0fVxuXG5cdHJidWdneVFTQSA9IHJidWdneVFTQS5sZW5ndGggJiYgbmV3IFJlZ0V4cCggcmJ1Z2d5UVNBLmpvaW4oXCJ8XCIpICk7XG5cdHJidWdneU1hdGNoZXMgPSByYnVnZ3lNYXRjaGVzLmxlbmd0aCAmJiBuZXcgUmVnRXhwKCByYnVnZ3lNYXRjaGVzLmpvaW4oXCJ8XCIpICk7XG5cblx0LyogQ29udGFpbnNcblx0LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqL1xuXHRoYXNDb21wYXJlID0gcm5hdGl2ZS50ZXN0KCBkb2NFbGVtLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uICk7XG5cblx0Ly8gRWxlbWVudCBjb250YWlucyBhbm90aGVyXG5cdC8vIFB1cnBvc2VmdWxseSBkb2VzIG5vdCBpbXBsZW1lbnQgaW5jbHVzaXZlIGRlc2NlbmRlbnRcblx0Ly8gQXMgaW4sIGFuIGVsZW1lbnQgZG9lcyBub3QgY29udGFpbiBpdHNlbGZcblx0Y29udGFpbnMgPSBoYXNDb21wYXJlIHx8IHJuYXRpdmUudGVzdCggZG9jRWxlbS5jb250YWlucyApID9cblx0XHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHRcdHZhciBhZG93biA9IGEubm9kZVR5cGUgPT09IDkgPyBhLmRvY3VtZW50RWxlbWVudCA6IGEsXG5cdFx0XHRcdGJ1cCA9IGIgJiYgYi5wYXJlbnROb2RlO1xuXHRcdFx0cmV0dXJuIGEgPT09IGJ1cCB8fCAhISggYnVwICYmIGJ1cC5ub2RlVHlwZSA9PT0gMSAmJiAoXG5cdFx0XHRcdGFkb3duLmNvbnRhaW5zID9cblx0XHRcdFx0XHRhZG93bi5jb250YWlucyggYnVwICkgOlxuXHRcdFx0XHRcdGEuY29tcGFyZURvY3VtZW50UG9zaXRpb24gJiYgYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYnVwICkgJiAxNlxuXHRcdFx0KSk7XG5cdFx0fSA6XG5cdFx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cdFx0XHRpZiAoIGIgKSB7XG5cdFx0XHRcdHdoaWxlICggKGIgPSBiLnBhcmVudE5vZGUpICkge1xuXHRcdFx0XHRcdGlmICggYiA9PT0gYSApIHtcblx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH07XG5cblx0LyogU29ydGluZ1xuXHQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG5cblx0Ly8gRG9jdW1lbnQgb3JkZXIgc29ydGluZ1xuXHRzb3J0T3JkZXIgPSBoYXNDb21wYXJlID9cblx0ZnVuY3Rpb24oIGEsIGIgKSB7XG5cblx0XHQvLyBGbGFnIGZvciBkdXBsaWNhdGUgcmVtb3ZhbFxuXHRcdGlmICggYSA9PT0gYiApIHtcblx0XHRcdGhhc0R1cGxpY2F0ZSA9IHRydWU7XG5cdFx0XHRyZXR1cm4gMDtcblx0XHR9XG5cblx0XHQvLyBTb3J0IG9uIG1ldGhvZCBleGlzdGVuY2UgaWYgb25seSBvbmUgaW5wdXQgaGFzIGNvbXBhcmVEb2N1bWVudFBvc2l0aW9uXG5cdFx0dmFyIGNvbXBhcmUgPSAhYS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiAtICFiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uO1xuXHRcdGlmICggY29tcGFyZSApIHtcblx0XHRcdHJldHVybiBjb21wYXJlO1xuXHRcdH1cblxuXHRcdC8vIENhbGN1bGF0ZSBwb3NpdGlvbiBpZiBib3RoIGlucHV0cyBiZWxvbmcgdG8gdGhlIHNhbWUgZG9jdW1lbnRcblx0XHRjb21wYXJlID0gKCBhLm93bmVyRG9jdW1lbnQgfHwgYSApID09PSAoIGIub3duZXJEb2N1bWVudCB8fCBiICkgP1xuXHRcdFx0YS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggYiApIDpcblxuXHRcdFx0Ly8gT3RoZXJ3aXNlIHdlIGtub3cgdGhleSBhcmUgZGlzY29ubmVjdGVkXG5cdFx0XHQxO1xuXG5cdFx0Ly8gRGlzY29ubmVjdGVkIG5vZGVzXG5cdFx0aWYgKCBjb21wYXJlICYgMSB8fFxuXHRcdFx0KCFzdXBwb3J0LnNvcnREZXRhY2hlZCAmJiBiLmNvbXBhcmVEb2N1bWVudFBvc2l0aW9uKCBhICkgPT09IGNvbXBhcmUpICkge1xuXG5cdFx0XHQvLyBDaG9vc2UgdGhlIGZpcnN0IGVsZW1lbnQgdGhhdCBpcyByZWxhdGVkIHRvIG91ciBwcmVmZXJyZWQgZG9jdW1lbnRcblx0XHRcdGlmICggYSA9PT0gZG9jIHx8IGEub3duZXJEb2N1bWVudCA9PT0gcHJlZmVycmVkRG9jICYmIGNvbnRhaW5zKHByZWZlcnJlZERvYywgYSkgKSB7XG5cdFx0XHRcdHJldHVybiAtMTtcblx0XHRcdH1cblx0XHRcdGlmICggYiA9PT0gZG9jIHx8IGIub3duZXJEb2N1bWVudCA9PT0gcHJlZmVycmVkRG9jICYmIGNvbnRhaW5zKHByZWZlcnJlZERvYywgYikgKSB7XG5cdFx0XHRcdHJldHVybiAxO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBNYWludGFpbiBvcmlnaW5hbCBvcmRlclxuXHRcdFx0cmV0dXJuIHNvcnRJbnB1dCA/XG5cdFx0XHRcdCggaW5kZXhPZiggc29ydElucHV0LCBhICkgLSBpbmRleE9mKCBzb3J0SW5wdXQsIGIgKSApIDpcblx0XHRcdFx0MDtcblx0XHR9XG5cblx0XHRyZXR1cm4gY29tcGFyZSAmIDQgPyAtMSA6IDE7XG5cdH0gOlxuXHRmdW5jdGlvbiggYSwgYiApIHtcblx0XHQvLyBFeGl0IGVhcmx5IGlmIHRoZSBub2RlcyBhcmUgaWRlbnRpY2FsXG5cdFx0aWYgKCBhID09PSBiICkge1xuXHRcdFx0aGFzRHVwbGljYXRlID0gdHJ1ZTtcblx0XHRcdHJldHVybiAwO1xuXHRcdH1cblxuXHRcdHZhciBjdXIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGF1cCA9IGEucGFyZW50Tm9kZSxcblx0XHRcdGJ1cCA9IGIucGFyZW50Tm9kZSxcblx0XHRcdGFwID0gWyBhIF0sXG5cdFx0XHRicCA9IFsgYiBdO1xuXG5cdFx0Ly8gUGFyZW50bGVzcyBub2RlcyBhcmUgZWl0aGVyIGRvY3VtZW50cyBvciBkaXNjb25uZWN0ZWRcblx0XHRpZiAoICFhdXAgfHwgIWJ1cCApIHtcblx0XHRcdHJldHVybiBhID09PSBkb2MgPyAtMSA6XG5cdFx0XHRcdGIgPT09IGRvYyA/IDEgOlxuXHRcdFx0XHRhdXAgPyAtMSA6XG5cdFx0XHRcdGJ1cCA/IDEgOlxuXHRcdFx0XHRzb3J0SW5wdXQgP1xuXHRcdFx0XHQoIGluZGV4T2YoIHNvcnRJbnB1dCwgYSApIC0gaW5kZXhPZiggc29ydElucHV0LCBiICkgKSA6XG5cdFx0XHRcdDA7XG5cblx0XHQvLyBJZiB0aGUgbm9kZXMgYXJlIHNpYmxpbmdzLCB3ZSBjYW4gZG8gYSBxdWljayBjaGVja1xuXHRcdH0gZWxzZSBpZiAoIGF1cCA9PT0gYnVwICkge1xuXHRcdFx0cmV0dXJuIHNpYmxpbmdDaGVjayggYSwgYiApO1xuXHRcdH1cblxuXHRcdC8vIE90aGVyd2lzZSB3ZSBuZWVkIGZ1bGwgbGlzdHMgb2YgdGhlaXIgYW5jZXN0b3JzIGZvciBjb21wYXJpc29uXG5cdFx0Y3VyID0gYTtcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7XG5cdFx0XHRhcC51bnNoaWZ0KCBjdXIgKTtcblx0XHR9XG5cdFx0Y3VyID0gYjtcblx0XHR3aGlsZSAoIChjdXIgPSBjdXIucGFyZW50Tm9kZSkgKSB7XG5cdFx0XHRicC51bnNoaWZ0KCBjdXIgKTtcblx0XHR9XG5cblx0XHQvLyBXYWxrIGRvd24gdGhlIHRyZWUgbG9va2luZyBmb3IgYSBkaXNjcmVwYW5jeVxuXHRcdHdoaWxlICggYXBbaV0gPT09IGJwW2ldICkge1xuXHRcdFx0aSsrO1xuXHRcdH1cblxuXHRcdHJldHVybiBpID9cblx0XHRcdC8vIERvIGEgc2libGluZyBjaGVjayBpZiB0aGUgbm9kZXMgaGF2ZSBhIGNvbW1vbiBhbmNlc3RvclxuXHRcdFx0c2libGluZ0NoZWNrKCBhcFtpXSwgYnBbaV0gKSA6XG5cblx0XHRcdC8vIE90aGVyd2lzZSBub2RlcyBpbiBvdXIgZG9jdW1lbnQgc29ydCBmaXJzdFxuXHRcdFx0YXBbaV0gPT09IHByZWZlcnJlZERvYyA/IC0xIDpcblx0XHRcdGJwW2ldID09PSBwcmVmZXJyZWREb2MgPyAxIDpcblx0XHRcdDA7XG5cdH07XG5cblx0cmV0dXJuIGRvYztcbn07XG5cblNpenpsZS5tYXRjaGVzID0gZnVuY3Rpb24oIGV4cHIsIGVsZW1lbnRzICkge1xuXHRyZXR1cm4gU2l6emxlKCBleHByLCBudWxsLCBudWxsLCBlbGVtZW50cyApO1xufTtcblxuU2l6emxlLm1hdGNoZXNTZWxlY3RvciA9IGZ1bmN0aW9uKCBlbGVtLCBleHByICkge1xuXHQvLyBTZXQgZG9jdW1lbnQgdmFycyBpZiBuZWVkZWRcblx0aWYgKCAoIGVsZW0ub3duZXJEb2N1bWVudCB8fCBlbGVtICkgIT09IGRvY3VtZW50ICkge1xuXHRcdHNldERvY3VtZW50KCBlbGVtICk7XG5cdH1cblxuXHQvLyBNYWtlIHN1cmUgdGhhdCBhdHRyaWJ1dGUgc2VsZWN0b3JzIGFyZSBxdW90ZWRcblx0ZXhwciA9IGV4cHIucmVwbGFjZSggcmF0dHJpYnV0ZVF1b3RlcywgXCI9JyQxJ11cIiApO1xuXG5cdGlmICggc3VwcG9ydC5tYXRjaGVzU2VsZWN0b3IgJiYgZG9jdW1lbnRJc0hUTUwgJiZcblx0XHQoICFyYnVnZ3lNYXRjaGVzIHx8ICFyYnVnZ3lNYXRjaGVzLnRlc3QoIGV4cHIgKSApICYmXG5cdFx0KCAhcmJ1Z2d5UVNBICAgICB8fCAhcmJ1Z2d5UVNBLnRlc3QoIGV4cHIgKSApICkge1xuXG5cdFx0dHJ5IHtcblx0XHRcdHZhciByZXQgPSBtYXRjaGVzLmNhbGwoIGVsZW0sIGV4cHIgKTtcblxuXHRcdFx0Ly8gSUUgOSdzIG1hdGNoZXNTZWxlY3RvciByZXR1cm5zIGZhbHNlIG9uIGRpc2Nvbm5lY3RlZCBub2Rlc1xuXHRcdFx0aWYgKCByZXQgfHwgc3VwcG9ydC5kaXNjb25uZWN0ZWRNYXRjaCB8fFxuXHRcdFx0XHRcdC8vIEFzIHdlbGwsIGRpc2Nvbm5lY3RlZCBub2RlcyBhcmUgc2FpZCB0byBiZSBpbiBhIGRvY3VtZW50XG5cdFx0XHRcdFx0Ly8gZnJhZ21lbnQgaW4gSUUgOVxuXHRcdFx0XHRcdGVsZW0uZG9jdW1lbnQgJiYgZWxlbS5kb2N1bWVudC5ub2RlVHlwZSAhPT0gMTEgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cdFx0XHR9XG5cdFx0fSBjYXRjaCAoZSkge31cblx0fVxuXG5cdHJldHVybiBTaXp6bGUoIGV4cHIsIGRvY3VtZW50LCBudWxsLCBbIGVsZW0gXSApLmxlbmd0aCA+IDA7XG59O1xuXG5TaXp6bGUuY29udGFpbnMgPSBmdW5jdGlvbiggY29udGV4dCwgZWxlbSApIHtcblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXG5cdGlmICggKCBjb250ZXh0Lm93bmVyRG9jdW1lbnQgfHwgY29udGV4dCApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggY29udGV4dCApO1xuXHR9XG5cdHJldHVybiBjb250YWlucyggY29udGV4dCwgZWxlbSApO1xufTtcblxuU2l6emxlLmF0dHIgPSBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0Ly8gU2V0IGRvY3VtZW50IHZhcnMgaWYgbmVlZGVkXG5cdGlmICggKCBlbGVtLm93bmVyRG9jdW1lbnQgfHwgZWxlbSApICE9PSBkb2N1bWVudCApIHtcblx0XHRzZXREb2N1bWVudCggZWxlbSApO1xuXHR9XG5cblx0dmFyIGZuID0gRXhwci5hdHRySGFuZGxlWyBuYW1lLnRvTG93ZXJDYXNlKCkgXSxcblx0XHQvLyBEb24ndCBnZXQgZm9vbGVkIGJ5IE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoalF1ZXJ5ICMxMzgwNylcblx0XHR2YWwgPSBmbiAmJiBoYXNPd24uY2FsbCggRXhwci5hdHRySGFuZGxlLCBuYW1lLnRvTG93ZXJDYXNlKCkgKSA/XG5cdFx0XHRmbiggZWxlbSwgbmFtZSwgIWRvY3VtZW50SXNIVE1MICkgOlxuXHRcdFx0dW5kZWZpbmVkO1xuXG5cdHJldHVybiB2YWwgIT09IHVuZGVmaW5lZCA/XG5cdFx0dmFsIDpcblx0XHRzdXBwb3J0LmF0dHJpYnV0ZXMgfHwgIWRvY3VtZW50SXNIVE1MID9cblx0XHRcdGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lICkgOlxuXHRcdFx0KHZhbCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZShuYW1lKSkgJiYgdmFsLnNwZWNpZmllZCA/XG5cdFx0XHRcdHZhbC52YWx1ZSA6XG5cdFx0XHRcdG51bGw7XG59O1xuXG5TaXp6bGUuZXJyb3IgPSBmdW5jdGlvbiggbXNnICkge1xuXHR0aHJvdyBuZXcgRXJyb3IoIFwiU3ludGF4IGVycm9yLCB1bnJlY29nbml6ZWQgZXhwcmVzc2lvbjogXCIgKyBtc2cgKTtcbn07XG5cbi8qKlxuICogRG9jdW1lbnQgc29ydGluZyBhbmQgcmVtb3ZpbmcgZHVwbGljYXRlc1xuICogQHBhcmFtIHtBcnJheUxpa2V9IHJlc3VsdHNcbiAqL1xuU2l6emxlLnVuaXF1ZVNvcnQgPSBmdW5jdGlvbiggcmVzdWx0cyApIHtcblx0dmFyIGVsZW0sXG5cdFx0ZHVwbGljYXRlcyA9IFtdLFxuXHRcdGogPSAwLFxuXHRcdGkgPSAwO1xuXG5cdC8vIFVubGVzcyB3ZSAqa25vdyogd2UgY2FuIGRldGVjdCBkdXBsaWNhdGVzLCBhc3N1bWUgdGhlaXIgcHJlc2VuY2Vcblx0aGFzRHVwbGljYXRlID0gIXN1cHBvcnQuZGV0ZWN0RHVwbGljYXRlcztcblx0c29ydElucHV0ID0gIXN1cHBvcnQuc29ydFN0YWJsZSAmJiByZXN1bHRzLnNsaWNlKCAwICk7XG5cdHJlc3VsdHMuc29ydCggc29ydE9yZGVyICk7XG5cblx0aWYgKCBoYXNEdXBsaWNhdGUgKSB7XG5cdFx0d2hpbGUgKCAoZWxlbSA9IHJlc3VsdHNbaSsrXSkgKSB7XG5cdFx0XHRpZiAoIGVsZW0gPT09IHJlc3VsdHNbIGkgXSApIHtcblx0XHRcdFx0aiA9IGR1cGxpY2F0ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdH1cblx0XHR3aGlsZSAoIGotLSApIHtcblx0XHRcdHJlc3VsdHMuc3BsaWNlKCBkdXBsaWNhdGVzWyBqIF0sIDEgKTtcblx0XHR9XG5cdH1cblxuXHQvLyBDbGVhciBpbnB1dCBhZnRlciBzb3J0aW5nIHRvIHJlbGVhc2Ugb2JqZWN0c1xuXHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9zaXp6bGUvcHVsbC8yMjVcblx0c29ydElucHV0ID0gbnVsbDtcblxuXHRyZXR1cm4gcmVzdWx0cztcbn07XG5cbi8qKlxuICogVXRpbGl0eSBmdW5jdGlvbiBmb3IgcmV0cmlldmluZyB0aGUgdGV4dCB2YWx1ZSBvZiBhbiBhcnJheSBvZiBET00gbm9kZXNcbiAqIEBwYXJhbSB7QXJyYXl8RWxlbWVudH0gZWxlbVxuICovXG5nZXRUZXh0ID0gU2l6emxlLmdldFRleHQgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0dmFyIG5vZGUsXG5cdFx0cmV0ID0gXCJcIixcblx0XHRpID0gMCxcblx0XHRub2RlVHlwZSA9IGVsZW0ubm9kZVR5cGU7XG5cblx0aWYgKCAhbm9kZVR5cGUgKSB7XG5cdFx0Ly8gSWYgbm8gbm9kZVR5cGUsIHRoaXMgaXMgZXhwZWN0ZWQgdG8gYmUgYW4gYXJyYXlcblx0XHR3aGlsZSAoIChub2RlID0gZWxlbVtpKytdKSApIHtcblx0XHRcdC8vIERvIG5vdCB0cmF2ZXJzZSBjb21tZW50IG5vZGVzXG5cdFx0XHRyZXQgKz0gZ2V0VGV4dCggbm9kZSApO1xuXHRcdH1cblx0fSBlbHNlIGlmICggbm9kZVR5cGUgPT09IDEgfHwgbm9kZVR5cGUgPT09IDkgfHwgbm9kZVR5cGUgPT09IDExICkge1xuXHRcdC8vIFVzZSB0ZXh0Q29udGVudCBmb3IgZWxlbWVudHNcblx0XHQvLyBpbm5lclRleHQgdXNhZ2UgcmVtb3ZlZCBmb3IgY29uc2lzdGVuY3kgb2YgbmV3IGxpbmVzIChqUXVlcnkgIzExMTUzKVxuXHRcdGlmICggdHlwZW9mIGVsZW0udGV4dENvbnRlbnQgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS50ZXh0Q29udGVudDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gVHJhdmVyc2UgaXRzIGNoaWxkcmVuXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcblx0XHRcdFx0cmV0ICs9IGdldFRleHQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSBpZiAoIG5vZGVUeXBlID09PSAzIHx8IG5vZGVUeXBlID09PSA0ICkge1xuXHRcdHJldHVybiBlbGVtLm5vZGVWYWx1ZTtcblx0fVxuXHQvLyBEbyBub3QgaW5jbHVkZSBjb21tZW50IG9yIHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb24gbm9kZXNcblxuXHRyZXR1cm4gcmV0O1xufTtcblxuRXhwciA9IFNpenpsZS5zZWxlY3RvcnMgPSB7XG5cblx0Ly8gQ2FuIGJlIGFkanVzdGVkIGJ5IHRoZSB1c2VyXG5cdGNhY2hlTGVuZ3RoOiA1MCxcblxuXHRjcmVhdGVQc2V1ZG86IG1hcmtGdW5jdGlvbixcblxuXHRtYXRjaDogbWF0Y2hFeHByLFxuXG5cdGF0dHJIYW5kbGU6IHt9LFxuXG5cdGZpbmQ6IHt9LFxuXG5cdHJlbGF0aXZlOiB7XG5cdFx0XCI+XCI6IHsgZGlyOiBcInBhcmVudE5vZGVcIiwgZmlyc3Q6IHRydWUgfSxcblx0XHRcIiBcIjogeyBkaXI6IFwicGFyZW50Tm9kZVwiIH0sXG5cdFx0XCIrXCI6IHsgZGlyOiBcInByZXZpb3VzU2libGluZ1wiLCBmaXJzdDogdHJ1ZSB9LFxuXHRcdFwiflwiOiB7IGRpcjogXCJwcmV2aW91c1NpYmxpbmdcIiB9XG5cdH0sXG5cblx0cHJlRmlsdGVyOiB7XG5cdFx0XCJBVFRSXCI6IGZ1bmN0aW9uKCBtYXRjaCApIHtcblx0XHRcdG1hdGNoWzFdID0gbWF0Y2hbMV0ucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0Ly8gTW92ZSB0aGUgZ2l2ZW4gdmFsdWUgdG8gbWF0Y2hbM10gd2hldGhlciBxdW90ZWQgb3IgdW5xdW90ZWRcblx0XHRcdG1hdGNoWzNdID0gKCBtYXRjaFszXSB8fCBtYXRjaFs0XSB8fCBtYXRjaFs1XSB8fCBcIlwiICkucmVwbGFjZSggcnVuZXNjYXBlLCBmdW5lc2NhcGUgKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsyXSA9PT0gXCJ+PVwiICkge1xuXHRcdFx0XHRtYXRjaFszXSA9IFwiIFwiICsgbWF0Y2hbM10gKyBcIiBcIjtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCA0ICk7XG5cdFx0fSxcblxuXHRcdFwiQ0hJTERcIjogZnVuY3Rpb24oIG1hdGNoICkge1xuXHRcdFx0LyogbWF0Y2hlcyBmcm9tIG1hdGNoRXhwcltcIkNISUxEXCJdXG5cdFx0XHRcdDEgdHlwZSAob25seXxudGh8Li4uKVxuXHRcdFx0XHQyIHdoYXQgKGNoaWxkfG9mLXR5cGUpXG5cdFx0XHRcdDMgYXJndW1lbnQgKGV2ZW58b2RkfFxcZCp8XFxkKm4oWystXVxcZCspP3wuLi4pXG5cdFx0XHRcdDQgeG4tY29tcG9uZW50IG9mIHhuK3kgYXJndW1lbnQgKFsrLV0/XFxkKm58KVxuXHRcdFx0XHQ1IHNpZ24gb2YgeG4tY29tcG9uZW50XG5cdFx0XHRcdDYgeCBvZiB4bi1jb21wb25lbnRcblx0XHRcdFx0NyBzaWduIG9mIHktY29tcG9uZW50XG5cdFx0XHRcdDggeSBvZiB5LWNvbXBvbmVudFxuXHRcdFx0Ki9cblx0XHRcdG1hdGNoWzFdID0gbWF0Y2hbMV0udG9Mb3dlckNhc2UoKTtcblxuXHRcdFx0aWYgKCBtYXRjaFsxXS5zbGljZSggMCwgMyApID09PSBcIm50aFwiICkge1xuXHRcdFx0XHQvLyBudGgtKiByZXF1aXJlcyBhcmd1bWVudFxuXHRcdFx0XHRpZiAoICFtYXRjaFszXSApIHtcblx0XHRcdFx0XHRTaXp6bGUuZXJyb3IoIG1hdGNoWzBdICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBudW1lcmljIHggYW5kIHkgcGFyYW1ldGVycyBmb3IgRXhwci5maWx0ZXIuQ0hJTERcblx0XHRcdFx0Ly8gcmVtZW1iZXIgdGhhdCBmYWxzZS90cnVlIGNhc3QgcmVzcGVjdGl2ZWx5IHRvIDAvMVxuXHRcdFx0XHRtYXRjaFs0XSA9ICsoIG1hdGNoWzRdID8gbWF0Y2hbNV0gKyAobWF0Y2hbNl0gfHwgMSkgOiAyICogKCBtYXRjaFszXSA9PT0gXCJldmVuXCIgfHwgbWF0Y2hbM10gPT09IFwib2RkXCIgKSApO1xuXHRcdFx0XHRtYXRjaFs1XSA9ICsoICggbWF0Y2hbN10gKyBtYXRjaFs4XSApIHx8IG1hdGNoWzNdID09PSBcIm9kZFwiICk7XG5cblx0XHRcdC8vIG90aGVyIHR5cGVzIHByb2hpYml0IGFyZ3VtZW50c1xuXHRcdFx0fSBlbHNlIGlmICggbWF0Y2hbM10gKSB7XG5cdFx0XHRcdFNpenpsZS5lcnJvciggbWF0Y2hbMF0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIG1hdGNoO1xuXHRcdH0sXG5cblx0XHRcIlBTRVVET1wiOiBmdW5jdGlvbiggbWF0Y2ggKSB7XG5cdFx0XHR2YXIgZXhjZXNzLFxuXHRcdFx0XHR1bnF1b3RlZCA9ICFtYXRjaFs2XSAmJiBtYXRjaFsyXTtcblxuXHRcdFx0aWYgKCBtYXRjaEV4cHJbXCJDSElMRFwiXS50ZXN0KCBtYXRjaFswXSApICkge1xuXHRcdFx0XHRyZXR1cm4gbnVsbDtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWNjZXB0IHF1b3RlZCBhcmd1bWVudHMgYXMtaXNcblx0XHRcdGlmICggbWF0Y2hbM10gKSB7XG5cdFx0XHRcdG1hdGNoWzJdID0gbWF0Y2hbNF0gfHwgbWF0Y2hbNV0gfHwgXCJcIjtcblxuXHRcdFx0Ly8gU3RyaXAgZXhjZXNzIGNoYXJhY3RlcnMgZnJvbSB1bnF1b3RlZCBhcmd1bWVudHNcblx0XHRcdH0gZWxzZSBpZiAoIHVucXVvdGVkICYmIHJwc2V1ZG8udGVzdCggdW5xdW90ZWQgKSAmJlxuXHRcdFx0XHQvLyBHZXQgZXhjZXNzIGZyb20gdG9rZW5pemUgKHJlY3Vyc2l2ZWx5KVxuXHRcdFx0XHQoZXhjZXNzID0gdG9rZW5pemUoIHVucXVvdGVkLCB0cnVlICkpICYmXG5cdFx0XHRcdC8vIGFkdmFuY2UgdG8gdGhlIG5leHQgY2xvc2luZyBwYXJlbnRoZXNpc1xuXHRcdFx0XHQoZXhjZXNzID0gdW5xdW90ZWQuaW5kZXhPZiggXCIpXCIsIHVucXVvdGVkLmxlbmd0aCAtIGV4Y2VzcyApIC0gdW5xdW90ZWQubGVuZ3RoKSApIHtcblxuXHRcdFx0XHQvLyBleGNlc3MgaXMgYSBuZWdhdGl2ZSBpbmRleFxuXHRcdFx0XHRtYXRjaFswXSA9IG1hdGNoWzBdLnNsaWNlKCAwLCBleGNlc3MgKTtcblx0XHRcdFx0bWF0Y2hbMl0gPSB1bnF1b3RlZC5zbGljZSggMCwgZXhjZXNzICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJldHVybiBvbmx5IGNhcHR1cmVzIG5lZWRlZCBieSB0aGUgcHNldWRvIGZpbHRlciBtZXRob2QgKHR5cGUgYW5kIGFyZ3VtZW50KVxuXHRcdFx0cmV0dXJuIG1hdGNoLnNsaWNlKCAwLCAzICk7XG5cdFx0fVxuXHR9LFxuXG5cdGZpbHRlcjoge1xuXG5cdFx0XCJUQUdcIjogZnVuY3Rpb24oIG5vZGVOYW1lU2VsZWN0b3IgKSB7XG5cdFx0XHR2YXIgbm9kZU5hbWUgPSBub2RlTmFtZVNlbGVjdG9yLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBub2RlTmFtZVNlbGVjdG9yID09PSBcIipcIiA/XG5cdFx0XHRcdGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiBlbGVtLm5vZGVOYW1lICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbm9kZU5hbWU7XG5cdFx0XHRcdH07XG5cdFx0fSxcblxuXHRcdFwiQ0xBU1NcIjogZnVuY3Rpb24oIGNsYXNzTmFtZSApIHtcblx0XHRcdHZhciBwYXR0ZXJuID0gY2xhc3NDYWNoZVsgY2xhc3NOYW1lICsgXCIgXCIgXTtcblxuXHRcdFx0cmV0dXJuIHBhdHRlcm4gfHxcblx0XHRcdFx0KHBhdHRlcm4gPSBuZXcgUmVnRXhwKCBcIihefFwiICsgd2hpdGVzcGFjZSArIFwiKVwiICsgY2xhc3NOYW1lICsgXCIoXCIgKyB3aGl0ZXNwYWNlICsgXCJ8JClcIiApKSAmJlxuXHRcdFx0XHRjbGFzc0NhY2hlKCBjbGFzc05hbWUsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdHJldHVybiBwYXR0ZXJuLnRlc3QoIHR5cGVvZiBlbGVtLmNsYXNzTmFtZSA9PT0gXCJzdHJpbmdcIiAmJiBlbGVtLmNsYXNzTmFtZSB8fCB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgIT09IFwidW5kZWZpbmVkXCIgJiYgZWxlbS5nZXRBdHRyaWJ1dGUoXCJjbGFzc1wiKSB8fCBcIlwiICk7XG5cdFx0XHRcdH0pO1xuXHRcdH0sXG5cblx0XHRcIkFUVFJcIjogZnVuY3Rpb24oIG5hbWUsIG9wZXJhdG9yLCBjaGVjayApIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIHJlc3VsdCA9IFNpenpsZS5hdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHRcdFx0aWYgKCByZXN1bHQgPT0gbnVsbCApIHtcblx0XHRcdFx0XHRyZXR1cm4gb3BlcmF0b3IgPT09IFwiIT1cIjtcblx0XHRcdFx0fVxuXHRcdFx0XHRpZiAoICFvcGVyYXRvciApIHtcblx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJlc3VsdCArPSBcIlwiO1xuXG5cdFx0XHRcdHJldHVybiBvcGVyYXRvciA9PT0gXCI9XCIgPyByZXN1bHQgPT09IGNoZWNrIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIhPVwiID8gcmVzdWx0ICE9PSBjaGVjayA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiXj1cIiA/IGNoZWNrICYmIHJlc3VsdC5pbmRleE9mKCBjaGVjayApID09PSAwIDpcblx0XHRcdFx0XHRvcGVyYXRvciA9PT0gXCIqPVwiID8gY2hlY2sgJiYgcmVzdWx0LmluZGV4T2YoIGNoZWNrICkgPiAtMSA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwiJD1cIiA/IGNoZWNrICYmIHJlc3VsdC5zbGljZSggLWNoZWNrLmxlbmd0aCApID09PSBjaGVjayA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwifj1cIiA/ICggXCIgXCIgKyByZXN1bHQucmVwbGFjZSggcndoaXRlc3BhY2UsIFwiIFwiICkgKyBcIiBcIiApLmluZGV4T2YoIGNoZWNrICkgPiAtMSA6XG5cdFx0XHRcdFx0b3BlcmF0b3IgPT09IFwifD1cIiA/IHJlc3VsdCA9PT0gY2hlY2sgfHwgcmVzdWx0LnNsaWNlKCAwLCBjaGVjay5sZW5ndGggKyAxICkgPT09IGNoZWNrICsgXCItXCIgOlxuXHRcdFx0XHRcdGZhbHNlO1xuXHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJDSElMRFwiOiBmdW5jdGlvbiggdHlwZSwgd2hhdCwgYXJndW1lbnQsIGZpcnN0LCBsYXN0ICkge1xuXHRcdFx0dmFyIHNpbXBsZSA9IHR5cGUuc2xpY2UoIDAsIDMgKSAhPT0gXCJudGhcIixcblx0XHRcdFx0Zm9yd2FyZCA9IHR5cGUuc2xpY2UoIC00ICkgIT09IFwibGFzdFwiLFxuXHRcdFx0XHRvZlR5cGUgPSB3aGF0ID09PSBcIm9mLXR5cGVcIjtcblxuXHRcdFx0cmV0dXJuIGZpcnN0ID09PSAxICYmIGxhc3QgPT09IDAgP1xuXG5cdFx0XHRcdC8vIFNob3J0Y3V0IGZvciA6bnRoLSoobilcblx0XHRcdFx0ZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdFx0cmV0dXJuICEhZWxlbS5wYXJlbnROb2RlO1xuXHRcdFx0XHR9IDpcblxuXHRcdFx0XHRmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0XHRcdHZhciBjYWNoZSwgb3V0ZXJDYWNoZSwgbm9kZSwgZGlmZiwgbm9kZUluZGV4LCBzdGFydCxcblx0XHRcdFx0XHRcdGRpciA9IHNpbXBsZSAhPT0gZm9yd2FyZCA/IFwibmV4dFNpYmxpbmdcIiA6IFwicHJldmlvdXNTaWJsaW5nXCIsXG5cdFx0XHRcdFx0XHRwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGUsXG5cdFx0XHRcdFx0XHRuYW1lID0gb2ZUeXBlICYmIGVsZW0ubm9kZU5hbWUudG9Mb3dlckNhc2UoKSxcblx0XHRcdFx0XHRcdHVzZUNhY2hlID0gIXhtbCAmJiAhb2ZUeXBlO1xuXG5cdFx0XHRcdFx0aWYgKCBwYXJlbnQgKSB7XG5cblx0XHRcdFx0XHRcdC8vIDooZmlyc3R8bGFzdHxvbmx5KS0oY2hpbGR8b2YtdHlwZSlcblx0XHRcdFx0XHRcdGlmICggc2ltcGxlICkge1xuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIGRpciApIHtcblx0XHRcdFx0XHRcdFx0XHRub2RlID0gZWxlbTtcblx0XHRcdFx0XHRcdFx0XHR3aGlsZSAoIChub2RlID0gbm9kZVsgZGlyIF0pICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBvZlR5cGUgPyBub2RlLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgPT09IG5hbWUgOiBub2RlLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdC8vIFJldmVyc2UgZGlyZWN0aW9uIGZvciA6b25seS0qIChpZiB3ZSBoYXZlbid0IHlldCBkb25lIHNvKVxuXHRcdFx0XHRcdFx0XHRcdHN0YXJ0ID0gZGlyID0gdHlwZSA9PT0gXCJvbmx5XCIgJiYgIXN0YXJ0ICYmIFwibmV4dFNpYmxpbmdcIjtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0c3RhcnQgPSBbIGZvcndhcmQgPyBwYXJlbnQuZmlyc3RDaGlsZCA6IHBhcmVudC5sYXN0Q2hpbGQgXTtcblxuXHRcdFx0XHRcdFx0Ly8gbm9uLXhtbCA6bnRoLWNoaWxkKC4uLikgc3RvcmVzIGNhY2hlIGRhdGEgb24gYHBhcmVudGBcblx0XHRcdFx0XHRcdGlmICggZm9yd2FyZCAmJiB1c2VDYWNoZSApIHtcblx0XHRcdFx0XHRcdFx0Ly8gU2VlayBgZWxlbWAgZnJvbSBhIHByZXZpb3VzbHktY2FjaGVkIGluZGV4XG5cdFx0XHRcdFx0XHRcdG91dGVyQ2FjaGUgPSBwYXJlbnRbIGV4cGFuZG8gXSB8fCAocGFyZW50WyBleHBhbmRvIF0gPSB7fSk7XG5cdFx0XHRcdFx0XHRcdGNhY2hlID0gb3V0ZXJDYWNoZVsgdHlwZSBdIHx8IFtdO1xuXHRcdFx0XHRcdFx0XHRub2RlSW5kZXggPSBjYWNoZVswXSA9PT0gZGlycnVucyAmJiBjYWNoZVsxXTtcblx0XHRcdFx0XHRcdFx0ZGlmZiA9IGNhY2hlWzBdID09PSBkaXJydW5zICYmIGNhY2hlWzJdO1xuXHRcdFx0XHRcdFx0XHRub2RlID0gbm9kZUluZGV4ICYmIHBhcmVudC5jaGlsZE5vZGVzWyBub2RlSW5kZXggXTtcblxuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIChub2RlID0gKytub2RlSW5kZXggJiYgbm9kZSAmJiBub2RlWyBkaXIgXSB8fFxuXG5cdFx0XHRcdFx0XHRcdFx0Ly8gRmFsbGJhY2sgdG8gc2Vla2luZyBgZWxlbWAgZnJvbSB0aGUgc3RhcnRcblx0XHRcdFx0XHRcdFx0XHQoZGlmZiA9IG5vZGVJbmRleCA9IDApIHx8IHN0YXJ0LnBvcCgpKSApIHtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIFdoZW4gZm91bmQsIGNhY2hlIGluZGV4ZXMgb24gYHBhcmVudGAgYW5kIGJyZWFrXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCBub2RlLm5vZGVUeXBlID09PSAxICYmICsrZGlmZiAmJiBub2RlID09PSBlbGVtICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0b3V0ZXJDYWNoZVsgdHlwZSBdID0gWyBkaXJydW5zLCBub2RlSW5kZXgsIGRpZmYgXTtcblx0XHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBVc2UgcHJldmlvdXNseS1jYWNoZWQgZWxlbWVudCBpbmRleCBpZiBhdmFpbGFibGVcblx0XHRcdFx0XHRcdH0gZWxzZSBpZiAoIHVzZUNhY2hlICYmIChjYWNoZSA9IChlbGVtWyBleHBhbmRvIF0gfHwgKGVsZW1bIGV4cGFuZG8gXSA9IHt9KSlbIHR5cGUgXSkgJiYgY2FjaGVbMF0gPT09IGRpcnJ1bnMgKSB7XG5cdFx0XHRcdFx0XHRcdGRpZmYgPSBjYWNoZVsxXTtcblxuXHRcdFx0XHRcdFx0Ly8geG1sIDpudGgtY2hpbGQoLi4uKSBvciA6bnRoLWxhc3QtY2hpbGQoLi4uKSBvciA6bnRoKC1sYXN0KT8tb2YtdHlwZSguLi4pXG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHQvLyBVc2UgdGhlIHNhbWUgbG9vcCBhcyBhYm92ZSB0byBzZWVrIGBlbGVtYCBmcm9tIHRoZSBzdGFydFxuXHRcdFx0XHRcdFx0XHR3aGlsZSAoIChub2RlID0gKytub2RlSW5kZXggJiYgbm9kZSAmJiBub2RlWyBkaXIgXSB8fFxuXHRcdFx0XHRcdFx0XHRcdChkaWZmID0gbm9kZUluZGV4ID0gMCkgfHwgc3RhcnQucG9wKCkpICkge1xuXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCAoIG9mVHlwZSA/IG5vZGUubm9kZU5hbWUudG9Mb3dlckNhc2UoKSA9PT0gbmFtZSA6IG5vZGUubm9kZVR5cGUgPT09IDEgKSAmJiArK2RpZmYgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBDYWNoZSB0aGUgaW5kZXggb2YgZWFjaCBlbmNvdW50ZXJlZCBlbGVtZW50XG5cdFx0XHRcdFx0XHRcdFx0XHRpZiAoIHVzZUNhY2hlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHQobm9kZVsgZXhwYW5kbyBdIHx8IChub2RlWyBleHBhbmRvIF0gPSB7fSkpWyB0eXBlIF0gPSBbIGRpcnJ1bnMsIGRpZmYgXTtcblx0XHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdFx0aWYgKCBub2RlID09PSBlbGVtICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gSW5jb3Jwb3JhdGUgdGhlIG9mZnNldCwgdGhlbiBjaGVjayBhZ2FpbnN0IGN5Y2xlIHNpemVcblx0XHRcdFx0XHRcdGRpZmYgLT0gbGFzdDtcblx0XHRcdFx0XHRcdHJldHVybiBkaWZmID09PSBmaXJzdCB8fCAoIGRpZmYgJSBmaXJzdCA9PT0gMCAmJiBkaWZmIC8gZmlyc3QgPj0gMCApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fTtcblx0XHR9LFxuXG5cdFx0XCJQU0VVRE9cIjogZnVuY3Rpb24oIHBzZXVkbywgYXJndW1lbnQgKSB7XG5cdFx0XHQvLyBwc2V1ZG8tY2xhc3MgbmFtZXMgYXJlIGNhc2UtaW5zZW5zaXRpdmVcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSL3NlbGVjdG9ycy8jcHNldWRvLWNsYXNzZXNcblx0XHRcdC8vIFByaW9yaXRpemUgYnkgY2FzZSBzZW5zaXRpdml0eSBpbiBjYXNlIGN1c3RvbSBwc2V1ZG9zIGFyZSBhZGRlZCB3aXRoIHVwcGVyY2FzZSBsZXR0ZXJzXG5cdFx0XHQvLyBSZW1lbWJlciB0aGF0IHNldEZpbHRlcnMgaW5oZXJpdHMgZnJvbSBwc2V1ZG9zXG5cdFx0XHR2YXIgYXJncyxcblx0XHRcdFx0Zm4gPSBFeHByLnBzZXVkb3NbIHBzZXVkbyBdIHx8IEV4cHIuc2V0RmlsdGVyc1sgcHNldWRvLnRvTG93ZXJDYXNlKCkgXSB8fFxuXHRcdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBwc2V1ZG86IFwiICsgcHNldWRvICk7XG5cblx0XHRcdC8vIFRoZSB1c2VyIG1heSB1c2UgY3JlYXRlUHNldWRvIHRvIGluZGljYXRlIHRoYXRcblx0XHRcdC8vIGFyZ3VtZW50cyBhcmUgbmVlZGVkIHRvIGNyZWF0ZSB0aGUgZmlsdGVyIGZ1bmN0aW9uXG5cdFx0XHQvLyBqdXN0IGFzIFNpenpsZSBkb2VzXG5cdFx0XHRpZiAoIGZuWyBleHBhbmRvIF0gKSB7XG5cdFx0XHRcdHJldHVybiBmbiggYXJndW1lbnQgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQnV0IG1haW50YWluIHN1cHBvcnQgZm9yIG9sZCBzaWduYXR1cmVzXG5cdFx0XHRpZiAoIGZuLmxlbmd0aCA+IDEgKSB7XG5cdFx0XHRcdGFyZ3MgPSBbIHBzZXVkbywgcHNldWRvLCBcIlwiLCBhcmd1bWVudCBdO1xuXHRcdFx0XHRyZXR1cm4gRXhwci5zZXRGaWx0ZXJzLmhhc093blByb3BlcnR5KCBwc2V1ZG8udG9Mb3dlckNhc2UoKSApID9cblx0XHRcdFx0XHRtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMgKSB7XG5cdFx0XHRcdFx0XHR2YXIgaWR4LFxuXHRcdFx0XHRcdFx0XHRtYXRjaGVkID0gZm4oIHNlZWQsIGFyZ3VtZW50ICksXG5cdFx0XHRcdFx0XHRcdGkgPSBtYXRjaGVkLmxlbmd0aDtcblx0XHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0XHRpZHggPSBpbmRleE9mKCBzZWVkLCBtYXRjaGVkW2ldICk7XG5cdFx0XHRcdFx0XHRcdHNlZWRbIGlkeCBdID0gISggbWF0Y2hlc1sgaWR4IF0gPSBtYXRjaGVkW2ldICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSkgOlxuXHRcdFx0XHRcdGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRcdFx0cmV0dXJuIGZuKCBlbGVtLCAwLCBhcmdzICk7XG5cdFx0XHRcdFx0fTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGZuO1xuXHRcdH1cblx0fSxcblxuXHRwc2V1ZG9zOiB7XG5cdFx0Ly8gUG90ZW50aWFsbHkgY29tcGxleCBwc2V1ZG9zXG5cdFx0XCJub3RcIjogbWFya0Z1bmN0aW9uKGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRcdC8vIFRyaW0gdGhlIHNlbGVjdG9yIHBhc3NlZCB0byBjb21waWxlXG5cdFx0XHQvLyB0byBhdm9pZCB0cmVhdGluZyBsZWFkaW5nIGFuZCB0cmFpbGluZ1xuXHRcdFx0Ly8gc3BhY2VzIGFzIGNvbWJpbmF0b3JzXG5cdFx0XHR2YXIgaW5wdXQgPSBbXSxcblx0XHRcdFx0cmVzdWx0cyA9IFtdLFxuXHRcdFx0XHRtYXRjaGVyID0gY29tcGlsZSggc2VsZWN0b3IucmVwbGFjZSggcnRyaW0sIFwiJDFcIiApICk7XG5cblx0XHRcdHJldHVybiBtYXRjaGVyWyBleHBhbmRvIF0gP1xuXHRcdFx0XHRtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlZWQsIG1hdGNoZXMsIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdFx0XHR2YXIgZWxlbSxcblx0XHRcdFx0XHRcdHVubWF0Y2hlZCA9IG1hdGNoZXIoIHNlZWQsIG51bGwsIHhtbCwgW10gKSxcblx0XHRcdFx0XHRcdGkgPSBzZWVkLmxlbmd0aDtcblxuXHRcdFx0XHRcdC8vIE1hdGNoIGVsZW1lbnRzIHVubWF0Y2hlZCBieSBgbWF0Y2hlcmBcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0XHRcdGlmICggKGVsZW0gPSB1bm1hdGNoZWRbaV0pICkge1xuXHRcdFx0XHRcdFx0XHRzZWVkW2ldID0gIShtYXRjaGVzW2ldID0gZWxlbSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KSA6XG5cdFx0XHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHRcdFx0aW5wdXRbMF0gPSBlbGVtO1xuXHRcdFx0XHRcdG1hdGNoZXIoIGlucHV0LCBudWxsLCB4bWwsIHJlc3VsdHMgKTtcblx0XHRcdFx0XHQvLyBEb24ndCBrZWVwIHRoZSBlbGVtZW50IChpc3N1ZSAjMjk5KVxuXHRcdFx0XHRcdGlucHV0WzBdID0gbnVsbDtcblx0XHRcdFx0XHRyZXR1cm4gIXJlc3VsdHMucG9wKCk7XG5cdFx0XHRcdH07XG5cdFx0fSksXG5cblx0XHRcImhhc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gU2l6emxlKCBzZWxlY3RvciwgZWxlbSApLmxlbmd0aCA+IDA7XG5cdFx0XHR9O1xuXHRcdH0pLFxuXG5cdFx0XCJjb250YWluc1wiOiBtYXJrRnVuY3Rpb24oZnVuY3Rpb24oIHRleHQgKSB7XG5cdFx0XHR0ZXh0ID0gdGV4dC5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApO1xuXHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0XHRyZXR1cm4gKCBlbGVtLnRleHRDb250ZW50IHx8IGVsZW0uaW5uZXJUZXh0IHx8IGdldFRleHQoIGVsZW0gKSApLmluZGV4T2YoIHRleHQgKSA+IC0xO1xuXHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdC8vIFwiV2hldGhlciBhbiBlbGVtZW50IGlzIHJlcHJlc2VudGVkIGJ5IGEgOmxhbmcoKSBzZWxlY3RvclxuXHRcdC8vIGlzIGJhc2VkIHNvbGVseSBvbiB0aGUgZWxlbWVudCdzIGxhbmd1YWdlIHZhbHVlXG5cdFx0Ly8gYmVpbmcgZXF1YWwgdG8gdGhlIGlkZW50aWZpZXIgQyxcblx0XHQvLyBvciBiZWdpbm5pbmcgd2l0aCB0aGUgaWRlbnRpZmllciBDIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IFwiLVwiLlxuXHRcdC8vIFRoZSBtYXRjaGluZyBvZiBDIGFnYWluc3QgdGhlIGVsZW1lbnQncyBsYW5ndWFnZSB2YWx1ZSBpcyBwZXJmb3JtZWQgY2FzZS1pbnNlbnNpdGl2ZWx5LlxuXHRcdC8vIFRoZSBpZGVudGlmaWVyIEMgZG9lcyBub3QgaGF2ZSB0byBiZSBhIHZhbGlkIGxhbmd1YWdlIG5hbWUuXCJcblx0XHQvLyBodHRwOi8vd3d3LnczLm9yZy9UUi9zZWxlY3RvcnMvI2xhbmctcHNldWRvXG5cdFx0XCJsYW5nXCI6IG1hcmtGdW5jdGlvbiggZnVuY3Rpb24oIGxhbmcgKSB7XG5cdFx0XHQvLyBsYW5nIHZhbHVlIG11c3QgYmUgYSB2YWxpZCBpZGVudGlmaWVyXG5cdFx0XHRpZiAoICFyaWRlbnRpZmllci50ZXN0KGxhbmcgfHwgXCJcIikgKSB7XG5cdFx0XHRcdFNpenpsZS5lcnJvciggXCJ1bnN1cHBvcnRlZCBsYW5nOiBcIiArIGxhbmcgKTtcblx0XHRcdH1cblx0XHRcdGxhbmcgPSBsYW5nLnJlcGxhY2UoIHJ1bmVzY2FwZSwgZnVuZXNjYXBlICkudG9Mb3dlckNhc2UoKTtcblx0XHRcdHJldHVybiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0dmFyIGVsZW1MYW5nO1xuXHRcdFx0XHRkbyB7XG5cdFx0XHRcdFx0aWYgKCAoZWxlbUxhbmcgPSBkb2N1bWVudElzSFRNTCA/XG5cdFx0XHRcdFx0XHRlbGVtLmxhbmcgOlxuXHRcdFx0XHRcdFx0ZWxlbS5nZXRBdHRyaWJ1dGUoXCJ4bWw6bGFuZ1wiKSB8fCBlbGVtLmdldEF0dHJpYnV0ZShcImxhbmdcIikpICkge1xuXG5cdFx0XHRcdFx0XHRlbGVtTGFuZyA9IGVsZW1MYW5nLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZWxlbUxhbmcgPT09IGxhbmcgfHwgZWxlbUxhbmcuaW5kZXhPZiggbGFuZyArIFwiLVwiICkgPT09IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9IHdoaWxlICggKGVsZW0gPSBlbGVtLnBhcmVudE5vZGUpICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fTtcblx0XHR9KSxcblxuXHRcdC8vIE1pc2NlbGxhbmVvdXNcblx0XHRcInRhcmdldFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBoYXNoID0gd2luZG93LmxvY2F0aW9uICYmIHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuXHRcdFx0cmV0dXJuIGhhc2ggJiYgaGFzaC5zbGljZSggMSApID09PSBlbGVtLmlkO1xuXHRcdH0sXG5cblx0XHRcInJvb3RcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRyZXR1cm4gZWxlbSA9PT0gZG9jRWxlbTtcblx0XHR9LFxuXG5cdFx0XCJmb2N1c1wiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBkb2N1bWVudC5hY3RpdmVFbGVtZW50ICYmICghZG9jdW1lbnQuaGFzRm9jdXMgfHwgZG9jdW1lbnQuaGFzRm9jdXMoKSkgJiYgISEoZWxlbS50eXBlIHx8IGVsZW0uaHJlZiB8fCB+ZWxlbS50YWJJbmRleCk7XG5cdFx0fSxcblxuXHRcdC8vIEJvb2xlYW4gcHJvcGVydGllc1xuXHRcdFwiZW5hYmxlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSBmYWxzZTtcblx0XHR9LFxuXG5cdFx0XCJkaXNhYmxlZFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLmRpc2FibGVkID09PSB0cnVlO1xuXHRcdH0sXG5cblx0XHRcImNoZWNrZWRcIjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHQvLyBJbiBDU1MzLCA6Y2hlY2tlZCBzaG91bGQgcmV0dXJuIGJvdGggY2hlY2tlZCBhbmQgc2VsZWN0ZWQgZWxlbWVudHNcblx0XHRcdC8vIGh0dHA6Ly93d3cudzMub3JnL1RSLzIwMTEvUkVDLWNzczMtc2VsZWN0b3JzLTIwMTEwOTI5LyNjaGVja2VkXG5cdFx0XHR2YXIgbm9kZU5hbWUgPSBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRyZXR1cm4gKG5vZGVOYW1lID09PSBcImlucHV0XCIgJiYgISFlbGVtLmNoZWNrZWQpIHx8IChub2RlTmFtZSA9PT0gXCJvcHRpb25cIiAmJiAhIWVsZW0uc2VsZWN0ZWQpO1xuXHRcdH0sXG5cblx0XHRcInNlbGVjdGVkXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Ly8gQWNjZXNzaW5nIHRoaXMgcHJvcGVydHkgbWFrZXMgc2VsZWN0ZWQtYnktZGVmYXVsdFxuXHRcdFx0Ly8gb3B0aW9ucyBpbiBTYWZhcmkgd29yayBwcm9wZXJseVxuXHRcdFx0aWYgKCBlbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdGVsZW0ucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZWxlbS5zZWxlY3RlZCA9PT0gdHJ1ZTtcblx0XHR9LFxuXG5cdFx0Ly8gQ29udGVudHNcblx0XHRcImVtcHR5XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Ly8gaHR0cDovL3d3dy53My5vcmcvVFIvc2VsZWN0b3JzLyNlbXB0eS1wc2V1ZG9cblx0XHRcdC8vIDplbXB0eSBpcyBuZWdhdGVkIGJ5IGVsZW1lbnQgKDEpIG9yIGNvbnRlbnQgbm9kZXMgKHRleHQ6IDM7IGNkYXRhOiA0OyBlbnRpdHkgcmVmOiA1KSxcblx0XHRcdC8vICAgYnV0IG5vdCBieSBvdGhlcnMgKGNvbW1lbnQ6IDg7IHByb2Nlc3NpbmcgaW5zdHJ1Y3Rpb246IDc7IGV0Yy4pXG5cdFx0XHQvLyBub2RlVHlwZSA8IDYgd29ya3MgYmVjYXVzZSBhdHRyaWJ1dGVzICgyKSBkbyBub3QgYXBwZWFyIGFzIGNoaWxkcmVuXG5cdFx0XHRmb3IgKCBlbGVtID0gZWxlbS5maXJzdENoaWxkOyBlbGVtOyBlbGVtID0gZWxlbS5uZXh0U2libGluZyApIHtcblx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlIDwgNiApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0sXG5cblx0XHRcInBhcmVudFwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiAhRXhwci5wc2V1ZG9zW1wiZW1wdHlcIl0oIGVsZW0gKTtcblx0XHR9LFxuXG5cdFx0Ly8gRWxlbWVudC9pbnB1dCB0eXBlc1xuXHRcdFwiaGVhZGVyXCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJoZWFkZXIudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImlucHV0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIHJpbnB1dHMudGVzdCggZWxlbS5ub2RlTmFtZSApO1xuXHRcdH0sXG5cblx0XHRcImJ1dHRvblwiOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBuYW1lID0gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpO1xuXHRcdFx0cmV0dXJuIG5hbWUgPT09IFwiaW5wdXRcIiAmJiBlbGVtLnR5cGUgPT09IFwiYnV0dG9uXCIgfHwgbmFtZSA9PT0gXCJidXR0b25cIjtcblx0XHR9LFxuXG5cdFx0XCJ0ZXh0XCI6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0dmFyIGF0dHI7XG5cdFx0XHRyZXR1cm4gZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIgJiZcblx0XHRcdFx0ZWxlbS50eXBlID09PSBcInRleHRcIiAmJlxuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFPDhcblx0XHRcdFx0Ly8gTmV3IEhUTUw1IGF0dHJpYnV0ZSB2YWx1ZXMgKGUuZy4sIFwic2VhcmNoXCIpIGFwcGVhciB3aXRoIGVsZW0udHlwZSA9PT0gXCJ0ZXh0XCJcblx0XHRcdFx0KCAoYXR0ciA9IGVsZW0uZ2V0QXR0cmlidXRlKFwidHlwZVwiKSkgPT0gbnVsbCB8fCBhdHRyLnRvTG93ZXJDYXNlKCkgPT09IFwidGV4dFwiICk7XG5cdFx0fSxcblxuXHRcdC8vIFBvc2l0aW9uLWluLWNvbGxlY3Rpb25cblx0XHRcImZpcnN0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gWyAwIF07XG5cdFx0fSksXG5cblx0XHRcImxhc3RcIjogY3JlYXRlUG9zaXRpb25hbFBzZXVkbyhmdW5jdGlvbiggbWF0Y2hJbmRleGVzLCBsZW5ndGggKSB7XG5cdFx0XHRyZXR1cm4gWyBsZW5ndGggLSAxIF07XG5cdFx0fSksXG5cblx0XHRcImVxXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHJldHVybiBbIGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQgXTtcblx0XHR9KSxcblxuXHRcdFwiZXZlblwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCApIHtcblx0XHRcdHZhciBpID0gMDtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSArPSAyICkge1xuXHRcdFx0XHRtYXRjaEluZGV4ZXMucHVzaCggaSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG1hdGNoSW5kZXhlcztcblx0XHR9KSxcblxuXHRcdFwib2RkXCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoICkge1xuXHRcdFx0dmFyIGkgPSAxO1xuXHRcdFx0Zm9yICggOyBpIDwgbGVuZ3RoOyBpICs9IDIgKSB7XG5cdFx0XHRcdG1hdGNoSW5kZXhlcy5wdXNoKCBpICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbWF0Y2hJbmRleGVzO1xuXHRcdH0pLFxuXG5cdFx0XCJsdFwiOiBjcmVhdGVQb3NpdGlvbmFsUHNldWRvKGZ1bmN0aW9uKCBtYXRjaEluZGV4ZXMsIGxlbmd0aCwgYXJndW1lbnQgKSB7XG5cdFx0XHR2YXIgaSA9IGFyZ3VtZW50IDwgMCA/IGFyZ3VtZW50ICsgbGVuZ3RoIDogYXJndW1lbnQ7XG5cdFx0XHRmb3IgKCA7IC0taSA+PSAwOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSksXG5cblx0XHRcImd0XCI6IGNyZWF0ZVBvc2l0aW9uYWxQc2V1ZG8oZnVuY3Rpb24oIG1hdGNoSW5kZXhlcywgbGVuZ3RoLCBhcmd1bWVudCApIHtcblx0XHRcdHZhciBpID0gYXJndW1lbnQgPCAwID8gYXJndW1lbnQgKyBsZW5ndGggOiBhcmd1bWVudDtcblx0XHRcdGZvciAoIDsgKytpIDwgbGVuZ3RoOyApIHtcblx0XHRcdFx0bWF0Y2hJbmRleGVzLnB1c2goIGkgKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBtYXRjaEluZGV4ZXM7XG5cdFx0fSlcblx0fVxufTtcblxuRXhwci5wc2V1ZG9zW1wibnRoXCJdID0gRXhwci5wc2V1ZG9zW1wiZXFcIl07XG5cbi8vIEFkZCBidXR0b24vaW5wdXQgdHlwZSBwc2V1ZG9zXG5mb3IgKCBpIGluIHsgcmFkaW86IHRydWUsIGNoZWNrYm94OiB0cnVlLCBmaWxlOiB0cnVlLCBwYXNzd29yZDogdHJ1ZSwgaW1hZ2U6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVJbnB1dFBzZXVkbyggaSApO1xufVxuZm9yICggaSBpbiB7IHN1Ym1pdDogdHJ1ZSwgcmVzZXQ6IHRydWUgfSApIHtcblx0RXhwci5wc2V1ZG9zWyBpIF0gPSBjcmVhdGVCdXR0b25Qc2V1ZG8oIGkgKTtcbn1cblxuLy8gRWFzeSBBUEkgZm9yIGNyZWF0aW5nIG5ldyBzZXRGaWx0ZXJzXG5mdW5jdGlvbiBzZXRGaWx0ZXJzKCkge31cbnNldEZpbHRlcnMucHJvdG90eXBlID0gRXhwci5maWx0ZXJzID0gRXhwci5wc2V1ZG9zO1xuRXhwci5zZXRGaWx0ZXJzID0gbmV3IHNldEZpbHRlcnMoKTtcblxudG9rZW5pemUgPSBTaXp6bGUudG9rZW5pemUgPSBmdW5jdGlvbiggc2VsZWN0b3IsIHBhcnNlT25seSApIHtcblx0dmFyIG1hdGNoZWQsIG1hdGNoLCB0b2tlbnMsIHR5cGUsXG5cdFx0c29GYXIsIGdyb3VwcywgcHJlRmlsdGVycyxcblx0XHRjYWNoZWQgPSB0b2tlbkNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCBjYWNoZWQgKSB7XG5cdFx0cmV0dXJuIHBhcnNlT25seSA/IDAgOiBjYWNoZWQuc2xpY2UoIDAgKTtcblx0fVxuXG5cdHNvRmFyID0gc2VsZWN0b3I7XG5cdGdyb3VwcyA9IFtdO1xuXHRwcmVGaWx0ZXJzID0gRXhwci5wcmVGaWx0ZXI7XG5cblx0d2hpbGUgKCBzb0ZhciApIHtcblxuXHRcdC8vIENvbW1hIGFuZCBmaXJzdCBydW5cblx0XHRpZiAoICFtYXRjaGVkIHx8IChtYXRjaCA9IHJjb21tYS5leGVjKCBzb0ZhciApKSApIHtcblx0XHRcdGlmICggbWF0Y2ggKSB7XG5cdFx0XHRcdC8vIERvbid0IGNvbnN1bWUgdHJhaWxpbmcgY29tbWFzIGFzIHZhbGlkXG5cdFx0XHRcdHNvRmFyID0gc29GYXIuc2xpY2UoIG1hdGNoWzBdLmxlbmd0aCApIHx8IHNvRmFyO1xuXHRcdFx0fVxuXHRcdFx0Z3JvdXBzLnB1c2goICh0b2tlbnMgPSBbXSkgKTtcblx0XHR9XG5cblx0XHRtYXRjaGVkID0gZmFsc2U7XG5cblx0XHQvLyBDb21iaW5hdG9yc1xuXHRcdGlmICggKG1hdGNoID0gcmNvbWJpbmF0b3JzLmV4ZWMoIHNvRmFyICkpICkge1xuXHRcdFx0bWF0Y2hlZCA9IG1hdGNoLnNoaWZ0KCk7XG5cdFx0XHR0b2tlbnMucHVzaCh7XG5cdFx0XHRcdHZhbHVlOiBtYXRjaGVkLFxuXHRcdFx0XHQvLyBDYXN0IGRlc2NlbmRhbnQgY29tYmluYXRvcnMgdG8gc3BhY2Vcblx0XHRcdFx0dHlwZTogbWF0Y2hbMF0ucmVwbGFjZSggcnRyaW0sIFwiIFwiIClcblx0XHRcdH0pO1xuXHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHR9XG5cblx0XHQvLyBGaWx0ZXJzXG5cdFx0Zm9yICggdHlwZSBpbiBFeHByLmZpbHRlciApIHtcblx0XHRcdGlmICggKG1hdGNoID0gbWF0Y2hFeHByWyB0eXBlIF0uZXhlYyggc29GYXIgKSkgJiYgKCFwcmVGaWx0ZXJzWyB0eXBlIF0gfHxcblx0XHRcdFx0KG1hdGNoID0gcHJlRmlsdGVyc1sgdHlwZSBdKCBtYXRjaCApKSkgKSB7XG5cdFx0XHRcdG1hdGNoZWQgPSBtYXRjaC5zaGlmdCgpO1xuXHRcdFx0XHR0b2tlbnMucHVzaCh7XG5cdFx0XHRcdFx0dmFsdWU6IG1hdGNoZWQsXG5cdFx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0XHRtYXRjaGVzOiBtYXRjaFxuXHRcdFx0XHR9KTtcblx0XHRcdFx0c29GYXIgPSBzb0Zhci5zbGljZSggbWF0Y2hlZC5sZW5ndGggKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRpZiAoICFtYXRjaGVkICkge1xuXHRcdFx0YnJlYWs7XG5cdFx0fVxuXHR9XG5cblx0Ly8gUmV0dXJuIHRoZSBsZW5ndGggb2YgdGhlIGludmFsaWQgZXhjZXNzXG5cdC8vIGlmIHdlJ3JlIGp1c3QgcGFyc2luZ1xuXHQvLyBPdGhlcndpc2UsIHRocm93IGFuIGVycm9yIG9yIHJldHVybiB0b2tlbnNcblx0cmV0dXJuIHBhcnNlT25seSA/XG5cdFx0c29GYXIubGVuZ3RoIDpcblx0XHRzb0ZhciA/XG5cdFx0XHRTaXp6bGUuZXJyb3IoIHNlbGVjdG9yICkgOlxuXHRcdFx0Ly8gQ2FjaGUgdGhlIHRva2Vuc1xuXHRcdFx0dG9rZW5DYWNoZSggc2VsZWN0b3IsIGdyb3VwcyApLnNsaWNlKCAwICk7XG59O1xuXG5mdW5jdGlvbiB0b1NlbGVjdG9yKCB0b2tlbnMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSB0b2tlbnMubGVuZ3RoLFxuXHRcdHNlbGVjdG9yID0gXCJcIjtcblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0c2VsZWN0b3IgKz0gdG9rZW5zW2ldLnZhbHVlO1xuXHR9XG5cdHJldHVybiBzZWxlY3Rvcjtcbn1cblxuZnVuY3Rpb24gYWRkQ29tYmluYXRvciggbWF0Y2hlciwgY29tYmluYXRvciwgYmFzZSApIHtcblx0dmFyIGRpciA9IGNvbWJpbmF0b3IuZGlyLFxuXHRcdGNoZWNrTm9uRWxlbWVudHMgPSBiYXNlICYmIGRpciA9PT0gXCJwYXJlbnROb2RlXCIsXG5cdFx0ZG9uZU5hbWUgPSBkb25lKys7XG5cblx0cmV0dXJuIGNvbWJpbmF0b3IuZmlyc3QgP1xuXHRcdC8vIENoZWNrIGFnYWluc3QgY2xvc2VzdCBhbmNlc3Rvci9wcmVjZWRpbmcgZWxlbWVudFxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR3aGlsZSAoIChlbGVtID0gZWxlbVsgZGlyIF0pICkge1xuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgY2hlY2tOb25FbGVtZW50cyApIHtcblx0XHRcdFx0XHRyZXR1cm4gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9IDpcblxuXHRcdC8vIENoZWNrIGFnYWluc3QgYWxsIGFuY2VzdG9yL3ByZWNlZGluZyBlbGVtZW50c1xuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb250ZXh0LCB4bWwgKSB7XG5cdFx0XHR2YXIgb2xkQ2FjaGUsIG91dGVyQ2FjaGUsXG5cdFx0XHRcdG5ld0NhY2hlID0gWyBkaXJydW5zLCBkb25lTmFtZSBdO1xuXG5cdFx0XHQvLyBXZSBjYW4ndCBzZXQgYXJiaXRyYXJ5IGRhdGEgb24gWE1MIG5vZGVzLCBzbyB0aGV5IGRvbid0IGJlbmVmaXQgZnJvbSBkaXIgY2FjaGluZ1xuXHRcdFx0aWYgKCB4bWwgKSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIG1hdGNoZXIoIGVsZW0sIGNvbnRleHQsIHhtbCApICkge1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHdoaWxlICggKGVsZW0gPSBlbGVtWyBkaXIgXSkgKSB7XG5cdFx0XHRcdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxIHx8IGNoZWNrTm9uRWxlbWVudHMgKSB7XG5cdFx0XHRcdFx0XHRvdXRlckNhY2hlID0gZWxlbVsgZXhwYW5kbyBdIHx8IChlbGVtWyBleHBhbmRvIF0gPSB7fSk7XG5cdFx0XHRcdFx0XHRpZiAoIChvbGRDYWNoZSA9IG91dGVyQ2FjaGVbIGRpciBdKSAmJlxuXHRcdFx0XHRcdFx0XHRvbGRDYWNoZVsgMCBdID09PSBkaXJydW5zICYmIG9sZENhY2hlWyAxIF0gPT09IGRvbmVOYW1lICkge1xuXG5cdFx0XHRcdFx0XHRcdC8vIEFzc2lnbiB0byBuZXdDYWNoZSBzbyByZXN1bHRzIGJhY2stcHJvcGFnYXRlIHRvIHByZXZpb3VzIGVsZW1lbnRzXG5cdFx0XHRcdFx0XHRcdHJldHVybiAobmV3Q2FjaGVbIDIgXSA9IG9sZENhY2hlWyAyIF0pO1xuXHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0Ly8gUmV1c2UgbmV3Y2FjaGUgc28gcmVzdWx0cyBiYWNrLXByb3BhZ2F0ZSB0byBwcmV2aW91cyBlbGVtZW50c1xuXHRcdFx0XHRcdFx0XHRvdXRlckNhY2hlWyBkaXIgXSA9IG5ld0NhY2hlO1xuXG5cdFx0XHRcdFx0XHRcdC8vIEEgbWF0Y2ggbWVhbnMgd2UncmUgZG9uZTsgYSBmYWlsIG1lYW5zIHdlIGhhdmUgdG8ga2VlcCBjaGVja2luZ1xuXHRcdFx0XHRcdFx0XHRpZiAoIChuZXdDYWNoZVsgMiBdID0gbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkpICkge1xuXHRcdFx0XHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcbn1cblxuZnVuY3Rpb24gZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICkge1xuXHRyZXR1cm4gbWF0Y2hlcnMubGVuZ3RoID4gMSA/XG5cdFx0ZnVuY3Rpb24oIGVsZW0sIGNvbnRleHQsIHhtbCApIHtcblx0XHRcdHZhciBpID0gbWF0Y2hlcnMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdGlmICggIW1hdGNoZXJzW2ldKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdH0gOlxuXHRcdG1hdGNoZXJzWzBdO1xufVxuXG5mdW5jdGlvbiBtdWx0aXBsZUNvbnRleHRzKCBzZWxlY3RvciwgY29udGV4dHMsIHJlc3VsdHMgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW4gPSBjb250ZXh0cy5sZW5ndGg7XG5cdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFNpenpsZSggc2VsZWN0b3IsIGNvbnRleHRzW2ldLCByZXN1bHRzICk7XG5cdH1cblx0cmV0dXJuIHJlc3VsdHM7XG59XG5cbmZ1bmN0aW9uIGNvbmRlbnNlKCB1bm1hdGNoZWQsIG1hcCwgZmlsdGVyLCBjb250ZXh0LCB4bWwgKSB7XG5cdHZhciBlbGVtLFxuXHRcdG5ld1VubWF0Y2hlZCA9IFtdLFxuXHRcdGkgPSAwLFxuXHRcdGxlbiA9IHVubWF0Y2hlZC5sZW5ndGgsXG5cdFx0bWFwcGVkID0gbWFwICE9IG51bGw7XG5cblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0aWYgKCAoZWxlbSA9IHVubWF0Y2hlZFtpXSkgKSB7XG5cdFx0XHRpZiAoICFmaWx0ZXIgfHwgZmlsdGVyKCBlbGVtLCBjb250ZXh0LCB4bWwgKSApIHtcblx0XHRcdFx0bmV3VW5tYXRjaGVkLnB1c2goIGVsZW0gKTtcblx0XHRcdFx0aWYgKCBtYXBwZWQgKSB7XG5cdFx0XHRcdFx0bWFwLnB1c2goIGkgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiBuZXdVbm1hdGNoZWQ7XG59XG5cbmZ1bmN0aW9uIHNldE1hdGNoZXIoIHByZUZpbHRlciwgc2VsZWN0b3IsIG1hdGNoZXIsIHBvc3RGaWx0ZXIsIHBvc3RGaW5kZXIsIHBvc3RTZWxlY3RvciApIHtcblx0aWYgKCBwb3N0RmlsdGVyICYmICFwb3N0RmlsdGVyWyBleHBhbmRvIF0gKSB7XG5cdFx0cG9zdEZpbHRlciA9IHNldE1hdGNoZXIoIHBvc3RGaWx0ZXIgKTtcblx0fVxuXHRpZiAoIHBvc3RGaW5kZXIgJiYgIXBvc3RGaW5kZXJbIGV4cGFuZG8gXSApIHtcblx0XHRwb3N0RmluZGVyID0gc2V0TWF0Y2hlciggcG9zdEZpbmRlciwgcG9zdFNlbGVjdG9yICk7XG5cdH1cblx0cmV0dXJuIG1hcmtGdW5jdGlvbihmdW5jdGlvbiggc2VlZCwgcmVzdWx0cywgY29udGV4dCwgeG1sICkge1xuXHRcdHZhciB0ZW1wLCBpLCBlbGVtLFxuXHRcdFx0cHJlTWFwID0gW10sXG5cdFx0XHRwb3N0TWFwID0gW10sXG5cdFx0XHRwcmVleGlzdGluZyA9IHJlc3VsdHMubGVuZ3RoLFxuXG5cdFx0XHQvLyBHZXQgaW5pdGlhbCBlbGVtZW50cyBmcm9tIHNlZWQgb3IgY29udGV4dFxuXHRcdFx0ZWxlbXMgPSBzZWVkIHx8IG11bHRpcGxlQ29udGV4dHMoIHNlbGVjdG9yIHx8IFwiKlwiLCBjb250ZXh0Lm5vZGVUeXBlID8gWyBjb250ZXh0IF0gOiBjb250ZXh0LCBbXSApLFxuXG5cdFx0XHQvLyBQcmVmaWx0ZXIgdG8gZ2V0IG1hdGNoZXIgaW5wdXQsIHByZXNlcnZpbmcgYSBtYXAgZm9yIHNlZWQtcmVzdWx0cyBzeW5jaHJvbml6YXRpb25cblx0XHRcdG1hdGNoZXJJbiA9IHByZUZpbHRlciAmJiAoIHNlZWQgfHwgIXNlbGVjdG9yICkgP1xuXHRcdFx0XHRjb25kZW5zZSggZWxlbXMsIHByZU1hcCwgcHJlRmlsdGVyLCBjb250ZXh0LCB4bWwgKSA6XG5cdFx0XHRcdGVsZW1zLFxuXG5cdFx0XHRtYXRjaGVyT3V0ID0gbWF0Y2hlciA/XG5cdFx0XHRcdC8vIElmIHdlIGhhdmUgYSBwb3N0RmluZGVyLCBvciBmaWx0ZXJlZCBzZWVkLCBvciBub24tc2VlZCBwb3N0RmlsdGVyIG9yIHByZWV4aXN0aW5nIHJlc3VsdHMsXG5cdFx0XHRcdHBvc3RGaW5kZXIgfHwgKCBzZWVkID8gcHJlRmlsdGVyIDogcHJlZXhpc3RpbmcgfHwgcG9zdEZpbHRlciApID9cblxuXHRcdFx0XHRcdC8vIC4uLmludGVybWVkaWF0ZSBwcm9jZXNzaW5nIGlzIG5lY2Vzc2FyeVxuXHRcdFx0XHRcdFtdIDpcblxuXHRcdFx0XHRcdC8vIC4uLm90aGVyd2lzZSB1c2UgcmVzdWx0cyBkaXJlY3RseVxuXHRcdFx0XHRcdHJlc3VsdHMgOlxuXHRcdFx0XHRtYXRjaGVySW47XG5cblx0XHQvLyBGaW5kIHByaW1hcnkgbWF0Y2hlc1xuXHRcdGlmICggbWF0Y2hlciApIHtcblx0XHRcdG1hdGNoZXIoIG1hdGNoZXJJbiwgbWF0Y2hlck91dCwgY29udGV4dCwgeG1sICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgcG9zdEZpbHRlclxuXHRcdGlmICggcG9zdEZpbHRlciApIHtcblx0XHRcdHRlbXAgPSBjb25kZW5zZSggbWF0Y2hlck91dCwgcG9zdE1hcCApO1xuXHRcdFx0cG9zdEZpbHRlciggdGVtcCwgW10sIGNvbnRleHQsIHhtbCApO1xuXG5cdFx0XHQvLyBVbi1tYXRjaCBmYWlsaW5nIGVsZW1lbnRzIGJ5IG1vdmluZyB0aGVtIGJhY2sgdG8gbWF0Y2hlckluXG5cdFx0XHRpID0gdGVtcC5sZW5ndGg7XG5cdFx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdFx0aWYgKCAoZWxlbSA9IHRlbXBbaV0pICkge1xuXHRcdFx0XHRcdG1hdGNoZXJPdXRbIHBvc3RNYXBbaV0gXSA9ICEobWF0Y2hlckluWyBwb3N0TWFwW2ldIF0gPSBlbGVtKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdGlmICggc2VlZCApIHtcblx0XHRcdGlmICggcG9zdEZpbmRlciB8fCBwcmVGaWx0ZXIgKSB7XG5cdFx0XHRcdGlmICggcG9zdEZpbmRlciApIHtcblx0XHRcdFx0XHQvLyBHZXQgdGhlIGZpbmFsIG1hdGNoZXJPdXQgYnkgY29uZGVuc2luZyB0aGlzIGludGVybWVkaWF0ZSBpbnRvIHBvc3RGaW5kZXIgY29udGV4dHNcblx0XHRcdFx0XHR0ZW1wID0gW107XG5cdFx0XHRcdFx0aSA9IG1hdGNoZXJPdXQubGVuZ3RoO1xuXHRcdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdFx0aWYgKCAoZWxlbSA9IG1hdGNoZXJPdXRbaV0pICkge1xuXHRcdFx0XHRcdFx0XHQvLyBSZXN0b3JlIG1hdGNoZXJJbiBzaW5jZSBlbGVtIGlzIG5vdCB5ZXQgYSBmaW5hbCBtYXRjaFxuXHRcdFx0XHRcdFx0XHR0ZW1wLnB1c2goIChtYXRjaGVySW5baV0gPSBlbGVtKSApO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRwb3N0RmluZGVyKCBudWxsLCAobWF0Y2hlck91dCA9IFtdKSwgdGVtcCwgeG1sICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBNb3ZlIG1hdGNoZWQgZWxlbWVudHMgZnJvbSBzZWVkIHRvIHJlc3VsdHMgdG8ga2VlcCB0aGVtIHN5bmNocm9uaXplZFxuXHRcdFx0XHRpID0gbWF0Y2hlck91dC5sZW5ndGg7XG5cdFx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRcdGlmICggKGVsZW0gPSBtYXRjaGVyT3V0W2ldKSAmJlxuXHRcdFx0XHRcdFx0KHRlbXAgPSBwb3N0RmluZGVyID8gaW5kZXhPZiggc2VlZCwgZWxlbSApIDogcHJlTWFwW2ldKSA+IC0xICkge1xuXG5cdFx0XHRcdFx0XHRzZWVkW3RlbXBdID0gIShyZXN1bHRzW3RlbXBdID0gZWxlbSk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHQvLyBBZGQgZWxlbWVudHMgdG8gcmVzdWx0cywgdGhyb3VnaCBwb3N0RmluZGVyIGlmIGRlZmluZWRcblx0XHR9IGVsc2Uge1xuXHRcdFx0bWF0Y2hlck91dCA9IGNvbmRlbnNlKFxuXHRcdFx0XHRtYXRjaGVyT3V0ID09PSByZXN1bHRzID9cblx0XHRcdFx0XHRtYXRjaGVyT3V0LnNwbGljZSggcHJlZXhpc3RpbmcsIG1hdGNoZXJPdXQubGVuZ3RoICkgOlxuXHRcdFx0XHRcdG1hdGNoZXJPdXRcblx0XHRcdCk7XG5cdFx0XHRpZiAoIHBvc3RGaW5kZXIgKSB7XG5cdFx0XHRcdHBvc3RGaW5kZXIoIG51bGwsIHJlc3VsdHMsIG1hdGNoZXJPdXQsIHhtbCApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cHVzaC5hcHBseSggcmVzdWx0cywgbWF0Y2hlck91dCApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSk7XG59XG5cbmZ1bmN0aW9uIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMgKSB7XG5cdHZhciBjaGVja0NvbnRleHQsIG1hdGNoZXIsIGosXG5cdFx0bGVuID0gdG9rZW5zLmxlbmd0aCxcblx0XHRsZWFkaW5nUmVsYXRpdmUgPSBFeHByLnJlbGF0aXZlWyB0b2tlbnNbMF0udHlwZSBdLFxuXHRcdGltcGxpY2l0UmVsYXRpdmUgPSBsZWFkaW5nUmVsYXRpdmUgfHwgRXhwci5yZWxhdGl2ZVtcIiBcIl0sXG5cdFx0aSA9IGxlYWRpbmdSZWxhdGl2ZSA/IDEgOiAwLFxuXG5cdFx0Ly8gVGhlIGZvdW5kYXRpb25hbCBtYXRjaGVyIGVuc3VyZXMgdGhhdCBlbGVtZW50cyBhcmUgcmVhY2hhYmxlIGZyb20gdG9wLWxldmVsIGNvbnRleHQocylcblx0XHRtYXRjaENvbnRleHQgPSBhZGRDb21iaW5hdG9yKCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtID09PSBjaGVja0NvbnRleHQ7XG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxuXHRcdG1hdGNoQW55Q29udGV4dCA9IGFkZENvbWJpbmF0b3IoIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGluZGV4T2YoIGNoZWNrQ29udGV4dCwgZWxlbSApID4gLTE7XG5cdFx0fSwgaW1wbGljaXRSZWxhdGl2ZSwgdHJ1ZSApLFxuXHRcdG1hdGNoZXJzID0gWyBmdW5jdGlvbiggZWxlbSwgY29udGV4dCwgeG1sICkge1xuXHRcdFx0dmFyIHJldCA9ICggIWxlYWRpbmdSZWxhdGl2ZSAmJiAoIHhtbCB8fCBjb250ZXh0ICE9PSBvdXRlcm1vc3RDb250ZXh0ICkgKSB8fCAoXG5cdFx0XHRcdChjaGVja0NvbnRleHQgPSBjb250ZXh0KS5ub2RlVHlwZSA/XG5cdFx0XHRcdFx0bWF0Y2hDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSA6XG5cdFx0XHRcdFx0bWF0Y2hBbnlDb250ZXh0KCBlbGVtLCBjb250ZXh0LCB4bWwgKSApO1xuXHRcdFx0Ly8gQXZvaWQgaGFuZ2luZyBvbnRvIGVsZW1lbnQgKGlzc3VlICMyOTkpXG5cdFx0XHRjaGVja0NvbnRleHQgPSBudWxsO1xuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9IF07XG5cblx0Zm9yICggOyBpIDwgbGVuOyBpKysgKSB7XG5cdFx0aWYgKCAobWF0Y2hlciA9IEV4cHIucmVsYXRpdmVbIHRva2Vuc1tpXS50eXBlIF0pICkge1xuXHRcdFx0bWF0Y2hlcnMgPSBbIGFkZENvbWJpbmF0b3IoZWxlbWVudE1hdGNoZXIoIG1hdGNoZXJzICksIG1hdGNoZXIpIF07XG5cdFx0fSBlbHNlIHtcblx0XHRcdG1hdGNoZXIgPSBFeHByLmZpbHRlclsgdG9rZW5zW2ldLnR5cGUgXS5hcHBseSggbnVsbCwgdG9rZW5zW2ldLm1hdGNoZXMgKTtcblxuXHRcdFx0Ly8gUmV0dXJuIHNwZWNpYWwgdXBvbiBzZWVpbmcgYSBwb3NpdGlvbmFsIG1hdGNoZXJcblx0XHRcdGlmICggbWF0Y2hlclsgZXhwYW5kbyBdICkge1xuXHRcdFx0XHQvLyBGaW5kIHRoZSBuZXh0IHJlbGF0aXZlIG9wZXJhdG9yIChpZiBhbnkpIGZvciBwcm9wZXIgaGFuZGxpbmdcblx0XHRcdFx0aiA9ICsraTtcblx0XHRcdFx0Zm9yICggOyBqIDwgbGVuOyBqKysgKSB7XG5cdFx0XHRcdFx0aWYgKCBFeHByLnJlbGF0aXZlWyB0b2tlbnNbal0udHlwZSBdICkge1xuXHRcdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiBzZXRNYXRjaGVyKFxuXHRcdFx0XHRcdGkgPiAxICYmIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApLFxuXHRcdFx0XHRcdGkgPiAxICYmIHRvU2VsZWN0b3IoXG5cdFx0XHRcdFx0XHQvLyBJZiB0aGUgcHJlY2VkaW5nIHRva2VuIHdhcyBhIGRlc2NlbmRhbnQgY29tYmluYXRvciwgaW5zZXJ0IGFuIGltcGxpY2l0IGFueS1lbGVtZW50IGAqYFxuXHRcdFx0XHRcdFx0dG9rZW5zLnNsaWNlKCAwLCBpIC0gMSApLmNvbmNhdCh7IHZhbHVlOiB0b2tlbnNbIGkgLSAyIF0udHlwZSA9PT0gXCIgXCIgPyBcIipcIiA6IFwiXCIgfSlcblx0XHRcdFx0XHQpLnJlcGxhY2UoIHJ0cmltLCBcIiQxXCIgKSxcblx0XHRcdFx0XHRtYXRjaGVyLFxuXHRcdFx0XHRcdGkgPCBqICYmIG1hdGNoZXJGcm9tVG9rZW5zKCB0b2tlbnMuc2xpY2UoIGksIGogKSApLFxuXHRcdFx0XHRcdGogPCBsZW4gJiYgbWF0Y2hlckZyb21Ub2tlbnMoICh0b2tlbnMgPSB0b2tlbnMuc2xpY2UoIGogKSkgKSxcblx0XHRcdFx0XHRqIDwgbGVuICYmIHRvU2VsZWN0b3IoIHRva2VucyApXG5cdFx0XHRcdCk7XG5cdFx0XHR9XG5cdFx0XHRtYXRjaGVycy5wdXNoKCBtYXRjaGVyICk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW1lbnRNYXRjaGVyKCBtYXRjaGVycyApO1xufVxuXG5mdW5jdGlvbiBtYXRjaGVyRnJvbUdyb3VwTWF0Y2hlcnMoIGVsZW1lbnRNYXRjaGVycywgc2V0TWF0Y2hlcnMgKSB7XG5cdHZhciBieVNldCA9IHNldE1hdGNoZXJzLmxlbmd0aCA+IDAsXG5cdFx0YnlFbGVtZW50ID0gZWxlbWVudE1hdGNoZXJzLmxlbmd0aCA+IDAsXG5cdFx0c3VwZXJNYXRjaGVyID0gZnVuY3Rpb24oIHNlZWQsIGNvbnRleHQsIHhtbCwgcmVzdWx0cywgb3V0ZXJtb3N0ICkge1xuXHRcdFx0dmFyIGVsZW0sIGosIG1hdGNoZXIsXG5cdFx0XHRcdG1hdGNoZWRDb3VudCA9IDAsXG5cdFx0XHRcdGkgPSBcIjBcIixcblx0XHRcdFx0dW5tYXRjaGVkID0gc2VlZCAmJiBbXSxcblx0XHRcdFx0c2V0TWF0Y2hlZCA9IFtdLFxuXHRcdFx0XHRjb250ZXh0QmFja3VwID0gb3V0ZXJtb3N0Q29udGV4dCxcblx0XHRcdFx0Ly8gV2UgbXVzdCBhbHdheXMgaGF2ZSBlaXRoZXIgc2VlZCBlbGVtZW50cyBvciBvdXRlcm1vc3QgY29udGV4dFxuXHRcdFx0XHRlbGVtcyA9IHNlZWQgfHwgYnlFbGVtZW50ICYmIEV4cHIuZmluZFtcIlRBR1wiXSggXCIqXCIsIG91dGVybW9zdCApLFxuXHRcdFx0XHQvLyBVc2UgaW50ZWdlciBkaXJydW5zIGlmZiB0aGlzIGlzIHRoZSBvdXRlcm1vc3QgbWF0Y2hlclxuXHRcdFx0XHRkaXJydW5zVW5pcXVlID0gKGRpcnJ1bnMgKz0gY29udGV4dEJhY2t1cCA9PSBudWxsID8gMSA6IE1hdGgucmFuZG9tKCkgfHwgMC4xKSxcblx0XHRcdFx0bGVuID0gZWxlbXMubGVuZ3RoO1xuXG5cdFx0XHRpZiAoIG91dGVybW9zdCApIHtcblx0XHRcdFx0b3V0ZXJtb3N0Q29udGV4dCA9IGNvbnRleHQgIT09IGRvY3VtZW50ICYmIGNvbnRleHQ7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCBlbGVtZW50cyBwYXNzaW5nIGVsZW1lbnRNYXRjaGVycyBkaXJlY3RseSB0byByZXN1bHRzXG5cdFx0XHQvLyBLZWVwIGBpYCBhIHN0cmluZyBpZiB0aGVyZSBhcmUgbm8gZWxlbWVudHMgc28gYG1hdGNoZWRDb3VudGAgd2lsbCBiZSBcIjAwXCIgYmVsb3dcblx0XHRcdC8vIFN1cHBvcnQ6IElFPDksIFNhZmFyaVxuXHRcdFx0Ly8gVG9sZXJhdGUgTm9kZUxpc3QgcHJvcGVydGllcyAoSUU6IFwibGVuZ3RoXCI7IFNhZmFyaTogPG51bWJlcj4pIG1hdGNoaW5nIGVsZW1lbnRzIGJ5IGlkXG5cdFx0XHRmb3IgKCA7IGkgIT09IGxlbiAmJiAoZWxlbSA9IGVsZW1zW2ldKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRcdGlmICggYnlFbGVtZW50ICYmIGVsZW0gKSB7XG5cdFx0XHRcdFx0aiA9IDA7XG5cdFx0XHRcdFx0d2hpbGUgKCAobWF0Y2hlciA9IGVsZW1lbnRNYXRjaGVyc1tqKytdKSApIHtcblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlciggZWxlbSwgY29udGV4dCwgeG1sICkgKSB7XG5cdFx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBvdXRlcm1vc3QgKSB7XG5cdFx0XHRcdFx0XHRkaXJydW5zID0gZGlycnVuc1VuaXF1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBUcmFjayB1bm1hdGNoZWQgZWxlbWVudHMgZm9yIHNldCBmaWx0ZXJzXG5cdFx0XHRcdGlmICggYnlTZXQgKSB7XG5cdFx0XHRcdFx0Ly8gVGhleSB3aWxsIGhhdmUgZ29uZSB0aHJvdWdoIGFsbCBwb3NzaWJsZSBtYXRjaGVyc1xuXHRcdFx0XHRcdGlmICggKGVsZW0gPSAhbWF0Y2hlciAmJiBlbGVtKSApIHtcblx0XHRcdFx0XHRcdG1hdGNoZWRDb3VudC0tO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIExlbmd0aGVuIHRoZSBhcnJheSBmb3IgZXZlcnkgZWxlbWVudCwgbWF0Y2hlZCBvciBub3Rcblx0XHRcdFx0XHRpZiAoIHNlZWQgKSB7XG5cdFx0XHRcdFx0XHR1bm1hdGNoZWQucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBBcHBseSBzZXQgZmlsdGVycyB0byB1bm1hdGNoZWQgZWxlbWVudHNcblx0XHRcdG1hdGNoZWRDb3VudCArPSBpO1xuXHRcdFx0aWYgKCBieVNldCAmJiBpICE9PSBtYXRjaGVkQ291bnQgKSB7XG5cdFx0XHRcdGogPSAwO1xuXHRcdFx0XHR3aGlsZSAoIChtYXRjaGVyID0gc2V0TWF0Y2hlcnNbaisrXSkgKSB7XG5cdFx0XHRcdFx0bWF0Y2hlciggdW5tYXRjaGVkLCBzZXRNYXRjaGVkLCBjb250ZXh0LCB4bWwgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdGlmICggc2VlZCApIHtcblx0XHRcdFx0XHQvLyBSZWludGVncmF0ZSBlbGVtZW50IG1hdGNoZXMgdG8gZWxpbWluYXRlIHRoZSBuZWVkIGZvciBzb3J0aW5nXG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVkQ291bnQgPiAwICkge1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggISh1bm1hdGNoZWRbaV0gfHwgc2V0TWF0Y2hlZFtpXSkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0c2V0TWF0Y2hlZFtpXSA9IHBvcC5jYWxsKCByZXN1bHRzICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBEaXNjYXJkIGluZGV4IHBsYWNlaG9sZGVyIHZhbHVlcyB0byBnZXQgb25seSBhY3R1YWwgbWF0Y2hlc1xuXHRcdFx0XHRcdHNldE1hdGNoZWQgPSBjb25kZW5zZSggc2V0TWF0Y2hlZCApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQWRkIG1hdGNoZXMgdG8gcmVzdWx0c1xuXHRcdFx0XHRwdXNoLmFwcGx5KCByZXN1bHRzLCBzZXRNYXRjaGVkICk7XG5cblx0XHRcdFx0Ly8gU2VlZGxlc3Mgc2V0IG1hdGNoZXMgc3VjY2VlZGluZyBtdWx0aXBsZSBzdWNjZXNzZnVsIG1hdGNoZXJzIHN0aXB1bGF0ZSBzb3J0aW5nXG5cdFx0XHRcdGlmICggb3V0ZXJtb3N0ICYmICFzZWVkICYmIHNldE1hdGNoZWQubGVuZ3RoID4gMCAmJlxuXHRcdFx0XHRcdCggbWF0Y2hlZENvdW50ICsgc2V0TWF0Y2hlcnMubGVuZ3RoICkgPiAxICkge1xuXG5cdFx0XHRcdFx0U2l6emxlLnVuaXF1ZVNvcnQoIHJlc3VsdHMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBPdmVycmlkZSBtYW5pcHVsYXRpb24gb2YgZ2xvYmFscyBieSBuZXN0ZWQgbWF0Y2hlcnNcblx0XHRcdGlmICggb3V0ZXJtb3N0ICkge1xuXHRcdFx0XHRkaXJydW5zID0gZGlycnVuc1VuaXF1ZTtcblx0XHRcdFx0b3V0ZXJtb3N0Q29udGV4dCA9IGNvbnRleHRCYWNrdXA7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiB1bm1hdGNoZWQ7XG5cdFx0fTtcblxuXHRyZXR1cm4gYnlTZXQgP1xuXHRcdG1hcmtGdW5jdGlvbiggc3VwZXJNYXRjaGVyICkgOlxuXHRcdHN1cGVyTWF0Y2hlcjtcbn1cblxuY29tcGlsZSA9IFNpenpsZS5jb21waWxlID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBtYXRjaCAvKiBJbnRlcm5hbCBVc2UgT25seSAqLyApIHtcblx0dmFyIGksXG5cdFx0c2V0TWF0Y2hlcnMgPSBbXSxcblx0XHRlbGVtZW50TWF0Y2hlcnMgPSBbXSxcblx0XHRjYWNoZWQgPSBjb21waWxlckNhY2hlWyBzZWxlY3RvciArIFwiIFwiIF07XG5cblx0aWYgKCAhY2FjaGVkICkge1xuXHRcdC8vIEdlbmVyYXRlIGEgZnVuY3Rpb24gb2YgcmVjdXJzaXZlIGZ1bmN0aW9ucyB0aGF0IGNhbiBiZSB1c2VkIHRvIGNoZWNrIGVhY2ggZWxlbWVudFxuXHRcdGlmICggIW1hdGNoICkge1xuXHRcdFx0bWF0Y2ggPSB0b2tlbml6ZSggc2VsZWN0b3IgKTtcblx0XHR9XG5cdFx0aSA9IG1hdGNoLmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdGNhY2hlZCA9IG1hdGNoZXJGcm9tVG9rZW5zKCBtYXRjaFtpXSApO1xuXHRcdFx0aWYgKCBjYWNoZWRbIGV4cGFuZG8gXSApIHtcblx0XHRcdFx0c2V0TWF0Y2hlcnMucHVzaCggY2FjaGVkICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRlbGVtZW50TWF0Y2hlcnMucHVzaCggY2FjaGVkICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FjaGUgdGhlIGNvbXBpbGVkIGZ1bmN0aW9uXG5cdFx0Y2FjaGVkID0gY29tcGlsZXJDYWNoZSggc2VsZWN0b3IsIG1hdGNoZXJGcm9tR3JvdXBNYXRjaGVycyggZWxlbWVudE1hdGNoZXJzLCBzZXRNYXRjaGVycyApICk7XG5cblx0XHQvLyBTYXZlIHNlbGVjdG9yIGFuZCB0b2tlbml6YXRpb25cblx0XHRjYWNoZWQuc2VsZWN0b3IgPSBzZWxlY3Rvcjtcblx0fVxuXHRyZXR1cm4gY2FjaGVkO1xufTtcblxuLyoqXG4gKiBBIGxvdy1sZXZlbCBzZWxlY3Rpb24gZnVuY3Rpb24gdGhhdCB3b3JrcyB3aXRoIFNpenpsZSdzIGNvbXBpbGVkXG4gKiAgc2VsZWN0b3IgZnVuY3Rpb25zXG4gKiBAcGFyYW0ge1N0cmluZ3xGdW5jdGlvbn0gc2VsZWN0b3IgQSBzZWxlY3RvciBvciBhIHByZS1jb21waWxlZFxuICogIHNlbGVjdG9yIGZ1bmN0aW9uIGJ1aWx0IHdpdGggU2l6emxlLmNvbXBpbGVcbiAqIEBwYXJhbSB7RWxlbWVudH0gY29udGV4dFxuICogQHBhcmFtIHtBcnJheX0gW3Jlc3VsdHNdXG4gKiBAcGFyYW0ge0FycmF5fSBbc2VlZF0gQSBzZXQgb2YgZWxlbWVudHMgdG8gbWF0Y2ggYWdhaW5zdFxuICovXG5zZWxlY3QgPSBTaXp6bGUuc2VsZWN0ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0LCByZXN1bHRzLCBzZWVkICkge1xuXHR2YXIgaSwgdG9rZW5zLCB0b2tlbiwgdHlwZSwgZmluZCxcblx0XHRjb21waWxlZCA9IHR5cGVvZiBzZWxlY3RvciA9PT0gXCJmdW5jdGlvblwiICYmIHNlbGVjdG9yLFxuXHRcdG1hdGNoID0gIXNlZWQgJiYgdG9rZW5pemUoIChzZWxlY3RvciA9IGNvbXBpbGVkLnNlbGVjdG9yIHx8IHNlbGVjdG9yKSApO1xuXG5cdHJlc3VsdHMgPSByZXN1bHRzIHx8IFtdO1xuXG5cdC8vIFRyeSB0byBtaW5pbWl6ZSBvcGVyYXRpb25zIGlmIHRoZXJlIGlzIG5vIHNlZWQgYW5kIG9ubHkgb25lIGdyb3VwXG5cdGlmICggbWF0Y2gubGVuZ3RoID09PSAxICkge1xuXG5cdFx0Ly8gVGFrZSBhIHNob3J0Y3V0IGFuZCBzZXQgdGhlIGNvbnRleHQgaWYgdGhlIHJvb3Qgc2VsZWN0b3IgaXMgYW4gSURcblx0XHR0b2tlbnMgPSBtYXRjaFswXSA9IG1hdGNoWzBdLnNsaWNlKCAwICk7XG5cdFx0aWYgKCB0b2tlbnMubGVuZ3RoID4gMiAmJiAodG9rZW4gPSB0b2tlbnNbMF0pLnR5cGUgPT09IFwiSURcIiAmJlxuXHRcdFx0XHRzdXBwb3J0LmdldEJ5SWQgJiYgY29udGV4dC5ub2RlVHlwZSA9PT0gOSAmJiBkb2N1bWVudElzSFRNTCAmJlxuXHRcdFx0XHRFeHByLnJlbGF0aXZlWyB0b2tlbnNbMV0udHlwZSBdICkge1xuXG5cdFx0XHRjb250ZXh0ID0gKCBFeHByLmZpbmRbXCJJRFwiXSggdG9rZW4ubWF0Y2hlc1swXS5yZXBsYWNlKHJ1bmVzY2FwZSwgZnVuZXNjYXBlKSwgY29udGV4dCApIHx8IFtdIClbMF07XG5cdFx0XHRpZiAoICFjb250ZXh0ICkge1xuXHRcdFx0XHRyZXR1cm4gcmVzdWx0cztcblxuXHRcdFx0Ly8gUHJlY29tcGlsZWQgbWF0Y2hlcnMgd2lsbCBzdGlsbCB2ZXJpZnkgYW5jZXN0cnksIHNvIHN0ZXAgdXAgYSBsZXZlbFxuXHRcdFx0fSBlbHNlIGlmICggY29tcGlsZWQgKSB7XG5cdFx0XHRcdGNvbnRleHQgPSBjb250ZXh0LnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cblx0XHRcdHNlbGVjdG9yID0gc2VsZWN0b3Iuc2xpY2UoIHRva2Vucy5zaGlmdCgpLnZhbHVlLmxlbmd0aCApO1xuXHRcdH1cblxuXHRcdC8vIEZldGNoIGEgc2VlZCBzZXQgZm9yIHJpZ2h0LXRvLWxlZnQgbWF0Y2hpbmdcblx0XHRpID0gbWF0Y2hFeHByW1wibmVlZHNDb250ZXh0XCJdLnRlc3QoIHNlbGVjdG9yICkgPyAwIDogdG9rZW5zLmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdHRva2VuID0gdG9rZW5zW2ldO1xuXG5cdFx0XHQvLyBBYm9ydCBpZiB3ZSBoaXQgYSBjb21iaW5hdG9yXG5cdFx0XHRpZiAoIEV4cHIucmVsYXRpdmVbICh0eXBlID0gdG9rZW4udHlwZSkgXSApIHtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIChmaW5kID0gRXhwci5maW5kWyB0eXBlIF0pICkge1xuXHRcdFx0XHQvLyBTZWFyY2gsIGV4cGFuZGluZyBjb250ZXh0IGZvciBsZWFkaW5nIHNpYmxpbmcgY29tYmluYXRvcnNcblx0XHRcdFx0aWYgKCAoc2VlZCA9IGZpbmQoXG5cdFx0XHRcdFx0dG9rZW4ubWF0Y2hlc1swXS5yZXBsYWNlKCBydW5lc2NhcGUsIGZ1bmVzY2FwZSApLFxuXHRcdFx0XHRcdHJzaWJsaW5nLnRlc3QoIHRva2Vuc1swXS50eXBlICkgJiYgdGVzdENvbnRleHQoIGNvbnRleHQucGFyZW50Tm9kZSApIHx8IGNvbnRleHRcblx0XHRcdFx0KSkgKSB7XG5cblx0XHRcdFx0XHQvLyBJZiBzZWVkIGlzIGVtcHR5IG9yIG5vIHRva2VucyByZW1haW4sIHdlIGNhbiByZXR1cm4gZWFybHlcblx0XHRcdFx0XHR0b2tlbnMuc3BsaWNlKCBpLCAxICk7XG5cdFx0XHRcdFx0c2VsZWN0b3IgPSBzZWVkLmxlbmd0aCAmJiB0b1NlbGVjdG9yKCB0b2tlbnMgKTtcblx0XHRcdFx0XHRpZiAoICFzZWxlY3RvciApIHtcblx0XHRcdFx0XHRcdHB1c2guYXBwbHkoIHJlc3VsdHMsIHNlZWQgKTtcblx0XHRcdFx0XHRcdHJldHVybiByZXN1bHRzO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ29tcGlsZSBhbmQgZXhlY3V0ZSBhIGZpbHRlcmluZyBmdW5jdGlvbiBpZiBvbmUgaXMgbm90IHByb3ZpZGVkXG5cdC8vIFByb3ZpZGUgYG1hdGNoYCB0byBhdm9pZCByZXRva2VuaXphdGlvbiBpZiB3ZSBtb2RpZmllZCB0aGUgc2VsZWN0b3IgYWJvdmVcblx0KCBjb21waWxlZCB8fCBjb21waWxlKCBzZWxlY3RvciwgbWF0Y2ggKSApKFxuXHRcdHNlZWQsXG5cdFx0Y29udGV4dCxcblx0XHQhZG9jdW1lbnRJc0hUTUwsXG5cdFx0cmVzdWx0cyxcblx0XHRyc2libGluZy50ZXN0KCBzZWxlY3RvciApICYmIHRlc3RDb250ZXh0KCBjb250ZXh0LnBhcmVudE5vZGUgKSB8fCBjb250ZXh0XG5cdCk7XG5cdHJldHVybiByZXN1bHRzO1xufTtcblxuLy8gT25lLXRpbWUgYXNzaWdubWVudHNcblxuLy8gU29ydCBzdGFiaWxpdHlcbnN1cHBvcnQuc29ydFN0YWJsZSA9IGV4cGFuZG8uc3BsaXQoXCJcIikuc29ydCggc29ydE9yZGVyICkuam9pbihcIlwiKSA9PT0gZXhwYW5kbztcblxuLy8gU3VwcG9ydDogQ2hyb21lIDE0LTM1K1xuLy8gQWx3YXlzIGFzc3VtZSBkdXBsaWNhdGVzIGlmIHRoZXkgYXJlbid0IHBhc3NlZCB0byB0aGUgY29tcGFyaXNvbiBmdW5jdGlvblxuc3VwcG9ydC5kZXRlY3REdXBsaWNhdGVzID0gISFoYXNEdXBsaWNhdGU7XG5cbi8vIEluaXRpYWxpemUgYWdhaW5zdCB0aGUgZGVmYXVsdCBkb2N1bWVudFxuc2V0RG9jdW1lbnQoKTtcblxuLy8gU3VwcG9ydDogV2Via2l0PDUzNy4zMiAtIFNhZmFyaSA2LjAuMy9DaHJvbWUgMjUgKGZpeGVkIGluIENocm9tZSAyNylcbi8vIERldGFjaGVkIG5vZGVzIGNvbmZvdW5kaW5nbHkgZm9sbG93ICplYWNoIG90aGVyKlxuc3VwcG9ydC5zb3J0RGV0YWNoZWQgPSBhc3NlcnQoZnVuY3Rpb24oIGRpdjEgKSB7XG5cdC8vIFNob3VsZCByZXR1cm4gMSwgYnV0IHJldHVybnMgNCAoZm9sbG93aW5nKVxuXHRyZXR1cm4gZGl2MS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbiggZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImRpdlwiKSApICYgMTtcbn0pO1xuXG4vLyBTdXBwb3J0OiBJRTw4XG4vLyBQcmV2ZW50IGF0dHJpYnV0ZS9wcm9wZXJ0eSBcImludGVycG9sYXRpb25cIlxuLy8gaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNTM2NDI5JTI4VlMuODUlMjkuYXNweFxuaWYgKCAhYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdGRpdi5pbm5lckhUTUwgPSBcIjxhIGhyZWY9JyMnPjwvYT5cIjtcblx0cmV0dXJuIGRpdi5maXJzdENoaWxkLmdldEF0dHJpYnV0ZShcImhyZWZcIikgPT09IFwiI1wiIDtcbn0pICkge1xuXHRhZGRIYW5kbGUoIFwidHlwZXxocmVmfGhlaWdodHx3aWR0aFwiLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0aWYgKCAhaXNYTUwgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoIG5hbWUsIG5hbWUudG9Mb3dlckNhc2UoKSA9PT0gXCJ0eXBlXCIgPyAxIDogMiApO1xuXHRcdH1cblx0fSk7XG59XG5cbi8vIFN1cHBvcnQ6IElFPDlcbi8vIFVzZSBkZWZhdWx0VmFsdWUgaW4gcGxhY2Ugb2YgZ2V0QXR0cmlidXRlKFwidmFsdWVcIilcbmlmICggIXN1cHBvcnQuYXR0cmlidXRlcyB8fCAhYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdGRpdi5pbm5lckhUTUwgPSBcIjxpbnB1dC8+XCI7XG5cdGRpdi5maXJzdENoaWxkLnNldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiLCBcIlwiICk7XG5cdHJldHVybiBkaXYuZmlyc3RDaGlsZC5nZXRBdHRyaWJ1dGUoIFwidmFsdWVcIiApID09PSBcIlwiO1xufSkgKSB7XG5cdGFkZEhhbmRsZSggXCJ2YWx1ZVwiLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0aWYgKCAhaXNYTUwgJiYgZWxlbS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpID09PSBcImlucHV0XCIgKSB7XG5cdFx0XHRyZXR1cm4gZWxlbS5kZWZhdWx0VmFsdWU7XG5cdFx0fVxuXHR9KTtcbn1cblxuLy8gU3VwcG9ydDogSUU8OVxuLy8gVXNlIGdldEF0dHJpYnV0ZU5vZGUgdG8gZmV0Y2ggYm9vbGVhbnMgd2hlbiBnZXRBdHRyaWJ1dGUgbGllc1xuaWYgKCAhYXNzZXJ0KGZ1bmN0aW9uKCBkaXYgKSB7XG5cdHJldHVybiBkaXYuZ2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIikgPT0gbnVsbDtcbn0pICkge1xuXHRhZGRIYW5kbGUoIGJvb2xlYW5zLCBmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0dmFyIHZhbDtcblx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdHJldHVybiBlbGVtWyBuYW1lIF0gPT09IHRydWUgPyBuYW1lLnRvTG93ZXJDYXNlKCkgOlxuXHRcdFx0XHRcdCh2YWwgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIG5hbWUgKSkgJiYgdmFsLnNwZWNpZmllZCA/XG5cdFx0XHRcdFx0dmFsLnZhbHVlIDpcblx0XHRcdFx0bnVsbDtcblx0XHR9XG5cdH0pO1xufVxuXG5yZXR1cm4gU2l6emxlO1xuXG59KSggd2luZG93ICk7XG5cblxuXG5qUXVlcnkuZmluZCA9IFNpenpsZTtcbmpRdWVyeS5leHByID0gU2l6emxlLnNlbGVjdG9ycztcbmpRdWVyeS5leHByW1wiOlwiXSA9IGpRdWVyeS5leHByLnBzZXVkb3M7XG5qUXVlcnkudW5pcXVlID0gU2l6emxlLnVuaXF1ZVNvcnQ7XG5qUXVlcnkudGV4dCA9IFNpenpsZS5nZXRUZXh0O1xualF1ZXJ5LmlzWE1MRG9jID0gU2l6emxlLmlzWE1MO1xualF1ZXJ5LmNvbnRhaW5zID0gU2l6emxlLmNvbnRhaW5zO1xuXG5cblxudmFyIHJuZWVkc0NvbnRleHQgPSBqUXVlcnkuZXhwci5tYXRjaC5uZWVkc0NvbnRleHQ7XG5cbnZhciByc2luZ2xlVGFnID0gKC9ePChcXHcrKVxccypcXC8/Pig/OjxcXC9cXDE+fCkkLyk7XG5cblxuXG52YXIgcmlzU2ltcGxlID0gL14uW146I1xcW1xcLixdKiQvO1xuXG4vLyBJbXBsZW1lbnQgdGhlIGlkZW50aWNhbCBmdW5jdGlvbmFsaXR5IGZvciBmaWx0ZXIgYW5kIG5vdFxuZnVuY3Rpb24gd2lubm93KCBlbGVtZW50cywgcXVhbGlmaWVyLCBub3QgKSB7XG5cdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHF1YWxpZmllciApICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtLCBpICkge1xuXHRcdFx0LyoganNoaW50IC1XMDE4ICovXG5cdFx0XHRyZXR1cm4gISFxdWFsaWZpZXIuY2FsbCggZWxlbSwgaSwgZWxlbSApICE9PSBub3Q7XG5cdFx0fSk7XG5cblx0fVxuXG5cdGlmICggcXVhbGlmaWVyLm5vZGVUeXBlICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuICggZWxlbSA9PT0gcXVhbGlmaWVyICkgIT09IG5vdDtcblx0XHR9KTtcblxuXHR9XG5cblx0aWYgKCB0eXBlb2YgcXVhbGlmaWVyID09PSBcInN0cmluZ1wiICkge1xuXHRcdGlmICggcmlzU2ltcGxlLnRlc3QoIHF1YWxpZmllciApICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5maWx0ZXIoIHF1YWxpZmllciwgZWxlbWVudHMsIG5vdCApO1xuXHRcdH1cblxuXHRcdHF1YWxpZmllciA9IGpRdWVyeS5maWx0ZXIoIHF1YWxpZmllciwgZWxlbWVudHMgKTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnkuZ3JlcCggZWxlbWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiAoIGpRdWVyeS5pbkFycmF5KCBlbGVtLCBxdWFsaWZpZXIgKSA+PSAwICkgIT09IG5vdDtcblx0fSk7XG59XG5cbmpRdWVyeS5maWx0ZXIgPSBmdW5jdGlvbiggZXhwciwgZWxlbXMsIG5vdCApIHtcblx0dmFyIGVsZW0gPSBlbGVtc1sgMCBdO1xuXG5cdGlmICggbm90ICkge1xuXHRcdGV4cHIgPSBcIjpub3QoXCIgKyBleHByICsgXCIpXCI7XG5cdH1cblxuXHRyZXR1cm4gZWxlbXMubGVuZ3RoID09PSAxICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgP1xuXHRcdGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvciggZWxlbSwgZXhwciApID8gWyBlbGVtIF0gOiBbXSA6XG5cdFx0alF1ZXJ5LmZpbmQubWF0Y2hlcyggZXhwciwgalF1ZXJ5LmdyZXAoIGVsZW1zLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHJldHVybiBlbGVtLm5vZGVUeXBlID09PSAxO1xuXHRcdH0pKTtcbn07XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRmaW5kOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGksXG5cdFx0XHRyZXQgPSBbXSxcblx0XHRcdHNlbGYgPSB0aGlzLFxuXHRcdFx0bGVuID0gc2VsZi5sZW5ndGg7XG5cblx0XHRpZiAoIHR5cGVvZiBzZWxlY3RvciAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggalF1ZXJ5KCBzZWxlY3RvciApLmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggc2VsZlsgaSBdLCB0aGlzICkgKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0pICk7XG5cdFx0fVxuXG5cdFx0Zm9yICggaSA9IDA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdGpRdWVyeS5maW5kKCBzZWxlY3Rvciwgc2VsZlsgaSBdLCByZXQgKTtcblx0XHR9XG5cblx0XHQvLyBOZWVkZWQgYmVjYXVzZSAkKCBzZWxlY3RvciwgY29udGV4dCApIGJlY29tZXMgJCggY29udGV4dCApLmZpbmQoIHNlbGVjdG9yIClcblx0XHRyZXQgPSB0aGlzLnB1c2hTdGFjayggbGVuID4gMSA/IGpRdWVyeS51bmlxdWUoIHJldCApIDogcmV0ICk7XG5cdFx0cmV0LnNlbGVjdG9yID0gdGhpcy5zZWxlY3RvciA/IHRoaXMuc2VsZWN0b3IgKyBcIiBcIiArIHNlbGVjdG9yIDogc2VsZWN0b3I7XG5cdFx0cmV0dXJuIHJldDtcblx0fSxcblx0ZmlsdGVyOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCB3aW5ub3codGhpcywgc2VsZWN0b3IgfHwgW10sIGZhbHNlKSApO1xuXHR9LFxuXHRub3Q6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soIHdpbm5vdyh0aGlzLCBzZWxlY3RvciB8fCBbXSwgdHJ1ZSkgKTtcblx0fSxcblx0aXM6IGZ1bmN0aW9uKCBzZWxlY3RvciApIHtcblx0XHRyZXR1cm4gISF3aW5ub3coXG5cdFx0XHR0aGlzLFxuXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgcG9zaXRpb25hbC9yZWxhdGl2ZSBzZWxlY3RvciwgY2hlY2sgbWVtYmVyc2hpcCBpbiB0aGUgcmV0dXJuZWQgc2V0XG5cdFx0XHQvLyBzbyAkKFwicDpmaXJzdFwiKS5pcyhcInA6bGFzdFwiKSB3b24ndCByZXR1cm4gdHJ1ZSBmb3IgYSBkb2Mgd2l0aCB0d28gXCJwXCIuXG5cdFx0XHR0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCIgJiYgcm5lZWRzQ29udGV4dC50ZXN0KCBzZWxlY3RvciApID9cblx0XHRcdFx0alF1ZXJ5KCBzZWxlY3RvciApIDpcblx0XHRcdFx0c2VsZWN0b3IgfHwgW10sXG5cdFx0XHRmYWxzZVxuXHRcdCkubGVuZ3RoO1xuXHR9XG59KTtcblxuXG4vLyBJbml0aWFsaXplIGEgalF1ZXJ5IG9iamVjdFxuXG5cbi8vIEEgY2VudHJhbCByZWZlcmVuY2UgdG8gdGhlIHJvb3QgalF1ZXJ5KGRvY3VtZW50KVxudmFyIHJvb3RqUXVlcnksXG5cblx0Ly8gVXNlIHRoZSBjb3JyZWN0IGRvY3VtZW50IGFjY29yZGluZ2x5IHdpdGggd2luZG93IGFyZ3VtZW50IChzYW5kYm94KVxuXHRkb2N1bWVudCA9IHdpbmRvdy5kb2N1bWVudCxcblxuXHQvLyBBIHNpbXBsZSB3YXkgdG8gY2hlY2sgZm9yIEhUTUwgc3RyaW5nc1xuXHQvLyBQcmlvcml0aXplICNpZCBvdmVyIDx0YWc+IHRvIGF2b2lkIFhTUyB2aWEgbG9jYXRpb24uaGFzaCAoIzk1MjEpXG5cdC8vIFN0cmljdCBIVE1MIHJlY29nbml0aW9uICgjMTEyOTA6IG11c3Qgc3RhcnQgd2l0aCA8KVxuXHRycXVpY2tFeHByID0gL14oPzpcXHMqKDxbXFx3XFxXXSs+KVtePl0qfCMoW1xcdy1dKikpJC8sXG5cblx0aW5pdCA9IGpRdWVyeS5mbi5pbml0ID0gZnVuY3Rpb24oIHNlbGVjdG9yLCBjb250ZXh0ICkge1xuXHRcdHZhciBtYXRjaCwgZWxlbTtcblxuXHRcdC8vIEhBTkRMRTogJChcIlwiKSwgJChudWxsKSwgJCh1bmRlZmluZWQpLCAkKGZhbHNlKVxuXHRcdGlmICggIXNlbGVjdG9yICkge1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0Ly8gSGFuZGxlIEhUTUwgc3RyaW5nc1xuXHRcdGlmICggdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0aWYgKCBzZWxlY3Rvci5jaGFyQXQoMCkgPT09IFwiPFwiICYmIHNlbGVjdG9yLmNoYXJBdCggc2VsZWN0b3IubGVuZ3RoIC0gMSApID09PSBcIj5cIiAmJiBzZWxlY3Rvci5sZW5ndGggPj0gMyApIHtcblx0XHRcdFx0Ly8gQXNzdW1lIHRoYXQgc3RyaW5ncyB0aGF0IHN0YXJ0IGFuZCBlbmQgd2l0aCA8PiBhcmUgSFRNTCBhbmQgc2tpcCB0aGUgcmVnZXggY2hlY2tcblx0XHRcdFx0bWF0Y2ggPSBbIG51bGwsIHNlbGVjdG9yLCBudWxsIF07XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdG1hdGNoID0gcnF1aWNrRXhwci5leGVjKCBzZWxlY3RvciApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBNYXRjaCBodG1sIG9yIG1ha2Ugc3VyZSBubyBjb250ZXh0IGlzIHNwZWNpZmllZCBmb3IgI2lkXG5cdFx0XHRpZiAoIG1hdGNoICYmIChtYXRjaFsxXSB8fCAhY29udGV4dCkgKSB7XG5cblx0XHRcdFx0Ly8gSEFORExFOiAkKGh0bWwpIC0+ICQoYXJyYXkpXG5cdFx0XHRcdGlmICggbWF0Y2hbMV0gKSB7XG5cdFx0XHRcdFx0Y29udGV4dCA9IGNvbnRleHQgaW5zdGFuY2VvZiBqUXVlcnkgPyBjb250ZXh0WzBdIDogY29udGV4dDtcblxuXHRcdFx0XHRcdC8vIHNjcmlwdHMgaXMgdHJ1ZSBmb3IgYmFjay1jb21wYXRcblx0XHRcdFx0XHQvLyBJbnRlbnRpb25hbGx5IGxldCB0aGUgZXJyb3IgYmUgdGhyb3duIGlmIHBhcnNlSFRNTCBpcyBub3QgcHJlc2VudFxuXHRcdFx0XHRcdGpRdWVyeS5tZXJnZSggdGhpcywgalF1ZXJ5LnBhcnNlSFRNTChcblx0XHRcdFx0XHRcdG1hdGNoWzFdLFxuXHRcdFx0XHRcdFx0Y29udGV4dCAmJiBjb250ZXh0Lm5vZGVUeXBlID8gY29udGV4dC5vd25lckRvY3VtZW50IHx8IGNvbnRleHQgOiBkb2N1bWVudCxcblx0XHRcdFx0XHRcdHRydWVcblx0XHRcdFx0XHQpICk7XG5cblx0XHRcdFx0XHQvLyBIQU5ETEU6ICQoaHRtbCwgcHJvcHMpXG5cdFx0XHRcdFx0aWYgKCByc2luZ2xlVGFnLnRlc3QoIG1hdGNoWzFdICkgJiYgalF1ZXJ5LmlzUGxhaW5PYmplY3QoIGNvbnRleHQgKSApIHtcblx0XHRcdFx0XHRcdGZvciAoIG1hdGNoIGluIGNvbnRleHQgKSB7XG5cdFx0XHRcdFx0XHRcdC8vIFByb3BlcnRpZXMgb2YgY29udGV4dCBhcmUgY2FsbGVkIGFzIG1ldGhvZHMgaWYgcG9zc2libGVcblx0XHRcdFx0XHRcdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggdGhpc1sgbWF0Y2ggXSApICkge1xuXHRcdFx0XHRcdFx0XHRcdHRoaXNbIG1hdGNoIF0oIGNvbnRleHRbIG1hdGNoIF0gKTtcblxuXHRcdFx0XHRcdFx0XHQvLyAuLi5hbmQgb3RoZXJ3aXNlIHNldCBhcyBhdHRyaWJ1dGVzXG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhpcy5hdHRyKCBtYXRjaCwgY29udGV4dFsgbWF0Y2ggXSApO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHRcdFx0Ly8gSEFORExFOiAkKCNpZClcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRlbGVtID0gZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIG1hdGNoWzJdICk7XG5cblx0XHRcdFx0XHQvLyBDaGVjayBwYXJlbnROb2RlIHRvIGNhdGNoIHdoZW4gQmxhY2tiZXJyeSA0LjYgcmV0dXJuc1xuXHRcdFx0XHRcdC8vIG5vZGVzIHRoYXQgYXJlIG5vIGxvbmdlciBpbiB0aGUgZG9jdW1lbnQgIzY5NjNcblx0XHRcdFx0XHRpZiAoIGVsZW0gJiYgZWxlbS5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRcdFx0Ly8gSGFuZGxlIHRoZSBjYXNlIHdoZXJlIElFIGFuZCBPcGVyYSByZXR1cm4gaXRlbXNcblx0XHRcdFx0XHRcdC8vIGJ5IG5hbWUgaW5zdGVhZCBvZiBJRFxuXHRcdFx0XHRcdFx0aWYgKCBlbGVtLmlkICE9PSBtYXRjaFsyXSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHJvb3RqUXVlcnkuZmluZCggc2VsZWN0b3IgKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gT3RoZXJ3aXNlLCB3ZSBpbmplY3QgdGhlIGVsZW1lbnQgZGlyZWN0bHkgaW50byB0aGUgalF1ZXJ5IG9iamVjdFxuXHRcdFx0XHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0XHRcdFx0dGhpc1swXSA9IGVsZW07XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0dGhpcy5jb250ZXh0ID0gZG9jdW1lbnQ7XG5cdFx0XHRcdFx0dGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cblx0XHRcdC8vIEhBTkRMRTogJChleHByLCAkKC4uLikpXG5cdFx0XHR9IGVsc2UgaWYgKCAhY29udGV4dCB8fCBjb250ZXh0LmpxdWVyeSApIHtcblx0XHRcdFx0cmV0dXJuICggY29udGV4dCB8fCByb290alF1ZXJ5ICkuZmluZCggc2VsZWN0b3IgKTtcblxuXHRcdFx0Ly8gSEFORExFOiAkKGV4cHIsIGNvbnRleHQpXG5cdFx0XHQvLyAod2hpY2ggaXMganVzdCBlcXVpdmFsZW50IHRvOiAkKGNvbnRleHQpLmZpbmQoZXhwcilcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiB0aGlzLmNvbnN0cnVjdG9yKCBjb250ZXh0ICkuZmluZCggc2VsZWN0b3IgKTtcblx0XHRcdH1cblxuXHRcdC8vIEhBTkRMRTogJChET01FbGVtZW50KVxuXHRcdH0gZWxzZSBpZiAoIHNlbGVjdG9yLm5vZGVUeXBlICkge1xuXHRcdFx0dGhpcy5jb250ZXh0ID0gdGhpc1swXSA9IHNlbGVjdG9yO1xuXHRcdFx0dGhpcy5sZW5ndGggPSAxO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cblx0XHQvLyBIQU5ETEU6ICQoZnVuY3Rpb24pXG5cdFx0Ly8gU2hvcnRjdXQgZm9yIGRvY3VtZW50IHJlYWR5XG5cdFx0fSBlbHNlIGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHNlbGVjdG9yICkgKSB7XG5cdFx0XHRyZXR1cm4gdHlwZW9mIHJvb3RqUXVlcnkucmVhZHkgIT09IFwidW5kZWZpbmVkXCIgP1xuXHRcdFx0XHRyb290alF1ZXJ5LnJlYWR5KCBzZWxlY3RvciApIDpcblx0XHRcdFx0Ly8gRXhlY3V0ZSBpbW1lZGlhdGVseSBpZiByZWFkeSBpcyBub3QgcHJlc2VudFxuXHRcdFx0XHRzZWxlY3RvciggalF1ZXJ5ICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBzZWxlY3Rvci5zZWxlY3RvciAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dGhpcy5zZWxlY3RvciA9IHNlbGVjdG9yLnNlbGVjdG9yO1xuXHRcdFx0dGhpcy5jb250ZXh0ID0gc2VsZWN0b3IuY29udGV4dDtcblx0XHR9XG5cblx0XHRyZXR1cm4galF1ZXJ5Lm1ha2VBcnJheSggc2VsZWN0b3IsIHRoaXMgKTtcblx0fTtcblxuLy8gR2l2ZSB0aGUgaW5pdCBmdW5jdGlvbiB0aGUgalF1ZXJ5IHByb3RvdHlwZSBmb3IgbGF0ZXIgaW5zdGFudGlhdGlvblxuaW5pdC5wcm90b3R5cGUgPSBqUXVlcnkuZm47XG5cbi8vIEluaXRpYWxpemUgY2VudHJhbCByZWZlcmVuY2VcbnJvb3RqUXVlcnkgPSBqUXVlcnkoIGRvY3VtZW50ICk7XG5cblxudmFyIHJwYXJlbnRzcHJldiA9IC9eKD86cGFyZW50c3xwcmV2KD86VW50aWx8QWxsKSkvLFxuXHQvLyBtZXRob2RzIGd1YXJhbnRlZWQgdG8gcHJvZHVjZSBhIHVuaXF1ZSBzZXQgd2hlbiBzdGFydGluZyBmcm9tIGEgdW5pcXVlIHNldFxuXHRndWFyYW50ZWVkVW5pcXVlID0ge1xuXHRcdGNoaWxkcmVuOiB0cnVlLFxuXHRcdGNvbnRlbnRzOiB0cnVlLFxuXHRcdG5leHQ6IHRydWUsXG5cdFx0cHJldjogdHJ1ZVxuXHR9O1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0ZGlyOiBmdW5jdGlvbiggZWxlbSwgZGlyLCB1bnRpbCApIHtcblx0XHR2YXIgbWF0Y2hlZCA9IFtdLFxuXHRcdFx0Y3VyID0gZWxlbVsgZGlyIF07XG5cblx0XHR3aGlsZSAoIGN1ciAmJiBjdXIubm9kZVR5cGUgIT09IDkgJiYgKHVudGlsID09PSB1bmRlZmluZWQgfHwgY3VyLm5vZGVUeXBlICE9PSAxIHx8ICFqUXVlcnkoIGN1ciApLmlzKCB1bnRpbCApKSApIHtcblx0XHRcdGlmICggY3VyLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRtYXRjaGVkLnB1c2goIGN1ciApO1xuXHRcdFx0fVxuXHRcdFx0Y3VyID0gY3VyW2Rpcl07XG5cdFx0fVxuXHRcdHJldHVybiBtYXRjaGVkO1xuXHR9LFxuXG5cdHNpYmxpbmc6IGZ1bmN0aW9uKCBuLCBlbGVtICkge1xuXHRcdHZhciByID0gW107XG5cblx0XHRmb3IgKCA7IG47IG4gPSBuLm5leHRTaWJsaW5nICkge1xuXHRcdFx0aWYgKCBuLm5vZGVUeXBlID09PSAxICYmIG4gIT09IGVsZW0gKSB7XG5cdFx0XHRcdHIucHVzaCggbiApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiByO1xuXHR9XG59KTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGhhczogZnVuY3Rpb24oIHRhcmdldCApIHtcblx0XHR2YXIgaSxcblx0XHRcdHRhcmdldHMgPSBqUXVlcnkoIHRhcmdldCwgdGhpcyApLFxuXHRcdFx0bGVuID0gdGFyZ2V0cy5sZW5ndGg7XG5cblx0XHRyZXR1cm4gdGhpcy5maWx0ZXIoZnVuY3Rpb24oKSB7XG5cdFx0XHRmb3IgKCBpID0gMDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRpZiAoIGpRdWVyeS5jb250YWlucyggdGhpcywgdGFyZ2V0c1tpXSApICkge1xuXHRcdFx0XHRcdHJldHVybiB0cnVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0Y2xvc2VzdDogZnVuY3Rpb24oIHNlbGVjdG9ycywgY29udGV4dCApIHtcblx0XHR2YXIgY3VyLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRsID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRtYXRjaGVkID0gW10sXG5cdFx0XHRwb3MgPSBybmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9ycyApIHx8IHR5cGVvZiBzZWxlY3RvcnMgIT09IFwic3RyaW5nXCIgP1xuXHRcdFx0XHRqUXVlcnkoIHNlbGVjdG9ycywgY29udGV4dCB8fCB0aGlzLmNvbnRleHQgKSA6XG5cdFx0XHRcdDA7XG5cblx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRmb3IgKCBjdXIgPSB0aGlzW2ldOyBjdXIgJiYgY3VyICE9PSBjb250ZXh0OyBjdXIgPSBjdXIucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0Ly8gQWx3YXlzIHNraXAgZG9jdW1lbnQgZnJhZ21lbnRzXG5cdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlIDwgMTEgJiYgKHBvcyA/XG5cdFx0XHRcdFx0cG9zLmluZGV4KGN1cikgPiAtMSA6XG5cblx0XHRcdFx0XHQvLyBEb24ndCBwYXNzIG5vbi1lbGVtZW50cyB0byBTaXp6bGVcblx0XHRcdFx0XHRjdXIubm9kZVR5cGUgPT09IDEgJiZcblx0XHRcdFx0XHRcdGpRdWVyeS5maW5kLm1hdGNoZXNTZWxlY3RvcihjdXIsIHNlbGVjdG9ycykpICkge1xuXG5cdFx0XHRcdFx0bWF0Y2hlZC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggbWF0Y2hlZC5sZW5ndGggPiAxID8galF1ZXJ5LnVuaXF1ZSggbWF0Y2hlZCApIDogbWF0Y2hlZCApO1xuXHR9LFxuXG5cdC8vIERldGVybWluZSB0aGUgcG9zaXRpb24gb2YgYW4gZWxlbWVudCB3aXRoaW5cblx0Ly8gdGhlIG1hdGNoZWQgc2V0IG9mIGVsZW1lbnRzXG5cdGluZGV4OiBmdW5jdGlvbiggZWxlbSApIHtcblxuXHRcdC8vIE5vIGFyZ3VtZW50LCByZXR1cm4gaW5kZXggaW4gcGFyZW50XG5cdFx0aWYgKCAhZWxlbSApIHtcblx0XHRcdHJldHVybiAoIHRoaXNbMF0gJiYgdGhpc1swXS5wYXJlbnROb2RlICkgPyB0aGlzLmZpcnN0KCkucHJldkFsbCgpLmxlbmd0aCA6IC0xO1xuXHRcdH1cblxuXHRcdC8vIGluZGV4IGluIHNlbGVjdG9yXG5cdFx0aWYgKCB0eXBlb2YgZWxlbSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBqUXVlcnkuaW5BcnJheSggdGhpc1swXSwgalF1ZXJ5KCBlbGVtICkgKTtcblx0XHR9XG5cblx0XHQvLyBMb2NhdGUgdGhlIHBvc2l0aW9uIG9mIHRoZSBkZXNpcmVkIGVsZW1lbnRcblx0XHRyZXR1cm4galF1ZXJ5LmluQXJyYXkoXG5cdFx0XHQvLyBJZiBpdCByZWNlaXZlcyBhIGpRdWVyeSBvYmplY3QsIHRoZSBmaXJzdCBlbGVtZW50IGlzIHVzZWRcblx0XHRcdGVsZW0uanF1ZXJ5ID8gZWxlbVswXSA6IGVsZW0sIHRoaXMgKTtcblx0fSxcblxuXHRhZGQ6IGZ1bmN0aW9uKCBzZWxlY3RvciwgY29udGV4dCApIHtcblx0XHRyZXR1cm4gdGhpcy5wdXNoU3RhY2soXG5cdFx0XHRqUXVlcnkudW5pcXVlKFxuXHRcdFx0XHRqUXVlcnkubWVyZ2UoIHRoaXMuZ2V0KCksIGpRdWVyeSggc2VsZWN0b3IsIGNvbnRleHQgKSApXG5cdFx0XHQpXG5cdFx0KTtcblx0fSxcblxuXHRhZGRCYWNrOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMuYWRkKCBzZWxlY3RvciA9PSBudWxsID9cblx0XHRcdHRoaXMucHJldk9iamVjdCA6IHRoaXMucHJldk9iamVjdC5maWx0ZXIoc2VsZWN0b3IpXG5cdFx0KTtcblx0fVxufSk7XG5cbmZ1bmN0aW9uIHNpYmxpbmcoIGN1ciwgZGlyICkge1xuXHRkbyB7XG5cdFx0Y3VyID0gY3VyWyBkaXIgXTtcblx0fSB3aGlsZSAoIGN1ciAmJiBjdXIubm9kZVR5cGUgIT09IDEgKTtcblxuXHRyZXR1cm4gY3VyO1xufVxuXG5qUXVlcnkuZWFjaCh7XG5cdHBhcmVudDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0dmFyIHBhcmVudCA9IGVsZW0ucGFyZW50Tm9kZTtcblx0XHRyZXR1cm4gcGFyZW50ICYmIHBhcmVudC5ub2RlVHlwZSAhPT0gMTEgPyBwYXJlbnQgOiBudWxsO1xuXHR9LFxuXHRwYXJlbnRzOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmRpciggZWxlbSwgXCJwYXJlbnROb2RlXCIgKTtcblx0fSxcblx0cGFyZW50c1VudGlsOiBmdW5jdGlvbiggZWxlbSwgaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwicGFyZW50Tm9kZVwiLCB1bnRpbCApO1xuXHR9LFxuXHRuZXh0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gc2libGluZyggZWxlbSwgXCJuZXh0U2libGluZ1wiICk7XG5cdH0sXG5cdHByZXY6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBzaWJsaW5nKCBlbGVtLCBcInByZXZpb3VzU2libGluZ1wiICk7XG5cdH0sXG5cdG5leHRBbGw6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBqUXVlcnkuZGlyKCBlbGVtLCBcIm5leHRTaWJsaW5nXCIgKTtcblx0fSxcblx0cHJldkFsbDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwicHJldmlvdXNTaWJsaW5nXCIgKTtcblx0fSxcblx0bmV4dFVudGlsOiBmdW5jdGlvbiggZWxlbSwgaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwibmV4dFNpYmxpbmdcIiwgdW50aWwgKTtcblx0fSxcblx0cHJldlVudGlsOiBmdW5jdGlvbiggZWxlbSwgaSwgdW50aWwgKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5kaXIoIGVsZW0sIFwicHJldmlvdXNTaWJsaW5nXCIsIHVudGlsICk7XG5cdH0sXG5cdHNpYmxpbmdzOiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4galF1ZXJ5LnNpYmxpbmcoICggZWxlbS5wYXJlbnROb2RlIHx8IHt9ICkuZmlyc3RDaGlsZCwgZWxlbSApO1xuXHR9LFxuXHRjaGlsZHJlbjogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0cmV0dXJuIGpRdWVyeS5zaWJsaW5nKCBlbGVtLmZpcnN0Q2hpbGQgKTtcblx0fSxcblx0Y29udGVudHM6IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdHJldHVybiBqUXVlcnkubm9kZU5hbWUoIGVsZW0sIFwiaWZyYW1lXCIgKSA/XG5cdFx0XHRlbGVtLmNvbnRlbnREb2N1bWVudCB8fCBlbGVtLmNvbnRlbnRXaW5kb3cuZG9jdW1lbnQgOlxuXHRcdFx0alF1ZXJ5Lm1lcmdlKCBbXSwgZWxlbS5jaGlsZE5vZGVzICk7XG5cdH1cbn0sIGZ1bmN0aW9uKCBuYW1lLCBmbiApIHtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggdW50aWwsIHNlbGVjdG9yICkge1xuXHRcdHZhciByZXQgPSBqUXVlcnkubWFwKCB0aGlzLCBmbiwgdW50aWwgKTtcblxuXHRcdGlmICggbmFtZS5zbGljZSggLTUgKSAhPT0gXCJVbnRpbFwiICkge1xuXHRcdFx0c2VsZWN0b3IgPSB1bnRpbDtcblx0XHR9XG5cblx0XHRpZiAoIHNlbGVjdG9yICYmIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldCA9IGpRdWVyeS5maWx0ZXIoIHNlbGVjdG9yLCByZXQgKTtcblx0XHR9XG5cblx0XHRpZiAoIHRoaXMubGVuZ3RoID4gMSApIHtcblx0XHRcdC8vIFJlbW92ZSBkdXBsaWNhdGVzXG5cdFx0XHRpZiAoICFndWFyYW50ZWVkVW5pcXVlWyBuYW1lIF0gKSB7XG5cdFx0XHRcdHJldCA9IGpRdWVyeS51bmlxdWUoIHJldCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZXZlcnNlIG9yZGVyIGZvciBwYXJlbnRzKiBhbmQgcHJldi1kZXJpdmF0aXZlc1xuXHRcdFx0aWYgKCBycGFyZW50c3ByZXYudGVzdCggbmFtZSApICkge1xuXHRcdFx0XHRyZXQgPSByZXQucmV2ZXJzZSgpO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLnB1c2hTdGFjayggcmV0ICk7XG5cdH07XG59KTtcbnZhciBybm90d2hpdGUgPSAoL1xcUysvZyk7XG5cblxuXG4vLyBTdHJpbmcgdG8gT2JqZWN0IG9wdGlvbnMgZm9ybWF0IGNhY2hlXG52YXIgb3B0aW9uc0NhY2hlID0ge307XG5cbi8vIENvbnZlcnQgU3RyaW5nLWZvcm1hdHRlZCBvcHRpb25zIGludG8gT2JqZWN0LWZvcm1hdHRlZCBvbmVzIGFuZCBzdG9yZSBpbiBjYWNoZVxuZnVuY3Rpb24gY3JlYXRlT3B0aW9ucyggb3B0aW9ucyApIHtcblx0dmFyIG9iamVjdCA9IG9wdGlvbnNDYWNoZVsgb3B0aW9ucyBdID0ge307XG5cdGpRdWVyeS5lYWNoKCBvcHRpb25zLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXSwgZnVuY3Rpb24oIF8sIGZsYWcgKSB7XG5cdFx0b2JqZWN0WyBmbGFnIF0gPSB0cnVlO1xuXHR9KTtcblx0cmV0dXJuIG9iamVjdDtcbn1cblxuLypcbiAqIENyZWF0ZSBhIGNhbGxiYWNrIGxpc3QgdXNpbmcgdGhlIGZvbGxvd2luZyBwYXJhbWV0ZXJzOlxuICpcbiAqXHRvcHRpb25zOiBhbiBvcHRpb25hbCBsaXN0IG9mIHNwYWNlLXNlcGFyYXRlZCBvcHRpb25zIHRoYXQgd2lsbCBjaGFuZ2UgaG93XG4gKlx0XHRcdHRoZSBjYWxsYmFjayBsaXN0IGJlaGF2ZXMgb3IgYSBtb3JlIHRyYWRpdGlvbmFsIG9wdGlvbiBvYmplY3RcbiAqXG4gKiBCeSBkZWZhdWx0IGEgY2FsbGJhY2sgbGlzdCB3aWxsIGFjdCBsaWtlIGFuIGV2ZW50IGNhbGxiYWNrIGxpc3QgYW5kIGNhbiBiZVxuICogXCJmaXJlZFwiIG11bHRpcGxlIHRpbWVzLlxuICpcbiAqIFBvc3NpYmxlIG9wdGlvbnM6XG4gKlxuICpcdG9uY2U6XHRcdFx0d2lsbCBlbnN1cmUgdGhlIGNhbGxiYWNrIGxpc3QgY2FuIG9ubHkgYmUgZmlyZWQgb25jZSAobGlrZSBhIERlZmVycmVkKVxuICpcbiAqXHRtZW1vcnk6XHRcdFx0d2lsbCBrZWVwIHRyYWNrIG9mIHByZXZpb3VzIHZhbHVlcyBhbmQgd2lsbCBjYWxsIGFueSBjYWxsYmFjayBhZGRlZFxuICpcdFx0XHRcdFx0YWZ0ZXIgdGhlIGxpc3QgaGFzIGJlZW4gZmlyZWQgcmlnaHQgYXdheSB3aXRoIHRoZSBsYXRlc3QgXCJtZW1vcml6ZWRcIlxuICpcdFx0XHRcdFx0dmFsdWVzIChsaWtlIGEgRGVmZXJyZWQpXG4gKlxuICpcdHVuaXF1ZTpcdFx0XHR3aWxsIGVuc3VyZSBhIGNhbGxiYWNrIGNhbiBvbmx5IGJlIGFkZGVkIG9uY2UgKG5vIGR1cGxpY2F0ZSBpbiB0aGUgbGlzdClcbiAqXG4gKlx0c3RvcE9uRmFsc2U6XHRpbnRlcnJ1cHQgY2FsbGluZ3Mgd2hlbiBhIGNhbGxiYWNrIHJldHVybnMgZmFsc2VcbiAqXG4gKi9cbmpRdWVyeS5DYWxsYmFja3MgPSBmdW5jdGlvbiggb3B0aW9ucyApIHtcblxuXHQvLyBDb252ZXJ0IG9wdGlvbnMgZnJvbSBTdHJpbmctZm9ybWF0dGVkIHRvIE9iamVjdC1mb3JtYXR0ZWQgaWYgbmVlZGVkXG5cdC8vICh3ZSBjaGVjayBpbiBjYWNoZSBmaXJzdClcblx0b3B0aW9ucyA9IHR5cGVvZiBvcHRpb25zID09PSBcInN0cmluZ1wiID9cblx0XHQoIG9wdGlvbnNDYWNoZVsgb3B0aW9ucyBdIHx8IGNyZWF0ZU9wdGlvbnMoIG9wdGlvbnMgKSApIDpcblx0XHRqUXVlcnkuZXh0ZW5kKCB7fSwgb3B0aW9ucyApO1xuXG5cdHZhciAvLyBGbGFnIHRvIGtub3cgaWYgbGlzdCBpcyBjdXJyZW50bHkgZmlyaW5nXG5cdFx0ZmlyaW5nLFxuXHRcdC8vIExhc3QgZmlyZSB2YWx1ZSAoZm9yIG5vbi1mb3JnZXR0YWJsZSBsaXN0cylcblx0XHRtZW1vcnksXG5cdFx0Ly8gRmxhZyB0byBrbm93IGlmIGxpc3Qgd2FzIGFscmVhZHkgZmlyZWRcblx0XHRmaXJlZCxcblx0XHQvLyBFbmQgb2YgdGhlIGxvb3Agd2hlbiBmaXJpbmdcblx0XHRmaXJpbmdMZW5ndGgsXG5cdFx0Ly8gSW5kZXggb2YgY3VycmVudGx5IGZpcmluZyBjYWxsYmFjayAobW9kaWZpZWQgYnkgcmVtb3ZlIGlmIG5lZWRlZClcblx0XHRmaXJpbmdJbmRleCxcblx0XHQvLyBGaXJzdCBjYWxsYmFjayB0byBmaXJlICh1c2VkIGludGVybmFsbHkgYnkgYWRkIGFuZCBmaXJlV2l0aClcblx0XHRmaXJpbmdTdGFydCxcblx0XHQvLyBBY3R1YWwgY2FsbGJhY2sgbGlzdFxuXHRcdGxpc3QgPSBbXSxcblx0XHQvLyBTdGFjayBvZiBmaXJlIGNhbGxzIGZvciByZXBlYXRhYmxlIGxpc3RzXG5cdFx0c3RhY2sgPSAhb3B0aW9ucy5vbmNlICYmIFtdLFxuXHRcdC8vIEZpcmUgY2FsbGJhY2tzXG5cdFx0ZmlyZSA9IGZ1bmN0aW9uKCBkYXRhICkge1xuXHRcdFx0bWVtb3J5ID0gb3B0aW9ucy5tZW1vcnkgJiYgZGF0YTtcblx0XHRcdGZpcmVkID0gdHJ1ZTtcblx0XHRcdGZpcmluZ0luZGV4ID0gZmlyaW5nU3RhcnQgfHwgMDtcblx0XHRcdGZpcmluZ1N0YXJ0ID0gMDtcblx0XHRcdGZpcmluZ0xlbmd0aCA9IGxpc3QubGVuZ3RoO1xuXHRcdFx0ZmlyaW5nID0gdHJ1ZTtcblx0XHRcdGZvciAoIDsgbGlzdCAmJiBmaXJpbmdJbmRleCA8IGZpcmluZ0xlbmd0aDsgZmlyaW5nSW5kZXgrKyApIHtcblx0XHRcdFx0aWYgKCBsaXN0WyBmaXJpbmdJbmRleCBdLmFwcGx5KCBkYXRhWyAwIF0sIGRhdGFbIDEgXSApID09PSBmYWxzZSAmJiBvcHRpb25zLnN0b3BPbkZhbHNlICkge1xuXHRcdFx0XHRcdG1lbW9yeSA9IGZhbHNlOyAvLyBUbyBwcmV2ZW50IGZ1cnRoZXIgY2FsbHMgdXNpbmcgYWRkXG5cdFx0XHRcdFx0YnJlYWs7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdGZpcmluZyA9IGZhbHNlO1xuXHRcdFx0aWYgKCBsaXN0ICkge1xuXHRcdFx0XHRpZiAoIHN0YWNrICkge1xuXHRcdFx0XHRcdGlmICggc3RhY2subGVuZ3RoICkge1xuXHRcdFx0XHRcdFx0ZmlyZSggc3RhY2suc2hpZnQoKSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSBlbHNlIGlmICggbWVtb3J5ICkge1xuXHRcdFx0XHRcdGxpc3QgPSBbXTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRzZWxmLmRpc2FibGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0sXG5cdFx0Ly8gQWN0dWFsIENhbGxiYWNrcyBvYmplY3Rcblx0XHRzZWxmID0ge1xuXHRcdFx0Ly8gQWRkIGEgY2FsbGJhY2sgb3IgYSBjb2xsZWN0aW9uIG9mIGNhbGxiYWNrcyB0byB0aGUgbGlzdFxuXHRcdFx0YWRkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBsaXN0ICkge1xuXHRcdFx0XHRcdC8vIEZpcnN0LCB3ZSBzYXZlIHRoZSBjdXJyZW50IGxlbmd0aFxuXHRcdFx0XHRcdHZhciBzdGFydCA9IGxpc3QubGVuZ3RoO1xuXHRcdFx0XHRcdChmdW5jdGlvbiBhZGQoIGFyZ3MgKSB7XG5cdFx0XHRcdFx0XHRqUXVlcnkuZWFjaCggYXJncywgZnVuY3Rpb24oIF8sIGFyZyApIHtcblx0XHRcdFx0XHRcdFx0dmFyIHR5cGUgPSBqUXVlcnkudHlwZSggYXJnICk7XG5cdFx0XHRcdFx0XHRcdGlmICggdHlwZSA9PT0gXCJmdW5jdGlvblwiICkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggIW9wdGlvbnMudW5pcXVlIHx8ICFzZWxmLmhhcyggYXJnICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRsaXN0LnB1c2goIGFyZyApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggYXJnICYmIGFyZy5sZW5ndGggJiYgdHlwZSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBJbnNwZWN0IHJlY3Vyc2l2ZWx5XG5cdFx0XHRcdFx0XHRcdFx0YWRkKCBhcmcgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0fSkoIGFyZ3VtZW50cyApO1xuXHRcdFx0XHRcdC8vIERvIHdlIG5lZWQgdG8gYWRkIHRoZSBjYWxsYmFja3MgdG8gdGhlXG5cdFx0XHRcdFx0Ly8gY3VycmVudCBmaXJpbmcgYmF0Y2g/XG5cdFx0XHRcdFx0aWYgKCBmaXJpbmcgKSB7XG5cdFx0XHRcdFx0XHRmaXJpbmdMZW5ndGggPSBsaXN0Lmxlbmd0aDtcblx0XHRcdFx0XHQvLyBXaXRoIG1lbW9yeSwgaWYgd2UncmUgbm90IGZpcmluZyB0aGVuXG5cdFx0XHRcdFx0Ly8gd2Ugc2hvdWxkIGNhbGwgcmlnaHQgYXdheVxuXHRcdFx0XHRcdH0gZWxzZSBpZiAoIG1lbW9yeSApIHtcblx0XHRcdFx0XHRcdGZpcmluZ1N0YXJ0ID0gc3RhcnQ7XG5cdFx0XHRcdFx0XHRmaXJlKCBtZW1vcnkgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gUmVtb3ZlIGEgY2FsbGJhY2sgZnJvbSB0aGUgbGlzdFxuXHRcdFx0cmVtb3ZlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCBsaXN0ICkge1xuXHRcdFx0XHRcdGpRdWVyeS5lYWNoKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBfLCBhcmcgKSB7XG5cdFx0XHRcdFx0XHR2YXIgaW5kZXg7XG5cdFx0XHRcdFx0XHR3aGlsZSAoICggaW5kZXggPSBqUXVlcnkuaW5BcnJheSggYXJnLCBsaXN0LCBpbmRleCApICkgPiAtMSApIHtcblx0XHRcdFx0XHRcdFx0bGlzdC5zcGxpY2UoIGluZGV4LCAxICk7XG5cdFx0XHRcdFx0XHRcdC8vIEhhbmRsZSBmaXJpbmcgaW5kZXhlc1xuXHRcdFx0XHRcdFx0XHRpZiAoIGZpcmluZyApIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGluZGV4IDw9IGZpcmluZ0xlbmd0aCApIHtcblx0XHRcdFx0XHRcdFx0XHRcdGZpcmluZ0xlbmd0aC0tO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0XHRpZiAoIGluZGV4IDw9IGZpcmluZ0luZGV4ICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0ZmlyaW5nSW5kZXgtLTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBDaGVjayBpZiBhIGdpdmVuIGNhbGxiYWNrIGlzIGluIHRoZSBsaXN0LlxuXHRcdFx0Ly8gSWYgbm8gYXJndW1lbnQgaXMgZ2l2ZW4sIHJldHVybiB3aGV0aGVyIG9yIG5vdCBsaXN0IGhhcyBjYWxsYmFja3MgYXR0YWNoZWQuXG5cdFx0XHRoYXM6IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRcdFx0cmV0dXJuIGZuID8galF1ZXJ5LmluQXJyYXkoIGZuLCBsaXN0ICkgPiAtMSA6ICEhKCBsaXN0ICYmIGxpc3QubGVuZ3RoICk7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gUmVtb3ZlIGFsbCBjYWxsYmFja3MgZnJvbSB0aGUgbGlzdFxuXHRcdFx0ZW1wdHk6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRsaXN0ID0gW107XG5cdFx0XHRcdGZpcmluZ0xlbmd0aCA9IDA7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIEhhdmUgdGhlIGxpc3QgZG8gbm90aGluZyBhbnltb3JlXG5cdFx0XHRkaXNhYmxlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0bGlzdCA9IHN0YWNrID0gbWVtb3J5ID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH0sXG5cdFx0XHQvLyBJcyBpdCBkaXNhYmxlZD9cblx0XHRcdGRpc2FibGVkOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0cmV0dXJuICFsaXN0O1xuXHRcdFx0fSxcblx0XHRcdC8vIExvY2sgdGhlIGxpc3QgaW4gaXRzIGN1cnJlbnQgc3RhdGVcblx0XHRcdGxvY2s6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRzdGFjayA9IHVuZGVmaW5lZDtcblx0XHRcdFx0aWYgKCAhbWVtb3J5ICkge1xuXHRcdFx0XHRcdHNlbGYuZGlzYWJsZSgpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIElzIGl0IGxvY2tlZD9cblx0XHRcdGxvY2tlZDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHJldHVybiAhc3RhY2s7XG5cdFx0XHR9LFxuXHRcdFx0Ly8gQ2FsbCBhbGwgY2FsbGJhY2tzIHdpdGggdGhlIGdpdmVuIGNvbnRleHQgYW5kIGFyZ3VtZW50c1xuXHRcdFx0ZmlyZVdpdGg6IGZ1bmN0aW9uKCBjb250ZXh0LCBhcmdzICkge1xuXHRcdFx0XHRpZiAoIGxpc3QgJiYgKCAhZmlyZWQgfHwgc3RhY2sgKSApIHtcblx0XHRcdFx0XHRhcmdzID0gYXJncyB8fCBbXTtcblx0XHRcdFx0XHRhcmdzID0gWyBjb250ZXh0LCBhcmdzLnNsaWNlID8gYXJncy5zbGljZSgpIDogYXJncyBdO1xuXHRcdFx0XHRcdGlmICggZmlyaW5nICkge1xuXHRcdFx0XHRcdFx0c3RhY2sucHVzaCggYXJncyApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRmaXJlKCBhcmdzICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIENhbGwgYWxsIHRoZSBjYWxsYmFja3Mgd2l0aCB0aGUgZ2l2ZW4gYXJndW1lbnRzXG5cdFx0XHRmaXJlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0c2VsZi5maXJlV2l0aCggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fSxcblx0XHRcdC8vIFRvIGtub3cgaWYgdGhlIGNhbGxiYWNrcyBoYXZlIGFscmVhZHkgYmVlbiBjYWxsZWQgYXQgbGVhc3Qgb25jZVxuXHRcdFx0ZmlyZWQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRyZXR1cm4gISFmaXJlZDtcblx0XHRcdH1cblx0XHR9O1xuXG5cdHJldHVybiBzZWxmO1xufTtcblxuXG5qUXVlcnkuZXh0ZW5kKHtcblxuXHREZWZlcnJlZDogZnVuY3Rpb24oIGZ1bmMgKSB7XG5cdFx0dmFyIHR1cGxlcyA9IFtcblx0XHRcdFx0Ly8gYWN0aW9uLCBhZGQgbGlzdGVuZXIsIGxpc3RlbmVyIGxpc3QsIGZpbmFsIHN0YXRlXG5cdFx0XHRcdFsgXCJyZXNvbHZlXCIsIFwiZG9uZVwiLCBqUXVlcnkuQ2FsbGJhY2tzKFwib25jZSBtZW1vcnlcIiksIFwicmVzb2x2ZWRcIiBdLFxuXHRcdFx0XHRbIFwicmVqZWN0XCIsIFwiZmFpbFwiLCBqUXVlcnkuQ2FsbGJhY2tzKFwib25jZSBtZW1vcnlcIiksIFwicmVqZWN0ZWRcIiBdLFxuXHRcdFx0XHRbIFwibm90aWZ5XCIsIFwicHJvZ3Jlc3NcIiwgalF1ZXJ5LkNhbGxiYWNrcyhcIm1lbW9yeVwiKSBdXG5cdFx0XHRdLFxuXHRcdFx0c3RhdGUgPSBcInBlbmRpbmdcIixcblx0XHRcdHByb21pc2UgPSB7XG5cdFx0XHRcdHN0YXRlOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gc3RhdGU7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdGFsd2F5czogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0ZGVmZXJyZWQuZG9uZSggYXJndW1lbnRzICkuZmFpbCggYXJndW1lbnRzICk7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cdFx0XHRcdHRoZW46IGZ1bmN0aW9uKCAvKiBmbkRvbmUsIGZuRmFpbCwgZm5Qcm9ncmVzcyAqLyApIHtcblx0XHRcdFx0XHR2YXIgZm5zID0gYXJndW1lbnRzO1xuXHRcdFx0XHRcdHJldHVybiBqUXVlcnkuRGVmZXJyZWQoZnVuY3Rpb24oIG5ld0RlZmVyICkge1xuXHRcdFx0XHRcdFx0alF1ZXJ5LmVhY2goIHR1cGxlcywgZnVuY3Rpb24oIGksIHR1cGxlICkge1xuXHRcdFx0XHRcdFx0XHR2YXIgZm4gPSBqUXVlcnkuaXNGdW5jdGlvbiggZm5zWyBpIF0gKSAmJiBmbnNbIGkgXTtcblx0XHRcdFx0XHRcdFx0Ly8gZGVmZXJyZWRbIGRvbmUgfCBmYWlsIHwgcHJvZ3Jlc3MgXSBmb3IgZm9yd2FyZGluZyBhY3Rpb25zIHRvIG5ld0RlZmVyXG5cdFx0XHRcdFx0XHRcdGRlZmVycmVkWyB0dXBsZVsxXSBdKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHRcdHZhciByZXR1cm5lZCA9IGZuICYmIGZuLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdFx0XHRcdFx0XHRpZiAoIHJldHVybmVkICYmIGpRdWVyeS5pc0Z1bmN0aW9uKCByZXR1cm5lZC5wcm9taXNlICkgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRyZXR1cm5lZC5wcm9taXNlKClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LmRvbmUoIG5ld0RlZmVyLnJlc29sdmUgKVxuXHRcdFx0XHRcdFx0XHRcdFx0XHQuZmFpbCggbmV3RGVmZXIucmVqZWN0IClcblx0XHRcdFx0XHRcdFx0XHRcdFx0LnByb2dyZXNzKCBuZXdEZWZlci5ub3RpZnkgKTtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0bmV3RGVmZXJbIHR1cGxlWyAwIF0gKyBcIldpdGhcIiBdKCB0aGlzID09PSBwcm9taXNlID8gbmV3RGVmZXIucHJvbWlzZSgpIDogdGhpcywgZm4gPyBbIHJldHVybmVkIF0gOiBhcmd1bWVudHMgKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0XHRmbnMgPSBudWxsO1xuXHRcdFx0XHRcdH0pLnByb21pc2UoKTtcblx0XHRcdFx0fSxcblx0XHRcdFx0Ly8gR2V0IGEgcHJvbWlzZSBmb3IgdGhpcyBkZWZlcnJlZFxuXHRcdFx0XHQvLyBJZiBvYmogaXMgcHJvdmlkZWQsIHRoZSBwcm9taXNlIGFzcGVjdCBpcyBhZGRlZCB0byB0aGUgb2JqZWN0XG5cdFx0XHRcdHByb21pc2U6IGZ1bmN0aW9uKCBvYmogKSB7XG5cdFx0XHRcdFx0cmV0dXJuIG9iaiAhPSBudWxsID8galF1ZXJ5LmV4dGVuZCggb2JqLCBwcm9taXNlICkgOiBwcm9taXNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVmZXJyZWQgPSB7fTtcblxuXHRcdC8vIEtlZXAgcGlwZSBmb3IgYmFjay1jb21wYXRcblx0XHRwcm9taXNlLnBpcGUgPSBwcm9taXNlLnRoZW47XG5cblx0XHQvLyBBZGQgbGlzdC1zcGVjaWZpYyBtZXRob2RzXG5cdFx0alF1ZXJ5LmVhY2goIHR1cGxlcywgZnVuY3Rpb24oIGksIHR1cGxlICkge1xuXHRcdFx0dmFyIGxpc3QgPSB0dXBsZVsgMiBdLFxuXHRcdFx0XHRzdGF0ZVN0cmluZyA9IHR1cGxlWyAzIF07XG5cblx0XHRcdC8vIHByb21pc2VbIGRvbmUgfCBmYWlsIHwgcHJvZ3Jlc3MgXSA9IGxpc3QuYWRkXG5cdFx0XHRwcm9taXNlWyB0dXBsZVsxXSBdID0gbGlzdC5hZGQ7XG5cblx0XHRcdC8vIEhhbmRsZSBzdGF0ZVxuXHRcdFx0aWYgKCBzdGF0ZVN0cmluZyApIHtcblx0XHRcdFx0bGlzdC5hZGQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0Ly8gc3RhdGUgPSBbIHJlc29sdmVkIHwgcmVqZWN0ZWQgXVxuXHRcdFx0XHRcdHN0YXRlID0gc3RhdGVTdHJpbmc7XG5cblx0XHRcdFx0Ly8gWyByZWplY3RfbGlzdCB8IHJlc29sdmVfbGlzdCBdLmRpc2FibGU7IHByb2dyZXNzX2xpc3QubG9ja1xuXHRcdFx0XHR9LCB0dXBsZXNbIGkgXiAxIF1bIDIgXS5kaXNhYmxlLCB0dXBsZXNbIDIgXVsgMiBdLmxvY2sgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gZGVmZXJyZWRbIHJlc29sdmUgfCByZWplY3QgfCBub3RpZnkgXVxuXHRcdFx0ZGVmZXJyZWRbIHR1cGxlWzBdIF0gPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0ZGVmZXJyZWRbIHR1cGxlWzBdICsgXCJXaXRoXCIgXSggdGhpcyA9PT0gZGVmZXJyZWQgPyBwcm9taXNlIDogdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0fTtcblx0XHRcdGRlZmVycmVkWyB0dXBsZVswXSArIFwiV2l0aFwiIF0gPSBsaXN0LmZpcmVXaXRoO1xuXHRcdH0pO1xuXG5cdFx0Ly8gTWFrZSB0aGUgZGVmZXJyZWQgYSBwcm9taXNlXG5cdFx0cHJvbWlzZS5wcm9taXNlKCBkZWZlcnJlZCApO1xuXG5cdFx0Ly8gQ2FsbCBnaXZlbiBmdW5jIGlmIGFueVxuXHRcdGlmICggZnVuYyApIHtcblx0XHRcdGZ1bmMuY2FsbCggZGVmZXJyZWQsIGRlZmVycmVkICk7XG5cdFx0fVxuXG5cdFx0Ly8gQWxsIGRvbmUhXG5cdFx0cmV0dXJuIGRlZmVycmVkO1xuXHR9LFxuXG5cdC8vIERlZmVycmVkIGhlbHBlclxuXHR3aGVuOiBmdW5jdGlvbiggc3Vib3JkaW5hdGUgLyogLCAuLi4sIHN1Ym9yZGluYXRlTiAqLyApIHtcblx0XHR2YXIgaSA9IDAsXG5cdFx0XHRyZXNvbHZlVmFsdWVzID0gc2xpY2UuY2FsbCggYXJndW1lbnRzICksXG5cdFx0XHRsZW5ndGggPSByZXNvbHZlVmFsdWVzLmxlbmd0aCxcblxuXHRcdFx0Ly8gdGhlIGNvdW50IG9mIHVuY29tcGxldGVkIHN1Ym9yZGluYXRlc1xuXHRcdFx0cmVtYWluaW5nID0gbGVuZ3RoICE9PSAxIHx8ICggc3Vib3JkaW5hdGUgJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIHN1Ym9yZGluYXRlLnByb21pc2UgKSApID8gbGVuZ3RoIDogMCxcblxuXHRcdFx0Ly8gdGhlIG1hc3RlciBEZWZlcnJlZC4gSWYgcmVzb2x2ZVZhbHVlcyBjb25zaXN0IG9mIG9ubHkgYSBzaW5nbGUgRGVmZXJyZWQsIGp1c3QgdXNlIHRoYXQuXG5cdFx0XHRkZWZlcnJlZCA9IHJlbWFpbmluZyA9PT0gMSA/IHN1Ym9yZGluYXRlIDogalF1ZXJ5LkRlZmVycmVkKCksXG5cblx0XHRcdC8vIFVwZGF0ZSBmdW5jdGlvbiBmb3IgYm90aCByZXNvbHZlIGFuZCBwcm9ncmVzcyB2YWx1ZXNcblx0XHRcdHVwZGF0ZUZ1bmMgPSBmdW5jdGlvbiggaSwgY29udGV4dHMsIHZhbHVlcyApIHtcblx0XHRcdFx0cmV0dXJuIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0XHRjb250ZXh0c1sgaSBdID0gdGhpcztcblx0XHRcdFx0XHR2YWx1ZXNbIGkgXSA9IGFyZ3VtZW50cy5sZW5ndGggPiAxID8gc2xpY2UuY2FsbCggYXJndW1lbnRzICkgOiB2YWx1ZTtcblx0XHRcdFx0XHRpZiAoIHZhbHVlcyA9PT0gcHJvZ3Jlc3NWYWx1ZXMgKSB7XG5cdFx0XHRcdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBjb250ZXh0cywgdmFsdWVzICk7XG5cblx0XHRcdFx0XHR9IGVsc2UgaWYgKCAhKC0tcmVtYWluaW5nKSApIHtcblx0XHRcdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBjb250ZXh0cywgdmFsdWVzICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9O1xuXHRcdFx0fSxcblxuXHRcdFx0cHJvZ3Jlc3NWYWx1ZXMsIHByb2dyZXNzQ29udGV4dHMsIHJlc29sdmVDb250ZXh0cztcblxuXHRcdC8vIGFkZCBsaXN0ZW5lcnMgdG8gRGVmZXJyZWQgc3Vib3JkaW5hdGVzOyB0cmVhdCBvdGhlcnMgYXMgcmVzb2x2ZWRcblx0XHRpZiAoIGxlbmd0aCA+IDEgKSB7XG5cdFx0XHRwcm9ncmVzc1ZhbHVlcyA9IG5ldyBBcnJheSggbGVuZ3RoICk7XG5cdFx0XHRwcm9ncmVzc0NvbnRleHRzID0gbmV3IEFycmF5KCBsZW5ndGggKTtcblx0XHRcdHJlc29sdmVDb250ZXh0cyA9IG5ldyBBcnJheSggbGVuZ3RoICk7XG5cdFx0XHRmb3IgKCA7IGkgPCBsZW5ndGg7IGkrKyApIHtcblx0XHRcdFx0aWYgKCByZXNvbHZlVmFsdWVzWyBpIF0gJiYgalF1ZXJ5LmlzRnVuY3Rpb24oIHJlc29sdmVWYWx1ZXNbIGkgXS5wcm9taXNlICkgKSB7XG5cdFx0XHRcdFx0cmVzb2x2ZVZhbHVlc1sgaSBdLnByb21pc2UoKVxuXHRcdFx0XHRcdFx0LmRvbmUoIHVwZGF0ZUZ1bmMoIGksIHJlc29sdmVDb250ZXh0cywgcmVzb2x2ZVZhbHVlcyApIClcblx0XHRcdFx0XHRcdC5mYWlsKCBkZWZlcnJlZC5yZWplY3QgKVxuXHRcdFx0XHRcdFx0LnByb2dyZXNzKCB1cGRhdGVGdW5jKCBpLCBwcm9ncmVzc0NvbnRleHRzLCBwcm9ncmVzc1ZhbHVlcyApICk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0LS1yZW1haW5pbmc7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBpZiB3ZSdyZSBub3Qgd2FpdGluZyBvbiBhbnl0aGluZywgcmVzb2x2ZSB0aGUgbWFzdGVyXG5cdFx0aWYgKCAhcmVtYWluaW5nICkge1xuXHRcdFx0ZGVmZXJyZWQucmVzb2x2ZVdpdGgoIHJlc29sdmVDb250ZXh0cywgcmVzb2x2ZVZhbHVlcyApO1xuXHRcdH1cblxuXHRcdHJldHVybiBkZWZlcnJlZC5wcm9taXNlKCk7XG5cdH1cbn0pO1xuXG5cbi8vIFRoZSBkZWZlcnJlZCB1c2VkIG9uIERPTSByZWFkeVxudmFyIHJlYWR5TGlzdDtcblxualF1ZXJ5LmZuLnJlYWR5ID0gZnVuY3Rpb24oIGZuICkge1xuXHQvLyBBZGQgdGhlIGNhbGxiYWNrXG5cdGpRdWVyeS5yZWFkeS5wcm9taXNlKCkuZG9uZSggZm4gKTtcblxuXHRyZXR1cm4gdGhpcztcbn07XG5cbmpRdWVyeS5leHRlbmQoe1xuXHQvLyBJcyB0aGUgRE9NIHJlYWR5IHRvIGJlIHVzZWQ/IFNldCB0byB0cnVlIG9uY2UgaXQgb2NjdXJzLlxuXHRpc1JlYWR5OiBmYWxzZSxcblxuXHQvLyBBIGNvdW50ZXIgdG8gdHJhY2sgaG93IG1hbnkgaXRlbXMgdG8gd2FpdCBmb3IgYmVmb3JlXG5cdC8vIHRoZSByZWFkeSBldmVudCBmaXJlcy4gU2VlICM2NzgxXG5cdHJlYWR5V2FpdDogMSxcblxuXHQvLyBIb2xkIChvciByZWxlYXNlKSB0aGUgcmVhZHkgZXZlbnRcblx0aG9sZFJlYWR5OiBmdW5jdGlvbiggaG9sZCApIHtcblx0XHRpZiAoIGhvbGQgKSB7XG5cdFx0XHRqUXVlcnkucmVhZHlXYWl0Kys7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpRdWVyeS5yZWFkeSggdHJ1ZSApO1xuXHRcdH1cblx0fSxcblxuXHQvLyBIYW5kbGUgd2hlbiB0aGUgRE9NIGlzIHJlYWR5XG5cdHJlYWR5OiBmdW5jdGlvbiggd2FpdCApIHtcblxuXHRcdC8vIEFib3J0IGlmIHRoZXJlIGFyZSBwZW5kaW5nIGhvbGRzIG9yIHdlJ3JlIGFscmVhZHkgcmVhZHlcblx0XHRpZiAoIHdhaXQgPT09IHRydWUgPyAtLWpRdWVyeS5yZWFkeVdhaXQgOiBqUXVlcnkuaXNSZWFkeSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBNYWtlIHN1cmUgYm9keSBleGlzdHMsIGF0IGxlYXN0LCBpbiBjYXNlIElFIGdldHMgYSBsaXR0bGUgb3ZlcnplYWxvdXMgKHRpY2tldCAjNTQ0MykuXG5cdFx0aWYgKCAhZG9jdW1lbnQuYm9keSApIHtcblx0XHRcdHJldHVybiBzZXRUaW1lb3V0KCBqUXVlcnkucmVhZHkgKTtcblx0XHR9XG5cblx0XHQvLyBSZW1lbWJlciB0aGF0IHRoZSBET00gaXMgcmVhZHlcblx0XHRqUXVlcnkuaXNSZWFkeSA9IHRydWU7XG5cblx0XHQvLyBJZiBhIG5vcm1hbCBET00gUmVhZHkgZXZlbnQgZmlyZWQsIGRlY3JlbWVudCwgYW5kIHdhaXQgaWYgbmVlZCBiZVxuXHRcdGlmICggd2FpdCAhPT0gdHJ1ZSAmJiAtLWpRdWVyeS5yZWFkeVdhaXQgPiAwICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIElmIHRoZXJlIGFyZSBmdW5jdGlvbnMgYm91bmQsIHRvIGV4ZWN1dGVcblx0XHRyZWFkeUxpc3QucmVzb2x2ZVdpdGgoIGRvY3VtZW50LCBbIGpRdWVyeSBdICk7XG5cblx0XHQvLyBUcmlnZ2VyIGFueSBib3VuZCByZWFkeSBldmVudHNcblx0XHRpZiAoIGpRdWVyeS5mbi50cmlnZ2VySGFuZGxlciApIHtcblx0XHRcdGpRdWVyeSggZG9jdW1lbnQgKS50cmlnZ2VySGFuZGxlciggXCJyZWFkeVwiICk7XG5cdFx0XHRqUXVlcnkoIGRvY3VtZW50ICkub2ZmKCBcInJlYWR5XCIgKTtcblx0XHR9XG5cdH1cbn0pO1xuXG4vKipcbiAqIENsZWFuLXVwIG1ldGhvZCBmb3IgZG9tIHJlYWR5IGV2ZW50c1xuICovXG5mdW5jdGlvbiBkZXRhY2goKSB7XG5cdGlmICggZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciApIHtcblx0XHRkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCBcIkRPTUNvbnRlbnRMb2FkZWRcIiwgY29tcGxldGVkLCBmYWxzZSApO1xuXHRcdHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCBcImxvYWRcIiwgY29tcGxldGVkLCBmYWxzZSApO1xuXG5cdH0gZWxzZSB7XG5cdFx0ZG9jdW1lbnQuZGV0YWNoRXZlbnQoIFwib25yZWFkeXN0YXRlY2hhbmdlXCIsIGNvbXBsZXRlZCApO1xuXHRcdHdpbmRvdy5kZXRhY2hFdmVudCggXCJvbmxvYWRcIiwgY29tcGxldGVkICk7XG5cdH1cbn1cblxuLyoqXG4gKiBUaGUgcmVhZHkgZXZlbnQgaGFuZGxlciBhbmQgc2VsZiBjbGVhbnVwIG1ldGhvZFxuICovXG5mdW5jdGlvbiBjb21wbGV0ZWQoKSB7XG5cdC8vIHJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIiBpcyBnb29kIGVub3VnaCBmb3IgdXMgdG8gY2FsbCB0aGUgZG9tIHJlYWR5IGluIG9sZElFXG5cdGlmICggZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciB8fCBldmVudC50eXBlID09PSBcImxvYWRcIiB8fCBkb2N1bWVudC5yZWFkeVN0YXRlID09PSBcImNvbXBsZXRlXCIgKSB7XG5cdFx0ZGV0YWNoKCk7XG5cdFx0alF1ZXJ5LnJlYWR5KCk7XG5cdH1cbn1cblxualF1ZXJ5LnJlYWR5LnByb21pc2UgPSBmdW5jdGlvbiggb2JqICkge1xuXHRpZiAoICFyZWFkeUxpc3QgKSB7XG5cblx0XHRyZWFkeUxpc3QgPSBqUXVlcnkuRGVmZXJyZWQoKTtcblxuXHRcdC8vIENhdGNoIGNhc2VzIHdoZXJlICQoZG9jdW1lbnQpLnJlYWR5KCkgaXMgY2FsbGVkIGFmdGVyIHRoZSBicm93c2VyIGV2ZW50IGhhcyBhbHJlYWR5IG9jY3VycmVkLlxuXHRcdC8vIHdlIG9uY2UgdHJpZWQgdG8gdXNlIHJlYWR5U3RhdGUgXCJpbnRlcmFjdGl2ZVwiIGhlcmUsIGJ1dCBpdCBjYXVzZWQgaXNzdWVzIGxpa2UgdGhlIG9uZVxuXHRcdC8vIGRpc2NvdmVyZWQgYnkgQ2hyaXNTIGhlcmU6IGh0dHA6Ly9idWdzLmpxdWVyeS5jb20vdGlja2V0LzEyMjgyI2NvbW1lbnQ6MTVcblx0XHRpZiAoIGRvY3VtZW50LnJlYWR5U3RhdGUgPT09IFwiY29tcGxldGVcIiApIHtcblx0XHRcdC8vIEhhbmRsZSBpdCBhc3luY2hyb25vdXNseSB0byBhbGxvdyBzY3JpcHRzIHRoZSBvcHBvcnR1bml0eSB0byBkZWxheSByZWFkeVxuXHRcdFx0c2V0VGltZW91dCggalF1ZXJ5LnJlYWR5ICk7XG5cblx0XHQvLyBTdGFuZGFyZHMtYmFzZWQgYnJvd3NlcnMgc3VwcG9ydCBET01Db250ZW50TG9hZGVkXG5cdFx0fSBlbHNlIGlmICggZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lciApIHtcblx0XHRcdC8vIFVzZSB0aGUgaGFuZHkgZXZlbnQgY2FsbGJhY2tcblx0XHRcdGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoIFwiRE9NQ29udGVudExvYWRlZFwiLCBjb21wbGV0ZWQsIGZhbHNlICk7XG5cblx0XHRcdC8vIEEgZmFsbGJhY2sgdG8gd2luZG93Lm9ubG9hZCwgdGhhdCB3aWxsIGFsd2F5cyB3b3JrXG5cdFx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lciggXCJsb2FkXCIsIGNvbXBsZXRlZCwgZmFsc2UgKTtcblxuXHRcdC8vIElmIElFIGV2ZW50IG1vZGVsIGlzIHVzZWRcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gRW5zdXJlIGZpcmluZyBiZWZvcmUgb25sb2FkLCBtYXliZSBsYXRlIGJ1dCBzYWZlIGFsc28gZm9yIGlmcmFtZXNcblx0XHRcdGRvY3VtZW50LmF0dGFjaEV2ZW50KCBcIm9ucmVhZHlzdGF0ZWNoYW5nZVwiLCBjb21wbGV0ZWQgKTtcblxuXHRcdFx0Ly8gQSBmYWxsYmFjayB0byB3aW5kb3cub25sb2FkLCB0aGF0IHdpbGwgYWx3YXlzIHdvcmtcblx0XHRcdHdpbmRvdy5hdHRhY2hFdmVudCggXCJvbmxvYWRcIiwgY29tcGxldGVkICk7XG5cblx0XHRcdC8vIElmIElFIGFuZCBub3QgYSBmcmFtZVxuXHRcdFx0Ly8gY29udGludWFsbHkgY2hlY2sgdG8gc2VlIGlmIHRoZSBkb2N1bWVudCBpcyByZWFkeVxuXHRcdFx0dmFyIHRvcCA9IGZhbHNlO1xuXG5cdFx0XHR0cnkge1xuXHRcdFx0XHR0b3AgPSB3aW5kb3cuZnJhbWVFbGVtZW50ID09IG51bGwgJiYgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXHRcdFx0fSBjYXRjaChlKSB7fVxuXG5cdFx0XHRpZiAoIHRvcCAmJiB0b3AuZG9TY3JvbGwgKSB7XG5cdFx0XHRcdChmdW5jdGlvbiBkb1Njcm9sbENoZWNrKCkge1xuXHRcdFx0XHRcdGlmICggIWpRdWVyeS5pc1JlYWR5ICkge1xuXG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHQvLyBVc2UgdGhlIHRyaWNrIGJ5IERpZWdvIFBlcmluaVxuXHRcdFx0XHRcdFx0XHQvLyBodHRwOi8vamF2YXNjcmlwdC5ud2JveC5jb20vSUVDb250ZW50TG9hZGVkL1xuXHRcdFx0XHRcdFx0XHR0b3AuZG9TY3JvbGwoXCJsZWZ0XCIpO1xuXHRcdFx0XHRcdFx0fSBjYXRjaChlKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiBzZXRUaW1lb3V0KCBkb1Njcm9sbENoZWNrLCA1MCApO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBkZXRhY2ggYWxsIGRvbSByZWFkeSBldmVudHNcblx0XHRcdFx0XHRcdGRldGFjaCgpO1xuXG5cdFx0XHRcdFx0XHQvLyBhbmQgZXhlY3V0ZSBhbnkgd2FpdGluZyBmdW5jdGlvbnNcblx0XHRcdFx0XHRcdGpRdWVyeS5yZWFkeSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSkoKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cmV0dXJuIHJlYWR5TGlzdC5wcm9taXNlKCBvYmogKTtcbn07XG5cblxudmFyIHN0cnVuZGVmaW5lZCA9IHR5cGVvZiB1bmRlZmluZWQ7XG5cblxuXG4vLyBTdXBwb3J0OiBJRTw5XG4vLyBJdGVyYXRpb24gb3ZlciBvYmplY3QncyBpbmhlcml0ZWQgcHJvcGVydGllcyBiZWZvcmUgaXRzIG93blxudmFyIGk7XG5mb3IgKCBpIGluIGpRdWVyeSggc3VwcG9ydCApICkge1xuXHRicmVhaztcbn1cbnN1cHBvcnQub3duTGFzdCA9IGkgIT09IFwiMFwiO1xuXG4vLyBOb3RlOiBtb3N0IHN1cHBvcnQgdGVzdHMgYXJlIGRlZmluZWQgaW4gdGhlaXIgcmVzcGVjdGl2ZSBtb2R1bGVzLlxuLy8gZmFsc2UgdW50aWwgdGhlIHRlc3QgaXMgcnVuXG5zdXBwb3J0LmlubGluZUJsb2NrTmVlZHNMYXlvdXQgPSBmYWxzZTtcblxuLy8gRXhlY3V0ZSBBU0FQIGluIGNhc2Ugd2UgbmVlZCB0byBzZXQgYm9keS5zdHlsZS56b29tXG5qUXVlcnkoZnVuY3Rpb24oKSB7XG5cdC8vIE1pbmlmaWVkOiB2YXIgYSxiLGMsZFxuXHR2YXIgdmFsLCBkaXYsIGJvZHksIGNvbnRhaW5lcjtcblxuXHRib2R5ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwiYm9keVwiIClbIDAgXTtcblx0aWYgKCAhYm9keSB8fCAhYm9keS5zdHlsZSApIHtcblx0XHQvLyBSZXR1cm4gZm9yIGZyYW1lc2V0IGRvY3MgdGhhdCBkb24ndCBoYXZlIGEgYm9keVxuXHRcdHJldHVybjtcblx0fVxuXG5cdC8vIFNldHVwXG5cdGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblx0Y29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApO1xuXHRjb250YWluZXIuc3R5bGUuY3NzVGV4dCA9IFwicG9zaXRpb246YWJzb2x1dGU7Ym9yZGVyOjA7d2lkdGg6MDtoZWlnaHQ6MDt0b3A6MDtsZWZ0Oi05OTk5cHhcIjtcblx0Ym9keS5hcHBlbmRDaGlsZCggY29udGFpbmVyICkuYXBwZW5kQ2hpbGQoIGRpdiApO1xuXG5cdGlmICggdHlwZW9mIGRpdi5zdHlsZS56b29tICE9PSBzdHJ1bmRlZmluZWQgKSB7XG5cdFx0Ly8gU3VwcG9ydDogSUU8OFxuXHRcdC8vIENoZWNrIGlmIG5hdGl2ZWx5IGJsb2NrLWxldmVsIGVsZW1lbnRzIGFjdCBsaWtlIGlubGluZS1ibG9ja1xuXHRcdC8vIGVsZW1lbnRzIHdoZW4gc2V0dGluZyB0aGVpciBkaXNwbGF5IHRvICdpbmxpbmUnIGFuZCBnaXZpbmdcblx0XHQvLyB0aGVtIGxheW91dFxuXHRcdGRpdi5zdHlsZS5jc3NUZXh0ID0gXCJkaXNwbGF5OmlubGluZTttYXJnaW46MDtib3JkZXI6MDtwYWRkaW5nOjFweDt3aWR0aDoxcHg7em9vbToxXCI7XG5cblx0XHRzdXBwb3J0LmlubGluZUJsb2NrTmVlZHNMYXlvdXQgPSB2YWwgPSBkaXYub2Zmc2V0V2lkdGggPT09IDM7XG5cdFx0aWYgKCB2YWwgKSB7XG5cdFx0XHQvLyBQcmV2ZW50IElFIDYgZnJvbSBhZmZlY3RpbmcgbGF5b3V0IGZvciBwb3NpdGlvbmVkIGVsZW1lbnRzICMxMTA0OFxuXHRcdFx0Ly8gUHJldmVudCBJRSBmcm9tIHNocmlua2luZyB0aGUgYm9keSBpbiBJRSA3IG1vZGUgIzEyODY5XG5cdFx0XHQvLyBTdXBwb3J0OiBJRTw4XG5cdFx0XHRib2R5LnN0eWxlLnpvb20gPSAxO1xuXHRcdH1cblx0fVxuXG5cdGJvZHkucmVtb3ZlQ2hpbGQoIGNvbnRhaW5lciApO1xufSk7XG5cblxuXG5cbihmdW5jdGlvbigpIHtcblx0dmFyIGRpdiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKTtcblxuXHQvLyBFeGVjdXRlIHRoZSB0ZXN0IG9ubHkgaWYgbm90IGFscmVhZHkgZXhlY3V0ZWQgaW4gYW5vdGhlciBtb2R1bGUuXG5cdGlmIChzdXBwb3J0LmRlbGV0ZUV4cGFuZG8gPT0gbnVsbCkge1xuXHRcdC8vIFN1cHBvcnQ6IElFPDlcblx0XHRzdXBwb3J0LmRlbGV0ZUV4cGFuZG8gPSB0cnVlO1xuXHRcdHRyeSB7XG5cdFx0XHRkZWxldGUgZGl2LnRlc3Q7XG5cdFx0fSBjYXRjaCggZSApIHtcblx0XHRcdHN1cHBvcnQuZGVsZXRlRXhwYW5kbyA9IGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdC8vIE51bGwgZWxlbWVudHMgdG8gYXZvaWQgbGVha3MgaW4gSUUuXG5cdGRpdiA9IG51bGw7XG59KSgpO1xuXG5cbi8qKlxuICogRGV0ZXJtaW5lcyB3aGV0aGVyIGFuIG9iamVjdCBjYW4gaGF2ZSBkYXRhXG4gKi9cbmpRdWVyeS5hY2NlcHREYXRhID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHZhciBub0RhdGEgPSBqUXVlcnkubm9EYXRhWyAoZWxlbS5ub2RlTmFtZSArIFwiIFwiKS50b0xvd2VyQ2FzZSgpIF0sXG5cdFx0bm9kZVR5cGUgPSArZWxlbS5ub2RlVHlwZSB8fCAxO1xuXG5cdC8vIERvIG5vdCBzZXQgZGF0YSBvbiBub24tZWxlbWVudCBET00gbm9kZXMgYmVjYXVzZSBpdCB3aWxsIG5vdCBiZSBjbGVhcmVkICgjODMzNSkuXG5cdHJldHVybiBub2RlVHlwZSAhPT0gMSAmJiBub2RlVHlwZSAhPT0gOSA/XG5cdFx0ZmFsc2UgOlxuXG5cdFx0Ly8gTm9kZXMgYWNjZXB0IGRhdGEgdW5sZXNzIG90aGVyd2lzZSBzcGVjaWZpZWQ7IHJlamVjdGlvbiBjYW4gYmUgY29uZGl0aW9uYWxcblx0XHQhbm9EYXRhIHx8IG5vRGF0YSAhPT0gdHJ1ZSAmJiBlbGVtLmdldEF0dHJpYnV0ZShcImNsYXNzaWRcIikgPT09IG5vRGF0YTtcbn07XG5cblxudmFyIHJicmFjZSA9IC9eKD86XFx7W1xcd1xcV10qXFx9fFxcW1tcXHdcXFddKlxcXSkkLyxcblx0cm11bHRpRGFzaCA9IC8oW0EtWl0pL2c7XG5cbmZ1bmN0aW9uIGRhdGFBdHRyKCBlbGVtLCBrZXksIGRhdGEgKSB7XG5cdC8vIElmIG5vdGhpbmcgd2FzIGZvdW5kIGludGVybmFsbHksIHRyeSB0byBmZXRjaCBhbnlcblx0Ly8gZGF0YSBmcm9tIHRoZSBIVE1MNSBkYXRhLSogYXR0cmlidXRlXG5cdGlmICggZGF0YSA9PT0gdW5kZWZpbmVkICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cblx0XHR2YXIgbmFtZSA9IFwiZGF0YS1cIiArIGtleS5yZXBsYWNlKCBybXVsdGlEYXNoLCBcIi0kMVwiICkudG9Mb3dlckNhc2UoKTtcblxuXHRcdGRhdGEgPSBlbGVtLmdldEF0dHJpYnV0ZSggbmFtZSApO1xuXG5cdFx0aWYgKCB0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHRyeSB7XG5cdFx0XHRcdGRhdGEgPSBkYXRhID09PSBcInRydWVcIiA/IHRydWUgOlxuXHRcdFx0XHRcdGRhdGEgPT09IFwiZmFsc2VcIiA/IGZhbHNlIDpcblx0XHRcdFx0XHRkYXRhID09PSBcIm51bGxcIiA/IG51bGwgOlxuXHRcdFx0XHRcdC8vIE9ubHkgY29udmVydCB0byBhIG51bWJlciBpZiBpdCBkb2Vzbid0IGNoYW5nZSB0aGUgc3RyaW5nXG5cdFx0XHRcdFx0K2RhdGEgKyBcIlwiID09PSBkYXRhID8gK2RhdGEgOlxuXHRcdFx0XHRcdHJicmFjZS50ZXN0KCBkYXRhICkgPyBqUXVlcnkucGFyc2VKU09OKCBkYXRhICkgOlxuXHRcdFx0XHRcdGRhdGE7XG5cdFx0XHR9IGNhdGNoKCBlICkge31cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHdlIHNldCB0aGUgZGF0YSBzbyBpdCBpc24ndCBjaGFuZ2VkIGxhdGVyXG5cdFx0XHRqUXVlcnkuZGF0YSggZWxlbSwga2V5LCBkYXRhICk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZGF0YTtcbn1cblxuLy8gY2hlY2tzIGEgY2FjaGUgb2JqZWN0IGZvciBlbXB0aW5lc3NcbmZ1bmN0aW9uIGlzRW1wdHlEYXRhT2JqZWN0KCBvYmogKSB7XG5cdHZhciBuYW1lO1xuXHRmb3IgKCBuYW1lIGluIG9iaiApIHtcblxuXHRcdC8vIGlmIHRoZSBwdWJsaWMgZGF0YSBvYmplY3QgaXMgZW1wdHksIHRoZSBwcml2YXRlIGlzIHN0aWxsIGVtcHR5XG5cdFx0aWYgKCBuYW1lID09PSBcImRhdGFcIiAmJiBqUXVlcnkuaXNFbXB0eU9iamVjdCggb2JqW25hbWVdICkgKSB7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cdFx0aWYgKCBuYW1lICE9PSBcInRvSlNPTlwiICkge1xuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBpbnRlcm5hbERhdGEoIGVsZW0sIG5hbWUsIGRhdGEsIHB2dCAvKiBJbnRlcm5hbCBVc2UgT25seSAqLyApIHtcblx0aWYgKCAhalF1ZXJ5LmFjY2VwdERhdGEoIGVsZW0gKSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHR2YXIgcmV0LCB0aGlzQ2FjaGUsXG5cdFx0aW50ZXJuYWxLZXkgPSBqUXVlcnkuZXhwYW5kbyxcblxuXHRcdC8vIFdlIGhhdmUgdG8gaGFuZGxlIERPTSBub2RlcyBhbmQgSlMgb2JqZWN0cyBkaWZmZXJlbnRseSBiZWNhdXNlIElFNi03XG5cdFx0Ly8gY2FuJ3QgR0Mgb2JqZWN0IHJlZmVyZW5jZXMgcHJvcGVybHkgYWNyb3NzIHRoZSBET00tSlMgYm91bmRhcnlcblx0XHRpc05vZGUgPSBlbGVtLm5vZGVUeXBlLFxuXG5cdFx0Ly8gT25seSBET00gbm9kZXMgbmVlZCB0aGUgZ2xvYmFsIGpRdWVyeSBjYWNoZTsgSlMgb2JqZWN0IGRhdGEgaXNcblx0XHQvLyBhdHRhY2hlZCBkaXJlY3RseSB0byB0aGUgb2JqZWN0IHNvIEdDIGNhbiBvY2N1ciBhdXRvbWF0aWNhbGx5XG5cdFx0Y2FjaGUgPSBpc05vZGUgPyBqUXVlcnkuY2FjaGUgOiBlbGVtLFxuXG5cdFx0Ly8gT25seSBkZWZpbmluZyBhbiBJRCBmb3IgSlMgb2JqZWN0cyBpZiBpdHMgY2FjaGUgYWxyZWFkeSBleGlzdHMgYWxsb3dzXG5cdFx0Ly8gdGhlIGNvZGUgdG8gc2hvcnRjdXQgb24gdGhlIHNhbWUgcGF0aCBhcyBhIERPTSBub2RlIHdpdGggbm8gY2FjaGVcblx0XHRpZCA9IGlzTm9kZSA/IGVsZW1bIGludGVybmFsS2V5IF0gOiBlbGVtWyBpbnRlcm5hbEtleSBdICYmIGludGVybmFsS2V5O1xuXG5cdC8vIEF2b2lkIGRvaW5nIGFueSBtb3JlIHdvcmsgdGhhbiB3ZSBuZWVkIHRvIHdoZW4gdHJ5aW5nIHRvIGdldCBkYXRhIG9uIGFuXG5cdC8vIG9iamVjdCB0aGF0IGhhcyBubyBkYXRhIGF0IGFsbFxuXHRpZiAoICghaWQgfHwgIWNhY2hlW2lkXSB8fCAoIXB2dCAmJiAhY2FjaGVbaWRdLmRhdGEpKSAmJiBkYXRhID09PSB1bmRlZmluZWQgJiYgdHlwZW9mIG5hbWUgPT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0aWYgKCAhaWQgKSB7XG5cdFx0Ly8gT25seSBET00gbm9kZXMgbmVlZCBhIG5ldyB1bmlxdWUgSUQgZm9yIGVhY2ggZWxlbWVudCBzaW5jZSB0aGVpciBkYXRhXG5cdFx0Ly8gZW5kcyB1cCBpbiB0aGUgZ2xvYmFsIGNhY2hlXG5cdFx0aWYgKCBpc05vZGUgKSB7XG5cdFx0XHRpZCA9IGVsZW1bIGludGVybmFsS2V5IF0gPSBkZWxldGVkSWRzLnBvcCgpIHx8IGpRdWVyeS5ndWlkKys7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGlkID0gaW50ZXJuYWxLZXk7XG5cdFx0fVxuXHR9XG5cblx0aWYgKCAhY2FjaGVbIGlkIF0gKSB7XG5cdFx0Ly8gQXZvaWQgZXhwb3NpbmcgalF1ZXJ5IG1ldGFkYXRhIG9uIHBsYWluIEpTIG9iamVjdHMgd2hlbiB0aGUgb2JqZWN0XG5cdFx0Ly8gaXMgc2VyaWFsaXplZCB1c2luZyBKU09OLnN0cmluZ2lmeVxuXHRcdGNhY2hlWyBpZCBdID0gaXNOb2RlID8ge30gOiB7IHRvSlNPTjogalF1ZXJ5Lm5vb3AgfTtcblx0fVxuXG5cdC8vIEFuIG9iamVjdCBjYW4gYmUgcGFzc2VkIHRvIGpRdWVyeS5kYXRhIGluc3RlYWQgb2YgYSBrZXkvdmFsdWUgcGFpcjsgdGhpcyBnZXRzXG5cdC8vIHNoYWxsb3cgY29waWVkIG92ZXIgb250byB0aGUgZXhpc3RpbmcgY2FjaGVcblx0aWYgKCB0eXBlb2YgbmFtZSA9PT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgbmFtZSA9PT0gXCJmdW5jdGlvblwiICkge1xuXHRcdGlmICggcHZ0ICkge1xuXHRcdFx0Y2FjaGVbIGlkIF0gPSBqUXVlcnkuZXh0ZW5kKCBjYWNoZVsgaWQgXSwgbmFtZSApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRjYWNoZVsgaWQgXS5kYXRhID0galF1ZXJ5LmV4dGVuZCggY2FjaGVbIGlkIF0uZGF0YSwgbmFtZSApO1xuXHRcdH1cblx0fVxuXG5cdHRoaXNDYWNoZSA9IGNhY2hlWyBpZCBdO1xuXG5cdC8vIGpRdWVyeSBkYXRhKCkgaXMgc3RvcmVkIGluIGEgc2VwYXJhdGUgb2JqZWN0IGluc2lkZSB0aGUgb2JqZWN0J3MgaW50ZXJuYWwgZGF0YVxuXHQvLyBjYWNoZSBpbiBvcmRlciB0byBhdm9pZCBrZXkgY29sbGlzaW9ucyBiZXR3ZWVuIGludGVybmFsIGRhdGEgYW5kIHVzZXItZGVmaW5lZFxuXHQvLyBkYXRhLlxuXHRpZiAoICFwdnQgKSB7XG5cdFx0aWYgKCAhdGhpc0NhY2hlLmRhdGEgKSB7XG5cdFx0XHR0aGlzQ2FjaGUuZGF0YSA9IHt9O1xuXHRcdH1cblxuXHRcdHRoaXNDYWNoZSA9IHRoaXNDYWNoZS5kYXRhO1xuXHR9XG5cblx0aWYgKCBkYXRhICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0dGhpc0NhY2hlWyBqUXVlcnkuY2FtZWxDYXNlKCBuYW1lICkgXSA9IGRhdGE7XG5cdH1cblxuXHQvLyBDaGVjayBmb3IgYm90aCBjb252ZXJ0ZWQtdG8tY2FtZWwgYW5kIG5vbi1jb252ZXJ0ZWQgZGF0YSBwcm9wZXJ0eSBuYW1lc1xuXHQvLyBJZiBhIGRhdGEgcHJvcGVydHkgd2FzIHNwZWNpZmllZFxuXHRpZiAoIHR5cGVvZiBuYW1lID09PSBcInN0cmluZ1wiICkge1xuXG5cdFx0Ly8gRmlyc3QgVHJ5IHRvIGZpbmQgYXMtaXMgcHJvcGVydHkgZGF0YVxuXHRcdHJldCA9IHRoaXNDYWNoZVsgbmFtZSBdO1xuXG5cdFx0Ly8gVGVzdCBmb3IgbnVsbHx1bmRlZmluZWQgcHJvcGVydHkgZGF0YVxuXHRcdGlmICggcmV0ID09IG51bGwgKSB7XG5cblx0XHRcdC8vIFRyeSB0byBmaW5kIHRoZSBjYW1lbENhc2VkIHByb3BlcnR5XG5cdFx0XHRyZXQgPSB0aGlzQ2FjaGVbIGpRdWVyeS5jYW1lbENhc2UoIG5hbWUgKSBdO1xuXHRcdH1cblx0fSBlbHNlIHtcblx0XHRyZXQgPSB0aGlzQ2FjaGU7XG5cdH1cblxuXHRyZXR1cm4gcmV0O1xufVxuXG5mdW5jdGlvbiBpbnRlcm5hbFJlbW92ZURhdGEoIGVsZW0sIG5hbWUsIHB2dCApIHtcblx0aWYgKCAhalF1ZXJ5LmFjY2VwdERhdGEoIGVsZW0gKSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHR2YXIgdGhpc0NhY2hlLCBpLFxuXHRcdGlzTm9kZSA9IGVsZW0ubm9kZVR5cGUsXG5cblx0XHQvLyBTZWUgalF1ZXJ5LmRhdGEgZm9yIG1vcmUgaW5mb3JtYXRpb25cblx0XHRjYWNoZSA9IGlzTm9kZSA/IGpRdWVyeS5jYWNoZSA6IGVsZW0sXG5cdFx0aWQgPSBpc05vZGUgPyBlbGVtWyBqUXVlcnkuZXhwYW5kbyBdIDogalF1ZXJ5LmV4cGFuZG87XG5cblx0Ly8gSWYgdGhlcmUgaXMgYWxyZWFkeSBubyBjYWNoZSBlbnRyeSBmb3IgdGhpcyBvYmplY3QsIHRoZXJlIGlzIG5vXG5cdC8vIHB1cnBvc2UgaW4gY29udGludWluZ1xuXHRpZiAoICFjYWNoZVsgaWQgXSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRpZiAoIG5hbWUgKSB7XG5cblx0XHR0aGlzQ2FjaGUgPSBwdnQgPyBjYWNoZVsgaWQgXSA6IGNhY2hlWyBpZCBdLmRhdGE7XG5cblx0XHRpZiAoIHRoaXNDYWNoZSApIHtcblxuXHRcdFx0Ly8gU3VwcG9ydCBhcnJheSBvciBzcGFjZSBzZXBhcmF0ZWQgc3RyaW5nIG5hbWVzIGZvciBkYXRhIGtleXNcblx0XHRcdGlmICggIWpRdWVyeS5pc0FycmF5KCBuYW1lICkgKSB7XG5cblx0XHRcdFx0Ly8gdHJ5IHRoZSBzdHJpbmcgYXMgYSBrZXkgYmVmb3JlIGFueSBtYW5pcHVsYXRpb25cblx0XHRcdFx0aWYgKCBuYW1lIGluIHRoaXNDYWNoZSApIHtcblx0XHRcdFx0XHRuYW1lID0gWyBuYW1lIF07XG5cdFx0XHRcdH0gZWxzZSB7XG5cblx0XHRcdFx0XHQvLyBzcGxpdCB0aGUgY2FtZWwgY2FzZWQgdmVyc2lvbiBieSBzcGFjZXMgdW5sZXNzIGEga2V5IHdpdGggdGhlIHNwYWNlcyBleGlzdHNcblx0XHRcdFx0XHRuYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggbmFtZSApO1xuXHRcdFx0XHRcdGlmICggbmFtZSBpbiB0aGlzQ2FjaGUgKSB7XG5cdFx0XHRcdFx0XHRuYW1lID0gWyBuYW1lIF07XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdG5hbWUgPSBuYW1lLnNwbGl0KFwiIFwiKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIElmIFwibmFtZVwiIGlzIGFuIGFycmF5IG9mIGtleXMuLi5cblx0XHRcdFx0Ly8gV2hlbiBkYXRhIGlzIGluaXRpYWxseSBjcmVhdGVkLCB2aWEgKFwia2V5XCIsIFwidmFsXCIpIHNpZ25hdHVyZSxcblx0XHRcdFx0Ly8ga2V5cyB3aWxsIGJlIGNvbnZlcnRlZCB0byBjYW1lbENhc2UuXG5cdFx0XHRcdC8vIFNpbmNlIHRoZXJlIGlzIG5vIHdheSB0byB0ZWxsIF9ob3dfIGEga2V5IHdhcyBhZGRlZCwgcmVtb3ZlXG5cdFx0XHRcdC8vIGJvdGggcGxhaW4ga2V5IGFuZCBjYW1lbENhc2Uga2V5LiAjMTI3ODZcblx0XHRcdFx0Ly8gVGhpcyB3aWxsIG9ubHkgcGVuYWxpemUgdGhlIGFycmF5IGFyZ3VtZW50IHBhdGguXG5cdFx0XHRcdG5hbWUgPSBuYW1lLmNvbmNhdCggalF1ZXJ5Lm1hcCggbmFtZSwgalF1ZXJ5LmNhbWVsQ2FzZSApICk7XG5cdFx0XHR9XG5cblx0XHRcdGkgPSBuYW1lLmxlbmd0aDtcblx0XHRcdHdoaWxlICggaS0tICkge1xuXHRcdFx0XHRkZWxldGUgdGhpc0NhY2hlWyBuYW1lW2ldIF07XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIHRoZXJlIGlzIG5vIGRhdGEgbGVmdCBpbiB0aGUgY2FjaGUsIHdlIHdhbnQgdG8gY29udGludWVcblx0XHRcdC8vIGFuZCBsZXQgdGhlIGNhY2hlIG9iamVjdCBpdHNlbGYgZ2V0IGRlc3Ryb3llZFxuXHRcdFx0aWYgKCBwdnQgPyAhaXNFbXB0eURhdGFPYmplY3QodGhpc0NhY2hlKSA6ICFqUXVlcnkuaXNFbXB0eU9iamVjdCh0aGlzQ2FjaGUpICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gU2VlIGpRdWVyeS5kYXRhIGZvciBtb3JlIGluZm9ybWF0aW9uXG5cdGlmICggIXB2dCApIHtcblx0XHRkZWxldGUgY2FjaGVbIGlkIF0uZGF0YTtcblxuXHRcdC8vIERvbid0IGRlc3Ryb3kgdGhlIHBhcmVudCBjYWNoZSB1bmxlc3MgdGhlIGludGVybmFsIGRhdGEgb2JqZWN0XG5cdFx0Ly8gaGFkIGJlZW4gdGhlIG9ubHkgdGhpbmcgbGVmdCBpbiBpdFxuXHRcdGlmICggIWlzRW1wdHlEYXRhT2JqZWN0KCBjYWNoZVsgaWQgXSApICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0fVxuXG5cdC8vIERlc3Ryb3kgdGhlIGNhY2hlXG5cdGlmICggaXNOb2RlICkge1xuXHRcdGpRdWVyeS5jbGVhbkRhdGEoIFsgZWxlbSBdLCB0cnVlICk7XG5cblx0Ly8gVXNlIGRlbGV0ZSB3aGVuIHN1cHBvcnRlZCBmb3IgZXhwYW5kb3Mgb3IgYGNhY2hlYCBpcyBub3QgYSB3aW5kb3cgcGVyIGlzV2luZG93ICgjMTAwODApXG5cdC8qIGpzaGludCBlcWVxZXE6IGZhbHNlICovXG5cdH0gZWxzZSBpZiAoIHN1cHBvcnQuZGVsZXRlRXhwYW5kbyB8fCBjYWNoZSAhPSBjYWNoZS53aW5kb3cgKSB7XG5cdFx0LyoganNoaW50IGVxZXFlcTogdHJ1ZSAqL1xuXHRcdGRlbGV0ZSBjYWNoZVsgaWQgXTtcblxuXHQvLyBXaGVuIGFsbCBlbHNlIGZhaWxzLCBudWxsXG5cdH0gZWxzZSB7XG5cdFx0Y2FjaGVbIGlkIF0gPSBudWxsO1xuXHR9XG59XG5cbmpRdWVyeS5leHRlbmQoe1xuXHRjYWNoZToge30sXG5cblx0Ly8gVGhlIGZvbGxvd2luZyBlbGVtZW50cyAoc3BhY2Utc3VmZml4ZWQgdG8gYXZvaWQgT2JqZWN0LnByb3RvdHlwZSBjb2xsaXNpb25zKVxuXHQvLyB0aHJvdyB1bmNhdGNoYWJsZSBleGNlcHRpb25zIGlmIHlvdSBhdHRlbXB0IHRvIHNldCBleHBhbmRvIHByb3BlcnRpZXNcblx0bm9EYXRhOiB7XG5cdFx0XCJhcHBsZXQgXCI6IHRydWUsXG5cdFx0XCJlbWJlZCBcIjogdHJ1ZSxcblx0XHQvLyAuLi5idXQgRmxhc2ggb2JqZWN0cyAod2hpY2ggaGF2ZSB0aGlzIGNsYXNzaWQpICpjYW4qIGhhbmRsZSBleHBhbmRvc1xuXHRcdFwib2JqZWN0IFwiOiBcImNsc2lkOkQyN0NEQjZFLUFFNkQtMTFjZi05NkI4LTQ0NDU1MzU0MDAwMFwiXG5cdH0sXG5cblx0aGFzRGF0YTogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0ZWxlbSA9IGVsZW0ubm9kZVR5cGUgPyBqUXVlcnkuY2FjaGVbIGVsZW1balF1ZXJ5LmV4cGFuZG9dIF0gOiBlbGVtWyBqUXVlcnkuZXhwYW5kbyBdO1xuXHRcdHJldHVybiAhIWVsZW0gJiYgIWlzRW1wdHlEYXRhT2JqZWN0KCBlbGVtICk7XG5cdH0sXG5cblx0ZGF0YTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGRhdGEgKSB7XG5cdFx0cmV0dXJuIGludGVybmFsRGF0YSggZWxlbSwgbmFtZSwgZGF0YSApO1xuXHR9LFxuXG5cdHJlbW92ZURhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHRcdHJldHVybiBpbnRlcm5hbFJlbW92ZURhdGEoIGVsZW0sIG5hbWUgKTtcblx0fSxcblxuXHQvLyBGb3IgaW50ZXJuYWwgdXNlIG9ubHkuXG5cdF9kYXRhOiBmdW5jdGlvbiggZWxlbSwgbmFtZSwgZGF0YSApIHtcblx0XHRyZXR1cm4gaW50ZXJuYWxEYXRhKCBlbGVtLCBuYW1lLCBkYXRhLCB0cnVlICk7XG5cdH0sXG5cblx0X3JlbW92ZURhdGE6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lICkge1xuXHRcdHJldHVybiBpbnRlcm5hbFJlbW92ZURhdGEoIGVsZW0sIG5hbWUsIHRydWUgKTtcblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRkYXRhOiBmdW5jdGlvbigga2V5LCB2YWx1ZSApIHtcblx0XHR2YXIgaSwgbmFtZSwgZGF0YSxcblx0XHRcdGVsZW0gPSB0aGlzWzBdLFxuXHRcdFx0YXR0cnMgPSBlbGVtICYmIGVsZW0uYXR0cmlidXRlcztcblxuXHRcdC8vIFNwZWNpYWwgZXhwZWN0aW9ucyBvZiAuZGF0YSBiYXNpY2FsbHkgdGh3YXJ0IGpRdWVyeS5hY2Nlc3MsXG5cdFx0Ly8gc28gaW1wbGVtZW50IHRoZSByZWxldmFudCBiZWhhdmlvciBvdXJzZWx2ZXNcblxuXHRcdC8vIEdldHMgYWxsIHZhbHVlc1xuXHRcdGlmICgga2V5ID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRpZiAoIHRoaXMubGVuZ3RoICkge1xuXHRcdFx0XHRkYXRhID0galF1ZXJ5LmRhdGEoIGVsZW0gKTtcblxuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgJiYgIWpRdWVyeS5fZGF0YSggZWxlbSwgXCJwYXJzZWRBdHRyc1wiICkgKSB7XG5cdFx0XHRcdFx0aSA9IGF0dHJzLmxlbmd0aDtcblx0XHRcdFx0XHR3aGlsZSAoIGktLSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUUxMStcblx0XHRcdFx0XHRcdC8vIFRoZSBhdHRycyBlbGVtZW50cyBjYW4gYmUgbnVsbCAoIzE0ODk0KVxuXHRcdFx0XHRcdFx0aWYgKCBhdHRyc1sgaSBdICkge1xuXHRcdFx0XHRcdFx0XHRuYW1lID0gYXR0cnNbIGkgXS5uYW1lO1xuXHRcdFx0XHRcdFx0XHRpZiAoIG5hbWUuaW5kZXhPZiggXCJkYXRhLVwiICkgPT09IDAgKSB7XG5cdFx0XHRcdFx0XHRcdFx0bmFtZSA9IGpRdWVyeS5jYW1lbENhc2UoIG5hbWUuc2xpY2UoNSkgKTtcblx0XHRcdFx0XHRcdFx0XHRkYXRhQXR0ciggZWxlbSwgbmFtZSwgZGF0YVsgbmFtZSBdICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0alF1ZXJ5Ll9kYXRhKCBlbGVtLCBcInBhcnNlZEF0dHJzXCIsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZGF0YTtcblx0XHR9XG5cblx0XHQvLyBTZXRzIG11bHRpcGxlIHZhbHVlc1xuXHRcdGlmICggdHlwZW9mIGtleSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeS5kYXRhKCB0aGlzLCBrZXkgKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMSA/XG5cblx0XHRcdC8vIFNldHMgb25lIHZhbHVlXG5cdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeS5kYXRhKCB0aGlzLCBrZXksIHZhbHVlICk7XG5cdFx0XHR9KSA6XG5cblx0XHRcdC8vIEdldHMgb25lIHZhbHVlXG5cdFx0XHQvLyBUcnkgdG8gZmV0Y2ggYW55IGludGVybmFsbHkgc3RvcmVkIGRhdGEgZmlyc3Rcblx0XHRcdGVsZW0gPyBkYXRhQXR0ciggZWxlbSwga2V5LCBqUXVlcnkuZGF0YSggZWxlbSwga2V5ICkgKSA6IHVuZGVmaW5lZDtcblx0fSxcblxuXHRyZW1vdmVEYXRhOiBmdW5jdGlvbigga2V5ICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkucmVtb3ZlRGF0YSggdGhpcywga2V5ICk7XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5cbmpRdWVyeS5leHRlbmQoe1xuXHRxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUsIGRhdGEgKSB7XG5cdFx0dmFyIHF1ZXVlO1xuXG5cdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0dHlwZSA9ICggdHlwZSB8fCBcImZ4XCIgKSArIFwicXVldWVcIjtcblx0XHRcdHF1ZXVlID0galF1ZXJ5Ll9kYXRhKCBlbGVtLCB0eXBlICk7XG5cblx0XHRcdC8vIFNwZWVkIHVwIGRlcXVldWUgYnkgZ2V0dGluZyBvdXQgcXVpY2tseSBpZiB0aGlzIGlzIGp1c3QgYSBsb29rdXBcblx0XHRcdGlmICggZGF0YSApIHtcblx0XHRcdFx0aWYgKCAhcXVldWUgfHwgalF1ZXJ5LmlzQXJyYXkoZGF0YSkgKSB7XG5cdFx0XHRcdFx0cXVldWUgPSBqUXVlcnkuX2RhdGEoIGVsZW0sIHR5cGUsIGpRdWVyeS5tYWtlQXJyYXkoZGF0YSkgKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRxdWV1ZS5wdXNoKCBkYXRhICk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBxdWV1ZSB8fCBbXTtcblx0XHR9XG5cdH0sXG5cblx0ZGVxdWV1ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7XG5cdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdFx0dmFyIHF1ZXVlID0galF1ZXJ5LnF1ZXVlKCBlbGVtLCB0eXBlICksXG5cdFx0XHRzdGFydExlbmd0aCA9IHF1ZXVlLmxlbmd0aCxcblx0XHRcdGZuID0gcXVldWUuc2hpZnQoKSxcblx0XHRcdGhvb2tzID0galF1ZXJ5Ll9xdWV1ZUhvb2tzKCBlbGVtLCB0eXBlICksXG5cdFx0XHRuZXh0ID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeS5kZXF1ZXVlKCBlbGVtLCB0eXBlICk7XG5cdFx0XHR9O1xuXG5cdFx0Ly8gSWYgdGhlIGZ4IHF1ZXVlIGlzIGRlcXVldWVkLCBhbHdheXMgcmVtb3ZlIHRoZSBwcm9ncmVzcyBzZW50aW5lbFxuXHRcdGlmICggZm4gPT09IFwiaW5wcm9ncmVzc1wiICkge1xuXHRcdFx0Zm4gPSBxdWV1ZS5zaGlmdCgpO1xuXHRcdFx0c3RhcnRMZW5ndGgtLTtcblx0XHR9XG5cblx0XHRpZiAoIGZuICkge1xuXG5cdFx0XHQvLyBBZGQgYSBwcm9ncmVzcyBzZW50aW5lbCB0byBwcmV2ZW50IHRoZSBmeCBxdWV1ZSBmcm9tIGJlaW5nXG5cdFx0XHQvLyBhdXRvbWF0aWNhbGx5IGRlcXVldWVkXG5cdFx0XHRpZiAoIHR5cGUgPT09IFwiZnhcIiApIHtcblx0XHRcdFx0cXVldWUudW5zaGlmdCggXCJpbnByb2dyZXNzXCIgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gY2xlYXIgdXAgdGhlIGxhc3QgcXVldWUgc3RvcCBmdW5jdGlvblxuXHRcdFx0ZGVsZXRlIGhvb2tzLnN0b3A7XG5cdFx0XHRmbi5jYWxsKCBlbGVtLCBuZXh0LCBob29rcyApO1xuXHRcdH1cblxuXHRcdGlmICggIXN0YXJ0TGVuZ3RoICYmIGhvb2tzICkge1xuXHRcdFx0aG9va3MuZW1wdHkuZmlyZSgpO1xuXHRcdH1cblx0fSxcblxuXHQvLyBub3QgaW50ZW5kZWQgZm9yIHB1YmxpYyBjb25zdW1wdGlvbiAtIGdlbmVyYXRlcyBhIHF1ZXVlSG9va3Mgb2JqZWN0LCBvciByZXR1cm5zIHRoZSBjdXJyZW50IG9uZVxuXHRfcXVldWVIb29rczogZnVuY3Rpb24oIGVsZW0sIHR5cGUgKSB7XG5cdFx0dmFyIGtleSA9IHR5cGUgKyBcInF1ZXVlSG9va3NcIjtcblx0XHRyZXR1cm4galF1ZXJ5Ll9kYXRhKCBlbGVtLCBrZXkgKSB8fCBqUXVlcnkuX2RhdGEoIGVsZW0sIGtleSwge1xuXHRcdFx0ZW1wdHk6IGpRdWVyeS5DYWxsYmFja3MoXCJvbmNlIG1lbW9yeVwiKS5hZGQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGpRdWVyeS5fcmVtb3ZlRGF0YSggZWxlbSwgdHlwZSArIFwicXVldWVcIiApO1xuXHRcdFx0XHRqUXVlcnkuX3JlbW92ZURhdGEoIGVsZW0sIGtleSApO1xuXHRcdFx0fSlcblx0XHR9KTtcblx0fVxufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRxdWV1ZTogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7XG5cdFx0dmFyIHNldHRlciA9IDI7XG5cblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0ZGF0YSA9IHR5cGU7XG5cdFx0XHR0eXBlID0gXCJmeFwiO1xuXHRcdFx0c2V0dGVyLS07XG5cdFx0fVxuXG5cdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoIDwgc2V0dGVyICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5xdWV1ZSggdGhpc1swXSwgdHlwZSApO1xuXHRcdH1cblxuXHRcdHJldHVybiBkYXRhID09PSB1bmRlZmluZWQgP1xuXHRcdFx0dGhpcyA6XG5cdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBxdWV1ZSA9IGpRdWVyeS5xdWV1ZSggdGhpcywgdHlwZSwgZGF0YSApO1xuXG5cdFx0XHRcdC8vIGVuc3VyZSBhIGhvb2tzIGZvciB0aGlzIHF1ZXVlXG5cdFx0XHRcdGpRdWVyeS5fcXVldWVIb29rcyggdGhpcywgdHlwZSApO1xuXG5cdFx0XHRcdGlmICggdHlwZSA9PT0gXCJmeFwiICYmIHF1ZXVlWzBdICE9PSBcImlucHJvZ3Jlc3NcIiApIHtcblx0XHRcdFx0XHRqUXVlcnkuZGVxdWV1ZSggdGhpcywgdHlwZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0fSxcblx0ZGVxdWV1ZTogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5kZXF1ZXVlKCB0aGlzLCB0eXBlICk7XG5cdFx0fSk7XG5cdH0sXG5cdGNsZWFyUXVldWU6IGZ1bmN0aW9uKCB0eXBlICkge1xuXHRcdHJldHVybiB0aGlzLnF1ZXVlKCB0eXBlIHx8IFwiZnhcIiwgW10gKTtcblx0fSxcblx0Ly8gR2V0IGEgcHJvbWlzZSByZXNvbHZlZCB3aGVuIHF1ZXVlcyBvZiBhIGNlcnRhaW4gdHlwZVxuXHQvLyBhcmUgZW1wdGllZCAoZnggaXMgdGhlIHR5cGUgYnkgZGVmYXVsdClcblx0cHJvbWlzZTogZnVuY3Rpb24oIHR5cGUsIG9iaiApIHtcblx0XHR2YXIgdG1wLFxuXHRcdFx0Y291bnQgPSAxLFxuXHRcdFx0ZGVmZXIgPSBqUXVlcnkuRGVmZXJyZWQoKSxcblx0XHRcdGVsZW1lbnRzID0gdGhpcyxcblx0XHRcdGkgPSB0aGlzLmxlbmd0aCxcblx0XHRcdHJlc29sdmUgPSBmdW5jdGlvbigpIHtcblx0XHRcdFx0aWYgKCAhKCAtLWNvdW50ICkgKSB7XG5cdFx0XHRcdFx0ZGVmZXIucmVzb2x2ZVdpdGgoIGVsZW1lbnRzLCBbIGVsZW1lbnRzIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblxuXHRcdGlmICggdHlwZW9mIHR5cGUgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRvYmogPSB0eXBlO1xuXHRcdFx0dHlwZSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXG5cdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHR0bXAgPSBqUXVlcnkuX2RhdGEoIGVsZW1lbnRzWyBpIF0sIHR5cGUgKyBcInF1ZXVlSG9va3NcIiApO1xuXHRcdFx0aWYgKCB0bXAgJiYgdG1wLmVtcHR5ICkge1xuXHRcdFx0XHRjb3VudCsrO1xuXHRcdFx0XHR0bXAuZW1wdHkuYWRkKCByZXNvbHZlICk7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJlc29sdmUoKTtcblx0XHRyZXR1cm4gZGVmZXIucHJvbWlzZSggb2JqICk7XG5cdH1cbn0pO1xudmFyIHBudW0gPSAoL1srLV0/KD86XFxkKlxcLnwpXFxkKyg/OltlRV1bKy1dP1xcZCt8KS8pLnNvdXJjZTtcblxudmFyIGNzc0V4cGFuZCA9IFsgXCJUb3BcIiwgXCJSaWdodFwiLCBcIkJvdHRvbVwiLCBcIkxlZnRcIiBdO1xuXG52YXIgaXNIaWRkZW4gPSBmdW5jdGlvbiggZWxlbSwgZWwgKSB7XG5cdFx0Ly8gaXNIaWRkZW4gbWlnaHQgYmUgY2FsbGVkIGZyb20galF1ZXJ5I2ZpbHRlciBmdW5jdGlvbjtcblx0XHQvLyBpbiB0aGF0IGNhc2UsIGVsZW1lbnQgd2lsbCBiZSBzZWNvbmQgYXJndW1lbnRcblx0XHRlbGVtID0gZWwgfHwgZWxlbTtcblx0XHRyZXR1cm4galF1ZXJ5LmNzcyggZWxlbSwgXCJkaXNwbGF5XCIgKSA9PT0gXCJub25lXCIgfHwgIWpRdWVyeS5jb250YWlucyggZWxlbS5vd25lckRvY3VtZW50LCBlbGVtICk7XG5cdH07XG5cblxuXG4vLyBNdWx0aWZ1bmN0aW9uYWwgbWV0aG9kIHRvIGdldCBhbmQgc2V0IHZhbHVlcyBvZiBhIGNvbGxlY3Rpb25cbi8vIFRoZSB2YWx1ZS9zIGNhbiBvcHRpb25hbGx5IGJlIGV4ZWN1dGVkIGlmIGl0J3MgYSBmdW5jdGlvblxudmFyIGFjY2VzcyA9IGpRdWVyeS5hY2Nlc3MgPSBmdW5jdGlvbiggZWxlbXMsIGZuLCBrZXksIHZhbHVlLCBjaGFpbmFibGUsIGVtcHR5R2V0LCByYXcgKSB7XG5cdHZhciBpID0gMCxcblx0XHRsZW5ndGggPSBlbGVtcy5sZW5ndGgsXG5cdFx0YnVsayA9IGtleSA9PSBudWxsO1xuXG5cdC8vIFNldHMgbWFueSB2YWx1ZXNcblx0aWYgKCBqUXVlcnkudHlwZSgga2V5ICkgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcblx0XHRmb3IgKCBpIGluIGtleSApIHtcblx0XHRcdGpRdWVyeS5hY2Nlc3MoIGVsZW1zLCBmbiwgaSwga2V5W2ldLCB0cnVlLCBlbXB0eUdldCwgcmF3ICk7XG5cdFx0fVxuXG5cdC8vIFNldHMgb25lIHZhbHVlXG5cdH0gZWxzZSBpZiAoIHZhbHVlICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0Y2hhaW5hYmxlID0gdHJ1ZTtcblxuXHRcdGlmICggIWpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmF3ID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRpZiAoIGJ1bGsgKSB7XG5cdFx0XHQvLyBCdWxrIG9wZXJhdGlvbnMgcnVuIGFnYWluc3QgdGhlIGVudGlyZSBzZXRcblx0XHRcdGlmICggcmF3ICkge1xuXHRcdFx0XHRmbi5jYWxsKCBlbGVtcywgdmFsdWUgKTtcblx0XHRcdFx0Zm4gPSBudWxsO1xuXG5cdFx0XHQvLyAuLi5leGNlcHQgd2hlbiBleGVjdXRpbmcgZnVuY3Rpb24gdmFsdWVzXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRidWxrID0gZm47XG5cdFx0XHRcdGZuID0gZnVuY3Rpb24oIGVsZW0sIGtleSwgdmFsdWUgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIGJ1bGsuY2FsbCggalF1ZXJ5KCBlbGVtICksIHZhbHVlICk7XG5cdFx0XHRcdH07XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0aWYgKCBmbiApIHtcblx0XHRcdGZvciAoIDsgaSA8IGxlbmd0aDsgaSsrICkge1xuXHRcdFx0XHRmbiggZWxlbXNbaV0sIGtleSwgcmF3ID8gdmFsdWUgOiB2YWx1ZS5jYWxsKCBlbGVtc1tpXSwgaSwgZm4oIGVsZW1zW2ldLCBrZXkgKSApICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGNoYWluYWJsZSA/XG5cdFx0ZWxlbXMgOlxuXG5cdFx0Ly8gR2V0c1xuXHRcdGJ1bGsgP1xuXHRcdFx0Zm4uY2FsbCggZWxlbXMgKSA6XG5cdFx0XHRsZW5ndGggPyBmbiggZWxlbXNbMF0sIGtleSApIDogZW1wdHlHZXQ7XG59O1xudmFyIHJjaGVja2FibGVUeXBlID0gKC9eKD86Y2hlY2tib3h8cmFkaW8pJC9pKTtcblxuXG5cbihmdW5jdGlvbigpIHtcblx0Ly8gTWluaWZpZWQ6IHZhciBhLGIsY1xuXHR2YXIgaW5wdXQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImlucHV0XCIgKSxcblx0XHRkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICksXG5cdFx0ZnJhZ21lbnQgPSBkb2N1bWVudC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCk7XG5cblx0Ly8gU2V0dXBcblx0ZGl2LmlubmVySFRNTCA9IFwiICA8bGluay8+PHRhYmxlPjwvdGFibGU+PGEgaHJlZj0nL2EnPmE8L2E+PGlucHV0IHR5cGU9J2NoZWNrYm94Jy8+XCI7XG5cblx0Ly8gSUUgc3RyaXBzIGxlYWRpbmcgd2hpdGVzcGFjZSB3aGVuIC5pbm5lckhUTUwgaXMgdXNlZFxuXHRzdXBwb3J0LmxlYWRpbmdXaGl0ZXNwYWNlID0gZGl2LmZpcnN0Q2hpbGQubm9kZVR5cGUgPT09IDM7XG5cblx0Ly8gTWFrZSBzdXJlIHRoYXQgdGJvZHkgZWxlbWVudHMgYXJlbid0IGF1dG9tYXRpY2FsbHkgaW5zZXJ0ZWRcblx0Ly8gSUUgd2lsbCBpbnNlcnQgdGhlbSBpbnRvIGVtcHR5IHRhYmxlc1xuXHRzdXBwb3J0LnRib2R5ID0gIWRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJ0Ym9keVwiICkubGVuZ3RoO1xuXG5cdC8vIE1ha2Ugc3VyZSB0aGF0IGxpbmsgZWxlbWVudHMgZ2V0IHNlcmlhbGl6ZWQgY29ycmVjdGx5IGJ5IGlubmVySFRNTFxuXHQvLyBUaGlzIHJlcXVpcmVzIGEgd3JhcHBlciBlbGVtZW50IGluIElFXG5cdHN1cHBvcnQuaHRtbFNlcmlhbGl6ZSA9ICEhZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKCBcImxpbmtcIiApLmxlbmd0aDtcblxuXHQvLyBNYWtlcyBzdXJlIGNsb25pbmcgYW4gaHRtbDUgZWxlbWVudCBkb2VzIG5vdCBjYXVzZSBwcm9ibGVtc1xuXHQvLyBXaGVyZSBvdXRlckhUTUwgaXMgdW5kZWZpbmVkLCB0aGlzIHN0aWxsIHdvcmtzXG5cdHN1cHBvcnQuaHRtbDVDbG9uZSA9XG5cdFx0ZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJuYXZcIiApLmNsb25lTm9kZSggdHJ1ZSApLm91dGVySFRNTCAhPT0gXCI8Om5hdj48LzpuYXY+XCI7XG5cblx0Ly8gQ2hlY2sgaWYgYSBkaXNjb25uZWN0ZWQgY2hlY2tib3ggd2lsbCByZXRhaW4gaXRzIGNoZWNrZWRcblx0Ly8gdmFsdWUgb2YgdHJ1ZSBhZnRlciBhcHBlbmRlZCB0byB0aGUgRE9NIChJRTYvNylcblx0aW5wdXQudHlwZSA9IFwiY2hlY2tib3hcIjtcblx0aW5wdXQuY2hlY2tlZCA9IHRydWU7XG5cdGZyYWdtZW50LmFwcGVuZENoaWxkKCBpbnB1dCApO1xuXHRzdXBwb3J0LmFwcGVuZENoZWNrZWQgPSBpbnB1dC5jaGVja2VkO1xuXG5cdC8vIE1ha2Ugc3VyZSB0ZXh0YXJlYSAoYW5kIGNoZWNrYm94KSBkZWZhdWx0VmFsdWUgaXMgcHJvcGVybHkgY2xvbmVkXG5cdC8vIFN1cHBvcnQ6IElFNi1JRTExK1xuXHRkaXYuaW5uZXJIVE1MID0gXCI8dGV4dGFyZWE+eDwvdGV4dGFyZWE+XCI7XG5cdHN1cHBvcnQubm9DbG9uZUNoZWNrZWQgPSAhIWRpdi5jbG9uZU5vZGUoIHRydWUgKS5sYXN0Q2hpbGQuZGVmYXVsdFZhbHVlO1xuXG5cdC8vICMxMTIxNyAtIFdlYktpdCBsb3NlcyBjaGVjayB3aGVuIHRoZSBuYW1lIGlzIGFmdGVyIHRoZSBjaGVja2VkIGF0dHJpYnV0ZVxuXHRmcmFnbWVudC5hcHBlbmRDaGlsZCggZGl2ICk7XG5cdGRpdi5pbm5lckhUTUwgPSBcIjxpbnB1dCB0eXBlPSdyYWRpbycgY2hlY2tlZD0nY2hlY2tlZCcgbmFtZT0ndCcvPlwiO1xuXG5cdC8vIFN1cHBvcnQ6IFNhZmFyaSA1LjEsIGlPUyA1LjEsIEFuZHJvaWQgNC54LCBBbmRyb2lkIDIuM1xuXHQvLyBvbGQgV2ViS2l0IGRvZXNuJ3QgY2xvbmUgY2hlY2tlZCBzdGF0ZSBjb3JyZWN0bHkgaW4gZnJhZ21lbnRzXG5cdHN1cHBvcnQuY2hlY2tDbG9uZSA9IGRpdi5jbG9uZU5vZGUoIHRydWUgKS5jbG9uZU5vZGUoIHRydWUgKS5sYXN0Q2hpbGQuY2hlY2tlZDtcblxuXHQvLyBTdXBwb3J0OiBJRTw5XG5cdC8vIE9wZXJhIGRvZXMgbm90IGNsb25lIGV2ZW50cyAoYW5kIHR5cGVvZiBkaXYuYXR0YWNoRXZlbnQgPT09IHVuZGVmaW5lZCkuXG5cdC8vIElFOS0xMCBjbG9uZXMgZXZlbnRzIGJvdW5kIHZpYSBhdHRhY2hFdmVudCwgYnV0IHRoZXkgZG9uJ3QgdHJpZ2dlciB3aXRoIC5jbGljaygpXG5cdHN1cHBvcnQubm9DbG9uZUV2ZW50ID0gdHJ1ZTtcblx0aWYgKCBkaXYuYXR0YWNoRXZlbnQgKSB7XG5cdFx0ZGl2LmF0dGFjaEV2ZW50KCBcIm9uY2xpY2tcIiwgZnVuY3Rpb24oKSB7XG5cdFx0XHRzdXBwb3J0Lm5vQ2xvbmVFdmVudCA9IGZhbHNlO1xuXHRcdH0pO1xuXG5cdFx0ZGl2LmNsb25lTm9kZSggdHJ1ZSApLmNsaWNrKCk7XG5cdH1cblxuXHQvLyBFeGVjdXRlIHRoZSB0ZXN0IG9ubHkgaWYgbm90IGFscmVhZHkgZXhlY3V0ZWQgaW4gYW5vdGhlciBtb2R1bGUuXG5cdGlmIChzdXBwb3J0LmRlbGV0ZUV4cGFuZG8gPT0gbnVsbCkge1xuXHRcdC8vIFN1cHBvcnQ6IElFPDlcblx0XHRzdXBwb3J0LmRlbGV0ZUV4cGFuZG8gPSB0cnVlO1xuXHRcdHRyeSB7XG5cdFx0XHRkZWxldGUgZGl2LnRlc3Q7XG5cdFx0fSBjYXRjaCggZSApIHtcblx0XHRcdHN1cHBvcnQuZGVsZXRlRXhwYW5kbyA9IGZhbHNlO1xuXHRcdH1cblx0fVxufSkoKTtcblxuXG4oZnVuY3Rpb24oKSB7XG5cdHZhciBpLCBldmVudE5hbWUsXG5cdFx0ZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApO1xuXG5cdC8vIFN1cHBvcnQ6IElFPDkgKGxhY2sgc3VibWl0L2NoYW5nZSBidWJibGUpLCBGaXJlZm94IDIzKyAobGFjayBmb2N1c2luIGV2ZW50KVxuXHRmb3IgKCBpIGluIHsgc3VibWl0OiB0cnVlLCBjaGFuZ2U6IHRydWUsIGZvY3VzaW46IHRydWUgfSkge1xuXHRcdGV2ZW50TmFtZSA9IFwib25cIiArIGk7XG5cblx0XHRpZiAoICEoc3VwcG9ydFsgaSArIFwiQnViYmxlc1wiIF0gPSBldmVudE5hbWUgaW4gd2luZG93KSApIHtcblx0XHRcdC8vIEJld2FyZSBvZiBDU1AgcmVzdHJpY3Rpb25zIChodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi9TZWN1cml0eS9DU1ApXG5cdFx0XHRkaXYuc2V0QXR0cmlidXRlKCBldmVudE5hbWUsIFwidFwiICk7XG5cdFx0XHRzdXBwb3J0WyBpICsgXCJCdWJibGVzXCIgXSA9IGRpdi5hdHRyaWJ1dGVzWyBldmVudE5hbWUgXS5leHBhbmRvID09PSBmYWxzZTtcblx0XHR9XG5cdH1cblxuXHQvLyBOdWxsIGVsZW1lbnRzIHRvIGF2b2lkIGxlYWtzIGluIElFLlxuXHRkaXYgPSBudWxsO1xufSkoKTtcblxuXG52YXIgcmZvcm1FbGVtcyA9IC9eKD86aW5wdXR8c2VsZWN0fHRleHRhcmVhKSQvaSxcblx0cmtleUV2ZW50ID0gL15rZXkvLFxuXHRybW91c2VFdmVudCA9IC9eKD86bW91c2V8cG9pbnRlcnxjb250ZXh0bWVudSl8Y2xpY2svLFxuXHRyZm9jdXNNb3JwaCA9IC9eKD86Zm9jdXNpbmZvY3VzfGZvY3Vzb3V0Ymx1cikkLyxcblx0cnR5cGVuYW1lc3BhY2UgPSAvXihbXi5dKikoPzpcXC4oLispfCkkLztcblxuZnVuY3Rpb24gcmV0dXJuVHJ1ZSgpIHtcblx0cmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJldHVybkZhbHNlKCkge1xuXHRyZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIHNhZmVBY3RpdmVFbGVtZW50KCkge1xuXHR0cnkge1xuXHRcdHJldHVybiBkb2N1bWVudC5hY3RpdmVFbGVtZW50O1xuXHR9IGNhdGNoICggZXJyICkgeyB9XG59XG5cbi8qXG4gKiBIZWxwZXIgZnVuY3Rpb25zIGZvciBtYW5hZ2luZyBldmVudHMgLS0gbm90IHBhcnQgb2YgdGhlIHB1YmxpYyBpbnRlcmZhY2UuXG4gKiBQcm9wcyB0byBEZWFuIEVkd2FyZHMnIGFkZEV2ZW50IGxpYnJhcnkgZm9yIG1hbnkgb2YgdGhlIGlkZWFzLlxuICovXG5qUXVlcnkuZXZlbnQgPSB7XG5cblx0Z2xvYmFsOiB7fSxcblxuXHRhZGQ6IGZ1bmN0aW9uKCBlbGVtLCB0eXBlcywgaGFuZGxlciwgZGF0YSwgc2VsZWN0b3IgKSB7XG5cdFx0dmFyIHRtcCwgZXZlbnRzLCB0LCBoYW5kbGVPYmpJbixcblx0XHRcdHNwZWNpYWwsIGV2ZW50SGFuZGxlLCBoYW5kbGVPYmosXG5cdFx0XHRoYW5kbGVycywgdHlwZSwgbmFtZXNwYWNlcywgb3JpZ1R5cGUsXG5cdFx0XHRlbGVtRGF0YSA9IGpRdWVyeS5fZGF0YSggZWxlbSApO1xuXG5cdFx0Ly8gRG9uJ3QgYXR0YWNoIGV2ZW50cyB0byBub0RhdGEgb3IgdGV4dC9jb21tZW50IG5vZGVzIChidXQgYWxsb3cgcGxhaW4gb2JqZWN0cylcblx0XHRpZiAoICFlbGVtRGF0YSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBDYWxsZXIgY2FuIHBhc3MgaW4gYW4gb2JqZWN0IG9mIGN1c3RvbSBkYXRhIGluIGxpZXUgb2YgdGhlIGhhbmRsZXJcblx0XHRpZiAoIGhhbmRsZXIuaGFuZGxlciApIHtcblx0XHRcdGhhbmRsZU9iakluID0gaGFuZGxlcjtcblx0XHRcdGhhbmRsZXIgPSBoYW5kbGVPYmpJbi5oYW5kbGVyO1xuXHRcdFx0c2VsZWN0b3IgPSBoYW5kbGVPYmpJbi5zZWxlY3Rvcjtcblx0XHR9XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB0aGUgaGFuZGxlciBoYXMgYSB1bmlxdWUgSUQsIHVzZWQgdG8gZmluZC9yZW1vdmUgaXQgbGF0ZXJcblx0XHRpZiAoICFoYW5kbGVyLmd1aWQgKSB7XG5cdFx0XHRoYW5kbGVyLmd1aWQgPSBqUXVlcnkuZ3VpZCsrO1xuXHRcdH1cblxuXHRcdC8vIEluaXQgdGhlIGVsZW1lbnQncyBldmVudCBzdHJ1Y3R1cmUgYW5kIG1haW4gaGFuZGxlciwgaWYgdGhpcyBpcyB0aGUgZmlyc3Rcblx0XHRpZiAoICEoZXZlbnRzID0gZWxlbURhdGEuZXZlbnRzKSApIHtcblx0XHRcdGV2ZW50cyA9IGVsZW1EYXRhLmV2ZW50cyA9IHt9O1xuXHRcdH1cblx0XHRpZiAoICEoZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUpICkge1xuXHRcdFx0ZXZlbnRIYW5kbGUgPSBlbGVtRGF0YS5oYW5kbGUgPSBmdW5jdGlvbiggZSApIHtcblx0XHRcdFx0Ly8gRGlzY2FyZCB0aGUgc2Vjb25kIGV2ZW50IG9mIGEgalF1ZXJ5LmV2ZW50LnRyaWdnZXIoKSBhbmRcblx0XHRcdFx0Ly8gd2hlbiBhbiBldmVudCBpcyBjYWxsZWQgYWZ0ZXIgYSBwYWdlIGhhcyB1bmxvYWRlZFxuXHRcdFx0XHRyZXR1cm4gdHlwZW9mIGpRdWVyeSAhPT0gc3RydW5kZWZpbmVkICYmICghZSB8fCBqUXVlcnkuZXZlbnQudHJpZ2dlcmVkICE9PSBlLnR5cGUpID9cblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQuZGlzcGF0Y2guYXBwbHkoIGV2ZW50SGFuZGxlLmVsZW0sIGFyZ3VtZW50cyApIDpcblx0XHRcdFx0XHR1bmRlZmluZWQ7XG5cdFx0XHR9O1xuXHRcdFx0Ly8gQWRkIGVsZW0gYXMgYSBwcm9wZXJ0eSBvZiB0aGUgaGFuZGxlIGZuIHRvIHByZXZlbnQgYSBtZW1vcnkgbGVhayB3aXRoIElFIG5vbi1uYXRpdmUgZXZlbnRzXG5cdFx0XHRldmVudEhhbmRsZS5lbGVtID0gZWxlbTtcblx0XHR9XG5cblx0XHQvLyBIYW5kbGUgbXVsdGlwbGUgZXZlbnRzIHNlcGFyYXRlZCBieSBhIHNwYWNlXG5cdFx0dHlwZXMgPSAoIHR5cGVzIHx8IFwiXCIgKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgWyBcIlwiIF07XG5cdFx0dCA9IHR5cGVzLmxlbmd0aDtcblx0XHR3aGlsZSAoIHQtLSApIHtcblx0XHRcdHRtcCA9IHJ0eXBlbmFtZXNwYWNlLmV4ZWMoIHR5cGVzW3RdICkgfHwgW107XG5cdFx0XHR0eXBlID0gb3JpZ1R5cGUgPSB0bXBbMV07XG5cdFx0XHRuYW1lc3BhY2VzID0gKCB0bXBbMl0gfHwgXCJcIiApLnNwbGl0KCBcIi5cIiApLnNvcnQoKTtcblxuXHRcdFx0Ly8gVGhlcmUgKm11c3QqIGJlIGEgdHlwZSwgbm8gYXR0YWNoaW5nIG5hbWVzcGFjZS1vbmx5IGhhbmRsZXJzXG5cdFx0XHRpZiAoICF0eXBlICkge1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gSWYgZXZlbnQgY2hhbmdlcyBpdHMgdHlwZSwgdXNlIHRoZSBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzIGZvciB0aGUgY2hhbmdlZCB0eXBlXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblxuXHRcdFx0Ly8gSWYgc2VsZWN0b3IgZGVmaW5lZCwgZGV0ZXJtaW5lIHNwZWNpYWwgZXZlbnQgYXBpIHR5cGUsIG90aGVyd2lzZSBnaXZlbiB0eXBlXG5cdFx0XHR0eXBlID0gKCBzZWxlY3RvciA/IHNwZWNpYWwuZGVsZWdhdGVUeXBlIDogc3BlY2lhbC5iaW5kVHlwZSApIHx8IHR5cGU7XG5cblx0XHRcdC8vIFVwZGF0ZSBzcGVjaWFsIGJhc2VkIG9uIG5ld2x5IHJlc2V0IHR5cGVcblx0XHRcdHNwZWNpYWwgPSBqUXVlcnkuZXZlbnQuc3BlY2lhbFsgdHlwZSBdIHx8IHt9O1xuXG5cdFx0XHQvLyBoYW5kbGVPYmogaXMgcGFzc2VkIHRvIGFsbCBldmVudCBoYW5kbGVyc1xuXHRcdFx0aGFuZGxlT2JqID0galF1ZXJ5LmV4dGVuZCh7XG5cdFx0XHRcdHR5cGU6IHR5cGUsXG5cdFx0XHRcdG9yaWdUeXBlOiBvcmlnVHlwZSxcblx0XHRcdFx0ZGF0YTogZGF0YSxcblx0XHRcdFx0aGFuZGxlcjogaGFuZGxlcixcblx0XHRcdFx0Z3VpZDogaGFuZGxlci5ndWlkLFxuXHRcdFx0XHRzZWxlY3Rvcjogc2VsZWN0b3IsXG5cdFx0XHRcdG5lZWRzQ29udGV4dDogc2VsZWN0b3IgJiYgalF1ZXJ5LmV4cHIubWF0Y2gubmVlZHNDb250ZXh0LnRlc3QoIHNlbGVjdG9yICksXG5cdFx0XHRcdG5hbWVzcGFjZTogbmFtZXNwYWNlcy5qb2luKFwiLlwiKVxuXHRcdFx0fSwgaGFuZGxlT2JqSW4gKTtcblxuXHRcdFx0Ly8gSW5pdCB0aGUgZXZlbnQgaGFuZGxlciBxdWV1ZSBpZiB3ZSdyZSB0aGUgZmlyc3Rcblx0XHRcdGlmICggIShoYW5kbGVycyA9IGV2ZW50c1sgdHlwZSBdKSApIHtcblx0XHRcdFx0aGFuZGxlcnMgPSBldmVudHNbIHR5cGUgXSA9IFtdO1xuXHRcdFx0XHRoYW5kbGVycy5kZWxlZ2F0ZUNvdW50ID0gMDtcblxuXHRcdFx0XHQvLyBPbmx5IHVzZSBhZGRFdmVudExpc3RlbmVyL2F0dGFjaEV2ZW50IGlmIHRoZSBzcGVjaWFsIGV2ZW50cyBoYW5kbGVyIHJldHVybnMgZmFsc2Vcblx0XHRcdFx0aWYgKCAhc3BlY2lhbC5zZXR1cCB8fCBzcGVjaWFsLnNldHVwLmNhbGwoIGVsZW0sIGRhdGEsIG5hbWVzcGFjZXMsIGV2ZW50SGFuZGxlICkgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdC8vIEJpbmQgdGhlIGdsb2JhbCBldmVudCBoYW5kbGVyIHRvIHRoZSBlbGVtZW50XG5cdFx0XHRcdFx0aWYgKCBlbGVtLmFkZEV2ZW50TGlzdGVuZXIgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmFkZEV2ZW50TGlzdGVuZXIoIHR5cGUsIGV2ZW50SGFuZGxlLCBmYWxzZSApO1xuXG5cdFx0XHRcdFx0fSBlbHNlIGlmICggZWxlbS5hdHRhY2hFdmVudCApIHtcblx0XHRcdFx0XHRcdGVsZW0uYXR0YWNoRXZlbnQoIFwib25cIiArIHR5cGUsIGV2ZW50SGFuZGxlICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGlmICggc3BlY2lhbC5hZGQgKSB7XG5cdFx0XHRcdHNwZWNpYWwuYWRkLmNhbGwoIGVsZW0sIGhhbmRsZU9iaiApO1xuXG5cdFx0XHRcdGlmICggIWhhbmRsZU9iai5oYW5kbGVyLmd1aWQgKSB7XG5cdFx0XHRcdFx0aGFuZGxlT2JqLmhhbmRsZXIuZ3VpZCA9IGhhbmRsZXIuZ3VpZDtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgdG8gdGhlIGVsZW1lbnQncyBoYW5kbGVyIGxpc3QsIGRlbGVnYXRlcyBpbiBmcm9udFxuXHRcdFx0aWYgKCBzZWxlY3RvciApIHtcblx0XHRcdFx0aGFuZGxlcnMuc3BsaWNlKCBoYW5kbGVycy5kZWxlZ2F0ZUNvdW50KyssIDAsIGhhbmRsZU9iaiApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0aGFuZGxlcnMucHVzaCggaGFuZGxlT2JqICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEtlZXAgdHJhY2sgb2Ygd2hpY2ggZXZlbnRzIGhhdmUgZXZlciBiZWVuIHVzZWQsIGZvciBldmVudCBvcHRpbWl6YXRpb25cblx0XHRcdGpRdWVyeS5ldmVudC5nbG9iYWxbIHR5cGUgXSA9IHRydWU7XG5cdFx0fVxuXG5cdFx0Ly8gTnVsbGlmeSBlbGVtIHRvIHByZXZlbnQgbWVtb3J5IGxlYWtzIGluIElFXG5cdFx0ZWxlbSA9IG51bGw7XG5cdH0sXG5cblx0Ly8gRGV0YWNoIGFuIGV2ZW50IG9yIHNldCBvZiBldmVudHMgZnJvbSBhbiBlbGVtZW50XG5cdHJlbW92ZTogZnVuY3Rpb24oIGVsZW0sIHR5cGVzLCBoYW5kbGVyLCBzZWxlY3RvciwgbWFwcGVkVHlwZXMgKSB7XG5cdFx0dmFyIGosIGhhbmRsZU9iaiwgdG1wLFxuXHRcdFx0b3JpZ0NvdW50LCB0LCBldmVudHMsXG5cdFx0XHRzcGVjaWFsLCBoYW5kbGVycywgdHlwZSxcblx0XHRcdG5hbWVzcGFjZXMsIG9yaWdUeXBlLFxuXHRcdFx0ZWxlbURhdGEgPSBqUXVlcnkuaGFzRGF0YSggZWxlbSApICYmIGpRdWVyeS5fZGF0YSggZWxlbSApO1xuXG5cdFx0aWYgKCAhZWxlbURhdGEgfHwgIShldmVudHMgPSBlbGVtRGF0YS5ldmVudHMpICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIE9uY2UgZm9yIGVhY2ggdHlwZS5uYW1lc3BhY2UgaW4gdHlwZXM7IHR5cGUgbWF5IGJlIG9taXR0ZWRcblx0XHR0eXBlcyA9ICggdHlwZXMgfHwgXCJcIiApLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbIFwiXCIgXTtcblx0XHR0ID0gdHlwZXMubGVuZ3RoO1xuXHRcdHdoaWxlICggdC0tICkge1xuXHRcdFx0dG1wID0gcnR5cGVuYW1lc3BhY2UuZXhlYyggdHlwZXNbdF0gKSB8fCBbXTtcblx0XHRcdHR5cGUgPSBvcmlnVHlwZSA9IHRtcFsxXTtcblx0XHRcdG5hbWVzcGFjZXMgPSAoIHRtcFsyXSB8fCBcIlwiICkuc3BsaXQoIFwiLlwiICkuc29ydCgpO1xuXG5cdFx0XHQvLyBVbmJpbmQgYWxsIGV2ZW50cyAob24gdGhpcyBuYW1lc3BhY2UsIGlmIHByb3ZpZGVkKSBmb3IgdGhlIGVsZW1lbnRcblx0XHRcdGlmICggIXR5cGUgKSB7XG5cdFx0XHRcdGZvciAoIHR5cGUgaW4gZXZlbnRzICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIGVsZW0sIHR5cGUgKyB0eXBlc1sgdCBdLCBoYW5kbGVyLCBzZWxlY3RvciwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGNvbnRpbnVlO1xuXHRcdFx0fVxuXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRcdHR5cGUgPSAoIHNlbGVjdG9yID8gc3BlY2lhbC5kZWxlZ2F0ZVR5cGUgOiBzcGVjaWFsLmJpbmRUeXBlICkgfHwgdHlwZTtcblx0XHRcdGhhbmRsZXJzID0gZXZlbnRzWyB0eXBlIF0gfHwgW107XG5cdFx0XHR0bXAgPSB0bXBbMl0gJiYgbmV3IFJlZ0V4cCggXCIoXnxcXFxcLilcIiArIG5hbWVzcGFjZXMuam9pbihcIlxcXFwuKD86LipcXFxcLnwpXCIpICsgXCIoXFxcXC58JClcIiApO1xuXG5cdFx0XHQvLyBSZW1vdmUgbWF0Y2hpbmcgZXZlbnRzXG5cdFx0XHRvcmlnQ291bnQgPSBqID0gaGFuZGxlcnMubGVuZ3RoO1xuXHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdGhhbmRsZU9iaiA9IGhhbmRsZXJzWyBqIF07XG5cblx0XHRcdFx0aWYgKCAoIG1hcHBlZFR5cGVzIHx8IG9yaWdUeXBlID09PSBoYW5kbGVPYmoub3JpZ1R5cGUgKSAmJlxuXHRcdFx0XHRcdCggIWhhbmRsZXIgfHwgaGFuZGxlci5ndWlkID09PSBoYW5kbGVPYmouZ3VpZCApICYmXG5cdFx0XHRcdFx0KCAhdG1wIHx8IHRtcC50ZXN0KCBoYW5kbGVPYmoubmFtZXNwYWNlICkgKSAmJlxuXHRcdFx0XHRcdCggIXNlbGVjdG9yIHx8IHNlbGVjdG9yID09PSBoYW5kbGVPYmouc2VsZWN0b3IgfHwgc2VsZWN0b3IgPT09IFwiKipcIiAmJiBoYW5kbGVPYmouc2VsZWN0b3IgKSApIHtcblx0XHRcdFx0XHRoYW5kbGVycy5zcGxpY2UoIGosIDEgKTtcblxuXHRcdFx0XHRcdGlmICggaGFuZGxlT2JqLnNlbGVjdG9yICkge1xuXHRcdFx0XHRcdFx0aGFuZGxlcnMuZGVsZWdhdGVDb3VudC0tO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRpZiAoIHNwZWNpYWwucmVtb3ZlICkge1xuXHRcdFx0XHRcdFx0c3BlY2lhbC5yZW1vdmUuY2FsbCggZWxlbSwgaGFuZGxlT2JqICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFJlbW92ZSBnZW5lcmljIGV2ZW50IGhhbmRsZXIgaWYgd2UgcmVtb3ZlZCBzb21ldGhpbmcgYW5kIG5vIG1vcmUgaGFuZGxlcnMgZXhpc3Rcblx0XHRcdC8vIChhdm9pZHMgcG90ZW50aWFsIGZvciBlbmRsZXNzIHJlY3Vyc2lvbiBkdXJpbmcgcmVtb3ZhbCBvZiBzcGVjaWFsIGV2ZW50IGhhbmRsZXJzKVxuXHRcdFx0aWYgKCBvcmlnQ291bnQgJiYgIWhhbmRsZXJzLmxlbmd0aCApIHtcblx0XHRcdFx0aWYgKCAhc3BlY2lhbC50ZWFyZG93biB8fCBzcGVjaWFsLnRlYXJkb3duLmNhbGwoIGVsZW0sIG5hbWVzcGFjZXMsIGVsZW1EYXRhLmhhbmRsZSApID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGVsZW1EYXRhLmhhbmRsZSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZGVsZXRlIGV2ZW50c1sgdHlwZSBdO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFJlbW92ZSB0aGUgZXhwYW5kbyBpZiBpdCdzIG5vIGxvbmdlciB1c2VkXG5cdFx0aWYgKCBqUXVlcnkuaXNFbXB0eU9iamVjdCggZXZlbnRzICkgKSB7XG5cdFx0XHRkZWxldGUgZWxlbURhdGEuaGFuZGxlO1xuXG5cdFx0XHQvLyByZW1vdmVEYXRhIGFsc28gY2hlY2tzIGZvciBlbXB0aW5lc3MgYW5kIGNsZWFycyB0aGUgZXhwYW5kbyBpZiBlbXB0eVxuXHRcdFx0Ly8gc28gdXNlIGl0IGluc3RlYWQgb2YgZGVsZXRlXG5cdFx0XHRqUXVlcnkuX3JlbW92ZURhdGEoIGVsZW0sIFwiZXZlbnRzXCIgKTtcblx0XHR9XG5cdH0sXG5cblx0dHJpZ2dlcjogZnVuY3Rpb24oIGV2ZW50LCBkYXRhLCBlbGVtLCBvbmx5SGFuZGxlcnMgKSB7XG5cdFx0dmFyIGhhbmRsZSwgb250eXBlLCBjdXIsXG5cdFx0XHRidWJibGVUeXBlLCBzcGVjaWFsLCB0bXAsIGksXG5cdFx0XHRldmVudFBhdGggPSBbIGVsZW0gfHwgZG9jdW1lbnQgXSxcblx0XHRcdHR5cGUgPSBoYXNPd24uY2FsbCggZXZlbnQsIFwidHlwZVwiICkgPyBldmVudC50eXBlIDogZXZlbnQsXG5cdFx0XHRuYW1lc3BhY2VzID0gaGFzT3duLmNhbGwoIGV2ZW50LCBcIm5hbWVzcGFjZVwiICkgPyBldmVudC5uYW1lc3BhY2Uuc3BsaXQoXCIuXCIpIDogW107XG5cblx0XHRjdXIgPSB0bXAgPSBlbGVtID0gZWxlbSB8fCBkb2N1bWVudDtcblxuXHRcdC8vIERvbid0IGRvIGV2ZW50cyBvbiB0ZXh0IGFuZCBjb21tZW50IG5vZGVzXG5cdFx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAzIHx8IGVsZW0ubm9kZVR5cGUgPT09IDggKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gZm9jdXMvYmx1ciBtb3JwaHMgdG8gZm9jdXNpbi9vdXQ7IGVuc3VyZSB3ZSdyZSBub3QgZmlyaW5nIHRoZW0gcmlnaHQgbm93XG5cdFx0aWYgKCByZm9jdXNNb3JwaC50ZXN0KCB0eXBlICsgalF1ZXJ5LmV2ZW50LnRyaWdnZXJlZCApICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGlmICggdHlwZS5pbmRleE9mKFwiLlwiKSA+PSAwICkge1xuXHRcdFx0Ly8gTmFtZXNwYWNlZCB0cmlnZ2VyOyBjcmVhdGUgYSByZWdleHAgdG8gbWF0Y2ggZXZlbnQgdHlwZSBpbiBoYW5kbGUoKVxuXHRcdFx0bmFtZXNwYWNlcyA9IHR5cGUuc3BsaXQoXCIuXCIpO1xuXHRcdFx0dHlwZSA9IG5hbWVzcGFjZXMuc2hpZnQoKTtcblx0XHRcdG5hbWVzcGFjZXMuc29ydCgpO1xuXHRcdH1cblx0XHRvbnR5cGUgPSB0eXBlLmluZGV4T2YoXCI6XCIpIDwgMCAmJiBcIm9uXCIgKyB0eXBlO1xuXG5cdFx0Ly8gQ2FsbGVyIGNhbiBwYXNzIGluIGEgalF1ZXJ5LkV2ZW50IG9iamVjdCwgT2JqZWN0LCBvciBqdXN0IGFuIGV2ZW50IHR5cGUgc3RyaW5nXG5cdFx0ZXZlbnQgPSBldmVudFsgalF1ZXJ5LmV4cGFuZG8gXSA/XG5cdFx0XHRldmVudCA6XG5cdFx0XHRuZXcgalF1ZXJ5LkV2ZW50KCB0eXBlLCB0eXBlb2YgZXZlbnQgPT09IFwib2JqZWN0XCIgJiYgZXZlbnQgKTtcblxuXHRcdC8vIFRyaWdnZXIgYml0bWFzazogJiAxIGZvciBuYXRpdmUgaGFuZGxlcnM7ICYgMiBmb3IgalF1ZXJ5IChhbHdheXMgdHJ1ZSlcblx0XHRldmVudC5pc1RyaWdnZXIgPSBvbmx5SGFuZGxlcnMgPyAyIDogMztcblx0XHRldmVudC5uYW1lc3BhY2UgPSBuYW1lc3BhY2VzLmpvaW4oXCIuXCIpO1xuXHRcdGV2ZW50Lm5hbWVzcGFjZV9yZSA9IGV2ZW50Lm5hbWVzcGFjZSA/XG5cdFx0XHRuZXcgUmVnRXhwKCBcIihefFxcXFwuKVwiICsgbmFtZXNwYWNlcy5qb2luKFwiXFxcXC4oPzouKlxcXFwufClcIikgKyBcIihcXFxcLnwkKVwiICkgOlxuXHRcdFx0bnVsbDtcblxuXHRcdC8vIENsZWFuIHVwIHRoZSBldmVudCBpbiBjYXNlIGl0IGlzIGJlaW5nIHJldXNlZFxuXHRcdGV2ZW50LnJlc3VsdCA9IHVuZGVmaW5lZDtcblx0XHRpZiAoICFldmVudC50YXJnZXQgKSB7XG5cdFx0XHRldmVudC50YXJnZXQgPSBlbGVtO1xuXHRcdH1cblxuXHRcdC8vIENsb25lIGFueSBpbmNvbWluZyBkYXRhIGFuZCBwcmVwZW5kIHRoZSBldmVudCwgY3JlYXRpbmcgdGhlIGhhbmRsZXIgYXJnIGxpc3Rcblx0XHRkYXRhID0gZGF0YSA9PSBudWxsID9cblx0XHRcdFsgZXZlbnQgXSA6XG5cdFx0XHRqUXVlcnkubWFrZUFycmF5KCBkYXRhLCBbIGV2ZW50IF0gKTtcblxuXHRcdC8vIEFsbG93IHNwZWNpYWwgZXZlbnRzIHRvIGRyYXcgb3V0c2lkZSB0aGUgbGluZXNcblx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIHR5cGUgXSB8fCB7fTtcblx0XHRpZiAoICFvbmx5SGFuZGxlcnMgJiYgc3BlY2lhbC50cmlnZ2VyICYmIHNwZWNpYWwudHJpZ2dlci5hcHBseSggZWxlbSwgZGF0YSApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgZXZlbnQgcHJvcGFnYXRpb24gcGF0aCBpbiBhZHZhbmNlLCBwZXIgVzNDIGV2ZW50cyBzcGVjICgjOTk1MSlcblx0XHQvLyBCdWJibGUgdXAgdG8gZG9jdW1lbnQsIHRoZW4gdG8gd2luZG93OyB3YXRjaCBmb3IgYSBnbG9iYWwgb3duZXJEb2N1bWVudCB2YXIgKCM5NzI0KVxuXHRcdGlmICggIW9ubHlIYW5kbGVycyAmJiAhc3BlY2lhbC5ub0J1YmJsZSAmJiAhalF1ZXJ5LmlzV2luZG93KCBlbGVtICkgKSB7XG5cblx0XHRcdGJ1YmJsZVR5cGUgPSBzcGVjaWFsLmRlbGVnYXRlVHlwZSB8fCB0eXBlO1xuXHRcdFx0aWYgKCAhcmZvY3VzTW9ycGgudGVzdCggYnViYmxlVHlwZSArIHR5cGUgKSApIHtcblx0XHRcdFx0Y3VyID0gY3VyLnBhcmVudE5vZGU7XG5cdFx0XHR9XG5cdFx0XHRmb3IgKCA7IGN1cjsgY3VyID0gY3VyLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdGV2ZW50UGF0aC5wdXNoKCBjdXIgKTtcblx0XHRcdFx0dG1wID0gY3VyO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPbmx5IGFkZCB3aW5kb3cgaWYgd2UgZ290IHRvIGRvY3VtZW50IChlLmcuLCBub3QgcGxhaW4gb2JqIG9yIGRldGFjaGVkIERPTSlcblx0XHRcdGlmICggdG1wID09PSAoZWxlbS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50KSApIHtcblx0XHRcdFx0ZXZlbnRQYXRoLnB1c2goIHRtcC5kZWZhdWx0VmlldyB8fCB0bXAucGFyZW50V2luZG93IHx8IHdpbmRvdyApO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIEZpcmUgaGFuZGxlcnMgb24gdGhlIGV2ZW50IHBhdGhcblx0XHRpID0gMDtcblx0XHR3aGlsZSAoIChjdXIgPSBldmVudFBhdGhbaSsrXSkgJiYgIWV2ZW50LmlzUHJvcGFnYXRpb25TdG9wcGVkKCkgKSB7XG5cblx0XHRcdGV2ZW50LnR5cGUgPSBpID4gMSA/XG5cdFx0XHRcdGJ1YmJsZVR5cGUgOlxuXHRcdFx0XHRzcGVjaWFsLmJpbmRUeXBlIHx8IHR5cGU7XG5cblx0XHRcdC8vIGpRdWVyeSBoYW5kbGVyXG5cdFx0XHRoYW5kbGUgPSAoIGpRdWVyeS5fZGF0YSggY3VyLCBcImV2ZW50c1wiICkgfHwge30gKVsgZXZlbnQudHlwZSBdICYmIGpRdWVyeS5fZGF0YSggY3VyLCBcImhhbmRsZVwiICk7XG5cdFx0XHRpZiAoIGhhbmRsZSApIHtcblx0XHRcdFx0aGFuZGxlLmFwcGx5KCBjdXIsIGRhdGEgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTmF0aXZlIGhhbmRsZXJcblx0XHRcdGhhbmRsZSA9IG9udHlwZSAmJiBjdXJbIG9udHlwZSBdO1xuXHRcdFx0aWYgKCBoYW5kbGUgJiYgaGFuZGxlLmFwcGx5ICYmIGpRdWVyeS5hY2NlcHREYXRhKCBjdXIgKSApIHtcblx0XHRcdFx0ZXZlbnQucmVzdWx0ID0gaGFuZGxlLmFwcGx5KCBjdXIsIGRhdGEgKTtcblx0XHRcdFx0aWYgKCBldmVudC5yZXN1bHQgPT09IGZhbHNlICkge1xuXHRcdFx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdFx0ZXZlbnQudHlwZSA9IHR5cGU7XG5cblx0XHQvLyBJZiBub2JvZHkgcHJldmVudGVkIHRoZSBkZWZhdWx0IGFjdGlvbiwgZG8gaXQgbm93XG5cdFx0aWYgKCAhb25seUhhbmRsZXJzICYmICFldmVudC5pc0RlZmF1bHRQcmV2ZW50ZWQoKSApIHtcblxuXHRcdFx0aWYgKCAoIXNwZWNpYWwuX2RlZmF1bHQgfHwgc3BlY2lhbC5fZGVmYXVsdC5hcHBseSggZXZlbnRQYXRoLnBvcCgpLCBkYXRhICkgPT09IGZhbHNlKSAmJlxuXHRcdFx0XHRqUXVlcnkuYWNjZXB0RGF0YSggZWxlbSApICkge1xuXG5cdFx0XHRcdC8vIENhbGwgYSBuYXRpdmUgRE9NIG1ldGhvZCBvbiB0aGUgdGFyZ2V0IHdpdGggdGhlIHNhbWUgbmFtZSBuYW1lIGFzIHRoZSBldmVudC5cblx0XHRcdFx0Ly8gQ2FuJ3QgdXNlIGFuIC5pc0Z1bmN0aW9uKCkgY2hlY2sgaGVyZSBiZWNhdXNlIElFNi83IGZhaWxzIHRoYXQgdGVzdC5cblx0XHRcdFx0Ly8gRG9uJ3QgZG8gZGVmYXVsdCBhY3Rpb25zIG9uIHdpbmRvdywgdGhhdCdzIHdoZXJlIGdsb2JhbCB2YXJpYWJsZXMgYmUgKCM2MTcwKVxuXHRcdFx0XHRpZiAoIG9udHlwZSAmJiBlbGVtWyB0eXBlIF0gJiYgIWpRdWVyeS5pc1dpbmRvdyggZWxlbSApICkge1xuXG5cdFx0XHRcdFx0Ly8gRG9uJ3QgcmUtdHJpZ2dlciBhbiBvbkZPTyBldmVudCB3aGVuIHdlIGNhbGwgaXRzIEZPTygpIG1ldGhvZFxuXHRcdFx0XHRcdHRtcCA9IGVsZW1bIG9udHlwZSBdO1xuXG5cdFx0XHRcdFx0aWYgKCB0bXAgKSB7XG5cdFx0XHRcdFx0XHRlbGVtWyBvbnR5cGUgXSA9IG51bGw7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gUHJldmVudCByZS10cmlnZ2VyaW5nIG9mIHRoZSBzYW1lIGV2ZW50LCBzaW5jZSB3ZSBhbHJlYWR5IGJ1YmJsZWQgaXQgYWJvdmVcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdHlwZTtcblx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0ZWxlbVsgdHlwZSBdKCk7XG5cdFx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdFx0XHQvLyBJRTw5IGRpZXMgb24gZm9jdXMvYmx1ciB0byBoaWRkZW4gZWxlbWVudCAoIzE0ODYsIzEyNTE4KVxuXHRcdFx0XHRcdFx0Ly8gb25seSByZXByb2R1Y2libGUgb24gd2luWFAgSUU4IG5hdGl2ZSwgbm90IElFOSBpbiBJRTggbW9kZVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQudHJpZ2dlcmVkID0gdW5kZWZpbmVkO1xuXG5cdFx0XHRcdFx0aWYgKCB0bXAgKSB7XG5cdFx0XHRcdFx0XHRlbGVtWyBvbnR5cGUgXSA9IHRtcDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZXZlbnQucmVzdWx0O1xuXHR9LFxuXG5cdGRpc3BhdGNoOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cblx0XHQvLyBNYWtlIGEgd3JpdGFibGUgalF1ZXJ5LkV2ZW50IGZyb20gdGhlIG5hdGl2ZSBldmVudCBvYmplY3Rcblx0XHRldmVudCA9IGpRdWVyeS5ldmVudC5maXgoIGV2ZW50ICk7XG5cblx0XHR2YXIgaSwgcmV0LCBoYW5kbGVPYmosIG1hdGNoZWQsIGosXG5cdFx0XHRoYW5kbGVyUXVldWUgPSBbXSxcblx0XHRcdGFyZ3MgPSBzbGljZS5jYWxsKCBhcmd1bWVudHMgKSxcblx0XHRcdGhhbmRsZXJzID0gKCBqUXVlcnkuX2RhdGEoIHRoaXMsIFwiZXZlbnRzXCIgKSB8fCB7fSApWyBldmVudC50eXBlIF0gfHwgW10sXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWxbIGV2ZW50LnR5cGUgXSB8fCB7fTtcblxuXHRcdC8vIFVzZSB0aGUgZml4LWVkIGpRdWVyeS5FdmVudCByYXRoZXIgdGhhbiB0aGUgKHJlYWQtb25seSkgbmF0aXZlIGV2ZW50XG5cdFx0YXJnc1swXSA9IGV2ZW50O1xuXHRcdGV2ZW50LmRlbGVnYXRlVGFyZ2V0ID0gdGhpcztcblxuXHRcdC8vIENhbGwgdGhlIHByZURpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZSwgYW5kIGxldCBpdCBiYWlsIGlmIGRlc2lyZWRcblx0XHRpZiAoIHNwZWNpYWwucHJlRGlzcGF0Y2ggJiYgc3BlY2lhbC5wcmVEaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApID09PSBmYWxzZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBEZXRlcm1pbmUgaGFuZGxlcnNcblx0XHRoYW5kbGVyUXVldWUgPSBqUXVlcnkuZXZlbnQuaGFuZGxlcnMuY2FsbCggdGhpcywgZXZlbnQsIGhhbmRsZXJzICk7XG5cblx0XHQvLyBSdW4gZGVsZWdhdGVzIGZpcnN0OyB0aGV5IG1heSB3YW50IHRvIHN0b3AgcHJvcGFnYXRpb24gYmVuZWF0aCB1c1xuXHRcdGkgPSAwO1xuXHRcdHdoaWxlICggKG1hdGNoZWQgPSBoYW5kbGVyUXVldWVbIGkrKyBdKSAmJiAhZXZlbnQuaXNQcm9wYWdhdGlvblN0b3BwZWQoKSApIHtcblx0XHRcdGV2ZW50LmN1cnJlbnRUYXJnZXQgPSBtYXRjaGVkLmVsZW07XG5cblx0XHRcdGogPSAwO1xuXHRcdFx0d2hpbGUgKCAoaGFuZGxlT2JqID0gbWF0Y2hlZC5oYW5kbGVyc1sgaisrIF0pICYmICFldmVudC5pc0ltbWVkaWF0ZVByb3BhZ2F0aW9uU3RvcHBlZCgpICkge1xuXG5cdFx0XHRcdC8vIFRyaWdnZXJlZCBldmVudCBtdXN0IGVpdGhlciAxKSBoYXZlIG5vIG5hbWVzcGFjZSwgb3Jcblx0XHRcdFx0Ly8gMikgaGF2ZSBuYW1lc3BhY2UocykgYSBzdWJzZXQgb3IgZXF1YWwgdG8gdGhvc2UgaW4gdGhlIGJvdW5kIGV2ZW50IChib3RoIGNhbiBoYXZlIG5vIG5hbWVzcGFjZSkuXG5cdFx0XHRcdGlmICggIWV2ZW50Lm5hbWVzcGFjZV9yZSB8fCBldmVudC5uYW1lc3BhY2VfcmUudGVzdCggaGFuZGxlT2JqLm5hbWVzcGFjZSApICkge1xuXG5cdFx0XHRcdFx0ZXZlbnQuaGFuZGxlT2JqID0gaGFuZGxlT2JqO1xuXHRcdFx0XHRcdGV2ZW50LmRhdGEgPSBoYW5kbGVPYmouZGF0YTtcblxuXHRcdFx0XHRcdHJldCA9ICggKGpRdWVyeS5ldmVudC5zcGVjaWFsWyBoYW5kbGVPYmoub3JpZ1R5cGUgXSB8fCB7fSkuaGFuZGxlIHx8IGhhbmRsZU9iai5oYW5kbGVyIClcblx0XHRcdFx0XHRcdFx0LmFwcGx5KCBtYXRjaGVkLmVsZW0sIGFyZ3MgKTtcblxuXHRcdFx0XHRcdGlmICggcmV0ICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIChldmVudC5yZXN1bHQgPSByZXQpID09PSBmYWxzZSApIHtcblx0XHRcdFx0XHRcdFx0ZXZlbnQucHJldmVudERlZmF1bHQoKTtcblx0XHRcdFx0XHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gQ2FsbCB0aGUgcG9zdERpc3BhdGNoIGhvb2sgZm9yIHRoZSBtYXBwZWQgdHlwZVxuXHRcdGlmICggc3BlY2lhbC5wb3N0RGlzcGF0Y2ggKSB7XG5cdFx0XHRzcGVjaWFsLnBvc3REaXNwYXRjaC5jYWxsKCB0aGlzLCBldmVudCApO1xuXHRcdH1cblxuXHRcdHJldHVybiBldmVudC5yZXN1bHQ7XG5cdH0sXG5cblx0aGFuZGxlcnM6IGZ1bmN0aW9uKCBldmVudCwgaGFuZGxlcnMgKSB7XG5cdFx0dmFyIHNlbCwgaGFuZGxlT2JqLCBtYXRjaGVzLCBpLFxuXHRcdFx0aGFuZGxlclF1ZXVlID0gW10sXG5cdFx0XHRkZWxlZ2F0ZUNvdW50ID0gaGFuZGxlcnMuZGVsZWdhdGVDb3VudCxcblx0XHRcdGN1ciA9IGV2ZW50LnRhcmdldDtcblxuXHRcdC8vIEZpbmQgZGVsZWdhdGUgaGFuZGxlcnNcblx0XHQvLyBCbGFjay1ob2xlIFNWRyA8dXNlPiBpbnN0YW5jZSB0cmVlcyAoIzEzMTgwKVxuXHRcdC8vIEF2b2lkIG5vbi1sZWZ0LWNsaWNrIGJ1YmJsaW5nIGluIEZpcmVmb3ggKCMzODYxKVxuXHRcdGlmICggZGVsZWdhdGVDb3VudCAmJiBjdXIubm9kZVR5cGUgJiYgKCFldmVudC5idXR0b24gfHwgZXZlbnQudHlwZSAhPT0gXCJjbGlja1wiKSApIHtcblxuXHRcdFx0LyoganNoaW50IGVxZXFlcTogZmFsc2UgKi9cblx0XHRcdGZvciAoIDsgY3VyICE9IHRoaXM7IGN1ciA9IGN1ci5wYXJlbnROb2RlIHx8IHRoaXMgKSB7XG5cdFx0XHRcdC8qIGpzaGludCBlcWVxZXE6IHRydWUgKi9cblxuXHRcdFx0XHQvLyBEb24ndCBjaGVjayBub24tZWxlbWVudHMgKCMxMzIwOClcblx0XHRcdFx0Ly8gRG9uJ3QgcHJvY2VzcyBjbGlja3Mgb24gZGlzYWJsZWQgZWxlbWVudHMgKCM2OTExLCAjODE2NSwgIzExMzgyLCAjMTE3NjQpXG5cdFx0XHRcdGlmICggY3VyLm5vZGVUeXBlID09PSAxICYmIChjdXIuZGlzYWJsZWQgIT09IHRydWUgfHwgZXZlbnQudHlwZSAhPT0gXCJjbGlja1wiKSApIHtcblx0XHRcdFx0XHRtYXRjaGVzID0gW107XG5cdFx0XHRcdFx0Zm9yICggaSA9IDA7IGkgPCBkZWxlZ2F0ZUNvdW50OyBpKysgKSB7XG5cdFx0XHRcdFx0XHRoYW5kbGVPYmogPSBoYW5kbGVyc1sgaSBdO1xuXG5cdFx0XHRcdFx0XHQvLyBEb24ndCBjb25mbGljdCB3aXRoIE9iamVjdC5wcm90b3R5cGUgcHJvcGVydGllcyAoIzEzMjAzKVxuXHRcdFx0XHRcdFx0c2VsID0gaGFuZGxlT2JqLnNlbGVjdG9yICsgXCIgXCI7XG5cblx0XHRcdFx0XHRcdGlmICggbWF0Y2hlc1sgc2VsIF0gPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdFx0bWF0Y2hlc1sgc2VsIF0gPSBoYW5kbGVPYmoubmVlZHNDb250ZXh0ID9cblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkoIHNlbCwgdGhpcyApLmluZGV4KCBjdXIgKSA+PSAwIDpcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZmluZCggc2VsLCB0aGlzLCBudWxsLCBbIGN1ciBdICkubGVuZ3RoO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0aWYgKCBtYXRjaGVzWyBzZWwgXSApIHtcblx0XHRcdFx0XHRcdFx0bWF0Y2hlcy5wdXNoKCBoYW5kbGVPYmogKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0aWYgKCBtYXRjaGVzLmxlbmd0aCApIHtcblx0XHRcdFx0XHRcdGhhbmRsZXJRdWV1ZS5wdXNoKHsgZWxlbTogY3VyLCBoYW5kbGVyczogbWF0Y2hlcyB9KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBBZGQgdGhlIHJlbWFpbmluZyAoZGlyZWN0bHktYm91bmQpIGhhbmRsZXJzXG5cdFx0aWYgKCBkZWxlZ2F0ZUNvdW50IDwgaGFuZGxlcnMubGVuZ3RoICkge1xuXHRcdFx0aGFuZGxlclF1ZXVlLnB1c2goeyBlbGVtOiB0aGlzLCBoYW5kbGVyczogaGFuZGxlcnMuc2xpY2UoIGRlbGVnYXRlQ291bnQgKSB9KTtcblx0XHR9XG5cblx0XHRyZXR1cm4gaGFuZGxlclF1ZXVlO1xuXHR9LFxuXG5cdGZpeDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdGlmICggZXZlbnRbIGpRdWVyeS5leHBhbmRvIF0gKSB7XG5cdFx0XHRyZXR1cm4gZXZlbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gQ3JlYXRlIGEgd3JpdGFibGUgY29weSBvZiB0aGUgZXZlbnQgb2JqZWN0IGFuZCBub3JtYWxpemUgc29tZSBwcm9wZXJ0aWVzXG5cdFx0dmFyIGksIHByb3AsIGNvcHksXG5cdFx0XHR0eXBlID0gZXZlbnQudHlwZSxcblx0XHRcdG9yaWdpbmFsRXZlbnQgPSBldmVudCxcblx0XHRcdGZpeEhvb2sgPSB0aGlzLmZpeEhvb2tzWyB0eXBlIF07XG5cblx0XHRpZiAoICFmaXhIb29rICkge1xuXHRcdFx0dGhpcy5maXhIb29rc1sgdHlwZSBdID0gZml4SG9vayA9XG5cdFx0XHRcdHJtb3VzZUV2ZW50LnRlc3QoIHR5cGUgKSA/IHRoaXMubW91c2VIb29rcyA6XG5cdFx0XHRcdHJrZXlFdmVudC50ZXN0KCB0eXBlICkgPyB0aGlzLmtleUhvb2tzIDpcblx0XHRcdFx0e307XG5cdFx0fVxuXHRcdGNvcHkgPSBmaXhIb29rLnByb3BzID8gdGhpcy5wcm9wcy5jb25jYXQoIGZpeEhvb2sucHJvcHMgKSA6IHRoaXMucHJvcHM7XG5cblx0XHRldmVudCA9IG5ldyBqUXVlcnkuRXZlbnQoIG9yaWdpbmFsRXZlbnQgKTtcblxuXHRcdGkgPSBjb3B5Lmxlbmd0aDtcblx0XHR3aGlsZSAoIGktLSApIHtcblx0XHRcdHByb3AgPSBjb3B5WyBpIF07XG5cdFx0XHRldmVudFsgcHJvcCBdID0gb3JpZ2luYWxFdmVudFsgcHJvcCBdO1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IElFPDlcblx0XHQvLyBGaXggdGFyZ2V0IHByb3BlcnR5ICgjMTkyNSlcblx0XHRpZiAoICFldmVudC50YXJnZXQgKSB7XG5cdFx0XHRldmVudC50YXJnZXQgPSBvcmlnaW5hbEV2ZW50LnNyY0VsZW1lbnQgfHwgZG9jdW1lbnQ7XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogQ2hyb21lIDIzKywgU2FmYXJpP1xuXHRcdC8vIFRhcmdldCBzaG91bGQgbm90IGJlIGEgdGV4dCBub2RlICgjNTA0LCAjMTMxNDMpXG5cdFx0aWYgKCBldmVudC50YXJnZXQubm9kZVR5cGUgPT09IDMgKSB7XG5cdFx0XHRldmVudC50YXJnZXQgPSBldmVudC50YXJnZXQucGFyZW50Tm9kZTtcblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBJRTw5XG5cdFx0Ly8gRm9yIG1vdXNlL2tleSBldmVudHMsIG1ldGFLZXk9PWZhbHNlIGlmIGl0J3MgdW5kZWZpbmVkICgjMzM2OCwgIzExMzI4KVxuXHRcdGV2ZW50Lm1ldGFLZXkgPSAhIWV2ZW50Lm1ldGFLZXk7XG5cblx0XHRyZXR1cm4gZml4SG9vay5maWx0ZXIgPyBmaXhIb29rLmZpbHRlciggZXZlbnQsIG9yaWdpbmFsRXZlbnQgKSA6IGV2ZW50O1xuXHR9LFxuXG5cdC8vIEluY2x1ZGVzIHNvbWUgZXZlbnQgcHJvcHMgc2hhcmVkIGJ5IEtleUV2ZW50IGFuZCBNb3VzZUV2ZW50XG5cdHByb3BzOiBcImFsdEtleSBidWJibGVzIGNhbmNlbGFibGUgY3RybEtleSBjdXJyZW50VGFyZ2V0IGV2ZW50UGhhc2UgbWV0YUtleSByZWxhdGVkVGFyZ2V0IHNoaWZ0S2V5IHRhcmdldCB0aW1lU3RhbXAgdmlldyB3aGljaFwiLnNwbGl0KFwiIFwiKSxcblxuXHRmaXhIb29rczoge30sXG5cblx0a2V5SG9va3M6IHtcblx0XHRwcm9wczogXCJjaGFyIGNoYXJDb2RlIGtleSBrZXlDb2RlXCIuc3BsaXQoXCIgXCIpLFxuXHRcdGZpbHRlcjogZnVuY3Rpb24oIGV2ZW50LCBvcmlnaW5hbCApIHtcblxuXHRcdFx0Ly8gQWRkIHdoaWNoIGZvciBrZXkgZXZlbnRzXG5cdFx0XHRpZiAoIGV2ZW50LndoaWNoID09IG51bGwgKSB7XG5cdFx0XHRcdGV2ZW50LndoaWNoID0gb3JpZ2luYWwuY2hhckNvZGUgIT0gbnVsbCA/IG9yaWdpbmFsLmNoYXJDb2RlIDogb3JpZ2luYWwua2V5Q29kZTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGV2ZW50O1xuXHRcdH1cblx0fSxcblxuXHRtb3VzZUhvb2tzOiB7XG5cdFx0cHJvcHM6IFwiYnV0dG9uIGJ1dHRvbnMgY2xpZW50WCBjbGllbnRZIGZyb21FbGVtZW50IG9mZnNldFggb2Zmc2V0WSBwYWdlWCBwYWdlWSBzY3JlZW5YIHNjcmVlblkgdG9FbGVtZW50XCIuc3BsaXQoXCIgXCIpLFxuXHRcdGZpbHRlcjogZnVuY3Rpb24oIGV2ZW50LCBvcmlnaW5hbCApIHtcblx0XHRcdHZhciBib2R5LCBldmVudERvYywgZG9jLFxuXHRcdFx0XHRidXR0b24gPSBvcmlnaW5hbC5idXR0b24sXG5cdFx0XHRcdGZyb21FbGVtZW50ID0gb3JpZ2luYWwuZnJvbUVsZW1lbnQ7XG5cblx0XHRcdC8vIENhbGN1bGF0ZSBwYWdlWC9ZIGlmIG1pc3NpbmcgYW5kIGNsaWVudFgvWSBhdmFpbGFibGVcblx0XHRcdGlmICggZXZlbnQucGFnZVggPT0gbnVsbCAmJiBvcmlnaW5hbC5jbGllbnRYICE9IG51bGwgKSB7XG5cdFx0XHRcdGV2ZW50RG9jID0gZXZlbnQudGFyZ2V0Lm93bmVyRG9jdW1lbnQgfHwgZG9jdW1lbnQ7XG5cdFx0XHRcdGRvYyA9IGV2ZW50RG9jLmRvY3VtZW50RWxlbWVudDtcblx0XHRcdFx0Ym9keSA9IGV2ZW50RG9jLmJvZHk7XG5cblx0XHRcdFx0ZXZlbnQucGFnZVggPSBvcmlnaW5hbC5jbGllbnRYICsgKCBkb2MgJiYgZG9jLnNjcm9sbExlZnQgfHwgYm9keSAmJiBib2R5LnNjcm9sbExlZnQgfHwgMCApIC0gKCBkb2MgJiYgZG9jLmNsaWVudExlZnQgfHwgYm9keSAmJiBib2R5LmNsaWVudExlZnQgfHwgMCApO1xuXHRcdFx0XHRldmVudC5wYWdlWSA9IG9yaWdpbmFsLmNsaWVudFkgKyAoIGRvYyAmJiBkb2Muc2Nyb2xsVG9wICB8fCBib2R5ICYmIGJvZHkuc2Nyb2xsVG9wICB8fCAwICkgLSAoIGRvYyAmJiBkb2MuY2xpZW50VG9wICB8fCBib2R5ICYmIGJvZHkuY2xpZW50VG9wICB8fCAwICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCByZWxhdGVkVGFyZ2V0LCBpZiBuZWNlc3Nhcnlcblx0XHRcdGlmICggIWV2ZW50LnJlbGF0ZWRUYXJnZXQgJiYgZnJvbUVsZW1lbnQgKSB7XG5cdFx0XHRcdGV2ZW50LnJlbGF0ZWRUYXJnZXQgPSBmcm9tRWxlbWVudCA9PT0gZXZlbnQudGFyZ2V0ID8gb3JpZ2luYWwudG9FbGVtZW50IDogZnJvbUVsZW1lbnQ7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEFkZCB3aGljaCBmb3IgY2xpY2s6IDEgPT09IGxlZnQ7IDIgPT09IG1pZGRsZTsgMyA9PT0gcmlnaHRcblx0XHRcdC8vIE5vdGU6IGJ1dHRvbiBpcyBub3Qgbm9ybWFsaXplZCwgc28gZG9uJ3QgdXNlIGl0XG5cdFx0XHRpZiAoICFldmVudC53aGljaCAmJiBidXR0b24gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0ZXZlbnQud2hpY2ggPSAoIGJ1dHRvbiAmIDEgPyAxIDogKCBidXR0b24gJiAyID8gMyA6ICggYnV0dG9uICYgNCA/IDIgOiAwICkgKSApO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gZXZlbnQ7XG5cdFx0fVxuXHR9LFxuXG5cdHNwZWNpYWw6IHtcblx0XHRsb2FkOiB7XG5cdFx0XHQvLyBQcmV2ZW50IHRyaWdnZXJlZCBpbWFnZS5sb2FkIGV2ZW50cyBmcm9tIGJ1YmJsaW5nIHRvIHdpbmRvdy5sb2FkXG5cdFx0XHRub0J1YmJsZTogdHJ1ZVxuXHRcdH0sXG5cdFx0Zm9jdXM6IHtcblx0XHRcdC8vIEZpcmUgbmF0aXZlIGV2ZW50IGlmIHBvc3NpYmxlIHNvIGJsdXIvZm9jdXMgc2VxdWVuY2UgaXMgY29ycmVjdFxuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggdGhpcyAhPT0gc2FmZUFjdGl2ZUVsZW1lbnQoKSAmJiB0aGlzLmZvY3VzICkge1xuXHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHR0aGlzLmZvY3VzKCk7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdFx0fSBjYXRjaCAoIGUgKSB7XG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRTw5XG5cdFx0XHRcdFx0XHQvLyBJZiB3ZSBlcnJvciBvbiBmb2N1cyB0byBoaWRkZW4gZWxlbWVudCAoIzE0ODYsICMxMjUxOCksXG5cdFx0XHRcdFx0XHQvLyBsZXQgLnRyaWdnZXIoKSBydW4gdGhlIGhhbmRsZXJzXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVsZWdhdGVUeXBlOiBcImZvY3VzaW5cIlxuXHRcdH0sXG5cdFx0Ymx1cjoge1xuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggdGhpcyA9PT0gc2FmZUFjdGl2ZUVsZW1lbnQoKSAmJiB0aGlzLmJsdXIgKSB7XG5cdFx0XHRcdFx0dGhpcy5ibHVyKCk7XG5cdFx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0ZGVsZWdhdGVUeXBlOiBcImZvY3Vzb3V0XCJcblx0XHR9LFxuXHRcdGNsaWNrOiB7XG5cdFx0XHQvLyBGb3IgY2hlY2tib3gsIGZpcmUgbmF0aXZlIGV2ZW50IHNvIGNoZWNrZWQgc3RhdGUgd2lsbCBiZSByaWdodFxuXHRcdFx0dHJpZ2dlcjogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggalF1ZXJ5Lm5vZGVOYW1lKCB0aGlzLCBcImlucHV0XCIgKSAmJiB0aGlzLnR5cGUgPT09IFwiY2hlY2tib3hcIiAmJiB0aGlzLmNsaWNrICkge1xuXHRcdFx0XHRcdHRoaXMuY2xpY2soKTtcblx0XHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHRcdH1cblx0XHRcdH0sXG5cblx0XHRcdC8vIEZvciBjcm9zcy1icm93c2VyIGNvbnNpc3RlbmN5LCBkb24ndCBmaXJlIG5hdGl2ZSAuY2xpY2soKSBvbiBsaW5rc1xuXHRcdFx0X2RlZmF1bHQ6IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0cmV0dXJuIGpRdWVyeS5ub2RlTmFtZSggZXZlbnQudGFyZ2V0LCBcImFcIiApO1xuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHRiZWZvcmV1bmxvYWQ6IHtcblx0XHRcdHBvc3REaXNwYXRjaDogZnVuY3Rpb24oIGV2ZW50ICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3ggMjArXG5cdFx0XHRcdC8vIEZpcmVmb3ggZG9lc24ndCBhbGVydCBpZiB0aGUgcmV0dXJuVmFsdWUgZmllbGQgaXMgbm90IHNldC5cblx0XHRcdFx0aWYgKCBldmVudC5yZXN1bHQgIT09IHVuZGVmaW5lZCAmJiBldmVudC5vcmlnaW5hbEV2ZW50ICkge1xuXHRcdFx0XHRcdGV2ZW50Lm9yaWdpbmFsRXZlbnQucmV0dXJuVmFsdWUgPSBldmVudC5yZXN1bHQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH0sXG5cblx0c2ltdWxhdGU6IGZ1bmN0aW9uKCB0eXBlLCBlbGVtLCBldmVudCwgYnViYmxlICkge1xuXHRcdC8vIFBpZ2d5YmFjayBvbiBhIGRvbm9yIGV2ZW50IHRvIHNpbXVsYXRlIGEgZGlmZmVyZW50IG9uZS5cblx0XHQvLyBGYWtlIG9yaWdpbmFsRXZlbnQgdG8gYXZvaWQgZG9ub3IncyBzdG9wUHJvcGFnYXRpb24sIGJ1dCBpZiB0aGVcblx0XHQvLyBzaW11bGF0ZWQgZXZlbnQgcHJldmVudHMgZGVmYXVsdCB0aGVuIHdlIGRvIHRoZSBzYW1lIG9uIHRoZSBkb25vci5cblx0XHR2YXIgZSA9IGpRdWVyeS5leHRlbmQoXG5cdFx0XHRuZXcgalF1ZXJ5LkV2ZW50KCksXG5cdFx0XHRldmVudCxcblx0XHRcdHtcblx0XHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdFx0aXNTaW11bGF0ZWQ6IHRydWUsXG5cdFx0XHRcdG9yaWdpbmFsRXZlbnQ6IHt9XG5cdFx0XHR9XG5cdFx0KTtcblx0XHRpZiAoIGJ1YmJsZSApIHtcblx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCBlLCBudWxsLCBlbGVtICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGpRdWVyeS5ldmVudC5kaXNwYXRjaC5jYWxsKCBlbGVtLCBlICk7XG5cdFx0fVxuXHRcdGlmICggZS5pc0RlZmF1bHRQcmV2ZW50ZWQoKSApIHtcblx0XHRcdGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG5cdFx0fVxuXHR9XG59O1xuXG5qUXVlcnkucmVtb3ZlRXZlbnQgPSBkb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyID9cblx0ZnVuY3Rpb24oIGVsZW0sIHR5cGUsIGhhbmRsZSApIHtcblx0XHRpZiAoIGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciApIHtcblx0XHRcdGVsZW0ucmVtb3ZlRXZlbnRMaXN0ZW5lciggdHlwZSwgaGFuZGxlLCBmYWxzZSApO1xuXHRcdH1cblx0fSA6XG5cdGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCBoYW5kbGUgKSB7XG5cdFx0dmFyIG5hbWUgPSBcIm9uXCIgKyB0eXBlO1xuXG5cdFx0aWYgKCBlbGVtLmRldGFjaEV2ZW50ICkge1xuXG5cdFx0XHQvLyAjODU0NSwgIzcwNTQsIHByZXZlbnRpbmcgbWVtb3J5IGxlYWtzIGZvciBjdXN0b20gZXZlbnRzIGluIElFNi04XG5cdFx0XHQvLyBkZXRhY2hFdmVudCBuZWVkZWQgcHJvcGVydHkgb24gZWxlbWVudCwgYnkgbmFtZSBvZiB0aGF0IGV2ZW50LCB0byBwcm9wZXJseSBleHBvc2UgaXQgdG8gR0Ncblx0XHRcdGlmICggdHlwZW9mIGVsZW1bIG5hbWUgXSA9PT0gc3RydW5kZWZpbmVkICkge1xuXHRcdFx0XHRlbGVtWyBuYW1lIF0gPSBudWxsO1xuXHRcdFx0fVxuXG5cdFx0XHRlbGVtLmRldGFjaEV2ZW50KCBuYW1lLCBoYW5kbGUgKTtcblx0XHR9XG5cdH07XG5cbmpRdWVyeS5FdmVudCA9IGZ1bmN0aW9uKCBzcmMsIHByb3BzICkge1xuXHQvLyBBbGxvdyBpbnN0YW50aWF0aW9uIHdpdGhvdXQgdGhlICduZXcnIGtleXdvcmRcblx0aWYgKCAhKHRoaXMgaW5zdGFuY2VvZiBqUXVlcnkuRXZlbnQpICkge1xuXHRcdHJldHVybiBuZXcgalF1ZXJ5LkV2ZW50KCBzcmMsIHByb3BzICk7XG5cdH1cblxuXHQvLyBFdmVudCBvYmplY3Rcblx0aWYgKCBzcmMgJiYgc3JjLnR5cGUgKSB7XG5cdFx0dGhpcy5vcmlnaW5hbEV2ZW50ID0gc3JjO1xuXHRcdHRoaXMudHlwZSA9IHNyYy50eXBlO1xuXG5cdFx0Ly8gRXZlbnRzIGJ1YmJsaW5nIHVwIHRoZSBkb2N1bWVudCBtYXkgaGF2ZSBiZWVuIG1hcmtlZCBhcyBwcmV2ZW50ZWRcblx0XHQvLyBieSBhIGhhbmRsZXIgbG93ZXIgZG93biB0aGUgdHJlZTsgcmVmbGVjdCB0aGUgY29ycmVjdCB2YWx1ZS5cblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHNyYy5kZWZhdWx0UHJldmVudGVkIHx8XG5cdFx0XHRcdHNyYy5kZWZhdWx0UHJldmVudGVkID09PSB1bmRlZmluZWQgJiZcblx0XHRcdFx0Ly8gU3VwcG9ydDogSUUgPCA5LCBBbmRyb2lkIDwgNC4wXG5cdFx0XHRcdHNyYy5yZXR1cm5WYWx1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0cmV0dXJuVHJ1ZSA6XG5cdFx0XHRyZXR1cm5GYWxzZTtcblxuXHQvLyBFdmVudCB0eXBlXG5cdH0gZWxzZSB7XG5cdFx0dGhpcy50eXBlID0gc3JjO1xuXHR9XG5cblx0Ly8gUHV0IGV4cGxpY2l0bHkgcHJvdmlkZWQgcHJvcGVydGllcyBvbnRvIHRoZSBldmVudCBvYmplY3Rcblx0aWYgKCBwcm9wcyApIHtcblx0XHRqUXVlcnkuZXh0ZW5kKCB0aGlzLCBwcm9wcyApO1xuXHR9XG5cblx0Ly8gQ3JlYXRlIGEgdGltZXN0YW1wIGlmIGluY29taW5nIGV2ZW50IGRvZXNuJ3QgaGF2ZSBvbmVcblx0dGhpcy50aW1lU3RhbXAgPSBzcmMgJiYgc3JjLnRpbWVTdGFtcCB8fCBqUXVlcnkubm93KCk7XG5cblx0Ly8gTWFyayBpdCBhcyBmaXhlZFxuXHR0aGlzWyBqUXVlcnkuZXhwYW5kbyBdID0gdHJ1ZTtcbn07XG5cbi8vIGpRdWVyeS5FdmVudCBpcyBiYXNlZCBvbiBET00zIEV2ZW50cyBhcyBzcGVjaWZpZWQgYnkgdGhlIEVDTUFTY3JpcHQgTGFuZ3VhZ2UgQmluZGluZ1xuLy8gaHR0cDovL3d3dy53My5vcmcvVFIvMjAwMy9XRC1ET00tTGV2ZWwtMy1FdmVudHMtMjAwMzAzMzEvZWNtYS1zY3JpcHQtYmluZGluZy5odG1sXG5qUXVlcnkuRXZlbnQucHJvdG90eXBlID0ge1xuXHRpc0RlZmF1bHRQcmV2ZW50ZWQ6IHJldHVybkZhbHNlLFxuXHRpc1Byb3BhZ2F0aW9uU3RvcHBlZDogcmV0dXJuRmFsc2UsXG5cdGlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkOiByZXR1cm5GYWxzZSxcblxuXHRwcmV2ZW50RGVmYXVsdDogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzRGVmYXVsdFByZXZlbnRlZCA9IHJldHVyblRydWU7XG5cdFx0aWYgKCAhZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBJZiBwcmV2ZW50RGVmYXVsdCBleGlzdHMsIHJ1biBpdCBvbiB0aGUgb3JpZ2luYWwgZXZlbnRcblx0XHRpZiAoIGUucHJldmVudERlZmF1bHQgKSB7XG5cdFx0XHRlLnByZXZlbnREZWZhdWx0KCk7XG5cblx0XHQvLyBTdXBwb3J0OiBJRVxuXHRcdC8vIE90aGVyd2lzZSBzZXQgdGhlIHJldHVyblZhbHVlIHByb3BlcnR5IG9mIHRoZSBvcmlnaW5hbCBldmVudCB0byBmYWxzZVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRlLnJldHVyblZhbHVlID0gZmFsc2U7XG5cdFx0fVxuXHR9LFxuXHRzdG9wUHJvcGFnYXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlID0gdGhpcy5vcmlnaW5hbEV2ZW50O1xuXG5cdFx0dGhpcy5pc1Byb3BhZ2F0aW9uU3RvcHBlZCA9IHJldHVyblRydWU7XG5cdFx0aWYgKCAhZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0Ly8gSWYgc3RvcFByb3BhZ2F0aW9uIGV4aXN0cywgcnVuIGl0IG9uIHRoZSBvcmlnaW5hbCBldmVudFxuXHRcdGlmICggZS5zdG9wUHJvcGFnYXRpb24gKSB7XG5cdFx0XHRlLnN0b3BQcm9wYWdhdGlvbigpO1xuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IElFXG5cdFx0Ly8gU2V0IHRoZSBjYW5jZWxCdWJibGUgcHJvcGVydHkgb2YgdGhlIG9yaWdpbmFsIGV2ZW50IHRvIHRydWVcblx0XHRlLmNhbmNlbEJ1YmJsZSA9IHRydWU7XG5cdH0sXG5cdHN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGUgPSB0aGlzLm9yaWdpbmFsRXZlbnQ7XG5cblx0XHR0aGlzLmlzSW1tZWRpYXRlUHJvcGFnYXRpb25TdG9wcGVkID0gcmV0dXJuVHJ1ZTtcblxuXHRcdGlmICggZSAmJiBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbiApIHtcblx0XHRcdGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKCk7XG5cdFx0fVxuXG5cdFx0dGhpcy5zdG9wUHJvcGFnYXRpb24oKTtcblx0fVxufTtcblxuLy8gQ3JlYXRlIG1vdXNlZW50ZXIvbGVhdmUgZXZlbnRzIHVzaW5nIG1vdXNlb3Zlci9vdXQgYW5kIGV2ZW50LXRpbWUgY2hlY2tzXG5qUXVlcnkuZWFjaCh7XG5cdG1vdXNlZW50ZXI6IFwibW91c2VvdmVyXCIsXG5cdG1vdXNlbGVhdmU6IFwibW91c2VvdXRcIixcblx0cG9pbnRlcmVudGVyOiBcInBvaW50ZXJvdmVyXCIsXG5cdHBvaW50ZXJsZWF2ZTogXCJwb2ludGVyb3V0XCJcbn0sIGZ1bmN0aW9uKCBvcmlnLCBmaXggKSB7XG5cdGpRdWVyeS5ldmVudC5zcGVjaWFsWyBvcmlnIF0gPSB7XG5cdFx0ZGVsZWdhdGVUeXBlOiBmaXgsXG5cdFx0YmluZFR5cGU6IGZpeCxcblxuXHRcdGhhbmRsZTogZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0dmFyIHJldCxcblx0XHRcdFx0dGFyZ2V0ID0gdGhpcyxcblx0XHRcdFx0cmVsYXRlZCA9IGV2ZW50LnJlbGF0ZWRUYXJnZXQsXG5cdFx0XHRcdGhhbmRsZU9iaiA9IGV2ZW50LmhhbmRsZU9iajtcblxuXHRcdFx0Ly8gRm9yIG1vdXNlbnRlci9sZWF2ZSBjYWxsIHRoZSBoYW5kbGVyIGlmIHJlbGF0ZWQgaXMgb3V0c2lkZSB0aGUgdGFyZ2V0LlxuXHRcdFx0Ly8gTkI6IE5vIHJlbGF0ZWRUYXJnZXQgaWYgdGhlIG1vdXNlIGxlZnQvZW50ZXJlZCB0aGUgYnJvd3NlciB3aW5kb3dcblx0XHRcdGlmICggIXJlbGF0ZWQgfHwgKHJlbGF0ZWQgIT09IHRhcmdldCAmJiAhalF1ZXJ5LmNvbnRhaW5zKCB0YXJnZXQsIHJlbGF0ZWQgKSkgKSB7XG5cdFx0XHRcdGV2ZW50LnR5cGUgPSBoYW5kbGVPYmoub3JpZ1R5cGU7XG5cdFx0XHRcdHJldCA9IGhhbmRsZU9iai5oYW5kbGVyLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKTtcblx0XHRcdFx0ZXZlbnQudHlwZSA9IGZpeDtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZXQ7XG5cdFx0fVxuXHR9O1xufSk7XG5cbi8vIElFIHN1Ym1pdCBkZWxlZ2F0aW9uXG5pZiAoICFzdXBwb3J0LnN1Ym1pdEJ1YmJsZXMgKSB7XG5cblx0alF1ZXJ5LmV2ZW50LnNwZWNpYWwuc3VibWl0ID0ge1xuXHRcdHNldHVwOiBmdW5jdGlvbigpIHtcblx0XHRcdC8vIE9ubHkgbmVlZCB0aGlzIGZvciBkZWxlZ2F0ZWQgZm9ybSBzdWJtaXQgZXZlbnRzXG5cdFx0XHRpZiAoIGpRdWVyeS5ub2RlTmFtZSggdGhpcywgXCJmb3JtXCIgKSApIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBMYXp5LWFkZCBhIHN1Ym1pdCBoYW5kbGVyIHdoZW4gYSBkZXNjZW5kYW50IGZvcm0gbWF5IHBvdGVudGlhbGx5IGJlIHN1Ym1pdHRlZFxuXHRcdFx0alF1ZXJ5LmV2ZW50LmFkZCggdGhpcywgXCJjbGljay5fc3VibWl0IGtleXByZXNzLl9zdWJtaXRcIiwgZnVuY3Rpb24oIGUgKSB7XG5cdFx0XHRcdC8vIE5vZGUgbmFtZSBjaGVjayBhdm9pZHMgYSBWTUwtcmVsYXRlZCBjcmFzaCBpbiBJRSAoIzk4MDcpXG5cdFx0XHRcdHZhciBlbGVtID0gZS50YXJnZXQsXG5cdFx0XHRcdFx0Zm9ybSA9IGpRdWVyeS5ub2RlTmFtZSggZWxlbSwgXCJpbnB1dFwiICkgfHwgalF1ZXJ5Lm5vZGVOYW1lKCBlbGVtLCBcImJ1dHRvblwiICkgPyBlbGVtLmZvcm0gOiB1bmRlZmluZWQ7XG5cdFx0XHRcdGlmICggZm9ybSAmJiAhalF1ZXJ5Ll9kYXRhKCBmb3JtLCBcInN1Ym1pdEJ1YmJsZXNcIiApICkge1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5hZGQoIGZvcm0sIFwic3VibWl0Ll9zdWJtaXRcIiwgZnVuY3Rpb24oIGV2ZW50ICkge1xuXHRcdFx0XHRcdFx0ZXZlbnQuX3N1Ym1pdF9idWJibGUgPSB0cnVlO1xuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdGpRdWVyeS5fZGF0YSggZm9ybSwgXCJzdWJtaXRCdWJibGVzXCIsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0XHQvLyByZXR1cm4gdW5kZWZpbmVkIHNpbmNlIHdlIGRvbid0IG5lZWQgYW4gZXZlbnQgbGlzdGVuZXJcblx0XHR9LFxuXG5cdFx0cG9zdERpc3BhdGNoOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHQvLyBJZiBmb3JtIHdhcyBzdWJtaXR0ZWQgYnkgdGhlIHVzZXIsIGJ1YmJsZSB0aGUgZXZlbnQgdXAgdGhlIHRyZWVcblx0XHRcdGlmICggZXZlbnQuX3N1Ym1pdF9idWJibGUgKSB7XG5cdFx0XHRcdGRlbGV0ZSBldmVudC5fc3VibWl0X2J1YmJsZTtcblx0XHRcdFx0aWYgKCB0aGlzLnBhcmVudE5vZGUgJiYgIWV2ZW50LmlzVHJpZ2dlciApIHtcblx0XHRcdFx0XHRqUXVlcnkuZXZlbnQuc2ltdWxhdGUoIFwic3VibWl0XCIsIHRoaXMucGFyZW50Tm9kZSwgZXZlbnQsIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0sXG5cblx0XHR0ZWFyZG93bjogZnVuY3Rpb24oKSB7XG5cdFx0XHQvLyBPbmx5IG5lZWQgdGhpcyBmb3IgZGVsZWdhdGVkIGZvcm0gc3VibWl0IGV2ZW50c1xuXHRcdFx0aWYgKCBqUXVlcnkubm9kZU5hbWUoIHRoaXMsIFwiZm9ybVwiICkgKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gUmVtb3ZlIGRlbGVnYXRlZCBoYW5kbGVyczsgY2xlYW5EYXRhIGV2ZW50dWFsbHkgcmVhcHMgc3VibWl0IGhhbmRsZXJzIGF0dGFjaGVkIGFib3ZlXG5cdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCB0aGlzLCBcIi5fc3VibWl0XCIgKTtcblx0XHR9XG5cdH07XG59XG5cbi8vIElFIGNoYW5nZSBkZWxlZ2F0aW9uIGFuZCBjaGVja2JveC9yYWRpbyBmaXhcbmlmICggIXN1cHBvcnQuY2hhbmdlQnViYmxlcyApIHtcblxuXHRqUXVlcnkuZXZlbnQuc3BlY2lhbC5jaGFuZ2UgPSB7XG5cblx0XHRzZXR1cDogZnVuY3Rpb24oKSB7XG5cblx0XHRcdGlmICggcmZvcm1FbGVtcy50ZXN0KCB0aGlzLm5vZGVOYW1lICkgKSB7XG5cdFx0XHRcdC8vIElFIGRvZXNuJ3QgZmlyZSBjaGFuZ2Ugb24gYSBjaGVjay9yYWRpbyB1bnRpbCBibHVyOyB0cmlnZ2VyIGl0IG9uIGNsaWNrXG5cdFx0XHRcdC8vIGFmdGVyIGEgcHJvcGVydHljaGFuZ2UuIEVhdCB0aGUgYmx1ci1jaGFuZ2UgaW4gc3BlY2lhbC5jaGFuZ2UuaGFuZGxlLlxuXHRcdFx0XHQvLyBUaGlzIHN0aWxsIGZpcmVzIG9uY2hhbmdlIGEgc2Vjb25kIHRpbWUgZm9yIGNoZWNrL3JhZGlvIGFmdGVyIGJsdXIuXG5cdFx0XHRcdGlmICggdGhpcy50eXBlID09PSBcImNoZWNrYm94XCIgfHwgdGhpcy50eXBlID09PSBcInJhZGlvXCIgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmFkZCggdGhpcywgXCJwcm9wZXJ0eWNoYW5nZS5fY2hhbmdlXCIsIGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0XHRcdGlmICggZXZlbnQub3JpZ2luYWxFdmVudC5wcm9wZXJ0eU5hbWUgPT09IFwiY2hlY2tlZFwiICkge1xuXHRcdFx0XHRcdFx0XHR0aGlzLl9qdXN0X2NoYW5nZWQgPSB0cnVlO1xuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHRcdGpRdWVyeS5ldmVudC5hZGQoIHRoaXMsIFwiY2xpY2suX2NoYW5nZVwiLCBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIHRoaXMuX2p1c3RfY2hhbmdlZCAmJiAhZXZlbnQuaXNUcmlnZ2VyICkge1xuXHRcdFx0XHRcdFx0XHR0aGlzLl9qdXN0X2NoYW5nZWQgPSBmYWxzZTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdC8vIEFsbG93IHRyaWdnZXJlZCwgc2ltdWxhdGVkIGNoYW5nZSBldmVudHMgKCMxMTUwMClcblx0XHRcdFx0XHRcdGpRdWVyeS5ldmVudC5zaW11bGF0ZSggXCJjaGFuZ2VcIiwgdGhpcywgZXZlbnQsIHRydWUgKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gZmFsc2U7XG5cdFx0XHR9XG5cdFx0XHQvLyBEZWxlZ2F0ZWQgZXZlbnQ7IGxhenktYWRkIGEgY2hhbmdlIGhhbmRsZXIgb24gZGVzY2VuZGFudCBpbnB1dHNcblx0XHRcdGpRdWVyeS5ldmVudC5hZGQoIHRoaXMsIFwiYmVmb3JlYWN0aXZhdGUuX2NoYW5nZVwiLCBmdW5jdGlvbiggZSApIHtcblx0XHRcdFx0dmFyIGVsZW0gPSBlLnRhcmdldDtcblxuXHRcdFx0XHRpZiAoIHJmb3JtRWxlbXMudGVzdCggZWxlbS5ub2RlTmFtZSApICYmICFqUXVlcnkuX2RhdGEoIGVsZW0sIFwiY2hhbmdlQnViYmxlc1wiICkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LmFkZCggZWxlbSwgXCJjaGFuZ2UuX2NoYW5nZVwiLCBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdFx0XHRpZiAoIHRoaXMucGFyZW50Tm9kZSAmJiAhZXZlbnQuaXNTaW11bGF0ZWQgJiYgIWV2ZW50LmlzVHJpZ2dlciApIHtcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnNpbXVsYXRlKCBcImNoYW5nZVwiLCB0aGlzLnBhcmVudE5vZGUsIGV2ZW50LCB0cnVlICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0alF1ZXJ5Ll9kYXRhKCBlbGVtLCBcImNoYW5nZUJ1YmJsZXNcIiwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9LFxuXG5cdFx0aGFuZGxlOiBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHR2YXIgZWxlbSA9IGV2ZW50LnRhcmdldDtcblxuXHRcdFx0Ly8gU3dhbGxvdyBuYXRpdmUgY2hhbmdlIGV2ZW50cyBmcm9tIGNoZWNrYm94L3JhZGlvLCB3ZSBhbHJlYWR5IHRyaWdnZXJlZCB0aGVtIGFib3ZlXG5cdFx0XHRpZiAoIHRoaXMgIT09IGVsZW0gfHwgZXZlbnQuaXNTaW11bGF0ZWQgfHwgZXZlbnQuaXNUcmlnZ2VyIHx8IChlbGVtLnR5cGUgIT09IFwicmFkaW9cIiAmJiBlbGVtLnR5cGUgIT09IFwiY2hlY2tib3hcIikgKSB7XG5cdFx0XHRcdHJldHVybiBldmVudC5oYW5kbGVPYmouaGFuZGxlci5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHR9XG5cdFx0fSxcblxuXHRcdHRlYXJkb3duOiBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5ldmVudC5yZW1vdmUoIHRoaXMsIFwiLl9jaGFuZ2VcIiApO1xuXG5cdFx0XHRyZXR1cm4gIXJmb3JtRWxlbXMudGVzdCggdGhpcy5ub2RlTmFtZSApO1xuXHRcdH1cblx0fTtcbn1cblxuLy8gQ3JlYXRlIFwiYnViYmxpbmdcIiBmb2N1cyBhbmQgYmx1ciBldmVudHNcbmlmICggIXN1cHBvcnQuZm9jdXNpbkJ1YmJsZXMgKSB7XG5cdGpRdWVyeS5lYWNoKHsgZm9jdXM6IFwiZm9jdXNpblwiLCBibHVyOiBcImZvY3Vzb3V0XCIgfSwgZnVuY3Rpb24oIG9yaWcsIGZpeCApIHtcblxuXHRcdC8vIEF0dGFjaCBhIHNpbmdsZSBjYXB0dXJpbmcgaGFuZGxlciBvbiB0aGUgZG9jdW1lbnQgd2hpbGUgc29tZW9uZSB3YW50cyBmb2N1c2luL2ZvY3Vzb3V0XG5cdFx0dmFyIGhhbmRsZXIgPSBmdW5jdGlvbiggZXZlbnQgKSB7XG5cdFx0XHRcdGpRdWVyeS5ldmVudC5zaW11bGF0ZSggZml4LCBldmVudC50YXJnZXQsIGpRdWVyeS5ldmVudC5maXgoIGV2ZW50ICksIHRydWUgKTtcblx0XHRcdH07XG5cblx0XHRqUXVlcnkuZXZlbnQuc3BlY2lhbFsgZml4IF0gPSB7XG5cdFx0XHRzZXR1cDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciBkb2MgPSB0aGlzLm93bmVyRG9jdW1lbnQgfHwgdGhpcyxcblx0XHRcdFx0XHRhdHRhY2hlcyA9IGpRdWVyeS5fZGF0YSggZG9jLCBmaXggKTtcblxuXHRcdFx0XHRpZiAoICFhdHRhY2hlcyApIHtcblx0XHRcdFx0XHRkb2MuYWRkRXZlbnRMaXN0ZW5lciggb3JpZywgaGFuZGxlciwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGpRdWVyeS5fZGF0YSggZG9jLCBmaXgsICggYXR0YWNoZXMgfHwgMCApICsgMSApO1xuXHRcdFx0fSxcblx0XHRcdHRlYXJkb3duOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGRvYyA9IHRoaXMub3duZXJEb2N1bWVudCB8fCB0aGlzLFxuXHRcdFx0XHRcdGF0dGFjaGVzID0galF1ZXJ5Ll9kYXRhKCBkb2MsIGZpeCApIC0gMTtcblxuXHRcdFx0XHRpZiAoICFhdHRhY2hlcyApIHtcblx0XHRcdFx0XHRkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lciggb3JpZywgaGFuZGxlciwgdHJ1ZSApO1xuXHRcdFx0XHRcdGpRdWVyeS5fcmVtb3ZlRGF0YSggZG9jLCBmaXggKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRqUXVlcnkuX2RhdGEoIGRvYywgZml4LCBhdHRhY2hlcyApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fSk7XG59XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXG5cdG9uOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiwgLypJTlRFUk5BTCovIG9uZSApIHtcblx0XHR2YXIgdHlwZSwgb3JpZ0ZuO1xuXG5cdFx0Ly8gVHlwZXMgY2FuIGJlIGEgbWFwIG9mIHR5cGVzL2hhbmRsZXJzXG5cdFx0aWYgKCB0eXBlb2YgdHlwZXMgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHQvLyAoIHR5cGVzLU9iamVjdCwgc2VsZWN0b3IsIGRhdGEgKVxuXHRcdFx0aWYgKCB0eXBlb2Ygc2VsZWN0b3IgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0XHRcdC8vICggdHlwZXMtT2JqZWN0LCBkYXRhIClcblx0XHRcdFx0ZGF0YSA9IGRhdGEgfHwgc2VsZWN0b3I7XG5cdFx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdFx0Zm9yICggdHlwZSBpbiB0eXBlcyApIHtcblx0XHRcdFx0dGhpcy5vbiggdHlwZSwgc2VsZWN0b3IsIGRhdGEsIHR5cGVzWyB0eXBlIF0sIG9uZSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXG5cdFx0aWYgKCBkYXRhID09IG51bGwgJiYgZm4gPT0gbnVsbCApIHtcblx0XHRcdC8vICggdHlwZXMsIGZuIClcblx0XHRcdGZuID0gc2VsZWN0b3I7XG5cdFx0XHRkYXRhID0gc2VsZWN0b3IgPSB1bmRlZmluZWQ7XG5cdFx0fSBlbHNlIGlmICggZm4gPT0gbnVsbCApIHtcblx0XHRcdGlmICggdHlwZW9mIHNlbGVjdG9yID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0XHQvLyAoIHR5cGVzLCBzZWxlY3RvciwgZm4gKVxuXHRcdFx0XHRmbiA9IGRhdGE7XG5cdFx0XHRcdGRhdGEgPSB1bmRlZmluZWQ7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyAoIHR5cGVzLCBkYXRhLCBmbiApXG5cdFx0XHRcdGZuID0gZGF0YTtcblx0XHRcdFx0ZGF0YSA9IHNlbGVjdG9yO1xuXHRcdFx0XHRzZWxlY3RvciA9IHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKCBmbiA9PT0gZmFsc2UgKSB7XG5cdFx0XHRmbiA9IHJldHVybkZhbHNlO1xuXHRcdH0gZWxzZSBpZiAoICFmbiApIHtcblx0XHRcdHJldHVybiB0aGlzO1xuXHRcdH1cblxuXHRcdGlmICggb25lID09PSAxICkge1xuXHRcdFx0b3JpZ0ZuID0gZm47XG5cdFx0XHRmbiA9IGZ1bmN0aW9uKCBldmVudCApIHtcblx0XHRcdFx0Ly8gQ2FuIHVzZSBhbiBlbXB0eSBzZXQsIHNpbmNlIGV2ZW50IGNvbnRhaW5zIHRoZSBpbmZvXG5cdFx0XHRcdGpRdWVyeSgpLm9mZiggZXZlbnQgKTtcblx0XHRcdFx0cmV0dXJuIG9yaWdGbi5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0XHR9O1xuXHRcdFx0Ly8gVXNlIHNhbWUgZ3VpZCBzbyBjYWxsZXIgY2FuIHJlbW92ZSB1c2luZyBvcmlnRm5cblx0XHRcdGZuLmd1aWQgPSBvcmlnRm4uZ3VpZCB8fCAoIG9yaWdGbi5ndWlkID0galF1ZXJ5Lmd1aWQrKyApO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5lYWNoKCBmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5ldmVudC5hZGQoIHRoaXMsIHR5cGVzLCBmbiwgZGF0YSwgc2VsZWN0b3IgKTtcblx0XHR9KTtcblx0fSxcblx0b25lOiBmdW5jdGlvbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiwgMSApO1xuXHR9LFxuXHRvZmY6IGZ1bmN0aW9uKCB0eXBlcywgc2VsZWN0b3IsIGZuICkge1xuXHRcdHZhciBoYW5kbGVPYmosIHR5cGU7XG5cdFx0aWYgKCB0eXBlcyAmJiB0eXBlcy5wcmV2ZW50RGVmYXVsdCAmJiB0eXBlcy5oYW5kbGVPYmogKSB7XG5cdFx0XHQvLyAoIGV2ZW50ICkgIGRpc3BhdGNoZWQgalF1ZXJ5LkV2ZW50XG5cdFx0XHRoYW5kbGVPYmogPSB0eXBlcy5oYW5kbGVPYmo7XG5cdFx0XHRqUXVlcnkoIHR5cGVzLmRlbGVnYXRlVGFyZ2V0ICkub2ZmKFxuXHRcdFx0XHRoYW5kbGVPYmoubmFtZXNwYWNlID8gaGFuZGxlT2JqLm9yaWdUeXBlICsgXCIuXCIgKyBoYW5kbGVPYmoubmFtZXNwYWNlIDogaGFuZGxlT2JqLm9yaWdUeXBlLFxuXHRcdFx0XHRoYW5kbGVPYmouc2VsZWN0b3IsXG5cdFx0XHRcdGhhbmRsZU9iai5oYW5kbGVyXG5cdFx0XHQpO1xuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXHRcdGlmICggdHlwZW9mIHR5cGVzID09PSBcIm9iamVjdFwiICkge1xuXHRcdFx0Ly8gKCB0eXBlcy1vYmplY3QgWywgc2VsZWN0b3JdIClcblx0XHRcdGZvciAoIHR5cGUgaW4gdHlwZXMgKSB7XG5cdFx0XHRcdHRoaXMub2ZmKCB0eXBlLCBzZWxlY3RvciwgdHlwZXNbIHR5cGUgXSApO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0fVxuXHRcdGlmICggc2VsZWN0b3IgPT09IGZhbHNlIHx8IHR5cGVvZiBzZWxlY3RvciA9PT0gXCJmdW5jdGlvblwiICkge1xuXHRcdFx0Ly8gKCB0eXBlcyBbLCBmbl0gKVxuXHRcdFx0Zm4gPSBzZWxlY3Rvcjtcblx0XHRcdHNlbGVjdG9yID0gdW5kZWZpbmVkO1xuXHRcdH1cblx0XHRpZiAoIGZuID09PSBmYWxzZSApIHtcblx0XHRcdGZuID0gcmV0dXJuRmFsc2U7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkuZXZlbnQucmVtb3ZlKCB0aGlzLCB0eXBlcywgZm4sIHNlbGVjdG9yICk7XG5cdFx0fSk7XG5cdH0sXG5cblx0dHJpZ2dlcjogZnVuY3Rpb24oIHR5cGUsIGRhdGEgKSB7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKCB0eXBlLCBkYXRhLCB0aGlzICk7XG5cdFx0fSk7XG5cdH0sXG5cdHRyaWdnZXJIYW5kbGVyOiBmdW5jdGlvbiggdHlwZSwgZGF0YSApIHtcblx0XHR2YXIgZWxlbSA9IHRoaXNbMF07XG5cdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5ldmVudC50cmlnZ2VyKCB0eXBlLCBkYXRhLCBlbGVtLCB0cnVlICk7XG5cdFx0fVxuXHR9XG59KTtcblxuXG5mdW5jdGlvbiBjcmVhdGVTYWZlRnJhZ21lbnQoIGRvY3VtZW50ICkge1xuXHR2YXIgbGlzdCA9IG5vZGVOYW1lcy5zcGxpdCggXCJ8XCIgKSxcblx0XHRzYWZlRnJhZyA9IGRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKTtcblxuXHRpZiAoIHNhZmVGcmFnLmNyZWF0ZUVsZW1lbnQgKSB7XG5cdFx0d2hpbGUgKCBsaXN0Lmxlbmd0aCApIHtcblx0XHRcdHNhZmVGcmFnLmNyZWF0ZUVsZW1lbnQoXG5cdFx0XHRcdGxpc3QucG9wKClcblx0XHRcdCk7XG5cdFx0fVxuXHR9XG5cdHJldHVybiBzYWZlRnJhZztcbn1cblxudmFyIG5vZGVOYW1lcyA9IFwiYWJicnxhcnRpY2xlfGFzaWRlfGF1ZGlvfGJkaXxjYW52YXN8ZGF0YXxkYXRhbGlzdHxkZXRhaWxzfGZpZ2NhcHRpb258ZmlndXJlfGZvb3RlcnxcIiArXG5cdFx0XCJoZWFkZXJ8aGdyb3VwfG1hcmt8bWV0ZXJ8bmF2fG91dHB1dHxwcm9ncmVzc3xzZWN0aW9ufHN1bW1hcnl8dGltZXx2aWRlb1wiLFxuXHRyaW5saW5lalF1ZXJ5ID0gLyBqUXVlcnlcXGQrPVwiKD86bnVsbHxcXGQrKVwiL2csXG5cdHJub3NoaW1jYWNoZSA9IG5ldyBSZWdFeHAoXCI8KD86XCIgKyBub2RlTmFtZXMgKyBcIilbXFxcXHMvPl1cIiwgXCJpXCIpLFxuXHRybGVhZGluZ1doaXRlc3BhY2UgPSAvXlxccysvLFxuXHRyeGh0bWxUYWcgPSAvPCg/IWFyZWF8YnJ8Y29sfGVtYmVkfGhyfGltZ3xpbnB1dHxsaW5rfG1ldGF8cGFyYW0pKChbXFx3Ol0rKVtePl0qKVxcLz4vZ2ksXG5cdHJ0YWdOYW1lID0gLzwoW1xcdzpdKykvLFxuXHRydGJvZHkgPSAvPHRib2R5L2ksXG5cdHJodG1sID0gLzx8JiM/XFx3KzsvLFxuXHRybm9Jbm5lcmh0bWwgPSAvPCg/OnNjcmlwdHxzdHlsZXxsaW5rKS9pLFxuXHQvLyBjaGVja2VkPVwiY2hlY2tlZFwiIG9yIGNoZWNrZWRcblx0cmNoZWNrZWQgPSAvY2hlY2tlZFxccyooPzpbXj1dfD1cXHMqLmNoZWNrZWQuKS9pLFxuXHRyc2NyaXB0VHlwZSA9IC9eJHxcXC8oPzpqYXZhfGVjbWEpc2NyaXB0L2ksXG5cdHJzY3JpcHRUeXBlTWFza2VkID0gL150cnVlXFwvKC4qKS8sXG5cdHJjbGVhblNjcmlwdCA9IC9eXFxzKjwhKD86XFxbQ0RBVEFcXFt8LS0pfCg/OlxcXVxcXXwtLSk+XFxzKiQvZyxcblxuXHQvLyBXZSBoYXZlIHRvIGNsb3NlIHRoZXNlIHRhZ3MgdG8gc3VwcG9ydCBYSFRNTCAoIzEzMjAwKVxuXHR3cmFwTWFwID0ge1xuXHRcdG9wdGlvbjogWyAxLCBcIjxzZWxlY3QgbXVsdGlwbGU9J211bHRpcGxlJz5cIiwgXCI8L3NlbGVjdD5cIiBdLFxuXHRcdGxlZ2VuZDogWyAxLCBcIjxmaWVsZHNldD5cIiwgXCI8L2ZpZWxkc2V0PlwiIF0sXG5cdFx0YXJlYTogWyAxLCBcIjxtYXA+XCIsIFwiPC9tYXA+XCIgXSxcblx0XHRwYXJhbTogWyAxLCBcIjxvYmplY3Q+XCIsIFwiPC9vYmplY3Q+XCIgXSxcblx0XHR0aGVhZDogWyAxLCBcIjx0YWJsZT5cIiwgXCI8L3RhYmxlPlwiIF0sXG5cdFx0dHI6IFsgMiwgXCI8dGFibGU+PHRib2R5PlwiLCBcIjwvdGJvZHk+PC90YWJsZT5cIiBdLFxuXHRcdGNvbDogWyAyLCBcIjx0YWJsZT48dGJvZHk+PC90Ym9keT48Y29sZ3JvdXA+XCIsIFwiPC9jb2xncm91cD48L3RhYmxlPlwiIF0sXG5cdFx0dGQ6IFsgMywgXCI8dGFibGU+PHRib2R5Pjx0cj5cIiwgXCI8L3RyPjwvdGJvZHk+PC90YWJsZT5cIiBdLFxuXG5cdFx0Ly8gSUU2LTggY2FuJ3Qgc2VyaWFsaXplIGxpbmssIHNjcmlwdCwgc3R5bGUsIG9yIGFueSBodG1sNSAoTm9TY29wZSkgdGFncyxcblx0XHQvLyB1bmxlc3Mgd3JhcHBlZCBpbiBhIGRpdiB3aXRoIG5vbi1icmVha2luZyBjaGFyYWN0ZXJzIGluIGZyb250IG9mIGl0LlxuXHRcdF9kZWZhdWx0OiBzdXBwb3J0Lmh0bWxTZXJpYWxpemUgPyBbIDAsIFwiXCIsIFwiXCIgXSA6IFsgMSwgXCJYPGRpdj5cIiwgXCI8L2Rpdj5cIiAgXVxuXHR9LFxuXHRzYWZlRnJhZ21lbnQgPSBjcmVhdGVTYWZlRnJhZ21lbnQoIGRvY3VtZW50ICksXG5cdGZyYWdtZW50RGl2ID0gc2FmZUZyYWdtZW50LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpICk7XG5cbndyYXBNYXAub3B0Z3JvdXAgPSB3cmFwTWFwLm9wdGlvbjtcbndyYXBNYXAudGJvZHkgPSB3cmFwTWFwLnRmb290ID0gd3JhcE1hcC5jb2xncm91cCA9IHdyYXBNYXAuY2FwdGlvbiA9IHdyYXBNYXAudGhlYWQ7XG53cmFwTWFwLnRoID0gd3JhcE1hcC50ZDtcblxuZnVuY3Rpb24gZ2V0QWxsKCBjb250ZXh0LCB0YWcgKSB7XG5cdHZhciBlbGVtcywgZWxlbSxcblx0XHRpID0gMCxcblx0XHRmb3VuZCA9IHR5cGVvZiBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lICE9PSBzdHJ1bmRlZmluZWQgPyBjb250ZXh0LmdldEVsZW1lbnRzQnlUYWdOYW1lKCB0YWcgfHwgXCIqXCIgKSA6XG5cdFx0XHR0eXBlb2YgY29udGV4dC5xdWVyeVNlbGVjdG9yQWxsICE9PSBzdHJ1bmRlZmluZWQgPyBjb250ZXh0LnF1ZXJ5U2VsZWN0b3JBbGwoIHRhZyB8fCBcIipcIiApIDpcblx0XHRcdHVuZGVmaW5lZDtcblxuXHRpZiAoICFmb3VuZCApIHtcblx0XHRmb3IgKCBmb3VuZCA9IFtdLCBlbGVtcyA9IGNvbnRleHQuY2hpbGROb2RlcyB8fCBjb250ZXh0OyAoZWxlbSA9IGVsZW1zW2ldKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRpZiAoICF0YWcgfHwgalF1ZXJ5Lm5vZGVOYW1lKCBlbGVtLCB0YWcgKSApIHtcblx0XHRcdFx0Zm91bmQucHVzaCggZWxlbSApO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBmb3VuZCwgZ2V0QWxsKCBlbGVtLCB0YWcgKSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB0YWcgPT09IHVuZGVmaW5lZCB8fCB0YWcgJiYgalF1ZXJ5Lm5vZGVOYW1lKCBjb250ZXh0LCB0YWcgKSA/XG5cdFx0alF1ZXJ5Lm1lcmdlKCBbIGNvbnRleHQgXSwgZm91bmQgKSA6XG5cdFx0Zm91bmQ7XG59XG5cbi8vIFVzZWQgaW4gYnVpbGRGcmFnbWVudCwgZml4ZXMgdGhlIGRlZmF1bHRDaGVja2VkIHByb3BlcnR5XG5mdW5jdGlvbiBmaXhEZWZhdWx0Q2hlY2tlZCggZWxlbSApIHtcblx0aWYgKCByY2hlY2thYmxlVHlwZS50ZXN0KCBlbGVtLnR5cGUgKSApIHtcblx0XHRlbGVtLmRlZmF1bHRDaGVja2VkID0gZWxlbS5jaGVja2VkO1xuXHR9XG59XG5cbi8vIFN1cHBvcnQ6IElFPDhcbi8vIE1hbmlwdWxhdGluZyB0YWJsZXMgcmVxdWlyZXMgYSB0Ym9keVxuZnVuY3Rpb24gbWFuaXB1bGF0aW9uVGFyZ2V0KCBlbGVtLCBjb250ZW50ICkge1xuXHRyZXR1cm4galF1ZXJ5Lm5vZGVOYW1lKCBlbGVtLCBcInRhYmxlXCIgKSAmJlxuXHRcdGpRdWVyeS5ub2RlTmFtZSggY29udGVudC5ub2RlVHlwZSAhPT0gMTEgPyBjb250ZW50IDogY29udGVudC5maXJzdENoaWxkLCBcInRyXCIgKSA/XG5cblx0XHRlbGVtLmdldEVsZW1lbnRzQnlUYWdOYW1lKFwidGJvZHlcIilbMF0gfHxcblx0XHRcdGVsZW0uYXBwZW5kQ2hpbGQoIGVsZW0ub3duZXJEb2N1bWVudC5jcmVhdGVFbGVtZW50KFwidGJvZHlcIikgKSA6XG5cdFx0ZWxlbTtcbn1cblxuLy8gUmVwbGFjZS9yZXN0b3JlIHRoZSB0eXBlIGF0dHJpYnV0ZSBvZiBzY3JpcHQgZWxlbWVudHMgZm9yIHNhZmUgRE9NIG1hbmlwdWxhdGlvblxuZnVuY3Rpb24gZGlzYWJsZVNjcmlwdCggZWxlbSApIHtcblx0ZWxlbS50eXBlID0gKGpRdWVyeS5maW5kLmF0dHIoIGVsZW0sIFwidHlwZVwiICkgIT09IG51bGwpICsgXCIvXCIgKyBlbGVtLnR5cGU7XG5cdHJldHVybiBlbGVtO1xufVxuZnVuY3Rpb24gcmVzdG9yZVNjcmlwdCggZWxlbSApIHtcblx0dmFyIG1hdGNoID0gcnNjcmlwdFR5cGVNYXNrZWQuZXhlYyggZWxlbS50eXBlICk7XG5cdGlmICggbWF0Y2ggKSB7XG5cdFx0ZWxlbS50eXBlID0gbWF0Y2hbMV07XG5cdH0gZWxzZSB7XG5cdFx0ZWxlbS5yZW1vdmVBdHRyaWJ1dGUoXCJ0eXBlXCIpO1xuXHR9XG5cdHJldHVybiBlbGVtO1xufVxuXG4vLyBNYXJrIHNjcmlwdHMgYXMgaGF2aW5nIGFscmVhZHkgYmVlbiBldmFsdWF0ZWRcbmZ1bmN0aW9uIHNldEdsb2JhbEV2YWwoIGVsZW1zLCByZWZFbGVtZW50cyApIHtcblx0dmFyIGVsZW0sXG5cdFx0aSA9IDA7XG5cdGZvciAoIDsgKGVsZW0gPSBlbGVtc1tpXSkgIT0gbnVsbDsgaSsrICkge1xuXHRcdGpRdWVyeS5fZGF0YSggZWxlbSwgXCJnbG9iYWxFdmFsXCIsICFyZWZFbGVtZW50cyB8fCBqUXVlcnkuX2RhdGEoIHJlZkVsZW1lbnRzW2ldLCBcImdsb2JhbEV2YWxcIiApICk7XG5cdH1cbn1cblxuZnVuY3Rpb24gY2xvbmVDb3B5RXZlbnQoIHNyYywgZGVzdCApIHtcblxuXHRpZiAoIGRlc3Qubm9kZVR5cGUgIT09IDEgfHwgIWpRdWVyeS5oYXNEYXRhKCBzcmMgKSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHR2YXIgdHlwZSwgaSwgbCxcblx0XHRvbGREYXRhID0galF1ZXJ5Ll9kYXRhKCBzcmMgKSxcblx0XHRjdXJEYXRhID0galF1ZXJ5Ll9kYXRhKCBkZXN0LCBvbGREYXRhICksXG5cdFx0ZXZlbnRzID0gb2xkRGF0YS5ldmVudHM7XG5cblx0aWYgKCBldmVudHMgKSB7XG5cdFx0ZGVsZXRlIGN1ckRhdGEuaGFuZGxlO1xuXHRcdGN1ckRhdGEuZXZlbnRzID0ge307XG5cblx0XHRmb3IgKCB0eXBlIGluIGV2ZW50cyApIHtcblx0XHRcdGZvciAoIGkgPSAwLCBsID0gZXZlbnRzWyB0eXBlIF0ubGVuZ3RoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRqUXVlcnkuZXZlbnQuYWRkKCBkZXN0LCB0eXBlLCBldmVudHNbIHR5cGUgXVsgaSBdICk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gbWFrZSB0aGUgY2xvbmVkIHB1YmxpYyBkYXRhIG9iamVjdCBhIGNvcHkgZnJvbSB0aGUgb3JpZ2luYWxcblx0aWYgKCBjdXJEYXRhLmRhdGEgKSB7XG5cdFx0Y3VyRGF0YS5kYXRhID0galF1ZXJ5LmV4dGVuZCgge30sIGN1ckRhdGEuZGF0YSApO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGZpeENsb25lTm9kZUlzc3Vlcyggc3JjLCBkZXN0ICkge1xuXHR2YXIgbm9kZU5hbWUsIGUsIGRhdGE7XG5cblx0Ly8gV2UgZG8gbm90IG5lZWQgdG8gZG8gYW55dGhpbmcgZm9yIG5vbi1FbGVtZW50c1xuXHRpZiAoIGRlc3Qubm9kZVR5cGUgIT09IDEgKSB7XG5cdFx0cmV0dXJuO1xuXHR9XG5cblx0bm9kZU5hbWUgPSBkZXN0Lm5vZGVOYW1lLnRvTG93ZXJDYXNlKCk7XG5cblx0Ly8gSUU2LTggY29waWVzIGV2ZW50cyBib3VuZCB2aWEgYXR0YWNoRXZlbnQgd2hlbiB1c2luZyBjbG9uZU5vZGUuXG5cdGlmICggIXN1cHBvcnQubm9DbG9uZUV2ZW50ICYmIGRlc3RbIGpRdWVyeS5leHBhbmRvIF0gKSB7XG5cdFx0ZGF0YSA9IGpRdWVyeS5fZGF0YSggZGVzdCApO1xuXG5cdFx0Zm9yICggZSBpbiBkYXRhLmV2ZW50cyApIHtcblx0XHRcdGpRdWVyeS5yZW1vdmVFdmVudCggZGVzdCwgZSwgZGF0YS5oYW5kbGUgKTtcblx0XHR9XG5cblx0XHQvLyBFdmVudCBkYXRhIGdldHMgcmVmZXJlbmNlZCBpbnN0ZWFkIG9mIGNvcGllZCBpZiB0aGUgZXhwYW5kbyBnZXRzIGNvcGllZCB0b29cblx0XHRkZXN0LnJlbW92ZUF0dHJpYnV0ZSggalF1ZXJ5LmV4cGFuZG8gKTtcblx0fVxuXG5cdC8vIElFIGJsYW5rcyBjb250ZW50cyB3aGVuIGNsb25pbmcgc2NyaXB0cywgYW5kIHRyaWVzIHRvIGV2YWx1YXRlIG5ld2x5LXNldCB0ZXh0XG5cdGlmICggbm9kZU5hbWUgPT09IFwic2NyaXB0XCIgJiYgZGVzdC50ZXh0ICE9PSBzcmMudGV4dCApIHtcblx0XHRkaXNhYmxlU2NyaXB0KCBkZXN0ICkudGV4dCA9IHNyYy50ZXh0O1xuXHRcdHJlc3RvcmVTY3JpcHQoIGRlc3QgKTtcblxuXHQvLyBJRTYtMTAgaW1wcm9wZXJseSBjbG9uZXMgY2hpbGRyZW4gb2Ygb2JqZWN0IGVsZW1lbnRzIHVzaW5nIGNsYXNzaWQuXG5cdC8vIElFMTAgdGhyb3dzIE5vTW9kaWZpY2F0aW9uQWxsb3dlZEVycm9yIGlmIHBhcmVudCBpcyBudWxsLCAjMTIxMzIuXG5cdH0gZWxzZSBpZiAoIG5vZGVOYW1lID09PSBcIm9iamVjdFwiICkge1xuXHRcdGlmICggZGVzdC5wYXJlbnROb2RlICkge1xuXHRcdFx0ZGVzdC5vdXRlckhUTUwgPSBzcmMub3V0ZXJIVE1MO1xuXHRcdH1cblxuXHRcdC8vIFRoaXMgcGF0aCBhcHBlYXJzIHVuYXZvaWRhYmxlIGZvciBJRTkuIFdoZW4gY2xvbmluZyBhbiBvYmplY3Rcblx0XHQvLyBlbGVtZW50IGluIElFOSwgdGhlIG91dGVySFRNTCBzdHJhdGVneSBhYm92ZSBpcyBub3Qgc3VmZmljaWVudC5cblx0XHQvLyBJZiB0aGUgc3JjIGhhcyBpbm5lckhUTUwgYW5kIHRoZSBkZXN0aW5hdGlvbiBkb2VzIG5vdCxcblx0XHQvLyBjb3B5IHRoZSBzcmMuaW5uZXJIVE1MIGludG8gdGhlIGRlc3QuaW5uZXJIVE1MLiAjMTAzMjRcblx0XHRpZiAoIHN1cHBvcnQuaHRtbDVDbG9uZSAmJiAoIHNyYy5pbm5lckhUTUwgJiYgIWpRdWVyeS50cmltKGRlc3QuaW5uZXJIVE1MKSApICkge1xuXHRcdFx0ZGVzdC5pbm5lckhUTUwgPSBzcmMuaW5uZXJIVE1MO1xuXHRcdH1cblxuXHR9IGVsc2UgaWYgKCBub2RlTmFtZSA9PT0gXCJpbnB1dFwiICYmIHJjaGVja2FibGVUeXBlLnRlc3QoIHNyYy50eXBlICkgKSB7XG5cdFx0Ly8gSUU2LTggZmFpbHMgdG8gcGVyc2lzdCB0aGUgY2hlY2tlZCBzdGF0ZSBvZiBhIGNsb25lZCBjaGVja2JveFxuXHRcdC8vIG9yIHJhZGlvIGJ1dHRvbi4gV29yc2UsIElFNi03IGZhaWwgdG8gZ2l2ZSB0aGUgY2xvbmVkIGVsZW1lbnRcblx0XHQvLyBhIGNoZWNrZWQgYXBwZWFyYW5jZSBpZiB0aGUgZGVmYXVsdENoZWNrZWQgdmFsdWUgaXNuJ3QgYWxzbyBzZXRcblxuXHRcdGRlc3QuZGVmYXVsdENoZWNrZWQgPSBkZXN0LmNoZWNrZWQgPSBzcmMuY2hlY2tlZDtcblxuXHRcdC8vIElFNi03IGdldCBjb25mdXNlZCBhbmQgZW5kIHVwIHNldHRpbmcgdGhlIHZhbHVlIG9mIGEgY2xvbmVkXG5cdFx0Ly8gY2hlY2tib3gvcmFkaW8gYnV0dG9uIHRvIGFuIGVtcHR5IHN0cmluZyBpbnN0ZWFkIG9mIFwib25cIlxuXHRcdGlmICggZGVzdC52YWx1ZSAhPT0gc3JjLnZhbHVlICkge1xuXHRcdFx0ZGVzdC52YWx1ZSA9IHNyYy52YWx1ZTtcblx0XHR9XG5cblx0Ly8gSUU2LTggZmFpbHMgdG8gcmV0dXJuIHRoZSBzZWxlY3RlZCBvcHRpb24gdG8gdGhlIGRlZmF1bHQgc2VsZWN0ZWRcblx0Ly8gc3RhdGUgd2hlbiBjbG9uaW5nIG9wdGlvbnNcblx0fSBlbHNlIGlmICggbm9kZU5hbWUgPT09IFwib3B0aW9uXCIgKSB7XG5cdFx0ZGVzdC5kZWZhdWx0U2VsZWN0ZWQgPSBkZXN0LnNlbGVjdGVkID0gc3JjLmRlZmF1bHRTZWxlY3RlZDtcblxuXHQvLyBJRTYtOCBmYWlscyB0byBzZXQgdGhlIGRlZmF1bHRWYWx1ZSB0byB0aGUgY29ycmVjdCB2YWx1ZSB3aGVuXG5cdC8vIGNsb25pbmcgb3RoZXIgdHlwZXMgb2YgaW5wdXQgZmllbGRzXG5cdH0gZWxzZSBpZiAoIG5vZGVOYW1lID09PSBcImlucHV0XCIgfHwgbm9kZU5hbWUgPT09IFwidGV4dGFyZWFcIiApIHtcblx0XHRkZXN0LmRlZmF1bHRWYWx1ZSA9IHNyYy5kZWZhdWx0VmFsdWU7XG5cdH1cbn1cblxualF1ZXJ5LmV4dGVuZCh7XG5cdGNsb25lOiBmdW5jdGlvbiggZWxlbSwgZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKSB7XG5cdFx0dmFyIGRlc3RFbGVtZW50cywgbm9kZSwgY2xvbmUsIGksIHNyY0VsZW1lbnRzLFxuXHRcdFx0aW5QYWdlID0galF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKTtcblxuXHRcdGlmICggc3VwcG9ydC5odG1sNUNsb25lIHx8IGpRdWVyeS5pc1hNTERvYyhlbGVtKSB8fCAhcm5vc2hpbWNhY2hlLnRlc3QoIFwiPFwiICsgZWxlbS5ub2RlTmFtZSArIFwiPlwiICkgKSB7XG5cdFx0XHRjbG9uZSA9IGVsZW0uY2xvbmVOb2RlKCB0cnVlICk7XG5cblx0XHQvLyBJRTw9OCBkb2VzIG5vdCBwcm9wZXJseSBjbG9uZSBkZXRhY2hlZCwgdW5rbm93biBlbGVtZW50IG5vZGVzXG5cdFx0fSBlbHNlIHtcblx0XHRcdGZyYWdtZW50RGl2LmlubmVySFRNTCA9IGVsZW0ub3V0ZXJIVE1MO1xuXHRcdFx0ZnJhZ21lbnREaXYucmVtb3ZlQ2hpbGQoIGNsb25lID0gZnJhZ21lbnREaXYuZmlyc3RDaGlsZCApO1xuXHRcdH1cblxuXHRcdGlmICggKCFzdXBwb3J0Lm5vQ2xvbmVFdmVudCB8fCAhc3VwcG9ydC5ub0Nsb25lQ2hlY2tlZCkgJiZcblx0XHRcdFx0KGVsZW0ubm9kZVR5cGUgPT09IDEgfHwgZWxlbS5ub2RlVHlwZSA9PT0gMTEpICYmICFqUXVlcnkuaXNYTUxEb2MoZWxlbSkgKSB7XG5cblx0XHRcdC8vIFdlIGVzY2hldyBTaXp6bGUgaGVyZSBmb3IgcGVyZm9ybWFuY2UgcmVhc29uczogaHR0cDovL2pzcGVyZi5jb20vZ2V0YWxsLXZzLXNpenpsZS8yXG5cdFx0XHRkZXN0RWxlbWVudHMgPSBnZXRBbGwoIGNsb25lICk7XG5cdFx0XHRzcmNFbGVtZW50cyA9IGdldEFsbCggZWxlbSApO1xuXG5cdFx0XHQvLyBGaXggYWxsIElFIGNsb25pbmcgaXNzdWVzXG5cdFx0XHRmb3IgKCBpID0gMDsgKG5vZGUgPSBzcmNFbGVtZW50c1tpXSkgIT0gbnVsbDsgKytpICkge1xuXHRcdFx0XHQvLyBFbnN1cmUgdGhhdCB0aGUgZGVzdGluYXRpb24gbm9kZSBpcyBub3QgbnVsbDsgRml4ZXMgIzk1ODdcblx0XHRcdFx0aWYgKCBkZXN0RWxlbWVudHNbaV0gKSB7XG5cdFx0XHRcdFx0Zml4Q2xvbmVOb2RlSXNzdWVzKCBub2RlLCBkZXN0RWxlbWVudHNbaV0gKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIENvcHkgdGhlIGV2ZW50cyBmcm9tIHRoZSBvcmlnaW5hbCB0byB0aGUgY2xvbmVcblx0XHRpZiAoIGRhdGFBbmRFdmVudHMgKSB7XG5cdFx0XHRpZiAoIGRlZXBEYXRhQW5kRXZlbnRzICkge1xuXHRcdFx0XHRzcmNFbGVtZW50cyA9IHNyY0VsZW1lbnRzIHx8IGdldEFsbCggZWxlbSApO1xuXHRcdFx0XHRkZXN0RWxlbWVudHMgPSBkZXN0RWxlbWVudHMgfHwgZ2V0QWxsKCBjbG9uZSApO1xuXG5cdFx0XHRcdGZvciAoIGkgPSAwOyAobm9kZSA9IHNyY0VsZW1lbnRzW2ldKSAhPSBudWxsOyBpKysgKSB7XG5cdFx0XHRcdFx0Y2xvbmVDb3B5RXZlbnQoIG5vZGUsIGRlc3RFbGVtZW50c1tpXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRjbG9uZUNvcHlFdmVudCggZWxlbSwgY2xvbmUgKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XG5cdFx0ZGVzdEVsZW1lbnRzID0gZ2V0QWxsKCBjbG9uZSwgXCJzY3JpcHRcIiApO1xuXHRcdGlmICggZGVzdEVsZW1lbnRzLmxlbmd0aCA+IDAgKSB7XG5cdFx0XHRzZXRHbG9iYWxFdmFsKCBkZXN0RWxlbWVudHMsICFpblBhZ2UgJiYgZ2V0QWxsKCBlbGVtLCBcInNjcmlwdFwiICkgKTtcblx0XHR9XG5cblx0XHRkZXN0RWxlbWVudHMgPSBzcmNFbGVtZW50cyA9IG5vZGUgPSBudWxsO1xuXG5cdFx0Ly8gUmV0dXJuIHRoZSBjbG9uZWQgc2V0XG5cdFx0cmV0dXJuIGNsb25lO1xuXHR9LFxuXG5cdGJ1aWxkRnJhZ21lbnQ6IGZ1bmN0aW9uKCBlbGVtcywgY29udGV4dCwgc2NyaXB0cywgc2VsZWN0aW9uICkge1xuXHRcdHZhciBqLCBlbGVtLCBjb250YWlucyxcblx0XHRcdHRtcCwgdGFnLCB0Ym9keSwgd3JhcCxcblx0XHRcdGwgPSBlbGVtcy5sZW5ndGgsXG5cblx0XHRcdC8vIEVuc3VyZSBhIHNhZmUgZnJhZ21lbnRcblx0XHRcdHNhZmUgPSBjcmVhdGVTYWZlRnJhZ21lbnQoIGNvbnRleHQgKSxcblxuXHRcdFx0bm9kZXMgPSBbXSxcblx0XHRcdGkgPSAwO1xuXG5cdFx0Zm9yICggOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0ZWxlbSA9IGVsZW1zWyBpIF07XG5cblx0XHRcdGlmICggZWxlbSB8fCBlbGVtID09PSAwICkge1xuXG5cdFx0XHRcdC8vIEFkZCBub2RlcyBkaXJlY3RseVxuXHRcdFx0XHRpZiAoIGpRdWVyeS50eXBlKCBlbGVtICkgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5Lm1lcmdlKCBub2RlcywgZWxlbS5ub2RlVHlwZSA/IFsgZWxlbSBdIDogZWxlbSApO1xuXG5cdFx0XHRcdC8vIENvbnZlcnQgbm9uLWh0bWwgaW50byBhIHRleHQgbm9kZVxuXHRcdFx0XHR9IGVsc2UgaWYgKCAhcmh0bWwudGVzdCggZWxlbSApICkge1xuXHRcdFx0XHRcdG5vZGVzLnB1c2goIGNvbnRleHQuY3JlYXRlVGV4dE5vZGUoIGVsZW0gKSApO1xuXG5cdFx0XHRcdC8vIENvbnZlcnQgaHRtbCBpbnRvIERPTSBub2Rlc1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRtcCA9IHRtcCB8fCBzYWZlLmFwcGVuZENoaWxkKCBjb250ZXh0LmNyZWF0ZUVsZW1lbnQoXCJkaXZcIikgKTtcblxuXHRcdFx0XHRcdC8vIERlc2VyaWFsaXplIGEgc3RhbmRhcmQgcmVwcmVzZW50YXRpb25cblx0XHRcdFx0XHR0YWcgPSAocnRhZ05hbWUuZXhlYyggZWxlbSApIHx8IFsgXCJcIiwgXCJcIiBdKVsgMSBdLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0d3JhcCA9IHdyYXBNYXBbIHRhZyBdIHx8IHdyYXBNYXAuX2RlZmF1bHQ7XG5cblx0XHRcdFx0XHR0bXAuaW5uZXJIVE1MID0gd3JhcFsxXSArIGVsZW0ucmVwbGFjZSggcnhodG1sVGFnLCBcIjwkMT48LyQyPlwiICkgKyB3cmFwWzJdO1xuXG5cdFx0XHRcdFx0Ly8gRGVzY2VuZCB0aHJvdWdoIHdyYXBwZXJzIHRvIHRoZSByaWdodCBjb250ZW50XG5cdFx0XHRcdFx0aiA9IHdyYXBbMF07XG5cdFx0XHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdFx0XHR0bXAgPSB0bXAubGFzdENoaWxkO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIE1hbnVhbGx5IGFkZCBsZWFkaW5nIHdoaXRlc3BhY2UgcmVtb3ZlZCBieSBJRVxuXHRcdFx0XHRcdGlmICggIXN1cHBvcnQubGVhZGluZ1doaXRlc3BhY2UgJiYgcmxlYWRpbmdXaGl0ZXNwYWNlLnRlc3QoIGVsZW0gKSApIHtcblx0XHRcdFx0XHRcdG5vZGVzLnB1c2goIGNvbnRleHQuY3JlYXRlVGV4dE5vZGUoIHJsZWFkaW5nV2hpdGVzcGFjZS5leGVjKCBlbGVtIClbMF0gKSApO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFJlbW92ZSBJRSdzIGF1dG9pbnNlcnRlZCA8dGJvZHk+IGZyb20gdGFibGUgZnJhZ21lbnRzXG5cdFx0XHRcdFx0aWYgKCAhc3VwcG9ydC50Ym9keSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gU3RyaW5nIHdhcyBhIDx0YWJsZT4sICptYXkqIGhhdmUgc3B1cmlvdXMgPHRib2R5PlxuXHRcdFx0XHRcdFx0ZWxlbSA9IHRhZyA9PT0gXCJ0YWJsZVwiICYmICFydGJvZHkudGVzdCggZWxlbSApID9cblx0XHRcdFx0XHRcdFx0dG1wLmZpcnN0Q2hpbGQgOlxuXG5cdFx0XHRcdFx0XHRcdC8vIFN0cmluZyB3YXMgYSBiYXJlIDx0aGVhZD4gb3IgPHRmb290PlxuXHRcdFx0XHRcdFx0XHR3cmFwWzFdID09PSBcIjx0YWJsZT5cIiAmJiAhcnRib2R5LnRlc3QoIGVsZW0gKSA/XG5cdFx0XHRcdFx0XHRcdFx0dG1wIDpcblx0XHRcdFx0XHRcdFx0XHQwO1xuXG5cdFx0XHRcdFx0XHRqID0gZWxlbSAmJiBlbGVtLmNoaWxkTm9kZXMubGVuZ3RoO1xuXHRcdFx0XHRcdFx0d2hpbGUgKCBqLS0gKSB7XG5cdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5Lm5vZGVOYW1lKCAodGJvZHkgPSBlbGVtLmNoaWxkTm9kZXNbal0pLCBcInRib2R5XCIgKSAmJiAhdGJvZHkuY2hpbGROb2Rlcy5sZW5ndGggKSB7XG5cdFx0XHRcdFx0XHRcdFx0ZWxlbS5yZW1vdmVDaGlsZCggdGJvZHkgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdGpRdWVyeS5tZXJnZSggbm9kZXMsIHRtcC5jaGlsZE5vZGVzICk7XG5cblx0XHRcdFx0XHQvLyBGaXggIzEyMzkyIGZvciBXZWJLaXQgYW5kIElFID4gOVxuXHRcdFx0XHRcdHRtcC50ZXh0Q29udGVudCA9IFwiXCI7XG5cblx0XHRcdFx0XHQvLyBGaXggIzEyMzkyIGZvciBvbGRJRVxuXHRcdFx0XHRcdHdoaWxlICggdG1wLmZpcnN0Q2hpbGQgKSB7XG5cdFx0XHRcdFx0XHR0bXAucmVtb3ZlQ2hpbGQoIHRtcC5maXJzdENoaWxkICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gUmVtZW1iZXIgdGhlIHRvcC1sZXZlbCBjb250YWluZXIgZm9yIHByb3BlciBjbGVhbnVwXG5cdFx0XHRcdFx0dG1wID0gc2FmZS5sYXN0Q2hpbGQ7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBGaXggIzExMzU2OiBDbGVhciBlbGVtZW50cyBmcm9tIGZyYWdtZW50XG5cdFx0aWYgKCB0bXAgKSB7XG5cdFx0XHRzYWZlLnJlbW92ZUNoaWxkKCB0bXAgKTtcblx0XHR9XG5cblx0XHQvLyBSZXNldCBkZWZhdWx0Q2hlY2tlZCBmb3IgYW55IHJhZGlvcyBhbmQgY2hlY2tib3hlc1xuXHRcdC8vIGFib3V0IHRvIGJlIGFwcGVuZGVkIHRvIHRoZSBET00gaW4gSUUgNi83ICgjODA2MClcblx0XHRpZiAoICFzdXBwb3J0LmFwcGVuZENoZWNrZWQgKSB7XG5cdFx0XHRqUXVlcnkuZ3JlcCggZ2V0QWxsKCBub2RlcywgXCJpbnB1dFwiICksIGZpeERlZmF1bHRDaGVja2VkICk7XG5cdFx0fVxuXG5cdFx0aSA9IDA7XG5cdFx0d2hpbGUgKCAoZWxlbSA9IG5vZGVzWyBpKysgXSkgKSB7XG5cblx0XHRcdC8vICM0MDg3IC0gSWYgb3JpZ2luIGFuZCBkZXN0aW5hdGlvbiBlbGVtZW50cyBhcmUgdGhlIHNhbWUsIGFuZCB0aGlzIGlzXG5cdFx0XHQvLyB0aGF0IGVsZW1lbnQsIGRvIG5vdCBkbyBhbnl0aGluZ1xuXHRcdFx0aWYgKCBzZWxlY3Rpb24gJiYgalF1ZXJ5LmluQXJyYXkoIGVsZW0sIHNlbGVjdGlvbiApICE9PSAtMSApIHtcblx0XHRcdFx0Y29udGludWU7XG5cdFx0XHR9XG5cblx0XHRcdGNvbnRhaW5zID0galF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKTtcblxuXHRcdFx0Ly8gQXBwZW5kIHRvIGZyYWdtZW50XG5cdFx0XHR0bXAgPSBnZXRBbGwoIHNhZmUuYXBwZW5kQ2hpbGQoIGVsZW0gKSwgXCJzY3JpcHRcIiApO1xuXG5cdFx0XHQvLyBQcmVzZXJ2ZSBzY3JpcHQgZXZhbHVhdGlvbiBoaXN0b3J5XG5cdFx0XHRpZiAoIGNvbnRhaW5zICkge1xuXHRcdFx0XHRzZXRHbG9iYWxFdmFsKCB0bXAgKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ2FwdHVyZSBleGVjdXRhYmxlc1xuXHRcdFx0aWYgKCBzY3JpcHRzICkge1xuXHRcdFx0XHRqID0gMDtcblx0XHRcdFx0d2hpbGUgKCAoZWxlbSA9IHRtcFsgaisrIF0pICkge1xuXHRcdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggZWxlbS50eXBlIHx8IFwiXCIgKSApIHtcblx0XHRcdFx0XHRcdHNjcmlwdHMucHVzaCggZWxlbSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRtcCA9IG51bGw7XG5cblx0XHRyZXR1cm4gc2FmZTtcblx0fSxcblxuXHRjbGVhbkRhdGE6IGZ1bmN0aW9uKCBlbGVtcywgLyogaW50ZXJuYWwgKi8gYWNjZXB0RGF0YSApIHtcblx0XHR2YXIgZWxlbSwgdHlwZSwgaWQsIGRhdGEsXG5cdFx0XHRpID0gMCxcblx0XHRcdGludGVybmFsS2V5ID0galF1ZXJ5LmV4cGFuZG8sXG5cdFx0XHRjYWNoZSA9IGpRdWVyeS5jYWNoZSxcblx0XHRcdGRlbGV0ZUV4cGFuZG8gPSBzdXBwb3J0LmRlbGV0ZUV4cGFuZG8sXG5cdFx0XHRzcGVjaWFsID0galF1ZXJ5LmV2ZW50LnNwZWNpYWw7XG5cblx0XHRmb3IgKCA7IChlbGVtID0gZWxlbXNbaV0pICE9IG51bGw7IGkrKyApIHtcblx0XHRcdGlmICggYWNjZXB0RGF0YSB8fCBqUXVlcnkuYWNjZXB0RGF0YSggZWxlbSApICkge1xuXG5cdFx0XHRcdGlkID0gZWxlbVsgaW50ZXJuYWxLZXkgXTtcblx0XHRcdFx0ZGF0YSA9IGlkICYmIGNhY2hlWyBpZCBdO1xuXG5cdFx0XHRcdGlmICggZGF0YSApIHtcblx0XHRcdFx0XHRpZiAoIGRhdGEuZXZlbnRzICkge1xuXHRcdFx0XHRcdFx0Zm9yICggdHlwZSBpbiBkYXRhLmV2ZW50cyApIHtcblx0XHRcdFx0XHRcdFx0aWYgKCBzcGVjaWFsWyB0eXBlIF0gKSB7XG5cdFx0XHRcdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnJlbW92ZSggZWxlbSwgdHlwZSApO1xuXG5cdFx0XHRcdFx0XHRcdC8vIFRoaXMgaXMgYSBzaG9ydGN1dCB0byBhdm9pZCBqUXVlcnkuZXZlbnQucmVtb3ZlJ3Mgb3ZlcmhlYWRcblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkucmVtb3ZlRXZlbnQoIGVsZW0sIHR5cGUsIGRhdGEuaGFuZGxlICk7XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBSZW1vdmUgY2FjaGUgb25seSBpZiBpdCB3YXMgbm90IGFscmVhZHkgcmVtb3ZlZCBieSBqUXVlcnkuZXZlbnQucmVtb3ZlXG5cdFx0XHRcdFx0aWYgKCBjYWNoZVsgaWQgXSApIHtcblxuXHRcdFx0XHRcdFx0ZGVsZXRlIGNhY2hlWyBpZCBdO1xuXG5cdFx0XHRcdFx0XHQvLyBJRSBkb2VzIG5vdCBhbGxvdyB1cyB0byBkZWxldGUgZXhwYW5kbyBwcm9wZXJ0aWVzIGZyb20gbm9kZXMsXG5cdFx0XHRcdFx0XHQvLyBub3IgZG9lcyBpdCBoYXZlIGEgcmVtb3ZlQXR0cmlidXRlIGZ1bmN0aW9uIG9uIERvY3VtZW50IG5vZGVzO1xuXHRcdFx0XHRcdFx0Ly8gd2UgbXVzdCBoYW5kbGUgYWxsIG9mIHRoZXNlIGNhc2VzXG5cdFx0XHRcdFx0XHRpZiAoIGRlbGV0ZUV4cGFuZG8gKSB7XG5cdFx0XHRcdFx0XHRcdGRlbGV0ZSBlbGVtWyBpbnRlcm5hbEtleSBdO1xuXG5cdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCB0eXBlb2YgZWxlbS5yZW1vdmVBdHRyaWJ1dGUgIT09IHN0cnVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdFx0ZWxlbS5yZW1vdmVBdHRyaWJ1dGUoIGludGVybmFsS2V5ICk7XG5cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdGVsZW1bIGludGVybmFsS2V5IF0gPSBudWxsO1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRkZWxldGVkSWRzLnB1c2goIGlkICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59KTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdHRleHQ6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHRyZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdGpRdWVyeS50ZXh0KCB0aGlzICkgOlxuXHRcdFx0XHR0aGlzLmVtcHR5KCkuYXBwZW5kKCAoIHRoaXNbMF0gJiYgdGhpc1swXS5vd25lckRvY3VtZW50IHx8IGRvY3VtZW50ICkuY3JlYXRlVGV4dE5vZGUoIHZhbHVlICkgKTtcblx0XHR9LCBudWxsLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCApO1xuXHR9LFxuXG5cdGFwcGVuZDogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHRoaXMuZG9tTWFuaXAoIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRpZiAoIHRoaXMubm9kZVR5cGUgPT09IDEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gMTEgfHwgdGhpcy5ub2RlVHlwZSA9PT0gOSApIHtcblx0XHRcdFx0dmFyIHRhcmdldCA9IG1hbmlwdWxhdGlvblRhcmdldCggdGhpcywgZWxlbSApO1xuXHRcdFx0XHR0YXJnZXQuYXBwZW5kQ2hpbGQoIGVsZW0gKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRwcmVwZW5kOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5kb21NYW5pcCggYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSA9PT0gMSB8fCB0aGlzLm5vZGVUeXBlID09PSAxMSB8fCB0aGlzLm5vZGVUeXBlID09PSA5ICkge1xuXHRcdFx0XHR2YXIgdGFyZ2V0ID0gbWFuaXB1bGF0aW9uVGFyZ2V0KCB0aGlzLCBlbGVtICk7XG5cdFx0XHRcdHRhcmdldC5pbnNlcnRCZWZvcmUoIGVsZW0sIHRhcmdldC5maXJzdENoaWxkICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0YmVmb3JlOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5kb21NYW5pcCggYXJndW1lbnRzLCBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdGlmICggdGhpcy5wYXJlbnROb2RlICkge1xuXHRcdFx0XHR0aGlzLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKCBlbGVtLCB0aGlzICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH0sXG5cblx0YWZ0ZXI6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLmRvbU1hbmlwKCBhcmd1bWVudHMsIGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0aWYgKCB0aGlzLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdHRoaXMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoIGVsZW0sIHRoaXMubmV4dFNpYmxpbmcgKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRyZW1vdmU6IGZ1bmN0aW9uKCBzZWxlY3Rvciwga2VlcERhdGEgLyogSW50ZXJuYWwgVXNlIE9ubHkgKi8gKSB7XG5cdFx0dmFyIGVsZW0sXG5cdFx0XHRlbGVtcyA9IHNlbGVjdG9yID8galF1ZXJ5LmZpbHRlciggc2VsZWN0b3IsIHRoaXMgKSA6IHRoaXMsXG5cdFx0XHRpID0gMDtcblxuXHRcdGZvciAoIDsgKGVsZW0gPSBlbGVtc1tpXSkgIT0gbnVsbDsgaSsrICkge1xuXG5cdFx0XHRpZiAoICFrZWVwRGF0YSAmJiBlbGVtLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRqUXVlcnkuY2xlYW5EYXRhKCBnZXRBbGwoIGVsZW0gKSApO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGVsZW0ucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0aWYgKCBrZWVwRGF0YSAmJiBqUXVlcnkuY29udGFpbnMoIGVsZW0ub3duZXJEb2N1bWVudCwgZWxlbSApICkge1xuXHRcdFx0XHRcdHNldEdsb2JhbEV2YWwoIGdldEFsbCggZWxlbSwgXCJzY3JpcHRcIiApICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0ZWxlbS5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKCBlbGVtICk7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0ZW1wdHk6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBlbGVtLFxuXHRcdFx0aSA9IDA7XG5cblx0XHRmb3IgKCA7IChlbGVtID0gdGhpc1tpXSkgIT0gbnVsbDsgaSsrICkge1xuXHRcdFx0Ly8gUmVtb3ZlIGVsZW1lbnQgbm9kZXMgYW5kIHByZXZlbnQgbWVtb3J5IGxlYWtzXG5cdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggZWxlbSwgZmFsc2UgKSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBSZW1vdmUgYW55IHJlbWFpbmluZyBub2Rlc1xuXHRcdFx0d2hpbGUgKCBlbGVtLmZpcnN0Q2hpbGQgKSB7XG5cdFx0XHRcdGVsZW0ucmVtb3ZlQ2hpbGQoIGVsZW0uZmlyc3RDaGlsZCApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBJZiB0aGlzIGlzIGEgc2VsZWN0LCBlbnN1cmUgdGhhdCBpdCBkaXNwbGF5cyBlbXB0eSAoIzEyMzM2KVxuXHRcdFx0Ly8gU3VwcG9ydDogSUU8OVxuXHRcdFx0aWYgKCBlbGVtLm9wdGlvbnMgJiYgalF1ZXJ5Lm5vZGVOYW1lKCBlbGVtLCBcInNlbGVjdFwiICkgKSB7XG5cdFx0XHRcdGVsZW0ub3B0aW9ucy5sZW5ndGggPSAwO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdGNsb25lOiBmdW5jdGlvbiggZGF0YUFuZEV2ZW50cywgZGVlcERhdGFBbmRFdmVudHMgKSB7XG5cdFx0ZGF0YUFuZEV2ZW50cyA9IGRhdGFBbmRFdmVudHMgPT0gbnVsbCA/IGZhbHNlIDogZGF0YUFuZEV2ZW50cztcblx0XHRkZWVwRGF0YUFuZEV2ZW50cyA9IGRlZXBEYXRhQW5kRXZlbnRzID09IG51bGwgPyBkYXRhQW5kRXZlbnRzIDogZGVlcERhdGFBbmRFdmVudHM7XG5cblx0XHRyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4galF1ZXJ5LmNsb25lKCB0aGlzLCBkYXRhQW5kRXZlbnRzLCBkZWVwRGF0YUFuZEV2ZW50cyApO1xuXHRcdH0pO1xuXHR9LFxuXG5cdGh0bWw6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRyZXR1cm4gYWNjZXNzKCB0aGlzLCBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHR2YXIgZWxlbSA9IHRoaXNbIDAgXSB8fCB7fSxcblx0XHRcdFx0aSA9IDAsXG5cdFx0XHRcdGwgPSB0aGlzLmxlbmd0aDtcblxuXHRcdFx0aWYgKCB2YWx1ZSA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRyZXR1cm4gZWxlbS5ub2RlVHlwZSA9PT0gMSA/XG5cdFx0XHRcdFx0ZWxlbS5pbm5lckhUTUwucmVwbGFjZSggcmlubGluZWpRdWVyeSwgXCJcIiApIDpcblx0XHRcdFx0XHR1bmRlZmluZWQ7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNlZSBpZiB3ZSBjYW4gdGFrZSBhIHNob3J0Y3V0IGFuZCBqdXN0IHVzZSBpbm5lckhUTUxcblx0XHRcdGlmICggdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmICFybm9Jbm5lcmh0bWwudGVzdCggdmFsdWUgKSAmJlxuXHRcdFx0XHQoIHN1cHBvcnQuaHRtbFNlcmlhbGl6ZSB8fCAhcm5vc2hpbWNhY2hlLnRlc3QoIHZhbHVlICkgICkgJiZcblx0XHRcdFx0KCBzdXBwb3J0LmxlYWRpbmdXaGl0ZXNwYWNlIHx8ICFybGVhZGluZ1doaXRlc3BhY2UudGVzdCggdmFsdWUgKSApICYmXG5cdFx0XHRcdCF3cmFwTWFwWyAocnRhZ05hbWUuZXhlYyggdmFsdWUgKSB8fCBbIFwiXCIsIFwiXCIgXSlbIDEgXS50b0xvd2VyQ2FzZSgpIF0gKSB7XG5cblx0XHRcdFx0dmFsdWUgPSB2YWx1ZS5yZXBsYWNlKCByeGh0bWxUYWcsIFwiPCQxPjwvJDI+XCIgKTtcblxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdGZvciAoOyBpIDwgbDsgaSsrICkge1xuXHRcdFx0XHRcdFx0Ly8gUmVtb3ZlIGVsZW1lbnQgbm9kZXMgYW5kIHByZXZlbnQgbWVtb3J5IGxlYWtzXG5cdFx0XHRcdFx0XHRlbGVtID0gdGhpc1tpXSB8fCB7fTtcblx0XHRcdFx0XHRcdGlmICggZWxlbS5ub2RlVHlwZSA9PT0gMSApIHtcblx0XHRcdFx0XHRcdFx0alF1ZXJ5LmNsZWFuRGF0YSggZ2V0QWxsKCBlbGVtLCBmYWxzZSApICk7XG5cdFx0XHRcdFx0XHRcdGVsZW0uaW5uZXJIVE1MID0gdmFsdWU7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0ZWxlbSA9IDA7XG5cblx0XHRcdFx0Ly8gSWYgdXNpbmcgaW5uZXJIVE1MIHRocm93cyBhbiBleGNlcHRpb24sIHVzZSB0aGUgZmFsbGJhY2sgbWV0aG9kXG5cdFx0XHRcdH0gY2F0Y2goZSkge31cblx0XHRcdH1cblxuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHR0aGlzLmVtcHR5KCkuYXBwZW5kKCB2YWx1ZSApO1xuXHRcdFx0fVxuXHRcdH0sIG51bGwsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoICk7XG5cdH0sXG5cblx0cmVwbGFjZVdpdGg6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBhcmcgPSBhcmd1bWVudHNbIDAgXTtcblxuXHRcdC8vIE1ha2UgdGhlIGNoYW5nZXMsIHJlcGxhY2luZyBlYWNoIGNvbnRleHQgZWxlbWVudCB3aXRoIHRoZSBuZXcgY29udGVudFxuXHRcdHRoaXMuZG9tTWFuaXAoIGFyZ3VtZW50cywgZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRhcmcgPSB0aGlzLnBhcmVudE5vZGU7XG5cblx0XHRcdGpRdWVyeS5jbGVhbkRhdGEoIGdldEFsbCggdGhpcyApICk7XG5cblx0XHRcdGlmICggYXJnICkge1xuXHRcdFx0XHRhcmcucmVwbGFjZUNoaWxkKCBlbGVtLCB0aGlzICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0XHQvLyBGb3JjZSByZW1vdmFsIGlmIHRoZXJlIHdhcyBubyBuZXcgY29udGVudCAoZS5nLiwgZnJvbSBlbXB0eSBhcmd1bWVudHMpXG5cdFx0cmV0dXJuIGFyZyAmJiAoYXJnLmxlbmd0aCB8fCBhcmcubm9kZVR5cGUpID8gdGhpcyA6IHRoaXMucmVtb3ZlKCk7XG5cdH0sXG5cblx0ZGV0YWNoOiBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0cmV0dXJuIHRoaXMucmVtb3ZlKCBzZWxlY3RvciwgdHJ1ZSApO1xuXHR9LFxuXG5cdGRvbU1hbmlwOiBmdW5jdGlvbiggYXJncywgY2FsbGJhY2sgKSB7XG5cblx0XHQvLyBGbGF0dGVuIGFueSBuZXN0ZWQgYXJyYXlzXG5cdFx0YXJncyA9IGNvbmNhdC5hcHBseSggW10sIGFyZ3MgKTtcblxuXHRcdHZhciBmaXJzdCwgbm9kZSwgaGFzU2NyaXB0cyxcblx0XHRcdHNjcmlwdHMsIGRvYywgZnJhZ21lbnQsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aCxcblx0XHRcdHNldCA9IHRoaXMsXG5cdFx0XHRpTm9DbG9uZSA9IGwgLSAxLFxuXHRcdFx0dmFsdWUgPSBhcmdzWzBdLFxuXHRcdFx0aXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdFx0Ly8gV2UgY2FuJ3QgY2xvbmVOb2RlIGZyYWdtZW50cyB0aGF0IGNvbnRhaW4gY2hlY2tlZCwgaW4gV2ViS2l0XG5cdFx0aWYgKCBpc0Z1bmN0aW9uIHx8XG5cdFx0XHRcdCggbCA+IDEgJiYgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiICYmXG5cdFx0XHRcdFx0IXN1cHBvcnQuY2hlY2tDbG9uZSAmJiByY2hlY2tlZC50ZXN0KCB2YWx1ZSApICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpbmRleCApIHtcblx0XHRcdFx0dmFyIHNlbGYgPSBzZXQuZXEoIGluZGV4ICk7XG5cdFx0XHRcdGlmICggaXNGdW5jdGlvbiApIHtcblx0XHRcdFx0XHRhcmdzWzBdID0gdmFsdWUuY2FsbCggdGhpcywgaW5kZXgsIHNlbGYuaHRtbCgpICk7XG5cdFx0XHRcdH1cblx0XHRcdFx0c2VsZi5kb21NYW5pcCggYXJncywgY2FsbGJhY2sgKTtcblx0XHRcdH0pO1xuXHRcdH1cblxuXHRcdGlmICggbCApIHtcblx0XHRcdGZyYWdtZW50ID0galF1ZXJ5LmJ1aWxkRnJhZ21lbnQoIGFyZ3MsIHRoaXNbIDAgXS5vd25lckRvY3VtZW50LCBmYWxzZSwgdGhpcyApO1xuXHRcdFx0Zmlyc3QgPSBmcmFnbWVudC5maXJzdENoaWxkO1xuXG5cdFx0XHRpZiAoIGZyYWdtZW50LmNoaWxkTm9kZXMubGVuZ3RoID09PSAxICkge1xuXHRcdFx0XHRmcmFnbWVudCA9IGZpcnN0O1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGZpcnN0ICkge1xuXHRcdFx0XHRzY3JpcHRzID0galF1ZXJ5Lm1hcCggZ2V0QWxsKCBmcmFnbWVudCwgXCJzY3JpcHRcIiApLCBkaXNhYmxlU2NyaXB0ICk7XG5cdFx0XHRcdGhhc1NjcmlwdHMgPSBzY3JpcHRzLmxlbmd0aDtcblxuXHRcdFx0XHQvLyBVc2UgdGhlIG9yaWdpbmFsIGZyYWdtZW50IGZvciB0aGUgbGFzdCBpdGVtIGluc3RlYWQgb2YgdGhlIGZpcnN0IGJlY2F1c2UgaXQgY2FuIGVuZCB1cFxuXHRcdFx0XHQvLyBiZWluZyBlbXB0aWVkIGluY29ycmVjdGx5IGluIGNlcnRhaW4gc2l0dWF0aW9ucyAoIzgwNzApLlxuXHRcdFx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRcdFx0bm9kZSA9IGZyYWdtZW50O1xuXG5cdFx0XHRcdFx0aWYgKCBpICE9PSBpTm9DbG9uZSApIHtcblx0XHRcdFx0XHRcdG5vZGUgPSBqUXVlcnkuY2xvbmUoIG5vZGUsIHRydWUsIHRydWUgKTtcblxuXHRcdFx0XHRcdFx0Ly8gS2VlcCByZWZlcmVuY2VzIHRvIGNsb25lZCBzY3JpcHRzIGZvciBsYXRlciByZXN0b3JhdGlvblxuXHRcdFx0XHRcdFx0aWYgKCBoYXNTY3JpcHRzICkge1xuXHRcdFx0XHRcdFx0XHRqUXVlcnkubWVyZ2UoIHNjcmlwdHMsIGdldEFsbCggbm9kZSwgXCJzY3JpcHRcIiApICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Y2FsbGJhY2suY2FsbCggdGhpc1tpXSwgbm9kZSwgaSApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0aWYgKCBoYXNTY3JpcHRzICkge1xuXHRcdFx0XHRcdGRvYyA9IHNjcmlwdHNbIHNjcmlwdHMubGVuZ3RoIC0gMSBdLm93bmVyRG9jdW1lbnQ7XG5cblx0XHRcdFx0XHQvLyBSZWVuYWJsZSBzY3JpcHRzXG5cdFx0XHRcdFx0alF1ZXJ5Lm1hcCggc2NyaXB0cywgcmVzdG9yZVNjcmlwdCApO1xuXG5cdFx0XHRcdFx0Ly8gRXZhbHVhdGUgZXhlY3V0YWJsZSBzY3JpcHRzIG9uIGZpcnN0IGRvY3VtZW50IGluc2VydGlvblxuXHRcdFx0XHRcdGZvciAoIGkgPSAwOyBpIDwgaGFzU2NyaXB0czsgaSsrICkge1xuXHRcdFx0XHRcdFx0bm9kZSA9IHNjcmlwdHNbIGkgXTtcblx0XHRcdFx0XHRcdGlmICggcnNjcmlwdFR5cGUudGVzdCggbm9kZS50eXBlIHx8IFwiXCIgKSAmJlxuXHRcdFx0XHRcdFx0XHQhalF1ZXJ5Ll9kYXRhKCBub2RlLCBcImdsb2JhbEV2YWxcIiApICYmIGpRdWVyeS5jb250YWlucyggZG9jLCBub2RlICkgKSB7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCBub2RlLnNyYyApIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBPcHRpb25hbCBBSkFYIGRlcGVuZGVuY3ksIGJ1dCB3b24ndCBydW4gc2NyaXB0cyBpZiBub3QgcHJlc2VudFxuXHRcdFx0XHRcdFx0XHRcdGlmICggalF1ZXJ5Ll9ldmFsVXJsICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0alF1ZXJ5Ll9ldmFsVXJsKCBub2RlLnNyYyApO1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdFx0XHRqUXVlcnkuZ2xvYmFsRXZhbCggKCBub2RlLnRleHQgfHwgbm9kZS50ZXh0Q29udGVudCB8fCBub2RlLmlubmVySFRNTCB8fCBcIlwiICkucmVwbGFjZSggcmNsZWFuU2NyaXB0LCBcIlwiICkgKTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEZpeCAjMTE4MDk6IEF2b2lkIGxlYWtpbmcgbWVtb3J5XG5cdFx0XHRcdGZyYWdtZW50ID0gZmlyc3QgPSBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG59KTtcblxualF1ZXJ5LmVhY2goe1xuXHRhcHBlbmRUbzogXCJhcHBlbmRcIixcblx0cHJlcGVuZFRvOiBcInByZXBlbmRcIixcblx0aW5zZXJ0QmVmb3JlOiBcImJlZm9yZVwiLFxuXHRpbnNlcnRBZnRlcjogXCJhZnRlclwiLFxuXHRyZXBsYWNlQWxsOiBcInJlcGxhY2VXaXRoXCJcbn0sIGZ1bmN0aW9uKCBuYW1lLCBvcmlnaW5hbCApIHtcblx0alF1ZXJ5LmZuWyBuYW1lIF0gPSBmdW5jdGlvbiggc2VsZWN0b3IgKSB7XG5cdFx0dmFyIGVsZW1zLFxuXHRcdFx0aSA9IDAsXG5cdFx0XHRyZXQgPSBbXSxcblx0XHRcdGluc2VydCA9IGpRdWVyeSggc2VsZWN0b3IgKSxcblx0XHRcdGxhc3QgPSBpbnNlcnQubGVuZ3RoIC0gMTtcblxuXHRcdGZvciAoIDsgaSA8PSBsYXN0OyBpKysgKSB7XG5cdFx0XHRlbGVtcyA9IGkgPT09IGxhc3QgPyB0aGlzIDogdGhpcy5jbG9uZSh0cnVlKTtcblx0XHRcdGpRdWVyeSggaW5zZXJ0W2ldIClbIG9yaWdpbmFsIF0oIGVsZW1zICk7XG5cblx0XHRcdC8vIE1vZGVybiBicm93c2VycyBjYW4gYXBwbHkgalF1ZXJ5IGNvbGxlY3Rpb25zIGFzIGFycmF5cywgYnV0IG9sZElFIG5lZWRzIGEgLmdldCgpXG5cdFx0XHRwdXNoLmFwcGx5KCByZXQsIGVsZW1zLmdldCgpICk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMucHVzaFN0YWNrKCByZXQgKTtcblx0fTtcbn0pO1xuXG5cbnZhciBpZnJhbWUsXG5cdGVsZW1kaXNwbGF5ID0ge307XG5cbi8qKlxuICogUmV0cmlldmUgdGhlIGFjdHVhbCBkaXNwbGF5IG9mIGEgZWxlbWVudFxuICogQHBhcmFtIHtTdHJpbmd9IG5hbWUgbm9kZU5hbWUgb2YgdGhlIGVsZW1lbnRcbiAqIEBwYXJhbSB7T2JqZWN0fSBkb2MgRG9jdW1lbnQgb2JqZWN0XG4gKi9cbi8vIENhbGxlZCBvbmx5IGZyb20gd2l0aGluIGRlZmF1bHREaXNwbGF5XG5mdW5jdGlvbiBhY3R1YWxEaXNwbGF5KCBuYW1lLCBkb2MgKSB7XG5cdHZhciBzdHlsZSxcblx0XHRlbGVtID0galF1ZXJ5KCBkb2MuY3JlYXRlRWxlbWVudCggbmFtZSApICkuYXBwZW5kVG8oIGRvYy5ib2R5ICksXG5cblx0XHQvLyBnZXREZWZhdWx0Q29tcHV0ZWRTdHlsZSBtaWdodCBiZSByZWxpYWJseSB1c2VkIG9ubHkgb24gYXR0YWNoZWQgZWxlbWVudFxuXHRcdGRpc3BsYXkgPSB3aW5kb3cuZ2V0RGVmYXVsdENvbXB1dGVkU3R5bGUgJiYgKCBzdHlsZSA9IHdpbmRvdy5nZXREZWZhdWx0Q29tcHV0ZWRTdHlsZSggZWxlbVsgMCBdICkgKSA/XG5cblx0XHRcdC8vIFVzZSBvZiB0aGlzIG1ldGhvZCBpcyBhIHRlbXBvcmFyeSBmaXggKG1vcmUgbGlrZSBvcHRtaXphdGlvbikgdW50aWwgc29tZXRoaW5nIGJldHRlciBjb21lcyBhbG9uZyxcblx0XHRcdC8vIHNpbmNlIGl0IHdhcyByZW1vdmVkIGZyb20gc3BlY2lmaWNhdGlvbiBhbmQgc3VwcG9ydGVkIG9ubHkgaW4gRkZcblx0XHRcdHN0eWxlLmRpc3BsYXkgOiBqUXVlcnkuY3NzKCBlbGVtWyAwIF0sIFwiZGlzcGxheVwiICk7XG5cblx0Ly8gV2UgZG9uJ3QgaGF2ZSBhbnkgZGF0YSBzdG9yZWQgb24gdGhlIGVsZW1lbnQsXG5cdC8vIHNvIHVzZSBcImRldGFjaFwiIG1ldGhvZCBhcyBmYXN0IHdheSB0byBnZXQgcmlkIG9mIHRoZSBlbGVtZW50XG5cdGVsZW0uZGV0YWNoKCk7XG5cblx0cmV0dXJuIGRpc3BsYXk7XG59XG5cbi8qKlxuICogVHJ5IHRvIGRldGVybWluZSB0aGUgZGVmYXVsdCBkaXNwbGF5IHZhbHVlIG9mIGFuIGVsZW1lbnRcbiAqIEBwYXJhbSB7U3RyaW5nfSBub2RlTmFtZVxuICovXG5mdW5jdGlvbiBkZWZhdWx0RGlzcGxheSggbm9kZU5hbWUgKSB7XG5cdHZhciBkb2MgPSBkb2N1bWVudCxcblx0XHRkaXNwbGF5ID0gZWxlbWRpc3BsYXlbIG5vZGVOYW1lIF07XG5cblx0aWYgKCAhZGlzcGxheSApIHtcblx0XHRkaXNwbGF5ID0gYWN0dWFsRGlzcGxheSggbm9kZU5hbWUsIGRvYyApO1xuXG5cdFx0Ly8gSWYgdGhlIHNpbXBsZSB3YXkgZmFpbHMsIHJlYWQgZnJvbSBpbnNpZGUgYW4gaWZyYW1lXG5cdFx0aWYgKCBkaXNwbGF5ID09PSBcIm5vbmVcIiB8fCAhZGlzcGxheSApIHtcblxuXHRcdFx0Ly8gVXNlIHRoZSBhbHJlYWR5LWNyZWF0ZWQgaWZyYW1lIGlmIHBvc3NpYmxlXG5cdFx0XHRpZnJhbWUgPSAoaWZyYW1lIHx8IGpRdWVyeSggXCI8aWZyYW1lIGZyYW1lYm9yZGVyPScwJyB3aWR0aD0nMCcgaGVpZ2h0PScwJy8+XCIgKSkuYXBwZW5kVG8oIGRvYy5kb2N1bWVudEVsZW1lbnQgKTtcblxuXHRcdFx0Ly8gQWx3YXlzIHdyaXRlIGEgbmV3IEhUTUwgc2tlbGV0b24gc28gV2Via2l0IGFuZCBGaXJlZm94IGRvbid0IGNob2tlIG9uIHJldXNlXG5cdFx0XHRkb2MgPSAoIGlmcmFtZVsgMCBdLmNvbnRlbnRXaW5kb3cgfHwgaWZyYW1lWyAwIF0uY29udGVudERvY3VtZW50ICkuZG9jdW1lbnQ7XG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFXG5cdFx0XHRkb2Mud3JpdGUoKTtcblx0XHRcdGRvYy5jbG9zZSgpO1xuXG5cdFx0XHRkaXNwbGF5ID0gYWN0dWFsRGlzcGxheSggbm9kZU5hbWUsIGRvYyApO1xuXHRcdFx0aWZyYW1lLmRldGFjaCgpO1xuXHRcdH1cblxuXHRcdC8vIFN0b3JlIHRoZSBjb3JyZWN0IGRlZmF1bHQgZGlzcGxheVxuXHRcdGVsZW1kaXNwbGF5WyBub2RlTmFtZSBdID0gZGlzcGxheTtcblx0fVxuXG5cdHJldHVybiBkaXNwbGF5O1xufVxuXG5cbihmdW5jdGlvbigpIHtcblx0dmFyIHNocmlua1dyYXBCbG9ja3NWYWw7XG5cblx0c3VwcG9ydC5zaHJpbmtXcmFwQmxvY2tzID0gZnVuY3Rpb24oKSB7XG5cdFx0aWYgKCBzaHJpbmtXcmFwQmxvY2tzVmFsICE9IG51bGwgKSB7XG5cdFx0XHRyZXR1cm4gc2hyaW5rV3JhcEJsb2Nrc1ZhbDtcblx0XHR9XG5cblx0XHQvLyBXaWxsIGJlIGNoYW5nZWQgbGF0ZXIgaWYgbmVlZGVkLlxuXHRcdHNocmlua1dyYXBCbG9ja3NWYWwgPSBmYWxzZTtcblxuXHRcdC8vIE1pbmlmaWVkOiB2YXIgYixjLGRcblx0XHR2YXIgZGl2LCBib2R5LCBjb250YWluZXI7XG5cblx0XHRib2R5ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwiYm9keVwiIClbIDAgXTtcblx0XHRpZiAoICFib2R5IHx8ICFib2R5LnN0eWxlICkge1xuXHRcdFx0Ly8gVGVzdCBmaXJlZCB0b28gZWFybHkgb3IgaW4gYW4gdW5zdXBwb3J0ZWQgZW52aXJvbm1lbnQsIGV4aXQuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gU2V0dXBcblx0XHRkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICk7XG5cdFx0Y29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApO1xuXHRcdGNvbnRhaW5lci5zdHlsZS5jc3NUZXh0ID0gXCJwb3NpdGlvbjphYnNvbHV0ZTtib3JkZXI6MDt3aWR0aDowO2hlaWdodDowO3RvcDowO2xlZnQ6LTk5OTlweFwiO1xuXHRcdGJvZHkuYXBwZW5kQ2hpbGQoIGNvbnRhaW5lciApLmFwcGVuZENoaWxkKCBkaXYgKTtcblxuXHRcdC8vIFN1cHBvcnQ6IElFNlxuXHRcdC8vIENoZWNrIGlmIGVsZW1lbnRzIHdpdGggbGF5b3V0IHNocmluay13cmFwIHRoZWlyIGNoaWxkcmVuXG5cdFx0aWYgKCB0eXBlb2YgZGl2LnN0eWxlLnpvb20gIT09IHN0cnVuZGVmaW5lZCApIHtcblx0XHRcdC8vIFJlc2V0IENTUzogYm94LXNpemluZzsgZGlzcGxheTsgbWFyZ2luOyBib3JkZXJcblx0XHRcdGRpdi5zdHlsZS5jc3NUZXh0ID1cblx0XHRcdFx0Ly8gU3VwcG9ydDogRmlyZWZveDwyOSwgQW5kcm9pZCAyLjNcblx0XHRcdFx0Ly8gVmVuZG9yLXByZWZpeCBib3gtc2l6aW5nXG5cdFx0XHRcdFwiLXdlYmtpdC1ib3gtc2l6aW5nOmNvbnRlbnQtYm94Oy1tb3otYm94LXNpemluZzpjb250ZW50LWJveDtcIiArXG5cdFx0XHRcdFwiYm94LXNpemluZzpjb250ZW50LWJveDtkaXNwbGF5OmJsb2NrO21hcmdpbjowO2JvcmRlcjowO1wiICtcblx0XHRcdFx0XCJwYWRkaW5nOjFweDt3aWR0aDoxcHg7em9vbToxXCI7XG5cdFx0XHRkaXYuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApLnN0eWxlLndpZHRoID0gXCI1cHhcIjtcblx0XHRcdHNocmlua1dyYXBCbG9ja3NWYWwgPSBkaXYub2Zmc2V0V2lkdGggIT09IDM7XG5cdFx0fVxuXG5cdFx0Ym9keS5yZW1vdmVDaGlsZCggY29udGFpbmVyICk7XG5cblx0XHRyZXR1cm4gc2hyaW5rV3JhcEJsb2Nrc1ZhbDtcblx0fTtcblxufSkoKTtcbnZhciBybWFyZ2luID0gKC9ebWFyZ2luLyk7XG5cbnZhciBybnVtbm9ucHggPSBuZXcgUmVnRXhwKCBcIl4oXCIgKyBwbnVtICsgXCIpKD8hcHgpW2EteiVdKyRcIiwgXCJpXCIgKTtcblxuXG5cbnZhciBnZXRTdHlsZXMsIGN1ckNTUyxcblx0cnBvc2l0aW9uID0gL14odG9wfHJpZ2h0fGJvdHRvbXxsZWZ0KSQvO1xuXG5pZiAoIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlICkge1xuXHRnZXRTdHlsZXMgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHQvLyBTdXBwb3J0OiBJRTw9MTErLCBGaXJlZm94PD0zMCsgKCMxNTA5OCwgIzE0MTUwKVxuXHRcdC8vIElFIHRocm93cyBvbiBlbGVtZW50cyBjcmVhdGVkIGluIHBvcHVwc1xuXHRcdC8vIEZGIG1lYW53aGlsZSB0aHJvd3Mgb24gZnJhbWUgZWxlbWVudHMgdGhyb3VnaCBcImRlZmF1bHRWaWV3LmdldENvbXB1dGVkU3R5bGVcIlxuXHRcdGlmICggZWxlbS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3Lm9wZW5lciApIHtcblx0XHRcdHJldHVybiBlbGVtLm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXcuZ2V0Q29tcHV0ZWRTdHlsZSggZWxlbSwgbnVsbCApO1xuXHRcdH1cblxuXHRcdHJldHVybiB3aW5kb3cuZ2V0Q29tcHV0ZWRTdHlsZSggZWxlbSwgbnVsbCApO1xuXHR9O1xuXG5cdGN1ckNTUyA9IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBjb21wdXRlZCApIHtcblx0XHR2YXIgd2lkdGgsIG1pbldpZHRoLCBtYXhXaWR0aCwgcmV0LFxuXHRcdFx0c3R5bGUgPSBlbGVtLnN0eWxlO1xuXG5cdFx0Y29tcHV0ZWQgPSBjb21wdXRlZCB8fCBnZXRTdHlsZXMoIGVsZW0gKTtcblxuXHRcdC8vIGdldFByb3BlcnR5VmFsdWUgaXMgb25seSBuZWVkZWQgZm9yIC5jc3MoJ2ZpbHRlcicpIGluIElFOSwgc2VlICMxMjUzN1xuXHRcdHJldCA9IGNvbXB1dGVkID8gY29tcHV0ZWQuZ2V0UHJvcGVydHlWYWx1ZSggbmFtZSApIHx8IGNvbXB1dGVkWyBuYW1lIF0gOiB1bmRlZmluZWQ7XG5cblx0XHRpZiAoIGNvbXB1dGVkICkge1xuXG5cdFx0XHRpZiAoIHJldCA9PT0gXCJcIiAmJiAhalF1ZXJ5LmNvbnRhaW5zKCBlbGVtLm93bmVyRG9jdW1lbnQsIGVsZW0gKSApIHtcblx0XHRcdFx0cmV0ID0galF1ZXJ5LnN0eWxlKCBlbGVtLCBuYW1lICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEEgdHJpYnV0ZSB0byB0aGUgXCJhd2Vzb21lIGhhY2sgYnkgRGVhbiBFZHdhcmRzXCJcblx0XHRcdC8vIENocm9tZSA8IDE3IGFuZCBTYWZhcmkgNS4wIHVzZXMgXCJjb21wdXRlZCB2YWx1ZVwiIGluc3RlYWQgb2YgXCJ1c2VkIHZhbHVlXCIgZm9yIG1hcmdpbi1yaWdodFxuXHRcdFx0Ly8gU2FmYXJpIDUuMS43IChhdCBsZWFzdCkgcmV0dXJucyBwZXJjZW50YWdlIGZvciBhIGxhcmdlciBzZXQgb2YgdmFsdWVzLCBidXQgd2lkdGggc2VlbXMgdG8gYmUgcmVsaWFibHkgcGl4ZWxzXG5cdFx0XHQvLyB0aGlzIGlzIGFnYWluc3QgdGhlIENTU09NIGRyYWZ0IHNwZWM6IGh0dHA6Ly9kZXYudzMub3JnL2Nzc3dnL2Nzc29tLyNyZXNvbHZlZC12YWx1ZXNcblx0XHRcdGlmICggcm51bW5vbnB4LnRlc3QoIHJldCApICYmIHJtYXJnaW4udGVzdCggbmFtZSApICkge1xuXG5cdFx0XHRcdC8vIFJlbWVtYmVyIHRoZSBvcmlnaW5hbCB2YWx1ZXNcblx0XHRcdFx0d2lkdGggPSBzdHlsZS53aWR0aDtcblx0XHRcdFx0bWluV2lkdGggPSBzdHlsZS5taW5XaWR0aDtcblx0XHRcdFx0bWF4V2lkdGggPSBzdHlsZS5tYXhXaWR0aDtcblxuXHRcdFx0XHQvLyBQdXQgaW4gdGhlIG5ldyB2YWx1ZXMgdG8gZ2V0IGEgY29tcHV0ZWQgdmFsdWUgb3V0XG5cdFx0XHRcdHN0eWxlLm1pbldpZHRoID0gc3R5bGUubWF4V2lkdGggPSBzdHlsZS53aWR0aCA9IHJldDtcblx0XHRcdFx0cmV0ID0gY29tcHV0ZWQud2lkdGg7XG5cblx0XHRcdFx0Ly8gUmV2ZXJ0IHRoZSBjaGFuZ2VkIHZhbHVlc1xuXHRcdFx0XHRzdHlsZS53aWR0aCA9IHdpZHRoO1xuXHRcdFx0XHRzdHlsZS5taW5XaWR0aCA9IG1pbldpZHRoO1xuXHRcdFx0XHRzdHlsZS5tYXhXaWR0aCA9IG1heFdpZHRoO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdC8vIFN1cHBvcnQ6IElFXG5cdFx0Ly8gSUUgcmV0dXJucyB6SW5kZXggdmFsdWUgYXMgYW4gaW50ZWdlci5cblx0XHRyZXR1cm4gcmV0ID09PSB1bmRlZmluZWQgP1xuXHRcdFx0cmV0IDpcblx0XHRcdHJldCArIFwiXCI7XG5cdH07XG59IGVsc2UgaWYgKCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY3VycmVudFN0eWxlICkge1xuXHRnZXRTdHlsZXMgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRyZXR1cm4gZWxlbS5jdXJyZW50U3R5bGU7XG5cdH07XG5cblx0Y3VyQ1NTID0gZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGNvbXB1dGVkICkge1xuXHRcdHZhciBsZWZ0LCBycywgcnNMZWZ0LCByZXQsXG5cdFx0XHRzdHlsZSA9IGVsZW0uc3R5bGU7XG5cblx0XHRjb21wdXRlZCA9IGNvbXB1dGVkIHx8IGdldFN0eWxlcyggZWxlbSApO1xuXHRcdHJldCA9IGNvbXB1dGVkID8gY29tcHV0ZWRbIG5hbWUgXSA6IHVuZGVmaW5lZDtcblxuXHRcdC8vIEF2b2lkIHNldHRpbmcgcmV0IHRvIGVtcHR5IHN0cmluZyBoZXJlXG5cdFx0Ly8gc28gd2UgZG9uJ3QgZGVmYXVsdCB0byBhdXRvXG5cdFx0aWYgKCByZXQgPT0gbnVsbCAmJiBzdHlsZSAmJiBzdHlsZVsgbmFtZSBdICkge1xuXHRcdFx0cmV0ID0gc3R5bGVbIG5hbWUgXTtcblx0XHR9XG5cblx0XHQvLyBGcm9tIHRoZSBhd2Vzb21lIGhhY2sgYnkgRGVhbiBFZHdhcmRzXG5cdFx0Ly8gaHR0cDovL2VyaWsuZWFlLm5ldC9hcmNoaXZlcy8yMDA3LzA3LzI3LzE4LjU0LjE1LyNjb21tZW50LTEwMjI5MVxuXG5cdFx0Ly8gSWYgd2UncmUgbm90IGRlYWxpbmcgd2l0aCBhIHJlZ3VsYXIgcGl4ZWwgbnVtYmVyXG5cdFx0Ly8gYnV0IGEgbnVtYmVyIHRoYXQgaGFzIGEgd2VpcmQgZW5kaW5nLCB3ZSBuZWVkIHRvIGNvbnZlcnQgaXQgdG8gcGl4ZWxzXG5cdFx0Ly8gYnV0IG5vdCBwb3NpdGlvbiBjc3MgYXR0cmlidXRlcywgYXMgdGhvc2UgYXJlIHByb3BvcnRpb25hbCB0byB0aGUgcGFyZW50IGVsZW1lbnQgaW5zdGVhZFxuXHRcdC8vIGFuZCB3ZSBjYW4ndCBtZWFzdXJlIHRoZSBwYXJlbnQgaW5zdGVhZCBiZWNhdXNlIGl0IG1pZ2h0IHRyaWdnZXIgYSBcInN0YWNraW5nIGRvbGxzXCIgcHJvYmxlbVxuXHRcdGlmICggcm51bW5vbnB4LnRlc3QoIHJldCApICYmICFycG9zaXRpb24udGVzdCggbmFtZSApICkge1xuXG5cdFx0XHQvLyBSZW1lbWJlciB0aGUgb3JpZ2luYWwgdmFsdWVzXG5cdFx0XHRsZWZ0ID0gc3R5bGUubGVmdDtcblx0XHRcdHJzID0gZWxlbS5ydW50aW1lU3R5bGU7XG5cdFx0XHRyc0xlZnQgPSBycyAmJiBycy5sZWZ0O1xuXG5cdFx0XHQvLyBQdXQgaW4gdGhlIG5ldyB2YWx1ZXMgdG8gZ2V0IGEgY29tcHV0ZWQgdmFsdWUgb3V0XG5cdFx0XHRpZiAoIHJzTGVmdCApIHtcblx0XHRcdFx0cnMubGVmdCA9IGVsZW0uY3VycmVudFN0eWxlLmxlZnQ7XG5cdFx0XHR9XG5cdFx0XHRzdHlsZS5sZWZ0ID0gbmFtZSA9PT0gXCJmb250U2l6ZVwiID8gXCIxZW1cIiA6IHJldDtcblx0XHRcdHJldCA9IHN0eWxlLnBpeGVsTGVmdCArIFwicHhcIjtcblxuXHRcdFx0Ly8gUmV2ZXJ0IHRoZSBjaGFuZ2VkIHZhbHVlc1xuXHRcdFx0c3R5bGUubGVmdCA9IGxlZnQ7XG5cdFx0XHRpZiAoIHJzTGVmdCApIHtcblx0XHRcdFx0cnMubGVmdCA9IHJzTGVmdDtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTdXBwb3J0OiBJRVxuXHRcdC8vIElFIHJldHVybnMgekluZGV4IHZhbHVlIGFzIGFuIGludGVnZXIuXG5cdFx0cmV0dXJuIHJldCA9PT0gdW5kZWZpbmVkID9cblx0XHRcdHJldCA6XG5cdFx0XHRyZXQgKyBcIlwiIHx8IFwiYXV0b1wiO1xuXHR9O1xufVxuXG5cblxuXG5mdW5jdGlvbiBhZGRHZXRIb29rSWYoIGNvbmRpdGlvbkZuLCBob29rRm4gKSB7XG5cdC8vIERlZmluZSB0aGUgaG9vaywgd2UnbGwgY2hlY2sgb24gdGhlIGZpcnN0IHJ1biBpZiBpdCdzIHJlYWxseSBuZWVkZWQuXG5cdHJldHVybiB7XG5cdFx0Z2V0OiBmdW5jdGlvbigpIHtcblx0XHRcdHZhciBjb25kaXRpb24gPSBjb25kaXRpb25GbigpO1xuXG5cdFx0XHRpZiAoIGNvbmRpdGlvbiA9PSBudWxsICkge1xuXHRcdFx0XHQvLyBUaGUgdGVzdCB3YXMgbm90IHJlYWR5IGF0IHRoaXMgcG9pbnQ7IHNjcmV3IHRoZSBob29rIHRoaXMgdGltZVxuXHRcdFx0XHQvLyBidXQgY2hlY2sgYWdhaW4gd2hlbiBuZWVkZWQgbmV4dCB0aW1lLlxuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdGlmICggY29uZGl0aW9uICkge1xuXHRcdFx0XHQvLyBIb29rIG5vdCBuZWVkZWQgKG9yIGl0J3Mgbm90IHBvc3NpYmxlIHRvIHVzZSBpdCBkdWUgdG8gbWlzc2luZyBkZXBlbmRlbmN5KSxcblx0XHRcdFx0Ly8gcmVtb3ZlIGl0LlxuXHRcdFx0XHQvLyBTaW5jZSB0aGVyZSBhcmUgbm8gb3RoZXIgaG9va3MgZm9yIG1hcmdpblJpZ2h0LCByZW1vdmUgdGhlIHdob2xlIG9iamVjdC5cblx0XHRcdFx0ZGVsZXRlIHRoaXMuZ2V0O1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIEhvb2sgbmVlZGVkOyByZWRlZmluZSBpdCBzbyB0aGF0IHRoZSBzdXBwb3J0IHRlc3QgaXMgbm90IGV4ZWN1dGVkIGFnYWluLlxuXG5cdFx0XHRyZXR1cm4gKHRoaXMuZ2V0ID0gaG9va0ZuKS5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdFx0fVxuXHR9O1xufVxuXG5cbihmdW5jdGlvbigpIHtcblx0Ly8gTWluaWZpZWQ6IHZhciBiLGMsZCxlLGYsZywgaCxpXG5cdHZhciBkaXYsIHN0eWxlLCBhLCBwaXhlbFBvc2l0aW9uVmFsLCBib3hTaXppbmdSZWxpYWJsZVZhbCxcblx0XHRyZWxpYWJsZUhpZGRlbk9mZnNldHNWYWwsIHJlbGlhYmxlTWFyZ2luUmlnaHRWYWw7XG5cblx0Ly8gU2V0dXBcblx0ZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApO1xuXHRkaXYuaW5uZXJIVE1MID0gXCIgIDxsaW5rLz48dGFibGU+PC90YWJsZT48YSBocmVmPScvYSc+YTwvYT48aW5wdXQgdHlwZT0nY2hlY2tib3gnLz5cIjtcblx0YSA9IGRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJhXCIgKVsgMCBdO1xuXHRzdHlsZSA9IGEgJiYgYS5zdHlsZTtcblxuXHQvLyBGaW5pc2ggZWFybHkgaW4gbGltaXRlZCAobm9uLWJyb3dzZXIpIGVudmlyb25tZW50c1xuXHRpZiAoICFzdHlsZSApIHtcblx0XHRyZXR1cm47XG5cdH1cblxuXHRzdHlsZS5jc3NUZXh0ID0gXCJmbG9hdDpsZWZ0O29wYWNpdHk6LjVcIjtcblxuXHQvLyBTdXBwb3J0OiBJRTw5XG5cdC8vIE1ha2Ugc3VyZSB0aGF0IGVsZW1lbnQgb3BhY2l0eSBleGlzdHMgKGFzIG9wcG9zZWQgdG8gZmlsdGVyKVxuXHRzdXBwb3J0Lm9wYWNpdHkgPSBzdHlsZS5vcGFjaXR5ID09PSBcIjAuNVwiO1xuXG5cdC8vIFZlcmlmeSBzdHlsZSBmbG9hdCBleGlzdGVuY2Vcblx0Ly8gKElFIHVzZXMgc3R5bGVGbG9hdCBpbnN0ZWFkIG9mIGNzc0Zsb2F0KVxuXHRzdXBwb3J0LmNzc0Zsb2F0ID0gISFzdHlsZS5jc3NGbG9hdDtcblxuXHRkaXYuc3R5bGUuYmFja2dyb3VuZENsaXAgPSBcImNvbnRlbnQtYm94XCI7XG5cdGRpdi5jbG9uZU5vZGUoIHRydWUgKS5zdHlsZS5iYWNrZ3JvdW5kQ2xpcCA9IFwiXCI7XG5cdHN1cHBvcnQuY2xlYXJDbG9uZVN0eWxlID0gZGl2LnN0eWxlLmJhY2tncm91bmRDbGlwID09PSBcImNvbnRlbnQtYm94XCI7XG5cblx0Ly8gU3VwcG9ydDogRmlyZWZveDwyOSwgQW5kcm9pZCAyLjNcblx0Ly8gVmVuZG9yLXByZWZpeCBib3gtc2l6aW5nXG5cdHN1cHBvcnQuYm94U2l6aW5nID0gc3R5bGUuYm94U2l6aW5nID09PSBcIlwiIHx8IHN0eWxlLk1vekJveFNpemluZyA9PT0gXCJcIiB8fFxuXHRcdHN0eWxlLldlYmtpdEJveFNpemluZyA9PT0gXCJcIjtcblxuXHRqUXVlcnkuZXh0ZW5kKHN1cHBvcnQsIHtcblx0XHRyZWxpYWJsZUhpZGRlbk9mZnNldHM6IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCByZWxpYWJsZUhpZGRlbk9mZnNldHNWYWwgPT0gbnVsbCApIHtcblx0XHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiByZWxpYWJsZUhpZGRlbk9mZnNldHNWYWw7XG5cdFx0fSxcblxuXHRcdGJveFNpemluZ1JlbGlhYmxlOiBmdW5jdGlvbigpIHtcblx0XHRcdGlmICggYm94U2l6aW5nUmVsaWFibGVWYWwgPT0gbnVsbCApIHtcblx0XHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBib3hTaXppbmdSZWxpYWJsZVZhbDtcblx0XHR9LFxuXG5cdFx0cGl4ZWxQb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIHBpeGVsUG9zaXRpb25WYWwgPT0gbnVsbCApIHtcblx0XHRcdFx0Y29tcHV0ZVN0eWxlVGVzdHMoKTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBwaXhlbFBvc2l0aW9uVmFsO1xuXHRcdH0sXG5cblx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xuXHRcdHJlbGlhYmxlTWFyZ2luUmlnaHQ6IGZ1bmN0aW9uKCkge1xuXHRcdFx0aWYgKCByZWxpYWJsZU1hcmdpblJpZ2h0VmFsID09IG51bGwgKSB7XG5cdFx0XHRcdGNvbXB1dGVTdHlsZVRlc3RzKCk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVsaWFibGVNYXJnaW5SaWdodFZhbDtcblx0XHR9XG5cdH0pO1xuXG5cdGZ1bmN0aW9uIGNvbXB1dGVTdHlsZVRlc3RzKCkge1xuXHRcdC8vIE1pbmlmaWVkOiB2YXIgYixjLGQsalxuXHRcdHZhciBkaXYsIGJvZHksIGNvbnRhaW5lciwgY29udGVudHM7XG5cblx0XHRib2R5ID0gZG9jdW1lbnQuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwiYm9keVwiIClbIDAgXTtcblx0XHRpZiAoICFib2R5IHx8ICFib2R5LnN0eWxlICkge1xuXHRcdFx0Ly8gVGVzdCBmaXJlZCB0b28gZWFybHkgb3IgaW4gYW4gdW5zdXBwb3J0ZWQgZW52aXJvbm1lbnQsIGV4aXQuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gU2V0dXBcblx0XHRkaXYgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCBcImRpdlwiICk7XG5cdFx0Y29udGFpbmVyID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApO1xuXHRcdGNvbnRhaW5lci5zdHlsZS5jc3NUZXh0ID0gXCJwb3NpdGlvbjphYnNvbHV0ZTtib3JkZXI6MDt3aWR0aDowO2hlaWdodDowO3RvcDowO2xlZnQ6LTk5OTlweFwiO1xuXHRcdGJvZHkuYXBwZW5kQ2hpbGQoIGNvbnRhaW5lciApLmFwcGVuZENoaWxkKCBkaXYgKTtcblxuXHRcdGRpdi5zdHlsZS5jc3NUZXh0ID1cblx0XHRcdC8vIFN1cHBvcnQ6IEZpcmVmb3g8MjksIEFuZHJvaWQgMi4zXG5cdFx0XHQvLyBWZW5kb3ItcHJlZml4IGJveC1zaXppbmdcblx0XHRcdFwiLXdlYmtpdC1ib3gtc2l6aW5nOmJvcmRlci1ib3g7LW1vei1ib3gtc2l6aW5nOmJvcmRlci1ib3g7XCIgK1xuXHRcdFx0XCJib3gtc2l6aW5nOmJvcmRlci1ib3g7ZGlzcGxheTpibG9jazttYXJnaW4tdG9wOjElO3RvcDoxJTtcIiArXG5cdFx0XHRcImJvcmRlcjoxcHg7cGFkZGluZzoxcHg7d2lkdGg6NHB4O3Bvc2l0aW9uOmFic29sdXRlXCI7XG5cblx0XHQvLyBTdXBwb3J0OiBJRTw5XG5cdFx0Ly8gQXNzdW1lIHJlYXNvbmFibGUgdmFsdWVzIGluIHRoZSBhYnNlbmNlIG9mIGdldENvbXB1dGVkU3R5bGVcblx0XHRwaXhlbFBvc2l0aW9uVmFsID0gYm94U2l6aW5nUmVsaWFibGVWYWwgPSBmYWxzZTtcblx0XHRyZWxpYWJsZU1hcmdpblJpZ2h0VmFsID0gdHJ1ZTtcblxuXHRcdC8vIENoZWNrIGZvciBnZXRDb21wdXRlZFN0eWxlIHNvIHRoYXQgdGhpcyBjb2RlIGlzIG5vdCBydW4gaW4gSUU8OS5cblx0XHRpZiAoIHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlICkge1xuXHRcdFx0cGl4ZWxQb3NpdGlvblZhbCA9ICggd2luZG93LmdldENvbXB1dGVkU3R5bGUoIGRpdiwgbnVsbCApIHx8IHt9ICkudG9wICE9PSBcIjElXCI7XG5cdFx0XHRib3hTaXppbmdSZWxpYWJsZVZhbCA9XG5cdFx0XHRcdCggd2luZG93LmdldENvbXB1dGVkU3R5bGUoIGRpdiwgbnVsbCApIHx8IHsgd2lkdGg6IFwiNHB4XCIgfSApLndpZHRoID09PSBcIjRweFwiO1xuXG5cdFx0XHQvLyBTdXBwb3J0OiBBbmRyb2lkIDIuM1xuXHRcdFx0Ly8gRGl2IHdpdGggZXhwbGljaXQgd2lkdGggYW5kIG5vIG1hcmdpbi1yaWdodCBpbmNvcnJlY3RseVxuXHRcdFx0Ly8gZ2V0cyBjb21wdXRlZCBtYXJnaW4tcmlnaHQgYmFzZWQgb24gd2lkdGggb2YgY29udGFpbmVyICgjMzMzMylcblx0XHRcdC8vIFdlYktpdCBCdWcgMTMzNDMgLSBnZXRDb21wdXRlZFN0eWxlIHJldHVybnMgd3JvbmcgdmFsdWUgZm9yIG1hcmdpbi1yaWdodFxuXHRcdFx0Y29udGVudHMgPSBkaXYuYXBwZW5kQ2hpbGQoIGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiZGl2XCIgKSApO1xuXG5cdFx0XHQvLyBSZXNldCBDU1M6IGJveC1zaXppbmc7IGRpc3BsYXk7IG1hcmdpbjsgYm9yZGVyOyBwYWRkaW5nXG5cdFx0XHRjb250ZW50cy5zdHlsZS5jc3NUZXh0ID0gZGl2LnN0eWxlLmNzc1RleHQgPVxuXHRcdFx0XHQvLyBTdXBwb3J0OiBGaXJlZm94PDI5LCBBbmRyb2lkIDIuM1xuXHRcdFx0XHQvLyBWZW5kb3ItcHJlZml4IGJveC1zaXppbmdcblx0XHRcdFx0XCItd2Via2l0LWJveC1zaXppbmc6Y29udGVudC1ib3g7LW1vei1ib3gtc2l6aW5nOmNvbnRlbnQtYm94O1wiICtcblx0XHRcdFx0XCJib3gtc2l6aW5nOmNvbnRlbnQtYm94O2Rpc3BsYXk6YmxvY2s7bWFyZ2luOjA7Ym9yZGVyOjA7cGFkZGluZzowXCI7XG5cdFx0XHRjb250ZW50cy5zdHlsZS5tYXJnaW5SaWdodCA9IGNvbnRlbnRzLnN0eWxlLndpZHRoID0gXCIwXCI7XG5cdFx0XHRkaXYuc3R5bGUud2lkdGggPSBcIjFweFwiO1xuXG5cdFx0XHRyZWxpYWJsZU1hcmdpblJpZ2h0VmFsID1cblx0XHRcdFx0IXBhcnNlRmxvYXQoICggd2luZG93LmdldENvbXB1dGVkU3R5bGUoIGNvbnRlbnRzLCBudWxsICkgfHwge30gKS5tYXJnaW5SaWdodCApO1xuXG5cdFx0XHRkaXYucmVtb3ZlQ2hpbGQoIGNvbnRlbnRzICk7XG5cdFx0fVxuXG5cdFx0Ly8gU3VwcG9ydDogSUU4XG5cdFx0Ly8gQ2hlY2sgaWYgdGFibGUgY2VsbHMgc3RpbGwgaGF2ZSBvZmZzZXRXaWR0aC9IZWlnaHQgd2hlbiB0aGV5IGFyZSBzZXRcblx0XHQvLyB0byBkaXNwbGF5Om5vbmUgYW5kIHRoZXJlIGFyZSBzdGlsbCBvdGhlciB2aXNpYmxlIHRhYmxlIGNlbGxzIGluIGFcblx0XHQvLyB0YWJsZSByb3c7IGlmIHNvLCBvZmZzZXRXaWR0aC9IZWlnaHQgYXJlIG5vdCByZWxpYWJsZSBmb3IgdXNlIHdoZW5cblx0XHQvLyBkZXRlcm1pbmluZyBpZiBhbiBlbGVtZW50IGhhcyBiZWVuIGhpZGRlbiBkaXJlY3RseSB1c2luZ1xuXHRcdC8vIGRpc3BsYXk6bm9uZSAoaXQgaXMgc3RpbGwgc2FmZSB0byB1c2Ugb2Zmc2V0cyBpZiBhIHBhcmVudCBlbGVtZW50IGlzXG5cdFx0Ly8gaGlkZGVuOyBkb24gc2FmZXR5IGdvZ2dsZXMgYW5kIHNlZSBidWcgIzQ1MTIgZm9yIG1vcmUgaW5mb3JtYXRpb24pLlxuXHRcdGRpdi5pbm5lckhUTUwgPSBcIjx0YWJsZT48dHI+PHRkPjwvdGQ+PHRkPnQ8L3RkPjwvdHI+PC90YWJsZT5cIjtcblx0XHRjb250ZW50cyA9IGRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZSggXCJ0ZFwiICk7XG5cdFx0Y29udGVudHNbIDAgXS5zdHlsZS5jc3NUZXh0ID0gXCJtYXJnaW46MDtib3JkZXI6MDtwYWRkaW5nOjA7ZGlzcGxheTpub25lXCI7XG5cdFx0cmVsaWFibGVIaWRkZW5PZmZzZXRzVmFsID0gY29udGVudHNbIDAgXS5vZmZzZXRIZWlnaHQgPT09IDA7XG5cdFx0aWYgKCByZWxpYWJsZUhpZGRlbk9mZnNldHNWYWwgKSB7XG5cdFx0XHRjb250ZW50c1sgMCBdLnN0eWxlLmRpc3BsYXkgPSBcIlwiO1xuXHRcdFx0Y29udGVudHNbIDEgXS5zdHlsZS5kaXNwbGF5ID0gXCJub25lXCI7XG5cdFx0XHRyZWxpYWJsZUhpZGRlbk9mZnNldHNWYWwgPSBjb250ZW50c1sgMCBdLm9mZnNldEhlaWdodCA9PT0gMDtcblx0XHR9XG5cblx0XHRib2R5LnJlbW92ZUNoaWxkKCBjb250YWluZXIgKTtcblx0fVxuXG59KSgpO1xuXG5cbi8vIEEgbWV0aG9kIGZvciBxdWlja2x5IHN3YXBwaW5nIGluL291dCBDU1MgcHJvcGVydGllcyB0byBnZXQgY29ycmVjdCBjYWxjdWxhdGlvbnMuXG5qUXVlcnkuc3dhcCA9IGZ1bmN0aW9uKCBlbGVtLCBvcHRpb25zLCBjYWxsYmFjaywgYXJncyApIHtcblx0dmFyIHJldCwgbmFtZSxcblx0XHRvbGQgPSB7fTtcblxuXHQvLyBSZW1lbWJlciB0aGUgb2xkIHZhbHVlcywgYW5kIGluc2VydCB0aGUgbmV3IG9uZXNcblx0Zm9yICggbmFtZSBpbiBvcHRpb25zICkge1xuXHRcdG9sZFsgbmFtZSBdID0gZWxlbS5zdHlsZVsgbmFtZSBdO1xuXHRcdGVsZW0uc3R5bGVbIG5hbWUgXSA9IG9wdGlvbnNbIG5hbWUgXTtcblx0fVxuXG5cdHJldCA9IGNhbGxiYWNrLmFwcGx5KCBlbGVtLCBhcmdzIHx8IFtdICk7XG5cblx0Ly8gUmV2ZXJ0IHRoZSBvbGQgdmFsdWVzXG5cdGZvciAoIG5hbWUgaW4gb3B0aW9ucyApIHtcblx0XHRlbGVtLnN0eWxlWyBuYW1lIF0gPSBvbGRbIG5hbWUgXTtcblx0fVxuXG5cdHJldHVybiByZXQ7XG59O1xuXG5cbnZhclxuXHRcdHJhbHBoYSA9IC9hbHBoYVxcKFteKV0qXFwpL2ksXG5cdHJvcGFjaXR5ID0gL29wYWNpdHlcXHMqPVxccyooW14pXSopLyxcblxuXHQvLyBzd2FwcGFibGUgaWYgZGlzcGxheSBpcyBub25lIG9yIHN0YXJ0cyB3aXRoIHRhYmxlIGV4Y2VwdCBcInRhYmxlXCIsIFwidGFibGUtY2VsbFwiLCBvciBcInRhYmxlLWNhcHRpb25cIlxuXHQvLyBzZWUgaGVyZSBmb3IgZGlzcGxheSB2YWx1ZXM6IGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvQ1NTL2Rpc3BsYXlcblx0cmRpc3BsYXlzd2FwID0gL14obm9uZXx0YWJsZSg/IS1jW2VhXSkuKykvLFxuXHRybnVtc3BsaXQgPSBuZXcgUmVnRXhwKCBcIl4oXCIgKyBwbnVtICsgXCIpKC4qKSRcIiwgXCJpXCIgKSxcblx0cnJlbE51bSA9IG5ldyBSZWdFeHAoIFwiXihbKy1dKT0oXCIgKyBwbnVtICsgXCIpXCIsIFwiaVwiICksXG5cblx0Y3NzU2hvdyA9IHsgcG9zaXRpb246IFwiYWJzb2x1dGVcIiwgdmlzaWJpbGl0eTogXCJoaWRkZW5cIiwgZGlzcGxheTogXCJibG9ja1wiIH0sXG5cdGNzc05vcm1hbFRyYW5zZm9ybSA9IHtcblx0XHRsZXR0ZXJTcGFjaW5nOiBcIjBcIixcblx0XHRmb250V2VpZ2h0OiBcIjQwMFwiXG5cdH0sXG5cblx0Y3NzUHJlZml4ZXMgPSBbIFwiV2Via2l0XCIsIFwiT1wiLCBcIk1velwiLCBcIm1zXCIgXTtcblxuXG4vLyByZXR1cm4gYSBjc3MgcHJvcGVydHkgbWFwcGVkIHRvIGEgcG90ZW50aWFsbHkgdmVuZG9yIHByZWZpeGVkIHByb3BlcnR5XG5mdW5jdGlvbiB2ZW5kb3JQcm9wTmFtZSggc3R5bGUsIG5hbWUgKSB7XG5cblx0Ly8gc2hvcnRjdXQgZm9yIG5hbWVzIHRoYXQgYXJlIG5vdCB2ZW5kb3IgcHJlZml4ZWRcblx0aWYgKCBuYW1lIGluIHN0eWxlICkge1xuXHRcdHJldHVybiBuYW1lO1xuXHR9XG5cblx0Ly8gY2hlY2sgZm9yIHZlbmRvciBwcmVmaXhlZCBuYW1lc1xuXHR2YXIgY2FwTmFtZSA9IG5hbWUuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBuYW1lLnNsaWNlKDEpLFxuXHRcdG9yaWdOYW1lID0gbmFtZSxcblx0XHRpID0gY3NzUHJlZml4ZXMubGVuZ3RoO1xuXG5cdHdoaWxlICggaS0tICkge1xuXHRcdG5hbWUgPSBjc3NQcmVmaXhlc1sgaSBdICsgY2FwTmFtZTtcblx0XHRpZiAoIG5hbWUgaW4gc3R5bGUgKSB7XG5cdFx0XHRyZXR1cm4gbmFtZTtcblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gb3JpZ05hbWU7XG59XG5cbmZ1bmN0aW9uIHNob3dIaWRlKCBlbGVtZW50cywgc2hvdyApIHtcblx0dmFyIGRpc3BsYXksIGVsZW0sIGhpZGRlbixcblx0XHR2YWx1ZXMgPSBbXSxcblx0XHRpbmRleCA9IDAsXG5cdFx0bGVuZ3RoID0gZWxlbWVudHMubGVuZ3RoO1xuXG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xuXHRcdGlmICggIWVsZW0uc3R5bGUgKSB7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cblx0XHR2YWx1ZXNbIGluZGV4IF0gPSBqUXVlcnkuX2RhdGEoIGVsZW0sIFwib2xkZGlzcGxheVwiICk7XG5cdFx0ZGlzcGxheSA9IGVsZW0uc3R5bGUuZGlzcGxheTtcblx0XHRpZiAoIHNob3cgKSB7XG5cdFx0XHQvLyBSZXNldCB0aGUgaW5saW5lIGRpc3BsYXkgb2YgdGhpcyBlbGVtZW50IHRvIGxlYXJuIGlmIGl0IGlzXG5cdFx0XHQvLyBiZWluZyBoaWRkZW4gYnkgY2FzY2FkZWQgcnVsZXMgb3Igbm90XG5cdFx0XHRpZiAoICF2YWx1ZXNbIGluZGV4IF0gJiYgZGlzcGxheSA9PT0gXCJub25lXCIgKSB7XG5cdFx0XHRcdGVsZW0uc3R5bGUuZGlzcGxheSA9IFwiXCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCBlbGVtZW50cyB3aGljaCBoYXZlIGJlZW4gb3ZlcnJpZGRlbiB3aXRoIGRpc3BsYXk6IG5vbmVcblx0XHRcdC8vIGluIGEgc3R5bGVzaGVldCB0byB3aGF0ZXZlciB0aGUgZGVmYXVsdCBicm93c2VyIHN0eWxlIGlzXG5cdFx0XHQvLyBmb3Igc3VjaCBhbiBlbGVtZW50XG5cdFx0XHRpZiAoIGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJcIiAmJiBpc0hpZGRlbiggZWxlbSApICkge1xuXHRcdFx0XHR2YWx1ZXNbIGluZGV4IF0gPSBqUXVlcnkuX2RhdGEoIGVsZW0sIFwib2xkZGlzcGxheVwiLCBkZWZhdWx0RGlzcGxheShlbGVtLm5vZGVOYW1lKSApO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHRoaWRkZW4gPSBpc0hpZGRlbiggZWxlbSApO1xuXG5cdFx0XHRpZiAoIGRpc3BsYXkgJiYgZGlzcGxheSAhPT0gXCJub25lXCIgfHwgIWhpZGRlbiApIHtcblx0XHRcdFx0alF1ZXJ5Ll9kYXRhKCBlbGVtLCBcIm9sZGRpc3BsYXlcIiwgaGlkZGVuID8gZGlzcGxheSA6IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICkgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHQvLyBTZXQgdGhlIGRpc3BsYXkgb2YgbW9zdCBvZiB0aGUgZWxlbWVudHMgaW4gYSBzZWNvbmQgbG9vcFxuXHQvLyB0byBhdm9pZCB0aGUgY29uc3RhbnQgcmVmbG93XG5cdGZvciAoIGluZGV4ID0gMDsgaW5kZXggPCBsZW5ndGg7IGluZGV4KysgKSB7XG5cdFx0ZWxlbSA9IGVsZW1lbnRzWyBpbmRleCBdO1xuXHRcdGlmICggIWVsZW0uc3R5bGUgKSB7XG5cdFx0XHRjb250aW51ZTtcblx0XHR9XG5cdFx0aWYgKCAhc2hvdyB8fCBlbGVtLnN0eWxlLmRpc3BsYXkgPT09IFwibm9uZVwiIHx8IGVsZW0uc3R5bGUuZGlzcGxheSA9PT0gXCJcIiApIHtcblx0XHRcdGVsZW0uc3R5bGUuZGlzcGxheSA9IHNob3cgPyB2YWx1ZXNbIGluZGV4IF0gfHwgXCJcIiA6IFwibm9uZVwiO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtZW50cztcbn1cblxuZnVuY3Rpb24gc2V0UG9zaXRpdmVOdW1iZXIoIGVsZW0sIHZhbHVlLCBzdWJ0cmFjdCApIHtcblx0dmFyIG1hdGNoZXMgPSBybnVtc3BsaXQuZXhlYyggdmFsdWUgKTtcblx0cmV0dXJuIG1hdGNoZXMgP1xuXHRcdC8vIEd1YXJkIGFnYWluc3QgdW5kZWZpbmVkIFwic3VidHJhY3RcIiwgZS5nLiwgd2hlbiB1c2VkIGFzIGluIGNzc0hvb2tzXG5cdFx0TWF0aC5tYXgoIDAsIG1hdGNoZXNbIDEgXSAtICggc3VidHJhY3QgfHwgMCApICkgKyAoIG1hdGNoZXNbIDIgXSB8fCBcInB4XCIgKSA6XG5cdFx0dmFsdWU7XG59XG5cbmZ1bmN0aW9uIGF1Z21lbnRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSwgaXNCb3JkZXJCb3gsIHN0eWxlcyApIHtcblx0dmFyIGkgPSBleHRyYSA9PT0gKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApID9cblx0XHQvLyBJZiB3ZSBhbHJlYWR5IGhhdmUgdGhlIHJpZ2h0IG1lYXN1cmVtZW50LCBhdm9pZCBhdWdtZW50YXRpb25cblx0XHQ0IDpcblx0XHQvLyBPdGhlcndpc2UgaW5pdGlhbGl6ZSBmb3IgaG9yaXpvbnRhbCBvciB2ZXJ0aWNhbCBwcm9wZXJ0aWVzXG5cdFx0bmFtZSA9PT0gXCJ3aWR0aFwiID8gMSA6IDAsXG5cblx0XHR2YWwgPSAwO1xuXG5cdGZvciAoIDsgaSA8IDQ7IGkgKz0gMiApIHtcblx0XHQvLyBib3RoIGJveCBtb2RlbHMgZXhjbHVkZSBtYXJnaW4sIHNvIGFkZCBpdCBpZiB3ZSB3YW50IGl0XG5cdFx0aWYgKCBleHRyYSA9PT0gXCJtYXJnaW5cIiApIHtcblx0XHRcdHZhbCArPSBqUXVlcnkuY3NzKCBlbGVtLCBleHRyYSArIGNzc0V4cGFuZFsgaSBdLCB0cnVlLCBzdHlsZXMgKTtcblx0XHR9XG5cblx0XHRpZiAoIGlzQm9yZGVyQm94ICkge1xuXHRcdFx0Ly8gYm9yZGVyLWJveCBpbmNsdWRlcyBwYWRkaW5nLCBzbyByZW1vdmUgaXQgaWYgd2Ugd2FudCBjb250ZW50XG5cdFx0XHRpZiAoIGV4dHJhID09PSBcImNvbnRlbnRcIiApIHtcblx0XHRcdFx0dmFsIC09IGpRdWVyeS5jc3MoIGVsZW0sIFwicGFkZGluZ1wiICsgY3NzRXhwYW5kWyBpIF0sIHRydWUsIHN0eWxlcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBhdCB0aGlzIHBvaW50LCBleHRyYSBpc24ndCBib3JkZXIgbm9yIG1hcmdpbiwgc28gcmVtb3ZlIGJvcmRlclxuXHRcdFx0aWYgKCBleHRyYSAhPT0gXCJtYXJnaW5cIiApIHtcblx0XHRcdFx0dmFsIC09IGpRdWVyeS5jc3MoIGVsZW0sIFwiYm9yZGVyXCIgKyBjc3NFeHBhbmRbIGkgXSArIFwiV2lkdGhcIiwgdHJ1ZSwgc3R5bGVzICk7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIGF0IHRoaXMgcG9pbnQsIGV4dHJhIGlzbid0IGNvbnRlbnQsIHNvIGFkZCBwYWRkaW5nXG5cdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgXCJwYWRkaW5nXCIgKyBjc3NFeHBhbmRbIGkgXSwgdHJ1ZSwgc3R5bGVzICk7XG5cblx0XHRcdC8vIGF0IHRoaXMgcG9pbnQsIGV4dHJhIGlzbid0IGNvbnRlbnQgbm9yIHBhZGRpbmcsIHNvIGFkZCBib3JkZXJcblx0XHRcdGlmICggZXh0cmEgIT09IFwicGFkZGluZ1wiICkge1xuXHRcdFx0XHR2YWwgKz0galF1ZXJ5LmNzcyggZWxlbSwgXCJib3JkZXJcIiArIGNzc0V4cGFuZFsgaSBdICsgXCJXaWR0aFwiLCB0cnVlLCBzdHlsZXMgKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gdmFsO1xufVxuXG5mdW5jdGlvbiBnZXRXaWR0aE9ySGVpZ2h0KCBlbGVtLCBuYW1lLCBleHRyYSApIHtcblxuXHQvLyBTdGFydCB3aXRoIG9mZnNldCBwcm9wZXJ0eSwgd2hpY2ggaXMgZXF1aXZhbGVudCB0byB0aGUgYm9yZGVyLWJveCB2YWx1ZVxuXHR2YXIgdmFsdWVJc0JvcmRlckJveCA9IHRydWUsXG5cdFx0dmFsID0gbmFtZSA9PT0gXCJ3aWR0aFwiID8gZWxlbS5vZmZzZXRXaWR0aCA6IGVsZW0ub2Zmc2V0SGVpZ2h0LFxuXHRcdHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApLFxuXHRcdGlzQm9yZGVyQm94ID0gc3VwcG9ydC5ib3hTaXppbmcgJiYgalF1ZXJ5LmNzcyggZWxlbSwgXCJib3hTaXppbmdcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImJvcmRlci1ib3hcIjtcblxuXHQvLyBzb21lIG5vbi1odG1sIGVsZW1lbnRzIHJldHVybiB1bmRlZmluZWQgZm9yIG9mZnNldFdpZHRoLCBzbyBjaGVjayBmb3IgbnVsbC91bmRlZmluZWRcblx0Ly8gc3ZnIC0gaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9NjQ5Mjg1XG5cdC8vIE1hdGhNTCAtIGh0dHBzOi8vYnVnemlsbGEubW96aWxsYS5vcmcvc2hvd19idWcuY2dpP2lkPTQ5MTY2OFxuXHRpZiAoIHZhbCA8PSAwIHx8IHZhbCA9PSBudWxsICkge1xuXHRcdC8vIEZhbGwgYmFjayB0byBjb21wdXRlZCB0aGVuIHVuY29tcHV0ZWQgY3NzIGlmIG5lY2Vzc2FyeVxuXHRcdHZhbCA9IGN1ckNTUyggZWxlbSwgbmFtZSwgc3R5bGVzICk7XG5cdFx0aWYgKCB2YWwgPCAwIHx8IHZhbCA9PSBudWxsICkge1xuXHRcdFx0dmFsID0gZWxlbS5zdHlsZVsgbmFtZSBdO1xuXHRcdH1cblxuXHRcdC8vIENvbXB1dGVkIHVuaXQgaXMgbm90IHBpeGVscy4gU3RvcCBoZXJlIGFuZCByZXR1cm4uXG5cdFx0aWYgKCBybnVtbm9ucHgudGVzdCh2YWwpICkge1xuXHRcdFx0cmV0dXJuIHZhbDtcblx0XHR9XG5cblx0XHQvLyB3ZSBuZWVkIHRoZSBjaGVjayBmb3Igc3R5bGUgaW4gY2FzZSBhIGJyb3dzZXIgd2hpY2ggcmV0dXJucyB1bnJlbGlhYmxlIHZhbHVlc1xuXHRcdC8vIGZvciBnZXRDb21wdXRlZFN0eWxlIHNpbGVudGx5IGZhbGxzIGJhY2sgdG8gdGhlIHJlbGlhYmxlIGVsZW0uc3R5bGVcblx0XHR2YWx1ZUlzQm9yZGVyQm94ID0gaXNCb3JkZXJCb3ggJiYgKCBzdXBwb3J0LmJveFNpemluZ1JlbGlhYmxlKCkgfHwgdmFsID09PSBlbGVtLnN0eWxlWyBuYW1lIF0gKTtcblxuXHRcdC8vIE5vcm1hbGl6ZSBcIlwiLCBhdXRvLCBhbmQgcHJlcGFyZSBmb3IgZXh0cmFcblx0XHR2YWwgPSBwYXJzZUZsb2F0KCB2YWwgKSB8fCAwO1xuXHR9XG5cblx0Ly8gdXNlIHRoZSBhY3RpdmUgYm94LXNpemluZyBtb2RlbCB0byBhZGQvc3VidHJhY3QgaXJyZWxldmFudCBzdHlsZXNcblx0cmV0dXJuICggdmFsICtcblx0XHRhdWdtZW50V2lkdGhPckhlaWdodChcblx0XHRcdGVsZW0sXG5cdFx0XHRuYW1lLFxuXHRcdFx0ZXh0cmEgfHwgKCBpc0JvcmRlckJveCA/IFwiYm9yZGVyXCIgOiBcImNvbnRlbnRcIiApLFxuXHRcdFx0dmFsdWVJc0JvcmRlckJveCxcblx0XHRcdHN0eWxlc1xuXHRcdClcblx0KSArIFwicHhcIjtcbn1cblxualF1ZXJ5LmV4dGVuZCh7XG5cdC8vIEFkZCBpbiBzdHlsZSBwcm9wZXJ0eSBob29rcyBmb3Igb3ZlcnJpZGluZyB0aGUgZGVmYXVsdFxuXHQvLyBiZWhhdmlvciBvZiBnZXR0aW5nIGFuZCBzZXR0aW5nIGEgc3R5bGUgcHJvcGVydHlcblx0Y3NzSG9va3M6IHtcblx0XHRvcGFjaXR5OiB7XG5cdFx0XHRnZXQ6IGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRcdFx0aWYgKCBjb21wdXRlZCApIHtcblx0XHRcdFx0XHQvLyBXZSBzaG91bGQgYWx3YXlzIGdldCBhIG51bWJlciBiYWNrIGZyb20gb3BhY2l0eVxuXHRcdFx0XHRcdHZhciByZXQgPSBjdXJDU1MoIGVsZW0sIFwib3BhY2l0eVwiICk7XG5cdFx0XHRcdFx0cmV0dXJuIHJldCA9PT0gXCJcIiA/IFwiMVwiIDogcmV0O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXG5cdC8vIERvbid0IGF1dG9tYXRpY2FsbHkgYWRkIFwicHhcIiB0byB0aGVzZSBwb3NzaWJseS11bml0bGVzcyBwcm9wZXJ0aWVzXG5cdGNzc051bWJlcjoge1xuXHRcdFwiY29sdW1uQ291bnRcIjogdHJ1ZSxcblx0XHRcImZpbGxPcGFjaXR5XCI6IHRydWUsXG5cdFx0XCJmbGV4R3Jvd1wiOiB0cnVlLFxuXHRcdFwiZmxleFNocmlua1wiOiB0cnVlLFxuXHRcdFwiZm9udFdlaWdodFwiOiB0cnVlLFxuXHRcdFwibGluZUhlaWdodFwiOiB0cnVlLFxuXHRcdFwib3BhY2l0eVwiOiB0cnVlLFxuXHRcdFwib3JkZXJcIjogdHJ1ZSxcblx0XHRcIm9ycGhhbnNcIjogdHJ1ZSxcblx0XHRcIndpZG93c1wiOiB0cnVlLFxuXHRcdFwiekluZGV4XCI6IHRydWUsXG5cdFx0XCJ6b29tXCI6IHRydWVcblx0fSxcblxuXHQvLyBBZGQgaW4gcHJvcGVydGllcyB3aG9zZSBuYW1lcyB5b3Ugd2lzaCB0byBmaXggYmVmb3JlXG5cdC8vIHNldHRpbmcgb3IgZ2V0dGluZyB0aGUgdmFsdWVcblx0Y3NzUHJvcHM6IHtcblx0XHQvLyBub3JtYWxpemUgZmxvYXQgY3NzIHByb3BlcnR5XG5cdFx0XCJmbG9hdFwiOiBzdXBwb3J0LmNzc0Zsb2F0ID8gXCJjc3NGbG9hdFwiIDogXCJzdHlsZUZsb2F0XCJcblx0fSxcblxuXHQvLyBHZXQgYW5kIHNldCB0aGUgc3R5bGUgcHJvcGVydHkgb24gYSBET00gTm9kZVxuXHRzdHlsZTogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIHZhbHVlLCBleHRyYSApIHtcblx0XHQvLyBEb24ndCBzZXQgc3R5bGVzIG9uIHRleHQgYW5kIGNvbW1lbnQgbm9kZXNcblx0XHRpZiAoICFlbGVtIHx8IGVsZW0ubm9kZVR5cGUgPT09IDMgfHwgZWxlbS5ub2RlVHlwZSA9PT0gOCB8fCAhZWxlbS5zdHlsZSApIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHQvLyBNYWtlIHN1cmUgdGhhdCB3ZSdyZSB3b3JraW5nIHdpdGggdGhlIHJpZ2h0IG5hbWVcblx0XHR2YXIgcmV0LCB0eXBlLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggbmFtZSApLFxuXHRcdFx0c3R5bGUgPSBlbGVtLnN0eWxlO1xuXG5cdFx0bmFtZSA9IGpRdWVyeS5jc3NQcm9wc1sgb3JpZ05hbWUgXSB8fCAoIGpRdWVyeS5jc3NQcm9wc1sgb3JpZ05hbWUgXSA9IHZlbmRvclByb3BOYW1lKCBzdHlsZSwgb3JpZ05hbWUgKSApO1xuXG5cdFx0Ly8gZ2V0cyBob29rIGZvciB0aGUgcHJlZml4ZWQgdmVyc2lvblxuXHRcdC8vIGZvbGxvd2VkIGJ5IHRoZSB1bnByZWZpeGVkIHZlcnNpb25cblx0XHRob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdIHx8IGpRdWVyeS5jc3NIb29rc1sgb3JpZ05hbWUgXTtcblxuXHRcdC8vIENoZWNrIGlmIHdlJ3JlIHNldHRpbmcgYSB2YWx1ZVxuXHRcdGlmICggdmFsdWUgIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdHR5cGUgPSB0eXBlb2YgdmFsdWU7XG5cblx0XHRcdC8vIGNvbnZlcnQgcmVsYXRpdmUgbnVtYmVyIHN0cmluZ3MgKCs9IG9yIC09KSB0byByZWxhdGl2ZSBudW1iZXJzLiAjNzM0NVxuXHRcdFx0aWYgKCB0eXBlID09PSBcInN0cmluZ1wiICYmIChyZXQgPSBycmVsTnVtLmV4ZWMoIHZhbHVlICkpICkge1xuXHRcdFx0XHR2YWx1ZSA9ICggcmV0WzFdICsgMSApICogcmV0WzJdICsgcGFyc2VGbG9hdCggalF1ZXJ5LmNzcyggZWxlbSwgbmFtZSApICk7XG5cdFx0XHRcdC8vIEZpeGVzIGJ1ZyAjOTIzN1xuXHRcdFx0XHR0eXBlID0gXCJudW1iZXJcIjtcblx0XHRcdH1cblxuXHRcdFx0Ly8gTWFrZSBzdXJlIHRoYXQgbnVsbCBhbmQgTmFOIHZhbHVlcyBhcmVuJ3Qgc2V0LiBTZWU6ICM3MTE2XG5cdFx0XHRpZiAoIHZhbHVlID09IG51bGwgfHwgdmFsdWUgIT09IHZhbHVlICkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGEgbnVtYmVyIHdhcyBwYXNzZWQgaW4sIGFkZCAncHgnIHRvIHRoZSAoZXhjZXB0IGZvciBjZXJ0YWluIENTUyBwcm9wZXJ0aWVzKVxuXHRcdFx0aWYgKCB0eXBlID09PSBcIm51bWJlclwiICYmICFqUXVlcnkuY3NzTnVtYmVyWyBvcmlnTmFtZSBdICkge1xuXHRcdFx0XHR2YWx1ZSArPSBcInB4XCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIEZpeGVzICM4OTA4LCBpdCBjYW4gYmUgZG9uZSBtb3JlIGNvcnJlY3RseSBieSBzcGVjaWZpbmcgc2V0dGVycyBpbiBjc3NIb29rcyxcblx0XHRcdC8vIGJ1dCBpdCB3b3VsZCBtZWFuIHRvIGRlZmluZSBlaWdodCAoZm9yIGV2ZXJ5IHByb2JsZW1hdGljIHByb3BlcnR5KSBpZGVudGljYWwgZnVuY3Rpb25zXG5cdFx0XHRpZiAoICFzdXBwb3J0LmNsZWFyQ2xvbmVTdHlsZSAmJiB2YWx1ZSA9PT0gXCJcIiAmJiBuYW1lLmluZGV4T2YoXCJiYWNrZ3JvdW5kXCIpID09PSAwICkge1xuXHRcdFx0XHRzdHlsZVsgbmFtZSBdID0gXCJpbmhlcml0XCI7XG5cdFx0XHR9XG5cblx0XHRcdC8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQsIHVzZSB0aGF0IHZhbHVlLCBvdGhlcndpc2UganVzdCBzZXQgdGhlIHNwZWNpZmllZCB2YWx1ZVxuXHRcdFx0aWYgKCAhaG9va3MgfHwgIShcInNldFwiIGluIGhvb2tzKSB8fCAodmFsdWUgPSBob29rcy5zZXQoIGVsZW0sIHZhbHVlLCBleHRyYSApKSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRcdC8vIFN1cHBvcnQ6IElFXG5cdFx0XHRcdC8vIFN3YWxsb3cgZXJyb3JzIGZyb20gJ2ludmFsaWQnIENTUyB2YWx1ZXMgKCM1NTA5KVxuXHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdHN0eWxlWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdFx0fSBjYXRjaChlKSB7fVxuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIElmIGEgaG9vayB3YXMgcHJvdmlkZWQgZ2V0IHRoZSBub24tY29tcHV0ZWQgdmFsdWUgZnJvbSB0aGVyZVxuXHRcdFx0aWYgKCBob29rcyAmJiBcImdldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5nZXQoIGVsZW0sIGZhbHNlLCBleHRyYSApKSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0XHRyZXR1cm4gcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBPdGhlcndpc2UganVzdCBnZXQgdGhlIHZhbHVlIGZyb20gdGhlIHN0eWxlIG9iamVjdFxuXHRcdFx0cmV0dXJuIHN0eWxlWyBuYW1lIF07XG5cdFx0fVxuXHR9LFxuXG5cdGNzczogZnVuY3Rpb24oIGVsZW0sIG5hbWUsIGV4dHJhLCBzdHlsZXMgKSB7XG5cdFx0dmFyIG51bSwgdmFsLCBob29rcyxcblx0XHRcdG9yaWdOYW1lID0galF1ZXJ5LmNhbWVsQ2FzZSggbmFtZSApO1xuXG5cdFx0Ly8gTWFrZSBzdXJlIHRoYXQgd2UncmUgd29ya2luZyB3aXRoIHRoZSByaWdodCBuYW1lXG5cdFx0bmFtZSA9IGpRdWVyeS5jc3NQcm9wc1sgb3JpZ05hbWUgXSB8fCAoIGpRdWVyeS5jc3NQcm9wc1sgb3JpZ05hbWUgXSA9IHZlbmRvclByb3BOYW1lKCBlbGVtLnN0eWxlLCBvcmlnTmFtZSApICk7XG5cblx0XHQvLyBnZXRzIGhvb2sgZm9yIHRoZSBwcmVmaXhlZCB2ZXJzaW9uXG5cdFx0Ly8gZm9sbG93ZWQgYnkgdGhlIHVucHJlZml4ZWQgdmVyc2lvblxuXHRcdGhvb2tzID0galF1ZXJ5LmNzc0hvb2tzWyBuYW1lIF0gfHwgalF1ZXJ5LmNzc0hvb2tzWyBvcmlnTmFtZSBdO1xuXG5cdFx0Ly8gSWYgYSBob29rIHdhcyBwcm92aWRlZCBnZXQgdGhlIGNvbXB1dGVkIHZhbHVlIGZyb20gdGhlcmVcblx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgKSB7XG5cdFx0XHR2YWwgPSBob29rcy5nZXQoIGVsZW0sIHRydWUsIGV4dHJhICk7XG5cdFx0fVxuXG5cdFx0Ly8gT3RoZXJ3aXNlLCBpZiBhIHdheSB0byBnZXQgdGhlIGNvbXB1dGVkIHZhbHVlIGV4aXN0cywgdXNlIHRoYXRcblx0XHRpZiAoIHZhbCA9PT0gdW5kZWZpbmVkICkge1xuXHRcdFx0dmFsID0gY3VyQ1NTKCBlbGVtLCBuYW1lLCBzdHlsZXMgKTtcblx0XHR9XG5cblx0XHQvL2NvbnZlcnQgXCJub3JtYWxcIiB0byBjb21wdXRlZCB2YWx1ZVxuXHRcdGlmICggdmFsID09PSBcIm5vcm1hbFwiICYmIG5hbWUgaW4gY3NzTm9ybWFsVHJhbnNmb3JtICkge1xuXHRcdFx0dmFsID0gY3NzTm9ybWFsVHJhbnNmb3JtWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0Ly8gUmV0dXJuLCBjb252ZXJ0aW5nIHRvIG51bWJlciBpZiBmb3JjZWQgb3IgYSBxdWFsaWZpZXIgd2FzIHByb3ZpZGVkIGFuZCB2YWwgbG9va3MgbnVtZXJpY1xuXHRcdGlmICggZXh0cmEgPT09IFwiXCIgfHwgZXh0cmEgKSB7XG5cdFx0XHRudW0gPSBwYXJzZUZsb2F0KCB2YWwgKTtcblx0XHRcdHJldHVybiBleHRyYSA9PT0gdHJ1ZSB8fCBqUXVlcnkuaXNOdW1lcmljKCBudW0gKSA/IG51bSB8fCAwIDogdmFsO1xuXHRcdH1cblx0XHRyZXR1cm4gdmFsO1xuXHR9XG59KTtcblxualF1ZXJ5LmVhY2goWyBcImhlaWdodFwiLCBcIndpZHRoXCIgXSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cdGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdID0ge1xuXHRcdGdldDogZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkLCBleHRyYSApIHtcblx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cdFx0XHRcdC8vIGNlcnRhaW4gZWxlbWVudHMgY2FuIGhhdmUgZGltZW5zaW9uIGluZm8gaWYgd2UgaW52aXNpYmx5IHNob3cgdGhlbVxuXHRcdFx0XHQvLyBob3dldmVyLCBpdCBtdXN0IGhhdmUgYSBjdXJyZW50IGRpc3BsYXkgc3R5bGUgdGhhdCB3b3VsZCBiZW5lZml0IGZyb20gdGhpc1xuXHRcdFx0XHRyZXR1cm4gcmRpc3BsYXlzd2FwLnRlc3QoIGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICkgKSAmJiBlbGVtLm9mZnNldFdpZHRoID09PSAwID9cblx0XHRcdFx0XHRqUXVlcnkuc3dhcCggZWxlbSwgY3NzU2hvdywgZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4gZ2V0V2lkdGhPckhlaWdodCggZWxlbSwgbmFtZSwgZXh0cmEgKTtcblx0XHRcdFx0XHR9KSA6XG5cdFx0XHRcdFx0Z2V0V2lkdGhPckhlaWdodCggZWxlbSwgbmFtZSwgZXh0cmEgKTtcblx0XHRcdH1cblx0XHR9LFxuXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUsIGV4dHJhICkge1xuXHRcdFx0dmFyIHN0eWxlcyA9IGV4dHJhICYmIGdldFN0eWxlcyggZWxlbSApO1xuXHRcdFx0cmV0dXJuIHNldFBvc2l0aXZlTnVtYmVyKCBlbGVtLCB2YWx1ZSwgZXh0cmEgP1xuXHRcdFx0XHRhdWdtZW50V2lkdGhPckhlaWdodChcblx0XHRcdFx0XHRlbGVtLFxuXHRcdFx0XHRcdG5hbWUsXG5cdFx0XHRcdFx0ZXh0cmEsXG5cdFx0XHRcdFx0c3VwcG9ydC5ib3hTaXppbmcgJiYgalF1ZXJ5LmNzcyggZWxlbSwgXCJib3hTaXppbmdcIiwgZmFsc2UsIHN0eWxlcyApID09PSBcImJvcmRlci1ib3hcIixcblx0XHRcdFx0XHRzdHlsZXNcblx0XHRcdFx0KSA6IDBcblx0XHRcdCk7XG5cdFx0fVxuXHR9O1xufSk7XG5cbmlmICggIXN1cHBvcnQub3BhY2l0eSApIHtcblx0alF1ZXJ5LmNzc0hvb2tzLm9wYWNpdHkgPSB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSwgY29tcHV0ZWQgKSB7XG5cdFx0XHQvLyBJRSB1c2VzIGZpbHRlcnMgZm9yIG9wYWNpdHlcblx0XHRcdHJldHVybiByb3BhY2l0eS50ZXN0KCAoY29tcHV0ZWQgJiYgZWxlbS5jdXJyZW50U3R5bGUgPyBlbGVtLmN1cnJlbnRTdHlsZS5maWx0ZXIgOiBlbGVtLnN0eWxlLmZpbHRlcikgfHwgXCJcIiApID9cblx0XHRcdFx0KCAwLjAxICogcGFyc2VGbG9hdCggUmVnRXhwLiQxICkgKSArIFwiXCIgOlxuXHRcdFx0XHRjb21wdXRlZCA/IFwiMVwiIDogXCJcIjtcblx0XHR9LFxuXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgc3R5bGUgPSBlbGVtLnN0eWxlLFxuXHRcdFx0XHRjdXJyZW50U3R5bGUgPSBlbGVtLmN1cnJlbnRTdHlsZSxcblx0XHRcdFx0b3BhY2l0eSA9IGpRdWVyeS5pc051bWVyaWMoIHZhbHVlICkgPyBcImFscGhhKG9wYWNpdHk9XCIgKyB2YWx1ZSAqIDEwMCArIFwiKVwiIDogXCJcIixcblx0XHRcdFx0ZmlsdGVyID0gY3VycmVudFN0eWxlICYmIGN1cnJlbnRTdHlsZS5maWx0ZXIgfHwgc3R5bGUuZmlsdGVyIHx8IFwiXCI7XG5cblx0XHRcdC8vIElFIGhhcyB0cm91YmxlIHdpdGggb3BhY2l0eSBpZiBpdCBkb2VzIG5vdCBoYXZlIGxheW91dFxuXHRcdFx0Ly8gRm9yY2UgaXQgYnkgc2V0dGluZyB0aGUgem9vbSBsZXZlbFxuXHRcdFx0c3R5bGUuem9vbSA9IDE7XG5cblx0XHRcdC8vIGlmIHNldHRpbmcgb3BhY2l0eSB0byAxLCBhbmQgbm8gb3RoZXIgZmlsdGVycyBleGlzdCAtIGF0dGVtcHQgdG8gcmVtb3ZlIGZpbHRlciBhdHRyaWJ1dGUgIzY2NTJcblx0XHRcdC8vIGlmIHZhbHVlID09PSBcIlwiLCB0aGVuIHJlbW92ZSBpbmxpbmUgb3BhY2l0eSAjMTI2ODVcblx0XHRcdGlmICggKCB2YWx1ZSA+PSAxIHx8IHZhbHVlID09PSBcIlwiICkgJiZcblx0XHRcdFx0XHRqUXVlcnkudHJpbSggZmlsdGVyLnJlcGxhY2UoIHJhbHBoYSwgXCJcIiApICkgPT09IFwiXCIgJiZcblx0XHRcdFx0XHRzdHlsZS5yZW1vdmVBdHRyaWJ1dGUgKSB7XG5cblx0XHRcdFx0Ly8gU2V0dGluZyBzdHlsZS5maWx0ZXIgdG8gbnVsbCwgXCJcIiAmIFwiIFwiIHN0aWxsIGxlYXZlIFwiZmlsdGVyOlwiIGluIHRoZSBjc3NUZXh0XG5cdFx0XHRcdC8vIGlmIFwiZmlsdGVyOlwiIGlzIHByZXNlbnQgYXQgYWxsLCBjbGVhclR5cGUgaXMgZGlzYWJsZWQsIHdlIHdhbnQgdG8gYXZvaWQgdGhpc1xuXHRcdFx0XHQvLyBzdHlsZS5yZW1vdmVBdHRyaWJ1dGUgaXMgSUUgT25seSwgYnV0IHNvIGFwcGFyZW50bHkgaXMgdGhpcyBjb2RlIHBhdGguLi5cblx0XHRcdFx0c3R5bGUucmVtb3ZlQXR0cmlidXRlKCBcImZpbHRlclwiICk7XG5cblx0XHRcdFx0Ly8gaWYgdGhlcmUgaXMgbm8gZmlsdGVyIHN0eWxlIGFwcGxpZWQgaW4gYSBjc3MgcnVsZSBvciB1bnNldCBpbmxpbmUgb3BhY2l0eSwgd2UgYXJlIGRvbmVcblx0XHRcdFx0aWYgKCB2YWx1ZSA9PT0gXCJcIiB8fCBjdXJyZW50U3R5bGUgJiYgIWN1cnJlbnRTdHlsZS5maWx0ZXIgKSB7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIG90aGVyd2lzZSwgc2V0IG5ldyBmaWx0ZXIgdmFsdWVzXG5cdFx0XHRzdHlsZS5maWx0ZXIgPSByYWxwaGEudGVzdCggZmlsdGVyICkgP1xuXHRcdFx0XHRmaWx0ZXIucmVwbGFjZSggcmFscGhhLCBvcGFjaXR5ICkgOlxuXHRcdFx0XHRmaWx0ZXIgKyBcIiBcIiArIG9wYWNpdHk7XG5cdFx0fVxuXHR9O1xufVxuXG5qUXVlcnkuY3NzSG9va3MubWFyZ2luUmlnaHQgPSBhZGRHZXRIb29rSWYoIHN1cHBvcnQucmVsaWFibGVNYXJnaW5SaWdodCxcblx0ZnVuY3Rpb24oIGVsZW0sIGNvbXB1dGVkICkge1xuXHRcdGlmICggY29tcHV0ZWQgKSB7XG5cdFx0XHQvLyBXZWJLaXQgQnVnIDEzMzQzIC0gZ2V0Q29tcHV0ZWRTdHlsZSByZXR1cm5zIHdyb25nIHZhbHVlIGZvciBtYXJnaW4tcmlnaHRcblx0XHRcdC8vIFdvcmsgYXJvdW5kIGJ5IHRlbXBvcmFyaWx5IHNldHRpbmcgZWxlbWVudCBkaXNwbGF5IHRvIGlubGluZS1ibG9ja1xuXHRcdFx0cmV0dXJuIGpRdWVyeS5zd2FwKCBlbGVtLCB7IFwiZGlzcGxheVwiOiBcImlubGluZS1ibG9ja1wiIH0sXG5cdFx0XHRcdGN1ckNTUywgWyBlbGVtLCBcIm1hcmdpblJpZ2h0XCIgXSApO1xuXHRcdH1cblx0fVxuKTtcblxuLy8gVGhlc2UgaG9va3MgYXJlIHVzZWQgYnkgYW5pbWF0ZSB0byBleHBhbmQgcHJvcGVydGllc1xualF1ZXJ5LmVhY2goe1xuXHRtYXJnaW46IFwiXCIsXG5cdHBhZGRpbmc6IFwiXCIsXG5cdGJvcmRlcjogXCJXaWR0aFwiXG59LCBmdW5jdGlvbiggcHJlZml4LCBzdWZmaXggKSB7XG5cdGpRdWVyeS5jc3NIb29rc1sgcHJlZml4ICsgc3VmZml4IF0gPSB7XG5cdFx0ZXhwYW5kOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0XHR2YXIgaSA9IDAsXG5cdFx0XHRcdGV4cGFuZGVkID0ge30sXG5cblx0XHRcdFx0Ly8gYXNzdW1lcyBhIHNpbmdsZSBudW1iZXIgaWYgbm90IGEgc3RyaW5nXG5cdFx0XHRcdHBhcnRzID0gdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiID8gdmFsdWUuc3BsaXQoXCIgXCIpIDogWyB2YWx1ZSBdO1xuXG5cdFx0XHRmb3IgKCA7IGkgPCA0OyBpKysgKSB7XG5cdFx0XHRcdGV4cGFuZGVkWyBwcmVmaXggKyBjc3NFeHBhbmRbIGkgXSArIHN1ZmZpeCBdID1cblx0XHRcdFx0XHRwYXJ0c1sgaSBdIHx8IHBhcnRzWyBpIC0gMiBdIHx8IHBhcnRzWyAwIF07XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBleHBhbmRlZDtcblx0XHR9XG5cdH07XG5cblx0aWYgKCAhcm1hcmdpbi50ZXN0KCBwcmVmaXggKSApIHtcblx0XHRqUXVlcnkuY3NzSG9va3NbIHByZWZpeCArIHN1ZmZpeCBdLnNldCA9IHNldFBvc2l0aXZlTnVtYmVyO1xuXHR9XG59KTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGNzczogZnVuY3Rpb24oIG5hbWUsIHZhbHVlICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHRcdHZhciBzdHlsZXMsIGxlbixcblx0XHRcdFx0bWFwID0ge30sXG5cdFx0XHRcdGkgPSAwO1xuXG5cdFx0XHRpZiAoIGpRdWVyeS5pc0FycmF5KCBuYW1lICkgKSB7XG5cdFx0XHRcdHN0eWxlcyA9IGdldFN0eWxlcyggZWxlbSApO1xuXHRcdFx0XHRsZW4gPSBuYW1lLmxlbmd0aDtcblxuXHRcdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0XHRtYXBbIG5hbWVbIGkgXSBdID0galF1ZXJ5LmNzcyggZWxlbSwgbmFtZVsgaSBdLCBmYWxzZSwgc3R5bGVzICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gbWFwO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdmFsdWUgIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgbmFtZSwgdmFsdWUgKSA6XG5cdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIG5hbWUgKTtcblx0XHR9LCBuYW1lLCB2YWx1ZSwgYXJndW1lbnRzLmxlbmd0aCA+IDEgKTtcblx0fSxcblx0c2hvdzogZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIHNob3dIaWRlKCB0aGlzLCB0cnVlICk7XG5cdH0sXG5cdGhpZGU6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiBzaG93SGlkZSggdGhpcyApO1xuXHR9LFxuXHR0b2dnbGU6IGZ1bmN0aW9uKCBzdGF0ZSApIHtcblx0XHRpZiAoIHR5cGVvZiBzdGF0ZSA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0XHRyZXR1cm4gc3RhdGUgPyB0aGlzLnNob3coKSA6IHRoaXMuaGlkZSgpO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIGlzSGlkZGVuKCB0aGlzICkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnNob3coKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLmhpZGUoKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufSk7XG5cblxuZnVuY3Rpb24gVHdlZW4oIGVsZW0sIG9wdGlvbnMsIHByb3AsIGVuZCwgZWFzaW5nICkge1xuXHRyZXR1cm4gbmV3IFR3ZWVuLnByb3RvdHlwZS5pbml0KCBlbGVtLCBvcHRpb25zLCBwcm9wLCBlbmQsIGVhc2luZyApO1xufVxualF1ZXJ5LlR3ZWVuID0gVHdlZW47XG5cblR3ZWVuLnByb3RvdHlwZSA9IHtcblx0Y29uc3RydWN0b3I6IFR3ZWVuLFxuXHRpbml0OiBmdW5jdGlvbiggZWxlbSwgb3B0aW9ucywgcHJvcCwgZW5kLCBlYXNpbmcsIHVuaXQgKSB7XG5cdFx0dGhpcy5lbGVtID0gZWxlbTtcblx0XHR0aGlzLnByb3AgPSBwcm9wO1xuXHRcdHRoaXMuZWFzaW5nID0gZWFzaW5nIHx8IFwic3dpbmdcIjtcblx0XHR0aGlzLm9wdGlvbnMgPSBvcHRpb25zO1xuXHRcdHRoaXMuc3RhcnQgPSB0aGlzLm5vdyA9IHRoaXMuY3VyKCk7XG5cdFx0dGhpcy5lbmQgPSBlbmQ7XG5cdFx0dGhpcy51bml0ID0gdW5pdCB8fCAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSA/IFwiXCIgOiBcInB4XCIgKTtcblx0fSxcblx0Y3VyOiBmdW5jdGlvbigpIHtcblx0XHR2YXIgaG9va3MgPSBUd2Vlbi5wcm9wSG9va3NbIHRoaXMucHJvcCBdO1xuXG5cdFx0cmV0dXJuIGhvb2tzICYmIGhvb2tzLmdldCA/XG5cdFx0XHRob29rcy5nZXQoIHRoaXMgKSA6XG5cdFx0XHRUd2Vlbi5wcm9wSG9va3MuX2RlZmF1bHQuZ2V0KCB0aGlzICk7XG5cdH0sXG5cdHJ1bjogZnVuY3Rpb24oIHBlcmNlbnQgKSB7XG5cdFx0dmFyIGVhc2VkLFxuXHRcdFx0aG9va3MgPSBUd2Vlbi5wcm9wSG9va3NbIHRoaXMucHJvcCBdO1xuXG5cdFx0aWYgKCB0aGlzLm9wdGlvbnMuZHVyYXRpb24gKSB7XG5cdFx0XHR0aGlzLnBvcyA9IGVhc2VkID0galF1ZXJ5LmVhc2luZ1sgdGhpcy5lYXNpbmcgXShcblx0XHRcdFx0cGVyY2VudCwgdGhpcy5vcHRpb25zLmR1cmF0aW9uICogcGVyY2VudCwgMCwgMSwgdGhpcy5vcHRpb25zLmR1cmF0aW9uXG5cdFx0XHQpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR0aGlzLnBvcyA9IGVhc2VkID0gcGVyY2VudDtcblx0XHR9XG5cdFx0dGhpcy5ub3cgPSAoIHRoaXMuZW5kIC0gdGhpcy5zdGFydCApICogZWFzZWQgKyB0aGlzLnN0YXJ0O1xuXG5cdFx0aWYgKCB0aGlzLm9wdGlvbnMuc3RlcCApIHtcblx0XHRcdHRoaXMub3B0aW9ucy5zdGVwLmNhbGwoIHRoaXMuZWxlbSwgdGhpcy5ub3csIHRoaXMgKTtcblx0XHR9XG5cblx0XHRpZiAoIGhvb2tzICYmIGhvb2tzLnNldCApIHtcblx0XHRcdGhvb2tzLnNldCggdGhpcyApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRUd2Vlbi5wcm9wSG9va3MuX2RlZmF1bHQuc2V0KCB0aGlzICk7XG5cdFx0fVxuXHRcdHJldHVybiB0aGlzO1xuXHR9XG59O1xuXG5Ud2Vlbi5wcm90b3R5cGUuaW5pdC5wcm90b3R5cGUgPSBUd2Vlbi5wcm90b3R5cGU7XG5cblR3ZWVuLnByb3BIb29rcyA9IHtcblx0X2RlZmF1bHQ6IHtcblx0XHRnZXQ6IGZ1bmN0aW9uKCB0d2VlbiApIHtcblx0XHRcdHZhciByZXN1bHQ7XG5cblx0XHRcdGlmICggdHdlZW4uZWxlbVsgdHdlZW4ucHJvcCBdICE9IG51bGwgJiZcblx0XHRcdFx0KCF0d2Vlbi5lbGVtLnN0eWxlIHx8IHR3ZWVuLmVsZW0uc3R5bGVbIHR3ZWVuLnByb3AgXSA9PSBudWxsKSApIHtcblx0XHRcdFx0cmV0dXJuIHR3ZWVuLmVsZW1bIHR3ZWVuLnByb3AgXTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gcGFzc2luZyBhbiBlbXB0eSBzdHJpbmcgYXMgYSAzcmQgcGFyYW1ldGVyIHRvIC5jc3Mgd2lsbCBhdXRvbWF0aWNhbGx5XG5cdFx0XHQvLyBhdHRlbXB0IGEgcGFyc2VGbG9hdCBhbmQgZmFsbGJhY2sgdG8gYSBzdHJpbmcgaWYgdGhlIHBhcnNlIGZhaWxzXG5cdFx0XHQvLyBzbywgc2ltcGxlIHZhbHVlcyBzdWNoIGFzIFwiMTBweFwiIGFyZSBwYXJzZWQgdG8gRmxvYXQuXG5cdFx0XHQvLyBjb21wbGV4IHZhbHVlcyBzdWNoIGFzIFwicm90YXRlKDFyYWQpXCIgYXJlIHJldHVybmVkIGFzIGlzLlxuXHRcdFx0cmVzdWx0ID0galF1ZXJ5LmNzcyggdHdlZW4uZWxlbSwgdHdlZW4ucHJvcCwgXCJcIiApO1xuXHRcdFx0Ly8gRW1wdHkgc3RyaW5ncywgbnVsbCwgdW5kZWZpbmVkIGFuZCBcImF1dG9cIiBhcmUgY29udmVydGVkIHRvIDAuXG5cdFx0XHRyZXR1cm4gIXJlc3VsdCB8fCByZXN1bHQgPT09IFwiYXV0b1wiID8gMCA6IHJlc3VsdDtcblx0XHR9LFxuXHRcdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdFx0Ly8gdXNlIHN0ZXAgaG9vayBmb3IgYmFjayBjb21wYXQgLSB1c2UgY3NzSG9vayBpZiBpdHMgdGhlcmUgLSB1c2UgLnN0eWxlIGlmIGl0c1xuXHRcdFx0Ly8gYXZhaWxhYmxlIGFuZCB1c2UgcGxhaW4gcHJvcGVydGllcyB3aGVyZSBhdmFpbGFibGVcblx0XHRcdGlmICggalF1ZXJ5LmZ4LnN0ZXBbIHR3ZWVuLnByb3AgXSApIHtcblx0XHRcdFx0alF1ZXJ5LmZ4LnN0ZXBbIHR3ZWVuLnByb3AgXSggdHdlZW4gKTtcblx0XHRcdH0gZWxzZSBpZiAoIHR3ZWVuLmVsZW0uc3R5bGUgJiYgKCB0d2Vlbi5lbGVtLnN0eWxlWyBqUXVlcnkuY3NzUHJvcHNbIHR3ZWVuLnByb3AgXSBdICE9IG51bGwgfHwgalF1ZXJ5LmNzc0hvb2tzWyB0d2Vlbi5wcm9wIF0gKSApIHtcblx0XHRcdFx0alF1ZXJ5LnN0eWxlKCB0d2Vlbi5lbGVtLCB0d2Vlbi5wcm9wLCB0d2Vlbi5ub3cgKyB0d2Vlbi51bml0ICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59O1xuXG4vLyBTdXBwb3J0OiBJRSA8PTlcbi8vIFBhbmljIGJhc2VkIGFwcHJvYWNoIHRvIHNldHRpbmcgdGhpbmdzIG9uIGRpc2Nvbm5lY3RlZCBub2Rlc1xuXG5Ud2Vlbi5wcm9wSG9va3Muc2Nyb2xsVG9wID0gVHdlZW4ucHJvcEhvb2tzLnNjcm9sbExlZnQgPSB7XG5cdHNldDogZnVuY3Rpb24oIHR3ZWVuICkge1xuXHRcdGlmICggdHdlZW4uZWxlbS5ub2RlVHlwZSAmJiB0d2Vlbi5lbGVtLnBhcmVudE5vZGUgKSB7XG5cdFx0XHR0d2Vlbi5lbGVtWyB0d2Vlbi5wcm9wIF0gPSB0d2Vlbi5ub3c7XG5cdFx0fVxuXHR9XG59O1xuXG5qUXVlcnkuZWFzaW5nID0ge1xuXHRsaW5lYXI6IGZ1bmN0aW9uKCBwICkge1xuXHRcdHJldHVybiBwO1xuXHR9LFxuXHRzd2luZzogZnVuY3Rpb24oIHAgKSB7XG5cdFx0cmV0dXJuIDAuNSAtIE1hdGguY29zKCBwICogTWF0aC5QSSApIC8gMjtcblx0fVxufTtcblxualF1ZXJ5LmZ4ID0gVHdlZW4ucHJvdG90eXBlLmluaXQ7XG5cbi8vIEJhY2sgQ29tcGF0IDwxLjggZXh0ZW5zaW9uIHBvaW50XG5qUXVlcnkuZnguc3RlcCA9IHt9O1xuXG5cblxuXG52YXJcblx0ZnhOb3csIHRpbWVySWQsXG5cdHJmeHR5cGVzID0gL14oPzp0b2dnbGV8c2hvd3xoaWRlKSQvLFxuXHRyZnhudW0gPSBuZXcgUmVnRXhwKCBcIl4oPzooWystXSk9fCkoXCIgKyBwbnVtICsgXCIpKFthLXolXSopJFwiLCBcImlcIiApLFxuXHRycnVuID0gL3F1ZXVlSG9va3MkLyxcblx0YW5pbWF0aW9uUHJlZmlsdGVycyA9IFsgZGVmYXVsdFByZWZpbHRlciBdLFxuXHR0d2VlbmVycyA9IHtcblx0XHRcIipcIjogWyBmdW5jdGlvbiggcHJvcCwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgdHdlZW4gPSB0aGlzLmNyZWF0ZVR3ZWVuKCBwcm9wLCB2YWx1ZSApLFxuXHRcdFx0XHR0YXJnZXQgPSB0d2Vlbi5jdXIoKSxcblx0XHRcdFx0cGFydHMgPSByZnhudW0uZXhlYyggdmFsdWUgKSxcblx0XHRcdFx0dW5pdCA9IHBhcnRzICYmIHBhcnRzWyAzIF0gfHwgKCBqUXVlcnkuY3NzTnVtYmVyWyBwcm9wIF0gPyBcIlwiIDogXCJweFwiICksXG5cblx0XHRcdFx0Ly8gU3RhcnRpbmcgdmFsdWUgY29tcHV0YXRpb24gaXMgcmVxdWlyZWQgZm9yIHBvdGVudGlhbCB1bml0IG1pc21hdGNoZXNcblx0XHRcdFx0c3RhcnQgPSAoIGpRdWVyeS5jc3NOdW1iZXJbIHByb3AgXSB8fCB1bml0ICE9PSBcInB4XCIgJiYgK3RhcmdldCApICYmXG5cdFx0XHRcdFx0cmZ4bnVtLmV4ZWMoIGpRdWVyeS5jc3MoIHR3ZWVuLmVsZW0sIHByb3AgKSApLFxuXHRcdFx0XHRzY2FsZSA9IDEsXG5cdFx0XHRcdG1heEl0ZXJhdGlvbnMgPSAyMDtcblxuXHRcdFx0aWYgKCBzdGFydCAmJiBzdGFydFsgMyBdICE9PSB1bml0ICkge1xuXHRcdFx0XHQvLyBUcnVzdCB1bml0cyByZXBvcnRlZCBieSBqUXVlcnkuY3NzXG5cdFx0XHRcdHVuaXQgPSB1bml0IHx8IHN0YXJ0WyAzIF07XG5cblx0XHRcdFx0Ly8gTWFrZSBzdXJlIHdlIHVwZGF0ZSB0aGUgdHdlZW4gcHJvcGVydGllcyBsYXRlciBvblxuXHRcdFx0XHRwYXJ0cyA9IHBhcnRzIHx8IFtdO1xuXG5cdFx0XHRcdC8vIEl0ZXJhdGl2ZWx5IGFwcHJveGltYXRlIGZyb20gYSBub256ZXJvIHN0YXJ0aW5nIHBvaW50XG5cdFx0XHRcdHN0YXJ0ID0gK3RhcmdldCB8fCAxO1xuXG5cdFx0XHRcdGRvIHtcblx0XHRcdFx0XHQvLyBJZiBwcmV2aW91cyBpdGVyYXRpb24gemVyb2VkIG91dCwgZG91YmxlIHVudGlsIHdlIGdldCAqc29tZXRoaW5nKlxuXHRcdFx0XHRcdC8vIFVzZSBhIHN0cmluZyBmb3IgZG91YmxpbmcgZmFjdG9yIHNvIHdlIGRvbid0IGFjY2lkZW50YWxseSBzZWUgc2NhbGUgYXMgdW5jaGFuZ2VkIGJlbG93XG5cdFx0XHRcdFx0c2NhbGUgPSBzY2FsZSB8fCBcIi41XCI7XG5cblx0XHRcdFx0XHQvLyBBZGp1c3QgYW5kIGFwcGx5XG5cdFx0XHRcdFx0c3RhcnQgPSBzdGFydCAvIHNjYWxlO1xuXHRcdFx0XHRcdGpRdWVyeS5zdHlsZSggdHdlZW4uZWxlbSwgcHJvcCwgc3RhcnQgKyB1bml0ICk7XG5cblx0XHRcdFx0Ly8gVXBkYXRlIHNjYWxlLCB0b2xlcmF0aW5nIHplcm8gb3IgTmFOIGZyb20gdHdlZW4uY3VyKClcblx0XHRcdFx0Ly8gQW5kIGJyZWFraW5nIHRoZSBsb29wIGlmIHNjYWxlIGlzIHVuY2hhbmdlZCBvciBwZXJmZWN0LCBvciBpZiB3ZSd2ZSBqdXN0IGhhZCBlbm91Z2hcblx0XHRcdFx0fSB3aGlsZSAoIHNjYWxlICE9PSAoc2NhbGUgPSB0d2Vlbi5jdXIoKSAvIHRhcmdldCkgJiYgc2NhbGUgIT09IDEgJiYgLS1tYXhJdGVyYXRpb25zICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIFVwZGF0ZSB0d2VlbiBwcm9wZXJ0aWVzXG5cdFx0XHRpZiAoIHBhcnRzICkge1xuXHRcdFx0XHRzdGFydCA9IHR3ZWVuLnN0YXJ0ID0gK3N0YXJ0IHx8ICt0YXJnZXQgfHwgMDtcblx0XHRcdFx0dHdlZW4udW5pdCA9IHVuaXQ7XG5cdFx0XHRcdC8vIElmIGEgKz0vLT0gdG9rZW4gd2FzIHByb3ZpZGVkLCB3ZSdyZSBkb2luZyBhIHJlbGF0aXZlIGFuaW1hdGlvblxuXHRcdFx0XHR0d2Vlbi5lbmQgPSBwYXJ0c1sgMSBdID9cblx0XHRcdFx0XHRzdGFydCArICggcGFydHNbIDEgXSArIDEgKSAqIHBhcnRzWyAyIF0gOlxuXHRcdFx0XHRcdCtwYXJ0c1sgMiBdO1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm4gdHdlZW47XG5cdFx0fSBdXG5cdH07XG5cbi8vIEFuaW1hdGlvbnMgY3JlYXRlZCBzeW5jaHJvbm91c2x5IHdpbGwgcnVuIHN5bmNocm9ub3VzbHlcbmZ1bmN0aW9uIGNyZWF0ZUZ4Tm93KCkge1xuXHRzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuXHRcdGZ4Tm93ID0gdW5kZWZpbmVkO1xuXHR9KTtcblx0cmV0dXJuICggZnhOb3cgPSBqUXVlcnkubm93KCkgKTtcbn1cblxuLy8gR2VuZXJhdGUgcGFyYW1ldGVycyB0byBjcmVhdGUgYSBzdGFuZGFyZCBhbmltYXRpb25cbmZ1bmN0aW9uIGdlbkZ4KCB0eXBlLCBpbmNsdWRlV2lkdGggKSB7XG5cdHZhciB3aGljaCxcblx0XHRhdHRycyA9IHsgaGVpZ2h0OiB0eXBlIH0sXG5cdFx0aSA9IDA7XG5cblx0Ly8gaWYgd2UgaW5jbHVkZSB3aWR0aCwgc3RlcCB2YWx1ZSBpcyAxIHRvIGRvIGFsbCBjc3NFeHBhbmQgdmFsdWVzLFxuXHQvLyBpZiB3ZSBkb24ndCBpbmNsdWRlIHdpZHRoLCBzdGVwIHZhbHVlIGlzIDIgdG8gc2tpcCBvdmVyIExlZnQgYW5kIFJpZ2h0XG5cdGluY2x1ZGVXaWR0aCA9IGluY2x1ZGVXaWR0aCA/IDEgOiAwO1xuXHRmb3IgKCA7IGkgPCA0IDsgaSArPSAyIC0gaW5jbHVkZVdpZHRoICkge1xuXHRcdHdoaWNoID0gY3NzRXhwYW5kWyBpIF07XG5cdFx0YXR0cnNbIFwibWFyZ2luXCIgKyB3aGljaCBdID0gYXR0cnNbIFwicGFkZGluZ1wiICsgd2hpY2ggXSA9IHR5cGU7XG5cdH1cblxuXHRpZiAoIGluY2x1ZGVXaWR0aCApIHtcblx0XHRhdHRycy5vcGFjaXR5ID0gYXR0cnMud2lkdGggPSB0eXBlO1xuXHR9XG5cblx0cmV0dXJuIGF0dHJzO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUd2VlbiggdmFsdWUsIHByb3AsIGFuaW1hdGlvbiApIHtcblx0dmFyIHR3ZWVuLFxuXHRcdGNvbGxlY3Rpb24gPSAoIHR3ZWVuZXJzWyBwcm9wIF0gfHwgW10gKS5jb25jYXQoIHR3ZWVuZXJzWyBcIipcIiBdICksXG5cdFx0aW5kZXggPSAwLFxuXHRcdGxlbmd0aCA9IGNvbGxlY3Rpb24ubGVuZ3RoO1xuXHRmb3IgKCA7IGluZGV4IDwgbGVuZ3RoOyBpbmRleCsrICkge1xuXHRcdGlmICggKHR3ZWVuID0gY29sbGVjdGlvblsgaW5kZXggXS5jYWxsKCBhbmltYXRpb24sIHByb3AsIHZhbHVlICkpICkge1xuXG5cdFx0XHQvLyB3ZSdyZSBkb25lIHdpdGggdGhpcyBwcm9wZXJ0eVxuXHRcdFx0cmV0dXJuIHR3ZWVuO1xuXHRcdH1cblx0fVxufVxuXG5mdW5jdGlvbiBkZWZhdWx0UHJlZmlsdGVyKCBlbGVtLCBwcm9wcywgb3B0cyApIHtcblx0LyoganNoaW50IHZhbGlkdGhpczogdHJ1ZSAqL1xuXHR2YXIgcHJvcCwgdmFsdWUsIHRvZ2dsZSwgdHdlZW4sIGhvb2tzLCBvbGRmaXJlLCBkaXNwbGF5LCBjaGVja0Rpc3BsYXksXG5cdFx0YW5pbSA9IHRoaXMsXG5cdFx0b3JpZyA9IHt9LFxuXHRcdHN0eWxlID0gZWxlbS5zdHlsZSxcblx0XHRoaWRkZW4gPSBlbGVtLm5vZGVUeXBlICYmIGlzSGlkZGVuKCBlbGVtICksXG5cdFx0ZGF0YVNob3cgPSBqUXVlcnkuX2RhdGEoIGVsZW0sIFwiZnhzaG93XCIgKTtcblxuXHQvLyBoYW5kbGUgcXVldWU6IGZhbHNlIHByb21pc2VzXG5cdGlmICggIW9wdHMucXVldWUgKSB7XG5cdFx0aG9va3MgPSBqUXVlcnkuX3F1ZXVlSG9va3MoIGVsZW0sIFwiZnhcIiApO1xuXHRcdGlmICggaG9va3MudW5xdWV1ZWQgPT0gbnVsbCApIHtcblx0XHRcdGhvb2tzLnVucXVldWVkID0gMDtcblx0XHRcdG9sZGZpcmUgPSBob29rcy5lbXB0eS5maXJlO1xuXHRcdFx0aG9va3MuZW1wdHkuZmlyZSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoICFob29rcy51bnF1ZXVlZCApIHtcblx0XHRcdFx0XHRvbGRmaXJlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHRcdGhvb2tzLnVucXVldWVkKys7XG5cblx0XHRhbmltLmFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdC8vIGRvaW5nIHRoaXMgbWFrZXMgc3VyZSB0aGF0IHRoZSBjb21wbGV0ZSBoYW5kbGVyIHdpbGwgYmUgY2FsbGVkXG5cdFx0XHQvLyBiZWZvcmUgdGhpcyBjb21wbGV0ZXNcblx0XHRcdGFuaW0uYWx3YXlzKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRob29rcy51bnF1ZXVlZC0tO1xuXHRcdFx0XHRpZiAoICFqUXVlcnkucXVldWUoIGVsZW0sIFwiZnhcIiApLmxlbmd0aCApIHtcblx0XHRcdFx0XHRob29rcy5lbXB0eS5maXJlKCk7XG5cdFx0XHRcdH1cblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0Ly8gaGVpZ2h0L3dpZHRoIG92ZXJmbG93IHBhc3Ncblx0aWYgKCBlbGVtLm5vZGVUeXBlID09PSAxICYmICggXCJoZWlnaHRcIiBpbiBwcm9wcyB8fCBcIndpZHRoXCIgaW4gcHJvcHMgKSApIHtcblx0XHQvLyBNYWtlIHN1cmUgdGhhdCBub3RoaW5nIHNuZWFrcyBvdXRcblx0XHQvLyBSZWNvcmQgYWxsIDMgb3ZlcmZsb3cgYXR0cmlidXRlcyBiZWNhdXNlIElFIGRvZXMgbm90XG5cdFx0Ly8gY2hhbmdlIHRoZSBvdmVyZmxvdyBhdHRyaWJ1dGUgd2hlbiBvdmVyZmxvd1ggYW5kXG5cdFx0Ly8gb3ZlcmZsb3dZIGFyZSBzZXQgdG8gdGhlIHNhbWUgdmFsdWVcblx0XHRvcHRzLm92ZXJmbG93ID0gWyBzdHlsZS5vdmVyZmxvdywgc3R5bGUub3ZlcmZsb3dYLCBzdHlsZS5vdmVyZmxvd1kgXTtcblxuXHRcdC8vIFNldCBkaXNwbGF5IHByb3BlcnR5IHRvIGlubGluZS1ibG9jayBmb3IgaGVpZ2h0L3dpZHRoXG5cdFx0Ly8gYW5pbWF0aW9ucyBvbiBpbmxpbmUgZWxlbWVudHMgdGhhdCBhcmUgaGF2aW5nIHdpZHRoL2hlaWdodCBhbmltYXRlZFxuXHRcdGRpc3BsYXkgPSBqUXVlcnkuY3NzKCBlbGVtLCBcImRpc3BsYXlcIiApO1xuXG5cdFx0Ly8gVGVzdCBkZWZhdWx0IGRpc3BsYXkgaWYgZGlzcGxheSBpcyBjdXJyZW50bHkgXCJub25lXCJcblx0XHRjaGVja0Rpc3BsYXkgPSBkaXNwbGF5ID09PSBcIm5vbmVcIiA/XG5cdFx0XHRqUXVlcnkuX2RhdGEoIGVsZW0sIFwib2xkZGlzcGxheVwiICkgfHwgZGVmYXVsdERpc3BsYXkoIGVsZW0ubm9kZU5hbWUgKSA6IGRpc3BsYXk7XG5cblx0XHRpZiAoIGNoZWNrRGlzcGxheSA9PT0gXCJpbmxpbmVcIiAmJiBqUXVlcnkuY3NzKCBlbGVtLCBcImZsb2F0XCIgKSA9PT0gXCJub25lXCIgKSB7XG5cblx0XHRcdC8vIGlubGluZS1sZXZlbCBlbGVtZW50cyBhY2NlcHQgaW5saW5lLWJsb2NrO1xuXHRcdFx0Ly8gYmxvY2stbGV2ZWwgZWxlbWVudHMgbmVlZCB0byBiZSBpbmxpbmUgd2l0aCBsYXlvdXRcblx0XHRcdGlmICggIXN1cHBvcnQuaW5saW5lQmxvY2tOZWVkc0xheW91dCB8fCBkZWZhdWx0RGlzcGxheSggZWxlbS5ub2RlTmFtZSApID09PSBcImlubGluZVwiICkge1xuXHRcdFx0XHRzdHlsZS5kaXNwbGF5ID0gXCJpbmxpbmUtYmxvY2tcIjtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHN0eWxlLnpvb20gPSAxO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmICggb3B0cy5vdmVyZmxvdyApIHtcblx0XHRzdHlsZS5vdmVyZmxvdyA9IFwiaGlkZGVuXCI7XG5cdFx0aWYgKCAhc3VwcG9ydC5zaHJpbmtXcmFwQmxvY2tzKCkgKSB7XG5cdFx0XHRhbmltLmFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdFx0c3R5bGUub3ZlcmZsb3cgPSBvcHRzLm92ZXJmbG93WyAwIF07XG5cdFx0XHRcdHN0eWxlLm92ZXJmbG93WCA9IG9wdHMub3ZlcmZsb3dbIDEgXTtcblx0XHRcdFx0c3R5bGUub3ZlcmZsb3dZID0gb3B0cy5vdmVyZmxvd1sgMiBdO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0Ly8gc2hvdy9oaWRlIHBhc3Ncblx0Zm9yICggcHJvcCBpbiBwcm9wcyApIHtcblx0XHR2YWx1ZSA9IHByb3BzWyBwcm9wIF07XG5cdFx0aWYgKCByZnh0eXBlcy5leGVjKCB2YWx1ZSApICkge1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBwcm9wIF07XG5cdFx0XHR0b2dnbGUgPSB0b2dnbGUgfHwgdmFsdWUgPT09IFwidG9nZ2xlXCI7XG5cdFx0XHRpZiAoIHZhbHVlID09PSAoIGhpZGRlbiA/IFwiaGlkZVwiIDogXCJzaG93XCIgKSApIHtcblxuXHRcdFx0XHQvLyBJZiB0aGVyZSBpcyBkYXRhU2hvdyBsZWZ0IG92ZXIgZnJvbSBhIHN0b3BwZWQgaGlkZSBvciBzaG93IGFuZCB3ZSBhcmUgZ29pbmcgdG8gcHJvY2VlZCB3aXRoIHNob3csIHdlIHNob3VsZCBwcmV0ZW5kIHRvIGJlIGhpZGRlblxuXHRcdFx0XHRpZiAoIHZhbHVlID09PSBcInNob3dcIiAmJiBkYXRhU2hvdyAmJiBkYXRhU2hvd1sgcHJvcCBdICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0aGlkZGVuID0gdHJ1ZTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0b3JpZ1sgcHJvcCBdID0gZGF0YVNob3cgJiYgZGF0YVNob3dbIHByb3AgXSB8fCBqUXVlcnkuc3R5bGUoIGVsZW0sIHByb3AgKTtcblxuXHRcdC8vIEFueSBub24tZnggdmFsdWUgc3RvcHMgdXMgZnJvbSByZXN0b3JpbmcgdGhlIG9yaWdpbmFsIGRpc3BsYXkgdmFsdWVcblx0XHR9IGVsc2Uge1xuXHRcdFx0ZGlzcGxheSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cdH1cblxuXHRpZiAoICFqUXVlcnkuaXNFbXB0eU9iamVjdCggb3JpZyApICkge1xuXHRcdGlmICggZGF0YVNob3cgKSB7XG5cdFx0XHRpZiAoIFwiaGlkZGVuXCIgaW4gZGF0YVNob3cgKSB7XG5cdFx0XHRcdGhpZGRlbiA9IGRhdGFTaG93LmhpZGRlbjtcblx0XHRcdH1cblx0XHR9IGVsc2Uge1xuXHRcdFx0ZGF0YVNob3cgPSBqUXVlcnkuX2RhdGEoIGVsZW0sIFwiZnhzaG93XCIsIHt9ICk7XG5cdFx0fVxuXG5cdFx0Ly8gc3RvcmUgc3RhdGUgaWYgaXRzIHRvZ2dsZSAtIGVuYWJsZXMgLnN0b3AoKS50b2dnbGUoKSB0byBcInJldmVyc2VcIlxuXHRcdGlmICggdG9nZ2xlICkge1xuXHRcdFx0ZGF0YVNob3cuaGlkZGVuID0gIWhpZGRlbjtcblx0XHR9XG5cdFx0aWYgKCBoaWRkZW4gKSB7XG5cdFx0XHRqUXVlcnkoIGVsZW0gKS5zaG93KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFuaW0uZG9uZShmdW5jdGlvbigpIHtcblx0XHRcdFx0alF1ZXJ5KCBlbGVtICkuaGlkZSgpO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHRcdGFuaW0uZG9uZShmdW5jdGlvbigpIHtcblx0XHRcdHZhciBwcm9wO1xuXHRcdFx0alF1ZXJ5Ll9yZW1vdmVEYXRhKCBlbGVtLCBcImZ4c2hvd1wiICk7XG5cdFx0XHRmb3IgKCBwcm9wIGluIG9yaWcgKSB7XG5cdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgcHJvcCwgb3JpZ1sgcHJvcCBdICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdFx0Zm9yICggcHJvcCBpbiBvcmlnICkge1xuXHRcdFx0dHdlZW4gPSBjcmVhdGVUd2VlbiggaGlkZGVuID8gZGF0YVNob3dbIHByb3AgXSA6IDAsIHByb3AsIGFuaW0gKTtcblxuXHRcdFx0aWYgKCAhKCBwcm9wIGluIGRhdGFTaG93ICkgKSB7XG5cdFx0XHRcdGRhdGFTaG93WyBwcm9wIF0gPSB0d2Vlbi5zdGFydDtcblx0XHRcdFx0aWYgKCBoaWRkZW4gKSB7XG5cdFx0XHRcdFx0dHdlZW4uZW5kID0gdHdlZW4uc3RhcnQ7XG5cdFx0XHRcdFx0dHdlZW4uc3RhcnQgPSBwcm9wID09PSBcIndpZHRoXCIgfHwgcHJvcCA9PT0gXCJoZWlnaHRcIiA/IDEgOiAwO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdC8vIElmIHRoaXMgaXMgYSBub29wIGxpa2UgLmhpZGUoKS5oaWRlKCksIHJlc3RvcmUgYW4gb3ZlcndyaXR0ZW4gZGlzcGxheSB2YWx1ZVxuXHR9IGVsc2UgaWYgKCAoZGlzcGxheSA9PT0gXCJub25lXCIgPyBkZWZhdWx0RGlzcGxheSggZWxlbS5ub2RlTmFtZSApIDogZGlzcGxheSkgPT09IFwiaW5saW5lXCIgKSB7XG5cdFx0c3R5bGUuZGlzcGxheSA9IGRpc3BsYXk7XG5cdH1cbn1cblxuZnVuY3Rpb24gcHJvcEZpbHRlciggcHJvcHMsIHNwZWNpYWxFYXNpbmcgKSB7XG5cdHZhciBpbmRleCwgbmFtZSwgZWFzaW5nLCB2YWx1ZSwgaG9va3M7XG5cblx0Ly8gY2FtZWxDYXNlLCBzcGVjaWFsRWFzaW5nIGFuZCBleHBhbmQgY3NzSG9vayBwYXNzXG5cdGZvciAoIGluZGV4IGluIHByb3BzICkge1xuXHRcdG5hbWUgPSBqUXVlcnkuY2FtZWxDYXNlKCBpbmRleCApO1xuXHRcdGVhc2luZyA9IHNwZWNpYWxFYXNpbmdbIG5hbWUgXTtcblx0XHR2YWx1ZSA9IHByb3BzWyBpbmRleCBdO1xuXHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIHZhbHVlICkgKSB7XG5cdFx0XHRlYXNpbmcgPSB2YWx1ZVsgMSBdO1xuXHRcdFx0dmFsdWUgPSBwcm9wc1sgaW5kZXggXSA9IHZhbHVlWyAwIF07XG5cdFx0fVxuXG5cdFx0aWYgKCBpbmRleCAhPT0gbmFtZSApIHtcblx0XHRcdHByb3BzWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdGRlbGV0ZSBwcm9wc1sgaW5kZXggXTtcblx0XHR9XG5cblx0XHRob29rcyA9IGpRdWVyeS5jc3NIb29rc1sgbmFtZSBdO1xuXHRcdGlmICggaG9va3MgJiYgXCJleHBhbmRcIiBpbiBob29rcyApIHtcblx0XHRcdHZhbHVlID0gaG9va3MuZXhwYW5kKCB2YWx1ZSApO1xuXHRcdFx0ZGVsZXRlIHByb3BzWyBuYW1lIF07XG5cblx0XHRcdC8vIG5vdCBxdWl0ZSAkLmV4dGVuZCwgdGhpcyB3b250IG92ZXJ3cml0ZSBrZXlzIGFscmVhZHkgcHJlc2VudC5cblx0XHRcdC8vIGFsc28gLSByZXVzaW5nICdpbmRleCcgZnJvbSBhYm92ZSBiZWNhdXNlIHdlIGhhdmUgdGhlIGNvcnJlY3QgXCJuYW1lXCJcblx0XHRcdGZvciAoIGluZGV4IGluIHZhbHVlICkge1xuXHRcdFx0XHRpZiAoICEoIGluZGV4IGluIHByb3BzICkgKSB7XG5cdFx0XHRcdFx0cHJvcHNbIGluZGV4IF0gPSB2YWx1ZVsgaW5kZXggXTtcblx0XHRcdFx0XHRzcGVjaWFsRWFzaW5nWyBpbmRleCBdID0gZWFzaW5nO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdHNwZWNpYWxFYXNpbmdbIG5hbWUgXSA9IGVhc2luZztcblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gQW5pbWF0aW9uKCBlbGVtLCBwcm9wZXJ0aWVzLCBvcHRpb25zICkge1xuXHR2YXIgcmVzdWx0LFxuXHRcdHN0b3BwZWQsXG5cdFx0aW5kZXggPSAwLFxuXHRcdGxlbmd0aCA9IGFuaW1hdGlvblByZWZpbHRlcnMubGVuZ3RoLFxuXHRcdGRlZmVycmVkID0galF1ZXJ5LkRlZmVycmVkKCkuYWx3YXlzKCBmdW5jdGlvbigpIHtcblx0XHRcdC8vIGRvbid0IG1hdGNoIGVsZW0gaW4gdGhlIDphbmltYXRlZCBzZWxlY3RvclxuXHRcdFx0ZGVsZXRlIHRpY2suZWxlbTtcblx0XHR9KSxcblx0XHR0aWNrID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoIHN0b3BwZWQgKSB7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHRcdHZhciBjdXJyZW50VGltZSA9IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXG5cdFx0XHRcdHJlbWFpbmluZyA9IE1hdGgubWF4KCAwLCBhbmltYXRpb24uc3RhcnRUaW1lICsgYW5pbWF0aW9uLmR1cmF0aW9uIC0gY3VycmVudFRpbWUgKSxcblx0XHRcdFx0Ly8gYXJjaGFpYyBjcmFzaCBidWcgd29uJ3QgYWxsb3cgdXMgdG8gdXNlIDEgLSAoIDAuNSB8fCAwICkgKCMxMjQ5Nylcblx0XHRcdFx0dGVtcCA9IHJlbWFpbmluZyAvIGFuaW1hdGlvbi5kdXJhdGlvbiB8fCAwLFxuXHRcdFx0XHRwZXJjZW50ID0gMSAtIHRlbXAsXG5cdFx0XHRcdGluZGV4ID0gMCxcblx0XHRcdFx0bGVuZ3RoID0gYW5pbWF0aW9uLnR3ZWVucy5sZW5ndGg7XG5cblx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xuXHRcdFx0XHRhbmltYXRpb24udHdlZW5zWyBpbmRleCBdLnJ1biggcGVyY2VudCApO1xuXHRcdFx0fVxuXG5cdFx0XHRkZWZlcnJlZC5ub3RpZnlXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiwgcGVyY2VudCwgcmVtYWluaW5nIF0pO1xuXG5cdFx0XHRpZiAoIHBlcmNlbnQgPCAxICYmIGxlbmd0aCApIHtcblx0XHRcdFx0cmV0dXJuIHJlbWFpbmluZztcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlZmVycmVkLnJlc29sdmVXaXRoKCBlbGVtLCBbIGFuaW1hdGlvbiBdICk7XG5cdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdH1cblx0XHR9LFxuXHRcdGFuaW1hdGlvbiA9IGRlZmVycmVkLnByb21pc2Uoe1xuXHRcdFx0ZWxlbTogZWxlbSxcblx0XHRcdHByb3BzOiBqUXVlcnkuZXh0ZW5kKCB7fSwgcHJvcGVydGllcyApLFxuXHRcdFx0b3B0czogalF1ZXJ5LmV4dGVuZCggdHJ1ZSwgeyBzcGVjaWFsRWFzaW5nOiB7fSB9LCBvcHRpb25zICksXG5cdFx0XHRvcmlnaW5hbFByb3BlcnRpZXM6IHByb3BlcnRpZXMsXG5cdFx0XHRvcmlnaW5hbE9wdGlvbnM6IG9wdGlvbnMsXG5cdFx0XHRzdGFydFRpbWU6IGZ4Tm93IHx8IGNyZWF0ZUZ4Tm93KCksXG5cdFx0XHRkdXJhdGlvbjogb3B0aW9ucy5kdXJhdGlvbixcblx0XHRcdHR3ZWVuczogW10sXG5cdFx0XHRjcmVhdGVUd2VlbjogZnVuY3Rpb24oIHByb3AsIGVuZCApIHtcblx0XHRcdFx0dmFyIHR3ZWVuID0galF1ZXJ5LlR3ZWVuKCBlbGVtLCBhbmltYXRpb24ub3B0cywgcHJvcCwgZW5kLFxuXHRcdFx0XHRcdFx0YW5pbWF0aW9uLm9wdHMuc3BlY2lhbEVhc2luZ1sgcHJvcCBdIHx8IGFuaW1hdGlvbi5vcHRzLmVhc2luZyApO1xuXHRcdFx0XHRhbmltYXRpb24udHdlZW5zLnB1c2goIHR3ZWVuICk7XG5cdFx0XHRcdHJldHVybiB0d2Vlbjtcblx0XHRcdH0sXG5cdFx0XHRzdG9wOiBmdW5jdGlvbiggZ290b0VuZCApIHtcblx0XHRcdFx0dmFyIGluZGV4ID0gMCxcblx0XHRcdFx0XHQvLyBpZiB3ZSBhcmUgZ29pbmcgdG8gdGhlIGVuZCwgd2Ugd2FudCB0byBydW4gYWxsIHRoZSB0d2VlbnNcblx0XHRcdFx0XHQvLyBvdGhlcndpc2Ugd2Ugc2tpcCB0aGlzIHBhcnRcblx0XHRcdFx0XHRsZW5ndGggPSBnb3RvRW5kID8gYW5pbWF0aW9uLnR3ZWVucy5sZW5ndGggOiAwO1xuXHRcdFx0XHRpZiAoIHN0b3BwZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH1cblx0XHRcdFx0c3RvcHBlZCA9IHRydWU7XG5cdFx0XHRcdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xuXHRcdFx0XHRcdGFuaW1hdGlvbi50d2VlbnNbIGluZGV4IF0ucnVuKCAxICk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHQvLyByZXNvbHZlIHdoZW4gd2UgcGxheWVkIHRoZSBsYXN0IGZyYW1lXG5cdFx0XHRcdC8vIG90aGVyd2lzZSwgcmVqZWN0XG5cdFx0XHRcdGlmICggZ290b0VuZCApIHtcblx0XHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggZWxlbSwgWyBhbmltYXRpb24sIGdvdG9FbmQgXSApO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIGVsZW0sIFsgYW5pbWF0aW9uLCBnb3RvRW5kIF0gKTtcblx0XHRcdFx0fVxuXHRcdFx0XHRyZXR1cm4gdGhpcztcblx0XHRcdH1cblx0XHR9KSxcblx0XHRwcm9wcyA9IGFuaW1hdGlvbi5wcm9wcztcblxuXHRwcm9wRmlsdGVyKCBwcm9wcywgYW5pbWF0aW9uLm9wdHMuc3BlY2lhbEVhc2luZyApO1xuXG5cdGZvciAoIDsgaW5kZXggPCBsZW5ndGggOyBpbmRleCsrICkge1xuXHRcdHJlc3VsdCA9IGFuaW1hdGlvblByZWZpbHRlcnNbIGluZGV4IF0uY2FsbCggYW5pbWF0aW9uLCBlbGVtLCBwcm9wcywgYW5pbWF0aW9uLm9wdHMgKTtcblx0XHRpZiAoIHJlc3VsdCApIHtcblx0XHRcdHJldHVybiByZXN1bHQ7XG5cdFx0fVxuXHR9XG5cblx0alF1ZXJ5Lm1hcCggcHJvcHMsIGNyZWF0ZVR3ZWVuLCBhbmltYXRpb24gKTtcblxuXHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBhbmltYXRpb24ub3B0cy5zdGFydCApICkge1xuXHRcdGFuaW1hdGlvbi5vcHRzLnN0YXJ0LmNhbGwoIGVsZW0sIGFuaW1hdGlvbiApO1xuXHR9XG5cblx0alF1ZXJ5LmZ4LnRpbWVyKFxuXHRcdGpRdWVyeS5leHRlbmQoIHRpY2ssIHtcblx0XHRcdGVsZW06IGVsZW0sXG5cdFx0XHRhbmltOiBhbmltYXRpb24sXG5cdFx0XHRxdWV1ZTogYW5pbWF0aW9uLm9wdHMucXVldWVcblx0XHR9KVxuXHQpO1xuXG5cdC8vIGF0dGFjaCBjYWxsYmFja3MgZnJvbSBvcHRpb25zXG5cdHJldHVybiBhbmltYXRpb24ucHJvZ3Jlc3MoIGFuaW1hdGlvbi5vcHRzLnByb2dyZXNzIClcblx0XHQuZG9uZSggYW5pbWF0aW9uLm9wdHMuZG9uZSwgYW5pbWF0aW9uLm9wdHMuY29tcGxldGUgKVxuXHRcdC5mYWlsKCBhbmltYXRpb24ub3B0cy5mYWlsIClcblx0XHQuYWx3YXlzKCBhbmltYXRpb24ub3B0cy5hbHdheXMgKTtcbn1cblxualF1ZXJ5LkFuaW1hdGlvbiA9IGpRdWVyeS5leHRlbmQoIEFuaW1hdGlvbiwge1xuXHR0d2VlbmVyOiBmdW5jdGlvbiggcHJvcHMsIGNhbGxiYWNrICkge1xuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHByb3BzICkgKSB7XG5cdFx0XHRjYWxsYmFjayA9IHByb3BzO1xuXHRcdFx0cHJvcHMgPSBbIFwiKlwiIF07XG5cdFx0fSBlbHNlIHtcblx0XHRcdHByb3BzID0gcHJvcHMuc3BsaXQoXCIgXCIpO1xuXHRcdH1cblxuXHRcdHZhciBwcm9wLFxuXHRcdFx0aW5kZXggPSAwLFxuXHRcdFx0bGVuZ3RoID0gcHJvcHMubGVuZ3RoO1xuXG5cdFx0Zm9yICggOyBpbmRleCA8IGxlbmd0aCA7IGluZGV4KysgKSB7XG5cdFx0XHRwcm9wID0gcHJvcHNbIGluZGV4IF07XG5cdFx0XHR0d2VlbmVyc1sgcHJvcCBdID0gdHdlZW5lcnNbIHByb3AgXSB8fCBbXTtcblx0XHRcdHR3ZWVuZXJzWyBwcm9wIF0udW5zaGlmdCggY2FsbGJhY2sgKTtcblx0XHR9XG5cdH0sXG5cblx0cHJlZmlsdGVyOiBmdW5jdGlvbiggY2FsbGJhY2ssIHByZXBlbmQgKSB7XG5cdFx0aWYgKCBwcmVwZW5kICkge1xuXHRcdFx0YW5pbWF0aW9uUHJlZmlsdGVycy51bnNoaWZ0KCBjYWxsYmFjayApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhbmltYXRpb25QcmVmaWx0ZXJzLnB1c2goIGNhbGxiYWNrICk7XG5cdFx0fVxuXHR9XG59KTtcblxualF1ZXJ5LnNwZWVkID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGZuICkge1xuXHR2YXIgb3B0ID0gc3BlZWQgJiYgdHlwZW9mIHNwZWVkID09PSBcIm9iamVjdFwiID8galF1ZXJ5LmV4dGVuZCgge30sIHNwZWVkICkgOiB7XG5cdFx0Y29tcGxldGU6IGZuIHx8ICFmbiAmJiBlYXNpbmcgfHxcblx0XHRcdGpRdWVyeS5pc0Z1bmN0aW9uKCBzcGVlZCApICYmIHNwZWVkLFxuXHRcdGR1cmF0aW9uOiBzcGVlZCxcblx0XHRlYXNpbmc6IGZuICYmIGVhc2luZyB8fCBlYXNpbmcgJiYgIWpRdWVyeS5pc0Z1bmN0aW9uKCBlYXNpbmcgKSAmJiBlYXNpbmdcblx0fTtcblxuXHRvcHQuZHVyYXRpb24gPSBqUXVlcnkuZngub2ZmID8gMCA6IHR5cGVvZiBvcHQuZHVyYXRpb24gPT09IFwibnVtYmVyXCIgPyBvcHQuZHVyYXRpb24gOlxuXHRcdG9wdC5kdXJhdGlvbiBpbiBqUXVlcnkuZnguc3BlZWRzID8galF1ZXJ5LmZ4LnNwZWVkc1sgb3B0LmR1cmF0aW9uIF0gOiBqUXVlcnkuZnguc3BlZWRzLl9kZWZhdWx0O1xuXG5cdC8vIG5vcm1hbGl6ZSBvcHQucXVldWUgLSB0cnVlL3VuZGVmaW5lZC9udWxsIC0+IFwiZnhcIlxuXHRpZiAoIG9wdC5xdWV1ZSA9PSBudWxsIHx8IG9wdC5xdWV1ZSA9PT0gdHJ1ZSApIHtcblx0XHRvcHQucXVldWUgPSBcImZ4XCI7XG5cdH1cblxuXHQvLyBRdWV1ZWluZ1xuXHRvcHQub2xkID0gb3B0LmNvbXBsZXRlO1xuXG5cdG9wdC5jb21wbGV0ZSA9IGZ1bmN0aW9uKCkge1xuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIG9wdC5vbGQgKSApIHtcblx0XHRcdG9wdC5vbGQuY2FsbCggdGhpcyApO1xuXHRcdH1cblxuXHRcdGlmICggb3B0LnF1ZXVlICkge1xuXHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIG9wdC5xdWV1ZSApO1xuXHRcdH1cblx0fTtcblxuXHRyZXR1cm4gb3B0O1xufTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGZhZGVUbzogZnVuY3Rpb24oIHNwZWVkLCB0bywgZWFzaW5nLCBjYWxsYmFjayApIHtcblxuXHRcdC8vIHNob3cgYW55IGhpZGRlbiBlbGVtZW50cyBhZnRlciBzZXR0aW5nIG9wYWNpdHkgdG8gMFxuXHRcdHJldHVybiB0aGlzLmZpbHRlciggaXNIaWRkZW4gKS5jc3MoIFwib3BhY2l0eVwiLCAwICkuc2hvdygpXG5cblx0XHRcdC8vIGFuaW1hdGUgdG8gdGhlIHZhbHVlIHNwZWNpZmllZFxuXHRcdFx0LmVuZCgpLmFuaW1hdGUoeyBvcGFjaXR5OiB0byB9LCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9LFxuXHRhbmltYXRlOiBmdW5jdGlvbiggcHJvcCwgc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSB7XG5cdFx0dmFyIGVtcHR5ID0galF1ZXJ5LmlzRW1wdHlPYmplY3QoIHByb3AgKSxcblx0XHRcdG9wdGFsbCA9IGpRdWVyeS5zcGVlZCggc3BlZWQsIGVhc2luZywgY2FsbGJhY2sgKSxcblx0XHRcdGRvQW5pbWF0aW9uID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRcdC8vIE9wZXJhdGUgb24gYSBjb3B5IG9mIHByb3Agc28gcGVyLXByb3BlcnR5IGVhc2luZyB3b24ndCBiZSBsb3N0XG5cdFx0XHRcdHZhciBhbmltID0gQW5pbWF0aW9uKCB0aGlzLCBqUXVlcnkuZXh0ZW5kKCB7fSwgcHJvcCApLCBvcHRhbGwgKTtcblxuXHRcdFx0XHQvLyBFbXB0eSBhbmltYXRpb25zLCBvciBmaW5pc2hpbmcgcmVzb2x2ZXMgaW1tZWRpYXRlbHlcblx0XHRcdFx0aWYgKCBlbXB0eSB8fCBqUXVlcnkuX2RhdGEoIHRoaXMsIFwiZmluaXNoXCIgKSApIHtcblx0XHRcdFx0XHRhbmltLnN0b3AoIHRydWUgKTtcblx0XHRcdFx0fVxuXHRcdFx0fTtcblx0XHRcdGRvQW5pbWF0aW9uLmZpbmlzaCA9IGRvQW5pbWF0aW9uO1xuXG5cdFx0cmV0dXJuIGVtcHR5IHx8IG9wdGFsbC5xdWV1ZSA9PT0gZmFsc2UgP1xuXHRcdFx0dGhpcy5lYWNoKCBkb0FuaW1hdGlvbiApIDpcblx0XHRcdHRoaXMucXVldWUoIG9wdGFsbC5xdWV1ZSwgZG9BbmltYXRpb24gKTtcblx0fSxcblx0c3RvcDogZnVuY3Rpb24oIHR5cGUsIGNsZWFyUXVldWUsIGdvdG9FbmQgKSB7XG5cdFx0dmFyIHN0b3BRdWV1ZSA9IGZ1bmN0aW9uKCBob29rcyApIHtcblx0XHRcdHZhciBzdG9wID0gaG9va3Muc3RvcDtcblx0XHRcdGRlbGV0ZSBob29rcy5zdG9wO1xuXHRcdFx0c3RvcCggZ290b0VuZCApO1xuXHRcdH07XG5cblx0XHRpZiAoIHR5cGVvZiB0eXBlICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0Z290b0VuZCA9IGNsZWFyUXVldWU7XG5cdFx0XHRjbGVhclF1ZXVlID0gdHlwZTtcblx0XHRcdHR5cGUgPSB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICggY2xlYXJRdWV1ZSAmJiB0eXBlICE9PSBmYWxzZSApIHtcblx0XHRcdHRoaXMucXVldWUoIHR5cGUgfHwgXCJmeFwiLCBbXSApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgZGVxdWV1ZSA9IHRydWUsXG5cdFx0XHRcdGluZGV4ID0gdHlwZSAhPSBudWxsICYmIHR5cGUgKyBcInF1ZXVlSG9va3NcIixcblx0XHRcdFx0dGltZXJzID0galF1ZXJ5LnRpbWVycyxcblx0XHRcdFx0ZGF0YSA9IGpRdWVyeS5fZGF0YSggdGhpcyApO1xuXG5cdFx0XHRpZiAoIGluZGV4ICkge1xuXHRcdFx0XHRpZiAoIGRhdGFbIGluZGV4IF0gJiYgZGF0YVsgaW5kZXggXS5zdG9wICkge1xuXHRcdFx0XHRcdHN0b3BRdWV1ZSggZGF0YVsgaW5kZXggXSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRmb3IgKCBpbmRleCBpbiBkYXRhICkge1xuXHRcdFx0XHRcdGlmICggZGF0YVsgaW5kZXggXSAmJiBkYXRhWyBpbmRleCBdLnN0b3AgJiYgcnJ1bi50ZXN0KCBpbmRleCApICkge1xuXHRcdFx0XHRcdFx0c3RvcFF1ZXVlKCBkYXRhWyBpbmRleCBdICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdGZvciAoIGluZGV4ID0gdGltZXJzLmxlbmd0aDsgaW5kZXgtLTsgKSB7XG5cdFx0XHRcdGlmICggdGltZXJzWyBpbmRleCBdLmVsZW0gPT09IHRoaXMgJiYgKHR5cGUgPT0gbnVsbCB8fCB0aW1lcnNbIGluZGV4IF0ucXVldWUgPT09IHR5cGUpICkge1xuXHRcdFx0XHRcdHRpbWVyc1sgaW5kZXggXS5hbmltLnN0b3AoIGdvdG9FbmQgKTtcblx0XHRcdFx0XHRkZXF1ZXVlID0gZmFsc2U7XG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBzdGFydCB0aGUgbmV4dCBpbiB0aGUgcXVldWUgaWYgdGhlIGxhc3Qgc3RlcCB3YXNuJ3QgZm9yY2VkXG5cdFx0XHQvLyB0aW1lcnMgY3VycmVudGx5IHdpbGwgY2FsbCB0aGVpciBjb21wbGV0ZSBjYWxsYmFja3MsIHdoaWNoIHdpbGwgZGVxdWV1ZVxuXHRcdFx0Ly8gYnV0IG9ubHkgaWYgdGhleSB3ZXJlIGdvdG9FbmRcblx0XHRcdGlmICggZGVxdWV1ZSB8fCAhZ290b0VuZCApIHtcblx0XHRcdFx0alF1ZXJ5LmRlcXVldWUoIHRoaXMsIHR5cGUgKTtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblx0ZmluaXNoOiBmdW5jdGlvbiggdHlwZSApIHtcblx0XHRpZiAoIHR5cGUgIT09IGZhbHNlICkge1xuXHRcdFx0dHlwZSA9IHR5cGUgfHwgXCJmeFwiO1xuXHRcdH1cblx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIGluZGV4LFxuXHRcdFx0XHRkYXRhID0galF1ZXJ5Ll9kYXRhKCB0aGlzICksXG5cdFx0XHRcdHF1ZXVlID0gZGF0YVsgdHlwZSArIFwicXVldWVcIiBdLFxuXHRcdFx0XHRob29rcyA9IGRhdGFbIHR5cGUgKyBcInF1ZXVlSG9va3NcIiBdLFxuXHRcdFx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdFx0XHRsZW5ndGggPSBxdWV1ZSA/IHF1ZXVlLmxlbmd0aCA6IDA7XG5cblx0XHRcdC8vIGVuYWJsZSBmaW5pc2hpbmcgZmxhZyBvbiBwcml2YXRlIGRhdGFcblx0XHRcdGRhdGEuZmluaXNoID0gdHJ1ZTtcblxuXHRcdFx0Ly8gZW1wdHkgdGhlIHF1ZXVlIGZpcnN0XG5cdFx0XHRqUXVlcnkucXVldWUoIHRoaXMsIHR5cGUsIFtdICk7XG5cblx0XHRcdGlmICggaG9va3MgJiYgaG9va3Muc3RvcCApIHtcblx0XHRcdFx0aG9va3Muc3RvcC5jYWxsKCB0aGlzLCB0cnVlICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIGxvb2sgZm9yIGFueSBhY3RpdmUgYW5pbWF0aW9ucywgYW5kIGZpbmlzaCB0aGVtXG5cdFx0XHRmb3IgKCBpbmRleCA9IHRpbWVycy5sZW5ndGg7IGluZGV4LS07ICkge1xuXHRcdFx0XHRpZiAoIHRpbWVyc1sgaW5kZXggXS5lbGVtID09PSB0aGlzICYmIHRpbWVyc1sgaW5kZXggXS5xdWV1ZSA9PT0gdHlwZSApIHtcblx0XHRcdFx0XHR0aW1lcnNbIGluZGV4IF0uYW5pbS5zdG9wKCB0cnVlICk7XG5cdFx0XHRcdFx0dGltZXJzLnNwbGljZSggaW5kZXgsIDEgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyBsb29rIGZvciBhbnkgYW5pbWF0aW9ucyBpbiB0aGUgb2xkIHF1ZXVlIGFuZCBmaW5pc2ggdGhlbVxuXHRcdFx0Zm9yICggaW5kZXggPSAwOyBpbmRleCA8IGxlbmd0aDsgaW5kZXgrKyApIHtcblx0XHRcdFx0aWYgKCBxdWV1ZVsgaW5kZXggXSAmJiBxdWV1ZVsgaW5kZXggXS5maW5pc2ggKSB7XG5cdFx0XHRcdFx0cXVldWVbIGluZGV4IF0uZmluaXNoLmNhbGwoIHRoaXMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0XHQvLyB0dXJuIG9mZiBmaW5pc2hpbmcgZmxhZ1xuXHRcdFx0ZGVsZXRlIGRhdGEuZmluaXNoO1xuXHRcdH0pO1xuXHR9XG59KTtcblxualF1ZXJ5LmVhY2goWyBcInRvZ2dsZVwiLCBcInNob3dcIiwgXCJoaWRlXCIgXSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cdHZhciBjc3NGbiA9IGpRdWVyeS5mblsgbmFtZSBdO1xuXHRqUXVlcnkuZm5bIG5hbWUgXSA9IGZ1bmN0aW9uKCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4gc3BlZWQgPT0gbnVsbCB8fCB0eXBlb2Ygc3BlZWQgPT09IFwiYm9vbGVhblwiID9cblx0XHRcdGNzc0ZuLmFwcGx5KCB0aGlzLCBhcmd1bWVudHMgKSA6XG5cdFx0XHR0aGlzLmFuaW1hdGUoIGdlbkZ4KCBuYW1lLCB0cnVlICksIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICk7XG5cdH07XG59KTtcblxuLy8gR2VuZXJhdGUgc2hvcnRjdXRzIGZvciBjdXN0b20gYW5pbWF0aW9uc1xualF1ZXJ5LmVhY2goe1xuXHRzbGlkZURvd246IGdlbkZ4KFwic2hvd1wiKSxcblx0c2xpZGVVcDogZ2VuRngoXCJoaWRlXCIpLFxuXHRzbGlkZVRvZ2dsZTogZ2VuRngoXCJ0b2dnbGVcIiksXG5cdGZhZGVJbjogeyBvcGFjaXR5OiBcInNob3dcIiB9LFxuXHRmYWRlT3V0OiB7IG9wYWNpdHk6IFwiaGlkZVwiIH0sXG5cdGZhZGVUb2dnbGU6IHsgb3BhY2l0eTogXCJ0b2dnbGVcIiB9XG59LCBmdW5jdGlvbiggbmFtZSwgcHJvcHMgKSB7XG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIHNwZWVkLCBlYXNpbmcsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiB0aGlzLmFuaW1hdGUoIHByb3BzLCBzcGVlZCwgZWFzaW5nLCBjYWxsYmFjayApO1xuXHR9O1xufSk7XG5cbmpRdWVyeS50aW1lcnMgPSBbXTtcbmpRdWVyeS5meC50aWNrID0gZnVuY3Rpb24oKSB7XG5cdHZhciB0aW1lcixcblx0XHR0aW1lcnMgPSBqUXVlcnkudGltZXJzLFxuXHRcdGkgPSAwO1xuXG5cdGZ4Tm93ID0galF1ZXJ5Lm5vdygpO1xuXG5cdGZvciAoIDsgaSA8IHRpbWVycy5sZW5ndGg7IGkrKyApIHtcblx0XHR0aW1lciA9IHRpbWVyc1sgaSBdO1xuXHRcdC8vIENoZWNrcyB0aGUgdGltZXIgaGFzIG5vdCBhbHJlYWR5IGJlZW4gcmVtb3ZlZFxuXHRcdGlmICggIXRpbWVyKCkgJiYgdGltZXJzWyBpIF0gPT09IHRpbWVyICkge1xuXHRcdFx0dGltZXJzLnNwbGljZSggaS0tLCAxICk7XG5cdFx0fVxuXHR9XG5cblx0aWYgKCAhdGltZXJzLmxlbmd0aCApIHtcblx0XHRqUXVlcnkuZnguc3RvcCgpO1xuXHR9XG5cdGZ4Tm93ID0gdW5kZWZpbmVkO1xufTtcblxualF1ZXJ5LmZ4LnRpbWVyID0gZnVuY3Rpb24oIHRpbWVyICkge1xuXHRqUXVlcnkudGltZXJzLnB1c2goIHRpbWVyICk7XG5cdGlmICggdGltZXIoKSApIHtcblx0XHRqUXVlcnkuZnguc3RhcnQoKTtcblx0fSBlbHNlIHtcblx0XHRqUXVlcnkudGltZXJzLnBvcCgpO1xuXHR9XG59O1xuXG5qUXVlcnkuZnguaW50ZXJ2YWwgPSAxMztcblxualF1ZXJ5LmZ4LnN0YXJ0ID0gZnVuY3Rpb24oKSB7XG5cdGlmICggIXRpbWVySWQgKSB7XG5cdFx0dGltZXJJZCA9IHNldEludGVydmFsKCBqUXVlcnkuZngudGljaywgalF1ZXJ5LmZ4LmludGVydmFsICk7XG5cdH1cbn07XG5cbmpRdWVyeS5meC5zdG9wID0gZnVuY3Rpb24oKSB7XG5cdGNsZWFySW50ZXJ2YWwoIHRpbWVySWQgKTtcblx0dGltZXJJZCA9IG51bGw7XG59O1xuXG5qUXVlcnkuZnguc3BlZWRzID0ge1xuXHRzbG93OiA2MDAsXG5cdGZhc3Q6IDIwMCxcblx0Ly8gRGVmYXVsdCBzcGVlZFxuXHRfZGVmYXVsdDogNDAwXG59O1xuXG5cbi8vIEJhc2VkIG9mZiBvZiB0aGUgcGx1Z2luIGJ5IENsaW50IEhlbGZlcnMsIHdpdGggcGVybWlzc2lvbi5cbi8vIGh0dHA6Ly9ibGluZHNpZ25hbHMuY29tL2luZGV4LnBocC8yMDA5LzA3L2pxdWVyeS1kZWxheS9cbmpRdWVyeS5mbi5kZWxheSA9IGZ1bmN0aW9uKCB0aW1lLCB0eXBlICkge1xuXHR0aW1lID0galF1ZXJ5LmZ4ID8galF1ZXJ5LmZ4LnNwZWVkc1sgdGltZSBdIHx8IHRpbWUgOiB0aW1lO1xuXHR0eXBlID0gdHlwZSB8fCBcImZ4XCI7XG5cblx0cmV0dXJuIHRoaXMucXVldWUoIHR5cGUsIGZ1bmN0aW9uKCBuZXh0LCBob29rcyApIHtcblx0XHR2YXIgdGltZW91dCA9IHNldFRpbWVvdXQoIG5leHQsIHRpbWUgKTtcblx0XHRob29rcy5zdG9wID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRjbGVhclRpbWVvdXQoIHRpbWVvdXQgKTtcblx0XHR9O1xuXHR9KTtcbn07XG5cblxuKGZ1bmN0aW9uKCkge1xuXHQvLyBNaW5pZmllZDogdmFyIGEsYixjLGQsZVxuXHR2YXIgaW5wdXQsIGRpdiwgc2VsZWN0LCBhLCBvcHQ7XG5cblx0Ly8gU2V0dXBcblx0ZGl2ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJkaXZcIiApO1xuXHRkaXYuc2V0QXR0cmlidXRlKCBcImNsYXNzTmFtZVwiLCBcInRcIiApO1xuXHRkaXYuaW5uZXJIVE1MID0gXCIgIDxsaW5rLz48dGFibGU+PC90YWJsZT48YSBocmVmPScvYSc+YTwvYT48aW5wdXQgdHlwZT0nY2hlY2tib3gnLz5cIjtcblx0YSA9IGRpdi5nZXRFbGVtZW50c0J5VGFnTmFtZShcImFcIilbIDAgXTtcblxuXHQvLyBGaXJzdCBiYXRjaCBvZiB0ZXN0cy5cblx0c2VsZWN0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcInNlbGVjdFwiKTtcblx0b3B0ID0gc2VsZWN0LmFwcGVuZENoaWxkKCBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwib3B0aW9uXCIpICk7XG5cdGlucHV0ID0gZGl2LmdldEVsZW1lbnRzQnlUYWdOYW1lKFwiaW5wdXRcIilbIDAgXTtcblxuXHRhLnN0eWxlLmNzc1RleHQgPSBcInRvcDoxcHhcIjtcblxuXHQvLyBUZXN0IHNldEF0dHJpYnV0ZSBvbiBjYW1lbENhc2UgY2xhc3MuIElmIGl0IHdvcmtzLCB3ZSBuZWVkIGF0dHJGaXhlcyB3aGVuIGRvaW5nIGdldC9zZXRBdHRyaWJ1dGUgKGllNi83KVxuXHRzdXBwb3J0LmdldFNldEF0dHJpYnV0ZSA9IGRpdi5jbGFzc05hbWUgIT09IFwidFwiO1xuXG5cdC8vIEdldCB0aGUgc3R5bGUgaW5mb3JtYXRpb24gZnJvbSBnZXRBdHRyaWJ1dGVcblx0Ly8gKElFIHVzZXMgLmNzc1RleHQgaW5zdGVhZClcblx0c3VwcG9ydC5zdHlsZSA9IC90b3AvLnRlc3QoIGEuZ2V0QXR0cmlidXRlKFwic3R5bGVcIikgKTtcblxuXHQvLyBNYWtlIHN1cmUgdGhhdCBVUkxzIGFyZW4ndCBtYW5pcHVsYXRlZFxuXHQvLyAoSUUgbm9ybWFsaXplcyBpdCBieSBkZWZhdWx0KVxuXHRzdXBwb3J0LmhyZWZOb3JtYWxpemVkID0gYS5nZXRBdHRyaWJ1dGUoXCJocmVmXCIpID09PSBcIi9hXCI7XG5cblx0Ly8gQ2hlY2sgdGhlIGRlZmF1bHQgY2hlY2tib3gvcmFkaW8gdmFsdWUgKFwiXCIgb24gV2ViS2l0OyBcIm9uXCIgZWxzZXdoZXJlKVxuXHRzdXBwb3J0LmNoZWNrT24gPSAhIWlucHV0LnZhbHVlO1xuXG5cdC8vIE1ha2Ugc3VyZSB0aGF0IGEgc2VsZWN0ZWQtYnktZGVmYXVsdCBvcHRpb24gaGFzIGEgd29ya2luZyBzZWxlY3RlZCBwcm9wZXJ0eS5cblx0Ly8gKFdlYktpdCBkZWZhdWx0cyB0byBmYWxzZSBpbnN0ZWFkIG9mIHRydWUsIElFIHRvbywgaWYgaXQncyBpbiBhbiBvcHRncm91cClcblx0c3VwcG9ydC5vcHRTZWxlY3RlZCA9IG9wdC5zZWxlY3RlZDtcblxuXHQvLyBUZXN0cyBmb3IgZW5jdHlwZSBzdXBwb3J0IG9uIGEgZm9ybSAoIzY3NDMpXG5cdHN1cHBvcnQuZW5jdHlwZSA9ICEhZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcImZvcm1cIikuZW5jdHlwZTtcblxuXHQvLyBNYWtlIHN1cmUgdGhhdCB0aGUgb3B0aW9ucyBpbnNpZGUgZGlzYWJsZWQgc2VsZWN0cyBhcmVuJ3QgbWFya2VkIGFzIGRpc2FibGVkXG5cdC8vIChXZWJLaXQgbWFya3MgdGhlbSBhcyBkaXNhYmxlZClcblx0c2VsZWN0LmRpc2FibGVkID0gdHJ1ZTtcblx0c3VwcG9ydC5vcHREaXNhYmxlZCA9ICFvcHQuZGlzYWJsZWQ7XG5cblx0Ly8gU3VwcG9ydDogSUU4IG9ubHlcblx0Ly8gQ2hlY2sgaWYgd2UgY2FuIHRydXN0IGdldEF0dHJpYnV0ZShcInZhbHVlXCIpXG5cdGlucHV0ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCggXCJpbnB1dFwiICk7XG5cdGlucHV0LnNldEF0dHJpYnV0ZSggXCJ2YWx1ZVwiLCBcIlwiICk7XG5cdHN1cHBvcnQuaW5wdXQgPSBpbnB1dC5nZXRBdHRyaWJ1dGUoIFwidmFsdWVcIiApID09PSBcIlwiO1xuXG5cdC8vIENoZWNrIGlmIGFuIGlucHV0IG1haW50YWlucyBpdHMgdmFsdWUgYWZ0ZXIgYmVjb21pbmcgYSByYWRpb1xuXHRpbnB1dC52YWx1ZSA9IFwidFwiO1xuXHRpbnB1dC5zZXRBdHRyaWJ1dGUoIFwidHlwZVwiLCBcInJhZGlvXCIgKTtcblx0c3VwcG9ydC5yYWRpb1ZhbHVlID0gaW5wdXQudmFsdWUgPT09IFwidFwiO1xufSkoKTtcblxuXG52YXIgcnJldHVybiA9IC9cXHIvZztcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdHZhbDogZnVuY3Rpb24oIHZhbHVlICkge1xuXHRcdHZhciBob29rcywgcmV0LCBpc0Z1bmN0aW9uLFxuXHRcdFx0ZWxlbSA9IHRoaXNbMF07XG5cblx0XHRpZiAoICFhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0aWYgKCBlbGVtICkge1xuXHRcdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgZWxlbS50eXBlIF0gfHwgalF1ZXJ5LnZhbEhvb2tzWyBlbGVtLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgXTtcblxuXHRcdFx0XHRpZiAoIGhvb2tzICYmIFwiZ2V0XCIgaW4gaG9va3MgJiYgKHJldCA9IGhvb2tzLmdldCggZWxlbSwgXCJ2YWx1ZVwiICkpICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHJldDtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldCA9IGVsZW0udmFsdWU7XG5cblx0XHRcdFx0cmV0dXJuIHR5cGVvZiByZXQgPT09IFwic3RyaW5nXCIgP1xuXHRcdFx0XHRcdC8vIGhhbmRsZSBtb3N0IGNvbW1vbiBzdHJpbmcgY2FzZXNcblx0XHRcdFx0XHRyZXQucmVwbGFjZShycmV0dXJuLCBcIlwiKSA6XG5cdFx0XHRcdFx0Ly8gaGFuZGxlIGNhc2VzIHdoZXJlIHZhbHVlIGlzIG51bGwvdW5kZWYgb3IgbnVtYmVyXG5cdFx0XHRcdFx0cmV0ID09IG51bGwgPyBcIlwiIDogcmV0O1xuXHRcdFx0fVxuXG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0aXNGdW5jdGlvbiA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApO1xuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaSApIHtcblx0XHRcdHZhciB2YWw7XG5cblx0XHRcdGlmICggdGhpcy5ub2RlVHlwZSAhPT0gMSApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIGlzRnVuY3Rpb24gKSB7XG5cdFx0XHRcdHZhbCA9IHZhbHVlLmNhbGwoIHRoaXMsIGksIGpRdWVyeSggdGhpcyApLnZhbCgpICk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR2YWwgPSB2YWx1ZTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gVHJlYXQgbnVsbC91bmRlZmluZWQgYXMgXCJcIjsgY29udmVydCBudW1iZXJzIHRvIHN0cmluZ1xuXHRcdFx0aWYgKCB2YWwgPT0gbnVsbCApIHtcblx0XHRcdFx0dmFsID0gXCJcIjtcblx0XHRcdH0gZWxzZSBpZiAoIHR5cGVvZiB2YWwgPT09IFwibnVtYmVyXCIgKSB7XG5cdFx0XHRcdHZhbCArPSBcIlwiO1xuXHRcdFx0fSBlbHNlIGlmICggalF1ZXJ5LmlzQXJyYXkoIHZhbCApICkge1xuXHRcdFx0XHR2YWwgPSBqUXVlcnkubWFwKCB2YWwsIGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHRcdFx0XHRyZXR1cm4gdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSArIFwiXCI7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXG5cdFx0XHRob29rcyA9IGpRdWVyeS52YWxIb29rc1sgdGhpcy50eXBlIF0gfHwgalF1ZXJ5LnZhbEhvb2tzWyB0aGlzLm5vZGVOYW1lLnRvTG93ZXJDYXNlKCkgXTtcblxuXHRcdFx0Ly8gSWYgc2V0IHJldHVybnMgdW5kZWZpbmVkLCBmYWxsIGJhY2sgdG8gbm9ybWFsIHNldHRpbmdcblx0XHRcdGlmICggIWhvb2tzIHx8ICEoXCJzZXRcIiBpbiBob29rcykgfHwgaG9va3Muc2V0KCB0aGlzLCB2YWwsIFwidmFsdWVcIiApID09PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHRoaXMudmFsdWUgPSB2YWw7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0dmFsSG9va3M6IHtcblx0XHRvcHRpb246IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciB2YWwgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBcInZhbHVlXCIgKTtcblx0XHRcdFx0cmV0dXJuIHZhbCAhPSBudWxsID9cblx0XHRcdFx0XHR2YWwgOlxuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFMTAtMTErXG5cdFx0XHRcdFx0Ly8gb3B0aW9uLnRleHQgdGhyb3dzIGV4Y2VwdGlvbnMgKCMxNDY4NiwgIzE0ODU4KVxuXHRcdFx0XHRcdGpRdWVyeS50cmltKCBqUXVlcnkudGV4dCggZWxlbSApICk7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRzZWxlY3Q6IHtcblx0XHRcdGdldDogZnVuY3Rpb24oIGVsZW0gKSB7XG5cdFx0XHRcdHZhciB2YWx1ZSwgb3B0aW9uLFxuXHRcdFx0XHRcdG9wdGlvbnMgPSBlbGVtLm9wdGlvbnMsXG5cdFx0XHRcdFx0aW5kZXggPSBlbGVtLnNlbGVjdGVkSW5kZXgsXG5cdFx0XHRcdFx0b25lID0gZWxlbS50eXBlID09PSBcInNlbGVjdC1vbmVcIiB8fCBpbmRleCA8IDAsXG5cdFx0XHRcdFx0dmFsdWVzID0gb25lID8gbnVsbCA6IFtdLFxuXHRcdFx0XHRcdG1heCA9IG9uZSA/IGluZGV4ICsgMSA6IG9wdGlvbnMubGVuZ3RoLFxuXHRcdFx0XHRcdGkgPSBpbmRleCA8IDAgP1xuXHRcdFx0XHRcdFx0bWF4IDpcblx0XHRcdFx0XHRcdG9uZSA/IGluZGV4IDogMDtcblxuXHRcdFx0XHQvLyBMb29wIHRocm91Z2ggYWxsIHRoZSBzZWxlY3RlZCBvcHRpb25zXG5cdFx0XHRcdGZvciAoIDsgaSA8IG1heDsgaSsrICkge1xuXHRcdFx0XHRcdG9wdGlvbiA9IG9wdGlvbnNbIGkgXTtcblxuXHRcdFx0XHRcdC8vIG9sZElFIGRvZXNuJ3QgdXBkYXRlIHNlbGVjdGVkIGFmdGVyIGZvcm0gcmVzZXQgKCMyNTUxKVxuXHRcdFx0XHRcdGlmICggKCBvcHRpb24uc2VsZWN0ZWQgfHwgaSA9PT0gaW5kZXggKSAmJlxuXHRcdFx0XHRcdFx0XHQvLyBEb24ndCByZXR1cm4gb3B0aW9ucyB0aGF0IGFyZSBkaXNhYmxlZCBvciBpbiBhIGRpc2FibGVkIG9wdGdyb3VwXG5cdFx0XHRcdFx0XHRcdCggc3VwcG9ydC5vcHREaXNhYmxlZCA/ICFvcHRpb24uZGlzYWJsZWQgOiBvcHRpb24uZ2V0QXR0cmlidXRlKFwiZGlzYWJsZWRcIikgPT09IG51bGwgKSAmJlxuXHRcdFx0XHRcdFx0XHQoICFvcHRpb24ucGFyZW50Tm9kZS5kaXNhYmxlZCB8fCAhalF1ZXJ5Lm5vZGVOYW1lKCBvcHRpb24ucGFyZW50Tm9kZSwgXCJvcHRncm91cFwiICkgKSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gR2V0IHRoZSBzcGVjaWZpYyB2YWx1ZSBmb3IgdGhlIG9wdGlvblxuXHRcdFx0XHRcdFx0dmFsdWUgPSBqUXVlcnkoIG9wdGlvbiApLnZhbCgpO1xuXG5cdFx0XHRcdFx0XHQvLyBXZSBkb24ndCBuZWVkIGFuIGFycmF5IGZvciBvbmUgc2VsZWN0c1xuXHRcdFx0XHRcdFx0aWYgKCBvbmUgKSB7XG5cdFx0XHRcdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0Ly8gTXVsdGktU2VsZWN0cyByZXR1cm4gYW4gYXJyYXlcblx0XHRcdFx0XHRcdHZhbHVlcy5wdXNoKCB2YWx1ZSApO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiB2YWx1ZXM7XG5cdFx0XHR9LFxuXG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdFx0dmFyIG9wdGlvblNldCwgb3B0aW9uLFxuXHRcdFx0XHRcdG9wdGlvbnMgPSBlbGVtLm9wdGlvbnMsXG5cdFx0XHRcdFx0dmFsdWVzID0galF1ZXJ5Lm1ha2VBcnJheSggdmFsdWUgKSxcblx0XHRcdFx0XHRpID0gb3B0aW9ucy5sZW5ndGg7XG5cblx0XHRcdFx0d2hpbGUgKCBpLS0gKSB7XG5cdFx0XHRcdFx0b3B0aW9uID0gb3B0aW9uc1sgaSBdO1xuXG5cdFx0XHRcdFx0aWYgKCBqUXVlcnkuaW5BcnJheSggalF1ZXJ5LnZhbEhvb2tzLm9wdGlvbi5nZXQoIG9wdGlvbiApLCB2YWx1ZXMgKSA+PSAwICkge1xuXG5cdFx0XHRcdFx0XHQvLyBTdXBwb3J0OiBJRTZcblx0XHRcdFx0XHRcdC8vIFdoZW4gbmV3IG9wdGlvbiBlbGVtZW50IGlzIGFkZGVkIHRvIHNlbGVjdCBib3ggd2UgbmVlZCB0b1xuXHRcdFx0XHRcdFx0Ly8gZm9yY2UgcmVmbG93IG9mIG5ld2x5IGFkZGVkIG5vZGUgaW4gb3JkZXIgdG8gd29ya2Fyb3VuZCBkZWxheVxuXHRcdFx0XHRcdFx0Ly8gb2YgaW5pdGlhbGl6YXRpb24gcHJvcGVydGllc1xuXHRcdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdFx0b3B0aW9uLnNlbGVjdGVkID0gb3B0aW9uU2V0ID0gdHJ1ZTtcblxuXHRcdFx0XHRcdFx0fSBjYXRjaCAoIF8gKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gV2lsbCBiZSBleGVjdXRlZCBvbmx5IGluIElFNlxuXHRcdFx0XHRcdFx0XHRvcHRpb24uc2Nyb2xsSGVpZ2h0O1xuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdG9wdGlvbi5zZWxlY3RlZCA9IGZhbHNlO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIEZvcmNlIGJyb3dzZXJzIHRvIGJlaGF2ZSBjb25zaXN0ZW50bHkgd2hlbiBub24tbWF0Y2hpbmcgdmFsdWUgaXMgc2V0XG5cdFx0XHRcdGlmICggIW9wdGlvblNldCApIHtcblx0XHRcdFx0XHRlbGVtLnNlbGVjdGVkSW5kZXggPSAtMTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdHJldHVybiBvcHRpb25zO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxufSk7XG5cbi8vIFJhZGlvcyBhbmQgY2hlY2tib3hlcyBnZXR0ZXIvc2V0dGVyXG5qUXVlcnkuZWFjaChbIFwicmFkaW9cIiwgXCJjaGVja2JveFwiIF0sIGZ1bmN0aW9uKCkge1xuXHRqUXVlcnkudmFsSG9va3NbIHRoaXMgXSA9IHtcblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdGlmICggalF1ZXJ5LmlzQXJyYXkoIHZhbHVlICkgKSB7XG5cdFx0XHRcdHJldHVybiAoIGVsZW0uY2hlY2tlZCA9IGpRdWVyeS5pbkFycmF5KCBqUXVlcnkoZWxlbSkudmFsKCksIHZhbHVlICkgPj0gMCApO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcblx0aWYgKCAhc3VwcG9ydC5jaGVja09uICkge1xuXHRcdGpRdWVyeS52YWxIb29rc1sgdGhpcyBdLmdldCA9IGZ1bmN0aW9uKCBlbGVtICkge1xuXHRcdFx0Ly8gU3VwcG9ydDogV2Via2l0XG5cdFx0XHQvLyBcIlwiIGlzIHJldHVybmVkIGluc3RlYWQgb2YgXCJvblwiIGlmIGEgdmFsdWUgaXNuJ3Qgc3BlY2lmaWVkXG5cdFx0XHRyZXR1cm4gZWxlbS5nZXRBdHRyaWJ1dGUoXCJ2YWx1ZVwiKSA9PT0gbnVsbCA/IFwib25cIiA6IGVsZW0udmFsdWU7XG5cdFx0fTtcblx0fVxufSk7XG5cblxuXG5cbnZhciBub2RlSG9vaywgYm9vbEhvb2ssXG5cdGF0dHJIYW5kbGUgPSBqUXVlcnkuZXhwci5hdHRySGFuZGxlLFxuXHRydXNlRGVmYXVsdCA9IC9eKD86Y2hlY2tlZHxzZWxlY3RlZCkkL2ksXG5cdGdldFNldEF0dHJpYnV0ZSA9IHN1cHBvcnQuZ2V0U2V0QXR0cmlidXRlLFxuXHRnZXRTZXRJbnB1dCA9IHN1cHBvcnQuaW5wdXQ7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRhdHRyOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LmF0dHIsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBuYW1lICkge1xuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggdGhpcywgbmFtZSApO1xuXHRcdH0pO1xuXHR9XG59KTtcblxualF1ZXJ5LmV4dGVuZCh7XG5cdGF0dHI6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHR2YXIgaG9va3MsIHJldCxcblx0XHRcdG5UeXBlID0gZWxlbS5ub2RlVHlwZTtcblxuXHRcdC8vIGRvbid0IGdldC9zZXQgYXR0cmlidXRlcyBvbiB0ZXh0LCBjb21tZW50IGFuZCBhdHRyaWJ1dGUgbm9kZXNcblx0XHRpZiAoICFlbGVtIHx8IG5UeXBlID09PSAzIHx8IG5UeXBlID09PSA4IHx8IG5UeXBlID09PSAyICkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIEZhbGxiYWNrIHRvIHByb3Agd2hlbiBhdHRyaWJ1dGVzIGFyZSBub3Qgc3VwcG9ydGVkXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS5nZXRBdHRyaWJ1dGUgPT09IHN0cnVuZGVmaW5lZCApIHtcblx0XHRcdHJldHVybiBqUXVlcnkucHJvcCggZWxlbSwgbmFtZSwgdmFsdWUgKTtcblx0XHR9XG5cblx0XHQvLyBBbGwgYXR0cmlidXRlcyBhcmUgbG93ZXJjYXNlXG5cdFx0Ly8gR3JhYiBuZWNlc3NhcnkgaG9vayBpZiBvbmUgaXMgZGVmaW5lZFxuXHRcdGlmICggblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApICkge1xuXHRcdFx0bmFtZSA9IG5hbWUudG9Mb3dlckNhc2UoKTtcblx0XHRcdGhvb2tzID0galF1ZXJ5LmF0dHJIb29rc1sgbmFtZSBdIHx8XG5cdFx0XHRcdCggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC50ZXN0KCBuYW1lICkgPyBib29sSG9vayA6IG5vZGVIb29rICk7XG5cdFx0fVxuXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXG5cdFx0XHRpZiAoIHZhbHVlID09PSBudWxsICkge1xuXHRcdFx0XHRqUXVlcnkucmVtb3ZlQXR0ciggZWxlbSwgbmFtZSApO1xuXG5cdFx0XHR9IGVsc2UgaWYgKCBob29rcyAmJiBcInNldFwiIGluIGhvb2tzICYmIChyZXQgPSBob29rcy5zZXQoIGVsZW0sIHZhbHVlLCBuYW1lICkpICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQ7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCBuYW1lLCB2YWx1ZSArIFwiXCIgKTtcblx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0fVxuXG5cdFx0fSBlbHNlIGlmICggaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAocmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkpICE9PSBudWxsICkge1xuXHRcdFx0cmV0dXJuIHJldDtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXQgPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBuYW1lICk7XG5cblx0XHRcdC8vIE5vbi1leGlzdGVudCBhdHRyaWJ1dGVzIHJldHVybiBudWxsLCB3ZSBub3JtYWxpemUgdG8gdW5kZWZpbmVkXG5cdFx0XHRyZXR1cm4gcmV0ID09IG51bGwgP1xuXHRcdFx0XHR1bmRlZmluZWQgOlxuXHRcdFx0XHRyZXQ7XG5cdFx0fVxuXHR9LFxuXG5cdHJlbW92ZUF0dHI6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHR2YXIgbmFtZSwgcHJvcE5hbWUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGF0dHJOYW1lcyA9IHZhbHVlICYmIHZhbHVlLm1hdGNoKCBybm90d2hpdGUgKTtcblxuXHRcdGlmICggYXR0ck5hbWVzICYmIGVsZW0ubm9kZVR5cGUgPT09IDEgKSB7XG5cdFx0XHR3aGlsZSAoIChuYW1lID0gYXR0ck5hbWVzW2krK10pICkge1xuXHRcdFx0XHRwcm9wTmFtZSA9IGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZTtcblxuXHRcdFx0XHQvLyBCb29sZWFuIGF0dHJpYnV0ZXMgZ2V0IHNwZWNpYWwgdHJlYXRtZW50ICgjMTA4NzApXG5cdFx0XHRcdGlmICggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC50ZXN0KCBuYW1lICkgKSB7XG5cdFx0XHRcdFx0Ly8gU2V0IGNvcnJlc3BvbmRpbmcgcHJvcGVydHkgdG8gZmFsc2Vcblx0XHRcdFx0XHRpZiAoIGdldFNldElucHV0ICYmIGdldFNldEF0dHJpYnV0ZSB8fCAhcnVzZURlZmF1bHQudGVzdCggbmFtZSApICkge1xuXHRcdFx0XHRcdFx0ZWxlbVsgcHJvcE5hbWUgXSA9IGZhbHNlO1xuXHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFPDlcblx0XHRcdFx0XHQvLyBBbHNvIGNsZWFyIGRlZmF1bHRDaGVja2VkL2RlZmF1bHRTZWxlY3RlZCAoaWYgYXBwcm9wcmlhdGUpXG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGVsZW1bIGpRdWVyeS5jYW1lbENhc2UoIFwiZGVmYXVsdC1cIiArIG5hbWUgKSBdID1cblx0XHRcdFx0XHRcdFx0ZWxlbVsgcHJvcE5hbWUgXSA9IGZhbHNlO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHQvLyBTZWUgIzk2OTkgZm9yIGV4cGxhbmF0aW9uIG9mIHRoaXMgYXBwcm9hY2ggKHNldHRpbmcgZmlyc3QsIHRoZW4gcmVtb3ZhbClcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRqUXVlcnkuYXR0ciggZWxlbSwgbmFtZSwgXCJcIiApO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0ZWxlbS5yZW1vdmVBdHRyaWJ1dGUoIGdldFNldEF0dHJpYnV0ZSA/IG5hbWUgOiBwcm9wTmFtZSApO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblxuXHRhdHRySG9va3M6IHtcblx0XHR0eXBlOiB7XG5cdFx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSApIHtcblx0XHRcdFx0aWYgKCAhc3VwcG9ydC5yYWRpb1ZhbHVlICYmIHZhbHVlID09PSBcInJhZGlvXCIgJiYgalF1ZXJ5Lm5vZGVOYW1lKGVsZW0sIFwiaW5wdXRcIikgKSB7XG5cdFx0XHRcdFx0Ly8gU2V0dGluZyB0aGUgdHlwZSBvbiBhIHJhZGlvIGJ1dHRvbiBhZnRlciB0aGUgdmFsdWUgcmVzZXRzIHRoZSB2YWx1ZSBpbiBJRTYtOVxuXHRcdFx0XHRcdC8vIFJlc2V0IHZhbHVlIHRvIGRlZmF1bHQgaW4gY2FzZSB0eXBlIGlzIHNldCBhZnRlciB2YWx1ZSBkdXJpbmcgY3JlYXRpb25cblx0XHRcdFx0XHR2YXIgdmFsID0gZWxlbS52YWx1ZTtcblx0XHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZSggXCJ0eXBlXCIsIHZhbHVlICk7XG5cdFx0XHRcdFx0aWYgKCB2YWwgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLnZhbHVlID0gdmFsO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cdH1cbn0pO1xuXG4vLyBIb29rIGZvciBib29sZWFuIGF0dHJpYnV0ZXNcbmJvb2xIb29rID0ge1xuXHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgbmFtZSApIHtcblx0XHRpZiAoIHZhbHVlID09PSBmYWxzZSApIHtcblx0XHRcdC8vIFJlbW92ZSBib29sZWFuIGF0dHJpYnV0ZXMgd2hlbiBzZXQgdG8gZmFsc2Vcblx0XHRcdGpRdWVyeS5yZW1vdmVBdHRyKCBlbGVtLCBuYW1lICk7XG5cdFx0fSBlbHNlIGlmICggZ2V0U2V0SW5wdXQgJiYgZ2V0U2V0QXR0cmlidXRlIHx8ICFydXNlRGVmYXVsdC50ZXN0KCBuYW1lICkgKSB7XG5cdFx0XHQvLyBJRTw4IG5lZWRzIHRoZSAqcHJvcGVydHkqIG5hbWVcblx0XHRcdGVsZW0uc2V0QXR0cmlidXRlKCAhZ2V0U2V0QXR0cmlidXRlICYmIGpRdWVyeS5wcm9wRml4WyBuYW1lIF0gfHwgbmFtZSwgbmFtZSApO1xuXG5cdFx0Ly8gVXNlIGRlZmF1bHRDaGVja2VkIGFuZCBkZWZhdWx0U2VsZWN0ZWQgZm9yIG9sZElFXG5cdFx0fSBlbHNlIHtcblx0XHRcdGVsZW1bIGpRdWVyeS5jYW1lbENhc2UoIFwiZGVmYXVsdC1cIiArIG5hbWUgKSBdID0gZWxlbVsgbmFtZSBdID0gdHJ1ZTtcblx0XHR9XG5cblx0XHRyZXR1cm4gbmFtZTtcblx0fVxufTtcblxuLy8gUmV0cmlldmUgYm9vbGVhbnMgc3BlY2lhbGx5XG5qUXVlcnkuZWFjaCggalF1ZXJ5LmV4cHIubWF0Y2guYm9vbC5zb3VyY2UubWF0Y2goIC9cXHcrL2cgKSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cblx0dmFyIGdldHRlciA9IGF0dHJIYW5kbGVbIG5hbWUgXSB8fCBqUXVlcnkuZmluZC5hdHRyO1xuXG5cdGF0dHJIYW5kbGVbIG5hbWUgXSA9IGdldFNldElucHV0ICYmIGdldFNldEF0dHJpYnV0ZSB8fCAhcnVzZURlZmF1bHQudGVzdCggbmFtZSApID9cblx0XHRmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0XHR2YXIgcmV0LCBoYW5kbGU7XG5cdFx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdFx0Ly8gQXZvaWQgYW4gaW5maW5pdGUgbG9vcCBieSB0ZW1wb3JhcmlseSByZW1vdmluZyB0aGlzIGZ1bmN0aW9uIGZyb20gdGhlIGdldHRlclxuXHRcdFx0XHRoYW5kbGUgPSBhdHRySGFuZGxlWyBuYW1lIF07XG5cdFx0XHRcdGF0dHJIYW5kbGVbIG5hbWUgXSA9IHJldDtcblx0XHRcdFx0cmV0ID0gZ2V0dGVyKCBlbGVtLCBuYW1lLCBpc1hNTCApICE9IG51bGwgP1xuXHRcdFx0XHRcdG5hbWUudG9Mb3dlckNhc2UoKSA6XG5cdFx0XHRcdFx0bnVsbDtcblx0XHRcdFx0YXR0ckhhbmRsZVsgbmFtZSBdID0gaGFuZGxlO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIHJldDtcblx0XHR9IDpcblx0XHRmdW5jdGlvbiggZWxlbSwgbmFtZSwgaXNYTUwgKSB7XG5cdFx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW1bIGpRdWVyeS5jYW1lbENhc2UoIFwiZGVmYXVsdC1cIiArIG5hbWUgKSBdID9cblx0XHRcdFx0XHRuYW1lLnRvTG93ZXJDYXNlKCkgOlxuXHRcdFx0XHRcdG51bGw7XG5cdFx0XHR9XG5cdFx0fTtcbn0pO1xuXG4vLyBmaXggb2xkSUUgYXR0cm9wZXJ0aWVzXG5pZiAoICFnZXRTZXRJbnB1dCB8fCAhZ2V0U2V0QXR0cmlidXRlICkge1xuXHRqUXVlcnkuYXR0ckhvb2tzLnZhbHVlID0ge1xuXHRcdHNldDogZnVuY3Rpb24oIGVsZW0sIHZhbHVlLCBuYW1lICkge1xuXHRcdFx0aWYgKCBqUXVlcnkubm9kZU5hbWUoIGVsZW0sIFwiaW5wdXRcIiApICkge1xuXHRcdFx0XHQvLyBEb2VzIG5vdCByZXR1cm4gc28gdGhhdCBzZXRBdHRyaWJ1dGUgaXMgYWxzbyB1c2VkXG5cdFx0XHRcdGVsZW0uZGVmYXVsdFZhbHVlID0gdmFsdWU7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBVc2Ugbm9kZUhvb2sgaWYgZGVmaW5lZCAoIzE5NTQpOyBvdGhlcndpc2Ugc2V0QXR0cmlidXRlIGlzIGZpbmVcblx0XHRcdFx0cmV0dXJuIG5vZGVIb29rICYmIG5vZGVIb29rLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG59XG5cbi8vIElFNi83IGRvIG5vdCBzdXBwb3J0IGdldHRpbmcvc2V0dGluZyBzb21lIGF0dHJpYnV0ZXMgd2l0aCBnZXQvc2V0QXR0cmlidXRlXG5pZiAoICFnZXRTZXRBdHRyaWJ1dGUgKSB7XG5cblx0Ly8gVXNlIHRoaXMgZm9yIGFueSBhdHRyaWJ1dGUgaW4gSUU2Lzdcblx0Ly8gVGhpcyBmaXhlcyBhbG1vc3QgZXZlcnkgSUU2LzcgaXNzdWVcblx0bm9kZUhvb2sgPSB7XG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUsIG5hbWUgKSB7XG5cdFx0XHQvLyBTZXQgdGhlIGV4aXN0aW5nIG9yIGNyZWF0ZSBhIG5ldyBhdHRyaWJ1dGUgbm9kZVxuXHRcdFx0dmFyIHJldCA9IGVsZW0uZ2V0QXR0cmlidXRlTm9kZSggbmFtZSApO1xuXHRcdFx0aWYgKCAhcmV0ICkge1xuXHRcdFx0XHRlbGVtLnNldEF0dHJpYnV0ZU5vZGUoXG5cdFx0XHRcdFx0KHJldCA9IGVsZW0ub3duZXJEb2N1bWVudC5jcmVhdGVBdHRyaWJ1dGUoIG5hbWUgKSlcblx0XHRcdFx0KTtcblx0XHRcdH1cblxuXHRcdFx0cmV0LnZhbHVlID0gdmFsdWUgKz0gXCJcIjtcblxuXHRcdFx0Ly8gQnJlYWsgYXNzb2NpYXRpb24gd2l0aCBjbG9uZWQgZWxlbWVudHMgYnkgYWxzbyB1c2luZyBzZXRBdHRyaWJ1dGUgKCM5NjQ2KVxuXHRcdFx0aWYgKCBuYW1lID09PSBcInZhbHVlXCIgfHwgdmFsdWUgPT09IGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lICkgKSB7XG5cdFx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHRcdH1cblx0XHR9XG5cdH07XG5cblx0Ly8gU29tZSBhdHRyaWJ1dGVzIGFyZSBjb25zdHJ1Y3RlZCB3aXRoIGVtcHR5LXN0cmluZyB2YWx1ZXMgd2hlbiBub3QgZGVmaW5lZFxuXHRhdHRySGFuZGxlLmlkID0gYXR0ckhhbmRsZS5uYW1lID0gYXR0ckhhbmRsZS5jb29yZHMgPVxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCBpc1hNTCApIHtcblx0XHRcdHZhciByZXQ7XG5cdFx0XHRpZiAoICFpc1hNTCApIHtcblx0XHRcdFx0cmV0dXJuIChyZXQgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIG5hbWUgKSkgJiYgcmV0LnZhbHVlICE9PSBcIlwiID9cblx0XHRcdFx0XHRyZXQudmFsdWUgOlxuXHRcdFx0XHRcdG51bGw7XG5cdFx0XHR9XG5cdFx0fTtcblxuXHQvLyBGaXhpbmcgdmFsdWUgcmV0cmlldmFsIG9uIGEgYnV0dG9uIHJlcXVpcmVzIHRoaXMgbW9kdWxlXG5cdGpRdWVyeS52YWxIb29rcy5idXR0b24gPSB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSwgbmFtZSApIHtcblx0XHRcdHZhciByZXQgPSBlbGVtLmdldEF0dHJpYnV0ZU5vZGUoIG5hbWUgKTtcblx0XHRcdGlmICggcmV0ICYmIHJldC5zcGVjaWZpZWQgKSB7XG5cdFx0XHRcdHJldHVybiByZXQudmFsdWU7XG5cdFx0XHR9XG5cdFx0fSxcblx0XHRzZXQ6IG5vZGVIb29rLnNldFxuXHR9O1xuXG5cdC8vIFNldCBjb250ZW50ZWRpdGFibGUgdG8gZmFsc2Ugb24gcmVtb3ZhbHMoIzEwNDI5KVxuXHQvLyBTZXR0aW5nIHRvIGVtcHR5IHN0cmluZyB0aHJvd3MgYW4gZXJyb3IgYXMgYW4gaW52YWxpZCB2YWx1ZVxuXHRqUXVlcnkuYXR0ckhvb2tzLmNvbnRlbnRlZGl0YWJsZSA9IHtcblx0XHRzZXQ6IGZ1bmN0aW9uKCBlbGVtLCB2YWx1ZSwgbmFtZSApIHtcblx0XHRcdG5vZGVIb29rLnNldCggZWxlbSwgdmFsdWUgPT09IFwiXCIgPyBmYWxzZSA6IHZhbHVlLCBuYW1lICk7XG5cdFx0fVxuXHR9O1xuXG5cdC8vIFNldCB3aWR0aCBhbmQgaGVpZ2h0IHRvIGF1dG8gaW5zdGVhZCBvZiAwIG9uIGVtcHR5IHN0cmluZyggQnVnICM4MTUwIClcblx0Ly8gVGhpcyBpcyBmb3IgcmVtb3ZhbHNcblx0alF1ZXJ5LmVhY2goWyBcIndpZHRoXCIsIFwiaGVpZ2h0XCIgXSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cdFx0alF1ZXJ5LmF0dHJIb29rc1sgbmFtZSBdID0ge1xuXHRcdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XG5cdFx0XHRcdGlmICggdmFsdWUgPT09IFwiXCIgKSB7XG5cdFx0XHRcdFx0ZWxlbS5zZXRBdHRyaWJ1dGUoIG5hbWUsIFwiYXV0b1wiICk7XG5cdFx0XHRcdFx0cmV0dXJuIHZhbHVlO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fSk7XG59XG5cbmlmICggIXN1cHBvcnQuc3R5bGUgKSB7XG5cdGpRdWVyeS5hdHRySG9va3Muc3R5bGUgPSB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdC8vIFJldHVybiB1bmRlZmluZWQgaW4gdGhlIGNhc2Ugb2YgZW1wdHkgc3RyaW5nXG5cdFx0XHQvLyBOb3RlOiBJRSB1cHBlcmNhc2VzIGNzcyBwcm9wZXJ0eSBuYW1lcywgYnV0IGlmIHdlIHdlcmUgdG8gLnRvTG93ZXJDYXNlKClcblx0XHRcdC8vIC5jc3NUZXh0LCB0aGF0IHdvdWxkIGRlc3Ryb3kgY2FzZSBzZW5zdGl0aXZpdHkgaW4gVVJMJ3MsIGxpa2UgaW4gXCJiYWNrZ3JvdW5kXCJcblx0XHRcdHJldHVybiBlbGVtLnN0eWxlLmNzc1RleHQgfHwgdW5kZWZpbmVkO1xuXHRcdH0sXG5cdFx0c2V0OiBmdW5jdGlvbiggZWxlbSwgdmFsdWUgKSB7XG5cdFx0XHRyZXR1cm4gKCBlbGVtLnN0eWxlLmNzc1RleHQgPSB2YWx1ZSArIFwiXCIgKTtcblx0XHR9XG5cdH07XG59XG5cblxuXG5cbnZhciByZm9jdXNhYmxlID0gL14oPzppbnB1dHxzZWxlY3R8dGV4dGFyZWF8YnV0dG9ufG9iamVjdCkkL2ksXG5cdHJjbGlja2FibGUgPSAvXig/OmF8YXJlYSkkL2k7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRwcm9wOiBmdW5jdGlvbiggbmFtZSwgdmFsdWUgKSB7XG5cdFx0cmV0dXJuIGFjY2VzcyggdGhpcywgalF1ZXJ5LnByb3AsIG5hbWUsIHZhbHVlLCBhcmd1bWVudHMubGVuZ3RoID4gMSApO1xuXHR9LFxuXG5cdHJlbW92ZVByb3A6IGZ1bmN0aW9uKCBuYW1lICkge1xuXHRcdG5hbWUgPSBqUXVlcnkucHJvcEZpeFsgbmFtZSBdIHx8IG5hbWU7XG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdC8vIHRyeS9jYXRjaCBoYW5kbGVzIGNhc2VzIHdoZXJlIElFIGJhbGtzIChzdWNoIGFzIHJlbW92aW5nIGEgcHJvcGVydHkgb24gd2luZG93KVxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0dGhpc1sgbmFtZSBdID0gdW5kZWZpbmVkO1xuXHRcdFx0XHRkZWxldGUgdGhpc1sgbmFtZSBdO1xuXHRcdFx0fSBjYXRjaCggZSApIHt9XG5cdFx0fSk7XG5cdH1cbn0pO1xuXG5qUXVlcnkuZXh0ZW5kKHtcblx0cHJvcEZpeDoge1xuXHRcdFwiZm9yXCI6IFwiaHRtbEZvclwiLFxuXHRcdFwiY2xhc3NcIjogXCJjbGFzc05hbWVcIlxuXHR9LFxuXG5cdHByb3A6IGZ1bmN0aW9uKCBlbGVtLCBuYW1lLCB2YWx1ZSApIHtcblx0XHR2YXIgcmV0LCBob29rcywgbm90eG1sLFxuXHRcdFx0blR5cGUgPSBlbGVtLm5vZGVUeXBlO1xuXG5cdFx0Ly8gZG9uJ3QgZ2V0L3NldCBwcm9wZXJ0aWVzIG9uIHRleHQsIGNvbW1lbnQgYW5kIGF0dHJpYnV0ZSBub2Rlc1xuXHRcdGlmICggIWVsZW0gfHwgblR5cGUgPT09IDMgfHwgblR5cGUgPT09IDggfHwgblR5cGUgPT09IDIgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0bm90eG1sID0gblR5cGUgIT09IDEgfHwgIWpRdWVyeS5pc1hNTERvYyggZWxlbSApO1xuXG5cdFx0aWYgKCBub3R4bWwgKSB7XG5cdFx0XHQvLyBGaXggbmFtZSBhbmQgYXR0YWNoIGhvb2tzXG5cdFx0XHRuYW1lID0galF1ZXJ5LnByb3BGaXhbIG5hbWUgXSB8fCBuYW1lO1xuXHRcdFx0aG9va3MgPSBqUXVlcnkucHJvcEhvb2tzWyBuYW1lIF07XG5cdFx0fVxuXG5cdFx0aWYgKCB2YWx1ZSAhPT0gdW5kZWZpbmVkICkge1xuXHRcdFx0cmV0dXJuIGhvb2tzICYmIFwic2V0XCIgaW4gaG9va3MgJiYgKHJldCA9IGhvb2tzLnNldCggZWxlbSwgdmFsdWUsIG5hbWUgKSkgIT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdHJldCA6XG5cdFx0XHRcdCggZWxlbVsgbmFtZSBdID0gdmFsdWUgKTtcblxuXHRcdH0gZWxzZSB7XG5cdFx0XHRyZXR1cm4gaG9va3MgJiYgXCJnZXRcIiBpbiBob29rcyAmJiAocmV0ID0gaG9va3MuZ2V0KCBlbGVtLCBuYW1lICkpICE9PSBudWxsID9cblx0XHRcdFx0cmV0IDpcblx0XHRcdFx0ZWxlbVsgbmFtZSBdO1xuXHRcdH1cblx0fSxcblxuXHRwcm9wSG9va3M6IHtcblx0XHR0YWJJbmRleDoge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0Ly8gZWxlbS50YWJJbmRleCBkb2Vzbid0IGFsd2F5cyByZXR1cm4gdGhlIGNvcnJlY3QgdmFsdWUgd2hlbiBpdCBoYXNuJ3QgYmVlbiBleHBsaWNpdGx5IHNldFxuXHRcdFx0XHQvLyBodHRwOi8vZmx1aWRwcm9qZWN0Lm9yZy9ibG9nLzIwMDgvMDEvMDkvZ2V0dGluZy1zZXR0aW5nLWFuZC1yZW1vdmluZy10YWJpbmRleC12YWx1ZXMtd2l0aC1qYXZhc2NyaXB0L1xuXHRcdFx0XHQvLyBVc2UgcHJvcGVyIGF0dHJpYnV0ZSByZXRyaWV2YWwoIzEyMDcyKVxuXHRcdFx0XHR2YXIgdGFiaW5kZXggPSBqUXVlcnkuZmluZC5hdHRyKCBlbGVtLCBcInRhYmluZGV4XCIgKTtcblxuXHRcdFx0XHRyZXR1cm4gdGFiaW5kZXggP1xuXHRcdFx0XHRcdHBhcnNlSW50KCB0YWJpbmRleCwgMTAgKSA6XG5cdFx0XHRcdFx0cmZvY3VzYWJsZS50ZXN0KCBlbGVtLm5vZGVOYW1lICkgfHwgcmNsaWNrYWJsZS50ZXN0KCBlbGVtLm5vZGVOYW1lICkgJiYgZWxlbS5ocmVmID9cblx0XHRcdFx0XHRcdDAgOlxuXHRcdFx0XHRcdFx0LTE7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59KTtcblxuLy8gU29tZSBhdHRyaWJ1dGVzIHJlcXVpcmUgYSBzcGVjaWFsIGNhbGwgb24gSUVcbi8vIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzNjQyOSUyOFZTLjg1JTI5LmFzcHhcbmlmICggIXN1cHBvcnQuaHJlZk5vcm1hbGl6ZWQgKSB7XG5cdC8vIGhyZWYvc3JjIHByb3BlcnR5IHNob3VsZCBnZXQgdGhlIGZ1bGwgbm9ybWFsaXplZCBVUkwgKCMxMDI5OS8jMTI5MTUpXG5cdGpRdWVyeS5lYWNoKFsgXCJocmVmXCIsIFwic3JjXCIgXSwgZnVuY3Rpb24oIGksIG5hbWUgKSB7XG5cdFx0alF1ZXJ5LnByb3BIb29rc1sgbmFtZSBdID0ge1xuXHRcdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdFx0cmV0dXJuIGVsZW0uZ2V0QXR0cmlidXRlKCBuYW1lLCA0ICk7XG5cdFx0XHR9XG5cdFx0fTtcblx0fSk7XG59XG5cbi8vIFN1cHBvcnQ6IFNhZmFyaSwgSUU5K1xuLy8gbWlzLXJlcG9ydHMgdGhlIGRlZmF1bHQgc2VsZWN0ZWQgcHJvcGVydHkgb2YgYW4gb3B0aW9uXG4vLyBBY2Nlc3NpbmcgdGhlIHBhcmVudCdzIHNlbGVjdGVkSW5kZXggcHJvcGVydHkgZml4ZXMgaXRcbmlmICggIXN1cHBvcnQub3B0U2VsZWN0ZWQgKSB7XG5cdGpRdWVyeS5wcm9wSG9va3Muc2VsZWN0ZWQgPSB7XG5cdFx0Z2V0OiBmdW5jdGlvbiggZWxlbSApIHtcblx0XHRcdHZhciBwYXJlbnQgPSBlbGVtLnBhcmVudE5vZGU7XG5cblx0XHRcdGlmICggcGFyZW50ICkge1xuXHRcdFx0XHRwYXJlbnQuc2VsZWN0ZWRJbmRleDtcblxuXHRcdFx0XHQvLyBNYWtlIHN1cmUgdGhhdCBpdCBhbHNvIHdvcmtzIHdpdGggb3B0Z3JvdXBzLCBzZWUgIzU3MDFcblx0XHRcdFx0aWYgKCBwYXJlbnQucGFyZW50Tm9kZSApIHtcblx0XHRcdFx0XHRwYXJlbnQucGFyZW50Tm9kZS5zZWxlY3RlZEluZGV4O1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gbnVsbDtcblx0XHR9XG5cdH07XG59XG5cbmpRdWVyeS5lYWNoKFtcblx0XCJ0YWJJbmRleFwiLFxuXHRcInJlYWRPbmx5XCIsXG5cdFwibWF4TGVuZ3RoXCIsXG5cdFwiY2VsbFNwYWNpbmdcIixcblx0XCJjZWxsUGFkZGluZ1wiLFxuXHRcInJvd1NwYW5cIixcblx0XCJjb2xTcGFuXCIsXG5cdFwidXNlTWFwXCIsXG5cdFwiZnJhbWVCb3JkZXJcIixcblx0XCJjb250ZW50RWRpdGFibGVcIlxuXSwgZnVuY3Rpb24oKSB7XG5cdGpRdWVyeS5wcm9wRml4WyB0aGlzLnRvTG93ZXJDYXNlKCkgXSA9IHRoaXM7XG59KTtcblxuLy8gSUU2LzcgY2FsbCBlbmN0eXBlIGVuY29kaW5nXG5pZiAoICFzdXBwb3J0LmVuY3R5cGUgKSB7XG5cdGpRdWVyeS5wcm9wRml4LmVuY3R5cGUgPSBcImVuY29kaW5nXCI7XG59XG5cblxuXG5cbnZhciByY2xhc3MgPSAvW1xcdFxcclxcblxcZl0vZztcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdGFkZENsYXNzOiBmdW5jdGlvbiggdmFsdWUgKSB7XG5cdFx0dmFyIGNsYXNzZXMsIGVsZW0sIGN1ciwgY2xhenosIGosIGZpbmFsVmFsdWUsXG5cdFx0XHRpID0gMCxcblx0XHRcdGxlbiA9IHRoaXMubGVuZ3RoLFxuXHRcdFx0cHJvY2VlZCA9IHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZTtcblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBqICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS5hZGRDbGFzcyggdmFsdWUuY2FsbCggdGhpcywgaiwgdGhpcy5jbGFzc05hbWUgKSApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKCBwcm9jZWVkICkge1xuXHRcdFx0Ly8gVGhlIGRpc2p1bmN0aW9uIGhlcmUgaXMgZm9yIGJldHRlciBjb21wcmVzc2liaWxpdHkgKHNlZSByZW1vdmVDbGFzcylcblx0XHRcdGNsYXNzZXMgPSAoIHZhbHVlIHx8IFwiXCIgKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgW107XG5cblx0XHRcdGZvciAoIDsgaSA8IGxlbjsgaSsrICkge1xuXHRcdFx0XHRlbGVtID0gdGhpc1sgaSBdO1xuXHRcdFx0XHRjdXIgPSBlbGVtLm5vZGVUeXBlID09PSAxICYmICggZWxlbS5jbGFzc05hbWUgP1xuXHRcdFx0XHRcdCggXCIgXCIgKyBlbGVtLmNsYXNzTmFtZSArIFwiIFwiICkucmVwbGFjZSggcmNsYXNzLCBcIiBcIiApIDpcblx0XHRcdFx0XHRcIiBcIlxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdGlmICggY3VyICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKGNsYXp6ID0gY2xhc3Nlc1tqKytdKSApIHtcblx0XHRcdFx0XHRcdGlmICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhenogKyBcIiBcIiApIDwgMCApIHtcblx0XHRcdFx0XHRcdFx0Y3VyICs9IGNsYXp6ICsgXCIgXCI7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gb25seSBhc3NpZ24gaWYgZGlmZmVyZW50IHRvIGF2b2lkIHVubmVlZGVkIHJlbmRlcmluZy5cblx0XHRcdFx0XHRmaW5hbFZhbHVlID0galF1ZXJ5LnRyaW0oIGN1ciApO1xuXHRcdFx0XHRcdGlmICggZWxlbS5jbGFzc05hbWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmNsYXNzTmFtZSA9IGZpbmFsVmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0cmVtb3ZlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSApIHtcblx0XHR2YXIgY2xhc3NlcywgZWxlbSwgY3VyLCBjbGF6eiwgaiwgZmluYWxWYWx1ZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0bGVuID0gdGhpcy5sZW5ndGgsXG5cdFx0XHRwcm9jZWVkID0gYXJndW1lbnRzLmxlbmd0aCA9PT0gMCB8fCB0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgdmFsdWU7XG5cblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbiggaiApIHtcblx0XHRcdFx0alF1ZXJ5KCB0aGlzICkucmVtb3ZlQ2xhc3MoIHZhbHVlLmNhbGwoIHRoaXMsIGosIHRoaXMuY2xhc3NOYW1lICkgKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0XHRpZiAoIHByb2NlZWQgKSB7XG5cdFx0XHRjbGFzc2VzID0gKCB2YWx1ZSB8fCBcIlwiICkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xuXG5cdFx0XHRmb3IgKCA7IGkgPCBsZW47IGkrKyApIHtcblx0XHRcdFx0ZWxlbSA9IHRoaXNbIGkgXTtcblx0XHRcdFx0Ly8gVGhpcyBleHByZXNzaW9uIGlzIGhlcmUgZm9yIGJldHRlciBjb21wcmVzc2liaWxpdHkgKHNlZSBhZGRDbGFzcylcblx0XHRcdFx0Y3VyID0gZWxlbS5ub2RlVHlwZSA9PT0gMSAmJiAoIGVsZW0uY2xhc3NOYW1lID9cblx0XHRcdFx0XHQoIFwiIFwiICsgZWxlbS5jbGFzc05hbWUgKyBcIiBcIiApLnJlcGxhY2UoIHJjbGFzcywgXCIgXCIgKSA6XG5cdFx0XHRcdFx0XCJcIlxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdGlmICggY3VyICkge1xuXHRcdFx0XHRcdGogPSAwO1xuXHRcdFx0XHRcdHdoaWxlICggKGNsYXp6ID0gY2xhc3Nlc1tqKytdKSApIHtcblx0XHRcdFx0XHRcdC8vIFJlbW92ZSAqYWxsKiBpbnN0YW5jZXNcblx0XHRcdFx0XHRcdHdoaWxlICggY3VyLmluZGV4T2YoIFwiIFwiICsgY2xhenogKyBcIiBcIiApID49IDAgKSB7XG5cdFx0XHRcdFx0XHRcdGN1ciA9IGN1ci5yZXBsYWNlKCBcIiBcIiArIGNsYXp6ICsgXCIgXCIsIFwiIFwiICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gb25seSBhc3NpZ24gaWYgZGlmZmVyZW50IHRvIGF2b2lkIHVubmVlZGVkIHJlbmRlcmluZy5cblx0XHRcdFx0XHRmaW5hbFZhbHVlID0gdmFsdWUgPyBqUXVlcnkudHJpbSggY3VyICkgOiBcIlwiO1xuXHRcdFx0XHRcdGlmICggZWxlbS5jbGFzc05hbWUgIT09IGZpbmFsVmFsdWUgKSB7XG5cdFx0XHRcdFx0XHRlbGVtLmNsYXNzTmFtZSA9IGZpbmFsVmFsdWU7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXM7XG5cdH0sXG5cblx0dG9nZ2xlQ2xhc3M6IGZ1bmN0aW9uKCB2YWx1ZSwgc3RhdGVWYWwgKSB7XG5cdFx0dmFyIHR5cGUgPSB0eXBlb2YgdmFsdWU7XG5cblx0XHRpZiAoIHR5cGVvZiBzdGF0ZVZhbCA9PT0gXCJib29sZWFuXCIgJiYgdHlwZSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHJldHVybiBzdGF0ZVZhbCA/IHRoaXMuYWRkQ2xhc3MoIHZhbHVlICkgOiB0aGlzLnJlbW92ZUNsYXNzKCB2YWx1ZSApO1xuXHRcdH1cblxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHZhbHVlICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKCBpICkge1xuXHRcdFx0XHRqUXVlcnkoIHRoaXMgKS50b2dnbGVDbGFzcyggdmFsdWUuY2FsbCh0aGlzLCBpLCB0aGlzLmNsYXNzTmFtZSwgc3RhdGVWYWwpLCBzdGF0ZVZhbCApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdGlmICggdHlwZSA9PT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdFx0Ly8gdG9nZ2xlIGluZGl2aWR1YWwgY2xhc3MgbmFtZXNcblx0XHRcdFx0dmFyIGNsYXNzTmFtZSxcblx0XHRcdFx0XHRpID0gMCxcblx0XHRcdFx0XHRzZWxmID0galF1ZXJ5KCB0aGlzICksXG5cdFx0XHRcdFx0Y2xhc3NOYW1lcyA9IHZhbHVlLm1hdGNoKCBybm90d2hpdGUgKSB8fCBbXTtcblxuXHRcdFx0XHR3aGlsZSAoIChjbGFzc05hbWUgPSBjbGFzc05hbWVzWyBpKysgXSkgKSB7XG5cdFx0XHRcdFx0Ly8gY2hlY2sgZWFjaCBjbGFzc05hbWUgZ2l2ZW4sIHNwYWNlIHNlcGFyYXRlZCBsaXN0XG5cdFx0XHRcdFx0aWYgKCBzZWxmLmhhc0NsYXNzKCBjbGFzc05hbWUgKSApIHtcblx0XHRcdFx0XHRcdHNlbGYucmVtb3ZlQ2xhc3MoIGNsYXNzTmFtZSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRzZWxmLmFkZENsYXNzKCBjbGFzc05hbWUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblxuXHRcdFx0Ly8gVG9nZ2xlIHdob2xlIGNsYXNzIG5hbWVcblx0XHRcdH0gZWxzZSBpZiAoIHR5cGUgPT09IHN0cnVuZGVmaW5lZCB8fCB0eXBlID09PSBcImJvb2xlYW5cIiApIHtcblx0XHRcdFx0aWYgKCB0aGlzLmNsYXNzTmFtZSApIHtcblx0XHRcdFx0XHQvLyBzdG9yZSBjbGFzc05hbWUgaWYgc2V0XG5cdFx0XHRcdFx0alF1ZXJ5Ll9kYXRhKCB0aGlzLCBcIl9fY2xhc3NOYW1lX19cIiwgdGhpcy5jbGFzc05hbWUgKTtcblx0XHRcdFx0fVxuXG5cdFx0XHRcdC8vIElmIHRoZSBlbGVtZW50IGhhcyBhIGNsYXNzIG5hbWUgb3IgaWYgd2UncmUgcGFzc2VkIFwiZmFsc2VcIixcblx0XHRcdFx0Ly8gdGhlbiByZW1vdmUgdGhlIHdob2xlIGNsYXNzbmFtZSAoaWYgdGhlcmUgd2FzIG9uZSwgdGhlIGFib3ZlIHNhdmVkIGl0KS5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIGJyaW5nIGJhY2sgd2hhdGV2ZXIgd2FzIHByZXZpb3VzbHkgc2F2ZWQgKGlmIGFueXRoaW5nKSxcblx0XHRcdFx0Ly8gZmFsbGluZyBiYWNrIHRvIHRoZSBlbXB0eSBzdHJpbmcgaWYgbm90aGluZyB3YXMgc3RvcmVkLlxuXHRcdFx0XHR0aGlzLmNsYXNzTmFtZSA9IHRoaXMuY2xhc3NOYW1lIHx8IHZhbHVlID09PSBmYWxzZSA/IFwiXCIgOiBqUXVlcnkuX2RhdGEoIHRoaXMsIFwiX19jbGFzc05hbWVfX1wiICkgfHwgXCJcIjtcblx0XHRcdH1cblx0XHR9KTtcblx0fSxcblxuXHRoYXNDbGFzczogZnVuY3Rpb24oIHNlbGVjdG9yICkge1xuXHRcdHZhciBjbGFzc05hbWUgPSBcIiBcIiArIHNlbGVjdG9yICsgXCIgXCIsXG5cdFx0XHRpID0gMCxcblx0XHRcdGwgPSB0aGlzLmxlbmd0aDtcblx0XHRmb3IgKCA7IGkgPCBsOyBpKysgKSB7XG5cdFx0XHRpZiAoIHRoaXNbaV0ubm9kZVR5cGUgPT09IDEgJiYgKFwiIFwiICsgdGhpc1tpXS5jbGFzc05hbWUgKyBcIiBcIikucmVwbGFjZShyY2xhc3MsIFwiIFwiKS5pbmRleE9mKCBjbGFzc05hbWUgKSA+PSAwICkge1xuXHRcdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn0pO1xuXG5cblxuXG4vLyBSZXR1cm4galF1ZXJ5IGZvciBhdHRyaWJ1dGVzLW9ubHkgaW5jbHVzaW9uXG5cblxualF1ZXJ5LmVhY2goIChcImJsdXIgZm9jdXMgZm9jdXNpbiBmb2N1c291dCBsb2FkIHJlc2l6ZSBzY3JvbGwgdW5sb2FkIGNsaWNrIGRibGNsaWNrIFwiICtcblx0XCJtb3VzZWRvd24gbW91c2V1cCBtb3VzZW1vdmUgbW91c2VvdmVyIG1vdXNlb3V0IG1vdXNlZW50ZXIgbW91c2VsZWF2ZSBcIiArXG5cdFwiY2hhbmdlIHNlbGVjdCBzdWJtaXQga2V5ZG93biBrZXlwcmVzcyBrZXl1cCBlcnJvciBjb250ZXh0bWVudVwiKS5zcGxpdChcIiBcIiksIGZ1bmN0aW9uKCBpLCBuYW1lICkge1xuXG5cdC8vIEhhbmRsZSBldmVudCBiaW5kaW5nXG5cdGpRdWVyeS5mblsgbmFtZSBdID0gZnVuY3Rpb24oIGRhdGEsIGZuICkge1xuXHRcdHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMCA/XG5cdFx0XHR0aGlzLm9uKCBuYW1lLCBudWxsLCBkYXRhLCBmbiApIDpcblx0XHRcdHRoaXMudHJpZ2dlciggbmFtZSApO1xuXHR9O1xufSk7XG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHRob3ZlcjogZnVuY3Rpb24oIGZuT3ZlciwgZm5PdXQgKSB7XG5cdFx0cmV0dXJuIHRoaXMubW91c2VlbnRlciggZm5PdmVyICkubW91c2VsZWF2ZSggZm5PdXQgfHwgZm5PdmVyICk7XG5cdH0sXG5cblx0YmluZDogZnVuY3Rpb24oIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIG51bGwsIGRhdGEsIGZuICk7XG5cdH0sXG5cdHVuYmluZDogZnVuY3Rpb24oIHR5cGVzLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vZmYoIHR5cGVzLCBudWxsLCBmbiApO1xuXHR9LFxuXG5cdGRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBkYXRhLCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZXMsIHNlbGVjdG9yLCBkYXRhLCBmbiApO1xuXHR9LFxuXHR1bmRlbGVnYXRlOiBmdW5jdGlvbiggc2VsZWN0b3IsIHR5cGVzLCBmbiApIHtcblx0XHQvLyAoIG5hbWVzcGFjZSApIG9yICggc2VsZWN0b3IsIHR5cGVzIFssIGZuXSApXG5cdFx0cmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyB0aGlzLm9mZiggc2VsZWN0b3IsIFwiKipcIiApIDogdGhpcy5vZmYoIHR5cGVzLCBzZWxlY3RvciB8fCBcIioqXCIsIGZuICk7XG5cdH1cbn0pO1xuXG5cbnZhciBub25jZSA9IGpRdWVyeS5ub3coKTtcblxudmFyIHJxdWVyeSA9ICgvXFw/Lyk7XG5cblxuXG52YXIgcnZhbGlkdG9rZW5zID0gLygsKXwoXFxbfHspfCh9fF0pfFwiKD86W15cIlxcXFxcXHJcXG5dfFxcXFxbXCJcXFxcXFwvYmZucnRdfFxcXFx1W1xcZGEtZkEtRl17NH0pKlwiXFxzKjo/fHRydWV8ZmFsc2V8bnVsbHwtPyg/ITBcXGQpXFxkKyg/OlxcLlxcZCt8KSg/OltlRV1bKy1dP1xcZCt8KS9nO1xuXG5qUXVlcnkucGFyc2VKU09OID0gZnVuY3Rpb24oIGRhdGEgKSB7XG5cdC8vIEF0dGVtcHQgdG8gcGFyc2UgdXNpbmcgdGhlIG5hdGl2ZSBKU09OIHBhcnNlciBmaXJzdFxuXHRpZiAoIHdpbmRvdy5KU09OICYmIHdpbmRvdy5KU09OLnBhcnNlICkge1xuXHRcdC8vIFN1cHBvcnQ6IEFuZHJvaWQgMi4zXG5cdFx0Ly8gV29ya2Fyb3VuZCBmYWlsdXJlIHRvIHN0cmluZy1jYXN0IG51bGwgaW5wdXRcblx0XHRyZXR1cm4gd2luZG93LkpTT04ucGFyc2UoIGRhdGEgKyBcIlwiICk7XG5cdH1cblxuXHR2YXIgcmVxdWlyZU5vbkNvbW1hLFxuXHRcdGRlcHRoID0gbnVsbCxcblx0XHRzdHIgPSBqUXVlcnkudHJpbSggZGF0YSArIFwiXCIgKTtcblxuXHQvLyBHdWFyZCBhZ2FpbnN0IGludmFsaWQgKGFuZCBwb3NzaWJseSBkYW5nZXJvdXMpIGlucHV0IGJ5IGVuc3VyaW5nIHRoYXQgbm90aGluZyByZW1haW5zXG5cdC8vIGFmdGVyIHJlbW92aW5nIHZhbGlkIHRva2Vuc1xuXHRyZXR1cm4gc3RyICYmICFqUXVlcnkudHJpbSggc3RyLnJlcGxhY2UoIHJ2YWxpZHRva2VucywgZnVuY3Rpb24oIHRva2VuLCBjb21tYSwgb3BlbiwgY2xvc2UgKSB7XG5cblx0XHQvLyBGb3JjZSB0ZXJtaW5hdGlvbiBpZiB3ZSBzZWUgYSBtaXNwbGFjZWQgY29tbWFcblx0XHRpZiAoIHJlcXVpcmVOb25Db21tYSAmJiBjb21tYSApIHtcblx0XHRcdGRlcHRoID0gMDtcblx0XHR9XG5cblx0XHQvLyBQZXJmb3JtIG5vIG1vcmUgcmVwbGFjZW1lbnRzIGFmdGVyIHJldHVybmluZyB0byBvdXRlcm1vc3QgZGVwdGhcblx0XHRpZiAoIGRlcHRoID09PSAwICkge1xuXHRcdFx0cmV0dXJuIHRva2VuO1xuXHRcdH1cblxuXHRcdC8vIENvbW1hcyBtdXN0IG5vdCBmb2xsb3cgXCJbXCIsIFwie1wiLCBvciBcIixcIlxuXHRcdHJlcXVpcmVOb25Db21tYSA9IG9wZW4gfHwgY29tbWE7XG5cblx0XHQvLyBEZXRlcm1pbmUgbmV3IGRlcHRoXG5cdFx0Ly8gYXJyYXkvb2JqZWN0IG9wZW4gKFwiW1wiIG9yIFwie1wiKTogZGVwdGggKz0gdHJ1ZSAtIGZhbHNlIChpbmNyZW1lbnQpXG5cdFx0Ly8gYXJyYXkvb2JqZWN0IGNsb3NlIChcIl1cIiBvciBcIn1cIik6IGRlcHRoICs9IGZhbHNlIC0gdHJ1ZSAoZGVjcmVtZW50KVxuXHRcdC8vIG90aGVyIGNhc2VzIChcIixcIiBvciBwcmltaXRpdmUpOiBkZXB0aCArPSB0cnVlIC0gdHJ1ZSAobnVtZXJpYyBjYXN0KVxuXHRcdGRlcHRoICs9ICFjbG9zZSAtICFvcGVuO1xuXG5cdFx0Ly8gUmVtb3ZlIHRoaXMgdG9rZW5cblx0XHRyZXR1cm4gXCJcIjtcblx0fSkgKSA/XG5cdFx0KCBGdW5jdGlvbiggXCJyZXR1cm4gXCIgKyBzdHIgKSApKCkgOlxuXHRcdGpRdWVyeS5lcnJvciggXCJJbnZhbGlkIEpTT046IFwiICsgZGF0YSApO1xufTtcblxuXG4vLyBDcm9zcy1icm93c2VyIHhtbCBwYXJzaW5nXG5qUXVlcnkucGFyc2VYTUwgPSBmdW5jdGlvbiggZGF0YSApIHtcblx0dmFyIHhtbCwgdG1wO1xuXHRpZiAoICFkYXRhIHx8IHR5cGVvZiBkYXRhICE9PSBcInN0cmluZ1wiICkge1xuXHRcdHJldHVybiBudWxsO1xuXHR9XG5cdHRyeSB7XG5cdFx0aWYgKCB3aW5kb3cuRE9NUGFyc2VyICkgeyAvLyBTdGFuZGFyZFxuXHRcdFx0dG1wID0gbmV3IERPTVBhcnNlcigpO1xuXHRcdFx0eG1sID0gdG1wLnBhcnNlRnJvbVN0cmluZyggZGF0YSwgXCJ0ZXh0L3htbFwiICk7XG5cdFx0fSBlbHNlIHsgLy8gSUVcblx0XHRcdHhtbCA9IG5ldyBBY3RpdmVYT2JqZWN0KCBcIk1pY3Jvc29mdC5YTUxET01cIiApO1xuXHRcdFx0eG1sLmFzeW5jID0gXCJmYWxzZVwiO1xuXHRcdFx0eG1sLmxvYWRYTUwoIGRhdGEgKTtcblx0XHR9XG5cdH0gY2F0Y2goIGUgKSB7XG5cdFx0eG1sID0gdW5kZWZpbmVkO1xuXHR9XG5cdGlmICggIXhtbCB8fCAheG1sLmRvY3VtZW50RWxlbWVudCB8fCB4bWwuZ2V0RWxlbWVudHNCeVRhZ05hbWUoIFwicGFyc2VyZXJyb3JcIiApLmxlbmd0aCApIHtcblx0XHRqUXVlcnkuZXJyb3IoIFwiSW52YWxpZCBYTUw6IFwiICsgZGF0YSApO1xuXHR9XG5cdHJldHVybiB4bWw7XG59O1xuXG5cbnZhclxuXHQvLyBEb2N1bWVudCBsb2NhdGlvblxuXHRhamF4TG9jUGFydHMsXG5cdGFqYXhMb2NhdGlvbixcblxuXHRyaGFzaCA9IC8jLiokLyxcblx0cnRzID0gLyhbPyZdKV89W14mXSovLFxuXHRyaGVhZGVycyA9IC9eKC4qPyk6WyBcXHRdKihbXlxcclxcbl0qKVxccj8kL21nLCAvLyBJRSBsZWF2ZXMgYW4gXFxyIGNoYXJhY3RlciBhdCBFT0xcblx0Ly8gIzc2NTMsICM4MTI1LCAjODE1MjogbG9jYWwgcHJvdG9jb2wgZGV0ZWN0aW9uXG5cdHJsb2NhbFByb3RvY29sID0gL14oPzphYm91dHxhcHB8YXBwLXN0b3JhZ2V8ListZXh0ZW5zaW9ufGZpbGV8cmVzfHdpZGdldCk6JC8sXG5cdHJub0NvbnRlbnQgPSAvXig/OkdFVHxIRUFEKSQvLFxuXHRycHJvdG9jb2wgPSAvXlxcL1xcLy8sXG5cdHJ1cmwgPSAvXihbXFx3ListXSs6KSg/OlxcL1xcLyg/OlteXFwvPyNdKkB8KShbXlxcLz8jOl0qKSg/OjooXFxkKyl8KXwpLyxcblxuXHQvKiBQcmVmaWx0ZXJzXG5cdCAqIDEpIFRoZXkgYXJlIHVzZWZ1bCB0byBpbnRyb2R1Y2UgY3VzdG9tIGRhdGFUeXBlcyAoc2VlIGFqYXgvanNvbnAuanMgZm9yIGFuIGV4YW1wbGUpXG5cdCAqIDIpIFRoZXNlIGFyZSBjYWxsZWQ6XG5cdCAqICAgIC0gQkVGT1JFIGFza2luZyBmb3IgYSB0cmFuc3BvcnRcblx0ICogICAgLSBBRlRFUiBwYXJhbSBzZXJpYWxpemF0aW9uIChzLmRhdGEgaXMgYSBzdHJpbmcgaWYgcy5wcm9jZXNzRGF0YSBpcyB0cnVlKVxuXHQgKiAzKSBrZXkgaXMgdGhlIGRhdGFUeXBlXG5cdCAqIDQpIHRoZSBjYXRjaGFsbCBzeW1ib2wgXCIqXCIgY2FuIGJlIHVzZWRcblx0ICogNSkgZXhlY3V0aW9uIHdpbGwgc3RhcnQgd2l0aCB0cmFuc3BvcnQgZGF0YVR5cGUgYW5kIFRIRU4gY29udGludWUgZG93biB0byBcIipcIiBpZiBuZWVkZWRcblx0ICovXG5cdHByZWZpbHRlcnMgPSB7fSxcblxuXHQvKiBUcmFuc3BvcnRzIGJpbmRpbmdzXG5cdCAqIDEpIGtleSBpcyB0aGUgZGF0YVR5cGVcblx0ICogMikgdGhlIGNhdGNoYWxsIHN5bWJvbCBcIipcIiBjYW4gYmUgdXNlZFxuXHQgKiAzKSBzZWxlY3Rpb24gd2lsbCBzdGFydCB3aXRoIHRyYW5zcG9ydCBkYXRhVHlwZSBhbmQgVEhFTiBnbyB0byBcIipcIiBpZiBuZWVkZWRcblx0ICovXG5cdHRyYW5zcG9ydHMgPSB7fSxcblxuXHQvLyBBdm9pZCBjb21tZW50LXByb2xvZyBjaGFyIHNlcXVlbmNlICgjMTAwOTgpOyBtdXN0IGFwcGVhc2UgbGludCBhbmQgZXZhZGUgY29tcHJlc3Npb25cblx0YWxsVHlwZXMgPSBcIiovXCIuY29uY2F0KFwiKlwiKTtcblxuLy8gIzgxMzgsIElFIG1heSB0aHJvdyBhbiBleGNlcHRpb24gd2hlbiBhY2Nlc3Npbmdcbi8vIGEgZmllbGQgZnJvbSB3aW5kb3cubG9jYXRpb24gaWYgZG9jdW1lbnQuZG9tYWluIGhhcyBiZWVuIHNldFxudHJ5IHtcblx0YWpheExvY2F0aW9uID0gbG9jYXRpb24uaHJlZjtcbn0gY2F0Y2goIGUgKSB7XG5cdC8vIFVzZSB0aGUgaHJlZiBhdHRyaWJ1dGUgb2YgYW4gQSBlbGVtZW50XG5cdC8vIHNpbmNlIElFIHdpbGwgbW9kaWZ5IGl0IGdpdmVuIGRvY3VtZW50LmxvY2F0aW9uXG5cdGFqYXhMb2NhdGlvbiA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoIFwiYVwiICk7XG5cdGFqYXhMb2NhdGlvbi5ocmVmID0gXCJcIjtcblx0YWpheExvY2F0aW9uID0gYWpheExvY2F0aW9uLmhyZWY7XG59XG5cbi8vIFNlZ21lbnQgbG9jYXRpb24gaW50byBwYXJ0c1xuYWpheExvY1BhcnRzID0gcnVybC5leGVjKCBhamF4TG9jYXRpb24udG9Mb3dlckNhc2UoKSApIHx8IFtdO1xuXG4vLyBCYXNlIFwiY29uc3RydWN0b3JcIiBmb3IgalF1ZXJ5LmFqYXhQcmVmaWx0ZXIgYW5kIGpRdWVyeS5hamF4VHJhbnNwb3J0XG5mdW5jdGlvbiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHN0cnVjdHVyZSApIHtcblxuXHQvLyBkYXRhVHlwZUV4cHJlc3Npb24gaXMgb3B0aW9uYWwgYW5kIGRlZmF1bHRzIHRvIFwiKlwiXG5cdHJldHVybiBmdW5jdGlvbiggZGF0YVR5cGVFeHByZXNzaW9uLCBmdW5jICkge1xuXG5cdFx0aWYgKCB0eXBlb2YgZGF0YVR5cGVFeHByZXNzaW9uICE9PSBcInN0cmluZ1wiICkge1xuXHRcdFx0ZnVuYyA9IGRhdGFUeXBlRXhwcmVzc2lvbjtcblx0XHRcdGRhdGFUeXBlRXhwcmVzc2lvbiA9IFwiKlwiO1xuXHRcdH1cblxuXHRcdHZhciBkYXRhVHlwZSxcblx0XHRcdGkgPSAwLFxuXHRcdFx0ZGF0YVR5cGVzID0gZGF0YVR5cGVFeHByZXNzaW9uLnRvTG93ZXJDYXNlKCkubWF0Y2goIHJub3R3aGl0ZSApIHx8IFtdO1xuXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggZnVuYyApICkge1xuXHRcdFx0Ly8gRm9yIGVhY2ggZGF0YVR5cGUgaW4gdGhlIGRhdGFUeXBlRXhwcmVzc2lvblxuXHRcdFx0d2hpbGUgKCAoZGF0YVR5cGUgPSBkYXRhVHlwZXNbaSsrXSkgKSB7XG5cdFx0XHRcdC8vIFByZXBlbmQgaWYgcmVxdWVzdGVkXG5cdFx0XHRcdGlmICggZGF0YVR5cGUuY2hhckF0KCAwICkgPT09IFwiK1wiICkge1xuXHRcdFx0XHRcdGRhdGFUeXBlID0gZGF0YVR5cGUuc2xpY2UoIDEgKSB8fCBcIipcIjtcblx0XHRcdFx0XHQoc3RydWN0dXJlWyBkYXRhVHlwZSBdID0gc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdKS51bnNoaWZ0KCBmdW5jICk7XG5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIGFwcGVuZFxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdChzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gPSBzdHJ1Y3R1cmVbIGRhdGFUeXBlIF0gfHwgW10pLnB1c2goIGZ1bmMgKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fTtcbn1cblxuLy8gQmFzZSBpbnNwZWN0aW9uIGZ1bmN0aW9uIGZvciBwcmVmaWx0ZXJzIGFuZCB0cmFuc3BvcnRzXG5mdW5jdGlvbiBpbnNwZWN0UHJlZmlsdGVyc09yVHJhbnNwb3J0cyggc3RydWN0dXJlLCBvcHRpb25zLCBvcmlnaW5hbE9wdGlvbnMsIGpxWEhSICkge1xuXG5cdHZhciBpbnNwZWN0ZWQgPSB7fSxcblx0XHRzZWVraW5nVHJhbnNwb3J0ID0gKCBzdHJ1Y3R1cmUgPT09IHRyYW5zcG9ydHMgKTtcblxuXHRmdW5jdGlvbiBpbnNwZWN0KCBkYXRhVHlwZSApIHtcblx0XHR2YXIgc2VsZWN0ZWQ7XG5cdFx0aW5zcGVjdGVkWyBkYXRhVHlwZSBdID0gdHJ1ZTtcblx0XHRqUXVlcnkuZWFjaCggc3RydWN0dXJlWyBkYXRhVHlwZSBdIHx8IFtdLCBmdW5jdGlvbiggXywgcHJlZmlsdGVyT3JGYWN0b3J5ICkge1xuXHRcdFx0dmFyIGRhdGFUeXBlT3JUcmFuc3BvcnQgPSBwcmVmaWx0ZXJPckZhY3RvcnkoIG9wdGlvbnMsIG9yaWdpbmFsT3B0aW9ucywganFYSFIgKTtcblx0XHRcdGlmICggdHlwZW9mIGRhdGFUeXBlT3JUcmFuc3BvcnQgPT09IFwic3RyaW5nXCIgJiYgIXNlZWtpbmdUcmFuc3BvcnQgJiYgIWluc3BlY3RlZFsgZGF0YVR5cGVPclRyYW5zcG9ydCBdICkge1xuXHRcdFx0XHRvcHRpb25zLmRhdGFUeXBlcy51bnNoaWZ0KCBkYXRhVHlwZU9yVHJhbnNwb3J0ICk7XG5cdFx0XHRcdGluc3BlY3QoIGRhdGFUeXBlT3JUcmFuc3BvcnQgKTtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fSBlbHNlIGlmICggc2Vla2luZ1RyYW5zcG9ydCApIHtcblx0XHRcdFx0cmV0dXJuICEoIHNlbGVjdGVkID0gZGF0YVR5cGVPclRyYW5zcG9ydCApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHRcdHJldHVybiBzZWxlY3RlZDtcblx0fVxuXG5cdHJldHVybiBpbnNwZWN0KCBvcHRpb25zLmRhdGFUeXBlc1sgMCBdICkgfHwgIWluc3BlY3RlZFsgXCIqXCIgXSAmJiBpbnNwZWN0KCBcIipcIiApO1xufVxuXG4vLyBBIHNwZWNpYWwgZXh0ZW5kIGZvciBhamF4IG9wdGlvbnNcbi8vIHRoYXQgdGFrZXMgXCJmbGF0XCIgb3B0aW9ucyAobm90IHRvIGJlIGRlZXAgZXh0ZW5kZWQpXG4vLyBGaXhlcyAjOTg4N1xuZnVuY3Rpb24gYWpheEV4dGVuZCggdGFyZ2V0LCBzcmMgKSB7XG5cdHZhciBkZWVwLCBrZXksXG5cdFx0ZmxhdE9wdGlvbnMgPSBqUXVlcnkuYWpheFNldHRpbmdzLmZsYXRPcHRpb25zIHx8IHt9O1xuXG5cdGZvciAoIGtleSBpbiBzcmMgKSB7XG5cdFx0aWYgKCBzcmNbIGtleSBdICE9PSB1bmRlZmluZWQgKSB7XG5cdFx0XHQoIGZsYXRPcHRpb25zWyBrZXkgXSA/IHRhcmdldCA6ICggZGVlcCB8fCAoZGVlcCA9IHt9KSApIClbIGtleSBdID0gc3JjWyBrZXkgXTtcblx0XHR9XG5cdH1cblx0aWYgKCBkZWVwICkge1xuXHRcdGpRdWVyeS5leHRlbmQoIHRydWUsIHRhcmdldCwgZGVlcCApO1xuXHR9XG5cblx0cmV0dXJuIHRhcmdldDtcbn1cblxuLyogSGFuZGxlcyByZXNwb25zZXMgdG8gYW4gYWpheCByZXF1ZXN0OlxuICogLSBmaW5kcyB0aGUgcmlnaHQgZGF0YVR5cGUgKG1lZGlhdGVzIGJldHdlZW4gY29udGVudC10eXBlIGFuZCBleHBlY3RlZCBkYXRhVHlwZSlcbiAqIC0gcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxuICovXG5mdW5jdGlvbiBhamF4SGFuZGxlUmVzcG9uc2VzKCBzLCBqcVhIUiwgcmVzcG9uc2VzICkge1xuXHR2YXIgZmlyc3REYXRhVHlwZSwgY3QsIGZpbmFsRGF0YVR5cGUsIHR5cGUsXG5cdFx0Y29udGVudHMgPSBzLmNvbnRlbnRzLFxuXHRcdGRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzO1xuXG5cdC8vIFJlbW92ZSBhdXRvIGRhdGFUeXBlIGFuZCBnZXQgY29udGVudC10eXBlIGluIHRoZSBwcm9jZXNzXG5cdHdoaWxlICggZGF0YVR5cGVzWyAwIF0gPT09IFwiKlwiICkge1xuXHRcdGRhdGFUeXBlcy5zaGlmdCgpO1xuXHRcdGlmICggY3QgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdGN0ID0gcy5taW1lVHlwZSB8fCBqcVhIUi5nZXRSZXNwb25zZUhlYWRlcihcIkNvbnRlbnQtVHlwZVwiKTtcblx0XHR9XG5cdH1cblxuXHQvLyBDaGVjayBpZiB3ZSdyZSBkZWFsaW5nIHdpdGggYSBrbm93biBjb250ZW50LXR5cGVcblx0aWYgKCBjdCApIHtcblx0XHRmb3IgKCB0eXBlIGluIGNvbnRlbnRzICkge1xuXHRcdFx0aWYgKCBjb250ZW50c1sgdHlwZSBdICYmIGNvbnRlbnRzWyB0eXBlIF0udGVzdCggY3QgKSApIHtcblx0XHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIHR5cGUgKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQ2hlY2sgdG8gc2VlIGlmIHdlIGhhdmUgYSByZXNwb25zZSBmb3IgdGhlIGV4cGVjdGVkIGRhdGFUeXBlXG5cdGlmICggZGF0YVR5cGVzWyAwIF0gaW4gcmVzcG9uc2VzICkge1xuXHRcdGZpbmFsRGF0YVR5cGUgPSBkYXRhVHlwZXNbIDAgXTtcblx0fSBlbHNlIHtcblx0XHQvLyBUcnkgY29udmVydGlibGUgZGF0YVR5cGVzXG5cdFx0Zm9yICggdHlwZSBpbiByZXNwb25zZXMgKSB7XG5cdFx0XHRpZiAoICFkYXRhVHlwZXNbIDAgXSB8fCBzLmNvbnZlcnRlcnNbIHR5cGUgKyBcIiBcIiArIGRhdGFUeXBlc1swXSBdICkge1xuXHRcdFx0XHRmaW5hbERhdGFUeXBlID0gdHlwZTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0XHRpZiAoICFmaXJzdERhdGFUeXBlICkge1xuXHRcdFx0XHRmaXJzdERhdGFUeXBlID0gdHlwZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0Ly8gT3IganVzdCB1c2UgZmlyc3Qgb25lXG5cdFx0ZmluYWxEYXRhVHlwZSA9IGZpbmFsRGF0YVR5cGUgfHwgZmlyc3REYXRhVHlwZTtcblx0fVxuXG5cdC8vIElmIHdlIGZvdW5kIGEgZGF0YVR5cGVcblx0Ly8gV2UgYWRkIHRoZSBkYXRhVHlwZSB0byB0aGUgbGlzdCBpZiBuZWVkZWRcblx0Ly8gYW5kIHJldHVybiB0aGUgY29ycmVzcG9uZGluZyByZXNwb25zZVxuXHRpZiAoIGZpbmFsRGF0YVR5cGUgKSB7XG5cdFx0aWYgKCBmaW5hbERhdGFUeXBlICE9PSBkYXRhVHlwZXNbIDAgXSApIHtcblx0XHRcdGRhdGFUeXBlcy51bnNoaWZ0KCBmaW5hbERhdGFUeXBlICk7XG5cdFx0fVxuXHRcdHJldHVybiByZXNwb25zZXNbIGZpbmFsRGF0YVR5cGUgXTtcblx0fVxufVxuXG4vKiBDaGFpbiBjb252ZXJzaW9ucyBnaXZlbiB0aGUgcmVxdWVzdCBhbmQgdGhlIG9yaWdpbmFsIHJlc3BvbnNlXG4gKiBBbHNvIHNldHMgdGhlIHJlc3BvbnNlWFhYIGZpZWxkcyBvbiB0aGUganFYSFIgaW5zdGFuY2VcbiAqL1xuZnVuY3Rpb24gYWpheENvbnZlcnQoIHMsIHJlc3BvbnNlLCBqcVhIUiwgaXNTdWNjZXNzICkge1xuXHR2YXIgY29udjIsIGN1cnJlbnQsIGNvbnYsIHRtcCwgcHJldixcblx0XHRjb252ZXJ0ZXJzID0ge30sXG5cdFx0Ly8gV29yayB3aXRoIGEgY29weSBvZiBkYXRhVHlwZXMgaW4gY2FzZSB3ZSBuZWVkIHRvIG1vZGlmeSBpdCBmb3IgY29udmVyc2lvblxuXHRcdGRhdGFUeXBlcyA9IHMuZGF0YVR5cGVzLnNsaWNlKCk7XG5cblx0Ly8gQ3JlYXRlIGNvbnZlcnRlcnMgbWFwIHdpdGggbG93ZXJjYXNlZCBrZXlzXG5cdGlmICggZGF0YVR5cGVzWyAxIF0gKSB7XG5cdFx0Zm9yICggY29udiBpbiBzLmNvbnZlcnRlcnMgKSB7XG5cdFx0XHRjb252ZXJ0ZXJzWyBjb252LnRvTG93ZXJDYXNlKCkgXSA9IHMuY29udmVydGVyc1sgY29udiBdO1xuXHRcdH1cblx0fVxuXG5cdGN1cnJlbnQgPSBkYXRhVHlwZXMuc2hpZnQoKTtcblxuXHQvLyBDb252ZXJ0IHRvIGVhY2ggc2VxdWVudGlhbCBkYXRhVHlwZVxuXHR3aGlsZSAoIGN1cnJlbnQgKSB7XG5cblx0XHRpZiAoIHMucmVzcG9uc2VGaWVsZHNbIGN1cnJlbnQgXSApIHtcblx0XHRcdGpxWEhSWyBzLnJlc3BvbnNlRmllbGRzWyBjdXJyZW50IF0gXSA9IHJlc3BvbnNlO1xuXHRcdH1cblxuXHRcdC8vIEFwcGx5IHRoZSBkYXRhRmlsdGVyIGlmIHByb3ZpZGVkXG5cdFx0aWYgKCAhcHJldiAmJiBpc1N1Y2Nlc3MgJiYgcy5kYXRhRmlsdGVyICkge1xuXHRcdFx0cmVzcG9uc2UgPSBzLmRhdGFGaWx0ZXIoIHJlc3BvbnNlLCBzLmRhdGFUeXBlICk7XG5cdFx0fVxuXG5cdFx0cHJldiA9IGN1cnJlbnQ7XG5cdFx0Y3VycmVudCA9IGRhdGFUeXBlcy5zaGlmdCgpO1xuXG5cdFx0aWYgKCBjdXJyZW50ICkge1xuXG5cdFx0XHQvLyBUaGVyZSdzIG9ubHkgd29yayB0byBkbyBpZiBjdXJyZW50IGRhdGFUeXBlIGlzIG5vbi1hdXRvXG5cdFx0XHRpZiAoIGN1cnJlbnQgPT09IFwiKlwiICkge1xuXG5cdFx0XHRcdGN1cnJlbnQgPSBwcmV2O1xuXG5cdFx0XHQvLyBDb252ZXJ0IHJlc3BvbnNlIGlmIHByZXYgZGF0YVR5cGUgaXMgbm9uLWF1dG8gYW5kIGRpZmZlcnMgZnJvbSBjdXJyZW50XG5cdFx0XHR9IGVsc2UgaWYgKCBwcmV2ICE9PSBcIipcIiAmJiBwcmV2ICE9PSBjdXJyZW50ICkge1xuXG5cdFx0XHRcdC8vIFNlZWsgYSBkaXJlY3QgY29udmVydGVyXG5cdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBwcmV2ICsgXCIgXCIgKyBjdXJyZW50IF0gfHwgY29udmVydGVyc1sgXCIqIFwiICsgY3VycmVudCBdO1xuXG5cdFx0XHRcdC8vIElmIG5vbmUgZm91bmQsIHNlZWsgYSBwYWlyXG5cdFx0XHRcdGlmICggIWNvbnYgKSB7XG5cdFx0XHRcdFx0Zm9yICggY29udjIgaW4gY29udmVydGVycyApIHtcblxuXHRcdFx0XHRcdFx0Ly8gSWYgY29udjIgb3V0cHV0cyBjdXJyZW50XG5cdFx0XHRcdFx0XHR0bXAgPSBjb252Mi5zcGxpdCggXCIgXCIgKTtcblx0XHRcdFx0XHRcdGlmICggdG1wWyAxIF0gPT09IGN1cnJlbnQgKSB7XG5cblx0XHRcdFx0XHRcdFx0Ly8gSWYgcHJldiBjYW4gYmUgY29udmVydGVkIHRvIGFjY2VwdGVkIGlucHV0XG5cdFx0XHRcdFx0XHRcdGNvbnYgPSBjb252ZXJ0ZXJzWyBwcmV2ICsgXCIgXCIgKyB0bXBbIDAgXSBdIHx8XG5cdFx0XHRcdFx0XHRcdFx0Y29udmVydGVyc1sgXCIqIFwiICsgdG1wWyAwIF0gXTtcblx0XHRcdFx0XHRcdFx0aWYgKCBjb252ICkge1xuXHRcdFx0XHRcdFx0XHRcdC8vIENvbmRlbnNlIGVxdWl2YWxlbmNlIGNvbnZlcnRlcnNcblx0XHRcdFx0XHRcdFx0XHRpZiAoIGNvbnYgPT09IHRydWUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHRjb252ID0gY29udmVydGVyc1sgY29udjIgXTtcblxuXHRcdFx0XHRcdFx0XHRcdC8vIE90aGVyd2lzZSwgaW5zZXJ0IHRoZSBpbnRlcm1lZGlhdGUgZGF0YVR5cGVcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2UgaWYgKCBjb252ZXJ0ZXJzWyBjb252MiBdICE9PSB0cnVlICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0Y3VycmVudCA9IHRtcFsgMCBdO1xuXHRcdFx0XHRcdFx0XHRcdFx0ZGF0YVR5cGVzLnVuc2hpZnQoIHRtcFsgMSBdICk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHRcdGJyZWFrO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gQXBwbHkgY29udmVydGVyIChpZiBub3QgYW4gZXF1aXZhbGVuY2UpXG5cdFx0XHRcdGlmICggY29udiAhPT0gdHJ1ZSApIHtcblxuXHRcdFx0XHRcdC8vIFVubGVzcyBlcnJvcnMgYXJlIGFsbG93ZWQgdG8gYnViYmxlLCBjYXRjaCBhbmQgcmV0dXJuIHRoZW1cblx0XHRcdFx0XHRpZiAoIGNvbnYgJiYgc1sgXCJ0aHJvd3NcIiBdICkge1xuXHRcdFx0XHRcdFx0cmVzcG9uc2UgPSBjb252KCByZXNwb25zZSApO1xuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRyZXNwb25zZSA9IGNvbnYoIHJlc3BvbnNlICk7XG5cdFx0XHRcdFx0XHR9IGNhdGNoICggZSApIHtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIHsgc3RhdGU6IFwicGFyc2VyZXJyb3JcIiwgZXJyb3I6IGNvbnYgPyBlIDogXCJObyBjb252ZXJzaW9uIGZyb20gXCIgKyBwcmV2ICsgXCIgdG8gXCIgKyBjdXJyZW50IH07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIHsgc3RhdGU6IFwic3VjY2Vzc1wiLCBkYXRhOiByZXNwb25zZSB9O1xufVxuXG5qUXVlcnkuZXh0ZW5kKHtcblxuXHQvLyBDb3VudGVyIGZvciBob2xkaW5nIHRoZSBudW1iZXIgb2YgYWN0aXZlIHF1ZXJpZXNcblx0YWN0aXZlOiAwLFxuXG5cdC8vIExhc3QtTW9kaWZpZWQgaGVhZGVyIGNhY2hlIGZvciBuZXh0IHJlcXVlc3Rcblx0bGFzdE1vZGlmaWVkOiB7fSxcblx0ZXRhZzoge30sXG5cblx0YWpheFNldHRpbmdzOiB7XG5cdFx0dXJsOiBhamF4TG9jYXRpb24sXG5cdFx0dHlwZTogXCJHRVRcIixcblx0XHRpc0xvY2FsOiBybG9jYWxQcm90b2NvbC50ZXN0KCBhamF4TG9jUGFydHNbIDEgXSApLFxuXHRcdGdsb2JhbDogdHJ1ZSxcblx0XHRwcm9jZXNzRGF0YTogdHJ1ZSxcblx0XHRhc3luYzogdHJ1ZSxcblx0XHRjb250ZW50VHlwZTogXCJhcHBsaWNhdGlvbi94LXd3dy1mb3JtLXVybGVuY29kZWQ7IGNoYXJzZXQ9VVRGLThcIixcblx0XHQvKlxuXHRcdHRpbWVvdXQ6IDAsXG5cdFx0ZGF0YTogbnVsbCxcblx0XHRkYXRhVHlwZTogbnVsbCxcblx0XHR1c2VybmFtZTogbnVsbCxcblx0XHRwYXNzd29yZDogbnVsbCxcblx0XHRjYWNoZTogbnVsbCxcblx0XHR0aHJvd3M6IGZhbHNlLFxuXHRcdHRyYWRpdGlvbmFsOiBmYWxzZSxcblx0XHRoZWFkZXJzOiB7fSxcblx0XHQqL1xuXG5cdFx0YWNjZXB0czoge1xuXHRcdFx0XCIqXCI6IGFsbFR5cGVzLFxuXHRcdFx0dGV4dDogXCJ0ZXh0L3BsYWluXCIsXG5cdFx0XHRodG1sOiBcInRleHQvaHRtbFwiLFxuXHRcdFx0eG1sOiBcImFwcGxpY2F0aW9uL3htbCwgdGV4dC94bWxcIixcblx0XHRcdGpzb246IFwiYXBwbGljYXRpb24vanNvbiwgdGV4dC9qYXZhc2NyaXB0XCJcblx0XHR9LFxuXG5cdFx0Y29udGVudHM6IHtcblx0XHRcdHhtbDogL3htbC8sXG5cdFx0XHRodG1sOiAvaHRtbC8sXG5cdFx0XHRqc29uOiAvanNvbi9cblx0XHR9LFxuXG5cdFx0cmVzcG9uc2VGaWVsZHM6IHtcblx0XHRcdHhtbDogXCJyZXNwb25zZVhNTFwiLFxuXHRcdFx0dGV4dDogXCJyZXNwb25zZVRleHRcIixcblx0XHRcdGpzb246IFwicmVzcG9uc2VKU09OXCJcblx0XHR9LFxuXG5cdFx0Ly8gRGF0YSBjb252ZXJ0ZXJzXG5cdFx0Ly8gS2V5cyBzZXBhcmF0ZSBzb3VyY2UgKG9yIGNhdGNoYWxsIFwiKlwiKSBhbmQgZGVzdGluYXRpb24gdHlwZXMgd2l0aCBhIHNpbmdsZSBzcGFjZVxuXHRcdGNvbnZlcnRlcnM6IHtcblxuXHRcdFx0Ly8gQ29udmVydCBhbnl0aGluZyB0byB0ZXh0XG5cdFx0XHRcIiogdGV4dFwiOiBTdHJpbmcsXG5cblx0XHRcdC8vIFRleHQgdG8gaHRtbCAodHJ1ZSA9IG5vIHRyYW5zZm9ybWF0aW9uKVxuXHRcdFx0XCJ0ZXh0IGh0bWxcIjogdHJ1ZSxcblxuXHRcdFx0Ly8gRXZhbHVhdGUgdGV4dCBhcyBhIGpzb24gZXhwcmVzc2lvblxuXHRcdFx0XCJ0ZXh0IGpzb25cIjogalF1ZXJ5LnBhcnNlSlNPTixcblxuXHRcdFx0Ly8gUGFyc2UgdGV4dCBhcyB4bWxcblx0XHRcdFwidGV4dCB4bWxcIjogalF1ZXJ5LnBhcnNlWE1MXG5cdFx0fSxcblxuXHRcdC8vIEZvciBvcHRpb25zIHRoYXQgc2hvdWxkbid0IGJlIGRlZXAgZXh0ZW5kZWQ6XG5cdFx0Ly8geW91IGNhbiBhZGQgeW91ciBvd24gY3VzdG9tIG9wdGlvbnMgaGVyZSBpZlxuXHRcdC8vIGFuZCB3aGVuIHlvdSBjcmVhdGUgb25lIHRoYXQgc2hvdWxkbid0IGJlXG5cdFx0Ly8gZGVlcCBleHRlbmRlZCAoc2VlIGFqYXhFeHRlbmQpXG5cdFx0ZmxhdE9wdGlvbnM6IHtcblx0XHRcdHVybDogdHJ1ZSxcblx0XHRcdGNvbnRleHQ6IHRydWVcblx0XHR9XG5cdH0sXG5cblx0Ly8gQ3JlYXRlcyBhIGZ1bGwgZmxlZGdlZCBzZXR0aW5ncyBvYmplY3QgaW50byB0YXJnZXRcblx0Ly8gd2l0aCBib3RoIGFqYXhTZXR0aW5ncyBhbmQgc2V0dGluZ3MgZmllbGRzLlxuXHQvLyBJZiB0YXJnZXQgaXMgb21pdHRlZCwgd3JpdGVzIGludG8gYWpheFNldHRpbmdzLlxuXHRhamF4U2V0dXA6IGZ1bmN0aW9uKCB0YXJnZXQsIHNldHRpbmdzICkge1xuXHRcdHJldHVybiBzZXR0aW5ncyA/XG5cblx0XHRcdC8vIEJ1aWxkaW5nIGEgc2V0dGluZ3Mgb2JqZWN0XG5cdFx0XHRhamF4RXh0ZW5kKCBhamF4RXh0ZW5kKCB0YXJnZXQsIGpRdWVyeS5hamF4U2V0dGluZ3MgKSwgc2V0dGluZ3MgKSA6XG5cblx0XHRcdC8vIEV4dGVuZGluZyBhamF4U2V0dGluZ3Ncblx0XHRcdGFqYXhFeHRlbmQoIGpRdWVyeS5hamF4U2V0dGluZ3MsIHRhcmdldCApO1xuXHR9LFxuXG5cdGFqYXhQcmVmaWx0ZXI6IGFkZFRvUHJlZmlsdGVyc09yVHJhbnNwb3J0cyggcHJlZmlsdGVycyApLFxuXHRhamF4VHJhbnNwb3J0OiBhZGRUb1ByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHRyYW5zcG9ydHMgKSxcblxuXHQvLyBNYWluIG1ldGhvZFxuXHRhamF4OiBmdW5jdGlvbiggdXJsLCBvcHRpb25zICkge1xuXG5cdFx0Ly8gSWYgdXJsIGlzIGFuIG9iamVjdCwgc2ltdWxhdGUgcHJlLTEuNSBzaWduYXR1cmVcblx0XHRpZiAoIHR5cGVvZiB1cmwgPT09IFwib2JqZWN0XCIgKSB7XG5cdFx0XHRvcHRpb25zID0gdXJsO1xuXHRcdFx0dXJsID0gdW5kZWZpbmVkO1xuXHRcdH1cblxuXHRcdC8vIEZvcmNlIG9wdGlvbnMgdG8gYmUgYW4gb2JqZWN0XG5cdFx0b3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cblx0XHR2YXIgLy8gQ3Jvc3MtZG9tYWluIGRldGVjdGlvbiB2YXJzXG5cdFx0XHRwYXJ0cyxcblx0XHRcdC8vIExvb3AgdmFyaWFibGVcblx0XHRcdGksXG5cdFx0XHQvLyBVUkwgd2l0aG91dCBhbnRpLWNhY2hlIHBhcmFtXG5cdFx0XHRjYWNoZVVSTCxcblx0XHRcdC8vIFJlc3BvbnNlIGhlYWRlcnMgYXMgc3RyaW5nXG5cdFx0XHRyZXNwb25zZUhlYWRlcnNTdHJpbmcsXG5cdFx0XHQvLyB0aW1lb3V0IGhhbmRsZVxuXHRcdFx0dGltZW91dFRpbWVyLFxuXG5cdFx0XHQvLyBUbyBrbm93IGlmIGdsb2JhbCBldmVudHMgYXJlIHRvIGJlIGRpc3BhdGNoZWRcblx0XHRcdGZpcmVHbG9iYWxzLFxuXG5cdFx0XHR0cmFuc3BvcnQsXG5cdFx0XHQvLyBSZXNwb25zZSBoZWFkZXJzXG5cdFx0XHRyZXNwb25zZUhlYWRlcnMsXG5cdFx0XHQvLyBDcmVhdGUgdGhlIGZpbmFsIG9wdGlvbnMgb2JqZWN0XG5cdFx0XHRzID0galF1ZXJ5LmFqYXhTZXR1cCgge30sIG9wdGlvbnMgKSxcblx0XHRcdC8vIENhbGxiYWNrcyBjb250ZXh0XG5cdFx0XHRjYWxsYmFja0NvbnRleHQgPSBzLmNvbnRleHQgfHwgcyxcblx0XHRcdC8vIENvbnRleHQgZm9yIGdsb2JhbCBldmVudHMgaXMgY2FsbGJhY2tDb250ZXh0IGlmIGl0IGlzIGEgRE9NIG5vZGUgb3IgalF1ZXJ5IGNvbGxlY3Rpb25cblx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dCA9IHMuY29udGV4dCAmJiAoIGNhbGxiYWNrQ29udGV4dC5ub2RlVHlwZSB8fCBjYWxsYmFja0NvbnRleHQuanF1ZXJ5ICkgP1xuXHRcdFx0XHRqUXVlcnkoIGNhbGxiYWNrQ29udGV4dCApIDpcblx0XHRcdFx0alF1ZXJ5LmV2ZW50LFxuXHRcdFx0Ly8gRGVmZXJyZWRzXG5cdFx0XHRkZWZlcnJlZCA9IGpRdWVyeS5EZWZlcnJlZCgpLFxuXHRcdFx0Y29tcGxldGVEZWZlcnJlZCA9IGpRdWVyeS5DYWxsYmFja3MoXCJvbmNlIG1lbW9yeVwiKSxcblx0XHRcdC8vIFN0YXR1cy1kZXBlbmRlbnQgY2FsbGJhY2tzXG5cdFx0XHRzdGF0dXNDb2RlID0gcy5zdGF0dXNDb2RlIHx8IHt9LFxuXHRcdFx0Ly8gSGVhZGVycyAodGhleSBhcmUgc2VudCBhbGwgYXQgb25jZSlcblx0XHRcdHJlcXVlc3RIZWFkZXJzID0ge30sXG5cdFx0XHRyZXF1ZXN0SGVhZGVyc05hbWVzID0ge30sXG5cdFx0XHQvLyBUaGUganFYSFIgc3RhdGVcblx0XHRcdHN0YXRlID0gMCxcblx0XHRcdC8vIERlZmF1bHQgYWJvcnQgbWVzc2FnZVxuXHRcdFx0c3RyQWJvcnQgPSBcImNhbmNlbGVkXCIsXG5cdFx0XHQvLyBGYWtlIHhoclxuXHRcdFx0anFYSFIgPSB7XG5cdFx0XHRcdHJlYWR5U3RhdGU6IDAsXG5cblx0XHRcdFx0Ly8gQnVpbGRzIGhlYWRlcnMgaGFzaHRhYmxlIGlmIG5lZWRlZFxuXHRcdFx0XHRnZXRSZXNwb25zZUhlYWRlcjogZnVuY3Rpb24oIGtleSApIHtcblx0XHRcdFx0XHR2YXIgbWF0Y2g7XG5cdFx0XHRcdFx0aWYgKCBzdGF0ZSA9PT0gMiApIHtcblx0XHRcdFx0XHRcdGlmICggIXJlc3BvbnNlSGVhZGVycyApIHtcblx0XHRcdFx0XHRcdFx0cmVzcG9uc2VIZWFkZXJzID0ge307XG5cdFx0XHRcdFx0XHRcdHdoaWxlICggKG1hdGNoID0gcmhlYWRlcnMuZXhlYyggcmVzcG9uc2VIZWFkZXJzU3RyaW5nICkpICkge1xuXHRcdFx0XHRcdFx0XHRcdHJlc3BvbnNlSGVhZGVyc1sgbWF0Y2hbMV0udG9Mb3dlckNhc2UoKSBdID0gbWF0Y2hbIDIgXTtcblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0bWF0Y2ggPSByZXNwb25zZUhlYWRlcnNbIGtleS50b0xvd2VyQ2FzZSgpIF07XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdHJldHVybiBtYXRjaCA9PSBudWxsID8gbnVsbCA6IG1hdGNoO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIFJhdyBzdHJpbmdcblx0XHRcdFx0Z2V0QWxsUmVzcG9uc2VIZWFkZXJzOiBmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRyZXR1cm4gc3RhdGUgPT09IDIgPyByZXNwb25zZUhlYWRlcnNTdHJpbmcgOiBudWxsO1xuXHRcdFx0XHR9LFxuXG5cdFx0XHRcdC8vIENhY2hlcyB0aGUgaGVhZGVyXG5cdFx0XHRcdHNldFJlcXVlc3RIZWFkZXI6IGZ1bmN0aW9uKCBuYW1lLCB2YWx1ZSApIHtcblx0XHRcdFx0XHR2YXIgbG5hbWUgPSBuYW1lLnRvTG93ZXJDYXNlKCk7XG5cdFx0XHRcdFx0aWYgKCAhc3RhdGUgKSB7XG5cdFx0XHRcdFx0XHRuYW1lID0gcmVxdWVzdEhlYWRlcnNOYW1lc1sgbG5hbWUgXSA9IHJlcXVlc3RIZWFkZXJzTmFtZXNbIGxuYW1lIF0gfHwgbmFtZTtcblx0XHRcdFx0XHRcdHJlcXVlc3RIZWFkZXJzWyBuYW1lIF0gPSB2YWx1ZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gT3ZlcnJpZGVzIHJlc3BvbnNlIGNvbnRlbnQtdHlwZSBoZWFkZXJcblx0XHRcdFx0b3ZlcnJpZGVNaW1lVHlwZTogZnVuY3Rpb24oIHR5cGUgKSB7XG5cdFx0XHRcdFx0aWYgKCAhc3RhdGUgKSB7XG5cdFx0XHRcdFx0XHRzLm1pbWVUeXBlID0gdHlwZTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gU3RhdHVzLWRlcGVuZGVudCBjYWxsYmFja3Ncblx0XHRcdFx0c3RhdHVzQ29kZTogZnVuY3Rpb24oIG1hcCApIHtcblx0XHRcdFx0XHR2YXIgY29kZTtcblx0XHRcdFx0XHRpZiAoIG1hcCApIHtcblx0XHRcdFx0XHRcdGlmICggc3RhdGUgPCAyICkge1xuXHRcdFx0XHRcdFx0XHRmb3IgKCBjb2RlIGluIG1hcCApIHtcblx0XHRcdFx0XHRcdFx0XHQvLyBMYXp5LWFkZCB0aGUgbmV3IGNhbGxiYWNrIGluIGEgd2F5IHRoYXQgcHJlc2VydmVzIG9sZCBvbmVzXG5cdFx0XHRcdFx0XHRcdFx0c3RhdHVzQ29kZVsgY29kZSBdID0gWyBzdGF0dXNDb2RlWyBjb2RlIF0sIG1hcFsgY29kZSBdIF07XG5cdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdC8vIEV4ZWN1dGUgdGhlIGFwcHJvcHJpYXRlIGNhbGxiYWNrc1xuXHRcdFx0XHRcdFx0XHRqcVhIUi5hbHdheXMoIG1hcFsganFYSFIuc3RhdHVzIF0gKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0cmV0dXJuIHRoaXM7XG5cdFx0XHRcdH0sXG5cblx0XHRcdFx0Ly8gQ2FuY2VsIHRoZSByZXF1ZXN0XG5cdFx0XHRcdGFib3J0OiBmdW5jdGlvbiggc3RhdHVzVGV4dCApIHtcblx0XHRcdFx0XHR2YXIgZmluYWxUZXh0ID0gc3RhdHVzVGV4dCB8fCBzdHJBYm9ydDtcblx0XHRcdFx0XHRpZiAoIHRyYW5zcG9ydCApIHtcblx0XHRcdFx0XHRcdHRyYW5zcG9ydC5hYm9ydCggZmluYWxUZXh0ICk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHRcdGRvbmUoIDAsIGZpbmFsVGV4dCApO1xuXHRcdFx0XHRcdHJldHVybiB0aGlzO1xuXHRcdFx0XHR9XG5cdFx0XHR9O1xuXG5cdFx0Ly8gQXR0YWNoIGRlZmVycmVkc1xuXHRcdGRlZmVycmVkLnByb21pc2UoIGpxWEhSICkuY29tcGxldGUgPSBjb21wbGV0ZURlZmVycmVkLmFkZDtcblx0XHRqcVhIUi5zdWNjZXNzID0ganFYSFIuZG9uZTtcblx0XHRqcVhIUi5lcnJvciA9IGpxWEhSLmZhaWw7XG5cblx0XHQvLyBSZW1vdmUgaGFzaCBjaGFyYWN0ZXIgKCM3NTMxOiBhbmQgc3RyaW5nIHByb21vdGlvbilcblx0XHQvLyBBZGQgcHJvdG9jb2wgaWYgbm90IHByb3ZpZGVkICgjNTg2NjogSUU3IGlzc3VlIHdpdGggcHJvdG9jb2wtbGVzcyB1cmxzKVxuXHRcdC8vIEhhbmRsZSBmYWxzeSB1cmwgaW4gdGhlIHNldHRpbmdzIG9iamVjdCAoIzEwMDkzOiBjb25zaXN0ZW5jeSB3aXRoIG9sZCBzaWduYXR1cmUpXG5cdFx0Ly8gV2UgYWxzbyB1c2UgdGhlIHVybCBwYXJhbWV0ZXIgaWYgYXZhaWxhYmxlXG5cdFx0cy51cmwgPSAoICggdXJsIHx8IHMudXJsIHx8IGFqYXhMb2NhdGlvbiApICsgXCJcIiApLnJlcGxhY2UoIHJoYXNoLCBcIlwiICkucmVwbGFjZSggcnByb3RvY29sLCBhamF4TG9jUGFydHNbIDEgXSArIFwiLy9cIiApO1xuXG5cdFx0Ly8gQWxpYXMgbWV0aG9kIG9wdGlvbiB0byB0eXBlIGFzIHBlciB0aWNrZXQgIzEyMDA0XG5cdFx0cy50eXBlID0gb3B0aW9ucy5tZXRob2QgfHwgb3B0aW9ucy50eXBlIHx8IHMubWV0aG9kIHx8IHMudHlwZTtcblxuXHRcdC8vIEV4dHJhY3QgZGF0YVR5cGVzIGxpc3Rcblx0XHRzLmRhdGFUeXBlcyA9IGpRdWVyeS50cmltKCBzLmRhdGFUeXBlIHx8IFwiKlwiICkudG9Mb3dlckNhc2UoKS5tYXRjaCggcm5vdHdoaXRlICkgfHwgWyBcIlwiIF07XG5cblx0XHQvLyBBIGNyb3NzLWRvbWFpbiByZXF1ZXN0IGlzIGluIG9yZGVyIHdoZW4gd2UgaGF2ZSBhIHByb3RvY29sOmhvc3Q6cG9ydCBtaXNtYXRjaFxuXHRcdGlmICggcy5jcm9zc0RvbWFpbiA9PSBudWxsICkge1xuXHRcdFx0cGFydHMgPSBydXJsLmV4ZWMoIHMudXJsLnRvTG93ZXJDYXNlKCkgKTtcblx0XHRcdHMuY3Jvc3NEb21haW4gPSAhISggcGFydHMgJiZcblx0XHRcdFx0KCBwYXJ0c1sgMSBdICE9PSBhamF4TG9jUGFydHNbIDEgXSB8fCBwYXJ0c1sgMiBdICE9PSBhamF4TG9jUGFydHNbIDIgXSB8fFxuXHRcdFx0XHRcdCggcGFydHNbIDMgXSB8fCAoIHBhcnRzWyAxIF0gPT09IFwiaHR0cDpcIiA/IFwiODBcIiA6IFwiNDQzXCIgKSApICE9PVxuXHRcdFx0XHRcdFx0KCBhamF4TG9jUGFydHNbIDMgXSB8fCAoIGFqYXhMb2NQYXJ0c1sgMSBdID09PSBcImh0dHA6XCIgPyBcIjgwXCIgOiBcIjQ0M1wiICkgKSApXG5cdFx0XHQpO1xuXHRcdH1cblxuXHRcdC8vIENvbnZlcnQgZGF0YSBpZiBub3QgYWxyZWFkeSBhIHN0cmluZ1xuXHRcdGlmICggcy5kYXRhICYmIHMucHJvY2Vzc0RhdGEgJiYgdHlwZW9mIHMuZGF0YSAhPT0gXCJzdHJpbmdcIiApIHtcblx0XHRcdHMuZGF0YSA9IGpRdWVyeS5wYXJhbSggcy5kYXRhLCBzLnRyYWRpdGlvbmFsICk7XG5cdFx0fVxuXG5cdFx0Ly8gQXBwbHkgcHJlZmlsdGVyc1xuXHRcdGluc3BlY3RQcmVmaWx0ZXJzT3JUcmFuc3BvcnRzKCBwcmVmaWx0ZXJzLCBzLCBvcHRpb25zLCBqcVhIUiApO1xuXG5cdFx0Ly8gSWYgcmVxdWVzdCB3YXMgYWJvcnRlZCBpbnNpZGUgYSBwcmVmaWx0ZXIsIHN0b3AgdGhlcmVcblx0XHRpZiAoIHN0YXRlID09PSAyICkge1xuXHRcdFx0cmV0dXJuIGpxWEhSO1xuXHRcdH1cblxuXHRcdC8vIFdlIGNhbiBmaXJlIGdsb2JhbCBldmVudHMgYXMgb2Ygbm93IGlmIGFza2VkIHRvXG5cdFx0Ly8gRG9uJ3QgZmlyZSBldmVudHMgaWYgalF1ZXJ5LmV2ZW50IGlzIHVuZGVmaW5lZCBpbiBhbiBBTUQtdXNhZ2Ugc2NlbmFyaW8gKCMxNTExOClcblx0XHRmaXJlR2xvYmFscyA9IGpRdWVyeS5ldmVudCAmJiBzLmdsb2JhbDtcblxuXHRcdC8vIFdhdGNoIGZvciBhIG5ldyBzZXQgb2YgcmVxdWVzdHNcblx0XHRpZiAoIGZpcmVHbG9iYWxzICYmIGpRdWVyeS5hY3RpdmUrKyA9PT0gMCApIHtcblx0XHRcdGpRdWVyeS5ldmVudC50cmlnZ2VyKFwiYWpheFN0YXJ0XCIpO1xuXHRcdH1cblxuXHRcdC8vIFVwcGVyY2FzZSB0aGUgdHlwZVxuXHRcdHMudHlwZSA9IHMudHlwZS50b1VwcGVyQ2FzZSgpO1xuXG5cdFx0Ly8gRGV0ZXJtaW5lIGlmIHJlcXVlc3QgaGFzIGNvbnRlbnRcblx0XHRzLmhhc0NvbnRlbnQgPSAhcm5vQ29udGVudC50ZXN0KCBzLnR5cGUgKTtcblxuXHRcdC8vIFNhdmUgdGhlIFVSTCBpbiBjYXNlIHdlJ3JlIHRveWluZyB3aXRoIHRoZSBJZi1Nb2RpZmllZC1TaW5jZVxuXHRcdC8vIGFuZC9vciBJZi1Ob25lLU1hdGNoIGhlYWRlciBsYXRlciBvblxuXHRcdGNhY2hlVVJMID0gcy51cmw7XG5cblx0XHQvLyBNb3JlIG9wdGlvbnMgaGFuZGxpbmcgZm9yIHJlcXVlc3RzIHdpdGggbm8gY29udGVudFxuXHRcdGlmICggIXMuaGFzQ29udGVudCApIHtcblxuXHRcdFx0Ly8gSWYgZGF0YSBpcyBhdmFpbGFibGUsIGFwcGVuZCBkYXRhIHRvIHVybFxuXHRcdFx0aWYgKCBzLmRhdGEgKSB7XG5cdFx0XHRcdGNhY2hlVVJMID0gKCBzLnVybCArPSAoIHJxdWVyeS50ZXN0KCBjYWNoZVVSTCApID8gXCImXCIgOiBcIj9cIiApICsgcy5kYXRhICk7XG5cdFx0XHRcdC8vICM5NjgyOiByZW1vdmUgZGF0YSBzbyB0aGF0IGl0J3Mgbm90IHVzZWQgaW4gYW4gZXZlbnR1YWwgcmV0cnlcblx0XHRcdFx0ZGVsZXRlIHMuZGF0YTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQWRkIGFudGktY2FjaGUgaW4gdXJsIGlmIG5lZWRlZFxuXHRcdFx0aWYgKCBzLmNhY2hlID09PSBmYWxzZSApIHtcblx0XHRcdFx0cy51cmwgPSBydHMudGVzdCggY2FjaGVVUkwgKSA/XG5cblx0XHRcdFx0XHQvLyBJZiB0aGVyZSBpcyBhbHJlYWR5IGEgJ18nIHBhcmFtZXRlciwgc2V0IGl0cyB2YWx1ZVxuXHRcdFx0XHRcdGNhY2hlVVJMLnJlcGxhY2UoIHJ0cywgXCIkMV89XCIgKyBub25jZSsrICkgOlxuXG5cdFx0XHRcdFx0Ly8gT3RoZXJ3aXNlIGFkZCBvbmUgdG8gdGhlIGVuZFxuXHRcdFx0XHRcdGNhY2hlVVJMICsgKCBycXVlcnkudGVzdCggY2FjaGVVUkwgKSA/IFwiJlwiIDogXCI/XCIgKSArIFwiXz1cIiArIG5vbmNlKys7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0Ly8gU2V0IHRoZSBJZi1Nb2RpZmllZC1TaW5jZSBhbmQvb3IgSWYtTm9uZS1NYXRjaCBoZWFkZXIsIGlmIGluIGlmTW9kaWZpZWQgbW9kZS5cblx0XHRpZiAoIHMuaWZNb2RpZmllZCApIHtcblx0XHRcdGlmICggalF1ZXJ5Lmxhc3RNb2RpZmllZFsgY2FjaGVVUkwgXSApIHtcblx0XHRcdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlciggXCJJZi1Nb2RpZmllZC1TaW5jZVwiLCBqUXVlcnkubGFzdE1vZGlmaWVkWyBjYWNoZVVSTCBdICk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoIGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdICkge1xuXHRcdFx0XHRqcVhIUi5zZXRSZXF1ZXN0SGVhZGVyKCBcIklmLU5vbmUtTWF0Y2hcIiwgalF1ZXJ5LmV0YWdbIGNhY2hlVVJMIF0gKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIGNvcnJlY3QgaGVhZGVyLCBpZiBkYXRhIGlzIGJlaW5nIHNlbnRcblx0XHRpZiAoIHMuZGF0YSAmJiBzLmhhc0NvbnRlbnQgJiYgcy5jb250ZW50VHlwZSAhPT0gZmFsc2UgfHwgb3B0aW9ucy5jb250ZW50VHlwZSApIHtcblx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIFwiQ29udGVudC1UeXBlXCIsIHMuY29udGVudFR5cGUgKTtcblx0XHR9XG5cblx0XHQvLyBTZXQgdGhlIEFjY2VwdHMgaGVhZGVyIGZvciB0aGUgc2VydmVyLCBkZXBlbmRpbmcgb24gdGhlIGRhdGFUeXBlXG5cdFx0anFYSFIuc2V0UmVxdWVzdEhlYWRlcihcblx0XHRcdFwiQWNjZXB0XCIsXG5cdFx0XHRzLmRhdGFUeXBlc1sgMCBdICYmIHMuYWNjZXB0c1sgcy5kYXRhVHlwZXNbMF0gXSA/XG5cdFx0XHRcdHMuYWNjZXB0c1sgcy5kYXRhVHlwZXNbMF0gXSArICggcy5kYXRhVHlwZXNbIDAgXSAhPT0gXCIqXCIgPyBcIiwgXCIgKyBhbGxUeXBlcyArIFwiOyBxPTAuMDFcIiA6IFwiXCIgKSA6XG5cdFx0XHRcdHMuYWNjZXB0c1sgXCIqXCIgXVxuXHRcdCk7XG5cblx0XHQvLyBDaGVjayBmb3IgaGVhZGVycyBvcHRpb25cblx0XHRmb3IgKCBpIGluIHMuaGVhZGVycyApIHtcblx0XHRcdGpxWEhSLnNldFJlcXVlc3RIZWFkZXIoIGksIHMuaGVhZGVyc1sgaSBdICk7XG5cdFx0fVxuXG5cdFx0Ly8gQWxsb3cgY3VzdG9tIGhlYWRlcnMvbWltZXR5cGVzIGFuZCBlYXJseSBhYm9ydFxuXHRcdGlmICggcy5iZWZvcmVTZW5kICYmICggcy5iZWZvcmVTZW5kLmNhbGwoIGNhbGxiYWNrQ29udGV4dCwganFYSFIsIHMgKSA9PT0gZmFsc2UgfHwgc3RhdGUgPT09IDIgKSApIHtcblx0XHRcdC8vIEFib3J0IGlmIG5vdCBkb25lIGFscmVhZHkgYW5kIHJldHVyblxuXHRcdFx0cmV0dXJuIGpxWEhSLmFib3J0KCk7XG5cdFx0fVxuXG5cdFx0Ly8gYWJvcnRpbmcgaXMgbm8gbG9uZ2VyIGEgY2FuY2VsbGF0aW9uXG5cdFx0c3RyQWJvcnQgPSBcImFib3J0XCI7XG5cblx0XHQvLyBJbnN0YWxsIGNhbGxiYWNrcyBvbiBkZWZlcnJlZHNcblx0XHRmb3IgKCBpIGluIHsgc3VjY2VzczogMSwgZXJyb3I6IDEsIGNvbXBsZXRlOiAxIH0gKSB7XG5cdFx0XHRqcVhIUlsgaSBdKCBzWyBpIF0gKTtcblx0XHR9XG5cblx0XHQvLyBHZXQgdHJhbnNwb3J0XG5cdFx0dHJhbnNwb3J0ID0gaW5zcGVjdFByZWZpbHRlcnNPclRyYW5zcG9ydHMoIHRyYW5zcG9ydHMsIHMsIG9wdGlvbnMsIGpxWEhSICk7XG5cblx0XHQvLyBJZiBubyB0cmFuc3BvcnQsIHdlIGF1dG8tYWJvcnRcblx0XHRpZiAoICF0cmFuc3BvcnQgKSB7XG5cdFx0XHRkb25lKCAtMSwgXCJObyBUcmFuc3BvcnRcIiApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRqcVhIUi5yZWFkeVN0YXRlID0gMTtcblxuXHRcdFx0Ly8gU2VuZCBnbG9iYWwgZXZlbnRcblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBcImFqYXhTZW5kXCIsIFsganFYSFIsIHMgXSApO1xuXHRcdFx0fVxuXHRcdFx0Ly8gVGltZW91dFxuXHRcdFx0aWYgKCBzLmFzeW5jICYmIHMudGltZW91dCA+IDAgKSB7XG5cdFx0XHRcdHRpbWVvdXRUaW1lciA9IHNldFRpbWVvdXQoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0anFYSFIuYWJvcnQoXCJ0aW1lb3V0XCIpO1xuXHRcdFx0XHR9LCBzLnRpbWVvdXQgKTtcblx0XHRcdH1cblxuXHRcdFx0dHJ5IHtcblx0XHRcdFx0c3RhdGUgPSAxO1xuXHRcdFx0XHR0cmFuc3BvcnQuc2VuZCggcmVxdWVzdEhlYWRlcnMsIGRvbmUgKTtcblx0XHRcdH0gY2F0Y2ggKCBlICkge1xuXHRcdFx0XHQvLyBQcm9wYWdhdGUgZXhjZXB0aW9uIGFzIGVycm9yIGlmIG5vdCBkb25lXG5cdFx0XHRcdGlmICggc3RhdGUgPCAyICkge1xuXHRcdFx0XHRcdGRvbmUoIC0xLCBlICk7XG5cdFx0XHRcdC8vIFNpbXBseSByZXRocm93IG90aGVyd2lzZVxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdHRocm93IGU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBDYWxsYmFjayBmb3Igd2hlbiBldmVyeXRoaW5nIGlzIGRvbmVcblx0XHRmdW5jdGlvbiBkb25lKCBzdGF0dXMsIG5hdGl2ZVN0YXR1c1RleHQsIHJlc3BvbnNlcywgaGVhZGVycyApIHtcblx0XHRcdHZhciBpc1N1Y2Nlc3MsIHN1Y2Nlc3MsIGVycm9yLCByZXNwb25zZSwgbW9kaWZpZWQsXG5cdFx0XHRcdHN0YXR1c1RleHQgPSBuYXRpdmVTdGF0dXNUZXh0O1xuXG5cdFx0XHQvLyBDYWxsZWQgb25jZVxuXHRcdFx0aWYgKCBzdGF0ZSA9PT0gMiApIHtcblx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdGF0ZSBpcyBcImRvbmVcIiBub3dcblx0XHRcdHN0YXRlID0gMjtcblxuXHRcdFx0Ly8gQ2xlYXIgdGltZW91dCBpZiBpdCBleGlzdHNcblx0XHRcdGlmICggdGltZW91dFRpbWVyICkge1xuXHRcdFx0XHRjbGVhclRpbWVvdXQoIHRpbWVvdXRUaW1lciApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBEZXJlZmVyZW5jZSB0cmFuc3BvcnQgZm9yIGVhcmx5IGdhcmJhZ2UgY29sbGVjdGlvblxuXHRcdFx0Ly8gKG5vIG1hdHRlciBob3cgbG9uZyB0aGUganFYSFIgb2JqZWN0IHdpbGwgYmUgdXNlZClcblx0XHRcdHRyYW5zcG9ydCA9IHVuZGVmaW5lZDtcblxuXHRcdFx0Ly8gQ2FjaGUgcmVzcG9uc2UgaGVhZGVyc1xuXHRcdFx0cmVzcG9uc2VIZWFkZXJzU3RyaW5nID0gaGVhZGVycyB8fCBcIlwiO1xuXG5cdFx0XHQvLyBTZXQgcmVhZHlTdGF0ZVxuXHRcdFx0anFYSFIucmVhZHlTdGF0ZSA9IHN0YXR1cyA+IDAgPyA0IDogMDtcblxuXHRcdFx0Ly8gRGV0ZXJtaW5lIGlmIHN1Y2Nlc3NmdWxcblx0XHRcdGlzU3VjY2VzcyA9IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwIHx8IHN0YXR1cyA9PT0gMzA0O1xuXG5cdFx0XHQvLyBHZXQgcmVzcG9uc2UgZGF0YVxuXHRcdFx0aWYgKCByZXNwb25zZXMgKSB7XG5cdFx0XHRcdHJlc3BvbnNlID0gYWpheEhhbmRsZVJlc3BvbnNlcyggcywganFYSFIsIHJlc3BvbnNlcyApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBDb252ZXJ0IG5vIG1hdHRlciB3aGF0ICh0aGF0IHdheSByZXNwb25zZVhYWCBmaWVsZHMgYXJlIGFsd2F5cyBzZXQpXG5cdFx0XHRyZXNwb25zZSA9IGFqYXhDb252ZXJ0KCBzLCByZXNwb25zZSwganFYSFIsIGlzU3VjY2VzcyApO1xuXG5cdFx0XHQvLyBJZiBzdWNjZXNzZnVsLCBoYW5kbGUgdHlwZSBjaGFpbmluZ1xuXHRcdFx0aWYgKCBpc1N1Y2Nlc3MgKSB7XG5cblx0XHRcdFx0Ly8gU2V0IHRoZSBJZi1Nb2RpZmllZC1TaW5jZSBhbmQvb3IgSWYtTm9uZS1NYXRjaCBoZWFkZXIsIGlmIGluIGlmTW9kaWZpZWQgbW9kZS5cblx0XHRcdFx0aWYgKCBzLmlmTW9kaWZpZWQgKSB7XG5cdFx0XHRcdFx0bW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlcihcIkxhc3QtTW9kaWZpZWRcIik7XG5cdFx0XHRcdFx0aWYgKCBtb2RpZmllZCApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5sYXN0TW9kaWZpZWRbIGNhY2hlVVJMIF0gPSBtb2RpZmllZDtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0bW9kaWZpZWQgPSBqcVhIUi5nZXRSZXNwb25zZUhlYWRlcihcImV0YWdcIik7XG5cdFx0XHRcdFx0aWYgKCBtb2RpZmllZCApIHtcblx0XHRcdFx0XHRcdGpRdWVyeS5ldGFnWyBjYWNoZVVSTCBdID0gbW9kaWZpZWQ7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gaWYgbm8gY29udGVudFxuXHRcdFx0XHRpZiAoIHN0YXR1cyA9PT0gMjA0IHx8IHMudHlwZSA9PT0gXCJIRUFEXCIgKSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IFwibm9jb250ZW50XCI7XG5cblx0XHRcdFx0Ly8gaWYgbm90IG1vZGlmaWVkXG5cdFx0XHRcdH0gZWxzZSBpZiAoIHN0YXR1cyA9PT0gMzA0ICkge1xuXHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcIm5vdG1vZGlmaWVkXCI7XG5cblx0XHRcdFx0Ly8gSWYgd2UgaGF2ZSBkYXRhLCBsZXQncyBjb252ZXJ0IGl0XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0c3RhdHVzVGV4dCA9IHJlc3BvbnNlLnN0YXRlO1xuXHRcdFx0XHRcdHN1Y2Nlc3MgPSByZXNwb25zZS5kYXRhO1xuXHRcdFx0XHRcdGVycm9yID0gcmVzcG9uc2UuZXJyb3I7XG5cdFx0XHRcdFx0aXNTdWNjZXNzID0gIWVycm9yO1xuXHRcdFx0XHR9XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBXZSBleHRyYWN0IGVycm9yIGZyb20gc3RhdHVzVGV4dFxuXHRcdFx0XHQvLyB0aGVuIG5vcm1hbGl6ZSBzdGF0dXNUZXh0IGFuZCBzdGF0dXMgZm9yIG5vbi1hYm9ydHNcblx0XHRcdFx0ZXJyb3IgPSBzdGF0dXNUZXh0O1xuXHRcdFx0XHRpZiAoIHN0YXR1cyB8fCAhc3RhdHVzVGV4dCApIHtcblx0XHRcdFx0XHRzdGF0dXNUZXh0ID0gXCJlcnJvclwiO1xuXHRcdFx0XHRcdGlmICggc3RhdHVzIDwgMCApIHtcblx0XHRcdFx0XHRcdHN0YXR1cyA9IDA7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cblx0XHRcdC8vIFNldCBkYXRhIGZvciB0aGUgZmFrZSB4aHIgb2JqZWN0XG5cdFx0XHRqcVhIUi5zdGF0dXMgPSBzdGF0dXM7XG5cdFx0XHRqcVhIUi5zdGF0dXNUZXh0ID0gKCBuYXRpdmVTdGF0dXNUZXh0IHx8IHN0YXR1c1RleHQgKSArIFwiXCI7XG5cblx0XHRcdC8vIFN1Y2Nlc3MvRXJyb3Jcblx0XHRcdGlmICggaXNTdWNjZXNzICkge1xuXHRcdFx0XHRkZWZlcnJlZC5yZXNvbHZlV2l0aCggY2FsbGJhY2tDb250ZXh0LCBbIHN1Y2Nlc3MsIHN0YXR1c1RleHQsIGpxWEhSIF0gKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGRlZmVycmVkLnJlamVjdFdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCwgZXJyb3IgXSApO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBTdGF0dXMtZGVwZW5kZW50IGNhbGxiYWNrc1xuXHRcdFx0anFYSFIuc3RhdHVzQ29kZSggc3RhdHVzQ29kZSApO1xuXHRcdFx0c3RhdHVzQ29kZSA9IHVuZGVmaW5lZDtcblxuXHRcdFx0aWYgKCBmaXJlR2xvYmFscyApIHtcblx0XHRcdFx0Z2xvYmFsRXZlbnRDb250ZXh0LnRyaWdnZXIoIGlzU3VjY2VzcyA/IFwiYWpheFN1Y2Nlc3NcIiA6IFwiYWpheEVycm9yXCIsXG5cdFx0XHRcdFx0WyBqcVhIUiwgcywgaXNTdWNjZXNzID8gc3VjY2VzcyA6IGVycm9yIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0Ly8gQ29tcGxldGVcblx0XHRcdGNvbXBsZXRlRGVmZXJyZWQuZmlyZVdpdGgoIGNhbGxiYWNrQ29udGV4dCwgWyBqcVhIUiwgc3RhdHVzVGV4dCBdICk7XG5cblx0XHRcdGlmICggZmlyZUdsb2JhbHMgKSB7XG5cdFx0XHRcdGdsb2JhbEV2ZW50Q29udGV4dC50cmlnZ2VyKCBcImFqYXhDb21wbGV0ZVwiLCBbIGpxWEhSLCBzIF0gKTtcblx0XHRcdFx0Ly8gSGFuZGxlIHRoZSBnbG9iYWwgQUpBWCBjb3VudGVyXG5cdFx0XHRcdGlmICggISggLS1qUXVlcnkuYWN0aXZlICkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5LmV2ZW50LnRyaWdnZXIoXCJhamF4U3RvcFwiKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHJldHVybiBqcVhIUjtcblx0fSxcblxuXHRnZXRKU09OOiBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjayApIHtcblx0XHRyZXR1cm4galF1ZXJ5LmdldCggdXJsLCBkYXRhLCBjYWxsYmFjaywgXCJqc29uXCIgKTtcblx0fSxcblxuXHRnZXRTY3JpcHQ6IGZ1bmN0aW9uKCB1cmwsIGNhbGxiYWNrICkge1xuXHRcdHJldHVybiBqUXVlcnkuZ2V0KCB1cmwsIHVuZGVmaW5lZCwgY2FsbGJhY2ssIFwic2NyaXB0XCIgKTtcblx0fVxufSk7XG5cbmpRdWVyeS5lYWNoKCBbIFwiZ2V0XCIsIFwicG9zdFwiIF0sIGZ1bmN0aW9uKCBpLCBtZXRob2QgKSB7XG5cdGpRdWVyeVsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdXJsLCBkYXRhLCBjYWxsYmFjaywgdHlwZSApIHtcblx0XHQvLyBzaGlmdCBhcmd1bWVudHMgaWYgZGF0YSBhcmd1bWVudCB3YXMgb21pdHRlZFxuXHRcdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIGRhdGEgKSApIHtcblx0XHRcdHR5cGUgPSB0eXBlIHx8IGNhbGxiYWNrO1xuXHRcdFx0Y2FsbGJhY2sgPSBkYXRhO1xuXHRcdFx0ZGF0YSA9IHVuZGVmaW5lZDtcblx0XHR9XG5cblx0XHRyZXR1cm4galF1ZXJ5LmFqYXgoe1xuXHRcdFx0dXJsOiB1cmwsXG5cdFx0XHR0eXBlOiBtZXRob2QsXG5cdFx0XHRkYXRhVHlwZTogdHlwZSxcblx0XHRcdGRhdGE6IGRhdGEsXG5cdFx0XHRzdWNjZXNzOiBjYWxsYmFja1xuXHRcdH0pO1xuXHR9O1xufSk7XG5cblxualF1ZXJ5Ll9ldmFsVXJsID0gZnVuY3Rpb24oIHVybCApIHtcblx0cmV0dXJuIGpRdWVyeS5hamF4KHtcblx0XHR1cmw6IHVybCxcblx0XHR0eXBlOiBcIkdFVFwiLFxuXHRcdGRhdGFUeXBlOiBcInNjcmlwdFwiLFxuXHRcdGFzeW5jOiBmYWxzZSxcblx0XHRnbG9iYWw6IGZhbHNlLFxuXHRcdFwidGhyb3dzXCI6IHRydWVcblx0fSk7XG59O1xuXG5cbmpRdWVyeS5mbi5leHRlbmQoe1xuXHR3cmFwQWxsOiBmdW5jdGlvbiggaHRtbCApIHtcblx0XHRpZiAoIGpRdWVyeS5pc0Z1bmN0aW9uKCBodG1sICkgKSB7XG5cdFx0XHRyZXR1cm4gdGhpcy5lYWNoKGZ1bmN0aW9uKGkpIHtcblx0XHRcdFx0alF1ZXJ5KHRoaXMpLndyYXBBbGwoIGh0bWwuY2FsbCh0aGlzLCBpKSApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0aWYgKCB0aGlzWzBdICkge1xuXHRcdFx0Ly8gVGhlIGVsZW1lbnRzIHRvIHdyYXAgdGhlIHRhcmdldCBhcm91bmRcblx0XHRcdHZhciB3cmFwID0galF1ZXJ5KCBodG1sLCB0aGlzWzBdLm93bmVyRG9jdW1lbnQgKS5lcSgwKS5jbG9uZSh0cnVlKTtcblxuXHRcdFx0aWYgKCB0aGlzWzBdLnBhcmVudE5vZGUgKSB7XG5cdFx0XHRcdHdyYXAuaW5zZXJ0QmVmb3JlKCB0aGlzWzBdICk7XG5cdFx0XHR9XG5cblx0XHRcdHdyYXAubWFwKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHR2YXIgZWxlbSA9IHRoaXM7XG5cblx0XHRcdFx0d2hpbGUgKCBlbGVtLmZpcnN0Q2hpbGQgJiYgZWxlbS5maXJzdENoaWxkLm5vZGVUeXBlID09PSAxICkge1xuXHRcdFx0XHRcdGVsZW0gPSBlbGVtLmZpcnN0Q2hpbGQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gZWxlbTtcblx0XHRcdH0pLmFwcGVuZCggdGhpcyApO1xuXHRcdH1cblxuXHRcdHJldHVybiB0aGlzO1xuXHR9LFxuXG5cdHdyYXBJbm5lcjogZnVuY3Rpb24oIGh0bWwgKSB7XG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggaHRtbCApICkge1xuXHRcdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbihpKSB7XG5cdFx0XHRcdGpRdWVyeSh0aGlzKS53cmFwSW5uZXIoIGh0bWwuY2FsbCh0aGlzLCBpKSApO1xuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZWFjaChmdW5jdGlvbigpIHtcblx0XHRcdHZhciBzZWxmID0galF1ZXJ5KCB0aGlzICksXG5cdFx0XHRcdGNvbnRlbnRzID0gc2VsZi5jb250ZW50cygpO1xuXG5cdFx0XHRpZiAoIGNvbnRlbnRzLmxlbmd0aCApIHtcblx0XHRcdFx0Y29udGVudHMud3JhcEFsbCggaHRtbCApO1xuXG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRzZWxmLmFwcGVuZCggaHRtbCApO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9LFxuXG5cdHdyYXA6IGZ1bmN0aW9uKCBodG1sICkge1xuXHRcdHZhciBpc0Z1bmN0aW9uID0galF1ZXJ5LmlzRnVuY3Rpb24oIGh0bWwgKTtcblxuXHRcdHJldHVybiB0aGlzLmVhY2goZnVuY3Rpb24oaSkge1xuXHRcdFx0alF1ZXJ5KCB0aGlzICkud3JhcEFsbCggaXNGdW5jdGlvbiA/IGh0bWwuY2FsbCh0aGlzLCBpKSA6IGh0bWwgKTtcblx0XHR9KTtcblx0fSxcblxuXHR1bndyYXA6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLnBhcmVudCgpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoICFqUXVlcnkubm9kZU5hbWUoIHRoaXMsIFwiYm9keVwiICkgKSB7XG5cdFx0XHRcdGpRdWVyeSggdGhpcyApLnJlcGxhY2VXaXRoKCB0aGlzLmNoaWxkTm9kZXMgKTtcblx0XHRcdH1cblx0XHR9KS5lbmQoKTtcblx0fVxufSk7XG5cblxualF1ZXJ5LmV4cHIuZmlsdGVycy5oaWRkZW4gPSBmdW5jdGlvbiggZWxlbSApIHtcblx0Ly8gU3VwcG9ydDogT3BlcmEgPD0gMTIuMTJcblx0Ly8gT3BlcmEgcmVwb3J0cyBvZmZzZXRXaWR0aHMgYW5kIG9mZnNldEhlaWdodHMgbGVzcyB0aGFuIHplcm8gb24gc29tZSBlbGVtZW50c1xuXHRyZXR1cm4gZWxlbS5vZmZzZXRXaWR0aCA8PSAwICYmIGVsZW0ub2Zmc2V0SGVpZ2h0IDw9IDAgfHxcblx0XHQoIXN1cHBvcnQucmVsaWFibGVIaWRkZW5PZmZzZXRzKCkgJiZcblx0XHRcdCgoZWxlbS5zdHlsZSAmJiBlbGVtLnN0eWxlLmRpc3BsYXkpIHx8IGpRdWVyeS5jc3MoIGVsZW0sIFwiZGlzcGxheVwiICkpID09PSBcIm5vbmVcIik7XG59O1xuXG5qUXVlcnkuZXhwci5maWx0ZXJzLnZpc2libGUgPSBmdW5jdGlvbiggZWxlbSApIHtcblx0cmV0dXJuICFqUXVlcnkuZXhwci5maWx0ZXJzLmhpZGRlbiggZWxlbSApO1xufTtcblxuXG5cblxudmFyIHIyMCA9IC8lMjAvZyxcblx0cmJyYWNrZXQgPSAvXFxbXFxdJC8sXG5cdHJDUkxGID0gL1xccj9cXG4vZyxcblx0cnN1Ym1pdHRlclR5cGVzID0gL14oPzpzdWJtaXR8YnV0dG9ufGltYWdlfHJlc2V0fGZpbGUpJC9pLFxuXHRyc3VibWl0dGFibGUgPSAvXig/OmlucHV0fHNlbGVjdHx0ZXh0YXJlYXxrZXlnZW4pL2k7XG5cbmZ1bmN0aW9uIGJ1aWxkUGFyYW1zKCBwcmVmaXgsIG9iaiwgdHJhZGl0aW9uYWwsIGFkZCApIHtcblx0dmFyIG5hbWU7XG5cblx0aWYgKCBqUXVlcnkuaXNBcnJheSggb2JqICkgKSB7XG5cdFx0Ly8gU2VyaWFsaXplIGFycmF5IGl0ZW0uXG5cdFx0alF1ZXJ5LmVhY2goIG9iaiwgZnVuY3Rpb24oIGksIHYgKSB7XG5cdFx0XHRpZiAoIHRyYWRpdGlvbmFsIHx8IHJicmFja2V0LnRlc3QoIHByZWZpeCApICkge1xuXHRcdFx0XHQvLyBUcmVhdCBlYWNoIGFycmF5IGl0ZW0gYXMgYSBzY2FsYXIuXG5cdFx0XHRcdGFkZCggcHJlZml4LCB2ICk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vIEl0ZW0gaXMgbm9uLXNjYWxhciAoYXJyYXkgb3Igb2JqZWN0KSwgZW5jb2RlIGl0cyBudW1lcmljIGluZGV4LlxuXHRcdFx0XHRidWlsZFBhcmFtcyggcHJlZml4ICsgXCJbXCIgKyAoIHR5cGVvZiB2ID09PSBcIm9iamVjdFwiID8gaSA6IFwiXCIgKSArIFwiXVwiLCB2LCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cblx0fSBlbHNlIGlmICggIXRyYWRpdGlvbmFsICYmIGpRdWVyeS50eXBlKCBvYmogKSA9PT0gXCJvYmplY3RcIiApIHtcblx0XHQvLyBTZXJpYWxpemUgb2JqZWN0IGl0ZW0uXG5cdFx0Zm9yICggbmFtZSBpbiBvYmogKSB7XG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4ICsgXCJbXCIgKyBuYW1lICsgXCJdXCIsIG9ialsgbmFtZSBdLCB0cmFkaXRpb25hbCwgYWRkICk7XG5cdFx0fVxuXG5cdH0gZWxzZSB7XG5cdFx0Ly8gU2VyaWFsaXplIHNjYWxhciBpdGVtLlxuXHRcdGFkZCggcHJlZml4LCBvYmogKTtcblx0fVxufVxuXG4vLyBTZXJpYWxpemUgYW4gYXJyYXkgb2YgZm9ybSBlbGVtZW50cyBvciBhIHNldCBvZlxuLy8ga2V5L3ZhbHVlcyBpbnRvIGEgcXVlcnkgc3RyaW5nXG5qUXVlcnkucGFyYW0gPSBmdW5jdGlvbiggYSwgdHJhZGl0aW9uYWwgKSB7XG5cdHZhciBwcmVmaXgsXG5cdFx0cyA9IFtdLFxuXHRcdGFkZCA9IGZ1bmN0aW9uKCBrZXksIHZhbHVlICkge1xuXHRcdFx0Ly8gSWYgdmFsdWUgaXMgYSBmdW5jdGlvbiwgaW52b2tlIGl0IGFuZCByZXR1cm4gaXRzIHZhbHVlXG5cdFx0XHR2YWx1ZSA9IGpRdWVyeS5pc0Z1bmN0aW9uKCB2YWx1ZSApID8gdmFsdWUoKSA6ICggdmFsdWUgPT0gbnVsbCA/IFwiXCIgOiB2YWx1ZSApO1xuXHRcdFx0c1sgcy5sZW5ndGggXSA9IGVuY29kZVVSSUNvbXBvbmVudCgga2V5ICkgKyBcIj1cIiArIGVuY29kZVVSSUNvbXBvbmVudCggdmFsdWUgKTtcblx0XHR9O1xuXG5cdC8vIFNldCB0cmFkaXRpb25hbCB0byB0cnVlIGZvciBqUXVlcnkgPD0gMS4zLjIgYmVoYXZpb3IuXG5cdGlmICggdHJhZGl0aW9uYWwgPT09IHVuZGVmaW5lZCApIHtcblx0XHR0cmFkaXRpb25hbCA9IGpRdWVyeS5hamF4U2V0dGluZ3MgJiYgalF1ZXJ5LmFqYXhTZXR0aW5ncy50cmFkaXRpb25hbDtcblx0fVxuXG5cdC8vIElmIGFuIGFycmF5IHdhcyBwYXNzZWQgaW4sIGFzc3VtZSB0aGF0IGl0IGlzIGFuIGFycmF5IG9mIGZvcm0gZWxlbWVudHMuXG5cdGlmICggalF1ZXJ5LmlzQXJyYXkoIGEgKSB8fCAoIGEuanF1ZXJ5ICYmICFqUXVlcnkuaXNQbGFpbk9iamVjdCggYSApICkgKSB7XG5cdFx0Ly8gU2VyaWFsaXplIHRoZSBmb3JtIGVsZW1lbnRzXG5cdFx0alF1ZXJ5LmVhY2goIGEsIGZ1bmN0aW9uKCkge1xuXHRcdFx0YWRkKCB0aGlzLm5hbWUsIHRoaXMudmFsdWUgKTtcblx0XHR9KTtcblxuXHR9IGVsc2Uge1xuXHRcdC8vIElmIHRyYWRpdGlvbmFsLCBlbmNvZGUgdGhlIFwib2xkXCIgd2F5ICh0aGUgd2F5IDEuMy4yIG9yIG9sZGVyXG5cdFx0Ly8gZGlkIGl0KSwgb3RoZXJ3aXNlIGVuY29kZSBwYXJhbXMgcmVjdXJzaXZlbHkuXG5cdFx0Zm9yICggcHJlZml4IGluIGEgKSB7XG5cdFx0XHRidWlsZFBhcmFtcyggcHJlZml4LCBhWyBwcmVmaXggXSwgdHJhZGl0aW9uYWwsIGFkZCApO1xuXHRcdH1cblx0fVxuXG5cdC8vIFJldHVybiB0aGUgcmVzdWx0aW5nIHNlcmlhbGl6YXRpb25cblx0cmV0dXJuIHMuam9pbiggXCImXCIgKS5yZXBsYWNlKCByMjAsIFwiK1wiICk7XG59O1xuXG5qUXVlcnkuZm4uZXh0ZW5kKHtcblx0c2VyaWFsaXplOiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4galF1ZXJ5LnBhcmFtKCB0aGlzLnNlcmlhbGl6ZUFycmF5KCkgKTtcblx0fSxcblx0c2VyaWFsaXplQXJyYXk6IGZ1bmN0aW9uKCkge1xuXHRcdHJldHVybiB0aGlzLm1hcChmdW5jdGlvbigpIHtcblx0XHRcdC8vIENhbiBhZGQgcHJvcEhvb2sgZm9yIFwiZWxlbWVudHNcIiB0byBmaWx0ZXIgb3IgYWRkIGZvcm0gZWxlbWVudHNcblx0XHRcdHZhciBlbGVtZW50cyA9IGpRdWVyeS5wcm9wKCB0aGlzLCBcImVsZW1lbnRzXCIgKTtcblx0XHRcdHJldHVybiBlbGVtZW50cyA/IGpRdWVyeS5tYWtlQXJyYXkoIGVsZW1lbnRzICkgOiB0aGlzO1xuXHRcdH0pXG5cdFx0LmZpbHRlcihmdW5jdGlvbigpIHtcblx0XHRcdHZhciB0eXBlID0gdGhpcy50eXBlO1xuXHRcdFx0Ly8gVXNlIC5pcyhcIjpkaXNhYmxlZFwiKSBzbyB0aGF0IGZpZWxkc2V0W2Rpc2FibGVkXSB3b3Jrc1xuXHRcdFx0cmV0dXJuIHRoaXMubmFtZSAmJiAhalF1ZXJ5KCB0aGlzICkuaXMoIFwiOmRpc2FibGVkXCIgKSAmJlxuXHRcdFx0XHRyc3VibWl0dGFibGUudGVzdCggdGhpcy5ub2RlTmFtZSApICYmICFyc3VibWl0dGVyVHlwZXMudGVzdCggdHlwZSApICYmXG5cdFx0XHRcdCggdGhpcy5jaGVja2VkIHx8ICFyY2hlY2thYmxlVHlwZS50ZXN0KCB0eXBlICkgKTtcblx0XHR9KVxuXHRcdC5tYXAoZnVuY3Rpb24oIGksIGVsZW0gKSB7XG5cdFx0XHR2YXIgdmFsID0galF1ZXJ5KCB0aGlzICkudmFsKCk7XG5cblx0XHRcdHJldHVybiB2YWwgPT0gbnVsbCA/XG5cdFx0XHRcdG51bGwgOlxuXHRcdFx0XHRqUXVlcnkuaXNBcnJheSggdmFsICkgP1xuXHRcdFx0XHRcdGpRdWVyeS5tYXAoIHZhbCwgZnVuY3Rpb24oIHZhbCApIHtcblx0XHRcdFx0XHRcdHJldHVybiB7IG5hbWU6IGVsZW0ubmFtZSwgdmFsdWU6IHZhbC5yZXBsYWNlKCByQ1JMRiwgXCJcXHJcXG5cIiApIH07XG5cdFx0XHRcdFx0fSkgOlxuXHRcdFx0XHRcdHsgbmFtZTogZWxlbS5uYW1lLCB2YWx1ZTogdmFsLnJlcGxhY2UoIHJDUkxGLCBcIlxcclxcblwiICkgfTtcblx0XHR9KS5nZXQoKTtcblx0fVxufSk7XG5cblxuLy8gQ3JlYXRlIHRoZSByZXF1ZXN0IG9iamVjdFxuLy8gKFRoaXMgaXMgc3RpbGwgYXR0YWNoZWQgdG8gYWpheFNldHRpbmdzIGZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5KVxualF1ZXJ5LmFqYXhTZXR0aW5ncy54aHIgPSB3aW5kb3cuQWN0aXZlWE9iamVjdCAhPT0gdW5kZWZpbmVkID9cblx0Ly8gU3VwcG9ydDogSUU2K1xuXHRmdW5jdGlvbigpIHtcblxuXHRcdC8vIFhIUiBjYW5ub3QgYWNjZXNzIGxvY2FsIGZpbGVzLCBhbHdheXMgdXNlIEFjdGl2ZVggZm9yIHRoYXQgY2FzZVxuXHRcdHJldHVybiAhdGhpcy5pc0xvY2FsICYmXG5cblx0XHRcdC8vIFN1cHBvcnQ6IElFNy04XG5cdFx0XHQvLyBvbGRJRSBYSFIgZG9lcyBub3Qgc3VwcG9ydCBub24tUkZDMjYxNiBtZXRob2RzICgjMTMyNDApXG5cdFx0XHQvLyBTZWUgaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2llL21zNTM2NjQ4KHY9dnMuODUpLmFzcHhcblx0XHRcdC8vIGFuZCBodHRwOi8vd3d3LnczLm9yZy9Qcm90b2NvbHMvcmZjMjYxNi9yZmMyNjE2LXNlYzkuaHRtbCNzZWM5XG5cdFx0XHQvLyBBbHRob3VnaCB0aGlzIGNoZWNrIGZvciBzaXggbWV0aG9kcyBpbnN0ZWFkIG9mIGVpZ2h0XG5cdFx0XHQvLyBzaW5jZSBJRSBhbHNvIGRvZXMgbm90IHN1cHBvcnQgXCJ0cmFjZVwiIGFuZCBcImNvbm5lY3RcIlxuXHRcdFx0L14oZ2V0fHBvc3R8aGVhZHxwdXR8ZGVsZXRlfG9wdGlvbnMpJC9pLnRlc3QoIHRoaXMudHlwZSApICYmXG5cblx0XHRcdGNyZWF0ZVN0YW5kYXJkWEhSKCkgfHwgY3JlYXRlQWN0aXZlWEhSKCk7XG5cdH0gOlxuXHQvLyBGb3IgYWxsIG90aGVyIGJyb3dzZXJzLCB1c2UgdGhlIHN0YW5kYXJkIFhNTEh0dHBSZXF1ZXN0IG9iamVjdFxuXHRjcmVhdGVTdGFuZGFyZFhIUjtcblxudmFyIHhocklkID0gMCxcblx0eGhyQ2FsbGJhY2tzID0ge30sXG5cdHhoclN1cHBvcnRlZCA9IGpRdWVyeS5hamF4U2V0dGluZ3MueGhyKCk7XG5cbi8vIFN1cHBvcnQ6IElFPDEwXG4vLyBPcGVuIHJlcXVlc3RzIG11c3QgYmUgbWFudWFsbHkgYWJvcnRlZCBvbiB1bmxvYWQgKCM1MjgwKVxuLy8gU2VlIGh0dHBzOi8vc3VwcG9ydC5taWNyb3NvZnQuY29tL2tiLzI4NTY3NDYgZm9yIG1vcmUgaW5mb1xuaWYgKCB3aW5kb3cuYXR0YWNoRXZlbnQgKSB7XG5cdHdpbmRvdy5hdHRhY2hFdmVudCggXCJvbnVubG9hZFwiLCBmdW5jdGlvbigpIHtcblx0XHRmb3IgKCB2YXIga2V5IGluIHhockNhbGxiYWNrcyApIHtcblx0XHRcdHhockNhbGxiYWNrc1sga2V5IF0oIHVuZGVmaW5lZCwgdHJ1ZSApO1xuXHRcdH1cblx0fSk7XG59XG5cbi8vIERldGVybWluZSBzdXBwb3J0IHByb3BlcnRpZXNcbnN1cHBvcnQuY29ycyA9ICEheGhyU3VwcG9ydGVkICYmICggXCJ3aXRoQ3JlZGVudGlhbHNcIiBpbiB4aHJTdXBwb3J0ZWQgKTtcbnhoclN1cHBvcnRlZCA9IHN1cHBvcnQuYWpheCA9ICEheGhyU3VwcG9ydGVkO1xuXG4vLyBDcmVhdGUgdHJhbnNwb3J0IGlmIHRoZSBicm93c2VyIGNhbiBwcm92aWRlIGFuIHhoclxuaWYgKCB4aHJTdXBwb3J0ZWQgKSB7XG5cblx0alF1ZXJ5LmFqYXhUcmFuc3BvcnQoZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdFx0Ly8gQ3Jvc3MgZG9tYWluIG9ubHkgYWxsb3dlZCBpZiBzdXBwb3J0ZWQgdGhyb3VnaCBYTUxIdHRwUmVxdWVzdFxuXHRcdGlmICggIW9wdGlvbnMuY3Jvc3NEb21haW4gfHwgc3VwcG9ydC5jb3JzICkge1xuXG5cdFx0XHR2YXIgY2FsbGJhY2s7XG5cblx0XHRcdHJldHVybiB7XG5cdFx0XHRcdHNlbmQ6IGZ1bmN0aW9uKCBoZWFkZXJzLCBjb21wbGV0ZSApIHtcblx0XHRcdFx0XHR2YXIgaSxcblx0XHRcdFx0XHRcdHhociA9IG9wdGlvbnMueGhyKCksXG5cdFx0XHRcdFx0XHRpZCA9ICsreGhySWQ7XG5cblx0XHRcdFx0XHQvLyBPcGVuIHRoZSBzb2NrZXRcblx0XHRcdFx0XHR4aHIub3Blbiggb3B0aW9ucy50eXBlLCBvcHRpb25zLnVybCwgb3B0aW9ucy5hc3luYywgb3B0aW9ucy51c2VybmFtZSwgb3B0aW9ucy5wYXNzd29yZCApO1xuXG5cdFx0XHRcdFx0Ly8gQXBwbHkgY3VzdG9tIGZpZWxkcyBpZiBwcm92aWRlZFxuXHRcdFx0XHRcdGlmICggb3B0aW9ucy54aHJGaWVsZHMgKSB7XG5cdFx0XHRcdFx0XHRmb3IgKCBpIGluIG9wdGlvbnMueGhyRmllbGRzICkge1xuXHRcdFx0XHRcdFx0XHR4aHJbIGkgXSA9IG9wdGlvbnMueGhyRmllbGRzWyBpIF07XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gT3ZlcnJpZGUgbWltZSB0eXBlIGlmIG5lZWRlZFxuXHRcdFx0XHRcdGlmICggb3B0aW9ucy5taW1lVHlwZSAmJiB4aHIub3ZlcnJpZGVNaW1lVHlwZSApIHtcblx0XHRcdFx0XHRcdHhoci5vdmVycmlkZU1pbWVUeXBlKCBvcHRpb25zLm1pbWVUeXBlICk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gWC1SZXF1ZXN0ZWQtV2l0aCBoZWFkZXJcblx0XHRcdFx0XHQvLyBGb3IgY3Jvc3MtZG9tYWluIHJlcXVlc3RzLCBzZWVpbmcgYXMgY29uZGl0aW9ucyBmb3IgYSBwcmVmbGlnaHQgYXJlXG5cdFx0XHRcdFx0Ly8gYWtpbiB0byBhIGppZ3NhdyBwdXp6bGUsIHdlIHNpbXBseSBuZXZlciBzZXQgaXQgdG8gYmUgc3VyZS5cblx0XHRcdFx0XHQvLyAoaXQgY2FuIGFsd2F5cyBiZSBzZXQgb24gYSBwZXItcmVxdWVzdCBiYXNpcyBvciBldmVuIHVzaW5nIGFqYXhTZXR1cClcblx0XHRcdFx0XHQvLyBGb3Igc2FtZS1kb21haW4gcmVxdWVzdHMsIHdvbid0IGNoYW5nZSBoZWFkZXIgaWYgYWxyZWFkeSBwcm92aWRlZC5cblx0XHRcdFx0XHRpZiAoICFvcHRpb25zLmNyb3NzRG9tYWluICYmICFoZWFkZXJzW1wiWC1SZXF1ZXN0ZWQtV2l0aFwiXSApIHtcblx0XHRcdFx0XHRcdGhlYWRlcnNbXCJYLVJlcXVlc3RlZC1XaXRoXCJdID0gXCJYTUxIdHRwUmVxdWVzdFwiO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdC8vIFNldCBoZWFkZXJzXG5cdFx0XHRcdFx0Zm9yICggaSBpbiBoZWFkZXJzICkge1xuXHRcdFx0XHRcdFx0Ly8gU3VwcG9ydDogSUU8OVxuXHRcdFx0XHRcdFx0Ly8gSUUncyBBY3RpdmVYT2JqZWN0IHRocm93cyBhICdUeXBlIE1pc21hdGNoJyBleGNlcHRpb24gd2hlbiBzZXR0aW5nXG5cdFx0XHRcdFx0XHQvLyByZXF1ZXN0IGhlYWRlciB0byBhIG51bGwtdmFsdWUuXG5cdFx0XHRcdFx0XHQvL1xuXHRcdFx0XHRcdFx0Ly8gVG8ga2VlcCBjb25zaXN0ZW50IHdpdGggb3RoZXIgWEhSIGltcGxlbWVudGF0aW9ucywgY2FzdCB0aGUgdmFsdWVcblx0XHRcdFx0XHRcdC8vIHRvIHN0cmluZyBhbmQgaWdub3JlIGB1bmRlZmluZWRgLlxuXHRcdFx0XHRcdFx0aWYgKCBoZWFkZXJzWyBpIF0gIT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0XHRcdFx0eGhyLnNldFJlcXVlc3RIZWFkZXIoIGksIGhlYWRlcnNbIGkgXSArIFwiXCIgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBEbyBzZW5kIHRoZSByZXF1ZXN0XG5cdFx0XHRcdFx0Ly8gVGhpcyBtYXkgcmFpc2UgYW4gZXhjZXB0aW9uIHdoaWNoIGlzIGFjdHVhbGx5XG5cdFx0XHRcdFx0Ly8gaGFuZGxlZCBpbiBqUXVlcnkuYWpheCAoc28gbm8gdHJ5L2NhdGNoIGhlcmUpXG5cdFx0XHRcdFx0eGhyLnNlbmQoICggb3B0aW9ucy5oYXNDb250ZW50ICYmIG9wdGlvbnMuZGF0YSApIHx8IG51bGwgKTtcblxuXHRcdFx0XHRcdC8vIExpc3RlbmVyXG5cdFx0XHRcdFx0Y2FsbGJhY2sgPSBmdW5jdGlvbiggXywgaXNBYm9ydCApIHtcblx0XHRcdFx0XHRcdHZhciBzdGF0dXMsIHN0YXR1c1RleHQsIHJlc3BvbnNlcztcblxuXHRcdFx0XHRcdFx0Ly8gV2FzIG5ldmVyIGNhbGxlZCBhbmQgaXMgYWJvcnRlZCBvciBjb21wbGV0ZVxuXHRcdFx0XHRcdFx0aWYgKCBjYWxsYmFjayAmJiAoIGlzQWJvcnQgfHwgeGhyLnJlYWR5U3RhdGUgPT09IDQgKSApIHtcblx0XHRcdFx0XHRcdFx0Ly8gQ2xlYW4gdXBcblx0XHRcdFx0XHRcdFx0ZGVsZXRlIHhockNhbGxiYWNrc1sgaWQgXTtcblx0XHRcdFx0XHRcdFx0Y2FsbGJhY2sgPSB1bmRlZmluZWQ7XG5cdFx0XHRcdFx0XHRcdHhoci5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBqUXVlcnkubm9vcDtcblxuXHRcdFx0XHRcdFx0XHQvLyBBYm9ydCBtYW51YWxseSBpZiBuZWVkZWRcblx0XHRcdFx0XHRcdFx0aWYgKCBpc0Fib3J0ICkge1xuXHRcdFx0XHRcdFx0XHRcdGlmICggeGhyLnJlYWR5U3RhdGUgIT09IDQgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHR4aHIuYWJvcnQoKTtcblx0XHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzcG9uc2VzID0ge307XG5cdFx0XHRcdFx0XHRcdFx0c3RhdHVzID0geGhyLnN0YXR1cztcblxuXHRcdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQ6IElFPDEwXG5cdFx0XHRcdFx0XHRcdFx0Ly8gQWNjZXNzaW5nIGJpbmFyeS1kYXRhIHJlc3BvbnNlVGV4dCB0aHJvd3MgYW4gZXhjZXB0aW9uXG5cdFx0XHRcdFx0XHRcdFx0Ly8gKCMxMTQyNilcblx0XHRcdFx0XHRcdFx0XHRpZiAoIHR5cGVvZiB4aHIucmVzcG9uc2VUZXh0ID09PSBcInN0cmluZ1wiICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0cmVzcG9uc2VzLnRleHQgPSB4aHIucmVzcG9uc2VUZXh0O1xuXHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdC8vIEZpcmVmb3ggdGhyb3dzIGFuIGV4Y2VwdGlvbiB3aGVuIGFjY2Vzc2luZ1xuXHRcdFx0XHRcdFx0XHRcdC8vIHN0YXR1c1RleHQgZm9yIGZhdWx0eSBjcm9zcy1kb21haW4gcmVxdWVzdHNcblx0XHRcdFx0XHRcdFx0XHR0cnkge1xuXHRcdFx0XHRcdFx0XHRcdFx0c3RhdHVzVGV4dCA9IHhoci5zdGF0dXNUZXh0O1xuXHRcdFx0XHRcdFx0XHRcdH0gY2F0Y2goIGUgKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQvLyBXZSBub3JtYWxpemUgd2l0aCBXZWJraXQgZ2l2aW5nIGFuIGVtcHR5IHN0YXR1c1RleHRcblx0XHRcdFx0XHRcdFx0XHRcdHN0YXR1c1RleHQgPSBcIlwiO1xuXHRcdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRcdC8vIEZpbHRlciBzdGF0dXMgZm9yIG5vbiBzdGFuZGFyZCBiZWhhdmlvcnNcblxuXHRcdFx0XHRcdFx0XHRcdC8vIElmIHRoZSByZXF1ZXN0IGlzIGxvY2FsIGFuZCB3ZSBoYXZlIGRhdGE6IGFzc3VtZSBhIHN1Y2Nlc3Ncblx0XHRcdFx0XHRcdFx0XHQvLyAoc3VjY2VzcyB3aXRoIG5vIGRhdGEgd29uJ3QgZ2V0IG5vdGlmaWVkLCB0aGF0J3MgdGhlIGJlc3Qgd2Vcblx0XHRcdFx0XHRcdFx0XHQvLyBjYW4gZG8gZ2l2ZW4gY3VycmVudCBpbXBsZW1lbnRhdGlvbnMpXG5cdFx0XHRcdFx0XHRcdFx0aWYgKCAhc3RhdHVzICYmIG9wdGlvbnMuaXNMb2NhbCAmJiAhb3B0aW9ucy5jcm9zc0RvbWFpbiApIHtcblx0XHRcdFx0XHRcdFx0XHRcdHN0YXR1cyA9IHJlc3BvbnNlcy50ZXh0ID8gMjAwIDogNDA0O1xuXHRcdFx0XHRcdFx0XHRcdC8vIElFIC0gIzE0NTA6IHNvbWV0aW1lcyByZXR1cm5zIDEyMjMgd2hlbiBpdCBzaG91bGQgYmUgMjA0XG5cdFx0XHRcdFx0XHRcdFx0fSBlbHNlIGlmICggc3RhdHVzID09PSAxMjIzICkge1xuXHRcdFx0XHRcdFx0XHRcdFx0c3RhdHVzID0gMjA0O1xuXHRcdFx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHQvLyBDYWxsIGNvbXBsZXRlIGlmIG5lZWRlZFxuXHRcdFx0XHRcdFx0aWYgKCByZXNwb25zZXMgKSB7XG5cdFx0XHRcdFx0XHRcdGNvbXBsZXRlKCBzdGF0dXMsIHN0YXR1c1RleHQsIHJlc3BvbnNlcywgeGhyLmdldEFsbFJlc3BvbnNlSGVhZGVycygpICk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fTtcblxuXHRcdFx0XHRcdGlmICggIW9wdGlvbnMuYXN5bmMgKSB7XG5cdFx0XHRcdFx0XHQvLyBpZiB3ZSdyZSBpbiBzeW5jIG1vZGUgd2UgZmlyZSB0aGUgY2FsbGJhY2tcblx0XHRcdFx0XHRcdGNhbGxiYWNrKCk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmICggeGhyLnJlYWR5U3RhdGUgPT09IDQgKSB7XG5cdFx0XHRcdFx0XHQvLyAoSUU2ICYgSUU3KSBpZiBpdCdzIGluIGNhY2hlIGFuZCBoYXMgYmVlblxuXHRcdFx0XHRcdFx0Ly8gcmV0cmlldmVkIGRpcmVjdGx5IHdlIG5lZWQgdG8gZmlyZSB0aGUgY2FsbGJhY2tcblx0XHRcdFx0XHRcdHNldFRpbWVvdXQoIGNhbGxiYWNrICk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIEFkZCB0byB0aGUgbGlzdCBvZiBhY3RpdmUgeGhyIGNhbGxiYWNrc1xuXHRcdFx0XHRcdFx0eGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IHhockNhbGxiYWNrc1sgaWQgXSA9IGNhbGxiYWNrO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSxcblxuXHRcdFx0XHRhYm9ydDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0aWYgKCBjYWxsYmFjayApIHtcblx0XHRcdFx0XHRcdGNhbGxiYWNrKCB1bmRlZmluZWQsIHRydWUgKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdH07XG5cdFx0fVxuXHR9KTtcbn1cblxuLy8gRnVuY3Rpb25zIHRvIGNyZWF0ZSB4aHJzXG5mdW5jdGlvbiBjcmVhdGVTdGFuZGFyZFhIUigpIHtcblx0dHJ5IHtcblx0XHRyZXR1cm4gbmV3IHdpbmRvdy5YTUxIdHRwUmVxdWVzdCgpO1xuXHR9IGNhdGNoKCBlICkge31cbn1cblxuZnVuY3Rpb24gY3JlYXRlQWN0aXZlWEhSKCkge1xuXHR0cnkge1xuXHRcdHJldHVybiBuZXcgd2luZG93LkFjdGl2ZVhPYmplY3QoIFwiTWljcm9zb2Z0LlhNTEhUVFBcIiApO1xuXHR9IGNhdGNoKCBlICkge31cbn1cblxuXG5cblxuLy8gSW5zdGFsbCBzY3JpcHQgZGF0YVR5cGVcbmpRdWVyeS5hamF4U2V0dXAoe1xuXHRhY2NlcHRzOiB7XG5cdFx0c2NyaXB0OiBcInRleHQvamF2YXNjcmlwdCwgYXBwbGljYXRpb24vamF2YXNjcmlwdCwgYXBwbGljYXRpb24vZWNtYXNjcmlwdCwgYXBwbGljYXRpb24veC1lY21hc2NyaXB0XCJcblx0fSxcblx0Y29udGVudHM6IHtcblx0XHRzY3JpcHQ6IC8oPzpqYXZhfGVjbWEpc2NyaXB0L1xuXHR9LFxuXHRjb252ZXJ0ZXJzOiB7XG5cdFx0XCJ0ZXh0IHNjcmlwdFwiOiBmdW5jdGlvbiggdGV4dCApIHtcblx0XHRcdGpRdWVyeS5nbG9iYWxFdmFsKCB0ZXh0ICk7XG5cdFx0XHRyZXR1cm4gdGV4dDtcblx0XHR9XG5cdH1cbn0pO1xuXG4vLyBIYW5kbGUgY2FjaGUncyBzcGVjaWFsIGNhc2UgYW5kIGdsb2JhbFxualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwic2NyaXB0XCIsIGZ1bmN0aW9uKCBzICkge1xuXHRpZiAoIHMuY2FjaGUgPT09IHVuZGVmaW5lZCApIHtcblx0XHRzLmNhY2hlID0gZmFsc2U7XG5cdH1cblx0aWYgKCBzLmNyb3NzRG9tYWluICkge1xuXHRcdHMudHlwZSA9IFwiR0VUXCI7XG5cdFx0cy5nbG9iYWwgPSBmYWxzZTtcblx0fVxufSk7XG5cbi8vIEJpbmQgc2NyaXB0IHRhZyBoYWNrIHRyYW5zcG9ydFxualF1ZXJ5LmFqYXhUcmFuc3BvcnQoIFwic2NyaXB0XCIsIGZ1bmN0aW9uKHMpIHtcblxuXHQvLyBUaGlzIHRyYW5zcG9ydCBvbmx5IGRlYWxzIHdpdGggY3Jvc3MgZG9tYWluIHJlcXVlc3RzXG5cdGlmICggcy5jcm9zc0RvbWFpbiApIHtcblxuXHRcdHZhciBzY3JpcHQsXG5cdFx0XHRoZWFkID0gZG9jdW1lbnQuaGVhZCB8fCBqUXVlcnkoXCJoZWFkXCIpWzBdIHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuXHRcdHJldHVybiB7XG5cblx0XHRcdHNlbmQ6IGZ1bmN0aW9uKCBfLCBjYWxsYmFjayApIHtcblxuXHRcdFx0XHRzY3JpcHQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwic2NyaXB0XCIpO1xuXG5cdFx0XHRcdHNjcmlwdC5hc3luYyA9IHRydWU7XG5cblx0XHRcdFx0aWYgKCBzLnNjcmlwdENoYXJzZXQgKSB7XG5cdFx0XHRcdFx0c2NyaXB0LmNoYXJzZXQgPSBzLnNjcmlwdENoYXJzZXQ7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRzY3JpcHQuc3JjID0gcy51cmw7XG5cblx0XHRcdFx0Ly8gQXR0YWNoIGhhbmRsZXJzIGZvciBhbGwgYnJvd3NlcnNcblx0XHRcdFx0c2NyaXB0Lm9ubG9hZCA9IHNjcmlwdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiggXywgaXNBYm9ydCApIHtcblxuXHRcdFx0XHRcdGlmICggaXNBYm9ydCB8fCAhc2NyaXB0LnJlYWR5U3RhdGUgfHwgL2xvYWRlZHxjb21wbGV0ZS8udGVzdCggc2NyaXB0LnJlYWR5U3RhdGUgKSApIHtcblxuXHRcdFx0XHRcdFx0Ly8gSGFuZGxlIG1lbW9yeSBsZWFrIGluIElFXG5cdFx0XHRcdFx0XHRzY3JpcHQub25sb2FkID0gc2NyaXB0Lm9ucmVhZHlzdGF0ZWNoYW5nZSA9IG51bGw7XG5cblx0XHRcdFx0XHRcdC8vIFJlbW92ZSB0aGUgc2NyaXB0XG5cdFx0XHRcdFx0XHRpZiAoIHNjcmlwdC5wYXJlbnROb2RlICkge1xuXHRcdFx0XHRcdFx0XHRzY3JpcHQucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCggc2NyaXB0ICk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdC8vIERlcmVmZXJlbmNlIHRoZSBzY3JpcHRcblx0XHRcdFx0XHRcdHNjcmlwdCA9IG51bGw7XG5cblx0XHRcdFx0XHRcdC8vIENhbGxiYWNrIGlmIG5vdCBhYm9ydFxuXHRcdFx0XHRcdFx0aWYgKCAhaXNBYm9ydCApIHtcblx0XHRcdFx0XHRcdFx0Y2FsbGJhY2soIDIwMCwgXCJzdWNjZXNzXCIgKTtcblx0XHRcdFx0XHRcdH1cblx0XHRcdFx0XHR9XG5cdFx0XHRcdH07XG5cblx0XHRcdFx0Ly8gQ2lyY3VtdmVudCBJRTYgYnVncyB3aXRoIGJhc2UgZWxlbWVudHMgKCMyNzA5IGFuZCAjNDM3OCkgYnkgcHJlcGVuZGluZ1xuXHRcdFx0XHQvLyBVc2UgbmF0aXZlIERPTSBtYW5pcHVsYXRpb24gdG8gYXZvaWQgb3VyIGRvbU1hbmlwIEFKQVggdHJpY2tlcnlcblx0XHRcdFx0aGVhZC5pbnNlcnRCZWZvcmUoIHNjcmlwdCwgaGVhZC5maXJzdENoaWxkICk7XG5cdFx0XHR9LFxuXG5cdFx0XHRhYm9ydDogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdGlmICggc2NyaXB0ICkge1xuXHRcdFx0XHRcdHNjcmlwdC5vbmxvYWQoIHVuZGVmaW5lZCwgdHJ1ZSApO1xuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufSk7XG5cblxuXG5cbnZhciBvbGRDYWxsYmFja3MgPSBbXSxcblx0cmpzb25wID0gLyg9KVxcPyg/PSZ8JCl8XFw/XFw/LztcblxuLy8gRGVmYXVsdCBqc29ucCBzZXR0aW5nc1xualF1ZXJ5LmFqYXhTZXR1cCh7XG5cdGpzb25wOiBcImNhbGxiYWNrXCIsXG5cdGpzb25wQ2FsbGJhY2s6IGZ1bmN0aW9uKCkge1xuXHRcdHZhciBjYWxsYmFjayA9IG9sZENhbGxiYWNrcy5wb3AoKSB8fCAoIGpRdWVyeS5leHBhbmRvICsgXCJfXCIgKyAoIG5vbmNlKysgKSApO1xuXHRcdHRoaXNbIGNhbGxiYWNrIF0gPSB0cnVlO1xuXHRcdHJldHVybiBjYWxsYmFjaztcblx0fVxufSk7XG5cbi8vIERldGVjdCwgbm9ybWFsaXplIG9wdGlvbnMgYW5kIGluc3RhbGwgY2FsbGJhY2tzIGZvciBqc29ucCByZXF1ZXN0c1xualF1ZXJ5LmFqYXhQcmVmaWx0ZXIoIFwianNvbiBqc29ucFwiLCBmdW5jdGlvbiggcywgb3JpZ2luYWxTZXR0aW5ncywganFYSFIgKSB7XG5cblx0dmFyIGNhbGxiYWNrTmFtZSwgb3ZlcndyaXR0ZW4sIHJlc3BvbnNlQ29udGFpbmVyLFxuXHRcdGpzb25Qcm9wID0gcy5qc29ucCAhPT0gZmFsc2UgJiYgKCByanNvbnAudGVzdCggcy51cmwgKSA/XG5cdFx0XHRcInVybFwiIDpcblx0XHRcdHR5cGVvZiBzLmRhdGEgPT09IFwic3RyaW5nXCIgJiYgISggcy5jb250ZW50VHlwZSB8fCBcIlwiICkuaW5kZXhPZihcImFwcGxpY2F0aW9uL3gtd3d3LWZvcm0tdXJsZW5jb2RlZFwiKSAmJiByanNvbnAudGVzdCggcy5kYXRhICkgJiYgXCJkYXRhXCJcblx0XHQpO1xuXG5cdC8vIEhhbmRsZSBpZmYgdGhlIGV4cGVjdGVkIGRhdGEgdHlwZSBpcyBcImpzb25wXCIgb3Igd2UgaGF2ZSBhIHBhcmFtZXRlciB0byBzZXRcblx0aWYgKCBqc29uUHJvcCB8fCBzLmRhdGFUeXBlc1sgMCBdID09PSBcImpzb25wXCIgKSB7XG5cblx0XHQvLyBHZXQgY2FsbGJhY2sgbmFtZSwgcmVtZW1iZXJpbmcgcHJlZXhpc3RpbmcgdmFsdWUgYXNzb2NpYXRlZCB3aXRoIGl0XG5cdFx0Y2FsbGJhY2tOYW1lID0gcy5qc29ucENhbGxiYWNrID0galF1ZXJ5LmlzRnVuY3Rpb24oIHMuanNvbnBDYWxsYmFjayApID9cblx0XHRcdHMuanNvbnBDYWxsYmFjaygpIDpcblx0XHRcdHMuanNvbnBDYWxsYmFjaztcblxuXHRcdC8vIEluc2VydCBjYWxsYmFjayBpbnRvIHVybCBvciBmb3JtIGRhdGFcblx0XHRpZiAoIGpzb25Qcm9wICkge1xuXHRcdFx0c1sganNvblByb3AgXSA9IHNbIGpzb25Qcm9wIF0ucmVwbGFjZSggcmpzb25wLCBcIiQxXCIgKyBjYWxsYmFja05hbWUgKTtcblx0XHR9IGVsc2UgaWYgKCBzLmpzb25wICE9PSBmYWxzZSApIHtcblx0XHRcdHMudXJsICs9ICggcnF1ZXJ5LnRlc3QoIHMudXJsICkgPyBcIiZcIiA6IFwiP1wiICkgKyBzLmpzb25wICsgXCI9XCIgKyBjYWxsYmFja05hbWU7XG5cdFx0fVxuXG5cdFx0Ly8gVXNlIGRhdGEgY29udmVydGVyIHRvIHJldHJpZXZlIGpzb24gYWZ0ZXIgc2NyaXB0IGV4ZWN1dGlvblxuXHRcdHMuY29udmVydGVyc1tcInNjcmlwdCBqc29uXCJdID0gZnVuY3Rpb24oKSB7XG5cdFx0XHRpZiAoICFyZXNwb25zZUNvbnRhaW5lciApIHtcblx0XHRcdFx0alF1ZXJ5LmVycm9yKCBjYWxsYmFja05hbWUgKyBcIiB3YXMgbm90IGNhbGxlZFwiICk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gcmVzcG9uc2VDb250YWluZXJbIDAgXTtcblx0XHR9O1xuXG5cdFx0Ly8gZm9yY2UganNvbiBkYXRhVHlwZVxuXHRcdHMuZGF0YVR5cGVzWyAwIF0gPSBcImpzb25cIjtcblxuXHRcdC8vIEluc3RhbGwgY2FsbGJhY2tcblx0XHRvdmVyd3JpdHRlbiA9IHdpbmRvd1sgY2FsbGJhY2tOYW1lIF07XG5cdFx0d2luZG93WyBjYWxsYmFja05hbWUgXSA9IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBhcmd1bWVudHM7XG5cdFx0fTtcblxuXHRcdC8vIENsZWFuLXVwIGZ1bmN0aW9uIChmaXJlcyBhZnRlciBjb252ZXJ0ZXJzKVxuXHRcdGpxWEhSLmFsd2F5cyhmdW5jdGlvbigpIHtcblx0XHRcdC8vIFJlc3RvcmUgcHJlZXhpc3RpbmcgdmFsdWVcblx0XHRcdHdpbmRvd1sgY2FsbGJhY2tOYW1lIF0gPSBvdmVyd3JpdHRlbjtcblxuXHRcdFx0Ly8gU2F2ZSBiYWNrIGFzIGZyZWVcblx0XHRcdGlmICggc1sgY2FsbGJhY2tOYW1lIF0gKSB7XG5cdFx0XHRcdC8vIG1ha2Ugc3VyZSB0aGF0IHJlLXVzaW5nIHRoZSBvcHRpb25zIGRvZXNuJ3Qgc2NyZXcgdGhpbmdzIGFyb3VuZFxuXHRcdFx0XHRzLmpzb25wQ2FsbGJhY2sgPSBvcmlnaW5hbFNldHRpbmdzLmpzb25wQ2FsbGJhY2s7XG5cblx0XHRcdFx0Ly8gc2F2ZSB0aGUgY2FsbGJhY2sgbmFtZSBmb3IgZnV0dXJlIHVzZVxuXHRcdFx0XHRvbGRDYWxsYmFja3MucHVzaCggY2FsbGJhY2tOYW1lICk7XG5cdFx0XHR9XG5cblx0XHRcdC8vIENhbGwgaWYgaXQgd2FzIGEgZnVuY3Rpb24gYW5kIHdlIGhhdmUgYSByZXNwb25zZVxuXHRcdFx0aWYgKCByZXNwb25zZUNvbnRhaW5lciAmJiBqUXVlcnkuaXNGdW5jdGlvbiggb3ZlcndyaXR0ZW4gKSApIHtcblx0XHRcdFx0b3ZlcndyaXR0ZW4oIHJlc3BvbnNlQ29udGFpbmVyWyAwIF0gKTtcblx0XHRcdH1cblxuXHRcdFx0cmVzcG9uc2VDb250YWluZXIgPSBvdmVyd3JpdHRlbiA9IHVuZGVmaW5lZDtcblx0XHR9KTtcblxuXHRcdC8vIERlbGVnYXRlIHRvIHNjcmlwdFxuXHRcdHJldHVybiBcInNjcmlwdFwiO1xuXHR9XG59KTtcblxuXG5cblxuLy8gZGF0YTogc3RyaW5nIG9mIGh0bWxcbi8vIGNvbnRleHQgKG9wdGlvbmFsKTogSWYgc3BlY2lmaWVkLCB0aGUgZnJhZ21lbnQgd2lsbCBiZSBjcmVhdGVkIGluIHRoaXMgY29udGV4dCwgZGVmYXVsdHMgdG8gZG9jdW1lbnRcbi8vIGtlZXBTY3JpcHRzIChvcHRpb25hbCk6IElmIHRydWUsIHdpbGwgaW5jbHVkZSBzY3JpcHRzIHBhc3NlZCBpbiB0aGUgaHRtbCBzdHJpbmdcbmpRdWVyeS5wYXJzZUhUTUwgPSBmdW5jdGlvbiggZGF0YSwgY29udGV4dCwga2VlcFNjcmlwdHMgKSB7XG5cdGlmICggIWRhdGEgfHwgdHlwZW9mIGRhdGEgIT09IFwic3RyaW5nXCIgKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblx0aWYgKCB0eXBlb2YgY29udGV4dCA9PT0gXCJib29sZWFuXCIgKSB7XG5cdFx0a2VlcFNjcmlwdHMgPSBjb250ZXh0O1xuXHRcdGNvbnRleHQgPSBmYWxzZTtcblx0fVxuXHRjb250ZXh0ID0gY29udGV4dCB8fCBkb2N1bWVudDtcblxuXHR2YXIgcGFyc2VkID0gcnNpbmdsZVRhZy5leGVjKCBkYXRhICksXG5cdFx0c2NyaXB0cyA9ICFrZWVwU2NyaXB0cyAmJiBbXTtcblxuXHQvLyBTaW5nbGUgdGFnXG5cdGlmICggcGFyc2VkICkge1xuXHRcdHJldHVybiBbIGNvbnRleHQuY3JlYXRlRWxlbWVudCggcGFyc2VkWzFdICkgXTtcblx0fVxuXG5cdHBhcnNlZCA9IGpRdWVyeS5idWlsZEZyYWdtZW50KCBbIGRhdGEgXSwgY29udGV4dCwgc2NyaXB0cyApO1xuXG5cdGlmICggc2NyaXB0cyAmJiBzY3JpcHRzLmxlbmd0aCApIHtcblx0XHRqUXVlcnkoIHNjcmlwdHMgKS5yZW1vdmUoKTtcblx0fVxuXG5cdHJldHVybiBqUXVlcnkubWVyZ2UoIFtdLCBwYXJzZWQuY2hpbGROb2RlcyApO1xufTtcblxuXG4vLyBLZWVwIGEgY29weSBvZiB0aGUgb2xkIGxvYWQgbWV0aG9kXG52YXIgX2xvYWQgPSBqUXVlcnkuZm4ubG9hZDtcblxuLyoqXG4gKiBMb2FkIGEgdXJsIGludG8gYSBwYWdlXG4gKi9cbmpRdWVyeS5mbi5sb2FkID0gZnVuY3Rpb24oIHVybCwgcGFyYW1zLCBjYWxsYmFjayApIHtcblx0aWYgKCB0eXBlb2YgdXJsICE9PSBcInN0cmluZ1wiICYmIF9sb2FkICkge1xuXHRcdHJldHVybiBfbG9hZC5hcHBseSggdGhpcywgYXJndW1lbnRzICk7XG5cdH1cblxuXHR2YXIgc2VsZWN0b3IsIHJlc3BvbnNlLCB0eXBlLFxuXHRcdHNlbGYgPSB0aGlzLFxuXHRcdG9mZiA9IHVybC5pbmRleE9mKFwiIFwiKTtcblxuXHRpZiAoIG9mZiA+PSAwICkge1xuXHRcdHNlbGVjdG9yID0galF1ZXJ5LnRyaW0oIHVybC5zbGljZSggb2ZmLCB1cmwubGVuZ3RoICkgKTtcblx0XHR1cmwgPSB1cmwuc2xpY2UoIDAsIG9mZiApO1xuXHR9XG5cblx0Ly8gSWYgaXQncyBhIGZ1bmN0aW9uXG5cdGlmICggalF1ZXJ5LmlzRnVuY3Rpb24oIHBhcmFtcyApICkge1xuXG5cdFx0Ly8gV2UgYXNzdW1lIHRoYXQgaXQncyB0aGUgY2FsbGJhY2tcblx0XHRjYWxsYmFjayA9IHBhcmFtcztcblx0XHRwYXJhbXMgPSB1bmRlZmluZWQ7XG5cblx0Ly8gT3RoZXJ3aXNlLCBidWlsZCBhIHBhcmFtIHN0cmluZ1xuXHR9IGVsc2UgaWYgKCBwYXJhbXMgJiYgdHlwZW9mIHBhcmFtcyA9PT0gXCJvYmplY3RcIiApIHtcblx0XHR0eXBlID0gXCJQT1NUXCI7XG5cdH1cblxuXHQvLyBJZiB3ZSBoYXZlIGVsZW1lbnRzIHRvIG1vZGlmeSwgbWFrZSB0aGUgcmVxdWVzdFxuXHRpZiAoIHNlbGYubGVuZ3RoID4gMCApIHtcblx0XHRqUXVlcnkuYWpheCh7XG5cdFx0XHR1cmw6IHVybCxcblxuXHRcdFx0Ly8gaWYgXCJ0eXBlXCIgdmFyaWFibGUgaXMgdW5kZWZpbmVkLCB0aGVuIFwiR0VUXCIgbWV0aG9kIHdpbGwgYmUgdXNlZFxuXHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdGRhdGFUeXBlOiBcImh0bWxcIixcblx0XHRcdGRhdGE6IHBhcmFtc1xuXHRcdH0pLmRvbmUoZnVuY3Rpb24oIHJlc3BvbnNlVGV4dCApIHtcblxuXHRcdFx0Ly8gU2F2ZSByZXNwb25zZSBmb3IgdXNlIGluIGNvbXBsZXRlIGNhbGxiYWNrXG5cdFx0XHRyZXNwb25zZSA9IGFyZ3VtZW50cztcblxuXHRcdFx0c2VsZi5odG1sKCBzZWxlY3RvciA/XG5cblx0XHRcdFx0Ly8gSWYgYSBzZWxlY3RvciB3YXMgc3BlY2lmaWVkLCBsb2NhdGUgdGhlIHJpZ2h0IGVsZW1lbnRzIGluIGEgZHVtbXkgZGl2XG5cdFx0XHRcdC8vIEV4Y2x1ZGUgc2NyaXB0cyB0byBhdm9pZCBJRSAnUGVybWlzc2lvbiBEZW5pZWQnIGVycm9yc1xuXHRcdFx0XHRqUXVlcnkoXCI8ZGl2PlwiKS5hcHBlbmQoIGpRdWVyeS5wYXJzZUhUTUwoIHJlc3BvbnNlVGV4dCApICkuZmluZCggc2VsZWN0b3IgKSA6XG5cblx0XHRcdFx0Ly8gT3RoZXJ3aXNlIHVzZSB0aGUgZnVsbCByZXN1bHRcblx0XHRcdFx0cmVzcG9uc2VUZXh0ICk7XG5cblx0XHR9KS5jb21wbGV0ZSggY2FsbGJhY2sgJiYgZnVuY3Rpb24oIGpxWEhSLCBzdGF0dXMgKSB7XG5cdFx0XHRzZWxmLmVhY2goIGNhbGxiYWNrLCByZXNwb25zZSB8fCBbIGpxWEhSLnJlc3BvbnNlVGV4dCwgc3RhdHVzLCBqcVhIUiBdICk7XG5cdFx0fSk7XG5cdH1cblxuXHRyZXR1cm4gdGhpcztcbn07XG5cblxuXG5cbi8vIEF0dGFjaCBhIGJ1bmNoIG9mIGZ1bmN0aW9ucyBmb3IgaGFuZGxpbmcgY29tbW9uIEFKQVggZXZlbnRzXG5qUXVlcnkuZWFjaCggWyBcImFqYXhTdGFydFwiLCBcImFqYXhTdG9wXCIsIFwiYWpheENvbXBsZXRlXCIsIFwiYWpheEVycm9yXCIsIFwiYWpheFN1Y2Nlc3NcIiwgXCJhamF4U2VuZFwiIF0sIGZ1bmN0aW9uKCBpLCB0eXBlICkge1xuXHRqUXVlcnkuZm5bIHR5cGUgXSA9IGZ1bmN0aW9uKCBmbiApIHtcblx0XHRyZXR1cm4gdGhpcy5vbiggdHlwZSwgZm4gKTtcblx0fTtcbn0pO1xuXG5cblxuXG5qUXVlcnkuZXhwci5maWx0ZXJzLmFuaW1hdGVkID0gZnVuY3Rpb24oIGVsZW0gKSB7XG5cdHJldHVybiBqUXVlcnkuZ3JlcChqUXVlcnkudGltZXJzLCBmdW5jdGlvbiggZm4gKSB7XG5cdFx0cmV0dXJuIGVsZW0gPT09IGZuLmVsZW07XG5cdH0pLmxlbmd0aDtcbn07XG5cblxuXG5cblxudmFyIGRvY0VsZW0gPSB3aW5kb3cuZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuXG4vKipcbiAqIEdldHMgYSB3aW5kb3cgZnJvbSBhbiBlbGVtZW50XG4gKi9cbmZ1bmN0aW9uIGdldFdpbmRvdyggZWxlbSApIHtcblx0cmV0dXJuIGpRdWVyeS5pc1dpbmRvdyggZWxlbSApID9cblx0XHRlbGVtIDpcblx0XHRlbGVtLm5vZGVUeXBlID09PSA5ID9cblx0XHRcdGVsZW0uZGVmYXVsdFZpZXcgfHwgZWxlbS5wYXJlbnRXaW5kb3cgOlxuXHRcdFx0ZmFsc2U7XG59XG5cbmpRdWVyeS5vZmZzZXQgPSB7XG5cdHNldE9mZnNldDogZnVuY3Rpb24oIGVsZW0sIG9wdGlvbnMsIGkgKSB7XG5cdFx0dmFyIGN1clBvc2l0aW9uLCBjdXJMZWZ0LCBjdXJDU1NUb3AsIGN1clRvcCwgY3VyT2Zmc2V0LCBjdXJDU1NMZWZ0LCBjYWxjdWxhdGVQb3NpdGlvbixcblx0XHRcdHBvc2l0aW9uID0galF1ZXJ5LmNzcyggZWxlbSwgXCJwb3NpdGlvblwiICksXG5cdFx0XHRjdXJFbGVtID0galF1ZXJ5KCBlbGVtICksXG5cdFx0XHRwcm9wcyA9IHt9O1xuXG5cdFx0Ly8gc2V0IHBvc2l0aW9uIGZpcnN0LCBpbi1jYXNlIHRvcC9sZWZ0IGFyZSBzZXQgZXZlbiBvbiBzdGF0aWMgZWxlbVxuXHRcdGlmICggcG9zaXRpb24gPT09IFwic3RhdGljXCIgKSB7XG5cdFx0XHRlbGVtLnN0eWxlLnBvc2l0aW9uID0gXCJyZWxhdGl2ZVwiO1xuXHRcdH1cblxuXHRcdGN1ck9mZnNldCA9IGN1ckVsZW0ub2Zmc2V0KCk7XG5cdFx0Y3VyQ1NTVG9wID0galF1ZXJ5LmNzcyggZWxlbSwgXCJ0b3BcIiApO1xuXHRcdGN1ckNTU0xlZnQgPSBqUXVlcnkuY3NzKCBlbGVtLCBcImxlZnRcIiApO1xuXHRcdGNhbGN1bGF0ZVBvc2l0aW9uID0gKCBwb3NpdGlvbiA9PT0gXCJhYnNvbHV0ZVwiIHx8IHBvc2l0aW9uID09PSBcImZpeGVkXCIgKSAmJlxuXHRcdFx0alF1ZXJ5LmluQXJyYXkoXCJhdXRvXCIsIFsgY3VyQ1NTVG9wLCBjdXJDU1NMZWZ0IF0gKSA+IC0xO1xuXG5cdFx0Ly8gbmVlZCB0byBiZSBhYmxlIHRvIGNhbGN1bGF0ZSBwb3NpdGlvbiBpZiBlaXRoZXIgdG9wIG9yIGxlZnQgaXMgYXV0byBhbmQgcG9zaXRpb24gaXMgZWl0aGVyIGFic29sdXRlIG9yIGZpeGVkXG5cdFx0aWYgKCBjYWxjdWxhdGVQb3NpdGlvbiApIHtcblx0XHRcdGN1clBvc2l0aW9uID0gY3VyRWxlbS5wb3NpdGlvbigpO1xuXHRcdFx0Y3VyVG9wID0gY3VyUG9zaXRpb24udG9wO1xuXHRcdFx0Y3VyTGVmdCA9IGN1clBvc2l0aW9uLmxlZnQ7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1clRvcCA9IHBhcnNlRmxvYXQoIGN1ckNTU1RvcCApIHx8IDA7XG5cdFx0XHRjdXJMZWZ0ID0gcGFyc2VGbG9hdCggY3VyQ1NTTGVmdCApIHx8IDA7XG5cdFx0fVxuXG5cdFx0aWYgKCBqUXVlcnkuaXNGdW5jdGlvbiggb3B0aW9ucyApICkge1xuXHRcdFx0b3B0aW9ucyA9IG9wdGlvbnMuY2FsbCggZWxlbSwgaSwgY3VyT2Zmc2V0ICk7XG5cdFx0fVxuXG5cdFx0aWYgKCBvcHRpb25zLnRvcCAhPSBudWxsICkge1xuXHRcdFx0cHJvcHMudG9wID0gKCBvcHRpb25zLnRvcCAtIGN1ck9mZnNldC50b3AgKSArIGN1clRvcDtcblx0XHR9XG5cdFx0aWYgKCBvcHRpb25zLmxlZnQgIT0gbnVsbCApIHtcblx0XHRcdHByb3BzLmxlZnQgPSAoIG9wdGlvbnMubGVmdCAtIGN1ck9mZnNldC5sZWZ0ICkgKyBjdXJMZWZ0O1xuXHRcdH1cblxuXHRcdGlmICggXCJ1c2luZ1wiIGluIG9wdGlvbnMgKSB7XG5cdFx0XHRvcHRpb25zLnVzaW5nLmNhbGwoIGVsZW0sIHByb3BzICk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1ckVsZW0uY3NzKCBwcm9wcyApO1xuXHRcdH1cblx0fVxufTtcblxualF1ZXJ5LmZuLmV4dGVuZCh7XG5cdG9mZnNldDogZnVuY3Rpb24oIG9wdGlvbnMgKSB7XG5cdFx0aWYgKCBhcmd1bWVudHMubGVuZ3RoICkge1xuXHRcdFx0cmV0dXJuIG9wdGlvbnMgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdHRoaXMgOlxuXHRcdFx0XHR0aGlzLmVhY2goZnVuY3Rpb24oIGkgKSB7XG5cdFx0XHRcdFx0alF1ZXJ5Lm9mZnNldC5zZXRPZmZzZXQoIHRoaXMsIG9wdGlvbnMsIGkgKTtcblx0XHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0dmFyIGRvY0VsZW0sIHdpbixcblx0XHRcdGJveCA9IHsgdG9wOiAwLCBsZWZ0OiAwIH0sXG5cdFx0XHRlbGVtID0gdGhpc1sgMCBdLFxuXHRcdFx0ZG9jID0gZWxlbSAmJiBlbGVtLm93bmVyRG9jdW1lbnQ7XG5cblx0XHRpZiAoICFkb2MgKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0ZG9jRWxlbSA9IGRvYy5kb2N1bWVudEVsZW1lbnQ7XG5cblx0XHQvLyBNYWtlIHN1cmUgaXQncyBub3QgYSBkaXNjb25uZWN0ZWQgRE9NIG5vZGVcblx0XHRpZiAoICFqUXVlcnkuY29udGFpbnMoIGRvY0VsZW0sIGVsZW0gKSApIHtcblx0XHRcdHJldHVybiBib3g7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgd2UgZG9uJ3QgaGF2ZSBnQkNSLCBqdXN0IHVzZSAwLDAgcmF0aGVyIHRoYW4gZXJyb3Jcblx0XHQvLyBCbGFja0JlcnJ5IDUsIGlPUyAzIChvcmlnaW5hbCBpUGhvbmUpXG5cdFx0aWYgKCB0eXBlb2YgZWxlbS5nZXRCb3VuZGluZ0NsaWVudFJlY3QgIT09IHN0cnVuZGVmaW5lZCApIHtcblx0XHRcdGJveCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0fVxuXHRcdHdpbiA9IGdldFdpbmRvdyggZG9jICk7XG5cdFx0cmV0dXJuIHtcblx0XHRcdHRvcDogYm94LnRvcCAgKyAoIHdpbi5wYWdlWU9mZnNldCB8fCBkb2NFbGVtLnNjcm9sbFRvcCApICAtICggZG9jRWxlbS5jbGllbnRUb3AgIHx8IDAgKSxcblx0XHRcdGxlZnQ6IGJveC5sZWZ0ICsgKCB3aW4ucGFnZVhPZmZzZXQgfHwgZG9jRWxlbS5zY3JvbGxMZWZ0ICkgLSAoIGRvY0VsZW0uY2xpZW50TGVmdCB8fCAwIClcblx0XHR9O1xuXHR9LFxuXG5cdHBvc2l0aW9uOiBmdW5jdGlvbigpIHtcblx0XHRpZiAoICF0aGlzWyAwIF0gKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dmFyIG9mZnNldFBhcmVudCwgb2Zmc2V0LFxuXHRcdFx0cGFyZW50T2Zmc2V0ID0geyB0b3A6IDAsIGxlZnQ6IDAgfSxcblx0XHRcdGVsZW0gPSB0aGlzWyAwIF07XG5cblx0XHQvLyBmaXhlZCBlbGVtZW50cyBhcmUgb2Zmc2V0IGZyb20gd2luZG93IChwYXJlbnRPZmZzZXQgPSB7dG9wOjAsIGxlZnQ6IDB9LCBiZWNhdXNlIGl0IGlzIGl0cyBvbmx5IG9mZnNldCBwYXJlbnRcblx0XHRpZiAoIGpRdWVyeS5jc3MoIGVsZW0sIFwicG9zaXRpb25cIiApID09PSBcImZpeGVkXCIgKSB7XG5cdFx0XHQvLyB3ZSBhc3N1bWUgdGhhdCBnZXRCb3VuZGluZ0NsaWVudFJlY3QgaXMgYXZhaWxhYmxlIHdoZW4gY29tcHV0ZWQgcG9zaXRpb24gaXMgZml4ZWRcblx0XHRcdG9mZnNldCA9IGVsZW0uZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEdldCAqcmVhbCogb2Zmc2V0UGFyZW50XG5cdFx0XHRvZmZzZXRQYXJlbnQgPSB0aGlzLm9mZnNldFBhcmVudCgpO1xuXG5cdFx0XHQvLyBHZXQgY29ycmVjdCBvZmZzZXRzXG5cdFx0XHRvZmZzZXQgPSB0aGlzLm9mZnNldCgpO1xuXHRcdFx0aWYgKCAhalF1ZXJ5Lm5vZGVOYW1lKCBvZmZzZXRQYXJlbnRbIDAgXSwgXCJodG1sXCIgKSApIHtcblx0XHRcdFx0cGFyZW50T2Zmc2V0ID0gb2Zmc2V0UGFyZW50Lm9mZnNldCgpO1xuXHRcdFx0fVxuXG5cdFx0XHQvLyBBZGQgb2Zmc2V0UGFyZW50IGJvcmRlcnNcblx0XHRcdHBhcmVudE9mZnNldC50b3AgICs9IGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudFsgMCBdLCBcImJvcmRlclRvcFdpZHRoXCIsIHRydWUgKTtcblx0XHRcdHBhcmVudE9mZnNldC5sZWZ0ICs9IGpRdWVyeS5jc3MoIG9mZnNldFBhcmVudFsgMCBdLCBcImJvcmRlckxlZnRXaWR0aFwiLCB0cnVlICk7XG5cdFx0fVxuXG5cdFx0Ly8gU3VidHJhY3QgcGFyZW50IG9mZnNldHMgYW5kIGVsZW1lbnQgbWFyZ2luc1xuXHRcdC8vIG5vdGU6IHdoZW4gYW4gZWxlbWVudCBoYXMgbWFyZ2luOiBhdXRvIHRoZSBvZmZzZXRMZWZ0IGFuZCBtYXJnaW5MZWZ0XG5cdFx0Ly8gYXJlIHRoZSBzYW1lIGluIFNhZmFyaSBjYXVzaW5nIG9mZnNldC5sZWZ0IHRvIGluY29ycmVjdGx5IGJlIDBcblx0XHRyZXR1cm4ge1xuXHRcdFx0dG9wOiAgb2Zmc2V0LnRvcCAgLSBwYXJlbnRPZmZzZXQudG9wIC0galF1ZXJ5LmNzcyggZWxlbSwgXCJtYXJnaW5Ub3BcIiwgdHJ1ZSApLFxuXHRcdFx0bGVmdDogb2Zmc2V0LmxlZnQgLSBwYXJlbnRPZmZzZXQubGVmdCAtIGpRdWVyeS5jc3MoIGVsZW0sIFwibWFyZ2luTGVmdFwiLCB0cnVlKVxuXHRcdH07XG5cdH0sXG5cblx0b2Zmc2V0UGFyZW50OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gdGhpcy5tYXAoZnVuY3Rpb24oKSB7XG5cdFx0XHR2YXIgb2Zmc2V0UGFyZW50ID0gdGhpcy5vZmZzZXRQYXJlbnQgfHwgZG9jRWxlbTtcblxuXHRcdFx0d2hpbGUgKCBvZmZzZXRQYXJlbnQgJiYgKCAhalF1ZXJ5Lm5vZGVOYW1lKCBvZmZzZXRQYXJlbnQsIFwiaHRtbFwiICkgJiYgalF1ZXJ5LmNzcyggb2Zmc2V0UGFyZW50LCBcInBvc2l0aW9uXCIgKSA9PT0gXCJzdGF0aWNcIiApICkge1xuXHRcdFx0XHRvZmZzZXRQYXJlbnQgPSBvZmZzZXRQYXJlbnQub2Zmc2V0UGFyZW50O1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuIG9mZnNldFBhcmVudCB8fCBkb2NFbGVtO1xuXHRcdH0pO1xuXHR9XG59KTtcblxuLy8gQ3JlYXRlIHNjcm9sbExlZnQgYW5kIHNjcm9sbFRvcCBtZXRob2RzXG5qUXVlcnkuZWFjaCggeyBzY3JvbGxMZWZ0OiBcInBhZ2VYT2Zmc2V0XCIsIHNjcm9sbFRvcDogXCJwYWdlWU9mZnNldFwiIH0sIGZ1bmN0aW9uKCBtZXRob2QsIHByb3AgKSB7XG5cdHZhciB0b3AgPSAvWS8udGVzdCggcHJvcCApO1xuXG5cdGpRdWVyeS5mblsgbWV0aG9kIF0gPSBmdW5jdGlvbiggdmFsICkge1xuXHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCBtZXRob2QsIHZhbCApIHtcblx0XHRcdHZhciB3aW4gPSBnZXRXaW5kb3coIGVsZW0gKTtcblxuXHRcdFx0aWYgKCB2YWwgPT09IHVuZGVmaW5lZCApIHtcblx0XHRcdFx0cmV0dXJuIHdpbiA/IChwcm9wIGluIHdpbikgPyB3aW5bIHByb3AgXSA6XG5cdFx0XHRcdFx0d2luLmRvY3VtZW50LmRvY3VtZW50RWxlbWVudFsgbWV0aG9kIF0gOlxuXHRcdFx0XHRcdGVsZW1bIG1ldGhvZCBdO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoIHdpbiApIHtcblx0XHRcdFx0d2luLnNjcm9sbFRvKFxuXHRcdFx0XHRcdCF0b3AgPyB2YWwgOiBqUXVlcnkoIHdpbiApLnNjcm9sbExlZnQoKSxcblx0XHRcdFx0XHR0b3AgPyB2YWwgOiBqUXVlcnkoIHdpbiApLnNjcm9sbFRvcCgpXG5cdFx0XHRcdCk7XG5cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGVsZW1bIG1ldGhvZCBdID0gdmFsO1xuXHRcdFx0fVxuXHRcdH0sIG1ldGhvZCwgdmFsLCBhcmd1bWVudHMubGVuZ3RoLCBudWxsICk7XG5cdH07XG59KTtcblxuLy8gQWRkIHRoZSB0b3AvbGVmdCBjc3NIb29rcyB1c2luZyBqUXVlcnkuZm4ucG9zaXRpb25cbi8vIFdlYmtpdCBidWc6IGh0dHBzOi8vYnVncy53ZWJraXQub3JnL3Nob3dfYnVnLmNnaT9pZD0yOTA4NFxuLy8gZ2V0Q29tcHV0ZWRTdHlsZSByZXR1cm5zIHBlcmNlbnQgd2hlbiBzcGVjaWZpZWQgZm9yIHRvcC9sZWZ0L2JvdHRvbS9yaWdodFxuLy8gcmF0aGVyIHRoYW4gbWFrZSB0aGUgY3NzIG1vZHVsZSBkZXBlbmQgb24gdGhlIG9mZnNldCBtb2R1bGUsIHdlIGp1c3QgY2hlY2sgZm9yIGl0IGhlcmVcbmpRdWVyeS5lYWNoKCBbIFwidG9wXCIsIFwibGVmdFwiIF0sIGZ1bmN0aW9uKCBpLCBwcm9wICkge1xuXHRqUXVlcnkuY3NzSG9va3NbIHByb3AgXSA9IGFkZEdldEhvb2tJZiggc3VwcG9ydC5waXhlbFBvc2l0aW9uLFxuXHRcdGZ1bmN0aW9uKCBlbGVtLCBjb21wdXRlZCApIHtcblx0XHRcdGlmICggY29tcHV0ZWQgKSB7XG5cdFx0XHRcdGNvbXB1dGVkID0gY3VyQ1NTKCBlbGVtLCBwcm9wICk7XG5cdFx0XHRcdC8vIGlmIGN1ckNTUyByZXR1cm5zIHBlcmNlbnRhZ2UsIGZhbGxiYWNrIHRvIG9mZnNldFxuXHRcdFx0XHRyZXR1cm4gcm51bW5vbnB4LnRlc3QoIGNvbXB1dGVkICkgP1xuXHRcdFx0XHRcdGpRdWVyeSggZWxlbSApLnBvc2l0aW9uKClbIHByb3AgXSArIFwicHhcIiA6XG5cdFx0XHRcdFx0Y29tcHV0ZWQ7XG5cdFx0XHR9XG5cdFx0fVxuXHQpO1xufSk7XG5cblxuLy8gQ3JlYXRlIGlubmVySGVpZ2h0LCBpbm5lcldpZHRoLCBoZWlnaHQsIHdpZHRoLCBvdXRlckhlaWdodCBhbmQgb3V0ZXJXaWR0aCBtZXRob2RzXG5qUXVlcnkuZWFjaCggeyBIZWlnaHQ6IFwiaGVpZ2h0XCIsIFdpZHRoOiBcIndpZHRoXCIgfSwgZnVuY3Rpb24oIG5hbWUsIHR5cGUgKSB7XG5cdGpRdWVyeS5lYWNoKCB7IHBhZGRpbmc6IFwiaW5uZXJcIiArIG5hbWUsIGNvbnRlbnQ6IHR5cGUsIFwiXCI6IFwib3V0ZXJcIiArIG5hbWUgfSwgZnVuY3Rpb24oIGRlZmF1bHRFeHRyYSwgZnVuY05hbWUgKSB7XG5cdFx0Ly8gbWFyZ2luIGlzIG9ubHkgZm9yIG91dGVySGVpZ2h0LCBvdXRlcldpZHRoXG5cdFx0alF1ZXJ5LmZuWyBmdW5jTmFtZSBdID0gZnVuY3Rpb24oIG1hcmdpbiwgdmFsdWUgKSB7XG5cdFx0XHR2YXIgY2hhaW5hYmxlID0gYXJndW1lbnRzLmxlbmd0aCAmJiAoIGRlZmF1bHRFeHRyYSB8fCB0eXBlb2YgbWFyZ2luICE9PSBcImJvb2xlYW5cIiApLFxuXHRcdFx0XHRleHRyYSA9IGRlZmF1bHRFeHRyYSB8fCAoIG1hcmdpbiA9PT0gdHJ1ZSB8fCB2YWx1ZSA9PT0gdHJ1ZSA/IFwibWFyZ2luXCIgOiBcImJvcmRlclwiICk7XG5cblx0XHRcdHJldHVybiBhY2Nlc3MoIHRoaXMsIGZ1bmN0aW9uKCBlbGVtLCB0eXBlLCB2YWx1ZSApIHtcblx0XHRcdFx0dmFyIGRvYztcblxuXHRcdFx0XHRpZiAoIGpRdWVyeS5pc1dpbmRvdyggZWxlbSApICkge1xuXHRcdFx0XHRcdC8vIEFzIG9mIDUvOC8yMDEyIHRoaXMgd2lsbCB5aWVsZCBpbmNvcnJlY3QgcmVzdWx0cyBmb3IgTW9iaWxlIFNhZmFyaSwgYnV0IHRoZXJlXG5cdFx0XHRcdFx0Ly8gaXNuJ3QgYSB3aG9sZSBsb3Qgd2UgY2FuIGRvLiBTZWUgcHVsbCByZXF1ZXN0IGF0IHRoaXMgVVJMIGZvciBkaXNjdXNzaW9uOlxuXHRcdFx0XHRcdC8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qcXVlcnkvanF1ZXJ5L3B1bGwvNzY0XG5cdFx0XHRcdFx0cmV0dXJuIGVsZW0uZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50WyBcImNsaWVudFwiICsgbmFtZSBdO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0Ly8gR2V0IGRvY3VtZW50IHdpZHRoIG9yIGhlaWdodFxuXHRcdFx0XHRpZiAoIGVsZW0ubm9kZVR5cGUgPT09IDkgKSB7XG5cdFx0XHRcdFx0ZG9jID0gZWxlbS5kb2N1bWVudEVsZW1lbnQ7XG5cblx0XHRcdFx0XHQvLyBFaXRoZXIgc2Nyb2xsW1dpZHRoL0hlaWdodF0gb3Igb2Zmc2V0W1dpZHRoL0hlaWdodF0gb3IgY2xpZW50W1dpZHRoL0hlaWdodF0sIHdoaWNoZXZlciBpcyBncmVhdGVzdFxuXHRcdFx0XHRcdC8vIHVuZm9ydHVuYXRlbHksIHRoaXMgY2F1c2VzIGJ1ZyAjMzgzOCBpbiBJRTYvOCBvbmx5LCBidXQgdGhlcmUgaXMgY3VycmVudGx5IG5vIGdvb2QsIHNtYWxsIHdheSB0byBmaXggaXQuXG5cdFx0XHRcdFx0cmV0dXJuIE1hdGgubWF4KFxuXHRcdFx0XHRcdFx0ZWxlbS5ib2R5WyBcInNjcm9sbFwiICsgbmFtZSBdLCBkb2NbIFwic2Nyb2xsXCIgKyBuYW1lIF0sXG5cdFx0XHRcdFx0XHRlbGVtLmJvZHlbIFwib2Zmc2V0XCIgKyBuYW1lIF0sIGRvY1sgXCJvZmZzZXRcIiArIG5hbWUgXSxcblx0XHRcdFx0XHRcdGRvY1sgXCJjbGllbnRcIiArIG5hbWUgXVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblxuXHRcdFx0XHRyZXR1cm4gdmFsdWUgPT09IHVuZGVmaW5lZCA/XG5cdFx0XHRcdFx0Ly8gR2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudCwgcmVxdWVzdGluZyBidXQgbm90IGZvcmNpbmcgcGFyc2VGbG9hdFxuXHRcdFx0XHRcdGpRdWVyeS5jc3MoIGVsZW0sIHR5cGUsIGV4dHJhICkgOlxuXG5cdFx0XHRcdFx0Ly8gU2V0IHdpZHRoIG9yIGhlaWdodCBvbiB0aGUgZWxlbWVudFxuXHRcdFx0XHRcdGpRdWVyeS5zdHlsZSggZWxlbSwgdHlwZSwgdmFsdWUsIGV4dHJhICk7XG5cdFx0XHR9LCB0eXBlLCBjaGFpbmFibGUgPyBtYXJnaW4gOiB1bmRlZmluZWQsIGNoYWluYWJsZSwgbnVsbCApO1xuXHRcdH07XG5cdH0pO1xufSk7XG5cblxuLy8gVGhlIG51bWJlciBvZiBlbGVtZW50cyBjb250YWluZWQgaW4gdGhlIG1hdGNoZWQgZWxlbWVudCBzZXRcbmpRdWVyeS5mbi5zaXplID0gZnVuY3Rpb24oKSB7XG5cdHJldHVybiB0aGlzLmxlbmd0aDtcbn07XG5cbmpRdWVyeS5mbi5hbmRTZWxmID0galF1ZXJ5LmZuLmFkZEJhY2s7XG5cblxuXG5cbi8vIFJlZ2lzdGVyIGFzIGEgbmFtZWQgQU1EIG1vZHVsZSwgc2luY2UgalF1ZXJ5IGNhbiBiZSBjb25jYXRlbmF0ZWQgd2l0aCBvdGhlclxuLy8gZmlsZXMgdGhhdCBtYXkgdXNlIGRlZmluZSwgYnV0IG5vdCB2aWEgYSBwcm9wZXIgY29uY2F0ZW5hdGlvbiBzY3JpcHQgdGhhdFxuLy8gdW5kZXJzdGFuZHMgYW5vbnltb3VzIEFNRCBtb2R1bGVzLiBBIG5hbWVkIEFNRCBpcyBzYWZlc3QgYW5kIG1vc3Qgcm9idXN0XG4vLyB3YXkgdG8gcmVnaXN0ZXIuIExvd2VyY2FzZSBqcXVlcnkgaXMgdXNlZCBiZWNhdXNlIEFNRCBtb2R1bGUgbmFtZXMgYXJlXG4vLyBkZXJpdmVkIGZyb20gZmlsZSBuYW1lcywgYW5kIGpRdWVyeSBpcyBub3JtYWxseSBkZWxpdmVyZWQgaW4gYSBsb3dlcmNhc2Vcbi8vIGZpbGUgbmFtZS4gRG8gdGhpcyBhZnRlciBjcmVhdGluZyB0aGUgZ2xvYmFsIHNvIHRoYXQgaWYgYW4gQU1EIG1vZHVsZSB3YW50c1xuLy8gdG8gY2FsbCBub0NvbmZsaWN0IHRvIGhpZGUgdGhpcyB2ZXJzaW9uIG9mIGpRdWVyeSwgaXQgd2lsbCB3b3JrLlxuXG4vLyBOb3RlIHRoYXQgZm9yIG1heGltdW0gcG9ydGFiaWxpdHksIGxpYnJhcmllcyB0aGF0IGFyZSBub3QgalF1ZXJ5IHNob3VsZFxuLy8gZGVjbGFyZSB0aGVtc2VsdmVzIGFzIGFub255bW91cyBtb2R1bGVzLCBhbmQgYXZvaWQgc2V0dGluZyBhIGdsb2JhbCBpZiBhblxuLy8gQU1EIGxvYWRlciBpcyBwcmVzZW50LiBqUXVlcnkgaXMgYSBzcGVjaWFsIGNhc2UuIEZvciBtb3JlIGluZm9ybWF0aW9uLCBzZWVcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9qcmJ1cmtlL3JlcXVpcmVqcy93aWtpL1VwZGF0aW5nLWV4aXN0aW5nLWxpYnJhcmllcyN3aWtpLWFub25cblxuaWYgKCB0eXBlb2YgZGVmaW5lID09PSBcImZ1bmN0aW9uXCIgJiYgZGVmaW5lLmFtZCApIHtcblx0ZGVmaW5lKCBcImpxdWVyeVwiLCBbXSwgZnVuY3Rpb24oKSB7XG5cdFx0cmV0dXJuIGpRdWVyeTtcblx0fSk7XG59XG5cblxuXG5cbnZhclxuXHQvLyBNYXAgb3ZlciBqUXVlcnkgaW4gY2FzZSBvZiBvdmVyd3JpdGVcblx0X2pRdWVyeSA9IHdpbmRvdy5qUXVlcnksXG5cblx0Ly8gTWFwIG92ZXIgdGhlICQgaW4gY2FzZSBvZiBvdmVyd3JpdGVcblx0XyQgPSB3aW5kb3cuJDtcblxualF1ZXJ5Lm5vQ29uZmxpY3QgPSBmdW5jdGlvbiggZGVlcCApIHtcblx0aWYgKCB3aW5kb3cuJCA9PT0galF1ZXJ5ICkge1xuXHRcdHdpbmRvdy4kID0gXyQ7XG5cdH1cblxuXHRpZiAoIGRlZXAgJiYgd2luZG93LmpRdWVyeSA9PT0galF1ZXJ5ICkge1xuXHRcdHdpbmRvdy5qUXVlcnkgPSBfalF1ZXJ5O1xuXHR9XG5cblx0cmV0dXJuIGpRdWVyeTtcbn07XG5cbi8vIEV4cG9zZSBqUXVlcnkgYW5kICQgaWRlbnRpZmllcnMsIGV2ZW4gaW5cbi8vIEFNRCAoIzcxMDIjY29tbWVudDoxMCwgaHR0cHM6Ly9naXRodWIuY29tL2pxdWVyeS9qcXVlcnkvcHVsbC81NTcpXG4vLyBhbmQgQ29tbW9uSlMgZm9yIGJyb3dzZXIgZW11bGF0b3JzICgjMTM1NjYpXG5pZiAoIHR5cGVvZiBub0dsb2JhbCA9PT0gc3RydW5kZWZpbmVkICkge1xuXHR3aW5kb3cualF1ZXJ5ID0gd2luZG93LiQgPSBqUXVlcnk7XG59XG5cblxuXG5cbnJldHVybiBqUXVlcnk7XG5cbn0pKTtcbiIsIjsoZnVuY3Rpb24od2luKXtcblx0dmFyIHN0b3JlID0ge30sXG5cdFx0ZG9jID0gd2luLmRvY3VtZW50LFxuXHRcdGxvY2FsU3RvcmFnZU5hbWUgPSAnbG9jYWxTdG9yYWdlJyxcblx0XHRzY3JpcHRUYWcgPSAnc2NyaXB0Jyxcblx0XHRzdG9yYWdlXG5cblx0c3RvcmUuZGlzYWJsZWQgPSBmYWxzZVxuXHRzdG9yZS52ZXJzaW9uID0gJzEuMy4xNydcblx0c3RvcmUuc2V0ID0gZnVuY3Rpb24oa2V5LCB2YWx1ZSkge31cblx0c3RvcmUuZ2V0ID0gZnVuY3Rpb24oa2V5LCBkZWZhdWx0VmFsKSB7fVxuXHRzdG9yZS5oYXMgPSBmdW5jdGlvbihrZXkpIHsgcmV0dXJuIHN0b3JlLmdldChrZXkpICE9PSB1bmRlZmluZWQgfVxuXHRzdG9yZS5yZW1vdmUgPSBmdW5jdGlvbihrZXkpIHt9XG5cdHN0b3JlLmNsZWFyID0gZnVuY3Rpb24oKSB7fVxuXHRzdG9yZS50cmFuc2FjdCA9IGZ1bmN0aW9uKGtleSwgZGVmYXVsdFZhbCwgdHJhbnNhY3Rpb25Gbikge1xuXHRcdGlmICh0cmFuc2FjdGlvbkZuID09IG51bGwpIHtcblx0XHRcdHRyYW5zYWN0aW9uRm4gPSBkZWZhdWx0VmFsXG5cdFx0XHRkZWZhdWx0VmFsID0gbnVsbFxuXHRcdH1cblx0XHRpZiAoZGVmYXVsdFZhbCA9PSBudWxsKSB7XG5cdFx0XHRkZWZhdWx0VmFsID0ge31cblx0XHR9XG5cdFx0dmFyIHZhbCA9IHN0b3JlLmdldChrZXksIGRlZmF1bHRWYWwpXG5cdFx0dHJhbnNhY3Rpb25Gbih2YWwpXG5cdFx0c3RvcmUuc2V0KGtleSwgdmFsKVxuXHR9XG5cdHN0b3JlLmdldEFsbCA9IGZ1bmN0aW9uKCkge31cblx0c3RvcmUuZm9yRWFjaCA9IGZ1bmN0aW9uKCkge31cblxuXHRzdG9yZS5zZXJpYWxpemUgPSBmdW5jdGlvbih2YWx1ZSkge1xuXHRcdHJldHVybiBKU09OLnN0cmluZ2lmeSh2YWx1ZSlcblx0fVxuXHRzdG9yZS5kZXNlcmlhbGl6ZSA9IGZ1bmN0aW9uKHZhbHVlKSB7XG5cdFx0aWYgKHR5cGVvZiB2YWx1ZSAhPSAnc3RyaW5nJykgeyByZXR1cm4gdW5kZWZpbmVkIH1cblx0XHR0cnkgeyByZXR1cm4gSlNPTi5wYXJzZSh2YWx1ZSkgfVxuXHRcdGNhdGNoKGUpIHsgcmV0dXJuIHZhbHVlIHx8IHVuZGVmaW5lZCB9XG5cdH1cblxuXHQvLyBGdW5jdGlvbnMgdG8gZW5jYXBzdWxhdGUgcXVlc3Rpb25hYmxlIEZpcmVGb3ggMy42LjEzIGJlaGF2aW9yXG5cdC8vIHdoZW4gYWJvdXQuY29uZmlnOjpkb20uc3RvcmFnZS5lbmFibGVkID09PSBmYWxzZVxuXHQvLyBTZWUgaHR0cHM6Ly9naXRodWIuY29tL21hcmN1c3dlc3Rpbi9zdG9yZS5qcy9pc3N1ZXMjaXNzdWUvMTNcblx0ZnVuY3Rpb24gaXNMb2NhbFN0b3JhZ2VOYW1lU3VwcG9ydGVkKCkge1xuXHRcdHRyeSB7IHJldHVybiAobG9jYWxTdG9yYWdlTmFtZSBpbiB3aW4gJiYgd2luW2xvY2FsU3RvcmFnZU5hbWVdKSB9XG5cdFx0Y2F0Y2goZXJyKSB7IHJldHVybiBmYWxzZSB9XG5cdH1cblxuXHRpZiAoaXNMb2NhbFN0b3JhZ2VOYW1lU3VwcG9ydGVkKCkpIHtcblx0XHRzdG9yYWdlID0gd2luW2xvY2FsU3RvcmFnZU5hbWVdXG5cdFx0c3RvcmUuc2V0ID0gZnVuY3Rpb24oa2V5LCB2YWwpIHtcblx0XHRcdGlmICh2YWwgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gc3RvcmUucmVtb3ZlKGtleSkgfVxuXHRcdFx0c3RvcmFnZS5zZXRJdGVtKGtleSwgc3RvcmUuc2VyaWFsaXplKHZhbCkpXG5cdFx0XHRyZXR1cm4gdmFsXG5cdFx0fVxuXHRcdHN0b3JlLmdldCA9IGZ1bmN0aW9uKGtleSwgZGVmYXVsdFZhbCkge1xuXHRcdFx0dmFyIHZhbCA9IHN0b3JlLmRlc2VyaWFsaXplKHN0b3JhZ2UuZ2V0SXRlbShrZXkpKVxuXHRcdFx0cmV0dXJuICh2YWwgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRWYWwgOiB2YWwpXG5cdFx0fVxuXHRcdHN0b3JlLnJlbW92ZSA9IGZ1bmN0aW9uKGtleSkgeyBzdG9yYWdlLnJlbW92ZUl0ZW0oa2V5KSB9XG5cdFx0c3RvcmUuY2xlYXIgPSBmdW5jdGlvbigpIHsgc3RvcmFnZS5jbGVhcigpIH1cblx0XHRzdG9yZS5nZXRBbGwgPSBmdW5jdGlvbigpIHtcblx0XHRcdHZhciByZXQgPSB7fVxuXHRcdFx0c3RvcmUuZm9yRWFjaChmdW5jdGlvbihrZXksIHZhbCkge1xuXHRcdFx0XHRyZXRba2V5XSA9IHZhbFxuXHRcdFx0fSlcblx0XHRcdHJldHVybiByZXRcblx0XHR9XG5cdFx0c3RvcmUuZm9yRWFjaCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG5cdFx0XHRmb3IgKHZhciBpPTA7IGk8c3RvcmFnZS5sZW5ndGg7IGkrKykge1xuXHRcdFx0XHR2YXIga2V5ID0gc3RvcmFnZS5rZXkoaSlcblx0XHRcdFx0Y2FsbGJhY2soa2V5LCBzdG9yZS5nZXQoa2V5KSlcblx0XHRcdH1cblx0XHR9XG5cdH0gZWxzZSBpZiAoZG9jLmRvY3VtZW50RWxlbWVudC5hZGRCZWhhdmlvcikge1xuXHRcdHZhciBzdG9yYWdlT3duZXIsXG5cdFx0XHRzdG9yYWdlQ29udGFpbmVyXG5cdFx0Ly8gU2luY2UgI3VzZXJEYXRhIHN0b3JhZ2UgYXBwbGllcyBvbmx5IHRvIHNwZWNpZmljIHBhdGhzLCB3ZSBuZWVkIHRvXG5cdFx0Ly8gc29tZWhvdyBsaW5rIG91ciBkYXRhIHRvIGEgc3BlY2lmaWMgcGF0aC4gIFdlIGNob29zZSAvZmF2aWNvbi5pY29cblx0XHQvLyBhcyBhIHByZXR0eSBzYWZlIG9wdGlvbiwgc2luY2UgYWxsIGJyb3dzZXJzIGFscmVhZHkgbWFrZSBhIHJlcXVlc3QgdG9cblx0XHQvLyB0aGlzIFVSTCBhbnl3YXkgYW5kIGJlaW5nIGEgNDA0IHdpbGwgbm90IGh1cnQgdXMgaGVyZS4gIFdlIHdyYXAgYW5cblx0XHQvLyBpZnJhbWUgcG9pbnRpbmcgdG8gdGhlIGZhdmljb24gaW4gYW4gQWN0aXZlWE9iamVjdChodG1sZmlsZSkgb2JqZWN0XG5cdFx0Ly8gKHNlZTogaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L2FhNzUyNTc0KHY9VlMuODUpLmFzcHgpXG5cdFx0Ly8gc2luY2UgdGhlIGlmcmFtZSBhY2Nlc3MgcnVsZXMgYXBwZWFyIHRvIGFsbG93IGRpcmVjdCBhY2Nlc3MgYW5kXG5cdFx0Ly8gbWFuaXB1bGF0aW9uIG9mIHRoZSBkb2N1bWVudCBlbGVtZW50LCBldmVuIGZvciBhIDQwNCBwYWdlLiAgVGhpc1xuXHRcdC8vIGRvY3VtZW50IGNhbiBiZSB1c2VkIGluc3RlYWQgb2YgdGhlIGN1cnJlbnQgZG9jdW1lbnQgKHdoaWNoIHdvdWxkXG5cdFx0Ly8gaGF2ZSBiZWVuIGxpbWl0ZWQgdG8gdGhlIGN1cnJlbnQgcGF0aCkgdG8gcGVyZm9ybSAjdXNlckRhdGEgc3RvcmFnZS5cblx0XHR0cnkge1xuXHRcdFx0c3RvcmFnZUNvbnRhaW5lciA9IG5ldyBBY3RpdmVYT2JqZWN0KCdodG1sZmlsZScpXG5cdFx0XHRzdG9yYWdlQ29udGFpbmVyLm9wZW4oKVxuXHRcdFx0c3RvcmFnZUNvbnRhaW5lci53cml0ZSgnPCcrc2NyaXB0VGFnKyc+ZG9jdW1lbnQudz13aW5kb3c8Lycrc2NyaXB0VGFnKyc+PGlmcmFtZSBzcmM9XCIvZmF2aWNvbi5pY29cIj48L2lmcmFtZT4nKVxuXHRcdFx0c3RvcmFnZUNvbnRhaW5lci5jbG9zZSgpXG5cdFx0XHRzdG9yYWdlT3duZXIgPSBzdG9yYWdlQ29udGFpbmVyLncuZnJhbWVzWzBdLmRvY3VtZW50XG5cdFx0XHRzdG9yYWdlID0gc3RvcmFnZU93bmVyLmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG5cdFx0fSBjYXRjaChlKSB7XG5cdFx0XHQvLyBzb21laG93IEFjdGl2ZVhPYmplY3QgaW5zdGFudGlhdGlvbiBmYWlsZWQgKHBlcmhhcHMgc29tZSBzcGVjaWFsXG5cdFx0XHQvLyBzZWN1cml0eSBzZXR0aW5ncyBvciBvdGhlcndzZSksIGZhbGwgYmFjayB0byBwZXItcGF0aCBzdG9yYWdlXG5cdFx0XHRzdG9yYWdlID0gZG9jLmNyZWF0ZUVsZW1lbnQoJ2RpdicpXG5cdFx0XHRzdG9yYWdlT3duZXIgPSBkb2MuYm9keVxuXHRcdH1cblx0XHR2YXIgd2l0aElFU3RvcmFnZSA9IGZ1bmN0aW9uKHN0b3JlRnVuY3Rpb24pIHtcblx0XHRcdHJldHVybiBmdW5jdGlvbigpIHtcblx0XHRcdFx0dmFyIGFyZ3MgPSBBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChhcmd1bWVudHMsIDApXG5cdFx0XHRcdGFyZ3MudW5zaGlmdChzdG9yYWdlKVxuXHRcdFx0XHQvLyBTZWUgaHR0cDovL21zZG4ubWljcm9zb2Z0LmNvbS9lbi11cy9saWJyYXJ5L21zNTMxMDgxKHY9VlMuODUpLmFzcHhcblx0XHRcdFx0Ly8gYW5kIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS9tczUzMTQyNCh2PVZTLjg1KS5hc3B4XG5cdFx0XHRcdHN0b3JhZ2VPd25lci5hcHBlbmRDaGlsZChzdG9yYWdlKVxuXHRcdFx0XHRzdG9yYWdlLmFkZEJlaGF2aW9yKCcjZGVmYXVsdCN1c2VyRGF0YScpXG5cdFx0XHRcdHN0b3JhZ2UubG9hZChsb2NhbFN0b3JhZ2VOYW1lKVxuXHRcdFx0XHR2YXIgcmVzdWx0ID0gc3RvcmVGdW5jdGlvbi5hcHBseShzdG9yZSwgYXJncylcblx0XHRcdFx0c3RvcmFnZU93bmVyLnJlbW92ZUNoaWxkKHN0b3JhZ2UpXG5cdFx0XHRcdHJldHVybiByZXN1bHRcblx0XHRcdH1cblx0XHR9XG5cblx0XHQvLyBJbiBJRTcsIGtleXMgY2Fubm90IHN0YXJ0IHdpdGggYSBkaWdpdCBvciBjb250YWluIGNlcnRhaW4gY2hhcnMuXG5cdFx0Ly8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXJjdXN3ZXN0aW4vc3RvcmUuanMvaXNzdWVzLzQwXG5cdFx0Ly8gU2VlIGh0dHBzOi8vZ2l0aHViLmNvbS9tYXJjdXN3ZXN0aW4vc3RvcmUuanMvaXNzdWVzLzgzXG5cdFx0dmFyIGZvcmJpZGRlbkNoYXJzUmVnZXggPSBuZXcgUmVnRXhwKFwiWyFcXFwiIyQlJicoKSorLC9cXFxcXFxcXDo7PD0+P0BbXFxcXF1eYHt8fX5dXCIsIFwiZ1wiKVxuXHRcdGZ1bmN0aW9uIGllS2V5Rml4KGtleSkge1xuXHRcdFx0cmV0dXJuIGtleS5yZXBsYWNlKC9eZC8sICdfX18kJicpLnJlcGxhY2UoZm9yYmlkZGVuQ2hhcnNSZWdleCwgJ19fXycpXG5cdFx0fVxuXHRcdHN0b3JlLnNldCA9IHdpdGhJRVN0b3JhZ2UoZnVuY3Rpb24oc3RvcmFnZSwga2V5LCB2YWwpIHtcblx0XHRcdGtleSA9IGllS2V5Rml4KGtleSlcblx0XHRcdGlmICh2YWwgPT09IHVuZGVmaW5lZCkgeyByZXR1cm4gc3RvcmUucmVtb3ZlKGtleSkgfVxuXHRcdFx0c3RvcmFnZS5zZXRBdHRyaWJ1dGUoa2V5LCBzdG9yZS5zZXJpYWxpemUodmFsKSlcblx0XHRcdHN0b3JhZ2Uuc2F2ZShsb2NhbFN0b3JhZ2VOYW1lKVxuXHRcdFx0cmV0dXJuIHZhbFxuXHRcdH0pXG5cdFx0c3RvcmUuZ2V0ID0gd2l0aElFU3RvcmFnZShmdW5jdGlvbihzdG9yYWdlLCBrZXksIGRlZmF1bHRWYWwpIHtcblx0XHRcdGtleSA9IGllS2V5Rml4KGtleSlcblx0XHRcdHZhciB2YWwgPSBzdG9yZS5kZXNlcmlhbGl6ZShzdG9yYWdlLmdldEF0dHJpYnV0ZShrZXkpKVxuXHRcdFx0cmV0dXJuICh2YWwgPT09IHVuZGVmaW5lZCA/IGRlZmF1bHRWYWwgOiB2YWwpXG5cdFx0fSlcblx0XHRzdG9yZS5yZW1vdmUgPSB3aXRoSUVTdG9yYWdlKGZ1bmN0aW9uKHN0b3JhZ2UsIGtleSkge1xuXHRcdFx0a2V5ID0gaWVLZXlGaXgoa2V5KVxuXHRcdFx0c3RvcmFnZS5yZW1vdmVBdHRyaWJ1dGUoa2V5KVxuXHRcdFx0c3RvcmFnZS5zYXZlKGxvY2FsU3RvcmFnZU5hbWUpXG5cdFx0fSlcblx0XHRzdG9yZS5jbGVhciA9IHdpdGhJRVN0b3JhZ2UoZnVuY3Rpb24oc3RvcmFnZSkge1xuXHRcdFx0dmFyIGF0dHJpYnV0ZXMgPSBzdG9yYWdlLlhNTERvY3VtZW50LmRvY3VtZW50RWxlbWVudC5hdHRyaWJ1dGVzXG5cdFx0XHRzdG9yYWdlLmxvYWQobG9jYWxTdG9yYWdlTmFtZSlcblx0XHRcdGZvciAodmFyIGk9MCwgYXR0cjsgYXR0cj1hdHRyaWJ1dGVzW2ldOyBpKyspIHtcblx0XHRcdFx0c3RvcmFnZS5yZW1vdmVBdHRyaWJ1dGUoYXR0ci5uYW1lKVxuXHRcdFx0fVxuXHRcdFx0c3RvcmFnZS5zYXZlKGxvY2FsU3RvcmFnZU5hbWUpXG5cdFx0fSlcblx0XHRzdG9yZS5nZXRBbGwgPSBmdW5jdGlvbihzdG9yYWdlKSB7XG5cdFx0XHR2YXIgcmV0ID0ge31cblx0XHRcdHN0b3JlLmZvckVhY2goZnVuY3Rpb24oa2V5LCB2YWwpIHtcblx0XHRcdFx0cmV0W2tleV0gPSB2YWxcblx0XHRcdH0pXG5cdFx0XHRyZXR1cm4gcmV0XG5cdFx0fVxuXHRcdHN0b3JlLmZvckVhY2ggPSB3aXRoSUVTdG9yYWdlKGZ1bmN0aW9uKHN0b3JhZ2UsIGNhbGxiYWNrKSB7XG5cdFx0XHR2YXIgYXR0cmlidXRlcyA9IHN0b3JhZ2UuWE1MRG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmF0dHJpYnV0ZXNcblx0XHRcdGZvciAodmFyIGk9MCwgYXR0cjsgYXR0cj1hdHRyaWJ1dGVzW2ldOyArK2kpIHtcblx0XHRcdFx0Y2FsbGJhY2soYXR0ci5uYW1lLCBzdG9yZS5kZXNlcmlhbGl6ZShzdG9yYWdlLmdldEF0dHJpYnV0ZShhdHRyLm5hbWUpKSlcblx0XHRcdH1cblx0XHR9KVxuXHR9XG5cblx0dHJ5IHtcblx0XHR2YXIgdGVzdEtleSA9ICdfX3N0b3JlanNfXydcblx0XHRzdG9yZS5zZXQodGVzdEtleSwgdGVzdEtleSlcblx0XHRpZiAoc3RvcmUuZ2V0KHRlc3RLZXkpICE9IHRlc3RLZXkpIHsgc3RvcmUuZGlzYWJsZWQgPSB0cnVlIH1cblx0XHRzdG9yZS5yZW1vdmUodGVzdEtleSlcblx0fSBjYXRjaChlKSB7XG5cdFx0c3RvcmUuZGlzYWJsZWQgPSB0cnVlXG5cdH1cblx0c3RvcmUuZW5hYmxlZCA9ICFzdG9yZS5kaXNhYmxlZFxuXG5cdGlmICh0eXBlb2YgbW9kdWxlICE9ICd1bmRlZmluZWQnICYmIG1vZHVsZS5leHBvcnRzICYmIHRoaXMubW9kdWxlICE9PSBtb2R1bGUpIHsgbW9kdWxlLmV4cG9ydHMgPSBzdG9yZSB9XG5cdGVsc2UgaWYgKHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCkgeyBkZWZpbmUoc3RvcmUpIH1cblx0ZWxzZSB7IHdpbi5zdG9yZSA9IHN0b3JlIH1cblxufSkoRnVuY3Rpb24oJ3JldHVybiB0aGlzJykoKSk7XG4iLCJtb2R1bGUuZXhwb3J0cz17XG4gIFwibmFtZVwiOiBcInlhc2d1aS11dGlsc1wiLFxuICBcInZlcnNpb25cIjogXCIxLjYuMFwiLFxuICBcImRlc2NyaXB0aW9uXCI6IFwiVXRpbHMgZm9yIFlBU0dVSSBsaWJzXCIsXG4gIFwibWFpblwiOiBcInNyYy9tYWluLmpzXCIsXG4gIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgXCJ0eXBlXCI6IFwiZ2l0XCIsXG4gICAgXCJ1cmxcIjogXCJnaXQ6Ly9naXRodWIuY29tL1lBU0dVSS9VdGlscy5naXRcIlxuICB9LFxuICBcImxpY2Vuc2VzXCI6IFtcbiAgICB7XG4gICAgICBcInR5cGVcIjogXCJNSVRcIixcbiAgICAgIFwidXJsXCI6IFwiaHR0cDovL3lhc2d1aS5naXRodWIuaW8vbGljZW5zZS50eHRcIlxuICAgIH1cbiAgXSxcbiAgXCJhdXRob3JcIjogXCJMYXVyZW5zIFJpZXR2ZWxkXCIsXG4gIFwibWFpbnRhaW5lcnNcIjogW1xuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcIkxhdXJlbnMgUmlldHZlbGRcIixcbiAgICAgIFwiZW1haWxcIjogXCJsYXVyZW5zLnJpZXR2ZWxkQGdtYWlsLmNvbVwiLFxuICAgICAgXCJ3ZWJcIjogXCJodHRwOi8vbGF1cmVuc3JpZXR2ZWxkLm5sXCJcbiAgICB9XG4gIF0sXG4gIFwiYnVnc1wiOiB7XG4gICAgXCJ1cmxcIjogXCJodHRwczovL2dpdGh1Yi5jb20vWUFTR1VJL1V0aWxzL2lzc3Vlc1wiXG4gIH0sXG4gIFwiaG9tZXBhZ2VcIjogXCJodHRwczovL2dpdGh1Yi5jb20vWUFTR1VJL1V0aWxzXCIsXG4gIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcInN0b3JlXCI6IFwiXjEuMy4xNFwiXG4gIH1cbn1cbiIsIndpbmRvdy5jb25zb2xlID0gd2luZG93LmNvbnNvbGUgfHwge1wibG9nXCI6ZnVuY3Rpb24oKXt9fTsvL21ha2Ugc3VyZSBhbnkgY29uc29sZSBzdGF0ZW1lbnRzIGRvbid0IGJyZWFrIElFXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0c3RvcmFnZTogcmVxdWlyZShcIi4vc3RvcmFnZS5qc1wiKSxcblx0c3ZnOiByZXF1aXJlKFwiLi9zdmcuanNcIiksXG5cdHZlcnNpb246IHtcblx0XHRcInlhc2d1aS11dGlsc1wiIDogcmVxdWlyZShcIi4uL3BhY2thZ2UuanNvblwiKS52ZXJzaW9uLFxuXHR9LFxuXHRuZXN0ZWRFeGlzdHMgOiBmdW5jdGlvbihvYmopIHtcblx0XHR2YXIgYXJncyA9IEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywgMSk7XG5cblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IGFyZ3MubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmICghb2JqIHx8ICFvYmouaGFzT3duUHJvcGVydHkoYXJnc1tpXSkpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXHRcdFx0b2JqID0gb2JqW2FyZ3NbaV1dO1xuXHRcdH1cblx0XHRyZXR1cm4gdHJ1ZTtcblx0fVxufTtcbiIsInZhciBzdG9yZSA9IHJlcXVpcmUoXCJzdG9yZVwiKTtcbnZhciB0aW1lcyA9IHtcblx0ZGF5OiBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gMTAwMCAqIDM2MDAgKiAyNDsvL21pbGxpcyB0byBkYXlcblx0fSxcblx0bW9udGg6IGZ1bmN0aW9uKCkge1xuXHRcdHRpbWVzLmRheSgpICogMzA7XG5cdH0sXG5cdHllYXI6IGZ1bmN0aW9uKCkge1xuXHRcdHRpbWVzLm1vbnRoKCkgKiAxMjtcblx0fVxufTtcblxudmFyIHJvb3QgPSBtb2R1bGUuZXhwb3J0cyA9IHtcblx0c2V0IDogZnVuY3Rpb24oa2V5LCB2YWwsIGV4cCkge1xuICAgIGlmICghc3RvcmUuZW5hYmxlZCkgcmV0dXJuOy8vdGhpcyBpcyBwcm9iYWJseSBpbiBwcml2YXRlIG1vZGUuIERvbid0IHJ1biwgYXMgd2UgbWlnaHQgZ2V0IEpzIGVycm9yc1xuXHRcdGlmIChrZXkgJiYgdmFsICE9PSB1bmRlZmluZWQpIHtcblx0XHRcdGlmICh0eXBlb2YgZXhwID09IFwic3RyaW5nXCIpIHtcblx0XHRcdFx0ZXhwID0gdGltZXNbZXhwXSgpO1xuXHRcdFx0fVxuXHRcdFx0Ly90cnkgdG8gc3RvcmUgc3RyaW5nIGZvciBkb20gb2JqZWN0cyAoZS5nLiBYTUwgcmVzdWx0KS4gT3RoZXJ3aXNlLCB3ZSBtaWdodCBnZXQgYSBjaXJjdWxhciByZWZlcmVuY2UgZXJyb3Igd2hlbiBzdHJpbmdpZnlpbmcgdGhpc1xuXHRcdFx0aWYgKHZhbC5kb2N1bWVudEVsZW1lbnQpIHZhbCA9IG5ldyBYTUxTZXJpYWxpemVyKCkuc2VyaWFsaXplVG9TdHJpbmcodmFsLmRvY3VtZW50RWxlbWVudCk7XG5cdFx0XHRzdG9yZS5zZXQoa2V5LCB7XG5cdFx0XHRcdHZhbCA6IHZhbCxcblx0XHRcdFx0ZXhwIDogZXhwLFxuXHRcdFx0XHR0aW1lIDogbmV3IERhdGUoKS5nZXRUaW1lKClcblx0XHRcdH0pO1xuXHRcdH1cblx0fSxcblx0cmVtb3ZlOiBmdW5jdGlvbihrZXkpIHtcblx0XHRpZiAoIXN0b3JlLmVuYWJsZWQpIHJldHVybjsvL3RoaXMgaXMgcHJvYmFibHkgaW4gcHJpdmF0ZSBtb2RlLiBEb24ndCBydW4sIGFzIHdlIG1pZ2h0IGdldCBKcyBlcnJvcnNcblx0XHRpZiAoa2V5KSBzdG9yZS5yZW1vdmUoa2V5KVxuXHR9LFxuXHRyZW1vdmVBbGw6IGZ1bmN0aW9uKGZpbHRlcikge1xuXHRcdGlmICghc3RvcmUuZW5hYmxlZCkgcmV0dXJuOy8vdGhpcyBpcyBwcm9iYWJseSBpbiBwcml2YXRlIG1vZGUuIERvbid0IHJ1biwgYXMgd2UgbWlnaHQgZ2V0IEpzIGVycm9yc1xuXHRcdGlmICh0eXBlb2YgZmlsdGVyID09PSAnZnVuY3Rpb24nKSB7XG5cdFx0XHRmb3IgKHZhciBrZXkgaW4gc3RvcmUuZ2V0QWxsKCkpIHtcblx0XHRcdFx0aWYgKGZpbHRlcihrZXksIHJvb3QuZ2V0KGtleSkpKSByb290LnJlbW92ZShrZXkpO1xuXHRcdFx0fVxuXHRcdH1cblx0fSxcblx0Z2V0IDogZnVuY3Rpb24oa2V5KSB7XG4gICAgaWYgKCFzdG9yZS5lbmFibGVkKSByZXR1cm4gbnVsbDsvL3RoaXMgaXMgcHJvYmFibHkgaW4gcHJpdmF0ZSBtb2RlLiBEb24ndCBydW4sIGFzIHdlIG1pZ2h0IGdldCBKcyBlcnJvcnNcblx0XHRpZiAoa2V5KSB7XG5cdFx0XHR2YXIgaW5mbyA9IHN0b3JlLmdldChrZXkpO1xuXHRcdFx0aWYgKCFpbmZvKSB7XG5cdFx0XHRcdHJldHVybiBudWxsO1xuXHRcdFx0fVxuXHRcdFx0aWYgKGluZm8uZXhwICYmIG5ldyBEYXRlKCkuZ2V0VGltZSgpIC0gaW5mby50aW1lID4gaW5mby5leHApIHtcblx0XHRcdFx0cmV0dXJuIG51bGw7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gaW5mby52YWw7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBudWxsO1xuXHRcdH1cblx0fVxuXG59O1xuIiwibW9kdWxlLmV4cG9ydHMgPSB7XG5cdGRyYXc6IGZ1bmN0aW9uKHBhcmVudCwgc3ZnU3RyaW5nKSB7XG5cdFx0aWYgKCFwYXJlbnQpIHJldHVybjtcblx0XHR2YXIgZWwgPSBtb2R1bGUuZXhwb3J0cy5nZXRFbGVtZW50KHN2Z1N0cmluZyk7XG5cdFx0aWYgKGVsKSB7XG5cdFx0XHRpZiAocGFyZW50LmFwcGVuZCkge1xuXHRcdFx0XHRwYXJlbnQuYXBwZW5kKGVsKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdC8vcmVndWxhciBkb20gZG9jXG5cdFx0XHRcdHBhcmVudC5hcHBlbmRDaGlsZChlbCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9LFxuXHRnZXRFbGVtZW50OiBmdW5jdGlvbihzdmdTdHJpbmcpIHtcblx0XHRpZiAoc3ZnU3RyaW5nICYmIHN2Z1N0cmluZy5pbmRleE9mKFwiPHN2Z1wiKSA9PSAwKSB7XG5cdFx0XHQvL25vIHN0eWxlIHBhc3NlZCB2aWEgY29uZmlnLiBndWVzcyBvd24gc3R5bGVzXG5cdFx0XHR2YXIgcGFyc2VyID0gbmV3IERPTVBhcnNlcigpO1xuXHRcdFx0dmFyIGRvbSA9IHBhcnNlci5wYXJzZUZyb21TdHJpbmcoc3ZnU3RyaW5nLCBcInRleHQveG1sXCIpO1xuXHRcdFx0dmFyIHN2ZyA9IGRvbS5kb2N1bWVudEVsZW1lbnQ7XG5cdFx0XHRcblx0XHRcdHZhciBzdmdDb250YWluZXIgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KFwiZGl2XCIpO1xuXHRcdFx0c3ZnQ29udGFpbmVyLmNsYXNzTmFtZSA9ICdzdmdJbWcnO1xuXHRcdFx0c3ZnQ29udGFpbmVyLmFwcGVuZENoaWxkKHN2Zyk7XG5cdFx0XHRyZXR1cm4gc3ZnQ29udGFpbmVyO1xuXHRcdH1cblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07IiwibW9kdWxlLmV4cG9ydHM9e1xuICBcIm5hbWVcIjogXCJ5YXNndWkteWFzcWVcIixcbiAgXCJkZXNjcmlwdGlvblwiOiBcIllldCBBbm90aGVyIFNQQVJRTCBRdWVyeSBFZGl0b3JcIixcbiAgXCJ2ZXJzaW9uXCI6IFwiMi42LjNcIixcbiAgXCJtYWluXCI6IFwic3JjL21haW4uanNcIixcbiAgXCJsaWNlbnNlXCI6IFwiTUlUXCIsXG4gIFwiYXV0aG9yXCI6IFwiTGF1cmVucyBSaWV0dmVsZFwiLFxuICBcImhvbWVwYWdlXCI6IFwiaHR0cDovL3lhc3FlLnlhc2d1aS5vcmdcIixcbiAgXCJkZXZEZXBlbmRlbmNpZXNcIjoge1xuICAgIFwiYnJvd3NlcmlmeVwiOiBcIl42LjEuMFwiLFxuICAgIFwiZ3VscFwiOiBcIn4zLjYuMFwiLFxuICAgIFwiZ3VscC1idW1wXCI6IFwiXjAuMS4xMVwiLFxuICAgIFwiZ3VscC1jb25jYXRcIjogXCJeMi40LjFcIixcbiAgICBcImd1bHAtY29ubmVjdFwiOiBcIl4yLjAuNVwiLFxuICAgIFwiZ3VscC1lbWJlZGxyXCI6IFwiXjAuNS4yXCIsXG4gICAgXCJndWxwLWZpbHRlclwiOiBcIl4xLjAuMlwiLFxuICAgIFwiZ3VscC1naXRcIjogXCJeMC41LjJcIixcbiAgICBcImd1bHAtanN2YWxpZGF0ZVwiOiBcIl4wLjIuMFwiLFxuICAgIFwiZ3VscC1saXZlcmVsb2FkXCI6IFwiXjEuMy4xXCIsXG4gICAgXCJndWxwLW1pbmlmeS1jc3NcIjogXCIwLjMuMTFcIixcbiAgICBcImd1bHAtbm90aWZ5XCI6IFwiXjIuMC4xXCIsXG4gICAgXCJndWxwLXJlbmFtZVwiOiBcIl4xLjIuMFwiLFxuICAgIFwiZ3VscC1zdHJlYW1pZnlcIjogXCIwLjAuNVwiLFxuICAgIFwiZ3VscC10YWctdmVyc2lvblwiOiBcIl4xLjEuMFwiLFxuICAgIFwiZ3VscC11Z2xpZnlcIjogXCJeMS4wLjFcIixcbiAgICBcInJlcXVpcmUtZGlyXCI6IFwiXjAuMS4wXCIsXG4gICAgXCJydW4tc2VxdWVuY2VcIjogXCJeMS4wLjFcIixcbiAgICBcInZpbnlsLWJ1ZmZlclwiOiBcIl4xLjAuMFwiLFxuICAgIFwidmlueWwtc291cmNlLXN0cmVhbVwiOiBcIn4wLjEuMVwiLFxuICAgIFwid2F0Y2hpZnlcIjogXCJeMC42LjRcIixcbiAgICBcImd1bHAtc291cmNlbWFwc1wiOiBcIl4xLjIuOFwiLFxuICAgIFwiZXhvcmNpc3RcIjogXCJeMC4xLjZcIixcbiAgICBcInZpbnlsLXRyYW5zZm9ybVwiOiBcIjAuMC4xXCIsXG4gICAgXCJndWxwLXNhc3NcIjogXCJeMi4wLjFcIixcbiAgICBcImJvb3RzdHJhcC1zYXNzXCI6IFwiXjMuMy4xXCIsXG4gICAgXCJicm93c2VyaWZ5LXRyYW5zZm9ybS10b29sc1wiOiBcIl4xLjIuMVwiLFxuICAgIFwiZ3VscC1jc3NpbXBvcnRcIjogXCJeMS4zLjFcIlxuICB9LFxuICBcImJ1Z3NcIjogXCJodHRwczovL2dpdGh1Yi5jb20vWUFTR1VJL1lBU1FFL2lzc3Vlcy9cIixcbiAgXCJrZXl3b3Jkc1wiOiBbXG4gICAgXCJKYXZhU2NyaXB0XCIsXG4gICAgXCJTUEFSUUxcIixcbiAgICBcIkVkaXRvclwiLFxuICAgIFwiU2VtYW50aWMgV2ViXCIsXG4gICAgXCJMaW5rZWQgRGF0YVwiXG4gIF0sXG4gIFwibWFpbnRhaW5lcnNcIjogW1xuICAgIHtcbiAgICAgIFwibmFtZVwiOiBcIkxhdXJlbnMgUmlldHZlbGRcIixcbiAgICAgIFwiZW1haWxcIjogXCJsYXVyZW5zLnJpZXR2ZWxkQGdtYWlsLmNvbVwiLFxuICAgICAgXCJ3ZWJcIjogXCJodHRwOi8vbGF1cmVuc3JpZXR2ZWxkLm5sXCJcbiAgICB9XG4gIF0sXG4gIFwicmVwb3NpdG9yeVwiOiB7XG4gICAgXCJ0eXBlXCI6IFwiZ2l0XCIsXG4gICAgXCJ1cmxcIjogXCJodHRwczovL2dpdGh1Yi5jb20vWUFTR1VJL1lBU1FFLmdpdFwiXG4gIH0sXG4gIFwiZGVwZW5kZW5jaWVzXCI6IHtcbiAgICBcImpxdWVyeVwiOiBcIn4gMS4xMS4wXCIsXG4gICAgXCJjb2RlbWlycm9yXCI6IFwiXjQuNy4wXCIsXG4gICAgXCJ5YXNndWktdXRpbHNcIjogXCJeMS40LjFcIlxuICB9LFxuICBcIm9wdGlvbmFsU2hpbVwiOiB7XG4gICAgXCJjb2RlbWlycm9yXCI6IHtcbiAgICAgIFwicmVxdWlyZVwiOiBcImNvZGVtaXJyb3JcIixcbiAgICAgIFwiZ2xvYmFsXCI6IFwiQ29kZU1pcnJvclwiXG4gICAgfSxcbiAgICBcImpxdWVyeVwiOiB7XG4gICAgICBcInJlcXVpcmVcIjogXCJqcXVlcnlcIixcbiAgICAgIFwiZ2xvYmFsXCI6IFwialF1ZXJ5XCJcbiAgICB9LFxuICAgIFwiLi4vLi4vbGliL2NvZGVtaXJyb3JcIjoge1xuICAgICAgXCJyZXF1aXJlXCI6IFwiY29kZW1pcnJvclwiLFxuICAgICAgXCJnbG9iYWxcIjogXCJDb2RlTWlycm9yXCJcbiAgICB9XG4gIH1cbn1cbiIsIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnanF1ZXJ5JyksXG5cdHV0aWxzID0gcmVxdWlyZSgnLi4vdXRpbHMuanMnKSxcblx0eXV0aWxzID0gcmVxdWlyZSgneWFzZ3VpLXV0aWxzJyksXG5cdFRyaWUgPSByZXF1aXJlKCcuLi8uLi9saWIvdHJpZS5qcycpLFxuXHRZQVNRRSA9IHJlcXVpcmUoJy4uL21haW4uanMnKTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbihZQVNRRSwgeWFzcWUpIHtcblx0dmFyIGNvbXBsZXRpb25Ob3RpZmljYXRpb25zID0ge307XG5cdHZhciBjb21wbGV0ZXJzID0ge307XG5cdHZhciB0cmllcyA9IHt9O1xuXG5cdHlhc3FlLm9uKCdjdXJzb3JBY3Rpdml0eScsIGZ1bmN0aW9uKHlhc3FlLCBldmVudEluZm8pIHtcblx0XHRhdXRvQ29tcGxldGUodHJ1ZSk7XG5cdH0pO1xuXHR5YXNxZS5vbignY2hhbmdlJywgZnVuY3Rpb24oKSB7XG5cdFx0dmFyIG5lZWRQb3NzaWJsZUFkanVzdG1lbnQgPSBbXTtcblx0XHRmb3IgKHZhciBub3RpZmljYXRpb25OYW1lIGluIGNvbXBsZXRpb25Ob3RpZmljYXRpb25zKSB7XG5cdFx0XHRpZiAoY29tcGxldGlvbk5vdGlmaWNhdGlvbnNbbm90aWZpY2F0aW9uTmFtZV0uaXMoJzp2aXNpYmxlJykpIHtcblx0XHRcdFx0bmVlZFBvc3NpYmxlQWRqdXN0bWVudC5wdXNoKGNvbXBsZXRpb25Ob3RpZmljYXRpb25zW25vdGlmaWNhdGlvbk5hbWVdKTtcblx0XHRcdH1cblx0XHR9XG5cdFx0aWYgKG5lZWRQb3NzaWJsZUFkanVzdG1lbnQubGVuZ3RoID4gMCkge1xuXHRcdFx0Ly9wb3NpdGlvbiBjb21wbGV0aW9uIG5vdGlmaWNhdGlvbnNcblx0XHRcdHZhciBzY3JvbGxCYXIgPSAkKHlhc3FlLmdldFdyYXBwZXJFbGVtZW50KCkpLmZpbmQoXCIuQ29kZU1pcnJvci12c2Nyb2xsYmFyXCIpO1xuXHRcdFx0dmFyIG9mZnNldCA9IDA7XG5cdFx0XHRpZiAoc2Nyb2xsQmFyLmlzKFwiOnZpc2libGVcIikpIHtcblx0XHRcdFx0b2Zmc2V0ID0gc2Nyb2xsQmFyLm91dGVyV2lkdGgoKTtcblx0XHRcdH1cblx0XHRcdG5lZWRQb3NzaWJsZUFkanVzdG1lbnQuZm9yRWFjaChmdW5jdGlvbihub3RpZmljYXRpb24pIHtcblx0XHRcdFx0bm90aWZpY2F0aW9uLmNzcyhcInJpZ2h0XCIsIG9mZnNldClcblx0XHRcdH0pO1xuXHRcdH1cblx0fSk7XG5cblxuXG5cdC8qKlxuXHQgKiBTdG9yZSBidWxrIGNvbXBsZXRpb25zIGluIG1lbW9yeSBhcyB0cmllLCBhbmQgc3RvcmUgdGhlc2UgaW4gbG9jYWxzdG9yYWdlIGFzIHdlbGwgKGlmIGVuYWJsZWQpXG5cdCAqIFxuXHQgKiBAbWV0aG9kIGRvYy5zdG9yZUJ1bGtDb21wbGV0aW9uc1xuXHQgKiBAcGFyYW0gY29tcGxldGlvbnMge2FycmF5fVxuXHQgKi9cblx0dmFyIHN0b3JlQnVsa0NvbXBsZXRpb25zID0gZnVuY3Rpb24oY29tcGxldGVyLCBjb21wbGV0aW9ucykge1xuXHRcdC8vIHN0b3JlIGFycmF5IGFzIHRyaWVcblx0XHR0cmllc1tjb21wbGV0ZXIubmFtZV0gPSBuZXcgVHJpZSgpO1xuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgY29tcGxldGlvbnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdHRyaWVzW2NvbXBsZXRlci5uYW1lXS5pbnNlcnQoY29tcGxldGlvbnNbaV0pO1xuXHRcdH1cblx0XHQvLyBzdG9yZSBpbiBsb2NhbHN0b3JhZ2UgYXMgd2VsbFxuXHRcdHZhciBzdG9yYWdlSWQgPSB1dGlscy5nZXRQZXJzaXN0ZW5jeUlkKHlhc3FlLCBjb21wbGV0ZXIucGVyc2lzdGVudCk7XG5cdFx0aWYgKHN0b3JhZ2VJZCkgeXV0aWxzLnN0b3JhZ2Uuc2V0KHN0b3JhZ2VJZCwgY29tcGxldGlvbnMsIFwibW9udGhcIik7XG5cdH07XG5cblx0dmFyIGluaXRDb21wbGV0ZXIgPSBmdW5jdGlvbihuYW1lLCBjb21wbGV0aW9uSW5pdCkge1xuXHRcdHZhciBjb21wbGV0ZXIgPSBjb21wbGV0ZXJzW25hbWVdID0gbmV3IGNvbXBsZXRpb25Jbml0KHlhc3FlLCBuYW1lKTtcblx0XHRjb21wbGV0ZXIubmFtZSA9IG5hbWU7XG5cdFx0aWYgKGNvbXBsZXRlci5idWxrKSB7XG5cdFx0XHR2YXIgc3RvcmVBcnJheUFzQnVsayA9IGZ1bmN0aW9uKHN1Z2dlc3Rpb25zKSB7XG5cdFx0XHRcdGlmIChzdWdnZXN0aW9ucyAmJiBzdWdnZXN0aW9ucyBpbnN0YW5jZW9mIEFycmF5ICYmIHN1Z2dlc3Rpb25zLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRzdG9yZUJ1bGtDb21wbGV0aW9ucyhjb21wbGV0ZXIsIHN1Z2dlc3Rpb25zKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdFx0aWYgKGNvbXBsZXRlci5nZXQgaW5zdGFuY2VvZiBBcnJheSkge1xuXHRcdFx0XHQvLyB3ZSBkb24ndCBjYXJlIHdoZXRoZXIgdGhlIGNvbXBsZXRpb25zIGFyZSBhbHJlYWR5IHN0b3JlZCBpblxuXHRcdFx0XHQvLyBsb2NhbHN0b3JhZ2UuIGp1c3QgdXNlIHRoaXMgb25lXG5cdFx0XHRcdHN0b3JlQXJyYXlBc0J1bGsoY29tcGxldGVyLmdldCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHQvLyBpZiBjb21wbGV0aW9ucyBhcmUgZGVmaW5lZCBpbiBsb2NhbHN0b3JhZ2UsIHVzZSB0aG9zZSEgKGNhbGxpbmcgdGhlXG5cdFx0XHRcdC8vIGZ1bmN0aW9uIG1heSBjb21lIHdpdGggb3ZlcmhlYWQgKGUuZy4gYXN5bmMgY2FsbHMpKVxuXHRcdFx0XHR2YXIgY29tcGxldGlvbnNGcm9tU3RvcmFnZSA9IG51bGw7XG5cdFx0XHRcdHZhciBwZXJzaXN0ZW5jeUlkZW50aWZpZXIgPSB1dGlscy5nZXRQZXJzaXN0ZW5jeUlkKHlhc3FlLCBjb21wbGV0ZXIucGVyc2lzdGVudCk7XG5cdFx0XHRcdGlmIChwZXJzaXN0ZW5jeUlkZW50aWZpZXIpXG5cdFx0XHRcdFx0Y29tcGxldGlvbnNGcm9tU3RvcmFnZSA9IHl1dGlscy5zdG9yYWdlLmdldChwZXJzaXN0ZW5jeUlkZW50aWZpZXIpO1xuXHRcdFx0XHRpZiAoY29tcGxldGlvbnNGcm9tU3RvcmFnZSAmJiBjb21wbGV0aW9uc0Zyb21TdG9yYWdlLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRzdG9yZUFycmF5QXNCdWxrKGNvbXBsZXRpb25zRnJvbVN0b3JhZ2UpO1xuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdC8vIG5vdGhpbmcgaW4gc3RvcmFnZS4gY2hlY2sgd2hldGhlciB3ZSBoYXZlIGEgZnVuY3Rpb24gdmlhIHdoaWNoIHdlXG5cdFx0XHRcdFx0Ly8gY2FuIGdldCBvdXIgcHJlZml4ZXNcblx0XHRcdFx0XHRpZiAoY29tcGxldGVyLmdldCBpbnN0YW5jZW9mIEZ1bmN0aW9uKSB7XG5cdFx0XHRcdFx0XHRpZiAoY29tcGxldGVyLmFzeW5jKSB7XG5cdFx0XHRcdFx0XHRcdGNvbXBsZXRlci5nZXQobnVsbCwgc3RvcmVBcnJheUFzQnVsayk7XG5cdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRzdG9yZUFycmF5QXNCdWxrKGNvbXBsZXRlci5nZXQoKSk7XG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xuXG5cdHZhciBhdXRvQ29tcGxldGUgPSBmdW5jdGlvbihmcm9tQXV0b1Nob3cpIHtcblx0XHRpZiAoeWFzcWUuc29tZXRoaW5nU2VsZWN0ZWQoKSlcblx0XHRcdHJldHVybjtcblx0XHR2YXIgdHJ5SGludFR5cGUgPSBmdW5jdGlvbihjb21wbGV0ZXIpIHtcblx0XHRcdGlmIChmcm9tQXV0b1Nob3cgLy8gZnJvbSBhdXRvU2hvdywgaS5lLiB0aGlzIGdldHMgY2FsbGVkIGVhY2ggdGltZSB0aGUgZWRpdG9yIGNvbnRlbnQgY2hhbmdlc1xuXHRcdFx0XHQmJiAoIWNvbXBsZXRlci5hdXRvU2hvdyAvLyBhdXRvc2hvdyBmb3IgIHRoaXMgcGFydGljdWxhciB0eXBlIG9mIGF1dG9jb21wbGV0aW9uIGlzIC1ub3QtIGVuYWJsZWRcblx0XHRcdFx0XHR8fCAoIWNvbXBsZXRlci5idWxrICYmIGNvbXBsZXRlci5hc3luYykpIC8vIGFzeW5jIGlzIGVuYWJsZWQgKGRvbid0IHdhbnQgdG8gcmUtZG8gYWpheC1saWtlIHJlcXVlc3QgZm9yIGV2ZXJ5IGVkaXRvciBjaGFuZ2UpXG5cdFx0XHQpIHtcblx0XHRcdFx0cmV0dXJuIGZhbHNlO1xuXHRcdFx0fVxuXG5cdFx0XHR2YXIgaGludENvbmZpZyA9IHtcblx0XHRcdFx0Y2xvc2VDaGFyYWN0ZXJzOiAvKD89YSliLyxcblx0XHRcdFx0Y29tcGxldGVTaW5nbGU6IGZhbHNlXG5cdFx0XHR9O1xuXHRcdFx0aWYgKCFjb21wbGV0ZXIuYnVsayAmJiBjb21wbGV0ZXIuYXN5bmMpIHtcblx0XHRcdFx0aGludENvbmZpZy5hc3luYyA9IHRydWU7XG5cdFx0XHR9XG5cdFx0XHR2YXIgd3JhcHBlZEhpbnRDYWxsYmFjayA9IGZ1bmN0aW9uKHlhc3FlLCBjYWxsYmFjaykge1xuXHRcdFx0XHRyZXR1cm4gZ2V0Q29tcGxldGlvbkhpbnRzT2JqZWN0KGNvbXBsZXRlciwgY2FsbGJhY2spO1xuXHRcdFx0fTtcblx0XHRcdHZhciByZXN1bHQgPSBZQVNRRS5zaG93SGludCh5YXNxZSwgd3JhcHBlZEhpbnRDYWxsYmFjaywgaGludENvbmZpZyk7XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHR9O1xuXHRcdGZvciAodmFyIGNvbXBsZXRlck5hbWUgaW4gY29tcGxldGVycykge1xuXHRcdFx0aWYgKCQuaW5BcnJheShjb21wbGV0ZXJOYW1lLCB5YXNxZS5vcHRpb25zLmF1dG9jb21wbGV0ZXJzKSA9PSAtMSkgY29udGludWU7IC8vdGhpcyBjb21wbGV0ZXIgaXMgZGlzYWJsZWRcblx0XHRcdHZhciBjb21wbGV0ZXIgPSBjb21wbGV0ZXJzW2NvbXBsZXRlck5hbWVdO1xuXHRcdFx0aWYgKCFjb21wbGV0ZXIuaXNWYWxpZENvbXBsZXRpb25Qb3NpdGlvbikgY29udGludWU7IC8vbm8gd2F5IHRvIGNoZWNrIHdoZXRoZXIgd2UgYXJlIGluIGEgdmFsaWQgcG9zaXRpb25cblxuXHRcdFx0aWYgKCFjb21wbGV0ZXIuaXNWYWxpZENvbXBsZXRpb25Qb3NpdGlvbigpKSB7XG5cdFx0XHRcdC8vaWYgbmVlZGVkLCBmaXJlIGNhbGxiYWNrcyBmb3Igd2hlbiB3ZSBhcmUgLW5vdC0gaW4gdmFsaWQgY29tcGxldGlvbiBwb3NpdGlvblxuXHRcdFx0XHRpZiAoY29tcGxldGVyLmNhbGxiYWNrcyAmJiBjb21wbGV0ZXIuY2FsbGJhY2tzLmludmFsaWRQb3NpdGlvbikge1xuXHRcdFx0XHRcdGNvbXBsZXRlci5jYWxsYmFja3MuaW52YWxpZFBvc2l0aW9uKHlhc3FlLCBjb21wbGV0ZXIpO1xuXHRcdFx0XHR9XG5cdFx0XHRcdC8vbm90IGluIGEgdmFsaWQgcG9zaXRpb24sIHNvIGNvbnRpbnVlIHRvIG5leHQgY29tcGxldGlvbiBjYW5kaWRhdGUgdHlwZVxuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblx0XHRcdC8vIHJ1biB2YWxpZCBwb3NpdGlvbiBoYW5kbGVyLCBpZiB0aGVyZSBpcyBvbmUgKGlmIGl0IHJldHVybnMgZmFsc2UsIHN0b3AgdGhlIGF1dG9jb21wbGV0aW9uISlcblx0XHRcdGlmIChjb21wbGV0ZXIuY2FsbGJhY2tzICYmIGNvbXBsZXRlci5jYWxsYmFja3MudmFsaWRQb3NpdGlvbikge1xuXHRcdFx0XHRpZiAoY29tcGxldGVyLmNhbGxiYWNrcy52YWxpZFBvc2l0aW9uKHlhc3FlLCBjb21wbGV0ZXIpID09PSBmYWxzZSlcblx0XHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblx0XHRcdHZhciBzdWNjZXNzID0gdHJ5SGludFR5cGUoY29tcGxldGVyKTtcblx0XHRcdGlmIChzdWNjZXNzKVxuXHRcdFx0XHRicmVhaztcblx0XHR9XG5cdH07XG5cblxuXG5cdHZhciBnZXRDb21wbGV0aW9uSGludHNPYmplY3QgPSBmdW5jdGlvbihjb21wbGV0ZXIsIGNhbGxiYWNrKSB7XG5cdFx0dmFyIGdldFN1Z2dlc3Rpb25zRnJvbVRva2VuID0gZnVuY3Rpb24ocGFydGlhbFRva2VuKSB7XG5cdFx0XHR2YXIgc3RyaW5nVG9BdXRvY29tcGxldGUgPSBwYXJ0aWFsVG9rZW4uYXV0b2NvbXBsZXRpb25TdHJpbmcgfHwgcGFydGlhbFRva2VuLnN0cmluZztcblx0XHRcdHZhciBzdWdnZXN0aW9ucyA9IFtdO1xuXHRcdFx0aWYgKHRyaWVzW2NvbXBsZXRlci5uYW1lXSkge1xuXHRcdFx0XHRzdWdnZXN0aW9ucyA9IHRyaWVzW2NvbXBsZXRlci5uYW1lXS5hdXRvQ29tcGxldGUoc3RyaW5nVG9BdXRvY29tcGxldGUpO1xuXHRcdFx0fSBlbHNlIGlmICh0eXBlb2YgY29tcGxldGVyLmdldCA9PSBcImZ1bmN0aW9uXCIgJiYgY29tcGxldGVyLmFzeW5jID09IGZhbHNlKSB7XG5cdFx0XHRcdHN1Z2dlc3Rpb25zID0gY29tcGxldGVyLmdldChzdHJpbmdUb0F1dG9jb21wbGV0ZSk7XG5cdFx0XHR9IGVsc2UgaWYgKHR5cGVvZiBjb21wbGV0ZXIuZ2V0ID09IFwib2JqZWN0XCIpIHtcblx0XHRcdFx0dmFyIHBhcnRpYWxUb2tlbkxlbmd0aCA9IHN0cmluZ1RvQXV0b2NvbXBsZXRlLmxlbmd0aDtcblx0XHRcdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBjb21wbGV0ZXIuZ2V0Lmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0dmFyIGNvbXBsZXRpb24gPSBjb21wbGV0ZXIuZ2V0W2ldO1xuXHRcdFx0XHRcdGlmIChjb21wbGV0aW9uLnNsaWNlKDAsIHBhcnRpYWxUb2tlbkxlbmd0aCkgPT0gc3RyaW5nVG9BdXRvY29tcGxldGUpIHtcblx0XHRcdFx0XHRcdHN1Z2dlc3Rpb25zLnB1c2goY29tcGxldGlvbik7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZ2V0U3VnZ2VzdGlvbnNBc0hpbnRPYmplY3Qoc3VnZ2VzdGlvbnMsIGNvbXBsZXRlciwgcGFydGlhbFRva2VuKTtcblxuXHRcdH07XG5cblxuXHRcdHZhciB0b2tlbiA9IHlhc3FlLmdldENvbXBsZXRlVG9rZW4oKTtcblx0XHRpZiAoY29tcGxldGVyLnByZVByb2Nlc3NUb2tlbikge1xuXHRcdFx0dG9rZW4gPSBjb21wbGV0ZXIucHJlUHJvY2Vzc1Rva2VuKHRva2VuKTtcblx0XHR9XG5cblx0XHRpZiAodG9rZW4pIHtcblx0XHRcdC8vIHVzZSBjdXN0b20gY29tcGxldGlvbmhpbnQgZnVuY3Rpb24sIHRvIGF2b2lkIHJlYWNoaW5nIGEgbG9vcCB3aGVuIHRoZVxuXHRcdFx0Ly8gY29tcGxldGlvbmhpbnQgaXMgdGhlIHNhbWUgYXMgdGhlIGN1cnJlbnQgdG9rZW5cblx0XHRcdC8vIHJlZ3VsYXIgYmVoYXZpb3VyIHdvdWxkIGtlZXAgY2hhbmdpbmcgdGhlIGNvZGVtaXJyb3IgZG9tLCBoZW5jZVxuXHRcdFx0Ly8gY29uc3RhbnRseSBjYWxsaW5nIHRoaXMgY2FsbGJhY2tcblx0XHRcdGlmICghY29tcGxldGVyLmJ1bGsgJiYgY29tcGxldGVyLmFzeW5jKSB7XG5cdFx0XHRcdHZhciB3cmFwcGVkQ2FsbGJhY2sgPSBmdW5jdGlvbihzdWdnZXN0aW9ucykge1xuXHRcdFx0XHRcdGNhbGxiYWNrKGdldFN1Z2dlc3Rpb25zQXNIaW50T2JqZWN0KHN1Z2dlc3Rpb25zLCBjb21wbGV0ZXIsIHRva2VuKSk7XG5cdFx0XHRcdH07XG5cdFx0XHRcdGNvbXBsZXRlci5nZXQodG9rZW4sIHdyYXBwZWRDYWxsYmFjayk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRyZXR1cm4gZ2V0U3VnZ2VzdGlvbnNGcm9tVG9rZW4odG9rZW4pO1xuXG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xuXG5cblx0LyoqXG5cdCAqICBnZXQgb3VyIGFycmF5IG9mIHN1Z2dlc3Rpb25zIChzdHJpbmdzKSBpbiB0aGUgY29kZW1pcnJvciBoaW50IGZvcm1hdFxuXHQgKi9cblx0dmFyIGdldFN1Z2dlc3Rpb25zQXNIaW50T2JqZWN0ID0gZnVuY3Rpb24oc3VnZ2VzdGlvbnMsIGNvbXBsZXRlciwgdG9rZW4pIHtcblx0XHR2YXIgaGludExpc3QgPSBbXTtcblx0XHRmb3IgKHZhciBpID0gMDsgaSA8IHN1Z2dlc3Rpb25zLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHR2YXIgc3VnZ2VzdGVkU3RyaW5nID0gc3VnZ2VzdGlvbnNbaV07XG5cdFx0XHRpZiAoY29tcGxldGVyLnBvc3RQcm9jZXNzVG9rZW4pIHtcblx0XHRcdFx0c3VnZ2VzdGVkU3RyaW5nID0gY29tcGxldGVyLnBvc3RQcm9jZXNzVG9rZW4odG9rZW4sIHN1Z2dlc3RlZFN0cmluZyk7XG5cdFx0XHR9XG5cdFx0XHRoaW50TGlzdC5wdXNoKHtcblx0XHRcdFx0dGV4dDogc3VnZ2VzdGVkU3RyaW5nLFxuXHRcdFx0XHRkaXNwbGF5VGV4dDogc3VnZ2VzdGVkU3RyaW5nLFxuXHRcdFx0XHRoaW50OiBzZWxlY3RIaW50LFxuXHRcdFx0fSk7XG5cdFx0fVxuXG5cdFx0dmFyIGN1ciA9IHlhc3FlLmdldEN1cnNvcigpO1xuXHRcdHZhciByZXR1cm5PYmogPSB7XG5cdFx0XHRjb21wbGV0aW9uVG9rZW46IHRva2VuLnN0cmluZyxcblx0XHRcdGxpc3Q6IGhpbnRMaXN0LFxuXHRcdFx0ZnJvbToge1xuXHRcdFx0XHRsaW5lOiBjdXIubGluZSxcblx0XHRcdFx0Y2g6IHRva2VuLnN0YXJ0XG5cdFx0XHR9LFxuXHRcdFx0dG86IHtcblx0XHRcdFx0bGluZTogY3VyLmxpbmUsXG5cdFx0XHRcdGNoOiB0b2tlbi5lbmRcblx0XHRcdH1cblx0XHR9O1xuXHRcdC8vaWYgd2UgaGF2ZSBzb21lIGF1dG9jb21wbGV0aW9uIGhhbmRsZXJzIHNwZWNpZmllZCwgYWRkIHRoZXNlIHRoZXNlIHRvIHRoZSBvYmplY3QuIENvZGVtaXJyb3Igd2lsbCB0YWtlIGNhcmUgb2YgZmlyaW5nIHRoZXNlXG5cdFx0aWYgKGNvbXBsZXRlci5jYWxsYmFja3MpIHtcblx0XHRcdGZvciAodmFyIGNhbGxiYWNrTmFtZSBpbiBjb21wbGV0ZXIuY2FsbGJhY2tzKSB7XG5cdFx0XHRcdGlmIChjb21wbGV0ZXIuY2FsbGJhY2tzW2NhbGxiYWNrTmFtZV0pIHtcblx0XHRcdFx0XHRZQVNRRS5vbihyZXR1cm5PYmosIGNhbGxiYWNrTmFtZSwgY29tcGxldGVyLmNhbGxiYWNrc1tjYWxsYmFja05hbWVdKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0XHRyZXR1cm4gcmV0dXJuT2JqO1xuXHR9O1xuXG5cdHJldHVybiB7XG5cdFx0aW5pdDogaW5pdENvbXBsZXRlcixcblx0XHRjb21wbGV0ZXJzOiBjb21wbGV0ZXJzLFxuXHRcdG5vdGlmaWNhdGlvbnM6IHtcblx0XHRcdGdldEVsOiBmdW5jdGlvbihjb21wbGV0ZXIpIHtcblx0XHRcdFx0cmV0dXJuICQoY29tcGxldGlvbk5vdGlmaWNhdGlvbnNbY29tcGxldGVyLm5hbWVdKTtcblx0XHRcdH0sXG5cdFx0XHRzaG93OiBmdW5jdGlvbih5YXNxZSwgY29tcGxldGVyKSB7XG5cdFx0XHRcdC8vb25seSBkcmF3IHdoZW4gdGhlIHVzZXIgbmVlZHMgdG8gdXNlIGEga2V5cHJlc3MgdG8gc3VtbW9uIGF1dG9jb21wbGV0aW9uc1xuXHRcdFx0XHRpZiAoIWNvbXBsZXRlci5hdXRvc2hvdykge1xuXHRcdFx0XHRcdGlmICghY29tcGxldGlvbk5vdGlmaWNhdGlvbnNbY29tcGxldGVyLm5hbWVdKSBjb21wbGV0aW9uTm90aWZpY2F0aW9uc1tjb21wbGV0ZXIubmFtZV0gPSAkKFwiPGRpdiBjbGFzcz0nY29tcGxldGlvbk5vdGlmaWNhdGlvbic+PC9kaXY+XCIpO1xuXHRcdFx0XHRcdGNvbXBsZXRpb25Ob3RpZmljYXRpb25zW2NvbXBsZXRlci5uYW1lXVxuXHRcdFx0XHRcdFx0LnNob3coKVxuXHRcdFx0XHRcdFx0LnRleHQoXCJQcmVzcyBcIiArIChuYXZpZ2F0b3IudXNlckFnZW50LmluZGV4T2YoJ01hYyBPUyBYJykgIT0gLTEgPyBcIkNNRFwiIDogXCJDVFJMXCIpICsgXCIgLSA8c3BhY2ViYXI+IHRvIGF1dG9jb21wbGV0ZVwiKVxuXHRcdFx0XHRcdFx0LmFwcGVuZFRvKCQoeWFzcWUuZ2V0V3JhcHBlckVsZW1lbnQoKSkpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LFxuXHRcdFx0aGlkZTogZnVuY3Rpb24oeWFzcWUsIGNvbXBsZXRlcikge1xuXHRcdFx0XHRpZiAoY29tcGxldGlvbk5vdGlmaWNhdGlvbnNbY29tcGxldGVyLm5hbWVdKSB7XG5cdFx0XHRcdFx0Y29tcGxldGlvbk5vdGlmaWNhdGlvbnNbY29tcGxldGVyLm5hbWVdLmhpZGUoKTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXG5cdFx0fSxcblx0XHRhdXRvQ29tcGxldGU6IGF1dG9Db21wbGV0ZSxcblx0XHRnZXRUcmllOiBmdW5jdGlvbihjb21wbGV0ZXIpIHtcblx0XHRcdHJldHVybiAodHlwZW9mIGNvbXBsZXRlciA9PSBcInN0cmluZ1wiID8gdHJpZXNbY29tcGxldGVyXSA6IHRyaWVzW2NvbXBsZXRlci5uYW1lXSk7XG5cdFx0fVxuXHR9XG59O1xuXG5cblxuXG5cblxuXG5cblxuLyoqXG4gKiBmdW5jdGlvbiB3aGljaCBmaXJlcyBhZnRlciB0aGUgdXNlciBzZWxlY3RzIGEgY29tcGxldGlvbi4gdGhpcyBmdW5jdGlvbiBjaGVja3Mgd2hldGhlciB3ZSBhY3R1YWxseSBuZWVkIHRvIHN0b3JlIHRoaXMgb25lIChpZiBjb21wbGV0aW9uIGlzIHNhbWUgYXMgY3VycmVudCB0b2tlbiwgZG9uJ3QgZG8gYW55dGhpbmcpXG4gKi9cbnZhciBzZWxlY3RIaW50ID0gZnVuY3Rpb24oeWFzcWUsIGRhdGEsIGNvbXBsZXRpb24pIHtcblx0aWYgKGNvbXBsZXRpb24udGV4dCAhPSB5YXNxZS5nZXRUb2tlbkF0KHlhc3FlLmdldEN1cnNvcigpKS5zdHJpbmcpIHtcblx0XHR5YXNxZS5yZXBsYWNlUmFuZ2UoY29tcGxldGlvbi50ZXh0LCBkYXRhLmZyb20sIGRhdGEudG8pO1xuXHR9XG59O1xuXG5cblxuXG5cbi8vXG4vL21vZHVsZS5leHBvcnRzID0ge1xuLy9cdHByZXByb2Nlc3NQcmVmaXhUb2tlbkZvckNvbXBsZXRpb246IHByZXByb2Nlc3NQcmVmaXhUb2tlbkZvckNvbXBsZXRpb24sXG4vL1x0cG9zdHByb2Nlc3NSZXNvdXJjZVRva2VuRm9yQ29tcGxldGlvbjogcG9zdHByb2Nlc3NSZXNvdXJjZVRva2VuRm9yQ29tcGxldGlvbixcbi8vXHRwcmVwcm9jZXNzUmVzb3VyY2VUb2tlbkZvckNvbXBsZXRpb246IHByZXByb2Nlc3NSZXNvdXJjZVRva2VuRm9yQ29tcGxldGlvbixcbi8vXHRzaG93Q29tcGxldGlvbk5vdGlmaWNhdGlvbjogc2hvd0NvbXBsZXRpb25Ob3RpZmljYXRpb24sXG4vL1x0aGlkZUNvbXBsZXRpb25Ob3RpZmljYXRpb246IGhpZGVDb21wbGV0aW9uTm90aWZpY2F0aW9uLFxuLy9cdGF1dG9Db21wbGV0ZTogYXV0b0NvbXBsZXRlLFxuLy9cdGF1dG9jb21wbGV0ZVZhcmlhYmxlczogYXV0b2NvbXBsZXRlVmFyaWFibGVzLFxuLy9cdGZldGNoRnJvbVByZWZpeENjOiBmZXRjaEZyb21QcmVmaXhDYyxcbi8vXHRmZXRjaEZyb21Mb3Y6IGZldGNoRnJvbUxvdixcbi8vLy9cdHN0b3JlQnVsa0NvbXBsZXRpb25zOiBzdG9yZUJ1bGtDb21wbGV0aW9ucyxcbi8vXHRsb2FkQnVsa0NvbXBsZXRpb25zOiBsb2FkQnVsa0NvbXBsZXRpb25zLFxuLy99OyIsIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHlhc3FlLCBuYW1lKSB7XG5cdHJldHVybiB7XG5cdFx0aXNWYWxpZENvbXBsZXRpb25Qb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHMuaXNWYWxpZENvbXBsZXRpb25Qb3NpdGlvbih5YXNxZSk7XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uKHRva2VuLCBjYWxsYmFjaykge1xuXHRcdFx0cmV0dXJuIHJlcXVpcmUoJy4vdXRpbHMnKS5mZXRjaEZyb21Mb3YoeWFzcWUsIHRoaXMsIHRva2VuLCBjYWxsYmFjayk7XG5cdFx0fSxcblx0XHRwcmVQcm9jZXNzVG9rZW46IGZ1bmN0aW9uKHRva2VuKSB7XG5cdFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHMucHJlUHJvY2Vzc1Rva2VuKHlhc3FlLCB0b2tlbilcblx0XHR9LFxuXHRcdHBvc3RQcm9jZXNzVG9rZW46IGZ1bmN0aW9uKHRva2VuLCBzdWdnZXN0ZWRTdHJpbmcpIHtcblx0XHRcdHJldHVybiBtb2R1bGUuZXhwb3J0cy5wb3N0UHJvY2Vzc1Rva2VuKHlhc3FlLCB0b2tlbiwgc3VnZ2VzdGVkU3RyaW5nKTtcblx0XHR9LFxuXHRcdGFzeW5jOiB0cnVlLFxuXHRcdGJ1bGs6IGZhbHNlLFxuXHRcdGF1dG9TaG93OiBmYWxzZSxcblx0XHRwZXJzaXN0ZW50OiBuYW1lLFxuXHRcdGNhbGxiYWNrczoge1xuXHRcdFx0dmFsaWRQb3NpdGlvbjogeWFzcWUuYXV0b2NvbXBsZXRlcnMubm90aWZpY2F0aW9ucy5zaG93LFxuXHRcdFx0aW52YWxpZFBvc2l0aW9uOiB5YXNxZS5hdXRvY29tcGxldGVycy5ub3RpZmljYXRpb25zLmhpZGUsXG5cdFx0fVxuXHR9XG59O1xuXG5tb2R1bGUuZXhwb3J0cy5pc1ZhbGlkQ29tcGxldGlvblBvc2l0aW9uID0gZnVuY3Rpb24oeWFzcWUpIHtcblx0dmFyIHRva2VuID0geWFzcWUuZ2V0Q29tcGxldGVUb2tlbigpO1xuXHRpZiAodG9rZW4uc3RyaW5nLmluZGV4T2YoXCI/XCIpID09IDApXG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR2YXIgY3VyID0geWFzcWUuZ2V0Q3Vyc29yKCk7XG5cdHZhciBwcmV2aW91c1Rva2VuID0geWFzcWUuZ2V0UHJldmlvdXNOb25Xc1Rva2VuKGN1ci5saW5lLCB0b2tlbik7XG5cdGlmIChwcmV2aW91c1Rva2VuLnN0cmluZyA9PSBcImFcIilcblx0XHRyZXR1cm4gdHJ1ZTtcblx0aWYgKHByZXZpb3VzVG9rZW4uc3RyaW5nID09IFwicmRmOnR5cGVcIilcblx0XHRyZXR1cm4gdHJ1ZTtcblx0aWYgKHByZXZpb3VzVG9rZW4uc3RyaW5nID09IFwicmRmczpkb21haW5cIilcblx0XHRyZXR1cm4gdHJ1ZTtcblx0aWYgKHByZXZpb3VzVG9rZW4uc3RyaW5nID09IFwicmRmczpyYW5nZVwiKVxuXHRcdHJldHVybiB0cnVlO1xuXHRyZXR1cm4gZmFsc2U7XG59O1xubW9kdWxlLmV4cG9ydHMucHJlUHJvY2Vzc1Rva2VuID0gZnVuY3Rpb24oeWFzcWUsIHRva2VuKSB7XG5cdHJldHVybiByZXF1aXJlKCcuL3V0aWxzLmpzJykucHJlcHJvY2Vzc1Jlc291cmNlVG9rZW5Gb3JDb21wbGV0aW9uKHlhc3FlLCB0b2tlbik7XG59O1xubW9kdWxlLmV4cG9ydHMucG9zdFByb2Nlc3NUb2tlbiA9IGZ1bmN0aW9uKHlhc3FlLCB0b2tlbiwgc3VnZ2VzdGVkU3RyaW5nKSB7XG5cdHJldHVybiByZXF1aXJlKCcuL3V0aWxzLmpzJykucG9zdHByb2Nlc3NSZXNvdXJjZVRva2VuRm9yQ29tcGxldGlvbih5YXNxZSwgdG9rZW4sIHN1Z2dlc3RlZFN0cmluZylcbn07IiwiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCdqcXVlcnknKTtcbi8vdGhpcyBpcyBhIG1hcHBpbmcgZnJvbSB0aGUgY2xhc3MgbmFtZXMgKGdlbmVyaWMgb25lcywgZm9yIGNvbXBhdGFiaWxpdHkgd2l0aCBjb2RlbWlycm9yIHRoZW1lcyksIHRvIHdoYXQgdGhleSAtYWN0dWFsbHktIHJlcHJlc2VudFxudmFyIHRva2VuVHlwZXMgPSB7XG5cdFwic3RyaW5nLTJcIjogXCJwcmVmaXhlZFwiLFxuXHRcImF0b21cIjogXCJ2YXJcIlxufTtcblxubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih5YXNxZSwgY29tcGxldGVyTmFtZSkge1xuXHQvL3RoaXMgYXV0b2NvbXBsZXRlciBhbHNvIGZpcmVzIG9uLWNoYW5nZSFcblx0eWFzcWUub24oXCJjaGFuZ2VcIiwgZnVuY3Rpb24oKSB7XG5cdFx0bW9kdWxlLmV4cG9ydHMuYXBwZW5kUHJlZml4SWZOZWVkZWQoeWFzcWUsIGNvbXBsZXRlck5hbWUpO1xuXHR9KTtcblxuXG5cdHJldHVybiB7XG5cdFx0aXNWYWxpZENvbXBsZXRpb25Qb3NpdGlvbjogZnVuY3Rpb24oKSB7XG5cdFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHMuaXNWYWxpZENvbXBsZXRpb25Qb3NpdGlvbih5YXNxZSk7XG5cdFx0fSxcblx0XHRnZXQ6IGZ1bmN0aW9uKHRva2VuLCBjYWxsYmFjaykge1xuXHRcdFx0JC5nZXQoXCJodHRwOi8vcHJlZml4LmNjL3BvcHVsYXIvYWxsLmZpbGUuanNvblwiLCBmdW5jdGlvbihkYXRhKSB7XG5cdFx0XHRcdHZhciBwcmVmaXhBcnJheSA9IFtdO1xuXHRcdFx0XHRmb3IgKHZhciBwcmVmaXggaW4gZGF0YSkge1xuXHRcdFx0XHRcdGlmIChwcmVmaXggPT0gXCJiaWZcIilcblx0XHRcdFx0XHRcdGNvbnRpbnVlOyAvLyBza2lwIHRoaXMgb25lISBzZWUgIzIzMVxuXHRcdFx0XHRcdHZhciBjb21wbGV0ZVN0cmluZyA9IHByZWZpeCArIFwiOiA8XCIgKyBkYXRhW3ByZWZpeF0gKyBcIj5cIjtcblx0XHRcdFx0XHRwcmVmaXhBcnJheS5wdXNoKGNvbXBsZXRlU3RyaW5nKTsgLy8gdGhlIGFycmF5IHdlIHdhbnQgdG8gc3RvcmUgaW4gbG9jYWxzdG9yYWdlXG5cdFx0XHRcdH1cblxuXHRcdFx0XHRwcmVmaXhBcnJheS5zb3J0KCk7XG5cdFx0XHRcdGNhbGxiYWNrKHByZWZpeEFycmF5KTtcblx0XHRcdH0pO1xuXHRcdH0sXG5cdFx0cHJlUHJvY2Vzc1Rva2VuOiBmdW5jdGlvbih0b2tlbikge1xuXHRcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzLnByZXByb2Nlc3NQcmVmaXhUb2tlbkZvckNvbXBsZXRpb24oeWFzcWUsIHRva2VuKVxuXHRcdH0sXG5cdFx0YXN5bmM6IHRydWUsXG5cdFx0YnVsazogdHJ1ZSxcblx0XHRhdXRvU2hvdzogdHJ1ZSxcblx0XHRwZXJzaXN0ZW50OiBjb21wbGV0ZXJOYW1lLFxuXHRcdGNhbGxiYWNrczoge1xuXHRcdFx0cGljazogZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHlhc3FlLmNvbGxhcHNlUHJlZml4ZXMoZmFsc2UpO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcbn07XG5tb2R1bGUuZXhwb3J0cy5pc1ZhbGlkQ29tcGxldGlvblBvc2l0aW9uID0gZnVuY3Rpb24oeWFzcWUpIHtcblx0dmFyIGN1ciA9IHlhc3FlLmdldEN1cnNvcigpLFxuXHRcdHRva2VuID0geWFzcWUuZ2V0VG9rZW5BdChjdXIpO1xuXG5cdC8vIG5vdCBhdCBlbmQgb2YgbGluZVxuXHRpZiAoeWFzcWUuZ2V0TGluZShjdXIubGluZSkubGVuZ3RoID4gY3VyLmNoKVxuXHRcdHJldHVybiBmYWxzZTtcblxuXHRpZiAodG9rZW4udHlwZSAhPSBcIndzXCIpIHtcblx0XHQvLyB3ZSB3YW50IHRvIGNvbXBsZXRlIHRva2VuLCBlLmcuIHdoZW4gdGhlIHByZWZpeCBzdGFydHMgd2l0aCBhbiBhXG5cdFx0Ly8gKHRyZWF0ZWQgYXMgYSB0b2tlbiBpbiBpdHNlbGYuLilcblx0XHQvLyBidXQgd2UgdG8gYXZvaWQgaW5jbHVkaW5nIHRoZSBQUkVGSVggdGFnLiBTbyB3aGVuIHdlIGhhdmUganVzdFxuXHRcdC8vIHR5cGVkIGEgc3BhY2UgYWZ0ZXIgdGhlIHByZWZpeCB0YWcsIGRvbid0IGdldCB0aGUgY29tcGxldGUgdG9rZW5cblx0XHR0b2tlbiA9IHlhc3FlLmdldENvbXBsZXRlVG9rZW4oKTtcblx0fVxuXG5cdC8vIHdlIHNob3VsZG50IGJlIGF0IHRoZSB1cmkgcGFydCB0aGUgcHJlZml4IGRlY2xhcmF0aW9uXG5cdC8vIGFsc28gY2hlY2sgd2hldGhlciBjdXJyZW50IHRva2VuIGlzbnQgJ2EnICh0aGF0IG1ha2VzIGNvZGVtaXJyb3Jcblx0Ly8gdGhpbmcgYSBuYW1lc3BhY2UgaXMgYSBwb3NzaWJsZWN1cnJlbnRcblx0aWYgKCF0b2tlbi5zdHJpbmcuaW5kZXhPZihcImFcIikgPT0gMCAmJiAkLmluQXJyYXkoXCJQTkFNRV9OU1wiLCB0b2tlbi5zdGF0ZS5wb3NzaWJsZUN1cnJlbnQpID09IC0xKVxuXHRcdHJldHVybiBmYWxzZTtcblxuXHQvLyBGaXJzdCB0b2tlbiBvZiBsaW5lIG5lZWRzIHRvIGJlIFBSRUZJWCxcblx0Ly8gdGhlcmUgc2hvdWxkIGJlIG5vIHRyYWlsaW5nIHRleHQgKG90aGVyd2lzZSwgdGV4dCBpcyB3cm9uZ2x5IGluc2VydGVkXG5cdC8vIGluIGJldHdlZW4pXG5cdHZhciBwcmV2aW91c1Rva2VuID0geWFzcWUuZ2V0UHJldmlvdXNOb25Xc1Rva2VuKGN1ci5saW5lLCB0b2tlbik7XG5cdGlmICghcHJldmlvdXNUb2tlbiB8fCBwcmV2aW91c1Rva2VuLnN0cmluZy50b1VwcGVyQ2FzZSgpICE9IFwiUFJFRklYXCIpIHJldHVybiBmYWxzZTtcblx0cmV0dXJuIHRydWU7XG59O1xubW9kdWxlLmV4cG9ydHMucHJlcHJvY2Vzc1ByZWZpeFRva2VuRm9yQ29tcGxldGlvbiA9IGZ1bmN0aW9uKHlhc3FlLCB0b2tlbikge1xuXHR2YXIgcHJldmlvdXNUb2tlbiA9IHlhc3FlLmdldFByZXZpb3VzTm9uV3NUb2tlbih5YXNxZS5nZXRDdXJzb3IoKS5saW5lLCB0b2tlbik7XG5cdGlmIChwcmV2aW91c1Rva2VuICYmIHByZXZpb3VzVG9rZW4uc3RyaW5nICYmIHByZXZpb3VzVG9rZW4uc3RyaW5nLnNsaWNlKC0xKSA9PSBcIjpcIikge1xuXHRcdC8vY29tYmluZSBib3RoIHRva2VucyEgSW4gdGhpcyBjYXNlIHdlIGhhdmUgdGhlIGN1cnNvciBhdCB0aGUgZW5kIG9mIGxpbmUgXCJQUkVGSVggYmxhOiA8XCIuXG5cdFx0Ly93ZSB3YW50IHRoZSB0b2tlbiB0byBiZSBcImJsYTogPFwiLCBlbiBub3QgXCI8XCJcblx0XHR0b2tlbiA9IHtcblx0XHRcdHN0YXJ0OiBwcmV2aW91c1Rva2VuLnN0YXJ0LFxuXHRcdFx0ZW5kOiB0b2tlbi5lbmQsXG5cdFx0XHRzdHJpbmc6IHByZXZpb3VzVG9rZW4uc3RyaW5nICsgXCIgXCIgKyB0b2tlbi5zdHJpbmcsXG5cdFx0XHRzdGF0ZTogdG9rZW4uc3RhdGVcblx0XHR9O1xuXHR9XG5cdHJldHVybiB0b2tlbjtcbn07XG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdHlwZWQgcHJlZml4IGlzIGRlY2xhcmVkLiBJZiBub3QsIGF1dG9tYXRpY2FsbHkgYWRkIGRlY2xhcmF0aW9uXG4gKiB1c2luZyBsaXN0IGZyb20gcHJlZml4LmNjXG4gKiBcbiAqIEBwYXJhbSB5YXNxZVxuICovXG5tb2R1bGUuZXhwb3J0cy5hcHBlbmRQcmVmaXhJZk5lZWRlZCA9IGZ1bmN0aW9uKHlhc3FlLCBjb21wbGV0ZXJOYW1lKSB7XG5cdGlmICgheWFzcWUuYXV0b2NvbXBsZXRlcnMuZ2V0VHJpZShjb21wbGV0ZXJOYW1lKSlcblx0XHRyZXR1cm47IC8vIG5vIHByZWZpeGVkIGRlZmluZWQuIGp1c3Qgc3RvcFxuXHRpZiAoIXlhc3FlLm9wdGlvbnMuYXV0b2NvbXBsZXRlcnMgfHwgeWFzcWUub3B0aW9ucy5hdXRvY29tcGxldGVycy5pbmRleE9mKGNvbXBsZXRlck5hbWUpID09IC0xKSByZXR1cm47IC8vdGhpcyBhdXRvY29tcGxldGVyIGlzIGRpc2FibGVkXG5cdHZhciBjdXIgPSB5YXNxZS5nZXRDdXJzb3IoKTtcblxuXHR2YXIgdG9rZW4gPSB5YXNxZS5nZXRUb2tlbkF0KGN1cik7XG5cdGlmICh0b2tlblR5cGVzW3Rva2VuLnR5cGVdID09IFwicHJlZml4ZWRcIikge1xuXHRcdHZhciBjb2xvbkluZGV4ID0gdG9rZW4uc3RyaW5nLmluZGV4T2YoXCI6XCIpO1xuXHRcdGlmIChjb2xvbkluZGV4ICE9PSAtMSkge1xuXHRcdFx0Ly8gY2hlY2sgcHJldmlvdXMgdG9rZW4gaXNudCBQUkVGSVgsIG9yIGEgJzwnKHdoaWNoIHdvdWxkIG1lYW4gd2UgYXJlIGluIGEgdXJpKVxuXHRcdFx0Ly9cdFx0XHR2YXIgZmlyc3RUb2tlblN0cmluZyA9IHlhc3FlLmdldE5leHROb25Xc1Rva2VuKGN1ci5saW5lKS5zdHJpbmcudG9VcHBlckNhc2UoKTtcblx0XHRcdHZhciBsYXN0Tm9uV3NUb2tlblN0cmluZyA9IHlhc3FlLmdldFByZXZpb3VzTm9uV3NUb2tlbihjdXIubGluZSwgdG9rZW4pLnN0cmluZy50b1VwcGVyQ2FzZSgpO1xuXHRcdFx0dmFyIHByZXZpb3VzVG9rZW4gPSB5YXNxZS5nZXRUb2tlbkF0KHtcblx0XHRcdFx0bGluZTogY3VyLmxpbmUsXG5cdFx0XHRcdGNoOiB0b2tlbi5zdGFydFxuXHRcdFx0fSk7IC8vIG5lZWRzIHRvIGJlIG51bGwgKGJlZ2lubmluZyBvZiBsaW5lKSwgb3Igd2hpdGVzcGFjZVxuXHRcdFx0aWYgKGxhc3ROb25Xc1Rva2VuU3RyaW5nICE9IFwiUFJFRklYXCIgJiYgKHByZXZpb3VzVG9rZW4udHlwZSA9PSBcIndzXCIgfHwgcHJldmlvdXNUb2tlbi50eXBlID09IG51bGwpKSB7XG5cdFx0XHRcdC8vIGNoZWNrIHdoZXRoZXIgaXQgaXNudCBkZWZpbmVkIGFscmVhZHkgKHNhdmVzIHVzIGZyb20gbG9vcGluZ1xuXHRcdFx0XHQvLyB0aHJvdWdoIHRoZSBhcnJheSlcblx0XHRcdFx0dmFyIGN1cnJlbnRQcmVmaXggPSB0b2tlbi5zdHJpbmcuc3Vic3RyaW5nKDAsIGNvbG9uSW5kZXggKyAxKTtcblx0XHRcdFx0dmFyIHF1ZXJ5UHJlZml4ZXMgPSB5YXNxZS5nZXRQcmVmaXhlc0Zyb21RdWVyeSgpO1xuXHRcdFx0XHRpZiAocXVlcnlQcmVmaXhlc1tjdXJyZW50UHJlZml4LnNsaWNlKDAsIC0xKV0gPT0gbnVsbCkge1xuXHRcdFx0XHRcdC8vIG9rLCBzbyBpdCBpc250IGFkZGVkIHlldCFcblx0XHRcdFx0XHR2YXIgY29tcGxldGlvbnMgPSB5YXNxZS5hdXRvY29tcGxldGVycy5nZXRUcmllKGNvbXBsZXRlck5hbWUpLmF1dG9Db21wbGV0ZShjdXJyZW50UHJlZml4KTtcblx0XHRcdFx0XHRpZiAoY29tcGxldGlvbnMubGVuZ3RoID4gMCkge1xuXHRcdFx0XHRcdFx0eWFzcWUuYWRkUHJlZml4ZXMoY29tcGxldGlvbnNbMF0pO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH1cblx0fVxufTsiLCIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJ2pxdWVyeScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih5YXNxZSwgbmFtZSkge1xuXHRyZXR1cm4ge1xuXHRcdGlzVmFsaWRDb21wbGV0aW9uUG9zaXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzLmlzVmFsaWRDb21wbGV0aW9uUG9zaXRpb24oeWFzcWUpO1xuXHRcdH0sXG5cdFx0Z2V0OiBmdW5jdGlvbih0b2tlbiwgY2FsbGJhY2spIHtcblx0XHRcdHJldHVybiByZXF1aXJlKCcuL3V0aWxzJykuZmV0Y2hGcm9tTG92KHlhc3FlLCB0aGlzLCB0b2tlbiwgY2FsbGJhY2spO1xuXHRcdH0sXG5cdFx0cHJlUHJvY2Vzc1Rva2VuOiBmdW5jdGlvbih0b2tlbikge1xuXHRcdFx0cmV0dXJuIG1vZHVsZS5leHBvcnRzLnByZVByb2Nlc3NUb2tlbih5YXNxZSwgdG9rZW4pXG5cdFx0fSxcblx0XHRwb3N0UHJvY2Vzc1Rva2VuOiBmdW5jdGlvbih0b2tlbiwgc3VnZ2VzdGVkU3RyaW5nKSB7XG5cdFx0XHRyZXR1cm4gbW9kdWxlLmV4cG9ydHMucG9zdFByb2Nlc3NUb2tlbih5YXNxZSwgdG9rZW4sIHN1Z2dlc3RlZFN0cmluZyk7XG5cdFx0fSxcblx0XHRhc3luYzogdHJ1ZSxcblx0XHRidWxrOiBmYWxzZSxcblx0XHRhdXRvU2hvdzogZmFsc2UsXG5cdFx0cGVyc2lzdGVudDogbmFtZSxcblx0XHRjYWxsYmFja3M6IHtcblx0XHRcdHZhbGlkUG9zaXRpb246IHlhc3FlLmF1dG9jb21wbGV0ZXJzLm5vdGlmaWNhdGlvbnMuc2hvdyxcblx0XHRcdGludmFsaWRQb3NpdGlvbjogeWFzcWUuYXV0b2NvbXBsZXRlcnMubm90aWZpY2F0aW9ucy5oaWRlLFxuXHRcdH1cblx0fVxufTtcblxubW9kdWxlLmV4cG9ydHMuaXNWYWxpZENvbXBsZXRpb25Qb3NpdGlvbiA9IGZ1bmN0aW9uKHlhc3FlKSB7XG5cdHZhciB0b2tlbiA9IHlhc3FlLmdldENvbXBsZXRlVG9rZW4oKTtcblx0aWYgKHRva2VuLnN0cmluZy5sZW5ndGggPT0gMClcblx0XHRyZXR1cm4gZmFsc2U7IC8vd2Ugd2FudCAtc29tZXRoaW5nLSB0byBhdXRvY29tcGxldGVcblx0aWYgKHRva2VuLnN0cmluZy5pbmRleE9mKFwiP1wiKSA9PSAwKVxuXHRcdHJldHVybiBmYWxzZTsgLy8gd2UgYXJlIHR5cGluZyBhIHZhclxuXHRpZiAoJC5pbkFycmF5KFwiYVwiLCB0b2tlbi5zdGF0ZS5wb3NzaWJsZUN1cnJlbnQpID49IDApXG5cdFx0cmV0dXJuIHRydWU7IC8vIHByZWRpY2F0ZSBwb3Ncblx0dmFyIGN1ciA9IHlhc3FlLmdldEN1cnNvcigpO1xuXHR2YXIgcHJldmlvdXNUb2tlbiA9IHlhc3FlLmdldFByZXZpb3VzTm9uV3NUb2tlbihjdXIubGluZSwgdG9rZW4pO1xuXHRpZiAocHJldmlvdXNUb2tlbi5zdHJpbmcgPT0gXCJyZGZzOnN1YlByb3BlcnR5T2ZcIilcblx0XHRyZXR1cm4gdHJ1ZTtcblxuXHQvLyBobW0sIHdlIHdvdWxkIGxpa2UgLWJldHRlci0gY2hlY2tzIGhlcmUsIGUuZy4gY2hlY2tpbmcgd2hldGhlciB3ZSBhcmVcblx0Ly8gaW4gYSBzdWJqZWN0LCBhbmQgd2hldGhlciBuZXh0IGl0ZW0gaXMgYSByZGZzOnN1YnByb3BlcnR5b2YuXG5cdC8vIGRpZmZpY3VsdCB0aG91Z2guLi4gdGhlIGdyYW1tYXIgd2UgdXNlIGlzIHVucmVsaWFibGUgd2hlbiB0aGUgcXVlcnlcblx0Ly8gaXMgaW52YWxpZCAoaS5lLiBkdXJpbmcgdHlwaW5nKSwgYW5kIG9mdGVuIHRoZSBwcmVkaWNhdGUgaXMgbm90IHR5cGVkXG5cdC8vIHlldCwgd2hlbiB3ZSBhcmUgYnVzeSB3cml0aW5nIHRoZSBzdWJqZWN0Li4uXG5cdHJldHVybiBmYWxzZTtcbn07XG5tb2R1bGUuZXhwb3J0cy5wcmVQcm9jZXNzVG9rZW4gPSBmdW5jdGlvbih5YXNxZSwgdG9rZW4pIHtcblx0cmV0dXJuIHJlcXVpcmUoJy4vdXRpbHMuanMnKS5wcmVwcm9jZXNzUmVzb3VyY2VUb2tlbkZvckNvbXBsZXRpb24oeWFzcWUsIHRva2VuKTtcbn07XG5tb2R1bGUuZXhwb3J0cy5wb3N0UHJvY2Vzc1Rva2VuID0gZnVuY3Rpb24oeWFzcWUsIHRva2VuLCBzdWdnZXN0ZWRTdHJpbmcpIHtcblx0cmV0dXJuIHJlcXVpcmUoJy4vdXRpbHMuanMnKS5wb3N0cHJvY2Vzc1Jlc291cmNlVG9rZW5Gb3JDb21wbGV0aW9uKHlhc3FlLCB0b2tlbiwgc3VnZ2VzdGVkU3RyaW5nKVxufTsiLCIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJ2pxdWVyeScpLFxuXHR1dGlscyA9IHJlcXVpcmUoJy4vdXRpbHMuanMnKSxcblx0eXV0aWxzID0gcmVxdWlyZSgneWFzZ3VpLXV0aWxzJyk7XG4vKipcbiAqIFdoZXJlIHRoZSBiYXNlIGNsYXNzIG9ubHkgY29udGFpbnMgZnVuY3Rpb25hbGl0eSByZWxhdGVkIHRvIC1hbGwtIGNvbXBsZXRpb25zLCB0aGlzIGNsYXNzIGNvbnRhaW5zIHNvbWUgdXRpbHMgdXNlZCBoZXJlIGFuZCB0aGVyZSBpbiBvdXIgYXV0b2NvbXBsZXRpb25zXG4gKi9cblxuXG5cbi8qKlxuICogQ29udmVydHMgcmRmOnR5cGUgdG8gaHR0cDovLy4uLi90eXBlIGFuZCBjb252ZXJ0cyA8aHR0cDovLy4uLj4gdG8gaHR0cDovLy4uLlxuICogU3RvcmVzIGFkZGl0aW9uYWwgaW5mbyBzdWNoIGFzIHRoZSB1c2VkIG5hbWVzcGFjZSBhbmQgcHJlZml4IGluIHRoZSB0b2tlbiBvYmplY3RcbiAqL1xudmFyIHByZXByb2Nlc3NSZXNvdXJjZVRva2VuRm9yQ29tcGxldGlvbiA9IGZ1bmN0aW9uKHlhc3FlLCB0b2tlbikge1xuXHR2YXIgcXVlcnlQcmVmaXhlcyA9IHlhc3FlLmdldFByZWZpeGVzRnJvbVF1ZXJ5KCk7XG5cdGlmICghdG9rZW4uc3RyaW5nLmluZGV4T2YoXCI8XCIpID09IDApIHtcblx0XHR0b2tlbi50b2tlblByZWZpeCA9IHRva2VuLnN0cmluZy5zdWJzdHJpbmcoMCwgdG9rZW4uc3RyaW5nLmluZGV4T2YoXCI6XCIpICsgMSk7XG5cblx0XHRpZiAocXVlcnlQcmVmaXhlc1t0b2tlbi50b2tlblByZWZpeC5zbGljZSgwLCAtMSldICE9IG51bGwpIHtcblx0XHRcdHRva2VuLnRva2VuUHJlZml4VXJpID0gcXVlcnlQcmVmaXhlc1t0b2tlbi50b2tlblByZWZpeC5zbGljZSgwLCAtMSldO1xuXHRcdH1cblx0fVxuXG5cdHRva2VuLmF1dG9jb21wbGV0aW9uU3RyaW5nID0gdG9rZW4uc3RyaW5nLnRyaW0oKTtcblx0aWYgKCF0b2tlbi5zdHJpbmcuaW5kZXhPZihcIjxcIikgPT0gMCAmJiB0b2tlbi5zdHJpbmcuaW5kZXhPZihcIjpcIikgPiAtMSkge1xuXHRcdC8vIGhtbSwgdGhlIHRva2VuIGlzIHByZWZpeGVkLiBXZSBzdGlsbCBuZWVkIHRoZSBjb21wbGV0ZSB1cmkgZm9yIGF1dG9jb21wbGV0aW9ucy4gZ2VuZXJhdGUgdGhpcyFcblx0XHRmb3IgKHZhciBwcmVmaXggaW4gcXVlcnlQcmVmaXhlcykge1xuXHRcdFx0aWYgKHRva2VuLnN0cmluZy5pbmRleE9mKHByZWZpeCkgPT0gMCkge1xuXHRcdFx0XHR0b2tlbi5hdXRvY29tcGxldGlvblN0cmluZyA9IHF1ZXJ5UHJlZml4ZXNbcHJlZml4XTtcblx0XHRcdFx0dG9rZW4uYXV0b2NvbXBsZXRpb25TdHJpbmcgKz0gdG9rZW4uc3RyaW5nLnN1YnN0cmluZyhwcmVmaXgubGVuZ3RoICsgMSk7XG5cdFx0XHRcdGJyZWFrO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGlmICh0b2tlbi5hdXRvY29tcGxldGlvblN0cmluZy5pbmRleE9mKFwiPFwiKSA9PSAwKSB0b2tlbi5hdXRvY29tcGxldGlvblN0cmluZyA9IHRva2VuLmF1dG9jb21wbGV0aW9uU3RyaW5nLnN1YnN0cmluZygxKTtcblx0aWYgKHRva2VuLmF1dG9jb21wbGV0aW9uU3RyaW5nLmluZGV4T2YoXCI+XCIsIHRva2VuLmxlbmd0aCAtIDEpICE9PSAtMSkgdG9rZW4uYXV0b2NvbXBsZXRpb25TdHJpbmcgPSB0b2tlbi5hdXRvY29tcGxldGlvblN0cmluZy5zdWJzdHJpbmcoMCwgdG9rZW4uYXV0b2NvbXBsZXRpb25TdHJpbmcubGVuZ3RoIC0gMSk7XG5cdHJldHVybiB0b2tlbjtcbn07XG5cbnZhciBwb3N0cHJvY2Vzc1Jlc291cmNlVG9rZW5Gb3JDb21wbGV0aW9uID0gZnVuY3Rpb24oeWFzcWUsIHRva2VuLCBzdWdnZXN0ZWRTdHJpbmcpIHtcblx0aWYgKHRva2VuLnRva2VuUHJlZml4ICYmIHRva2VuLmF1dG9jb21wbGV0aW9uU3RyaW5nICYmIHRva2VuLnRva2VuUHJlZml4VXJpKSB7XG5cdFx0Ly8gd2UgbmVlZCB0byBnZXQgdGhlIHN1Z2dlc3RlZCBzdHJpbmcgYmFjayB0byBwcmVmaXhlZCBmb3JtXG5cdFx0c3VnZ2VzdGVkU3RyaW5nID0gdG9rZW4udG9rZW5QcmVmaXggKyBzdWdnZXN0ZWRTdHJpbmcuc3Vic3RyaW5nKHRva2VuLnRva2VuUHJlZml4VXJpLmxlbmd0aCk7XG5cdH0gZWxzZSB7XG5cdFx0Ly8gaXQgaXMgYSByZWd1bGFyIHVyaS4gYWRkICc8JyBhbmQgJz4nIHRvIHN0cmluZ1xuXHRcdHN1Z2dlc3RlZFN0cmluZyA9IFwiPFwiICsgc3VnZ2VzdGVkU3RyaW5nICsgXCI+XCI7XG5cdH1cblx0cmV0dXJuIHN1Z2dlc3RlZFN0cmluZztcbn07XG5cbnZhciBmZXRjaEZyb21Mb3YgPSBmdW5jdGlvbih5YXNxZSwgY29tcGxldGVyLCB0b2tlbiwgY2FsbGJhY2spIHtcblx0aWYgKCF0b2tlbiB8fCAhdG9rZW4uc3RyaW5nIHx8IHRva2VuLnN0cmluZy50cmltKCkubGVuZ3RoID09IDApIHtcblx0XHR5YXNxZS5hdXRvY29tcGxldGVycy5ub3RpZmljYXRpb25zLmdldEVsKGNvbXBsZXRlcilcblx0XHRcdC5lbXB0eSgpXG5cdFx0XHQuYXBwZW5kKFwiTm90aGluZyB0byBhdXRvY29tcGxldGUgeWV0IVwiKTtcblx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cblx0dmFyIG1heFJlc3VsdHMgPSA1MDtcblxuXHR2YXIgYXJncyA9IHtcblx0XHRxOiB0b2tlbi5hdXRvY29tcGxldGlvblN0cmluZyxcblx0XHRwYWdlOiAxXG5cdH07XG5cdGlmIChjb21wbGV0ZXIubmFtZSA9PSBcImNsYXNzZXNcIikge1xuXHRcdGFyZ3MudHlwZSA9IFwiY2xhc3NcIjtcblx0fSBlbHNlIHtcblx0XHRhcmdzLnR5cGUgPSBcInByb3BlcnR5XCI7XG5cdH1cblx0dmFyIHJlc3VsdHMgPSBbXTtcblx0dmFyIHVybCA9IFwiXCI7XG5cdHZhciB1cGRhdGVVcmwgPSBmdW5jdGlvbigpIHtcblx0XHR1cmwgPSBcImh0dHA6Ly9sb3Yub2tmbi5vcmcvZGF0YXNldC9sb3YvYXBpL3YyL2F1dG9jb21wbGV0ZS90ZXJtcz9cIiArICQucGFyYW0oYXJncyk7XG5cdH07XG5cdHVwZGF0ZVVybCgpO1xuXHR2YXIgaW5jcmVhc2VQYWdlID0gZnVuY3Rpb24oKSB7XG5cdFx0YXJncy5wYWdlKys7XG5cdFx0dXBkYXRlVXJsKCk7XG5cdH07XG5cdHZhciBkb1JlcXVlc3RzID0gZnVuY3Rpb24oKSB7XG5cdFx0JC5nZXQoXG5cdFx0XHR1cmwsXG5cdFx0XHRmdW5jdGlvbihkYXRhKSB7XG5cdFx0XHRcdGZvciAodmFyIGkgPSAwOyBpIDwgZGF0YS5yZXN1bHRzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHRcdFx0aWYgKCQuaXNBcnJheShkYXRhLnJlc3VsdHNbaV0udXJpKSAmJiBkYXRhLnJlc3VsdHNbaV0udXJpLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRcdHJlc3VsdHMucHVzaChkYXRhLnJlc3VsdHNbaV0udXJpWzBdKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0cmVzdWx0cy5wdXNoKGRhdGEucmVzdWx0c1tpXS51cmkpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9XG5cdFx0XHRcdGlmIChyZXN1bHRzLmxlbmd0aCA8IGRhdGEudG90YWxfcmVzdWx0cyAmJiByZXN1bHRzLmxlbmd0aCA8IG1heFJlc3VsdHMpIHtcblx0XHRcdFx0XHRpbmNyZWFzZVBhZ2UoKTtcblx0XHRcdFx0XHRkb1JlcXVlc3RzKCk7XG5cdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0Ly9pZiBub3RpZmljYXRpb24gYmFyIGlzIHRoZXJlLCBzaG93IGZlZWRiYWNrLCBvciBjbG9zZVxuXHRcdFx0XHRcdGlmIChyZXN1bHRzLmxlbmd0aCA+IDApIHtcblx0XHRcdFx0XHRcdHlhc3FlLmF1dG9jb21wbGV0ZXJzLm5vdGlmaWNhdGlvbnMuaGlkZSh5YXNxZSwgY29tcGxldGVyKVxuXHRcdFx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFx0XHR5YXNxZS5hdXRvY29tcGxldGVycy5ub3RpZmljYXRpb25zLmdldEVsKGNvbXBsZXRlcikudGV4dChcIjAgbWF0Y2hlcyBmb3VuZC4uLlwiKTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0Y2FsbGJhY2socmVzdWx0cyk7XG5cdFx0XHRcdFx0Ly8gcmVxdWVzdHMgZG9uZSEgRG9uJ3QgY2FsbCB0aGlzIGZ1bmN0aW9uIGFnYWluXG5cdFx0XHRcdH1cblx0XHRcdH0pLmZhaWwoZnVuY3Rpb24oanFYSFIsIHRleHRTdGF0dXMsIGVycm9yVGhyb3duKSB7XG5cdFx0XHR5YXNxZS5hdXRvY29tcGxldGVycy5ub3RpZmljYXRpb25zLmdldEVsKGNvbXBsZXRlcilcblx0XHRcdFx0LmVtcHR5KClcblx0XHRcdFx0LmFwcGVuZChcIkZhaWxlZCBmZXRjaGluZyBzdWdnZXN0aW9ucy4uXCIpO1xuXG5cdFx0fSk7XG5cdH07XG5cdC8vaWYgbm90aWZpY2F0aW9uIGJhciBpcyB0aGVyZSwgc2hvdyBhIGxvYWRlclxuXHR5YXNxZS5hdXRvY29tcGxldGVycy5ub3RpZmljYXRpb25zLmdldEVsKGNvbXBsZXRlcilcblx0XHQuZW1wdHkoKVxuXHRcdC5hcHBlbmQoJChcIjxzcGFuPkZldGNodGluZyBhdXRvY29tcGxldGlvbnMgJm5ic3A7PC9zcGFuPlwiKSlcblx0XHQuYXBwZW5kKCQoeXV0aWxzLnN2Zy5nZXRFbGVtZW50KHJlcXVpcmUoJy4uL2ltZ3MuanMnKS5sb2FkZXIpKS5hZGRDbGFzcyhcIm5vdGlmaWNhdGlvbkxvYWRlclwiKSk7XG5cdGRvUmVxdWVzdHMoKTtcbn07XG5cblxuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0ZmV0Y2hGcm9tTG92OiBmZXRjaEZyb21Mb3YsXG5cdHByZXByb2Nlc3NSZXNvdXJjZVRva2VuRm9yQ29tcGxldGlvbjogcHJlcHJvY2Vzc1Jlc291cmNlVG9rZW5Gb3JDb21wbGV0aW9uLFxuXHRwb3N0cHJvY2Vzc1Jlc291cmNlVG9rZW5Gb3JDb21wbGV0aW9uOiBwb3N0cHJvY2Vzc1Jlc291cmNlVG9rZW5Gb3JDb21wbGV0aW9uLFxufTsiLCIndXNlIHN0cmljdCc7XG52YXIgJCA9IHJlcXVpcmUoJ2pxdWVyeScpO1xubW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbih5YXNxZSkge1xuXHRyZXR1cm4ge1xuXHRcdGlzVmFsaWRDb21wbGV0aW9uUG9zaXRpb246IGZ1bmN0aW9uKCkge1xuXHRcdFx0dmFyIHRva2VuID0geWFzcWUuZ2V0VG9rZW5BdCh5YXNxZS5nZXRDdXJzb3IoKSk7XG5cdFx0XHRpZiAodG9rZW4udHlwZSAhPSBcIndzXCIpIHtcblx0XHRcdFx0dG9rZW4gPSB5YXNxZS5nZXRDb21wbGV0ZVRva2VuKHRva2VuKTtcblx0XHRcdFx0aWYgKHRva2VuICYmIHRva2VuLnN0cmluZy5pbmRleE9mKFwiP1wiKSA9PSAwKSB7XG5cdFx0XHRcdFx0cmV0dXJuIHRydWU7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHRcdHJldHVybiBmYWxzZTtcblx0XHR9LFxuXHRcdGdldDogZnVuY3Rpb24odG9rZW4pIHtcblx0XHRcdGlmICh0b2tlbi50cmltKCkubGVuZ3RoID09IDApIHJldHVybiBbXTsgLy9ub3RoaW5nIHRvIGF1dG9jb21wbGV0ZVxuXHRcdFx0dmFyIGRpc3RpbmN0VmFycyA9IHt9O1xuXHRcdFx0Ly9kbyB0aGlzIG91dHNpZGUgb2YgY29kZW1pcnJvci4gSSBleHBlY3QganF1ZXJ5IHRvIGJlIGZhc3RlciBoZXJlIChqdXN0IGZpbmRpbmcgZG9tIGVsZW1lbnRzIHdpdGggY2xhc3NuYW1lcylcblx0XHRcdCQoeWFzcWUuZ2V0V3JhcHBlckVsZW1lbnQoKSkuZmluZChcIi5jbS1hdG9tXCIpLmVhY2goZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHZhciB2YXJpYWJsZSA9IHRoaXMuaW5uZXJIVE1MO1xuXHRcdFx0XHRpZiAodmFyaWFibGUuaW5kZXhPZihcIj9cIikgPT0gMCkge1xuXHRcdFx0XHRcdC8vb2ssIGxldHMgY2hlY2sgaWYgdGhlIG5leHQgZWxlbWVudCBpbiB0aGUgZGl2IGlzIGFuIGF0b20gYXMgd2VsbC4gSW4gdGhhdCBjYXNlLCB0aGV5IGJlbG9uZyB0b2dldGhlciAobWF5IGhhcHBlbiBzb21ldGltZXMgd2hlbiBxdWVyeSBpcyBub3Qgc3ludGFjdGljYWxseSB2YWxpZClcblx0XHRcdFx0XHR2YXIgbmV4dEVsID0gJCh0aGlzKS5uZXh0KCk7XG5cdFx0XHRcdFx0dmFyIG5leHRFbENsYXNzID0gbmV4dEVsLmF0dHIoJ2NsYXNzJyk7XG5cdFx0XHRcdFx0aWYgKG5leHRFbENsYXNzICYmIG5leHRFbC5hdHRyKCdjbGFzcycpLmluZGV4T2YoXCJjbS1hdG9tXCIpID49IDApIHtcblx0XHRcdFx0XHRcdHZhcmlhYmxlICs9IG5leHRFbC50ZXh0KCk7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly9za2lwIHNpbmdsZSBxdWVzdGlvbm1hcmtzXG5cdFx0XHRcdFx0aWYgKHZhcmlhYmxlLmxlbmd0aCA8PSAxKSByZXR1cm47XG5cblx0XHRcdFx0XHQvL2l0IHNob3VsZCBtYXRjaCBvdXIgdG9rZW4gb2Zjb3Vyc2Vcblx0XHRcdFx0XHRpZiAodmFyaWFibGUuaW5kZXhPZih0b2tlbikgIT09IDApIHJldHVybjtcblxuXHRcdFx0XHRcdC8vc2tpcCBleGFjdCBtYXRjaGVzXG5cdFx0XHRcdFx0aWYgKHZhcmlhYmxlID09IHRva2VuKSByZXR1cm47XG5cblx0XHRcdFx0XHQvL3N0b3JlIGluIG1hcCBzbyB3ZSBoYXZlIGEgdW5pcXVlIGxpc3QgXG5cdFx0XHRcdFx0ZGlzdGluY3RWYXJzW3ZhcmlhYmxlXSA9IHRydWU7XG5cblxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHRcdHZhciB2YXJpYWJsZXMgPSBbXTtcblx0XHRcdGZvciAodmFyIHZhcmlhYmxlIGluIGRpc3RpbmN0VmFycykge1xuXHRcdFx0XHR2YXJpYWJsZXMucHVzaCh2YXJpYWJsZSk7XG5cdFx0XHR9XG5cdFx0XHR2YXJpYWJsZXMuc29ydCgpO1xuXHRcdFx0cmV0dXJuIHZhcmlhYmxlcztcblx0XHR9LFxuXHRcdGFzeW5jOiBmYWxzZSxcblx0XHRidWxrOiBmYWxzZSxcblx0XHRhdXRvU2hvdzogdHJ1ZSxcblx0fVxufTsiLCIvKipcbiAqIFRoZSBkZWZhdWx0IG9wdGlvbnMgb2YgWUFTUUUgKGNoZWNrIHRoZSBDb2RlTWlycm9yIGRvY3VtZW50YXRpb24gZm9yIGV2ZW5cbiAqIG1vcmUgb3B0aW9ucywgc3VjaCBhcyBkaXNhYmxpbmcgbGluZSBudW1iZXJzLCBvciBjaGFuZ2luZyBrZXlib2FyZCBzaG9ydGN1dFxuICoga2V5cykuIEVpdGhlciBjaGFuZ2UgdGhlIGRlZmF1bHQgb3B0aW9ucyBieSBzZXR0aW5nIFlBU1FFLmRlZmF1bHRzLCBvciBieVxuICogcGFzc2luZyB5b3VyIG93biBvcHRpb25zIGFzIHNlY29uZCBhcmd1bWVudCB0byB0aGUgWUFTUUUgY29uc3RydWN0b3JcbiAqL1xudmFyICQgPSByZXF1aXJlKCdqcXVlcnknKSxcblx0WUFTUUUgPSByZXF1aXJlKCcuL21haW4uanMnKTtcbllBU1FFLmRlZmF1bHRzID0gJC5leHRlbmQodHJ1ZSwge30sIFlBU1FFLmRlZmF1bHRzLCB7XG5cdG1vZGU6IFwic3BhcnFsMTFcIixcblx0LyoqXG5cdCAqIFF1ZXJ5IHN0cmluZ1xuXHQgKi9cblx0dmFsdWU6IFwiUFJFRklYIHJkZjogPGh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyM+XFxuUFJFRklYIHJkZnM6IDxodHRwOi8vd3d3LnczLm9yZy8yMDAwLzAxL3JkZi1zY2hlbWEjPlxcblNFTEVDVCAqIFdIRVJFIHtcXG4gID9zdWIgP3ByZWQgP29iaiAuXFxufSBcXG5MSU1JVCAxMFwiLFxuXHRoaWdobGlnaHRTZWxlY3Rpb25NYXRjaGVzOiB7XG5cdFx0c2hvd1Rva2VuOiAvXFx3L1xuXHR9LFxuXHR0YWJNb2RlOiBcImluZGVudFwiLFxuXHRsaW5lTnVtYmVyczogdHJ1ZSxcblx0bGluZVdyYXBwaW5nOiB0cnVlLFxuXHRiYWNrZHJvcDogZmFsc2UsXG5cdGZvbGRHdXR0ZXI6IHtcblx0XHRyYW5nZUZpbmRlcjogbmV3IFlBU1FFLmZvbGQuY29tYmluZShZQVNRRS5mb2xkLmJyYWNlLCBZQVNRRS5mb2xkLnByZWZpeClcblx0fSxcblx0Y29sbGFwc2VQcmVmaXhlc09uTG9hZDogZmFsc2UsXG5cdGd1dHRlcnM6IFtcImd1dHRlckVycm9yQmFyXCIsIFwiQ29kZU1pcnJvci1saW5lbnVtYmVyc1wiLCBcIkNvZGVNaXJyb3ItZm9sZGd1dHRlclwiXSxcblx0bWF0Y2hCcmFja2V0czogdHJ1ZSxcblx0Zml4ZWRHdXR0ZXI6IHRydWUsXG5cdHN5bnRheEVycm9yQ2hlY2s6IHRydWUsXG5cdC8qKlxuXHQgKiBFeHRyYSBzaG9ydGN1dCBrZXlzLiBDaGVjayB0aGUgQ29kZU1pcnJvciBtYW51YWwgb24gaG93IHRvIGFkZCB5b3VyIG93blxuXHQgKlxuXHQgKiBAcHJvcGVydHkgZXh0cmFLZXlzXG5cdCAqIEB0eXBlIG9iamVjdFxuXHQgKi9cblx0ZXh0cmFLZXlzOiB7XG5cdFx0Ly9cdFx0XHRcdFx0XCJDdHJsLVNwYWNlXCIgOiBmdW5jdGlvbih5YXNxZSkge1xuXHRcdC8vXHRcdFx0XHRcdFx0WUFTUUUuYXV0b0NvbXBsZXRlKHlhc3FlKTtcblx0XHQvL1x0XHRcdFx0XHR9LFxuXHRcdFwiQ3RybC1TcGFjZVwiOiBZQVNRRS5hdXRvQ29tcGxldGUsXG5cblx0XHRcIkNtZC1TcGFjZVwiOiBZQVNRRS5hdXRvQ29tcGxldGUsXG5cdFx0XCJDdHJsLURcIjogWUFTUUUuZGVsZXRlTGluZSxcblx0XHRcIkN0cmwtS1wiOiBZQVNRRS5kZWxldGVMaW5lLFxuXHRcdFwiQ21kLURcIjogWUFTUUUuZGVsZXRlTGluZSxcblx0XHRcIkNtZC1LXCI6IFlBU1FFLmRlbGV0ZUxpbmUsXG5cdFx0XCJDdHJsLS9cIjogWUFTUUUuY29tbWVudExpbmVzLFxuXHRcdFwiQ21kLS9cIjogWUFTUUUuY29tbWVudExpbmVzLFxuXHRcdFwiQ3RybC1BbHQtRG93blwiOiBZQVNRRS5jb3B5TGluZURvd24sXG5cdFx0XCJDdHJsLUFsdC1VcFwiOiBZQVNRRS5jb3B5TGluZVVwLFxuXHRcdFwiQ21kLUFsdC1Eb3duXCI6IFlBU1FFLmNvcHlMaW5lRG93bixcblx0XHRcIkNtZC1BbHQtVXBcIjogWUFTUUUuY29weUxpbmVVcCxcblx0XHRcIlNoaWZ0LUN0cmwtRlwiOiBZQVNRRS5kb0F1dG9Gb3JtYXQsXG5cdFx0XCJTaGlmdC1DbWQtRlwiOiBZQVNRRS5kb0F1dG9Gb3JtYXQsXG5cdFx0XCJDdHJsLV1cIjogWUFTUUUuaW5kZW50TW9yZSxcblx0XHRcIkNtZC1dXCI6IFlBU1FFLmluZGVudE1vcmUsXG5cdFx0XCJDdHJsLVtcIjogWUFTUUUuaW5kZW50TGVzcyxcblx0XHRcIkNtZC1bXCI6IFlBU1FFLmluZGVudExlc3MsXG5cdFx0XCJDdHJsLVNcIjogWUFTUUUuc3RvcmVRdWVyeSxcblx0XHRcIkNtZC1TXCI6IFlBU1FFLnN0b3JlUXVlcnksXG5cdFx0XCJDdHJsLUVudGVyXCI6IFlBU1FFLmV4ZWN1dGVRdWVyeSxcblx0XHRcIkNtZC1FbnRlclwiOiBZQVNRRS5leGVjdXRlUXVlcnksXG5cdFx0XCJGMTFcIjogZnVuY3Rpb24oeWFzcWUpIHtcblx0XHRcdHlhc3FlLnNldE9wdGlvbihcImZ1bGxTY3JlZW5cIiwgIXlhc3FlLmdldE9wdGlvbihcImZ1bGxTY3JlZW5cIikpO1xuXHRcdH0sXG5cdFx0XCJFc2NcIjogZnVuY3Rpb24oeWFzcWUpIHtcblx0XHRcdGlmICh5YXNxZS5nZXRPcHRpb24oXCJmdWxsU2NyZWVuXCIpKSB5YXNxZS5zZXRPcHRpb24oXCJmdWxsU2NyZWVuXCIsIGZhbHNlKTtcblx0XHR9XG5cdH0sXG5cdGN1cnNvckhlaWdodDogMC45LFxuXG5cblx0LyoqXG5cdCAqIFNob3cgYSBidXR0b24gd2l0aCB3aGljaCB1c2VycyBjYW4gY3JlYXRlIGEgbGluayB0byB0aGlzIHF1ZXJ5LiBTZXQgdGhpcyB2YWx1ZSB0byBudWxsIHRvIGRpc2FibGUgdGhpcyBmdW5jdGlvbmFsaXR5LlxuXHQgKiBCeSBkZWZhdWx0LCB0aGlzIGZlYXR1cmUgaXMgZW5hYmxlZCwgYW5kIHRoZSBvbmx5IHRoZSBxdWVyeSB2YWx1ZSBpcyBhcHBlbmRlZCB0byB0aGUgbGluay5cblx0ICogcHMuIFRoaXMgZnVuY3Rpb24gc2hvdWxkIHJldHVybiBhbiBvYmplY3Qgd2hpY2ggaXMgcGFyc2VhYmxlIGJ5IGpRdWVyeS5wYXJhbSAoaHR0cDovL2FwaS5qcXVlcnkuY29tL2pRdWVyeS5wYXJhbS8pXG5cdCAqL1xuXHRjcmVhdGVTaGFyZUxpbms6IFlBU1FFLmNyZWF0ZVNoYXJlTGluayxcblxuXHRjcmVhdGVTaG9ydExpbms6IG51bGwsXG5cblx0LyoqXG5cdCAqIENvbnN1bWUgbGlua3Mgc2hhcmVkIGJ5IG90aGVycywgYnkgY2hlY2tpbmcgdGhlIHVybCBmb3IgYXJndW1lbnRzIGNvbWluZyBmcm9tIGEgcXVlcnkgbGluay4gRGVmYXVsdHMgYnkgb25seSBjaGVja2luZyB0aGUgJ3F1ZXJ5PScgYXJndW1lbnQgaW4gdGhlIHVybFxuXHQgKi9cblx0Y29uc3VtZVNoYXJlTGluazogWUFTUUUuY29uc3VtZVNoYXJlTGluayxcblxuXG5cblxuXHQvKipcblx0ICogQ2hhbmdlIHBlcnNpc3RlbmN5IHNldHRpbmdzIGZvciB0aGUgWUFTUUUgcXVlcnkgdmFsdWUuIFNldHRpbmcgdGhlIHZhbHVlc1xuXHQgKiB0byBudWxsLCB3aWxsIGRpc2FibGUgcGVyc2lzdGFuY3k6IG5vdGhpbmcgaXMgc3RvcmVkIGJldHdlZW4gYnJvd3NlclxuXHQgKiBzZXNzaW9ucyBTZXR0aW5nIHRoZSB2YWx1ZXMgdG8gYSBzdHJpbmcgKG9yIGEgZnVuY3Rpb24gd2hpY2ggcmV0dXJucyBhXG5cdCAqIHN0cmluZyksIHdpbGwgc3RvcmUgdGhlIHF1ZXJ5IGluIGxvY2Fsc3RvcmFnZSB1c2luZyB0aGUgc3BlY2lmaWVkIHN0cmluZy5cblx0ICogQnkgZGVmYXVsdCwgdGhlIElEIGlzIGR5bmFtaWNhbGx5IGdlbmVyYXRlZCB1c2luZyB0aGUgY2xvc2VzdCBkb20gSUQsIHRvIGF2b2lkIGNvbGxpc3Npb25zIHdoZW4gdXNpbmcgbXVsdGlwbGUgWUFTUUUgaXRlbXMgb24gb25lXG5cdCAqIHBhZ2Vcblx0ICpcblx0ICogQHR5cGUgZnVuY3Rpb258c3RyaW5nXG5cdCAqL1xuXHRwZXJzaXN0ZW50OiBmdW5jdGlvbih5YXNxZSkge1xuXHRcdHJldHVybiBcInlhc3FlX1wiICsgJCh5YXNxZS5nZXRXcmFwcGVyRWxlbWVudCgpKS5jbG9zZXN0KCdbaWRdJykuYXR0cignaWQnKSArIFwiX3F1ZXJ5VmFsXCI7XG5cdH0sXG5cblxuXHQvKipcblx0ICogU2V0dGluZ3MgZm9yIHF1ZXJ5aW5nIHNwYXJxbCBlbmRwb2ludHNcblx0ICovXG5cdHNwYXJxbDoge1xuXHRcdHNob3dRdWVyeUJ1dHRvbjogZmFsc2UsXG5cblx0XHQvKipmXG5cdFx0ICogRW5kcG9pbnQgdG8gcXVlcnlcblx0XHQgKlxuXHRcdCAqIEBwcm9wZXJ0eSBzcGFycWwuZW5kcG9pbnRcblx0XHQgKiBAdHlwZSBTdHJpbmd8ZnVuY3Rpb25cblx0XHQgKi9cblx0XHRlbmRwb2ludDogXCJodHRwOi8vZGJwZWRpYS5vcmcvc3BhcnFsXCIsXG5cdFx0LyoqXG5cdFx0ICogUmVxdWVzdCBtZXRob2QgdmlhIHdoaWNoIHRvIGFjY2VzcyBTUEFSUUwgZW5kcG9pbnRcblx0XHQgKlxuXHRcdCAqIEBwcm9wZXJ0eSBzcGFycWwucmVxdWVzdE1ldGhvZFxuXHRcdCAqIEB0eXBlIFN0cmluZ3xmdW5jdGlvblxuXHRcdCAqL1xuXHRcdHJlcXVlc3RNZXRob2Q6IFwiUE9TVFwiLFxuXG5cdFx0LyoqXG5cdFx0ICogQHR5cGUgU3RyaW5nfGZ1bmN0aW9uXG5cdFx0ICovXG5cdFx0YWNjZXB0SGVhZGVyR3JhcGg6IFwidGV4dC90dXJ0bGUsKi8qO3E9MC45XCIsXG5cdFx0LyoqXG5cdFx0ICogQHR5cGUgU3RyaW5nfGZ1bmN0aW9uXG5cdFx0ICovXG5cdFx0YWNjZXB0SGVhZGVyU2VsZWN0OiBcImFwcGxpY2F0aW9uL3NwYXJxbC1yZXN1bHRzK2pzb24sKi8qO3E9MC45XCIsXG5cdFx0LyoqXG5cdFx0ICogQHR5cGUgU3RyaW5nfGZ1bmN0aW9uXG5cdFx0ICovXG5cdFx0YWNjZXB0SGVhZGVyVXBkYXRlOiBcInRleHQvcGxhaW4sKi8qO3E9MC45XCIsXG5cblx0XHQvKipcblx0XHQgKiBOYW1lZCBncmFwaHMgdG8gcXVlcnkuXG5cdFx0ICovXG5cdFx0bmFtZWRHcmFwaHM6IFtdLFxuXHRcdC8qKlxuXHRcdCAqIERlZmF1bHQgZ3JhcGhzIHRvIHF1ZXJ5LlxuXHRcdCAqL1xuXHRcdGRlZmF1bHRHcmFwaHM6IFtdLFxuXG5cdFx0LyoqXG5cdFx0ICogQWRkaXRpb25hbCByZXF1ZXN0IGFyZ3VtZW50cy4gQWRkIHRoZW0gaW4gdGhlIGZvcm06IHtuYW1lOiBcIm5hbWVcIiwgdmFsdWU6IFwidmFsdWVcIn1cblx0XHQgKi9cblx0XHRhcmdzOiBbXSxcblxuXHRcdC8qKlxuXHRcdCAqIEFkZGl0aW9uYWwgcmVxdWVzdCBoZWFkZXJzXG5cdFx0ICovXG5cdFx0aGVhZGVyczoge30sXG5cblx0XHRnZXRRdWVyeUZvckFqYXg6IG51bGwsXG5cdFx0LyoqXG5cdFx0ICogU2V0IG9mIGFqYXggY2FsbGJhY2tzXG5cdFx0ICovXG5cdFx0Y2FsbGJhY2tzOiB7XG5cdFx0XHRiZWZvcmVTZW5kOiBudWxsLFxuXHRcdFx0Y29tcGxldGU6IG51bGwsXG5cdFx0XHRlcnJvcjogbnVsbCxcblx0XHRcdHN1Y2Nlc3M6IG51bGxcblx0XHR9LFxuXHRcdGhhbmRsZXJzOiB7fSAvL2tlZXAgaGVyZSBmb3IgYmFja3dhcmRzIGNvbXBhdGFiaWxpdHlcblx0fSxcbn0pO1xuIiwiJ3VzZSBzdHJpY3QnO1xubW9kdWxlLmV4cG9ydHMgPSB7XG5cdHF1ZXJ5OiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmVyc2lvbj1cIjEuMVwiIHg9XCIwcHhcIiB5PVwiMHB4XCIgd2lkdGg9XCIxMDAlXCIgaGVpZ2h0PVwiMTAwJVwiIHZpZXdCb3g9XCIwIDAgODAgODBcIiBlbmFibGUtYmFja2dyb3VuZD1cIm5ldyAwIDAgODAgODBcIiB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiPjxnID48L2c+PGcgPlx0PHBhdGggZD1cIk02NC42MjIsMi40MTFIMTQuOTk1Yy02LjYyNywwLTEyLDUuMzczLTEyLDEydjQ5Ljg5N2MwLDYuNjI3LDUuMzczLDEyLDEyLDEyaDQ5LjYyN2M2LjYyNywwLDEyLTUuMzczLDEyLTEyVjE0LjQxMSAgIEM3Ni42MjIsNy43ODMsNzEuMjQ5LDIuNDExLDY0LjYyMiwyLjQxMXogTTI0LjEyNSw2My45MDZWMTUuMDkzTDYxLDM5LjE2OEwyNC4xMjUsNjMuOTA2elwiLz48L2c+PC9zdmc+Jyxcblx0cXVlcnlJbnZhbGlkOiAnPHN2ZyAgIHhtbG5zOmRjPVwiaHR0cDovL3B1cmwub3JnL2RjL2VsZW1lbnRzLzEuMS9cIiAgIHhtbG5zOmNjPVwiaHR0cDovL2NyZWF0aXZlY29tbW9ucy5vcmcvbnMjXCIgICB4bWxuczpyZGY9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjXCIgICB4bWxuczpzdmc9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiICAgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiICAgeG1sbnM6c29kaXBvZGk9XCJodHRwOi8vc29kaXBvZGkuc291cmNlZm9yZ2UubmV0L0RURC9zb2RpcG9kaS0wLmR0ZFwiICAgeG1sbnM6aW5rc2NhcGU9XCJodHRwOi8vd3d3Lmlua3NjYXBlLm9yZy9uYW1lc3BhY2VzL2lua3NjYXBlXCIgICB2ZXJzaW9uPVwiMS4xXCIgICB4PVwiMHB4XCIgICB5PVwiMHB4XCIgICB3aWR0aD1cIjEwMCVcIiAgIGhlaWdodD1cIjEwMCVcIiAgIHZpZXdCb3g9XCIwIDAgNzMuNjI3IDczLjg5N1wiICAgZW5hYmxlLWJhY2tncm91bmQ9XCJuZXcgMCAwIDgwIDgwXCIgICB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiICAgICAgaW5rc2NhcGU6dmVyc2lvbj1cIjAuNDguNCByOTkzOVwiICAgc29kaXBvZGk6ZG9jbmFtZT1cIndhcm5pbmcuc3ZnXCI+PG1ldGFkYXRhICAgICA+PHJkZjpSREY+PGNjOldvcmsgICAgICAgICByZGY6YWJvdXQ9XCJcIj48ZGM6Zm9ybWF0PmltYWdlL3N2Zyt4bWw8L2RjOmZvcm1hdD48ZGM6dHlwZSAgICAgICAgICAgcmRmOnJlc291cmNlPVwiaHR0cDovL3B1cmwub3JnL2RjL2RjbWl0eXBlL1N0aWxsSW1hZ2VcIiAvPjwvY2M6V29yaz48L3JkZjpSREY+PC9tZXRhZGF0YT48ZGVmcyAgICAgIC8+PHNvZGlwb2RpOm5hbWVkdmlldyAgICAgcGFnZWNvbG9yPVwiI2ZmZmZmZlwiICAgICBib3JkZXJjb2xvcj1cIiM2NjY2NjZcIiAgICAgYm9yZGVyb3BhY2l0eT1cIjFcIiAgICAgb2JqZWN0dG9sZXJhbmNlPVwiMTBcIiAgICAgZ3JpZHRvbGVyYW5jZT1cIjEwXCIgICAgIGd1aWRldG9sZXJhbmNlPVwiMTBcIiAgICAgaW5rc2NhcGU6cGFnZW9wYWNpdHk9XCIwXCIgICAgIGlua3NjYXBlOnBhZ2VzaGFkb3c9XCIyXCIgICAgIGlua3NjYXBlOndpbmRvdy13aWR0aD1cIjE4NTVcIiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD1cIjEwNTZcIiAgICAgICAgICBzaG93Z3JpZD1cImZhbHNlXCIgICAgIGlua3NjYXBlOnpvb209XCIzLjE5MzYzNDRcIiAgICAgaW5rc2NhcGU6Y3g9XCIzNi44MTM1XCIgICAgIGlua3NjYXBlOmN5PVwiMzYuOTQ4NVwiICAgICBpbmtzY2FwZTp3aW5kb3cteD1cIjI2MjVcIiAgICAgaW5rc2NhcGU6d2luZG93LXk9XCIyNFwiICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPVwiMVwiICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPVwic3ZnMlwiIC8+PGcgICAgIHRyYW5zZm9ybT1cInRyYW5zbGF0ZSgtMi45OTUsLTIuNDExKVwiICAgICAgLz48ZyAgICAgdHJhbnNmb3JtPVwidHJhbnNsYXRlKC0yLjk5NSwtMi40MTEpXCIgICAgID48cGF0aCAgICAgICBkPVwiTSA2NC42MjIsMi40MTEgSCAxNC45OTUgYyAtNi42MjcsMCAtMTIsNS4zNzMgLTEyLDEyIHYgNDkuODk3IGMgMCw2LjYyNyA1LjM3MywxMiAxMiwxMiBoIDQ5LjYyNyBjIDYuNjI3LDAgMTIsLTUuMzczIDEyLC0xMiBWIDE0LjQxMSBjIDAsLTYuNjI4IC01LjM3MywtMTIgLTEyLC0xMiB6IE0gMjQuMTI1LDYzLjkwNiBWIDE1LjA5MyBMIDYxLDM5LjE2OCAyNC4xMjUsNjMuOTA2IHpcIiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPVwiMFwiICAgICAgICAvPjwvZz48cGF0aCAgICAgZD1cIk0gNjYuMTI5MzgxLDY1LjkwMzc4NCBIIDQ5Ljc2OTg3NSBjIC0xLjY0NzIxLDAgLTIuODg5Mzg1LC0wLjU4MTE0NiAtMy40OTg2NzgsLTEuNjM1OTUgLTAuNjA5MjkzLC0xLjA1NTYwOCAtMC40OTEwNzksLTIuNDIyMTYxIDAuMzMyMzkxLC0zLjg0ODIyMyBsIDguMTc5NzUzLC0xNC4xNjcwNjkgYyAwLjgyMjkzNCwtMS40MjYzMyAxLjk0NzcsLTIuMjExNzM3IDMuMTY2MDE4LC0yLjIxMTczNyAxLjIxODMxOSwwIDIuMzQzMDg2LDAuNzg1NDA3IDMuMTY2MDE5LDIuMjExNzM3IGwgOC4xNzk3NTEsMTQuMTY3MDY5IGMgMC44MjM0NzIsMS40MjYwNjIgMC45NDE2ODYsMi43OTI2MTUgMC4zMzIzOSwzLjg0ODIyMyAtMC42MDkwMjMsMS4wNTQ4MDQgLTEuODUxMTk3LDEuNjM1OTUgLTMuNDk4MTM4LDEuNjM1OTUgeiBNIDU5LjYxODgxNSw2MC45MTc2NiBjIDAsLTAuODUwMjc2IC0wLjY4OTQ0LC0xLjUzOTcxOSAtMS41Mzk3MTcsLTEuNTM5NzE5IC0wLjg1MDI3NiwwIC0xLjUzOTcxOCwwLjY4OTQ0MyAtMS41Mzk3MTgsMS41Mzk3MTkgMCwwLjg1MDI3NyAwLjY4OTQ0MiwxLjUzOTcxOCAxLjUzOTcxOCwxLjUzOTcxOCAwLjg1MDI3NywwIDEuNTM5NzE3LC0wLjY4OTQ0MSAxLjUzOTcxNywtMS41Mzk3MTggeiBtIDAuMDQxNTUsLTkuMjY1OTE5IGMgMCwtMC44NzMwNjEgLTAuNzA3OTM5LC0xLjU4MDk5OCAtMS41ODA5OTksLTEuNTgwOTk4IC0wLjg3MzA2MSwwIC0xLjU4MDk5OSwwLjcwNzkzNyAtMS41ODA5OTksMS41ODA5OTggbCAwLjM3MzQwMyw1LjYxMDk2NSBoIDAuMDA1MSBjIDAuMDU0MTUsMC42MTk3NDcgMC41Njg1NDgsMS4xMDc2MSAxLjIwMjUwNCwxLjEwNzYxIDAuNTg2MjM5LDAgMS4wNzU0NDMsLTAuNDE1NzU2IDEuMTg4NTYzLC0wLjk2ODQ4OSAwLjAwOTIsLTAuMDQ0NzYgMC4wMDk5LC0wLjA5MjQ4IDAuMDEzOTIsLTAuMTM4ODU0IGggMC4wMTA3MiBsIDAuMzY3Nzc2LC01LjYxMTIzMiB6XCIgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT1cIjBcIiAgICAgc3R5bGU9XCJmaWxsOiNhYTg4MDBcIiAvPjwvc3ZnPicsXG5cdGRvd25sb2FkOiAnPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgeG1sbnM6eGxpbms9XCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rXCIgdmVyc2lvbj1cIjEuMVwiIGJhc2VQcm9maWxlPVwidGlueVwiIHg9XCIwcHhcIiB5PVwiMHB4XCIgd2lkdGg9XCIxMDAlXCIgaGVpZ2h0PVwiMTAwJVwiIHZpZXdCb3g9XCIwIDAgMTAwIDEwMFwiIHhtbDpzcGFjZT1cInByZXNlcnZlXCI+PGcgPjwvZz48ZyA+XHQ8cGF0aCBmaWxsLXJ1bGU9XCJldmVub2RkXCIgZmlsbD1cIiMwMDAwMDBcIiBkPVwiTTg4LDg0di0yYzAtMi45NjEtMC44NTktNC00LTRIMTZjLTIuOTYxLDAtNCwwLjk4LTQsNHYyYzAsMy4xMDIsMS4wMzksNCw0LDRoNjggICBDODcuMDIsODgsODgsODcuMDM5LDg4LDg0eiBNNTgsMTJINDJjLTUsMC02LDAuOTQxLTYsNnYyMkgxNmwzNCwzNGwzNC0zNEg2NFYxOEM2NCwxMi45NDEsNjIuOTM5LDEyLDU4LDEyelwiLz48L2c+PC9zdmc+Jyxcblx0c2hhcmU6ICc8c3ZnIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4bWxuczp4bGluaz1cImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIiB2ZXJzaW9uPVwiMS4xXCIgIHg9XCIwcHhcIiB5PVwiMHB4XCIgd2lkdGg9XCIxMDAlXCIgaGVpZ2h0PVwiMTAwJVwiIHZpZXdCb3g9XCIwIDAgMTAwIDEwMFwiIHN0eWxlPVwiZW5hYmxlLWJhY2tncm91bmQ6bmV3IDAgMCAxMDAgMTAwO1wiIHhtbDpzcGFjZT1cInByZXNlcnZlXCI+PHBhdGggZD1cIk0zNi43NjQsNTBjMCwwLjMwOC0wLjA3LDAuNTk4LTAuMDg4LDAuOTA1bDMyLjI0NywxNi4xMTljMi43Ni0yLjMzOCw2LjI5My0zLjc5NywxMC4xOTUtMy43OTcgIEM4Ny44OSw2My4yMjgsOTUsNzAuMzM4LDk1LDc5LjEwOUM5NSw4Ny44OSw4Ny44OSw5NSw3OS4xMTgsOTVjLTguNzgsMC0xNS44ODItNy4xMS0xNS44ODItMTUuODkxYzAtMC4zMTYsMC4wNy0wLjU5OCwwLjA4OC0wLjkwNSAgTDMxLjA3Nyw2Mi4wODVjLTIuNzY5LDIuMzI5LTYuMjkzLDMuNzg4LTEwLjE5NSwzLjc4OEMxMi4xMSw2NS44NzMsNSw1OC43NzEsNSw1MGMwLTguNzgsNy4xMS0xNS44OTEsMTUuODgyLTE1Ljg5MSAgYzMuOTAyLDAsNy40MjcsMS40NjgsMTAuMTk1LDMuNzk3bDMyLjI0Ny0xNi4xMTljLTAuMDE4LTAuMzA4LTAuMDg4LTAuNTk4LTAuMDg4LTAuOTE0QzYzLjIzNiwxMi4xMSw3MC4zMzgsNSw3OS4xMTgsNSAgQzg3Ljg5LDUsOTUsMTIuMTEsOTUsMjAuODczYzAsOC43OC03LjExLDE1Ljg5MS0xNS44ODIsMTUuODkxYy0zLjkxMSwwLTcuNDM2LTEuNDY4LTEwLjE5NS0zLjgwNkwzNi42NzYsNDkuMDg2ICBDMzYuNjkzLDQ5LjM5NCwzNi43NjQsNDkuNjg0LDM2Ljc2NCw1MHpcIi8+PC9zdmc+Jyxcblx0d2FybmluZzogJzxzdmcgICB4bWxuczpkYz1cImh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvXCIgICB4bWxuczpjYz1cImh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zI1wiICAgeG1sbnM6cmRmPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zI1wiICAgeG1sbnM6c3ZnPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiAgIHhtbG5zOnNvZGlwb2RpPVwiaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGRcIiAgIHhtbG5zOmlua3NjYXBlPVwiaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZVwiICAgdmVyc2lvbj1cIjEuMVwiICAgeD1cIjBweFwiICAgeT1cIjBweFwiICAgdmlld0JveD1cIjAgMCA2Ni4zOTk5OTggNjYuMzk5OTk4XCIgICBlbmFibGUtYmFja2dyb3VuZD1cIm5ldyAwIDAgNjkuMyA2OS4zXCIgICB4bWw6c3BhY2U9XCJwcmVzZXJ2ZVwiICAgaGVpZ2h0PVwiMTAwJVwiICAgd2lkdGg9XCIxMDAlXCIgICBpbmtzY2FwZTp2ZXJzaW9uPVwiMC40OC40IHI5OTM5XCIgICA+PGcgICAgICB0cmFuc2Zvcm09XCJ0cmFuc2xhdGUoLTEuNSwtMS41KVwiICAgICBzdHlsZT1cImZpbGw6I2ZmMDAwMFwiPjxwYXRoICAgICAgIGQ9XCJNIDM0LjcsMS41IEMgMTYuNCwxLjUgMS41LDE2LjQgMS41LDM0LjcgMS41LDUzIDE2LjQsNjcuOSAzNC43LDY3LjkgNTMsNjcuOSA2Ny45LDUzIDY3LjksMzQuNyA2Ny45LDE2LjQgNTMsMS41IDM0LjcsMS41IHogbSAwLDU5LjQgQyAyMC4yLDYwLjkgOC41LDQ5LjEgOC41LDM0LjcgOC41LDIwLjIgMjAuMyw4LjUgMzQuNyw4LjUgYyAxNC40LDAgMjYuMiwxMS44IDI2LjIsMjYuMiAwLDE0LjQgLTExLjgsMjYuMiAtMjYuMiwyNi4yIHpcIiAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9XCIwXCIgICAgICAgc3R5bGU9XCJmaWxsOiNmZjAwMDBcIiAvPjxwYXRoICAgICAgIGQ9XCJtIDM0LjYsNDcuMSBjIC0xLjQsMCAtMi41LDAuNSAtMy41LDEuNSAtMC45LDEgLTEuNCwyLjIgLTEuNCwzLjYgMCwxLjYgMC41LDIuOCAxLjUsMy44IDEsMC45IDIuMSwxLjMgMy40LDEuMyAxLjMsMCAyLjQsLTAuNSAzLjQsLTEuNCAxLC0wLjkgMS41LC0yLjIgMS41LC0zLjcgMCwtMS40IC0wLjUsLTIuNiAtMS40LC0zLjYgLTAuOSwtMSAtMi4xLC0xLjUgLTMuNSwtMS41IHpcIiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPVwiMFwiICAgICAgIHN0eWxlPVwiZmlsbDojZmYwMDAwXCIgLz48cGF0aCAgICAgICBkPVwibSAzNC44LDEzLjkgYyAtMS41LDAgLTIuOCwwLjUgLTMuNywxLjYgLTAuOSwxIC0xLjQsMi40IC0xLjQsNC4yIDAsMS4xIDAuMSwyLjkgMC4yLDUuNiBsIDAuOCwxMy4xIGMgMC4yLDEuOCAwLjQsMy4yIDAuOSw0LjEgMC41LDEuMiAxLjUsMS44IDIuOSwxLjggMS4zLDAgMi4zLC0wLjcgMi45LC0xLjkgMC41LC0xIDAuNywtMi4zIDAuOSwtNCBMIDM5LjQsMjUgYyAwLjEsLTEuMyAwLjIsLTIuNSAwLjIsLTMuOCAwLC0yLjIgLTAuMywtMy45IC0wLjgsLTUuMSAtMC41LC0xIC0xLjYsLTIuMiAtNCwtMi4yIHpcIiAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPVwiMFwiICAgICAgIHN0eWxlPVwiZmlsbDojZmYwMDAwXCIgLz48L2c+PC9zdmc+Jyxcblx0ZnVsbHNjcmVlbjogJzxzdmcgICB4bWxuczpkYz1cImh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvXCIgICB4bWxuczpjYz1cImh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zI1wiICAgeG1sbnM6cmRmPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zI1wiICAgeG1sbnM6c3ZnPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiAgIHhtbG5zOnNvZGlwb2RpPVwiaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGRcIiAgIHhtbG5zOmlua3NjYXBlPVwiaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZVwiICAgdmVyc2lvbj1cIjEuMVwiICAgICAgeD1cIjBweFwiICAgeT1cIjBweFwiICAgd2lkdGg9XCIxMDAlXCIgICBoZWlnaHQ9XCIxMDAlXCIgICB2aWV3Qm94PVwiNSAtMTAgNzQuMDc0MDc0IDEwMFwiICAgZW5hYmxlLWJhY2tncm91bmQ9XCJuZXcgMCAwIDEwMCAxMDBcIiAgIHhtbDpzcGFjZT1cInByZXNlcnZlXCIgICBpbmtzY2FwZTp2ZXJzaW9uPVwiMC40OC40IHI5OTM5XCIgICBzb2RpcG9kaTpkb2NuYW1lPVwibm91bl8yMTg2X2NjLnN2Z1wiPjxtZXRhZGF0YSAgICAgPjxyZGY6UkRGPjxjYzpXb3JrICAgICAgICAgcmRmOmFib3V0PVwiXCI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUgICAgICAgICAgIHJkZjpyZXNvdXJjZT1cImh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlXCIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMgICAgICAvPjxzb2RpcG9kaTpuYW1lZHZpZXcgICAgIHBhZ2Vjb2xvcj1cIiNmZmZmZmZcIiAgICAgYm9yZGVyY29sb3I9XCIjNjY2NjY2XCIgICAgIGJvcmRlcm9wYWNpdHk9XCIxXCIgICAgIG9iamVjdHRvbGVyYW5jZT1cIjEwXCIgICAgIGdyaWR0b2xlcmFuY2U9XCIxMFwiICAgICBndWlkZXRvbGVyYW5jZT1cIjEwXCIgICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PVwiMFwiICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PVwiMlwiICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9XCI2NDBcIiAgICAgaW5rc2NhcGU6d2luZG93LWhlaWdodD1cIjQ4MFwiICAgICAgICAgIHNob3dncmlkPVwiZmFsc2VcIiAgICAgZml0LW1hcmdpbi10b3A9XCIwXCIgICAgIGZpdC1tYXJnaW4tbGVmdD1cIjBcIiAgICAgZml0LW1hcmdpbi1yaWdodD1cIjBcIiAgICAgZml0LW1hcmdpbi1ib3R0b209XCIwXCIgICAgIGlua3NjYXBlOnpvb209XCIyLjM2XCIgICAgIGlua3NjYXBlOmN4PVwiNDQuMTAxNTA5XCIgICAgIGlua3NjYXBlOmN5PVwiMzEuNDgxNDgxXCIgICAgIGlua3NjYXBlOndpbmRvdy14PVwiNjVcIiAgICAgaW5rc2NhcGU6d2luZG93LXk9XCIyNFwiICAgICBpbmtzY2FwZTp3aW5kb3ctbWF4aW1pemVkPVwiMFwiICAgICBpbmtzY2FwZTpjdXJyZW50LWxheWVyPVwiTGF5ZXJfMVwiIC8+PHBhdGggICAgIGQ9XCJtIC03Ljk2Mjk2MywtMTAgdiAzOC44ODkgbCAxNi42NjcsLTE2LjY2NyAxNi42NjcsMTYuNjY3IDUuNTU1LC01LjU1NSAtMTYuNjY3LC0xNi42NjcgMTYuNjY3LC0xNi42NjcgaCAtMzguODg5IHpcIiAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPVwiMFwiICAgICBzdHlsZT1cImZpbGw6IzAxMDEwMVwiIC8+PHBhdGggICAgIGQ9XCJtIDkyLjAzNzAzNywtMTAgdiAzOC44ODkgbCAtMTYuNjY3LC0xNi42NjcgLTE2LjY2NiwxNi42NjcgLTUuNTU2LC01LjU1NSAxNi42NjYsLTE2LjY2NyAtMTYuNjY2LC0xNi42NjcgaCAzOC44ODkgelwiICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9XCIwXCIgICAgIHN0eWxlPVwiZmlsbDojMDEwMTAxXCIgLz48cGF0aCAgICAgZD1cIk0gLTcuOTYyOTYzLDkwIFYgNTEuMTExIGwgMTYuNjY3LDE2LjY2NiAxNi42NjcsLTE2LjY2NiA1LjU1NSw1LjU1NiAtMTYuNjY3LDE2LjY2NiAxNi42NjcsMTYuNjY3IGggLTM4Ljg4OSB6XCIgICAgICAgICAgaW5rc2NhcGU6Y29ubmVjdG9yLWN1cnZhdHVyZT1cIjBcIiAgICAgc3R5bGU9XCJmaWxsOiMwMTAxMDFcIiAvPjxwYXRoICAgICBkPVwiTSA5Mi4wMzcwMzcsOTAgViA1MS4xMTEgbCAtMTYuNjY3LDE2LjY2NiAtMTYuNjY2LC0xNi42NjYgLTUuNTU2LDUuNTU2IDE2LjY2NiwxNi42NjYgLTE2LjY2NiwxNi42NjcgaCAzOC44ODkgelwiICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9XCIwXCIgICAgIHN0eWxlPVwiZmlsbDojMDEwMTAxXCIgLz48L3N2Zz4nLFxuXHRzbWFsbHNjcmVlbjogJzxzdmcgICB4bWxuczpkYz1cImh0dHA6Ly9wdXJsLm9yZy9kYy9lbGVtZW50cy8xLjEvXCIgICB4bWxuczpjYz1cImh0dHA6Ly9jcmVhdGl2ZWNvbW1vbnMub3JnL25zI1wiICAgeG1sbnM6cmRmPVwiaHR0cDovL3d3dy53My5vcmcvMTk5OS8wMi8yMi1yZGYtc3ludGF4LW5zI1wiICAgeG1sbnM6c3ZnPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiAgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiAgIHhtbG5zOnNvZGlwb2RpPVwiaHR0cDovL3NvZGlwb2RpLnNvdXJjZWZvcmdlLm5ldC9EVEQvc29kaXBvZGktMC5kdGRcIiAgIHhtbG5zOmlua3NjYXBlPVwiaHR0cDovL3d3dy5pbmtzY2FwZS5vcmcvbmFtZXNwYWNlcy9pbmtzY2FwZVwiICAgdmVyc2lvbj1cIjEuMVwiICAgICAgeD1cIjBweFwiICAgeT1cIjBweFwiICAgd2lkdGg9XCIxMDAlXCIgICBoZWlnaHQ9XCIxMDAlXCIgICB2aWV3Qm94PVwiNSAtMTAgNzQuMDc0MDc0IDEwMFwiICAgZW5hYmxlLWJhY2tncm91bmQ9XCJuZXcgMCAwIDEwMCAxMDBcIiAgIHhtbDpzcGFjZT1cInByZXNlcnZlXCIgICBpbmtzY2FwZTp2ZXJzaW9uPVwiMC40OC40IHI5OTM5XCIgICBzb2RpcG9kaTpkb2NuYW1lPVwibm91bl8yMTg2X2NjLnN2Z1wiPjxtZXRhZGF0YSAgICAgPjxyZGY6UkRGPjxjYzpXb3JrICAgICAgICAgcmRmOmFib3V0PVwiXCI+PGRjOmZvcm1hdD5pbWFnZS9zdmcreG1sPC9kYzpmb3JtYXQ+PGRjOnR5cGUgICAgICAgICAgIHJkZjpyZXNvdXJjZT1cImh0dHA6Ly9wdXJsLm9yZy9kYy9kY21pdHlwZS9TdGlsbEltYWdlXCIgLz48L2NjOldvcms+PC9yZGY6UkRGPjwvbWV0YWRhdGE+PGRlZnMgICAgICAvPjxzb2RpcG9kaTpuYW1lZHZpZXcgICAgIHBhZ2Vjb2xvcj1cIiNmZmZmZmZcIiAgICAgYm9yZGVyY29sb3I9XCIjNjY2NjY2XCIgICAgIGJvcmRlcm9wYWNpdHk9XCIxXCIgICAgIG9iamVjdHRvbGVyYW5jZT1cIjEwXCIgICAgIGdyaWR0b2xlcmFuY2U9XCIxMFwiICAgICBndWlkZXRvbGVyYW5jZT1cIjEwXCIgICAgIGlua3NjYXBlOnBhZ2VvcGFjaXR5PVwiMFwiICAgICBpbmtzY2FwZTpwYWdlc2hhZG93PVwiMlwiICAgICBpbmtzY2FwZTp3aW5kb3ctd2lkdGg9XCIxODU1XCIgICAgIGlua3NjYXBlOndpbmRvdy1oZWlnaHQ9XCIxMDU2XCIgICAgICAgICAgc2hvd2dyaWQ9XCJmYWxzZVwiICAgICBmaXQtbWFyZ2luLXRvcD1cIjBcIiAgICAgZml0LW1hcmdpbi1sZWZ0PVwiMFwiICAgICBmaXQtbWFyZ2luLXJpZ2h0PVwiMFwiICAgICBmaXQtbWFyZ2luLWJvdHRvbT1cIjBcIiAgICAgaW5rc2NhcGU6em9vbT1cIjIuMzZcIiAgICAgaW5rc2NhcGU6Y3g9XCI0NC4xMDE1MDlcIiAgICAgaW5rc2NhcGU6Y3k9XCIzMS40ODE0ODFcIiAgICAgaW5rc2NhcGU6d2luZG93LXg9XCI2NVwiICAgICBpbmtzY2FwZTp3aW5kb3cteT1cIjI0XCIgICAgIGlua3NjYXBlOndpbmRvdy1tYXhpbWl6ZWQ9XCIxXCIgICAgIGlua3NjYXBlOmN1cnJlbnQtbGF5ZXI9XCJMYXllcl8xXCIgLz48cGF0aCAgICAgZD1cIm0gMzAuOTI2MDM3LDI4Ljg4OSAwLC0zOC44ODkgLTE2LjY2NywxNi42NjcgLTE2LjY2NywtMTYuNjY3IC01LjU1NSw1LjU1NSAxNi42NjcsMTYuNjY3IC0xNi42NjcsMTYuNjY3IDM4Ljg4OSwwIHpcIiAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPVwiMFwiICAgICBzdHlsZT1cImZpbGw6IzAxMDEwMVwiIC8+PHBhdGggICAgIGQ9XCJtIDUzLjE0ODAzNywyOC44ODkgMCwtMzguODg5IDE2LjY2NywxNi42NjcgMTYuNjY2LC0xNi42NjcgNS41NTYsNS41NTUgLTE2LjY2NiwxNi42NjcgMTYuNjY2LDE2LjY2NyAtMzguODg5LDAgelwiICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9XCIwXCIgICAgIHN0eWxlPVwiZmlsbDojMDEwMTAxXCIgLz48cGF0aCAgICAgZD1cIm0gMzAuOTI2MDM3LDUxLjExMSAwLDM4Ljg4OSAtMTYuNjY3LC0xNi42NjYgLTE2LjY2NywxNi42NjYgLTUuNTU1LC01LjU1NiAxNi42NjcsLTE2LjY2NiAtMTYuNjY3LC0xNi42NjcgMzguODg5LDAgelwiICAgICAgICAgIGlua3NjYXBlOmNvbm5lY3Rvci1jdXJ2YXR1cmU9XCIwXCIgICAgIHN0eWxlPVwiZmlsbDojMDEwMTAxXCIgLz48cGF0aCAgICAgZD1cIm0gNTMuMTQ4MDM3LDUxLjExMSAwLDM4Ljg4OSAxNi42NjcsLTE2LjY2NiAxNi42NjYsMTYuNjY2IDUuNTU2LC01LjU1NiAtMTYuNjY2LC0xNi42NjYgMTYuNjY2LC0xNi42NjcgLTM4Ljg4OSwwIHpcIiAgICAgICAgICBpbmtzY2FwZTpjb25uZWN0b3ItY3VydmF0dXJlPVwiMFwiICAgICBzdHlsZT1cImZpbGw6IzAxMDEwMVwiIC8+PC9zdmc+Jyxcbn07XG4iLCIndXNlIHN0cmljdCc7XG4vL21ha2Ugc3VyZSBhbnkgY29uc29sZSBzdGF0ZW1lbnRzXG53aW5kb3cuY29uc29sZSA9IHdpbmRvdy5jb25zb2xlIHx8IHtcblx0XCJsb2dcIjogZnVuY3Rpb24oKSB7fVxufTtcblxuLyoqXG4gKiBMb2FkIGxpYnJhcmllc1xuICovXG52YXIgJCA9IHJlcXVpcmUoXCJqcXVlcnlcIiksXG5cdENvZGVNaXJyb3IgPSByZXF1aXJlKFwiY29kZW1pcnJvclwiKSxcblx0dXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzLmpzJyksXG5cdHl1dGlscyA9IHJlcXVpcmUoJ3lhc2d1aS11dGlscycpLFxuXHRpbWdzID0gcmVxdWlyZSgnLi9pbWdzLmpzJyk7XG5cbnJlcXVpcmUoXCIuLi9saWIvZGVwYXJhbS5qc1wiKTtcbnJlcXVpcmUoJ2NvZGVtaXJyb3IvYWRkb24vZm9sZC9mb2xkY29kZS5qcycpO1xucmVxdWlyZSgnY29kZW1pcnJvci9hZGRvbi9mb2xkL2ZvbGRndXR0ZXIuanMnKTtcbnJlcXVpcmUoJ2NvZGVtaXJyb3IvYWRkb24vZm9sZC94bWwtZm9sZC5qcycpO1xucmVxdWlyZSgnY29kZW1pcnJvci9hZGRvbi9mb2xkL2JyYWNlLWZvbGQuanMnKTtcbnJlcXVpcmUoJy4vcHJlZml4Rm9sZC5qcycpO1xucmVxdWlyZSgnY29kZW1pcnJvci9hZGRvbi9oaW50L3Nob3ctaGludC5qcycpO1xucmVxdWlyZSgnY29kZW1pcnJvci9hZGRvbi9zZWFyY2gvc2VhcmNoY3Vyc29yLmpzJyk7XG5yZXF1aXJlKCdjb2RlbWlycm9yL2FkZG9uL2VkaXQvbWF0Y2hicmFja2V0cy5qcycpO1xucmVxdWlyZSgnY29kZW1pcnJvci9hZGRvbi9ydW5tb2RlL3J1bm1vZGUuanMnKTtcbnJlcXVpcmUoJ2NvZGVtaXJyb3IvYWRkb24vZGlzcGxheS9mdWxsc2NyZWVuLmpzJyk7XG5yZXF1aXJlKCcuLi9saWIvZ3JhbW1hci90b2tlbml6ZXIuanMnKTtcblxuXG5cbi8qKlxuICogTWFpbiBZQVNRRSBjb25zdHJ1Y3Rvci4gUGFzcyBhIERPTSBlbGVtZW50IGFzIGFyZ3VtZW50IHRvIGFwcGVuZCB0aGUgZWRpdG9yIHRvLCBhbmQgKG9wdGlvbmFsbHkpIHBhc3MgYWxvbmcgY29uZmlnIHNldHRpbmdzIChzZWUgdGhlIFlBU1FFLmRlZmF1bHRzIG9iamVjdCBiZWxvdywgYXMgd2VsbCBhcyB0aGUgcmVndWxhciBDb2RlTWlycm9yIGRvY3VtZW50YXRpb24sIGZvciBtb3JlIGluZm9ybWF0aW9uIG9uIGNvbmZpZ3VyYWJpbGl0eSlcbiAqXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7RE9NLUVsZW1lbnR9IHBhcmVudCBlbGVtZW50IHRvIGFwcGVuZCBlZGl0b3IgdG8uXG4gKiBAcGFyYW0ge29iamVjdH0gc2V0dGluZ3NcbiAqIEBjbGFzcyBZQVNRRVxuICogQHJldHVybiB7ZG9jfSBZQVNRRSBkb2N1bWVudFxuICovXG52YXIgcm9vdCA9IG1vZHVsZS5leHBvcnRzID0gZnVuY3Rpb24ocGFyZW50LCBjb25maWcpIHtcblx0dmFyIHJvb3RFbCA9ICQoXCI8ZGl2PlwiLCB7XG5cdFx0Y2xhc3M6ICd5YXNxZSdcblx0fSkuYXBwZW5kVG8oJChwYXJlbnQpKTtcblx0Y29uZmlnID0gZXh0ZW5kQ29uZmlnKGNvbmZpZyk7XG5cdHZhciB5YXNxZSA9IGV4dGVuZENtSW5zdGFuY2UoQ29kZU1pcnJvcihyb290RWxbMF0sIGNvbmZpZykpO1xuXHRwb3N0UHJvY2Vzc0NtRWxlbWVudCh5YXNxZSk7XG5cdHJldHVybiB5YXNxZTtcbn07XG5cbi8qKlxuICogRXh0ZW5kIGNvbmZpZyBvYmplY3QsIHdoaWNoIHdlIHdpbGwgcGFzcyBvbiB0byB0aGUgQ00gY29uc3RydWN0b3IgbGF0ZXIgb24uXG4gKiBOZWVkIHRoaXMsIHRvIG1ha2Ugc3VyZSBvdXIgb3duICdvbkJsdXInIGV0YyBldmVudHMgZG8gbm90IGdldCBvdmVyd3JpdHRlbiBieVxuICogcGVvcGxlIHdobyBhZGQgdGhlaXIgb3duIG9uYmx1ciBldmVudHMgdG8gdGhlIGNvbmZpZyBBZGRpdGlvbmFsbHksIG5lZWQgdGhpc1xuICogdG8gaW5jbHVkZSB0aGUgQ00gZGVmYXVsdHMgb3Vyc2VsdmVzLiBDb2RlTWlycm9yIGhhcyBhIG1ldGhvZCBmb3IgaW5jbHVkaW5nXG4gKiBkZWZhdWx0cywgYnV0IHdlIGNhbid0IHJlbHkgb24gdGhhdCBvbmU6IGl0IGFzc3VtZXMgZmxhdCBjb25maWcgb2JqZWN0LCB3aGVyZVxuICogd2UgaGF2ZSBuZXN0ZWQgb2JqZWN0cyAoZS5nLiB0aGUgcGVyc2lzdGVuY3kgb3B0aW9uKVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbnZhciBleHRlbmRDb25maWcgPSBmdW5jdGlvbihjb25maWcpIHtcblx0dmFyIGV4dGVuZGVkQ29uZmlnID0gJC5leHRlbmQodHJ1ZSwge30sIHJvb3QuZGVmYXVsdHMsIGNvbmZpZyk7XG5cblx0Ly8gSSBrbm93LCBjb2RlbWlycm9yIGRlYWxzIHdpdGggIGRlZmF1bHQgb3B0aW9ucyBhcyB3ZWxsLlxuXHQvL0hvd2V2ZXIsIGl0IGRvZXMgbm90IGRvIHRoaXMgcmVjdXJzaXZlbHkgKGkuZS4gdGhlIHBlcnNpc3RlbmN5IG9wdGlvbilcblxuXG5cdHJldHVybiBleHRlbmRlZENvbmZpZztcbn07XG4vKipcbiAqIEFkZCBleHRyYSBmdW5jdGlvbnMgdG8gdGhlIENNIGRvY3VtZW50IChpLmUuIHRoZSBjb2RlbWlycm9yIGluc3RhbnRpYXRlZFxuICogb2JqZWN0KVxuICpcbiAqIEBwcml2YXRlXG4gKi9cbnZhciBleHRlbmRDbUluc3RhbmNlID0gZnVuY3Rpb24oeWFzcWUpIHtcblx0Ly9pbnN0YW50aWF0ZSBhdXRvY29tcGxldGVyc1xuXHR5YXNxZS5hdXRvY29tcGxldGVycyA9IHJlcXVpcmUoJy4vYXV0b2NvbXBsZXRlcnMvYXV0b2NvbXBsZXRlckJhc2UuanMnKShyb290LCB5YXNxZSk7XG5cdGlmICh5YXNxZS5vcHRpb25zLmF1dG9jb21wbGV0ZXJzKSB7XG5cdFx0eWFzcWUub3B0aW9ucy5hdXRvY29tcGxldGVycy5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcblx0XHRcdGlmIChyb290LkF1dG9jb21wbGV0ZXJzW25hbWVdKSB5YXNxZS5hdXRvY29tcGxldGVycy5pbml0KG5hbWUsIHJvb3QuQXV0b2NvbXBsZXRlcnNbbmFtZV0pO1xuXHRcdH0pXG5cdH1cblx0eWFzcWUubGFzdFF1ZXJ5RHVyYXRpb24gPSBudWxsO1xuXHR5YXNxZS5nZXRDb21wbGV0ZVRva2VuID0gZnVuY3Rpb24odG9rZW4sIGN1cikge1xuXHRcdHJldHVybiByZXF1aXJlKCcuL3Rva2VuVXRpbHMuanMnKS5nZXRDb21wbGV0ZVRva2VuKHlhc3FlLCB0b2tlbiwgY3VyKTtcblx0fTtcblx0eWFzcWUuZ2V0UHJldmlvdXNOb25Xc1Rva2VuID0gZnVuY3Rpb24obGluZSwgdG9rZW4pIHtcblx0XHRyZXR1cm4gcmVxdWlyZSgnLi90b2tlblV0aWxzLmpzJykuZ2V0UHJldmlvdXNOb25Xc1Rva2VuKHlhc3FlLCBsaW5lLCB0b2tlbik7XG5cdH07XG5cdHlhc3FlLmdldE5leHROb25Xc1Rva2VuID0gZnVuY3Rpb24obGluZU51bWJlciwgY2hhck51bWJlcikge1xuXHRcdHJldHVybiByZXF1aXJlKCcuL3Rva2VuVXRpbHMuanMnKS5nZXROZXh0Tm9uV3NUb2tlbih5YXNxZSwgbGluZU51bWJlciwgY2hhck51bWJlcik7XG5cdH07XG5cdHlhc3FlLmNvbGxhcHNlUHJlZml4ZXMgPSBmdW5jdGlvbihjb2xsYXBzZSkge1xuXHRcdHlhc3FlLmZvbGRDb2RlKHJlcXVpcmUoJy4vcHJlZml4Rm9sZC5qcycpLmZpbmRGaXJzdFByZWZpeExpbmUoeWFzcWUpLCBZQVNRRS5mb2xkLnByZWZpeCwgKGNvbGxhcHNlID8gXCJmb2xkXCIgOiBcInVuZm9sZFwiKSk7XG5cdH07XG5cdHZhciBiYWNrZHJvcCA9IG51bGw7XG5cdHZhciBhbmltYXRlU3BlZWQgPSBudWxsO1xuXHR5YXNxZS5zZXRCYWNrZHJvcCA9IGZ1bmN0aW9uKHNob3cpIHtcblxuXG5cdFx0aWYgKHlhc3FlLm9wdGlvbnMuYmFja2Ryb3AgfHwgeWFzcWUub3B0aW9ucy5iYWNrZHJvcCA9PT0gMCB8fCB5YXNxZS5vcHRpb25zLmJhY2tkcm9wID09PSAnMCcpIHtcblx0XHRcdGlmIChhbmltYXRlU3BlZWQgPT09IG51bGwpIHtcblx0XHRcdFx0YW5pbWF0ZVNwZWVkID0gK3lhc3FlLm9wdGlvbnMuYmFja2Ryb3A7XG5cdFx0XHRcdGlmIChhbmltYXRlU3BlZWQgPT09IDEpIHtcblx0XHRcdFx0XHQvL2FoLCB5YXNxZS5vcHRpb25zLmJhY2tkcm9wIHdhcyAndHJ1ZScuIFNldCB0aGlzIHRvIGRlZmF1bHQgYW5pbWF0ZSBzcGVlZCA0MDBcblx0XHRcdFx0XHRhbmltYXRlU3BlZWQgPSA0MDA7XG5cdFx0XHRcdH1cblx0XHRcdH1cblxuXG5cdFx0XHRpZiAoIWJhY2tkcm9wKSB7XG5cdFx0XHRcdGJhY2tkcm9wID0gJCgnPGRpdj4nLCB7XG5cdFx0XHRcdFx0XHRjbGFzczogJ2JhY2tkcm9wJ1xuXHRcdFx0XHRcdH0pXG5cdFx0XHRcdFx0LmNsaWNrKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0JCh0aGlzKS5oaWRlKCk7XG5cdFx0XHRcdFx0fSlcblx0XHRcdFx0XHQuaW5zZXJ0QWZ0ZXIoJCh5YXNxZS5nZXRXcmFwcGVyRWxlbWVudCgpKSk7XG5cdFx0XHR9XG5cdFx0XHRpZiAoc2hvdykge1xuXHRcdFx0XHRiYWNrZHJvcC5zaG93KGFuaW1hdGVTcGVlZCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRiYWNrZHJvcC5oaWRlKGFuaW1hdGVTcGVlZCk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xuXHQvKipcblx0ICogRXhlY3V0ZSBxdWVyeS4gUGFzcyBhIGNhbGxiYWNrIGZ1bmN0aW9uLCBvciBhIGNvbmZpZ3VyYXRpb24gb2JqZWN0IChzZWVcblx0ICogZGVmYXVsdCBzZXR0aW5ncyBiZWxvdyBmb3IgcG9zc2libGUgdmFsdWVzKSBJLmUuLCB5b3UgY2FuIGNoYW5nZSB0aGVcblx0ICogcXVlcnkgY29uZmlndXJhdGlvbiBieSBlaXRoZXIgY2hhbmdpbmcgdGhlIGRlZmF1bHQgc2V0dGluZ3MsIGNoYW5naW5nIHRoZVxuXHQgKiBzZXR0aW5ncyBvZiB0aGlzIGRvY3VtZW50LCBvciBieSBwYXNzaW5nIHF1ZXJ5IHNldHRpbmdzIHRvIHRoaXMgZnVuY3Rpb25cblx0ICpcblx0ICogQG1ldGhvZCBkb2MucXVlcnlcblx0ICogQHBhcmFtIGZ1bmN0aW9ufG9iamVjdFxuXHQgKi9cblx0eWFzcWUucXVlcnkgPSBmdW5jdGlvbihjYWxsYmFja09yQ29uZmlnKSB7XG5cdFx0cm9vdC5leGVjdXRlUXVlcnkoeWFzcWUsIGNhbGxiYWNrT3JDb25maWcpO1xuXHR9O1xuXG5cdHlhc3FlLmdldFVybEFyZ3VtZW50cyA9IGZ1bmN0aW9uKGNvbmZpZykge1xuXHRcdHJldHVybiByb290LmdldFVybEFyZ3VtZW50cyh5YXNxZSwgY29uZmlnKTtcblx0fTtcblxuXHQvKipcblx0ICogRmV0Y2ggZGVmaW5lZCBwcmVmaXhlcyBmcm9tIHF1ZXJ5IHN0cmluZ1xuXHQgKlxuXHQgKiBAbWV0aG9kIGRvYy5nZXRQcmVmaXhlc0Zyb21RdWVyeVxuXHQgKiBAcmV0dXJuIG9iamVjdFxuXHQgKi9cblx0eWFzcWUuZ2V0UHJlZml4ZXNGcm9tUXVlcnkgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4gcmVxdWlyZSgnLi9wcmVmaXhVdGlscy5qcycpLmdldFByZWZpeGVzRnJvbVF1ZXJ5KHlhc3FlKTtcblx0fTtcblxuXHR5YXNxZS5hZGRQcmVmaXhlcyA9IGZ1bmN0aW9uKHByZWZpeGVzKSB7XG5cdFx0cmV0dXJuIHJlcXVpcmUoJy4vcHJlZml4VXRpbHMuanMnKS5hZGRQcmVmaXhlcyh5YXNxZSwgcHJlZml4ZXMpO1xuXHR9O1xuXHR5YXNxZS5yZW1vdmVQcmVmaXhlcyA9IGZ1bmN0aW9uKHByZWZpeGVzKSB7XG5cdFx0cmV0dXJuIHJlcXVpcmUoJy4vcHJlZml4VXRpbHMuanMnKS5yZW1vdmVQcmVmaXhlcyh5YXNxZSwgcHJlZml4ZXMpO1xuXHR9O1xuXG5cdHlhc3FlLmdldFZhbHVlV2l0aG91dENvbW1lbnRzID0gZnVuY3Rpb24oKSB7XG5cdFx0dmFyIGNsZWFuZWRRdWVyeSA9IFwiXCI7XG5cdFx0cm9vdC5ydW5Nb2RlKHlhc3FlLmdldFZhbHVlKCksIFwic3BhcnFsMTFcIiwgZnVuY3Rpb24oc3RyaW5nVmFsLCBjbGFzc05hbWUpIHtcblx0XHRcdGlmIChjbGFzc05hbWUgIT0gXCJjb21tZW50XCIpIHtcblx0XHRcdFx0Y2xlYW5lZFF1ZXJ5ICs9IHN0cmluZ1ZhbDtcblx0XHRcdH1cblx0XHR9KTtcblx0XHRyZXR1cm4gY2xlYW5lZFF1ZXJ5O1xuXHR9O1xuXHQvKipcblx0ICogRmV0Y2ggdGhlIHF1ZXJ5IHR5cGUgKGUuZy4sIFNFTEVDVHx8REVTQ1JJQkV8fElOU0VSVHx8REVMRVRFfHxBU0t8fENPTlNUUlVDVClcblx0ICpcblx0ICogQG1ldGhvZCBkb2MuZ2V0UXVlcnlUeXBlXG5cdCAqIEByZXR1cm4gc3RyaW5nXG5cdCAqXG5cdCAqL1xuXHR5YXNxZS5nZXRRdWVyeVR5cGUgPSBmdW5jdGlvbigpIHtcblx0XHRyZXR1cm4geWFzcWUucXVlcnlUeXBlO1xuXHR9O1xuXHQvKipcblx0ICogRmV0Y2ggdGhlIHF1ZXJ5IG1vZGU6ICdxdWVyeScgb3IgJ3VwZGF0ZSdcblx0ICpcblx0ICogQG1ldGhvZCBkb2MuZ2V0UXVlcnlNb2RlXG5cdCAqIEByZXR1cm4gc3RyaW5nXG5cdCAqXG5cdCAqL1xuXHR5YXNxZS5nZXRRdWVyeU1vZGUgPSBmdW5jdGlvbigpIHtcblx0XHR2YXIgdHlwZSA9IHlhc3FlLmdldFF1ZXJ5VHlwZSgpO1xuXHRcdGlmICh0eXBlID09IFwiSU5TRVJUXCIgfHwgdHlwZSA9PSBcIkRFTEVURVwiIHx8IHR5cGUgPT0gXCJMT0FEXCIgfHwgdHlwZSA9PSBcIkNMRUFSXCIgfHwgdHlwZSA9PSBcIkNSRUFURVwiIHx8IHR5cGUgPT0gXCJEUk9QXCIgfHwgdHlwZSA9PSBcIkNPUFlcIiB8fCB0eXBlID09IFwiTU9WRVwiIHx8IHR5cGUgPT0gXCJBRERcIikge1xuXHRcdFx0cmV0dXJuIFwidXBkYXRlXCI7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHJldHVybiBcInF1ZXJ5XCI7XG5cdFx0fVxuXG5cdH07XG5cblx0eWFzcWUuc2V0Q2hlY2tTeW50YXhFcnJvcnMgPSBmdW5jdGlvbihpc0VuYWJsZWQpIHtcblx0XHR5YXNxZS5vcHRpb25zLnN5bnRheEVycm9yQ2hlY2sgPSBpc0VuYWJsZWQ7XG5cdFx0Y2hlY2tTeW50YXgoeWFzcWUpO1xuXHR9O1xuXG5cdHlhc3FlLmVuYWJsZUNvbXBsZXRlciA9IGZ1bmN0aW9uKG5hbWUpIHtcblx0XHRhZGRDb21wbGV0ZXJUb1NldHRpbmdzKHlhc3FlLm9wdGlvbnMsIG5hbWUpO1xuXHRcdGlmIChyb290LkF1dG9jb21wbGV0ZXJzW25hbWVdKSB5YXNxZS5hdXRvY29tcGxldGVycy5pbml0KG5hbWUsIHJvb3QuQXV0b2NvbXBsZXRlcnNbbmFtZV0pO1xuXHR9O1xuXHR5YXNxZS5kaXNhYmxlQ29tcGxldGVyID0gZnVuY3Rpb24obmFtZSkge1xuXHRcdHJlbW92ZUNvbXBsZXRlckZyb21TZXR0aW5ncyh5YXNxZS5vcHRpb25zLCBuYW1lKTtcblx0fTtcblx0cmV0dXJuIHlhc3FlO1xufTtcblxudmFyIGFkZENvbXBsZXRlclRvU2V0dGluZ3MgPSBmdW5jdGlvbihzZXR0aW5ncywgbmFtZSkge1xuXHRpZiAoIXNldHRpbmdzLmF1dG9jb21wbGV0ZXJzKSBzZXR0aW5ncy5hdXRvY29tcGxldGVycyA9IFtdO1xuXHRzZXR0aW5ncy5hdXRvY29tcGxldGVycy5wdXNoKG5hbWUpO1xufTtcbnZhciByZW1vdmVDb21wbGV0ZXJGcm9tU2V0dGluZ3MgPSBmdW5jdGlvbihzZXR0aW5ncywgbmFtZSkge1xuXHRpZiAodHlwZW9mIHNldHRpbmdzLmF1dG9jb21wbGV0ZXJzID09IFwib2JqZWN0XCIpIHtcblx0XHR2YXIgaW5kZXggPSAkLmluQXJyYXkobmFtZSwgc2V0dGluZ3MuYXV0b2NvbXBsZXRlcnMpO1xuXHRcdGlmIChpbmRleCA+PSAwKSB7XG5cdFx0XHRzZXR0aW5ncy5hdXRvY29tcGxldGVycy5zcGxpY2UoaW5kZXgsIDEpO1xuXHRcdFx0cmVtb3ZlQ29tcGxldGVyRnJvbVNldHRpbmdzKHNldHRpbmdzLCBuYW1lKTsgLy9qdXN0IGluIGNhc2UuIHN1cHBvc2UgMSBjb21wbGV0ZXIgaXMgbGlzdGVkIHR3aWNlXG5cdFx0fVxuXHR9XG59O1xudmFyIHBvc3RQcm9jZXNzQ21FbGVtZW50ID0gZnVuY3Rpb24oeWFzcWUpIHtcblx0LyoqXG5cdCAqIFNldCBkb2MgdmFsdWVcblx0ICovXG5cdHZhciBzdG9yYWdlSWQgPSB1dGlscy5nZXRQZXJzaXN0ZW5jeUlkKHlhc3FlLCB5YXNxZS5vcHRpb25zLnBlcnNpc3RlbnQpO1xuXHRpZiAoc3RvcmFnZUlkKSB7XG5cdFx0dmFyIHZhbHVlRnJvbVN0b3JhZ2UgPSB5dXRpbHMuc3RvcmFnZS5nZXQoc3RvcmFnZUlkKTtcblx0XHRpZiAodmFsdWVGcm9tU3RvcmFnZSlcblx0XHRcdHlhc3FlLnNldFZhbHVlKHZhbHVlRnJvbVN0b3JhZ2UpO1xuXHR9XG5cblx0cm9vdC5kcmF3QnV0dG9ucyh5YXNxZSk7XG5cblx0LyoqXG5cdCAqIEFkZCBldmVudCBoYW5kbGVyc1xuXHQgKi9cblx0eWFzcWUub24oJ2JsdXInLCBmdW5jdGlvbih5YXNxZSwgZXZlbnRJbmZvKSB7XG5cdFx0cm9vdC5zdG9yZVF1ZXJ5KHlhc3FlKTtcblx0fSk7XG5cdHlhc3FlLm9uKCdjaGFuZ2UnLCBmdW5jdGlvbih5YXNxZSwgZXZlbnRJbmZvKSB7XG5cdFx0Y2hlY2tTeW50YXgoeWFzcWUpO1xuXHRcdHJvb3QudXBkYXRlUXVlcnlCdXR0b24oeWFzcWUpO1xuXHRcdHJvb3QucG9zaXRpb25CdXR0b25zKHlhc3FlKTtcblx0fSk7XG5cdHlhc3FlLm9uKCdjaGFuZ2VzJywgZnVuY3Rpb24oKSB7XG5cdFx0Ly9lLmcuIG9uIHBhc3RlXG5cdFx0Y2hlY2tTeW50YXgoeWFzcWUpO1xuXHRcdHJvb3QudXBkYXRlUXVlcnlCdXR0b24oeWFzcWUpO1xuXHRcdHJvb3QucG9zaXRpb25CdXR0b25zKHlhc3FlKTtcblx0fSk7XG5cblx0eWFzcWUub24oJ2N1cnNvckFjdGl2aXR5JywgZnVuY3Rpb24oeWFzcWUsIGV2ZW50SW5mbykge1xuXHRcdHVwZGF0ZUJ1dHRvbnNUcmFuc3BhcmVuY3koeWFzcWUpO1xuXHR9KTtcblx0eWFzcWUucHJldlF1ZXJ5VmFsaWQgPSBmYWxzZTtcblx0Y2hlY2tTeW50YXgoeWFzcWUpOyAvLyBvbiBmaXJzdCBsb2FkLCBjaGVjayBhcyB3ZWxsIChvdXIgc3RvcmVkIG9yIGRlZmF1bHQgcXVlcnkgbWlnaHQgYmUgaW5jb3JyZWN0KVxuXHRyb290LnBvc2l0aW9uQnV0dG9ucyh5YXNxZSk7XG5cblx0JCh5YXNxZS5nZXRXcmFwcGVyRWxlbWVudCgpKS5vbignbW91c2VlbnRlcicsICcuY20tYXRvbScsIGZ1bmN0aW9uKCkge1xuXHRcdHZhciBtYXRjaFRleHQgPSAkKHRoaXMpLnRleHQoKTtcblx0XHQkKHlhc3FlLmdldFdyYXBwZXJFbGVtZW50KCkpLmZpbmQoJy5jbS1hdG9tJykuZmlsdGVyKGZ1bmN0aW9uKCkge1xuXHRcdFx0cmV0dXJuICQodGhpcykudGV4dCgpID09PSBtYXRjaFRleHQ7XG5cdFx0fSkuYWRkQ2xhc3MoJ21hdGNoaW5nVmFyJyk7XG5cdH0pLm9uKCdtb3VzZWxlYXZlJywgJy5jbS1hdG9tJywgZnVuY3Rpb24oKSB7XG5cdFx0JCh5YXNxZS5nZXRXcmFwcGVyRWxlbWVudCgpKS5maW5kKCcubWF0Y2hpbmdWYXInKS5yZW1vdmVDbGFzcygnbWF0Y2hpbmdWYXInKTtcblx0fSk7XG5cdC8qKlxuXHQgKiBjaGVjayB1cmwgYXJncyBhbmQgbW9kaWZ5IHlhc3FlIHNldHRpbmdzIGlmIG5lZWRlZFxuXHQgKi9cblx0aWYgKHlhc3FlLm9wdGlvbnMuY29uc3VtZVNoYXJlTGluaykge1xuXHRcdHlhc3FlLm9wdGlvbnMuY29uc3VtZVNoYXJlTGluayh5YXNxZSwgZ2V0VXJsUGFyYW1zKCkpO1xuXHRcdC8vYW5kOiBhZGQgYSBoYXNoIGxpc3RlbmVyIVxuXHRcdHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKFwiaGFzaGNoYW5nZVwiLCBmdW5jdGlvbigpIHtcblx0XHRcdHlhc3FlLm9wdGlvbnMuY29uc3VtZVNoYXJlTGluayh5YXNxZSwgZ2V0VXJsUGFyYW1zKCkpO1xuXHRcdH0pO1xuXHR9XG5cdGlmICh5YXNxZS5vcHRpb25zLmNvbGxhcHNlUHJlZml4ZXNPbkxvYWQpIHlhc3FlLmNvbGxhcHNlUHJlZml4ZXModHJ1ZSk7XG59O1xuXG4vKipcbiAqIGdldCB1cmwgcGFyYW1zLiBmaXJzdCB0cnkgZmV0Y2hpbmcgdXNpbmcgaGFzaC4gSWYgaXQgZmFpbHMsIHRyeSB0aGUgcmVndWxhciBxdWVyeSBwYXJhbWV0ZXJzIChmb3IgYmFja3dhcmRzIGNvbXBhdGFiaWxpdHkpXG4gKi9cbnZhciBnZXRVcmxQYXJhbXMgPSBmdW5jdGlvbigpIHtcblx0Ly9maXJzdCB0cnkgaGFzaFxuXHR2YXIgdXJsUGFyYW1zID0gbnVsbDtcblx0aWYgKHdpbmRvdy5sb2NhdGlvbi5oYXNoLmxlbmd0aCA+IDEpIHtcblx0XHQvL2ZpcmVmb3ggZG9lcyBzb21lIGRlY29kaW5nIGlmIHdlJ3JlIHVzaW5nIHdpbmRvdy5sb2NhdGlvbi5oYXNoIChlLmcuIHRoZSArIHNpZ24gaW4gY29udGVudFR5cGUgc2V0dGluZ3MpXG5cdFx0Ly9Eb24ndCB3YW50IHRoaXMuIFNvIHNpbXBseSBnZXQgdGhlIGhhc2ggc3RyaW5nIG91cnNlbHZlc1xuXHRcdHVybFBhcmFtcyA9ICQuZGVwYXJhbShsb2NhdGlvbi5ocmVmLnNwbGl0KFwiI1wiKVsxXSlcblx0fVxuXHRpZiAoKCF1cmxQYXJhbXMgfHwgISgncXVlcnknIGluIHVybFBhcmFtcykpICYmIHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gubGVuZ3RoID4gMSkge1xuXHRcdC8vb2ssIHRoZW4ganVzdCB0cnkgcmVndWxhciB1cmwgcGFyYW1zXG5cdFx0dXJsUGFyYW1zID0gJC5kZXBhcmFtKHdpbmRvdy5sb2NhdGlvbi5zZWFyY2guc3Vic3RyaW5nKDEpKTtcblx0fVxuXHRyZXR1cm4gdXJsUGFyYW1zO1xufTtcblxuXG5cbi8qKlxuICogVXBkYXRlIHRyYW5zcGFyZW5jeSBvZiBidXR0b25zLiBJbmNyZWFzZSB0cmFuc3BhcmVuY3kgd2hlbiBjdXJzb3IgaXMgYmVsb3cgYnV0dG9uc1xuICovXG5cbnZhciB1cGRhdGVCdXR0b25zVHJhbnNwYXJlbmN5ID0gZnVuY3Rpb24oeWFzcWUpIHtcblx0eWFzcWUuY3Vyc29yID0gJChcIi5Db2RlTWlycm9yLWN1cnNvclwiKTtcblx0aWYgKHlhc3FlLmJ1dHRvbnMgJiYgeWFzcWUuYnV0dG9ucy5pcyhcIjp2aXNpYmxlXCIpICYmIHlhc3FlLmN1cnNvci5sZW5ndGggPiAwKSB7XG5cdFx0aWYgKHV0aWxzLmVsZW1lbnRzT3ZlcmxhcCh5YXNxZS5jdXJzb3IsIHlhc3FlLmJ1dHRvbnMpKSB7XG5cdFx0XHR5YXNxZS5idXR0b25zLmZpbmQoXCJzdmdcIikuYXR0cihcIm9wYWNpdHlcIiwgXCIwLjJcIik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHlhc3FlLmJ1dHRvbnMuZmluZChcInN2Z1wiKS5hdHRyKFwib3BhY2l0eVwiLCBcIjEuMFwiKTtcblx0XHR9XG5cdH1cbn07XG5cblxuXG5cblxuXG5cblxuXG52YXIgY2xlYXJFcnJvciA9IG51bGw7XG52YXIgY2hlY2tTeW50YXggPSBmdW5jdGlvbih5YXNxZSwgZGVlcGNoZWNrKSB7XG5cblx0eWFzcWUucXVlcnlWYWxpZCA9IHRydWU7XG5cblx0eWFzcWUuY2xlYXJHdXR0ZXIoXCJndXR0ZXJFcnJvckJhclwiKTtcblxuXHR2YXIgc3RhdGUgPSBudWxsO1xuXHRmb3IgKHZhciBsID0gMDsgbCA8IHlhc3FlLmxpbmVDb3VudCgpOyArK2wpIHtcblx0XHR2YXIgcHJlY2lzZSA9IGZhbHNlO1xuXHRcdGlmICgheWFzcWUucHJldlF1ZXJ5VmFsaWQpIHtcblx0XHRcdC8vIHdlIGRvbid0IHdhbnQgY2FjaGVkIGluZm9ybWF0aW9uIGluIHRoaXMgY2FzZSwgb3RoZXJ3aXNlIHRoZVxuXHRcdFx0Ly8gcHJldmlvdXMgZXJyb3Igc2lnbiBtaWdodCBzdGlsbCBzaG93IHVwLFxuXHRcdFx0Ly8gZXZlbiB0aG91Z2ggdGhlIHN5bnRheCBlcnJvciBtaWdodCBiZSBnb25lIGFscmVhZHlcblx0XHRcdHByZWNpc2UgPSB0cnVlO1xuXHRcdH1cblxuXHRcdHZhciB0b2tlbiA9IHlhc3FlLmdldFRva2VuQXQoe1xuXHRcdFx0bGluZTogbCxcblx0XHRcdGNoOiB5YXNxZS5nZXRMaW5lKGwpLmxlbmd0aFxuXHRcdH0sIHByZWNpc2UpO1xuXHRcdHZhciBzdGF0ZSA9IHRva2VuLnN0YXRlO1xuXHRcdHlhc3FlLnF1ZXJ5VHlwZSA9IHN0YXRlLnF1ZXJ5VHlwZTtcblx0XHRpZiAoc3RhdGUuT0sgPT0gZmFsc2UpIHtcblx0XHRcdGlmICgheWFzcWUub3B0aW9ucy5zeW50YXhFcnJvckNoZWNrKSB7XG5cdFx0XHRcdC8vdGhlIGxpYnJhcnkgd2UgdXNlIGFscmVhZHkgbWFya3MgZXZlcnl0aGluZyBhcyBiZWluZyBhbiBlcnJvci4gT3ZlcndyaXRlIHRoaXMgY2xhc3MgYXR0cmlidXRlLlxuXHRcdFx0XHQkKHlhc3FlLmdldFdyYXBwZXJFbGVtZW50KS5maW5kKFwiLnNwLWVycm9yXCIpLmNzcyhcImNvbG9yXCIsIFwiYmxhY2tcIik7XG5cdFx0XHRcdC8vd2UgZG9uJ3Qgd2FudCB0byBndXR0ZXIgZXJyb3IsIHNvIHJldHVyblxuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cblx0XHRcdHZhciB3YXJuaW5nRWwgPSB5dXRpbHMuc3ZnLmdldEVsZW1lbnQoaW1ncy53YXJuaW5nKTtcblx0XHRcdGlmIChzdGF0ZS5wb3NzaWJsZUN1cnJlbnQgJiYgc3RhdGUucG9zc2libGVDdXJyZW50Lmxlbmd0aCA+IDApIHtcblx0XHRcdFx0Ly9cdFx0XHRcdHdhcm5pbmdFbC5zdHlsZS56SW5kZXggPSBcIjk5OTk5OTk5XCI7XG5cdFx0XHRcdHJlcXVpcmUoJy4vdG9vbHRpcCcpKHlhc3FlLCB3YXJuaW5nRWwsIGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdHZhciBleHBlY3RlZEVuY29kZWQgPSBbXTtcblx0XHRcdFx0XHRzdGF0ZS5wb3NzaWJsZUN1cnJlbnQuZm9yRWFjaChmdW5jdGlvbihleHBlY3RlZCkge1xuXHRcdFx0XHRcdFx0ZXhwZWN0ZWRFbmNvZGVkLnB1c2goXCI8c3Ryb25nIHN0eWxlPSd0ZXh0LWRlY29yYXRpb246dW5kZXJsaW5lJz5cIiArICQoXCI8ZGl2Lz5cIikudGV4dChleHBlY3RlZCkuaHRtbCgpICsgXCI8L3N0cm9uZz5cIik7XG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdFx0cmV0dXJuIFwiVGhpcyBsaW5lIGlzIGludmFsaWQuIEV4cGVjdGVkOiBcIiArIGV4cGVjdGVkRW5jb2RlZC5qb2luKFwiLCBcIik7XG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdFx0d2FybmluZ0VsLnN0eWxlLm1hcmdpblRvcCA9IFwiMnB4XCI7XG5cdFx0XHR3YXJuaW5nRWwuc3R5bGUubWFyZ2luTGVmdCA9IFwiMnB4XCI7XG5cdFx0XHR3YXJuaW5nRWwuY2xhc3NOYW1lID0gJ3BhcnNlRXJyb3JJY29uJztcblx0XHRcdHlhc3FlLnNldEd1dHRlck1hcmtlcihsLCBcImd1dHRlckVycm9yQmFyXCIsIHdhcm5pbmdFbCk7XG5cblx0XHRcdHlhc3FlLnF1ZXJ5VmFsaWQgPSBmYWxzZTtcblx0XHRcdGJyZWFrO1xuXHRcdH1cblx0fVxuXHR5YXNxZS5wcmV2UXVlcnlWYWxpZCA9IHlhc3FlLnF1ZXJ5VmFsaWQ7XG5cdGlmIChkZWVwY2hlY2spIHtcblx0XHRpZiAoc3RhdGUgIT0gbnVsbCAmJiBzdGF0ZS5zdGFjayAhPSB1bmRlZmluZWQpIHtcblx0XHRcdHZhciBzdGFjayA9IHN0YXRlLnN0YWNrLFxuXHRcdFx0XHRsZW4gPSBzdGF0ZS5zdGFjay5sZW5ndGg7XG5cdFx0XHQvLyBCZWNhdXNlIGluY3JlbWVudGFsIHBhcnNlciBkb2Vzbid0IHJlY2VpdmUgZW5kLW9mLWlucHV0XG5cdFx0XHQvLyBpdCBjYW4ndCBjbGVhciBzdGFjaywgc28gd2UgaGF2ZSB0byBjaGVjayB0aGF0IHdoYXRldmVyXG5cdFx0XHQvLyBpcyBsZWZ0IG9uIHRoZSBzdGFjayBpcyBuaWxsYWJsZVxuXHRcdFx0aWYgKGxlbiA+IDEpXG5cdFx0XHRcdHlhc3FlLnF1ZXJ5VmFsaWQgPSBmYWxzZTtcblx0XHRcdGVsc2UgaWYgKGxlbiA9PSAxKSB7XG5cdFx0XHRcdGlmIChzdGFja1swXSAhPSBcInNvbHV0aW9uTW9kaWZpZXJcIiAmJiBzdGFja1swXSAhPSBcIj9saW1pdE9mZnNldENsYXVzZXNcIiAmJiBzdGFja1swXSAhPSBcIj9vZmZzZXRDbGF1c2VcIilcblx0XHRcdFx0XHR5YXNxZS5xdWVyeVZhbGlkID0gZmFsc2U7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG59O1xuLyoqXG4gKiBTdGF0aWMgVXRpbHNcbiAqL1xuLy8gZmlyc3QgdGFrZSBhbGwgQ29kZU1pcnJvciByZWZlcmVuY2VzIGFuZCBzdG9yZSB0aGVtIGluIHRoZSBZQVNRRSBvYmplY3RcbiQuZXh0ZW5kKHJvb3QsIENvZGVNaXJyb3IpO1xuXG5cbi8vYWRkIHJlZ2lzdHJhciBmb3IgYXV0b2NvbXBsZXRlcnNcbnJvb3QuQXV0b2NvbXBsZXRlcnMgPSB7fTtcbnJvb3QucmVnaXN0ZXJBdXRvY29tcGxldGVyID0gZnVuY3Rpb24obmFtZSwgY29uc3RydWN0b3IpIHtcblx0cm9vdC5BdXRvY29tcGxldGVyc1tuYW1lXSA9IGNvbnN0cnVjdG9yO1xuXHRhZGRDb21wbGV0ZXJUb1NldHRpbmdzKHJvb3QuZGVmYXVsdHMsIG5hbWUpO1xufVxuXG5yb290LmF1dG9Db21wbGV0ZSA9IGZ1bmN0aW9uKHlhc3FlKSB7XG5cdC8vdGhpcyBmdW5jdGlvbiBnZXRzIGNhbGxlZCB3aGVuIHByZXNzaW5nIHRoZSBrZXlib2FyZCBzaG9ydGN1dC4gSS5lLiwgYXV0b1Nob3cgPSBmYWxzZVxuXHR5YXNxZS5hdXRvY29tcGxldGVycy5hdXRvQ29tcGxldGUoZmFsc2UpO1xufTtcbi8vaW5jbHVkZSB0aGUgYXV0b2NvbXBsZXRlcnMgd2UgcHJvdmlkZSBvdXQtb2YtdGhlLWJveFxucm9vdC5yZWdpc3RlckF1dG9jb21wbGV0ZXIoXCJwcmVmaXhlc1wiLCByZXF1aXJlKFwiLi9hdXRvY29tcGxldGVycy9wcmVmaXhlcy5qc1wiKSk7XG5yb290LnJlZ2lzdGVyQXV0b2NvbXBsZXRlcihcInByb3BlcnRpZXNcIiwgcmVxdWlyZShcIi4vYXV0b2NvbXBsZXRlcnMvcHJvcGVydGllcy5qc1wiKSk7XG5yb290LnJlZ2lzdGVyQXV0b2NvbXBsZXRlcihcImNsYXNzZXNcIiwgcmVxdWlyZShcIi4vYXV0b2NvbXBsZXRlcnMvY2xhc3Nlcy5qc1wiKSk7XG5yb290LnJlZ2lzdGVyQXV0b2NvbXBsZXRlcihcInZhcmlhYmxlc1wiLCByZXF1aXJlKFwiLi9hdXRvY29tcGxldGVycy92YXJpYWJsZXMuanNcIikpO1xuXG5cbnJvb3QucG9zaXRpb25CdXR0b25zID0gZnVuY3Rpb24oeWFzcWUpIHtcblx0dmFyIHNjcm9sbEJhciA9ICQoeWFzcWUuZ2V0V3JhcHBlckVsZW1lbnQoKSkuZmluZChcIi5Db2RlTWlycm9yLXZzY3JvbGxiYXJcIik7XG5cdHZhciBvZmZzZXQgPSAwO1xuXHRpZiAoc2Nyb2xsQmFyLmlzKFwiOnZpc2libGVcIikpIHtcblx0XHRvZmZzZXQgPSBzY3JvbGxCYXIub3V0ZXJXaWR0aCgpO1xuXHR9XG5cdGlmICh5YXNxZS5idXR0b25zLmlzKFwiOnZpc2libGVcIikpIHlhc3FlLmJ1dHRvbnMuY3NzKFwicmlnaHRcIiwgb2Zmc2V0ICsgNCk7XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIHNoYXJlIGxpbmtcbiAqXG4gKiBAbWV0aG9kIFlBU1FFLmNyZWF0ZVNoYXJlTGlua1xuICogQHBhcmFtIHtkb2N9IFlBU1FFIGRvY3VtZW50XG4gKiBAZGVmYXVsdCB7cXVlcnk6IGRvYy5nZXRWYWx1ZSgpfVxuICogQHJldHVybiBvYmplY3RcbiAqL1xucm9vdC5jcmVhdGVTaGFyZUxpbmsgPSBmdW5jdGlvbih5YXNxZSkge1xuXHQvL2V4dGVuZCBleGlzdGluZyBsaW5rLCBzbyBmaXJzdCBmZXRjaCBjdXJyZW50IGFyZ3VtZW50c1xuXHR2YXIgdXJsUGFyYW1zID0ge307XG5cdGlmICh3aW5kb3cubG9jYXRpb24uaGFzaC5sZW5ndGggPiAxKSB1cmxQYXJhbXMgPSAkLmRlcGFyYW0od2luZG93LmxvY2F0aW9uLmhhc2guc3Vic3RyaW5nKDEpKTtcblx0dXJsUGFyYW1zWydxdWVyeSddID0geWFzcWUuZ2V0VmFsdWUoKTtcblx0cmV0dXJuIHVybFBhcmFtcztcbn07XG5cbi8qKlxuICogQ29uc3VtZSB0aGUgc2hhcmUgbGluaywgYnkgcGFyc2luZyB0aGUgZG9jdW1lbnQgVVJMIGZvciBwb3NzaWJsZSB5YXNxZSBhcmd1bWVudHMsIGFuZCBzZXR0aW5nIHRoZSBhcHByb3ByaWF0ZSB2YWx1ZXMgaW4gdGhlIFlBU1FFIGRvY1xuICpcbiAqIEBtZXRob2QgWUFTUUUuY29uc3VtZVNoYXJlTGlua1xuICogQHBhcmFtIHtkb2N9IFlBU1FFIGRvY3VtZW50XG4gKi9cbnJvb3QuY29uc3VtZVNoYXJlTGluayA9IGZ1bmN0aW9uKHlhc3FlLCB1cmxQYXJhbXMpIHtcblx0aWYgKHVybFBhcmFtcyAmJiB1cmxQYXJhbXMucXVlcnkpIHtcblx0XHR5YXNxZS5zZXRWYWx1ZSh1cmxQYXJhbXMucXVlcnkpO1xuXHR9XG59O1xucm9vdC5kcmF3QnV0dG9ucyA9IGZ1bmN0aW9uKHlhc3FlKSB7XG5cdHlhc3FlLmJ1dHRvbnMgPSAkKFwiPGRpdiBjbGFzcz0neWFzcWVfYnV0dG9ucyc+PC9kaXY+XCIpLmFwcGVuZFRvKCQoeWFzcWUuZ2V0V3JhcHBlckVsZW1lbnQoKSkpO1xuXG5cdC8qKlxuXHQgKiBkcmF3IHNoYXJlIGxpbmsgYnV0dG9uXG5cdCAqL1xuXHRpZiAoeWFzcWUub3B0aW9ucy5jcmVhdGVTaGFyZUxpbmspIHtcblxuXHRcdHZhciBzdmdTaGFyZSA9ICQoeXV0aWxzLnN2Zy5nZXRFbGVtZW50KGltZ3Muc2hhcmUpKTtcblx0XHRzdmdTaGFyZS5jbGljayhmdW5jdGlvbihldmVudCkge1xuXHRcdFx0XHRldmVudC5zdG9wUHJvcGFnYXRpb24oKTtcblx0XHRcdFx0dmFyIHBvcHVwID0gJChcIjxkaXYgY2xhc3M9J3lhc3FlX3NoYXJlUG9wdXAnPjwvZGl2PlwiKS5hcHBlbmRUbyh5YXNxZS5idXR0b25zKTtcblx0XHRcdFx0JCgnaHRtbCcpLmNsaWNrKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdGlmIChwb3B1cCkgcG9wdXAucmVtb3ZlKCk7XG5cdFx0XHRcdH0pO1xuXG5cdFx0XHRcdHBvcHVwLmNsaWNrKGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0XHRcdFx0ZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG5cdFx0XHRcdH0pO1xuXHRcdFx0XHR2YXIgJGlucHV0ID0gJChcIjxpbnB1dD5cIikudmFsKGxvY2F0aW9uLnByb3RvY29sICsgJy8vJyArIGxvY2F0aW9uLmhvc3QgKyBsb2NhdGlvbi5wYXRobmFtZSArIGxvY2F0aW9uLnNlYXJjaCArIFwiI1wiICsgJC5wYXJhbSh5YXNxZS5vcHRpb25zLmNyZWF0ZVNoYXJlTGluayh5YXNxZSkpKTtcblxuXHRcdFx0XHQkaW5wdXQuZm9jdXMoZnVuY3Rpb24oKSB7XG5cdFx0XHRcdFx0dmFyICR0aGlzID0gJCh0aGlzKTtcblx0XHRcdFx0XHQkdGhpcy5zZWxlY3QoKTtcblxuXHRcdFx0XHRcdC8vIFdvcmsgYXJvdW5kIENocm9tZSdzIGxpdHRsZSBwcm9ibGVtXG5cdFx0XHRcdFx0JHRoaXMubW91c2V1cChmdW5jdGlvbigpIHtcblx0XHRcdFx0XHRcdC8vIFByZXZlbnQgZnVydGhlciBtb3VzZXVwIGludGVydmVudGlvblxuXHRcdFx0XHRcdFx0JHRoaXMudW5iaW5kKFwibW91c2V1cFwiKTtcblx0XHRcdFx0XHRcdHJldHVybiBmYWxzZTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSk7XG5cblx0XHRcdFx0cG9wdXAuZW1wdHkoKS5hcHBlbmQoJCgnPGRpdj4nLCB7Y2xhc3M6J2lucHV0V3JhcHBlcid9KS5hcHBlbmQoJGlucHV0KSk7XG5cdFx0XHRcdGlmICh5YXNxZS5vcHRpb25zLmNyZWF0ZVNob3J0TGluaykge1xuXHRcdFx0XHRcdHBvcHVwLmFkZENsYXNzKCdlbmFibGVTaG9ydCcpO1xuXHRcdFx0XHRcdCQoJzxidXR0b24+U2hvcnRlbjwvYnV0dG9uPicpXG5cdFx0XHRcdFx0XHQuYWRkQ2xhc3MoJ3lhc3FlX2J0biB5YXNxZV9idG4tc20geWFzcWVfYnRuLXByaW1hcnknKVxuXHRcdFx0XHRcdFx0LmNsaWNrKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRcdFx0XHQkKHRoaXMpLmF0dHIoJ2Rpc2FibGVkJywgJ2Rpc2FibGVkJyk7XG5cdFx0XHRcdFx0XHRcdHlhc3FlLm9wdGlvbnMuY3JlYXRlU2hvcnRMaW5rKCRpbnB1dC52YWwoKSwgZnVuY3Rpb24oZXJyU3RyaW5nLCBzaG9ydExpbmspIHtcblx0XHRcdFx0XHRcdFx0XHRpZiAoZXJyU3RyaW5nKSB7XG5cdFx0XHRcdFx0XHRcdFx0XHQkaW5wdXQucmVtb3ZlKCk7XG5cdFx0XHRcdFx0XHRcdFx0XHRwb3B1cC5maW5kKCcuaW5wdXRXcmFwcGVyJykuYXBwZW5kKCQoJzxzcGFuPicsIHtjbGFzczpcInNob3J0bGlua0VyclwifSkudGV4dChlcnJTdHJpbmcpKTtcblx0XHRcdFx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0XHRcdFx0JGlucHV0LnZhbChzaG9ydExpbmspLmZvY3VzKCk7XG5cdFx0XHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdFx0XHR9KVxuXHRcdFx0XHRcdFx0fSkuYXBwZW5kVG8ocG9wdXApO1xuXHRcdFx0XHR9XG5cdFx0XHRcdHZhciBwb3NpdGlvbnMgPSBzdmdTaGFyZS5wb3NpdGlvbigpO1xuXHRcdFx0XHRwb3B1cC5jc3MoXCJ0b3BcIiwgKHBvc2l0aW9ucy50b3AgKyBzdmdTaGFyZS5vdXRlckhlaWdodCgpICsgcGFyc2VJbnQocG9wdXAuY3NzKCdwYWRkaW5nLXRvcCcpKSApICsgXCJweFwiKS5jc3MoXCJsZWZ0XCIsICgocG9zaXRpb25zLmxlZnQgKyBzdmdTaGFyZS5vdXRlcldpZHRoKCkpIC0gcG9wdXAub3V0ZXJXaWR0aCgpKSArIFwicHhcIik7XG5cdFx0XHRcdCRpbnB1dC5mb2N1cygpO1xuXHRcdFx0fSlcblx0XHRcdC5hZGRDbGFzcyhcInlhc3FlX3NoYXJlXCIpXG5cdFx0XHQuYXR0cihcInRpdGxlXCIsIFwiU2hhcmUgeW91ciBxdWVyeVwiKVxuXHRcdFx0LmFwcGVuZFRvKHlhc3FlLmJ1dHRvbnMpO1xuXG5cdH1cblxuXG5cdC8qKlxuXHQgKiBkcmF3IGZ1bGxzY3JlZW4gYnV0dG9uXG5cdCAqL1xuXG5cdHZhciB0b2dnbGVGdWxsc2NyZWVuID0gJCgnPGRpdj4nLCB7XG5cdFx0XHRjbGFzczogJ2Z1bGxzY3JlZW5Ub2dnbGVCdG5zJ1xuXHRcdH0pXG5cdFx0LmFwcGVuZCgkKHl1dGlscy5zdmcuZ2V0RWxlbWVudChpbWdzLmZ1bGxzY3JlZW4pKVxuXHRcdFx0LmFkZENsYXNzKFwieWFzcWVfZnVsbHNjcmVlbkJ0blwiKVxuXHRcdFx0LmF0dHIoXCJ0aXRsZVwiLCBcIlNldCBlZGl0b3IgZnVsbCBzY3JlZW5cIilcblx0XHRcdC5jbGljayhmdW5jdGlvbigpIHtcblx0XHRcdFx0eWFzcWUuc2V0T3B0aW9uKFwiZnVsbFNjcmVlblwiLCB0cnVlKTtcblx0XHRcdH0pKVxuXHRcdC5hcHBlbmQoJCh5dXRpbHMuc3ZnLmdldEVsZW1lbnQoaW1ncy5zbWFsbHNjcmVlbikpXG5cdFx0XHQuYWRkQ2xhc3MoXCJ5YXNxZV9zbWFsbHNjcmVlbkJ0blwiKVxuXHRcdFx0LmF0dHIoXCJ0aXRsZVwiLCBcIlNldCBlZGl0b3IgdG8gbm9ybWFsZSBzaXplXCIpXG5cdFx0XHQuY2xpY2soZnVuY3Rpb24oKSB7XG5cdFx0XHRcdHlhc3FlLnNldE9wdGlvbihcImZ1bGxTY3JlZW5cIiwgZmFsc2UpO1xuXHRcdFx0fSkpXG5cdHlhc3FlLmJ1dHRvbnMuYXBwZW5kKHRvZ2dsZUZ1bGxzY3JlZW4pO1xuXG5cblx0aWYgKHlhc3FlLm9wdGlvbnMuc3BhcnFsLnNob3dRdWVyeUJ1dHRvbikge1xuXHRcdCQoXCI8ZGl2PlwiLCB7XG5cdFx0XHRcdGNsYXNzOiAneWFzcWVfcXVlcnlCdXR0b24nXG5cdFx0XHR9KVxuXHRcdFx0LmNsaWNrKGZ1bmN0aW9uKCkge1xuXHRcdFx0XHRpZiAoJCh0aGlzKS5oYXNDbGFzcyhcInF1ZXJ5X2J1c3lcIikpIHtcblx0XHRcdFx0XHRpZiAoeWFzcWUueGhyKSB5YXNxZS54aHIuYWJvcnQoKTtcblx0XHRcdFx0XHRyb290LnVwZGF0ZVF1ZXJ5QnV0dG9uKHlhc3FlKTtcblx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHR5YXNxZS5xdWVyeSgpO1xuXHRcdFx0XHR9XG5cdFx0XHR9KVxuXHRcdFx0LmFwcGVuZFRvKHlhc3FlLmJ1dHRvbnMpO1xuXHRcdHJvb3QudXBkYXRlUXVlcnlCdXR0b24oeWFzcWUpO1xuXHR9XG5cbn07XG5cblxudmFyIHF1ZXJ5QnV0dG9uSWRzID0ge1xuXHRcImJ1c3lcIjogXCJsb2FkZXJcIixcblx0XCJ2YWxpZFwiOiBcInF1ZXJ5XCIsXG5cdFwiZXJyb3JcIjogXCJxdWVyeUludmFsaWRcIlxufTtcblxuLyoqXG4gKiBVcGRhdGUgdGhlIHF1ZXJ5IGJ1dHRvbiBkZXBlbmRpbmcgb24gY3VycmVudCBxdWVyeSBzdGF0dXMuIElmIG5vIHF1ZXJ5IHN0YXR1cyBpcyBwYXNzZWQgdmlhIHRoZSBwYXJhbWV0ZXIsIGl0IGF1dG8tZGV0ZWN0cyB0aGUgY3VycmVudCBxdWVyeSBzdGF0dXNcbiAqXG4gKiBAcGFyYW0ge2RvY30gWUFTUUUgZG9jdW1lbnRcbiAqIEBwYXJhbSBzdGF0dXMge3N0cmluZ3xudWxsLCBcImJ1c3lcInxcInZhbGlkXCJ8XCJlcnJvclwifVxuICovXG5yb290LnVwZGF0ZVF1ZXJ5QnV0dG9uID0gZnVuY3Rpb24oeWFzcWUsIHN0YXR1cykge1xuXHR2YXIgcXVlcnlCdXR0b24gPSAkKHlhc3FlLmdldFdyYXBwZXJFbGVtZW50KCkpLmZpbmQoXCIueWFzcWVfcXVlcnlCdXR0b25cIik7XG5cdGlmIChxdWVyeUJ1dHRvbi5sZW5ndGggPT0gMCkgcmV0dXJuOyAvL25vIHF1ZXJ5IGJ1dHRvbiBkcmF3blxuXG5cdC8vZGV0ZWN0IHN0YXR1c1xuXHRpZiAoIXN0YXR1cykge1xuXHRcdHN0YXR1cyA9IFwidmFsaWRcIjtcblx0XHRpZiAoeWFzcWUucXVlcnlWYWxpZCA9PT0gZmFsc2UpIHN0YXR1cyA9IFwiZXJyb3JcIjtcblx0fVxuXG5cdGlmIChzdGF0dXMgIT0geWFzcWUucXVlcnlTdGF0dXMpIHtcblx0XHRxdWVyeUJ1dHRvblxuXHRcdFx0LmVtcHR5KClcblx0XHRcdC5yZW1vdmVDbGFzcyhmdW5jdGlvbihpbmRleCwgY2xhc3NOYW1lcykge1xuXHRcdFx0XHRyZXR1cm4gY2xhc3NOYW1lcy5zcGxpdChcIiBcIikuZmlsdGVyKGZ1bmN0aW9uKGMpIHtcblx0XHRcdFx0XHQvL3JlbW92ZSBjbGFzc25hbWUgZnJvbSBwcmV2aW91cyBzdGF0dXNcblx0XHRcdFx0XHRyZXR1cm4gYy5pbmRleE9mKFwicXVlcnlfXCIpID09IDA7XG5cdFx0XHRcdH0pLmpvaW4oXCIgXCIpO1xuXHRcdFx0fSk7XG5cblx0XHRpZiAoc3RhdHVzID09IFwiYnVzeVwiKSB7XG5cdFx0XHRxdWVyeUJ1dHRvbi5hcHBlbmQoJCgnPGRpdj4nLCB7XG5cdFx0XHRcdGNsYXNzOiAnbG9hZGVyJyxcblx0XHRcdH0pKTtcblx0XHRcdHlhc3FlLnF1ZXJ5U3RhdHVzID0gc3RhdHVzO1xuXHRcdH0gZWxzZSBpZiAoc3RhdHVzID09IFwidmFsaWRcIiB8fCBzdGF0dXMgPT0gXCJlcnJvclwiKSB7XG5cdFx0XHRxdWVyeUJ1dHRvbi5hZGRDbGFzcyhcInF1ZXJ5X1wiICsgc3RhdHVzKTtcblx0XHRcdHl1dGlscy5zdmcuZHJhdyhxdWVyeUJ1dHRvbiwgaW1nc1txdWVyeUJ1dHRvbklkc1tzdGF0dXNdXSk7XG5cdFx0XHR5YXNxZS5xdWVyeVN0YXR1cyA9IHN0YXR1cztcblx0XHR9XG5cdH1cbn07XG4vKipcbiAqIEluaXRpYWxpemUgWUFTUUUgZnJvbSBhbiBleGlzdGluZyB0ZXh0IGFyZWEgKHNlZSBodHRwOi8vY29kZW1pcnJvci5uZXQvZG9jL21hbnVhbC5odG1sI2Zyb21UZXh0QXJlYSBmb3IgbW9yZSBpbmZvKVxuICpcbiAqIEBtZXRob2QgWUFTUUUuZnJvbVRleHRBcmVhXG4gKiBAcGFyYW0gdGV4dEFyZWEge0RPTSBlbGVtZW50fVxuICogQHBhcmFtIGNvbmZpZyB7b2JqZWN0fVxuICogQHJldHVybnMge2RvY30gWUFTUUUgZG9jdW1lbnRcbiAqL1xucm9vdC5mcm9tVGV4dEFyZWEgPSBmdW5jdGlvbih0ZXh0QXJlYUVsLCBjb25maWcpIHtcblx0Y29uZmlnID0gZXh0ZW5kQ29uZmlnKGNvbmZpZyk7XG5cdC8vYWRkIHlhc3FlIGRpdiBhcyBwYXJlbnQgKG5lZWRlZCBmb3Igc3R5bGVzIHRvIGJlIG1hbmFnZWFibGUgYW5kIHNjb3BlZCkuXG5cdC8vSW4gdGhpcyBjYXNlLCBJIC1hbHNvLSBwdXQgaXQgYXMgcGFyZW50IGVsIG9mIHRoZSB0ZXh0IGFyZWEuIFRoaXMgaXMgd3JhcHBlZCBpbiBhIGRpdiBub3dcblx0dmFyIHJvb3RFbCA9ICQoXCI8ZGl2PlwiLCB7XG5cdFx0Y2xhc3M6ICd5YXNxZSdcblx0fSkuaW5zZXJ0QmVmb3JlKCQodGV4dEFyZWFFbCkpLmFwcGVuZCgkKHRleHRBcmVhRWwpKTtcblx0dmFyIHlhc3FlID0gZXh0ZW5kQ21JbnN0YW5jZShDb2RlTWlycm9yLmZyb21UZXh0QXJlYSh0ZXh0QXJlYUVsLCBjb25maWcpKTtcblx0cG9zdFByb2Nlc3NDbUVsZW1lbnQoeWFzcWUpO1xuXHRyZXR1cm4geWFzcWU7XG59O1xuXG5cbnJvb3Quc3RvcmVRdWVyeSA9IGZ1bmN0aW9uKHlhc3FlKSB7XG5cdHZhciBzdG9yYWdlSWQgPSB1dGlscy5nZXRQZXJzaXN0ZW5jeUlkKHlhc3FlLCB5YXNxZS5vcHRpb25zLnBlcnNpc3RlbnQpO1xuXHRpZiAoc3RvcmFnZUlkKSB7XG5cdFx0eXV0aWxzLnN0b3JhZ2Uuc2V0KHN0b3JhZ2VJZCwgeWFzcWUuZ2V0VmFsdWUoKSwgXCJtb250aFwiKTtcblx0fVxufTtcbnJvb3QuY29tbWVudExpbmVzID0gZnVuY3Rpb24oeWFzcWUpIHtcblx0dmFyIHN0YXJ0TGluZSA9IHlhc3FlLmdldEN1cnNvcih0cnVlKS5saW5lO1xuXHR2YXIgZW5kTGluZSA9IHlhc3FlLmdldEN1cnNvcihmYWxzZSkubGluZTtcblx0dmFyIG1pbiA9IE1hdGgubWluKHN0YXJ0TGluZSwgZW5kTGluZSk7XG5cdHZhciBtYXggPSBNYXRoLm1heChzdGFydExpbmUsIGVuZExpbmUpO1xuXG5cdC8vIGlmIGFsbCBsaW5lcyBzdGFydCB3aXRoICMsIHJlbW92ZSB0aGlzIGNoYXIuIE90aGVyd2lzZSBhZGQgdGhpcyBjaGFyXG5cdHZhciBsaW5lc0FyZUNvbW1lbnRlZCA9IHRydWU7XG5cdGZvciAodmFyIGkgPSBtaW47IGkgPD0gbWF4OyBpKyspIHtcblx0XHR2YXIgbGluZSA9IHlhc3FlLmdldExpbmUoaSk7XG5cdFx0aWYgKGxpbmUubGVuZ3RoID09IDAgfHwgbGluZS5zdWJzdHJpbmcoMCwgMSkgIT0gXCIjXCIpIHtcblx0XHRcdGxpbmVzQXJlQ29tbWVudGVkID0gZmFsc2U7XG5cdFx0XHRicmVhaztcblx0XHR9XG5cdH1cblx0Zm9yICh2YXIgaSA9IG1pbjsgaSA8PSBtYXg7IGkrKykge1xuXHRcdGlmIChsaW5lc0FyZUNvbW1lbnRlZCkge1xuXHRcdFx0Ly8gbGluZXMgYXJlIGNvbW1lbnRlZCwgc28gcmVtb3ZlIGNvbW1lbnRzXG5cdFx0XHR5YXNxZS5yZXBsYWNlUmFuZ2UoXCJcIiwge1xuXHRcdFx0XHRsaW5lOiBpLFxuXHRcdFx0XHRjaDogMFxuXHRcdFx0fSwge1xuXHRcdFx0XHRsaW5lOiBpLFxuXHRcdFx0XHRjaDogMVxuXHRcdFx0fSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIE5vdCBhbGwgbGluZXMgYXJlIGNvbW1lbnRlZCwgc28gYWRkIGNvbW1lbnRzXG5cdFx0XHR5YXNxZS5yZXBsYWNlUmFuZ2UoXCIjXCIsIHtcblx0XHRcdFx0bGluZTogaSxcblx0XHRcdFx0Y2g6IDBcblx0XHRcdH0pO1xuXHRcdH1cblxuXHR9XG59O1xuXG5yb290LmNvcHlMaW5lVXAgPSBmdW5jdGlvbih5YXNxZSkge1xuXHR2YXIgY3Vyc29yID0geWFzcWUuZ2V0Q3Vyc29yKCk7XG5cdHZhciBsaW5lQ291bnQgPSB5YXNxZS5saW5lQ291bnQoKTtcblx0Ly8gRmlyc3QgY3JlYXRlIG5ldyBlbXB0eSBsaW5lIGF0IGVuZCBvZiB0ZXh0XG5cdHlhc3FlLnJlcGxhY2VSYW5nZShcIlxcblwiLCB7XG5cdFx0bGluZTogbGluZUNvdW50IC0gMSxcblx0XHRjaDogeWFzcWUuZ2V0TGluZShsaW5lQ291bnQgLSAxKS5sZW5ndGhcblx0fSk7XG5cdC8vIENvcHkgYWxsIGxpbmVzIHRvIHRoZWlyIG5leHQgbGluZVxuXHRmb3IgKHZhciBpID0gbGluZUNvdW50OyBpID4gY3Vyc29yLmxpbmU7IGktLSkge1xuXHRcdHZhciBsaW5lID0geWFzcWUuZ2V0TGluZShpIC0gMSk7XG5cdFx0eWFzcWUucmVwbGFjZVJhbmdlKGxpbmUsIHtcblx0XHRcdGxpbmU6IGksXG5cdFx0XHRjaDogMFxuXHRcdH0sIHtcblx0XHRcdGxpbmU6IGksXG5cdFx0XHRjaDogeWFzcWUuZ2V0TGluZShpKS5sZW5ndGhcblx0XHR9KTtcblx0fVxufTtcbnJvb3QuY29weUxpbmVEb3duID0gZnVuY3Rpb24oeWFzcWUpIHtcblx0cm9vdC5jb3B5TGluZVVwKHlhc3FlKTtcblx0Ly8gTWFrZSBzdXJlIGN1cnNvciBnb2VzIG9uZSBkb3duICh3ZSBhcmUgY29weWluZyBkb3dud2FyZHMpXG5cdHZhciBjdXJzb3IgPSB5YXNxZS5nZXRDdXJzb3IoKTtcblx0Y3Vyc29yLmxpbmUrKztcblx0eWFzcWUuc2V0Q3Vyc29yKGN1cnNvcik7XG59O1xucm9vdC5kb0F1dG9Gb3JtYXQgPSBmdW5jdGlvbih5YXNxZSkge1xuXHRpZiAoeWFzcWUuc29tZXRoaW5nU2VsZWN0ZWQoKSkge1xuXHRcdHZhciB0byA9IHtcblx0XHRcdGxpbmU6IHlhc3FlLmdldEN1cnNvcihmYWxzZSkubGluZSxcblx0XHRcdGNoOiB5YXNxZS5nZXRTZWxlY3Rpb24oKS5sZW5ndGhcblx0XHR9O1xuXHRcdGF1dG9Gb3JtYXRSYW5nZSh5YXNxZSwgeWFzcWUuZ2V0Q3Vyc29yKHRydWUpLCB0byk7XG5cdH0gZWxzZSB7XG5cdFx0dmFyIHRvdGFsTGluZXMgPSB5YXNxZS5saW5lQ291bnQoKTtcblx0XHR2YXIgdG90YWxDaGFycyA9IHlhc3FlLmdldFRleHRBcmVhKCkudmFsdWUubGVuZ3RoO1xuXHRcdGF1dG9Gb3JtYXRSYW5nZSh5YXNxZSwge1xuXHRcdFx0bGluZTogMCxcblx0XHRcdGNoOiAwXG5cdFx0fSwge1xuXHRcdFx0bGluZTogdG90YWxMaW5lcyxcblx0XHRcdGNoOiB0b3RhbENoYXJzXG5cdFx0fSk7XG5cdH1cblxufTtcblxuXG52YXIgYXV0b0Zvcm1hdFJhbmdlID0gZnVuY3Rpb24oeWFzcWUsIGZyb20sIHRvKSB7XG5cdHZhciBhYnNTdGFydCA9IHlhc3FlLmluZGV4RnJvbVBvcyhmcm9tKTtcblx0dmFyIGFic0VuZCA9IHlhc3FlLmluZGV4RnJvbVBvcyh0byk7XG5cdC8vIEluc2VydCBhZGRpdGlvbmFsIGxpbmUgYnJlYWtzIHdoZXJlIG5lY2Vzc2FyeSBhY2NvcmRpbmcgdG8gdGhlXG5cdC8vIG1vZGUncyBzeW50YXhcblx0dmFyIHJlcyA9IGF1dG9Gb3JtYXRMaW5lQnJlYWtzKHlhc3FlLmdldFZhbHVlKCksIGFic1N0YXJ0LCBhYnNFbmQpO1xuXG5cdC8vIFJlcGxhY2UgYW5kIGF1dG8taW5kZW50IHRoZSByYW5nZVxuXHR5YXNxZS5vcGVyYXRpb24oZnVuY3Rpb24oKSB7XG5cdFx0eWFzcWUucmVwbGFjZVJhbmdlKHJlcywgZnJvbSwgdG8pO1xuXHRcdHZhciBzdGFydExpbmUgPSB5YXNxZS5wb3NGcm9tSW5kZXgoYWJzU3RhcnQpLmxpbmU7XG5cdFx0dmFyIGVuZExpbmUgPSB5YXNxZS5wb3NGcm9tSW5kZXgoYWJzU3RhcnQgKyByZXMubGVuZ3RoKS5saW5lO1xuXHRcdGZvciAodmFyIGkgPSBzdGFydExpbmU7IGkgPD0gZW5kTGluZTsgaSsrKSB7XG5cdFx0XHR5YXNxZS5pbmRlbnRMaW5lKGksIFwic21hcnRcIik7XG5cdFx0fVxuXHR9KTtcbn07XG5cbnZhciBhdXRvRm9ybWF0TGluZUJyZWFrcyA9IGZ1bmN0aW9uKHRleHQsIHN0YXJ0LCBlbmQpIHtcblx0dGV4dCA9IHRleHQuc3Vic3RyaW5nKHN0YXJ0LCBlbmQpO1xuXHR2YXIgYnJlYWtBZnRlckFycmF5ID0gW1xuXHRcdFtcImtleXdvcmRcIiwgXCJ3c1wiLCBcInByZWZpeGVkXCIsIFwid3NcIiwgXCJ1cmlcIl0sIC8vIGkuZS4gcHJlZml4IGRlY2xhcmF0aW9uXG5cdFx0W1wia2V5d29yZFwiLCBcIndzXCIsIFwidXJpXCJdIC8vIGkuZS4gYmFzZVxuXHRdO1xuXHR2YXIgYnJlYWtBZnRlckNoYXJhY3RlcnMgPSBbXCJ7XCIsIFwiLlwiLCBcIjtcIl07XG5cdHZhciBicmVha0JlZm9yZUNoYXJhY3RlcnMgPSBbXCJ9XCJdO1xuXHR2YXIgZ2V0QnJlYWtUeXBlID0gZnVuY3Rpb24oc3RyaW5nVmFsLCB0eXBlKSB7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBicmVha0FmdGVyQXJyYXkubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChzdGFja1RyYWNlLnZhbHVlT2YoKS50b1N0cmluZygpID09IGJyZWFrQWZ0ZXJBcnJheVtpXS52YWx1ZU9mKClcblx0XHRcdFx0LnRvU3RyaW5nKCkpIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgYnJlYWtBZnRlckNoYXJhY3RlcnMubGVuZ3RoOyBpKyspIHtcblx0XHRcdGlmIChzdHJpbmdWYWwgPT0gYnJlYWtBZnRlckNoYXJhY3RlcnNbaV0pIHtcblx0XHRcdFx0cmV0dXJuIDE7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGZvciAodmFyIGkgPSAwOyBpIDwgYnJlYWtCZWZvcmVDaGFyYWN0ZXJzLmxlbmd0aDsgaSsrKSB7XG5cdFx0XHQvLyBkb24ndCB3YW50IHRvIGlzc3VlICdicmVha2JlZm9yZScgQU5EICdicmVha2FmdGVyJywgc28gY2hlY2tcblx0XHRcdC8vIGN1cnJlbnQgbGluZVxuXHRcdFx0aWYgKCQudHJpbShjdXJyZW50TGluZSkgIT0gJycgJiYgc3RyaW5nVmFsID09IGJyZWFrQmVmb3JlQ2hhcmFjdGVyc1tpXSkge1xuXHRcdFx0XHRyZXR1cm4gLTE7XG5cdFx0XHR9XG5cdFx0fVxuXHRcdHJldHVybiAwO1xuXHR9O1xuXHR2YXIgZm9ybWF0dGVkUXVlcnkgPSBcIlwiO1xuXHR2YXIgY3VycmVudExpbmUgPSBcIlwiO1xuXHR2YXIgc3RhY2tUcmFjZSA9IFtdO1xuXHRDb2RlTWlycm9yLnJ1bk1vZGUodGV4dCwgXCJzcGFycWwxMVwiLCBmdW5jdGlvbihzdHJpbmdWYWwsIHR5cGUpIHtcblx0XHRzdGFja1RyYWNlLnB1c2godHlwZSk7XG5cdFx0dmFyIGJyZWFrVHlwZSA9IGdldEJyZWFrVHlwZShzdHJpbmdWYWwsIHR5cGUpO1xuXHRcdGlmIChicmVha1R5cGUgIT0gMCkge1xuXHRcdFx0aWYgKGJyZWFrVHlwZSA9PSAxKSB7XG5cdFx0XHRcdGZvcm1hdHRlZFF1ZXJ5ICs9IHN0cmluZ1ZhbCArIFwiXFxuXCI7XG5cdFx0XHRcdGN1cnJlbnRMaW5lID0gXCJcIjtcblx0XHRcdH0gZWxzZSB7IC8vICgtMSlcblx0XHRcdFx0Zm9ybWF0dGVkUXVlcnkgKz0gXCJcXG5cIiArIHN0cmluZ1ZhbDtcblx0XHRcdFx0Y3VycmVudExpbmUgPSBzdHJpbmdWYWw7XG5cdFx0XHR9XG5cdFx0XHRzdGFja1RyYWNlID0gW107XG5cdFx0fSBlbHNlIHtcblx0XHRcdGN1cnJlbnRMaW5lICs9IHN0cmluZ1ZhbDtcblx0XHRcdGZvcm1hdHRlZFF1ZXJ5ICs9IHN0cmluZ1ZhbDtcblx0XHR9XG5cdFx0aWYgKHN0YWNrVHJhY2UubGVuZ3RoID09IDEgJiYgc3RhY2tUcmFjZVswXSA9PSBcInNwLXdzXCIpXG5cdFx0XHRzdGFja1RyYWNlID0gW107XG5cdH0pO1xuXHRyZXR1cm4gJC50cmltKGZvcm1hdHRlZFF1ZXJ5LnJlcGxhY2UoL1xcblxccypcXG4vZywgJ1xcbicpKTtcbn07XG5cbnJlcXVpcmUoJy4vc3BhcnFsLmpzJyksXG5cdHJlcXVpcmUoJy4vZGVmYXVsdHMuanMnKTtcbnJvb3QuJCA9ICQ7XG5yb290LnZlcnNpb24gPSB7XG5cdFwiQ29kZU1pcnJvclwiOiBDb2RlTWlycm9yLnZlcnNpb24sXG5cdFwiWUFTUUVcIjogcmVxdWlyZShcIi4uL3BhY2thZ2UuanNvblwiKS52ZXJzaW9uLFxuXHRcImpxdWVyeVwiOiAkLmZuLmpxdWVyeSxcblx0XCJ5YXNndWktdXRpbHNcIjogeXV0aWxzLnZlcnNpb25cbn07XG4iLCJ2YXIgQ29kZU1pcnJvciA9IHJlcXVpcmUoJ2NvZGVtaXJyb3InKSxcblx0dG9rZW5VdGlscyA9IHJlcXVpcmUoJy4vdG9rZW5VdGlscy5qcycpO1xuXG5cInVzZSBzdHJpY3RcIjtcbnZhciBsb29rRm9yID0gXCJQUkVGSVhcIjtcbm1vZHVsZS5leHBvcnRzID0ge1xuXHRmaW5kRmlyc3RQcmVmaXhMaW5lOiBmdW5jdGlvbihjbSkge1xuXHRcdHZhciBsYXN0TGluZSA9IGNtLmxhc3RMaW5lKCk7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPD0gbGFzdExpbmU7ICsraSkge1xuXHRcdFx0aWYgKGZpbmRGaXJzdFByZWZpeChjbSwgaSkgPj0gMCkge1xuXHRcdFx0XHRyZXR1cm4gaTtcblx0XHRcdH1cblx0XHR9XG5cdH1cbn1cblxuZnVuY3Rpb24gZmluZEZpcnN0UHJlZml4KGNtLCBsaW5lLCBjaCwgbGluZVRleHQpIHtcblx0aWYgKCFjaCkgY2ggPSAwO1xuXHRpZiAoIWxpbmVUZXh0KSBsaW5lVGV4dCA9IGNtLmdldExpbmUobGluZSk7XG5cdGxpbmVUZXh0ID0gbGluZVRleHQudG9VcHBlckNhc2UoKTtcblx0Zm9yICh2YXIgYXQgPSBjaCwgcGFzcyA9IDA7Oykge1xuXHRcdHZhciBmb3VuZCA9IGxpbmVUZXh0LmluZGV4T2YobG9va0ZvciwgYXQpO1xuXHRcdGlmIChmb3VuZCA9PSAtMSkge1xuXHRcdFx0aWYgKHBhc3MgPT0gMSlcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRwYXNzID0gMTtcblx0XHRcdGF0ID0gbGluZVRleHQubGVuZ3RoO1xuXHRcdFx0Y29udGludWU7XG5cdFx0fVxuXHRcdGlmIChwYXNzID09IDEgJiYgZm91bmQgPCBjaClcblx0XHRcdGJyZWFrO1xuXHRcdHRva2VuVHlwZSA9IGNtLmdldFRva2VuVHlwZUF0KENvZGVNaXJyb3IuUG9zKGxpbmUsIGZvdW5kICsgMSkpO1xuXHRcdGlmICghL14oY29tbWVudHxzdHJpbmcpLy50ZXN0KHRva2VuVHlwZSkpXG5cdFx0XHRyZXR1cm4gZm91bmQgKyAxO1xuXHRcdGF0ID0gZm91bmQgLSAxO1xuXHR9XG59XG5cbkNvZGVNaXJyb3IucmVnaXN0ZXJIZWxwZXIoXCJmb2xkXCIsIFwicHJlZml4XCIsIGZ1bmN0aW9uKGNtLCBzdGFydCkge1xuXHR2YXIgbGluZSA9IHN0YXJ0LmxpbmUsXG5cdFx0bGluZVRleHQgPSBjbS5nZXRMaW5lKGxpbmUpO1xuXG5cdHZhciBzdGFydENoLCB0b2tlblR5cGU7XG5cblx0ZnVuY3Rpb24gaGFzUHJldmlvdXNQcmVmaXgoKSB7XG5cdFx0dmFyIGhhc1ByZXZpb3VzUHJlZml4ID0gZmFsc2U7XG5cdFx0Zm9yICh2YXIgaSA9IGxpbmUgLSAxOyBpID49IDA7IGktLSkge1xuXHRcdFx0aWYgKGNtLmdldExpbmUoaSkudG9VcHBlckNhc2UoKS5pbmRleE9mKGxvb2tGb3IpID49IDApIHtcblx0XHRcdFx0aGFzUHJldmlvdXNQcmVmaXggPSB0cnVlO1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIGhhc1ByZXZpb3VzUHJlZml4O1xuXHR9XG5cblxuXHRmdW5jdGlvbiBmaW5kT3BlbmluZyhvcGVuQ2gpIHtcblx0XHRmb3IgKHZhciBhdCA9IHN0YXJ0LmNoLCBwYXNzID0gMDs7KSB7XG5cdFx0XHR2YXIgZm91bmQgPSBhdCA8PSAwID8gLTEgOiBsaW5lVGV4dC5sYXN0SW5kZXhPZihvcGVuQ2gsIGF0IC0gMSk7XG5cdFx0XHRpZiAoZm91bmQgPT0gLTEpIHtcblx0XHRcdFx0aWYgKHBhc3MgPT0gMSlcblx0XHRcdFx0XHRicmVhaztcblx0XHRcdFx0cGFzcyA9IDE7XG5cdFx0XHRcdGF0ID0gbGluZVRleHQubGVuZ3RoO1xuXHRcdFx0XHRjb250aW51ZTtcblx0XHRcdH1cblx0XHRcdGlmIChwYXNzID09IDEgJiYgZm91bmQgPCBzdGFydC5jaClcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR0b2tlblR5cGUgPSBjbS5nZXRUb2tlblR5cGVBdChDb2RlTWlycm9yLlBvcyhsaW5lLCBmb3VuZCArIDEpKTtcblx0XHRcdGlmICghL14oY29tbWVudHxzdHJpbmcpLy50ZXN0KHRva2VuVHlwZSkpXG5cdFx0XHRcdHJldHVybiBmb3VuZCArIDE7XG5cdFx0XHRhdCA9IGZvdW5kIC0gMTtcblx0XHR9XG5cdH1cblx0dmFyIGdldExhc3RQcmVmaXhQb3MgPSBmdW5jdGlvbihsaW5lLCBjaCkge1xuXHRcdHZhciBwcmVmaXhLZXl3b3JkVG9rZW4gPSBjbS5nZXRUb2tlbkF0KENvZGVNaXJyb3IuUG9zKGxpbmUsIGNoICsgMSkpO1xuXHRcdGlmICghcHJlZml4S2V5d29yZFRva2VuIHx8IHByZWZpeEtleXdvcmRUb2tlbi50eXBlICE9IFwia2V5d29yZFwiKSByZXR1cm4gLTE7XG5cdFx0dmFyIHByZWZpeFNob3J0bmFtZSA9IHRva2VuVXRpbHMuZ2V0TmV4dE5vbldzVG9rZW4oY20sIGxpbmUsIHByZWZpeEtleXdvcmRUb2tlbi5lbmQgKyAxKTtcblx0XHRpZiAoIXByZWZpeFNob3J0bmFtZSB8fCBwcmVmaXhTaG9ydG5hbWUudHlwZSAhPSBcInN0cmluZy0yXCIpIHJldHVybiAtMTsgLy9taXNzaW5nIHByZWZpeCBrZXl3b3JkIHNob3J0bmFtZVxuXHRcdHZhciBwcmVmaXhVcmkgPSB0b2tlblV0aWxzLmdldE5leHROb25Xc1Rva2VuKGNtLCBsaW5lLCBwcmVmaXhTaG9ydG5hbWUuZW5kICsgMSk7XG5cdFx0aWYgKCFwcmVmaXhVcmkgfHwgcHJlZml4VXJpLnR5cGUgIT0gXCJ2YXJpYWJsZS0zXCIpIHJldHVybiAtMTsgLy9taXNzaW5nIHByZWZpeCB1cmlcblx0XHRyZXR1cm4gcHJlZml4VXJpLmVuZDtcblx0fVxuXG5cdC8vb25seSB1c2Ugb3BlbmluZyBwcmVmaXggZGVjbGFyYXRpb25cblx0aWYgKGhhc1ByZXZpb3VzUHJlZml4KCkpXG5cdFx0cmV0dXJuO1xuXHR2YXIgcHJlZml4U3RhcnQgPSBmaW5kRmlyc3RQcmVmaXgoY20sIGxpbmUsIHN0YXJ0LmNoLCBsaW5lVGV4dCk7XG5cblx0aWYgKHByZWZpeFN0YXJ0ID09IG51bGwpXG5cdFx0cmV0dXJuO1xuXHR2YXIgc3RvcEF0ID0gJ3snOyAvL2lmIHRoaXMgY2hhciBpcyB0aGVyZSwgd2Ugd29uJ3QgaGF2ZSBhIGNoYW5jZSBvZiBmaW5kaW5nIG1vcmUgcHJlZml4ZXNcblx0dmFyIHN0b3BBdE5leHRMaW5lID0gZmFsc2U7XG5cdHZhciBjb3VudCA9IDEsXG5cdFx0bGFzdExpbmUgPSBjbS5sYXN0TGluZSgpLFxuXHRcdGVuZCwgZW5kQ2g7XG5cdHZhciBwcmVmaXhFbmRDaGFyID0gZ2V0TGFzdFByZWZpeFBvcyhsaW5lLCBwcmVmaXhTdGFydCk7XG5cdHZhciBwcmVmaXhFbmRMaW5lID0gbGluZTtcblxuXHRvdXRlcjogZm9yICh2YXIgaSA9IGxpbmU7IGkgPD0gbGFzdExpbmU7ICsraSkge1xuXHRcdGlmIChzdG9wQXROZXh0TGluZSlcblx0XHRcdGJyZWFrO1xuXHRcdHZhciB0ZXh0ID0gY20uZ2V0TGluZShpKSxcblx0XHRcdHBvcyA9IGkgPT0gbGluZSA/IHByZWZpeFN0YXJ0ICsgMSA6IDA7XG5cblx0XHRmb3IgKDs7KSB7XG5cdFx0XHRpZiAoIXN0b3BBdE5leHRMaW5lICYmIHRleHQuaW5kZXhPZihzdG9wQXQpID49IDApXG5cdFx0XHRcdHN0b3BBdE5leHRMaW5lID0gdHJ1ZTtcblxuXHRcdFx0dmFyIG5leHRQcmVmaXhEZWNsYXJhdGlvbiA9IHRleHQudG9VcHBlckNhc2UoKVxuXHRcdFx0XHQuaW5kZXhPZihsb29rRm9yLCBwb3MpO1xuXG5cdFx0XHRpZiAobmV4dFByZWZpeERlY2xhcmF0aW9uID49IDApIHtcblx0XHRcdFx0aWYgKChlbmRDaCA9IGdldExhc3RQcmVmaXhQb3MoaSwgbmV4dFByZWZpeERlY2xhcmF0aW9uKSkgPiAwKSB7XG5cdFx0XHRcdFx0cHJlZml4RW5kQ2hhciA9IGVuZENoO1xuXHRcdFx0XHRcdHByZWZpeEVuZExpbmUgPSBpO1xuXHRcdFx0XHRcdHBvcyA9IHByZWZpeEVuZENoYXI7XG5cdFx0XHRcdH1cblx0XHRcdFx0cG9zKys7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRicmVhaztcblx0XHRcdH1cblx0XHR9XG5cdH1cblx0cmV0dXJuIHtcblx0XHRmcm9tOiBDb2RlTWlycm9yLlBvcyhsaW5lLCBwcmVmaXhTdGFydCArIGxvb2tGb3IubGVuZ3RoKSxcblx0XHR0bzogQ29kZU1pcnJvci5Qb3MocHJlZml4RW5kTGluZSwgcHJlZml4RW5kQ2hhcilcblx0fTtcbn0pOyIsIid1c2Ugc3RyaWN0Jztcbi8qKlxuICogQXBwZW5kIHByZWZpeCBkZWNsYXJhdGlvbiB0byBsaXN0IG9mIHByZWZpeGVzIGluIHF1ZXJ5IHdpbmRvdy5cbiAqIFxuICogQHBhcmFtIHlhc3FlXG4gKiBAcGFyYW0gcHJlZml4XG4gKi9cbnZhciBhZGRQcmVmaXhlcyA9IGZ1bmN0aW9uKHlhc3FlLCBwcmVmaXhlcykge1xuXHR2YXIgZXhpc3RpbmdQcmVmaXhlcyA9IHlhc3FlLmdldFByZWZpeGVzRnJvbVF1ZXJ5KCk7XG5cdC8vZm9yIGJhY2t3YXJkcyBjb21wYXRhYmlsaXR5LCB3ZSBzdGlsIHN1cHBvcnQgcHJlZml4ZXMgdmFsdWUgYXMgc3RyaW5nIChlLmcuICdyZGY6IDxodHRwOi8vZmJmZ2ZnZj4nXG5cdGlmICh0eXBlb2YgcHJlZml4ZXMgPT0gXCJzdHJpbmdcIikge1xuXHRcdGFkZFByZWZpeEFzU3RyaW5nKHlhc3FlLCBwcmVmaXhlcyk7XG5cdH0gZWxzZSB7XG5cdFx0Zm9yICh2YXIgcHJlZiBpbiBwcmVmaXhlcykge1xuXHRcdFx0aWYgKCEocHJlZiBpbiBleGlzdGluZ1ByZWZpeGVzKSlcblx0XHRcdFx0YWRkUHJlZml4QXNTdHJpbmcoeWFzcWUsIHByZWYgKyBcIjogPFwiICsgcHJlZml4ZXNbcHJlZl0gKyBcIj5cIik7XG5cdFx0fVxuXHR9XG5cdHlhc3FlLmNvbGxhcHNlUHJlZml4ZXMoZmFsc2UpO1xufTtcblxudmFyIGFkZFByZWZpeEFzU3RyaW5nID0gZnVuY3Rpb24oeWFzcWUsIHByZWZpeFN0cmluZykge1xuXHR2YXIgbGFzdFByZWZpeCA9IG51bGw7XG5cdHZhciBsYXN0UHJlZml4TGluZSA9IDA7XG5cdHZhciBudW1MaW5lcyA9IHlhc3FlLmxpbmVDb3VudCgpO1xuXHRmb3IgKHZhciBpID0gMDsgaSA8IG51bUxpbmVzOyBpKyspIHtcblx0XHR2YXIgZmlyc3RUb2tlbiA9IHlhc3FlLmdldE5leHROb25Xc1Rva2VuKGkpO1xuXHRcdGlmIChmaXJzdFRva2VuICE9IG51bGwgJiYgKGZpcnN0VG9rZW4uc3RyaW5nID09IFwiUFJFRklYXCIgfHwgZmlyc3RUb2tlbi5zdHJpbmcgPT0gXCJCQVNFXCIpKSB7XG5cdFx0XHRsYXN0UHJlZml4ID0gZmlyc3RUb2tlbjtcblx0XHRcdGxhc3RQcmVmaXhMaW5lID0gaTtcblx0XHR9XG5cdH1cblxuXHRpZiAobGFzdFByZWZpeCA9PSBudWxsKSB7XG5cdFx0eWFzcWUucmVwbGFjZVJhbmdlKFwiUFJFRklYIFwiICsgcHJlZml4U3RyaW5nICsgXCJcXG5cIiwge1xuXHRcdFx0bGluZTogMCxcblx0XHRcdGNoOiAwXG5cdFx0fSk7XG5cdH0gZWxzZSB7XG5cdFx0dmFyIHByZXZpb3VzSW5kZW50ID0gZ2V0SW5kZW50RnJvbUxpbmUoeWFzcWUsIGxhc3RQcmVmaXhMaW5lKTtcblx0XHR5YXNxZS5yZXBsYWNlUmFuZ2UoXCJcXG5cIiArIHByZXZpb3VzSW5kZW50ICsgXCJQUkVGSVggXCIgKyBwcmVmaXhTdHJpbmcsIHtcblx0XHRcdGxpbmU6IGxhc3RQcmVmaXhMaW5lXG5cdFx0fSk7XG5cdH1cblx0eWFzcWUuY29sbGFwc2VQcmVmaXhlcyhmYWxzZSk7XG59O1xudmFyIHJlbW92ZVByZWZpeGVzID0gZnVuY3Rpb24oeWFzcWUsIHByZWZpeGVzKSB7XG5cdHZhciBlc2NhcGVSZWdleCA9IGZ1bmN0aW9uKHN0cmluZykge1xuXHRcdC8vdGFrZW4gZnJvbSBodHRwOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzM1NjE0OTMvaXMtdGhlcmUtYS1yZWdleHAtZXNjYXBlLWZ1bmN0aW9uLWluLWphdmFzY3JpcHQvMzU2MTcxMSMzNTYxNzExXG5cdFx0cmV0dXJuIHN0cmluZy5yZXBsYWNlKC9bLVxcL1xcXFxeJCorPy4oKXxbXFxde31dL2csICdcXFxcJCYnKTtcblx0fVxuXHRmb3IgKHZhciBwcmVmIGluIHByZWZpeGVzKSB7XG5cdFx0eWFzcWUuc2V0VmFsdWUoeWFzcWUuZ2V0VmFsdWUoKS5yZXBsYWNlKG5ldyBSZWdFeHAoXCJQUkVGSVhcXFxccypcIiArIHByZWYgKyBcIjpcXFxccypcIiArIGVzY2FwZVJlZ2V4KFwiPFwiICsgcHJlZml4ZXNbcHJlZl0gKyBcIj5cIikgKyBcIlxcXFxzKlwiLCBcImlnXCIpLCAnJykpO1xuXHR9XG5cdHlhc3FlLmNvbGxhcHNlUHJlZml4ZXMoZmFsc2UpO1xuXG59O1xuXG4vKipcbiAqIEdldCBkZWZpbmVkIHByZWZpeGVzIGZyb20gcXVlcnkgYXMgYXJyYXksIGluIGZvcm1hdCB7XCJwcmVmaXg6XCIgXCJ1cmlcIn1cbiAqIFxuICogQHBhcmFtIGNtXG4gKiBAcmV0dXJucyB7QXJyYXl9XG4gKi9cbnZhciBnZXRQcmVmaXhlc0Zyb21RdWVyeSA9IGZ1bmN0aW9uKHlhc3FlKSB7XG5cdHZhciBxdWVyeVByZWZpeGVzID0ge307XG5cdHZhciBzaG91bGRDb250aW51ZSA9IHRydWU7XG5cdHZhciBnZXRQcmVmaXhlc0Zyb21MaW5lID0gZnVuY3Rpb24obGluZU9mZnNldCwgY29sT2Zmc2V0KSB7XG5cdFx0aWYgKCFzaG91bGRDb250aW51ZSkgcmV0dXJuO1xuXHRcdGlmICghY29sT2Zmc2V0KSBjb2xPZmZzZXQgPSAxO1xuXHRcdHZhciB0b2tlbiA9IHlhc3FlLmdldE5leHROb25Xc1Rva2VuKGksIGNvbE9mZnNldCk7XG5cdFx0aWYgKHRva2VuKSB7XG5cdFx0XHRpZiAodG9rZW4uc3RhdGUucG9zc2libGVDdXJyZW50LmluZGV4T2YoXCJQUkVGSVhcIikgPT0gLTEgJiYgdG9rZW4uc3RhdGUucG9zc2libGVOZXh0LmluZGV4T2YoXCJQUkVGSVhcIikgPT0gLTEpIHNob3VsZENvbnRpbnVlID0gZmFsc2U7IC8vd2UgYXJlIGJleW9uZCB0aGUgcGxhY2UgaW4gdGhlIHF1ZXJ5IHdoZXJlIHdlIGNhbiBlbnRlciBwcmVmaXhlc1xuXHRcdFx0aWYgKHRva2VuLnN0cmluZy50b1VwcGVyQ2FzZSgpID09IFwiUFJFRklYXCIpIHtcblx0XHRcdFx0dmFyIHByZWZpeCA9IHlhc3FlLmdldE5leHROb25Xc1Rva2VuKGksIHRva2VuLmVuZCArIDEpO1xuXHRcdFx0XHRpZiAocHJlZml4KSB7XG5cdFx0XHRcdFx0dmFyIHVyaSA9IHlhc3FlLmdldE5leHROb25Xc1Rva2VuKGksIHByZWZpeC5lbmQgKyAxKTtcblx0XHRcdFx0XHRpZiAodXJpKSB7XG5cdFx0XHRcdFx0XHR2YXIgdXJpU3RyaW5nID0gdXJpLnN0cmluZztcblx0XHRcdFx0XHRcdGlmICh1cmlTdHJpbmcuaW5kZXhPZihcIjxcIikgPT0gMClcblx0XHRcdFx0XHRcdFx0dXJpU3RyaW5nID0gdXJpU3RyaW5nLnN1YnN0cmluZygxKTtcblx0XHRcdFx0XHRcdGlmICh1cmlTdHJpbmcuc2xpY2UoLTEpID09IFwiPlwiKVxuXHRcdFx0XHRcdFx0XHR1cmlTdHJpbmcgPSB1cmlTdHJpbmdcblx0XHRcdFx0XHRcdFx0LnN1YnN0cmluZygwLCB1cmlTdHJpbmcubGVuZ3RoIC0gMSk7XG5cdFx0XHRcdFx0XHRxdWVyeVByZWZpeGVzW3ByZWZpeC5zdHJpbmcuc2xpY2UoMCwgLTEpXSA9IHVyaVN0cmluZztcblxuXHRcdFx0XHRcdFx0Z2V0UHJlZml4ZXNGcm9tTGluZShsaW5lT2Zmc2V0LCB1cmkuZW5kICsgMSk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdGdldFByZWZpeGVzRnJvbUxpbmUobGluZU9mZnNldCwgcHJlZml4LmVuZCArIDEpO1xuXHRcdFx0XHRcdH1cblxuXHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdGdldFByZWZpeGVzRnJvbUxpbmUobGluZU9mZnNldCwgdG9rZW4uZW5kICsgMSk7XG5cdFx0XHRcdH1cblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGdldFByZWZpeGVzRnJvbUxpbmUobGluZU9mZnNldCwgdG9rZW4uZW5kICsgMSk7XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xuXG5cblx0dmFyIG51bUxpbmVzID0geWFzcWUubGluZUNvdW50KCk7XG5cdGZvciAodmFyIGkgPSAwOyBpIDwgbnVtTGluZXM7IGkrKykge1xuXHRcdGlmICghc2hvdWxkQ29udGludWUpIGJyZWFrO1xuXHRcdGdldFByZWZpeGVzRnJvbUxpbmUoaSk7XG5cblx0fVxuXHRyZXR1cm4gcXVlcnlQcmVmaXhlcztcbn07XG5cbi8qKlxuICogR2V0IHRoZSB1c2VkIGluZGVudGF0aW9uIGZvciBhIGNlcnRhaW4gbGluZVxuICogXG4gKiBAcGFyYW0geWFzcWVcbiAqIEBwYXJhbSBsaW5lXG4gKiBAcGFyYW0gY2hhck51bWJlclxuICogQHJldHVybnNcbiAqL1xudmFyIGdldEluZGVudEZyb21MaW5lID0gZnVuY3Rpb24oeWFzcWUsIGxpbmUsIGNoYXJOdW1iZXIpIHtcblx0aWYgKGNoYXJOdW1iZXIgPT0gdW5kZWZpbmVkKVxuXHRcdGNoYXJOdW1iZXIgPSAxO1xuXHR2YXIgdG9rZW4gPSB5YXNxZS5nZXRUb2tlbkF0KHtcblx0XHRsaW5lOiBsaW5lLFxuXHRcdGNoOiBjaGFyTnVtYmVyXG5cdH0pO1xuXHRpZiAodG9rZW4gPT0gbnVsbCB8fCB0b2tlbiA9PSB1bmRlZmluZWQgfHwgdG9rZW4udHlwZSAhPSBcIndzXCIpIHtcblx0XHRyZXR1cm4gXCJcIjtcblx0fSBlbHNlIHtcblx0XHRyZXR1cm4gdG9rZW4uc3RyaW5nICsgZ2V0SW5kZW50RnJvbUxpbmUoeWFzcWUsIGxpbmUsIHRva2VuLmVuZCArIDEpO1xuXHR9O1xufTtcblxubW9kdWxlLmV4cG9ydHMgPSB7XG5cdGFkZFByZWZpeGVzOiBhZGRQcmVmaXhlcyxcblx0Z2V0UHJlZml4ZXNGcm9tUXVlcnk6IGdldFByZWZpeGVzRnJvbVF1ZXJ5LFxuXHRyZW1vdmVQcmVmaXhlczogcmVtb3ZlUHJlZml4ZXNcbn07IiwiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCdqcXVlcnknKSxcblx0WUFTUUUgPSByZXF1aXJlKCcuL21haW4uanMnKTtcbllBU1FFLmV4ZWN1dGVRdWVyeSA9IGZ1bmN0aW9uKHlhc3FlLCBjYWxsYmFja09yQ29uZmlnKSB7XG5cdFlBU1FFLnNpZ25hbCh5YXNxZSwgJ3F1ZXJ5JywgeWFzcWUsIGNhbGxiYWNrT3JDb25maWcpO1xuXHR2YXIgY2FsbGJhY2sgPSAodHlwZW9mIGNhbGxiYWNrT3JDb25maWcgPT0gXCJmdW5jdGlvblwiID8gY2FsbGJhY2tPckNvbmZpZyA6IG51bGwpO1xuXHR2YXIgY29uZmlnID0gKHR5cGVvZiBjYWxsYmFja09yQ29uZmlnID09IFwib2JqZWN0XCIgPyBjYWxsYmFja09yQ29uZmlnIDoge30pO1xuXG5cdGlmICh5YXNxZS5vcHRpb25zLnNwYXJxbClcblx0XHRjb25maWcgPSAkLmV4dGVuZCh7fSwgeWFzcWUub3B0aW9ucy5zcGFycWwsIGNvbmZpZyk7XG5cblx0Ly9mb3IgYmFja3dhcmRzIGNvbXBhdGFiaWxpdHksIG1ha2Ugc3VyZSB3ZSBjb3B5IHNwYXJxbCBoYW5kbGVycyB0byBzcGFycWwgY2FsbGJhY2tzXG5cdGlmIChjb25maWcuaGFuZGxlcnMpXG5cdFx0JC5leHRlbmQodHJ1ZSwgY29uZmlnLmNhbGxiYWNrcywgY29uZmlnLmhhbmRsZXJzKTtcblxuXG5cdGlmICghY29uZmlnLmVuZHBvaW50IHx8IGNvbmZpZy5lbmRwb2ludC5sZW5ndGggPT0gMClcblx0XHRyZXR1cm47IC8vIG5vdGhpbmcgdG8gcXVlcnkhXG5cblx0LyoqXG5cdCAqIGluaXRpYWxpemUgYWpheCBjb25maWdcblx0ICovXG5cdHZhciBhamF4Q29uZmlnID0ge1xuXHRcdHVybDogKHR5cGVvZiBjb25maWcuZW5kcG9pbnQgPT0gXCJmdW5jdGlvblwiID8gY29uZmlnLmVuZHBvaW50KHlhc3FlKSA6IGNvbmZpZy5lbmRwb2ludCksXG5cdFx0dHlwZTogKHR5cGVvZiBjb25maWcucmVxdWVzdE1ldGhvZCA9PSBcImZ1bmN0aW9uXCIgPyBjb25maWcucmVxdWVzdE1ldGhvZCh5YXNxZSkgOiBjb25maWcucmVxdWVzdE1ldGhvZCksXG5cdFx0aGVhZGVyczoge1xuXHRcdFx0QWNjZXB0OiBnZXRBY2NlcHRIZWFkZXIoeWFzcWUsIGNvbmZpZyksXG5cdFx0fVxuXHR9O1xuXHRpZiAoY29uZmlnLnhockZpZWxkcykgYWpheENvbmZpZy54aHJGaWVsZHMgPSBjb25maWcueGhyRmllbGRzO1xuXHQvKipcblx0ICogYWRkIGNvbXBsZXRlLCBiZWZvcmVzZW5kLCBldGMgY2FsbGJhY2tzIChpZiBzcGVjaWZpZWQpXG5cdCAqL1xuXHR2YXIgaGFuZGxlckRlZmluZWQgPSBmYWxzZTtcblx0aWYgKGNvbmZpZy5jYWxsYmFja3MpIHtcblx0XHRmb3IgKHZhciBoYW5kbGVyIGluIGNvbmZpZy5jYWxsYmFja3MpIHtcblx0XHRcdGlmIChjb25maWcuY2FsbGJhY2tzW2hhbmRsZXJdKSB7XG5cdFx0XHRcdGhhbmRsZXJEZWZpbmVkID0gdHJ1ZTtcblx0XHRcdFx0YWpheENvbmZpZ1toYW5kbGVyXSA9IGNvbmZpZy5jYWxsYmFja3NbaGFuZGxlcl07XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdGFqYXhDb25maWcuZGF0YSA9IHlhc3FlLmdldFVybEFyZ3VtZW50cyhjb25maWcpO1xuXHRpZiAoIWhhbmRsZXJEZWZpbmVkICYmICFjYWxsYmFjaylcblx0XHRyZXR1cm47IC8vIG9rLCB3ZSBjYW4gcXVlcnksIGJ1dCBoYXZlIG5vIGNhbGxiYWNrcy4ganVzdCBzdG9wIG5vd1xuXG5cdC8vIGlmIG9ubHkgY2FsbGJhY2sgaXMgcGFzc2VkIGFzIGFyZywgYWRkIHRoYXQgb24gYXMgJ29uQ29tcGxldGUnIGNhbGxiYWNrXG5cdGlmIChjYWxsYmFjaylcblx0XHRhamF4Q29uZmlnLmNvbXBsZXRlID0gY2FsbGJhY2s7XG5cblxuXG5cdC8qKlxuXHQgKiBtZXJnZSBhZGRpdGlvbmFsIHJlcXVlc3QgaGVhZGVyc1xuXHQgKi9cblx0aWYgKGNvbmZpZy5oZWFkZXJzICYmICEkLmlzRW1wdHlPYmplY3QoY29uZmlnLmhlYWRlcnMpKVxuXHRcdCQuZXh0ZW5kKGFqYXhDb25maWcuaGVhZGVycywgY29uZmlnLmhlYWRlcnMpO1xuXG5cdFlBU1FFLnVwZGF0ZVF1ZXJ5QnV0dG9uKHlhc3FlLCBcImJ1c3lcIik7XG5cdHlhc3FlLnNldEJhY2tkcm9wKHRydWUpO1xuXHR2YXIgcXVlcnlTdGFydCA9IG5ldyBEYXRlKCk7XG5cdHZhciB1cGRhdGVZYXNxZSA9IGZ1bmN0aW9uKCkge1xuXHRcdHlhc3FlLmxhc3RRdWVyeUR1cmF0aW9uID0gbmV3IERhdGUoKSAtIHF1ZXJ5U3RhcnQ7XG5cdFx0WUFTUUUudXBkYXRlUXVlcnlCdXR0b24oeWFzcWUpO1xuXHRcdHlhc3FlLnNldEJhY2tkcm9wKGZhbHNlKTtcblx0fTtcblx0Ly9NYWtlIHN1cmUgdGhlIHF1ZXJ5IGJ1dHRvbiBpcyB1cGRhdGVkIGFnYWluIG9uIGNvbXBsZXRlXG5cdHZhciBjb21wbGV0ZUNhbGxiYWNrcyA9IFtcblx0XHRmdW5jdGlvbigpe3JlcXVpcmUoJy4vbWFpbi5qcycpLnNpZ25hbCh5YXNxZSwgJ3F1ZXJ5RmluaXNoJywgYXJndW1lbnRzKX0sXG5cdFx0dXBkYXRlWWFzcWVcblx0XTtcblxuXHRpZiAoYWpheENvbmZpZy5jb21wbGV0ZSkge1xuXHRcdGNvbXBsZXRlQ2FsbGJhY2tzLnB1c2goYWpheENvbmZpZy5jb21wbGV0ZSk7XG5cdH1cblx0YWpheENvbmZpZy5jb21wbGV0ZSA9IGNvbXBsZXRlQ2FsbGJhY2tzO1xuXG5cdHlhc3FlLnhociA9ICQuYWpheChhamF4Q29uZmlnKTtcbn07XG5cblxuWUFTUUUuZ2V0VXJsQXJndW1lbnRzID0gZnVuY3Rpb24oeWFzcWUsIGNvbmZpZykge1xuXHR2YXIgcXVlcnlNb2RlID0geWFzcWUuZ2V0UXVlcnlNb2RlKCk7XG5cdHZhciBkYXRhID0gW3tcblx0XHRuYW1lOiB5YXNxZS5nZXRRdWVyeU1vZGUoKSwgLy9laXRoZXIgJ3VwZGF0ZScgb3IgJ3F1ZXJ5J1xuXHRcdHZhbHVlOiAoY29uZmlnLmdldFF1ZXJ5Rm9yQWpheD8gY29uZmlnLmdldFF1ZXJ5Rm9yQWpheCh5YXNxZSk6IHlhc3FlLmdldFZhbHVlKCkpXG5cdH1dO1xuXG5cdC8qKlxuXHQgKiBhZGQgbmFtZWQgZ3JhcGhzIHRvIGFqYXggY29uZmlnXG5cdCAqL1xuXHRpZiAoY29uZmlnLm5hbWVkR3JhcGhzICYmIGNvbmZpZy5uYW1lZEdyYXBocy5sZW5ndGggPiAwKSB7XG5cdFx0dmFyIGFyZ05hbWUgPSAocXVlcnlNb2RlID09IFwicXVlcnlcIiA/IFwibmFtZWQtZ3JhcGgtdXJpXCIgOiBcInVzaW5nLW5hbWVkLWdyYXBoLXVyaSBcIik7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBjb25maWcubmFtZWRHcmFwaHMubGVuZ3RoOyBpKyspXG5cdFx0XHRkYXRhLnB1c2goe1xuXHRcdFx0XHRuYW1lOiBhcmdOYW1lLFxuXHRcdFx0XHR2YWx1ZTogY29uZmlnLm5hbWVkR3JhcGhzW2ldXG5cdFx0XHR9KTtcblx0fVxuXHQvKipcblx0ICogYWRkIGRlZmF1bHQgZ3JhcGhzIHRvIGFqYXggY29uZmlnXG5cdCAqL1xuXHRpZiAoY29uZmlnLmRlZmF1bHRHcmFwaHMgJiYgY29uZmlnLmRlZmF1bHRHcmFwaHMubGVuZ3RoID4gMCkge1xuXHRcdHZhciBhcmdOYW1lID0gKHF1ZXJ5TW9kZSA9PSBcInF1ZXJ5XCIgPyBcImRlZmF1bHQtZ3JhcGgtdXJpXCIgOiBcInVzaW5nLWdyYXBoLXVyaSBcIik7XG5cdFx0Zm9yICh2YXIgaSA9IDA7IGkgPCBjb25maWcuZGVmYXVsdEdyYXBocy5sZW5ndGg7IGkrKylcblx0XHRcdGRhdGEucHVzaCh7XG5cdFx0XHRcdG5hbWU6IGFyZ05hbWUsXG5cdFx0XHRcdHZhbHVlOiBjb25maWcuZGVmYXVsdEdyYXBoc1tpXVxuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogYWRkIGFkZGl0aW9uYWwgcmVxdWVzdCBhcmdzXG5cdCAqL1xuXHRpZiAoY29uZmlnLmFyZ3MgJiYgY29uZmlnLmFyZ3MubGVuZ3RoID4gMCkgJC5tZXJnZShkYXRhLCBjb25maWcuYXJncyk7XG5cblx0cmV0dXJuIGRhdGE7XG59XG52YXIgZ2V0QWNjZXB0SGVhZGVyID0gZnVuY3Rpb24oeWFzcWUsIGNvbmZpZykge1xuXHR2YXIgYWNjZXB0SGVhZGVyID0gbnVsbDtcblx0aWYgKGNvbmZpZy5hY2NlcHRIZWFkZXIgJiYgIWNvbmZpZy5hY2NlcHRIZWFkZXJHcmFwaCAmJiAhY29uZmlnLmFjY2VwdEhlYWRlclNlbGVjdCAmJiAhY29uZmlnLmFjY2VwdEhlYWRlclVwZGF0ZSkge1xuXHRcdC8vdGhpcyBpcyB0aGUgb2xkIGNvbmZpZy4gRm9yIGJhY2t3YXJkcyBjb21wYXRhYmlsaXR5LCBrZWVwIHN1cHBvcnRpbmcgaXRcblx0XHRpZiAodHlwZW9mIGNvbmZpZy5hY2NlcHRIZWFkZXIgPT0gXCJmdW5jdGlvblwiKSB7XG5cdFx0XHRhY2NlcHRIZWFkZXIgPSBjb25maWcuYWNjZXB0SGVhZGVyKHlhc3FlKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0YWNjZXB0SGVhZGVyID0gY29uZmlnLmFjY2VwdEhlYWRlcjtcblx0XHR9XG5cdH0gZWxzZSB7XG5cdFx0aWYgKHlhc3FlLmdldFF1ZXJ5TW9kZSgpID09IFwidXBkYXRlXCIpIHtcblx0XHRcdGFjY2VwdEhlYWRlciA9ICh0eXBlb2YgY29uZmlnLmFjY2VwdEhlYWRlciA9PSBcImZ1bmN0aW9uXCIgPyBjb25maWcuYWNjZXB0SGVhZGVyVXBkYXRlKHlhc3FlKSA6IGNvbmZpZy5hY2NlcHRIZWFkZXJVcGRhdGUpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHR2YXIgcVR5cGUgPSB5YXNxZS5nZXRRdWVyeVR5cGUoKTtcblx0XHRcdGlmIChxVHlwZSA9PSBcIkRFU0NSSUJFXCIgfHwgcVR5cGUgPT0gXCJDT05TVFJVQ1RcIikge1xuXHRcdFx0XHRhY2NlcHRIZWFkZXIgPSAodHlwZW9mIGNvbmZpZy5hY2NlcHRIZWFkZXJHcmFwaCA9PSBcImZ1bmN0aW9uXCIgPyBjb25maWcuYWNjZXB0SGVhZGVyR3JhcGgoeWFzcWUpIDogY29uZmlnLmFjY2VwdEhlYWRlckdyYXBoKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGFjY2VwdEhlYWRlciA9ICh0eXBlb2YgY29uZmlnLmFjY2VwdEhlYWRlclNlbGVjdCA9PSBcImZ1bmN0aW9uXCIgPyBjb25maWcuYWNjZXB0SGVhZGVyU2VsZWN0KHlhc3FlKSA6IGNvbmZpZy5hY2NlcHRIZWFkZXJTZWxlY3QpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXHRyZXR1cm4gYWNjZXB0SGVhZGVyO1xufTtcbiIsIid1c2Ugc3RyaWN0Jztcbi8qKlxuICogV2hlbiB0eXBpbmcgYSBxdWVyeSwgdGhpcyBxdWVyeSBpcyBzb21ldGltZXMgc3ludGFjdGljYWxseSBpbnZhbGlkLCBjYXVzaW5nXG4gKiB0aGUgY3VycmVudCB0b2tlbnMgdG8gYmUgaW5jb3JyZWN0IFRoaXMgY2F1c2VzIHByb2JsZW0gZm9yIGF1dG9jb21wbGV0aW9uLlxuICogaHR0cDovL2JsYSBtaWdodCByZXN1bHQgaW4gdHdvIHRva2VuczogaHR0cDovLyBhbmQgYmxhLiBXZSdsbCB3YW50IHRvIGNvbWJpbmVcbiAqIHRoZXNlXG4gKiBcbiAqIEBwYXJhbSB5YXNxZSB7ZG9jfVxuICogQHBhcmFtIHRva2VuIHtvYmplY3R9XG4gKiBAcGFyYW0gY3Vyc29yIHtvYmplY3R9XG4gKiBAcmV0dXJuIHRva2VuIHtvYmplY3R9XG4gKiBAbWV0aG9kIFlBU1FFLmdldENvbXBsZXRlVG9rZW5cbiAqL1xudmFyIGdldENvbXBsZXRlVG9rZW4gPSBmdW5jdGlvbih5YXNxZSwgdG9rZW4sIGN1cikge1xuXHRpZiAoIWN1cikge1xuXHRcdGN1ciA9IHlhc3FlLmdldEN1cnNvcigpO1xuXHR9XG5cdGlmICghdG9rZW4pIHtcblx0XHR0b2tlbiA9IHlhc3FlLmdldFRva2VuQXQoY3VyKTtcblx0fVxuXHR2YXIgcHJldlRva2VuID0geWFzcWUuZ2V0VG9rZW5BdCh7XG5cdFx0bGluZTogY3VyLmxpbmUsXG5cdFx0Y2g6IHRva2VuLnN0YXJ0XG5cdH0pO1xuXHQvLyBub3Qgc3RhcnQgb2YgbGluZSwgYW5kIG5vdCB3aGl0ZXNwYWNlXG5cdGlmIChcblx0XHRwcmV2VG9rZW4udHlwZSAhPSBudWxsICYmIHByZXZUb2tlbi50eXBlICE9IFwid3NcIiAmJiB0b2tlbi50eXBlICE9IG51bGwgJiYgdG9rZW4udHlwZSAhPSBcIndzXCJcblx0KSB7XG5cdFx0dG9rZW4uc3RhcnQgPSBwcmV2VG9rZW4uc3RhcnQ7XG5cdFx0dG9rZW4uc3RyaW5nID0gcHJldlRva2VuLnN0cmluZyArIHRva2VuLnN0cmluZztcblx0XHRyZXR1cm4gZ2V0Q29tcGxldGVUb2tlbih5YXNxZSwgdG9rZW4sIHtcblx0XHRcdGxpbmU6IGN1ci5saW5lLFxuXHRcdFx0Y2g6IHByZXZUb2tlbi5zdGFydFxuXHRcdH0pOyAvLyByZWN1cnNpdmVseSwgbWlnaHQgaGF2ZSBtdWx0aXBsZSB0b2tlbnMgd2hpY2ggaXQgc2hvdWxkIGluY2x1ZGVcblx0fSBlbHNlIGlmICh0b2tlbi50eXBlICE9IG51bGwgJiYgdG9rZW4udHlwZSA9PSBcIndzXCIpIHtcblx0XHQvL2Fsd2F5cyBrZWVwIDEgY2hhciBvZiB3aGl0ZXNwYWNlIGJldHdlZW4gdG9rZW5zLiBPdGhlcndpc2UsIGF1dG9jb21wbGV0aW9ucyBtaWdodCBlbmQgdXAgbmV4dCB0byB0aGUgcHJldmlvdXMgbm9kZSwgd2l0aG91dCB3aGl0ZXNwYWNlIGJldHdlZW4gdGhlbVxuXHRcdHRva2VuLnN0YXJ0ID0gdG9rZW4uc3RhcnQgKyAxO1xuXHRcdHRva2VuLnN0cmluZyA9IHRva2VuLnN0cmluZy5zdWJzdHJpbmcoMSk7XG5cdFx0cmV0dXJuIHRva2VuO1xuXHR9IGVsc2Uge1xuXHRcdHJldHVybiB0b2tlbjtcblx0fVxufTtcbnZhciBnZXRQcmV2aW91c05vbldzVG9rZW4gPSBmdW5jdGlvbih5YXNxZSwgbGluZSwgdG9rZW4pIHtcblx0dmFyIHByZXZpb3VzVG9rZW4gPSB5YXNxZS5nZXRUb2tlbkF0KHtcblx0XHRsaW5lOiBsaW5lLFxuXHRcdGNoOiB0b2tlbi5zdGFydFxuXHR9KTtcblx0aWYgKHByZXZpb3VzVG9rZW4gIT0gbnVsbCAmJiBwcmV2aW91c1Rva2VuLnR5cGUgPT0gXCJ3c1wiKSB7XG5cdFx0cHJldmlvdXNUb2tlbiA9IGdldFByZXZpb3VzTm9uV3NUb2tlbih5YXNxZSwgbGluZSwgcHJldmlvdXNUb2tlbik7XG5cdH1cblx0cmV0dXJuIHByZXZpb3VzVG9rZW47XG59XG52YXIgZ2V0TmV4dE5vbldzVG9rZW4gPSBmdW5jdGlvbih5YXNxZSwgbGluZU51bWJlciwgY2hhck51bWJlcikge1xuXHRpZiAoY2hhck51bWJlciA9PSB1bmRlZmluZWQpXG5cdFx0Y2hhck51bWJlciA9IDE7XG5cdHZhciB0b2tlbiA9IHlhc3FlLmdldFRva2VuQXQoe1xuXHRcdGxpbmU6IGxpbmVOdW1iZXIsXG5cdFx0Y2g6IGNoYXJOdW1iZXJcblx0fSk7XG5cdGlmICh0b2tlbiA9PSBudWxsIHx8IHRva2VuID09IHVuZGVmaW5lZCB8fCB0b2tlbi5lbmQgPCBjaGFyTnVtYmVyKSB7XG5cdFx0cmV0dXJuIG51bGw7XG5cdH1cblx0aWYgKHRva2VuLnR5cGUgPT0gXCJ3c1wiKSB7XG5cdFx0cmV0dXJuIGdldE5leHROb25Xc1Rva2VuKHlhc3FlLCBsaW5lTnVtYmVyLCB0b2tlbi5lbmQgKyAxKTtcblx0fVxuXHRyZXR1cm4gdG9rZW47XG59O1xuXG5tb2R1bGUuZXhwb3J0cyA9IHtcblx0Z2V0UHJldmlvdXNOb25Xc1Rva2VuOiBnZXRQcmV2aW91c05vbldzVG9rZW4sXG5cdGdldENvbXBsZXRlVG9rZW46IGdldENvbXBsZXRlVG9rZW4sXG5cdGdldE5leHROb25Xc1Rva2VuOiBnZXROZXh0Tm9uV3NUb2tlbixcbn07IiwiJ3VzZSBzdHJpY3QnO1xudmFyICQgPSByZXF1aXJlKCdqcXVlcnknKSxcblx0dXRpbHMgPSByZXF1aXJlKCcuL3V0aWxzLmpzJyk7XG5cbi8qKlxuICogV3JpdGUgb3VyIG93biB0b29sdGlwLCB0byBhdm9pZCBsb2FkaW5nIGFub3RoZXIgbGlicmFyeSBmb3IganVzdCB0aGlzIGZ1bmN0aW9uYWxpdHkuIEZvciBub3csIHdlIG9ubHkgdXNlIHRvb2x0aXAgZm9yIHNob3dpbmcgcGFyc2UgZXJyb3JzLCBzbyB0aGlzIGlzIHF1aXRlIGEgdGFpbG9yZWQgc29sdXRpb25cbiAqIFJlcXVpcmVtZW50czogXG4gKiBcdFx0cG9zaXRpb24gdG9vbHRpcCB3aXRoaW4gY29kZW1pcnJvciBmcmFtZSBhcyBtdWNoIGFzIHBvc3NpYmxlLCB0byBhdm9pZCB6LWluZGV4IGlzc3VlcyB3aXRoIGV4dGVybmFsIHRoaW5ncyBvbiBwYWdlXG4gKiBcdFx0dXNlIGh0bWwgYXMgY29udGVudFxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uKHlhc3FlLCBwYXJlbnQsIGh0bWwpIHtcblx0dmFyIHBhcmVudCA9ICQocGFyZW50KTtcblx0dmFyIHRvb2x0aXA7XG5cdHBhcmVudC5ob3ZlcihmdW5jdGlvbigpIHtcblx0XHRcdGlmICh0eXBlb2YgaHRtbCA9PSBcImZ1bmN0aW9uXCIpIGh0bWwgPSBodG1sKCk7XG5cdFx0XHR0b29sdGlwID0gJChcIjxkaXY+XCIpLmFkZENsYXNzKCd5YXNxZV90b29sdGlwJykuaHRtbChodG1sKS5hcHBlbmRUbyhwYXJlbnQpO1xuXHRcdFx0cmVwb3NpdGlvblRvb2x0aXAoKTtcblx0XHR9LFxuXHRcdGZ1bmN0aW9uKCkge1xuXHRcdFx0JChcIi55YXNxZV90b29sdGlwXCIpLnJlbW92ZSgpO1xuXHRcdH0pO1xuXG5cblxuXHQvKipcblx0ICogb25seSBuZWVkIHRvIHRha2UgaW50byBhY2NvdW50IHRvcCBhbmQgYm90dG9tIG9mZnNldCBmb3IgdGhpcyB1c2VjYXNlXG5cdCAqL1xuXHR2YXIgcmVwb3NpdGlvblRvb2x0aXAgPSBmdW5jdGlvbigpIHtcblx0XHRpZiAoJCh5YXNxZS5nZXRXcmFwcGVyRWxlbWVudCgpKS5vZmZzZXQoKS50b3AgPj0gdG9vbHRpcC5vZmZzZXQoKS50b3ApIHtcblx0XHRcdC8vc2hpdCwgbW92ZSB0aGUgdG9vbHRpcCBkb3duLiBUaGUgdG9vbHRpcCBub3cgaG92ZXJzIG92ZXIgdGhlIHRvcCBlZGdlIG9mIHRoZSB5YXNxZSBpbnN0YW5jZVxuXHRcdFx0dG9vbHRpcC5jc3MoJ2JvdHRvbScsICdhdXRvJyk7XG5cdFx0XHR0b29sdGlwLmNzcygndG9wJywgJzI2cHgnKTtcblx0XHR9XG5cdH07XG59OyIsIid1c2Ugc3RyaWN0JztcbnZhciAkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XG5cbnZhciBrZXlFeGlzdHMgPSBmdW5jdGlvbihvYmplY3RUb1Rlc3QsIGtleSkge1xuXHR2YXIgZXhpc3RzID0gZmFsc2U7XG5cdHRyeSB7XG5cdFx0aWYgKG9iamVjdFRvVGVzdFtrZXldICE9PSB1bmRlZmluZWQpXG5cdFx0XHRleGlzdHMgPSB0cnVlO1xuXHR9IGNhdGNoIChlKSB7fVxuXHRyZXR1cm4gZXhpc3RzO1xufTtcblxudmFyIGdldFBlcnNpc3RlbmN5SWQgPSBmdW5jdGlvbih5YXNxZSwgcGVyc2lzdGVudElkQ3JlYXRvcikge1xuXHR2YXIgcGVyc2lzdGVuY3lJZCA9IG51bGw7XG5cblx0aWYgKHBlcnNpc3RlbnRJZENyZWF0b3IpIHtcblx0XHRpZiAodHlwZW9mIHBlcnNpc3RlbnRJZENyZWF0b3IgPT0gXCJzdHJpbmdcIikge1xuXHRcdFx0cGVyc2lzdGVuY3lJZCA9IHBlcnNpc3RlbnRJZENyZWF0b3I7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHBlcnNpc3RlbmN5SWQgPSBwZXJzaXN0ZW50SWRDcmVhdG9yKHlhc3FlKTtcblx0XHR9XG5cdH1cblx0cmV0dXJuIHBlcnNpc3RlbmN5SWQ7XG59O1xuXG52YXIgZWxlbWVudHNPdmVybGFwID0gKGZ1bmN0aW9uKCkge1xuXHRmdW5jdGlvbiBnZXRQb3NpdGlvbnMoZWxlbSkge1xuXHRcdHZhciBwb3MsIHdpZHRoLCBoZWlnaHQ7XG5cdFx0cG9zID0gJChlbGVtKS5vZmZzZXQoKTtcblx0XHR3aWR0aCA9ICQoZWxlbSkud2lkdGgoKTtcblx0XHRoZWlnaHQgPSAkKGVsZW0pLmhlaWdodCgpO1xuXHRcdHJldHVybiBbXG5cdFx0XHRbcG9zLmxlZnQsIHBvcy5sZWZ0ICsgd2lkdGhdLFxuXHRcdFx0W3Bvcy50b3AsIHBvcy50b3AgKyBoZWlnaHRdXG5cdFx0XTtcblx0fVxuXG5cdGZ1bmN0aW9uIGNvbXBhcmVQb3NpdGlvbnMocDEsIHAyKSB7XG5cdFx0dmFyIHIxLCByMjtcblx0XHRyMSA9IHAxWzBdIDwgcDJbMF0gPyBwMSA6IHAyO1xuXHRcdHIyID0gcDFbMF0gPCBwMlswXSA/IHAyIDogcDE7XG5cdFx0cmV0dXJuIHIxWzFdID4gcjJbMF0gfHwgcjFbMF0gPT09IHIyWzBdO1xuXHR9XG5cblx0cmV0dXJuIGZ1bmN0aW9uKGEsIGIpIHtcblx0XHR2YXIgcG9zMSA9IGdldFBvc2l0aW9ucyhhKSxcblx0XHRcdHBvczIgPSBnZXRQb3NpdGlvbnMoYik7XG5cdFx0cmV0dXJuIGNvbXBhcmVQb3NpdGlvbnMocG9zMVswXSwgcG9zMlswXSkgJiYgY29tcGFyZVBvc2l0aW9ucyhwb3MxWzFdLCBwb3MyWzFdKTtcblx0fTtcbn0pKCk7XG5cbm1vZHVsZS5leHBvcnRzID0ge1xuXHRrZXlFeGlzdHM6IGtleUV4aXN0cyxcblx0Z2V0UGVyc2lzdGVuY3lJZDogZ2V0UGVyc2lzdGVuY3lJZCxcblx0ZWxlbWVudHNPdmVybGFwOiBlbGVtZW50c092ZXJsYXAsXG59OyJdfQ==\n","'use strict';\n/*\n jQuery deparam is an extraction of the deparam method from Ben Alman's jQuery BBQ\n http://benalman.com/projects/jquery-bbq-plugin/\n*/\nvar $ = require(\"jquery\");\n$.deparam = function (params, coerce) {\nvar obj = {},\n\tcoerce_types = { 'true': !0, 'false': !1, 'null': null };\n \n// Iterate over all name=value pairs.\n$.each(params.replace(/\\+/g, ' ').split('&'), function (j,v) {\n var param = v.split('='),\n\t key = decodeURIComponent(param[0]),\n\t val,\n\t cur = obj,\n\t i = 0,\n\t\t\n\t // If key is more complex than 'foo', like 'a[]' or 'a[b][c]', split it\n\t // into its component parts.\n\t keys = key.split(']['),\n\t keys_last = keys.length - 1;\n\t\n // If the first keys part contains [ and the last ends with ], then []\n // are correctly balanced.\n if (/\\[/.test(keys[0]) && /\\]$/.test(keys[keys_last])) {\n\t// Remove the trailing ] from the last keys part.\n\tkeys[keys_last] = keys[keys_last].replace(/\\]$/, '');\n\t \n\t// Split first keys part into two parts on the [ and add them back onto\n\t// the beginning of the keys array.\n\tkeys = keys.shift().split('[').concat(keys);\n\t \n\tkeys_last = keys.length - 1;\n } else {\n\t// Basic 'foo' style key.\n\tkeys_last = 0;\n }\n\t\n // Are we dealing with a name=value pair, or just a name?\n if (param.length === 2) {\n\tval = decodeURIComponent(param[1]);\n\t \n\t// Coerce values.\n\tif (coerce) {\n\t val = val && !isNaN(val) ? +val // number\n\t\t : val === 'undefined' ? undefined // undefined\n\t\t : coerce_types[val] !== undefined ? coerce_types[val] // true, false, null\n\t\t : val; // string\n\t}\n\t \n\tif ( keys_last ) {\n\t // Complex key, build deep object structure based on a few rules:\n\t // * The 'cur' pointer starts at the object top-level.\n\t // * [] = array push (n is set to array length), [n] = array if n is \n\t // numeric, otherwise object.\n\t // * If at the last keys part, set the value.\n\t // * For each keys part, if the current level is undefined create an\n\t // object or array based on the type of the next keys part.\n\t // * Move the 'cur' pointer to the next level.\n\t // * Rinse & repeat.\n\t for (; i <= keys_last; i++) {\n\t\tkey = keys[i] === '' ? cur.length : keys[i];\n\t\tcur = cur[key] = i < keys_last\n\t\t ? cur[key] || (keys[i+1] && isNaN(keys[i+1]) ? {} : [])\n\t\t : val;\n\t }\n\t\t\n\t} else {\n\t // Simple key, even simpler rules, since only scalars and shallow\n\t // arrays are allowed.\n\t\t\n\t if ($.isArray(obj[key])) {\n\t\t// val is already an array, so push on the next value.\n\t\tobj[key].push( val );\n\t\t \n\t } else if (obj[key] !== undefined) {\n\t\t// val isn't an array, but since a second value has been specified,\n\t\t// convert val into an array.\n\t\tobj[key] = [obj[key], val];\n\t\t \n\t } else {\n\t\t// val is a scalar.\n\t\tobj[key] = val;\n\t }\n\t}\n\t \n } else if (key) {\n\t// No value was defined, so set something meaningful.\n\tobj[key] = coerce\n\t ? undefined\n\t : '';\n }\n});\n \nreturn obj;\n};\n","module.exports = {table:\n{\n \"*[&&,valueLogical]\" : {\n \"&&\": [\"[&&,valueLogical]\",\"*[&&,valueLogical]\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \";\": []}, \n \"*[,,expression]\" : {\n \",\": [\"[,,expression]\",\"*[,,expression]\"], \n \")\": []}, \n \"*[,,objectPath]\" : {\n \",\": [\"[,,objectPath]\",\"*[,,objectPath]\"], \n \".\": [], \n \";\": [], \n \"]\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"*[,,object]\" : {\n \",\": [\"[,,object]\",\"*[,,object]\"], \n \".\": [], \n \";\": [], \n \"]\": [], \n \"}\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": []}, \n \"*[/,pathEltOrInverse]\" : {\n \"/\": [\"[/,pathEltOrInverse]\",\"*[/,pathEltOrInverse]\"], \n \"|\": [], \n \")\": [], \n \"(\": [], \n \"[\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"*[;,?[or([verbPath,verbSimple]),objectList]]\" : {\n \";\": [\"[;,?[or([verbPath,verbSimple]),objectList]]\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \".\": [], \n \"]\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"*[;,?[verb,objectList]]\" : {\n \";\": [\"[;,?[verb,objectList]]\",\"*[;,?[verb,objectList]]\"], \n \".\": [], \n \"]\": [], \n \"}\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": []}, \n \"*[UNION,groupGraphPattern]\" : {\n \"UNION\": [\"[UNION,groupGraphPattern]\",\"*[UNION,groupGraphPattern]\"], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"(\": [], \n \"[\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \".\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"*[graphPatternNotTriples,?.,?triplesBlock]\" : {\n \"{\": [\"[graphPatternNotTriples,?.,?triplesBlock]\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"OPTIONAL\": [\"[graphPatternNotTriples,?.,?triplesBlock]\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"MINUS\": [\"[graphPatternNotTriples,?.,?triplesBlock]\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"GRAPH\": [\"[graphPatternNotTriples,?.,?triplesBlock]\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"SERVICE\": [\"[graphPatternNotTriples,?.,?triplesBlock]\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"FILTER\": [\"[graphPatternNotTriples,?.,?triplesBlock]\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"BIND\": [\"[graphPatternNotTriples,?.,?triplesBlock]\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"VALUES\": [\"[graphPatternNotTriples,?.,?triplesBlock]\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"}\": []}, \n \"*[quadsNotTriples,?.,?triplesTemplate]\" : {\n \"GRAPH\": [\"[quadsNotTriples,?.,?triplesTemplate]\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"}\": []}, \n \"*[|,pathOneInPropertySet]\" : {\n \"|\": [\"[|,pathOneInPropertySet]\",\"*[|,pathOneInPropertySet]\"], \n \")\": []}, \n \"*[|,pathSequence]\" : {\n \"|\": [\"[|,pathSequence]\",\"*[|,pathSequence]\"], \n \")\": [], \n \"(\": [], \n \"[\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"*[||,conditionalAndExpression]\" : {\n \"||\": [\"[||,conditionalAndExpression]\",\"*[||,conditionalAndExpression]\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \";\": []}, \n \"*dataBlockValue\" : {\n \"UNDEF\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"IRI_REF\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"TRUE\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"FALSE\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"PNAME_LN\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"PNAME_NS\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"STRING_LITERAL1\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"STRING_LITERAL2\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"STRING_LITERAL_LONG1\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"STRING_LITERAL_LONG2\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"INTEGER\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"DECIMAL\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"DOUBLE\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"INTEGER_POSITIVE\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"DECIMAL_POSITIVE\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"DOUBLE_POSITIVE\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"INTEGER_NEGATIVE\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"DECIMAL_NEGATIVE\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"DOUBLE_NEGATIVE\": [\"dataBlockValue\",\"*dataBlockValue\"], \n \"}\": [], \n \")\": []}, \n \"*datasetClause\" : {\n \"FROM\": [\"datasetClause\",\"*datasetClause\"], \n \"WHERE\": [], \n \"{\": []}, \n \"*describeDatasetClause\" : {\n \"FROM\": [\"describeDatasetClause\",\"*describeDatasetClause\"], \n \"ORDER\": [], \n \"HAVING\": [], \n \"GROUP\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"WHERE\": [], \n \"{\": [], \n \"VALUES\": [], \n \"$\": []}, \n \"*graphNode\" : {\n \"(\": [\"graphNode\",\"*graphNode\"], \n \"[\": [\"graphNode\",\"*graphNode\"], \n \"VAR1\": [\"graphNode\",\"*graphNode\"], \n \"VAR2\": [\"graphNode\",\"*graphNode\"], \n \"NIL\": [\"graphNode\",\"*graphNode\"], \n \"IRI_REF\": [\"graphNode\",\"*graphNode\"], \n \"TRUE\": [\"graphNode\",\"*graphNode\"], \n \"FALSE\": [\"graphNode\",\"*graphNode\"], \n \"BLANK_NODE_LABEL\": [\"graphNode\",\"*graphNode\"], \n \"ANON\": [\"graphNode\",\"*graphNode\"], \n \"PNAME_LN\": [\"graphNode\",\"*graphNode\"], \n \"PNAME_NS\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL1\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL2\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL_LONG1\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL_LONG2\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER_NEGATIVE\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL_NEGATIVE\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE_NEGATIVE\": [\"graphNode\",\"*graphNode\"], \n \")\": []}, \n \"*graphNodePath\" : {\n \"(\": [\"graphNodePath\",\"*graphNodePath\"], \n \"[\": [\"graphNodePath\",\"*graphNodePath\"], \n \"VAR1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"VAR2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"NIL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"IRI_REF\": [\"graphNodePath\",\"*graphNodePath\"], \n \"TRUE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"FALSE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"BLANK_NODE_LABEL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"ANON\": [\"graphNodePath\",\"*graphNodePath\"], \n \"PNAME_LN\": [\"graphNodePath\",\"*graphNodePath\"], \n \"PNAME_NS\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL_LONG1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL_LONG2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \")\": []}, \n \"*groupCondition\" : {\n \"(\": [\"groupCondition\",\"*groupCondition\"], \n \"STR\": [\"groupCondition\",\"*groupCondition\"], \n \"LANG\": [\"groupCondition\",\"*groupCondition\"], \n \"LANGMATCHES\": [\"groupCondition\",\"*groupCondition\"], \n \"DATATYPE\": [\"groupCondition\",\"*groupCondition\"], \n \"BOUND\": [\"groupCondition\",\"*groupCondition\"], \n \"IRI\": [\"groupCondition\",\"*groupCondition\"], \n \"URI\": [\"groupCondition\",\"*groupCondition\"], \n \"BNODE\": [\"groupCondition\",\"*groupCondition\"], \n \"RAND\": [\"groupCondition\",\"*groupCondition\"], \n \"ABS\": [\"groupCondition\",\"*groupCondition\"], \n \"CEIL\": [\"groupCondition\",\"*groupCondition\"], \n \"FLOOR\": [\"groupCondition\",\"*groupCondition\"], \n \"ROUND\": [\"groupCondition\",\"*groupCondition\"], \n \"CONCAT\": [\"groupCondition\",\"*groupCondition\"], \n \"STRLEN\": [\"groupCondition\",\"*groupCondition\"], \n \"UCASE\": [\"groupCondition\",\"*groupCondition\"], \n \"LCASE\": [\"groupCondition\",\"*groupCondition\"], \n \"ENCODE_FOR_URI\": [\"groupCondition\",\"*groupCondition\"], \n \"CONTAINS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRSTARTS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRENDS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRBEFORE\": [\"groupCondition\",\"*groupCondition\"], \n \"STRAFTER\": [\"groupCondition\",\"*groupCondition\"], \n \"YEAR\": [\"groupCondition\",\"*groupCondition\"], \n \"MONTH\": [\"groupCondition\",\"*groupCondition\"], \n \"DAY\": [\"groupCondition\",\"*groupCondition\"], \n \"HOURS\": [\"groupCondition\",\"*groupCondition\"], \n \"MINUTES\": [\"groupCondition\",\"*groupCondition\"], \n \"SECONDS\": [\"groupCondition\",\"*groupCondition\"], \n \"TIMEZONE\": [\"groupCondition\",\"*groupCondition\"], \n \"TZ\": [\"groupCondition\",\"*groupCondition\"], \n \"NOW\": [\"groupCondition\",\"*groupCondition\"], \n \"UUID\": [\"groupCondition\",\"*groupCondition\"], \n \"STRUUID\": [\"groupCondition\",\"*groupCondition\"], \n \"MD5\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA1\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA256\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA384\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA512\": [\"groupCondition\",\"*groupCondition\"], \n \"COALESCE\": [\"groupCondition\",\"*groupCondition\"], \n \"IF\": [\"groupCondition\",\"*groupCondition\"], \n \"STRLANG\": [\"groupCondition\",\"*groupCondition\"], \n \"STRDT\": [\"groupCondition\",\"*groupCondition\"], \n \"SAMETERM\": [\"groupCondition\",\"*groupCondition\"], \n \"ISIRI\": [\"groupCondition\",\"*groupCondition\"], \n \"ISURI\": [\"groupCondition\",\"*groupCondition\"], \n \"ISBLANK\": [\"groupCondition\",\"*groupCondition\"], \n \"ISLITERAL\": [\"groupCondition\",\"*groupCondition\"], \n \"ISNUMERIC\": [\"groupCondition\",\"*groupCondition\"], \n \"VAR1\": [\"groupCondition\",\"*groupCondition\"], \n \"VAR2\": [\"groupCondition\",\"*groupCondition\"], \n \"SUBSTR\": [\"groupCondition\",\"*groupCondition\"], \n \"REPLACE\": [\"groupCondition\",\"*groupCondition\"], \n \"REGEX\": [\"groupCondition\",\"*groupCondition\"], \n \"EXISTS\": [\"groupCondition\",\"*groupCondition\"], \n \"NOT\": [\"groupCondition\",\"*groupCondition\"], \n \"IRI_REF\": [\"groupCondition\",\"*groupCondition\"], \n \"PNAME_LN\": [\"groupCondition\",\"*groupCondition\"], \n \"PNAME_NS\": [\"groupCondition\",\"*groupCondition\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"ORDER\": [], \n \"HAVING\": [], \n \"$\": [], \n \"}\": []}, \n \"*havingCondition\" : {\n \"(\": [\"havingCondition\",\"*havingCondition\"], \n \"STR\": [\"havingCondition\",\"*havingCondition\"], \n \"LANG\": [\"havingCondition\",\"*havingCondition\"], \n \"LANGMATCHES\": [\"havingCondition\",\"*havingCondition\"], \n \"DATATYPE\": [\"havingCondition\",\"*havingCondition\"], \n \"BOUND\": [\"havingCondition\",\"*havingCondition\"], \n \"IRI\": [\"havingCondition\",\"*havingCondition\"], \n \"URI\": [\"havingCondition\",\"*havingCondition\"], \n \"BNODE\": [\"havingCondition\",\"*havingCondition\"], \n \"RAND\": [\"havingCondition\",\"*havingCondition\"], \n \"ABS\": [\"havingCondition\",\"*havingCondition\"], \n \"CEIL\": [\"havingCondition\",\"*havingCondition\"], \n \"FLOOR\": [\"havingCondition\",\"*havingCondition\"], \n \"ROUND\": [\"havingCondition\",\"*havingCondition\"], \n \"CONCAT\": [\"havingCondition\",\"*havingCondition\"], \n \"STRLEN\": [\"havingCondition\",\"*havingCondition\"], \n \"UCASE\": [\"havingCondition\",\"*havingCondition\"], \n \"LCASE\": [\"havingCondition\",\"*havingCondition\"], \n \"ENCODE_FOR_URI\": [\"havingCondition\",\"*havingCondition\"], \n \"CONTAINS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRSTARTS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRENDS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRBEFORE\": [\"havingCondition\",\"*havingCondition\"], \n \"STRAFTER\": [\"havingCondition\",\"*havingCondition\"], \n \"YEAR\": [\"havingCondition\",\"*havingCondition\"], \n \"MONTH\": [\"havingCondition\",\"*havingCondition\"], \n \"DAY\": [\"havingCondition\",\"*havingCondition\"], \n \"HOURS\": [\"havingCondition\",\"*havingCondition\"], \n \"MINUTES\": [\"havingCondition\",\"*havingCondition\"], \n \"SECONDS\": [\"havingCondition\",\"*havingCondition\"], \n \"TIMEZONE\": [\"havingCondition\",\"*havingCondition\"], \n \"TZ\": [\"havingCondition\",\"*havingCondition\"], \n \"NOW\": [\"havingCondition\",\"*havingCondition\"], \n \"UUID\": [\"havingCondition\",\"*havingCondition\"], \n \"STRUUID\": [\"havingCondition\",\"*havingCondition\"], \n \"MD5\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA1\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA256\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA384\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA512\": [\"havingCondition\",\"*havingCondition\"], \n \"COALESCE\": [\"havingCondition\",\"*havingCondition\"], \n \"IF\": [\"havingCondition\",\"*havingCondition\"], \n \"STRLANG\": [\"havingCondition\",\"*havingCondition\"], \n \"STRDT\": [\"havingCondition\",\"*havingCondition\"], \n \"SAMETERM\": [\"havingCondition\",\"*havingCondition\"], \n \"ISIRI\": [\"havingCondition\",\"*havingCondition\"], \n \"ISURI\": [\"havingCondition\",\"*havingCondition\"], \n \"ISBLANK\": [\"havingCondition\",\"*havingCondition\"], \n \"ISLITERAL\": [\"havingCondition\",\"*havingCondition\"], \n \"ISNUMERIC\": [\"havingCondition\",\"*havingCondition\"], \n \"SUBSTR\": [\"havingCondition\",\"*havingCondition\"], \n \"REPLACE\": [\"havingCondition\",\"*havingCondition\"], \n \"REGEX\": [\"havingCondition\",\"*havingCondition\"], \n \"EXISTS\": [\"havingCondition\",\"*havingCondition\"], \n \"NOT\": [\"havingCondition\",\"*havingCondition\"], \n \"IRI_REF\": [\"havingCondition\",\"*havingCondition\"], \n \"PNAME_LN\": [\"havingCondition\",\"*havingCondition\"], \n \"PNAME_NS\": [\"havingCondition\",\"*havingCondition\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"ORDER\": [], \n \"$\": [], \n \"}\": []}, \n \"*or([[ (,*dataBlockValue,)],NIL])\" : {\n \"(\": [\"or([[ (,*dataBlockValue,)],NIL])\",\"*or([[ (,*dataBlockValue,)],NIL])\"], \n \"NIL\": [\"or([[ (,*dataBlockValue,)],NIL])\",\"*or([[ (,*dataBlockValue,)],NIL])\"], \n \"}\": []}, \n \"*or([[*,unaryExpression],[/,unaryExpression]])\" : {\n \"*\": [\"or([[*,unaryExpression],[/,unaryExpression]])\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"/\": [\"or([[*,unaryExpression],[/,unaryExpression]])\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \"+\": [], \n \"-\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \";\": []}, \n \"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\" : {\n \"+\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"-\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_POSITIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_POSITIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_POSITIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_NEGATIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_NEGATIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_NEGATIVE\": [\"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \";\": []}, \n \"*or([baseDecl,prefixDecl])\" : {\n \"BASE\": [\"or([baseDecl,prefixDecl])\",\"*or([baseDecl,prefixDecl])\"], \n \"PREFIX\": [\"or([baseDecl,prefixDecl])\",\"*or([baseDecl,prefixDecl])\"], \n \"$\": [], \n \"CONSTRUCT\": [], \n \"DESCRIBE\": [], \n \"ASK\": [], \n \"INSERT\": [], \n \"DELETE\": [], \n \"SELECT\": [], \n \"LOAD\": [], \n \"CLEAR\": [], \n \"DROP\": [], \n \"ADD\": [], \n \"MOVE\": [], \n \"COPY\": [], \n \"CREATE\": [], \n \"WITH\": []}, \n \"*or([var,[ (,expression,AS,var,)]])\" : {\n \"(\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR1\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR2\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"WHERE\": [], \n \"{\": [], \n \"FROM\": []}, \n \"*orderCondition\" : {\n \"ASC\": [\"orderCondition\",\"*orderCondition\"], \n \"DESC\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR1\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR2\": [\"orderCondition\",\"*orderCondition\"], \n \"(\": [\"orderCondition\",\"*orderCondition\"], \n \"STR\": [\"orderCondition\",\"*orderCondition\"], \n \"LANG\": [\"orderCondition\",\"*orderCondition\"], \n \"LANGMATCHES\": [\"orderCondition\",\"*orderCondition\"], \n \"DATATYPE\": [\"orderCondition\",\"*orderCondition\"], \n \"BOUND\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI\": [\"orderCondition\",\"*orderCondition\"], \n \"URI\": [\"orderCondition\",\"*orderCondition\"], \n \"BNODE\": [\"orderCondition\",\"*orderCondition\"], \n \"RAND\": [\"orderCondition\",\"*orderCondition\"], \n \"ABS\": [\"orderCondition\",\"*orderCondition\"], \n \"CEIL\": [\"orderCondition\",\"*orderCondition\"], \n \"FLOOR\": [\"orderCondition\",\"*orderCondition\"], \n \"ROUND\": [\"orderCondition\",\"*orderCondition\"], \n \"CONCAT\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLEN\": [\"orderCondition\",\"*orderCondition\"], \n \"UCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"LCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"ENCODE_FOR_URI\": [\"orderCondition\",\"*orderCondition\"], \n \"CONTAINS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRSTARTS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRENDS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRBEFORE\": [\"orderCondition\",\"*orderCondition\"], \n \"STRAFTER\": [\"orderCondition\",\"*orderCondition\"], \n \"YEAR\": [\"orderCondition\",\"*orderCondition\"], \n \"MONTH\": [\"orderCondition\",\"*orderCondition\"], \n \"DAY\": [\"orderCondition\",\"*orderCondition\"], \n \"HOURS\": [\"orderCondition\",\"*orderCondition\"], \n \"MINUTES\": [\"orderCondition\",\"*orderCondition\"], \n \"SECONDS\": [\"orderCondition\",\"*orderCondition\"], \n \"TIMEZONE\": [\"orderCondition\",\"*orderCondition\"], \n \"TZ\": [\"orderCondition\",\"*orderCondition\"], \n \"NOW\": [\"orderCondition\",\"*orderCondition\"], \n \"UUID\": [\"orderCondition\",\"*orderCondition\"], \n \"STRUUID\": [\"orderCondition\",\"*orderCondition\"], \n \"MD5\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA1\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA256\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA384\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA512\": [\"orderCondition\",\"*orderCondition\"], \n \"COALESCE\": [\"orderCondition\",\"*orderCondition\"], \n \"IF\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLANG\": [\"orderCondition\",\"*orderCondition\"], \n \"STRDT\": [\"orderCondition\",\"*orderCondition\"], \n \"SAMETERM\": [\"orderCondition\",\"*orderCondition\"], \n \"ISIRI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISURI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISBLANK\": [\"orderCondition\",\"*orderCondition\"], \n \"ISLITERAL\": [\"orderCondition\",\"*orderCondition\"], \n \"ISNUMERIC\": [\"orderCondition\",\"*orderCondition\"], \n \"SUBSTR\": [\"orderCondition\",\"*orderCondition\"], \n \"REPLACE\": [\"orderCondition\",\"*orderCondition\"], \n \"REGEX\": [\"orderCondition\",\"*orderCondition\"], \n \"EXISTS\": [\"orderCondition\",\"*orderCondition\"], \n \"NOT\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI_REF\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_LN\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_NS\": [\"orderCondition\",\"*orderCondition\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"$\": [], \n \"}\": []}, \n \"*usingClause\" : {\n \"USING\": [\"usingClause\",\"*usingClause\"], \n \"WHERE\": []}, \n \"*var\" : {\n \"VAR1\": [\"var\",\"*var\"], \n \"VAR2\": [\"var\",\"*var\"], \n \")\": []}, \n \"*varOrIRIref\" : {\n \"VAR1\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"VAR2\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"IRI_REF\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_LN\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_NS\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"ORDER\": [], \n \"HAVING\": [], \n \"GROUP\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"WHERE\": [], \n \"{\": [], \n \"FROM\": [], \n \"VALUES\": [], \n \"$\": []}, \n \"+graphNode\" : {\n \"(\": [\"graphNode\",\"*graphNode\"], \n \"[\": [\"graphNode\",\"*graphNode\"], \n \"VAR1\": [\"graphNode\",\"*graphNode\"], \n \"VAR2\": [\"graphNode\",\"*graphNode\"], \n \"NIL\": [\"graphNode\",\"*graphNode\"], \n \"IRI_REF\": [\"graphNode\",\"*graphNode\"], \n \"TRUE\": [\"graphNode\",\"*graphNode\"], \n \"FALSE\": [\"graphNode\",\"*graphNode\"], \n \"BLANK_NODE_LABEL\": [\"graphNode\",\"*graphNode\"], \n \"ANON\": [\"graphNode\",\"*graphNode\"], \n \"PNAME_LN\": [\"graphNode\",\"*graphNode\"], \n \"PNAME_NS\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL1\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL2\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL_LONG1\": [\"graphNode\",\"*graphNode\"], \n \"STRING_LITERAL_LONG2\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE_POSITIVE\": [\"graphNode\",\"*graphNode\"], \n \"INTEGER_NEGATIVE\": [\"graphNode\",\"*graphNode\"], \n \"DECIMAL_NEGATIVE\": [\"graphNode\",\"*graphNode\"], \n \"DOUBLE_NEGATIVE\": [\"graphNode\",\"*graphNode\"]}, \n \"+graphNodePath\" : {\n \"(\": [\"graphNodePath\",\"*graphNodePath\"], \n \"[\": [\"graphNodePath\",\"*graphNodePath\"], \n \"VAR1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"VAR2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"NIL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"IRI_REF\": [\"graphNodePath\",\"*graphNodePath\"], \n \"TRUE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"FALSE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"BLANK_NODE_LABEL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"ANON\": [\"graphNodePath\",\"*graphNodePath\"], \n \"PNAME_LN\": [\"graphNodePath\",\"*graphNodePath\"], \n \"PNAME_NS\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL_LONG1\": [\"graphNodePath\",\"*graphNodePath\"], \n \"STRING_LITERAL_LONG2\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE_POSITIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"INTEGER_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DECIMAL_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"], \n \"DOUBLE_NEGATIVE\": [\"graphNodePath\",\"*graphNodePath\"]}, \n \"+groupCondition\" : {\n \"(\": [\"groupCondition\",\"*groupCondition\"], \n \"STR\": [\"groupCondition\",\"*groupCondition\"], \n \"LANG\": [\"groupCondition\",\"*groupCondition\"], \n \"LANGMATCHES\": [\"groupCondition\",\"*groupCondition\"], \n \"DATATYPE\": [\"groupCondition\",\"*groupCondition\"], \n \"BOUND\": [\"groupCondition\",\"*groupCondition\"], \n \"IRI\": [\"groupCondition\",\"*groupCondition\"], \n \"URI\": [\"groupCondition\",\"*groupCondition\"], \n \"BNODE\": [\"groupCondition\",\"*groupCondition\"], \n \"RAND\": [\"groupCondition\",\"*groupCondition\"], \n \"ABS\": [\"groupCondition\",\"*groupCondition\"], \n \"CEIL\": [\"groupCondition\",\"*groupCondition\"], \n \"FLOOR\": [\"groupCondition\",\"*groupCondition\"], \n \"ROUND\": [\"groupCondition\",\"*groupCondition\"], \n \"CONCAT\": [\"groupCondition\",\"*groupCondition\"], \n \"STRLEN\": [\"groupCondition\",\"*groupCondition\"], \n \"UCASE\": [\"groupCondition\",\"*groupCondition\"], \n \"LCASE\": [\"groupCondition\",\"*groupCondition\"], \n \"ENCODE_FOR_URI\": [\"groupCondition\",\"*groupCondition\"], \n \"CONTAINS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRSTARTS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRENDS\": [\"groupCondition\",\"*groupCondition\"], \n \"STRBEFORE\": [\"groupCondition\",\"*groupCondition\"], \n \"STRAFTER\": [\"groupCondition\",\"*groupCondition\"], \n \"YEAR\": [\"groupCondition\",\"*groupCondition\"], \n \"MONTH\": [\"groupCondition\",\"*groupCondition\"], \n \"DAY\": [\"groupCondition\",\"*groupCondition\"], \n \"HOURS\": [\"groupCondition\",\"*groupCondition\"], \n \"MINUTES\": [\"groupCondition\",\"*groupCondition\"], \n \"SECONDS\": [\"groupCondition\",\"*groupCondition\"], \n \"TIMEZONE\": [\"groupCondition\",\"*groupCondition\"], \n \"TZ\": [\"groupCondition\",\"*groupCondition\"], \n \"NOW\": [\"groupCondition\",\"*groupCondition\"], \n \"UUID\": [\"groupCondition\",\"*groupCondition\"], \n \"STRUUID\": [\"groupCondition\",\"*groupCondition\"], \n \"MD5\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA1\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA256\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA384\": [\"groupCondition\",\"*groupCondition\"], \n \"SHA512\": [\"groupCondition\",\"*groupCondition\"], \n \"COALESCE\": [\"groupCondition\",\"*groupCondition\"], \n \"IF\": [\"groupCondition\",\"*groupCondition\"], \n \"STRLANG\": [\"groupCondition\",\"*groupCondition\"], \n \"STRDT\": [\"groupCondition\",\"*groupCondition\"], \n \"SAMETERM\": [\"groupCondition\",\"*groupCondition\"], \n \"ISIRI\": [\"groupCondition\",\"*groupCondition\"], \n \"ISURI\": [\"groupCondition\",\"*groupCondition\"], \n \"ISBLANK\": [\"groupCondition\",\"*groupCondition\"], \n \"ISLITERAL\": [\"groupCondition\",\"*groupCondition\"], \n \"ISNUMERIC\": [\"groupCondition\",\"*groupCondition\"], \n \"VAR1\": [\"groupCondition\",\"*groupCondition\"], \n \"VAR2\": [\"groupCondition\",\"*groupCondition\"], \n \"SUBSTR\": [\"groupCondition\",\"*groupCondition\"], \n \"REPLACE\": [\"groupCondition\",\"*groupCondition\"], \n \"REGEX\": [\"groupCondition\",\"*groupCondition\"], \n \"EXISTS\": [\"groupCondition\",\"*groupCondition\"], \n \"NOT\": [\"groupCondition\",\"*groupCondition\"], \n \"IRI_REF\": [\"groupCondition\",\"*groupCondition\"], \n \"PNAME_LN\": [\"groupCondition\",\"*groupCondition\"], \n \"PNAME_NS\": [\"groupCondition\",\"*groupCondition\"]}, \n \"+havingCondition\" : {\n \"(\": [\"havingCondition\",\"*havingCondition\"], \n \"STR\": [\"havingCondition\",\"*havingCondition\"], \n \"LANG\": [\"havingCondition\",\"*havingCondition\"], \n \"LANGMATCHES\": [\"havingCondition\",\"*havingCondition\"], \n \"DATATYPE\": [\"havingCondition\",\"*havingCondition\"], \n \"BOUND\": [\"havingCondition\",\"*havingCondition\"], \n \"IRI\": [\"havingCondition\",\"*havingCondition\"], \n \"URI\": [\"havingCondition\",\"*havingCondition\"], \n \"BNODE\": [\"havingCondition\",\"*havingCondition\"], \n \"RAND\": [\"havingCondition\",\"*havingCondition\"], \n \"ABS\": [\"havingCondition\",\"*havingCondition\"], \n \"CEIL\": [\"havingCondition\",\"*havingCondition\"], \n \"FLOOR\": [\"havingCondition\",\"*havingCondition\"], \n \"ROUND\": [\"havingCondition\",\"*havingCondition\"], \n \"CONCAT\": [\"havingCondition\",\"*havingCondition\"], \n \"STRLEN\": [\"havingCondition\",\"*havingCondition\"], \n \"UCASE\": [\"havingCondition\",\"*havingCondition\"], \n \"LCASE\": [\"havingCondition\",\"*havingCondition\"], \n \"ENCODE_FOR_URI\": [\"havingCondition\",\"*havingCondition\"], \n \"CONTAINS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRSTARTS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRENDS\": [\"havingCondition\",\"*havingCondition\"], \n \"STRBEFORE\": [\"havingCondition\",\"*havingCondition\"], \n \"STRAFTER\": [\"havingCondition\",\"*havingCondition\"], \n \"YEAR\": [\"havingCondition\",\"*havingCondition\"], \n \"MONTH\": [\"havingCondition\",\"*havingCondition\"], \n \"DAY\": [\"havingCondition\",\"*havingCondition\"], \n \"HOURS\": [\"havingCondition\",\"*havingCondition\"], \n \"MINUTES\": [\"havingCondition\",\"*havingCondition\"], \n \"SECONDS\": [\"havingCondition\",\"*havingCondition\"], \n \"TIMEZONE\": [\"havingCondition\",\"*havingCondition\"], \n \"TZ\": [\"havingCondition\",\"*havingCondition\"], \n \"NOW\": [\"havingCondition\",\"*havingCondition\"], \n \"UUID\": [\"havingCondition\",\"*havingCondition\"], \n \"STRUUID\": [\"havingCondition\",\"*havingCondition\"], \n \"MD5\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA1\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA256\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA384\": [\"havingCondition\",\"*havingCondition\"], \n \"SHA512\": [\"havingCondition\",\"*havingCondition\"], \n \"COALESCE\": [\"havingCondition\",\"*havingCondition\"], \n \"IF\": [\"havingCondition\",\"*havingCondition\"], \n \"STRLANG\": [\"havingCondition\",\"*havingCondition\"], \n \"STRDT\": [\"havingCondition\",\"*havingCondition\"], \n \"SAMETERM\": [\"havingCondition\",\"*havingCondition\"], \n \"ISIRI\": [\"havingCondition\",\"*havingCondition\"], \n \"ISURI\": [\"havingCondition\",\"*havingCondition\"], \n \"ISBLANK\": [\"havingCondition\",\"*havingCondition\"], \n \"ISLITERAL\": [\"havingCondition\",\"*havingCondition\"], \n \"ISNUMERIC\": [\"havingCondition\",\"*havingCondition\"], \n \"SUBSTR\": [\"havingCondition\",\"*havingCondition\"], \n \"REPLACE\": [\"havingCondition\",\"*havingCondition\"], \n \"REGEX\": [\"havingCondition\",\"*havingCondition\"], \n \"EXISTS\": [\"havingCondition\",\"*havingCondition\"], \n \"NOT\": [\"havingCondition\",\"*havingCondition\"], \n \"IRI_REF\": [\"havingCondition\",\"*havingCondition\"], \n \"PNAME_LN\": [\"havingCondition\",\"*havingCondition\"], \n \"PNAME_NS\": [\"havingCondition\",\"*havingCondition\"]}, \n \"+or([var,[ (,expression,AS,var,)]])\" : {\n \"(\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR1\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"], \n \"VAR2\": [\"or([var,[ (,expression,AS,var,)]])\",\"*or([var,[ (,expression,AS,var,)]])\"]}, \n \"+orderCondition\" : {\n \"ASC\": [\"orderCondition\",\"*orderCondition\"], \n \"DESC\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR1\": [\"orderCondition\",\"*orderCondition\"], \n \"VAR2\": [\"orderCondition\",\"*orderCondition\"], \n \"(\": [\"orderCondition\",\"*orderCondition\"], \n \"STR\": [\"orderCondition\",\"*orderCondition\"], \n \"LANG\": [\"orderCondition\",\"*orderCondition\"], \n \"LANGMATCHES\": [\"orderCondition\",\"*orderCondition\"], \n \"DATATYPE\": [\"orderCondition\",\"*orderCondition\"], \n \"BOUND\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI\": [\"orderCondition\",\"*orderCondition\"], \n \"URI\": [\"orderCondition\",\"*orderCondition\"], \n \"BNODE\": [\"orderCondition\",\"*orderCondition\"], \n \"RAND\": [\"orderCondition\",\"*orderCondition\"], \n \"ABS\": [\"orderCondition\",\"*orderCondition\"], \n \"CEIL\": [\"orderCondition\",\"*orderCondition\"], \n \"FLOOR\": [\"orderCondition\",\"*orderCondition\"], \n \"ROUND\": [\"orderCondition\",\"*orderCondition\"], \n \"CONCAT\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLEN\": [\"orderCondition\",\"*orderCondition\"], \n \"UCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"LCASE\": [\"orderCondition\",\"*orderCondition\"], \n \"ENCODE_FOR_URI\": [\"orderCondition\",\"*orderCondition\"], \n \"CONTAINS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRSTARTS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRENDS\": [\"orderCondition\",\"*orderCondition\"], \n \"STRBEFORE\": [\"orderCondition\",\"*orderCondition\"], \n \"STRAFTER\": [\"orderCondition\",\"*orderCondition\"], \n \"YEAR\": [\"orderCondition\",\"*orderCondition\"], \n \"MONTH\": [\"orderCondition\",\"*orderCondition\"], \n \"DAY\": [\"orderCondition\",\"*orderCondition\"], \n \"HOURS\": [\"orderCondition\",\"*orderCondition\"], \n \"MINUTES\": [\"orderCondition\",\"*orderCondition\"], \n \"SECONDS\": [\"orderCondition\",\"*orderCondition\"], \n \"TIMEZONE\": [\"orderCondition\",\"*orderCondition\"], \n \"TZ\": [\"orderCondition\",\"*orderCondition\"], \n \"NOW\": [\"orderCondition\",\"*orderCondition\"], \n \"UUID\": [\"orderCondition\",\"*orderCondition\"], \n \"STRUUID\": [\"orderCondition\",\"*orderCondition\"], \n \"MD5\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA1\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA256\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA384\": [\"orderCondition\",\"*orderCondition\"], \n \"SHA512\": [\"orderCondition\",\"*orderCondition\"], \n \"COALESCE\": [\"orderCondition\",\"*orderCondition\"], \n \"IF\": [\"orderCondition\",\"*orderCondition\"], \n \"STRLANG\": [\"orderCondition\",\"*orderCondition\"], \n \"STRDT\": [\"orderCondition\",\"*orderCondition\"], \n \"SAMETERM\": [\"orderCondition\",\"*orderCondition\"], \n \"ISIRI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISURI\": [\"orderCondition\",\"*orderCondition\"], \n \"ISBLANK\": [\"orderCondition\",\"*orderCondition\"], \n \"ISLITERAL\": [\"orderCondition\",\"*orderCondition\"], \n \"ISNUMERIC\": [\"orderCondition\",\"*orderCondition\"], \n \"SUBSTR\": [\"orderCondition\",\"*orderCondition\"], \n \"REPLACE\": [\"orderCondition\",\"*orderCondition\"], \n \"REGEX\": [\"orderCondition\",\"*orderCondition\"], \n \"EXISTS\": [\"orderCondition\",\"*orderCondition\"], \n \"NOT\": [\"orderCondition\",\"*orderCondition\"], \n \"IRI_REF\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_LN\": [\"orderCondition\",\"*orderCondition\"], \n \"PNAME_NS\": [\"orderCondition\",\"*orderCondition\"]}, \n \"+varOrIRIref\" : {\n \"VAR1\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"VAR2\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"IRI_REF\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_LN\": [\"varOrIRIref\",\"*varOrIRIref\"], \n \"PNAME_NS\": [\"varOrIRIref\",\"*varOrIRIref\"]}, \n \"?.\" : {\n \".\": [\".\"], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"(\": [], \n \"[\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?DISTINCT\" : {\n \"DISTINCT\": [\"DISTINCT\"], \n \"!\": [], \n \"+\": [], \n \"-\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"(\": [], \n \"STR\": [], \n \"LANG\": [], \n \"LANGMATCHES\": [], \n \"DATATYPE\": [], \n \"BOUND\": [], \n \"IRI\": [], \n \"URI\": [], \n \"BNODE\": [], \n \"RAND\": [], \n \"ABS\": [], \n \"CEIL\": [], \n \"FLOOR\": [], \n \"ROUND\": [], \n \"CONCAT\": [], \n \"STRLEN\": [], \n \"UCASE\": [], \n \"LCASE\": [], \n \"ENCODE_FOR_URI\": [], \n \"CONTAINS\": [], \n \"STRSTARTS\": [], \n \"STRENDS\": [], \n \"STRBEFORE\": [], \n \"STRAFTER\": [], \n \"YEAR\": [], \n \"MONTH\": [], \n \"DAY\": [], \n \"HOURS\": [], \n \"MINUTES\": [], \n \"SECONDS\": [], \n \"TIMEZONE\": [], \n \"TZ\": [], \n \"NOW\": [], \n \"UUID\": [], \n \"STRUUID\": [], \n \"MD5\": [], \n \"SHA1\": [], \n \"SHA256\": [], \n \"SHA384\": [], \n \"SHA512\": [], \n \"COALESCE\": [], \n \"IF\": [], \n \"STRLANG\": [], \n \"STRDT\": [], \n \"SAMETERM\": [], \n \"ISIRI\": [], \n \"ISURI\": [], \n \"ISBLANK\": [], \n \"ISLITERAL\": [], \n \"ISNUMERIC\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"COUNT\": [], \n \"SUM\": [], \n \"MIN\": [], \n \"MAX\": [], \n \"AVG\": [], \n \"SAMPLE\": [], \n \"GROUP_CONCAT\": [], \n \"SUBSTR\": [], \n \"REPLACE\": [], \n \"REGEX\": [], \n \"EXISTS\": [], \n \"NOT\": [], \n \"IRI_REF\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"*\": []}, \n \"?GRAPH\" : {\n \"GRAPH\": [\"GRAPH\"], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?SILENT\" : {\n \"SILENT\": [\"SILENT\"], \n \"VAR1\": [], \n \"VAR2\": [], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?SILENT_1\" : {\n \"SILENT\": [\"SILENT\"], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?SILENT_2\" : {\n \"SILENT\": [\"SILENT\"], \n \"GRAPH\": [], \n \"DEFAULT\": [], \n \"NAMED\": [], \n \"ALL\": []}, \n \"?SILENT_3\" : {\n \"SILENT\": [\"SILENT\"], \n \"GRAPH\": []}, \n \"?SILENT_4\" : {\n \"SILENT\": [\"SILENT\"], \n \"DEFAULT\": [], \n \"GRAPH\": [], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": []}, \n \"?WHERE\" : {\n \"WHERE\": [\"WHERE\"], \n \"{\": []}, \n \"?[,,expression]\" : {\n \",\": [\"[,,expression]\"], \n \")\": []}, \n \"?[.,?constructTriples]\" : {\n \".\": [\"[.,?constructTriples]\"], \n \"}\": []}, \n \"?[.,?triplesBlock]\" : {\n \".\": [\"[.,?triplesBlock]\"], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?[.,?triplesTemplate]\" : {\n \".\": [\"[.,?triplesTemplate]\"], \n \"}\": [], \n \"GRAPH\": []}, \n \"?[;,SEPARATOR,=,string]\" : {\n \";\": [\"[;,SEPARATOR,=,string]\"], \n \")\": []}, \n \"?[;,update]\" : {\n \";\": [\"[;,update]\"], \n \"$\": []}, \n \"?[AS,var]\" : {\n \"AS\": [\"[AS,var]\"], \n \")\": []}, \n \"?[INTO,graphRef]\" : {\n \"INTO\": [\"[INTO,graphRef]\"], \n \";\": [], \n \"$\": []}, \n \"?[or([verbPath,verbSimple]),objectList]\" : {\n \"VAR1\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"VAR2\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"^\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"a\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"!\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"(\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"IRI_REF\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"PNAME_LN\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \"PNAME_NS\": [\"[or([verbPath,verbSimple]),objectList]\"], \n \";\": [], \n \".\": [], \n \"]\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?[pathOneInPropertySet,*[|,pathOneInPropertySet]]\" : {\n \"a\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"^\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"IRI_REF\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"PNAME_LN\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \"PNAME_NS\": [\"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\"], \n \")\": []}, \n \"?[update1,?[;,update]]\" : {\n \"INSERT\": [\"[update1,?[;,update]]\"], \n \"DELETE\": [\"[update1,?[;,update]]\"], \n \"LOAD\": [\"[update1,?[;,update]]\"], \n \"CLEAR\": [\"[update1,?[;,update]]\"], \n \"DROP\": [\"[update1,?[;,update]]\"], \n \"ADD\": [\"[update1,?[;,update]]\"], \n \"MOVE\": [\"[update1,?[;,update]]\"], \n \"COPY\": [\"[update1,?[;,update]]\"], \n \"CREATE\": [\"[update1,?[;,update]]\"], \n \"WITH\": [\"[update1,?[;,update]]\"], \n \"$\": []}, \n \"?[verb,objectList]\" : {\n \"a\": [\"[verb,objectList]\"], \n \"VAR1\": [\"[verb,objectList]\"], \n \"VAR2\": [\"[verb,objectList]\"], \n \"IRI_REF\": [\"[verb,objectList]\"], \n \"PNAME_LN\": [\"[verb,objectList]\"], \n \"PNAME_NS\": [\"[verb,objectList]\"], \n \";\": [], \n \".\": [], \n \"]\": [], \n \"}\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": []}, \n \"?argList\" : {\n \"NIL\": [\"argList\"], \n \"(\": [\"argList\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \"+\": [], \n \"-\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"*\": [], \n \"/\": [], \n \";\": []}, \n \"?constructTriples\" : {\n \"VAR1\": [\"constructTriples\"], \n \"VAR2\": [\"constructTriples\"], \n \"NIL\": [\"constructTriples\"], \n \"(\": [\"constructTriples\"], \n \"[\": [\"constructTriples\"], \n \"IRI_REF\": [\"constructTriples\"], \n \"TRUE\": [\"constructTriples\"], \n \"FALSE\": [\"constructTriples\"], \n \"BLANK_NODE_LABEL\": [\"constructTriples\"], \n \"ANON\": [\"constructTriples\"], \n \"PNAME_LN\": [\"constructTriples\"], \n \"PNAME_NS\": [\"constructTriples\"], \n \"STRING_LITERAL1\": [\"constructTriples\"], \n \"STRING_LITERAL2\": [\"constructTriples\"], \n \"STRING_LITERAL_LONG1\": [\"constructTriples\"], \n \"STRING_LITERAL_LONG2\": [\"constructTriples\"], \n \"INTEGER\": [\"constructTriples\"], \n \"DECIMAL\": [\"constructTriples\"], \n \"DOUBLE\": [\"constructTriples\"], \n \"INTEGER_POSITIVE\": [\"constructTriples\"], \n \"DECIMAL_POSITIVE\": [\"constructTriples\"], \n \"DOUBLE_POSITIVE\": [\"constructTriples\"], \n \"INTEGER_NEGATIVE\": [\"constructTriples\"], \n \"DECIMAL_NEGATIVE\": [\"constructTriples\"], \n \"DOUBLE_NEGATIVE\": [\"constructTriples\"], \n \"}\": []}, \n \"?groupClause\" : {\n \"GROUP\": [\"groupClause\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"ORDER\": [], \n \"HAVING\": [], \n \"$\": [], \n \"}\": []}, \n \"?havingClause\" : {\n \"HAVING\": [\"havingClause\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"ORDER\": [], \n \"$\": [], \n \"}\": []}, \n \"?insertClause\" : {\n \"INSERT\": [\"insertClause\"], \n \"WHERE\": [], \n \"USING\": []}, \n \"?limitClause\" : {\n \"LIMIT\": [\"limitClause\"], \n \"VALUES\": [], \n \"$\": [], \n \"}\": []}, \n \"?limitOffsetClauses\" : {\n \"LIMIT\": [\"limitOffsetClauses\"], \n \"OFFSET\": [\"limitOffsetClauses\"], \n \"VALUES\": [], \n \"$\": [], \n \"}\": []}, \n \"?offsetClause\" : {\n \"OFFSET\": [\"offsetClause\"], \n \"VALUES\": [], \n \"$\": [], \n \"}\": []}, \n \"?or([DISTINCT,REDUCED])\" : {\n \"DISTINCT\": [\"or([DISTINCT,REDUCED])\"], \n \"REDUCED\": [\"or([DISTINCT,REDUCED])\"], \n \"*\": [], \n \"(\": [], \n \"VAR1\": [], \n \"VAR2\": []}, \n \"?or([LANGTAG,[^^,iriRef]])\" : {\n \"LANGTAG\": [\"or([LANGTAG,[^^,iriRef]])\"], \n \"^^\": [\"or([LANGTAG,[^^,iriRef]])\"], \n \"UNDEF\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"a\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"^\": [], \n \"!\": [], \n \"(\": [], \n \".\": [], \n \";\": [], \n \",\": [], \n \"AS\": [], \n \")\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \"+\": [], \n \"-\": [], \n \"*\": [], \n \"/\": [], \n \"}\": [], \n \"[\": [], \n \"NIL\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"]\": [], \n \"GRAPH\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": []}, \n \"?or([[*,unaryExpression],[/,unaryExpression]])\" : {\n \"*\": [\"or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"/\": [\"or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"+\": [], \n \"-\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": [], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \"=\": [], \n \"!=\": [], \n \"<\": [], \n \">\": [], \n \"<=\": [], \n \">=\": [], \n \"IN\": [], \n \"NOT\": [], \n \";\": []}, \n \"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\" : {\n \"=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"!=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"<\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \">\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"<=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \">=\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IN\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"NOT\": [\"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"AS\": [], \n \")\": [], \n \",\": [], \n \"||\": [], \n \"&&\": [], \n \";\": []}, \n \"?orderClause\" : {\n \"ORDER\": [\"orderClause\"], \n \"VALUES\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"$\": [], \n \"}\": []}, \n \"?pathMod\" : {\n \"*\": [\"pathMod\"], \n \"?\": [\"pathMod\"], \n \"+\": [\"pathMod\"], \n \"{\": [\"pathMod\"], \n \"|\": [], \n \"/\": [], \n \")\": [], \n \"(\": [], \n \"[\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"?triplesBlock\" : {\n \"VAR1\": [\"triplesBlock\"], \n \"VAR2\": [\"triplesBlock\"], \n \"NIL\": [\"triplesBlock\"], \n \"(\": [\"triplesBlock\"], \n \"[\": [\"triplesBlock\"], \n \"IRI_REF\": [\"triplesBlock\"], \n \"TRUE\": [\"triplesBlock\"], \n \"FALSE\": [\"triplesBlock\"], \n \"BLANK_NODE_LABEL\": [\"triplesBlock\"], \n \"ANON\": [\"triplesBlock\"], \n \"PNAME_LN\": [\"triplesBlock\"], \n \"PNAME_NS\": [\"triplesBlock\"], \n \"STRING_LITERAL1\": [\"triplesBlock\"], \n \"STRING_LITERAL2\": [\"triplesBlock\"], \n \"STRING_LITERAL_LONG1\": [\"triplesBlock\"], \n \"STRING_LITERAL_LONG2\": [\"triplesBlock\"], \n \"INTEGER\": [\"triplesBlock\"], \n \"DECIMAL\": [\"triplesBlock\"], \n \"DOUBLE\": [\"triplesBlock\"], \n \"INTEGER_POSITIVE\": [\"triplesBlock\"], \n \"DECIMAL_POSITIVE\": [\"triplesBlock\"], \n \"DOUBLE_POSITIVE\": [\"triplesBlock\"], \n \"INTEGER_NEGATIVE\": [\"triplesBlock\"], \n \"DECIMAL_NEGATIVE\": [\"triplesBlock\"], \n \"DOUBLE_NEGATIVE\": [\"triplesBlock\"], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"?triplesTemplate\" : {\n \"VAR1\": [\"triplesTemplate\"], \n \"VAR2\": [\"triplesTemplate\"], \n \"NIL\": [\"triplesTemplate\"], \n \"(\": [\"triplesTemplate\"], \n \"[\": [\"triplesTemplate\"], \n \"IRI_REF\": [\"triplesTemplate\"], \n \"TRUE\": [\"triplesTemplate\"], \n \"FALSE\": [\"triplesTemplate\"], \n \"BLANK_NODE_LABEL\": [\"triplesTemplate\"], \n \"ANON\": [\"triplesTemplate\"], \n \"PNAME_LN\": [\"triplesTemplate\"], \n \"PNAME_NS\": [\"triplesTemplate\"], \n \"STRING_LITERAL1\": [\"triplesTemplate\"], \n \"STRING_LITERAL2\": [\"triplesTemplate\"], \n \"STRING_LITERAL_LONG1\": [\"triplesTemplate\"], \n \"STRING_LITERAL_LONG2\": [\"triplesTemplate\"], \n \"INTEGER\": [\"triplesTemplate\"], \n \"DECIMAL\": [\"triplesTemplate\"], \n \"DOUBLE\": [\"triplesTemplate\"], \n \"INTEGER_POSITIVE\": [\"triplesTemplate\"], \n \"DECIMAL_POSITIVE\": [\"triplesTemplate\"], \n \"DOUBLE_POSITIVE\": [\"triplesTemplate\"], \n \"INTEGER_NEGATIVE\": [\"triplesTemplate\"], \n \"DECIMAL_NEGATIVE\": [\"triplesTemplate\"], \n \"DOUBLE_NEGATIVE\": [\"triplesTemplate\"], \n \"}\": [], \n \"GRAPH\": []}, \n \"?whereClause\" : {\n \"WHERE\": [\"whereClause\"], \n \"{\": [\"whereClause\"], \n \"ORDER\": [], \n \"HAVING\": [], \n \"GROUP\": [], \n \"LIMIT\": [], \n \"OFFSET\": [], \n \"VALUES\": [], \n \"$\": []}, \n \"[ (,*dataBlockValue,)]\" : {\n \"(\": [\"(\",\"*dataBlockValue\",\")\"]}, \n \"[ (,*var,)]\" : {\n \"(\": [\"(\",\"*var\",\")\"]}, \n \"[ (,expression,)]\" : {\n \"(\": [\"(\",\"expression\",\")\"]}, \n \"[ (,expression,AS,var,)]\" : {\n \"(\": [\"(\",\"expression\",\"AS\",\"var\",\")\"]}, \n \"[!=,numericExpression]\" : {\n \"!=\": [\"!=\",\"numericExpression\"]}, \n \"[&&,valueLogical]\" : {\n \"&&\": [\"&&\",\"valueLogical\"]}, \n \"[*,unaryExpression]\" : {\n \"*\": [\"*\",\"unaryExpression\"]}, \n \"[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]\" : {\n \"WHERE\": [\"*datasetClause\",\"WHERE\",\"{\",\"?triplesTemplate\",\"}\",\"solutionModifier\"], \n \"FROM\": [\"*datasetClause\",\"WHERE\",\"{\",\"?triplesTemplate\",\"}\",\"solutionModifier\"]}, \n \"[+,multiplicativeExpression]\" : {\n \"+\": [\"+\",\"multiplicativeExpression\"]}, \n \"[,,expression]\" : {\n \",\": [\",\",\"expression\"]}, \n \"[,,integer,}]\" : {\n \",\": [\",\",\"integer\",\"}\"]}, \n \"[,,objectPath]\" : {\n \",\": [\",\",\"objectPath\"]}, \n \"[,,object]\" : {\n \",\": [\",\",\"object\"]}, \n \"[,,or([},[integer,}]])]\" : {\n \",\": [\",\",\"or([},[integer,}]])\"]}, \n \"[-,multiplicativeExpression]\" : {\n \"-\": [\"-\",\"multiplicativeExpression\"]}, \n \"[.,?constructTriples]\" : {\n \".\": [\".\",\"?constructTriples\"]}, \n \"[.,?triplesBlock]\" : {\n \".\": [\".\",\"?triplesBlock\"]}, \n \"[.,?triplesTemplate]\" : {\n \".\": [\".\",\"?triplesTemplate\"]}, \n \"[/,pathEltOrInverse]\" : {\n \"/\": [\"/\",\"pathEltOrInverse\"]}, \n \"[/,unaryExpression]\" : {\n \"/\": [\"/\",\"unaryExpression\"]}, \n \"[;,?[or([verbPath,verbSimple]),objectList]]\" : {\n \";\": [\";\",\"?[or([verbPath,verbSimple]),objectList]\"]}, \n \"[;,?[verb,objectList]]\" : {\n \";\": [\";\",\"?[verb,objectList]\"]}, \n \"[;,SEPARATOR,=,string]\" : {\n \";\": [\";\",\"SEPARATOR\",\"=\",\"string\"]}, \n \"[;,update]\" : {\n \";\": [\";\",\"update\"]}, \n \"[<,numericExpression]\" : {\n \"<\": [\"<\",\"numericExpression\"]}, \n \"[<=,numericExpression]\" : {\n \"<=\": [\"<=\",\"numericExpression\"]}, \n \"[=,numericExpression]\" : {\n \"=\": [\"=\",\"numericExpression\"]}, \n \"[>,numericExpression]\" : {\n \">\": [\">\",\"numericExpression\"]}, \n \"[>=,numericExpression]\" : {\n \">=\": [\">=\",\"numericExpression\"]}, \n \"[AS,var]\" : {\n \"AS\": [\"AS\",\"var\"]}, \n \"[IN,expressionList]\" : {\n \"IN\": [\"IN\",\"expressionList\"]}, \n \"[INTO,graphRef]\" : {\n \"INTO\": [\"INTO\",\"graphRef\"]}, \n \"[NAMED,iriRef]\" : {\n \"NAMED\": [\"NAMED\",\"iriRef\"]}, \n \"[NOT,IN,expressionList]\" : {\n \"NOT\": [\"NOT\",\"IN\",\"expressionList\"]}, \n \"[UNION,groupGraphPattern]\" : {\n \"UNION\": [\"UNION\",\"groupGraphPattern\"]}, \n \"[^^,iriRef]\" : {\n \"^^\": [\"^^\",\"iriRef\"]}, \n \"[constructTemplate,*datasetClause,whereClause,solutionModifier]\" : {\n \"{\": [\"constructTemplate\",\"*datasetClause\",\"whereClause\",\"solutionModifier\"]}, \n \"[deleteClause,?insertClause]\" : {\n \"DELETE\": [\"deleteClause\",\"?insertClause\"]}, \n \"[graphPatternNotTriples,?.,?triplesBlock]\" : {\n \"{\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"OPTIONAL\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"MINUS\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"GRAPH\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"SERVICE\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"FILTER\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"BIND\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"], \n \"VALUES\": [\"graphPatternNotTriples\",\"?.\",\"?triplesBlock\"]}, \n \"[integer,or([[,,or([},[integer,}]])],}])]\" : {\n \"INTEGER\": [\"integer\",\"or([[,,or([},[integer,}]])],}])\"]}, \n \"[integer,}]\" : {\n \"INTEGER\": [\"integer\",\"}\"]}, \n \"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\" : {\n \"INTEGER_POSITIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_POSITIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_POSITIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER_NEGATIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_NEGATIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_NEGATIVE\": [\"or([numericLiteralPositive,numericLiteralNegative])\",\"?or([[*,unaryExpression],[/,unaryExpression]])\"]}, \n \"[or([verbPath,verbSimple]),objectList]\" : {\n \"VAR1\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"VAR2\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"^\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"a\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"!\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"(\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"IRI_REF\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"PNAME_LN\": [\"or([verbPath,verbSimple])\",\"objectList\"], \n \"PNAME_NS\": [\"or([verbPath,verbSimple])\",\"objectList\"]}, \n \"[pathOneInPropertySet,*[|,pathOneInPropertySet]]\" : {\n \"a\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"^\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"IRI_REF\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"PNAME_LN\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"], \n \"PNAME_NS\": [\"pathOneInPropertySet\",\"*[|,pathOneInPropertySet]\"]}, \n \"[quadsNotTriples,?.,?triplesTemplate]\" : {\n \"GRAPH\": [\"quadsNotTriples\",\"?.\",\"?triplesTemplate\"]}, \n \"[update1,?[;,update]]\" : {\n \"INSERT\": [\"update1\",\"?[;,update]\"], \n \"DELETE\": [\"update1\",\"?[;,update]\"], \n \"LOAD\": [\"update1\",\"?[;,update]\"], \n \"CLEAR\": [\"update1\",\"?[;,update]\"], \n \"DROP\": [\"update1\",\"?[;,update]\"], \n \"ADD\": [\"update1\",\"?[;,update]\"], \n \"MOVE\": [\"update1\",\"?[;,update]\"], \n \"COPY\": [\"update1\",\"?[;,update]\"], \n \"CREATE\": [\"update1\",\"?[;,update]\"], \n \"WITH\": [\"update1\",\"?[;,update]\"]}, \n \"[verb,objectList]\" : {\n \"a\": [\"verb\",\"objectList\"], \n \"VAR1\": [\"verb\",\"objectList\"], \n \"VAR2\": [\"verb\",\"objectList\"], \n \"IRI_REF\": [\"verb\",\"objectList\"], \n \"PNAME_LN\": [\"verb\",\"objectList\"], \n \"PNAME_NS\": [\"verb\",\"objectList\"]}, \n \"[|,pathOneInPropertySet]\" : {\n \"|\": [\"|\",\"pathOneInPropertySet\"]}, \n \"[|,pathSequence]\" : {\n \"|\": [\"|\",\"pathSequence\"]}, \n \"[||,conditionalAndExpression]\" : {\n \"||\": [\"||\",\"conditionalAndExpression\"]}, \n \"add\" : {\n \"ADD\": [\"ADD\",\"?SILENT_4\",\"graphOrDefault\",\"TO\",\"graphOrDefault\"]}, \n \"additiveExpression\" : {\n \"!\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"+\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"-\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"VAR1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"VAR2\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"(\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"LANG\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"LANGMATCHES\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DATATYPE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"BOUND\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"IRI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"URI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"BNODE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"RAND\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ABS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"CEIL\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"FLOOR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ROUND\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"CONCAT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRLEN\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"UCASE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"LCASE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ENCODE_FOR_URI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"CONTAINS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRSTARTS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRENDS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRBEFORE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRAFTER\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"YEAR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MONTH\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DAY\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"HOURS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MINUTES\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SECONDS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"TIMEZONE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"TZ\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"NOW\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"UUID\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRUUID\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MD5\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA256\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA384\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SHA512\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"COALESCE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"IF\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRLANG\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRDT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SAMETERM\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISIRI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISURI\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISBLANK\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISLITERAL\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"ISNUMERIC\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"TRUE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"FALSE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"COUNT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SUM\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MIN\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"MAX\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"AVG\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SAMPLE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"GROUP_CONCAT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"SUBSTR\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"REPLACE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"REGEX\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"EXISTS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"NOT\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"IRI_REF\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL2\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL_LONG1\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"STRING_LITERAL_LONG2\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_POSITIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_POSITIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_POSITIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"INTEGER_NEGATIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DECIMAL_NEGATIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"DOUBLE_NEGATIVE\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"PNAME_LN\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"], \n \"PNAME_NS\": [\"multiplicativeExpression\",\"*or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\"]}, \n \"aggregate\" : {\n \"COUNT\": [\"COUNT\",\"(\",\"?DISTINCT\",\"or([*,expression])\",\")\"], \n \"SUM\": [\"SUM\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"MIN\": [\"MIN\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"MAX\": [\"MAX\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"AVG\": [\"AVG\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"SAMPLE\": [\"SAMPLE\",\"(\",\"?DISTINCT\",\"expression\",\")\"], \n \"GROUP_CONCAT\": [\"GROUP_CONCAT\",\"(\",\"?DISTINCT\",\"expression\",\"?[;,SEPARATOR,=,string]\",\")\"]}, \n \"allowBnodes\" : {\n \"}\": []}, \n \"allowVars\" : {\n \"}\": []}, \n \"argList\" : {\n \"NIL\": [\"NIL\"], \n \"(\": [\"(\",\"?DISTINCT\",\"expression\",\"*[,,expression]\",\")\"]}, \n \"askQuery\" : {\n \"ASK\": [\"ASK\",\"*datasetClause\",\"whereClause\",\"solutionModifier\"]}, \n \"baseDecl\" : {\n \"BASE\": [\"BASE\",\"IRI_REF\"]}, \n \"bind\" : {\n \"BIND\": [\"BIND\",\"(\",\"expression\",\"AS\",\"var\",\")\"]}, \n \"blankNode\" : {\n \"BLANK_NODE_LABEL\": [\"BLANK_NODE_LABEL\"], \n \"ANON\": [\"ANON\"]}, \n \"blankNodePropertyList\" : {\n \"[\": [\"[\",\"propertyListNotEmpty\",\"]\"]}, \n \"blankNodePropertyListPath\" : {\n \"[\": [\"[\",\"propertyListPathNotEmpty\",\"]\"]}, \n \"booleanLiteral\" : {\n \"TRUE\": [\"TRUE\"], \n \"FALSE\": [\"FALSE\"]}, \n \"brackettedExpression\" : {\n \"(\": [\"(\",\"expression\",\")\"]}, \n \"builtInCall\" : {\n \"STR\": [\"STR\",\"(\",\"expression\",\")\"], \n \"LANG\": [\"LANG\",\"(\",\"expression\",\")\"], \n \"LANGMATCHES\": [\"LANGMATCHES\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"DATATYPE\": [\"DATATYPE\",\"(\",\"expression\",\")\"], \n \"BOUND\": [\"BOUND\",\"(\",\"var\",\")\"], \n \"IRI\": [\"IRI\",\"(\",\"expression\",\")\"], \n \"URI\": [\"URI\",\"(\",\"expression\",\")\"], \n \"BNODE\": [\"BNODE\",\"or([[ (,expression,)],NIL])\"], \n \"RAND\": [\"RAND\",\"NIL\"], \n \"ABS\": [\"ABS\",\"(\",\"expression\",\")\"], \n \"CEIL\": [\"CEIL\",\"(\",\"expression\",\")\"], \n \"FLOOR\": [\"FLOOR\",\"(\",\"expression\",\")\"], \n \"ROUND\": [\"ROUND\",\"(\",\"expression\",\")\"], \n \"CONCAT\": [\"CONCAT\",\"expressionList\"], \n \"SUBSTR\": [\"substringExpression\"], \n \"STRLEN\": [\"STRLEN\",\"(\",\"expression\",\")\"], \n \"REPLACE\": [\"strReplaceExpression\"], \n \"UCASE\": [\"UCASE\",\"(\",\"expression\",\")\"], \n \"LCASE\": [\"LCASE\",\"(\",\"expression\",\")\"], \n \"ENCODE_FOR_URI\": [\"ENCODE_FOR_URI\",\"(\",\"expression\",\")\"], \n \"CONTAINS\": [\"CONTAINS\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRSTARTS\": [\"STRSTARTS\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRENDS\": [\"STRENDS\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRBEFORE\": [\"STRBEFORE\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRAFTER\": [\"STRAFTER\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"YEAR\": [\"YEAR\",\"(\",\"expression\",\")\"], \n \"MONTH\": [\"MONTH\",\"(\",\"expression\",\")\"], \n \"DAY\": [\"DAY\",\"(\",\"expression\",\")\"], \n \"HOURS\": [\"HOURS\",\"(\",\"expression\",\")\"], \n \"MINUTES\": [\"MINUTES\",\"(\",\"expression\",\")\"], \n \"SECONDS\": [\"SECONDS\",\"(\",\"expression\",\")\"], \n \"TIMEZONE\": [\"TIMEZONE\",\"(\",\"expression\",\")\"], \n \"TZ\": [\"TZ\",\"(\",\"expression\",\")\"], \n \"NOW\": [\"NOW\",\"NIL\"], \n \"UUID\": [\"UUID\",\"NIL\"], \n \"STRUUID\": [\"STRUUID\",\"NIL\"], \n \"MD5\": [\"MD5\",\"(\",\"expression\",\")\"], \n \"SHA1\": [\"SHA1\",\"(\",\"expression\",\")\"], \n \"SHA256\": [\"SHA256\",\"(\",\"expression\",\")\"], \n \"SHA384\": [\"SHA384\",\"(\",\"expression\",\")\"], \n \"SHA512\": [\"SHA512\",\"(\",\"expression\",\")\"], \n \"COALESCE\": [\"COALESCE\",\"expressionList\"], \n \"IF\": [\"IF\",\"(\",\"expression\",\",\",\"expression\",\",\",\"expression\",\")\"], \n \"STRLANG\": [\"STRLANG\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"STRDT\": [\"STRDT\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"SAMETERM\": [\"SAMETERM\",\"(\",\"expression\",\",\",\"expression\",\")\"], \n \"ISIRI\": [\"ISIRI\",\"(\",\"expression\",\")\"], \n \"ISURI\": [\"ISURI\",\"(\",\"expression\",\")\"], \n \"ISBLANK\": [\"ISBLANK\",\"(\",\"expression\",\")\"], \n \"ISLITERAL\": [\"ISLITERAL\",\"(\",\"expression\",\")\"], \n \"ISNUMERIC\": [\"ISNUMERIC\",\"(\",\"expression\",\")\"], \n \"REGEX\": [\"regexExpression\"], \n \"EXISTS\": [\"existsFunc\"], \n \"NOT\": [\"notExistsFunc\"]}, \n \"clear\" : {\n \"CLEAR\": [\"CLEAR\",\"?SILENT_2\",\"graphRefAll\"]}, \n \"collection\" : {\n \"(\": [\"(\",\"+graphNode\",\")\"]}, \n \"collectionPath\" : {\n \"(\": [\"(\",\"+graphNodePath\",\")\"]}, \n \"conditionalAndExpression\" : {\n \"!\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"+\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"-\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"VAR1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"VAR2\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"(\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"LANG\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"LANGMATCHES\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DATATYPE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"BOUND\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"IRI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"URI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"BNODE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"RAND\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ABS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"CEIL\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"FLOOR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ROUND\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"CONCAT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRLEN\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"UCASE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"LCASE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ENCODE_FOR_URI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"CONTAINS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRSTARTS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRENDS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRBEFORE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRAFTER\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"YEAR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MONTH\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DAY\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"HOURS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MINUTES\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SECONDS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"TIMEZONE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"TZ\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"NOW\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"UUID\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRUUID\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MD5\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA256\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA384\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SHA512\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"COALESCE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"IF\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRLANG\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRDT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SAMETERM\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISIRI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISURI\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISBLANK\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISLITERAL\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"ISNUMERIC\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"TRUE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"FALSE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"COUNT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SUM\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MIN\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"MAX\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"AVG\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SAMPLE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"GROUP_CONCAT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"SUBSTR\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"REPLACE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"REGEX\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"EXISTS\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"NOT\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"IRI_REF\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL2\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL_LONG1\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"STRING_LITERAL_LONG2\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"INTEGER\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DECIMAL\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DOUBLE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"INTEGER_POSITIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DECIMAL_POSITIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DOUBLE_POSITIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"INTEGER_NEGATIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DECIMAL_NEGATIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"DOUBLE_NEGATIVE\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"PNAME_LN\": [\"valueLogical\",\"*[&&,valueLogical]\"], \n \"PNAME_NS\": [\"valueLogical\",\"*[&&,valueLogical]\"]}, \n \"conditionalOrExpression\" : {\n \"!\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"+\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"-\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"VAR1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"VAR2\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"(\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"LANG\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"LANGMATCHES\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DATATYPE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"BOUND\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"IRI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"URI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"BNODE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"RAND\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ABS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"CEIL\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"FLOOR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ROUND\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"CONCAT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRLEN\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"UCASE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"LCASE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ENCODE_FOR_URI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"CONTAINS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRSTARTS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRENDS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRBEFORE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRAFTER\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"YEAR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MONTH\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DAY\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"HOURS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MINUTES\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SECONDS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"TIMEZONE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"TZ\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"NOW\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"UUID\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRUUID\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MD5\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA256\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA384\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SHA512\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"COALESCE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"IF\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRLANG\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRDT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SAMETERM\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISIRI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISURI\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISBLANK\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISLITERAL\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"ISNUMERIC\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"TRUE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"FALSE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"COUNT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SUM\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MIN\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"MAX\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"AVG\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SAMPLE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"GROUP_CONCAT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"SUBSTR\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"REPLACE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"REGEX\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"EXISTS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"NOT\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"IRI_REF\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL2\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL_LONG1\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"STRING_LITERAL_LONG2\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"INTEGER\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DECIMAL\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DOUBLE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"INTEGER_POSITIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DECIMAL_POSITIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DOUBLE_POSITIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"INTEGER_NEGATIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DECIMAL_NEGATIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"DOUBLE_NEGATIVE\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"PNAME_LN\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"], \n \"PNAME_NS\": [\"conditionalAndExpression\",\"*[||,conditionalAndExpression]\"]}, \n \"constraint\" : {\n \"(\": [\"brackettedExpression\"], \n \"STR\": [\"builtInCall\"], \n \"LANG\": [\"builtInCall\"], \n \"LANGMATCHES\": [\"builtInCall\"], \n \"DATATYPE\": [\"builtInCall\"], \n \"BOUND\": [\"builtInCall\"], \n \"IRI\": [\"builtInCall\"], \n \"URI\": [\"builtInCall\"], \n \"BNODE\": [\"builtInCall\"], \n \"RAND\": [\"builtInCall\"], \n \"ABS\": [\"builtInCall\"], \n \"CEIL\": [\"builtInCall\"], \n \"FLOOR\": [\"builtInCall\"], \n \"ROUND\": [\"builtInCall\"], \n \"CONCAT\": [\"builtInCall\"], \n \"STRLEN\": [\"builtInCall\"], \n \"UCASE\": [\"builtInCall\"], \n \"LCASE\": [\"builtInCall\"], \n \"ENCODE_FOR_URI\": [\"builtInCall\"], \n \"CONTAINS\": [\"builtInCall\"], \n \"STRSTARTS\": [\"builtInCall\"], \n \"STRENDS\": [\"builtInCall\"], \n \"STRBEFORE\": [\"builtInCall\"], \n \"STRAFTER\": [\"builtInCall\"], \n \"YEAR\": [\"builtInCall\"], \n \"MONTH\": [\"builtInCall\"], \n \"DAY\": [\"builtInCall\"], \n \"HOURS\": [\"builtInCall\"], \n \"MINUTES\": [\"builtInCall\"], \n \"SECONDS\": [\"builtInCall\"], \n \"TIMEZONE\": [\"builtInCall\"], \n \"TZ\": [\"builtInCall\"], \n \"NOW\": [\"builtInCall\"], \n \"UUID\": [\"builtInCall\"], \n \"STRUUID\": [\"builtInCall\"], \n \"MD5\": [\"builtInCall\"], \n \"SHA1\": [\"builtInCall\"], \n \"SHA256\": [\"builtInCall\"], \n \"SHA384\": [\"builtInCall\"], \n \"SHA512\": [\"builtInCall\"], \n \"COALESCE\": [\"builtInCall\"], \n \"IF\": [\"builtInCall\"], \n \"STRLANG\": [\"builtInCall\"], \n \"STRDT\": [\"builtInCall\"], \n \"SAMETERM\": [\"builtInCall\"], \n \"ISIRI\": [\"builtInCall\"], \n \"ISURI\": [\"builtInCall\"], \n \"ISBLANK\": [\"builtInCall\"], \n \"ISLITERAL\": [\"builtInCall\"], \n \"ISNUMERIC\": [\"builtInCall\"], \n \"SUBSTR\": [\"builtInCall\"], \n \"REPLACE\": [\"builtInCall\"], \n \"REGEX\": [\"builtInCall\"], \n \"EXISTS\": [\"builtInCall\"], \n \"NOT\": [\"builtInCall\"], \n \"IRI_REF\": [\"functionCall\"], \n \"PNAME_LN\": [\"functionCall\"], \n \"PNAME_NS\": [\"functionCall\"]}, \n \"constructQuery\" : {\n \"CONSTRUCT\": [\"CONSTRUCT\",\"or([[constructTemplate,*datasetClause,whereClause,solutionModifier],[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]])\"]}, \n \"constructTemplate\" : {\n \"{\": [\"{\",\"?constructTriples\",\"}\"]}, \n \"constructTriples\" : {\n \"VAR1\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"VAR2\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"NIL\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"(\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"[\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"IRI_REF\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"TRUE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"FALSE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"BLANK_NODE_LABEL\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"ANON\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"PNAME_LN\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"PNAME_NS\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL1\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL2\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL_LONG1\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"STRING_LITERAL_LONG2\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"INTEGER\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DECIMAL\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DOUBLE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"INTEGER_POSITIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DECIMAL_POSITIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DOUBLE_POSITIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"INTEGER_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DECIMAL_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"], \n \"DOUBLE_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?constructTriples]\"]}, \n \"copy\" : {\n \"COPY\": [\"COPY\",\"?SILENT_4\",\"graphOrDefault\",\"TO\",\"graphOrDefault\"]}, \n \"create\" : {\n \"CREATE\": [\"CREATE\",\"?SILENT_3\",\"graphRef\"]}, \n \"dataBlock\" : {\n \"NIL\": [\"or([inlineDataOneVar,inlineDataFull])\"], \n \"(\": [\"or([inlineDataOneVar,inlineDataFull])\"], \n \"VAR1\": [\"or([inlineDataOneVar,inlineDataFull])\"], \n \"VAR2\": [\"or([inlineDataOneVar,inlineDataFull])\"]}, \n \"dataBlockValue\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"STRING_LITERAL1\": [\"rdfLiteral\"], \n \"STRING_LITERAL2\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG1\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG2\": [\"rdfLiteral\"], \n \"INTEGER\": [\"numericLiteral\"], \n \"DECIMAL\": [\"numericLiteral\"], \n \"DOUBLE\": [\"numericLiteral\"], \n \"INTEGER_POSITIVE\": [\"numericLiteral\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteral\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteral\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteral\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteral\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteral\"], \n \"TRUE\": [\"booleanLiteral\"], \n \"FALSE\": [\"booleanLiteral\"], \n \"UNDEF\": [\"UNDEF\"]}, \n \"datasetClause\" : {\n \"FROM\": [\"FROM\",\"or([defaultGraphClause,namedGraphClause])\"]}, \n \"defaultGraphClause\" : {\n \"IRI_REF\": [\"sourceSelector\"], \n \"PNAME_LN\": [\"sourceSelector\"], \n \"PNAME_NS\": [\"sourceSelector\"]}, \n \"delete1\" : {\n \"DATA\": [\"DATA\",\"quadDataNoBnodes\"], \n \"WHERE\": [\"WHERE\",\"quadPatternNoBnodes\"], \n \"{\": [\"quadPatternNoBnodes\",\"?insertClause\",\"*usingClause\",\"WHERE\",\"groupGraphPattern\"]}, \n \"deleteClause\" : {\n \"DELETE\": [\"DELETE\",\"quadPattern\"]}, \n \"describeDatasetClause\" : {\n \"FROM\": [\"FROM\",\"or([defaultGraphClause,namedGraphClause])\"]}, \n \"describeQuery\" : {\n \"DESCRIBE\": [\"DESCRIBE\",\"or([+varOrIRIref,*])\",\"*describeDatasetClause\",\"?whereClause\",\"solutionModifier\"]}, \n \"disallowBnodes\" : {\n \"}\": [], \n \"GRAPH\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"(\": [], \n \"[\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"disallowVars\" : {\n \"}\": [], \n \"GRAPH\": [], \n \"VAR1\": [], \n \"VAR2\": [], \n \"NIL\": [], \n \"(\": [], \n \"[\": [], \n \"IRI_REF\": [], \n \"TRUE\": [], \n \"FALSE\": [], \n \"BLANK_NODE_LABEL\": [], \n \"ANON\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"STRING_LITERAL1\": [], \n \"STRING_LITERAL2\": [], \n \"STRING_LITERAL_LONG1\": [], \n \"STRING_LITERAL_LONG2\": [], \n \"INTEGER\": [], \n \"DECIMAL\": [], \n \"DOUBLE\": [], \n \"INTEGER_POSITIVE\": [], \n \"DECIMAL_POSITIVE\": [], \n \"DOUBLE_POSITIVE\": [], \n \"INTEGER_NEGATIVE\": [], \n \"DECIMAL_NEGATIVE\": [], \n \"DOUBLE_NEGATIVE\": []}, \n \"drop\" : {\n \"DROP\": [\"DROP\",\"?SILENT_2\",\"graphRefAll\"]}, \n \"existsFunc\" : {\n \"EXISTS\": [\"EXISTS\",\"groupGraphPattern\"]}, \n \"expression\" : {\n \"!\": [\"conditionalOrExpression\"], \n \"+\": [\"conditionalOrExpression\"], \n \"-\": [\"conditionalOrExpression\"], \n \"VAR1\": [\"conditionalOrExpression\"], \n \"VAR2\": [\"conditionalOrExpression\"], \n \"(\": [\"conditionalOrExpression\"], \n \"STR\": [\"conditionalOrExpression\"], \n \"LANG\": [\"conditionalOrExpression\"], \n \"LANGMATCHES\": [\"conditionalOrExpression\"], \n \"DATATYPE\": [\"conditionalOrExpression\"], \n \"BOUND\": [\"conditionalOrExpression\"], \n \"IRI\": [\"conditionalOrExpression\"], \n \"URI\": [\"conditionalOrExpression\"], \n \"BNODE\": [\"conditionalOrExpression\"], \n \"RAND\": [\"conditionalOrExpression\"], \n \"ABS\": [\"conditionalOrExpression\"], \n \"CEIL\": [\"conditionalOrExpression\"], \n \"FLOOR\": [\"conditionalOrExpression\"], \n \"ROUND\": [\"conditionalOrExpression\"], \n \"CONCAT\": [\"conditionalOrExpression\"], \n \"STRLEN\": [\"conditionalOrExpression\"], \n \"UCASE\": [\"conditionalOrExpression\"], \n \"LCASE\": [\"conditionalOrExpression\"], \n \"ENCODE_FOR_URI\": [\"conditionalOrExpression\"], \n \"CONTAINS\": [\"conditionalOrExpression\"], \n \"STRSTARTS\": [\"conditionalOrExpression\"], \n \"STRENDS\": [\"conditionalOrExpression\"], \n \"STRBEFORE\": [\"conditionalOrExpression\"], \n \"STRAFTER\": [\"conditionalOrExpression\"], \n \"YEAR\": [\"conditionalOrExpression\"], \n \"MONTH\": [\"conditionalOrExpression\"], \n \"DAY\": [\"conditionalOrExpression\"], \n \"HOURS\": [\"conditionalOrExpression\"], \n \"MINUTES\": [\"conditionalOrExpression\"], \n \"SECONDS\": [\"conditionalOrExpression\"], \n \"TIMEZONE\": [\"conditionalOrExpression\"], \n \"TZ\": [\"conditionalOrExpression\"], \n \"NOW\": [\"conditionalOrExpression\"], \n \"UUID\": [\"conditionalOrExpression\"], \n \"STRUUID\": [\"conditionalOrExpression\"], \n \"MD5\": [\"conditionalOrExpression\"], \n \"SHA1\": [\"conditionalOrExpression\"], \n \"SHA256\": [\"conditionalOrExpression\"], \n \"SHA384\": [\"conditionalOrExpression\"], \n \"SHA512\": [\"conditionalOrExpression\"], \n \"COALESCE\": [\"conditionalOrExpression\"], \n \"IF\": [\"conditionalOrExpression\"], \n \"STRLANG\": [\"conditionalOrExpression\"], \n \"STRDT\": [\"conditionalOrExpression\"], \n \"SAMETERM\": [\"conditionalOrExpression\"], \n \"ISIRI\": [\"conditionalOrExpression\"], \n \"ISURI\": [\"conditionalOrExpression\"], \n \"ISBLANK\": [\"conditionalOrExpression\"], \n \"ISLITERAL\": [\"conditionalOrExpression\"], \n \"ISNUMERIC\": [\"conditionalOrExpression\"], \n \"TRUE\": [\"conditionalOrExpression\"], \n \"FALSE\": [\"conditionalOrExpression\"], \n \"COUNT\": [\"conditionalOrExpression\"], \n \"SUM\": [\"conditionalOrExpression\"], \n \"MIN\": [\"conditionalOrExpression\"], \n \"MAX\": [\"conditionalOrExpression\"], \n \"AVG\": [\"conditionalOrExpression\"], \n \"SAMPLE\": [\"conditionalOrExpression\"], \n \"GROUP_CONCAT\": [\"conditionalOrExpression\"], \n \"SUBSTR\": [\"conditionalOrExpression\"], \n \"REPLACE\": [\"conditionalOrExpression\"], \n \"REGEX\": [\"conditionalOrExpression\"], \n \"EXISTS\": [\"conditionalOrExpression\"], \n \"NOT\": [\"conditionalOrExpression\"], \n \"IRI_REF\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL1\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL2\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL_LONG1\": [\"conditionalOrExpression\"], \n \"STRING_LITERAL_LONG2\": [\"conditionalOrExpression\"], \n \"INTEGER\": [\"conditionalOrExpression\"], \n \"DECIMAL\": [\"conditionalOrExpression\"], \n \"DOUBLE\": [\"conditionalOrExpression\"], \n \"INTEGER_POSITIVE\": [\"conditionalOrExpression\"], \n \"DECIMAL_POSITIVE\": [\"conditionalOrExpression\"], \n \"DOUBLE_POSITIVE\": [\"conditionalOrExpression\"], \n \"INTEGER_NEGATIVE\": [\"conditionalOrExpression\"], \n \"DECIMAL_NEGATIVE\": [\"conditionalOrExpression\"], \n \"DOUBLE_NEGATIVE\": [\"conditionalOrExpression\"], \n \"PNAME_LN\": [\"conditionalOrExpression\"], \n \"PNAME_NS\": [\"conditionalOrExpression\"]}, \n \"expressionList\" : {\n \"NIL\": [\"NIL\"], \n \"(\": [\"(\",\"expression\",\"*[,,expression]\",\")\"]}, \n \"filter\" : {\n \"FILTER\": [\"FILTER\",\"constraint\"]}, \n \"functionCall\" : {\n \"IRI_REF\": [\"iriRef\",\"argList\"], \n \"PNAME_LN\": [\"iriRef\",\"argList\"], \n \"PNAME_NS\": [\"iriRef\",\"argList\"]}, \n \"graphGraphPattern\" : {\n \"GRAPH\": [\"GRAPH\",\"varOrIRIref\",\"groupGraphPattern\"]}, \n \"graphNode\" : {\n \"VAR1\": [\"varOrTerm\"], \n \"VAR2\": [\"varOrTerm\"], \n \"NIL\": [\"varOrTerm\"], \n \"IRI_REF\": [\"varOrTerm\"], \n \"TRUE\": [\"varOrTerm\"], \n \"FALSE\": [\"varOrTerm\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\"], \n \"ANON\": [\"varOrTerm\"], \n \"PNAME_LN\": [\"varOrTerm\"], \n \"PNAME_NS\": [\"varOrTerm\"], \n \"STRING_LITERAL1\": [\"varOrTerm\"], \n \"STRING_LITERAL2\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\"], \n \"INTEGER\": [\"varOrTerm\"], \n \"DECIMAL\": [\"varOrTerm\"], \n \"DOUBLE\": [\"varOrTerm\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\"], \n \"(\": [\"triplesNode\"], \n \"[\": [\"triplesNode\"]}, \n \"graphNodePath\" : {\n \"VAR1\": [\"varOrTerm\"], \n \"VAR2\": [\"varOrTerm\"], \n \"NIL\": [\"varOrTerm\"], \n \"IRI_REF\": [\"varOrTerm\"], \n \"TRUE\": [\"varOrTerm\"], \n \"FALSE\": [\"varOrTerm\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\"], \n \"ANON\": [\"varOrTerm\"], \n \"PNAME_LN\": [\"varOrTerm\"], \n \"PNAME_NS\": [\"varOrTerm\"], \n \"STRING_LITERAL1\": [\"varOrTerm\"], \n \"STRING_LITERAL2\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\"], \n \"INTEGER\": [\"varOrTerm\"], \n \"DECIMAL\": [\"varOrTerm\"], \n \"DOUBLE\": [\"varOrTerm\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\"], \n \"(\": [\"triplesNodePath\"], \n \"[\": [\"triplesNodePath\"]}, \n \"graphOrDefault\" : {\n \"DEFAULT\": [\"DEFAULT\"], \n \"IRI_REF\": [\"?GRAPH\",\"iriRef\"], \n \"PNAME_LN\": [\"?GRAPH\",\"iriRef\"], \n \"PNAME_NS\": [\"?GRAPH\",\"iriRef\"], \n \"GRAPH\": [\"?GRAPH\",\"iriRef\"]}, \n \"graphPatternNotTriples\" : {\n \"{\": [\"groupOrUnionGraphPattern\"], \n \"OPTIONAL\": [\"optionalGraphPattern\"], \n \"MINUS\": [\"minusGraphPattern\"], \n \"GRAPH\": [\"graphGraphPattern\"], \n \"SERVICE\": [\"serviceGraphPattern\"], \n \"FILTER\": [\"filter\"], \n \"BIND\": [\"bind\"], \n \"VALUES\": [\"inlineData\"]}, \n \"graphRef\" : {\n \"GRAPH\": [\"GRAPH\",\"iriRef\"]}, \n \"graphRefAll\" : {\n \"GRAPH\": [\"graphRef\"], \n \"DEFAULT\": [\"DEFAULT\"], \n \"NAMED\": [\"NAMED\"], \n \"ALL\": [\"ALL\"]}, \n \"graphTerm\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"STRING_LITERAL1\": [\"rdfLiteral\"], \n \"STRING_LITERAL2\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG1\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG2\": [\"rdfLiteral\"], \n \"INTEGER\": [\"numericLiteral\"], \n \"DECIMAL\": [\"numericLiteral\"], \n \"DOUBLE\": [\"numericLiteral\"], \n \"INTEGER_POSITIVE\": [\"numericLiteral\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteral\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteral\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteral\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteral\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteral\"], \n \"TRUE\": [\"booleanLiteral\"], \n \"FALSE\": [\"booleanLiteral\"], \n \"BLANK_NODE_LABEL\": [\"blankNode\"], \n \"ANON\": [\"blankNode\"], \n \"NIL\": [\"NIL\"]}, \n \"groupClause\" : {\n \"GROUP\": [\"GROUP\",\"BY\",\"+groupCondition\"]}, \n \"groupCondition\" : {\n \"STR\": [\"builtInCall\"], \n \"LANG\": [\"builtInCall\"], \n \"LANGMATCHES\": [\"builtInCall\"], \n \"DATATYPE\": [\"builtInCall\"], \n \"BOUND\": [\"builtInCall\"], \n \"IRI\": [\"builtInCall\"], \n \"URI\": [\"builtInCall\"], \n \"BNODE\": [\"builtInCall\"], \n \"RAND\": [\"builtInCall\"], \n \"ABS\": [\"builtInCall\"], \n \"CEIL\": [\"builtInCall\"], \n \"FLOOR\": [\"builtInCall\"], \n \"ROUND\": [\"builtInCall\"], \n \"CONCAT\": [\"builtInCall\"], \n \"STRLEN\": [\"builtInCall\"], \n \"UCASE\": [\"builtInCall\"], \n \"LCASE\": [\"builtInCall\"], \n \"ENCODE_FOR_URI\": [\"builtInCall\"], \n \"CONTAINS\": [\"builtInCall\"], \n \"STRSTARTS\": [\"builtInCall\"], \n \"STRENDS\": [\"builtInCall\"], \n \"STRBEFORE\": [\"builtInCall\"], \n \"STRAFTER\": [\"builtInCall\"], \n \"YEAR\": [\"builtInCall\"], \n \"MONTH\": [\"builtInCall\"], \n \"DAY\": [\"builtInCall\"], \n \"HOURS\": [\"builtInCall\"], \n \"MINUTES\": [\"builtInCall\"], \n \"SECONDS\": [\"builtInCall\"], \n \"TIMEZONE\": [\"builtInCall\"], \n \"TZ\": [\"builtInCall\"], \n \"NOW\": [\"builtInCall\"], \n \"UUID\": [\"builtInCall\"], \n \"STRUUID\": [\"builtInCall\"], \n \"MD5\": [\"builtInCall\"], \n \"SHA1\": [\"builtInCall\"], \n \"SHA256\": [\"builtInCall\"], \n \"SHA384\": [\"builtInCall\"], \n \"SHA512\": [\"builtInCall\"], \n \"COALESCE\": [\"builtInCall\"], \n \"IF\": [\"builtInCall\"], \n \"STRLANG\": [\"builtInCall\"], \n \"STRDT\": [\"builtInCall\"], \n \"SAMETERM\": [\"builtInCall\"], \n \"ISIRI\": [\"builtInCall\"], \n \"ISURI\": [\"builtInCall\"], \n \"ISBLANK\": [\"builtInCall\"], \n \"ISLITERAL\": [\"builtInCall\"], \n \"ISNUMERIC\": [\"builtInCall\"], \n \"SUBSTR\": [\"builtInCall\"], \n \"REPLACE\": [\"builtInCall\"], \n \"REGEX\": [\"builtInCall\"], \n \"EXISTS\": [\"builtInCall\"], \n \"NOT\": [\"builtInCall\"], \n \"IRI_REF\": [\"functionCall\"], \n \"PNAME_LN\": [\"functionCall\"], \n \"PNAME_NS\": [\"functionCall\"], \n \"(\": [\"(\",\"expression\",\"?[AS,var]\",\")\"], \n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"]}, \n \"groupGraphPattern\" : {\n \"{\": [\"{\",\"or([subSelect,groupGraphPatternSub])\",\"}\"]}, \n \"groupGraphPatternSub\" : {\n \"{\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"OPTIONAL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"MINUS\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"GRAPH\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"SERVICE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"FILTER\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"BIND\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"VALUES\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"VAR1\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"VAR2\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"NIL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"(\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"[\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"IRI_REF\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"TRUE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"FALSE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"BLANK_NODE_LABEL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"ANON\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"PNAME_LN\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"PNAME_NS\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL1\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL2\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG1\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG2\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"INTEGER\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DECIMAL\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DOUBLE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"INTEGER_POSITIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DECIMAL_POSITIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DOUBLE_POSITIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"INTEGER_NEGATIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DECIMAL_NEGATIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"DOUBLE_NEGATIVE\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"], \n \"}\": [\"?triplesBlock\",\"*[graphPatternNotTriples,?.,?triplesBlock]\"]}, \n \"groupOrUnionGraphPattern\" : {\n \"{\": [\"groupGraphPattern\",\"*[UNION,groupGraphPattern]\"]}, \n \"havingClause\" : {\n \"HAVING\": [\"HAVING\",\"+havingCondition\"]}, \n \"havingCondition\" : {\n \"(\": [\"constraint\"], \n \"STR\": [\"constraint\"], \n \"LANG\": [\"constraint\"], \n \"LANGMATCHES\": [\"constraint\"], \n \"DATATYPE\": [\"constraint\"], \n \"BOUND\": [\"constraint\"], \n \"IRI\": [\"constraint\"], \n \"URI\": [\"constraint\"], \n \"BNODE\": [\"constraint\"], \n \"RAND\": [\"constraint\"], \n \"ABS\": [\"constraint\"], \n \"CEIL\": [\"constraint\"], \n \"FLOOR\": [\"constraint\"], \n \"ROUND\": [\"constraint\"], \n \"CONCAT\": [\"constraint\"], \n \"STRLEN\": [\"constraint\"], \n \"UCASE\": [\"constraint\"], \n \"LCASE\": [\"constraint\"], \n \"ENCODE_FOR_URI\": [\"constraint\"], \n \"CONTAINS\": [\"constraint\"], \n \"STRSTARTS\": [\"constraint\"], \n \"STRENDS\": [\"constraint\"], \n \"STRBEFORE\": [\"constraint\"], \n \"STRAFTER\": [\"constraint\"], \n \"YEAR\": [\"constraint\"], \n \"MONTH\": [\"constraint\"], \n \"DAY\": [\"constraint\"], \n \"HOURS\": [\"constraint\"], \n \"MINUTES\": [\"constraint\"], \n \"SECONDS\": [\"constraint\"], \n \"TIMEZONE\": [\"constraint\"], \n \"TZ\": [\"constraint\"], \n \"NOW\": [\"constraint\"], \n \"UUID\": [\"constraint\"], \n \"STRUUID\": [\"constraint\"], \n \"MD5\": [\"constraint\"], \n \"SHA1\": [\"constraint\"], \n \"SHA256\": [\"constraint\"], \n \"SHA384\": [\"constraint\"], \n \"SHA512\": [\"constraint\"], \n \"COALESCE\": [\"constraint\"], \n \"IF\": [\"constraint\"], \n \"STRLANG\": [\"constraint\"], \n \"STRDT\": [\"constraint\"], \n \"SAMETERM\": [\"constraint\"], \n \"ISIRI\": [\"constraint\"], \n \"ISURI\": [\"constraint\"], \n \"ISBLANK\": [\"constraint\"], \n \"ISLITERAL\": [\"constraint\"], \n \"ISNUMERIC\": [\"constraint\"], \n \"SUBSTR\": [\"constraint\"], \n \"REPLACE\": [\"constraint\"], \n \"REGEX\": [\"constraint\"], \n \"EXISTS\": [\"constraint\"], \n \"NOT\": [\"constraint\"], \n \"IRI_REF\": [\"constraint\"], \n \"PNAME_LN\": [\"constraint\"], \n \"PNAME_NS\": [\"constraint\"]}, \n \"inlineData\" : {\n \"VALUES\": [\"VALUES\",\"dataBlock\"]}, \n \"inlineDataFull\" : {\n \"NIL\": [\"or([NIL,[ (,*var,)]])\",\"{\",\"*or([[ (,*dataBlockValue,)],NIL])\",\"}\"], \n \"(\": [\"or([NIL,[ (,*var,)]])\",\"{\",\"*or([[ (,*dataBlockValue,)],NIL])\",\"}\"]}, \n \"inlineDataOneVar\" : {\n \"VAR1\": [\"var\",\"{\",\"*dataBlockValue\",\"}\"], \n \"VAR2\": [\"var\",\"{\",\"*dataBlockValue\",\"}\"]}, \n \"insert1\" : {\n \"DATA\": [\"DATA\",\"quadData\"], \n \"{\": [\"quadPattern\",\"*usingClause\",\"WHERE\",\"groupGraphPattern\"]}, \n \"insertClause\" : {\n \"INSERT\": [\"INSERT\",\"quadPattern\"]}, \n \"integer\" : {\n \"INTEGER\": [\"INTEGER\"]}, \n \"iriRef\" : {\n \"IRI_REF\": [\"IRI_REF\"], \n \"PNAME_LN\": [\"prefixedName\"], \n \"PNAME_NS\": [\"prefixedName\"]}, \n \"iriRefOrFunction\" : {\n \"IRI_REF\": [\"iriRef\",\"?argList\"], \n \"PNAME_LN\": [\"iriRef\",\"?argList\"], \n \"PNAME_NS\": [\"iriRef\",\"?argList\"]}, \n \"limitClause\" : {\n \"LIMIT\": [\"LIMIT\",\"INTEGER\"]}, \n \"limitOffsetClauses\" : {\n \"LIMIT\": [\"limitClause\",\"?offsetClause\"], \n \"OFFSET\": [\"offsetClause\",\"?limitClause\"]}, \n \"load\" : {\n \"LOAD\": [\"LOAD\",\"?SILENT_1\",\"iriRef\",\"?[INTO,graphRef]\"]}, \n \"minusGraphPattern\" : {\n \"MINUS\": [\"MINUS\",\"groupGraphPattern\"]}, \n \"modify\" : {\n \"WITH\": [\"WITH\",\"iriRef\",\"or([[deleteClause,?insertClause],insertClause])\",\"*usingClause\",\"WHERE\",\"groupGraphPattern\"]}, \n \"move\" : {\n \"MOVE\": [\"MOVE\",\"?SILENT_4\",\"graphOrDefault\",\"TO\",\"graphOrDefault\"]}, \n \"multiplicativeExpression\" : {\n \"!\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"+\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"-\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"VAR1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"VAR2\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"(\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"LANG\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"LANGMATCHES\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DATATYPE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"BOUND\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"IRI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"URI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"BNODE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"RAND\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ABS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"CEIL\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"FLOOR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ROUND\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"CONCAT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRLEN\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"UCASE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"LCASE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ENCODE_FOR_URI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"CONTAINS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRSTARTS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRENDS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRBEFORE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRAFTER\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"YEAR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MONTH\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DAY\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"HOURS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MINUTES\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SECONDS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"TIMEZONE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"TZ\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"NOW\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"UUID\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRUUID\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MD5\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA256\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA384\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SHA512\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"COALESCE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"IF\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRLANG\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRDT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SAMETERM\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISIRI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISURI\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISBLANK\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISLITERAL\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"ISNUMERIC\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"TRUE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"FALSE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"COUNT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SUM\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MIN\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"MAX\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"AVG\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SAMPLE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"GROUP_CONCAT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"SUBSTR\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"REPLACE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"REGEX\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"EXISTS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"NOT\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"IRI_REF\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL2\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL_LONG1\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"STRING_LITERAL_LONG2\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER_POSITIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_POSITIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_POSITIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"INTEGER_NEGATIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DECIMAL_NEGATIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"DOUBLE_NEGATIVE\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"PNAME_LN\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"], \n \"PNAME_NS\": [\"unaryExpression\",\"*or([[*,unaryExpression],[/,unaryExpression]])\"]}, \n \"namedGraphClause\" : {\n \"NAMED\": [\"NAMED\",\"sourceSelector\"]}, \n \"notExistsFunc\" : {\n \"NOT\": [\"NOT\",\"EXISTS\",\"groupGraphPattern\"]}, \n \"numericExpression\" : {\n \"!\": [\"additiveExpression\"], \n \"+\": [\"additiveExpression\"], \n \"-\": [\"additiveExpression\"], \n \"VAR1\": [\"additiveExpression\"], \n \"VAR2\": [\"additiveExpression\"], \n \"(\": [\"additiveExpression\"], \n \"STR\": [\"additiveExpression\"], \n \"LANG\": [\"additiveExpression\"], \n \"LANGMATCHES\": [\"additiveExpression\"], \n \"DATATYPE\": [\"additiveExpression\"], \n \"BOUND\": [\"additiveExpression\"], \n \"IRI\": [\"additiveExpression\"], \n \"URI\": [\"additiveExpression\"], \n \"BNODE\": [\"additiveExpression\"], \n \"RAND\": [\"additiveExpression\"], \n \"ABS\": [\"additiveExpression\"], \n \"CEIL\": [\"additiveExpression\"], \n \"FLOOR\": [\"additiveExpression\"], \n \"ROUND\": [\"additiveExpression\"], \n \"CONCAT\": [\"additiveExpression\"], \n \"STRLEN\": [\"additiveExpression\"], \n \"UCASE\": [\"additiveExpression\"], \n \"LCASE\": [\"additiveExpression\"], \n \"ENCODE_FOR_URI\": [\"additiveExpression\"], \n \"CONTAINS\": [\"additiveExpression\"], \n \"STRSTARTS\": [\"additiveExpression\"], \n \"STRENDS\": [\"additiveExpression\"], \n \"STRBEFORE\": [\"additiveExpression\"], \n \"STRAFTER\": [\"additiveExpression\"], \n \"YEAR\": [\"additiveExpression\"], \n \"MONTH\": [\"additiveExpression\"], \n \"DAY\": [\"additiveExpression\"], \n \"HOURS\": [\"additiveExpression\"], \n \"MINUTES\": [\"additiveExpression\"], \n \"SECONDS\": [\"additiveExpression\"], \n \"TIMEZONE\": [\"additiveExpression\"], \n \"TZ\": [\"additiveExpression\"], \n \"NOW\": [\"additiveExpression\"], \n \"UUID\": [\"additiveExpression\"], \n \"STRUUID\": [\"additiveExpression\"], \n \"MD5\": [\"additiveExpression\"], \n \"SHA1\": [\"additiveExpression\"], \n \"SHA256\": [\"additiveExpression\"], \n \"SHA384\": [\"additiveExpression\"], \n \"SHA512\": [\"additiveExpression\"], \n \"COALESCE\": [\"additiveExpression\"], \n \"IF\": [\"additiveExpression\"], \n \"STRLANG\": [\"additiveExpression\"], \n \"STRDT\": [\"additiveExpression\"], \n \"SAMETERM\": [\"additiveExpression\"], \n \"ISIRI\": [\"additiveExpression\"], \n \"ISURI\": [\"additiveExpression\"], \n \"ISBLANK\": [\"additiveExpression\"], \n \"ISLITERAL\": [\"additiveExpression\"], \n \"ISNUMERIC\": [\"additiveExpression\"], \n \"TRUE\": [\"additiveExpression\"], \n \"FALSE\": [\"additiveExpression\"], \n \"COUNT\": [\"additiveExpression\"], \n \"SUM\": [\"additiveExpression\"], \n \"MIN\": [\"additiveExpression\"], \n \"MAX\": [\"additiveExpression\"], \n \"AVG\": [\"additiveExpression\"], \n \"SAMPLE\": [\"additiveExpression\"], \n \"GROUP_CONCAT\": [\"additiveExpression\"], \n \"SUBSTR\": [\"additiveExpression\"], \n \"REPLACE\": [\"additiveExpression\"], \n \"REGEX\": [\"additiveExpression\"], \n \"EXISTS\": [\"additiveExpression\"], \n \"NOT\": [\"additiveExpression\"], \n \"IRI_REF\": [\"additiveExpression\"], \n \"STRING_LITERAL1\": [\"additiveExpression\"], \n \"STRING_LITERAL2\": [\"additiveExpression\"], \n \"STRING_LITERAL_LONG1\": [\"additiveExpression\"], \n \"STRING_LITERAL_LONG2\": [\"additiveExpression\"], \n \"INTEGER\": [\"additiveExpression\"], \n \"DECIMAL\": [\"additiveExpression\"], \n \"DOUBLE\": [\"additiveExpression\"], \n \"INTEGER_POSITIVE\": [\"additiveExpression\"], \n \"DECIMAL_POSITIVE\": [\"additiveExpression\"], \n \"DOUBLE_POSITIVE\": [\"additiveExpression\"], \n \"INTEGER_NEGATIVE\": [\"additiveExpression\"], \n \"DECIMAL_NEGATIVE\": [\"additiveExpression\"], \n \"DOUBLE_NEGATIVE\": [\"additiveExpression\"], \n \"PNAME_LN\": [\"additiveExpression\"], \n \"PNAME_NS\": [\"additiveExpression\"]}, \n \"numericLiteral\" : {\n \"INTEGER\": [\"numericLiteralUnsigned\"], \n \"DECIMAL\": [\"numericLiteralUnsigned\"], \n \"DOUBLE\": [\"numericLiteralUnsigned\"], \n \"INTEGER_POSITIVE\": [\"numericLiteralPositive\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteralPositive\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteralPositive\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteralNegative\"]}, \n \"numericLiteralNegative\" : {\n \"INTEGER_NEGATIVE\": [\"INTEGER_NEGATIVE\"], \n \"DECIMAL_NEGATIVE\": [\"DECIMAL_NEGATIVE\"], \n \"DOUBLE_NEGATIVE\": [\"DOUBLE_NEGATIVE\"]}, \n \"numericLiteralPositive\" : {\n \"INTEGER_POSITIVE\": [\"INTEGER_POSITIVE\"], \n \"DECIMAL_POSITIVE\": [\"DECIMAL_POSITIVE\"], \n \"DOUBLE_POSITIVE\": [\"DOUBLE_POSITIVE\"]}, \n \"numericLiteralUnsigned\" : {\n \"INTEGER\": [\"INTEGER\"], \n \"DECIMAL\": [\"DECIMAL\"], \n \"DOUBLE\": [\"DOUBLE\"]}, \n \"object\" : {\n \"(\": [\"graphNode\"], \n \"[\": [\"graphNode\"], \n \"VAR1\": [\"graphNode\"], \n \"VAR2\": [\"graphNode\"], \n \"NIL\": [\"graphNode\"], \n \"IRI_REF\": [\"graphNode\"], \n \"TRUE\": [\"graphNode\"], \n \"FALSE\": [\"graphNode\"], \n \"BLANK_NODE_LABEL\": [\"graphNode\"], \n \"ANON\": [\"graphNode\"], \n \"PNAME_LN\": [\"graphNode\"], \n \"PNAME_NS\": [\"graphNode\"], \n \"STRING_LITERAL1\": [\"graphNode\"], \n \"STRING_LITERAL2\": [\"graphNode\"], \n \"STRING_LITERAL_LONG1\": [\"graphNode\"], \n \"STRING_LITERAL_LONG2\": [\"graphNode\"], \n \"INTEGER\": [\"graphNode\"], \n \"DECIMAL\": [\"graphNode\"], \n \"DOUBLE\": [\"graphNode\"], \n \"INTEGER_POSITIVE\": [\"graphNode\"], \n \"DECIMAL_POSITIVE\": [\"graphNode\"], \n \"DOUBLE_POSITIVE\": [\"graphNode\"], \n \"INTEGER_NEGATIVE\": [\"graphNode\"], \n \"DECIMAL_NEGATIVE\": [\"graphNode\"], \n \"DOUBLE_NEGATIVE\": [\"graphNode\"]}, \n \"objectList\" : {\n \"(\": [\"object\",\"*[,,object]\"], \n \"[\": [\"object\",\"*[,,object]\"], \n \"VAR1\": [\"object\",\"*[,,object]\"], \n \"VAR2\": [\"object\",\"*[,,object]\"], \n \"NIL\": [\"object\",\"*[,,object]\"], \n \"IRI_REF\": [\"object\",\"*[,,object]\"], \n \"TRUE\": [\"object\",\"*[,,object]\"], \n \"FALSE\": [\"object\",\"*[,,object]\"], \n \"BLANK_NODE_LABEL\": [\"object\",\"*[,,object]\"], \n \"ANON\": [\"object\",\"*[,,object]\"], \n \"PNAME_LN\": [\"object\",\"*[,,object]\"], \n \"PNAME_NS\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL1\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL2\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL_LONG1\": [\"object\",\"*[,,object]\"], \n \"STRING_LITERAL_LONG2\": [\"object\",\"*[,,object]\"], \n \"INTEGER\": [\"object\",\"*[,,object]\"], \n \"DECIMAL\": [\"object\",\"*[,,object]\"], \n \"DOUBLE\": [\"object\",\"*[,,object]\"], \n \"INTEGER_POSITIVE\": [\"object\",\"*[,,object]\"], \n \"DECIMAL_POSITIVE\": [\"object\",\"*[,,object]\"], \n \"DOUBLE_POSITIVE\": [\"object\",\"*[,,object]\"], \n \"INTEGER_NEGATIVE\": [\"object\",\"*[,,object]\"], \n \"DECIMAL_NEGATIVE\": [\"object\",\"*[,,object]\"], \n \"DOUBLE_NEGATIVE\": [\"object\",\"*[,,object]\"]}, \n \"objectListPath\" : {\n \"(\": [\"objectPath\",\"*[,,objectPath]\"], \n \"[\": [\"objectPath\",\"*[,,objectPath]\"], \n \"VAR1\": [\"objectPath\",\"*[,,objectPath]\"], \n \"VAR2\": [\"objectPath\",\"*[,,objectPath]\"], \n \"NIL\": [\"objectPath\",\"*[,,objectPath]\"], \n \"IRI_REF\": [\"objectPath\",\"*[,,objectPath]\"], \n \"TRUE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"FALSE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"BLANK_NODE_LABEL\": [\"objectPath\",\"*[,,objectPath]\"], \n \"ANON\": [\"objectPath\",\"*[,,objectPath]\"], \n \"PNAME_LN\": [\"objectPath\",\"*[,,objectPath]\"], \n \"PNAME_NS\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL1\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL2\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL_LONG1\": [\"objectPath\",\"*[,,objectPath]\"], \n \"STRING_LITERAL_LONG2\": [\"objectPath\",\"*[,,objectPath]\"], \n \"INTEGER\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DECIMAL\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DOUBLE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"INTEGER_POSITIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DECIMAL_POSITIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DOUBLE_POSITIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"INTEGER_NEGATIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DECIMAL_NEGATIVE\": [\"objectPath\",\"*[,,objectPath]\"], \n \"DOUBLE_NEGATIVE\": [\"objectPath\",\"*[,,objectPath]\"]}, \n \"objectPath\" : {\n \"(\": [\"graphNodePath\"], \n \"[\": [\"graphNodePath\"], \n \"VAR1\": [\"graphNodePath\"], \n \"VAR2\": [\"graphNodePath\"], \n \"NIL\": [\"graphNodePath\"], \n \"IRI_REF\": [\"graphNodePath\"], \n \"TRUE\": [\"graphNodePath\"], \n \"FALSE\": [\"graphNodePath\"], \n \"BLANK_NODE_LABEL\": [\"graphNodePath\"], \n \"ANON\": [\"graphNodePath\"], \n \"PNAME_LN\": [\"graphNodePath\"], \n \"PNAME_NS\": [\"graphNodePath\"], \n \"STRING_LITERAL1\": [\"graphNodePath\"], \n \"STRING_LITERAL2\": [\"graphNodePath\"], \n \"STRING_LITERAL_LONG1\": [\"graphNodePath\"], \n \"STRING_LITERAL_LONG2\": [\"graphNodePath\"], \n \"INTEGER\": [\"graphNodePath\"], \n \"DECIMAL\": [\"graphNodePath\"], \n \"DOUBLE\": [\"graphNodePath\"], \n \"INTEGER_POSITIVE\": [\"graphNodePath\"], \n \"DECIMAL_POSITIVE\": [\"graphNodePath\"], \n \"DOUBLE_POSITIVE\": [\"graphNodePath\"], \n \"INTEGER_NEGATIVE\": [\"graphNodePath\"], \n \"DECIMAL_NEGATIVE\": [\"graphNodePath\"], \n \"DOUBLE_NEGATIVE\": [\"graphNodePath\"]}, \n \"offsetClause\" : {\n \"OFFSET\": [\"OFFSET\",\"INTEGER\"]}, \n \"optionalGraphPattern\" : {\n \"OPTIONAL\": [\"OPTIONAL\",\"groupGraphPattern\"]}, \n \"or([*,expression])\" : {\n \"*\": [\"*\"], \n \"!\": [\"expression\"], \n \"+\": [\"expression\"], \n \"-\": [\"expression\"], \n \"VAR1\": [\"expression\"], \n \"VAR2\": [\"expression\"], \n \"(\": [\"expression\"], \n \"STR\": [\"expression\"], \n \"LANG\": [\"expression\"], \n \"LANGMATCHES\": [\"expression\"], \n \"DATATYPE\": [\"expression\"], \n \"BOUND\": [\"expression\"], \n \"IRI\": [\"expression\"], \n \"URI\": [\"expression\"], \n \"BNODE\": [\"expression\"], \n \"RAND\": [\"expression\"], \n \"ABS\": [\"expression\"], \n \"CEIL\": [\"expression\"], \n \"FLOOR\": [\"expression\"], \n \"ROUND\": [\"expression\"], \n \"CONCAT\": [\"expression\"], \n \"STRLEN\": [\"expression\"], \n \"UCASE\": [\"expression\"], \n \"LCASE\": [\"expression\"], \n \"ENCODE_FOR_URI\": [\"expression\"], \n \"CONTAINS\": [\"expression\"], \n \"STRSTARTS\": [\"expression\"], \n \"STRENDS\": [\"expression\"], \n \"STRBEFORE\": [\"expression\"], \n \"STRAFTER\": [\"expression\"], \n \"YEAR\": [\"expression\"], \n \"MONTH\": [\"expression\"], \n \"DAY\": [\"expression\"], \n \"HOURS\": [\"expression\"], \n \"MINUTES\": [\"expression\"], \n \"SECONDS\": [\"expression\"], \n \"TIMEZONE\": [\"expression\"], \n \"TZ\": [\"expression\"], \n \"NOW\": [\"expression\"], \n \"UUID\": [\"expression\"], \n \"STRUUID\": [\"expression\"], \n \"MD5\": [\"expression\"], \n \"SHA1\": [\"expression\"], \n \"SHA256\": [\"expression\"], \n \"SHA384\": [\"expression\"], \n \"SHA512\": [\"expression\"], \n \"COALESCE\": [\"expression\"], \n \"IF\": [\"expression\"], \n \"STRLANG\": [\"expression\"], \n \"STRDT\": [\"expression\"], \n \"SAMETERM\": [\"expression\"], \n \"ISIRI\": [\"expression\"], \n \"ISURI\": [\"expression\"], \n \"ISBLANK\": [\"expression\"], \n \"ISLITERAL\": [\"expression\"], \n \"ISNUMERIC\": [\"expression\"], \n \"TRUE\": [\"expression\"], \n \"FALSE\": [\"expression\"], \n \"COUNT\": [\"expression\"], \n \"SUM\": [\"expression\"], \n \"MIN\": [\"expression\"], \n \"MAX\": [\"expression\"], \n \"AVG\": [\"expression\"], \n \"SAMPLE\": [\"expression\"], \n \"GROUP_CONCAT\": [\"expression\"], \n \"SUBSTR\": [\"expression\"], \n \"REPLACE\": [\"expression\"], \n \"REGEX\": [\"expression\"], \n \"EXISTS\": [\"expression\"], \n \"NOT\": [\"expression\"], \n \"IRI_REF\": [\"expression\"], \n \"STRING_LITERAL1\": [\"expression\"], \n \"STRING_LITERAL2\": [\"expression\"], \n \"STRING_LITERAL_LONG1\": [\"expression\"], \n \"STRING_LITERAL_LONG2\": [\"expression\"], \n \"INTEGER\": [\"expression\"], \n \"DECIMAL\": [\"expression\"], \n \"DOUBLE\": [\"expression\"], \n \"INTEGER_POSITIVE\": [\"expression\"], \n \"DECIMAL_POSITIVE\": [\"expression\"], \n \"DOUBLE_POSITIVE\": [\"expression\"], \n \"INTEGER_NEGATIVE\": [\"expression\"], \n \"DECIMAL_NEGATIVE\": [\"expression\"], \n \"DOUBLE_NEGATIVE\": [\"expression\"], \n \"PNAME_LN\": [\"expression\"], \n \"PNAME_NS\": [\"expression\"]}, \n \"or([+or([var,[ (,expression,AS,var,)]]),*])\" : {\n \"(\": [\"+or([var,[ (,expression,AS,var,)]])\"], \n \"VAR1\": [\"+or([var,[ (,expression,AS,var,)]])\"], \n \"VAR2\": [\"+or([var,[ (,expression,AS,var,)]])\"], \n \"*\": [\"*\"]}, \n \"or([+varOrIRIref,*])\" : {\n \"VAR1\": [\"+varOrIRIref\"], \n \"VAR2\": [\"+varOrIRIref\"], \n \"IRI_REF\": [\"+varOrIRIref\"], \n \"PNAME_LN\": [\"+varOrIRIref\"], \n \"PNAME_NS\": [\"+varOrIRIref\"], \n \"*\": [\"*\"]}, \n \"or([ASC,DESC])\" : {\n \"ASC\": [\"ASC\"], \n \"DESC\": [\"DESC\"]}, \n \"or([DISTINCT,REDUCED])\" : {\n \"DISTINCT\": [\"DISTINCT\"], \n \"REDUCED\": [\"REDUCED\"]}, \n \"or([LANGTAG,[^^,iriRef]])\" : {\n \"LANGTAG\": [\"LANGTAG\"], \n \"^^\": [\"[^^,iriRef]\"]}, \n \"or([NIL,[ (,*var,)]])\" : {\n \"NIL\": [\"NIL\"], \n \"(\": [\"[ (,*var,)]\"]}, \n \"or([[ (,*dataBlockValue,)],NIL])\" : {\n \"(\": [\"[ (,*dataBlockValue,)]\"], \n \"NIL\": [\"NIL\"]}, \n \"or([[ (,expression,)],NIL])\" : {\n \"(\": [\"[ (,expression,)]\"], \n \"NIL\": [\"NIL\"]}, \n \"or([[*,unaryExpression],[/,unaryExpression]])\" : {\n \"*\": [\"[*,unaryExpression]\"], \n \"/\": [\"[/,unaryExpression]\"]}, \n \"or([[+,multiplicativeExpression],[-,multiplicativeExpression],[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]])\" : {\n \"+\": [\"[+,multiplicativeExpression]\"], \n \"-\": [\"[-,multiplicativeExpression]\"], \n \"INTEGER_POSITIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DECIMAL_POSITIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DOUBLE_POSITIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"INTEGER_NEGATIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DECIMAL_NEGATIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"], \n \"DOUBLE_NEGATIVE\": [\"[or([numericLiteralPositive,numericLiteralNegative]),?or([[*,unaryExpression],[/,unaryExpression]])]\"]}, \n \"or([[,,or([},[integer,}]])],}])\" : {\n \",\": [\"[,,or([},[integer,}]])]\"], \n \"}\": [\"}\"]}, \n \"or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\" : {\n \"=\": [\"[=,numericExpression]\"], \n \"!=\": [\"[!=,numericExpression]\"], \n \"<\": [\"[<,numericExpression]\"], \n \">\": [\"[>,numericExpression]\"], \n \"<=\": [\"[<=,numericExpression]\"], \n \">=\": [\"[>=,numericExpression]\"], \n \"IN\": [\"[IN,expressionList]\"], \n \"NOT\": [\"[NOT,IN,expressionList]\"]}, \n \"or([[constructTemplate,*datasetClause,whereClause,solutionModifier],[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]])\" : {\n \"{\": [\"[constructTemplate,*datasetClause,whereClause,solutionModifier]\"], \n \"WHERE\": [\"[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]\"], \n \"FROM\": [\"[*datasetClause,WHERE,{,?triplesTemplate,},solutionModifier]\"]}, \n \"or([[deleteClause,?insertClause],insertClause])\" : {\n \"DELETE\": [\"[deleteClause,?insertClause]\"], \n \"INSERT\": [\"insertClause\"]}, \n \"or([[integer,or([[,,or([},[integer,}]])],}])],[,,integer,}]])\" : {\n \"INTEGER\": [\"[integer,or([[,,or([},[integer,}]])],}])]\"], \n \",\": [\"[,,integer,}]\"]}, \n \"or([baseDecl,prefixDecl])\" : {\n \"BASE\": [\"baseDecl\"], \n \"PREFIX\": [\"prefixDecl\"]}, \n \"or([defaultGraphClause,namedGraphClause])\" : {\n \"IRI_REF\": [\"defaultGraphClause\"], \n \"PNAME_LN\": [\"defaultGraphClause\"], \n \"PNAME_NS\": [\"defaultGraphClause\"], \n \"NAMED\": [\"namedGraphClause\"]}, \n \"or([inlineDataOneVar,inlineDataFull])\" : {\n \"VAR1\": [\"inlineDataOneVar\"], \n \"VAR2\": [\"inlineDataOneVar\"], \n \"NIL\": [\"inlineDataFull\"], \n \"(\": [\"inlineDataFull\"]}, \n \"or([iriRef,[NAMED,iriRef]])\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"NAMED\": [\"[NAMED,iriRef]\"]}, \n \"or([iriRef,a])\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"a\": [\"a\"]}, \n \"or([numericLiteralPositive,numericLiteralNegative])\" : {\n \"INTEGER_POSITIVE\": [\"numericLiteralPositive\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteralPositive\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteralPositive\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteralNegative\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteralNegative\"]}, \n \"or([queryAll,updateAll])\" : {\n \"CONSTRUCT\": [\"queryAll\"], \n \"DESCRIBE\": [\"queryAll\"], \n \"ASK\": [\"queryAll\"], \n \"SELECT\": [\"queryAll\"], \n \"INSERT\": [\"updateAll\"], \n \"DELETE\": [\"updateAll\"], \n \"LOAD\": [\"updateAll\"], \n \"CLEAR\": [\"updateAll\"], \n \"DROP\": [\"updateAll\"], \n \"ADD\": [\"updateAll\"], \n \"MOVE\": [\"updateAll\"], \n \"COPY\": [\"updateAll\"], \n \"CREATE\": [\"updateAll\"], \n \"WITH\": [\"updateAll\"], \n \"$\": [\"updateAll\"]}, \n \"or([selectQuery,constructQuery,describeQuery,askQuery])\" : {\n \"SELECT\": [\"selectQuery\"], \n \"CONSTRUCT\": [\"constructQuery\"], \n \"DESCRIBE\": [\"describeQuery\"], \n \"ASK\": [\"askQuery\"]}, \n \"or([subSelect,groupGraphPatternSub])\" : {\n \"SELECT\": [\"subSelect\"], \n \"{\": [\"groupGraphPatternSub\"], \n \"OPTIONAL\": [\"groupGraphPatternSub\"], \n \"MINUS\": [\"groupGraphPatternSub\"], \n \"GRAPH\": [\"groupGraphPatternSub\"], \n \"SERVICE\": [\"groupGraphPatternSub\"], \n \"FILTER\": [\"groupGraphPatternSub\"], \n \"BIND\": [\"groupGraphPatternSub\"], \n \"VALUES\": [\"groupGraphPatternSub\"], \n \"VAR1\": [\"groupGraphPatternSub\"], \n \"VAR2\": [\"groupGraphPatternSub\"], \n \"NIL\": [\"groupGraphPatternSub\"], \n \"(\": [\"groupGraphPatternSub\"], \n \"[\": [\"groupGraphPatternSub\"], \n \"IRI_REF\": [\"groupGraphPatternSub\"], \n \"TRUE\": [\"groupGraphPatternSub\"], \n \"FALSE\": [\"groupGraphPatternSub\"], \n \"BLANK_NODE_LABEL\": [\"groupGraphPatternSub\"], \n \"ANON\": [\"groupGraphPatternSub\"], \n \"PNAME_LN\": [\"groupGraphPatternSub\"], \n \"PNAME_NS\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL1\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL2\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL_LONG1\": [\"groupGraphPatternSub\"], \n \"STRING_LITERAL_LONG2\": [\"groupGraphPatternSub\"], \n \"INTEGER\": [\"groupGraphPatternSub\"], \n \"DECIMAL\": [\"groupGraphPatternSub\"], \n \"DOUBLE\": [\"groupGraphPatternSub\"], \n \"INTEGER_POSITIVE\": [\"groupGraphPatternSub\"], \n \"DECIMAL_POSITIVE\": [\"groupGraphPatternSub\"], \n \"DOUBLE_POSITIVE\": [\"groupGraphPatternSub\"], \n \"INTEGER_NEGATIVE\": [\"groupGraphPatternSub\"], \n \"DECIMAL_NEGATIVE\": [\"groupGraphPatternSub\"], \n \"DOUBLE_NEGATIVE\": [\"groupGraphPatternSub\"], \n \"}\": [\"groupGraphPatternSub\"]}, \n \"or([var,[ (,expression,AS,var,)]])\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"(\": [\"[ (,expression,AS,var,)]\"]}, \n \"or([verbPath,verbSimple])\" : {\n \"^\": [\"verbPath\"], \n \"a\": [\"verbPath\"], \n \"!\": [\"verbPath\"], \n \"(\": [\"verbPath\"], \n \"IRI_REF\": [\"verbPath\"], \n \"PNAME_LN\": [\"verbPath\"], \n \"PNAME_NS\": [\"verbPath\"], \n \"VAR1\": [\"verbSimple\"], \n \"VAR2\": [\"verbSimple\"]}, \n \"or([},[integer,}]])\" : {\n \"}\": [\"}\"], \n \"INTEGER\": [\"[integer,}]\"]}, \n \"orderClause\" : {\n \"ORDER\": [\"ORDER\",\"BY\",\"+orderCondition\"]}, \n \"orderCondition\" : {\n \"ASC\": [\"or([ASC,DESC])\",\"brackettedExpression\"], \n \"DESC\": [\"or([ASC,DESC])\",\"brackettedExpression\"], \n \"(\": [\"constraint\"], \n \"STR\": [\"constraint\"], \n \"LANG\": [\"constraint\"], \n \"LANGMATCHES\": [\"constraint\"], \n \"DATATYPE\": [\"constraint\"], \n \"BOUND\": [\"constraint\"], \n \"IRI\": [\"constraint\"], \n \"URI\": [\"constraint\"], \n \"BNODE\": [\"constraint\"], \n \"RAND\": [\"constraint\"], \n \"ABS\": [\"constraint\"], \n \"CEIL\": [\"constraint\"], \n \"FLOOR\": [\"constraint\"], \n \"ROUND\": [\"constraint\"], \n \"CONCAT\": [\"constraint\"], \n \"STRLEN\": [\"constraint\"], \n \"UCASE\": [\"constraint\"], \n \"LCASE\": [\"constraint\"], \n \"ENCODE_FOR_URI\": [\"constraint\"], \n \"CONTAINS\": [\"constraint\"], \n \"STRSTARTS\": [\"constraint\"], \n \"STRENDS\": [\"constraint\"], \n \"STRBEFORE\": [\"constraint\"], \n \"STRAFTER\": [\"constraint\"], \n \"YEAR\": [\"constraint\"], \n \"MONTH\": [\"constraint\"], \n \"DAY\": [\"constraint\"], \n \"HOURS\": [\"constraint\"], \n \"MINUTES\": [\"constraint\"], \n \"SECONDS\": [\"constraint\"], \n \"TIMEZONE\": [\"constraint\"], \n \"TZ\": [\"constraint\"], \n \"NOW\": [\"constraint\"], \n \"UUID\": [\"constraint\"], \n \"STRUUID\": [\"constraint\"], \n \"MD5\": [\"constraint\"], \n \"SHA1\": [\"constraint\"], \n \"SHA256\": [\"constraint\"], \n \"SHA384\": [\"constraint\"], \n \"SHA512\": [\"constraint\"], \n \"COALESCE\": [\"constraint\"], \n \"IF\": [\"constraint\"], \n \"STRLANG\": [\"constraint\"], \n \"STRDT\": [\"constraint\"], \n \"SAMETERM\": [\"constraint\"], \n \"ISIRI\": [\"constraint\"], \n \"ISURI\": [\"constraint\"], \n \"ISBLANK\": [\"constraint\"], \n \"ISLITERAL\": [\"constraint\"], \n \"ISNUMERIC\": [\"constraint\"], \n \"SUBSTR\": [\"constraint\"], \n \"REPLACE\": [\"constraint\"], \n \"REGEX\": [\"constraint\"], \n \"EXISTS\": [\"constraint\"], \n \"NOT\": [\"constraint\"], \n \"IRI_REF\": [\"constraint\"], \n \"PNAME_LN\": [\"constraint\"], \n \"PNAME_NS\": [\"constraint\"], \n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"]}, \n \"path\" : {\n \"^\": [\"pathAlternative\"], \n \"a\": [\"pathAlternative\"], \n \"!\": [\"pathAlternative\"], \n \"(\": [\"pathAlternative\"], \n \"IRI_REF\": [\"pathAlternative\"], \n \"PNAME_LN\": [\"pathAlternative\"], \n \"PNAME_NS\": [\"pathAlternative\"]}, \n \"pathAlternative\" : {\n \"^\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"a\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"!\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"(\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"IRI_REF\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"PNAME_LN\": [\"pathSequence\",\"*[|,pathSequence]\"], \n \"PNAME_NS\": [\"pathSequence\",\"*[|,pathSequence]\"]}, \n \"pathElt\" : {\n \"a\": [\"pathPrimary\",\"?pathMod\"], \n \"!\": [\"pathPrimary\",\"?pathMod\"], \n \"(\": [\"pathPrimary\",\"?pathMod\"], \n \"IRI_REF\": [\"pathPrimary\",\"?pathMod\"], \n \"PNAME_LN\": [\"pathPrimary\",\"?pathMod\"], \n \"PNAME_NS\": [\"pathPrimary\",\"?pathMod\"]}, \n \"pathEltOrInverse\" : {\n \"a\": [\"pathElt\"], \n \"!\": [\"pathElt\"], \n \"(\": [\"pathElt\"], \n \"IRI_REF\": [\"pathElt\"], \n \"PNAME_LN\": [\"pathElt\"], \n \"PNAME_NS\": [\"pathElt\"], \n \"^\": [\"^\",\"pathElt\"]}, \n \"pathMod\" : {\n \"*\": [\"*\"], \n \"?\": [\"?\"], \n \"+\": [\"+\"], \n \"{\": [\"{\",\"or([[integer,or([[,,or([},[integer,}]])],}])],[,,integer,}]])\"]}, \n \"pathNegatedPropertySet\" : {\n \"a\": [\"pathOneInPropertySet\"], \n \"^\": [\"pathOneInPropertySet\"], \n \"IRI_REF\": [\"pathOneInPropertySet\"], \n \"PNAME_LN\": [\"pathOneInPropertySet\"], \n \"PNAME_NS\": [\"pathOneInPropertySet\"], \n \"(\": [\"(\",\"?[pathOneInPropertySet,*[|,pathOneInPropertySet]]\",\")\"]}, \n \"pathOneInPropertySet\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"], \n \"a\": [\"a\"], \n \"^\": [\"^\",\"or([iriRef,a])\"]}, \n \"pathPrimary\" : {\n \"IRI_REF\": [\"storeProperty\",\"iriRef\"], \n \"PNAME_LN\": [\"storeProperty\",\"iriRef\"], \n \"PNAME_NS\": [\"storeProperty\",\"iriRef\"], \n \"a\": [\"storeProperty\",\"a\"], \n \"!\": [\"!\",\"pathNegatedPropertySet\"], \n \"(\": [\"(\",\"path\",\")\"]}, \n \"pathSequence\" : {\n \"^\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"a\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"!\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"(\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"IRI_REF\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"PNAME_LN\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"], \n \"PNAME_NS\": [\"pathEltOrInverse\",\"*[/,pathEltOrInverse]\"]}, \n \"prefixDecl\" : {\n \"PREFIX\": [\"PREFIX\",\"PNAME_NS\",\"IRI_REF\"]}, \n \"prefixedName\" : {\n \"PNAME_LN\": [\"PNAME_LN\"], \n \"PNAME_NS\": [\"PNAME_NS\"]}, \n \"primaryExpression\" : {\n \"(\": [\"brackettedExpression\"], \n \"STR\": [\"builtInCall\"], \n \"LANG\": [\"builtInCall\"], \n \"LANGMATCHES\": [\"builtInCall\"], \n \"DATATYPE\": [\"builtInCall\"], \n \"BOUND\": [\"builtInCall\"], \n \"IRI\": [\"builtInCall\"], \n \"URI\": [\"builtInCall\"], \n \"BNODE\": [\"builtInCall\"], \n \"RAND\": [\"builtInCall\"], \n \"ABS\": [\"builtInCall\"], \n \"CEIL\": [\"builtInCall\"], \n \"FLOOR\": [\"builtInCall\"], \n \"ROUND\": [\"builtInCall\"], \n \"CONCAT\": [\"builtInCall\"], \n \"STRLEN\": [\"builtInCall\"], \n \"UCASE\": [\"builtInCall\"], \n \"LCASE\": [\"builtInCall\"], \n \"ENCODE_FOR_URI\": [\"builtInCall\"], \n \"CONTAINS\": [\"builtInCall\"], \n \"STRSTARTS\": [\"builtInCall\"], \n \"STRENDS\": [\"builtInCall\"], \n \"STRBEFORE\": [\"builtInCall\"], \n \"STRAFTER\": [\"builtInCall\"], \n \"YEAR\": [\"builtInCall\"], \n \"MONTH\": [\"builtInCall\"], \n \"DAY\": [\"builtInCall\"], \n \"HOURS\": [\"builtInCall\"], \n \"MINUTES\": [\"builtInCall\"], \n \"SECONDS\": [\"builtInCall\"], \n \"TIMEZONE\": [\"builtInCall\"], \n \"TZ\": [\"builtInCall\"], \n \"NOW\": [\"builtInCall\"], \n \"UUID\": [\"builtInCall\"], \n \"STRUUID\": [\"builtInCall\"], \n \"MD5\": [\"builtInCall\"], \n \"SHA1\": [\"builtInCall\"], \n \"SHA256\": [\"builtInCall\"], \n \"SHA384\": [\"builtInCall\"], \n \"SHA512\": [\"builtInCall\"], \n \"COALESCE\": [\"builtInCall\"], \n \"IF\": [\"builtInCall\"], \n \"STRLANG\": [\"builtInCall\"], \n \"STRDT\": [\"builtInCall\"], \n \"SAMETERM\": [\"builtInCall\"], \n \"ISIRI\": [\"builtInCall\"], \n \"ISURI\": [\"builtInCall\"], \n \"ISBLANK\": [\"builtInCall\"], \n \"ISLITERAL\": [\"builtInCall\"], \n \"ISNUMERIC\": [\"builtInCall\"], \n \"SUBSTR\": [\"builtInCall\"], \n \"REPLACE\": [\"builtInCall\"], \n \"REGEX\": [\"builtInCall\"], \n \"EXISTS\": [\"builtInCall\"], \n \"NOT\": [\"builtInCall\"], \n \"IRI_REF\": [\"iriRefOrFunction\"], \n \"PNAME_LN\": [\"iriRefOrFunction\"], \n \"PNAME_NS\": [\"iriRefOrFunction\"], \n \"STRING_LITERAL1\": [\"rdfLiteral\"], \n \"STRING_LITERAL2\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG1\": [\"rdfLiteral\"], \n \"STRING_LITERAL_LONG2\": [\"rdfLiteral\"], \n \"INTEGER\": [\"numericLiteral\"], \n \"DECIMAL\": [\"numericLiteral\"], \n \"DOUBLE\": [\"numericLiteral\"], \n \"INTEGER_POSITIVE\": [\"numericLiteral\"], \n \"DECIMAL_POSITIVE\": [\"numericLiteral\"], \n \"DOUBLE_POSITIVE\": [\"numericLiteral\"], \n \"INTEGER_NEGATIVE\": [\"numericLiteral\"], \n \"DECIMAL_NEGATIVE\": [\"numericLiteral\"], \n \"DOUBLE_NEGATIVE\": [\"numericLiteral\"], \n \"TRUE\": [\"booleanLiteral\"], \n \"FALSE\": [\"booleanLiteral\"], \n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"COUNT\": [\"aggregate\"], \n \"SUM\": [\"aggregate\"], \n \"MIN\": [\"aggregate\"], \n \"MAX\": [\"aggregate\"], \n \"AVG\": [\"aggregate\"], \n \"SAMPLE\": [\"aggregate\"], \n \"GROUP_CONCAT\": [\"aggregate\"]}, \n \"prologue\" : {\n \"BASE\": [\"*or([baseDecl,prefixDecl])\"], \n \"PREFIX\": [\"*or([baseDecl,prefixDecl])\"], \n \"$\": [\"*or([baseDecl,prefixDecl])\"], \n \"CONSTRUCT\": [\"*or([baseDecl,prefixDecl])\"], \n \"DESCRIBE\": [\"*or([baseDecl,prefixDecl])\"], \n \"ASK\": [\"*or([baseDecl,prefixDecl])\"], \n \"INSERT\": [\"*or([baseDecl,prefixDecl])\"], \n \"DELETE\": [\"*or([baseDecl,prefixDecl])\"], \n \"SELECT\": [\"*or([baseDecl,prefixDecl])\"], \n \"LOAD\": [\"*or([baseDecl,prefixDecl])\"], \n \"CLEAR\": [\"*or([baseDecl,prefixDecl])\"], \n \"DROP\": [\"*or([baseDecl,prefixDecl])\"], \n \"ADD\": [\"*or([baseDecl,prefixDecl])\"], \n \"MOVE\": [\"*or([baseDecl,prefixDecl])\"], \n \"COPY\": [\"*or([baseDecl,prefixDecl])\"], \n \"CREATE\": [\"*or([baseDecl,prefixDecl])\"], \n \"WITH\": [\"*or([baseDecl,prefixDecl])\"]}, \n \"propertyList\" : {\n \"a\": [\"propertyListNotEmpty\"], \n \"VAR1\": [\"propertyListNotEmpty\"], \n \"VAR2\": [\"propertyListNotEmpty\"], \n \"IRI_REF\": [\"propertyListNotEmpty\"], \n \"PNAME_LN\": [\"propertyListNotEmpty\"], \n \"PNAME_NS\": [\"propertyListNotEmpty\"], \n \".\": [], \n \"}\": [], \n \"GRAPH\": []}, \n \"propertyListNotEmpty\" : {\n \"a\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"VAR1\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"VAR2\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"IRI_REF\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"PNAME_LN\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"], \n \"PNAME_NS\": [\"verb\",\"objectList\",\"*[;,?[verb,objectList]]\"]}, \n \"propertyListPath\" : {\n \"a\": [\"propertyListNotEmpty\"], \n \"VAR1\": [\"propertyListNotEmpty\"], \n \"VAR2\": [\"propertyListNotEmpty\"], \n \"IRI_REF\": [\"propertyListNotEmpty\"], \n \"PNAME_LN\": [\"propertyListNotEmpty\"], \n \"PNAME_NS\": [\"propertyListNotEmpty\"], \n \".\": [], \n \"{\": [], \n \"OPTIONAL\": [], \n \"MINUS\": [], \n \"GRAPH\": [], \n \"SERVICE\": [], \n \"FILTER\": [], \n \"BIND\": [], \n \"VALUES\": [], \n \"}\": []}, \n \"propertyListPathNotEmpty\" : {\n \"VAR1\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"VAR2\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"^\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"a\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"!\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"(\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"IRI_REF\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"PNAME_LN\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"], \n \"PNAME_NS\": [\"or([verbPath,verbSimple])\",\"objectListPath\",\"*[;,?[or([verbPath,verbSimple]),objectList]]\"]}, \n \"quadData\" : {\n \"{\": [\"{\",\"disallowVars\",\"quads\",\"allowVars\",\"}\"]}, \n \"quadDataNoBnodes\" : {\n \"{\": [\"{\",\"disallowBnodes\",\"disallowVars\",\"quads\",\"allowVars\",\"allowBnodes\",\"}\"]}, \n \"quadPattern\" : {\n \"{\": [\"{\",\"quads\",\"}\"]}, \n \"quadPatternNoBnodes\" : {\n \"{\": [\"{\",\"disallowBnodes\",\"quads\",\"allowBnodes\",\"}\"]}, \n \"quads\" : {\n \"GRAPH\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"VAR1\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"VAR2\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"NIL\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"(\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"[\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"IRI_REF\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"TRUE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"FALSE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"BLANK_NODE_LABEL\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"ANON\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"PNAME_LN\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"PNAME_NS\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL1\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL2\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG1\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG2\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"INTEGER\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DECIMAL\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DOUBLE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"INTEGER_POSITIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DECIMAL_POSITIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DOUBLE_POSITIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"INTEGER_NEGATIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DECIMAL_NEGATIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"DOUBLE_NEGATIVE\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"], \n \"}\": [\"?triplesTemplate\",\"*[quadsNotTriples,?.,?triplesTemplate]\"]}, \n \"quadsNotTriples\" : {\n \"GRAPH\": [\"GRAPH\",\"varOrIRIref\",\"{\",\"?triplesTemplate\",\"}\"]}, \n \"queryAll\" : {\n \"CONSTRUCT\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"], \n \"DESCRIBE\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"], \n \"ASK\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"], \n \"SELECT\": [\"or([selectQuery,constructQuery,describeQuery,askQuery])\",\"valuesClause\"]}, \n \"rdfLiteral\" : {\n \"STRING_LITERAL1\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"], \n \"STRING_LITERAL2\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"], \n \"STRING_LITERAL_LONG1\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"], \n \"STRING_LITERAL_LONG2\": [\"string\",\"?or([LANGTAG,[^^,iriRef]])\"]}, \n \"regexExpression\" : {\n \"REGEX\": [\"REGEX\",\"(\",\"expression\",\",\",\"expression\",\"?[,,expression]\",\")\"]}, \n \"relationalExpression\" : {\n \"!\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"+\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"-\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"VAR1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"VAR2\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"(\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"LANG\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"LANGMATCHES\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DATATYPE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"BOUND\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IRI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"URI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"BNODE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"RAND\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ABS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"CEIL\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"FLOOR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ROUND\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"CONCAT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRLEN\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"UCASE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"LCASE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ENCODE_FOR_URI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"CONTAINS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRSTARTS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRENDS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRBEFORE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRAFTER\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"YEAR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MONTH\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DAY\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"HOURS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MINUTES\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SECONDS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"TIMEZONE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"TZ\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"NOW\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"UUID\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRUUID\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MD5\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA256\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA384\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SHA512\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"COALESCE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IF\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRLANG\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRDT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SAMETERM\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISIRI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISURI\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISBLANK\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISLITERAL\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"ISNUMERIC\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"TRUE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"FALSE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"COUNT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SUM\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MIN\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"MAX\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"AVG\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SAMPLE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"GROUP_CONCAT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"SUBSTR\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"REPLACE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"REGEX\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"EXISTS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"NOT\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"IRI_REF\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL2\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL_LONG1\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"STRING_LITERAL_LONG2\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"INTEGER\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DECIMAL\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DOUBLE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"INTEGER_POSITIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DECIMAL_POSITIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DOUBLE_POSITIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"INTEGER_NEGATIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DECIMAL_NEGATIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"DOUBLE_NEGATIVE\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"PNAME_LN\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"], \n \"PNAME_NS\": [\"numericExpression\",\"?or([[=,numericExpression],[!=,numericExpression],[<,numericExpression],[>,numericExpression],[<=,numericExpression],[>=,numericExpression],[IN,expressionList],[NOT,IN,expressionList]])\"]}, \n \"selectClause\" : {\n \"SELECT\": [\"SELECT\",\"?or([DISTINCT,REDUCED])\",\"or([+or([var,[ (,expression,AS,var,)]]),*])\"]}, \n \"selectQuery\" : {\n \"SELECT\": [\"selectClause\",\"*datasetClause\",\"whereClause\",\"solutionModifier\"]}, \n \"serviceGraphPattern\" : {\n \"SERVICE\": [\"SERVICE\",\"?SILENT\",\"varOrIRIref\",\"groupGraphPattern\"]}, \n \"solutionModifier\" : {\n \"LIMIT\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"OFFSET\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"ORDER\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"HAVING\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"GROUP\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"VALUES\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"$\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"], \n \"}\": [\"?groupClause\",\"?havingClause\",\"?orderClause\",\"?limitOffsetClauses\"]}, \n \"sourceSelector\" : {\n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"]}, \n \"sparql11\" : {\n \"$\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"CONSTRUCT\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"DESCRIBE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"ASK\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"INSERT\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"DELETE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"SELECT\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"LOAD\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"CLEAR\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"DROP\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"ADD\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"MOVE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"COPY\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"CREATE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"WITH\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"BASE\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"], \n \"PREFIX\": [\"prologue\",\"or([queryAll,updateAll])\",\"$\"]}, \n \"storeProperty\" : {\n \"VAR1\": [], \n \"VAR2\": [], \n \"IRI_REF\": [], \n \"PNAME_LN\": [], \n \"PNAME_NS\": [], \n \"a\": []}, \n \"strReplaceExpression\" : {\n \"REPLACE\": [\"REPLACE\",\"(\",\"expression\",\",\",\"expression\",\",\",\"expression\",\"?[,,expression]\",\")\"]}, \n \"string\" : {\n \"STRING_LITERAL1\": [\"STRING_LITERAL1\"], \n \"STRING_LITERAL2\": [\"STRING_LITERAL2\"], \n \"STRING_LITERAL_LONG1\": [\"STRING_LITERAL_LONG1\"], \n \"STRING_LITERAL_LONG2\": [\"STRING_LITERAL_LONG2\"]}, \n \"subSelect\" : {\n \"SELECT\": [\"selectClause\",\"whereClause\",\"solutionModifier\",\"valuesClause\"]}, \n \"substringExpression\" : {\n \"SUBSTR\": [\"SUBSTR\",\"(\",\"expression\",\",\",\"expression\",\"?[,,expression]\",\")\"]}, \n \"triplesBlock\" : {\n \"VAR1\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"VAR2\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"NIL\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"(\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"[\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"IRI_REF\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"TRUE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"FALSE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"BLANK_NODE_LABEL\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"ANON\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"PNAME_LN\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"PNAME_NS\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL1\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL2\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG1\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"STRING_LITERAL_LONG2\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"INTEGER\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DECIMAL\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DOUBLE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"INTEGER_POSITIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DECIMAL_POSITIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DOUBLE_POSITIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"INTEGER_NEGATIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DECIMAL_NEGATIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"], \n \"DOUBLE_NEGATIVE\": [\"triplesSameSubjectPath\",\"?[.,?triplesBlock]\"]}, \n \"triplesNode\" : {\n \"(\": [\"collection\"], \n \"[\": [\"blankNodePropertyList\"]}, \n \"triplesNodePath\" : {\n \"(\": [\"collectionPath\"], \n \"[\": [\"blankNodePropertyListPath\"]}, \n \"triplesSameSubject\" : {\n \"VAR1\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"VAR2\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"NIL\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"IRI_REF\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"TRUE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"FALSE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"ANON\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"PNAME_LN\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"PNAME_NS\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL1\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL2\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"INTEGER\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DECIMAL\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DOUBLE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\",\"propertyListNotEmpty\"], \n \"(\": [\"triplesNode\",\"propertyList\"], \n \"[\": [\"triplesNode\",\"propertyList\"]}, \n \"triplesSameSubjectPath\" : {\n \"VAR1\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"VAR2\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"NIL\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"IRI_REF\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"TRUE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"FALSE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"BLANK_NODE_LABEL\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"ANON\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"PNAME_LN\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"PNAME_NS\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL1\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL2\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL_LONG1\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"STRING_LITERAL_LONG2\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"INTEGER\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DECIMAL\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DOUBLE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"INTEGER_POSITIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DECIMAL_POSITIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DOUBLE_POSITIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"INTEGER_NEGATIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DECIMAL_NEGATIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"DOUBLE_NEGATIVE\": [\"varOrTerm\",\"propertyListPathNotEmpty\"], \n \"(\": [\"triplesNodePath\",\"propertyListPath\"], \n \"[\": [\"triplesNodePath\",\"propertyListPath\"]}, \n \"triplesTemplate\" : {\n \"VAR1\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"VAR2\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"NIL\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"(\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"[\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"IRI_REF\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"TRUE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"FALSE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"BLANK_NODE_LABEL\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"ANON\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"PNAME_LN\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"PNAME_NS\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL1\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL2\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG1\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"STRING_LITERAL_LONG2\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"INTEGER\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DECIMAL\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DOUBLE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"INTEGER_POSITIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DECIMAL_POSITIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DOUBLE_POSITIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"INTEGER_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DECIMAL_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"], \n \"DOUBLE_NEGATIVE\": [\"triplesSameSubject\",\"?[.,?triplesTemplate]\"]}, \n \"unaryExpression\" : {\n \"!\": [\"!\",\"primaryExpression\"], \n \"+\": [\"+\",\"primaryExpression\"], \n \"-\": [\"-\",\"primaryExpression\"], \n \"VAR1\": [\"primaryExpression\"], \n \"VAR2\": [\"primaryExpression\"], \n \"(\": [\"primaryExpression\"], \n \"STR\": [\"primaryExpression\"], \n \"LANG\": [\"primaryExpression\"], \n \"LANGMATCHES\": [\"primaryExpression\"], \n \"DATATYPE\": [\"primaryExpression\"], \n \"BOUND\": [\"primaryExpression\"], \n \"IRI\": [\"primaryExpression\"], \n \"URI\": [\"primaryExpression\"], \n \"BNODE\": [\"primaryExpression\"], \n \"RAND\": [\"primaryExpression\"], \n \"ABS\": [\"primaryExpression\"], \n \"CEIL\": [\"primaryExpression\"], \n \"FLOOR\": [\"primaryExpression\"], \n \"ROUND\": [\"primaryExpression\"], \n \"CONCAT\": [\"primaryExpression\"], \n \"STRLEN\": [\"primaryExpression\"], \n \"UCASE\": [\"primaryExpression\"], \n \"LCASE\": [\"primaryExpression\"], \n \"ENCODE_FOR_URI\": [\"primaryExpression\"], \n \"CONTAINS\": [\"primaryExpression\"], \n \"STRSTARTS\": [\"primaryExpression\"], \n \"STRENDS\": [\"primaryExpression\"], \n \"STRBEFORE\": [\"primaryExpression\"], \n \"STRAFTER\": [\"primaryExpression\"], \n \"YEAR\": [\"primaryExpression\"], \n \"MONTH\": [\"primaryExpression\"], \n \"DAY\": [\"primaryExpression\"], \n \"HOURS\": [\"primaryExpression\"], \n \"MINUTES\": [\"primaryExpression\"], \n \"SECONDS\": [\"primaryExpression\"], \n \"TIMEZONE\": [\"primaryExpression\"], \n \"TZ\": [\"primaryExpression\"], \n \"NOW\": [\"primaryExpression\"], \n \"UUID\": [\"primaryExpression\"], \n \"STRUUID\": [\"primaryExpression\"], \n \"MD5\": [\"primaryExpression\"], \n \"SHA1\": [\"primaryExpression\"], \n \"SHA256\": [\"primaryExpression\"], \n \"SHA384\": [\"primaryExpression\"], \n \"SHA512\": [\"primaryExpression\"], \n \"COALESCE\": [\"primaryExpression\"], \n \"IF\": [\"primaryExpression\"], \n \"STRLANG\": [\"primaryExpression\"], \n \"STRDT\": [\"primaryExpression\"], \n \"SAMETERM\": [\"primaryExpression\"], \n \"ISIRI\": [\"primaryExpression\"], \n \"ISURI\": [\"primaryExpression\"], \n \"ISBLANK\": [\"primaryExpression\"], \n \"ISLITERAL\": [\"primaryExpression\"], \n \"ISNUMERIC\": [\"primaryExpression\"], \n \"TRUE\": [\"primaryExpression\"], \n \"FALSE\": [\"primaryExpression\"], \n \"COUNT\": [\"primaryExpression\"], \n \"SUM\": [\"primaryExpression\"], \n \"MIN\": [\"primaryExpression\"], \n \"MAX\": [\"primaryExpression\"], \n \"AVG\": [\"primaryExpression\"], \n \"SAMPLE\": [\"primaryExpression\"], \n \"GROUP_CONCAT\": [\"primaryExpression\"], \n \"SUBSTR\": [\"primaryExpression\"], \n \"REPLACE\": [\"primaryExpression\"], \n \"REGEX\": [\"primaryExpression\"], \n \"EXISTS\": [\"primaryExpression\"], \n \"NOT\": [\"primaryExpression\"], \n \"IRI_REF\": [\"primaryExpression\"], \n \"STRING_LITERAL1\": [\"primaryExpression\"], \n \"STRING_LITERAL2\": [\"primaryExpression\"], \n \"STRING_LITERAL_LONG1\": [\"primaryExpression\"], \n \"STRING_LITERAL_LONG2\": [\"primaryExpression\"], \n \"INTEGER\": [\"primaryExpression\"], \n \"DECIMAL\": [\"primaryExpression\"], \n \"DOUBLE\": [\"primaryExpression\"], \n \"INTEGER_POSITIVE\": [\"primaryExpression\"], \n \"DECIMAL_POSITIVE\": [\"primaryExpression\"], \n \"DOUBLE_POSITIVE\": [\"primaryExpression\"], \n \"INTEGER_NEGATIVE\": [\"primaryExpression\"], \n \"DECIMAL_NEGATIVE\": [\"primaryExpression\"], \n \"DOUBLE_NEGATIVE\": [\"primaryExpression\"], \n \"PNAME_LN\": [\"primaryExpression\"], \n \"PNAME_NS\": [\"primaryExpression\"]}, \n \"update\" : {\n \"INSERT\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"DELETE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"LOAD\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"CLEAR\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"DROP\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"ADD\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"MOVE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"COPY\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"CREATE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"WITH\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"BASE\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"PREFIX\": [\"prologue\",\"?[update1,?[;,update]]\"], \n \"$\": [\"prologue\",\"?[update1,?[;,update]]\"]}, \n \"update1\" : {\n \"LOAD\": [\"load\"], \n \"CLEAR\": [\"clear\"], \n \"DROP\": [\"drop\"], \n \"ADD\": [\"add\"], \n \"MOVE\": [\"move\"], \n \"COPY\": [\"copy\"], \n \"CREATE\": [\"create\"], \n \"INSERT\": [\"INSERT\",\"insert1\"], \n \"DELETE\": [\"DELETE\",\"delete1\"], \n \"WITH\": [\"modify\"]}, \n \"updateAll\" : {\n \"INSERT\": [\"?[update1,?[;,update]]\"], \n \"DELETE\": [\"?[update1,?[;,update]]\"], \n \"LOAD\": [\"?[update1,?[;,update]]\"], \n \"CLEAR\": [\"?[update1,?[;,update]]\"], \n \"DROP\": [\"?[update1,?[;,update]]\"], \n \"ADD\": [\"?[update1,?[;,update]]\"], \n \"MOVE\": [\"?[update1,?[;,update]]\"], \n \"COPY\": [\"?[update1,?[;,update]]\"], \n \"CREATE\": [\"?[update1,?[;,update]]\"], \n \"WITH\": [\"?[update1,?[;,update]]\"], \n \"$\": [\"?[update1,?[;,update]]\"]}, \n \"usingClause\" : {\n \"USING\": [\"USING\",\"or([iriRef,[NAMED,iriRef]])\"]}, \n \"valueLogical\" : {\n \"!\": [\"relationalExpression\"], \n \"+\": [\"relationalExpression\"], \n \"-\": [\"relationalExpression\"], \n \"VAR1\": [\"relationalExpression\"], \n \"VAR2\": [\"relationalExpression\"], \n \"(\": [\"relationalExpression\"], \n \"STR\": [\"relationalExpression\"], \n \"LANG\": [\"relationalExpression\"], \n \"LANGMATCHES\": [\"relationalExpression\"], \n \"DATATYPE\": [\"relationalExpression\"], \n \"BOUND\": [\"relationalExpression\"], \n \"IRI\": [\"relationalExpression\"], \n \"URI\": [\"relationalExpression\"], \n \"BNODE\": [\"relationalExpression\"], \n \"RAND\": [\"relationalExpression\"], \n \"ABS\": [\"relationalExpression\"], \n \"CEIL\": [\"relationalExpression\"], \n \"FLOOR\": [\"relationalExpression\"], \n \"ROUND\": [\"relationalExpression\"], \n \"CONCAT\": [\"relationalExpression\"], \n \"STRLEN\": [\"relationalExpression\"], \n \"UCASE\": [\"relationalExpression\"], \n \"LCASE\": [\"relationalExpression\"], \n \"ENCODE_FOR_URI\": [\"relationalExpression\"], \n \"CONTAINS\": [\"relationalExpression\"], \n \"STRSTARTS\": [\"relationalExpression\"], \n \"STRENDS\": [\"relationalExpression\"], \n \"STRBEFORE\": [\"relationalExpression\"], \n \"STRAFTER\": [\"relationalExpression\"], \n \"YEAR\": [\"relationalExpression\"], \n \"MONTH\": [\"relationalExpression\"], \n \"DAY\": [\"relationalExpression\"], \n \"HOURS\": [\"relationalExpression\"], \n \"MINUTES\": [\"relationalExpression\"], \n \"SECONDS\": [\"relationalExpression\"], \n \"TIMEZONE\": [\"relationalExpression\"], \n \"TZ\": [\"relationalExpression\"], \n \"NOW\": [\"relationalExpression\"], \n \"UUID\": [\"relationalExpression\"], \n \"STRUUID\": [\"relationalExpression\"], \n \"MD5\": [\"relationalExpression\"], \n \"SHA1\": [\"relationalExpression\"], \n \"SHA256\": [\"relationalExpression\"], \n \"SHA384\": [\"relationalExpression\"], \n \"SHA512\": [\"relationalExpression\"], \n \"COALESCE\": [\"relationalExpression\"], \n \"IF\": [\"relationalExpression\"], \n \"STRLANG\": [\"relationalExpression\"], \n \"STRDT\": [\"relationalExpression\"], \n \"SAMETERM\": [\"relationalExpression\"], \n \"ISIRI\": [\"relationalExpression\"], \n \"ISURI\": [\"relationalExpression\"], \n \"ISBLANK\": [\"relationalExpression\"], \n \"ISLITERAL\": [\"relationalExpression\"], \n \"ISNUMERIC\": [\"relationalExpression\"], \n \"TRUE\": [\"relationalExpression\"], \n \"FALSE\": [\"relationalExpression\"], \n \"COUNT\": [\"relationalExpression\"], \n \"SUM\": [\"relationalExpression\"], \n \"MIN\": [\"relationalExpression\"], \n \"MAX\": [\"relationalExpression\"], \n \"AVG\": [\"relationalExpression\"], \n \"SAMPLE\": [\"relationalExpression\"], \n \"GROUP_CONCAT\": [\"relationalExpression\"], \n \"SUBSTR\": [\"relationalExpression\"], \n \"REPLACE\": [\"relationalExpression\"], \n \"REGEX\": [\"relationalExpression\"], \n \"EXISTS\": [\"relationalExpression\"], \n \"NOT\": [\"relationalExpression\"], \n \"IRI_REF\": [\"relationalExpression\"], \n \"STRING_LITERAL1\": [\"relationalExpression\"], \n \"STRING_LITERAL2\": [\"relationalExpression\"], \n \"STRING_LITERAL_LONG1\": [\"relationalExpression\"], \n \"STRING_LITERAL_LONG2\": [\"relationalExpression\"], \n \"INTEGER\": [\"relationalExpression\"], \n \"DECIMAL\": [\"relationalExpression\"], \n \"DOUBLE\": [\"relationalExpression\"], \n \"INTEGER_POSITIVE\": [\"relationalExpression\"], \n \"DECIMAL_POSITIVE\": [\"relationalExpression\"], \n \"DOUBLE_POSITIVE\": [\"relationalExpression\"], \n \"INTEGER_NEGATIVE\": [\"relationalExpression\"], \n \"DECIMAL_NEGATIVE\": [\"relationalExpression\"], \n \"DOUBLE_NEGATIVE\": [\"relationalExpression\"], \n \"PNAME_LN\": [\"relationalExpression\"], \n \"PNAME_NS\": [\"relationalExpression\"]}, \n \"valuesClause\" : {\n \"VALUES\": [\"VALUES\",\"dataBlock\"], \n \"$\": [], \n \"}\": []}, \n \"var\" : {\n \"VAR1\": [\"VAR1\"], \n \"VAR2\": [\"VAR2\"]}, \n \"varOrIRIref\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"IRI_REF\": [\"iriRef\"], \n \"PNAME_LN\": [\"iriRef\"], \n \"PNAME_NS\": [\"iriRef\"]}, \n \"varOrTerm\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"], \n \"NIL\": [\"graphTerm\"], \n \"IRI_REF\": [\"graphTerm\"], \n \"TRUE\": [\"graphTerm\"], \n \"FALSE\": [\"graphTerm\"], \n \"BLANK_NODE_LABEL\": [\"graphTerm\"], \n \"ANON\": [\"graphTerm\"], \n \"PNAME_LN\": [\"graphTerm\"], \n \"PNAME_NS\": [\"graphTerm\"], \n \"STRING_LITERAL1\": [\"graphTerm\"], \n \"STRING_LITERAL2\": [\"graphTerm\"], \n \"STRING_LITERAL_LONG1\": [\"graphTerm\"], \n \"STRING_LITERAL_LONG2\": [\"graphTerm\"], \n \"INTEGER\": [\"graphTerm\"], \n \"DECIMAL\": [\"graphTerm\"], \n \"DOUBLE\": [\"graphTerm\"], \n \"INTEGER_POSITIVE\": [\"graphTerm\"], \n \"DECIMAL_POSITIVE\": [\"graphTerm\"], \n \"DOUBLE_POSITIVE\": [\"graphTerm\"], \n \"INTEGER_NEGATIVE\": [\"graphTerm\"], \n \"DECIMAL_NEGATIVE\": [\"graphTerm\"], \n \"DOUBLE_NEGATIVE\": [\"graphTerm\"]}, \n \"verb\" : {\n \"VAR1\": [\"storeProperty\",\"varOrIRIref\"], \n \"VAR2\": [\"storeProperty\",\"varOrIRIref\"], \n \"IRI_REF\": [\"storeProperty\",\"varOrIRIref\"], \n \"PNAME_LN\": [\"storeProperty\",\"varOrIRIref\"], \n \"PNAME_NS\": [\"storeProperty\",\"varOrIRIref\"], \n \"a\": [\"storeProperty\",\"a\"]}, \n \"verbPath\" : {\n \"^\": [\"path\"], \n \"a\": [\"path\"], \n \"!\": [\"path\"], \n \"(\": [\"path\"], \n \"IRI_REF\": [\"path\"], \n \"PNAME_LN\": [\"path\"], \n \"PNAME_NS\": [\"path\"]}, \n \"verbSimple\" : {\n \"VAR1\": [\"var\"], \n \"VAR2\": [\"var\"]}, \n \"whereClause\" : {\n \"{\": [\"?WHERE\",\"groupGraphPattern\"], \n \"WHERE\": [\"?WHERE\",\"groupGraphPattern\"]}\n},\n\nkeywords:/^(GROUP_CONCAT|DATATYPE|BASE|PREFIX|SELECT|CONSTRUCT|DESCRIBE|ASK|FROM|NAMED|ORDER|BY|LIMIT|ASC|DESC|OFFSET|DISTINCT|REDUCED|WHERE|GRAPH|OPTIONAL|UNION|FILTER|GROUP|HAVING|AS|VALUES|LOAD|CLEAR|DROP|CREATE|MOVE|COPY|SILENT|INSERT|DELETE|DATA|WITH|TO|USING|NAMED|MINUS|BIND|LANGMATCHES|LANG|BOUND|SAMETERM|ISIRI|ISURI|ISBLANK|ISLITERAL|REGEX|TRUE|FALSE|UNDEF|ADD|DEFAULT|ALL|SERVICE|INTO|IN|NOT|IRI|URI|BNODE|RAND|ABS|CEIL|FLOOR|ROUND|CONCAT|STRLEN|UCASE|LCASE|ENCODE_FOR_URI|CONTAINS|STRSTARTS|STRENDS|STRBEFORE|STRAFTER|YEAR|MONTH|DAY|HOURS|MINUTES|SECONDS|TIMEZONE|TZ|NOW|UUID|STRUUID|MD5|SHA1|SHA256|SHA384|SHA512|COALESCE|IF|STRLANG|STRDT|ISNUMERIC|SUBSTR|REPLACE|EXISTS|COUNT|SUM|MIN|MAX|AVG|SAMPLE|SEPARATOR|STR)/i ,\n\npunct:/^(\\*|a|\\.|\\{|\\}|,|\\(|\\)|;|\\[|\\]|\\|\\||&&|=|!=|!|<=|>=|<|>|\\+|-|\\/|\\^\\^|\\?|\\||\\^)/ ,\n\nstartSymbol:\"sparql11\",\nacceptEmpty:true,\n}","\"use strict\";\nvar CodeMirror = require('codemirror');\nCodeMirror.defineMode(\"sparql11\", function(config, parserConfig) {\n\n\tvar indentUnit = config.indentUnit;\n\n\tvar grammar = require('./_tokenizer-table.js');\n\tvar ll1_table = grammar.table;\n\n\tvar IRI_REF = '<[^<>\\\"\\'\\|\\{\\}\\^\\\\\\x00-\\x20]*>';\n\t/*\n\t * PN_CHARS_BASE =\n\t * '[A-Z]|[a-z]|[\\\\u00C0-\\\\u00D6]|[\\\\u00D8-\\\\u00F6]|[\\\\u00F8-\\\\u02FF]|[\\\\u0370-\\\\u037D]|[\\\\u037F-\\\\u1FFF]|[\\\\u200C-\\\\u200D]|[\\\\u2070-\\\\u218F]|[\\\\u2C00-\\\\u2FEF]|[\\\\u3001-\\\\uD7FF]|[\\\\uF900-\\\\uFDCF]|[\\\\uFDF0-\\\\uFFFD]|[\\\\u10000-\\\\uEFFFF]';\n\t */\n\n\tvar PN_CHARS_BASE =\n\t\t'[A-Za-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD]';\n\tvar PN_CHARS_U = PN_CHARS_BASE+'|_';\n\n\tvar PN_CHARS= '('+PN_CHARS_U+'|-|[0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040])';\n\tvar VARNAME = '('+PN_CHARS_U+'|[0-9])'+\n\t\t'('+PN_CHARS_U+'|[0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040])*';\n\tvar VAR1 = '\\\\?'+VARNAME;\n\tvar VAR2 = '\\\\$'+VARNAME;\n\n\tvar PN_PREFIX= '('+PN_CHARS_BASE+')((('+PN_CHARS+')|\\\\.)*('+PN_CHARS+'))?';\n\n\tvar HEX= '[0-9A-Fa-f]';\n\tvar PERCENT='(%'+HEX+HEX+')';\n\tvar PN_LOCAL_ESC='(\\\\\\\\[_~\\\\.\\\\-!\\\\$&\\'\\\\(\\\\)\\\\*\\\\+,;=/\\\\?#@%])';\n\tvar PLX= '('+PERCENT+'|'+PN_LOCAL_ESC+')';\n\tvar PN_LOCAL= '('+PN_CHARS_U+'|:|[0-9]|'+PLX+')(('+PN_CHARS+'|\\\\.|:|'+PLX+')*('+PN_CHARS+'|:|'+PLX+'))?';\n\tvar BLANK_NODE_LABEL = '_:('+PN_CHARS_U+'|[0-9])(('+PN_CHARS+'|\\\\.)*'+PN_CHARS+')?';\n\tvar PNAME_NS = '('+PN_PREFIX+')?:';\n\tvar PNAME_LN = PNAME_NS+PN_LOCAL;\n\tvar LANGTAG = '@[a-zA-Z]+(-[a-zA-Z0-9]+)*';\n\n\tvar EXPONENT = '[eE][\\\\+-]?[0-9]+';\n\tvar INTEGER = '[0-9]+';\n\tvar DECIMAL = '(([0-9]+\\\\.[0-9]*)|(\\\\.[0-9]+))';\n\tvar DOUBLE =\n\t\t'(([0-9]+\\\\.[0-9]*'+EXPONENT+')|'+\n\t\t'(\\\\.[0-9]+'+EXPONENT+')|'+\n\t\t'([0-9]+'+EXPONENT+'))';\n\n\tvar INTEGER_POSITIVE = '\\\\+' + INTEGER;\n\tvar DECIMAL_POSITIVE = '\\\\+' + DECIMAL;\n\tvar DOUBLE_POSITIVE = '\\\\+' + DOUBLE;\n\tvar INTEGER_NEGATIVE = '-' + INTEGER;\n\tvar DECIMAL_NEGATIVE = '-' + DECIMAL;\n\tvar DOUBLE_NEGATIVE = '-' + DOUBLE;\n\n\tvar ECHAR = '\\\\\\\\[tbnrf\\\\\\\\\"\\']';\n\t\n\t\n\t //IMPORTANT: this unicode rule is not in the official grammar.\n //Reason: https://github.com/YASGUI/YASQE/issues/49\n //unicode escape sequences (which the sparql spec considers part of the pre-processing of sparql queries)\n //are marked as invalid. We have little choice (other than adding a layer of complixity) than to modify the grammar accordingly\n //however, for now only allow these escape sequences in literals (where actually, this should be allows in e.g. prefixes as well)\n\tvar hex4 = HEX + '{4}'\n\tvar unicode = '(\\\\\\\\u' + hex4 +'|\\\\\\\\U00(10|0' + HEX + ')'+ hex4 + ')';\n\tvar LINE_BREAK = \"\\n\";\n\tvar STRING_LITERAL1 = \"'(([^\\\\x27\\\\x5C\\\\x0A\\\\x0D])|\"+ECHAR+\"|\" + unicode + \")*'\";\n\tvar STRING_LITERAL2 = '\"(([^\\\\x22\\\\x5C\\\\x0A\\\\x0D])|'+ECHAR+'|' + unicode + ')*\"';\n\t\n\tvar STRING_LITERAL_LONG = {\n\t\tSINGLE: {\n\t\t\tCAT: \"STRING_LITERAL_LONG1\",\n\t\t\tQUOTES: \"'''\",\n\t\t\tCONTENTS: \"(('|'')?([^'\\\\\\\\]|\"+ECHAR+\"|\"+unicode+\"))*\",\n\t\t\t\n\t\t},\n\t\tDOUBLE: {\n\t\t\tCAT: \"STRING_LITERAL_LONG2\",\n\t\t\tQUOTES: '\"\"\"',\n\t\t\tCONTENTS: '((\"|\"\")?([^\"\\\\\\\\]|'+ECHAR+'|'+unicode+'))*',\n\t\t}\n\t};\n\tfor (var key in STRING_LITERAL_LONG) {\n\t\tSTRING_LITERAL_LONG[key].COMPLETE = STRING_LITERAL_LONG[key].QUOTES + STRING_LITERAL_LONG[key].CONTENTS + STRING_LITERAL_LONG[key].QUOTES;\n\t}\n//\tvar STRING_LITERAL_LONG_QUOTES = {\n//\t\t\"STRING_LITERAL_LONG_QUOTES1\": \"'''\",\n//\t\t\"STRING_LITERAL_LONG_QUOTES2\": '\"\"\"',\n//\t}\n//\tvar STRING_LITERAL_LONG_CONTENTS = {\n//\t\t\"STRING_LITERAL_LONG_QUOTES1\": \"(('|'')?([^'\\\\\\\\]|\"+ECHAR+\"|\"+unicode+\"))*\",\n//\t\t\"STRING_LITERAL_LONG_QUOTES2\": '((\"|\"\")?([^\"\\\\\\\\]|'+ECHAR+'|'+unicode+'))*'\n//\t};\n//\tvar STRING_LITERAL_LONG1 = STRING_LITERAL_LONG['SINGLE'].QUOTES + STRING_LITERAL_LONG['SINGLE'].CONTENTS + STRING_LITERAL_LONG['SINGLE'].QUOTES;\n//\tvar STRING_LITERAL_LONG2 = STRING_LITERAL_LONG['DOUBLE'].QUOTES + STRING_LITERAL_LONG['DOUBLE'].CONTENTS + STRING_LITERAL_LONG['DOUBLE'].QUOTES;\n\t\n//\tvar stringLiteralLongContentTerminals = {};\n//\tfor (var key in STRING_LITERAL_LONG) {\n//\t\tstringLiteralLongContentTerminals[key] = {\n//\t\t\tname: key,\n//\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG_CONTENTS[key]),\n//\t\t\tstyle:\"string\"\n//\t\t};\n//\t}\n\t//some regular expressions not used in regular terminals, because this is used accross lines\n\tvar stringLiteralLongRegex = {};\n\tfor (var key in STRING_LITERAL_LONG) {\n\t\tstringLiteralLongRegex[key] = {\n\t\t\tcomplete: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].COMPLETE),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\tcontents: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].CONTENTS),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\tclosing: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].CONTENTS + STRING_LITERAL_LONG[key].QUOTES),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\tquotes: {\n\t\t\t\tname: \"STRING_LITERAL_LONG_QUOTES_\" + key,\n\t\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL_LONG[key].QUOTES),\n\t\t\t\tstyle:\"string\"\n\t\t\t},\n\t\t\n\t\t}\n\t}\n\t\n\tvar WS = '[\\\\x20\\\\x09\\\\x0D\\\\x0A]';\n\t// Careful! Code mirror feeds one line at a time with no \\n\n\t// ... but otherwise comment is terminated by \\n\n\tvar COMMENT = '#([^\\\\n\\\\r]*[\\\\n\\\\r]|[^\\\\n\\\\r]*$)';\n\tvar WS_OR_COMMENT_STAR = '('+WS+'|('+COMMENT+'))*';\n\tvar NIL = '\\\\('+WS_OR_COMMENT_STAR+'\\\\)';\n\tvar ANON = '\\\\['+WS_OR_COMMENT_STAR+'\\\\]';\n\tvar terminals= [\n\t\t{ name: \"WS\",\n\t\t\tregex:new RegExp(\"^\"+WS+\"+\"),\n\t\t\tstyle:\"ws\" },\n\n\t\t{ name: \"COMMENT\",\n\t\t\tregex:new RegExp(\"^\"+COMMENT),\n\t\t\tstyle:\"comment\" },\n\n\t\t{ name: \"IRI_REF\",\n\t\t\tregex:new RegExp(\"^\"+IRI_REF),\n\t\t\tstyle:\"variable-3\" },\n\n\t\t{ name: \"VAR1\",\n\t\t\tregex:new RegExp(\"^\"+VAR1),\n\t\t\tstyle:\"atom\"},\n\n\t\t{ name: \"VAR2\",\n\t\t\tregex:new RegExp(\"^\"+VAR2),\n\t\t\tstyle:\"atom\"},\n\n\t\t{ name: \"LANGTAG\",\n\t\t\tregex:new RegExp(\"^\"+LANGTAG),\n\t\t\tstyle:\"meta\"},\n\n\t\t{ name: \"DOUBLE\",\n\t\t\tregex:new RegExp(\"^\"+DOUBLE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DECIMAL\",\n\t\t\tregex:new RegExp(\"^\"+DECIMAL),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"INTEGER\",\n\t\t\tregex:new RegExp(\"^\"+INTEGER),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DOUBLE_POSITIVE\",\n\t\t\tregex:new RegExp(\"^\"+DOUBLE_POSITIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DECIMAL_POSITIVE\",\n\t\t\tregex:new RegExp(\"^\"+DECIMAL_POSITIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"INTEGER_POSITIVE\",\n\t\t\tregex:new RegExp(\"^\"+INTEGER_POSITIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DOUBLE_NEGATIVE\",\n\t\t\tregex:new RegExp(\"^\"+DOUBLE_NEGATIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"DECIMAL_NEGATIVE\",\n\t\t\tregex:new RegExp(\"^\"+DECIMAL_NEGATIVE),\n\t\t\tstyle:\"number\" },\n\n\t\t{ name: \"INTEGER_NEGATIVE\",\n\t\t\tregex:new RegExp(\"^\"+INTEGER_NEGATIVE),\n\t\t\tstyle:\"number\" },\n//\t\tstringLiteralLongRegex.SINGLE.complete,\n//\t\tstringLiteralLongRegex.DOUBLE.complete,\n//\t\tstringLiteralLongRegex.SINGLE.quotes,\n//\t\tstringLiteralLongRegex.DOUBLE.quotes,\n\t\t\n\t\t{ name: \"STRING_LITERAL1\",\n\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL1),\n\t\t\tstyle:\"string\" },\n\n\t\t{ name: \"STRING_LITERAL2\",\n\t\t\tregex:new RegExp(\"^\"+STRING_LITERAL2),\n\t\t\tstyle:\"string\" },\n\n\t\t// Enclosed comments won't be highlighted\n\t\t{ name: \"NIL\",\n\t\t\tregex:new RegExp(\"^\"+NIL),\n\t\t\tstyle:\"punc\" },\n\n\t\t// Enclosed comments won't be highlighted\n\t\t{ name: \"ANON\",\n\t\t\tregex:new RegExp(\"^\"+ANON),\n\t\t\tstyle:\"punc\" },\n\n\t\t{ name: \"PNAME_LN\",\n\t\t\tregex:new RegExp(\"^\"+PNAME_LN),\n\t\t\tstyle:\"string-2\" },\n\n\t\t{ name: \"PNAME_NS\",\n\t\t\tregex:new RegExp(\"^\"+PNAME_NS),\n\t\t\tstyle:\"string-2\" },\n\n\t\t{ name: \"BLANK_NODE_LABEL\",\n\t\t\tregex:new RegExp(\"^\"+BLANK_NODE_LABEL),\n\t\t\tstyle:\"string-2\" }\n\t];\n\n\tfunction getPossibles(symbol) {\n\t\tvar possibles=[], possiblesOb=ll1_table[symbol];\n\t\tif (possiblesOb!=undefined) {\n\t\t\tfor (var property in possiblesOb) {\n\t\t\t\tpossibles.push(property.toString());\n\t\t\t}\n\t\t} else {\n\t\t\tpossibles.push(symbol);\n\t\t}\n\t\treturn possibles;\n\t}\n\n\n\tfunction tokenBase(stream, state) {\n\n\t\tfunction nextToken() {\n\t\t\tvar consumed=null;\n\t\t\tif (state.inLiteral) {\n\t\t\t\t\n\t\t\t\tvar closingQuotes = false;\n\t\t\t\t//multi-line literal. try to parse contents.\n\t\t\t\tconsumed = stream.match(stringLiteralLongRegex[state.inLiteral].contents.regex, true, false);\n\t\t\t\tif (consumed && consumed[0].length == 0) {\n\t\t\t\t\t//try seeing whether we can consume closing quotes, to avoid stopping\n\t\t\t\t\tconsumed = stream.match(stringLiteralLongRegex[state.inLiteral].closing.regex, true, false);\n\t\t\t\t\tclosingQuotes = true;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (consumed && consumed[0].length > 0) {\n\t\t\t\t\t//some string content here. \n\t\t\t\t\t var returnObj = {\n\t\t\t\t\t\tquotePos: (closingQuotes? 'end': 'content'),\n\t\t\t\t\t\tcat: STRING_LITERAL_LONG[state.inLiteral].CAT,\n\t\t\t\t\t\tstyle: stringLiteralLongRegex[state.inLiteral].complete.style,\n\t\t\t\t\t\ttext: consumed[0],\n\t\t\t\t\t\tstart: stream.start\n\t\t\t\t\t};\n\t\t\t\t\t if (closingQuotes) state.inLiteral = false;\n\t\t\t\t\t return returnObj;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t//Multiline literals\n\t\t\tfor (var quoteType in stringLiteralLongRegex) {\n\t\t\t\tconsumed= stream.match(stringLiteralLongRegex[quoteType].quotes.regex,true,false);\n\t\t\t\tif (consumed) {\n\t\t\t\t\tvar quotePos;\n\t\t\t\t\tif (state.inLiteral) {\n\t\t\t\t\t\t//end of literal. everything is fine\n\t\t\t\t\t\tstate.inLiteral = false;\n\t\t\t\t\t\tquotePos = 'end';\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate.inLiteral = quoteType;\n\t\t\t\t\t\tquotePos = 'start';\n\t\t\t\t\t}\n\t\t\t\t\treturn {\n\t\t\t\t\t\tcat: STRING_LITERAL_LONG[quoteType].CAT,\n\t\t\t\t\t\tstyle: stringLiteralLongRegex[quoteType].quotes.style,\n\t\t\t\t\t\ttext: consumed[0],\n\t\t\t\t\t\tquotePos: quotePos,\n\t\t\t\t\t\tstart: stream.start\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t// Tokens defined by individual regular expressions\n\t\t\tfor (var i=0; i\",\n\t\t\t\t\t\t\t style: \"error\",\n\t\t\t\t\t\t\t text: consumed[0],\n\t\t\t\t\t\t\t start: stream.start\n\t\t\t\t\t\t };\n\t\t}\n\n\t\tfunction recordFailurePos() {\n\t\t\t// tokenOb.style= \"sp-invalid\";\n\t\t\tvar col= stream.column();\n\t\t\tstate.errorStartPos= col;\n\t\t\tstate.errorEndPos= col+tokenOb.text.length;\n\t\t};\n\n\t\tfunction setQueryType(s) {\n\t\t\tif (state.queryType==null) {\n\t\t\t\tif (s ==\"SELECT\" || s==\"CONSTRUCT\" || s==\"ASK\" || s==\"DESCRIBE\" || s==\"INSERT\" || s==\"DELETE\" || s==\"LOAD\" || s==\"CLEAR\" || s==\"CREATE\" || s==\"DROP\" || s==\"COPY\" || s==\"MOVE\" || s==\"ADD\")\n\t\t\t\t\tstate.queryType=s;\n\t\t\t}\n\t\t}\n\n\t\t// Some fake non-terminals are just there to have side-effect on state\n\t\t// - i.e. allow or disallow variables and bnodes in certain non-nesting\n\t\t// contexts\n\t\tfunction setSideConditions(topSymbol) {\n\t\t\tif (topSymbol==\"disallowVars\") state.allowVars=false;\n\t\t\telse if (topSymbol==\"allowVars\") state.allowVars=true;\n\t\t\telse if (topSymbol==\"disallowBnodes\") state.allowBnodes=false;\n\t\t\telse if (topSymbol==\"allowBnodes\") state.allowBnodes=true;\n\t\t\telse if (topSymbol==\"storeProperty\") state.storeProperty=true;\n\t\t}\n\n\t\tfunction checkSideConditions(topSymbol) {\n\t\t\treturn(\n\t\t\t\t(state.allowVars || topSymbol!=\"var\") &&\n\t\t\t\t\t(state.allowBnodes ||\n\t\t\t\t\t (topSymbol!=\"blankNode\" &&\n\t\t\t\t\t\ttopSymbol!=\"blankNodePropertyList\" &&\n\t\t\t\t\t\ttopSymbol!=\"blankNodePropertyListPath\")));\n\t\t}\n\n\t\t// CodeMirror works with one line at a time,\n\t\t// but newline should behave like whitespace\n\t\t// - i.e. a definite break between tokens (for autocompleter)\n\t\tif (stream.pos==0)\n\t\t\tstate.possibleCurrent= state.possibleNext;\n\n\t\tvar tokenOb= nextToken();\n\n\n\t\tif (tokenOb.cat==\"\") {\n\t\t\t// set error state, and\n\t\t\tif (state.OK==true) {\n\t\t\t\tstate.OK=false;\n\t\t\t\trecordFailurePos();\n\t\t\t}\n\t\t\tstate.complete=false;\n\t\t\t// alert(\"Invalid:\"+tokenOb.text);\n\t\t\treturn tokenOb.style;\n\t\t}\n\n\t\tif (tokenOb.cat == \"WS\" || tokenOb.cat == \"COMMENT\" || (tokenOb.quotePos && tokenOb.quotePos != 'end')) {\n\t\t\tstate.possibleCurrent = state.possibleNext;\n\t\t\treturn(tokenOb.style);\n\t\t}\n\t\t// Otherwise, run the parser until the token is digested\n\t\t// or failure\n\t\tvar finished= false;\n\t\tvar topSymbol;\n\t\tvar token= tokenOb.cat;\n\t\t\n\t\tif (!tokenOb.quotePos || tokenOb.quotePos == 'end') {\n\t\t// Incremental LL1 parse\n\t\t\twhile(state.stack.length>0 && token && state.OK && !finished ) {\n\t\t\t\ttopSymbol= state.stack.pop();\n\t\n\t\t\t\tif (!ll1_table[topSymbol]) {\n\t\t\t\t\t// Top symbol is a terminal\n\t\t\t\t\tif (topSymbol == token) {\n\t\t\t\t\t\t// Matching terminals\n\t\t\t\t\t\t// - consume token from input stream\n\t\t\t\t\t\tfinished=true;\n\t\t\t\t\t\tsetQueryType(topSymbol);\n\t\t\t\t\t\t// Check whether $ (end of input token) is poss next\n\t\t\t\t\t\t// for everything on stack\n\t\t\t\t\t\tvar allNillable=true;\n\t\t\t\t\t\tfor(var sp=state.stack.length;sp>0;--sp) {\n\t\t\t\t\t\t\tvar item=ll1_table[state.stack[sp-1]];\n\t\t\t\t\t\t\tif (!item || !item[\"$\"])\n\t\t\t\t\t\t\t\tallNillable=false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstate.complete= allNillable;\n\t\t\t\t\t\tif (state.storeProperty && token.cat != \"punc\") {\n\t\t\t\t\t\t\tstate.lastProperty = tokenOb.text;\n\t\t\t\t\t\t\tstate.storeProperty = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstate.OK=false;\n\t\t\t\t\t\tstate.complete=false;\n\t\t\t\t\t\trecordFailurePos();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// topSymbol is nonterminal\n\t\t\t\t\t// - see if there is an entry for topSymbol\n\t\t\t\t\t// and nextToken in table\n\t\t\t\t\tvar nextSymbols= ll1_table[topSymbol][token];\n\t\t\t\t\tif (nextSymbols!=undefined && checkSideConditions(topSymbol)) {\n\t\t\t\t\t\t// Match - copy RHS of rule to stack\n\t\t\t\t\t\tfor (var i=nextSymbols.length-1; i>=0; --i) {\n\t\t\t\t\t\t\tstate.stack.push(nextSymbols[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Peform any non-grammatical side-effects\n\t\t\t\t\t\tsetSideConditions(topSymbol);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// No match in table - fail\n\t\t\t\t\t\tstate.OK=false;\n\t\t\t\t\t\tstate.complete=false;\n\t\t\t\t\t\trecordFailurePos();\n\t\t\t\t\t\tstate.stack.push(topSymbol); // Shove topSymbol back on stack\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!finished && state.OK) { \n\t\t\tstate.OK=false; state.complete=false; recordFailurePos(); \n\t\t}\n\t\t\n\t\tif (state.possibleCurrent.indexOf('a') >= 0){\n\t\t\tstate.lastPredicateOffset = tokenOb.start;\n\t\t}\n\t\tstate.possibleCurrent = state.possibleNext;\n\t\t\n\t\tstate.possibleNext = getPossibles(state.stack[state.stack.length-1]);\n\n\t\treturn tokenOb.style;\n\t}\n\n\tvar indentTop={\n\t\t\"*[,, object]\": 3,\n\t\t\"*[(,),object]\": 3,\n\t\t\"*[(,),objectPath]\": 3,\n\t\t\"*[/,pathEltOrInverse]\": 2,\n\t\t\"object\": 2,\n\t\t\"objectPath\": 2,\n\t\t\"objectList\": 2,\n\t\t\"objectListPath\": 2,\n\t\t\"storeProperty\": 2,\n\t\t\"pathMod\": 2,\n\t\t\"?pathMod\": 2,\n\t\t\"propertyListNotEmpty\": 1,\n\t\t\"propertyList\": 1,\n\t\t\"propertyListPath\": 1,\n\t\t\"propertyListPathNotEmpty\": 1,\n\t\t\"?[verb,objectList]\": 1,\n//\t\t\"?[or([verbPath, verbSimple]),objectList]\": 1,\n\t};\n\n\tvar indentTable={\n\t\t\"}\":1,\n\t\t\"]\":0,\n\t\t\")\":1,\n\t\t\"{\":-1,\n\t\t\"(\":-1,\n//\t\t\"*[;,?[or([verbPath,verbSimple]),objectList]]\": 1,\n\t};\n\t\n\n\tfunction indent(state, textAfter) {\n\t\t//just avoid we don't indent multi-line literals\n\t\tif (state.inLiteral) return 0;\n\t\tif (state.stack.length && state.stack[state.stack.length-1] == \"?[or([verbPath,verbSimple]),objectList]\") {\n\t\t\t//we are after a semi-colon. I.e., nicely align this line with predicate position of previous line\n\t\t\treturn state.lastPredicateOffset;\n\t\t} else {\n\t\t\tvar n = 0; // indent level\n\t\t\tvar i = state.stack.length-1;\n\t\t\tif (/^[\\}\\]\\)]/.test(textAfter)) {\n\t\t\t\t// Skip stack items until after matching bracket\n\t\t\t\tvar closeBracket=textAfter.substr(0,1);\n\t\t\t\tfor( ;i>=0;--i)\t{\n\t\t\t\t\tif (state.stack[i]==closeBracket) {\n\t\t\t\t\t\t--i; \n\t\t\t\t\t\tbreak;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Consider nullable non-terminals if at top of stack\n\t\t\t\tvar dn = indentTop[state.stack[i]];\n\t\t\t\tif (dn) { \n\t\t\t\t\tn += dn; \n\t\t\t\t\t--i;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor( ;i>=0;--i)\t{\n\t\t\t\tvar dn = indentTable[state.stack[i]];\n\t\t\t\tif (dn) {\n\t\t\t\t\tn+=dn;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn n * config.indentUnit;\n\t\t}\n\t};\n\n\treturn {\n\t\ttoken: tokenBase,\n\t\tstartState: function(base) {\n\t\t\treturn {\n\t\t\t\ttokenize: tokenBase,\n\t\t\t\tOK: true,\n\t\t\t\tcomplete: grammar.acceptEmpty,\n\t\t\t\terrorStartPos: null,\n\t\t\t\terrorEndPos: null,\n\t\t\t\tqueryType: null,\n\t\t\t\tpossibleCurrent: getPossibles(grammar.startSymbol),\n\t\t\t\tpossibleNext: getPossibles(grammar.startSymbol),\n\t\t\t\tallowVars : true,\n\t\t\t\tallowBnodes : true,\n\t\t\t\tstoreProperty : false,\n\t\t\t\tlastProperty : \"\",\n\t\t\t\tinLiteral: false,\n\t\t\t\tstack: [grammar.startSymbol],\n\t\t\t\tlastPredicateOffset: config.indentUnit,\n\t\t\t}; \n\t\t},\n\t\tindent: indent,\n\t\telectricChars: \"}])\"\n\t};\n}\n);\nCodeMirror.defineMIME(\"application/x-sparql-query\", \"sparql11\");\n","/*\n* TRIE implementation in Javascript\n* Copyright (c) 2010 Saurabh Odhyan | http://odhyan.com\n* \n* Permission is hereby granted, free of charge, to any person obtaining a copy\n* of this software and associated documentation files (the \"Software\"), to deal\n* in the Software without restriction, including without limitation the rights\n* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n* copies of the Software, and to permit persons to whom the Software is\n* furnished to do so, subject to the following conditions:\n* \n* The above copyright notice and this permission notice shall be included in\n* all copies or substantial portions of the Software.\n* \n* THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n* THE SOFTWARE.\n*\n* Date: Nov 7, 2010\n*/\n\n/*\n* A trie, or prefix tree, is a multi-way tree structure useful for storing strings over an alphabet. \n* It has been used to store large dictionaries of English (say) words in spell-checking programs \n* and in natural-language \"understanding\" programs. \n* @see http://en.wikipedia.org/wiki/Trie\n* @see http://www.csse.monash.edu.au/~lloyd/tildeAlgDS/Tree/Trie/\n/*\n\n* @class Trie\n* @constructor\n*/ \nvar Trie = module.exports = function() {\n this.words = 0;\n this.prefixes = 0;\n this.children = [];\n};\n\nTrie.prototype = {\n \n /*\n * Insert a word into the dictionary. \n * Recursively traverse through the trie nodes, and create new node if does not already exist.\n *\n * @method insert\n * @param {String} str Word to insert in the dictionary\n * @param {Integer} pos Current index of the string to be inserted\n * @return {Void}\n */\n insert: function(str, pos) {\n if(str.length == 0) { //blank string cannot be inserted\n return;\n }\n \n var T = this,\n k,\n child;\n \n if(pos === undefined) {\n pos = 0;\n }\n if(pos === str.length) {\n T.words ++;\n return;\n }\n T.prefixes ++;\n k = str[pos];\n if(T.children[k] === undefined) { //if node for this char doesn't exist, create one\n T.children[k] = new Trie();\n }\n child = T.children[k];\n child.insert(str, pos + 1);\n },\n \n /*\n * Remove a word from the dictionary.\n *\n * @method remove\n * @param {String} str Word to be removed\n * @param {Integer} pos Current index of the string to be removed\n * @return {Void}\n */\n remove: function(str, pos) {\n if(str.length == 0) {\n return;\n }\n \n var T = this,\n k,\n child;\n \n if(pos === undefined) {\n pos = 0;\n } \n if(T === undefined) {\n return;\n }\n if(pos === str.length) {\n T.words --;\n return;\n }\n T.prefixes --;\n k = str[pos];\n child = T.children[k];\n child.remove(str, pos + 1);\n },\n \n /*\n * Update an existing word in the dictionary. \n * This method removes the old word from the dictionary and inserts the new word.\n *\n * @method update\n * @param {String} strOld The old word to be replaced\n * @param {String} strNew The new word to be inserted\n * @return {Void}\n */\n update: function(strOld, strNew) {\n if(strOld.length == 0 || strNew.length == 0) {\n return;\n }\n this.remove(strOld);\n this.insert(strNew);\n },\n \n /*\n * Count the number of times a given word has been inserted into the dictionary\n *\n * @method countWord\n * @param {String} str Word to get count of\n * @param {Integer} pos Current index of the given word\n * @return {Integer} The number of times a given word exists in the dictionary\n */\n countWord: function(str, pos) {\n if(str.length == 0) {\n return 0;\n }\n \n var T = this,\n k,\n child,\n ret = 0;\n \n if(pos === undefined) {\n pos = 0;\n } \n if(pos === str.length) {\n return T.words;\n }\n k = str[pos];\n child = T.children[k];\n if(child !== undefined) { //node exists\n ret = child.countWord(str, pos + 1);\n }\n return ret;\n },\n \n /*\n * Count the number of times a given prefix exists in the dictionary\n *\n * @method countPrefix\n * @param {String} str Prefix to get count of\n * @param {Integer} pos Current index of the given prefix\n * @return {Integer} The number of times a given prefix exists in the dictionary\n */\n countPrefix: function(str, pos) {\n if(str.length == 0) {\n return 0;\n }\n \n var T = this,\n k,\n child,\n ret = 0;\n\n if(pos === undefined) {\n pos = 0;\n }\n if(pos === str.length) {\n return T.prefixes;\n }\n var k = str[pos];\n child = T.children[k];\n if(child !== undefined) { //node exists\n ret = child.countPrefix(str, pos + 1); \n }\n return ret; \n },\n \n /*\n * Find a word in the dictionary\n *\n * @method find\n * @param {String} str The word to find in the dictionary\n * @return {Boolean} True if the word exists in the dictionary, else false\n */\n find: function(str) {\n if(str.length == 0) {\n return false;\n }\n \n if(this.countWord(str) > 0) {\n return true;\n } else {\n return false;\n }\n },\n \n /*\n * Get all words in the dictionary\n *\n * @method getAllWords\n * @param {String} str Prefix of current word\n * @return {Array} Array of words in the dictionary\n */\n getAllWords: function(str) {\n var T = this,\n k,\n child,\n ret = [];\n if(str === undefined) {\n str = \"\";\n }\n if(T === undefined) {\n return [];\n }\n if(T.words > 0) {\n ret.push(str);\n }\n for(k in T.children) {\n child = T.children[k];\n ret = ret.concat(child.getAllWords(str + k));\n }\n return ret;\n },\n \n /*\n * Autocomplete a given prefix\n *\n * @method autoComplete\n * @param {String} str Prefix to be completed based on dictionary entries\n * @param {Integer} pos Current index of the prefix\n * @return {Array} Array of possible suggestions\n */\n autoComplete: function(str, pos) {\n \n \n var T = this,\n k,\n child;\n if(str.length == 0) {\n\t\t\tif (pos === undefined) {\n\t\t\t\treturn T.getAllWords(str);\n\t\t\t} else {\n\t\t\t\treturn [];\n\t\t\t}\n }\n if(pos === undefined) {\n pos = 0;\n } \n k = str[pos];\n child = T.children[k];\n if(child === undefined) { //node doesn't exist\n return [];\n }\n if(pos === str.length - 1) {\n return child.getAllWords(str);\n }\n return child.autoComplete(str, pos + 1);\n }\n};\n","// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n CodeMirror.defineOption(\"fullScreen\", false, function(cm, val, old) {\n if (old == CodeMirror.Init) old = false;\n if (!old == !val) return;\n if (val) setFullscreen(cm);\n else setNormal(cm);\n });\n\n function setFullscreen(cm) {\n var wrap = cm.getWrapperElement();\n cm.state.fullScreenRestore = {scrollTop: window.pageYOffset, scrollLeft: window.pageXOffset,\n width: wrap.style.width, height: wrap.style.height};\n wrap.style.width = \"\";\n wrap.style.height = \"auto\";\n wrap.className += \" CodeMirror-fullscreen\";\n document.documentElement.style.overflow = \"hidden\";\n cm.refresh();\n }\n\n function setNormal(cm) {\n var wrap = cm.getWrapperElement();\n wrap.className = wrap.className.replace(/\\s*CodeMirror-fullscreen\\b/, \"\");\n document.documentElement.style.overflow = \"\";\n var info = cm.state.fullScreenRestore;\n wrap.style.width = info.width; wrap.style.height = info.height;\n window.scrollTo(info.scrollLeft, info.scrollTop);\n cm.refresh();\n }\n});\n","// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n var ie_lt8 = /MSIE \\d/.test(navigator.userAgent) &&\n (document.documentMode == null || document.documentMode < 8);\n\n var Pos = CodeMirror.Pos;\n\n var matching = {\"(\": \")>\", \")\": \"(<\", \"[\": \"]>\", \"]\": \"[<\", \"{\": \"}>\", \"}\": \"{<\"};\n\n function findMatchingBracket(cm, where, strict, config) {\n var line = cm.getLineHandle(where.line), pos = where.ch - 1;\n var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];\n if (!match) return null;\n var dir = match.charAt(1) == \">\" ? 1 : -1;\n if (strict && (dir > 0) != (pos == where.ch)) return null;\n var style = cm.getTokenTypeAt(Pos(where.line, pos + 1));\n\n var found = scanForBracket(cm, Pos(where.line, pos + (dir > 0 ? 1 : 0)), dir, style || null, config);\n if (found == null) return null;\n return {from: Pos(where.line, pos), to: found && found.pos,\n match: found && found.ch == match.charAt(0), forward: dir > 0};\n }\n\n // bracketRegex is used to specify which type of bracket to scan\n // should be a regexp, e.g. /[[\\]]/\n //\n // Note: If \"where\" is on an open bracket, then this bracket is ignored.\n //\n // Returns false when no bracket was found, null when it reached\n // maxScanLines and gave up\n function scanForBracket(cm, where, dir, style, config) {\n var maxScanLen = (config && config.maxScanLineLength) || 10000;\n var maxScanLines = (config && config.maxScanLines) || 1000;\n\n var stack = [];\n var re = config && config.bracketRegex ? config.bracketRegex : /[(){}[\\]]/;\n var lineEnd = dir > 0 ? Math.min(where.line + maxScanLines, cm.lastLine() + 1)\n : Math.max(cm.firstLine() - 1, where.line - maxScanLines);\n for (var lineNo = where.line; lineNo != lineEnd; lineNo += dir) {\n var line = cm.getLine(lineNo);\n if (!line) continue;\n var pos = dir > 0 ? 0 : line.length - 1, end = dir > 0 ? line.length : -1;\n if (line.length > maxScanLen) continue;\n if (lineNo == where.line) pos = where.ch - (dir < 0 ? 1 : 0);\n for (; pos != end; pos += dir) {\n var ch = line.charAt(pos);\n if (re.test(ch) && (style === undefined || cm.getTokenTypeAt(Pos(lineNo, pos + 1)) == style)) {\n var match = matching[ch];\n if ((match.charAt(1) == \">\") == (dir > 0)) stack.push(ch);\n else if (!stack.length) return {pos: Pos(lineNo, pos), ch: ch};\n else stack.pop();\n }\n }\n }\n return lineNo - dir == (dir > 0 ? cm.lastLine() : cm.firstLine()) ? false : null;\n }\n\n function matchBrackets(cm, autoclear, config) {\n // Disable brace matching in long lines, since it'll cause hugely slow updates\n var maxHighlightLen = cm.state.matchBrackets.maxHighlightLineLength || 1000;\n var marks = [], ranges = cm.listSelections();\n for (var i = 0; i < ranges.length; i++) {\n var match = ranges[i].empty() && findMatchingBracket(cm, ranges[i].head, false, config);\n if (match && cm.getLine(match.from.line).length <= maxHighlightLen) {\n var style = match.match ? \"CodeMirror-matchingbracket\" : \"CodeMirror-nonmatchingbracket\";\n marks.push(cm.markText(match.from, Pos(match.from.line, match.from.ch + 1), {className: style}));\n if (match.to && cm.getLine(match.to.line).length <= maxHighlightLen)\n marks.push(cm.markText(match.to, Pos(match.to.line, match.to.ch + 1), {className: style}));\n }\n }\n\n if (marks.length) {\n // Kludge to work around the IE bug from issue #1193, where text\n // input stops going to the textare whever this fires.\n if (ie_lt8 && cm.state.focused) cm.display.input.focus();\n\n var clear = function() {\n cm.operation(function() {\n for (var i = 0; i < marks.length; i++) marks[i].clear();\n });\n };\n if (autoclear) setTimeout(clear, 800);\n else return clear;\n }\n }\n\n var currentlyHighlighted = null;\n function doMatchBrackets(cm) {\n cm.operation(function() {\n if (currentlyHighlighted) {currentlyHighlighted(); currentlyHighlighted = null;}\n currentlyHighlighted = matchBrackets(cm, false, cm.state.matchBrackets);\n });\n }\n\n CodeMirror.defineOption(\"matchBrackets\", false, function(cm, val, old) {\n if (old && old != CodeMirror.Init)\n cm.off(\"cursorActivity\", doMatchBrackets);\n if (val) {\n cm.state.matchBrackets = typeof val == \"object\" ? val : {};\n cm.on(\"cursorActivity\", doMatchBrackets);\n }\n });\n\n CodeMirror.defineExtension(\"matchBrackets\", function() {matchBrackets(this, true);});\n CodeMirror.defineExtension(\"findMatchingBracket\", function(pos, strict, config){\n return findMatchingBracket(this, pos, strict, config);\n });\n CodeMirror.defineExtension(\"scanForBracket\", function(pos, dir, style, config){\n return scanForBracket(this, pos, dir, style, config);\n });\n});\n","// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nCodeMirror.registerHelper(\"fold\", \"brace\", function(cm, start) {\n var line = start.line, lineText = cm.getLine(line);\n var startCh, tokenType;\n\n function findOpening(openCh) {\n for (var at = start.ch, pass = 0;;) {\n var found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);\n if (found == -1) {\n if (pass == 1) break;\n pass = 1;\n at = lineText.length;\n continue;\n }\n if (pass == 1 && found < start.ch) break;\n tokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));\n if (!/^(comment|string)/.test(tokenType)) return found + 1;\n at = found - 1;\n }\n }\n\n var startToken = \"{\", endToken = \"}\", startCh = findOpening(\"{\");\n if (startCh == null) {\n startToken = \"[\", endToken = \"]\";\n startCh = findOpening(\"[\");\n }\n\n if (startCh == null) return;\n var count = 1, lastLine = cm.lastLine(), end, endCh;\n outer: for (var i = line; i <= lastLine; ++i) {\n var text = cm.getLine(i), pos = i == line ? startCh : 0;\n for (;;) {\n var nextOpen = text.indexOf(startToken, pos), nextClose = text.indexOf(endToken, pos);\n if (nextOpen < 0) nextOpen = text.length;\n if (nextClose < 0) nextClose = text.length;\n pos = Math.min(nextOpen, nextClose);\n if (pos == text.length) break;\n if (cm.getTokenTypeAt(CodeMirror.Pos(i, pos + 1)) == tokenType) {\n if (pos == nextOpen) ++count;\n else if (!--count) { end = i; endCh = pos; break outer; }\n }\n ++pos;\n }\n }\n if (end == null || line == end && endCh == startCh) return;\n return {from: CodeMirror.Pos(line, startCh),\n to: CodeMirror.Pos(end, endCh)};\n});\n\nCodeMirror.registerHelper(\"fold\", \"import\", function(cm, start) {\n function hasImport(line) {\n if (line < cm.firstLine() || line > cm.lastLine()) return null;\n var start = cm.getTokenAt(CodeMirror.Pos(line, 1));\n if (!/\\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));\n if (start.type != \"keyword\" || start.string != \"import\") return null;\n // Now find closing semicolon, return its position\n for (var i = line, e = Math.min(cm.lastLine(), line + 10); i <= e; ++i) {\n var text = cm.getLine(i), semi = text.indexOf(\";\");\n if (semi != -1) return {startCh: start.end, end: CodeMirror.Pos(i, semi)};\n }\n }\n\n var start = start.line, has = hasImport(start), prev;\n if (!has || hasImport(start - 1) || ((prev = hasImport(start - 2)) && prev.end.line == start - 1))\n return null;\n for (var end = has.end;;) {\n var next = hasImport(end.line + 1);\n if (next == null) break;\n end = next.end;\n }\n return {from: cm.clipPos(CodeMirror.Pos(start, has.startCh + 1)), to: end};\n});\n\nCodeMirror.registerHelper(\"fold\", \"include\", function(cm, start) {\n function hasInclude(line) {\n if (line < cm.firstLine() || line > cm.lastLine()) return null;\n var start = cm.getTokenAt(CodeMirror.Pos(line, 1));\n if (!/\\S/.test(start.string)) start = cm.getTokenAt(CodeMirror.Pos(line, start.end + 1));\n if (start.type == \"meta\" && start.string.slice(0, 8) == \"#include\") return start.start + 8;\n }\n\n var start = start.line, has = hasInclude(start);\n if (has == null || hasInclude(start - 1) != null) return null;\n for (var end = start;;) {\n var next = hasInclude(end + 1);\n if (next == null) break;\n ++end;\n }\n return {from: CodeMirror.Pos(start, has + 1),\n to: cm.clipPos(CodeMirror.Pos(end))};\n});\n\n});\n","// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n function doFold(cm, pos, options, force) {\n if (options && options.call) {\n var finder = options;\n options = null;\n } else {\n var finder = getOption(cm, options, \"rangeFinder\");\n }\n if (typeof pos == \"number\") pos = CodeMirror.Pos(pos, 0);\n var minSize = getOption(cm, options, \"minFoldSize\");\n\n function getRange(allowFolded) {\n var range = finder(cm, pos);\n if (!range || range.to.line - range.from.line < minSize) return null;\n var marks = cm.findMarksAt(range.from);\n for (var i = 0; i < marks.length; ++i) {\n if (marks[i].__isFold && force !== \"fold\") {\n if (!allowFolded) return null;\n range.cleared = true;\n marks[i].clear();\n }\n }\n return range;\n }\n\n var range = getRange(true);\n if (getOption(cm, options, \"scanUp\")) while (!range && pos.line > cm.firstLine()) {\n pos = CodeMirror.Pos(pos.line - 1, 0);\n range = getRange(false);\n }\n if (!range || range.cleared || force === \"unfold\") return;\n\n var myWidget = makeWidget(cm, options);\n CodeMirror.on(myWidget, \"mousedown\", function(e) {\n myRange.clear();\n CodeMirror.e_preventDefault(e);\n });\n var myRange = cm.markText(range.from, range.to, {\n replacedWith: myWidget,\n clearOnEnter: true,\n __isFold: true\n });\n myRange.on(\"clear\", function(from, to) {\n CodeMirror.signal(cm, \"unfold\", cm, from, to);\n });\n CodeMirror.signal(cm, \"fold\", cm, range.from, range.to);\n }\n\n function makeWidget(cm, options) {\n var widget = getOption(cm, options, \"widget\");\n if (typeof widget == \"string\") {\n var text = document.createTextNode(widget);\n widget = document.createElement(\"span\");\n widget.appendChild(text);\n widget.className = \"CodeMirror-foldmarker\";\n }\n return widget;\n }\n\n // Clumsy backwards-compatible interface\n CodeMirror.newFoldFunction = function(rangeFinder, widget) {\n return function(cm, pos) { doFold(cm, pos, {rangeFinder: rangeFinder, widget: widget}); };\n };\n\n // New-style interface\n CodeMirror.defineExtension(\"foldCode\", function(pos, options, force) {\n doFold(this, pos, options, force);\n });\n\n CodeMirror.defineExtension(\"isFolded\", function(pos) {\n var marks = this.findMarksAt(pos);\n for (var i = 0; i < marks.length; ++i)\n if (marks[i].__isFold) return true;\n });\n\n CodeMirror.commands.toggleFold = function(cm) {\n cm.foldCode(cm.getCursor());\n };\n CodeMirror.commands.fold = function(cm) {\n cm.foldCode(cm.getCursor(), null, \"fold\");\n };\n CodeMirror.commands.unfold = function(cm) {\n cm.foldCode(cm.getCursor(), null, \"unfold\");\n };\n CodeMirror.commands.foldAll = function(cm) {\n cm.operation(function() {\n for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)\n cm.foldCode(CodeMirror.Pos(i, 0), null, \"fold\");\n });\n };\n CodeMirror.commands.unfoldAll = function(cm) {\n cm.operation(function() {\n for (var i = cm.firstLine(), e = cm.lastLine(); i <= e; i++)\n cm.foldCode(CodeMirror.Pos(i, 0), null, \"unfold\");\n });\n };\n\n CodeMirror.registerHelper(\"fold\", \"combine\", function() {\n var funcs = Array.prototype.slice.call(arguments, 0);\n return function(cm, start) {\n for (var i = 0; i < funcs.length; ++i) {\n var found = funcs[i](cm, start);\n if (found) return found;\n }\n };\n });\n\n CodeMirror.registerHelper(\"fold\", \"auto\", function(cm, start) {\n var helpers = cm.getHelpers(start, \"fold\");\n for (var i = 0; i < helpers.length; i++) {\n var cur = helpers[i](cm, start);\n if (cur) return cur;\n }\n });\n\n var defaultOptions = {\n rangeFinder: CodeMirror.fold.auto,\n widget: \"\\u2194\",\n minFoldSize: 0,\n scanUp: false\n };\n\n CodeMirror.defineOption(\"foldOptions\", null);\n\n function getOption(cm, options, name) {\n if (options && options[name] !== undefined)\n return options[name];\n var editorOptions = cm.options.foldOptions;\n if (editorOptions && editorOptions[name] !== undefined)\n return editorOptions[name];\n return defaultOptions[name];\n }\n\n CodeMirror.defineExtension(\"foldOption\", function(options, name) {\n return getOption(this, options, name);\n });\n});\n","// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"), require(\"./foldcode\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\", \"./foldcode\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n CodeMirror.defineOption(\"foldGutter\", false, function(cm, val, old) {\n if (old && old != CodeMirror.Init) {\n cm.clearGutter(cm.state.foldGutter.options.gutter);\n cm.state.foldGutter = null;\n cm.off(\"gutterClick\", onGutterClick);\n cm.off(\"change\", onChange);\n cm.off(\"viewportChange\", onViewportChange);\n cm.off(\"fold\", onFold);\n cm.off(\"unfold\", onFold);\n cm.off(\"swapDoc\", updateInViewport);\n }\n if (val) {\n cm.state.foldGutter = new State(parseOptions(val));\n updateInViewport(cm);\n cm.on(\"gutterClick\", onGutterClick);\n cm.on(\"change\", onChange);\n cm.on(\"viewportChange\", onViewportChange);\n cm.on(\"fold\", onFold);\n cm.on(\"unfold\", onFold);\n cm.on(\"swapDoc\", updateInViewport);\n }\n });\n\n var Pos = CodeMirror.Pos;\n\n function State(options) {\n this.options = options;\n this.from = this.to = 0;\n }\n\n function parseOptions(opts) {\n if (opts === true) opts = {};\n if (opts.gutter == null) opts.gutter = \"CodeMirror-foldgutter\";\n if (opts.indicatorOpen == null) opts.indicatorOpen = \"CodeMirror-foldgutter-open\";\n if (opts.indicatorFolded == null) opts.indicatorFolded = \"CodeMirror-foldgutter-folded\";\n return opts;\n }\n\n function isFolded(cm, line) {\n var marks = cm.findMarksAt(Pos(line));\n for (var i = 0; i < marks.length; ++i)\n if (marks[i].__isFold && marks[i].find().from.line == line) return true;\n }\n\n function marker(spec) {\n if (typeof spec == \"string\") {\n var elt = document.createElement(\"div\");\n elt.className = spec + \" CodeMirror-guttermarker-subtle\";\n return elt;\n } else {\n return spec.cloneNode(true);\n }\n }\n\n function updateFoldInfo(cm, from, to) {\n var opts = cm.state.foldGutter.options, cur = from;\n var minSize = cm.foldOption(opts, \"minFoldSize\");\n var func = cm.foldOption(opts, \"rangeFinder\");\n cm.eachLine(from, to, function(line) {\n var mark = null;\n if (isFolded(cm, cur)) {\n mark = marker(opts.indicatorFolded);\n } else {\n var pos = Pos(cur, 0);\n var range = func && func(cm, pos);\n if (range && range.to.line - range.from.line >= minSize)\n mark = marker(opts.indicatorOpen);\n }\n cm.setGutterMarker(line, opts.gutter, mark);\n ++cur;\n });\n }\n\n function updateInViewport(cm) {\n var vp = cm.getViewport(), state = cm.state.foldGutter;\n if (!state) return;\n cm.operation(function() {\n updateFoldInfo(cm, vp.from, vp.to);\n });\n state.from = vp.from; state.to = vp.to;\n }\n\n function onGutterClick(cm, line, gutter) {\n var opts = cm.state.foldGutter.options;\n if (gutter != opts.gutter) return;\n cm.foldCode(Pos(line, 0), opts.rangeFinder);\n }\n\n function onChange(cm) {\n var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;\n state.from = state.to = 0;\n clearTimeout(state.changeUpdate);\n state.changeUpdate = setTimeout(function() { updateInViewport(cm); }, opts.foldOnChangeTimeSpan || 600);\n }\n\n function onViewportChange(cm) {\n var state = cm.state.foldGutter, opts = cm.state.foldGutter.options;\n clearTimeout(state.changeUpdate);\n state.changeUpdate = setTimeout(function() {\n var vp = cm.getViewport();\n if (state.from == state.to || vp.from - state.to > 20 || state.from - vp.to > 20) {\n updateInViewport(cm);\n } else {\n cm.operation(function() {\n if (vp.from < state.from) {\n updateFoldInfo(cm, vp.from, state.from);\n state.from = vp.from;\n }\n if (vp.to > state.to) {\n updateFoldInfo(cm, state.to, vp.to);\n state.to = vp.to;\n }\n });\n }\n }, opts.updateViewportTimeSpan || 400);\n }\n\n function onFold(cm, from) {\n var state = cm.state.foldGutter, line = from.line;\n if (line >= state.from && line < state.to)\n updateFoldInfo(cm, line, line + 1);\n }\n});\n","// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n var Pos = CodeMirror.Pos;\n function cmp(a, b) { return a.line - b.line || a.ch - b.ch; }\n\n var nameStartChar = \"A-Z_a-z\\\\u00C0-\\\\u00D6\\\\u00D8-\\\\u00F6\\\\u00F8-\\\\u02FF\\\\u0370-\\\\u037D\\\\u037F-\\\\u1FFF\\\\u200C-\\\\u200D\\\\u2070-\\\\u218F\\\\u2C00-\\\\u2FEF\\\\u3001-\\\\uD7FF\\\\uF900-\\\\uFDCF\\\\uFDF0-\\\\uFFFD\";\n var nameChar = nameStartChar + \"\\-\\:\\.0-9\\\\u00B7\\\\u0300-\\\\u036F\\\\u203F-\\\\u2040\";\n var xmlTagStart = new RegExp(\"<(/?)([\" + nameStartChar + \"][\" + nameChar + \"]*)\", \"g\");\n\n function Iter(cm, line, ch, range) {\n this.line = line; this.ch = ch;\n this.cm = cm; this.text = cm.getLine(line);\n this.min = range ? range.from : cm.firstLine();\n this.max = range ? range.to - 1 : cm.lastLine();\n }\n\n function tagAt(iter, ch) {\n var type = iter.cm.getTokenTypeAt(Pos(iter.line, ch));\n return type && /\\btag\\b/.test(type);\n }\n\n function nextLine(iter) {\n if (iter.line >= iter.max) return;\n iter.ch = 0;\n iter.text = iter.cm.getLine(++iter.line);\n return true;\n }\n function prevLine(iter) {\n if (iter.line <= iter.min) return;\n iter.text = iter.cm.getLine(--iter.line);\n iter.ch = iter.text.length;\n return true;\n }\n\n function toTagEnd(iter) {\n for (;;) {\n var gt = iter.text.indexOf(\">\", iter.ch);\n if (gt == -1) { if (nextLine(iter)) continue; else return; }\n if (!tagAt(iter, gt + 1)) { iter.ch = gt + 1; continue; }\n var lastSlash = iter.text.lastIndexOf(\"/\", gt);\n var selfClose = lastSlash > -1 && !/\\S/.test(iter.text.slice(lastSlash + 1, gt));\n iter.ch = gt + 1;\n return selfClose ? \"selfClose\" : \"regular\";\n }\n }\n function toTagStart(iter) {\n for (;;) {\n var lt = iter.ch ? iter.text.lastIndexOf(\"<\", iter.ch - 1) : -1;\n if (lt == -1) { if (prevLine(iter)) continue; else return; }\n if (!tagAt(iter, lt + 1)) { iter.ch = lt; continue; }\n xmlTagStart.lastIndex = lt;\n iter.ch = lt;\n var match = xmlTagStart.exec(iter.text);\n if (match && match.index == lt) return match;\n }\n }\n\n function toNextTag(iter) {\n for (;;) {\n xmlTagStart.lastIndex = iter.ch;\n var found = xmlTagStart.exec(iter.text);\n if (!found) { if (nextLine(iter)) continue; else return; }\n if (!tagAt(iter, found.index + 1)) { iter.ch = found.index + 1; continue; }\n iter.ch = found.index + found[0].length;\n return found;\n }\n }\n function toPrevTag(iter) {\n for (;;) {\n var gt = iter.ch ? iter.text.lastIndexOf(\">\", iter.ch - 1) : -1;\n if (gt == -1) { if (prevLine(iter)) continue; else return; }\n if (!tagAt(iter, gt + 1)) { iter.ch = gt; continue; }\n var lastSlash = iter.text.lastIndexOf(\"/\", gt);\n var selfClose = lastSlash > -1 && !/\\S/.test(iter.text.slice(lastSlash + 1, gt));\n iter.ch = gt + 1;\n return selfClose ? \"selfClose\" : \"regular\";\n }\n }\n\n function findMatchingClose(iter, tag) {\n var stack = [];\n for (;;) {\n var next = toNextTag(iter), end, startLine = iter.line, startCh = iter.ch - (next ? next[0].length : 0);\n if (!next || !(end = toTagEnd(iter))) return;\n if (end == \"selfClose\") continue;\n if (next[1]) { // closing tag\n for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == next[2]) {\n stack.length = i;\n break;\n }\n if (i < 0 && (!tag || tag == next[2])) return {\n tag: next[2],\n from: Pos(startLine, startCh),\n to: Pos(iter.line, iter.ch)\n };\n } else { // opening tag\n stack.push(next[2]);\n }\n }\n }\n function findMatchingOpen(iter, tag) {\n var stack = [];\n for (;;) {\n var prev = toPrevTag(iter);\n if (!prev) return;\n if (prev == \"selfClose\") { toTagStart(iter); continue; }\n var endLine = iter.line, endCh = iter.ch;\n var start = toTagStart(iter);\n if (!start) return;\n if (start[1]) { // closing tag\n stack.push(start[2]);\n } else { // opening tag\n for (var i = stack.length - 1; i >= 0; --i) if (stack[i] == start[2]) {\n stack.length = i;\n break;\n }\n if (i < 0 && (!tag || tag == start[2])) return {\n tag: start[2],\n from: Pos(iter.line, iter.ch),\n to: Pos(endLine, endCh)\n };\n }\n }\n }\n\n CodeMirror.registerHelper(\"fold\", \"xml\", function(cm, start) {\n var iter = new Iter(cm, start.line, 0);\n for (;;) {\n var openTag = toNextTag(iter), end;\n if (!openTag || iter.line != start.line || !(end = toTagEnd(iter))) return;\n if (!openTag[1] && end != \"selfClose\") {\n var start = Pos(iter.line, iter.ch);\n var close = findMatchingClose(iter, openTag[2]);\n return close && {from: start, to: close.from};\n }\n }\n });\n CodeMirror.findMatchingTag = function(cm, pos, range) {\n var iter = new Iter(cm, pos.line, pos.ch, range);\n if (iter.text.indexOf(\">\") == -1 && iter.text.indexOf(\"<\") == -1) return;\n var end = toTagEnd(iter), to = end && Pos(iter.line, iter.ch);\n var start = end && toTagStart(iter);\n if (!end || !start || cmp(iter, pos) > 0) return;\n var here = {from: Pos(iter.line, iter.ch), to: to, tag: start[2]};\n if (end == \"selfClose\") return {open: here, close: null, at: \"open\"};\n\n if (start[1]) { // closing tag\n return {open: findMatchingOpen(iter, start[2]), close: here, at: \"close\"};\n } else { // opening tag\n iter = new Iter(cm, to.line, to.ch, range);\n return {open: here, close: findMatchingClose(iter, start[2]), at: \"open\"};\n }\n };\n\n CodeMirror.findEnclosingTag = function(cm, pos, range) {\n var iter = new Iter(cm, pos.line, pos.ch, range);\n for (;;) {\n var open = findMatchingOpen(iter);\n if (!open) break;\n var forward = new Iter(cm, pos.line, pos.ch, range);\n var close = findMatchingClose(forward, open.tag);\n if (close) return {open: open, close: close};\n }\n };\n\n // Used by addon/edit/closetag.js\n CodeMirror.scanForClosingTag = function(cm, pos, name, end) {\n var iter = new Iter(cm, pos.line, pos.ch, end ? {from: 0, to: end} : null);\n return findMatchingClose(iter, name);\n };\n});\n","// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n\n var HINT_ELEMENT_CLASS = \"CodeMirror-hint\";\n var ACTIVE_HINT_ELEMENT_CLASS = \"CodeMirror-hint-active\";\n\n // This is the old interface, kept around for now to stay\n // backwards-compatible.\n CodeMirror.showHint = function(cm, getHints, options) {\n if (!getHints) return cm.showHint(options);\n if (options && options.async) getHints.async = true;\n var newOpts = {hint: getHints};\n if (options) for (var prop in options) newOpts[prop] = options[prop];\n return cm.showHint(newOpts);\n };\n\n CodeMirror.defineExtension(\"showHint\", function(options) {\n // We want a single cursor position.\n if (this.listSelections().length > 1 || this.somethingSelected()) return;\n\n if (this.state.completionActive) this.state.completionActive.close();\n var completion = this.state.completionActive = new Completion(this, options);\n var getHints = completion.options.hint;\n if (!getHints) return;\n\n CodeMirror.signal(this, \"startCompletion\", this);\n if (getHints.async)\n getHints(this, function(hints) { completion.showHints(hints); }, completion.options);\n else\n return completion.showHints(getHints(this, completion.options));\n });\n\n function Completion(cm, options) {\n this.cm = cm;\n this.options = this.buildOptions(options);\n this.widget = this.onClose = null;\n }\n\n Completion.prototype = {\n close: function() {\n if (!this.active()) return;\n this.cm.state.completionActive = null;\n\n if (this.widget) this.widget.close();\n if (this.onClose) this.onClose();\n CodeMirror.signal(this.cm, \"endCompletion\", this.cm);\n },\n\n active: function() {\n return this.cm.state.completionActive == this;\n },\n\n pick: function(data, i) {\n var completion = data.list[i];\n if (completion.hint) completion.hint(this.cm, data, completion);\n else this.cm.replaceRange(getText(completion), completion.from || data.from,\n completion.to || data.to, \"complete\");\n CodeMirror.signal(data, \"pick\", completion);\n this.close();\n },\n\n showHints: function(data) {\n if (!data || !data.list.length || !this.active()) return this.close();\n\n if (this.options.completeSingle && data.list.length == 1)\n this.pick(data, 0);\n else\n this.showWidget(data);\n },\n\n showWidget: function(data) {\n this.widget = new Widget(this, data);\n CodeMirror.signal(data, \"shown\");\n\n var debounce = 0, completion = this, finished;\n var closeOn = this.options.closeCharacters;\n var startPos = this.cm.getCursor(), startLen = this.cm.getLine(startPos.line).length;\n\n var requestAnimationFrame = window.requestAnimationFrame || function(fn) {\n return setTimeout(fn, 1000/60);\n };\n var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;\n\n function done() {\n if (finished) return;\n finished = true;\n completion.close();\n completion.cm.off(\"cursorActivity\", activity);\n if (data) CodeMirror.signal(data, \"close\");\n }\n\n function update() {\n if (finished) return;\n CodeMirror.signal(data, \"update\");\n var getHints = completion.options.hint;\n if (getHints.async)\n getHints(completion.cm, finishUpdate, completion.options);\n else\n finishUpdate(getHints(completion.cm, completion.options));\n }\n function finishUpdate(data_) {\n data = data_;\n if (finished) return;\n if (!data || !data.list.length) return done();\n if (completion.widget) completion.widget.close();\n completion.widget = new Widget(completion, data);\n }\n\n function clearDebounce() {\n if (debounce) {\n cancelAnimationFrame(debounce);\n debounce = 0;\n }\n }\n\n function activity() {\n clearDebounce();\n var pos = completion.cm.getCursor(), line = completion.cm.getLine(pos.line);\n if (pos.line != startPos.line || line.length - pos.ch != startLen - startPos.ch ||\n pos.ch < startPos.ch || completion.cm.somethingSelected() ||\n (pos.ch && closeOn.test(line.charAt(pos.ch - 1)))) {\n completion.close();\n } else {\n debounce = requestAnimationFrame(update);\n if (completion.widget) completion.widget.close();\n }\n }\n this.cm.on(\"cursorActivity\", activity);\n this.onClose = done;\n },\n\n buildOptions: function(options) {\n var editor = this.cm.options.hintOptions;\n var out = {};\n for (var prop in defaultOptions) out[prop] = defaultOptions[prop];\n if (editor) for (var prop in editor)\n if (editor[prop] !== undefined) out[prop] = editor[prop];\n if (options) for (var prop in options)\n if (options[prop] !== undefined) out[prop] = options[prop];\n return out;\n }\n };\n\n function getText(completion) {\n if (typeof completion == \"string\") return completion;\n else return completion.text;\n }\n\n function buildKeyMap(completion, handle) {\n var baseMap = {\n Up: function() {handle.moveFocus(-1);},\n Down: function() {handle.moveFocus(1);},\n PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},\n PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},\n Home: function() {handle.setFocus(0);},\n End: function() {handle.setFocus(handle.length - 1);},\n Enter: handle.pick,\n Tab: handle.pick,\n Esc: handle.close\n };\n var custom = completion.options.customKeys;\n var ourMap = custom ? {} : baseMap;\n function addBinding(key, val) {\n var bound;\n if (typeof val != \"string\")\n bound = function(cm) { return val(cm, handle); };\n // This mechanism is deprecated\n else if (baseMap.hasOwnProperty(val))\n bound = baseMap[val];\n else\n bound = val;\n ourMap[key] = bound;\n }\n if (custom)\n for (var key in custom) if (custom.hasOwnProperty(key))\n addBinding(key, custom[key]);\n var extra = completion.options.extraKeys;\n if (extra)\n for (var key in extra) if (extra.hasOwnProperty(key))\n addBinding(key, extra[key]);\n return ourMap;\n }\n\n function getHintElement(hintsElement, el) {\n while (el && el != hintsElement) {\n if (el.nodeName.toUpperCase() === \"LI\" && el.parentNode == hintsElement) return el;\n el = el.parentNode;\n }\n }\n\n function Widget(completion, data) {\n this.completion = completion;\n this.data = data;\n var widget = this, cm = completion.cm;\n\n var hints = this.hints = document.createElement(\"ul\");\n hints.className = \"CodeMirror-hints\";\n this.selectedHint = data.selectedHint || 0;\n\n var completions = data.list;\n for (var i = 0; i < completions.length; ++i) {\n var elt = hints.appendChild(document.createElement(\"li\")), cur = completions[i];\n var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? \"\" : \" \" + ACTIVE_HINT_ELEMENT_CLASS);\n if (cur.className != null) className = cur.className + \" \" + className;\n elt.className = className;\n if (cur.render) cur.render(elt, data, cur);\n else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));\n elt.hintId = i;\n }\n\n var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);\n var left = pos.left, top = pos.bottom, below = true;\n hints.style.left = left + \"px\";\n hints.style.top = top + \"px\";\n // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.\n var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);\n var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);\n (completion.options.container || document.body).appendChild(hints);\n var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;\n if (overlapY > 0) {\n var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);\n if (curTop - height > 0) { // Fits above cursor\n hints.style.top = (top = pos.top - height) + \"px\";\n below = false;\n } else if (height > winH) {\n hints.style.height = (winH - 5) + \"px\";\n hints.style.top = (top = pos.bottom - box.top) + \"px\";\n var cursor = cm.getCursor();\n if (data.from.ch != cursor.ch) {\n pos = cm.cursorCoords(cursor);\n hints.style.left = (left = pos.left) + \"px\";\n box = hints.getBoundingClientRect();\n }\n }\n }\n var overlapX = box.right - winW;\n if (overlapX > 0) {\n if (box.right - box.left > winW) {\n hints.style.width = (winW - 5) + \"px\";\n overlapX -= (box.right - box.left) - winW;\n }\n hints.style.left = (left = pos.left - overlapX) + \"px\";\n }\n\n cm.addKeyMap(this.keyMap = buildKeyMap(completion, {\n moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },\n setFocus: function(n) { widget.changeActive(n); },\n menuSize: function() { return widget.screenAmount(); },\n length: completions.length,\n close: function() { completion.close(); },\n pick: function() { widget.pick(); },\n data: data\n }));\n\n if (completion.options.closeOnUnfocus) {\n var closingOnBlur;\n cm.on(\"blur\", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });\n cm.on(\"focus\", this.onFocus = function() { clearTimeout(closingOnBlur); });\n }\n\n var startScroll = cm.getScrollInfo();\n cm.on(\"scroll\", this.onScroll = function() {\n var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();\n var newTop = top + startScroll.top - curScroll.top;\n var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);\n if (!below) point += hints.offsetHeight;\n if (point <= editor.top || point >= editor.bottom) return completion.close();\n hints.style.top = newTop + \"px\";\n hints.style.left = (left + startScroll.left - curScroll.left) + \"px\";\n });\n\n CodeMirror.on(hints, \"dblclick\", function(e) {\n var t = getHintElement(hints, e.target || e.srcElement);\n if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}\n });\n\n CodeMirror.on(hints, \"click\", function(e) {\n var t = getHintElement(hints, e.target || e.srcElement);\n if (t && t.hintId != null) {\n widget.changeActive(t.hintId);\n if (completion.options.completeOnSingleClick) widget.pick();\n }\n });\n\n CodeMirror.on(hints, \"mousedown\", function() {\n setTimeout(function(){cm.focus();}, 20);\n });\n\n CodeMirror.signal(data, \"select\", completions[0], hints.firstChild);\n return true;\n }\n\n Widget.prototype = {\n close: function() {\n if (this.completion.widget != this) return;\n this.completion.widget = null;\n this.hints.parentNode.removeChild(this.hints);\n this.completion.cm.removeKeyMap(this.keyMap);\n\n var cm = this.completion.cm;\n if (this.completion.options.closeOnUnfocus) {\n cm.off(\"blur\", this.onBlur);\n cm.off(\"focus\", this.onFocus);\n }\n cm.off(\"scroll\", this.onScroll);\n },\n\n pick: function() {\n this.completion.pick(this.data, this.selectedHint);\n },\n\n changeActive: function(i, avoidWrap) {\n if (i >= this.data.list.length)\n i = avoidWrap ? this.data.list.length - 1 : 0;\n else if (i < 0)\n i = avoidWrap ? 0 : this.data.list.length - 1;\n if (this.selectedHint == i) return;\n var node = this.hints.childNodes[this.selectedHint];\n node.className = node.className.replace(\" \" + ACTIVE_HINT_ELEMENT_CLASS, \"\");\n node = this.hints.childNodes[this.selectedHint = i];\n node.className += \" \" + ACTIVE_HINT_ELEMENT_CLASS;\n if (node.offsetTop < this.hints.scrollTop)\n this.hints.scrollTop = node.offsetTop - 3;\n else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)\n this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;\n CodeMirror.signal(this.data, \"select\", this.data.list[this.selectedHint], node);\n },\n\n screenAmount: function() {\n return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;\n }\n };\n\n CodeMirror.registerHelper(\"hint\", \"auto\", function(cm, options) {\n var helpers = cm.getHelpers(cm.getCursor(), \"hint\"), words;\n if (helpers.length) {\n for (var i = 0; i < helpers.length; i++) {\n var cur = helpers[i](cm, options);\n if (cur && cur.list.length) return cur;\n }\n } else if (words = cm.getHelper(cm.getCursor(), \"hintWords\")) {\n if (words) return CodeMirror.hint.fromList(cm, {words: words});\n } else if (CodeMirror.hint.anyword) {\n return CodeMirror.hint.anyword(cm, options);\n }\n });\n\n CodeMirror.registerHelper(\"hint\", \"fromList\", function(cm, options) {\n var cur = cm.getCursor(), token = cm.getTokenAt(cur);\n var found = [];\n for (var i = 0; i < options.words.length; i++) {\n var word = options.words[i];\n if (word.slice(0, token.string.length) == token.string)\n found.push(word);\n }\n\n if (found.length) return {\n list: found,\n from: CodeMirror.Pos(cur.line, token.start),\n to: CodeMirror.Pos(cur.line, token.end)\n };\n });\n\n CodeMirror.commands.autocomplete = CodeMirror.showHint;\n\n var defaultOptions = {\n hint: CodeMirror.hint.auto,\n completeSingle: true,\n alignWithWord: true,\n closeCharacters: /[\\s()\\[\\]{};:>,]/,\n closeOnUnfocus: true,\n completeOnSingleClick: false,\n container: null,\n customKeys: null,\n extraKeys: null\n };\n\n CodeMirror.defineOption(\"hintOptions\", null);\n});\n","// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n\"use strict\";\n\nCodeMirror.runMode = function(string, modespec, callback, options) {\n var mode = CodeMirror.getMode(CodeMirror.defaults, modespec);\n var ie = /MSIE \\d/.test(navigator.userAgent);\n var ie_lt9 = ie && (document.documentMode == null || document.documentMode < 9);\n\n if (callback.nodeType == 1) {\n var tabSize = (options && options.tabSize) || CodeMirror.defaults.tabSize;\n var node = callback, col = 0;\n node.innerHTML = \"\";\n callback = function(text, style) {\n if (text == \"\\n\") {\n // Emitting LF or CRLF on IE8 or earlier results in an incorrect display.\n // Emitting a carriage return makes everything ok.\n node.appendChild(document.createTextNode(ie_lt9 ? '\\r' : text));\n col = 0;\n return;\n }\n var content = \"\";\n // replace tabs\n for (var pos = 0;;) {\n var idx = text.indexOf(\"\\t\", pos);\n if (idx == -1) {\n content += text.slice(pos);\n col += text.length - pos;\n break;\n } else {\n col += idx - pos;\n content += text.slice(pos, idx);\n var size = tabSize - col % tabSize;\n col += size;\n for (var i = 0; i < size; ++i) content += \" \";\n pos = idx + 1;\n }\n }\n\n if (style) {\n var sp = node.appendChild(document.createElement(\"span\"));\n sp.className = \"cm-\" + style.replace(/ +/g, \" cm-\");\n sp.appendChild(document.createTextNode(content));\n } else {\n node.appendChild(document.createTextNode(content));\n }\n };\n }\n\n var lines = CodeMirror.splitLines(string), state = (options && options.state) || CodeMirror.startState(mode);\n for (var i = 0, e = lines.length; i < e; ++i) {\n if (i) callback(\"\\n\");\n var stream = new CodeMirror.StringStream(lines[i]);\n if (!stream.string && mode.blankLine) mode.blankLine(state);\n while (!stream.eol()) {\n var style = mode.token(stream, state);\n callback(stream.current(), style, i, stream.start, state);\n stream.start = stream.pos;\n }\n }\n};\n\n});\n","// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n mod(require(\"../../lib/codemirror\"));\n else if (typeof define == \"function\" && define.amd) // AMD\n define([\"../../lib/codemirror\"], mod);\n else // Plain browser env\n mod(CodeMirror);\n})(function(CodeMirror) {\n \"use strict\";\n var Pos = CodeMirror.Pos;\n\n function SearchCursor(doc, query, pos, caseFold) {\n this.atOccurrence = false; this.doc = doc;\n if (caseFold == null && typeof query == \"string\") caseFold = false;\n\n pos = pos ? doc.clipPos(pos) : Pos(0, 0);\n this.pos = {from: pos, to: pos};\n\n // The matches method is filled in based on the type of query.\n // It takes a position and a direction, and returns an object\n // describing the next occurrence of the query, or null if no\n // more matches were found.\n if (typeof query != \"string\") { // Regexp match\n if (!query.global) query = new RegExp(query.source, query.ignoreCase ? \"ig\" : \"g\");\n this.matches = function(reverse, pos) {\n if (reverse) {\n query.lastIndex = 0;\n var line = doc.getLine(pos.line).slice(0, pos.ch), cutOff = 0, match, start;\n for (;;) {\n query.lastIndex = cutOff;\n var newMatch = query.exec(line);\n if (!newMatch) break;\n match = newMatch;\n start = match.index;\n cutOff = match.index + (match[0].length || 1);\n if (cutOff == line.length) break;\n }\n var matchLen = (match && match[0].length) || 0;\n if (!matchLen) {\n if (start == 0 && line.length == 0) {match = undefined;}\n else if (start != doc.getLine(pos.line).length) {\n matchLen++;\n }\n }\n } else {\n query.lastIndex = pos.ch;\n var line = doc.getLine(pos.line), match = query.exec(line);\n var matchLen = (match && match[0].length) || 0;\n var start = match && match.index;\n if (start + matchLen != line.length && !matchLen) matchLen = 1;\n }\n if (match && matchLen)\n return {from: Pos(pos.line, start),\n to: Pos(pos.line, start + matchLen),\n match: match};\n };\n } else { // String query\n var origQuery = query;\n if (caseFold) query = query.toLowerCase();\n var fold = caseFold ? function(str){return str.toLowerCase();} : function(str){return str;};\n var target = query.split(\"\\n\");\n // Different methods for single-line and multi-line queries\n if (target.length == 1) {\n if (!query.length) {\n // Empty string would match anything and never progress, so\n // we define it to match nothing instead.\n this.matches = function() {};\n } else {\n this.matches = function(reverse, pos) {\n if (reverse) {\n var orig = doc.getLine(pos.line).slice(0, pos.ch), line = fold(orig);\n var match = line.lastIndexOf(query);\n if (match > -1) {\n match = adjustPos(orig, line, match);\n return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};\n }\n } else {\n var orig = doc.getLine(pos.line).slice(pos.ch), line = fold(orig);\n var match = line.indexOf(query);\n if (match > -1) {\n match = adjustPos(orig, line, match) + pos.ch;\n return {from: Pos(pos.line, match), to: Pos(pos.line, match + origQuery.length)};\n }\n }\n };\n }\n } else {\n var origTarget = origQuery.split(\"\\n\");\n this.matches = function(reverse, pos) {\n var last = target.length - 1;\n if (reverse) {\n if (pos.line - (target.length - 1) < doc.firstLine()) return;\n if (fold(doc.getLine(pos.line).slice(0, origTarget[last].length)) != target[target.length - 1]) return;\n var to = Pos(pos.line, origTarget[last].length);\n for (var ln = pos.line - 1, i = last - 1; i >= 1; --i, --ln)\n if (target[i] != fold(doc.getLine(ln))) return;\n var line = doc.getLine(ln), cut = line.length - origTarget[0].length;\n if (fold(line.slice(cut)) != target[0]) return;\n return {from: Pos(ln, cut), to: to};\n } else {\n if (pos.line + (target.length - 1) > doc.lastLine()) return;\n var line = doc.getLine(pos.line), cut = line.length - origTarget[0].length;\n if (fold(line.slice(cut)) != target[0]) return;\n var from = Pos(pos.line, cut);\n for (var ln = pos.line + 1, i = 1; i < last; ++i, ++ln)\n if (target[i] != fold(doc.getLine(ln))) return;\n if (fold(doc.getLine(ln).slice(0, origTarget[last].length)) != target[last]) return;\n return {from: from, to: Pos(ln, origTarget[last].length)};\n }\n };\n }\n }\n }\n\n SearchCursor.prototype = {\n findNext: function() {return this.find(false);},\n findPrevious: function() {return this.find(true);},\n\n find: function(reverse) {\n var self = this, pos = this.doc.clipPos(reverse ? this.pos.from : this.pos.to);\n function savePosAndFail(line) {\n var pos = Pos(line, 0);\n self.pos = {from: pos, to: pos};\n self.atOccurrence = false;\n return false;\n }\n\n for (;;) {\n if (this.pos = this.matches(reverse, pos)) {\n this.atOccurrence = true;\n return this.pos.match || true;\n }\n if (reverse) {\n if (!pos.line) return savePosAndFail(0);\n pos = Pos(pos.line-1, this.doc.getLine(pos.line-1).length);\n }\n else {\n var maxLine = this.doc.lineCount();\n if (pos.line == maxLine - 1) return savePosAndFail(maxLine);\n pos = Pos(pos.line + 1, 0);\n }\n }\n },\n\n from: function() {if (this.atOccurrence) return this.pos.from;},\n to: function() {if (this.atOccurrence) return this.pos.to;},\n\n replace: function(newText) {\n if (!this.atOccurrence) return;\n var lines = CodeMirror.splitLines(newText);\n this.doc.replaceRange(lines, this.pos.from, this.pos.to);\n this.pos.to = Pos(this.pos.from.line + lines.length - 1,\n lines[lines.length - 1].length + (lines.length == 1 ? this.pos.from.ch : 0));\n }\n };\n\n // Maps a position in a case-folded line back to a position in the original line\n // (compensating for codepoints increasing in number during folding)\n function adjustPos(orig, folded, pos) {\n if (orig.length == folded.length) return pos;\n for (var pos1 = Math.min(pos, orig.length);;) {\n var len1 = orig.slice(0, pos1).toLowerCase().length;\n if (len1 < pos) ++pos1;\n else if (len1 > pos) --pos1;\n else return pos1;\n }\n }\n\n CodeMirror.defineExtension(\"getSearchCursor\", function(query, pos, caseFold) {\n return new SearchCursor(this.doc, query, pos, caseFold);\n });\n CodeMirror.defineDocExtension(\"getSearchCursor\", function(query, pos, caseFold) {\n return new SearchCursor(this, query, pos, caseFold);\n });\n\n CodeMirror.defineExtension(\"selectMatches\", function(query, caseFold) {\n var ranges = [], next;\n var cur = this.getSearchCursor(query, this.getCursor(\"from\"), caseFold);\n while (next = cur.findNext()) {\n if (CodeMirror.cmpPos(cur.to(), this.getCursor(\"to\")) > 0) break;\n ranges.push({anchor: cur.from(), head: cur.to()});\n }\n if (ranges.length)\n this.setSelections(ranges, 0);\n });\n});\n","// CodeMirror, copyright (c) by Marijn Haverbeke and others\n// Distributed under an MIT license: http://codemirror.net/LICENSE\n\n// This is CodeMirror (http://codemirror.net), a code editor\n// implemented in JavaScript on top of the browser's DOM.\n//\n// You can find some technical background for some of the code below\n// at http://marijnhaverbeke.nl/blog/#cm-internals .\n\n(function(mod) {\n if (typeof exports == \"object\" && typeof module == \"object\") // CommonJS\n module.exports = mod();\n else if (typeof define == \"function\" && define.amd) // AMD\n return define([], mod);\n else // Plain browser env\n this.CodeMirror = mod();\n})(function() {\n \"use strict\";\n\n // BROWSER SNIFFING\n\n // Kludges for bugs and behavior differences that can't be feature\n // detected are enabled based on userAgent etc sniffing.\n\n var gecko = /gecko\\/\\d/i.test(navigator.userAgent);\n // ie_uptoN means Internet Explorer version N or lower\n var ie_upto10 = /MSIE \\d/.test(navigator.userAgent);\n var ie_11up = /Trident\\/(?:[7-9]|\\d{2,})\\..*rv:(\\d+)/.exec(navigator.userAgent);\n var ie = ie_upto10 || ie_11up;\n var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);\n var webkit = /WebKit\\//.test(navigator.userAgent);\n var qtwebkit = webkit && /Qt\\/\\d+\\.\\d+/.test(navigator.userAgent);\n var chrome = /Chrome\\//.test(navigator.userAgent);\n var presto = /Opera\\//.test(navigator.userAgent);\n var safari = /Apple Computer/.test(navigator.vendor);\n var khtml = /KHTML\\//.test(navigator.userAgent);\n var mac_geMountainLion = /Mac OS X 1\\d\\D([8-9]|\\d\\d)\\D/.test(navigator.userAgent);\n var phantom = /PhantomJS/.test(navigator.userAgent);\n\n var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\\/\\w+/.test(navigator.userAgent);\n // This is woefully incomplete. Suggestions for alternative methods welcome.\n var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);\n var mac = ios || /Mac/.test(navigator.platform);\n var windows = /win/i.test(navigator.platform);\n\n var presto_version = presto && navigator.userAgent.match(/Version\\/(\\d*\\.\\d*)/);\n if (presto_version) presto_version = Number(presto_version[1]);\n if (presto_version && presto_version >= 15) { presto = false; webkit = true; }\n // Some browsers use the wrong event properties to signal cmd/ctrl on OS X\n var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));\n var captureRightClick = gecko || (ie && ie_version >= 9);\n\n // Optimize some code when these features are not used.\n var sawReadOnlySpans = false, sawCollapsedSpans = false;\n\n // EDITOR CONSTRUCTOR\n\n // A CodeMirror instance represents an editor. This is the object\n // that user code is usually dealing with.\n\n function CodeMirror(place, options) {\n if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);\n\n this.options = options = options ? copyObj(options) : {};\n // Determine effective options based on given values and defaults.\n copyObj(defaults, options, false);\n setGuttersForLineNumbers(options);\n\n var doc = options.value;\n if (typeof doc == \"string\") doc = new Doc(doc, options.mode);\n this.doc = doc;\n\n var display = this.display = new Display(place, doc);\n display.wrapper.CodeMirror = this;\n updateGutters(this);\n themeChanged(this);\n if (options.lineWrapping)\n this.display.wrapper.className += \" CodeMirror-wrap\";\n if (options.autofocus && !mobile) focusInput(this);\n initScrollbars(this);\n\n this.state = {\n keyMaps: [], // stores maps added by addKeyMap\n overlays: [], // highlighting overlays, as added by addOverlay\n modeGen: 0, // bumped when mode/overlay changes, used to invalidate highlighting info\n overwrite: false, focused: false,\n suppressEdits: false, // used to disable editing during key handlers when in readOnly mode\n pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in readInput\n draggingText: false,\n highlight: new Delayed(), // stores highlight worker timeout\n keySeq: null // Unfinished key sequence\n };\n\n // Override magic textarea content restore that IE sometimes does\n // on our hidden textarea on reload\n if (ie && ie_version < 11) setTimeout(bind(resetInput, this, true), 20);\n\n registerEventHandlers(this);\n ensureGlobalHandlers();\n\n startOperation(this);\n this.curOp.forceUpdate = true;\n attachDoc(this, doc);\n\n if ((options.autofocus && !mobile) || activeElt() == display.input)\n setTimeout(bind(onFocus, this), 20);\n else\n onBlur(this);\n\n for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))\n optionHandlers[opt](this, options[opt], Init);\n maybeUpdateLineNumberWidth(this);\n for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);\n endOperation(this);\n // Suppress optimizelegibility in Webkit, since it breaks text\n // measuring on line wrapping boundaries.\n if (webkit && options.lineWrapping &&\n getComputedStyle(display.lineDiv).textRendering == \"optimizelegibility\")\n display.lineDiv.style.textRendering = \"auto\";\n }\n\n // DISPLAY CONSTRUCTOR\n\n // The display handles the DOM integration, both for input reading\n // and content drawing. It holds references to DOM nodes and\n // display-related state.\n\n function Display(place, doc) {\n var d = this;\n\n // The semihidden textarea that is focused when the editor is\n // focused, and receives input.\n var input = d.input = elt(\"textarea\", null, null, \"position: absolute; padding: 0; width: 1px; height: 1em; outline: none\");\n // The textarea is kept positioned near the cursor to prevent the\n // fact that it'll be scrolled into view on input from scrolling\n // our fake cursor out of view. On webkit, when wrap=off, paste is\n // very slow. So make the area wide instead.\n if (webkit) input.style.width = \"1000px\";\n else input.setAttribute(\"wrap\", \"off\");\n // If border: 0; -- iOS fails to open keyboard (issue #1287)\n if (ios) input.style.border = \"1px solid black\";\n input.setAttribute(\"autocorrect\", \"off\"); input.setAttribute(\"autocapitalize\", \"off\"); input.setAttribute(\"spellcheck\", \"false\");\n\n // Wraps and hides input textarea\n d.inputDiv = elt(\"div\", [input], null, \"overflow: hidden; position: relative; width: 3px; height: 0px;\");\n // Covers bottom-right square when both scrollbars are present.\n d.scrollbarFiller = elt(\"div\", null, \"CodeMirror-scrollbar-filler\");\n d.scrollbarFiller.setAttribute(\"not-content\", \"true\");\n // Covers bottom of gutter when coverGutterNextToScrollbar is on\n // and h scrollbar is present.\n d.gutterFiller = elt(\"div\", null, \"CodeMirror-gutter-filler\");\n d.gutterFiller.setAttribute(\"not-content\", \"true\");\n // Will contain the actual code, positioned to cover the viewport.\n d.lineDiv = elt(\"div\", null, \"CodeMirror-code\");\n // Elements are added to these to represent selection and cursors.\n d.selectionDiv = elt(\"div\", null, null, \"position: relative; z-index: 1\");\n d.cursorDiv = elt(\"div\", null, \"CodeMirror-cursors\");\n // A visibility: hidden element used to find the size of things.\n d.measure = elt(\"div\", null, \"CodeMirror-measure\");\n // When lines outside of the viewport are measured, they are drawn in this.\n d.lineMeasure = elt(\"div\", null, \"CodeMirror-measure\");\n // Wraps everything that needs to exist inside the vertically-padded coordinate system\n d.lineSpace = elt(\"div\", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],\n null, \"position: relative; outline: none\");\n // Moved around its parent to cover visible view.\n d.mover = elt(\"div\", [elt(\"div\", [d.lineSpace], \"CodeMirror-lines\")], null, \"position: relative\");\n // Set to the height of the document, allowing scrolling.\n d.sizer = elt(\"div\", [d.mover], \"CodeMirror-sizer\");\n d.sizerWidth = null;\n // Behavior of elts with overflow: auto and padding is\n // inconsistent across browsers. This is used to ensure the\n // scrollable area is big enough.\n d.heightForcer = elt(\"div\", null, null, \"position: absolute; height: \" + scrollerGap + \"px; width: 1px;\");\n // Will contain the gutters, if any.\n d.gutters = elt(\"div\", null, \"CodeMirror-gutters\");\n d.lineGutter = null;\n // Actual scrollable element.\n d.scroller = elt(\"div\", [d.sizer, d.heightForcer, d.gutters], \"CodeMirror-scroll\");\n d.scroller.setAttribute(\"tabIndex\", \"-1\");\n // The element in which the editor lives.\n d.wrapper = elt(\"div\", [d.inputDiv, d.scrollbarFiller, d.gutterFiller, d.scroller], \"CodeMirror\");\n\n // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)\n if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }\n // Needed to hide big blue blinking cursor on Mobile Safari\n if (ios) input.style.width = \"0px\";\n if (!webkit) d.scroller.draggable = true;\n // Needed to handle Tab key in KHTML\n if (khtml) { d.inputDiv.style.height = \"1px\"; d.inputDiv.style.position = \"absolute\"; }\n\n if (place) {\n if (place.appendChild) place.appendChild(d.wrapper);\n else place(d.wrapper);\n }\n\n // Current rendered range (may be bigger than the view window).\n d.viewFrom = d.viewTo = doc.first;\n d.reportedViewFrom = d.reportedViewTo = doc.first;\n // Information about the rendered lines.\n d.view = [];\n d.renderedView = null;\n // Holds info about a single rendered line when it was rendered\n // for measurement, while not in view.\n d.externalMeasured = null;\n // Empty space (in pixels) above the view\n d.viewOffset = 0;\n d.lastWrapHeight = d.lastWrapWidth = 0;\n d.updateLineNumbers = null;\n\n d.nativeBarWidth = d.barHeight = d.barWidth = 0;\n d.scrollbarsClipped = false;\n\n // Used to only resize the line number gutter when necessary (when\n // the amount of lines crosses a boundary that makes its width change)\n d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;\n // See readInput and resetInput\n d.prevInput = \"\";\n // Set to true when a non-horizontal-scrolling line widget is\n // added. As an optimization, line widget aligning is skipped when\n // this is false.\n d.alignWidgets = false;\n // Flag that indicates whether we expect input to appear real soon\n // now (after some event like 'keypress' or 'input') and are\n // polling intensively.\n d.pollingFast = false;\n // Self-resetting timeout for the poller\n d.poll = new Delayed();\n\n d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;\n\n // Tracks when resetInput has punted to just putting a short\n // string into the textarea instead of the full selection.\n d.inaccurateSelection = false;\n\n // Tracks the maximum line length so that the horizontal scrollbar\n // can be kept static when scrolling.\n d.maxLine = null;\n d.maxLineLength = 0;\n d.maxLineChanged = false;\n\n // Used for measuring wheel scrolling granularity\n d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;\n\n // True when shift is held down.\n d.shift = false;\n\n // Used to track whether anything happened since the context menu\n // was opened.\n d.selForContextMenu = null;\n }\n\n // STATE UPDATES\n\n // Used to get the editor into a consistent state again when options change.\n\n function loadMode(cm) {\n cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);\n resetModeState(cm);\n }\n\n function resetModeState(cm) {\n cm.doc.iter(function(line) {\n if (line.stateAfter) line.stateAfter = null;\n if (line.styles) line.styles = null;\n });\n cm.doc.frontier = cm.doc.first;\n startWorker(cm, 100);\n cm.state.modeGen++;\n if (cm.curOp) regChange(cm);\n }\n\n function wrappingChanged(cm) {\n if (cm.options.lineWrapping) {\n addClass(cm.display.wrapper, \"CodeMirror-wrap\");\n cm.display.sizer.style.minWidth = \"\";\n cm.display.sizerWidth = null;\n } else {\n rmClass(cm.display.wrapper, \"CodeMirror-wrap\");\n findMaxLine(cm);\n }\n estimateLineHeights(cm);\n regChange(cm);\n clearCaches(cm);\n setTimeout(function(){updateScrollbars(cm);}, 100);\n }\n\n // Returns a function that estimates the height of a line, to use as\n // first approximation until the line becomes visible (and is thus\n // properly measurable).\n function estimateHeight(cm) {\n var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;\n var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);\n return function(line) {\n if (lineIsHidden(cm.doc, line)) return 0;\n\n var widgetsHeight = 0;\n if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {\n if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;\n }\n\n if (wrapping)\n return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;\n else\n return widgetsHeight + th;\n };\n }\n\n function estimateLineHeights(cm) {\n var doc = cm.doc, est = estimateHeight(cm);\n doc.iter(function(line) {\n var estHeight = est(line);\n if (estHeight != line.height) updateLineHeight(line, estHeight);\n });\n }\n\n function themeChanged(cm) {\n cm.display.wrapper.className = cm.display.wrapper.className.replace(/\\s*cm-s-\\S+/g, \"\") +\n cm.options.theme.replace(/(^|\\s)\\s*/g, \" cm-s-\");\n clearCaches(cm);\n }\n\n function guttersChanged(cm) {\n updateGutters(cm);\n regChange(cm);\n setTimeout(function(){alignHorizontally(cm);}, 20);\n }\n\n // Rebuild the gutter elements, ensure the margin to the left of the\n // code matches their width.\n function updateGutters(cm) {\n var gutters = cm.display.gutters, specs = cm.options.gutters;\n removeChildren(gutters);\n for (var i = 0; i < specs.length; ++i) {\n var gutterClass = specs[i];\n var gElt = gutters.appendChild(elt(\"div\", null, \"CodeMirror-gutter \" + gutterClass));\n if (gutterClass == \"CodeMirror-linenumbers\") {\n cm.display.lineGutter = gElt;\n gElt.style.width = (cm.display.lineNumWidth || 1) + \"px\";\n }\n }\n gutters.style.display = i ? \"\" : \"none\";\n updateGutterSpace(cm);\n }\n\n function updateGutterSpace(cm) {\n var width = cm.display.gutters.offsetWidth;\n cm.display.sizer.style.marginLeft = width + \"px\";\n }\n\n // Compute the character length of a line, taking into account\n // collapsed ranges (see markText) that might hide parts, and join\n // other lines onto it.\n function lineLength(line) {\n if (line.height == 0) return 0;\n var len = line.text.length, merged, cur = line;\n while (merged = collapsedSpanAtStart(cur)) {\n var found = merged.find(0, true);\n cur = found.from.line;\n len += found.from.ch - found.to.ch;\n }\n cur = line;\n while (merged = collapsedSpanAtEnd(cur)) {\n var found = merged.find(0, true);\n len -= cur.text.length - found.from.ch;\n cur = found.to.line;\n len += cur.text.length - found.to.ch;\n }\n return len;\n }\n\n // Find the longest line in the document.\n function findMaxLine(cm) {\n var d = cm.display, doc = cm.doc;\n d.maxLine = getLine(doc, doc.first);\n d.maxLineLength = lineLength(d.maxLine);\n d.maxLineChanged = true;\n doc.iter(function(line) {\n var len = lineLength(line);\n if (len > d.maxLineLength) {\n d.maxLineLength = len;\n d.maxLine = line;\n }\n });\n }\n\n // Make sure the gutters options contains the element\n // \"CodeMirror-linenumbers\" when the lineNumbers option is true.\n function setGuttersForLineNumbers(options) {\n var found = indexOf(options.gutters, \"CodeMirror-linenumbers\");\n if (found == -1 && options.lineNumbers) {\n options.gutters = options.gutters.concat([\"CodeMirror-linenumbers\"]);\n } else if (found > -1 && !options.lineNumbers) {\n options.gutters = options.gutters.slice(0);\n options.gutters.splice(found, 1);\n }\n }\n\n // SCROLLBARS\n\n // Prepare DOM reads needed to update the scrollbars. Done in one\n // shot to minimize update/measure roundtrips.\n function measureForScrollbars(cm) {\n var d = cm.display, gutterW = d.gutters.offsetWidth;\n var docH = Math.round(cm.doc.height + paddingVert(cm.display));\n return {\n clientHeight: d.scroller.clientHeight,\n viewHeight: d.wrapper.clientHeight,\n scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,\n viewWidth: d.wrapper.clientWidth,\n barLeft: cm.options.fixedGutter ? gutterW : 0,\n docHeight: docH,\n scrollHeight: docH + scrollGap(cm) + d.barHeight,\n nativeBarWidth: d.nativeBarWidth,\n gutterWidth: gutterW\n };\n }\n\n function NativeScrollbars(place, scroll, cm) {\n this.cm = cm;\n var vert = this.vert = elt(\"div\", [elt(\"div\", null, null, \"min-width: 1px\")], \"CodeMirror-vscrollbar\");\n var horiz = this.horiz = elt(\"div\", [elt(\"div\", null, null, \"height: 100%; min-height: 1px\")], \"CodeMirror-hscrollbar\");\n place(vert); place(horiz);\n\n on(vert, \"scroll\", function() {\n if (vert.clientHeight) scroll(vert.scrollTop, \"vertical\");\n });\n on(horiz, \"scroll\", function() {\n if (horiz.clientWidth) scroll(horiz.scrollLeft, \"horizontal\");\n });\n\n this.checkedOverlay = false;\n // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).\n if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = \"18px\";\n }\n\n NativeScrollbars.prototype = copyObj({\n update: function(measure) {\n var needsH = measure.scrollWidth > measure.clientWidth + 1;\n var needsV = measure.scrollHeight > measure.clientHeight + 1;\n var sWidth = measure.nativeBarWidth;\n\n if (needsV) {\n this.vert.style.display = \"block\";\n this.vert.style.bottom = needsH ? sWidth + \"px\" : \"0\";\n var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);\n // A bug in IE8 can cause this value to be negative, so guard it.\n this.vert.firstChild.style.height =\n Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + \"px\";\n } else {\n this.vert.style.display = \"\";\n this.vert.firstChild.style.height = \"0\";\n }\n\n if (needsH) {\n this.horiz.style.display = \"block\";\n this.horiz.style.right = needsV ? sWidth + \"px\" : \"0\";\n this.horiz.style.left = measure.barLeft + \"px\";\n var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);\n this.horiz.firstChild.style.width =\n (measure.scrollWidth - measure.clientWidth + totalWidth) + \"px\";\n } else {\n this.horiz.style.display = \"\";\n this.horiz.firstChild.style.width = \"0\";\n }\n\n if (!this.checkedOverlay && measure.clientHeight > 0) {\n if (sWidth == 0) this.overlayHack();\n this.checkedOverlay = true;\n }\n\n return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};\n },\n setScrollLeft: function(pos) {\n if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;\n },\n setScrollTop: function(pos) {\n if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;\n },\n overlayHack: function() {\n var w = mac && !mac_geMountainLion ? \"12px\" : \"18px\";\n this.horiz.style.minHeight = this.vert.style.minWidth = w;\n var self = this;\n var barMouseDown = function(e) {\n if (e_target(e) != self.vert && e_target(e) != self.horiz)\n operation(self.cm, onMouseDown)(e);\n };\n on(this.vert, \"mousedown\", barMouseDown);\n on(this.horiz, \"mousedown\", barMouseDown);\n },\n clear: function() {\n var parent = this.horiz.parentNode;\n parent.removeChild(this.horiz);\n parent.removeChild(this.vert);\n }\n }, NativeScrollbars.prototype);\n\n function NullScrollbars() {}\n\n NullScrollbars.prototype = copyObj({\n update: function() { return {bottom: 0, right: 0}; },\n setScrollLeft: function() {},\n setScrollTop: function() {},\n clear: function() {}\n }, NullScrollbars.prototype);\n\n CodeMirror.scrollbarModel = {\"native\": NativeScrollbars, \"null\": NullScrollbars};\n\n function initScrollbars(cm) {\n if (cm.display.scrollbars) {\n cm.display.scrollbars.clear();\n if (cm.display.scrollbars.addClass)\n rmClass(cm.display.wrapper, cm.display.scrollbars.addClass);\n }\n\n cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) {\n cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);\n on(node, \"mousedown\", function() {\n if (cm.state.focused) setTimeout(bind(focusInput, cm), 0);\n });\n node.setAttribute(\"not-content\", \"true\");\n }, function(pos, axis) {\n if (axis == \"horizontal\") setScrollLeft(cm, pos);\n else setScrollTop(cm, pos);\n }, cm);\n if (cm.display.scrollbars.addClass)\n addClass(cm.display.wrapper, cm.display.scrollbars.addClass);\n }\n\n function updateScrollbars(cm, measure) {\n if (!measure) measure = measureForScrollbars(cm);\n var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;\n updateScrollbarsInner(cm, measure);\n for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {\n if (startWidth != cm.display.barWidth && cm.options.lineWrapping)\n updateHeightsInViewport(cm);\n updateScrollbarsInner(cm, measureForScrollbars(cm));\n startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;\n }\n }\n\n // Re-synchronize the fake scrollbars with the actual size of the\n // content.\n function updateScrollbarsInner(cm, measure) {\n var d = cm.display;\n var sizes = d.scrollbars.update(measure);\n\n d.sizer.style.paddingRight = (d.barWidth = sizes.right) + \"px\";\n d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + \"px\";\n\n if (sizes.right && sizes.bottom) {\n d.scrollbarFiller.style.display = \"block\";\n d.scrollbarFiller.style.height = sizes.bottom + \"px\";\n d.scrollbarFiller.style.width = sizes.right + \"px\";\n } else d.scrollbarFiller.style.display = \"\";\n if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {\n d.gutterFiller.style.display = \"block\";\n d.gutterFiller.style.height = sizes.bottom + \"px\";\n d.gutterFiller.style.width = measure.gutterWidth + \"px\";\n } else d.gutterFiller.style.display = \"\";\n }\n\n // Compute the lines that are visible in a given viewport (defaults\n // the the current scroll position). viewport may contain top,\n // height, and ensure (see op.scrollToPos) properties.\n function visibleLines(display, doc, viewport) {\n var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;\n top = Math.floor(top - paddingTop(display));\n var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;\n\n var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);\n // Ensure is a {from: {line, ch}, to: {line, ch}} object, and\n // forces those lines into the viewport (if possible).\n if (viewport && viewport.ensure) {\n var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;\n if (ensureFrom < from) {\n from = ensureFrom;\n to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);\n } else if (Math.min(ensureTo, doc.lastLine()) >= to) {\n from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);\n to = ensureTo;\n }\n }\n return {from: from, to: Math.max(to, from + 1)};\n }\n\n // LINE NUMBERS\n\n // Re-align line numbers and gutter marks to compensate for\n // horizontal scrolling.\n function alignHorizontally(cm) {\n var display = cm.display, view = display.view;\n if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;\n var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;\n var gutterW = display.gutters.offsetWidth, left = comp + \"px\";\n for (var i = 0; i < view.length; i++) if (!view[i].hidden) {\n if (cm.options.fixedGutter && view[i].gutter)\n view[i].gutter.style.left = left;\n var align = view[i].alignable;\n if (align) for (var j = 0; j < align.length; j++)\n align[j].style.left = left;\n }\n if (cm.options.fixedGutter)\n display.gutters.style.left = (comp + gutterW) + \"px\";\n }\n\n // Used to ensure that the line number gutter is still the right\n // size for the current document size. Returns true when an update\n // is needed.\n function maybeUpdateLineNumberWidth(cm) {\n if (!cm.options.lineNumbers) return false;\n var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;\n if (last.length != display.lineNumChars) {\n var test = display.measure.appendChild(elt(\"div\", [elt(\"div\", last)],\n \"CodeMirror-linenumber CodeMirror-gutter-elt\"));\n var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;\n display.lineGutter.style.width = \"\";\n display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding);\n display.lineNumWidth = display.lineNumInnerWidth + padding;\n display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;\n display.lineGutter.style.width = display.lineNumWidth + \"px\";\n updateGutterSpace(cm);\n return true;\n }\n return false;\n }\n\n function lineNumberFor(options, i) {\n return String(options.lineNumberFormatter(i + options.firstLineNumber));\n }\n\n // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,\n // but using getBoundingClientRect to get a sub-pixel-accurate\n // result.\n function compensateForHScroll(display) {\n return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;\n }\n\n // DISPLAY DRAWING\n\n function DisplayUpdate(cm, viewport, force) {\n var display = cm.display;\n\n this.viewport = viewport;\n // Store some values that we'll need later (but don't want to force a relayout for)\n this.visible = visibleLines(display, cm.doc, viewport);\n this.editorIsHidden = !display.wrapper.offsetWidth;\n this.wrapperHeight = display.wrapper.clientHeight;\n this.wrapperWidth = display.wrapper.clientWidth;\n this.oldDisplayWidth = displayWidth(cm);\n this.force = force;\n this.dims = getDimensions(cm);\n }\n\n function maybeClipScrollbars(cm) {\n var display = cm.display;\n if (!display.scrollbarsClipped && display.scroller.offsetWidth) {\n display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;\n display.heightForcer.style.height = scrollGap(cm) + \"px\";\n display.sizer.style.marginBottom = -display.nativeBarWidth + \"px\";\n display.sizer.style.borderRightWidth = scrollGap(cm) + \"px\";\n display.scrollbarsClipped = true;\n }\n }\n\n // Does the actual updating of the line display. Bails out\n // (returning false) when there is nothing to be done and forced is\n // false.\n function updateDisplayIfNeeded(cm, update) {\n var display = cm.display, doc = cm.doc;\n\n if (update.editorIsHidden) {\n resetView(cm);\n return false;\n }\n\n // Bail out if the visible area is already rendered and nothing changed.\n if (!update.force &&\n update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&\n (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&\n display.renderedView == display.view && countDirtyView(cm) == 0)\n return false;\n\n if (maybeUpdateLineNumberWidth(cm)) {\n resetView(cm);\n update.dims = getDimensions(cm);\n }\n\n // Compute a suitable new viewport (from & to)\n var end = doc.first + doc.size;\n var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);\n var to = Math.min(end, update.visible.to + cm.options.viewportMargin);\n if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);\n if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);\n if (sawCollapsedSpans) {\n from = visualLineNo(cm.doc, from);\n to = visualLineEndNo(cm.doc, to);\n }\n\n var different = from != display.viewFrom || to != display.viewTo ||\n display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;\n adjustView(cm, from, to);\n\n display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));\n // Position the mover div to align with the current scroll position\n cm.display.mover.style.top = display.viewOffset + \"px\";\n\n var toUpdate = countDirtyView(cm);\n if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&\n (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))\n return false;\n\n // For big changes, we hide the enclosing element during the\n // update, since that speeds up the operations on most browsers.\n var focused = activeElt();\n if (toUpdate > 4) display.lineDiv.style.display = \"none\";\n patchDisplay(cm, display.updateLineNumbers, update.dims);\n if (toUpdate > 4) display.lineDiv.style.display = \"\";\n display.renderedView = display.view;\n // There might have been a widget with a focused element that got\n // hidden or updated, if so re-focus it.\n if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();\n\n // Prevent selection and cursors from interfering with the scroll\n // width and height.\n removeChildren(display.cursorDiv);\n removeChildren(display.selectionDiv);\n display.gutters.style.height = 0;\n\n if (different) {\n display.lastWrapHeight = update.wrapperHeight;\n display.lastWrapWidth = update.wrapperWidth;\n startWorker(cm, 400);\n }\n\n display.updateLineNumbers = null;\n\n return true;\n }\n\n function postUpdateDisplay(cm, update) {\n var force = update.force, viewport = update.viewport;\n for (var first = true;; first = false) {\n if (first && cm.options.lineWrapping && update.oldDisplayWidth != displayWidth(cm)) {\n force = true;\n } else {\n force = false;\n // Clip forced viewport to actual scrollable area.\n if (viewport && viewport.top != null)\n viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};\n // Updated line heights might result in the drawn area not\n // actually covering the viewport. Keep looping until it does.\n update.visible = visibleLines(cm.display, cm.doc, viewport);\n if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)\n break;\n }\n if (!updateDisplayIfNeeded(cm, update)) break;\n updateHeightsInViewport(cm);\n var barMeasure = measureForScrollbars(cm);\n updateSelection(cm);\n setDocumentHeight(cm, barMeasure);\n updateScrollbars(cm, barMeasure);\n }\n\n signalLater(cm, \"update\", cm);\n if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {\n signalLater(cm, \"viewportChange\", cm, cm.display.viewFrom, cm.display.viewTo);\n cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;\n }\n }\n\n function updateDisplaySimple(cm, viewport) {\n var update = new DisplayUpdate(cm, viewport);\n if (updateDisplayIfNeeded(cm, update)) {\n updateHeightsInViewport(cm);\n postUpdateDisplay(cm, update);\n var barMeasure = measureForScrollbars(cm);\n updateSelection(cm);\n setDocumentHeight(cm, barMeasure);\n updateScrollbars(cm, barMeasure);\n }\n }\n\n function setDocumentHeight(cm, measure) {\n cm.display.sizer.style.minHeight = measure.docHeight + \"px\";\n var total = measure.docHeight + cm.display.barHeight;\n cm.display.heightForcer.style.top = total + \"px\";\n cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + \"px\";\n }\n\n // Read the actual heights of the rendered lines, and update their\n // stored heights to match.\n function updateHeightsInViewport(cm) {\n var display = cm.display;\n var prevBottom = display.lineDiv.offsetTop;\n for (var i = 0; i < display.view.length; i++) {\n var cur = display.view[i], height;\n if (cur.hidden) continue;\n if (ie && ie_version < 8) {\n var bot = cur.node.offsetTop + cur.node.offsetHeight;\n height = bot - prevBottom;\n prevBottom = bot;\n } else {\n var box = cur.node.getBoundingClientRect();\n height = box.bottom - box.top;\n }\n var diff = cur.line.height - height;\n if (height < 2) height = textHeight(display);\n if (diff > .001 || diff < -.001) {\n updateLineHeight(cur.line, height);\n updateWidgetHeight(cur.line);\n if (cur.rest) for (var j = 0; j < cur.rest.length; j++)\n updateWidgetHeight(cur.rest[j]);\n }\n }\n }\n\n // Read and store the height of line widgets associated with the\n // given line.\n function updateWidgetHeight(line) {\n if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)\n line.widgets[i].height = line.widgets[i].node.offsetHeight;\n }\n\n // Do a bulk-read of the DOM positions and sizes needed to draw the\n // view, so that we don't interleave reading and writing to the DOM.\n function getDimensions(cm) {\n var d = cm.display, left = {}, width = {};\n var gutterLeft = d.gutters.clientLeft;\n for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {\n left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;\n width[cm.options.gutters[i]] = n.clientWidth;\n }\n return {fixedPos: compensateForHScroll(d),\n gutterTotalWidth: d.gutters.offsetWidth,\n gutterLeft: left,\n gutterWidth: width,\n wrapperWidth: d.wrapper.clientWidth};\n }\n\n // Sync the actual display DOM structure with display.view, removing\n // nodes for lines that are no longer in view, and creating the ones\n // that are not there yet, and updating the ones that are out of\n // date.\n function patchDisplay(cm, updateNumbersFrom, dims) {\n var display = cm.display, lineNumbers = cm.options.lineNumbers;\n var container = display.lineDiv, cur = container.firstChild;\n\n function rm(node) {\n var next = node.nextSibling;\n // Works around a throw-scroll bug in OS X Webkit\n if (webkit && mac && cm.display.currentWheelTarget == node)\n node.style.display = \"none\";\n else\n node.parentNode.removeChild(node);\n return next;\n }\n\n var view = display.view, lineN = display.viewFrom;\n // Loop over the elements in the view, syncing cur (the DOM nodes\n // in display.lineDiv) with the view as we go.\n for (var i = 0; i < view.length; i++) {\n var lineView = view[i];\n if (lineView.hidden) {\n } else if (!lineView.node) { // Not drawn yet\n var node = buildLineElement(cm, lineView, lineN, dims);\n container.insertBefore(node, cur);\n } else { // Already drawn\n while (cur != lineView.node) cur = rm(cur);\n var updateNumber = lineNumbers && updateNumbersFrom != null &&\n updateNumbersFrom <= lineN && lineView.lineNumber;\n if (lineView.changes) {\n if (indexOf(lineView.changes, \"gutter\") > -1) updateNumber = false;\n updateLineForChanges(cm, lineView, lineN, dims);\n }\n if (updateNumber) {\n removeChildren(lineView.lineNumber);\n lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));\n }\n cur = lineView.node.nextSibling;\n }\n lineN += lineView.size;\n }\n while (cur) cur = rm(cur);\n }\n\n // When an aspect of a line changes, a string is added to\n // lineView.changes. This updates the relevant part of the line's\n // DOM structure.\n function updateLineForChanges(cm, lineView, lineN, dims) {\n for (var j = 0; j < lineView.changes.length; j++) {\n var type = lineView.changes[j];\n if (type == \"text\") updateLineText(cm, lineView);\n else if (type == \"gutter\") updateLineGutter(cm, lineView, lineN, dims);\n else if (type == \"class\") updateLineClasses(lineView);\n else if (type == \"widget\") updateLineWidgets(lineView, dims);\n }\n lineView.changes = null;\n }\n\n // Lines with gutter elements, widgets or a background class need to\n // be wrapped, and have the extra elements added to the wrapper div\n function ensureLineWrapped(lineView) {\n if (lineView.node == lineView.text) {\n lineView.node = elt(\"div\", null, null, \"position: relative\");\n if (lineView.text.parentNode)\n lineView.text.parentNode.replaceChild(lineView.node, lineView.text);\n lineView.node.appendChild(lineView.text);\n if (ie && ie_version < 8) lineView.node.style.zIndex = 2;\n }\n return lineView.node;\n }\n\n function updateLineBackground(lineView) {\n var cls = lineView.bgClass ? lineView.bgClass + \" \" + (lineView.line.bgClass || \"\") : lineView.line.bgClass;\n if (cls) cls += \" CodeMirror-linebackground\";\n if (lineView.background) {\n if (cls) lineView.background.className = cls;\n else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }\n } else if (cls) {\n var wrap = ensureLineWrapped(lineView);\n lineView.background = wrap.insertBefore(elt(\"div\", null, cls), wrap.firstChild);\n }\n }\n\n // Wrapper around buildLineContent which will reuse the structure\n // in display.externalMeasured when possible.\n function getLineContent(cm, lineView) {\n var ext = cm.display.externalMeasured;\n if (ext && ext.line == lineView.line) {\n cm.display.externalMeasured = null;\n lineView.measure = ext.measure;\n return ext.built;\n }\n return buildLineContent(cm, lineView);\n }\n\n // Redraw the line's text. Interacts with the background and text\n // classes because the mode may output tokens that influence these\n // classes.\n function updateLineText(cm, lineView) {\n var cls = lineView.text.className;\n var built = getLineContent(cm, lineView);\n if (lineView.text == lineView.node) lineView.node = built.pre;\n lineView.text.parentNode.replaceChild(built.pre, lineView.text);\n lineView.text = built.pre;\n if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {\n lineView.bgClass = built.bgClass;\n lineView.textClass = built.textClass;\n updateLineClasses(lineView);\n } else if (cls) {\n lineView.text.className = cls;\n }\n }\n\n function updateLineClasses(lineView) {\n updateLineBackground(lineView);\n if (lineView.line.wrapClass)\n ensureLineWrapped(lineView).className = lineView.line.wrapClass;\n else if (lineView.node != lineView.text)\n lineView.node.className = \"\";\n var textClass = lineView.textClass ? lineView.textClass + \" \" + (lineView.line.textClass || \"\") : lineView.line.textClass;\n lineView.text.className = textClass || \"\";\n }\n\n function updateLineGutter(cm, lineView, lineN, dims) {\n if (lineView.gutter) {\n lineView.node.removeChild(lineView.gutter);\n lineView.gutter = null;\n }\n var markers = lineView.line.gutterMarkers;\n if (cm.options.lineNumbers || markers) {\n var wrap = ensureLineWrapped(lineView);\n var gutterWrap = lineView.gutter =\n wrap.insertBefore(elt(\"div\", null, \"CodeMirror-gutter-wrapper\", \"left: \" +\n (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +\n \"px; width: \" + dims.gutterTotalWidth + \"px\"),\n lineView.text);\n if (lineView.line.gutterClass)\n gutterWrap.className += \" \" + lineView.line.gutterClass;\n if (cm.options.lineNumbers && (!markers || !markers[\"CodeMirror-linenumbers\"]))\n lineView.lineNumber = gutterWrap.appendChild(\n elt(\"div\", lineNumberFor(cm.options, lineN),\n \"CodeMirror-linenumber CodeMirror-gutter-elt\",\n \"left: \" + dims.gutterLeft[\"CodeMirror-linenumbers\"] + \"px; width: \"\n + cm.display.lineNumInnerWidth + \"px\"));\n if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {\n var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];\n if (found)\n gutterWrap.appendChild(elt(\"div\", [found], \"CodeMirror-gutter-elt\", \"left: \" +\n dims.gutterLeft[id] + \"px; width: \" + dims.gutterWidth[id] + \"px\"));\n }\n }\n }\n\n function updateLineWidgets(lineView, dims) {\n if (lineView.alignable) lineView.alignable = null;\n for (var node = lineView.node.firstChild, next; node; node = next) {\n var next = node.nextSibling;\n if (node.className == \"CodeMirror-linewidget\")\n lineView.node.removeChild(node);\n }\n insertLineWidgets(lineView, dims);\n }\n\n // Build a line's DOM representation from scratch\n function buildLineElement(cm, lineView, lineN, dims) {\n var built = getLineContent(cm, lineView);\n lineView.text = lineView.node = built.pre;\n if (built.bgClass) lineView.bgClass = built.bgClass;\n if (built.textClass) lineView.textClass = built.textClass;\n\n updateLineClasses(lineView);\n updateLineGutter(cm, lineView, lineN, dims);\n insertLineWidgets(lineView, dims);\n return lineView.node;\n }\n\n // A lineView may contain multiple logical lines (when merged by\n // collapsed spans). The widgets for all of them need to be drawn.\n function insertLineWidgets(lineView, dims) {\n insertLineWidgetsFor(lineView.line, lineView, dims, true);\n if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)\n insertLineWidgetsFor(lineView.rest[i], lineView, dims, false);\n }\n\n function insertLineWidgetsFor(line, lineView, dims, allowAbove) {\n if (!line.widgets) return;\n var wrap = ensureLineWrapped(lineView);\n for (var i = 0, ws = line.widgets; i < ws.length; ++i) {\n var widget = ws[i], node = elt(\"div\", [widget.node], \"CodeMirror-linewidget\");\n if (!widget.handleMouseEvents) node.setAttribute(\"cm-ignore-events\", \"true\");\n positionLineWidget(widget, node, lineView, dims);\n if (allowAbove && widget.above)\n wrap.insertBefore(node, lineView.gutter || lineView.text);\n else\n wrap.appendChild(node);\n signalLater(widget, \"redraw\");\n }\n }\n\n function positionLineWidget(widget, node, lineView, dims) {\n if (widget.noHScroll) {\n (lineView.alignable || (lineView.alignable = [])).push(node);\n var width = dims.wrapperWidth;\n node.style.left = dims.fixedPos + \"px\";\n if (!widget.coverGutter) {\n width -= dims.gutterTotalWidth;\n node.style.paddingLeft = dims.gutterTotalWidth + \"px\";\n }\n node.style.width = width + \"px\";\n }\n if (widget.coverGutter) {\n node.style.zIndex = 5;\n node.style.position = \"relative\";\n if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + \"px\";\n }\n }\n\n // POSITION OBJECT\n\n // A Pos instance represents a position within the text.\n var Pos = CodeMirror.Pos = function(line, ch) {\n if (!(this instanceof Pos)) return new Pos(line, ch);\n this.line = line; this.ch = ch;\n };\n\n // Compare two positions, return 0 if they are the same, a negative\n // number when a is less, and a positive number otherwise.\n var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };\n\n function copyPos(x) {return Pos(x.line, x.ch);}\n function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }\n function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }\n\n // SELECTION / CURSOR\n\n // Selection objects are immutable. A new one is created every time\n // the selection changes. A selection is one or more non-overlapping\n // (and non-touching) ranges, sorted, and an integer that indicates\n // which one is the primary selection (the one that's scrolled into\n // view, that getCursor returns, etc).\n function Selection(ranges, primIndex) {\n this.ranges = ranges;\n this.primIndex = primIndex;\n }\n\n Selection.prototype = {\n primary: function() { return this.ranges[this.primIndex]; },\n equals: function(other) {\n if (other == this) return true;\n if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;\n for (var i = 0; i < this.ranges.length; i++) {\n var here = this.ranges[i], there = other.ranges[i];\n if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;\n }\n return true;\n },\n deepCopy: function() {\n for (var out = [], i = 0; i < this.ranges.length; i++)\n out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));\n return new Selection(out, this.primIndex);\n },\n somethingSelected: function() {\n for (var i = 0; i < this.ranges.length; i++)\n if (!this.ranges[i].empty()) return true;\n return false;\n },\n contains: function(pos, end) {\n if (!end) end = pos;\n for (var i = 0; i < this.ranges.length; i++) {\n var range = this.ranges[i];\n if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)\n return i;\n }\n return -1;\n }\n };\n\n function Range(anchor, head) {\n this.anchor = anchor; this.head = head;\n }\n\n Range.prototype = {\n from: function() { return minPos(this.anchor, this.head); },\n to: function() { return maxPos(this.anchor, this.head); },\n empty: function() {\n return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;\n }\n };\n\n // Take an unsorted, potentially overlapping set of ranges, and\n // build a selection out of it. 'Consumes' ranges array (modifying\n // it).\n function normalizeSelection(ranges, primIndex) {\n var prim = ranges[primIndex];\n ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });\n primIndex = indexOf(ranges, prim);\n for (var i = 1; i < ranges.length; i++) {\n var cur = ranges[i], prev = ranges[i - 1];\n if (cmp(prev.to(), cur.from()) >= 0) {\n var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());\n var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;\n if (i <= primIndex) --primIndex;\n ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));\n }\n }\n return new Selection(ranges, primIndex);\n }\n\n function simpleSelection(anchor, head) {\n return new Selection([new Range(anchor, head || anchor)], 0);\n }\n\n // Most of the external API clips given positions to make sure they\n // actually exist within the document.\n function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}\n function clipPos(doc, pos) {\n if (pos.line < doc.first) return Pos(doc.first, 0);\n var last = doc.first + doc.size - 1;\n if (pos.line > last) return Pos(last, getLine(doc, last).text.length);\n return clipToLen(pos, getLine(doc, pos.line).text.length);\n }\n function clipToLen(pos, linelen) {\n var ch = pos.ch;\n if (ch == null || ch > linelen) return Pos(pos.line, linelen);\n else if (ch < 0) return Pos(pos.line, 0);\n else return pos;\n }\n function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}\n function clipPosArray(doc, array) {\n for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);\n return out;\n }\n\n // SELECTION UPDATES\n\n // The 'scroll' parameter given to many of these indicated whether\n // the new cursor position should be scrolled into view after\n // modifying the selection.\n\n // If shift is held or the extend flag is set, extends a range to\n // include a given position (and optionally a second position).\n // Otherwise, simply returns the range between the given positions.\n // Used for cursor motion and such.\n function extendRange(doc, range, head, other) {\n if (doc.cm && doc.cm.display.shift || doc.extend) {\n var anchor = range.anchor;\n if (other) {\n var posBefore = cmp(head, anchor) < 0;\n if (posBefore != (cmp(other, anchor) < 0)) {\n anchor = head;\n head = other;\n } else if (posBefore != (cmp(head, other) < 0)) {\n head = other;\n }\n }\n return new Range(anchor, head);\n } else {\n return new Range(other || head, head);\n }\n }\n\n // Extend the primary selection range, discard the rest.\n function extendSelection(doc, head, other, options) {\n setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);\n }\n\n // Extend all selections (pos is an array of selections with length\n // equal the number of selections)\n function extendSelections(doc, heads, options) {\n for (var out = [], i = 0; i < doc.sel.ranges.length; i++)\n out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);\n var newSel = normalizeSelection(out, doc.sel.primIndex);\n setSelection(doc, newSel, options);\n }\n\n // Updates a single range in the selection.\n function replaceOneSelection(doc, i, range, options) {\n var ranges = doc.sel.ranges.slice(0);\n ranges[i] = range;\n setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);\n }\n\n // Reset the selection to a single range.\n function setSimpleSelection(doc, anchor, head, options) {\n setSelection(doc, simpleSelection(anchor, head), options);\n }\n\n // Give beforeSelectionChange handlers a change to influence a\n // selection update.\n function filterSelectionChange(doc, sel) {\n var obj = {\n ranges: sel.ranges,\n update: function(ranges) {\n this.ranges = [];\n for (var i = 0; i < ranges.length; i++)\n this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),\n clipPos(doc, ranges[i].head));\n }\n };\n signal(doc, \"beforeSelectionChange\", doc, obj);\n if (doc.cm) signal(doc.cm, \"beforeSelectionChange\", doc.cm, obj);\n if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);\n else return sel;\n }\n\n function setSelectionReplaceHistory(doc, sel, options) {\n var done = doc.history.done, last = lst(done);\n if (last && last.ranges) {\n done[done.length - 1] = sel;\n setSelectionNoUndo(doc, sel, options);\n } else {\n setSelection(doc, sel, options);\n }\n }\n\n // Set a new selection.\n function setSelection(doc, sel, options) {\n setSelectionNoUndo(doc, sel, options);\n addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);\n }\n\n function setSelectionNoUndo(doc, sel, options) {\n if (hasHandler(doc, \"beforeSelectionChange\") || doc.cm && hasHandler(doc.cm, \"beforeSelectionChange\"))\n sel = filterSelectionChange(doc, sel);\n\n var bias = options && options.bias ||\n (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);\n setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));\n\n if (!(options && options.scroll === false) && doc.cm)\n ensureCursorVisible(doc.cm);\n }\n\n function setSelectionInner(doc, sel) {\n if (sel.equals(doc.sel)) return;\n\n doc.sel = sel;\n\n if (doc.cm) {\n doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;\n signalCursorActivity(doc.cm);\n }\n signalLater(doc, \"cursorActivity\", doc);\n }\n\n // Verify that the selection does not partially select any atomic\n // marked ranges.\n function reCheckSelection(doc) {\n setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);\n }\n\n // Return a selection that does not partially select any atomic\n // ranges.\n function skipAtomicInSelection(doc, sel, bias, mayClear) {\n var out;\n for (var i = 0; i < sel.ranges.length; i++) {\n var range = sel.ranges[i];\n var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);\n var newHead = skipAtomic(doc, range.head, bias, mayClear);\n if (out || newAnchor != range.anchor || newHead != range.head) {\n if (!out) out = sel.ranges.slice(0, i);\n out[i] = new Range(newAnchor, newHead);\n }\n }\n return out ? normalizeSelection(out, sel.primIndex) : sel;\n }\n\n // Ensure a given position is not inside an atomic range.\n function skipAtomic(doc, pos, bias, mayClear) {\n var flipped = false, curPos = pos;\n var dir = bias || 1;\n doc.cantEdit = false;\n search: for (;;) {\n var line = getLine(doc, curPos.line);\n if (line.markedSpans) {\n for (var i = 0; i < line.markedSpans.length; ++i) {\n var sp = line.markedSpans[i], m = sp.marker;\n if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&\n (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {\n if (mayClear) {\n signal(m, \"beforeCursorEnter\");\n if (m.explicitlyCleared) {\n if (!line.markedSpans) break;\n else {--i; continue;}\n }\n }\n if (!m.atomic) continue;\n var newPos = m.find(dir < 0 ? -1 : 1);\n if (cmp(newPos, curPos) == 0) {\n newPos.ch += dir;\n if (newPos.ch < 0) {\n if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));\n else newPos = null;\n } else if (newPos.ch > line.text.length) {\n if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);\n else newPos = null;\n }\n if (!newPos) {\n if (flipped) {\n // Driven in a corner -- no valid cursor position found at all\n // -- try again *with* clearing, if we didn't already\n if (!mayClear) return skipAtomic(doc, pos, bias, true);\n // Otherwise, turn off editing until further notice, and return the start of the doc\n doc.cantEdit = true;\n return Pos(doc.first, 0);\n }\n flipped = true; newPos = pos; dir = -dir;\n }\n }\n curPos = newPos;\n continue search;\n }\n }\n }\n return curPos;\n }\n }\n\n // SELECTION DRAWING\n\n // Redraw the selection and/or cursor\n function drawSelection(cm) {\n var display = cm.display, doc = cm.doc, result = {};\n var curFragment = result.cursors = document.createDocumentFragment();\n var selFragment = result.selection = document.createDocumentFragment();\n\n for (var i = 0; i < doc.sel.ranges.length; i++) {\n var range = doc.sel.ranges[i];\n var collapsed = range.empty();\n if (collapsed || cm.options.showCursorWhenSelecting)\n drawSelectionCursor(cm, range, curFragment);\n if (!collapsed)\n drawSelectionRange(cm, range, selFragment);\n }\n\n // Move the hidden textarea near the cursor to prevent scrolling artifacts\n if (cm.options.moveInputWithCursor) {\n var headPos = cursorCoords(cm, doc.sel.primary().head, \"div\");\n var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();\n result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,\n headPos.top + lineOff.top - wrapOff.top));\n result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,\n headPos.left + lineOff.left - wrapOff.left));\n }\n\n return result;\n }\n\n function showSelection(cm, drawn) {\n removeChildrenAndAdd(cm.display.cursorDiv, drawn.cursors);\n removeChildrenAndAdd(cm.display.selectionDiv, drawn.selection);\n if (drawn.teTop != null) {\n cm.display.inputDiv.style.top = drawn.teTop + \"px\";\n cm.display.inputDiv.style.left = drawn.teLeft + \"px\";\n }\n }\n\n function updateSelection(cm) {\n showSelection(cm, drawSelection(cm));\n }\n\n // Draws a cursor for the given range\n function drawSelectionCursor(cm, range, output) {\n var pos = cursorCoords(cm, range.head, \"div\", null, null, !cm.options.singleCursorHeightPerLine);\n\n var cursor = output.appendChild(elt(\"div\", \"\\u00a0\", \"CodeMirror-cursor\"));\n cursor.style.left = pos.left + \"px\";\n cursor.style.top = pos.top + \"px\";\n cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + \"px\";\n\n if (pos.other) {\n // Secondary cursor, shown when on a 'jump' in bi-directional text\n var otherCursor = output.appendChild(elt(\"div\", \"\\u00a0\", \"CodeMirror-cursor CodeMirror-secondarycursor\"));\n otherCursor.style.display = \"\";\n otherCursor.style.left = pos.other.left + \"px\";\n otherCursor.style.top = pos.other.top + \"px\";\n otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + \"px\";\n }\n }\n\n // Draws the given range as a highlighted selection\n function drawSelectionRange(cm, range, output) {\n var display = cm.display, doc = cm.doc;\n var fragment = document.createDocumentFragment();\n var padding = paddingH(cm.display), leftSide = padding.left;\n var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;\n\n function add(left, top, width, bottom) {\n if (top < 0) top = 0;\n top = Math.round(top);\n bottom = Math.round(bottom);\n fragment.appendChild(elt(\"div\", null, \"CodeMirror-selected\", \"position: absolute; left: \" + left +\n \"px; top: \" + top + \"px; width: \" + (width == null ? rightSide - left : width) +\n \"px; height: \" + (bottom - top) + \"px\"));\n }\n\n function drawForLine(line, fromArg, toArg) {\n var lineObj = getLine(doc, line);\n var lineLen = lineObj.text.length;\n var start, end;\n function coords(ch, bias) {\n return charCoords(cm, Pos(line, ch), \"div\", lineObj, bias);\n }\n\n iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {\n var leftPos = coords(from, \"left\"), rightPos, left, right;\n if (from == to) {\n rightPos = leftPos;\n left = right = leftPos.left;\n } else {\n rightPos = coords(to - 1, \"right\");\n if (dir == \"rtl\") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }\n left = leftPos.left;\n right = rightPos.right;\n }\n if (fromArg == null && from == 0) left = leftSide;\n if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part\n add(left, leftPos.top, null, leftPos.bottom);\n left = leftSide;\n if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);\n }\n if (toArg == null && to == lineLen) right = rightSide;\n if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)\n start = leftPos;\n if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)\n end = rightPos;\n if (left < leftSide + 1) left = leftSide;\n add(left, rightPos.top, right - left, rightPos.bottom);\n });\n return {start: start, end: end};\n }\n\n var sFrom = range.from(), sTo = range.to();\n if (sFrom.line == sTo.line) {\n drawForLine(sFrom.line, sFrom.ch, sTo.ch);\n } else {\n var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);\n var singleVLine = visualLine(fromLine) == visualLine(toLine);\n var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;\n var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;\n if (singleVLine) {\n if (leftEnd.top < rightStart.top - 2) {\n add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);\n add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);\n } else {\n add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);\n }\n }\n if (leftEnd.bottom < rightStart.top)\n add(leftSide, leftEnd.bottom, null, rightStart.top);\n }\n\n output.appendChild(fragment);\n }\n\n // Cursor-blinking\n function restartBlink(cm) {\n if (!cm.state.focused) return;\n var display = cm.display;\n clearInterval(display.blinker);\n var on = true;\n display.cursorDiv.style.visibility = \"\";\n if (cm.options.cursorBlinkRate > 0)\n display.blinker = setInterval(function() {\n display.cursorDiv.style.visibility = (on = !on) ? \"\" : \"hidden\";\n }, cm.options.cursorBlinkRate);\n else if (cm.options.cursorBlinkRate < 0)\n display.cursorDiv.style.visibility = \"hidden\";\n }\n\n // HIGHLIGHT WORKER\n\n function startWorker(cm, time) {\n if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)\n cm.state.highlight.set(time, bind(highlightWorker, cm));\n }\n\n function highlightWorker(cm) {\n var doc = cm.doc;\n if (doc.frontier < doc.first) doc.frontier = doc.first;\n if (doc.frontier >= cm.display.viewTo) return;\n var end = +new Date + cm.options.workTime;\n var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));\n var changedLines = [];\n\n doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {\n if (doc.frontier >= cm.display.viewFrom) { // Visible\n var oldStyles = line.styles;\n var highlighted = highlightLine(cm, line, state, true);\n line.styles = highlighted.styles;\n var oldCls = line.styleClasses, newCls = highlighted.classes;\n if (newCls) line.styleClasses = newCls;\n else if (oldCls) line.styleClasses = null;\n var ischange = !oldStyles || oldStyles.length != line.styles.length ||\n oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);\n for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];\n if (ischange) changedLines.push(doc.frontier);\n line.stateAfter = copyState(doc.mode, state);\n } else {\n processLine(cm, line.text, state);\n line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;\n }\n ++doc.frontier;\n if (+new Date > end) {\n startWorker(cm, cm.options.workDelay);\n return true;\n }\n });\n if (changedLines.length) runInOp(cm, function() {\n for (var i = 0; i < changedLines.length; i++)\n regLineChange(cm, changedLines[i], \"text\");\n });\n }\n\n // Finds the line to start with when starting a parse. Tries to\n // find a line with a stateAfter, so that it can start with a\n // valid state. If that fails, it returns the line with the\n // smallest indentation, which tends to need the least context to\n // parse correctly.\n function findStartLine(cm, n, precise) {\n var minindent, minline, doc = cm.doc;\n var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);\n for (var search = n; search > lim; --search) {\n if (search <= doc.first) return doc.first;\n var line = getLine(doc, search - 1);\n if (line.stateAfter && (!precise || search <= doc.frontier)) return search;\n var indented = countColumn(line.text, null, cm.options.tabSize);\n if (minline == null || minindent > indented) {\n minline = search - 1;\n minindent = indented;\n }\n }\n return minline;\n }\n\n function getStateBefore(cm, n, precise) {\n var doc = cm.doc, display = cm.display;\n if (!doc.mode.startState) return true;\n var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;\n if (!state) state = startState(doc.mode);\n else state = copyState(doc.mode, state);\n doc.iter(pos, n, function(line) {\n processLine(cm, line.text, state);\n var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo;\n line.stateAfter = save ? copyState(doc.mode, state) : null;\n ++pos;\n });\n if (precise) doc.frontier = pos;\n return state;\n }\n\n // POSITION MEASUREMENT\n\n function paddingTop(display) {return display.lineSpace.offsetTop;}\n function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}\n function paddingH(display) {\n if (display.cachedPaddingH) return display.cachedPaddingH;\n var e = removeChildrenAndAdd(display.measure, elt(\"pre\", \"x\"));\n var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;\n var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};\n if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data;\n return data;\n }\n\n function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; }\n function displayWidth(cm) {\n return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth;\n }\n function displayHeight(cm) {\n return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight;\n }\n\n // Ensure the lineView.wrapping.heights array is populated. This is\n // an array of bottom offsets for the lines that make up a drawn\n // line. When lineWrapping is on, there might be more than one\n // height.\n function ensureLineHeights(cm, lineView, rect) {\n var wrapping = cm.options.lineWrapping;\n var curWidth = wrapping && displayWidth(cm);\n if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {\n var heights = lineView.measure.heights = [];\n if (wrapping) {\n lineView.measure.width = curWidth;\n var rects = lineView.text.firstChild.getClientRects();\n for (var i = 0; i < rects.length - 1; i++) {\n var cur = rects[i], next = rects[i + 1];\n if (Math.abs(cur.bottom - next.bottom) > 2)\n heights.push((cur.bottom + next.top) / 2 - rect.top);\n }\n }\n heights.push(rect.bottom - rect.top);\n }\n }\n\n // Find a line map (mapping character offsets to text nodes) and a\n // measurement cache for the given line number. (A line view might\n // contain multiple lines when collapsed ranges are present.)\n function mapFromLineView(lineView, line, lineN) {\n if (lineView.line == line)\n return {map: lineView.measure.map, cache: lineView.measure.cache};\n for (var i = 0; i < lineView.rest.length; i++)\n if (lineView.rest[i] == line)\n return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]};\n for (var i = 0; i < lineView.rest.length; i++)\n if (lineNo(lineView.rest[i]) > lineN)\n return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true};\n }\n\n // Render a line into the hidden node display.externalMeasured. Used\n // when measurement is needed for a line that's not in the viewport.\n function updateExternalMeasurement(cm, line) {\n line = visualLine(line);\n var lineN = lineNo(line);\n var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);\n view.lineN = lineN;\n var built = view.built = buildLineContent(cm, view);\n view.text = built.pre;\n removeChildrenAndAdd(cm.display.lineMeasure, built.pre);\n return view;\n }\n\n // Get a {top, bottom, left, right} box (in line-local coordinates)\n // for a given character.\n function measureChar(cm, line, ch, bias) {\n return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias);\n }\n\n // Find a line view that corresponds to the given line number.\n function findViewForLine(cm, lineN) {\n if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)\n return cm.display.view[findViewIndex(cm, lineN)];\n var ext = cm.display.externalMeasured;\n if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)\n return ext;\n }\n\n // Measurement can be split in two steps, the set-up work that\n // applies to the whole line, and the measurement of the actual\n // character. Functions like coordsChar, that need to do a lot of\n // measurements in a row, can thus ensure that the set-up work is\n // only done once.\n function prepareMeasureForLine(cm, line) {\n var lineN = lineNo(line);\n var view = findViewForLine(cm, lineN);\n if (view && !view.text)\n view = null;\n else if (view && view.changes)\n updateLineForChanges(cm, view, lineN, getDimensions(cm));\n if (!view)\n view = updateExternalMeasurement(cm, line);\n\n var info = mapFromLineView(view, line, lineN);\n return {\n line: line, view: view, rect: null,\n map: info.map, cache: info.cache, before: info.before,\n hasHeights: false\n };\n }\n\n // Given a prepared measurement object, measures the position of an\n // actual character (or fetches it from the cache).\n function measureCharPrepared(cm, prepared, ch, bias, varHeight) {\n if (prepared.before) ch = -1;\n var key = ch + (bias || \"\"), found;\n if (prepared.cache.hasOwnProperty(key)) {\n found = prepared.cache[key];\n } else {\n if (!prepared.rect)\n prepared.rect = prepared.view.text.getBoundingClientRect();\n if (!prepared.hasHeights) {\n ensureLineHeights(cm, prepared.view, prepared.rect);\n prepared.hasHeights = true;\n }\n found = measureCharInner(cm, prepared, ch, bias);\n if (!found.bogus) prepared.cache[key] = found;\n }\n return {left: found.left, right: found.right,\n top: varHeight ? found.rtop : found.top,\n bottom: varHeight ? found.rbottom : found.bottom};\n }\n\n var nullRect = {left: 0, right: 0, top: 0, bottom: 0};\n\n function measureCharInner(cm, prepared, ch, bias) {\n var map = prepared.map;\n\n var node, start, end, collapse;\n // First, search the line map for the text node corresponding to,\n // or closest to, the target character.\n for (var i = 0; i < map.length; i += 3) {\n var mStart = map[i], mEnd = map[i + 1];\n if (ch < mStart) {\n start = 0; end = 1;\n collapse = \"left\";\n } else if (ch < mEnd) {\n start = ch - mStart;\n end = start + 1;\n } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {\n end = mEnd - mStart;\n start = end - 1;\n if (ch >= mEnd) collapse = \"right\";\n }\n if (start != null) {\n node = map[i + 2];\n if (mStart == mEnd && bias == (node.insertLeft ? \"left\" : \"right\"))\n collapse = bias;\n if (bias == \"left\" && start == 0)\n while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {\n node = map[(i -= 3) + 2];\n collapse = \"left\";\n }\n if (bias == \"right\" && start == mEnd - mStart)\n while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {\n node = map[(i += 3) + 2];\n collapse = \"right\";\n }\n break;\n }\n }\n\n var rect;\n if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.\n for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned\n while (start && isExtendingChar(prepared.line.text.charAt(mStart + start))) --start;\n while (mStart + end < mEnd && isExtendingChar(prepared.line.text.charAt(mStart + end))) ++end;\n if (ie && ie_version < 9 && start == 0 && end == mEnd - mStart) {\n rect = node.parentNode.getBoundingClientRect();\n } else if (ie && cm.options.lineWrapping) {\n var rects = range(node, start, end).getClientRects();\n if (rects.length)\n rect = rects[bias == \"right\" ? rects.length - 1 : 0];\n else\n rect = nullRect;\n } else {\n rect = range(node, start, end).getBoundingClientRect() || nullRect;\n }\n if (rect.left || rect.right || start == 0) break;\n end = start;\n start = start - 1;\n collapse = \"right\";\n }\n if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect);\n } else { // If it is a widget, simply get the box for the whole widget.\n if (start > 0) collapse = bias = \"right\";\n var rects;\n if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)\n rect = rects[bias == \"right\" ? rects.length - 1 : 0];\n else\n rect = node.getBoundingClientRect();\n }\n if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {\n var rSpan = node.parentNode.getClientRects()[0];\n if (rSpan)\n rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom};\n else\n rect = nullRect;\n }\n\n var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;\n var mid = (rtop + rbot) / 2;\n var heights = prepared.view.measure.heights;\n for (var i = 0; i < heights.length - 1; i++)\n if (mid < heights[i]) break;\n var top = i ? heights[i - 1] : 0, bot = heights[i];\n var result = {left: (collapse == \"right\" ? rect.right : rect.left) - prepared.rect.left,\n right: (collapse == \"left\" ? rect.left : rect.right) - prepared.rect.left,\n top: top, bottom: bot};\n if (!rect.left && !rect.right) result.bogus = true;\n if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }\n\n return result;\n }\n\n // Work around problem with bounding client rects on ranges being\n // returned incorrectly when zoomed on IE10 and below.\n function maybeUpdateRectForZooming(measure, rect) {\n if (!window.screen || screen.logicalXDPI == null ||\n screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))\n return rect;\n var scaleX = screen.logicalXDPI / screen.deviceXDPI;\n var scaleY = screen.logicalYDPI / screen.deviceYDPI;\n return {left: rect.left * scaleX, right: rect.right * scaleX,\n top: rect.top * scaleY, bottom: rect.bottom * scaleY};\n }\n\n function clearLineMeasurementCacheFor(lineView) {\n if (lineView.measure) {\n lineView.measure.cache = {};\n lineView.measure.heights = null;\n if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)\n lineView.measure.caches[i] = {};\n }\n }\n\n function clearLineMeasurementCache(cm) {\n cm.display.externalMeasure = null;\n removeChildren(cm.display.lineMeasure);\n for (var i = 0; i < cm.display.view.length; i++)\n clearLineMeasurementCacheFor(cm.display.view[i]);\n }\n\n function clearCaches(cm) {\n clearLineMeasurementCache(cm);\n cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;\n if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;\n cm.display.lineNumChars = null;\n }\n\n function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }\n function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }\n\n // Converts a {top, bottom, left, right} box from line-local\n // coordinates into another coordinate system. Context may be one of\n // \"line\", \"div\" (display.lineDiv), \"local\"/null (editor), \"window\",\n // or \"page\".\n function intoCoordSystem(cm, lineObj, rect, context) {\n if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {\n var size = widgetHeight(lineObj.widgets[i]);\n rect.top += size; rect.bottom += size;\n }\n if (context == \"line\") return rect;\n if (!context) context = \"local\";\n var yOff = heightAtLine(lineObj);\n if (context == \"local\") yOff += paddingTop(cm.display);\n else yOff -= cm.display.viewOffset;\n if (context == \"page\" || context == \"window\") {\n var lOff = cm.display.lineSpace.getBoundingClientRect();\n yOff += lOff.top + (context == \"window\" ? 0 : pageScrollY());\n var xOff = lOff.left + (context == \"window\" ? 0 : pageScrollX());\n rect.left += xOff; rect.right += xOff;\n }\n rect.top += yOff; rect.bottom += yOff;\n return rect;\n }\n\n // Coverts a box from \"div\" coords to another coordinate system.\n // Context may be \"window\", \"page\", \"div\", or \"local\"/null.\n function fromCoordSystem(cm, coords, context) {\n if (context == \"div\") return coords;\n var left = coords.left, top = coords.top;\n // First move into \"page\" coordinate system\n if (context == \"page\") {\n left -= pageScrollX();\n top -= pageScrollY();\n } else if (context == \"local\" || !context) {\n var localBox = cm.display.sizer.getBoundingClientRect();\n left += localBox.left;\n top += localBox.top;\n }\n\n var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();\n return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};\n }\n\n function charCoords(cm, pos, context, lineObj, bias) {\n if (!lineObj) lineObj = getLine(cm.doc, pos.line);\n return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context);\n }\n\n // Returns a box for a given cursor position, which may have an\n // 'other' property containing the position of the secondary cursor\n // on a bidi boundary.\n function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {\n lineObj = lineObj || getLine(cm.doc, pos.line);\n if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj);\n function get(ch, right) {\n var m = measureCharPrepared(cm, preparedMeasure, ch, right ? \"right\" : \"left\", varHeight);\n if (right) m.left = m.right; else m.right = m.left;\n return intoCoordSystem(cm, lineObj, m, context);\n }\n function getBidi(ch, partPos) {\n var part = order[partPos], right = part.level % 2;\n if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {\n part = order[--partPos];\n ch = bidiRight(part) - (part.level % 2 ? 0 : 1);\n right = true;\n } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {\n part = order[++partPos];\n ch = bidiLeft(part) - part.level % 2;\n right = false;\n }\n if (right && ch == part.to && ch > part.from) return get(ch - 1);\n return get(ch, right);\n }\n var order = getOrder(lineObj), ch = pos.ch;\n if (!order) return get(ch);\n var partPos = getBidiPartAt(order, ch);\n var val = getBidi(ch, partPos);\n if (bidiOther != null) val.other = getBidi(ch, bidiOther);\n return val;\n }\n\n // Used to cheaply estimate the coordinates for a position. Used for\n // intermediate scroll updates.\n function estimateCoords(cm, pos) {\n var left = 0, pos = clipPos(cm.doc, pos);\n if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch;\n var lineObj = getLine(cm.doc, pos.line);\n var top = heightAtLine(lineObj) + paddingTop(cm.display);\n return {left: left, right: left, top: top, bottom: top + lineObj.height};\n }\n\n // Positions returned by coordsChar contain some extra information.\n // xRel is the relative x position of the input coordinates compared\n // to the found position (so xRel > 0 means the coordinates are to\n // the right of the character position, for example). When outside\n // is true, that means the coordinates lie outside the line's\n // vertical range.\n function PosWithInfo(line, ch, outside, xRel) {\n var pos = Pos(line, ch);\n pos.xRel = xRel;\n if (outside) pos.outside = true;\n return pos;\n }\n\n // Compute the character position closest to the given coordinates.\n // Input must be lineSpace-local (\"div\" coordinate system).\n function coordsChar(cm, x, y) {\n var doc = cm.doc;\n y += cm.display.viewOffset;\n if (y < 0) return PosWithInfo(doc.first, 0, true, -1);\n var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;\n if (lineN > last)\n return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);\n if (x < 0) x = 0;\n\n var lineObj = getLine(doc, lineN);\n for (;;) {\n var found = coordsCharInner(cm, lineObj, lineN, x, y);\n var merged = collapsedSpanAtEnd(lineObj);\n var mergedPos = merged && merged.find(0, true);\n if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))\n lineN = lineNo(lineObj = mergedPos.to.line);\n else\n return found;\n }\n }\n\n function coordsCharInner(cm, lineObj, lineNo, x, y) {\n var innerOff = y - heightAtLine(lineObj);\n var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;\n var preparedMeasure = prepareMeasureForLine(cm, lineObj);\n\n function getX(ch) {\n var sp = cursorCoords(cm, Pos(lineNo, ch), \"line\", lineObj, preparedMeasure);\n wrongLine = true;\n if (innerOff > sp.bottom) return sp.left - adjust;\n else if (innerOff < sp.top) return sp.left + adjust;\n else wrongLine = false;\n return sp.left;\n }\n\n var bidi = getOrder(lineObj), dist = lineObj.text.length;\n var from = lineLeft(lineObj), to = lineRight(lineObj);\n var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;\n\n if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);\n // Do a binary search between these bounds.\n for (;;) {\n if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {\n var ch = x < fromX || x - fromX <= toX - x ? from : to;\n var xDiff = x - (ch == from ? fromX : toX);\n while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;\n var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,\n xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);\n return pos;\n }\n var step = Math.ceil(dist / 2), middle = from + step;\n if (bidi) {\n middle = from;\n for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);\n }\n var middleX = getX(middle);\n if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}\n else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}\n }\n }\n\n var measureText;\n // Compute the default text height.\n function textHeight(display) {\n if (display.cachedTextHeight != null) return display.cachedTextHeight;\n if (measureText == null) {\n measureText = elt(\"pre\");\n // Measure a bunch of lines, for browsers that compute\n // fractional heights.\n for (var i = 0; i < 49; ++i) {\n measureText.appendChild(document.createTextNode(\"x\"));\n measureText.appendChild(elt(\"br\"));\n }\n measureText.appendChild(document.createTextNode(\"x\"));\n }\n removeChildrenAndAdd(display.measure, measureText);\n var height = measureText.offsetHeight / 50;\n if (height > 3) display.cachedTextHeight = height;\n removeChildren(display.measure);\n return height || 1;\n }\n\n // Compute the default character width.\n function charWidth(display) {\n if (display.cachedCharWidth != null) return display.cachedCharWidth;\n var anchor = elt(\"span\", \"xxxxxxxxxx\");\n var pre = elt(\"pre\", [anchor]);\n removeChildrenAndAdd(display.measure, pre);\n var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;\n if (width > 2) display.cachedCharWidth = width;\n return width || 10;\n }\n\n // OPERATIONS\n\n // Operations are used to wrap a series of changes to the editor\n // state in such a way that each change won't have to update the\n // cursor and display (which would be awkward, slow, and\n // error-prone). Instead, display updates are batched and then all\n // combined and executed at once.\n\n var operationGroup = null;\n\n var nextOpId = 0;\n // Start a new operation.\n function startOperation(cm) {\n cm.curOp = {\n cm: cm,\n viewChanged: false, // Flag that indicates that lines might need to be redrawn\n startHeight: cm.doc.height, // Used to detect need to update scrollbar\n forceUpdate: false, // Used to force a redraw\n updateInput: null, // Whether to reset the input textarea\n typing: false, // Whether this reset should be careful to leave existing text (for compositing)\n changeObjs: null, // Accumulated changes, for firing change events\n cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on\n cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already\n selectionChanged: false, // Whether the selection needs to be redrawn\n updateMaxLine: false, // Set when the widest line needs to be determined anew\n scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet\n scrollToPos: null, // Used to scroll to a specific position\n id: ++nextOpId // Unique ID\n };\n if (operationGroup) {\n operationGroup.ops.push(cm.curOp);\n } else {\n cm.curOp.ownsGroup = operationGroup = {\n ops: [cm.curOp],\n delayedCallbacks: []\n };\n }\n }\n\n function fireCallbacksForOps(group) {\n // Calls delayed callbacks and cursorActivity handlers until no\n // new ones appear\n var callbacks = group.delayedCallbacks, i = 0;\n do {\n for (; i < callbacks.length; i++)\n callbacks[i]();\n for (var j = 0; j < group.ops.length; j++) {\n var op = group.ops[j];\n if (op.cursorActivityHandlers)\n while (op.cursorActivityCalled < op.cursorActivityHandlers.length)\n op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm);\n }\n } while (i < callbacks.length);\n }\n\n // Finish an operation, updating the display and signalling delayed events\n function endOperation(cm) {\n var op = cm.curOp, group = op.ownsGroup;\n if (!group) return;\n\n try { fireCallbacksForOps(group); }\n finally {\n operationGroup = null;\n for (var i = 0; i < group.ops.length; i++)\n group.ops[i].cm.curOp = null;\n endOperations(group);\n }\n }\n\n // The DOM updates done when an operation finishes are batched so\n // that the minimum number of relayouts are required.\n function endOperations(group) {\n var ops = group.ops;\n for (var i = 0; i < ops.length; i++) // Read DOM\n endOperation_R1(ops[i]);\n for (var i = 0; i < ops.length; i++) // Write DOM (maybe)\n endOperation_W1(ops[i]);\n for (var i = 0; i < ops.length; i++) // Read DOM\n endOperation_R2(ops[i]);\n for (var i = 0; i < ops.length; i++) // Write DOM (maybe)\n endOperation_W2(ops[i]);\n for (var i = 0; i < ops.length; i++) // Read DOM\n endOperation_finish(ops[i]);\n }\n\n function endOperation_R1(op) {\n var cm = op.cm, display = cm.display;\n maybeClipScrollbars(cm);\n if (op.updateMaxLine) findMaxLine(cm);\n\n op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||\n op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||\n op.scrollToPos.to.line >= display.viewTo) ||\n display.maxLineChanged && cm.options.lineWrapping;\n op.update = op.mustUpdate &&\n new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);\n }\n\n function endOperation_W1(op) {\n op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);\n }\n\n function endOperation_R2(op) {\n var cm = op.cm, display = cm.display;\n if (op.updatedDisplay) updateHeightsInViewport(cm);\n\n op.barMeasure = measureForScrollbars(cm);\n\n // If the max line changed since it was last measured, measure it,\n // and ensure the document's width matches it.\n // updateDisplay_W2 will use these properties to do the actual resizing\n if (display.maxLineChanged && !cm.options.lineWrapping) {\n op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;\n cm.display.sizerWidth = op.adjustWidthTo;\n op.barMeasure.scrollWidth =\n Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);\n op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));\n }\n\n if (op.updatedDisplay || op.selectionChanged)\n op.newSelectionNodes = drawSelection(cm);\n }\n\n function endOperation_W2(op) {\n var cm = op.cm;\n\n if (op.adjustWidthTo != null) {\n cm.display.sizer.style.minWidth = op.adjustWidthTo + \"px\";\n if (op.maxScrollLeft < cm.doc.scrollLeft)\n setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true);\n cm.display.maxLineChanged = false;\n }\n\n if (op.newSelectionNodes)\n showSelection(cm, op.newSelectionNodes);\n if (op.updatedDisplay)\n setDocumentHeight(cm, op.barMeasure);\n if (op.updatedDisplay || op.startHeight != cm.doc.height)\n updateScrollbars(cm, op.barMeasure);\n\n if (op.selectionChanged) restartBlink(cm);\n\n if (cm.state.focused && op.updateInput)\n resetInput(cm, op.typing);\n }\n\n function endOperation_finish(op) {\n var cm = op.cm, display = cm.display, doc = cm.doc;\n\n if (op.updatedDisplay) postUpdateDisplay(cm, op.update);\n\n // Abort mouse wheel delta measurement, when scrolling explicitly\n if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))\n display.wheelStartX = display.wheelStartY = null;\n\n // Propagate the scroll position to the actual DOM scroller\n if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {\n doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));\n display.scrollbars.setScrollTop(doc.scrollTop);\n display.scroller.scrollTop = doc.scrollTop;\n }\n if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {\n doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - displayWidth(cm), op.scrollLeft));\n display.scrollbars.setScrollLeft(doc.scrollLeft);\n display.scroller.scrollLeft = doc.scrollLeft;\n alignHorizontally(cm);\n }\n // If we need to scroll a specific position into view, do so.\n if (op.scrollToPos) {\n var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),\n clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);\n if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);\n }\n\n // Fire events for markers that are hidden/unidden by editing or\n // undoing\n var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;\n if (hidden) for (var i = 0; i < hidden.length; ++i)\n if (!hidden[i].lines.length) signal(hidden[i], \"hide\");\n if (unhidden) for (var i = 0; i < unhidden.length; ++i)\n if (unhidden[i].lines.length) signal(unhidden[i], \"unhide\");\n\n if (display.wrapper.offsetHeight)\n doc.scrollTop = cm.display.scroller.scrollTop;\n\n // Fire change events, and delayed event handlers\n if (op.changeObjs)\n signal(cm, \"changes\", cm, op.changeObjs);\n }\n\n // Run the given function in an operation\n function runInOp(cm, f) {\n if (cm.curOp) return f();\n startOperation(cm);\n try { return f(); }\n finally { endOperation(cm); }\n }\n // Wraps a function in an operation. Returns the wrapped function.\n function operation(cm, f) {\n return function() {\n if (cm.curOp) return f.apply(cm, arguments);\n startOperation(cm);\n try { return f.apply(cm, arguments); }\n finally { endOperation(cm); }\n };\n }\n // Used to add methods to editor and doc instances, wrapping them in\n // operations.\n function methodOp(f) {\n return function() {\n if (this.curOp) return f.apply(this, arguments);\n startOperation(this);\n try { return f.apply(this, arguments); }\n finally { endOperation(this); }\n };\n }\n function docMethodOp(f) {\n return function() {\n var cm = this.cm;\n if (!cm || cm.curOp) return f.apply(this, arguments);\n startOperation(cm);\n try { return f.apply(this, arguments); }\n finally { endOperation(cm); }\n };\n }\n\n // VIEW TRACKING\n\n // These objects are used to represent the visible (currently drawn)\n // part of the document. A LineView may correspond to multiple\n // logical lines, if those are connected by collapsed ranges.\n function LineView(doc, line, lineN) {\n // The starting line\n this.line = line;\n // Continuing lines, if any\n this.rest = visualLineContinued(line);\n // Number of logical lines in this visual line\n this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;\n this.node = this.text = null;\n this.hidden = lineIsHidden(doc, line);\n }\n\n // Create a range of LineView objects for the given lines.\n function buildViewArray(cm, from, to) {\n var array = [], nextPos;\n for (var pos = from; pos < to; pos = nextPos) {\n var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);\n nextPos = pos + view.size;\n array.push(view);\n }\n return array;\n }\n\n // Updates the display.view data structure for a given change to the\n // document. From and to are in pre-change coordinates. Lendiff is\n // the amount of lines added or subtracted by the change. This is\n // used for changes that span multiple lines, or change the way\n // lines are divided into visual lines. regLineChange (below)\n // registers single-line changes.\n function regChange(cm, from, to, lendiff) {\n if (from == null) from = cm.doc.first;\n if (to == null) to = cm.doc.first + cm.doc.size;\n if (!lendiff) lendiff = 0;\n\n var display = cm.display;\n if (lendiff && to < display.viewTo &&\n (display.updateLineNumbers == null || display.updateLineNumbers > from))\n display.updateLineNumbers = from;\n\n cm.curOp.viewChanged = true;\n\n if (from >= display.viewTo) { // Change after\n if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)\n resetView(cm);\n } else if (to <= display.viewFrom) { // Change before\n if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {\n resetView(cm);\n } else {\n display.viewFrom += lendiff;\n display.viewTo += lendiff;\n }\n } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap\n resetView(cm);\n } else if (from <= display.viewFrom) { // Top overlap\n var cut = viewCuttingPoint(cm, to, to + lendiff, 1);\n if (cut) {\n display.view = display.view.slice(cut.index);\n display.viewFrom = cut.lineN;\n display.viewTo += lendiff;\n } else {\n resetView(cm);\n }\n } else if (to >= display.viewTo) { // Bottom overlap\n var cut = viewCuttingPoint(cm, from, from, -1);\n if (cut) {\n display.view = display.view.slice(0, cut.index);\n display.viewTo = cut.lineN;\n } else {\n resetView(cm);\n }\n } else { // Gap in the middle\n var cutTop = viewCuttingPoint(cm, from, from, -1);\n var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);\n if (cutTop && cutBot) {\n display.view = display.view.slice(0, cutTop.index)\n .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))\n .concat(display.view.slice(cutBot.index));\n display.viewTo += lendiff;\n } else {\n resetView(cm);\n }\n }\n\n var ext = display.externalMeasured;\n if (ext) {\n if (to < ext.lineN)\n ext.lineN += lendiff;\n else if (from < ext.lineN + ext.size)\n display.externalMeasured = null;\n }\n }\n\n // Register a change to a single line. Type must be one of \"text\",\n // \"gutter\", \"class\", \"widget\"\n function regLineChange(cm, line, type) {\n cm.curOp.viewChanged = true;\n var display = cm.display, ext = cm.display.externalMeasured;\n if (ext && line >= ext.lineN && line < ext.lineN + ext.size)\n display.externalMeasured = null;\n\n if (line < display.viewFrom || line >= display.viewTo) return;\n var lineView = display.view[findViewIndex(cm, line)];\n if (lineView.node == null) return;\n var arr = lineView.changes || (lineView.changes = []);\n if (indexOf(arr, type) == -1) arr.push(type);\n }\n\n // Clear the view.\n function resetView(cm) {\n cm.display.viewFrom = cm.display.viewTo = cm.doc.first;\n cm.display.view = [];\n cm.display.viewOffset = 0;\n }\n\n // Find the view element corresponding to a given line. Return null\n // when the line isn't visible.\n function findViewIndex(cm, n) {\n if (n >= cm.display.viewTo) return null;\n n -= cm.display.viewFrom;\n if (n < 0) return null;\n var view = cm.display.view;\n for (var i = 0; i < view.length; i++) {\n n -= view[i].size;\n if (n < 0) return i;\n }\n }\n\n function viewCuttingPoint(cm, oldN, newN, dir) {\n var index = findViewIndex(cm, oldN), diff, view = cm.display.view;\n if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)\n return {index: index, lineN: newN};\n for (var i = 0, n = cm.display.viewFrom; i < index; i++)\n n += view[i].size;\n if (n != oldN) {\n if (dir > 0) {\n if (index == view.length - 1) return null;\n diff = (n + view[index].size) - oldN;\n index++;\n } else {\n diff = n - oldN;\n }\n oldN += diff; newN += diff;\n }\n while (visualLineNo(cm.doc, newN) != newN) {\n if (index == (dir < 0 ? 0 : view.length - 1)) return null;\n newN += dir * view[index - (dir < 0 ? 1 : 0)].size;\n index += dir;\n }\n return {index: index, lineN: newN};\n }\n\n // Force the view to cover a given range, adding empty view element\n // or clipping off existing ones as needed.\n function adjustView(cm, from, to) {\n var display = cm.display, view = display.view;\n if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {\n display.view = buildViewArray(cm, from, to);\n display.viewFrom = from;\n } else {\n if (display.viewFrom > from)\n display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view);\n else if (display.viewFrom < from)\n display.view = display.view.slice(findViewIndex(cm, from));\n display.viewFrom = from;\n if (display.viewTo < to)\n display.view = display.view.concat(buildViewArray(cm, display.viewTo, to));\n else if (display.viewTo > to)\n display.view = display.view.slice(0, findViewIndex(cm, to));\n }\n display.viewTo = to;\n }\n\n // Count the number of lines in the view whose DOM representation is\n // out of date (or nonexistent).\n function countDirtyView(cm) {\n var view = cm.display.view, dirty = 0;\n for (var i = 0; i < view.length; i++) {\n var lineView = view[i];\n if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty;\n }\n return dirty;\n }\n\n // INPUT HANDLING\n\n // Poll for input changes, using the normal rate of polling. This\n // runs as long as the editor is focused.\n function slowPoll(cm) {\n if (cm.display.pollingFast) return;\n cm.display.poll.set(cm.options.pollInterval, function() {\n readInput(cm);\n if (cm.state.focused) slowPoll(cm);\n });\n }\n\n // When an event has just come in that is likely to add or change\n // something in the input textarea, we poll faster, to ensure that\n // the change appears on the screen quickly.\n function fastPoll(cm) {\n var missed = false;\n cm.display.pollingFast = true;\n function p() {\n var changed = readInput(cm);\n if (!changed && !missed) {missed = true; cm.display.poll.set(60, p);}\n else {cm.display.pollingFast = false; slowPoll(cm);}\n }\n cm.display.poll.set(20, p);\n }\n\n // This will be set to an array of strings when copying, so that,\n // when pasting, we know what kind of selections the copied text\n // was made out of.\n var lastCopied = null;\n\n // Read input from the textarea, and update the document to match.\n // When something is selected, it is present in the textarea, and\n // selected (unless it is huge, in which case a placeholder is\n // used). When nothing is selected, the cursor sits after previously\n // seen text (can be empty), which is stored in prevInput (we must\n // not reset the textarea when typing, because that breaks IME).\n function readInput(cm) {\n var input = cm.display.input, prevInput = cm.display.prevInput, doc = cm.doc;\n // Since this is called a *lot*, try to bail out as cheaply as\n // possible when it is clear that nothing happened. hasSelection\n // will be the case when there is a lot of text in the textarea,\n // in which case reading its value would be expensive.\n if (!cm.state.focused || (hasSelection(input) && !prevInput) || isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq)\n return false;\n // See paste handler for more on the fakedLastChar kludge\n if (cm.state.pasteIncoming && cm.state.fakedLastChar) {\n input.value = input.value.substring(0, input.value.length - 1);\n cm.state.fakedLastChar = false;\n }\n var text = input.value;\n // If nothing changed, bail.\n if (text == prevInput && !cm.somethingSelected()) return false;\n // Work around nonsensical selection resetting in IE9/10, and\n // inexplicable appearance of private area unicode characters on\n // some key combos in Mac (#2689).\n if (ie && ie_version >= 9 && cm.display.inputHasSelection === text ||\n mac && /[\\uf700-\\uf7ff]/.test(text)) {\n resetInput(cm);\n return false;\n }\n\n var withOp = !cm.curOp;\n if (withOp) startOperation(cm);\n cm.display.shift = false;\n\n if (text.charCodeAt(0) == 0x200b && doc.sel == cm.display.selForContextMenu && !prevInput)\n prevInput = \"\\u200b\";\n // Find the part of the input that is actually new\n var same = 0, l = Math.min(prevInput.length, text.length);\n while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;\n var inserted = text.slice(same), textLines = splitLines(inserted);\n\n // When pasing N lines into N selections, insert one line per selection\n var multiPaste = null;\n if (cm.state.pasteIncoming && doc.sel.ranges.length > 1) {\n if (lastCopied && lastCopied.join(\"\\n\") == inserted)\n multiPaste = doc.sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines);\n else if (textLines.length == doc.sel.ranges.length)\n multiPaste = map(textLines, function(l) { return [l]; });\n }\n\n // Normal behavior is to insert the new text into every selection\n for (var i = doc.sel.ranges.length - 1; i >= 0; i--) {\n var range = doc.sel.ranges[i];\n var from = range.from(), to = range.to();\n // Handle deletion\n if (same < prevInput.length)\n from = Pos(from.line, from.ch - (prevInput.length - same));\n // Handle overwrite\n else if (cm.state.overwrite && range.empty() && !cm.state.pasteIncoming)\n to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));\n var updateInput = cm.curOp.updateInput;\n var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,\n origin: cm.state.pasteIncoming ? \"paste\" : cm.state.cutIncoming ? \"cut\" : \"+input\"};\n makeChange(cm.doc, changeEvent);\n signalLater(cm, \"inputRead\", cm, changeEvent);\n // When an 'electric' character is inserted, immediately trigger a reindent\n if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&\n cm.options.smartIndent && range.head.ch < 100 &&\n (!i || doc.sel.ranges[i - 1].head.line != range.head.line)) {\n var mode = cm.getModeAt(range.head);\n var end = changeEnd(changeEvent);\n if (mode.electricChars) {\n for (var j = 0; j < mode.electricChars.length; j++)\n if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {\n indentLine(cm, end.line, \"smart\");\n break;\n }\n } else if (mode.electricInput) {\n if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch)))\n indentLine(cm, end.line, \"smart\");\n }\n }\n }\n ensureCursorVisible(cm);\n cm.curOp.updateInput = updateInput;\n cm.curOp.typing = true;\n\n // Don't leave long text in the textarea, since it makes further polling slow\n if (text.length > 1000 || text.indexOf(\"\\n\") > -1) input.value = cm.display.prevInput = \"\";\n else cm.display.prevInput = text;\n if (withOp) endOperation(cm);\n cm.state.pasteIncoming = cm.state.cutIncoming = false;\n return true;\n }\n\n // Reset the input to correspond to the selection (or to be empty,\n // when not typing and nothing is selected)\n function resetInput(cm, typing) {\n if (cm.display.contextMenuPending) return;\n var minimal, selected, doc = cm.doc;\n if (cm.somethingSelected()) {\n cm.display.prevInput = \"\";\n var range = doc.sel.primary();\n minimal = hasCopyEvent &&\n (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);\n var content = minimal ? \"-\" : selected || cm.getSelection();\n cm.display.input.value = content;\n if (cm.state.focused) selectInput(cm.display.input);\n if (ie && ie_version >= 9) cm.display.inputHasSelection = content;\n } else if (!typing) {\n cm.display.prevInput = cm.display.input.value = \"\";\n if (ie && ie_version >= 9) cm.display.inputHasSelection = null;\n }\n cm.display.inaccurateSelection = minimal;\n }\n\n function focusInput(cm) {\n if (cm.options.readOnly != \"nocursor\" && (!mobile || activeElt() != cm.display.input))\n cm.display.input.focus();\n }\n\n function ensureFocus(cm) {\n if (!cm.state.focused) { focusInput(cm); onFocus(cm); }\n }\n\n function isReadOnly(cm) {\n return cm.options.readOnly || cm.doc.cantEdit;\n }\n\n // EVENT HANDLERS\n\n // Attach the necessary event handlers when initializing the editor\n function registerEventHandlers(cm) {\n var d = cm.display;\n on(d.scroller, \"mousedown\", operation(cm, onMouseDown));\n // Older IE's will not fire a second mousedown for a double click\n if (ie && ie_version < 11)\n on(d.scroller, \"dblclick\", operation(cm, function(e) {\n if (signalDOMEvent(cm, e)) return;\n var pos = posFromMouse(cm, e);\n if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;\n e_preventDefault(e);\n var word = cm.findWordAt(pos);\n extendSelection(cm.doc, word.anchor, word.head);\n }));\n else\n on(d.scroller, \"dblclick\", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });\n // Prevent normal selection in the editor (we handle our own)\n on(d.lineSpace, \"selectstart\", function(e) {\n if (!eventInWidget(d, e)) e_preventDefault(e);\n });\n // Some browsers fire contextmenu *after* opening the menu, at\n // which point we can't mess with it anymore. Context menu is\n // handled in onMouseDown for these browsers.\n if (!captureRightClick) on(d.scroller, \"contextmenu\", function(e) {onContextMenu(cm, e);});\n\n // Sync scrolling between fake scrollbars and real scrollable\n // area, ensure viewport is updated when scrolling.\n on(d.scroller, \"scroll\", function() {\n if (d.scroller.clientHeight) {\n setScrollTop(cm, d.scroller.scrollTop);\n setScrollLeft(cm, d.scroller.scrollLeft, true);\n signal(cm, \"scroll\", cm);\n }\n });\n\n // Listen to wheel events in order to try and update the viewport on time.\n on(d.scroller, \"mousewheel\", function(e){onScrollWheel(cm, e);});\n on(d.scroller, \"DOMMouseScroll\", function(e){onScrollWheel(cm, e);});\n\n // Prevent wrapper from ever scrolling\n on(d.wrapper, \"scroll\", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });\n\n on(d.input, \"keyup\", function(e) { onKeyUp.call(cm, e); });\n on(d.input, \"input\", function() {\n if (ie && ie_version >= 9 && cm.display.inputHasSelection) cm.display.inputHasSelection = null;\n readInput(cm);\n });\n on(d.input, \"keydown\", operation(cm, onKeyDown));\n on(d.input, \"keypress\", operation(cm, onKeyPress));\n on(d.input, \"focus\", bind(onFocus, cm));\n on(d.input, \"blur\", bind(onBlur, cm));\n\n function drag_(e) {\n if (!signalDOMEvent(cm, e)) e_stop(e);\n }\n if (cm.options.dragDrop) {\n on(d.scroller, \"dragstart\", function(e){onDragStart(cm, e);});\n on(d.scroller, \"dragenter\", drag_);\n on(d.scroller, \"dragover\", drag_);\n on(d.scroller, \"drop\", operation(cm, onDrop));\n }\n on(d.scroller, \"paste\", function(e) {\n if (eventInWidget(d, e)) return;\n cm.state.pasteIncoming = true;\n focusInput(cm);\n fastPoll(cm);\n });\n on(d.input, \"paste\", function() {\n // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206\n // Add a char to the end of textarea before paste occur so that\n // selection doesn't span to the end of textarea.\n if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {\n var start = d.input.selectionStart, end = d.input.selectionEnd;\n d.input.value += \"$\";\n // The selection end needs to be set before the start, otherwise there\n // can be an intermediate non-empty selection between the two, which\n // can override the middle-click paste buffer on linux and cause the\n // wrong thing to get pasted.\n d.input.selectionEnd = end;\n d.input.selectionStart = start;\n cm.state.fakedLastChar = true;\n }\n cm.state.pasteIncoming = true;\n fastPoll(cm);\n });\n\n function prepareCopyCut(e) {\n if (cm.somethingSelected()) {\n lastCopied = cm.getSelections();\n if (d.inaccurateSelection) {\n d.prevInput = \"\";\n d.inaccurateSelection = false;\n d.input.value = lastCopied.join(\"\\n\");\n selectInput(d.input);\n }\n } else {\n var text = [], ranges = [];\n for (var i = 0; i < cm.doc.sel.ranges.length; i++) {\n var line = cm.doc.sel.ranges[i].head.line;\n var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};\n ranges.push(lineRange);\n text.push(cm.getRange(lineRange.anchor, lineRange.head));\n }\n if (e.type == \"cut\") {\n cm.setSelections(ranges, null, sel_dontScroll);\n } else {\n d.prevInput = \"\";\n d.input.value = text.join(\"\\n\");\n selectInput(d.input);\n }\n lastCopied = text;\n }\n if (e.type == \"cut\") cm.state.cutIncoming = true;\n }\n on(d.input, \"cut\", prepareCopyCut);\n on(d.input, \"copy\", prepareCopyCut);\n\n // Needed to handle Tab key in KHTML\n if (khtml) on(d.sizer, \"mouseup\", function() {\n if (activeElt() == d.input) d.input.blur();\n focusInput(cm);\n });\n }\n\n // Called when the window resizes\n function onResize(cm) {\n var d = cm.display;\n if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)\n return;\n // Might be a text scaling operation, clear size caches.\n d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;\n d.scrollbarsClipped = false;\n cm.setSize();\n }\n\n // MOUSE EVENTS\n\n // Return true when the given mouse event happened in a widget\n function eventInWidget(display, e) {\n for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {\n if (!n || (n.nodeType == 1 && n.getAttribute(\"cm-ignore-events\") == \"true\") ||\n (n.parentNode == display.sizer && n != display.mover))\n return true;\n }\n }\n\n // Given a mouse event, find the corresponding position. If liberal\n // is false, it checks whether a gutter or scrollbar was clicked,\n // and returns null if it was. forRect is used by rectangular\n // selections, and tries to estimate a character position even for\n // coordinates beyond the right of the text.\n function posFromMouse(cm, e, liberal, forRect) {\n var display = cm.display;\n if (!liberal && e_target(e).getAttribute(\"not-content\") == \"true\") return null;\n\n var x, y, space = display.lineSpace.getBoundingClientRect();\n // Fails unpredictably on IE[67] when mouse is dragged around quickly.\n try { x = e.clientX - space.left; y = e.clientY - space.top; }\n catch (e) { return null; }\n var coords = coordsChar(cm, x, y), line;\n if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {\n var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;\n coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));\n }\n return coords;\n }\n\n // A mouse down can be a single click, double click, triple click,\n // start of selection drag, start of text drag, new cursor\n // (ctrl-click), rectangle drag (alt-drag), or xwin\n // middle-click-paste. Or it might be a click on something we should\n // not interfere with, such as a scrollbar or widget.\n function onMouseDown(e) {\n if (signalDOMEvent(this, e)) return;\n var cm = this, display = cm.display;\n display.shift = e.shiftKey;\n\n if (eventInWidget(display, e)) {\n if (!webkit) {\n // Briefly turn off draggability, to allow widgets to do\n // normal dragging things.\n display.scroller.draggable = false;\n setTimeout(function(){display.scroller.draggable = true;}, 100);\n }\n return;\n }\n if (clickInGutter(cm, e)) return;\n var start = posFromMouse(cm, e);\n window.focus();\n\n switch (e_button(e)) {\n case 1:\n if (start)\n leftButtonDown(cm, e, start);\n else if (e_target(e) == display.scroller)\n e_preventDefault(e);\n break;\n case 2:\n if (webkit) cm.state.lastMiddleDown = +new Date;\n if (start) extendSelection(cm.doc, start);\n setTimeout(bind(focusInput, cm), 20);\n e_preventDefault(e);\n break;\n case 3:\n if (captureRightClick) onContextMenu(cm, e);\n break;\n }\n }\n\n var lastClick, lastDoubleClick;\n function leftButtonDown(cm, e, start) {\n setTimeout(bind(ensureFocus, cm), 0);\n\n var now = +new Date, type;\n if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {\n type = \"triple\";\n } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {\n type = \"double\";\n lastDoubleClick = {time: now, pos: start};\n } else {\n type = \"single\";\n lastClick = {time: now, pos: start};\n }\n\n var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained;\n if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&\n type == \"single\" && (contained = sel.contains(start)) > -1 &&\n !sel.ranges[contained].empty())\n leftButtonStartDrag(cm, e, start, modifier);\n else\n leftButtonSelect(cm, e, start, type, modifier);\n }\n\n // Start a text drag. When it ends, see if any dragging actually\n // happen, and treat as a click if it didn't.\n function leftButtonStartDrag(cm, e, start, modifier) {\n var display = cm.display;\n var dragEnd = operation(cm, function(e2) {\n if (webkit) display.scroller.draggable = false;\n cm.state.draggingText = false;\n off(document, \"mouseup\", dragEnd);\n off(display.scroller, \"drop\", dragEnd);\n if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {\n e_preventDefault(e2);\n if (!modifier)\n extendSelection(cm.doc, start);\n focusInput(cm);\n // Work around unexplainable focus problem in IE9 (#2127)\n if (ie && ie_version == 9)\n setTimeout(function() {document.body.focus(); focusInput(cm);}, 20);\n }\n });\n // Let the drag handler handle this.\n if (webkit) display.scroller.draggable = true;\n cm.state.draggingText = dragEnd;\n // IE's approach to draggable\n if (display.scroller.dragDrop) display.scroller.dragDrop();\n on(document, \"mouseup\", dragEnd);\n on(display.scroller, \"drop\", dragEnd);\n }\n\n // Normal selection, as opposed to text dragging.\n function leftButtonSelect(cm, e, start, type, addNew) {\n var display = cm.display, doc = cm.doc;\n e_preventDefault(e);\n\n var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;\n if (addNew && !e.shiftKey) {\n ourIndex = doc.sel.contains(start);\n if (ourIndex > -1)\n ourRange = ranges[ourIndex];\n else\n ourRange = new Range(start, start);\n } else {\n ourRange = doc.sel.primary();\n }\n\n if (e.altKey) {\n type = \"rect\";\n if (!addNew) ourRange = new Range(start, start);\n start = posFromMouse(cm, e, true, true);\n ourIndex = -1;\n } else if (type == \"double\") {\n var word = cm.findWordAt(start);\n if (cm.display.shift || doc.extend)\n ourRange = extendRange(doc, ourRange, word.anchor, word.head);\n else\n ourRange = word;\n } else if (type == \"triple\") {\n var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)));\n if (cm.display.shift || doc.extend)\n ourRange = extendRange(doc, ourRange, line.anchor, line.head);\n else\n ourRange = line;\n } else {\n ourRange = extendRange(doc, ourRange, start);\n }\n\n if (!addNew) {\n ourIndex = 0;\n setSelection(doc, new Selection([ourRange], 0), sel_mouse);\n startSel = doc.sel;\n } else if (ourIndex == -1) {\n ourIndex = ranges.length;\n setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),\n {scroll: false, origin: \"*mouse\"});\n } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == \"single\") {\n setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0));\n startSel = doc.sel;\n } else {\n replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);\n }\n\n var lastPos = start;\n function extendTo(pos) {\n if (cmp(lastPos, pos) == 0) return;\n lastPos = pos;\n\n if (type == \"rect\") {\n var ranges = [], tabSize = cm.options.tabSize;\n var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);\n var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);\n var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);\n for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));\n line <= end; line++) {\n var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);\n if (left == right)\n ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos)));\n else if (text.length > leftPos)\n ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));\n }\n if (!ranges.length) ranges.push(new Range(start, start));\n setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),\n {origin: \"*mouse\", scroll: false});\n cm.scrollIntoView(pos);\n } else {\n var oldRange = ourRange;\n var anchor = oldRange.anchor, head = pos;\n if (type != \"single\") {\n if (type == \"double\")\n var range = cm.findWordAt(pos);\n else\n var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));\n if (cmp(range.anchor, anchor) > 0) {\n head = range.head;\n anchor = minPos(oldRange.from(), range.anchor);\n } else {\n head = range.anchor;\n anchor = maxPos(oldRange.to(), range.head);\n }\n }\n var ranges = startSel.ranges.slice(0);\n ranges[ourIndex] = new Range(clipPos(doc, anchor), head);\n setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse);\n }\n }\n\n var editorSize = display.wrapper.getBoundingClientRect();\n // Used to ensure timeout re-tries don't fire when another extend\n // happened in the meantime (clearTimeout isn't reliable -- at\n // least on Chrome, the timeouts still happen even when cleared,\n // if the clear happens after their scheduled firing time).\n var counter = 0;\n\n function extend(e) {\n var curCount = ++counter;\n var cur = posFromMouse(cm, e, true, type == \"rect\");\n if (!cur) return;\n if (cmp(cur, lastPos) != 0) {\n ensureFocus(cm);\n extendTo(cur);\n var visible = visibleLines(display, doc);\n if (cur.line >= visible.to || cur.line < visible.from)\n setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);\n } else {\n var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;\n if (outside) setTimeout(operation(cm, function() {\n if (counter != curCount) return;\n display.scroller.scrollTop += outside;\n extend(e);\n }), 50);\n }\n }\n\n function done(e) {\n counter = Infinity;\n e_preventDefault(e);\n focusInput(cm);\n off(document, \"mousemove\", move);\n off(document, \"mouseup\", up);\n doc.history.lastSelOrigin = null;\n }\n\n var move = operation(cm, function(e) {\n if (!e_button(e)) done(e);\n else extend(e);\n });\n var up = operation(cm, done);\n on(document, \"mousemove\", move);\n on(document, \"mouseup\", up);\n }\n\n // Determines whether an event happened in the gutter, and fires the\n // handlers for the corresponding event.\n function gutterEvent(cm, e, type, prevent, signalfn) {\n try { var mX = e.clientX, mY = e.clientY; }\n catch(e) { return false; }\n if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;\n if (prevent) e_preventDefault(e);\n\n var display = cm.display;\n var lineBox = display.lineDiv.getBoundingClientRect();\n\n if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);\n mY -= lineBox.top - display.viewOffset;\n\n for (var i = 0; i < cm.options.gutters.length; ++i) {\n var g = display.gutters.childNodes[i];\n if (g && g.getBoundingClientRect().right >= mX) {\n var line = lineAtHeight(cm.doc, mY);\n var gutter = cm.options.gutters[i];\n signalfn(cm, type, cm, line, gutter, e);\n return e_defaultPrevented(e);\n }\n }\n }\n\n function clickInGutter(cm, e) {\n return gutterEvent(cm, e, \"gutterClick\", true, signalLater);\n }\n\n // Kludge to work around strange IE behavior where it'll sometimes\n // re-fire a series of drag-related events right after the drop (#1551)\n var lastDrop = 0;\n\n function onDrop(e) {\n var cm = this;\n if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))\n return;\n e_preventDefault(e);\n if (ie) lastDrop = +new Date;\n var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;\n if (!pos || isReadOnly(cm)) return;\n // Might be a file drop, in which case we simply extract the text\n // and insert it.\n if (files && files.length && window.FileReader && window.File) {\n var n = files.length, text = Array(n), read = 0;\n var loadFile = function(file, i) {\n var reader = new FileReader;\n reader.onload = operation(cm, function() {\n text[i] = reader.result;\n if (++read == n) {\n pos = clipPos(cm.doc, pos);\n var change = {from: pos, to: pos, text: splitLines(text.join(\"\\n\")), origin: \"paste\"};\n makeChange(cm.doc, change);\n setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));\n }\n });\n reader.readAsText(file);\n };\n for (var i = 0; i < n; ++i) loadFile(files[i], i);\n } else { // Normal drop\n // Don't do a replace if the drop happened inside of the selected text.\n if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {\n cm.state.draggingText(e);\n // Ensure the editor is re-focused\n setTimeout(bind(focusInput, cm), 20);\n return;\n }\n try {\n var text = e.dataTransfer.getData(\"Text\");\n if (text) {\n if (cm.state.draggingText && !(mac ? e.metaKey : e.ctrlKey))\n var selected = cm.listSelections();\n setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));\n if (selected) for (var i = 0; i < selected.length; ++i)\n replaceRange(cm.doc, \"\", selected[i].anchor, selected[i].head, \"drag\");\n cm.replaceSelection(text, \"around\", \"paste\");\n focusInput(cm);\n }\n }\n catch(e){}\n }\n }\n\n function onDragStart(cm, e) {\n if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }\n if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;\n\n e.dataTransfer.setData(\"Text\", cm.getSelection());\n\n // Use dummy image instead of default browsers image.\n // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.\n if (e.dataTransfer.setDragImage && !safari) {\n var img = elt(\"img\", null, null, \"position: fixed; left: 0; top: 0;\");\n img.src = \"data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==\";\n if (presto) {\n img.width = img.height = 1;\n cm.display.wrapper.appendChild(img);\n // Force a relayout, or Opera won't use our image for some obscure reason\n img._top = img.offsetTop;\n }\n e.dataTransfer.setDragImage(img, 0, 0);\n if (presto) img.parentNode.removeChild(img);\n }\n }\n\n // SCROLL EVENTS\n\n // Sync the scrollable area and scrollbars, ensure the viewport\n // covers the visible area.\n function setScrollTop(cm, val) {\n if (Math.abs(cm.doc.scrollTop - val) < 2) return;\n cm.doc.scrollTop = val;\n if (!gecko) updateDisplaySimple(cm, {top: val});\n if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;\n cm.display.scrollbars.setScrollTop(val);\n if (gecko) updateDisplaySimple(cm);\n startWorker(cm, 100);\n }\n // Sync scroller and scrollbar, ensure the gutter elements are\n // aligned.\n function setScrollLeft(cm, val, isScroller) {\n if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;\n val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);\n cm.doc.scrollLeft = val;\n alignHorizontally(cm);\n if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;\n cm.display.scrollbars.setScrollLeft(val);\n }\n\n // Since the delta values reported on mouse wheel events are\n // unstandardized between browsers and even browser versions, and\n // generally horribly unpredictable, this code starts by measuring\n // the scroll effect that the first few mouse wheel events have,\n // and, from that, detects the way it can convert deltas to pixel\n // offsets afterwards.\n //\n // The reason we want to know the amount a wheel event will scroll\n // is that it gives us a chance to update the display before the\n // actual scrolling happens, reducing flickering.\n\n var wheelSamples = 0, wheelPixelsPerUnit = null;\n // Fill in a browser-detected starting value on browsers where we\n // know one. These don't have to be accurate -- the result of them\n // being wrong would just be a slight flicker on the first wheel\n // scroll (if it is large enough).\n if (ie) wheelPixelsPerUnit = -.53;\n else if (gecko) wheelPixelsPerUnit = 15;\n else if (chrome) wheelPixelsPerUnit = -.7;\n else if (safari) wheelPixelsPerUnit = -1/3;\n\n var wheelEventDelta = function(e) {\n var dx = e.wheelDeltaX, dy = e.wheelDeltaY;\n if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;\n if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;\n else if (dy == null) dy = e.wheelDelta;\n return {x: dx, y: dy};\n };\n CodeMirror.wheelEventPixels = function(e) {\n var delta = wheelEventDelta(e);\n delta.x *= wheelPixelsPerUnit;\n delta.y *= wheelPixelsPerUnit;\n return delta;\n };\n\n function onScrollWheel(cm, e) {\n var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;\n\n var display = cm.display, scroll = display.scroller;\n // Quit if there's nothing to scroll here\n if (!(dx && scroll.scrollWidth > scroll.clientWidth ||\n dy && scroll.scrollHeight > scroll.clientHeight)) return;\n\n // Webkit browsers on OS X abort momentum scrolls when the target\n // of the scroll event is removed from the scrollable element.\n // This hack (see related code in patchDisplay) makes sure the\n // element is kept around.\n if (dy && mac && webkit) {\n outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {\n for (var i = 0; i < view.length; i++) {\n if (view[i].node == cur) {\n cm.display.currentWheelTarget = cur;\n break outer;\n }\n }\n }\n }\n\n // On some browsers, horizontal scrolling will cause redraws to\n // happen before the gutter has been realigned, causing it to\n // wriggle around in a most unseemly way. When we have an\n // estimated pixels/delta value, we just handle horizontal\n // scrolling entirely here. It'll be slightly off from native, but\n // better than glitching out.\n if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {\n if (dy)\n setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));\n setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));\n e_preventDefault(e);\n display.wheelStartX = null; // Abort measurement, if in progress\n return;\n }\n\n // 'Project' the visible viewport to cover the area that is being\n // scrolled into view (if we know enough to estimate it).\n if (dy && wheelPixelsPerUnit != null) {\n var pixels = dy * wheelPixelsPerUnit;\n var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;\n if (pixels < 0) top = Math.max(0, top + pixels - 50);\n else bot = Math.min(cm.doc.height, bot + pixels + 50);\n updateDisplaySimple(cm, {top: top, bottom: bot});\n }\n\n if (wheelSamples < 20) {\n if (display.wheelStartX == null) {\n display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;\n display.wheelDX = dx; display.wheelDY = dy;\n setTimeout(function() {\n if (display.wheelStartX == null) return;\n var movedX = scroll.scrollLeft - display.wheelStartX;\n var movedY = scroll.scrollTop - display.wheelStartY;\n var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||\n (movedX && display.wheelDX && movedX / display.wheelDX);\n display.wheelStartX = display.wheelStartY = null;\n if (!sample) return;\n wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);\n ++wheelSamples;\n }, 200);\n } else {\n display.wheelDX += dx; display.wheelDY += dy;\n }\n }\n }\n\n // KEY EVENTS\n\n // Run a handler that was bound to a key.\n function doHandleBinding(cm, bound, dropShift) {\n if (typeof bound == \"string\") {\n bound = commands[bound];\n if (!bound) return false;\n }\n // Ensure previous input has been read, so that the handler sees a\n // consistent view of the document\n if (cm.display.pollingFast && readInput(cm)) cm.display.pollingFast = false;\n var prevShift = cm.display.shift, done = false;\n try {\n if (isReadOnly(cm)) cm.state.suppressEdits = true;\n if (dropShift) cm.display.shift = false;\n done = bound(cm) != Pass;\n } finally {\n cm.display.shift = prevShift;\n cm.state.suppressEdits = false;\n }\n return done;\n }\n\n function lookupKeyForEditor(cm, name, handle) {\n for (var i = 0; i < cm.state.keyMaps.length; i++) {\n var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);\n if (result) return result;\n }\n return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))\n || lookupKey(name, cm.options.keyMap, handle, cm);\n }\n\n var stopSeq = new Delayed;\n function dispatchKey(cm, name, e, handle) {\n var seq = cm.state.keySeq;\n if (seq) {\n if (isModifierKey(name)) return \"handled\";\n stopSeq.set(50, function() {\n if (cm.state.keySeq == seq) {\n cm.state.keySeq = null;\n resetInput(cm);\n }\n });\n name = seq + \" \" + name;\n }\n var result = lookupKeyForEditor(cm, name, handle);\n\n if (result == \"multi\")\n cm.state.keySeq = name;\n if (result == \"handled\")\n signalLater(cm, \"keyHandled\", cm, name, e);\n\n if (result == \"handled\" || result == \"multi\") {\n e_preventDefault(e);\n restartBlink(cm);\n }\n\n if (seq && !result && /\\'$/.test(name)) {\n e_preventDefault(e);\n return true;\n }\n return !!result;\n }\n\n // Handle a key from the keydown event.\n function handleKeyBinding(cm, e) {\n var name = keyName(e, true);\n if (!name) return false;\n\n if (e.shiftKey && !cm.state.keySeq) {\n // First try to resolve full name (including 'Shift-'). Failing\n // that, see if there is a cursor-motion command (starting with\n // 'go') bound to the keyname without 'Shift-'.\n return dispatchKey(cm, \"Shift-\" + name, e, function(b) {return doHandleBinding(cm, b, true);})\n || dispatchKey(cm, name, e, function(b) {\n if (typeof b == \"string\" ? /^go[A-Z]/.test(b) : b.motion)\n return doHandleBinding(cm, b);\n });\n } else {\n return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); });\n }\n }\n\n // Handle a key from the keypress event\n function handleCharBinding(cm, e, ch) {\n return dispatchKey(cm, \"'\" + ch + \"'\", e,\n function(b) { return doHandleBinding(cm, b, true); });\n }\n\n var lastStoppedKey = null;\n function onKeyDown(e) {\n var cm = this;\n ensureFocus(cm);\n if (signalDOMEvent(cm, e)) return;\n // IE does strange things with escape.\n if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false;\n var code = e.keyCode;\n cm.display.shift = code == 16 || e.shiftKey;\n var handled = handleKeyBinding(cm, e);\n if (presto) {\n lastStoppedKey = handled ? code : null;\n // Opera has no cut event... we try to at least catch the key combo\n if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))\n cm.replaceSelection(\"\", null, \"cut\");\n }\n\n // Turn mouse into crosshair when Alt is held on Mac.\n if (code == 18 && !/\\bCodeMirror-crosshair\\b/.test(cm.display.lineDiv.className))\n showCrossHair(cm);\n }\n\n function showCrossHair(cm) {\n var lineDiv = cm.display.lineDiv;\n addClass(lineDiv, \"CodeMirror-crosshair\");\n\n function up(e) {\n if (e.keyCode == 18 || !e.altKey) {\n rmClass(lineDiv, \"CodeMirror-crosshair\");\n off(document, \"keyup\", up);\n off(document, \"mouseover\", up);\n }\n }\n on(document, \"keyup\", up);\n on(document, \"mouseover\", up);\n }\n\n function onKeyUp(e) {\n if (e.keyCode == 16) this.doc.sel.shift = false;\n signalDOMEvent(this, e);\n }\n\n function onKeyPress(e) {\n var cm = this;\n if (signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return;\n var keyCode = e.keyCode, charCode = e.charCode;\n if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}\n if (((presto && (!e.which || e.which < 10)) || khtml) && handleKeyBinding(cm, e)) return;\n var ch = String.fromCharCode(charCode == null ? keyCode : charCode);\n if (handleCharBinding(cm, e, ch)) return;\n if (ie && ie_version >= 9) cm.display.inputHasSelection = null;\n fastPoll(cm);\n }\n\n // FOCUS/BLUR EVENTS\n\n function onFocus(cm) {\n if (cm.options.readOnly == \"nocursor\") return;\n if (!cm.state.focused) {\n signal(cm, \"focus\", cm);\n cm.state.focused = true;\n addClass(cm.display.wrapper, \"CodeMirror-focused\");\n // The prevInput test prevents this from firing when a context\n // menu is closed (since the resetInput would kill the\n // select-all detection hack)\n if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {\n resetInput(cm);\n if (webkit) setTimeout(bind(resetInput, cm, true), 0); // Issue #1730\n }\n }\n slowPoll(cm);\n restartBlink(cm);\n }\n function onBlur(cm) {\n if (cm.state.focused) {\n signal(cm, \"blur\", cm);\n cm.state.focused = false;\n rmClass(cm.display.wrapper, \"CodeMirror-focused\");\n }\n clearInterval(cm.display.blinker);\n setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150);\n }\n\n // CONTEXT MENU HANDLING\n\n // To make the context menu work, we need to briefly unhide the\n // textarea (making it as unobtrusive as possible) to let the\n // right-click take effect on it.\n function onContextMenu(cm, e) {\n if (signalDOMEvent(cm, e, \"contextmenu\")) return;\n var display = cm.display;\n if (eventInWidget(display, e) || contextMenuInGutter(cm, e)) return;\n\n var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;\n if (!pos || presto) return; // Opera is difficult.\n\n // Reset the current text selection only if the click is done outside of the selection\n // and 'resetSelectionOnContextMenu' option is true.\n var reset = cm.options.resetSelectionOnContextMenu;\n if (reset && cm.doc.sel.contains(pos) == -1)\n operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);\n\n var oldCSS = display.input.style.cssText;\n display.inputDiv.style.position = \"absolute\";\n display.input.style.cssText = \"position: fixed; width: 30px; height: 30px; top: \" + (e.clientY - 5) +\n \"px; left: \" + (e.clientX - 5) + \"px; z-index: 1000; background: \" +\n (ie ? \"rgba(255, 255, 255, .05)\" : \"transparent\") +\n \"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);\";\n if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)\n focusInput(cm);\n if (webkit) window.scrollTo(null, oldScrollY);\n resetInput(cm);\n // Adds \"Select all\" to context menu in FF\n if (!cm.somethingSelected()) display.input.value = display.prevInput = \" \";\n display.contextMenuPending = true;\n display.selForContextMenu = cm.doc.sel;\n clearTimeout(display.detectingSelectAll);\n\n // Select-all will be greyed out if there's nothing to select, so\n // this adds a zero-width space so that we can later check whether\n // it got selected.\n function prepareSelectAllHack() {\n if (display.input.selectionStart != null) {\n var selected = cm.somethingSelected();\n var extval = display.input.value = \"\\u200b\" + (selected ? display.input.value : \"\");\n display.prevInput = selected ? \"\" : \"\\u200b\";\n display.input.selectionStart = 1; display.input.selectionEnd = extval.length;\n // Re-set this, in case some other handler touched the\n // selection in the meantime.\n display.selForContextMenu = cm.doc.sel;\n }\n }\n function rehide() {\n display.contextMenuPending = false;\n display.inputDiv.style.position = \"relative\";\n display.input.style.cssText = oldCSS;\n if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos);\n slowPoll(cm);\n\n // Try to detect the user choosing select-all\n if (display.input.selectionStart != null) {\n if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();\n var i = 0, poll = function() {\n if (display.selForContextMenu == cm.doc.sel && display.input.selectionStart == 0)\n operation(cm, commands.selectAll)(cm);\n else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);\n else resetInput(cm);\n };\n display.detectingSelectAll = setTimeout(poll, 200);\n }\n }\n\n if (ie && ie_version >= 9) prepareSelectAllHack();\n if (captureRightClick) {\n e_stop(e);\n var mouseup = function() {\n off(window, \"mouseup\", mouseup);\n setTimeout(rehide, 20);\n };\n on(window, \"mouseup\", mouseup);\n } else {\n setTimeout(rehide, 50);\n }\n }\n\n function contextMenuInGutter(cm, e) {\n if (!hasHandler(cm, \"gutterContextMenu\")) return false;\n return gutterEvent(cm, e, \"gutterContextMenu\", false, signal);\n }\n\n // UPDATING\n\n // Compute the position of the end of a change (its 'to' property\n // refers to the pre-change end).\n var changeEnd = CodeMirror.changeEnd = function(change) {\n if (!change.text) return change.to;\n return Pos(change.from.line + change.text.length - 1,\n lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));\n };\n\n // Adjust a position to refer to the post-change position of the\n // same text, or the end of the change if the change covers it.\n function adjustForChange(pos, change) {\n if (cmp(pos, change.from) < 0) return pos;\n if (cmp(pos, change.to) <= 0) return changeEnd(change);\n\n var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;\n if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch;\n return Pos(line, ch);\n }\n\n function computeSelAfterChange(doc, change) {\n var out = [];\n for (var i = 0; i < doc.sel.ranges.length; i++) {\n var range = doc.sel.ranges[i];\n out.push(new Range(adjustForChange(range.anchor, change),\n adjustForChange(range.head, change)));\n }\n return normalizeSelection(out, doc.sel.primIndex);\n }\n\n function offsetPos(pos, old, nw) {\n if (pos.line == old.line)\n return Pos(nw.line, pos.ch - old.ch + nw.ch);\n else\n return Pos(nw.line + (pos.line - old.line), pos.ch);\n }\n\n // Used by replaceSelections to allow moving the selection to the\n // start or around the replaced test. Hint may be \"start\" or \"around\".\n function computeReplacedSel(doc, changes, hint) {\n var out = [];\n var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;\n for (var i = 0; i < changes.length; i++) {\n var change = changes[i];\n var from = offsetPos(change.from, oldPrev, newPrev);\n var to = offsetPos(changeEnd(change), oldPrev, newPrev);\n oldPrev = change.to;\n newPrev = to;\n if (hint == \"around\") {\n var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;\n out[i] = new Range(inv ? to : from, inv ? from : to);\n } else {\n out[i] = new Range(from, from);\n }\n }\n return new Selection(out, doc.sel.primIndex);\n }\n\n // Allow \"beforeChange\" event handlers to influence a change\n function filterChange(doc, change, update) {\n var obj = {\n canceled: false,\n from: change.from,\n to: change.to,\n text: change.text,\n origin: change.origin,\n cancel: function() { this.canceled = true; }\n };\n if (update) obj.update = function(from, to, text, origin) {\n if (from) this.from = clipPos(doc, from);\n if (to) this.to = clipPos(doc, to);\n if (text) this.text = text;\n if (origin !== undefined) this.origin = origin;\n };\n signal(doc, \"beforeChange\", doc, obj);\n if (doc.cm) signal(doc.cm, \"beforeChange\", doc.cm, obj);\n\n if (obj.canceled) return null;\n return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};\n }\n\n // Apply a change to a document, and add it to the document's\n // history, and propagating it to all linked documents.\n function makeChange(doc, change, ignoreReadOnly) {\n if (doc.cm) {\n if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly);\n if (doc.cm.state.suppressEdits) return;\n }\n\n if (hasHandler(doc, \"beforeChange\") || doc.cm && hasHandler(doc.cm, \"beforeChange\")) {\n change = filterChange(doc, change, true);\n if (!change) return;\n }\n\n // Possibly split or suppress the update based on the presence\n // of read-only spans in its range.\n var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);\n if (split) {\n for (var i = split.length - 1; i >= 0; --i)\n makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [\"\"] : change.text});\n } else {\n makeChangeInner(doc, change);\n }\n }\n\n function makeChangeInner(doc, change) {\n if (change.text.length == 1 && change.text[0] == \"\" && cmp(change.from, change.to) == 0) return;\n var selAfter = computeSelAfterChange(doc, change);\n addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);\n\n makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));\n var rebased = [];\n\n linkedDocs(doc, function(doc, sharedHist) {\n if (!sharedHist && indexOf(rebased, doc.history) == -1) {\n rebaseHist(doc.history, change);\n rebased.push(doc.history);\n }\n makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));\n });\n }\n\n // Revert a change stored in a document's history.\n function makeChangeFromHistory(doc, type, allowSelectionOnly) {\n if (doc.cm && doc.cm.state.suppressEdits) return;\n\n var hist = doc.history, event, selAfter = doc.sel;\n var source = type == \"undo\" ? hist.done : hist.undone, dest = type == \"undo\" ? hist.undone : hist.done;\n\n // Verify that there is a useable event (so that ctrl-z won't\n // needlessly clear selection events)\n for (var i = 0; i < source.length; i++) {\n event = source[i];\n if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)\n break;\n }\n if (i == source.length) return;\n hist.lastOrigin = hist.lastSelOrigin = null;\n\n for (;;) {\n event = source.pop();\n if (event.ranges) {\n pushSelectionToHistory(event, dest);\n if (allowSelectionOnly && !event.equals(doc.sel)) {\n setSelection(doc, event, {clearRedo: false});\n return;\n }\n selAfter = event;\n }\n else break;\n }\n\n // Build up a reverse change object to add to the opposite history\n // stack (redo when undoing, and vice versa).\n var antiChanges = [];\n pushSelectionToHistory(selAfter, dest);\n dest.push({changes: antiChanges, generation: hist.generation});\n hist.generation = event.generation || ++hist.maxGeneration;\n\n var filter = hasHandler(doc, \"beforeChange\") || doc.cm && hasHandler(doc.cm, \"beforeChange\");\n\n for (var i = event.changes.length - 1; i >= 0; --i) {\n var change = event.changes[i];\n change.origin = type;\n if (filter && !filterChange(doc, change, false)) {\n source.length = 0;\n return;\n }\n\n antiChanges.push(historyChangeFromChange(doc, change));\n\n var after = i ? computeSelAfterChange(doc, change) : lst(source);\n makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));\n if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)});\n var rebased = [];\n\n // Propagate to the linked documents\n linkedDocs(doc, function(doc, sharedHist) {\n if (!sharedHist && indexOf(rebased, doc.history) == -1) {\n rebaseHist(doc.history, change);\n rebased.push(doc.history);\n }\n makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));\n });\n }\n }\n\n // Sub-views need their line numbers shifted when text is added\n // above or below them in the parent document.\n function shiftDoc(doc, distance) {\n if (distance == 0) return;\n doc.first += distance;\n doc.sel = new Selection(map(doc.sel.ranges, function(range) {\n return new Range(Pos(range.anchor.line + distance, range.anchor.ch),\n Pos(range.head.line + distance, range.head.ch));\n }), doc.sel.primIndex);\n if (doc.cm) {\n regChange(doc.cm, doc.first, doc.first - distance, distance);\n for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)\n regLineChange(doc.cm, l, \"gutter\");\n }\n }\n\n // More lower-level change function, handling only a single document\n // (not linked ones).\n function makeChangeSingleDoc(doc, change, selAfter, spans) {\n if (doc.cm && !doc.cm.curOp)\n return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);\n\n if (change.to.line < doc.first) {\n shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));\n return;\n }\n if (change.from.line > doc.lastLine()) return;\n\n // Clip the change to the size of this doc\n if (change.from.line < doc.first) {\n var shift = change.text.length - 1 - (doc.first - change.from.line);\n shiftDoc(doc, shift);\n change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),\n text: [lst(change.text)], origin: change.origin};\n }\n var last = doc.lastLine();\n if (change.to.line > last) {\n change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),\n text: [change.text[0]], origin: change.origin};\n }\n\n change.removed = getBetween(doc, change.from, change.to);\n\n if (!selAfter) selAfter = computeSelAfterChange(doc, change);\n if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans);\n else updateDoc(doc, change, spans);\n setSelectionNoUndo(doc, selAfter, sel_dontScroll);\n }\n\n // Handle the interaction of a change to a document with the editor\n // that this document is part of.\n function makeChangeSingleDocInEditor(cm, change, spans) {\n var doc = cm.doc, display = cm.display, from = change.from, to = change.to;\n\n var recomputeMaxLength = false, checkWidthStart = from.line;\n if (!cm.options.lineWrapping) {\n checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));\n doc.iter(checkWidthStart, to.line + 1, function(line) {\n if (line == display.maxLine) {\n recomputeMaxLength = true;\n return true;\n }\n });\n }\n\n if (doc.sel.contains(change.from, change.to) > -1)\n signalCursorActivity(cm);\n\n updateDoc(doc, change, spans, estimateHeight(cm));\n\n if (!cm.options.lineWrapping) {\n doc.iter(checkWidthStart, from.line + change.text.length, function(line) {\n var len = lineLength(line);\n if (len > display.maxLineLength) {\n display.maxLine = line;\n display.maxLineLength = len;\n display.maxLineChanged = true;\n recomputeMaxLength = false;\n }\n });\n if (recomputeMaxLength) cm.curOp.updateMaxLine = true;\n }\n\n // Adjust frontier, schedule worker\n doc.frontier = Math.min(doc.frontier, from.line);\n startWorker(cm, 400);\n\n var lendiff = change.text.length - (to.line - from.line) - 1;\n // Remember that these lines changed, for updating the display\n if (change.full)\n regChange(cm);\n else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))\n regLineChange(cm, from.line, \"text\");\n else\n regChange(cm, from.line, to.line + 1, lendiff);\n\n var changesHandler = hasHandler(cm, \"changes\"), changeHandler = hasHandler(cm, \"change\");\n if (changeHandler || changesHandler) {\n var obj = {\n from: from, to: to,\n text: change.text,\n removed: change.removed,\n origin: change.origin\n };\n if (changeHandler) signalLater(cm, \"change\", cm, obj);\n if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj);\n }\n cm.display.selForContextMenu = null;\n }\n\n function replaceRange(doc, code, from, to, origin) {\n if (!to) to = from;\n if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }\n if (typeof code == \"string\") code = splitLines(code);\n makeChange(doc, {from: from, to: to, text: code, origin: origin});\n }\n\n // SCROLLING THINGS INTO VIEW\n\n // If an editor sits on the top or bottom of the window, partially\n // scrolled out of view, this ensures that the cursor is visible.\n function maybeScrollWindow(cm, coords) {\n if (signalDOMEvent(cm, \"scrollCursorIntoView\")) return;\n\n var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;\n if (coords.top + box.top < 0) doScroll = true;\n else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;\n if (doScroll != null && !phantom) {\n var scrollNode = elt(\"div\", \"\\u200b\", null, \"position: absolute; top: \" +\n (coords.top - display.viewOffset - paddingTop(cm.display)) + \"px; height: \" +\n (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + \"px; left: \" +\n coords.left + \"px; width: 2px;\");\n cm.display.lineSpace.appendChild(scrollNode);\n scrollNode.scrollIntoView(doScroll);\n cm.display.lineSpace.removeChild(scrollNode);\n }\n }\n\n // Scroll a given position into view (immediately), verifying that\n // it actually became visible (as line heights are accurately\n // measured, the position of something may 'drift' during drawing).\n function scrollPosIntoView(cm, pos, end, margin) {\n if (margin == null) margin = 0;\n for (var limit = 0; limit < 5; limit++) {\n var changed = false, coords = cursorCoords(cm, pos);\n var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);\n var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),\n Math.min(coords.top, endCoords.top) - margin,\n Math.max(coords.left, endCoords.left),\n Math.max(coords.bottom, endCoords.bottom) + margin);\n var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;\n if (scrollPos.scrollTop != null) {\n setScrollTop(cm, scrollPos.scrollTop);\n if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;\n }\n if (scrollPos.scrollLeft != null) {\n setScrollLeft(cm, scrollPos.scrollLeft);\n if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;\n }\n if (!changed) break;\n }\n return coords;\n }\n\n // Scroll a given set of coordinates into view (immediately).\n function scrollIntoView(cm, x1, y1, x2, y2) {\n var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);\n if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);\n if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);\n }\n\n // Calculate a new scroll position needed to scroll the given\n // rectangle into view. Returns an object with scrollTop and\n // scrollLeft properties. When these are undefined, the\n // vertical/horizontal position does not need to be adjusted.\n function calculateScrollPos(cm, x1, y1, x2, y2) {\n var display = cm.display, snapMargin = textHeight(cm.display);\n if (y1 < 0) y1 = 0;\n var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;\n var screen = displayHeight(cm), result = {};\n if (y2 - y1 > screen) y2 = y1 + screen;\n var docBottom = cm.doc.height + paddingVert(display);\n var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;\n if (y1 < screentop) {\n result.scrollTop = atTop ? 0 : y1;\n } else if (y2 > screentop + screen) {\n var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);\n if (newTop != screentop) result.scrollTop = newTop;\n }\n\n var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;\n var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);\n var tooWide = x2 - x1 > screenw;\n if (tooWide) x2 = x1 + screenw;\n if (x1 < 10)\n result.scrollLeft = 0;\n else if (x1 < screenleft)\n result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));\n else if (x2 > screenw + screenleft - 3)\n result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw;\n return result;\n }\n\n // Store a relative adjustment to the scroll position in the current\n // operation (to be applied when the operation finishes).\n function addToScrollPos(cm, left, top) {\n if (left != null || top != null) resolveScrollToPos(cm);\n if (left != null)\n cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left;\n if (top != null)\n cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;\n }\n\n // Make sure that at the end of the operation the current cursor is\n // shown.\n function ensureCursorVisible(cm) {\n resolveScrollToPos(cm);\n var cur = cm.getCursor(), from = cur, to = cur;\n if (!cm.options.lineWrapping) {\n from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur;\n to = Pos(cur.line, cur.ch + 1);\n }\n cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true};\n }\n\n // When an operation has its scrollToPos property set, and another\n // scroll action is applied before the end of the operation, this\n // 'simulates' scrolling that position into view in a cheap way, so\n // that the effect of intermediate scroll commands is not ignored.\n function resolveScrollToPos(cm) {\n var range = cm.curOp.scrollToPos;\n if (range) {\n cm.curOp.scrollToPos = null;\n var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);\n var sPos = calculateScrollPos(cm, Math.min(from.left, to.left),\n Math.min(from.top, to.top) - range.margin,\n Math.max(from.right, to.right),\n Math.max(from.bottom, to.bottom) + range.margin);\n cm.scrollTo(sPos.scrollLeft, sPos.scrollTop);\n }\n }\n\n // API UTILITIES\n\n // Indent the given line. The how parameter can be \"smart\",\n // \"add\"/null, \"subtract\", or \"prev\". When aggressive is false\n // (typically set to true for forced single-line indents), empty\n // lines are not indented, and places where the mode returns Pass\n // are left alone.\n function indentLine(cm, n, how, aggressive) {\n var doc = cm.doc, state;\n if (how == null) how = \"add\";\n if (how == \"smart\") {\n // Fall back to \"prev\" when the mode doesn't have an indentation\n // method.\n if (!doc.mode.indent) how = \"prev\";\n else state = getStateBefore(cm, n);\n }\n\n var tabSize = cm.options.tabSize;\n var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);\n if (line.stateAfter) line.stateAfter = null;\n var curSpaceString = line.text.match(/^\\s*/)[0], indentation;\n if (!aggressive && !/\\S/.test(line.text)) {\n indentation = 0;\n how = \"not\";\n } else if (how == \"smart\") {\n indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);\n if (indentation == Pass || indentation > 150) {\n if (!aggressive) return;\n how = \"prev\";\n }\n }\n if (how == \"prev\") {\n if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);\n else indentation = 0;\n } else if (how == \"add\") {\n indentation = curSpace + cm.options.indentUnit;\n } else if (how == \"subtract\") {\n indentation = curSpace - cm.options.indentUnit;\n } else if (typeof how == \"number\") {\n indentation = curSpace + how;\n }\n indentation = Math.max(0, indentation);\n\n var indentString = \"\", pos = 0;\n if (cm.options.indentWithTabs)\n for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += \"\\t\";}\n if (pos < indentation) indentString += spaceStr(indentation - pos);\n\n if (indentString != curSpaceString) {\n replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), \"+input\");\n } else {\n // Ensure that, if the cursor was in the whitespace at the start\n // of the line, it is moved to the end of that space.\n for (var i = 0; i < doc.sel.ranges.length; i++) {\n var range = doc.sel.ranges[i];\n if (range.head.line == n && range.head.ch < curSpaceString.length) {\n var pos = Pos(n, curSpaceString.length);\n replaceOneSelection(doc, i, new Range(pos, pos));\n break;\n }\n }\n }\n line.stateAfter = null;\n }\n\n // Utility for applying a change to a line by handle or number,\n // returning the number and optionally registering the line as\n // changed.\n function changeLine(doc, handle, changeType, op) {\n var no = handle, line = handle;\n if (typeof handle == \"number\") line = getLine(doc, clipLine(doc, handle));\n else no = lineNo(handle);\n if (no == null) return null;\n if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType);\n return line;\n }\n\n // Helper for deleting text near the selection(s), used to implement\n // backspace, delete, and similar functionality.\n function deleteNearSelection(cm, compute) {\n var ranges = cm.doc.sel.ranges, kill = [];\n // Build up a set of ranges to kill first, merging overlapping\n // ranges.\n for (var i = 0; i < ranges.length; i++) {\n var toKill = compute(ranges[i]);\n while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {\n var replaced = kill.pop();\n if (cmp(replaced.from, toKill.from) < 0) {\n toKill.from = replaced.from;\n break;\n }\n }\n kill.push(toKill);\n }\n // Next, remove those actual ranges.\n runInOp(cm, function() {\n for (var i = kill.length - 1; i >= 0; i--)\n replaceRange(cm.doc, \"\", kill[i].from, kill[i].to, \"+delete\");\n ensureCursorVisible(cm);\n });\n }\n\n // Used for horizontal relative motion. Dir is -1 or 1 (left or\n // right), unit can be \"char\", \"column\" (like char, but doesn't\n // cross line boundaries), \"word\" (across next word), or \"group\" (to\n // the start of next group of word or non-word-non-whitespace\n // chars). The visually param controls whether, in right-to-left\n // text, direction 1 means to move towards the next index in the\n // string, or towards the character to the right of the current\n // position. The resulting position will have a hitSide=true\n // property if it reached the end of the document.\n function findPosH(doc, pos, dir, unit, visually) {\n var line = pos.line, ch = pos.ch, origDir = dir;\n var lineObj = getLine(doc, line);\n var possible = true;\n function findNextLine() {\n var l = line + dir;\n if (l < doc.first || l >= doc.first + doc.size) return (possible = false);\n line = l;\n return lineObj = getLine(doc, l);\n }\n function moveOnce(boundToLine) {\n var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);\n if (next == null) {\n if (!boundToLine && findNextLine()) {\n if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);\n else ch = dir < 0 ? lineObj.text.length : 0;\n } else return (possible = false);\n } else ch = next;\n return true;\n }\n\n if (unit == \"char\") moveOnce();\n else if (unit == \"column\") moveOnce(true);\n else if (unit == \"word\" || unit == \"group\") {\n var sawType = null, group = unit == \"group\";\n var helper = doc.cm && doc.cm.getHelper(pos, \"wordChars\");\n for (var first = true;; first = false) {\n if (dir < 0 && !moveOnce(!first)) break;\n var cur = lineObj.text.charAt(ch) || \"\\n\";\n var type = isWordChar(cur, helper) ? \"w\"\n : group && cur == \"\\n\" ? \"n\"\n : !group || /\\s/.test(cur) ? null\n : \"p\";\n if (group && !first && !type) type = \"s\";\n if (sawType && sawType != type) {\n if (dir < 0) {dir = 1; moveOnce();}\n break;\n }\n\n if (type) sawType = type;\n if (dir > 0 && !moveOnce(!first)) break;\n }\n }\n var result = skipAtomic(doc, Pos(line, ch), origDir, true);\n if (!possible) result.hitSide = true;\n return result;\n }\n\n // For relative vertical movement. Dir may be -1 or 1. Unit can be\n // \"page\" or \"line\". The resulting position will have a hitSide=true\n // property if it reached the end of the document.\n function findPosV(cm, pos, dir, unit) {\n var doc = cm.doc, x = pos.left, y;\n if (unit == \"page\") {\n var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);\n y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));\n } else if (unit == \"line\") {\n y = dir > 0 ? pos.bottom + 3 : pos.top - 3;\n }\n for (;;) {\n var target = coordsChar(cm, x, y);\n if (!target.outside) break;\n if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }\n y += dir * 5;\n }\n return target;\n }\n\n // EDITOR METHODS\n\n // The publicly visible API. Note that methodOp(f) means\n // 'wrap f in an operation, performed on its `this` parameter'.\n\n // This is not the complete set of editor methods. Most of the\n // methods defined on the Doc type are also injected into\n // CodeMirror.prototype, for backwards compatibility and\n // convenience.\n\n CodeMirror.prototype = {\n constructor: CodeMirror,\n focus: function(){window.focus(); focusInput(this); fastPoll(this);},\n\n setOption: function(option, value) {\n var options = this.options, old = options[option];\n if (options[option] == value && option != \"mode\") return;\n options[option] = value;\n if (optionHandlers.hasOwnProperty(option))\n operation(this, optionHandlers[option])(this, value, old);\n },\n\n getOption: function(option) {return this.options[option];},\n getDoc: function() {return this.doc;},\n\n addKeyMap: function(map, bottom) {\n this.state.keyMaps[bottom ? \"push\" : \"unshift\"](getKeyMap(map));\n },\n removeKeyMap: function(map) {\n var maps = this.state.keyMaps;\n for (var i = 0; i < maps.length; ++i)\n if (maps[i] == map || maps[i].name == map) {\n maps.splice(i, 1);\n return true;\n }\n },\n\n addOverlay: methodOp(function(spec, options) {\n var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);\n if (mode.startState) throw new Error(\"Overlays may not be stateful.\");\n this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});\n this.state.modeGen++;\n regChange(this);\n }),\n removeOverlay: methodOp(function(spec) {\n var overlays = this.state.overlays;\n for (var i = 0; i < overlays.length; ++i) {\n var cur = overlays[i].modeSpec;\n if (cur == spec || typeof spec == \"string\" && cur.name == spec) {\n overlays.splice(i, 1);\n this.state.modeGen++;\n regChange(this);\n return;\n }\n }\n }),\n\n indentLine: methodOp(function(n, dir, aggressive) {\n if (typeof dir != \"string\" && typeof dir != \"number\") {\n if (dir == null) dir = this.options.smartIndent ? \"smart\" : \"prev\";\n else dir = dir ? \"add\" : \"subtract\";\n }\n if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);\n }),\n indentSelection: methodOp(function(how) {\n var ranges = this.doc.sel.ranges, end = -1;\n for (var i = 0; i < ranges.length; i++) {\n var range = ranges[i];\n if (!range.empty()) {\n var from = range.from(), to = range.to();\n var start = Math.max(end, from.line);\n end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;\n for (var j = start; j < end; ++j)\n indentLine(this, j, how);\n var newRanges = this.doc.sel.ranges;\n if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)\n replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll);\n } else if (range.head.line > end) {\n indentLine(this, range.head.line, how, true);\n end = range.head.line;\n if (i == this.doc.sel.primIndex) ensureCursorVisible(this);\n }\n }\n }),\n\n // Fetch the parser token for a given character. Useful for hacks\n // that want to inspect the mode state (say, for completion).\n getTokenAt: function(pos, precise) {\n return takeToken(this, pos, precise);\n },\n\n getLineTokens: function(line, precise) {\n return takeToken(this, Pos(line), precise, true);\n },\n\n getTokenTypeAt: function(pos) {\n pos = clipPos(this.doc, pos);\n var styles = getLineStyles(this, getLine(this.doc, pos.line));\n var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;\n var type;\n if (ch == 0) type = styles[2];\n else for (;;) {\n var mid = (before + after) >> 1;\n if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;\n else if (styles[mid * 2 + 1] < ch) before = mid + 1;\n else { type = styles[mid * 2 + 2]; break; }\n }\n var cut = type ? type.indexOf(\"cm-overlay \") : -1;\n return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1);\n },\n\n getModeAt: function(pos) {\n var mode = this.doc.mode;\n if (!mode.innerMode) return mode;\n return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;\n },\n\n getHelper: function(pos, type) {\n return this.getHelpers(pos, type)[0];\n },\n\n getHelpers: function(pos, type) {\n var found = [];\n if (!helpers.hasOwnProperty(type)) return helpers;\n var help = helpers[type], mode = this.getModeAt(pos);\n if (typeof mode[type] == \"string\") {\n if (help[mode[type]]) found.push(help[mode[type]]);\n } else if (mode[type]) {\n for (var i = 0; i < mode[type].length; i++) {\n var val = help[mode[type][i]];\n if (val) found.push(val);\n }\n } else if (mode.helperType && help[mode.helperType]) {\n found.push(help[mode.helperType]);\n } else if (help[mode.name]) {\n found.push(help[mode.name]);\n }\n for (var i = 0; i < help._global.length; i++) {\n var cur = help._global[i];\n if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)\n found.push(cur.val);\n }\n return found;\n },\n\n getStateAfter: function(line, precise) {\n var doc = this.doc;\n line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);\n return getStateBefore(this, line + 1, precise);\n },\n\n cursorCoords: function(start, mode) {\n var pos, range = this.doc.sel.primary();\n if (start == null) pos = range.head;\n else if (typeof start == \"object\") pos = clipPos(this.doc, start);\n else pos = start ? range.from() : range.to();\n return cursorCoords(this, pos, mode || \"page\");\n },\n\n charCoords: function(pos, mode) {\n return charCoords(this, clipPos(this.doc, pos), mode || \"page\");\n },\n\n coordsChar: function(coords, mode) {\n coords = fromCoordSystem(this, coords, mode || \"page\");\n return coordsChar(this, coords.left, coords.top);\n },\n\n lineAtHeight: function(height, mode) {\n height = fromCoordSystem(this, {top: height, left: 0}, mode || \"page\").top;\n return lineAtHeight(this.doc, height + this.display.viewOffset);\n },\n heightAtLine: function(line, mode) {\n var end = false, last = this.doc.first + this.doc.size - 1;\n if (line < this.doc.first) line = this.doc.first;\n else if (line > last) { line = last; end = true; }\n var lineObj = getLine(this.doc, line);\n return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || \"page\").top +\n (end ? this.doc.height - heightAtLine(lineObj) : 0);\n },\n\n defaultTextHeight: function() { return textHeight(this.display); },\n defaultCharWidth: function() { return charWidth(this.display); },\n\n setGutterMarker: methodOp(function(line, gutterID, value) {\n return changeLine(this.doc, line, \"gutter\", function(line) {\n var markers = line.gutterMarkers || (line.gutterMarkers = {});\n markers[gutterID] = value;\n if (!value && isEmpty(markers)) line.gutterMarkers = null;\n return true;\n });\n }),\n\n clearGutter: methodOp(function(gutterID) {\n var cm = this, doc = cm.doc, i = doc.first;\n doc.iter(function(line) {\n if (line.gutterMarkers && line.gutterMarkers[gutterID]) {\n line.gutterMarkers[gutterID] = null;\n regLineChange(cm, i, \"gutter\");\n if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;\n }\n ++i;\n });\n }),\n\n addLineWidget: methodOp(function(handle, node, options) {\n return addLineWidget(this, handle, node, options);\n }),\n\n removeLineWidget: function(widget) { widget.clear(); },\n\n lineInfo: function(line) {\n if (typeof line == \"number\") {\n if (!isLine(this.doc, line)) return null;\n var n = line;\n line = getLine(this.doc, line);\n if (!line) return null;\n } else {\n var n = lineNo(line);\n if (n == null) return null;\n }\n return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,\n textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,\n widgets: line.widgets};\n },\n\n getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};},\n\n addWidget: function(pos, node, scroll, vert, horiz) {\n var display = this.display;\n pos = cursorCoords(this, clipPos(this.doc, pos));\n var top = pos.bottom, left = pos.left;\n node.style.position = \"absolute\";\n node.setAttribute(\"cm-ignore-events\", \"true\");\n display.sizer.appendChild(node);\n if (vert == \"over\") {\n top = pos.top;\n } else if (vert == \"above\" || vert == \"near\") {\n var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),\n hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);\n // Default to positioning above (if specified and possible); otherwise default to positioning below\n if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)\n top = pos.top - node.offsetHeight;\n else if (pos.bottom + node.offsetHeight <= vspace)\n top = pos.bottom;\n if (left + node.offsetWidth > hspace)\n left = hspace - node.offsetWidth;\n }\n node.style.top = top + \"px\";\n node.style.left = node.style.right = \"\";\n if (horiz == \"right\") {\n left = display.sizer.clientWidth - node.offsetWidth;\n node.style.right = \"0px\";\n } else {\n if (horiz == \"left\") left = 0;\n else if (horiz == \"middle\") left = (display.sizer.clientWidth - node.offsetWidth) / 2;\n node.style.left = left + \"px\";\n }\n if (scroll)\n scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);\n },\n\n triggerOnKeyDown: methodOp(onKeyDown),\n triggerOnKeyPress: methodOp(onKeyPress),\n triggerOnKeyUp: onKeyUp,\n\n execCommand: function(cmd) {\n if (commands.hasOwnProperty(cmd))\n return commands[cmd](this);\n },\n\n findPosH: function(from, amount, unit, visually) {\n var dir = 1;\n if (amount < 0) { dir = -1; amount = -amount; }\n for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {\n cur = findPosH(this.doc, cur, dir, unit, visually);\n if (cur.hitSide) break;\n }\n return cur;\n },\n\n moveH: methodOp(function(dir, unit) {\n var cm = this;\n cm.extendSelectionsBy(function(range) {\n if (cm.display.shift || cm.doc.extend || range.empty())\n return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually);\n else\n return dir < 0 ? range.from() : range.to();\n }, sel_move);\n }),\n\n deleteH: methodOp(function(dir, unit) {\n var sel = this.doc.sel, doc = this.doc;\n if (sel.somethingSelected())\n doc.replaceSelection(\"\", null, \"+delete\");\n else\n deleteNearSelection(this, function(range) {\n var other = findPosH(doc, range.head, dir, unit, false);\n return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};\n });\n }),\n\n findPosV: function(from, amount, unit, goalColumn) {\n var dir = 1, x = goalColumn;\n if (amount < 0) { dir = -1; amount = -amount; }\n for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {\n var coords = cursorCoords(this, cur, \"div\");\n if (x == null) x = coords.left;\n else coords.left = x;\n cur = findPosV(this, coords, dir, unit);\n if (cur.hitSide) break;\n }\n return cur;\n },\n\n moveV: methodOp(function(dir, unit) {\n var cm = this, doc = this.doc, goals = [];\n var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected();\n doc.extendSelectionsBy(function(range) {\n if (collapse)\n return dir < 0 ? range.from() : range.to();\n var headPos = cursorCoords(cm, range.head, \"div\");\n if (range.goalColumn != null) headPos.left = range.goalColumn;\n goals.push(headPos.left);\n var pos = findPosV(cm, headPos, dir, unit);\n if (unit == \"page\" && range == doc.sel.primary())\n addToScrollPos(cm, null, charCoords(cm, pos, \"div\").top - headPos.top);\n return pos;\n }, sel_move);\n if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++)\n doc.sel.ranges[i].goalColumn = goals[i];\n }),\n\n // Find the word at the given position (as returned by coordsChar).\n findWordAt: function(pos) {\n var doc = this.doc, line = getLine(doc, pos.line).text;\n var start = pos.ch, end = pos.ch;\n if (line) {\n var helper = this.getHelper(pos, \"wordChars\");\n if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;\n var startChar = line.charAt(start);\n var check = isWordChar(startChar, helper)\n ? function(ch) { return isWordChar(ch, helper); }\n : /\\s/.test(startChar) ? function(ch) {return /\\s/.test(ch);}\n : function(ch) {return !/\\s/.test(ch) && !isWordChar(ch);};\n while (start > 0 && check(line.charAt(start - 1))) --start;\n while (end < line.length && check(line.charAt(end))) ++end;\n }\n return new Range(Pos(pos.line, start), Pos(pos.line, end));\n },\n\n toggleOverwrite: function(value) {\n if (value != null && value == this.state.overwrite) return;\n if (this.state.overwrite = !this.state.overwrite)\n addClass(this.display.cursorDiv, \"CodeMirror-overwrite\");\n else\n rmClass(this.display.cursorDiv, \"CodeMirror-overwrite\");\n\n signal(this, \"overwriteToggle\", this, this.state.overwrite);\n },\n hasFocus: function() { return activeElt() == this.display.input; },\n\n scrollTo: methodOp(function(x, y) {\n if (x != null || y != null) resolveScrollToPos(this);\n if (x != null) this.curOp.scrollLeft = x;\n if (y != null) this.curOp.scrollTop = y;\n }),\n getScrollInfo: function() {\n var scroller = this.display.scroller;\n return {left: scroller.scrollLeft, top: scroller.scrollTop,\n height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,\n width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,\n clientHeight: displayHeight(this), clientWidth: displayWidth(this)};\n },\n\n scrollIntoView: methodOp(function(range, margin) {\n if (range == null) {\n range = {from: this.doc.sel.primary().head, to: null};\n if (margin == null) margin = this.options.cursorScrollMargin;\n } else if (typeof range == \"number\") {\n range = {from: Pos(range, 0), to: null};\n } else if (range.from == null) {\n range = {from: range, to: null};\n }\n if (!range.to) range.to = range.from;\n range.margin = margin || 0;\n\n if (range.from.line != null) {\n resolveScrollToPos(this);\n this.curOp.scrollToPos = range;\n } else {\n var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left),\n Math.min(range.from.top, range.to.top) - range.margin,\n Math.max(range.from.right, range.to.right),\n Math.max(range.from.bottom, range.to.bottom) + range.margin);\n this.scrollTo(sPos.scrollLeft, sPos.scrollTop);\n }\n }),\n\n setSize: methodOp(function(width, height) {\n var cm = this;\n function interpret(val) {\n return typeof val == \"number\" || /^\\d+$/.test(String(val)) ? val + \"px\" : val;\n }\n if (width != null) cm.display.wrapper.style.width = interpret(width);\n if (height != null) cm.display.wrapper.style.height = interpret(height);\n if (cm.options.lineWrapping) clearLineMeasurementCache(this);\n var lineNo = cm.display.viewFrom;\n cm.doc.iter(lineNo, cm.display.viewTo, function(line) {\n if (line.widgets) for (var i = 0; i < line.widgets.length; i++)\n if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, \"widget\"); break; }\n ++lineNo;\n });\n cm.curOp.forceUpdate = true;\n signal(cm, \"refresh\", this);\n }),\n\n operation: function(f){return runInOp(this, f);},\n\n refresh: methodOp(function() {\n var oldHeight = this.display.cachedTextHeight;\n regChange(this);\n this.curOp.forceUpdate = true;\n clearCaches(this);\n this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop);\n updateGutterSpace(this);\n if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)\n estimateLineHeights(this);\n signal(this, \"refresh\", this);\n }),\n\n swapDoc: methodOp(function(doc) {\n var old = this.doc;\n old.cm = null;\n attachDoc(this, doc);\n clearCaches(this);\n resetInput(this);\n this.scrollTo(doc.scrollLeft, doc.scrollTop);\n this.curOp.forceScroll = true;\n signalLater(this, \"swapDoc\", this, old);\n return old;\n }),\n\n getInputField: function(){return this.display.input;},\n getWrapperElement: function(){return this.display.wrapper;},\n getScrollerElement: function(){return this.display.scroller;},\n getGutterElement: function(){return this.display.gutters;}\n };\n eventMixin(CodeMirror);\n\n // OPTION DEFAULTS\n\n // The default configuration options.\n var defaults = CodeMirror.defaults = {};\n // Functions to run when options are changed.\n var optionHandlers = CodeMirror.optionHandlers = {};\n\n function option(name, deflt, handle, notOnInit) {\n CodeMirror.defaults[name] = deflt;\n if (handle) optionHandlers[name] =\n notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;\n }\n\n // Passed to option handlers when there is no old value.\n var Init = CodeMirror.Init = {toString: function(){return \"CodeMirror.Init\";}};\n\n // These two are, on init, called from the constructor because they\n // have to be initialized before the editor can start at all.\n option(\"value\", \"\", function(cm, val) {\n cm.setValue(val);\n }, true);\n option(\"mode\", null, function(cm, val) {\n cm.doc.modeOption = val;\n loadMode(cm);\n }, true);\n\n option(\"indentUnit\", 2, loadMode, true);\n option(\"indentWithTabs\", false);\n option(\"smartIndent\", true);\n option(\"tabSize\", 4, function(cm) {\n resetModeState(cm);\n clearCaches(cm);\n regChange(cm);\n }, true);\n option(\"specialChars\", /[\\t\\u0000-\\u0019\\u00ad\\u200b-\\u200f\\u2028\\u2029\\ufeff]/g, function(cm, val) {\n cm.options.specialChars = new RegExp(val.source + (val.test(\"\\t\") ? \"\" : \"|\\t\"), \"g\");\n cm.refresh();\n }, true);\n option(\"specialCharPlaceholder\", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);\n option(\"electricChars\", true);\n option(\"rtlMoveVisually\", !windows);\n option(\"wholeLineUpdateBefore\", true);\n\n option(\"theme\", \"default\", function(cm) {\n themeChanged(cm);\n guttersChanged(cm);\n }, true);\n option(\"keyMap\", \"default\", function(cm, val, old) {\n var next = getKeyMap(val);\n var prev = old != CodeMirror.Init && getKeyMap(old);\n if (prev && prev.detach) prev.detach(cm, next);\n if (next.attach) next.attach(cm, prev || null);\n });\n option(\"extraKeys\", null);\n\n option(\"lineWrapping\", false, wrappingChanged, true);\n option(\"gutters\", [], function(cm) {\n setGuttersForLineNumbers(cm.options);\n guttersChanged(cm);\n }, true);\n option(\"fixedGutter\", true, function(cm, val) {\n cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + \"px\" : \"0\";\n cm.refresh();\n }, true);\n option(\"coverGutterNextToScrollbar\", false, function(cm) {updateScrollbars(cm);}, true);\n option(\"scrollbarStyle\", \"native\", function(cm) {\n initScrollbars(cm);\n updateScrollbars(cm);\n cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);\n cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);\n }, true);\n option(\"lineNumbers\", false, function(cm) {\n setGuttersForLineNumbers(cm.options);\n guttersChanged(cm);\n }, true);\n option(\"firstLineNumber\", 1, guttersChanged, true);\n option(\"lineNumberFormatter\", function(integer) {return integer;}, guttersChanged, true);\n option(\"showCursorWhenSelecting\", false, updateSelection, true);\n\n option(\"resetSelectionOnContextMenu\", true);\n\n option(\"readOnly\", false, function(cm, val) {\n if (val == \"nocursor\") {\n onBlur(cm);\n cm.display.input.blur();\n cm.display.disabled = true;\n } else {\n cm.display.disabled = false;\n if (!val) resetInput(cm);\n }\n });\n option(\"disableInput\", false, function(cm, val) {if (!val) resetInput(cm);}, true);\n option(\"dragDrop\", true);\n\n option(\"cursorBlinkRate\", 530);\n option(\"cursorScrollMargin\", 0);\n option(\"cursorHeight\", 1, updateSelection, true);\n option(\"singleCursorHeightPerLine\", true, updateSelection, true);\n option(\"workTime\", 100);\n option(\"workDelay\", 100);\n option(\"flattenSpans\", true, resetModeState, true);\n option(\"addModeClass\", false, resetModeState, true);\n option(\"pollInterval\", 100);\n option(\"undoDepth\", 200, function(cm, val){cm.doc.history.undoDepth = val;});\n option(\"historyEventDelay\", 1250);\n option(\"viewportMargin\", 10, function(cm){cm.refresh();}, true);\n option(\"maxHighlightLength\", 10000, resetModeState, true);\n option(\"moveInputWithCursor\", true, function(cm, val) {\n if (!val) cm.display.inputDiv.style.top = cm.display.inputDiv.style.left = 0;\n });\n\n option(\"tabindex\", null, function(cm, val) {\n cm.display.input.tabIndex = val || \"\";\n });\n option(\"autofocus\", null);\n\n // MODE DEFINITION AND QUERYING\n\n // Known modes, by name and by MIME\n var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};\n\n // Extra arguments are stored as the mode's dependencies, which is\n // used by (legacy) mechanisms like loadmode.js to automatically\n // load a mode. (Preferred mechanism is the require/define calls.)\n CodeMirror.defineMode = function(name, mode) {\n if (!CodeMirror.defaults.mode && name != \"null\") CodeMirror.defaults.mode = name;\n if (arguments.length > 2)\n mode.dependencies = Array.prototype.slice.call(arguments, 2);\n modes[name] = mode;\n };\n\n CodeMirror.defineMIME = function(mime, spec) {\n mimeModes[mime] = spec;\n };\n\n // Given a MIME type, a {name, ...options} config object, or a name\n // string, return a mode config object.\n CodeMirror.resolveMode = function(spec) {\n if (typeof spec == \"string\" && mimeModes.hasOwnProperty(spec)) {\n spec = mimeModes[spec];\n } else if (spec && typeof spec.name == \"string\" && mimeModes.hasOwnProperty(spec.name)) {\n var found = mimeModes[spec.name];\n if (typeof found == \"string\") found = {name: found};\n spec = createObj(found, spec);\n spec.name = found.name;\n } else if (typeof spec == \"string\" && /^[\\w\\-]+\\/[\\w\\-]+\\+xml$/.test(spec)) {\n return CodeMirror.resolveMode(\"application/xml\");\n }\n if (typeof spec == \"string\") return {name: spec};\n else return spec || {name: \"null\"};\n };\n\n // Given a mode spec (anything that resolveMode accepts), find and\n // initialize an actual mode object.\n CodeMirror.getMode = function(options, spec) {\n var spec = CodeMirror.resolveMode(spec);\n var mfactory = modes[spec.name];\n if (!mfactory) return CodeMirror.getMode(options, \"text/plain\");\n var modeObj = mfactory(options, spec);\n if (modeExtensions.hasOwnProperty(spec.name)) {\n var exts = modeExtensions[spec.name];\n for (var prop in exts) {\n if (!exts.hasOwnProperty(prop)) continue;\n if (modeObj.hasOwnProperty(prop)) modeObj[\"_\" + prop] = modeObj[prop];\n modeObj[prop] = exts[prop];\n }\n }\n modeObj.name = spec.name;\n if (spec.helperType) modeObj.helperType = spec.helperType;\n if (spec.modeProps) for (var prop in spec.modeProps)\n modeObj[prop] = spec.modeProps[prop];\n\n return modeObj;\n };\n\n // Minimal default mode.\n CodeMirror.defineMode(\"null\", function() {\n return {token: function(stream) {stream.skipToEnd();}};\n });\n CodeMirror.defineMIME(\"text/plain\", \"null\");\n\n // This can be used to attach properties to mode objects from\n // outside the actual mode definition.\n var modeExtensions = CodeMirror.modeExtensions = {};\n CodeMirror.extendMode = function(mode, properties) {\n var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});\n copyObj(properties, exts);\n };\n\n // EXTENSIONS\n\n CodeMirror.defineExtension = function(name, func) {\n CodeMirror.prototype[name] = func;\n };\n CodeMirror.defineDocExtension = function(name, func) {\n Doc.prototype[name] = func;\n };\n CodeMirror.defineOption = option;\n\n var initHooks = [];\n CodeMirror.defineInitHook = function(f) {initHooks.push(f);};\n\n var helpers = CodeMirror.helpers = {};\n CodeMirror.registerHelper = function(type, name, value) {\n if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};\n helpers[type][name] = value;\n };\n CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {\n CodeMirror.registerHelper(type, name, value);\n helpers[type]._global.push({pred: predicate, val: value});\n };\n\n // MODE STATE HANDLING\n\n // Utility functions for working with state. Exported because nested\n // modes need to do this for their inner modes.\n\n var copyState = CodeMirror.copyState = function(mode, state) {\n if (state === true) return state;\n if (mode.copyState) return mode.copyState(state);\n var nstate = {};\n for (var n in state) {\n var val = state[n];\n if (val instanceof Array) val = val.concat([]);\n nstate[n] = val;\n }\n return nstate;\n };\n\n var startState = CodeMirror.startState = function(mode, a1, a2) {\n return mode.startState ? mode.startState(a1, a2) : true;\n };\n\n // Given a mode and a state (for that mode), find the inner mode and\n // state at the position that the state refers to.\n CodeMirror.innerMode = function(mode, state) {\n while (mode.innerMode) {\n var info = mode.innerMode(state);\n if (!info || info.mode == mode) break;\n state = info.state;\n mode = info.mode;\n }\n return info || {mode: mode, state: state};\n };\n\n // STANDARD COMMANDS\n\n // Commands are parameter-less actions that can be performed on an\n // editor, mostly used for keybindings.\n var commands = CodeMirror.commands = {\n selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);},\n singleSelection: function(cm) {\n cm.setSelection(cm.getCursor(\"anchor\"), cm.getCursor(\"head\"), sel_dontScroll);\n },\n killLine: function(cm) {\n deleteNearSelection(cm, function(range) {\n if (range.empty()) {\n var len = getLine(cm.doc, range.head.line).text.length;\n if (range.head.ch == len && range.head.line < cm.lastLine())\n return {from: range.head, to: Pos(range.head.line + 1, 0)};\n else\n return {from: range.head, to: Pos(range.head.line, len)};\n } else {\n return {from: range.from(), to: range.to()};\n }\n });\n },\n deleteLine: function(cm) {\n deleteNearSelection(cm, function(range) {\n return {from: Pos(range.from().line, 0),\n to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};\n });\n },\n delLineLeft: function(cm) {\n deleteNearSelection(cm, function(range) {\n return {from: Pos(range.from().line, 0), to: range.from()};\n });\n },\n delWrappedLineLeft: function(cm) {\n deleteNearSelection(cm, function(range) {\n var top = cm.charCoords(range.head, \"div\").top + 5;\n var leftPos = cm.coordsChar({left: 0, top: top}, \"div\");\n return {from: leftPos, to: range.from()};\n });\n },\n delWrappedLineRight: function(cm) {\n deleteNearSelection(cm, function(range) {\n var top = cm.charCoords(range.head, \"div\").top + 5;\n var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, \"div\");\n return {from: range.from(), to: rightPos };\n });\n },\n undo: function(cm) {cm.undo();},\n redo: function(cm) {cm.redo();},\n undoSelection: function(cm) {cm.undoSelection();},\n redoSelection: function(cm) {cm.redoSelection();},\n goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},\n goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},\n goLineStart: function(cm) {\n cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); },\n {origin: \"+move\", bias: 1});\n },\n goLineStartSmart: function(cm) {\n cm.extendSelectionsBy(function(range) {\n return lineStartSmart(cm, range.head);\n }, {origin: \"+move\", bias: 1});\n },\n goLineEnd: function(cm) {\n cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); },\n {origin: \"+move\", bias: -1});\n },\n goLineRight: function(cm) {\n cm.extendSelectionsBy(function(range) {\n var top = cm.charCoords(range.head, \"div\").top + 5;\n return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, \"div\");\n }, sel_move);\n },\n goLineLeft: function(cm) {\n cm.extendSelectionsBy(function(range) {\n var top = cm.charCoords(range.head, \"div\").top + 5;\n return cm.coordsChar({left: 0, top: top}, \"div\");\n }, sel_move);\n },\n goLineLeftSmart: function(cm) {\n cm.extendSelectionsBy(function(range) {\n var top = cm.charCoords(range.head, \"div\").top + 5;\n var pos = cm.coordsChar({left: 0, top: top}, \"div\");\n if (pos.ch < cm.getLine(pos.line).search(/\\S/)) return lineStartSmart(cm, range.head);\n return pos;\n }, sel_move);\n },\n goLineUp: function(cm) {cm.moveV(-1, \"line\");},\n goLineDown: function(cm) {cm.moveV(1, \"line\");},\n goPageUp: function(cm) {cm.moveV(-1, \"page\");},\n goPageDown: function(cm) {cm.moveV(1, \"page\");},\n goCharLeft: function(cm) {cm.moveH(-1, \"char\");},\n goCharRight: function(cm) {cm.moveH(1, \"char\");},\n goColumnLeft: function(cm) {cm.moveH(-1, \"column\");},\n goColumnRight: function(cm) {cm.moveH(1, \"column\");},\n goWordLeft: function(cm) {cm.moveH(-1, \"word\");},\n goGroupRight: function(cm) {cm.moveH(1, \"group\");},\n goGroupLeft: function(cm) {cm.moveH(-1, \"group\");},\n goWordRight: function(cm) {cm.moveH(1, \"word\");},\n delCharBefore: function(cm) {cm.deleteH(-1, \"char\");},\n delCharAfter: function(cm) {cm.deleteH(1, \"char\");},\n delWordBefore: function(cm) {cm.deleteH(-1, \"word\");},\n delWordAfter: function(cm) {cm.deleteH(1, \"word\");},\n delGroupBefore: function(cm) {cm.deleteH(-1, \"group\");},\n delGroupAfter: function(cm) {cm.deleteH(1, \"group\");},\n indentAuto: function(cm) {cm.indentSelection(\"smart\");},\n indentMore: function(cm) {cm.indentSelection(\"add\");},\n indentLess: function(cm) {cm.indentSelection(\"subtract\");},\n insertTab: function(cm) {cm.replaceSelection(\"\\t\");},\n insertSoftTab: function(cm) {\n var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;\n for (var i = 0; i < ranges.length; i++) {\n var pos = ranges[i].from();\n var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);\n spaces.push(new Array(tabSize - col % tabSize + 1).join(\" \"));\n }\n cm.replaceSelections(spaces);\n },\n defaultTab: function(cm) {\n if (cm.somethingSelected()) cm.indentSelection(\"add\");\n else cm.execCommand(\"insertTab\");\n },\n transposeChars: function(cm) {\n runInOp(cm, function() {\n var ranges = cm.listSelections(), newSel = [];\n for (var i = 0; i < ranges.length; i++) {\n var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;\n if (line) {\n if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);\n if (cur.ch > 0) {\n cur = new Pos(cur.line, cur.ch + 1);\n cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),\n Pos(cur.line, cur.ch - 2), cur, \"+transpose\");\n } else if (cur.line > cm.doc.first) {\n var prev = getLine(cm.doc, cur.line - 1).text;\n if (prev)\n cm.replaceRange(line.charAt(0) + \"\\n\" + prev.charAt(prev.length - 1),\n Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), \"+transpose\");\n }\n }\n newSel.push(new Range(cur, cur));\n }\n cm.setSelections(newSel);\n });\n },\n newlineAndIndent: function(cm) {\n runInOp(cm, function() {\n var len = cm.listSelections().length;\n for (var i = 0; i < len; i++) {\n var range = cm.listSelections()[i];\n cm.replaceRange(\"\\n\", range.anchor, range.head, \"+input\");\n cm.indentLine(range.from().line + 1, null, true);\n ensureCursorVisible(cm);\n }\n });\n },\n toggleOverwrite: function(cm) {cm.toggleOverwrite();}\n };\n\n\n // STANDARD KEYMAPS\n\n var keyMap = CodeMirror.keyMap = {};\n\n keyMap.basic = {\n \"Left\": \"goCharLeft\", \"Right\": \"goCharRight\", \"Up\": \"goLineUp\", \"Down\": \"goLineDown\",\n \"End\": \"goLineEnd\", \"Home\": \"goLineStartSmart\", \"PageUp\": \"goPageUp\", \"PageDown\": \"goPageDown\",\n \"Delete\": \"delCharAfter\", \"Backspace\": \"delCharBefore\", \"Shift-Backspace\": \"delCharBefore\",\n \"Tab\": \"defaultTab\", \"Shift-Tab\": \"indentAuto\",\n \"Enter\": \"newlineAndIndent\", \"Insert\": \"toggleOverwrite\",\n \"Esc\": \"singleSelection\"\n };\n // Note that the save and find-related commands aren't defined by\n // default. User code or addons can define them. Unknown commands\n // are simply ignored.\n keyMap.pcDefault = {\n \"Ctrl-A\": \"selectAll\", \"Ctrl-D\": \"deleteLine\", \"Ctrl-Z\": \"undo\", \"Shift-Ctrl-Z\": \"redo\", \"Ctrl-Y\": \"redo\",\n \"Ctrl-Home\": \"goDocStart\", \"Ctrl-End\": \"goDocEnd\", \"Ctrl-Up\": \"goLineUp\", \"Ctrl-Down\": \"goLineDown\",\n \"Ctrl-Left\": \"goGroupLeft\", \"Ctrl-Right\": \"goGroupRight\", \"Alt-Left\": \"goLineStart\", \"Alt-Right\": \"goLineEnd\",\n \"Ctrl-Backspace\": \"delGroupBefore\", \"Ctrl-Delete\": \"delGroupAfter\", \"Ctrl-S\": \"save\", \"Ctrl-F\": \"find\",\n \"Ctrl-G\": \"findNext\", \"Shift-Ctrl-G\": \"findPrev\", \"Shift-Ctrl-F\": \"replace\", \"Shift-Ctrl-R\": \"replaceAll\",\n \"Ctrl-[\": \"indentLess\", \"Ctrl-]\": \"indentMore\",\n \"Ctrl-U\": \"undoSelection\", \"Shift-Ctrl-U\": \"redoSelection\", \"Alt-U\": \"redoSelection\",\n fallthrough: \"basic\"\n };\n // Very basic readline/emacs-style bindings, which are standard on Mac.\n keyMap.emacsy = {\n \"Ctrl-F\": \"goCharRight\", \"Ctrl-B\": \"goCharLeft\", \"Ctrl-P\": \"goLineUp\", \"Ctrl-N\": \"goLineDown\",\n \"Alt-F\": \"goWordRight\", \"Alt-B\": \"goWordLeft\", \"Ctrl-A\": \"goLineStart\", \"Ctrl-E\": \"goLineEnd\",\n \"Ctrl-V\": \"goPageDown\", \"Shift-Ctrl-V\": \"goPageUp\", \"Ctrl-D\": \"delCharAfter\", \"Ctrl-H\": \"delCharBefore\",\n \"Alt-D\": \"delWordAfter\", \"Alt-Backspace\": \"delWordBefore\", \"Ctrl-K\": \"killLine\", \"Ctrl-T\": \"transposeChars\"\n };\n keyMap.macDefault = {\n \"Cmd-A\": \"selectAll\", \"Cmd-D\": \"deleteLine\", \"Cmd-Z\": \"undo\", \"Shift-Cmd-Z\": \"redo\", \"Cmd-Y\": \"redo\",\n \"Cmd-Home\": \"goDocStart\", \"Cmd-Up\": \"goDocStart\", \"Cmd-End\": \"goDocEnd\", \"Cmd-Down\": \"goDocEnd\", \"Alt-Left\": \"goGroupLeft\",\n \"Alt-Right\": \"goGroupRight\", \"Cmd-Left\": \"goLineLeft\", \"Cmd-Right\": \"goLineRight\", \"Alt-Backspace\": \"delGroupBefore\",\n \"Ctrl-Alt-Backspace\": \"delGroupAfter\", \"Alt-Delete\": \"delGroupAfter\", \"Cmd-S\": \"save\", \"Cmd-F\": \"find\",\n \"Cmd-G\": \"findNext\", \"Shift-Cmd-G\": \"findPrev\", \"Cmd-Alt-F\": \"replace\", \"Shift-Cmd-Alt-F\": \"replaceAll\",\n \"Cmd-[\": \"indentLess\", \"Cmd-]\": \"indentMore\", \"Cmd-Backspace\": \"delWrappedLineLeft\", \"Cmd-Delete\": \"delWrappedLineRight\",\n \"Cmd-U\": \"undoSelection\", \"Shift-Cmd-U\": \"redoSelection\", \"Ctrl-Up\": \"goDocStart\", \"Ctrl-Down\": \"goDocEnd\",\n fallthrough: [\"basic\", \"emacsy\"]\n };\n keyMap[\"default\"] = mac ? keyMap.macDefault : keyMap.pcDefault;\n\n // KEYMAP DISPATCH\n\n function normalizeKeyName(name) {\n var parts = name.split(/-(?!$)/), name = parts[parts.length - 1];\n var alt, ctrl, shift, cmd;\n for (var i = 0; i < parts.length - 1; i++) {\n var mod = parts[i];\n if (/^(cmd|meta|m)$/i.test(mod)) cmd = true;\n else if (/^a(lt)?$/i.test(mod)) alt = true;\n else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;\n else if (/^s(hift)$/i.test(mod)) shift = true;\n else throw new Error(\"Unrecognized modifier name: \" + mod);\n }\n if (alt) name = \"Alt-\" + name;\n if (ctrl) name = \"Ctrl-\" + name;\n if (cmd) name = \"Cmd-\" + name;\n if (shift) name = \"Shift-\" + name;\n return name;\n }\n\n // This is a kludge to keep keymaps mostly working as raw objects\n // (backwards compatibility) while at the same time support features\n // like normalization and multi-stroke key bindings. It compiles a\n // new normalized keymap, and then updates the old object to reflect\n // this.\n CodeMirror.normalizeKeyMap = function(keymap) {\n var copy = {};\n for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) {\n var value = keymap[keyname];\n if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue;\n if (value == \"...\") { delete keymap[keyname]; continue; }\n\n var keys = map(keyname.split(\" \"), normalizeKeyName);\n for (var i = 0; i < keys.length; i++) {\n var val, name;\n if (i == keys.length - 1) {\n name = keyname;\n val = value;\n } else {\n name = keys.slice(0, i + 1).join(\" \");\n val = \"...\";\n }\n var prev = copy[name];\n if (!prev) copy[name] = val;\n else if (prev != val) throw new Error(\"Inconsistent bindings for \" + name);\n }\n delete keymap[keyname];\n }\n for (var prop in copy) keymap[prop] = copy[prop];\n return keymap;\n };\n\n var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) {\n map = getKeyMap(map);\n var found = map.call ? map.call(key, context) : map[key];\n if (found === false) return \"nothing\";\n if (found === \"...\") return \"multi\";\n if (found != null && handle(found)) return \"handled\";\n\n if (map.fallthrough) {\n if (Object.prototype.toString.call(map.fallthrough) != \"[object Array]\")\n return lookupKey(key, map.fallthrough, handle, context);\n for (var i = 0; i < map.fallthrough.length; i++) {\n var result = lookupKey(key, map.fallthrough[i], handle, context);\n if (result) return result;\n }\n }\n };\n\n // Modifier key presses don't count as 'real' key presses for the\n // purpose of keymap fallthrough.\n var isModifierKey = CodeMirror.isModifierKey = function(value) {\n var name = typeof value == \"string\" ? value : keyNames[value.keyCode];\n return name == \"Ctrl\" || name == \"Alt\" || name == \"Shift\" || name == \"Mod\";\n };\n\n // Look up the name of a key as indicated by an event object.\n var keyName = CodeMirror.keyName = function(event, noShift) {\n if (presto && event.keyCode == 34 && event[\"char\"]) return false;\n var base = keyNames[event.keyCode], name = base;\n if (name == null || event.altGraphKey) return false;\n if (event.altKey && base != \"Alt\") name = \"Alt-\" + name;\n if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != \"Ctrl\") name = \"Ctrl-\" + name;\n if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != \"Cmd\") name = \"Cmd-\" + name;\n if (!noShift && event.shiftKey && base != \"Shift\") name = \"Shift-\" + name;\n return name;\n };\n\n function getKeyMap(val) {\n return typeof val == \"string\" ? keyMap[val] : val;\n }\n\n // FROMTEXTAREA\n\n CodeMirror.fromTextArea = function(textarea, options) {\n if (!options) options = {};\n options.value = textarea.value;\n if (!options.tabindex && textarea.tabindex)\n options.tabindex = textarea.tabindex;\n if (!options.placeholder && textarea.placeholder)\n options.placeholder = textarea.placeholder;\n // Set autofocus to true if this textarea is focused, or if it has\n // autofocus and no other element is focused.\n if (options.autofocus == null) {\n var hasFocus = activeElt();\n options.autofocus = hasFocus == textarea ||\n textarea.getAttribute(\"autofocus\") != null && hasFocus == document.body;\n }\n\n function save() {textarea.value = cm.getValue();}\n if (textarea.form) {\n on(textarea.form, \"submit\", save);\n // Deplorable hack to make the submit method do the right thing.\n if (!options.leaveSubmitMethodAlone) {\n var form = textarea.form, realSubmit = form.submit;\n try {\n var wrappedSubmit = form.submit = function() {\n save();\n form.submit = realSubmit;\n form.submit();\n form.submit = wrappedSubmit;\n };\n } catch(e) {}\n }\n }\n\n textarea.style.display = \"none\";\n var cm = CodeMirror(function(node) {\n textarea.parentNode.insertBefore(node, textarea.nextSibling);\n }, options);\n cm.save = save;\n cm.getTextArea = function() { return textarea; };\n cm.toTextArea = function() {\n cm.toTextArea = isNaN; // Prevent this from being ran twice\n save();\n textarea.parentNode.removeChild(cm.getWrapperElement());\n textarea.style.display = \"\";\n if (textarea.form) {\n off(textarea.form, \"submit\", save);\n if (typeof textarea.form.submit == \"function\")\n textarea.form.submit = realSubmit;\n }\n };\n return cm;\n };\n\n // STRING STREAM\n\n // Fed to the mode parsers, provides helper functions to make\n // parsers more succinct.\n\n var StringStream = CodeMirror.StringStream = function(string, tabSize) {\n this.pos = this.start = 0;\n this.string = string;\n this.tabSize = tabSize || 8;\n this.lastColumnPos = this.lastColumnValue = 0;\n this.lineStart = 0;\n };\n\n StringStream.prototype = {\n eol: function() {return this.pos >= this.string.length;},\n sol: function() {return this.pos == this.lineStart;},\n peek: function() {return this.string.charAt(this.pos) || undefined;},\n next: function() {\n if (this.pos < this.string.length)\n return this.string.charAt(this.pos++);\n },\n eat: function(match) {\n var ch = this.string.charAt(this.pos);\n if (typeof match == \"string\") var ok = ch == match;\n else var ok = ch && (match.test ? match.test(ch) : match(ch));\n if (ok) {++this.pos; return ch;}\n },\n eatWhile: function(match) {\n var start = this.pos;\n while (this.eat(match)){}\n return this.pos > start;\n },\n eatSpace: function() {\n var start = this.pos;\n while (/[\\s\\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;\n return this.pos > start;\n },\n skipToEnd: function() {this.pos = this.string.length;},\n skipTo: function(ch) {\n var found = this.string.indexOf(ch, this.pos);\n if (found > -1) {this.pos = found; return true;}\n },\n backUp: function(n) {this.pos -= n;},\n column: function() {\n if (this.lastColumnPos < this.start) {\n this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);\n this.lastColumnPos = this.start;\n }\n return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);\n },\n indentation: function() {\n return countColumn(this.string, null, this.tabSize) -\n (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);\n },\n match: function(pattern, consume, caseInsensitive) {\n if (typeof pattern == \"string\") {\n var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};\n var substr = this.string.substr(this.pos, pattern.length);\n if (cased(substr) == cased(pattern)) {\n if (consume !== false) this.pos += pattern.length;\n return true;\n }\n } else {\n var match = this.string.slice(this.pos).match(pattern);\n if (match && match.index > 0) return null;\n if (match && consume !== false) this.pos += match[0].length;\n return match;\n }\n },\n current: function(){return this.string.slice(this.start, this.pos);},\n hideFirstChars: function(n, inner) {\n this.lineStart += n;\n try { return inner(); }\n finally { this.lineStart -= n; }\n }\n };\n\n // TEXTMARKERS\n\n // Created with markText and setBookmark methods. A TextMarker is a\n // handle that can be used to clear or find a marked position in the\n // document. Line objects hold arrays (markedSpans) containing\n // {from, to, marker} object pointing to such marker objects, and\n // indicating that such a marker is present on that line. Multiple\n // lines may point to the same marker when it spans across lines.\n // The spans will have null for their from/to properties when the\n // marker continues beyond the start/end of the line. Markers have\n // links back to the lines they currently touch.\n\n var TextMarker = CodeMirror.TextMarker = function(doc, type) {\n this.lines = [];\n this.type = type;\n this.doc = doc;\n };\n eventMixin(TextMarker);\n\n // Clear the marker.\n TextMarker.prototype.clear = function() {\n if (this.explicitlyCleared) return;\n var cm = this.doc.cm, withOp = cm && !cm.curOp;\n if (withOp) startOperation(cm);\n if (hasHandler(this, \"clear\")) {\n var found = this.find();\n if (found) signalLater(this, \"clear\", found.from, found.to);\n }\n var min = null, max = null;\n for (var i = 0; i < this.lines.length; ++i) {\n var line = this.lines[i];\n var span = getMarkedSpanFor(line.markedSpans, this);\n if (cm && !this.collapsed) regLineChange(cm, lineNo(line), \"text\");\n else if (cm) {\n if (span.to != null) max = lineNo(line);\n if (span.from != null) min = lineNo(line);\n }\n line.markedSpans = removeMarkedSpan(line.markedSpans, span);\n if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)\n updateLineHeight(line, textHeight(cm.display));\n }\n if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {\n var visual = visualLine(this.lines[i]), len = lineLength(visual);\n if (len > cm.display.maxLineLength) {\n cm.display.maxLine = visual;\n cm.display.maxLineLength = len;\n cm.display.maxLineChanged = true;\n }\n }\n\n if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);\n this.lines.length = 0;\n this.explicitlyCleared = true;\n if (this.atomic && this.doc.cantEdit) {\n this.doc.cantEdit = false;\n if (cm) reCheckSelection(cm.doc);\n }\n if (cm) signalLater(cm, \"markerCleared\", cm, this);\n if (withOp) endOperation(cm);\n if (this.parent) this.parent.clear();\n };\n\n // Find the position of the marker in the document. Returns a {from,\n // to} object by default. Side can be passed to get a specific side\n // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the\n // Pos objects returned contain a line object, rather than a line\n // number (used to prevent looking up the same line twice).\n TextMarker.prototype.find = function(side, lineObj) {\n if (side == null && this.type == \"bookmark\") side = 1;\n var from, to;\n for (var i = 0; i < this.lines.length; ++i) {\n var line = this.lines[i];\n var span = getMarkedSpanFor(line.markedSpans, this);\n if (span.from != null) {\n from = Pos(lineObj ? line : lineNo(line), span.from);\n if (side == -1) return from;\n }\n if (span.to != null) {\n to = Pos(lineObj ? line : lineNo(line), span.to);\n if (side == 1) return to;\n }\n }\n return from && {from: from, to: to};\n };\n\n // Signals that the marker's widget changed, and surrounding layout\n // should be recomputed.\n TextMarker.prototype.changed = function() {\n var pos = this.find(-1, true), widget = this, cm = this.doc.cm;\n if (!pos || !cm) return;\n runInOp(cm, function() {\n var line = pos.line, lineN = lineNo(pos.line);\n var view = findViewForLine(cm, lineN);\n if (view) {\n clearLineMeasurementCacheFor(view);\n cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;\n }\n cm.curOp.updateMaxLine = true;\n if (!lineIsHidden(widget.doc, line) && widget.height != null) {\n var oldHeight = widget.height;\n widget.height = null;\n var dHeight = widgetHeight(widget) - oldHeight;\n if (dHeight)\n updateLineHeight(line, line.height + dHeight);\n }\n });\n };\n\n TextMarker.prototype.attachLine = function(line) {\n if (!this.lines.length && this.doc.cm) {\n var op = this.doc.cm.curOp;\n if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)\n (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);\n }\n this.lines.push(line);\n };\n TextMarker.prototype.detachLine = function(line) {\n this.lines.splice(indexOf(this.lines, line), 1);\n if (!this.lines.length && this.doc.cm) {\n var op = this.doc.cm.curOp;\n (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);\n }\n };\n\n // Collapsed markers have unique ids, in order to be able to order\n // them, which is needed for uniquely determining an outer marker\n // when they overlap (they may nest, but not partially overlap).\n var nextMarkerId = 0;\n\n // Create a marker, wire it up to the right lines, and\n function markText(doc, from, to, options, type) {\n // Shared markers (across linked documents) are handled separately\n // (markTextShared will call out to this again, once per\n // document).\n if (options && options.shared) return markTextShared(doc, from, to, options, type);\n // Ensure we are in an operation.\n if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);\n\n var marker = new TextMarker(doc, type), diff = cmp(from, to);\n if (options) copyObj(options, marker, false);\n // Don't connect empty markers unless clearWhenEmpty is false\n if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)\n return marker;\n if (marker.replacedWith) {\n // Showing up as a widget implies collapsed (widget replaces text)\n marker.collapsed = true;\n marker.widgetNode = elt(\"span\", [marker.replacedWith], \"CodeMirror-widget\");\n if (!options.handleMouseEvents) marker.widgetNode.setAttribute(\"cm-ignore-events\", \"true\");\n if (options.insertLeft) marker.widgetNode.insertLeft = true;\n }\n if (marker.collapsed) {\n if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||\n from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))\n throw new Error(\"Inserting collapsed marker partially overlapping an existing one\");\n sawCollapsedSpans = true;\n }\n\n if (marker.addToHistory)\n addChangeToHistory(doc, {from: from, to: to, origin: \"markText\"}, doc.sel, NaN);\n\n var curLine = from.line, cm = doc.cm, updateMaxLine;\n doc.iter(curLine, to.line + 1, function(line) {\n if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)\n updateMaxLine = true;\n if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);\n addMarkedSpan(line, new MarkedSpan(marker,\n curLine == from.line ? from.ch : null,\n curLine == to.line ? to.ch : null));\n ++curLine;\n });\n // lineIsHidden depends on the presence of the spans, so needs a second pass\n if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {\n if (lineIsHidden(doc, line)) updateLineHeight(line, 0);\n });\n\n if (marker.clearOnEnter) on(marker, \"beforeCursorEnter\", function() { marker.clear(); });\n\n if (marker.readOnly) {\n sawReadOnlySpans = true;\n if (doc.history.done.length || doc.history.undone.length)\n doc.clearHistory();\n }\n if (marker.collapsed) {\n marker.id = ++nextMarkerId;\n marker.atomic = true;\n }\n if (cm) {\n // Sync editor state\n if (updateMaxLine) cm.curOp.updateMaxLine = true;\n if (marker.collapsed)\n regChange(cm, from.line, to.line + 1);\n else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)\n for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, \"text\");\n if (marker.atomic) reCheckSelection(cm.doc);\n signalLater(cm, \"markerAdded\", cm, marker);\n }\n return marker;\n }\n\n // SHARED TEXTMARKERS\n\n // A shared marker spans multiple linked documents. It is\n // implemented as a meta-marker-object controlling multiple normal\n // markers.\n var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) {\n this.markers = markers;\n this.primary = primary;\n for (var i = 0; i < markers.length; ++i)\n markers[i].parent = this;\n };\n eventMixin(SharedTextMarker);\n\n SharedTextMarker.prototype.clear = function() {\n if (this.explicitlyCleared) return;\n this.explicitlyCleared = true;\n for (var i = 0; i < this.markers.length; ++i)\n this.markers[i].clear();\n signalLater(this, \"clear\");\n };\n SharedTextMarker.prototype.find = function(side, lineObj) {\n return this.primary.find(side, lineObj);\n };\n\n function markTextShared(doc, from, to, options, type) {\n options = copyObj(options);\n options.shared = false;\n var markers = [markText(doc, from, to, options, type)], primary = markers[0];\n var widget = options.widgetNode;\n linkedDocs(doc, function(doc) {\n if (widget) options.widgetNode = widget.cloneNode(true);\n markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));\n for (var i = 0; i < doc.linked.length; ++i)\n if (doc.linked[i].isParent) return;\n primary = lst(markers);\n });\n return new SharedTextMarker(markers, primary);\n }\n\n function findSharedMarkers(doc) {\n return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),\n function(m) { return m.parent; });\n }\n\n function copySharedMarkers(doc, markers) {\n for (var i = 0; i < markers.length; i++) {\n var marker = markers[i], pos = marker.find();\n var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);\n if (cmp(mFrom, mTo)) {\n var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);\n marker.markers.push(subMark);\n subMark.parent = marker;\n }\n }\n }\n\n function detachSharedMarkers(markers) {\n for (var i = 0; i < markers.length; i++) {\n var marker = markers[i], linked = [marker.primary.doc];;\n linkedDocs(marker.primary.doc, function(d) { linked.push(d); });\n for (var j = 0; j < marker.markers.length; j++) {\n var subMarker = marker.markers[j];\n if (indexOf(linked, subMarker.doc) == -1) {\n subMarker.parent = null;\n marker.markers.splice(j--, 1);\n }\n }\n }\n }\n\n // TEXTMARKER SPANS\n\n function MarkedSpan(marker, from, to) {\n this.marker = marker;\n this.from = from; this.to = to;\n }\n\n // Search an array of spans for a span matching the given marker.\n function getMarkedSpanFor(spans, marker) {\n if (spans) for (var i = 0; i < spans.length; ++i) {\n var span = spans[i];\n if (span.marker == marker) return span;\n }\n }\n // Remove a span from an array, returning undefined if no spans are\n // left (we don't store arrays for lines without spans).\n function removeMarkedSpan(spans, span) {\n for (var r, i = 0; i < spans.length; ++i)\n if (spans[i] != span) (r || (r = [])).push(spans[i]);\n return r;\n }\n // Add a span to a line.\n function addMarkedSpan(line, span) {\n line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];\n span.marker.attachLine(line);\n }\n\n // Used for the algorithm that adjusts markers for a change in the\n // document. These functions cut an array of spans at a given\n // character position, returning an array of remaining chunks (or\n // undefined if nothing remains).\n function markedSpansBefore(old, startCh, isInsert) {\n if (old) for (var i = 0, nw; i < old.length; ++i) {\n var span = old[i], marker = span.marker;\n var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);\n if (startsBefore || span.from == startCh && marker.type == \"bookmark\" && (!isInsert || !span.marker.insertLeft)) {\n var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);\n (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));\n }\n }\n return nw;\n }\n function markedSpansAfter(old, endCh, isInsert) {\n if (old) for (var i = 0, nw; i < old.length; ++i) {\n var span = old[i], marker = span.marker;\n var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);\n if (endsAfter || span.from == endCh && marker.type == \"bookmark\" && (!isInsert || span.marker.insertLeft)) {\n var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);\n (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,\n span.to == null ? null : span.to - endCh));\n }\n }\n return nw;\n }\n\n // Given a change object, compute the new set of marker spans that\n // cover the line in which the change took place. Removes spans\n // entirely within the change, reconnects spans belonging to the\n // same marker that appear on both sides of the change, and cuts off\n // spans partially within the change. Returns an array of span\n // arrays with one element for each line in (after) the change.\n function stretchSpansOverChange(doc, change) {\n if (change.full) return null;\n var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;\n var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;\n if (!oldFirst && !oldLast) return null;\n\n var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;\n // Get the spans that 'stick out' on both sides\n var first = markedSpansBefore(oldFirst, startCh, isInsert);\n var last = markedSpansAfter(oldLast, endCh, isInsert);\n\n // Next, merge those two ends\n var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);\n if (first) {\n // Fix up .to properties of first\n for (var i = 0; i < first.length; ++i) {\n var span = first[i];\n if (span.to == null) {\n var found = getMarkedSpanFor(last, span.marker);\n if (!found) span.to = startCh;\n else if (sameLine) span.to = found.to == null ? null : found.to + offset;\n }\n }\n }\n if (last) {\n // Fix up .from in last (or move them into first in case of sameLine)\n for (var i = 0; i < last.length; ++i) {\n var span = last[i];\n if (span.to != null) span.to += offset;\n if (span.from == null) {\n var found = getMarkedSpanFor(first, span.marker);\n if (!found) {\n span.from = offset;\n if (sameLine) (first || (first = [])).push(span);\n }\n } else {\n span.from += offset;\n if (sameLine) (first || (first = [])).push(span);\n }\n }\n }\n // Make sure we didn't create any zero-length spans\n if (first) first = clearEmptySpans(first);\n if (last && last != first) last = clearEmptySpans(last);\n\n var newMarkers = [first];\n if (!sameLine) {\n // Fill gap with whole-line-spans\n var gap = change.text.length - 2, gapMarkers;\n if (gap > 0 && first)\n for (var i = 0; i < first.length; ++i)\n if (first[i].to == null)\n (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));\n for (var i = 0; i < gap; ++i)\n newMarkers.push(gapMarkers);\n newMarkers.push(last);\n }\n return newMarkers;\n }\n\n // Remove spans that are empty and don't have a clearWhenEmpty\n // option of false.\n function clearEmptySpans(spans) {\n for (var i = 0; i < spans.length; ++i) {\n var span = spans[i];\n if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)\n spans.splice(i--, 1);\n }\n if (!spans.length) return null;\n return spans;\n }\n\n // Used for un/re-doing changes from the history. Combines the\n // result of computing the existing spans with the set of spans that\n // existed in the history (so that deleting around a span and then\n // undoing brings back the span).\n function mergeOldSpans(doc, change) {\n var old = getOldSpans(doc, change);\n var stretched = stretchSpansOverChange(doc, change);\n if (!old) return stretched;\n if (!stretched) return old;\n\n for (var i = 0; i < old.length; ++i) {\n var oldCur = old[i], stretchCur = stretched[i];\n if (oldCur && stretchCur) {\n spans: for (var j = 0; j < stretchCur.length; ++j) {\n var span = stretchCur[j];\n for (var k = 0; k < oldCur.length; ++k)\n if (oldCur[k].marker == span.marker) continue spans;\n oldCur.push(span);\n }\n } else if (stretchCur) {\n old[i] = stretchCur;\n }\n }\n return old;\n }\n\n // Used to 'clip' out readOnly ranges when making a change.\n function removeReadOnlyRanges(doc, from, to) {\n var markers = null;\n doc.iter(from.line, to.line + 1, function(line) {\n if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {\n var mark = line.markedSpans[i].marker;\n if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))\n (markers || (markers = [])).push(mark);\n }\n });\n if (!markers) return null;\n var parts = [{from: from, to: to}];\n for (var i = 0; i < markers.length; ++i) {\n var mk = markers[i], m = mk.find(0);\n for (var j = 0; j < parts.length; ++j) {\n var p = parts[j];\n if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue;\n var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);\n if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)\n newParts.push({from: p.from, to: m.from});\n if (dto > 0 || !mk.inclusiveRight && !dto)\n newParts.push({from: m.to, to: p.to});\n parts.splice.apply(parts, newParts);\n j += newParts.length - 1;\n }\n }\n return parts;\n }\n\n // Connect or disconnect spans from a line.\n function detachMarkedSpans(line) {\n var spans = line.markedSpans;\n if (!spans) return;\n for (var i = 0; i < spans.length; ++i)\n spans[i].marker.detachLine(line);\n line.markedSpans = null;\n }\n function attachMarkedSpans(line, spans) {\n if (!spans) return;\n for (var i = 0; i < spans.length; ++i)\n spans[i].marker.attachLine(line);\n line.markedSpans = spans;\n }\n\n // Helpers used when computing which overlapping collapsed span\n // counts as the larger one.\n function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }\n function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }\n\n // Returns a number indicating which of two overlapping collapsed\n // spans is larger (and thus includes the other). Falls back to\n // comparing ids when the spans cover exactly the same range.\n function compareCollapsedMarkers(a, b) {\n var lenDiff = a.lines.length - b.lines.length;\n if (lenDiff != 0) return lenDiff;\n var aPos = a.find(), bPos = b.find();\n var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);\n if (fromCmp) return -fromCmp;\n var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);\n if (toCmp) return toCmp;\n return b.id - a.id;\n }\n\n // Find out whether a line ends or starts in a collapsed span. If\n // so, return the marker for that span.\n function collapsedSpanAtSide(line, start) {\n var sps = sawCollapsedSpans && line.markedSpans, found;\n if (sps) for (var sp, i = 0; i < sps.length; ++i) {\n sp = sps[i];\n if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&\n (!found || compareCollapsedMarkers(found, sp.marker) < 0))\n found = sp.marker;\n }\n return found;\n }\n function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }\n function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }\n\n // Test whether there exists a collapsed span that partially\n // overlaps (covers the start or end, but not both) of a new span.\n // Such overlap is not allowed.\n function conflictingCollapsedRange(doc, lineNo, from, to, marker) {\n var line = getLine(doc, lineNo);\n var sps = sawCollapsedSpans && line.markedSpans;\n if (sps) for (var i = 0; i < sps.length; ++i) {\n var sp = sps[i];\n if (!sp.marker.collapsed) continue;\n var found = sp.marker.find(0);\n var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);\n var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);\n if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue;\n if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) ||\n fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight)))\n return true;\n }\n }\n\n // A visual line is a line as drawn on the screen. Folding, for\n // example, can cause multiple logical lines to appear on the same\n // visual line. This finds the start of the visual line that the\n // given line is part of (usually that is the line itself).\n function visualLine(line) {\n var merged;\n while (merged = collapsedSpanAtStart(line))\n line = merged.find(-1, true).line;\n return line;\n }\n\n // Returns an array of logical lines that continue the visual line\n // started by the argument, or undefined if there are no such lines.\n function visualLineContinued(line) {\n var merged, lines;\n while (merged = collapsedSpanAtEnd(line)) {\n line = merged.find(1, true).line;\n (lines || (lines = [])).push(line);\n }\n return lines;\n }\n\n // Get the line number of the start of the visual line that the\n // given line number is part of.\n function visualLineNo(doc, lineN) {\n var line = getLine(doc, lineN), vis = visualLine(line);\n if (line == vis) return lineN;\n return lineNo(vis);\n }\n // Get the line number of the start of the next visual line after\n // the given line.\n function visualLineEndNo(doc, lineN) {\n if (lineN > doc.lastLine()) return lineN;\n var line = getLine(doc, lineN), merged;\n if (!lineIsHidden(doc, line)) return lineN;\n while (merged = collapsedSpanAtEnd(line))\n line = merged.find(1, true).line;\n return lineNo(line) + 1;\n }\n\n // Compute whether a line is hidden. Lines count as hidden when they\n // are part of a visual line that starts with another line, or when\n // they are entirely covered by collapsed, non-widget span.\n function lineIsHidden(doc, line) {\n var sps = sawCollapsedSpans && line.markedSpans;\n if (sps) for (var sp, i = 0; i < sps.length; ++i) {\n sp = sps[i];\n if (!sp.marker.collapsed) continue;\n if (sp.from == null) return true;\n if (sp.marker.widgetNode) continue;\n if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))\n return true;\n }\n }\n function lineIsHiddenInner(doc, line, span) {\n if (span.to == null) {\n var end = span.marker.find(1, true);\n return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker));\n }\n if (span.marker.inclusiveRight && span.to == line.text.length)\n return true;\n for (var sp, i = 0; i < line.markedSpans.length; ++i) {\n sp = line.markedSpans[i];\n if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&\n (sp.to == null || sp.to != span.from) &&\n (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&\n lineIsHiddenInner(doc, line, sp)) return true;\n }\n }\n\n // LINE WIDGETS\n\n // Line widgets are block elements displayed above or below a line.\n\n var LineWidget = CodeMirror.LineWidget = function(cm, node, options) {\n if (options) for (var opt in options) if (options.hasOwnProperty(opt))\n this[opt] = options[opt];\n this.cm = cm;\n this.node = node;\n };\n eventMixin(LineWidget);\n\n function adjustScrollWhenAboveVisible(cm, line, diff) {\n if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))\n addToScrollPos(cm, null, diff);\n }\n\n LineWidget.prototype.clear = function() {\n var cm = this.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);\n if (no == null || !ws) return;\n for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);\n if (!ws.length) line.widgets = null;\n var height = widgetHeight(this);\n runInOp(cm, function() {\n adjustScrollWhenAboveVisible(cm, line, -height);\n regLineChange(cm, no, \"widget\");\n updateLineHeight(line, Math.max(0, line.height - height));\n });\n };\n LineWidget.prototype.changed = function() {\n var oldH = this.height, cm = this.cm, line = this.line;\n this.height = null;\n var diff = widgetHeight(this) - oldH;\n if (!diff) return;\n runInOp(cm, function() {\n cm.curOp.forceUpdate = true;\n adjustScrollWhenAboveVisible(cm, line, diff);\n updateLineHeight(line, line.height + diff);\n });\n };\n\n function widgetHeight(widget) {\n if (widget.height != null) return widget.height;\n if (!contains(document.body, widget.node)) {\n var parentStyle = \"position: relative;\";\n if (widget.coverGutter)\n parentStyle += \"margin-left: -\" + widget.cm.display.gutters.offsetWidth + \"px;\";\n if (widget.noHScroll)\n parentStyle += \"width: \" + widget.cm.display.wrapper.clientWidth + \"px;\";\n removeChildrenAndAdd(widget.cm.display.measure, elt(\"div\", [widget.node], null, parentStyle));\n }\n return widget.height = widget.node.offsetHeight;\n }\n\n function addLineWidget(cm, handle, node, options) {\n var widget = new LineWidget(cm, node, options);\n if (widget.noHScroll) cm.display.alignWidgets = true;\n changeLine(cm.doc, handle, \"widget\", function(line) {\n var widgets = line.widgets || (line.widgets = []);\n if (widget.insertAt == null) widgets.push(widget);\n else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);\n widget.line = line;\n if (!lineIsHidden(cm.doc, line)) {\n var aboveVisible = heightAtLine(line) < cm.doc.scrollTop;\n updateLineHeight(line, line.height + widgetHeight(widget));\n if (aboveVisible) addToScrollPos(cm, null, widget.height);\n cm.curOp.forceUpdate = true;\n }\n return true;\n });\n return widget;\n }\n\n // LINE DATA STRUCTURE\n\n // Line objects. These hold state related to a line, including\n // highlighting info (the styles array).\n var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {\n this.text = text;\n attachMarkedSpans(this, markedSpans);\n this.height = estimateHeight ? estimateHeight(this) : 1;\n };\n eventMixin(Line);\n Line.prototype.lineNo = function() { return lineNo(this); };\n\n // Change the content (text, markers) of a line. Automatically\n // invalidates cached information and tries to re-estimate the\n // line's height.\n function updateLine(line, text, markedSpans, estimateHeight) {\n line.text = text;\n if (line.stateAfter) line.stateAfter = null;\n if (line.styles) line.styles = null;\n if (line.order != null) line.order = null;\n detachMarkedSpans(line);\n attachMarkedSpans(line, markedSpans);\n var estHeight = estimateHeight ? estimateHeight(line) : 1;\n if (estHeight != line.height) updateLineHeight(line, estHeight);\n }\n\n // Detach a line from the document tree and its markers.\n function cleanUpLine(line) {\n line.parent = null;\n detachMarkedSpans(line);\n }\n\n function extractLineClasses(type, output) {\n if (type) for (;;) {\n var lineClass = type.match(/(?:^|\\s+)line-(background-)?(\\S+)/);\n if (!lineClass) break;\n type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);\n var prop = lineClass[1] ? \"bgClass\" : \"textClass\";\n if (output[prop] == null)\n output[prop] = lineClass[2];\n else if (!(new RegExp(\"(?:^|\\s)\" + lineClass[2] + \"(?:$|\\s)\")).test(output[prop]))\n output[prop] += \" \" + lineClass[2];\n }\n return type;\n }\n\n function callBlankLine(mode, state) {\n if (mode.blankLine) return mode.blankLine(state);\n if (!mode.innerMode) return;\n var inner = CodeMirror.innerMode(mode, state);\n if (inner.mode.blankLine) return inner.mode.blankLine(inner.state);\n }\n\n function readToken(mode, stream, state, inner) {\n for (var i = 0; i < 10; i++) {\n if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode;\n var style = mode.token(stream, state);\n if (stream.pos > stream.start) return style;\n }\n throw new Error(\"Mode \" + mode.name + \" failed to advance stream.\");\n }\n\n // Utility for getTokenAt and getLineTokens\n function takeToken(cm, pos, precise, asArray) {\n function getObj(copy) {\n return {start: stream.start, end: stream.pos,\n string: stream.current(),\n type: style || null,\n state: copy ? copyState(doc.mode, state) : state};\n }\n\n var doc = cm.doc, mode = doc.mode, style;\n pos = clipPos(doc, pos);\n var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise);\n var stream = new StringStream(line.text, cm.options.tabSize), tokens;\n if (asArray) tokens = [];\n while ((asArray || stream.pos < pos.ch) && !stream.eol()) {\n stream.start = stream.pos;\n style = readToken(mode, stream, state);\n if (asArray) tokens.push(getObj(true));\n }\n return asArray ? tokens : getObj();\n }\n\n // Run the given mode's parser over a line, calling f for each token.\n function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {\n var flattenSpans = mode.flattenSpans;\n if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;\n var curStart = 0, curStyle = null;\n var stream = new StringStream(text, cm.options.tabSize), style;\n var inner = cm.options.addModeClass && [null];\n if (text == \"\") extractLineClasses(callBlankLine(mode, state), lineClasses);\n while (!stream.eol()) {\n if (stream.pos > cm.options.maxHighlightLength) {\n flattenSpans = false;\n if (forceToEnd) processLine(cm, text, state, stream.pos);\n stream.pos = text.length;\n style = null;\n } else {\n style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses);\n }\n if (inner) {\n var mName = inner[0].name;\n if (mName) style = \"m-\" + (style ? mName + \" \" + style : mName);\n }\n if (!flattenSpans || curStyle != style) {\n while (curStart < stream.start) {\n curStart = Math.min(stream.start, curStart + 50000);\n f(curStart, curStyle);\n }\n curStyle = style;\n }\n stream.start = stream.pos;\n }\n while (curStart < stream.pos) {\n // Webkit seems to refuse to render text nodes longer than 57444 characters\n var pos = Math.min(stream.pos, curStart + 50000);\n f(pos, curStyle);\n curStart = pos;\n }\n }\n\n // Compute a style array (an array starting with a mode generation\n // -- for invalidation -- followed by pairs of end positions and\n // style strings), which is used to highlight the tokens on the\n // line.\n function highlightLine(cm, line, state, forceToEnd) {\n // A styles array always starts with a number identifying the\n // mode/overlays that it is based on (for easy invalidation).\n var st = [cm.state.modeGen], lineClasses = {};\n // Compute the base array of styles\n runMode(cm, line.text, cm.doc.mode, state, function(end, style) {\n st.push(end, style);\n }, lineClasses, forceToEnd);\n\n // Run overlays, adjust style array.\n for (var o = 0; o < cm.state.overlays.length; ++o) {\n var overlay = cm.state.overlays[o], i = 1, at = 0;\n runMode(cm, line.text, overlay.mode, true, function(end, style) {\n var start = i;\n // Ensure there's a token end at the current position, and that i points at it\n while (at < end) {\n var i_end = st[i];\n if (i_end > end)\n st.splice(i, 1, end, st[i+1], i_end);\n i += 2;\n at = Math.min(end, i_end);\n }\n if (!style) return;\n if (overlay.opaque) {\n st.splice(start, i - start, end, \"cm-overlay \" + style);\n i = start + 2;\n } else {\n for (; start < i; start += 2) {\n var cur = st[start+1];\n st[start+1] = (cur ? cur + \" \" : \"\") + \"cm-overlay \" + style;\n }\n }\n }, lineClasses);\n }\n\n return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null};\n }\n\n function getLineStyles(cm, line, updateFrontier) {\n if (!line.styles || line.styles[0] != cm.state.modeGen) {\n var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));\n line.styles = result.styles;\n if (result.classes) line.styleClasses = result.classes;\n else if (line.styleClasses) line.styleClasses = null;\n if (updateFrontier === cm.doc.frontier) cm.doc.frontier++;\n }\n return line.styles;\n }\n\n // Lightweight form of highlight -- proceed over this line and\n // update state, but don't save a style array. Used for lines that\n // aren't currently visible.\n function processLine(cm, text, state, startAt) {\n var mode = cm.doc.mode;\n var stream = new StringStream(text, cm.options.tabSize);\n stream.start = stream.pos = startAt || 0;\n if (text == \"\") callBlankLine(mode, state);\n while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {\n readToken(mode, stream, state);\n stream.start = stream.pos;\n }\n }\n\n // Convert a style as returned by a mode (either null, or a string\n // containing one or more styles) to a CSS style. This is cached,\n // and also looks for line-wide styles.\n var styleToClassCache = {}, styleToClassCacheWithMode = {};\n function interpretTokenStyle(style, options) {\n if (!style || /^\\s*$/.test(style)) return null;\n var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;\n return cache[style] ||\n (cache[style] = style.replace(/\\S+/g, \"cm-$&\"));\n }\n\n // Render the DOM representation of the text of a line. Also builds\n // up a 'line map', which points at the DOM nodes that represent\n // specific stretches of text, and is used by the measuring code.\n // The returned object contains the DOM node, this map, and\n // information about line-wide styles that were set by the mode.\n function buildLineContent(cm, lineView) {\n // The padding-right forces the element to have a 'border', which\n // is needed on Webkit to be able to get line-level bounding\n // rectangles for it (in measureChar).\n var content = elt(\"span\", null, null, webkit ? \"padding-right: .1px\" : null);\n var builder = {pre: elt(\"pre\", [content]), content: content, col: 0, pos: 0, cm: cm};\n lineView.measure = {};\n\n // Iterate over the logical lines that make up this visual line.\n for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {\n var line = i ? lineView.rest[i - 1] : lineView.line, order;\n builder.pos = 0;\n builder.addToken = buildToken;\n // Optionally wire in some hacks into the token-rendering\n // algorithm, to deal with browser quirks.\n if ((ie || webkit) && cm.getOption(\"lineWrapping\"))\n builder.addToken = buildTokenSplitSpaces(builder.addToken);\n if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))\n builder.addToken = buildTokenBadBidi(builder.addToken, order);\n builder.map = [];\n var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);\n insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));\n if (line.styleClasses) {\n if (line.styleClasses.bgClass)\n builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || \"\");\n if (line.styleClasses.textClass)\n builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || \"\");\n }\n\n // Ensure at least a single node is present, for measuring.\n if (builder.map.length == 0)\n builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure)));\n\n // Store the map and a cache object for the current logical line\n if (i == 0) {\n lineView.measure.map = builder.map;\n lineView.measure.cache = {};\n } else {\n (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map);\n (lineView.measure.caches || (lineView.measure.caches = [])).push({});\n }\n }\n\n // See issue #2901\n if (webkit && /\\bcm-tab\\b/.test(builder.content.lastChild.className))\n builder.content.className = \"cm-tab-wrap-hack\";\n\n signal(cm, \"renderLine\", cm, lineView.line, builder.pre);\n if (builder.pre.className)\n builder.textClass = joinClasses(builder.pre.className, builder.textClass || \"\");\n\n return builder;\n }\n\n function defaultSpecialCharPlaceholder(ch) {\n var token = elt(\"span\", \"\\u2022\", \"cm-invalidchar\");\n token.title = \"\\\\u\" + ch.charCodeAt(0).toString(16);\n return token;\n }\n\n // Build up the DOM representation for a single token, and add it to\n // the line map. Takes care to render special characters separately.\n function buildToken(builder, text, style, startStyle, endStyle, title, css) {\n if (!text) return;\n var special = builder.cm.options.specialChars, mustWrap = false;\n if (!special.test(text)) {\n builder.col += text.length;\n var content = document.createTextNode(text);\n builder.map.push(builder.pos, builder.pos + text.length, content);\n if (ie && ie_version < 9) mustWrap = true;\n builder.pos += text.length;\n } else {\n var content = document.createDocumentFragment(), pos = 0;\n while (true) {\n special.lastIndex = pos;\n var m = special.exec(text);\n var skipped = m ? m.index - pos : text.length - pos;\n if (skipped) {\n var txt = document.createTextNode(text.slice(pos, pos + skipped));\n if (ie && ie_version < 9) content.appendChild(elt(\"span\", [txt]));\n else content.appendChild(txt);\n builder.map.push(builder.pos, builder.pos + skipped, txt);\n builder.col += skipped;\n builder.pos += skipped;\n }\n if (!m) break;\n pos += skipped + 1;\n if (m[0] == \"\\t\") {\n var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;\n var txt = content.appendChild(elt(\"span\", spaceStr(tabWidth), \"cm-tab\"));\n builder.col += tabWidth;\n } else {\n var txt = builder.cm.options.specialCharPlaceholder(m[0]);\n if (ie && ie_version < 9) content.appendChild(elt(\"span\", [txt]));\n else content.appendChild(txt);\n builder.col += 1;\n }\n builder.map.push(builder.pos, builder.pos + 1, txt);\n builder.pos++;\n }\n }\n if (style || startStyle || endStyle || mustWrap || css) {\n var fullStyle = style || \"\";\n if (startStyle) fullStyle += startStyle;\n if (endStyle) fullStyle += endStyle;\n var token = elt(\"span\", [content], fullStyle, css);\n if (title) token.title = title;\n return builder.content.appendChild(token);\n }\n builder.content.appendChild(content);\n }\n\n function buildTokenSplitSpaces(inner) {\n function split(old) {\n var out = \" \";\n for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? \" \" : \"\\u00a0\";\n out += \" \";\n return out;\n }\n return function(builder, text, style, startStyle, endStyle, title) {\n inner(builder, text.replace(/ {3,}/g, split), style, startStyle, endStyle, title);\n };\n }\n\n // Work around nonsense dimensions being reported for stretches of\n // right-to-left text.\n function buildTokenBadBidi(inner, order) {\n return function(builder, text, style, startStyle, endStyle, title) {\n style = style ? style + \" cm-force-border\" : \"cm-force-border\";\n var start = builder.pos, end = start + text.length;\n for (;;) {\n // Find the part that overlaps with the start of this text\n for (var i = 0; i < order.length; i++) {\n var part = order[i];\n if (part.to > start && part.from <= start) break;\n }\n if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title);\n inner(builder, text.slice(0, part.to - start), style, startStyle, null, title);\n startStyle = null;\n text = text.slice(part.to - start);\n start = part.to;\n }\n };\n }\n\n function buildCollapsedSpan(builder, size, marker, ignoreWidget) {\n var widget = !ignoreWidget && marker.widgetNode;\n if (widget) {\n builder.map.push(builder.pos, builder.pos + size, widget);\n builder.content.appendChild(widget);\n }\n builder.pos += size;\n }\n\n // Outputs a number of spans to make up a line, taking highlighting\n // and marked text into account.\n function insertLineContent(line, builder, styles) {\n var spans = line.markedSpans, allText = line.text, at = 0;\n if (!spans) {\n for (var i = 1; i < styles.length; i+=2)\n builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options));\n return;\n }\n\n var len = allText.length, pos = 0, i = 1, text = \"\", style, css;\n var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;\n for (;;) {\n if (nextChange == pos) { // Update current marker set\n spanStyle = spanEndStyle = spanStartStyle = title = css = \"\";\n collapsed = null; nextChange = Infinity;\n var foundBookmarks = [];\n for (var j = 0; j < spans.length; ++j) {\n var sp = spans[j], m = sp.marker;\n if (sp.from <= pos && (sp.to == null || sp.to > pos)) {\n if (sp.to != null && nextChange > sp.to) { nextChange = sp.to; spanEndStyle = \"\"; }\n if (m.className) spanStyle += \" \" + m.className;\n if (m.css) css = m.css;\n if (m.startStyle && sp.from == pos) spanStartStyle += \" \" + m.startStyle;\n if (m.endStyle && sp.to == nextChange) spanEndStyle += \" \" + m.endStyle;\n if (m.title && !title) title = m.title;\n if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))\n collapsed = sp;\n } else if (sp.from > pos && nextChange > sp.from) {\n nextChange = sp.from;\n }\n if (m.type == \"bookmark\" && sp.from == pos && m.widgetNode) foundBookmarks.push(m);\n }\n if (collapsed && (collapsed.from || 0) == pos) {\n buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,\n collapsed.marker, collapsed.from == null);\n if (collapsed.to == null) return;\n }\n if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)\n buildCollapsedSpan(builder, 0, foundBookmarks[j]);\n }\n if (pos >= len) break;\n\n var upto = Math.min(len, nextChange);\n while (true) {\n if (text) {\n var end = pos + text.length;\n if (!collapsed) {\n var tokenText = end > upto ? text.slice(0, upto - pos) : text;\n builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,\n spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : \"\", title, css);\n }\n if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}\n pos = end;\n spanStartStyle = \"\";\n }\n text = allText.slice(at, at = styles[i++]);\n style = interpretTokenStyle(styles[i++], builder.cm.options);\n }\n }\n }\n\n // DOCUMENT DATA STRUCTURE\n\n // By default, updates that start and end at the beginning of a line\n // are treated specially, in order to make the association of line\n // widgets and marker elements with the text behave more intuitive.\n function isWholeLineUpdate(doc, change) {\n return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == \"\" &&\n (!doc.cm || doc.cm.options.wholeLineUpdateBefore);\n }\n\n // Perform a change on the document data structure.\n function updateDoc(doc, change, markedSpans, estimateHeight) {\n function spansFor(n) {return markedSpans ? markedSpans[n] : null;}\n function update(line, text, spans) {\n updateLine(line, text, spans, estimateHeight);\n signalLater(line, \"change\", line, change);\n }\n function linesFor(start, end) {\n for (var i = start, result = []; i < end; ++i)\n result.push(new Line(text[i], spansFor(i), estimateHeight));\n return result;\n }\n\n var from = change.from, to = change.to, text = change.text;\n var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);\n var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;\n\n // Adjust the line structure\n if (change.full) {\n doc.insert(0, linesFor(0, text.length));\n doc.remove(text.length, doc.size - text.length);\n } else if (isWholeLineUpdate(doc, change)) {\n // This is a whole-line replace. Treated specially to make\n // sure line objects move the way they are supposed to.\n var added = linesFor(0, text.length - 1);\n update(lastLine, lastLine.text, lastSpans);\n if (nlines) doc.remove(from.line, nlines);\n if (added.length) doc.insert(from.line, added);\n } else if (firstLine == lastLine) {\n if (text.length == 1) {\n update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);\n } else {\n var added = linesFor(1, text.length - 1);\n added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));\n update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));\n doc.insert(from.line + 1, added);\n }\n } else if (text.length == 1) {\n update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));\n doc.remove(from.line + 1, nlines);\n } else {\n update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));\n update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);\n var added = linesFor(1, text.length - 1);\n if (nlines > 1) doc.remove(from.line + 1, nlines - 1);\n doc.insert(from.line + 1, added);\n }\n\n signalLater(doc, \"change\", doc, change);\n }\n\n // The document is represented as a BTree consisting of leaves, with\n // chunk of lines in them, and branches, with up to ten leaves or\n // other branch nodes below them. The top node is always a branch\n // node, and is the document object itself (meaning it has\n // additional methods and properties).\n //\n // All nodes have parent links. The tree is used both to go from\n // line numbers to line objects, and to go from objects to numbers.\n // It also indexes by height, and is used to convert between height\n // and line object, and to find the total height of the document.\n //\n // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html\n\n function LeafChunk(lines) {\n this.lines = lines;\n this.parent = null;\n for (var i = 0, height = 0; i < lines.length; ++i) {\n lines[i].parent = this;\n height += lines[i].height;\n }\n this.height = height;\n }\n\n LeafChunk.prototype = {\n chunkSize: function() { return this.lines.length; },\n // Remove the n lines at offset 'at'.\n removeInner: function(at, n) {\n for (var i = at, e = at + n; i < e; ++i) {\n var line = this.lines[i];\n this.height -= line.height;\n cleanUpLine(line);\n signalLater(line, \"delete\");\n }\n this.lines.splice(at, n);\n },\n // Helper used to collapse a small branch into a single leaf.\n collapse: function(lines) {\n lines.push.apply(lines, this.lines);\n },\n // Insert the given array of lines at offset 'at', count them as\n // having the given height.\n insertInner: function(at, lines, height) {\n this.height += height;\n this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));\n for (var i = 0; i < lines.length; ++i) lines[i].parent = this;\n },\n // Used to iterate over a part of the tree.\n iterN: function(at, n, op) {\n for (var e = at + n; at < e; ++at)\n if (op(this.lines[at])) return true;\n }\n };\n\n function BranchChunk(children) {\n this.children = children;\n var size = 0, height = 0;\n for (var i = 0; i < children.length; ++i) {\n var ch = children[i];\n size += ch.chunkSize(); height += ch.height;\n ch.parent = this;\n }\n this.size = size;\n this.height = height;\n this.parent = null;\n }\n\n BranchChunk.prototype = {\n chunkSize: function() { return this.size; },\n removeInner: function(at, n) {\n this.size -= n;\n for (var i = 0; i < this.children.length; ++i) {\n var child = this.children[i], sz = child.chunkSize();\n if (at < sz) {\n var rm = Math.min(n, sz - at), oldHeight = child.height;\n child.removeInner(at, rm);\n this.height -= oldHeight - child.height;\n if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }\n if ((n -= rm) == 0) break;\n at = 0;\n } else at -= sz;\n }\n // If the result is smaller than 25 lines, ensure that it is a\n // single leaf node.\n if (this.size - n < 25 &&\n (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {\n var lines = [];\n this.collapse(lines);\n this.children = [new LeafChunk(lines)];\n this.children[0].parent = this;\n }\n },\n collapse: function(lines) {\n for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines);\n },\n insertInner: function(at, lines, height) {\n this.size += lines.length;\n this.height += height;\n for (var i = 0; i < this.children.length; ++i) {\n var child = this.children[i], sz = child.chunkSize();\n if (at <= sz) {\n child.insertInner(at, lines, height);\n if (child.lines && child.lines.length > 50) {\n while (child.lines.length > 50) {\n var spilled = child.lines.splice(child.lines.length - 25, 25);\n var newleaf = new LeafChunk(spilled);\n child.height -= newleaf.height;\n this.children.splice(i + 1, 0, newleaf);\n newleaf.parent = this;\n }\n this.maybeSpill();\n }\n break;\n }\n at -= sz;\n }\n },\n // When a node has grown, check whether it should be split.\n maybeSpill: function() {\n if (this.children.length <= 10) return;\n var me = this;\n do {\n var spilled = me.children.splice(me.children.length - 5, 5);\n var sibling = new BranchChunk(spilled);\n if (!me.parent) { // Become the parent node\n var copy = new BranchChunk(me.children);\n copy.parent = me;\n me.children = [copy, sibling];\n me = copy;\n } else {\n me.size -= sibling.size;\n me.height -= sibling.height;\n var myIndex = indexOf(me.parent.children, me);\n me.parent.children.splice(myIndex + 1, 0, sibling);\n }\n sibling.parent = me.parent;\n } while (me.children.length > 10);\n me.parent.maybeSpill();\n },\n iterN: function(at, n, op) {\n for (var i = 0; i < this.children.length; ++i) {\n var child = this.children[i], sz = child.chunkSize();\n if (at < sz) {\n var used = Math.min(n, sz - at);\n if (child.iterN(at, used, op)) return true;\n if ((n -= used) == 0) break;\n at = 0;\n } else at -= sz;\n }\n }\n };\n\n var nextDocId = 0;\n var Doc = CodeMirror.Doc = function(text, mode, firstLine) {\n if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);\n if (firstLine == null) firstLine = 0;\n\n BranchChunk.call(this, [new LeafChunk([new Line(\"\", null)])]);\n this.first = firstLine;\n this.scrollTop = this.scrollLeft = 0;\n this.cantEdit = false;\n this.cleanGeneration = 1;\n this.frontier = firstLine;\n var start = Pos(firstLine, 0);\n this.sel = simpleSelection(start);\n this.history = new History(null);\n this.id = ++nextDocId;\n this.modeOption = mode;\n\n if (typeof text == \"string\") text = splitLines(text);\n updateDoc(this, {from: start, to: start, text: text});\n setSelection(this, simpleSelection(start), sel_dontScroll);\n };\n\n Doc.prototype = createObj(BranchChunk.prototype, {\n constructor: Doc,\n // Iterate over the document. Supports two forms -- with only one\n // argument, it calls that for each line in the document. With\n // three, it iterates over the range given by the first two (with\n // the second being non-inclusive).\n iter: function(from, to, op) {\n if (op) this.iterN(from - this.first, to - from, op);\n else this.iterN(this.first, this.first + this.size, from);\n },\n\n // Non-public interface for adding and removing lines.\n insert: function(at, lines) {\n var height = 0;\n for (var i = 0; i < lines.length; ++i) height += lines[i].height;\n this.insertInner(at - this.first, lines, height);\n },\n remove: function(at, n) { this.removeInner(at - this.first, n); },\n\n // From here, the methods are part of the public interface. Most\n // are also available from CodeMirror (editor) instances.\n\n getValue: function(lineSep) {\n var lines = getLines(this, this.first, this.first + this.size);\n if (lineSep === false) return lines;\n return lines.join(lineSep || \"\\n\");\n },\n setValue: docMethodOp(function(code) {\n var top = Pos(this.first, 0), last = this.first + this.size - 1;\n makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),\n text: splitLines(code), origin: \"setValue\", full: true}, true);\n setSelection(this, simpleSelection(top));\n }),\n replaceRange: function(code, from, to, origin) {\n from = clipPos(this, from);\n to = to ? clipPos(this, to) : from;\n replaceRange(this, code, from, to, origin);\n },\n getRange: function(from, to, lineSep) {\n var lines = getBetween(this, clipPos(this, from), clipPos(this, to));\n if (lineSep === false) return lines;\n return lines.join(lineSep || \"\\n\");\n },\n\n getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},\n\n getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},\n getLineNumber: function(line) {return lineNo(line);},\n\n getLineHandleVisualStart: function(line) {\n if (typeof line == \"number\") line = getLine(this, line);\n return visualLine(line);\n },\n\n lineCount: function() {return this.size;},\n firstLine: function() {return this.first;},\n lastLine: function() {return this.first + this.size - 1;},\n\n clipPos: function(pos) {return clipPos(this, pos);},\n\n getCursor: function(start) {\n var range = this.sel.primary(), pos;\n if (start == null || start == \"head\") pos = range.head;\n else if (start == \"anchor\") pos = range.anchor;\n else if (start == \"end\" || start == \"to\" || start === false) pos = range.to();\n else pos = range.from();\n return pos;\n },\n listSelections: function() { return this.sel.ranges; },\n somethingSelected: function() {return this.sel.somethingSelected();},\n\n setCursor: docMethodOp(function(line, ch, options) {\n setSimpleSelection(this, clipPos(this, typeof line == \"number\" ? Pos(line, ch || 0) : line), null, options);\n }),\n setSelection: docMethodOp(function(anchor, head, options) {\n setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);\n }),\n extendSelection: docMethodOp(function(head, other, options) {\n extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);\n }),\n extendSelections: docMethodOp(function(heads, options) {\n extendSelections(this, clipPosArray(this, heads, options));\n }),\n extendSelectionsBy: docMethodOp(function(f, options) {\n extendSelections(this, map(this.sel.ranges, f), options);\n }),\n setSelections: docMethodOp(function(ranges, primary, options) {\n if (!ranges.length) return;\n for (var i = 0, out = []; i < ranges.length; i++)\n out[i] = new Range(clipPos(this, ranges[i].anchor),\n clipPos(this, ranges[i].head));\n if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex);\n setSelection(this, normalizeSelection(out, primary), options);\n }),\n addSelection: docMethodOp(function(anchor, head, options) {\n var ranges = this.sel.ranges.slice(0);\n ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));\n setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);\n }),\n\n getSelection: function(lineSep) {\n var ranges = this.sel.ranges, lines;\n for (var i = 0; i < ranges.length; i++) {\n var sel = getBetween(this, ranges[i].from(), ranges[i].to());\n lines = lines ? lines.concat(sel) : sel;\n }\n if (lineSep === false) return lines;\n else return lines.join(lineSep || \"\\n\");\n },\n getSelections: function(lineSep) {\n var parts = [], ranges = this.sel.ranges;\n for (var i = 0; i < ranges.length; i++) {\n var sel = getBetween(this, ranges[i].from(), ranges[i].to());\n if (lineSep !== false) sel = sel.join(lineSep || \"\\n\");\n parts[i] = sel;\n }\n return parts;\n },\n replaceSelection: function(code, collapse, origin) {\n var dup = [];\n for (var i = 0; i < this.sel.ranges.length; i++)\n dup[i] = code;\n this.replaceSelections(dup, collapse, origin || \"+input\");\n },\n replaceSelections: docMethodOp(function(code, collapse, origin) {\n var changes = [], sel = this.sel;\n for (var i = 0; i < sel.ranges.length; i++) {\n var range = sel.ranges[i];\n changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};\n }\n var newSel = collapse && collapse != \"end\" && computeReplacedSel(this, changes, collapse);\n for (var i = changes.length - 1; i >= 0; i--)\n makeChange(this, changes[i]);\n if (newSel) setSelectionReplaceHistory(this, newSel);\n else if (this.cm) ensureCursorVisible(this.cm);\n }),\n undo: docMethodOp(function() {makeChangeFromHistory(this, \"undo\");}),\n redo: docMethodOp(function() {makeChangeFromHistory(this, \"redo\");}),\n undoSelection: docMethodOp(function() {makeChangeFromHistory(this, \"undo\", true);}),\n redoSelection: docMethodOp(function() {makeChangeFromHistory(this, \"redo\", true);}),\n\n setExtending: function(val) {this.extend = val;},\n getExtending: function() {return this.extend;},\n\n historySize: function() {\n var hist = this.history, done = 0, undone = 0;\n for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done;\n for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone;\n return {undo: done, redo: undone};\n },\n clearHistory: function() {this.history = new History(this.history.maxGeneration);},\n\n markClean: function() {\n this.cleanGeneration = this.changeGeneration(true);\n },\n changeGeneration: function(forceSplit) {\n if (forceSplit)\n this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null;\n return this.history.generation;\n },\n isClean: function (gen) {\n return this.history.generation == (gen || this.cleanGeneration);\n },\n\n getHistory: function() {\n return {done: copyHistoryArray(this.history.done),\n undone: copyHistoryArray(this.history.undone)};\n },\n setHistory: function(histData) {\n var hist = this.history = new History(this.history.maxGeneration);\n hist.done = copyHistoryArray(histData.done.slice(0), null, true);\n hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);\n },\n\n addLineClass: docMethodOp(function(handle, where, cls) {\n return changeLine(this, handle, where == \"gutter\" ? \"gutter\" : \"class\", function(line) {\n var prop = where == \"text\" ? \"textClass\"\n : where == \"background\" ? \"bgClass\"\n : where == \"gutter\" ? \"gutterClass\" : \"wrapClass\";\n if (!line[prop]) line[prop] = cls;\n else if (classTest(cls).test(line[prop])) return false;\n else line[prop] += \" \" + cls;\n return true;\n });\n }),\n removeLineClass: docMethodOp(function(handle, where, cls) {\n return changeLine(this, handle, where == \"gutter\" ? \"gutter\" : \"class\", function(line) {\n var prop = where == \"text\" ? \"textClass\"\n : where == \"background\" ? \"bgClass\"\n : where == \"gutter\" ? \"gutterClass\" : \"wrapClass\";\n var cur = line[prop];\n if (!cur) return false;\n else if (cls == null) line[prop] = null;\n else {\n var found = cur.match(classTest(cls));\n if (!found) return false;\n var end = found.index + found[0].length;\n line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? \"\" : \" \") + cur.slice(end) || null;\n }\n return true;\n });\n }),\n\n markText: function(from, to, options) {\n return markText(this, clipPos(this, from), clipPos(this, to), options, \"range\");\n },\n setBookmark: function(pos, options) {\n var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),\n insertLeft: options && options.insertLeft,\n clearWhenEmpty: false, shared: options && options.shared};\n pos = clipPos(this, pos);\n return markText(this, pos, pos, realOpts, \"bookmark\");\n },\n findMarksAt: function(pos) {\n pos = clipPos(this, pos);\n var markers = [], spans = getLine(this, pos.line).markedSpans;\n if (spans) for (var i = 0; i < spans.length; ++i) {\n var span = spans[i];\n if ((span.from == null || span.from <= pos.ch) &&\n (span.to == null || span.to >= pos.ch))\n markers.push(span.marker.parent || span.marker);\n }\n return markers;\n },\n findMarks: function(from, to, filter) {\n from = clipPos(this, from); to = clipPos(this, to);\n var found = [], lineNo = from.line;\n this.iter(from.line, to.line + 1, function(line) {\n var spans = line.markedSpans;\n if (spans) for (var i = 0; i < spans.length; i++) {\n var span = spans[i];\n if (!(lineNo == from.line && from.ch > span.to ||\n span.from == null && lineNo != from.line||\n lineNo == to.line && span.from > to.ch) &&\n (!filter || filter(span.marker)))\n found.push(span.marker.parent || span.marker);\n }\n ++lineNo;\n });\n return found;\n },\n getAllMarks: function() {\n var markers = [];\n this.iter(function(line) {\n var sps = line.markedSpans;\n if (sps) for (var i = 0; i < sps.length; ++i)\n if (sps[i].from != null) markers.push(sps[i].marker);\n });\n return markers;\n },\n\n posFromIndex: function(off) {\n var ch, lineNo = this.first;\n this.iter(function(line) {\n var sz = line.text.length + 1;\n if (sz > off) { ch = off; return true; }\n off -= sz;\n ++lineNo;\n });\n return clipPos(this, Pos(lineNo, ch));\n },\n indexFromPos: function (coords) {\n coords = clipPos(this, coords);\n var index = coords.ch;\n if (coords.line < this.first || coords.ch < 0) return 0;\n this.iter(this.first, coords.line, function (line) {\n index += line.text.length + 1;\n });\n return index;\n },\n\n copy: function(copyHistory) {\n var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);\n doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;\n doc.sel = this.sel;\n doc.extend = false;\n if (copyHistory) {\n doc.history.undoDepth = this.history.undoDepth;\n doc.setHistory(this.getHistory());\n }\n return doc;\n },\n\n linkedDoc: function(options) {\n if (!options) options = {};\n var from = this.first, to = this.first + this.size;\n if (options.from != null && options.from > from) from = options.from;\n if (options.to != null && options.to < to) to = options.to;\n var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);\n if (options.sharedHist) copy.history = this.history;\n (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});\n copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];\n copySharedMarkers(copy, findSharedMarkers(this));\n return copy;\n },\n unlinkDoc: function(other) {\n if (other instanceof CodeMirror) other = other.doc;\n if (this.linked) for (var i = 0; i < this.linked.length; ++i) {\n var link = this.linked[i];\n if (link.doc != other) continue;\n this.linked.splice(i, 1);\n other.unlinkDoc(this);\n detachSharedMarkers(findSharedMarkers(this));\n break;\n }\n // If the histories were shared, split them again\n if (other.history == this.history) {\n var splitIds = [other.id];\n linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);\n other.history = new History(null);\n other.history.done = copyHistoryArray(this.history.done, splitIds);\n other.history.undone = copyHistoryArray(this.history.undone, splitIds);\n }\n },\n iterLinkedDocs: function(f) {linkedDocs(this, f);},\n\n getMode: function() {return this.mode;},\n getEditor: function() {return this.cm;}\n });\n\n // Public alias.\n Doc.prototype.eachLine = Doc.prototype.iter;\n\n // Set up methods on CodeMirror's prototype to redirect to the editor's document.\n var dontDelegate = \"iter insert remove copy getEditor\".split(\" \");\n for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)\n CodeMirror.prototype[prop] = (function(method) {\n return function() {return method.apply(this.doc, arguments);};\n })(Doc.prototype[prop]);\n\n eventMixin(Doc);\n\n // Call f for all linked documents.\n function linkedDocs(doc, f, sharedHistOnly) {\n function propagate(doc, skip, sharedHist) {\n if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {\n var rel = doc.linked[i];\n if (rel.doc == skip) continue;\n var shared = sharedHist && rel.sharedHist;\n if (sharedHistOnly && !shared) continue;\n f(rel.doc, shared);\n propagate(rel.doc, doc, shared);\n }\n }\n propagate(doc, null, true);\n }\n\n // Attach a document to an editor.\n function attachDoc(cm, doc) {\n if (doc.cm) throw new Error(\"This document is already in use.\");\n cm.doc = doc;\n doc.cm = cm;\n estimateLineHeights(cm);\n loadMode(cm);\n if (!cm.options.lineWrapping) findMaxLine(cm);\n cm.options.mode = doc.modeOption;\n regChange(cm);\n }\n\n // LINE UTILITIES\n\n // Find the line object corresponding to the given line number.\n function getLine(doc, n) {\n n -= doc.first;\n if (n < 0 || n >= doc.size) throw new Error(\"There is no line \" + (n + doc.first) + \" in the document.\");\n for (var chunk = doc; !chunk.lines;) {\n for (var i = 0;; ++i) {\n var child = chunk.children[i], sz = child.chunkSize();\n if (n < sz) { chunk = child; break; }\n n -= sz;\n }\n }\n return chunk.lines[n];\n }\n\n // Get the part of a document between two positions, as an array of\n // strings.\n function getBetween(doc, start, end) {\n var out = [], n = start.line;\n doc.iter(start.line, end.line + 1, function(line) {\n var text = line.text;\n if (n == end.line) text = text.slice(0, end.ch);\n if (n == start.line) text = text.slice(start.ch);\n out.push(text);\n ++n;\n });\n return out;\n }\n // Get the lines between from and to, as array of strings.\n function getLines(doc, from, to) {\n var out = [];\n doc.iter(from, to, function(line) { out.push(line.text); });\n return out;\n }\n\n // Update the height of a line, propagating the height change\n // upwards to parent nodes.\n function updateLineHeight(line, height) {\n var diff = height - line.height;\n if (diff) for (var n = line; n; n = n.parent) n.height += diff;\n }\n\n // Given a line object, find its line number by walking up through\n // its parent links.\n function lineNo(line) {\n if (line.parent == null) return null;\n var cur = line.parent, no = indexOf(cur.lines, line);\n for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {\n for (var i = 0;; ++i) {\n if (chunk.children[i] == cur) break;\n no += chunk.children[i].chunkSize();\n }\n }\n return no + cur.first;\n }\n\n // Find the line at the given vertical position, using the height\n // information in the document tree.\n function lineAtHeight(chunk, h) {\n var n = chunk.first;\n outer: do {\n for (var i = 0; i < chunk.children.length; ++i) {\n var child = chunk.children[i], ch = child.height;\n if (h < ch) { chunk = child; continue outer; }\n h -= ch;\n n += child.chunkSize();\n }\n return n;\n } while (!chunk.lines);\n for (var i = 0; i < chunk.lines.length; ++i) {\n var line = chunk.lines[i], lh = line.height;\n if (h < lh) break;\n h -= lh;\n }\n return n + i;\n }\n\n\n // Find the height above the given line.\n function heightAtLine(lineObj) {\n lineObj = visualLine(lineObj);\n\n var h = 0, chunk = lineObj.parent;\n for (var i = 0; i < chunk.lines.length; ++i) {\n var line = chunk.lines[i];\n if (line == lineObj) break;\n else h += line.height;\n }\n for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {\n for (var i = 0; i < p.children.length; ++i) {\n var cur = p.children[i];\n if (cur == chunk) break;\n else h += cur.height;\n }\n }\n return h;\n }\n\n // Get the bidi ordering for the given line (and cache it). Returns\n // false for lines that are fully left-to-right, and an array of\n // BidiSpan objects otherwise.\n function getOrder(line) {\n var order = line.order;\n if (order == null) order = line.order = bidiOrdering(line.text);\n return order;\n }\n\n // HISTORY\n\n function History(startGen) {\n // Arrays of change events and selections. Doing something adds an\n // event to done and clears undo. Undoing moves events from done\n // to undone, redoing moves them in the other direction.\n this.done = []; this.undone = [];\n this.undoDepth = Infinity;\n // Used to track when changes can be merged into a single undo\n // event\n this.lastModTime = this.lastSelTime = 0;\n this.lastOp = this.lastSelOp = null;\n this.lastOrigin = this.lastSelOrigin = null;\n // Used by the isClean() method\n this.generation = this.maxGeneration = startGen || 1;\n }\n\n // Create a history change event from an updateDoc-style change\n // object.\n function historyChangeFromChange(doc, change) {\n var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};\n attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);\n linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);\n return histChange;\n }\n\n // Pop all selection events off the end of a history array. Stop at\n // a change event.\n function clearSelectionEvents(array) {\n while (array.length) {\n var last = lst(array);\n if (last.ranges) array.pop();\n else break;\n }\n }\n\n // Find the top change event in the history. Pop off selection\n // events that are in the way.\n function lastChangeEvent(hist, force) {\n if (force) {\n clearSelectionEvents(hist.done);\n return lst(hist.done);\n } else if (hist.done.length && !lst(hist.done).ranges) {\n return lst(hist.done);\n } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {\n hist.done.pop();\n return lst(hist.done);\n }\n }\n\n // Register a change in the history. Merges changes that are within\n // a single operation, ore are close together with an origin that\n // allows merging (starting with \"+\") into a single event.\n function addChangeToHistory(doc, change, selAfter, opId) {\n var hist = doc.history;\n hist.undone.length = 0;\n var time = +new Date, cur;\n\n if ((hist.lastOp == opId ||\n hist.lastOrigin == change.origin && change.origin &&\n ((change.origin.charAt(0) == \"+\" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||\n change.origin.charAt(0) == \"*\")) &&\n (cur = lastChangeEvent(hist, hist.lastOp == opId))) {\n // Merge this change into the last event\n var last = lst(cur.changes);\n if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {\n // Optimized case for simple insertion -- don't want to add\n // new changesets for every character typed\n last.to = changeEnd(change);\n } else {\n // Add new sub-event\n cur.changes.push(historyChangeFromChange(doc, change));\n }\n } else {\n // Can not be merged, start a new event.\n var before = lst(hist.done);\n if (!before || !before.ranges)\n pushSelectionToHistory(doc.sel, hist.done);\n cur = {changes: [historyChangeFromChange(doc, change)],\n generation: hist.generation};\n hist.done.push(cur);\n while (hist.done.length > hist.undoDepth) {\n hist.done.shift();\n if (!hist.done[0].ranges) hist.done.shift();\n }\n }\n hist.done.push(selAfter);\n hist.generation = ++hist.maxGeneration;\n hist.lastModTime = hist.lastSelTime = time;\n hist.lastOp = hist.lastSelOp = opId;\n hist.lastOrigin = hist.lastSelOrigin = change.origin;\n\n if (!last) signal(doc, \"historyAdded\");\n }\n\n function selectionEventCanBeMerged(doc, origin, prev, sel) {\n var ch = origin.charAt(0);\n return ch == \"*\" ||\n ch == \"+\" &&\n prev.ranges.length == sel.ranges.length &&\n prev.somethingSelected() == sel.somethingSelected() &&\n new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500);\n }\n\n // Called whenever the selection changes, sets the new selection as\n // the pending selection in the history, and pushes the old pending\n // selection into the 'done' array when it was significantly\n // different (in number of selected ranges, emptiness, or time).\n function addSelectionToHistory(doc, sel, opId, options) {\n var hist = doc.history, origin = options && options.origin;\n\n // A new event is started when the previous origin does not match\n // the current, or the origins don't allow matching. Origins\n // starting with * are always merged, those starting with + are\n // merged when similar and close together in time.\n if (opId == hist.lastSelOp ||\n (origin && hist.lastSelOrigin == origin &&\n (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||\n selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))\n hist.done[hist.done.length - 1] = sel;\n else\n pushSelectionToHistory(sel, hist.done);\n\n hist.lastSelTime = +new Date;\n hist.lastSelOrigin = origin;\n hist.lastSelOp = opId;\n if (options && options.clearRedo !== false)\n clearSelectionEvents(hist.undone);\n }\n\n function pushSelectionToHistory(sel, dest) {\n var top = lst(dest);\n if (!(top && top.ranges && top.equals(sel)))\n dest.push(sel);\n }\n\n // Used to store marked span information in the history.\n function attachLocalSpans(doc, change, from, to) {\n var existing = change[\"spans_\" + doc.id], n = 0;\n doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {\n if (line.markedSpans)\n (existing || (existing = change[\"spans_\" + doc.id] = {}))[n] = line.markedSpans;\n ++n;\n });\n }\n\n // When un/re-doing restores text containing marked spans, those\n // that have been explicitly cleared should not be restored.\n function removeClearedSpans(spans) {\n if (!spans) return null;\n for (var i = 0, out; i < spans.length; ++i) {\n if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }\n else if (out) out.push(spans[i]);\n }\n return !out ? spans : out.length ? out : null;\n }\n\n // Retrieve and filter the old marked spans stored in a change event.\n function getOldSpans(doc, change) {\n var found = change[\"spans_\" + doc.id];\n if (!found) return null;\n for (var i = 0, nw = []; i < change.text.length; ++i)\n nw.push(removeClearedSpans(found[i]));\n return nw;\n }\n\n // Used both to provide a JSON-safe object in .getHistory, and, when\n // detaching a document, to split the history in two\n function copyHistoryArray(events, newGroup, instantiateSel) {\n for (var i = 0, copy = []; i < events.length; ++i) {\n var event = events[i];\n if (event.ranges) {\n copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);\n continue;\n }\n var changes = event.changes, newChanges = [];\n copy.push({changes: newChanges});\n for (var j = 0; j < changes.length; ++j) {\n var change = changes[j], m;\n newChanges.push({from: change.from, to: change.to, text: change.text});\n if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\\d+)$/)) {\n if (indexOf(newGroup, Number(m[1])) > -1) {\n lst(newChanges)[prop] = change[prop];\n delete change[prop];\n }\n }\n }\n }\n return copy;\n }\n\n // Rebasing/resetting history to deal with externally-sourced changes\n\n function rebaseHistSelSingle(pos, from, to, diff) {\n if (to < pos.line) {\n pos.line += diff;\n } else if (from < pos.line) {\n pos.line = from;\n pos.ch = 0;\n }\n }\n\n // Tries to rebase an array of history events given a change in the\n // document. If the change touches the same lines as the event, the\n // event, and everything 'behind' it, is discarded. If the change is\n // before the event, the event's positions are updated. Uses a\n // copy-on-write scheme for the positions, to avoid having to\n // reallocate them all on every rebase, but also avoid problems with\n // shared position objects being unsafely updated.\n function rebaseHistArray(array, from, to, diff) {\n for (var i = 0; i < array.length; ++i) {\n var sub = array[i], ok = true;\n if (sub.ranges) {\n if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }\n for (var j = 0; j < sub.ranges.length; j++) {\n rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);\n rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);\n }\n continue;\n }\n for (var j = 0; j < sub.changes.length; ++j) {\n var cur = sub.changes[j];\n if (to < cur.from.line) {\n cur.from = Pos(cur.from.line + diff, cur.from.ch);\n cur.to = Pos(cur.to.line + diff, cur.to.ch);\n } else if (from <= cur.to.line) {\n ok = false;\n break;\n }\n }\n if (!ok) {\n array.splice(0, i + 1);\n i = 0;\n }\n }\n }\n\n function rebaseHist(hist, change) {\n var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;\n rebaseHistArray(hist.done, from, to, diff);\n rebaseHistArray(hist.undone, from, to, diff);\n }\n\n // EVENT UTILITIES\n\n // Due to the fact that we still support jurassic IE versions, some\n // compatibility wrappers are needed.\n\n var e_preventDefault = CodeMirror.e_preventDefault = function(e) {\n if (e.preventDefault) e.preventDefault();\n else e.returnValue = false;\n };\n var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) {\n if (e.stopPropagation) e.stopPropagation();\n else e.cancelBubble = true;\n };\n function e_defaultPrevented(e) {\n return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;\n }\n var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);};\n\n function e_target(e) {return e.target || e.srcElement;}\n function e_button(e) {\n var b = e.which;\n if (b == null) {\n if (e.button & 1) b = 1;\n else if (e.button & 2) b = 3;\n else if (e.button & 4) b = 2;\n }\n if (mac && e.ctrlKey && b == 1) b = 3;\n return b;\n }\n\n // EVENT HANDLING\n\n // Lightweight event framework. on/off also work on DOM nodes,\n // registering native DOM handlers.\n\n var on = CodeMirror.on = function(emitter, type, f) {\n if (emitter.addEventListener)\n emitter.addEventListener(type, f, false);\n else if (emitter.attachEvent)\n emitter.attachEvent(\"on\" + type, f);\n else {\n var map = emitter._handlers || (emitter._handlers = {});\n var arr = map[type] || (map[type] = []);\n arr.push(f);\n }\n };\n\n var off = CodeMirror.off = function(emitter, type, f) {\n if (emitter.removeEventListener)\n emitter.removeEventListener(type, f, false);\n else if (emitter.detachEvent)\n emitter.detachEvent(\"on\" + type, f);\n else {\n var arr = emitter._handlers && emitter._handlers[type];\n if (!arr) return;\n for (var i = 0; i < arr.length; ++i)\n if (arr[i] == f) { arr.splice(i, 1); break; }\n }\n };\n\n var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {\n var arr = emitter._handlers && emitter._handlers[type];\n if (!arr) return;\n var args = Array.prototype.slice.call(arguments, 2);\n for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);\n };\n\n var orphanDelayedCallbacks = null;\n\n // Often, we want to signal events at a point where we are in the\n // middle of some work, but don't want the handler to start calling\n // other methods on the editor, which might be in an inconsistent\n // state or simply not expect any other events to happen.\n // signalLater looks whether there are any handlers, and schedules\n // them to be executed when the last operation ends, or, if no\n // operation is active, when a timeout fires.\n function signalLater(emitter, type /*, values...*/) {\n var arr = emitter._handlers && emitter._handlers[type];\n if (!arr) return;\n var args = Array.prototype.slice.call(arguments, 2), list;\n if (operationGroup) {\n list = operationGroup.delayedCallbacks;\n } else if (orphanDelayedCallbacks) {\n list = orphanDelayedCallbacks;\n } else {\n list = orphanDelayedCallbacks = [];\n setTimeout(fireOrphanDelayed, 0);\n }\n function bnd(f) {return function(){f.apply(null, args);};};\n for (var i = 0; i < arr.length; ++i)\n list.push(bnd(arr[i]));\n }\n\n function fireOrphanDelayed() {\n var delayed = orphanDelayedCallbacks;\n orphanDelayedCallbacks = null;\n for (var i = 0; i < delayed.length; ++i) delayed[i]();\n }\n\n // The DOM events that CodeMirror handles can be overridden by\n // registering a (non-DOM) handler on the editor for the event name,\n // and preventDefault-ing the event in that handler.\n function signalDOMEvent(cm, e, override) {\n if (typeof e == \"string\")\n e = {type: e, preventDefault: function() { this.defaultPrevented = true; }};\n signal(cm, override || e.type, cm, e);\n return e_defaultPrevented(e) || e.codemirrorIgnore;\n }\n\n function signalCursorActivity(cm) {\n var arr = cm._handlers && cm._handlers.cursorActivity;\n if (!arr) return;\n var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);\n for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1)\n set.push(arr[i]);\n }\n\n function hasHandler(emitter, type) {\n var arr = emitter._handlers && emitter._handlers[type];\n return arr && arr.length > 0;\n }\n\n // Add on and off methods to a constructor's prototype, to make\n // registering events on such objects more convenient.\n function eventMixin(ctor) {\n ctor.prototype.on = function(type, f) {on(this, type, f);};\n ctor.prototype.off = function(type, f) {off(this, type, f);};\n }\n\n // MISC UTILITIES\n\n // Number of pixels added to scroller and sizer to hide scrollbar\n var scrollerGap = 30;\n\n // Returned or thrown by various protocols to signal 'I'm not\n // handling this'.\n var Pass = CodeMirror.Pass = {toString: function(){return \"CodeMirror.Pass\";}};\n\n // Reused option objects for setSelection & friends\n var sel_dontScroll = {scroll: false}, sel_mouse = {origin: \"*mouse\"}, sel_move = {origin: \"+move\"};\n\n function Delayed() {this.id = null;}\n Delayed.prototype.set = function(ms, f) {\n clearTimeout(this.id);\n this.id = setTimeout(f, ms);\n };\n\n // Counts the column offset in a string, taking tabs into account.\n // Used mostly to find indentation.\n var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) {\n if (end == null) {\n end = string.search(/[^\\s\\u00a0]/);\n if (end == -1) end = string.length;\n }\n for (var i = startIndex || 0, n = startValue || 0;;) {\n var nextTab = string.indexOf(\"\\t\", i);\n if (nextTab < 0 || nextTab >= end)\n return n + (end - i);\n n += nextTab - i;\n n += tabSize - (n % tabSize);\n i = nextTab + 1;\n }\n };\n\n // The inverse of countColumn -- find the offset that corresponds to\n // a particular column.\n function findColumn(string, goal, tabSize) {\n for (var pos = 0, col = 0;;) {\n var nextTab = string.indexOf(\"\\t\", pos);\n if (nextTab == -1) nextTab = string.length;\n var skipped = nextTab - pos;\n if (nextTab == string.length || col + skipped >= goal)\n return pos + Math.min(skipped, goal - col);\n col += nextTab - pos;\n col += tabSize - (col % tabSize);\n pos = nextTab + 1;\n if (col >= goal) return pos;\n }\n }\n\n var spaceStrs = [\"\"];\n function spaceStr(n) {\n while (spaceStrs.length <= n)\n spaceStrs.push(lst(spaceStrs) + \" \");\n return spaceStrs[n];\n }\n\n function lst(arr) { return arr[arr.length-1]; }\n\n var selectInput = function(node) { node.select(); };\n if (ios) // Mobile Safari apparently has a bug where select() is broken.\n selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; };\n else if (ie) // Suppress mysterious IE10 errors\n selectInput = function(node) { try { node.select(); } catch(_e) {} };\n\n function indexOf(array, elt) {\n for (var i = 0; i < array.length; ++i)\n if (array[i] == elt) return i;\n return -1;\n }\n function map(array, f) {\n var out = [];\n for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);\n return out;\n }\n\n function createObj(base, props) {\n var inst;\n if (Object.create) {\n inst = Object.create(base);\n } else {\n var ctor = function() {};\n ctor.prototype = base;\n inst = new ctor();\n }\n if (props) copyObj(props, inst);\n return inst;\n };\n\n function copyObj(obj, target, overwrite) {\n if (!target) target = {};\n for (var prop in obj)\n if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))\n target[prop] = obj[prop];\n return target;\n }\n\n function bind(f) {\n var args = Array.prototype.slice.call(arguments, 1);\n return function(){return f.apply(null, args);};\n }\n\n var nonASCIISingleCaseWordChar = /[\\u00df\\u0590-\\u05f4\\u0600-\\u06ff\\u3040-\\u309f\\u30a0-\\u30ff\\u3400-\\u4db5\\u4e00-\\u9fcc\\uac00-\\ud7af]/;\n var isWordCharBasic = CodeMirror.isWordChar = function(ch) {\n return /\\w/.test(ch) || ch > \"\\x80\" &&\n (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));\n };\n function isWordChar(ch, helper) {\n if (!helper) return isWordCharBasic(ch);\n if (helper.source.indexOf(\"\\\\w\") > -1 && isWordCharBasic(ch)) return true;\n return helper.test(ch);\n }\n\n function isEmpty(obj) {\n for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;\n return true;\n }\n\n // Extending unicode characters. A series of a non-extending char +\n // any number of extending chars is treated as a single unit as far\n // as editing and measuring is concerned. This is not fully correct,\n // since some scripts/fonts/browsers also treat other configurations\n // of code points as a group.\n var extendingChars = /[\\u0300-\\u036f\\u0483-\\u0489\\u0591-\\u05bd\\u05bf\\u05c1\\u05c2\\u05c4\\u05c5\\u05c7\\u0610-\\u061a\\u064b-\\u065e\\u0670\\u06d6-\\u06dc\\u06de-\\u06e4\\u06e7\\u06e8\\u06ea-\\u06ed\\u0711\\u0730-\\u074a\\u07a6-\\u07b0\\u07eb-\\u07f3\\u0816-\\u0819\\u081b-\\u0823\\u0825-\\u0827\\u0829-\\u082d\\u0900-\\u0902\\u093c\\u0941-\\u0948\\u094d\\u0951-\\u0955\\u0962\\u0963\\u0981\\u09bc\\u09be\\u09c1-\\u09c4\\u09cd\\u09d7\\u09e2\\u09e3\\u0a01\\u0a02\\u0a3c\\u0a41\\u0a42\\u0a47\\u0a48\\u0a4b-\\u0a4d\\u0a51\\u0a70\\u0a71\\u0a75\\u0a81\\u0a82\\u0abc\\u0ac1-\\u0ac5\\u0ac7\\u0ac8\\u0acd\\u0ae2\\u0ae3\\u0b01\\u0b3c\\u0b3e\\u0b3f\\u0b41-\\u0b44\\u0b4d\\u0b56\\u0b57\\u0b62\\u0b63\\u0b82\\u0bbe\\u0bc0\\u0bcd\\u0bd7\\u0c3e-\\u0c40\\u0c46-\\u0c48\\u0c4a-\\u0c4d\\u0c55\\u0c56\\u0c62\\u0c63\\u0cbc\\u0cbf\\u0cc2\\u0cc6\\u0ccc\\u0ccd\\u0cd5\\u0cd6\\u0ce2\\u0ce3\\u0d3e\\u0d41-\\u0d44\\u0d4d\\u0d57\\u0d62\\u0d63\\u0dca\\u0dcf\\u0dd2-\\u0dd4\\u0dd6\\u0ddf\\u0e31\\u0e34-\\u0e3a\\u0e47-\\u0e4e\\u0eb1\\u0eb4-\\u0eb9\\u0ebb\\u0ebc\\u0ec8-\\u0ecd\\u0f18\\u0f19\\u0f35\\u0f37\\u0f39\\u0f71-\\u0f7e\\u0f80-\\u0f84\\u0f86\\u0f87\\u0f90-\\u0f97\\u0f99-\\u0fbc\\u0fc6\\u102d-\\u1030\\u1032-\\u1037\\u1039\\u103a\\u103d\\u103e\\u1058\\u1059\\u105e-\\u1060\\u1071-\\u1074\\u1082\\u1085\\u1086\\u108d\\u109d\\u135f\\u1712-\\u1714\\u1732-\\u1734\\u1752\\u1753\\u1772\\u1773\\u17b7-\\u17bd\\u17c6\\u17c9-\\u17d3\\u17dd\\u180b-\\u180d\\u18a9\\u1920-\\u1922\\u1927\\u1928\\u1932\\u1939-\\u193b\\u1a17\\u1a18\\u1a56\\u1a58-\\u1a5e\\u1a60\\u1a62\\u1a65-\\u1a6c\\u1a73-\\u1a7c\\u1a7f\\u1b00-\\u1b03\\u1b34\\u1b36-\\u1b3a\\u1b3c\\u1b42\\u1b6b-\\u1b73\\u1b80\\u1b81\\u1ba2-\\u1ba5\\u1ba8\\u1ba9\\u1c2c-\\u1c33\\u1c36\\u1c37\\u1cd0-\\u1cd2\\u1cd4-\\u1ce0\\u1ce2-\\u1ce8\\u1ced\\u1dc0-\\u1de6\\u1dfd-\\u1dff\\u200c\\u200d\\u20d0-\\u20f0\\u2cef-\\u2cf1\\u2de0-\\u2dff\\u302a-\\u302f\\u3099\\u309a\\ua66f-\\ua672\\ua67c\\ua67d\\ua6f0\\ua6f1\\ua802\\ua806\\ua80b\\ua825\\ua826\\ua8c4\\ua8e0-\\ua8f1\\ua926-\\ua92d\\ua947-\\ua951\\ua980-\\ua982\\ua9b3\\ua9b6-\\ua9b9\\ua9bc\\uaa29-\\uaa2e\\uaa31\\uaa32\\uaa35\\uaa36\\uaa43\\uaa4c\\uaab0\\uaab2-\\uaab4\\uaab7\\uaab8\\uaabe\\uaabf\\uaac1\\uabe5\\uabe8\\uabed\\udc00-\\udfff\\ufb1e\\ufe00-\\ufe0f\\ufe20-\\ufe26\\uff9e\\uff9f]/;\n function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }\n\n // DOM UTILITIES\n\n function elt(tag, content, className, style) {\n var e = document.createElement(tag);\n if (className) e.className = className;\n if (style) e.style.cssText = style;\n if (typeof content == \"string\") e.appendChild(document.createTextNode(content));\n else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);\n return e;\n }\n\n var range;\n if (document.createRange) range = function(node, start, end) {\n var r = document.createRange();\n r.setEnd(node, end);\n r.setStart(node, start);\n return r;\n };\n else range = function(node, start, end) {\n var r = document.body.createTextRange();\n try { r.moveToElementText(node.parentNode); }\n catch(e) { return r; }\n r.collapse(true);\n r.moveEnd(\"character\", end);\n r.moveStart(\"character\", start);\n return r;\n };\n\n function removeChildren(e) {\n for (var count = e.childNodes.length; count > 0; --count)\n e.removeChild(e.firstChild);\n return e;\n }\n\n function removeChildrenAndAdd(parent, e) {\n return removeChildren(parent).appendChild(e);\n }\n\n function contains(parent, child) {\n if (parent.contains)\n return parent.contains(child);\n while (child = child.parentNode)\n if (child == parent) return true;\n }\n\n function activeElt() { return document.activeElement; }\n // Older versions of IE throws unspecified error when touching\n // document.activeElement in some cases (during loading, in iframe)\n if (ie && ie_version < 11) activeElt = function() {\n try { return document.activeElement; }\n catch(e) { return document.body; }\n };\n\n function classTest(cls) { return new RegExp(\"(^|\\\\s)\" + cls + \"(?:$|\\\\s)\\\\s*\"); }\n var rmClass = CodeMirror.rmClass = function(node, cls) {\n var current = node.className;\n var match = classTest(cls).exec(current);\n if (match) {\n var after = current.slice(match.index + match[0].length);\n node.className = current.slice(0, match.index) + (after ? match[1] + after : \"\");\n }\n };\n var addClass = CodeMirror.addClass = function(node, cls) {\n var current = node.className;\n if (!classTest(cls).test(current)) node.className += (current ? \" \" : \"\") + cls;\n };\n function joinClasses(a, b) {\n var as = a.split(\" \");\n for (var i = 0; i < as.length; i++)\n if (as[i] && !classTest(as[i]).test(b)) b += \" \" + as[i];\n return b;\n }\n\n // WINDOW-WIDE EVENTS\n\n // These must be handled carefully, because naively registering a\n // handler for each editor will cause the editors to never be\n // garbage collected.\n\n function forEachCodeMirror(f) {\n if (!document.body.getElementsByClassName) return;\n var byClass = document.body.getElementsByClassName(\"CodeMirror\");\n for (var i = 0; i < byClass.length; i++) {\n var cm = byClass[i].CodeMirror;\n if (cm) f(cm);\n }\n }\n\n var globalsRegistered = false;\n function ensureGlobalHandlers() {\n if (globalsRegistered) return;\n registerGlobalHandlers();\n globalsRegistered = true;\n }\n function registerGlobalHandlers() {\n // When the window resizes, we need to refresh active editors.\n var resizeTimer;\n on(window, \"resize\", function() {\n if (resizeTimer == null) resizeTimer = setTimeout(function() {\n resizeTimer = null;\n forEachCodeMirror(onResize);\n }, 100);\n });\n // When the window loses focus, we want to show the editor as blurred\n on(window, \"blur\", function() {\n forEachCodeMirror(onBlur);\n });\n }\n\n // FEATURE DETECTION\n\n // Detect drag-and-drop\n var dragAndDrop = function() {\n // There is *some* kind of drag-and-drop support in IE6-8, but I\n // couldn't get it to work yet.\n if (ie && ie_version < 9) return false;\n var div = elt('div');\n return \"draggable\" in div || \"dragDrop\" in div;\n }();\n\n var zwspSupported;\n function zeroWidthElement(measure) {\n if (zwspSupported == null) {\n var test = elt(\"span\", \"\\u200b\");\n removeChildrenAndAdd(measure, elt(\"span\", [test, document.createTextNode(\"x\")]));\n if (measure.firstChild.offsetHeight != 0)\n zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8);\n }\n if (zwspSupported) return elt(\"span\", \"\\u200b\");\n else return elt(\"span\", \"\\u00a0\", null, \"display: inline-block; width: 1px; margin-right: -1px\");\n }\n\n // Feature-detect IE's crummy client rect reporting for bidi text\n var badBidiRects;\n function hasBadBidiRects(measure) {\n if (badBidiRects != null) return badBidiRects;\n var txt = removeChildrenAndAdd(measure, document.createTextNode(\"A\\u062eA\"));\n var r0 = range(txt, 0, 1).getBoundingClientRect();\n if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780)\n var r1 = range(txt, 1, 2).getBoundingClientRect();\n return badBidiRects = (r1.right - r0.right < 3);\n }\n\n // See if \"\".split is the broken IE version, if so, provide an\n // alternative way to split lines.\n var splitLines = CodeMirror.splitLines = \"\\n\\nb\".split(/\\n/).length != 3 ? function(string) {\n var pos = 0, result = [], l = string.length;\n while (pos <= l) {\n var nl = string.indexOf(\"\\n\", pos);\n if (nl == -1) nl = string.length;\n var line = string.slice(pos, string.charAt(nl - 1) == \"\\r\" ? nl - 1 : nl);\n var rt = line.indexOf(\"\\r\");\n if (rt != -1) {\n result.push(line.slice(0, rt));\n pos += rt + 1;\n } else {\n result.push(line);\n pos = nl + 1;\n }\n }\n return result;\n } : function(string){return string.split(/\\r\\n?|\\n/);};\n\n var hasSelection = window.getSelection ? function(te) {\n try { return te.selectionStart != te.selectionEnd; }\n catch(e) { return false; }\n } : function(te) {\n try {var range = te.ownerDocument.selection.createRange();}\n catch(e) {}\n if (!range || range.parentElement() != te) return false;\n return range.compareEndPoints(\"StartToEnd\", range) != 0;\n };\n\n var hasCopyEvent = (function() {\n var e = elt(\"div\");\n if (\"oncopy\" in e) return true;\n e.setAttribute(\"oncopy\", \"return;\");\n return typeof e.oncopy == \"function\";\n })();\n\n var badZoomedRects = null;\n function hasBadZoomedRects(measure) {\n if (badZoomedRects != null) return badZoomedRects;\n var node = removeChildrenAndAdd(measure, elt(\"span\", \"x\"));\n var normal = node.getBoundingClientRect();\n var fromRange = range(node, 0, 1).getBoundingClientRect();\n return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1;\n }\n\n // KEY NAMES\n\n var keyNames = {3: \"Enter\", 8: \"Backspace\", 9: \"Tab\", 13: \"Enter\", 16: \"Shift\", 17: \"Ctrl\", 18: \"Alt\",\n 19: \"Pause\", 20: \"CapsLock\", 27: \"Esc\", 32: \"Space\", 33: \"PageUp\", 34: \"PageDown\", 35: \"End\",\n 36: \"Home\", 37: \"Left\", 38: \"Up\", 39: \"Right\", 40: \"Down\", 44: \"PrintScrn\", 45: \"Insert\",\n 46: \"Delete\", 59: \";\", 61: \"=\", 91: \"Mod\", 92: \"Mod\", 93: \"Mod\", 107: \"=\", 109: \"-\", 127: \"Delete\",\n 173: \"-\", 186: \";\", 187: \"=\", 188: \",\", 189: \"-\", 190: \".\", 191: \"/\", 192: \"`\", 219: \"[\", 220: \"\\\\\",\n 221: \"]\", 222: \"'\", 63232: \"Up\", 63233: \"Down\", 63234: \"Left\", 63235: \"Right\", 63272: \"Delete\",\n 63273: \"Home\", 63275: \"End\", 63276: \"PageUp\", 63277: \"PageDown\", 63302: \"Insert\"};\n CodeMirror.keyNames = keyNames;\n (function() {\n // Number keys\n for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);\n // Alphabetic keys\n for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);\n // Function keys\n for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = \"F\" + i;\n })();\n\n // BIDI HELPERS\n\n function iterateBidiSections(order, from, to, f) {\n if (!order) return f(from, to, \"ltr\");\n var found = false;\n for (var i = 0; i < order.length; ++i) {\n var part = order[i];\n if (part.from < to && part.to > from || from == to && part.to == from) {\n f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? \"rtl\" : \"ltr\");\n found = true;\n }\n }\n if (!found) f(from, to, \"ltr\");\n }\n\n function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }\n function bidiRight(part) { return part.level % 2 ? part.from : part.to; }\n\n function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }\n function lineRight(line) {\n var order = getOrder(line);\n if (!order) return line.text.length;\n return bidiRight(lst(order));\n }\n\n function lineStart(cm, lineN) {\n var line = getLine(cm.doc, lineN);\n var visual = visualLine(line);\n if (visual != line) lineN = lineNo(visual);\n var order = getOrder(visual);\n var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);\n return Pos(lineN, ch);\n }\n function lineEnd(cm, lineN) {\n var merged, line = getLine(cm.doc, lineN);\n while (merged = collapsedSpanAtEnd(line)) {\n line = merged.find(1, true).line;\n lineN = null;\n }\n var order = getOrder(line);\n var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);\n return Pos(lineN == null ? lineNo(line) : lineN, ch);\n }\n function lineStartSmart(cm, pos) {\n var start = lineStart(cm, pos.line);\n var line = getLine(cm.doc, start.line);\n var order = getOrder(line);\n if (!order || order[0].level == 0) {\n var firstNonWS = Math.max(0, line.text.search(/\\S/));\n var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;\n return Pos(start.line, inWS ? 0 : firstNonWS);\n }\n return start;\n }\n\n function compareBidiLevel(order, a, b) {\n var linedir = order[0].level;\n if (a == linedir) return true;\n if (b == linedir) return false;\n return a < b;\n }\n var bidiOther;\n function getBidiPartAt(order, pos) {\n bidiOther = null;\n for (var i = 0, found; i < order.length; ++i) {\n var cur = order[i];\n if (cur.from < pos && cur.to > pos) return i;\n if ((cur.from == pos || cur.to == pos)) {\n if (found == null) {\n found = i;\n } else if (compareBidiLevel(order, cur.level, order[found].level)) {\n if (cur.from != cur.to) bidiOther = found;\n return i;\n } else {\n if (cur.from != cur.to) bidiOther = i;\n return found;\n }\n }\n }\n return found;\n }\n\n function moveInLine(line, pos, dir, byUnit) {\n if (!byUnit) return pos + dir;\n do pos += dir;\n while (pos > 0 && isExtendingChar(line.text.charAt(pos)));\n return pos;\n }\n\n // This is needed in order to move 'visually' through bi-directional\n // text -- i.e., pressing left should make the cursor go left, even\n // when in RTL text. The tricky part is the 'jumps', where RTL and\n // LTR text touch each other. This often requires the cursor offset\n // to move more than one unit, in order to visually move one unit.\n function moveVisually(line, start, dir, byUnit) {\n var bidi = getOrder(line);\n if (!bidi) return moveLogically(line, start, dir, byUnit);\n var pos = getBidiPartAt(bidi, start), part = bidi[pos];\n var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);\n\n for (;;) {\n if (target > part.from && target < part.to) return target;\n if (target == part.from || target == part.to) {\n if (getBidiPartAt(bidi, target) == pos) return target;\n part = bidi[pos += dir];\n return (dir > 0) == part.level % 2 ? part.to : part.from;\n } else {\n part = bidi[pos += dir];\n if (!part) return null;\n if ((dir > 0) == part.level % 2)\n target = moveInLine(line, part.to, -1, byUnit);\n else\n target = moveInLine(line, part.from, 1, byUnit);\n }\n }\n }\n\n function moveLogically(line, start, dir, byUnit) {\n var target = start + dir;\n if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;\n return target < 0 || target > line.text.length ? null : target;\n }\n\n // Bidirectional ordering algorithm\n // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm\n // that this (partially) implements.\n\n // One-char codes used for character types:\n // L (L): Left-to-Right\n // R (R): Right-to-Left\n // r (AL): Right-to-Left Arabic\n // 1 (EN): European Number\n // + (ES): European Number Separator\n // % (ET): European Number Terminator\n // n (AN): Arabic Number\n // , (CS): Common Number Separator\n // m (NSM): Non-Spacing Mark\n // b (BN): Boundary Neutral\n // s (B): Paragraph Separator\n // t (S): Segment Separator\n // w (WS): Whitespace\n // N (ON): Other Neutrals\n\n // Returns null if characters are ordered as they appear\n // (left-to-right), or an array of sections ({from, to, level}\n // objects) in the order in which they occur visually.\n var bidiOrdering = (function() {\n // Character types for codepoints 0 to 0xff\n var lowTypes = \"bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN\";\n // Character types for codepoints 0x600 to 0x6ff\n var arabicTypes = \"rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm\";\n function charType(code) {\n if (code <= 0xf7) return lowTypes.charAt(code);\n else if (0x590 <= code && code <= 0x5f4) return \"R\";\n else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600);\n else if (0x6ee <= code && code <= 0x8ac) return \"r\";\n else if (0x2000 <= code && code <= 0x200b) return \"w\";\n else if (code == 0x200c) return \"b\";\n else return \"L\";\n }\n\n var bidiRE = /[\\u0590-\\u05f4\\u0600-\\u06ff\\u0700-\\u08ac]/;\n var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;\n // Browsers seem to always treat the boundaries of block elements as being L.\n var outerType = \"L\";\n\n function BidiSpan(level, from, to) {\n this.level = level;\n this.from = from; this.to = to;\n }\n\n return function(str) {\n if (!bidiRE.test(str)) return false;\n var len = str.length, types = [];\n for (var i = 0, type; i < len; ++i)\n types.push(type = charType(str.charCodeAt(i)));\n\n // W1. Examine each non-spacing mark (NSM) in the level run, and\n // change the type of the NSM to the type of the previous\n // character. If the NSM is at the start of the level run, it will\n // get the type of sor.\n for (var i = 0, prev = outerType; i < len; ++i) {\n var type = types[i];\n if (type == \"m\") types[i] = prev;\n else prev = type;\n }\n\n // W2. Search backwards from each instance of a European number\n // until the first strong type (R, L, AL, or sor) is found. If an\n // AL is found, change the type of the European number to Arabic\n // number.\n // W3. Change all ALs to R.\n for (var i = 0, cur = outerType; i < len; ++i) {\n var type = types[i];\n if (type == \"1\" && cur == \"r\") types[i] = \"n\";\n else if (isStrong.test(type)) { cur = type; if (type == \"r\") types[i] = \"R\"; }\n }\n\n // W4. A single European separator between two European numbers\n // changes to a European number. A single common separator between\n // two numbers of the same type changes to that type.\n for (var i = 1, prev = types[0]; i < len - 1; ++i) {\n var type = types[i];\n if (type == \"+\" && prev == \"1\" && types[i+1] == \"1\") types[i] = \"1\";\n else if (type == \",\" && prev == types[i+1] &&\n (prev == \"1\" || prev == \"n\")) types[i] = prev;\n prev = type;\n }\n\n // W5. A sequence of European terminators adjacent to European\n // numbers changes to all European numbers.\n // W6. Otherwise, separators and terminators change to Other\n // Neutral.\n for (var i = 0; i < len; ++i) {\n var type = types[i];\n if (type == \",\") types[i] = \"N\";\n else if (type == \"%\") {\n for (var end = i + 1; end < len && types[end] == \"%\"; ++end) {}\n var replace = (i && types[i-1] == \"!\") || (end < len && types[end] == \"1\") ? \"1\" : \"N\";\n for (var j = i; j < end; ++j) types[j] = replace;\n i = end - 1;\n }\n }\n\n // W7. Search backwards from each instance of a European number\n // until the first strong type (R, L, or sor) is found. If an L is\n // found, then change the type of the European number to L.\n for (var i = 0, cur = outerType; i < len; ++i) {\n var type = types[i];\n if (cur == \"L\" && type == \"1\") types[i] = \"L\";\n else if (isStrong.test(type)) cur = type;\n }\n\n // N1. A sequence of neutrals takes the direction of the\n // surrounding strong text if the text on both sides has the same\n // direction. European and Arabic numbers act as if they were R in\n // terms of their influence on neutrals. Start-of-level-run (sor)\n // and end-of-level-run (eor) are used at level run boundaries.\n // N2. Any remaining neutrals take the embedding direction.\n for (var i = 0; i < len; ++i) {\n if (isNeutral.test(types[i])) {\n for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}\n var before = (i ? types[i-1] : outerType) == \"L\";\n var after = (end < len ? types[end] : outerType) == \"L\";\n var replace = before || after ? \"L\" : \"R\";\n for (var j = i; j < end; ++j) types[j] = replace;\n i = end - 1;\n }\n }\n\n // Here we depart from the documented algorithm, in order to avoid\n // building up an actual levels array. Since there are only three\n // levels (0, 1, 2) in an implementation that doesn't take\n // explicit embedding into account, we can build up the order on\n // the fly, without following the level-based algorithm.\n var order = [], m;\n for (var i = 0; i < len;) {\n if (countsAsLeft.test(types[i])) {\n var start = i;\n for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}\n order.push(new BidiSpan(0, start, i));\n } else {\n var pos = i, at = order.length;\n for (++i; i < len && types[i] != \"L\"; ++i) {}\n for (var j = pos; j < i;) {\n if (countsAsNum.test(types[j])) {\n if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j));\n var nstart = j;\n for (++j; j < i && countsAsNum.test(types[j]); ++j) {}\n order.splice(at, 0, new BidiSpan(2, nstart, j));\n pos = j;\n } else ++j;\n }\n if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i));\n }\n }\n if (order[0].level == 1 && (m = str.match(/^\\s+/))) {\n order[0].from = m[0].length;\n order.unshift(new BidiSpan(0, 0, m[0].length));\n }\n if (lst(order).level == 1 && (m = str.match(/\\s+$/))) {\n lst(order).to -= m[0].length;\n order.push(new BidiSpan(0, len - m[0].length, len));\n }\n if (order[0].level != lst(order).level)\n order.push(new BidiSpan(order[0].level, len, len));\n\n return order;\n };\n })();\n\n // THE END\n\n CodeMirror.version = \"4.12.0\";\n\n return CodeMirror;\n});\n","/*!\n * jQuery JavaScript Library v1.11.2\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-17T15:27Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper window is present,\n\t\t// execute the factory and get jQuery\n\t\t// For environments that do not inherently posses a window with a document\n\t\t// (such as Node.js), expose a jQuery-making factory as module.exports\n\t\t// This accentuates the need for the creation of a real window\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\n\nvar deletedIds = [];\n\nvar slice = deletedIds.slice;\n\nvar concat = deletedIds.concat;\n\nvar push = deletedIds.push;\n\nvar indexOf = deletedIds.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"1.11.2\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1, IE<9\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: deletedIds.sort,\n\tsplice: deletedIds.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\treturn !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Handle iteration over inherited properties before own properties.\n\t\tif ( support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || hasOwn.call( obj, key );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1, IE<9\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( indexOf ) {\n\t\t\t\treturn indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\twhile ( j < len ) {\n\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)\n\t\tif ( len !== len ) {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: function() {\n\t\treturn +( new Date() );\n\t},\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n});\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\tvar length = obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.0-pre\n * http://sizzlejs.com/\n *\n * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2014-12-16\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\tnodeType = context.nodeType;\n\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\tif ( !seed && documentIsHTML ) {\n\n\t\t// Try to shortcut find operations when possible (e.g., not under DocumentFragment)\n\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document (jQuery #6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType !== 1 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\tparent = doc.defaultView;\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent !== parent.top ) {\n\t\t// IE11 does not have attachEvent, so all must suffer\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Support tests\n\t---------------------------------------------------------------------- */\n\tdocumentIsHTML = !isXML( doc );\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( doc.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"\" +\n\t\t\t\t\"\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t// but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (oldCache = outerCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\touterCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: ) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n * selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n * selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is no seed and only one group\n\tif ( match.length === 1 ) {\n\n\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = (/^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/);\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t}));\n};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n});\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tdocument = window.document,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn typeof rootjQuery.ready !== \"undefined\" ?\n\t\t\t\trootjQuery.ready( selector ) :\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.extend({\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\njQuery.fn.extend({\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.unique(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\nvar rnotwhite = (/\\S+/g);\n\n\n\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\t// Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\n\t\t\t\t\t} else if ( !(--remaining) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend({\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n});\n\n/**\n * Clean-up method for dom ready events\n */\nfunction detach() {\n\tif ( document.addEventListener ) {\n\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t} else {\n\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\twindow.detachEvent( \"onload\", completed );\n\t}\n}\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\t// readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\tdetach();\n\t\tjQuery.ready();\n\t}\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", completed );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// detach all dom ready events\n\t\t\t\t\t\tdetach();\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n\nvar strundefined = typeof undefined;\n\n\n\n// Support: IE<9\n// Iteration over object's inherited properties before its own\nvar i;\nfor ( i in jQuery( support ) ) {\n\tbreak;\n}\nsupport.ownLast = i !== \"0\";\n\n// Note: most support tests are defined in their respective modules.\n// false until the test is run\nsupport.inlineBlockNeedsLayout = false;\n\n// Execute ASAP in case we need to set body.style.zoom\njQuery(function() {\n\t// Minified: var a,b,c,d\n\tvar val, div, body, container;\n\n\tbody = document.getElementsByTagName( \"body\" )[ 0 ];\n\tif ( !body || !body.style ) {\n\t\t// Return for frameset docs that don't have a body\n\t\treturn;\n\t}\n\n\t// Setup\n\tdiv = document.createElement( \"div\" );\n\tcontainer = document.createElement( \"div\" );\n\tcontainer.style.cssText = \"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\";\n\tbody.appendChild( container ).appendChild( div );\n\n\tif ( typeof div.style.zoom !== strundefined ) {\n\t\t// Support: IE<8\n\t\t// Check if natively block-level elements act like inline-block\n\t\t// elements when setting their display to 'inline' and giving\n\t\t// them layout\n\t\tdiv.style.cssText = \"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\";\n\n\t\tsupport.inlineBlockNeedsLayout = val = div.offsetWidth === 3;\n\t\tif ( val ) {\n\t\t\t// Prevent IE 6 from affecting layout for positioned elements #11048\n\t\t\t// Prevent IE from shrinking the body in IE 7 mode #12869\n\t\t\t// Support: IE<8\n\t\t\tbody.style.zoom = 1;\n\t\t}\n\t}\n\n\tbody.removeChild( container );\n});\n\n\n\n\n(function() {\n\tvar div = document.createElement( \"div\" );\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\n/**\n * Determines whether an object can have data\n */\njQuery.acceptData = function( elem ) {\n\tvar noData = jQuery.noData[ (elem.nodeName + \" \").toLowerCase() ],\n\t\tnodeType = +elem.nodeType || 1;\n\n\t// Do not set data on non-element DOM nodes because it will not be cleared (#8335).\n\treturn nodeType !== 1 && nodeType !== 9 ?\n\t\tfalse :\n\n\t\t// Nodes accept data unless otherwise specified; rejection can be conditional\n\t\t!noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n};\n\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\n\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t// can't GC object references properly across the DOM-JS boundary\n\t\tisNode = elem.nodeType,\n\n\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t// attached directly to the object so GC can occur automatically\n\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t// Avoid doing any more work than we need to when trying to get data on an\n\t// object that has no data at all\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t// ends up in the global cache\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\t// Avoid exposing jQuery metadata on plain JS objects when the object\n\t\t// is serialized using JSON.stringify\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\n\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t// shallow copied over onto the existing cache\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\n\t// jQuery data() is stored in a separate object inside the object's internal data\n\t// cache in order to avoid key collisions between internal data and user-defined\n\t// data.\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\n\t// Check for both converted-to-camel and non-converted data property names\n\t// If a data property was specified\n\tif ( typeof name === \"string\" ) {\n\n\t\t// First Try to find as-is property data\n\t\tret = thisCache[ name ];\n\n\t\t// Test for null|undefined property data\n\t\tif ( ret == null ) {\n\n\t\t\t// Try to find the camelCased property\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\n\t\t// See jQuery.data for more information\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t// If there is already no cache entry for this object, there is no\n\t// purpose in continuing\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\n\t\t\t// Support array or space separated string names for data keys\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\n\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t// and let the cache object itself get destroyed\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// See jQuery.data for more information\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\n\t\t// Don't destroy the parent cache unless the internal data object\n\t\t// had been the only thing left in it\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Destroy the cache\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\n\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t/* jshint eqeqeq: false */\n\t} else if ( support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\n\t// When all else fails, null\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\n\t// The following elements (space-suffixed to avoid Object.prototype collisions)\n\t// throw uncatchable exceptions if you attempt to set expando properties\n\tnoData: {\n\t\t\"applet \": true,\n\t\t\"embed \": true,\n\t\t// ...but Flash objects (which have this classid) *can* handle expandos\n\t\t\"object \": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[0],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Special expections of .data basically thwart jQuery.access,\n\t\t// so implement the relevant behavior ourselves\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\n\t\t\t// Sets one value\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\n\t\t\t// Gets one value\n\t\t\t// Try to fetch any internally stored data first\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\n\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar pnum = (/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/).source;\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n\t};\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlength = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n};\nvar rcheckableType = (/^(?:checkbox|radio)$/i);\n\n\n\n(function() {\n\t// Minified: var a,b,c\n\tvar input = document.createElement( \"input\" ),\n\t\tdiv = document.createElement( \"div\" ),\n\t\tfragment = document.createDocumentFragment();\n\n\t// Setup\n\tdiv.innerHTML = \"
a\";\n\n\t// IE strips leading whitespace when .innerHTML is used\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\n\t// Make sure that tbody elements aren't automatically inserted\n\t// IE will insert them into empty tables\n\tsupport.tbody = !div.getElementsByTagName( \"tbody\" ).length;\n\n\t// Make sure that link elements get serialized correctly by innerHTML\n\t// This requires a wrapper element in IE\n\tsupport.htmlSerialize = !!div.getElementsByTagName( \"link\" ).length;\n\n\t// Makes sure cloning an html5 element does not cause problems\n\t// Where outerHTML is undefined, this still works\n\tsupport.html5Clone =\n\t\tdocument.createElement( \"nav\" ).cloneNode( true ).outerHTML !== \"<:nav>\";\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tinput.type = \"checkbox\";\n\tinput.checked = true;\n\tfragment.appendChild( input );\n\tsupport.appendChecked = input.checked;\n\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\t// Support: IE6-IE11+\n\tdiv.innerHTML = \"\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tfragment.appendChild( div );\n\tdiv.innerHTML = \"\";\n\n\t// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3\n\t// old WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<9\n\t// Opera does not clone events (and typeof div.attachEvent === undefined).\n\t// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n\tsupport.noCloneEvent = true;\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\n\t// Execute the test only if not already executed in another module.\n\tif (support.deleteExpando == null) {\n\t\t// Support: IE<9\n\t\tsupport.deleteExpando = true;\n\t\ttry {\n\t\t\tdelete div.test;\n\t\t} catch( e ) {\n\t\t\tsupport.deleteExpando = false;\n\t\t}\n\t}\n})();\n\n\n(function() {\n\tvar i, eventName,\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\teventName = \"on\" + i;\n\n\t\tif ( !(support[ i + \"Bubbles\" ] = eventName in window) ) {\n\t\t\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\t\t\tdiv.setAttribute( eventName, \"t\" );\n\t\t\tsupport[ i + \"Bubbles\" ] = div.attributes[ eventName ].expando === false;\n\t\t}\n\t}\n\n\t// Null elements to avoid leaks in IE.\n\tdiv = null;\n})();\n\n\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && jQuery.acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486,#12518)\n\t\t\t\t\t\t// only reproducible on winXP IE8 native, not IE9 in IE8 mode\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Fix target property (#1925)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Support: Chrome 23+, Safari?\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// If we error on focus to hidden element (#1486, #12518),\n\t\t\t\t\t\t// let .trigger() run the handlers\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\t\t\t\t// Support: IE < 9, Android < 4.0\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If preventDefault exists, run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// Support: IE\n\t\t// Otherwise set the returnValue property of the original event to false\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// If stopPropagation exists, run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\t// Support: IE\n\t\t// Set the cancelBubble property of the original event to true\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e && e.stopImmediatePropagation ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tjQuery._data( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = jQuery._data( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tjQuery._removeData( doc, fix );\n\t\t\t\t} else {\n\t\t\t\t\tjQuery._data( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event ) dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\n\n\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\t\toption: [ 1, \"\" ],\n\t\tlegend: [ 1, \"
\", \"
\" ],\n\t\tarea: [ 1, \"\", \"\" ],\n\t\tparam: [ 1, \"\", \"\" ],\n\t\tthead: [ 1, \"\", \"
\" ],\n\t\ttr: [ 2, \"\", \"
\" ],\n\t\tcol: [ 2, \"\", \"
\" ],\n\t\ttd: [ 3, \"\", \"
\" ],\n\n\t\t// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n\t\t// unless wrapped in a div with non-breaking characters in front of it.\n\t\t_default: support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X
\", \"
\" ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\n\n// Used in buildFragment, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\n// Support: IE<8\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 copies events bound via attachEvent when using cloneNode.\n\tif ( !support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\n\t\t// Event data gets referenced instead of copied if the expando gets copied too\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\n\t// IE blanks contents when cloning scripts, and tries to evaluate newly-set text\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\n\t// IE6-10 improperly clones children of object elements using classid.\n\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!support.noCloneEvent || !support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\t// Fix all IE cloning issues\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\n\t\t\t// Ensure a safe fragment\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = (rtagName.exec( elem ) || [ \"\", \"\" ])[ 1 ].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1>\" ) + wrap[2];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Manually add leading whitespace removed by IE\n\t\t\t\t\tif ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted from table fragments\n\t\t\t\t\tif ( !support.tbody ) {\n\n\t\t\t\t\t\t// String was a , *may* have spurious \n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\n\t\t\t\t\t\t\t// String was a bare or \n\t\t\t\t\t\t\twrap[1] === \"
\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Fix #12392 for WebKit and IE > 9\n\t\t\t\t\ttmp.textContent = \"\";\n\n\t\t\t\t\t// Fix #12392 for oldIE\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remember the top-level container for proper cleanup\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from fragment\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tdeletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n});\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\tremove: function( selector, keepData /* Internal Use Only */ ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\n\t\t\t// If this is a select, ensure that it displays empty (#12336)\n\t\t\t// Support: IE<9\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map(function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( support.htmlSerialize || !rnoshimcache.test( value ) ) &&\n\t\t\t\t( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ (rtagName.exec( value ) || [ \"\", \"\" ])[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar arg = arguments[ 0 ];\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\targ = this.parentNode;\n\n\t\t\tjQuery.cleanData( getAll( this ) );\n\n\t\t\tif ( arg ) {\n\t\t\t\targ.replaceChild( elem, this );\n\t\t\t}\n\t\t});\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn arg && (arg.length || arg.nodeType) ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction ||\n\t\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\n\t\t\t// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\n\nvar iframe,\n\telemdisplay = {};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar style,\n\t\telem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\t// getDefaultComputedStyle might be reliably used only on attached element\n\t\tdisplay = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ?\n\n\t\t\t// Use of this method is a temporary fix (more like optmization) until something better comes along,\n\t\t\t// since it was removed from specification and supported only in FF\n\t\t\tstyle.display : jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = (iframe || jQuery( \"')\n\t\t\tstorageContainer.close()\n\t\t\tstorageOwner = storageContainer.w.frames[0].document\n\t\t\tstorage = storageOwner.createElement('div')\n\t\t} catch(e) {\n\t\t\t// somehow ActiveXObject instantiation failed (perhaps some special\n\t\t\t// security settings or otherwse), fall back to per-path storage\n\t\t\tstorage = doc.createElement('div')\n\t\t\tstorageOwner = doc.body\n\t\t}\n\t\tvar withIEStorage = function(storeFunction) {\n\t\t\treturn function() {\n\t\t\t\tvar args = Array.prototype.slice.call(arguments, 0)\n\t\t\t\targs.unshift(storage)\n\t\t\t\t// See http://msdn.microsoft.com/en-us/library/ms531081(v=VS.85).aspx\n\t\t\t\t// and http://msdn.microsoft.com/en-us/library/ms531424(v=VS.85).aspx\n\t\t\t\tstorageOwner.appendChild(storage)\n\t\t\t\tstorage.addBehavior('#default#userData')\n\t\t\t\tstorage.load(localStorageName)\n\t\t\t\tvar result = storeFunction.apply(store, args)\n\t\t\t\tstorageOwner.removeChild(storage)\n\t\t\t\treturn result\n\t\t\t}\n\t\t}\n\n\t\t// In IE7, keys cannot start with a digit or contain certain chars.\n\t\t// See https://github.com/marcuswestin/store.js/issues/40\n\t\t// See https://github.com/marcuswestin/store.js/issues/83\n\t\tvar forbiddenCharsRegex = new RegExp(\"[!\\\"#$%&'()*+,/\\\\\\\\:;<=>?@[\\\\]^`{|}~]\", \"g\")\n\t\tfunction ieKeyFix(key) {\n\t\t\treturn key.replace(/^d/, '___$&').replace(forbiddenCharsRegex, '___')\n\t\t}\n\t\tstore.set = withIEStorage(function(storage, key, val) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tif (val === undefined) { return store.remove(key) }\n\t\t\tstorage.setAttribute(key, store.serialize(val))\n\t\t\tstorage.save(localStorageName)\n\t\t\treturn val\n\t\t})\n\t\tstore.get = withIEStorage(function(storage, key, defaultVal) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tvar val = store.deserialize(storage.getAttribute(key))\n\t\t\treturn (val === undefined ? defaultVal : val)\n\t\t})\n\t\tstore.remove = withIEStorage(function(storage, key) {\n\t\t\tkey = ieKeyFix(key)\n\t\t\tstorage.removeAttribute(key)\n\t\t\tstorage.save(localStorageName)\n\t\t})\n\t\tstore.clear = withIEStorage(function(storage) {\n\t\t\tvar attributes = storage.XMLDocument.documentElement.attributes\n\t\t\tstorage.load(localStorageName)\n\t\t\tfor (var i=0, attr; attr=attributes[i]; i++) {\n\t\t\t\tstorage.removeAttribute(attr.name)\n\t\t\t}\n\t\t\tstorage.save(localStorageName)\n\t\t})\n\t\tstore.getAll = function(storage) {\n\t\t\tvar ret = {}\n\t\t\tstore.forEach(function(key, val) {\n\t\t\t\tret[key] = val\n\t\t\t})\n\t\t\treturn ret\n\t\t}\n\t\tstore.forEach = withIEStorage(function(storage, callback) {\n\t\t\tvar attributes = storage.XMLDocument.documentElement.attributes\n\t\t\tfor (var i=0, attr; attr=attributes[i]; ++i) {\n\t\t\t\tcallback(attr.name, store.deserialize(storage.getAttribute(attr.name)))\n\t\t\t}\n\t\t})\n\t}\n\n\ttry {\n\t\tvar testKey = '__storejs__'\n\t\tstore.set(testKey, testKey)\n\t\tif (store.get(testKey) != testKey) { store.disabled = true }\n\t\tstore.remove(testKey)\n\t} catch(e) {\n\t\tstore.disabled = true\n\t}\n\tstore.enabled = !store.disabled\n\n\tif (typeof module != 'undefined' && module.exports && this.module !== module) { module.exports = store }\n\telse if (typeof define === 'function' && define.amd) { define(store) }\n\telse { win.store = store }\n\n})(Function('return this')());\n","module.exports={\n \"name\": \"yasgui-utils\",\n \"version\": \"1.6.0\",\n \"description\": \"Utils for YASGUI libs\",\n \"main\": \"src/main.js\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/YASGUI/Utils.git\"\n },\n \"licenses\": [\n {\n \"type\": \"MIT\",\n \"url\": \"http://yasgui.github.io/license.txt\"\n }\n ],\n \"author\": \"Laurens Rietveld\",\n \"maintainers\": [\n {\n \"name\": \"Laurens Rietveld\",\n \"email\": \"laurens.rietveld@gmail.com\",\n \"web\": \"http://laurensrietveld.nl\"\n }\n ],\n \"bugs\": {\n \"url\": \"https://github.com/YASGUI/Utils/issues\"\n },\n \"homepage\": \"https://github.com/YASGUI/Utils\",\n \"dependencies\": {\n \"store\": \"^1.3.14\"\n }\n}\n","window.console = window.console || {\"log\":function(){}};//make sure any console statements don't break IE\nmodule.exports = {\n\tstorage: require(\"./storage.js\"),\n\tsvg: require(\"./svg.js\"),\n\tversion: {\n\t\t\"yasgui-utils\" : require(\"../package.json\").version,\n\t},\n\tnestedExists : function(obj) {\n\t\tvar args = Array.prototype.slice.call(arguments, 1);\n\n\t\tfor (var i = 0; i < args.length; i++) {\n\t\t\tif (!obj || !obj.hasOwnProperty(args[i])) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tobj = obj[args[i]];\n\t\t}\n\t\treturn true;\n\t}\n};\n","var store = require(\"store\");\nvar times = {\n\tday: function() {\n\t\treturn 1000 * 3600 * 24;//millis to day\n\t},\n\tmonth: function() {\n\t\ttimes.day() * 30;\n\t},\n\tyear: function() {\n\t\ttimes.month() * 12;\n\t}\n};\n\nvar root = module.exports = {\n\tset : function(key, val, exp) {\n if (!store.enabled) return;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (key && val !== undefined) {\n\t\t\tif (typeof exp == \"string\") {\n\t\t\t\texp = times[exp]();\n\t\t\t}\n\t\t\t//try to store string for dom objects (e.g. XML result). Otherwise, we might get a circular reference error when stringifying this\n\t\t\tif (val.documentElement) val = new XMLSerializer().serializeToString(val.documentElement);\n\t\t\tstore.set(key, {\n\t\t\t\tval : val,\n\t\t\t\texp : exp,\n\t\t\t\ttime : new Date().getTime()\n\t\t\t});\n\t\t}\n\t},\n\tremove: function(key) {\n\t\tif (!store.enabled) return;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (key) store.remove(key)\n\t},\n\tremoveAll: function(filter) {\n\t\tif (!store.enabled) return;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (typeof filter === 'function') {\n\t\t\tfor (var key in store.getAll()) {\n\t\t\t\tif (filter(key, root.get(key))) root.remove(key);\n\t\t\t}\n\t\t}\n\t},\n\tget : function(key) {\n if (!store.enabled) return null;//this is probably in private mode. Don't run, as we might get Js errors\n\t\tif (key) {\n\t\t\tvar info = store.get(key);\n\t\t\tif (!info) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tif (info.exp && new Date().getTime() - info.time > info.exp) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn info.val;\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n};\n","module.exports = {\n\tdraw: function(parent, svgString) {\n\t\tif (!parent) return;\n\t\tvar el = module.exports.getElement(svgString);\n\t\tif (el) {\n\t\t\tif (parent.append) {\n\t\t\t\tparent.append(el);\n\t\t\t} else {\n\t\t\t\t//regular dom doc\n\t\t\t\tparent.appendChild(el);\n\t\t\t}\n\t\t}\n\t},\n\tgetElement: function(svgString) {\n\t\tif (svgString && svgString.indexOf(\" 0) {\n\t\t\t//position completion notifications\n\t\t\tvar scrollBar = $(yasqe.getWrapperElement()).find(\".CodeMirror-vscrollbar\");\n\t\t\tvar offset = 0;\n\t\t\tif (scrollBar.is(\":visible\")) {\n\t\t\t\toffset = scrollBar.outerWidth();\n\t\t\t}\n\t\t\tneedPossibleAdjustment.forEach(function(notification) {\n\t\t\t\tnotification.css(\"right\", offset)\n\t\t\t});\n\t\t}\n\t});\n\n\n\n\t/**\n\t * Store bulk completions in memory as trie, and store these in localstorage as well (if enabled)\n\t * \n\t * @method doc.storeBulkCompletions\n\t * @param completions {array}\n\t */\n\tvar storeBulkCompletions = function(completer, completions) {\n\t\t// store array as trie\n\t\ttries[completer.name] = new Trie();\n\t\tfor (var i = 0; i < completions.length; i++) {\n\t\t\ttries[completer.name].insert(completions[i]);\n\t\t}\n\t\t// store in localstorage as well\n\t\tvar storageId = utils.getPersistencyId(yasqe, completer.persistent);\n\t\tif (storageId) yutils.storage.set(storageId, completions, \"month\");\n\t};\n\n\tvar initCompleter = function(name, completionInit) {\n\t\tvar completer = completers[name] = new completionInit(yasqe, name);\n\t\tcompleter.name = name;\n\t\tif (completer.bulk) {\n\t\t\tvar storeArrayAsBulk = function(suggestions) {\n\t\t\t\tif (suggestions && suggestions instanceof Array && suggestions.length > 0) {\n\t\t\t\t\tstoreBulkCompletions(completer, suggestions);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (completer.get instanceof Array) {\n\t\t\t\t// we don't care whether the completions are already stored in\n\t\t\t\t// localstorage. just use this one\n\t\t\t\tstoreArrayAsBulk(completer.get);\n\t\t\t} else {\n\t\t\t\t// if completions are defined in localstorage, use those! (calling the\n\t\t\t\t// function may come with overhead (e.g. async calls))\n\t\t\t\tvar completionsFromStorage = null;\n\t\t\t\tvar persistencyIdentifier = utils.getPersistencyId(yasqe, completer.persistent);\n\t\t\t\tif (persistencyIdentifier)\n\t\t\t\t\tcompletionsFromStorage = yutils.storage.get(persistencyIdentifier);\n\t\t\t\tif (completionsFromStorage && completionsFromStorage.length > 0) {\n\t\t\t\t\tstoreArrayAsBulk(completionsFromStorage);\n\t\t\t\t} else {\n\t\t\t\t\t// nothing in storage. check whether we have a function via which we\n\t\t\t\t\t// can get our prefixes\n\t\t\t\t\tif (completer.get instanceof Function) {\n\t\t\t\t\t\tif (completer.async) {\n\t\t\t\t\t\t\tcompleter.get(null, storeArrayAsBulk);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tstoreArrayAsBulk(completer.get());\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\tvar autoComplete = function(fromAutoShow) {\n\t\tif (yasqe.somethingSelected())\n\t\t\treturn;\n\t\tvar tryHintType = function(completer) {\n\t\t\tif (fromAutoShow // from autoShow, i.e. this gets called each time the editor content changes\n\t\t\t\t&& (!completer.autoShow // autoshow for this particular type of autocompletion is -not- enabled\n\t\t\t\t\t|| (!completer.bulk && completer.async)) // async is enabled (don't want to re-do ajax-like request for every editor change)\n\t\t\t) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tvar hintConfig = {\n\t\t\t\tcloseCharacters: /(?=a)b/,\n\t\t\t\tcompleteSingle: false\n\t\t\t};\n\t\t\tif (!completer.bulk && completer.async) {\n\t\t\t\thintConfig.async = true;\n\t\t\t}\n\t\t\tvar wrappedHintCallback = function(yasqe, callback) {\n\t\t\t\treturn getCompletionHintsObject(completer, callback);\n\t\t\t};\n\t\t\tvar result = YASQE.showHint(yasqe, wrappedHintCallback, hintConfig);\n\t\t\treturn true;\n\t\t};\n\t\tfor (var completerName in completers) {\n\t\t\tif ($.inArray(completerName, yasqe.options.autocompleters) == -1) continue; //this completer is disabled\n\t\t\tvar completer = completers[completerName];\n\t\t\tif (!completer.isValidCompletionPosition) continue; //no way to check whether we are in a valid position\n\n\t\t\tif (!completer.isValidCompletionPosition()) {\n\t\t\t\t//if needed, fire callbacks for when we are -not- in valid completion position\n\t\t\t\tif (completer.callbacks && completer.callbacks.invalidPosition) {\n\t\t\t\t\tcompleter.callbacks.invalidPosition(yasqe, completer);\n\t\t\t\t}\n\t\t\t\t//not in a valid position, so continue to next completion candidate type\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t// run valid position handler, if there is one (if it returns false, stop the autocompletion!)\n\t\t\tif (completer.callbacks && completer.callbacks.validPosition) {\n\t\t\t\tif (completer.callbacks.validPosition(yasqe, completer) === false)\n\t\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tvar success = tryHintType(completer);\n\t\t\tif (success)\n\t\t\t\tbreak;\n\t\t}\n\t};\n\n\n\n\tvar getCompletionHintsObject = function(completer, callback) {\n\t\tvar getSuggestionsFromToken = function(partialToken) {\n\t\t\tvar stringToAutocomplete = partialToken.autocompletionString || partialToken.string;\n\t\t\tvar suggestions = [];\n\t\t\tif (tries[completer.name]) {\n\t\t\t\tsuggestions = tries[completer.name].autoComplete(stringToAutocomplete);\n\t\t\t} else if (typeof completer.get == \"function\" && completer.async == false) {\n\t\t\t\tsuggestions = completer.get(stringToAutocomplete);\n\t\t\t} else if (typeof completer.get == \"object\") {\n\t\t\t\tvar partialTokenLength = stringToAutocomplete.length;\n\t\t\t\tfor (var i = 0; i < completer.get.length; i++) {\n\t\t\t\t\tvar completion = completer.get[i];\n\t\t\t\t\tif (completion.slice(0, partialTokenLength) == stringToAutocomplete) {\n\t\t\t\t\t\tsuggestions.push(completion);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn getSuggestionsAsHintObject(suggestions, completer, partialToken);\n\n\t\t};\n\n\n\t\tvar token = yasqe.getCompleteToken();\n\t\tif (completer.preProcessToken) {\n\t\t\ttoken = completer.preProcessToken(token);\n\t\t}\n\n\t\tif (token) {\n\t\t\t// use custom completionhint function, to avoid reaching a loop when the\n\t\t\t// completionhint is the same as the current token\n\t\t\t// regular behaviour would keep changing the codemirror dom, hence\n\t\t\t// constantly calling this callback\n\t\t\tif (!completer.bulk && completer.async) {\n\t\t\t\tvar wrappedCallback = function(suggestions) {\n\t\t\t\t\tcallback(getSuggestionsAsHintObject(suggestions, completer, token));\n\t\t\t\t};\n\t\t\t\tcompleter.get(token, wrappedCallback);\n\t\t\t} else {\n\t\t\t\treturn getSuggestionsFromToken(token);\n\n\t\t\t}\n\t\t}\n\t};\n\n\n\t/**\n\t * get our array of suggestions (strings) in the codemirror hint format\n\t */\n\tvar getSuggestionsAsHintObject = function(suggestions, completer, token) {\n\t\tvar hintList = [];\n\t\tfor (var i = 0; i < suggestions.length; i++) {\n\t\t\tvar suggestedString = suggestions[i];\n\t\t\tif (completer.postProcessToken) {\n\t\t\t\tsuggestedString = completer.postProcessToken(token, suggestedString);\n\t\t\t}\n\t\t\thintList.push({\n\t\t\t\ttext: suggestedString,\n\t\t\t\tdisplayText: suggestedString,\n\t\t\t\thint: selectHint,\n\t\t\t});\n\t\t}\n\n\t\tvar cur = yasqe.getCursor();\n\t\tvar returnObj = {\n\t\t\tcompletionToken: token.string,\n\t\t\tlist: hintList,\n\t\t\tfrom: {\n\t\t\t\tline: cur.line,\n\t\t\t\tch: token.start\n\t\t\t},\n\t\t\tto: {\n\t\t\t\tline: cur.line,\n\t\t\t\tch: token.end\n\t\t\t}\n\t\t};\n\t\t//if we have some autocompletion handlers specified, add these these to the object. Codemirror will take care of firing these\n\t\tif (completer.callbacks) {\n\t\t\tfor (var callbackName in completer.callbacks) {\n\t\t\t\tif (completer.callbacks[callbackName]) {\n\t\t\t\t\tYASQE.on(returnObj, callbackName, completer.callbacks[callbackName]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn returnObj;\n\t};\n\n\treturn {\n\t\tinit: initCompleter,\n\t\tcompleters: completers,\n\t\tnotifications: {\n\t\t\tgetEl: function(completer) {\n\t\t\t\treturn $(completionNotifications[completer.name]);\n\t\t\t},\n\t\t\tshow: function(yasqe, completer) {\n\t\t\t\t//only draw when the user needs to use a keypress to summon autocompletions\n\t\t\t\tif (!completer.autoshow) {\n\t\t\t\t\tif (!completionNotifications[completer.name]) completionNotifications[completer.name] = $(\"
\");\n\t\t\t\t\tcompletionNotifications[completer.name]\n\t\t\t\t\t\t.show()\n\t\t\t\t\t\t.text(\"Press \" + (navigator.userAgent.indexOf('Mac OS X') != -1 ? \"CMD\" : \"CTRL\") + \" - to autocomplete\")\n\t\t\t\t\t\t.appendTo($(yasqe.getWrapperElement()));\n\t\t\t\t}\n\t\t\t},\n\t\t\thide: function(yasqe, completer) {\n\t\t\t\tif (completionNotifications[completer.name]) {\n\t\t\t\t\tcompletionNotifications[completer.name].hide();\n\t\t\t\t}\n\t\t\t}\n\n\t\t},\n\t\tautoComplete: autoComplete,\n\t\tgetTrie: function(completer) {\n\t\t\treturn (typeof completer == \"string\" ? tries[completer] : tries[completer.name]);\n\t\t}\n\t}\n};\n\n\n\n\n\n\n\n\n\n/**\n * function which fires after the user selects a completion. this function checks whether we actually need to store this one (if completion is same as current token, don't do anything)\n */\nvar selectHint = function(yasqe, data, completion) {\n\tif (completion.text != yasqe.getTokenAt(yasqe.getCursor()).string) {\n\t\tyasqe.replaceRange(completion.text, data.from, data.to);\n\t}\n};\n\n\n\n\n\n//\n//module.exports = {\n//\tpreprocessPrefixTokenForCompletion: preprocessPrefixTokenForCompletion,\n//\tpostprocessResourceTokenForCompletion: postprocessResourceTokenForCompletion,\n//\tpreprocessResourceTokenForCompletion: preprocessResourceTokenForCompletion,\n//\tshowCompletionNotification: showCompletionNotification,\n//\thideCompletionNotification: hideCompletionNotification,\n//\tautoComplete: autoComplete,\n//\tautocompleteVariables: autocompleteVariables,\n//\tfetchFromPrefixCc: fetchFromPrefixCc,\n//\tfetchFromLov: fetchFromLov,\n////\tstoreBulkCompletions: storeBulkCompletions,\n//\tloadBulkCompletions: loadBulkCompletions,\n//};","'use strict';\nvar $ = require('jquery');\nmodule.exports = function(yasqe, name) {\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\treturn module.exports.isValidCompletionPosition(yasqe);\n\t\t},\n\t\tget: function(token, callback) {\n\t\t\treturn require('./utils').fetchFromLov(yasqe, this, token, callback);\n\t\t},\n\t\tpreProcessToken: function(token) {\n\t\t\treturn module.exports.preProcessToken(yasqe, token)\n\t\t},\n\t\tpostProcessToken: function(token, suggestedString) {\n\t\t\treturn module.exports.postProcessToken(yasqe, token, suggestedString);\n\t\t},\n\t\tasync: true,\n\t\tbulk: false,\n\t\tautoShow: false,\n\t\tpersistent: name,\n\t\tcallbacks: {\n\t\t\tvalidPosition: yasqe.autocompleters.notifications.show,\n\t\t\tinvalidPosition: yasqe.autocompleters.notifications.hide,\n\t\t}\n\t}\n};\n\nmodule.exports.isValidCompletionPosition = function(yasqe) {\n\tvar token = yasqe.getCompleteToken();\n\tif (token.string.indexOf(\"?\") == 0)\n\t\treturn false;\n\tvar cur = yasqe.getCursor();\n\tvar previousToken = yasqe.getPreviousNonWsToken(cur.line, token);\n\tif (previousToken.string == \"a\")\n\t\treturn true;\n\tif (previousToken.string == \"rdf:type\")\n\t\treturn true;\n\tif (previousToken.string == \"rdfs:domain\")\n\t\treturn true;\n\tif (previousToken.string == \"rdfs:range\")\n\t\treturn true;\n\treturn false;\n};\nmodule.exports.preProcessToken = function(yasqe, token) {\n\treturn require('./utils.js').preprocessResourceTokenForCompletion(yasqe, token);\n};\nmodule.exports.postProcessToken = function(yasqe, token, suggestedString) {\n\treturn require('./utils.js').postprocessResourceTokenForCompletion(yasqe, token, suggestedString)\n};","'use strict';\nvar $ = require('jquery');\n//this is a mapping from the class names (generic ones, for compatability with codemirror themes), to what they -actually- represent\nvar tokenTypes = {\n\t\"string-2\": \"prefixed\",\n\t\"atom\": \"var\"\n};\n\nmodule.exports = function(yasqe, completerName) {\n\t//this autocompleter also fires on-change!\n\tyasqe.on(\"change\", function() {\n\t\tmodule.exports.appendPrefixIfNeeded(yasqe, completerName);\n\t});\n\n\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\treturn module.exports.isValidCompletionPosition(yasqe);\n\t\t},\n\t\tget: function(token, callback) {\n\t\t\t$.get(\"http://prefix.cc/popular/all.file.json\", function(data) {\n\t\t\t\tvar prefixArray = [];\n\t\t\t\tfor (var prefix in data) {\n\t\t\t\t\tif (prefix == \"bif\")\n\t\t\t\t\t\tcontinue; // skip this one! see #231\n\t\t\t\t\tvar completeString = prefix + \": <\" + data[prefix] + \">\";\n\t\t\t\t\tprefixArray.push(completeString); // the array we want to store in localstorage\n\t\t\t\t}\n\n\t\t\t\tprefixArray.sort();\n\t\t\t\tcallback(prefixArray);\n\t\t\t});\n\t\t},\n\t\tpreProcessToken: function(token) {\n\t\t\treturn module.exports.preprocessPrefixTokenForCompletion(yasqe, token)\n\t\t},\n\t\tasync: true,\n\t\tbulk: true,\n\t\tautoShow: true,\n\t\tpersistent: completerName,\n\t\tcallbacks: {\n\t\t\tpick: function() {\n\t\t\t\tyasqe.collapsePrefixes(false);\n\t\t\t}\n\t\t}\n\t};\n};\nmodule.exports.isValidCompletionPosition = function(yasqe) {\n\tvar cur = yasqe.getCursor(),\n\t\ttoken = yasqe.getTokenAt(cur);\n\n\t// not at end of line\n\tif (yasqe.getLine(cur.line).length > cur.ch)\n\t\treturn false;\n\n\tif (token.type != \"ws\") {\n\t\t// we want to complete token, e.g. when the prefix starts with an a\n\t\t// (treated as a token in itself..)\n\t\t// but we to avoid including the PREFIX tag. So when we have just\n\t\t// typed a space after the prefix tag, don't get the complete token\n\t\ttoken = yasqe.getCompleteToken();\n\t}\n\n\t// we shouldnt be at the uri part the prefix declaration\n\t// also check whether current token isnt 'a' (that makes codemirror\n\t// thing a namespace is a possiblecurrent\n\tif (!token.string.indexOf(\"a\") == 0 && $.inArray(\"PNAME_NS\", token.state.possibleCurrent) == -1)\n\t\treturn false;\n\n\t// First token of line needs to be PREFIX,\n\t// there should be no trailing text (otherwise, text is wrongly inserted\n\t// in between)\n\tvar previousToken = yasqe.getPreviousNonWsToken(cur.line, token);\n\tif (!previousToken || previousToken.string.toUpperCase() != \"PREFIX\") return false;\n\treturn true;\n};\nmodule.exports.preprocessPrefixTokenForCompletion = function(yasqe, token) {\n\tvar previousToken = yasqe.getPreviousNonWsToken(yasqe.getCursor().line, token);\n\tif (previousToken && previousToken.string && previousToken.string.slice(-1) == \":\") {\n\t\t//combine both tokens! In this case we have the cursor at the end of line \"PREFIX bla: <\".\n\t\t//we want the token to be \"bla: <\", en not \"<\"\n\t\ttoken = {\n\t\t\tstart: previousToken.start,\n\t\t\tend: token.end,\n\t\t\tstring: previousToken.string + \" \" + token.string,\n\t\t\tstate: token.state\n\t\t};\n\t}\n\treturn token;\n};\n/**\n * Check whether typed prefix is declared. If not, automatically add declaration\n * using list from prefix.cc\n * \n * @param yasqe\n */\nmodule.exports.appendPrefixIfNeeded = function(yasqe, completerName) {\n\tif (!yasqe.autocompleters.getTrie(completerName))\n\t\treturn; // no prefixed defined. just stop\n\tif (!yasqe.options.autocompleters || yasqe.options.autocompleters.indexOf(completerName) == -1) return; //this autocompleter is disabled\n\tvar cur = yasqe.getCursor();\n\n\tvar token = yasqe.getTokenAt(cur);\n\tif (tokenTypes[token.type] == \"prefixed\") {\n\t\tvar colonIndex = token.string.indexOf(\":\");\n\t\tif (colonIndex !== -1) {\n\t\t\t// check previous token isnt PREFIX, or a '<'(which would mean we are in a uri)\n\t\t\t//\t\t\tvar firstTokenString = yasqe.getNextNonWsToken(cur.line).string.toUpperCase();\n\t\t\tvar lastNonWsTokenString = yasqe.getPreviousNonWsToken(cur.line, token).string.toUpperCase();\n\t\t\tvar previousToken = yasqe.getTokenAt({\n\t\t\t\tline: cur.line,\n\t\t\t\tch: token.start\n\t\t\t}); // needs to be null (beginning of line), or whitespace\n\t\t\tif (lastNonWsTokenString != \"PREFIX\" && (previousToken.type == \"ws\" || previousToken.type == null)) {\n\t\t\t\t// check whether it isnt defined already (saves us from looping\n\t\t\t\t// through the array)\n\t\t\t\tvar currentPrefix = token.string.substring(0, colonIndex + 1);\n\t\t\t\tvar queryPrefixes = yasqe.getPrefixesFromQuery();\n\t\t\t\tif (queryPrefixes[currentPrefix.slice(0, -1)] == null) {\n\t\t\t\t\t// ok, so it isnt added yet!\n\t\t\t\t\tvar completions = yasqe.autocompleters.getTrie(completerName).autoComplete(currentPrefix);\n\t\t\t\t\tif (completions.length > 0) {\n\t\t\t\t\t\tyasqe.addPrefixes(completions[0]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};","'use strict';\nvar $ = require('jquery');\nmodule.exports = function(yasqe, name) {\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\treturn module.exports.isValidCompletionPosition(yasqe);\n\t\t},\n\t\tget: function(token, callback) {\n\t\t\treturn require('./utils').fetchFromLov(yasqe, this, token, callback);\n\t\t},\n\t\tpreProcessToken: function(token) {\n\t\t\treturn module.exports.preProcessToken(yasqe, token)\n\t\t},\n\t\tpostProcessToken: function(token, suggestedString) {\n\t\t\treturn module.exports.postProcessToken(yasqe, token, suggestedString);\n\t\t},\n\t\tasync: true,\n\t\tbulk: false,\n\t\tautoShow: false,\n\t\tpersistent: name,\n\t\tcallbacks: {\n\t\t\tvalidPosition: yasqe.autocompleters.notifications.show,\n\t\t\tinvalidPosition: yasqe.autocompleters.notifications.hide,\n\t\t}\n\t}\n};\n\nmodule.exports.isValidCompletionPosition = function(yasqe) {\n\tvar token = yasqe.getCompleteToken();\n\tif (token.string.length == 0)\n\t\treturn false; //we want -something- to autocomplete\n\tif (token.string.indexOf(\"?\") == 0)\n\t\treturn false; // we are typing a var\n\tif ($.inArray(\"a\", token.state.possibleCurrent) >= 0)\n\t\treturn true; // predicate pos\n\tvar cur = yasqe.getCursor();\n\tvar previousToken = yasqe.getPreviousNonWsToken(cur.line, token);\n\tif (previousToken.string == \"rdfs:subPropertyOf\")\n\t\treturn true;\n\n\t// hmm, we would like -better- checks here, e.g. checking whether we are\n\t// in a subject, and whether next item is a rdfs:subpropertyof.\n\t// difficult though... the grammar we use is unreliable when the query\n\t// is invalid (i.e. during typing), and often the predicate is not typed\n\t// yet, when we are busy writing the subject...\n\treturn false;\n};\nmodule.exports.preProcessToken = function(yasqe, token) {\n\treturn require('./utils.js').preprocessResourceTokenForCompletion(yasqe, token);\n};\nmodule.exports.postProcessToken = function(yasqe, token, suggestedString) {\n\treturn require('./utils.js').postprocessResourceTokenForCompletion(yasqe, token, suggestedString)\n};","'use strict';\nvar $ = require('jquery'),\n\tutils = require('./utils.js'),\n\tyutils = require('yasgui-utils');\n/**\n * Where the base class only contains functionality related to -all- completions, this class contains some utils used here and there in our autocompletions\n */\n\n\n\n/**\n * Converts rdf:type to http://.../type and converts to http://...\n * Stores additional info such as the used namespace and prefix in the token object\n */\nvar preprocessResourceTokenForCompletion = function(yasqe, token) {\n\tvar queryPrefixes = yasqe.getPrefixesFromQuery();\n\tif (!token.string.indexOf(\"<\") == 0) {\n\t\ttoken.tokenPrefix = token.string.substring(0, token.string.indexOf(\":\") + 1);\n\n\t\tif (queryPrefixes[token.tokenPrefix.slice(0, -1)] != null) {\n\t\t\ttoken.tokenPrefixUri = queryPrefixes[token.tokenPrefix.slice(0, -1)];\n\t\t}\n\t}\n\n\ttoken.autocompletionString = token.string.trim();\n\tif (!token.string.indexOf(\"<\") == 0 && token.string.indexOf(\":\") > -1) {\n\t\t// hmm, the token is prefixed. We still need the complete uri for autocompletions. generate this!\n\t\tfor (var prefix in queryPrefixes) {\n\t\t\tif (token.string.indexOf(prefix) == 0) {\n\t\t\t\ttoken.autocompletionString = queryPrefixes[prefix];\n\t\t\t\ttoken.autocompletionString += token.string.substring(prefix.length + 1);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\tif (token.autocompletionString.indexOf(\"<\") == 0) token.autocompletionString = token.autocompletionString.substring(1);\n\tif (token.autocompletionString.indexOf(\">\", token.length - 1) !== -1) token.autocompletionString = token.autocompletionString.substring(0, token.autocompletionString.length - 1);\n\treturn token;\n};\n\nvar postprocessResourceTokenForCompletion = function(yasqe, token, suggestedString) {\n\tif (token.tokenPrefix && token.autocompletionString && token.tokenPrefixUri) {\n\t\t// we need to get the suggested string back to prefixed form\n\t\tsuggestedString = token.tokenPrefix + suggestedString.substring(token.tokenPrefixUri.length);\n\t} else {\n\t\t// it is a regular uri. add '<' and '>' to string\n\t\tsuggestedString = \"<\" + suggestedString + \">\";\n\t}\n\treturn suggestedString;\n};\n\nvar fetchFromLov = function(yasqe, completer, token, callback) {\n\tif (!token || !token.string || token.string.trim().length == 0) {\n\t\tyasqe.autocompleters.notifications.getEl(completer)\n\t\t\t.empty()\n\t\t\t.append(\"Nothing to autocomplete yet!\");\n\t\treturn false;\n\t}\n\tvar maxResults = 50;\n\n\tvar args = {\n\t\tq: token.autocompletionString,\n\t\tpage: 1\n\t};\n\tif (completer.name == \"classes\") {\n\t\targs.type = \"class\";\n\t} else {\n\t\targs.type = \"property\";\n\t}\n\tvar results = [];\n\tvar url = \"\";\n\tvar updateUrl = function() {\n\t\turl = \"http://lov.okfn.org/dataset/lov/api/v2/autocomplete/terms?\" + $.param(args);\n\t};\n\tupdateUrl();\n\tvar increasePage = function() {\n\t\targs.page++;\n\t\tupdateUrl();\n\t};\n\tvar doRequests = function() {\n\t\t$.get(\n\t\t\turl,\n\t\t\tfunction(data) {\n\t\t\t\tfor (var i = 0; i < data.results.length; i++) {\n\t\t\t\t\tif ($.isArray(data.results[i].uri) && data.results[i].uri.length > 0) {\n\t\t\t\t\t\tresults.push(data.results[i].uri[0]);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresults.push(data.results[i].uri);\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t\tif (results.length < data.total_results && results.length < maxResults) {\n\t\t\t\t\tincreasePage();\n\t\t\t\t\tdoRequests();\n\t\t\t\t} else {\n\t\t\t\t\t//if notification bar is there, show feedback, or close\n\t\t\t\t\tif (results.length > 0) {\n\t\t\t\t\t\tyasqe.autocompleters.notifications.hide(yasqe, completer)\n\t\t\t\t\t} else {\n\t\t\t\t\t\tyasqe.autocompleters.notifications.getEl(completer).text(\"0 matches found...\");\n\t\t\t\t\t}\n\t\t\t\t\tcallback(results);\n\t\t\t\t\t// requests done! Don't call this function again\n\t\t\t\t}\n\t\t\t}).fail(function(jqXHR, textStatus, errorThrown) {\n\t\t\tyasqe.autocompleters.notifications.getEl(completer)\n\t\t\t\t.empty()\n\t\t\t\t.append(\"Failed fetching suggestions..\");\n\n\t\t});\n\t};\n\t//if notification bar is there, show a loader\n\tyasqe.autocompleters.notifications.getEl(completer)\n\t\t.empty()\n\t\t.append($(\"Fetchting autocompletions  \"))\n\t\t.append($(yutils.svg.getElement(require('../imgs.js').loader)).addClass(\"notificationLoader\"));\n\tdoRequests();\n};\n\n\n\nmodule.exports = {\n\tfetchFromLov: fetchFromLov,\n\tpreprocessResourceTokenForCompletion: preprocessResourceTokenForCompletion,\n\tpostprocessResourceTokenForCompletion: postprocessResourceTokenForCompletion,\n};","'use strict';\nvar $ = require('jquery');\nmodule.exports = function(yasqe) {\n\treturn {\n\t\tisValidCompletionPosition: function() {\n\t\t\tvar token = yasqe.getTokenAt(yasqe.getCursor());\n\t\t\tif (token.type != \"ws\") {\n\t\t\t\ttoken = yasqe.getCompleteToken(token);\n\t\t\t\tif (token && token.string.indexOf(\"?\") == 0) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t\tget: function(token) {\n\t\t\tif (token.trim().length == 0) return []; //nothing to autocomplete\n\t\t\tvar distinctVars = {};\n\t\t\t//do this outside of codemirror. I expect jquery to be faster here (just finding dom elements with classnames)\n\t\t\t$(yasqe.getWrapperElement()).find(\".cm-atom\").each(function() {\n\t\t\t\tvar variable = this.innerHTML;\n\t\t\t\tif (variable.indexOf(\"?\") == 0) {\n\t\t\t\t\t//ok, lets check if the next element in the div is an atom as well. In that case, they belong together (may happen sometimes when query is not syntactically valid)\n\t\t\t\t\tvar nextEl = $(this).next();\n\t\t\t\t\tvar nextElClass = nextEl.attr('class');\n\t\t\t\t\tif (nextElClass && nextEl.attr('class').indexOf(\"cm-atom\") >= 0) {\n\t\t\t\t\t\tvariable += nextEl.text();\n\t\t\t\t\t}\n\n\t\t\t\t\t//skip single questionmarks\n\t\t\t\t\tif (variable.length <= 1) return;\n\n\t\t\t\t\t//it should match our token ofcourse\n\t\t\t\t\tif (variable.indexOf(token) !== 0) return;\n\n\t\t\t\t\t//skip exact matches\n\t\t\t\t\tif (variable == token) return;\n\n\t\t\t\t\t//store in map so we have a unique list \n\t\t\t\t\tdistinctVars[variable] = true;\n\n\n\t\t\t\t}\n\t\t\t});\n\t\t\tvar variables = [];\n\t\t\tfor (var variable in distinctVars) {\n\t\t\t\tvariables.push(variable);\n\t\t\t}\n\t\t\tvariables.sort();\n\t\t\treturn variables;\n\t\t},\n\t\tasync: false,\n\t\tbulk: false,\n\t\tautoShow: true,\n\t}\n};","var sparql = require('./sparql.js'),\n $ = require('jquery');\nvar quote = function(string) {\n return \"'\" + string + \"'\";\n}\nmodule.exports = {\n createCurlString : function(yasqe, config) {\n var ajaxConfig = sparql.getAjaxConfig(yasqe, config);\n \n var url = yasqe.options.sparql.endpoint;\n if (yasqe.options.sparql.requestMethod == 'GET') {\n url += '?' + $.param(ajaxConfig.data);\n }\n var cmds = [\n 'curl', url,\n '-X', yasqe.options.sparql.requestMethod\n ];\n if (yasqe.options.sparql.requestMethod == 'POST') {\n cmds.push('--data ' + quote($.param(ajaxConfig.data)));\n }\n for (var header in ajaxConfig.headers) {\n cmds.push('-H ' + quote(header + ': ' + ajaxConfig.headers[header]));\n }\n return cmds.join(' ');\n\n\n\n\n }\n}\n","/**\n * The default options of YASQE (check the CodeMirror documentation for even\n * more options, such as disabling line numbers, or changing keyboard shortcut\n * keys). Either change the default options by setting YASQE.defaults, or by\n * passing your own options as second argument to the YASQE constructor\n */\nvar $ = require('jquery'),\n\tYASQE = require('./main.js');\nYASQE.defaults = $.extend(true, {}, YASQE.defaults, {\n\tmode: \"sparql11\",\n\t/**\n\t * Query string\n\t */\n\tvalue: \"PREFIX rdf: \\nPREFIX rdfs: \\nSELECT * WHERE {\\n ?sub ?pred ?obj .\\n} \\nLIMIT 10\",\n\thighlightSelectionMatches: {\n\t\tshowToken: /\\w/\n\t},\n\ttabMode: \"indent\",\n\tlineNumbers: true,\n\tlineWrapping: true,\n\tbackdrop: false,\n\tfoldGutter: {\n\t\trangeFinder: new YASQE.fold.combine(YASQE.fold.brace, YASQE.fold.prefix)\n\t},\n\tcollapsePrefixesOnLoad: false,\n\tgutters: [\"gutterErrorBar\", \"CodeMirror-linenumbers\", \"CodeMirror-foldgutter\"],\n\tmatchBrackets: true,\n\tfixedGutter: true,\n\tsyntaxErrorCheck: true,\n\t/**\n\t * Extra shortcut keys. Check the CodeMirror manual on how to add your own\n\t *\n\t * @property extraKeys\n\t * @type object\n\t */\n\textraKeys: {\n\t\t//\t\t\t\t\t\"Ctrl-Space\" : function(yasqe) {\n\t\t//\t\t\t\t\t\tYASQE.autoComplete(yasqe);\n\t\t//\t\t\t\t\t},\n\t\t\"Ctrl-Space\": YASQE.autoComplete,\n\n\t\t\"Cmd-Space\": YASQE.autoComplete,\n\t\t\"Ctrl-D\": YASQE.deleteLine,\n\t\t\"Ctrl-K\": YASQE.deleteLine,\n\t\t\"Cmd-D\": YASQE.deleteLine,\n\t\t\"Cmd-K\": YASQE.deleteLine,\n\t\t\"Ctrl-/\": YASQE.commentLines,\n\t\t\"Cmd-/\": YASQE.commentLines,\n\t\t\"Ctrl-Alt-Down\": YASQE.copyLineDown,\n\t\t\"Ctrl-Alt-Up\": YASQE.copyLineUp,\n\t\t\"Cmd-Alt-Down\": YASQE.copyLineDown,\n\t\t\"Cmd-Alt-Up\": YASQE.copyLineUp,\n\t\t\"Shift-Ctrl-F\": YASQE.doAutoFormat,\n\t\t\"Shift-Cmd-F\": YASQE.doAutoFormat,\n\t\t\"Ctrl-]\": YASQE.indentMore,\n\t\t\"Cmd-]\": YASQE.indentMore,\n\t\t\"Ctrl-[\": YASQE.indentLess,\n\t\t\"Cmd-[\": YASQE.indentLess,\n\t\t\"Ctrl-S\": YASQE.storeQuery,\n\t\t\"Cmd-S\": YASQE.storeQuery,\n\t\t\"Ctrl-Enter\": YASQE.executeQuery,\n\t\t\"Cmd-Enter\": YASQE.executeQuery,\n\t\t\"F11\": function(yasqe) {\n\t\t\tyasqe.setOption(\"fullScreen\", !yasqe.getOption(\"fullScreen\"));\n\t\t},\n\t\t\"Esc\": function(yasqe) {\n\t\t\tif (yasqe.getOption(\"fullScreen\")) yasqe.setOption(\"fullScreen\", false);\n\t\t}\n\t},\n\tcursorHeight: 0.9,\n\n\n\t/**\n\t * Show a button with which users can create a link to this query. Set this value to null to disable this functionality.\n\t * By default, this feature is enabled, and the only the query value is appended to the link.\n\t * ps. This function should return an object which is parseable by jQuery.param (http://api.jquery.com/jQuery.param/)\n\t */\n\tcreateShareLink: YASQE.createShareLink,\n\n\tcreateShortLink: null,\n\n\t/**\n\t * Consume links shared by others, by checking the url for arguments coming from a query link. Defaults by only checking the 'query=' argument in the url\n\t */\n\tconsumeShareLink: YASQE.consumeShareLink,\n\n\n\n\n\t/**\n\t * Change persistency settings for the YASQE query value. Setting the values\n\t * to null, will disable persistancy: nothing is stored between browser\n\t * sessions Setting the values to a string (or a function which returns a\n\t * string), will store the query in localstorage using the specified string.\n\t * By default, the ID is dynamically generated using the closest dom ID, to avoid collissions when using multiple YASQE items on one\n\t * page\n\t *\n\t * @type function|string\n\t */\n\tpersistent: function(yasqe) {\n\t\treturn \"yasqe_\" + $(yasqe.getWrapperElement()).closest('[id]').attr('id') + \"_queryVal\";\n\t},\n\n\n\t/**\n\t * Settings for querying sparql endpoints\n\t */\n\tsparql: {\n\t\tshowQueryButton: false,\n\n\t\t/**f\n\t\t * Endpoint to query\n\t\t *\n\t\t * @property sparql.endpoint\n\t\t * @type String|function\n\t\t */\n\t\tendpoint: \"http://dbpedia.org/sparql\",\n\t\t/**\n\t\t * Request method via which to access SPARQL endpoint\n\t\t *\n\t\t * @property sparql.requestMethod\n\t\t * @type String|function\n\t\t */\n\t\trequestMethod: \"POST\",\n\n\t\t/**\n\t\t * @type String|function\n\t\t */\n\t\tacceptHeaderGraph: \"text/turtle,*/*;q=0.9\",\n\t\t/**\n\t\t * @type String|function\n\t\t */\n\t\tacceptHeaderSelect: \"application/sparql-results+json,*/*;q=0.9\",\n\t\t/**\n\t\t * @type String|function\n\t\t */\n\t\tacceptHeaderUpdate: \"text/plain,*/*;q=0.9\",\n\n\t\t/**\n\t\t * Named graphs to query.\n\t\t */\n\t\tnamedGraphs: [],\n\t\t/**\n\t\t * Default graphs to query.\n\t\t */\n\t\tdefaultGraphs: [],\n\n\t\t/**\n\t\t * Additional request arguments. Add them in the form: {name: \"name\", value: \"value\"}\n\t\t */\n\t\targs: [],\n\n\t\t/**\n\t\t * Additional request headers\n\t\t */\n\t\theaders: {},\n\n\t\tgetQueryForAjax: null,\n\t\t/**\n\t\t * Set of ajax callbacks\n\t\t */\n\t\tcallbacks: {\n\t\t\tbeforeSend: null,\n\t\t\tcomplete: null,\n\t\t\terror: null,\n\t\t\tsuccess: null\n\t\t},\n\t\thandlers: {} //keep here for backwards compatability\n\t},\n});\n","'use strict';\nmodule.exports = {\n\tquery: '\t',\n\tqueryInvalid: 'image/svg+xml',\n\tdownload: '\t',\n\tshare: '',\n\twarning: '',\n\tfullscreen: 'image/svg+xml',\n\tsmallscreen: 'image/svg+xml',\n};\n","'use strict';\n//make sure any console statements\nwindow.console = window.console || {\n\t\"log\": function() {}\n};\n\n/**\n * Load libraries\n */\nvar $ = require(\"jquery\"),\n\tCodeMirror = require(\"codemirror\"),\n\tutils = require('./utils.js'),\n\tyutils = require('yasgui-utils'),\n\timgs = require('./imgs.js');\n\nrequire(\"../lib/deparam.js\");\nrequire('codemirror/addon/fold/foldcode.js');\nrequire('codemirror/addon/fold/foldgutter.js');\nrequire('codemirror/addon/fold/xml-fold.js');\nrequire('codemirror/addon/fold/brace-fold.js');\nrequire('./prefixFold.js');\nrequire('codemirror/addon/hint/show-hint.js');\nrequire('codemirror/addon/search/searchcursor.js');\nrequire('codemirror/addon/edit/matchbrackets.js');\nrequire('codemirror/addon/runmode/runmode.js');\nrequire('codemirror/addon/display/fullscreen.js');\nrequire('../lib/grammar/tokenizer.js');\n\n\n\n/**\n * Main YASQE constructor. Pass a DOM element as argument to append the editor to, and (optionally) pass along config settings (see the YASQE.defaults object below, as well as the regular CodeMirror documentation, for more information on configurability)\n *\n * @constructor\n * @param {DOM-Element} parent element to append editor to.\n * @param {object} settings\n * @class YASQE\n * @return {doc} YASQE document\n */\nvar root = module.exports = function(parent, config) {\n\tvar rootEl = $(\"
\", {\n\t\tclass: 'yasqe'\n\t}).appendTo($(parent));\n\tconfig = extendConfig(config);\n\tvar yasqe = extendCmInstance(CodeMirror(rootEl[0], config));\n\tpostProcessCmElement(yasqe);\n\treturn yasqe;\n};\n\n/**\n * Extend config object, which we will pass on to the CM constructor later on.\n * Need this, to make sure our own 'onBlur' etc events do not get overwritten by\n * people who add their own onblur events to the config Additionally, need this\n * to include the CM defaults ourselves. CodeMirror has a method for including\n * defaults, but we can't rely on that one: it assumes flat config object, where\n * we have nested objects (e.g. the persistency option)\n *\n * @private\n */\nvar extendConfig = function(config) {\n\tvar extendedConfig = $.extend(true, {}, root.defaults, config);\n\n\t// I know, codemirror deals with default options as well.\n\t//However, it does not do this recursively (i.e. the persistency option)\n\n\n\treturn extendedConfig;\n};\n/**\n * Add extra functions to the CM document (i.e. the codemirror instantiated\n * object)\n *\n * @private\n */\nvar extendCmInstance = function(yasqe) {\n\t//instantiate autocompleters\n\tyasqe.autocompleters = require('./autocompleters/autocompleterBase.js')(root, yasqe);\n\tif (yasqe.options.autocompleters) {\n\t\tyasqe.options.autocompleters.forEach(function(name) {\n\t\t\tif (root.Autocompleters[name]) yasqe.autocompleters.init(name, root.Autocompleters[name]);\n\t\t})\n\t}\n\tyasqe.lastQueryDuration = null;\n\tyasqe.getCompleteToken = function(token, cur) {\n\t\treturn require('./tokenUtils.js').getCompleteToken(yasqe, token, cur);\n\t};\n\tyasqe.getPreviousNonWsToken = function(line, token) {\n\t\treturn require('./tokenUtils.js').getPreviousNonWsToken(yasqe, line, token);\n\t};\n\tyasqe.getNextNonWsToken = function(lineNumber, charNumber) {\n\t\treturn require('./tokenUtils.js').getNextNonWsToken(yasqe, lineNumber, charNumber);\n\t};\n\tyasqe.collapsePrefixes = function(collapse) {\n\t\tyasqe.foldCode(require('./prefixFold.js').findFirstPrefixLine(yasqe), YASQE.fold.prefix, (collapse ? \"fold\" : \"unfold\"));\n\t};\n\tvar backdrop = null;\n\tvar animateSpeed = null;\n\tyasqe.setBackdrop = function(show) {\n\n\n\t\tif (yasqe.options.backdrop || yasqe.options.backdrop === 0 || yasqe.options.backdrop === '0') {\n\t\t\tif (animateSpeed === null) {\n\t\t\t\tanimateSpeed = +yasqe.options.backdrop;\n\t\t\t\tif (animateSpeed === 1) {\n\t\t\t\t\t//ah, yasqe.options.backdrop was 'true'. Set this to default animate speed 400\n\t\t\t\t\tanimateSpeed = 400;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\tif (!backdrop) {\n\t\t\t\tbackdrop = $('
', {\n\t\t\t\t\t\tclass: 'backdrop'\n\t\t\t\t\t})\n\t\t\t\t\t.click(function() {\n\t\t\t\t\t\t$(this).hide();\n\t\t\t\t\t})\n\t\t\t\t\t.insertAfter($(yasqe.getWrapperElement()));\n\t\t\t}\n\t\t\tif (show) {\n\t\t\t\tbackdrop.show(animateSpeed);\n\t\t\t} else {\n\t\t\t\tbackdrop.hide(animateSpeed);\n\t\t\t}\n\t\t}\n\t};\n\t/**\n\t * Execute query. Pass a callback function, or a configuration object (see\n\t * default settings below for possible values) I.e., you can change the\n\t * query configuration by either changing the default settings, changing the\n\t * settings of this document, or by passing query settings to this function\n\t *\n\t * @method doc.query\n\t * @param function|object\n\t */\n\tyasqe.query = function(callbackOrConfig) {\n\t\troot.executeQuery(yasqe, callbackOrConfig);\n\t};\n\n\tyasqe.getUrlArguments = function(config) {\n\t\treturn root.getUrlArguments(yasqe, config);\n\t};\n\n\t/**\n\t * Fetch defined prefixes from query string\n\t *\n\t * @method doc.getPrefixesFromQuery\n\t * @return object\n\t */\n\tyasqe.getPrefixesFromQuery = function() {\n\t\treturn require('./prefixUtils.js').getPrefixesFromQuery(yasqe);\n\t};\n\n\tyasqe.addPrefixes = function(prefixes) {\n\t\treturn require('./prefixUtils.js').addPrefixes(yasqe, prefixes);\n\t};\n\tyasqe.removePrefixes = function(prefixes) {\n\t\treturn require('./prefixUtils.js').removePrefixes(yasqe, prefixes);\n\t};\n\n\tyasqe.getValueWithoutComments = function() {\n\t\tvar cleanedQuery = \"\";\n\t\troot.runMode(yasqe.getValue(), \"sparql11\", function(stringVal, className) {\n\t\t\tif (className != \"comment\") {\n\t\t\t\tcleanedQuery += stringVal;\n\t\t\t}\n\t\t});\n\t\treturn cleanedQuery;\n\t};\n\t/**\n\t * Fetch the query type (e.g., SELECT||DESCRIBE||INSERT||DELETE||ASK||CONSTRUCT)\n\t *\n\t * @method doc.getQueryType\n\t * @return string\n\t *\n\t */\n\tyasqe.getQueryType = function() {\n\t\treturn yasqe.queryType;\n\t};\n\t/**\n\t * Fetch the query mode: 'query' or 'update'\n\t *\n\t * @method doc.getQueryMode\n\t * @return string\n\t *\n\t */\n\tyasqe.getQueryMode = function() {\n\t\tvar type = yasqe.getQueryType();\n\t\tif (type == \"INSERT\" || type == \"DELETE\" || type == \"LOAD\" || type == \"CLEAR\" || type == \"CREATE\" || type == \"DROP\" || type == \"COPY\" || type == \"MOVE\" || type == \"ADD\") {\n\t\t\treturn \"update\";\n\t\t} else {\n\t\t\treturn \"query\";\n\t\t}\n\n\t};\n\n\tyasqe.setCheckSyntaxErrors = function(isEnabled) {\n\t\tyasqe.options.syntaxErrorCheck = isEnabled;\n\t\tcheckSyntax(yasqe);\n\t};\n\n\tyasqe.enableCompleter = function(name) {\n\t\taddCompleterToSettings(yasqe.options, name);\n\t\tif (root.Autocompleters[name]) yasqe.autocompleters.init(name, root.Autocompleters[name]);\n\t};\n\tyasqe.disableCompleter = function(name) {\n\t\tremoveCompleterFromSettings(yasqe.options, name);\n\t};\n\treturn yasqe;\n};\n\nvar addCompleterToSettings = function(settings, name) {\n\tif (!settings.autocompleters) settings.autocompleters = [];\n\tsettings.autocompleters.push(name);\n};\nvar removeCompleterFromSettings = function(settings, name) {\n\tif (typeof settings.autocompleters == \"object\") {\n\t\tvar index = $.inArray(name, settings.autocompleters);\n\t\tif (index >= 0) {\n\t\t\tsettings.autocompleters.splice(index, 1);\n\t\t\tremoveCompleterFromSettings(settings, name); //just in case. suppose 1 completer is listed twice\n\t\t}\n\t}\n};\nvar postProcessCmElement = function(yasqe) {\n\t/**\n\t * Set doc value\n\t */\n\tvar storageId = utils.getPersistencyId(yasqe, yasqe.options.persistent);\n\tif (storageId) {\n\t\tvar valueFromStorage = yutils.storage.get(storageId);\n\t\tif (valueFromStorage)\n\t\t\tyasqe.setValue(valueFromStorage);\n\t}\n\n\troot.drawButtons(yasqe);\n\n\t/**\n\t * Add event handlers\n\t */\n\tyasqe.on('blur', function(yasqe, eventInfo) {\n\t\troot.storeQuery(yasqe);\n\t});\n\tyasqe.on('change', function(yasqe, eventInfo) {\n\t\tcheckSyntax(yasqe);\n\t\troot.updateQueryButton(yasqe);\n\t\troot.positionButtons(yasqe);\n\t});\n\tyasqe.on('changes', function() {\n\t\t//e.g. on paste\n\t\tcheckSyntax(yasqe);\n\t\troot.updateQueryButton(yasqe);\n\t\troot.positionButtons(yasqe);\n\t});\n\n\tyasqe.on('cursorActivity', function(yasqe, eventInfo) {\n\t\tupdateButtonsTransparency(yasqe);\n\t});\n\tyasqe.prevQueryValid = false;\n\tcheckSyntax(yasqe); // on first load, check as well (our stored or default query might be incorrect)\n\troot.positionButtons(yasqe);\n\n\t$(yasqe.getWrapperElement()).on('mouseenter', '.cm-atom', function() {\n\t\tvar matchText = $(this).text();\n\t\t$(yasqe.getWrapperElement()).find('.cm-atom').filter(function() {\n\t\t\treturn $(this).text() === matchText;\n\t\t}).addClass('matchingVar');\n\t}).on('mouseleave', '.cm-atom', function() {\n\t\t$(yasqe.getWrapperElement()).find('.matchingVar').removeClass('matchingVar');\n\t});\n\t/**\n\t * check url args and modify yasqe settings if needed\n\t */\n\tif (yasqe.options.consumeShareLink) {\n\t\tyasqe.options.consumeShareLink(yasqe, getUrlParams());\n\t\t//and: add a hash listener!\n\t\twindow.addEventListener(\"hashchange\", function() {\n\t\t\tyasqe.options.consumeShareLink(yasqe, getUrlParams());\n\t\t});\n\t}\n\tif (yasqe.options.collapsePrefixesOnLoad) yasqe.collapsePrefixes(true);\n};\n\n/**\n * get url params. first try fetching using hash. If it fails, try the regular query parameters (for backwards compatability)\n */\nvar getUrlParams = function() {\n\t//first try hash\n\tvar urlParams = null;\n\tif (window.location.hash.length > 1) {\n\t\t//firefox does some decoding if we're using window.location.hash (e.g. the + sign in contentType settings)\n\t\t//Don't want this. So simply get the hash string ourselves\n\t\turlParams = $.deparam(location.href.split(\"#\")[1])\n\t}\n\tif ((!urlParams || !('query' in urlParams)) && window.location.search.length > 1) {\n\t\t//ok, then just try regular url params\n\t\turlParams = $.deparam(window.location.search.substring(1));\n\t}\n\treturn urlParams;\n};\n\n\n\n/**\n * Update transparency of buttons. Increase transparency when cursor is below buttons\n */\n\nvar updateButtonsTransparency = function(yasqe) {\n\tyasqe.cursor = $(\".CodeMirror-cursor\");\n\tif (yasqe.buttons && yasqe.buttons.is(\":visible\") && yasqe.cursor.length > 0) {\n\t\tif (utils.elementsOverlap(yasqe.cursor, yasqe.buttons)) {\n\t\t\tyasqe.buttons.find(\"svg\").attr(\"opacity\", \"0.2\");\n\t\t} else {\n\t\t\tyasqe.buttons.find(\"svg\").attr(\"opacity\", \"1.0\");\n\t\t}\n\t}\n};\n\n\n\n\n\n\n\n\n\nvar clearError = null;\nvar checkSyntax = function(yasqe, deepcheck) {\n\n\tyasqe.queryValid = true;\n\n\tyasqe.clearGutter(\"gutterErrorBar\");\n\n\tvar state = null;\n\tfor (var l = 0; l < yasqe.lineCount(); ++l) {\n\t\tvar precise = false;\n\t\tif (!yasqe.prevQueryValid) {\n\t\t\t// we don't want cached information in this case, otherwise the\n\t\t\t// previous error sign might still show up,\n\t\t\t// even though the syntax error might be gone already\n\t\t\tprecise = true;\n\t\t}\n\n\t\tvar token = yasqe.getTokenAt({\n\t\t\tline: l,\n\t\t\tch: yasqe.getLine(l).length\n\t\t}, precise);\n\t\tvar state = token.state;\n\t\tyasqe.queryType = state.queryType;\n\t\tif (state.OK == false) {\n\t\t\tif (!yasqe.options.syntaxErrorCheck) {\n\t\t\t\t//the library we use already marks everything as being an error. Overwrite this class attribute.\n\t\t\t\t$(yasqe.getWrapperElement).find(\".sp-error\").css(\"color\", \"black\");\n\t\t\t\t//we don't want to gutter error, so return\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar warningEl = yutils.svg.getElement(imgs.warning);\n\t\t\tif (state.possibleCurrent && state.possibleCurrent.length > 0) {\n\t\t\t\t//\t\t\t\twarningEl.style.zIndex = \"99999999\";\n\t\t\t\trequire('./tooltip')(yasqe, warningEl, function() {\n\t\t\t\t\tvar expectedEncoded = [];\n\t\t\t\t\tstate.possibleCurrent.forEach(function(expected) {\n\t\t\t\t\t\texpectedEncoded.push(\"\" + $(\"
\").text(expected).html() + \"\");\n\t\t\t\t\t});\n\t\t\t\t\treturn \"This line is invalid. Expected: \" + expectedEncoded.join(\", \");\n\t\t\t\t});\n\t\t\t}\n\t\t\twarningEl.style.marginTop = \"2px\";\n\t\t\twarningEl.style.marginLeft = \"2px\";\n\t\t\twarningEl.className = 'parseErrorIcon';\n\t\t\tyasqe.setGutterMarker(l, \"gutterErrorBar\", warningEl);\n\n\t\t\tyasqe.queryValid = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tyasqe.prevQueryValid = yasqe.queryValid;\n\tif (deepcheck) {\n\t\tif (state != null && state.stack != undefined) {\n\t\t\tvar stack = state.stack,\n\t\t\t\tlen = state.stack.length;\n\t\t\t// Because incremental parser doesn't receive end-of-input\n\t\t\t// it can't clear stack, so we have to check that whatever\n\t\t\t// is left on the stack is nillable\n\t\t\tif (len > 1)\n\t\t\t\tyasqe.queryValid = false;\n\t\t\telse if (len == 1) {\n\t\t\t\tif (stack[0] != \"solutionModifier\" && stack[0] != \"?limitOffsetClauses\" && stack[0] != \"?offsetClause\")\n\t\t\t\t\tyasqe.queryValid = false;\n\t\t\t}\n\t\t}\n\t}\n};\n/**\n * Static Utils\n */\n// first take all CodeMirror references and store them in the YASQE object\n$.extend(root, CodeMirror);\n\n\n//add registrar for autocompleters\nroot.Autocompleters = {};\nroot.registerAutocompleter = function(name, constructor) {\n\troot.Autocompleters[name] = constructor;\n\taddCompleterToSettings(root.defaults, name);\n}\n\nroot.autoComplete = function(yasqe) {\n\t//this function gets called when pressing the keyboard shortcut. I.e., autoShow = false\n\tyasqe.autocompleters.autoComplete(false);\n};\n//include the autocompleters we provide out-of-the-box\nroot.registerAutocompleter(\"prefixes\", require(\"./autocompleters/prefixes.js\"));\nroot.registerAutocompleter(\"properties\", require(\"./autocompleters/properties.js\"));\nroot.registerAutocompleter(\"classes\", require(\"./autocompleters/classes.js\"));\nroot.registerAutocompleter(\"variables\", require(\"./autocompleters/variables.js\"));\n\n\nroot.positionButtons = function(yasqe) {\n\tvar scrollBar = $(yasqe.getWrapperElement()).find(\".CodeMirror-vscrollbar\");\n\tvar offset = 0;\n\tif (scrollBar.is(\":visible\")) {\n\t\toffset = scrollBar.outerWidth();\n\t}\n\tif (yasqe.buttons.is(\":visible\")) yasqe.buttons.css(\"right\", offset + 4);\n};\n\n/**\n * Create a share link\n *\n * @method YASQE.createShareLink\n * @param {doc} YASQE document\n * @default {query: doc.getValue()}\n * @return object\n */\nroot.createShareLink = function(yasqe) {\n\t//extend existing link, so first fetch current arguments\n\tvar urlParams = {};\n\tif (window.location.hash.length > 1) urlParams = $.deparam(window.location.hash.substring(1));\n\turlParams['query'] = yasqe.getValue();\n\treturn urlParams;\n};\nroot.getAsCurl = function(yasqe, ajaxConfig) {\n\tvar curl = require('./curl.js');\n\treturn curl.createCurlString(yasqe, ajaxConfig);\n};\n/**\n * Consume the share link, by parsing the document URL for possible yasqe arguments, and setting the appropriate values in the YASQE doc\n *\n * @method YASQE.consumeShareLink\n * @param {doc} YASQE document\n */\nroot.consumeShareLink = function(yasqe, urlParams) {\n\tif (urlParams && urlParams.query) {\n\t\tyasqe.setValue(urlParams.query);\n\t}\n};\nroot.drawButtons = function(yasqe) {\n\tyasqe.buttons = $(\"
\").appendTo($(yasqe.getWrapperElement()));\n\n\t/**\n\t * draw share link button\n\t */\n\tif (yasqe.options.createShareLink) {\n\n\t\tvar svgShare = $(yutils.svg.getElement(imgs.share));\n\t\tsvgShare.click(function(event) {\n\t\t\t\tevent.stopPropagation();\n\t\t\t\tvar popup = $(\"
\").appendTo(yasqe.buttons);\n\t\t\t\t$('html').click(function() {\n\t\t\t\t\tif (popup) popup.remove();\n\t\t\t\t});\n\n\t\t\t\tpopup.click(function(event) {\n\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t});\n\t\t\t\tvar $input = $(\"\").val(location.protocol + '//' + location.host + location.pathname + location.search + \"#\" + $.param(yasqe.options.createShareLink(yasqe)));\n\n\t\t\t\t$input.focus(function() {\n\t\t\t\t\tvar $this = $(this);\n\t\t\t\t\t$this.select();\n\n\t\t\t\t\t// Work around Chrome's little problem\n\t\t\t\t\t$this.mouseup(function() {\n\t\t\t\t\t\t// Prevent further mouseup intervention\n\t\t\t\t\t\t$this.unbind(\"mouseup\");\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\tpopup.empty().append($('
', {class:'inputWrapper'}).append($input));\n\t\t\t\tif (yasqe.options.createShortLink) {\n\t\t\t\t\tpopup.addClass('enableShort');\n\t\t\t\t\t$('')\n\t\t\t\t\t\t.addClass('yasqe_btn yasqe_btn-sm yasqe_btn-primary')\n\t\t\t\t\t\t.click(function() {\n\t\t\t\t\t\t\t$(this).parent().find('button').attr('disabled', 'disabled');\n\t\t\t\t\t\t\tyasqe.options.createShortLink($input.val(), function(errString, shortLink) {\n\t\t\t\t\t\t\t\tif (errString) {\n\t\t\t\t\t\t\t\t\t$input.remove();\n\t\t\t\t\t\t\t\t\tpopup.find('.inputWrapper').append($('', {class:\"shortlinkErr\"}).text(errString));\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$input.val(shortLink).focus();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t}).appendTo(popup);\n\t\t\t\t}\n\t\t\t\t$('')\n\t\t\t\t\t.addClass('yasqe_btn yasqe_btn-sm yasqe_btn-primary')\n\t\t\t\t\t.click(function() {\n\n\t\t\t\t\t\t$(this).parent().find('button').attr('disabled', 'disabled');\n\t\t\t\t\t\t$input.val(root.getAsCurl(yasqe)).focus();\n\t\t\t\t\t}).appendTo(popup);\n\t\t\t\tvar positions = svgShare.position();\n\t\t\t\tpopup.css(\"top\", (positions.top + svgShare.outerHeight() + parseInt(popup.css('padding-top')) ) + \"px\").css(\"left\", ((positions.left + svgShare.outerWidth()) - popup.outerWidth()) + \"px\");\n\t\t\t\t$input.focus();\n\t\t\t})\n\t\t\t.addClass(\"yasqe_share\")\n\t\t\t.attr(\"title\", \"Share your query\")\n\t\t\t.appendTo(yasqe.buttons);\n\n\t}\n\n\n\t/**\n\t * draw fullscreen button\n\t */\n\n\tvar toggleFullscreen = $('
', {\n\t\t\tclass: 'fullscreenToggleBtns'\n\t\t})\n\t\t.append($(yutils.svg.getElement(imgs.fullscreen))\n\t\t\t.addClass(\"yasqe_fullscreenBtn\")\n\t\t\t.attr(\"title\", \"Set editor full screen\")\n\t\t\t.click(function() {\n\t\t\t\tyasqe.setOption(\"fullScreen\", true);\n\t\t\t}))\n\t\t.append($(yutils.svg.getElement(imgs.smallscreen))\n\t\t\t.addClass(\"yasqe_smallscreenBtn\")\n\t\t\t.attr(\"title\", \"Set editor to normale size\")\n\t\t\t.click(function() {\n\t\t\t\tyasqe.setOption(\"fullScreen\", false);\n\t\t\t}))\n\tyasqe.buttons.append(toggleFullscreen);\n\n\n\tif (yasqe.options.sparql.showQueryButton) {\n\t\t$(\"
\", {\n\t\t\t\tclass: 'yasqe_queryButton'\n\t\t\t})\n\t\t\t.click(function() {\n\t\t\t\tif ($(this).hasClass(\"query_busy\")) {\n\t\t\t\t\tif (yasqe.xhr) yasqe.xhr.abort();\n\t\t\t\t\troot.updateQueryButton(yasqe);\n\t\t\t\t} else {\n\t\t\t\t\tyasqe.query();\n\t\t\t\t}\n\t\t\t})\n\t\t\t.appendTo(yasqe.buttons);\n\t\troot.updateQueryButton(yasqe);\n\t}\n\n};\n\n\nvar queryButtonIds = {\n\t\"busy\": \"loader\",\n\t\"valid\": \"query\",\n\t\"error\": \"queryInvalid\"\n};\n\n/**\n * Update the query button depending on current query status. If no query status is passed via the parameter, it auto-detects the current query status\n *\n * @param {doc} YASQE document\n * @param status {string|null, \"busy\"|\"valid\"|\"error\"}\n */\nroot.updateQueryButton = function(yasqe, status) {\n\tvar queryButton = $(yasqe.getWrapperElement()).find(\".yasqe_queryButton\");\n\tif (queryButton.length == 0) return; //no query button drawn\n\n\t//detect status\n\tif (!status) {\n\t\tstatus = \"valid\";\n\t\tif (yasqe.queryValid === false) status = \"error\";\n\t}\n\n\tif (status != yasqe.queryStatus) {\n\t\tqueryButton\n\t\t\t.empty()\n\t\t\t.removeClass(function(index, classNames) {\n\t\t\t\treturn classNames.split(\" \").filter(function(c) {\n\t\t\t\t\t//remove classname from previous status\n\t\t\t\t\treturn c.indexOf(\"query_\") == 0;\n\t\t\t\t}).join(\" \");\n\t\t\t});\n\n\t\tif (status == \"busy\") {\n\t\t\tqueryButton.append($('
', {\n\t\t\t\tclass: 'loader',\n\t\t\t}));\n\t\t\tyasqe.queryStatus = status;\n\t\t} else if (status == \"valid\" || status == \"error\") {\n\t\t\tqueryButton.addClass(\"query_\" + status);\n\t\t\tyutils.svg.draw(queryButton, imgs[queryButtonIds[status]]);\n\t\t\tyasqe.queryStatus = status;\n\t\t}\n\t}\n};\n/**\n * Initialize YASQE from an existing text area (see http://codemirror.net/doc/manual.html#fromTextArea for more info)\n *\n * @method YASQE.fromTextArea\n * @param textArea {DOM element}\n * @param config {object}\n * @returns {doc} YASQE document\n */\nroot.fromTextArea = function(textAreaEl, config) {\n\tconfig = extendConfig(config);\n\t//add yasqe div as parent (needed for styles to be manageable and scoped).\n\t//In this case, I -also- put it as parent el of the text area. This is wrapped in a div now\n\tvar rootEl = $(\"
\", {\n\t\tclass: 'yasqe'\n\t}).insertBefore($(textAreaEl)).append($(textAreaEl));\n\tvar yasqe = extendCmInstance(CodeMirror.fromTextArea(textAreaEl, config));\n\tpostProcessCmElement(yasqe);\n\treturn yasqe;\n};\n\n\nroot.storeQuery = function(yasqe) {\n\tvar storageId = utils.getPersistencyId(yasqe, yasqe.options.persistent);\n\tif (storageId) {\n\t\tyutils.storage.set(storageId, yasqe.getValue(), \"month\");\n\t}\n};\nroot.commentLines = function(yasqe) {\n\tvar startLine = yasqe.getCursor(true).line;\n\tvar endLine = yasqe.getCursor(false).line;\n\tvar min = Math.min(startLine, endLine);\n\tvar max = Math.max(startLine, endLine);\n\n\t// if all lines start with #, remove this char. Otherwise add this char\n\tvar linesAreCommented = true;\n\tfor (var i = min; i <= max; i++) {\n\t\tvar line = yasqe.getLine(i);\n\t\tif (line.length == 0 || line.substring(0, 1) != \"#\") {\n\t\t\tlinesAreCommented = false;\n\t\t\tbreak;\n\t\t}\n\t}\n\tfor (var i = min; i <= max; i++) {\n\t\tif (linesAreCommented) {\n\t\t\t// lines are commented, so remove comments\n\t\t\tyasqe.replaceRange(\"\", {\n\t\t\t\tline: i,\n\t\t\t\tch: 0\n\t\t\t}, {\n\t\t\t\tline: i,\n\t\t\t\tch: 1\n\t\t\t});\n\t\t} else {\n\t\t\t// Not all lines are commented, so add comments\n\t\t\tyasqe.replaceRange(\"#\", {\n\t\t\t\tline: i,\n\t\t\t\tch: 0\n\t\t\t});\n\t\t}\n\n\t}\n};\n\nroot.copyLineUp = function(yasqe) {\n\tvar cursor = yasqe.getCursor();\n\tvar lineCount = yasqe.lineCount();\n\t// First create new empty line at end of text\n\tyasqe.replaceRange(\"\\n\", {\n\t\tline: lineCount - 1,\n\t\tch: yasqe.getLine(lineCount - 1).length\n\t});\n\t// Copy all lines to their next line\n\tfor (var i = lineCount; i > cursor.line; i--) {\n\t\tvar line = yasqe.getLine(i - 1);\n\t\tyasqe.replaceRange(line, {\n\t\t\tline: i,\n\t\t\tch: 0\n\t\t}, {\n\t\t\tline: i,\n\t\t\tch: yasqe.getLine(i).length\n\t\t});\n\t}\n};\nroot.copyLineDown = function(yasqe) {\n\troot.copyLineUp(yasqe);\n\t// Make sure cursor goes one down (we are copying downwards)\n\tvar cursor = yasqe.getCursor();\n\tcursor.line++;\n\tyasqe.setCursor(cursor);\n};\nroot.doAutoFormat = function(yasqe) {\n\tif (yasqe.somethingSelected()) {\n\t\tvar to = {\n\t\t\tline: yasqe.getCursor(false).line,\n\t\t\tch: yasqe.getSelection().length\n\t\t};\n\t\tautoFormatRange(yasqe, yasqe.getCursor(true), to);\n\t} else {\n\t\tvar totalLines = yasqe.lineCount();\n\t\tvar totalChars = yasqe.getTextArea().value.length;\n\t\tautoFormatRange(yasqe, {\n\t\t\tline: 0,\n\t\t\tch: 0\n\t\t}, {\n\t\t\tline: totalLines,\n\t\t\tch: totalChars\n\t\t});\n\t}\n\n};\n\n\nvar autoFormatRange = function(yasqe, from, to) {\n\tvar absStart = yasqe.indexFromPos(from);\n\tvar absEnd = yasqe.indexFromPos(to);\n\t// Insert additional line breaks where necessary according to the\n\t// mode's syntax\n\tvar res = autoFormatLineBreaks(yasqe.getValue(), absStart, absEnd);\n\n\t// Replace and auto-indent the range\n\tyasqe.operation(function() {\n\t\tyasqe.replaceRange(res, from, to);\n\t\tvar startLine = yasqe.posFromIndex(absStart).line;\n\t\tvar endLine = yasqe.posFromIndex(absStart + res.length).line;\n\t\tfor (var i = startLine; i <= endLine; i++) {\n\t\t\tyasqe.indentLine(i, \"smart\");\n\t\t}\n\t});\n};\n\nvar autoFormatLineBreaks = function(text, start, end) {\n\ttext = text.substring(start, end);\n\tvar breakAfterArray = [\n\t\t[\"keyword\", \"ws\", \"prefixed\", \"ws\", \"uri\"], // i.e. prefix declaration\n\t\t[\"keyword\", \"ws\", \"uri\"] // i.e. base\n\t];\n\tvar breakAfterCharacters = [\"{\", \".\", \";\"];\n\tvar breakBeforeCharacters = [\"}\"];\n\tvar getBreakType = function(stringVal, type) {\n\t\tfor (var i = 0; i < breakAfterArray.length; i++) {\n\t\t\tif (stackTrace.valueOf().toString() == breakAfterArray[i].valueOf()\n\t\t\t\t.toString()) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tfor (var i = 0; i < breakAfterCharacters.length; i++) {\n\t\t\tif (stringVal == breakAfterCharacters[i]) {\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t}\n\t\tfor (var i = 0; i < breakBeforeCharacters.length; i++) {\n\t\t\t// don't want to issue 'breakbefore' AND 'breakafter', so check\n\t\t\t// current line\n\t\t\tif ($.trim(currentLine) != '' && stringVal == breakBeforeCharacters[i]) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t};\n\tvar formattedQuery = \"\";\n\tvar currentLine = \"\";\n\tvar stackTrace = [];\n\tCodeMirror.runMode(text, \"sparql11\", function(stringVal, type) {\n\t\tstackTrace.push(type);\n\t\tvar breakType = getBreakType(stringVal, type);\n\t\tif (breakType != 0) {\n\t\t\tif (breakType == 1) {\n\t\t\t\tformattedQuery += stringVal + \"\\n\";\n\t\t\t\tcurrentLine = \"\";\n\t\t\t} else { // (-1)\n\t\t\t\tformattedQuery += \"\\n\" + stringVal;\n\t\t\t\tcurrentLine = stringVal;\n\t\t\t}\n\t\t\tstackTrace = [];\n\t\t} else {\n\t\t\tcurrentLine += stringVal;\n\t\t\tformattedQuery += stringVal;\n\t\t}\n\t\tif (stackTrace.length == 1 && stackTrace[0] == \"sp-ws\")\n\t\t\tstackTrace = [];\n\t});\n\treturn $.trim(formattedQuery.replace(/\\n\\s*\\n/g, '\\n'));\n};\n\nrequire('./sparql.js'),\n\trequire('./defaults.js');\nroot.$ = $;\nroot.version = {\n\t\"CodeMirror\": CodeMirror.version,\n\t\"YASQE\": require(\"../package.json\").version,\n\t\"jquery\": $.fn.jquery,\n\t\"yasgui-utils\": yutils.version\n};\n","var CodeMirror = require('codemirror'),\n\ttokenUtils = require('./tokenUtils.js');\n\n\"use strict\";\nvar lookFor = \"PREFIX\";\nmodule.exports = {\n\tfindFirstPrefixLine: function(cm) {\n\t\tvar lastLine = cm.lastLine();\n\t\tfor (var i = 0; i <= lastLine; ++i) {\n\t\t\tif (findFirstPrefix(cm, i) >= 0) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction findFirstPrefix(cm, line, ch, lineText) {\n\tif (!ch) ch = 0;\n\tif (!lineText) lineText = cm.getLine(line);\n\tlineText = lineText.toUpperCase();\n\tfor (var at = ch, pass = 0;;) {\n\t\tvar found = lineText.indexOf(lookFor, at);\n\t\tif (found == -1) {\n\t\t\tif (pass == 1)\n\t\t\t\tbreak;\n\t\t\tpass = 1;\n\t\t\tat = lineText.length;\n\t\t\tcontinue;\n\t\t}\n\t\tif (pass == 1 && found < ch)\n\t\t\tbreak;\n\t\ttokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));\n\t\tif (!/^(comment|string)/.test(tokenType))\n\t\t\treturn found + 1;\n\t\tat = found - 1;\n\t}\n}\n\nCodeMirror.registerHelper(\"fold\", \"prefix\", function(cm, start) {\n\tvar line = start.line,\n\t\tlineText = cm.getLine(line);\n\n\tvar startCh, tokenType;\n\n\tfunction hasPreviousPrefix() {\n\t\tvar hasPreviousPrefix = false;\n\t\tfor (var i = line - 1; i >= 0; i--) {\n\t\t\tif (cm.getLine(i).toUpperCase().indexOf(lookFor) >= 0) {\n\t\t\t\thasPreviousPrefix = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn hasPreviousPrefix;\n\t}\n\n\n\tfunction findOpening(openCh) {\n\t\tfor (var at = start.ch, pass = 0;;) {\n\t\t\tvar found = at <= 0 ? -1 : lineText.lastIndexOf(openCh, at - 1);\n\t\t\tif (found == -1) {\n\t\t\t\tif (pass == 1)\n\t\t\t\t\tbreak;\n\t\t\t\tpass = 1;\n\t\t\t\tat = lineText.length;\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (pass == 1 && found < start.ch)\n\t\t\t\tbreak;\n\t\t\ttokenType = cm.getTokenTypeAt(CodeMirror.Pos(line, found + 1));\n\t\t\tif (!/^(comment|string)/.test(tokenType))\n\t\t\t\treturn found + 1;\n\t\t\tat = found - 1;\n\t\t}\n\t}\n\tvar getLastPrefixPos = function(line, ch) {\n\t\tvar prefixKeywordToken = cm.getTokenAt(CodeMirror.Pos(line, ch + 1));\n\t\tif (!prefixKeywordToken || prefixKeywordToken.type != \"keyword\") return -1;\n\t\tvar prefixShortname = tokenUtils.getNextNonWsToken(cm, line, prefixKeywordToken.end + 1);\n\t\tif (!prefixShortname || prefixShortname.type != \"string-2\") return -1; //missing prefix keyword shortname\n\t\tvar prefixUri = tokenUtils.getNextNonWsToken(cm, line, prefixShortname.end + 1);\n\t\tif (!prefixUri || prefixUri.type != \"variable-3\") return -1; //missing prefix uri\n\t\treturn prefixUri.end;\n\t}\n\n\t//only use opening prefix declaration\n\tif (hasPreviousPrefix())\n\t\treturn;\n\tvar prefixStart = findFirstPrefix(cm, line, start.ch, lineText);\n\n\tif (prefixStart == null)\n\t\treturn;\n\tvar stopAt = '{'; //if this char is there, we won't have a chance of finding more prefixes\n\tvar stopAtNextLine = false;\n\tvar count = 1,\n\t\tlastLine = cm.lastLine(),\n\t\tend, endCh;\n\tvar prefixEndChar = getLastPrefixPos(line, prefixStart);\n\tvar prefixEndLine = line;\n\n\touter: for (var i = line; i <= lastLine; ++i) {\n\t\tif (stopAtNextLine)\n\t\t\tbreak;\n\t\tvar text = cm.getLine(i),\n\t\t\tpos = i == line ? prefixStart + 1 : 0;\n\n\t\tfor (;;) {\n\t\t\tif (!stopAtNextLine && text.indexOf(stopAt) >= 0)\n\t\t\t\tstopAtNextLine = true;\n\n\t\t\tvar nextPrefixDeclaration = text.toUpperCase()\n\t\t\t\t.indexOf(lookFor, pos);\n\n\t\t\tif (nextPrefixDeclaration >= 0) {\n\t\t\t\tif ((endCh = getLastPrefixPos(i, nextPrefixDeclaration)) > 0) {\n\t\t\t\t\tprefixEndChar = endCh;\n\t\t\t\t\tprefixEndLine = i;\n\t\t\t\t\tpos = prefixEndChar;\n\t\t\t\t}\n\t\t\t\tpos++;\n\t\t\t} else {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\treturn {\n\t\tfrom: CodeMirror.Pos(line, prefixStart + lookFor.length),\n\t\tto: CodeMirror.Pos(prefixEndLine, prefixEndChar)\n\t};\n});","'use strict';\n/**\n * Append prefix declaration to list of prefixes in query window.\n * \n * @param yasqe\n * @param prefix\n */\nvar addPrefixes = function(yasqe, prefixes) {\n\tvar existingPrefixes = yasqe.getPrefixesFromQuery();\n\t//for backwards compatability, we stil support prefixes value as string (e.g. 'rdf: '\n\tif (typeof prefixes == \"string\") {\n\t\taddPrefixAsString(yasqe, prefixes);\n\t} else {\n\t\tfor (var pref in prefixes) {\n\t\t\tif (!(pref in existingPrefixes))\n\t\t\t\taddPrefixAsString(yasqe, pref + \": <\" + prefixes[pref] + \">\");\n\t\t}\n\t}\n\tyasqe.collapsePrefixes(false);\n};\n\nvar addPrefixAsString = function(yasqe, prefixString) {\n\tvar lastPrefix = null;\n\tvar lastPrefixLine = 0;\n\tvar numLines = yasqe.lineCount();\n\tfor (var i = 0; i < numLines; i++) {\n\t\tvar firstToken = yasqe.getNextNonWsToken(i);\n\t\tif (firstToken != null && (firstToken.string == \"PREFIX\" || firstToken.string == \"BASE\")) {\n\t\t\tlastPrefix = firstToken;\n\t\t\tlastPrefixLine = i;\n\t\t}\n\t}\n\n\tif (lastPrefix == null) {\n\t\tyasqe.replaceRange(\"PREFIX \" + prefixString + \"\\n\", {\n\t\t\tline: 0,\n\t\t\tch: 0\n\t\t});\n\t} else {\n\t\tvar previousIndent = getIndentFromLine(yasqe, lastPrefixLine);\n\t\tyasqe.replaceRange(\"\\n\" + previousIndent + \"PREFIX \" + prefixString, {\n\t\t\tline: lastPrefixLine\n\t\t});\n\t}\n\tyasqe.collapsePrefixes(false);\n};\nvar removePrefixes = function(yasqe, prefixes) {\n\tvar escapeRegex = function(string) {\n\t\t//taken from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript/3561711#3561711\n\t\treturn string.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n\t}\n\tfor (var pref in prefixes) {\n\t\tyasqe.setValue(yasqe.getValue().replace(new RegExp(\"PREFIX\\\\s*\" + pref + \":\\\\s*\" + escapeRegex(\"<\" + prefixes[pref] + \">\") + \"\\\\s*\", \"ig\"), ''));\n\t}\n\tyasqe.collapsePrefixes(false);\n\n};\n\n/**\n * Get defined prefixes from query as array, in format {\"prefix:\" \"uri\"}\n * \n * @param cm\n * @returns {Array}\n */\nvar getPrefixesFromQuery = function(yasqe) {\n\tvar queryPrefixes = {};\n\tvar shouldContinue = true;\n\tvar getPrefixesFromLine = function(lineOffset, colOffset) {\n\t\tif (!shouldContinue) return;\n\t\tif (!colOffset) colOffset = 1;\n\t\tvar token = yasqe.getNextNonWsToken(i, colOffset);\n\t\tif (token) {\n\t\t\tif (token.state.possibleCurrent.indexOf(\"PREFIX\") == -1 && token.state.possibleNext.indexOf(\"PREFIX\") == -1) shouldContinue = false; //we are beyond the place in the query where we can enter prefixes\n\t\t\tif (token.string.toUpperCase() == \"PREFIX\") {\n\t\t\t\tvar prefix = yasqe.getNextNonWsToken(i, token.end + 1);\n\t\t\t\tif (prefix) {\n\t\t\t\t\tvar uri = yasqe.getNextNonWsToken(i, prefix.end + 1);\n\t\t\t\t\tif (uri) {\n\t\t\t\t\t\tvar uriString = uri.string;\n\t\t\t\t\t\tif (uriString.indexOf(\"<\") == 0)\n\t\t\t\t\t\t\turiString = uriString.substring(1);\n\t\t\t\t\t\tif (uriString.slice(-1) == \">\")\n\t\t\t\t\t\t\turiString = uriString\n\t\t\t\t\t\t\t.substring(0, uriString.length - 1);\n\t\t\t\t\t\tqueryPrefixes[prefix.string.slice(0, -1)] = uriString;\n\n\t\t\t\t\t\tgetPrefixesFromLine(lineOffset, uri.end + 1);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgetPrefixesFromLine(lineOffset, prefix.end + 1);\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\tgetPrefixesFromLine(lineOffset, token.end + 1);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tgetPrefixesFromLine(lineOffset, token.end + 1);\n\t\t\t}\n\t\t}\n\t};\n\n\n\tvar numLines = yasqe.lineCount();\n\tfor (var i = 0; i < numLines; i++) {\n\t\tif (!shouldContinue) break;\n\t\tgetPrefixesFromLine(i);\n\n\t}\n\treturn queryPrefixes;\n};\n\n/**\n * Get the used indentation for a certain line\n * \n * @param yasqe\n * @param line\n * @param charNumber\n * @returns\n */\nvar getIndentFromLine = function(yasqe, line, charNumber) {\n\tif (charNumber == undefined)\n\t\tcharNumber = 1;\n\tvar token = yasqe.getTokenAt({\n\t\tline: line,\n\t\tch: charNumber\n\t});\n\tif (token == null || token == undefined || token.type != \"ws\") {\n\t\treturn \"\";\n\t} else {\n\t\treturn token.string + getIndentFromLine(yasqe, line, token.end + 1);\n\t};\n};\n\nmodule.exports = {\n\taddPrefixes: addPrefixes,\n\tgetPrefixesFromQuery: getPrefixesFromQuery,\n\tremovePrefixes: removePrefixes\n};","'use strict';\nvar $ = require('jquery'),\n\tYASQE = require('./main.js');\n\nYASQE.getAjaxConfig = function(yasqe, callbackOrConfig) {\n\tvar callback = (typeof callbackOrConfig == \"function\" ? callbackOrConfig : null);\n\tvar config = (typeof callbackOrConfig == \"object\" ? callbackOrConfig : {});\n\n\tif (yasqe.options.sparql)\n\t\tconfig = $.extend({}, yasqe.options.sparql, config);\n\n\t//for backwards compatability, make sure we copy sparql handlers to sparql callbacks\n\tif (config.handlers)\n\t\t$.extend(true, config.callbacks, config.handlers);\n\n\t\n\tif (!config.endpoint || config.endpoint.length == 0)\n\t\treturn; // nothing to query!\n\n\t/**\n\t * initialize ajax config\n\t */\n\tvar ajaxConfig = {\n\t\turl: (typeof config.endpoint == \"function\" ? config.endpoint(yasqe) : config.endpoint),\n\t\ttype: (typeof config.requestMethod == \"function\" ? config.requestMethod(yasqe) : config.requestMethod),\n\t\theaders: {\n\t\t\tAccept: getAcceptHeader(yasqe, config),\n\t\t}\n\t};\n\tif (config.xhrFields) ajaxConfig.xhrFields = config.xhrFields;\n\t/**\n\t * add complete, beforesend, etc callbacks (if specified)\n\t */\n\tvar handlerDefined = false;\n\tif (config.callbacks) {\n\t\tfor (var handler in config.callbacks) {\n\t\t\tif (config.callbacks[handler]) {\n\t\t\t\thandlerDefined = true;\n\t\t\t\tajaxConfig[handler] = config.callbacks[handler];\n\t\t\t}\n\t\t}\n\t}\n\tajaxConfig.data = yasqe.getUrlArguments(config);\n\tif (!handlerDefined && !callback)\n\t\treturn; // ok, we can query, but have no callbacks. just stop now\n\n\t// if only callback is passed as arg, add that on as 'onComplete' callback\n\tif (callback)\n\t\tajaxConfig.complete = callback;\n\n\n\n\t/**\n\t * merge additional request headers\n\t */\n\tif (config.headers && !$.isEmptyObject(config.headers))\n\t\t$.extend(ajaxConfig.headers, config.headers);\n\n\n\tvar queryStart = new Date();\n\tvar updateYasqe = function() {\n\t\tyasqe.lastQueryDuration = new Date() - queryStart;\n\t\tYASQE.updateQueryButton(yasqe);\n\t\tyasqe.setBackdrop(false);\n\t};\n\t//Make sure the query button is updated again on complete\n\tvar completeCallbacks = [\n\t\tfunction(){require('./main.js').signal(yasqe, 'queryFinish', arguments)},\n\t\tupdateYasqe\n\t];\n\n\tif (ajaxConfig.complete) {\n\t\tcompleteCallbacks.push(ajaxConfig.complete);\n\t}\n\tajaxConfig.complete = completeCallbacks;\n\treturn ajaxConfig;\n};\n\n\n\nYASQE.executeQuery = function(yasqe, callbackOrConfig) {\n\tYASQE.signal(yasqe, 'query', yasqe, callbackOrConfig);\n\tYASQE.updateQueryButton(yasqe, \"busy\");\n\tyasqe.setBackdrop(true);\n\tyasqe.xhr = $.ajax(YASQE.getAjaxConfig(yasqe, callbackOrConfig));\n};\n\n\nYASQE.getUrlArguments = function(yasqe, config) {\n\tvar queryMode = yasqe.getQueryMode();\n\tvar data = [{\n\t\tname: yasqe.getQueryMode(), //either 'update' or 'query'\n\t\tvalue: (config.getQueryForAjax? config.getQueryForAjax(yasqe): yasqe.getValue())\n\t}];\n\n\t/**\n\t * add named graphs to ajax config\n\t */\n\tif (config.namedGraphs && config.namedGraphs.length > 0) {\n\t\tvar argName = (queryMode == \"query\" ? \"named-graph-uri\" : \"using-named-graph-uri \");\n\t\tfor (var i = 0; i < config.namedGraphs.length; i++)\n\t\t\tdata.push({\n\t\t\t\tname: argName,\n\t\t\t\tvalue: config.namedGraphs[i]\n\t\t\t});\n\t}\n\t/**\n\t * add default graphs to ajax config\n\t */\n\tif (config.defaultGraphs && config.defaultGraphs.length > 0) {\n\t\tvar argName = (queryMode == \"query\" ? \"default-graph-uri\" : \"using-graph-uri \");\n\t\tfor (var i = 0; i < config.defaultGraphs.length; i++)\n\t\t\tdata.push({\n\t\t\t\tname: argName,\n\t\t\t\tvalue: config.defaultGraphs[i]\n\t\t\t});\n\t}\n\n\t/**\n\t * add additional request args\n\t */\n\tif (config.args && config.args.length > 0) $.merge(data, config.args);\n\n\treturn data;\n}\nvar getAcceptHeader = function(yasqe, config) {\n\tvar acceptHeader = null;\n\tif (config.acceptHeader && !config.acceptHeaderGraph && !config.acceptHeaderSelect && !config.acceptHeaderUpdate) {\n\t\t//this is the old config. For backwards compatability, keep supporting it\n\t\tif (typeof config.acceptHeader == \"function\") {\n\t\t\tacceptHeader = config.acceptHeader(yasqe);\n\t\t} else {\n\t\t\tacceptHeader = config.acceptHeader;\n\t\t}\n\t} else {\n\t\tif (yasqe.getQueryMode() == \"update\") {\n\t\t\tacceptHeader = (typeof config.acceptHeader == \"function\" ? config.acceptHeaderUpdate(yasqe) : config.acceptHeaderUpdate);\n\t\t} else {\n\t\t\tvar qType = yasqe.getQueryType();\n\t\t\tif (qType == \"DESCRIBE\" || qType == \"CONSTRUCT\") {\n\t\t\t\tacceptHeader = (typeof config.acceptHeaderGraph == \"function\" ? config.acceptHeaderGraph(yasqe) : config.acceptHeaderGraph);\n\t\t\t} else {\n\t\t\t\tacceptHeader = (typeof config.acceptHeaderSelect == \"function\" ? config.acceptHeaderSelect(yasqe) : config.acceptHeaderSelect);\n\t\t\t}\n\t\t}\n\t}\n\treturn acceptHeader;\n};\n\nmodule.exports = {\n\tgetAjaxConfig: YASQE.getAjaxConfig\n}\n","'use strict';\n/**\n * When typing a query, this query is sometimes syntactically invalid, causing\n * the current tokens to be incorrect This causes problem for autocompletion.\n * http://bla might result in two tokens: http:// and bla. We'll want to combine\n * these\n * \n * @param yasqe {doc}\n * @param token {object}\n * @param cursor {object}\n * @return token {object}\n * @method YASQE.getCompleteToken\n */\nvar getCompleteToken = function(yasqe, token, cur) {\n\tif (!cur) {\n\t\tcur = yasqe.getCursor();\n\t}\n\tif (!token) {\n\t\ttoken = yasqe.getTokenAt(cur);\n\t}\n\tvar prevToken = yasqe.getTokenAt({\n\t\tline: cur.line,\n\t\tch: token.start\n\t});\n\t// not start of line, and not whitespace\n\tif (\n\t\tprevToken.type != null && prevToken.type != \"ws\" && token.type != null && token.type != \"ws\"\n\t) {\n\t\ttoken.start = prevToken.start;\n\t\ttoken.string = prevToken.string + token.string;\n\t\treturn getCompleteToken(yasqe, token, {\n\t\t\tline: cur.line,\n\t\t\tch: prevToken.start\n\t\t}); // recursively, might have multiple tokens which it should include\n\t} else if (token.type != null && token.type == \"ws\") {\n\t\t//always keep 1 char of whitespace between tokens. Otherwise, autocompletions might end up next to the previous node, without whitespace between them\n\t\ttoken.start = token.start + 1;\n\t\ttoken.string = token.string.substring(1);\n\t\treturn token;\n\t} else {\n\t\treturn token;\n\t}\n};\nvar getPreviousNonWsToken = function(yasqe, line, token) {\n\tvar previousToken = yasqe.getTokenAt({\n\t\tline: line,\n\t\tch: token.start\n\t});\n\tif (previousToken != null && previousToken.type == \"ws\") {\n\t\tpreviousToken = getPreviousNonWsToken(yasqe, line, previousToken);\n\t}\n\treturn previousToken;\n}\nvar getNextNonWsToken = function(yasqe, lineNumber, charNumber) {\n\tif (charNumber == undefined)\n\t\tcharNumber = 1;\n\tvar token = yasqe.getTokenAt({\n\t\tline: lineNumber,\n\t\tch: charNumber\n\t});\n\tif (token == null || token == undefined || token.end < charNumber) {\n\t\treturn null;\n\t}\n\tif (token.type == \"ws\") {\n\t\treturn getNextNonWsToken(yasqe, lineNumber, token.end + 1);\n\t}\n\treturn token;\n};\n\nmodule.exports = {\n\tgetPreviousNonWsToken: getPreviousNonWsToken,\n\tgetCompleteToken: getCompleteToken,\n\tgetNextNonWsToken: getNextNonWsToken,\n};","'use strict';\nvar $ = require('jquery'),\n\tutils = require('./utils.js');\n\n/**\n * Write our own tooltip, to avoid loading another library for just this functionality. For now, we only use tooltip for showing parse errors, so this is quite a tailored solution\n * Requirements: \n * \t\tposition tooltip within codemirror frame as much as possible, to avoid z-index issues with external things on page\n * \t\tuse html as content\n */\nmodule.exports = function(yasqe, parent, html) {\n\tvar parent = $(parent);\n\tvar tooltip;\n\tparent.hover(function() {\n\t\t\tif (typeof html == \"function\") html = html();\n\t\t\ttooltip = $(\"
\").addClass('yasqe_tooltip').html(html).appendTo(parent);\n\t\t\trepositionTooltip();\n\t\t},\n\t\tfunction() {\n\t\t\t$(\".yasqe_tooltip\").remove();\n\t\t});\n\n\n\n\t/**\n\t * only need to take into account top and bottom offset for this usecase\n\t */\n\tvar repositionTooltip = function() {\n\t\tif ($(yasqe.getWrapperElement()).offset().top >= tooltip.offset().top) {\n\t\t\t//shit, move the tooltip down. The tooltip now hovers over the top edge of the yasqe instance\n\t\t\ttooltip.css('bottom', 'auto');\n\t\t\ttooltip.css('top', '26px');\n\t\t}\n\t};\n};","'use strict';\nvar $ = require('jquery');\n\nvar keyExists = function(objectToTest, key) {\n\tvar exists = false;\n\ttry {\n\t\tif (objectToTest[key] !== undefined)\n\t\t\texists = true;\n\t} catch (e) {}\n\treturn exists;\n};\n\nvar getPersistencyId = function(yasqe, persistentIdCreator) {\n\tvar persistencyId = null;\n\n\tif (persistentIdCreator) {\n\t\tif (typeof persistentIdCreator == \"string\") {\n\t\t\tpersistencyId = persistentIdCreator;\n\t\t} else {\n\t\t\tpersistencyId = persistentIdCreator(yasqe);\n\t\t}\n\t}\n\treturn persistencyId;\n};\n\nvar elementsOverlap = (function() {\n\tfunction getPositions(elem) {\n\t\tvar pos, width, height;\n\t\tpos = $(elem).offset();\n\t\twidth = $(elem).width();\n\t\theight = $(elem).height();\n\t\treturn [\n\t\t\t[pos.left, pos.left + width],\n\t\t\t[pos.top, pos.top + height]\n\t\t];\n\t}\n\n\tfunction comparePositions(p1, p2) {\n\t\tvar r1, r2;\n\t\tr1 = p1[0] < p2[0] ? p1 : p2;\n\t\tr2 = p1[0] < p2[0] ? p2 : p1;\n\t\treturn r1[1] > r2[0] || r1[0] === r2[0];\n\t}\n\n\treturn function(a, b) {\n\t\tvar pos1 = getPositions(a),\n\t\t\tpos2 = getPositions(b);\n\t\treturn comparePositions(pos1[0], pos2[0]) && comparePositions(pos1[1], pos2[1]);\n\t};\n})();\n\nmodule.exports = {\n\tkeyExists: keyExists,\n\tgetPersistencyId: getPersistencyId,\n\telementsOverlap: elementsOverlap,\n};"],"sourceRoot":"/source/"}