\n * **Note:** The template instance and the link instance may be different objects if the template has\n * been cloned. For this reason it is **not** safe to do anything other than DOM transformations that\n * apply to all cloned DOM nodes within the compile function. Specifically, DOM listener registration\n * should be done in a linking function rather than in a compile function.\n *
\n\n * \n * **Note:** The compile function cannot handle directives that recursively use themselves in their\n * own templates or compile functions. Compiling these directives results in an infinite loop and a\n * stack overflow errors.\n *\n * This can be avoided by manually using $compile in the postLink function to imperatively compile\n * a directive's template instead of relying on automatic template compilation via `template` or\n * `templateUrl` declaration or manual compilation inside the compile function.\n *
\n *\n * \n * **Note:** The `transclude` function that is passed to the compile function is deprecated, as it\n * e.g. does not know about the right outer scope. Please use the transclude function that is passed\n * to the link function instead.\n *
\n\n * A compile function can have a return value which can be either a function or an object.\n *\n * * returning a (post-link) function - is equivalent to registering the linking function via the\n * `link` property of the config object when the compile function is empty.\n *\n * * returning an object with function(s) registered via `pre` and `post` properties - allows you to\n * control when a linking function should be called during the linking phase. See info about\n * pre-linking and post-linking functions below.\n *\n *\n * #### `link`\n * This property is used only if the `compile` property is not defined.\n *\n * ```js\n * function link(scope, iElement, iAttrs, controller, transcludeFn) { ... }\n * ```\n *\n * The link function is responsible for registering DOM listeners as well as updating the DOM. It is\n * executed after the template has been cloned. This is where most of the directive logic will be\n * put.\n *\n * * `scope` - {@link ng.$rootScope.Scope Scope} - The scope to be used by the\n * directive for registering {@link ng.$rootScope.Scope#$watch watches}.\n *\n * * `iElement` - instance element - The element where the directive is to be used. It is safe to\n * manipulate the children of the element only in `postLink` function since the children have\n * already been linked.\n *\n * * `iAttrs` - instance attributes - Normalized list of attributes declared on this element shared\n * between all directive linking functions.\n *\n * * `controller` - the directive's required controller instance(s) - Instances are shared\n * among all directives, which allows the directives to use the controllers as a communication\n * channel. The exact value depends on the directive's `require` property:\n * * no controller(s) required: the directive's own controller, or `undefined` if it doesn't have one\n * * `string`: the controller instance\n * * `array`: array of controller instances\n *\n * If a required controller cannot be found, and it is optional, the instance is `null`,\n * otherwise the {@link error:$compile:ctreq Missing Required Controller} error is thrown.\n *\n * Note that you can also require the directive's own controller - it will be made available like\n * any other controller.\n *\n * * `transcludeFn` - A transclude linking function pre-bound to the correct transclusion scope.\n * This is the same as the `$transclude`\n * parameter of directive controllers, see there for details.\n * `function([scope], cloneLinkingFn, futureParentElement)`.\n *\n * #### Pre-linking function\n *\n * Executed before the child elements are linked. Not safe to do DOM transformation since the\n * compiler linking function will fail to locate the correct elements for linking.\n *\n * #### Post-linking function\n *\n * Executed after the child elements are linked.\n *\n * Note that child elements that contain `templateUrl` directives will not have been compiled\n * and linked since they are waiting for their template to load asynchronously and their own\n * compilation and linking has been suspended until that occurs.\n *\n * It is safe to do DOM transformation in the post-linking function on elements that are not waiting\n * for their async templates to be resolved.\n *\n *\n * ### Transclusion\n *\n * Transclusion is the process of extracting a collection of DOM elements from one part of the DOM and\n * copying them to another part of the DOM, while maintaining their connection to the original AngularJS\n * scope from where they were taken.\n *\n * Transclusion is used (often with {@link ngTransclude}) to insert the\n * original contents of a directive's element into a specified place in the template of the directive.\n * The benefit of transclusion, over simply moving the DOM elements manually, is that the transcluded\n * content has access to the properties on the scope from which it was taken, even if the directive\n * has isolated scope.\n * See the {@link guide/directive#creating-a-directive-that-wraps-other-elements Directives Guide}.\n *\n * This makes it possible for the widget to have private state for its template, while the transcluded\n * content has access to its originating scope.\n *\n * \n * **Note:** When testing an element transclude directive you must not place the directive at the root of the\n * DOM fragment that is being compiled. See {@link guide/unit-testing#testing-transclusion-directives\n * Testing Transclusion Directives}.\n *
\n *\n * #### Transclusion Functions\n *\n * When a directive requests transclusion, the compiler extracts its contents and provides a **transclusion\n * function** to the directive's `link` function and `controller`. This transclusion function is a special\n * **linking function** that will return the compiled contents linked to a new transclusion scope.\n *\n * \n * If you are just using {@link ngTransclude} then you don't need to worry about this function, since\n * ngTransclude will deal with it for us.\n *
\n *\n * If you want to manually control the insertion and removal of the transcluded content in your directive\n * then you must use this transclude function. When you call a transclude function it returns a a jqLite/JQuery\n * object that contains the compiled DOM, which is linked to the correct transclusion scope.\n *\n * When you call a transclusion function you can pass in a **clone attach function**. This function accepts\n * two parameters, `function(clone, scope) { ... }`, where the `clone` is a fresh compiled copy of your transcluded\n * content and the `scope` is the newly created transclusion scope, to which the clone is bound.\n *\n * \n * **Best Practice**: Always provide a `cloneFn` (clone attach function) when you call a translude function\n * since you then get a fresh clone of the original DOM and also have access to the new transclusion scope.\n *
\n *\n * It is normal practice to attach your transcluded content (`clone`) to the DOM inside your **clone\n * attach function**:\n *\n * ```js\n * var transcludedContent, transclusionScope;\n *\n * $transclude(function(clone, scope) {\n * element.append(clone);\n * transcludedContent = clone;\n * transclusionScope = scope;\n * });\n * ```\n *\n * Later, if you want to remove the transcluded content from your DOM then you should also destroy the\n * associated transclusion scope:\n *\n * ```js\n * transcludedContent.remove();\n * transclusionScope.$destroy();\n * ```\n *\n * \n * **Best Practice**: if you intend to add and remove transcluded content manually in your directive\n * (by calling the transclude function to get the DOM and calling `element.remove()` to remove it),\n * then you are also responsible for calling `$destroy` on the transclusion scope.\n *
\n *\n * The built-in DOM manipulation directives, such as {@link ngIf}, {@link ngSwitch} and {@link ngRepeat}\n * automatically destroy their transluded clones as necessary so you do not need to worry about this if\n * you are simply using {@link ngTransclude} to inject the transclusion into your directive.\n *\n *\n * #### Transclusion Scopes\n *\n * When you call a transclude function it returns a DOM fragment that is pre-bound to a **transclusion\n * scope**. This scope is special, in that it is a child of the directive's scope (and so gets destroyed\n * when the directive's scope gets destroyed) but it inherits the properties of the scope from which it\n * was taken.\n *\n * For example consider a directive that uses transclusion and isolated scope. The DOM hierarchy might look\n * like this:\n *\n * ```html\n * \n * **Note**: Typically directives are registered with `module.directive`. The example below is\n * to illustrate how `$compile` works.\n *
\n *\n \n * **Note:** Passing a `transclude` function to the $compile function is deprecated, as it\n * e.g. will not use the right outer scope. Please pass the transclude function as a\n * `parentBoundTranscludeFn` to the link function instead.\n *
\n *\n * @param {number} maxPriority only apply directives lower than given priority (Only effects the\n * root element(s), not their children)\n * @returns {function(scope, cloneAttachFn=, options=)} a link function which is used to bind template\n * (a DOM element/tree) to a scope. Where:\n *\n * * `scope` - A {@link ng.$rootScope.Scope Scope} to bind to.\n * * `cloneAttachFn` - If `cloneAttachFn` is provided, then the link function will clone the\n * `template` and call the `cloneAttachFn` function allowing the caller to attach the\n * cloned elements to the DOM document at the appropriate place. The `cloneAttachFn` is\n * called as: \n forEach($compileNodes, function(node, index) {\n if (node.nodeType == NODE_TYPE_TEXT && node.nodeValue.match(/\\S+/) /* non-empty */ ) {\n $compileNodes[index] = jqLite(node).wrap('').parent()[0];\n }\n });\n var compositeLinkFn =\n compileNodes($compileNodes, transcludeFn, $compileNodes,\n maxPriority, ignoreDirective, previousCompileContext);\n compile.$$addScopeClass($compileNodes);\n var namespace = null;\n return function publicLinkFn(scope, cloneConnectFn, options) {\n assertArg(scope, 'scope');\n\n if (previousCompileContext && previousCompileContext.needsNewScope) {\n // A parent directive did a replace and a directive on this element asked\n // for transclusion, which caused us to lose a layer of element on which\n // we could hold the new transclusion scope, so we will create it manually\n // here.\n scope = scope.$parent.$new();\n }\n\n options = options || {};\n var parentBoundTranscludeFn = options.parentBoundTranscludeFn,\n transcludeControllers = options.transcludeControllers,\n futureParentElement = options.futureParentElement;\n\n // When `parentBoundTranscludeFn` is passed, it is a\n // `controllersBoundTransclude` function (it was previously passed\n // as `transclude` to directive.link) so we must unwrap it to get\n // its `boundTranscludeFn`\n if (parentBoundTranscludeFn && parentBoundTranscludeFn.$$boundTransclude) {\n parentBoundTranscludeFn = parentBoundTranscludeFn.$$boundTransclude;\n }\n\n if (!namespace) {\n namespace = detectNamespaceForChildElements(futureParentElement);\n }\n var $linkNode;\n if (namespace !== 'html') {\n // When using a directive with replace:true and templateUrl the $compileNodes\n // (or a child element inside of them)\n // might change, so we need to recreate the namespace adapted compileNodes\n // for call to the link function.\n // Note: This will already clone the nodes...\n $linkNode = jqLite(\n wrapTemplate(namespace, jqLite('').append($compileNodes).html())\n );\n } else if (cloneConnectFn) {\n // important!!: we must call our jqLite.clone() since the jQuery one is trying to be smart\n // and sometimes changes the structure of the DOM.\n $linkNode = JQLitePrototype.clone.call($compileNodes);\n } else {\n $linkNode = $compileNodes;\n }\n\n if (transcludeControllers) {\n for (var controllerName in transcludeControllers) {\n $linkNode.data('$' + controllerName + 'Controller', transcludeControllers[controllerName].instance);\n }\n }\n\n compile.$$addScopeInfo($linkNode, scope);\n\n if (cloneConnectFn) cloneConnectFn($linkNode, scope);\n if (compositeLinkFn) compositeLinkFn(scope, $linkNode, $linkNode, parentBoundTranscludeFn);\n return $linkNode;\n };\n }\n\n function detectNamespaceForChildElements(parentElement) {\n // TODO: Make this detect MathML as well...\n var node = parentElement && parentElement[0];\n if (!node) {\n return 'html';\n } else {\n return nodeName_(node) !== 'foreignobject' && node.toString().match(/SVG/) ? 'svg' : 'html';\n }\n }\n\n /**\n * Compile function matches each node in nodeList against the directives. Once all directives\n * for a particular node are collected their compile functions are executed. The compile\n * functions return values - the linking functions - are combined into a composite linking\n * function, which is the a linking function for the node.\n *\n * @param {NodeList} nodeList an array of nodes or NodeList to compile\n * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the\n * scope argument is auto-generated to the new child of the transcluded parent scope.\n * @param {DOMElement=} $rootElement If the nodeList is the root of the compilation tree then\n * the rootElement must be set the jqLite collection of the compile root. This is\n * needed so that the jqLite collection items can be replaced with widgets.\n * @param {number=} maxPriority Max directive priority.\n * @returns {Function} A composite linking function of all of the matched directives or null.\n */\n function compileNodes(nodeList, transcludeFn, $rootElement, maxPriority, ignoreDirective,\n previousCompileContext) {\n var linkFns = [],\n attrs, directives, nodeLinkFn, childNodes, childLinkFn, linkFnFound, nodeLinkFnFound;\n\n for (var i = 0; i < nodeList.length; i++) {\n attrs = new Attributes();\n\n // we must always refer to nodeList[i] since the nodes can be replaced underneath us.\n directives = collectDirectives(nodeList[i], [], attrs, i === 0 ? maxPriority : undefined,\n ignoreDirective);\n\n nodeLinkFn = (directives.length)\n ? applyDirectivesToNode(directives, nodeList[i], attrs, transcludeFn, $rootElement,\n null, [], [], previousCompileContext)\n : null;\n\n if (nodeLinkFn && nodeLinkFn.scope) {\n compile.$$addScopeClass(attrs.$$element);\n }\n\n childLinkFn = (nodeLinkFn && nodeLinkFn.terminal ||\n !(childNodes = nodeList[i].childNodes) ||\n !childNodes.length)\n ? null\n : compileNodes(childNodes,\n nodeLinkFn ? (\n (nodeLinkFn.transcludeOnThisElement || !nodeLinkFn.templateOnThisElement)\n && nodeLinkFn.transclude) : transcludeFn);\n\n if (nodeLinkFn || childLinkFn) {\n linkFns.push(i, nodeLinkFn, childLinkFn);\n linkFnFound = true;\n nodeLinkFnFound = nodeLinkFnFound || nodeLinkFn;\n }\n\n //use the previous context only for the first element in the virtual group\n previousCompileContext = null;\n }\n\n // return a linking function if we have found anything, null otherwise\n return linkFnFound ? compositeLinkFn : null;\n\n function compositeLinkFn(scope, nodeList, $rootElement, parentBoundTranscludeFn) {\n var nodeLinkFn, childLinkFn, node, childScope, i, ii, idx, childBoundTranscludeFn;\n var stableNodeList;\n\n\n if (nodeLinkFnFound) {\n // copy nodeList so that if a nodeLinkFn removes or adds an element at this DOM level our\n // offsets don't get screwed up\n var nodeListLength = nodeList.length;\n stableNodeList = new Array(nodeListLength);\n\n // create a sparse array by only copying the elements which have a linkFn\n for (i = 0; i < linkFns.length; i+=3) {\n idx = linkFns[i];\n stableNodeList[idx] = nodeList[idx];\n }\n } else {\n stableNodeList = nodeList;\n }\n\n for (i = 0, ii = linkFns.length; i < ii;) {\n node = stableNodeList[linkFns[i++]];\n nodeLinkFn = linkFns[i++];\n childLinkFn = linkFns[i++];\n\n if (nodeLinkFn) {\n if (nodeLinkFn.scope) {\n childScope = scope.$new();\n compile.$$addScopeInfo(jqLite(node), childScope);\n } else {\n childScope = scope;\n }\n\n if (nodeLinkFn.transcludeOnThisElement) {\n childBoundTranscludeFn = createBoundTranscludeFn(\n scope, nodeLinkFn.transclude, parentBoundTranscludeFn);\n\n } else if (!nodeLinkFn.templateOnThisElement && parentBoundTranscludeFn) {\n childBoundTranscludeFn = parentBoundTranscludeFn;\n\n } else if (!parentBoundTranscludeFn && transcludeFn) {\n childBoundTranscludeFn = createBoundTranscludeFn(scope, transcludeFn);\n\n } else {\n childBoundTranscludeFn = null;\n }\n\n nodeLinkFn(childLinkFn, childScope, node, $rootElement, childBoundTranscludeFn);\n\n } else if (childLinkFn) {\n childLinkFn(scope, node.childNodes, undefined, parentBoundTranscludeFn);\n }\n }\n }\n }\n\n function createBoundTranscludeFn(scope, transcludeFn, previousBoundTranscludeFn) {\n\n var boundTranscludeFn = function(transcludedScope, cloneFn, controllers, futureParentElement, containingScope) {\n\n if (!transcludedScope) {\n transcludedScope = scope.$new(false, containingScope);\n transcludedScope.$$transcluded = true;\n }\n\n return transcludeFn(transcludedScope, cloneFn, {\n parentBoundTranscludeFn: previousBoundTranscludeFn,\n transcludeControllers: controllers,\n futureParentElement: futureParentElement\n });\n };\n\n return boundTranscludeFn;\n }\n\n /**\n * Looks for directives on the given node and adds them to the directive collection which is\n * sorted.\n *\n * @param node Node to search.\n * @param directives An array to which the directives are added to. This array is sorted before\n * the function returns.\n * @param attrs The shared attrs object which is used to populate the normalized attributes.\n * @param {number=} maxPriority Max directive priority.\n */\n function collectDirectives(node, directives, attrs, maxPriority, ignoreDirective) {\n var nodeType = node.nodeType,\n attrsMap = attrs.$attr,\n match,\n className;\n\n switch (nodeType) {\n case NODE_TYPE_ELEMENT: /* Element */\n // use the node name:
\n addDirective(directives,\n directiveNormalize(nodeName_(node)), 'E', maxPriority, ignoreDirective);\n\n // iterate over the attributes\n for (var attr, name, nName, ngAttrName, value, isNgAttr, nAttrs = node.attributes,\n j = 0, jj = nAttrs && nAttrs.length; j < jj; j++) {\n var attrStartName = false;\n var attrEndName = false;\n\n attr = nAttrs[j];\n name = attr.name;\n value = trim(attr.value);\n\n // support ngAttr attribute binding\n ngAttrName = directiveNormalize(name);\n if (isNgAttr = NG_ATTR_BINDING.test(ngAttrName)) {\n name = name.replace(PREFIX_REGEXP, '')\n .substr(8).replace(/_(.)/g, function(match, letter) {\n return letter.toUpperCase();\n });\n }\n\n var multiElementMatch = ngAttrName.match(MULTI_ELEMENT_DIR_RE);\n if (multiElementMatch && directiveIsMultiElement(multiElementMatch[1])) {\n attrStartName = name;\n attrEndName = name.substr(0, name.length - 5) + 'end';\n name = name.substr(0, name.length - 6);\n }\n\n nName = directiveNormalize(name.toLowerCase());\n attrsMap[nName] = name;\n if (isNgAttr || !attrs.hasOwnProperty(nName)) {\n attrs[nName] = value;\n if (getBooleanAttrName(node, nName)) {\n attrs[nName] = true; // presence means true\n }\n }\n addAttrInterpolateDirective(node, directives, value, nName, isNgAttr);\n addDirective(directives, nName, 'A', maxPriority, ignoreDirective, attrStartName,\n attrEndName);\n }\n\n // use class as directive\n className = node.className;\n if (isObject(className)) {\n // Maybe SVGAnimatedString\n className = className.animVal;\n }\n if (isString(className) && className !== '') {\n while (match = CLASS_DIRECTIVE_REGEXP.exec(className)) {\n nName = directiveNormalize(match[2]);\n if (addDirective(directives, nName, 'C', maxPriority, ignoreDirective)) {\n attrs[nName] = trim(match[3]);\n }\n className = className.substr(match.index + match[0].length);\n }\n }\n break;\n case NODE_TYPE_TEXT: /* Text Node */\n if (msie === 11) {\n // Workaround for #11781\n while (node.parentNode && node.nextSibling && node.nextSibling.nodeType === NODE_TYPE_TEXT) {\n node.nodeValue = node.nodeValue + node.nextSibling.nodeValue;\n node.parentNode.removeChild(node.nextSibling);\n }\n }\n addTextInterpolateDirective(directives, node.nodeValue);\n break;\n case NODE_TYPE_COMMENT: /* Comment */\n try {\n match = COMMENT_DIRECTIVE_REGEXP.exec(node.nodeValue);\n if (match) {\n nName = directiveNormalize(match[1]);\n if (addDirective(directives, nName, 'M', maxPriority, ignoreDirective)) {\n attrs[nName] = trim(match[2]);\n }\n }\n } catch (e) {\n // turns out that under some circumstances IE9 throws errors when one attempts to read\n // comment's node value.\n // Just ignore it and continue. (Can't seem to reproduce in test case.)\n }\n break;\n }\n\n directives.sort(byPriority);\n return directives;\n }\n\n /**\n * Given a node with an directive-start it collects all of the siblings until it finds\n * directive-end.\n * @param node\n * @param attrStart\n * @param attrEnd\n * @returns {*}\n */\n function groupScan(node, attrStart, attrEnd) {\n var nodes = [];\n var depth = 0;\n if (attrStart && node.hasAttribute && node.hasAttribute(attrStart)) {\n do {\n if (!node) {\n throw $compileMinErr('uterdir',\n \"Unterminated attribute, found '{0}' but no matching '{1}' found.\",\n attrStart, attrEnd);\n }\n if (node.nodeType == NODE_TYPE_ELEMENT) {\n if (node.hasAttribute(attrStart)) depth++;\n if (node.hasAttribute(attrEnd)) depth--;\n }\n nodes.push(node);\n node = node.nextSibling;\n } while (depth > 0);\n } else {\n nodes.push(node);\n }\n\n return jqLite(nodes);\n }\n\n /**\n * Wrapper for linking function which converts normal linking function into a grouped\n * linking function.\n * @param linkFn\n * @param attrStart\n * @param attrEnd\n * @returns {Function}\n */\n function groupElementsLinkFnWrapper(linkFn, attrStart, attrEnd) {\n return function(scope, element, attrs, controllers, transcludeFn) {\n element = groupScan(element[0], attrStart, attrEnd);\n return linkFn(scope, element, attrs, controllers, transcludeFn);\n };\n }\n\n /**\n * Once the directives have been collected, their compile functions are executed. This method\n * is responsible for inlining directive templates as well as terminating the application\n * of the directives if the terminal directive has been reached.\n *\n * @param {Array} directives Array of collected directives to execute their compile function.\n * this needs to be pre-sorted by priority order.\n * @param {Node} compileNode The raw DOM node to apply the compile functions to\n * @param {Object} templateAttrs The shared attribute function\n * @param {function(angular.Scope, cloneAttachFn=)} transcludeFn A linking function, where the\n * scope argument is auto-generated to the new\n * child of the transcluded parent scope.\n * @param {JQLite} jqCollection If we are working on the root of the compile tree then this\n * argument has the root jqLite array so that we can replace nodes\n * on it.\n * @param {Object=} originalReplaceDirective An optional directive that will be ignored when\n * compiling the transclusion.\n * @param {Array.} preLinkFns\n * @param {Array.} postLinkFns\n * @param {Object} previousCompileContext Context used for previous compilation of the current\n * node\n * @returns {Function} linkFn\n */\n function applyDirectivesToNode(directives, compileNode, templateAttrs, transcludeFn,\n jqCollection, originalReplaceDirective, preLinkFns, postLinkFns,\n previousCompileContext) {\n previousCompileContext = previousCompileContext || {};\n\n var terminalPriority = -Number.MAX_VALUE,\n newScopeDirective = previousCompileContext.newScopeDirective,\n controllerDirectives = previousCompileContext.controllerDirectives,\n newIsolateScopeDirective = previousCompileContext.newIsolateScopeDirective,\n templateDirective = previousCompileContext.templateDirective,\n nonTlbTranscludeDirective = previousCompileContext.nonTlbTranscludeDirective,\n hasTranscludeDirective = false,\n hasTemplate = false,\n hasElementTranscludeDirective = previousCompileContext.hasElementTranscludeDirective,\n $compileNode = templateAttrs.$$element = jqLite(compileNode),\n directive,\n directiveName,\n $template,\n replaceDirective = originalReplaceDirective,\n childTranscludeFn = transcludeFn,\n linkFn,\n directiveValue;\n\n // executes all directives on the current element\n for (var i = 0, ii = directives.length; i < ii; i++) {\n directive = directives[i];\n var attrStart = directive.$$start;\n var attrEnd = directive.$$end;\n\n // collect multiblock sections\n if (attrStart) {\n $compileNode = groupScan(compileNode, attrStart, attrEnd);\n }\n $template = undefined;\n\n if (terminalPriority > directive.priority) {\n break; // prevent further processing of directives\n }\n\n if (directiveValue = directive.scope) {\n\n // skip the check for directives with async templates, we'll check the derived sync\n // directive when the template arrives\n if (!directive.templateUrl) {\n if (isObject(directiveValue)) {\n // This directive is trying to add an isolated scope.\n // Check that there is no scope of any kind already\n assertNoDuplicate('new/isolated scope', newIsolateScopeDirective || newScopeDirective,\n directive, $compileNode);\n newIsolateScopeDirective = directive;\n } else {\n // This directive is trying to add a child scope.\n // Check that there is no isolated scope already\n assertNoDuplicate('new/isolated scope', newIsolateScopeDirective, directive,\n $compileNode);\n }\n }\n\n newScopeDirective = newScopeDirective || directive;\n }\n\n directiveName = directive.name;\n\n if (!directive.templateUrl && directive.controller) {\n directiveValue = directive.controller;\n controllerDirectives = controllerDirectives || createMap();\n assertNoDuplicate(\"'\" + directiveName + \"' controller\",\n controllerDirectives[directiveName], directive, $compileNode);\n controllerDirectives[directiveName] = directive;\n }\n\n if (directiveValue = directive.transclude) {\n hasTranscludeDirective = true;\n\n // Special case ngIf and ngRepeat so that we don't complain about duplicate transclusion.\n // This option should only be used by directives that know how to safely handle element transclusion,\n // where the transcluded nodes are added or replaced after linking.\n if (!directive.$$tlb) {\n assertNoDuplicate('transclusion', nonTlbTranscludeDirective, directive, $compileNode);\n nonTlbTranscludeDirective = directive;\n }\n\n if (directiveValue == 'element') {\n hasElementTranscludeDirective = true;\n terminalPriority = directive.priority;\n $template = $compileNode;\n $compileNode = templateAttrs.$$element =\n jqLite(document.createComment(' ' + directiveName + ': ' +\n templateAttrs[directiveName] + ' '));\n compileNode = $compileNode[0];\n replaceWith(jqCollection, sliceArgs($template), compileNode);\n\n childTranscludeFn = compile($template, transcludeFn, terminalPriority,\n replaceDirective && replaceDirective.name, {\n // Don't pass in:\n // - controllerDirectives - otherwise we'll create duplicates controllers\n // - newIsolateScopeDirective or templateDirective - combining templates with\n // element transclusion doesn't make sense.\n //\n // We need only nonTlbTranscludeDirective so that we prevent putting transclusion\n // on the same element more than once.\n nonTlbTranscludeDirective: nonTlbTranscludeDirective\n });\n } else {\n $template = jqLite(jqLiteClone(compileNode)).contents();\n $compileNode.empty(); // clear contents\n childTranscludeFn = compile($template, transcludeFn, undefined,\n undefined, { needsNewScope: directive.$$isolateScope || directive.$$newScope});\n }\n }\n\n if (directive.template) {\n hasTemplate = true;\n assertNoDuplicate('template', templateDirective, directive, $compileNode);\n templateDirective = directive;\n\n directiveValue = (isFunction(directive.template))\n ? directive.template($compileNode, templateAttrs)\n : directive.template;\n\n directiveValue = denormalizeTemplate(directiveValue);\n\n if (directive.replace) {\n replaceDirective = directive;\n if (jqLiteIsTextNode(directiveValue)) {\n $template = [];\n } else {\n $template = removeComments(wrapTemplate(directive.templateNamespace, trim(directiveValue)));\n }\n compileNode = $template[0];\n\n if ($template.length != 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {\n throw $compileMinErr('tplrt',\n \"Template for directive '{0}' must have exactly one root element. {1}\",\n directiveName, '');\n }\n\n replaceWith(jqCollection, $compileNode, compileNode);\n\n var newTemplateAttrs = {$attr: {}};\n\n // combine directives from the original node and from the template:\n // - take the array of directives for this element\n // - split it into two parts, those that already applied (processed) and those that weren't (unprocessed)\n // - collect directives from the template and sort them by priority\n // - combine directives as: processed + template + unprocessed\n var templateDirectives = collectDirectives(compileNode, [], newTemplateAttrs);\n var unprocessedDirectives = directives.splice(i + 1, directives.length - (i + 1));\n\n if (newIsolateScopeDirective || newScopeDirective) {\n // The original directive caused the current element to be replaced but this element\n // also needs to have a new scope, so we need to tell the template directives\n // that they would need to get their scope from further up, if they require transclusion\n markDirectiveScope(templateDirectives, newIsolateScopeDirective, newScopeDirective);\n }\n directives = directives.concat(templateDirectives).concat(unprocessedDirectives);\n mergeTemplateAttributes(templateAttrs, newTemplateAttrs);\n\n ii = directives.length;\n } else {\n $compileNode.html(directiveValue);\n }\n }\n\n if (directive.templateUrl) {\n hasTemplate = true;\n assertNoDuplicate('template', templateDirective, directive, $compileNode);\n templateDirective = directive;\n\n if (directive.replace) {\n replaceDirective = directive;\n }\n\n nodeLinkFn = compileTemplateUrl(directives.splice(i, directives.length - i), $compileNode,\n templateAttrs, jqCollection, hasTranscludeDirective && childTranscludeFn, preLinkFns, postLinkFns, {\n controllerDirectives: controllerDirectives,\n newScopeDirective: (newScopeDirective !== directive) && newScopeDirective,\n newIsolateScopeDirective: newIsolateScopeDirective,\n templateDirective: templateDirective,\n nonTlbTranscludeDirective: nonTlbTranscludeDirective\n });\n ii = directives.length;\n } else if (directive.compile) {\n try {\n linkFn = directive.compile($compileNode, templateAttrs, childTranscludeFn);\n if (isFunction(linkFn)) {\n addLinkFns(null, linkFn, attrStart, attrEnd);\n } else if (linkFn) {\n addLinkFns(linkFn.pre, linkFn.post, attrStart, attrEnd);\n }\n } catch (e) {\n $exceptionHandler(e, startingTag($compileNode));\n }\n }\n\n if (directive.terminal) {\n nodeLinkFn.terminal = true;\n terminalPriority = Math.max(terminalPriority, directive.priority);\n }\n\n }\n\n nodeLinkFn.scope = newScopeDirective && newScopeDirective.scope === true;\n nodeLinkFn.transcludeOnThisElement = hasTranscludeDirective;\n nodeLinkFn.templateOnThisElement = hasTemplate;\n nodeLinkFn.transclude = childTranscludeFn;\n\n previousCompileContext.hasElementTranscludeDirective = hasElementTranscludeDirective;\n\n // might be normal or delayed nodeLinkFn depending on if templateUrl is present\n return nodeLinkFn;\n\n ////////////////////\n\n function addLinkFns(pre, post, attrStart, attrEnd) {\n if (pre) {\n if (attrStart) pre = groupElementsLinkFnWrapper(pre, attrStart, attrEnd);\n pre.require = directive.require;\n pre.directiveName = directiveName;\n if (newIsolateScopeDirective === directive || directive.$$isolateScope) {\n pre = cloneAndAnnotateFn(pre, {isolateScope: true});\n }\n preLinkFns.push(pre);\n }\n if (post) {\n if (attrStart) post = groupElementsLinkFnWrapper(post, attrStart, attrEnd);\n post.require = directive.require;\n post.directiveName = directiveName;\n if (newIsolateScopeDirective === directive || directive.$$isolateScope) {\n post = cloneAndAnnotateFn(post, {isolateScope: true});\n }\n postLinkFns.push(post);\n }\n }\n\n\n function getControllers(directiveName, require, $element, elementControllers) {\n var value;\n\n if (isString(require)) {\n var match = require.match(REQUIRE_PREFIX_REGEXP);\n var name = require.substring(match[0].length);\n var inheritType = match[1] || match[3];\n var optional = match[2] === '?';\n\n //If only parents then start at the parent element\n if (inheritType === '^^') {\n $element = $element.parent();\n //Otherwise attempt getting the controller from elementControllers in case\n //the element is transcluded (and has no data) and to avoid .data if possible\n } else {\n value = elementControllers && elementControllers[name];\n value = value && value.instance;\n }\n\n if (!value) {\n var dataName = '$' + name + 'Controller';\n value = inheritType ? $element.inheritedData(dataName) : $element.data(dataName);\n }\n\n if (!value && !optional) {\n throw $compileMinErr('ctreq',\n \"Controller '{0}', required by directive '{1}', can't be found!\",\n name, directiveName);\n }\n } else if (isArray(require)) {\n value = [];\n for (var i = 0, ii = require.length; i < ii; i++) {\n value[i] = getControllers(directiveName, require[i], $element, elementControllers);\n }\n }\n\n return value || null;\n }\n\n function setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope) {\n var elementControllers = createMap();\n for (var controllerKey in controllerDirectives) {\n var directive = controllerDirectives[controllerKey];\n var locals = {\n $scope: directive === newIsolateScopeDirective || directive.$$isolateScope ? isolateScope : scope,\n $element: $element,\n $attrs: attrs,\n $transclude: transcludeFn\n };\n\n var controller = directive.controller;\n if (controller == '@') {\n controller = attrs[directive.name];\n }\n\n var controllerInstance = $controller(controller, locals, true, directive.controllerAs);\n\n // For directives with element transclusion the element is a comment,\n // but jQuery .data doesn't support attaching data to comment nodes as it's hard to\n // clean up (http://bugs.jquery.com/ticket/8335).\n // Instead, we save the controllers for the element in a local hash and attach to .data\n // later, once we have the actual element.\n elementControllers[directive.name] = controllerInstance;\n if (!hasElementTranscludeDirective) {\n $element.data('$' + directive.name + 'Controller', controllerInstance.instance);\n }\n }\n return elementControllers;\n }\n\n function nodeLinkFn(childLinkFn, scope, linkNode, $rootElement, boundTranscludeFn) {\n var linkFn, isolateScope, controllerScope, elementControllers, transcludeFn, $element,\n attrs, removeScopeBindingWatches, removeControllerBindingWatches;\n\n if (compileNode === linkNode) {\n attrs = templateAttrs;\n $element = templateAttrs.$$element;\n } else {\n $element = jqLite(linkNode);\n attrs = new Attributes($element, templateAttrs);\n }\n\n controllerScope = scope;\n if (newIsolateScopeDirective) {\n isolateScope = scope.$new(true);\n } else if (newScopeDirective) {\n controllerScope = scope.$parent;\n }\n\n if (boundTranscludeFn) {\n // track `boundTranscludeFn` so it can be unwrapped if `transcludeFn`\n // is later passed as `parentBoundTranscludeFn` to `publicLinkFn`\n transcludeFn = controllersBoundTransclude;\n transcludeFn.$$boundTransclude = boundTranscludeFn;\n }\n\n if (controllerDirectives) {\n elementControllers = setupControllers($element, attrs, transcludeFn, controllerDirectives, isolateScope, scope);\n }\n\n if (newIsolateScopeDirective) {\n // Initialize isolate scope bindings for new isolate scope directive.\n compile.$$addScopeInfo($element, isolateScope, true, !(templateDirective && (templateDirective === newIsolateScopeDirective ||\n templateDirective === newIsolateScopeDirective.$$originalDirective)));\n compile.$$addScopeClass($element, true);\n isolateScope.$$isolateBindings =\n newIsolateScopeDirective.$$isolateBindings;\n removeScopeBindingWatches = initializeDirectiveBindings(scope, attrs, isolateScope,\n isolateScope.$$isolateBindings,\n newIsolateScopeDirective);\n if (removeScopeBindingWatches) {\n isolateScope.$on('$destroy', removeScopeBindingWatches);\n }\n }\n\n // Initialize bindToController bindings\n for (var name in elementControllers) {\n var controllerDirective = controllerDirectives[name];\n var controller = elementControllers[name];\n var bindings = controllerDirective.$$bindings.bindToController;\n\n if (controller.identifier && bindings) {\n removeControllerBindingWatches =\n initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);\n }\n\n var controllerResult = controller();\n if (controllerResult !== controller.instance) {\n // If the controller constructor has a return value, overwrite the instance\n // from setupControllers\n controller.instance = controllerResult;\n $element.data('$' + controllerDirective.name + 'Controller', controllerResult);\n removeControllerBindingWatches && removeControllerBindingWatches();\n removeControllerBindingWatches =\n initializeDirectiveBindings(controllerScope, attrs, controller.instance, bindings, controllerDirective);\n }\n }\n\n // PRELINKING\n for (i = 0, ii = preLinkFns.length; i < ii; i++) {\n linkFn = preLinkFns[i];\n invokeLinkFn(linkFn,\n linkFn.isolateScope ? isolateScope : scope,\n $element,\n attrs,\n linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),\n transcludeFn\n );\n }\n\n // RECURSION\n // We only pass the isolate scope, if the isolate directive has a template,\n // otherwise the child elements do not belong to the isolate directive.\n var scopeToChild = scope;\n if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) {\n scopeToChild = isolateScope;\n }\n childLinkFn && childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);\n\n // POSTLINKING\n for (i = postLinkFns.length - 1; i >= 0; i--) {\n linkFn = postLinkFns[i];\n invokeLinkFn(linkFn,\n linkFn.isolateScope ? isolateScope : scope,\n $element,\n attrs,\n linkFn.require && getControllers(linkFn.directiveName, linkFn.require, $element, elementControllers),\n transcludeFn\n );\n }\n\n // This is the function that is injected as `$transclude`.\n // Note: all arguments are optional!\n function controllersBoundTransclude(scope, cloneAttachFn, futureParentElement) {\n var transcludeControllers;\n\n // No scope passed in:\n if (!isScope(scope)) {\n futureParentElement = cloneAttachFn;\n cloneAttachFn = scope;\n scope = undefined;\n }\n\n if (hasElementTranscludeDirective) {\n transcludeControllers = elementControllers;\n }\n if (!futureParentElement) {\n futureParentElement = hasElementTranscludeDirective ? $element.parent() : $element;\n }\n return boundTranscludeFn(scope, cloneAttachFn, transcludeControllers, futureParentElement, scopeToChild);\n }\n }\n }\n\n // Depending upon the context in which a directive finds itself it might need to have a new isolated\n // or child scope created. For instance:\n // * if the directive has been pulled into a template because another directive with a higher priority\n // asked for element transclusion\n // * if the directive itself asks for transclusion but it is at the root of a template and the original\n // element was replaced. See https://github.com/angular/angular.js/issues/12936\n function markDirectiveScope(directives, isolateScope, newScope) {\n for (var j = 0, jj = directives.length; j < jj; j++) {\n directives[j] = inherit(directives[j], {$$isolateScope: isolateScope, $$newScope: newScope});\n }\n }\n\n /**\n * looks up the directive and decorates it with exception handling and proper parameters. We\n * call this the boundDirective.\n *\n * @param {string} name name of the directive to look up.\n * @param {string} location The directive must be found in specific format.\n * String containing any of theses characters:\n *\n * * `E`: element name\n * * `A': attribute\n * * `C`: class\n * * `M`: comment\n * @returns {boolean} true if directive was added.\n */\n function addDirective(tDirectives, name, location, maxPriority, ignoreDirective, startAttrName,\n endAttrName) {\n if (name === ignoreDirective) return null;\n var match = null;\n if (hasDirectives.hasOwnProperty(name)) {\n for (var directive, directives = $injector.get(name + Suffix),\n i = 0, ii = directives.length; i < ii; i++) {\n try {\n directive = directives[i];\n if ((isUndefined(maxPriority) || maxPriority > directive.priority) &&\n directive.restrict.indexOf(location) != -1) {\n if (startAttrName) {\n directive = inherit(directive, {$$start: startAttrName, $$end: endAttrName});\n }\n tDirectives.push(directive);\n match = directive;\n }\n } catch (e) { $exceptionHandler(e); }\n }\n }\n return match;\n }\n\n\n /**\n * looks up the directive and returns true if it is a multi-element directive,\n * and therefore requires DOM nodes between -start and -end markers to be grouped\n * together.\n *\n * @param {string} name name of the directive to look up.\n * @returns true if directive was registered as multi-element.\n */\n function directiveIsMultiElement(name) {\n if (hasDirectives.hasOwnProperty(name)) {\n for (var directive, directives = $injector.get(name + Suffix),\n i = 0, ii = directives.length; i < ii; i++) {\n directive = directives[i];\n if (directive.multiElement) {\n return true;\n }\n }\n }\n return false;\n }\n\n /**\n * When the element is replaced with HTML template then the new attributes\n * on the template need to be merged with the existing attributes in the DOM.\n * The desired effect is to have both of the attributes present.\n *\n * @param {object} dst destination attributes (original DOM)\n * @param {object} src source attributes (from the directive template)\n */\n function mergeTemplateAttributes(dst, src) {\n var srcAttr = src.$attr,\n dstAttr = dst.$attr,\n $element = dst.$$element;\n\n // reapply the old attributes to the new element\n forEach(dst, function(value, key) {\n if (key.charAt(0) != '$') {\n if (src[key] && src[key] !== value) {\n value += (key === 'style' ? ';' : ' ') + src[key];\n }\n dst.$set(key, value, true, srcAttr[key]);\n }\n });\n\n // copy the new attributes on the old attrs object\n forEach(src, function(value, key) {\n if (key == 'class') {\n safeAddClass($element, value);\n dst['class'] = (dst['class'] ? dst['class'] + ' ' : '') + value;\n } else if (key == 'style') {\n $element.attr('style', $element.attr('style') + ';' + value);\n dst['style'] = (dst['style'] ? dst['style'] + ';' : '') + value;\n // `dst` will never contain hasOwnProperty as DOM parser won't let it.\n // You will get an \"InvalidCharacterError: DOM Exception 5\" error if you\n // have an attribute like \"has-own-property\" or \"data-has-own-property\", etc.\n } else if (key.charAt(0) != '$' && !dst.hasOwnProperty(key)) {\n dst[key] = value;\n dstAttr[key] = srcAttr[key];\n }\n });\n }\n\n\n function compileTemplateUrl(directives, $compileNode, tAttrs,\n $rootElement, childTranscludeFn, preLinkFns, postLinkFns, previousCompileContext) {\n var linkQueue = [],\n afterTemplateNodeLinkFn,\n afterTemplateChildLinkFn,\n beforeTemplateCompileNode = $compileNode[0],\n origAsyncDirective = directives.shift(),\n derivedSyncDirective = inherit(origAsyncDirective, {\n templateUrl: null, transclude: null, replace: null, $$originalDirective: origAsyncDirective\n }),\n templateUrl = (isFunction(origAsyncDirective.templateUrl))\n ? origAsyncDirective.templateUrl($compileNode, tAttrs)\n : origAsyncDirective.templateUrl,\n templateNamespace = origAsyncDirective.templateNamespace;\n\n $compileNode.empty();\n\n $templateRequest(templateUrl)\n .then(function(content) {\n var compileNode, tempTemplateAttrs, $template, childBoundTranscludeFn;\n\n content = denormalizeTemplate(content);\n\n if (origAsyncDirective.replace) {\n if (jqLiteIsTextNode(content)) {\n $template = [];\n } else {\n $template = removeComments(wrapTemplate(templateNamespace, trim(content)));\n }\n compileNode = $template[0];\n\n if ($template.length != 1 || compileNode.nodeType !== NODE_TYPE_ELEMENT) {\n throw $compileMinErr('tplrt',\n \"Template for directive '{0}' must have exactly one root element. {1}\",\n origAsyncDirective.name, templateUrl);\n }\n\n tempTemplateAttrs = {$attr: {}};\n replaceWith($rootElement, $compileNode, compileNode);\n var templateDirectives = collectDirectives(compileNode, [], tempTemplateAttrs);\n\n if (isObject(origAsyncDirective.scope)) {\n // the original directive that caused the template to be loaded async required\n // an isolate scope\n markDirectiveScope(templateDirectives, true);\n }\n directives = templateDirectives.concat(directives);\n mergeTemplateAttributes(tAttrs, tempTemplateAttrs);\n } else {\n compileNode = beforeTemplateCompileNode;\n $compileNode.html(content);\n }\n\n directives.unshift(derivedSyncDirective);\n\n afterTemplateNodeLinkFn = applyDirectivesToNode(directives, compileNode, tAttrs,\n childTranscludeFn, $compileNode, origAsyncDirective, preLinkFns, postLinkFns,\n previousCompileContext);\n forEach($rootElement, function(node, i) {\n if (node == compileNode) {\n $rootElement[i] = $compileNode[0];\n }\n });\n afterTemplateChildLinkFn = compileNodes($compileNode[0].childNodes, childTranscludeFn);\n\n while (linkQueue.length) {\n var scope = linkQueue.shift(),\n beforeTemplateLinkNode = linkQueue.shift(),\n linkRootElement = linkQueue.shift(),\n boundTranscludeFn = linkQueue.shift(),\n linkNode = $compileNode[0];\n\n if (scope.$$destroyed) continue;\n\n if (beforeTemplateLinkNode !== beforeTemplateCompileNode) {\n var oldClasses = beforeTemplateLinkNode.className;\n\n if (!(previousCompileContext.hasElementTranscludeDirective &&\n origAsyncDirective.replace)) {\n // it was cloned therefore we have to clone as well.\n linkNode = jqLiteClone(compileNode);\n }\n replaceWith(linkRootElement, jqLite(beforeTemplateLinkNode), linkNode);\n\n // Copy in CSS classes from original node\n safeAddClass(jqLite(linkNode), oldClasses);\n }\n if (afterTemplateNodeLinkFn.transcludeOnThisElement) {\n childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);\n } else {\n childBoundTranscludeFn = boundTranscludeFn;\n }\n afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, linkNode, $rootElement,\n childBoundTranscludeFn);\n }\n linkQueue = null;\n });\n\n return function delayedNodeLinkFn(ignoreChildLinkFn, scope, node, rootElement, boundTranscludeFn) {\n var childBoundTranscludeFn = boundTranscludeFn;\n if (scope.$$destroyed) return;\n if (linkQueue) {\n linkQueue.push(scope,\n node,\n rootElement,\n childBoundTranscludeFn);\n } else {\n if (afterTemplateNodeLinkFn.transcludeOnThisElement) {\n childBoundTranscludeFn = createBoundTranscludeFn(scope, afterTemplateNodeLinkFn.transclude, boundTranscludeFn);\n }\n afterTemplateNodeLinkFn(afterTemplateChildLinkFn, scope, node, rootElement, childBoundTranscludeFn);\n }\n };\n }\n\n\n /**\n * Sorting function for bound directives.\n */\n function byPriority(a, b) {\n var diff = b.priority - a.priority;\n if (diff !== 0) return diff;\n if (a.name !== b.name) return (a.name < b.name) ? -1 : 1;\n return a.index - b.index;\n }\n\n function assertNoDuplicate(what, previousDirective, directive, element) {\n\n function wrapModuleNameIfDefined(moduleName) {\n return moduleName ?\n (' (module: ' + moduleName + ')') :\n '';\n }\n\n if (previousDirective) {\n throw $compileMinErr('multidir', 'Multiple directives [{0}{1}, {2}{3}] asking for {4} on: {5}',\n previousDirective.name, wrapModuleNameIfDefined(previousDirective.$$moduleName),\n directive.name, wrapModuleNameIfDefined(directive.$$moduleName), what, startingTag(element));\n }\n }\n\n\n function addTextInterpolateDirective(directives, text) {\n var interpolateFn = $interpolate(text, true);\n if (interpolateFn) {\n directives.push({\n priority: 0,\n compile: function textInterpolateCompileFn(templateNode) {\n var templateNodeParent = templateNode.parent(),\n hasCompileParent = !!templateNodeParent.length;\n\n // When transcluding a template that has bindings in the root\n // we don't have a parent and thus need to add the class during linking fn.\n if (hasCompileParent) compile.$$addBindingClass(templateNodeParent);\n\n return function textInterpolateLinkFn(scope, node) {\n var parent = node.parent();\n if (!hasCompileParent) compile.$$addBindingClass(parent);\n compile.$$addBindingInfo(parent, interpolateFn.expressions);\n scope.$watch(interpolateFn, function interpolateFnWatchAction(value) {\n node[0].nodeValue = value;\n });\n };\n }\n });\n }\n }\n\n\n function wrapTemplate(type, template) {\n type = lowercase(type || 'html');\n switch (type) {\n case 'svg':\n case 'math':\n var wrapper = document.createElement('div');\n wrapper.innerHTML = '<' + type + '>' + template + '' + type + '>';\n return wrapper.childNodes[0].childNodes;\n default:\n return template;\n }\n }\n\n\n function getTrustedContext(node, attrNormalizedName) {\n if (attrNormalizedName == \"srcdoc\") {\n return $sce.HTML;\n }\n var tag = nodeName_(node);\n // maction[xlink:href] can source SVG. It's not limited to .\n if (attrNormalizedName == \"xlinkHref\" ||\n (tag == \"form\" && attrNormalizedName == \"action\") ||\n (tag != \"img\" && (attrNormalizedName == \"src\" ||\n attrNormalizedName == \"ngSrc\"))) {\n return $sce.RESOURCE_URL;\n }\n }\n\n\n function addAttrInterpolateDirective(node, directives, value, name, allOrNothing) {\n var trustedContext = getTrustedContext(node, name);\n allOrNothing = ALL_OR_NOTHING_ATTRS[name] || allOrNothing;\n\n var interpolateFn = $interpolate(value, true, trustedContext, allOrNothing);\n\n // no interpolation found -> ignore\n if (!interpolateFn) return;\n\n\n if (name === \"multiple\" && nodeName_(node) === \"select\") {\n throw $compileMinErr(\"selmulti\",\n \"Binding to the 'multiple' attribute is not supported. Element: {0}\",\n startingTag(node));\n }\n\n directives.push({\n priority: 100,\n compile: function() {\n return {\n pre: function attrInterpolatePreLinkFn(scope, element, attr) {\n var $$observers = (attr.$$observers || (attr.$$observers = createMap()));\n\n if (EVENT_HANDLER_ATTR_REGEXP.test(name)) {\n throw $compileMinErr('nodomevents',\n \"Interpolations for HTML DOM event attributes are disallowed. Please use the \" +\n \"ng- versions (such as ng-click instead of onclick) instead.\");\n }\n\n // If the attribute has changed since last $interpolate()ed\n var newValue = attr[name];\n if (newValue !== value) {\n // we need to interpolate again since the attribute value has been updated\n // (e.g. by another directive's compile function)\n // ensure unset/empty values make interpolateFn falsy\n interpolateFn = newValue && $interpolate(newValue, true, trustedContext, allOrNothing);\n value = newValue;\n }\n\n // if attribute was updated so that there is no interpolation going on we don't want to\n // register any observers\n if (!interpolateFn) return;\n\n // initialize attr object so that it's ready in case we need the value for isolate\n // scope initialization, otherwise the value would not be available from isolate\n // directive's linking fn during linking phase\n attr[name] = interpolateFn(scope);\n\n ($$observers[name] || ($$observers[name] = [])).$$inter = true;\n (attr.$$observers && attr.$$observers[name].$$scope || scope).\n $watch(interpolateFn, function interpolateFnWatchAction(newValue, oldValue) {\n //special case for class attribute addition + removal\n //so that class changes can tap into the animation\n //hooks provided by the $animate service. Be sure to\n //skip animations when the first digest occurs (when\n //both the new and the old values are the same) since\n //the CSS classes are the non-interpolated values\n if (name === 'class' && newValue != oldValue) {\n attr.$updateClass(newValue, oldValue);\n } else {\n attr.$set(name, newValue);\n }\n });\n }\n };\n }\n });\n }\n\n\n /**\n * This is a special jqLite.replaceWith, which can replace items which\n * have no parents, provided that the containing jqLite collection is provided.\n *\n * @param {JqLite=} $rootElement The root of the compile tree. Used so that we can replace nodes\n * in the root of the tree.\n * @param {JqLite} elementsToRemove The jqLite element which we are going to replace. We keep\n * the shell, but replace its DOM node reference.\n * @param {Node} newNode The new DOM node.\n */\n function replaceWith($rootElement, elementsToRemove, newNode) {\n var firstElementToRemove = elementsToRemove[0],\n removeCount = elementsToRemove.length,\n parent = firstElementToRemove.parentNode,\n i, ii;\n\n if ($rootElement) {\n for (i = 0, ii = $rootElement.length; i < ii; i++) {\n if ($rootElement[i] == firstElementToRemove) {\n $rootElement[i++] = newNode;\n for (var j = i, j2 = j + removeCount - 1,\n jj = $rootElement.length;\n j < jj; j++, j2++) {\n if (j2 < jj) {\n $rootElement[j] = $rootElement[j2];\n } else {\n delete $rootElement[j];\n }\n }\n $rootElement.length -= removeCount - 1;\n\n // If the replaced element is also the jQuery .context then replace it\n // .context is a deprecated jQuery api, so we should set it only when jQuery set it\n // http://api.jquery.com/context/\n if ($rootElement.context === firstElementToRemove) {\n $rootElement.context = newNode;\n }\n break;\n }\n }\n }\n\n if (parent) {\n parent.replaceChild(newNode, firstElementToRemove);\n }\n\n // TODO(perf): what's this document fragment for? is it needed? can we at least reuse it?\n var fragment = document.createDocumentFragment();\n fragment.appendChild(firstElementToRemove);\n\n if (jqLite.hasData(firstElementToRemove)) {\n // Copy over user data (that includes Angular's $scope etc.). Don't copy private\n // data here because there's no public interface in jQuery to do that and copying over\n // event listeners (which is the main use of private data) wouldn't work anyway.\n jqLite.data(newNode, jqLite.data(firstElementToRemove));\n\n // Remove data of the replaced element. We cannot just call .remove()\n // on the element it since that would deallocate scope that is needed\n // for the new node. Instead, remove the data \"manually\".\n if (!jQuery) {\n delete jqLite.cache[firstElementToRemove[jqLite.expando]];\n } else {\n // jQuery 2.x doesn't expose the data storage. Use jQuery.cleanData to clean up after\n // the replaced element. The cleanData version monkey-patched by Angular would cause\n // the scope to be trashed and we do need the very same scope to work with the new\n // element. However, we cannot just cache the non-patched version and use it here as\n // that would break if another library patches the method after Angular does (one\n // example is jQuery UI). Instead, set a flag indicating scope destroying should be\n // skipped this one time.\n skipDestroyOnNextJQueryCleanData = true;\n jQuery.cleanData([firstElementToRemove]);\n }\n }\n\n for (var k = 1, kk = elementsToRemove.length; k < kk; k++) {\n var element = elementsToRemove[k];\n jqLite(element).remove(); // must do this way to clean up expando\n fragment.appendChild(element);\n delete elementsToRemove[k];\n }\n\n elementsToRemove[0] = newNode;\n elementsToRemove.length = 1;\n }\n\n\n function cloneAndAnnotateFn(fn, annotation) {\n return extend(function() { return fn.apply(null, arguments); }, fn, annotation);\n }\n\n\n function invokeLinkFn(linkFn, scope, $element, attrs, controllers, transcludeFn) {\n try {\n linkFn(scope, $element, attrs, controllers, transcludeFn);\n } catch (e) {\n $exceptionHandler(e, startingTag($element));\n }\n }\n\n\n // Set up $watches for isolate scope and controller bindings. This process\n // only occurs for isolate scopes and new scopes with controllerAs.\n function initializeDirectiveBindings(scope, attrs, destination, bindings, directive) {\n var removeWatchCollection = [];\n forEach(bindings, function(definition, scopeName) {\n var attrName = definition.attrName,\n optional = definition.optional,\n mode = definition.mode, // @, =, or &\n lastValue,\n parentGet, parentSet, compare;\n\n switch (mode) {\n\n case '@':\n if (!optional && !hasOwnProperty.call(attrs, attrName)) {\n destination[scopeName] = attrs[attrName] = void 0;\n }\n attrs.$observe(attrName, function(value) {\n if (isString(value)) {\n destination[scopeName] = value;\n }\n });\n attrs.$$observers[attrName].$$scope = scope;\n if (isString(attrs[attrName])) {\n // If the attribute has been provided then we trigger an interpolation to ensure\n // the value is there for use in the link fn\n destination[scopeName] = $interpolate(attrs[attrName])(scope);\n }\n break;\n\n case '=':\n if (!hasOwnProperty.call(attrs, attrName)) {\n if (optional) break;\n attrs[attrName] = void 0;\n }\n if (optional && !attrs[attrName]) break;\n\n parentGet = $parse(attrs[attrName]);\n if (parentGet.literal) {\n compare = equals;\n } else {\n compare = function(a, b) { return a === b || (a !== a && b !== b); };\n }\n parentSet = parentGet.assign || function() {\n // reset the change, or we will throw this exception on every $digest\n lastValue = destination[scopeName] = parentGet(scope);\n throw $compileMinErr('nonassign',\n \"Expression '{0}' used with directive '{1}' is non-assignable!\",\n attrs[attrName], directive.name);\n };\n lastValue = destination[scopeName] = parentGet(scope);\n var parentValueWatch = function parentValueWatch(parentValue) {\n if (!compare(parentValue, destination[scopeName])) {\n // we are out of sync and need to copy\n if (!compare(parentValue, lastValue)) {\n // parent changed and it has precedence\n destination[scopeName] = parentValue;\n } else {\n // if the parent can be assigned then do so\n parentSet(scope, parentValue = destination[scopeName]);\n }\n }\n return lastValue = parentValue;\n };\n parentValueWatch.$stateful = true;\n var removeWatch;\n if (definition.collection) {\n removeWatch = scope.$watchCollection(attrs[attrName], parentValueWatch);\n } else {\n removeWatch = scope.$watch($parse(attrs[attrName], parentValueWatch), null, parentGet.literal);\n }\n removeWatchCollection.push(removeWatch);\n break;\n\n case '&':\n // Don't assign Object.prototype method to scope\n parentGet = attrs.hasOwnProperty(attrName) ? $parse(attrs[attrName]) : noop;\n\n // Don't assign noop to destination if expression is not valid\n if (parentGet === noop && optional) break;\n\n destination[scopeName] = function(locals) {\n return parentGet(scope, locals);\n };\n break;\n }\n });\n\n return removeWatchCollection.length && function removeWatches() {\n for (var i = 0, ii = removeWatchCollection.length; i < ii; ++i) {\n removeWatchCollection[i]();\n }\n };\n }\n }];\n}\n\nvar PREFIX_REGEXP = /^((?:x|data)[\\:\\-_])/i;\n/**\n * Converts all accepted directives format into proper directive name.\n * @param name Name to normalize\n */\nfunction directiveNormalize(name) {\n return camelCase(name.replace(PREFIX_REGEXP, ''));\n}\n\n/**\n * @ngdoc type\n * @name $compile.directive.Attributes\n *\n * @description\n * A shared object between directive compile / linking functions which contains normalized DOM\n * element attributes. The values reflect current binding state `{{ }}`. The normalization is\n * needed since all of these are treated as equivalent in Angular:\n *\n * ```\n * \n * ```\n */\n\n/**\n * @ngdoc property\n * @name $compile.directive.Attributes#$attr\n *\n * @description\n * A map of DOM element attribute names to the normalized name. This is\n * needed to do reverse lookup from normalized name back to actual name.\n */\n\n\n/**\n * @ngdoc method\n * @name $compile.directive.Attributes#$set\n * @kind function\n *\n * @description\n * Set DOM element attribute value.\n *\n *\n * @param {string} name Normalized element attribute name of the property to modify. The name is\n * reverse-translated using the {@link ng.$compile.directive.Attributes#$attr $attr}\n * property to the original name.\n * @param {string} value Value to set the attribute to. The value can be an interpolated string.\n */\n\n\n\n/**\n * Closure compiler type information\n */\n\nfunction nodesetLinkingFn(\n /* angular.Scope */ scope,\n /* NodeList */ nodeList,\n /* Element */ rootElement,\n /* function(Function) */ boundTranscludeFn\n) {}\n\nfunction directiveLinkingFn(\n /* nodesetLinkingFn */ nodesetLinkingFn,\n /* angular.Scope */ scope,\n /* Node */ node,\n /* Element */ rootElement,\n /* function(Function) */ boundTranscludeFn\n) {}\n\nfunction tokenDifference(str1, str2) {\n var values = '',\n tokens1 = str1.split(/\\s+/),\n tokens2 = str2.split(/\\s+/);\n\n outer:\n for (var i = 0; i < tokens1.length; i++) {\n var token = tokens1[i];\n for (var j = 0; j < tokens2.length; j++) {\n if (token == tokens2[j]) continue outer;\n }\n values += (values.length > 0 ? ' ' : '') + token;\n }\n return values;\n}\n\nfunction removeComments(jqNodes) {\n jqNodes = jqLite(jqNodes);\n var i = jqNodes.length;\n\n if (i <= 1) {\n return jqNodes;\n }\n\n while (i--) {\n var node = jqNodes[i];\n if (node.nodeType === NODE_TYPE_COMMENT) {\n splice.call(jqNodes, i, 1);\n }\n }\n return jqNodes;\n}\n\nvar $controllerMinErr = minErr('$controller');\n\n\nvar CNTRL_REG = /^(\\S+)(\\s+as\\s+(\\w+))?$/;\nfunction identifierForController(controller, ident) {\n if (ident && isString(ident)) return ident;\n if (isString(controller)) {\n var match = CNTRL_REG.exec(controller);\n if (match) return match[3];\n }\n}\n\n\n/**\n * @ngdoc provider\n * @name $controllerProvider\n * @description\n * The {@link ng.$controller $controller service} is used by Angular to create new\n * controllers.\n *\n * This provider allows controller registration via the\n * {@link ng.$controllerProvider#register register} method.\n */\nfunction $ControllerProvider() {\n var controllers = {},\n globals = false;\n\n /**\n * @ngdoc method\n * @name $controllerProvider#register\n * @param {string|Object} name Controller name, or an object map of controllers where the keys are\n * the names and the values are the constructors.\n * @param {Function|Array} constructor Controller constructor fn (optionally decorated with DI\n * annotations in the array notation).\n */\n this.register = function(name, constructor) {\n assertNotHasOwnProperty(name, 'controller');\n if (isObject(name)) {\n extend(controllers, name);\n } else {\n controllers[name] = constructor;\n }\n };\n\n /**\n * @ngdoc method\n * @name $controllerProvider#allowGlobals\n * @description If called, allows `$controller` to find controller constructors on `window`\n */\n this.allowGlobals = function() {\n globals = true;\n };\n\n\n this.$get = ['$injector', '$window', function($injector, $window) {\n\n /**\n * @ngdoc service\n * @name $controller\n * @requires $injector\n *\n * @param {Function|string} constructor If called with a function then it's considered to be the\n * controller constructor function. Otherwise it's considered to be a string which is used\n * to retrieve the controller constructor using the following steps:\n *\n * * check if a controller with given name is registered via `$controllerProvider`\n * * check if evaluating the string on the current scope returns a constructor\n * * if $controllerProvider#allowGlobals, check `window[constructor]` on the global\n * `window` object (not recommended)\n *\n * The string can use the `controller as property` syntax, where the controller instance is published\n * as the specified property on the `scope`; the `scope` must be injected into `locals` param for this\n * to work correctly.\n *\n * @param {Object} locals Injection locals for Controller.\n * @return {Object} Instance of given controller.\n *\n * @description\n * `$controller` service is responsible for instantiating controllers.\n *\n * It's just a simple call to {@link auto.$injector $injector}, but extracted into\n * a service, so that one can override this service with [BC version](https://gist.github.com/1649788).\n */\n return function(expression, locals, later, ident) {\n // PRIVATE API:\n // param `later` --- indicates that the controller's constructor is invoked at a later time.\n // If true, $controller will allocate the object with the correct\n // prototype chain, but will not invoke the controller until a returned\n // callback is invoked.\n // param `ident` --- An optional label which overrides the label parsed from the controller\n // expression, if any.\n var instance, match, constructor, identifier;\n later = later === true;\n if (ident && isString(ident)) {\n identifier = ident;\n }\n\n if (isString(expression)) {\n match = expression.match(CNTRL_REG);\n if (!match) {\n throw $controllerMinErr('ctrlfmt',\n \"Badly formed controller string '{0}'. \" +\n \"Must match `__name__ as __id__` or `__name__`.\", expression);\n }\n constructor = match[1],\n identifier = identifier || match[3];\n expression = controllers.hasOwnProperty(constructor)\n ? controllers[constructor]\n : getter(locals.$scope, constructor, true) ||\n (globals ? getter($window, constructor, true) : undefined);\n\n assertArgFn(expression, constructor, true);\n }\n\n if (later) {\n // Instantiate controller later:\n // This machinery is used to create an instance of the object before calling the\n // controller's constructor itself.\n //\n // This allows properties to be added to the controller before the constructor is\n // invoked. Primarily, this is used for isolate scope bindings in $compile.\n //\n // This feature is not intended for use by applications, and is thus not documented\n // publicly.\n // Object creation: http://jsperf.com/create-constructor/2\n var controllerPrototype = (isArray(expression) ?\n expression[expression.length - 1] : expression).prototype;\n instance = Object.create(controllerPrototype || null);\n\n if (identifier) {\n addIdentifier(locals, identifier, instance, constructor || expression.name);\n }\n\n var instantiate;\n return instantiate = extend(function() {\n var result = $injector.invoke(expression, instance, locals, constructor);\n if (result !== instance && (isObject(result) || isFunction(result))) {\n instance = result;\n if (identifier) {\n // If result changed, re-assign controllerAs value to scope.\n addIdentifier(locals, identifier, instance, constructor || expression.name);\n }\n }\n return instance;\n }, {\n instance: instance,\n identifier: identifier\n });\n }\n\n instance = $injector.instantiate(expression, locals, constructor);\n\n if (identifier) {\n addIdentifier(locals, identifier, instance, constructor || expression.name);\n }\n\n return instance;\n };\n\n function addIdentifier(locals, identifier, instance, name) {\n if (!(locals && isObject(locals.$scope))) {\n throw minErr('$controller')('noscp',\n \"Cannot export controller '{0}' as '{1}'! No $scope object provided via `locals`.\",\n name, identifier);\n }\n\n locals.$scope[identifier] = instance;\n }\n }];\n}\n\n/**\n * @ngdoc service\n * @name $document\n * @requires $window\n *\n * @description\n * A {@link angular.element jQuery or jqLite} wrapper for the browser's `window.document` object.\n *\n * @example\n \n \n \n
$document title:
\n
window.document title:
\n
\n \n \n angular.module('documentExample', [])\n .controller('ExampleController', ['$scope', '$document', function($scope, $document) {\n $scope.title = $document[0].title;\n $scope.windowTitle = angular.element(window.document)[0].title;\n }]);\n \n \n */\nfunction $DocumentProvider() {\n this.$get = ['$window', function(window) {\n return jqLite(window.document);\n }];\n}\n\n/**\n * @ngdoc service\n * @name $exceptionHandler\n * @requires ng.$log\n *\n * @description\n * Any uncaught exception in angular expressions is delegated to this service.\n * The default implementation simply delegates to `$log.error` which logs it into\n * the browser console.\n *\n * In unit tests, if `angular-mocks.js` is loaded, this service is overridden by\n * {@link ngMock.$exceptionHandler mock $exceptionHandler} which aids in testing.\n *\n * ## Example:\n *\n * ```js\n * angular.module('exceptionOverride', []).factory('$exceptionHandler', function() {\n * return function(exception, cause) {\n * exception.message += ' (caused by \"' + cause + '\")';\n * throw exception;\n * };\n * });\n * ```\n *\n * This example will override the normal action of `$exceptionHandler`, to make angular\n * exceptions fail hard when they happen, instead of just logging to the console.\n *\n *
\n * Note, that code executed in event-listeners (even those registered using jqLite's `on`/`bind`\n * methods) does not delegate exceptions to the {@link ng.$exceptionHandler $exceptionHandler}\n * (unless executed during a digest).\n *\n * If you wish, you can manually delegate exceptions, e.g.\n * `try { ... } catch(e) { $exceptionHandler(e); }`\n *\n * @param {Error} exception Exception associated with the error.\n * @param {string=} cause optional information about the context in which\n * the error was thrown.\n *\n */\nfunction $ExceptionHandlerProvider() {\n this.$get = ['$log', function($log) {\n return function(exception, cause) {\n $log.error.apply($log, arguments);\n };\n }];\n}\n\nvar $$ForceReflowProvider = function() {\n this.$get = ['$document', function($document) {\n return function(domNode) {\n //the line below will force the browser to perform a repaint so\n //that all the animated elements within the animation frame will\n //be properly updated and drawn on screen. This is required to\n //ensure that the preparation animation is properly flushed so that\n //the active state picks up from there. DO NOT REMOVE THIS LINE.\n //DO NOT OPTIMIZE THIS LINE. THE MINIFIER WILL REMOVE IT OTHERWISE WHICH\n //WILL RESULT IN AN UNPREDICTABLE BUG THAT IS VERY HARD TO TRACK DOWN AND\n //WILL TAKE YEARS AWAY FROM YOUR LIFE.\n if (domNode) {\n if (!domNode.nodeType && domNode instanceof jqLite) {\n domNode = domNode[0];\n }\n } else {\n domNode = $document[0].body;\n }\n return domNode.offsetWidth + 1;\n };\n }];\n};\n\nvar APPLICATION_JSON = 'application/json';\nvar CONTENT_TYPE_APPLICATION_JSON = {'Content-Type': APPLICATION_JSON + ';charset=utf-8'};\nvar JSON_START = /^\\[|^\\{(?!\\{)/;\nvar JSON_ENDS = {\n '[': /]$/,\n '{': /}$/\n};\nvar JSON_PROTECTION_PREFIX = /^\\)\\]\\}',?\\n/;\nvar $httpMinErr = minErr('$http');\nvar $httpMinErrLegacyFn = function(method) {\n return function() {\n throw $httpMinErr('legacy', 'The method `{0}` on the promise returned from `$http` has been disabled.', method);\n };\n};\n\nfunction serializeValue(v) {\n if (isObject(v)) {\n return isDate(v) ? v.toISOString() : toJson(v);\n }\n return v;\n}\n\n\nfunction $HttpParamSerializerProvider() {\n /**\n * @ngdoc service\n * @name $httpParamSerializer\n * @description\n *\n * Default {@link $http `$http`} params serializer that converts objects to strings\n * according to the following rules:\n *\n * * `{'foo': 'bar'}` results in `foo=bar`\n * * `{'foo': Date.now()}` results in `foo=2015-04-01T09%3A50%3A49.262Z` (`toISOString()` and encoded representation of a Date object)\n * * `{'foo': ['bar', 'baz']}` results in `foo=bar&foo=baz` (repeated key for each array element)\n * * `{'foo': {'bar':'baz'}}` results in `foo=%7B%22bar%22%3A%22baz%22%7D\"` (stringified and encoded representation of an object)\n *\n * Note that serializer will sort the request parameters alphabetically.\n * */\n\n this.$get = function() {\n return function ngParamSerializer(params) {\n if (!params) return '';\n var parts = [];\n forEachSorted(params, function(value, key) {\n if (value === null || isUndefined(value)) return;\n if (isArray(value)) {\n forEach(value, function(v, k) {\n parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(v)));\n });\n } else {\n parts.push(encodeUriQuery(key) + '=' + encodeUriQuery(serializeValue(value)));\n }\n });\n\n return parts.join('&');\n };\n };\n}\n\nfunction $HttpParamSerializerJQLikeProvider() {\n /**\n * @ngdoc service\n * @name $httpParamSerializerJQLike\n * @description\n *\n * Alternative {@link $http `$http`} params serializer that follows\n * jQuery's [`param()`](http://api.jquery.com/jquery.param/) method logic.\n * The serializer will also sort the params alphabetically.\n *\n * To use it for serializing `$http` request parameters, set it as the `paramSerializer` property:\n *\n * ```js\n * $http({\n * url: myUrl,\n * method: 'GET',\n * params: myParams,\n * paramSerializer: '$httpParamSerializerJQLike'\n * });\n * ```\n *\n * It is also possible to set it as the default `paramSerializer` in the\n * {@link $httpProvider#defaults `$httpProvider`}.\n *\n * Additionally, you can inject the serializer and use it explicitly, for example to serialize\n * form data for submission:\n *\n * ```js\n * .controller(function($http, $httpParamSerializerJQLike) {\n * //...\n *\n * $http({\n * url: myUrl,\n * method: 'POST',\n * data: $httpParamSerializerJQLike(myData),\n * headers: {\n * 'Content-Type': 'application/x-www-form-urlencoded'\n * }\n * });\n *\n * });\n * ```\n *\n * */\n this.$get = function() {\n return function jQueryLikeParamSerializer(params) {\n if (!params) return '';\n var parts = [];\n serialize(params, '', true);\n return parts.join('&');\n\n function serialize(toSerialize, prefix, topLevel) {\n if (toSerialize === null || isUndefined(toSerialize)) return;\n if (isArray(toSerialize)) {\n forEach(toSerialize, function(value, index) {\n serialize(value, prefix + '[' + (isObject(value) ? index : '') + ']');\n });\n } else if (isObject(toSerialize) && !isDate(toSerialize)) {\n forEachSorted(toSerialize, function(value, key) {\n serialize(value, prefix +\n (topLevel ? '' : '[') +\n key +\n (topLevel ? '' : ']'));\n });\n } else {\n parts.push(encodeUriQuery(prefix) + '=' + encodeUriQuery(serializeValue(toSerialize)));\n }\n }\n };\n };\n}\n\nfunction defaultHttpResponseTransform(data, headers) {\n if (isString(data)) {\n // Strip json vulnerability protection prefix and trim whitespace\n var tempData = data.replace(JSON_PROTECTION_PREFIX, '').trim();\n\n if (tempData) {\n var contentType = headers('Content-Type');\n if ((contentType && (contentType.indexOf(APPLICATION_JSON) === 0)) || isJsonLike(tempData)) {\n data = fromJson(tempData);\n }\n }\n }\n\n return data;\n}\n\nfunction isJsonLike(str) {\n var jsonStart = str.match(JSON_START);\n return jsonStart && JSON_ENDS[jsonStart[0]].test(str);\n}\n\n/**\n * Parse headers into key value object\n *\n * @param {string} headers Raw headers as a string\n * @returns {Object} Parsed headers as key value object\n */\nfunction parseHeaders(headers) {\n var parsed = createMap(), i;\n\n function fillInParsed(key, val) {\n if (key) {\n parsed[key] = parsed[key] ? parsed[key] + ', ' + val : val;\n }\n }\n\n if (isString(headers)) {\n forEach(headers.split('\\n'), function(line) {\n i = line.indexOf(':');\n fillInParsed(lowercase(trim(line.substr(0, i))), trim(line.substr(i + 1)));\n });\n } else if (isObject(headers)) {\n forEach(headers, function(headerVal, headerKey) {\n fillInParsed(lowercase(headerKey), trim(headerVal));\n });\n }\n\n return parsed;\n}\n\n\n/**\n * Returns a function that provides access to parsed headers.\n *\n * Headers are lazy parsed when first requested.\n * @see parseHeaders\n *\n * @param {(string|Object)} headers Headers to provide access to.\n * @returns {function(string=)} Returns a getter function which if called with:\n *\n * - if called with single an argument returns a single header value or null\n * - if called with no arguments returns an object containing all headers.\n */\nfunction headersGetter(headers) {\n var headersObj;\n\n return function(name) {\n if (!headersObj) headersObj = parseHeaders(headers);\n\n if (name) {\n var value = headersObj[lowercase(name)];\n if (value === void 0) {\n value = null;\n }\n return value;\n }\n\n return headersObj;\n };\n}\n\n\n/**\n * Chain all given functions\n *\n * This function is used for both request and response transforming\n *\n * @param {*} data Data to transform.\n * @param {function(string=)} headers HTTP headers getter fn.\n * @param {number} status HTTP status code of the response.\n * @param {(Function|Array.)} fns Function or an array of functions.\n * @returns {*} Transformed data.\n */\nfunction transformData(data, headers, status, fns) {\n if (isFunction(fns)) {\n return fns(data, headers, status);\n }\n\n forEach(fns, function(fn) {\n data = fn(data, headers, status);\n });\n\n return data;\n}\n\n\nfunction isSuccess(status) {\n return 200 <= status && status < 300;\n}\n\n\n/**\n * @ngdoc provider\n * @name $httpProvider\n * @description\n * Use `$httpProvider` to change the default behavior of the {@link ng.$http $http} service.\n * */\nfunction $HttpProvider() {\n /**\n * @ngdoc property\n * @name $httpProvider#defaults\n * @description\n *\n * Object containing default values for all {@link ng.$http $http} requests.\n *\n * - **`defaults.cache`** - {Object} - an object built with {@link ng.$cacheFactory `$cacheFactory`}\n * that will provide the cache for all requests who set their `cache` property to `true`.\n * If you set the `defaults.cache = false` then only requests that specify their own custom\n * cache object will be cached. See {@link $http#caching $http Caching} for more information.\n *\n * - **`defaults.xsrfCookieName`** - {string} - Name of cookie containing the XSRF token.\n * Defaults value is `'XSRF-TOKEN'`.\n *\n * - **`defaults.xsrfHeaderName`** - {string} - Name of HTTP header to populate with the\n * XSRF token. Defaults value is `'X-XSRF-TOKEN'`.\n *\n * - **`defaults.headers`** - {Object} - Default headers for all $http requests.\n * Refer to {@link ng.$http#setting-http-headers $http} for documentation on\n * setting default headers.\n * - **`defaults.headers.common`**\n * - **`defaults.headers.post`**\n * - **`defaults.headers.put`**\n * - **`defaults.headers.patch`**\n *\n *\n * - **`defaults.paramSerializer`** - `{string|function(Object):string}` - A function\n * used to the prepare string representation of request parameters (specified as an object).\n * If specified as string, it is interpreted as a function registered with the {@link auto.$injector $injector}.\n * Defaults to {@link ng.$httpParamSerializer $httpParamSerializer}.\n *\n **/\n var defaults = this.defaults = {\n // transform incoming response data\n transformResponse: [defaultHttpResponseTransform],\n\n // transform outgoing request data\n transformRequest: [function(d) {\n return isObject(d) && !isFile(d) && !isBlob(d) && !isFormData(d) ? toJson(d) : d;\n }],\n\n // default headers\n headers: {\n common: {\n 'Accept': 'application/json, text/plain, */*'\n },\n post: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),\n put: shallowCopy(CONTENT_TYPE_APPLICATION_JSON),\n patch: shallowCopy(CONTENT_TYPE_APPLICATION_JSON)\n },\n\n xsrfCookieName: 'XSRF-TOKEN',\n xsrfHeaderName: 'X-XSRF-TOKEN',\n\n paramSerializer: '$httpParamSerializer'\n };\n\n var useApplyAsync = false;\n /**\n * @ngdoc method\n * @name $httpProvider#useApplyAsync\n * @description\n *\n * Configure $http service to combine processing of multiple http responses received at around\n * the same time via {@link ng.$rootScope.Scope#$applyAsync $rootScope.$applyAsync}. This can result in\n * significant performance improvement for bigger applications that make many HTTP requests\n * concurrently (common during application bootstrap).\n *\n * Defaults to false. If no value is specified, returns the current configured value.\n *\n * @param {boolean=} value If true, when requests are loaded, they will schedule a deferred\n * \"apply\" on the next tick, giving time for subsequent requests in a roughly ~10ms window\n * to load and share the same digest cycle.\n *\n * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining.\n * otherwise, returns the current configured value.\n **/\n this.useApplyAsync = function(value) {\n if (isDefined(value)) {\n useApplyAsync = !!value;\n return this;\n }\n return useApplyAsync;\n };\n\n var useLegacyPromise = true;\n /**\n * @ngdoc method\n * @name $httpProvider#useLegacyPromiseExtensions\n * @description\n *\n * Configure `$http` service to return promises without the shorthand methods `success` and `error`.\n * This should be used to make sure that applications work without these methods.\n *\n * Defaults to true. If no value is specified, returns the current configured value.\n *\n * @param {boolean=} value If true, `$http` will return a promise with the deprecated legacy `success` and `error` methods.\n *\n * @returns {boolean|Object} If a value is specified, returns the $httpProvider for chaining.\n * otherwise, returns the current configured value.\n **/\n this.useLegacyPromiseExtensions = function(value) {\n if (isDefined(value)) {\n useLegacyPromise = !!value;\n return this;\n }\n return useLegacyPromise;\n };\n\n /**\n * @ngdoc property\n * @name $httpProvider#interceptors\n * @description\n *\n * Array containing service factories for all synchronous or asynchronous {@link ng.$http $http}\n * pre-processing of request or postprocessing of responses.\n *\n * These service factories are ordered by request, i.e. they are applied in the same order as the\n * array, on request, but reverse order, on response.\n *\n * {@link ng.$http#interceptors Interceptors detailed info}\n **/\n var interceptorFactories = this.interceptors = [];\n\n this.$get = ['$httpBackend', '$$cookieReader', '$cacheFactory', '$rootScope', '$q', '$injector',\n function($httpBackend, $$cookieReader, $cacheFactory, $rootScope, $q, $injector) {\n\n var defaultCache = $cacheFactory('$http');\n\n /**\n * Make sure that default param serializer is exposed as a function\n */\n defaults.paramSerializer = isString(defaults.paramSerializer) ?\n $injector.get(defaults.paramSerializer) : defaults.paramSerializer;\n\n /**\n * Interceptors stored in reverse order. Inner interceptors before outer interceptors.\n * The reversal is needed so that we can build up the interception chain around the\n * server request.\n */\n var reversedInterceptors = [];\n\n forEach(interceptorFactories, function(interceptorFactory) {\n reversedInterceptors.unshift(isString(interceptorFactory)\n ? $injector.get(interceptorFactory) : $injector.invoke(interceptorFactory));\n });\n\n /**\n * @ngdoc service\n * @kind function\n * @name $http\n * @requires ng.$httpBackend\n * @requires $cacheFactory\n * @requires $rootScope\n * @requires $q\n * @requires $injector\n *\n * @description\n * The `$http` service is a core Angular service that facilitates communication with the remote\n * HTTP servers via the browser's [XMLHttpRequest](https://developer.mozilla.org/en/xmlhttprequest)\n * object or via [JSONP](http://en.wikipedia.org/wiki/JSONP).\n *\n * For unit testing applications that use `$http` service, see\n * {@link ngMock.$httpBackend $httpBackend mock}.\n *\n * For a higher level of abstraction, please check out the {@link ngResource.$resource\n * $resource} service.\n *\n * The $http API is based on the {@link ng.$q deferred/promise APIs} exposed by\n * the $q service. While for simple usage patterns this doesn't matter much, for advanced usage\n * it is important to familiarize yourself with these APIs and the guarantees they provide.\n *\n *\n * ## General usage\n * The `$http` service is a function which takes a single argument — a {@link $http#usage configuration object} —\n * that is used to generate an HTTP request and returns a {@link ng.$q promise}.\n *\n * ```js\n * // Simple GET request example:\n * $http({\n * method: 'GET',\n * url: '/someUrl'\n * }).then(function successCallback(response) {\n * // this callback will be called asynchronously\n * // when the response is available\n * }, function errorCallback(response) {\n * // called asynchronously if an error occurs\n * // or server returns response with an error status.\n * });\n * ```\n *\n * The response object has these properties:\n *\n * - **data** – `{string|Object}` – The response body transformed with the transform\n * functions.\n * - **status** – `{number}` – HTTP status code of the response.\n * - **headers** – `{function([headerName])}` – Header getter function.\n * - **config** – `{Object}` – The configuration object that was used to generate the request.\n * - **statusText** – `{string}` – HTTP status text of the response.\n *\n * A response status code between 200 and 299 is considered a success status and\n * will result in the success callback being called. Note that if the response is a redirect,\n * XMLHttpRequest will transparently follow it, meaning that the error callback will not be\n * called for such responses.\n *\n *\n * ## Shortcut methods\n *\n * Shortcut methods are also available. All shortcut methods require passing in the URL, and\n * request data must be passed in for POST/PUT requests. An optional config can be passed as the\n * last argument.\n *\n * ```js\n * $http.get('/someUrl', config).then(successCallback, errorCallback);\n * $http.post('/someUrl', data, config).then(successCallback, errorCallback);\n * ```\n *\n * Complete list of shortcut methods:\n *\n * - {@link ng.$http#get $http.get}\n * - {@link ng.$http#head $http.head}\n * - {@link ng.$http#post $http.post}\n * - {@link ng.$http#put $http.put}\n * - {@link ng.$http#delete $http.delete}\n * - {@link ng.$http#jsonp $http.jsonp}\n * - {@link ng.$http#patch $http.patch}\n *\n *\n * ## Writing Unit Tests that use $http\n * When unit testing (using {@link ngMock ngMock}), it is necessary to call\n * {@link ngMock.$httpBackend#flush $httpBackend.flush()} to flush each pending\n * request using trained responses.\n *\n * ```\n * $httpBackend.expectGET(...);\n * $http.get(...);\n * $httpBackend.flush();\n * ```\n *\n * ## Deprecation Notice\n * \n * The `$http` legacy promise methods `success` and `error` have been deprecated.\n * Use the standard `then` method instead.\n * If {@link $httpProvider#useLegacyPromiseExtensions `$httpProvider.useLegacyPromiseExtensions`} is set to\n * `false` then these methods will throw {@link $http:legacy `$http/legacy`} error.\n *
\n *\n * ## Setting HTTP Headers\n *\n * The $http service will automatically add certain HTTP headers to all requests. These defaults\n * can be fully configured by accessing the `$httpProvider.defaults.headers` configuration\n * object, which currently contains this default configuration:\n *\n * - `$httpProvider.defaults.headers.common` (headers that are common for all requests):\n * - `Accept: application/json, text/plain, * / *`\n * - `$httpProvider.defaults.headers.post`: (header defaults for POST requests)\n * - `Content-Type: application/json`\n * - `$httpProvider.defaults.headers.put` (header defaults for PUT requests)\n * - `Content-Type: application/json`\n *\n * To add or overwrite these defaults, simply add or remove a property from these configuration\n * objects. To add headers for an HTTP method other than POST or PUT, simply add a new object\n * with the lowercased HTTP method name as the key, e.g.\n * `$httpProvider.defaults.headers.get = { 'My-Header' : 'value' }`.\n *\n * The defaults can also be set at runtime via the `$http.defaults` object in the same\n * fashion. For example:\n *\n * ```\n * module.run(function($http) {\n * $http.defaults.headers.common.Authorization = 'Basic YmVlcDpib29w'\n * });\n * ```\n *\n * In addition, you can supply a `headers` property in the config object passed when\n * calling `$http(config)`, which overrides the defaults without changing them globally.\n *\n * To explicitly remove a header automatically added via $httpProvider.defaults.headers on a per request basis,\n * Use the `headers` property, setting the desired header to `undefined`. For example:\n *\n * ```js\n * var req = {\n * method: 'POST',\n * url: 'http://example.com',\n * headers: {\n * 'Content-Type': undefined\n * },\n * data: { test: 'test' }\n * }\n *\n * $http(req).then(function(){...}, function(){...});\n * ```\n *\n * ## Transforming Requests and Responses\n *\n * Both requests and responses can be transformed using transformation functions: `transformRequest`\n * and `transformResponse`. These properties can be a single function that returns\n * the transformed value (`function(data, headersGetter, status)`) or an array of such transformation functions,\n * which allows you to `push` or `unshift` a new transformation function into the transformation chain.\n *\n * ### Default Transformations\n *\n * The `$httpProvider` provider and `$http` service expose `defaults.transformRequest` and\n * `defaults.transformResponse` properties. If a request does not provide its own transformations\n * then these will be applied.\n *\n * You can augment or replace the default transformations by modifying these properties by adding to or\n * replacing the array.\n *\n * Angular provides the following default transformations:\n *\n * Request transformations (`$httpProvider.defaults.transformRequest` and `$http.defaults.transformRequest`):\n *\n * - If the `data` property of the request configuration object contains an object, serialize it\n * into JSON format.\n *\n * Response transformations (`$httpProvider.defaults.transformResponse` and `$http.defaults.transformResponse`):\n *\n * - If XSRF prefix is detected, strip it (see Security Considerations section below).\n * - If JSON response is detected, deserialize it using a JSON parser.\n *\n *\n * ### Overriding the Default Transformations Per Request\n *\n * If you wish override the request/response transformations only for a single request then provide\n * `transformRequest` and/or `transformResponse` properties on the configuration object passed\n * into `$http`.\n *\n * Note that if you provide these properties on the config object the default transformations will be\n * overwritten. If you wish to augment the default transformations then you must include them in your\n * local transformation array.\n *\n * The following code demonstrates adding a new response transformation to be run after the default response\n * transformations have been run.\n *\n * ```js\n * function appendTransform(defaults, transform) {\n *\n * // We can't guarantee that the default transformation is an array\n * defaults = angular.isArray(defaults) ? defaults : [defaults];\n *\n * // Append the new transformation to the defaults\n * return defaults.concat(transform);\n * }\n *\n * $http({\n * url: '...',\n * method: 'GET',\n * transformResponse: appendTransform($http.defaults.transformResponse, function(value) {\n * return doTransform(value);\n * })\n * });\n * ```\n *\n *\n * ## Caching\n *\n * To enable caching, set the request configuration `cache` property to `true` (to use default\n * cache) or to a custom cache object (built with {@link ng.$cacheFactory `$cacheFactory`}).\n * When the cache is enabled, `$http` stores the response from the server in the specified\n * cache. The next time the same request is made, the response is served from the cache without\n * sending a request to the server.\n *\n * Note that even if the response is served from cache, delivery of the data is asynchronous in\n * the same way that real requests are.\n *\n * If there are multiple GET requests for the same URL that should be cached using the same\n * cache, but the cache is not populated yet, only one request to the server will be made and\n * the remaining requests will be fulfilled using the response from the first request.\n *\n * You can change the default cache to a new object (built with\n * {@link ng.$cacheFactory `$cacheFactory`}) by updating the\n * {@link ng.$http#defaults `$http.defaults.cache`} property. All requests who set\n * their `cache` property to `true` will now use this cache object.\n *\n * If you set the default cache to `false` then only requests that specify their own custom\n * cache object will be cached.\n *\n * ## Interceptors\n *\n * Before you start creating interceptors, be sure to understand the\n * {@link ng.$q $q and deferred/promise APIs}.\n *\n * For purposes of global error handling, authentication, or any kind of synchronous or\n * asynchronous pre-processing of request or postprocessing of responses, it is desirable to be\n * able to intercept requests before they are handed to the server and\n * responses before they are handed over to the application code that\n * initiated these requests. The interceptors leverage the {@link ng.$q\n * promise APIs} to fulfill this need for both synchronous and asynchronous pre-processing.\n *\n * The interceptors are service factories that are registered with the `$httpProvider` by\n * adding them to the `$httpProvider.interceptors` array. The factory is called and\n * injected with dependencies (if specified) and returns the interceptor.\n *\n * There are two kinds of interceptors (and two kinds of rejection interceptors):\n *\n * * `request`: interceptors get called with a http {@link $http#usage config} object. The function is free to\n * modify the `config` object or create a new one. The function needs to return the `config`\n * object directly, or a promise containing the `config` or a new `config` object.\n * * `requestError`: interceptor gets called when a previous interceptor threw an error or\n * resolved with a rejection.\n * * `response`: interceptors get called with http `response` object. The function is free to\n * modify the `response` object or create a new one. The function needs to return the `response`\n * object directly, or as a promise containing the `response` or a new `response` object.\n * * `responseError`: interceptor gets called when a previous interceptor threw an error or\n * resolved with a rejection.\n *\n *\n * ```js\n * // register the interceptor as a service\n * $provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {\n * return {\n * // optional method\n * 'request': function(config) {\n * // do something on success\n * return config;\n * },\n *\n * // optional method\n * 'requestError': function(rejection) {\n * // do something on error\n * if (canRecover(rejection)) {\n * return responseOrNewPromise\n * }\n * return $q.reject(rejection);\n * },\n *\n *\n *\n * // optional method\n * 'response': function(response) {\n * // do something on success\n * return response;\n * },\n *\n * // optional method\n * 'responseError': function(rejection) {\n * // do something on error\n * if (canRecover(rejection)) {\n * return responseOrNewPromise\n * }\n * return $q.reject(rejection);\n * }\n * };\n * });\n *\n * $httpProvider.interceptors.push('myHttpInterceptor');\n *\n *\n * // alternatively, register the interceptor via an anonymous factory\n * $httpProvider.interceptors.push(function($q, dependency1, dependency2) {\n * return {\n * 'request': function(config) {\n * // same as above\n * },\n *\n * 'response': function(response) {\n * // same as above\n * }\n * };\n * });\n * ```\n *\n * ## Security Considerations\n *\n * When designing web applications, consider security threats from:\n *\n * - [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)\n * - [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery)\n *\n * Both server and the client must cooperate in order to eliminate these threats. Angular comes\n * pre-configured with strategies that address these issues, but for this to work backend server\n * cooperation is required.\n *\n * ### JSON Vulnerability Protection\n *\n * A [JSON vulnerability](http://haacked.com/archive/2008/11/20/anatomy-of-a-subtle-json-vulnerability.aspx)\n * allows third party website to turn your JSON resource URL into\n * [JSONP](http://en.wikipedia.org/wiki/JSONP) request under some conditions. To\n * counter this your server can prefix all JSON requests with following string `\")]}',\\n\"`.\n * Angular will automatically strip the prefix before processing it as JSON.\n *\n * For example if your server needs to return:\n * ```js\n * ['one','two']\n * ```\n *\n * which is vulnerable to attack, your server can return:\n * ```js\n * )]}',\n * ['one','two']\n * ```\n *\n * Angular will strip the prefix, before processing the JSON.\n *\n *\n * ### Cross Site Request Forgery (XSRF) Protection\n *\n * [XSRF](http://en.wikipedia.org/wiki/Cross-site_request_forgery) is a technique by which\n * an unauthorized site can gain your user's private data. Angular provides a mechanism\n * to counter XSRF. When performing XHR requests, the $http service reads a token from a cookie\n * (by default, `XSRF-TOKEN`) and sets it as an HTTP header (`X-XSRF-TOKEN`). Since only\n * JavaScript that runs on your domain could read the cookie, your server can be assured that\n * the XHR came from JavaScript running on your domain. The header will not be set for\n * cross-domain requests.\n *\n * To take advantage of this, your server needs to set a token in a JavaScript readable session\n * cookie called `XSRF-TOKEN` on the first HTTP GET request. On subsequent XHR requests the\n * server can verify that the cookie matches `X-XSRF-TOKEN` HTTP header, and therefore be sure\n * that only JavaScript running on your domain could have sent the request. The token must be\n * unique for each user and must be verifiable by the server (to prevent the JavaScript from\n * making up its own tokens). We recommend that the token is a digest of your site's\n * authentication cookie with a [salt](https://en.wikipedia.org/wiki/Salt_(cryptography))\n * for added security.\n *\n * The name of the headers can be specified using the xsrfHeaderName and xsrfCookieName\n * properties of either $httpProvider.defaults at config-time, $http.defaults at run-time,\n * or the per-request config object.\n *\n * In order to prevent collisions in environments where multiple Angular apps share the\n * same domain or subdomain, we recommend that each application uses unique cookie name.\n *\n * @param {object} config Object describing the request to be made and how it should be\n * processed. The object has following properties:\n *\n * - **method** – `{string}` – HTTP method (e.g. 'GET', 'POST', etc)\n * - **url** – `{string}` – Absolute or relative URL of the resource that is being requested.\n * - **params** – `{Object.}` – Map of strings or objects which will be serialized\n * with the `paramSerializer` and appended as GET parameters.\n * - **data** – `{string|Object}` – Data to be sent as the request message data.\n * - **headers** – `{Object}` – Map of strings or functions which return strings representing\n * HTTP headers to send to the server. If the return value of a function is null, the\n * header will not be sent. Functions accept a config object as an argument.\n * - **xsrfHeaderName** – `{string}` – Name of HTTP header to populate with the XSRF token.\n * - **xsrfCookieName** – `{string}` – Name of cookie containing the XSRF token.\n * - **transformRequest** –\n * `{function(data, headersGetter)|Array.}` –\n * transform function or an array of such functions. The transform function takes the http\n * request body and headers and returns its transformed (typically serialized) version.\n * See {@link ng.$http#overriding-the-default-transformations-per-request\n * Overriding the Default Transformations}\n * - **transformResponse** –\n * `{function(data, headersGetter, status)|Array.}` –\n * transform function or an array of such functions. The transform function takes the http\n * response body, headers and status and returns its transformed (typically deserialized) version.\n * See {@link ng.$http#overriding-the-default-transformations-per-request\n * Overriding the Default TransformationjqLiks}\n * - **paramSerializer** - `{string|function(Object):string}` - A function used to\n * prepare the string representation of request parameters (specified as an object).\n * If specified as string, it is interpreted as function registered with the\n * {@link $injector $injector}, which means you can create your own serializer\n * by registering it as a {@link auto.$provide#service service}.\n * The default serializer is the {@link $httpParamSerializer $httpParamSerializer};\n * alternatively, you can use the {@link $httpParamSerializerJQLike $httpParamSerializerJQLike}\n * - **cache** – `{boolean|Cache}` – If true, a default $http cache will be used to cache the\n * GET request, otherwise if a cache instance built with\n * {@link ng.$cacheFactory $cacheFactory}, this cache will be used for\n * caching.\n * - **timeout** – `{number|Promise}` – timeout in milliseconds, or {@link ng.$q promise}\n * that should abort the request when resolved.\n * - **withCredentials** - `{boolean}` - whether to set the `withCredentials` flag on the\n * XHR object. See [requests with credentials](https://developer.mozilla.org/docs/Web/HTTP/Access_control_CORS#Requests_with_credentials)\n * for more information.\n * - **responseType** - `{string}` - see\n * [XMLHttpRequest.responseType](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#xmlhttprequest-responsetype).\n *\n * @returns {HttpPromise} Returns a {@link ng.$q `Promise}` that will be resolved to a response object\n * when the request succeeds or fails.\n *\n *\n * @property {Array. \n *\n * @param {string|function=} stateConfig.templateUrl\n * \n *\n * path or function that returns a path to an html\n * template that should be used by uiView.\n * \n * If `templateUrl` is a function, it will be called with the following parameters:\n *\n * - {array.<object>} - state parameters extracted from the current $location.path() by \n * applying the current state\n *\n * templateUrl: \"home.html\"
\n * templateUrl: function(params) {\n * return myTemplates[params.pageId]; }
\n *\n * @param {function=} stateConfig.templateProvider\n * \n * Provider function that returns HTML content string.\n * templateProvider:\n * function(MyTemplateService, params) {\n * return MyTemplateService.getTemplate(params.pageId);\n * }
\n *\n * @param {string|function=} stateConfig.controller\n * \n *\n * Controller fn that should be associated with newly\n * related scope or the name of a registered controller if passed as a string.\n * Optionally, the ControllerAs may be declared here.\n * controller: \"MyRegisteredController\"
\n * controller:\n * \"MyRegisteredController as fooCtrl\"}
\n * controller: function($scope, MyService) {\n * $scope.data = MyService.getData(); }
\n *\n * @param {function=} stateConfig.controllerProvider\n * \n *\n * Injectable provider function that returns the actual controller or string.\n * controllerProvider:\n * function(MyResolveData) {\n * if (MyResolveData.foo)\n * return \"FooCtrl\"\n * else if (MyResolveData.bar)\n * return \"BarCtrl\";\n * else return function($scope) {\n * $scope.baz = \"Qux\";\n * }\n * }
\n *\n * @param {string=} stateConfig.controllerAs\n * \n * \n * A controller alias name. If present the controller will be\n * published to scope under the controllerAs name.\n * controllerAs: \"myCtrl\"
\n *\n * @param {string|object=} stateConfig.parent\n * \n * Optionally specifies the parent state of this state.\n *\n * parent: 'parentState'
\n * parent: parentState // JS variable
\n *\n * @param {object=} stateConfig.resolve\n * \n *\n * An optional map<string, function> of dependencies which\n * should be injected into the controller. If any of these dependencies are promises, \n * the router will wait for them all to be resolved before the controller is instantiated.\n * If all the promises are resolved successfully, the $stateChangeSuccess event is fired\n * and the values of the resolved promises are injected into any controllers that reference them.\n * If any of the promises are rejected the $stateChangeError event is fired.\n *\n * The map object is:\n * \n * - key - {string}: name of dependency to be injected into controller\n * - factory - {string|function}: If string then it is alias for service. Otherwise if function, \n * it is injected and return value it treated as dependency. If result is a promise, it is \n * resolved before its value is injected into controller.\n *\n * resolve: {\n * myResolve1:\n * function($http, $stateParams) {\n * return $http.get(\"/api/foos/\"+stateParams.fooID);\n * }\n * }
\n *\n * @param {string=} stateConfig.url\n * \n *\n * A url fragment with optional parameters. When a state is navigated or\n * transitioned to, the `$stateParams` service will be populated with any \n * parameters that were passed.\n *\n * (See {@link ui.router.util.type:UrlMatcher UrlMatcher} `UrlMatcher`} for\n * more details on acceptable patterns )\n *\n * examples:\n * url: \"/home\"\n * url: \"/users/:userid\"\n * url: \"/books/{bookid:[a-zA-Z_-]}\"\n * url: \"/books/{categoryid:int}\"\n * url: \"/books/{publishername:string}/{categoryid:int}\"\n * url: \"/messages?before&after\"\n * url: \"/messages?{before:date}&{after:date}\"\n * url: \"/messages/:mailboxid?{before:date}&{after:date}\"\n *
\n *\n * @param {object=} stateConfig.views\n * \n * an optional map<string, object> which defined multiple views, or targets views\n * manually/explicitly.\n *\n * Examples:\n *\n * Targets three named `ui-view`s in the parent state's template\n * views: {\n * header: {\n * controller: \"headerCtrl\",\n * templateUrl: \"header.html\"\n * }, body: {\n * controller: \"bodyCtrl\",\n * templateUrl: \"body.html\"\n * }, footer: {\n * controller: \"footCtrl\",\n * templateUrl: \"footer.html\"\n * }\n * }
\n *\n * Targets named `ui-view=\"header\"` from grandparent state 'top''s template, and named `ui-view=\"body\" from parent state's template.\n * views: {\n * 'header@top': {\n * controller: \"msgHeaderCtrl\",\n * templateUrl: \"msgHeader.html\"\n * }, 'body': {\n * controller: \"messagesCtrl\",\n * templateUrl: \"messages.html\"\n * }\n * }
\n *\n * @param {boolean=} [stateConfig.abstract=false]\n * \n * An abstract state will never be directly activated,\n * but can provide inherited properties to its common children states.\n * abstract: true
\n *\n * @param {function=} stateConfig.onEnter\n * \n *\n * Callback function for when a state is entered. Good way\n * to trigger an action or dispatch an event, such as opening a dialog.\n * If minifying your scripts, make sure to explictly annotate this function,\n * because it won't be automatically annotated by your build tools.\n *\n * onEnter: function(MyService, $stateParams) {\n * MyService.foo($stateParams.myParam);\n * }
\n *\n * @param {function=} stateConfig.onExit\n * \n *\n * Callback function for when a state is exited. Good way to\n * trigger an action or dispatch an event, such as opening a dialog.\n * If minifying your scripts, make sure to explictly annotate this function,\n * because it won't be automatically annotated by your build tools.\n *\n * onExit: function(MyService, $stateParams) {\n * MyService.cleanup($stateParams.myParam);\n * }
\n *\n * @param {boolean=} [stateConfig.reloadOnSearch=true]\n * \n *\n * If `false`, will not retrigger the same state\n * just because a search/query parameter has changed (via $location.search() or $location.hash()). \n * Useful for when you'd like to modify $location.search() without triggering a reload.\n * reloadOnSearch: false
\n *\n * @param {object=} stateConfig.data\n * \n *\n * Arbitrary data object, useful for custom configuration. The parent state's `data` is\n * prototypally inherited. In other words, adding a data property to a state adds it to\n * the entire subtree via prototypal inheritance.\n *\n * data: {\n * requiredRole: 'foo'\n * }
\n *\n * @param {object=} stateConfig.params\n * \n *\n * A map which optionally configures parameters declared in the `url`, or\n * defines additional non-url parameters. For each parameter being\n * configured, add a configuration object keyed to the name of the parameter.\n *\n * Each parameter configuration object may contain the following properties:\n *\n * - ** value ** - {object|function=}: specifies the default value for this\n * parameter. This implicitly sets this parameter as optional.\n *\n * When UI-Router routes to a state and no value is\n * specified for this parameter in the URL or transition, the\n * default value will be used instead. If `value` is a function,\n * it will be injected and invoked, and the return value used.\n *\n * *Note*: `undefined` is treated as \"no default value\" while `null`\n * is treated as \"the default value is `null`\".\n *\n * *Shorthand*: If you only need to configure the default value of the\n * parameter, you may use a shorthand syntax. In the **`params`**\n * map, instead mapping the param name to a full parameter configuration\n * object, simply set map it to the default parameter value, e.g.:\n *\n * // define a parameter's default value\n * params: {\n * param1: { value: \"defaultValue\" }\n * }\n * // shorthand default values\n * params: {\n * param1: \"defaultValue\",\n * param2: \"param2Default\"\n * }
\n *\n * - ** array ** - {boolean=}: *(default: false)* If true, the param value will be\n * treated as an array of values. If you specified a Type, the value will be\n * treated as an array of the specified Type. Note: query parameter values\n * default to a special `\"auto\"` mode.\n *\n * For query parameters in `\"auto\"` mode, if multiple values for a single parameter\n * are present in the URL (e.g.: `/foo?bar=1&bar=2&bar=3`) then the values\n * are mapped to an array (e.g.: `{ foo: [ '1', '2', '3' ] }`). However, if\n * only one value is present (e.g.: `/foo?bar=1`) then the value is treated as single\n * value (e.g.: `{ foo: '1' }`).\n *\n * params: {\n * param1: { array: true }\n * }
\n *\n * - ** squash ** - {bool|string=}: `squash` configures how a default parameter value is represented in the URL when\n * the current parameter value is the same as the default value. If `squash` is not set, it uses the\n * configured default squash policy.\n * (See {@link ui.router.util.$urlMatcherFactory#methods_defaultSquashPolicy `defaultSquashPolicy()`})\n *\n * There are three squash settings:\n *\n * - false: The parameter's default value is not squashed. It is encoded and included in the URL\n * - true: The parameter's default value is omitted from the URL. If the parameter is preceeded and followed\n * by slashes in the state's `url` declaration, then one of those slashes are omitted.\n * This can allow for cleaner looking URLs.\n * - `\"\"`: The parameter's default value is replaced with an arbitrary placeholder of your choice.\n *\n * params: {\n * param1: {\n * value: \"defaultId\",\n * squash: true\n * } }\n * // squash \"defaultValue\" to \"~\"\n * params: {\n * param1: {\n * value: \"defaultValue\",\n * squash: \"~\"\n * } }\n *
\n *\n *\n * @example\n * \n * // Some state name examples\n *\n * // stateName can be a single top-level name (must be unique).\n * $stateProvider.state(\"home\", {});\n *\n * // Or it can be a nested state name. This state is a child of the\n * // above \"home\" state.\n * $stateProvider.state(\"home.newest\", {});\n *\n * // Nest states as deeply as needed.\n * $stateProvider.state(\"home.newest.abc.xyz.inception\", {});\n *\n * // state() returns $stateProvider, so you can chain state declarations.\n * $stateProvider\n * .state(\"home\", {})\n * .state(\"about\", {})\n * .state(\"contacts\", {});\n *
\n *\n */\n this.state = state;\n function state(name, definition) {\n /*jshint validthis: true */\n if (isObject(name)) definition = name;\n else definition.name = name;\n registerState(definition);\n return this;\n }\n\n /**\n * @ngdoc object\n * @name ui.router.state.$state\n *\n * @requires $rootScope\n * @requires $q\n * @requires ui.router.state.$view\n * @requires $injector\n * @requires ui.router.util.$resolve\n * @requires ui.router.state.$stateParams\n * @requires ui.router.router.$urlRouter\n *\n * @property {object} params A param object, e.g. {sectionId: section.id)}, that \n * you'd like to test against the current active state.\n * @property {object} current A reference to the state's config object. However \n * you passed it in. Useful for accessing custom data.\n * @property {object} transition Currently pending transition. A promise that'll \n * resolve or reject.\n *\n * @description\n * `$state` service is responsible for representing states as well as transitioning\n * between them. It also provides interfaces to ask for current state or even states\n * you're coming from.\n */\n this.$get = $get;\n $get.$inject = ['$rootScope', '$q', '$view', '$injector', '$resolve', '$stateParams', '$urlRouter', '$location', '$urlMatcherFactory'];\n function $get( $rootScope, $q, $view, $injector, $resolve, $stateParams, $urlRouter, $location, $urlMatcherFactory) {\n\n var TransitionSuperseded = $q.reject(new Error('transition superseded'));\n var TransitionPrevented = $q.reject(new Error('transition prevented'));\n var TransitionAborted = $q.reject(new Error('transition aborted'));\n var TransitionFailed = $q.reject(new Error('transition failed'));\n\n // Handles the case where a state which is the target of a transition is not found, and the user\n // can optionally retry or defer the transition\n function handleRedirect(redirect, state, params, options) {\n /**\n * @ngdoc event\n * @name ui.router.state.$state#$stateNotFound\n * @eventOf ui.router.state.$state\n * @eventType broadcast on root scope\n * @description\n * Fired when a requested state **cannot be found** using the provided state name during transition.\n * The event is broadcast allowing any handlers a single chance to deal with the error (usually by\n * lazy-loading the unfound state). A special `unfoundState` object is passed to the listener handler,\n * you can see its three properties in the example. You can use `event.preventDefault()` to abort the\n * transition and the promise returned from `go` will be rejected with a `'transition aborted'` value.\n *\n * @param {Object} event Event object.\n * @param {Object} unfoundState Unfound State information. Contains: `to, toParams, options` properties.\n * @param {State} fromState Current state object.\n * @param {Object} fromParams Current state params.\n *\n * @example\n *\n * \n * // somewhere, assume lazy.state has not been defined\n * $state.go(\"lazy.state\", {a:1, b:2}, {inherit:false});\n *\n * // somewhere else\n * $scope.$on('$stateNotFound',\n * function(event, unfoundState, fromState, fromParams){\n * console.log(unfoundState.to); // \"lazy.state\"\n * console.log(unfoundState.toParams); // {a:1, b:2}\n * console.log(unfoundState.options); // {inherit:false} + default options\n * })\n *
\n */\n var evt = $rootScope.$broadcast('$stateNotFound', redirect, state, params);\n\n if (evt.defaultPrevented) {\n $urlRouter.update();\n return TransitionAborted;\n }\n\n if (!evt.retry) {\n return null;\n }\n\n // Allow the handler to return a promise to defer state lookup retry\n if (options.$retry) {\n $urlRouter.update();\n return TransitionFailed;\n }\n var retryTransition = $state.transition = $q.when(evt.retry);\n\n retryTransition.then(function() {\n if (retryTransition !== $state.transition) return TransitionSuperseded;\n redirect.options.$retry = true;\n return $state.transitionTo(redirect.to, redirect.toParams, redirect.options);\n }, function() {\n return TransitionAborted;\n });\n $urlRouter.update();\n\n return retryTransition;\n }\n\n root.locals = { resolve: null, globals: { $stateParams: {} } };\n\n $state = {\n params: {},\n current: root.self,\n $current: root,\n transition: null\n };\n\n /**\n * @ngdoc function\n * @name ui.router.state.$state#reload\n * @methodOf ui.router.state.$state\n *\n * @description\n * A method that force reloads the current state. All resolves are re-resolved,\n * controllers reinstantiated, and events re-fired.\n *\n * @example\n * \n * var app angular.module('app', ['ui.router']);\n *\n * app.controller('ctrl', function ($scope, $state) {\n * $scope.reload = function(){\n * $state.reload();\n * }\n * });\n *
\n *\n * `reload()` is just an alias for:\n * \n * $state.transitionTo($state.current, $stateParams, { \n * reload: true, inherit: false, notify: true\n * });\n *
\n *\n * @param {string=|object=} state - A state name or a state object, which is the root of the resolves to be re-resolved.\n * @example\n * \n * //assuming app application consists of 3 states: 'contacts', 'contacts.detail', 'contacts.detail.item' \n * //and current state is 'contacts.detail.item'\n * var app angular.module('app', ['ui.router']);\n *\n * app.controller('ctrl', function ($scope, $state) {\n * $scope.reload = function(){\n * //will reload 'contact.detail' and 'contact.detail.item' states\n * $state.reload('contact.detail');\n * }\n * });\n *
\n *\n * `reload()` is just an alias for:\n * \n * $state.transitionTo($state.current, $stateParams, { \n * reload: true, inherit: false, notify: true\n * });\n *
\n\n * @returns {promise} A promise representing the state of the new transition. See\n * {@link ui.router.state.$state#methods_go $state.go}.\n */\n $state.reload = function reload(state) {\n return $state.transitionTo($state.current, $stateParams, { reload: state || true, inherit: false, notify: true});\n };\n\n /**\n * @ngdoc function\n * @name ui.router.state.$state#go\n * @methodOf ui.router.state.$state\n *\n * @description\n * Convenience method for transitioning to a new state. `$state.go` calls \n * `$state.transitionTo` internally but automatically sets options to \n * `{ location: true, inherit: true, relative: $state.$current, notify: true }`. \n * This allows you to easily use an absolute or relative to path and specify \n * only the parameters you'd like to update (while letting unspecified parameters \n * inherit from the currently active ancestor states).\n *\n * @example\n * \n * var app = angular.module('app', ['ui.router']);\n *\n * app.controller('ctrl', function ($scope, $state) {\n * $scope.changeState = function () {\n * $state.go('contact.detail');\n * };\n * });\n *
\n * \n *\n * @param {string} to Absolute state name or relative state path. Some examples:\n *\n * - `$state.go('contact.detail')` - will go to the `contact.detail` state\n * - `$state.go('^')` - will go to a parent state\n * - `$state.go('^.sibling')` - will go to a sibling state\n * - `$state.go('.child.grandchild')` - will go to grandchild state\n *\n * @param {object=} params A map of the parameters that will be sent to the state, \n * will populate $stateParams. Any parameters that are not specified will be inherited from currently \n * defined parameters. This allows, for example, going to a sibling state that shares parameters\n * specified in a parent state. Parameter inheritance only works between common ancestor states, I.e.\n * transitioning to a sibling will get you the parameters for all parents, transitioning to a child\n * will get you all current parameters, etc.\n * @param {object=} options Options object. The options are:\n *\n * - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`\n * will not. If string, must be `\"replace\"`, which will update url and also replace last history record.\n * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.\n * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'), \n * defines which state to be relative from.\n * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.\n * - **`reload`** (v0.2.5) - {boolean=false}, If `true` will force transition even if the state or params \n * have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd\n * use this when you want to force a reload when *everything* is the same, including search params.\n *\n * @returns {promise} A promise representing the state of the new transition.\n *\n * Possible success values:\n *\n * - $state.current\n *\n *
Possible rejection values:\n *\n * - 'transition superseded' - when a newer transition has been started after this one\n * - 'transition prevented' - when `event.preventDefault()` has been called in a `$stateChangeStart` listener\n * - 'transition aborted' - when `event.preventDefault()` has been called in a `$stateNotFound` listener or\n * when a `$stateNotFound` `event.retry` promise errors.\n * - 'transition failed' - when a state has been unsuccessfully found after 2 tries.\n * - *resolve error* - when an error has occurred with a `resolve`\n *\n */\n $state.go = function go(to, params, options) {\n return $state.transitionTo(to, params, extend({ inherit: true, relative: $state.$current }, options));\n };\n\n /**\n * @ngdoc function\n * @name ui.router.state.$state#transitionTo\n * @methodOf ui.router.state.$state\n *\n * @description\n * Low-level method for transitioning to a new state. {@link ui.router.state.$state#methods_go $state.go}\n * uses `transitionTo` internally. `$state.go` is recommended in most situations.\n *\n * @example\n * \n * var app = angular.module('app', ['ui.router']);\n *\n * app.controller('ctrl', function ($scope, $state) {\n * $scope.changeState = function () {\n * $state.transitionTo('contact.detail');\n * };\n * });\n *
\n *\n * @param {string} to State name.\n * @param {object=} toParams A map of the parameters that will be sent to the state,\n * will populate $stateParams.\n * @param {object=} options Options object. The options are:\n *\n * - **`location`** - {boolean=true|string=} - If `true` will update the url in the location bar, if `false`\n * will not. If string, must be `\"replace\"`, which will update url and also replace last history record.\n * - **`inherit`** - {boolean=false}, If `true` will inherit url parameters from current url.\n * - **`relative`** - {object=}, When transitioning with relative path (e.g '^'), \n * defines which state to be relative from.\n * - **`notify`** - {boolean=true}, If `true` will broadcast $stateChangeStart and $stateChangeSuccess events.\n * - **`reload`** (v0.2.5) - {boolean=false|string=|object=}, If `true` will force transition even if the state or params \n * have not changed, aka a reload of the same state. It differs from reloadOnSearch because you'd\n * use this when you want to force a reload when *everything* is the same, including search params.\n * if String, then will reload the state with the name given in reload, and any children.\n * if Object, then a stateObj is expected, will reload the state found in stateObj, and any children.\n *\n * @returns {promise} A promise representing the state of the new transition. See\n * {@link ui.router.state.$state#methods_go $state.go}.\n */\n $state.transitionTo = function transitionTo(to, toParams, options) {\n toParams = toParams || {};\n options = extend({\n location: true, inherit: false, relative: null, notify: true, reload: false, $retry: false\n }, options || {});\n\n var from = $state.$current, fromParams = $state.params, fromPath = from.path;\n var evt, toState = findState(to, options.relative);\n\n // Store the hash param for later (since it will be stripped out by various methods)\n var hash = toParams['#'];\n\n if (!isDefined(toState)) {\n var redirect = { to: to, toParams: toParams, options: options };\n var redirectResult = handleRedirect(redirect, from.self, fromParams, options);\n\n if (redirectResult) {\n return redirectResult;\n }\n\n // Always retry once if the $stateNotFound was not prevented\n // (handles either redirect changed or state lazy-definition)\n to = redirect.to;\n toParams = redirect.toParams;\n options = redirect.options;\n toState = findState(to, options.relative);\n\n if (!isDefined(toState)) {\n if (!options.relative) throw new Error(\"No such state '\" + to + \"'\");\n throw new Error(\"Could not resolve '\" + to + \"' from state '\" + options.relative + \"'\");\n }\n }\n if (toState[abstractKey]) throw new Error(\"Cannot transition to abstract state '\" + to + \"'\");\n if (options.inherit) toParams = inheritParams($stateParams, toParams || {}, $state.$current, toState);\n if (!toState.params.$$validates(toParams)) return TransitionFailed;\n\n toParams = toState.params.$$values(toParams);\n to = toState;\n\n var toPath = to.path;\n\n // Starting from the root of the path, keep all levels that haven't changed\n var keep = 0, state = toPath[keep], locals = root.locals, toLocals = [];\n\n if (!options.reload) {\n while (state && state === fromPath[keep] && state.ownParams.$$equals(toParams, fromParams)) {\n locals = toLocals[keep] = state.locals;\n keep++;\n state = toPath[keep];\n }\n } else if (isString(options.reload) || isObject(options.reload)) {\n if (isObject(options.reload) && !options.reload.name) {\n throw new Error('Invalid reload state object');\n }\n \n var reloadState = options.reload === true ? fromPath[0] : findState(options.reload);\n if (options.reload && !reloadState) {\n throw new Error(\"No such reload state '\" + (isString(options.reload) ? options.reload : options.reload.name) + \"'\");\n }\n\n while (state && state === fromPath[keep] && state !== reloadState) {\n locals = toLocals[keep] = state.locals;\n keep++;\n state = toPath[keep];\n }\n }\n\n // If we're going to the same state and all locals are kept, we've got nothing to do.\n // But clear 'transition', as we still want to cancel any other pending transitions.\n // TODO: We may not want to bump 'transition' if we're called from a location change\n // that we've initiated ourselves, because we might accidentally abort a legitimate\n // transition initiated from code?\n if (shouldSkipReload(to, toParams, from, fromParams, locals, options)) {\n if (hash) toParams['#'] = hash;\n $state.params = toParams;\n copy($state.params, $stateParams);\n if (options.location && to.navigable && to.navigable.url) {\n $urlRouter.push(to.navigable.url, toParams, {\n $$avoidResync: true, replace: options.location === 'replace'\n });\n $urlRouter.update(true);\n }\n $state.transition = null;\n return $q.when($state.current);\n }\n\n // Filter parameters before we pass them to event handlers etc.\n toParams = filterByKeys(to.params.$$keys(), toParams || {});\n\n // Broadcast start event and cancel the transition if requested\n if (options.notify) {\n /**\n * @ngdoc event\n * @name ui.router.state.$state#$stateChangeStart\n * @eventOf ui.router.state.$state\n * @eventType broadcast on root scope\n * @description\n * Fired when the state transition **begins**. You can use `event.preventDefault()`\n * to prevent the transition from happening and then the transition promise will be\n * rejected with a `'transition prevented'` value.\n *\n * @param {Object} event Event object.\n * @param {State} toState The state being transitioned to.\n * @param {Object} toParams The params supplied to the `toState`.\n * @param {State} fromState The current state, pre-transition.\n * @param {Object} fromParams The params supplied to the `fromState`.\n *\n * @example\n *\n * \n * $rootScope.$on('$stateChangeStart',\n * function(event, toState, toParams, fromState, fromParams){\n * event.preventDefault();\n * // transitionTo() promise will be rejected with\n * // a 'transition prevented' error\n * })\n *
\n */\n if ($rootScope.$broadcast('$stateChangeStart', to.self, toParams, from.self, fromParams).defaultPrevented) {\n $rootScope.$broadcast('$stateChangeCancel', to.self, toParams, from.self, fromParams);\n $urlRouter.update();\n return TransitionPrevented;\n }\n }\n\n // Resolve locals for the remaining states, but don't update any global state just\n // yet -- if anything fails to resolve the current state needs to remain untouched.\n // We also set up an inheritance chain for the locals here. This allows the view directive\n // to quickly look up the correct definition for each view in the current state. Even\n // though we create the locals object itself outside resolveState(), it is initially\n // empty and gets filled asynchronously. We need to keep track of the promise for the\n // (fully resolved) current locals, and pass this down the chain.\n var resolved = $q.when(locals);\n\n for (var l = keep; l < toPath.length; l++, state = toPath[l]) {\n locals = toLocals[l] = inherit(locals);\n resolved = resolveState(state, toParams, state === to, resolved, locals, options);\n }\n\n // Once everything is resolved, we are ready to perform the actual transition\n // and return a promise for the new state. We also keep track of what the\n // current promise is, so that we can detect overlapping transitions and\n // keep only the outcome of the last transition.\n var transition = $state.transition = resolved.then(function () {\n var l, entering, exiting;\n\n if ($state.transition !== transition) return TransitionSuperseded;\n\n // Exit 'from' states not kept\n for (l = fromPath.length - 1; l >= keep; l--) {\n exiting = fromPath[l];\n if (exiting.self.onExit) {\n $injector.invoke(exiting.self.onExit, exiting.self, exiting.locals.globals);\n }\n exiting.locals = null;\n }\n\n // Enter 'to' states not kept\n for (l = keep; l < toPath.length; l++) {\n entering = toPath[l];\n entering.locals = toLocals[l];\n if (entering.self.onEnter) {\n $injector.invoke(entering.self.onEnter, entering.self, entering.locals.globals);\n }\n }\n\n // Re-add the saved hash before we start returning things\n if (hash) toParams['#'] = hash;\n\n // Run it again, to catch any transitions in callbacks\n if ($state.transition !== transition) return TransitionSuperseded;\n\n // Update globals in $state\n $state.$current = to;\n $state.current = to.self;\n $state.params = toParams;\n copy($state.params, $stateParams);\n $state.transition = null;\n\n if (options.location && to.navigable) {\n $urlRouter.push(to.navigable.url, to.navigable.locals.globals.$stateParams, {\n $$avoidResync: true, replace: options.location === 'replace'\n });\n }\n\n if (options.notify) {\n /**\n * @ngdoc event\n * @name ui.router.state.$state#$stateChangeSuccess\n * @eventOf ui.router.state.$state\n * @eventType broadcast on root scope\n * @description\n * Fired once the state transition is **complete**.\n *\n * @param {Object} event Event object.\n * @param {State} toState The state being transitioned to.\n * @param {Object} toParams The params supplied to the `toState`.\n * @param {State} fromState The current state, pre-transition.\n * @param {Object} fromParams The params supplied to the `fromState`.\n */\n $rootScope.$broadcast('$stateChangeSuccess', to.self, toParams, from.self, fromParams);\n }\n $urlRouter.update(true);\n\n return $state.current;\n }, function (error) {\n if ($state.transition !== transition) return TransitionSuperseded;\n\n $state.transition = null;\n /**\n * @ngdoc event\n * @name ui.router.state.$state#$stateChangeError\n * @eventOf ui.router.state.$state\n * @eventType broadcast on root scope\n * @description\n * Fired when an **error occurs** during transition. It's important to note that if you\n * have any errors in your resolve functions (javascript errors, non-existent services, etc)\n * they will not throw traditionally. You must listen for this $stateChangeError event to\n * catch **ALL** errors.\n *\n * @param {Object} event Event object.\n * @param {State} toState The state being transitioned to.\n * @param {Object} toParams The params supplied to the `toState`.\n * @param {State} fromState The current state, pre-transition.\n * @param {Object} fromParams The params supplied to the `fromState`.\n * @param {Error} error The resolve error object.\n */\n evt = $rootScope.$broadcast('$stateChangeError', to.self, toParams, from.self, fromParams, error);\n\n if (!evt.defaultPrevented) {\n $urlRouter.update();\n }\n\n return $q.reject(error);\n });\n\n return transition;\n };\n\n /**\n * @ngdoc function\n * @name ui.router.state.$state#is\n * @methodOf ui.router.state.$state\n *\n * @description\n * Similar to {@link ui.router.state.$state#methods_includes $state.includes},\n * but only checks for the full state name. If params is supplied then it will be\n * tested for strict equality against the current active params object, so all params\n * must match with none missing and no extras.\n *\n * @example\n * \n * $state.$current.name = 'contacts.details.item';\n *\n * // absolute name\n * $state.is('contact.details.item'); // returns true\n * $state.is(contactDetailItemStateObject); // returns true\n *\n * // relative name (. and ^), typically from a template\n * // E.g. from the 'contacts.details' template\n * Item
\n *
\n *\n * @param {string|object} stateOrName The state name (absolute or relative) or state object you'd like to check.\n * @param {object=} params A param object, e.g. `{sectionId: section.id}`, that you'd like\n * to test against the current active state.\n * @param {object=} options An options object. The options are:\n *\n * - **`relative`** - {string|object} - If `stateOrName` is a relative state name and `options.relative` is set, .is will\n * test relative to `options.relative` state (or name).\n *\n * @returns {boolean} Returns true if it is the state.\n */\n $state.is = function is(stateOrName, params, options) {\n options = extend({ relative: $state.$current }, options || {});\n var state = findState(stateOrName, options.relative);\n\n if (!isDefined(state)) { return undefined; }\n if ($state.$current !== state) { return false; }\n return params ? equalForKeys(state.params.$$values(params), $stateParams) : true;\n };\n\n /**\n * @ngdoc function\n * @name ui.router.state.$state#includes\n * @methodOf ui.router.state.$state\n *\n * @description\n * A method to determine if the current active state is equal to or is the child of the\n * state stateName. If any params are passed then they will be tested for a match as well.\n * Not all the parameters need to be passed, just the ones you'd like to test for equality.\n *\n * @example\n * Partial and relative names\n * \n * $state.$current.name = 'contacts.details.item';\n *\n * // Using partial names\n * $state.includes(\"contacts\"); // returns true\n * $state.includes(\"contacts.details\"); // returns true\n * $state.includes(\"contacts.details.item\"); // returns true\n * $state.includes(\"contacts.list\"); // returns false\n * $state.includes(\"about\"); // returns false\n *\n * // Using relative names (. and ^), typically from a template\n * // E.g. from the 'contacts.details' template\n * Item
\n *
\n *\n * Basic globbing patterns\n * \n * $state.$current.name = 'contacts.details.item.url';\n *\n * $state.includes(\"*.details.*.*\"); // returns true\n * $state.includes(\"*.details.**\"); // returns true\n * $state.includes(\"**.item.**\"); // returns true\n * $state.includes(\"*.details.item.url\"); // returns true\n * $state.includes(\"*.details.*.url\"); // returns true\n * $state.includes(\"*.details.*\"); // returns false\n * $state.includes(\"item.**\"); // returns false\n *
\n *\n * @param {string} stateOrName A partial name, relative name, or glob pattern\n * to be searched for within the current state name.\n * @param {object=} params A param object, e.g. `{sectionId: section.id}`,\n * that you'd like to test against the current active state.\n * @param {object=} options An options object. The options are:\n *\n * - **`relative`** - {string|object=} - If `stateOrName` is a relative state reference and `options.relative` is set,\n * .includes will test relative to `options.relative` state (or name).\n *\n * @returns {boolean} Returns true if it does include the state\n */\n $state.includes = function includes(stateOrName, params, options) {\n options = extend({ relative: $state.$current }, options || {});\n if (isString(stateOrName) && isGlob(stateOrName)) {\n if (!doesStateMatchGlob(stateOrName)) {\n return false;\n }\n stateOrName = $state.$current.name;\n }\n\n var state = findState(stateOrName, options.relative);\n if (!isDefined(state)) { return undefined; }\n if (!isDefined($state.$current.includes[state.name])) { return false; }\n return params ? equalForKeys(state.params.$$values(params), $stateParams, objectKeys(params)) : true;\n };\n\n\n /**\n * @ngdoc function\n * @name ui.router.state.$state#href\n * @methodOf ui.router.state.$state\n *\n * @description\n * A url generation method that returns the compiled url for the given state populated with the given params.\n *\n * @example\n * \n * expect($state.href(\"about.person\", { person: \"bob\" })).toEqual(\"/about/bob\");\n *
\n *\n * @param {string|object} stateOrName The state name or state object you'd like to generate a url from.\n * @param {object=} params An object of parameter values to fill the state's required parameters.\n * @param {object=} options Options object. The options are:\n *\n * - **`lossy`** - {boolean=true} - If true, and if there is no url associated with the state provided in the\n * first parameter, then the constructed href url will be built from the first navigable ancestor (aka\n * ancestor with a valid url).\n * - **`inherit`** - {boolean=true}, If `true` will inherit url parameters from current url.\n * - **`relative`** - {object=$state.$current}, When transitioning with relative path (e.g '^'), \n * defines which state to be relative from.\n * - **`absolute`** - {boolean=false}, If true will generate an absolute url, e.g. \"http://www.example.com/fullurl\".\n * \n * @returns {string} compiled state url\n */\n $state.href = function href(stateOrName, params, options) {\n options = extend({\n lossy: true,\n inherit: true,\n absolute: false,\n relative: $state.$current\n }, options || {});\n\n var state = findState(stateOrName, options.relative);\n\n if (!isDefined(state)) return null;\n if (options.inherit) params = inheritParams($stateParams, params || {}, $state.$current, state);\n \n var nav = (state && options.lossy) ? state.navigable : state;\n\n if (!nav || nav.url === undefined || nav.url === null) {\n return null;\n }\n return $urlRouter.href(nav.url, filterByKeys(state.params.$$keys().concat('#'), params || {}), {\n absolute: options.absolute\n });\n };\n\n /**\n * @ngdoc function\n * @name ui.router.state.$state#get\n * @methodOf ui.router.state.$state\n *\n * @description\n * Returns the state configuration object for any specific state or all states.\n *\n * @param {string|object=} stateOrName (absolute or relative) If provided, will only get the config for\n * the requested state. If not provided, returns an array of ALL state configs.\n * @param {string|object=} context When stateOrName is a relative state reference, the state will be retrieved relative to context.\n * @returns {Object|Array} State configuration object or array of all objects.\n */\n $state.get = function (stateOrName, context) {\n if (arguments.length === 0) return map(objectKeys(states), function(name) { return states[name].self; });\n var state = findState(stateOrName, context || $state.$current);\n return (state && state.self) ? state.self : null;\n };\n\n function resolveState(state, params, paramsAreFiltered, inherited, dst, options) {\n // Make a restricted $stateParams with only the parameters that apply to this state if\n // necessary. In addition to being available to the controller and onEnter/onExit callbacks,\n // we also need $stateParams to be available for any $injector calls we make during the\n // dependency resolution process.\n var $stateParams = (paramsAreFiltered) ? params : filterByKeys(state.params.$$keys(), params);\n var locals = { $stateParams: $stateParams };\n\n // Resolve 'global' dependencies for the state, i.e. those not specific to a view.\n // We're also including $stateParams in this; that way the parameters are restricted\n // to the set that should be visible to the state, and are independent of when we update\n // the global $state and $stateParams values.\n dst.resolve = $resolve.resolve(state.resolve, locals, dst.resolve, state);\n var promises = [dst.resolve.then(function (globals) {\n dst.globals = globals;\n })];\n if (inherited) promises.push(inherited);\n\n function resolveViews() {\n var viewsPromises = [];\n\n // Resolve template and dependencies for all views.\n forEach(state.views, function (view, name) {\n var injectables = (view.resolve && view.resolve !== state.resolve ? view.resolve : {});\n injectables.$template = [ function () {\n return $view.load(name, { view: view, locals: dst.globals, params: $stateParams, notify: options.notify }) || '';\n }];\n\n viewsPromises.push($resolve.resolve(injectables, dst.globals, dst.resolve, state).then(function (result) {\n // References to the controller (only instantiated at link time)\n if (isFunction(view.controllerProvider) || isArray(view.controllerProvider)) {\n var injectLocals = angular.extend({}, injectables, dst.globals);\n result.$$controller = $injector.invoke(view.controllerProvider, null, injectLocals);\n } else {\n result.$$controller = view.controller;\n }\n // Provide access to the state itself for internal use\n result.$$state = state;\n result.$$controllerAs = view.controllerAs;\n dst[name] = result;\n }));\n });\n\n return $q.all(viewsPromises).then(function(){\n return dst.globals;\n });\n }\n\n // Wait for all the promises and then return the activation object\n return $q.all(promises).then(resolveViews).then(function (values) {\n return dst;\n });\n }\n\n return $state;\n }\n\n function shouldSkipReload(to, toParams, from, fromParams, locals, options) {\n // Return true if there are no differences in non-search (path/object) params, false if there are differences\n function nonSearchParamsEqual(fromAndToState, fromParams, toParams) {\n // Identify whether all the parameters that differ between `fromParams` and `toParams` were search params.\n function notSearchParam(key) {\n return fromAndToState.params[key].location != \"search\";\n }\n var nonQueryParamKeys = fromAndToState.params.$$keys().filter(notSearchParam);\n var nonQueryParams = pick.apply({}, [fromAndToState.params].concat(nonQueryParamKeys));\n var nonQueryParamSet = new $$UMFP.ParamSet(nonQueryParams);\n return nonQueryParamSet.$$equals(fromParams, toParams);\n }\n\n // If reload was not explicitly requested\n // and we're transitioning to the same state we're already in\n // and the locals didn't change\n // or they changed in a way that doesn't merit reloading\n // (reloadOnParams:false, or reloadOnSearch.false and only search params changed)\n // Then return true.\n if (!options.reload && to === from &&\n (locals === from.locals || (to.self.reloadOnSearch === false && nonSearchParamsEqual(from, fromParams, toParams)))) {\n return true;\n }\n }\n}\n\nangular.module('ui.router.state')\n .value('$stateParams', {})\n .provider('$state', $StateProvider);\n\n\n$ViewProvider.$inject = [];\nfunction $ViewProvider() {\n\n this.$get = $get;\n /**\n * @ngdoc object\n * @name ui.router.state.$view\n *\n * @requires ui.router.util.$templateFactory\n * @requires $rootScope\n *\n * @description\n *\n */\n $get.$inject = ['$rootScope', '$templateFactory'];\n function $get( $rootScope, $templateFactory) {\n return {\n // $view.load('full.viewName', { template: ..., controller: ..., resolve: ..., async: false, params: ... })\n /**\n * @ngdoc function\n * @name ui.router.state.$view#load\n * @methodOf ui.router.state.$view\n *\n * @description\n *\n * @param {string} name name\n * @param {object} options option object.\n */\n load: function load(name, options) {\n var result, defaults = {\n template: null, controller: null, view: null, locals: null, notify: true, async: true, params: {}\n };\n options = extend(defaults, options);\n\n if (options.view) {\n result = $templateFactory.fromConfig(options.view, options.params, options.locals);\n }\n if (result && options.notify) {\n /**\n * @ngdoc event\n * @name ui.router.state.$state#$viewContentLoading\n * @eventOf ui.router.state.$view\n * @eventType broadcast on root scope\n * @description\n *\n * Fired once the view **begins loading**, *before* the DOM is rendered.\n *\n * @param {Object} event Event object.\n * @param {Object} viewConfig The view config properties (template, controller, etc).\n *\n * @example\n *\n * \n * $scope.$on('$viewContentLoading',\n * function(event, viewConfig){\n * // Access to all the view config properties.\n * // and one special property 'targetView'\n * // viewConfig.targetView\n * });\n *
\n */\n $rootScope.$broadcast('$viewContentLoading', options);\n }\n return result;\n }\n };\n }\n}\n\nangular.module('ui.router.state').provider('$view', $ViewProvider);\n\n/**\n * @ngdoc object\n * @name ui.router.state.$uiViewScrollProvider\n *\n * @description\n * Provider that returns the {@link ui.router.state.$uiViewScroll} service function.\n */\nfunction $ViewScrollProvider() {\n\n var useAnchorScroll = false;\n\n /**\n * @ngdoc function\n * @name ui.router.state.$uiViewScrollProvider#useAnchorScroll\n * @methodOf ui.router.state.$uiViewScrollProvider\n *\n * @description\n * Reverts back to using the core [`$anchorScroll`](http://docs.angularjs.org/api/ng.$anchorScroll) service for\n * scrolling based on the url anchor.\n */\n this.useAnchorScroll = function () {\n useAnchorScroll = true;\n };\n\n /**\n * @ngdoc object\n * @name ui.router.state.$uiViewScroll\n *\n * @requires $anchorScroll\n * @requires $timeout\n *\n * @description\n * When called with a jqLite element, it scrolls the element into view (after a\n * `$timeout` so the DOM has time to refresh).\n *\n * If you prefer to rely on `$anchorScroll` to scroll the view to the anchor,\n * this can be enabled by calling {@link ui.router.state.$uiViewScrollProvider#methods_useAnchorScroll `$uiViewScrollProvider.useAnchorScroll()`}.\n */\n this.$get = ['$anchorScroll', '$timeout', function ($anchorScroll, $timeout) {\n if (useAnchorScroll) {\n return $anchorScroll;\n }\n\n return function ($element) {\n return $timeout(function () {\n $element[0].scrollIntoView();\n }, 0, false);\n };\n }];\n}\n\nangular.module('ui.router.state').provider('$uiViewScroll', $ViewScrollProvider);\n\n/**\n * @ngdoc directive\n * @name ui.router.state.directive:ui-view\n *\n * @requires ui.router.state.$state\n * @requires $compile\n * @requires $controller\n * @requires $injector\n * @requires ui.router.state.$uiViewScroll\n * @requires $document\n *\n * @restrict ECA\n *\n * @description\n * The ui-view directive tells $state where to place your templates.\n *\n * @param {string=} name A view name. The name should be unique amongst the other views in the\n * same state. You can have views of the same name that live in different states.\n *\n * @param {string=} autoscroll It allows you to set the scroll behavior of the browser window\n * when a view is populated. By default, $anchorScroll is overridden by ui-router's custom scroll\n * service, {@link ui.router.state.$uiViewScroll}. This custom service let's you\n * scroll ui-view elements into view when they are populated during a state activation.\n *\n * *Note: To revert back to old [`$anchorScroll`](http://docs.angularjs.org/api/ng.$anchorScroll)\n * functionality, call `$uiViewScrollProvider.useAnchorScroll()`.*\n *\n * @param {string=} onload Expression to evaluate whenever the view updates.\n * \n * @example\n * A view can be unnamed or named. \n * \n * \n * \n * \n * \n * \n *
\n *\n * You can only have one unnamed view within any template (or root html). If you are only using a \n * single view and it is unnamed then you can populate it like so:\n * \n * \n * $stateProvider.state(\"home\", {\n * template: \"HELLO!
\"\n * })\n *
\n * \n * The above is a convenient shortcut equivalent to specifying your view explicitly with the {@link ui.router.state.$stateProvider#views `views`}\n * config property, by name, in this case an empty name:\n * \n * $stateProvider.state(\"home\", {\n * views: {\n * \"\": {\n * template: \"HELLO!
\"\n * }\n * } \n * })\n *
\n * \n * But typically you'll only use the views property if you name your view or have more than one view \n * in the same template. There's not really a compelling reason to name a view if its the only one, \n * but you could if you wanted, like so:\n * \n * \n *
\n * \n * $stateProvider.state(\"home\", {\n * views: {\n * \"main\": {\n * template: \"HELLO!
\"\n * }\n * } \n * })\n *
\n * \n * Really though, you'll use views to set up multiple views:\n * \n * \n * \n * \n *
\n * \n * \n * $stateProvider.state(\"home\", {\n * views: {\n * \"\": {\n * template: \"HELLO!
\"\n * },\n * \"chart\": {\n * template: \"\"\n * },\n * \"data\": {\n * template: \"\"\n * }\n * } \n * })\n *
\n *\n * Examples for `autoscroll`:\n *\n * \n * \n * \n *\n * \n * \n * \n * \n *
\n */\n$ViewDirective.$inject = ['$state', '$injector', '$uiViewScroll', '$interpolate'];\nfunction $ViewDirective( $state, $injector, $uiViewScroll, $interpolate) {\n\n function getService() {\n return ($injector.has) ? function(service) {\n return $injector.has(service) ? $injector.get(service) : null;\n } : function(service) {\n try {\n return $injector.get(service);\n } catch (e) {\n return null;\n }\n };\n }\n\n var service = getService(),\n $animator = service('$animator'),\n $animate = service('$animate');\n\n // Returns a set of DOM manipulation functions based on which Angular version\n // it should use\n function getRenderer(attrs, scope) {\n var statics = function() {\n return {\n enter: function (element, target, cb) { target.after(element); cb(); },\n leave: function (element, cb) { element.remove(); cb(); }\n };\n };\n\n if ($animate) {\n return {\n enter: function(element, target, cb) {\n var promise = $animate.enter(element, null, target, cb);\n if (promise && promise.then) promise.then(cb);\n },\n leave: function(element, cb) {\n var promise = $animate.leave(element, cb);\n if (promise && promise.then) promise.then(cb);\n }\n };\n }\n\n if ($animator) {\n var animate = $animator && $animator(scope, attrs);\n\n return {\n enter: function(element, target, cb) {animate.enter(element, null, target); cb(); },\n leave: function(element, cb) { animate.leave(element); cb(); }\n };\n }\n\n return statics();\n }\n\n var directive = {\n restrict: 'ECA',\n terminal: true,\n priority: 400,\n transclude: 'element',\n compile: function (tElement, tAttrs, $transclude) {\n return function (scope, $element, attrs) {\n var previousEl, currentEl, currentScope, latestLocals,\n onloadExp = attrs.onload || '',\n autoScrollExp = attrs.autoscroll,\n renderer = getRenderer(attrs, scope);\n\n scope.$on('$stateChangeSuccess', function() {\n updateView(false);\n });\n scope.$on('$viewContentLoading', function() {\n updateView(false);\n });\n\n updateView(true);\n\n function cleanupLastView() {\n if (previousEl) {\n previousEl.remove();\n previousEl = null;\n }\n\n if (currentScope) {\n currentScope.$destroy();\n currentScope = null;\n }\n\n if (currentEl) {\n renderer.leave(currentEl, function() {\n previousEl = null;\n });\n\n previousEl = currentEl;\n currentEl = null;\n }\n }\n\n function updateView(firstTime) {\n var newScope,\n name = getUiViewName(scope, attrs, $element, $interpolate),\n previousLocals = name && $state.$current && $state.$current.locals[name];\n\n if (!firstTime && previousLocals === latestLocals) return; // nothing to do\n newScope = scope.$new();\n latestLocals = $state.$current.locals[name];\n\n var clone = $transclude(newScope, function(clone) {\n renderer.enter(clone, $element, function onUiViewEnter() {\n if(currentScope) {\n currentScope.$emit('$viewContentAnimationEnded');\n }\n\n if (angular.isDefined(autoScrollExp) && !autoScrollExp || scope.$eval(autoScrollExp)) {\n $uiViewScroll(clone);\n }\n });\n cleanupLastView();\n });\n\n currentEl = clone;\n currentScope = newScope;\n /**\n * @ngdoc event\n * @name ui.router.state.directive:ui-view#$viewContentLoaded\n * @eventOf ui.router.state.directive:ui-view\n * @eventType emits on ui-view directive scope\n * @description *\n * Fired once the view is **loaded**, *after* the DOM is rendered.\n *\n * @param {Object} event Event object.\n */\n currentScope.$emit('$viewContentLoaded');\n currentScope.$eval(onloadExp);\n }\n };\n }\n };\n\n return directive;\n}\n\n$ViewDirectiveFill.$inject = ['$compile', '$controller', '$state', '$interpolate'];\nfunction $ViewDirectiveFill ( $compile, $controller, $state, $interpolate) {\n return {\n restrict: 'ECA',\n priority: -400,\n compile: function (tElement) {\n var initial = tElement.html();\n return function (scope, $element, attrs) {\n var current = $state.$current,\n name = getUiViewName(scope, attrs, $element, $interpolate),\n locals = current && current.locals[name];\n\n if (! locals) {\n return;\n }\n\n $element.data('$uiView', { name: name, state: locals.$$state });\n $element.html(locals.$template ? locals.$template : initial);\n\n var link = $compile($element.contents());\n\n if (locals.$$controller) {\n locals.$scope = scope;\n locals.$element = $element;\n var controller = $controller(locals.$$controller, locals);\n if (locals.$$controllerAs) {\n scope[locals.$$controllerAs] = controller;\n }\n $element.data('$ngControllerController', controller);\n $element.children().data('$ngControllerController', controller);\n }\n\n link(scope);\n };\n }\n };\n}\n\n/**\n * Shared ui-view code for both directives:\n * Given scope, element, and its attributes, return the view's name\n */\nfunction getUiViewName(scope, attrs, element, $interpolate) {\n var name = $interpolate(attrs.uiView || attrs.name || '')(scope);\n var inherited = element.inheritedData('$uiView');\n return name.indexOf('@') >= 0 ? name : (name + '@' + (inherited ? inherited.state.name : ''));\n}\n\nangular.module('ui.router.state').directive('uiView', $ViewDirective);\nangular.module('ui.router.state').directive('uiView', $ViewDirectiveFill);\n\nfunction parseStateRef(ref, current) {\n var preparsed = ref.match(/^\\s*({[^}]*})\\s*$/), parsed;\n if (preparsed) ref = current + '(' + preparsed[1] + ')';\n parsed = ref.replace(/\\n/g, \" \").match(/^([^(]+?)\\s*(\\((.*)\\))?$/);\n if (!parsed || parsed.length !== 4) throw new Error(\"Invalid state ref '\" + ref + \"'\");\n return { state: parsed[1], paramExpr: parsed[3] || null };\n}\n\nfunction stateContext(el) {\n var stateData = el.parent().inheritedData('$uiView');\n\n if (stateData && stateData.state && stateData.state.name) {\n return stateData.state;\n }\n}\n\n/**\n * @ngdoc directive\n * @name ui.router.state.directive:ui-sref\n *\n * @requires ui.router.state.$state\n * @requires $timeout\n *\n * @restrict A\n *\n * @description\n * A directive that binds a link (`` tag) to a state. If the state has an associated \n * URL, the directive will automatically generate & update the `href` attribute via \n * the {@link ui.router.state.$state#methods_href $state.href()} method. Clicking \n * the link will trigger a state transition with optional parameters. \n *\n * Also middle-clicking, right-clicking, and ctrl-clicking on the link will be \n * handled natively by the browser.\n *\n * You can also use relative state paths within ui-sref, just like the relative \n * paths passed to `$state.go()`. You just need to be aware that the path is relative\n * to the state that the link lives in, in other words the state that loaded the \n * template containing the link.\n *\n * You can specify options to pass to {@link ui.router.state.$state#go $state.go()}\n * using the `ui-sref-opts` attribute. Options are restricted to `location`, `inherit`,\n * and `reload`.\n *\n * @example\n * Here's an example of how you'd use ui-sref and how it would compile. If you have the \n * following template:\n * \n * Home | About | Next page\n * \n *
\n * \n * \n * Then the compiled html would be (assuming Html5Mode is off and current state is contacts):\n * \n * Home | About | Next page\n * \n *
\n * - \n * Joe\n *
\n * - \n * Alice\n *
\n * - \n * Bob\n *
\n *
\n *\n * Home\n * \n *\n * @param {string} ui-sref 'stateName' can be any valid absolute or relative state\n * @param {Object} ui-sref-opts options to pass to {@link ui.router.state.$state#go $state.go()}\n */\n$StateRefDirective.$inject = ['$state', '$timeout'];\nfunction $StateRefDirective($state, $timeout) {\n var allowedOptions = ['location', 'inherit', 'reload', 'absolute'];\n\n return {\n restrict: 'A',\n require: ['?^uiSrefActive', '?^uiSrefActiveEq'],\n link: function(scope, element, attrs, uiSrefActive) {\n var ref = parseStateRef(attrs.uiSref, $state.current.name);\n var params = null, url = null, base = stateContext(element) || $state.$current;\n // SVGAElement does not use the href attribute, but rather the 'xlinkHref' attribute.\n var hrefKind = Object.prototype.toString.call(element.prop('href')) === '[object SVGAnimatedString]' ?\n 'xlink:href' : 'href';\n var newHref = null, isAnchor = element.prop(\"tagName\").toUpperCase() === \"A\";\n var isForm = element[0].nodeName === \"FORM\";\n var attr = isForm ? \"action\" : hrefKind, nav = true;\n\n var options = { relative: base, inherit: true };\n var optionsOverride = scope.$eval(attrs.uiSrefOpts) || {};\n\n angular.forEach(allowedOptions, function(option) {\n if (option in optionsOverride) {\n options[option] = optionsOverride[option];\n }\n });\n\n var update = function(newVal) {\n if (newVal) params = angular.copy(newVal);\n if (!nav) return;\n\n newHref = $state.href(ref.state, params, options);\n\n var activeDirective = uiSrefActive[1] || uiSrefActive[0];\n if (activeDirective) {\n activeDirective.$$addStateInfo(ref.state, params);\n }\n if (newHref === null) {\n nav = false;\n return false;\n }\n attrs.$set(attr, newHref);\n };\n\n if (ref.paramExpr) {\n scope.$watch(ref.paramExpr, function(newVal, oldVal) {\n if (newVal !== params) update(newVal);\n }, true);\n params = angular.copy(scope.$eval(ref.paramExpr));\n }\n update();\n\n if (isForm) return;\n\n element.bind(\"click\", function(e) {\n var button = e.which || e.button;\n if ( !(button > 1 || e.ctrlKey || e.metaKey || e.shiftKey || element.attr('target')) ) {\n // HACK: This is to allow ng-clicks to be processed before the transition is initiated:\n var transition = $timeout(function() {\n $state.go(ref.state, params, options);\n });\n e.preventDefault();\n\n // if the state has no URL, ignore one preventDefault from the directive.\n var ignorePreventDefaultCount = isAnchor && !newHref ? 1: 0;\n e.preventDefault = function() {\n if (ignorePreventDefaultCount-- <= 0)\n $timeout.cancel(transition);\n };\n }\n });\n }\n };\n}\n\n/**\n * @ngdoc directive\n * @name ui.router.state.directive:ui-sref-active\n *\n * @requires ui.router.state.$state\n * @requires ui.router.state.$stateParams\n * @requires $interpolate\n *\n * @restrict A\n *\n * @description\n * A directive working alongside ui-sref to add classes to an element when the\n * related ui-sref directive's state is active, and removing them when it is inactive.\n * The primary use-case is to simplify the special appearance of navigation menus\n * relying on `ui-sref`, by having the \"active\" state's menu button appear different,\n * distinguishing it from the inactive menu items.\n *\n * ui-sref-active can live on the same element as ui-sref or on a parent element. The first\n * ui-sref-active found at the same level or above the ui-sref will be used.\n *\n * Will activate when the ui-sref's target state or any child state is active. If you\n * need to activate only when the ui-sref target state is active and *not* any of\n * it's children, then you will use\n * {@link ui.router.state.directive:ui-sref-active-eq ui-sref-active-eq}\n *\n * @example\n * Given the following template:\n * \n *
\n * \n *\n *\n * When the app state is \"app.user\" (or any children states), and contains the state parameter \"user\" with value \"bilbobaggins\",\n * the resulting HTML will appear as (note the 'active' class):\n * \n *
\n * \n *\n * The class name is interpolated **once** during the directives link time (any further changes to the\n * interpolated value are ignored).\n *\n * Multiple classes may be specified in a space-separated format:\n * \n *
\n * \n */\n\n/**\n * @ngdoc directive\n * @name ui.router.state.directive:ui-sref-active-eq\n *\n * @requires ui.router.state.$state\n * @requires ui.router.state.$stateParams\n * @requires $interpolate\n *\n * @restrict A\n *\n * @description\n * The same as {@link ui.router.state.directive:ui-sref-active ui-sref-active} but will only activate\n * when the exact target state used in the `ui-sref` is active; no child states.\n *\n */\n$StateRefActiveDirective.$inject = ['$state', '$stateParams', '$interpolate'];\nfunction $StateRefActiveDirective($state, $stateParams, $interpolate) {\n return {\n restrict: \"A\",\n controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {\n var states = [], activeClass;\n\n // There probably isn't much point in $observing this\n // uiSrefActive and uiSrefActiveEq share the same directive object with some\n // slight difference in logic routing\n activeClass = $interpolate($attrs.uiSrefActiveEq || $attrs.uiSrefActive || '', false)($scope);\n\n // Allow uiSref to communicate with uiSrefActive[Equals]\n this.$$addStateInfo = function (newState, newParams) {\n var state = $state.get(newState, stateContext($element));\n\n states.push({\n state: state || { name: newState },\n params: newParams\n });\n\n update();\n };\n\n $scope.$on('$stateChangeSuccess', update);\n\n // Update route state\n function update() {\n if (anyMatch()) {\n $element.addClass(activeClass);\n } else {\n $element.removeClass(activeClass);\n }\n }\n\n function anyMatch() {\n for (var i = 0; i < states.length; i++) {\n if (isMatch(states[i].state, states[i].params)) {\n return true;\n }\n }\n return false;\n }\n\n function isMatch(state, params) {\n if (typeof $attrs.uiSrefActiveEq !== 'undefined') {\n return $state.is(state.name, params);\n } else {\n return $state.includes(state.name, params);\n }\n }\n }]\n };\n}\n\nangular.module('ui.router.state')\n .directive('uiSref', $StateRefDirective)\n .directive('uiSrefActive', $StateRefActiveDirective)\n .directive('uiSrefActiveEq', $StateRefActiveDirective);\n\n/**\n * @ngdoc filter\n * @name ui.router.state.filter:isState\n *\n * @requires ui.router.state.$state\n *\n * @description\n * Translates to {@link ui.router.state.$state#methods_is $state.is(\"stateName\")}.\n */\n$IsStateFilter.$inject = ['$state'];\nfunction $IsStateFilter($state) {\n var isFilter = function (state) {\n return $state.is(state);\n };\n isFilter.$stateful = true;\n return isFilter;\n}\n\n/**\n * @ngdoc filter\n * @name ui.router.state.filter:includedByState\n *\n * @requires ui.router.state.$state\n *\n * @description\n * Translates to {@link ui.router.state.$state#methods_includes $state.includes('fullOrPartialStateName')}.\n */\n$IncludedByStateFilter.$inject = ['$state'];\nfunction $IncludedByStateFilter($state) {\n var includesFilter = function (state) {\n return $state.includes(state);\n };\n includesFilter.$stateful = true;\n return includesFilter;\n}\n\nangular.module('ui.router.state')\n .filter('isState', $IsStateFilter)\n .filter('includedByState', $IncludedByStateFilter);\n})(window, window.angular);",
"//! moment.js\n//! version : 2.9.0\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\n(function (undefined) {\n /************************************\n Constants\n ************************************/\n\n var moment,\n VERSION = '2.9.0',\n // the global-scope this is NOT the global object in Node.js\n globalScope = (typeof global !== 'undefined' && (typeof window === 'undefined' || window === global.window)) ? global : this,\n oldGlobalMoment,\n round = Math.round,\n hasOwnProperty = Object.prototype.hasOwnProperty,\n i,\n\n YEAR = 0,\n MONTH = 1,\n DATE = 2,\n HOUR = 3,\n MINUTE = 4,\n SECOND = 5,\n MILLISECOND = 6,\n\n // internal storage for locale config files\n locales = {},\n\n // extra moment internal properties (plugins register props here)\n momentProperties = [],\n\n // check for nodeJS\n hasModule = (typeof module !== 'undefined' && module && module.exports),\n\n // ASP.NET json date format regex\n aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i,\n aspNetTimeSpanJsonRegex = /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/,\n\n // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,\n\n // format tokens\n formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g,\n localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g,\n\n // parsing token regexes\n parseTokenOneOrTwoDigits = /\\d\\d?/, // 0 - 99\n parseTokenOneToThreeDigits = /\\d{1,3}/, // 0 - 999\n parseTokenOneToFourDigits = /\\d{1,4}/, // 0 - 9999\n parseTokenOneToSixDigits = /[+\\-]?\\d{1,6}/, // -999,999 - 999,999\n parseTokenDigits = /\\d+/, // nonzero number of digits\n parseTokenWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.\n parseTokenTimezone = /Z|[\\+\\-]\\d\\d:?\\d\\d/gi, // +00:00 -00:00 +0000 -0000 or Z\n parseTokenT = /T/i, // T (ISO separator)\n parseTokenOffsetMs = /[\\+\\-]?\\d+/, // 1234567890123\n parseTokenTimestampMs = /[\\+\\-]?\\d+(\\.\\d{1,3})?/, // 123456789 123456789.123\n\n //strict parsing regexes\n parseTokenOneDigit = /\\d/, // 0 - 9\n parseTokenTwoDigits = /\\d\\d/, // 00 - 99\n parseTokenThreeDigits = /\\d{3}/, // 000 - 999\n parseTokenFourDigits = /\\d{4}/, // 0000 - 9999\n parseTokenSixDigits = /[+-]?\\d{6}/, // -999,999 - 999,999\n parseTokenSignedNumber = /[+-]?\\d+/, // -inf - inf\n\n // iso 8601 regex\n // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\n isoRegex = /^\\s*(?:[+-]\\d{6}|\\d{4})-(?:(\\d\\d-\\d\\d)|(W\\d\\d$)|(W\\d\\d-\\d)|(\\d\\d\\d))((T| )(\\d\\d(:\\d\\d(:\\d\\d(\\.\\d+)?)?)?)?([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/,\n\n isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',\n\n isoDates = [\n ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d{2}-\\d{2}/],\n ['YYYY-MM-DD', /\\d{4}-\\d{2}-\\d{2}/],\n ['GGGG-[W]WW-E', /\\d{4}-W\\d{2}-\\d/],\n ['GGGG-[W]WW', /\\d{4}-W\\d{2}/],\n ['YYYY-DDD', /\\d{4}-\\d{3}/]\n ],\n\n // iso time formats and regexes\n isoTimes = [\n ['HH:mm:ss.SSSS', /(T| )\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n ['HH:mm:ss', /(T| )\\d\\d:\\d\\d:\\d\\d/],\n ['HH:mm', /(T| )\\d\\d:\\d\\d/],\n ['HH', /(T| )\\d\\d/]\n ],\n\n // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-', '15', '30']\n parseTimezoneChunker = /([\\+\\-]|\\d\\d)/gi,\n\n // getter and setter names\n proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),\n unitMillisecondFactors = {\n 'Milliseconds' : 1,\n 'Seconds' : 1e3,\n 'Minutes' : 6e4,\n 'Hours' : 36e5,\n 'Days' : 864e5,\n 'Months' : 2592e6,\n 'Years' : 31536e6\n },\n\n unitAliases = {\n ms : 'millisecond',\n s : 'second',\n m : 'minute',\n h : 'hour',\n d : 'day',\n D : 'date',\n w : 'week',\n W : 'isoWeek',\n M : 'month',\n Q : 'quarter',\n y : 'year',\n DDD : 'dayOfYear',\n e : 'weekday',\n E : 'isoWeekday',\n gg: 'weekYear',\n GG: 'isoWeekYear'\n },\n\n camelFunctions = {\n dayofyear : 'dayOfYear',\n isoweekday : 'isoWeekday',\n isoweek : 'isoWeek',\n weekyear : 'weekYear',\n isoweekyear : 'isoWeekYear'\n },\n\n // format function strings\n formatFunctions = {},\n\n // default relative time thresholds\n relativeTimeThresholds = {\n s: 45, // seconds to minute\n m: 45, // minutes to hour\n h: 22, // hours to day\n d: 26, // days to month\n M: 11 // months to year\n },\n\n // tokens to ordinalize and pad\n ordinalizeTokens = 'DDD w W M D d'.split(' '),\n paddedTokens = 'M D H h m s w W'.split(' '),\n\n formatTokenFunctions = {\n M : function () {\n return this.month() + 1;\n },\n MMM : function (format) {\n return this.localeData().monthsShort(this, format);\n },\n MMMM : function (format) {\n return this.localeData().months(this, format);\n },\n D : function () {\n return this.date();\n },\n DDD : function () {\n return this.dayOfYear();\n },\n d : function () {\n return this.day();\n },\n dd : function (format) {\n return this.localeData().weekdaysMin(this, format);\n },\n ddd : function (format) {\n return this.localeData().weekdaysShort(this, format);\n },\n dddd : function (format) {\n return this.localeData().weekdays(this, format);\n },\n w : function () {\n return this.week();\n },\n W : function () {\n return this.isoWeek();\n },\n YY : function () {\n return leftZeroFill(this.year() % 100, 2);\n },\n YYYY : function () {\n return leftZeroFill(this.year(), 4);\n },\n YYYYY : function () {\n return leftZeroFill(this.year(), 5);\n },\n YYYYYY : function () {\n var y = this.year(), sign = y >= 0 ? '+' : '-';\n return sign + leftZeroFill(Math.abs(y), 6);\n },\n gg : function () {\n return leftZeroFill(this.weekYear() % 100, 2);\n },\n gggg : function () {\n return leftZeroFill(this.weekYear(), 4);\n },\n ggggg : function () {\n return leftZeroFill(this.weekYear(), 5);\n },\n GG : function () {\n return leftZeroFill(this.isoWeekYear() % 100, 2);\n },\n GGGG : function () {\n return leftZeroFill(this.isoWeekYear(), 4);\n },\n GGGGG : function () {\n return leftZeroFill(this.isoWeekYear(), 5);\n },\n e : function () {\n return this.weekday();\n },\n E : function () {\n return this.isoWeekday();\n },\n a : function () {\n return this.localeData().meridiem(this.hours(), this.minutes(), true);\n },\n A : function () {\n return this.localeData().meridiem(this.hours(), this.minutes(), false);\n },\n H : function () {\n return this.hours();\n },\n h : function () {\n return this.hours() % 12 || 12;\n },\n m : function () {\n return this.minutes();\n },\n s : function () {\n return this.seconds();\n },\n S : function () {\n return toInt(this.milliseconds() / 100);\n },\n SS : function () {\n return leftZeroFill(toInt(this.milliseconds() / 10), 2);\n },\n SSS : function () {\n return leftZeroFill(this.milliseconds(), 3);\n },\n SSSS : function () {\n return leftZeroFill(this.milliseconds(), 3);\n },\n Z : function () {\n var a = this.utcOffset(),\n b = '+';\n if (a < 0) {\n a = -a;\n b = '-';\n }\n return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);\n },\n ZZ : function () {\n var a = this.utcOffset(),\n b = '+';\n if (a < 0) {\n a = -a;\n b = '-';\n }\n return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);\n },\n z : function () {\n return this.zoneAbbr();\n },\n zz : function () {\n return this.zoneName();\n },\n x : function () {\n return this.valueOf();\n },\n X : function () {\n return this.unix();\n },\n Q : function () {\n return this.quarter();\n }\n },\n\n deprecations = {},\n\n lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'],\n\n updateInProgress = false;\n\n // Pick the first defined of two or three arguments. dfl comes from\n // default.\n function dfl(a, b, c) {\n switch (arguments.length) {\n case 2: return a != null ? a : b;\n case 3: return a != null ? a : b != null ? b : c;\n default: throw new Error('Implement me');\n }\n }\n\n function hasOwnProp(a, b) {\n return hasOwnProperty.call(a, b);\n }\n\n function defaultParsingFlags() {\n // We need to deep clone this object, and es5 standard is not very\n // helpful.\n return {\n empty : false,\n unusedTokens : [],\n unusedInput : [],\n overflow : -2,\n charsLeftOver : 0,\n nullInput : false,\n invalidMonth : null,\n invalidFormat : false,\n userInvalidated : false,\n iso: false\n };\n }\n\n function printMsg(msg) {\n if (moment.suppressDeprecationWarnings === false &&\n typeof console !== 'undefined' && console.warn) {\n console.warn('Deprecation warning: ' + msg);\n }\n }\n\n function deprecate(msg, fn) {\n var firstTime = true;\n return extend(function () {\n if (firstTime) {\n printMsg(msg);\n firstTime = false;\n }\n return fn.apply(this, arguments);\n }, fn);\n }\n\n function deprecateSimple(name, msg) {\n if (!deprecations[name]) {\n printMsg(msg);\n deprecations[name] = true;\n }\n }\n\n function padToken(func, count) {\n return function (a) {\n return leftZeroFill(func.call(this, a), count);\n };\n }\n function ordinalizeToken(func, period) {\n return function (a) {\n return this.localeData().ordinal(func.call(this, a), period);\n };\n }\n\n function monthDiff(a, b) {\n // difference in months\n var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n // b is in (anchor - 1 month, anchor + 1 month)\n anchor = a.clone().add(wholeMonthDiff, 'months'),\n anchor2, adjust;\n\n if (b - anchor < 0) {\n anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n // linear across the month\n adjust = (b - anchor) / (anchor - anchor2);\n } else {\n anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n // linear across the month\n adjust = (b - anchor) / (anchor2 - anchor);\n }\n\n return -(wholeMonthDiff + adjust);\n }\n\n while (ordinalizeTokens.length) {\n i = ordinalizeTokens.pop();\n formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);\n }\n while (paddedTokens.length) {\n i = paddedTokens.pop();\n formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);\n }\n formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);\n\n\n function meridiemFixWrap(locale, hour, meridiem) {\n var isPm;\n\n if (meridiem == null) {\n // nothing to do\n return hour;\n }\n if (locale.meridiemHour != null) {\n return locale.meridiemHour(hour, meridiem);\n } else if (locale.isPM != null) {\n // Fallback\n isPm = locale.isPM(meridiem);\n if (isPm && hour < 12) {\n hour += 12;\n }\n if (!isPm && hour === 12) {\n hour = 0;\n }\n return hour;\n } else {\n // thie is not supposed to happen\n return hour;\n }\n }\n\n /************************************\n Constructors\n ************************************/\n\n function Locale() {\n }\n\n // Moment prototype object\n function Moment(config, skipOverflow) {\n if (skipOverflow !== false) {\n checkOverflow(config);\n }\n copyConfig(this, config);\n this._d = new Date(+config._d);\n // Prevent infinite loop in case updateOffset creates new moment\n // objects.\n if (updateInProgress === false) {\n updateInProgress = true;\n moment.updateOffset(this);\n updateInProgress = false;\n }\n }\n\n // Duration Constructor\n function Duration(duration) {\n var normalizedInput = normalizeObjectUnits(duration),\n years = normalizedInput.year || 0,\n quarters = normalizedInput.quarter || 0,\n months = normalizedInput.month || 0,\n weeks = normalizedInput.week || 0,\n days = normalizedInput.day || 0,\n hours = normalizedInput.hour || 0,\n minutes = normalizedInput.minute || 0,\n seconds = normalizedInput.second || 0,\n milliseconds = normalizedInput.millisecond || 0;\n\n // representation for dateAddRemove\n this._milliseconds = +milliseconds +\n seconds * 1e3 + // 1000\n minutes * 6e4 + // 1000 * 60\n hours * 36e5; // 1000 * 60 * 60\n // Because of dateAddRemove treats 24 hours as different from a\n // day when working around DST, we need to store them separately\n this._days = +days +\n weeks * 7;\n // It is impossible translate months into days without knowing\n // which months you are are talking about, so we have to store\n // it separately.\n this._months = +months +\n quarters * 3 +\n years * 12;\n\n this._data = {};\n\n this._locale = moment.localeData();\n\n this._bubble();\n }\n\n /************************************\n Helpers\n ************************************/\n\n\n function extend(a, b) {\n for (var i in b) {\n if (hasOwnProp(b, i)) {\n a[i] = b[i];\n }\n }\n\n if (hasOwnProp(b, 'toString')) {\n a.toString = b.toString;\n }\n\n if (hasOwnProp(b, 'valueOf')) {\n a.valueOf = b.valueOf;\n }\n\n return a;\n }\n\n function copyConfig(to, from) {\n var i, prop, val;\n\n if (typeof from._isAMomentObject !== 'undefined') {\n to._isAMomentObject = from._isAMomentObject;\n }\n if (typeof from._i !== 'undefined') {\n to._i = from._i;\n }\n if (typeof from._f !== 'undefined') {\n to._f = from._f;\n }\n if (typeof from._l !== 'undefined') {\n to._l = from._l;\n }\n if (typeof from._strict !== 'undefined') {\n to._strict = from._strict;\n }\n if (typeof from._tzm !== 'undefined') {\n to._tzm = from._tzm;\n }\n if (typeof from._isUTC !== 'undefined') {\n to._isUTC = from._isUTC;\n }\n if (typeof from._offset !== 'undefined') {\n to._offset = from._offset;\n }\n if (typeof from._pf !== 'undefined') {\n to._pf = from._pf;\n }\n if (typeof from._locale !== 'undefined') {\n to._locale = from._locale;\n }\n\n if (momentProperties.length > 0) {\n for (i in momentProperties) {\n prop = momentProperties[i];\n val = from[prop];\n if (typeof val !== 'undefined') {\n to[prop] = val;\n }\n }\n }\n\n return to;\n }\n\n function absRound(number) {\n if (number < 0) {\n return Math.ceil(number);\n } else {\n return Math.floor(number);\n }\n }\n\n // left zero fill a number\n // see http://jsperf.com/left-zero-filling for performance comparison\n function leftZeroFill(number, targetLength, forceSign) {\n var output = '' + Math.abs(number),\n sign = number >= 0;\n\n while (output.length < targetLength) {\n output = '0' + output;\n }\n return (sign ? (forceSign ? '+' : '') : '-') + output;\n }\n\n function positiveMomentsDifference(base, other) {\n var res = {milliseconds: 0, months: 0};\n\n res.months = other.month() - base.month() +\n (other.year() - base.year()) * 12;\n if (base.clone().add(res.months, 'M').isAfter(other)) {\n --res.months;\n }\n\n res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n return res;\n }\n\n function momentsDifference(base, other) {\n var res;\n other = makeAs(other, base);\n if (base.isBefore(other)) {\n res = positiveMomentsDifference(base, other);\n } else {\n res = positiveMomentsDifference(other, base);\n res.milliseconds = -res.milliseconds;\n res.months = -res.months;\n }\n\n return res;\n }\n\n // TODO: remove 'name' arg after deprecation is removed\n function createAdder(direction, name) {\n return function (val, period) {\n var dur, tmp;\n //invert the arguments, but complain about it\n if (period !== null && !isNaN(+period)) {\n deprecateSimple(name, 'moment().' + name + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');\n tmp = val; val = period; period = tmp;\n }\n\n val = typeof val === 'string' ? +val : val;\n dur = moment.duration(val, period);\n addOrSubtractDurationFromMoment(this, dur, direction);\n return this;\n };\n }\n\n function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {\n var milliseconds = duration._milliseconds,\n days = duration._days,\n months = duration._months;\n updateOffset = updateOffset == null ? true : updateOffset;\n\n if (milliseconds) {\n mom._d.setTime(+mom._d + milliseconds * isAdding);\n }\n if (days) {\n rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);\n }\n if (months) {\n rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);\n }\n if (updateOffset) {\n moment.updateOffset(mom, days || months);\n }\n }\n\n // check if is an array\n function isArray(input) {\n return Object.prototype.toString.call(input) === '[object Array]';\n }\n\n function isDate(input) {\n return Object.prototype.toString.call(input) === '[object Date]' ||\n input instanceof Date;\n }\n\n // compare two arrays, return the number of differences\n function compareArrays(array1, array2, dontConvert) {\n var len = Math.min(array1.length, array2.length),\n lengthDiff = Math.abs(array1.length - array2.length),\n diffs = 0,\n i;\n for (i = 0; i < len; i++) {\n if ((dontConvert && array1[i] !== array2[i]) ||\n (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n diffs++;\n }\n }\n return diffs + lengthDiff;\n }\n\n function normalizeUnits(units) {\n if (units) {\n var lowered = units.toLowerCase().replace(/(.)s$/, '$1');\n units = unitAliases[units] || camelFunctions[lowered] || lowered;\n }\n return units;\n }\n\n function normalizeObjectUnits(inputObject) {\n var normalizedInput = {},\n normalizedProp,\n prop;\n\n for (prop in inputObject) {\n if (hasOwnProp(inputObject, prop)) {\n normalizedProp = normalizeUnits(prop);\n if (normalizedProp) {\n normalizedInput[normalizedProp] = inputObject[prop];\n }\n }\n }\n\n return normalizedInput;\n }\n\n function makeList(field) {\n var count, setter;\n\n if (field.indexOf('week') === 0) {\n count = 7;\n setter = 'day';\n }\n else if (field.indexOf('month') === 0) {\n count = 12;\n setter = 'month';\n }\n else {\n return;\n }\n\n moment[field] = function (format, index) {\n var i, getter,\n method = moment._locale[field],\n results = [];\n\n if (typeof format === 'number') {\n index = format;\n format = undefined;\n }\n\n getter = function (i) {\n var m = moment().utc().set(setter, i);\n return method.call(moment._locale, m, format || '');\n };\n\n if (index != null) {\n return getter(index);\n }\n else {\n for (i = 0; i < count; i++) {\n results.push(getter(i));\n }\n return results;\n }\n };\n }\n\n function toInt(argumentForCoercion) {\n var coercedNumber = +argumentForCoercion,\n value = 0;\n\n if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n if (coercedNumber >= 0) {\n value = Math.floor(coercedNumber);\n } else {\n value = Math.ceil(coercedNumber);\n }\n }\n\n return value;\n }\n\n function daysInMonth(year, month) {\n return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n }\n\n function weeksInYear(year, dow, doy) {\n return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week;\n }\n\n function daysInYear(year) {\n return isLeapYear(year) ? 366 : 365;\n }\n\n function isLeapYear(year) {\n return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n }\n\n function checkOverflow(m) {\n var overflow;\n if (m._a && m._pf.overflow === -2) {\n overflow =\n m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :\n m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :\n m._a[HOUR] < 0 || m._a[HOUR] > 24 ||\n (m._a[HOUR] === 24 && (m._a[MINUTE] !== 0 ||\n m._a[SECOND] !== 0 ||\n m._a[MILLISECOND] !== 0)) ? HOUR :\n m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :\n m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :\n m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :\n -1;\n\n if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n overflow = DATE;\n }\n\n m._pf.overflow = overflow;\n }\n }\n\n function isValid(m) {\n if (m._isValid == null) {\n m._isValid = !isNaN(m._d.getTime()) &&\n m._pf.overflow < 0 &&\n !m._pf.empty &&\n !m._pf.invalidMonth &&\n !m._pf.nullInput &&\n !m._pf.invalidFormat &&\n !m._pf.userInvalidated;\n\n if (m._strict) {\n m._isValid = m._isValid &&\n m._pf.charsLeftOver === 0 &&\n m._pf.unusedTokens.length === 0 &&\n m._pf.bigHour === undefined;\n }\n }\n return m._isValid;\n }\n\n function normalizeLocale(key) {\n return key ? key.toLowerCase().replace('_', '-') : key;\n }\n\n // pick the locale from the array\n // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n function chooseLocale(names) {\n var i = 0, j, next, locale, split;\n\n while (i < names.length) {\n split = normalizeLocale(names[i]).split('-');\n j = split.length;\n next = normalizeLocale(names[i + 1]);\n next = next ? next.split('-') : null;\n while (j > 0) {\n locale = loadLocale(split.slice(0, j).join('-'));\n if (locale) {\n return locale;\n }\n if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n //the next array item is better than a shallower substring of this one\n break;\n }\n j--;\n }\n i++;\n }\n return null;\n }\n\n function loadLocale(name) {\n var oldLocale = null;\n if (!locales[name] && hasModule) {\n try {\n oldLocale = moment.locale();\n require('./locale/' + name);\n // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales\n moment.locale(oldLocale);\n } catch (e) { }\n }\n return locales[name];\n }\n\n // Return a moment from input, that is local/utc/utcOffset equivalent to\n // model.\n function makeAs(input, model) {\n var res, diff;\n if (model._isUTC) {\n res = model.clone();\n diff = (moment.isMoment(input) || isDate(input) ?\n +input : +moment(input)) - (+res);\n // Use low-level api, because this fn is low-level api.\n res._d.setTime(+res._d + diff);\n moment.updateOffset(res, false);\n return res;\n } else {\n return moment(input).local();\n }\n }\n\n /************************************\n Locale\n ************************************/\n\n\n extend(Locale.prototype, {\n\n set : function (config) {\n var prop, i;\n for (i in config) {\n prop = config[i];\n if (typeof prop === 'function') {\n this[i] = prop;\n } else {\n this['_' + i] = prop;\n }\n }\n // Lenient ordinal parsing accepts just a number in addition to\n // number + (possibly) stuff coming from _ordinalParseLenient.\n this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\\d{1,2}/.source);\n },\n\n _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n months : function (m) {\n return this._months[m.month()];\n },\n\n _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n monthsShort : function (m) {\n return this._monthsShort[m.month()];\n },\n\n monthsParse : function (monthName, format, strict) {\n var i, mom, regex;\n\n if (!this._monthsParse) {\n this._monthsParse = [];\n this._longMonthsParse = [];\n this._shortMonthsParse = [];\n }\n\n for (i = 0; i < 12; i++) {\n // make the regex if we don't have it already\n mom = moment.utc([2000, i]);\n if (strict && !this._longMonthsParse[i]) {\n this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n }\n if (!strict && !this._monthsParse[i]) {\n regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n }\n // test the regex\n if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n return i;\n } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n return i;\n } else if (!strict && this._monthsParse[i].test(monthName)) {\n return i;\n }\n }\n },\n\n _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n weekdays : function (m) {\n return this._weekdays[m.day()];\n },\n\n _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n weekdaysShort : function (m) {\n return this._weekdaysShort[m.day()];\n },\n\n _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n weekdaysMin : function (m) {\n return this._weekdaysMin[m.day()];\n },\n\n weekdaysParse : function (weekdayName) {\n var i, mom, regex;\n\n if (!this._weekdaysParse) {\n this._weekdaysParse = [];\n }\n\n for (i = 0; i < 7; i++) {\n // make the regex if we don't have it already\n if (!this._weekdaysParse[i]) {\n mom = moment([2000, 1]).day(i);\n regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n }\n // test the regex\n if (this._weekdaysParse[i].test(weekdayName)) {\n return i;\n }\n }\n },\n\n _longDateFormat : {\n LTS : 'h:mm:ss A',\n LT : 'h:mm A',\n L : 'MM/DD/YYYY',\n LL : 'MMMM D, YYYY',\n LLL : 'MMMM D, YYYY LT',\n LLLL : 'dddd, MMMM D, YYYY LT'\n },\n longDateFormat : function (key) {\n var output = this._longDateFormat[key];\n if (!output && this._longDateFormat[key.toUpperCase()]) {\n output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {\n return val.slice(1);\n });\n this._longDateFormat[key] = output;\n }\n return output;\n },\n\n isPM : function (input) {\n // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n // Using charAt should be more compatible.\n return ((input + '').toLowerCase().charAt(0) === 'p');\n },\n\n _meridiemParse : /[ap]\\.?m?\\.?/i,\n meridiem : function (hours, minutes, isLower) {\n if (hours > 11) {\n return isLower ? 'pm' : 'PM';\n } else {\n return isLower ? 'am' : 'AM';\n }\n },\n\n\n _calendar : {\n sameDay : '[Today at] LT',\n nextDay : '[Tomorrow at] LT',\n nextWeek : 'dddd [at] LT',\n lastDay : '[Yesterday at] LT',\n lastWeek : '[Last] dddd [at] LT',\n sameElse : 'L'\n },\n calendar : function (key, mom, now) {\n var output = this._calendar[key];\n return typeof output === 'function' ? output.apply(mom, [now]) : output;\n },\n\n _relativeTime : {\n future : 'in %s',\n past : '%s ago',\n s : 'a few seconds',\n m : 'a minute',\n mm : '%d minutes',\n h : 'an hour',\n hh : '%d hours',\n d : 'a day',\n dd : '%d days',\n M : 'a month',\n MM : '%d months',\n y : 'a year',\n yy : '%d years'\n },\n\n relativeTime : function (number, withoutSuffix, string, isFuture) {\n var output = this._relativeTime[string];\n return (typeof output === 'function') ?\n output(number, withoutSuffix, string, isFuture) :\n output.replace(/%d/i, number);\n },\n\n pastFuture : function (diff, output) {\n var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);\n },\n\n ordinal : function (number) {\n return this._ordinal.replace('%d', number);\n },\n _ordinal : '%d',\n _ordinalParse : /\\d{1,2}/,\n\n preparse : function (string) {\n return string;\n },\n\n postformat : function (string) {\n return string;\n },\n\n week : function (mom) {\n return weekOfYear(mom, this._week.dow, this._week.doy).week;\n },\n\n _week : {\n dow : 0, // Sunday is the first day of the week.\n doy : 6 // The week that contains Jan 1st is the first week of the year.\n },\n\n firstDayOfWeek : function () {\n return this._week.dow;\n },\n\n firstDayOfYear : function () {\n return this._week.doy;\n },\n\n _invalidDate: 'Invalid date',\n invalidDate: function () {\n return this._invalidDate;\n }\n });\n\n /************************************\n Formatting\n ************************************/\n\n\n function removeFormattingTokens(input) {\n if (input.match(/\\[[\\s\\S]/)) {\n return input.replace(/^\\[|\\]$/g, '');\n }\n return input.replace(/\\\\/g, '');\n }\n\n function makeFormatFunction(format) {\n var array = format.match(formattingTokens), i, length;\n\n for (i = 0, length = array.length; i < length; i++) {\n if (formatTokenFunctions[array[i]]) {\n array[i] = formatTokenFunctions[array[i]];\n } else {\n array[i] = removeFormattingTokens(array[i]);\n }\n }\n\n return function (mom) {\n var output = '';\n for (i = 0; i < length; i++) {\n output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];\n }\n return output;\n };\n }\n\n // format date using native date object\n function formatMoment(m, format) {\n if (!m.isValid()) {\n return m.localeData().invalidDate();\n }\n\n format = expandFormat(format, m.localeData());\n\n if (!formatFunctions[format]) {\n formatFunctions[format] = makeFormatFunction(format);\n }\n\n return formatFunctions[format](m);\n }\n\n function expandFormat(format, locale) {\n var i = 5;\n\n function replaceLongDateFormatTokens(input) {\n return locale.longDateFormat(input) || input;\n }\n\n localFormattingTokens.lastIndex = 0;\n while (i >= 0 && localFormattingTokens.test(format)) {\n format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n localFormattingTokens.lastIndex = 0;\n i -= 1;\n }\n\n return format;\n }\n\n\n /************************************\n Parsing\n ************************************/\n\n\n // get the regex to find the next token\n function getParseRegexForToken(token, config) {\n var a, strict = config._strict;\n switch (token) {\n case 'Q':\n return parseTokenOneDigit;\n case 'DDDD':\n return parseTokenThreeDigits;\n case 'YYYY':\n case 'GGGG':\n case 'gggg':\n return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;\n case 'Y':\n case 'G':\n case 'g':\n return parseTokenSignedNumber;\n case 'YYYYYY':\n case 'YYYYY':\n case 'GGGGG':\n case 'ggggg':\n return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;\n case 'S':\n if (strict) {\n return parseTokenOneDigit;\n }\n /* falls through */\n case 'SS':\n if (strict) {\n return parseTokenTwoDigits;\n }\n /* falls through */\n case 'SSS':\n if (strict) {\n return parseTokenThreeDigits;\n }\n /* falls through */\n case 'DDD':\n return parseTokenOneToThreeDigits;\n case 'MMM':\n case 'MMMM':\n case 'dd':\n case 'ddd':\n case 'dddd':\n return parseTokenWord;\n case 'a':\n case 'A':\n return config._locale._meridiemParse;\n case 'x':\n return parseTokenOffsetMs;\n case 'X':\n return parseTokenTimestampMs;\n case 'Z':\n case 'ZZ':\n return parseTokenTimezone;\n case 'T':\n return parseTokenT;\n case 'SSSS':\n return parseTokenDigits;\n case 'MM':\n case 'DD':\n case 'YY':\n case 'GG':\n case 'gg':\n case 'HH':\n case 'hh':\n case 'mm':\n case 'ss':\n case 'ww':\n case 'WW':\n return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;\n case 'M':\n case 'D':\n case 'd':\n case 'H':\n case 'h':\n case 'm':\n case 's':\n case 'w':\n case 'W':\n case 'e':\n case 'E':\n return parseTokenOneOrTwoDigits;\n case 'Do':\n return strict ? config._locale._ordinalParse : config._locale._ordinalParseLenient;\n default :\n a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\\\', '')), 'i'));\n return a;\n }\n }\n\n function utcOffsetFromString(string) {\n string = string || '';\n var possibleTzMatches = (string.match(parseTokenTimezone) || []),\n tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],\n parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],\n minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n return parts[0] === '+' ? minutes : -minutes;\n }\n\n // function to convert string input to date\n function addTimeToArrayFromToken(token, input, config) {\n var a, datePartArray = config._a;\n\n switch (token) {\n // QUARTER\n case 'Q':\n if (input != null) {\n datePartArray[MONTH] = (toInt(input) - 1) * 3;\n }\n break;\n // MONTH\n case 'M' : // fall through to MM\n case 'MM' :\n if (input != null) {\n datePartArray[MONTH] = toInt(input) - 1;\n }\n break;\n case 'MMM' : // fall through to MMMM\n case 'MMMM' :\n a = config._locale.monthsParse(input, token, config._strict);\n // if we didn't find a month name, mark the date as invalid.\n if (a != null) {\n datePartArray[MONTH] = a;\n } else {\n config._pf.invalidMonth = input;\n }\n break;\n // DAY OF MONTH\n case 'D' : // fall through to DD\n case 'DD' :\n if (input != null) {\n datePartArray[DATE] = toInt(input);\n }\n break;\n case 'Do' :\n if (input != null) {\n datePartArray[DATE] = toInt(parseInt(\n input.match(/\\d{1,2}/)[0], 10));\n }\n break;\n // DAY OF YEAR\n case 'DDD' : // fall through to DDDD\n case 'DDDD' :\n if (input != null) {\n config._dayOfYear = toInt(input);\n }\n\n break;\n // YEAR\n case 'YY' :\n datePartArray[YEAR] = moment.parseTwoDigitYear(input);\n break;\n case 'YYYY' :\n case 'YYYYY' :\n case 'YYYYYY' :\n datePartArray[YEAR] = toInt(input);\n break;\n // AM / PM\n case 'a' : // fall through to A\n case 'A' :\n config._meridiem = input;\n // config._isPm = config._locale.isPM(input);\n break;\n // HOUR\n case 'h' : // fall through to hh\n case 'hh' :\n config._pf.bigHour = true;\n /* falls through */\n case 'H' : // fall through to HH\n case 'HH' :\n datePartArray[HOUR] = toInt(input);\n break;\n // MINUTE\n case 'm' : // fall through to mm\n case 'mm' :\n datePartArray[MINUTE] = toInt(input);\n break;\n // SECOND\n case 's' : // fall through to ss\n case 'ss' :\n datePartArray[SECOND] = toInt(input);\n break;\n // MILLISECOND\n case 'S' :\n case 'SS' :\n case 'SSS' :\n case 'SSSS' :\n datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);\n break;\n // UNIX OFFSET (MILLISECONDS)\n case 'x':\n config._d = new Date(toInt(input));\n break;\n // UNIX TIMESTAMP WITH MS\n case 'X':\n config._d = new Date(parseFloat(input) * 1000);\n break;\n // TIMEZONE\n case 'Z' : // fall through to ZZ\n case 'ZZ' :\n config._useUTC = true;\n config._tzm = utcOffsetFromString(input);\n break;\n // WEEKDAY - human\n case 'dd':\n case 'ddd':\n case 'dddd':\n a = config._locale.weekdaysParse(input);\n // if we didn't get a weekday name, mark the date as invalid\n if (a != null) {\n config._w = config._w || {};\n config._w['d'] = a;\n } else {\n config._pf.invalidWeekday = input;\n }\n break;\n // WEEK, WEEK DAY - numeric\n case 'w':\n case 'ww':\n case 'W':\n case 'WW':\n case 'd':\n case 'e':\n case 'E':\n token = token.substr(0, 1);\n /* falls through */\n case 'gggg':\n case 'GGGG':\n case 'GGGGG':\n token = token.substr(0, 2);\n if (input) {\n config._w = config._w || {};\n config._w[token] = toInt(input);\n }\n break;\n case 'gg':\n case 'GG':\n config._w = config._w || {};\n config._w[token] = moment.parseTwoDigitYear(input);\n }\n }\n\n function dayOfYearFromWeekInfo(config) {\n var w, weekYear, week, weekday, dow, doy, temp;\n\n w = config._w;\n if (w.GG != null || w.W != null || w.E != null) {\n dow = 1;\n doy = 4;\n\n // TODO: We need to take the current isoWeekYear, but that depends on\n // how we interpret now (local, utc, fixed offset). So create\n // a now version of current config (take local/utc/offset flags, and\n // create now).\n weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year);\n week = dfl(w.W, 1);\n weekday = dfl(w.E, 1);\n } else {\n dow = config._locale._week.dow;\n doy = config._locale._week.doy;\n\n weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);\n week = dfl(w.w, 1);\n\n if (w.d != null) {\n // weekday -- low day numbers are considered next week\n weekday = w.d;\n if (weekday < dow) {\n ++week;\n }\n } else if (w.e != null) {\n // local weekday -- counting starts from begining of week\n weekday = w.e + dow;\n } else {\n // default to begining of week\n weekday = dow;\n }\n }\n temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);\n\n config._a[YEAR] = temp.year;\n config._dayOfYear = temp.dayOfYear;\n }\n\n // convert an array to a date.\n // the array should mirror the parameters below\n // note: all values past the year are optional and will default to the lowest possible value.\n // [year, month, day , hour, minute, second, millisecond]\n function dateFromConfig(config) {\n var i, date, input = [], currentDate, yearToUse;\n\n if (config._d) {\n return;\n }\n\n currentDate = currentDateArray(config);\n\n //compute day of the year from weeks and weekdays\n if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n dayOfYearFromWeekInfo(config);\n }\n\n //if the day of the year is set, figure out what it is\n if (config._dayOfYear) {\n yearToUse = dfl(config._a[YEAR], currentDate[YEAR]);\n\n if (config._dayOfYear > daysInYear(yearToUse)) {\n config._pf._overflowDayOfYear = true;\n }\n\n date = makeUTCDate(yearToUse, 0, config._dayOfYear);\n config._a[MONTH] = date.getUTCMonth();\n config._a[DATE] = date.getUTCDate();\n }\n\n // Default to current date.\n // * if no year, month, day of month are given, default to today\n // * if day of month is given, default month and year\n // * if month is given, default only year\n // * if year is given, don't default anything\n for (i = 0; i < 3 && config._a[i] == null; ++i) {\n config._a[i] = input[i] = currentDate[i];\n }\n\n // Zero out whatever was not defaulted, including time\n for (; i < 7; i++) {\n config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n }\n\n // Check for 24:00:00.000\n if (config._a[HOUR] === 24 &&\n config._a[MINUTE] === 0 &&\n config._a[SECOND] === 0 &&\n config._a[MILLISECOND] === 0) {\n config._nextDay = true;\n config._a[HOUR] = 0;\n }\n\n config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);\n // Apply timezone offset from input. The actual utcOffset can be changed\n // with parseZone.\n if (config._tzm != null) {\n config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n }\n\n if (config._nextDay) {\n config._a[HOUR] = 24;\n }\n }\n\n function dateFromObject(config) {\n var normalizedInput;\n\n if (config._d) {\n return;\n }\n\n normalizedInput = normalizeObjectUnits(config._i);\n config._a = [\n normalizedInput.year,\n normalizedInput.month,\n normalizedInput.day || normalizedInput.date,\n normalizedInput.hour,\n normalizedInput.minute,\n normalizedInput.second,\n normalizedInput.millisecond\n ];\n\n dateFromConfig(config);\n }\n\n function currentDateArray(config) {\n var now = new Date();\n if (config._useUTC) {\n return [\n now.getUTCFullYear(),\n now.getUTCMonth(),\n now.getUTCDate()\n ];\n } else {\n return [now.getFullYear(), now.getMonth(), now.getDate()];\n }\n }\n\n // date from string and format string\n function makeDateFromStringAndFormat(config) {\n if (config._f === moment.ISO_8601) {\n parseISO(config);\n return;\n }\n\n config._a = [];\n config._pf.empty = true;\n\n // This array is used to make a Date, either with `new Date` or `Date.UTC`\n var string = '' + config._i,\n i, parsedInput, tokens, token, skipped,\n stringLength = string.length,\n totalParsedInputLength = 0;\n\n tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n for (i = 0; i < tokens.length; i++) {\n token = tokens[i];\n parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n if (parsedInput) {\n skipped = string.substr(0, string.indexOf(parsedInput));\n if (skipped.length > 0) {\n config._pf.unusedInput.push(skipped);\n }\n string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n totalParsedInputLength += parsedInput.length;\n }\n // don't parse if it's not a known token\n if (formatTokenFunctions[token]) {\n if (parsedInput) {\n config._pf.empty = false;\n }\n else {\n config._pf.unusedTokens.push(token);\n }\n addTimeToArrayFromToken(token, parsedInput, config);\n }\n else if (config._strict && !parsedInput) {\n config._pf.unusedTokens.push(token);\n }\n }\n\n // add remaining unparsed input length to the string\n config._pf.charsLeftOver = stringLength - totalParsedInputLength;\n if (string.length > 0) {\n config._pf.unusedInput.push(string);\n }\n\n // clear _12h flag if hour is <= 12\n if (config._pf.bigHour === true && config._a[HOUR] <= 12) {\n config._pf.bigHour = undefined;\n }\n // handle meridiem\n config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR],\n config._meridiem);\n dateFromConfig(config);\n checkOverflow(config);\n }\n\n function unescapeFormat(s) {\n return s.replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n return p1 || p2 || p3 || p4;\n });\n }\n\n // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n function regexpEscape(s) {\n return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n }\n\n // date from string and array of format strings\n function makeDateFromStringAndArray(config) {\n var tempConfig,\n bestMoment,\n\n scoreToBeat,\n i,\n currentScore;\n\n if (config._f.length === 0) {\n config._pf.invalidFormat = true;\n config._d = new Date(NaN);\n return;\n }\n\n for (i = 0; i < config._f.length; i++) {\n currentScore = 0;\n tempConfig = copyConfig({}, config);\n if (config._useUTC != null) {\n tempConfig._useUTC = config._useUTC;\n }\n tempConfig._pf = defaultParsingFlags();\n tempConfig._f = config._f[i];\n makeDateFromStringAndFormat(tempConfig);\n\n if (!isValid(tempConfig)) {\n continue;\n }\n\n // if there is any input that was not parsed add a penalty for that format\n currentScore += tempConfig._pf.charsLeftOver;\n\n //or tokens\n currentScore += tempConfig._pf.unusedTokens.length * 10;\n\n tempConfig._pf.score = currentScore;\n\n if (scoreToBeat == null || currentScore < scoreToBeat) {\n scoreToBeat = currentScore;\n bestMoment = tempConfig;\n }\n }\n\n extend(config, bestMoment || tempConfig);\n }\n\n // date from iso format\n function parseISO(config) {\n var i, l,\n string = config._i,\n match = isoRegex.exec(string);\n\n if (match) {\n config._pf.iso = true;\n for (i = 0, l = isoDates.length; i < l; i++) {\n if (isoDates[i][1].exec(string)) {\n // match[5] should be 'T' or undefined\n config._f = isoDates[i][0] + (match[6] || ' ');\n break;\n }\n }\n for (i = 0, l = isoTimes.length; i < l; i++) {\n if (isoTimes[i][1].exec(string)) {\n config._f += isoTimes[i][0];\n break;\n }\n }\n if (string.match(parseTokenTimezone)) {\n config._f += 'Z';\n }\n makeDateFromStringAndFormat(config);\n } else {\n config._isValid = false;\n }\n }\n\n // date from iso format or fallback\n function makeDateFromString(config) {\n parseISO(config);\n if (config._isValid === false) {\n delete config._isValid;\n moment.createFromInputFallback(config);\n }\n }\n\n function map(arr, fn) {\n var res = [], i;\n for (i = 0; i < arr.length; ++i) {\n res.push(fn(arr[i], i));\n }\n return res;\n }\n\n function makeDateFromInput(config) {\n var input = config._i, matched;\n if (input === undefined) {\n config._d = new Date();\n } else if (isDate(input)) {\n config._d = new Date(+input);\n } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {\n config._d = new Date(+matched[1]);\n } else if (typeof input === 'string') {\n makeDateFromString(config);\n } else if (isArray(input)) {\n config._a = map(input.slice(0), function (obj) {\n return parseInt(obj, 10);\n });\n dateFromConfig(config);\n } else if (typeof(input) === 'object') {\n dateFromObject(config);\n } else if (typeof(input) === 'number') {\n // from milliseconds\n config._d = new Date(input);\n } else {\n moment.createFromInputFallback(config);\n }\n }\n\n function makeDate(y, m, d, h, M, s, ms) {\n //can't just apply() to create a date:\n //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply\n var date = new Date(y, m, d, h, M, s, ms);\n\n //the date constructor doesn't accept years < 1970\n if (y < 1970) {\n date.setFullYear(y);\n }\n return date;\n }\n\n function makeUTCDate(y) {\n var date = new Date(Date.UTC.apply(null, arguments));\n if (y < 1970) {\n date.setUTCFullYear(y);\n }\n return date;\n }\n\n function parseWeekday(input, locale) {\n if (typeof input === 'string') {\n if (!isNaN(input)) {\n input = parseInt(input, 10);\n }\n else {\n input = locale.weekdaysParse(input);\n if (typeof input !== 'number') {\n return null;\n }\n }\n }\n return input;\n }\n\n /************************************\n Relative Time\n ************************************/\n\n\n // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n }\n\n function relativeTime(posNegDuration, withoutSuffix, locale) {\n var duration = moment.duration(posNegDuration).abs(),\n seconds = round(duration.as('s')),\n minutes = round(duration.as('m')),\n hours = round(duration.as('h')),\n days = round(duration.as('d')),\n months = round(duration.as('M')),\n years = round(duration.as('y')),\n\n args = seconds < relativeTimeThresholds.s && ['s', seconds] ||\n minutes === 1 && ['m'] ||\n minutes < relativeTimeThresholds.m && ['mm', minutes] ||\n hours === 1 && ['h'] ||\n hours < relativeTimeThresholds.h && ['hh', hours] ||\n days === 1 && ['d'] ||\n days < relativeTimeThresholds.d && ['dd', days] ||\n months === 1 && ['M'] ||\n months < relativeTimeThresholds.M && ['MM', months] ||\n years === 1 && ['y'] || ['yy', years];\n\n args[2] = withoutSuffix;\n args[3] = +posNegDuration > 0;\n args[4] = locale;\n return substituteTimeAgo.apply({}, args);\n }\n\n\n /************************************\n Week of Year\n ************************************/\n\n\n // firstDayOfWeek 0 = sun, 6 = sat\n // the day of the week that starts the week\n // (usually sunday or monday)\n // firstDayOfWeekOfYear 0 = sun, 6 = sat\n // the first week is the week that contains the first\n // of this day of the week\n // (eg. ISO weeks use thursday (4))\n function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {\n var end = firstDayOfWeekOfYear - firstDayOfWeek,\n daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),\n adjustedMoment;\n\n\n if (daysToDayOfWeek > end) {\n daysToDayOfWeek -= 7;\n }\n\n if (daysToDayOfWeek < end - 7) {\n daysToDayOfWeek += 7;\n }\n\n adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');\n return {\n week: Math.ceil(adjustedMoment.dayOfYear() / 7),\n year: adjustedMoment.year()\n };\n }\n\n //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {\n var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear;\n\n d = d === 0 ? 7 : d;\n weekday = weekday != null ? weekday : firstDayOfWeek;\n daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);\n dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;\n\n return {\n year: dayOfYear > 0 ? year : year - 1,\n dayOfYear: dayOfYear > 0 ? dayOfYear : daysInYear(year - 1) + dayOfYear\n };\n }\n\n /************************************\n Top Level Functions\n ************************************/\n\n function makeMoment(config) {\n var input = config._i,\n format = config._f,\n res;\n\n config._locale = config._locale || moment.localeData(config._l);\n\n if (input === null || (format === undefined && input === '')) {\n return moment.invalid({nullInput: true});\n }\n\n if (typeof input === 'string') {\n config._i = input = config._locale.preparse(input);\n }\n\n if (moment.isMoment(input)) {\n return new Moment(input, true);\n } else if (format) {\n if (isArray(format)) {\n makeDateFromStringAndArray(config);\n } else {\n makeDateFromStringAndFormat(config);\n }\n } else {\n makeDateFromInput(config);\n }\n\n res = new Moment(config);\n if (res._nextDay) {\n // Adding is smart enough around DST\n res.add(1, 'd');\n res._nextDay = undefined;\n }\n\n return res;\n }\n\n moment = function (input, format, locale, strict) {\n var c;\n\n if (typeof(locale) === 'boolean') {\n strict = locale;\n locale = undefined;\n }\n // object construction must be done this way.\n // https://github.com/moment/moment/issues/1423\n c = {};\n c._isAMomentObject = true;\n c._i = input;\n c._f = format;\n c._l = locale;\n c._strict = strict;\n c._isUTC = false;\n c._pf = defaultParsingFlags();\n\n return makeMoment(c);\n };\n\n moment.suppressDeprecationWarnings = false;\n\n moment.createFromInputFallback = deprecate(\n 'moment construction falls back to js Date. This is ' +\n 'discouraged and will be removed in upcoming major ' +\n 'release. Please refer to ' +\n 'https://github.com/moment/moment/issues/1407 for more info.',\n function (config) {\n config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n }\n );\n\n // Pick a moment m from moments so that m[fn](other) is true for all\n // other. This relies on the function fn to be transitive.\n //\n // moments should either be an array of moment objects or an array, whose\n // first element is an array of moment objects.\n function pickBy(fn, moments) {\n var res, i;\n if (moments.length === 1 && isArray(moments[0])) {\n moments = moments[0];\n }\n if (!moments.length) {\n return moment();\n }\n res = moments[0];\n for (i = 1; i < moments.length; ++i) {\n if (moments[i][fn](res)) {\n res = moments[i];\n }\n }\n return res;\n }\n\n moment.min = function () {\n var args = [].slice.call(arguments, 0);\n\n return pickBy('isBefore', args);\n };\n\n moment.max = function () {\n var args = [].slice.call(arguments, 0);\n\n return pickBy('isAfter', args);\n };\n\n // creating with utc\n moment.utc = function (input, format, locale, strict) {\n var c;\n\n if (typeof(locale) === 'boolean') {\n strict = locale;\n locale = undefined;\n }\n // object construction must be done this way.\n // https://github.com/moment/moment/issues/1423\n c = {};\n c._isAMomentObject = true;\n c._useUTC = true;\n c._isUTC = true;\n c._l = locale;\n c._i = input;\n c._f = format;\n c._strict = strict;\n c._pf = defaultParsingFlags();\n\n return makeMoment(c).utc();\n };\n\n // creating with unix timestamp (in seconds)\n moment.unix = function (input) {\n return moment(input * 1000);\n };\n\n // duration\n moment.duration = function (input, key) {\n var duration = input,\n // matching against regexp is expensive, do it on demand\n match = null,\n sign,\n ret,\n parseIso,\n diffRes;\n\n if (moment.isDuration(input)) {\n duration = {\n ms: input._milliseconds,\n d: input._days,\n M: input._months\n };\n } else if (typeof input === 'number') {\n duration = {};\n if (key) {\n duration[key] = input;\n } else {\n duration.milliseconds = input;\n }\n } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {\n sign = (match[1] === '-') ? -1 : 1;\n duration = {\n y: 0,\n d: toInt(match[DATE]) * sign,\n h: toInt(match[HOUR]) * sign,\n m: toInt(match[MINUTE]) * sign,\n s: toInt(match[SECOND]) * sign,\n ms: toInt(match[MILLISECOND]) * sign\n };\n } else if (!!(match = isoDurationRegex.exec(input))) {\n sign = (match[1] === '-') ? -1 : 1;\n parseIso = function (inp) {\n // We'd normally use ~~inp for this, but unfortunately it also\n // converts floats to ints.\n // inp may be undefined, so careful calling replace on it.\n var res = inp && parseFloat(inp.replace(',', '.'));\n // apply sign while we're at it\n return (isNaN(res) ? 0 : res) * sign;\n };\n duration = {\n y: parseIso(match[2]),\n M: parseIso(match[3]),\n d: parseIso(match[4]),\n h: parseIso(match[5]),\n m: parseIso(match[6]),\n s: parseIso(match[7]),\n w: parseIso(match[8])\n };\n } else if (duration == null) {// checks for null or undefined\n duration = {};\n } else if (typeof duration === 'object' &&\n ('from' in duration || 'to' in duration)) {\n diffRes = momentsDifference(moment(duration.from), moment(duration.to));\n\n duration = {};\n duration.ms = diffRes.milliseconds;\n duration.M = diffRes.months;\n }\n\n ret = new Duration(duration);\n\n if (moment.isDuration(input) && hasOwnProp(input, '_locale')) {\n ret._locale = input._locale;\n }\n\n return ret;\n };\n\n // version number\n moment.version = VERSION;\n\n // default format\n moment.defaultFormat = isoFormat;\n\n // constant that refers to the ISO standard\n moment.ISO_8601 = function () {};\n\n // Plugins that add properties should also add the key here (null value),\n // so we can properly clone ourselves.\n moment.momentProperties = momentProperties;\n\n // This function will be called whenever a moment is mutated.\n // It is intended to keep the offset in sync with the timezone.\n moment.updateOffset = function () {};\n\n // This function allows you to set a threshold for relative time strings\n moment.relativeTimeThreshold = function (threshold, limit) {\n if (relativeTimeThresholds[threshold] === undefined) {\n return false;\n }\n if (limit === undefined) {\n return relativeTimeThresholds[threshold];\n }\n relativeTimeThresholds[threshold] = limit;\n return true;\n };\n\n moment.lang = deprecate(\n 'moment.lang is deprecated. Use moment.locale instead.',\n function (key, value) {\n return moment.locale(key, value);\n }\n );\n\n // This function will load locale and then set the global locale. If\n // no arguments are passed in, it will simply return the current global\n // locale key.\n moment.locale = function (key, values) {\n var data;\n if (key) {\n if (typeof(values) !== 'undefined') {\n data = moment.defineLocale(key, values);\n }\n else {\n data = moment.localeData(key);\n }\n\n if (data) {\n moment.duration._locale = moment._locale = data;\n }\n }\n\n return moment._locale._abbr;\n };\n\n moment.defineLocale = function (name, values) {\n if (values !== null) {\n values.abbr = name;\n if (!locales[name]) {\n locales[name] = new Locale();\n }\n locales[name].set(values);\n\n // backwards compat for now: also set the locale\n moment.locale(name);\n\n return locales[name];\n } else {\n // useful for testing\n delete locales[name];\n return null;\n }\n };\n\n moment.langData = deprecate(\n 'moment.langData is deprecated. Use moment.localeData instead.',\n function (key) {\n return moment.localeData(key);\n }\n );\n\n // returns locale data\n moment.localeData = function (key) {\n var locale;\n\n if (key && key._locale && key._locale._abbr) {\n key = key._locale._abbr;\n }\n\n if (!key) {\n return moment._locale;\n }\n\n if (!isArray(key)) {\n //short-circuit everything else\n locale = loadLocale(key);\n if (locale) {\n return locale;\n }\n key = [key];\n }\n\n return chooseLocale(key);\n };\n\n // compare moment object\n moment.isMoment = function (obj) {\n return obj instanceof Moment ||\n (obj != null && hasOwnProp(obj, '_isAMomentObject'));\n };\n\n // for typechecking Duration objects\n moment.isDuration = function (obj) {\n return obj instanceof Duration;\n };\n\n for (i = lists.length - 1; i >= 0; --i) {\n makeList(lists[i]);\n }\n\n moment.normalizeUnits = function (units) {\n return normalizeUnits(units);\n };\n\n moment.invalid = function (flags) {\n var m = moment.utc(NaN);\n if (flags != null) {\n extend(m._pf, flags);\n }\n else {\n m._pf.userInvalidated = true;\n }\n\n return m;\n };\n\n moment.parseZone = function () {\n return moment.apply(null, arguments).parseZone();\n };\n\n moment.parseTwoDigitYear = function (input) {\n return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n };\n\n moment.isDate = isDate;\n\n /************************************\n Moment Prototype\n ************************************/\n\n\n extend(moment.fn = Moment.prototype, {\n\n clone : function () {\n return moment(this);\n },\n\n valueOf : function () {\n return +this._d - ((this._offset || 0) * 60000);\n },\n\n unix : function () {\n return Math.floor(+this / 1000);\n },\n\n toString : function () {\n return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n },\n\n toDate : function () {\n return this._offset ? new Date(+this) : this._d;\n },\n\n toISOString : function () {\n var m = moment(this).utc();\n if (0 < m.year() && m.year() <= 9999) {\n if ('function' === typeof Date.prototype.toISOString) {\n // native implementation is ~50x faster, use it when we can\n return this.toDate().toISOString();\n } else {\n return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n }\n } else {\n return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n }\n },\n\n toArray : function () {\n var m = this;\n return [\n m.year(),\n m.month(),\n m.date(),\n m.hours(),\n m.minutes(),\n m.seconds(),\n m.milliseconds()\n ];\n },\n\n isValid : function () {\n return isValid(this);\n },\n\n isDSTShifted : function () {\n if (this._a) {\n return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;\n }\n\n return false;\n },\n\n parsingFlags : function () {\n return extend({}, this._pf);\n },\n\n invalidAt: function () {\n return this._pf.overflow;\n },\n\n utc : function (keepLocalTime) {\n return this.utcOffset(0, keepLocalTime);\n },\n\n local : function (keepLocalTime) {\n if (this._isUTC) {\n this.utcOffset(0, keepLocalTime);\n this._isUTC = false;\n\n if (keepLocalTime) {\n this.subtract(this._dateUtcOffset(), 'm');\n }\n }\n return this;\n },\n\n format : function (inputString) {\n var output = formatMoment(this, inputString || moment.defaultFormat);\n return this.localeData().postformat(output);\n },\n\n add : createAdder(1, 'add'),\n\n subtract : createAdder(-1, 'subtract'),\n\n diff : function (input, units, asFloat) {\n var that = makeAs(input, this),\n zoneDiff = (that.utcOffset() - this.utcOffset()) * 6e4,\n anchor, diff, output, daysAdjust;\n\n units = normalizeUnits(units);\n\n if (units === 'year' || units === 'month' || units === 'quarter') {\n output = monthDiff(this, that);\n if (units === 'quarter') {\n output = output / 3;\n } else if (units === 'year') {\n output = output / 12;\n }\n } else {\n diff = this - that;\n output = units === 'second' ? diff / 1e3 : // 1000\n units === 'minute' ? diff / 6e4 : // 1000 * 60\n units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60\n units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n diff;\n }\n return asFloat ? output : absRound(output);\n },\n\n from : function (time, withoutSuffix) {\n return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n },\n\n fromNow : function (withoutSuffix) {\n return this.from(moment(), withoutSuffix);\n },\n\n calendar : function (time) {\n // We want to compare the start of today, vs this.\n // Getting start-of-today depends on whether we're locat/utc/offset\n // or not.\n var now = time || moment(),\n sod = makeAs(now, this).startOf('day'),\n diff = this.diff(sod, 'days', true),\n format = diff < -6 ? 'sameElse' :\n diff < -1 ? 'lastWeek' :\n diff < 0 ? 'lastDay' :\n diff < 1 ? 'sameDay' :\n diff < 2 ? 'nextDay' :\n diff < 7 ? 'nextWeek' : 'sameElse';\n return this.format(this.localeData().calendar(format, this, moment(now)));\n },\n\n isLeapYear : function () {\n return isLeapYear(this.year());\n },\n\n isDST : function () {\n return (this.utcOffset() > this.clone().month(0).utcOffset() ||\n this.utcOffset() > this.clone().month(5).utcOffset());\n },\n\n day : function (input) {\n var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n if (input != null) {\n input = parseWeekday(input, this.localeData());\n return this.add(input - day, 'd');\n } else {\n return day;\n }\n },\n\n month : makeAccessor('Month', true),\n\n startOf : function (units) {\n units = normalizeUnits(units);\n // the following switch intentionally omits break keywords\n // to utilize falling through the cases.\n switch (units) {\n case 'year':\n this.month(0);\n /* falls through */\n case 'quarter':\n case 'month':\n this.date(1);\n /* falls through */\n case 'week':\n case 'isoWeek':\n case 'day':\n this.hours(0);\n /* falls through */\n case 'hour':\n this.minutes(0);\n /* falls through */\n case 'minute':\n this.seconds(0);\n /* falls through */\n case 'second':\n this.milliseconds(0);\n /* falls through */\n }\n\n // weeks are a special case\n if (units === 'week') {\n this.weekday(0);\n } else if (units === 'isoWeek') {\n this.isoWeekday(1);\n }\n\n // quarters are also special\n if (units === 'quarter') {\n this.month(Math.floor(this.month() / 3) * 3);\n }\n\n return this;\n },\n\n endOf: function (units) {\n units = normalizeUnits(units);\n if (units === undefined || units === 'millisecond') {\n return this;\n }\n return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n },\n\n isAfter: function (input, units) {\n var inputMs;\n units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n if (units === 'millisecond') {\n input = moment.isMoment(input) ? input : moment(input);\n return +this > +input;\n } else {\n inputMs = moment.isMoment(input) ? +input : +moment(input);\n return inputMs < +this.clone().startOf(units);\n }\n },\n\n isBefore: function (input, units) {\n var inputMs;\n units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n if (units === 'millisecond') {\n input = moment.isMoment(input) ? input : moment(input);\n return +this < +input;\n } else {\n inputMs = moment.isMoment(input) ? +input : +moment(input);\n return +this.clone().endOf(units) < inputMs;\n }\n },\n\n isBetween: function (from, to, units) {\n return this.isAfter(from, units) && this.isBefore(to, units);\n },\n\n isSame: function (input, units) {\n var inputMs;\n units = normalizeUnits(units || 'millisecond');\n if (units === 'millisecond') {\n input = moment.isMoment(input) ? input : moment(input);\n return +this === +input;\n } else {\n inputMs = +moment(input);\n return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));\n }\n },\n\n min: deprecate(\n 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',\n function (other) {\n other = moment.apply(null, arguments);\n return other < this ? this : other;\n }\n ),\n\n max: deprecate(\n 'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',\n function (other) {\n other = moment.apply(null, arguments);\n return other > this ? this : other;\n }\n ),\n\n zone : deprecate(\n 'moment().zone is deprecated, use moment().utcOffset instead. ' +\n 'https://github.com/moment/moment/issues/1779',\n function (input, keepLocalTime) {\n if (input != null) {\n if (typeof input !== 'string') {\n input = -input;\n }\n\n this.utcOffset(input, keepLocalTime);\n\n return this;\n } else {\n return -this.utcOffset();\n }\n }\n ),\n\n // keepLocalTime = true means only change the timezone, without\n // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n // +0200, so we adjust the time as needed, to be valid.\n //\n // Keeping the time actually adds/subtracts (one hour)\n // from the actual represented time. That is why we call updateOffset\n // a second time. In case it wants us to change the offset again\n // _changeInProgress == true case, then we have to adjust, because\n // there is no such time in the given timezone.\n utcOffset : function (input, keepLocalTime) {\n var offset = this._offset || 0,\n localAdjust;\n if (input != null) {\n if (typeof input === 'string') {\n input = utcOffsetFromString(input);\n }\n if (Math.abs(input) < 16) {\n input = input * 60;\n }\n if (!this._isUTC && keepLocalTime) {\n localAdjust = this._dateUtcOffset();\n }\n this._offset = input;\n this._isUTC = true;\n if (localAdjust != null) {\n this.add(localAdjust, 'm');\n }\n if (offset !== input) {\n if (!keepLocalTime || this._changeInProgress) {\n addOrSubtractDurationFromMoment(this,\n moment.duration(input - offset, 'm'), 1, false);\n } else if (!this._changeInProgress) {\n this._changeInProgress = true;\n moment.updateOffset(this, true);\n this._changeInProgress = null;\n }\n }\n\n return this;\n } else {\n return this._isUTC ? offset : this._dateUtcOffset();\n }\n },\n\n isLocal : function () {\n return !this._isUTC;\n },\n\n isUtcOffset : function () {\n return this._isUTC;\n },\n\n isUtc : function () {\n return this._isUTC && this._offset === 0;\n },\n\n zoneAbbr : function () {\n return this._isUTC ? 'UTC' : '';\n },\n\n zoneName : function () {\n return this._isUTC ? 'Coordinated Universal Time' : '';\n },\n\n parseZone : function () {\n if (this._tzm) {\n this.utcOffset(this._tzm);\n } else if (typeof this._i === 'string') {\n this.utcOffset(utcOffsetFromString(this._i));\n }\n return this;\n },\n\n hasAlignedHourOffset : function (input) {\n if (!input) {\n input = 0;\n }\n else {\n input = moment(input).utcOffset();\n }\n\n return (this.utcOffset() - input) % 60 === 0;\n },\n\n daysInMonth : function () {\n return daysInMonth(this.year(), this.month());\n },\n\n dayOfYear : function (input) {\n var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;\n return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n },\n\n quarter : function (input) {\n return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n },\n\n weekYear : function (input) {\n var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;\n return input == null ? year : this.add((input - year), 'y');\n },\n\n isoWeekYear : function (input) {\n var year = weekOfYear(this, 1, 4).year;\n return input == null ? year : this.add((input - year), 'y');\n },\n\n week : function (input) {\n var week = this.localeData().week(this);\n return input == null ? week : this.add((input - week) * 7, 'd');\n },\n\n isoWeek : function (input) {\n var week = weekOfYear(this, 1, 4).week;\n return input == null ? week : this.add((input - week) * 7, 'd');\n },\n\n weekday : function (input) {\n var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n return input == null ? weekday : this.add(input - weekday, 'd');\n },\n\n isoWeekday : function (input) {\n // behaves the same as moment#day except\n // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n // as a setter, sunday should belong to the previous week.\n return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);\n },\n\n isoWeeksInYear : function () {\n return weeksInYear(this.year(), 1, 4);\n },\n\n weeksInYear : function () {\n var weekInfo = this.localeData()._week;\n return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n },\n\n get : function (units) {\n units = normalizeUnits(units);\n return this[units]();\n },\n\n set : function (units, value) {\n var unit;\n if (typeof units === 'object') {\n for (unit in units) {\n this.set(unit, units[unit]);\n }\n }\n else {\n units = normalizeUnits(units);\n if (typeof this[units] === 'function') {\n this[units](value);\n }\n }\n return this;\n },\n\n // If passed a locale key, it will set the locale for this\n // instance. Otherwise, it will return the locale configuration\n // variables for this instance.\n locale : function (key) {\n var newLocaleData;\n\n if (key === undefined) {\n return this._locale._abbr;\n } else {\n newLocaleData = moment.localeData(key);\n if (newLocaleData != null) {\n this._locale = newLocaleData;\n }\n return this;\n }\n },\n\n lang : deprecate(\n 'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n function (key) {\n if (key === undefined) {\n return this.localeData();\n } else {\n return this.locale(key);\n }\n }\n ),\n\n localeData : function () {\n return this._locale;\n },\n\n _dateUtcOffset : function () {\n // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n // https://github.com/moment/moment/pull/1871\n return -Math.round(this._d.getTimezoneOffset() / 15) * 15;\n }\n\n });\n\n function rawMonthSetter(mom, value) {\n var dayOfMonth;\n\n // TODO: Move this out of here!\n if (typeof value === 'string') {\n value = mom.localeData().monthsParse(value);\n // TODO: Another silent failure?\n if (typeof value !== 'number') {\n return mom;\n }\n }\n\n dayOfMonth = Math.min(mom.date(),\n daysInMonth(mom.year(), value));\n mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n return mom;\n }\n\n function rawGetter(mom, unit) {\n return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();\n }\n\n function rawSetter(mom, unit, value) {\n if (unit === 'Month') {\n return rawMonthSetter(mom, value);\n } else {\n return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n }\n }\n\n function makeAccessor(unit, keepTime) {\n return function (value) {\n if (value != null) {\n rawSetter(this, unit, value);\n moment.updateOffset(this, keepTime);\n return this;\n } else {\n return rawGetter(this, unit);\n }\n };\n }\n\n moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false);\n moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false);\n moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false);\n // Setting the hour should keep the time, because the user explicitly\n // specified which hour he wants. So trying to maintain the same hour (in\n // a new timezone) makes sense. Adding/subtracting hours does not follow\n // this rule.\n moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);\n // moment.fn.month is defined separately\n moment.fn.date = makeAccessor('Date', true);\n moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));\n moment.fn.year = makeAccessor('FullYear', true);\n moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));\n\n // add plural methods\n moment.fn.days = moment.fn.day;\n moment.fn.months = moment.fn.month;\n moment.fn.weeks = moment.fn.week;\n moment.fn.isoWeeks = moment.fn.isoWeek;\n moment.fn.quarters = moment.fn.quarter;\n\n // add aliased format methods\n moment.fn.toJSON = moment.fn.toISOString;\n\n // alias isUtc for dev-friendliness\n moment.fn.isUTC = moment.fn.isUtc;\n\n /************************************\n Duration Prototype\n ************************************/\n\n\n function daysToYears (days) {\n // 400 years have 146097 days (taking into account leap year rules)\n return days * 400 / 146097;\n }\n\n function yearsToDays (years) {\n // years * 365 + absRound(years / 4) -\n // absRound(years / 100) + absRound(years / 400);\n return years * 146097 / 400;\n }\n\n extend(moment.duration.fn = Duration.prototype, {\n\n _bubble : function () {\n var milliseconds = this._milliseconds,\n days = this._days,\n months = this._months,\n data = this._data,\n seconds, minutes, hours, years = 0;\n\n // The following code bubbles up values, see the tests for\n // examples of what that means.\n data.milliseconds = milliseconds % 1000;\n\n seconds = absRound(milliseconds / 1000);\n data.seconds = seconds % 60;\n\n minutes = absRound(seconds / 60);\n data.minutes = minutes % 60;\n\n hours = absRound(minutes / 60);\n data.hours = hours % 24;\n\n days += absRound(hours / 24);\n\n // Accurately convert days to years, assume start from year 0.\n years = absRound(daysToYears(days));\n days -= absRound(yearsToDays(years));\n\n // 30 days to a month\n // TODO (iskren): Use anchor date (like 1st Jan) to compute this.\n months += absRound(days / 30);\n days %= 30;\n\n // 12 months -> 1 year\n years += absRound(months / 12);\n months %= 12;\n\n data.days = days;\n data.months = months;\n data.years = years;\n },\n\n abs : function () {\n this._milliseconds = Math.abs(this._milliseconds);\n this._days = Math.abs(this._days);\n this._months = Math.abs(this._months);\n\n this._data.milliseconds = Math.abs(this._data.milliseconds);\n this._data.seconds = Math.abs(this._data.seconds);\n this._data.minutes = Math.abs(this._data.minutes);\n this._data.hours = Math.abs(this._data.hours);\n this._data.months = Math.abs(this._data.months);\n this._data.years = Math.abs(this._data.years);\n\n return this;\n },\n\n weeks : function () {\n return absRound(this.days() / 7);\n },\n\n valueOf : function () {\n return this._milliseconds +\n this._days * 864e5 +\n (this._months % 12) * 2592e6 +\n toInt(this._months / 12) * 31536e6;\n },\n\n humanize : function (withSuffix) {\n var output = relativeTime(this, !withSuffix, this.localeData());\n\n if (withSuffix) {\n output = this.localeData().pastFuture(+this, output);\n }\n\n return this.localeData().postformat(output);\n },\n\n add : function (input, val) {\n // supports only 2.0-style add(1, 's') or add(moment)\n var dur = moment.duration(input, val);\n\n this._milliseconds += dur._milliseconds;\n this._days += dur._days;\n this._months += dur._months;\n\n this._bubble();\n\n return this;\n },\n\n subtract : function (input, val) {\n var dur = moment.duration(input, val);\n\n this._milliseconds -= dur._milliseconds;\n this._days -= dur._days;\n this._months -= dur._months;\n\n this._bubble();\n\n return this;\n },\n\n get : function (units) {\n units = normalizeUnits(units);\n return this[units.toLowerCase() + 's']();\n },\n\n as : function (units) {\n var days, months;\n units = normalizeUnits(units);\n\n if (units === 'month' || units === 'year') {\n days = this._days + this._milliseconds / 864e5;\n months = this._months + daysToYears(days) * 12;\n return units === 'month' ? months : months / 12;\n } else {\n // handle milliseconds separately because of floating point math errors (issue #1867)\n days = this._days + Math.round(yearsToDays(this._months / 12));\n switch (units) {\n case 'week': return days / 7 + this._milliseconds / 6048e5;\n case 'day': return days + this._milliseconds / 864e5;\n case 'hour': return days * 24 + this._milliseconds / 36e5;\n case 'minute': return days * 24 * 60 + this._milliseconds / 6e4;\n case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000;\n // Math.floor prevents floating point math errors here\n case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds;\n default: throw new Error('Unknown unit ' + units);\n }\n }\n },\n\n lang : moment.fn.lang,\n locale : moment.fn.locale,\n\n toIsoString : deprecate(\n 'toIsoString() is deprecated. Please use toISOString() instead ' +\n '(notice the capitals)',\n function () {\n return this.toISOString();\n }\n ),\n\n toISOString : function () {\n // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n var years = Math.abs(this.years()),\n months = Math.abs(this.months()),\n days = Math.abs(this.days()),\n hours = Math.abs(this.hours()),\n minutes = Math.abs(this.minutes()),\n seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);\n\n if (!this.asSeconds()) {\n // this is the same as C#'s (Noda) and python (isodate)...\n // but not other JS (goog.date)\n return 'P0D';\n }\n\n return (this.asSeconds() < 0 ? '-' : '') +\n 'P' +\n (years ? years + 'Y' : '') +\n (months ? months + 'M' : '') +\n (days ? days + 'D' : '') +\n ((hours || minutes || seconds) ? 'T' : '') +\n (hours ? hours + 'H' : '') +\n (minutes ? minutes + 'M' : '') +\n (seconds ? seconds + 'S' : '');\n },\n\n localeData : function () {\n return this._locale;\n },\n\n toJSON : function () {\n return this.toISOString();\n }\n });\n\n moment.duration.fn.toString = moment.duration.fn.toISOString;\n\n function makeDurationGetter(name) {\n moment.duration.fn[name] = function () {\n return this._data[name];\n };\n }\n\n for (i in unitMillisecondFactors) {\n if (hasOwnProp(unitMillisecondFactors, i)) {\n makeDurationGetter(i.toLowerCase());\n }\n }\n\n moment.duration.fn.asMilliseconds = function () {\n return this.as('ms');\n };\n moment.duration.fn.asSeconds = function () {\n return this.as('s');\n };\n moment.duration.fn.asMinutes = function () {\n return this.as('m');\n };\n moment.duration.fn.asHours = function () {\n return this.as('h');\n };\n moment.duration.fn.asDays = function () {\n return this.as('d');\n };\n moment.duration.fn.asWeeks = function () {\n return this.as('weeks');\n };\n moment.duration.fn.asMonths = function () {\n return this.as('M');\n };\n moment.duration.fn.asYears = function () {\n return this.as('y');\n };\n\n /************************************\n Default Locale\n ************************************/\n\n\n // Set default locale, other locale will inherit from English.\n moment.locale('en', {\n ordinalParse: /\\d{1,2}(th|st|nd|rd)/,\n ordinal : function (number) {\n var b = number % 10,\n output = (toInt(number % 100 / 10) === 1) ? 'th' :\n (b === 1) ? 'st' :\n (b === 2) ? 'nd' :\n (b === 3) ? 'rd' : 'th';\n return number + output;\n }\n });\n\n /* EMBED_LOCALES */\n\n /************************************\n Exposing Moment\n ************************************/\n\n function makeGlobal(shouldDeprecate) {\n /*global ender:false */\n if (typeof ender !== 'undefined') {\n return;\n }\n oldGlobalMoment = globalScope.moment;\n if (shouldDeprecate) {\n globalScope.moment = deprecate(\n 'Accessing Moment through the global scope is ' +\n 'deprecated, and will be removed in an upcoming ' +\n 'release.',\n moment);\n } else {\n globalScope.moment = moment;\n }\n }\n\n // CommonJS module is defined\n if (hasModule) {\n module.exports = moment;\n } else if (typeof define === 'function' && define.amd) {\n define(function (require, exports, module) {\n if (module.config && module.config() && module.config().noGlobal === true) {\n // release the global variable\n globalScope.moment = oldGlobalMoment;\n }\n\n return moment;\n });\n makeGlobal(true);\n } else {\n makeGlobal();\n }\n}).call(this);\n",
"/**\n * autoNumeric.js\n * @author: Bob Knothe\n * @author: Sokolov Yura\n * @version: 1.9.39 - 2015-07-17 GMT 5:00 PM / 19:00\n *\n * Created by Robert J. Knothe on 2010-10-25. Please report any bugs to https://github.com/BobKnothe/autoNumeric\n * Contributor by Sokolov Yura on 2010-11-07\n *\n * Copyright (c) 2011 Robert J. Knothe http://www.decorplanit.com/plugin/\n *\n * The MIT License (http://www.opensource.org/licenses/mit-license.php)\n *\n * Permission is hereby granted, free of charge, to any person\n * obtaining a copy of this software and associated documentation\n * files (the \"Software\"), to deal in the Software without\n * restriction, including without limitation the rights to use,\n * copy, modify, merge, publish, distribute, sublicense, and/or sell\n * copies of the Software, and to permit persons to whom the\n * Software is furnished to do so, subject to the following\n * conditions:\n *\n * The above copyright notice and this permission notice shall be\n * included in all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n * OTHER DEALINGS IN THE SOFTWARE.\n */\n(function ($) {\n \"use strict\";\n /*jslint browser: true*/\n /*global jQuery: false*/\n /*Cross browser routine for getting selected range/cursor position\n */\n\n /**\n * Cross browser routine for getting selected range/cursor position\n */\n function getElementSelection(that) {\n var position = {};\n if (that.selectionStart === undefined) {\n that.focus();\n var select = document.selection.createRange();\n position.length = select.text.length;\n select.moveStart('character', -that.value.length);\n position.end = select.text.length;\n position.start = position.end - position.length;\n } else {\n position.start = that.selectionStart;\n position.end = that.selectionEnd;\n position.length = position.end - position.start;\n }\n return position;\n }\n\n /**\n * Cross browser routine for setting selected range/cursor position\n */\n function setElementSelection(that, start, end) {\n if (that.selectionStart === undefined) {\n that.focus();\n var r = that.createTextRange();\n r.collapse(true);\n r.moveEnd('character', end);\n r.moveStart('character', start);\n r.select();\n } else {\n that.selectionStart = start;\n that.selectionEnd = end;\n }\n }\n\n /**\n * run callbacks in parameters if any\n * any parameter could be a callback:\n * - a function, which invoked with jQuery element, parameters and this parameter name and returns parameter value\n * - a name of function, attached to $(selector).autoNumeric.functionName(){} - which was called previously\n */\n function runCallbacks($this, settings) {\n /**\n * loops through the settings object (option array) to find the following\n * k = option name example k=aNum\n * val = option value example val=0123456789\n */\n $.each(settings, function (k, val) {\n if (typeof val === 'function') {\n settings[k] = val($this, settings, k);\n } else if (typeof $this.autoNumeric[val] === 'function') {\n /**\n * calls the attached function from the html5 data example: data-a-sign=\"functionName\"\n */\n settings[k] = $this.autoNumeric[val]($this, settings, k);\n }\n });\n }\n\n /**\n * Converts the vMin, vMax & mDec string to numeric value\n */\n function convertKeyToNumber(settings, key) {\n if (typeof (settings[key]) === 'string') {\n settings[key] *= 1;\n }\n }\n\n /**\n * Preparing user defined options for further usage\n * merge them with defaults appropriately\n */\n function autoCode($this, settings) {\n runCallbacks($this, settings);\n settings.tagList = ['b', 'caption', 'cite', 'code', 'dd', 'del', 'div', 'dfn', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ins', 'kdb', 'label', 'li', 'output', 'p', 'q', 's', 'sample', 'span', 'strong', 'td', 'th', 'u', 'var'];\n var vmax = settings.vMax.toString().split('.'),\n vmin = (!settings.vMin && settings.vMin !== 0) ? [] : settings.vMin.toString().split('.');\n convertKeyToNumber(settings, 'vMax');\n convertKeyToNumber(settings, 'vMin');\n convertKeyToNumber(settings, 'mDec'); /** set mDec if not defined by user */\n settings.mDec = (settings.mRound === 'CHF') ? '2' : settings.mDec;\n settings.allowLeading = true;\n settings.aNeg = settings.vMin < 0 ? '-' : '';\n vmax[0] = vmax[0].replace('-', '');\n vmin[0] = vmin[0].replace('-', '');\n settings.mInt = Math.max(vmax[0].length, vmin[0].length, 1);\n if (settings.mDec === null) {\n var vmaxLength = 0,\n vminLength = 0;\n if (vmax[1]) {\n vmaxLength = vmax[1].length;\n }\n if (vmin[1]) {\n vminLength = vmin[1].length;\n }\n settings.mDec = Math.max(vmaxLength, vminLength);\n } /** set alternative decimal separator key */\n if (settings.altDec === null && settings.mDec > 0) {\n if (settings.aDec === '.' && settings.aSep !== ',') {\n settings.altDec = ',';\n } else if (settings.aDec === ',' && settings.aSep !== '.') {\n settings.altDec = '.';\n }\n }\n /** cache regexps for autoStrip */\n var aNegReg = settings.aNeg ? '([-\\\\' + settings.aNeg + ']?)' : '(-?)';\n settings.aNegRegAutoStrip = aNegReg;\n settings.skipFirstAutoStrip = new RegExp(aNegReg + '[^-' + (settings.aNeg ? '\\\\' + settings.aNeg : '') + '\\\\' + settings.aDec + '\\\\d]' + '.*?(\\\\d|\\\\' + settings.aDec + '\\\\d)');\n settings.skipLastAutoStrip = new RegExp('(\\\\d\\\\' + settings.aDec + '?)[^\\\\' + settings.aDec + '\\\\d]\\\\D*$');\n var allowed = '-' + settings.aNum + '\\\\' + settings.aDec;\n settings.allowedAutoStrip = new RegExp('[^' + allowed + ']', 'gi');\n settings.numRegAutoStrip = new RegExp(aNegReg + '(?:\\\\' + settings.aDec + '?(\\\\d+\\\\' + settings.aDec + '\\\\d+)|(\\\\d*(?:\\\\' + settings.aDec + '\\\\d*)?))');\n return settings;\n }\n\n /**\n * strips all unwanted characters and leave only a number alert\n */\n function autoStrip(s, settings, strip_zero) {\n if (settings.aSign) { /** remove currency sign */\n while (s.indexOf(settings.aSign) > -1) {\n s = s.replace(settings.aSign, '');\n }\n }\n s = s.replace(settings.skipFirstAutoStrip, '$1$2'); /** first replace anything before digits */\n s = s.replace(settings.skipLastAutoStrip, '$1'); /** then replace anything after digits */\n s = s.replace(settings.allowedAutoStrip, ''); /** then remove any uninterested characters */\n if (settings.altDec) {\n s = s.replace(settings.altDec, settings.aDec);\n } /** get only number string */\n var m = s.match(settings.numRegAutoStrip);\n s = m ? [m[1], m[2], m[3]].join('') : '';\n if ((settings.lZero === 'allow' || settings.lZero === 'keep') && strip_zero !== 'strip') {\n var parts = [],\n nSign = '';\n parts = s.split(settings.aDec);\n if (parts[0].indexOf('-') !== -1) {\n nSign = '-';\n parts[0] = parts[0].replace('-', '');\n }\n if (parts[0].length > settings.mInt && parts[0].charAt(0) === '0') { /** strip leading zero if need */\n parts[0] = parts[0].slice(1);\n }\n s = nSign + parts.join(settings.aDec);\n }\n if ((strip_zero && settings.lZero === 'deny') || (strip_zero && settings.lZero === 'allow' && settings.allowLeading === false)) {\n var strip_reg = '^' + settings.aNegRegAutoStrip + '0*(\\\\d' + (strip_zero === 'leading' ? ')' : '|$)');\n strip_reg = new RegExp(strip_reg);\n s = s.replace(strip_reg, '$1$2');\n }\n return s;\n }\n\n /**\n * places or removes brackets on negative values\n * works only when with pSign: 'p'\n */\n function negativeBracket(s, settings) {\n if (settings.pSign === 'p') {\n var brackets = settings.nBracket.split(',');\n if (!settings.hasFocus && !settings.removeBrackets) {\n s = s.replace(settings.aNeg, '');\n s = brackets[0] + s + brackets[1];\n } else if ((settings.hasFocus && s.charAt(0) === brackets[0]) || (settings.removeBrackets && s.charAt(0) === brackets[0])) {\n s = s.replace(brackets[0], settings.aNeg);\n s = s.replace(brackets[1], '');\n }\n }\n return s;\n }\n\n /**\n * function to handle numbers less than 0 that are stored in Exponential notation ex: .0000001 stored as 1e-7\n */\n function checkValue(value, settings) {\n if (value) {\n var checkSmall = +value;\n if (checkSmall < 0.000001 && checkSmall > -1) {\n value = +value;\n if (value < 0.000001 && value > 0) {\n value = (value + 10).toString();\n value = value.substring(1);\n }\n if (value < 0 && value > -1) {\n value = (value - 10).toString();\n value = '-' + value.substring(2);\n }\n value = value.toString();\n } else {\n var parts = value.split('.');\n if (parts[1] !== undefined) {\n if (+parts[1] === 0) {\n value = parts[0];\n } else {\n parts[1] = parts[1].replace(/0*$/, '');\n value = parts.join('.');\n }\n }\n }\n }\n return (settings.lZero === 'keep') ? value : value.replace(/^0*(\\d)/, '$1');\n }\n\n /**\n * prepare number string to be converted to real number\n */\n function fixNumber(s, aDec, aNeg) {\n if (aDec && aDec !== '.') {\n s = s.replace(aDec, '.');\n }\n if (aNeg && aNeg !== '-') {\n s = s.replace(aNeg, '-');\n }\n if (!s.match(/\\d/)) {\n s += '0';\n }\n return s;\n }\n\n /**\n * prepare real number to be converted to our format\n */\n function presentNumber(s, aDec, aNeg) {\n if (aNeg && aNeg !== '-') {\n s = s.replace('-', aNeg);\n }\n if (aDec && aDec !== '.') {\n s = s.replace('.', aDec);\n }\n return s;\n }\n\n /**\n * private function to check for empty value\n */\n function checkEmpty(iv, settings, signOnEmpty) {\n if (iv === '' || iv === settings.aNeg) {\n if (settings.wEmpty === 'zero') {\n return iv + '0';\n }\n if (settings.wEmpty === 'sign' || signOnEmpty) {\n return iv + settings.aSign;\n }\n return iv;\n }\n return null;\n }\n\n /**\n * private function that formats our number\n */\n function autoGroup(iv, settings) {\n iv = autoStrip(iv, settings);\n var testNeg = iv.replace(',', '.'),\n empty = checkEmpty(iv, settings, true);\n if (empty !== null) {\n return empty;\n }\n var digitalGroup = '';\n if (settings.dGroup === 2) {\n digitalGroup = /(\\d)((\\d)(\\d{2}?)+)$/;\n } else if (settings.dGroup === 4) {\n digitalGroup = /(\\d)((\\d{4}?)+)$/;\n } else {\n digitalGroup = /(\\d)((\\d{3}?)+)$/;\n } /** splits the string at the decimal string */\n var ivSplit = iv.split(settings.aDec);\n if (settings.altDec && ivSplit.length === 1) {\n ivSplit = iv.split(settings.altDec);\n } /** assigns the whole number to the a variable (s) */\n var s = ivSplit[0];\n if (settings.aSep) {\n while (digitalGroup.test(s)) { /** re-inserts the thousand separator via a regular expression */\n s = s.replace(digitalGroup, '$1' + settings.aSep + '$2');\n }\n }\n if (settings.mDec !== 0 && ivSplit.length > 1) {\n if (ivSplit[1].length > settings.mDec) {\n ivSplit[1] = ivSplit[1].substring(0, settings.mDec);\n } /** joins the whole number with the decimal value */\n iv = s + settings.aDec + ivSplit[1];\n } else { /** if whole numbers only */\n iv = s;\n }\n if (settings.aSign) {\n var has_aNeg = iv.indexOf(settings.aNeg) !== -1;\n iv = iv.replace(settings.aNeg, '');\n iv = settings.pSign === 'p' ? settings.aSign + iv : iv + settings.aSign;\n if (has_aNeg) {\n iv = settings.aNeg + iv;\n }\n }\n if (testNeg < 0 && settings.nBracket !== null) { /** removes the negative sign and places brackets */\n iv = negativeBracket(iv, settings);\n }\n return iv;\n }\n\n /**\n * round number after setting by pasting or $().autoNumericSet()\n * private function for round the number\n * please note this handled as text - JavaScript math function can return inaccurate values\n * also this offers multiple rounding methods that are not easily accomplished in JavaScript\n */\n function autoRound(iv, settings) { /** value to string */\n iv = (iv === '') ? '0' : iv.toString();\n convertKeyToNumber(settings, 'mDec'); /** set mDec to number needed when mDec set by 'update method */\n if (settings.mRound === 'CHF') {\n iv = (Math.round(iv * 20) / 20).toString();\n }\n var ivRounded = '',\n i = 0,\n nSign = '',\n rDec = (typeof (settings.aPad) === 'boolean' || settings.aPad === null) ? (settings.aPad ? settings.mDec : 0) : +settings.aPad;\n var truncateZeros = function (ivRounded) { /** truncate not needed zeros */\n var regex = (rDec === 0) ? (/(\\.(?:\\d*[1-9])?)0*$/) : rDec === 1 ? (/(\\.\\d(?:\\d*[1-9])?)0*$/) : new RegExp('(\\\\.\\\\d{' + rDec + '}(?:\\\\d*[1-9])?)0*$');\n ivRounded = ivRounded.replace(regex, '$1'); /** If there are no decimal places, we don't need a decimal point at the end */\n if (rDec === 0) {\n ivRounded = ivRounded.replace(/\\.$/, '');\n }\n return ivRounded;\n };\n if (iv.charAt(0) === '-') { /** Checks if the iv (input Value)is a negative value */\n nSign = '-';\n iv = iv.replace('-', ''); /** removes the negative sign will be added back later if required */\n }\n if (!iv.match(/^\\d/)) { /** append a zero if first character is not a digit (then it is likely to be a dot)*/\n iv = '0' + iv;\n }\n if (nSign === '-' && +iv === 0) { /** determines if the value is zero - if zero no negative sign */\n nSign = '';\n }\n if ((+iv > 0 && settings.lZero !== 'keep') || (iv.length > 0 && settings.lZero === 'allow')) { /** trims leading zero's if needed */\n iv = iv.replace(/^0*(\\d)/, '$1');\n }\n var dPos = iv.lastIndexOf('.'),\n /** virtual decimal position */\n vdPos = (dPos === -1) ? iv.length - 1 : dPos,\n /** checks decimal places to determine if rounding is required */\n cDec = (iv.length - 1) - vdPos; /** check if no rounding is required */\n if (cDec <= settings.mDec) {\n ivRounded = iv; /** check if we need to pad with zeros */\n if (cDec < rDec) {\n if (dPos === -1) {\n ivRounded += '.';\n }\n var zeros = '000000';\n while (cDec < rDec) {\n zeros = zeros.substring(0, rDec - cDec);\n ivRounded += zeros;\n cDec += zeros.length;\n }\n } else if (cDec > rDec) {\n ivRounded = truncateZeros(ivRounded);\n } else if (cDec === 0 && rDec === 0) {\n ivRounded = ivRounded.replace(/\\.$/, '');\n }\n if (settings.mRound !== 'CHF') {\n return (+ivRounded === 0) ? ivRounded : nSign + ivRounded;\n }\n if (settings.mRound === 'CHF') {\n dPos = ivRounded.lastIndexOf('.');\n iv = ivRounded;\n }\n\n } /** rounded length of the string after rounding */\n var rLength = dPos + settings.mDec,\n tRound = +iv.charAt(rLength + 1),\n ivArray = iv.substring(0, rLength + 1).split(''),\n odd = (iv.charAt(rLength) === '.') ? (iv.charAt(rLength - 1) % 2) : (iv.charAt(rLength) % 2),\n onePass = true;\n if (odd !== 1) {\n odd = (odd === 0 && (iv.substring(rLength + 2, iv.length) > 0)) ? 1 : 0;\n }\n /*jslint white: true*/\n if ((tRound > 4 && settings.mRound === 'S') || /** Round half up symmetric */\n (tRound > 4 && settings.mRound === 'A' && nSign === '') || /** Round half up asymmetric positive values */\n (tRound > 5 && settings.mRound === 'A' && nSign === '-') || /** Round half up asymmetric negative values */\n (tRound > 5 && settings.mRound === 's') || /** Round half down symmetric */\n (tRound > 5 && settings.mRound === 'a' && nSign === '') || /** Round half down asymmetric positive values */\n (tRound > 4 && settings.mRound === 'a' && nSign === '-') || /** Round half down asymmetric negative values */\n (tRound > 5 && settings.mRound === 'B') || /** Round half even \"Banker's Rounding\" */\n (tRound === 5 && settings.mRound === 'B' && odd === 1) || /** Round half even \"Banker's Rounding\" */\n (tRound > 0 && settings.mRound === 'C' && nSign === '') || /** Round to ceiling toward positive infinite */\n (tRound > 0 && settings.mRound === 'F' && nSign === '-') || /** Round to floor toward negative infinite */\n (tRound > 0 && settings.mRound === 'U') || /** round up away from zero */\n (settings.mRound === 'CHF')) { /** Round Swiss FRanc */\n /*jslint white: false*/\n for (i = (ivArray.length - 1); i >= 0; i -= 1) { /** Round up the last digit if required, and continue until no more 9's are found */\n if (ivArray[i] !== '.') {\n if (settings.mRound === 'CHF' && ivArray[i] <= 2 && onePass) {\n ivArray[i] = 0;\n onePass = false;\n break;\n }\n if (settings.mRound === 'CHF' && ivArray[i] <= 7 && onePass) {\n ivArray[i] = 5;\n onePass = false;\n break;\n }\n if (settings.mRound === 'CHF' && onePass) {\n ivArray[i] = 10;\n onePass = false;\n } else {\n ivArray[i] = +ivArray[i] + 1;\n }\n if (ivArray[i] < 10) {\n break;\n }\n if (i > 0) {\n ivArray[i] = '0';\n }\n }\n }\n }\n ivArray = ivArray.slice(0, rLength + 1); /** Reconstruct the string, converting any 10's to 0's */\n ivRounded = truncateZeros(ivArray.join('')); /** return rounded value */\n return (+ivRounded === 0) ? ivRounded : nSign + ivRounded;\n }\n\n /**\n * truncate decimal part of a number\n */\n function truncateDecimal(s, settings, paste) {\n var aDec = settings.aDec,\n mDec = settings.mDec;\n s = (paste === 'paste') ? autoRound(s, settings) : s;\n if (aDec && mDec) {\n var parts = s.split(aDec);\n /** truncate decimal part to satisfying length\n * cause we would round it anyway */\n if (parts[1] && parts[1].length > mDec) {\n if (mDec > 0) {\n parts[1] = parts[1].substring(0, mDec);\n s = parts.join(aDec);\n } else {\n s = parts[0];\n }\n }\n }\n return s;\n }\n\n /**\n * checking that number satisfy format conditions\n * and lays between settings.vMin and settings.vMax\n * and the string length does not exceed the digits in settings.vMin and settings.vMax\n */\n function autoCheck(s, settings) {\n s = autoStrip(s, settings);\n s = truncateDecimal(s, settings);\n s = fixNumber(s, settings.aDec, settings.aNeg);\n var value = +s;\n return value >= settings.vMin && value <= settings.vMax;\n }\n\n /**\n * Holder object for field properties\n */\n function AutoNumericHolder(that, settings) {\n this.settings = settings;\n this.that = that;\n this.$that = $(that);\n this.formatted = false;\n this.settingsClone = autoCode(this.$that, this.settings);\n this.value = that.value;\n }\n AutoNumericHolder.prototype = {\n init: function (e) {\n this.value = this.that.value;\n this.settingsClone = autoCode(this.$that, this.settings);\n this.ctrlKey = e.ctrlKey;\n this.cmdKey = e.metaKey;\n this.shiftKey = e.shiftKey;\n this.selection = getElementSelection(this.that); /** keypress event overwrites meaningful value of e.keyCode */\n if (e.type === 'keydown' || e.type === 'keyup') {\n this.kdCode = e.keyCode;\n }\n this.which = e.which;\n this.processed = false;\n this.formatted = false;\n },\n setSelection: function (start, end, setReal) {\n start = Math.max(start, 0);\n end = Math.min(end, this.that.value.length);\n this.selection = {\n start: start,\n end: end,\n length: end - start\n };\n if (setReal === undefined || setReal) {\n setElementSelection(this.that, start, end);\n }\n },\n setPosition: function (pos, setReal) {\n this.setSelection(pos, pos, setReal);\n },\n getBeforeAfter: function () {\n var value = this.value,\n left = value.substring(0, this.selection.start),\n right = value.substring(this.selection.end, value.length);\n return [left, right];\n },\n getBeforeAfterStriped: function () {\n var parts = this.getBeforeAfter();\n parts[0] = autoStrip(parts[0], this.settingsClone);\n parts[1] = autoStrip(parts[1], this.settingsClone);\n return parts;\n },\n\n /**\n * strip parts from excess characters and leading zeroes\n */\n normalizeParts: function (left, right) {\n var settingsClone = this.settingsClone;\n right = autoStrip(right, settingsClone); /** if right is not empty and first character is not aDec, */\n /** we could strip all zeros, otherwise only leading */\n var strip = right.match(/^\\d/) ? true : 'leading';\n left = autoStrip(left, settingsClone, strip); /** prevents multiple leading zeros from being entered */\n if ((left === '' || left === settingsClone.aNeg) && settingsClone.lZero === 'deny') {\n if (right > '') {\n right = right.replace(/^0*(\\d)/, '$1');\n }\n }\n var new_value = left + right; /** insert zero if has leading dot */\n if (settingsClone.aDec) {\n var m = new_value.match(new RegExp('^' + settingsClone.aNegRegAutoStrip + '\\\\' + settingsClone.aDec));\n if (m) {\n left = left.replace(m[1], m[1] + '0');\n new_value = left + right;\n }\n } /** insert zero if number is empty and io.wEmpty == 'zero' */\n if (settingsClone.wEmpty === 'zero' && (new_value === settingsClone.aNeg || new_value === '')) {\n left += '0';\n }\n return [left, right];\n },\n\n /**\n * set part of number to value keeping position of cursor\n */\n setValueParts: function (left, right, paste) {\n var settingsClone = this.settingsClone,\n parts = this.normalizeParts(left, right),\n new_value = parts.join(''),\n position = parts[0].length;\n if (autoCheck(new_value, settingsClone)) {\n new_value = truncateDecimal(new_value, settingsClone, paste);\n if (position > new_value.length) {\n position = new_value.length;\n }\n this.value = new_value;\n this.setPosition(position, false);\n return true;\n }\n return false;\n },\n\n /**\n * helper function for expandSelectionOnSign\n * returns sign position of a formatted value\n */\n signPosition: function () {\n var settingsClone = this.settingsClone,\n aSign = settingsClone.aSign,\n that = this.that;\n if (aSign) {\n var aSignLen = aSign.length;\n if (settingsClone.pSign === 'p') {\n var hasNeg = settingsClone.aNeg && that.value && that.value.charAt(0) === settingsClone.aNeg;\n return hasNeg ? [1, aSignLen + 1] : [0, aSignLen];\n }\n var valueLen = that.value.length;\n return [valueLen - aSignLen, valueLen];\n }\n return [1000, -1];\n },\n\n /**\n * expands selection to cover whole sign\n * prevents partial deletion/copying/overwriting of a sign\n */\n expandSelectionOnSign: function (setReal) {\n var sign_position = this.signPosition(),\n selection = this.selection;\n if (selection.start < sign_position[1] && selection.end > sign_position[0]) { /** if selection catches something except sign and catches only space from sign */\n if ((selection.start < sign_position[0] || selection.end > sign_position[1]) && this.value.substring(Math.max(selection.start, sign_position[0]), Math.min(selection.end, sign_position[1])).match(/^\\s*$/)) { /** then select without empty space */\n if (selection.start < sign_position[0]) {\n this.setSelection(selection.start, sign_position[0], setReal);\n } else {\n this.setSelection(sign_position[1], selection.end, setReal);\n }\n } else { /** else select with whole sign */\n this.setSelection(Math.min(selection.start, sign_position[0]), Math.max(selection.end, sign_position[1]), setReal);\n }\n }\n },\n\n /**\n * try to strip pasted value to digits\n */\n checkPaste: function () {\n if (this.valuePartsBeforePaste !== undefined) {\n var parts = this.getBeforeAfter(),\n\n oldParts = this.valuePartsBeforePaste;\n delete this.valuePartsBeforePaste; /** try to strip pasted value first */\n parts[0] = parts[0].substr(0, oldParts[0].length) + autoStrip(parts[0].substr(oldParts[0].length), this.settingsClone);\n if (!this.setValueParts(parts[0], parts[1], 'paste')) {\n this.value = oldParts.join('');\n this.setPosition(oldParts[0].length, false);\n }\n }\n },\n\n /**\n * process pasting, cursor moving and skipping of not interesting keys\n * if returns true, further processing is not performed\n */\n skipAllways: function (e) {\n var kdCode = this.kdCode,\n which = this.which,\n ctrlKey = this.ctrlKey,\n cmdKey = this.cmdKey,\n shiftKey = this.shiftKey; /** catch the ctrl up on ctrl-v */\n if (((ctrlKey || cmdKey) && e.type === 'keyup' && this.valuePartsBeforePaste !== undefined) || (shiftKey && kdCode === 45)) {\n this.checkPaste();\n return false;\n }\n /** codes are taken from http://www.cambiaresearch.com/c4/702b8cd1-e5b0-42e6-83ac-25f0306e3e25/Javascript-Char-Codes-Key-Codes.aspx\n * skip Fx keys, windows keys, other special keys\n * Thanks Ney Estrabelli for the FF for Mac meta key support \"keycode 224\"\n */\n if ((kdCode >= 112 && kdCode <= 123) || (kdCode >= 91 && kdCode <= 93) || (kdCode >= 9 && kdCode <= 31) || (kdCode < 8 && (which === 0 || which === kdCode)) || kdCode === 144 || kdCode === 145 || kdCode === 45 || kdCode === 224) {\n return true;\n }\n if ((ctrlKey || cmdKey) && kdCode === 65) { /** if select all (a=65)*/\n return true;\n }\n if ((ctrlKey || cmdKey) && (kdCode === 67 || kdCode === 86 || kdCode === 88)) { /** if copy (c=67) paste (v=86) or cut (x=88) */\n if (e.type === 'keydown') {\n this.expandSelectionOnSign();\n }\n if (kdCode === 86 || kdCode === 45) { /** try to prevent wrong paste */\n if (e.type === 'keydown' || e.type === 'keypress') {\n if (this.valuePartsBeforePaste === undefined) {\n this.valuePartsBeforePaste = this.getBeforeAfter();\n }\n } else {\n this.checkPaste();\n }\n }\n return e.type === 'keydown' || e.type === 'keypress' || kdCode === 67;\n }\n if (ctrlKey || cmdKey) {\n return true;\n }\n if (kdCode === 37 || kdCode === 39) { /** jump over thousand separator */\n var aSep = this.settingsClone.aSep,\n start = this.selection.start,\n value = this.that.value;\n if (e.type === 'keydown' && aSep && !this.shiftKey) {\n if (kdCode === 37 && value.charAt(start - 2) === aSep) {\n this.setPosition(start - 1);\n } else if (kdCode === 39 && value.charAt(start + 1) === aSep) {\n this.setPosition(start + 1);\n }\n }\n return true;\n }\n if (kdCode >= 34 && kdCode <= 40) {\n return true;\n }\n return false;\n },\n\n /**\n * process deletion of characters\n * returns true if processing performed\n */\n processAllways: function () {\n var parts; /** process backspace or delete */\n if (this.kdCode === 8 || this.kdCode === 46) {\n if (!this.selection.length) {\n parts = this.getBeforeAfterStriped();\n if (this.kdCode === 8) {\n parts[0] = parts[0].substring(0, parts[0].length - 1);\n } else {\n parts[1] = parts[1].substring(1, parts[1].length);\n }\n this.setValueParts(parts[0], parts[1]);\n } else {\n this.expandSelectionOnSign(false);\n parts = this.getBeforeAfterStriped();\n this.setValueParts(parts[0], parts[1]);\n }\n return true;\n }\n return false;\n },\n\n /**\n * process insertion of characters\n * returns true if processing performed\n */\n processKeypress: function () {\n var settingsClone = this.settingsClone,\n cCode = String.fromCharCode(this.which),\n parts = this.getBeforeAfterStriped(),\n left = parts[0],\n right = parts[1]; /** start rules when the decimal character key is pressed */\n /** always use numeric pad dot to insert decimal separator */\n if (cCode === settingsClone.aDec || (settingsClone.altDec && cCode === settingsClone.altDec) || ((cCode === '.' || cCode === ',') && this.kdCode === 110)) { /** do not allow decimal character if no decimal part allowed */\n if (!settingsClone.mDec || !settingsClone.aDec) {\n return true;\n } /** do not allow decimal character before aNeg character */\n if (settingsClone.aNeg && right.indexOf(settingsClone.aNeg) > -1) {\n return true;\n } /** do not allow decimal character if other decimal character present */\n if (left.indexOf(settingsClone.aDec) > -1) {\n return true;\n }\n if (right.indexOf(settingsClone.aDec) > 0) {\n return true;\n }\n if (right.indexOf(settingsClone.aDec) === 0) {\n right = right.substr(1);\n }\n this.setValueParts(left + settingsClone.aDec, right);\n return true;\n }\n /**\n * start rule on negative sign & prevent minus if not allowed\n */\n if (cCode === '-' || cCode === '+') {\n if (!settingsClone.aNeg) {\n return true;\n } /** caret is always after minus */\n if (left === '' && right.indexOf(settingsClone.aNeg) > -1) {\n left = settingsClone.aNeg;\n right = right.substring(1, right.length);\n } /** change sign of number, remove part if should */\n if (left.charAt(0) === settingsClone.aNeg) {\n left = left.substring(1, left.length);\n } else {\n left = (cCode === '-') ? settingsClone.aNeg + left : left;\n }\n this.setValueParts(left, right);\n return true;\n } /** digits */\n if (cCode >= '0' && cCode <= '9') { /** if try to insert digit before minus */\n if (settingsClone.aNeg && left === '' && right.indexOf(settingsClone.aNeg) > -1) {\n left = settingsClone.aNeg;\n right = right.substring(1, right.length);\n }\n if (settingsClone.vMax <= 0 && settingsClone.vMin < settingsClone.vMax && this.value.indexOf(settingsClone.aNeg) === -1 && cCode !== '0') {\n left = settingsClone.aNeg + left;\n }\n this.setValueParts(left + cCode, right);\n return true;\n } /** prevent any other character */\n return true;\n },\n\n /**\n * formatting of just processed value with keeping of cursor position\n */\n formatQuick: function () {\n var settingsClone = this.settingsClone,\n parts = this.getBeforeAfterStriped(),\n leftLength = this.value;\n if ((settingsClone.aSep === '' || (settingsClone.aSep !== '' && leftLength.indexOf(settingsClone.aSep) === -1)) && (settingsClone.aSign === '' || (settingsClone.aSign !== '' && leftLength.indexOf(settingsClone.aSign) === -1))) {\n var subParts = [],\n nSign = '';\n subParts = leftLength.split(settingsClone.aDec);\n if (subParts[0].indexOf('-') > -1) {\n nSign = '-';\n subParts[0] = subParts[0].replace('-', '');\n parts[0] = parts[0].replace('-', '');\n }\n if (subParts[0].length > settingsClone.mInt && parts[0].charAt(0) === '0') { /** strip leading zero if need */\n parts[0] = parts[0].slice(1);\n }\n parts[0] = nSign + parts[0];\n }\n var value = autoGroup(this.value, this.settingsClone),\n position = value.length;\n if (value) {\n /** prepare regexp which searches for cursor position from unformatted left part */\n var left_ar = parts[0].split(''),\n i = 0;\n for (i; i < left_ar.length; i += 1) { /** thanks Peter Kovari */\n if (!left_ar[i].match('\\\\d')) {\n left_ar[i] = '\\\\' + left_ar[i];\n }\n }\n var leftReg = new RegExp('^.*?' + left_ar.join('.*?'));\n /** search cursor position in formatted value */\n var newLeft = value.match(leftReg);\n if (newLeft) {\n position = newLeft[0].length;\n /** if we are just before sign which is in prefix position */\n if (((position === 0 && value.charAt(0) !== settingsClone.aNeg) || (position === 1 && value.charAt(0) === settingsClone.aNeg)) && settingsClone.aSign && settingsClone.pSign === 'p') {\n /** place caret after prefix sign */\n position = this.settingsClone.aSign.length + (value.charAt(0) === '-' ? 1 : 0);\n }\n } else if (settingsClone.aSign && settingsClone.pSign === 's') {\n /** if we could not find a place for cursor and have a sign as a suffix */\n /** place carret before suffix currency sign */\n position -= settingsClone.aSign.length;\n }\n }\n this.that.value = value;\n this.setPosition(position);\n this.formatted = true;\n }\n };\n\n /**\n * thanks to Anthony & Evan C\n */\n function autoGet(obj) {\n if (typeof obj === 'string') {\n obj = obj.replace(/\\[/g, \"\\\\[\").replace(/\\]/g, \"\\\\]\");\n obj = '#' + obj.replace(/(:|\\.)/g, '\\\\$1');\n /** obj = '#' + obj.replace(/([;&,\\.\\+\\*\\~':\"\\!\\^#$%@\\[\\]\\(\\)=>\\|])/g, '\\\\$1'); */\n /** possible modification to replace the above 2 lines */\n }\n return $(obj);\n }\n\n /**\n * function to attach data to the element\n * and imitate the holder\n */\n function getHolder($that, settings, update) {\n var data = $that.data('autoNumeric');\n if (!data) {\n data = {};\n $that.data('autoNumeric', data);\n }\n var holder = data.holder;\n if ((holder === undefined && settings) || update) {\n holder = new AutoNumericHolder($that.get(0), settings);\n data.holder = holder;\n }\n return holder;\n }\n\n var methods = {\n\n /**\n * Method to initiate autoNumeric and attached the settings (default and options passed as a parameter\n * $(someSelector).autoNumeric('init'); // initiate autoNumeric with defaults\n * $(someSelector).autoNumeric('init', {option}); // initiate autoNumeric with options\n * $(someSelector).autoNumeric(); // initiate autoNumeric with defaults\n * $(someSelector).autoNumeric({option}); // initiate autoNumeric with options\n * options passes as a parameter example '{aSep: '.', aDec: ',', aSign: '€ '}\n */\n init: function (options) {\n return this.each(function () {\n var $this = $(this),\n settings = $this.data('autoNumeric'), /** attempt to grab 'autoNumeric' settings, if they don't exist returns \"undefined\". */\n tagData = $this.data(), /** attempt to grab HTML5 data, if they don't exist we'll get \"undefined\".*/\n $input = $this.is('input[type=text], input[type=hidden], input[type=tel], input:not([type])');\n if (typeof settings !== 'object') { /** If we couldn't grab settings, create them from defaults and passed options. */\n settings = $.extend({}, $.fn.autoNumeric.defaults, tagData, options, {\n aNum: '0123456789',\n hasFocus: false,\n removeBrackets: false,\n runOnce: false,\n tagList: ['b', 'caption', 'cite', 'code', 'dd', 'del', 'div', 'dfn', 'dt', 'em', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ins', 'kdb', 'label', 'li', 'output', 'p', 'q', 's', 'sample', 'span', 'strong', 'td', 'th', 'u', 'var']\n }); /** Merge defaults, tagData and options */\n if (settings.aDec === settings.aSep) {\n $.error(\"autoNumeric will not function properly when the decimal character aDec: '\" + settings.aDec + \"' and thousand separator aSep: '\" + settings.aSep + \"' are the same character\");\n }\n $this.data('autoNumeric', settings); /** Save our new settings */\n } else {\n return this;\n }\n var holder = getHolder($this, settings);\n if (!$input && $this.prop('tagName').toLowerCase() === 'input') { /** checks for non-supported input types */\n $.error('The input type \"' + $this.prop('type') + '\" is not supported by autoNumeric()');\n\n }\n if ($.inArray($this.prop('tagName').toLowerCase(), settings.tagList) === -1 && $this.prop('tagName').toLowerCase() !== 'input') {\n $.error(\"The <\" + $this.prop('tagName').toLowerCase() + \"> is not supported by autoNumeric()\");\n\n }\n if (settings.runOnce === false && settings.aForm) { /** routine to format default value on page load */\n if ($input) {\n var setValue = true;\n if ($this[0].value === '' && settings.wEmpty === 'empty') {\n $this[0].value = '';\n setValue = false;\n }\n if ($this[0].value === '' && settings.wEmpty === 'sign') {\n $this[0].value = settings.aSign;\n setValue = false;\n }\n /** checks for page reload from back button\n * also checks for ASP.net form post back\n * the following HTML data attribute is REQUIRED (data-an-default=\"same value as the value attribute\")\n * example: \n */\n if (setValue && $this.val() !== '' && ((settings.anDefault === null && $this[0].value === $this.prop('defaultValue')) || (settings.anDefault !== null && settings.anDefault.toString() === $this.val()))) {\n $this.autoNumeric('set', $this.val());\n }\n }\n if ($.inArray($this.prop('tagName').toLowerCase(), settings.tagList) !== -1 && $this.text() !== '') {\n $this.autoNumeric('set', $this.text());\n }\n }\n settings.runOnce = true;\n if ($this.is('input[type=text], input[type=hidden], input[type=tel], input:not([type])')) { /**added hidden type */\n $this.on('keydown.autoNumeric', function (e) {\n holder = getHolder($this);\n if (holder.settings.aDec === holder.settings.aSep) {\n $.error(\"autoNumeric will not function properly when the decimal character aDec: '\" + holder.settings.aDec + \"' and thousand separator aSep: '\" + holder.settings.aSep + \"' are the same character\");\n }\n if (holder.that.readOnly) {\n holder.processed = true;\n return true;\n }\n /** The below streamed code / comment allows the \"enter\" keydown to throw a change() event */\n /** if (e.keyCode === 13 && holder.inVal !== $this.val()){\n $this.change();\n holder.inVal = $this.val();\n }*/\n holder.init(e);\n if (holder.skipAllways(e)) {\n holder.processed = true;\n return true;\n }\n if (holder.processAllways()) {\n holder.processed = true;\n holder.formatQuick();\n e.preventDefault();\n return false;\n }\n holder.formatted = false;\n return true;\n });\n $this.on('keypress.autoNumeric', function (e) {\n holder = getHolder($this);\n var processed = holder.processed;\n holder.init(e);\n if (holder.skipAllways(e)) {\n return true;\n }\n if (processed) {\n e.preventDefault();\n return false;\n }\n if (holder.processAllways() || holder.processKeypress()) {\n holder.formatQuick();\n e.preventDefault();\n return false;\n }\n holder.formatted = false;\n });\n $this.on('keyup.autoNumeric', function (e) {\n holder = getHolder($this);\n holder.init(e);\n var skip = holder.skipAllways(e);\n holder.kdCode = 0;\n delete holder.valuePartsBeforePaste;\n if ($this[0].value === holder.settings.aSign) { /** added to properly place the caret when only the currency is present */\n if (holder.settings.pSign === 's') {\n setElementSelection(this, 0, 0);\n } else {\n setElementSelection(this, holder.settings.aSign.length, holder.settings.aSign.length);\n }\n }\n if (skip) {\n return true;\n }\n if (this.value === '') {\n return true;\n }\n if (!holder.formatted) {\n holder.formatQuick();\n }\n });\n $this.on('focusin.autoNumeric', function () {\n holder = getHolder($this);\n var $settings = holder.settingsClone;\n $settings.hasFocus = true;\n if ($settings.nBracket !== null) {\n var checkVal = $this.val();\n $this.val(negativeBracket(checkVal, $settings));\n }\n holder.inVal = $this.val();\n var onEmpty = checkEmpty(holder.inVal, $settings, true);\n if (onEmpty !== null && onEmpty !== '') {\n $this.val(onEmpty);\n }\n });\n $this.on('focusout.autoNumeric', function () {\n holder = getHolder($this);\n var $settings = holder.settingsClone,\n value = $this.val(),\n origValue = value;\n $settings.hasFocus = false;\n var strip_zero = ''; /** added to control leading zero */\n if ($settings.lZero === 'allow') { /** added to control leading zero */\n $settings.allowLeading = false;\n strip_zero = 'leading';\n }\n if (value !== '') {\n value = autoStrip(value, $settings, strip_zero);\n if (checkEmpty(value, $settings) === null && autoCheck(value, $settings, $this[0])) {\n value = fixNumber(value, $settings.aDec, $settings.aNeg);\n value = autoRound(value, $settings);\n value = presentNumber(value, $settings.aDec, $settings.aNeg);\n } else {\n value = '';\n }\n }\n var groupedValue = checkEmpty(value, $settings, false);\n if (groupedValue === null) {\n groupedValue = autoGroup(value, $settings);\n }\n if (groupedValue !== holder.inVal || groupedValue !== origValue) {\n $this.val(groupedValue);\n $this.change();\n delete holder.inVal;\n }\n });\n }\n });\n },\n\n /**\n * method to remove settings and stop autoNumeric() - does not remove the formatting\n * $(someSelector).autoNumeric('destroy'); // destroy autoNumeric\n * no parameters accepted\n */\n destroy: function () {\n return $(this).each(function () {\n var $this = $(this);\n $this.off('.autoNumeric');\n $this.removeData('autoNumeric');\n });\n },\n\n /**\n * method to update settings - can be call as many times\n * $(someSelector).autoNumeric('update', {options}); // updates the settings\n * options passes as a parameter example '{aSep: '.', aDec: ',', aSign: '€ '}\n */\n update: function (options) {\n return $(this).each(function () {\n var $this = autoGet($(this)),\n settings = $this.data('autoNumeric');\n if (typeof settings !== 'object') {\n $.error(\"You must initialize autoNumeric('init', {options}) prior to calling the 'update' method\");\n }\n var strip = $this.autoNumeric('get');\n settings = $.extend(settings, options);\n getHolder($this, settings, true);\n if (settings.aDec === settings.aSep) {\n $.error(\"autoNumeric will not function properly when the decimal character aDec: '\" + settings.aDec + \"' and thousand separator aSep: '\" + settings.aSep + \"' are the same character\");\n }\n $this.data('autoNumeric', settings);\n if ($this.val() !== '' || $this.text() !== '') {\n return $this.autoNumeric('set', strip);\n }\n return;\n });\n },\n\n /**\n * method to format value sent as a parameter \"\"\n * $(someSelector).autoNumeric('set', 'value'}); // formats the value being passed\n * value passed as a string - can be a integer '1234' or double '1234.56789'\n * must contain only numbers and one decimal (period) character\n */\n set: function (valueIn) {\n if (valueIn === null) {\n return;\n }\n return $(this).each(function () {\n var $this = autoGet($(this)),\n settings = $this.data('autoNumeric'),\n value = valueIn.toString(),\n testValue = valueIn.toString(),\n $input = $this.is('input[type=text], input[type=hidden], input[type=tel], input:not([type])');\n if (typeof settings !== 'object') {\n $.error(\"You must initialize autoNumeric('init', {options}) prior to calling the 'set' method\");\n }\n /** allows locale decimal separator to be a comma */\n if ((testValue === $this.attr('value') || testValue === $this.text()) && settings.runOnce === false) {\n value = value.replace(',', '.');\n }\n if (!$.isNumeric(+value)) {\n $.error(\"The value (\" + value + \") being 'set' is not numeric and has caused a error to be thrown\");\n }\n value = checkValue(value, settings);\n settings.setEvent = true;\n value.toString();\n if (value !== '') {\n value = autoRound(value, settings);\n }\n value = presentNumber(value, settings.aDec, settings.aNeg);\n if (!autoCheck(value, settings)) {\n value = autoRound('', settings);\n }\n value = autoGroup(value, settings);\n if ($input) {\n return $this.val(value);\n }\n if ($.inArray($this.prop('tagName').toLowerCase(), settings.tagList) !== -1) {\n return $this.text(value);\n }\n return false;\n });\n },\n\n /**\n * method to get the unformatted that accepts up to one parameter\n * $(someSelector).autoNumeric('get'); no parameters accepted\n * values returned as ISO numeric string \"1234.56\" where the decimal character is a period\n * only the first element in the selector is returned\n */\n get: function () {\n var $this = autoGet($(this)),\n settings = $this.data('autoNumeric');\n if (typeof settings !== 'object') {\n $.error(\"You must initialize autoNumeric('init', {options}) prior to calling the 'get' method\");\n }\n var getValue = '';\n /** determine the element type then use .eq(0) selector to grab the value of the first element in selector */\n if ($this.is('input[type=text], input[type=hidden], input[type=tel], input:not([type])')) { /**added hidden type */\n getValue = $this.eq(0).val();\n } else if ($.inArray($this.prop('tagName').toLowerCase(), settings.tagList) !== -1) {\n getValue = $this.eq(0).text();\n } else {\n $.error(\"The <\" + $this.prop('tagName').toLowerCase() + \"> is not supported by autoNumeric()\");\n }\n if ((getValue === '' && settings.wEmpty === 'empty') || (getValue === settings.aSign && (settings.wEmpty === 'sign' || settings.wEmpty === 'empty'))) {\n return '';\n }\n if (getValue !== '' && settings.nBracket !== null) {\n settings.removeBrackets = true;\n getValue = negativeBracket(getValue, settings);\n settings.removeBrackets = false;\n }\n if (settings.runOnce || settings.aForm === false) {\n getValue = autoStrip(getValue, settings);\n }\n getValue = fixNumber(getValue, settings.aDec, settings.aNeg);\n if (+getValue === 0 && settings.lZero !== 'keep') {\n getValue = '0';\n }\n if (settings.lZero === 'keep') {\n return getValue;\n }\n getValue = checkValue(getValue, settings);\n return getValue; /** returned Numeric String */\n },\n\n /**\n * The 'getString' method used jQuerys .serialize() method that creates a text string in standard URL-encoded notation\n * it then loops through the string and un-formats the inputs with autoNumeric\n * $(someSelector).autoNumeric('getString'); no parameter accepted\n * values returned as ISO numeric string \"1234.56\" where the decimal character is a period\n */\n getString: function () {\n var isAutoNumeric = false,\n $this = autoGet($(this)),\n formFields = $this.serialize(),\n formParts = formFields.split('&'),\n formIndex = $('form').index($this),\n allFormElements = $('form:eq(' + formIndex + ')'),\n aiIndex = [], /* all input index */\n scIndex = [], /* successful control index */\n rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, /* from jQuery serialize method */\n rsubmittable = /^(?:input|select|textarea|keygen)/i, /* from jQuery serialize method */\n rcheckableType = /^(?:checkbox|radio)$/i,\n rnonAutoNumericTypes = /^(?:button|checkbox|color|date|datetime|datetime-local|email|file|image|month|number|password|radio|range|reset|search|submit|time|url|week)/i,\n count = 0;\n /*jslint unparam: true*/\n /* index of successful elements */\n $.each(allFormElements[0], function (i, field) {\n if (field.name !== '' && rsubmittable.test(field.localName) && !rsubmitterTypes.test(field.type) && !field.disabled && (field.checked || !rcheckableType.test(field.type))) {\n scIndex.push(count);\n count = count + 1;\n } else {\n scIndex.push(-1);\n }\n });\n /* index of all inputs tags except checkbox */\n count = 0;\n $.each(allFormElements[0], function (i, field) {\n if (field.localName === 'input' && (field.type === '' || field.type === 'text' || field.type === 'hidden' || field.type === 'tel')) {\n aiIndex.push(count);\n count = count + 1;\n } else {\n aiIndex.push(-1);\n if (field.localName === 'input' && rnonAutoNumericTypes.test(field.type)) {\n count = count + 1;\n }\n }\n });\n $.each(formParts, function (i, miniParts) {\n miniParts = formParts[i].split('=');\n var scElement = $.inArray(i, scIndex);\n if (scElement > -1 && aiIndex[scElement] > -1) {\n var testInput = $('form:eq(' + formIndex + ') input:eq(' + aiIndex[scElement] + ')'),\n settings = testInput.data('autoNumeric');\n if (typeof settings === 'object') {\n if (miniParts[1] !== null) {\n miniParts[1] = $('form:eq(' + formIndex + ') input:eq(' + aiIndex[scElement] + ')').autoNumeric('get').toString();\n formParts[i] = miniParts.join('=');\n isAutoNumeric = true;\n }\n }\n }\n });\n /*jslint unparam: false*/\n if (!isAutoNumeric) {\n $.error(\"You must initialize autoNumeric('init', {options}) prior to calling the 'getString' method\");\n }\n return formParts.join('&');\n },\n\n /**\n * The 'getString' method used jQuerys .serializeArray() method that creates array or objects that can be encoded as a JSON string\n * it then loops through the string and un-formats the inputs with autoNumeric\n * $(someSelector).autoNumeric('getArray'); no parameter accepted\n * values returned as ISO numeric string \"1234.56\" where the decimal character is a period\n */\n getArray: function () {\n var isAutoNumeric = false,\n $this = autoGet($(this)),\n formFields = $this.serializeArray(),\n formIndex = $('form').index($this),\n allFormElements = $('form:eq(' + formIndex + ')'),\n aiIndex = [], /* all input index */\n scIndex = [], /* successful control index */\n rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, /* from jQuery serialize method */\n rsubmittable = /^(?:input|select|textarea|keygen)/i, /* from jQuery serialize method */\n rcheckableType = /^(?:checkbox|radio)$/i,\n rnonAutoNumericTypes = /^(?:button|checkbox|color|date|datetime|datetime-local|email|file|image|month|number|password|radio|range|reset|search|submit|time|url|week)/i,\n count = 0;\n /*jslint unparam: true*/\n /* index of successful elements */\n $.each(allFormElements[0], function (i, field) {\n if (field.name !== '' && rsubmittable.test(field.localName) && !rsubmitterTypes.test(field.type) && !field.disabled && (field.checked || !rcheckableType.test(field.type))) {\n scIndex.push(count);\n count = count + 1;\n } else {\n scIndex.push(-1);\n }\n });\n /* index of all inputs tags */\n count = 0;\n $.each(allFormElements[0], function (i, field) {\n if (field.localName === 'input' && (field.type === '' || field.type === 'text' || field.type === 'hidden' || field.type === 'tel')) {\n aiIndex.push(count);\n count = count + 1;\n } else {\n aiIndex.push(-1);\n if (field.localName === 'input' && rnonAutoNumericTypes.test(field.type)) {\n count = count + 1;\n }\n }\n });\n $.each(formFields, function (i, field) {\n var scElement = $.inArray(i, scIndex);\n if (scElement > -1 && aiIndex[scElement] > -1) {\n var testInput = $('form:eq(' + formIndex + ') input:eq(' + aiIndex[scElement] + ')'),\n settings = testInput.data('autoNumeric');\n if (typeof settings === 'object') {\n field.value = $('form:eq(' + formIndex + ') input:eq(' + aiIndex[scElement] + ')').autoNumeric('get').toString();\n isAutoNumeric = true;\n }\n }\n });\n /*jslint unparam: false*/\n if (!isAutoNumeric) {\n $.error(\"None of the successful form inputs are initialized by autoNumeric.\");\n }\n return formFields;\n },\n\n /**\n * The 'getSteetings returns the object with autoNumeric settings for those who need to look under the hood\n * $(someSelector).autoNumeric('getSettings'); // no parameters accepted\n * $(someSelector).autoNumeric('getSettings').aDec; // return the aDec setting as a string - ant valid setting can be used\n */\n getSettings: function () {\n var $this = autoGet($(this));\n return $this.eq(0).data('autoNumeric');\n }\n };\n\n /**\n * autoNumeric function\n */\n $.fn.autoNumeric = function (method) {\n if (methods[method]) {\n return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));\n }\n if (typeof method === 'object' || !method) {\n return methods.init.apply(this, arguments);\n }\n $.error('Method \"' + method + '\" is not supported by autoNumeric()');\n };\n\n /**\n * Defaults are public - these can be overridden by the following:\n * HTML5 data attributes\n * Options passed by the 'init' or 'update' methods\n * Use jQuery's $.extend method - great way to pass ASP.NET current culture settings\n */\n $.fn.autoNumeric.defaults = {\n /** allowed thousand separator characters\n * comma = ','\n * period \"full stop\" = '.'\n * apostrophe is escaped = '\\''\n * space = ' '\n * none = ''\n * NOTE: do not use numeric characters\n */\n aSep: ',',\n /** digital grouping for the thousand separator used in Format\n * dGroup: '2', results in 99,99,99,999 common in India for values less than 1 billion and greater than -1 billion\n * dGroup: '3', results in 999,999,999 default\n * dGroup: '4', results in 9999,9999,9999 used in some Asian countries\n */\n dGroup: '3',\n /** allowed decimal separator characters\n * period \"full stop\" = '.'\n * comma = ','\n */\n aDec: '.',\n /** allow to declare alternative decimal separator which is automatically replaced by aDec\n * developed for countries the use a comma ',' as the decimal character\n * and have keyboards\\numeric pads that have a period 'full stop' as the decimal characters (Spain is an example)\n */\n altDec: null,\n /** allowed currency symbol\n * Must be in quotes aSign: '$', a space is allowed aSign: '$ '\n */\n aSign: '',\n /** placement of currency sign\n * for prefix pSign: 'p',\n * for suffix pSign: 's',\n */\n pSign: 'p',\n /** maximum possible value\n * value must be enclosed in quotes and use the period for the decimal point\n * value must be larger than vMin\n */\n vMax: '9999999999999.99',\n /** minimum possible value\n * value must be enclosed in quotes and use the period for the decimal point\n * value must be smaller than vMax\n */\n vMin: '-9999999999999.99',\n /** max number of decimal places = used to override decimal places set by the vMin & vMax values\n * value must be enclosed in quotes example mDec: '3',\n * This can also set the value via a call back function mDec: 'css:#\n */\n mDec: null,\n /** method used for rounding\n * mRound: 'S', Round-Half-Up Symmetric (default)\n * mRound: 'A', Round-Half-Up Asymmetric\n * mRound: 's', Round-Half-Down Symmetric (lower case s)\n * mRound: 'a', Round-Half-Down Asymmetric (lower case a)\n * mRound: 'B', Round-Half-Even \"Bankers Rounding\"\n * mRound: 'U', Round Up \"Round-Away-From-Zero\"\n * mRound: 'D', Round Down \"Round-Toward-Zero\" - same as truncate\n * mRound: 'C', Round to Ceiling \"Toward Positive Infinity\"\n * mRound: 'F', Round to Floor \"Toward Negative Infinity\"\n */\n mRound: 'S',\n /** controls decimal padding\n * aPad: true - always Pad decimals with zeros\n * aPad: false - does not pad with zeros.\n * aPad: `some number` - pad decimals with zero to number different from mDec\n * thanks to Jonas Johansson for the suggestion\n */\n aPad: true,\n /** places brackets on negative value -$ 999.99 to (999.99)\n * visible only when the field does NOT have focus the left and right symbols should be enclosed in quotes and seperated by a comma\n * nBracket: null, nBracket: '(,)', nBracket: '[,]', nBracket: '<,>' or nBracket: '{,}'\n */\n nBracket: null,\n /** Displayed on empty string\n * wEmpty: 'empty', - input can be blank\n * wEmpty: 'zero', - displays zero\n * wEmpty: 'sign', - displays the currency sign\n */\n wEmpty: 'empty',\n /** controls leading zero behavior\n * lZero: 'allow', - allows leading zeros to be entered. Zeros will be truncated when entering additional digits. On focusout zeros will be deleted.\n * lZero: 'deny', - allows only one leading zero on values less than one\n * lZero: 'keep', - allows leading zeros to be entered. on fousout zeros will be retained.\n */\n lZero: 'allow',\n /** determine if the select all keyboard command will select\n * the complete input text or only the input numeric value\n * if the currency symbol is between the numeric value and the negative sign only the numeric value will sellected\n */\n sNumber: true,\n /** determine if the default value will be formatted on page ready.\n * true = automatically formats the default value on page ready\n * false = will not format the default value\n */\n aForm: true,\n /** helper option for ASP.NET postback\n * should be the value of the unformatted default value\n * examples:\n * no default value='' {anDefault: ''}\n * value=1234.56 {anDefault: '1234.56'}\n */\n anDefault: null\n };\n}(jQuery));",
"// ==ClosureCompiler==\n// @compilation_level SIMPLE_OPTIMIZATIONS\n\n/**\n * @license jqGrid 4.7.0 - jQuery Grid\n * Copyright (c) 2008, Tony Tomov, tony@trirand.com\n * Dual licensed under the MIT and GPL licenses\n * http://www.opensource.org/licenses/mit-license.php\n * http://www.gnu.org/licenses/gpl-2.0.html\n * Date: 2014-12-08\n */\n//jsHint options\n/*jshint evil:true, eqeqeq:false, eqnull:true, devel:true */\n/*global jQuery */\n\n(function ($) {\n\"use strict\";\n$.jgrid = $.jgrid || {};\n$.extend($.jgrid,{\n\tversion : \"4.7.0\",\n\thtmlDecode : function(value){\n\t\tif(value && (value===' ' || value===' ' || (value.length===1 && value.charCodeAt(0)===160))) { return \"\";}\n\t\treturn !value ? value : String(value).replace(/>/g, \">\").replace(/</g, \"<\").replace(/"/g, '\"').replace(/&/g, \"&\");\t\t\n\t},\n\thtmlEncode : function (value){\n\t\treturn !value ? value : String(value).replace(/&/g, \"&\").replace(/\\\"/g, \""\").replace(//g, \">\");\n\t},\n\tformat : function(format){ //jqgformat\n\t\tvar args = $.makeArray(arguments).slice(1);\n\t\tif(format==null) { format = \"\"; }\n\t\treturn format.replace(/\\{(\\d+)\\}/g, function(m, i){\n\t\t\treturn args[i];\n\t\t});\n\t},\n\tmsie : navigator.appName === 'Microsoft Internet Explorer',\n\tmsiever : function () {\n\t\tvar rv = -1;\n\t\tvar ua = navigator.userAgent;\n\t\tvar re = new RegExp(\"MSIE ([0-9]{1,}[\\.0-9]{0,})\");\n\t\tif (re.exec(ua) != null) {\n\t\t\trv = parseFloat( RegExp.$1 );\n\t\t}\n\t\treturn rv;\n\t},\n\tgetCellIndex : function (cell) {\n\t\tvar c = $(cell);\n\t\tif (c.is('tr')) { return -1; }\n\t\tc = (!c.is('td') && !c.is('th') ? c.closest(\"td,th\") : c)[0];\n\t\tif ($.jgrid.msie) { return $.inArray(c, c.parentNode.cells); }\n\t\treturn c.cellIndex;\n\t},\n\tstripHtml : function(v) {\n\t\tv = String(v);\n\t\tvar regexp = /<(\"[^\"]*\"|'[^']*'|[^'\">])*>/gi;\n\t\tif (v) {\n\t\t\tv = v.replace(regexp,\"\");\n\t\t\treturn (v && v !== ' ' && v !== ' ') ? v.replace(/\\\"/g,\"'\") : \"\";\n\t\t} \n\t\t\treturn v;\n\t},\n\tstripPref : function (pref, id) {\n\t\tvar obj = $.type( pref );\n\t\tif( obj === \"string\" || obj === \"number\") {\n\t\t\tpref = String(pref);\n\t\t\tid = pref !== \"\" ? String(id).replace(String(pref), \"\") : id;\n\t\t}\n\t\treturn id;\n\t},\n\tparse : function(jsonString) {\n\t\tvar js = jsonString;\n\t\tif (js.substr(0,9) === \"while(1);\") { js = js.substr(9); }\n\t\tif (js.substr(0,2) === \"/*\") { js = js.substr(2,js.length-4); }\n\t\tif(!js) { js = \"{}\"; }\n\t\treturn ($.jgrid.useJSON===true && typeof JSON === 'object' && typeof JSON.parse === 'function') ?\n\t\t\tJSON.parse(js) :\n\t\t\teval('(' + js + ')');\n\t},\n\tparseDate : function(format, date, newformat, opts) {\n\t\tvar\ttoken = /\\\\.|[dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU]/g,\n\t\ttimezone = /\\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[-+]\\d{4})?)\\b/g,\n\t\ttimezoneClip = /[^-+\\dA-Z]/g,\n\t\tmsDateRegExp = new RegExp(\"^\\/Date\\\\((([-+])?[0-9]+)(([-+])([0-9]{2})([0-9]{2}))?\\\\)\\/$\"),\n\t\tmsMatch = ((typeof date === 'string') ? date.match(msDateRegExp): null),\n\t\tpad = function (value, length) {\n\t\t\tvalue = String(value);\n\t\t\tlength = parseInt(length,10) || 2;\n\t\t\twhile (value.length < length) { value = '0' + value; }\n\t\t\treturn value;\n\t\t},\n\t\tts = {m : 1, d : 1, y : 1970, h : 0, i : 0, s : 0, u:0},\n\t\ttimestamp=0, dM, k,hl,\n\t\th12to24 = function(ampm, h){\n\t\t\tif (ampm === 0){ if (h === 12) { h = 0;} }\n\t\t\telse { if (h !== 12) { h += 12; } }\n\t\t\treturn h;\n\t\t},\n\t\toffset =0;\n\t\tif(opts === undefined) {\n\t\t\topts = $.jgrid.formatter.date;\n\t\t}\n\t\t// old lang files\n\t\tif(opts.parseRe === undefined ) {\n\t\t\topts.parseRe = /[#%\\\\\\/:_;.,\\t\\s-]/;\n\t\t}\n\t\tif( opts.masks.hasOwnProperty(format) ) { format = opts.masks[format]; }\n\t\tif(date && date != null) {\n\t\t\tif( !isNaN( date - 0 ) && String(format).toLowerCase() === \"u\") {\n\t\t\t\t//Unix timestamp\n\t\t\t\ttimestamp = new Date( parseFloat(date)*1000 );\n\t\t\t} else if(date.constructor === Date) {\n\t\t\t\ttimestamp = date;\n\t\t\t\t// Microsoft date format support\n\t\t\t} else if( msMatch !== null ) {\n\t\t\t\ttimestamp = new Date(parseInt(msMatch[1], 10));\n\t\t\t\tif (msMatch[3]) {\n\t\t\t\t\toffset = Number(msMatch[5]) * 60 + Number(msMatch[6]);\n\t\t\t\t\toffset *= ((msMatch[4] === '-') ? 1 : -1);\n\t\t\t\t\toffset -= timestamp.getTimezoneOffset();\n\t\t\t\t\ttimestamp.setTime(Number(Number(timestamp) + (offset * 60 * 1000)));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t//Support ISO8601Long that have Z at the end to indicate UTC timezone\n\t\t\t\tif(opts.srcformat === 'ISO8601Long' && date.charAt(date.length - 1) === 'Z') {\n\t\t\t\t\toffset -= (new Date()).getTimezoneOffset();\n\t\t\t\t}\n\t\t\t\tdate = String(date).replace(/\\T/g,\"#\").replace(/\\t/,\"%\").split(opts.parseRe);\n\t\t\t\tformat = format.replace(/\\T/g,\"#\").replace(/\\t/,\"%\").split(opts.parseRe);\n\t\t\t\t// parsing for month names\n\t\t\t\tfor(k=0,hl=format.length;k 11){date[k] = dM+1-12; ts.m = date[k];}\n\t\t\t\t\t}\n\t\t\t\t\tif(format[k] === 'a') {\n\t\t\t\t\t\tdM = $.inArray(date[k],opts.AmPm);\n\t\t\t\t\t\tif(dM !== -1 && dM < 2 && date[k] === opts.AmPm[dM]){\n\t\t\t\t\t\t\tdate[k] = dM;\n\t\t\t\t\t\t\tts.h = h12to24(date[k], ts.h);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif(format[k] === 'A') {\n\t\t\t\t\t\tdM = $.inArray(date[k],opts.AmPm);\n\t\t\t\t\t\tif(dM !== -1 && dM > 1 && date[k] === opts.AmPm[dM]){\n\t\t\t\t\t\t\tdate[k] = dM-2;\n\t\t\t\t\t\t\tts.h = h12to24(date[k], ts.h);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (format[k] === 'g') {\n\t\t\t\t\t\tts.h = parseInt(date[k], 10);\n\t\t\t\t\t}\n\t\t\t\t\tif(date[k] !== undefined) {\n\t\t\t\t\t\tts[format[k].toLowerCase()] = parseInt(date[k],10);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif(ts.f) {ts.m = ts.f;}\n\t\t\t\tif( ts.m === 0 && ts.y === 0 && ts.d === 0) {\n\t\t\t\t\treturn \" \" ;\n\t\t\t\t}\n\t\t\t\tts.m = parseInt(ts.m,10)-1;\n\t\t\t\tvar ty = ts.y;\n\t\t\t\tif (ty >= 70 && ty <= 99) {ts.y = 1900+ts.y;}\n\t\t\t\telse if (ty >=0 && ty <=69) {ts.y= 2000+ts.y;}\n\t\t\t\ttimestamp = new Date(ts.y, ts.m, ts.d, ts.h, ts.i, ts.s, ts.u);\n\t\t\t\t//Apply offset to show date as local time.\n\t\t\t\tif(offset > 0) {\n\t\t\t\t\ttimestamp.setTime(Number(Number(timestamp) + (offset * 60 * 1000)));\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\ttimestamp = new Date(ts.y, ts.m, ts.d, ts.h, ts.i, ts.s, ts.u);\n\t\t}\n\t\tif(opts.userLocalTime && offset === 0) {\n\t\t\toffset -= (new Date()).getTimezoneOffset();\n\t\t\tif( offset > 0 ) {\n\t\t\t\ttimestamp.setTime(Number(Number(timestamp) + (offset * 60 * 1000)));\n\t\t\t}\n\t\t}\n\t\tif( newformat === undefined ) {\n\t\t\treturn timestamp;\n\t\t}\n\t\tif( opts.masks.hasOwnProperty(newformat) ) {\n\t\t\tnewformat = opts.masks[newformat];\n\t\t} else if ( !newformat ) {\n\t\t\tnewformat = 'Y-m-d';\n\t\t}\n\t\tvar \n\t\t\tG = timestamp.getHours(),\n\t\t\ti = timestamp.getMinutes(),\n\t\t\tj = timestamp.getDate(),\n\t\t\tn = timestamp.getMonth() + 1,\n\t\t\to = timestamp.getTimezoneOffset(),\n\t\t\ts = timestamp.getSeconds(),\n\t\t\tu = timestamp.getMilliseconds(),\n\t\t\tw = timestamp.getDay(),\n\t\t\tY = timestamp.getFullYear(),\n\t\t\tN = (w + 6) % 7 + 1,\n\t\t\tz = (new Date(Y, n - 1, j) - new Date(Y, 0, 1)) / 86400000,\n\t\t\tflags = {\n\t\t\t\t// Day\n\t\t\t\td: pad(j),\n\t\t\t\tD: opts.dayNames[w],\n\t\t\t\tj: j,\n\t\t\t\tl: opts.dayNames[w + 7],\n\t\t\t\tN: N,\n\t\t\t\tS: opts.S(j),\n\t\t\t\t//j < 11 || j > 13 ? ['st', 'nd', 'rd', 'th'][Math.min((j - 1) % 10, 3)] : 'th',\n\t\t\t\tw: w,\n\t\t\t\tz: z,\n\t\t\t\t// Week\n\t\t\t\tW: N < 5 ? Math.floor((z + N - 1) / 7) + 1 : Math.floor((z + N - 1) / 7) || ((new Date(Y - 1, 0, 1).getDay() + 6) % 7 < 4 ? 53 : 52),\n\t\t\t\t// Month\n\t\t\t\tF: opts.monthNames[n - 1 + 12],\n\t\t\t\tm: pad(n),\n\t\t\t\tM: opts.monthNames[n - 1],\n\t\t\t\tn: n,\n\t\t\t\tt: '?',\n\t\t\t\t// Year\n\t\t\t\tL: '?',\n\t\t\t\to: '?',\n\t\t\t\tY: Y,\n\t\t\t\ty: String(Y).substring(2),\n\t\t\t\t// Time\n\t\t\t\ta: G < 12 ? opts.AmPm[0] : opts.AmPm[1],\n\t\t\t\tA: G < 12 ? opts.AmPm[2] : opts.AmPm[3],\n\t\t\t\tB: '?',\n\t\t\t\tg: G % 12 || 12,\n\t\t\t\tG: G,\n\t\t\t\th: pad(G % 12 || 12),\n\t\t\t\tH: pad(G),\n\t\t\t\ti: pad(i),\n\t\t\t\ts: pad(s),\n\t\t\t\tu: u,\n\t\t\t\t// Timezone\n\t\t\t\te: '?',\n\t\t\t\tI: '?',\n\t\t\t\tO: (o > 0 ? \"-\" : \"+\") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4),\n\t\t\t\tP: '?',\n\t\t\t\tT: (String(timestamp).match(timezone) || [\"\"]).pop().replace(timezoneClip, \"\"),\n\t\t\t\tZ: '?',\n\t\t\t\t// Full Date/Time\n\t\t\t\tc: '?',\n\t\t\t\tr: '?',\n\t\t\t\tU: Math.floor(timestamp / 1000)\n\t\t\t};\n\t\treturn newformat.replace(token, function ($0) {\n\t\t\treturn flags.hasOwnProperty($0) ? flags[$0] : $0.substring(1);\n\t\t});\n\t},\n\tjqID : function(sid){\n\t\treturn String(sid).replace(/[!\"#$%&'()*+,.\\/:; <=>?@\\[\\\\\\]\\^`{|}~]/g,\"\\\\$&\");\n\t},\n\tguid : 1,\n\tuidPref: 'jqg',\n\trandId : function( prefix )\t{\n\t\treturn (prefix || $.jgrid.uidPref) + ($.jgrid.guid++);\n\t},\n\tgetAccessor : function(obj, expr) {\n\t\tvar ret,p,prm = [], i;\n\t\tif( typeof expr === 'function') { return expr(obj); }\n\t\tret = obj[expr];\n\t\tif(ret===undefined) {\n\t\t\ttry {\n\t\t\t\tif ( typeof expr === 'string' ) {\n\t\t\t\t\tprm = expr.split('.');\n\t\t\t\t}\n\t\t\t\ti = prm.length;\n\t\t\t\tif( i ) {\n\t\t\t\t\tret = obj;\n\t\t\t\t\twhile (ret && i--) {\n\t\t\t\t\t\tp = prm.shift();\n\t\t\t\t\t\tret = ret[p];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch (e) {}\n\t\t}\n\t\treturn ret;\n\t},\n\tgetXmlData: function (obj, expr, returnObj) {\n\t\tvar ret, m = typeof expr === 'string' ? expr.match(/^(.*)\\[(\\w+)\\]$/) : null;\n\t\tif (typeof expr === 'function') { return expr(obj); }\n\t\tif (m && m[2]) {\n\t\t\t// m[2] is the attribute selector\n\t\t\t// m[1] is an optional element selector\n\t\t\t// examples: \"[id]\", \"rows[page]\"\n\t\t\treturn m[1] ? $(m[1], obj).attr(m[2]) : $(obj).attr(m[2]);\n\t\t}\n\t\t\tret = $(expr, obj);\n\t\t\tif (returnObj) { return ret; }\n\t\t\t//$(expr, obj).filter(':last'); // we use ':last' to be more compatible with old version of jqGrid\n\t\t\treturn ret.length > 0 ? $(ret).text() : undefined;\n\t},\n\tcellWidth : function () {\n\t\tvar $testDiv = $(\"\"),\n\t\ttestCell = $testDiv.appendTo(\"body\")\n\t\t\t.find(\"td\")\n\t\t\t.width();\n\t\t$testDiv.remove();\n\t\treturn Math.abs(testCell-5) > 0.1;\n\t},\n\tcell_width : true,\n\tajaxOptions: {},\n\tfrom : function(source){\n\t\t// Original Author Hugo Bonacci\n\t\t// License MIT http://jlinq.codeplex.com/license\n\t\tvar QueryObject=function(d,q){\n\t\tif(typeof d===\"string\"){\n\t\t\td=$.data(d);\n\t\t}\n\t\tvar self=this,\n\t\t_data=d,\n\t\t_usecase=true,\n\t\t_trim=false,\n\t\t_query=q,\n\t\t_stripNum = /[\\$,%]/g,\n\t\t_lastCommand=null,\n\t\t_lastField=null,\n\t\t_orDepth=0,\n\t\t_negate=false,\n\t\t_queuedOperator=\"\",\n\t\t_sorting=[],\n\t\t_useProperties=true;\n\t\tif(typeof d===\"object\"&&d.push) {\n\t\t\tif(d.length>0){\n\t\t\t\tif(typeof d[0]!==\"object\"){\n\t\t\t\t\t_useProperties=false;\n\t\t\t\t}else{\n\t\t\t\t\t_useProperties=true;\n\t\t\t\t}\n\t\t\t}\n\t\t}else{\n\t\t\tthrow \"data provides is not an array\";\n\t\t}\n\t\tthis._hasData=function(){\n\t\t\treturn _data===null?false:_data.length===0?false:true;\n\t\t};\n\t\tthis._getStr=function(s){\n\t\t\tvar phrase=[];\n\t\t\tif(_trim){\n\t\t\t\tphrase.push(\"jQuery.trim(\");\n\t\t\t}\n\t\t\tphrase.push(\"String(\"+s+\")\");\n\t\t\tif(_trim){\n\t\t\t\tphrase.push(\")\");\n\t\t\t}\n\t\t\tif(!_usecase){\n\t\t\t\tphrase.push(\".toLowerCase()\");\n\t\t\t}\n\t\t\treturn phrase.join(\"\");\n\t\t};\n\t\tthis._strComp=function(val){\n\t\t\tif(typeof val===\"string\"){\n\t\t\t\treturn\".toString()\";\n\t\t\t}\n\t\t\treturn\"\";\n\t\t};\n\t\tthis._group=function(f,u){\n\t\t\treturn({field:f.toString(),unique:u,items:[]});\n\t\t};\n\t\tthis._toStr=function(phrase){\n\t\t\tif(_trim){\n\t\t\t\tphrase=$.trim(phrase);\n\t\t\t}\n\t\t\tphrase=phrase.toString().replace(/\\\\/g,'\\\\\\\\').replace(/\\\"/g,'\\\\\"');\n\t\t\treturn _usecase ? phrase : phrase.toLowerCase();\n\t\t};\n\t\tthis._funcLoop=function(func){\n\t\t\tvar results=[];\n\t\t\t$.each(_data,function(i,v){\n\t\t\t\tresults.push(func(v));\n\t\t\t});\n\t\t\treturn results;\n\t\t};\n\t\tthis._append=function(s){\n\t\t\tvar i;\n\t\t\tif(_query===null){\n\t\t\t\t_query=\"\";\n\t\t\t} else {\n\t\t\t\t_query+=_queuedOperator === \"\" ? \" && \" :_queuedOperator;\n\t\t\t}\n\t\t\tfor (i=0;i<_orDepth;i++){\n\t\t\t\t_query+=\"(\";\n\t\t\t}\n\t\t\tif(_negate){\n\t\t\t\t_query+=\"!\";\n\t\t\t}\n\t\t\t_query+=\"(\"+s+\")\";\n\t\t\t_negate=false;\n\t\t\t_queuedOperator=\"\";\n\t\t\t_orDepth=0;\n\t\t};\n\t\tthis._setCommand=function(f,c){\n\t\t\t_lastCommand=f;\n\t\t\t_lastField=c;\n\t\t};\n\t\tthis._resetNegate=function(){\n\t\t\t_negate=false;\n\t\t};\n\t\tthis._repeatCommand=function(f,v){\n\t\t\tif(_lastCommand===null){\n\t\t\t\treturn self;\n\t\t\t}\n\t\t\tif(f!==null&&v!==null){\n\t\t\t\treturn _lastCommand(f,v);\n\t\t\t}\n\t\t\tif(_lastField===null){\n\t\t\t\treturn _lastCommand(f);\n\t\t\t}\n\t\t\tif(!_useProperties){\n\t\t\t\treturn _lastCommand(f);\n\t\t\t}\n\t\t\treturn _lastCommand(_lastField,f);\n\t\t};\n\t\tthis._equals=function(a,b){\n\t\t\treturn(self._compare(a,b,1)===0);\n\t\t};\n\t\tthis._compare=function(a,b,d){\n\t\t\tvar toString = Object.prototype.toString;\n\t\t\tif( d === undefined) { d = 1; }\n\t\t\tif(a===undefined) { a = null; }\n\t\t\tif(b===undefined) { b = null; }\n\t\t\tif(a===null && b===null){\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif(a===null&&b!==null){\n\t\t\t\treturn 1;\n\t\t\t}\n\t\t\tif(a!==null&&b===null){\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif (toString.call(a) === '[object Date]' && toString.call(b) === '[object Date]') {\n\t\t\t\tif (a < b) { return -d; }\n\t\t\t\tif (a > b) { return d; }\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif(!_usecase && typeof a !== \"number\" && typeof b !== \"number\" ) {\n\t\t\t\ta=String(a);\n\t\t\t\tb=String(b);\n\t\t\t}\n\t\t\tif(ab){return d;}\n\t\t\treturn 0;\n\t\t};\n\t\tthis._performSort=function(){\n\t\t\tif(_sorting.length===0){return;}\n\t\t\t_data=self._doSort(_data,0);\n\t\t};\n\t\tthis._doSort=function(d,q){\n\t\t\tvar by=_sorting[q].by,\n\t\t\tdir=_sorting[q].dir,\n\t\t\ttype = _sorting[q].type,\n\t\t\tdfmt = _sorting[q].datefmt,\n\t\t\tsfunc = _sorting[q].sfunc;\n\t\t\tif(q===_sorting.length-1){\n\t\t\t\treturn self._getOrder(d, by, dir, type, dfmt, sfunc);\n\t\t\t}\n\t\t\tq++;\n\t\t\tvar values=self._getGroup(d,by,dir,type,dfmt), results=[], i, j, sorted;\n\t\t\tfor(i=0;i0;\n\t\t};\n\t\tthis.andNot=function(f,v,x){\n\t\t\t_negate=!_negate;\n\t\t\treturn self.and(f,v,x);\n\t\t};\n\t\tthis.orNot=function(f,v,x){\n\t\t\t_negate=!_negate;\n\t\t\treturn self.or(f,v,x);\n\t\t};\n\t\tthis.not=function(f,v,x){\n\t\t\treturn self.andNot(f,v,x);\n\t\t};\n\t\tthis.and=function(f,v,x){\n\t\t\t_queuedOperator=\" && \";\n\t\t\tif(f===undefined){\n\t\t\t\treturn self;\n\t\t\t}\n\t\t\treturn self._repeatCommand(f,v,x);\n\t\t};\n\t\tthis.or=function(f,v,x){\n\t\t\t_queuedOperator=\" || \";\n\t\t\tif(f===undefined) { return self; }\n\t\t\treturn self._repeatCommand(f,v,x);\n\t\t};\n\t\tthis.orBegin=function(){\n\t\t\t_orDepth++;\n\t\t\treturn self;\n\t\t};\n\t\tthis.orEnd=function(){\n\t\t\tif (_query !== null){\n\t\t\t\t_query+=\")\";\n\t\t\t}\n\t\t\treturn self;\n\t\t};\n\t\tthis.isNot=function(f){\n\t\t\t_negate=!_negate;\n\t\t\treturn self.is(f);\n\t\t};\n\t\tthis.is=function(f){\n\t\t\tself._append('this.'+f);\n\t\t\tself._resetNegate();\n\t\t\treturn self;\n\t\t};\n\t\tthis._compareValues=function(func,f,v,how,t){\n\t\t\tvar fld;\n\t\t\tif(_useProperties){\n\t\t\t\tfld='jQuery.jgrid.getAccessor(this,\\''+f+'\\')';\n\t\t\t}else{\n\t\t\t\tfld='this';\n\t\t\t}\n\t\t\tif(v===undefined) { v = null; }\n\t\t\t//var val=v===null?f:v,\n\t\t\tvar val =v,\n\t\t\tswst = t.stype === undefined ? \"text\" : t.stype;\n\t\t\tif(v !== null) {\n\t\t\tswitch(swst) {\n\t\t\t\tcase 'int':\n\t\t\t\tcase 'integer':\n\t\t\t\t\tval = (isNaN(Number(val)) || val===\"\") ? '0' : val; // To be fixed with more inteligent code\n\t\t\t\t\tfld = 'parseInt('+fld+',10)';\n\t\t\t\t\tval = 'parseInt('+val+',10)';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'float':\n\t\t\t\tcase 'number':\n\t\t\t\tcase 'numeric':\n\t\t\t\t\tval = String(val).replace(_stripNum, '');\n\t\t\t\t\tval = (isNaN(Number(val)) || val===\"\") ? '0' : val; // To be fixed with more inteligent code\n\t\t\t\t\tfld = 'parseFloat('+fld+')';\n\t\t\t\t\tval = 'parseFloat('+val+')';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'date':\n\t\t\t\tcase 'datetime':\n\t\t\t\t\tval = String($.jgrid.parseDate(t.newfmt || 'Y-m-d',val).getTime());\n\t\t\t\t\tfld = 'jQuery.jgrid.parseDate(\"'+t.srcfmt+'\",'+fld+').getTime()';\n\t\t\t\t\tbreak;\n\t\t\t\tdefault :\n\t\t\t\t\tfld=self._getStr(fld);\n\t\t\t\t\tval=self._getStr('\"'+self._toStr(val)+'\"');\n\t\t\t}\n\t\t\t}\n\t\t\tself._append(fld+' '+how+' '+val);\n\t\t\tself._setCommand(func,f);\n\t\t\tself._resetNegate();\n\t\t\treturn self;\n\t\t};\n\t\tthis.equals=function(f,v,t){\n\t\t\treturn self._compareValues(self.equals,f,v,\"==\",t);\n\t\t};\n\t\tthis.notEquals=function(f,v,t){\n\t\t\treturn self._compareValues(self.equals,f,v,\"!==\",t);\n\t\t};\n\t\tthis.isNull = function(f,v,t){\n\t\t\treturn self._compareValues(self.equals,f,null,\"===\",t);\n\t\t};\n\t\tthis.greater=function(f,v,t){\n\t\t\treturn self._compareValues(self.greater,f,v,\">\",t);\n\t\t};\n\t\tthis.less=function(f,v,t){\n\t\t\treturn self._compareValues(self.less,f,v,\"<\",t);\n\t\t};\n\t\tthis.greaterOrEquals=function(f,v,t){\n\t\t\treturn self._compareValues(self.greaterOrEquals,f,v,\">=\",t);\n\t\t};\n\t\tthis.lessOrEquals=function(f,v,t){\n\t\t\treturn self._compareValues(self.lessOrEquals,f,v,\"<=\",t);\n\t\t};\n\t\tthis.startsWith=function(f,v){\n\t\t\tvar val = (v==null) ? f: v,\n\t\t\tlength=_trim ? $.trim(val.toString()).length : val.toString().length;\n\t\t\tif(_useProperties){\n\t\t\t\tself._append(self._getStr('jQuery.jgrid.getAccessor(this,\\''+f+'\\')')+'.substr(0,'+length+') == '+self._getStr('\"'+self._toStr(v)+'\"'));\n\t\t\t}else{\n\t\t\t\tif (v!=null) { length=_trim?$.trim(v.toString()).length:v.toString().length; }\n\t\t\t\tself._append(self._getStr('this')+'.substr(0,'+length+') == '+self._getStr('\"'+self._toStr(f)+'\"'));\n\t\t\t}\n\t\t\tself._setCommand(self.startsWith,f);\n\t\t\tself._resetNegate();\n\t\t\treturn self;\n\t\t};\n\t\tthis.endsWith=function(f,v){\n\t\t\tvar val = (v==null) ? f: v,\n\t\t\tlength=_trim ? $.trim(val.toString()).length:val.toString().length;\n\t\t\tif(_useProperties){\n\t\t\t\tself._append(self._getStr('jQuery.jgrid.getAccessor(this,\\''+f+'\\')')+'.substr('+self._getStr('jQuery.jgrid.getAccessor(this,\\''+f+'\\')')+'.length-'+length+','+length+') == \"'+self._toStr(v)+'\"');\n\t\t\t} else {\n\t\t\t\tself._append(self._getStr('this')+'.substr('+self._getStr('this')+'.length-\"'+self._toStr(f)+'\".length,\"'+self._toStr(f)+'\".length) == \"'+self._toStr(f)+'\"');\n\t\t\t}\n\t\t\tself._setCommand(self.endsWith,f);self._resetNegate();\n\t\t\treturn self;\n\t\t};\n\t\tthis.contains=function(f,v){\n\t\t\tif(_useProperties){\n\t\t\t\tself._append(self._getStr('jQuery.jgrid.getAccessor(this,\\''+f+'\\')')+'.indexOf(\"'+self._toStr(v)+'\",0) > -1');\n\t\t\t}else{\n\t\t\t\tself._append(self._getStr('this')+'.indexOf(\"'+self._toStr(f)+'\",0) > -1');\n\t\t\t}\n\t\t\tself._setCommand(self.contains,f);\n\t\t\tself._resetNegate();\n\t\t\treturn self;\n\t\t};\n\t\tthis.groupBy=function(by,dir,type, datefmt){\n\t\t\tif(!self._hasData()){\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\treturn self._getGroup(_data,by,dir,type, datefmt);\n\t\t};\n\t\tthis.orderBy=function(by,dir,stype, dfmt, sfunc){\n\t\t\tdir = dir == null ? \"a\" :$.trim(dir.toString().toLowerCase());\n\t\t\tif(stype == null) { stype = \"text\"; }\n\t\t\tif(dfmt == null) { dfmt = \"Y-m-d\"; }\n\t\t\tif(sfunc == null) { sfunc = false; }\n\t\t\tif(dir===\"desc\"||dir===\"descending\"){dir=\"d\";}\n\t\t\tif(dir===\"asc\"||dir===\"ascending\"){dir=\"a\";}\n\t\t\t_sorting.push({by:by,dir:dir,type:stype, datefmt: dfmt, sfunc: sfunc});\n\t\t\treturn self;\n\t\t};\n\t\treturn self;\n\t\t};\n\treturn new QueryObject(source,null);\n\t},\n\tgetMethod: function (name) {\n return this.getAccessor($.fn.jqGrid, name);\n\t},\n\textend : function(methods) {\n\t\t$.extend($.fn.jqGrid,methods);\n\t\tif (!this.no_legacy_api) {\n\t\t\t$.fn.extend(methods);\n\t\t}\n\t}\n});\n\n$.fn.jqGrid = function( pin ) {\n\tif (typeof pin === 'string') {\n\t\tvar fn = $.jgrid.getMethod(pin);\n\t\tif (!fn) {\n\t\t\tthrow (\"jqGrid - No such method: \" + pin);\n\t\t}\n\t\tvar args = $.makeArray(arguments).slice(1);\n\t\treturn fn.apply(this,args);\n\t}\n\treturn this.each( function() {\n\t\tif(this.grid) {return;}\n\t\tvar localData;\n\t\tif (pin != null && pin.data !== undefined) {\n\t\t\tlocalData = pin.data;\n\t\t\tpin.data = [];\n\t\t}\n\n\t\tvar p = $.extend(true,{\n\t\t\turl: \"\",\n\t\t\theight: 150,\n\t\t\tpage: 1,\n\t\t\trowNum: 20,\n\t\t\trowTotal : null,\n\t\t\trecords: 0,\n\t\t\tpager: \"\",\n\t\t\tpgbuttons: true,\n\t\t\tpginput: true,\n\t\t\tcolModel: [],\n\t\t\trowList: [],\n\t\t\tcolNames: [],\n\t\t\tsortorder: \"asc\",\n\t\t\tsortname: \"\",\n\t\t\tdatatype: \"xml\",\n\t\t\tmtype: \"GET\",\n\t\t\taltRows: false,\n\t\t\tselarrrow: [],\n\t\t\tsavedRow: [],\n\t\t\tshrinkToFit: true,\n\t\t\txmlReader: {},\n\t\t\tjsonReader: {},\n\t\t\tsubGrid: false,\n\t\t\tsubGridModel :[],\n\t\t\treccount: 0,\n\t\t\tlastpage: 0,\n\t\t\tlastsort: 0,\n\t\t\tselrow: null,\n\t\t\tbeforeSelectRow: null,\n\t\t\tonSelectRow: null,\n\t\t\tonSortCol: null,\n\t\t\tondblClickRow: null,\n\t\t\tonRightClickRow: null,\n\t\t\tonPaging: null,\n\t\t\tonSelectAll: null,\n\t\t\tonInitGrid : null,\n\t\t\tloadComplete: null,\n\t\t\tgridComplete: null,\n\t\t\tloadError: null,\n\t\t\tloadBeforeSend: null,\n\t\t\tafterInsertRow: null,\n\t\t\tbeforeRequest: null,\n\t\t\tbeforeProcessing : null,\n\t\t\tonHeaderClick: null,\n\t\t\tviewrecords: false,\n\t\t\tloadonce: false,\n\t\t\tmultiselect: false,\n\t\t\tmultikey: false,\n\t\t\tediturl: null,\n\t\t\tsearch: false,\n\t\t\tcaption: \"\",\n\t\t\thidegrid: true,\n\t\t\thiddengrid: false,\n\t\t\tpostData: {},\n\t\t\tuserData: {},\n\t\t\ttreeGrid : false,\n\t\t\ttreeGridModel : 'nested',\n\t\t\ttreeReader : {},\n\t\t\ttreeANode : -1,\n\t\t\tExpandColumn: null,\n\t\t\ttree_root_level : 0,\n\t\t\tprmNames: {page:\"page\",rows:\"rows\", sort: \"sidx\",order: \"sord\", search:\"_search\", nd:\"nd\", id:\"id\",oper:\"oper\",editoper:\"edit\",addoper:\"add\",deloper:\"del\", subgridid:\"id\", npage: null, totalrows:\"totalrows\"},\n\t\t\tforceFit : false,\n\t\t\tgridstate : \"visible\",\n\t\t\tcellEdit: false,\n\t\t\tcellsubmit: \"remote\",\n\t\t\tnv:0,\n\t\t\tloadui: \"enable\",\n\t\t\ttoolbar: [false,\"\"],\n\t\t\tscroll: false,\n\t\t\tmultiboxonly : false,\n\t\t\tdeselectAfterSort : true,\n\t\t\tscrollrows : false,\n\t\t\tautowidth: false,\n\t\t\tscrollOffset :18,\n\t\t\tcellLayout: 5,\n\t\t\tsubGridWidth: 20,\n\t\t\tmultiselectWidth: 20,\n\t\t\tgridview: false,\n\t\t\trownumWidth: 25,\n\t\t\trownumbers : false,\n\t\t\tpagerpos: 'center',\n\t\t\trecordpos: 'right',\n\t\t\tfooterrow : false,\n\t\t\tuserDataOnFooter : false,\n\t\t\thoverrows : true,\n\t\t\taltclass : 'ui-priority-secondary',\n\t\t\tviewsortcols : [false,'vertical',true],\n\t\t\tresizeclass : '',\n\t\t\tautoencode : false,\n\t\t\tremapColumns : [],\n\t\t\tajaxGridOptions :{},\n\t\t\tdirection : \"ltr\",\n\t\t\ttoppager: false,\n\t\t\theadertitles: false,\n\t\t\tscrollTimeout: 40,\n\t\t\tdata : [],\n\t\t\t_index : {},\n\t\t\tgrouping : false,\n\t\t\tgroupingView : {groupField:[],groupOrder:[], groupText:[],groupColumnShow:[],groupSummary:[], showSummaryOnHide: false, sortitems:[], sortnames:[], summary:[],summaryval:[], plusicon: 'ui-icon-circlesmall-plus', minusicon: 'ui-icon-circlesmall-minus', displayField: [], groupSummaryPos:[], formatDisplayField : [], _locgr : false},\n\t\t\tignoreCase : false,\n\t\t\tcmTemplate : {},\n\t\t\tidPrefix : \"\",\n\t\t\tmultiSort : false,\n\t\t\tminColWidth : 33\n\t\t}, $.jgrid.defaults, pin || {});\n\t\tif (localData !== undefined) {\n\t\t\tp.data = localData;\n\t\t\tpin.data = localData;\n\t\t}\n\t\tvar ts= this, grid={\n\t\t\theaders:[],\n\t\t\tcols:[],\n\t\t\tfooters: [],\n\t\t\tdragStart: function(i,x,y) {\n\t\t\t\tvar gridLeftPos = $(this.bDiv).offset().left;\n\t\t\t\tthis.resizing = { idx: i, startX: x.pageX, sOL : x.pageX - gridLeftPos };\n\t\t\t\tthis.hDiv.style.cursor = \"col-resize\";\n\t\t\t\tthis.curGbox = $(\"#rs_m\"+$.jgrid.jqID(p.id),\"#gbox_\"+$.jgrid.jqID(p.id));\n\t\t\t\tthis.curGbox.css({display:\"block\",left:x.pageX-gridLeftPos,top:y[1],height:y[2]});\n\t\t\t\t$(ts).triggerHandler(\"jqGridResizeStart\", [x, i]);\n\t\t\t\tif($.isFunction(p.resizeStart)) { p.resizeStart.call(ts,x,i); }\n\t\t\t\tdocument.onselectstart=function(){return false;};\n\t\t\t},\n\t\t\tdragMove: function(x) {\n\t\t\t\tif(this.resizing) {\n\t\t\t\t\tvar diff = x.pageX-this.resizing.startX,\n\t\t\t\t\th = this.headers[this.resizing.idx],\n\t\t\t\t\tnewWidth = p.direction === \"ltr\" ? h.width + diff : h.width - diff, hn, nWn;\n\t\t\t\t\tif(newWidth > 33) {\n\t\t\t\t\t\tthis.curGbox.css({left:this.resizing.sOL+diff});\n\t\t\t\t\t\tif(p.forceFit===true ){\n\t\t\t\t\t\t\thn = this.headers[this.resizing.idx+p.nv];\n\t\t\t\t\t\t\tnWn = p.direction === \"ltr\" ? hn.width - diff : hn.width + diff;\n\t\t\t\t\t\t\tif(nWn > p.minColWidth ) {\n\t\t\t\t\t\t\t\th.newWidth = newWidth;\n\t\t\t\t\t\t\t\thn.newWidth = nWn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthis.newWidth = p.direction === \"ltr\" ? p.tblwidth+diff : p.tblwidth-diff;\n\t\t\t\t\t\t\th.newWidth = newWidth;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdragEnd: function() {\n\t\t\t\tthis.hDiv.style.cursor = \"default\";\n\t\t\t\tif(this.resizing) {\n\t\t\t\t\tvar idx = this.resizing.idx,\n\t\t\t\t\tnw = this.headers[idx].newWidth || this.headers[idx].width;\n\t\t\t\t\tnw = parseInt(nw,10);\n\t\t\t\t\tthis.resizing = false;\n\t\t\t\t\t$(\"#rs_m\"+$.jgrid.jqID(p.id)).css(\"display\",\"none\");\n\t\t\t\t\tp.colModel[idx].width = nw;\n\t\t\t\t\tthis.headers[idx].width = nw;\n\t\t\t\t\tthis.headers[idx].el.style.width = nw + \"px\";\n\t\t\t\t\tthis.cols[idx].style.width = nw+\"px\";\n\t\t\t\t\tif(this.footers.length>0) {this.footers[idx].style.width = nw+\"px\";}\n\t\t\t\t\tif(p.forceFit===true){\n\t\t\t\t\t\tnw = this.headers[idx+p.nv].newWidth || this.headers[idx+p.nv].width;\n\t\t\t\t\t\tthis.headers[idx+p.nv].width = nw;\n\t\t\t\t\t\tthis.headers[idx+p.nv].el.style.width = nw + \"px\";\n\t\t\t\t\t\tthis.cols[idx+p.nv].style.width = nw+\"px\";\n\t\t\t\t\t\tif(this.footers.length>0) {this.footers[idx+p.nv].style.width = nw+\"px\";}\n\t\t\t\t\t\tp.colModel[idx+p.nv].width = nw;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.tblwidth = this.newWidth || p.tblwidth;\n\t\t\t\t\t\t$('table:first',this.bDiv).css(\"width\",p.tblwidth+\"px\");\n\t\t\t\t\t\t$('table:first',this.hDiv).css(\"width\",p.tblwidth+\"px\");\n\t\t\t\t\t\tthis.hDiv.scrollLeft = this.bDiv.scrollLeft;\n\t\t\t\t\t\tif(p.footerrow) {\n\t\t\t\t\t\t\t$('table:first',this.sDiv).css(\"width\",p.tblwidth+\"px\");\n\t\t\t\t\t\t\tthis.sDiv.scrollLeft = this.bDiv.scrollLeft;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t$(ts).triggerHandler(\"jqGridResizeStop\", [nw, idx]);\n\t\t\t\t\tif($.isFunction(p.resizeStop)) { p.resizeStop.call(ts,nw,idx); }\n\t\t\t\t}\n\t\t\t\tthis.curGbox = null;\n\t\t\t\tdocument.onselectstart=function(){return true;};\n\t\t\t},\n\t\t\tpopulateVisible: function() {\n\t\t\t\tif (grid.timer) { clearTimeout(grid.timer); }\n\t\t\t\tgrid.timer = null;\n\t\t\t\tvar dh = $(grid.bDiv).height();\n\t\t\t\tif (!dh) { return; }\n\t\t\t\tvar table = $(\"table:first\", grid.bDiv);\n\t\t\t\tvar rows, rh;\n\t\t\t\tif(table[0].rows.length) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\trows = table[0].rows[1];\n\t\t\t\t\t\trh = rows ? $(rows).outerHeight() || grid.prevRowHeight : grid.prevRowHeight;\n\t\t\t\t\t} catch (pv) {\n\t\t\t\t\t\trh = grid.prevRowHeight;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (!rh) { return; }\n\t\t\t\tgrid.prevRowHeight = rh;\n\t\t\t\tvar rn = p.rowNum;\n\t\t\t\tvar scrollTop = grid.scrollTop = grid.bDiv.scrollTop;\n\t\t\t\tvar ttop = Math.round(table.position().top) - scrollTop;\n\t\t\t\tvar tbot = ttop + table.height();\n\t\t\t\tvar div = rh * rn;\n\t\t\t\tvar page, npage, empty;\n\t\t\t\tif ( tbot < dh && ttop <= 0 &&\n\t\t\t\t\t(p.lastpage===undefined||(parseInt((tbot + scrollTop + div - 1) / div,10) || 0) <= p.lastpage))\n\t\t\t\t{\n\t\t\t\t\tnpage = parseInt((dh - tbot + div - 1) / div,10) || 1;\n\t\t\t\t\tif (tbot >= 0 || npage < 2 || p.scroll === true) {\n\t\t\t\t\t\tpage = ( Math.round((tbot + scrollTop) / div) || 0) + 1;\n\t\t\t\t\t\tttop = -1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tttop = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (ttop > 0) {\n\t\t\t\t\tpage = ( parseInt(scrollTop / div,10) || 0 ) + 1;\n\t\t\t\t\tnpage = (parseInt((scrollTop + dh) / div,10) || 0) + 2 - page;\n\t\t\t\t\tempty = true;\n\t\t\t\t}\n\t\t\t\tif (npage) {\n\t\t\t\t\tif (p.lastpage && (page > p.lastpage || p.lastpage===1 || (page === p.page && page===p.lastpage)) ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (grid.hDiv.loading) {\n\t\t\t\t\t\tgrid.timer = setTimeout(grid.populateVisible, p.scrollTimeout);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tp.page = page;\n\t\t\t\t\t\tif (empty) {\n\t\t\t\t\t\t\tgrid.selectionPreserver(table[0]);\n\t\t\t\t\t\t\tgrid.emptyRows.call(table[0], false, false);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tgrid.populate(npage);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tscrollGrid: function( e ) {\n\t\t\t\tif(p.scroll) {\n\t\t\t\t\tvar scrollTop = grid.bDiv.scrollTop;\n\t\t\t\t\tif(grid.scrollTop === undefined) { grid.scrollTop = 0; }\n\t\t\t\t\tif (scrollTop !== grid.scrollTop) {\n\t\t\t\t\t\tgrid.scrollTop = scrollTop;\n\t\t\t\t\t\tif (grid.timer) { clearTimeout(grid.timer); }\n\t\t\t\t\t\tgrid.timer = setTimeout(grid.populateVisible, p.scrollTimeout);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tgrid.hDiv.scrollLeft = grid.bDiv.scrollLeft;\n\t\t\t\tif(p.footerrow) {\n\t\t\t\t\tgrid.sDiv.scrollLeft = grid.bDiv.scrollLeft;\n\t\t\t\t}\n\t\t\t\tif( e ) { e.stopPropagation(); }\n\t\t\t},\n\t\t\tselectionPreserver : function(ts) {\n\t\t\t\tvar p = ts.p,\n\t\t\t\tsr = p.selrow, sra = p.selarrrow ? $.makeArray(p.selarrrow) : null,\n\t\t\t\tleft = ts.grid.bDiv.scrollLeft,\n\t\t\t\trestoreSelection = function() {\n\t\t\t\t\tvar i;\n\t\t\t\t\tp.selrow = null;\n\t\t\t\t\tp.selarrrow = [];\n\t\t\t\t\tif(p.multiselect && sra && sra.length>0) {\n\t\t\t\t\t\tfor(i=0;i