'use strict';var $jscomp=$jscomp||{};$jscomp.scope={};$jscomp.ASSUME_ES5=false;$jscomp.ASSUME_NO_NATIVE_MAP=false;$jscomp.ASSUME_NO_NATIVE_SET=false;$jscomp.SIMPLE_FROUND_POLYFILL=false;$jscomp.defineProperty=$jscomp.ASSUME_ES5||typeof Object.defineProperties=="function"?Object.defineProperty:function(target,property,descriptor){descriptor=descriptor;if(target==Array.prototype||target==Object.prototype)return;target[property]=descriptor.value};
$jscomp.getGlobal=function(maybeGlobal){return typeof window!="undefined"&&window===maybeGlobal?maybeGlobal:typeof global!="undefined"&&global!=null?global:maybeGlobal};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.polyfill=function(target,polyfill,fromLang,toLang){if(!polyfill)return;var obj=$jscomp.global;var split=target.split(".");for(var i=0;i<split.length-1;i++){var key=split[i];if(!(key in obj))obj[key]={};obj=obj[key]}var property=split[split.length-1];var orig=obj[property];var impl=polyfill(orig);if(impl==orig||impl==null)return;$jscomp.defineProperty(obj,property,{configurable:true,writable:true,value:impl})};
$jscomp.polyfill("Array.prototype.copyWithin",function(orig){if(orig)return orig;var polyfill=function(target,start,opt_end){var len=this.length;target=toInteger(target);start=toInteger(start);var end=opt_end===undefined?len:toInteger(opt_end);var to=target<0?Math.max(len+target,0):Math.min(target,len);var from=start<0?Math.max(len+start,0):Math.min(start,len);var final=end<0?Math.max(len+end,0):Math.min(end,len);if(to<from)while(from<final)if(from in this)this[to++]=this[from++];else{delete this[to++];
from++}else{final=Math.min(final,len+from-to);to+=final-from;while(final>from)if(--final in this)this[--to]=this[final];else delete this[--to]}return this};function toInteger(arg){var n=Number(arg);if(n===Infinity||n===-Infinity)return n;return n|0}return polyfill},"es6","es3");$jscomp.arrayIteratorImpl=function(array){var index=0;return function(){if(index<array.length)return{done:false,value:array[index++]};else return{done:true}}};$jscomp.arrayIterator=function(array){return{next:$jscomp.arrayIteratorImpl(array)}};
$jscomp.SYMBOL_PREFIX="jscomp_symbol_";$jscomp.initSymbol=function(){$jscomp.initSymbol=function(){};if(!$jscomp.global["Symbol"])$jscomp.global["Symbol"]=$jscomp.Symbol};$jscomp.SymbolClass=function(id,opt_description){this.$jscomp$symbol$id_=id;this.description;$jscomp.defineProperty(this,"description",{configurable:true,writable:true,value:opt_description})};$jscomp.SymbolClass.prototype.toString=function(){return this.$jscomp$symbol$id_};
$jscomp.Symbol=function(){var counter=0;function Symbol(opt_description){if(this instanceof Symbol)throw new TypeError("Symbol is not a constructor");return new $jscomp.SymbolClass($jscomp.SYMBOL_PREFIX+(opt_description||"")+"_"+counter++,opt_description)}return Symbol}();
$jscomp.initSymbolIterator=function(){$jscomp.initSymbol();var symbolIterator=$jscomp.global["Symbol"].iterator;if(!symbolIterator)symbolIterator=$jscomp.global["Symbol"].iterator=$jscomp.global["Symbol"]("Symbol.iterator");if(typeof Array.prototype[symbolIterator]!="function")$jscomp.defineProperty(Array.prototype,symbolIterator,{configurable:true,writable:true,value:function(){return $jscomp.iteratorPrototype($jscomp.arrayIteratorImpl(this))}});$jscomp.initSymbolIterator=function(){}};
$jscomp.initSymbolAsyncIterator=function(){$jscomp.initSymbol();var symbolAsyncIterator=$jscomp.global["Symbol"].asyncIterator;if(!symbolAsyncIterator)symbolAsyncIterator=$jscomp.global["Symbol"].asyncIterator=$jscomp.global["Symbol"]("Symbol.asyncIterator");$jscomp.initSymbolAsyncIterator=function(){}};$jscomp.iteratorPrototype=function(next){$jscomp.initSymbolIterator();var iterator={next:next};iterator[$jscomp.global["Symbol"].iterator]=function(){return this};return iterator};
$jscomp.iteratorFromArray=function(array,transform){$jscomp.initSymbolIterator();if(array instanceof String)array=array+"";var i=0;var iter={next:function(){if(i<array.length){var index=i++;return{value:transform(index,array[index]),done:false}}iter.next=function(){return{done:true,value:void 0}};return iter.next()}};iter[Symbol.iterator]=function(){return iter};return iter};
$jscomp.polyfill("Array.prototype.entries",function(orig){if(orig)return orig;var polyfill=function(){return $jscomp.iteratorFromArray(this,function(i,v){return[i,v]})};return polyfill},"es6","es3");
$jscomp.polyfill("Array.prototype.fill",function(orig){if(orig)return orig;var polyfill=function(value,opt_start,opt_end){var length=this.length||0;if(opt_start<0)opt_start=Math.max(0,length+opt_start);if(opt_end==null||opt_end>length)opt_end=length;opt_end=Number(opt_end);if(opt_end<0)opt_end=Math.max(0,length+opt_end);for(var i=Number(opt_start||0);i<opt_end;i++)this[i]=value;return this};return polyfill},"es6","es3");
$jscomp.findInternal=function(array,callback,thisArg){if(array instanceof String)array=String(array);var len=array.length;for(var i=0;i<len;i++){var value=array[i];if(callback.call(thisArg,value,i,array))return{i:i,v:value}}return{i:-1,v:void 0}};$jscomp.polyfill("Array.prototype.find",function(orig){if(orig)return orig;var polyfill=function(callback,opt_thisArg){return $jscomp.findInternal(this,callback,opt_thisArg).v};return polyfill},"es6","es3");
$jscomp.polyfill("Array.prototype.findIndex",function(orig){if(orig)return orig;var polyfill=function(callback,opt_thisArg){return $jscomp.findInternal(this,callback,opt_thisArg).i};return polyfill},"es6","es3");
$jscomp.polyfill("Array.prototype.flat",function(orig){if(orig)return orig;var flat=function(depth){depth=depth===undefined?1:depth;var flattened=[];for(var i=0;i<this.length;i++){var element=this[i];if(Array.isArray(element)&&depth>0){var inner=Array.prototype.flat.call(element,depth-1);flattened.push.apply(flattened,inner)}else flattened.push(element)}return flattened};return flat},"es9","es5");
$jscomp.polyfill("Array.prototype.flatMap",function(orig){if(orig)return orig;var flatMap=function(callback,thisArg){var mapped=[];for(var i=0;i<this.length;i++){var result=callback.call(thisArg,this[i],i,this);if(Array.isArray(result))mapped.push.apply(mapped,result);else mapped.push(result)}return mapped};return flatMap},"es9","es5");
$jscomp.polyfill("Array.from",function(orig){if(orig)return orig;var polyfill=function(arrayLike,opt_mapFn,opt_thisArg){opt_mapFn=opt_mapFn!=null?opt_mapFn:function(x){return x};var result=[];var iteratorFunction=typeof Symbol!="undefined"&&Symbol.iterator&&arrayLike[Symbol.iterator];if(typeof iteratorFunction=="function"){arrayLike=iteratorFunction.call(arrayLike);var next;var k=0;while(!(next=arrayLike.next()).done)result.push(opt_mapFn.call(opt_thisArg,next.value,k++))}else{var len=arrayLike.length;
for(var i=0;i<len;i++)result.push(opt_mapFn.call(opt_thisArg,arrayLike[i],i))}return result};return polyfill},"es6","es3");$jscomp.polyfill("Object.is",function(orig){if(orig)return orig;var polyfill=function(left,right){if(left===right)return left!==0||1/left===1/right;else return left!==left&&right!==right};return polyfill},"es6","es3");
$jscomp.polyfill("Array.prototype.includes",function(orig){if(orig)return orig;var includes=function(searchElement,opt_fromIndex){var array=this;if(array instanceof String)array=String(array);var len=array.length;var i=opt_fromIndex||0;if(i<0)i=Math.max(i+len,0);for(;i<len;i++){var element=array[i];if(element===searchElement||Object.is(element,searchElement))return true}return false};return includes},"es7","es3");
$jscomp.polyfill("Array.prototype.keys",function(orig){if(orig)return orig;var polyfill=function(){return $jscomp.iteratorFromArray(this,function(i){return i})};return polyfill},"es6","es3");$jscomp.polyfill("Array.of",function(orig){if(orig)return orig;var polyfill=function(var_args){return Array.from(arguments)};return polyfill},"es6","es3");
$jscomp.polyfill("Array.prototype.values",function(orig){if(orig)return orig;var polyfill=function(){return $jscomp.iteratorFromArray(this,function(k,v){return v})};return polyfill},"es8","es3");$jscomp.makeIterator=function(iterable){var iteratorFunction=typeof Symbol!="undefined"&&Symbol.iterator&&iterable[Symbol.iterator];return iteratorFunction?iteratorFunction.call(iterable):$jscomp.arrayIterator(iterable)};$jscomp.FORCE_POLYFILL_PROMISE=false;
$jscomp.polyfill("Promise",function(NativePromise){if(NativePromise&&!$jscomp.FORCE_POLYFILL_PROMISE)return NativePromise;function AsyncExecutor(){this.batch_=null}AsyncExecutor.prototype.asyncExecute=function(f){if(this.batch_==null){this.batch_=[];var self=this;this.asyncExecuteFunction(function(){self.executeBatch_()})}this.batch_.push(f)};var nativeSetTimeout=$jscomp.global["setTimeout"];AsyncExecutor.prototype.asyncExecuteFunction=function(f){nativeSetTimeout(f,0)};AsyncExecutor.prototype.executeBatch_=
function(){while(this.batch_&&this.batch_.length){var executingBatch=this.batch_;this.batch_=[];for(var i=0;i<executingBatch.length;++i){var f=executingBatch[i];executingBatch[i]=null;try{f()}catch(error){this.asyncThrow_(error)}}}this.batch_=null};AsyncExecutor.prototype.asyncThrow_=function(exception){this.asyncExecuteFunction(function(){throw exception;})};var PromiseState={PENDING:0,FULFILLED:1,REJECTED:2};var PolyfillPromise=function(executor){this.state_=PromiseState.PENDING;this.result_=undefined;
this.onSettledCallbacks_=[];var resolveAndReject=this.createResolveAndReject_();try{executor(resolveAndReject.resolve,resolveAndReject.reject)}catch(e){resolveAndReject.reject(e)}};PolyfillPromise.prototype.createResolveAndReject_=function(){var thisPromise=this;var alreadyCalled=false;function firstCallWins(method){return function(x){if(!alreadyCalled){alreadyCalled=true;method.call(thisPromise,x)}}}return{resolve:firstCallWins(this.resolveTo_),reject:firstCallWins(this.reject_)}};PolyfillPromise.prototype.resolveTo_=
function(value){if(value===this)this.reject_(new TypeError("A Promise cannot resolve to itself"));else if(value instanceof PolyfillPromise)this.settleSameAsPromise_(value);else if(isObject(value))this.resolveToNonPromiseObj_(value);else this.fulfill_(value)};PolyfillPromise.prototype.resolveToNonPromiseObj_=function(obj){var thenMethod=undefined;try{thenMethod=obj.then}catch(error){this.reject_(error);return}if(typeof thenMethod=="function")this.settleSameAsThenable_(thenMethod,obj);else this.fulfill_(obj)};
function isObject(value){switch(typeof value){case "object":return value!=null;case "function":return true;default:return false}}PolyfillPromise.prototype.reject_=function(reason){this.settle_(PromiseState.REJECTED,reason)};PolyfillPromise.prototype.fulfill_=function(value){this.settle_(PromiseState.FULFILLED,value)};PolyfillPromise.prototype.settle_=function(settledState,valueOrReason){if(this.state_!=PromiseState.PENDING)throw new Error("Cannot settle("+settledState+", "+valueOrReason+"): Promise already settled in state"+
this.state_);this.state_=settledState;this.result_=valueOrReason;this.executeOnSettledCallbacks_()};PolyfillPromise.prototype.executeOnSettledCallbacks_=function(){if(this.onSettledCallbacks_!=null){for(var i=0;i<this.onSettledCallbacks_.length;++i)asyncExecutor.asyncExecute(this.onSettledCallbacks_[i]);this.onSettledCallbacks_=null}};var asyncExecutor=new AsyncExecutor;PolyfillPromise.prototype.settleSameAsPromise_=function(promise){var methods=this.createResolveAndReject_();promise.callWhenSettled_(methods.resolve,
methods.reject)};PolyfillPromise.prototype.settleSameAsThenable_=function(thenMethod,thenable){var methods=this.createResolveAndReject_();try{thenMethod.call(thenable,methods.resolve,methods.reject)}catch(error){methods.reject(error)}};PolyfillPromise.prototype.then=function(onFulfilled,onRejected){var resolveChild;var rejectChild;var childPromise=new PolyfillPromise(function(resolve,reject){resolveChild=resolve;rejectChild=reject});function createCallback(paramF,defaultF){if(typeof paramF=="function")return function(x){try{resolveChild(paramF(x))}catch(error){rejectChild(error)}};
else return defaultF}this.callWhenSettled_(createCallback(onFulfilled,resolveChild),createCallback(onRejected,rejectChild));return childPromise};PolyfillPromise.prototype.catch=function(onRejected){return this.then(undefined,onRejected)};PolyfillPromise.prototype.callWhenSettled_=function(onFulfilled,onRejected){var thisPromise=this;function callback(){switch(thisPromise.state_){case PromiseState.FULFILLED:onFulfilled(thisPromise.result_);break;case PromiseState.REJECTED:onRejected(thisPromise.result_);
break;default:throw new Error("Unexpected state: "+thisPromise.state_);}}if(this.onSettledCallbacks_==null)asyncExecutor.asyncExecute(callback);else this.onSettledCallbacks_.push(callback)};function resolvingPromise(opt_value){if(opt_value instanceof PolyfillPromise)return opt_value;else return new PolyfillPromise(function(resolve,reject){resolve(opt_value)})}PolyfillPromise["resolve"]=resolvingPromise;PolyfillPromise["reject"]=function(opt_reason){return new PolyfillPromise(function(resolve,reject){reject(opt_reason)})};
PolyfillPromise["race"]=function(thenablesOrValues){return new PolyfillPromise(function(resolve,reject){var iterator=$jscomp.makeIterator(thenablesOrValues);for(var iterRec=iterator.next();!iterRec.done;iterRec=iterator.next())resolvingPromise(iterRec.value).callWhenSettled_(resolve,reject)})};PolyfillPromise["all"]=function(thenablesOrValues){var iterator=$jscomp.makeIterator(thenablesOrValues);var iterRec=iterator.next();if(iterRec.done)return resolvingPromise([]);else return new PolyfillPromise(function(resolveAll,
rejectAll){var resultsArray=[];var unresolvedCount=0;function onFulfilled(i){return function(ithResult){resultsArray[i]=ithResult;unresolvedCount--;if(unresolvedCount==0)resolveAll(resultsArray)}}do{resultsArray.push(undefined);unresolvedCount++;resolvingPromise(iterRec.value).callWhenSettled_(onFulfilled(resultsArray.length-1),rejectAll);iterRec=iterator.next()}while(!iterRec.done)})};return PolyfillPromise},"es6","es3");
$jscomp.polyfill("Promise.prototype.finally",function(orig){if(orig)return orig;var polyfill=function(onFinally){return this.then(function(value){var promise=Promise.resolve(onFinally());return promise.then(function(){return value})},function(reason){var promise=Promise.resolve(onFinally());return promise.then(function(){throw reason;})})};return polyfill},"es9","es3");
$jscomp.makeAsyncIterator=function(iterable){$jscomp.initSymbolAsyncIterator();var asyncIteratorFunction=iterable[Symbol.asyncIterator];if(asyncIteratorFunction!==undefined)return asyncIteratorFunction.call(iterable);return new $jscomp.AsyncIteratorFromSyncWrapper($jscomp.makeIterator(iterable))};
$jscomp.AsyncIteratorFromSyncWrapper=function(iterator){this[Symbol.asyncIterator]=function(){return this};this[Symbol.iterator]=function(){return iterator};this.next=function(param){return Promise.resolve(iterator.next(param))};if(iterator["throw"]!==undefined)this["throw"]=function(param){return Promise.resolve(iterator["throw"](param))};if(iterator["return"]!==undefined)this["return"]=function(param){return Promise.resolve(iterator["return"](param))}};
$jscomp.AsyncGeneratorWrapper$ActionEnum={YIELD_VALUE:0,YIELD_STAR:1,AWAIT_VALUE:2};$jscomp.AsyncGeneratorWrapper$ActionRecord=function(action,value){this.action=action;this.value=value};$jscomp.AsyncGeneratorWrapper$GeneratorMethod={NEXT:"next",THROW:"throw",RETURN:"return"};$jscomp.AsyncGeneratorWrapper$ExecutionFrame_=function(method,param,resolve,reject){this.method=method;this.param=param;this.resolve=resolve;this.reject=reject};
$jscomp.AsyncGeneratorWrapper$ExecutionNode_=function(frame,next){this.frame=frame;this.next=next};$jscomp.AsyncGeneratorWrapper$ExecutionQueue_=function(){this.head_=null;this.tail_=null};$jscomp.AsyncGeneratorWrapper$ExecutionQueue_.prototype.isEmpty=function(){return this.head_===null};$jscomp.AsyncGeneratorWrapper$ExecutionQueue_.prototype.first=function(){if(this.head_)return this.head_.frame;else throw new Error("no frames in executionQueue");};
$jscomp.AsyncGeneratorWrapper$ExecutionQueue_.prototype.drop=function(){if(this.head_){this.head_=this.head_.next;if(!this.head_)this.tail_=null}};$jscomp.AsyncGeneratorWrapper$ExecutionQueue_.prototype.enqueue=function(newFrame){var node=new $jscomp.AsyncGeneratorWrapper$ExecutionNode_(newFrame,null);if(this.tail_){this.tail_.next=node;this.tail_=node}else{this.head_=node;this.tail_=node}};
$jscomp.AsyncGeneratorWrapper=function(generator){this.generator_=generator;this.delegate_=null;this.executionQueue_=new $jscomp.AsyncGeneratorWrapper$ExecutionQueue_;$jscomp.initSymbolAsyncIterator();this[Symbol.asyncIterator]=function(){return this};var self=this;this.boundHandleDelegateResult_=function(record){self.handleDelegateResult_(record)};this.boundHandleDelegateError_=function(thrownError){self.handleDelegateError_(thrownError)};this.boundRejectAndClose_=function(err){self.rejectAndClose_(err)}};
$jscomp.AsyncGeneratorWrapper.prototype.enqueueMethod_=function(method,param){var self=this;return new Promise(function(resolve,reject){var wasEmpty=self.executionQueue_.isEmpty();self.executionQueue_.enqueue(new $jscomp.AsyncGeneratorWrapper$ExecutionFrame_(method,param,resolve,reject));if(wasEmpty)self.runFrame_()})};$jscomp.AsyncGeneratorWrapper.prototype.next=function(opt_value){return this.enqueueMethod_($jscomp.AsyncGeneratorWrapper$GeneratorMethod.NEXT,opt_value)};
$jscomp.AsyncGeneratorWrapper.prototype.return=function(value){return this.enqueueMethod_($jscomp.AsyncGeneratorWrapper$GeneratorMethod.RETURN,new $jscomp.AsyncGeneratorWrapper$ActionRecord($jscomp.AsyncGeneratorWrapper$ActionEnum.YIELD_VALUE,value))};$jscomp.AsyncGeneratorWrapper.prototype.throw=function(exception){return this.enqueueMethod_($jscomp.AsyncGeneratorWrapper$GeneratorMethod.THROW,exception)};
$jscomp.AsyncGeneratorWrapper.prototype.runFrame_=function(){if(!this.executionQueue_.isEmpty())try{if(this.delegate_)this.runDelegateFrame_();else this.runGeneratorFrame_()}catch(err){this.rejectAndClose_(err)}};
$jscomp.AsyncGeneratorWrapper.prototype.runGeneratorFrame_=function(){var self=this;var frame=this.executionQueue_.first();try{var genRec=this.generator_[frame.method](frame.param);if(genRec.value instanceof $jscomp.AsyncGeneratorWrapper$ActionRecord)switch(genRec.value.action){case $jscomp.AsyncGeneratorWrapper$ActionEnum.YIELD_VALUE:Promise.resolve(genRec.value.value).then(function(resolvedValue){frame.resolve({value:resolvedValue,done:genRec.done});self.executionQueue_.drop();self.runFrame_()},
function(e){frame.reject(e);self.executionQueue_.drop();self.runFrame_()}).catch(this.boundRejectAndClose_);return;case $jscomp.AsyncGeneratorWrapper$ActionEnum.YIELD_STAR:self.delegate_=$jscomp.makeAsyncIterator(genRec.value.value);frame.method=$jscomp.AsyncGeneratorWrapper$GeneratorMethod.NEXT;frame.param=undefined;self.runFrame_();return;case $jscomp.AsyncGeneratorWrapper$ActionEnum.AWAIT_VALUE:Promise.resolve(genRec.value.value).then(function(resolvedValue){frame.method=$jscomp.AsyncGeneratorWrapper$GeneratorMethod.NEXT;
frame.param=resolvedValue;self.runFrame_()},function(thrownErr){frame.method=$jscomp.AsyncGeneratorWrapper$GeneratorMethod.THROW;frame.param=thrownErr;self.runFrame_()}).catch(this.boundRejectAndClose_);return;default:throw new Error("Unrecognized AsyncGeneratorWrapper$ActionEnum");}else{frame.resolve(genRec);self.executionQueue_.drop();self.runFrame_()}}catch(e){frame.reject(e);self.executionQueue_.drop();self.runFrame_()}};
$jscomp.AsyncGeneratorWrapper.prototype.runDelegateFrame_=function(){if(!this.delegate_)throw new Error("no delegate to perform execution");var frame=this.executionQueue_.first();if(frame.method in this.delegate_)try{this.delegate_[frame.method](frame.param).then(this.boundHandleDelegateResult_,this.boundHandleDelegateError_).catch(this.boundRejectAndClose_)}catch(err){this.handleDelegateError_(err)}else{this.delegate_=null;this.runFrame_()}};
$jscomp.AsyncGeneratorWrapper.prototype.handleDelegateResult_=function(record){var frame=this.executionQueue_.first();if(record.done===true){this.delegate_=null;frame.method=$jscomp.AsyncGeneratorWrapper$GeneratorMethod.NEXT;frame.param=record.value;this.runFrame_()}else{frame.resolve({value:record.value,done:false});this.executionQueue_.drop();this.runFrame_()}};
$jscomp.AsyncGeneratorWrapper.prototype.handleDelegateError_=function(thrownError){var frame=this.executionQueue_.first();this.delegate_=null;frame.method=$jscomp.AsyncGeneratorWrapper$GeneratorMethod.THROW;frame.param=thrownError;this.runFrame_()};
$jscomp.AsyncGeneratorWrapper.prototype.rejectAndClose_=function(err){if(!this.executionQueue_.isEmpty()){this.executionQueue_.first().reject(err);this.executionQueue_.drop()}if(this.delegate_&&"return"in this.delegate_){this.delegate_["return"](undefined);this.delegate_=null}this.generator_["return"](undefined);this.runFrame_()};$jscomp.underscoreProtoCanBeSet=function(){var x={a:true};var y={};try{y.__proto__=x;return y.a}catch(e){}return false};
$jscomp.setPrototypeOf=typeof Object.setPrototypeOf=="function"?Object.setPrototypeOf:$jscomp.underscoreProtoCanBeSet()?function(target,proto){target.__proto__=proto;if(target.__proto__!==proto)throw new TypeError(target+" is not extensible");return target}:null;$jscomp.generator={};$jscomp.generator.ensureIteratorResultIsObject_=function(result){if(result instanceof Object)return;throw new TypeError("Iterator result "+result+" is not an object");};
$jscomp.generator.Context=function(){this.isRunning_=false;this.yieldAllIterator_=null;this.yieldResult=undefined;this.nextAddress=1;this.catchAddress_=0;this.finallyAddress_=0;this.abruptCompletion_=null;this.finallyContexts_=null};$jscomp.generator.Context.prototype.start_=function(){if(this.isRunning_)throw new TypeError("Generator is already running");this.isRunning_=true};$jscomp.generator.Context.prototype.stop_=function(){this.isRunning_=false};
$jscomp.generator.Context.prototype.jumpToErrorHandler_=function(){this.nextAddress=this.catchAddress_||this.finallyAddress_};$jscomp.generator.Context.prototype.next_=function(value){this.yieldResult=value};$jscomp.generator.Context.prototype.throw_=function(e){this.abruptCompletion_={exception:e,isException:true};this.jumpToErrorHandler_()};$jscomp.generator.Context.prototype.return=function(value){this.abruptCompletion_={return:value};this.nextAddress=this.finallyAddress_};
$jscomp.generator.Context.prototype.jumpThroughFinallyBlocks=function(nextAddress){this.abruptCompletion_={jumpTo:nextAddress};this.nextAddress=this.finallyAddress_};$jscomp.generator.Context.prototype.yield=function(value,resumeAddress){this.nextAddress=resumeAddress;return{value:value}};
$jscomp.generator.Context.prototype.yieldAll=function(iterable,resumeAddress){var iterator=$jscomp.makeIterator(iterable);var result=iterator.next();$jscomp.generator.ensureIteratorResultIsObject_(result);if(result.done){this.yieldResult=result.value;this.nextAddress=resumeAddress;return}this.yieldAllIterator_=iterator;return this.yield(result.value,resumeAddress)};$jscomp.generator.Context.prototype.jumpTo=function(nextAddress){this.nextAddress=nextAddress};
$jscomp.generator.Context.prototype.jumpToEnd=function(){this.nextAddress=0};$jscomp.generator.Context.prototype.setCatchFinallyBlocks=function(catchAddress,finallyAddress){this.catchAddress_=catchAddress;if(finallyAddress!=undefined)this.finallyAddress_=finallyAddress};$jscomp.generator.Context.prototype.setFinallyBlock=function(finallyAddress){this.catchAddress_=0;this.finallyAddress_=finallyAddress||0};
$jscomp.generator.Context.prototype.leaveTryBlock=function(nextAddress,catchAddress){this.nextAddress=nextAddress;this.catchAddress_=catchAddress||0};$jscomp.generator.Context.prototype.enterCatchBlock=function(nextCatchBlockAddress){this.catchAddress_=nextCatchBlockAddress||0;var exception=this.abruptCompletion_.exception;this.abruptCompletion_=null;return exception};
$jscomp.generator.Context.prototype.enterFinallyBlock=function(nextCatchAddress,nextFinallyAddress,finallyDepth){if(!finallyDepth)this.finallyContexts_=[this.abruptCompletion_];else this.finallyContexts_[finallyDepth]=this.abruptCompletion_;this.catchAddress_=nextCatchAddress||0;this.finallyAddress_=nextFinallyAddress||0};
$jscomp.generator.Context.prototype.leaveFinallyBlock=function(nextAddress,finallyDepth){var preservedContext=this.finallyContexts_.splice(finallyDepth||0)[0];var abruptCompletion=this.abruptCompletion_=this.abruptCompletion_||preservedContext;if(abruptCompletion){if(abruptCompletion.isException)return this.jumpToErrorHandler_();if(abruptCompletion.jumpTo!=undefined&&this.finallyAddress_<abruptCompletion.jumpTo){this.nextAddress=abruptCompletion.jumpTo;this.abruptCompletion_=null}else this.nextAddress=
this.finallyAddress_}else this.nextAddress=nextAddress};$jscomp.generator.Context.prototype.forIn=function(object){return new $jscomp.generator.Context.PropertyIterator(object)};$jscomp.generator.Context.PropertyIterator=function(object){this.object_=object;this.properties_=[];for(var property in object)this.properties_.push(property);this.properties_.reverse()};
$jscomp.generator.Context.PropertyIterator.prototype.getNext=function(){while(this.properties_.length>0){var property=this.properties_.pop();if(property in this.object_)return property}return null};$jscomp.generator.Engine_=function(program){this.context_=new $jscomp.generator.Context;this.program_=program};
$jscomp.generator.Engine_.prototype.next_=function(value){this.context_.start_();if(this.context_.yieldAllIterator_)return this.yieldAllStep_(this.context_.yieldAllIterator_.next,value,this.context_.next_);this.context_.next_(value);return this.nextStep_()};
$jscomp.generator.Engine_.prototype.return_=function(value){this.context_.start_();var yieldAllIterator=this.context_.yieldAllIterator_;if(yieldAllIterator){var returnFunction="return"in yieldAllIterator?yieldAllIterator["return"]:function(v){return{value:v,done:true}};return this.yieldAllStep_(returnFunction,value,this.context_.return)}this.context_.return(value);return this.nextStep_()};
$jscomp.generator.Engine_.prototype.throw_=function(exception){this.context_.start_();if(this.context_.yieldAllIterator_)return this.yieldAllStep_(this.context_.yieldAllIterator_["throw"],exception,this.context_.next_);this.context_.throw_(exception);return this.nextStep_()};
$jscomp.generator.Engine_.prototype.yieldAllStep_=function(action,value,nextAction){try{var result=action.call(this.context_.yieldAllIterator_,value);$jscomp.generator.ensureIteratorResultIsObject_(result);if(!result.done){this.context_.stop_();return result}var resultValue=result.value}catch(e){this.context_.yieldAllIterator_=null;this.context_.throw_(e);return this.nextStep_()}this.context_.yieldAllIterator_=null;nextAction.call(this.context_,resultValue);return this.nextStep_()};
$jscomp.generator.Engine_.prototype.nextStep_=function(){while(this.context_.nextAddress)try{var yieldValue=this.program_(this.context_);if(yieldValue){this.context_.stop_();return{value:yieldValue.value,done:false}}}catch(e){this.context_.yieldResult=undefined;this.context_.throw_(e)}this.context_.stop_();if(this.context_.abruptCompletion_){var abruptCompletion=this.context_.abruptCompletion_;this.context_.abruptCompletion_=null;if(abruptCompletion.isException)throw abruptCompletion.exception;return{value:abruptCompletion.return,
done:true}}return{value:undefined,done:true}};$jscomp.generator.Generator_=function(engine){this.next=function(opt_value){return engine.next_(opt_value)};this.throw=function(exception){return engine.throw_(exception)};this.return=function(value){return engine.return_(value)};$jscomp.initSymbolIterator();this[Symbol.iterator]=function(){return this}};
$jscomp.generator.createGenerator=function(generator,program){var result=new $jscomp.generator.Generator_(new $jscomp.generator.Engine_(program));if($jscomp.setPrototypeOf)$jscomp.setPrototypeOf(result,generator.prototype);return result};
$jscomp.asyncExecutePromiseGenerator=function(generator){function passValueToGenerator(value){return generator.next(value)}function passErrorToGenerator(error){return generator.throw(error)}return new Promise(function(resolve,reject){function handleGeneratorRecord(genRec){if(genRec.done)resolve(genRec.value);else Promise.resolve(genRec.value).then(passValueToGenerator,passErrorToGenerator).then(handleGeneratorRecord,reject)}handleGeneratorRecord(generator.next())})};
$jscomp.asyncExecutePromiseGeneratorFunction=function(generatorFunction){return $jscomp.asyncExecutePromiseGenerator(generatorFunction())};$jscomp.asyncExecutePromiseGeneratorProgram=function(program){return $jscomp.asyncExecutePromiseGenerator(new $jscomp.generator.Generator_(new $jscomp.generator.Engine_(program)))};
$jscomp.checkEs6ConformanceViaProxy=function(){try{var proxied={};var proxy=Object.create(new $jscomp.global["Proxy"](proxied,{"get":function(target,key,receiver){return target==proxied&&key=="q"&&receiver==proxy}}));return proxy["q"]===true}catch(err){return false}};$jscomp.USE_PROXY_FOR_ES6_CONFORMANCE_CHECKS=false;$jscomp.ES6_CONFORMANCE=$jscomp.USE_PROXY_FOR_ES6_CONFORMANCE_CHECKS&&$jscomp.checkEs6ConformanceViaProxy();
$jscomp.owns=function(obj,prop){return Object.prototype.hasOwnProperty.call(obj,prop)};
$jscomp.polyfill("WeakMap",function(NativeWeakMap){function isConformant(){if(!NativeWeakMap||!Object.seal)return false;try{var x=Object.seal({});var y=Object.seal({});var map=new NativeWeakMap([[x,2],[y,3]]);if(map.get(x)!=2||map.get(y)!=3)return false;map.delete(x);map.set(y,4);return!map.has(x)&&map.get(y)==4}catch(err){return false}}if($jscomp.USE_PROXY_FOR_ES6_CONFORMANCE_CHECKS){if(NativeWeakMap&&$jscomp.ES6_CONFORMANCE)return NativeWeakMap}else if(isConformant())return NativeWeakMap;var prop=
"$jscomp_hidden_"+Math.random();function WeakMapMembership(){}function isValidKey(key){var type=typeof key;return type==="object"&&key!==null||type==="function"}function insert(target){if(!$jscomp.owns(target,prop)){var obj=new WeakMapMembership;$jscomp.defineProperty(target,prop,{value:obj})}}function patch(name){var prev=Object[name];if(prev)Object[name]=function(target){if(target instanceof WeakMapMembership)return target;else{insert(target);return prev(target)}}}patch("freeze");patch("preventExtensions");
patch("seal");var index=0;var PolyfillWeakMap=function(opt_iterable){this.id_=(index+=Math.random()+1).toString();if(opt_iterable){var iter=$jscomp.makeIterator(opt_iterable);var entry;while(!(entry=iter.next()).done){var item=entry.value;this.set(item[0],item[1])}}};PolyfillWeakMap.prototype.set=function(key,value){if(!isValidKey(key))throw new Error("Invalid WeakMap key");insert(key);if(!$jscomp.owns(key,prop))throw new Error("WeakMap key fail: "+key);key[prop][this.id_]=value;return this};PolyfillWeakMap.prototype.get=
function(key){return isValidKey(key)&&$jscomp.owns(key,prop)?key[prop][this.id_]:undefined};PolyfillWeakMap.prototype.has=function(key){return isValidKey(key)&&$jscomp.owns(key,prop)&&$jscomp.owns(key[prop],this.id_)};PolyfillWeakMap.prototype.delete=function(key){if(!isValidKey(key)||!$jscomp.owns(key,prop)||!$jscomp.owns(key[prop],this.id_))return false;return delete key[prop][this.id_]};return PolyfillWeakMap},"es6","es3");
$jscomp.MapEntry=function(){this.previous;this.next;this.head;this.key;this.value};
$jscomp.polyfill("Map",function(NativeMap){function isConformant(){if($jscomp.ASSUME_NO_NATIVE_MAP||!NativeMap||typeof NativeMap!="function"||!NativeMap.prototype.entries||typeof Object.seal!="function")return false;try{NativeMap=NativeMap;var key=Object.seal({x:4});var map=new NativeMap($jscomp.makeIterator([[key,"s"]]));if(map.get(key)!="s"||map.size!=1||map.get({x:4})||map.set({x:4},"t")!=map||map.size!=2)return false;var iter=map.entries();var item=iter.next();if(item.done||item.value[0]!=key||
item.value[1]!="s")return false;item=iter.next();if(item.done||item.value[0].x!=4||item.value[1]!="t"||!iter.next().done)return false;return true}catch(err){return false}}if($jscomp.USE_PROXY_FOR_ES6_CONFORMANCE_CHECKS){if(NativeMap&&$jscomp.ES6_CONFORMANCE)return NativeMap}else if(isConformant())return NativeMap;$jscomp.initSymbolIterator();var idMap=new WeakMap;var PolyfillMap=function(opt_iterable){this.data_={};this.head_=createHead();this.size=0;if(opt_iterable){var iter=$jscomp.makeIterator(opt_iterable);
var entry;while(!(entry=iter.next()).done){var item=entry.value;this.set(item[0],item[1])}}};PolyfillMap.prototype.set=function(key,value){key=key===0?0:key;var r=maybeGetEntry(this,key);if(!r.list)r.list=this.data_[r.id]=[];if(!r.entry){r.entry={next:this.head_,previous:this.head_.previous,head:this.head_,key:key,value:value};r.list.push(r.entry);this.head_.previous.next=r.entry;this.head_.previous=r.entry;this.size++}else r.entry.value=value;return this};PolyfillMap.prototype.delete=function(key){var r=
maybeGetEntry(this,key);if(r.entry&&r.list){r.list.splice(r.index,1);if(!r.list.length)delete this.data_[r.id];r.entry.previous.next=r.entry.next;r.entry.next.previous=r.entry.previous;r.entry.head=null;this.size--;return true}return false};PolyfillMap.prototype.clear=function(){this.data_={};this.head_=this.head_.previous=createHead();this.size=0};PolyfillMap.prototype.has=function(key){return!!maybeGetEntry(this,key).entry};PolyfillMap.prototype.get=function(key){var entry=maybeGetEntry(this,key).entry;
return entry&&entry.value};PolyfillMap.prototype.entries=function(){return makeIterator(this,function(entry){return[entry.key,entry.value]})};PolyfillMap.prototype.keys=function(){return makeIterator(this,function(entry){return entry.key})};PolyfillMap.prototype.values=function(){return makeIterator(this,function(entry){return entry.value})};PolyfillMap.prototype.forEach=function(callback,opt_thisArg){var iter=this.entries();var item;while(!(item=iter.next()).done){var entry=item.value;callback.call(opt_thisArg,
entry[1],entry[0],this)}};PolyfillMap.prototype[Symbol.iterator]=PolyfillMap.prototype.entries;var maybeGetEntry=function(map,key){var id=getId(key);var list=map.data_[id];if(list&&$jscomp.owns(map.data_,id))for(var index=0;index<list.length;index++){var entry=list[index];if(key!==key&&entry.key!==entry.key||key===entry.key)return{id:id,list:list,index:index,entry:entry}}return{id:id,list:list,index:-1,entry:undefined}};var makeIterator=function(map,func){var entry=map.head_;return $jscomp.iteratorPrototype(function(){if(entry){while(entry.head!=
map.head_)entry=entry.previous;while(entry.next!=entry.head){entry=entry.next;return{done:false,value:func(entry)}}entry=null}return{done:true,value:void 0}})};var createHead=function(){var head={};head.previous=head.next=head.head=head;return head};var mapIndex=0;var getId=function(obj){var type=obj&&typeof obj;if(type=="object"||type=="function"){obj=obj;if(!idMap.has(obj)){var id=""+ ++mapIndex;idMap.set(obj,id);return id}return idMap.get(obj)}return"p_"+obj};return PolyfillMap},"es6","es3");
$jscomp.polyfill("Math.acosh",function(orig){if(orig)return orig;var polyfill=function(x){x=Number(x);return Math.log(x+Math.sqrt(x*x-1))};return polyfill},"es6","es3");$jscomp.polyfill("Math.asinh",function(orig){if(orig)return orig;var polyfill=function(x){x=Number(x);if(x===0)return x;var y=Math.log(Math.abs(x)+Math.sqrt(x*x+1));return x<0?-y:y};return polyfill},"es6","es3");
$jscomp.polyfill("Math.log1p",function(orig){if(orig)return orig;var polyfill=function(x){x=Number(x);if(x<.25&&x>-.25){var y=x;var d=1;var z=x;var zPrev=0;var s=1;while(zPrev!=z){y*=x;s*=-1;z=(zPrev=z)+s*y/++d}return z}return Math.log(1+x)};return polyfill},"es6","es3");$jscomp.polyfill("Math.atanh",function(orig){if(orig)return orig;var log1p=Math.log1p;var polyfill=function(x){x=Number(x);return(log1p(x)-log1p(-x))/2};return polyfill},"es6","es3");
$jscomp.polyfill("Math.cbrt",function(orig){if(orig)return orig;var polyfill=function(x){if(x===0)return x;x=Number(x);var y=Math.pow(Math.abs(x),1/3);return x<0?-y:y};return polyfill},"es6","es3");
$jscomp.polyfill("Math.clz32",function(orig){if(orig)return orig;var polyfill=function(x){x=Number(x)>>>0;if(x===0)return 32;var result=0;if((x&4294901760)===0){x<<=16;result+=16}if((x&4278190080)===0){x<<=8;result+=8}if((x&4026531840)===0){x<<=4;result+=4}if((x&3221225472)===0){x<<=2;result+=2}if((x&2147483648)===0)result++;return result};return polyfill},"es6","es3");
$jscomp.polyfill("Math.cosh",function(orig){if(orig)return orig;var exp=Math.exp;var polyfill=function(x){x=Number(x);return(exp(x)+exp(-x))/2};return polyfill},"es6","es3");$jscomp.polyfill("Math.expm1",function(orig){if(orig)return orig;var polyfill=function(x){x=Number(x);if(x<.25&&x>-.25){var y=x;var d=1;var z=x;var zPrev=0;while(zPrev!=z){y*=x/++d;z=(zPrev=z)+y}return z}return Math.exp(x)-1};return polyfill},"es6","es3");
$jscomp.polyfill("Math.fround",function(orig){if(orig)return orig;if($jscomp.SIMPLE_FROUND_POLYFILL||typeof Float32Array!=="function")return function(arg){return arg};var arr=new Float32Array(1);var polyfill=function(arg){arr[0]=arg;return arr[0]};return polyfill},"es6","es3");
$jscomp.polyfill("Math.hypot",function(orig){if(orig)return orig;var polyfill=function(var_args){if(arguments.length<2)return arguments.length?Math.abs(arguments[0]):0;var i,z,sum,max;for(max=0,i=0;i<arguments.length;i++)max=Math.max(max,Math.abs(arguments[i]));if(max>1E100||max<1E-100){if(!max)return max;sum=0;for(i=0;i<arguments.length;i++){z=Number(arguments[i])/max;sum+=z*z}return Math.sqrt(sum)*max}else{sum=0;for(i=0;i<arguments.length;i++){z=Number(arguments[i]);sum+=z*z}return Math.sqrt(sum)}};
return polyfill},"es6","es3");$jscomp.polyfill("Math.imul",function(orig){if(orig)return orig;var polyfill=function(a,b){a=Number(a);b=Number(b);var ah=a>>>16&65535;var al=a&65535;var bh=b>>>16&65535;var bl=b&65535;var lh=ah*bl+al*bh<<16>>>0;return al*bl+lh|0};return polyfill},"es6","es3");$jscomp.polyfill("Math.log10",function(orig){if(orig)return orig;var polyfill=function(x){return Math.log(x)/Math.LN10};return polyfill},"es6","es3");
$jscomp.polyfill("Math.log2",function(orig){if(orig)return orig;var polyfill=function(x){return Math.log(x)/Math.LN2};return polyfill},"es6","es3");$jscomp.polyfill("Math.sign",function(orig){if(orig)return orig;var polyfill=function(x){x=Number(x);return x===0||isNaN(x)?x:x>0?1:-1};return polyfill},"es6","es3");$jscomp.polyfill("Math.sinh",function(orig){if(orig)return orig;var exp=Math.exp;var polyfill=function(x){x=Number(x);if(x===0)return x;return(exp(x)-exp(-x))/2};return polyfill},"es6","es3");
$jscomp.polyfill("Math.tanh",function(orig){if(orig)return orig;var polyfill=function(x){x=Number(x);if(x===0)return x;var y=Math.exp(-2*Math.abs(x));var z=(1-y)/(1+y);return x<0?-z:z};return polyfill},"es6","es3");$jscomp.polyfill("Math.trunc",function(orig){if(orig)return orig;var polyfill=function(x){x=Number(x);if(isNaN(x)||x===Infinity||x===-Infinity||x===0)return x;var y=Math.floor(Math.abs(x));return x<0?-y:y};return polyfill},"es6","es3");
$jscomp.polyfill("Number.EPSILON",function(orig){return Math.pow(2,-52)},"es6","es3");$jscomp.polyfill("Number.MAX_SAFE_INTEGER",function(){return 9007199254740991},"es6","es3");$jscomp.polyfill("Number.MIN_SAFE_INTEGER",function(){return-9007199254740991},"es6","es3");$jscomp.polyfill("Number.isFinite",function(orig){if(orig)return orig;var polyfill=function(x){if(typeof x!=="number")return false;return!isNaN(x)&&x!==Infinity&&x!==-Infinity};return polyfill},"es6","es3");
$jscomp.polyfill("Number.isInteger",function(orig){if(orig)return orig;var polyfill=function(x){if(!Number.isFinite(x))return false;return x===Math.floor(x)};return polyfill},"es6","es3");$jscomp.polyfill("Number.isNaN",function(orig){if(orig)return orig;var polyfill=function(x){return typeof x==="number"&&isNaN(x)};return polyfill},"es6","es3");
$jscomp.polyfill("Number.isSafeInteger",function(orig){if(orig)return orig;var polyfill=function(x){return Number.isInteger(x)&&Math.abs(x)<=Number.MAX_SAFE_INTEGER};return polyfill},"es6","es3");$jscomp.polyfill("Number.parseFloat",function(orig){return orig||parseFloat},"es6","es3");$jscomp.polyfill("Number.parseInt",function(orig){return orig||parseInt},"es6","es3");
$jscomp.assign=typeof Object.assign=="function"?Object.assign:function(target,var_args){for(var i=1;i<arguments.length;i++){var source=arguments[i];if(!source)continue;for(var key in source)if($jscomp.owns(source,key))target[key]=source[key]}return target};$jscomp.polyfill("Object.assign",function(orig){return orig||$jscomp.assign},"es6","es3");
$jscomp.polyfill("Object.entries",function(orig){if(orig)return orig;var entries=function(obj){var result=[];for(var key in obj)if($jscomp.owns(obj,key))result.push([key,obj[key]]);return result};return entries},"es8","es3");
$jscomp.polyfill("Object.fromEntries",function(orig){if(orig)return orig;function fromEntries(iter){var obj={};$jscomp.initSymbolIterator();if(!(Symbol.iterator in iter))throw new TypeError(""+iter+" is not iterable");var iteratorFn=iter[Symbol.iterator];var iterator=iteratorFn.call(iter);for(var result=iterator.next();!result.done;result=iterator.next()){var pair=result.value;if(Object(pair)!==pair)throw new TypeError("iterable for fromEntries should yield objects");var key=pair[0];var val=pair[1];
obj[key]=val}return obj}return fromEntries},"es_2019","es3");$jscomp.polyfill("Object.getOwnPropertySymbols",function(orig){if(orig)return orig;return function(){return[]}},"es6","es5");
$jscomp.polyfill("Reflect.ownKeys",function(orig){if(orig)return orig;var symbolPrefix="jscomp_symbol_";function isSymbol(key){return key.substring(0,symbolPrefix.length)==symbolPrefix}var polyfill=function(target){var keys=[];var names=Object.getOwnPropertyNames(target);var symbols=Object.getOwnPropertySymbols(target);for(var i=0;i<names.length;i++)(isSymbol(names[i])?symbols:keys).push(names[i]);return keys.concat(symbols)};return polyfill},"es6","es5");
$jscomp.polyfill("Object.getOwnPropertyDescriptors",function(orig){if(orig)return orig;var getOwnPropertyDescriptors=function(obj){var result={};var keys=Reflect.ownKeys(obj);for(var i=0;i<keys.length;i++)result[keys[i]]=Object.getOwnPropertyDescriptor(obj,keys[i]);return result};return getOwnPropertyDescriptors},"es8","es5");$jscomp.polyfill("Object.setPrototypeOf",function(orig){return orig||$jscomp.setPrototypeOf},"es6","es5");
$jscomp.polyfill("Object.values",function(orig){if(orig)return orig;var values=function(obj){var result=[];for(var key in obj)if($jscomp.owns(obj,key))result.push(obj[key]);return result};return values},"es8","es3");$jscomp.polyfill("Reflect.apply",function(orig){if(orig)return orig;var apply=Function.prototype.apply;var polyfill=function(target,thisArg,argList){return apply.call(target,thisArg,argList)};return polyfill},"es6","es3");
$jscomp.objectCreate=$jscomp.ASSUME_ES5||typeof Object.create=="function"?Object.create:function(prototype){var ctor=function(){};ctor.prototype=prototype;return new ctor};
$jscomp.construct=function(){function reflectConstructWorks(){function Base(){}function Derived(){}new Base;Reflect.construct(Base,[],Derived);return new Base instanceof Base}if(typeof Reflect!="undefined"&&Reflect.construct){if(reflectConstructWorks())return Reflect.construct;var brokenConstruct=Reflect.construct;var patchedConstruct=function(target,argList,opt_newTarget){var out=brokenConstruct(target,argList);if(opt_newTarget)Reflect.setPrototypeOf(out,opt_newTarget.prototype);return out};return patchedConstruct}function construct(target,
argList,opt_newTarget){if(opt_newTarget===undefined)opt_newTarget=target;var proto=opt_newTarget.prototype||Object.prototype;var obj=$jscomp.objectCreate(proto);var apply=Function.prototype.apply;var out=apply.call(target,obj,argList);return out||obj}return construct}();$jscomp.polyfill("Reflect.construct",function(orig){return $jscomp.construct},"es6","es3");
$jscomp.polyfill("Reflect.defineProperty",function(orig){if(orig)return orig;var polyfill=function(target,propertyKey,attributes){try{Object.defineProperty(target,propertyKey,attributes);var desc=Object.getOwnPropertyDescriptor(target,propertyKey);if(!desc)return false;return desc.configurable===(attributes.configurable||false)&&desc.enumerable===(attributes.enumerable||false)&&("value"in desc?desc.value===attributes.value&&desc.writable===(attributes.writable||false):desc.get===attributes.get&&desc.set===
attributes.set)}catch(err){return false}};return polyfill},"es6","es5");$jscomp.polyfill("Reflect.deleteProperty",function(orig){if(orig)return orig;var polyfill=function(target,propertyKey){if(!$jscomp.owns(target,propertyKey))return true;try{return delete target[propertyKey]}catch(err){return false}};return polyfill},"es6","es3");$jscomp.polyfill("Reflect.getOwnPropertyDescriptor",function(orig){return orig||Object.getOwnPropertyDescriptor},"es6","es5");
$jscomp.polyfill("Reflect.getPrototypeOf",function(orig){return orig||Object.getPrototypeOf},"es6","es5");$jscomp.findDescriptor=function(target,propertyKey){var obj=target;while(obj){var property=Reflect.getOwnPropertyDescriptor(obj,propertyKey);if(property)return property;obj=Reflect.getPrototypeOf(obj)}return undefined};
$jscomp.polyfill("Reflect.get",function(orig){if(orig)return orig;var polyfill=function(target,propertyKey,opt_receiver){if(arguments.length<=2)return target[propertyKey];var property=$jscomp.findDescriptor(target,propertyKey);if(property)return property.get?property.get.call(opt_receiver):property.value;return undefined};return polyfill},"es6","es5");
$jscomp.polyfill("Reflect.has",function(orig){if(orig)return orig;var polyfill=function(target,propertyKey){return propertyKey in target};return polyfill},"es6","es3");$jscomp.polyfill("Reflect.isExtensible",function(orig){if(orig)return orig;if($jscomp.ASSUME_ES5||typeof Object.isExtensible=="function")return Object.isExtensible;return function(){return true}},"es6","es3");
$jscomp.polyfill("Reflect.preventExtensions",function(orig){if(orig)return orig;if(!($jscomp.ASSUME_ES5||typeof Object.preventExtensions=="function"))return function(){return false};var polyfill=function(target){Object.preventExtensions(target);return!Object.isExtensible(target)};return polyfill},"es6","es3");
$jscomp.polyfill("Reflect.set",function(orig){if(orig)return orig;var polyfill=function(target,propertyKey,value,opt_receiver){var property=$jscomp.findDescriptor(target,propertyKey);if(!property){if(Reflect.isExtensible(target)){target[propertyKey]=value;return true}return false}if(property.set){property.set.call(arguments.length>3?opt_receiver:target,value);return true}else if(property.writable&&!Object.isFrozen(target)){target[propertyKey]=value;return true}return false};return polyfill},"es6",
"es5");$jscomp.polyfill("Reflect.setPrototypeOf",function(orig){if(orig)return orig;else if($jscomp.setPrototypeOf){var setPrototypeOf=$jscomp.setPrototypeOf;var polyfill=function(target,proto){try{setPrototypeOf(target,proto);return true}catch(e){return false}};return polyfill}else return null},"es6","es5");
$jscomp.polyfill("Set",function(NativeSet){function isConformant(){if($jscomp.ASSUME_NO_NATIVE_SET||!NativeSet||typeof NativeSet!="function"||!NativeSet.prototype.entries||typeof Object.seal!="function")return false;try{NativeSet=NativeSet;var value=Object.seal({x:4});var set=new NativeSet($jscomp.makeIterator([value]));if(!set.has(value)||set.size!=1||set.add(value)!=set||set.size!=1||set.add({x:4})!=set||set.size!=2)return false;var iter=set.entries();var item=iter.next();if(item.done||item.value[0]!=
value||item.value[1]!=value)return false;item=iter.next();if(item.done||item.value[0]==value||item.value[0].x!=4||item.value[1]!=item.value[0])return false;return iter.next().done}catch(err){return false}}if($jscomp.USE_PROXY_FOR_ES6_CONFORMANCE_CHECKS){if(NativeSet&&$jscomp.ES6_CONFORMANCE)return NativeSet}else if(isConformant())return NativeSet;$jscomp.initSymbolIterator();var PolyfillSet=function(opt_iterable){this.map_=new Map;if(opt_iterable){var iter=$jscomp.makeIterator(opt_iterable);var entry;
while(!(entry=iter.next()).done){var item=entry.value;this.add(item)}}this.size=this.map_.size};PolyfillSet.prototype.add=function(value){value=value===0?0:value;this.map_.set(value,value);this.size=this.map_.size;return this};PolyfillSet.prototype.delete=function(value){var result=this.map_.delete(value);this.size=this.map_.size;return result};PolyfillSet.prototype.clear=function(){this.map_.clear();this.size=0};PolyfillSet.prototype.has=function(value){return this.map_.has(value)};PolyfillSet.prototype.entries=
function(){return this.map_.entries()};PolyfillSet.prototype.values=function(){return this.map_.values()};PolyfillSet.prototype.keys=PolyfillSet.prototype.values;PolyfillSet.prototype[Symbol.iterator]=PolyfillSet.prototype.values;PolyfillSet.prototype.forEach=function(callback,opt_thisArg){var set=this;this.map_.forEach(function(value){return callback.call(opt_thisArg,value,value,set)})};return PolyfillSet},"es6","es3");
$jscomp.checkStringArgs=function(thisArg,arg,func){if(thisArg==null)throw new TypeError("The 'this' value for String.prototype."+func+" must not be null or undefined");if(arg instanceof RegExp)throw new TypeError("First argument to String.prototype."+func+" must not be a regular expression");return thisArg+""};
$jscomp.polyfill("String.prototype.codePointAt",function(orig){if(orig)return orig;var polyfill=function(position){var string=$jscomp.checkStringArgs(this,null,"codePointAt");var size=string.length;position=Number(position)||0;if(!(position>=0&&position<size))return void 0;position=position|0;var first=string.charCodeAt(position);if(first<55296||first>56319||position+1===size)return first;var second=string.charCodeAt(position+1);if(second<56320||second>57343)return first;return(first-55296)*1024+
second+9216};return polyfill},"es6","es3");$jscomp.polyfill("String.prototype.endsWith",function(orig){if(orig)return orig;var polyfill=function(searchString,opt_position){var string=$jscomp.checkStringArgs(this,searchString,"endsWith");searchString=searchString+"";if(opt_position===void 0)opt_position=string.length;var i=Math.max(0,Math.min(opt_position|0,string.length));var j=searchString.length;while(j>0&&i>0)if(string[--i]!=searchString[--j])return false;return j<=0};return polyfill},"es6","es3");
$jscomp.polyfill("String.fromCodePoint",function(orig){if(orig)return orig;var polyfill=function(var_args){var result="";for(var i=0;i<arguments.length;i++){var code=Number(arguments[i]);if(code<0||code>1114111||code!==Math.floor(code))throw new RangeError("invalid_code_point "+code);if(code<=65535)result+=String.fromCharCode(code);else{code-=65536;result+=String.fromCharCode(code>>>10&1023|55296);result+=String.fromCharCode(code&1023|56320)}}return result};return polyfill},"es6","es3");
$jscomp.polyfill("String.prototype.includes",function(orig){if(orig)return orig;var polyfill=function(searchString,opt_position){var string=$jscomp.checkStringArgs(this,searchString,"includes");return string.indexOf(searchString,opt_position||0)!==-1};return polyfill},"es6","es3");
$jscomp.polyfill("String.prototype.repeat",function(orig){if(orig)return orig;var polyfill=function(copies){var string=$jscomp.checkStringArgs(this,null,"repeat");if(copies<0||copies>1342177279)throw new RangeError("Invalid count value");copies=copies|0;var result="";while(copies){if(copies&1)result+=string;if(copies>>>=1)string+=string}return result};return polyfill},"es6","es3");
$jscomp.stringPadding=function(padString,padLength){var padding=padString!==undefined?String(padString):" ";if(!(padLength>0)||!padding)return"";var repeats=Math.ceil(padLength/padding.length);return padding.repeat(repeats).substring(0,padLength)};
$jscomp.polyfill("String.prototype.padEnd",function(orig){if(orig)return orig;var padEnd=function(targetLength,opt_padString){var string=$jscomp.checkStringArgs(this,null,"padStart");var padLength=targetLength-string.length;return string+$jscomp.stringPadding(opt_padString,padLength)};return padEnd},"es8","es3");
$jscomp.polyfill("String.prototype.padStart",function(orig){if(orig)return orig;var padStart=function(targetLength,opt_padString){var string=$jscomp.checkStringArgs(this,null,"padStart");var padLength=targetLength-string.length;return $jscomp.stringPadding(opt_padString,padLength)+string};return padStart},"es8","es3");
$jscomp.polyfill("String.prototype.startsWith",function(orig){if(orig)return orig;var polyfill=function(searchString,opt_position){var string=$jscomp.checkStringArgs(this,searchString,"startsWith");searchString=searchString+"";var strLen=string.length;var searchLen=searchString.length;var i=Math.max(0,Math.min(opt_position|0,string.length));var j=0;while(j<searchLen&&i<strLen)if(string[i++]!=searchString[j++])return false;return j>=searchLen};return polyfill},"es6","es3");
$jscomp.polyfill("String.prototype.trimRight",function(orig){function polyfill(){return this.replace(/[\s\xa0]+$/,"")}return orig||polyfill},"es_2019","es3");$jscomp.polyfill("String.prototype.trimEnd",function(orig){return orig||String.prototype.trimRight},"es_2019","es3");$jscomp.polyfill("String.prototype.trimLeft",function(orig){function polyfill(){return this.replace(/^[\s\xa0]+/,"")}return orig||polyfill},"es_2019","es3");
$jscomp.polyfill("String.prototype.trimStart",function(orig){return orig||String.prototype.trimLeft},"es_2019","es3");$jscomp.arrayFromIterator=function(iterator){var i;var arr=[];while(!(i=iterator.next()).done)arr.push(i.value);return arr};$jscomp.arrayFromIterable=function(iterable){if(iterable instanceof Array)return iterable;else return $jscomp.arrayFromIterator($jscomp.makeIterator(iterable))};
$jscomp.inherits=function(childCtor,parentCtor){childCtor.prototype=$jscomp.objectCreate(parentCtor.prototype);childCtor.prototype.constructor=childCtor;if($jscomp.setPrototypeOf){var setPrototypeOf=$jscomp.setPrototypeOf;setPrototypeOf(childCtor,parentCtor)}else for(var p in parentCtor){if(p=="prototype")continue;if(Object.defineProperties){var descriptor=Object.getOwnPropertyDescriptor(parentCtor,p);if(descriptor)Object.defineProperty(childCtor,p,descriptor)}else childCtor[p]=parentCtor[p]}childCtor.superClass_=
parentCtor.prototype};
$jscomp.polyfill("WeakSet",function(NativeWeakSet){function isConformant(){if(!NativeWeakSet||!Object.seal)return false;try{var x=Object.seal({});var y=Object.seal({});var set=new NativeWeakSet([x]);if(!set.has(x)||set.has(y))return false;set.delete(x);set.add(y);return!set.has(x)&&set.has(y)}catch(err){return false}}if($jscomp.USE_PROXY_FOR_ES6_CONFORMANCE_CHECKS){if(NativeWeakSet&&$jscomp.ES6_CONFORMANCE)return NativeWeakSet}else if(isConformant())return NativeWeakSet;var PolyfillWeakSet=function(opt_iterable){this.map_=
new WeakMap;if(opt_iterable){var iter=$jscomp.makeIterator(opt_iterable);var entry;while(!(entry=iter.next()).done){var item=entry.value;this.add(item)}}};PolyfillWeakSet.prototype.add=function(elem){this.map_.set(elem,true);return this};PolyfillWeakSet.prototype.has=function(elem){return this.map_.has(elem)};PolyfillWeakSet.prototype.delete=function(elem){return this.map_.delete(elem)};return PolyfillWeakSet},"es6","es3");
goog.loadModule(function(exports){"use strict";goog.module("grrUi.templates.templates.templatesModule");goog.module.declareLegacyNamespace();exports=angular.module("grrUi.templates",[]);angular.module("grrUi.templates").run(["$templateCache",function($templateCache){$templateCache.put("/acl/approval-info.html",'<h2>Grant access to a {$ controller.approvalTypeTitle $}</h2>\n\n<p>\n  The user <strong>{$ username $}</strong> has requested you to grant them\n  access based on:\n</p>\n\n<blockquote>\n  {$ controller.approvalObject.reason $}\n</blockquote>\n\x3c!--\nThere is a Chrome bug that selects too much text when using triple\nclick, see\nhttps://groups.google.com/a/chromium.org/forum/#!topic/chromium-bugs/P1N9-q5875Y\n\nThe only workaround here is to add a <br>, really nothing else we tried\n(p, div) works. We don\'t want to have any visual difference\neither so it\'s in a div with 0 height.\n--\x3e\n<div style="height: 0"><br></div>\n\n<button class="btn"\n        name="grant-approval"\n        ng-class="{\'btn-success\': !controller.approvalObject.isValid,\n                   \'btn-warning\': controller.approvalObject.isValid}"\n        ng-click="controller.onClick()"\n        ng-disabled="controller.requestSent">\n  <i ng-if="controller.requestSent && !controller.statusMessage"\n     class="fa fa-spinner fa-spin fa-fw"></i>\n  Approve\n</button>\n\n<span class="status-message"\n      ng-if="controller.requestSent && controller.statusMessage">\n  <em>{$ controller.statusMessage $}</em>\n</span>\n');
$templateCache.put("/acl/client-approval-view.html",'<grr-approval-info approval-type="\'client\'"\n                   username="controller.username"\n                   object-id="controller.clientId"\n                   approval-id="controller.approvalId">\n</grr-approval-info>\n\n<hr>\n\n<grr-host-info client-id="controller.clientId"\n               read-only="true">\n</grr-host-info>\n');$templateCache.put("/acl/cron-job-approval-view.html",'<grr-approval-info approval-type="\'cron-job\'"\n                   username="controller.username"\n                   object-id="controller.cronJobId"\n                   approval-id="controller.approvalId">\n</grr-approval-info>\n\n<hr>\n\n<grr-cron-job-overview ng-if="controller.cronJobId"\n                       cron-job-id="controller.cronJobId" />\n');
$templateCache.put("/acl/hunt-approval-view.html",'<div class="container-fluid">\n\n  <div class="row">\n    <div class="col-md-12 vertically-padded">\n      <div class="panel panel-default">\n        <div class="panel-body">\n          \x3c!-- NOTE: approval-object is an out-binding.\n               It is set by grr-approval-info when the approval object is fetched. --\x3e\n          <grr-approval-info approval-type="\'hunt\'"\n                             username="controller.username"\n                             object-id="controller.huntId"\n                             approval-id="controller.approvalId"\n\n                             approval-object="controller.approvalObject">\n          </grr-approval-info>\n\n          <span class="text-danger" ng-if="controller.approvalObject &&\n                                           !controller.approvalObject.value.copied_from_hunt &&\n                                           !controller.approvalObject.value.copied_from_flow">\n            This hunt is new. It wasn\'t copied from another hunt and wasn\'t created from a flow. <strong>Make sure it is safe to run!</strong>\n          </span>\n        </div>\n      </div>\n    </div>\n  </div>\n\n\n  <div ng-if="controller.approvalObject.value.copied_from_hunt">\n    <div class="row">\n      <div class="col-md-12">\n        <div class="panel panel-default">\n          <div class="panel-body">\n            <h3>This hunt was copied from <grr-semantic-value value="controller.approvalObject.value.copied_from_hunt.value.hunt_id"></grr-semantic-value></h3>\n\n            <grr-hunt-from-hunt-copy-review source-hunt="controller.approvalObject.value.copied_from_hunt"\n                                            new-hunt="controller.approvalObject.value.subject">\n            </grr-hunt-from-hunt-copy-review>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n  <div ng-if="controller.approvalObject.value.copied_from_flow">\n    <div class="row">\n      <div class="col-md-12">\n        <div class="panel panel-default">\n          <div class="panel-body">\n            \x3c!-- grr-client-context is needed to render the flow ID link correctly. --\x3e\n            <grr-client-context client-id="controller.approvalObject.value.copied_from_flow.value.client_id.value">\n              <h3>This hunt was created from a flow <grr-semantic-value value="controller.approvalObject.value.copied_from_flow.value.flow_id"></grr-semantic-value></h3>\n\n              <grr-hunt-from-flow-copy-review source-flow="controller.approvalObject.value.copied_from_flow"\n                                              new-hunt="controller.approvalObject.value.subject">\n              </grr-hunt-from-flow-copy-review>\n            </grr-client-context>\n          </div>\n        </div>\n      </div>\n    </div>\n  </div>\n\n\n  <div class="row" ng-show="controller.approvalObject">\n    <div class="col-md-12">\n      <div class="panel panel-default">\n        <div class="panel-body">\n          <h3>Hunt overview</h3>\n          <grr-hunt-overview hunt-id="controller.huntId">\n          </grr-hunt-overview>\n        </div>\n      </div>\n    </div>\n  </div>\n</div>\n');
$templateCache.put("/acl/hunt-from-flow-copy-review.html",'<div class="container-fluid">\n  <div class="row comparison">\n\n    <div class="row">\n      <div class="col-md-6">\n        <div class="comparison-header">Source flow:</div>\n      </div>\n      <div class="col-md-6">\n        <div class="comparison-header">Hunt flow parameters:</div>\n      </div>\n    </div>\n\n    <div class="comparison-section">\n      <grr-semantic-protos-diff original-value="controller.sourceFlow"\n                                new-value="controller.newFlow"\n                                visible-fields="[\'name\', \'args\']">\n      </grr-semantic-protos-diff>\n    </div>\n\n  </div>\n</div>\n');
$templateCache.put("/acl/hunt-from-hunt-copy-review.html",'<div class="container-fluid">\n  <div class="row comparison">\n\n    <div class="row">\n      <div class="col-md-6">\n        <div class="comparison-header">Was:</div>\n      </div>\n      <div class="col-md-6">\n        <div class="comparison-header">Is:</div>\n      </div>\n    </div>\n\n    <div class="comparison-section">\n      <grr-semantic-protos-diff original-value="sourceHunt"\n                                new-value="newHunt"\n                                visible-fields="[\'flow_name\', \'flow_args\']">\n      </grr-semantic-protos-diff>\n    </div>\n\n    <div class="comparison-section">\n      <grr-semantic-protos-diff original-value="sourceHunt.value.hunt_runner_args"\n                                new-value="newHunt.value.hunt_runner_args"\n                                hidden-fields="[\'client_rule_set\', \'original_object\']">\n      </grr-semantic-protos-diff>\n    </div>\n\n    <div class="comparison-section">\n      <grr-semantic-protos-diff original-value="sourceHunt.value.client_rule_set"\n                                new-value="newHunt.value.client_rule_set">\n      </grr-semantic-protos-diff>\n    </div>\n\n    <div class="comparison-section">\n      <grr-semantic-protos-diff original-value="sourceHunt.value.hunt_runner_args.value.output_plugins"\n                                new-value="newHunt.value.hunt_runner_args.value.output_plugins">\n      </grr-semantic-protos-diff>\n    </div>\n\n  </div>\n</div>\n');
$templateCache.put("/acl/request-approval-dialog.html",'<grr-confirmation-dialog name="RequestApprovalDialog"\n                         title="\'Request \' + controller.subjectTitle + \' Approval\'"\n                         proceed="controller.proceed()"\n                         proceed-name="\'Submit\'"\n                         proceed-class="\'btn-success\'"\n                         can-proceed="controller.reason && controller.approversList"\n                         auto-close-on-success="true">\n\n  <p class="text-info">\n    Approval is required to access this\n    {$ controller.subjectTitle | lowercase $}.\n\n    <blockquote ng-if="accessErrorDescription">\n      {$ accessErrorDescription $}\n    </blockquote>\n  </p>\n\n  <h3>Create a new approval request.</h3>\n  <form class="form-horizontal acl-form">\n    <div class="form-group">\n      <label class="control-label">Approvers</label>\n      <div class="controls">\n        <grr-approver-input ng-model="controller.approversList"></grr-approver-input>\n      </div>\n    </div>\n\n\n    <div class="form-group" ng-if="controller.ccAddresses.length">\n      <div class="controls">\n        <label>\n          <input type="checkbox" name="cc_approval" ng-model="controller.useCcAddresses">\n          </input>\n          CC {$ controller.ccAddresses.join(\', \') $}\n        </label>\n      </div>\n    </div>\n\n    <div class="form-group">\n      <label class="control-label">Reason</label>\n      <div class="controls">\n        <select class="form-control"\n                name="acl_recent_reasons"\n                ng-model="controller.selectedRecentReason">\n          <option value="">Enter New Reason...</option>\n          <option ng-repeat="reason in controller.recentReasons"\n                  value="{$ reason $}">{$ reason $}</option>\n        </select>\n      </div>\n    </div>\n\n    <div class="form-group">\n      <label class="control-label"></label>\n      <div class="controls">\n        <input type="text" name="acl_reason" class="form-control"\n               ng-disabled="controller.selectedRecentReason"\n               ng-model="controller.reason">\n        </input>\n      </div>\n    </div>\n\n    <div class="form-group" ng-if="approvalType == \'client\'">\n      <div class="controls">\n        <label>\n          <input type="checkbox" name="keepalive" ng-model="controller.keepClientAlive">\n          </input>\n          Keep this client alive as soon as it comes online.\n        </label>\n      </div>\n    </div>\n\n  </form>\n\n</grr-confirmation-dialog>\n');
$templateCache.put("/artifact/artifact-descriptor.html",'<h5 class="preserve-linebreaks">{$ ::value.value.artifact.value.doc.value $}</h5>\n<table class="table table-bordered table-condensed">\n  <tr ng-if="::value.value.error_message.value">\n    <td class="col-md-3 proto_error">Error</td>\n    <td class="col-md-9 proto_error">\n      <grr-semantic-value value="::value.value.error_message.value" />\n    </td>\n  </tr>\n  <tr>\n    <td class="col-md-3">Labels</td>\n    <td class="col-md-9">\n      <grr-semantic-value value="::value.value.artifact.value.labels" />\n    </td>\n  </tr>\n\n  <tr>\n    <td class="col-md-3">Platforms</td>\n    <td class="col-md-9">\n      <grr-semantic-value value="::value.value.artifact.value.supported_os" />\n    </td>\n  </tr>\n\n  <tr>\n    <td class="col-md-3">Conditions</td>\n    <td class="col-md-9">\n      <grr-semantic-value value="::value.value.artifact.value.conditions" />\n    </td>\n  </tr>\n\n  <tr>\n    <td class="col-md-3">Path Dependencies</td>\n    <td class="col-md-9">\n      <grr-semantic-value value="::value.value.path_dependencies" />\n    </td>\n  </tr>\n\n  <tr>\n    <td class="col-md-3">Links</td>\n    <td class="col-md-9">\n      <div ng-repeat="link in ::value.value.artifact.value.urls">\n        <a ng-href="{{::link.value}}" target="_blank">{$ ::link.value $}</a>\n      </div>\n    </td>\n  </tr>\n\n  <tr>\n    <td class="col-md-3">Output Type</td>\n    <td class="col-md-9">\n      <grr-semantic-value value="::value.value.output_types" />\n    </td>\n  </tr>\n</table>\n\n<div ng-if="::value.value.artifact.value.sources.length > 0">\n  <h5>Artifact Sources</h5>\n  <grr-semantic-value value="::value.value.artifact.value.sources" />\n</div>\n\n<div ng-if="::value.value.processors.length > 0">\n  <h5>Artifact Processors</h5>\n  <grr-semantic-value value="::value.value.processors" />\n</div>\n');
$templateCache.put("/artifact/artifact-manager-view.html",'<ul class="breadcrumb">\n  <li>\n    <button class="btn btn-default"\n            title="Upload Artifacts as JSON or YAML"\n            name="UploadArtifact"\n            ng-click="controller.upload()">\n      <img src=\'/static/images/upload.png\' class=\'toolbar_icon\'>\n    </button>\n\n    <button class="btn btn-default"\n            title="Delete selected artifacts"\n            name="DeleteArtifact"\n            ng-disabled="controller.numSelectedDescriptors == 0"\n            ng-click="controller.deleteSelected()">\n      <img src=\'/static/images/editdelete.png\' class=\'toolbar_icon\'>\n    </button>\n  </li>\n</ul>\n\n<table class="table table-condensed table-bordered full-width">\n  <colgroup>\n    <col style="width: 40px">\n    <col width="100px"></col>\n    <col width="100%"></col>\n  </colgroup>\n\n  <thead>\n    <tr>\n      <th><input type="checkbox" class="client-checkbox select-all"\n                 ng-model="controller.allDescriptorsSelected"\n                 ng-change="controller.selectAll()" />\n      <th>Artifact Name</th>\n      <th>Artifact Details</th>\n    </tr>\n  </thead>\n\n  <tbody>\n    <tr grr-infinite-table grr-api-items-provider url="controller.artifactsUrl"\n        page-size="65536"\n        transform-items="controller.transformItems(items)"\n        trigger-update="controller.triggerUpdate">\n\n      \x3c!-- Selection checkbox --\x3e\n      <td>\n        <input type="checkbox" class="client-checkbox"\n               ng-change="controller.updateNumSelectedDescriptors()"\n               ng-model="controller.selectedDescriptors[item.value.artifact.value.name.value]"\n               ng-click="$event.stopPropagation()"\n               />\n      </td>\n\n      <td><grr-semantic-value value="::item.value.artifact.value.name"></grr-semantic-value></td>\n      <td><grr-semantic-value value="::item"></grr-semantic-value></td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/artifact/artifact-name.html",'\x3c!-- We\'re using "controller.artifactType && ..." syntax so that the expression is\n     resolved to undefined when artifactType is undefined. This way one-time\n     binding doesn\'t get removed until controller.artifactType becomes something\n     other than undefined (see "One-time binding" section here:\n     https://docs.angularjs.org/guide/expression). --\x3e\n<span ng-class="::{\'system\': controller.artifactType && controller.artifactType === \'SYSTEM\',\n                   \'user\': controller.artifactType && controller.artifactType === \'USER\'}">\n  <nobr>\n    {$ ::value.value $}\n\n    <span class="icon"\n          title="Custom Uploaded Artifact"\n          ng-if="::controller.artifactType && controller.artifactType === \'USER\'">\n      <i class="fa fa-user fa-1" aria-hidden="true"></i>\n    </span>\n  </nobr>\n</span>\n');
$templateCache.put("/artifact/artifacts-list-form.html",'<div class="container-fluid">\n\n<div class="col-md-5">\n\n  <div class="input-group">\n    <input name="Search" class="form-control" style="background-color: #ffffff" type="text" placeholder="Search" ng-model="controller.search"></input>\n\n    <span class="input-group-btn" uib-dropdown>\n      <button type="button" class="btn btn-default" uib-dropdown-toggle aria-haspopup="true" aria-expanded="false">\n        {$ controller.selectedPlatform || "All Platforms" $}\n        <span class="caret"></span>\n      </button>\n      <ul class="dropdown-menu" uib-dropdown-menu>\n        <li ng-repeat="platform in controller.platforms">\n          <a ng-click="controller.selectedPlatform = platform">{$ platform || "All Platforms" $}</a>\n        </li>\n      </ul>\n    </span>\n\n  </div>\n\n  <div style="height: 150px; overflow-y: auto; overflow-x: hidden; border: 1px solid #dddddd; border-top: none">\n\n    <table name="Artifacts" class="table table-condensed table-hover table-striped">\n      <colgroup>\n        <col width="100%"></col>\n      </colgroup>\n\n      <tbody>\n        <tr ng-if="!controller.descriptorsError && controller.descriptors === undefined">\n          <td>\n            <i class="fa fa-spinner fa-spin fa-1"></i>\n            <em>Loading artifacts...</em>\n          </td>\n        </tr>\n        <tr ng-if="controller.descriptorsError" class="alert-danger danger">\n          <td>\n            <strong>Can\'t fetch artifacts list:</strong><br/>\n            <span class="preserve-linebreaks">{$ controller.descriptorsError $}</span>\n          </td>\n        </tr>\n        <tr ng-repeat="descriptor in controller.descriptorsList |\n                       orderBy:\'value.artifact.value.name.value\' |\n                       filter:controller.searchFilterRef |\n                       filter:controller.platformFilterRef"\n            ng-class="{\'row-selected\': descriptor.value.artifact.value.name ==\n                      controller.selectedName}">\n          <td style="cursor: pointer; border: none"\n              ng-dblclick="controller.add(descriptor.value.artifact.value.name)"\n              ng-click="controller.selectedName = descriptor.value.artifact.value.name">\n            <div style="display:block" class="full-width-height"\n                 ng-class="::{\'custom-artifact\': descriptor.value.is_custom.value === true}">\n              {$ ::descriptor.value.artifact.value.name.value $}\n\n              <span title="Custom Uploaded Artifact"\n                    ng-if="::descriptor.value.is_custom.value === true">\n                <i class="fa fa-user fa-1" aria-hidden="true"></i>\n              </span>\n            </div>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n\n  <div style="full-width">\n    <div class="pull-left" style="padding-top: 1.5em">\n      <p>Selected Artifacts:</p>\n    </div>\n    <div class="pull-right">\n      <button class="btn btn-default btn-sm form-add" style="margin-top: 0.5em" name="Add"\n              ng-click="controller.add(controller.selectedName)">\n        Add\n      </button>\n    </div>\n    <div class="clearfix"></div>\n  </div>\n\n  <div style="margin-top: 0em; height: 150px; overflow-y: auto; overflow-x: hidden; border: 1px solid #dddddd">\n\n    <table name="SelectedArtifacts" class="table table-condensed table-hover table-striped">\n      <colgroup>\n        <col width="100%"></col>\n      </colgroup>\n\n      <tbody>\n        <tr ng-if="value.length > 0"\n            ng-repeat="name in value | orderBy:\'value\'"\n            ng-class="{\'row-selected\': name == controller.selectedName}">\n          <td style="cursor: pointer; border: none"\n              ng-dblclick="controller.remove(name)"\n              ng-click="controller.selectedName = name"\n              ng-class="{\'row-selected\': name == controller.selectedName}">\n            <div style="display:block" class="full-width-height">\n              <strong>{$ ::name.value $}</strong>\n\n              <span title="Custom Uploaded Artifact"\n                    ng-if="::controller.descriptors[name.value].value.is_custom.value === true">\n                <i class="fa fa-user fa-1" aria-hidden="true"></i>\n              </span>\n            </div>\n          </td>\n        </tr>\n        <tr ng-if="value.length == 0">\n          <td>\n            <em>Use "Add" button or double-click to add artifacts to the list.</em>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n\n  <div class="full-width" style="margin-top: 0.5em">\n    <button class="btn btn-default btn-sm form-add" name="Add"\n            ng-click="controller.clear()">\n      Clear\n    </button>\n\n    <div class="pull-right">\n      <button class="btn btn-default btn-sm form-add" name="Add"\n              ng-click="controller.remove(controller.selectedName)">\n        Remove\n      </button>\n    </div>\n    <div style="cleafix"></div>\n  </div>\n</div>\n\n<div name="ArtifactInfo" class="col-md-7"\n     grr-force-refresh refresh-trigger="controller.selectedName.value">\n  <grr-semantic-value value="controller.descriptors[controller.selectedName.value]" />\n</div>\n\n</div>\n');
$templateCache.put("/artifact/delete-artifacts-dialog.html",'<grr-confirmation-dialog name="DeleteArtifactDialog"\n                         title="\'Delete Selected Artifacts\'"\n                         proceed="controller.proceed()">\n\n  <p>Are you sure you want to delete following artifacts?</p>\n  <ul>\n    <li ng-repeat="name in names">\n      {$ name $}\n    </li>\n  </ul>\n\n</grr-confirmation-dialog>');$templateCache.put("/artifact/upload-artifact-dialog.html",'<grr-confirmation-dialog name="UploadArtifactDialog"\n                         title="\'Upload Artifact\'"\n                         proceed="controller.proceed()">\n\n  <input type="file" ng-disabled="controller.inProgress"\n         onchange="angular.element(this).scope().controller.onFileSet(this.files)" />\n\n</grr-confirmation-dialog>\n');
$templateCache.put("/client/add-clients-labels-dialog.html",'<grr-confirmation-dialog name="AddClientsLabelsDialog"\n                         title="\'Add Label\'"\n                         proceed="controller.proceed()"\n                         can-proceed="controller.labelName">\n\n  <form class="form-horizontal">\n    <div class="form-group">\n      <label class="control-label" for="labelBox">Label</label>\n      <div class="controls">\n        <input type="text" name="labelBox" ng-model="controller.labelName" />\n      </div>\n    </div>\n  </form>\n\n  <table class="table table-striped table-condensed">\n    <thead>\n    <tr>\n      <th>Affected clients:</th>\n    </tr>\n    </thead>\n    <tbody>\n    <tr ng-repeat="client in clients">\n      <td><grr-client-urn value="client.value.client_id" /></td>\n    </tr>\n    </tbody>\n  </table>\n\n</grr-confirmation-dialog>\n');
$templateCache.put("/client/check-client-access.html","<div ng-class=\"{'access-disabled': clientId !== undefined && !outHasAccess}\">\n  <ng-transclude></ng-transclude>\n</div>\n");$templateCache.put("/client/client-crashes.html",'<grr-check-client-access client-id="controller.clientId">\n  <grr-semantic-value value="controller.crashes"></grr-semantic-value>\n</grr-check-client-access>\n');$templateCache.put("/client/client-disk-warnings-modal.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()" aria-hidden="true">x</button>\n  <h3>Disk warnings</h3>\n</div>\n<div class="modal-body">\n  <table>\n    <tr>\n      <th>volume</th>\n      <th>available space</th>\n    </tr>\n    <tr ng-repeat="warning in warnings">\n      <td class="disk-warnings-volume">{$ ::warning.volume $}</td>\n      <td class="disk-warnings-space">{$ warning.percent | number:0 $}%</td>\n    </tr>\n  </table>\n</div>\n<div class="modal-footer">\n  <button class="btn btn-primary" ng-click="$dismiss()">Close</button>\n</div>\n');
$templateCache.put("/client/client-load-view.html",'<grr-check-client-access client-id="controller.clientId">\n\n  <div ng-if="controller.clientId">\n\n    <grr-debug-requests-view fetch-responses="0">\n    </grr-debug-requests-view>\n\n    <div class="pull-right padded">\n      <div class="btn-group">\n        <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="60">1h</label>\n        <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="180">3h</label>\n        <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="360">6h</label>\n        <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="1440">1d</label>\n        <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="10080">7d</label>\n        <label class="btn btn-primary" ng-model="controller.duration" uib-btn-radio="44640">31d</label>\n      </div>\n    </div>\n\n    <div class="clearfix"></div>\n\n    <div class="padded">\n\n      <h4>Client CPU usage</h4>\n      <grr-timeseries-graph title="Client CPU usage"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime"\n                            compute-delta="true">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="User CPU seconds"\n                                     metric="cpu_user">\n        </grr-client-load-graph-serie>\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="System CPU seconds"\n                                     metric="cpu_system">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client CPU load percentage</h4>\n      <grr-timeseries-graph title="Client CPU load percentage"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="CPU load percentage"\n                                     metric="cpu_percent">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client IO usage</h4>\n      <grr-timeseries-graph title="Client IO usage"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime"\n                            compute-delta="true">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Bytes read"\n                                     metric="io_read_bytes">\n        </grr-client-load-graph-serie>\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Bytes written"\n                                     metric="io_write_bytes">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client IO operations count</h4>\n      <grr-timeseries-graph title="Client IO operations"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime"\n                            compute-delta="true">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Read operations count"\n                                     metric="io_read_ops">\n        </grr-client-load-graph-serie>\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Write operations count"\n                                     metric="io_write_ops">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client memory usage percentage</h4>\n      <grr-timeseries-graph title="Client memory usage percentage"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Memory usage percentage"\n                                     metric="memory_percent">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client RSS/VMS sizes</h4>\n      <grr-timeseries-graph title="Client RSS/VMS sizes"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="RSS size"\n                                     metric="memory_rss_size">\n        </grr-client-load-graph-serie>\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="VMS size"\n                                     metric="memory_vms_size">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n      <h4>Client network usage</h4>\n      <grr-timeseries-graph title="Client network usage"\n                            start-time="controller.startTime"\n                            end-time="controller.endTime"\n                            compute-delta="true">\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Bytes received"\n                                     metric="network_bytes_received">\n        </grr-client-load-graph-serie>\n        <grr-client-load-graph-serie client-id="controller.clientId"\n                                     label="Bytes sent"\n                                     metric="network_bytes_sent">\n        </grr-client-load-graph-serie>\n      </grr-timeseries-graph>\n\n    </div>\n\n  </div>\n\n</grr-check-client-access>\n');
$templateCache.put("/client/client-status-icons.html",'<div ng-cloak class="centered" ng-if="controller.iconName != null">\n  <img class="grr-icon-small" name="clientStatusIcon"\n       ng-src="/static/images/{$ ::controller.iconName $}.png"\n       title="{$ ::controller.lastPing | grrTimeSince $}" />\n\n  <img ng-if="::controller.crashTime != null" class="grr-icon"\n       ng-src="/static/images/skull-icon.png" name="clientCrashIcon"\n       title="{$ ::controller.crashTime | grrTimeSince $}" />\n\n  <img ng-if="::controller.diskWarnings.length > 0" class="grr-icon"\n       ng-src="/static/images/hdd-bang-icon.png" name="clientDiskWarnings"\n       ng-click="controller.showDiskWarnings($event)"\n       style="cursor: pointer !important;"\n       title="Disk free space is low (click for details)" />\n</div>\n');
$templateCache.put("/client/clients-list.html",'<ul class="breadcrumb">\n  <li>\n    <button title="Add Labels" class="btn btn-default"\n            ng-disabled="controller.numSelectedClients == 0"\n            ng-click="controller.showLabelsDialog(\'add\')"\n            name="AddLabels">\n      <img src="/static/images/label-add.png" class="toolbar_icon" />\n    </button>\n    <button title="Remove Labels" class="btn btn-default"\n            ng-disabled="controller.numSelectedClients == 0"\n            ng-click="controller.showLabelsDialog(\'remove\')"\n            name="RemoveLabels">\n      <img src="/static/images/label-remove.png" class="toolbar_icon" />\n    </button>\n  </li>\n</ul>\n\n<table class="table table-striped table-condensed table-hover table-bordered full-width">\n  <colgroup>\n    <col style="width: 40px">\n    <col style="width: 40px">\n    <col style="width: 13em">\n    <col style="width: 13em">\n    <col style="width: 20%">\n    <col style="width: 10%">\n    <col style="width: 20%">\n    <col style="width: 15%">\n    <col style="width: 15%">\n    <col style="width: 8%">\n    <col style="width: 15%">\n  </colgroup>\n  <thead>\n    <tr>\n      <th><input type="checkbox" class="client-checkbox select-all"\n                 grr-disable-if-no-trait="modify_client_labels_action_enabled"\n                 ng-model="controller.allClientsSelected"\n                 ng-change="controller.selectAll()" />\n      </th>\n      <th>Online</th>\n      <th>Subject</th>\n      <th>Host</th>\n      <th>OS Version</th>\n      <th>MAC</th>\n      <th>Usernames</th>\n      <th>First Seen</th>\n      <th>Client version</th>\n      <th>Labels</th>\n      <th>Last Checkin</th>\n      <th>OS Install Date</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-infinite-table grr-api-items-provider\n        query-params="{query: controller.query}"\n        url="controller.clientsQueryUrl"\n        transform-items="controller.onClientsFetched(items)"\n        trigger-update="controller.triggerUpdate"\n        ng-click="controller.onClientClick(item)">\n      \x3c!-- Selection checkbox --\x3e\n      <td>\n        <input type="checkbox" class="client-checkbox"\n               grr-disable-if-no-trait="modify_client_labels_action_enabled"\n               client_id="{$ item.value.client_id.value $}"\n               ng-model="controller.selectedClients[item.value.client_id.value]"\n               ng-change="controller.updateNumSelectedClients()"\n               ng-click="$event.stopPropagation()"\n               />\n      </td>\n\n      \x3c!-- Online status --\x3e\n      <td>\n        <grr-client-status-icons client="::item" />\n      </td>\n\n      \x3c!-- Subject --\x3e\n      <td>\n        <span type="subject">{$ ::item.value.client_id.value $}</span>\n      </td>\n\n      \x3c!-- Host --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.os_info.value.fqdn" />\n      </td>\n\n      \x3c!-- OS Version --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.os_info.value.version" />\n      </td>\n\n      \x3c!-- MAC --\x3e\n      <td>\n        <grr-semantic-value value="::item._mac_addresses" />\n      </td>\n\n      \x3c!-- Usernames --\x3e\n      <td>\n        <grr-semantic-value value="::item._usernames" />\n      </td>\n\n      \x3c!-- First seen --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.first_seen_at" />\n      </td>\n\n      \x3c!-- Client version --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.agent_info.value.client_version" />\n      </td>\n\n      \x3c!-- Labels --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.labels" />\n      </td>\n\n      \x3c!-- Latest checkin --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.last_clock" />\n      </td>\n\n      \x3c!-- OS install date --\x3e\n      <td>\n        <grr-semantic-value value="::item.value.os_info.value.install_date" />\n      </td>\n\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/client/debug-requests-view.html",'<grr-check-client-access client-id="controller.clientId"\n                         ng-if="controller.clientId">\n\n  <div class="horizontally-padded">\n\n    <h3>Client requests for {$ controller.clientId $}</h3>\n\n    <div ng-if="controller.actionRequests === undefined">\n      Loading...\n    </div>\n\n    <div ng-if="controller.actionRequests.length === 0">\n      No actions currently in progress.\n    </div>\n\n    <div grr-force-refresh refresh-trigger="controller.actionRequests">\n      <grr-semantic-value value="::controller.actionRequests">\n      </grr-semantic-value>\n    </div>\n\n  </div>\n\n</grr-check-client-access>\n');
$templateCache.put("/client/host-history-dialog.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$close()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h4 class="modal-title">Client {$ clientId $}: {$ fieldPath $} history</h4>\n</div>\n<div class="modal-body">\n  <div ng-if="controller.items === undefined" class="text-center">\n    <i class="fa fa-spinner fa-spin fa-3x margin-bottom"></i>\n    <div>Loading...</div>\n  </div>\n\n  <div ng-if="controller.items !== undefined"\n       grr-force-refresh refresh-trigger="controller.items">\n\n    <p class="text-right">\n      <em>\n        Time range <strong>from</strong>\n        <grr-semantic-value value="::controller.startTime"></grr-semantic-value>\n        <strong>to</strong>\n        <grr-semantic-value value="::controller.endTime"></grr-semantic-value>\n      </em>\n    </p>\n\n    <table class="table table-condensed history">\n      <thead>\n        <tr>\n          <th>Time</th>\n          <th>Version</th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr ng-repeat="item in ::controller.items">\n          <td class="time">\n            <grr-semantic-value value="::item[0]"></grr-semantic-value>\n          </td>\n          <td class="version">\n            <grr-semantic-value value="::item[1]"></grr-semantic-value>\n          </td>\n        </tr>\n      </tbody>\n    </table>\n\n  </div>\n</div>\n<div class="modal-footer">\n  <button class="btn btn-primary" ng-click="close()">Close</button>\n</div>\n');
$templateCache.put("/client/host-info.html",'<div ng-if="controller.client">\n\n  <h1>\n    {$ controller.client.value.os_info.value.fqdn.value $}\n    <span>{$ controller.clientId $}</span>\n  </h1>\n\n  <div ng-if="!readOnly">\n    <grr-check-client-access client-id="controller.clientId" no-redirect="true"\n                             out-has-access="controller.hasClientAccess">\n    </grr-check-client-access>\n\n    <div class="no-approval alert alert-danger alert-block"\n         ng-if="controller.hasClientAccess !== undefined && !controller.hasClientAccess">\n      <i class="fa fa-warning"></i> You do not have an <b>approval</b> for this client. <br/>\n\n      <button name="requestApproval" class="btn btn-default"\n              ng-click="controller.requestApproval()">Request Approval</button>\n    </div>\n  </div>\n\n  \x3c!-- Toolbar --\x3e\n  <div class="client-actions">\n\n    <button ng-if="!readOnly"\n            class="btn btn-default"\n            ng-click="controller.interrogate()"\n            ng-disabled="!controller.hasClientAccess || controller.interrogateOperationId">\n      <i class="fa fa-search-plus"\n         ng-if="!controller.interrogateOperationId"></i>\n      <i class="fa fa-spinner fa-spin fa-fw"\n          ng-if="controller.interrogateOperationId"></i>\n      Interrogate\n    </button>\n\n    <div class="btn-group">\n      <label class="btn btn-default" uib-btn-radio="false" ng-model="controller.showDetails">\n        Overview\n      </label>\n      <label class="btn btn-default" uib-btn-radio="true" ng-model="controller.showDetails">\n        Full details\n      </label>\n    </div>\n\n    <grr-version-dropdown version="controller.clientVersion"\n                          url="controller.clientVersionUrl">\n    </grr-version-dropdown>\n\n    <div class="clearfix"></div>\n  </div>\n\n\n  \x3c!-- Client Details --\x3e\n  <div class="client-overview" ng-if="!controller.showDetails"\n       grr-force-refresh refresh-trigger="controller.client">\n\n    \x3c!-- Overview --\x3e\n    <div class="client-info-wrapup">\n      <dt>OS</dt>\n      <dd>\n        <div ng-if="controller.client.value.os_info.value.system">\n          <i class="fa fa-linux" ng-if="controller.client.value.os_info.value.system.value == \'Linux\'"></i>\n          <i class="fa fa-windows" ng-if="controller.client.value.os_info.value.system.value == \'Windows\'"></i>\n          <i class="fa fa-apple" ng-if="controller.client.value.os_info.value.system.value == \'Apple\'"></i>\n\n          <grr-semantic-value value="controller.client.value.os_info.value.system"></grr-semantic-value>\n          <span ng-if="controller.client.value.os_info.value.system.value && (controller.client.value.os_info.value.release.value || controller.client.value.os_info.value.version.value)">,</span>\n          <grr-semantic-value value="controller.client.value.os_info.value.release"></grr-semantic-value>\n          <grr-semantic-value value="controller.client.value.os_info.value.version"></grr-semantic-value>\n        </div>\n\n        <div ng-if="!controller.client.value.os_info.value.system">\n          -\n        </div>\n      </dd>\n\n      <dt>Last Local Clock</dt>\n      <dd>\n        <i class="fa fa-history"></i>\n        <div ng-if="!controller.client.value.last_clock">-</div>\n        <grr-semantic-value value="controller.client.value.last_clock"\n                            ng-if="controller.client.value.last_clock">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>GRR Client Version</dt>\n      <dd>\n        <div ng-if="!controller.client.value.agent_info.value.client_version.value">-</div>\n        <grr-semantic-value value="controller.client.value.agent_info.value.client_version.value"\n                            ng-if="controller.client.value.agent_info.value.client_version.value">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Architecture</dt>\n      <dd>\n        <div ng-if="!controller.client.value.os_info.value.machine">-</div>\n        <grr-semantic-value value="controller.client.value.os_info.value.machine"\n                            ng-if="controller.client.value.os_info.value.machine">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Kernel</dt>\n      <dd>\n        <div ng-if="!controller.client.value.os_info.value.kernel">-</div>\n        <grr-semantic-value value="controller.client.value.os_info.value.kernel"\n                            ng-if="controller.client.value.os_info.value.kernel">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Memory Size</dt>\n      <dd>\n        <div ng-if="!controller.client.value.memory_size">-</div>\n        <grr-semantic-value value="controller.client.value.memory_size"\n                            ng-if="controller.client.value.memory_size">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Labels</dt>\n      <dd>\n        <span ng-if="!controller.client.value.labels.length">\n          No labels assigned.\n        </span>\n\n        <ul ng-if="controller.client.value.labels.length" class="label-list">\n          <li ng-repeat="label in controller.client.value.labels">\n            <span class="label label-success">{$ label.value.name.value $}</span>\n          </li>\n        </ul>\n      </dd>\n\n      <dt>Users</dt>\n      <dd>\n        <div ng-if="!controller.client.value.users.length">-</div>\n\n        <ul class="user-list">\n          <li ng-repeat="user in controller.client.value.users">\n            <i class="fa fa-user"></i> {$ ::user.value.full_name.value $} ({$ ::user.value.username.value $})\n          </li>\n        </ul>\n      </dd>\n    </div>\n\n    \x3c!-- Info Tiles --\x3e\n    <div class="client-info-details">\n\n      <div class="col-md-12 col-lg-6">\n\n        <section>\n          <h2><i class="fa fa-clock-o"></i> Timestamps</h2>\n\n          <table class="properties">\n            <tr>\n              <th>OS installation time</th>\n              <td ng-if="controller.client.value.os_info.value.install_date">\n                <grr-semantic-value value="controller.client.value.os_info.value.install_date">\n                </grr-semantic-value>\n                <span class="time-since">{$ (controller.client.value.os_info.value.install_date.value | grrTimeSince) $}</span>\n              </td>\n              <td ng-if="!controller.client.value.os_info.value.install_date">\n                -\n              </td>\n            </tr>\n            <tr>\n              <th>First seen</th>\n              <td ng-if="controller.client.value.first_seen_at">\n                <grr-semantic-value value="controller.client.value.first_seen_at">\n                </grr-semantic-value>\n                <span class="time-since">{$ controller.client.value.first_seen_at.value | grrTimeSince $}</span>\n              </td>\n              <td ng-if="!controller.client.value.first_seen_at">\n                -\n              </td>\n            </tr>\n            <tr>\n              <th>Last booted</th>\n              <td ng-if="controller.client.value.last_booted_at">\n                <grr-semantic-value value="controller.client.value.last_booted_at">\n                </grr-semantic-value>\n                <span class="time-since">{$ controller.client.value.last_booted_at.value | grrTimeSince $}</span>\n              </td>\n              <td ng-if="!controller.client.value.last_booted_at">\n                -\n              </td>\n            </tr>\n            <tr>\n              <th>Last seen</th>\n              <td ng-if="controller.client.value.last_seen_at">\n                <grr-semantic-value value="controller.client.value.last_seen_at">\n                </grr-semantic-value>\n                <span class="time-since">{$ controller.client.value.last_seen_at.value | grrTimeSince $}</span>\n              </td>\n              <td ng-if="!controller.client.value.last_seen_at">\n                -\n              </td>\n            </tr>\n          </table>\n        </section>\n      </div>\n\n      <div class="col-md-12 col-lg-6">\n        <section>\n          <h2><i class="fa fa-exchange"></i> Interfaces</h2>\n\n          <div ng-if="!controller.client.value.interfaces"\n               class="no-section-info">\n            No interface information available.\n          </div>\n\n          <table ng-if="controller.client.value.interfaces"\n                 class="full-section-info">\n            <thead>\n              <tr>\n                <th>IF Name</th>\n                <th>Mac Address</th>\n                <th>Addresses</th>\n              </tr>\n            </thead>\n            <tr ng-repeat="interface in controller.client.value.interfaces">\n              <td>\n                {$ ::interface.value.ifname.value $}\n              </td>\n              <td class="mac-address">\n                <grr-semantic-value value="interface.value.mac_address"></grr-semantic-value>\n              </td>\n              <td class="mac-address">\n                <ul>\n                  <li ng-repeat="address in interface.value.addresses">\n                    <grr-semantic-value value="address"></grr-semantic-value>\n                  </li>\n                </ul>\n              </td>\n            </tr>\n          </table>\n        </section>\n      </div>\n    </div>\n  </div>\n\n  \x3c!-- Shows the full view on the client with all properties and in full details --\x3e\n  <div class="client-details"\n       ng-if="controller.showDetails"\n       grr-force-refresh refresh-trigger="controller.client">\n    <grr-semantic-versioned-proto\n      client="::controller.client"\n      value="::controller.client"\n      on-field-click="controller.showHistoryDialog(fieldPath)"\n      history-depth="2">\n    </grr-semantic-versioned-proto>\n  </div>\n</div>\n');
$templateCache.put("/client/remove-clients-labels-dialog.html",'<grr-confirmation-dialog name="RemoveClientsLabelsDialog"\n                         title="\'Remove Label\'"\n                         proceed="controller.proceed()">\n\n  <form class="form-horizontal">\n    <div class="form-group">\n      <label class="control-label" for="labelBox">Label</label>\n      <div class="controls">\n        <select class="form-control"\n                ng-model="controller.labelName"\n                ng-options="item as item for item in controller.availableLabels">\n        </select>\n      </div>\n    </div>\n  </form>\n\n  <table class="table table-striped table-condensed">\n    <thead>\n    <tr>\n      <th>Affected clients:</th>\n    </tr>\n    </thead>\n    <tbody>\n    <tr ng-repeat="client in clients">\n      <td><grr-client-urn value="client.value.client_id" /></td>\n    </tr>\n    </tbody>\n  </table>\n\n</grr-confirmation-dialog>\n');
$templateCache.put("/config/binaries-list.html",'<table class="table table-condensed table-hover table-striped"\n       ng-if="controller.binaries.length > 0">\n  <tbody>\n    <tr ng-repeat="binary in ::controller.binaries"\n        ng-click="controller.onBinaryClicked(binary)">\n      <td>\n        <span ng-if="::binary.dirName.length > 0" class="path">\n          <strong>{$ ::binary.dirName $}</strong> / {$ ::binary.baseName $}\n        </span>\n        <span ng-if="::binary.dirName.length === 0" class="path">\n          {$ ::binary.baseName $}\n        </span>\n        <span class="timestamp pull-right">\n          <grr-semantic-value value="::binary.value.timestamp">\n          </grr-semantic-value>\n        </span>\n        <span ng-if="::binary.value.size !== undefined"\n              class="size pull-right">\n          <grr-semantic-value value="::binary.value.size">\n          </grr-semantic-value>\n        </span>\n      </td>\n    </tr>\n  </tbody>\n</table>\n\n<div class="padded" ng-if="controller.binaries.length === 0">\nNone.\n</div>\n');
$templateCache.put("/config/config-binaries-view.html",'<div class="padded" ng-if="controller.binaries !== undefined">\n\n  <div class="panel panel-default">\n    <div class="panel-heading">\n      <i class="fa fa-code fa-2" aria-hidden="true"></i>\n      Python Hacks\n    </div>\n\n    <grr-binaries-list binaries="controller.binaries"\n                       type-filter="PYTHON_HACK">\n    </grr-binaries-list>\n  </div>\n\n  <div class="panel panel-default">\n    <div class="panel-heading">\n      <i class="fa fa-cogs fa-xs" aria-hidden="true"></i>\n      Executables\n    </div>\n    <grr-binaries-list binaries="controller.binaries"\n                       type-filter="EXECUTABLE">\n    </grr-binaries-list>\n  </div>\n\n  <div class="panel panel-default">\n    <div class="panel-heading">\n      <i class="fa fa-th-large fa-2" aria-hidden="true"></i>\n      Components\n    </div>\n    <grr-binaries-list binaries="controller.binaries"\n                       type-filter="COMPONENT">\n    </grr-binaries-list>\n  </div>\n\n</div>\n\n<div class="padded" ng-if="controller.binaries === undefined">\nLoading...\n</div>\n');
$templateCache.put("/config/config-view.html",'<div class="container-fluid">\n  <div class="row horizontally-padded">\n\n    <h2>Configuration</h2>\n    <p>This is a read-only view of the frontend configuration. Blue values have\n    been changed from the default settings.</p>\n\n    <section ng-repeat="(section_name, section) in ::controller.items">\n      <h3>{$ ::section_name $}</h3>\n\n      <table class="table table-condensed table-bordered table-striped\n                    full-width fixed-layout">\n        <colgroup>\n          <col style="width: 40%" />\n          <col style="width: 60%" />\n        </colgroup>\n\n        <tbody class="TableBody">\n          <tr ng-repeat="(name, config) in ::section"\n              ng-class="::{warning: config.value.is_redacted.value}">\n            <td>{$ name $}</td>\n            <td>\n              <div ng-if="::config.value.is_redacted.value">(redacted)</div>\n              <grr-semantic-value value="::config.value.value">\n              </grr-semantic-value>\n              <div ng-if="::config.is_expanded">\n                <em>(expanded from {$ ::config.value.raw_value $})</em>\n              </div>\n            </td>\n          </tr>\n        </tbody>\n      <table>\n    </section>\n\n  </div>\n</div>\n');
$templateCache.put("/core/aff4-object-representation.html",'<div>\n  <table class="table table-condensed table-bordered full-width">\n\n    <colgroup>\n      <col style="width: 30ex" />\n      <col style="width: 100%" />\n      <col style="width: 30ex" />\n    </colgroup>\n\n    <thead>\n      <tr>\n        <th class="ui-state-default">Attribute</th>\n        <th class="ui-state-default">Value</th>\n        <th class="ui-state-default">Age</th>\n      </tr>\n    </thead>\n\n    <tbody>\n\n      <tr ng-repeat-start="type in ::controller.aff4ObjectRepresentation.types">\n        <td colspan="3" class="grr_aff4_type_header">\n          <b>{$ ::type.value.name.value $}</b>\n        </td>\n      </tr>\n\n      <tr ng-repeat="attribute in ::type.value.attributes" ng-repeat-end>\n\n        <td ng-click="attribute.historical = !attribute.historical">\n          <i class="fa fa-plus" ng-if="attribute.value.values.length > 1 && !attribute.historical"></i>\n          <i class="fa fa-minus" ng-if="attribute.value.values.length > 1 && attribute.historical"></i>\n          <b>{$ ::attribute.value.name.value $}</b>\n        </td>\n\n        <td>\n          <div ng-if="!attribute.historical">\n            <grr-semantic-value value="::attribute.value.values[0].value.value"></grr-semantic-value>\n          </div>\n\n          \x3c!-- Historical view with all previous values and their timestamps. --\x3e\n          <div class="historical" ng-if="attribute.historical">\n            <table class="table table-striped table-condensed table-hover table-bordered full-width">\n              <tr>\n                <th class="ui-state-default">Value</th>\n                <th class="ui-state-default">Age</th>\n              </tr>\n              <tr ng-repeat="historical in ::attribute.value.values">\n                <td>\n                  <grr-semantic-value value="::historical.value.value"></grr-semantic-value>\n                </td>\n                <td>\n                  <grr-timestamp value="::historical.value.age"></grr-timestamp>\n                </td>\n              </tr>\n            </table>\n          </div>\n        </td>\n\n        <td>\n          <grr-timestamp value="::attribute.value.values[0].value.age"></grr-timestamp>\n        </td>\n\n      </tr>\n\n    </tbody>\n\n  </table>\n\n</div>\n');
$templateCache.put("/core/confirmation-dialog.html",'\x3c!-- "title" attribute here is needed to override the "title" attribute that\n     will be set in grr-confirmation-dialog (that will be one level above)\n     and that will contain an Angular template expression. "title"\n     attribute is used by nested DOM elements when showing tooltips. --\x3e\n<div ng-attr-title="{$ title $}">\n\n  <div class="modal-header">\n    <button type="button" class="close" ng-click="controller.dismiss()">\n      <span aria-hidden="true">&times;</span>\n      <span class="sr-only">Close</span>\n    </button>\n    <h3 class="modal-title">{$ title $}</h3>\n  </div>\n\n  <div class="modal-body">\n    <ng-transclude></ng-transclude>\n  </div>\n\n  <div class="modal-footer" ng-if="!controller.success && !controller.error">\n    <button class="btn btn-default"\n            ng-click="controller.dismiss()"\n            ng-attr-title="{$ cancelName || \'Cancel\' $}"\n            name="Cancel">\n      {$ cancelName || \'Cancel\' $}\n    </button>\n\n    <button class="btn {$ proceedClass || \'btn-primary\' $}"\n            ng-click="controller.proceed()"\n            ng-disabled="canProceed && !canProceed()"\n            ng-attr-title="{$ proceedName || \'Proceed\' $}"\n            name="Proceed">\n      {$ proceedName || \'Proceed\' $}\n    </button>\n  </div>\n\n  <div class="modal-footer" ng-if="controller.success || controller.error">\n    <span class="text-success horizontally-padded"ng-if="controller.success">\n      <span class="glyphicon glyphicon-ok"></span>\n      <strong>{$ controller.success $}</strong>\n    </span>\n\n    <span class="text-danger horizontally-padded" ng-if="controller.error">\n      <span class="glyphicon glyphicon-exclamation-sign"></span>\n      <strong>{$ controller.error $}</strong>\n    </span>\n\n    <button class="btn btn-default"\n            ng-click="controller.close()"\n            ng-attr-title="{$ closeName || \'Close\' $}"\n            name="Close">\n      {$ closeName || \'Close\' $}\n    </button>\n  </div>\n\n</div>\n');
$templateCache.put("/core/download-collection-as.html",'<div class="export-buttons pull-right">\n  <div class="well well-sm export-well">\n    <span class="control-label">Download As:</span>\n    <select class="form-control pull-left"\n            ng-options="plugin as displayName for\n                        (plugin, displayName) in controller.pluginToDisplayName"\n            ng-model="controller.selectedPlugin"\n            id="plugin-select">\n    </select>\n    <button ng-click="controller.downloadAs(controller.selectedPlugin)" type="button"\n            name="download-as" class="btn btn-default">\n      Download\n    </button>\n  </div>\n</div>\n<div class="clearfix"></div>\n');
$templateCache.put("/core/download-collection-files.html",'<div class="well well-small">\n  <div class="pull-left">\n    Files referenced in this collection can be downloaded as an archive:&nbsp;\n\n    <div class="btn-group" uib-dropdown>\n      <button class="btn btn-default DownloadButton"\n              ng-disabled="controller.fileArchiveGenerationStarted"\n              ng-click="controller.generateFileArchive(controller.primaryArchiveExtension)">\n        Generate {$ controller.primaryArchiveExtension | uppercase $}\n      </button>\n      <button class="btn btn-default dropdown-toggle"\n              ng-disabled="controller.fileArchiveGenerationStarted"\n              uib-dropdown-toggle>\n        <span class="caret"></span>\n      </button>\n      <ul class="dropdown-menu" uib-dropdown-menu>\n       <li>\n         <a ng-click="controller.generateFileArchive(controller.secondaryArchiveExtension); $event.preventDefault()"\n            href="#">\n           Generate {$ controller.secondaryArchiveExtension | uppercase $}\n         </a>\n       </li>\n      </ul>\n    </div>\n  </div>\n\n  <div class="pull-right">\n    <em>NOTE: generated archive will contain <strong>symlinks</strong>.<br/>\n      Unsure whether your archive utility supports them?<br/>\n      Just unpack the archive before browsing its contents.</em>\n  </div>\n  <div class="clearfix"></div>\n\n  <div class="export-command" ng-if="controller.exportCommand">\n    <a ng-click="exportCommandExpanded = !exportCommandExpanded">\n      {$ exportCommandExpanded ? \'Hide\' : \'Show\' $} export command\n    </a>\n    <div uib-collapse="!exportCommandExpanded" class="padded">\n      <p>\n        To download all the files referenced in the collection, you can use\n        this command:\n      </p>\n      <pre>{$ controller.exportCommand $}</pre>\n    </div>\n  </div>\n</div>\n\n<div class="alert alert-success"\n     ng-if="controller.fileArchiveGenerationStarted &&\n            controller.fileArchiveGenerationSuccess !== undefined">\n  <em>Generation has started.</em>\n</div>\n\n<div class="alert alert-error"\n     ng-if="controller.fileArchiveGenerationStarted &&\n            controller.fileArchiveGenerationError !== undefined">\n  <em>Can\'t generate archive: {$ controller.fileArchiveGenerationError $}.</em>\n</div>\n');
$templateCache.put("/core/paged-filtered-table-bottom.html",'<h5 ng-if="parentController.showLoading">Loading...</h5>\n\n<div ng-if="!parentController.showLoading && parentController.totalCount > 0 && !parentController.filterApplied">\n  <ul uib-pagination total-items="parentController.totalCount" items-per-page="parentController.pageSize"\n      max-size="15" rotate="false" boundary-links="true"\n      ng-model="parentController.paginationSelectedPage"\n      ng-change="parentController.onPageChange(parentController.paginationSelectedPage - 1)">\n  </ul>\n</div>\n\n<div ng-if="!parentController.showLoading && parentController.totalCount > 0 &&\n            parentController.filterApplied && !parentController.filterFinished">\n  <div class="btn-group" uib-dropdown>\n    <button class="btn btn-default" ng-click="parentController.fetchFilteredItems(1)">\n      Fetch More\n    </button>\n    <button class="btn btn-default dropdown-toggle" uib-dropdown-toggle>\n      <span class="caret"></span>\n    </button>\n    <ul class="dropdown-menu" uib-dropdown-menu>\n      <li><a ng-click="parentController.fetchFilteredItems(2)">Fetch {$ parentController.pageSize * 2 $} items</a></li>\n      <li><a ng-click="parentController.fetchFilteredItems(5)">Fetch {$ parentController.pageSize * 5 $} items</a></li>\n      <li><a ng-click="parentController.fetchFilteredItems(10)">Fetch {$ parentController.pageSize * 10 $} items</a></li>\n    </ul>\n  </div>\n</div>\n');
$templateCache.put("/core/paged-filtered-table-top.html",'<h5 class="pull-left" ng-if="parentController.totalCount !== undefined">\n  <span ng-if="parentController.totalCount && !parentController.filterApplied">{$ parentController.totalCount $} entries</span>\n  <span ng-if="parentController.totalCount && parentController.filterApplied">Filtered by: {$ parentController.filterValue $}</span>\n</h5>\n\n<div class="pull-right" ng-if="parentController.totalCount">\n  <input type="text" class="search-query"\n         ng-model="parentController.filterEditedValue"\n         ng-keydown="$event.which == 13 && parentController.applyFilter()"\n         placeholder="">\n  <button class="btn btn-default" ng-click="parentController.applyFilter()">Filter</button>\n</div>\n<div class="clear"></div>\n\n');
$templateCache.put("/core/results-collection.html",'\x3c!-- "Download as" buttons --\x3e\n<grr-download-collection-as base-url="exportedResultsUrl"\n                            ng-if="exportedResultsUrl &&\n                                   controller.resultsArePresent">\n</grr-download-collection-as>\n\n\x3c!-- "Download Files" panel --\x3e\n<grr-download-collection-files download-url="downloadFilesUrl"\n                               export-command-url="exportCommandUrl"\n\n                               ng-if="downloadFilesUrl &&\n                                      controller.resultsAreFiles">\n\n</grr-download-collection-files>\n\n<grr-output-plugins-notes output-plugins-url="outputPluginsUrl"\n                          ng-if="outputPluginsUrl">\n</grr-output-plugins-notes>\n\n\x3c!-- Results table --\x3e\n<table class="table table-striped table-condensed table-bordered full-width"\n       ng-if="resultsUrl">\n  <thead>\n    <tr>\n      <th>Value</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-paged-filtered-table\n        grr-api-items-provider url="::resultsUrl"\n        transform-items="controller.transformItems(items)"\n        auto-refresh-interval="::controller.autoRefreshInterval">\n      <td><grr-semantic-value value="::item" /></td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/core/search-box.html",'<div>\n  <a href="/help/{$ controller.contextHelpUrl $}" target="_blank"\n     class="pull-right">\n    <i class="glyphicon glyphicon-question-sign input-append"></i>\n  </a>\n\n  <form class="pull-right client-search-box">\n    <div class="form-group">\n      <div class="input-group">\n        <input id="client_query" autocomplete="off"\n               grr-disable-if-no-trait="search_clients_action_enabled"\n               type="text" name="q" class="form-control search-query"\n               placeholder="Search Box" ng-model="controller.query"\n               ng-keypress="$event.which == 13 && controller.submitQuery()"\n               uib-typeahead="label for label in controller.labels | filter:$viewValue | limitTo:8"\n               typeahead-min-length="3"\n               typeahead-focus-first="false"\n               typeahead-template-url="/static/angular-components/core/typeahead-match.html"\n        />\n        <span class="input-group-btn">\n          <button id="client_query_submit"\n                  type="button"\n                  class="btn btn-default search-query"\n                  ng-click="controller.submitQuery()">\n            <span class="glyphicon glyphicon-search"></span>\n          </button>\n        </span>\n      </div>\n    </div>\n  </form>\n</div>\n');
$templateCache.put("/core/server-error-button.html",'<button id="show_backtrace" class="nav-btn btn btn-danger"\n        ng-click="controller.showError()"\n        ng-show="controller.buttonVisible">\n  <img src="/static/images/stock_dialog_question.png" class="grr-icon"/>\n</button>\n');$templateCache.put("/core/server-error-dialog.html",'<div name="ServerErrorDialog">\n  <div class="modal-header">\n    <button type="button" class="close" ng-click="close()" aria-hidden="true">\u00d7</button>\n    <h3>{$ message $}</h3>\n  </div>\n  <div class="modal-body">\n    <pre>{$ traceBack $}</pre>\n  </div>\n  <div class="modal-footer">\n    <button class="btn btn-primary" ng-click="close()">Close</button>\n  </div>\n</div>');
$templateCache.put("/core/troggle.html",'<div ng-click="switchState()">\n  <span ng-if="state === \'SET\'">\u2713</span>\n  <span ng-if="state === \'UNSET\'">\u2715</span>\n  <span ng-if="state === \'VOID\'">_</span>\n</div>\n');$templateCache.put("/core/typeahead-match.html",'\x3c!--\n  Custom autocompletion list item template:\n\n  Removed highlighting, since highlighting uses the whole input text, but we suggest autocompletions\n  based on parts. Also, this reduces the attack surface because HTML binding is no loner required.\n\n  Removed title, since ng-attr-title was not evaluated properly and showed literally\n  {{match.label}} in tooltips.\n--\x3e\n<a href tabindex="-1" ng-bind="match.label"></a>\n');
$templateCache.put("/core/version-dropdown.html",'<div>\n\n  <select ng-model="controller.version"\n          ng-disabled="!controller.versions.length"\n          class="form-control version-dropdown">\n\n    <option ng-if="controller.versions.length"\n            ng-selected="controller.isSelected(\'HEAD\')"\n            value="HEAD">\n      HEAD\n    </option>\n\n    \x3c!-- We cannot use ng-options here, since it does not set the selected attribute. --\x3e\n    <option ng-repeat="v in controller.versions"\n            ng-selected="controller.isSelected(v.value)"\n            value="{$ v.value $}">\n      {$ v.value | grrTimestamp $}\n    </option>\n\n    <option ng-if="!controller.versions.length"\n            ng-selected="true"\n            value="">\n      No versions available.\n    </option>\n\n  </select>\n\n  \x3c!-- Indicate that we are not showing the latest item. --\x3e\n  <div class="newer-version-hint" ng-if="!controller.isLatestSelected()">\n    Newer Version available.\n  </div>\n\n</div>\n');
$templateCache.put("/core/wizard-form-page.html",'<div class="modal-body" ng-show="controller.formController.currentPage === controller">\n  <ng-transclude></ng-transclude>\n</div>\n');$templateCache.put("/core/wizard-form.html",'<div class="Wizard FormData">\n  <div class="WizardPage">\n    <div class="WizardBar modal-header">\n      <button type="button" class="close"\n              ng-click="controller.reject()" aria-hidden="true">\n        x\n      </button>\n\n      <h3>{$ title $} -\n        <span class="Description">\n          {$ controller.currentPage.title $}\n        </span>\n        <span ng-if="controller.currentPage.helpLink">\n          <a ng-href="{$ controller.currentPage.helpLink $}" target="_blank">\n            <i class="glyphicon glyphicon-question-sign"></i>\n          </a>\n        </span>\n        <span class="page-indicator">\n          Step {$ controller.currentPageIndex + 1 $} out of {$ controller.pages.length $}\n        </span>\n      </h3>\n    </div>\n\n    <ng-transclude></ng-transclude>\n  </div>\n\n  <div class="modal-footer navbar-inner">\n    <ul class="nav pull-right">\n      <button ng-if="controller.currentPageIndex > 0 && !controller.currentPage.noBackButton"\n              class="btn btn-default Back"\n              ng-click="controller.back()">\n        {$ controller.currentPage.prevButtonLabel $}\n      </button>\n      <button class="btn btn-primary Next"\n              ng-disabled="!controller.currentPage.isValid"\n              ng-click="controller.next()">\n        {$ controller.currentPage.nextButtonLabel $}\n      </button>\n    </ul>\n  </div>\n\n</div>\n');
$templateCache.put("/cron/cron-job-inspector.html",'<div class="padded" grr-force-refresh refresh-trigger="cronJobId">\n\n  <div ng-if="!cronJobId">\n    Please select a cron job to see the details.\n  </div>\n\n  <uib-tabset ng-if="cronJobId">\n    <uib-tab heading="Details" id="Details">\n      <grr-cron-job-overview cron-job-id="cronJobId">\n      </grr-cron-job-overview>\n    </uib-tab>\n\n    <uib-tab heading="Runs" id="Runs">\n      <grr-cron-job-runs-list cron-job-id="cronJobId">\n      </grr-cron-job-runs-list>\n    </uib-tab>\n  </uib-tabset>\n\n</div>\n');
$templateCache.put("/cron/cron-job-overview.html",'<div ng-if="cronJobId && !controller.cronJob">\n  Loading...\n</div>\n\n<div ng-if="controller.cronJob">\n\n  <dl class="dl-horizontal dl-flow">\n    <div class="dl-group">\n      <dt>ID</dt>\n      <dd>{$ controller.cronJobId $}</dd>\n\n      <dt>Cron Job ID</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.cron_job_id">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Description</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.description">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Enabled</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.enabled">\n        </grr-semantic-value>\n      </dd>\n    </div>\n\n\n    <div class="dl-group">\n      <dt>Frequency</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.frequency">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Last Run Time</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.last_run_time">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Max Iteration Lifetime</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.lifetime">\n        </grr-semantic-value>\n      </dd>\n\n      <dt>Allow Overruns</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.allow_overruns">\n        </grr-semantic-value>\n      </dd>\n    </div>\n\n    <div class="dl-group">\n      <dt>Cron Arguments</dt>\n      <dd>\n        <grr-semantic-value value="controller.cronJob.value.args">\n        </grr-semantic-value>\n      </dd>\n    </div>\n\n  </dl>\n\n</div>\n');
$templateCache.put("/cron/cron-job-runs-list.html",'<table class="table table-striped table-condensed table-hover table-bordered full-width">\n  <colgroup>\n    <col style="width: 40px">\n    <col style="width: 20%">\n    <col style="width: 20%">\n    <col style="width: 20%">\n    <col style="width: 20%">\n    <col style="width: 20%">\n  </colgroup>\n  <thead>\n    <tr>\n      <th>Status</th>\n      <th>Run ID</th>\n      <th>Started At</th>\n      <th>Finished At</th>\n      <th>Log Message</th>\n      <th>Backtrace</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-infinite-table page-size="100"\n        grr-api-items-provider url="controller.runsUrl"\n        ng-class="{\'row-selected\': controller.selectedRunId === item.value.run_id.value}"\n        ng-click="controller.selectedRunId = item.value.run_id.value">\n      <td>\n        <div class="centered run-state-icon">\n          <img ng-if="::item.value.status.value == \'FINISHED\'"\n               title="Run finished normally."\n               class="grr-icon grr-run-icon" src="/static/images/stock_yes.png" />\n          <img ng-if="::item.value.status.value == \'RUNNING\'"\n               title="Run is still running."\n               class="grr-icon grr-run-icon" src="/static/images/clock.png" />\n          <img ng-if="::item.value.status.value == \'ERROR\'"\n               title="Run terminated with an error."\n               class="grr-icon grr-run-icon" src="/static/images/nuke.png" />\n          <img ng-if="::item.value.status.value == \'LIFETIME_EXCEEDED\'"\n               title="The cron job run was cancelled because it ran for too long."\n               class="grr-icon grr-run-icon" src="/static/images/skull-icon.png" />\n        </div>\n      </td>\n      <td><grr-semantic-value value="::item.value.run_id"></grr-semantic-value></td>\n      <td><grr-semantic-value value="::item.value.started_at"></grr-semantic-value></td>\n      <td><grr-semantic-value value="::item.value.finished_at"></grr-semantic-value></td>\n      <td name="log_message">{$ ::item.value.log_message.value $}</grr-semantic-value></td>\n      <td name="backtrace"><span>{$ ::item.value.backtrace.value $}</span></td>\n    </tr>\n  </tbody>\n </table>\n');
$templateCache.put("/cron/cron-job-status-icon.html",'<div class="centered cron-state-icon"\n     ng-init="cronJobState = cronJob.value.enabled.value"\n     state="{$ ::cronJobState $}">\n  <img ng-if="::cronJobState"\n       title="Cron job is enabled."\n       class="grr-icon grr-cronJob-icon" src="/static/images/clock.png" />\n  <img ng-if="::!cronJobState"\n       title="Cron job is disabled."\n       class="grr-icon grr-cronJob-icon" src="/static/images/pause.png" />\n</div>\n');$templateCache.put("/cron/cron-jobs-list.html",
'<ul class="breadcrumb">\n  <li>\n    <div class="btn-group">\n      <button title="Schedule Hunt" class="btn btn-default" name="ScheduleHuntCronJob"\n              ng-click="controller.newCronJob()">\n        <img src="/static/images/new.png" class="toolbar_icon">\n      </button>\n    </div>\n\n    <div class="btn-group">\n      <button title="Enable Cron Job" class="btn btn-default" name="EnableCronJob"\n              ng-click="controller.enableCronJob()"\n              ng-disabled="!controller.selectedCronJobId ||\n                           controller.cronJobsById[controller.selectedCronJobId].value.enabled.value">\n        <img src="/static/images/play_button.png" class="toolbar_icon">\n      </button>\n\n      <button title="Force Run Cron Job" class="btn btn-default" name="ForceRunCronJob"\n              ng-click="controller.forceRunCronJob()"\n              ng-disabled="!controller.selectedCronJobId">\n        <img src="/static/images/play_force_button.png" class="toolbar_icon">\n      </button>\n\n      <button title="Disable Cron Job" class="btn btn-default" name="DisableCronJob"\n              ng-click="controller.disableCronJob()"\n              ng-disabled="!controller.selectedCronJobId ||\n                           !controller.cronJobsById[controller.selectedCronJobId].value.enabled.value">\n        <img src="/static/images/pause_button.png" class="toolbar_icon">\n      </button>\n    </div>\n\n    <div class="btn-group">\n      <button title="Delete Cron Job" class="btn btn-default" name="DeleteCronJob"\n              ng-click="controller.showDeleteCronJobConfirmation()"\n              ng-disabled="!controller.selectedCronJobId">\n        <img src="/static/images/editdelete.png" class="toolbar_icon">\n      </button>\n    </div>\n  </li>\n</ul>\n\n<table class="table table-striped table-condensed table-hover table-bordered full-width">\n  <colgroup>\n    <col style="width: 40px">\n    <col style="width: 10%">\n    <col style="width: 10%">\n    <col style="width: 10%">\n    <col style="width: 70%">\n  </colgroup>\n  <thead>\n    <tr>\n      <th>State</th>\n      <th>Name</th>\n      <th>Last Run</th>\n      <th>Frequency</th>\n      <th>Description</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-infinite-table grr-api-items-provider url="controller.cronUrl" page-size="50"\n        transform-items="controller.transformItems(items)"\n        trigger-update="controller.triggerUpdate"\n        ng-click="controller.selectItem(item)"\n        ng-class="{\'row-selected\': item.value.cron_job_id.value == controller.selectedCronJobId,\n                  \'danger\': item.value.is_failing.value == true,\n                  \'warning\': item.value.is_failing.value != true && item.isStuck == true}">\n      <td><grr-cron-job-status-icon cron-job="::item" /></td>\n      <td>{$ ::item.value.cron_job_id.value $}</td>\n      <td><grr-semantic-value value="::item.value.last_run_time" /></td>\n      <td><grr-semantic-value value="::item.value.frequency" /></td>\n      <td><grr-semantic-value value="::item.value.description" /></td>\n    </tr>\n\n  </tbody>\n</table>\n');
$templateCache.put("/cron/cron-view.html",'<div grr-splitter orientation="horizontal" class="rightSplitterContainer">\n  <div grr-splitter-pane id="content_rightPane" class="rightTopPane">\n    <grr-cron-jobs-list selected-cron-job-id="controller.selectedCronJobId">\n    </grr-cron-jobs-list>\n  </div>\n\n  <div grr-splitter-pane id="main_bottomPane" class="rightBottomPane">\n    <grr-cron-job-inspector cron-job-id="controller.selectedCronJobId">\n    </grr-cron-job-inspector>\n  </div>\n</div>\n');
$templateCache.put("/docs/api-description.html",'<span ng-repeat="paragraph in ::controller.paragraphs">\n  {$ paragraph $}\n  <br ng-if="::!$last"></br>\n</span>\n');$templateCache.put("/docs/api-docs.html",'<div class="container-fluid">\n  <div class="row">\n    <div class="col-md-9">\n      <div class="doc-item">\n        <h1>GRR API</h1>\n      </div>\n\n      <p>\n        Below is the list of HTTP API calls that the GRR Admin UI can handle.\n        For every supported route you\'ll find a list of supported query\n        parameters (if any). These parameters are passed either as URL query\n        parameters or as parts of URL path.<br/>\n        For example:\n      </p>\n      <p>\n        <samp>/api/hunts?<strong>offset=100&amp;count=20</strong></samp><br>\n      </p>\n\n      <br/>\n      <h4>Permissions</h4>\n      <p>\n        If special permissions are required to access certain resources,\n        &quot;reason&quot; query parameter may be specified.\n        For example:</p>\n      <p>\n        <samp>/api/aff4/C.123456789abcdef1/analysis/AnalyzeClientMemory/myusername-1435178456.2?<strong>reason=InvestigationID+1234</strong></samp>\n      </p>\n\n      <br/>\n      <h4>Type information</h4>\n      <p>\n        GRR API responses usually contain richly typed data. If you don\'t need the type information, you can strip it from any response by setting "strip_type_info" flag. For example:\n      </p>\n      <p>\n        <samp>/api/hunts?offset=100&amp;count=20&amp;<strong>strip_type_info=1</strong></samp><br>\n      </p>\n\n      <h4>XSSI protection</h4>\n      <p>\n        To prevent against Cross Site Script Inclusion (XSSI) attacks, the JSON response body starts with a magic prefix line that must be stripped before feeding the rest of the response body to a JSON parser:\n      </p>\n      <p>\n        <samp>)]}\'<br>[ ... valid JSON ... ]</samp><br>\n      </p>\n      <br/>\n\n      <div class="panel panel-default doc-item-category"\n           ng-repeat="category in ::controller.categories">\n\n        <div class="panel-heading" id="docs-category-{$ $index $}">\n          <h2>{$ category $}</h2>\n        </div>\n\n        <div class="panel-body" grr-on-scroll-into-view="controller.visibleCategory = category">\n          <div class="doc-item"\n               ng-repeat="apiMethod in ::controller.apiMethodsByCategory[category]">\n            <p class="lead">\n              {$ ::apiMethod.http_methods.join(\', \') $}\n              <grr-api-route value="::apiMethod.http_route"></grr-api-route>\n            </p>\n\n            <grr-api-description value="::apiMethod.doc"></grr-api-description>\n            <grr-api-query-spec args-type="::apiMethod.args_type_descriptor.name"></grr-api-query-spec>\n\n            <div ng-if="controller.examplesByMethod[apiMethod.name].length > 0">\n              <h4>Examples:</h4>\n\n              <table class="example table table-condensed"\n                     ng-repeat="example in ::controller.examplesByMethod[apiMethod.name]">\n                <thead>\n                  <th>\n                    <grr-api-route value="::example.url"></grr-api-route>\n\n                    <div class="pull-right" ng-if="::example.type_stripped_response !== undefined">\n                      <input ng-model="example.showTypeStripped" type="checkbox">\n                        Show type-stripped response\n                      </input>\n                    </div>\n\n                    <div class="request-payload" ng-if="example.request_payload">\n                      <span class="method-label">{$ ::apiMethod.http_methods.join(\', \') $} body:</span>\n                      <div class="json pre-scrollable">{$ ::example.request_payload | json:2 $}</div>\n                    </div>\n                  </th>\n                </thead>\n                <tbody>\n                  <tr>\n                    <td>\n                      <div class="json pre-scrollable" ng-if="!example.showTypeStripped">{$ ::example.response | json:2 $}</div>\n                      <div class="json pre-scrollable" ng-if="example.showTypeStripped">{$ ::example.type_stripped_response | json:2 $}</div>\n                    </td>\n                  </tr>\n                </tbody>\n              </table>\n            </div>\n\n          </div>\n        </div>\n\n      </div>\n\n    </div>\n    <div class="col-md-3 vertically-padded">\n\n      <div class="list-group doc-toc">\n        <a ng-class="{\'active\': controller.visibleCategory == category}"\n           ng-repeat="category in controller.categories" class="list-group-item"\n           ng-click="controller.onCategoryLinkClick(category)">\n          {$ category $}\n        </a>\n      </ul>\n    </div>\n  </div>  \x3c!-- div class=row --\x3e\n</div>  \x3c!-- div class=container-fluid --\x3e\n');
$templateCache.put("/docs/api-query-spec.html",'<div ng-if="::argsType.length > 0" class="query-parameters">\n  <h4 ng-if="::noHeader === undefined">Parameters</h4>\n\n  <table class="table table-striped table-condensed table-bordered">\n    <thead>\n      <th>Parameter</th>\n      <th>Type</th>\n      <th>Description</th>\n    </thead>\n    <tbody>\n      <tr ng-repeat="field in ::controller.descriptorFields">\n        <td>{$ ::prefix $}{$ ::field.name $}</td>\n        <td>\n          <abbr ng-if="::controller.typeHints[field.type] !== undefined"\n                title="{$ ::controller.typeHints[field.type] $}">\n            {$ ::field.type $}\n          </abbr>\n          <span ng-if="::controller.typeHints[field.type] === undefined">\n            {$ ::field.type $}\n          </span>\n        </td>\n        <td>\n          <grr-api-description value="::field.doc"></grr-api-description>\n          <span ng-if="::field.type == \'EnumNamedValue\'">\n            Possible values:\n            <ul>\n              <li ng-repeat="allowedValue in ::field.allowed_values">\n                {$ ::allowedValue.name $}\n                <span ng-if="::allowedValue.doc.length > 0">\n                  - {$ ::allowedValue.doc $}\n                </span>\n              </li>\n            </ul>\n          </span>\n        </td>\n      </tr>\n    </tbody>\n  </table>\n</div>\n</div>\n');
$templateCache.put("/docs/api-route.html",'<span ng-repeat="component in ::controller.routeComponents"><wbr><span>/</span><strong ng-if="component.type && !controller.fillIns[component.value]">&lt;{$ component.value $}&gt;<span ng-if="component.type === \'path\'">...</span></strong><strong ng-if="component.type && controller.fillIns[component.value]">{$ controller.fillIns[component.value] $}</strong><span ng-if="!component.type">{$ component.value $}</span></span>\x3c!-- query parameters (if any) --\x3e<span ng-if="::controller.hasQueryParameters">?<span ng-repeat="(paramName, paramValue) in ::controller.queryParameters"><strong>{$ ::paramName $}<span ng-if="::paramValue !== null">={$ ::paramValue $}</span></strong><span ng-if="::!$last">&amp;</span><wbr></span>\n');
$templateCache.put("/flow/client-flows-list.html",'<div class="toolbar">\n  <div class="breadcrumb">\n    <li>\n      <button title="Cancel Selected Flows" class="btn btn-default" name="cancel_flow"\n              ng-disabled="!selectedFlowId"\n              ng-click="controller.cancelButtonClicked()">\n        <img src="/static/images/editdelete.png" class="toolbar_icon">\n      </button>\n\n      <button class="btn btn-default" name="copy_flow"\n              title="Copy Flow"\n              ng-disabled="!selectedFlowId"\n              ng-click="controller.copyFlow()">\n        <img src="/static/images/copy.png" class="toolbar-icon" />\n      </button>\n\n      <button title="Create Hunt From Flow" class="btn btn-default" name="create_hunt"\n              ng-disabled="!selectedFlowId"\n              ng-click="controller.createHuntFromFlow()">\n        <i class="fa fa-crosshairs"></i>\n      </button>\n    </li>\n  </div>\n</div>\n\n<div class="fill-parent-with-toolbar">\n  <grr-flows-list flows-url="controller.flowsUrl"\n                  selected-flow-id="selectedFlowId"\n                  trigger-update="controller.triggerUpdate">\n  </grr-flows-list>\n</div>\n');
$templateCache.put("/flow/client-flows-view.html",'<grr-check-client-access client-id="controller.clientId">\n\n  \x3c!-- grr-client-context is used by directives that need to know current client-id to render\n       data. Example: stats/grr-stat-entry-directive.js uses client id to build AFF4 path\n       corresponding to a stat entry. --\x3e\n  <grr-client-context client-id="controller.clientId">\n\n    <div grr-splitter orientation="horizontal" class="rightSplitterContainer">\n      <div grr-splitter-pane id="content_rightPane" class="rightTopPane">\n        <grr-client-flows-list client-id="controller.clientId"\n                               selected-flow-id="controller.selectedFlowId"/>\n      </div>\n\n      <div grr-splitter-pane id="main_bottomPane" class="rightBottomPane">\n        <grr-flow-inspector flow-id="controller.selectedFlowId"\n                            api-base-path="controller.flowApiBasePath"\n                            active-tab="controller.tab" />\n      </div>\n    </div>\n\n  </grr-client-context>\n\n</grr-check-client-access>\n');
$templateCache.put("/flow/copy-flow-form.html",'<div ng-if="!controller.flow">\n  Loading...\n</div>\n\n<grr-confirmation-dialog ng-if="controller.flow"\n                         name="CopyFlowDialog"\n                         title="\'Copy \' + controller.flow.value.name.value + \' flow\'"\n                         proceed="controller.proceed()"\n                         proceed-name="\'Launch!\'"\n                         can-proceed="!controller.flowFormHasErrors">\n\n  <grr-flow-form\n    flow-args="controller.flow.value.args"\n    flow-runner-args="controller.flow.value.runner_args"\n    with-output-plugins="true"\n    has-errors="controller.flowFormHasErrors">\n  </grr-flow-form>\n\n</grr-confirmation-dialog>\n');
$templateCache.put("/flow/flow-api-helper.html",'<p>To start this flow on this client via the API, you can use one of the following options:</p>\n\n<div ng-repeat="(label, result) in controller.result">\n  <p>\n    <strong>{$ label $}</strong>\n    <em ng-if="!result[\'webAuthType\']">(authentication details are omitted)</em>\n\n    <pre>{$ result.data $}</pre>\n  </p>\n\n</div>\n');$templateCache.put("/flow/flow-form.html",'<grr-form-value value="flowArgs"></grr-form-value>\n<hr>\n<grr-form-value value="flowRunnerArgs"></grr-form-value>\n\n<div ng-if="withOutputPlugins && controller.outputPluginsField !== undefined">\n  <hr>\n  <grr-form-proto-repeated-field\n    descriptor="controller.outputPluginDescriptor"\n    field="controller.outputPluginsField"\n    value="flowRunnerArgs.value.output_plugins">\n  </grr-form-proto-repeated-field>\n</div>\n');
$templateCache.put("/flow/flow-info.html",'<div class="padded" ng-if="descriptor.value.name.value">\n\n<h3>{$ descriptor.value.name.value $}</h3>\n<p class="preserve-linebreaks">{$ descriptor.value.doc.value $}</p>\n\n</div>\n\n<div class="padded" ng-if="!descriptor.value.name.value">No flow selected.</span>\n');$templateCache.put("/flow/flow-inspector.html",'<div class="padded" grr-force-refresh refresh-trigger="flowId">\n\n  <div ng-if="!flowId">\n    Please select a flow to see its details here.\n  </div>\n\n  <uib-tabset ng-if="flowId" active="controller.activeTab">\n    <uib-tab heading="Flow Information" index="\'\'">\n      <grr-flow-overview flow-id="flowId" api-base-path="apiBasePath"\n                         ng-if="controller.tabsShown[\'\']" />\n    </uib-tab>\n\n    <uib-tab heading="Requests" index="\'requests\'">\n      <grr-flow-requests flow-id="flowId" api-base-path="apiBasePath"\n                         ng-if="controller.tabsShown[\'requests\']" />\n    </uib-tab>\n\n    <uib-tab heading="Results" index="\'results\'">\n      <grr-flow-results flow-id="flowId" api-base-path="apiBasePath"\n                        ng-if="controller.tabsShown[\'results\']" />\n    </uib-tab>\n\n    <uib-tab heading="Log" index="\'log\'">\n      <grr-flow-log flow-id="flowId" api-base-path="apiBasePath"\n                    ng-if="controller.tabsShown[\'log\']" />\n    </uib-tab>\n\n    <uib-tab heading="API" index="\'api\'">\n      <grr-flow-api-helper flow-id="flowId" api-base-path="apiBasePath"\n                           ng-if="controller.tabsShown[\'api\']" />\n    </uib-tab>\n  </uib-tabset>\n\n</div>\n');
$templateCache.put("/flow/flow-log.html",'<table class="proto-table no-cell-border full-width">\n  <thead>\n    <tr>\n      <th>Age</th>\n      <th>Flow Name</th>\n      <th>Flow Id</th>\n      <th>Message</th>\n    </tr>\n  </thead>\n  <tbody ng-if="controller.logsUrl">\n    <tr grr-paged-filtered-table grr-api-items-provider url="::controller.logsUrl"\n        auto-refresh-interval="::controller.autoRefreshInterval">\n      <td class="table-cell proto_key"><grr-timestamp value="::item.value.timestamp" /></td>\n      <td class="table-cell proto_key"><grr-semantic-value value="::item.value.flow_name" /></td>\n      <td class="table-cell proto_key"><grr-semantic-value value="::item.value.flow_id" /></td>\n      <td class="table-cell proto_key"><grr-semantic-value value="::item.value.log_message" /></td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/flow/flow-overview.html",'<div ng-if="flowId && !controller.flow">\n  Loading...\n</div>\n\n<div ng-if="controller.flow">\n\n  <dl class="dl-horizontal dl-flow">\n    <grr-force-refresh refresh-trigger="controller.flow">\n\n      <div ng-if="::controller.flow.value.internal_error">\n        <br>\n        <dt class="alert-danger danger">Error while Opening</dt>\n        <dd>{$ ::controller.flow.value.internal_error.value $}</dd>\n        <br><br>\n      </div>\n\n      <dt>Name</dt>\n      <dd><grr-semantic-value value="::controller.flow.value.name" /></dd>\n\n      <dt>Flow ID</dt>\n      <dd><grr-semantic-value value="::controller.flow.value.flow_id" /></dd>\n\n      <dt>Creator</dt>\n      <dd><grr-semantic-value value="::controller.flow.value.creator" /></dd>\n\n      <dt>Start Time</dt>\n      <dd><grr-timestamp value="controller.flow.value.started_at" /></dd>\n\n      <dt>Last Active</dt>\n      <dd><grr-timestamp value="controller.flow.value.last_active_at" /></dd>\n\n      <dt>State</dt>\n      <dd><grr-semantic-value value="::controller.flow.value.state" /></dd>\n      <br>\n    </grr-force-refresh>\n\n    \x3c!-- Don\'t auto-refresh arguments since they don\'t change during\n         the lifetime of the flow. --\x3e\n    <dt>Arguments</dt>\n    <dd>\n      <grr-semantic-value value="::controller.flow.value.args"\n                          ng-if="::controller.flow.value.args">\n      </grr-semantic-value>\n      <span ng-if="!controller.flow.value.args">-</span>\n    </dd>\n    <br>\n\n    <dt>Runner Arguments</dt>\n    <dd>\n      <grr-semantic-value value="::controller.flow.value.runner_args"\n                          ng-if="::controller.flow.value.runner_args">\n      </grr-semantic-value>\n      <span ng-if="!controller.flow.value.runner_args">-</span>\n    </dd>\n    <br>\n\n    \x3c!-- As context may be UI-heavy, only update it when it actually\n         changes. --\x3e\n    <grr-force-refresh refresh-trigger="controller.flow.value.context">\n      <dt>Context</dt>\n      <dd>\n        <grr-semantic-value value="::controller.flow.value.context">\n        </grr-semantic-value>\n        <span ng-if="::!controller.flow.value.context">-</span>\n      </dd>\n      <br>\n    </grr-force-refresh>\n\n    \x3c!-- As state may be UI-heavy, only update it when it actually\n         changes. --\x3e\n    <grr-force-refresh refresh-trigger="controller.flow.value.state_data">\n      <dt>State Data</dt>\n      <dd>\n        <grr-semantic-value value="::controller.flow.value.state_data">\n        </grr-semantic-value>\n        <span ng-if="::!controller.flow.value.state_data">-</span>\n      </dd>\n      <br>\n    </grr-force-refresh>\n  </dl>\n\n</div>\n');
$templateCache.put("/flow/flow-requests.html",'<table class="table table-striped table-condensed table-hover table-bordered\n              full-width">\n  <thead>\n    <tr>\n      <th>ID</th>\n      <th>Request</th>\n      <th>Responses</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-infinite-table grr-api-items-provider url="controller.requestsUrl">\n      <td><grr-semantic-value value="::item.value.request_id" /></td>\n      <td><grr-semantic-value value="::item.value.request_state" /></td>\n      <td><grr-semantic-value value="::item.value.responses" /></td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/flow/flow-results.html",'<grr-results-collection\n  results-url="controller.flowResultsUrl"\n  exported-results-url="controller.flowExportedResultsUrl"\n  output-plugins-url="controller.outputPluginsUrl"\n  export-command-url="controller.exportCommandUrl"\n  download-files-url="controller.downloadFilesUrl"\n\n  ng-if= "controller.flowResultsUrl" />\n');$templateCache.put("/flow/flow-status-icon.html",'<div class="centered flow-state-icon"\n     ng-init="flowState = flow.value.state.value"\n     state="{$ ::flowState $}">\n  <img ng-if="::flowState == \'TERMINATED\'"\n       title="Flow finished normally."\n       class="grr-icon grr-flow-icon" src="/static/images/stock_yes.png" />\n  <img ng-if="::flowState == \'RUNNING\'"\n       title="Flow is still running."\n       class="grr-icon grr-flow-icon" src="/static/images/clock.png" />\n  <img ng-if="::flowState == \'ERROR\'"\n       title="Flow terminated with an error."\n       class="grr-icon grr-flow-icon" src="/static/images/nuke.png" />\n  <img ng-if="::flowState == \'CLIENT_CRASHED\'"\n       title="The client crashed while executing this flow."\n       class="grr-icon grr-flow-icon" src="/static/images/skull-icon.png" />\n</div>\n');
$templateCache.put("/flow/flows-list.html",'<table class="table table-striped table-condensed table-hover table-bordered full-width">\n  <colgroup>\n    <col style="width: 40px">\n    <col style="width: 20%">\n    <col style="width: 20%">\n    <col style="width: 20%">\n    <col style="width: 20%">\n    <col style="width: 20%">\n  </colgroup>\n  <thead>\n    <tr>\n      <th>State</th>\n      <th>Path</th>\n      <th>Flow Name</th>\n      <th>Creation Time</th>\n      <th>Last Active</th>\n      <th>Creator</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-infinite-table grr-api-items-provider url="flowsUrl" page-size="controller.pageSize"\n        transform-items="controller.transformItems(items)"\n        trigger-update="controller.triggerTableUpdate"\n        auto-refresh-interval="controller.autoRefreshInterval"\n        ng-click="controller.selectItem(item)"\n        ng-class="{\'row-selected\': item.value.flow_id.value == controller.selectedFlowId}"\n        ng-if="item.shown">\n      <td><grr-flow-status-icon flow="::item" /></td>\n      <td>\n        <span ng-if="::item.expanded === undefined"\n              style="float: left; margin-left: {$ ::item.depth $}em"\n              class="tree_leaf">\n        </span>\n        <span ng-if="::item.expanded !== undefined"\n              ng-class="{\'tree_closed\': !item.expanded, \'tree_opened\': item.expanded}"\n              ng-click="item.expand($event)"\n              style="margin-left: {$ ::item.depth $}em"\n              class="tree_branch">\n        </span>\n        {$ ::item.shortId $}\n      </td>\n      <td>\n        <grr-semantic-value value="::item.value.name" />\n      </td>\n      <td>\n        <grr-semantic-value value="::item.value.started_at" />\n      </td>\n      <td>\n        <grr-semantic-value value="::item.value.last_active_at" />\n      </td>\n      <td>\n        <grr-semantic-value value="::item.value.creator" />\n      </td>\n    </tr>\n\n  </tbody>\n</table>\n');
$templateCache.put("/flow/start-flow-form.html",'<div ng-if="!controller.requestSent">\n\n<div class="context-help">\n  <a href="/help/investigating-with-grr/flows/index.html" target="_blank">\n    <i class="glyphicon glyphicon-question-sign"></i>\n  </a>\n</div>\n\n<div class="padded" ng-if="!descriptor">\nPlease Select a flow to launch from the tree on the left.\n</div>\n\n<div class="padded" ng-if="descriptor">\n\n  <grr-flow-form flow-args="controller.flowArguments"\n                 flow-runner-args="controller.flowRunnerArguments"\n                 with-output-plugins="clientId"\n                 has-errors="controller.flowFormHasErrors">\n  </grr-flow-form>\n\n  <div class="form-group">\n    <div class="col-sm-offset-2 col-sm-3 padded">\n      <button class="btn btn-success Launch"\n              ng-disabled="controller.flowFormHasErrors"\n              ng-click="controller.startClientFlow()">\n        Launch\n      </button>\n    </div>\n  </div>\n\n</div>\n\n</div>\n\n<div class="padded" ng-if="controller.requestSent">\n  <div ng-if="!controller.responseData && !controller.responseError">\n    <uib-progressbar class="progress-striped active" max="100" value="50">\n      Launching flow {$ descriptor[\'value\'][\'name\'][\'value\'] $}...\n    </uib-progressbar>\n  </div>\n\n  <div class="panel panel-default" ng-if="controller.responseData">\n    <div class="panel-body">\n      <p>\n        Launched Flow {$ descriptor[\'value\'][\'name\'][\'value\'] $}:\n      </p>\n      <p>\n        <grr-semantic-value value="controller.responseData"></grr-semantic-value>\n      </p>\n    </div>\n  </div>\n\n  <div class="alert alert-error" ng-if="controller.responseError">\n    <p><em>Can\'t start flow {$ descriptor[\'name\'] $}:</em></p>\n    <p class="preserve-linebreaks">{$ controller.responseError $}</p>\n  </div>\n</div>\n');
$templateCache.put("/flow/start-flow-view.html",'<grr-check-client-access client-id="controller.clientId">\n\n  <grr-flow-descriptors-tree selected-descriptor="controller.selection.flowDescriptor">\n  </grr-flow-descriptors-tree>\n\n  <div grr-splitter orientation="horizontal" class="flow-details">\n\n    <div grr-splitter-pane size="75" id="main_rightTopPane" class="rightTopPane">\n      <grr-start-flow-form client-id="controller.clientId"\n                           descriptor="controller.selection.flowDescriptor" />\n    </div>\n\n    <div grr-splitter-pane size="25" id="main_rightBottomPane" class="rightBottomPane">\n      <grr-flow-info descriptor="controller.selection.flowDescriptor" />\n    </div>\n\n  </div>\n\n</grr-check-client-access>\n');
$templateCache.put("/forms/auto-generated-aes128-key-form.html",'<grr-form-primitive value="value"\n                    metadata="metadata">\n</grr-form-value>\n');$templateCache.put("/forms/bytes-form.html",'<div class="form-group" ng-class="{\'has-error has-feedback\': value.validationError}">\n  <input class="form-control" type="text" ng-model="controller.valueString"></input>\n  <span ng-if="value.validationError"\n        class="glyphicon glyphicon-remove form-control-feedback"\n        aria-hidden="true"></span>\n  <div class="text-danger" ng-if="value.validationError">\n    {$ value.validationError $}\n  </div>\n</div>\n');
$templateCache.put("/forms/client-label-form.html",'<label class="control-label">{{\n  controller.formLabel || \'Client label\'\n}}</label>\n<div class="controls select-label-controls">\n  <select class="form-control"\n          ng-model="controller.clientLabel"\n          ng-options="label.name as label.name\n                      for label in controller.labelsList">\n    <option value="" ng-if="!controller.hideEmptyOption">{{\n      controller.emptyOptionLabel\n    }}</option>\n  </select>\n</div>\n');
$templateCache.put("/forms/datetime-form.html",'<div class="input-group" ng-class="{\'has-error\': controller.isInvalid}">\n\n  <input type="text" class="form-control"\n         ng-model="controller.valueString"\n         placeholder="{$ controller.format $}"></input>\n  <div class="input-group-btn">\n    <button type="button" name="Today" class="btn btn-default"\n            ng-click="controller.today()"><small>Today</small></button>\n  </div>\n\n</div>\n\n<div class="has-error" ng-if="controller.isInvalid">\n  <span class="help-block">\n    Expected format is {$ controller.format $}, i.e. {$ controller.example $}\n  </span>\n</div>\n');
$templateCache.put("/forms/dict-form.html",'<div class="form-group">\n  <button class="btn btn-default add" name="Add"\n          ng-click="controller.addPair()">\n    <i class="glyphicon glyphicon-plus"></i>\n  </button>\n</div>\n\n<div ng-repeat="pair in controller.keyValueList">\n  <button type="button" class="close" name="Remove"\n          ng-click="controller.removePair($index)">&times;</button>\n  <div class="form-group pair">\n      <input class="form-control key" type="text" ng-model="pair.key"></input>\n      <span>=</span>\n      <grr-form-value class="value" value="pair.value"></grr-form-value>\n  </div>\n</div>\n');
$templateCache.put("/forms/duration-form.html",'<div class="input-group" ng-class="{\'has-error\': controller.isInvalid}">\n\n  <input type="text" class="form-control"\n         ng-model="controller.valueString"></input>\n\n</div>\n\n<div class="has-error" ng-if="controller.isInvalid">\n  <span class="help-block">\n    Expected format is [number][unit] where unit may be "s" for seconds, "m" for minutes, "h" for hours, "d" for days or "w" for weeks.\n  </span>\n</div>\n');$templateCache.put("/forms/ext-flags-condition-form.html",
'<dl class="dl-horizontal">\n  <dt>\n    <button type="button" class="btn btn-link"\n         ng-click="controller.linuxPickerShown = !controller.linuxPickerShown">\n      Linux extended flags\n      <i class="glyphicon"\n         ng-class="{ \'glyphicon-chevron-down\': controller.linuxPickerShown, \'glyphicon-chevron-right\': !controller.linuxPickerShown }"></i>\n    </button>\n  </dt>\n  <dd>\n    <grr-ext-flags-linux-picker-short ng-if="controller.linuxPickerShown"\n      bits-set="value.value.linux_bits_set"\n      bits-unset="value.value.linux_bits_unset" />\n    <grr-ext-flags-linux-picker-long ng-if="controller.linuxPickerShown"\n      bits-set="value.value.linux_bits_set"\n      bits-unset="value.value.linux_bits_unset" />\n  </dd>\n  <dt>\n    <button type="button" class="btn btn-link"\n         ng-click="controller.osxPickerShown = !controller.osxPickerShown">\n      macOS extended flags\n      <i class="glyphicon"\n         ng-class="{ \'glyphicon-chevron-down\': controller.osxPickerShown, \'glyphicon-chevron-right\': !controller.osxPickerShown }"></i>\n    </button>\n  </dt>\n  <dd>\n    <grr-ext-flags-osx-picker ng-if="controller.osxPickerShown"\n      bits-set="value.value.osx_bits_set"\n      bits-unset="value.value.osx_bits_unset" />\n  </dd>\n</dl>\n');
$templateCache.put("/forms/ext-flags-linux-picker-long.html",'<form class="form-horizontal">\n  <div ng-repeat="flag in controller.flags.children" class="form-group">\n    <div class="col-md-7">\n      <label for="{$ flag.name $}" class="control-label">\n        {$ flag.description $}\n      </label>\n    </div>\n    <div class="col-md-5">\n      <select id="{$ flag.name $}" ng-model="flag.state" class="form-control">\n        <option value="VOID">ignored</option>\n        <option value="SET">required set</option>\n        <option value="UNSET">required unset</option>\n      </select>\n    </div>\n  </div>\n</div>\n');
$templateCache.put("/forms/ext-flags-linux-picker-short.html",'<div class="col-md-12">\n  <table class="well">\n    <tr>\n      <th ng-repeat="flag in controller.flags.children" title="{$ ::flag.description $}">\n        {$ ::flag.identifier $}\n      </th>\n    </tr>\n    <tr>\n      <td ng-repeat="flag in controller.flags.children">\n        <grr-troggle ng-model="flag.state" />\n      </td>\n    </tr>\n  </table>\n</div>\n');$templateCache.put("/forms/ext-flags-osx-picker.html",'<table>\n  <tr>\n    <th ng-repeat="flag in controller.flags.children">\n      <span class="label label-default" title="{$ flag.description $}">\n        {$ flag.identifier $}\n      </span>\n    </th>\n  </tr>\n  <tr>\n    <td ng-repeat="flag in controller.flags.children">\n      <grr-troggle ng-model="flag.state" />\n    </td>\n  </tr>\n</table>\n');
$templateCache.put("/forms/foreman-label-rule-form.html",'<div class="form-group">\n  <label class="control-label">Match mode</label>\n  <div class="controls">\n    <grr-form-value value="value.value.match_mode"\n                    metadata="controller.matchModeMetadata">\n    </grr-form-value>\n  </div>\n</div>\n\n<div class="form-group">\n  <label class="control-label">Add label</label>\n  <div class="controls">\n    <button class="btn btn-default form-add" ng-click="controller.addLabel()">\n      <i class="glyphicon glyphicon-plus"></i>\n    </button>\n  </div>\n</div>\n\n<div class="form-group" ng-repeat="label_name in value.value.label_names">\n  <grr-form-client-label client-label="label_name.value"\n                         form-label="\'Label name\'"\n                         hide-empty-option="true">\n  </grr-form-client-label>\n  <button type="button" class="close remove-label"\n          ng-click="controller.removeLabel($index)"\n          ng-disabled="value.value.label_names.length <= 1">\u00d7</button>\n</div>\n');
$templateCache.put("/forms/glob-expression-form.html",'<input type="text" class="form-control"\n       ng-model="value.value"\n       placeholder="Type %% for autocompletion..."\n       uib-typeahead="item.expressionWithSuggestion as item.suggestion for item in controller.getSuggestions($viewValue)"\n       typeahead-append-to-body="true"\n       typeahead-template-url="/static/angular-components/core/typeahead-match.html"\n/>\n');$templateCache.put("/forms/glob-expressions-list-form.html",'\x3c!-- no-custom-template=true prevents infinite recursion. --\x3e\n<grr-form-proto-repeated-field ng-if="value"\n  value="value"\n  descriptor="descriptor"\n  field="field"\n  no-custom-template="true">\n</grr-form-proto-repeated-field>\n');
$templateCache.put("/forms/output-plugin-descriptor-form.html",'<div class="well well-large">\n\n  <div class="form-group">\n    <label class="control-label" title="Plugin">\n      Plugin\n    </label>\n    <div class="controls">\n      <select class="form-control" ng-model="value.value.plugin_name.value"\n              ng-options="optionValue as optionValue\n                          for optionValue in controller.allowedPluginsNames">\n      </select>\n    </div>\n  </div>\n\n  <div class="form-group">\n    <grr-form-value value="value.value.plugin_args" />\n  </div>\n\n</div>\n');
$templateCache.put("/forms/semantic-enum-form.html",'<select class="form-control" ng-model="value.value"\n        ng-options="optionValue.value as optionValue.label\n                    for optionValue in controller.allowedOptions">\n</select>\n');$templateCache.put("/forms/semantic-primitive-form.html",'<span ng-if="controller.valueType">\n  <input ng-if="controller.valueType == \'RDFBool\' ||\n                controller.valueType == \'bool\'" class="form-control"\n         type="checkbox" ng-model="value.value" />\n\n  <input ng-if="controller.valueType == \'RDFInteger\' ||\n                controller.valueType == \'int\' ||\n                controller.valueType == \'long\' ||\n                controller.valueType == \'float\'" class="form-control"\n         type="number" ng-model="value.value" />\n\n  <input ng-if="controller.valueType == \'RDFString\' ||\n                controller.valueType == \'basestring\' ||\n                controller.valueType == \'str\' ||\n                controller.valueType == \'unicode\' ||\n                controller.valueType == \'RDFURN\'" class="form-control"\n         type="text" ng-model="value.value" />\n\n  <input ng-if="controller.valueType == \'RDFBytes\' ||\n                controller.valueType == \'bytes\'" class="form-control"\n         type="text" ng-model="value.value" />\n</span>\n');
$templateCache.put("/forms/semantic-proto-form.html",'<div ng-if="controller.valueDescriptor.union_field">\n  <grr-form-proto-union value="controller.editedValue"\n                        descriptor="controller.valueDescriptor" />\n</div>\n\n<div ng-if="!controller.valueDescriptor.union_field">\n  <div class="form-group" ng-if="metadata.depth >= 2">\n    <i class="nested-icon glyphicon" ng-click="controller.expanded = !controller.expanded"\n       ng-class="{\'glyphicon-plus\': !controller.expanded, \'glyphicon-minus\': controller.expanded}"></i>\n  </div>\n\n  <div ng-if="(metadata.depth === undefined || metadata.depth < 2 || controller.expanded)">\n\n    <div ng-repeat="field in controller.valueDescriptor.fields |\n                    filter:controller.regularFieldsOnly |\n                    filter:controller.boundNotExplicitlyHiddenFields">\n      <grr-form-proto-single-field value="controller.editedValue.value[field.name]"\n                                   field="field"\n                                   ng-if="!field.repeated">\n      </grr-form-proto-single-field>\n\n      <grr-form-proto-repeated-field value="controller.editedValue.value[field.name]"\n                                     descriptor="controller.descriptors[field.type]"\n                                     field="field"\n                                     ng-if="field.repeated">\n      </grr-form-proto-repeated-field>\n    </div>\n\n    <div ng-if="controller.hasAdvancedFields">\n      <div>\n        <label class="control-label">\n          <a class="advanced-label"\n             ng-click="controller.advancedShown = !controller.advancedShown">\n            Advanced\n          </a>\n          <i class="advanced-icon glyphicon"\n             ng-class="{\'glyphicon-chevron-right\': !controller.advancedShown,\n                       \'glyphicon-chevron-down\': controller.advancedShown}"></i>\n        </label>\n      </div>\n      <div class="clearfix"></div>\n\n      <div class="advanced-controls" ng-show="controller.advancedShown">\n        <div ng-repeat="field in controller.valueDescriptor.fields |\n                        filter:controller.advancedFieldsOnly |\n                        filter:controller.boundNotExplicitlyHiddenFields">\n          <grr-form-proto-single-field value="controller.editedValue.value[field.name]"\n                                       field="field"\n                                       ng-if="!field.repeated">\n          </grr-form-proto-single-field>\n\n          <grr-form-proto-repeated-field value="controller.editedValue.value[field.name]"\n                                         descriptor="controller.descriptors[field.type]"\n                                         field="field"\n                                         ng-if="field.repeated">\n          </grr-form-proto-repeated-field>\n        </div>\n      </div>\n    </div>\n    <div class="clearfix"></div>\n\n  </div>\n\n</div>\n');
$templateCache.put("/forms/semantic-proto-repeated-field-form.html",'<div ng-if="controller.hasCustomTemplate === false">\n  <div class="form-group">\n    <label class="control-label" title="{$ field.doc $}">\n      {$ field.friendly_name $}\n      <a ng-if="field.context_help_url"\n         ng-href="/help/{$ field.context_help_url $}" target="_blank">\n        <i class="glyphicon glyphicon-question-sign"></i>\n      </a>\n    </label>\n\n    <div class="controls">\n      <button class="btn btn-default form-add" name="Add"\n              ng-click="controller.addItem()">\n        <i class="glyphicon glyphicon-plus"></i>\n      </button>\n    </div>\n  </div>\n\n  <div ng-repeat="item in value">\n    <button type="button" class="control-label close" name="Remove"\n            ng-click="controller.removeItem($index)">&times;</button>\n    <div class="controls">\n      <div class="form-group">\n        <grr-form-value value="item" metadata="field"></grr-form-value>\n      </div>\n    </div>\n  </div>\n</div>\n\n<div ng-show="controller.hasCustomTemplate === true && !controller.hideCustomTemplateLabel">\n  <div class="form-group">\n    <label class="control-label" title="{$ field.doc $}">\n      {$ field.friendly_name $}\n      <a ng-if="field.context_help_url"\n         ng-href="/help/{$ field.context_help_url $}" target="_blank">\n        <i class="glyphicon glyphicon-question-sign"></i>\n      </a>\n    </label>\n  </div>\n\n  <div class="controls">\n    <div class="form-group" name="custom-template">\n      \x3c!-- custom template will be inserted here if it\'s available --\x3e\n    </div>\n  </div>\n</div>\n\n<div ng-show="controller.hasCustomTemplate === true && controller.hideCustomTemplateLabel">\n  <div class="form-group" name="custom-template-without-label">\n    \x3c!-- custom template occupying the full form row (without a standard form label)\n         will be inserted here if it\'s available --\x3e\n  </div>\n</div>\n');
$templateCache.put("/forms/semantic-proto-single-field-form.html",'<div class="form-group">\n  <label class="control-label" title="{$ field.doc $}">\n    {$ field.friendly_name $}\n    <a ng-if="field.context_help_url"\n       ng-href="/help/{$ field.context_help_url $}" target="_blank">\n      <i class="glyphicon glyphicon-question-sign"></i>\n    </a>\n  </label>\n  <div class="controls">\n    <grr-form-value value="value" metadata="field" />\n  </div>\n</div>\n');$templateCache.put("/forms/semantic-proto-union-form.html",
'<div class="well well-large">\n\n  <div class="form-group">\n    <label class="control-label" title="{$ controller.unionField.doc $}">\n      {$ controller.unionField.friendly_name $}\n    </label>\n    <div class="controls">\n      <grr-form-value value="value.value[controller.unionField.name]"\n                      metadata="controller.unionField" />\n    </div>\n  </div>\n\n  <div class="form-group">\n    <grr-form-value value="value.value[controller.unionFieldValue]" />\n  </div>\n\n</div>\n');
$templateCache.put("/forms/timerange-form.html",'<label class="control-label">{{\n  controller.startTimeLabel || \'Time range start time\'\n}}</label>\n<div class="controls">\n  <grr-form-value value="controller.formStartTime"></grr-form-value>\n</div>\n\n<label class="control-label">{{\n  controller.durationLabel || \'Time range duration\'\n}}</label>\n<div class="controls">\n  <grr-form-value value="controller.formDuration"></grr-form-value>\n</div>\n');$templateCache.put("/hunt/hunt-clients.html",
'<div class="pull-right horizontally-padded">\n  <div class="btn-group">\n    <label class="btn btn-default" name="ShowOutstandingClients"\n           ng-model="controller.clientType" uib-btn-radio="\'outstanding\'">\n      Outstanding\n    </label>\n    <label class="btn btn-default" name="ShowCompletedClients"\n           ng-model="controller.clientType" uib-btn-radio="\'completed\'">\n      Completed\n    </label>\n  </div>\n</div>\n<div class="padded clearfix"></div>\n\n<grr-force-refresh refresh-trigger="controller.huntClientsUrl">\n\n  <table class="table table-striped table-condensed table-bordered full-width">\n    <thead>\n      <tr>\n        <th>Client</th>\n        <th>Flow</th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr grr-infinite-table grr-api-items-provider\n          url="::controller.huntClientsUrl">\n        <td><grr-semantic-value value="::item.value.client_id" /></td>\n        <td>\n          <a ui-sref="client.flows(::{clientId: item.value.client_id.value,\n                      flowId: item.value.flow_id.value})">\n            {$ ::item.value.flow_id.value $}\n          </a>\n        </td>\n      </tr>\n    </tbody>\n  </table>\n\n</grr-force-refresh>\n');
$templateCache.put("/hunt/hunt-context.html",'<grr-semantic-value value="::controller.runner_args"></grr-semantic-value>\n<grr-semantic-value value="::controller.args"></grr-semantic-value>\n<grr-semantic-value value="::controller.context"></grr-semantic-value>\n<grr-semantic-value value="::controller.state"></grr-semantic-value>\n');$templateCache.put("/hunt/hunt-crashes.html",'<table class="table table-striped table-condensed table-bordered full-width">\n  <thead>\n    <tr>\n      <th>Client</th>\n      <th>Crash Details</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-paged-filtered-table grr-api-items-provider url="::controller.crashesUrl"\n        auto-refresh-interval="::controller.autoRefreshInterval">\n      <td ng-class="::{proto_key: $index % 2 == 0}">\n        <grr-client-urn value="::item.value.client_id.value" />\n      </td>\n      <td ng-class="::{proto_key: $index % 2 == 0}">\n        <dl class="dl-horizontal">\n\n          <dt>Timestamp</dt>\n          <dd><grr-timestamp value="::item.value.timestamp" /></dd>\n\n          <dt>Crash Type</dt>\n          <dd><grr-semantic-value value="::item.value.crash_type" /> </dd>\n\n          <div ng-if="::item.value.crash_message !== undefined">\n            <dt>Crash Message</dt><dd><grr-semantic-value value="::item.value.crash_message" />\n          </div>\n\n          <div ng-if="::item.value.backtrace !== undefined">\n            <dt>Backtrace</dt><dd><grr-semantic-value value="::item.value.backtrace" />\n          </div>\n\n          <div ng-if="::item.value.session_id !== undefined">\n            <dt>Session Id</dt><dd><grr-semantic-value value="::item.value.session_id" /></dd>\n          </div>\n\n          <dt>Client Information</dt>\n          <dd><grr-semantic-value value="::item.value.client_info" /></dd>\n        </dl>\n      </td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/hunt/hunt-errors.html",'<table class="proto-table no-cell-border full-width">\n  <thead>\n    <tr>\n      <th>Age</th>\n      <th>Client</th>\n      <th>Backtrace</th>\n      <th>Message</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-paged-filtered-table grr-api-items-provider url="::controller.errorsUrl"\n        auto-refresh-interval="::controller.autoRefreshInterval">\n      <td ng-class="::{proto_key: $index % 2 == 0}"><grr-timestamp value="::item.value.timestamp" /></td>\n      <td ng-class="::{proto_key: $index % 2 == 0}"><grr-client-urn value="::item.value.client_id" /></td>\n      <td ng-class="::{proto_key: $index % 2 == 0}">{$ ::item.value.backtrace.value $}</td>\n      <td ng-class="::{proto_key: $index % 2 == 0}">{$ ::item.value.log_message.value $}</td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/hunt/hunt-graph.html",'<div class="fill-parent" ng-class="{\'invisible\': !controller.inProgress}">\n    Loading...\n</div>\n\n<div class="fill-parent" ng-class="{\'invisible\': controller.inProgress || controller.informationAvailable}">\n  No data to graph yet.\n</div>\n\n<div class="fill-parent client-completion-graph"\n     ng-class="{\'invisible\': controller.inProgress || !controller.informationAvailable}">\n</div>\n');$templateCache.put("/hunt/hunt-inspector.html",'<div class="padded">\n\n  <div ng-if="!huntId">\n    Please select a hunt to see its details here.\n  </div>\n\n  <uib-tabset ng-if="huntId && huntId === controller.shownHuntId"\n              active="controller.activeTab">\n    <uib-tab heading="Overview" index="\'\'">\n      <grr-hunt-overview hunt-id="huntId" ng-if="controller.tabsShown[\'\']">\n      </grr-hunt-overview>\n    </uib-tab>\n\n    <uib-tab heading="Log" index="\'log\'">\n      <grr-hunt-log hunt-id="huntId" ng-if="controller.tabsShown[\'log\']">\n      </grr-hunt-log>\n    </uib-tab>\n\n    <uib-tab heading="Errors" index="\'errors\'">\n      <grr-hunt-errors hunt-id="huntId" ng-if="controller.tabsShown[\'errors\']">\n      </grr-hunt-errors>\n    </uib-tab>\n\n    <uib-tab heading="Graph" index="\'hunt-graph\'">\n      <grr-hunt-graph hunt-id="huntId" ng-if="controller.tabsShown[\'hunt-graph\']">\n      </grr-hunt-graph>\n    </uib-tab>\n\n    <uib-tab heading="Results" index="\'results\'">\n      <grr-hunt-results hunt-id="huntId" ng-if="controller.tabsShown[\'results\']">\n      </grr-hunt-results>\n    </uib-tab>\n\n    <uib-tab heading="Stats" index="\'stats\'">\n      <grr-hunt-stats hunt-id="huntId" ng-if="controller.tabsShown[\'stats\']">\n      </grr-hunt-stats>\n    </uib-tab>\n\n    <uib-tab heading="Crashes" index="\'crashes\'">\n      <grr-hunt-crashes hunt-id="huntId" ng-if="controller.tabsShown[\'crashes\']">\n      </grr-hunt-crashes>\n    </uib-tab>\n\n    <uib-tab heading="Clients" index="\'clients\'">\n      <grr-hunt-clients hunt-id="huntId" ng-if="controller.tabsShown[\'clients\']">\n      </grr-hunt-clients>\n    </uib-tab>\n\n    <uib-tab heading="Context Details" index="\'context-details\'">\n      <grr-hunt-context hunt-id="huntId" ng-if="controller.tabsShown[\'context-details\']">\n      </grr-hunt-context>\n    </uib-tab>\n  </uib-tabset>\n\n</div>\n');
$templateCache.put("/hunt/hunt-log.html",'<table class="proto-table no-cell-border full-width">\n  <thead>\n    <tr>\n      <th>Age</th>\n      <th>Client</th>\n      <th>Flow Id</th>\n      <th>Flow Name</th>\n      <th>Message</th>\n    </tr>\n  </thead>\n  <tbody>\n    <tr grr-paged-filtered-table page-size="100"\n        grr-api-items-provider url="::controller.logsUrl"\n        transform-items="controller.transformItems(items)"\n        auto-refresh-interval="::controller.autoRefreshInterval">\n      <td ng-class="::{proto_key: item.highlighted}"><grr-timestamp value="::item.value.timestamp" /></td>\n      <td ng-class="::{proto_key: item.highlighted}"><grr-client-urn value="::item.value.client_id" /></td>\n      <td ng-class="::{proto_key: item.highlighted}">\n        <grr-client-context client-id="item.value.client_id.value">\n          <grr-flow-id value="item.value.flow_id" />\n        </grr-client-context>\n      </td>\n      <td ng-class="::{proto_key: item.highlighted}">{$ ::item.value.flow_name.value $}</td>\n      <td ng-class="::{proto_key: item.highlighted}">{$ ::item.value.log_message.value $}</td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/hunt/hunt-overview.html",'<div ng-if="huntId && !controller.hunt">\n  Loading...\n</div>\n\n<div ng-if="controller.hunt">\n\n  <dl class="dl-horizontal dl-hunt">\n\n    <grr-force-refresh refresh-trigger="controller.hunt">\n\n      <div ng-if="::controller.hunt.value.internal_error">\n        <br>\n        <dt class="alert-danger danger">Error while Opening</dt>\n        <dd>{$ ::controller.hunt.value.internal_error.value $}</dd>\n        <br><br>\n      </div>\n\n      <dt>Name</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.name" /></dd>\n\n      <dt>Description</dt>\n      <dd>{$ ::controller.hunt.value.description.value $}</dd>\n\n      <dt>Hunt ID</dt>\n      <dd>{$ ::controller.huntId $}</dd>\n\n      <dt>Creator</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.creator" /></dd>\n\n      <dt>Creation time</dt>\n      <dd><grr-timestamp value="controller.hunt.value.created" /></dd>\n\n      <dt>Start time (initial)</dt>\n      <dd ng-if="::!controller.hunt.value.init_start_time">-</dd>\n      <dd ng-if="::controller.hunt.value.init_start_time">\n        <grr-timestamp value="controller.hunt.value.init_start_time"></grr-timestamp>\n      </dd>\n\n      <dt>Start time (last)</dt>\n      <dd ng-if="::!controller.hunt.value.last_start_time">-</dd>\n      <dd ng-if="::controller.hunt.value.last_start_time">\n        <grr-timestamp value="controller.hunt.value.last_start_time"></grr-timestamp>\n      </dd>\n\n      <dt>Duration</dt>\n      <dd><grr-duration value="controller.hunt.value.duration" /></dd>\n\n      <dt>Expiration time</dt>\n      <dd ng-if="::!controller.huntExpirationTime">-</dd>\n      <dd ng-if="::controller.huntExpirationTime">\n        <grr-timestamp value="controller.huntExpirationTime"></grr-timestamp>\n      </dd>\n\n      <dt>Crash Limit</dt>\n      <dd ng-if="::!controller.hunt.value.crash_limit">-</dd>\n      <dd ng-if="::controller.hunt.value.crash_limit">\n        <grr-semantic-value value="::controller.hunt.value.crash_limit" />\n      </dd>\n\n      <dt>Client Limit</dt>\n      <dd ng-if="::!controller.hunt.value.client_limit">-</dd>\n      <dd ng-if="::controller.hunt.value.client_limit">\n        <grr-semantic-value value="::controller.hunt.value.client_limit" />\n      </dd>\n\n      <dt>Client Rate (clients/min)</dt>\n      <dd ng-if="::!controller.hunt.value.client_rate">-</dd>\n      <dd ng-if="::controller.hunt.value.client_rate">\n        <grr-semantic-value value="::controller.hunt.value.client_rate" />\n\n        <span ng-if="::controller.hunt.value.client_rate.value === 0">\n          (<grr-rapid-hunt-status flow-name="::controller.hunt.value.flow_name.value"\n                                  flow-args="::controller.hunt.value.flow_args"\n                                  client-rate="::controller.hunt.value.client_rate.value">\n          </grr-rapid-hunt-status>)\n        </span>\n      </dd>\n      <br>\n\n      <dt>Status</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.state" /></dd>\n\n      <dt>Clients Queued</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.clients_queued_count" /></dd>\n\n      <dt>Clients Scheduled</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.all_clients_count" /></dd>\n\n      <dt>Clients Outstanding</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.remaining_clients_count" /></dd>\n\n      <dt>Clients Completed</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.completed_clients_count" /></dd>\n\n      <dt>Clients with Results</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.clients_with_results_count" /></dd>\n\n      <dt>Results</dt>\n      <dd><grr-semantic-value value="::controller.hunt.value.results_count" /></dd>\n\n      <dt>Total CPU Time Used</dt>\n      <dd><grr-exact-duration value="::controller.hunt.value.total_cpu_usage" /></dd>\n\n      <dt>Total Network Traffic</dt>\n      <dd><grr-byte-size value="::controller.hunt.value.total_net_usage" /></dd>\n      <br>\n    </grr-force-refresh>\n\n    \x3c!-- Don\'t auto-refresh hunt arguments since they can\'t be changed after the\n         hunt object is created. --\x3e\n    <dt>Flow Name</dt>\n    <dd><grr-semantic-value value="::controller.hunt.value.flow_name" /></dd>\n\n    <dt>Flow Arguments</dt>\n    <dd><grr-semantic-value value="::controller.hunt.value.flow_args" /></dd>\n    <br>\n\n\n    <span ng-if="::controller.hunt.value.client_rule_set">\n      <dt>Client Rule Set</dt>\n      <dd>\n        <grr-semantic-value value="::controller.hunt.value.client_rule_set" />\n      </dd>\n    </span>\n    <br>\n\n\n    <span ng-if="::controller.hunt.value.hunt_runner_args.value.output_plugins">\n      <dt>Output Plugins</dt>\n      <dd>\n        <grr-semantic-value value="::controller.hunt.value.hunt_runner_args.value.output_plugins" />\n      </dd>\n    </span>\n\n  </dl>\n\n</div>\n');
$templateCache.put("/hunt/hunt-results.html",'<grr-results-collection\n  results-url="controller.resultsUrl"\n  exported-results-url="controller.exportedResultsUrl"\n  output-plugins-url="controller.outputPluginsUrl"\n  download-files-url="controller.downloadFilesUrl"\n  export-command-url="controller.exportCommandUrl"\n  transform-items="controller.transformItems(items)"\n\n  ng-if= "controller.resultsUrl"/>\n');$templateCache.put("/hunt/hunt-stats.html",'<h3>Total number of clients: {$ ::controller.totalClientCount $}</h3>\n\n<h3>User CPU seconds</h3>\n<dl class="dl-horizontal">\n  <dt>User CPU mean</dt>\n  <dd>{$ ::controller.userCpuStats.mean | number:1 $}</dd>\n\n  <dt>User CPU stdev</dt>\n  <dd>{$ ::controller.userCpuStats.stdev | number:1 $}</dd>\n\n  <dt>Clients Histogram</dt>\n  <dd class="histogram">\n    <grr-comparison-chart typed-data="controller.userCpuStats"\n                          preserve-order="true">\n    </grr-comparison-chart>\n  </dd>\n</dl>\n\n<h3>System CPU seconds</h3>\n<dl class="dl-horizontal">\n  <dt>System CPU mean</dt>\n  <dd>{$ ::controller.systemCpuStats.mean | number:1 $}</dd>\n\n  <dt>System CPU stdev</dt>\n  <dd>{$ ::controller.systemCpuStats.stdev | number:1 $}</dd>\n\n  <dt>Clients Histogram</dt>\n  <dd class="histogram">\n    <grr-comparison-chart typed-data="controller.systemCpuStats"\n                          preserve-order="true">\n    </grr-comparison-chart>\n  </dd>\n</dl>\n\n<h3>Network bytes sent</h3>\n<dl class="dl-horizontal">\n  <dt>Network bytes sent mean</dt>\n  <dd>{$ ::controller.networkBytesStats.mean | number:1 $}</dd>\n\n  <dt>Network bytes sent stdev</dt>\n  <dd>{$ ::controller.networkBytesStats.stdev | number:1 $}</dd>\n\n  <dt>Clients Histogram</dt>\n  <dd class="histogram">\n    <grr-comparison-chart typed-data="controller.networkBytesStats"\n                          preserve-order="true">\n    </grr-comparison-chart>\n  </dd>\n</dl>\n\n<h3>Worst performers</h3>\n<table class="table table-condensed table-striped table-bordered">\n  <thead>\n    <th>Client Id</th>\n    <th>User CPU seconds</th>\n    <th>System CPU seconds</th>\n    <th>Network bytes sent</th>\n  </thead>\n  <tbody>\n    <tr ng-repeat="client in controller.stats.value.worst_performers">\n      <td><grr-semantic-value value="client.value.client_id"></grr-semantic-value></td>\n      <td>{$ ::client.value.cpu_usage.value.user_cpu_time.value | number:1 $}</td>\n      <td>{$ ::client.value.cpu_usage.value.system_cpu_time.value | number:1 $}</td>\n      <td>{$ ::client.value.network_bytes_sent.value $}</td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/hunt/hunt-status-icon.html",'<div class="centered hunt-state-icon" state="{$ ::hunt.value.state.value $}">\n  <img ng-if="::hunt.value.state.value == \'STOPPED\'"\n       class="grr-icon grr-flow-icon" src="/static/images/stop.png" />\n  <img ng-if="::hunt.value.state.value == \'STARTED\'"\n       class="grr-icon grr-flow-icon" src="/static/images/clock.png" />\n  <img ng-if="::hunt.value.state.value == \'PAUSED\'"\n       class="grr-icon grr-flow-icon" src="/static/images/pause.png" />\n  <img ng-if="::hunt.value.state.value == \'COMPLETED\'"\n       class="grr-icon grr-flow-icon" src="/static/images/stock_yes.png" />\n</div>\n');
$templateCache.put("/hunt/hunts-list.html",'<div class="toolbar">\n  <ul class="breadcrumb">\n    <li>\n      <button class="btn btn-default" name="NewHunt"\n              title="New Hunt" ng-click="controller.newHunt()">\n        <img src="/static/images/new.png" class="toolbar-icon" />\n      </button>\n\n      <div class="btn-group">\n        <button class="btn btn-default" name="RunHunt"\n                title="Run Hunt"\n                ng-disabled="controller.huntsById[selectedHuntId].value.state.value != \'PAUSED\' &&\n                             controller.huntsById[selectedHuntId].value.state.value != \'STOPPED\'"\n                ng-click="controller.runHunt()">\n          <img src="/static/images/play_button.png" class="toolbar-icon" />\n        </button>\n\n        <button class="btn btn-default" name="StopHunt"\n                title="Stop Hunt"\n                ng-disabled="controller.huntsById[selectedHuntId].value.state.value != \'STARTED\'"\n                ng-click="controller.stopHunt()">\n          <img src="/static/images/stop_button.png" class="toolbar-icon" />\n        </button>\n      </div>\n\n      <div class="btn-group">\n        <button class="btn btn-default" name="ModifyHunt"\n                title="Modify Hunt"\n                ng-disabled="controller.huntsById[selectedHuntId].value.state.value != \'PAUSED\' &&\n                             controller.huntsById[selectedHuntId].value.state.value != \'STOPPED\'"\n                ng-click="controller.modifyHunt()">\n          <img src="/static/images/modify.png" class="toolbar-icon" />\n        </button>\n\n        <button class="btn btn-default" name="CopyHunt"\n                title="Copy Hunt"\n                ng-disabled="!selectedHuntId"\n                ng-click="controller.copyHunt()">\n          <img src="/static/images/copy.png" class="toolbar-icon" />\n        </button>\n\n        <button class="btn btn-default" name="DeleteHunt"\n                title="Delete Hunt"\n                ng-disabled="controller.huntsById[selectedHuntId].value.state.value != \'PAUSED\' &&\n                             controller.huntsById[selectedHuntId].value.state.value != \'STOPPED\'"\n                ng-click="controller.deleteHunt()">\n          <img src="/static/images/editdelete.png" class="toolbar-icon" />\n        </button>\n      </div>\n\n      <div class="btn-group">\n        <button class="btn btn-default" name="ToggleRobotHuntDisplay"\n                title="Show/Hide Automated hunts" uib-btn-checkbox\n                ng-model="controller.showRobotHunts">\n          <img src="/static/images/robot.png" class="toolbar-icon" />\n        </button>\n        <a href="/help/investigating-with-grr/hunts/controlling-hunts.html" target="_blank"\n          class="pull-right">\n          <i class="glyphicon glyphicon-question-sign input-append"></i>\n        </a>\n      </div>\n    </li>\n  </ul>\n</div>\n\n<div class="fill-parent-with-toolbar">\n  <table class="table table-striped table-condensed table-hover table-bordered full-width">\n    <colgroup>\n      <col />\n      <col />\n      <col />\n      <col />\n      <col />\n      <col />\n      <col />\n      <col />\n      <col width="100%" />\n    </colgroup>\n    <thead>\n      <tr>\n        <th>Status</th>\n        <th>Hunt ID</th>\n        <th>Creation time</th>\n        <th>Start Time</th>\n        <th>Duration</th>\n        <th>Expiration time</th>\n        <th>Client Limit</th>\n        <th>Creator</th>\n        <th>Description</th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr grr-infinite-table page-size="100"\n          grr-api-items-provider url="controller.huntsUrl"\n          transform-items="controller.transformItems(items)" trigger-update="controller.triggerUpdate"\n          ng-click="controller.selectItem(item)"\n          ng-class="{\'row-selected\': item.value.hunt_id.value == selectedHuntId, \'warning\': item.value.is_robot.value}"\n          ng-show="controller.showRobotHunts || !item.value.is_robot.value">\n\n        <td><grr-hunt-status-icon hunt="::item" /></td>\n        <td>{$ ::item.value.hunt_id.value $}</td>\n        <td><grr-timestamp value="::item.value.created" /></td>\n        <td><grr-timestamp value="::item.value.last_start_time" /></td>\n        <td><grr-duration value="::item.value.duration" /></td>\n        <td><grr-timestamp value="::item.value.expiration_time" /></td>\n        <td>{$ ::item.value.client_limit.value $}</td>\n        <td>{$ ::item.value.creator.value $}</td>\n        <td>{$ ::item.value.description.value $}</td>\n      </tr>\n    </tbody>\n  </table>\n</div>\n');
$templateCache.put("/hunt/hunts-view.html",'<div grr-splitter orientation="horizontal" class="rightSplitterContainer">\n  <div grr-splitter-pane id="content_rightPane" class="rightTopPane">\n    <grr-hunts-list selected-hunt-id="controller.selectedHuntId" />\n  </div>\n\n  <div grr-splitter-pane id="main_bottomPane" class="rightBottomPane">\n    <grr-hunt-inspector hunt-id="controller.selectedHuntId"\n                        active-tab="controller.tab" />\n  </div>\n</div>\n');$templateCache.put("/hunt/modify-hunt-dialog.html",
'<grr-confirmation-dialog name="ModifyHuntDialog"\n                         title="\'Modify this hunt\'"\n                         proceed="controller.proceed()"\n                         proceed-name="\'Modify!\'"\n                         can-proceed="controller.argsObj">\n\n\n  <grr-form-proto ng-if="controller.argsObj"\n                  value="controller.argsObj"\n                  visible-fields="[\'client_limit\', \'client_rate\', \'duration\']">\n  </grr-form-proto>\n\n  <div ng-if="!controller.argsObj">\n    <i class="fa fa-spinner fa-spin fa-fw"></i> Loading...\n  </div>\n\n</grr-confirmation-dialog>\n');
$templateCache.put("/hunt/rapid-hunt-status.html",'<span ng-if="controller.enabled">\n  <span ng-if="controller.isEligible" class="text-success">\n    <strong>This hunt is eligible for rapid hunting.\n      <span ng-if="clientRate === 0">Client rate set to 0.</span>\n    </strong>\n  </span>\n\n  <span ng-if="!controller.isEligible">\n    <em>This hunt is not eligible for rapid hunting.</em>\n  </span>\n\n  <a ng-href="/help/investigating-with-grr/hunts/rapid-hunts.html" target="_blank">\n    <i class="glyphicon glyphicon-question-sign"></i>\n  </a>\n</span>\n');
$templateCache.put("/output-plugins/output-plugin-logs-modal.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h3 class="modal-title">Inspect {$ label $}</h3>\n</div>\n<div class="modal-body">\n  <div class="padded">\n\n    <table class="table table-striped table-condensed table-hover table-bordered full-width">\n      <thead>\n        <tr>\n          <th>Time</th>\n          <th>Status</th>\n          <th>Summary</th>\n          <th>Batch size</th>\n          <th>Batch index</th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr grr-paged-filtered-table grr-api-items-provider url="url">\n          <td><grr-timestamp value="::item.age" /></td>\n          <td><grr-semantic-value value="::item.value.status" /></td>\n          <td><grr-semantic-value value="::item.value.summary" /></td>\n          <td><grr-semantic-value value="::item.value.batch_size" /></td>\n          <td><grr-semantic-value value="::item.value.batch_index" /></td>\n        </tr>\n      </tbody>\n    </table>\n\n  </div>\n</div>\n<div class="modal-footer">\n  <button class="btn btn-default" ng-click="$dismiss()" name="Close">\n    Close\n  </button>\n</div>\n');
$templateCache.put("/output-plugins/output-plugin-logs.html",'<span ng-if="controller.itemsCount > 0">\n\n  <span class="label cursor-pointer" ng-class="cssClass" ng-click="controller.onClick()">\n    <span ng-if="icon" ng-class="icon"\n          class="glyphicon" aria-hidden="true">\n    </span>\n    {$ controller.itemsCount $} {$ label $}\n  </span>\n\n</span>\n');$templateCache.put("/output-plugins/output-plugin-note.html",'<div class="panel panel-default">\n  <div class="panel-heading">\n    {$ controller.pluginTitle $}\n    <div class="pull-right">\n      <grr-output-plugin-logs url="controller.pluginLogsUrl"\n                              label="logs"\n                              css-class="label-default">\n      </grr-output-plugin-logs>\n      &nbsp;\n      <grr-output-plugin-logs url="controller.pluginErrorsUrl"\n                              label="errors"\n                              css-class="label-danger"\n                              icon="glyphicon-exclamation-mark">\n      </grr-output-plugin-logs>\n    </div>\n  </div>\n  <div class="panel-body">\n    <grr-output-plugin-note-body output-plugin="outputPlugin" />\n  </div>\n</div>\n');
$templateCache.put("/output-plugins/output-plugins-notes.html",'<div ng-repeat="outputPlugin in controller.outputPlugins">\n  <grr-output-plugin-note output-plugin="outputPlugin"\n                          output-plugins-url="outputPluginsUrl">\n  </grr-output-plugin-note>\n</div>\n<div class="alert alert-error" ng-if="controller.error">\n  <em>Can\'t fetch output plugins list: {$ controller.error $}.</em>\n</div>\n');$templateCache.put("/semantic/api-hunt-result.html",'<grr-client-context client-id="::value.value.client_id.value">\n  <grr-semantic-proto value="::value"><grr-semantic-proto>\n</grr-client-context>\n');
$templateCache.put("/semantic/byte-size.html",'<span ng-if="::controller.stringifiedByteSize !== undefined"\n      title="{$ ::value.value $} bytes">\n  {$ ::controller.stringifiedByteSize $}\n</span>\n');$templateCache.put("/semantic/bytes.html",'<a ng-if="controller.stringifiedBytes === undefined" ng-click="controller.onClick($event)">\n  Show bytes...\n</a>\n<nobr ng-if="::controller.stringifiedBytes">{$ ::controller.stringifiedBytes $}</nobr>\n');$templateCache.put("/semantic/client-urn-modal.html",
'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h4 class="modal-title">Client {$ ::controller.clientId $}</h4>\n</div>\n<div class="modal-body">\n  <grr-semantic-value value="::controller.clientDetails" />\n</div>\n');$templateCache.put("/semantic/client-urn.html",'<nobr ng-if="::value">\n  <a ng-if="::controller.clientId"\n     ui-sref="client.hostInfo(::{clientId: controller.clientId })">\n    {$ ::controller.clientId $}\n  </a>\n\n  <button class="btn btn-default btn-xs" ng-click="controller.onInfoClick()">\n    <span class="glyphicon glyphicon-info-sign"></span>\n  </button>\n</nobr>\n');
$templateCache.put("/semantic/data-object.html",'<table class="proto_table">\n  <tbody>\n    <tr ng-repeat="keyValuePair in ::value.value.items">\n      <td class="proto_key">\n        {$ ::keyValuePair.value.key.value $}\n      </td>\n\n      <td class="proto_value">\n        <grr-semantic-value value="::keyValuePair.value.value" />\n      </td>\n    </tr>\n  </tbody>\n</table>\n');$templateCache.put("/semantic/dict.html",'<table class="proto_table">\n  <tbody>\n    <tr ng-repeat="(key, value) in ::value.value">\n      <td class="proto_key" ng-if="::key !== \'mro\' && key !== \'data\'">\n        {$ ::key $}\n      </td>\n\n      <td class="proto_value">\n        <grr-semantic-value value="::value" />\n      </td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/semantic/flow-id.html",'<nobr ng-if="::value">\n  <a ng-if="::controller.clientId !== undefined"\n    title="Flow {$ ::value.value $} ran on client {$ ::controller.clientId $}"\n    ui-sref="client.flows(::{clientId: controller.clientId, flowId: value.value })">\n    {$ ::value.value $}\n  </a>\n  <span ng-if="::controller.clientId === undefined">{$ ::value.value $}</span>\n</nobr>\n');$templateCache.put("/semantic/hunt-id.html",'<nobr ng-if="::value">\n  <a ui-sref="hunts(::{huntId: value.value })">\n    {$ ::value.value $}\n  </a>\n</nobr>\n');
$templateCache.put("/semantic/json.html",'<a ng-if="controller.prettyJson === undefined" ng-click="controller.onClick($event)">\n  Show JSON...\n</a>\n<span ng-if="::controller.prettyJson" class="preserve-whitespace">{$ ::controller.prettyJson $}</span>\n');$templateCache.put("/semantic/object-label.html",'<span ng-if="::controller.labelOwner == \'GRR\'" class="label label-default">\n  {$ ::controller.labelName $}\n</span>\n\n<span ng-if="::controller.labelOwner != \'GRR\'" class="label label-success">\n  {$ ::controller.labelName $}\n</span>\n');
$templateCache.put("/semantic/osquery-table.html",'<div class="outer-wrapper">\n  <pre><code>{$ controller.query $}</code></pre>\n  <div class="table-wrapper">\n    <table class="table table-striped table-hover table-bordered">\n      <thead>\n        <tr>\n          <th ng-repeat="column in controller.columns">{$ column $}</th>\n        </tr>\n      </thead>\n      <tbody>\n        <tr ng-repeat="row in controller.rows">\n          <td ng-repeat="value in row track by $index">{$ value $}</td>\n        </tr>\n      </tbody>\n    </table>\n  </div>\n</div>\n');
$templateCache.put("/semantic/semantic-diff-annotated-proto.html","<table ng-class=\"::{'diff-added': value._diff === 'added',\n                 'diff-removed': value._diff === 'removed',\n                 'diff-changed': value._diff === 'changed',\n                 'proto_table': true}\">\n  <tbody>\n    <tr ng-repeat=\"item in ::controller.items\"\n        ng-class=\"::{'diff-added': item.value._diff === 'added',\n                  'diff-removed': item.value._diff === 'removed',\n                  'diff-changed': item.value._diff === 'changed'}\">\n      <td class=\"proto_key\" ng-if=\"::item.desc !== undefined\">\n        <abbr title=\"{$ ::item.desc $}\">{$ ::item.key $}</abbr>\n      </td>\n      <td class=\"proto_key\" ng-if=\"::item.desc === undefined\">{$ ::item.key $}</td>\n\n      <td class=\"proto_value\">\n        <grr-semantic-value ng-if=\"::!item.isList && item.value !== undefined\" value=\"::item.value\">\n        </grr-semantic-value>\n        <div ng-if=\"::item.isList === true\">\n          <div ng-repeat=\"repeatedItem in ::item.value\"\n               ng-class=\"::{'diff-added': repeatedItem._diff === 'added',\n                         'diff-removed': repeatedItem._diff === 'removed',\n                         'diff-changed': repeatedItem._diff === 'changed',\n                         'repeated': true}\">\n            <grr-semantic-value value=\"::repeatedItem\"></grr-semantic-value>\n          </div>\n        </div>\n      </td>\n    </tr>\n  </tbody>\n</table>\n");
$templateCache.put("/semantic/semantic-proto.html",'<table class="proto_table">\n  <tbody>\n    <tr ng-repeat="item in ::controller.items">\n      <td class="proto_key" ng-if="::item.desc !== undefined">\n        <abbr title="{$ ::item.desc $}">{$ ::item.key $}</abbr>\n      </td>\n      <td class="proto_key" ng-if="::item.desc === undefined">{$ ::item.key $}</td>\n\n      <td class="proto_value">\n        <grr-semantic-value ng-if="::item.value !== undefined" value="::item.value" />\n      </td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/semantic/semantic-protos-diff.html",'<grr-semantic-value-registry-override map="::controller.overrideMap">\n\n  <div class="row">\n    <div class="col-md-6">\n      <grr-semantic-diff-annotated-proto ng-if="::controller.annotatedOriginalValue"\n                                         value="::controller.annotatedOriginalValue"\n                                         visible-fields="::visibleFields"\n                                         hidden-fields="::hiddenFields">\n      </grr-semantic-diff-annotated-proto>\n      <span ng-if="::!controller.annotatedOriginalValue">-</span>\n    </div>\n\n    <div class="col-md-6">\n      <grr-semantic-diff-annotated-proto ng-if="::controller.annotatedNewValue"\n                                         value="::controller.annotatedNewValue"\n                                         visible-fields="::visibleFields"\n                                         hidden-fields="::hiddenFields">\n      </grr-semantic-diff-annotated-proto>\n      <span ng-if="::!controller.annotatedNewValue">-</span>\n    </div>\n  </div>\n\n</grr-semantic-value-registry-override>\n');
$templateCache.put("/semantic/semantic-versioned-proto.html",'<table class="proto_table">\n  <tbody>\n    <tr ng-repeat="item in ::controller.items">\n      <td class="proto_key" >\n        <abbr title="{$ ::item.desc $}" ng-if="::item.desc !== undefined">{$ ::item.key $}</abbr>\n        <span ng-if="::item.desc === undefined">{$ ::item.key $}</span>\n        <span class="proto_history">\n          <button class="btn btn-default btn-xs"\n                  ng-click="onFieldClick({\'fieldPath\': item.historyPath || item.structKey})">\n            <span class="glyphicon glyphicon-time"></span>\n          </button>\n        </span>\n      </td>\n\n      <td class="proto_value" ng-if="::item.recursiveItem === true">\n        <grr-semantic-versioned-proto ng-if="::item.value !== undefined"\n                                      value="::item.value"\n                                      on-field-click="onFieldClick({\'fieldPath\': fieldPath})"\n                                      history-depth="::historyDepth - 1"\n                                      history-path="::item.historyPath">\n        </grr-semantic-versioned-proto>\n      </td>\n      <td class="proto_value" ng-if="::item.recursiveItem === false">\n        <grr-semantic-value ng-if="::item.value !== undefined" value="::item.value" />\n      </td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/semantic/stat-entry.html",'<table class="proto_table">\n  <tbody>\n    <tr>\n      <td class="proto_key">\n        <abbr title="The location of this file in the AFF4 space.">Aff4path</abbr>\n      </td>\n      <td class="proto_value">\n        <grr-semantic-value value="::controller.aff4Path"></grr-semantic-value>\n\n        <button ng-if="::controller.downloadUrl !== undefined"\n                class="btn btn-default btn-xs" name="download"\n                type="button" ng-click="controller.onDownloadClick()">\n          <span class="glyphicon glyphicon-download"></span>\n        </button>\n      </td>\n    </tr>\n  </tbody>\n</table>\n<grr-semantic-proto value="::controller.statEntry"\n                    hidden-fields="::[\'aff4path\']">\n</grr-semantic-proto>\n');
$templateCache.put("/semantic/stat-ext-flags-linux.html",'<div ng-switch="::controller.status">\n  <span ng-switch-when="MALFORMED">malformed</span>\n  <span ng-switch-when="NONE">none</span>\n  <ul ng-switch-when="SOME">\n    <li ng-repeat="flag in ::controller.flags track by $index">\n      <span ng-if="flag === null">-</span>\n      <abbr ng-if="flag !== null" title="{$ flag.description $}">\n        {$ ::flag.identifier $}\n      </abbr>\n    </li>\n  </ul>\n</div>\n');$templateCache.put("/semantic/stat-ext-flags-osx.html",
'<div ng-switch="::controller.status">\n  <span ng-switch-when="MALFORMED">malformed</span>\n  <span ng-switch-when="NONE">none</span>\n  <ul ng-switch-when="SOME">\n    <li ng-repeat="flag in ::controller.flags">\n      <abbr title="{$ ::flag.description $}">{$ ::flag.identifier $}</abbr>\n    </li>\n  </ul>\n</div>\n');$templateCache.put("/semantic/timestamp.html",'<span ng-if="::controller.formattedTimestamp" ng-mouseenter="controller.onMouseEnter()">\n  <span class="hidden-md hidden-lg">\n    <span ng-repeat="component in ::controller.formattedTimestampComponents">\n      <nobr>{$ ::component $}</nobr>\n    </span>\n  </span>\n  <span class="visible-md-inline visible-lg-inline">\n    <nobr>\n      {$ ::controller.formattedTimestamp $}\n    </nobr>\n  </span>\n</span>\n');
$templateCache.put("/semantic/urn.html",'<span ng-if="::controller.ref === undefined"\n      title="This URN points to AFF4 location not accessible from the UI">\n  <em>{$ ::controller.plainValue $}</em>\n</span>\n<a ng-if="::controller.ref !== undefined" ng-href="{$ ::controller.ref $}"\n   ng-click="controller.onClick()">{$ ::controller.plainValue $}</a>\n');$templateCache.put("/sidebar/client-summary.html",'<div>\n  <div class="client-name">\n    <span ng-if="client.value.os_info.value.fqdn">\n      {$ client.value.os_info.value.fqdn.value $}\n    </span>\n    <span ng-if="!client.value.os_info.value.fqdn">\n      {$ client.value.client_id.value $}\n    </span>\n  </div>\n  <div class="approval-reason" ng-if="controller.approvalReason">\n    Access reason: {$ controller.approvalReason $}\n  </div>\n  <div class="client-status">\n    \x3c!-- Output of the directives below depends on the current time (as\n         they depend on the time *passed since* the time the client was last\n         active. We have to refresh them every second, as Angular won\'t\n         detect the changes automatically (since source value - last_seen_at -\n         stays the same). --\x3e\n    <grr-periodic-refresh interval="1000">\n      Status:\n      <grr-client-status-icons client="client"></grr-client-status-icons>\n      {$ (client.value.last_seen_at.value | grrTimeSince) $}\n    </grr-periodic-refresh>\n  </div>\n  <span ng-if="controller.crashTime != null" class="last-crash">\n    <strong>Last crash:</strong><br/>\n    {$ (controller.crashTime | grrTimeSince) $}\n  </span>\n  <div class="client-ip-info">\n    <img ng-if="controller.lastIP.status === \'UNKNOWN\'" class="grr-icon-small vertical_aligned" src="/static/images/ip_unknown.png">\n    <img ng-if="controller.lastIP.status === \'INTERNAL\'" class="grr-icon-small vertical_aligned" src="/static/images/ip_internal.png">\n    <img ng-if="controller.lastIP.status === \'EXTERNAL\'" class="grr-icon-small vertical_aligned" src="/static/images/ip_external.png">\n    <img ng-if="controller.lastIP.status === \'VPN\'" class="grr-icon-small vertical_aligned" src="/static/images/ip_unknown.png">\n    {$ controller.lastIP.info $}\n  </div>\n\n  <grr-client-warnings client="client"></grr-client-warnings>\n</div>\n');
$templateCache.put("/sidebar/client-warnings.html",'<div ng-repeat="warning in controller.warnings" class="alert alert-danger">\n  <grr-markdown source="warning"></grr-markdown>\n</div>\n');$templateCache.put("/sidebar/nav-dropdown.html",'<a class="dropdown-toggle"\n   ng-click="controller.isCollapsed = !controller.isCollapsed">\n\n  {$ title $}<i class="caret"></i>\n\n</a>\n<div uib-collapse="controller.isCollapsed">\n  <ng-transclude></ng-transclude>\n</div>');$templateCache.put("/sidebar/nav-link.html",
'<a class="nav-link"\n   ng-disabled="disabled"\n   ng-class="{\'disabled\': disabled}"\n   ng-click="controller.openLink($event)"\n   ng-href="{$ controller.href $}"\n   grrtarget="{$ state $}">\n\n  <i ng-if="disabled" class="fa fa-lock" title="Missing approvals."></i>\n  <ng-transclude></ng-transclude>\n\n</a>\n');$templateCache.put("/sidebar/navigator.html",'<div id="navigator">\n\n  <section ng-if="controller.clientId && !controller.client">\n    Loading...\n  </section>\n\n  \x3c!-- Client overview and links for client navigation --\x3e\n  <section ng-if="controller.client">\n    \x3c!-- Client overview--\x3e\n    <grr-periodic-refresh interval="30000"\n                          on-refresh="controller.refreshClientDetails()">\n    </grr-periodic-refresh>\n    <grr-client-summary client="controller.client"></grr-client-summary>\n\n    \x3c!-- Client links --\x3e\n    <ul class="nav nav-list">\n      <li grr-nav-link state="client.hostInfo"\n          params="{clientId: controller.clientId}">\n        Host Information\n      </li>\n      <li grr-nav-link state="client.launchFlows"\n          params="{clientId: controller.clientId}"\n          disabled="!controller.uiTraits.start_client_flow_nav_item_enabled || !controller.hasClientAccess">\n        Start new flows\n      </li>\n      <li grr-nav-link state="client.vfs"\n          params="{clientId: controller.clientId}"\n          disabled="!controller.uiTraits.browse_virtual_file_system_nav_item_enabled || !controller.hasClientAccess">\n        Browse Virtual Filesystem\n      </li>\n      <li grr-nav-link state="client.flows"\n          params="{clientId: controller.clientId}"\n          disabled="!controller.uiTraits.manage_client_flows_nav_item_enabled || !controller.hasClientAccess">\n        Manage launched flows\n      </li>\n\n      <li id="HostAdvanced" grr-nav-dropdown title="Advanced">\n        <ul class="nav nav-list">\n          <li grr-nav-link state="client.crashes"\n              params="{clientId: controller.clientId}"\n              disabled="!controller.hasClientAccess">\n            Crashes\n          </li>\n          <li grr-nav-link state="client.debugRequests"\n              params="{clientId: controller.clientId}"\n              disabled="!controller.hasClientAccess">\n            Debug Client Requests\n          </li>\n          <li grr-nav-link state="client.loadStats"\n              params="{clientId: controller.clientId}"\n              disabled="!controller.hasClientAccess">\n            Client Load Stats\n          </li>\n        </ul>\n      </li>\n    </ul>\n  </section>\n\n  \x3c!-- Management links --\x3e\n  <section>\n    <h1>Management</h1>\n\n    <ul class="nav nav-list">\n      <li grr-nav-link state="crons"\n          disabled="!controller.uiTraits.cron_jobs_nav_item_enabled">\n        Cron Jobs\n      </li>\n      <li grr-nav-link state="hunts"\n          disabled="!controller.uiTraits.hunt_manager_nav_item_enabled">\n        Hunts\n      </li>\n      <li grr-nav-link state="stats"\n          disabled="!controller.uiTraits.show_statistics_nav_item_enabled">\n        Statistics\n      </li>\n    </ul>\n  </section>\n\n  \x3c!-- Configuration links --\x3e\n  <section>\n    <h1>Configuration</h1>\n\n    <ul class="nav nav-list">\n      <li grr-nav-link state="manageBinaries"\n          disabled="!controller.uiTraits.manage_binaries_nav_item_enabled">\n        Binaries\n      </li>\n      <li grr-nav-link state="config"\n          disabled="!controller.uiTraits.settings_nav_item_enabled">\n        Settings\n      </li>\n      <li grr-nav-link state="artifacts"\n          disabled="!controller.uiTraits.artifact_manager_nav_item_enabled">\n        Artifacts\n      </li>\n    </ul>\n  </section>\n</div>\n');
$templateCache.put("/stats/audit-chart.html",'<h3>{{ controller.errorMsg }}</h3>\n\n<table class="table table-striped table-condensed table-hover table-bordered\n              full-width">\n  <thead>\n    <tr>\n      <th ng-repeat="titleCaseLabel in controller.auditTitleCaseUsedFields\n                     track by $index">\n        {{ titleCaseLabel }}\n      </th>\n    </tr>\n  </thead>\n\n  <tbody>\n    <tr ng-repeat="row in controller.typedAuditRows track by $index">\n      <td ng-repeat="label in controller.auditUsedFields track by $index">\n        <grr-semantic-value value="row.value[label]"></grr-semantic-value>\n      </td>\n    </tr>\n  </tbody>\n</table>\n');
$templateCache.put("/stats/chart.html","<grr-line-chart ng-if=\"typedData.value.representation_type.value == 'LINE_CHART'\"\n                typed-data=\"typedData['value']['line_chart']\">\n</grr-line-chart>\n\n<grr-comparison-chart ng-if=\"typedData.value.representation_type.value == 'PIE_CHART'\"\n                      typed-data=\"typedData['value']['pie_chart']\">\n</grr-comparison-chart>\n\n<grr-comparison-chart ng-if=\"typedData.value.representation_type.value == 'STACK_CHART'\"\n                      typed-data=\"typedData['value']['stack_chart']\">\n</grr-comparison-chart>\n\n<grr-audit-chart ng-if=\"typedData.value.representation_type.value == 'AUDIT_CHART'\"\n                 typed-data=\"typedData\">\n</grr-audit-chart>\n");
$templateCache.put("/stats/comparison-chart.html",'<div ng-if="controller.values.length === 0">\n  No data to display.\n</div>\n\n<div ng-if="controller.values.length > 0">\n  <table class="table table-striped table-condensed">\n    <colgroup>\n      <col style="width: 20%">\n      <col style="width: 20%">\n      <col style="width: 60%">\n    </colgroup>\n    <thead>\n      <tr>\n        <th>Label</th>\n        <th>Value</th>\n        <th></th>\n      </tr>\n    </thead>\n    <tbody>\n      <tr ng-repeat="item in controller.values">\n        <td>\n          {{ item.label }}\n        </td>\n        <td>\n          {{ item.value }}\n        </td>\n        <td>\n          <uib-progressbar value="item.percent"></uib-progressbar>\n        </td>\n      </tr>\n    </tbody>\n  </table>\n</div>\n');
$templateCache.put("/stats/line-chart.html",'<div class="chart">\n</div>\n<div class="chart-legend">\n</div>\n');$templateCache.put("/stats/report-listing.html",'<div>\n  <div class="report-listing-tree">\n  </div>\n</div>\n');$templateCache.put("/stats/report.html",'<div class="padded">\n  <span ng-if="controller.state === \'INITIAL\'">\n    <h3>\n      Select a report to view.\n    </h3>\n  </span>\n\n  <span ng-if="controller.reportDesc">\n    <h3>\n      {{ controller.titleCasedType }}\n      |\n      {{ controller.reportDesc.title }}\n    </h3>\n\n    <h4>\n      {{ controller.reportDesc.summary }}\n    </h4>\n\n    <span ng-if="controller.reportDesc.type === \'CLIENT\'">\n      <grr-form-client-label client-label="controller.clientLabel">\n      </grr-form-client-label>\n    </span>\n\n    <span ng-if="controller.reportDesc.requires_time_range">\n      <grr-form-timerange start-time-secs="controller.startTime"\n                          duration-secs="controller.duration">\n      </grr-form-timerange>\n    </span>\n\n    <div ng-if="controller.reportDesc.type === \'CLIENT\' ||\n                controller.reportDesc.requires_time_range"\n         class="controls">\n        <button class="btn btn-default" ng-click="controller.refreshReport()">\n          Show report\n        </button>\n    </div>\n  </span>\n\n  <span ng-if="controller.state === \'LOADING\'">\n    <h4>\n      Loading...\n    </h4>\n  </span>\n\n  <span ng-if="controller.state === \'LOADED\'">\n    <grr-chart typed-data="controller.typedReportData"></grr-chart>\n  </span>\n</div>\n');
$templateCache.put("/stats/stats-view.html",'<grr-report-listing selection-name="controller.selectionName">\n</grr-report-listing>\n\n<grr-report name="controller.selectionName"\n            start-time="controller.startTime"\n            duration="controller.duration"\n            client-label="controller.clientLabel"></grr-report>\n');$templateCache.put("/stats/timeseries-graph.html",'<ng-transclude></ng-transclude>\n\n<div class="fill-parent-no-margins" ng-if="controller.inProgress">\n  Loading...\n</div>\n<div class="fill-parent-no-margins" ng-if="!controller.inProgress && controller.isEmpty">\n  No data to display.\n</div>\n<div class="timeseries-graph" ng-show="!controller.inProgress && !controller.isEmpty"></div>\n<div class="timeseries-graph-legend"></div>\n');
$templateCache.put("/user/approver-input.html",'<input name="acl_approver"\n       type="text"\n       class="form-control"\n       placeholder="approver1, approver2, approver3, ..."\n       ng-model="model"\n       uib-typeahead="item.suggestion as item.username for item in controller.loadApproverSuggestions($viewValue)"\n       typeahead-append-to-body="true"\n       typeahead-template-url="/static/angular-components/core/typeahead-match.html"\n       ng-trim="false"\n/>\n');$templateCache.put("/user/user-dashboard.html",
'<div class="container-fluid">\n  <div class="row horizontally-padded">\n    <div id=\'front\'><h2>Welcome to GRR</h2></div>\n    Query for a system to view in the search box above.\n\n    <p>\n      Type a search term to search for a machine using either a hostname,\n      mac address or username.\n    </p>\n    <br/>\n\n    <div name="RecentlyAccessedClients" class="panel panel-default">\n      <div class="panel-heading">\n        <h4>Recently Accessed <strong>Clients</strong></h4>\n      </div>\n      <div class="panel-body">\n\n        <span ng-if="controller.clientApprovals === undefined">\n          Loading...\n        </span>\n\n        <span ng-if="controller.clientApprovals.length == 0">\n          None.\n        </span>\n\n        <table ng-if="controller.clientApprovals.length > 0"\n               class="table table-condensed table-hover table-bordered full-width">\n          <colgroup>\n            <col style="width: 40px">\n            <col style="width: 40px">\n            <col style="width: 13em">\n            <col style="width: 13em">\n            <col style="width: 20%">\n            <col style="width: 20%">\n            <col style="width: 20%">\n            <col style="width: 20%">\n          </colgroup>\n          <thead>\n            <tr>\n              <th>Online</th>\n              <th>Subject</th>\n              <th>Host</th>\n              <th>Labels</th>\n              <th>Last Checkin</th>\n              <th>Reason</th>\n            </tr>\n          </thead>\n          <tr ng-repeat="approval in ::controller.clientApprovals"\n              ng-class="::{\'half-transparent\': !approval.value.is_valid.value}"\n              ng-click="controller.onClientClicked(approval.value.subject.value.client_id.value)">\n            \x3c!-- Online status --\x3e\n            <td>\n              <grr-client-status-icons client="::approval.value.subject" />\n            </td>\n\n            \x3c!-- Client Id --\x3e\n            <td>\n              <span type="subject">\n                {$ ::approval.value.subject.value.client_id.value $}\n              </span>\n            </td>\n\n            \x3c!-- Client Host --\x3e\n            <td class="host">\n              <grr-semantic-value\n                 value="::approval.value.subject.value.os_info.value.fqdn" />\n            </td>\n\n            \x3c!-- Client Labels --\x3e\n            <td>\n              <grr-semantic-value\n                 value="::approval.value.subject.value.labels" />\n            </td>\n\n            \x3c!-- Client Latest checkin --\x3e\n            <td>\n              <grr-semantic-value\n                 value="::approval.value.subject.value.last_clock" />\n            </td>\n\n            \x3c!-- Reason --\x3e\n            <td class="reason">\n              <grr-semantic-value\n                 value="::approval.value.reason" />\n            </td>\n\n          </tr>\n\n        </table>\n        <p class="small text-right">\n          <em>* semi-transparent rows designate expired approvals</em>\n        </p>\n      </div>\n    </div>\n\n\n    <div name="RecentlyCreatedHunts"  class="panel panel-default">\n      <div class="panel-heading">\n        <h4>Recently Created <strong>Hunts</strong></h4>\n      </div>\n      <div class="panel-body">\n\n        <span ng-if="controller.hunts === undefined">\n          Loading...\n        </span>\n\n        <span ng-if="controller.hunts.length == 0">\n          None.\n        </span>\n\n        <table ng-if="controller.hunts.length > 0"\n               class="table table-condensed table-hover table-bordered full-width">\n          <colgroup>\n            <col style="width: 40px" />\n            <col />\n            <col />\n            <col style="width: 16em" />\n            <col style="width: 16em" />\n            <col />\n            <col width="100%" />\n          </colgroup>\n          <thead>\n            <tr>\n              <th>Status</th>\n              <th>Hunt ID</th>\n              <th>Name</th>\n              <th>Start Time</th>\n              <th>Expires</th>\n              <th>Client Limit</th>\n              <th>Description</th>\n            </tr>\n          </thead>\n          <tbody>\n            <tr ng-repeat="hunt in ::controller.hunts"\n                ng-click="controller.onHuntClicked(hunt)">\n              <td><grr-hunt-status-icon hunt="::hunt" /></td>\n              <td>{$ ::hunt.value.hunt_id.value $}</td>\n              <td>{$ ::hunt.value.name.value $}</td>\n              <td><grr-timestamp value="::hunt.value.created" /></td>\n              <td><grr-timestamp value="::hunt.value.expires" /></td>\n              <td>{$ ::hunt.value.client_limit.value $}</td>\n              <td>{$ ::hunt.value.description.value $}</td>\n            </tr>\n          </tbody>\n        </table>\n\n      </div>\n    </div>\n\n  </div>  \x3c!-- row --\x3e\n</div>  \x3c!-- container --\x3e\n');
$templateCache.put("/user/user-label.html",'<p ng-if="!controller.error">\n  User: {$ controller.username $}\n</p>\n<p ng-if="controller.error">\n  User: <span class="text-danger"><em>{$ controller.error $}</em></span>\n</p>\n');$templateCache.put("/user/user-notification-button.html",'<button id="notification_button" class="nav-btn btn"\n        ng-class="controller.notificationCount === 0 ? \'btn-info\' : \'btn-danger\'"\n        ng-click="controller.showNotifications()">\n   {$ controller.notificationCount $}\n</button>');
$templateCache.put("/user/user-notification-dialog.html",'<div name="NotificationDialog">\n  <div class="modal-header">\n    <button type="button" class="close" ng-click="close()" aria-hidden="true">\u00d7</button>\n    <h3>Notifications</h3>\n  </div>\n  <div class="modal-body">\n    <table class="table table-striped table-condensed table-bordered full-width">\n      <tbody>\n      <tr grr-paged-filtered-table\n          page-size="50"\n          grr-api-items-provider\n          method="POST"\n          url="::controller.notificationUrl">\n        <td>\n          <grr-user-notification-item notification="item" close="close()" />\n        </td>\n      </tr>\n      </tbody>\n    </table>\n  </div>\n  <div class="modal-footer">\n    <button class="btn btn-primary" ng-click="close()">Close</button>\n  </div>\n</div>\n');
$templateCache.put("/user/user-notification-item.html",'<div ng-class="{ \'pending\': notification.isPending, \'has-link\': notification.link }">\n  \x3c!-- Either the notification is shown as regular link to some source item --\x3e\n  <a ng-if="!notification.isFileDownload" ng-click="controller.openReference()">\n    <div class="notification-icon">\n      <i ng-if="notification.refType === \'DISCOVERY\'" class="fa fa-binoculars"></i>\n      <i ng-if="notification.refType === \'HUNT\'" class="fa fa-crosshairs"></i>\n      <i ng-if="notification.refType === \'FLOW\'" class="fa fa-code-fork"></i>\n      <i ng-if="notification.refType === \'CRON\'" class="fa fa-history"></i>\n      <i ng-if="notification.refType === \'VFS\'" class="fa fa-hdd-o"></i>\n      <i ng-if="notification.refType === \'CLIENT_APPROVAL\'" class="fa fa-unlock"></i>\n      <i ng-if="notification.refType === \'HUNT_APPROVAL\'" class="fa fa-unlock"></i>\n      <i ng-if="notification.refType === \'CRON_JOB_APPROVAL\'" class="fa fa-unlock"></i>\n    </div>\n\n    <div class="notification-content">\n      <grr-semantic-value value="::notification.value.message"></grr-semantic-value>\n      <grr-timestamp value="::notification.value.timestamp" />\n    </div>\n\n    <div class="no-link-indicator" ng-if="!notification.link">\n      <i class="fa fa-chain-broken"></i>\n      This is a LEGACY notification (therefore it\'s not clickable)\n    </div>\n  </a>\n\n  <div ng-if="notification.isFileDownload">\n    <div class="notification-icon">\n      <i class="fa fa-download"></i>\n    </div>\n    <div class="notification-content">\n      <grr-semantic-value value="::notification.value.message"></grr-semantic-value>\n      <grr-timestamp value="::notification.value.timestamp" />\n    </div>\n    <div class="no-link-indicator">\n      <i class="fa fa-chain-broken"></i>\n      This is a LEGACY file download notification (therefore it\'s not clickable)\n    </div>\n  </div>\n</div>\n');
$templateCache.put("/user/user-settings-button-modal.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h3 class="modal-title">Settings</h3>\n</div>\n<div class="modal-body">\n  <grr-form-value value="controller.userSettings"></grr-form-value>\n\n  <div class="aler alert-success padded" role="alert"\n       ng-if="controller.done && !controller.error">\n    Settings were successfully updated. Reloading...\n  </div>\n\n  <div class="aler alert-danger padded" role="alert"\n       ng-if="controller.done && controller.error">\n    {$ controller.error $}\n  </div>\n</div>\n<div class="modal-footer">\n  <button class="btn btn-default" ng-click="$dismiss()" name="Close">\n    Close\n  </button>\n  <button class="btn btn-primary" ng-if="!controller.requestSent"\n          ng-click="controller.saveSettings()" name="Proceed">\n    Apply\n  </button>\n</div>\n');
$templateCache.put("/user/user-settings-button.html",'<button class="btn btn-default" ng-click="controller.onClick()">\n  <img src="/static/images/modify.png">\n</button>\n');$templateCache.put("/client/virtual-file-system/breadcrumbs.html",'<ul class="breadcrumb">\n\n  <li ng-repeat="item in controller.items">\n    <a ng-click="controller.selectPath(item.path)">{$ item.name $}</a>\n  </li>\n\n  <li ng-if="controller.activeItem" class="active">\n      {$ controller.activeItem $}\n  </li>\n\n  <div class="clearfix"></div>\n\n</ul>\n');
$templateCache.put("/client/virtual-file-system/encodings-dropdown.html",'<select ng-model="encoding"\n        ng-disabled="!controller.encodings.length"\n        class="form-control">\n\n    \x3c!-- We cannot use ng-options here, since it does not set the selected attribute. --\x3e\n    <option ng-repeat="e in controller.encodings"\n            ng-selected="e.value === encoding"\n            value="{$ e.value $}">\n      {$ e.value $}\n    </option>\n\n    <option ng-if="!controller.encodings.length"\n            ng-selected="!controller.encodings.length"\n            value="">\n      No encodings available.\n    </option>\n\n</select>');
$templateCache.put("/client/virtual-file-system/file-details.html",'<div>\n\n  <div ng-if="!controller.fileContext.selectedFilePath" class="padded">\n    Please select a file or a folder to see its details here.\n  </div>\n\n  <div ng-if="controller.fileContext.selectedFilePath" class="padded">\n\n    <grr-breadcrumbs path="controller.fileContext.selectedFilePath"\n                     strip-ending-slash="true">\n    </grr-breadcrumbs>\n\n    <grr-version-dropdown url="controller.fileVersionUrl"\n                          version="controller.fileContext.selectedFileVersion">\n    </grr-version-dropdown>\n\n    <h1>{$ controller.selectedFileName $}</h1>\n\n    <uib-tabset active="controller.currentTab">\n\n      <uib-tab heading="Stats" index="\'stats\'">\n        <div ng-if="controller.currentTab === \'stats\'">\n          <grr-file-stats-view></grr-file-stats-view>\n        </div>\n      </uib-tab>\n\n      <uib-tab heading="Download" index="\'download\'"\n               disable="controller.fileIsDirectory">\n        <div ng-if="controller.currentTab === \'download\'">\n          <div grr-force-refresh refresh-trigger="controller.downloadQueryParams.age">\n            <grr-file-download-view></grr-file-download-view>\n          </div>\n        </div>\n\n      </uib-tab>\n\n      <uib-tab heading="TextView" index="\'textview\'"\n               disable="controller.fileIsDirectory">\n        <div ng-if="controller.currentTab === \'textview\'">\n          <grr-file-text-view></grr-file-text-view>\n        </div>\n      </uib-tab>\n\n      <uib-tab heading="HexView" index="\'hexview\'"\n               disable="controller.fileIsDirectory">\n        <div ng-if="controller.currentTab === \'hexview\'">\n          <grr-file-hex-view></grr-file-hex-view>\n        </div>\n      </uib-tab>\n\n    </uib-tabset>\n\n  </div>\n\n</div>\n');
$templateCache.put("/client/virtual-file-system/file-download-view.html",'<div grr-force-refresh refresh-trigger="controller.fileDetails">\n\n  <div ng-if="controller.fileDetails === undefined">\n    Loading...\n  </div>\n\n  <div ng-if="controller.fileDetails !== undefined">\n\n    <div ng-if="controller.fileDetails.value.hash">\n      <h4>Hash</h4>\n      <span>\n        <grr-semantic-value value="controller.fileDetails.value.hash" />\n      </span>\n    </div>\n\n    <div ng-if="controller.fileDetails.value.last_collected">\n      <h4>Last Collected</h4>\n      <span>\n        <grr-timestamp value="controller.fileDetails.value.last_collected" />\n      </span>\n\n      <h4>Download</h4>\n      <p>\n        <button class="btn btn-default"\n                ng-click="controller.downloadFile()">\n          Download ({$ controller.fileDetails.value.last_collected_size.value $} bytes)\n        </button>\n      </p>\n      <p>\n        Or by using command line export tool:\n      </p>\n      <div class="monospace">\n        <pre>{$ controller.downloadCommand $}</pre>\n      </div>\n      <hr />\n    </div>\n\n    <div>\n      <button class="btn btn-default"\n              ng-click="controller.updateFile()"\n              ng-disabled="controller.updateInProgress">\n        <i class="fa fa-refresh"\n           ng-class="{\'fa-spin\': controller.updateInProgress}"></i>\n        {{ controller.fileDetails.value.last_collected ? \'Re-Collect\' : \'Collect\' }} from the client\n      </button>\n    </div>\n\n  </div>\n\n</div>\n');
$templateCache.put("/client/virtual-file-system/file-hex-view.html",'<div>\n\n  \x3c!-- Show pagination and content if there is file content. --\x3e\n  <div ng-if="controller.hexDataRows.length">\n\n    <div>\n      <ul uib-pagination total-items="controller.pageCount" items-per-page="1"\n          max-size="10" rotate="false" boundary-links="true"\n          ng-model="controller.page" ng-if="controller.pageCount > 1">\n      </ul>\n    </div>\n\n    \x3c!-- Show the hex view using three separate tables to enable vertical selection. --\x3e\n    <div class="monospace">\n      <table>\n        <tr>\n          <th>Offset</th>\n          <th>000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f</th>\n          <th></th>\n        </tr>\n        <tr>\n          <td>\n            \x3c!-- Offset --\x3e\n            <table class="offset-area">\n              <tr ng-repeat="row in controller.hexDataRows">\n                <td class="offset">\n                  {$ ::row.offset | grrHexNumber $}\n                </td>\n              </tr>\n            </table>\n          </td>\n          <td>\n            \x3c!-- Hex --\x3e\n            <table class="hex-area">\n              <tr ng-repeat="row in controller.hexDataRows">\n                <td>\n                  {$ ::row.data | grrBytesToHex $}\n                </td>\n              </tr>\n            </table>\n          </td>\n          <td>\n            \x3c!-- Content --\x3e\n            <table class="content-area">\n              <tr ng-repeat="row in controller.hexDataRows">\n                <td class="data">\n                  {$ ::row.data $}\n                </td>\n              </tr>\n            </table>\n          </td>\n        </tr>\n      </table>\n    </div>\n\n    <div>\n      <ul uib-pagination total-items="controller.pageCount" items-per-page="1"\n          max-size="10" rotate="false" boundary-links="true"\n          ng-model="controller.page" ng-if="controller.pageCount > 1">\n      </ul>\n    </div>\n\n  </div>\n\n  \x3c!-- Show a hint if no content exists. --\x3e\n  <div ng-if="!controller.hexDataRows.length" class="no-content">\n    No file content to show.\n  </div>\n\n</div>\n');
$templateCache.put("/client/virtual-file-system/file-stats-view.html",'<div grr-force-refresh refresh-trigger="controller.details">\n  <grr-aff4-object-representation value="controller.details"></grr-aff4-object-representation>\n</div>');$templateCache.put("/client/virtual-file-system/file-table.html",'<div class="outer fill-parent no-margins">\n\n  <div class="navbar navbar-default toolbar">\n\n    <div class="navbar-inner">\n      <div class="navbar-form pull-left">\n\n        <div class="btn-group" role="group">\n          <button id="refresh-dir" class="btn btn-default"\n                  title="Refresh this directory (sync its listing with the client)"\n                  ng-disabled="controller.lastRefreshOperationId"\n                  ng-click="controller.startVfsRefreshOperation()">\n            <img src="/static/images/stock_refresh.png" class="toolbar_icon" />\n          </button>\n\n          <grr-recursive-list-button client-id="controller.fileContext.clientId"\n                                     file-path="controller.fileContext.selectedFilePath"\n                                     class="space-right">\n          </grr-recursive-list-button>\n        </div>\n\n        <grr-vfs-files-archive-button client-id="controller.fileContext.clientId"\n                                      file-path="controller.fileContext.selectedFilePath"\n                                      class="space-right">\n        </grr-vfs-files-archive-button>\n\n        <div class="input-group large">\n          <input type="text" class="form-control file-search" placeholder="Filter Items"\n                 ng-model="controller.filterEditedValue" grr-bind-key="controller.updateFilter()">\n          <span class="input-group-btn">\n            <button class="btn btn-default" type="button" ng-click="controller.updateFilter()">\n              <i class="fa fa-filter"></i>\n            </button>\n          </span>\n        </div>\n\n      </div>\n\n      <div class="navbar-form pull-right">\n\n        <grr-r-we-owned-button class="space-right"></grr-r-we-owned-button>\n\n        <div class="btn-group" uib-dropdown>\n          <label class="btn btn-default"\n                 uib-btn-radio="\'list\'" ng-model="controller.viewMode">\n            <i class="fa fa-list"></i> File list\n          </label>\n          <label class="btn btn-default"\n                 uib-btn-radio="\'timeline\'" ng-model="controller.viewMode">\n            <i class="fa fa-history"></i> Timeline\n          </label>\n          <button name="timelineDropdown" class="btn btn-default dropdown-toggle"\n                  uib-dropdown-toggle>\n            <span class="caret"></span>\n          </button>\n          <ul class="dropdown-menu" uib-dropdown-menu>\n            <li>\n              <a name="downloadTimelineGrrFormat"\n                 ng-click="controller.downloadTimeline(\'GRR\'); $event.preventDefault()"\n                 href="#">\n                Download timeline as GRR CSV\n              </a>\n            </li>\n            <li>\n              <a name="downloadTimelineBodyFormat"\n                 ng-click="controller.downloadTimeline(\'BODY\'); $event.preventDefault()"\n                 href="#">\n                Download timeline as body CSV\n              </a>\n            </li>\n          </ul>\n        </div>\n      </div>\n\n    </div>\n\n  </div>\n\n  <div class="breadcrumbs">\n    <grr-breadcrumbs path="controller.fileContext.selectedFilePath"></grr-breadcrumbs>\n  </div>\n\n  <div class="content">\n    <div grr-force-refresh refresh-trigger="controller.fileListUrl"\n         ng-if="controller.viewMode === \'list\'">\n      <table class="table table-striped table-condensed table-hover table-bordered full-width file-list">\n\n        <thead>\n          <tr>\n            <th>Icon</th>\n            <th>Name</th>\n            <th>st_size</th>\n            <th>st_mtime</th>\n            <th>st_ctime</th>\n            <th>GRR Snapshot</th>\n          </tr>\n        </thead>\n\n        \x3c!-- We need this ng-if to make sure fileListUrl is stable when ApiItemsProvider is called. --\x3e\n        <tbody ng-if="controller.fileListUrl">\n          <tr grr-infinite-table page-size="1000"\n              filter-value="controller.filterValue"\n              trigger-update="controller.triggerUpdate"\n              grr-api-items-provider\n              url="controller.fileListUrl"\n              ng-click="controller.selectFile(item)"\n              ng-dblclick="controller.selectFolder(item)"\n              ng-class="{\'row-selected\': item.value.path.value === controller.fileContext.selectedFilePath}">\n            <td>\n              <img class="grr-icon directory" src="/static/images/directory.png"\n                   alt="Directory" title="Directory" ng-if="item.value.is_directory.value">\n              <img class="grr-icon file" src="/static/images/file.png"\n                   alt="File Like Object" title="File Like Object" ng-if="!item.value.is_directory.value">\n            </td>\n            <td><grr-semantic-value value="::item.value.name" /></td>\n            <td>\n              <grr-semantic-value class="pull-left"\n                                  value="::item.value.stat.value.st_size"></grr-semantic-value>\n              <span ng-if="::item.value.last_collected_size !== undefined" class="pull-right">\n                <i class="fa fa-download"\n                   title="Collected ({$ ::item.value.last_collected_size.value $} bytes)"\n                   aria-hidden="true">\n                </i>\n              </span>\n              <div class="clearfix"></div>\n            </td>\n            <td><grr-semantic-value value="::item.value.stat.value.st_mtime" /></td>\n            <td><grr-semantic-value value="::item.value.stat.value.st_ctime" /></td>\n            <td><grr-timestamp value="::item.value.age.value" /></td>\n          </tr>\n        </tbody>\n\n      </table>\n\n    </div>\n\n    <grr-file-timeline ng-if="controller.viewMode === \'timeline\'"\n                       filter-value="controller.filterValue">\n    </grr-file-timeline>\n\n  </div>\n</div>\n');
$templateCache.put("/client/virtual-file-system/file-text-view.html",'<div>\n\n  \x3c!-- Show pagination and content if there is file content. --\x3e\n  <div ng-if="controller.fileContent">\n\n    <div>\n      <ul uib-pagination total-items="controller.pageCount" items-per-page="1"\n          max-size="1" rotate="false" boundary-links="true"\n          ng-model="controller.page" ng-if="controller.pageCount > 1">\n      </ul>\n\n      <grr-encodings-dropdown encoding="controller.encoding">\n      </grr-encodings-dropdown>\n\n      <div style="clear:both"></div>\n    </div>\n\n    <div class="monospace">\n      <pre>{$ controller.fileContent $}</pre>\n    </div>\n\n    <div>\n      <ul uib-pagination total-items="controller.pageCount" items-per-page="1"\n          max-size="1" rotate="false" boundary-links="true"\n          ng-model="controller.page" ng-if="controller.pageCount > 1">\n      </ul>\n    </div>\n\n  </div>\n\n  \x3c!-- Show a hint if no content exists. --\x3e\n  <div ng-if="!controller.fileContent" class="no-content">\n    No file content to show.\n  </div>\n\n</div>\n');
$templateCache.put("/client/virtual-file-system/file-timeline.html",'<table class="table table-striped table-condensed table-hover table-bordered full-width file-list">\n\n  <colgroup>\n    <col style="width: 14em">\n    <col>\n    <col style="width: 225px">\n  </colgroup>\n\n  <thead>\n    <tr>\n      <th>Timestamp</th>\n      <th>File</th>\n      <th>Message</th>\n    </tr>\n  </thead>\n\n  <tbody ng-if="controller.inProgress">\n    <tr class="timeline-refresh-indicator">\n      <td colspan="3">\n        <i class="fa fa-spinner fa-spin fa-3x margin-bottom"></i>\n        <div>Creating timeline...</div>\n      </td>\n    </tr>\n  </tbody>\n\n  \x3c!-- We need this ng-if to make sure timelineItems is stable when ApiMemoryItemsProvider is called. --\x3e\n  <tbody ng-if="controller.timelineItems && !controller.inProgress">\n    <tr grr-infinite-table\n        filter-value=\'filterValue\'\n        trigger-update="controller.triggerUpdate"\n        grr-memory-items-provider\n        items="controller.timelineItems"\n        ng-class="{\'row-selected\': item === controller.selectedItem}"\n        ng-click="controller.selectFile(item)">\n      <td><grr-semantic-value value="::item.value.timestamp" /></td>\n      <td><grr-semantic-value value="::item.value.file_path" /></td>\n      <td>\n        <div ng-if="item.value.action.value === \'MODIFICATION\'"><pre class=\'inline\'>M--</pre> File modified.</div>\n        <div ng-if="item.value.action.value === \'ACCESS\'"><pre class=\'inline\'>-A-</pre> File access.</div>\n        <div ng-if="item.value.action.value === \'METADATA_CHANGED\'"><pre class=\'inline\'>--C</pre> File metadata changed.</div>\n      </td>\n    </tr>\n  </tbody>\n\n</table>\n');
$templateCache.put("/client/virtual-file-system/file-tree.html",'<div>\n  <div id="file-tree">\n  </div>\n</div>');$templateCache.put("/client/virtual-file-system/file-view.html",'<grr-check-client-access client-id="controller.clientId">\n\n  <grr-file-context client-id="controller.clientId"\n                    selected-file-path="controller.selectedFilePath"\n                    selected-file-version="controller.fileVersion">\n\n    <div grr-splitter orientation="vertical">\n      <div grr-splitter-pane size="25" id="main_leftPane" class="leftPane">\n        <grr-file-tree />\n      </div>\n\n      <div grr-splitter-pane size="75" id="main_rightPane" class="rightPane">\n        <div grr-splitter orientation="horizontal" class="rightSplitterContainer">\n\n          <div grr-splitter-pane id="content_rightPane" class="rightTopPane">\n            <grr-file-table view-mode="controller.viewMode" />\n          </div>\n\n          <div grr-splitter-pane id="main_bottomPane" class="rightBottomPane">\n            <grr-file-details current-tab="controller.tab" />\n          </div>\n\n        </div>\n      </div>\n    </div>\n\n  </grr-file-context>\n\n</grr-check-client-access>\n');
$templateCache.put("/client/virtual-file-system/r-we-owned-button-modal.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h3 class="modal-title">Are we owned?</h3>\n</div>\n<div class="modal-body">\n  <p class="text-info">\n    {$ phrase $}\n  </p>\n</div>\n<div class="modal-footer">\n  <button ng-if="!controller.done"\n          class="btn btn-default" ng-click="$dismiss()" name="Cancel">\n    Cancel\n  </button>\n</div>\n');
$templateCache.put("/client/virtual-file-system/r-we-owned-button.html",'<button class="btn btn-default"\n        title="Is this machine pwned?"\n        style="position: relative"\n        ng-click="controller.onClick()">\n  <img src="/static/images/stock_dialog_question.png" class="toolbar_icon">\n</button>\n');$templateCache.put("/client/virtual-file-system/recursive-list-button-modal.html",'<div class="modal-header">\n  <button type="button" class="close" ng-click="$dismiss()">\n    <span aria-hidden="true">&times;</span>\n    <span class="sr-only">Close</span>\n  </button>\n  <h3 class="modal-title">Recursive Directory Refresh</h3>\n</div>\n<div class="modal-body">\n  <grr-form-proto value="controller.refreshOperation"\n                  visible-fields="[\'max_depth\']">\n  </grr-form-proto>\n\n  <div class="aler alert-success padded" role="alert"\n       ng-if="controller.done && !controller.error">\n    Refresh started successfully!\n  </div>\n\n  <div class="aler alert-danger padded" role="alert"\n       ng-if="controller.done && controller.error">\n    {$ controller.error $}\n  </div>\n</div>\n<div class="modal-footer">\n  <button ng-if="!controller.done"\n          class="btn btn-default" ng-click="$dismiss()" name="Cancel">\n    Cancel\n  </button>\n  <button ng-if="controller.done"\n          class="btn btn-default" ng-click="$dismiss()" name="Close">\n    Close\n  </button>\n  <button class="btn btn-primary" ng-if="!controller.requestSent"\n          ng-click="controller.createRefreshOperation()"\n          name="Proceed">\n    Refresh\n  </button>\n</div>\n');
$templateCache.put("/client/virtual-file-system/recursive-list-button.html",'<button class="btn btn-default"\n        title="Recursively refresh this directory (sync its listing with the client)"\n        style="position: relative"\n        name="RecursiveRefresh"\n        ng-click="controller.onClick()"\n        ng-disabled="controller.lastOperationId">\n  <img src="/static/images/stock_refresh.png" class="toolbar_icon">\n  <span style="position: absolute; left: 23px; top: 5px; font-weight: bold;\n               font-size: 18px; -webkit-text-stroke: 1px #000; color: #fff">R</span>\n</button>\n');
$templateCache.put("/client/virtual-file-system/vfs-files-archive-button.html",'<span uib-dropdown>\n  <div class="btn-group large" uib-dropdown-toggle>\n    <button type="button" class="btn btn-default">\n      <i class="fa fa-file-o"></i>\n      <i class="fa fa-arrow-circle-down annotation"></i>\n    </button>\n    <button type="button" class="btn btn-default dropdown-toggle">\n      <span class="caret"></span>\n    </button>\n  </div>\n  <ul class="dropdown-menu" uib-dropdown-menu>\n    <li ng-class="{\'disabled\': controller.downloadCurrentFolderDisabled}">\n      <a name="downloadCurrentFolder"\n         ng-click="controller.downloadCurrentFolder($event)"\n         href="#">\n        Download files collected in <strong>this folder and below</strong>\n      </a>\n    </li>\n    <li ng-class="{\'disabled\': controller.downloadEverythingDisabled}">\n      <a name="downloadEverything"\n         ng-click="controller.downloadEverything($event)"\n         href="#">\n        Download <strong>all</strong> files collected from this client\n      </a>\n    </li>\n  </ul>\n</span>\n');
$templateCache.put("/cron/new-cron-job-wizard/configure-schedule-page.html","<div class=\"padded\">\n  <grr-form-proto value=\"cronJobArgs\"\n                  visible-fields=\"['description', 'periodicity', 'lifetime', 'allow_overruns']\">\n  </grr-form-proto>\n</div>\n");$templateCache.put("/cron/new-cron-job-wizard/form.html",'<grr-wizard-form title="Schedule Cron Hunt" on-resolve="onResolve()" on-reject="onReject()">\n\n  \x3c!-- Configure schedule --\x3e\n  <grr-wizard-form-page\n      title="Cron Job properties"\n      is-valid="controller.huntRunnerArgs.value.client_rule_set">\n\n    <grr-configure-schedule-page cron-job-args="createCronJobArgs">\n    </grr-configure-schedule-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure flow --\x3e\n  <grr-wizard-form-page title="What to run?"\n                        is-valid="createCronJobArgs.value.flow_name.value">\n\n    <grr-configure-flow-page flow-name="createCronJobArgs.value.flow_name.value"\n                             flow-arguments="createCronJobArgs.value.flow_args"\n                             hunt-runner-args="controller.huntRunnerArgs">\n    </grr-configure-flow-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure hunt --\x3e\n  <grr-wizard-form-page title="Hunt parameters"\n                        help-link="/help/investigating-with-grr/hunts/limits.html">\n\n    <grr-configure-hunt-page hunt-runner-args="createCronJobArgs.value.hunt_runner_args">\n    </grr-configure-hunt-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure output plugins --\x3e\n  <grr-wizard-form-page title="Define Output Processing">\n\n    <grr-configure-output-plugins-page output-plugins="controller.huntRunnerArgs.value.output_plugins">\n    </grr-configure-output-plugins-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure rules --\x3e\n  <grr-wizard-form-page title="Where to run?">\n\n    <grr-configure-rules-page\n        client-rule-set="controller.huntRunnerArgs.value.client_rule_set">\n    </grr-configure-rules-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Review --\x3e\n  <grr-wizard-form-page title="Review"\n                        next-button-label="Schedule Hunt">\n\n    <grr-new-cron-job-review-page cron-job-args="createCronJobArgs">\n    </grr-new-cron-job-review-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Submit the hunt and show the status --\x3e\n  <grr-wizard-form-page title="Result"\n                        is-valid="controller.serverResponse != null"\n                        on-show="controller.sendRequest()"\n                        next-button-label="Done"\n                        no-back-button="true">\n\n    <grr-new-cron-job-status-page response="controller.serverResponse">\n    </grr-new-cron-job-status-page>\n\n  </grr-wizard-form-page>\n\n</grr-wizard-form>\n');
$templateCache.put("/cron/new-cron-job-wizard/review-page.html",'<div class="padded" grr-force-refresh refresh-trigger="cronJobArgs">\n\n  <dl class="dl-horizontal">\n    <dt>Scheduling</dt>\n    <dd>\n      <grr-semantic-proto value="cronJobArgs"\n                          visible-fields="[\'description\', \'periodicity\', \'lifetime\', \'allow_overruns\']">\n      </grr-semantic-proto>\n    </dd>\n  </dl>\n\n  <dl class="dl-horizontal">\n    <dt>Hunt Flow Name</dt>\n    <dd>\n      <grr-semantic-value value="cronJobArgs.value.flow_name">\n      </grr-semantic-value>\n    </dd>\n    <dt>Hunt Flow Arguments</dt>\n    <dd>\n      <grr-semantic-value value="cronJobArgs.value.flow_args">\n      </grr-semantic-value>\n    </dd>\n  </dl>\n\n  <dl class="dl-horizontal">\n    <dt>Hunt Runner Arguments</dt>\n    <dd>\n      <grr-semantic-value value="cronJobArgs.value.hunt_runner_args">\n      </grr-semantic-value>\n    </dd>\n  </dl>\n\n</div>\n');
$templateCache.put("/cron/new-cron-job-wizard/status-page.html",'<div class="padded">\n\n  <div ng-if="!response">\n    <uib-progressbar class="progress-striped active" max="100" value="50">\n      Creating cron job...\n    </uib-progressbar>\n  </div>\n\n  <div ng-if="response && response.error" class="alert alert-error">\n    <p><em>Can\'t create cron job:</em></p>\n    <p class="preserve-linebreaks">{$ response.data $}</p>\n  </div>\n\n  <div ng-if="response && !response.error" class="panel panel-default">\n    <div class="panel-body">\n      <p>\n        Created Cron Job:\n        <grr-semantic-value value="response.data"></grr-semantic-value>\n      </p>\n    </div>\n  </div>\n\n</div>\n');
$templateCache.put("/hunt/new-hunt-wizard/configure-flow-page.html",'<grr-flow-descriptors-tree selected-descriptor="controller.flowDescriptor" />\n\n<div class="flow-configuration-pane">\n  <div class="padded">\n    <div ng-if="flowArguments != null">\n      <legend>{$ flowName $}</legend>\n\n      <grr-form-value value="flowArguments">\n      </grr-form-value>\n\n      <br>\n      <legend>Description</legend>\n      <grr-flow-info descriptor="controller.flowDescriptor" />\n    </div>\n\n    <span ng-if="flowArguments == null">\n      Please select a flow from the tree on the left.\n    </span>\n  </div>\n\n</div>\n\n');
$templateCache.put("/hunt/new-hunt-wizard/configure-hunt-page.html",'<div class="padded">\n  <grr-form-proto value="huntRunnerArgs"\n                  hidden-fields="[\'hunt_name\', \'client_rule_set\']">\n  </grr-form-proto>\n</div>\n');$templateCache.put("/hunt/new-hunt-wizard/configure-output-plugins-page.html",'<div class="padded">\n  <grr-form-proto-repeated-field\n     descriptor="controller.outputPluginDescriptor"\n     field="controller.outputPluginsField"\n     value="outputPlugins">\n  </grr-form-proto-repeated-field>\n</div>\n');
$templateCache.put("/hunt/new-hunt-wizard/configure-rules-page.html",'<div class="padded">\n  <grr-form-value value="clientRuleSet"></grr-form-value>\n\n  <h3 class="text-center" ng-if="!clientRuleSet.value.rules ||\n                              clientRuleSet.value.rules.length == 0">\n    No rules specified!\n    <span ng-if="!clientRuleSet.value.match_mode.value ||\n                 clientRuleSet.value.match_mode.value == \'MATCH_ALL\'">\n      The hunt will run on all clients.\n    </span>\n    <span ng-if="clientRuleSet.value.match_mode.value &&\n                 clientRuleSet.value.match_mode.value == \'MATCH_ANY\'">\n      The hunt won\'t run on any client.\n    </span>\n  </h3>\n</div>\n');
$templateCache.put("/hunt/new-hunt-wizard/copy-form.html",'<div class="padded" ng-if="controller.createHuntArgs === undefined">\n  Loading...\n</div>\n\n<grr-new-hunt-wizard-form\n   ng-if="controller.createHuntArgs !== undefined"\n\n   on-resolve="onResolve()"\n   on-reject="onReject()"\n   create-hunt-args="controller.createHuntArgs">\n</grr-new-hunt-wizard-form>\n');$templateCache.put("/hunt/new-hunt-wizard/create-hunt-from-flow-form.html",'<div class="padded" ng-if="controller.createHuntArgs === undefined">\n  Loading...\n</div>\n\n<grr-new-hunt-wizard-form\n   ng-if="controller.createHuntArgs !== undefined"\n\n   on-resolve="onResolve({huntId: huntId})"\n   on-reject="onReject()"\n   create-hunt-args="controller.createHuntArgs">\n\n</grr-new-hunt-wizard-form>\n');
$templateCache.put("/hunt/new-hunt-wizard/form.html",'<grr-wizard-form title="New Hunt" on-resolve="controller.resolve()" on-reject="onReject()">\n\n  \x3c!-- Configure flow --\x3e\n  <grr-wizard-form-page title="What to run?"\n                        is-valid="createHuntArgs.value.flow_name.value &&\n                                  !controller.configureFlowPageHasErrors">\n\n    <grr-configure-flow-page flow-name="createHuntArgs.value.flow_name.value"\n                             flow-arguments="createHuntArgs.value.flow_args"\n                             has-errors="controller.configureFlowPageHasErrors">\n    </grr-configure-flow-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure hunt --\x3e\n  <grr-wizard-form-page title="Hunt parameters"\n                        help-link="/help/investigating-with-grr/hunts/limits.html">\n    <grr-configure-hunt-page hunt-runner-args="createHuntArgs.value.hunt_runner_args">\n    </grr-configure-hunt-page>\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure output plugins --\x3e\n  <grr-wizard-form-page title="How to process results?">\n\n    <grr-configure-output-plugins-page\n      output-plugins="createHuntArgs.value.hunt_runner_args.value.output_plugins">\n    </grr-configure-output-plugins-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Configure rules --\x3e\n  <grr-wizard-form-page title="Where to run?"\n                        help-link="/help/investigating-with-grr/hunts/rules.html">\n\n    <grr-configure-rules-page\n        client-rule-set="createHuntArgs.value.hunt_runner_args.value.client_rule_set">\n    </grr-configure-rules-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Review --\x3e\n  <grr-wizard-form-page title="Review"\n                        next-button-label="Create Hunt">\n\n    <grr-new-hunt-review-page create-hunt-args="createHuntArgs">\n    </grr-new-hunt-review-page>\n\n  </grr-wizard-form-page>\n\n  \x3c!-- Submit the hunt and show the status --\x3e\n  <grr-wizard-form-page title="Result"\n                        is-valid="controller.serverResponse != null"\n                        on-show="controller.sendRequest()"\n                        next-button-label="Done"\n                        no-back-button="true">\n\n    <grr-new-hunt-status-page response="controller.serverResponse">\n    </grr-new-hunt-status-page>\n\n  </grr-wizard-form-page>\n\n</grr-wizard-form>\n');
$templateCache.put("/hunt/new-hunt-wizard/review-page.html",'<div class="padded" grr-force-refresh refresh-trigger="createHuntArgs">\n  <grr-rapid-hunt-status flow-name="createHuntArgs.value.flow_name.value"\n                         flow-args="createHuntArgs.value.flow_args"\n                         client-rate="createHuntArgs.value.hunt_runner_args.value.client_rate.value"\n                         is-eligible="controller.isRapidHuntEligible">\n  </grr-rapid-hunt-status>\n\n  <grr-semantic-value value="createHuntArgs"></grr-semantic-value>\n</div>\n');
$templateCache.put("/hunt/new-hunt-wizard/status-page.html",'<div class="padded">\n\n  <div ng-if="!response">\n    <uib-progressbar class="progress-striped active" max="100" value="50">\n      Creating hunt...\n    </uib-progressbar>\n  </div>\n\n  <div ng-if="response && response.error" class="alert alert-error">\n    <p><em>Can\'t create hunt:</em></p>\n    <p class="preserve-linebreaks">{$ response.data $}</p>\n  </div>\n\n  <div ng-if="response && !response.error" class="panel panel-default">\n    <div class="panel-body">\n      <p>\n        Created Hunt:\n        <grr-semantic-value value="response.data.value.hunt_id"></grr-semantic-value>\n      </p>\n      <p>\n        Hunt arguments:<br/>\n        <grr-semantic-value value="response.data.value.hunt_args"></grr-semantic-value>\n      </p>\n      <p>\n        Runner arguments:<br/>\n        <grr-semantic-value value="response.data.value.hunt_runner_args"></grr-semantic-value>\n      </p>\n    </div>\n  </div>\n\n</div>\n');
$templateCache.put("/semantic/pseudo/fetch-more-link.html",'<a ng-if="!continuationShown" ng-click="onClick($event)">\n  More items available...\n</a>\n<grr-semantic-value ng-if="::continuationShown" value="::value.value" />\n')}]);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.utils");goog.module.declareLegacyNamespace();exports.CLIENT_ID_RE=/^C\.[0-9a-fA-F]{16}$/;exports.camelCaseToDashDelimited=function(input){return input.replace(/\W+/g,"-").replace(/([A-Z])/g,"-$1").replace(/^-+/,"").replace(/-+$/,"").toLowerCase()};exports.upperCaseToTitleCase=function(input){return(input.charAt(0).toUpperCase()+input.slice(1).toLowerCase()).replace(/_/g," ")};exports.stringToList=function(input){var result=[];
angular.forEach((input||"").split(","),function(item){item=item.trim();if(item)result.push(item)});return result};exports.stripAff4Prefix=function(input){var aff4Prefix="aff4:/";if(input.toLowerCase().indexOf(aff4Prefix)==0)return input.substr(aff4Prefix.length);else return input};exports.getLastPathComponent=function(input){var components=input.split("/");return components[components.length-1]};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.acl.requestApprovalDialogDirective");goog.module.declareLegacyNamespace();const {stringToList}=goog.require("grrUi.core.utils");const RequestApprovalDialogController=function($scope,$q,grrApiService){this.scope_=$scope;this.q_=$q;this.grrApiService_=grrApiService;this.subjectTitle;this.ccAddresses=[];this.recentReasons;this.selectedRecentReason;this.approversList;this.reason;this.useCcAddresses=true;this.keepClientAlive=true;this.scope_.$watch("approvalType",
this.onApprovalTypeChange_.bind(this));this.scope_.$watch("controller.selectedRecentReason",this.onSelectedRecentReasonChange_.bind(this));this.grrApiService_.getCached("/config/Email.approval_optional_cc_address").then(this.onCcAddressResponse_.bind(this));this.grrApiService_.get("/users/me/approvals/client",{count:7}).then(this.onLatestApprovalsResponse_.bind(this))};RequestApprovalDialogController.prototype.onApprovalTypeChange_=function(newValue){if(angular.isString(newValue))this.subjectTitle=
newValue.charAt(0).toUpperCase()+newValue.slice(1).replace("-"," ")};RequestApprovalDialogController.prototype.onSelectedRecentReasonChange_=function(newValue){if(angular.isString(newValue)&&newValue)this.reason=newValue};RequestApprovalDialogController.prototype.onCcAddressResponse_=function(response){this.ccAddresses=stringToList(response["data"]["value"]["value"])};RequestApprovalDialogController.prototype.onLatestApprovalsResponse_=function(response){this.recentReasons=[];var items=response["data"]["items"];
for(var i=0;i<items.length;++i){var reason=items[i]["value"]["reason"]["value"];if(this.recentReasons.indexOf(reason)===-1)this.recentReasons.push(reason)}};RequestApprovalDialogController.prototype.proceed=function(){var deferred=this.q_.defer();var url=this.scope_["createRequestUrl"];var args=angular.copy(this.scope_["createRequestArgs"]);args["approval"]["reason"]=this.reason;args["approval"]["notified_users"]=stringToList(this.approversList);if(this.useCcAddresses&&this.ccAddresses)args["approval"]["email_cc_addresses"]=
this.ccAddresses;if(this.scope_["approvalType"]==="client"&&this.keepClientAlive)args["keep_client_alive"]=true;this.grrApiService_.post(url,args).then(function success(){deferred.resolve("Approval request was sent.")},function failure(response){deferred.reject(response["data"]["message"])});return deferred.promise};exports.RequestApprovalDialogDirective=function(){return{scope:{approvalType:"=",createRequestUrl:"=",createRequestArgs:"=",accessErrorDescription:"="},restrict:"E",templateUrl:"/static/angular-components/acl/"+
"request-approval-dialog.html",controller:RequestApprovalDialogController,controllerAs:"controller"}};exports.RequestApprovalDialogDirective.directive_name="grrRequestApprovalDialog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.acl.aclDialogService");goog.module.declareLegacyNamespace();const {RequestApprovalDialogDirective}=goog.require("grrUi.acl.requestApprovalDialogDirective");const {stripAff4Prefix}=goog.require("grrUi.core.utils");exports.AclDialogService=function($rootScope,grrDialogService){this.rootScope_=$rootScope;this.grrDialogService_=grrDialogService};var AclDialogService=exports.AclDialogService;AclDialogService.service_name="grrAclDialogService";
AclDialogService.prototype.openRequestApprovalDialog=function(approvalType,createRequestUrl,createRequestArgs,opt_accessErrorDescription){$(".modal-dialog:visible").each(function(){$(this).scope()["$parent"]["$dismiss"]()});var directive=RequestApprovalDialogDirective;return this.grrDialogService_.openDirectiveDialog(directive.directive_name,{approvalType:approvalType,createRequestUrl:createRequestUrl,createRequestArgs:createRequestArgs,accessErrorDescription:opt_accessErrorDescription})};AclDialogService.prototype.openRequestClientApprovalDialog=
function(clientId,opt_accessErrorDescription){return this.openRequestApprovalDialog("client","/users/me/approvals/client/"+clientId,{client_id:clientId,approval:{}},opt_accessErrorDescription)};AclDialogService.prototype.openRequestHuntApprovalDialog=function(huntId,opt_accessErrorDescription){return this.openRequestApprovalDialog("hunt","/users/me/approvals/hunt/"+huntId,{hunt_id:huntId,approval:{}},opt_accessErrorDescription)};AclDialogService.prototype.openRequestCronJobApprovalDialog=function(cronJobId,
opt_accessErrorDescription){return this.openRequestApprovalDialog("cron-job","/users/me/approvals/cron-job/"+cronJobId,{cron_job_id:cronJobId,approval:{}},opt_accessErrorDescription)};AclDialogService.prototype.openApprovalDialogForSubject=function(subject,message){var components=stripAff4Prefix(subject).split("/");if(/^C\.[0-9a-fA-F]{16}$/.test(components[0]))this.openRequestClientApprovalDialog(components[0],message);else if(components[0]=="hunts")this.openRequestHuntApprovalDialog(components[1],
message);else if(components[0]=="cron")this.openRequestCronJobApprovalDialog(components[1],message);else throw new Error("Can't determine type of resources.");};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.apiService");goog.module.declareLegacyNamespace();var UNAUTHORIZED_API_RESPONSE_EVENT="UnauthorizedApiResponse";exports.UNAUTHORIZED_API_RESPONSE_EVENT=UNAUTHORIZED_API_RESPONSE_EVENT;exports.encodeUrlPath=function(urlPath){var components=urlPath.split("/");var encodedComponents=components.map(encodeURIComponent);return encodedComponents.join("/")};var encodeUrlPath=exports.encodeUrlPath;exports.stripTypeInfo=function(richlyTypedValue){var recursiveStrip=
function(value){if(angular.isArray(value))value=value.map(recursiveStrip);else if(angular.isDefined(value.value)){value=value.value;if(angular.isObject(value))for(var k in value)value[k]=recursiveStrip(value[k])}return value};return recursiveStrip(angular.copy(richlyTypedValue))};var stripTypeInfo=exports.stripTypeInfo;var wrapCancellablePromise_=function(promise){var cancel=promise["cancel"];if(angular.isUndefined(promise["_oldThen"])){promise["_oldThen"]=promise["then"];promise["then"]=function(onFulfilled,
onRejected,progressBack){var result=promise["_oldThen"](onFulfilled,onRejected,progressBack);result["cancel"]=cancel;return wrapCancellablePromise_(result)}}if(angular.isUndefined(promise["_oldCatch"])){promise["_oldCatch"]=promise["catch"];promise["catch"]=function(callback){var result=promise["_oldCatch"](callback);result["cancel"]=cancel;return wrapCancellablePromise_(result)}}if(angular.isUndefined(promise["_oldFinally"])){promise["_oldFinally"]=promise["finally"];promise["finally"]=function(callback,
progressBack){var result=promise["_oldFinally"](callback,progressBack);result["cancel"]=cancel;return wrapCancellablePromise_(result)}}return promise};exports.ApiService=function($http,$q,$interval,$rootScope,grrLoadingIndicatorService){this.http_=$http;this.q_=$q;this.interval_=$interval;this.rootScope_=$rootScope;this.grrLoadingIndicatorService_=grrLoadingIndicatorService;this.authDeferred_=this.q_.defer()};var ApiService=exports.ApiService;ApiService.service_name="grrApiService";ApiService.prototype.waitForAuth_=
function(fn){return this.authDeferred_.promise.then(function(){return fn()})};ApiService.prototype.markAuthDone=function(){this.authDeferred_.resolve()};ApiService.prototype.sendRequestWithoutPayload_=function(method,apiPath,opt_params,opt_requestSettings){var requestParams=angular.extend({},opt_params);var requestSettings=angular.extend({},opt_requestSettings);var loadingKey=this.grrLoadingIndicatorService_.startLoading();var apiPrefix="/api/";if(requestSettings["useV2"])apiPrefix+="v2/";var url=
encodeUrlPath(apiPrefix+apiPath.replace(/^\//,""));return this.waitForAuth_(function(){var promise=this.http_({method:method,url:url,params:requestParams,cache:requestSettings["cache"]});return promise.finally(function(){this.grrLoadingIndicatorService_.stopLoading(loadingKey)}.bind(this))}.bind(this))};ApiService.prototype.head=function(apiPath,opt_params){return this.sendRequestWithoutPayload_("HEAD",apiPath,opt_params)};ApiService.prototype.get=function(apiPath,opt_params){return this.sendRequestWithoutPayload_("GET",
apiPath,opt_params)};ApiService.prototype.getV2=function(apiPath,opt_params){return this.sendRequestWithoutPayload_("GET",apiPath,opt_params,{"useV2":true})};ApiService.prototype.getCached=function(apiPath,opt_params){return this.sendRequestWithoutPayload_("GET",apiPath,opt_params,{cache:true})};ApiService.prototype.getV2Cached=function(apiPath,opt_params){return this.sendRequestWithoutPayload_("GET",apiPath,opt_params,{cache:true,useV2:true})};ApiService.prototype.poll=function(apiPath,intervalMs,
opt_params,opt_checkFn){if(angular.isUndefined(opt_checkFn))opt_checkFn=function(response){return response["data"]["state"]==="FINISHED"}.bind(this);var result=this.q_.defer();var inProgress=false;var cancelled=false;var pollIteration=function(){inProgress=true;this.get(apiPath,opt_params).then(function success(response){if(cancelled)return;result.notify(response);if(opt_checkFn(response))result.resolve(response)}.bind(this),function failure(response){if(cancelled)return;result.reject(response)}.bind(this)).finally(function(){if(cancelled)return;
inProgress=false}.bind(this))}.bind(this);pollIteration();var intervalPromise=this.interval_(function(){if(!inProgress)pollIteration()}.bind(this),intervalMs);result.promise["cancel"]=function(){cancelled=true;this.interval_.cancel(intervalPromise)}.bind(this);result.promise.finally(result.promise["cancel"]);return wrapCancellablePromise_(result.promise)};ApiService.prototype.cancelPoll=function(pollPromise){if(angular.isDefined(pollPromise)){if(angular.isUndefined(pollPromise["cancel"]))throw new Error("Invalid promise to cancel: not cancelable.");
pollPromise["cancel"]()}};ApiService.prototype.downloadFile=function(apiPath,opt_params){var requestParams=angular.extend({},opt_params);var url=encodeUrlPath("/api/"+apiPath.replace(/^\//,""));return this.http_.head(url,{params:requestParams}).then(function(){var paramsString=Object.keys(requestParams).sort().map(function(key){return[key,requestParams[key]].map(encodeURIComponent).join("=")}).join("&");if(paramsString.length>0)url+="?"+paramsString;var deferred=this.q_.defer();var iframe=document.createElement("iframe");
iframe.src=url;angular.element(iframe).addClass("grr-binary-download");document.body.appendChild(iframe);var intervalPromise=this.interval_(function(){try{if(iframe.contentWindow.document.readyState==="complete"){this.interval_.cancel(intervalPromise);deferred.resolve()}}catch(err){deferred.reject({data:{message:"Unknown error."}})}}.bind(this),500);return deferred.promise.finally(function(){this.interval_.cancel(intervalPromise)}.bind(this))}.bind(this),function failure(response){if(response.status==
403){var headers=response.headers();this.rootScope_.$broadcast(UNAUTHORIZED_API_RESPONSE_EVENT,{subject:headers["x-grr-unauthorized-access-subject"],reason:headers["x-grr-unauthorized-access-reason"]})}return this.q_.reject(response)}.bind(this))};ApiService.prototype.sendRequestWithPayload_=function(httpMethod,apiPath,opt_params,opt_stripTypeInfo,opt_files){if(opt_stripTypeInfo)opt_params=stripTypeInfo(opt_params);var request;if(angular.equals(opt_files||{},{}))request={method:httpMethod,url:encodeUrlPath("/api/"+
apiPath.replace(/^\//,"")),data:opt_params,headers:{}};else{var fd=new FormData;angular.forEach(opt_files,function(value,key){fd.append(key,value)}.bind(this));fd.append("_params_",angular.toJson(opt_params||{}));request={method:httpMethod,url:encodeUrlPath("/api/"+apiPath.replace(/^\//,"")),data:fd,transformRequest:angular.identity,headers:{"Content-Type":undefined}}}return this.waitForAuth_(function(){var loadingKey=this.grrLoadingIndicatorService_.startLoading();var promise=this.http_(request);
return promise.finally(function(){this.grrLoadingIndicatorService_.stopLoading(loadingKey)}.bind(this))}.bind(this))};ApiService.prototype.post=function(apiPath,opt_params,opt_stripTypeInfo,opt_files){return this.sendRequestWithPayload_("POST",apiPath,opt_params,opt_stripTypeInfo,opt_files)};ApiService.prototype.delete=function(apiPath,opt_params,opt_stripTypeInfo){return this.sendRequestWithPayload_("DELETE",apiPath,opt_params,opt_stripTypeInfo)};ApiService.prototype.patch=function(apiPath,opt_params,
opt_stripTypeInfo){return this.sendRequestWithPayload_("PATCH",apiPath,opt_params,opt_stripTypeInfo)};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.acl.approvalInfoDirective");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const ApprovalInfoController=function($scope,$attrs,grrApiService){this.scope_=$scope;this.attrs_=$attrs;this.grrApiService_=grrApiService;this.fetchUrl;this.grantUrl;this.approvalTypeTitle;this.approvalObject;this.requestSent;this.statusMessage;this.scope_.$watchGroup(["approvalType","objectId","approvalId"],
this.onParamsChanged_.bind(this));this.scope_.$watch("controller.fetchUrl",this.onApprovalFetchUrlChanged_.bind(this))};ApprovalInfoController.prototype.onParamsChanged_=function(){if(angular.isString(this.scope_["approvalType"])&&angular.isString(this.scope_["username"])&&angular.isString(this.scope_["objectId"])&&angular.isString(this.scope_["approvalId"])){this.approvalTypeTitle=this.scope_["approvalType"].replace("-"," ");this.fetchUrl=["users",this.scope_["username"],"approvals",this.scope_["approvalType"],
this.scope_["objectId"],this.scope_["approvalId"]].join("/");this.grantUrl=this.fetchUrl+"/actions/grant"}};ApprovalInfoController.prototype.onApprovalFetchUrlChanged_=function(){this.approvalObject=null;if(angular.isString(this.fetchUrl))this.grrApiService_.get(this.fetchUrl).then(function(response){if(this.attrs_["approvalObject"])this.scope_["approvalObject"]=response["data"];this.approvalObject=stripTypeInfo(response["data"]);if(this.approvalObject["is_valid"]){this.requestSent=true;this.statusMessage=
"This approval has already been granted!"}}.bind(this))};ApprovalInfoController.prototype.onClick=function(){if(!angular.isObject(this.approvalObject))return;this.requestSent=true;this.grrApiService_.post(this.grantUrl).then(function success(){this.statusMessage="Approval granted."}.bind(this),function failure(response){this.statusMessage="FAILURE: "+response["data"]["message"]}.bind(this))};exports.ApprovalInfoDirective=function(){return{scope:{approvalType:"=",username:"=",objectId:"=",approvalId:"=",
approvalObject:"="},restrict:"E",templateUrl:"/static/angular-components/acl/approval-info.html",controller:ApprovalInfoController,controllerAs:"controller"}};exports.ApprovalInfoDirective.directive_name="grrApprovalInfo";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.acl.clientApprovalViewDirective");goog.module.declareLegacyNamespace();const ClientApprovalViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.username;this.clientId;this.approvalId;this.grrRoutingService_.uiOnParamsChanged(this.scope_,["username","clientId","approvalId"],function(params){this.username=params[0];this.clientId=params[1];this.approvalId=params[2]}.bind(this))};
exports.ClientApprovalViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/acl/client-approval-view.html",controller:ClientApprovalViewController,controllerAs:"controller"}};exports.ClientApprovalViewDirective.directive_name="grrClientApprovalView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.acl.cronJobApprovalViewDirective");goog.module.declareLegacyNamespace();const CronJobApprovalViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.username;this.cronJobId;this.approvalId;this.grrRoutingService_.uiOnParamsChanged(this.scope_,["username","cronJobId","approvalId"],function(params){this.username=params[0];this.cronJobId=params[1];this.approvalId=params[2]}.bind(this))};
exports.CronJobApprovalViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/acl/cron-job-approval-view.html",controller:CronJobApprovalViewController,controllerAs:"controller"}};exports.CronJobApprovalViewDirective.directive_name="grrCronJobApprovalView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.acl.huntApprovalViewDirective");goog.module.declareLegacyNamespace();const HuntApprovalViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.username;this.huntId;this.approvalId;this.approvalObject;this.grrRoutingService_.uiOnParamsChanged(this.scope_,["username","huntId","approvalId"],function(params){this.username=params[0];this.huntId=params[1];this.approvalId=params[2]}.bind(this))};
exports.HuntApprovalViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/acl/hunt-approval-view.html",controller:HuntApprovalViewController,controllerAs:"controller"}};exports.HuntApprovalViewDirective.directive_name="grrHuntApprovalView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.acl.huntFromFlowCopyReviewDirective");goog.module.declareLegacyNamespace();const HuntFromFlowCopyReviewController=function($scope,grrRoutingService){this.scope_=$scope;this.sourceFlow;this.newFlow;this.scope_.$watchGroup(["sourceFlow","newHunt"],this.onValuesChanged_.bind(this))};HuntFromFlowCopyReviewController.prototype.onValuesChanged_=function(){if(angular.isDefined(this.scope_["sourceFlow"])&&angular.isDefined(this.scope_["newHunt"])){this.sourceFlow=
this.scope_["sourceFlow"];this.newFlow=angular.copy(this.sourceFlow);var newHunt=this.scope_["newHunt"];this.newFlow["value"]["name"]=newHunt["value"]["flow_name"];this.newFlow["value"]["args"]=newHunt["value"]["flow_args"]}};exports.HuntFromFlowCopyReviewDirective=function(){return{scope:{sourceFlow:"=",newHunt:"="},restrict:"E",templateUrl:"/static/angular-components/acl/hunt-from-flow-copy-review.html",controller:HuntFromFlowCopyReviewController,controllerAs:"controller"}};exports.HuntFromFlowCopyReviewDirective.directive_name=
"grrHuntFromFlowCopyReview";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.acl.huntFromHuntCopyReviewDirective");goog.module.declareLegacyNamespace();exports.HuntFromHuntCopyReviewDirective=function(){return{scope:{sourceHunt:"=",newHunt:"="},restrict:"E",templateUrl:"/static/angular-components/acl/hunt-from-hunt-copy-review.html"}};exports.HuntFromHuntCopyReviewDirective.directive_name="grrHuntFromHuntCopyReview";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.acl.acl");goog.module.declareLegacyNamespace();const {AclDialogService}=goog.require("grrUi.acl.aclDialogService");const {ApprovalInfoDirective}=goog.require("grrUi.acl.approvalInfoDirective");const {ClientApprovalViewDirective}=goog.require("grrUi.acl.clientApprovalViewDirective");const {CronJobApprovalViewDirective}=goog.require("grrUi.acl.cronJobApprovalViewDirective");const {HuntApprovalViewDirective}=goog.require("grrUi.acl.huntApprovalViewDirective");
const {HuntFromFlowCopyReviewDirective}=goog.require("grrUi.acl.huntFromFlowCopyReviewDirective");const {HuntFromHuntCopyReviewDirective}=goog.require("grrUi.acl.huntFromHuntCopyReviewDirective");const {RequestApprovalDialogDirective}=goog.require("grrUi.acl.requestApprovalDialogDirective");const {UNAUTHORIZED_API_RESPONSE_EVENT}=goog.require("grrUi.core.apiService");exports.aclModule=angular.module("grrUi.acl",["grrUi.core"]);exports.aclModule.service(AclDialogService.service_name,AclDialogService);
exports.aclModule.directive(ApprovalInfoDirective.directive_name,ApprovalInfoDirective);exports.aclModule.directive(ClientApprovalViewDirective.directive_name,ClientApprovalViewDirective);exports.aclModule.directive(CronJobApprovalViewDirective.directive_name,CronJobApprovalViewDirective);exports.aclModule.directive(HuntApprovalViewDirective.directive_name,HuntApprovalViewDirective);exports.aclModule.directive(HuntFromFlowCopyReviewDirective.directive_name,HuntFromFlowCopyReviewDirective);exports.aclModule.directive(HuntFromHuntCopyReviewDirective.directive_name,
HuntFromHuntCopyReviewDirective);exports.aclModule.directive(RequestApprovalDialogDirective.directive_name,RequestApprovalDialogDirective);exports.aclModule.run(function($rootScope,grrAclDialogService){$rootScope.$on(UNAUTHORIZED_API_RESPONSE_EVENT,function(event,data){grrAclDialogService.openApprovalDialogForSubject(data["subject"],data["reason"])})});return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.artifact.artifactDescriptorDirective");goog.module.declareLegacyNamespace();const ArtifactDescriptorController=function($scope){this.scope_=$scope};exports.ArtifactDescriptorDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/artifact/artifact-descriptor.html",controller:ArtifactDescriptorController,controllerAs:"controller"}};exports.ArtifactDescriptorDirective.directive_name="grrArtifactDescriptor";
exports.ArtifactDescriptorDirective.semantic_type="ArtifactDescriptor";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.artifact.artifactDescriptorsService");goog.module.declareLegacyNamespace();exports.ArtifactDescriptorsService=function($q,grrApiService){this.q_=$q;this.grrApiService_=grrApiService;this.fillCachePromise_;this.descriptorsCache_};var ArtifactDescriptorsService=exports.ArtifactDescriptorsService;ArtifactDescriptorsService.prototype.fillCacheIfNeeded_=function(){if(this.fillCachePromise_)return this.fillCachePromise_;var deferred=this.q_.defer();
if(!angular.isObject(this.descriptorsCache_)){this.grrApiService_.get("/artifacts").then(function success(response){this.descriptorsCache_={};angular.forEach(response["data"]["items"],function(descriptor){var name=descriptor["value"]["artifact"]["value"]["name"]["value"];this.descriptorsCache_[name]=descriptor}.bind(this));deferred.resolve()}.bind(this),function failure(response){deferred.reject(response["data"]["message"])}.bind(this)).finally(function(){this.fillCachePromise_=null}.bind(this));
this.fillCachePromise_=deferred.promise}else deferred.resolve();return deferred.promise};ArtifactDescriptorsService.prototype.listDescriptors=function(){return this.fillCacheIfNeeded_().then(function(){return angular.copy(this.descriptorsCache_)}.bind(this))};ArtifactDescriptorsService.prototype.getDescriptorByName=function(name){return this.fillCacheIfNeeded_().then(function(){return this.descriptorsCache_[name]}.bind(this))};ArtifactDescriptorsService.prototype.clearCache=function(){this.descriptorsCache_=
null};ArtifactDescriptorsService.service_name="grrArtifactDescriptorsService";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.artifact.deleteArtifactsDialogDirective");goog.module.declareLegacyNamespace();const DeleteArtifactsDialogController=function($scope,$q,grrApiService,grrArtifactDescriptorsService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrArtifactDescriptorsService_=grrArtifactDescriptorsService;this.q_=$q};DeleteArtifactsDialogController.prototype.proceed=function(){var deferred=this.q_.defer();this.grrApiService_.delete("/artifacts",
{names:this.scope_["names"]}).then(function success(){deferred.resolve("Artifacts were deleted successfully.");this.grrArtifactDescriptorsService_.clearCache()}.bind(this),function failure(response){deferred.reject(response.data.message)}.bind(this));return deferred.promise};exports.DeleteArtifactsDialogDirective=function(){return{scope:{names:"="},restrict:"E",templateUrl:"/static/angular-components/artifact/"+"delete-artifacts-dialog.html",controller:DeleteArtifactsDialogController,controllerAs:"controller"}};
exports.DeleteArtifactsDialogDirective.directive_name="grrDeleteArtifactsDialog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.artifact.uploadArtifactDialogDirective");goog.module.declareLegacyNamespace();const UploadArtifactDialogController=function($scope,$q,grrApiService,grrArtifactDescriptorsService){this.scope_=$scope;this.q_=$q;this.grrApiService_=grrApiService;this.grrArtifactDescriptorsService_=grrArtifactDescriptorsService;this.artifact=null;this.inProgress=false};UploadArtifactDialogController.prototype.onFileSet=function(files){this.scope_.$apply(()=>
{const reader=new FileReader;reader.onload=event=>{this.artifact=event.target.result};reader.readAsText(files[0],"UTF-8")})};UploadArtifactDialogController.prototype.proceed=function(){var deferred=this.q_.defer();this.inProgress=true;this.grrApiService_.post("/artifacts",{"artifact":this.artifact},false,{}).then(function success(){deferred.resolve("Artifact was successfully uploaded.");this.grrArtifactDescriptorsService_.clearCache()}.bind(this),function failure(response){deferred.reject(response.data.message)}.bind(this));
return deferred.promise};exports.UploadArtifactDialogDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/artifact/"+"upload-artifact-dialog.html",controller:UploadArtifactDialogController,controllerAs:"controller"}};exports.UploadArtifactDialogDirective.directive_name="grrUploadArtifactDialog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.artifact.artifactDialogService");goog.module.declareLegacyNamespace();const {DeleteArtifactsDialogDirective}=goog.require("grrUi.artifact.deleteArtifactsDialogDirective");const {UploadArtifactDialogDirective}=goog.require("grrUi.artifact.uploadArtifactDialogDirective");exports.ArtifactDialogService=function(grrDialogService){this.grrDialogService_=grrDialogService};var ArtifactDialogService=exports.ArtifactDialogService;ArtifactDialogService.service_name=
"grrArtifactDialogService";ArtifactDialogService.prototype.openDeleteArtifacts=function(names){var directive=DeleteArtifactsDialogDirective;return this.grrDialogService_.openDirectiveDialog(directive.directive_name,{names:names})};ArtifactDialogService.prototype.openUploadArtifact=function(){var directive=UploadArtifactDialogDirective;return this.grrDialogService_.openDirectiveDialog(directive.directive_name)};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.artifact.artifactManagerViewDirective");goog.module.declareLegacyNamespace();const ArtifactManagerViewController=function($scope,grrApiService,grrArtifactDialogService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrArtifactDialogService_=grrArtifactDialogService;this.triggerUpdate;this.descriptors=[];this.selectedDescriptors={};this.numSelectedDescriptors=0;this.allDescriptorsSelected=false};ArtifactManagerViewController.prototype.artifactsUrl=
"/artifacts";ArtifactManagerViewController.prototype.transformItems=function(items){this.descriptors=[];angular.forEach(items,function(item){if(item.value.is_custom.value)this.descriptors.push(item)}.bind(this));return this.descriptors};ArtifactManagerViewController.prototype.selectAll=function(){angular.forEach(this.descriptors,function(descriptor){this.selectedDescriptors[descriptor.value.artifact.value.name.value]=this.allDescriptorsSelected}.bind(this));this.updateNumSelectedDescriptors()};ArtifactManagerViewController.prototype.upload=
function(){var result=this.grrArtifactDialogService_.openUploadArtifact();result.then(function resolve(){this.triggerUpdate()}.bind(this))};ArtifactManagerViewController.prototype.deleteSelected=function(){var namesToDelete=[];for(var name in this.selectedDescriptors)if(this.selectedDescriptors[name])namesToDelete.push(name);var result=this.grrArtifactDialogService_.openDeleteArtifacts(namesToDelete);result.then(function resolve(){this.selectedDescriptors={};this.numSelectedDescriptors=0;this.triggerUpdate()}.bind(this))};
ArtifactManagerViewController.prototype.updateNumSelectedDescriptors=function(){var count=0;for(var key in this.selectedDescriptors)if(this.selectedDescriptors[key])++count;this.numSelectedDescriptors=count};exports.ArtifactManagerViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/artifact/"+"artifact-manager-view.html",controller:ArtifactManagerViewController,controllerAs:"controller"}};exports.ArtifactManagerViewDirective.directive_name="grrArtifactManagerView";
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.artifact.artifactNameDirective");goog.module.declareLegacyNamespace();var SYSTEM_ARTIFACT_TYPE="SYSTEM";var USER_ARTIFACT_TYPE="USER";var UNKNOWN_ARTIFACT_TYPE="UNKNOWN";const ArtifactNameController=function($scope,grrArtifactDescriptorsService){this.scope_=$scope;this.grrArtifactDescriptorsService_=grrArtifactDescriptorsService;this.artifactType;this.scope_.$watch("::value",this.onValueChange_.bind(this))};ArtifactNameController.prototype.onValueChange_=
function(newArtifactName){if(!angular.isObject(newArtifactName))return;this.grrArtifactDescriptorsService_.getDescriptorByName(newArtifactName["value"]).then(function(descriptor){if(angular.isDefined(descriptor)){var isCustom=descriptor["value"]["is_custom"]["value"];this.artifactType=isCustom?USER_ARTIFACT_TYPE:SYSTEM_ARTIFACT_TYPE}else this.artifactType=UNKNOWN_ARTIFACT_TYPE}.bind(this))};exports.ArtifactNameDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/artifact/artifact-name.html",
controller:ArtifactNameController,controllerAs:"controller"}};exports.ArtifactNameDirective.directive_name="grrArtifactName";exports.ArtifactNameDirective.semantic_type="ArtifactName";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.artifact.artifactsListFormDirective");goog.module.declareLegacyNamespace();const ArtifactsListFormController=function($scope,grrArtifactDescriptorsService){this.scope_=$scope;this.grrArtifactDescriptorsService_=grrArtifactDescriptorsService;this.descriptorsList=[];this.descriptors;this.descriptorsError;this.selectedName;this.platforms=["","Darwin","Linux","Windows"];this.selectedPlatform="";this.search="";this.searchFilterRef=this.searchFilter.bind(this);
this.platformFilterRef=this.platformFilter.bind(this);this.grrArtifactDescriptorsService_.listDescriptors().then(this.onArtifactsResponse_.bind(this),this.onArtifactsRequestFailure_.bind(this));this.scope_.$watch("controller.descriptors",this.onDescriptorsOrValueChange_.bind(this));this.scope_.$watchCollection("value",this.onDescriptorsOrValueChange_.bind(this))};ArtifactsListFormController.prototype.searchFilter=function(descriptor){return!this.search||descriptor.value.artifact.value.name.value.toLowerCase().indexOf(this.search.toLowerCase())!=
-1};ArtifactsListFormController.prototype.platformFilter=function(descriptor){if(!this.selectedPlatform)return true;var checkOsList=function(osList){for(var i in osList){var os=osList[i];if(os.value==this.selectedPlatform)return true}return false}.bind(this);if(checkOsList(descriptor["value"]["artifact"]["value"]["supported_os"]||[]))return true;var sourceList=descriptor["value"]["artifact"]["value"]["sources"]||[];for(var index in sourceList){var source=sourceList[index];if(checkOsList(source["value"]["supported_os"]||
[]))return true}return false};ArtifactsListFormController.prototype.onArtifactsResponse_=function(descriptors){this.descriptors=descriptors};ArtifactsListFormController.prototype.onArtifactsRequestFailure_=function(error){this.descriptorsError=error};ArtifactsListFormController.prototype.add=function(name){var index=-1;for(var i=0;i<this.scope_.value.length;++i)if(this.scope_.value[i]["value"]==name["value"]){index=i;break}if(index==-1)this.scope_.value.push(name)};ArtifactsListFormController.prototype.remove=
function(name){var index=-1;for(var i=0;i<this.scope_.value.length;++i)if(this.scope_.value[i]["value"]==name["value"]){index=i;break}if(index!=-1)this.scope_.value.splice(index,1)};ArtifactsListFormController.prototype.clear=function(){angular.forEach(angular.copy(this.scope_.value),function(name){this.remove(name)}.bind(this))};ArtifactsListFormController.prototype.onDescriptorsOrValueChange_=function(){if(angular.isDefined(this.descriptors)&&angular.isDefined(this.scope_.value)){this.descriptorsList=
[];angular.forEach(this.descriptors,function(descriptor,name){var index=-1;for(var i=0;i<this.scope_.value.length;++i)if(this.scope_.value[i]["value"]==name){index=i;break}if(index==-1)this.descriptorsList.push(descriptor)}.bind(this))}};exports.ArtifactsListFormDirective=function(){return{restrict:"E",scope:{descriptor:"=",value:"="},templateUrl:"/static/angular-components/artifact/"+"artifacts-list-form.html",controller:ArtifactsListFormController,controllerAs:"controller"}};exports.ArtifactsListFormDirective.directive_name=
"grrArtifactsListForm";exports.ArtifactsListFormDirective.semantic_type="ArtifactName";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.aff4ObjectRepresentationDirective");goog.module.declareLegacyNamespace();var Aff4ObjectRepresentationController=function($scope){this.scope_=$scope;this.scope_.value;this.aff4ObjectRepresentation;this.scope_.$watch("::value",this.onValueChange.bind(this))};Aff4ObjectRepresentationController.prototype.onValueChange=function(){if(angular.isObject(this.scope_.value))this.aff4ObjectRepresentation=this.scope_.value.value;else this.aff4ObjectRepresentation=
this.scope_.value};exports.Aff4ObjectRepresentationDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/core/aff4-object-representation.html",controller:Aff4ObjectRepresentationController,controllerAs:"controller"}};exports.Aff4ObjectRepresentationDirective.directive_name="grrAff4ObjectRepresentation";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.itemsProviderController");goog.module.declareLegacyNamespace();exports.Items;exports.ItemsProviderController=function(){};var ItemsProviderController=exports.ItemsProviderController;ItemsProviderController.prototype.fetchItems=goog.abstractMethod;ItemsProviderController.prototype.fetchFilteredItems=goog.abstractMethod;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.apiItemsProviderDirective");goog.module.declareLegacyNamespace();const {Items,ItemsProviderController}=goog.require("grrUi.core.itemsProviderController");exports.ApiItemsProviderController=function($scope,$attrs,$parse,grrApiService,$log){this.scope_=$scope;this.grrApiService_=grrApiService;this.log_=$log;this.url;this.queryParams;this.transformItems;this.method;$scope.$watch($attrs["url"],function(){this.url=$scope.$eval($attrs["url"])}.bind(this));
if($attrs["queryParams"])$scope.$watch($attrs["queryParams"],function(){this.queryParams=$scope.$eval($attrs["queryParams"])}.bind(this));if($attrs["transformItems"])this.transformItems=$parse($attrs["transformItems"]);if($attrs["method"])this.method=$attrs["method"]};var ApiItemsProviderController=exports.ApiItemsProviderController;ApiItemsProviderController.prototype.fetchItems=function(offset,count,opt_withTotalCount){var params=angular.extend(this.queryParams||{},{"offset":offset,"count":count});
if(this.method==="POST")return this.grrApiService_.post(this.url,params).then(this.onFetchedItems_.bind(this));else return this.grrApiService_.get(this.url,params).then(this.onFetchedItems_.bind(this))};ApiItemsProviderController.prototype.fetchFilteredItems=function(filter,offset,count){var params=angular.extend(this.queryParams||{},{"filter":filter,"offset":offset,"count":count});if(this.method==="POST")return this.grrApiService_.post(this.url,params).then(this.onFetchedItems_.bind(this));else return this.grrApiService_.get(this.url,
params).then(this.onFetchedItems_.bind(this))};ApiItemsProviderController.prototype.onFetchedItems_=function(response){var result={items:response.data["items"]||[],offset:response.data["offset"]};if(angular.isDefined(response.data["total_count"]))result.totalCount=response.data["total_count"];if(angular.isDefined(result.items)&&angular.isDefined(this.transformItems)){try{result.items=this.transformItems(this.scope_,{"items":result.items})}catch(e){this.log_.error("transformItems (on url "+this.url+
") failed: "+e);throw e;}if(angular.isUndefined(result.items)){var errorStr="transform-items function returned undefined";this.log_.error(errorStr);throw new Error(errorStr);}}return result};exports.ApiItemsProviderDirective=function(){return{restrict:"A",priority:2E3,controller:ApiItemsProviderController}};exports.ApiItemsProviderDirective.directive_name="grrApiItemsProvider";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.basenameFilter");goog.module.declareLegacyNamespace();const filterImplementation=function(input){if(!angular.isString(input))return input;else{var components=input.split("/");return components[components.length-1]}};exports.BasenameFilter=function(){return filterImplementation};exports.BasenameFilter.filter_name="grrBasename";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.bindKeyDirective");goog.module.declareLegacyNamespace();const BindKeyController=function($scope,$element,$attrs){this.scope_=$scope;this.element_=$element;this.key_=13;this.callbackExpr_;if($attrs["key"])this.key_=parseInt($attrs["key"],10);if($attrs["grrBindKey"])this.callbackExpr_=$attrs["grrBindKey"];$element.bind("keydown, keypress",this.onKeyDown_.bind(this))};BindKeyController.prototype.onKeyDown_=function(event){if(event["which"]===
this.key_){this.scope_.$apply(function(){this.scope_.$eval(this.callbackExpr_)}.bind(this));event.preventDefault()}};exports.BindKeyDirective=function(){return{restrict:"A",controller:BindKeyController}};exports.BindKeyDirective.directive_name="grrBindKey";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.bytesToHexFilter");goog.module.declareLegacyNamespace();const filterImplementation=function(bytes){var hex="";for(var i=0;i<bytes.length;i+=1){var char=bytes.charCodeAt(i).toString(16);hex+=("0"+char).substr(-2)}return hex};exports.BytesToHexFilter=function(){return function(input){return filterImplementation(input)}};exports.BytesToHexFilter.filter_name="grrBytesToHex";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.canaryOnlyDirective");goog.module.declareLegacyNamespace();const {ApiService}=goog.require("grrUi.core.apiService");var getCanaryModeValue=function(grrApiService,callback){grrApiService.getCached("/users/me").then(function(response){var canaryMode;try{canaryMode=response["data"]["value"]["settings"]["value"]["canary_mode"]["value"]}catch(err){canaryMode=false}callback(canaryMode)})};const CanaryOnlyController=function(grrApiService){this.canaryMode=
false;getCanaryModeValue(grrApiService,canaryMode=>{this.canaryMode=canaryMode})};const NonCanaryOnlyController=function(grrApiService){this.canaryMode=true;getCanaryModeValue(grrApiService,canaryMode=>{this.canaryMode=canaryMode})};exports.CanaryOnlyDirective=function(){return{scope:{},restrict:"E",controller:CanaryOnlyController,controllerAs:"controller",transclude:true,template:"<ng-transclude ng-if='controller.canaryMode'></ng-transclude>"}};exports.CanaryOnlyDirective.directive_name="grrCanaryOnly";
exports.NonCanaryOnlyDirective=function(){return{scope:{},restrict:"E",controller:NonCanaryOnlyController,controllerAs:"controller",transclude:true,template:"<ng-transclude ng-if='!controller.canaryMode'></ng-transclude>"}};exports.NonCanaryOnlyDirective.directive_name="grrNonCanaryOnly";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.clockDirective");goog.module.declareLegacyNamespace();const ClockController=function($scope,$interval,grrTimeService){this.grrTimeService_=grrTimeService;this.formattedClock;this.updateLiveClock_();$interval(this.updateLiveClock_.bind(this),1E3)};ClockController.prototype.updateLiveClock_=function(){this.formattedClock=this.grrTimeService_.formatAsUTC()};exports.ClockDirective=function(){return{scope:{},restrict:"E",template:'<div class="navbar-text pull-right">'+
"{$ controller.formattedClock $}"+"</div>",controller:ClockController,controllerAs:"controller"}};exports.ClockDirective.directive_name="grrLiveClock";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.confirmationDialogDirective");goog.module.declareLegacyNamespace();const ConfirmationDialogController=function($scope,$timeout){this.scope_=$scope;this.timeout_=$timeout;this.error;this.success};ConfirmationDialogController.prototype.proceed=function(){var result=this.scope_.proceed();if(result)result.then(function success(successMessage){this.success=successMessage;if(this.scope_["autoCloseOnSuccess"])this.timeout_(function(){this.close()}.bind(this),
1E3)}.bind(this),function failure(errorMessage){this.error=errorMessage}.bind(this))};ConfirmationDialogController.prototype.dismiss=function(){var curScope=this.scope_;while(curScope&&!curScope["$dismiss"])curScope=curScope.$parent;if(curScope)curScope["$dismiss"]()};ConfirmationDialogController.prototype.close=function(){var curScope=this.scope_;while(curScope&&!curScope["$close"])curScope=curScope.$parent;if(curScope)curScope["$close"]()};exports.ConfirmationDialogDirective=function(){return{scope:{title:"=",
closeName:"=",cancelName:"=",proceedName:"=",proceedClass:"=",proceed:"&",canProceed:"&?",autoCloseOnSuccess:"="},restrict:"E",transclude:true,templateUrl:"/static/angular-components/core/confirmation-dialog.html",controller:ConfirmationDialogController,controllerAs:"controller"}};exports.ConfirmationDialogDirective.directive_name="grrConfirmationDialog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.dialogService");goog.module.declareLegacyNamespace();const {camelCaseToDashDelimited}=goog.require("grrUi.core.utils");exports.DialogService=function($rootScope,$uibModal){this.rootScope_=$rootScope;this.uibModal_=$uibModal};var DialogService=exports.DialogService;DialogService.service_name="grrDialogService";DialogService.prototype.openConfirmation=function(title,message,proceed){var modalScope=this.rootScope_.$new();modalScope.title=
title;modalScope.message=message;modalScope.proceed=proceed;var modalInstance=this.uibModal_.open({template:'<grr-confirmation-dialog title="title" proceed="proceed()" >'+'  <div class="vertically-padded">{$ message $}</div>'+"</grr-confirmation-dialog>",scope:modalScope});return modalInstance.result};DialogService.prototype.openDirectiveDialog=function(directive,opt_params,opt_modalParams){var modalScope=this.rootScope_.$new();var paramString="";var tagName=camelCaseToDashDelimited(directive);if(angular.isDefined(opt_params))angular.forEach(opt_params||
{},function(value,key){modalScope[key]=opt_params[key];paramString+=" "+camelCaseToDashDelimited(key)+'="'+key+'"'});var template="<"+tagName+" "+paramString+' close="$close()" />';var modalParams=angular.extend({template:template,scope:modalScope},opt_modalParams||{});var modalInstance=this.uibModal_.open(modalParams);return modalInstance.result};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.disableIfNoTraitDirective");goog.module.declareLegacyNamespace();const DisableIfNoTraitController=function($attrs,grrApiService){this.attrs_=$attrs;this.grrApiService_=grrApiService;this.traitName_;this.attrs_.$observe("grrDisableIfNoTrait",this.onTraitNameChange_.bind(this))};DisableIfNoTraitController.prototype.onTraitNameChange_=function(newValue){this.traitName_=newValue;if(angular.isUndefined(newValue))this.attrs_.$set("disable",
false);else this.grrApiService_.getCached("users/me").then(this.onUserInfo_.bind(this))};DisableIfNoTraitController.prototype.onUserInfo_=function(response){var traitValue=false;var interfaceTraits=response["data"]["value"]["interface_traits"];if(angular.isDefined(interfaceTraits))if(angular.isDefined(interfaceTraits["value"][this.traitName_]))traitValue=interfaceTraits["value"][this.traitName_]["value"];this.attrs_.$set("disabled",!traitValue)};exports.DisableIfNoTraitDirective=function(){return{scope:{},
restrict:"A",controller:DisableIfNoTraitController,controllerAs:"controller"}};exports.DisableIfNoTraitDirective.directive_name="grrDisableIfNoTrait";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.serverErrorButtonDirective");goog.module.declareLegacyNamespace();var ERROR_EVENT_NAME="ServerError";const ServerErrorButtonController=function($rootScope,$scope,$uibModal){this.rootScope_=$rootScope;this.scope_=$scope;this.uibModal_=$uibModal;this.error;this.buttonVisible;this.rootScope_.$on(ERROR_EVENT_NAME,this.onErrorEvent.bind(this))};ServerErrorButtonController.prototype.onErrorEvent=function(unused_event,error){if(!angular.isObject(error)||
!angular.isString(error.message))return;if(error.message.length){this.error=error;this.buttonVisible=true}else{this.error=null;this.buttonVisible=false}};ServerErrorButtonController.prototype.showError=function(){var modalScope=this.scope_.$new();modalScope.message=this.error.message;modalScope.traceBack=this.error.traceBack;modalScope.close=function(){modalInstance.close()};this.scope_.$on("$destroy",function(){modalScope.$destroy()});var modalInstance=this.uibModal_.open({template:'<grr-server-error-dialog close="close()" message="message" trace-back="traceBack" />',
scope:modalScope,windowClass:"wide-modal high-modal",size:"lg"});modalInstance.result.finally(function(){this.error=null;this.buttonVisible=false}.bind(this))};exports.ServerErrorButtonDirective=function(){return{scope:true,restrict:"E",replace:true,templateUrl:"/static/angular-components/core/server-error-button.html",controller:ServerErrorButtonController,controllerAs:"controller"}};var ServerErrorButtonDirective=exports.ServerErrorButtonDirective;ServerErrorButtonDirective.directive_name="grrServerErrorButton";
ServerErrorButtonDirective.error_event_name=ERROR_EVENT_NAME;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.downloadCollectionAsDirective");goog.module.declareLegacyNamespace();const {ServerErrorButtonDirective}=goog.require("grrUi.core.serverErrorButtonDirective");var ERROR_EVENT_NAME=ServerErrorButtonDirective.error_event_name;const DownloadCollectionAsController=function($rootScope,$scope,grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.grrApiService_=grrApiService;this.pluginToDisplayName={"csv-zip":"CSV (zipped)",
"flattened-yaml-zip":"Flattened YAML (zipped)","sqlite-zip":"SQLite scripts (zipped)"};this.selectedPlugin="csv-zip"};DownloadCollectionAsController.prototype.downloadAs=function(pluginName){var url=this.scope_["baseUrl"]+"/"+pluginName;this.grrApiService_.downloadFile(url).then(function success(){}.bind(this),function failure(response){if(angular.isUndefined(response.status))this.rootScope_.$broadcast(ERROR_EVENT_NAME,{message:"Couldn't download exported results."})}.bind(this))};exports.DownloadCollectionAsDirective=
function(){return{scope:{baseUrl:"="},restrict:"E",templateUrl:"/static/angular-components/core/download-collection-as.html",controller:DownloadCollectionAsController,controllerAs:"controller"}};exports.DownloadCollectionAsDirective.directive_name="grrDownloadCollectionAs";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.downloadCollectionFilesDirective");goog.module.declareLegacyNamespace();exports.valuePointsToFile=function(value){if(value["type"]=="ApiFlowResult"||value["type"]=="ApiHuntResult")value=value["value"]["payload"];if(value["type"]=="StatEntry"||value["type"]=="FileFinderResult"||value["type"]=="ArtifactFilesDownloaderResult")return true;else return false};const DownloadCollectionFilesController=function($scope,$window,grrApiService){this.scope_=
$scope;this.grrApiService_=grrApiService;this.scope_.downloadUrl;this.primaryArchiveExtension;this.secondaryArchiveExtension;this.fileArchiveGenerationStarted;this.fileArchiveGenerationSuccess;this.fileArchiveGenerationError;this.exportCommand;if($window.navigator.appVersion.indexOf("Mac")!=-1){this.primaryArchiveExtension="tar.gz";this.secondaryArchiveExtension="zip"}else{this.primaryArchiveExtension="zip";this.secondaryArchiveExtension="tar.gz"}this.scope_.$watch("exportCommandUrl",function(newValue){if(angular.isUndefined(newValue))return;
this.grrApiService_.get(newValue).then(function(response){if(angular.isDefined(response["data"]["command"]))this.exportCommand=response["data"]["command"]}.bind(this))}.bind(this))};DownloadCollectionFilesController.prototype.generateFileArchive=function(format){var requestFormat=format.toUpperCase().replace(".","_");this.grrApiService_.downloadFile(this.scope_["downloadUrl"],{archive_format:requestFormat}).then(function success(){this.fileArchiveGenerationSuccess=true}.bind(this),function failure(response){this.fileArchiveGenerationError=
response.data["message"]}.bind(this));this.fileArchiveGenerationStarted=true};exports.DownloadCollectionFilesDirective=function(){return{scope:{exportCommandUrl:"=?",downloadUrl:"="},restrict:"E",templateUrl:"/static/angular-components/core/"+"download-collection-files.html",controller:DownloadCollectionFilesController,controllerAs:"controller"}};exports.DownloadCollectionFilesDirective.directive_name="grrDownloadCollectionFiles";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.encodeUriComponentFilter");goog.module.declareLegacyNamespace();exports.EncodeUriComponentFilter=function(){return window.encodeURIComponent};exports.EncodeUriComponentFilter.filter_name="grrEncodeUriComponent";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.firebaseService");goog.module.declareLegacyNamespace();exports.FirebaseService=function($http,grrApiService){this.http_=$http;this.grrApiService_=grrApiService};var FirebaseService=exports.FirebaseService;FirebaseService.service_name="grrFirebaseService";FirebaseService.prototype.setupIfNeeded=function(){if(angular.isUndefined(window.firebase)||firebase.apps.length==0){this.grrApiService_.markAuthDone();return}var firebaseError;
firebase.auth().getRedirectResult().then(function(result){}.bind(this)).catch(function(error){firebaseError=error;this.grrApiService_.markAuthDone()}.bind(this));firebase.auth().onAuthStateChanged(function(user){if(user)user.getToken().then(function(token){this.http_.defaults.headers["common"]["Authorization"]="Bearer "+token;this.grrApiService_.markAuthDone()}.bind(this));else if(!firebaseError){var providerName=firebase.apps[0].options["authProvider"];var provider=new firebase.auth[providerName];
firebase.auth().signInWithRedirect(provider)}}.bind(this))};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.forceRefreshDirective");goog.module.declareLegacyNamespace();const ForceRefreshController=function($scope,$element,$transclude){this.scope_=$scope;this.element_=$element;this.transclude_=$transclude;this.transcludedScope_;this.scope_.$watch("refreshTrigger",this.updateDom_.bind(this),true)};ForceRefreshController.prototype.updateDom_=function(){if(angular.isDefined(this.transcludedScope_)){this.transcludedScope_.$destroy();this.transcludedScope_=
undefined}this.element_.empty();this.transclude_(function(clone,scope){this.element_.empty();this.element_.append(clone);this.transcludedScope_=scope}.bind(this))};exports.ForceRefreshDirective=function(){return{scope:{refreshTrigger:"="},restrict:"EA",transclude:true,controller:ForceRefreshController,controllerAs:"controller"}};exports.ForceRefreshDirective.directive_name="grrForceRefresh";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.hexNumberFilter");goog.module.declareLegacyNamespace();const filterImplementation=function(input){var hex=input.toString(16);var targetLength=Math.ceil(hex.length/8)*8;var leadingZeros=Array(targetLength-hex.length+1).join(0);return"0x"+leadingZeros+hex};exports.HexNumberFilter=function(){return function(input){return filterImplementation(input)}};exports.HexNumberFilter.filter_name="grrHexNumber";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.infiniteTableDirective");goog.module.declareLegacyNamespace();exports.InfiniteTableController=function($scope,$attrs,$element,$interval,$transclude,$parse,$log){this.scope_=$scope;this.attrs_=$attrs;this.element_=$element;this.interval_=$interval;this.transclude_=$transclude;this.log_=$log;this.itemsProvider;this.fetchedItems_=[];this.currentPage_=0;this.showUntilPage_=0;this.updateCounter_=0;this.filterValue_;this.loadingInProgress_=
false;this.autoRefreshInProgress_=false;this.rootElement_=this.element_.parent();this.pageSize_=Number($scope.$eval(this.attrs_["pageSize"]))||InfiniteTableController.DEFAULT_PAGE_SIZE;this.elementScopes_={};var template=angular.element(InfiniteTableController.LOADING_TEMPLATE);this.element_.replaceWith(template);if(angular.isDefined(this.attrs_["triggerUpdate"])){var parsedExpression=$parse(this.attrs_["triggerUpdate"]);parsedExpression.assign(this.scope_,this.triggerUpdate.bind(this))}var loadingTimer=
this.interval_(this.checkIfTableLoadingIsVisible_.bind(this),100);this.scope_.$on("$destroy",function(){this.interval_.cancel(loadingTimer)}.bind(this));this.autoRefreshInterval_=Number($scope.$eval(this.attrs_["autoRefreshInterval"]));if(this.autoRefreshInterval_){var refreshTimer=this.interval_(this.refreshData_.bind(this),this.autoRefreshInterval_);this.scope_.$on("$destroy",function(){this.interval_.cancel(refreshTimer)}.bind(this))}this.scope_.$watch(this.attrs_["filterValue"],this.onFilterChange_.bind(this))};
var InfiniteTableController=exports.InfiniteTableController;InfiniteTableController.DEFAULT_PAGE_SIZE=50;InfiniteTableController.LOADING_TEMPLATE='<tr><td colspan="100" '+'class="table-loading">Loading...</td></tr>';InfiniteTableController.UNIQUE_KEY_NAME="_grrTableKey";InfiniteTableController.ROW_HASH_NAME="_grrTableRowHash";InfiniteTableController.prototype.setFetchedItems_=function(newValue){if(newValue.length!=this.fetchedItems_.length){var loadingElement=$(this.rootElement_).find("tr:has(td.table-loading)");
for(var i=this.fetchedItems_.length;i<newValue.length;++i)this.transclude_(function(clone,scope){scope.item=newValue[i];var key=newValue[i][InfiniteTableController.UNIQUE_KEY_NAME];if(angular.isUndefined(key)&&this.autoRefreshInterval_)this.log_.error("items in infinite table with auto-refresh "+"have to have "+InfiniteTableController.UNIQUE_KEY_NAME+" set");key=key||"";var rowHash=newValue[i][InfiniteTableController.ROW_HASH_NAME];if(angular.isUndefined(rowHash)&&this.autoRefreshInterval_)this.log_.error("items in infinite table with auto-refresh "+
"have to have "+InfiniteTableController.ROW_HASH_NAME+" set");rowHash=rowHash||"";var startComment=document.createComment("-> "+key);var endComment=document.createComment("<- "+key);this.elementScopes_[key]=[startComment,endComment,scope,rowHash];$(startComment).insertBefore(loadingElement);clone.insertBefore(loadingElement);$(endComment).insertBefore(loadingElement)}.bind(this))}this.fetchedItems_=newValue};InfiniteTableController.prototype.triggerUpdate=function(graceful){if(graceful){if(!this.autoRefreshInterval_)throw new Error("graceful refresh is only possible in infinite tables "+
"with auto-refresh turned on");this.refreshData_()}else{this.updateCounter_++;this.loadingInProgress_=false;this.autoRefreshInProgress_=false;this.setFetchedItems_([]);this.currentPage_=0;this.rootElement_.html(InfiniteTableController.LOADING_TEMPLATE)}};InfiniteTableController.prototype.onFilterChange_=function(newFilterValue){if(newFilterValue!==this.filterValue_){this.filterValue_=newFilterValue;this.triggerUpdate(false)}};InfiniteTableController.prototype.checkIfTableLoadingIsVisible_=function(){if(this.loadingInProgress_)return;
$(this.rootElement_).find(".table-loading").each(function(index,loadingElement){var loadingOffset=loadingElement.getBoundingClientRect();var elem=document.elementFromPoint(Math.ceil(loadingOffset.left)+1,Math.ceil(loadingOffset.top)+1);if($(elem).hasClass("table-loading"))this.tableLoadingElementWasShown_();else if(this.showUntilPage_>this.currentPage_)this.tableLoadingElementWasShown_()}.bind(this))};InfiniteTableController.prototype.refreshData_=function(){if(this.loadingInProgress_||this.autoRefreshInProgress_)return;
this.autoRefreshInProgress_=true;var prevUpdateCounter=this.updateCounter_;this.itemsProvider.fetchItems(0,this.currentPage_*this.pageSize_).then(function(newItems){if(this.updateCounter_===prevUpdateCounter){this.autoRefreshInProgress_=false;this.onAutoRefreshDataFetched_(newItems)}}.bind(this))};InfiniteTableController.prototype.onAutoRefreshDataFetched_=function(newItems){for(var i=newItems.items.length-1;i>=0;--i){var newItem=newItems.items[i];var key=newItem[InfiniteTableController.UNIQUE_KEY_NAME];
var rowHash=newItem[InfiniteTableController.ROW_HASH_NAME];var elemScope=this.elementScopes_[key];if(angular.isDefined(elemScope)){var startComment=elemScope[0];var endComment=elemScope[1];var scope=elemScope[2];var oldRowHash=elemScope[3];if(angular.equals(oldRowHash,rowHash))continue;scope.$destroy();var toRemove=[];for(var e=startComment.nextSibling;e!==endComment;e=e.nextSibling)toRemove.push(e);$(toRemove).remove();this.transclude_(function(clone,scope){scope.item=newItem;this.elementScopes_[key]=
[startComment,endComment,scope,rowHash];clone.insertBefore(endComment)}.bind(this))}else{this.fetchedItems_.splice(0,0,newItem);this.transclude_(function(clone,scope){scope.item=newItem;var startComment=document.createComment("-> "+key);var endComment=document.createComment("<- "+key);this.elementScopes_[key]=[startComment,endComment,scope,rowHash];this.rootElement_.prepend([startComment,clone,endComment])}.bind(this))}}};InfiniteTableController.prototype.tableLoadingElementWasShown_=function(){this.loadingInProgress_=
true;var prevUpdateCounter=this.updateCounter_;if(!this.filterValue_)this.itemsProvider.fetchItems(this.currentPage_*this.pageSize_,this.pageSize_).then(function(values){if(this.updateCounter_===prevUpdateCounter)this.onItemsFetched_(values)}.bind(this));else this.itemsProvider.fetchFilteredItems(this.filterValue_,this.currentPage_*this.pageSize_,this.pageSize_).then(function(values){if(this.updateCounter_===prevUpdateCounter)this.onItemsFetched_(values)}.bind(this))};InfiniteTableController.prototype.onItemsFetched_=
function(newlyFetchedItems){this.setFetchedItems_(this.fetchedItems_.concat(newlyFetchedItems.items));if(newlyFetchedItems.items.length==0)$(this.rootElement_).find("tr:has(.table-loading)").remove();this.currentPage_+=1;if(this.currentPage_>this.showUntilPage_)this.showUntilPage_=this.currentPage_;this.loadingInProgress_=false};exports.InfiniteTableDirective=function(){return{transclude:"element",restrict:"A",priority:1E3,terminal:true,require:["grrInfiniteTable","?grrMemoryItemsProvider","?grrApiItemsProvider"],
controller:InfiniteTableController,link:function(scope,element,attrs,controllers){var providerController=undefined;for(var i=1;i<controllers.length;++i)if(angular.isObject(controllers[i])){if(angular.isDefined(providerController))throw new Error("Can have only 1 provider.");providerController=controllers[i]}if(angular.isUndefined(providerController))throw new Error("Data provider not specified.");controllers[0].itemsProvider=providerController}}};exports.InfiniteTableDirective.directive_name="grrInfiniteTable";
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.loadingIndicatorDirective");goog.module.declareLegacyNamespace();var LOADING_STARTED_EVENT_NAME="grrLoadingStartedEvent";var LOADING_FINISHED_EVENT_NAME="grrLoadingFinishedEvent";const LoadingIndicatorController=function($rootScope,$scope){this.rootScope_=$rootScope;this.scope_=$scope;this.queue=[];this.queueIsEmpty=true;this.rootScope_.$on(LOADING_STARTED_EVENT_NAME,this.onLoadingStartedEvent_.bind(this));this.rootScope_.$on(LOADING_FINISHED_EVENT_NAME,
this.onLoadingFinishedEvent_.bind(this))};LoadingIndicatorController.prototype.onLoadingStartedEvent_=function(event,key){this.queue.push(key);this.queueIsEmpty=this.queue.length===0};LoadingIndicatorController.prototype.onLoadingFinishedEvent_=function(event,key){var index=this.queue.indexOf(key);if(index>=0){this.queue.splice(index,1);this.queueIsEmpty=this.queue.length===0}else;};exports.LoadingIndicatorDirective=function(){return{scope:true,restrict:"E",template:'<div id="ajax_spinner" class="ajax_spinner" ng-hide="controller.queueIsEmpty">'+
'    <img src="/static/images/ajax-loader.gif">'+"</div>",controller:LoadingIndicatorController,controllerAs:"controller"}};var LoadingIndicatorDirective=exports.LoadingIndicatorDirective;LoadingIndicatorDirective.directive_name="grrLoadingIndicator";LoadingIndicatorDirective.loading_started_event_name=LOADING_STARTED_EVENT_NAME;LoadingIndicatorDirective.loading_finished_event_name=LOADING_FINISHED_EVENT_NAME;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.loadingIndicatorService");goog.module.declareLegacyNamespace();const {LoadingIndicatorDirective}=goog.require("grrUi.core.loadingIndicatorDirective");var LOADING_STARTED_EVENT_NAME=LoadingIndicatorDirective.loading_started_event_name;var LOADING_FINISHED_EVENT_NAME=LoadingIndicatorDirective.loading_finished_event_name;exports.LoadingIndicatorService=function($rootScope){this.rootScope_=$rootScope;this.key=0};var LoadingIndicatorService=
exports.LoadingIndicatorService;LoadingIndicatorService.service_name="grrLoadingIndicatorService";LoadingIndicatorService.prototype.getNextKey_=function(){return this.key++};LoadingIndicatorService.prototype.startLoading=function(){var key=this.getNextKey_();this.rootScope_.$broadcast(LOADING_STARTED_EVENT_NAME,key);return key};LoadingIndicatorService.prototype.stopLoading=function(key){this.rootScope_.$broadcast(LOADING_FINISHED_EVENT_NAME,key)};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.markdownDirective");goog.module.declareLegacyNamespace();const MarkdownController=function($scope,$element,$window){this.scope_=$scope;this.element_=$element;this.window_=$window;this.scope_.$watch("source",this.onSourceChange_.bind(this))};MarkdownController.prototype.onSourceChange_=function(newValue){this.element_.html("");if(angular.isDefined(newValue))this.element_.html(marked(newValue))};exports.MarkdownDirective=function(){return{scope:{source:"="},
restrict:"E",controller:MarkdownController}};exports.MarkdownDirective.directive_name="grrMarkdown";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.memoryItemsProviderDirective");goog.module.declareLegacyNamespace();const {Items,ItemsProviderController}=goog.require("grrUi.core.itemsProviderController");exports.MemoryItemsProviderController=function($scope,$q,$attrs,$parse){this.q_=$q;this.items_;if(angular.isUndefined($attrs.items))throw new Error('"items" attribute has to be specified.');$scope.$watch($attrs.items,function(){this.items_=$scope.$eval($attrs.items)}.bind(this))};
var MemoryItemsProviderController=exports.MemoryItemsProviderController;MemoryItemsProviderController.prototype.fetchItems=function(offset,count,opt_withTotalCount){if(angular.isUndefined(opt_withTotalCount))opt_withTotalCount=false;var items=this.items_;var deferred=this.q_.defer();var resultItems=items.slice(offset,offset+count);var result={offset:offset,items:resultItems};if(opt_withTotalCount)result.totalCount=items.length;deferred.resolve(result);return deferred.promise};MemoryItemsProviderController.prototype.fetchFilteredItems=
function(filter,offset,count){filter=filter.toLowerCase();var items=this.items_;var deferred=this.q_.defer();var filteredItems=[];angular.forEach(items,function(item){if(JSON.stringify(item).toLowerCase().indexOf(filter)!=-1)filteredItems.push(item)});filteredItems=filteredItems.slice(offset,offset+count);var result={offset:offset,items:filteredItems};deferred.resolve(result);return deferred.promise};exports.MemoryItemsProviderDirective=function(){return{restrict:"A",priority:2E3,controller:MemoryItemsProviderController}};
exports.MemoryItemsProviderDirective.directive_name="grrMemoryItemsProvider";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.onScrollIntoViewDirective");goog.module.declareLegacyNamespace();const OnScrollIntoViewController=function($scope,$element,$attrs,$interval,$window){this.scope_=$scope;this.attrs_=$attrs;this.element_=$element;this.window_=$window;this.currentlyVisible=false;var stop=$interval(this.onInterval.bind(this),100);$scope.$on("$destroy",function(){$interval.cancel(stop)})};OnScrollIntoViewController.prototype.onInterval=function(){var elemOffset=
$(this.element_).offset();var elemWidth=$(this.element_).width();var elemHeight=$(this.element_).height();var elem=document.elementFromPoint(elemOffset.left-$(this.window_).scrollLeft()+1,elemOffset.top-$(this.window_).scrollTop()+1);var isVisible=elem==$(this.element_)[0];if(!isVisible){elem=document.elementFromPoint(elemOffset.left+elemWidth-$(this.window_).scrollLeft()-1,elemOffset.top+elemHeight-$(this.window_).scrollTop()-1);isVisible=elem==$(this.element_)[0]}if(!isVisible){elem=document.elementFromPoint(elemOffset.left+
elemWidth/2-$(this.window_).scrollLeft(),elemOffset.top+elemHeight/2-$(this.window_).scrollTop());isVisible=elem==$(this.element_)[0]}if(this.currentlyVisible!=isVisible){this.currentlyVisible=isVisible;if(isVisible)this.scope_.$eval(this.attrs_["grrOnScrollIntoView"])}};exports.OnScrollIntoViewDirective=function(){return{restrict:"A",controller:OnScrollIntoViewController}};exports.OnScrollIntoViewDirective.directive_name="grrOnScrollIntoView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.pagedFilteredTableDirective");goog.module.declareLegacyNamespace();exports.TableTopDirective=function(){return{scope:{parentController:"="},require:"^grrPagedFilteredTable",templateUrl:"/static/angular-components/core/"+"paged-filtered-table-top.html",restrict:"E"}};exports.TableTopDirective.directive_name="grrPagedFilteredTableTop";exports.TableBottomDirective=function(){return{scope:{parentController:"="},require:"^grrPagedFilteredTable",
templateUrl:"/static/angular-components/core/"+"paged-filtered-table-bottom.html",restrict:"E"}};exports.TableBottomDirective.directive_name="grrPagedFilteredTableBottom";const PagedFilteredTableController=function($scope,$element,$transclude,$compile,$interval){this.scope_=$scope;this.scope_.pageSize;this.scope_.autoRefreshInterval;this.element_=$element;this.transclude_=$transclude;this.compile_=$compile;this.interval_=$interval;this.itemsProvider;this.currentPage=0;this.paginationSelectedPage=
1;this.showLoading=true;this.items=[];this.totalCount;this.pageSize=this.scope_.pageSize||PagedFilteredTableController.DEFAULT_PAGE_SIZE;this.filterEditedValue="";this.filterValue="";this.filterApplied=false;this.filterFinished=false;this.requestCounter_=0;this.autoRefreshInProgress_=false;this.addTopDirective_();this.addBottomDirective_();this.scope_.$watch("::controller.itemsProvider",function(){this.fetchUnfilteredItems(true)}.bind(this));if(this.scope_.autoRefreshInterval){var refreshTimer=this.interval_(this.onAutoRefresh_.bind(this),
this.scope_.autoRefreshInterval);this.scope_.$on("$destroy",function(){this.interval_.cancel(refreshTimer)}.bind(this))}};PagedFilteredTableController.DEFAULT_PAGE_SIZE=50;PagedFilteredTableController.prototype.addTopDirective_=function(){var template=angular.element('<grr-paged-filtered-table-top parent-controller="controller" />');var table=this.element_.closest("table");template.insertBefore(table);this.compile_(template)(this.scope_)};PagedFilteredTableController.prototype.addBottomDirective_=
function(){var template=angular.element('<grr-paged-filtered-table-bottom parent-controller="controller" />');var table=this.element_.closest("table");template.insertAfter(table);this.compile_(template)(this.scope_)};PagedFilteredTableController.prototype.wrapWithCounterCheck_=function(callback){this.requestCounter_+=1;var curRequestCounter=this.requestCounter_;return function(data){if(this.requestCounter_==curRequestCounter)return callback(data)}.bind(this)};PagedFilteredTableController.prototype.fetchUnfilteredItems=
function(withTotalCount){this.showLoading=true;this.setItems_([]);this.itemsProvider.fetchItems(this.currentPage*this.pageSize,this.pageSize,withTotalCount).then(this.wrapWithCounterCheck_(this.onFetchedUnfilteredItems_.bind(this)))};PagedFilteredTableController.prototype.onFetchedUnfilteredItems_=function(items){this.showLoading=false;this.setItems_(items.items);if(angular.isDefined(items.totalCount))this.totalCount=items.totalCount};PagedFilteredTableController.prototype.applyFilter=function(){this.filterValue=
this.filterEditedValue;this.filterApplied=this.filterValue!="";this.filterFinished=false;this.currentPage=0;this.paginationSelectedPage=1;this.setItems_([]);if(this.filterApplied)this.fetchFilteredItems();else this.fetchUnfilteredItems(false)};PagedFilteredTableController.prototype.fetchFilteredItems=function(opt_numPages){if(angular.isUndefined(opt_numPages))opt_numPages=1;this.showLoading=true;this.itemsProvider.fetchFilteredItems(this.filterValue,this.items.length,this.pageSize*opt_numPages).then(this.wrapWithCounterCheck_(this.onFetchedFilteredItems_.bind(this)))};
PagedFilteredTableController.prototype.onFetchedFilteredItems_=function(items){this.showLoading=false;this.setItems_(this.items.concat(items.items));if(items.items.length==0||items.items.length%this.pageSize!=0)this.filterFinished=true};PagedFilteredTableController.prototype.setItems_=function(newItems){var indexOffset=0;if(angular.equals(this.items,newItems.slice(0,this.items.length)))indexOffset=this.items.length;else this.element_.siblings().remove();this.items=newItems;for(var i=indexOffset;i<
this.items.length;++i)this.transclude_(function(clone,scope){scope.item=this.items[i];scope.$index=i;this.element_.parent().append(clone)}.bind(this),this.element_.parent())};PagedFilteredTableController.prototype.onAutoRefresh_=function(){if(this.filterApplied||this.items.length>=this.pageSize||this.autoRefreshInProgress_)return;var callback=this.wrapWithCounterCheck_(this.onFetchedUnfilteredItems_.bind(this));this.autoRefreshInProgress_=true;this.itemsProvider.fetchItems(this.currentPage*this.pageSize,
this.pageSize,true).then(callback).finally(function(){this.autoRefreshInProgress_=false}.bind(this))};PagedFilteredTableController.prototype.onPageChange=function(newPage){this.currentPage=newPage;if(!this.filterApplied)this.fetchUnfilteredItems(false)};exports.PagedFilteredTableDirective=function(){return{scope:{pageSize:"=?",autoRefreshInterval:"=?"},transclude:"element",restrict:"A",priority:1E3,terminal:true,require:["?grrMemoryItemsProvider","?grrApiItemsProvider"],controller:PagedFilteredTableController,
controllerAs:"controller",link:function(scope,element,attrs,controllers){var providerController=undefined;for(var i=0;i<controllers.length;++i)if(angular.isObject(controllers[i])){if(angular.isDefined(providerController))throw new Error("Can have only 1 provider.");providerController=controllers[i]}if(angular.isUndefined(providerController))throw new Error("Data provider not specified.");scope.controller.itemsProvider=providerController}}};exports.PagedFilteredTableDirective.directive_name="grrPagedFilteredTable";
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.periodicRefreshDirective");goog.module.declareLegacyNamespace();const PeriodicRefreshController=function($scope,$interval){this.scope_=$scope;this.interval_=$interval;this.refreshTrigger=0;this.updateOperationInterval_;this.scope_.$watch("interval",this.onIntervalChange_.bind(this));this.scope_.$on("$destroy",function(){if(this.updateOperationInterval_)this.interval_.cancel(this.updateOperationInterval_)}.bind(this))};PeriodicRefreshController.prototype.onIntervalChange_=
function(newValue){if(this.updateOperationInterval_){this.interval_.cancel(this.updateOperationInterval_);this.updateOperationInterval_=null}if(angular.isDefined(newValue))this.updateOperationInterval_=this.interval_(this.onInterval_.bind(this),newValue)};PeriodicRefreshController.prototype.onInterval_=function(){this.refreshTrigger+=1;if(this.scope_["onRefresh"])this.scope_["onRefresh"]()};exports.PeriodicRefreshDirective=function(){return{scope:{interval:"=",onRefresh:"&"},restrict:"EA",transclude:true,
template:"<grr-force-refresh "+'refresh-trigger="controller.refreshTrigger">'+"<ng-transclude /></grr-force-refresh>",controller:PeriodicRefreshController,controllerAs:"controller"}};exports.PeriodicRefreshDirective.directive_name="grrPeriodicRefresh";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.reflectionService");goog.module.declareLegacyNamespace();exports.ReflectionService=function($q,grrApiService){this.q_=$q;this.grrApiService_=grrApiService;this.descriptorsCache_;this.requestsQueue_=[]};var ReflectionService=exports.ReflectionService;ReflectionService.service_name="grrReflectionService";ReflectionService.prototype.processRequestsQueue_=function(){angular.forEach(this.requestsQueue_,function(request){var result=
this.getRDFValueDescriptorFromCache_(request[1],request[2]);request[0].resolve(result)}.bind(this));this.requestsQueue_=[]};ReflectionService.prototype.getRDFValueDescriptorFromCache_=function(valueType,opt_withDeps){if(!opt_withDeps)return this.descriptorsCache_[valueType];else{var results={};var fillInResult=function(type){if(angular.isDefined(results[type]))return;var descriptor=this.descriptorsCache_[type];results[type]=descriptor;angular.forEach(descriptor["fields"],function(fieldDescriptor){if(angular.isDefined(fieldDescriptor["type"]))fillInResult(fieldDescriptor["type"])})}.bind(this);
fillInResult(valueType);return results}};ReflectionService.prototype.getRDFValueDescriptor=function(valueType,opt_withDeps){var deferred=this.q_.defer();if(angular.isDefined(this.descriptorsCache_)){var result=this.getRDFValueDescriptorFromCache_(valueType,opt_withDeps);deferred.resolve(result);return deferred.promise}else{if(this.requestsQueue_.length===0){var apiPromise=this.grrApiService_.get("reflection/rdfvalue/all");apiPromise.then(function(response){this.descriptorsCache_={};angular.forEach(response["data"]["items"],
function(item){this.descriptorsCache_[item["name"]]=item}.bind(this));return this.processRequestsQueue_()}.bind(this))}this.requestsQueue_.push([deferred,valueType,opt_withDeps]);return deferred.promise}};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.fileDownloadUtils");goog.module.declareLegacyNamespace();var AFF4_PREFIXES={"OS":"fs/os","TSK":"fs/tsk","REGISTRY":"registry","TMPFILE":"temp"};var splitPathspec=function(pathspec){var result=[];var cur=pathspec["value"];while(angular.isDefined(cur["pathtype"])){result.push(cur);if(angular.isDefined(cur["nested_path"]))cur=cur["nested_path"]["value"];else break}return result};exports.pathSpecToAff4Path=function(pathspec,clientId){var components=
splitPathspec(pathspec);var firstComponent=components[0];var result,start;if(components.length>1&&firstComponent["pathtype"]["value"]=="OS"&&components[1]["pathtype"]["value"]=="TSK"){var dev=firstComponent["path"]["value"];if(angular.isDefined(firstComponent["offset"]))dev+=":"+Math.round(firstComponent["offset"]["value"]/512);if(dev.startsWith("/"))dev=dev.substring(1);result=["aff4:",clientId,AFF4_PREFIXES["TSK"],dev];start=1}else{result=["aff4:",clientId,AFF4_PREFIXES[firstComponent["pathtype"]["value"]]];
start=0}for(var i=start;i<components.length;++i){var p=components[i];var component=p["path"]["value"];if(component.startsWith("/"))component=component.substring(1);if(angular.isDefined(p["offset"]))component+=":"+Math.round(p["offset"]["value"]/512);if(angular.isDefined(p["stream_name"]))component+=":"+p["stream_name"]["value"];result.push(component)}return result.join("/")};var pathSpecToAff4Path=exports.pathSpecToAff4Path;exports.vfsRoots=["fs","registry","temp"];exports.downloadableVfsRoots=["fs",
"temp"];exports.getPathSpecFromValue=function(value){if(!value)return null;if(value["type"]=="ApiFlowResult"||value["type"]=="ApiHuntResult")value=value["value"]["payload"];switch(value["type"]){case "StatEntry":return value["value"]["pathspec"];case "FileFinderResult":var st=value["value"]["stat_entry"];if(angular.isDefined(st)&&angular.isDefined(st["value"]["pathspec"]))return st["value"]["pathspec"];return null;case "ArtifactFilesDownloaderResult":return exports.getPathSpecFromValue(value["value"]["downloaded_file"]);
default:return null}};const makeStatEntryDownloadable_=function(value,downloadUrl,downloadParams){var originalValue=angular.copy(value);for(var prop in value)if(value.hasOwnProperty(prop))delete value[prop];angular.extend(value,{type:"__DownloadableStatEntry",originalValue:originalValue,downloadUrl:downloadUrl,downloadParams:downloadParams})};const makeFileFinderResultDownloadable_=function(value,downloadUrl,downloadParams){makeStatEntryDownloadable_(value["value"]["stat_entry"],downloadUrl,downloadParams)};
const makeArtifactFilesDownloaderResultDownloadable_=function(value,downloadUrl,downloadParams){exports.makeValueDownloadable(value["value"]["downloaded_file"],downloadUrl,downloadParams)};exports.makeValueDownloadable=function(value,downloadUrl,downloadParams){if(!value)return false;if(value["type"]==="ApiFlowResult"||value["type"]==="ApiHuntResult")value=value["value"]["payload"];switch(value["type"]){case "StatEntry":makeStatEntryDownloadable_(value,downloadUrl,downloadParams);return true;case "FileFinderResult":makeFileFinderResultDownloadable_(value,
downloadUrl,downloadParams);return true;case "ArtifactFilesDownloaderResult":makeArtifactFilesDownloaderResultDownloadable_(value,downloadUrl,downloadParams);return true;default:return false}};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.resultsCollectionDirective");goog.module.declareLegacyNamespace();const {getPathSpecFromValue}=goog.require("grrUi.core.fileDownloadUtils");let autoRefreshIntervalMs=20*1E3;exports.setAutoRefreshInterval=function(millis){autoRefreshIntervalMs=millis};var MAX_ITEMS_TO_CHECK_FOR_FILES=50;const ResultsCollectionController=function($scope){this.scope_=$scope;this.resultsArePresent;this.resultsAreFiles;this.autoRefreshInterval=autoRefreshIntervalMs;
this.numCheckedItems_=0};ResultsCollectionController.prototype.transformItems=function(items){if(items.length>0)this.resultsArePresent=true;if(!this.resultsAreFiles&&this.numCheckedItems_<MAX_ITEMS_TO_CHECK_FOR_FILES){this.numCheckedItems_+=items.length;this.resultsAreFiles=false;for(var i=0;i<items.length;i++)if(getPathSpecFromValue(items[i])!=null){this.resultsAreFiles=true;break}}if(this.scope_["transformItems"])return this.scope_["transformItems"]({"items":items});else return items};exports.ResultsCollectionDirective=
function(){return{scope:{resultsUrl:"=",exportedResultsUrl:"=",outputPluginsUrl:"=",exportCommandUrl:"=?",downloadFilesUrl:"=",transformItems:"&?"},restrict:"E",templateUrl:"/static/angular-components/core/results-collection.html",controller:ResultsCollectionController,controllerAs:"controller"}};exports.ResultsCollectionDirective.directive_name="grrResultsCollection";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.searchBoxDirective");goog.module.declareLegacyNamespace();var SEARCH_KEYWORDS=["host","mac","ip","user","label"];const SearchBoxController=function($scope,$element,$interval,grrApiService,grrRoutingService){this.scope_=$scope;this.element_=$element;this.interval_=$interval;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.query="";this.labels=[];this.grrApiService_.get("/clients/labels").then(this.onGetLabels_.bind(this))};
SearchBoxController.prototype.onGetLabels_=function(response){angular.forEach(response["data"]["items"],function(label){this.labels.push("label:"+label["value"]["name"]["value"])}.bind(this))};SearchBoxController.prototype.submitQuery=function(){if(this.isHuntId_(this.query))this.checkHunt_(this.query);else this.grrRoutingService_.go("search",{q:this.query})};SearchBoxController.prototype.isHuntId_=function(input){var hunt_regex=/^([A-Z0-9]+:)?[A-F0-9]{6,12}$/i;if(!hunt_regex.test(input))return false;
var components=input.split(":");var potential_keyword=components[0].toLowerCase();return SEARCH_KEYWORDS.indexOf(potential_keyword)===-1};SearchBoxController.prototype.checkHunt_=function(huntId){this.grrApiService_.get("hunts/"+huntId).then(function success(response){var huntId=response.data["value"]["hunt_id"]["value"];this.grrRoutingService_.go("hunts",{huntId:huntId})}.bind(this),function error(){this.grrRoutingService_.go("search",{q:this.query})}.bind(this))};SearchBoxController.prototype.contextHelpUrl=
"investigating-with-grr/searching-for-client.html";exports.SearchBoxDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/core/search-box.html",controller:SearchBoxController,controllerAs:"controller"}};exports.SearchBoxDirective.directive_name="grrSearchBox";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.serverErrorDialogDirective");goog.module.declareLegacyNamespace();const ServerErrorDialogController=function($scope){this.scope_=$scope};exports.ServerErrorDialogDirective=function(){return{scope:{close:"&",message:"=",traceBack:"="},restrict:"E",templateUrl:"/static/angular-components/core/server-error-dialog.html",controller:ServerErrorDialogController,controllerAs:"controller"}};exports.ServerErrorDialogDirective.directive_name=
"grrServerErrorDialog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.serverErrorInterceptorFactory");goog.module.declareLegacyNamespace();const {ServerErrorButtonDirective}=goog.require("grrUi.core.serverErrorButtonDirective");var ERROR_EVENT_NAME=ServerErrorButtonDirective.error_event_name;var INTERCEPTED_STATUS_CODES=[500];const needsInterception_=function(response){return INTERCEPTED_STATUS_CODES.indexOf(response.status)!==-1};const extractError_=function(response){var data=response.data||{};
return{message:data.message||"Unknown Server Error",traceBack:data.traceBack}};exports.ServerErrorInterceptorFactory=function($rootScope,$q){return{responseError:function(response){if(needsInterception_(response)){var error=extractError_(response);$rootScope.$broadcast(ERROR_EVENT_NAME,error)}return $q.reject(response)}}};var ServerErrorInterceptorFactory=exports.ServerErrorInterceptorFactory;ServerErrorInterceptorFactory.factory_name="grrServerErrorInterceptorFactory";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.serverErrorPreviewDirective");goog.module.declareLegacyNamespace();const {ServerErrorButtonDirective}=goog.require("grrUi.core.serverErrorButtonDirective");var ERROR_EVENT_NAME=ServerErrorButtonDirective.error_event_name;var ERROR_PREVIEW_INTERVAL=5E3;const ServerErrorPreviewController=function($rootScope,$scope,$timeout){this.rootScope_=$rootScope;this.scope_=$scope;this.timeout_=$timeout;this.error;this.labelVisible;this.rootScope_.$on(ERROR_EVENT_NAME,
this.onErrorEvent.bind(this))};ServerErrorPreviewController.prototype.onErrorEvent=function(unused_event,error){if(!angular.isObject(error)||!angular.isString(error.message))return;if(error.message.length){this.error=error;this.labelVisible=true;this.timeout_(function(){this.labelVisible=false}.bind(this),ERROR_PREVIEW_INTERVAL)}else{this.error=null;this.labelVisible=false}};exports.ServerErrorPreviewDirective=function(){return{scope:true,restrict:"E",replace:true,template:'<div class="navbar-text" ng-show="controller.labelVisible">'+
"    {$ controller.error.message $}"+"</div>",controller:ServerErrorPreviewController,controllerAs:"controller"}};var ServerErrorPreviewDirective=exports.ServerErrorPreviewDirective;ServerErrorPreviewDirective.directive_name="grrServerErrorPreview";ServerErrorPreviewDirective.error_preview_interval=5E3;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.splitterDirective");goog.module.declareLegacyNamespace();const SplitterController=function($scope,$element,$interval){this.scope_=$scope;this.element_=$element;this.interval_=$interval;this.scope_.orientation;this.panes=[]};SplitterController.prototype.addPane=function(pane){this.panes.push(pane)};SplitterController.prototype.link=function(){let sizeLeft=100;let sizeLeftCount=0;this.panes.forEach(pane=>{if(pane["size"])sizeLeft-=
parseInt(pane["size"],10);else++sizeLeftCount});const defaultSize=sizeLeft/sizeLeftCount;const splitterOptions={gutterSize:4,sizes:this.panes.map(pane=>parseInt(pane["size"]||defaultSize,10))};if(this.scope_["orientation"]=="horizontal")splitterOptions["direction"]="vertical";else if(this.scope_["orientation"]==="vertical")splitterOptions["direction"]="horizontal";else throw Error('Orientation can be either "vertical" or "horizontal".');const elems=this.panes.map(pane=>pane["elem"]);var count=0;var stop;
var registerSplitter=function(){if($(this.element_).width()>0&&$(this.element_).height()>0||count>5){Split(elems,splitterOptions);this.interval_.cancel(stop)}else count+=1}.bind(this);stop=this.interval_(registerSplitter,100);registerSplitter();this.element_.on("$destroy",function(){this.interval_.cancel(stop)}.bind(this))};exports.SplitterDirective=function(){return{scope:{orientation:"@"},restrict:"EA",transclude:true,template:'<div class="splitter fill-parent no-margins" '+"ng-transclude></div>",
controller:SplitterController,controllerAs:"controller",link:function(scope,element,attrs){scope.controller.link()}}};exports.SplitterDirective.directive_name="grrSplitter";exports.SplitterPaneDirective=function(){return{scope:{size:"@"},restrict:"EA",require:"^grrSplitter",transclude:true,template:'<div class="fill-parent no-margins" ng-transclude></div>',link:function(scope,element,attrs,grrSplitterCtrl){scope["elem"]=element[0];grrSplitterCtrl.addPane(scope)}}};exports.SplitterPaneDirective.directive_name=
"grrSplitterPane";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.timeService");goog.module.declareLegacyNamespace();exports.TimeService=function(){};var TimeService=exports.TimeService;TimeService.service_name="grrTimeService";TimeService.prototype.getCurrentTimeMs=function(){return(new Date).getTime()};TimeService.prototype.formatAsUTC=function(opt_timestamp){var when=angular.isUndefined(opt_timestamp)?moment():moment(opt_timestamp);return when.utc().format("YYYY-MM-DD HH:mm:ss")+" UTC"};TimeService.prototype.getFormattedDiffFromCurrentTime=
function(timestamp){var diff=moment(timestamp).diff(moment());if(Math.abs(diff)<60*1E3)return"now";return moment.duration(diff).humanize(true)};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.timeSinceFilter");goog.module.declareLegacyNamespace();const filterImplementation=function(grrTimeService,input){var currentTimeMs=grrTimeService.getCurrentTimeMs();var inputTimeMs=input/1E3;if(inputTimeMs<1E-6)return"<invalid time value>";var differenceSec=Math.abs(Math.round((currentTimeMs-inputTimeMs)/1E3));var measureUnit;var measureValue;if(differenceSec<60){measureUnit="seconds";measureValue=differenceSec}else if(differenceSec<
60*60){measureUnit="minutes";measureValue=Math.floor(differenceSec/60)}else if(differenceSec<60*60*24){measureUnit="hours";measureValue=Math.floor(differenceSec/(60*60))}else{measureUnit="days";measureValue=Math.floor(differenceSec/(60*60*24))}if(currentTimeMs>=inputTimeMs)return measureValue+" "+measureUnit+" ago";else return"in "+measureValue+" "+measureUnit};exports.TimeSinceFilter=function(grrTimeService){return function(input){return filterImplementation(grrTimeService,input)}};exports.TimeSinceFilter.filter_name=
"grrTimeSince";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.timestampFilter");goog.module.declareLegacyNamespace();const filterImplementation=function(grrTimeService,value){if(angular.isNumber(value)){var timestamp=value/1E3;return grrTimeService.formatAsUTC(timestamp)}else return"-"};exports.TimestampFilter=function(grrTimeService){return function(input){return filterImplementation(grrTimeService,input)}};exports.TimestampFilter.filter_name="grrTimestamp";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.troggleDirective");goog.module.declareLegacyNamespace();const TroggleState={SET:"SET",UNSET:"UNSET",VOID:"VOID"};const nextTroggleState=state=>{switch(state){case TroggleState.SET:return TroggleState.UNSET;case TroggleState.UNSET:return TroggleState.VOID;case TroggleState.VOID:return TroggleState.SET}throw new Error(`invalid state: ${state}`);};const TroggleDirective=function(){return{restrict:"E",templateUrl:"/static/angular-components/core/troggle.html",
require:"ngModel",link:function(scope,element,attrs,ngModelController){ngModelController.$render=function(){scope.state=ngModelController.$viewValue};scope.$watch("state",function(){ngModelController.$setViewValue(scope.state)});scope.switchState=function(){scope.state=nextTroggleState(scope.state)}}}};TroggleDirective.directive_name="grrTroggle";exports.TroggleState=TroggleState;exports.TroggleDirective=TroggleDirective;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.versionDropdownDirective");goog.module.declareLegacyNamespace();var REFRESH_VERSIONS_EVENT="RefreshVersionsEvent";const VersionDropdownController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.versions;this.version;this.requestCounter_=0;this.updateInProgress_;this.scope_.$watch("url",this.fetchVersions_.bind(this));this.scope_.$watch("version",this.onVersionBindingChange_.bind(this));
this.scope_.$watch("controller.version",this.onControllerVersionChange_.bind(this));this.scope_.$on(REFRESH_VERSIONS_EVENT,this.fetchVersions_.bind(this))};VersionDropdownController.prototype.onVersionBindingChange_=function(newValue){if(angular.isUndefined(newValue)&&this.version==="HEAD")return;if(angular.isDefined(this.versions))for(var i=0;i<this.versions.length;++i)if(newValue===this.versions[i]["value"]){this.version=this.scope_["version"].toString();return}this.syncSelectedVersion_()};VersionDropdownController.prototype.syncSelectedVersion_=
function(){if(angular.isUndefined(this.versions)||this.versions.length===0)return;if(this.scope_["version"]){this.versions.push({value:this.scope_["version"],type:"RDFDatetime"});this.versions.sort(function(v1,v2){if(v1["value"]<v2["value"])return 1;else if(v1["value"]==v2["value"])return 0;else return-1}.bind(this));this.versions=this.versions.filter(function(value,index,arr){if(index==0)return true;else return value["value"]!=arr[index-1]["value"]}.bind(this));this.version=this.scope_["version"].toString()}else this.version=
"HEAD"};VersionDropdownController.prototype.fetchVersions_=function(){var url=this.scope_["url"];if(angular.isDefined(url)){this.updateInProgress_=true;this.requestCounter_+=1;var curCounter=this.requestCounter_;this.grrApiService_.get(url).then(function(response){if(curCounter===this.requestCounter_){this.onVersionsFetched_(response);this.updateInProgress_=false}}.bind(this))}};VersionDropdownController.prototype.onVersionsFetched_=function(response){var responseField=this.scope_["responseField"]||
"times";this.versions=response["data"][responseField];if(!this.versions.length)return;this.syncSelectedVersion_()};VersionDropdownController.prototype.onControllerVersionChange_=function(){if(angular.isUndefined(this.version))return;if(this.version=="HEAD")this.scope_["version"]=undefined;else this.scope_["version"]=parseInt(this.version,10)};VersionDropdownController.prototype.isSelected=function(value){if(value=="HEAD")return this.version==value;else return parseInt(this.version,10)==value};VersionDropdownController.prototype.isLatestSelected=
function(){if(this.updateInProgress_)return true;if(this.version=="HEAD")return true;return!this.versions||this.versions.length===0||!this.scope_["version"]||this.version===this.versions[0].value.toString()};exports.VersionDropdownDirective=function(){return{restrict:"E",scope:{url:"=",version:"=",responseField:"@"},templateUrl:"/static/angular-components/core/version-dropdown.html",controller:VersionDropdownController,controllerAs:"controller"}};exports.VersionDropdownDirective.directive_name="grrVersionDropdown";
exports.VersionDropdownDirective.REFRESH_VERSIONS_EVENT=REFRESH_VERSIONS_EVENT;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.wizardFormDirective");goog.module.declareLegacyNamespace();exports.WizardFormController=function($scope){this.scope_=$scope;this.pages=[];this.currentPage;this.currentPageIndex;this.scope_.$watchCollection("controller.pages",this.onPagesOrCurrentPageChange_.bind(this));this.scope_.$watch("controller.currentPage",this.onPagesOrCurrentPageChange_.bind(this));this.scope_.$watch("controller.currentPage",function(newValue){if(angular.isDefined(newValue))newValue.onShow()}.bind(this))};
var WizardFormController=exports.WizardFormController;WizardFormController.prototype.onPagesOrCurrentPageChange_=function(){this.currentPageIndex=this.pages.indexOf(this.currentPage)};WizardFormController.prototype.back=function(){var index=this.pages.indexOf(this.currentPage);if(index==0)throw new Error("Can't go back from the first page.");this.currentPage=this.pages[index-1]};WizardFormController.prototype.next=function(){var index=this.pages.indexOf(this.currentPage);if(index<this.pages.length-
1)this.currentPage=this.pages[index+1];else this.scope_["onResolve"]()};WizardFormController.prototype.reject=function(){this.scope_["onReject"]()};WizardFormController.prototype.registerPage=function(pageController){this.pages.push(pageController);if(angular.isUndefined(this.currentPage))this.currentPage=pageController};exports.WizardFormDirective=function(){return{scope:{title:"@",onResolve:"&",onReject:"&"},restrict:"E",transclude:true,templateUrl:"/static/angular-components/core/wizard-form.html",
controller:WizardFormController,controllerAs:"controller"}};exports.WizardFormDirective.directive_name="grrWizardForm";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.wizardFormPageDirective");goog.module.declareLegacyNamespace();exports.WizardFormPageController=function($scope,$attrs){this.scope_=$scope;this.attrs_=$attrs;this.formController;this.title;this.helpLink;this.prevButtonLabel="Back";this.nextButtonLabel="Next";this.noBackButton=false;this.isValid=true;this.scope_.$watch("title",function(newValue){this.title=newValue}.bind(this));this.scope_.$watch("prevButtonLabel",function(newValue){if(angular.isDefined(newValue))this.prevButtonLabel=
newValue}.bind(this));this.scope_.$watch("nextButtonLabel",function(newValue){if(angular.isDefined(newValue))this.nextButtonLabel=newValue}.bind(this));this.scope_.$watch("noBackButton",function(newValue){this.noBackButton=newValue}.bind(this));this.scope_.$watch("isValid",function(newValue){if(angular.isDefined(this.attrs_["isValid"]))this.isValid=newValue}.bind(this));this.scope_.$watch("helpLink",function(newValue){this.helpLink=newValue}.bind(this))};var WizardFormPageController=exports.WizardFormPageController;
WizardFormPageController.prototype.onShow=function(){this.scope_["onShow"]()};exports.WizardFormPageDirective=function(){return{scope:{title:"@",helpLink:"@",prevButtonLabel:"@",nextButtonLabel:"@",noBackButton:"=?",isValid:"=?",onShow:"&"},restrict:"E",transclude:true,templateUrl:"/static/angular-components/core/wizard-form-page.html",controller:WizardFormPageController,controllerAs:"controller",require:"^grrWizardForm",link:function(scope,element,attrs,formController){scope.controller.formController=
formController;formController.registerPage(scope.controller)}}};exports.WizardFormPageDirective.directive_name="grrWizardFormPage";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.core");goog.module.declareLegacyNamespace();const {Aff4ObjectRepresentationDirective}=goog.require("grrUi.core.aff4ObjectRepresentationDirective");const {ApiItemsProviderDirective}=goog.require("grrUi.core.apiItemsProviderDirective");const {ApiService}=goog.require("grrUi.core.apiService");const {BasenameFilter}=goog.require("grrUi.core.basenameFilter");const {BindKeyDirective}=goog.require("grrUi.core.bindKeyDirective");const {BytesToHexFilter}=
goog.require("grrUi.core.bytesToHexFilter");const {CanaryOnlyDirective,NonCanaryOnlyDirective}=goog.require("grrUi.core.canaryOnlyDirective");const {ClockDirective}=goog.require("grrUi.core.clockDirective");const {ConfirmationDialogDirective}=goog.require("grrUi.core.confirmationDialogDirective");const {DialogService}=goog.require("grrUi.core.dialogService");const {DisableIfNoTraitDirective}=goog.require("grrUi.core.disableIfNoTraitDirective");const {DownloadCollectionAsDirective}=goog.require("grrUi.core.downloadCollectionAsDirective");
const {DownloadCollectionFilesDirective}=goog.require("grrUi.core.downloadCollectionFilesDirective");const {EncodeUriComponentFilter}=goog.require("grrUi.core.encodeUriComponentFilter");const {FirebaseService}=goog.require("grrUi.core.firebaseService");const {ForceRefreshDirective}=goog.require("grrUi.core.forceRefreshDirective");const {HexNumberFilter}=goog.require("grrUi.core.hexNumberFilter");const {InfiniteTableDirective}=goog.require("grrUi.core.infiniteTableDirective");const {LoadingIndicatorDirective}=
goog.require("grrUi.core.loadingIndicatorDirective");const {LoadingIndicatorService}=goog.require("grrUi.core.loadingIndicatorService");const {MarkdownDirective}=goog.require("grrUi.core.markdownDirective");const {MemoryItemsProviderDirective}=goog.require("grrUi.core.memoryItemsProviderDirective");const {OnScrollIntoViewDirective}=goog.require("grrUi.core.onScrollIntoViewDirective");const {PagedFilteredTableDirective,TableBottomDirective,TableTopDirective}=goog.require("grrUi.core.pagedFilteredTableDirective");
const {PeriodicRefreshDirective}=goog.require("grrUi.core.periodicRefreshDirective");const {ReflectionService}=goog.require("grrUi.core.reflectionService");const {ResultsCollectionDirective}=goog.require("grrUi.core.resultsCollectionDirective");const {SearchBoxDirective}=goog.require("grrUi.core.searchBoxDirective");const {ServerErrorButtonDirective}=goog.require("grrUi.core.serverErrorButtonDirective");const {ServerErrorDialogDirective}=goog.require("grrUi.core.serverErrorDialogDirective");const {ServerErrorInterceptorFactory}=
goog.require("grrUi.core.serverErrorInterceptorFactory");const {ServerErrorPreviewDirective}=goog.require("grrUi.core.serverErrorPreviewDirective");const {SplitterDirective,SplitterPaneDirective}=goog.require("grrUi.core.splitterDirective");const {TimeService}=goog.require("grrUi.core.timeService");const {TimeSinceFilter}=goog.require("grrUi.core.timeSinceFilter");const {TimestampFilter}=goog.require("grrUi.core.timestampFilter");const {TroggleDirective}=goog.require("grrUi.core.troggleDirective");
const {VersionDropdownDirective}=goog.require("grrUi.core.versionDropdownDirective");const {WizardFormDirective}=goog.require("grrUi.core.wizardFormDirective");const {WizardFormPageDirective}=goog.require("grrUi.core.wizardFormPageDirective");exports.coreModule=angular.module("grrUi.core",["ngCookies","ngSanitize","ui.bootstrap"]);exports.coreModule.directive(Aff4ObjectRepresentationDirective.directive_name,Aff4ObjectRepresentationDirective);exports.coreModule.directive(ApiItemsProviderDirective.directive_name,
ApiItemsProviderDirective);exports.coreModule.directive(BindKeyDirective.directive_name,BindKeyDirective);exports.coreModule.directive(VersionDropdownDirective.directive_name,VersionDropdownDirective);exports.coreModule.directive(ForceRefreshDirective.directive_name,ForceRefreshDirective);exports.coreModule.directive(LoadingIndicatorDirective.directive_name,LoadingIndicatorDirective);exports.coreModule.directive(OnScrollIntoViewDirective.directive_name,OnScrollIntoViewDirective);exports.coreModule.directive(MarkdownDirective.directive_name,
MarkdownDirective);exports.coreModule.directive(MemoryItemsProviderDirective.directive_name,MemoryItemsProviderDirective);exports.coreModule.directive(PagedFilteredTableDirective.directive_name,PagedFilteredTableDirective);exports.coreModule.directive(TableTopDirective.directive_name,TableTopDirective);exports.coreModule.directive(TableBottomDirective.directive_name,TableBottomDirective);exports.coreModule.directive(PeriodicRefreshDirective.directive_name,PeriodicRefreshDirective);exports.coreModule.directive(InfiniteTableDirective.directive_name,
InfiniteTableDirective);exports.coreModule.directive(ResultsCollectionDirective.directive_name,ResultsCollectionDirective);exports.coreModule.directive(SplitterDirective.directive_name,SplitterDirective);exports.coreModule.directive(SplitterPaneDirective.directive_name,SplitterPaneDirective);exports.coreModule.directive(ClockDirective.directive_name,ClockDirective);exports.coreModule.directive(DownloadCollectionAsDirective.directive_name,DownloadCollectionAsDirective);exports.coreModule.directive(DownloadCollectionFilesDirective.directive_name,
DownloadCollectionFilesDirective);exports.coreModule.directive(WizardFormDirective.directive_name,WizardFormDirective);exports.coreModule.directive(WizardFormPageDirective.directive_name,WizardFormPageDirective);exports.coreModule.directive(ConfirmationDialogDirective.directive_name,ConfirmationDialogDirective);exports.coreModule.directive(DisableIfNoTraitDirective.directive_name,DisableIfNoTraitDirective);exports.coreModule.directive(CanaryOnlyDirective.directive_name,CanaryOnlyDirective);exports.coreModule.directive(NonCanaryOnlyDirective.directive_name,
NonCanaryOnlyDirective);exports.coreModule.directive(SearchBoxDirective.directive_name,SearchBoxDirective);exports.coreModule.directive(ServerErrorButtonDirective.directive_name,ServerErrorButtonDirective);exports.coreModule.directive(ServerErrorDialogDirective.directive_name,ServerErrorDialogDirective);exports.coreModule.directive(ServerErrorPreviewDirective.directive_name,ServerErrorPreviewDirective);exports.coreModule.directive(TroggleDirective.directive_name,TroggleDirective);exports.coreModule.service(ApiService.service_name,
ApiService);exports.coreModule.service(FirebaseService.service_name,FirebaseService);exports.coreModule.service(ReflectionService.service_name,ReflectionService);exports.coreModule.service(TimeService.service_name,TimeService);exports.coreModule.service(DialogService.service_name,DialogService);exports.coreModule.service(LoadingIndicatorService.service_name,LoadingIndicatorService);exports.coreModule.filter(BasenameFilter.filter_name,BasenameFilter);exports.coreModule.filter(BytesToHexFilter.filter_name,
BytesToHexFilter);exports.coreModule.filter(EncodeUriComponentFilter.filter_name,EncodeUriComponentFilter);exports.coreModule.filter(HexNumberFilter.filter_name,HexNumberFilter);exports.coreModule.filter(TimeSinceFilter.filter_name,TimeSinceFilter);exports.coreModule.filter(TimestampFilter.filter_name,TimestampFilter);exports.coreModule.factory(ServerErrorInterceptorFactory.factory_name,ServerErrorInterceptorFactory);exports.coreModule.config(function($httpProvider){$httpProvider.interceptors.push(ServerErrorInterceptorFactory.factory_name)});
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.autoGeneratedAes128KeyFormDirective");goog.module.declareLegacyNamespace();exports.generateRandomBytes=function(length){var tokens="0123456789abcdef";var result=[];for(var i=0;i<length*2;++i)result.push(tokens[Math.floor(Math.random()*16)]);return result.join("")};const AutoGeneratedAES128KeyFormController=function($scope){this.scope_=$scope;this.scope_.$watch("value",this.onValueChange_.bind(this))};AutoGeneratedAES128KeyFormController.prototype.onValueChange_=
function(newValue){if(angular.isDefined(newValue)&&!newValue["value"])newValue["value"]=exports.generateRandomBytes(16)};exports.AutoGeneratedAES128KeyFormDirective=function(){return{scope:{value:"=",metadata:"=?",hiddenFields:"=?"},restrict:"E",templateUrl:"/static/angular-components/forms/"+"auto-generated-aes128-key-form.html",controller:AutoGeneratedAES128KeyFormController,controllerAs:"controller"}};exports.AutoGeneratedAES128KeyFormDirective.directive_name="grrFormAutoGeneratedAes128Key";exports.AutoGeneratedAES128KeyFormDirective.semantic_type=
"AutoGeneratedAES128Key";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.bytesFormDirective");goog.module.declareLegacyNamespace();exports.bytesToHexEncodedString=function(bytes){var segmentStart=0;var str=[];var blen=bytes.length;for(var i=0;i<blen;i+=1){var c=bytes.charCodeAt(i);if(c<32||c>126){var segmentLength=i-segmentStart;if(segmentLength>0)str.push(bytes.substr(segmentStart,segmentLength));segmentStart=i+1;var hc=c.toString(16);if(hc.length==1)hc="0"+hc;str.push("\\x"+hc)}}segmentLength=blen-
segmentStart;if(segmentLength>0)str.push(bytes.substr(segmentStart,segmentLength));return str.join("")};var bytesToHexEncodedString=exports.bytesToHexEncodedString;exports.hexEncodedStringToBytes=function(str){return str.replace(/\\x([0-9A-Fa-f]{2})/g,function(){return String.fromCharCode(parseInt(arguments[1],16))})};var hexEncodedStringToBytes=exports.hexEncodedStringToBytes;exports.isByteString=function(str){var blen=str.length;for(var i=0;i<blen;i+=1){var c=str.charCodeAt(i);if(c>=256)return false}return true};
var isByteString=exports.isByteString;const BytesFormController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.valueString="";this.scope_.$watch("value.value",this.onValueChange_.bind(this));this.scope_.$watch("controller.valueString",this.onValueStringChange_.bind(this))};BytesFormController.prototype.onValueChange_=function(newValue){if(angular.isString(newValue))try{var base64DecodedBytes=this.window_.atob(newValue);if(base64DecodedBytes!=hexEncodedStringToBytes(this.valueString))this.valueString=
bytesToHexEncodedString(base64DecodedBytes)}catch(err){this.valueString=""}};BytesFormController.prototype.onValueStringChange_=function(newValue){if(angular.isUndefined(newValue))return;if(!isByteString(newValue)){this.scope_["value"]["validationError"]="Unicode characters are not allowed in a byte string.";return}else delete this.scope_["value"]["validationError"];this.scope_["value"]["value"]=this.window_.btoa(hexEncodedStringToBytes(newValue))};exports.BytesFormDirective=function(){return{restrict:"E",
scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/bytes-form.html",controller:BytesFormController,controllerAs:"controller"}};exports.BytesFormDirective.directive_name="grrFormBytes";exports.BytesFormDirective.semantic_type="RDFBytes";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.clientLabelFormDirective");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const ClientLabelFormController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.labelsList;this.clientLabel;this.formLabel;this.hideEmptyOption;this.emptyOptionLabel;this.grrApiService_.get("/clients/labels").then(function(response){this.labelsList=stripTypeInfo(response["data"]["items"]);
this.scope_.$watch("controller.hideEmptyOption",function(){if(!this.clientLabel&&this.hideEmptyOption&&this.labelsList.length>0)this.clientLabel=this.labelsList[0]["name"]}.bind(this))}.bind(this))};ClientLabelFormController.prototype.$onInit=function(){this.hideEmptyOption=this.hideEmptyOption||false;this.emptyOptionLabel=this.emptyOptionLabel||"-- All clients --"};exports.ClientLabelFormDirective=function(){return{scope:{clientLabel:"=",formLabel:"=?",hideEmptyOption:"=?",emptyOptionLabel:"=?"},
bindToController:true,restrict:"E",templateUrl:"/static/angular-components/forms/client-label-form.html",controller:ClientLabelFormController,controllerAs:"controller"}};exports.ClientLabelFormDirective.directive_name="grrFormClientLabel";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.datetimeFormDirective");goog.module.declareLegacyNamespace();class DatetimeFormController{constructor($scope){this.scope_=$scope;this.valueString="";this.isInvalid=false;this.format="YYYY-MM-DD HH:mm";this.example=moment.utc().format(this.format);this.scope_.$watch("value.value",val=>this.onValueChange_(val));this.scope_.$watch("controller.valueString",val=>this.onValueStringChange_(val))}onValueChange_(newValue){if(newValue===
undefined||newValue===null){if(this.valueString&&!this.isInvalid)this.valueString="";return}const parsed=moment.utc(newValue/1E3);if(!parsed.isValid()){this.valueString="";return}if(this.valueString===parsed.format(this.format))return;this.valueString=parsed.format(this.format)}onValueStringChange_(newValue){const parsed=moment.utc(newValue,this.format,true);this.isInvalid=!parsed.isValid();if(parsed.isValid())this.scope_.value.value=parsed.valueOf()*1E3;else this.scope_.value.value=null}today(){this.scope_.value.value=
moment().valueOf()*1E3}}exports.DatetimeFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/datetime-form.html",controller:DatetimeFormController,controllerAs:"controller"}};exports.DatetimeFormDirective.directive_name="grrFormDatetime";exports.DatetimeFormDirective.semantic_type="RDFDatetime";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.dictFormDirective");goog.module.declareLegacyNamespace();const DictFormController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.keyValueList;this.keyValueDescriptor;this.stringDefault;this.grrReflectionService_.getRDFValueDescriptor("RDFString").then(function(descriptor){this.stringDefault=descriptor["default"];this.scope_.$watch("controller.keyValueList",this.onKeyValueListChange_.bind(this),
true);this.scope_.$watch("value.value",this.onValueChange_.bind(this),true)}.bind(this))};DictFormController.prototype.convertFromRDFString=function(value){if(angular.isUndefined(value)||value["type"]!="RDFString")return value;value=angular.copy(value);var s=value["value"].trim();if(/^\d+$/.test(s)){value["value"]=parseInt(s,10);value["type"]="RDFInteger"}else if(/^0x[0-9a-fA-F]+$/.test(s)){value["value"]=parseInt(s.substring(2),16);value["type"]="RDFInteger"}else if(s.toLowerCase()=="true"){value["value"]=
true;value["type"]="RDFBool"}else if(s.toLowerCase()=="false"){value["value"]=false;value["type"]="RDFBool"}return value};DictFormController.prototype.onKeyValueListChange_=function(newValue){if(angular.isDefined(newValue)){this.scope_.value.value={};for(var i=0;i<this.keyValueList.length;++i){var pair=this.keyValueList[i];this.scope_.value.value[pair["key"]]=this.convertFromRDFString(pair["value"])}}};DictFormController.prototype.onValueChange_=function(newValue){if(angular.isObject(newValue)){if(angular.isUndefined(this.keyValueList))this.keyValueList=
[];angular.forEach(newValue,function(value,key){var found=false;for(var i=0;i<this.keyValueList.length;++i){var pair=this.keyValueList[i];if(pair["key"]==key){found=true;if(!angular.equals(this.convertFromRDFString(pair["value"]),value))pair["value"]=value}}if(!found)this.keyValueList.push({key:key,value:value})}.bind(this))}else this.keyValueList=[]};DictFormController.prototype.addPair=function(){this.keyValueList.push({key:"",value:angular.copy(this.stringDefault)})};DictFormController.prototype.removePair=
function(index){this.keyValueList.splice(index,1)};exports.DictFormDirective=function(){return{restrict:"E",scope:{value:"="},templateUrl:"/static/angular-components/forms/dict-form.html",controller:DictFormController,controllerAs:"controller"}};exports.DictFormDirective.directive_name="grrFormDict";exports.DictFormDirective.semantic_types=["dict","Dict"];return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.durationDirective");goog.module.declareLegacyNamespace();var hasFraction_=function(value){return value-Math.floor(value)>1E-16};exports.stringifySeconds=function(value){if(value==0)return"0";var newDuration=moment.duration(value,"s");var unit;var units=["d","h","m","s"];for(var i=0;i<units.length;++i)if(!hasFraction_(newDuration.as(units[i]))){unit=units[i];break}if(angular.isUndefined(unit))throw new Error("Internal logic error: unit can't be undefined.");
var n=newDuration.as(unit);if(unit=="d"&&n%7==0){n=n/7;unit="w"}return n.toString()+unit};const DurationController=function($scope){this.scope_=$scope;this.stringifiedDuration;this.scope_.$watch("::value",this.onValueChange.bind(this))};DurationController.prototype.onValueChange=function(newValue){if(newValue!==undefined&&angular.isNumber(newValue.value)){const duration=newValue.value;this.stringifiedDuration=exports.stringifySeconds(duration)}else this.stringifiedDuration="-"};exports.DurationDirective=
function(){return{scope:{value:"="},restrict:"E",template:'<nobr ng-if="::controller.stringifiedDuration">'+"{$ ::controller.stringifiedDuration $}</nobr>",controller:DurationController,controllerAs:"controller"}};exports.DurationDirective.directive_name="grrDuration";exports.DurationDirective.semantic_type="DurationSeconds";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.durationFormDirective");goog.module.declareLegacyNamespace();const {stringifySeconds}=goog.require("grrUi.semantic.durationDirective");const DurationFormController=function($scope){this.scope_=$scope;this.valueString="";this.isInvalid=false;this.regex_=/^(\d+)([smhdw])?$/;this.scope_.$watch("value.value",this.onValueChange_.bind(this));this.scope_.$watch("controller.valueString",this.onValueStringChange_.bind(this))};DurationFormController.prototype.parseString_=
function(stringValue){var match=stringValue.trim().match(this.regex_);if(match==null)return null;else{var n=parseInt(match[1],10);var unit=match[2]||"s";return moment.duration(n,unit)}};DurationFormController.prototype.onValueChange_=function(newValue){if(angular.isNumber(newValue)){var currentParsedDuration=this.parseString_(this.valueString);if(currentParsedDuration!=null&&newValue==currentParsedDuration.asSeconds())return;this.valueString=stringifySeconds(newValue)}};DurationFormController.prototype.onValueStringChange_=
function(newValue){if(newValue==""){this.scope_.value.value=null;this.isInvalid=false}else{var duration=this.parseString_(newValue);this.scope_.value.value=duration!==null?duration.asSeconds():null;this.isInvalid=duration===null}};exports.DurationFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/duration-form.html",controller:DurationFormController,controllerAs:"controller"}};exports.DurationFormDirective.directive_name="grrFormDuration";
exports.DurationFormDirective.semantic_type="DurationSeconds";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.extFlagsConditionFormDirective");goog.module.declareLegacyNamespace();const ExtFlagsConditionFormController=function($scope){this.linuxPickerShown=false;this.osxPickerShown=false};const ExtFlagsConditionFormDirective=function(){return{restrict:"E",scope:{value:"="},templateUrl:"/static/angular-components/forms/ext-flags-condition-form.html",controller:ExtFlagsConditionFormController,controllerAs:"controller"}};ExtFlagsConditionFormDirective.directive_name=
"grrExtFlagsConditionForm";ExtFlagsConditionFormDirective.semantic_type="FileFinderExtFlagsCondition";exports.ExtFlagsConditionFormDirective=ExtFlagsConditionFormDirective;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.extFlags");goog.module.declareLegacyNamespace();let Flag;const getLinuxFlagByIdentifier=function(identifier){const result=LINUX_FLAGS.find(flag=>flag.identifier==identifier);if(result===undefined)throw new Error(`flag with identifier '${identifier}' not found`);return result};const getFlagByName=function(name,flags){const result=flags.find(flag=>flag.name==name);if(result===undefined)throw new Error(`flag with name '${name}' not found`);
return result};const getLinuxFlagByName=function(name){return getFlagByName(name,LINUX_FLAGS)};const getOsxFlagByName=function(name){return getFlagByName(name,OSX_FLAGS)};const getLinuxFlagMaskByName=function(name){return getLinuxFlagByName(name).mask};const getOsxFlagMaskByName=function(name){return getOsxFlagByName(name).mask};const getLinuxFlagMaskByNames=function(names){return names.map(getLinuxFlagMaskByName).reduce((acc,mask)=>acc|mask)};const getOsxFlagMaskByNames=function(names){return names.map(getOsxFlagMaskByName).reduce((acc,
mask)=>acc|mask)};const LINUX_FLAGS=[{name:"FS_SECRM_FL",identifier:"s",mask:1,description:"secure deletion"},{name:"FS_UNRM_FL",identifier:"u",mask:2,description:"undelete"},{name:"FS_COMPR_FL",identifier:"c",mask:4,description:"compress file"},{name:"FS_SYNC_FL",identifier:"S",mask:8,description:"synchronous updates"},{name:"FS_IMMUTABLE_FL",identifier:"i",mask:16,description:"immutable file"},{name:"FS_APPEND_FL",identifier:"a",mask:32,description:"writes to file may only append"},{name:"FS_NODUMP_FL",
identifier:"d",mask:64,description:"do not dump file"},{name:"FS_NOATIME_FL",identifier:"A",mask:128,description:"do not update atime"},{name:"FS_DIRTY_FL",identifier:"Z",mask:256,description:"compressed file is dirty"},{name:"FS_COMPRBLK_FL",identifier:"B",mask:512,description:"one or more compressed clusters"},{name:"FS_NOCOMP_FL",identifier:"X",mask:1024,description:"do not compress"},{name:"FS_ECOMPR_FL",identifier:"E",mask:2048,description:"compression error"},{name:"FS_INDEX_FL",identifier:"I",
mask:4096,description:"hash-indexed directory"},{name:"FS_JOURNAL_DATA_FL",identifier:"j",mask:16384,description:"reserved for ext3"},{name:"FS_NOTAIL_FL",identifier:"t",mask:32768,description:"file tail should not be merged"},{name:"FS_DIRSYNC_FL",identifier:"D",mask:65536,description:"dirsync behaviour (directories only)"},{name:"FS_TOPDIR_FL",identifier:"T",mask:131072,description:"top of directory hierarchies"},{name:"EXT4_HUGE_FILE_FL",identifier:"h",mask:262144,description:"set to each huge file"},
{name:"FS_EXTENT_FL",identifier:"e",mask:524288,description:"extents"},{name:"FS_NOCOW_FL",identifier:"C",mask:8388608,description:"do not copy-on-write"}];const LINUX_FLAGS_ORDERED="suSDiadAcBZXEjItTehC".split("").map(getLinuxFlagByIdentifier);const OSX_FLAGS=[{name:"UF_NODUMP",identifier:"nodump",mask:1,description:"do not dump file"},{name:"UF_IMMUTABLE",identifier:"uimmutable",mask:2,description:"file may not be changed"},{name:"UF_APPEND",identifier:"uappend",mask:4,description:"writes to file may only append"},
{name:"UF_OPAQUE",identifier:"opaque",mask:8,description:"directory is opaque wrt. union"},{name:"UF_HIDDEN",identifier:"hidden",mask:32768,description:"hint that this item should not be displayed in a GUI"},{name:"SF_ARCHIVED",identifier:"archived",mask:65536,description:"file is archived"},{name:"SF_IMMUTABLE",identifier:"simmutable",mask:131072,description:"file may not be changed"},{name:"SF_APPEND",identifier:"sappend",mask:262144,description:"writes to file may only append"},{name:"SF_NOUNLINK",
identifier:"sunlnk",mask:1048576,description:"item may not be removed, renamed or mounted on"}];exports.Flag=Flag;exports.LINUX_FLAGS=LINUX_FLAGS;exports.LINUX_FLAGS_ORDERED=LINUX_FLAGS_ORDERED;exports.OSX_FLAGS=OSX_FLAGS;exports.getLinuxFlagMaskByNames=getLinuxFlagMaskByNames;exports.getOsxFlagMaskByNames=getOsxFlagMaskByNames;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.extFlagsTroggling");goog.module.declareLegacyNamespace();const {Flag}=goog.require("grrUi.client.extFlags");const {TroggleState}=goog.require("grrUi.core.troggleDirective");class TroggableFlag{constructor(owner,flag){this.owner=owner;this.name=flag.name;this.identifier=flag.identifier;this.mask=flag.mask;this.description=flag.description}get state(){const bitsSet=this.owner.bitsSet;const bitsUnset=this.owner.bitsUnset;if((this.mask&
bitsSet&bitsUnset)!==0)throw new Error(`${this.name} required to be both set and unset`);if((this.mask&bitsSet)!==0)return TroggleState.SET;if((this.mask&bitsUnset)!==0)return TroggleState.UNSET;return TroggleState.VOID}set state(value){switch(value){case TroggleState.SET:this.owner.bitsSet|=this.mask;this.owner.bitsUnset&=~this.mask;break;case TroggleState.UNSET:this.owner.bitsSet&=~this.mask;this.owner.bitsUnset|=this.mask;break;case TroggleState.VOID:this.owner.bitsSet&=~this.mask;this.owner.bitsUnset&=
~this.mask;break;default:throw new Error(`unexpected state value: ${value}`);}}}class TroggableFlags{constructor(flags){this.bitsSet=0;this.bitsUnset=0;this.children=[];for(const flag of flags)this.children.push(new TroggableFlag(this,flag))}}exports.TroggableFlag=TroggableFlag;exports.TroggableFlags=TroggableFlags;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.extFlagsLinuxPickerLongDirective");goog.module.declareLegacyNamespace();const {LINUX_FLAGS_ORDERED}=goog.require("grrUi.client.extFlags");const {TroggableFlags}=goog.require("grrUi.forms.extFlagsTroggling");const ExtFlagsLinuxPickerLongController=function($scope){this.flags=new TroggableFlags(LINUX_FLAGS_ORDERED);$scope.$watch("bitsSet.value",value=>{this.flags.bitsSet=value});$scope.$watch("bitsUnset.value",value=>{this.flags.bitsUnset=
value});$scope.$watch("controller.flags.bitsSet",value=>{$scope["bitsSet"]["value"]=value});$scope.$watch("controller.flags.bitsUnset",value=>{$scope["bitsUnset"]["value"]=value})};const ExtFlagsLinuxPickerLongDirective=function(){return{restrict:"E",scope:{bitsSet:"=",bitsUnset:"="},templateUrl:"/static/angular-components/forms/ext-flags-linux-picker-long.html",controller:ExtFlagsLinuxPickerLongController,controllerAs:"controller"}};ExtFlagsLinuxPickerLongDirective.directive_name="grrExtFlagsLinuxPickerLong";
exports.ExtFlagsLinuxPickerLongDirective=ExtFlagsLinuxPickerLongDirective;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.extFlagsLinuxPickerShortDirective");goog.module.declareLegacyNamespace();const {LINUX_FLAGS_ORDERED}=goog.require("grrUi.client.extFlags");const {TroggableFlags}=goog.require("grrUi.forms.extFlagsTroggling");const ExtFlagsLinuxPickerShortController=function($scope){this.flags=new TroggableFlags(LINUX_FLAGS_ORDERED);$scope.$watch("bitsSet.value",value=>{this.flags.bitsSet=value});$scope.$watch("bitsUnset.value",value=>{this.flags.bitsUnset=
value});$scope.$watch("controller.flags.bitsSet",value=>{$scope["bitsSet"]["value"]=value});$scope.$watch("controller.flags.bitsUnset",value=>{$scope["bitsUnset"]["value"]=value})};const ExtFlagsLinuxPickerShortDirective=function(){return{restrict:"E",scope:{bitsSet:"=",bitsUnset:"="},templateUrl:"/static/angular-components/forms/ext-flags-linux-picker-short.html",controller:ExtFlagsLinuxPickerShortController,controllerAs:"controller"}};ExtFlagsLinuxPickerShortDirective.directive_name="grrExtFlagsLinuxPickerShort";
exports.ExtFlagsLinuxPickerShortDirective=ExtFlagsLinuxPickerShortDirective;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.extFlagsOsxPickerDirective");goog.module.declareLegacyNamespace();const {OSX_FLAGS}=goog.require("grrUi.client.extFlags");const {TroggableFlags}=goog.require("grrUi.forms.extFlagsTroggling");const ExtFlagsOsxPickerController=function($scope){this.flags=new TroggableFlags(OSX_FLAGS);$scope.$watch("bitsSet.value",value=>{this.flags.bitsSet=value});$scope.$watch("bitsUnset.value",value=>{this.flags.bitsUnset=value});$scope.$watch("controller.flags.bitsSet",
value=>{$scope["bitsSet"]["value"]=value});$scope.$watch("controller.flags.bitsUnset",value=>{$scope["bitsUnset"]["value"]=value})};const ExtFlagsOsxPickerDirective=function(){return{restrict:"E",scope:{bitsSet:"=",bitsUnset:"="},templateUrl:"/static/angular-components/forms/ext-flags-osx-picker.html",controller:ExtFlagsOsxPickerController,controllerAs:"controller"}};ExtFlagsOsxPickerDirective.directive_name="grrExtFlagsOsxPicker";exports.ExtFlagsOsxPickerDirective=ExtFlagsOsxPickerDirective;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.foremanLabelRuleFormDirective");goog.module.declareLegacyNamespace();const ForemanLabelRuleFormController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.defaultLabel_="";this.grrReflectionService_.getRDFValueDescriptor("ForemanLabelClientRule").then(function(descriptor){angular.forEach(descriptor["fields"],function(field){if(field["name"]=="match_mode")this.matchModeMetadata=
field}.bind(this));this.scope_.$watch("value.value",function(value){if(angular.isDefined(value)){if(angular.isUndefined(value["match_mode"]))value["match_mode"]=angular.copy(this.matchModeMetadata["default"]);if(angular.isUndefined(value["label_names"]))value["label_names"]=[];if(value["label_names"].length==0)this.addLabel()}}.bind(this))}.bind(this))};ForemanLabelRuleFormController.prototype.addLabel=function(){this.scope_["value"]["value"]["label_names"].push({type:"unicode",value:this.defaultLabel_})};
ForemanLabelRuleFormController.prototype.removeLabel=function(index){this.scope_["value"]["value"]["label_names"].splice(index,1)};exports.ForemanLabelRuleFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/foreman-label-rule-form.html",controller:ForemanLabelRuleFormController,controllerAs:"controller"}};exports.ForemanLabelRuleFormDirective.directive_name="grrFormLabel";exports.ForemanLabelRuleFormDirective.semantic_type="ForemanLabelClientRule";
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.globExpressionFormDirective");goog.module.declareLegacyNamespace();exports.getSuggestions=function(expression,entries){const DELIMITER="%%";if(!expression||!entries)return[];const parts=expression.split(DELIMITER);if(parts.length%2===1)return[];const term=parts.pop().replace(/%$/,"");const prefix=parts.join(DELIMITER);return entries.filter(field=>field.includes(term)).map(field=>DELIMITER+field+DELIMITER).map(field=>({expressionWithSuggestion:prefix+
field,suggestion:field}))};const GlobExpressionFormController=function(grrApiService,$scope){this.fields=[];grrApiService.get("/clients/kb-fields").then(res=>res.data.items.map(item=>item.value)).then(fields=>this.fields=fields)};GlobExpressionFormController.prototype.getSuggestions=function(expression){return exports.getSuggestions(expression,this.fields)};exports.GlobExpressionFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/glob-expression-form.html",
controller:GlobExpressionFormController,controllerAs:"controller"}};exports.GlobExpressionFormDirective.directive_name="grrFormGlobExpression";exports.GlobExpressionFormDirective.semantic_type="GlobExpression";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.globExpressionsListFormDirective");goog.module.declareLegacyNamespace();const GlobExpressionsListFormController=function($scope){this.scope_=$scope;this.scope_.$watchGroup(["descriptor","value","field"],this.onArgumentsChange_.bind(this))};GlobExpressionsListFormController.prototype.onArgumentsChange_=function(){if(angular.isDefined(this.scope_["descriptor"])&&angular.isDefined(this.scope_["field"])&&angular.isDefined(this.scope_["value"]))if(this.scope_["value"].length==
0){var newGlob=angular.copy(this.scope_["descriptor"]["default"]);this.scope_["value"].push(newGlob)}};exports.GlobExpressionsListFormDirective=function(){return{restrict:"E",scope:{descriptor:"=",value:"=",field:"="},templateUrl:"/static/angular-components/forms/"+"glob-expressions-list-form.html",controller:GlobExpressionsListFormController,controllerAs:"controller"}};exports.GlobExpressionsListFormDirective.directive_name="grrGlobExpressionsListForm";exports.GlobExpressionsListFormDirective.hideCustomTemplateLabel=
true;exports.GlobExpressionsListFormDirective.semantic_type="GlobExpression";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.outputPluginDescriptorFormDirective");goog.module.declareLegacyNamespace();const OutputPluginDescriptorFormController=function($scope,grrApiService,grrReflectionService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrReflectionService_=grrReflectionService;this.outputPluginsDescriptors;this.allowedPluginsNames;this.grrApiService_.get("/output-plugins/all").then(function(response){this.outputPluginsDescriptors={};
angular.forEach(response["data"]["items"],function(item){if(item["plugin_type"]==="LEGACY")this.outputPluginsDescriptors[item["name"]]=item}.bind(this));this.allowedPluginsNames=Object.keys(this.outputPluginsDescriptors).sort();if(angular.isUndefined(this.scope_.$eval("value.value.plugin_name.value")))this.scope_["value"]["value"]["plugin_name"]={type:"RDFString",value:this.allowedPluginsNames[0]};this.scope_.$watch("value.value.plugin_name.value",function(newValue){if(angular.isDefined(newValue)){var argsType=
this.outputPluginsDescriptors[newValue]["args_type"];var pluginArgs=this.scope_["value"]["value"]["plugin_args"];if(angular.isUndefined(pluginArgs)||pluginArgs["type"]!=argsType)this.grrReflectionService_.getRDFValueDescriptor(argsType).then(function(descriptor){this.scope_["value"]["value"]["plugin_args"]=angular.copy(descriptor["default"])}.bind(this))}}.bind(this))}.bind(this))};exports.OutputPluginDescriptorFormDirective=function(){return{restrict:"E",scope:{value:"="},templateUrl:"/static/angular-components/forms/"+
"output-plugin-descriptor-form.html",controller:OutputPluginDescriptorFormController,controllerAs:"controller"}};exports.OutputPluginDescriptorFormDirective.directive_name="grrOutputPluginDescriptorForm";exports.OutputPluginDescriptorFormDirective.semantic_type="OutputPluginDescriptor";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.semanticEnumFormDirective");goog.module.declareLegacyNamespace();const SemanticEnumFormController=function($scope){this.scope_=$scope;this.allowedOptions=[];this.scope_.$watch("metadata.allowed_values",this.onAllowedValuesChange_.bind(this))};SemanticEnumFormController.prototype.onAllowedValuesChange_=function(newValue){this.allowedOptions=[];if(angular.isDefined(newValue)){this.allowedOptions=[];angular.forEach(newValue,function(option){var defaultLabel=
"";var defaultOptionName=this.scope_.$eval("metadata.default.value");if(defaultOptionName==option.name)defaultLabel=" (default)";var label=option.name;if(option.doc)label=option.doc;this.allowedOptions.push({value:option.name,label:label+defaultLabel})}.bind(this))}};exports.SemanticEnumFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"="},templateUrl:"/static/angular-components/forms/semantic-enum-form.html",controller:SemanticEnumFormController,controllerAs:"controller"}};
exports.SemanticEnumFormDirective.directive_name="grrFormEnum";exports.SemanticEnumFormDirective.semantic_type="EnumNamedValue";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.semanticPrimitiveFormDirective");goog.module.declareLegacyNamespace();const SemanticPrimitiveFormController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.valueType;this.scope_.$watch("value.type",this.onValueTypeChange_.bind(this))};SemanticPrimitiveFormController.prototype.onValueTypeChange_=function(newValue){if(newValue===undefined){this.valueType=undefined;return}var descriptorHandler=
function(descriptor){var allowedTypes=exports.SemanticPrimitiveFormDirective.semantic_types;var typeIndex=-1;angular.forEach(allowedTypes,function(type){var index=descriptor["mro"].indexOf(type);if(index!=-1&&(typeIndex==-1||typeIndex>index)){typeIndex=index;this.valueType=type}}.bind(this));if(!this.valueType)this.valueType="RDFString"}.bind(this);this.grrReflectionService_.getRDFValueDescriptor(newValue).then(descriptorHandler)};exports.SemanticPrimitiveFormDirective=function(){return{restrict:"E",
scope:{value:"="},templateUrl:"/static/angular-components/forms/"+"semantic-primitive-form.html",controller:SemanticPrimitiveFormController,controllerAs:"controller"}};exports.SemanticPrimitiveFormDirective.directive_name="grrFormPrimitive";exports.SemanticPrimitiveFormDirective.semantic_types=["RDFBool","bool","RDFInteger","int","long","float","RDFString","basestring","RDFURN","str","unicode","bytes"];return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.semanticProtoFormDirective");goog.module.declareLegacyNamespace();const SemanticProtoFormController=function($scope,$attrs,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.advancedShown=false;this.hasAdvancedFields=false;this.expanded=false;this.editedValue;this.lastAssignedScopeValue_;if(angular.isDefined($attrs["hiddenFields"])&&angular.isDefined($attrs["visibleFields"]))throw new Error("Either hidden-fields or visible-fields attribute may "+
"be specified, not both.");this.scope_.$watch("value",this.onValueChange_.bind(this),true);this.scope_.$watch("controller.editedValue.value",this.onEditedValueChange_.bind(this),true);this.boundNotExplicitlyHiddenFields=this.notExplicitlyHiddenFields_.bind(this)};SemanticProtoFormController.prototype.notExplicitlyHiddenFields_=function(field,opt_index){if(angular.isDefined(this.scope_["hiddenFields"]))return this.scope_["hiddenFields"].indexOf(field["name"])==-1;else if(angular.isDefined(this.scope_["visibleFields"]))return this.scope_["visibleFields"].indexOf(field["name"])!=
-1;else return true};SemanticProtoFormController.prototype.regularFieldsOnly=function(field,index){return angular.isUndefined(field["labels"])||field["labels"].indexOf("HIDDEN")==-1&&field["labels"].indexOf("ADVANCED")==-1};SemanticProtoFormController.prototype.advancedFieldsOnly=function(field,index){return angular.isDefined(field["labels"])&&field["labels"].indexOf("HIDDEN")==-1&&field["labels"].indexOf("ADVANCED")!=-1};SemanticProtoFormController.prototype.onValueChange_=function(newValue,oldValue){if(angular.isUndefined(newValue)){this.descriptors=
undefined;this.valueDescriptor=undefined;this.editedValue=undefined;return}if(angular.isDefined(this.lastAssignedScopeValue_)&&angular.isDefined(newValue)&&this.lastAssignedScopeValue_["type"]===newValue["type"]){const updatedField=this.valueDescriptor["fields"].find(field=>{const hasHiddenLabel=field["labels"]&&field["labels"].indexOf("HIDDEN")!=-1;return!hasHiddenLabel&&this.notExplicitlyHiddenFields_(field)&&!angular.equals(newValue["value"][field["name"]],this.lastAssignedScopeValue_["value"][field["name"]])});
if(updatedField===undefined)return}this.grrReflectionService_.getRDFValueDescriptor(this.scope_["value"]["type"],true).then(this.onDescriptorsFetched_.bind(this))};SemanticProtoFormController.prototype.onEditedValueChange_=function(newValue,oldValue){if(angular.isDefined(newValue)){if(angular.isDefined(oldValue))angular.forEach(newValue,function(value,key){if(!angular.equals(oldValue[key],newValue[key]))this.scope_["value"]["value"][key]=angular.copy(value)}.bind(this));angular.forEach(this.valueDescriptor["fields"],
function(field){if(this.notExplicitlyHiddenFields_(field))if(field["type"]&&angular.equals(this.scope_["value"]["value"][field["name"]],this.descriptors[field["type"]]["default"])&&(angular.isUndefined(field["default"])||angular.equals(field["default"],this.descriptors[field["type"]]["default"])))delete this.scope_["value"]["value"][field["name"]]}.bind(this));this.lastAssignedScopeValue_=angular.copy(this.scope_["value"])}};SemanticProtoFormController.prototype.onDescriptorsFetched_=function(descriptors){this.descriptors=
descriptors;this.valueDescriptor=angular.copy(descriptors[this.scope_["value"]["type"]]);if(angular.isUndefined(this.editedValue))this.editedValue=angular.copy(this.scope_["value"]);if(angular.isUndefined(this.editedValue["value"]))this.editedValue.value={};angular.forEach(this.valueDescriptor["fields"],function(field){if(angular.isDefined(field["labels"])){if(field["labels"].indexOf("HIDDEN")!=-1)return;if(field["labels"].indexOf("ADVANCED")!=-1)this.hasAdvancedFields=true}let defaultFieldValue=
undefined;if(!field["dynamic"])if(field["repeated"]){field["depth"]=0;defaultFieldValue=[]}else{field["depth"]=(this.scope_.$eval("metadata.depth")||0)+1;if(angular.isDefined(field["default"]))defaultFieldValue=angular.copy(field["default"]);else defaultFieldValue=angular.copy(descriptors[field["type"]]["default"])}const scopeValueContent=this.scope_["value"]["value"];const editedValueConent=this.editedValue["value"];const fieldName=field["name"];const fieldValueChanged=!angular.equals(scopeValueContent[fieldName],
editedValueConent[fieldName]);if(fieldValueChanged&&!(scopeValueContent[fieldName]===undefined&&angular.equals(editedValueConent[fieldName],defaultFieldValue)))editedValueConent[fieldName]=angular.copy(scopeValueContent[fieldName]);if(defaultFieldValue!==undefined&&angular.isUndefined(editedValueConent[fieldName]))editedValueConent[fieldName]=defaultFieldValue}.bind(this));this.lastAssignedScopeValue_=angular.copy(this.scope_["value"])};exports.SemanticProtoFormDirective=function(){return{scope:{value:"=",
metadata:"=?",hiddenFields:"=?",visibleFields:"=?"},restrict:"E",templateUrl:"/static/angular-components/forms/semantic-proto-form.html",controller:SemanticProtoFormController,controllerAs:"controller"}};exports.SemanticProtoFormDirective.directive_name="grrFormProto";exports.SemanticProtoFormDirective.semantic_type="RDFProtoStruct";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.semanticProtoRepeatedFieldFormDirective");goog.module.declareLegacyNamespace();const {camelCaseToDashDelimited}=goog.require("grrUi.core.utils");const SemanticProtoRepeatedFieldFormController=function($scope,$element,$compile,grrSemanticRepeatedFormDirectivesRegistryService){this.scope_=$scope;this.element_=$element;this.compile_=$compile;this.grrSemanticRepeatedFormDirectivesRegistryService_=grrSemanticRepeatedFormDirectivesRegistryService;
this.hasCustomTemplate;this.hideCustomTemplateLabel;this.scope_.$watchGroup(["field","descriptor","value"],this.onFieldDescriptorChange_.bind(this))};SemanticProtoRepeatedFieldFormController.prototype.onFieldDescriptorChange_=function(){if(angular.isDefined(this.scope_["field"])&&angular.isDefined(this.scope_["descriptor"])&&angular.isDefined(this.scope_["value"]))if(this.scope_["noCustomTemplate"])this.onCustomDirectiveNotFound_();else this.grrSemanticRepeatedFormDirectivesRegistryService_.findDirectiveForType(this.scope_["descriptor"]["mro"][0]).then(this.onCustomDirectiveFound_.bind(this),
this.onCustomDirectiveNotFound_.bind(this))};SemanticProtoRepeatedFieldFormController.prototype.onCustomDirectiveNotFound_=function(){this.hasCustomTemplate=false};SemanticProtoRepeatedFieldFormController.prototype.onCustomDirectiveFound_=function(directive){this.hasCustomTemplate=true;this.hideCustomTemplateLabel=directive["hideCustomTemplateLabel"];var element=angular.element("<span />");element.html("<"+camelCaseToDashDelimited(directive.directive_name)+' descriptor="descriptor" value="value" field="field" />');
var template=this.compile_(element);var customTemplateElement;if(this.hideCustomTemplateLabel)customTemplateElement=this.element_.find('div[name="custom-template-without-label"]');else customTemplateElement=this.element_.find('div[name="custom-template"]');customTemplateElement.html("");template(this.scope_,function(cloned,opt_scope){customTemplateElement.append(cloned)}.bind(this))};SemanticProtoRepeatedFieldFormController.prototype.addItem=function(){this.scope_.value.splice(0,0,angular.copy(this.scope_["descriptor"]["default"]))};
SemanticProtoRepeatedFieldFormController.prototype.removeItem=function(index){this.scope_.value.splice(index,1)};exports.SemanticProtoRepeatedFieldFormDirective=function(){return{scope:{value:"=",descriptor:"=",field:"=",noCustomTemplate:"="},restrict:"E",templateUrl:"/static/angular-components/forms/"+"semantic-proto-repeated-field-form.html",controller:SemanticProtoRepeatedFieldFormController,controllerAs:"controller"}};exports.SemanticProtoRepeatedFieldFormDirective.directive_name="grrFormProtoRepeatedField";
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.semanticProtoSingleFieldFormDirective");goog.module.declareLegacyNamespace();exports.SemanticProtoSingleFieldFormDirective=function(){return{scope:{value:"=",field:"="},restrict:"E",templateUrl:"/static/angular-components/forms/"+"semantic-proto-single-field-form.html"}};exports.SemanticProtoSingleFieldFormDirective.directive_name="grrFormProtoSingleField";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.semanticProtoUnionFormDirective");goog.module.declareLegacyNamespace();const SemanticProtoUnionFormController=function($scope){this.scope_=$scope;this.unionField;this.unionFieldValue;$scope.$watch("descriptor",this.onDescriptorChange_.bind(this));$scope.$watch("value.value[controller.unionField.name].value",this.onUnionFieldValueChange_.bind(this))};SemanticProtoUnionFormController.prototype.onDescriptorChange_=function(newValue){if(angular.isUndefined(newValue))this.unionField=
undefined;else angular.forEach(newValue["fields"],function(field){if(field.name==newValue["union_field"])this.unionField=field}.bind(this))};SemanticProtoUnionFormController.prototype.onUnionFieldValueChange_=function(newValue,oldValue){if(angular.isDefined(newValue)){if(angular.isDefined(oldValue)&&oldValue!==newValue){var unionPart=this.scope_["value"]["value"][this.unionFieldValue];if(angular.isObject(unionPart)){unionPart["value"]={};this.scope_["value"]["value"][this.unionFieldValue]=angular.copy(unionPart)}}this.unionFieldValue=
newValue.toLowerCase()}else this.unionFieldValue=undefined};exports.SemanticProtoUnionFormDirective=function(){return{scope:{value:"=",descriptor:"="},restrict:"E",templateUrl:"/static/angular-components/forms/"+"semantic-proto-union-form.html",controller:SemanticProtoUnionFormController,controllerAs:"controller"}};exports.SemanticProtoUnionFormDirective.directive_name="grrFormProtoUnion";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.core.semanticRegistryService");goog.module.declareLegacyNamespace();exports.SemanticRegistryService=function($q,grrReflectionService){this.q_=$q;this.grrReflectionService_=grrReflectionService;this.directivesByType_={}};var SemanticRegistryService=exports.SemanticRegistryService;SemanticRegistryService.values_service_name="grrSemanticValueDirectivesRegistryService";SemanticRegistryService.forms_service_name="grrSemanticFormDirectivesRegistryService";
SemanticRegistryService.repeated_forms_service_name="grrSemanticRepeatedFormDirectivesRegistryService";SemanticRegistryService.output_plugins_service_name="grrOutputPluginsDirectivesRegistryService";SemanticRegistryService.prototype.registerDirective=function(type,directive){this.directivesByType_[type]=directive};SemanticRegistryService.prototype.findDirectiveForMro=function(mro,overrides){overrides=overrides||{};for(var i=0;i<mro.length;++i){var objType=mro[i];var directive=overrides[objType];if(angular.isUndefined(directive))directive=
this.directivesByType_[objType];if(angular.isDefined(directive))return directive}return undefined};SemanticRegistryService.prototype.findDirectiveForType=function(type,overrides){overrides=overrides||{};if(angular.isDefined(overrides[type])){var deferred=this.q_.defer();deferred.resolve(overrides[type]);return deferred.promise}if(angular.isDefined(this.directivesByType_[type])){var deferred=this.q_.defer();deferred.resolve(this.directivesByType_[type]);return deferred.promise}var handleDescriptor=
function(descriptor){var directive=this.findDirectiveForMro(descriptor["mro"],overrides);if(angular.isDefined(directive))return directive;else return this.q_.reject(new Error("No directive found."))}.bind(this);return this.grrReflectionService_.getRDFValueDescriptor(type).then(handleDescriptor)};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.semanticValueFormDirective");goog.module.declareLegacyNamespace();let templatesCache={};exports.clearCaches=function(){templatesCache={}};exports.SemanticValueFormController=function($scope,$compile,$element,grrSemanticFormDirectivesRegistryService){this.scope_=$scope;this.compile_=$compile;this.element_=$element;this.elementScope_;this.grrSemanticFormDirectivesRegistryService_=grrSemanticFormDirectivesRegistryService;this.scope_.$watch("value.type",
this.onValueTypeChange_.bind(this))};var SemanticValueFormController=exports.SemanticValueFormController;SemanticValueFormController.prototype.onValueTypeChange_=function(newValue){this.element_.html("");if(angular.isDefined(this.elementScope_)){this.elementScope_.$destroy();this.elementScope_=undefined}if(angular.isUndefined(newValue))return;var updateElement=function(tmpl){if(angular.isDefined(tmpl)){this.elementScope_=this.scope_.$new();tmpl(this.elementScope_,function(cloned,opt_scope){this.element_.append(cloned)}.bind(this))}else this.element_.text("Can't handle type: "+
this.value["type"])}.bind(this);var value=this.scope_.value;var template=templatesCache[value["type"]];if(angular.isUndefined(template))this.compileSingleTypedValueTemplate_(value).then(function(template){templatesCache[value["type"]]=template;updateElement(template)}.bind(this));else updateElement(template)};SemanticValueFormController.prototype.camelCaseToDashDelimited=function(directiveName){return directiveName.replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase()};SemanticValueFormController.prototype.compileSingleTypedValueTemplate_=
function(value){var successHandler=function success(directive){var element=angular.element("<span />");element.html("<"+this.camelCaseToDashDelimited(directive.directive_name)+' metadata="metadata" value="value" />');return this.compile_(element)}.bind(this);var failureHandler=function failure(){var element=angular.element("<span />");element.html('<p class="form-control-static">No directive '+"for type: {$ value.type $}.</p>");return this.compile_(element)}.bind(this);return this.grrSemanticFormDirectivesRegistryService_.findDirectiveForType(value["type"]).then(successHandler,
failureHandler)};exports.SemanticValueFormDirective=function(){return{restrict:"E",scope:{value:"=",metadata:"=?"},controller:SemanticValueFormController,controllerAs:"controller"}};exports.SemanticValueFormDirective.directive_name="grrFormValue";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.timerangeFormDirective");goog.module.declareLegacyNamespace();const TimerangeFormController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.startTimeSecs;this.formStartTime;this.durationSecs;this.formDuration;this.startTimeLabel;this.durationLabel;this.grrReflectionService_.getRDFValueDescriptor("RDFDatetime").then(function(rdfDesc){this.formStartTime=angular.copy(rdfDesc["default"]);
return this.grrReflectionService_.getRDFValueDescriptor("DurationSeconds")}.bind(this)).then(function(rdfDesc){this.formDuration=angular.copy(rdfDesc["default"]);this.scope_.$watchGroup(["controller.startTimeSecs","controller.durationSecs"],this.onParamsChange_.bind(this));this.scope_.$watchGroup(["controller.formStartTime.value","controller.formDuration.value"],this.onSubformsChange_.bind(this));this.onParamsChange_([this.startTimeSecs,this.durationSecs])}.bind(this))};TimerangeFormController.prototype.onParamsChange_=
function([startTimeSecs,durationSecs]){if(startTimeSecs!==null)this.formStartTime["value"]=startTimeSecs*1E6;if(durationSecs!==null)this.formDuration["value"]=durationSecs};TimerangeFormController.prototype.onSubformsChange_=function([formStartTime,formDuration]){if(formStartTime!==null)this.startTimeSecs=formStartTime/1E6;this.durationSecs=formDuration};exports.TimerangeFormDirective=function(){return{scope:{startTimeSecs:"=",durationSecs:"=",startTimeLabel:"=?",durationLabel:"=?"},bindToController:true,
restrict:"E",templateUrl:"/static/angular-components/forms/timerange-form.html",controller:TimerangeFormController,controllerAs:"controller"}};exports.TimerangeFormDirective.directive_name="grrFormTimerange";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.forms");goog.module.declareLegacyNamespace();const {AutoGeneratedAES128KeyFormDirective}=goog.require("grrUi.forms.autoGeneratedAes128KeyFormDirective");const {BytesFormDirective}=goog.require("grrUi.forms.bytesFormDirective");const {ClientLabelFormDirective}=goog.require("grrUi.forms.clientLabelFormDirective");const {DatetimeFormDirective}=goog.require("grrUi.forms.datetimeFormDirective");const {DictFormDirective}=goog.require("grrUi.forms.dictFormDirective");
const {DurationFormDirective}=goog.require("grrUi.forms.durationFormDirective");const {ExtFlagsConditionFormDirective}=goog.require("grrUi.forms.extFlagsConditionFormDirective");const {ExtFlagsLinuxPickerLongDirective}=goog.require("grrUi.forms.extFlagsLinuxPickerLongDirective");const {ExtFlagsLinuxPickerShortDirective}=goog.require("grrUi.forms.extFlagsLinuxPickerShortDirective");const {ExtFlagsOsxPickerDirective}=goog.require("grrUi.forms.extFlagsOsxPickerDirective");const {ForemanLabelRuleFormDirective}=
goog.require("grrUi.forms.foremanLabelRuleFormDirective");const {GlobExpressionFormDirective}=goog.require("grrUi.forms.globExpressionFormDirective");const {GlobExpressionsListFormDirective}=goog.require("grrUi.forms.globExpressionsListFormDirective");const {OutputPluginDescriptorFormDirective}=goog.require("grrUi.forms.outputPluginDescriptorFormDirective");const {SemanticEnumFormDirective}=goog.require("grrUi.forms.semanticEnumFormDirective");const {SemanticPrimitiveFormDirective}=goog.require("grrUi.forms.semanticPrimitiveFormDirective");
const {SemanticProtoFormDirective}=goog.require("grrUi.forms.semanticProtoFormDirective");const {SemanticProtoRepeatedFieldFormDirective}=goog.require("grrUi.forms.semanticProtoRepeatedFieldFormDirective");const {SemanticProtoSingleFieldFormDirective}=goog.require("grrUi.forms.semanticProtoSingleFieldFormDirective");const {SemanticProtoUnionFormDirective}=goog.require("grrUi.forms.semanticProtoUnionFormDirective");const {SemanticRegistryService}=goog.require("grrUi.core.semanticRegistryService");
const {SemanticValueFormDirective}=goog.require("grrUi.forms.semanticValueFormDirective");const {TimerangeFormDirective}=goog.require("grrUi.forms.timerangeFormDirective");const {coreModule}=goog.require("grrUi.core.core");exports.formsModule=angular.module("grrUi.forms",[coreModule.name,"ui.bootstrap"]);exports.formsModule.service(SemanticRegistryService.forms_service_name,SemanticRegistryService);exports.formsModule.service(SemanticRegistryService.repeated_forms_service_name,SemanticRegistryService);
exports.formsModule.directive(AutoGeneratedAES128KeyFormDirective.directive_name,AutoGeneratedAES128KeyFormDirective);exports.formsModule.directive(BytesFormDirective.directive_name,BytesFormDirective);exports.formsModule.directive(ClientLabelFormDirective.directive_name,ClientLabelFormDirective);exports.formsModule.directive(DatetimeFormDirective.directive_name,DatetimeFormDirective);exports.formsModule.directive(DictFormDirective.directive_name,DictFormDirective);exports.formsModule.directive(DurationFormDirective.directive_name,
DurationFormDirective);exports.formsModule.directive(GlobExpressionFormDirective.directive_name,GlobExpressionFormDirective);exports.formsModule.directive(GlobExpressionsListFormDirective.directive_name,GlobExpressionsListFormDirective);exports.formsModule.directive(OutputPluginDescriptorFormDirective.directive_name,OutputPluginDescriptorFormDirective);exports.formsModule.directive(SemanticEnumFormDirective.directive_name,SemanticEnumFormDirective);exports.formsModule.directive(ExtFlagsConditionFormDirective.directive_name,
ExtFlagsConditionFormDirective);exports.formsModule.directive(ExtFlagsLinuxPickerLongDirective.directive_name,ExtFlagsLinuxPickerLongDirective);exports.formsModule.directive(ExtFlagsLinuxPickerShortDirective.directive_name,ExtFlagsLinuxPickerShortDirective);exports.formsModule.directive(ExtFlagsOsxPickerDirective.directive_name,ExtFlagsOsxPickerDirective);exports.formsModule.directive(ForemanLabelRuleFormDirective.directive_name,ForemanLabelRuleFormDirective);exports.formsModule.directive(SemanticPrimitiveFormDirective.directive_name,
SemanticPrimitiveFormDirective);exports.formsModule.directive(SemanticProtoFormDirective.directive_name,SemanticProtoFormDirective);exports.formsModule.directive(SemanticProtoSingleFieldFormDirective.directive_name,SemanticProtoSingleFieldFormDirective);exports.formsModule.directive(SemanticProtoRepeatedFieldFormDirective.directive_name,SemanticProtoRepeatedFieldFormDirective);exports.formsModule.directive(SemanticProtoUnionFormDirective.directive_name,SemanticProtoUnionFormDirective);exports.formsModule.directive(SemanticValueFormDirective.directive_name,
SemanticValueFormDirective);exports.formsModule.directive(TimerangeFormDirective.directive_name,TimerangeFormDirective);exports.formsModule.run(function(grrSemanticFormDirectivesRegistryService){var registry=grrSemanticFormDirectivesRegistryService;registry.registerDirective(AutoGeneratedAES128KeyFormDirective.semantic_type,AutoGeneratedAES128KeyFormDirective);registry.registerDirective(BytesFormDirective.semantic_type,BytesFormDirective);registry.registerDirective(DatetimeFormDirective.semantic_type,
DatetimeFormDirective);var dictSemanticTypes=DictFormDirective.semantic_types;angular.forEach(dictSemanticTypes,function(dictSemanticType){registry.registerDirective(dictSemanticType,DictFormDirective)});registry.registerDirective(DurationFormDirective.semantic_type,DurationFormDirective);registry.registerDirective(ExtFlagsConditionFormDirective.semantic_type,ExtFlagsConditionFormDirective);registry.registerDirective(GlobExpressionFormDirective.semantic_type,GlobExpressionFormDirective);registry.registerDirective(OutputPluginDescriptorFormDirective.semantic_type,
OutputPluginDescriptorFormDirective);var primitiveSemanticTypes=SemanticPrimitiveFormDirective.semantic_types;angular.forEach(primitiveSemanticTypes,function(primitiveSemanticType){registry.registerDirective(primitiveSemanticType,SemanticPrimitiveFormDirective)});registry.registerDirective(SemanticEnumFormDirective.semantic_type,SemanticEnumFormDirective);registry.registerDirective(ForemanLabelRuleFormDirective.semantic_type,ForemanLabelRuleFormDirective);registry.registerDirective(SemanticProtoFormDirective.semantic_type,
SemanticProtoFormDirective)});exports.formsModule.run(function(grrSemanticRepeatedFormDirectivesRegistryService){var registry=grrSemanticRepeatedFormDirectivesRegistryService;registry.registerDirective(GlobExpressionsListFormDirective.semantic_type,GlobExpressionsListFormDirective)});return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.apiHuntResultDirective");goog.module.declareLegacyNamespace();exports.ApiHuntResultDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/api-hunt-result.html"}};exports.ApiHuntResultDirective.directive_name="grrApiHuntResult";exports.ApiHuntResultDirective.semantic_type="ApiHuntResult";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.byteSizeDirective");goog.module.declareLegacyNamespace();var KB_UNIT=1024;var MB_UNIT=KB_UNIT*1024;var GB_UNIT=MB_UNIT*1024;const stringifyByteSize=function(value){if(value==0)return[0,""];if(value>GB_UNIT)return[value/GB_UNIT,"GiB"];else if(value>MB_UNIT)return[value/MB_UNIT,"MiB"];else if(value>KB_UNIT)return[value/KB_UNIT,"KiB"];else return[value,"B"]};const ByteSizeController=function($scope){this.scope_=$scope;this.stringifiedByteSize;
this.scope_.$watch("::value",this.onValueChange.bind(this))};ByteSizeController.prototype.onValueChange=function(newValue){if(!angular.isDefined(newValue))return;var byteSize=newValue.value;if(angular.isNumber(byteSize)){var stringified=stringifyByteSize(byteSize);var size=stringified[0];var sizeToken=stringified[1];var result=[Math.floor(size).toString()];var decimalPart=Math.round(size%1*10).toString();if(decimalPart!=="0")result.push(".",decimalPart);result.push(sizeToken);this.stringifiedByteSize=
result.join("")}else this.stringifiedByteSize="-"};exports.ByteSizeDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/byte-size.html",controller:ByteSizeController,controllerAs:"controller"}};exports.ByteSizeDirective.directive_name="grrByteSize";exports.ByteSizeDirective.semantic_type="ByteSize";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.bytesDirective");goog.module.declareLegacyNamespace();const {bytesToHexEncodedString}=goog.require("grrUi.forms.bytesFormDirective");const BytesController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.stringifiedBytes;this.scope_.$watch("::value",this.onValueChange.bind(this))};var FIRST_RENDER_LIMIT=1024;BytesController.prototype.onClick=function(e){e.stopPropagation();var bytes=this.scope_["value"]["value"];
try{this.stringifiedBytes=bytesToHexEncodedString(this.window_.atob(bytes))}catch(err){this.stringifiedBytes="base64decodeerror("+err.message+"):"+bytes}};BytesController.prototype.onValueChange=function(newValue){var bytes=newValue.value;if(angular.isString(bytes)){if(bytes.length<FIRST_RENDER_LIMIT)try{this.stringifiedBytes=bytesToHexEncodedString(this.window_.atob(bytes))}catch(err){this.stringifiedBytes="base64decodeerror("+err.message+"):"+bytes}}else this.stringifiedBytes=""};exports.BytesDirective=
function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/bytes.html",controller:BytesController,controllerAs:"controller"}};exports.BytesDirective.directive_name="grrBytes";exports.BytesDirective.semantic_types=["RDFBytes","bytes"];return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.clientUrnDirective");goog.module.declareLegacyNamespace();var ClientUrnController=function($scope,$uibModal,grrApiService){this.scope_=$scope;this.scope_.value;this.uibModal_=$uibModal;this.grrApiService_=grrApiService;this.clientDetails;this.clientId;this.scope_.$watch("::value",this.onValueChange.bind(this))};ClientUrnController.prototype.onValueChange=function(){var clientUrn;if(angular.isObject(this.scope_.value))clientUrn=
this.scope_.value.value;else clientUrn=this.scope_.value;if(angular.isString(clientUrn))this.clientId=clientUrn.replace(/^aff4:\//,"")};ClientUrnController.prototype.onInfoClick=function(){this.uibModal_.open({templateUrl:"/static/angular-components/semantic/client-urn-modal.html",scope:this.scope_});this.grrApiService_.get("clients/"+this.clientId).then(function(response){this.clientDetails=response.data}.bind(this))};exports.ClientUrnDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/client-urn.html",
controller:ClientUrnController,controllerAs:"controller"}};exports.ClientUrnDirective.directive_name="grrClientUrn";exports.ClientUrnDirective.semantic_types=["ClientURN","ApiClientId"];return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.dataObjectDirective");goog.module.declareLegacyNamespace();exports.DataObjectDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/data-object.html"}};exports.DataObjectDirective.directive_name="grrDataObject";exports.DataObjectDirective.semantic_type="ApiDataObject";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.dictDirective");goog.module.declareLegacyNamespace();exports.DictDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/dict.html"}};exports.DictDirective.directive_name="grrDict";exports.DictDirective.semantic_types=["dict","Dict"];return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.encryptionKeyDirective");goog.module.declareLegacyNamespace();exports.stringifyEncryptionKey=function(base64Bytes){var decoded=window.atob(base64Bytes);var result=[];for(var i=0;i<decoded.length;++i){var c=decoded.charCodeAt(i).toString(16);if(c.length==1)c="0"+c;result.push(c)}return result.join("")};const EncryptionKeyController=function($scope){this.scope_=$scope;this.stringifiedKey;this.scope_.$watch("::value.value",this.onValueChange.bind(this))};
EncryptionKeyController.prototype.onValueChange=function(newValue){if(angular.isDefined(newValue))this.stringifiedKey=exports.stringifyEncryptionKey(newValue)};exports.EncryptionKeyDirective=function(){return{scope:{value:"="},restrict:"E",template:"{$ ::controller.stringifiedKey $}",controller:EncryptionKeyController,controllerAs:"controller"}};exports.EncryptionKeyDirective.directive_name="grrEncryptionKey";exports.EncryptionKeyDirective.semantic_type="EncryptionKey";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.exactDurationDirective");goog.module.declareLegacyNamespace();let TimeUnit;const SECOND={seconds:1,symbol:"s"};const MINUTE={seconds:60*SECOND.seconds,symbol:"m"};const HOUR={seconds:60*MINUTE.seconds,symbol:"h"};const DAY={seconds:24*HOUR.seconds,symbol:"d"};const WEEK={seconds:7*DAY.seconds,symbol:"w"};const stringifySeconds=function(seconds){if(seconds<0)throw new Error(`Unexpected negative number: ${seconds}`);seconds=
Math.round(seconds);const components=[];for(const unit of[WEEK,DAY,HOUR,MINUTE,SECOND]){const units=Math.floor(seconds/unit.seconds);seconds-=units*unit.seconds;if(units>0)components.push(`${units}${unit.symbol}`)}if(components.length==0)return"0s";else return components.join(" ")};const ExactDurationController=function($scope){this.scope_=$scope;this.stringifiedDuration=null;this.scope_.$watch("::value",newValue=>this.onValueChange(newValue))};ExactDurationController.prototype.onValueChange=function(newValue){if(!angular.isDefined(newValue))return;
const duration=newValue.value;if(angular.isNumber(duration))this.stringifiedDuration=stringifySeconds(duration);else this.stringifiedDuration="-"};const ExactDurationDirective=function(){return{scope:{value:"="},restrict:"E",template:`
      <nobr ng-if="controller.stringifiedDuration">
        {$ ::controller.stringifiedDuration $}
      </nobr>
    `,controller:ExactDurationController,controllerAs:"controller"}};ExactDurationDirective.directive_name="grrExactDuration";ExactDurationDirective.semantic_type="DurationSeconds";exports.ExactDurationDirective=ExactDurationDirective;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.flowIdDirective");goog.module.declareLegacyNamespace();const FlowIdController=function($scope){this.scope_=$scope;this.clientId};exports.FlowIdDirective=function(){return{scope:{value:"="},require:"?^grrClientContext",restrict:"E",templateUrl:"/static/angular-components/semantic/flow-id.html",controller:FlowIdController,controllerAs:"controller",link:function(scope,element,attrs,grrClientContextCtrl){if(grrClientContextCtrl)scope["controller"].clientId=
grrClientContextCtrl.clientId}}};exports.FlowIdDirective.directive_name="grrFlowId";exports.FlowIdDirective.semantic_type="ApiFlowId";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.hashDigestDirective");goog.module.declareLegacyNamespace();const HashDigestController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.stringifiedBytes;this.scope_.$watch("::value",this.onValueChange.bind(this))};HashDigestController.prototype.bytesToHexString=function(bytes){var hex="";for(var i=0;i<bytes.length;i+=1){var char=bytes.charCodeAt(i).toString(16);hex+=("0"+char).substr(-2)}return hex};HashDigestController.prototype.onValueChange=
function(newValue){var bytes=newValue.value;if(angular.isString(bytes))try{this.stringifiedBytes=this.bytesToHexString(this.window_.atob(bytes))}catch(err){this.stringifiedBytes="base64decodeerror("+err.message+"):"+bytes}else this.stringifiedBytes=""};exports.HashDigestDirective=function(){return{scope:{value:"="},restrict:"E",template:'<nobr ng-if="::controller.stringifiedBytes !== undefined">'+"{$ ::controller.stringifiedBytes $}</nobr>",controller:HashDigestController,controllerAs:"controller"}};
exports.HashDigestDirective.directive_name="grrHashDigest";exports.HashDigestDirective.semantic_type="HashDigest";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.hashListDirective");goog.module.declareLegacyNamespace();var HASH_SIZE=32;const HashListController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.chunks=[];this.scope_.$watch("::value",this.onValueChange.bind(this))};HashListController.prototype.onValueChange=function(newValue){this.chunks=[];if(angular.isString(newValue.value)){var bytes=this.window_.atob(newValue.value);while(bytes){var chunkStr=bytes.substr(0,
HASH_SIZE);bytes=bytes.substr(HASH_SIZE);this.chunks.push({value:this.window_.btoa(chunkStr),type:"HashDigest"})}}};exports.HashListDirective=function(){return{scope:{value:"="},restrict:"E",template:'<grr-semantic-value value="::controller.chunks" />',controller:HashListController,controllerAs:"controller"}};exports.HashListDirective.directive_name="grrHashList";exports.HashListDirective.semantic_type="HashList";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.huntIdDirective");goog.module.declareLegacyNamespace();exports.HuntIdDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/hunt-id.html"}};exports.HuntIdDirective.directive_name="grrHuntId";exports.HuntIdDirective.semantic_type="ApiHuntId";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.jsonDirective");goog.module.declareLegacyNamespace();const JsonController=function($scope,$window){this.scope_=$scope;this.window_=$window;this.prettyJson;this.scope_.$watch("::value",this.onValueChange.bind(this))};var FIRST_RENDER_LIMIT=1024;JsonController.prototype.onClick=function(e){e.stopPropagation();var jsonStr=this.scope_["value"]["value"];try{var parsedJson=JSON.parse(jsonStr);this.prettyJson=JSON.stringify(parsedJson,
null,2)}catch(err){this.prettyJson="jsonerror("+err.message+"):"+jsonStr}};JsonController.prototype.onValueChange=function(newValue){var jsonStr=newValue.value;if(angular.isString(jsonStr)){if(jsonStr.length<FIRST_RENDER_LIMIT)try{var parsedJson=JSON.parse(jsonStr);this.prettyJson=JSON.stringify(parsedJson,null,2)}catch(err){this.prettyJson="jsonerror("+err.message+"):"+jsonStr}}else this.prettyJson=""};exports.JsonDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/json.html",
controller:JsonController,controllerAs:"controller"}};exports.JsonDirective.directive_name="grrJson";exports.JsonDirective.semantic_type="ZippedJSONBytes";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.macAddressDirective");goog.module.declareLegacyNamespace();const convertMacAddressToString=function(address){var result=[];for(var i=0;i<address.length;++i){var part=address.charCodeAt(i).toString(16);if(part.length===1)part="0"+part;result.push(part)}return result.join(":")};const MacAddressController=function($scope){this.scope_=$scope;this.convertedAddress;this.scope_.$watch("::value",this.onValueChange.bind(this))};MacAddressController.prototype.onValueChange=
function(newValue){var address=newValue.value;if(angular.isString(address))this.convertedAddress=convertMacAddressToString(window.atob(address));else this.convertedAddress="-"};exports.MacAddressDirective=function(){return{scope:{value:"="},restrict:"E",template:'<nobr ng-if="::controller.convertedAddress !== undefined">'+"{$ ::controller.convertedAddress $}</nobr>",controller:MacAddressController,controllerAs:"controller"}};exports.MacAddressDirective.directive_name="grrMacAddress";exports.MacAddressDirective.semantic_type=
"MacAddress";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.networkAddressDirective");goog.module.declareLegacyNamespace();const convertIpv4AddressToString=function(address){var result=[];for(var i=0;i<address.length;++i){var part=address.charCodeAt(i).toString(10);if(part.length===1)part="0"+part;result.push(part)}return result.join(".")};const convertIpv6AddressToString=function(address){var result=[];var colonCounter=0;for(var i=0;i<address.length;++i){var part=address.charCodeAt(i).toString(16);
if(part.length===1)part="0"+part;result.push(part);if(++colonCounter==2){result.push(":");colonCounter=0}}return result.join("")};const convertBase64AddressToString=function(address,addressType){if(angular.isUndefined(address))return"-";else switch(addressType){case "INET":return convertIpv4AddressToString(window.atob(address));case "INET6":return convertIpv6AddressToString(window.atob(address));default:return"<unknown address type>"}};const NetworkAddressController=function($scope){this.scope_=$scope;
this.convertedAddress;this.scope_.$watch("::value",this.onValueChange.bind(this))};NetworkAddressController.prototype.onValueChange=function(newValue){if(!angular.isObject(newValue)){this.convertedAddress="-";return}if(angular.isObject(newValue.value))if(angular.isDefined(newValue.value.packed_bytes))this.convertedAddress=convertBase64AddressToString(newValue.value.packed_bytes.value,newValue.value.address_type.value);else if(angular.isDefined(newValue.value.human_readable))this.convertedAddress=
newValue.value.human_readable.value;else this.convertedAddress="<unknown>";else if(angular.isObject(newValue))if(angular.isDefined(newValue.packed_bytes))this.convertedAddress=convertBase64AddressToString(newValue.packed_bytes,newValue.address_type);else if(angular.isDefined(newValue.human_readable))this.convertedAddress=newValue.human_readable;else this.convertedAddress="<unknown>"};exports.NetworkAddressDirective=function(){return{scope:{value:"="},restrict:"E",template:'<nobr ng-if="::controller.convertedAddress !== undefined">'+
"{$ ::controller.convertedAddress $}</nobr>",controller:NetworkAddressController,controllerAs:"controller"}};exports.NetworkAddressDirective.directive_name="grrNetworkAddress";exports.NetworkAddressDirective.semantic_type="NetworkAddress";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.objectLabelDirective");goog.module.declareLegacyNamespace();const ObjectLabelController=function($scope){this.scope_=$scope;this.labelName;this.labelOwner;this.scope_.$watch("::value",this.onValueChange_.bind(this))};ObjectLabelController.prototype.onValueChange_=function(newValue){if(!newValue)this.labelName=this.labelType=null;if(angular.isDefined(newValue["value"])){this.labelName=newValue["value"]["name"]["value"];this.labelOwner=
newValue["value"]["owner"]["value"]}else{this.labelName=newValue["name"];this.labelOwner=newValue["owner"]}};exports.ObjectLabelDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/object-label.html",controller:ObjectLabelController,controllerAs:"controller"}};exports.ObjectLabelDirective.directive_name="grrObjectLabel";exports.ObjectLabelDirective.semantic_type="ClientLabel";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.osqueryTableDirective");goog.module.declareLegacyNamespace();let Column;const parseColumn=column=>{return column["value"]["name"]["value"]};let Row;const parseRow=row=>{return row["value"]["values"].map(value=>value["value"])};const OsqueryTableController=function($scope){this.query;this.columns;this.rows;$scope.$watch("::value",table=>this.onValueChange_(table))};OsqueryTableController.prototype.onValueChange_=function(table){if(table===
undefined)return;this.query=table["value"]["query"]["value"];this.columns=table["value"]["header"]["value"]["columns"].map(parseColumn);this.rows=table["value"]["rows"].map(parseRow)};exports.OsqueryTableDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/osquery-table.html",controller:OsqueryTableController,controllerAs:"controller"}};exports.OsqueryTableDirective.directive_name="grrOsqueryTable";exports.OsqueryTableDirective.semantic_type=
"OsqueryTable";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.primitiveDirective");goog.module.declareLegacyNamespace();exports.PrimitiveDirective=function(){return{scope:{value:"="},restrict:"E",template:"{$ ::value.value $}"}};exports.PrimitiveDirective.directive_name="grrPrimitive";exports.PrimitiveDirective.semantic_types=["RDFBool","bool","RDFInteger","int","long","float","RDFString","basestring","str","unicode"];return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.semanticValueDirective");goog.module.declareLegacyNamespace();let singleValueTemplateCache={};let repeatedValuesTemplate;exports.clearCaches=function(){singleValueTemplateCache={};repeatedValuesTemplate=undefined};exports.getCachedSingleValueTemplate=function(name){return singleValueTemplateCache[name]};const RegistryOverrideController=function($scope){this.scope_=$scope;this.map;this.overrideKey;this.scope_.$watch(function(){return this.map}.bind(this),
this.onMapChange_.bind(this))};RegistryOverrideController.prototype.onMapChange_=function(newValue){this.overrideKey="";angular.forEach(Object.keys(this.map).sort(),function(key){var value=this.map[key];this.overrideKey+=":"+key+"_"+value["directive_name"]}.bind(this))};exports.RegistryOverrideDirective=function(){return{scope:{map:"="},controller:RegistryOverrideController,bindToController:true,restrict:"E",transclude:true,template:"<ng-transclude></ng-transclude>"}};exports.RegistryOverrideDirective.directive_name=
"grrSemanticValueRegistryOverride";const SemanticValueController=function($scope,$compile,$element,grrSemanticValueDirectivesRegistryService){this.scope_=$scope;this.scope_.value;this.compile_=$compile;this.element_=$element;this.grrSemanticValueDirectivesRegistryService_=grrSemanticValueDirectivesRegistryService;this.registryOverrideController;this.scope_.$watch("::value",this.onValueChange.bind(this))};SemanticValueController.prototype.camelCaseToDashDelimited=function(directiveName){return directiveName.replace(/\W+/g,
"-").replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase()};SemanticValueController.prototype.compileSingleTypedValueTemplate_=function(value){var successHandler=function(directive){var element=angular.element("<span />");element.html("<"+this.camelCaseToDashDelimited(directive.directive_name)+' value="::value" />');return this.compile_(element)}.bind(this);var failureHandler=function(directive){var element=angular.element("<span />");element.html("{$ ::value.value $}");return this.compile_(element)}.bind(this);
var overrides;if(this.registryOverrideController)overrides=this.registryOverrideController.map;return this.grrSemanticValueDirectivesRegistryService_.findDirectiveForType(value["type"],overrides).then(successHandler,failureHandler)};SemanticValueController.prototype.compileRepeatedValueTemplate_=function(){var element=angular.element('<div ng-repeat="item in ::repeatedValue || []">'+'<grr-semantic-value value="::item" /></div>');return this.compile_(element)};SemanticValueController.prototype.onValueChange=
function(){var value=this.scope_.value;if(value==null)return;var template;if(angular.isDefined(value["type"])){var handleTemplate=function(template){template(this.scope_,function(cloned,opt_scope){this.element_.html("");this.element_.append(cloned)}.bind(this))}.bind(this);var cacheKey=value["type"];if(this.registryOverrideController)cacheKey+=this.registryOverrideController.overrideKey;template=singleValueTemplateCache[cacheKey];if(angular.isUndefined(template))this.compileSingleTypedValueTemplate_(value).then(function(tmpl){singleValueTemplateCache[cacheKey]=
tmpl;handleTemplate(tmpl)}.bind(this));else handleTemplate(template)}else if(angular.isArray(value)){if(value.length>10){var continuation=value.slice(10);this.scope_.repeatedValue=value.slice(0,10);this.scope_.repeatedValue.push({type:"__FetchMoreLink",value:continuation})}else this.scope_.repeatedValue=value;if(angular.isUndefined(repeatedValuesTemplate))repeatedValuesTemplate=this.compileRepeatedValueTemplate_();template=repeatedValuesTemplate;template(this.scope_,function(cloned,opt_scope){this.element_.html("");
this.element_.append(cloned)}.bind(this))}else this.element_.text(value.toString()+" ")};exports.SemanticValueDirective=function(){return{scope:{value:"="},require:"?^grrSemanticValueRegistryOverride",restrict:"E",controller:SemanticValueController,controllerAs:"controller",link:function(scope,element,attrs,grrSemanticValueRegistryOverrideCtrl){if(grrSemanticValueRegistryOverrideCtrl)scope["controller"]["registryOverrideController"]=grrSemanticValueRegistryOverrideCtrl}}};exports.SemanticValueDirective.directive_name=
"grrSemanticValue";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.semanticProtoDirective");goog.module.declareLegacyNamespace();exports.getUnionFieldValue=function(value,descriptor){var unionFieldName=descriptor["union_field"];if(angular.isUndefined(unionFieldName))throw new Error("Not a union-type structure.");if(angular.isDefined(value["value"][unionFieldName]))return value["value"][unionFieldName]["value"].toLowerCase();else{var fieldsLength=descriptor["fields"].length;for(var i=0;i<fieldsLength;++i){var field=
descriptor["fields"][i];if(field["name"]==unionFieldName)return field["default"]["value"].toLowerCase()}}throw new Error("Can't determine value of the union field.");};var getUnionFieldValue=exports.getUnionFieldValue;exports.buildUnionItems=function(value,descriptor){var items=[];var unionFieldName=descriptor["union_field"];var unionFieldValue=getUnionFieldValue(value,descriptor);var fieldsLength=descriptor["fields"].length;for(var i=0;i<fieldsLength;++i){var field=descriptor["fields"][i];var key=
field["name"];if(key!==unionFieldName&&key!==unionFieldValue)continue;var keyValue=value.value[key];if(angular.isUndefined(keyValue))keyValue=field["default"];items.push({"value":keyValue,"key":field["friendly_name"]||field["name"],"desc":field["doc"]})}return items};var buildUnionItems=exports.buildUnionItems;exports.buildNonUnionItems=function(value,descriptor,opt_visibleFields,opt_hiddenFields){if(angular.isUndefined(descriptor["fields"]))return[];var items=[];var fieldsLength=descriptor["fields"].length;
for(var i=0;i<fieldsLength;++i){var field=descriptor["fields"][i];var key=field["name"];var keyValue=value.value[key];if(opt_visibleFields&&opt_visibleFields.indexOf(key)==-1)continue;if(opt_hiddenFields&&opt_hiddenFields.indexOf(key)!=-1)continue;if(angular.isUndefined(keyValue))if(!opt_visibleFields)continue;else keyValue=angular.copy(field["default"]);items.push({"value":keyValue,"key":field["friendly_name"]||field["name"],"structKey":field["name"],"desc":field["doc"],"fieldDescriptor":field})}return items};
var buildNonUnionItems=exports.buildNonUnionItems;exports.buildItems=function(value,descriptor,opt_visibleFields,opt_hiddenFields){if(angular.isDefined(descriptor["union_field"]))return buildUnionItems(value,descriptor);else return buildNonUnionItems(value,descriptor,opt_visibleFields,opt_hiddenFields)};var buildItems=exports.buildItems;var SemanticProtoController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.items;this.scope_.$watch("::value",
this.onValueChange.bind(this))};SemanticProtoController.prototype.onValueChange=function(newValue,oldValue){if(newValue===undefined&&oldValue===undefined)return;if(angular.isObject(this.scope_["value"])){var valueType=this.scope_["value"]["type"];this.grrReflectionService_.getRDFValueDescriptor(valueType).then(function success(descriptor){this.items=buildItems(this.scope_["value"],descriptor,this.scope_["visibleFields"],this.scope_["hiddenFields"])}.bind(this))}else this.items=[]};exports.SemanticProtoDirective=
function(){return{scope:{value:"=",visibleFields:"=",hiddenFields:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/semantic-proto.html",controller:SemanticProtoController,controllerAs:"controller"}};exports.SemanticProtoDirective.directive_name="grrSemanticProto";exports.SemanticProtoDirective.semantic_type="RDFProtoStruct";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.semanticDiffAnnotatedProtoDirective");goog.module.declareLegacyNamespace();const {buildItems}=goog.require("grrUi.semantic.semanticProtoDirective");var SemanticDiffAnnotatedProtoController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.items;this.scope_.$watch("::value",this.onValueChange_.bind(this))};SemanticDiffAnnotatedProtoController.prototype.onValueChange_=
function(newValue,oldValue){if(newValue===undefined&&oldValue===undefined)return;if(angular.isObject(this.scope_["value"]))this.grrReflectionService_.getRDFValueDescriptor(this.scope_["value"]["type"]).then(function success(descriptor){this.items=buildItems(this.scope_["value"],descriptor,this.scope_["visibleFields"],this.scope_["hiddenFields"]);angular.forEach(this.items,function(item){item["isList"]=angular.isArray(item["value"])}.bind(this))}.bind(this));else this.items=[]};exports.SemanticDiffAnnotatedProtoDirective=
function(){return{scope:{value:"=",visibleFields:"=",hiddenFields:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/"+"semantic-diff-annotated-proto.html",controller:SemanticDiffAnnotatedProtoController,controllerAs:"controller"}};exports.SemanticDiffAnnotatedProtoDirective.directive_name="grrSemanticDiffAnnotatedProto";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.semanticProtosDiffDirective");goog.module.declareLegacyNamespace();const {SemanticDiffAnnotatedProtoDirective}=goog.require("grrUi.semantic.semanticDiffAnnotatedProtoDirective");const {SemanticProtoDirective}=goog.require("grrUi.semantic.semanticProtoDirective");var diffAnnotateArrays=function(originalValue,newValue){angular.forEach(originalValue,function(originalItem){var found=false;angular.forEach(newValue,function(newItem){if(angular.equals(originalItem,
newItem))found=true});if(!found)originalItem["_diff"]="removed"});angular.forEach(newValue,function(newItem){var found=false;angular.forEach(originalValue,function(originalItem){if(angular.equals(originalItem,newItem))found=true});if(!found)newItem["_diff"]="added"})};exports.diffAnnotate=function(originalValue,newValue){if(angular.isUndefined(originalValue)&&angular.isUndefined(newValue))return;if(angular.isUndefined(originalValue)){newValue["_diff"]="added";return}if(angular.isUndefined(newValue)){originalValue["_diff"]=
"removed";return}if(angular.isArray(originalValue)&&!angular.isArray(newValue)||!angular.isArray(originalValue)&&angular.isArray(newValue)){originalValue["_diff"]=newValue["_diff"]="changed";return}if(angular.isArray(originalValue)&&angular.isArray(newValue)){diffAnnotateArrays(originalValue,newValue);return}if(originalValue["type"]!=newValue["type"]){originalValue["_diff"]=newValue["_diff"]="changed";return}if(angular.isString(originalValue["value"])||angular.isNumber(originalValue["value"])){if(!angular.equals(originalValue["value"],
newValue["value"]))originalValue["_diff"]=newValue["_diff"]="changed";return}var allKeys=angular.extend({},originalValue["value"],newValue["value"]);for(var key in allKeys)diffAnnotate(originalValue["value"][key],newValue["value"][key])};var diffAnnotate=exports.diffAnnotate;const SemanticProtosDiffController=function($scope){this.scope_=$scope;this.annotatedOriginalValue;this.annotatedNewValue;var protoType=SemanticProtoDirective.semantic_type;var protoDirectiveOverride=SemanticDiffAnnotatedProtoDirective;
this.overrideMap={};this.overrideMap[protoType]=protoDirectiveOverride;this.scope_.$watchGroup(["originalValue","newValue"],this.onValuesChange_.bind(this))};SemanticProtosDiffController.prototype.onValuesChange_=function(){if(angular.isUndefined(this.scope_["originalValue"])||angular.isUndefined(this.scope_["newValue"]))return;this.annotatedOriginalValue=angular.copy(this.scope_["originalValue"]);this.annotatedNewValue=angular.copy(this.scope_["newValue"]);diffAnnotate(this.annotatedOriginalValue,
this.annotatedNewValue)};exports.SemanticProtosDiffDirective=function(){return{scope:{originalValue:"=",newValue:"=",visibleFields:"=",hiddenFields:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/"+"semantic-protos-diff.html",controller:SemanticProtosDiffController,controllerAs:"controller"}};exports.SemanticProtosDiffDirective.directive_name="grrSemanticProtosDiff";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.semanticVersionedProtoDirective");goog.module.declareLegacyNamespace();const {buildNonUnionItems}=goog.require("grrUi.semantic.semanticProtoDirective");var SemanticVersionedProtoController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.items;this.scope_.$watch("::value",this.onValueChange_.bind(this))};SemanticVersionedProtoController.prototype.processItems_=function(items,
descriptors){angular.forEach(items,function(item){var itemType=item["fieldDescriptor"]["type"];item["recursiveItem"]=this.scope_["historyDepth"]>1&&descriptors[itemType]["kind"]==="struct"&&!item["fieldDescriptor"]["repeated"]&&!item["fieldDescriptor"]["dynamic"];if(!this.scope_["historyPath"])item["historyPath"]=item["structKey"];else item["historyPath"]=this.scope_["historyPath"]+"."+item["structKey"]}.bind(this));return items};SemanticVersionedProtoController.prototype.onValueChange_=function(newValue,
oldValue){if(newValue===undefined&&oldValue===undefined)return;if(angular.isObject(this.scope_["value"])){var valueType=this.scope_["value"]["type"];this.grrReflectionService_.getRDFValueDescriptor(valueType,true).then(function success(descriptors){var items=buildNonUnionItems(this.scope_["value"],descriptors[valueType]);this.items=this.processItems_(items,descriptors)}.bind(this))}else this.items=[]};exports.SemanticVersionedProtoDirective=function(){return{scope:{value:"=",onFieldClick:"&",historyDepth:"=",
historyPath:"=?"},restrict:"E",templateUrl:"/static/angular-components/semantic/semantic-versioned-proto.html",controller:SemanticVersionedProtoController,controllerAs:"controller"}};exports.SemanticVersionedProtoDirective.directive_name="grrSemanticVersionedProto";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.statEntryDirective");goog.module.declareLegacyNamespace();const {ServerErrorButtonDirective}=goog.require("grrUi.core.serverErrorButtonDirective");const {pathSpecToAff4Path}=goog.require("grrUi.core.fileDownloadUtils");var ERROR_EVENT_NAME=ServerErrorButtonDirective.error_event_name;const StatEntryController=function($rootScope,$scope,grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.grrApiService_=grrApiService;
this.clientId;this.aff4Path;this.statEntry;this.downloadUrl;this.downloadParams;this.scope_.$watch("::value",this.onValueChange_.bind(this))};StatEntryController.prototype.onValueChange_=function(newValue){if(angular.isUndefined(newValue))return;if(newValue["type"]=="__DownloadableStatEntry"){this.statEntry=newValue["originalValue"];this.downloadUrl=newValue["downloadUrl"];this.downloadParams=newValue["downloadParams"]}else this.statEntry=newValue;if(this.clientId&&angular.isDefined(this.statEntry["value"]["pathspec"]))this.aff4Path=
{type:"RDFURN",value:pathSpecToAff4Path(this.statEntry["value"]["pathspec"],this.clientId)};else this.aff4Path={type:"RDFString",value:"<unknown>"}};StatEntryController.prototype.onDownloadClick=function(){this.grrApiService_.downloadFile(this.downloadUrl,this.downloadParams).then(function success(){}.bind(this),function failure(response){if(response.status!==500)this.rootScope_.$broadcast(ERROR_EVENT_NAME,{message:"Couldn't download the file. Most likely "+"it was just referenced and not downloaded from the "+
"client."})}.bind(this))};exports.StatEntryDirective=function(){return{scope:{value:"="},require:"?^grrClientContext",restrict:"E",templateUrl:"/static/angular-components/semantic/stat-entry.html",controller:StatEntryController,controllerAs:"controller",link:function(scope,element,attrs,grrClientContextCtrl){if(grrClientContextCtrl)scope["controller"].clientId=grrClientContextCtrl.clientId}}};exports.StatEntryDirective.directive_name="grrStatEntry";exports.StatEntryDirective.semantic_types=["StatEntry",
"__DownloadableStatEntry"];return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.statExtFlagsLinuxDirective");goog.module.declareLegacyNamespace();const {Flag,LINUX_FLAGS_ORDERED}=goog.require("grrUi.client.extFlags");const FlagsStatus={MALFORMED:"MALFORMED",SOME:"SOME",NONE:"NONE"};const StatExtFlagsLinuxController=function($scope){this.scope_=$scope;this.scope_.value;this.scope_.$watch("::value",this.onValueChange.bind(this));this.status=FlagsStatus.NONE;this.flags=[]};StatExtFlagsLinuxController.prototype.onValueChange=
function(value){if(angular.isUndefined(value))return;const mask=value.value;if(!Number.isInteger(mask)||mask<0){this.status=FlagsStatus.MALFORMED;return}this.status=FlagsStatus.SOME;this.flags=LINUX_FLAGS_ORDERED.map(flag=>{return(flag.mask&mask)!==0?flag:null})};exports.StatExtFlagsLinuxDirective=function($filter){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/stat-ext-flags-linux.html",controller:StatExtFlagsLinuxController,controllerAs:"controller"}};const StatExtFlagsLinuxDirective=
exports.StatExtFlagsLinuxDirective;StatExtFlagsLinuxDirective.directive_name="grrStatExtFlagsLinux";StatExtFlagsLinuxDirective.semantic_type="StatExtFlagsLinux";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.statExtFlagsOsxDirective");goog.module.declareLegacyNamespace();const {Flag,OSX_FLAGS}=goog.require("grrUi.client.extFlags");const FlagsStatus={MALFORMED:"MALFORMED",SOME:"SOME",NONE:"NONE"};const StatExtFlagsOsxController=function($scope){this.scope_=$scope;this.scope_.value;this.scope_.$watch("::value",this.onValueChange.bind(this));this.status=FlagsStatus.NONE;this.flags=[]};StatExtFlagsOsxController.prototype.onValueChange=
function(value){if(angular.isUndefined(value))return;const mask=value.value;if(!Number.isInteger(mask)||mask<0){this.status=FlagsStatus.MALFORMED;return}this.status=FlagsStatus.SOME;this.flags=OSX_FLAGS.filter(flag=>(flag.mask&mask)!==0)};exports.StatExtFlagsOsxDirective=function($filter){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/stat-ext-flags-osx.html",controller:StatExtFlagsOsxController,controllerAs:"controller"}};const StatExtFlagsOsxDirective=exports.StatExtFlagsOsxDirective;
StatExtFlagsOsxDirective.directive_name="grrStatExtFlagsOsx";StatExtFlagsOsxDirective.semantic_type="StatExtFlagsOsx";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.statModeDirective");goog.module.declareLegacyNamespace();var S_IFMT=61440;var S_IFIFO=4096;var S_IFCHR=8192;var S_IFDIR=16384;var S_IFBLK=24576;var S_IFREG=32768;var S_IFLNK=40960;var S_IFSOCK=49152;var S_IFWHT=57344;var S_IMODE=4095;var S_ISUID=2048;var S_ISGID=1024;var S_ISVTX=512;var S_IRUSR=256;var S_IWUSR=128;var S_IXUSR=64;var S_IRGRP=32;var S_IWGRP=16;var S_IXGRP=8;var S_IROTH=4;var S_IWOTH=2;var S_IXOTH=1;const StatModeController=
function($scope){this.scope_=$scope;this.scope_.value;this.statMode;this.octalStatMode;this.scope_.$watch("::value",this.onValueChange.bind(this))};StatModeController.prototype.onValueChange=function(newValue){if(!newValue||!angular.isNumber(newValue.value)){this.octalStatMode="-";this.statMode="-"}else{var statMode=newValue.value;this.octalStatMode=this.calculateOctalMode_(statMode);this.statMode=this.calculateModeString_(statMode)}};StatModeController.prototype.calculateOctalMode_=function(statMode){return this.getMode_(statMode).toString(8)};
StatModeController.prototype.calculateModeString_=function(statMode){var fileType="-";if(this.isRegularFile_(statMode))fileType="-";else if(this.isBlockDevice_(statMode))fileType="b";else if(this.isCharacterDevice_(statMode))fileType="c";else if(this.isDirectory_(statMode))fileType="d";else if(this.isFifo_(statMode))fileType="p";else if(this.isLink_(statMode))fileType="l";else if(this.isSocket_(statMode))fileType="s";var permissions="";permissions+=statMode&S_IRUSR?"r":"-";permissions+=statMode&S_IWUSR?
"w":"-";if(statMode&S_ISUID)permissions+=statMode&S_IXUSR?"s":"S";else permissions+=statMode&S_IXUSR?"x":"-";permissions+=statMode&S_IRGRP?"r":"-";permissions+=statMode&S_IWGRP?"w":"-";if(statMode&S_ISGID)permissions+=statMode&S_IXGRP?"s":"S";else permissions+=statMode&S_IXGRP?"x":"-";permissions+=statMode&S_IROTH?"r":"-";permissions+=statMode&S_IWOTH?"w":"-";if(statMode&S_ISVTX)permissions+=statMode&S_IXOTH?"t":"T";else permissions+=statMode&S_IXOTH?"x":"-";return fileType+permissions};StatModeController.prototype.getMode_=
function(mode){return mode&S_IMODE};StatModeController.prototype.getType_=function(mode){return mode&S_IFMT};StatModeController.prototype.isDirectory_=function(mode){return this.getType_(mode)===S_IFDIR};StatModeController.prototype.isCharacterDevice_=function(mode){return this.getType_(mode)===S_IFCHR};StatModeController.prototype.isBlockDevice_=function(mode){return this.getType_(mode)===S_IFBLK};StatModeController.prototype.isRegularFile_=function(mode){return this.getType_(mode)===S_IFREG};StatModeController.prototype.isFifo_=
function(mode){return this.getType_(mode)===S_IFIFO};StatModeController.prototype.isLink_=function(mode){return this.getType_(mode)===S_IFLNK};StatModeController.prototype.isSocket_=function(mode){return this.getType_(mode)===S_IFSOCK};exports.StatModeDirective=function($filter){return{scope:{value:"="},restrict:"E",template:'<abbr title="Mode {$ ::controller.octalStatMode $}">'+"  {$ ::controller.statMode $}"+"</abbr>",controller:StatModeController,controllerAs:"controller"}};exports.StatModeDirective.directive_name=
"grrStatMode";exports.StatModeDirective.semantic_type="StatMode";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.timestampDirective");goog.module.declareLegacyNamespace();const TimestampController=function($scope,$element,grrTimeService){this.scope_=$scope;this.scope_.value;this.formattedTimestamp;this.formattedTimestampComponents;this.value;this.element_=$element;this.timeService_=grrTimeService;this.scope_.$watch("::value",this.onValueChange.bind(this))};TimestampController.prototype.onValueChange=function(newValue){if(angular.isDefined(newValue))if(newValue===
null||newValue===0)this.formattedTimestamp="-";else{var timestamp;if(angular.isObject(newValue))timestamp=newValue.value/1E3;else timestamp=newValue/1E3;this.value=timestamp;this.formattedTimestamp=this.timeService_.formatAsUTC(timestamp);this.formattedTimestampComponents=this.formattedTimestamp.split(" ")}};TimestampController.prototype.onMouseEnter=function(){var span=$(this.element_).find("span")[0];if(angular.isDefined(this.value))span.title=this.timeService_.getFormattedDiffFromCurrentTime(Number(this.value))};
exports.TimestampDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/timestamp.html",controller:TimestampController,controllerAs:"controller"}};exports.TimestampDirective.directive_name="grrTimestamp";exports.TimestampDirective.semantic_type="RDFDatetime";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.timestampSecondsDirective");goog.module.declareLegacyNamespace();const TimestampSecondsController=function($scope){this.scope_=$scope;this.scope_.value;this.timestampValue;this.scope_.$watch("::value",this.onValueChange.bind(this))};TimestampSecondsController.prototype.onValueChange=function(newValue){if(angular.isDefined(newValue)){var timestamp;if(angular.isObject(newValue))timestamp=newValue.value;else timestamp=newValue;
this.timestampValue=timestamp*1E6}};exports.TimestampSecondsDirective=function(){return{scope:{value:"="},restrict:"E",template:'<grr-timestamp value="::controller.timestampValue"></grr-timestamp>',controller:TimestampSecondsController,controllerAs:"controller"}};exports.TimestampSecondsDirective.directive_name="grrTimestampSeconds";exports.TimestampSecondsDirective.semantic_type="RDFDatetimeSeconds";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.routing.aff4UrnToUrl");goog.module.declareLegacyNamespace();const {CLIENT_ID_RE,stripAff4Prefix}=goog.require("grrUi.core.utils");const {vfsRoots}=goog.require("grrUi.core.fileDownloadUtils");exports.aff4UrnToUrl=function(urn){var components=stripAff4Prefix(urn).split("/");if(CLIENT_ID_RE.test(components[0]))if(vfsRoots.includes(components[1]))return{state:"client.vfs",params:{clientId:components[0],path:components.slice(1).join("/")}};
else if(components[1]==="flows"&&components.length===3)return{state:"client.flows",params:{clientId:components[0],flowId:components[2]}};else return{state:"client",params:{clientId:components[0]}};else if(components[0]==="hunts")return{state:"hunts",params:{huntId:components[1]}};else if(components[0]==="cron")return{state:"crons",params:{cronJobId:components[1]}};else if(components[0]==="ACL")if(CLIENT_ID_RE.test(components[1]))return{state:"clientApproval",params:{clientId:components[1],username:components[components.length-
2],approvalId:components[components.length-1]}};else if(components[1]=="hunts")return{state:"huntApproval",params:{huntId:components[2],username:components[components.length-2],approvalId:components[components.length-1]}};else if(components[1]=="cron")return{state:"cronJobApproval",params:{cronJobId:components[2],username:components[components.length-2],approvalId:components[components.length-1]}};return null};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.urnDirective");goog.module.declareLegacyNamespace();const {aff4UrnToUrl}=goog.require("grrUi.routing.aff4UrnToUrl");const UrnController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.plainValue;this.ref;this.refState;this.refParams;this.scope_.$watch("::value",this.onValueChange_.bind(this))};UrnController.prototype.onValueChange_=function(newValue){if(angular.isObject(newValue))this.plainValue=
newValue.value;else if(angular.isString(newValue))this.plainValue=newValue;else return;var urlResult=aff4UrnToUrl(this.plainValue);if(urlResult){this.refState=urlResult.state;this.refParams=urlResult.params;this.ref=this.grrRoutingService_.href(urlResult.state,urlResult.params)}};UrnController.prototype.onClick=function(){this.grrRoutingService_.go("client.vfs",this.refParams)};exports.UrnDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/semantic/urn.html",
controller:UrnController,controllerAs:"controller"}};exports.UrnDirective.directive_name="grrUrn";exports.UrnDirective.semantic_type="RDFURN";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.pseudo.fetchMoreLinkDirective");goog.module.declareLegacyNamespace();exports.FetchMoreLinkDirective=function(){return{scope:{value:"="},link:function(scope){scope.onClick=function(e){scope.continuationShown=true;e.stopPropagation()}},restrict:"E",templateUrl:"/static/angular-components/semantic/pseudo/"+"fetch-more-link.html"}};exports.FetchMoreLinkDirective.directive_name="grrFetchMoreLink";exports.FetchMoreLinkDirective.semantic_type=
"__FetchMoreLink";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.pseudo.pseudo");goog.module.declareLegacyNamespace();const {FetchMoreLinkDirective}=goog.require("grrUi.semantic.pseudo.fetchMoreLinkDirective");const {coreModule}=goog.require("grrUi.core.core");exports.pseudoModule=angular.module("grrUi.semantic.pseudo",[coreModule.name,"ui.bootstrap"]);exports.pseudoModule.directive(FetchMoreLinkDirective.directive_name,FetchMoreLinkDirective);exports.pseudoModule.run(function(grrSemanticValueDirectivesRegistryService){var registry=
grrSemanticValueDirectivesRegistryService;registry.registerDirective(FetchMoreLinkDirective.semantic_type,FetchMoreLinkDirective)});return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.routing.routingService");goog.module.declareLegacyNamespace();exports.RoutingService=function($state){this.state_=$state};var RoutingService=exports.RoutingService;RoutingService.service_name="grrRoutingService";RoutingService.prototype.href=function(targetState,opt_params){return this.state_.href(targetState,opt_params)};RoutingService.prototype.go=function(targetState,opt_params){var currentState=this.state_.current.name;return this.state_.go(targetState,
opt_params,{notify:currentState!==targetState})};RoutingService.prototype.uiOnParamsChanged=function(scope,paramNames,callback,opt_stateAgnostic){var currentStateName=this.state_.current.name;if(!angular.isArray(paramNames)){var paramName=paramNames;paramNames=[paramName]}return scope.$watchCollection(function(){return paramNames.map(function(paramName){return this.state_.params[paramName]}.bind(this))}.bind(this),function(newValues,oldValues){if(!opt_stateAgnostic&&!this.state_.includes(currentStateName))return;
if(newValues.length===1)callback(newValues[0],this.state_.params);else callback(newValues,this.state_.params)}.bind(this))};RoutingService.prototype.onStateChange=function(scope,callback){callback(this.state_.current.name,this.state_.params);return scope.$on("$stateChangeSuccess",function(event,state,params){callback(state.name,params)}.bind(this))};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.utils");goog.module.declareLegacyNamespace();exports.ensurePathIsFolder=function(path){if(path.endsWith("/"))return path;else return path+"/"};exports.getFolderFromPath=function(path){if(!path)return"";var components=path.split("/");return components.slice(0,-1).join("/")};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.fileViewDirective");goog.module.declareLegacyNamespace();const replaceInvalidChars_=function(item){return item.replace(/[^a-zA-Z0-9]/g,function(invChar){var hex=invChar.charCodeAt(0).toString(16);return"_"+hex.toUpperCase()})};exports.getFileId=function(filePath){var components=filePath.split("/");var result=components.map(replaceInvalidChars_);return"_"+result.join("-")};exports.getFilePathFromId=function(fileId){var replaceEncodedChars=
function(item){return item.replace(/_[0-9A-F][0-9A-F]?/g,function(encChar){var charNum=parseInt(encChar.substr(1),16);return String.fromCharCode(charNum)})};var components=fileId.substr(1).split("-");var mapped=components.map(replaceEncodedChars);return mapped.join("/")};const FileViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.selectedFilePath;this.viewMode="list";this.tab="stats";this.fileVersion;this.clientId;this.grrRoutingService_.uiOnParamsChanged(this.scope_,
["clientId","path","version","mode","tab"],this.onUrlRoutingParamsChanged_.bind(this));this.scope_.$watchGroup(["controller.selectedFilePath","controller.fileVersion","controller.viewMode","controller.tab"],this.onFileContextRoutingParamsChange_.bind(this))};FileViewController.prototype.onUrlRoutingParamsChanged_=function(params){this.clientId=params[0];this.selectedFilePath=params[1];this.fileVersion=parseInt(params[2],10)||undefined;this.viewMode=params[3]||"list";this.tab=params[4]||"stats"};FileViewController.prototype.onFileContextRoutingParamsChange_=
function(){var params={path:this.selectedFilePath};params["version"]=this.fileVersion||undefined;if(!this.viewMode||this.viewMode=="list")params["mode"]=undefined;else params["mode"]=this.viewMode;if(!this.tab||this.tab=="stats")params["tab"]=undefined;else params["tab"]=this.tab;this.grrRoutingService_.go("client.vfs",params)};exports.FileViewDirective=function(){return{restrict:"E",scope:{},templateUrl:"/static/angular-components/client/virtual-file-system/file-view.html",controller:FileViewController,
controllerAs:"controller"}};exports.FileViewDirective.directive_name="grrFileView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.routing.rewriteUrl");goog.module.declareLegacyNamespace();const {aff4UrnToUrl}=goog.require("grrUi.routing.aff4UrnToUrl");const {encodeUrlPath}=goog.require("grrUi.core.apiService");const {ensurePathIsFolder}=goog.require("grrUi.client.virtualFileSystem.utils");const {getFilePathFromId}=goog.require("grrUi.client.virtualFileSystem.fileViewDirective");const parseHash=function(hash){if(hash.indexOf("#")==0)hash=hash.substr(1);var result=
{};var parts=hash.split("&");for(var i=0;i<parts.length;i++){var kv=parts[i].split("=");if(kv[0]&&kv[1])result[kv[0]]=decodeURIComponent(kv[1].replace(/\+/g," ")||"")}return result};exports.rewriteUrl=function(url){var hashState=parseHash(url);var clientId=hashState["c"];if(clientId&&clientId.indexOf("aff4:/")===0)clientId=clientId.split("/")[1];var main=hashState["main"];switch(main){case "ManageCron":var cronJobUrn=hashState["cron_job_urn"];var cronJobId=cronJobUrn?cronJobUrn.split("/")[2]:"";return"/crons/"+
cronJobId;case "ManageHunts":var huntUrn=hashState["hunt_id"];var huntId=huntUrn?huntUrn.split("/")[2]:"";return"/hunts/"+huntId;case "GlobalLaunchFlows":return"/global-flows";case "ServerLoadView":return"/server-load";case "BinaryConfigurationView":return"/manage-binaries";case "ConfigManager":return"/config";case "ArtifactManagerView":return"/artifacts";case "ApiDocumentation":return"/api-docs";case "GrantAccess":var acl=hashState["acl"]||"";var routingState=aff4UrnToUrl(acl);switch(routingState["state"]){case "clientApproval":return["/users",
routingState["params"]["username"],"approvals","client",routingState["params"]["clientId"],routingState["params"]["approvalId"]].join("/");case "huntApproval":return["/users",routingState["params"]["username"],"approvals","hunt",routingState["params"]["huntId"],routingState["params"]["approvalId"]].join("/");case "cronJobApproval":return["/users",routingState["params"]["username"],"approvals","cron-job",routingState["params"]["cronJobId"],routingState["params"]["approvalId"]].join("/");default:break}return"/";
case "CanaryTestRenderer":return"/canary-test";case "HostTable":var q=hashState["q"]||"";return"/search?q="+q;case "HostInformation":return"/clients/"+clientId;case "VirtualFileSystemView":var path;if(hashState["aff4_path"])path=hashState["aff4_path"].slice(hashState["c"].length+1);else path=ensurePathIsFolder(getFilePathFromId(hashState["t"]||""));return"/clients/"+clientId+"/vfs/"+encodeUrlPath(path);case "TimelineMain":case "ContainerViewer":var path=hashState["container"]||"";var query=hashState["query"]||
"";return"/clients/"+clientId+"/vfs-container"+"?path="+path+"&query="+query;case "LaunchFlows":return"/clients/"+clientId+"/launch-flow";case "ManageFlows":var flowUrn=hashState["flow"];var flowId=flowUrn?flowUrn.split("/")[3]:"";return"/clients/"+clientId+"/flows/"+flowId;case "DebugClientRequestsView":return"/clients/"+clientId+"/debug-requests";case "ClientLoadView":return"/clients/"+clientId+"/load";case "ClientCrashesRenderer":return"/clients/"+clientId+"/crashes";case "ClientStatsView":return"/clients/"+
clientId+"/stats";default:if(clientId)return"/clients/"+clientId;return null}};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.routing.routing");goog.module.declareLegacyNamespace();const {RoutingService}=goog.require("grrUi.routing.routingService");const {encodeUrlPath}=goog.require("grrUi.core.apiService");const {rewriteUrl}=goog.require("grrUi.routing.rewriteUrl");exports.routingModule=angular.module("grrUi.routing",["ui.router"]);exports.routingModule.service(RoutingService.service_name,RoutingService);exports.routingModule.config(function($stateProvider,
$urlRouterProvider,$urlMatcherFactoryProvider){$urlMatcherFactoryProvider.type("pathWithUnescapedSlashes",{encode:function(item){if(!item)return"";else return encodeUrlPath(item)},decode:function(item){if(!item)return"";else return decodeURIComponent(item)},pattern:/.*/});$urlRouterProvider.deferIntercept();$stateProvider.state("userDashboard",{url:"",template:"<grr-user-dashboard />",title:"Home"}).state("search",{url:"/search?q",template:"<grr-clients-list />",title:function(params){if(params["q"])return'Search for "'+
params["q"]+'"';else return"Client List"}}).state("apiDocs",{url:"/api-docs",template:"<grr-api-docs />",title:"API Docs"}).state("clientApproval",{url:"/users/:username/approvals/client/:clientId/:approvalId",template:"<grr-client-approval-view />",title:function(params){return["Approvals",params["username"],params["clientId"]]}}).state("huntApproval",{url:"/users/:username/approvals/hunt/:huntId/:approvalId",template:"<grr-hunt-approval-view />",title:function(params){return["Approvals",params["username"],
params["huntId"]]}}).state("cronJobApproval",{url:"/users/:username/approvals/cron-job/:cronJobId/:approvalId",template:"<grr-cron-job-approval-view />",title:function(params){return["Approvals",params["username"],params["cronJobId"]]}}).state("crons",{url:"/crons/:cronJobId/:tab",template:"<grr-cron-view />",params:{cronJobId:{value:null,squash:true},tab:{value:null,squash:true}},title:function(params){if(params["cronJobId"])return["Cron Jobs",params["cronJobId"]];else return"Cron Jobs"}}).state("hunts",
{url:"/hunts/:huntId/:tab",template:"<grr-hunts-view />",params:{huntId:{value:null,squash:true},tab:{value:null,squash:true}},title:function(params){if(params["huntId"])return params["huntId"];else return"Hunts"}}).state("stats",{url:"/stats/:name/:client_label?start_time&duration",template:"<grr-stats-view />",params:{name:{value:null,squash:true},client_label:{value:null,squash:true}},title:"Stats"}).state("manageBinaries",{url:"/manage-binaries",template:"<grr-config-binaries-view />",title:"Binaries"}).state("config",
{url:"/config",template:"<grr-config-view />",title:"Configuration"}).state("artifacts",{url:"/artifacts",template:"<grr-artifact-manager-view />",title:"Artifacts"}).state("client",{url:"/clients/:clientId",redirectTo:"client.hostInfo",template:"<div ui-view></div>",title:function(params){return params["clientId"]}}).state("client.hostInfo",{url:"/host-info",template:"<grr-host-info />",title:"Host Information"}).state("client.launchFlows",{url:"/launch-flow",template:"<grr-start-flow-view />",title:"Launch Flows"}).state("client.vfs",
{url:"/vfs/{path:pathWithUnescapedSlashes}?version&mode&tab",template:"<grr-file-view />",title:function(params){return"/"+(params["path"]||"")}}).state("client.flows",{url:"/flows/:flowId/:tab",template:"<grr-client-flows-view />",params:{flowId:{value:null,squash:true},tab:{value:null,squash:true}},title:function(params){if(params["flowId"])return params["flowId"];else return"Flows"}}).state("client.crashes",{url:"/crashes",template:"<grr-client-crashes />",title:"Crashes"}).state("client.debugRequests",
{url:"/debug-requests",template:"<grr-debug-requests-view />",title:"Debug Requests"}).state("client.loadStats",{url:"/load-stats",template:"<grr-client-load-view />",title:"Load Stats"})}).run(function($rootScope,$location,$state,$urlRouter,$document){var updateTitle=function(){var breadcrumbs=[];var curState=$state["$current"];while(angular.isDefined(curState)){if(angular.isString(curState.title))breadcrumbs.splice(0,0,curState.title);else if(angular.isFunction(curState.title)){var newItem=curState.title($state.params);
if(angular.isArray(newItem))breadcrumbs=newItem.concat(breadcrumbs);else breadcrumbs.splice(0,0,newItem)}curState=curState.parent}breadcrumbs.splice(0,0,"GRR");$document[0].title=breadcrumbs.join(" | ")};$rootScope.$on("$stateChangeStart",function(evt,to,params){if(to.redirectTo){evt.preventDefault();$state.go(to.redirectTo,params)}});$rootScope.$on("$stateChangeSuccess",updateTitle);$rootScope.$on("$locationChangeSuccess",function(evt){evt.preventDefault();var url=$location.url().substring(1);var rewrittenUrl=
rewriteUrl(url);if(rewrittenUrl)$location.url(rewrittenUrl);$urlRouter.sync();updateTitle()});$urlRouter.listen()});return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.semantic.semantic");goog.module.declareLegacyNamespace();const {ApiHuntResultDirective}=goog.require("grrUi.semantic.apiHuntResultDirective");const {ByteSizeDirective}=goog.require("grrUi.semantic.byteSizeDirective");const {BytesDirective}=goog.require("grrUi.semantic.bytesDirective");const {ClientUrnDirective}=goog.require("grrUi.semantic.clientUrnDirective");const {DataObjectDirective}=goog.require("grrUi.semantic.dataObjectDirective");
const {DictDirective}=goog.require("grrUi.semantic.dictDirective");const {DurationDirective}=goog.require("grrUi.semantic.durationDirective");const {EncryptionKeyDirective}=goog.require("grrUi.semantic.encryptionKeyDirective");const {ExactDurationDirective}=goog.require("grrUi.semantic.exactDurationDirective");const {FlowIdDirective}=goog.require("grrUi.semantic.flowIdDirective");const {HashDigestDirective}=goog.require("grrUi.semantic.hashDigestDirective");const {HashListDirective}=goog.require("grrUi.semantic.hashListDirective");
const {HuntIdDirective}=goog.require("grrUi.semantic.huntIdDirective");const {JsonDirective}=goog.require("grrUi.semantic.jsonDirective");const {MacAddressDirective}=goog.require("grrUi.semantic.macAddressDirective");const {NetworkAddressDirective}=goog.require("grrUi.semantic.networkAddressDirective");const {ObjectLabelDirective}=goog.require("grrUi.semantic.objectLabelDirective");const {OsqueryTableDirective}=goog.require("grrUi.semantic.osqueryTableDirective");const {PrimitiveDirective}=goog.require("grrUi.semantic.primitiveDirective");
const {RegistryOverrideDirective,SemanticValueDirective}=goog.require("grrUi.semantic.semanticValueDirective");const {SemanticDiffAnnotatedProtoDirective}=goog.require("grrUi.semantic.semanticDiffAnnotatedProtoDirective");const {SemanticProtoDirective}=goog.require("grrUi.semantic.semanticProtoDirective");const {SemanticProtosDiffDirective}=goog.require("grrUi.semantic.semanticProtosDiffDirective");const {SemanticRegistryService}=goog.require("grrUi.core.semanticRegistryService");const {SemanticVersionedProtoDirective}=
goog.require("grrUi.semantic.semanticVersionedProtoDirective");const {StatEntryDirective}=goog.require("grrUi.semantic.statEntryDirective");const {StatExtFlagsLinuxDirective}=goog.require("grrUi.semantic.statExtFlagsLinuxDirective");const {StatExtFlagsOsxDirective}=goog.require("grrUi.semantic.statExtFlagsOsxDirective");const {StatModeDirective}=goog.require("grrUi.semantic.statModeDirective");const {TimestampDirective}=goog.require("grrUi.semantic.timestampDirective");const {TimestampSecondsDirective}=
goog.require("grrUi.semantic.timestampSecondsDirective");const {UrnDirective}=goog.require("grrUi.semantic.urnDirective");const {coreModule}=goog.require("grrUi.core.core");const {pseudoModule}=goog.require("grrUi.semantic.pseudo.pseudo");const {routingModule}=goog.require("grrUi.routing.routing");exports.semanticModule=angular.module("grrUi.semantic",[coreModule.name,routingModule.name,pseudoModule.name,"ui.bootstrap"]);exports.semanticModule.directive(ApiHuntResultDirective.directive_name,ApiHuntResultDirective);
exports.semanticModule.directive(ByteSizeDirective.directive_name,ByteSizeDirective);exports.semanticModule.directive(BytesDirective.directive_name,BytesDirective);exports.semanticModule.directive(ClientUrnDirective.directive_name,ClientUrnDirective);exports.semanticModule.directive(DataObjectDirective.directive_name,DataObjectDirective);exports.semanticModule.directive(DictDirective.directive_name,DictDirective);exports.semanticModule.directive(DurationDirective.directive_name,DurationDirective);
exports.semanticModule.directive(EncryptionKeyDirective.directive_name,EncryptionKeyDirective);exports.semanticModule.directive(ExactDurationDirective.directive_name,ExactDurationDirective);exports.semanticModule.directive(FlowIdDirective.directive_name,FlowIdDirective);exports.semanticModule.directive(HashDigestDirective.directive_name,HashDigestDirective);exports.semanticModule.directive(HashListDirective.directive_name,HashListDirective);exports.semanticModule.directive(HuntIdDirective.directive_name,
HuntIdDirective);exports.semanticModule.directive(JsonDirective.directive_name,JsonDirective);exports.semanticModule.directive(MacAddressDirective.directive_name,MacAddressDirective);exports.semanticModule.directive(NetworkAddressDirective.directive_name,NetworkAddressDirective);exports.semanticModule.directive(ObjectLabelDirective.directive_name,ObjectLabelDirective);exports.semanticModule.directive(OsqueryTableDirective.directive_name,OsqueryTableDirective);exports.semanticModule.directive(PrimitiveDirective.directive_name,
PrimitiveDirective);exports.semanticModule.directive(SemanticDiffAnnotatedProtoDirective.directive_name,SemanticDiffAnnotatedProtoDirective);exports.semanticModule.directive(SemanticProtoDirective.directive_name,SemanticProtoDirective);exports.semanticModule.directive(RegistryOverrideDirective.directive_name,RegistryOverrideDirective);exports.semanticModule.directive(SemanticValueDirective.directive_name,SemanticValueDirective);exports.semanticModule.directive(SemanticProtosDiffDirective.directive_name,
SemanticProtosDiffDirective);exports.semanticModule.directive(SemanticVersionedProtoDirective.directive_name,SemanticVersionedProtoDirective);exports.semanticModule.directive(StatEntryDirective.directive_name,StatEntryDirective);exports.semanticModule.directive(StatExtFlagsLinuxDirective.directive_name,StatExtFlagsLinuxDirective);exports.semanticModule.directive(StatExtFlagsOsxDirective.directive_name,StatExtFlagsOsxDirective);exports.semanticModule.directive(StatModeDirective.directive_name,StatModeDirective);
exports.semanticModule.directive(TimestampDirective.directive_name,TimestampDirective);exports.semanticModule.directive(TimestampSecondsDirective.directive_name,TimestampSecondsDirective);exports.semanticModule.directive(UrnDirective.directive_name,UrnDirective);exports.semanticModule.service(SemanticRegistryService.values_service_name,SemanticRegistryService);exports.semanticModule.run(function(grrSemanticValueDirectivesRegistryService){var registry=grrSemanticValueDirectivesRegistryService;registry.registerDirective(ApiHuntResultDirective.semantic_type,
ApiHuntResultDirective);registry.registerDirective(ByteSizeDirective.semantic_type,ByteSizeDirective);angular.forEach(BytesDirective.semantic_types,function(type){registry.registerDirective(type,BytesDirective)}.bind(this));angular.forEach(ClientUrnDirective.semantic_types,function(type){registry.registerDirective(type,ClientUrnDirective)}.bind(this));registry.registerDirective(DataObjectDirective.semantic_type,DataObjectDirective);angular.forEach(DictDirective.semantic_types,function(type){registry.registerDirective(type,
DictDirective)}.bind(this));registry.registerDirective(DurationDirective.semantic_type,DurationDirective);registry.registerDirective(EncryptionKeyDirective.semantic_type,EncryptionKeyDirective);registry.registerDirective(FlowIdDirective.semantic_type,FlowIdDirective);registry.registerDirective(HashDigestDirective.semantic_type,HashDigestDirective);registry.registerDirective(HashListDirective.semantic_type,HashListDirective);registry.registerDirective(HuntIdDirective.semantic_type,HuntIdDirective);
registry.registerDirective(JsonDirective.semantic_type,JsonDirective);registry.registerDirective(MacAddressDirective.semantic_type,MacAddressDirective);registry.registerDirective(NetworkAddressDirective.semantic_type,NetworkAddressDirective);registry.registerDirective(ObjectLabelDirective.semantic_type,ObjectLabelDirective);registry.registerDirective(ObjectLabelDirective.semantic_type,ObjectLabelDirective);registry.registerDirective(OsqueryTableDirective.semantic_type,OsqueryTableDirective);angular.forEach(PrimitiveDirective.semantic_types,
function(type){registry.registerDirective(type,PrimitiveDirective)}.bind(this));registry.registerDirective(SemanticProtoDirective.semantic_type,SemanticProtoDirective);angular.forEach(StatEntryDirective.semantic_types,function(type){registry.registerDirective(type,StatEntryDirective)}.bind(this));registry.registerDirective(StatExtFlagsLinuxDirective.semantic_type,StatExtFlagsLinuxDirective);registry.registerDirective(StatExtFlagsOsxDirective.semantic_type,StatExtFlagsOsxDirective);registry.registerDirective(StatModeDirective.semantic_type,
StatModeDirective);registry.registerDirective(TimestampDirective.semantic_type,TimestampDirective);registry.registerDirective(TimestampSecondsDirective.semantic_type,TimestampSecondsDirective);registry.registerDirective(UrnDirective.semantic_type,UrnDirective)});return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.artifact.artifact");goog.module.declareLegacyNamespace();const {ArtifactDescriptorDirective}=goog.require("grrUi.artifact.artifactDescriptorDirective");const {ArtifactDescriptorsService}=goog.require("grrUi.artifact.artifactDescriptorsService");const {ArtifactDialogService}=goog.require("grrUi.artifact.artifactDialogService");const {ArtifactManagerViewDirective}=goog.require("grrUi.artifact.artifactManagerViewDirective");const {ArtifactNameDirective}=
goog.require("grrUi.artifact.artifactNameDirective");const {ArtifactsListFormDirective}=goog.require("grrUi.artifact.artifactsListFormDirective");const {DeleteArtifactsDialogDirective}=goog.require("grrUi.artifact.deleteArtifactsDialogDirective");const {UploadArtifactDialogDirective}=goog.require("grrUi.artifact.uploadArtifactDialogDirective");const {coreModule}=goog.require("grrUi.core.core");const {formsModule}=goog.require("grrUi.forms.forms");const {semanticModule}=goog.require("grrUi.semantic.semantic");
exports.artifactModule=angular.module("grrUi.artifact",[coreModule.name,formsModule.name,semanticModule.name,"ui.bootstrap"]);exports.artifactModule.directive(ArtifactDescriptorDirective.directive_name,ArtifactDescriptorDirective);exports.artifactModule.directive(ArtifactNameDirective.directive_name,ArtifactNameDirective);exports.artifactModule.directive(ArtifactManagerViewDirective.directive_name,ArtifactManagerViewDirective);exports.artifactModule.directive(ArtifactsListFormDirective.directive_name,
ArtifactsListFormDirective);exports.artifactModule.directive(DeleteArtifactsDialogDirective.directive_name,DeleteArtifactsDialogDirective);exports.artifactModule.directive(UploadArtifactDialogDirective.directive_name,UploadArtifactDialogDirective);exports.artifactModule.service(ArtifactDescriptorsService.service_name,ArtifactDescriptorsService);exports.artifactModule.service(ArtifactDialogService.service_name,ArtifactDialogService);exports.artifactModule.run(function(grrSemanticRepeatedFormDirectivesRegistryService){var registry=
grrSemanticRepeatedFormDirectivesRegistryService;registry.registerDirective(ArtifactsListFormDirective.semantic_type,ArtifactsListFormDirective)});exports.artifactModule.run(function(grrSemanticValueDirectivesRegistryService){var registry=grrSemanticValueDirectivesRegistryService;registry.registerDirective(ArtifactDescriptorDirective.semantic_type,ArtifactDescriptorDirective);registry.registerDirective(ArtifactNameDirective.semantic_type,ArtifactNameDirective)});return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.addClientsLabelsDialogDirective");goog.module.declareLegacyNamespace();const AddClientsLabelsDialogController=function($scope,$q,grrApiService){this.scope_=$scope;this.q_=$q;this.grrApiService_=grrApiService;this.labelName};AddClientsLabelsDialogController.prototype.proceed=function(){var clients=[];angular.forEach(this.scope_["clients"],function(clientObj){clients.push(clientObj["value"]["client_id"]["value"])});var deferred=
this.q_.defer();var url="/clients/labels/add";var params={client_ids:clients,labels:[this.labelName]};this.grrApiService_.post(url,params).then(function success(){deferred.resolve("Label was successfully added.")}.bind(this),function failure(response){deferred.reject(response.data.message)}.bind(this));return deferred.promise};exports.AddClientsLabelsDialogDirective=function(){return{scope:{clients:"="},restrict:"E",templateUrl:"/static/angular-components/client/"+"add-clients-labels-dialog.html",
controller:AddClientsLabelsDialogController,controllerAs:"controller"}};exports.AddClientsLabelsDialogDirective.directive_name="grrAddClientsLabelsDialog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.checkClientAccessDirective");goog.module.declareLegacyNamespace();const CheckClientAccessController=function($scope,$timeout,grrApiService,grrRoutingService){this.scope_=$scope;this.timeout_=$timeout;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.scope_.$watch("clientId",this.onClientIdChange_.bind(this))};CheckClientAccessController.prototype.onClientIdChange_=function(clientId){if(angular.isDefined(clientId)){this.scope_["outHasAccess"]=
undefined;this.grrApiService_.head("clients/"+clientId+"/flows").then(this.onClientAccessPermitted_.bind(this),this.onClientAccessRejected_.bind(this))}};CheckClientAccessController.prototype.onClientAccessPermitted_=function(){this.scope_["outHasAccess"]=true};CheckClientAccessController.prototype.onClientAccessRejected_=function(){this.scope_["outHasAccess"]=false;if(!this.scope_["noRedirect"])this.timeout_(function(){var clientId=this.scope_["clientId"];if(angular.isDefined(clientId))this.grrRoutingService_.go("client",
{clientId:clientId})}.bind(this),1E3)};exports.CheckClientAccessDirective=function(){return{scope:{noRedirect:"=",clientId:"=",outHasAccess:"=?"},transclude:true,restrict:"E",templateUrl:"/static/angular-components/client/check-client-access.html",controller:CheckClientAccessController,controllerAs:"controller"}};exports.CheckClientAccessDirective.directive_name="grrCheckClientAccess";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.clientContextDirective");goog.module.declareLegacyNamespace();const ClientContextController=function($scope){this.clientId;$scope.$watch("clientId",this.onClientIdChange_.bind(this))};ClientContextController.prototype.onClientIdChange_=function(clientId){this.clientId=clientId};exports.ClientContextDirective=function(){return{scope:{clientId:"="},restrict:"E",transclude:true,template:'<ng-transclude ng-if="controller.clientId"></ng-transclude>',
controller:ClientContextController,controllerAs:"controller"}};exports.ClientContextDirective.directive_name="grrClientContext";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.clientCrashesDirective");goog.module.declareLegacyNamespace();const ClientCrashesController=function($scope,grrApiService,grrRoutingService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.clientId;this.crashes;this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientIdChange_.bind(this))};ClientCrashesController.prototype.onClientIdChange_=function(clientId){this.clientId=
clientId;this.grrApiService_.get("clients/"+clientId+"/crashes").then(function(response){this.crashes=response["data"]["items"]}.bind(this))};exports.ClientCrashesDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/client/client-crashes.html",controller:ClientCrashesController,controllerAs:"controller"}};exports.ClientCrashesDirective.directive_name="grrClientCrashes";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.removeClientsLabelsDialogDirective");goog.module.declareLegacyNamespace();const RemoveClientsLabelsDialogController=function($scope,$q,grrApiService){this.scope_=$scope;this.q_=$q;this.grrApiService_=grrApiService;this.availableLabels=[];this.labelName;this.scope_.$watch("clients",this.onClientsChange_.bind(this))};RemoveClientsLabelsDialogController.prototype.onClientsChange_=function(newValue){var labelsSet={};if(angular.isDefined(newValue))angular.forEach(newValue,
function(client){if(angular.isDefined(client["value"]["labels"]))angular.forEach(client["value"]["labels"],function(label){if(label["value"]["owner"]["value"]!=="GRR")labelsSet[label["value"]["name"]["value"]]=true})}.bind(this));this.availableLabels=Object.keys(labelsSet);if(this.availableLabels.length>0)this.labelName=this.availableLabels[0]};RemoveClientsLabelsDialogController.prototype.proceed=function(){var clients=[];angular.forEach(this.scope_["clients"],function(clientObj){clients.push(clientObj["value"]["client_id"]["value"])});
var deferred=this.q_.defer();var url="/clients/labels/remove";var params={client_ids:clients,labels:[this.labelName]};this.grrApiService_.post(url,params).then(function success(){deferred.resolve("Label was successfully removed.")}.bind(this),function failure(response){deferred.reject(response.data.message)}.bind(this));return deferred.promise};exports.RemoveClientsLabelsDialogDirective=function(){return{scope:{clients:"="},restrict:"E",templateUrl:"/static/angular-components/client/"+"remove-clients-labels-dialog.html",
controller:RemoveClientsLabelsDialogController,controllerAs:"controller"}};exports.RemoveClientsLabelsDialogDirective.directive_name="grrRemoveClientsLabelsDialog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.clientDialogService");goog.module.declareLegacyNamespace();const {AddClientsLabelsDialogDirective}=goog.require("grrUi.client.addClientsLabelsDialogDirective");const {RemoveClientsLabelsDialogDirective}=goog.require("grrUi.client.removeClientsLabelsDialogDirective");exports.ClientDialogService=function(grrDialogService){this.grrDialogService_=grrDialogService};var ClientDialogService=exports.ClientDialogService;ClientDialogService.service_name=
"grrClientDialogService";ClientDialogService.prototype.openAddClientLabels=function(clients){var directive=AddClientsLabelsDialogDirective;return this.grrDialogService_.openDirectiveDialog(directive.directive_name,{clients:clients})};ClientDialogService.prototype.openRemoveClientLabels=function(clients){var directive=RemoveClientsLabelsDialogDirective;return this.grrDialogService_.openDirectiveDialog(directive.directive_name,{clients:clients})};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.clientLoadGraphSerieDirective");goog.module.declareLegacyNamespace();exports.ClientLoadGraphSerieDirective=()=>{return{scope:{clientId:"=",metric:"@",rate:"@",label:"@"},restrict:"E",require:"^grrTimeseriesGraph",link:(scope,element,attrs,grrTimeseriesGraphCtrl)=>{scope.$watch("::clientId",()=>{if(angular.isUndefined(scope.clientId))return;const options={};if(scope.rate)options["rate"]=scope.rate;const path=`clients/${scope.clientId}/load-stats/${scope.metric}`;
grrTimeseriesGraphCtrl.addSerieDescriptor({label:scope.label,requestPath:path,requestOptions:options})})}}};exports.ClientLoadGraphSerieDirective.directive_name="grrClientLoadGraphSerie";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.clientLoadViewDirective");goog.module.declareLegacyNamespace();const ClientLoadViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.cliendId;this.startTime;this.endTime;this.duration=60;this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientIdChange_.bind(this));this.scope_.$watch("controller.duration",this.onDurationChange.bind(this))};ClientLoadViewController.prototype.onClientIdChange_=
function(clientId){this.clientId=clientId};ClientLoadViewController.prototype.onDurationChange=function(newValue){this.endTime=Math.round((new Date).getTime()*1E3);this.startTime=this.endTime-this.duration*60*1E6};exports.ClientLoadViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/client/client-load-view.html",controller:ClientLoadViewController,controllerAs:"controller"}};exports.ClientLoadViewDirective.directive_name="grrClientLoadView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.clientStatusIconsDirective");goog.module.declareLegacyNamespace();let DiskWarning;const ClientStatusIconsController=function($scope,$rootScope,$uibModal,grrTimeService){this.scope_=$scope;this.rootScope_=$rootScope;this.uibModal_=$uibModal;this.grrTimeService_=grrTimeService;this.iconName;this.crashTime;this.diskWarnings=[];this.lastPing;this.scope_.$watch("::client",this.onClientChange_.bind(this))};ClientStatusIconsController.prototype.showDiskWarnings=
function(event){const scope=this.rootScope_.$new(true);scope.warnings=this.diskWarnings;this.uibModal_.open({templateUrl:"/static/angular-components/client/"+"client-disk-warnings-modal.html",scope:scope});event.stopPropagation()};ClientStatusIconsController.prototype.onClientChange_=function(newValue){this.iconName=this.showCrashIcon=null;this.diskWarnings=[];if(angular.isObject(newValue)){this.lastPing=this.scope_.$eval("client.value.last_seen_at.value");if(angular.isUndefined(this.lastPing))this.lastPing=
0;var currentTimeMs=this.grrTimeService_.getCurrentTimeMs();var timeLastSeenSecs=(currentTimeMs-this.lastPing/1E3)/1E3;if(timeLastSeenSecs<60*15)this.iconName="online";else if(timeLastSeenSecs<60*60*24)this.iconName="online-1d";else this.iconName="offline";var crashTime=this.scope_.$eval("client.value.last_crash_at.value");if(angular.isDefined(crashTime)&&currentTimeMs/1E3-crashTime/1E6<60*60*24)this.crashTime=crashTime;angular.forEach(newValue["value"]["volumes"]||[],function(volume){if(volume["value"]["windowsvolume"]&&
volume["value"]["windowsvolume"]["value"]["drive_type"]["value"]=="DRIVE_CDROM")return;if(angular.isDefined(volume["value"]["actual_available_allocation_units"])&&angular.isDefined(volume["value"]["total_allocation_units"])){var percent=volume["value"]["actual_available_allocation_units"]["value"]/volume["value"]["total_allocation_units"]["value"]*100;if(percent<=5){var volumeName="";if(volume["value"]["name"])volumeName=volume["value"]["name"]["value"];this.diskWarnings.push({volume:volumeName,percent:percent})}}}.bind(this))}};
exports.ClientStatusIconsDirective=function(){return{scope:{client:"="},restrict:"E",templateUrl:"/static/angular-components/client/"+"client-status-icons.html",controller:ClientStatusIconsController,controllerAs:"controller"}};exports.ClientStatusIconsDirective.directive_name="grrClientStatusIcons";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.clientUsernamesDirective");goog.module.declareLegacyNamespace();const ClientUsernamesController=function($scope){this.scope_=$scope;this.scope_.usernames;this.scope_.$watch("::value",this.onValueChange_.bind(this))};ClientUsernamesController.prototype.onValueChange_=function(){if(angular.isDefined(this.scope_.value)){var users=this.scope_.value.value.split(" ");var array=[];angular.forEach(users,function(value){array.push({"type":"RDFString",
"value":value})});this.scope_.usernames=array}};exports.ClientUsernamesDirective=function(){return{scope:{value:"="},restrict:"E",template:'<grr-semantic-value value="::usernames" />',controller:ClientUsernamesController,controllerAs:"controller"}};exports.ClientUsernamesDirective.directive_name="grrClientUsernames";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.clientsListDirective");goog.module.declareLegacyNamespace();const ClientsListController=function($scope,grrClientDialogService,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.grrClientDialogService_=grrClientDialogService;this.triggerUpdate;this.clients={};this.selectedClients={};this.allClientsSelected=false;this.numSelectedClients=0;this.query;this.grrRoutingService_.uiOnParamsChanged(this.scope_,
"q",this.onQueryChange_.bind(this))};ClientsListController.prototype.onQueryChange_=function(query){this.query=query;if(this.triggerUpdate)this.triggerUpdate()};ClientsListController.prototype.onClientClick=function(client){var clientId=client["value"]["client_id"]["value"];this.grrRoutingService_.go("client",{clientId:clientId})};ClientsListController.prototype.updateNumSelectedClients=function(){var count=0;for(var key in this.selectedClients)if(this.selectedClients[key])++count;this.numSelectedClients=
count};ClientsListController.prototype.onClientsFetched=function(items){angular.forEach(items,function(item){var clientId=item["value"]["client_id"]["value"];this.clients[clientId]=item;this.selectedClients[clientId]=false;item["_mac_addresses"]=[];angular.forEach(item["value"]["interfaces"],function(iface){if(angular.isDefined(iface["value"]["mac_address"]))item["_mac_addresses"].push(iface["value"]["mac_address"])}.bind(this));item["_usernames"]=[];angular.forEach(item["value"]["users"],function(user){item["_usernames"].push(user["value"]["username"])}.bind(this));
item["tableKey"]=clientId}.bind(this));return items};ClientsListController.prototype.selectAll=function(){for(var key in this.selectedClients)this.selectedClients[key]=this.allClientsSelected;this.updateNumSelectedClients()};ClientsListController.prototype.showLabelsDialog=function(action){var clients=[];for(var clientId in this.selectedClients)if(this.selectedClients[clientId])clients.push(this.clients[clientId]);var result;if(action=="add")result=this.grrClientDialogService_.openAddClientLabels(clients);
else if(action=="remove")result=this.grrClientDialogService_.openRemoveClientLabels(clients);else throw Error("Unexpected action: "+action);result.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){}.bind(this))};ClientsListController.prototype.clientsQueryUrl="/clients";exports.ClientsListDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/client/clients-list.html",controller:ClientsListController,controllerAs:"controller"}};exports.ClientsListDirective.directive_name=
"grrClientsList";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.debugRequestsViewDirective");goog.module.declareLegacyNamespace();const DebugRequestsViewController=function($scope,grrApiService,grrRoutingService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.cliendId;this.actionRequests;this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientIdChange_.bind(this))};DebugRequestsViewController.prototype.onClientIdChange_=
function(clientId){this.clientId=clientId;this.actionRequests=undefined;if(angular.isDefined(this.clientId)){var url="clients/"+this.clientId+"/action-requests";var fetchResponses=1;if(angular.isDefined(this.scope_["fetchResponses"]))fetchResponses=this.scope_["fetchResponses"];this.grrApiService_.get(url,{"fetch_responses":fetchResponses}).then(function(response){this.actionRequests=response["data"]["items"]||[]}.bind(this))}};exports.DebugRequestsViewDirective=function(){return{scope:{fetchResponses:"="},
restrict:"E",templateUrl:"/static/angular-components/client/debug-requests-view.html",controller:DebugRequestsViewController,controllerAs:"controller"}};exports.DebugRequestsViewDirective.directive_name="grrDebugRequestsView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.hostHistoryDialogDirective");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const {TimeService}=goog.require("grrUi.core.timeService");const HostHistoryDialogController=function($scope,grrApiService,grrTimeService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrTimeService_=grrTimeService;this.items;this.endTime;this.startTime;this.scope_.$watchGroup(["clientId",
"fieldPath"],this.onParamsChange_.bind(this))};HostHistoryDialogController.prototype.onParamsChange_=function(){var clientId=this.scope_["clientId"];var fieldPath=this.scope_["fieldPath"];if(angular.isDefined(clientId)&&angular.isDefined(fieldPath)){var endTime=this.grrTimeService_.getCurrentTimeMs()*1E3;var startTime=endTime-1E6*60*60*24*365;this.startTime={type:"RDFDatetime",value:startTime};this.endTime={type:"RDFDatetime",value:endTime};this.grrApiService_.get("/clients/"+clientId+"/versions",
{mode:"DIFF",start:startTime,end:endTime}).then(function(response){this.buildItems_(response["data"]["items"])}.bind(this))}};HostHistoryDialogController.prototype.getFieldFromVersion_=function(version,fieldPath){var components=fieldPath.split(".");var curValue=version;for(var i=0;i<components.length;++i){var component=components[i];curValue=curValue["value"][component];if(angular.isUndefined(curValue))break}return curValue};HostHistoryDialogController.prototype.buildItems_=function(versions){var fieldPath=
this.scope_["fieldPath"];var prevCompareValue;this.items=[];angular.forEach(versions,function(version){var versionValue=this.getFieldFromVersion_(version,fieldPath);if(angular.isUndefined(versionValue))return;var compareValue=stripTypeInfo(versionValue);if(angular.equals(prevCompareValue,compareValue))return;this.items.push([version["value"]["age"],versionValue]);prevCompareValue=compareValue}.bind(this));this.items.reverse()};exports.HostHistoryDialogDirective=function(){return{scope:{clientId:"=",
fieldPath:"=",close:"&"},restrict:"E",templateUrl:"/static/angular-components/client/host-history-dialog.html",controller:HostHistoryDialogController,controllerAs:"controller"}};exports.HostHistoryDialogDirective.directive_name="grrHostHistoryDialog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.hostInfoDirective");goog.module.declareLegacyNamespace();var OPERATION_POLL_INTERVAL_MS=1E3;const HostInfoController=function($scope,$interval,grrApiService,grrRoutingService,grrAclDialogService,grrDialogService){this.scope_=$scope;this.interval_=$interval;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.grrAclDialogService_=grrAclDialogService;this.grrDialogService_=grrDialogService;this.clientVersionUrl;
this.clientId;this.clientVersion;this.client;this.hasClientAccess;this.fetchDetailsRequestId=0;this.interrogateOperationId;this.showDetails=false;this.interrogateOperationInterval_;this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientIdChange_.bind(this));this.scope_.$watch("clientId",this.onClientIdChange_.bind(this));this.scope_.$watch("controller.clientVersion",this.onClientVersionChange_.bind(this));this.scope_.$on("$destroy",this.stopMonitorInterrogateOperation_.bind(this))};
HostInfoController.prototype.onClientIdChange_=function(clientId){if(angular.isDefined(clientId)){this.clientId=clientId;this.clientVersionUrl="/clients/"+clientId+"/version-times";this.fetchClientDetails_()}};HostInfoController.prototype.onClientVersionChange_=function(newValue){if(angular.isUndefined(newValue))return;if(angular.isUndefined(this.client)||this.client["value"]["age"]["value"]!==newValue)this.fetchClientDetails_()};HostInfoController.prototype.fetchClientDetails_=function(){var url=
"/clients/"+this.clientId;var params={};if(this.clientVersion)params["timestamp"]=this.clientVersion;this.fetchDetailsRequestId+=1;var requestId=this.fetchDetailsRequestId;this.grrApiService_.get(url,params).then(function success(response){if(this.fetchDetailsRequestId!=requestId)return;this.client=response.data;this.clientVersion=response.data["value"]["age"]["value"]}.bind(this))};HostInfoController.prototype.requestApproval=function(){this.grrAclDialogService_.openRequestClientApprovalDialog(this.clientId)};
HostInfoController.prototype.interrogate=function(){var url="/clients/"+this.clientId+"/actions/interrogate";this.grrApiService_.post(url).then(function success(response){this.interrogateOperationId=response["data"]["operation_id"];this.monitorInterrogateOperation_()}.bind(this),function failure(response){this.stopMonitorInterrogateOperation_()}.bind(this))};HostInfoController.prototype.monitorInterrogateOperation_=function(){this.interrogateOperationInterval_=this.interval_(this.pollInterrogateOperationState_.bind(this),
OPERATION_POLL_INTERVAL_MS)};HostInfoController.prototype.pollInterrogateOperationState_=function(){var url="clients/"+this.clientId+"/actions/interrogate/"+this.interrogateOperationId;this.grrApiService_.get(url).then(function success(response){if(response["data"]["state"]==="FINISHED"){this.stopMonitorInterrogateOperation_();this.clientVersion=null;this.fetchClientDetails_()}}.bind(this),function failure(response){this.stopMonitorInterrogateOperation_()}.bind(this))};HostInfoController.prototype.stopMonitorInterrogateOperation_=
function(){this.interrogateOperationId=null;this.interval_.cancel(this.interrogateOperationInterval_)};HostInfoController.prototype.showHistoryDialog=function(fieldPath){this.grrDialogService_.openDirectiveDialog("grrHostHistoryDialog",{clientId:this.clientId,fieldPath:fieldPath},{windowClass:"high-modal"})};exports.HostInfoDirective=function(){return{scope:{"clientId":"=","readOnly":"="},restrict:"E",templateUrl:"/static/angular-components/client/host-info.html",controller:HostInfoController,controllerAs:"controller"}};
exports.HostInfoDirective.directive_name="grrHostInfo";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.auditChartDirective");goog.module.declareLegacyNamespace();const {stripTypeInfo}=goog.require("grrUi.core.apiService");const {upperCaseToTitleCase}=goog.require("grrUi.core.utils");const AuditChartController=function($scope,$element){this.scope_=$scope;this.element_=$element;this.auditUsedFields;this.auditTitleCaseUsedFields;this.typedAuditRows;this.errorMsg="";this.scope_.$watch("typedData",function(typedData){if(angular.isDefined(typedData)&&
angular.isDefined(typedData["value"]))this.initAuditChart_(typedData["value"]["audit_chart"])}.bind(this))};AuditChartController.prototype.initAuditChart_=function(typedAuditChartData){var auditChartData=stripTypeInfo(typedAuditChartData);this.auditUsedFields=undefined;this.auditTitleCaseUsedFields=undefined;this.typedAuditRows=undefined;if(angular.isUndefined(auditChartData["rows"])||auditChartData["rows"].length==0||angular.isUndefined(auditChartData["used_fields"])||auditChartData["used_fields"].length==
0){this.errorMsg="No data to display.";return}this.auditUsedFields=auditChartData["used_fields"];this.auditTitleCaseUsedFields=auditChartData["used_fields"].map(upperCaseToTitleCase);this.typedAuditRows=typedAuditChartData["value"]["rows"]};exports.AuditChartDirective=function(){return{scope:{typedData:"="},restrict:"E",templateUrl:"/static/angular-components/stats/audit-chart.html",controller:AuditChartController,controllerAs:"controller"}};exports.AuditChartDirective.directive_name="grrAuditChart";
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.chartDirective");goog.module.declareLegacyNamespace();exports.ChartDirective=function(){return{scope:{typedData:"="},restrict:"E",templateUrl:"/static/angular-components/stats/chart.html"}};exports.ChartDirective.directive_name="grrChart";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.comparisonChartDirective");goog.module.declareLegacyNamespace();const ComparisonChartController=function($scope){this.scope_=$scope;this.values=[];this.scope_.$watchGroup(["typedData","preserveOrder"],([typedData,_])=>{if(angular.isDefined(typedData))this.initComparisonChart_(typedData["value"])})};ComparisonChartController.prototype.initComparisonChart_=function(comparisonChartData){this.values=[];let maxValue=0;comparisonChartData["data"].forEach(series=>
{const label=series["value"]["label"]["value"];const value=series["value"]["x"]["value"];this.values.push({label:label,value:value});if(value>maxValue)maxValue=value});if(!this.scope_["preserveOrder"])this.values.sort((a,b)=>b["value"]-a["value"]);angular.forEach(this.values,v=>{v["percent"]=Math.round(v["value"]/maxValue*100)})};exports.ComparisonChartDirective=function(){return{scope:{typedData:"=",preserveOrder:"="},restrict:"E",templateUrl:"/static/angular-components/stats/comparison-chart.html",
controller:ComparisonChartController,controllerAs:"controller"}};exports.ComparisonChartDirective.directive_name="grrComparisonChart";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.graphUtils");goog.module.declareLegacyNamespace();exports.buildTimeseriesGraph=function(graphDiv,legendDiv,seriesDict){const labels=["Time"];const dataMap=new Map;for(var label in seriesDict){var serie=seriesDict[label];labels.push(label);angular.forEach(serie,dataPoint=>{let entry=dataMap.get(dataPoint[0]);if(entry===undefined){entry={};dataMap.set(dataPoint[0],entry)}entry[label]=dataPoint[1]})}const timestamps=Array.from(dataMap.keys());
timestamps.sort();const data=[];angular.forEach(timestamps,t=>{const row=[new Date(t)];const timestampData=dataMap.get(t);for(let i=1;i<labels.length;++i)row.push(timestampData[labels[i]]);data.push(row)});return new Dygraph(graphDiv[0],data,{animatedZoom:true,labels:labels,labelsDiv:legendDiv?legendDiv[0]:undefined,connectSeparatedPoints:true,labelsSeparateLines:true,highlightSeriesOpts:{strokeWidth:2,strokeBorderWidth:1,highlightCircleSize:5},highlightCircleSize:2,strokeBorderWidth:1,axes:{x:{valueFormatter:ms=>
{return(new Date(ms)).toUTCString()}}}})};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.lineChartDirective");goog.module.declareLegacyNamespace();const {buildTimeseriesGraph}=goog.require("grrUi.stats.graphUtils");const LineChartController=function($scope,$element){this.scope_=$scope;this.element_=$element;this.chartElement_=this.element_.find(".chart");this.chartLegendElement_=this.element_.find(".chart-legend");this.scope_.$watch("typedData",typedData=>{if(angular.isDefined(typedData))this.initLineChart_(typedData["value"])})};
LineChartController.prototype.initLineChart_=function(lineChartData){if(angular.isUndefined(lineChartData["data"])||lineChartData["data"].length==0){this.errorMsg="No data to display.";return}const series={};angular.forEach(lineChartData["data"],serie=>{const label=serie["value"]["label"]["value"];series[label]=serie["value"]["points"].map(p=>[p["value"]["x"]["value"],p["value"]["y"]["value"]])});this.chartElement_.resize(()=>{this.chartElement_.html("");buildTimeseriesGraph(this.chartElement_,this.chartLegendElement_,
series)});this.chartElement_.resize()};exports.LineChartDirective=function(){return{scope:{typedData:"="},restrict:"E",templateUrl:"/static/angular-components/stats/line-chart.html",controller:LineChartController,controllerAs:"controller"}};exports.LineChartDirective.directive_name="grrLineChart";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.reportDescsService");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");exports.ReportDescsService=function($q,grrApiService){this.q_=$q;this.grrApiService_=grrApiService;this.reports_;this.descsByName_};var ReportDescsService=exports.ReportDescsService;ReportDescsService.service_name="grrReportDescsService";ReportDescsService.prototype.getDescs=function(){var deferred=
this.q_.defer();if(angular.isDefined(this.reports_))deferred.resolve(this.reports_);else this.grrApiService_.get("stats/reports").then(function(response){this.reports_=stripTypeInfo(response["data"]["reports"]);deferred.resolve(this.reports_)}.bind(this));return deferred.promise};ReportDescsService.prototype.getDescByName=function(name){var deferred=this.q_.defer();if(angular.isDefined(this.descsByName_))deferred.resolve(this.descsByName_[name]);else this.getDescs().then(function(reports){this.descsByName_=
{};for(var i=0;i<reports.length;i++){var desc=reports[i]["desc"];this.descsByName_[desc["name"]]=desc}deferred.resolve(this.descsByName_[name])}.bind(this));return deferred.promise};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.reportDirective");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const {ReflectionService}=goog.require("grrUi.core.reflectionService");const {ReportDescsService}=goog.require("grrUi.stats.reportDescsService");const {TimeService}=goog.require("grrUi.core.timeService");const {upperCaseToTitleCase}=goog.require("grrUi.core.utils");var WEEK_SECONDS=7*24*60*60;var DEFAULT_START_TIME_SECS=
Math.ceil(moment().valueOf()/1E3-WEEK_SECONDS);var DEFAULT_DURATION_SECS=WEEK_SECONDS;var DEFAULT_CLIENT_LABEL="";const ReportController=function($scope,grrApiService,grrReflectionService,grrTimeService,grrReportDescsService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrReflectionService_=grrReflectionService;this.grrTimeService_=grrTimeService;this.grrReportDescsService_=grrReportDescsService;this.state="INITIAL";this.titleCasedType;this.typedReportData;this.reportData;this.reportDesc;
this.startTime=null;this.duration=null;this.clientLabel=null;this.latestFetchTime_=0;this.scope_.$watch("name",function(name){this.grrReportDescsService_.getDescByName(name).then(function(desc){if(angular.isUndefined(desc))return;this.reportDesc=desc;this.titleCasedType=upperCaseToTitleCase(this.reportDesc["type"]);this.onParamsChange_()}.bind(this))}.bind(this));this.scope_.$watchGroup(["startTime","duration","clientLabel"],this.onParamsChange_.bind(this))};ReportController.prototype.onParamsChange_=
function(){var startTime=this.scope_["startTime"];if(angular.isDefined(startTime))this.startTime=startTime;var duration=this.scope_["duration"];if(angular.isDefined(duration))this.duration=duration;var clientLabel=this.scope_["clientLabel"];if(angular.isDefined(clientLabel))this.clientLabel=clientLabel;this.fetchData_()};ReportController.prototype.refreshReport=function(){this.scope_["startTime"]=this.startTime;this.scope_["duration"]=this.duration;this.scope_["clientLabel"]=this.clientLabel};ReportController.prototype.fetchData_=
function(){if(angular.isUndefined(this.reportDesc))return;var name=this.reportDesc["name"];if(!name)return;this.state="LOADING";var startTime=DEFAULT_START_TIME_SECS;if(this.startTime!==null)startTime=this.startTime;var duration=DEFAULT_DURATION_SECS;if(this.duration!==null)duration=this.duration;var clientLabel=DEFAULT_CLIENT_LABEL;if(this.clientLabel!==null)clientLabel=this.clientLabel;var apiUrl="stats/reports/"+name;var apiParams={start_time:startTime*1E6,duration:duration,client_label:clientLabel};
if(this.reportDesc["requires_time_range"]){this.startTime=startTime;this.duration=duration}if(this.reportDesc["type"]==="CLIENT")this.clientLabel=clientLabel;var fetchTime=this.grrTimeService_.getCurrentTimeMs();this.latestFetchTime_=fetchTime;this.grrApiService_.get(apiUrl,apiParams).then(function(response){if(fetchTime!==this.latestFetchTime_)return;this.typedReportData=response["data"]["data"];this.reportData=stripTypeInfo(this.typedReportData);this.state="LOADED"}.bind(this))};exports.ReportDirective=
function(){return{scope:{name:"=?",startTime:"=?",duration:"=?",clientLabel:"=?"},restrict:"E",templateUrl:"/static/angular-components/stats/report.html",controller:ReportController,controllerAs:"controller"}};exports.ReportDirective.directive_name="grrReport";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.reportListingDirective");goog.module.declareLegacyNamespace();const {upperCaseToTitleCase}=goog.require("grrUi.core.utils");exports.parseStatsReportsApiResponse=function(reports){var ret=[];var reportsByType={};angular.forEach(reports,function(report){var desc=report["desc"];var reportType=desc["type"];var typeReportListing;if(angular.isUndefined(reportsByType[reportType])){typeReportListing=[];reportsByType[reportType]=typeReportListing;
ret.push({text:upperCaseToTitleCase(reportType),children:typeReportListing,state:{opened:true,disabled:true}})}else typeReportListing=reportsByType[reportType];var leaf={id:desc["name"],text:desc["title"],desc:desc};typeReportListing.push(leaf)});return ret};var parseStatsReportsApiResponse=exports.parseStatsReportsApiResponse;const ReportListingController=function($scope,$element,grrReportDescsService){this.scope_=$scope;this.element_=$element;this.grrReportDescsService_=grrReportDescsService;this.treeElement_=
this.element_.find(".report-listing-tree");this.tree_;this.selectionName_;this.reportListing_;this.grrReportDescsService_.getDescs().then(function(reports){this.reportListing_=parseStatsReportsApiResponse(reports);this.initTree_()}.bind(this));this.scope_.$watch("selectionName",function(selectionName){if(angular.isUndefined(selectionName))return;this.selectionName_=selectionName}.bind(this));this.scope_.$watch("controller.selectionName_",function(){if(angular.isUndefined(this.selectionName_))return;
this.scope_["selectionName"]=this.selectionName_;this.updateTreeSelection_()}.bind(this))};ReportListingController.prototype.initTree_=function(){this.treeElement_.jstree({"core":{"data":this.reportListing_}});this.tree_=this.treeElement_.jstree(true);this.treeElement_.on("loaded.jstree",function(event,data){this.updateTreeSelection_()}.bind(this));this.treeElement_.on("select_node.jstree",function(event,data){var desc=data["node"]["original"]["desc"];this.selectionName_=desc["name"]}.bind(this))};
ReportListingController.prototype.updateTreeSelection_=function(){if(angular.isUndefined(this.tree_))return;this.tree_["deselect_all"]();this.tree_["select_node"](this.selectionName_)};exports.ReportListingDirective=function(){return{restrict:"E",scope:{selectionName:"=?"},templateUrl:"/static/angular-components/stats/report-listing.html",controller:ReportListingController,controllerAs:"controller"}};exports.ReportListingDirective.directive_name="grrReportListing";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.statsViewDirective");goog.module.declareLegacyNamespace();const StatsViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.selectionName;this.startTime;this.duration;this.clientLabel;this.oldSelectionName_;this.grrRoutingService_.uiOnParamsChanged(this.scope_,["name","start_time","duration","client_label"],this.onUrlParamsChange_.bind(this));this.scope_.$watchGroup(["controller.selectionName",
"controller.startTime","controller.duration","controller.clientLabel"],this.onControllerParamsChange_.bind(this))};StatsViewController.prototype.onUrlParamsChange_=function(unused_values,params){var selectionName=params["name"];if(angular.isDefined(selectionName))this.selectionName=selectionName;var startTimeStr=params["start_time"];if(angular.isDefined(startTimeStr))this.startTime=parseInt(startTimeStr,10);var durationStr=params["duration"];if(angular.isDefined(durationStr))this.duration=parseInt(durationStr,
10);var clientLabel=params["client_label"];if(angular.isDefined(clientLabel))this.clientLabel=clientLabel};StatsViewController.prototype.onControllerParamsChange_=function(){if(angular.isUndefined(this.selectionName))return;if(angular.isDefined(this.oldSelectionName_)&&this.oldSelectionName_!==this.selectionName){this.startTime=null;this.duration=null;this.clientLabel=null}this.oldSelectionName_=this.selectionName;var urlParams={name:this.selectionName};if(angular.isDefined(this.startTime))urlParams["start_time"]=
this.startTime;if(angular.isDefined(this.duration))urlParams["duration"]=this.duration;if(angular.isDefined(this.clientLabel))urlParams["client_label"]=this.clientLabel;this.grrRoutingService_.go("stats",urlParams)};exports.StatsViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/stats/stats-view.html",controller:StatsViewController,controllerAs:"controller"}};exports.StatsViewDirective.directive_name="grrStatsView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.timeseriesGraphDirective");goog.module.declareLegacyNamespace();const {buildTimeseriesGraph}=goog.require("grrUi.stats.graphUtils");let TimeserieDescriptor;const TimeseriesGraphController=function($scope,$element,$interval,grrApiService){this.scope_=$scope;this.element_=$element;this.interval_=$interval;this.grrApiService_=grrApiService;this.timeRange=[NaN,NaN];this.seriesDescriptors=[];this.fetchedSeries={};this.inProgress=false;
this.isEmpty=false;this.scope_.$watch("startTime",this.onStartTimeChange_.bind(this));this.scope_.$watch("endTime",this.onEndTimeChange_.bind(this));this.scope_.$watch("controller.timeRange",this.onConfigurationChange_.bind(this),true);this.scope_.$watch("controller.seriesDescriptors",this.onConfigurationChange_.bind(this),true)};TimeseriesGraphController.prototype.onStartTimeChange_=function(newValue){this.timeRange[0]=newValue};TimeseriesGraphController.prototype.onEndTimeChange_=function(newValue){this.timeRange[1]=
newValue};TimeseriesGraphController.prototype.computeDelta_=function(points){if(!points||points.length<2)return;let prevPointValue=points.shift()[1];for(var i=0;i<points.length;++i){const pointValue=points[i][1];points[i][1]=points[i][1]-prevPointValue;prevPointValue=pointValue}};TimeseriesGraphController.prototype.onConfigurationChange_=function(){this.inProgress=true;this.isEmpty=false;this.fetchedSeries={};angular.forEach(this.seriesDescriptors,descriptor=>{const options={start:this.timeRange[0],
end:this.timeRange[1]};angular.extend(options,descriptor.requestOptions||{});const prevTimeRange=this.timeRange.slice();this.grrApiService_.get(descriptor.requestPath,options).then(response=>{if(angular.equals(prevTimeRange,this.timeRange)){const serie=response["data"]["data_points"]||[];if(this.scope_["computeDelta"])this.computeDelta_(serie["data_points"]);this.fetchedSeries[descriptor.label]=serie;this.buildGraphIfNeeded_()}})})};TimeseriesGraphController.prototype.addSerieDescriptor=function(descriptor){this.seriesDescriptors.push(descriptor)};
TimeseriesGraphController.prototype.buildGraphIfNeeded_=function(){if(Object.keys(this.fetchedSeries).length===this.seriesDescriptors.length){this.isEmpty=Object.values(this.fetchedSeries).every(series=>series.length===0);this.inProgress=false;if(this.isEmpty)return;const intervalPromise=this.interval_(()=>{const graphElement=$(this.element_).find(".timeseries-graph");const graphLegendElement=$(this.element_).find(".timeseries-graph-legend");if(graphElement&&graphElement.width()>0&&graphElement.height()>
0){buildTimeseriesGraph(graphElement,graphLegendElement,this.fetchedSeries);this.interval_.cancel(intervalPromise)}},500,10)}};exports.TimeseriesGraphDirective=function(){return{scope:{title:"@",computeDelta:"@",startTime:"=",endTime:"="},restrict:"E",templateUrl:"/static/angular-components/stats/timeseries-graph.html",transclude:true,controller:TimeseriesGraphController,controllerAs:"controller"}};exports.TimeseriesGraphDirective.directive_name="grrTimeseriesGraph";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.stats.stats");goog.module.declareLegacyNamespace();const {AuditChartDirective}=goog.require("grrUi.stats.auditChartDirective");const {ChartDirective}=goog.require("grrUi.stats.chartDirective");const {ComparisonChartDirective}=goog.require("grrUi.stats.comparisonChartDirective");const {LineChartDirective}=goog.require("grrUi.stats.lineChartDirective");const {ReportDescsService}=goog.require("grrUi.stats.reportDescsService");const {ReportDirective}=
goog.require("grrUi.stats.reportDirective");const {ReportListingDirective}=goog.require("grrUi.stats.reportListingDirective");const {StatsViewDirective}=goog.require("grrUi.stats.statsViewDirective");const {TimeseriesGraphDirective}=goog.require("grrUi.stats.timeseriesGraphDirective");const {coreModule}=goog.require("grrUi.core.core");exports.statsModule=angular.module("grrUi.stats",[coreModule.name]);exports.statsModule.directive(AuditChartDirective.directive_name,AuditChartDirective);exports.statsModule.directive(ComparisonChartDirective.directive_name,
ComparisonChartDirective);exports.statsModule.directive(ChartDirective.directive_name,ChartDirective);exports.statsModule.directive(LineChartDirective.directive_name,LineChartDirective);exports.statsModule.directive(ReportDirective.directive_name,ReportDirective);exports.statsModule.directive(ReportListingDirective.directive_name,ReportListingDirective);exports.statsModule.directive(StatsViewDirective.directive_name,StatsViewDirective);exports.statsModule.directive(TimeseriesGraphDirective.directive_name,
TimeseriesGraphDirective);exports.statsModule.service(ReportDescsService.service_name,ReportDescsService);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.breadcrumbsDirective");goog.module.declareLegacyNamespace();const BreadcrumbsController=function($rootScope,$scope,grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.items;this.activeItem;this.scope_.$watchGroup(["path","stripEndingSlash"],this.onDirectiveArgsChange_.bind(this))};BreadcrumbsController.prototype.onDirectiveArgsChange_=function(){var pathArg=this.scope_["path"];var stripEndingSlashArg=
this.scope_["stripEndingSlash"];this.items=[];this.activeItem=undefined;if(!pathArg)return;var components=pathArg.split("/");if(stripEndingSlashArg&&pathArg.endsWith("/"))components=components.slice(0,components.length-1);if(components.length<2)return;components=components.slice(0,-1);var currentPath="";angular.forEach(components.slice(0,-1),function(component){currentPath+=component+"/";this.items.push({name:component,path:currentPath})}.bind(this));this.activeItem=components[components.length-1]};
BreadcrumbsController.prototype.selectPath=function(path){this.scope_["path"]=path};exports.BreadcrumbsDirective=function(){return{restrict:"E",scope:{path:"=",stripEndingSlash:"="},templateUrl:"/static/angular-components/client/virtual-file-system/breadcrumbs.html",controller:BreadcrumbsController,controllerAs:"controller"}};exports.BreadcrumbsDirective.directive_name="grrBreadcrumbs";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.encodingsDropdownDirective");goog.module.declareLegacyNamespace();const EncodingsDropdownController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrApiService_.get("reflection/file-encodings").then(function(response){this.encodings=response.data["encodings"]}.bind(this))};exports.EncodingsDropdownDirective=function(){return{restrict:"E",scope:{encoding:"="},templateUrl:"/static/angular-components/client/virtual-file-system/encodings-dropdown.html",
controller:EncodingsDropdownController,controllerAs:"controller"}};exports.EncodingsDropdownDirective.directive_name="grrEncodingsDropdown";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.fileContextDirective");goog.module.declareLegacyNamespace();exports.FileContextController=function($scope){this.scope_=$scope;this.clientId;this.selectedFilePath;this.selectedFileVersion;this.scope_.$watchGroup(["clientId","selectedFilePath","selectedFileVersion"],this.onDirectiveArgumentsChange_.bind(this));this.scope_.$watchGroup(["controller.clientId","controller.selectedFilePath","controller.selectedFileVersion"],
this.onControllerValuesChange_.bind(this))};var FileContextController=exports.FileContextController;FileContextController.prototype.onDirectiveArgumentsChange_=function(){this.clientId=this.scope_["clientId"];this.selectedFilePath=this.scope_["selectedFilePath"];this.selectedFileVersion=this.scope_["selectedFileVersion"]};FileContextController.prototype.onControllerValuesChange_=function(){this.scope_["clientId"]=this.clientId;this.scope_["selectedFilePath"]=this.selectedFilePath;this.scope_["selectedFileVersion"]=
this.selectedFileVersion};FileContextController.prototype.selectFile=function(filePath,opt_fileVersion){this.selectedFilePath=filePath;this.selectedFileVersion=opt_fileVersion||undefined};exports.FileContextDirective=function(){return{restrict:"E",scope:{clientId:"=",selectedFilePath:"=",selectedFileVersion:"="},transclude:true,template:"<ng-transclude />",controller:FileContextController,controllerAs:"controller"}};exports.FileContextDirective.directive_name="grrFileContext";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.events");goog.module.declareLegacyNamespace();exports.REFRESH_FOLDER_EVENT="RefreshFolderEvent";exports.REFRESH_FILE_EVENT="RefreshFileEvent";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.fileDetailsDirective");goog.module.declareLegacyNamespace();const {REFRESH_FILE_EVENT}=goog.require("grrUi.client.virtualFileSystem.events");const {VersionDropdownDirective}=goog.require("grrUi.core.versionDropdownDirective");var REFRESH_VERSIONS_EVENT=VersionDropdownDirective.REFRESH_VERSIONS_EVENT;const FileDetailsController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;
this.shownFileName;this.fileVersionUrl;this.fileContext;this.fileIsDirectory;this.downloadQueryParams;this.currentTab="stats";this.scope_.$on(REFRESH_FILE_EVENT,this.refreshFile_.bind(this));this.scope_.$watch("currentTab",this.onDirectiveTabChange_.bind(this));this.scope_.$watch("controller.currentTab",this.onControllerTabChange_.bind(this));this.scope_.$watchGroup(["controller.fileContext.clientId","controller.fileContext.selectedFilePath","controller.fileContext.selectedFileVersion"],this.onContextChange_.bind(this))};
FileDetailsController.prototype.onDirectiveTabChange_=function(newValue){if(angular.isString(newValue))this.currentTab=newValue};FileDetailsController.prototype.onControllerTabChange_=function(newValue,oldValue){if(newValue!==oldValue)this.scope_["currentTab"]=newValue};FileDetailsController.prototype.onContextChange_=function(){var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"];if(angular.isDefined(clientId)&&angular.isDefined(selectedFilePath))this.fetchFileDetails_()};
FileDetailsController.prototype.fetchFileDetails_=function(){var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];var url="clients/"+clientId+"/vfs-details/"+selectedFilePath;var params={};if(fileVersion)params["timestamp"]=fileVersion;this.grrApiService_.get(url,params).then(this.onFileDetailsFetched_.bind(this))};FileDetailsController.prototype.onFileDetailsFetched_=function(response){var clientId=
this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];var fileDetails=response.data["file"];this.fileVersionUrl="clients/"+clientId+"/vfs-version-times/"+selectedFilePath;this.fileIsDirectory=fileDetails["value"]["is_directory"]["value"];this.downloadQueryParams={clientId:clientId,aff4_path:"aff4:/"+clientId+"/"+selectedFilePath};if(fileVersion)this.downloadQueryParams["age"]=fileVersion;var components=fileDetails["value"]["path"]["value"].split("/");
this.selectedFileName=components[components.length-1]};FileDetailsController.prototype.refreshFile_=function(){this.fileContext["selectedFileVersion"]=undefined;this.scope_.$broadcast(REFRESH_VERSIONS_EVENT,{});this.fetchFileDetails_()};FileDetailsController.prototype.targetsCurrentSelection_=function(fileDetails){var selectedFilePath=this.fileContext["selectedFilePath"];return fileDetails["value"]["path"]["value"]===selectedFilePath};exports.FileDetailsDirective=function(){return{restrict:"E",scope:{currentTab:"="},
require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-details.html",controller:FileDetailsController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};exports.FileDetailsDirective.directive_name="grrFileDetails";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.fileDownloadViewDirective");goog.module.declareLegacyNamespace();const {REFRESH_FILE_EVENT}=goog.require("grrUi.client.virtualFileSystem.events");const {ServerErrorButtonDirective}=goog.require("grrUi.core.serverErrorButtonDirective");var ERROR_EVENT_NAME=ServerErrorButtonDirective.error_event_name;var OPERATION_POLL_INTERVAL_MS=1E3;const FileDownloadViewController=function($rootScope,$scope,$interval,grrApiService){this.rootScope_=
$rootScope;this.scope_=$scope;this.interval_=$interval;this.fileContext;this.grrApiService_=grrApiService;this.updateOperationId;this.updateOperationInterval_;this.updateInProgress;this.downloadCommand;this.fileDetails;this.scope_.$watchGroup(["controller.fileContext.clientId","controller.fileContext.selectedFilePath","controller.fileContext.selectedFileVersion"],this.onContextChange_.bind(this));this.scope_.$on("$destroy",this.stopMonitorUpdateOperation_.bind(this))};FileDownloadViewController.prototype.onContextChange_=
function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];if(angular.isDefined(clientId)&&angular.isDefined(filePath)){var commandUrl="clients/"+clientId+"/vfs-download-command/"+filePath;this.grrApiService_.get(commandUrl).then(function(response){this.downloadCommand=response.data["command"]}.bind(this));var detailsUrl="clients/"+clientId+"/vfs-details/"+filePath;var params={};if(fileVersion)params["timestamp"]=
fileVersion;this.fileDetails=undefined;this.grrApiService_.get(detailsUrl,params).then(function(response){this.fileDetails=response.data["file"]}.bind(this))}};FileDownloadViewController.prototype.updateFile=function(){if(this.updateInProgress)return;var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"];var url="clients/"+clientId+"/vfs-update";var params={file_path:selectedFilePath};this.updateInProgress=true;this.grrApiService_.post(url,params).then(function success(response){this.updateOperationId=
response["data"]["operation_id"];this.monitorUpdateOperation_()}.bind(this),function failure(response){this.stopMonitorUpdateOperation_()}.bind(this))};FileDownloadViewController.prototype.monitorUpdateOperation_=function(){this.updateOperationInterval_=this.interval_(this.pollUpdateOperationState_.bind(this),OPERATION_POLL_INTERVAL_MS)};FileDownloadViewController.prototype.pollUpdateOperationState_=function(){var clientId=this.fileContext["clientId"];var url="clients/"+clientId+"/vfs-update/"+this.updateOperationId;
this.grrApiService_.get(url).then(function success(response){if(response["data"]["state"]==="FINISHED"){this.rootScope_.$broadcast(REFRESH_FILE_EVENT);this.stopMonitorUpdateOperation_()}}.bind(this),function failure(response){this.stopMonitorUpdateOperation_()}.bind(this))};FileDownloadViewController.prototype.stopMonitorUpdateOperation_=function(){this.updateOperationId=null;this.updateInProgress=false;this.interval_.cancel(this.updateOperationInterval_)};FileDownloadViewController.prototype.downloadFile=
function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];var url="clients/"+clientId+"/vfs-blob/"+filePath;var params={};if(fileVersion)params["timestamp"]=fileVersion;this.grrApiService_.downloadFile(url,params).then(function success(){}.bind(this),function failure(response){if(angular.isUndefined(response.status))this.rootScope_.$broadcast(ERROR_EVENT_NAME,{message:"Couldn't download file."})}.bind(this))};
exports.FileDownloadViewDirective=function(){return{restrict:"E",scope:{},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-download-view.html",controller:FileDownloadViewController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};exports.FileDownloadViewDirective.directive_name="grrFileDownloadView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.fileHexViewDirective");goog.module.declareLegacyNamespace();const FileHexViewController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.fileContext;this.hexDataRows;this.page=1;this.pageCount=1;this.rows_=25;this.columns_=32;this.offset_=0;this.chunkSize_=this.rows_*this.columns_;this.scope_.$watchGroup(["controller.fileContext.clientId","controller.fileContext.selectedFilePath",
"controller.fileContext.selectedFileVersion"],this.onContextChange_.bind(this));this.scope_.$watch("controller.page",this.onPageChange_.bind(this))};FileHexViewController.prototype.onContextChange_=function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];if(angular.isDefined(clientId)&&angular.isDefined(filePath))this.fetchText_()};FileHexViewController.prototype.onPageChange_=function(page,oldPage){if(this.page!==oldPage){this.offset_=(this.page-1)*this.chunkSize_;
this.fetchText_()}};FileHexViewController.prototype.fetchText_=function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];var url="clients/"+clientId+"/vfs-blob/"+filePath;var headParams={};if(fileVersion)headParams["timestamp"]=fileVersion;this.grrApiService_.head(url,headParams).then(function(response){var total_size=response.headers("Content-Length");this.pageCount=Math.ceil(total_size/this.chunkSize_);
var params={};params["offset"]=this.offset_;params["length"]=this.chunkSize_;if(fileVersion)params["timestamp"]=fileVersion;return this.grrApiService_.get(url,params)}.bind(this)).then(function(response){this.parseFileContentToHexRepresentation_(response.data)}.bind(this),function(){this.hexDataRows=null}.bind(this))};FileHexViewController.prototype.parseFileContentToHexRepresentation_=function(fileContent){this.hexDataRows=[];if(!fileContent)return;for(var i=0;i<this.rows_;i++){var rowOffset=this.offset_+
i*this.columns_;this.hexDataRows.push({offset:rowOffset,data:fileContent.substr(i*this.columns_,this.columns_)})}};exports.FileHexViewDirective=function(){return{restrict:"E",scope:{},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-hex-view.html",controller:FileHexViewController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};exports.FileHexViewDirective.directive_name=
"grrFileHexView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.fileStatsViewDirective");goog.module.declareLegacyNamespace();const FileStatsViewController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.fileContext;this.details;this.scope_.$watchGroup(["controller.fileContext.clientId","controller.fileContext.selectedFilePath","controller.fileContext.selectedFileVersion"],this.onContextChange_.bind(this))};FileStatsViewController.prototype.onContextChange_=
function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];if(angular.isDefined(clientId)&&angular.isDefined(filePath)){var fileDetailsUrl="clients/"+clientId+"/vfs-details/"+filePath;var params={};if(fileVersion)params["timestamp"]=fileVersion;this.grrApiService_.get(fileDetailsUrl,params).then(function(response){this.details=response.data["file"]["value"]["details"]}.bind(this))}};exports.FileStatsViewDirective=
function(){return{restrict:"E",scope:{},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-stats-view.html",controller:FileStatsViewController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};exports.FileStatsViewDirective.directive_name="grrFileStatsView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.fileTableDirective");goog.module.declareLegacyNamespace();const {REFRESH_FILE_EVENT,REFRESH_FOLDER_EVENT}=goog.require("grrUi.client.virtualFileSystem.events");const {ServerErrorButtonDirective}=goog.require("grrUi.core.serverErrorButtonDirective");const {ensurePathIsFolder,getFolderFromPath}=goog.require("grrUi.client.virtualFileSystem.utils");var ERROR_EVENT_NAME=ServerErrorButtonDirective.error_event_name;
var OPERATION_POLL_INTERVAL_MS=1E3;const FileTableController=function($rootScope,$scope,$interval,grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.interval_=$interval;this.grrApiService_=grrApiService;this.selectedFilePath_;this.fileListUrl;this.lastRefreshOperationId;this.filterEditedValue="";this.filterValue="";this.fileContext;this.triggerUpdate;this.viewMode="list";this.scope_.$watch("viewMode",newVal=>this.viewMode=newVal);this.scope_.$watch("controller.viewMode",newVal=>this.scope_["viewMode"]=
newVal);this.scope_.$on(REFRESH_FOLDER_EVENT,this.refreshFileList_.bind(this));this.scope_.$on(REFRESH_FILE_EVENT,this.refreshFileList_.bind(this));this.scope_.$watch("controller.fileContext.clientId",this.refreshFileList_.bind(this));this.scope_.$watch("controller.fileContext.selectedFilePath",this.onFilePathChange_.bind(this))};FileTableController.prototype.onFilePathChange_=function(newValue,oldValue){var newFolder=getFolderFromPath(newValue);var oldFolder=getFolderFromPath(oldValue);if(newFolder!==
oldFolder){this.refreshFileList_();this.lastRefreshOperationId=null}};FileTableController.prototype.refreshFileList_=function(){var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"]||"";var selectedFolderPath=getFolderFromPath(selectedFilePath);this.filter="";this.fileListUrl="clients/"+clientId+"/vfs-index/"+selectedFolderPath;if(this.triggerUpdate)this.triggerUpdate()};FileTableController.prototype.selectFile=function(file){this.fileContext.selectFile(file["value"]["path"]["value"],
0)};FileTableController.prototype.selectFolder=function(file){var clientId=this.fileContext["clientId"];var filePath=file["value"]["path"]["value"];filePath=ensurePathIsFolder(filePath);this.fileContext.selectFile(filePath,0);this.fileListUrl="clients/"+clientId+"/vfs-index/"+filePath};FileTableController.prototype.startVfsRefreshOperation=function(){var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"];var selectedFolderPath=getFolderFromPath(selectedFilePath);
var url="clients/"+clientId+"/vfs-refresh-operations";var refreshOperation={file_path:selectedFolderPath,max_depth:1,notify_user:false};var operationId=this.lastRefreshOperationId="unknown";this.grrApiService_.post(url,refreshOperation).then(function success(response){operationId=this.lastRefreshOperationId=response["data"]["operation_id"];var pollPromise=this.grrApiService_.poll(url+"/"+operationId,OPERATION_POLL_INTERVAL_MS);this.scope_.$on("$destroy",function(){this.grrApiService_.cancelPoll(pollPromise)}.bind(this));
return pollPromise}.bind(this)).then(function success(){this.rootScope_.$broadcast(REFRESH_FOLDER_EVENT,ensurePathIsFolder(selectedFolderPath))}.bind(this)).finally(function(){if(this.lastRefreshOperationId==operationId)this.lastRefreshOperationId=null}.bind(this))};FileTableController.prototype.updateFilter=function(){this.filterValue=this.filterEditedValue};FileTableController.prototype.downloadTimeline=function(format){var clientId=this.fileContext["clientId"];var selectedFilePath=this.fileContext["selectedFilePath"]||
"";var selectedFolderPath=getFolderFromPath(selectedFilePath);var url="clients/"+clientId+"/vfs-timeline-csv/"+selectedFolderPath;this.grrApiService_.downloadFile(url,{"format":format}).then(function success(){}.bind(this),function failure(response){if(angular.isUndefined(response.status))this.rootScope_.$broadcast(ERROR_EVENT_NAME,{message:"Couldn't export the timeline."})}.bind(this))};exports.FileTableDirective=function(){return{restrict:"E",scope:{viewMode:"="},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-table.html",
controller:FileTableController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};exports.FileTableDirective.directive_name="grrFileTable";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.fileTextViewDirective");goog.module.declareLegacyNamespace();const FileTextViewController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.fileContext;this.fileContent;this.encoding="UTF_8";this.page=1;this.pageCount=1;this.chunkSize_=1E4;this.scope_.$watchGroup(["controller.fileContext.clientId","controller.fileContext.selectedFilePath","controller.fileContext.selectedFileVersion"],
this.onContextChange_.bind(this));this.scope_.$watch("controller.encoding",this.onEncodingChange_.bind(this));this.scope_.$watch("controller.page",this.onPageChange_.bind(this))};FileTextViewController.prototype.onContextChange_=function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];if(angular.isDefined(clientId)&&angular.isDefined(filePath))this.fetchText_()};FileTextViewController.prototype.onPageChange_=function(page,oldPage){if(this.page!==oldPage)this.fetchText_()};
FileTextViewController.prototype.onEncodingChange_=function(encoding,oldEncoding){if(this.encoding!==oldEncoding)this.fetchText_()};FileTextViewController.prototype.fetchText_=function(){var clientId=this.fileContext["clientId"];var filePath=this.fileContext["selectedFilePath"];var fileVersion=this.fileContext["selectedFileVersion"];var offset=(this.page-1)*this.chunkSize_;var url="clients/"+clientId+"/vfs-text/"+filePath;var params={};params["encoding"]=this.encoding;params["offset"]=offset;params["length"]=
this.chunkSize_;if(fileVersion)params["timestamp"]=fileVersion;this.grrApiService_.get(url,params).then(function(response){this.fileContent=response.data["content"];var total_size=response.data["total_size"];this.pageCount=Math.ceil(total_size/this.chunkSize_)}.bind(this),function(){this.fileContent=null}.bind(this))};exports.FileTextViewDirective=function(){return{restrict:"E",scope:{},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-text-view.html",
controller:FileTextViewController,controllerAs:"controller",link:function(scope,element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};exports.FileTextViewDirective.directive_name="grrFileTextView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.fileTimelineDirective");goog.module.declareLegacyNamespace();const {REFRESH_FILE_EVENT,REFRESH_FOLDER_EVENT}=goog.require("grrUi.client.virtualFileSystem.events");const {getFolderFromPath}=goog.require("grrUi.client.virtualFileSystem.utils");const FileTimelineController=function($scope,$interval,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.fileContext;this.timelineItems;this.selectedItem;
this.inProgress;this.currentFolder;this.triggerUpdate;this.scope_.$on(REFRESH_FOLDER_EVENT,this.refreshTimeline_.bind(this));this.scope_.$on(REFRESH_FILE_EVENT,this.refreshTimeline_.bind(this));this.scope_.$watch("controller.fileContext.clientId",this.refreshTimeline_.bind(this));this.scope_.$watch("controller.fileContext.selectedFilePath",this.onFilePathChange_.bind(this))};FileTimelineController.prototype.onFilePathChange_=function(newFilePath){if(angular.isUndefined(newFilePath))return;var newFolder=
getFolderFromPath(newFilePath);if(newFilePath.endsWith("/")||angular.isUndefined(this.currentFolder)){this.currentFolder=newFolder;this.refreshTimeline_();return}var newFolderComponents=newFolder.split("/");var currentFolderComponents=this.currentFolder.split("/");for(var i=0;i<currentFolderComponents.length;++i)if(newFolderComponents[i]!=currentFolderComponents[i]){this.refreshTimeline_();this.currentFolder=newFolder}};FileTimelineController.prototype.refreshTimeline_=function(){var clientId=this.fileContext["clientId"];
var selectedFolderPath=getFolderFromPath(this.fileContext["selectedFilePath"]);if(angular.isUndefined(this.currentFolder))this.currentFolder=selectedFolderPath;this.inProgress=true;var url="clients/"+clientId+"/vfs-timeline/"+selectedFolderPath;this.grrApiService_.get(url).then(this.onTimelineFetched_.bind(this)).finally(function(){this.inProgress=false}.bind(this))};FileTimelineController.prototype.onTimelineFetched_=function(response){var selectedFilePath=this.fileContext["selectedFilePath"];var selectedFileVersion=
this.fileContext["selectedFileVersion"];this.timelineItems=response.data["items"];this.selectedItem=this.timelineItems.find(function(item){var v=item["value"];if(v["file_path"]["value"]===selectedFilePath)return!selectedFileVersion||v["timestamp"]["value"]===selectedFileVersion}.bind(this))||null;if(this.selectedItem&&!selectedFileVersion)this.fileContext["selectedFileVersion"]=this.selectedItem["value"]["timestamp"]["value"];if(this.triggerUpdate)this.triggerUpdate()};FileTimelineController.prototype.selectFile=
function(timelineItem){this.selectedItem=timelineItem;var clientId=this.fileContext["clientId"];var selectedFilePath=timelineItem["value"]["file_path"]["value"];var timestamp=timelineItem["value"]["timestamp"]["value"];var url="clients/"+clientId+"/vfs-version-times/"+selectedFilePath;this.grrApiService_.get(url).then(function success(response){var versions=response.data["times"];var fileVersion=Number.MAX_VALUE;angular.forEach(versions,function(version){if(version["value"]>=timestamp)fileVersion=
Math.min(fileVersion,version["value"])});if(fileVersion===Number.MAX_VALUE)if(versions.length)fileVersion=versions[0]["value"];else fileVersion=null;this.fileContext.selectFile(selectedFilePath,fileVersion)}.bind(this))};exports.FileTimelineDirective=function(){return{restrict:"E",scope:{filterValue:"=?"},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-timeline.html",controller:FileTimelineController,controllerAs:"controller",link:function(scope,element,
attrs,fileContextController){scope.controller.fileContext=fileContextController}}};exports.FileTimelineDirective.directive_name="grrFileTimeline";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.fileTreeDirective");goog.module.declareLegacyNamespace();const {REFRESH_FOLDER_EVENT}=goog.require("grrUi.client.virtualFileSystem.events");const {ensurePathIsFolder,getFolderFromPath}=goog.require("grrUi.client.virtualFileSystem.utils");const {getFileId}=goog.require("grrUi.client.virtualFileSystem.fileViewDirective");const FileTreeController=function($rootScope,$scope,$element,grrApiService,grrRoutingService){this.rootScope_=
$rootScope;this.scope_=$scope;this.element_=$element;this.treeElement_=$element.find("#file-tree");this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.fileContext;this.scope_.$on(REFRESH_FOLDER_EVENT,this.onRefreshFolderEvent_.bind(this));this.scope_.$watch("controller.fileContext.clientId",this.onClientIdChange_.bind(this));this.scope_.$watch("controller.fileContext.selectedFilePath",this.onSelectedFilePathChange_.bind(this))};FileTreeController.prototype.onClientIdChange_=
function(){if(angular.isDefined(this.fileContext["clientId"]))this.initTree_()};FileTreeController.prototype.initTree_=function(){var controller=this;this.treeElement_.jstree({"core":{"multiple":false,"data":function(node,cb){if(node.id==="#")controller.getChildFiles_("").then(cb);else controller.getChildFiles_(node.data.path).then(cb)}}});this.treeElement_.on("changed.jstree",function(e,data){if(data["action"]!=="select_node")return;var selectionId=data.selected[0];var node=this.treeElement_.jstree("get_node",
selectionId);var folderPath=node.data.path;if(getFolderFromPath(this.fileContext["selectedFilePath"])===folderPath)this.rootScope_.$broadcast(REFRESH_FOLDER_EVENT,ensurePathIsFolder(folderPath));else this.fileContext.selectFile(ensurePathIsFolder(folderPath));var treeInstance=data["instance"];treeInstance["refresh_node"](data.node)}.bind(this));this.treeElement_.on("close_node.jstree",function(e,data){data.node["data"]["refreshOnOpen"]=true}.bind(this));this.treeElement_.on("open_node.jstree",function(e,
data){if(data.node["data"]["refreshOnOpen"]){data.node["data"]["refreshOnOpen"]=false;var treeInstance=data["instance"];treeInstance["refresh_node"](data.node)}}.bind(this));this.treeElement_.on("loaded.jstree",function(){var selectedFilePath=this.fileContext["selectedFilePath"];if(selectedFilePath)this.expandToFilePath_(getFileId(getFolderFromPath(selectedFilePath)),true)}.bind(this));this.treeElement_.on("select_node.jstree",function(event,data){$(this)["jstree"]("open_node","#"+data.node.id);return true})};
FileTreeController.prototype.getChildFiles_=function(folderPath){var clientId_=this.fileContext["clientId"];var url="clients/"+clientId_+"/vfs-index/"+folderPath;var params={directories_only:1};return this.grrApiService_.get(url,params).then(this.parseFileResponse_.bind(this))};FileTreeController.prototype.parseFileResponse_=function(response){var files=response.data["items"];var result=[];angular.forEach(files,function(file){var filePath=file["value"]["path"]["value"];var fileId=getFileId(filePath);
result.push({id:fileId,text:file["value"]["name"]["value"],data:{path:filePath},children:true})}.bind(this));return result};FileTreeController.prototype.onRefreshFolderEvent_=function(e,path){if(angular.isUndefined(path))path=this.fileContext["selectedFilePath"];var nodeId=getFileId(getFolderFromPath(path));var node=$("#"+nodeId);this.treeElement_.jstree(true)["refresh_node"](node)};FileTreeController.prototype.onSelectedFilePathChange_=function(){var selectedFilePath=this.fileContext["selectedFilePath"];
if(selectedFilePath){var selectedFolderPath=getFolderFromPath(selectedFilePath);this.expandToFilePath_(getFileId(selectedFolderPath),true)}};FileTreeController.prototype.expandToFilePath_=function(filePathId,opt_suppressEvent){if(!filePathId)return;var element=this.treeElement_;var parts=filePathId.split("-");var cb=function(i,prev_node){var id_to_open=parts.slice(0,i+1).join("-");var node=$("#"+id_to_open);if(node.length)if(parts[i+1])element.jstree("open_node",node,function(){cb(i+1,node)},"no_hash");
else{element.jstree(true)["deselect_all"](true);element.jstree(true)["select_node"](node,opt_suppressEvent)}else if(prev_node){element.jstree(true)["deselect_all"](true);element.jstree(true)["select_node"](prev_node,opt_suppressEvent)}}.bind(this);cb(0,null)};exports.FileTreeDirective=function(){return{restrict:"E",scope:{},require:"^grrFileContext",templateUrl:"/static/angular-components/client/virtual-file-system/file-tree.html",controller:FileTreeController,controllerAs:"controller",link:function(scope,
element,attrs,fileContextController){scope.controller.fileContext=fileContextController}}};exports.FileTreeDirective.directive_name="grrFileTree";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.rWeOwnedButtonDirective");goog.module.declareLegacyNamespace();var phrases=["It is certain","You were eaten by a Grue!","\u4e2d\u56fd got you!!","All your bases are belong to us!","Maybe it was the Russians?","It is decidedly so","Without a doubt","Yes - definitely","You may rely on it","As I see it, yes","Most likely","Outlook good","Signs point to yes","Yes","Reply hazy, try again","Ask again later","Better not tell you now",
"Cannot predict now","Concentrate and ask again","Don't count on it","My reply is no","My sources say no","Outlook not so good","Very doubtful"];const RWeOwnedButtonController=function($scope,$uibModal){this.scope_=$scope;this.uibModal_=$uibModal;this.phrase};RWeOwnedButtonController.prototype.onClick=function(){var randomIndex=Math.floor(Math.random()*phrases.length);this.scope_.phrase=phrases[randomIndex];this.uibModal_.open({templateUrl:"/static/angular-components/client/virtual-file-system/"+
"r-we-owned-button-modal.html",scope:this.scope_})};exports.RWeOwnedButtonDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/client/virtual-file-system/r-we-owned-button.html",controller:RWeOwnedButtonController,controllerAs:"controller"}};exports.RWeOwnedButtonDirective.directive_name="grrRWeOwnedButton";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.recursiveListButtonDirective");goog.module.declareLegacyNamespace();const {REFRESH_FOLDER_EVENT}=goog.require("grrUi.client.virtualFileSystem.events");const {ensurePathIsFolder,getFolderFromPath}=goog.require("grrUi.client.virtualFileSystem.utils");var OPERATION_POLL_INTERVAL_MS=1E3;const RecursiveListButtonController=function($rootScope,$scope,$timeout,$uibModal,grrApiService,grrReflectionService){this.rootScope_=
$rootScope;this.scope_=$scope;this.timeout_=$timeout;this.uibModal_=$uibModal;this.grrApiService_=grrApiService;this.grrReflectionService_=grrReflectionService;this.lastOperationId;this.refreshOperation;this.done;this.error;this.modalInstance;this.scope_.$watchGroup(["clientId","filePath"],this.onClientOrPathChange_.bind(this))};RecursiveListButtonController.MAX_DEPTH=5;RecursiveListButtonController.prototype.onClientOrPathChange_=function(){this.lastOperationId=null};RecursiveListButtonController.prototype.onClick=
function(){this.isDisabled=true;this.done=false;this.error=null;this.grrReflectionService_.getRDFValueDescriptor("ApiCreateVfsRefreshOperationArgs",true).then(function(descriptors){this.refreshOperation=angular.copy(descriptors["ApiCreateVfsRefreshOperationArgs"]["default"]);var filePath=angular.copy(descriptors["RDFString"]["default"]);filePath["value"]=getFolderFromPath(this.scope_["filePath"]);this.refreshOperation["value"]["file_path"]=filePath;var maxDepth=angular.copy(descriptors["RDFInteger"]["default"]);
maxDepth["value"]=RecursiveListButtonController.MAX_DEPTH;this.refreshOperation["value"]["max_depth"]=maxDepth;this.refreshOperation["value"]["notify_user"]=true;this.modalInstance=this.uibModal_.open({templateUrl:"/static/angular-components/client/virtual-file-system/"+"recursive-list-button-modal.html",scope:this.scope_})}.bind(this))};RecursiveListButtonController.prototype.createRefreshOperation=function(){var aff4Prefix="aff4:/";var clientId=this.scope_["clientId"];if(clientId.toLowerCase().indexOf(aff4Prefix)==
0)clientId=clientId.substr(aff4Prefix.length);var url="clients/"+clientId+"/vfs-refresh-operations";var refreshOperation=angular.copy(this.refreshOperation);var operationId=this.lastOperationId="unknown";this.grrApiService_.post(url,refreshOperation,true).then(function success(response){this.done=true;this.timeout_(function(){this.modalInstance.close()}.bind(this),1E3);operationId=this.lastOperationId=response["data"]["operation_id"];var pollPromise=this.grrApiService_.poll(url+"/"+operationId,OPERATION_POLL_INTERVAL_MS);
this.scope_.$on("$destroy",function(){this.grrApiService_.cancelPoll(pollPromise)}.bind(this));return pollPromise}.bind(this),function failure(response){this.done=true;this.error=response["data"]["message"]||"Unknown error."}.bind(this)).then(function success(){var path=refreshOperation["value"]["file_path"]["value"];this.rootScope_.$broadcast(REFRESH_FOLDER_EVENT,ensurePathIsFolder(path))}.bind(this)).finally(function(){if(this.lastOperationId==operationId)this.lastOperationId=null}.bind(this))};
exports.RecursiveListButtonDirective=function(){return{scope:{clientId:"=",filePath:"="},restrict:"E",templateUrl:"/static/angular-components/client/virtual-file-system/"+"recursive-list-button.html",controller:RecursiveListButtonController,controllerAs:"controller"}};exports.RecursiveListButtonDirective.directive_name="grrRecursiveListButton";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective");goog.module.declareLegacyNamespace();const {ServerErrorButtonDirective}=goog.require("grrUi.core.serverErrorButtonDirective");const {getFolderFromPath}=goog.require("grrUi.client.virtualFileSystem.utils");var ERROR_EVENT_NAME=ServerErrorButtonDirective.error_event_name;exports.DOWNLOAD_EVERYTHING_REENABLE_DELAY=3E4;var DOWNLOAD_EVERYTHING_REENABLE_DELAY=exports.DOWNLOAD_EVERYTHING_REENABLE_DELAY;
const VfsFilesArchiveButtonController=function($rootScope,$scope,$timeout,grrApiService){this.rootScope_=$rootScope;this.scope_=$scope;this.timeout_=$timeout;this.grrApiService_=grrApiService;this.downloadEverythingDisabled=false;this.downloadCurrentFolderDisabled=false;this.scope_.$watch("clientId",function(){this.downloadEverythingDisabled=false}.bind(this));this.scope_.$watch("filePath",function(value){this.downloadCurrentFolderDisabled=false}.bind(this))};VfsFilesArchiveButtonController.prototype._download=
function(path){var clientId=this.scope_["clientId"];var url="clients/"+clientId+"/vfs-files-archive/"+path;this.grrApiService_.downloadFile(url).then(function success(){}.bind(this),function failure(response){if(angular.isUndefined(response.status))this.rootScope_.$broadcast(ERROR_EVENT_NAME,{message:"Couldn't download the VFS archive."})}.bind(this))};VfsFilesArchiveButtonController.prototype.downloadCurrentFolder=function(e){e.preventDefault();if(!this.downloadCurrentFolderDisabled){var folderPath=
getFolderFromPath(this.scope_["filePath"]);this._download(folderPath);this.downloadCurrentFolderDisabled=true}};VfsFilesArchiveButtonController.prototype.downloadEverything=function(e){e.preventDefault();if(!this.downloadEverythingDisabled){this._download("");this.downloadEverythingDisabled=true;this.timeout_(function(){this.downloadEverythingDisabled=false}.bind(this),DOWNLOAD_EVERYTHING_REENABLE_DELAY)}};exports.VfsFilesArchiveButtonDirective=function(){return{scope:{clientId:"=",filePath:"="},
restrict:"E",templateUrl:"/static/angular-components/client/virtual-file-system/"+"vfs-files-archive-button.html",controller:VfsFilesArchiveButtonController,controllerAs:"controller"}};exports.VfsFilesArchiveButtonDirective.directive_name="grrVfsFilesArchiveButton";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.virtualFileSystem.virtualFileSystem");goog.module.declareLegacyNamespace();const {BreadcrumbsDirective}=goog.require("grrUi.client.virtualFileSystem.breadcrumbsDirective");const {EncodingsDropdownDirective}=goog.require("grrUi.client.virtualFileSystem.encodingsDropdownDirective");const {FileContextDirective}=goog.require("grrUi.client.virtualFileSystem.fileContextDirective");const {FileDetailsDirective}=goog.require("grrUi.client.virtualFileSystem.fileDetailsDirective");
const {FileDownloadViewDirective}=goog.require("grrUi.client.virtualFileSystem.fileDownloadViewDirective");const {FileHexViewDirective}=goog.require("grrUi.client.virtualFileSystem.fileHexViewDirective");const {FileStatsViewDirective}=goog.require("grrUi.client.virtualFileSystem.fileStatsViewDirective");const {FileTableDirective}=goog.require("grrUi.client.virtualFileSystem.fileTableDirective");const {FileTextViewDirective}=goog.require("grrUi.client.virtualFileSystem.fileTextViewDirective");const {FileTimelineDirective}=
goog.require("grrUi.client.virtualFileSystem.fileTimelineDirective");const {FileTreeDirective}=goog.require("grrUi.client.virtualFileSystem.fileTreeDirective");const {FileViewDirective}=goog.require("grrUi.client.virtualFileSystem.fileViewDirective");const {RWeOwnedButtonDirective}=goog.require("grrUi.client.virtualFileSystem.rWeOwnedButtonDirective");const {RecursiveListButtonDirective}=goog.require("grrUi.client.virtualFileSystem.recursiveListButtonDirective");const {VfsFilesArchiveButtonDirective}=
goog.require("grrUi.client.virtualFileSystem.vfsFilesArchiveButtonDirective");const {coreModule}=goog.require("grrUi.core.core");const {semanticModule}=goog.require("grrUi.semantic.semantic");exports.virtualFileSystemModule=angular.module("grrUi.client.virtualFileSystem",[coreModule.name,semanticModule.name]);exports.virtualFileSystemModule.directive(BreadcrumbsDirective.directive_name,BreadcrumbsDirective);exports.virtualFileSystemModule.directive(EncodingsDropdownDirective.directive_name,EncodingsDropdownDirective);
exports.virtualFileSystemModule.directive(FileContextDirective.directive_name,FileContextDirective);exports.virtualFileSystemModule.directive(FileDetailsDirective.directive_name,FileDetailsDirective);exports.virtualFileSystemModule.directive(FileDownloadViewDirective.directive_name,FileDownloadViewDirective);exports.virtualFileSystemModule.directive(FileHexViewDirective.directive_name,FileHexViewDirective);exports.virtualFileSystemModule.directive(FileStatsViewDirective.directive_name,FileStatsViewDirective);
exports.virtualFileSystemModule.directive(FileTableDirective.directive_name,FileTableDirective);exports.virtualFileSystemModule.directive(FileTimelineDirective.directive_name,FileTimelineDirective);exports.virtualFileSystemModule.directive(FileTextViewDirective.directive_name,FileTextViewDirective);exports.virtualFileSystemModule.directive(FileTreeDirective.directive_name,FileTreeDirective);exports.virtualFileSystemModule.directive(FileViewDirective.directive_name,FileViewDirective);exports.virtualFileSystemModule.directive(RecursiveListButtonDirective.directive_name,
RecursiveListButtonDirective);exports.virtualFileSystemModule.directive(VfsFilesArchiveButtonDirective.directive_name,VfsFilesArchiveButtonDirective);exports.virtualFileSystemModule.directive(RWeOwnedButtonDirective.directive_name,RWeOwnedButtonDirective);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.client.client");goog.module.declareLegacyNamespace();const {AddClientsLabelsDialogDirective}=goog.require("grrUi.client.addClientsLabelsDialogDirective");const {CheckClientAccessDirective}=goog.require("grrUi.client.checkClientAccessDirective");const {ClientContextDirective}=goog.require("grrUi.client.clientContextDirective");const {ClientCrashesDirective}=goog.require("grrUi.client.clientCrashesDirective");const {ClientDialogService}=
goog.require("grrUi.client.clientDialogService");const {ClientLoadGraphSerieDirective}=goog.require("grrUi.client.clientLoadGraphSerieDirective");const {ClientLoadViewDirective}=goog.require("grrUi.client.clientLoadViewDirective");const {ClientStatusIconsDirective}=goog.require("grrUi.client.clientStatusIconsDirective");const {ClientUsernamesDirective}=goog.require("grrUi.client.clientUsernamesDirective");const {ClientsListDirective}=goog.require("grrUi.client.clientsListDirective");const {DebugRequestsViewDirective}=
goog.require("grrUi.client.debugRequestsViewDirective");const {HostHistoryDialogDirective}=goog.require("grrUi.client.hostHistoryDialogDirective");const {HostInfoDirective}=goog.require("grrUi.client.hostInfoDirective");const {RemoveClientsLabelsDialogDirective}=goog.require("grrUi.client.removeClientsLabelsDialogDirective");const {coreModule}=goog.require("grrUi.core.core");const {semanticModule}=goog.require("grrUi.semantic.semantic");const {statsModule}=goog.require("grrUi.stats.stats");const {virtualFileSystemModule}=
goog.require("grrUi.client.virtualFileSystem.virtualFileSystem");exports.clientModule=angular.module("grrUi.client",[virtualFileSystemModule.name,coreModule.name,semanticModule.name,statsModule.name]);exports.clientModule.directive(AddClientsLabelsDialogDirective.directive_name,AddClientsLabelsDialogDirective);exports.clientModule.directive(CheckClientAccessDirective.directive_name,CheckClientAccessDirective);exports.clientModule.directive(ClientContextDirective.directive_name,ClientContextDirective);
exports.clientModule.directive(ClientCrashesDirective.directive_name,ClientCrashesDirective);exports.clientModule.directive(ClientsListDirective.directive_name,ClientsListDirective);exports.clientModule.directive(ClientLoadGraphSerieDirective.directive_name,ClientLoadGraphSerieDirective);exports.clientModule.directive(ClientLoadViewDirective.directive_name,ClientLoadViewDirective);exports.clientModule.directive(ClientStatusIconsDirective.directive_name,ClientStatusIconsDirective);exports.clientModule.directive(ClientUsernamesDirective.directive_name,
ClientUsernamesDirective);exports.clientModule.directive(DebugRequestsViewDirective.directive_name,DebugRequestsViewDirective);exports.clientModule.directive(HostHistoryDialogDirective.directive_name,HostHistoryDialogDirective);exports.clientModule.directive(HostInfoDirective.directive_name,HostInfoDirective);exports.clientModule.directive(RemoveClientsLabelsDialogDirective.directive_name,RemoveClientsLabelsDialogDirective);exports.clientModule.service(ClientDialogService.service_name,ClientDialogService);
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.config.binariesListDirective");goog.module.declareLegacyNamespace();exports.sortBinaries=function(binaries){return binaries.map(function(b){var newB=angular.copy(b);var pathComponents=newB["value"]["path"]["value"].split("/");newB["pathLen"]=pathComponents.length;newB["baseName"]=pathComponents.pop();newB["dirName"]=pathComponents.join("/");return newB}).sort(function(a,b){if(a["pathLen"]!==b["pathLen"])return b["pathLen"]-a["pathLen"];
return a["value"]["path"]["value"].localeCompare(b["value"]["path"]["value"])})};var sortBinaries=exports.sortBinaries;const BinariesListController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.binaries;this.scope_.$watchGroup(["binaries","binaryType"],this.onBinariesChange_.bind(this))};BinariesListController.prototype.onBinariesChange_=function(){this.binaries=[];if(angular.isDefined(this.scope_["binaries"])){var filteredBinaries=this.scope_["binaries"].filter(function(b){return b["value"]["type"]["value"]===
this.scope_["typeFilter"]}.bind(this));this.binaries=sortBinaries(filteredBinaries)}};BinariesListController.prototype.onBinaryClicked=function(binary){var url="/config/binaries-blobs/"+binary["value"]["type"]["value"]+"/"+binary["value"]["path"]["value"];this.grrApiService_.downloadFile(url)};exports.BinariesListDirective=function(){return{restrict:"E",scope:{binaries:"=",typeFilter:"@"},templateUrl:"/static/angular-components/config/binaries-list.html",controller:BinariesListController,controllerAs:"controller"}};
exports.BinariesListDirective.directive_name="grrBinariesList";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.config.configBinariesViewDirective");goog.module.declareLegacyNamespace();const ConfigBinariesViewController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.binaries;this.grrApiService_.get("/config/binaries").then(function(response){this.binaries=response["data"]["items"]}.bind(this))};exports.ConfigBinariesViewDirective=function(){return{restrict:"E",scope:{},templateUrl:"/static/angular-components/config/config-binaries-view.html",
controller:ConfigBinariesViewController,controllerAs:"controller"}};exports.ConfigBinariesViewDirective.directive_name="grrConfigBinariesView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.config.configViewDirective");goog.module.declareLegacyNamespace();const ConfigViewController=function($scope,$http){$http.get("/api/config").then(function(config){this.items={};angular.forEach(config["data"]["sections"],function(section){var sectionName=section["value"]["name"]["value"];var sectionOptions=section["value"]["options"];this.items[sectionName]={};angular.forEach(sectionOptions,function(option){this.items[sectionName][option["value"]["name"]["value"]]=
option}.bind(this))}.bind(this))}.bind(this))};exports.ConfigViewDirective=function(){return{restrict:"E",scope:{},templateUrl:"/static/angular-components/config/config-view.html",controller:ConfigViewController,controllerAs:"controller"}};exports.ConfigViewDirective.directive_name="grrConfigView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.config.config");goog.module.declareLegacyNamespace();const {BinariesListDirective}=goog.require("grrUi.config.binariesListDirective");const {ConfigBinariesViewDirective}=goog.require("grrUi.config.configBinariesViewDirective");const {ConfigViewDirective}=goog.require("grrUi.config.configViewDirective");const {coreModule}=goog.require("grrUi.core.core");exports.configModule=angular.module("grrUi.config",[coreModule.name]);exports.configModule.directive(BinariesListDirective.directive_name,
BinariesListDirective);exports.configModule.directive(ConfigBinariesViewDirective.directive_name,ConfigBinariesViewDirective);exports.configModule.directive(ConfigViewDirective.directive_name,ConfigViewDirective);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.cronJobInspectorDirective");goog.module.declareLegacyNamespace();exports.CronJobInspectorDirective=function(){return{scope:{cronJobId:"="},restrict:"E",templateUrl:"/static/angular-components/cron/cron-job-inspector.html"}};exports.CronJobInspectorDirective.directive_name="grrCronJobInspector";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.cronJobOverviewDirective");goog.module.declareLegacyNamespace();const CronJobOverviewController=function($scope,grrApiService){this.scope_=$scope;this.scope_.cronJobId;this.grrApiService_=grrApiService;this.cronJob;this.cronJobId;this.scope_.$watch("cronJobId",this.onCronJobIdChange.bind(this))};CronJobOverviewController.prototype.onCronJobIdChange=function(newCronJobId){this.cronJob=null;if(angular.isDefined(newCronJobId)){this.cronJobId=
newCronJobId;this.grrApiService_.get("cron-jobs/"+this.cronJobId).then(this.onCronJobFetched.bind(this))}};CronJobOverviewController.prototype.onCronJobFetched=function(response){this.cronJob=response.data};exports.CronJobOverviewDirective=function(){return{scope:{cronJobId:"="},restrict:"E",templateUrl:"/static/angular-components/cron/cron-job-overview.html",controller:CronJobOverviewController,controllerAs:"controller"}};exports.CronJobOverviewDirective.directive_name="grrCronJobOverview";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.cronJobRunsListDirective");goog.module.declareLegacyNamespace();const CronJobRunsListController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.runsUrl;this.cronJobId;this.selectedRun;this.scope_.$watch("cronJobId",this.onCronJobIdChange_.bind(this))};CronJobRunsListController.prototype.onCronJobIdChange_=function(cronJobId){if(angular.isString(cronJobId)){var components=cronJobId.split("/");
this.cronJobId=components[components.length-1];this.runsUrl="/cron-jobs/"+this.cronJobId+"/runs"}};CronJobRunsListController.prototype.closeDetails=function(){this.selectedRun=null};exports.CronJobRunsListDirective=function(){return{scope:{cronJobId:"=",selectedRunId:"=?"},restrict:"E",templateUrl:"/static/angular-components/cron/cron-job-runs-list.html",controller:CronJobRunsListController,controllerAs:"controller"}};exports.CronJobRunsListDirective.directive_name="grrCronJobRunsList";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.cronJobStatusIconDirective");goog.module.declareLegacyNamespace();exports.CronJobStatusIconDirective=function(){return{scope:{cronJob:"="},restrict:"E",templateUrl:"/static/angular-components/cron/cron-job-status-icon.html"}};exports.CronJobStatusIconDirective.directive_name="grrCronJobStatusIcon";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.cronJobsListDirective");goog.module.declareLegacyNamespace();const {stripAff4Prefix}=goog.require("grrUi.core.utils");const CronJobsListController=function($scope,$uibModal,$q,grrTimeService,grrApiService,grrDialogService,grrAclDialogService){this.scope_=$scope;this.uibModal_=$uibModal;this.q_=$q;this.timeService_=grrTimeService;this.grrApiService_=grrApiService;this.grrDialogService_=grrDialogService;this.grrAclDialogService_=
grrAclDialogService;this.cronJobsById={};this.selectedCronJobId;this.triggerUpdate;this.ooCronHuntsEnabled;this.scope_.$watch("controller.selectedCronJobId",function(newValue){if(angular.isDefined(newValue))this.scope_["selectedCronJobId"]=newValue}.bind(this));this.scope_.$watch("selectedCronJobId",function(newValue){if(angular.isDefined(newValue))this.selectedCronJobId=newValue}.bind(this))};CronJobsListController.prototype.cronUrl="/cron-jobs";CronJobsListController.prototype.wrapApiPromise_=function(promise,
successMessage){return promise.then(function success(){return successMessage}.bind(this),function failure(response){var message=response["data"]["message"];if(response["status"]===403){var subject=response["data"]["subject"];var cronJobId=stripAff4Prefix(subject).split("/")[1];this.grrAclDialogService_.openRequestCronJobApprovalDialog(cronJobId,message)}return this.q_.reject(message)}.bind(this))};CronJobsListController.prototype.buildCronJobUrl_=function(cronJobId){return"cron-jobs/"+cronJobId};
CronJobsListController.prototype.selectItem=function(item){this.selectedCronJobId=item["value"]["cron_job_id"]["value"]};CronJobsListController.prototype.transformItems=function(items){items=angular.copy(items);angular.forEach(items,function(item,index){var cronJobId=item["value"]["cron_job_id"]["value"];this.cronJobsById[cronJobId]=item;var frequency=item["value"]["frequency"]["value"];var currentTime=this.timeService_.getCurrentTimeMs()/1E3;var last_run_time;if(angular.isDefined(item["value"]["last_run_time"]))last_run_time=
item["value"]["last_run_time"]["value"]/1E3;else last_run_time=0;item.isStuck=currentTime-last_run_time>frequency*2}.bind(this));return items};CronJobsListController.prototype.newCronJob=function(){var modalScope=this.scope_.$new();modalScope.resolve=function(){modalInstance.close()};modalScope.reject=function(){modalInstance.dismiss()};this.scope_.$on("$destroy",function(){modalScope.$destroy()});modalScope.result={};var modalInstance=this.uibModal_.open({template:'<grr-new-cron-job-wizard-form on-resolve="resolve()" '+
'on-reject="reject()" cron-job="result.cronJob" />',scope:modalScope,windowClass:"wide-modal high-modal",size:"lg"});modalInstance.result.then(function resolve(){this.triggerUpdate();this.selectedCronJobId=modalScope["result"]["cronJob"]["value"]["cron_job_id"]["value"]}.bind(this))};CronJobsListController.prototype.enableCronJob=function(){var modalPromise=this.grrDialogService_.openConfirmation("Enable this cron job?","Are you sure you want to ENABLE this cron job?",function(){var promise=this.grrApiService_.patch(this.buildCronJobUrl_(this.selectedCronJobId),
{enabled:true});return this.wrapApiPromise_(promise,"Cron job was ENABLED successfully!")}.bind(this));modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};CronJobsListController.prototype.disableCronJob=function(){var modalPromise=this.grrDialogService_.openConfirmation("Disable this cron job?","Are you sure you want to DISABLE this cron job?",function(){var promise=this.grrApiService_.patch(this.buildCronJobUrl_(this.selectedCronJobId),
{enabled:false});return this.wrapApiPromise_(promise,"Cron job was DISABLED successfully!")}.bind(this));modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};CronJobsListController.prototype.showDeleteCronJobConfirmation=function(){var dialogResult=this.grrDialogService_.openConfirmation("Delete cron job","Are you sure you want to DELETE this cron job?",this.deleteCronJob_.bind(this));dialogResult.then(function resolve(){this.triggerUpdate()}.bind(this))};
CronJobsListController.prototype.deleteCronJob_=function(){var url=this.buildCronJobUrl_(this.selectedCronJobId);var promise=this.grrApiService_.delete(url);return this.wrapApiPromise_(promise,"Cron job was deleted successfully!")};CronJobsListController.prototype.forceRunCronJob=function(){var modalPromise=this.grrDialogService_.openConfirmation("Force-run this cron job?","Are you sure you want to FORCE-RUN this cron job?",function(){var promise=this.grrApiService_.post(this.buildCronJobUrl_(this.selectedCronJobId)+
"/actions/force-run");return this.wrapApiPromise_(promise,"Cron job flow was FORCE-STARTED successfully!")}.bind(this));modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};exports.CronJobsListDirective=function(){return{scope:{selectedCronJobId:"=?"},restrict:"E",templateUrl:"/static/angular-components/cron/cron-jobs-list.html",controller:CronJobsListController,controllerAs:"controller"}};exports.CronJobsListDirective.directive_name=
"grrCronJobsList";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.cronViewDirective");goog.module.declareLegacyNamespace();const CronViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.selectedCronJobId;this.scope_.$watch("controller.selectedCronJobId",this.onSelectedCronJobIdChange_.bind(this));this.grrRoutingService_.uiOnParamsChanged(this.scope_,"cronJobId",this.onParamsChange_.bind(this))};CronViewController.prototype.onParamsChange_=
function(cronJobId){if(cronJobId)this.selectedCronJobId=cronJobId};CronViewController.prototype.onSelectedCronJobIdChange_=function(newValue){if(angular.isDefined(newValue))this.grrRoutingService_.go("crons",{cronJobId:newValue})};exports.CronViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/cron/cron-view.html",controller:CronViewController,controllerAs:"controller"}};exports.CronViewDirective.directive_name="grrCronView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.newCronJobWizard.configureSchedulePageDirective");goog.module.declareLegacyNamespace();exports.ConfigureSchedulePageDirective=function(){return{scope:{cronJobArgs:"="},restrict:"E",templateUrl:"/static/angular-components/cron/new-cron-job-wizard/"+"configure-schedule-page.html",controllerAs:"controller"}};exports.ConfigureSchedulePageDirective.directive_name="grrConfigureSchedulePage";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.newHuntWizard.formDirective");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const {ReflectionService}=goog.require("grrUi.core.reflectionService");exports.DEFAULT_PLUGIN_URL="/config/"+"AdminUI.new_hunt_wizard.default_output_plugin";var DEFAULT_PLUGIN_URL=exports.DEFAULT_PLUGIN_URL;const FormController=function($scope,grrReflectionService,grrApiService){this.scope_=
$scope;this.grrReflectionService_=grrReflectionService;this.grrApiService_=grrApiService;this.descriptors_={};this.defaultOutputPluginName;this.configureFlowPageHasErrors;this.grrApiService_.get(DEFAULT_PLUGIN_URL).then(function(response){if(angular.isDefined(response["data"]["value"]))this.defaultOutputPluginName=response["data"]["value"]["value"];return this.grrReflectionService_.getRDFValueDescriptor("ApiCreateHuntArgs",true)}.bind(this)).then(function(descriptors){angular.extend(this.descriptors_,
descriptors);this.scope_.$watch("createHuntArgs",this.onCreateHuntArgsChange_.bind(this))}.bind(this))};FormController.prototype.onCreateHuntArgsChange_=function(newValue){if(angular.isUndefined(newValue))newValue=this.scope_["createHuntArgs"]=angular.copy(this.descriptors_["ApiCreateHuntArgs"]["default"]);if(angular.isUndefined(newValue["value"]["flow_name"]))newValue["value"]["flow_name"]=angular.copy(this.descriptors_["RDFString"]["default"]);var hra=newValue["value"]["hunt_runner_args"];if(angular.isUndefined(hra))hra=
newValue["value"]["hunt_runner_args"]=angular.copy(this.descriptors_["HuntRunnerArgs"]["default"]);if(angular.isUndefined(hra["value"]["output_plugins"]))if(this.defaultOutputPluginName){var defaultPluginDescriptor=angular.copy(this.descriptors_["OutputPluginDescriptor"]["default"]);defaultPluginDescriptor["value"]["plugin_name"]=angular.copy(this.descriptors_["RDFString"]["default"]);defaultPluginDescriptor["value"]["plugin_name"]["value"]=this.defaultOutputPluginName;hra["value"]["output_plugins"]=
[defaultPluginDescriptor]}else if(angular.isUndefined(newValue["value"]["output_plugins"]))hra["value"]["output_plugins"]=[];if(angular.isUndefined(hra["value"]["client_rule_set"]))hra["value"]["client_rule_set"]=angular.copy(this.descriptors_["ForemanClientRuleSet"]["default"])};FormController.prototype.sendRequest=function(){this.grrApiService_.post("/hunts",stripTypeInfo(this.scope_["createHuntArgs"])).then(function resolve(response){this.serverResponse=response}.bind(this),function reject(response){this.serverResponse=
response;this.serverResponse["error"]=true}.bind(this))};FormController.prototype.resolve=function(){var onResolve=this.scope_["onResolve"];if(onResolve&&this.serverResponse){var huntId=this.serverResponse["data"]["value"]["hunt_id"]["value"];onResolve({huntId:huntId})}};exports.FormDirective=function(){return{scope:{createHuntArgs:"=?",onResolve:"&",onReject:"&"},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/form.html",controller:FormController,controllerAs:"controller"}};
exports.FormDirective.directive_name="grrNewHuntWizardForm";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.newCronJobWizard.formDirective");goog.module.declareLegacyNamespace();const {DEFAULT_PLUGIN_URL}=goog.require("grrUi.hunt.newHuntWizard.formDirective");const FormController=function($scope,grrReflectionService,grrApiService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.grrApiService_=grrApiService;this.descriptors_={};this.defaultOutputPluginName;this.grrApiService_.get(DEFAULT_PLUGIN_URL).then(function(response){if(angular.isDefined(response["data"]["value"]))this.defaultOutputPluginName=
response["data"]["value"]["value"];return this.grrReflectionService_.getRDFValueDescriptor("ApiCreateCronJobArgs",true)}.bind(this)).then(function(descriptors){angular.extend(this.descriptors_,descriptors);this.scope_.$watch("createCronJobArgs",this.onCronJobCreateArgsChange_.bind(this))}.bind(this));this.scope_.$watch("createCronJobArgs.value.hunt_runner_args",function(newValue){this.huntRunnerArgs=newValue}.bind(this));this.scope_.$watch("createCronJobArgs.value.description.value",this.onCronJobDescriptionChange_.bind(this))};
FormController.prototype.onCronJobDescriptionChange_=function(newValue,oldValue){if(newValue&&this.huntRunnerArgs){oldValue=oldValue||"";var huntDescription;if(angular.isDefined(this.huntRunnerArgs.value.description))huntDescription=this.huntRunnerArgs.value.description.value;var cronSuffix=" (cron)";if(angular.isUndefined(huntDescription)||huntDescription==oldValue+cronSuffix)this.huntRunnerArgs.value.description={type:"RDFString",value:newValue+cronSuffix}}};FormController.prototype.onCronJobCreateArgsChange_=
function(newValue){if(angular.isUndefined(newValue))newValue=this.scope_["createCronJobArgs"]=angular.copy(this.descriptors_["ApiCreateCronJobArgs"]["default"]);if(angular.isUndefined(newValue["value"]["periodicity"]))newValue["value"]["periodicity"]={type:"DurationSeconds",value:60*60*24*7};if(angular.isUndefined(newValue["value"]["lifetime"]))newValue["value"]["lifetime"]={type:"DurationSeconds",value:60*60*1};if(angular.isUndefined(newValue["value"]["flow_name"]))newValue["value"]["flow_name"]=
angular.copy(this.descriptors_["RDFString"]["default"]);if(angular.isUndefined(newValue["value"]["hunt_runner_args"]))newValue["value"]["hunt_runner_args"]=angular.copy(this.descriptors_["HuntRunnerArgs"]["default"]);var huntRunnerArgs=newValue["value"]["hunt_runner_args"]["value"];if(angular.isUndefined(huntRunnerArgs["client_rule_set"]))huntRunnerArgs["client_rule_set"]=angular.copy(this.descriptors_["ForemanClientRuleSet"]["default"]);if(angular.isUndefined(huntRunnerArgs["output_plugins"]))if(this.defaultOutputPluginName){var defaultPluginDescriptor=
angular.copy(this.descriptors_["OutputPluginDescriptor"]["default"]);defaultPluginDescriptor["value"]["plugin_name"]=angular.copy(this.descriptors_["RDFString"]["default"]);defaultPluginDescriptor["value"]["plugin_name"]["value"]=this.defaultOutputPluginName;huntRunnerArgs["output_plugins"]=[defaultPluginDescriptor]}else huntRunnerArgs["output_plugins"]=[]};FormController.prototype.sendRequest=function(){this.grrApiService_.post("/cron-jobs",this.scope_["createCronJobArgs"],true).then(function resolve(response){this.serverResponse=
response;this.scope_["cronJob"]=response["data"]}.bind(this),function reject(response){this.serverResponse=response;this.serverResponse["error"]=true}.bind(this))};exports.FormDirective=function(){return{scope:{createCronJobArgs:"=?",cronJob:"=?",onResolve:"&",onReject:"&"},restrict:"E",templateUrl:"/static/angular-components/cron/new-cron-job-wizard/"+"form.html",controller:FormController,controllerAs:"controller"}};exports.FormDirective.directive_name="grrNewCronJobWizardForm";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.newCronJobWizard.reviewPageDirective");goog.module.declareLegacyNamespace();exports.ReviewPageDirective=function(){return{scope:{cronJobArgs:"="},restrict:"E",templateUrl:"/static/angular-components/cron/new-cron-job-wizard/"+"review-page.html",controllerAs:"controller"}};exports.ReviewPageDirective.directive_name="grrNewCronJobReviewPage";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.newCronJobWizard.statusPageDirective");goog.module.declareLegacyNamespace();exports.StatusPageDirective=function(){return{scope:{response:"="},restrict:"E",templateUrl:"/static/angular-components/cron/new-cron-job-wizard/"+"status-page.html"}};exports.StatusPageDirective.directive_name="grrNewCronJobStatusPage";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.newCronJobWizard.newCronJobWizard");goog.module.declareLegacyNamespace();const {ConfigureSchedulePageDirective}=goog.require("grrUi.cron.newCronJobWizard.configureSchedulePageDirective");const {FormDirective}=goog.require("grrUi.cron.newCronJobWizard.formDirective");const {ReviewPageDirective}=goog.require("grrUi.cron.newCronJobWizard.reviewPageDirective");const {StatusPageDirective}=goog.require("grrUi.cron.newCronJobWizard.statusPageDirective");
const {coreModule}=goog.require("grrUi.core.core");exports.newCronJobWizardModule=angular.module("grrUi.cron.newCronJobWizard",["ui.bootstrap",coreModule.name]);exports.newCronJobWizardModule.directive(FormDirective.directive_name,FormDirective);exports.newCronJobWizardModule.directive(ReviewPageDirective.directive_name,ReviewPageDirective);exports.newCronJobWizardModule.directive(StatusPageDirective.directive_name,StatusPageDirective);exports.newCronJobWizardModule.directive(ConfigureSchedulePageDirective.directive_name,
ConfigureSchedulePageDirective);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.cron.cron");goog.module.declareLegacyNamespace();const {CronJobInspectorDirective}=goog.require("grrUi.cron.cronJobInspectorDirective");const {CronJobOverviewDirective}=goog.require("grrUi.cron.cronJobOverviewDirective");const {CronJobRunsListDirective}=goog.require("grrUi.cron.cronJobRunsListDirective");const {CronJobStatusIconDirective}=goog.require("grrUi.cron.cronJobStatusIconDirective");const {CronJobsListDirective}=goog.require("grrUi.cron.cronJobsListDirective");
const {CronViewDirective}=goog.require("grrUi.cron.cronViewDirective");const {coreModule}=goog.require("grrUi.core.core");const {newCronJobWizardModule}=goog.require("grrUi.cron.newCronJobWizard.newCronJobWizard");exports.cronModule=angular.module("grrUi.cron",[coreModule.name,newCronJobWizardModule.name]);exports.cronModule.directive(CronJobInspectorDirective.directive_name,CronJobInspectorDirective);exports.cronModule.directive(CronJobsListDirective.directive_name,CronJobsListDirective);exports.cronModule.directive(CronJobOverviewDirective.directive_name,
CronJobOverviewDirective);exports.cronModule.directive(CronJobRunsListDirective.directive_name,CronJobRunsListDirective);exports.cronModule.directive(CronJobStatusIconDirective.directive_name,CronJobStatusIconDirective);exports.cronModule.directive(CronViewDirective.directive_name,CronViewDirective);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.docs.apiDescriptionDirective");goog.module.declareLegacyNamespace();const ApiDescriptionController=function($scope){this.scope_=$scope;this.paragraphs=[];this.scope_.$watch("::value",this.onValueChange.bind(this))};ApiDescriptionController.prototype.onValueChange=function(newValue){if(angular.isString(newValue))this.paragraphs=newValue.split("\n\n")};exports.ApiDescriptionDirective=function(){return{scope:{value:"="},restrict:"E",templateUrl:"/static/angular-components/docs/api-description.html",
controller:ApiDescriptionController,controllerAs:"controller"}};exports.ApiDescriptionDirective.directive_name="grrApiDescription";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.docs.apiDocsDirective");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const ApiDocsController=function($element,$http,grrApiService){this.element_=$element;this.http_=$http;this.grrApiService_=grrApiService;this.apiMethodsByCategory;this.examplesByMethod;this.categories;this.visibleCategory;this.grrApiService_.get("reflection/api-methods").then(this.onApiMethodsListFetched_.bind(this));
this.http_.get("/static/angular-components/docs/api-docs-examples.json").then(this.onExamplesFetched_.bind(this))};ApiDocsController.prototype.onApiMethodsListFetched_=function(response){var categoriesDict={};var items=stripTypeInfo(response["data"]["items"]);angular.forEach(items,function(descriptor){var category=descriptor["category"];if(!category)category="Other";if(categoriesDict[category]===undefined)categoriesDict[category]=[];categoriesDict[category].push(descriptor)}.bind(this));angular.forEach(categoriesDict,
function(descriptors){descriptors.sort(function(a,b){var astr=a["name"]+"_"+a["http_route"];var bstr=b["name"]+"_"+b["http_route"];if(astr>bstr)return 1;else if(astr<bstr)return-1;else return 0})}.bind(this));this.apiMethodsByCategory=categoriesDict;this.categories=Object.keys(categoriesDict).sort();this.visibleCategory=this.categories[0]};ApiDocsController.prototype.onExamplesFetched_=function(response){this.examplesByMethod={};angular.forEach(response.data,function(handlerExamples){angular.forEach(handlerExamples,
function(example){var apiMethod=example["api_method"];if(!this.examplesByMethod[apiMethod])this.examplesByMethod[apiMethod]=[];this.examplesByMethod[apiMethod].push(example)}.bind(this))}.bind(this))};ApiDocsController.prototype.onCategoryLinkClick=function(category){var index=this.categories.indexOf(category);var headingElement=$("#docs-category-"+index.toString());var scrollableContainer=headingElement.parent();while(scrollableContainer.length!=0){if(scrollableContainer.scrollTop()>0||Math.abs(scrollableContainer[0].clientHeight-
scrollableContainer[0].scrollHeight)>1){var offset=headingElement.offset()["top"]-scrollableContainer.offset()["top"]+scrollableContainer.scrollTop();var prevOffset=scrollableContainer.scrollTop();scrollableContainer.scrollTop(offset);if(scrollableContainer.scrollTop()!=prevOffset||Math.abs(prevOffset-offset)<=1)break}scrollableContainer=scrollableContainer.parent()}};exports.ApiDocsDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/docs/api-docs.html",controller:ApiDocsController,
controllerAs:"controller"}};exports.ApiDocsDirective.directive_name="grrApiDocs";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.docs.apiHelperCurlService");goog.module.declareLegacyNamespace();exports.ApiHelperCurlService=function($q,$window){this.q_=$q;this.window_=$window};var ApiHelperCurlService=exports.ApiHelperCurlService;ApiHelperCurlService.service_name="grrApiHelperCurlService";ApiHelperCurlService.prototype.buildStartFlow=function(clientId,createFlowJson){var deferred=this.q_.defer();var result="CSRFTOKEN=`curl "+this.window_.location.origin+" -o /dev/null -s -c - | grep csrftoken  | cut -f 7`; \\\n\t"+
'curl -X POST -H "Content-Type: application/json" '+'-H "X-CSRFToken: $CSRFTOKEN" \\\n\t'+this.window_.location.origin+"/api/v2/clients/"+clientId+"/flows -d @- << EOF\n";result+=JSON.stringify(createFlowJson,null,2);result+="\nEOF";deferred.resolve(result);return deferred.promise};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.docs.apiHelperService");goog.module.declareLegacyNamespace();exports.ApiHelperService=function($q,grrApiService){this.q_=$q;this.grrApiService_=grrApiService;this.helperTuples_=[]};var ApiHelperService=exports.ApiHelperService;ApiHelperService.service_name="grrApiHelperService";ApiHelperService.prototype.clear=function(){this.helperTuples_=[]};ApiHelperService.prototype.registerHelper=function(type,webAuthType,helper){this.helperTuples_.push([type,
webAuthType,helper])};ApiHelperService.prototype.buildStartFlow_=function(webAuthType,clientId,createFlowJson){var helpersByType={};for(var i=0;i<this.helperTuples_.length;++i){var helperTuple=this.helperTuples_[i];var helperType=helperTuple[0];var helperWebAuthType=helperTuple[1];if(!helpersByType[helperType]&&!helperWebAuthType||helperWebAuthType==webAuthType)helpersByType[helperType]=helperTuple}var result={};var promises=[];angular.forEach(helpersByType,function(helperTuple,key){var helperWebAuthType=
helperTuple[1];var helper=helperTuple[2];var promise=helper["buildStartFlow"](clientId,createFlowJson).then(function(data){result[key]={webAuthType:helperWebAuthType,data:data}}.bind(this));promises.push(promise)}.bind(this));return this.q_.all(promises).then(function(){return result}.bind(this))};ApiHelperService.prototype.buildStartFlow=function(clientId,createFlowJson){return this.grrApiService_.getCached("/config/AdminUI.webauth_manager").then(function(response){var webAuthType=response["data"]["value"]["value"];
return this.buildStartFlow_(webAuthType,clientId,createFlowJson)}.bind(this))};return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.docs.apiQuerySpecDirective");goog.module.declareLegacyNamespace();const ApiQuerySpecController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.descriptorFields;this.descriptorsCache;this.typeHints={"RDFDatetime":"Time since epoch in microseconds.","RDFBool":"Either 1 or 0.","RDFURN":'Path string with components separated by "/", i.e. '+'"foo/bar/blah".'};this.scope_.$watch("argsType",
this.onArgsTypeChange.bind(this))};ApiQuerySpecController.prototype.onArgsTypeChange=function(newValue){this.argsDescriptor=null;if(angular.isString(newValue))this.grrReflectionService_.getRDFValueDescriptor(newValue,true).then(function(result){this.descriptorFields=[];angular.forEach(result[newValue]["fields"],function(field){if(field.name!=="additional_args")this.descriptorFields.push(field)}.bind(this));this.descriptorsCache=result}.bind(this))};exports.ApiQuerySpecDirective=function(){return{scope:{argsType:"=",
prefix:"=",noHeader:"@"},restrict:"E",templateUrl:"/static/angular-components/docs/api-query-spec.html",controller:ApiQuerySpecController,controllerAs:"controller"}};exports.ApiQuerySpecDirective.directive_name="grrApiQuerySpec";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.docs.apiRouteDirective");goog.module.declareLegacyNamespace();let RouteComponent;const ApiRouteController=function($scope){this.scope_=$scope;this.routeComponents;this.queryParameters;this.hasQueryParameters;this.scope_.$watch("::value",this.onValueChange.bind(this))};ApiRouteController.prototype.onValueChange=function(){var routeComponents=this.routeComponents=[];var queryParameters=this.queryParameters={};if(angular.isString(this.scope_.value)){var route=
this.scope_.value;var questionMarkIndex=route.indexOf("?");if(questionMarkIndex!=-1){var queryParamString=route.substring(questionMarkIndex+1,route.length);route=route.substring(0,questionMarkIndex);var vars=queryParamString.split("&");angular.forEach(vars,function(variable){var pair=variable.split("=");if(pair.length==2)queryParameters[pair[0]]=pair[1];else queryParameters[pair[0]]=null})}var components=route.split("/");angular.forEach(components,function(component){if(component.length>0)if(component[0]===
"<"){component=component.substring(1,component.length-1);var componentParts=component.split(":");var componentType,componentValue;if(componentParts.length===1){componentType="string";componentValue=componentParts[0]}else{componentType=componentParts[0];componentValue=componentParts[1]}routeComponents.push({type:componentType,value:componentValue})}else routeComponents.push({value:component})}.bind(this))}this.hasQueryParameters=Object.keys(queryParameters).length>0};exports.ApiRouteDirective=function(){return{scope:{value:"="},
restrict:"E",templateUrl:"/static/angular-components/docs/api-route.html",controller:ApiRouteController,controllerAs:"controller"}};exports.ApiRouteDirective.directive_name="grrApiRoute";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.docs.docs");goog.module.declareLegacyNamespace();const {ApiDescriptionDirective}=goog.require("grrUi.docs.apiDescriptionDirective");const {ApiDocsDirective}=goog.require("grrUi.docs.apiDocsDirective");const {ApiHelperCurlService}=goog.require("grrUi.docs.apiHelperCurlService");const {ApiHelperService}=goog.require("grrUi.docs.apiHelperService");const {ApiQuerySpecDirective}=goog.require("grrUi.docs.apiQuerySpecDirective");const {ApiRouteDirective}=
goog.require("grrUi.docs.apiRouteDirective");const {coreModule}=goog.require("grrUi.core.core");exports.docsModule=angular.module("grrUi.docs",[coreModule.name]);exports.docsModule.directive(ApiDescriptionDirective.directive_name,ApiDescriptionDirective);exports.docsModule.directive(ApiDocsDirective.directive_name,ApiDocsDirective);exports.docsModule.directive(ApiRouteDirective.directive_name,ApiRouteDirective);exports.docsModule.directive(ApiQuerySpecDirective.directive_name,ApiQuerySpecDirective);
exports.docsModule.service(ApiHelperService.service_name,ApiHelperService);exports.docsModule.service(ApiHelperCurlService.service_name,ApiHelperCurlService);exports.docsModule.run(function(grrApiHelperService,grrApiHelperCurlService){grrApiHelperService.registerHelper("HTTP",null,grrApiHelperCurlService)});return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.clientFlowsListDirective");goog.module.declareLegacyNamespace();const ClientFlowsListController=function($scope,$timeout,$uibModal,grrApiService,grrRoutingService){this.scope_=$scope;this.timeout_=$timeout;this.uibModal_=$uibModal;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.flowsUrl;this.triggerUpdate;this.scope_.$watch("clientId",this.onClientIdChange_.bind(this))};ClientFlowsListController.prototype.onClientIdChange_=
function(newValue){if(angular.isString(newValue)){var components=newValue.split("/");var basename=components[components.length-1];this.flowsUrl="/clients/"+basename+"/flows"}else this.flowsUrl=null};ClientFlowsListController.prototype.cancelButtonClicked=function(){var cancelUrl=[this.flowsUrl,this.scope_["selectedFlowId"],"actions/cancel"].join("/");this.grrApiService_.post(cancelUrl,{}).then(function(){this.triggerUpdate();var flowId=this.scope_["selectedFlowId"];this.scope_["selectedFlowId"]=undefined;
this.timeout_(function(){this.scope_["selectedFlowId"]=flowId}.bind(this),0)}.bind(this))};ClientFlowsListController.prototype.createHuntFromFlow=function(){var huntId;var modalScope=this.scope_.$new();modalScope["clientId"]=this.scope_["clientId"];modalScope["flowId"]=this.scope_["selectedFlowId"];modalScope["resolve"]=function(newHuntId){huntId=newHuntId;modalInstance.close()}.bind(this);modalScope["reject"]=function(){modalInstance.dismiss()}.bind(this);this.scope_.$on("$destroy",function(){modalScope.$destroy()});
var modalInstance=this.uibModal_.open({template:'<grr-new-hunt-wizard-create-from-flow-form on-resolve="resolve(huntId)" '+'on-reject="reject()" flow-id="flowId" client-id="clientId" />',scope:modalScope,windowClass:"wide-modal high-modal",size:"lg"});modalInstance.result.then(function resolve(){this.grrRoutingService_.go("hunts",{huntId:huntId})}.bind(this))};ClientFlowsListController.prototype.copyFlow=function(){var newFlowId;var modalScope=this.scope_.$new();modalScope["clientId"]=this.scope_["clientId"];
modalScope["flowId"]=this.scope_["selectedFlowId"];modalScope["resolve"]=function(newFlowObj){newFlowId=newFlowObj["value"]["flow_id"]["value"];modalInstance.close()}.bind(this);this.scope_.$on("$destroy",function(){modalScope.$destroy()});var modalInstance=this.uibModal_.open({template:'<grr-copy-flow-form on-resolve="resolve(flow)" '+'flow-id="flowId" client-id="clientId" />',scope:modalScope,windowClass:"wide-modal high-modal",size:"lg"});modalInstance.result.then(function resolve(){if(angular.isDefined(newFlowId)){this.grrRoutingService_.go("client.flows",
{flowId:newFlowId});this.triggerUpdate()}}.bind(this))};exports.ClientFlowsListDirective=function(){return{scope:{clientId:"=",selectedFlowId:"=?"},restrict:"E",templateUrl:"/static/angular-components/flow/client-flows-list.html",controller:ClientFlowsListController,controllerAs:"controller"}};exports.ClientFlowsListDirective.directive_name="grrClientFlowsList";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.clientFlowsViewDirective");goog.module.declareLegacyNamespace();const ClientFlowsViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.clientId;this.selectedFlowId;this.tab;this.flowApiBasePath;this.scope_.$watchGroup(["controller.selectedFlowId","controller.tab"],this.onSelectionOrTabChange_.bind(this));this.grrRoutingService_.uiOnParamsChanged(this.scope_,["clientId",
"flowId","tab"],this.onRoutingParamsChange_.bind(this))};ClientFlowsViewController.prototype.onRoutingParamsChange_=function(unused_newValues,opt_stateParams){this.clientId=opt_stateParams["clientId"];this.selectedFlowId=opt_stateParams["flowId"];this.tab=opt_stateParams["tab"];this.flowApiBasePath=["clients",this.clientId,"flows"].join("/")};ClientFlowsViewController.prototype.onSelectionOrTabChange_=function(){if(angular.isDefined(this.selectedFlowId))this.grrRoutingService_.go("client.flows",{flowId:this.selectedFlowId,
tab:this.tab})};exports.ClientFlowsViewDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/flow/client-flows-view.html",controller:ClientFlowsViewController,controllerAs:"controller"}};exports.ClientFlowsViewDirective.directive_name="grrClientFlowsView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.copyFlowFormDirective");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const CopyFlowFormController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.flow;this.flowFormHasErrors;this.scope_.$watchGroup(["flowId","clientId"],this.onFlowIdClientIdChange_.bind(this))};CopyFlowFormController.prototype.onFlowIdClientIdChange_=function(newValues){if(newValues.every(angular.isDefined)){var flowUrl=
["clients",this.scope_["clientId"],"flows",this.scope_["flowId"]].join("/");this.grrApiService_.get(flowUrl).then(function(response){this.flow=response["data"]}.bind(this))}};CopyFlowFormController.prototype.proceed=function(){var strippedFlow=stripTypeInfo(this.flow);return this.grrApiService_.post("clients/"+this.scope_["clientId"]+"/flows",{flow:{runner_args:strippedFlow["runner_args"],args:strippedFlow["args"]},original_flow:{flow_id:this.scope_["flowId"],client_id:this.scope_["clientId"]}}).then(function success(response){this.scope_["onResolve"]({"flow":response["data"]});
return"Flow was successfully launched!"}.bind(this),function failure(response){var e=response["data"]["message"]||"Unknown error";throw e;}.bind(this))};exports.CopyFlowFormDirective=function(){return{scope:{flowId:"=",clientId:"=",onResolve:"&"},restrict:"E",templateUrl:"/static/angular-components/flow/copy-flow-form.html",controller:CopyFlowFormController,controllerAs:"controller"}};exports.CopyFlowFormDirective.directive_name="grrCopyFlowForm";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowApiHelperDirective");goog.module.declareLegacyNamespace();const FlowApiHelperController=function($scope,grrApiService,grrApiHelperService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrApiHelperService_=grrApiHelperService;this.clientId;this.result;this.scope_.$watchGroup(["flowId","apiBasePath"],this.onFlowIdOrBasePathChange_.bind(this))};FlowApiHelperController.prototype.onFlowIdOrBasePathChange_=function(newValues){this.flow=
null;this.result=null;if(newValues.every(angular.isDefined)){var flowUrl=this.scope_["apiBasePath"]+"/"+this.scope_["flowId"];this.grrApiService_.getV2(flowUrl).then(function(response){var flow={args:response.data["args"],name:response.data["name"]};if(response.data["runnerArgs"]&&response.data["runnerArgs"]["outputPlugins"])flow["runnerArgs"]={outputPlugins:response.data["runnerArgs"]["outputPlugins"]};var createFlow={flow:flow};this.grrApiHelperService_.buildStartFlow(this.clientId,createFlow).then(function(result){this.result=
result}.bind(this))}.bind(this))}};exports.FlowApiHelperDirective=function(){return{scope:{flowId:"=",apiBasePath:"="},require:"?^grrClientContext",restrict:"E",templateUrl:"/static/angular-components/flow/flow-api-helper.html",controller:FlowApiHelperController,controllerAs:"controller",link:function(scope,element,attrs,grrClientContextCtrl){if(grrClientContextCtrl)scope["controller"].clientId=grrClientContextCtrl.clientId}}};exports.FlowApiHelperDirective.directive_name="grrFlowApiHelper";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowDescriptorsTreeDirective");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const FlowDescriptorsTreeController=function($scope,$element,grrApiService){this.scope_=$scope;this.element_=$element;this.grrApiService_=grrApiService;this.flowsDescriptors;this.userSettings;this.grrApiService_.get("/users/me").then(function(response){this.userSettings=response.data["value"]["settings"]}.bind(this));
this.grrApiService_.get("/flows/descriptors").then(function(response){this.flowsDescriptors=this.groupDescriptorsByCategory_(response["data"]["items"])}.bind(this));this.scope_.$watchGroup(["controller.userSettings","controller.flowsDescriptors"],this.onDescriptorsOrSettingsChange_.bind(this))};FlowDescriptorsTreeController.prototype.groupDescriptorsByCategory_=function(items){var result={};angular.forEach(items,function(item){var category=item["value"]["category"]["value"];result[category]=result[category]||
[];result[category].push(item)}.bind(this));return result};FlowDescriptorsTreeController.prototype.onDescriptorsOrSettingsChange_=function(){if(angular.isUndefined(this.flowsDescriptors)||angular.isUndefined(this.userSettings))return;var mode=this.scope_.$eval("controller.userSettings.value.mode.value");if(angular.isUndefined(mode))mode="BASIC";var treeNodes=[];var descriptorsKeys=Object.keys(this.flowsDescriptors).sort();angular.forEach(descriptorsKeys,function(category){var categoryNode={text:category,
li_attr:{id:"_"+category},children:[]};var descriptors=this.flowsDescriptors[category].sort(function(a,b){a=stripTypeInfo(a);b=stripTypeInfo(b);var aName=a["friendly_name"]||a["name"];var bName=b["friendly_name"]||b["name"];if(aName<bName)return-1;else if(aName>bName)return 1;else return 0});angular.forEach(descriptors,function(descriptor){var strippedDescriptor=stripTypeInfo(descriptor);if(mode=="DEBUG"||strippedDescriptor["behaviours"].indexOf(mode)!=-1)categoryNode["children"].push({data:{descriptor:descriptor},
li_attr:{id:"_"+category+"-"+strippedDescriptor["name"]},text:strippedDescriptor["friendly_name"]||strippedDescriptor["name"],icon:"file"})}.bind(this));treeNodes.push(categoryNode)}.bind(this));var treeElem=$(this.element_).children("div.tree");treeElem.jstree({"core":{"data":treeNodes}});treeElem.on("select_node.jstree",function(e,data){data["instance"]["toggle_node"](data["node"]);if(data.node.data!==null){var descriptor=data.node.data.descriptor;this.scope_.$apply(function(){this.scope_.selectedDescriptor=
descriptor}.bind(this))}}.bind(this))};exports.FlowDescriptorsTreeDirective=function(){return{scope:{selectedDescriptor:"=?"},restrict:"E",template:'<div class="tree"></div>',controller:FlowDescriptorsTreeController,controllerAs:"controller"}};exports.FlowDescriptorsTreeDirective.directive_name="grrFlowDescriptorsTree";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.forms.utils");goog.module.declareLegacyNamespace();exports.valueHasErrors=function(value){if(!angular.isObject(value))return false;if(value["validationError"])return true;if(angular.isArray(value)){var alen=value.length;for(var i=0;i<alen;++i)if(valueHasErrors(value[i]))return true;return false}if(angular.isObject(value["value"])){var nestedValue=value["value"];for(var k in nestedValue)if(valueHasErrors(nestedValue[k]))return true}return false};
var valueHasErrors=exports.valueHasErrors;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowFormDirective");goog.module.declareLegacyNamespace();const {valueHasErrors}=goog.require("grrUi.forms.utils");const FlowFormController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.outputPluginsField;this.outputPluginDescriptor;this.grrReflectionService_.getRDFValueDescriptor("FlowRunnerArgs").then(function(descriptor){angular.forEach(descriptor["fields"],function(field){if(field.name==
"output_plugins")this.outputPluginsField=field}.bind(this));return this.grrReflectionService_.getRDFValueDescriptor("OutputPluginDescriptor")}.bind(this)).then(function(descriptor){this.outputPluginDescriptor=descriptor}.bind(this));this.scope_.$watch("flowRunnerArgs.value.output_plugins",this.onOutputPluginsChanged_.bind(this));this.scope_.$watch(function(){return[this.scope_["flowArgs"],this.scope_["flowRunnerArgs"]]}.bind(this),this.onArgsDeepChange_.bind(this),true)};FlowFormController.prototype.onArgsDeepChange_=
function(){this.scope_["hasErrors"]=valueHasErrors(this.scope_["flowArgs"])||valueHasErrors(this.scope_["flowRunnerArgs"])};FlowFormController.prototype.onOutputPluginsChanged_=function(newValue){if(!this.scope_["withOutputPlugins"])return;var flowRunnerArgs=this.scope_["flowRunnerArgs"];if(angular.isUndefined(newValue)&&angular.isDefined(flowRunnerArgs))flowRunnerArgs["value"]["output_plugins"]=[]};exports.FlowFormDirective=function(){return{scope:{flowArgs:"=",flowRunnerArgs:"=",withOutputPlugins:"=",
hasErrors:"=?"},restrict:"E",templateUrl:"/static/angular-components/flow/flow-form.html",controller:FlowFormController,controllerAs:"controller"}};exports.FlowFormDirective.directive_name="grrFlowForm";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowInfoDirective");goog.module.declareLegacyNamespace();const FlowInfoController=function($scope){this.scope_=$scope};exports.FlowInfoDirective=function(){return{scope:{descriptor:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-info.html",controller:FlowInfoController,controllerAs:"controller"}};exports.FlowInfoDirective.directive_name="grrFlowInfo";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowInspectorDirective");goog.module.declareLegacyNamespace();const FlowInspectorController=function($scope){this.scope_=$scope;this.activeTab="";this.tabsShown={};this.scope_.$watch("activeTab",this.onDirectiveArgumentsChange_.bind(this));this.scope_.$watch("controller.activeTab",this.onTabChange_.bind(this))};FlowInspectorController.prototype.onDirectiveArgumentsChange_=function(newValue){if(angular.isString(newValue))this.activeTab=
newValue};FlowInspectorController.prototype.onTabChange_=function(newValue,oldValue){if(newValue!==oldValue)this.scope_["activeTab"]=newValue;this.tabsShown[newValue]=true};exports.FlowInspectorDirective=function(){return{scope:{flowId:"=",apiBasePath:"=",activeTab:"=?"},controller:FlowInspectorController,controllerAs:"controller",restrict:"E",templateUrl:"/static/angular-components/flow/flow-inspector.html"}};exports.FlowInspectorDirective.directive_name="grrFlowInspector";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowLogDirective");goog.module.declareLegacyNamespace();let AUTO_REFRESH_INTERVAL_MS=20*1E3;exports.setAutoRefreshInterval=function(millis){AUTO_REFRESH_INTERVAL_MS=millis};const FlowLogController=function($scope){this.scope_=$scope;this.logsUrl;this.autoRefreshInterval=AUTO_REFRESH_INTERVAL_MS;this.scope_.$watchGroup(["flowId","apiBasePath"],this.onFlowIdOrBasePathChange_.bind(this))};FlowLogController.prototype.onFlowIdOrBasePathChange_=
function(newValue){if(angular.isDefined(this.scope_["flowId"])&&angular.isDefined(this.scope_["apiBasePath"]))this.logsUrl=[this.scope_["apiBasePath"],this.scope_["flowId"],"log"].join("/")};exports.FlowLogDirective=function(){return{scope:{flowId:"=",apiBasePath:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-log.html",controller:FlowLogController,controllerAs:"controller"}};exports.FlowLogDirective.directive_name="grrFlowLog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowOverviewDirective");goog.module.declareLegacyNamespace();let AUTO_REFRESH_INTERVAL_MS=15*1E3;exports.setAutoRefreshInterval=function(millis){AUTO_REFRESH_INTERVAL_MS=millis};const FlowOverviewController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.flow;this.pollPromise_;this.scope_.$on("$destroy",function(){this.grrApiService_.cancelPoll(this.pollPromise_)}.bind(this));this.scope_.$watchGroup(["flowId",
"apiBasePath"],this.startPolling.bind(this))};FlowOverviewController.prototype.startPolling=function(){this.grrApiService_.cancelPoll(this.pollPromise_);this.pollPromise_=undefined;if(angular.isDefined(this.scope_["apiBasePath"])&&angular.isDefined(this.scope_["flowId"])){var flowUrl=this.scope_["apiBasePath"]+"/"+this.scope_["flowId"];var interval=AUTO_REFRESH_INTERVAL_MS;this.pollPromise_=this.grrApiService_.poll(flowUrl,interval);this.pollPromise_.then(undefined,undefined,function notify(response){this.flow=
response["data"]}.bind(this))}};exports.FlowOverviewDirective=function(){return{scope:{flowId:"=",apiBasePath:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-overview.html",controller:FlowOverviewController,controllerAs:"controller"}};exports.FlowOverviewDirective.directive_name="grrFlowOverview";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowRequestsDirective");goog.module.declareLegacyNamespace();const FlowRequestsController=function($scope){this.scope_=$scope;this.requestsUrl;this.scope_.$watchGroup(["flowId","apiBasePath"],this.onFlowIdOrBasePathChange_.bind(this))};FlowRequestsController.prototype.onFlowIdOrBasePathChange_=function(newValues){if(newValues.every(angular.isDefined))this.requestsUrl=[this.scope_["apiBasePath"],this.scope_["flowId"],"requests"].join("/")};
exports.FlowRequestsDirective=function(){return{scope:{flowId:"=",apiBasePath:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-requests.html",controller:FlowRequestsController,controllerAs:"controller"}};exports.FlowRequestsDirective.directive_name="grrFlowRequests";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowResultsDirective");goog.module.declareLegacyNamespace();const FlowResultsController=function($scope){this.scope_=$scope;this.flowResultsUrl;this.flowExportedResultsUrl;this.outputPluginsMetadataUrl;this.downloadFilesUrl;this.exportCommand;this.scope_.$watchGroup(["flowId","apiBasePath"],this.onFlowIdOrBasePathChange_.bind(this))};FlowResultsController.prototype.onFlowIdOrBasePathChange_=function(newValues){this.flowResultsUrl=
this.outputPluginsMetadataUrl=this.downloadFilesUrl=null;if(newValues.every(angular.isDefined)){var flowUrl=this.scope_["apiBasePath"]+"/"+this.scope_["flowId"];this.flowResultsUrl=flowUrl+"/results";this.flowExportedResultsUrl=flowUrl+"/exported-results";this.outputPluginsUrl=flowUrl+"/output-plugins";this.exportCommandUrl=flowUrl+"/results/export-command";this.downloadFilesUrl=flowUrl+"/results/files-archive"}};exports.FlowResultsDirective=function(){return{scope:{flowId:"=",apiBasePath:"="},restrict:"E",
templateUrl:"/static/angular-components/flow/flow-results.html",controller:FlowResultsController,controllerAs:"controller"}};exports.FlowResultsDirective.directive_name="grrFlowResults";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowStatusIconDirective");goog.module.declareLegacyNamespace();exports.FlowStatusIconDirective=function(){return{scope:{flow:"="},restrict:"E",templateUrl:"/static/angular-components/flow/flow-status-icon.html"}};exports.FlowStatusIconDirective.directive_name="grrFlowStatusIcon";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flowsListDirective");goog.module.declareLegacyNamespace();const {InfiniteTableController}=goog.require("grrUi.core.infiniteTableDirective");var TABLE_KEY_NAME=InfiniteTableController.UNIQUE_KEY_NAME;var TABLE_ROW_HASH=InfiniteTableController.ROW_HASH_NAME;let AUTO_REFRESH_INTERVAL_MS=30*1E3;exports.setAutoRefreshInterval=function(millis){AUTO_REFRESH_INTERVAL_MS=millis};const PAGE_SIZE=1E3;exports.flattenFlowsList=function(flows,
opt_currentDepth){if(angular.isUndefined(opt_currentDepth))opt_currentDepth=0;var result=[];for(var i=0;i<flows.length;++i){var flow=angular.copy(flows[i]);flow["depth"]=opt_currentDepth;result.push(flow);if(angular.isDefined(flow["value"])&&angular.isDefined(flow["value"]["nested_flows"])){result=result.concat(exports.flattenFlowsList(flow["value"]["nested_flows"],opt_currentDepth+1));delete flow["value"]["nested_flows"]}}return result};var flattenFlowsList=exports.flattenFlowsList;exports.toggleFlowExpansion=
function(flows,index){var flowToExpand=flows[index];var i;flowToExpand.expanded=!flowToExpand.expanded;if(!flowToExpand.expanded)for(i=index+1;i<flows.length;++i)if(flows[i].depth>flowToExpand.depth)flows[i].shown=false;else break;else{var ignoreDepth=null;for(i=index+1;i<flows.length;++i)if(flows[i].depth>flowToExpand.depth){if(!ignoreDepth||ignoreDepth>=flows[i].depth){flows[i].shown=true;ignoreDepth=flows[i].expanded?null:flows[i].depth}}else break}return flows};var toggleFlowExpansion=exports.toggleFlowExpansion;
const FlowsListController=function($scope,$element,grrApiService){this.scope_=$scope;this.element_=$element;this.flowsById={};this.selectedFlowId;this.triggerTableUpdate;this.autoRefreshInterval=AUTO_REFRESH_INTERVAL_MS;this.pageSize=PAGE_SIZE;this.scope_.$watch("controller.selectedFlowId",function(newValue){if(angular.isDefined(newValue))this.scope_["selectedFlowId"]=newValue}.bind(this));this.scope_.$watch("selectedFlowId",function(newValue){if(angular.isDefined(newValue))this.selectedFlowId=newValue}.bind(this));
this.scope_["triggerUpdate"]=this.triggerUpdate.bind(this)};FlowsListController.prototype.selectItem=function(item){this.selectedFlowId=item["value"]["flow_id"]["value"]};FlowsListController.prototype.transformItems=function(items){var flattenedItems=flattenFlowsList(items);angular.forEach(flattenedItems,function(item,index){var components=item["value"]["flow_id"]["value"].split("/");item.shortId=components[components.length-1];item.shown=item.depth==0;if(index<flattenedItems.length-1&&flattenedItems[index+
1].depth>item.depth)item.expanded=false;item.expand=function(e){e.stopPropagation();toggleFlowExpansion(flattenedItems,index)};var state="BROKEN";if(angular.isDefined(item["value"]["state"]))state=item["value"]["state"]["value"];var last_active_at=0;if(angular.isDefined(item["value"]["last_active_at"]))last_active_at=item["value"]["last_active_at"]["value"];item[TABLE_KEY_NAME]=item["value"]["flow_id"]["value"];item[TABLE_ROW_HASH]=[state,last_active_at]}.bind(this));return flattenedItems};FlowsListController.prototype.triggerUpdate=
function(){this.triggerTableUpdate(true)};exports.FlowsListDirective=function(){return{scope:{flowsUrl:"=",selectedFlowId:"=?",triggerUpdate:"=?"},restrict:"E",templateUrl:"/static/angular-components/flow/flows-list.html",controller:FlowsListController,controllerAs:"controller"}};exports.FlowsListDirective.directive_name="grrFlowsList";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.startFlowFormDirective");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const {ReflectionService}=goog.require("grrUi.core.reflectionService");const StartFlowFormController=function($scope,grrApiService,grrReflectionService){this.scope_=$scope;this.scope_.clientId;this.grrApiService_=grrApiService;this.grrReflectionService_=grrReflectionService;this.flowArguments;this.flowRunnerArguments;
this.requestSent=false;this.responseError;this.responseData;this.outputPluginsField;this.outputPluginDescriptor;this.flowFormHasErrors;this.scope_.$watch("descriptor",function(flowDescriptor){this.requestSent=false;this.responseError=null;this.responseData=null;if(angular.isDefined(flowDescriptor)){this.flowArguments=angular.copy(flowDescriptor["value"]["default_args"]);this.grrReflectionService_.getRDFValueDescriptor("FlowRunnerArgs").then(function(descriptor){this.flowRunnerArguments=angular.copy(descriptor["default"]);
this.flowRunnerArguments["value"]["flow_name"]=flowDescriptor["value"]["name"]}.bind(this))}}.bind(this))};StartFlowFormController.prototype.startClientFlow=function(){var clientIdComponents=this.scope_["clientId"].split("/");var clientId;if(clientIdComponents[0]=="aff4:")clientId=clientIdComponents[1];else clientId=clientIdComponents[0];this.grrApiService_.post("/clients/"+clientId+"/flows",{flow:{runner_args:stripTypeInfo(this.flowRunnerArguments),args:stripTypeInfo(this.flowArguments)}}).then(function success(response){this.responseData=
response["data"]}.bind(this),function failure(response){this.responseError=response["data"]["message"]||"Unknown error"}.bind(this));this.requestSent=true};exports.StartFlowFormDirective=function(){return{scope:{clientId:"=?",descriptor:"="},restrict:"E",templateUrl:"/static/angular-components/flow/start-flow-form.html",controller:StartFlowFormController,controllerAs:"controller"}};exports.StartFlowFormDirective.directive_name="grrStartFlowForm";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.startFlowViewDirective");goog.module.declareLegacyNamespace();const StartFlowViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.cliendId;this.selection={};this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientIdChange_.bind(this))};StartFlowViewController.prototype.onClientIdChange_=function(clientId){this.clientId=clientId};exports.StartFlowViewDirective=
function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/flow/start-flow-view.html",controller:StartFlowViewController,controllerAs:"controller"}};exports.StartFlowViewDirective.directive_name="grrStartFlowView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.flow.flow");goog.module.declareLegacyNamespace();const {ClientFlowsListDirective}=goog.require("grrUi.flow.clientFlowsListDirective");const {ClientFlowsViewDirective}=goog.require("grrUi.flow.clientFlowsViewDirective");const {CopyFlowFormDirective}=goog.require("grrUi.flow.copyFlowFormDirective");const {FlowApiHelperDirective}=goog.require("grrUi.flow.flowApiHelperDirective");const {FlowDescriptorsTreeDirective}=goog.require("grrUi.flow.flowDescriptorsTreeDirective");
const {FlowFormDirective}=goog.require("grrUi.flow.flowFormDirective");const {FlowInfoDirective}=goog.require("grrUi.flow.flowInfoDirective");const {FlowInspectorDirective}=goog.require("grrUi.flow.flowInspectorDirective");const {FlowLogDirective}=goog.require("grrUi.flow.flowLogDirective");const {FlowOverviewDirective}=goog.require("grrUi.flow.flowOverviewDirective");const {FlowRequestsDirective}=goog.require("grrUi.flow.flowRequestsDirective");const {FlowResultsDirective}=goog.require("grrUi.flow.flowResultsDirective");
const {FlowStatusIconDirective}=goog.require("grrUi.flow.flowStatusIconDirective");const {FlowsListDirective}=goog.require("grrUi.flow.flowsListDirective");const {StartFlowFormDirective}=goog.require("grrUi.flow.startFlowFormDirective");const {StartFlowViewDirective}=goog.require("grrUi.flow.startFlowViewDirective");const {coreModule}=goog.require("grrUi.core.core");exports.flowModule=angular.module("grrUi.flow",[coreModule.name]);exports.flowModule.directive(ClientFlowsListDirective.directive_name,
ClientFlowsListDirective);exports.flowModule.directive(ClientFlowsViewDirective.directive_name,ClientFlowsViewDirective);exports.flowModule.directive(CopyFlowFormDirective.directive_name,CopyFlowFormDirective);exports.flowModule.directive(FlowApiHelperDirective.directive_name,FlowApiHelperDirective);exports.flowModule.directive(FlowDescriptorsTreeDirective.directive_name,FlowDescriptorsTreeDirective);exports.flowModule.directive(FlowFormDirective.directive_name,FlowFormDirective);exports.flowModule.directive(FlowInfoDirective.directive_name,
FlowInfoDirective);exports.flowModule.directive(FlowInspectorDirective.directive_name,FlowInspectorDirective);exports.flowModule.directive(FlowLogDirective.directive_name,FlowLogDirective);exports.flowModule.directive(FlowOverviewDirective.directive_name,FlowOverviewDirective);exports.flowModule.directive(FlowRequestsDirective.directive_name,FlowRequestsDirective);exports.flowModule.directive(FlowResultsDirective.directive_name,FlowResultsDirective);exports.flowModule.directive(FlowStatusIconDirective.directive_name,
FlowStatusIconDirective);exports.flowModule.directive(FlowsListDirective.directive_name,FlowsListDirective);exports.flowModule.directive(StartFlowFormDirective.directive_name,StartFlowFormDirective);exports.flowModule.directive(StartFlowViewDirective.directive_name,StartFlowViewDirective);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntClientsDirective");goog.module.declareLegacyNamespace();const HuntClientsController=function($scope){this.scope_=$scope;this.huntClientsUrl;this.clientType="completed";this.scope_.$watchGroup(["huntId","controller.clientType"],this.onHuntIdOrClientTypeChange_.bind(this))};HuntClientsController.prototype.onHuntIdOrClientTypeChange_=function(){var huntId=this.scope_["huntId"];if(!angular.isString(huntId)||!angular.isString(this.clientType))return;
this.huntClientsUrl="/hunts/"+huntId+"/clients/"+this.clientType};exports.HuntClientsDirective=function(){return{scope:{huntId:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-clients.html",controller:HuntClientsController,controllerAs:"controller"}};exports.HuntClientsDirective.directive_name="grrHuntClients";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntContextDirective");goog.module.declareLegacyNamespace();const HuntContextController=function($scope,grrApiService){this.grrApiService_=grrApiService;this.context;this.state;$scope.$watch("huntId",this.onHuntIdChange_.bind(this))};HuntContextController.prototype.onHuntIdChange_=function(huntId){if(!angular.isString(huntId))return;var url="/hunts/"+huntId+"/context";this.grrApiService_.get(url).then(function success(response){this.context=
response.data["context"];this.state=response.data["state"]}.bind(this))};exports.HuntContextDirective=function(){return{scope:{huntId:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-context.html",controller:HuntContextController,controllerAs:"controller"}};exports.HuntContextDirective.directive_name="grrHuntContext";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntCrashesDirective");goog.module.declareLegacyNamespace();let AUTO_REFRESH_INTERVAL_MS=20*1E3;exports.setAutoRefreshInterval=function(millis){AUTO_REFRESH_INTERVAL_MS=millis};const HuntCrashesController=function($scope){this.scope_=$scope;this.scope_.huntId;this.crashesUrl;this.autoRefreshInterval=AUTO_REFRESH_INTERVAL_MS;this.scope_.$watch("huntId",this.onHuntIdChange_.bind(this))};HuntCrashesController.prototype.onHuntIdChange_=
function(huntId){if(angular.isDefined(huntId))this.crashesUrl="hunts/"+huntId+"/crashes"};exports.HuntCrashesDirective=function(){return{scope:{huntId:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-crashes.html",controller:HuntCrashesController,controllerAs:"controller"}};exports.HuntCrashesDirective.directive_name="grrHuntCrashes";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntErrorsDirective");goog.module.declareLegacyNamespace();let AUTO_REFRESH_INTERVAL_MS=20*1E3;exports.setAutoRefreshInterval=function(millis){AUTO_REFRESH_INTERVAL_MS=millis};const HuntErrorsController=function($scope){this.scope_=$scope;this.scope_.huntId;this.errorsUrl;this.autoRefreshInterval=AUTO_REFRESH_INTERVAL_MS;this.scope_.$watch("huntId",this.onHuntIdChange_.bind(this))};HuntErrorsController.prototype.onHuntIdChange_=
function(huntId){if(angular.isDefined(huntId))this.errorsUrl="hunts/"+huntId+"/errors"};exports.HuntErrorsDirective=function(){return{scope:{huntId:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-errors.html",controller:HuntErrorsController,controllerAs:"controller"}};exports.HuntErrorsDirective.directive_name="grrHuntErrors";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntGraphDirective");goog.module.declareLegacyNamespace();const {buildTimeseriesGraph}=goog.require("grrUi.stats.graphUtils");const HuntGraphController=function($scope,$element,grrApiService){this.scope_=$scope;this.element_=$element;this.grrApiService_=grrApiService;this.scope_.huntId;this.inProgress=false;this.clientStartPoints;this.clientFinishPoints;this.informationAvailable;this.maxSampleSize=1E3;this.scope_.$watch("huntId",
this.onHuntIdChange_.bind(this))};HuntGraphController.prototype.onHuntIdChange_=function(){this.hunt=null;this.huntSummary=null;if(angular.isDefined(this.scope_.huntId)){this.huntId=this.scope_["huntId"];this.inProgress=true;var url="hunts/"+this.huntId+"/client-completion-stats";var params={"strip_type_info":1,"size":this.maxSampleSize};this.grrApiService_.get(url,params).then(this.onHuntGraphFetched_.bind(this))}};HuntGraphController.prototype.onHuntGraphFetched_=function(response){this.clientStartPoints=
this.parseDataPoints_(response.data["start_points"]);this.clientFinishPoints=this.parseDataPoints_(response.data["complete_points"]);this.informationAvailable=angular.isArray(this.clientStartPoints)&&this.clientStartPoints.length>0||angular.isArray(this.clientFinishPoints)&&this.clientFinishPoints.length>0;this.drawGraph_();this.inProgress=false};HuntGraphController.prototype.parseDataPoints_=function(points){var result=[];angular.forEach(points,function(point){result.push([Math.round(point["x_value"]*
1E3),point["y_value"]])});return result};HuntGraphController.prototype.drawGraph_=function(){var graphElement=$(this.element_).find(".client-completion-graph");if(graphElement&&this.informationAvailable){graphElement.resize(()=>{graphElement.html("");buildTimeseriesGraph(graphElement,undefined,{"Agents issued.":this.clientStartPoints,"Agents completed.":this.clientFinishPoints})});graphElement.resize()}};exports.HuntGraphDirective=function(){return{scope:{huntId:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-graph.html",
controller:HuntGraphController,controllerAs:"controller"}};exports.HuntGraphDirective.directive_name="grrHuntGraph";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntInspectorDirective");goog.module.declareLegacyNamespace();const HuntInspectorController=function($scope){this.scope_=$scope;this.shownHuntId;this.activeTab="";this.tabsShown={};this.scope_.$watchGroup(["huntId","activeTab"],this.onDirectiveArgumentsChange_.bind(this));this.scope_.$watch("controller.activeTab",this.onTabChange_.bind(this))};HuntInspectorController.prototype.onDirectiveArgumentsChange_=function(){if(angular.isString(this.scope_["activeTab"]))this.activeTab=
this.scope_["activeTab"];this.scope_.$evalAsync(function(){this.shownHuntId=this.scope_["huntId"]}.bind(this))};HuntInspectorController.prototype.onTabChange_=function(newValue,oldValue){if(newValue!==oldValue)this.scope_["activeTab"]=newValue;this.tabsShown[newValue]=true};exports.HuntInspectorDirective=function(){return{scope:{huntId:"=",activeTab:"=?"},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-inspector.html",controller:HuntInspectorController,controllerAs:"controller"}};exports.HuntInspectorDirective.directive_name=
"grrHuntInspector";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntLogDirective");goog.module.declareLegacyNamespace();let AUTO_REFRESH_INTERVAL_MS=20*1E3;exports.setAutoRefreshInterval=function(millis){AUTO_REFRESH_INTERVAL_MS=millis};const HuntLogController=function($scope){this.scope_=$scope;this.scope_.huntId;this.autoRefreshInterval=AUTO_REFRESH_INTERVAL_MS;this.scope_.$watch("huntId",this.onHuntIdChange_.bind(this))};HuntLogController.prototype.onHuntIdChange_=function(huntId){if(angular.isDefined(huntId))this.logsUrl=
"hunts/"+huntId+"/log"};HuntLogController.prototype.transformItems=function(items){var clientId=null;var highlighted=false;for(var i=0;i<items.length;++i){var item=items[i];var itemClientId=null;if(item.value.client_id!==undefined)itemClientId=item.value.client_id.value;if(clientId!==itemClientId){clientId=itemClientId;highlighted=!highlighted}else item.value.client_id=null;item.highlighted=highlighted}return items};exports.HuntLogDirective=function(){return{scope:{huntId:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-log.html",
controller:HuntLogController,controllerAs:"controller"}};exports.HuntLogDirective.directive_name="grrHuntLog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.utils");goog.module.declareLegacyNamespace();let DurationSeconds;let Timestamp;let Hunt;exports.huntExpirationTime=hunt=>{const initStartTime=hunt.value.init_start_time;const duration=hunt.value.duration;if(initStartTime===undefined||duration===undefined)return undefined;return{type:"RDFDatetime",value:initStartTime.value+duration.value*1E6}};exports.DurationSeconds=DurationSeconds;exports.Timestamp=Timestamp;exports.Hunt=Hunt;
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntOverviewDirective");goog.module.declareLegacyNamespace();const {huntExpirationTime}=goog.require("grrUi.hunt.utils");let AUTO_REFRESH_INTERVAL_MS=15*1E3;exports.setAutoRefreshInterval=function(millis){AUTO_REFRESH_INTERVAL_MS=millis};const HuntOverviewController=function($scope,grrApiService,grrRoutingService){this.scope_=$scope;this.scope_.huntId;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;
this.huntId;this.hunt;this.huntExpirationTime;this.pollPromise_;this.scope_.$on("$destroy",function(){this.grrApiService_.cancelPoll(this.pollPromise_)}.bind(this));this.scope_.$watch("huntId",this.startPolling_.bind(this))};HuntOverviewController.prototype.startPolling_=function(){this.grrApiService_.cancelPoll(this.pollPromise_);this.pollPromise_=undefined;if(angular.isDefined(this.scope_["huntId"])){this.huntId=this.scope_["huntId"];var huntUrl="hunts/"+this.huntId;var interval=AUTO_REFRESH_INTERVAL_MS;
this.pollPromise_=this.grrApiService_.poll(huntUrl,interval);this.pollPromise_.then(undefined,undefined,response=>{const hunt=response["data"];this.hunt=hunt;this.huntExpirationTime=huntExpirationTime(hunt)})}};exports.HuntOverviewDirective=function(){return{scope:{huntId:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-overview.html",controller:HuntOverviewController,controllerAs:"controller"}};exports.HuntOverviewDirective.directive_name="grrHuntOverview";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntResultsDirective");goog.module.declareLegacyNamespace();const {downloadableVfsRoots,getPathSpecFromValue,makeValueDownloadable,pathSpecToAff4Path}=goog.require("grrUi.core.fileDownloadUtils");const {stripAff4Prefix}=goog.require("grrUi.core.utils");const HuntResultsController=function($scope){this.scope_=$scope;this.resultsUrl;this.exportedResultsUrl;this.outputPluginsUrl;this.downloadFilesUrl;this.exportCommandUrl;$scope.$watch("huntId",
this.onHuntIdChange.bind(this))};HuntResultsController.prototype.onHuntIdChange=function(huntId){if(!angular.isString(huntId))return;this.resultsUrl="/hunts/"+huntId+"/results";this.exportedResultsUrl="/hunts/"+huntId+"/exported-results";this.downloadFilesUrl=this.resultsUrl+"/files-archive";this.exportCommandUrl=this.resultsUrl+"/export-command";this.outputPluginsUrl="/hunts/"+huntId+"/output-plugins"};HuntResultsController.prototype.transformItems=function(items){var urlPrefix="/hunts/"+this.scope_["huntId"]+
"/results/clients";var newItems=items.map(function(item){var pathSpec=getPathSpecFromValue(item);if(!pathSpec)return item;var clientId=item["value"]["client_id"]["value"];var aff4Path=stripAff4Prefix(pathSpecToAff4Path(pathSpec,clientId));var components=aff4Path.split("/");var vfsPath=components.slice(1).join("/");var legitimatePath=downloadableVfsRoots.some(function(vfsRoot){var prefix=vfsRoot+"/";return vfsPath.startsWith(prefix)}.bind(this));if(!legitimatePath)return item;var downloadUrl=urlPrefix+
"/"+clientId+"/vfs-blob/"+vfsPath;var downloadParams={"timestamp":item["value"]["timestamp"]["value"]};var downloadableItem=angular.copy(item);makeValueDownloadable(downloadableItem,downloadUrl,downloadParams);return downloadableItem});return newItems};exports.HuntResultsDirective=function(){return{scope:{huntId:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-results.html",controller:HuntResultsController,controllerAs:"controller"}};exports.HuntResultsDirective.directive_name=
"grrHuntResults";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntStatsDirective");goog.module.declareLegacyNamespace();const {ApiService}=goog.require("grrUi.core.apiService");const HuntStatsController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.stats;this.userCpuStats;this.systemCpuStats;this.networkBytesStats;this.totalClientCount;this.scope_.$watch("huntId",x=>this.onHuntIdChange_(x))};function formatSeconds(value){return value.toFixed(1)+
"s"}function formatBytes(value){if(value<1024)return`${value} B`;else return`${Math.round(value/1024)} KiB`}HuntStatsController.prototype.convertHistogramToComparisonChart_=function(data,labelFormatFn){const series=[];let mean=undefined;let stdev=undefined;if(data!==undefined){const bins=data["value"]["histogram"]["value"]["bins"];for(const bin of bins){let num=0;if(bin["value"]["num"]!==undefined)num=bin["value"]["num"]["value"];series.push({value:{label:{value:"< "+labelFormatFn(bin["value"]["range_max_value"]["value"])},
x:{value:num}}})}if(series.length>0&&bins.length>1){const lastSerie=series[series.length-1]["value"];lastSerie["label"]["value"]="> "+labelFormatFn(bins[bins.length-2]["value"]["range_max_value"]["value"])}if(data["value"]["num"]){mean=data["value"]["sum"]["value"]/data["value"]["num"]["value"];stdev=Math.sqrt(data["value"]["sum_sq"]["value"]/data["value"]["num"]["value"]-Math.pow(mean,2))}}return{mean,stdev,value:{data:series}}};HuntStatsController.prototype.onHuntIdChange_=function(huntId){if(!angular.isString(huntId))return;
var url=`/hunts/${huntId}/stats`;this.grrApiService_.get(url).then(response=>{this.stats=response.data["stats"];this.userCpuStats=this.convertHistogramToComparisonChart_(this.stats["value"]["user_cpu_stats"],formatSeconds);this.systemCpuStats=this.convertHistogramToComparisonChart_(this.stats["value"]["system_cpu_stats"],formatSeconds);this.networkBytesStats=this.convertHistogramToComparisonChart_(this.stats["value"]["network_bytes_sent_stats"],formatBytes);if(this.stats["value"]["user_cpu_stats"])this.totalClientCount=
this.stats["value"]["user_cpu_stats"]["num"]["value"]})};exports.HuntStatsDirective=function(){return{scope:{huntId:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-stats.html",controller:HuntStatsController,controllerAs:"controller"}};exports.HuntStatsDirective.directive_name="grrHuntStats";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntStatusIconDirective");goog.module.declareLegacyNamespace();exports.HuntStatusIconDirective=function(){return{scope:{hunt:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/hunt-status-icon.html"}};exports.HuntStatusIconDirective.directive_name="grrHuntStatusIcon";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntsListDirective");goog.module.declareLegacyNamespace();const {AclDialogService}=goog.require("grrUi.acl.aclDialogService");const {ApiService}=goog.require("grrUi.core.apiService");const {DialogService}=goog.require("grrUi.core.dialogService");const {huntExpirationTime}=goog.require("grrUi.hunt.utils");const {stripAff4Prefix}=goog.require("grrUi.core.utils");const HuntsListController=function($scope,$q,$uibModal,grrDialogService,
grrApiService,grrAclDialogService){this.scope_=$scope;this.q_=$q;this.uibModal_=$uibModal;this.grrDialogService_=grrDialogService;this.grrApiService_=grrApiService;this.grrAclDialogService_=grrAclDialogService;this.huntsById={};this.showRobotHunts=false;this.triggerUpdate};HuntsListController.prototype.huntsUrl="/hunts";HuntsListController.prototype.buildHuntUrl_=function(){var components=this.scope_["selectedHuntId"].split("/");var basename=components[components.length-1];return this.huntsUrl+"/"+
basename};HuntsListController.prototype.wrapApiPromise_=function(promise,successMessage){return promise.then(function success(){return successMessage}.bind(this),function failure(response){var message=response["data"]["message"];if(response["status"]===403){var subject=response["data"]["subject"];var huntId=stripAff4Prefix(subject).split("/")[1];this.grrAclDialogService_.openRequestHuntApprovalDialog(huntId,message)}return this.q_.reject(message)}.bind(this))};HuntsListController.prototype.selectItem=
function(item){this.scope_["selectedHuntId"]=item.value.hunt_id.value};HuntsListController.prototype.newHunt=function(){var modalScope=this.scope_.$new();modalScope.resolve=function(){modalInstance.close()};modalScope.reject=function(){modalInstance.dismiss()};this.scope_.$on("$destroy",function(){modalScope.$destroy()});var modalInstance=this.uibModal_.open({template:'<grr-new-hunt-wizard-form on-resolve="resolve()" '+'on-reject="reject()" />',scope:modalScope,windowClass:"wide-modal high-modal",
size:"lg"});modalInstance.result.then(function resolve(){this.triggerUpdate()}.bind(this))};HuntsListController.prototype.runHunt=function(){var modalPromise=this.grrDialogService_.openConfirmation("Run this hunt?","Are you sure you want to run this hunt?",function(){var promise=this.grrApiService_.patch(this.buildHuntUrl_(),{state:"STARTED"});return this.wrapApiPromise_(promise,"Hunt started successfully!")}.bind(this));modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};
HuntsListController.prototype.stopHunt=function(){var modalPromise=this.grrDialogService_.openConfirmation("Stop this hunt?","Are you sure you want to stop this hunt? Once a hunt is "+"stopped, resuming it is not possible.",function(){var promise=this.grrApiService_.patch(this.buildHuntUrl_(),{state:"STOPPED"});return this.wrapApiPromise_(promise,"Hunt stopped successfully!")}.bind(this));modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};
HuntsListController.prototype.modifyHunt=function(){var components=this.scope_["selectedHuntId"].split("/");var huntId=components[components.length-1];var argsObj={};var modalPromise=this.grrDialogService_.openDirectiveDialog("grrModifyHuntDialog",{huntId:huntId});modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};HuntsListController.prototype.copyHunt=function(){var modalScope=this.scope_.$new();modalScope.huntId=this.scope_["selectedHuntId"];
modalScope.resolve=function(){modalInstance.close()};modalScope.reject=function(){modalInstance.dismiss()};this.scope_.$on("$destroy",function(){modalScope.$destroy()});var modalInstance=this.uibModal_.open({template:'<grr-new-hunt-wizard-copy-form on-resolve="resolve()" '+'on-reject="reject()" hunt-id="huntId" />',scope:modalScope,windowClass:"wide-modal high-modal",size:"lg"});modalInstance.result.then(function resolve(){this.triggerUpdate()}.bind(this))};HuntsListController.prototype.deleteHunt=
function(){var modalPromise=this.grrDialogService_.openConfirmation("Delete this hunt?","Are you sure you want to delete this hunt?",function(){var promise=this.grrApiService_.delete(this.buildHuntUrl_());return this.wrapApiPromise_(promise,"Hunt deleted successfully!")}.bind(this));modalPromise.then(function resolve(){this.triggerUpdate()}.bind(this),function dismiss(){this.triggerUpdate()}.bind(this))};HuntsListController.prototype.transformItems=function(items){angular.forEach(items,function(item){item["value"]["expiration_time"]=
huntExpirationTime(item);this.huntsById[item["value"]["hunt_id"]["value"]]=item}.bind(this));return items};exports.HuntsListDirective=function(){return{scope:{selectedHuntId:"=?"},restrict:"E",templateUrl:"/static/angular-components/hunt/hunts-list.html",controller:HuntsListController,controllerAs:"controller"}};exports.HuntsListDirective.directive_name="grrHuntsList";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.huntsViewDirective");goog.module.declareLegacyNamespace();const HuntsViewController=function($scope,grrRoutingService){this.scope_=$scope;this.grrRoutingService_=grrRoutingService;this.selectedHuntId;this.tab;this.scope_.$watchGroup(["controller.selectedHuntId","controller.tab"],this.onSelectionChange_.bind(this));this.grrRoutingService_.uiOnParamsChanged(this.scope_,["huntId","tab"],this.onParamsChange_.bind(this))};HuntsViewController.prototype.onParamsChange_=
function(newValues,opt_stateParams){if(opt_stateParams["huntId"])this.selectedHuntId=opt_stateParams["huntId"];this.tab=opt_stateParams["tab"]};HuntsViewController.prototype.onSelectionChange_=function(){if(angular.isDefined(this.selectedHuntId))this.grrRoutingService_.go("hunts",{huntId:this.selectedHuntId,tab:this.tab})};exports.HuntsViewDirective=function(){return{restrict:"E",scope:{},templateUrl:"/static/angular-components/hunt/hunts-view.html",controller:HuntsViewController,controllerAs:"controller"}};
exports.HuntsViewDirective.directive_name="grrHuntsView";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.modifyHuntDialogDirective");goog.module.declareLegacyNamespace();const {AclDialogService}=goog.require("grrUi.acl.aclDialogService");const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const {stripAff4Prefix}=goog.require("grrUi.core.utils");const ModifyHuntDialogController=function($scope,$q,grrApiService,grrAclDialogService){this.scope_=$scope;this.q_=$q;this.grrApiService_=grrApiService;this.grrAclDialogService_=
grrAclDialogService;this.argsObj;this.scope_.$watch("huntId",this.onHuntIdChange_.bind(this))};ModifyHuntDialogController.prototype.onHuntIdChange_=function(newValue){this.argsObj=undefined;if(angular.isString(newValue))this.grrApiService_.get("/hunts/"+newValue).then(function(response){var hunt=response["data"];this.argsObj={type:"ApiModifyHuntArgs",value:{}};angular.forEach(["client_limit","client_rate","duration"],function(k){var v=hunt["value"][k];if(v)this.argsObj["value"][k]=angular.copy(v)}.bind(this))}.bind(this))};
ModifyHuntDialogController.prototype.proceed=function(){var request=stripTypeInfo(this.argsObj);return this.grrApiService_.patch("/hunts/"+this.scope_["huntId"],request).then(function success(){return"Hunt modified successfully!"}.bind(this),function failure(response){var message=response["data"]["message"];if(response["status"]===403){var subject=response["data"]["subject"];var huntId=stripAff4Prefix(subject).split("/")[1];this.grrAclDialogService_.openRequestHuntApprovalDialog(huntId,message)}return this.q_.reject(message)}.bind(this))};
exports.ModifyHuntDialogDirective=function(){return{scope:{huntId:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/modify-hunt-dialog.html",controller:ModifyHuntDialogController,controllerAs:"controller"}};exports.ModifyHuntDialogDirective.directive_name="grrModifyHuntDialog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.rapidHuntStatusDirective");goog.module.declareLegacyNamespace();const isPathInvalid_=path=>{return(path["value"].match(/\*/g)||[]).length>1};exports.isEligible=(flowName,flowArgs)=>{if(flowName!=="FileFinder"&&flowName!=="ClientFileFinder")return false;const hasInvalidPath=(flowArgs["value"]["paths"]||[]).find(isPathInvalid_);if(hasInvalidPath)return false;if(flowArgs["value"]["action"]!==undefined&&flowArgs["value"]["action"]["value"]["action_type"]&&
flowArgs["value"]["action"]["value"]["action_type"]["value"]==="DOWNLOAD")return false;return true};const isEligible=exports.isEligible;const RapidHuntStatusController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.enabled=false;this.isEligible=false;this.grrApiService_.getCached("/config/AdminUI.rapid_hunts_enabled").then(response=>{this.enabled=response["data"]["value"]["value"];if(this.enabled){this.scope_.$watch("flowName",this.onFlowChange_.bind(this));
this.scope_.$watch("flowArgs",this.onFlowChange_.bind(this))}})};RapidHuntStatusController.prototype.onFlowChange_=function(){if(angular.isUndefined(this.scope_["flowName"])||angular.isUndefined(this.scope_["flowArgs"]))return;this.scope_["isEligible"]=this.isEligible=isEligible(this.scope_["flowName"],this.scope_["flowArgs"])};exports.RapidHuntStatusDirective=function(){return{scope:{flowName:"<",flowArgs:"<",clientRate:"<",isEligible:"=?"},restrict:"E",templateUrl:"/static/angular-components/hunt/rapid-hunt-status.html",
controller:RapidHuntStatusController,controllerAs:"controller"}};exports.RapidHuntStatusDirective.directive_name="grrRapidHuntStatus";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.newHuntWizard.configureFlowPageDirective");goog.module.declareLegacyNamespace();const {valueHasErrors}=goog.require("grrUi.forms.utils");const ConfigureFlowPageController=function($scope){this.scope_=$scope;this.flowDescriptor;this.scope_.$watch("controller.flowDescriptor",function(flowDescriptor){if(angular.isUndefined(flowDescriptor))return;this.scope_.flowName=flowDescriptor["value"]["name"]["value"];this.scope_["flowArguments"]=
angular.copy(flowDescriptor["value"]["default_args"])}.bind(this));this.scope_.$watch("flowArguments",this.onFlowArgumentsDeepChange_.bind(this),true)};ConfigureFlowPageController.prototype.onFlowArgumentsDeepChange_=function(newValue){this.scope_["hasErrors"]=valueHasErrors(newValue)};exports.ConfigureFlowPageDirective=function(){return{scope:{flowName:"=",flowArguments:"=",hasErrors:"=?"},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"configure-flow-page.html",controller:ConfigureFlowPageController,
controllerAs:"controller"}};exports.ConfigureFlowPageDirective.directive_name="grrConfigureFlowPage";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.newHuntWizard.configureHuntPageDirective");goog.module.declareLegacyNamespace();exports.ConfigureHuntPageDirective=function(){return{scope:{huntRunnerArgs:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"configure-hunt-page.html"}};exports.ConfigureHuntPageDirective.directive_name="grrConfigureHuntPage";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective");goog.module.declareLegacyNamespace();const ConfigureOutputPluginsPageController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.outputPluginsField;this.outputPluginDescriptor;this.grrReflectionService_.getRDFValueDescriptor("GenericHuntArgs",true).then(this.onDescriptors_.bind(this))};ConfigureOutputPluginsPageController.prototype.onDescriptors_=
function(descriptors){angular.forEach(descriptors["GenericHuntArgs"]["fields"],function(field){if(field.name=="output_plugins")this.outputPluginsField=field}.bind(this));this.outputPluginDescriptor=descriptors["OutputPluginDescriptor"]};exports.ConfigureOutputPluginsPageDirective=function(){return{scope:{outputPlugins:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"configure-output-plugins-page.html",controller:ConfigureOutputPluginsPageController,controllerAs:"controller"}};
exports.ConfigureOutputPluginsPageDirective.directive_name="grrConfigureOutputPluginsPage";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.newHuntWizard.configureRulesPageDirective");goog.module.declareLegacyNamespace();exports.ConfigureRulesPageDirective=function(){return{scope:{clientRuleSet:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"configure-rules-page.html"}};exports.ConfigureRulesPageDirective.directive_name="grrConfigureRulesPage";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.newHuntWizard.copyFormDirective");goog.module.declareLegacyNamespace();const CopyFormController=function($scope,grrReflectionService,grrApiService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.grrApiService_=grrApiService;this.createHuntArgs;this.createHuntArgsDescriptor;this.grrReflectionService_.getRDFValueDescriptor("ApiCreateHuntArgs",true).then(function(descriptor){this.createHuntArgsDescriptor=
descriptor["ApiCreateHuntArgs"];this.huntRefDescriptor=descriptor["ApiHuntReference"];this.scope_.$watch("huntId",this.onHuntIdChange_.bind(this))}.bind(this))};CopyFormController.prototype.onHuntIdChange_=function(){if(angular.isDefined(this.scope_["huntId"])){this.huntId=this.scope_["huntId"];this.grrApiService_.get("hunts/"+this.huntId).then(this.onHuntFetched_.bind(this))}};CopyFormController.prototype.onHuntFetched_=function(response){var hunt=response["data"];this.createHuntArgs=angular.copy(this.createHuntArgsDescriptor["default"]);
this.createHuntArgs["value"]["flow_name"]=angular.copy(hunt["value"]["flow_name"]);this.createHuntArgs["value"]["flow_args"]=angular.copy(hunt["value"]["flow_args"]);var huntRunnerArgs=this.createHuntArgs["value"]["hunt_runner_args"]=angular.copy(hunt["value"]["hunt_runner_args"]);if(angular.isDefined(huntRunnerArgs["value"]["description"]))huntRunnerArgs["value"]["description"]["value"]+=" (copy)";this.createHuntArgs["value"]["original_hunt"]=angular.copy(this.huntRefDescriptor["default"]);this.createHuntArgs["value"]["original_hunt"]["value"]["hunt_id"]=
hunt["value"]["hunt_id"]};exports.CopyFormDirective=function(){return{scope:{huntId:"=",onResolve:"&",onReject:"&"},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"copy-form.html",controller:CopyFormController,controllerAs:"controller"}};exports.CopyFormDirective.directive_name="grrNewHuntWizardCopyForm";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective");goog.module.declareLegacyNamespace();const CreateHuntFromFlowFormController=function($scope,grrApiService,grrReflectionService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrReflectionService_=grrReflectionService;this.createHuntArgs;this.flow_;this.descriptors_={};this.grrReflectionService_.getRDFValueDescriptor("ApiCreateHuntArgs",true).then(function(descriptors){angular.extend(this.descriptors_,
descriptors);this.scope_.$watchGroup(["flowId","clientId"],this.onFlowIdClientIdChange_.bind(this))}.bind(this))};CreateHuntFromFlowFormController.prototype.onFlowIdClientIdChange_=function(newValues){if(newValues.every(angular.isDefined)){var flowUrl=["clients",this.scope_["clientId"],"flows",this.scope_["flowId"]].join("/");this.grrApiService_.get(flowUrl).then(function(response){this.flow_=response["data"]}.bind(this)).then(this.onFlowDataFetched_.bind(this))}};CreateHuntFromFlowFormController.prototype.onFlowDataFetched_=
function(){var huntArgs=angular.copy(this.descriptors_["ApiCreateHuntArgs"]["default"]);huntArgs["value"]["flow_name"]=angular.copy(this.flow_["value"]["name"]);huntArgs["value"]["flow_args"]=angular.copy(this.flow_["value"]["args"]);huntArgs["value"]["original_flow"]=angular.copy(this.descriptors_["FlowReference"]["default"]);huntArgs["value"]["original_flow"]["value"]["flow_id"]=this.flow_["value"]["flow_id"]["value"];huntArgs["value"]["original_flow"]["value"]["client_id"]=this.scope_["clientId"];
this.createHuntArgs=huntArgs};exports.CreateHuntFromFlowFormDirective=function(){return{scope:{flowId:"=",clientId:"=",onResolve:"&",onReject:"&"},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"create-hunt-from-flow-form.html",controller:CreateHuntFromFlowFormController,controllerAs:"controller"}};exports.CreateHuntFromFlowFormDirective.directive_name="grrNewHuntWizardCreateFromFlowForm";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.newHuntWizard.reviewPageDirective");goog.module.declareLegacyNamespace();const ReviewPageController=function($scope,grrReflectionService){this.scope_=$scope;this.grrReflectionService_=grrReflectionService;this.isRapidHuntEligible=false;this.oldClientRate_=null;this.scope_.$watch("controller.isRapidHuntEligible",this.onRapidHuntEligibilityChange_.bind(this))};ReviewPageController.prototype.onRapidHuntEligibilityChange_=function(newValue){if(newValue)this.grrReflectionService_.getRDFValueDescriptor("float").then(desc=>
{const clientRate=angular.copy(desc["default"]);this.oldClientRate_=this.scope_["createHuntArgs"]["value"]["hunt_runner_args"]["value"]["client_rate"];this.scope_["createHuntArgs"]["value"]["hunt_runner_args"]["value"]["client_rate"]=clientRate});else if(this.oldClientRate_!==null){this.scope_["createHuntArgs"]["value"]["hunt_runner_args"]["value"]["client_rate"]=this.oldClientRate_;this.oldClientRate_=null}};exports.ReviewPageDirective=function(){return{scope:{createHuntArgs:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+
"review-page.html",controller:ReviewPageController,controllerAs:"controller"}};exports.ReviewPageDirective.directive_name="grrNewHuntReviewPage";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.newHuntWizard.statusPageDirective");goog.module.declareLegacyNamespace();exports.StatusPageDirective=function(){return{scope:{response:"="},restrict:"E",templateUrl:"/static/angular-components/hunt/new-hunt-wizard/"+"status-page.html"}};exports.StatusPageDirective.directive_name="grrNewHuntStatusPage";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.newHuntWizard.newHuntWizard");goog.module.declareLegacyNamespace();const {ConfigureFlowPageDirective}=goog.require("grrUi.hunt.newHuntWizard.configureFlowPageDirective");const {ConfigureHuntPageDirective}=goog.require("grrUi.hunt.newHuntWizard.configureHuntPageDirective");const {ConfigureOutputPluginsPageDirective}=goog.require("grrUi.hunt.newHuntWizard.configureOutputPluginsPageDirective");const {ConfigureRulesPageDirective}=
goog.require("grrUi.hunt.newHuntWizard.configureRulesPageDirective");const {CopyFormDirective}=goog.require("grrUi.hunt.newHuntWizard.copyFormDirective");const {CreateHuntFromFlowFormDirective}=goog.require("grrUi.hunt.newHuntWizard.createHuntFromFlowFormDirective");const {FormDirective}=goog.require("grrUi.hunt.newHuntWizard.formDirective");const {ReviewPageDirective}=goog.require("grrUi.hunt.newHuntWizard.reviewPageDirective");const {StatusPageDirective}=goog.require("grrUi.hunt.newHuntWizard.statusPageDirective");
const {coreModule}=goog.require("grrUi.core.core");exports.newHuntWizardModule=angular.module("grrUi.hunt.newHuntWizard",["ui.bootstrap",coreModule.name]);exports.newHuntWizardModule.directive(ConfigureFlowPageDirective.directive_name,ConfigureFlowPageDirective);exports.newHuntWizardModule.directive(ConfigureHuntPageDirective.directive_name,ConfigureHuntPageDirective);exports.newHuntWizardModule.directive(ConfigureOutputPluginsPageDirective.directive_name,ConfigureOutputPluginsPageDirective);exports.newHuntWizardModule.directive(ConfigureRulesPageDirective.directive_name,
ConfigureRulesPageDirective);exports.newHuntWizardModule.directive(ReviewPageDirective.directive_name,ReviewPageDirective);exports.newHuntWizardModule.directive(StatusPageDirective.directive_name,StatusPageDirective);exports.newHuntWizardModule.directive(CopyFormDirective.directive_name,CopyFormDirective);exports.newHuntWizardModule.directive(FormDirective.directive_name,FormDirective);exports.newHuntWizardModule.directive(CreateHuntFromFlowFormDirective.directive_name,CreateHuntFromFlowFormDirective);
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.hunt.hunt");goog.module.declareLegacyNamespace();const {HuntClientsDirective}=goog.require("grrUi.hunt.huntClientsDirective");const {HuntContextDirective}=goog.require("grrUi.hunt.huntContextDirective");const {HuntCrashesDirective}=goog.require("grrUi.hunt.huntCrashesDirective");const {HuntErrorsDirective}=goog.require("grrUi.hunt.huntErrorsDirective");const {HuntGraphDirective}=goog.require("grrUi.hunt.huntGraphDirective");const {HuntInspectorDirective}=
goog.require("grrUi.hunt.huntInspectorDirective");const {HuntLogDirective}=goog.require("grrUi.hunt.huntLogDirective");const {HuntOverviewDirective}=goog.require("grrUi.hunt.huntOverviewDirective");const {HuntResultsDirective}=goog.require("grrUi.hunt.huntResultsDirective");const {HuntStatsDirective}=goog.require("grrUi.hunt.huntStatsDirective");const {HuntStatusIconDirective}=goog.require("grrUi.hunt.huntStatusIconDirective");const {HuntsListDirective}=goog.require("grrUi.hunt.huntsListDirective");
const {HuntsViewDirective}=goog.require("grrUi.hunt.huntsViewDirective");const {ModifyHuntDialogDirective}=goog.require("grrUi.hunt.modifyHuntDialogDirective");const {RapidHuntStatusDirective}=goog.require("grrUi.hunt.rapidHuntStatusDirective");const {coreModule}=goog.require("grrUi.core.core");const {newHuntWizardModule}=goog.require("grrUi.hunt.newHuntWizard.newHuntWizard");exports.huntModule=angular.module("grrUi.hunt",["ui.bootstrap",coreModule.name,newHuntWizardModule.name]);exports.huntModule.directive(HuntClientsDirective.directive_name,
HuntClientsDirective);exports.huntModule.directive(HuntContextDirective.directive_name,HuntContextDirective);exports.huntModule.directive(HuntCrashesDirective.directive_name,HuntCrashesDirective);exports.huntModule.directive(HuntErrorsDirective.directive_name,HuntErrorsDirective);exports.huntModule.directive(HuntGraphDirective.directive_name,HuntGraphDirective);exports.huntModule.directive(HuntInspectorDirective.directive_name,HuntInspectorDirective);exports.huntModule.directive(HuntLogDirective.directive_name,
HuntLogDirective);exports.huntModule.directive(HuntOverviewDirective.directive_name,HuntOverviewDirective);exports.huntModule.directive(HuntResultsDirective.directive_name,HuntResultsDirective);exports.huntModule.directive(HuntStatusIconDirective.directive_name,HuntStatusIconDirective);exports.huntModule.directive(HuntStatsDirective.directive_name,HuntStatsDirective);exports.huntModule.directive(HuntsListDirective.directive_name,HuntsListDirective);exports.huntModule.directive(HuntsViewDirective.directive_name,
HuntsViewDirective);exports.huntModule.directive(ModifyHuntDialogDirective.directive_name,ModifyHuntDialogDirective);exports.huntModule.directive(RapidHuntStatusDirective.directive_name,RapidHuntStatusDirective);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.local.local");goog.module.declareLegacyNamespace();exports.localModule=angular.module("grrUi.local",[]);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.outputPlugins.outputPluginLogsDirective");goog.module.declareLegacyNamespace();const OutputPluginLogsController=function($scope,$uibModal,grrApiService){this.scope_=$scope;this.uibModal_=$uibModal;this.grrApiService_=grrApiService;this.itemsCount;this.scope_.$watch("url",this.onUrlChange_.bind(this))};OutputPluginLogsController.prototype.onUrlChange_=function(newValue){if(angular.isDefined(newValue))this.grrApiService_.get(newValue,
{count:1}).then(function(response){this.itemsCount=response["data"]["total_count"]}.bind(this))};OutputPluginLogsController.prototype.onClick=function(){this.uibModal_.open({templateUrl:"/static/angular-components/output-plugins/"+"output-plugin-logs-modal.html",scope:this.scope_,windowClass:"wide-modal high-modal",size:"lg"})};exports.OutputPluginLogsDirective=function(){return{scope:{url:"=",label:"@",cssClass:"@",icon:"@"},restrict:"E",templateUrl:"/static/angular-components/output-plugins/"+"output-plugin-logs.html",
controller:OutputPluginLogsController,controllerAs:"controller"}};exports.OutputPluginLogsDirective.directive_name="grrOutputPluginLogs";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.outputPlugins.outputPluginNoteBodyDirective");goog.module.declareLegacyNamespace();const OutputPluginNoteBodyController=function($scope,$compile,$element,grrOutputPluginsDirectivesRegistryService){this.scope_=$scope;this.scope_.outputPlugin;this.compile_=$compile;this.element_=$element;this.grrOutputPluginsDirectivesRegistryService_=grrOutputPluginsDirectivesRegistryService;this.scope_.$watch("outputPlugin",this.onOutputPluginChange_.bind(this))};
OutputPluginNoteBodyController.prototype.camelCaseToDashDelimited=function(directiveName){return directiveName.replace(/([a-z\d])([A-Z])/g,"$1-$2").toLowerCase()};OutputPluginNoteBodyController.prototype.onOutputPluginChange_=function(){if(angular.isDefined(this.scope_["outputPlugin"])){var descriptor=this.scope_["outputPlugin"]["value"]["plugin_descriptor"];var pluginName=descriptor["value"]["plugin_name"]["value"];var directive=this.grrOutputPluginsDirectivesRegistryService_.findDirectiveForMro([pluginName]);
if(angular.isDefined(directive)){var element=angular.element("<span />");element.html("<"+this.camelCaseToDashDelimited(directive.directive_name)+' output-plugin="outputPlugin" />');var template=this.compile_(element);template(this.scope_,function(cloned,opt_scope){this.element_.html("");this.element_.append(cloned)}.bind(this))}else this.element_.html("")}};exports.OutputPluginNoteBodyDirective=function(){return{scope:{outputPlugin:"="},restrict:"E",controller:OutputPluginNoteBodyController,controllerAs:"controller"}};
exports.OutputPluginNoteBodyDirective.directive_name="grrOutputPluginNoteBody";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.outputPlugins.outputPluginNoteDirective");goog.module.declareLegacyNamespace();const OutputPluginNoteController=function($scope,grrOutputPluginsDirectivesRegistryService){this.scope_=$scope;this.scope_.outputPlugin;this.pluginTitle;this.pluginLogsUrl;this.pluginErrorsUrl;this.grrOutputPluginsDirectivesRegistryService_=grrOutputPluginsDirectivesRegistryService;this.scope_.$watchGroup(["outputPlugin","outputPluginsUrl"],this.onOutputPluginChange_.bind(this))};
OutputPluginNoteController.prototype.onOutputPluginChange_=function(){if(angular.isDefined(this.scope_["outputPlugin"])&&angular.isDefined(this.scope_["outputPluginsUrl"])){var descriptor=this.scope_["outputPlugin"]["value"]["plugin_descriptor"];var pluginName=descriptor["value"]["plugin_name"]["value"];var directive=this.grrOutputPluginsDirectivesRegistryService_.findDirectiveForMro([pluginName]);if(angular.isDefined(directive))this.pluginTitle=directive.output_plugin_title;else this.pluginTitle=
pluginName;var logsUrlBase=this.scope_["outputPluginsUrl"]+"/"+this.scope_["outputPlugin"]["value"]["id"]["value"];this.pluginLogsUrl=logsUrlBase+"/logs";this.pluginErrorsUrl=logsUrlBase+"/errors"}};exports.OutputPluginNoteDirective=function(){return{scope:{outputPluginsUrl:"=",outputPlugin:"="},restrict:"E",templateUrl:"/static/angular-components/output-plugins/"+"output-plugin-note.html",controller:OutputPluginNoteController,controllerAs:"controller"}};exports.OutputPluginNoteDirective.directive_name=
"grrOutputPluginNote";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.outputPlugins.outputPluginsNotesDirective");goog.module.declareLegacyNamespace();const OutputPluginsNotesController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.error;this.outputPlugins;this.scope_.$watch("outputPluginsUrl",this.onOutputPluginsUrlChange_.bind(this))};OutputPluginsNotesController.prototype.onOutputPluginsUrlChange_=function(newValue){if(angular.isDefined(newValue))this.grrApiService_.get(newValue).then(function success(response){this.outputPlugins=
response["data"]["items"]}.bind(this),function failure(response){this.error=response["data"]["message"]}.bind(this))};exports.OutputPluginsNotesDirective=function(){return{scope:{outputPluginsUrl:"="},restrict:"E",templateUrl:"/static/angular-components/output-plugins/"+"output-plugins-notes.html",controller:OutputPluginsNotesController,controllerAs:"controller"}};exports.OutputPluginsNotesDirective.directive_name="grrOutputPluginsNotes";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.outputPlugins.outputPlugins");goog.module.declareLegacyNamespace();const {OutputPluginLogsDirective}=goog.require("grrUi.outputPlugins.outputPluginLogsDirective");const {OutputPluginNoteBodyDirective}=goog.require("grrUi.outputPlugins.outputPluginNoteBodyDirective");const {OutputPluginNoteDirective}=goog.require("grrUi.outputPlugins.outputPluginNoteDirective");const {OutputPluginsNotesDirective}=goog.require("grrUi.outputPlugins.outputPluginsNotesDirective");
const {SemanticRegistryService}=goog.require("grrUi.core.semanticRegistryService");const {coreModule}=goog.require("grrUi.core.core");exports.outputPluginsModule=angular.module("grrUi.outputPlugins",[coreModule.name,"ui.bootstrap"]);exports.outputPluginsModule.directive(OutputPluginsNotesDirective.directive_name,OutputPluginsNotesDirective);exports.outputPluginsModule.directive(OutputPluginLogsDirective.directive_name,OutputPluginLogsDirective);exports.outputPluginsModule.directive(OutputPluginNoteDirective.directive_name,
OutputPluginNoteDirective);exports.outputPluginsModule.directive(OutputPluginNoteBodyDirective.directive_name,OutputPluginNoteBodyDirective);exports.outputPluginsModule.service(SemanticRegistryService.output_plugins_service_name,SemanticRegistryService);exports.outputPluginsModule.run(function(grrOutputPluginsDirectivesRegistryService){});return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.sidebar.clientSummaryDirective");goog.module.declareLegacyNamespace();const ClientSummaryController=function($scope,grrApiService,grrTimeService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrTimeService_=grrTimeService;this.approvalReason;this.lastIP;this.crashTime;this.scope_.$watch("client",this.onClientChange_.bind(this))};ClientSummaryController.prototype.onClientChange_=function(){if(!this.scope_["client"])return;
if(this.scope_["client"]["value"]["last_crash_at"]){var currentTimeMs=this.grrTimeService_.getCurrentTimeMs();var crashTime=this.scope_["client"]["value"]["last_crash_at"]["value"];if(angular.isDefined(crashTime)&&currentTimeMs/1E3-crashTime/1E6<60*60*24)this.crashTime=crashTime}var clientId=this.scope_["client"]["value"]["client_id"]["value"];var lastIPUrl="clients/"+clientId+"/last-ip";this.grrApiService_.get(lastIPUrl).then(function(response){this.lastIP=response.data}.bind(this));var approvalUrl=
"users/me/approvals/client/"+clientId;this.grrApiService_.get(approvalUrl).then(function(response){var approvals=response.data["items"];if(approvals&&approvals.length)this.approvalReason=approvals[0]["value"]["reason"]["value"]}.bind(this))};exports.ClientSummaryDirective=function(){return{scope:{client:"="},restrict:"E",templateUrl:"/static/angular-components/sidebar/client-summary.html",controller:ClientSummaryController,controllerAs:"controller"}};exports.ClientSummaryDirective.directive_name=
"grrClientSummary";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.sidebar.clientWarningsDirective");goog.module.declareLegacyNamespace();const checkIfLabelMatchesRule=(label,rule)=>{const labelName=label["value"]["name"]["value"].toLowerCase();return rule["withLabels"].indexOf(labelName)!=-1};const ClientWarningsController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.rules_=[];this.warnings=[];this.grrApiService_.getV2Cached("/config/AdminUI.client_warnings").then(response=>
{const data=response["data"];if(data["value"]){this.rules_=data["value"]["rules"];for(const rule of this.rules_)rule["withLabels"]=rule["withLabels"].map(l=>l.toLowerCase())}}).then(()=>{this.scope_.$watch("client",this.onClientChange_.bind(this))})};ClientWarningsController.prototype.onClientChange_=function(newValue){this.warnings=[];if(angular.isUndefined(newValue)||angular.isUndefined(newValue["value"]["labels"]))return;for(let rule of this.rules_)for(let label of newValue["value"]["labels"])if(checkIfLabelMatchesRule(label,
rule)){this.warnings.push(rule["message"]);break}};exports.ClientWarningsDirective=function(){return{scope:{client:"="},restrict:"E",templateUrl:"/static/angular-components/sidebar/client-warnings.html",controller:ClientWarningsController,controllerAs:"controller"}};exports.ClientWarningsDirective.directive_name="grrClientWarnings";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.sidebar.navDropdownDirective");goog.module.declareLegacyNamespace();exports.NavDropdownController=function(){this.isCollapsed=true};var NavDropdownController=exports.NavDropdownController;exports.NavDropdownDirective=function(){return{scope:{title:"@"},restrict:"A",transclude:true,templateUrl:"/static/angular-components/sidebar/nav-dropdown.html",controller:NavDropdownController,controllerAs:"controller"}};exports.NavDropdownDirective.directive_name=
"grrNavDropdown";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.sidebar.navLinkDirective");goog.module.declareLegacyNamespace();const {NavDropdownController}=goog.require("grrUi.sidebar.navDropdownDirective");const {RoutingService}=goog.require("grrUi.routing.routingService");const NavLinkController=function($scope,$element,grrRoutingService){this.scope_=$scope;this.element_=$element;this.grrRoutingService_=grrRoutingService;this.navDropdownController;this.isActive=false;this.href;this.scope_.$watchGroup(["state",
"params"],this.onStateOrParamsChange_.bind(this));this.grrRoutingService_.onStateChange(this.scope_,this.applyActiveState_.bind(this))};NavLinkController.prototype.onStateOrParamsChange_=function(){this.href="#";if(angular.isDefined(this.scope_["state"]))this.href=this.grrRoutingService_.href(this.scope_["state"],this.scope_["params"])};NavLinkController.prototype.openLink=function(event){event.preventDefault();if(this.scope_["disabled"])return;this.grrRoutingService_.go(this.scope_["state"],this.scope_["params"])};
NavLinkController.prototype.applyActiveState_=function(activeState){this.isActive=activeState===this.scope_["state"];if(this.isActive){this.element_.addClass("active");if(this.navDropdownController)this.navDropdownController.isCollapsed=false}else this.element_.removeClass("active")};exports.NavLinkDirective=function(){return{scope:{state:"@",params:"=?",disabled:"=?"},restrict:"A",require:"?^grrNavDropdown",transclude:true,templateUrl:"/static/angular-components/sidebar/nav-link.html",controller:NavLinkController,
controllerAs:"controller",link:function(scope,elem,attr,navDropdownController){scope.controller.navDropdownController=navDropdownController}}};exports.NavLinkDirective.directive_name="grrNavLink";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.sidebar.navigatorDirective");goog.module.declareLegacyNamespace();const {ApiService,stripTypeInfo}=goog.require("grrUi.core.apiService");const {RoutingService}=goog.require("grrUi.routing.routingService");const NavigatorController=function($scope,grrApiService,grrRoutingService){this.scope_=$scope;this.grrApiService_=grrApiService;this.grrRoutingService_=grrRoutingService;this.client;this.clientId;this.hasClientAccess=false;this.uiTraits;
this.grrApiService_.getCached("users/me").then(function(response){this.uiTraits=stripTypeInfo(response["data"])["interface_traits"]}.bind(this));this.grrRoutingService_.uiOnParamsChanged(this.scope_,"clientId",this.onClientSelectionChange_.bind(this),true)};NavigatorController.prototype.onClientSelectionChange_=function(clientId){if(!clientId)return;if(clientId.indexOf("aff4:/")===0)clientId=clientId.split("/")[1];if(this.clientId===clientId)return;this.clientId=clientId;this.client=null;this.refreshClientDetails();
this.checkClientAccess_()};NavigatorController.prototype.refreshClientDetails=function(){var url="clients/"+this.clientId;this.grrApiService_.get(url).then(this.onClientDetailsFetched_.bind(this))};NavigatorController.prototype.onClientDetailsFetched_=function(response){this.client=response["data"]};NavigatorController.prototype.checkClientAccess_=function(){this.grrApiService_.head("clients/"+this.clientId+"/flows").then(function resolve(){this.hasClientAccess=true}.bind(this),function reject(){this.hasClientAccess=
false}.bind(this))};exports.NavigatorDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/sidebar/navigator.html",controller:NavigatorController,controllerAs:"controller"}};exports.NavigatorDirective.directive_name="grrNavigator";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.sidebar.sidebar");goog.module.declareLegacyNamespace();const {ClientSummaryDirective}=goog.require("grrUi.sidebar.clientSummaryDirective");const {ClientWarningsDirective}=goog.require("grrUi.sidebar.clientWarningsDirective");const {NavDropdownDirective}=goog.require("grrUi.sidebar.navDropdownDirective");const {NavLinkDirective}=goog.require("grrUi.sidebar.navLinkDirective");const {NavigatorDirective}=goog.require("grrUi.sidebar.navigatorDirective");
const {coreModule}=goog.require("grrUi.core.core");exports.sidebarModule=angular.module("grrUi.sidebar",[coreModule.name]);exports.sidebarModule.directive(ClientSummaryDirective.directive_name,ClientSummaryDirective);exports.sidebarModule.directive(ClientWarningsDirective.directive_name,ClientWarningsDirective);exports.sidebarModule.directive(NavDropdownDirective.directive_name,NavDropdownDirective);exports.sidebarModule.directive(NavLinkDirective.directive_name,NavLinkDirective);exports.sidebarModule.directive(NavigatorDirective.directive_name,
NavigatorDirective);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.user.approverInputDirective");goog.module.declareLegacyNamespace();const ApproverInputController=function(grrApiService,$q){this.$q=$q;this.grrApiService_=grrApiService};ApproverInputController.prototype.loadApproverSuggestions=function(input){if(!input)return this.$q.resolve([]);const matches=input.match(/^(.*?)([^,\s]+)$/);if(!matches)return this.$q.resolve([]);const [,prefix,usernameQuery]=matches;const ignore=prefix.split(/\s*,\s*/);
return this.grrApiService_.get("/users/approver-suggestions",{username_query:usernameQuery}).then(res=>res.data["suggestions"].map(suggestion=>suggestion.value.username.value).filter(username=>!ignore.includes(username)).map(username=>({suggestion:prefix+username+", ",username:username})))};exports.ApproverInputDirective=function(){return{restrict:"E",scope:{model:"=ngModel"},templateUrl:"/static/angular-components/user/approver-input.html",controller:ApproverInputController,controllerAs:"controller"}};
exports.ApproverInputDirective.directive_name="grrApproverInput";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.user.userDashboardDirective");goog.module.declareLegacyNamespace();const MAX_SHOWN_CLIENTS=7;const filterOutDuplicateApprovals=function(approvals){const approvalsMap={};for(const item of approvals){const itemKey=item["value"]["subject"]["value"]["client_id"]["value"];const prevApproval=approvalsMap[itemKey];if(prevApproval){const prevApprovalHasPrecedence=prevApproval["value"]["is_valid"]["value"]||!item["value"]["is_valid"]["value"];
if(prevApprovalHasPrecedence)continue}approvalsMap[itemKey]=item}const result=[];for(const item of approvals){const itemKey=item["value"]["subject"]["value"]["client_id"]["value"];const selectedApproval=approvalsMap[itemKey];if(item["value"]["id"]["value"]===selectedApproval["value"]["id"]["value"])result.push(item)}return result};exports.filterOutDuplicateApprovals=filterOutDuplicateApprovals;const UserDashboardController=function($scope,grrApiService,grrRoutingService){this.scope_=$scope;this.grrApiService_=
grrApiService;this.grrRoutingService_=grrRoutingService;this.clientApprovals;this.grrApiService_.get("/users/me/approvals/client",{count:20}).then(r=>this.onClientApprovals_(r));this.grrApiService_.get("/hunts",{count:5,active_within:"31d",created_by:"me"}).then(r=>this.onHunts_(r))};UserDashboardController.prototype.onClientApprovals_=function(response){this.clientApprovals=filterOutDuplicateApprovals(response["data"]["items"]).slice(0,MAX_SHOWN_CLIENTS)};UserDashboardController.prototype.onHunts_=
function(response){this.hunts=response["data"]["items"]};UserDashboardController.prototype.onClientClicked=function(clientId){this.grrRoutingService_.go("client",{clientId:clientId})};UserDashboardController.prototype.onHuntClicked=function(hunt){var huntId=hunt["value"]["urn"]["value"].split("/")[2];this.grrRoutingService_.go("hunts",{huntId:huntId})};exports.UserDashboardDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/user/user-dashboard.html",controller:UserDashboardController,
controllerAs:"controller"}};exports.UserDashboardDirective.directive_name="grrUserDashboard";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.user.userNotificationButtonDirective");goog.module.declareLegacyNamespace();var SECOND=1E3;var FETCH_INTERVAL=10*SECOND;const UserNotificationButtonController=function($scope,$interval,$uibModal,grrApiService){this.scope_=$scope;this.interval_=$interval;this.uibModal_=$uibModal;this.grrApiService_=grrApiService;this.notificationCount=0;this.fetchNotificationCount_();this.interval_(this.fetchNotificationCount_.bind(this),FETCH_INTERVAL)};
UserNotificationButtonController.prototype.fetchNotificationCount_=function(){this.grrApiService_.get("users/me/notifications/pending/count").then(function(response){this.notificationCount=response.data["count"]}.bind(this))};UserNotificationButtonController.prototype.showNotifications=function(){var modalScope=this.scope_.$new();var modalInstance=this.uibModal_.open({template:'<grr-user-notification-dialog close="$close()" />',scope:modalScope,size:"lg"});modalInstance.result.finally(function(){this.notificationCount=
0}.bind(this))};exports.UserNotificationButtonDirective=function(){return{scope:true,restrict:"E",templateUrl:"/static/angular-components/user/user-notification-button.html",controller:UserNotificationButtonController,controllerAs:"controller"}};var UserNotificationButtonDirective=exports.UserNotificationButtonDirective;UserNotificationButtonDirective.directive_name="grrUserNotificationButton";UserNotificationButtonDirective.fetch_interval=FETCH_INTERVAL;return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.user.userNotificationItemDirective");goog.module.declareLegacyNamespace();const {encodeUrlPath,stripTypeInfo}=goog.require("grrUi.core.apiService");const {stripAff4Prefix}=goog.require("grrUi.core.utils");exports.openReference=function(notification,$location){if(!notification["isFileDownload"]&&notification["link"]){$location.path(notification["link"]);return true}else return false};var openReference=exports.openReference;exports.annotateApiNotification=
function(notification){notification["isPending"]=notification["value"]["is_pending"]["value"];if(angular.isDefined(notification["value"]["reference"])){notification["link"]=getLink_(notification);notification["refType"]=notification["value"]["reference"]["value"]["type"]["value"]}};var annotateApiNotification=exports.annotateApiNotification;var getLink_=function(notification){var strippedNotification=stripTypeInfo(notification);if(!strippedNotification["reference"]||!strippedNotification["reference"]["type"])return null;
var reference=strippedNotification["reference"];var referenceType=reference["type"];var referenceDetails=reference[referenceType.toLowerCase()];var urlParameters={};if(referenceType==="CLIENT")return["clients",stripAff4Prefix(referenceDetails["client_id"])].join("/");else if(referenceType==="HUNT"){var huntId=referenceDetails["hunt_id"];return["hunts",huntId].join("/")}else if(referenceType==="CRON"){var cronJobName=referenceDetails["cron_job_id"];return["crons",cronJobName].join("/")}else if(referenceType===
"VFS")return["clients",stripAff4Prefix(referenceDetails["client_id"]),"vfs",encodeUrlPath(stripAff4Prefix(referenceDetails["vfs_path"]))].join("/");else if(referenceType=="FLOW"){var flowId=referenceDetails["flow_id"];return["clients",stripAff4Prefix(referenceDetails["client_id"]),"flows",flowId].join("/")}else if(referenceType==="CLIENT_APPROVAL"){var clientId=stripAff4Prefix(referenceDetails["client_id"]);return["users",referenceDetails["username"],"approvals","client",clientId,referenceDetails["approval_id"]].join("/")}else if(referenceType===
"HUNT_APPROVAL")return["users",referenceDetails["username"],"approvals","hunt",referenceDetails["hunt_id"],referenceDetails["approval_id"]].join("/");else if(referenceType==="CRON_JOB_APPROVAL")return["users",referenceDetails["username"],"approvals","cron-job",referenceDetails["cron_job_id"],referenceDetails["approval_id"]].join("/");return null};const UserNotificationItemController=function($scope,$location){this.scope_=$scope;this.location_=$location;this.scope_.$watch("notification",this.onNotificationChanged_.bind(this))};
UserNotificationItemController.prototype.onNotificationChanged_=function(notification){annotateApiNotification(notification)};UserNotificationItemController.prototype.openReference=function(){if(openReference(this.scope_["notification"],this.location_))this.scope_["close"]()};exports.UserNotificationItemDirective=function(){return{scope:{notification:"=",close:"&"},restrict:"E",templateUrl:"/static/angular-components/user/user-notification-item.html",controller:UserNotificationItemController,controllerAs:"controller"}};
exports.UserNotificationItemDirective.directive_name="grrUserNotificationItem";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.user.userDesktopNotificationsDirective");goog.module.declareLegacyNamespace();const {UserNotificationButtonDirective}=goog.require("grrUi.user.userNotificationButtonDirective");const {annotateApiNotification,openReference}=goog.require("grrUi.user.userNotificationItemDirective");document.addEventListener("DOMContentLoaded",function(){if(typeof Notification!=="undefined"&&Notification.permission!=="granted")Notification.requestPermission()});
var FETCH_INTERVAL=UserNotificationButtonDirective.fetch_interval;var MAX_DISPLAYED_NOTIFICATIONS=2;const UserDesktopNotificationsController=function($scope,$interval,$window,$location,grrApiService,grrTimeService){if(typeof Notification==="undefined")return;this.scope_=$scope;this.interval_=$interval;this.window_=$window;this.location_=$location;this.grrApiService_=grrApiService;this.timeService_=grrTimeService;this.notifications_=[];this.lastTimestamp_=this.timeService_.getCurrentTimeMs()*1E3;this.interval_(this.fetchPendingNotifications_.bind(this),
FETCH_INTERVAL)};UserDesktopNotificationsController.prototype.notify_=function(title,body,tag,opt_onclick){var notification=new Notification(title,{body:body,icon:"static/images/grr_logo_notification.png",tag:tag});notification.onclick=function(){this.window_.focus();notification.close();if(angular.isDefined(opt_onclick))opt_onclick()}.bind(this);this.notifications_.push(notification);if(this.notifications_.length>MAX_DISPLAYED_NOTIFICATIONS)this.notifications_.shift().close();return notification};
UserDesktopNotificationsController.prototype.fetchPendingNotifications_=function(){this.grrApiService_.get("users/me/notifications/pending",{timestamp:this.lastTimestamp_}).then(function(response){var items=response["data"]["items"];if(items.length==0)return;items.sort(function(lhs,rhs){return lhs["value"]["timestamp"]["value"]-rhs["value"]["timestamp"]["value"]});this.lastTimestamp_=items[items.length-1]["value"]["timestamp"]["value"];if(items.length>MAX_DISPLAYED_NOTIFICATIONS)items=items.slice(-MAX_DISPLAYED_NOTIFICATIONS);
for(var i=0;i<items.length;++i){var item=items[i];annotateApiNotification(item);this.notify_("GRR",item["value"]["message"]["value"],"GRR"+item["value"]["timestamp"]["value"],function(){this.grrApiService_.delete("users/me/notifications/pending/"+item["value"]["timestamp"]["value"]);openReference(item,this.location_)}.bind(this))}}.bind(this))};exports.UserDesktopNotificationsDirective=function(){return{scope:true,restrict:"E",controller:UserDesktopNotificationsController,controllerAs:"controller"}};
var UserDesktopNotificationsDirective=exports.UserDesktopNotificationsDirective;UserDesktopNotificationsDirective.directive_name="grrUserDesktopNotifications";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.user.userLabelDirective");goog.module.declareLegacyNamespace();const UserLabelController=function($scope,grrApiService){this.scope_=$scope;this.grrApiService_=grrApiService;this.username;this.error;this.grrApiService_.getCached("users/me").then(function(response){this.username=response.data["value"]["username"]["value"]}.bind(this),function(error){if(error["status"]==403)this.error="Authentication Error";else this.error=error["statusText"]||
"Error"}.bind(this))};exports.UserLabelDirective=function(){return{scope:true,restrict:"E",templateUrl:"/static/angular-components/user/user-label.html",controller:UserLabelController,controllerAs:"controller"}};var UserLabelDirective=exports.UserLabelDirective;UserLabelDirective.directive_name="grrUserLabel";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.user.userNotificationDialogDirective");goog.module.declareLegacyNamespace();const UserNotificationDialogController=function($scope){this.scope_=$scope;this.notificationUrl="users/me/notifications"};exports.UserNotificationDialogDirective=function(){return{scope:{close:"&"},restrict:"E",templateUrl:"/static/angular-components/user/user-notification-dialog.html",controller:UserNotificationDialogController,controllerAs:"controller"}};
exports.UserNotificationDialogDirective.directive_name="grrUserNotificationDialog";return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.user.userSettingsButtonDirective");goog.module.declareLegacyNamespace();const UserSettingsButtonController=function($scope,$uibModal,$timeout,$window,grrApiService){this.scope_=$scope;this.uibModal_=$uibModal;this.timeout_=$timeout;this.window_=$window;this.grrApiService_=grrApiService;this.requestSent;this.done;this.error;this.userSettings};UserSettingsButtonController.prototype.onClick=function(){this.requestSent=false;this.done=
false;this.error=undefined;this.userSettings=undefined;this.grrApiService_.getCached("users/me").then(function(response){this.userSettings=response["data"]["value"]["settings"]}.bind(this));this.uibModal_.open({templateUrl:"/static/angular-components/user/"+"user-settings-button-modal.html",scope:this.scope_})};UserSettingsButtonController.prototype.saveSettings=function(){var newUser={type:"GRRUser",value:{settings:this.userSettings}};this.grrApiService_.post("users/me",newUser,true).then(function success(){this.done=
true;this.timeout_(this.window_.location.reload.bind(this.window_.location),500)}.bind(this),function failure(response){this.done=true;this.error=response.data.message||"Unknown error."}.bind(this));this.requestSent=true};exports.UserSettingsButtonDirective=function(){return{scope:{},restrict:"E",templateUrl:"/static/angular-components/user/"+"user-settings-button.html",controller:UserSettingsButtonController,controllerAs:"controller"}};exports.UserSettingsButtonDirective.directive_name="grrUserSettingsButton";
return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.user.user");goog.module.declareLegacyNamespace();const {ApproverInputDirective}=goog.require("grrUi.user.approverInputDirective");const {UserDashboardDirective}=goog.require("grrUi.user.userDashboardDirective");const {UserDesktopNotificationsDirective}=goog.require("grrUi.user.userDesktopNotificationsDirective");const {UserLabelDirective}=goog.require("grrUi.user.userLabelDirective");const {UserNotificationButtonDirective}=goog.require("grrUi.user.userNotificationButtonDirective");
const {UserNotificationDialogDirective}=goog.require("grrUi.user.userNotificationDialogDirective");const {UserNotificationItemDirective}=goog.require("grrUi.user.userNotificationItemDirective");const {UserSettingsButtonDirective}=goog.require("grrUi.user.userSettingsButtonDirective");const {coreModule}=goog.require("grrUi.core.core");const {formsModule}=goog.require("grrUi.forms.forms");exports.userModule=angular.module("grrUi.user",[coreModule.name,formsModule.name]);exports.userModule.directive(ApproverInputDirective.directive_name,
ApproverInputDirective);exports.userModule.directive(UserDashboardDirective.directive_name,UserDashboardDirective);exports.userModule.directive(UserDesktopNotificationsDirective.directive_name,UserDesktopNotificationsDirective);exports.userModule.directive(UserLabelDirective.directive_name,UserLabelDirective);exports.userModule.directive(UserNotificationButtonDirective.directive_name,UserNotificationButtonDirective);exports.userModule.directive(UserNotificationDialogDirective.directive_name,UserNotificationDialogDirective);
exports.userModule.directive(UserNotificationItemDirective.directive_name,UserNotificationItemDirective);exports.userModule.directive(UserSettingsButtonDirective.directive_name,UserSettingsButtonDirective);return exports});goog.loadModule(function(exports){"use strict";goog.module("grrUi.appController");goog.module.declareLegacyNamespace();const templatesModule=goog.require("grrUi.templates.templates.templatesModule");const {aclModule}=goog.require("grrUi.acl.acl");const {artifactModule}=goog.require("grrUi.artifact.artifact");const {clientModule}=goog.require("grrUi.client.client");const {configModule}=goog.require("grrUi.config.config");const {coreModule}=goog.require("grrUi.core.core");const {cronModule}=goog.require("grrUi.cron.cron");
const {docsModule}=goog.require("grrUi.docs.docs");const {flowModule}=goog.require("grrUi.flow.flow");const {formsModule}=goog.require("grrUi.forms.forms");const {huntModule}=goog.require("grrUi.hunt.hunt");const {localModule}=goog.require("grrUi.local.local");const {outputPluginsModule}=goog.require("grrUi.outputPlugins.outputPlugins");const {routingModule}=goog.require("grrUi.routing.routing");const {semanticModule}=goog.require("grrUi.semantic.semantic");const {sidebarModule}=goog.require("grrUi.sidebar.sidebar");
const {statsModule}=goog.require("grrUi.stats.stats");const {userModule}=goog.require("grrUi.user.user");exports.appControllerModule=angular.module("grrUi.appController",[aclModule.name,artifactModule.name,clientModule.name,configModule.name,coreModule.name,cronModule.name,docsModule.name,flowModule.name,formsModule.name,huntModule.name,localModule.name,outputPluginsModule.name,routingModule.name,semanticModule.name,statsModule.name,sidebarModule.name,templatesModule.name,userModule.name]);window.grrInterceptedJSErrors_=
[];window.grrInterceptedHTTPErrors_=[];exports.appControllerModule.config(function($httpProvider,$interpolateProvider,$qProvider,$locationProvider,$rootScopeProvider,$provide){$interpolateProvider.startSymbol("{$");$interpolateProvider.endSymbol("$}");$httpProvider.defaults.headers.post["Content-Type"]="application/x-www-form-urlencoded";$httpProvider.interceptors.push(function($q){return{responseError:function(rejection){if([400,403,404].indexOf(rejection["status"])===-1)window.grrInterceptedHTTPErrors_.push(rejection);
return $q.reject(rejection)}}});$qProvider.errorOnUnhandledRejections(false);$locationProvider.hashPrefix("");$rootScopeProvider.digestTtl(50);$provide.decorator("$exceptionHandler",function($delegate){return function(exception,cause){window.grrInterceptedJSErrors_.push(exception.stack||exception.toString());$delegate(exception,cause)}})});exports.appControllerModule.run(function($injector,$http,$cookies,grrFirebaseService,grrReflectionService){$http.defaults.headers.post["X-CSRFToken"]=$cookies.get("csrftoken");
$http.defaults.headers.delete=$http.defaults.headers.patch={"X-CSRFToken":$cookies.get("csrftoken")};grrFirebaseService.setupIfNeeded();grrReflectionService.getRDFValueDescriptor("ACLToken")});$["jstree"]["_themes"]="/static/third-party/jstree/themes/";jQuery["migrateMute"]=true;exports.appControllerModule.controller("GrrUiAppController",function(){});return exports});
//# sourceMappingURL=grr-ui.bundle.js.map