// Domain Public by Eric Wendelin http://eriwen.com/ (2008)
//                  Luke Smith http://lucassmith.name/ (2008)
//                  Loic Dachary <loic@dachary.org> (2008)
//                  Johan Euphrosine <proppy@aminche.com> (2008)
//                  Oyvind Sean Kinsey http://kinsey.no/blog (2010)
//                  Victor Homyakov <victor-homyakov@users.sourceforge.net> (2010)

/**
 * Main function giving a function stack trace with a forced or passed in Error
 *
 * @cfg {Error} e The error to create a stacktrace from (optional)
 * @cfg {Boolean} guess If we should try to resolve the names of anonymous functions
 * @return {Array} of Strings with functions, lines, files, and arguments where possible
 */
function printStackTrace(options) {
   options = options || { guess: true };
   var ex = options.e || null, guess = !!options.guess;
   var p = new printStackTrace.implementation(), result = p.run(ex);
   return (guess) ? p.guessAnonymousFunctions(result) : result;
}

printStackTrace.implementation = function () {
};

printStackTrace.implementation.prototype = {
   /**
    * @param {Error} ex The error to create a stacktrace from (optional)
    * @param {String} mode Forced mode (optional, mostly for unit tests)
    */
   run: function (ex, mode) {
      ex = ex || this.createException();
      // examine exception properties w/o debugger
      //for (var prop in ex) {alert("Ex['" + prop + "']=" + ex[prop]);}
      mode = mode || this.mode(ex);
      if (mode === 'other') {
         return this.other(arguments.callee);
      } else {
         return this[mode](ex);
      }
   },

   createException: function () {
      try {
         this.undef();
      } catch (e) {
         return e;
      }
   },

   /**
    * Mode could differ for different exception, e.g.
    * exceptions in Chrome may or may not have arguments or stack.
    *
    * @return {String} mode of operation for the exception
    */
   mode: function (e) {
      if (e['arguments'] && e.stack) {
         return 'chrome';
      } else if (e.stack && e.sourceURL) {
         return 'safari';
      } else if (typeof e.message === 'string' && typeof window !== 'undefined' && window.opera) {
         // e.message.indexOf("Backtrace:") > -1 -> opera
         // !e.stacktrace -> opera
         if (!e.stacktrace) {
            return 'opera9'; // use e.message
         }
         // 'opera#sourceloc' in e -> opera9, opera10a
         if (e.message.indexOf('\n') > -1 && e.message.split('\n').length > e.stacktrace.split('\n').length) {
            return 'opera9'; // use e.message
         }
         // e.stacktrace && !e.stack -> opera10a
         if (!e.stack) {
            return 'opera10a'; // use e.stacktrace
         }
         // e.stacktrace && e.stack -> opera10b
         if (e.stacktrace.indexOf("called from line") < 0) {
            return 'opera10b'; // use e.stacktrace, format differs from 'opera10a'
         }
         // e.stacktrace && e.stack -> opera11
         return 'opera11'; // use e.stacktrace, format differs from 'opera10a', 'opera10b'
      } else if (e.stack) {
         return 'firefox';
      }
      return 'other';
   },

   /**
    * Given a context, function name, and callback function, overwrite it so that it calls
    * printStackTrace() first with a callback and then runs the rest of the body.
    *
    * @param {Object} context of execution (e.g. window)
    * @param {String} functionName to instrument
    * @param {Function} function to call with a stack trace on invocation
    */
   instrumentFunction: function (context, functionName, callback) {
      context = context || window;
      var original = context[functionName];
      context[functionName] = function instrumented() {
         callback.call(this, printStackTrace().slice(4));
         return context[functionName]._instrumented.apply(this, arguments);
      };
      context[functionName]._instrumented = original;
   },

   /**
    * Given a context and function name of a function that has been
    * instrumented, revert the function to it's original (non-instrumented)
    * state.
    *
    * @param {Object} context of execution (e.g. window)
    * @param {String} functionName to de-instrument
    */
   deinstrumentFunction: function (context, functionName) {
      if (context[functionName].constructor === Function &&
              context[functionName]._instrumented &&
              context[functionName]._instrumented.constructor === Function) {
         context[functionName] = context[functionName]._instrumented;
      }
   },

   /**
    * Given an Error object, return a formatted Array based on Chrome's stack string.
    *
    * @param e - Error object to inspect
    * @return Array<String> of function calls, files and line numbers
    */
   chrome: function (e) {
      var stack = (e.stack + '\n').replace(/^\S[^\(]+?[\n$]/gm, '').
        replace(/^\s+(at eval )?at\s+/gm, '').
        replace(/^([^\(]+?)([\n$])/gm, '{anonymous}()@$1$2').
        replace(/^Object.<anonymous>\s*\(([^\)]+)\)/gm, '{anonymous}()@$1').split('\n');
      stack.pop();
      return stack;
   },

   /**
    * Given an Error object, return a formatted Array based on Safari's stack string.
    *
    * @param e - Error object to inspect
    * @return Array<String> of function calls, files and line numbers
    */
   safari: function (e) {
      return e.stack.replace(/\[native code\]\n/m, '').replace(/^@/gm, '{anonymous}()@').split('\n');
   },

   /**
    * Given an Error object, return a formatted Array based on Firefox's stack string.
    *
    * @param e - Error object to inspect
    * @return Array<String> of function calls, files and line numbers
    */
   firefox: function (e) {
      return e.stack.replace(/(?:\n@:0)?\s+$/m, '').replace(/^[\(@]/gm, '{anonymous}()@').split('\n');
   },

   opera11: function (e) {
      var ANON = '{anonymous}', lineRE = /^.*line (\d+), column (\d+)(?: in (.+))? in (\S+):$/;
      var lines = e.stacktrace.split('\n'), result = [];

      for (var i = 0, len = lines.length; i < len; i += 2) {
         var match = lineRE.exec(lines[i]);
         if (match) {
            var location = match[4] + ':' + match[1] + ':' + match[2];
            var fnName = match[3] || "global code";
            fnName = fnName.replace(/<anonymous function: (\S+)>/, "$1").replace(/<anonymous function>/, ANON);
            result.push(fnName + '@' + location + ' -- ' + lines[i + 1].replace(/^\s+/, ''));
         }
      }

      return result;
   },

   opera10b: function (e) {
      // "<anonymous function: run>([arguments not available])@file://localhost/G:/js/stacktrace.js:27\n" +
      // "printStackTrace([arguments not available])@file://localhost/G:/js/stacktrace.js:18\n" +
      // "@file://localhost/G:/js/test/functional/testcase1.html:15"
      var lineRE = /^(.*)@(.+):(\d+)$/;
      var lines = e.stacktrace.split('\n'), result = [];

      for (var i = 0, len = lines.length; i < len; i++) {
         var match = lineRE.exec(lines[i]);
         if (match) {
            var fnName = match[1] ? (match[1] + '()') : "global code";
            result.push(fnName + '@' + match[2] + ':' + match[3]);
         }
      }

      return result;
   },

   /**
    * Given an Error object, return a formatted Array based on Opera 10's stacktrace string.
    *
    * @param e - Error object to inspect
    * @return Array<String> of function calls, files and line numbers
    */
   opera10a: function (e) {
      // "  Line 27 of linked script file://localhost/G:/js/stacktrace.js\n"
      // "  Line 11 of inline#1 script in file://localhost/G:/js/test/functional/testcase1.html: In function foo\n"
      var ANON = '{anonymous}', lineRE = /Line (\d+).*script (?:in )?(\S+)(?:: In function (\S+))?$/i;
      var lines = e.stacktrace.split('\n'), result = [];

      for (var i = 0, len = lines.length; i < len; i += 2) {
         var match = lineRE.exec(lines[i]);
         if (match) {
            var fnName = match[3] || ANON;
            result.push(fnName + '()@' + match[2] + ':' + match[1] + ' -- ' + lines[i + 1].replace(/^\s+/, ''));
         }
      }

      return result;
   },

   // Opera 7.x-9.2x only!
   opera9: function (e) {
      // "  Line 43 of linked script file://localhost/G:/js/stacktrace.js\n"
      // "  Line 7 of inline#1 script in file://localhost/G:/js/test/functional/testcase1.html\n"
      var ANON = '{anonymous}', lineRE = /Line (\d+).*script (?:in )?(\S+)/i;
      var lines = e.message.split('\n'), result = [];

      for (var i = 2, len = lines.length; i < len; i += 2) {
         var match = lineRE.exec(lines[i]);
         if (match) {
            result.push(ANON + '()@' + match[2] + ':' + match[1] + ' -- ' + lines[i + 1].replace(/^\s+/, ''));
         }
      }

      return result;
   },

   // Safari 5-, IE 9-, and others
   other: function (curr) {
      var ANON = '{anonymous}', fnRE = /function\s*([\w\-$]+)?\s*\(/i, stack = [], fn, args, maxStackSize = 10;
      while (curr && curr['arguments'] && stack.length < maxStackSize) {
         fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON;
         args = Array.prototype.slice.call(curr['arguments'] || []);
         stack[stack.length] = fn + '(' + this.stringifyArguments(args) + ')';
         curr = curr.caller;
      }
      return stack;
   },

   /**
    * Given arguments array as a String, subsituting type names for non-string types.
    *
    * @param {Arguments} args
    * @return {Array} of Strings with stringified arguments
    */
   stringifyArguments: function (args) {
      var result = [];
      var slice = Array.prototype.slice;
      for (var i = 0; i < args.length; ++i) {
         var arg = args[i];
         if (arg === undefined) {
            result[i] = 'undefined';
         } else if (arg === null) {
            result[i] = 'null';
         } else if (arg.constructor) {
            if (arg.constructor === Array) {
               if (arg.length < 3) {
                  result[i] = '[' + this.stringifyArguments(arg) + ']';
               } else {
                  result[i] = '[' + this.stringifyArguments(slice.call(arg, 0, 1)) + '...' + this.stringifyArguments(slice.call(arg, -1)) + ']';
               }
            } else if (arg.constructor === Object) {
               result[i] = '#object';
            } else if (arg.constructor === Function) {
               result[i] = '#function';
            } else if (arg.constructor === String) {
               result[i] = '"' + arg + '"';
            } else if (arg.constructor === Number) {
               result[i] = arg;
            }
         }
      }
      return result.join(',');
   },

   sourceCache: {},

   /**
    * @return the text from a given URL
    */
   ajax: function (url) {
      var req = this.createXMLHTTPObject();
      if (req) {
         try {
            req.open('GET', url, false);
            //req.overrideMimeType('text/plain');
            //req.overrideMimeType('text/javascript');
            req.send(null);
            //return req.status == 200 ? req.responseText : '';
            return req.responseText;
         } catch (e) {
         }
      }
      return '';
   },

   /**
    * Try XHR methods in order and store XHR factory.
    *
    * @return <Function> XHR function or equivalent
    */
   createXMLHTTPObject: function () {
      var xmlhttp, XMLHttpFactories = [
          function () {
             return new XMLHttpRequest();
          }, function () {
             return new ActiveXObject('Msxml2.XMLHTTP');
          }, function () {
             return new ActiveXObject('Msxml3.XMLHTTP');
          }, function () {
             return new ActiveXObject('Microsoft.XMLHTTP');
          }
      ];
      for (var i = 0; i < XMLHttpFactories.length; i++) {
         try {
            xmlhttp = XMLHttpFactories[i]();
            // Use memoization to cache the factory
            this.createXMLHTTPObject = XMLHttpFactories[i];
            return xmlhttp;
         } catch (e) {
         }
      }
   },

   /**
    * Given a URL, check if it is in the same domain (so we can get the source
    * via Ajax).
    *
    * @param url <String> source url
    * @return False if we need a cross-domain request
    */
   isSameDomain: function (url) {
      return typeof location !== "undefined" && url.indexOf(location.hostname) !== -1; // location may not be defined, e.g. when running from nodejs.
   },

   /**
    * Get source code from given URL if in the same domain.
    *
    * @param url <String> JS source URL
    * @return <Array> Array of source code lines
    */
   getSource: function (url) {
      // TODO reuse source from script tags?
      if (!(url in this.sourceCache)) {
         this.sourceCache[url] = this.ajax(url).split('\n');
      }
      return this.sourceCache[url];
   },

   guessAnonymousFunctions: function (stack) {
      for (var i = 0; i < stack.length; ++i) {
         var reStack = /\{anonymous\}\(.*\)@(.*)/,
             reRef = /^(.*?)(?::(\d+))(?::(\d+))?(?: -- .+)?$/,
             frame = stack[i], ref = reStack.exec(frame);

         if (ref) {
            var m = reRef.exec(ref[1]);
            if (m) { // If falsey, we did not get any file/line information
               var file = m[1], lineno = m[2], charno = m[3] || 0;
               if (file && this.isSameDomain(file) && lineno) {
                  var functionName = this.guessAnonymousFunction(file, lineno, charno);
                  stack[i] = frame.replace('{anonymous}', functionName);
               }
            }
         }
      }
      return stack;
   },

   guessAnonymousFunction: function (url, lineNo, charNo) {
      var ret;
      try {
         ret = this.findFunctionName(this.getSource(url), lineNo);
      } catch (e) {
         ret = 'getSource failed with url: ' + url + ', exception: ' + e.toString();
      }
      return ret;
   },

   findFunctionName: function (source, lineNo) {
      // FIXME findFunctionName fails for compressed source
      // (more than one function on the same line)
      // TODO use captured args
      // function {name}({args}) m[1]=name m[2]=args
      var reFunctionDeclaration = /function\s+([^(]*?)\s*\(([^)]*)\)/;
      // {name} = function ({args}) TODO args capture
      // /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*function(?:[^(]*)/
      var reFunctionExpression = /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*function\b/;
      // {name} = eval()
      var reFunctionEvaluation = /['"]?([0-9A-Za-z_]+)['"]?\s*[:=]\s*(?:eval|new Function)\b/;
      // Walk backwards in the source lines until we find
      // the line which matches one of the patterns above
      var code = "", line, maxLines = Math.min(lineNo, 20), m, commentPos;
      for (var i = 0; i < maxLines; ++i) {
         // lineNo is 1-based, source[] is 0-based
         line = source[lineNo - i - 1];
         commentPos = line.indexOf('//');
         if (commentPos >= 0) {
            line = line.substr(0, commentPos);
         }
         // TODO check other types of comments? Commented code may lead to false positive
         if (line) {
            code = line + code;
            m = reFunctionExpression.exec(code);
            if (m && m[1]) {
               return m[1];
            }
            m = reFunctionDeclaration.exec(code);
            if (m && m[1]) {
               //return m[1] + "(" + (m[2] || "") + ")";
               return m[1];
            }
            m = reFunctionEvaluation.exec(code);
            if (m && m[1]) {
               return m[1];
            }
         }
      }
      return '(?)';
   }
};window.decodeURIComponent=(function(f){return function(URIComponent){try{return f.call(this,URIComponent.replace(/\+/g," "))}catch(exception){if(!(exception instanceof URIError)){throw exception;}if('console'in window&&'log'in console){console.log('decodeURIComponent error, falling back to exceptionless decoder so site still runs',exception,URIComponent)}var decodeURIComponentAlternative=function(str){str=str.replace(/%([EF][0-9A-F])%([89AB][0-9A-F])%([89AB][0-9A-F])/g,function(code,hex1,hex2,hex3){var n1=parseInt(hex1,16)-0xE0;var n2=parseInt(hex2,16)-0x80;if(n1==0&&n2<32){return code}var n3=parseInt(hex3,16)-0x80;var n=(n1<<12)+(n2<<6)+n3;if(n>0xFFFF){return code}return String.fromCharCode(n)});str=str.replace(/%([CD][0-9A-F])%([89AB][0-9A-F])/g,function(code,hex1,hex2){var n1=parseInt(hex1,16)-0xC0;if(n1<2){return code}var n2=parseInt(hex2,16)-0x80;return String.fromCharCode((n1<<6)+n2)});str=str.replace(/%([0-7][0-9A-F])/g,function(code,hex){return String.fromCharCode(parseInt(hex,16))});return str};return decodeURIComponentAlternative(URIComponent)}}})(window.decodeURIComponent);if(!Object.keys){Object.keys=(function(){'use strict';var hasOwnProperty=Object.prototype.hasOwnProperty,hasDontEnumBug=!({toString:null}).propertyIsEnumerable('toString'),dontEnums=['toString','toLocaleString','valueOf','hasOwnProperty','isPrototypeOf','propertyIsEnumerable','constructor'],dontEnumsLength=dontEnums.length;return function(obj){if(typeof obj!=='object'&&(typeof obj!=='function'||obj===null)){throw new TypeError('Object.keys called on non-object');}var result=[],prop,i;for(prop in obj){if(hasOwnProperty.call(obj,prop)){result.push(prop)}}if(hasDontEnumBug){for(i=0;i<dontEnumsLength;i++){if(hasOwnProperty.call(obj,dontEnums[i])){result.push(dontEnums[i])}}}return result}}())}if(!Object.freeze){Object.freeze=function(o){return o}}if(typeof Object.create!='function'){Object.create=(function(){function Temp(){}var hasOwn=Object.prototype.hasOwnProperty;return function(O){if(typeof O!='object'){throw TypeError('Object prototype may only be an Object or null');}Temp.prototype=O;var obj=new Temp;Temp.prototype=null;if(arguments.length>1){var Properties=Object(arguments[1]);for(var prop in Properties){if(hasOwn.call(Properties,prop)){obj[prop]=Properties[prop]}}}return obj}})()}var __extends=this.__extends||function(d,b){function __(){this.constructor=d}__.prototype=b.prototype;d.prototype=new __};function Observable(){}Observable.prototype={Observe:(function(){var _observedValues={};var noid={};return function(id){var callbacks,method,topic;id=id||noid;topic=_observedValues[id];if(!topic){callbacks=jQuery.Callbacks();topic={update:callbacks.fire,subscribe:callbacks.add,unsubscribe:callbacks.remove};_observedValues[id]=topic}return topic}})()};if(!Array.prototype.find){Object.defineProperty(Array.prototype,'find',{value:function(predicate){if(this==null){throw TypeError('"this" is null or not defined');}var o=Object(this);var len=o.length>>>0;if(typeof predicate!=='function'){throw TypeError('predicate must be a function');}var thisArg=arguments[1];var k=0;while(k<len){var kValue=o[k];if(predicate.call(thisArg,kValue,k,o)){return kValue}k++}return undefined},configurable:true,writable:true})}(function(){if(typeof window.CustomEvent==="function")return false;function CustomEvent(event,params){params=params||{bubbles:false,cancelable:false,detail:undefined};var evt=document.createEvent('CustomEvent');evt.initCustomEvent(event,params.bubbles,params.cancelable,params.detail);return evt}CustomEvent.prototype=window.Event.prototype;window.CustomEvent=CustomEvent})();(function(){var beforePrint=new CustomEvent("beforePrint",{bubbles:true,cancelable:false});var afterPrint=new CustomEvent("afterPrint",{bubbles:true,cancelable:false});if('onafterprint'in window){window.onafterprint=function(){document.dispatchEvent(afterPrint)}}if('onbeforeprint'in window){window.onbeforeprint=function(){document.dispatchEvent(beforePrint)}}else{if(window.matchMedia){var mediaQueryList=window.matchMedia('print');mediaQueryList.addListener(function(mql){if(mql.matches){document.dispatchEvent(beforePrint)}else{document.dispatchEvent(afterPrint)}})}}}());var AblConstants=Object.freeze({Enums:{_AblDebug:{NoDebug:0,Reload:1,Results:2,Client:4,OutputXml:256,OutputLXml:512,_XmlMask:768,ClearResolveCache:1024,HttpCache:2048,KeepUrl:65536,All:-1,_DebugMask:255,True:255},_AblOutput:{Normal:0,Text:1,Txt:1,Xml:2,LXml:3,FinalXml:4,Record:5,Json:6,JsonDebug:7,Rec:5,Raw:5},_AblClient:{NoOptions:0,NoRctxInherit:1}}});var ABL=ABL||{};$("html").removeClass("progressive");(function(undefined){var idx=-1;var code=[38,38,40,40,37,39,37,39,66,65];var oldBodyContents;var backShowing=false;var busy=false;var crappyBrowser=!(Modernizr.csstransforms3d&&Modernizr.csstransitions&&Modernizr.opacity);function addPrefixedCss($el,prop,css,prefixCss){var result={};result[prop]=css;result["-webkit-"+prop]=(prefixCss?"-webkit-":"")+css;result["-moz-"+prop]=(prefixCss?"-moz-":"")+css;result["-o-"+prop]=(prefixCss?"-o-":"")+css;$el.css(result)}function doFlip(){if(busy){return}if(crappyBrowser){if($.browser.opera){alert("Congratulations! You have entered the Konami code. Peace.")}else{alert("Congratulations! You have entered the Konami code in a crappy browser. Go upgrade. Peace.")}return}busy=true;var $body=$("body");var $html=$("html");if(backShowing){if(window.location.hash==="#credits"){window.location.hash=""}}else if(window.location.hash===""){window.location.hash="#credits"}var $credits=$("#credits");if(!$credits||!$credits.size()){ABL.Log('too bad, no credits element found');busy=false;return false}var t=700;addPrefixedCss($body,"transition","transform "+t+"ms ease-in",true);if(backShowing){addPrefixedCss($body,"transform","rotateY(270deg)")}else{addPrefixedCss($body,"transition","transform "+0+"ms ease-in",true);addPrefixedCss($body,"transform","rotateY(1deg)");setTimeout(function(){addPrefixedCss($body,"transition","transform "+t+"ms ease-in",true);addPrefixedCss($body,"transform","rotateY(90deg)")},1)}setTimeout(function(){if(backShowing){$credits.hide();$('.skip-to-content-wrapper').show()}else{$credits.show();var height=document.height||document.documentElement.clientHeight;if($credits.height()<height){$credits.height(height)}$('.skip-to-content-wrapper').hide();$body.scrollTop(0);$html.scrollTop(0)}setTimeout(function(){addPrefixedCss($body,"transition","transform "+t+"ms ease-out",true);if(backShowing){addPrefixedCss($body,"transform","rotateY(360deg)")}else{addPrefixedCss($body,"transform","rotateY(180deg)")}setTimeout(function(){if(backShowing){addPrefixedCss($body,"transition","none");addPrefixedCss($body,"transform","rotateY(0deg)")}backShowing=!backShowing;busy=false;codeReset()},t)},0)},t)}function codeEntered(){if(busy){return}var $html=$("html");addPrefixedCss($html,"transform-style","preserve-3d");addPrefixedCss($html,"perspective","2000px");if($("#credits").size()){setTimeout(function(){doFlip()},0);return}$.ajax('~/credits/').done(function(data){setTimeout(function(){if(!$("#credits").size()){$("body").prepend(data);$("#credits").find("#exit").on("click",codeEntered)}doFlip()},0)})}function codeReset(){idx=-1}$(document).on("keydown",function(e){if(idx<code.length){if(e.keyCode===27&&backShowing){codeEntered()}else if(code[idx+1]===e.keyCode){idx+=1;if(idx==code.length-1){codeEntered()}}else{idx=-1}}});if("onhashchange"in window&&'addEventListener'in window){window.addEventListener("hashchange",function(e){if(window.location.hash==="#credits"){codeEntered()}else if(backShowing){codeEntered()}},false)}if(!crappyBrowser&&window.location.hash==="#credits"){$(codeEntered)}})();$(document).ajaxError(function(event,xhr,settings,exception){var msg,stacktrace,error;ABL.Log('AjaxError:',event,xhr,settings,exception);if(!ABL){if(exception){throw exception;}else{throw new Error(" ABL object doesn't exist, and I got an ajax error.");}}settings=settings||{};if(exception==='abort'){ABL.Log('Abort! A new global AJAX request was fired, so the previous one is aborted');return true}if(typeof exception==='object'){msg=exception.msg||exception.message||"Ajax Error with status "+xhr.status;msg+=" - url is "+settings.url;stacktrace=exception.stack}else if(typeof exception==='string'){msg="Ajax Error "+exception+" - url is "+settings.url}if(!msg){msg="Ajax Error with status "+xhr.status+" - url is "+settings.url}LoadingIndicator.showError(settings.url);ABL.LogError(msg,stacktrace);try{if(Userstats.active){var errorTime=event.timeStamp||Date.now();var errorUrl=settings.url||(('target'in event&&'location'in event.target&&'href'in event.target.location)?event.target.location.href:'');Userstats.sendStats({e_type:'ajaxError',e_msg:msg,e_stack:stacktrace,e_t:errorTime,e_url:errorUrl,e_http:(('status'in xhr)?xhr.status:500)},"error")}}catch(statsError){ABL.LogError("Error with sending error to error analysis endpoint",statsError)}return true});(function(ABL,undefined){function _getPageUrl(href){var uri,query,result;href=href||State.Get("href");if(href===undefined){if(window.location.hash&&window.location.hash.length>1){href=ABL.GetSignificantPath(window.location.hash.substr(1))}else{href=ABL.GetSignificantPath(window.location.href)}}else if(href){uri=URI.asURI(href);href=uri.toString(false,false,false,true,true)}if(href.substr(0,1)=="/"){var match=/.*~\//.exec(href);if(match){href=href.substr(match[0].length)}}else{if(href.substr(0,2)=="~/"){href=href.substr(2)}var winloc=URI.asURI(ABL.GetSignificantPath(window.location.href));href=winloc.toString(false,false,false,true,true)+href}query=State.ExposedUrlString();if(query){result=href+"?"+query}else{result=href}State.Set("href",result);return result};function _getPageTitle(){var page=State.Get('page');return State.Settings.Get('sitetitle')};var _jqXHR={};function _request(historyState,cached,httpMethod){cached=typeof cached=='undefined'?true:cached;var ajaxFail,ajaxDone,beforeSend;if(State.DebugMode()){ABL.Log('     - state ',historyState);ABL.Log('     - title ',document.title);ABL.Log('     - url ',document.location)}var urlBase=URI.asURI(_getPageUrl(historyState['href']));var resetState=historyState['i_invalidateclientstate'];if(resetState)State.Reset();var ajaxUrlArguments='';if(!$.isEmptyObject(historyState)){ajaxUrlArguments=State.AsArgString(historyState)}if('abort'in _jqXHR){_jqXHR.abort()}urlBase.query=ajaxUrlArguments;urlBase.fragment='';var ajaxUrl=_createAjaxRequestUrl(urlBase.toString());httpMethod=httpMethod?forceHTTPMethod:(ajaxUrl.length>State.Settings.Get("getlimit")?"POST":"GET");var data=null;if(httpMethod=='POST'){ajaxUrl=urlBase.toString(false,false,false,true,true);data=ajaxUrlArguments}ajaxDone=function(responseText,status){$('#ablContent').html(responseText).attr('tabindex','-1').focus();ABL.LogInfo('ajax done. firing event abl:page:updated');ABL.Event.trigger('abl:page:updated');if(resetState){ABL.SetHistoryState()}};ajaxFail=function(jqXHR,status,error){if(error=='abort'){ABL.Log('Ajax request aborted',jqXHR);return false}else if(status==414&&httpMethod==="GET"){ABL.Log('Request too long: retrying with POST');_request(historyState,cached,"POST")}else{ABL.Log('Ajax error'+error,null)}};beforeSend=function(){ABL.Log('abl:page:unload');ABL.Event.trigger('abl:page:unload')};ABL.Log('     - ajax-url ',ajaxUrl);_jqXHR=$.ajax({url:ajaxUrl,type:httpMethod,cache:cached,beforeSend:beforeSend,data:data});_jqXHR.done(ajaxDone);_jqXHR.fail(ajaxFail)};function _createAjaxRequestUrl(url){return url+(url?'&':'?')+'ajax=true'};var stateId=0;return $.extend(ABL,{Initialized:false,WrapError:function(msg,ex){if(!ex){return new Error(msg)}ex.message=msg+" "+ex.message;return ex},ExceptionHandler:(function(){var handler;var haveErrorStacks="stack"in new Error("foobar");function Handler(){};Handler.prototype={HandleException:function(ex,optMsg){if(!ex){throw new Error("Empty exception object.");}if(optMsg){ex=ABL.WrapError(optMsg,ex)}var msg=ex.msg||ex.message||""+ex;var stacktrace=ex.stack;if(!ABL){throw ex;}if(!ABL.LogError(msg,stacktrace)){throw ex;}},HandleError:function(msg,stacktrace){var error;if(!ABL){if(haveErrorStacks){error=new Error(msg);error.stack=stacktrace}else{error=new Error(msg+"Stacktrace: "+stacktrace)}}if(!ABL.LogError(msg,stacktrace)){if(haveErrorStacks){error=new Error(msg);error.stack=stacktrace}else{error=new Error(msg+"Stacktrace: "+stacktrace)}}if(error){throw error;}},WindowOnError:function(msg,url,line){msg=msg||"";url=url||"";line=line||"unknown";ABL.LogError(msg+" url = "+url,"line is "+line);if(State.DebugMode()){LoadingIndicator.showError()}else{LoadingIndicator.hide()}return false}};handler=new Handler;return handler})(),Event:window.jQuery(document),Modules:{},RegisterModule:function(obj){if("init"in obj&&typeof obj.init=="function"){this.Event.bind('abl:initialize',function(e,data){obj.init(data)})}},RegisterLegacyModule:function(name,obj){if(name in window){throw'Error registering module '+name+': a global variable or module of that name already exists.';}var instance=new obj;window[name]=instance;this.Modules[name]=instance;this.Event.bind('abl:initialize',function(e,data){instance.Initialize(data)})},GetProviderPrefix:function(optProvider,providerFromState,providerSettingsObject){providerFromState=typeof providerFromState==='undefined'?State.Get('provider'):providerFromState;providerSettingsObject=typeof providerSettingsObject==='undefined'?State.Settings.Get('providers'):providerSettingsObject;optProvider=typeof optProvider==="undefined"?providerFromState:optProvider;if(optProvider===''){return''}if(!providerSettingsObject){return optProvider}var provider=providerSettingsObject[optProvider];if(provider){if('urlPrefix'in provider){return provider['urlPrefix']}else if("isAliasOf"in provider){return providerSettingsObject[provider.isAliasOf]['urlPrefix']}}return optProvider},GetSignificantPath:function(href,appPath,providerSettingsObject){var hrefIsExplicit=true;if(typeof href==='undefined'){href=window.location.href;hrefIsExplicit=false}appPath=typeof appPath==='undefined'?State.Settings.Get("applicationpath"):appPath;providerSettingsObject=typeof providerSettingsObject==='undefined'?State.Settings.Get('providers'):providerSettingsObject;if(!href){return""}var uriObject=URI.asURI(href);href=uriObject.toString(false,false,false,true,true);var path=uriObject.path!==null?uriObject.path:'';path=path==='/'?'':path;var indexProviderPrefix=-1;var providerPrefixes=[];var providerOnUrl="";var appPathRegex=new RegExp(appPath,"i");var appPathMatch=appPathRegex.exec(path);if(appPathMatch!=null&&appPathMatch.index===0){path=path.substring(appPath.length)}$.each(providerSettingsObject,function(provider){if("urlPrefix"in providerSettingsObject[provider]){providerPrefixes.push(providerSettingsObject[provider].urlPrefix)}providerPrefixes.push(provider)});var providerPrefixesUnique=[];$.each(providerPrefixes,function(i,el){if(el&&$.inArray(el,providerPrefixesUnique)===-1){providerPrefixesUnique.push(el)}});var providerRegex=new RegExp('^('+providerPrefixesUnique.join('/|')+'/)',"i");var providerPrefixMatch=providerRegex.exec(path);if(providerPrefixMatch!=null){providerOnUrl=providerPrefixMatch[1].substring(0,providerPrefixMatch[1].indexOf('/'));path=path.substring(providerPrefixMatch.index+providerPrefixMatch[1].length)}return appPath+ABL.GetProviderUrlPrefix(providerOnUrl,providerOnUrl,providerSettingsObject)+path},GetProviderFromUrlPrefix:function(prefix){if(typeof prefix!=="string"){return undefined}var providers=State.Settings.Get("providers");var p;for(p in providers){if(p&&providers.hasOwnProperty(p)&&"urlPrefix"in providers[p]&&providers[p].urlPrefix===prefix){return p}}return undefined},GetProviderUrlPrefix:function(optProvider,providerFromState,providerSettingsObject){var prefix=this.GetProviderPrefix(optProvider,providerFromState,providerSettingsObject);if(prefix){return prefix+"/"}else{return''}},GetBaseUrl:function(optProvider,appPath){appPath=typeof appPath==='undefined'?State.Settings.Get("applicationpath"):appPath;var urlPath=[appPath,ABL.GetProviderUrlPrefix(optProvider)].join('/').replace(/\/\//g,"/");return(urlPath.length>1&&urlPath.substr(urlPath.length-1)!='/')?urlPath=urlPath+'/':urlPath},History:{Store:{_UrlToState:{},Replace:function(url,state){if(typeof url!='string'||url==''){ABL.LogError('History Store Replace, url is not a string or empty:'+url);return}$.jStorage.deleteKey(url);return this.Set(url,state)},Set:function(url,state){if(typeof url!='string'||url==''){ABL.LogError('History Store Set, url is not a string or empty:'+url);return}url=url+"&t="+(new Date).getTime();$.jStorage.set(url,state);return url},Get:function(url){if(typeof url!='string'||url==''){ABL.LogError('History Store Get, url is not a string or empty:'+url);return}return $.jStorage.get(url,{})}},NormalizeUrl:function(url){if(!Modernizr.history){var appPath=State.Settings.Get('applicationpath');if(url.substr(0,appPath.length)===appPath){url=url.substr(appPath.length)}}return url}},Request:function(){ABL.PushState(State.AsObject(true),_getPageTitle(),_getPageUrl())},SetHistoryState:function(){var title,url,state,entry;title=_getPageTitle();url=ABL.History.NormalizeUrl(_getPageUrl());state=State.AsObject(true);ABL.LogInfo('setHistoryState',state);if(Modernizr.history){entry=history.state;entry={id:!entry?stateId:entry.id,state:state};stateId=entry.id;history.replaceState(entry,title,url)}else{entry=ABL.History.Store.Get(url);entry={id:!entry?stateId:entry.id,state:state,ignoreHashChange:true};stateId=entry.id;var hash=ABL.History.Store.Replace(url,entry);if(typeof hash!='undefined'){ABL.LogInfo('Setting location.hash from "SetHistoryState" - '+hash);location.hash='#'+hash}}},HandleStateChange:function(state,src){ABL.LogInfo("  - state change event. Src: "+src);if(state==null||$.isEmptyObject(state)){ABL.LogInfo('no data in state, stopping');return}_request(state)},BindStateChange:function(){var entry;var getPageEvent=function(){var oldStateId;if(entry){oldStateId=stateId;stateId=entry.id;if(entry.id<oldStateId){return'abl:page:back'}else if(entry.id>oldStateId){return'abl:page:forward'}}};var triggerPageEvent=function(pageEvent){if(pageEvent){ABL.Event.trigger(pageEvent)}};if(Modernizr.history){ABL.LogInfo('Binding "popstate" - Supports native HTML5 API');$(window).on('popstate',function(ev){entry=ev.originalEvent.state;var pageEvent=getPageEvent();ABL.HandleStateChange(!entry?undefined:entry.state,'popstate');triggerPageEvent(pageEvent)})}else{ABL.LogInfo('Binding "hashchange" - Does not support native HTML5 API');$(window).on('hashchange',function(){var url=location.hash.slice(1);entry=ABL.History.Store.Get(url);if("ignoreHashChange"in entry&&entry.ignoreHashChange===true){delete entry["ignoreHashChange"];return}var pageEvent=getPageEvent();ABL.HandleStateChange(!entry?undefined:entry.state,'hashchange');triggerPageEvent(pageEvent)})}},PushState:function(state,title,url){url=ABL.History.NormalizeUrl(url);var historyEntry={id:(++stateId),state:state};if(Modernizr.history){history.pushState(historyEntry,title,url);ABL.HandleStateChange(state,'pushState')}else{var hash=ABL.History.Store.Set(url,historyEntry);if(typeof hash!='undefined'){ABL.LogInfo('Setting location.hash from "PushState" - '+hash);location.hash='#'+hash}}},Reset:function(){ABL.Event.trigger('abl:reset');State.Reset();jQuery.each(ABL.Modules,function(key,val){if('HandleReset'in val){val.HandleReset()}})},SearchMethod:function(optionalQuery){var q=optionalQuery||State.Get('q');var match=q.match(/(^\w+)[:=]/);if(match!=null){return match[1]}return''},FullRecord:{},ShortRecord:{},Util:{tryParseStringToBool:function(inValue,outValue){if(typeof inValue!='string'){return false}var callback=outValue;if(typeof outValue=="object"){callback=function(b){outValue.val=b}}switch(inValue.toLowerCase()){case'true':callback(true);return true;break;case'false':callback(false);return true;break;default:return false;break}}}})})(ABL);window.onerror=ABL.ExceptionHandler.WindowOnError;if(window.location.hash!=="#credits"){ABL.initialHash=window.location.hash}var State=(function(){function _State(){}__extends(_State,Observable);var state=new _State;var _current={action:{serverExposed:false,urlExposed:false},page:{serverExposed:true,urlExposed:function(){return!/^results$|^fullrecord$|^welcome$|^error|^advancedsearch|^author$/.test(State.GetCurrentSubPage())},set:function(val){if(typeof(val)==='string'&&val.indexOf('/')==0){this.value=val.substring(1)}else{this.value=val}}},debug:{serverExposed:true,urlExposed:function(){return true}},concept:{serverExposed:true,setExplicitlyByServer:true,get:function(){if(!$.IsUndefinedOrEmpty(this.value)){return this.value}else{return state.Get('q')}}},cmd:{serverExposed:true},cs:{defValue:'unknown',serverExposed:true,setExplicitlyByServer:true},curpage:{defValue:'1',serverExposed:true,urlExposed:function(){return this.value!='1'&&State.GetCurrentSubPage()=='results'},get:function(){if(typeof this.value=='undefined'){this.value=this.defValue}return this.value.toString()}},hardsort:{defValue:'',serverExposed:true,urlExposed:function(){return!!state.Get('hardsort')&&(State.GetCurrentSubPage()=='results'||State.GetCurrentSubPage()=='error')}},i_fk:{serverExposed:true,get:function(){return state.Get('fixatekeys').join(';')},set:function(val){state.Set('fixatekeys',(typeof(val)==="string"&&val.length)?val.split(';'):[])}},c_showfullavail:{serverExposed:true,urlExposed:false},i_startup:{serverExposed:false},serverstate:{defValue:{}},i_invalidateclientstate:{defValue:'false',setExplicitlyByServer:true},inlibrary:{defValue:'false',serverExposed:true},href:{serverExposed:true,urlExposed:false,get:function(){return this.value}},itemid:{serverExposed:true,urlExposed:function(){return State.GetCurrentSubPage()=='fullrecord'||State.GetCurrentSubPage()=='error'}},i_silent:{setExplicitlyByServer:true},q:{serverExposed:true,urlExposed:function(){return(this.value!='special:list')&&!$.IsUndefinedOrEmpty(this.value)&&(State.GetCurrentSubPage()!='fullrecord')},get:function(){switch(this.value){case'special:list':return'';default:return this.value}}},nodymsearch:{defValue:'false',serverExposed:true,urlExposed:function(){return(this.value==='true'||this.value===true)&&State.GetCurrentSubPage()=='results'}},s:{serverExposed:true,urlExposed:true,setExplicitlyByServer:true},si:{serverExposed:true,setExplicitlyByServer:true},p:{serverExposed:true,urlExposed:function(){var val=this.value||this.defValue;if(!val||!val.name){return false}return val.name.toLowerCase()!="root"&&val.name.toLowerCase()!=this.defValue.name.toLowerCase()},urlValue:function(val){if(typeof val=="undefined"){ABL.Log('ABL.State.p.urlValue is undefined');return''}return val.name}},skin:{serverExposed:true,urlExposed:function(){var profile=State.Get("p");return this.defValue!=this.value&&typeof this.value!='undefined'&&(typeof profile=='undefined'||profile.skin!=this.value)}},t_dim:{serverExposed:true},t_method:{serverExposed:true,get:function(){return state.Get('method')},set:function(val){state.Set('method',val)}},uilang:{defValue:'',value:'',serverExposed:true,urlExposed:function(){var profile=State.Get("p");return this.defValue!=this.value&&(typeof profile=='undefined'||profile.uilang!=this.value)}},undup:{serverExposed:true,urlExposed:function(){var globalSetting=state.Settings.Get('undup');return typeof globalSetting!=='undefined'&&globalSetting!==state.Get('undup')}},visualquery:{},branch:{serverExposed:true,value:'',urlExposed:function(){return true}},chain:{defValue:[],value:this.defValue,get:function(){return jQuery.extend([],this.value)}},detaillevel:{defValue:'default',serverExposed:true,urlExposed:function(){return!$.IsUndefinedOrEmpty(this.value)&&this.value.toLowerCase()!=='default'}},dim:{value:[""],urlExposed:function(){return!$.Equals(this.value,[""])&&(State.GetCurrentSubPage()=='results'||State.GetCurrentSubPage()=='error')},get:function(){var ret=[];if(typeof this.value=='undefined'){return[""]}jQuery.each(this.value,function(){if(typeof this.dim!='undefined'&&typeof this.kw!='undefined'){ret.push(this.dim+'('+this.kw+')')}});if($.Equals(ret,[])){return[""]}if($.IsUndefinedOrEmpty(ret)){return[""]}return ret},set:function(val){var v,b,ret=[];if($.isArray(val)){for(var i=0;i<val.length;i++){v=val[i];if(v['dim']){ret.push(v)}else{if(v!=''){b=v.indexOf('(');ret.push({dim:v.substring(0,b),kw:v.substring(b+1,v.length-1)})}}}}else if(typeof val==='string'){if(val!==''){b=val.indexOf('(');ret.push({dim:val.substring(0,b),kw:val.substring(b+1,val.length-1)})}}else{ABL.LogError("Weird dim object received in state",val)}if($.Equals(ret,[])){this.value=[""]}else{this.value=ret}},serverExposed:function(){return true}},fixatekeys:{defValue:[],value:this.defValue,get:function(){return jQuery.extend([],this.value)}},mxdk:{defValue:-1,serverExposed:true},method:{},sellbl:{},collapseddims:{value:{},get:function(){return jQuery.extend({},this.value)}},provider:{serverExposed:true,urlExposed:false},rctx:{serverExposed:true,get:function(){if(typeof this.value!='undefined'){return this.value}else{return''}},set:function(val){this.value=val}}};for(var key in _current){_current[key]["native"]=true}var _settings={ablversion:'',guid:'',fixaterefinekeys:false,startconcept:'',maxquerylength:200,recordsperpage:'',undup:undefined,hidesearchbox:false,hideheader:false,hidefooter:false};var _settingsLoaded=false;function _EnsureSettingsLoaded(){if(!_settingsLoaded){throw"Attempt to get settings that have not yet been loaded.";}}state.GetCurrentSubPage=function(optionalPageString){var page=optionalPageString||state.GetCurrentPage();var subpageMatch=page.match(/\/([^\/]*)$/);subpageMatch=subpageMatch||'';return subpageMatch.length>1?subpageMatch[1]:""};state.GetCurrentPage=function(){return state.Get('page')};state.Settings={Get:function(name){_EnsureSettingsLoaded();var settingsValue=_settings[name];if(typeof settingsValue==='undefined'){settingsValue=state.Settings.GetFromProvider(name,State.Get('provider'))}var boolValue={val:false};if(ABL.Util.tryParseStringToBool(settingsValue,boolValue)){settingsValue=boolValue.val}return settingsValue},Set:function(name,value){if(typeof _current[name]!='undefined'){_current[name]['defValue']=value}_settings[name]=value},GetFromProvider:function(name,provider){_EnsureSettingsLoaded();if(!('providers'in _settings)){return undefined}var providerObject=_settings.providers[provider];if(typeof providerObject!='undefined'&&'settings'in providerObject){return providerObject.settings[name]}return undefined}};state.IsKnownQueryParamName=function(name){if(!name){return false}if(typeof name!="string"){name=name.toString()}name=name.toLowerCase();var prefix=name.substr(0,2);if(prefix==="c_"||prefix==="t_"||prefix==="i_"){return true}if(name in _current){return!!_current[name]["native"]}if(name==="action"){return true}return false};state.Get=function(name){var value=_current[name];var returnedStateValue;if(typeof value=='undefined'){}else{if($.isFunction(value['get'])){returnedStateValue=value.get()}else if(typeof value['value']!='undefined'){returnedStateValue=value['value']}else if(typeof value['defValue']!='undefined'){returnedStateValue=value['defValue']}else{returnedStateValue=''}}var boolValue={val:false};if(ABL.Util.tryParseStringToBool(returnedStateValue,boolValue)){returnedStateValue=boolValue.val}return returnedStateValue};state.Set=function(name,newValue){var value=_current[name];var oldValue=state.Get(name);if(typeof value=='undefined'){if(transparent.isTransparent(name)){ABL.LogInfo('Transparent value Set('+name+','+newValue+')')}else{ABL.LogInfo('State.Set('+name+') was undefined, created now!')}if(newValue!=''){_current[name]={value:newValue,serverExposed:true}}}else{if($.isFunction(value['set'])){value.set(newValue)}else{value['value']=newValue}if(!$.Equals(oldValue,State.Get(name))){State.Observe(name).update(State.Get(name))}}};var updateStateFromKeyValue=function(key,val,decode){if(typeof val!='undefined'){if(decode&&typeof val=='string'){val=decodeURIComponent(val)}if(key=="p"&&typeof val=="string"){return}state.Set(key,val)}else{reset(key)}};state.ReplaceWithObject=function(obj,options){options=options||{replacerctx:true,decode:false,stoponemptystate:true};var replaceRctx=options['replacerctx'];var decode=options['decode'];if(options['stoponemptystate']&&$.isEmptyObject(obj)){return}jQuery.each(_current,function(key,val){if(!replaceRctx&&key=='rctx'){return true}if(typeof obj[key]!='undefined'){updateStateFromKeyValue(key,obj[key],decode)}else{reset(key)}})};state.ExtendWithObject=function(obj,decode){jQuery.each(obj,function(key,val){updateStateFromKeyValue(key,val,decode)})};var reset=function(key){var stateValue=_current[key];if(typeof stateValue=='undefined'){ABL.LogError("state value undefined",key);return}var defValue=stateValue['defValue'];if(typeof defValue!='undefined'){state.Set(key,defValue)}else{state.Set(key,undefined)}};state.LoadServerState=function(serverObject){ABL.LogInfo('Loading Server State: ',serverObject);jQuery.each(_current,function(key,val){if(transparent.isTransparent(key)){reset(key)}});jQuery.each(serverObject,function(key,val){updateStateFromKeyValue(key,val);if(transparent.isTransparent(key)&&typeof _current[key]!='undefined'&&typeof _current[key]['serverExposed']=='undefined'){_current[key]['serverExposed']=transparent.isUrlExposed(key)}});jQuery.each(_current,function(key,val){if(val['setExplicitlyByServer']&&state.Get(key)!=serverObject[key]){reset(key)}})};state.Reset=function(){jQuery.each(_current,function(key,val){if(key!='debug'){reset(key)}});state.Set('cmd','reset')};state.AsHtmlString=function(){function displayStateObj(obj){var dispString='<ul class="values">';jQuery.each(obj,function(key,val){var objValue='';if(key=='set'){return}if($.isFunction(val)){try{objValue=val()}catch(e){objValue='[function that could not be executed]';ABL.Log("Error in AsHtmlString",e)}}else if($.isArray(val)){objValue='[ '+val.join(', ')+' ]'}else if(typeof val=='object'){if(jQuery.isEmptyObject(val)){objValue='[empty object]'}else{objValue=displayStateObj(val)}}else{objValue=val}dispString+='<li>'+key+($.isFunction(val)?'(): ':': ')+objValue+'</li>'});dispString+='</ul>';return dispString}function displayStateObjFancy(obj){var dispString='<ul>';jQuery.each(obj,function(objKey,objValue){dispString+='<li class="key"><span class="keyname">'+objKey+'</span>: ';if($.isFunction(objValue)){dispString+=objValue()}else if($.isArray(objValue)){dispString+='[ '+objValue.join(', ')+' ]'}else if(typeof objValue=='object'){if(jQuery.isEmptyObject(objValue)){dispString+='[empty object]'}else{dispString+=displayStateObj(objValue)}}else{dispString+=objValue}dispString+='</li>'});dispString+='</ul></div></br>';return dispString}var t='<div class="stateDebugInfo"><p>State as Argstring:</p><input type="text" value="'+state.AsArgString()+'" style="width:100%" />';t+='<br/><br/><h2>State Object:</h2>';t+=displayStateObjFancy(_current);t+='<br/><br/><h2>Settings Object:</h2>';t+=displayStateObjFancy(_settings);return t};state.AsArgString=function(override){var o=override||state.AsObject(true);jQuery.each(o,function(key,value){if(typeof value=='undefined'){o[key]=''}else if(key!="href"){o[key]=$.optApply(_current[key],'urlValue',value,State.Get(key))}});return jQuery.param(o,true)};state.ExposedUrlString=function(queryParamPrefix){var ret={};var ignoreUrlExposure=state.HasDebugFlag("KeepUrl");queryParamPrefix=queryParamPrefix||"";jQuery.each(_current,function(key,val){if(key=='href'){return}if(ignoreUrlExposure||$.optApply(val,'urlExposed',false)||transparent.isUrlExposed(key)){var gottenValue=state.Get(key);if(gottenValue){gottenValue=$.optApply(val,'urlValue',gottenValue,gottenValue)}if(gottenValue!==''){ret[key]=gottenValue}}});var params=jQuery.param(ret,true);if(params){return queryParamPrefix+params}else{return''}};state.AsObject=function(checkServerExposed){if(checkServerExposed&&state.Get('i_invalidateclientstate')){var serverstate=state.Get('serverstate');return serverstate}var ret={};jQuery.each(_current,function(key,val){if(checkServerExposed){var serverExposed=$.optApply(val,'serverExposed',!!val['serverExposed']);if(serverExposed){ret[key]=state.Get(key)}if(typeof ret[key]=='undefined'||ret[key]==null){ret[key]=''}}else{ret[key]=state.Get(key)}});return ret};state.LoadServerSettings=function(){_settingsLoaded=false;if(!ABL.SettingsFromServer){throw"No settings from server found.";}jQuery.each(ABL.SettingsFromServer,function(key,val){state.Settings.Set(key,val)});ABL.SettingsFromServer=null;_settingsLoaded=true};var transparent={isTransparent:function(key){return/^[cit]_.+/i.test(key)},isUrlExposed:function(key){return this.isInheritable(key)},isInheritable:function(key){return/^c_.+/i.test(key)}};state.DebugMode=function(){return state.Get('debug')};state.HasDebugFlag=function(flag){if(!flag){return false}var debugKeys=$.map(AblConstants.Enums._AblDebug,function(val,key){return key});function parseToNumber(d){var result,parts,i,j,tmp,key;if(typeof d==="number"){return d}if(typeof d==="undefined"){return 0}if(typeof d==="boolean"&&!d){return 0}d=""+d;result=parseInt(d,16);if(!isNaN(result)){return result}result=parseInt(d,10);if(!isNaN(result)){return result}result=0;parts=d.split(/,|\|/);for(i=0;i<parts.length;i++){if(parts.length>1&&(tmp=parseToNumber(parts[i]))){result=result|tmp}else{for(j=0;j<debugKeys.length;j++){key=debugKeys[j];if(key.toLowerCase()===parts[i].toLowerCase()){result=result|AblConstants.Enums._AblDebug[key]}}}}return result}flag=parseToNumber(flag);return(parseToNumber(state.DebugMode())&flag)===flag};return state})();(function(ABL,undefined){function _createLoggableMessage(type,arguments){if(!_shouldLog()){return}type=type||'log';var args=Array.prototype.slice.call(arguments);if(!/MSIE\s\d/.test(window.navigator.userAgent)&&'console'in window&&type in console){console[type].apply(console,args)}else if('console'in window&&'log'in console){var a=[];for(var i=0;i<args.length;i++){if(typeof args[i]=='object'){a.push(JSON.stringify(args[i]))}a.push(args[i])}console.log(a)}};function _shouldLog(){return State.DebugMode()||State.Get('c_log')||State.Get('c_d')};return $.extend(ABL,{Log:function(){_createLoggableMessage('log',arguments)},LogWarning:function(){_createLoggableMessage('warn',arguments)},LogInfo:function(){_createLoggableMessage('info',arguments)},LogError:function(msg,stacktrace){if(!_shouldLog()){return true}if(!window.console){return false}if(typeof msg==="string"){stacktrace=stacktrace||printStackTrace()}else{stacktrace=stacktrace||printStackTrace({e:msg})}if(!window.console.error){if(window.console.log){console.log("ERROR: "+msg,stacktrace);return true}return false}console.error(msg+"\n",stacktrace);if('trace'in console){console.trace()}return true}})})(ABL);function LocalizationModule(){this._clientLangData=null}LocalizationModule.prototype={Initialize:function(lang,skin){if(this._clientLangData){throw"Already initialized localization data.";}this.RefreshData(lang,skin);this.RefreshData(lang,skin,"dimension","branches")},RefreshData:function(lang,skin,type,id){ABL.LogInfo("Retrieving Clientlang.ashx with synchronous AJAX call... (should only happen max of once per visit)");var date=new Date;var qarg;var bld=State.Settings.Get('bld')||(date.getFullYear()+''+date.getDate()+date.getMonth()+'.'+date.getHours()+date.getMinutes()+date.getSeconds());var url;if($.IsUndefinedOrEmpty(lang)){lang=State.Get('uilang');qarg=location.search.match(/uilang\=(..)/);if(qarg){lang=qarg[1]}}if($.IsUndefinedOrEmpty(skin)){skin=State.Get('skin');qarg=location.search.match(/skin\=(..)/);if(qarg){skin=qarg[1]}}url=ABL.GetBaseUrl()+'clientlang.ashx?lang='+lang+'&skin='+skin+'&bld='+bld;if(!$.IsUndefinedOrEmpty(type)){url=url+'&'+encodeURIComponent(type)+'='+encodeURIComponent(id)}var that=this;$.ajax({url:url,cache:true,async:false,dataType:'json',traditional:true,global:false,success:function(data,textStatus){if(that._clientLangData===null){that._clientLangData=data}else{$.extend(that._clientLangData,data)}},error:function(data,textStatus,error){throw"Couldn't fetch localization data. error: "+error;}})},TransBranch:function(id){if(!this._clientLangData){throw"Localization has not yet initialized.";}if($.IsUndefinedOrEmpty(id)||typeof id!=="string"){return id}if(id&&id.substr(0,1)!=="/"){id="/"+id}var foundKeys=$.grep(Object.keys(this._clientLangData),function(o){if(o.toLowerCase().indexOf(id.toLowerCase(),o.length-id.length)>-1){return o}},false);if(foundKeys.length>0){return this.Trans(foundKeys[0])}return""},Trans:function(id){if(!this._clientLangData){throw"Localization has not yet initialized.";}id=id.toLowerCase();if(typeof(this._clientLangData[id])==="string"){var str=this._clientLangData[id];if(arguments.length>1){for(var i=1;i<arguments.length;i++){var re=new RegExp("\%"+i+"[sd]","g");str=str.replace(re,arguments[i])}}return str}return id}};ABL.RegisterLegacyModule("Localization",LocalizationModule);(function($){$.fn.clearForm=function(){return this.find('input, select').each(function(){var type=this.type,tag=this.tagName.toLowerCase();if(tag==='form'){return $(':input',this).clearForm()}if(type==='text'||type==='password'||tag==='textarea'||type==='email'||type==='search'||type==='url'||type==='tel'||type==='password'){this.value=''}else if(type==='checkbox'||type==='radio'){this.checked=false}else if(tag==='select'){this.selectedIndex=0}})};$.fn.getBackgroundImages=function(){var result=$();var src=null;$(this).each(function(){src=$(this).css('background-image').replace(/"/g,"").replace(/url\(|\)$/ig,"");if(src){result=result.add($("<img src='"+src+"' />"))}});return result}})(jQuery);jQuery.extend({trunc:function(str,len){var i=len||450,s;if(str.length>i){s=str.substr(i).search(/\s/);if(s<0){return str}return str.substr(0,i+s)+"…"}return str},textWidth:function(text,font){var f=font||'15px arial',o=$('<div>'+text+'</div>').css({position:'absolute',float:'left','white-space':'nowrap',visibility:'hidden',font:f}).appendTo($('body')),w=o.width();o.remove();return w},truncToFirstChar:function(str,toFirstCharExpr,minLength,maxLength,start){var i=minLength||100;var _maxLength=maxLength||i;var s=str.substr(i).search(toFirstCharExpr);if(s<0){return $.trunc(str,s+i)}return str.substr(0,Math.min(i+s,_maxLength))+"…"},optApply:function(o,fnName,defVal){if(!(typeof fnName==="string")){return defVal}if(!o&&(typeof o==="undefined"||o===null)){return defVal}if(fnName in o){if($.isFunction(o[fnName])){return o[fnName].apply(o,Array.prototype.slice.call(arguments,3))}else if(typeof o[fnName]==="boolean"){return o[fnName]}}return defVal},run:function(fn,handler){try{fn()}catch(err1){if(handler&&typeof handler==="function"&&handler(err1)){throw err1;}try{if(window["ABL"]&&ABL.ExceptionHandler){ABL.ExceptionHandler(err1)}}catch(err2){try{if(console){if(console.error){console.error(""+err1)}else if(console.log){console.log(""+err1)}}}catch(_){}}}},runFn:function(f,h){return function(){$.run(f,h)}},readyRun:function(f,h){$($.runFn(f,h))},setTimeout:function(f,t){setTimeout($.runFn(f),t)},requestAnimationFrame:(function(){var fn=window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(callback){window.setTimeout(callback,1000/60)};return function(callback){fn(callback)}})()});jQuery.cachedScript=function(url,options){options=$.extend(options||{},{dataType:"script",cache:true,url:url});return jQuery.ajax(options)};jQuery.extend({getQueryStringParams:function(queryString){var vars={},hash;var idx;idx=queryString.indexOf("?");if(idx>=0){queryString=queryString.slice(idx+1)}idx=queryString.indexOf("#");if(idx>=0){queryString=queryString.substr(0,idx)}var hashes=queryString.split('&');for(var i=0;i<hashes.length;i++){idx=hashes[i].indexOf('=');var val=hashes[i].substring(idx+1);var key=hashes[i].substring(0,idx);if(typeof vars[key]!=='undefined'){if($.isArray(vars[key])){vars[key].push(val)}else{var orig=vars[key];vars[key]=[];vars[key].push(orig);vars[key].push(val)}}else{vars[key]=val}}return vars},gup:function(name,queryString){name=name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");var regexS="[\\?&]"+name+"=([^&#]*)";var regex=new RegExp(regexS);var results=regex.exec(queryString||window.location.href);if(results===null){return""}else{return results[1]}},getObjectFromQueryString:function(queryString){var o={};var a=$.getQueryStringParams(queryString);$.each(a,function(key,val){if($.isArray(val)){for(var i=0;i<val.length;i++){val[i]=decodeURIComponent(val[i])}o[key]=val}else{o[key]=decodeURIComponent(val)}});return o},IsUndefinedOrEmpty:function(str){return typeof str==='undefined'||str===''},Chunk:function(array,count){if(count==null||count<1)return[];var result=[];var i=0,length=array.length;while(i<length){result.push(array.slice(i,i+=count))}return result},Equals:(function(){var getClass=function(val){return Object.prototype.toString.call(val).match(/^\[object\s(.*)\]$/)[1]};var whatis=function(val){if(val===undefined){return'undefined'}if(val===null){return'null'}var type=typeof val;if(type==='object'){type=getClass(val).toLowerCase()}if(type==='number'){if(val.toString().indexOf('.')>0){return'float'}else{return'integer'}}return type};var compareObjects=function(a,b){if(a===b){return true}for(var i in a){if(b.hasOwnProperty(i)){if(!equal(a[i],b[i])){return false}}else{return false}}for(var j in b){if(!a.hasOwnProperty(j)){return false}}return true};var compareArrays=function(a,b){if(!a||!b){return false}if(a.length!==b.length){return false}if(a===b){return true}for(var i=0;i<a.length;i++){if(!equal(a[i],b[i])){return false}}return true};var _equal={array:compareArrays,object:compareObjects,date:function(a,b){return a.getTime()===b.getTime()},regexp:function(a,b){return a.toString()===b.toString()},'function':function(a,b){return a.toString()===b.toString()}};var equal=function(a,b){if(a!==b){var atype=whatis(a),btype=whatis(b);if(atype===btype){return _equal.hasOwnProperty(atype)?_equal[atype](a,b):a===b}return false}return true};return equal})(),GetFirstProp:function(obj){for(var i in obj)return obj[i]},escapeUserContent:function(text){var div=document.createElement('div');div.appendChild(document.createTextNode(text));return div.innerHTML}});(function(){var clientRequiresProxy=!$.support.cors&&!(window["XDomainRequest"]&&typeof window["XDomainRequest"]==="function");$.ajaxPrefilter(function(options,originalOptions,jqXHR){var proxyRequest=clientRequiresProxy;var uri,originalUrl,proxySettings;if(options.crossDomain){if(options.dataType==="jsonp"){return}if((options.dataType==="json"||options.dataType==="script")&&options.jsonpCallback){return}if(options.type!=="GET"){throw new Error("CORS: "+options.type+" not -yet- supported");}if(window["State"]){if(!proxyRequest){uri=new URI(options.url);var path=uri.path;if(uri.authority.match(/:\d+$/)){uri=uri.scheme+"://"+uri.authority}else if(uri.scheme==='https'){uri=uri.scheme+"://"+uri.authority+":443"}else{uri=uri.scheme+"://"+uri.authority+":80"}proxySettings=State.Settings.Get("proxy");var settings=!!proxySettings&&proxySettings[uri];if(!settings){throw new Error("No proxy defined for URI "+uri+" but needed because it's a cross domain request");}if(path&&settings.PathExpr){if(!new RegExp(settings.PathExpr).test(path)){throw new Error("No proxy defined for path "+path);}}else{}proxyRequest=!proxySettings[uri].CORS}if(proxyRequest){options.data=$.param({data:options.data||"",url:options.url});originalUrl=options.url;options.url=State.Settings.Get('applicationpath');if(options.url.charAt(options.url.length-1)==="/"){options.url=options.url+"proxy.ashx"}else{options.url=options.url+"/proxy.ashx"}options.crossDomain=false;options.global=false;if(window["ABL"]){ABL.LogInfo("Request was proxied. Url '"+originalUrl+"' proxied to '"+options.url+"'")}}}else{throw new Error("Failed to do CORS request: State is not available");}}});if(!$.support.cors&&!clientRequiresProxy){$.ajaxTransport(function(options,originalOptions,jqXHR){if(options.crossDomain){var req=new window.XDomainRequest;return{send:function(headers,completeCallback){req.onload=function(){completeCallback(200,"success",{text:req.responseText},{})};req.onerror=function(){completeCallback(400,"error","",{})};req.ontimeout=req.onerror;req.open("GET",options.url);req.send()},abort:function(){req.abort()}}}})}})();ABL.FullRecord=(function(){var blockXhr;var blockXhrId=0;return{BlockManager:{RemoveBlock:function($block,loadTimeInMillis){if(loadTimeInMillis&&loadTimeInMillis>0&&loadTimeInMillis<800){var that=this;setTimeout(function(){that.RemoveBlock($block,0)},1000-loadTimeInMillis);return}if($block&&$block.size()){if(!$block.hasClass('fullrecord-block')){throw new Error("RemoveBlock: class:("+$block.attr('class')+') id:('+$block.attr('id')+") given object does not appear to be a fullrecord block.");}ABL.FullRecord.Navigation.Remove($block.attr('id'));if($block.next("*").find('.fullrecord-block').size()){$block.animate({height:0},{duration:250,easing:"linear",complete:function(){$block.remove()}})}else{$block.remove()}}},LoadAjaxBlocks:function(){var blockMgr=this;var startTime=(new Date).getTime();if(blockXhr){for(var i=0;i<blockMgr.length;i++){try{blockXhr[i].abort()}catch(_){}}}blockXhr=[];blockXhrId+=1;var localXhrId=blockXhrId;$(".fullrecord-block").each(function(){var url,action,target,$target,callback,dataType,$block;$block=$(this);callback=$block.data('callback');url=$block.data("url");if(!url){return}var action=$block.data("action")||"insert";target=$block.data("targetelement")||$block.data("target-element");$target=$("#"+target);if($target.size()===0){$target=$block}dataType=$block.data("type")||"html";if(!$target&&$target.size()===0&&dataType==="html"){throw new Error("Missing target for fullrecord block.");}blockXhr.push($.ajax({url:url,dataType:dataType,global:false,success:function(data){if(localXhrId!==blockXhrId){return}var loadTime=(new Date).getTime()-startTime;if(!data){blockMgr.RemoveBlock($block,loadTime)}else{if(dataType==="html"){if(!data.length){blockMgr.RemoveBlock($block,loadTime);return}if(action==="insert"){$target.html(data)}else if(action==="replace"){$target.replaceWith(data)}else{throw new Error("action "+action+" not supported");}}$block.trigger('abl:fullrecord:blockinit',[data,loadTime])}},error:function(data){if(localXhrId!==blockXhrId){return}blockMgr.RemoveBlock($block,(new Date).getTime()-startTime)}}))})}},Navigation:{_subNavId:"#subNavigation",Update:function(){var that=this;var $container=$(this._subNavId);if($container.length==0){return false}$container.children().slice(1).remove();$('.fullrecord-block').each(function(){var $this=$(this);if($this.data('include-in-navigation')){if(typeof $this.attr('id')!='undefined'&&!$this.data("url")){ABL.FullRecord.Navigation.Add($this.attr('id'),$this.data('navigation-text'))}}})},Remove:function(id){$(this._subNavId).find('li > a[href="#'+id+'"]').parent().remove()},Add:function(id,name){var text,$item;if(!id){throw new Error("Navigation.Add: id is empty");}ABL.LogInfo('adding id: '+id);text=id.replace('block_','');if($.IsUndefinedOrEmpty(name)){name=$('#'+id).data('navigation-text');if($.IsUndefinedOrEmpty(name)){if(typeof id=='undefined'){name=""}else{name=Localization.Trans('fullrec-nav-'+text)}}}$item=$(this._subNavId).append('<li><a href="#'+id+'" data-scroll="true" data-ga-text="'+text+'">'+name+'</a></li>').css({display:'none'}).fadeIn('fast');$item.find("a").attr("data-ga-action",$("#subNavigationTop").attr("data-ga-action"))}}}})();ABL.Event.bind("abl:fullrecord:updated",function(){ABL.FullRecord.BlockManager.LoadAjaxBlocks();ABL.FullRecord.Navigation.Update();$(function(){PageHelpers.FixElement.Register($(".feedback-top-wrapper"))});var $createApiLink=$('#create-api-link');if($createApiLink.length){$createApiLink.off('click.api');$createApiLink.on('click.api',function(e){var stateObj=State.AsObject();$('#create-api-link-url').remove();$('#create-api-link-key').removeClass('warning');var authorization=$('#create-api-link-key').val();if(!authorization){$('#create-api-link-key').addClass('warning');return}var link=ABL.GetBaseUrl()+'api/v1/details/?id='+stateObj.itemid+'&authorization='+authorization;$createApiLink.after('<div id="create-api-link-url"><a href="'+link+'" target="_blank" class="debug-link">API link</a></div>')})}var $meerOverMedia=$('#meerovermedia');if($meerOverMedia.length){var momImage=new Image;momImage.src=$meerOverMedia.attr('href').replace('olifant.dll','cover.dll');$(momImage).imagesLoaded().always(function(){var width=0;var loadedMomImg=this.img;if(this.isLoaded){if('naturalWidth'in loadedMomImg){width=loadedMomImg.naturalWidth}else{var img=new Image;img.src=loadedMomImg.src;width=img.width}if(width>1){$meerOverMedia.show();PageHelpers.SetContainerVisible($meerOverMedia)}}})}});$(document).on('abl:fullrecord:blockinit','.fullrecord-block',function(event,xmlResult){if($('html').hasClass('ie')&&!$('html').hasClass('ienew')){return}var magnification=1.1;var disabled=false;$(this).find(".scroll-item .zoomable").each(function(){var hasLoaded=false;var $overlay,$figure;var oldWidth,oldHeight,left,top;var $scroller=$(this).parents('.scroller');var fixup=$.noop;var mouseOver=false;$(this).bind("mouseleave blur",function(event){if(!$overlay){return}var figureLeft,figureTop,offset;offset=$(this).offset();figureLeft=offset.left;figureTop=offset.top;if(event.pageX>figureLeft&&event.pageX<figureLeft+$(this).width()&&event.pageY>figureTop&&event.pageY<figureTop+$(this).height()){return}mouseOver=false;if(hasLoaded){$overlay.animate({width:oldWidth,height:oldHeight,top:top,left:left},{duration:200,easing:"linear",step:fixup,complete:function(){$overlay.remove();$overlay=null;$figure.removeClass("overlay");fixup()}})}hasLoaded=false});$(this).bind("mouseenter focus",function(event){if($scroller&&$scroller.size()&&$scroller.first().hasClass("scrolling")){return}if(mouseOver){return}if(disabled){return}if($overlay){return}$figure=$(this);var $this=$(this).find("img");if(!$figure.parents(".scroll-item").hasClass("enabled")){return}mouseOver=true;hasLoaded=false;$overlay=$('<img class="zoom-overlay"/>');var src=$this.css('background-image').replace(/"/g,"").replace(/url\(|\)$/ig,"");if(src=="none"){return}$overlay.attr('src',src);$overlay.bind("mouseleave",function(event){$figure.trigger($.Event("mouseenter",$.extend(event,{__fake:true})));return true});$overlay.bind("click",function(event){disabled=true;$overlay.remove();$figure.parent().trigger("click")});var overlayOffset=$this.offset();function onLoad(){oldWidth=$overlay.width();oldHeight=$overlay.height();width=Math.ceil(oldWidth*magnification);height=Math.ceil(oldHeight*magnification);left=overlayOffset.left;top=overlayOffset.top+$this.innerHeight()-oldHeight;$overlay.css({position:"absolute",display:"none",cursor:"pointer",zIndex:1000,left:left,top:top});var delta=Math.max(0,(height-width)/2);hasLoaded=true;if(mouseOver){$figure.addClass("overlay");$overlay.show();$overlay.animate({width:width,height:height,top:top-(height-oldHeight)/2+delta,left:left-(width-oldWidth)/2},{duration:200,easing:"linear",step:fixup,complete:function(){}})}else{$overlay.remove();$overlay=null;fixup()}}$overlay.load(onLoad);$overlay.hide();$("#fullRecord").prepend($overlay)})});ABL.FullRecord.Navigation.Update();return false});ABL.Event.bind('abl:initialize',function(){$(document).on('abl:fullrecord:blockshow',function(event,data){var $block=data;ABL.FullRecord.Navigation.Add($block.attr('id'),$block.data('navigation-text'))})});function GoogleAnalyticsModule(){this._Settings={};this._GaqInit=false}GoogleAnalyticsModule.prototype=(function(){var undefined;function _FormatRequest(reqJson,ctx){var a,i,j,oldIndex,newArg,args,argVal,key,tmp,undefined;if(!reqJson){return reqJson}for(j=0;j<reqJson.Commands.length;j++){if(reqJson.Commands[j].Command){args=reqJson.Commands[j].Args;for(a=0;a<args.length;a++){newArg='';oldIndex=0;if(typeof args[a]==="string"){args[a]={Value:args[a],Type:"string"}}if(args[a]&&args[a].Value){argVal=args[a].Value}else{continue}for(i=argVal.indexOf("{",0);i>=0;i=argVal.indexOf("{",oldIndex)){newArg+=argVal.substring(oldIndex,i);oldIndex=argVal.indexOf("}",i+1);if(oldIndex<0){throw"Google Analytics: bad format, expected }: "+argVal;}key=argVal.substring(i+1,oldIndex);tmp=ctx[key]||ctx[key.toLowerCase()];if(tmp===undefined||tmp===null){tmp=""}newArg+=tmp;oldIndex+=1}newArg+=argVal.substr(oldIndex);args[a].Value=newArg}}}};function _GetArgArray(args){var result=[];var type;for(var i=0;i<args.length;i++){type=args[i].Type||"string";if(type==="string"){result.push(args[i].Value)}else if(type==="number"){if(args[i].Value){result.push(parseInt(args[i].Value,10))}else{result.push(0)}}else{throw"Google Analytics: type "+type+" not understood.";}}return result}function _GetArgArrayDbgString(args){var result="";for(var i=0;i<args.length;i++){if(typeof args[i]=="string"){result+='"'+args[i]+'", '}else{result+=args[i]+", "}}if(result.length<=2){return result}return result.substr(0,result.length-2)}function _LowerCaseKeys(a){var result={};var lc;if(!a){return a}for(var prop in a){lc=prop.toLowerCase();if(lc in a){result[prop]=a[prop]}else{result[lc]=a[prop]}}return result};function _ParseUrlIntoContext(url){try{var uri=new URI(url);var result={scheme:uri.scheme,authority:uri.authority,path:uri.path,querystring:uri.query,fragment:uri.fragment};if(uri.query){var params=$.getObjectFromQueryString(uri.query);for(var param in params){if(!(param in result)){result[param]=params[param]}}}return result}catch(_){return null}}var testQueue=[];var testEnabled=false;return{Initialize:function(state){this._Settings=State.Settings.Get('GoogleAnalytics')||{};var ga=this;$(document).on("click","*[data-ga-action]",function(e){ga.FireOn($(this))})},GetContext:function($el){var gaArgJson,i,atts,prop,propVal,attVals,override,tmp,href,urlContext;$el=$el||$(this);if(!$el){return null}try{gaArgJson=$el.attr("data-ga-args");gaArgJson=gaArgJson?$.parseJSON(gaArgJson):gaArgJson;if(typeof gaArgJson=="string"){gaArgJson=jQuery.parseJSON(gaArgJson)}else if(!gaArgJson){gaArgJson={}}atts=$el.get(0).attributes;if(atts&&atts.length){attVals={};for(i=0;i<atts.length;i++){override=false;if(atts[i].name.indexOf("data-ga-")==0){prop=atts[i].name.substr(8);if(!prop||prop=="action"||prop=="args"){continue}override=true}else{prop=atts[i].name;if(prop=="href"){continue}}propVal=atts[i].value;if(override||!(prop in attVals)){attVals[prop]=propVal}}for(prop in attVals){if(!(prop in gaArgJson)){gaArgJson[prop]=attVals[prop]}}}if($el.is("input[type=checkbox]")){if(!("checked"in gaArgJson)){gaArgJson["checked"]=$el.is(":checked")+""}}href=$el.attr("href");if(href){href=href.replace(/(&|\?)(rctx=.*?)(&|$)/,"$1");urlContext=_ParseUrlIntoContext(href);for(prop in urlContext){if(!(prop in gaArgJson)){gaArgJson[prop]=urlContext[prop]}}if(!("href"in gaArgJson)){gaArgJson["href"]=href}}if(!("text"in gaArgJson)){gaArgJson["text"]=$el.text()}return gaArgJson}catch(_){ABL.ExceptionHandler.HandleException(_,"failed Google Analytics log");return null}},_GetGaq:function(){if(window._gaq==undefined){window._gaq=[]}var _gaq=window._gaq;var that=this;if(this._GaqInit===false){if(this._Settings&&_gaq){jQuery.each(this._Settings,function(key,val){that.PushAnalyticsCommand(_gaq,key,val)})}this._GaqInit=true}return _gaq},FireOn:function($el,requestJson,jsContext){if(!requestJson){requestJson=$el.attr("data-ga-action");if(!requestJson){return}requestJson=$.parseJSON(requestJson)}if(!jsContext){jsContext=this.GetContext($el)}this.Fire(requestJson,jsContext)},FireCallback:function(requestJson,jsContext){var ga=this;return function(){ga.FireOn($(this),requestJson,jsContext)}},Fire:function(requestJson,jsContext){var gaReq;try{if(!requestJson){return}if(typeof requestJson==="string"){ABL.Log("Got analytics json: "+requestJson);gaReq=jQuery.parseJSON(requestJson)}else{ABL.Log("Got analytics json: "+JSON.stringify(requestJson));gaReq=requestJson}if(jsContext){if(typeof jsContext==="string"){jsContext=jQuery.parseJSON(jsContext)}_LowerCaseKeys(jsContext);_FormatRequest(gaReq,jsContext)}var _gaq=this._GetGaq();if(!_gaq){ABL.LogError("No Google Analytics Async Queue found.");return}testEnabled=!!State.Get("debug");for(var i=0;i<gaReq.Accounts.length;i++){ABL.LogInfo("> Running commands for account "+gaReq.Accounts[i]);this.PushAnalyticsCommand(_gaq,"_setAccount",gaReq.Accounts[i]);var providerPrefix=ABL.GetProviderPrefix();providerPrefix=(providerPrefix.length<=0?"":providerPrefix+"/");var subPage;if(jsContext&&'page'in jsContext){subPage=State.GetCurrentSubPage(jsContext['page'])}else{subPage=State.GetCurrentSubPage()}this.PushAnalyticsCommand(_gaq,"_trackPageview",providerPrefix+subPage);for(var j=0;j<gaReq.Commands.length;j++){this.PushAnalyticsCommands(_gaq,gaReq.Commands[j].Command,gaReq.Commands[j].Args)}}}catch(_){ABL.ExceptionHandler.HandleException(_,"failed Google Analytics log")}},PushAnalyticsCommand:function(queue,cmd,arg){if(typeof arg==='undefined'||arg===null){queue.push([cmd]);ABL.LogInfo("Queued command: ['"+cmd+"']")}else{queue.push([cmd,arg]);ABL.LogInfo("Queued command: ['"+cmd+"', "+(typeof arg=="string"?("'"+arg+"'"):arg)+"]")}if(testEnabled){testQueue.push([cmd,arg])}},PushAnalyticsCommands:function(queue,cmd,args){args=_GetArgArray(args);queue.push([cmd].concat(args));ABL.LogInfo("Queued command: ['"+cmd+"', "+_GetArgArrayDbgString(args)+"]");if(testEnabled){testQueue.push([cmd].concat(args))}},DequeueTestCommands:function(){var result=testQueue;testQueue=[];return result},GetTestCommands:function(){return testQueue}}})();ABL.RegisterLegacyModule("GA",GoogleAnalyticsModule);