Repository: goofychris/art-template Branch: master Commit: ee8a223fe4c3 Files: 103 Total size: 532.9 KB Directory structure: gitextract_injr0rlg/ ├── .babelrc ├── .editorconfig ├── .eslintignore ├── .eslintrc.json ├── .github/ │ └── ISSUE_TEMPLATE.md ├── .gitignore ├── .prettierrc ├── .travis.yml ├── CHANGELOG.md ├── LICENSE ├── README.md ├── example/ │ ├── node-include/ │ │ ├── footer.art │ │ ├── header.art │ │ ├── index.art │ │ └── index.js │ ├── node-layout/ │ │ ├── index.art │ │ ├── index.js │ │ ├── layout.art │ │ └── nested-block/ │ │ ├── index.art │ │ ├── index.js │ │ ├── inner-layout.art │ │ └── outer-layout.art │ ├── web-art-syntax/ │ │ ├── basic.html │ │ ├── compile-error.html │ │ ├── compile.html │ │ ├── filter.html │ │ ├── include.html │ │ ├── no-escape.html │ │ ├── print.html │ │ └── runtime-error.html │ ├── web-ie-compatible/ │ │ └── index.html │ ├── web-native-syntax/ │ │ ├── basic.html │ │ ├── compile-error.html │ │ ├── compile.html │ │ ├── filter.html │ │ ├── include.html │ │ ├── no-escape.html │ │ ├── print.html │ │ └── runtime-error.html │ ├── web-requirejs/ │ │ ├── index.html │ │ └── require.js │ └── web-test-speed/ │ ├── index.html │ └── js/ │ ├── handlebars.js │ └── highcharts.js ├── index.d.ts ├── index.js ├── package.json ├── src/ │ ├── compile/ │ │ ├── adapter/ │ │ │ ├── caches.js │ │ │ ├── extend.js │ │ │ ├── html-minifier.js │ │ │ ├── include.js │ │ │ ├── loader.js │ │ │ ├── onerror.js │ │ │ ├── resolve-filename.js │ │ │ ├── rule.art.js │ │ │ └── rule.native.js │ │ ├── compiler.js │ │ ├── defaults.js │ │ ├── error.js │ │ ├── es-tokenizer.js │ │ ├── index.js │ │ ├── runtime.js │ │ └── tpl-tokenizer.js │ ├── defaults.js │ ├── extension.js │ ├── index.js │ ├── precompile.js │ ├── render.js │ └── runtime.js ├── test/ │ ├── compile/ │ │ ├── adapter/ │ │ │ ├── caches.js │ │ │ ├── html-minifier.js │ │ │ ├── loader.js │ │ │ ├── onerror.js │ │ │ ├── resolve-filename.js │ │ │ ├── rule.art.js │ │ │ └── rule.native.js │ │ ├── compiler.js │ │ ├── defaults.js │ │ ├── es-tokenizer.js │ │ ├── index.js │ │ ├── runtime.js │ │ └── tpl-tokenizer.js │ ├── index.js │ ├── node.js │ └── res/ │ ├── extend-options/ │ │ ├── file.art │ │ ├── file2.art │ │ └── include.art │ ├── extension.compile-error.2.tpl │ ├── extension.compile-error.tpl │ ├── extension.file.html │ ├── extension.file.tpl │ ├── extension.runtime-error.2.tpl │ ├── extension.runtime-error.tpl │ ├── file.art │ ├── file.html │ ├── index/ │ │ ├── include.html │ │ └── index.html │ ├── nested-block/ │ │ ├── base-layout.art │ │ ├── default.art │ │ ├── index.art │ │ └── layout.art │ └── template.file.html └── webpack.config.js ================================================ FILE CONTENTS ================================================ ================================================ FILE: .babelrc ================================================ { "presets": [ ["env", { "targets": { "browsers": ["Explorer >= 7"] } }] ] } ================================================ FILE: .editorconfig ================================================ root = true [*] indent_style = space indent_size = 4 end_of_line = lf charset = utf-8 trim_trailing_whitespace = false insert_final_newline = false ================================================ FILE: .eslintignore ================================================ lib/* ================================================ FILE: .eslintrc.json ================================================ { "env": { "browser": true, "commonjs": true, "es6": true, "node": true }, "parserOptions": { "ecmaFeatures": { "jsx": true }, "sourceType": "module" }, "globals": { "describe": true, "it": true }, "plugins": [ "prettier" ], "rules": { "no-const-assign": "warn", "no-this-before-super": "warn", "no-undef": "warn", "no-unreachable": "warn", "no-unused-vars": "warn", "constructor-super": "warn", "valid-typeof": "warn", "prettier/prettier": "error" } } ================================================ FILE: .github/ISSUE_TEMPLATE.md ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store .vscode .idea lib coverage node_modules npm-debug.log ================================================ FILE: .prettierrc ================================================ { "printWidth": 100, "parser": "flow", "useTabs": false, "tabWidth": 4, "singleQuote": true } ================================================ FILE: .travis.yml ================================================ language: node_js node_js: - 6 cache: directories: - node_modules branches: only: - master install: - npm install script: - npm run build - npm test after_success: - npm run coverage ================================================ FILE: CHANGELOG.md ================================================ # CHANGELOG ## v4.13.2 1. 修复 npm 包 index.d.ts 丢失的问题 ## v4.13.1 1. 修复在某些情况 runtime 提示 window 未定义的问题 [#553](https://github.com/aui/art-template/issues/553) ## v4.13.0 1. 修复超大模板编译性能问题 [#539](https://github.com/aui/art-template/issues/539)、[#4](https://github.com/aui/express-art-template/issues/4) 2. 支持嵌套 block [#468](https://github.com/aui/art-template/issues/468) ## v4.12.2 1. 修复 [#483](https://github.com/aui/art-template/issues/483) ## v4.12.1 1. 修复过滤器不能使用包含空的格字符串参数的问题 ## v4.12.0 1. `bail` 默认为 `true` 2. 修复过滤器不支持 javascript 表达式的问题 [#430](https://github.com/aui/art-template/issues/430) ## v4.11.0 1. `include`、`extend` 支持使用函数表达式。例如 `{{include(file, {list[]})}}` [#414](https://github.com/aui/art-template/issues/414) 2. 修复 `options.escape=false` 不生效的 BUG ## v4.10.2 1. 修复与 art-template-loader 兼容问题 [art-template-loader#9](https://github.com/aui/art-template-loader/issues/9) ## v4.10.1 1. `rule.use` 函数第一个传入数据类型由“类 `String` ”对象改为真正的 `String` 对象 ## v4.10.0 1. 修复标准语法的 BUG [#408](https://github.com/aui/art-template/issues/408),并且不再兼容 v3 的辅助方法调用:`{{helper args}}` 2. 修复 EJS `<%- include(src) %>` 语句兼容问题 ## v4.9.1 1. 修复模板内部 `$escape` 与 `$each` 变量可能没有定义的问题 [#3](https://github.com/aui/express-art-template/issues/3) [#1](https://github.com/aui/express-art-template/issues/1) ## v4.9.0 1. 增强调试功能:日志输出错误行号以及上下文 ## v4.8.2 1. 修复子模板没有继承父模板编译 options 问题 2. 渲染函数参数可以为空 ## v4.8.1 1. 修复低版本 NodeJS 报错问题 ## v4.8.0 1. 过滤器支持在运行时注入 [#4](https://github.com/aui/art-template-loader/issues/4) 2. 过滤器语法可以直接使用全局对象,无需特别声明。例如 `{{url | encodeURIComponent}}` ## v4.7.0 1. 增加 `ignore` 配置,可以让模板编译器忽略指定的变量初始化 2. 增加 `htmlMinifierOptions` 配置,可对 [htmlMinifie](https://github.com/kangax/html-minifier) 压缩器进行配置 ## v4.6.0 1. `$escape()` 函数提高 4 倍性能 2. 支持输出 sourceMap: sourcesContent ## v4.5.1 1. 修复 `{{/if}}` 语句不支持头尾空格的问题 2. 修复 NodeJS 版本兼容问题 [#393](https://github.com/aui/art-template/issues/393) ## v4.5.0 1. 支持对 `options.imports` 的深拷贝 [#1](https://github.com/aui/express-art-template/issues/1) 2. 支持对 `options.rules` 的覆盖 ## v4.4.2 1. 兼容 IE8 ## v4.4.1 1. 修正 `root` 配置的行为,如果 filename 为全局模块路径,会直接根据 `root` 来定位 2. 修复多行模板逻辑表达式下 sourceMap 行号记录不准确的 BUG 3. 标准化错误处理 ## v4.4.0 1. 预编译 API 支持输出 sourceMap ## v4.3.2 1. 修复 web 版本无法被 requirejs 加载问题 ## v4.3.1 1. 修复预编译 API 默认配置 `imports` 错误问题 ## v4.3.0 1. NodeJS: 支持预编译 API ## v4.2.1 1. 适配器 `loader`、`onerror`、`htmlMinifier` 第二个参数接收 `options` ## v4.2.0 1. 支持 HTML、CSS、JS 压缩(`minimize: true`)。同时废弃 `compressor` 字段 2. 修复配置 `debuger` 拼写错误,`debuger` 更名为 `onerror` 3. 将模板全局变量 `$options` 私有化 ## v4.1.0 1. 支持 layout 2. 修复 `{{if else value}}` 语句 BUG 3. 修复多个 `include` 语句共存导致路径的 BUG ## v4.0.0 1. 调试功能增强:支持编译阶段捕获语法错误具体行 2. `template.config()` 方法取消,请直接读写 `template.defaults` 3. `template.helpers` 更改为 `template.defaults.imports` 4. `template.defaults.debuger` 选项可以定制输出的调试信息 5. `template.defaults.parser` 被取消,使用更强大的 `template.defaults.rules` 代替 6. 兼容 EJS 的模板 7. 使用 ECMA5 构建,低于 IE9 的浏览器需要使用 ECMA5 补丁以及 JSON 库支持才可以运行 8. `<%=value%>` 语句支持输出 JSON ## v3.1.0 1. 修复``template.runder()``方法与文档表现不一致的问题 2. 去掉鸡肋的``fs.watch``特性 ## v3.0.3 1. 解决``template.helper()``方法传入的数据被转成字符串的问题 #96 2. 解决``{{value || value2}}``被识别为管道语句的问题 #105 ## v3.0.2 1. ~~解决管道语法必须使用空格分隔的问题~~ ## v3.0.1 1. 适配 express3.x 与 4.x,修复路径 BUG ## v3.0.0 1. 提供 NodeJS 专属版本,支持使用路径加载模板,并且模板的``include``语句也支持相对路径 2. 适配 [express](http://expressjs.com) 框架 3. 内置``print``语句支持传入多个参数 4. 支持全局缓存配置 5. 简洁语法版支持管道风格的 helper 调用,例如:``{{time | dateFormat:'yyyy年 MM月 dd日 hh:mm:ss'}}`` 当前版本接口有调整,请阅读 [升级参考](#升级参考) > artTemplate 预编译工具 [TmodJS](https://github.com/aui/tmodjs) 已更新 ## v2.0.4 1. 修复低版本安卓浏览器编译后可能产生语法错误的问题(因为此版本浏览器 js 引擎存在 BUG) ## v2.0.3 1. 优化辅助方法性能 2. NodeJS 用户可以通过 npm 获取 artTemplate:``$ npm install art-template -g`` 3. 不转义输出语句推荐使用``<%=#value%>``(兼容 v2.0.3 版本之前使用的``<%==value%>``),而简版语法则可以使用``{{#value}}`` 4. 提供简版语法的合并版本 dist/[template-simple.js](https://raw.github.com/aui/artTemplate/master/dist/template-simple.js) ## v2.0.2 1. 优化自定义语法扩展,减少体积 2. [重要]为了最大化兼容第三方库,自定义语法扩展默认界定符修改为``{{``与``}}``。 3. 修复合并工具的BUG [#25](https://github.com/aui/artTemplate/issues/25) 4. 公开了内部缓存,可以通过``template.cache``访问到编译后的函数 5. 公开了辅助方法缓存,可以通过``template.helpers``访问到 6. 优化了调试信息 ## v2.0.1 1. 修复模板变量静态分析的[BUG](https://github.com/aui/artTemplate/pull/22) ## v2.0 release 1. ~~编译工具更名为 atc,成为 artTemplate 的子项目单独维护:~~ ## v2.0 beta5 1. 修复编译工具可能存在重复依赖的问题。感谢 @warmhug 2. 修复预编译``include``内部实现可能产生上下文不一致的问题。感谢 @warmhug 3. 编译工具支持使用拖拽文件进行单独编译 ## v2.0 beta4 1. 修复编译工具在压缩模板可能导致 HTML 意外截断的问题。感谢 @warmhug 2. 完善编译工具对``include``支持支持,可以支持不同目录之间模板嵌套 3. 修复编译工具没能正确处理自定义语法插件的辅助方法 ## v2.0 beta1 1. 对非 String、Number 类型的数据不输出,而 Function 类型求值后输出。 2. 默认对 html 进行转义输出,原文输出可使用``<%==value%>``(备注:v2.0.3 推荐使用``<%=#value%>``),也可以关闭默认的转义功能``template.defaults.escape = false``。 3. 增加批处理工具支持把模板编译成不依赖模板引擎的 js 文件,可通过 RequireJS、SeaJS 等模块加载器进行异步加载。 ================================================ FILE: LICENSE ================================================ The MIT License (MIT) Copyright (c) 2016-2020 糖饼 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # art-template [![NPM Version](https://img.shields.io/npm/v/art-template.svg)](https://npmjs.org/package/art-template) [![NPM Downloads](http://img.shields.io/npm/dm/art-template.svg)](https://npmjs.org/package/art-template) [![Node.js Version](https://img.shields.io/node/v/art-template.svg)](http://nodejs.org/download/) [![Travis-ci](https://travis-ci.org/aui/art-template.svg?branch=master)](https://travis-ci.org/aui/art-template) [![Coverage Status](https://coveralls.io/repos/github/aui/art-template/badge.svg?branch=master)](https://coveralls.io/github/aui/art-template?branch=master) [English document](https://goofychris.github.io/art-template/) | [中文文档](https://goofychris.github.io/art-template/zh-cn/index.html) art-template is a simple and superfast templating engine that optimizes template rendering speed by scope pre-declared technique, hence achieving runtime performance which is close to the limits of JavaScript. At the same time, it supports both NodeJS and browser. [speed test online](https://goofychris.github.io/art-template/rendering-test/). art-template 是一个简约、超快的模板引擎。它采用作用域预声明的技术来优化模板渲染速度,从而获得接近 JavaScript 极限的运行性能,并且同时支持 NodeJS 和浏览器。[在线速度测试](https://goofychris.github.io/art-template/rendering-test/)。 [![chart](https://goofychris.github.io/art-template/images/chart@2x.png)](https://goofychris.github.io/art-template/rendering-test/) ## Feature 1. performance is close to the JavaScript rendering limits 2. debugging friendly. Syntax errors or runtime errors will be positioned accurately at which line of template. Support setting breakpoint in templating files (Webpack Loader) 3. support Express, Koa, Webpack 4. support template inheritance and sub template 5. browser version is only 6KB ## 特性 1. 拥有接近 JavaScript 渲染极限的的性能 2. 调试友好:语法、运行时错误日志精确到模板所在行;支持在模板文件上打断点(Webpack Loader) 5. 支持 Express、Koa、Webpack 6. 支持模板继承与子模板 7. 浏览器版本仅 6KB 大小 ================================================ FILE: example/node-include/footer.art ================================================
================================================ FILE: example/node-include/header.art ================================================

{{title}}

================================================ FILE: example/node-include/index.art ================================================ {{title}} <% include('./header.art', { title: title }) %>

This is just an awesome page.

{{include './footer.art'}} ================================================ FILE: example/node-include/index.js ================================================ const path = require('path'); const template = require('../../src'); const data = { title: 'My Page' }; const html = template(path.resolve(__dirname, 'index.art'), data); console.log(html); ================================================ FILE: example/node-layout/index.art ================================================ {{extend './layout.art'}} {{block 'title'}}{{title}}{{/block}} {{block 'head'}} {{/block}} {{block 'content'}}

This is just an awesome page.

{{/block}} ================================================ FILE: example/node-layout/index.js ================================================ const path = require('path'); const template = require('../../src'); const data = { title: 'My Page' }; const html = template(path.resolve(__dirname, 'index.art'), data); console.log(html); ================================================ FILE: example/node-layout/layout.art ================================================ {{block 'title'}}My Site{{/block}} {{block 'head'}} {{/block}} {{block 'content'}}{{/block}} ================================================ FILE: example/node-layout/nested-block/index.art ================================================ {{extend './inner-layout.art'}} {{block 'content-inner'}}

my innter content

{{/block}} ================================================ FILE: example/node-layout/nested-block/index.js ================================================ const path = require('path'); const template = require('../../../src'); const data = { title: 'My Page' }; const html = template(path.resolve(__dirname, 'index.art'), data); console.log(html); ================================================ FILE: example/node-layout/nested-block/inner-layout.art ================================================ {{extend './outer-layout.art'}} {{block 'content-1'}}
{{block 'content-inner'}}

default inner

{{/block}} {{title}}
{{/block}} {{block 'content-2'}}
{{block 'content-inner-2'}}

default inner2

{{/block}}
{{/block}} ================================================ FILE: example/node-layout/nested-block/outer-layout.art ================================================ {{block 'title'}}{{title}}{{/block}} {{block 'content-1'}}{{/block}} {{block 'content-2'}}{{/block}} ================================================ FILE: example/web-art-syntax/basic.html ================================================ basic-demo
================================================ FILE: example/web-art-syntax/compile-error.html ================================================ debug-demo

错误捕获(请打开控制台)

================================================ FILE: example/web-art-syntax/compile.html ================================================ compile-demo

在javascript中存放模板

================================================ FILE: example/web-art-syntax/filter.html ================================================ helper-demo

自定义过滤器

================================================ FILE: example/web-art-syntax/include.html ================================================ include-demo
================================================ FILE: example/web-art-syntax/no-escape.html ================================================ no escape-demo

不转义HTML

================================================ FILE: example/web-art-syntax/print.html ================================================ print-demo

print

================================================ FILE: example/web-art-syntax/runtime-error.html ================================================ debug-demo

错误捕获(请打开控制台)

================================================ FILE: example/web-ie-compatible/index.html ================================================ IE
================================================ FILE: example/web-native-syntax/basic.html ================================================ basic-demo
================================================ FILE: example/web-native-syntax/compile-error.html ================================================ debug-demo

错误捕获(请打开控制台)

================================================ FILE: example/web-native-syntax/compile.html ================================================ compile-demo

在javascript中存放模板

================================================ FILE: example/web-native-syntax/filter.html ================================================ helper-demo

自定义过滤器

================================================ FILE: example/web-native-syntax/include.html ================================================ include-demo
================================================ FILE: example/web-native-syntax/no-escape.html ================================================ no escape-demo

不转义HTML

================================================ FILE: example/web-native-syntax/print.html ================================================ print-demo

print

================================================ FILE: example/web-native-syntax/runtime-error.html ================================================ debug-demo

错误捕获(请打开控制台)

================================================ FILE: example/web-requirejs/index.html ================================================ basic-demo
================================================ FILE: example/web-requirejs/require.js ================================================ /** vim: et:ts=4:sw=4:sts=4 * @license RequireJS 2.3.3 Copyright jQuery Foundation and other contributors. * Released under MIT license, https://github.com/requirejs/requirejs/blob/master/LICENSE */ var requirejs,require,define;!function(global,setTimeout){function commentReplace(e,t){return t||""}function isFunction(e){return"[object Function]"===ostring.call(e)}function isArray(e){return"[object Array]"===ostring.call(e)}function each(e,t){if(e){var i;for(i=0;i-1&&(!e[i]||!t(e[i],i,e));i-=1);}}function hasProp(e,t){return hasOwn.call(e,t)}function getOwn(e,t){return hasProp(e,t)&&e[t]}function eachProp(e,t){var i;for(i in e)if(hasProp(e,i)&&t(e[i],i))break}function mixin(e,t,i,r){return t&&eachProp(t,function(t,n){!i&&hasProp(e,n)||(!r||"object"!=typeof t||!t||isArray(t)||isFunction(t)||t instanceof RegExp?e[n]=t:(e[n]||(e[n]={}),mixin(e[n],t,i,r)))}),e}function bind(e,t){return function(){return t.apply(e,arguments)}}function scripts(){return document.getElementsByTagName("script")}function defaultOnError(e){throw e}function getGlobal(e){if(!e)return e;var t=global;return each(e.split("."),function(e){t=t[e]}),t}function makeError(e,t,i,r){var n=new Error(t+"\nhttp://requirejs.org/docs/errors.html#"+e);return n.requireType=e,n.requireModules=r,i&&(n.originalError=i),n}function newContext(e){function t(e){var t,i;for(t=0;t0&&(e.splice(t-1,2),t-=2)}}function i(e,i,r){var n,o,a,s,u,c,d,p,f,l,h,m,g=i&&i.split("/"),v=y.map,x=v&&v["*"];if(e&&(e=e.split("/"),d=e.length-1,y.nodeIdCompat&&jsSuffixRegExp.test(e[d])&&(e[d]=e[d].replace(jsSuffixRegExp,"")),"."===e[0].charAt(0)&&g&&(m=g.slice(0,g.length-1),e=m.concat(e)),t(e),e=e.join("/")),r&&v&&(g||x)){a=e.split("/");e:for(s=a.length;s>0;s-=1){if(c=a.slice(0,s).join("/"),g)for(u=g.length;u>0;u-=1)if(o=getOwn(v,g.slice(0,u).join("/")),o&&(o=getOwn(o,c))){p=o,f=s;break e}!l&&x&&getOwn(x,c)&&(l=getOwn(x,c),h=s)}!p&&l&&(p=l,f=h),p&&(a.splice(0,f,p),e=a.join("/"))}return n=getOwn(y.pkgs,e),n?n:e}function r(e){isBrowser&&each(scripts(),function(t){if(t.getAttribute("data-requiremodule")===e&&t.getAttribute("data-requirecontext")===q.contextName)return t.parentNode.removeChild(t),!0})}function n(e){var t=getOwn(y.paths,e);if(t&&isArray(t)&&t.length>1)return t.shift(),q.require.undef(e),q.makeRequire(null,{skipMap:!0})([e]),!0}function o(e){var t,i=e?e.indexOf("!"):-1;return i>-1&&(t=e.substring(0,i),e=e.substring(i+1,e.length)),[t,e]}function a(e,t,r,n){var a,s,u,c,d=null,p=t?t.name:null,f=e,l=!0,h="";return e||(l=!1,e="_@r"+(T+=1)),c=o(e),d=c[0],e=c[1],d&&(d=i(d,p,n),s=getOwn(j,d)),e&&(d?h=r?e:s&&s.normalize?s.normalize(e,function(e){return i(e,p,n)}):e.indexOf("!")===-1?i(e,p,n):e:(h=i(e,p,n),c=o(h),d=c[0],h=c[1],r=!0,a=q.nameToUrl(h))),u=!d||s||r?"":"_unnormalized"+(A+=1),{prefix:d,name:h,parentMap:t,unnormalized:!!u,url:a,originalName:f,isDefine:l,id:(d?d+"!"+h:h)+u}}function s(e){var t=e.id,i=getOwn(S,t);return i||(i=S[t]=new q.Module(e)),i}function u(e,t,i){var r=e.id,n=getOwn(S,r);!hasProp(j,r)||n&&!n.defineEmitComplete?(n=s(e),n.error&&"error"===t?i(n.error):n.on(t,i)):"defined"===t&&i(j[r])}function c(e,t){var i=e.requireModules,r=!1;t?t(e):(each(i,function(t){var i=getOwn(S,t);i&&(i.error=e,i.events.error&&(r=!0,i.emit("error",e)))}),r||req.onError(e))}function d(){globalDefQueue.length&&(each(globalDefQueue,function(e){var t=e[0];"string"==typeof t&&(q.defQueueMap[t]=!0),O.push(e)}),globalDefQueue=[])}function p(e){delete S[e],delete k[e]}function f(e,t,i){var r=e.map.id;e.error?e.emit("error",e.error):(t[r]=!0,each(e.depMaps,function(r,n){var o=r.id,a=getOwn(S,o);!a||e.depMatched[n]||i[o]||(getOwn(t,o)?(e.defineDep(n,j[o]),e.check()):f(a,t,i))}),i[r]=!0)}function l(){var e,t,i=1e3*y.waitSeconds,o=i&&q.startTime+i<(new Date).getTime(),a=[],s=[],u=!1,d=!0;if(!x){if(x=!0,eachProp(k,function(e){var i=e.map,c=i.id;if(e.enabled&&(i.isDefine||s.push(e),!e.error))if(!e.inited&&o)n(c)?(t=!0,u=!0):(a.push(c),r(c));else if(!e.inited&&e.fetched&&i.isDefine&&(u=!0,!i.prefix))return d=!1}),o&&a.length)return e=makeError("timeout","Load timeout for modules: "+a,null,a),e.contextName=q.contextName,c(e);d&&each(s,function(e){f(e,{},{})}),o&&!t||!u||!isBrowser&&!isWebWorker||w||(w=setTimeout(function(){w=0,l()},50)),x=!1}}function h(e){hasProp(j,e[0])||s(a(e[0],null,!0)).init(e[1],e[2])}function m(e,t,i,r){e.detachEvent&&!isOpera?r&&e.detachEvent(r,t):e.removeEventListener(i,t,!1)}function g(e){var t=e.currentTarget||e.srcElement;return m(t,q.onScriptLoad,"load","onreadystatechange"),m(t,q.onScriptError,"error"),{node:t,id:t&&t.getAttribute("data-requiremodule")}}function v(){var e;for(d();O.length;){if(e=O.shift(),null===e[0])return c(makeError("mismatch","Mismatched anonymous define() module: "+e[e.length-1]));h(e)}q.defQueueMap={}}var x,b,q,E,w,y={waitSeconds:7,baseUrl:"./",paths:{},bundles:{},pkgs:{},shim:{},config:{}},S={},k={},M={},O=[],j={},P={},R={},T=1,A=1;return E={require:function(e){return e.require?e.require:e.require=q.makeRequire(e.map)},exports:function(e){if(e.usingExports=!0,e.map.isDefine)return e.exports?j[e.map.id]=e.exports:e.exports=j[e.map.id]={}},module:function(e){return e.module?e.module:e.module={id:e.map.id,uri:e.map.url,config:function(){return getOwn(y.config,e.map.id)||{}},exports:e.exports||(e.exports={})}}},b=function(e){this.events=getOwn(M,e.id)||{},this.map=e,this.shim=getOwn(y.shim,e.id),this.depExports=[],this.depMaps=[],this.depMatched=[],this.pluginMaps={},this.depCount=0},b.prototype={init:function(e,t,i,r){r=r||{},this.inited||(this.factory=t,i?this.on("error",i):this.events.error&&(i=bind(this,function(e){this.emit("error",e)})),this.depMaps=e&&e.slice(0),this.errback=i,this.inited=!0,this.ignore=r.ignore,r.enabled||this.enabled?this.enable():this.check())},defineDep:function(e,t){this.depMatched[e]||(this.depMatched[e]=!0,this.depCount-=1,this.depExports[e]=t)},fetch:function(){if(!this.fetched){this.fetched=!0,q.startTime=(new Date).getTime();var e=this.map;return this.shim?void q.makeRequire(this.map,{enableBuildCallback:!0})(this.shim.deps||[],bind(this,function(){return e.prefix?this.callPlugin():this.load()})):e.prefix?this.callPlugin():this.load()}},load:function(){var e=this.map.url;P[e]||(P[e]=!0,q.load(this.map.id,e))},check:function(){if(this.enabled&&!this.enabling){var e,t,i=this.map.id,r=this.depExports,n=this.exports,o=this.factory;if(this.inited){if(this.error)this.emit("error",this.error);else if(!this.defining){if(this.defining=!0,this.depCount<1&&!this.defined){if(isFunction(o)){if(this.events.error&&this.map.isDefine||req.onError!==defaultOnError)try{n=q.execCb(i,o,r,n)}catch(t){e=t}else n=q.execCb(i,o,r,n);if(this.map.isDefine&&void 0===n&&(t=this.module,t?n=t.exports:this.usingExports&&(n=this.exports)),e)return e.requireMap=this.map,e.requireModules=this.map.isDefine?[this.map.id]:null,e.requireType=this.map.isDefine?"define":"require",c(this.error=e)}else n=o;if(this.exports=n,this.map.isDefine&&!this.ignore&&(j[i]=n,req.onResourceLoad)){var a=[];each(this.depMaps,function(e){a.push(e.normalizedMap||e)}),req.onResourceLoad(q,this.map,a)}p(i),this.defined=!0}this.defining=!1,this.defined&&!this.defineEmitted&&(this.defineEmitted=!0,this.emit("defined",this.exports),this.defineEmitComplete=!0)}}else hasProp(q.defQueueMap,i)||this.fetch()}},callPlugin:function(){var e=this.map,t=e.id,r=a(e.prefix);this.depMaps.push(r),u(r,"defined",bind(this,function(r){var n,o,d,f=getOwn(R,this.map.id),l=this.map.name,h=this.map.parentMap?this.map.parentMap.name:null,m=q.makeRequire(e.parentMap,{enableBuildCallback:!0});return this.map.unnormalized?(r.normalize&&(l=r.normalize(l,function(e){return i(e,h,!0)})||""),o=a(e.prefix+"!"+l,this.map.parentMap,!0),u(o,"defined",bind(this,function(e){this.map.normalizedMap=o,this.init([],function(){return e},null,{enabled:!0,ignore:!0})})),d=getOwn(S,o.id),void(d&&(this.depMaps.push(o),this.events.error&&d.on("error",bind(this,function(e){this.emit("error",e)})),d.enable()))):f?(this.map.url=q.nameToUrl(f),void this.load()):(n=bind(this,function(e){this.init([],function(){return e},null,{enabled:!0})}),n.error=bind(this,function(e){this.inited=!0,this.error=e,e.requireModules=[t],eachProp(S,function(e){0===e.map.id.indexOf(t+"_unnormalized")&&p(e.map.id)}),c(e)}),n.fromText=bind(this,function(i,r){var o=e.name,u=a(o),d=useInteractive;r&&(i=r),d&&(useInteractive=!1),s(u),hasProp(y.config,t)&&(y.config[o]=y.config[t]);try{req.exec(i)}catch(e){return c(makeError("fromtexteval","fromText eval for "+t+" failed: "+e,e,[t]))}d&&(useInteractive=!0),this.depMaps.push(u),q.completeLoad(o),m([o],n)}),void r.load(e.name,m,n,y))})),q.enable(r,this),this.pluginMaps[r.id]=r},enable:function(){k[this.map.id]=this,this.enabled=!0,this.enabling=!0,each(this.depMaps,bind(this,function(e,t){var i,r,n;if("string"==typeof e){if(e=a(e,this.map.isDefine?this.map:this.map.parentMap,!1,!this.skipMap),this.depMaps[t]=e,n=getOwn(E,e.id))return void(this.depExports[t]=n(this));this.depCount+=1,u(e,"defined",bind(this,function(e){this.undefed||(this.defineDep(t,e),this.check())})),this.errback?u(e,"error",bind(this,this.errback)):this.events.error&&u(e,"error",bind(this,function(e){this.emit("error",e)}))}i=e.id,r=S[i],hasProp(E,i)||!r||r.enabled||q.enable(e,this)})),eachProp(this.pluginMaps,bind(this,function(e){var t=getOwn(S,e.id);t&&!t.enabled&&q.enable(e,this)})),this.enabling=!1,this.check()},on:function(e,t){var i=this.events[e];i||(i=this.events[e]=[]),i.push(t)},emit:function(e,t){each(this.events[e],function(e){e(t)}),"error"===e&&delete this.events[e]}},q={config:y,contextName:e,registry:S,defined:j,urlFetched:P,defQueue:O,defQueueMap:{},Module:b,makeModuleMap:a,nextTick:req.nextTick,onError:c,configure:function(e){if(e.baseUrl&&"/"!==e.baseUrl.charAt(e.baseUrl.length-1)&&(e.baseUrl+="/"),"string"==typeof e.urlArgs){var t=e.urlArgs;e.urlArgs=function(e,i){return(i.indexOf("?")===-1?"?":"&")+t}}var i=y.shim,r={paths:!0,bundles:!0,config:!0,map:!0};eachProp(e,function(e,t){r[t]?(y[t]||(y[t]={}),mixin(y[t],e,!0,!0)):y[t]=e}),e.bundles&&eachProp(e.bundles,function(e,t){each(e,function(e){e!==t&&(R[e]=t)})}),e.shim&&(eachProp(e.shim,function(e,t){isArray(e)&&(e={deps:e}),!e.exports&&!e.init||e.exportsFn||(e.exportsFn=q.makeShimExports(e)),i[t]=e}),y.shim=i),e.packages&&each(e.packages,function(e){var t,i;e="string"==typeof e?{name:e}:e,i=e.name,t=e.location,t&&(y.paths[i]=e.location),y.pkgs[i]=e.name+"/"+(e.main||"main").replace(currDirRegExp,"").replace(jsSuffixRegExp,"")}),eachProp(S,function(e,t){e.inited||e.map.unnormalized||(e.map=a(t,null,!0))}),(e.deps||e.callback)&&q.require(e.deps||[],e.callback)},makeShimExports:function(e){function t(){var t;return e.init&&(t=e.init.apply(global,arguments)),t||e.exports&&getGlobal(e.exports)}return t},makeRequire:function(t,n){function o(i,r,u){var d,p,f;return n.enableBuildCallback&&r&&isFunction(r)&&(r.__requireJsBuild=!0),"string"==typeof i?isFunction(r)?c(makeError("requireargs","Invalid require call"),u):t&&hasProp(E,i)?E[i](S[t.id]):req.get?req.get(q,i,t,o):(p=a(i,t,!1,!0),d=p.id,hasProp(j,d)?j[d]:c(makeError("notloaded",'Module name "'+d+'" has not been loaded yet for context: '+e+(t?"":". Use require([])")))):(v(),q.nextTick(function(){v(),f=s(a(null,t)),f.skipMap=n.skipMap,f.init(i,r,u,{enabled:!0}),l()}),o)}return n=n||{},mixin(o,{isBrowser:isBrowser,toUrl:function(e){var r,n=e.lastIndexOf("."),o=e.split("/")[0],a="."===o||".."===o;return n!==-1&&(!a||n>1)&&(r=e.substring(n,e.length),e=e.substring(0,n)),q.nameToUrl(i(e,t&&t.id,!0),r,!0)},defined:function(e){return hasProp(j,a(e,t,!1,!0).id)},specified:function(e){return e=a(e,t,!1,!0).id,hasProp(j,e)||hasProp(S,e)}}),t||(o.undef=function(e){d();var i=a(e,t,!0),n=getOwn(S,e);n.undefed=!0,r(e),delete j[e],delete P[i.url],delete M[e],eachReverse(O,function(t,i){t[0]===e&&O.splice(i,1)}),delete q.defQueueMap[e],n&&(n.events.defined&&(M[e]=n.events),p(e))}),o},enable:function(e){var t=getOwn(S,e.id);t&&s(e).enable()},completeLoad:function(e){var t,i,r,o=getOwn(y.shim,e)||{},a=o.exports;for(d();O.length;){if(i=O.shift(),null===i[0]){if(i[0]=e,t)break;t=!0}else i[0]===e&&(t=!0);h(i)}if(q.defQueueMap={},r=getOwn(S,e),!t&&!hasProp(j,e)&&r&&!r.inited){if(!(!y.enforceDefine||a&&getGlobal(a)))return n(e)?void 0:c(makeError("nodefine","No define call for "+e,null,[e]));h([e,o.deps||[],o.exportsFn])}l()},nameToUrl:function(e,t,i){var r,n,o,a,s,u,c,d=getOwn(y.pkgs,e);if(d&&(e=d),c=getOwn(R,e))return q.nameToUrl(c,t,i);if(req.jsExtRegExp.test(e))s=e+(t||"");else{for(r=y.paths,n=e.split("/"),o=n.length;o>0;o-=1)if(a=n.slice(0,o).join("/"),u=getOwn(r,a)){isArray(u)&&(u=u[0]),n.splice(0,o,u);break}s=n.join("/"),s+=t||(/^data\:|^blob\:|\?/.test(s)||i?"":".js"),s=("/"===s.charAt(0)||s.match(/^[\w\+\.\-]+:/)?"":y.baseUrl)+s}return y.urlArgs&&!/^blob\:/.test(s)?s+y.urlArgs(e,s):s},load:function(e,t){req.load(q,e,t)},execCb:function(e,t,i,r){return t.apply(r,i)},onScriptLoad:function(e){if("load"===e.type||readyRegExp.test((e.currentTarget||e.srcElement).readyState)){interactiveScript=null;var t=g(e);q.completeLoad(t.id)}},onScriptError:function(e){var t=g(e);if(!n(t.id)){var i=[];return eachProp(S,function(e,r){0!==r.indexOf("_@r")&&each(e.depMaps,function(e){if(e.id===t.id)return i.push(r),!0})}),c(makeError("scripterror",'Script error for "'+t.id+(i.length?'", needed by: '+i.join(", "):'"'),e,[t.id]))}}},q.require=q.makeRequire(),q}function getInteractiveScript(){return interactiveScript&&"interactive"===interactiveScript.readyState?interactiveScript:(eachReverse(scripts(),function(e){if("interactive"===e.readyState)return interactiveScript=e}),interactiveScript)}var req,s,head,baseElement,dataMain,src,interactiveScript,currentlyAddingScript,mainScript,subPath,version="2.3.3",commentRegExp=/\/\*[\s\S]*?\*\/|([^:"'=]|^)\/\/.*$/gm,cjsRequireRegExp=/[^.]\s*require\s*\(\s*["']([^'"\s]+)["']\s*\)/g,jsSuffixRegExp=/\.js$/,currDirRegExp=/^\.\//,op=Object.prototype,ostring=op.toString,hasOwn=op.hasOwnProperty,isBrowser=!("undefined"==typeof window||"undefined"==typeof navigator||!window.document),isWebWorker=!isBrowser&&"undefined"!=typeof importScripts,readyRegExp=isBrowser&&"PLAYSTATION 3"===navigator.platform?/^complete$/:/^(complete|loaded)$/,defContextName="_",isOpera="undefined"!=typeof opera&&"[object Opera]"===opera.toString(),contexts={},cfg={},globalDefQueue=[],useInteractive=!1;if("undefined"==typeof define){if("undefined"!=typeof requirejs){if(isFunction(requirejs))return;cfg=requirejs,requirejs=void 0}"undefined"==typeof require||isFunction(require)||(cfg=require,require=void 0),req=requirejs=function(e,t,i,r){var n,o,a=defContextName;return isArray(e)||"string"==typeof e||(o=e,isArray(t)?(e=t,t=i,i=r):e=[]),o&&o.context&&(a=o.context),n=getOwn(contexts,a),n||(n=contexts[a]=req.s.newContext(a)),o&&n.configure(o),n.require(e,t,i)},req.config=function(e){return req(e)},req.nextTick="undefined"!=typeof setTimeout?function(e){setTimeout(e,4)}:function(e){e()},require||(require=req),req.version=version,req.jsExtRegExp=/^\/|:|\?|\.js$/,req.isBrowser=isBrowser,s=req.s={contexts:contexts,newContext:newContext},req({}),each(["toUrl","undef","defined","specified"],function(e){req[e]=function(){var t=contexts[defContextName];return t.require[e].apply(t,arguments)}}),isBrowser&&(head=s.head=document.getElementsByTagName("head")[0],baseElement=document.getElementsByTagName("base")[0],baseElement&&(head=s.head=baseElement.parentNode)),req.onError=defaultOnError,req.createNode=function(e,t,i){var r=e.xhtml?document.createElementNS("http://www.w3.org/1999/xhtml","html:script"):document.createElement("script");return r.type=e.scriptType||"text/javascript",r.charset="utf-8",r.async=!0,r},req.load=function(e,t,i){var r,n=e&&e.config||{};if(isBrowser)return r=req.createNode(n,t,i),r.setAttribute("data-requirecontext",e.contextName),r.setAttribute("data-requiremodule",t),!r.attachEvent||r.attachEvent.toString&&r.attachEvent.toString().indexOf("[native code")<0||isOpera?(r.addEventListener("load",e.onScriptLoad,!1),r.addEventListener("error",e.onScriptError,!1)):(useInteractive=!0,r.attachEvent("onreadystatechange",e.onScriptLoad)),r.src=i,n.onNodeCreated&&n.onNodeCreated(r,n,t,i),currentlyAddingScript=r,baseElement?head.insertBefore(r,baseElement):head.appendChild(r),currentlyAddingScript=null,r;if(isWebWorker)try{setTimeout(function(){},0),importScripts(i),e.completeLoad(t)}catch(r){e.onError(makeError("importscripts","importScripts failed for "+t+" at "+i,r,[t]))}},isBrowser&&!cfg.skipDataMain&&eachReverse(scripts(),function(e){if(head||(head=e.parentNode),dataMain=e.getAttribute("data-main"))return mainScript=dataMain,cfg.baseUrl||mainScript.indexOf("!")!==-1||(src=mainScript.split("/"),mainScript=src.pop(),subPath=src.length?src.join("/")+"/":"./",cfg.baseUrl=subPath),mainScript=mainScript.replace(jsSuffixRegExp,""),req.jsExtRegExp.test(mainScript)&&(mainScript=dataMain),cfg.deps=cfg.deps?cfg.deps.concat(mainScript):[mainScript],!0}),define=function(e,t,i){var r,n;"string"!=typeof e&&(i=t,t=e,e=null),isArray(t)||(i=t,t=null),!t&&isFunction(i)&&(t=[],i.length&&(i.toString().replace(commentRegExp,commentReplace).replace(cjsRequireRegExp,function(e,i){t.push(i)}),t=(1===i.length?["require"]:["require","exports","module"]).concat(t))),useInteractive&&(r=currentlyAddingScript||getInteractiveScript(),r&&(e||(e=r.getAttribute("data-requiremodule")),n=contexts[r.getAttribute("data-requirecontext")])),n?(n.defQueue.push([e,t,i]),n.defQueueMap[e]=!0):globalDefQueue.push([e,t,i])},define.amd={jQuery:!0},req.exec=function(text){return eval(text)},req(cfg)}}(this,"undefined"==typeof setTimeout?void 0:setTimeout); ================================================ FILE: example/web-test-speed/index.html ================================================ Template Engine Rendering Speed Test
================================================ FILE: example/web-test-speed/js/handlebars.js ================================================ /*! handlebars v4.0.5 Copyright (C) 2011-2015 by Yehuda Katz Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. @license */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["Handlebars"] = factory(); else root["Handlebars"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _handlebarsRuntime = __webpack_require__(2); var _handlebarsRuntime2 = _interopRequireDefault(_handlebarsRuntime); // Compiler imports var _handlebarsCompilerAst = __webpack_require__(21); var _handlebarsCompilerAst2 = _interopRequireDefault(_handlebarsCompilerAst); var _handlebarsCompilerBase = __webpack_require__(22); var _handlebarsCompilerCompiler = __webpack_require__(27); var _handlebarsCompilerJavascriptCompiler = __webpack_require__(28); var _handlebarsCompilerJavascriptCompiler2 = _interopRequireDefault(_handlebarsCompilerJavascriptCompiler); var _handlebarsCompilerVisitor = __webpack_require__(25); var _handlebarsCompilerVisitor2 = _interopRequireDefault(_handlebarsCompilerVisitor); var _handlebarsNoConflict = __webpack_require__(20); var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict); var _create = _handlebarsRuntime2['default'].create; function create() { var hb = _create(); hb.compile = function (input, options) { return _handlebarsCompilerCompiler.compile(input, options, hb); }; hb.precompile = function (input, options) { return _handlebarsCompilerCompiler.precompile(input, options, hb); }; hb.AST = _handlebarsCompilerAst2['default']; hb.Compiler = _handlebarsCompilerCompiler.Compiler; hb.JavaScriptCompiler = _handlebarsCompilerJavascriptCompiler2['default']; hb.Parser = _handlebarsCompilerBase.parser; hb.parse = _handlebarsCompilerBase.parse; return hb; } var inst = create(); inst.create = create; _handlebarsNoConflict2['default'](inst); inst.Visitor = _handlebarsCompilerVisitor2['default']; inst['default'] = inst; exports['default'] = inst; module.exports = exports['default']; /***/ }, /* 1 */ /***/ function(module, exports) { "use strict"; exports["default"] = function (obj) { return obj && obj.__esModule ? obj : { "default": obj }; }; exports.__esModule = true; /***/ }, /* 2 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireWildcard = __webpack_require__(3)['default']; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _handlebarsBase = __webpack_require__(4); var base = _interopRequireWildcard(_handlebarsBase); // Each of these augment the Handlebars object. No need to setup here. // (This is done to easily share code between commonjs and browse envs) var _handlebarsSafeString = __webpack_require__(18); var _handlebarsSafeString2 = _interopRequireDefault(_handlebarsSafeString); var _handlebarsException = __webpack_require__(6); var _handlebarsException2 = _interopRequireDefault(_handlebarsException); var _handlebarsUtils = __webpack_require__(5); var Utils = _interopRequireWildcard(_handlebarsUtils); var _handlebarsRuntime = __webpack_require__(19); var runtime = _interopRequireWildcard(_handlebarsRuntime); var _handlebarsNoConflict = __webpack_require__(20); var _handlebarsNoConflict2 = _interopRequireDefault(_handlebarsNoConflict); // For compatibility and usage outside of module systems, make the Handlebars object a namespace function create() { var hb = new base.HandlebarsEnvironment(); Utils.extend(hb, base); hb.SafeString = _handlebarsSafeString2['default']; hb.Exception = _handlebarsException2['default']; hb.Utils = Utils; hb.escapeExpression = Utils.escapeExpression; hb.VM = runtime; hb.template = function (spec) { return runtime.template(spec, hb); }; return hb; } var inst = create(); inst.create = create; _handlebarsNoConflict2['default'](inst); inst['default'] = inst; exports['default'] = inst; module.exports = exports['default']; /***/ }, /* 3 */ /***/ function(module, exports) { "use strict"; exports["default"] = function (obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj["default"] = obj; return newObj; } }; exports.__esModule = true; /***/ }, /* 4 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.HandlebarsEnvironment = HandlebarsEnvironment; var _utils = __webpack_require__(5); var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); var _helpers = __webpack_require__(7); var _decorators = __webpack_require__(15); var _logger = __webpack_require__(17); var _logger2 = _interopRequireDefault(_logger); var VERSION = '4.0.5'; exports.VERSION = VERSION; var COMPILER_REVISION = 7; exports.COMPILER_REVISION = COMPILER_REVISION; var REVISION_CHANGES = { 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it 2: '== 1.0.0-rc.3', 3: '== 1.0.0-rc.4', 4: '== 1.x.x', 5: '== 2.0.0-alpha.x', 6: '>= 2.0.0-beta.1', 7: '>= 4.0.0' }; exports.REVISION_CHANGES = REVISION_CHANGES; var objectType = '[object Object]'; function HandlebarsEnvironment(helpers, partials, decorators) { this.helpers = helpers || {}; this.partials = partials || {}; this.decorators = decorators || {}; _helpers.registerDefaultHelpers(this); _decorators.registerDefaultDecorators(this); } HandlebarsEnvironment.prototype = { constructor: HandlebarsEnvironment, logger: _logger2['default'], log: _logger2['default'].log, registerHelper: function registerHelper(name, fn) { if (_utils.toString.call(name) === objectType) { if (fn) { throw new _exception2['default']('Arg not supported with multiple helpers'); } _utils.extend(this.helpers, name); } else { this.helpers[name] = fn; } }, unregisterHelper: function unregisterHelper(name) { delete this.helpers[name]; }, registerPartial: function registerPartial(name, partial) { if (_utils.toString.call(name) === objectType) { _utils.extend(this.partials, name); } else { if (typeof partial === 'undefined') { throw new _exception2['default']('Attempting to register a partial called "' + name + '" as undefined'); } this.partials[name] = partial; } }, unregisterPartial: function unregisterPartial(name) { delete this.partials[name]; }, registerDecorator: function registerDecorator(name, fn) { if (_utils.toString.call(name) === objectType) { if (fn) { throw new _exception2['default']('Arg not supported with multiple decorators'); } _utils.extend(this.decorators, name); } else { this.decorators[name] = fn; } }, unregisterDecorator: function unregisterDecorator(name) { delete this.decorators[name]; } }; var log = _logger2['default'].log; exports.log = log; exports.createFrame = _utils.createFrame; exports.logger = _logger2['default']; /***/ }, /* 5 */ /***/ function(module, exports) { 'use strict'; exports.__esModule = true; exports.extend = extend; exports.indexOf = indexOf; exports.escapeExpression = escapeExpression; exports.isEmpty = isEmpty; exports.createFrame = createFrame; exports.blockParams = blockParams; exports.appendContextPath = appendContextPath; var escape = { '&': '&', '<': '<', '>': '>', '"': '"', "'": ''', '`': '`', '=': '=' }; var badChars = /[&<>"'`=]/g, possible = /[&<>"'`=]/; function escapeChar(chr) { return escape[chr]; } function extend(obj /* , ...source */) { for (var i = 1; i < arguments.length; i++) { for (var key in arguments[i]) { if (Object.prototype.hasOwnProperty.call(arguments[i], key)) { obj[key] = arguments[i][key]; } } } return obj; } var toString = Object.prototype.toString; exports.toString = toString; // Sourced from lodash // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt /* eslint-disable func-style */ var isFunction = function isFunction(value) { return typeof value === 'function'; }; // fallback for older versions of Chrome and Safari /* istanbul ignore next */ if (isFunction(/x/)) { exports.isFunction = isFunction = function (value) { return typeof value === 'function' && toString.call(value) === '[object Function]'; }; } exports.isFunction = isFunction; /* eslint-enable func-style */ /* istanbul ignore next */ var isArray = Array.isArray || function (value) { return value && typeof value === 'object' ? toString.call(value) === '[object Array]' : false; }; exports.isArray = isArray; // Older IE versions do not directly support indexOf so we must implement our own, sadly. function indexOf(array, value) { for (var i = 0, len = array.length; i < len; i++) { if (array[i] === value) { return i; } } return -1; } function escapeExpression(string) { if (typeof string !== 'string') { // don't escape SafeStrings, since they're already safe if (string && string.toHTML) { return string.toHTML(); } else if (string == null) { return ''; } else if (!string) { return string + ''; } // Force a string conversion as this will be done by the append regardless and // the regex test will do this transparently behind the scenes, causing issues if // an object's to string has escaped characters in it. string = '' + string; } if (!possible.test(string)) { return string; } return string.replace(badChars, escapeChar); } function isEmpty(value) { if (!value && value !== 0) { return true; } else if (isArray(value) && value.length === 0) { return true; } else { return false; } } function createFrame(object) { var frame = extend({}, object); frame._parent = object; return frame; } function blockParams(params, ids) { params.path = ids; return params; } function appendContextPath(contextPath, id) { return (contextPath ? contextPath + '.' : '') + id; } /***/ }, /* 6 */ /***/ function(module, exports) { 'use strict'; exports.__esModule = true; var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack']; function Exception(message, node) { var loc = node && node.loc, line = undefined, column = undefined; if (loc) { line = loc.start.line; column = loc.start.column; message += ' - ' + line + ':' + column; } var tmp = Error.prototype.constructor.call(this, message); // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work. for (var idx = 0; idx < errorProps.length; idx++) { this[errorProps[idx]] = tmp[errorProps[idx]]; } /* istanbul ignore else */ if (Error.captureStackTrace) { Error.captureStackTrace(this, Exception); } if (loc) { this.lineNumber = line; this.column = column; } } Exception.prototype = new Error(); exports['default'] = Exception; module.exports = exports['default']; /***/ }, /* 7 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.registerDefaultHelpers = registerDefaultHelpers; var _helpersBlockHelperMissing = __webpack_require__(8); var _helpersBlockHelperMissing2 = _interopRequireDefault(_helpersBlockHelperMissing); var _helpersEach = __webpack_require__(9); var _helpersEach2 = _interopRequireDefault(_helpersEach); var _helpersHelperMissing = __webpack_require__(10); var _helpersHelperMissing2 = _interopRequireDefault(_helpersHelperMissing); var _helpersIf = __webpack_require__(11); var _helpersIf2 = _interopRequireDefault(_helpersIf); var _helpersLog = __webpack_require__(12); var _helpersLog2 = _interopRequireDefault(_helpersLog); var _helpersLookup = __webpack_require__(13); var _helpersLookup2 = _interopRequireDefault(_helpersLookup); var _helpersWith = __webpack_require__(14); var _helpersWith2 = _interopRequireDefault(_helpersWith); function registerDefaultHelpers(instance) { _helpersBlockHelperMissing2['default'](instance); _helpersEach2['default'](instance); _helpersHelperMissing2['default'](instance); _helpersIf2['default'](instance); _helpersLog2['default'](instance); _helpersLookup2['default'](instance); _helpersWith2['default'](instance); } /***/ }, /* 8 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(5); exports['default'] = function (instance) { instance.registerHelper('blockHelperMissing', function (context, options) { var inverse = options.inverse, fn = options.fn; if (context === true) { return fn(this); } else if (context === false || context == null) { return inverse(this); } else if (_utils.isArray(context)) { if (context.length > 0) { if (options.ids) { options.ids = [options.name]; } return instance.helpers.each(context, options); } else { return inverse(this); } } else { if (options.data && options.ids) { var data = _utils.createFrame(options.data); data.contextPath = _utils.appendContextPath(options.data.contextPath, options.name); options = { data: data }; } return fn(context, options); } }); }; module.exports = exports['default']; /***/ }, /* 9 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _utils = __webpack_require__(5); var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); exports['default'] = function (instance) { instance.registerHelper('each', function (context, options) { if (!options) { throw new _exception2['default']('Must pass iterator to #each'); } var fn = options.fn, inverse = options.inverse, i = 0, ret = '', data = undefined, contextPath = undefined; if (options.data && options.ids) { contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]) + '.'; } if (_utils.isFunction(context)) { context = context.call(this); } if (options.data) { data = _utils.createFrame(options.data); } function execIteration(field, index, last) { if (data) { data.key = field; data.index = index; data.first = index === 0; data.last = !!last; if (contextPath) { data.contextPath = contextPath + field; } } ret = ret + fn(context[field], { data: data, blockParams: _utils.blockParams([context[field], field], [contextPath + field, null]) }); } if (context && typeof context === 'object') { if (_utils.isArray(context)) { for (var j = context.length; i < j; i++) { if (i in context) { execIteration(i, i, i === context.length - 1); } } } else { var priorKey = undefined; for (var key in context) { if (context.hasOwnProperty(key)) { // We're running the iterations one step out of sync so we can detect // the last iteration without have to scan the object twice and create // an itermediate keys array. if (priorKey !== undefined) { execIteration(priorKey, i - 1); } priorKey = key; i++; } } if (priorKey !== undefined) { execIteration(priorKey, i - 1, true); } } } if (i === 0) { ret = inverse(this); } return ret; }); }; module.exports = exports['default']; /***/ }, /* 10 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); exports['default'] = function (instance) { instance.registerHelper('helperMissing', function () /* [args, ]options */{ if (arguments.length === 1) { // A missing field in a {{foo}} construct. return undefined; } else { // Someone is actually trying to call something, blow up. throw new _exception2['default']('Missing helper: "' + arguments[arguments.length - 1].name + '"'); } }); }; module.exports = exports['default']; /***/ }, /* 11 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(5); exports['default'] = function (instance) { instance.registerHelper('if', function (conditional, options) { if (_utils.isFunction(conditional)) { conditional = conditional.call(this); } // Default behavior is to render the positive path if the value is truthy and not empty. // The `includeZero` option may be set to treat the condtional as purely not empty based on the // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative. if (!options.hash.includeZero && !conditional || _utils.isEmpty(conditional)) { return options.inverse(this); } else { return options.fn(this); } }); instance.registerHelper('unless', function (conditional, options) { return instance.helpers['if'].call(this, conditional, { fn: options.inverse, inverse: options.fn, hash: options.hash }); }); }; module.exports = exports['default']; /***/ }, /* 12 */ /***/ function(module, exports) { 'use strict'; exports.__esModule = true; exports['default'] = function (instance) { instance.registerHelper('log', function () /* message, options */{ var args = [undefined], options = arguments[arguments.length - 1]; for (var i = 0; i < arguments.length - 1; i++) { args.push(arguments[i]); } var level = 1; if (options.hash.level != null) { level = options.hash.level; } else if (options.data && options.data.level != null) { level = options.data.level; } args[0] = level; instance.log.apply(instance, args); }); }; module.exports = exports['default']; /***/ }, /* 13 */ /***/ function(module, exports) { 'use strict'; exports.__esModule = true; exports['default'] = function (instance) { instance.registerHelper('lookup', function (obj, field) { return obj && obj[field]; }); }; module.exports = exports['default']; /***/ }, /* 14 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(5); exports['default'] = function (instance) { instance.registerHelper('with', function (context, options) { if (_utils.isFunction(context)) { context = context.call(this); } var fn = options.fn; if (!_utils.isEmpty(context)) { var data = options.data; if (options.data && options.ids) { data = _utils.createFrame(options.data); data.contextPath = _utils.appendContextPath(options.data.contextPath, options.ids[0]); } return fn(context, { data: data, blockParams: _utils.blockParams([context], [data && data.contextPath]) }); } else { return options.inverse(this); } }); }; module.exports = exports['default']; /***/ }, /* 15 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.registerDefaultDecorators = registerDefaultDecorators; var _decoratorsInline = __webpack_require__(16); var _decoratorsInline2 = _interopRequireDefault(_decoratorsInline); function registerDefaultDecorators(instance) { _decoratorsInline2['default'](instance); } /***/ }, /* 16 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(5); exports['default'] = function (instance) { instance.registerDecorator('inline', function (fn, props, container, options) { var ret = fn; if (!props.partials) { props.partials = {}; ret = function (context, options) { // Create a new partials stack frame prior to exec. var original = container.partials; container.partials = _utils.extend({}, original, props.partials); var ret = fn(context, options); container.partials = original; return ret; }; } props.partials[options.args[0]] = options.fn; return ret; }); }; module.exports = exports['default']; /***/ }, /* 17 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(5); var logger = { methodMap: ['debug', 'info', 'warn', 'error'], level: 'info', // Maps a given level value to the `methodMap` indexes above. lookupLevel: function lookupLevel(level) { if (typeof level === 'string') { var levelMap = _utils.indexOf(logger.methodMap, level.toLowerCase()); if (levelMap >= 0) { level = levelMap; } else { level = parseInt(level, 10); } } return level; }, // Can be overridden in the host environment log: function log(level) { level = logger.lookupLevel(level); if (typeof console !== 'undefined' && logger.lookupLevel(logger.level) <= level) { var method = logger.methodMap[level]; if (!console[method]) { // eslint-disable-line no-console method = 'log'; } for (var _len = arguments.length, message = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { message[_key - 1] = arguments[_key]; } console[method].apply(console, message); // eslint-disable-line no-console } } }; exports['default'] = logger; module.exports = exports['default']; /***/ }, /* 18 */ /***/ function(module, exports) { // Build out our basic SafeString type 'use strict'; exports.__esModule = true; function SafeString(string) { this.string = string; } SafeString.prototype.toString = SafeString.prototype.toHTML = function () { return '' + this.string; }; exports['default'] = SafeString; module.exports = exports['default']; /***/ }, /* 19 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireWildcard = __webpack_require__(3)['default']; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.checkRevision = checkRevision; exports.template = template; exports.wrapProgram = wrapProgram; exports.resolvePartial = resolvePartial; exports.invokePartial = invokePartial; exports.noop = noop; var _utils = __webpack_require__(5); var Utils = _interopRequireWildcard(_utils); var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); var _base = __webpack_require__(4); function checkRevision(compilerInfo) { var compilerRevision = compilerInfo && compilerInfo[0] || 1, currentRevision = _base.COMPILER_REVISION; if (compilerRevision !== currentRevision) { if (compilerRevision < currentRevision) { var runtimeVersions = _base.REVISION_CHANGES[currentRevision], compilerVersions = _base.REVISION_CHANGES[compilerRevision]; throw new _exception2['default']('Template was precompiled with an older version of Handlebars than the current runtime. ' + 'Please update your precompiler to a newer version (' + runtimeVersions + ') or downgrade your runtime to an older version (' + compilerVersions + ').'); } else { // Use the embedded version info since the runtime doesn't know about this revision yet throw new _exception2['default']('Template was precompiled with a newer version of Handlebars than the current runtime. ' + 'Please update your runtime to a newer version (' + compilerInfo[1] + ').'); } } } function template(templateSpec, env) { /* istanbul ignore next */ if (!env) { throw new _exception2['default']('No environment passed to template'); } if (!templateSpec || !templateSpec.main) { throw new _exception2['default']('Unknown template object: ' + typeof templateSpec); } templateSpec.main.decorator = templateSpec.main_d; // Note: Using env.VM references rather than local var references throughout this section to allow // for external users to override these as psuedo-supported APIs. env.VM.checkRevision(templateSpec.compiler); function invokePartialWrapper(partial, context, options) { if (options.hash) { context = Utils.extend({}, context, options.hash); if (options.ids) { options.ids[0] = true; } } partial = env.VM.resolvePartial.call(this, partial, context, options); var result = env.VM.invokePartial.call(this, partial, context, options); if (result == null && env.compile) { options.partials[options.name] = env.compile(partial, templateSpec.compilerOptions, env); result = options.partials[options.name](context, options); } if (result != null) { if (options.indent) { var lines = result.split('\n'); for (var i = 0, l = lines.length; i < l; i++) { if (!lines[i] && i + 1 === l) { break; } lines[i] = options.indent + lines[i]; } result = lines.join('\n'); } return result; } else { throw new _exception2['default']('The partial ' + options.name + ' could not be compiled when running in runtime-only mode'); } } // Just add water var container = { strict: function strict(obj, name) { if (!(name in obj)) { throw new _exception2['default']('"' + name + '" not defined in ' + obj); } return obj[name]; }, lookup: function lookup(depths, name) { var len = depths.length; for (var i = 0; i < len; i++) { if (depths[i] && depths[i][name] != null) { return depths[i][name]; } } }, lambda: function lambda(current, context) { return typeof current === 'function' ? current.call(context) : current; }, escapeExpression: Utils.escapeExpression, invokePartial: invokePartialWrapper, fn: function fn(i) { var ret = templateSpec[i]; ret.decorator = templateSpec[i + '_d']; return ret; }, programs: [], program: function program(i, data, declaredBlockParams, blockParams, depths) { var programWrapper = this.programs[i], fn = this.fn(i); if (data || depths || blockParams || declaredBlockParams) { programWrapper = wrapProgram(this, i, fn, data, declaredBlockParams, blockParams, depths); } else if (!programWrapper) { programWrapper = this.programs[i] = wrapProgram(this, i, fn); } return programWrapper; }, data: function data(value, depth) { while (value && depth--) { value = value._parent; } return value; }, merge: function merge(param, common) { var obj = param || common; if (param && common && param !== common) { obj = Utils.extend({}, common, param); } return obj; }, noop: env.VM.noop, compilerInfo: templateSpec.compiler }; function ret(context) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var data = options.data; ret._setup(options); if (!options.partial && templateSpec.useData) { data = initData(context, data); } var depths = undefined, blockParams = templateSpec.useBlockParams ? [] : undefined; if (templateSpec.useDepths) { if (options.depths) { depths = context !== options.depths[0] ? [context].concat(options.depths) : options.depths; } else { depths = [context]; } } function main(context /*, options*/) { return '' + templateSpec.main(container, context, container.helpers, container.partials, data, blockParams, depths); } main = executeDecorators(templateSpec.main, main, container, options.depths || [], data, blockParams); return main(context, options); } ret.isTop = true; ret._setup = function (options) { if (!options.partial) { container.helpers = container.merge(options.helpers, env.helpers); if (templateSpec.usePartial) { container.partials = container.merge(options.partials, env.partials); } if (templateSpec.usePartial || templateSpec.useDecorators) { container.decorators = container.merge(options.decorators, env.decorators); } } else { container.helpers = options.helpers; container.partials = options.partials; container.decorators = options.decorators; } }; ret._child = function (i, data, blockParams, depths) { if (templateSpec.useBlockParams && !blockParams) { throw new _exception2['default']('must pass block params'); } if (templateSpec.useDepths && !depths) { throw new _exception2['default']('must pass parent depths'); } return wrapProgram(container, i, templateSpec[i], data, 0, blockParams, depths); }; return ret; } function wrapProgram(container, i, fn, data, declaredBlockParams, blockParams, depths) { function prog(context) { var options = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1]; var currentDepths = depths; if (depths && context !== depths[0]) { currentDepths = [context].concat(depths); } return fn(container, context, container.helpers, container.partials, options.data || data, blockParams && [options.blockParams].concat(blockParams), currentDepths); } prog = executeDecorators(fn, prog, container, depths, data, blockParams); prog.program = i; prog.depth = depths ? depths.length : 0; prog.blockParams = declaredBlockParams || 0; return prog; } function resolvePartial(partial, context, options) { if (!partial) { if (options.name === '@partial-block') { partial = options.data['partial-block']; } else { partial = options.partials[options.name]; } } else if (!partial.call && !options.name) { // This is a dynamic partial that returned a string options.name = partial; partial = options.partials[partial]; } return partial; } function invokePartial(partial, context, options) { options.partial = true; if (options.ids) { options.data.contextPath = options.ids[0] || options.data.contextPath; } var partialBlock = undefined; if (options.fn && options.fn !== noop) { options.data = _base.createFrame(options.data); partialBlock = options.data['partial-block'] = options.fn; if (partialBlock.partials) { options.partials = Utils.extend({}, options.partials, partialBlock.partials); } } if (partial === undefined && partialBlock) { partial = partialBlock; } if (partial === undefined) { throw new _exception2['default']('The partial ' + options.name + ' could not be found'); } else if (partial instanceof Function) { return partial(context, options); } } function noop() { return ''; } function initData(context, data) { if (!data || !('root' in data)) { data = data ? _base.createFrame(data) : {}; data.root = context; } return data; } function executeDecorators(fn, prog, container, depths, data, blockParams) { if (fn.decorator) { var props = {}; prog = fn.decorator(prog, props, container, depths && depths[0], data, blockParams, depths); Utils.extend(prog, props); } return prog; } /***/ }, /* 20 */ /***/ function(module, exports) { /* WEBPACK VAR INJECTION */(function(global) {/* global window */ 'use strict'; exports.__esModule = true; exports['default'] = function (Handlebars) { /* istanbul ignore next */ var root = typeof global !== 'undefined' ? global : window, $Handlebars = root.Handlebars; /* istanbul ignore next */ Handlebars.noConflict = function () { if (root.Handlebars === Handlebars) { root.Handlebars = $Handlebars; } return Handlebars; }; }; module.exports = exports['default']; /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()))) /***/ }, /* 21 */ /***/ function(module, exports) { 'use strict'; exports.__esModule = true; var AST = { // Public API used to evaluate derived attributes regarding AST nodes helpers: { // a mustache is definitely a helper if: // * it is an eligible helper, and // * it has at least one parameter or hash segment helperExpression: function helperExpression(node) { return node.type === 'SubExpression' || (node.type === 'MustacheStatement' || node.type === 'BlockStatement') && !!(node.params && node.params.length || node.hash); }, scopedId: function scopedId(path) { return (/^\.|this\b/.test(path.original) ); }, // an ID is simple if it only has one part, and that part is not // `..` or `this`. simpleId: function simpleId(path) { return path.parts.length === 1 && !AST.helpers.scopedId(path) && !path.depth; } } }; // Must be exported as an object rather than the root of the module as the jison lexer // must modify the object to operate properly. exports['default'] = AST; module.exports = exports['default']; /***/ }, /* 22 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; var _interopRequireWildcard = __webpack_require__(3)['default']; exports.__esModule = true; exports.parse = parse; var _parser = __webpack_require__(23); var _parser2 = _interopRequireDefault(_parser); var _whitespaceControl = __webpack_require__(24); var _whitespaceControl2 = _interopRequireDefault(_whitespaceControl); var _helpers = __webpack_require__(26); var Helpers = _interopRequireWildcard(_helpers); var _utils = __webpack_require__(5); exports.parser = _parser2['default']; var yy = {}; _utils.extend(yy, Helpers); function parse(input, options) { // Just return if an already-compiled AST was passed in. if (input.type === 'Program') { return input; } _parser2['default'].yy = yy; // Altering the shared object here, but this is ok as parser is a sync operation yy.locInfo = function (locInfo) { return new yy.SourceLocation(options && options.srcName, locInfo); }; var strip = new _whitespaceControl2['default'](options); return strip.accept(_parser2['default'].parse(input)); } /***/ }, /* 23 */ /***/ function(module, exports) { /* istanbul ignore next */ /* Jison generated parser */ "use strict"; var handlebars = (function () { var parser = { trace: function trace() {}, yy: {}, symbols_: { "error": 2, "root": 3, "program": 4, "EOF": 5, "program_repetition0": 6, "statement": 7, "mustache": 8, "block": 9, "rawBlock": 10, "partial": 11, "partialBlock": 12, "content": 13, "COMMENT": 14, "CONTENT": 15, "openRawBlock": 16, "rawBlock_repetition_plus0": 17, "END_RAW_BLOCK": 18, "OPEN_RAW_BLOCK": 19, "helperName": 20, "openRawBlock_repetition0": 21, "openRawBlock_option0": 22, "CLOSE_RAW_BLOCK": 23, "openBlock": 24, "block_option0": 25, "closeBlock": 26, "openInverse": 27, "block_option1": 28, "OPEN_BLOCK": 29, "openBlock_repetition0": 30, "openBlock_option0": 31, "openBlock_option1": 32, "CLOSE": 33, "OPEN_INVERSE": 34, "openInverse_repetition0": 35, "openInverse_option0": 36, "openInverse_option1": 37, "openInverseChain": 38, "OPEN_INVERSE_CHAIN": 39, "openInverseChain_repetition0": 40, "openInverseChain_option0": 41, "openInverseChain_option1": 42, "inverseAndProgram": 43, "INVERSE": 44, "inverseChain": 45, "inverseChain_option0": 46, "OPEN_ENDBLOCK": 47, "OPEN": 48, "mustache_repetition0": 49, "mustache_option0": 50, "OPEN_UNESCAPED": 51, "mustache_repetition1": 52, "mustache_option1": 53, "CLOSE_UNESCAPED": 54, "OPEN_PARTIAL": 55, "partialName": 56, "partial_repetition0": 57, "partial_option0": 58, "openPartialBlock": 59, "OPEN_PARTIAL_BLOCK": 60, "openPartialBlock_repetition0": 61, "openPartialBlock_option0": 62, "param": 63, "sexpr": 64, "OPEN_SEXPR": 65, "sexpr_repetition0": 66, "sexpr_option0": 67, "CLOSE_SEXPR": 68, "hash": 69, "hash_repetition_plus0": 70, "hashSegment": 71, "ID": 72, "EQUALS": 73, "blockParams": 74, "OPEN_BLOCK_PARAMS": 75, "blockParams_repetition_plus0": 76, "CLOSE_BLOCK_PARAMS": 77, "path": 78, "dataName": 79, "STRING": 80, "NUMBER": 81, "BOOLEAN": 82, "UNDEFINED": 83, "NULL": 84, "DATA": 85, "pathSegments": 86, "SEP": 87, "$accept": 0, "$end": 1 }, terminals_: { 2: "error", 5: "EOF", 14: "COMMENT", 15: "CONTENT", 18: "END_RAW_BLOCK", 19: "OPEN_RAW_BLOCK", 23: "CLOSE_RAW_BLOCK", 29: "OPEN_BLOCK", 33: "CLOSE", 34: "OPEN_INVERSE", 39: "OPEN_INVERSE_CHAIN", 44: "INVERSE", 47: "OPEN_ENDBLOCK", 48: "OPEN", 51: "OPEN_UNESCAPED", 54: "CLOSE_UNESCAPED", 55: "OPEN_PARTIAL", 60: "OPEN_PARTIAL_BLOCK", 65: "OPEN_SEXPR", 68: "CLOSE_SEXPR", 72: "ID", 73: "EQUALS", 75: "OPEN_BLOCK_PARAMS", 77: "CLOSE_BLOCK_PARAMS", 80: "STRING", 81: "NUMBER", 82: "BOOLEAN", 83: "UNDEFINED", 84: "NULL", 85: "DATA", 87: "SEP" }, productions_: [0, [3, 2], [4, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [7, 1], [13, 1], [10, 3], [16, 5], [9, 4], [9, 4], [24, 6], [27, 6], [38, 6], [43, 2], [45, 3], [45, 1], [26, 3], [8, 5], [8, 5], [11, 5], [12, 3], [59, 5], [63, 1], [63, 1], [64, 5], [69, 1], [71, 3], [74, 3], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [20, 1], [56, 1], [56, 1], [79, 2], [78, 1], [86, 3], [86, 1], [6, 0], [6, 2], [17, 1], [17, 2], [21, 0], [21, 2], [22, 0], [22, 1], [25, 0], [25, 1], [28, 0], [28, 1], [30, 0], [30, 2], [31, 0], [31, 1], [32, 0], [32, 1], [35, 0], [35, 2], [36, 0], [36, 1], [37, 0], [37, 1], [40, 0], [40, 2], [41, 0], [41, 1], [42, 0], [42, 1], [46, 0], [46, 1], [49, 0], [49, 2], [50, 0], [50, 1], [52, 0], [52, 2], [53, 0], [53, 1], [57, 0], [57, 2], [58, 0], [58, 1], [61, 0], [61, 2], [62, 0], [62, 1], [66, 0], [66, 2], [67, 0], [67, 1], [70, 1], [70, 2], [76, 1], [76, 2]], performAction: function anonymous(yytext, yyleng, yylineno, yy, yystate, $$, _$ /**/) { var $0 = $$.length - 1; switch (yystate) { case 1: return $$[$0 - 1]; break; case 2: this.$ = yy.prepareProgram($$[$0]); break; case 3: this.$ = $$[$0]; break; case 4: this.$ = $$[$0]; break; case 5: this.$ = $$[$0]; break; case 6: this.$ = $$[$0]; break; case 7: this.$ = $$[$0]; break; case 8: this.$ = $$[$0]; break; case 9: this.$ = { type: 'CommentStatement', value: yy.stripComment($$[$0]), strip: yy.stripFlags($$[$0], $$[$0]), loc: yy.locInfo(this._$) }; break; case 10: this.$ = { type: 'ContentStatement', original: $$[$0], value: $$[$0], loc: yy.locInfo(this._$) }; break; case 11: this.$ = yy.prepareRawBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$); break; case 12: this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1] }; break; case 13: this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], false, this._$); break; case 14: this.$ = yy.prepareBlock($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0], true, this._$); break; case 15: this.$ = { open: $$[$0 - 5], path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) }; break; case 16: this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) }; break; case 17: this.$ = { path: $$[$0 - 4], params: $$[$0 - 3], hash: $$[$0 - 2], blockParams: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 5], $$[$0]) }; break; case 18: this.$ = { strip: yy.stripFlags($$[$0 - 1], $$[$0 - 1]), program: $$[$0] }; break; case 19: var inverse = yy.prepareBlock($$[$0 - 2], $$[$0 - 1], $$[$0], $$[$0], false, this._$), program = yy.prepareProgram([inverse], $$[$0 - 1].loc); program.chained = true; this.$ = { strip: $$[$0 - 2].strip, program: program, chain: true }; break; case 20: this.$ = $$[$0]; break; case 21: this.$ = { path: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 2], $$[$0]) }; break; case 22: this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$); break; case 23: this.$ = yy.prepareMustache($$[$0 - 3], $$[$0 - 2], $$[$0 - 1], $$[$0 - 4], yy.stripFlags($$[$0 - 4], $$[$0]), this._$); break; case 24: this.$ = { type: 'PartialStatement', name: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], indent: '', strip: yy.stripFlags($$[$0 - 4], $$[$0]), loc: yy.locInfo(this._$) }; break; case 25: this.$ = yy.preparePartialBlock($$[$0 - 2], $$[$0 - 1], $$[$0], this._$); break; case 26: this.$ = { path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], strip: yy.stripFlags($$[$0 - 4], $$[$0]) }; break; case 27: this.$ = $$[$0]; break; case 28: this.$ = $$[$0]; break; case 29: this.$ = { type: 'SubExpression', path: $$[$0 - 3], params: $$[$0 - 2], hash: $$[$0 - 1], loc: yy.locInfo(this._$) }; break; case 30: this.$ = { type: 'Hash', pairs: $$[$0], loc: yy.locInfo(this._$) }; break; case 31: this.$ = { type: 'HashPair', key: yy.id($$[$0 - 2]), value: $$[$0], loc: yy.locInfo(this._$) }; break; case 32: this.$ = yy.id($$[$0 - 1]); break; case 33: this.$ = $$[$0]; break; case 34: this.$ = $$[$0]; break; case 35: this.$ = { type: 'StringLiteral', value: $$[$0], original: $$[$0], loc: yy.locInfo(this._$) }; break; case 36: this.$ = { type: 'NumberLiteral', value: Number($$[$0]), original: Number($$[$0]), loc: yy.locInfo(this._$) }; break; case 37: this.$ = { type: 'BooleanLiteral', value: $$[$0] === 'true', original: $$[$0] === 'true', loc: yy.locInfo(this._$) }; break; case 38: this.$ = { type: 'UndefinedLiteral', original: undefined, value: undefined, loc: yy.locInfo(this._$) }; break; case 39: this.$ = { type: 'NullLiteral', original: null, value: null, loc: yy.locInfo(this._$) }; break; case 40: this.$ = $$[$0]; break; case 41: this.$ = $$[$0]; break; case 42: this.$ = yy.preparePath(true, $$[$0], this._$); break; case 43: this.$ = yy.preparePath(false, $$[$0], this._$); break; case 44: $$[$0 - 2].push({ part: yy.id($$[$0]), original: $$[$0], separator: $$[$0 - 1] });this.$ = $$[$0 - 2]; break; case 45: this.$ = [{ part: yy.id($$[$0]), original: $$[$0] }]; break; case 46: this.$ = []; break; case 47: $$[$0 - 1].push($$[$0]); break; case 48: this.$ = [$$[$0]]; break; case 49: $$[$0 - 1].push($$[$0]); break; case 50: this.$ = []; break; case 51: $$[$0 - 1].push($$[$0]); break; case 58: this.$ = []; break; case 59: $$[$0 - 1].push($$[$0]); break; case 64: this.$ = []; break; case 65: $$[$0 - 1].push($$[$0]); break; case 70: this.$ = []; break; case 71: $$[$0 - 1].push($$[$0]); break; case 78: this.$ = []; break; case 79: $$[$0 - 1].push($$[$0]); break; case 82: this.$ = []; break; case 83: $$[$0 - 1].push($$[$0]); break; case 86: this.$ = []; break; case 87: $$[$0 - 1].push($$[$0]); break; case 90: this.$ = []; break; case 91: $$[$0 - 1].push($$[$0]); break; case 94: this.$ = []; break; case 95: $$[$0 - 1].push($$[$0]); break; case 98: this.$ = [$$[$0]]; break; case 99: $$[$0 - 1].push($$[$0]); break; case 100: this.$ = [$$[$0]]; break; case 101: $$[$0 - 1].push($$[$0]); break; } }, table: [{ 3: 1, 4: 2, 5: [2, 46], 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 1: [3] }, { 5: [1, 4] }, { 5: [2, 2], 7: 5, 8: 6, 9: 7, 10: 8, 11: 9, 12: 10, 13: 11, 14: [1, 12], 15: [1, 20], 16: 17, 19: [1, 23], 24: 15, 27: 16, 29: [1, 21], 34: [1, 22], 39: [2, 2], 44: [2, 2], 47: [2, 2], 48: [1, 13], 51: [1, 14], 55: [1, 18], 59: 19, 60: [1, 24] }, { 1: [2, 1] }, { 5: [2, 47], 14: [2, 47], 15: [2, 47], 19: [2, 47], 29: [2, 47], 34: [2, 47], 39: [2, 47], 44: [2, 47], 47: [2, 47], 48: [2, 47], 51: [2, 47], 55: [2, 47], 60: [2, 47] }, { 5: [2, 3], 14: [2, 3], 15: [2, 3], 19: [2, 3], 29: [2, 3], 34: [2, 3], 39: [2, 3], 44: [2, 3], 47: [2, 3], 48: [2, 3], 51: [2, 3], 55: [2, 3], 60: [2, 3] }, { 5: [2, 4], 14: [2, 4], 15: [2, 4], 19: [2, 4], 29: [2, 4], 34: [2, 4], 39: [2, 4], 44: [2, 4], 47: [2, 4], 48: [2, 4], 51: [2, 4], 55: [2, 4], 60: [2, 4] }, { 5: [2, 5], 14: [2, 5], 15: [2, 5], 19: [2, 5], 29: [2, 5], 34: [2, 5], 39: [2, 5], 44: [2, 5], 47: [2, 5], 48: [2, 5], 51: [2, 5], 55: [2, 5], 60: [2, 5] }, { 5: [2, 6], 14: [2, 6], 15: [2, 6], 19: [2, 6], 29: [2, 6], 34: [2, 6], 39: [2, 6], 44: [2, 6], 47: [2, 6], 48: [2, 6], 51: [2, 6], 55: [2, 6], 60: [2, 6] }, { 5: [2, 7], 14: [2, 7], 15: [2, 7], 19: [2, 7], 29: [2, 7], 34: [2, 7], 39: [2, 7], 44: [2, 7], 47: [2, 7], 48: [2, 7], 51: [2, 7], 55: [2, 7], 60: [2, 7] }, { 5: [2, 8], 14: [2, 8], 15: [2, 8], 19: [2, 8], 29: [2, 8], 34: [2, 8], 39: [2, 8], 44: [2, 8], 47: [2, 8], 48: [2, 8], 51: [2, 8], 55: [2, 8], 60: [2, 8] }, { 5: [2, 9], 14: [2, 9], 15: [2, 9], 19: [2, 9], 29: [2, 9], 34: [2, 9], 39: [2, 9], 44: [2, 9], 47: [2, 9], 48: [2, 9], 51: [2, 9], 55: [2, 9], 60: [2, 9] }, { 20: 25, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 36, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 37, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 4: 38, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 13: 40, 15: [1, 20], 17: 39 }, { 20: 42, 56: 41, 64: 43, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 45, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 5: [2, 10], 14: [2, 10], 15: [2, 10], 18: [2, 10], 19: [2, 10], 29: [2, 10], 34: [2, 10], 39: [2, 10], 44: [2, 10], 47: [2, 10], 48: [2, 10], 51: [2, 10], 55: [2, 10], 60: [2, 10] }, { 20: 46, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 47, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 48, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 42, 56: 49, 64: 43, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [2, 78], 49: 50, 65: [2, 78], 72: [2, 78], 80: [2, 78], 81: [2, 78], 82: [2, 78], 83: [2, 78], 84: [2, 78], 85: [2, 78] }, { 23: [2, 33], 33: [2, 33], 54: [2, 33], 65: [2, 33], 68: [2, 33], 72: [2, 33], 75: [2, 33], 80: [2, 33], 81: [2, 33], 82: [2, 33], 83: [2, 33], 84: [2, 33], 85: [2, 33] }, { 23: [2, 34], 33: [2, 34], 54: [2, 34], 65: [2, 34], 68: [2, 34], 72: [2, 34], 75: [2, 34], 80: [2, 34], 81: [2, 34], 82: [2, 34], 83: [2, 34], 84: [2, 34], 85: [2, 34] }, { 23: [2, 35], 33: [2, 35], 54: [2, 35], 65: [2, 35], 68: [2, 35], 72: [2, 35], 75: [2, 35], 80: [2, 35], 81: [2, 35], 82: [2, 35], 83: [2, 35], 84: [2, 35], 85: [2, 35] }, { 23: [2, 36], 33: [2, 36], 54: [2, 36], 65: [2, 36], 68: [2, 36], 72: [2, 36], 75: [2, 36], 80: [2, 36], 81: [2, 36], 82: [2, 36], 83: [2, 36], 84: [2, 36], 85: [2, 36] }, { 23: [2, 37], 33: [2, 37], 54: [2, 37], 65: [2, 37], 68: [2, 37], 72: [2, 37], 75: [2, 37], 80: [2, 37], 81: [2, 37], 82: [2, 37], 83: [2, 37], 84: [2, 37], 85: [2, 37] }, { 23: [2, 38], 33: [2, 38], 54: [2, 38], 65: [2, 38], 68: [2, 38], 72: [2, 38], 75: [2, 38], 80: [2, 38], 81: [2, 38], 82: [2, 38], 83: [2, 38], 84: [2, 38], 85: [2, 38] }, { 23: [2, 39], 33: [2, 39], 54: [2, 39], 65: [2, 39], 68: [2, 39], 72: [2, 39], 75: [2, 39], 80: [2, 39], 81: [2, 39], 82: [2, 39], 83: [2, 39], 84: [2, 39], 85: [2, 39] }, { 23: [2, 43], 33: [2, 43], 54: [2, 43], 65: [2, 43], 68: [2, 43], 72: [2, 43], 75: [2, 43], 80: [2, 43], 81: [2, 43], 82: [2, 43], 83: [2, 43], 84: [2, 43], 85: [2, 43], 87: [1, 51] }, { 72: [1, 35], 86: 52 }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 52: 53, 54: [2, 82], 65: [2, 82], 72: [2, 82], 80: [2, 82], 81: [2, 82], 82: [2, 82], 83: [2, 82], 84: [2, 82], 85: [2, 82] }, { 25: 54, 38: 56, 39: [1, 58], 43: 57, 44: [1, 59], 45: 55, 47: [2, 54] }, { 28: 60, 43: 61, 44: [1, 59], 47: [2, 56] }, { 13: 63, 15: [1, 20], 18: [1, 62] }, { 15: [2, 48], 18: [2, 48] }, { 33: [2, 86], 57: 64, 65: [2, 86], 72: [2, 86], 80: [2, 86], 81: [2, 86], 82: [2, 86], 83: [2, 86], 84: [2, 86], 85: [2, 86] }, { 33: [2, 40], 65: [2, 40], 72: [2, 40], 80: [2, 40], 81: [2, 40], 82: [2, 40], 83: [2, 40], 84: [2, 40], 85: [2, 40] }, { 33: [2, 41], 65: [2, 41], 72: [2, 41], 80: [2, 41], 81: [2, 41], 82: [2, 41], 83: [2, 41], 84: [2, 41], 85: [2, 41] }, { 20: 65, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 66, 47: [1, 67] }, { 30: 68, 33: [2, 58], 65: [2, 58], 72: [2, 58], 75: [2, 58], 80: [2, 58], 81: [2, 58], 82: [2, 58], 83: [2, 58], 84: [2, 58], 85: [2, 58] }, { 33: [2, 64], 35: 69, 65: [2, 64], 72: [2, 64], 75: [2, 64], 80: [2, 64], 81: [2, 64], 82: [2, 64], 83: [2, 64], 84: [2, 64], 85: [2, 64] }, { 21: 70, 23: [2, 50], 65: [2, 50], 72: [2, 50], 80: [2, 50], 81: [2, 50], 82: [2, 50], 83: [2, 50], 84: [2, 50], 85: [2, 50] }, { 33: [2, 90], 61: 71, 65: [2, 90], 72: [2, 90], 80: [2, 90], 81: [2, 90], 82: [2, 90], 83: [2, 90], 84: [2, 90], 85: [2, 90] }, { 20: 75, 33: [2, 80], 50: 72, 63: 73, 64: 76, 65: [1, 44], 69: 74, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 72: [1, 80] }, { 23: [2, 42], 33: [2, 42], 54: [2, 42], 65: [2, 42], 68: [2, 42], 72: [2, 42], 75: [2, 42], 80: [2, 42], 81: [2, 42], 82: [2, 42], 83: [2, 42], 84: [2, 42], 85: [2, 42], 87: [1, 51] }, { 20: 75, 53: 81, 54: [2, 84], 63: 82, 64: 76, 65: [1, 44], 69: 83, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 26: 84, 47: [1, 67] }, { 47: [2, 55] }, { 4: 85, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 39: [2, 46], 44: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 47: [2, 20] }, { 20: 86, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 4: 87, 6: 3, 14: [2, 46], 15: [2, 46], 19: [2, 46], 29: [2, 46], 34: [2, 46], 47: [2, 46], 48: [2, 46], 51: [2, 46], 55: [2, 46], 60: [2, 46] }, { 26: 88, 47: [1, 67] }, { 47: [2, 57] }, { 5: [2, 11], 14: [2, 11], 15: [2, 11], 19: [2, 11], 29: [2, 11], 34: [2, 11], 39: [2, 11], 44: [2, 11], 47: [2, 11], 48: [2, 11], 51: [2, 11], 55: [2, 11], 60: [2, 11] }, { 15: [2, 49], 18: [2, 49] }, { 20: 75, 33: [2, 88], 58: 89, 63: 90, 64: 76, 65: [1, 44], 69: 91, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 65: [2, 94], 66: 92, 68: [2, 94], 72: [2, 94], 80: [2, 94], 81: [2, 94], 82: [2, 94], 83: [2, 94], 84: [2, 94], 85: [2, 94] }, { 5: [2, 25], 14: [2, 25], 15: [2, 25], 19: [2, 25], 29: [2, 25], 34: [2, 25], 39: [2, 25], 44: [2, 25], 47: [2, 25], 48: [2, 25], 51: [2, 25], 55: [2, 25], 60: [2, 25] }, { 20: 93, 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 31: 94, 33: [2, 60], 63: 95, 64: 76, 65: [1, 44], 69: 96, 70: 77, 71: 78, 72: [1, 79], 75: [2, 60], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 33: [2, 66], 36: 97, 63: 98, 64: 76, 65: [1, 44], 69: 99, 70: 77, 71: 78, 72: [1, 79], 75: [2, 66], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 22: 100, 23: [2, 52], 63: 101, 64: 76, 65: [1, 44], 69: 102, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 20: 75, 33: [2, 92], 62: 103, 63: 104, 64: 76, 65: [1, 44], 69: 105, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 106] }, { 33: [2, 79], 65: [2, 79], 72: [2, 79], 80: [2, 79], 81: [2, 79], 82: [2, 79], 83: [2, 79], 84: [2, 79], 85: [2, 79] }, { 33: [2, 81] }, { 23: [2, 27], 33: [2, 27], 54: [2, 27], 65: [2, 27], 68: [2, 27], 72: [2, 27], 75: [2, 27], 80: [2, 27], 81: [2, 27], 82: [2, 27], 83: [2, 27], 84: [2, 27], 85: [2, 27] }, { 23: [2, 28], 33: [2, 28], 54: [2, 28], 65: [2, 28], 68: [2, 28], 72: [2, 28], 75: [2, 28], 80: [2, 28], 81: [2, 28], 82: [2, 28], 83: [2, 28], 84: [2, 28], 85: [2, 28] }, { 23: [2, 30], 33: [2, 30], 54: [2, 30], 68: [2, 30], 71: 107, 72: [1, 108], 75: [2, 30] }, { 23: [2, 98], 33: [2, 98], 54: [2, 98], 68: [2, 98], 72: [2, 98], 75: [2, 98] }, { 23: [2, 45], 33: [2, 45], 54: [2, 45], 65: [2, 45], 68: [2, 45], 72: [2, 45], 73: [1, 109], 75: [2, 45], 80: [2, 45], 81: [2, 45], 82: [2, 45], 83: [2, 45], 84: [2, 45], 85: [2, 45], 87: [2, 45] }, { 23: [2, 44], 33: [2, 44], 54: [2, 44], 65: [2, 44], 68: [2, 44], 72: [2, 44], 75: [2, 44], 80: [2, 44], 81: [2, 44], 82: [2, 44], 83: [2, 44], 84: [2, 44], 85: [2, 44], 87: [2, 44] }, { 54: [1, 110] }, { 54: [2, 83], 65: [2, 83], 72: [2, 83], 80: [2, 83], 81: [2, 83], 82: [2, 83], 83: [2, 83], 84: [2, 83], 85: [2, 83] }, { 54: [2, 85] }, { 5: [2, 13], 14: [2, 13], 15: [2, 13], 19: [2, 13], 29: [2, 13], 34: [2, 13], 39: [2, 13], 44: [2, 13], 47: [2, 13], 48: [2, 13], 51: [2, 13], 55: [2, 13], 60: [2, 13] }, { 38: 56, 39: [1, 58], 43: 57, 44: [1, 59], 45: 112, 46: 111, 47: [2, 76] }, { 33: [2, 70], 40: 113, 65: [2, 70], 72: [2, 70], 75: [2, 70], 80: [2, 70], 81: [2, 70], 82: [2, 70], 83: [2, 70], 84: [2, 70], 85: [2, 70] }, { 47: [2, 18] }, { 5: [2, 14], 14: [2, 14], 15: [2, 14], 19: [2, 14], 29: [2, 14], 34: [2, 14], 39: [2, 14], 44: [2, 14], 47: [2, 14], 48: [2, 14], 51: [2, 14], 55: [2, 14], 60: [2, 14] }, { 33: [1, 114] }, { 33: [2, 87], 65: [2, 87], 72: [2, 87], 80: [2, 87], 81: [2, 87], 82: [2, 87], 83: [2, 87], 84: [2, 87], 85: [2, 87] }, { 33: [2, 89] }, { 20: 75, 63: 116, 64: 76, 65: [1, 44], 67: 115, 68: [2, 96], 69: 117, 70: 77, 71: 78, 72: [1, 79], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 33: [1, 118] }, { 32: 119, 33: [2, 62], 74: 120, 75: [1, 121] }, { 33: [2, 59], 65: [2, 59], 72: [2, 59], 75: [2, 59], 80: [2, 59], 81: [2, 59], 82: [2, 59], 83: [2, 59], 84: [2, 59], 85: [2, 59] }, { 33: [2, 61], 75: [2, 61] }, { 33: [2, 68], 37: 122, 74: 123, 75: [1, 121] }, { 33: [2, 65], 65: [2, 65], 72: [2, 65], 75: [2, 65], 80: [2, 65], 81: [2, 65], 82: [2, 65], 83: [2, 65], 84: [2, 65], 85: [2, 65] }, { 33: [2, 67], 75: [2, 67] }, { 23: [1, 124] }, { 23: [2, 51], 65: [2, 51], 72: [2, 51], 80: [2, 51], 81: [2, 51], 82: [2, 51], 83: [2, 51], 84: [2, 51], 85: [2, 51] }, { 23: [2, 53] }, { 33: [1, 125] }, { 33: [2, 91], 65: [2, 91], 72: [2, 91], 80: [2, 91], 81: [2, 91], 82: [2, 91], 83: [2, 91], 84: [2, 91], 85: [2, 91] }, { 33: [2, 93] }, { 5: [2, 22], 14: [2, 22], 15: [2, 22], 19: [2, 22], 29: [2, 22], 34: [2, 22], 39: [2, 22], 44: [2, 22], 47: [2, 22], 48: [2, 22], 51: [2, 22], 55: [2, 22], 60: [2, 22] }, { 23: [2, 99], 33: [2, 99], 54: [2, 99], 68: [2, 99], 72: [2, 99], 75: [2, 99] }, { 73: [1, 109] }, { 20: 75, 63: 126, 64: 76, 65: [1, 44], 72: [1, 35], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 23], 14: [2, 23], 15: [2, 23], 19: [2, 23], 29: [2, 23], 34: [2, 23], 39: [2, 23], 44: [2, 23], 47: [2, 23], 48: [2, 23], 51: [2, 23], 55: [2, 23], 60: [2, 23] }, { 47: [2, 19] }, { 47: [2, 77] }, { 20: 75, 33: [2, 72], 41: 127, 63: 128, 64: 76, 65: [1, 44], 69: 129, 70: 77, 71: 78, 72: [1, 79], 75: [2, 72], 78: 26, 79: 27, 80: [1, 28], 81: [1, 29], 82: [1, 30], 83: [1, 31], 84: [1, 32], 85: [1, 34], 86: 33 }, { 5: [2, 24], 14: [2, 24], 15: [2, 24], 19: [2, 24], 29: [2, 24], 34: [2, 24], 39: [2, 24], 44: [2, 24], 47: [2, 24], 48: [2, 24], 51: [2, 24], 55: [2, 24], 60: [2, 24] }, { 68: [1, 130] }, { 65: [2, 95], 68: [2, 95], 72: [2, 95], 80: [2, 95], 81: [2, 95], 82: [2, 95], 83: [2, 95], 84: [2, 95], 85: [2, 95] }, { 68: [2, 97] }, { 5: [2, 21], 14: [2, 21], 15: [2, 21], 19: [2, 21], 29: [2, 21], 34: [2, 21], 39: [2, 21], 44: [2, 21], 47: [2, 21], 48: [2, 21], 51: [2, 21], 55: [2, 21], 60: [2, 21] }, { 33: [1, 131] }, { 33: [2, 63] }, { 72: [1, 133], 76: 132 }, { 33: [1, 134] }, { 33: [2, 69] }, { 15: [2, 12] }, { 14: [2, 26], 15: [2, 26], 19: [2, 26], 29: [2, 26], 34: [2, 26], 47: [2, 26], 48: [2, 26], 51: [2, 26], 55: [2, 26], 60: [2, 26] }, { 23: [2, 31], 33: [2, 31], 54: [2, 31], 68: [2, 31], 72: [2, 31], 75: [2, 31] }, { 33: [2, 74], 42: 135, 74: 136, 75: [1, 121] }, { 33: [2, 71], 65: [2, 71], 72: [2, 71], 75: [2, 71], 80: [2, 71], 81: [2, 71], 82: [2, 71], 83: [2, 71], 84: [2, 71], 85: [2, 71] }, { 33: [2, 73], 75: [2, 73] }, { 23: [2, 29], 33: [2, 29], 54: [2, 29], 65: [2, 29], 68: [2, 29], 72: [2, 29], 75: [2, 29], 80: [2, 29], 81: [2, 29], 82: [2, 29], 83: [2, 29], 84: [2, 29], 85: [2, 29] }, { 14: [2, 15], 15: [2, 15], 19: [2, 15], 29: [2, 15], 34: [2, 15], 39: [2, 15], 44: [2, 15], 47: [2, 15], 48: [2, 15], 51: [2, 15], 55: [2, 15], 60: [2, 15] }, { 72: [1, 138], 77: [1, 137] }, { 72: [2, 100], 77: [2, 100] }, { 14: [2, 16], 15: [2, 16], 19: [2, 16], 29: [2, 16], 34: [2, 16], 44: [2, 16], 47: [2, 16], 48: [2, 16], 51: [2, 16], 55: [2, 16], 60: [2, 16] }, { 33: [1, 139] }, { 33: [2, 75] }, { 33: [2, 32] }, { 72: [2, 101], 77: [2, 101] }, { 14: [2, 17], 15: [2, 17], 19: [2, 17], 29: [2, 17], 34: [2, 17], 39: [2, 17], 44: [2, 17], 47: [2, 17], 48: [2, 17], 51: [2, 17], 55: [2, 17], 60: [2, 17] }], defaultActions: { 4: [2, 1], 55: [2, 55], 57: [2, 20], 61: [2, 57], 74: [2, 81], 83: [2, 85], 87: [2, 18], 91: [2, 89], 102: [2, 53], 105: [2, 93], 111: [2, 19], 112: [2, 77], 117: [2, 97], 120: [2, 63], 123: [2, 69], 124: [2, 12], 136: [2, 75], 137: [2, 32] }, parseError: function parseError(str, hash) { throw new Error(str); }, parse: function parse(input) { var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1; this.lexer.setInput(input); this.lexer.yy = this.yy; this.yy.lexer = this.lexer; this.yy.parser = this; if (typeof this.lexer.yylloc == "undefined") this.lexer.yylloc = {}; var yyloc = this.lexer.yylloc; lstack.push(yyloc); var ranges = this.lexer.options && this.lexer.options.ranges; if (typeof this.yy.parseError === "function") this.parseError = this.yy.parseError; function popStack(n) { stack.length = stack.length - 2 * n; vstack.length = vstack.length - n; lstack.length = lstack.length - n; } function lex() { var token; token = self.lexer.lex() || 1; if (typeof token !== "number") { token = self.symbols_[token] || token; } return token; } var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected; while (true) { state = stack[stack.length - 1]; if (this.defaultActions[state]) { action = this.defaultActions[state]; } else { if (symbol === null || typeof symbol == "undefined") { symbol = lex(); } action = table[state] && table[state][symbol]; } if (typeof action === "undefined" || !action.length || !action[0]) { var errStr = ""; if (!recovering) { expected = []; for (p in table[state]) if (this.terminals_[p] && p > 2) { expected.push("'" + this.terminals_[p] + "'"); } if (this.lexer.showPosition) { errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'"; } else { errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1 ? "end of input" : "'" + (this.terminals_[symbol] || symbol) + "'"); } this.parseError(errStr, { text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected }); } } if (action[0] instanceof Array && action.length > 1) { throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol); } switch (action[0]) { case 1: stack.push(symbol); vstack.push(this.lexer.yytext); lstack.push(this.lexer.yylloc); stack.push(action[1]); symbol = null; if (!preErrorSymbol) { yyleng = this.lexer.yyleng; yytext = this.lexer.yytext; yylineno = this.lexer.yylineno; yyloc = this.lexer.yylloc; if (recovering > 0) recovering--; } else { symbol = preErrorSymbol; preErrorSymbol = null; } break; case 2: len = this.productions_[action[1]][1]; yyval.$ = vstack[vstack.length - len]; yyval._$ = { first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column }; if (ranges) { yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]]; } r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack); if (typeof r !== "undefined") { return r; } if (len) { stack = stack.slice(0, -1 * len * 2); vstack = vstack.slice(0, -1 * len); lstack = lstack.slice(0, -1 * len); } stack.push(this.productions_[action[1]][0]); vstack.push(yyval.$); lstack.push(yyval._$); newState = table[stack[stack.length - 2]][stack[stack.length - 1]]; stack.push(newState); break; case 3: return true; } } return true; } }; /* Jison generated lexer */ var lexer = (function () { var lexer = { EOF: 1, parseError: function parseError(str, hash) { if (this.yy.parser) { this.yy.parser.parseError(str, hash); } else { throw new Error(str); } }, setInput: function setInput(input) { this._input = input; this._more = this._less = this.done = false; this.yylineno = this.yyleng = 0; this.yytext = this.matched = this.match = ''; this.conditionStack = ['INITIAL']; this.yylloc = { first_line: 1, first_column: 0, last_line: 1, last_column: 0 }; if (this.options.ranges) this.yylloc.range = [0, 0]; this.offset = 0; return this; }, input: function input() { var ch = this._input[0]; this.yytext += ch; this.yyleng++; this.offset++; this.match += ch; this.matched += ch; var lines = ch.match(/(?:\r\n?|\n).*/g); if (lines) { this.yylineno++; this.yylloc.last_line++; } else { this.yylloc.last_column++; } if (this.options.ranges) this.yylloc.range[1]++; this._input = this._input.slice(1); return ch; }, unput: function unput(ch) { var len = ch.length; var lines = ch.split(/(?:\r\n?|\n)/g); this._input = ch + this._input; this.yytext = this.yytext.substr(0, this.yytext.length - len - 1); //this.yyleng -= len; this.offset -= len; var oldLines = this.match.split(/(?:\r\n?|\n)/g); this.match = this.match.substr(0, this.match.length - 1); this.matched = this.matched.substr(0, this.matched.length - 1); if (lines.length - 1) this.yylineno -= lines.length - 1; var r = this.yylloc.range; this.yylloc = { first_line: this.yylloc.first_line, last_line: this.yylineno + 1, first_column: this.yylloc.first_column, last_column: lines ? (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length : this.yylloc.first_column - len }; if (this.options.ranges) { this.yylloc.range = [r[0], r[0] + this.yyleng - len]; } return this; }, more: function more() { this._more = true; return this; }, less: function less(n) { this.unput(this.match.slice(n)); }, pastInput: function pastInput() { var past = this.matched.substr(0, this.matched.length - this.match.length); return (past.length > 20 ? '...' : '') + past.substr(-20).replace(/\n/g, ""); }, upcomingInput: function upcomingInput() { var next = this.match; if (next.length < 20) { next += this._input.substr(0, 20 - next.length); } return (next.substr(0, 20) + (next.length > 20 ? '...' : '')).replace(/\n/g, ""); }, showPosition: function showPosition() { var pre = this.pastInput(); var c = new Array(pre.length + 1).join("-"); return pre + this.upcomingInput() + "\n" + c + "^"; }, next: function next() { if (this.done) { return this.EOF; } if (!this._input) this.done = true; var token, match, tempMatch, index, col, lines; if (!this._more) { this.yytext = ''; this.match = ''; } var rules = this._currentRules(); for (var i = 0; i < rules.length; i++) { tempMatch = this._input.match(this.rules[rules[i]]); if (tempMatch && (!match || tempMatch[0].length > match[0].length)) { match = tempMatch; index = i; if (!this.options.flex) break; } } if (match) { lines = match[0].match(/(?:\r\n?|\n).*/g); if (lines) this.yylineno += lines.length; this.yylloc = { first_line: this.yylloc.last_line, last_line: this.yylineno + 1, first_column: this.yylloc.last_column, last_column: lines ? lines[lines.length - 1].length - lines[lines.length - 1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length }; this.yytext += match[0]; this.match += match[0]; this.matches = match; this.yyleng = this.yytext.length; if (this.options.ranges) { this.yylloc.range = [this.offset, this.offset += this.yyleng]; } this._more = false; this._input = this._input.slice(match[0].length); this.matched += match[0]; token = this.performAction.call(this, this.yy, this, rules[index], this.conditionStack[this.conditionStack.length - 1]); if (this.done && this._input) this.done = false; if (token) return token;else return; } if (this._input === "") { return this.EOF; } else { return this.parseError('Lexical error on line ' + (this.yylineno + 1) + '. Unrecognized text.\n' + this.showPosition(), { text: "", token: null, line: this.yylineno }); } }, lex: function lex() { var r = this.next(); if (typeof r !== 'undefined') { return r; } else { return this.lex(); } }, begin: function begin(condition) { this.conditionStack.push(condition); }, popState: function popState() { return this.conditionStack.pop(); }, _currentRules: function _currentRules() { return this.conditions[this.conditionStack[this.conditionStack.length - 1]].rules; }, topState: function topState() { return this.conditionStack[this.conditionStack.length - 2]; }, pushState: function begin(condition) { this.begin(condition); } }; lexer.options = {}; lexer.performAction = function anonymous(yy, yy_, $avoiding_name_collisions, YY_START /**/) { function strip(start, end) { return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng - end); } var YYSTATE = YY_START; switch ($avoiding_name_collisions) { case 0: if (yy_.yytext.slice(-2) === "\\\\") { strip(0, 1); this.begin("mu"); } else if (yy_.yytext.slice(-1) === "\\") { strip(0, 1); this.begin("emu"); } else { this.begin("mu"); } if (yy_.yytext) return 15; break; case 1: return 15; break; case 2: this.popState(); return 15; break; case 3: this.begin('raw');return 15; break; case 4: this.popState(); // Should be using `this.topState()` below, but it currently // returns the second top instead of the first top. Opened an // issue about it at https://github.com/zaach/jison/issues/291 if (this.conditionStack[this.conditionStack.length - 1] === 'raw') { return 15; } else { yy_.yytext = yy_.yytext.substr(5, yy_.yyleng - 9); return 'END_RAW_BLOCK'; } break; case 5: return 15; break; case 6: this.popState(); return 14; break; case 7: return 65; break; case 8: return 68; break; case 9: return 19; break; case 10: this.popState(); this.begin('raw'); return 23; break; case 11: return 55; break; case 12: return 60; break; case 13: return 29; break; case 14: return 47; break; case 15: this.popState();return 44; break; case 16: this.popState();return 44; break; case 17: return 34; break; case 18: return 39; break; case 19: return 51; break; case 20: return 48; break; case 21: this.unput(yy_.yytext); this.popState(); this.begin('com'); break; case 22: this.popState(); return 14; break; case 23: return 48; break; case 24: return 73; break; case 25: return 72; break; case 26: return 72; break; case 27: return 87; break; case 28: // ignore whitespace break; case 29: this.popState();return 54; break; case 30: this.popState();return 33; break; case 31: yy_.yytext = strip(1, 2).replace(/\\"/g, '"');return 80; break; case 32: yy_.yytext = strip(1, 2).replace(/\\'/g, "'");return 80; break; case 33: return 85; break; case 34: return 82; break; case 35: return 82; break; case 36: return 83; break; case 37: return 84; break; case 38: return 81; break; case 39: return 75; break; case 40: return 77; break; case 41: return 72; break; case 42: yy_.yytext = yy_.yytext.replace(/\\([\\\]])/g, '$1');return 72; break; case 43: return 'INVALID'; break; case 44: return 5; break; } }; lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/, /^(?:[^\x00]+)/, /^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/, /^(?:\{\{\{\{(?=[^/]))/, /^(?:\{\{\{\{\/[^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=[=}\s\/.])\}\}\}\})/, /^(?:[^\x00]*?(?=(\{\{\{\{)))/, /^(?:[\s\S]*?--(~)?\}\})/, /^(?:\()/, /^(?:\))/, /^(?:\{\{\{\{)/, /^(?:\}\}\}\})/, /^(?:\{\{(~)?>)/, /^(?:\{\{(~)?#>)/, /^(?:\{\{(~)?#\*?)/, /^(?:\{\{(~)?\/)/, /^(?:\{\{(~)?\^\s*(~)?\}\})/, /^(?:\{\{(~)?\s*else\s*(~)?\}\})/, /^(?:\{\{(~)?\^)/, /^(?:\{\{(~)?\s*else\b)/, /^(?:\{\{(~)?\{)/, /^(?:\{\{(~)?&)/, /^(?:\{\{(~)?!--)/, /^(?:\{\{(~)?![\s\S]*?\}\})/, /^(?:\{\{(~)?\*?)/, /^(?:=)/, /^(?:\.\.)/, /^(?:\.(?=([=~}\s\/.)|])))/, /^(?:[\/.])/, /^(?:\s+)/, /^(?:\}(~)?\}\})/, /^(?:(~)?\}\})/, /^(?:"(\\["]|[^"])*")/, /^(?:'(\\[']|[^'])*')/, /^(?:@)/, /^(?:true(?=([~}\s)])))/, /^(?:false(?=([~}\s)])))/, /^(?:undefined(?=([~}\s)])))/, /^(?:null(?=([~}\s)])))/, /^(?:-?[0-9]+(?:\.[0-9]+)?(?=([~}\s)])))/, /^(?:as\s+\|)/, /^(?:\|)/, /^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)|]))))/, /^(?:\[(\\\]|[^\]])*\])/, /^(?:.)/, /^(?:$)/]; lexer.conditions = { "mu": { "rules": [7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44], "inclusive": false }, "emu": { "rules": [2], "inclusive": false }, "com": { "rules": [6], "inclusive": false }, "raw": { "rules": [3, 4, 5], "inclusive": false }, "INITIAL": { "rules": [0, 1, 44], "inclusive": true } }; return lexer; })(); parser.lexer = lexer; function Parser() { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser; return new Parser(); })();exports.__esModule = true; exports['default'] = handlebars; /***/ }, /* 24 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _visitor = __webpack_require__(25); var _visitor2 = _interopRequireDefault(_visitor); function WhitespaceControl() { var options = arguments.length <= 0 || arguments[0] === undefined ? {} : arguments[0]; this.options = options; } WhitespaceControl.prototype = new _visitor2['default'](); WhitespaceControl.prototype.Program = function (program) { var doStandalone = !this.options.ignoreStandalone; var isRoot = !this.isRootSeen; this.isRootSeen = true; var body = program.body; for (var i = 0, l = body.length; i < l; i++) { var current = body[i], strip = this.accept(current); if (!strip) { continue; } var _isPrevWhitespace = isPrevWhitespace(body, i, isRoot), _isNextWhitespace = isNextWhitespace(body, i, isRoot), openStandalone = strip.openStandalone && _isPrevWhitespace, closeStandalone = strip.closeStandalone && _isNextWhitespace, inlineStandalone = strip.inlineStandalone && _isPrevWhitespace && _isNextWhitespace; if (strip.close) { omitRight(body, i, true); } if (strip.open) { omitLeft(body, i, true); } if (doStandalone && inlineStandalone) { omitRight(body, i); if (omitLeft(body, i)) { // If we are on a standalone node, save the indent info for partials if (current.type === 'PartialStatement') { // Pull out the whitespace from the final line current.indent = /([ \t]+$)/.exec(body[i - 1].original)[1]; } } } if (doStandalone && openStandalone) { omitRight((current.program || current.inverse).body); // Strip out the previous content node if it's whitespace only omitLeft(body, i); } if (doStandalone && closeStandalone) { // Always strip the next node omitRight(body, i); omitLeft((current.inverse || current.program).body); } } return program; }; WhitespaceControl.prototype.BlockStatement = WhitespaceControl.prototype.DecoratorBlock = WhitespaceControl.prototype.PartialBlockStatement = function (block) { this.accept(block.program); this.accept(block.inverse); // Find the inverse program that is involed with whitespace stripping. var program = block.program || block.inverse, inverse = block.program && block.inverse, firstInverse = inverse, lastInverse = inverse; if (inverse && inverse.chained) { firstInverse = inverse.body[0].program; // Walk the inverse chain to find the last inverse that is actually in the chain. while (lastInverse.chained) { lastInverse = lastInverse.body[lastInverse.body.length - 1].program; } } var strip = { open: block.openStrip.open, close: block.closeStrip.close, // Determine the standalone candiacy. Basically flag our content as being possibly standalone // so our parent can determine if we actually are standalone openStandalone: isNextWhitespace(program.body), closeStandalone: isPrevWhitespace((firstInverse || program).body) }; if (block.openStrip.close) { omitRight(program.body, null, true); } if (inverse) { var inverseStrip = block.inverseStrip; if (inverseStrip.open) { omitLeft(program.body, null, true); } if (inverseStrip.close) { omitRight(firstInverse.body, null, true); } if (block.closeStrip.open) { omitLeft(lastInverse.body, null, true); } // Find standalone else statments if (!this.options.ignoreStandalone && isPrevWhitespace(program.body) && isNextWhitespace(firstInverse.body)) { omitLeft(program.body); omitRight(firstInverse.body); } } else if (block.closeStrip.open) { omitLeft(program.body, null, true); } return strip; }; WhitespaceControl.prototype.Decorator = WhitespaceControl.prototype.MustacheStatement = function (mustache) { return mustache.strip; }; WhitespaceControl.prototype.PartialStatement = WhitespaceControl.prototype.CommentStatement = function (node) { /* istanbul ignore next */ var strip = node.strip || {}; return { inlineStandalone: true, open: strip.open, close: strip.close }; }; function isPrevWhitespace(body, i, isRoot) { if (i === undefined) { i = body.length; } // Nodes that end with newlines are considered whitespace (but are special // cased for strip operations) var prev = body[i - 1], sibling = body[i - 2]; if (!prev) { return isRoot; } if (prev.type === 'ContentStatement') { return (sibling || !isRoot ? /\r?\n\s*?$/ : /(^|\r?\n)\s*?$/).test(prev.original); } } function isNextWhitespace(body, i, isRoot) { if (i === undefined) { i = -1; } var next = body[i + 1], sibling = body[i + 2]; if (!next) { return isRoot; } if (next.type === 'ContentStatement') { return (sibling || !isRoot ? /^\s*?\r?\n/ : /^\s*?(\r?\n|$)/).test(next.original); } } // Marks the node to the right of the position as omitted. // I.e. {{foo}}' ' will mark the ' ' node as omitted. // // If i is undefined, then the first child will be marked as such. // // If mulitple is truthy then all whitespace will be stripped out until non-whitespace // content is met. function omitRight(body, i, multiple) { var current = body[i == null ? 0 : i + 1]; if (!current || current.type !== 'ContentStatement' || !multiple && current.rightStripped) { return; } var original = current.value; current.value = current.value.replace(multiple ? /^\s+/ : /^[ \t]*\r?\n?/, ''); current.rightStripped = current.value !== original; } // Marks the node to the left of the position as omitted. // I.e. ' '{{foo}} will mark the ' ' node as omitted. // // If i is undefined then the last child will be marked as such. // // If mulitple is truthy then all whitespace will be stripped out until non-whitespace // content is met. function omitLeft(body, i, multiple) { var current = body[i == null ? body.length - 1 : i - 1]; if (!current || current.type !== 'ContentStatement' || !multiple && current.leftStripped) { return; } // We omit the last node if it's whitespace only and not preceeded by a non-content node. var original = current.value; current.value = current.value.replace(multiple ? /\s+$/ : /[ \t]+$/, ''); current.leftStripped = current.value !== original; return current.leftStripped; } exports['default'] = WhitespaceControl; module.exports = exports['default']; /***/ }, /* 25 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); function Visitor() { this.parents = []; } Visitor.prototype = { constructor: Visitor, mutating: false, // Visits a given value. If mutating, will replace the value if necessary. acceptKey: function acceptKey(node, name) { var value = this.accept(node[name]); if (this.mutating) { // Hacky sanity check: This may have a few false positives for type for the helper // methods but will generally do the right thing without a lot of overhead. if (value && !Visitor.prototype[value.type]) { throw new _exception2['default']('Unexpected node type "' + value.type + '" found when accepting ' + name + ' on ' + node.type); } node[name] = value; } }, // Performs an accept operation with added sanity check to ensure // required keys are not removed. acceptRequired: function acceptRequired(node, name) { this.acceptKey(node, name); if (!node[name]) { throw new _exception2['default'](node.type + ' requires ' + name); } }, // Traverses a given array. If mutating, empty respnses will be removed // for child elements. acceptArray: function acceptArray(array) { for (var i = 0, l = array.length; i < l; i++) { this.acceptKey(array, i); if (!array[i]) { array.splice(i, 1); i--; l--; } } }, accept: function accept(object) { if (!object) { return; } /* istanbul ignore next: Sanity code */ if (!this[object.type]) { throw new _exception2['default']('Unknown type: ' + object.type, object); } if (this.current) { this.parents.unshift(this.current); } this.current = object; var ret = this[object.type](object); this.current = this.parents.shift(); if (!this.mutating || ret) { return ret; } else if (ret !== false) { return object; } }, Program: function Program(program) { this.acceptArray(program.body); }, MustacheStatement: visitSubExpression, Decorator: visitSubExpression, BlockStatement: visitBlock, DecoratorBlock: visitBlock, PartialStatement: visitPartial, PartialBlockStatement: function PartialBlockStatement(partial) { visitPartial.call(this, partial); this.acceptKey(partial, 'program'); }, ContentStatement: function ContentStatement() /* content */{}, CommentStatement: function CommentStatement() /* comment */{}, SubExpression: visitSubExpression, PathExpression: function PathExpression() /* path */{}, StringLiteral: function StringLiteral() /* string */{}, NumberLiteral: function NumberLiteral() /* number */{}, BooleanLiteral: function BooleanLiteral() /* bool */{}, UndefinedLiteral: function UndefinedLiteral() /* literal */{}, NullLiteral: function NullLiteral() /* literal */{}, Hash: function Hash(hash) { this.acceptArray(hash.pairs); }, HashPair: function HashPair(pair) { this.acceptRequired(pair, 'value'); } }; function visitSubExpression(mustache) { this.acceptRequired(mustache, 'path'); this.acceptArray(mustache.params); this.acceptKey(mustache, 'hash'); } function visitBlock(block) { visitSubExpression.call(this, block); this.acceptKey(block, 'program'); this.acceptKey(block, 'inverse'); } function visitPartial(partial) { this.acceptRequired(partial, 'name'); this.acceptArray(partial.params); this.acceptKey(partial, 'hash'); } exports['default'] = Visitor; module.exports = exports['default']; /***/ }, /* 26 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.SourceLocation = SourceLocation; exports.id = id; exports.stripFlags = stripFlags; exports.stripComment = stripComment; exports.preparePath = preparePath; exports.prepareMustache = prepareMustache; exports.prepareRawBlock = prepareRawBlock; exports.prepareBlock = prepareBlock; exports.prepareProgram = prepareProgram; exports.preparePartialBlock = preparePartialBlock; var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); function validateClose(open, close) { close = close.path ? close.path.original : close; if (open.path.original !== close) { var errorNode = { loc: open.path.loc }; throw new _exception2['default'](open.path.original + " doesn't match " + close, errorNode); } } function SourceLocation(source, locInfo) { this.source = source; this.start = { line: locInfo.first_line, column: locInfo.first_column }; this.end = { line: locInfo.last_line, column: locInfo.last_column }; } function id(token) { if (/^\[.*\]$/.test(token)) { return token.substr(1, token.length - 2); } else { return token; } } function stripFlags(open, close) { return { open: open.charAt(2) === '~', close: close.charAt(close.length - 3) === '~' }; } function stripComment(comment) { return comment.replace(/^\{\{~?\!-?-?/, '').replace(/-?-?~?\}\}$/, ''); } function preparePath(data, parts, loc) { loc = this.locInfo(loc); var original = data ? '@' : '', dig = [], depth = 0, depthString = ''; for (var i = 0, l = parts.length; i < l; i++) { var part = parts[i].part, // If we have [] syntax then we do not treat path references as operators, // i.e. foo.[this] resolves to approximately context.foo['this'] isLiteral = parts[i].original !== part; original += (parts[i].separator || '') + part; if (!isLiteral && (part === '..' || part === '.' || part === 'this')) { if (dig.length > 0) { throw new _exception2['default']('Invalid path: ' + original, { loc: loc }); } else if (part === '..') { depth++; depthString += '../'; } } else { dig.push(part); } } return { type: 'PathExpression', data: data, depth: depth, parts: dig, original: original, loc: loc }; } function prepareMustache(path, params, hash, open, strip, locInfo) { // Must use charAt to support IE pre-10 var escapeFlag = open.charAt(3) || open.charAt(2), escaped = escapeFlag !== '{' && escapeFlag !== '&'; var decorator = /\*/.test(open); return { type: decorator ? 'Decorator' : 'MustacheStatement', path: path, params: params, hash: hash, escaped: escaped, strip: strip, loc: this.locInfo(locInfo) }; } function prepareRawBlock(openRawBlock, contents, close, locInfo) { validateClose(openRawBlock, close); locInfo = this.locInfo(locInfo); var program = { type: 'Program', body: contents, strip: {}, loc: locInfo }; return { type: 'BlockStatement', path: openRawBlock.path, params: openRawBlock.params, hash: openRawBlock.hash, program: program, openStrip: {}, inverseStrip: {}, closeStrip: {}, loc: locInfo }; } function prepareBlock(openBlock, program, inverseAndProgram, close, inverted, locInfo) { if (close && close.path) { validateClose(openBlock, close); } var decorator = /\*/.test(openBlock.open); program.blockParams = openBlock.blockParams; var inverse = undefined, inverseStrip = undefined; if (inverseAndProgram) { if (decorator) { throw new _exception2['default']('Unexpected inverse block on decorator', inverseAndProgram); } if (inverseAndProgram.chain) { inverseAndProgram.program.body[0].closeStrip = close.strip; } inverseStrip = inverseAndProgram.strip; inverse = inverseAndProgram.program; } if (inverted) { inverted = inverse; inverse = program; program = inverted; } return { type: decorator ? 'DecoratorBlock' : 'BlockStatement', path: openBlock.path, params: openBlock.params, hash: openBlock.hash, program: program, inverse: inverse, openStrip: openBlock.strip, inverseStrip: inverseStrip, closeStrip: close && close.strip, loc: this.locInfo(locInfo) }; } function prepareProgram(statements, loc) { if (!loc && statements.length) { var firstLoc = statements[0].loc, lastLoc = statements[statements.length - 1].loc; /* istanbul ignore else */ if (firstLoc && lastLoc) { loc = { source: firstLoc.source, start: { line: firstLoc.start.line, column: firstLoc.start.column }, end: { line: lastLoc.end.line, column: lastLoc.end.column } }; } } return { type: 'Program', body: statements, strip: {}, loc: loc }; } function preparePartialBlock(open, program, close, locInfo) { validateClose(open, close); return { type: 'PartialBlockStatement', name: open.path, params: open.params, hash: open.hash, program: program, openStrip: open.strip, closeStrip: close && close.strip, loc: this.locInfo(locInfo) }; } /***/ }, /* 27 */ /***/ function(module, exports, __webpack_require__) { /* eslint-disable new-cap */ 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; exports.Compiler = Compiler; exports.precompile = precompile; exports.compile = compile; var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); var _utils = __webpack_require__(5); var _ast = __webpack_require__(21); var _ast2 = _interopRequireDefault(_ast); var slice = [].slice; function Compiler() {} // the foundHelper register will disambiguate helper lookup from finding a // function in a context. This is necessary for mustache compatibility, which // requires that context functions in blocks are evaluated by blockHelperMissing, // and then proceed as if the resulting value was provided to blockHelperMissing. Compiler.prototype = { compiler: Compiler, equals: function equals(other) { var len = this.opcodes.length; if (other.opcodes.length !== len) { return false; } for (var i = 0; i < len; i++) { var opcode = this.opcodes[i], otherOpcode = other.opcodes[i]; if (opcode.opcode !== otherOpcode.opcode || !argEquals(opcode.args, otherOpcode.args)) { return false; } } // We know that length is the same between the two arrays because they are directly tied // to the opcode behavior above. len = this.children.length; for (var i = 0; i < len; i++) { if (!this.children[i].equals(other.children[i])) { return false; } } return true; }, guid: 0, compile: function compile(program, options) { this.sourceNode = []; this.opcodes = []; this.children = []; this.options = options; this.stringParams = options.stringParams; this.trackIds = options.trackIds; options.blockParams = options.blockParams || []; // These changes will propagate to the other compiler components var knownHelpers = options.knownHelpers; options.knownHelpers = { 'helperMissing': true, 'blockHelperMissing': true, 'each': true, 'if': true, 'unless': true, 'with': true, 'log': true, 'lookup': true }; if (knownHelpers) { for (var _name in knownHelpers) { /* istanbul ignore else */ if (_name in knownHelpers) { options.knownHelpers[_name] = knownHelpers[_name]; } } } return this.accept(program); }, compileProgram: function compileProgram(program) { var childCompiler = new this.compiler(), // eslint-disable-line new-cap result = childCompiler.compile(program, this.options), guid = this.guid++; this.usePartial = this.usePartial || result.usePartial; this.children[guid] = result; this.useDepths = this.useDepths || result.useDepths; return guid; }, accept: function accept(node) { /* istanbul ignore next: Sanity code */ if (!this[node.type]) { throw new _exception2['default']('Unknown type: ' + node.type, node); } this.sourceNode.unshift(node); var ret = this[node.type](node); this.sourceNode.shift(); return ret; }, Program: function Program(program) { this.options.blockParams.unshift(program.blockParams); var body = program.body, bodyLength = body.length; for (var i = 0; i < bodyLength; i++) { this.accept(body[i]); } this.options.blockParams.shift(); this.isSimple = bodyLength === 1; this.blockParams = program.blockParams ? program.blockParams.length : 0; return this; }, BlockStatement: function BlockStatement(block) { transformLiteralToPath(block); var program = block.program, inverse = block.inverse; program = program && this.compileProgram(program); inverse = inverse && this.compileProgram(inverse); var type = this.classifySexpr(block); if (type === 'helper') { this.helperSexpr(block, program, inverse); } else if (type === 'simple') { this.simpleSexpr(block); // now that the simple mustache is resolved, we need to // evaluate it by executing `blockHelperMissing` this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); this.opcode('emptyHash'); this.opcode('blockValue', block.path.original); } else { this.ambiguousSexpr(block, program, inverse); // now that the simple mustache is resolved, we need to // evaluate it by executing `blockHelperMissing` this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); this.opcode('emptyHash'); this.opcode('ambiguousBlockValue'); } this.opcode('append'); }, DecoratorBlock: function DecoratorBlock(decorator) { var program = decorator.program && this.compileProgram(decorator.program); var params = this.setupFullMustacheParams(decorator, program, undefined), path = decorator.path; this.useDecorators = true; this.opcode('registerDecorator', params.length, path.original); }, PartialStatement: function PartialStatement(partial) { this.usePartial = true; var program = partial.program; if (program) { program = this.compileProgram(partial.program); } var params = partial.params; if (params.length > 1) { throw new _exception2['default']('Unsupported number of partial arguments: ' + params.length, partial); } else if (!params.length) { if (this.options.explicitPartialContext) { this.opcode('pushLiteral', 'undefined'); } else { params.push({ type: 'PathExpression', parts: [], depth: 0 }); } } var partialName = partial.name.original, isDynamic = partial.name.type === 'SubExpression'; if (isDynamic) { this.accept(partial.name); } this.setupFullMustacheParams(partial, program, undefined, true); var indent = partial.indent || ''; if (this.options.preventIndent && indent) { this.opcode('appendContent', indent); indent = ''; } this.opcode('invokePartial', isDynamic, partialName, indent); this.opcode('append'); }, PartialBlockStatement: function PartialBlockStatement(partialBlock) { this.PartialStatement(partialBlock); }, MustacheStatement: function MustacheStatement(mustache) { this.SubExpression(mustache); if (mustache.escaped && !this.options.noEscape) { this.opcode('appendEscaped'); } else { this.opcode('append'); } }, Decorator: function Decorator(decorator) { this.DecoratorBlock(decorator); }, ContentStatement: function ContentStatement(content) { if (content.value) { this.opcode('appendContent', content.value); } }, CommentStatement: function CommentStatement() {}, SubExpression: function SubExpression(sexpr) { transformLiteralToPath(sexpr); var type = this.classifySexpr(sexpr); if (type === 'simple') { this.simpleSexpr(sexpr); } else if (type === 'helper') { this.helperSexpr(sexpr); } else { this.ambiguousSexpr(sexpr); } }, ambiguousSexpr: function ambiguousSexpr(sexpr, program, inverse) { var path = sexpr.path, name = path.parts[0], isBlock = program != null || inverse != null; this.opcode('getContext', path.depth); this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); path.strict = true; this.accept(path); this.opcode('invokeAmbiguous', name, isBlock); }, simpleSexpr: function simpleSexpr(sexpr) { var path = sexpr.path; path.strict = true; this.accept(path); this.opcode('resolvePossibleLambda'); }, helperSexpr: function helperSexpr(sexpr, program, inverse) { var params = this.setupFullMustacheParams(sexpr, program, inverse), path = sexpr.path, name = path.parts[0]; if (this.options.knownHelpers[name]) { this.opcode('invokeKnownHelper', params.length, name); } else if (this.options.knownHelpersOnly) { throw new _exception2['default']('You specified knownHelpersOnly, but used the unknown helper ' + name, sexpr); } else { path.strict = true; path.falsy = true; this.accept(path); this.opcode('invokeHelper', params.length, path.original, _ast2['default'].helpers.simpleId(path)); } }, PathExpression: function PathExpression(path) { this.addDepth(path.depth); this.opcode('getContext', path.depth); var name = path.parts[0], scoped = _ast2['default'].helpers.scopedId(path), blockParamId = !path.depth && !scoped && this.blockParamIndex(name); if (blockParamId) { this.opcode('lookupBlockParam', blockParamId, path.parts); } else if (!name) { // Context reference, i.e. `{{foo .}}` or `{{foo ..}}` this.opcode('pushContext'); } else if (path.data) { this.options.data = true; this.opcode('lookupData', path.depth, path.parts, path.strict); } else { this.opcode('lookupOnContext', path.parts, path.falsy, path.strict, scoped); } }, StringLiteral: function StringLiteral(string) { this.opcode('pushString', string.value); }, NumberLiteral: function NumberLiteral(number) { this.opcode('pushLiteral', number.value); }, BooleanLiteral: function BooleanLiteral(bool) { this.opcode('pushLiteral', bool.value); }, UndefinedLiteral: function UndefinedLiteral() { this.opcode('pushLiteral', 'undefined'); }, NullLiteral: function NullLiteral() { this.opcode('pushLiteral', 'null'); }, Hash: function Hash(hash) { var pairs = hash.pairs, i = 0, l = pairs.length; this.opcode('pushHash'); for (; i < l; i++) { this.pushParam(pairs[i].value); } while (i--) { this.opcode('assignToHash', pairs[i].key); } this.opcode('popHash'); }, // HELPERS opcode: function opcode(name) { this.opcodes.push({ opcode: name, args: slice.call(arguments, 1), loc: this.sourceNode[0].loc }); }, addDepth: function addDepth(depth) { if (!depth) { return; } this.useDepths = true; }, classifySexpr: function classifySexpr(sexpr) { var isSimple = _ast2['default'].helpers.simpleId(sexpr.path); var isBlockParam = isSimple && !!this.blockParamIndex(sexpr.path.parts[0]); // a mustache is an eligible helper if: // * its id is simple (a single part, not `this` or `..`) var isHelper = !isBlockParam && _ast2['default'].helpers.helperExpression(sexpr); // if a mustache is an eligible helper but not a definite // helper, it is ambiguous, and will be resolved in a later // pass or at runtime. var isEligible = !isBlockParam && (isHelper || isSimple); // if ambiguous, we can possibly resolve the ambiguity now // An eligible helper is one that does not have a complex path, i.e. `this.foo`, `../foo` etc. if (isEligible && !isHelper) { var _name2 = sexpr.path.parts[0], options = this.options; if (options.knownHelpers[_name2]) { isHelper = true; } else if (options.knownHelpersOnly) { isEligible = false; } } if (isHelper) { return 'helper'; } else if (isEligible) { return 'ambiguous'; } else { return 'simple'; } }, pushParams: function pushParams(params) { for (var i = 0, l = params.length; i < l; i++) { this.pushParam(params[i]); } }, pushParam: function pushParam(val) { var value = val.value != null ? val.value : val.original || ''; if (this.stringParams) { if (value.replace) { value = value.replace(/^(\.?\.\/)*/g, '').replace(/\//g, '.'); } if (val.depth) { this.addDepth(val.depth); } this.opcode('getContext', val.depth || 0); this.opcode('pushStringParam', value, val.type); if (val.type === 'SubExpression') { // SubExpressions get evaluated and passed in // in string params mode. this.accept(val); } } else { if (this.trackIds) { var blockParamIndex = undefined; if (val.parts && !_ast2['default'].helpers.scopedId(val) && !val.depth) { blockParamIndex = this.blockParamIndex(val.parts[0]); } if (blockParamIndex) { var blockParamChild = val.parts.slice(1).join('.'); this.opcode('pushId', 'BlockParam', blockParamIndex, blockParamChild); } else { value = val.original || value; if (value.replace) { value = value.replace(/^this(?:\.|$)/, '').replace(/^\.\//, '').replace(/^\.$/, ''); } this.opcode('pushId', val.type, value); } } this.accept(val); } }, setupFullMustacheParams: function setupFullMustacheParams(sexpr, program, inverse, omitEmpty) { var params = sexpr.params; this.pushParams(params); this.opcode('pushProgram', program); this.opcode('pushProgram', inverse); if (sexpr.hash) { this.accept(sexpr.hash); } else { this.opcode('emptyHash', omitEmpty); } return params; }, blockParamIndex: function blockParamIndex(name) { for (var depth = 0, len = this.options.blockParams.length; depth < len; depth++) { var blockParams = this.options.blockParams[depth], param = blockParams && _utils.indexOf(blockParams, name); if (blockParams && param >= 0) { return [depth, param]; } } } }; function precompile(input, options, env) { if (input == null || typeof input !== 'string' && input.type !== 'Program') { throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.precompile. You passed ' + input); } options = options || {}; if (!('data' in options)) { options.data = true; } if (options.compat) { options.useDepths = true; } var ast = env.parse(input, options), environment = new env.Compiler().compile(ast, options); return new env.JavaScriptCompiler().compile(environment, options); } function compile(input, options, env) { if (options === undefined) options = {}; if (input == null || typeof input !== 'string' && input.type !== 'Program') { throw new _exception2['default']('You must pass a string or Handlebars AST to Handlebars.compile. You passed ' + input); } if (!('data' in options)) { options.data = true; } if (options.compat) { options.useDepths = true; } var compiled = undefined; function compileInput() { var ast = env.parse(input, options), environment = new env.Compiler().compile(ast, options), templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true); return env.template(templateSpec); } // Template is only compiled on first use and cached after that point. function ret(context, execOptions) { if (!compiled) { compiled = compileInput(); } return compiled.call(this, context, execOptions); } ret._setup = function (setupOptions) { if (!compiled) { compiled = compileInput(); } return compiled._setup(setupOptions); }; ret._child = function (i, data, blockParams, depths) { if (!compiled) { compiled = compileInput(); } return compiled._child(i, data, blockParams, depths); }; return ret; } function argEquals(a, b) { if (a === b) { return true; } if (_utils.isArray(a) && _utils.isArray(b) && a.length === b.length) { for (var i = 0; i < a.length; i++) { if (!argEquals(a[i], b[i])) { return false; } } return true; } } function transformLiteralToPath(sexpr) { if (!sexpr.path.parts) { var literal = sexpr.path; // Casting to string here to make false and 0 literal values play nicely with the rest // of the system. sexpr.path = { type: 'PathExpression', data: false, depth: 0, parts: [literal.original + ''], original: literal.original + '', loc: literal.loc }; } } /***/ }, /* 28 */ /***/ function(module, exports, __webpack_require__) { 'use strict'; var _interopRequireDefault = __webpack_require__(1)['default']; exports.__esModule = true; var _base = __webpack_require__(4); var _exception = __webpack_require__(6); var _exception2 = _interopRequireDefault(_exception); var _utils = __webpack_require__(5); var _codeGen = __webpack_require__(29); var _codeGen2 = _interopRequireDefault(_codeGen); function Literal(value) { this.value = value; } function JavaScriptCompiler() {} JavaScriptCompiler.prototype = { // PUBLIC API: You can override these methods in a subclass to provide // alternative compiled forms for name lookup and buffering semantics nameLookup: function nameLookup(parent, name /* , type*/) { if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) { return [parent, '.', name]; } else { return [parent, '[', JSON.stringify(name), ']']; } }, depthedLookup: function depthedLookup(name) { return [this.aliasable('container.lookup'), '(depths, "', name, '")']; }, compilerInfo: function compilerInfo() { var revision = _base.COMPILER_REVISION, versions = _base.REVISION_CHANGES[revision]; return [revision, versions]; }, appendToBuffer: function appendToBuffer(source, location, explicit) { // Force a source as this simplifies the merge logic. if (!_utils.isArray(source)) { source = [source]; } source = this.source.wrap(source, location); if (this.environment.isSimple) { return ['return ', source, ';']; } else if (explicit) { // This is a case where the buffer operation occurs as a child of another // construct, generally braces. We have to explicitly output these buffer // operations to ensure that the emitted code goes in the correct location. return ['buffer += ', source, ';']; } else { source.appendToBuffer = true; return source; } }, initializeBuffer: function initializeBuffer() { return this.quotedString(''); }, // END PUBLIC API compile: function compile(environment, options, context, asObject) { this.environment = environment; this.options = options; this.stringParams = this.options.stringParams; this.trackIds = this.options.trackIds; this.precompile = !asObject; this.name = this.environment.name; this.isChild = !!context; this.context = context || { decorators: [], programs: [], environments: [] }; this.preamble(); this.stackSlot = 0; this.stackVars = []; this.aliases = {}; this.registers = { list: [] }; this.hashes = []; this.compileStack = []; this.inlineStack = []; this.blockParams = []; this.compileChildren(environment, options); this.useDepths = this.useDepths || environment.useDepths || environment.useDecorators || this.options.compat; this.useBlockParams = this.useBlockParams || environment.useBlockParams; var opcodes = environment.opcodes, opcode = undefined, firstLoc = undefined, i = undefined, l = undefined; for (i = 0, l = opcodes.length; i < l; i++) { opcode = opcodes[i]; this.source.currentLocation = opcode.loc; firstLoc = firstLoc || opcode.loc; this[opcode.opcode].apply(this, opcode.args); } // Flush any trailing content that might be pending. this.source.currentLocation = firstLoc; this.pushSource(''); /* istanbul ignore next */ if (this.stackSlot || this.inlineStack.length || this.compileStack.length) { throw new _exception2['default']('Compile completed with content left on stack'); } if (!this.decorators.isEmpty()) { this.useDecorators = true; this.decorators.prepend('var decorators = container.decorators;\n'); this.decorators.push('return fn;'); if (asObject) { this.decorators = Function.apply(this, ['fn', 'props', 'container', 'depth0', 'data', 'blockParams', 'depths', this.decorators.merge()]); } else { this.decorators.prepend('function(fn, props, container, depth0, data, blockParams, depths) {\n'); this.decorators.push('}\n'); this.decorators = this.decorators.merge(); } } else { this.decorators = undefined; } var fn = this.createFunctionContext(asObject); if (!this.isChild) { var ret = { compiler: this.compilerInfo(), main: fn }; if (this.decorators) { ret.main_d = this.decorators; // eslint-disable-line camelcase ret.useDecorators = true; } var _context = this.context; var programs = _context.programs; var decorators = _context.decorators; for (i = 0, l = programs.length; i < l; i++) { if (programs[i]) { ret[i] = programs[i]; if (decorators[i]) { ret[i + '_d'] = decorators[i]; ret.useDecorators = true; } } } if (this.environment.usePartial) { ret.usePartial = true; } if (this.options.data) { ret.useData = true; } if (this.useDepths) { ret.useDepths = true; } if (this.useBlockParams) { ret.useBlockParams = true; } if (this.options.compat) { ret.compat = true; } if (!asObject) { ret.compiler = JSON.stringify(ret.compiler); this.source.currentLocation = { start: { line: 1, column: 0 } }; ret = this.objectLiteral(ret); if (options.srcName) { ret = ret.toStringWithSourceMap({ file: options.destName }); ret.map = ret.map && ret.map.toString(); } else { ret = ret.toString(); } } else { ret.compilerOptions = this.options; } return ret; } else { return fn; } }, preamble: function preamble() { // track the last context pushed into place to allow skipping the // getContext opcode when it would be a noop this.lastContext = 0; this.source = new _codeGen2['default'](this.options.srcName); this.decorators = new _codeGen2['default'](this.options.srcName); }, createFunctionContext: function createFunctionContext(asObject) { var varDeclarations = ''; var locals = this.stackVars.concat(this.registers.list); if (locals.length > 0) { varDeclarations += ', ' + locals.join(', '); } // Generate minimizer alias mappings // // When using true SourceNodes, this will update all references to the given alias // as the source nodes are reused in situ. For the non-source node compilation mode, // aliases will not be used, but this case is already being run on the client and // we aren't concern about minimizing the template size. var aliasCount = 0; for (var alias in this.aliases) { // eslint-disable-line guard-for-in var node = this.aliases[alias]; if (this.aliases.hasOwnProperty(alias) && node.children && node.referenceCount > 1) { varDeclarations += ', alias' + ++aliasCount + '=' + alias; node.children[0] = 'alias' + aliasCount; } } var params = ['container', 'depth0', 'helpers', 'partials', 'data']; if (this.useBlockParams || this.useDepths) { params.push('blockParams'); } if (this.useDepths) { params.push('depths'); } // Perform a second pass over the output to merge content when possible var source = this.mergeSource(varDeclarations); if (asObject) { params.push(source); return Function.apply(this, params); } else { return this.source.wrap(['function(', params.join(','), ') {\n ', source, '}']); } }, mergeSource: function mergeSource(varDeclarations) { var isSimple = this.environment.isSimple, appendOnly = !this.forceBuffer, appendFirst = undefined, sourceSeen = undefined, bufferStart = undefined, bufferEnd = undefined; this.source.each(function (line) { if (line.appendToBuffer) { if (bufferStart) { line.prepend(' + '); } else { bufferStart = line; } bufferEnd = line; } else { if (bufferStart) { if (!sourceSeen) { appendFirst = true; } else { bufferStart.prepend('buffer += '); } bufferEnd.add(';'); bufferStart = bufferEnd = undefined; } sourceSeen = true; if (!isSimple) { appendOnly = false; } } }); if (appendOnly) { if (bufferStart) { bufferStart.prepend('return '); bufferEnd.add(';'); } else if (!sourceSeen) { this.source.push('return "";'); } } else { varDeclarations += ', buffer = ' + (appendFirst ? '' : this.initializeBuffer()); if (bufferStart) { bufferStart.prepend('return buffer + '); bufferEnd.add(';'); } else { this.source.push('return buffer;'); } } if (varDeclarations) { this.source.prepend('var ' + varDeclarations.substring(2) + (appendFirst ? '' : ';\n')); } return this.source.merge(); }, // [blockValue] // // On stack, before: hash, inverse, program, value // On stack, after: return value of blockHelperMissing // // The purpose of this opcode is to take a block of the form // `{{#this.foo}}...{{/this.foo}}`, resolve the value of `foo`, and // replace it on the stack with the result of properly // invoking blockHelperMissing. blockValue: function blockValue(name) { var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'), params = [this.contextName(0)]; this.setupHelperArgs(name, 0, params); var blockName = this.popStack(); params.splice(1, 0, blockName); this.push(this.source.functionCall(blockHelperMissing, 'call', params)); }, // [ambiguousBlockValue] // // On stack, before: hash, inverse, program, value // Compiler value, before: lastHelper=value of last found helper, if any // On stack, after, if no lastHelper: same as [blockValue] // On stack, after, if lastHelper: value ambiguousBlockValue: function ambiguousBlockValue() { // We're being a bit cheeky and reusing the options value from the prior exec var blockHelperMissing = this.aliasable('helpers.blockHelperMissing'), params = [this.contextName(0)]; this.setupHelperArgs('', 0, params, true); this.flushInline(); var current = this.topStack(); params.splice(1, 0, current); this.pushSource(['if (!', this.lastHelper, ') { ', current, ' = ', this.source.functionCall(blockHelperMissing, 'call', params), '}']); }, // [appendContent] // // On stack, before: ... // On stack, after: ... // // Appends the string value of `content` to the current buffer appendContent: function appendContent(content) { if (this.pendingContent) { content = this.pendingContent + content; } else { this.pendingLocation = this.source.currentLocation; } this.pendingContent = content; }, // [append] // // On stack, before: value, ... // On stack, after: ... // // Coerces `value` to a String and appends it to the current buffer. // // If `value` is truthy, or 0, it is coerced into a string and appended // Otherwise, the empty string is appended append: function append() { if (this.isInline()) { this.replaceStack(function (current) { return [' != null ? ', current, ' : ""']; }); this.pushSource(this.appendToBuffer(this.popStack())); } else { var local = this.popStack(); this.pushSource(['if (', local, ' != null) { ', this.appendToBuffer(local, undefined, true), ' }']); if (this.environment.isSimple) { this.pushSource(['else { ', this.appendToBuffer("''", undefined, true), ' }']); } } }, // [appendEscaped] // // On stack, before: value, ... // On stack, after: ... // // Escape `value` and append it to the buffer appendEscaped: function appendEscaped() { this.pushSource(this.appendToBuffer([this.aliasable('container.escapeExpression'), '(', this.popStack(), ')'])); }, // [getContext] // // On stack, before: ... // On stack, after: ... // Compiler value, after: lastContext=depth // // Set the value of the `lastContext` compiler value to the depth getContext: function getContext(depth) { this.lastContext = depth; }, // [pushContext] // // On stack, before: ... // On stack, after: currentContext, ... // // Pushes the value of the current context onto the stack. pushContext: function pushContext() { this.pushStackLiteral(this.contextName(this.lastContext)); }, // [lookupOnContext] // // On stack, before: ... // On stack, after: currentContext[name], ... // // Looks up the value of `name` on the current context and pushes // it onto the stack. lookupOnContext: function lookupOnContext(parts, falsy, strict, scoped) { var i = 0; if (!scoped && this.options.compat && !this.lastContext) { // The depthed query is expected to handle the undefined logic for the root level that // is implemented below, so we evaluate that directly in compat mode this.push(this.depthedLookup(parts[i++])); } else { this.pushContext(); } this.resolvePath('context', parts, i, falsy, strict); }, // [lookupBlockParam] // // On stack, before: ... // On stack, after: blockParam[name], ... // // Looks up the value of `parts` on the given block param and pushes // it onto the stack. lookupBlockParam: function lookupBlockParam(blockParamId, parts) { this.useBlockParams = true; this.push(['blockParams[', blockParamId[0], '][', blockParamId[1], ']']); this.resolvePath('context', parts, 1); }, // [lookupData] // // On stack, before: ... // On stack, after: data, ... // // Push the data lookup operator lookupData: function lookupData(depth, parts, strict) { if (!depth) { this.pushStackLiteral('data'); } else { this.pushStackLiteral('container.data(data, ' + depth + ')'); } this.resolvePath('data', parts, 0, true, strict); }, resolvePath: function resolvePath(type, parts, i, falsy, strict) { // istanbul ignore next var _this = this; if (this.options.strict || this.options.assumeObjects) { this.push(strictLookup(this.options.strict && strict, this, parts, type)); return; } var len = parts.length; for (; i < len; i++) { /* eslint-disable no-loop-func */ this.replaceStack(function (current) { var lookup = _this.nameLookup(current, parts[i], type); // We want to ensure that zero and false are handled properly if the context (falsy flag) // needs to have the special handling for these values. if (!falsy) { return [' != null ? ', lookup, ' : ', current]; } else { // Otherwise we can use generic falsy handling return [' && ', lookup]; } }); /* eslint-enable no-loop-func */ } }, // [resolvePossibleLambda] // // On stack, before: value, ... // On stack, after: resolved value, ... // // If the `value` is a lambda, replace it on the stack by // the return value of the lambda resolvePossibleLambda: function resolvePossibleLambda() { this.push([this.aliasable('container.lambda'), '(', this.popStack(), ', ', this.contextName(0), ')']); }, // [pushStringParam] // // On stack, before: ... // On stack, after: string, currentContext, ... // // This opcode is designed for use in string mode, which // provides the string value of a parameter along with its // depth rather than resolving it immediately. pushStringParam: function pushStringParam(string, type) { this.pushContext(); this.pushString(type); // If it's a subexpression, the string result // will be pushed after this opcode. if (type !== 'SubExpression') { if (typeof string === 'string') { this.pushString(string); } else { this.pushStackLiteral(string); } } }, emptyHash: function emptyHash(omitEmpty) { if (this.trackIds) { this.push('{}'); // hashIds } if (this.stringParams) { this.push('{}'); // hashContexts this.push('{}'); // hashTypes } this.pushStackLiteral(omitEmpty ? 'undefined' : '{}'); }, pushHash: function pushHash() { if (this.hash) { this.hashes.push(this.hash); } this.hash = { values: [], types: [], contexts: [], ids: [] }; }, popHash: function popHash() { var hash = this.hash; this.hash = this.hashes.pop(); if (this.trackIds) { this.push(this.objectLiteral(hash.ids)); } if (this.stringParams) { this.push(this.objectLiteral(hash.contexts)); this.push(this.objectLiteral(hash.types)); } this.push(this.objectLiteral(hash.values)); }, // [pushString] // // On stack, before: ... // On stack, after: quotedString(string), ... // // Push a quoted version of `string` onto the stack pushString: function pushString(string) { this.pushStackLiteral(this.quotedString(string)); }, // [pushLiteral] // // On stack, before: ... // On stack, after: value, ... // // Pushes a value onto the stack. This operation prevents // the compiler from creating a temporary variable to hold // it. pushLiteral: function pushLiteral(value) { this.pushStackLiteral(value); }, // [pushProgram] // // On stack, before: ... // On stack, after: program(guid), ... // // Push a program expression onto the stack. This takes // a compile-time guid and converts it into a runtime-accessible // expression. pushProgram: function pushProgram(guid) { if (guid != null) { this.pushStackLiteral(this.programExpression(guid)); } else { this.pushStackLiteral(null); } }, // [registerDecorator] // // On stack, before: hash, program, params..., ... // On stack, after: ... // // Pops off the decorator's parameters, invokes the decorator, // and inserts the decorator into the decorators list. registerDecorator: function registerDecorator(paramSize, name) { var foundDecorator = this.nameLookup('decorators', name, 'decorator'), options = this.setupHelperArgs(name, paramSize); this.decorators.push(['fn = ', this.decorators.functionCall(foundDecorator, '', ['fn', 'props', 'container', options]), ' || fn;']); }, // [invokeHelper] // // On stack, before: hash, inverse, program, params..., ... // On stack, after: result of helper invocation // // Pops off the helper's parameters, invokes the helper, // and pushes the helper's return value onto the stack. // // If the helper is not found, `helperMissing` is called. invokeHelper: function invokeHelper(paramSize, name, isSimple) { var nonHelper = this.popStack(), helper = this.setupHelper(paramSize, name), simple = isSimple ? [helper.name, ' || '] : ''; var lookup = ['('].concat(simple, nonHelper); if (!this.options.strict) { lookup.push(' || ', this.aliasable('helpers.helperMissing')); } lookup.push(')'); this.push(this.source.functionCall(lookup, 'call', helper.callParams)); }, // [invokeKnownHelper] // // On stack, before: hash, inverse, program, params..., ... // On stack, after: result of helper invocation // // This operation is used when the helper is known to exist, // so a `helperMissing` fallback is not required. invokeKnownHelper: function invokeKnownHelper(paramSize, name) { var helper = this.setupHelper(paramSize, name); this.push(this.source.functionCall(helper.name, 'call', helper.callParams)); }, // [invokeAmbiguous] // // On stack, before: hash, inverse, program, params..., ... // On stack, after: result of disambiguation // // This operation is used when an expression like `{{foo}}` // is provided, but we don't know at compile-time whether it // is a helper or a path. // // This operation emits more code than the other options, // and can be avoided by passing the `knownHelpers` and // `knownHelpersOnly` flags at compile-time. invokeAmbiguous: function invokeAmbiguous(name, helperCall) { this.useRegister('helper'); var nonHelper = this.popStack(); this.emptyHash(); var helper = this.setupHelper(0, name, helperCall); var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper'); var lookup = ['(', '(helper = ', helperName, ' || ', nonHelper, ')']; if (!this.options.strict) { lookup[0] = '(helper = '; lookup.push(' != null ? helper : ', this.aliasable('helpers.helperMissing')); } this.push(['(', lookup, helper.paramsInit ? ['),(', helper.paramsInit] : [], '),', '(typeof helper === ', this.aliasable('"function"'), ' ? ', this.source.functionCall('helper', 'call', helper.callParams), ' : helper))']); }, // [invokePartial] // // On stack, before: context, ... // On stack after: result of partial invocation // // This operation pops off a context, invokes a partial with that context, // and pushes the result of the invocation back. invokePartial: function invokePartial(isDynamic, name, indent) { var params = [], options = this.setupParams(name, 1, params); if (isDynamic) { name = this.popStack(); delete options.name; } if (indent) { options.indent = JSON.stringify(indent); } options.helpers = 'helpers'; options.partials = 'partials'; options.decorators = 'container.decorators'; if (!isDynamic) { params.unshift(this.nameLookup('partials', name, 'partial')); } else { params.unshift(name); } if (this.options.compat) { options.depths = 'depths'; } options = this.objectLiteral(options); params.push(options); this.push(this.source.functionCall('container.invokePartial', '', params)); }, // [assignToHash] // // On stack, before: value, ..., hash, ... // On stack, after: ..., hash, ... // // Pops a value off the stack and assigns it to the current hash assignToHash: function assignToHash(key) { var value = this.popStack(), context = undefined, type = undefined, id = undefined; if (this.trackIds) { id = this.popStack(); } if (this.stringParams) { type = this.popStack(); context = this.popStack(); } var hash = this.hash; if (context) { hash.contexts[key] = context; } if (type) { hash.types[key] = type; } if (id) { hash.ids[key] = id; } hash.values[key] = value; }, pushId: function pushId(type, name, child) { if (type === 'BlockParam') { this.pushStackLiteral('blockParams[' + name[0] + '].path[' + name[1] + ']' + (child ? ' + ' + JSON.stringify('.' + child) : '')); } else if (type === 'PathExpression') { this.pushString(name); } else if (type === 'SubExpression') { this.pushStackLiteral('true'); } else { this.pushStackLiteral('null'); } }, // HELPERS compiler: JavaScriptCompiler, compileChildren: function compileChildren(environment, options) { var children = environment.children, child = undefined, compiler = undefined; for (var i = 0, l = children.length; i < l; i++) { child = children[i]; compiler = new this.compiler(); // eslint-disable-line new-cap var index = this.matchExistingProgram(child); if (index == null) { this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children index = this.context.programs.length; child.index = index; child.name = 'program' + index; this.context.programs[index] = compiler.compile(child, options, this.context, !this.precompile); this.context.decorators[index] = compiler.decorators; this.context.environments[index] = child; this.useDepths = this.useDepths || compiler.useDepths; this.useBlockParams = this.useBlockParams || compiler.useBlockParams; } else { child.index = index; child.name = 'program' + index; this.useDepths = this.useDepths || child.useDepths; this.useBlockParams = this.useBlockParams || child.useBlockParams; } } }, matchExistingProgram: function matchExistingProgram(child) { for (var i = 0, len = this.context.environments.length; i < len; i++) { var environment = this.context.environments[i]; if (environment && environment.equals(child)) { return i; } } }, programExpression: function programExpression(guid) { var child = this.environment.children[guid], programParams = [child.index, 'data', child.blockParams]; if (this.useBlockParams || this.useDepths) { programParams.push('blockParams'); } if (this.useDepths) { programParams.push('depths'); } return 'container.program(' + programParams.join(', ') + ')'; }, useRegister: function useRegister(name) { if (!this.registers[name]) { this.registers[name] = true; this.registers.list.push(name); } }, push: function push(expr) { if (!(expr instanceof Literal)) { expr = this.source.wrap(expr); } this.inlineStack.push(expr); return expr; }, pushStackLiteral: function pushStackLiteral(item) { this.push(new Literal(item)); }, pushSource: function pushSource(source) { if (this.pendingContent) { this.source.push(this.appendToBuffer(this.source.quotedString(this.pendingContent), this.pendingLocation)); this.pendingContent = undefined; } if (source) { this.source.push(source); } }, replaceStack: function replaceStack(callback) { var prefix = ['('], stack = undefined, createdStack = undefined, usedLiteral = undefined; /* istanbul ignore next */ if (!this.isInline()) { throw new _exception2['default']('replaceStack on non-inline'); } // We want to merge the inline statement into the replacement statement via ',' var top = this.popStack(true); if (top instanceof Literal) { // Literals do not need to be inlined stack = [top.value]; prefix = ['(', stack]; usedLiteral = true; } else { // Get or create the current stack name for use by the inline createdStack = true; var _name = this.incrStack(); prefix = ['((', this.push(_name), ' = ', top, ')']; stack = this.topStack(); } var item = callback.call(this, stack); if (!usedLiteral) { this.popStack(); } if (createdStack) { this.stackSlot--; } this.push(prefix.concat(item, ')')); }, incrStack: function incrStack() { this.stackSlot++; if (this.stackSlot > this.stackVars.length) { this.stackVars.push('stack' + this.stackSlot); } return this.topStackName(); }, topStackName: function topStackName() { return 'stack' + this.stackSlot; }, flushInline: function flushInline() { var inlineStack = this.inlineStack; this.inlineStack = []; for (var i = 0, len = inlineStack.length; i < len; i++) { var entry = inlineStack[i]; /* istanbul ignore if */ if (entry instanceof Literal) { this.compileStack.push(entry); } else { var stack = this.incrStack(); this.pushSource([stack, ' = ', entry, ';']); this.compileStack.push(stack); } } }, isInline: function isInline() { return this.inlineStack.length; }, popStack: function popStack(wrapped) { var inline = this.isInline(), item = (inline ? this.inlineStack : this.compileStack).pop(); if (!wrapped && item instanceof Literal) { return item.value; } else { if (!inline) { /* istanbul ignore next */ if (!this.stackSlot) { throw new _exception2['default']('Invalid stack pop'); } this.stackSlot--; } return item; } }, topStack: function topStack() { var stack = this.isInline() ? this.inlineStack : this.compileStack, item = stack[stack.length - 1]; /* istanbul ignore if */ if (item instanceof Literal) { return item.value; } else { return item; } }, contextName: function contextName(context) { if (this.useDepths && context) { return 'depths[' + context + ']'; } else { return 'depth' + context; } }, quotedString: function quotedString(str) { return this.source.quotedString(str); }, objectLiteral: function objectLiteral(obj) { return this.source.objectLiteral(obj); }, aliasable: function aliasable(name) { var ret = this.aliases[name]; if (ret) { ret.referenceCount++; return ret; } ret = this.aliases[name] = this.source.wrap(name); ret.aliasable = true; ret.referenceCount = 1; return ret; }, setupHelper: function setupHelper(paramSize, name, blockHelper) { var params = [], paramsInit = this.setupHelperArgs(name, paramSize, params, blockHelper); var foundHelper = this.nameLookup('helpers', name, 'helper'), callContext = this.aliasable(this.contextName(0) + ' != null ? ' + this.contextName(0) + ' : {}'); return { params: params, paramsInit: paramsInit, name: foundHelper, callParams: [callContext].concat(params) }; }, setupParams: function setupParams(helper, paramSize, params) { var options = {}, contexts = [], types = [], ids = [], objectArgs = !params, param = undefined; if (objectArgs) { params = []; } options.name = this.quotedString(helper); options.hash = this.popStack(); if (this.trackIds) { options.hashIds = this.popStack(); } if (this.stringParams) { options.hashTypes = this.popStack(); options.hashContexts = this.popStack(); } var inverse = this.popStack(), program = this.popStack(); // Avoid setting fn and inverse if neither are set. This allows // helpers to do a check for `if (options.fn)` if (program || inverse) { options.fn = program || 'container.noop'; options.inverse = inverse || 'container.noop'; } // The parameters go on to the stack in order (making sure that they are evaluated in order) // so we need to pop them off the stack in reverse order var i = paramSize; while (i--) { param = this.popStack(); params[i] = param; if (this.trackIds) { ids[i] = this.popStack(); } if (this.stringParams) { types[i] = this.popStack(); contexts[i] = this.popStack(); } } if (objectArgs) { options.args = this.source.generateArray(params); } if (this.trackIds) { options.ids = this.source.generateArray(ids); } if (this.stringParams) { options.types = this.source.generateArray(types); options.contexts = this.source.generateArray(contexts); } if (this.options.data) { options.data = 'data'; } if (this.useBlockParams) { options.blockParams = 'blockParams'; } return options; }, setupHelperArgs: function setupHelperArgs(helper, paramSize, params, useRegister) { var options = this.setupParams(helper, paramSize, params); options = this.objectLiteral(options); if (useRegister) { this.useRegister('options'); params.push('options'); return ['options=', options]; } else if (params) { params.push(options); return ''; } else { return options; } } }; (function () { var reservedWords = ('break else new var' + ' case finally return void' + ' catch for switch while' + ' continue function this with' + ' default if throw' + ' delete in try' + ' do instanceof typeof' + ' abstract enum int short' + ' boolean export interface static' + ' byte extends long super' + ' char final native synchronized' + ' class float package throws' + ' const goto private transient' + ' debugger implements protected volatile' + ' double import public let yield await' + ' null true false').split(' '); var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {}; for (var i = 0, l = reservedWords.length; i < l; i++) { compilerWords[reservedWords[i]] = true; } })(); JavaScriptCompiler.isValidJavaScriptVariableName = function (name) { return !JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name); }; function strictLookup(requireTerminal, compiler, parts, type) { var stack = compiler.popStack(), i = 0, len = parts.length; if (requireTerminal) { len--; } for (; i < len; i++) { stack = compiler.nameLookup(stack, parts[i], type); } if (requireTerminal) { return [compiler.aliasable('container.strict'), '(', stack, ', ', compiler.quotedString(parts[i]), ')']; } else { return stack; } } exports['default'] = JavaScriptCompiler; module.exports = exports['default']; /***/ }, /* 29 */ /***/ function(module, exports, __webpack_require__) { /* global define */ 'use strict'; exports.__esModule = true; var _utils = __webpack_require__(5); var SourceNode = undefined; try { /* istanbul ignore next */ if (false) { // We don't support this in AMD environments. For these environments, we asusme that // they are running on the browser and thus have no need for the source-map library. var SourceMap = require('source-map'); SourceNode = SourceMap.SourceNode; } } catch (err) {} /* NOP */ /* istanbul ignore if: tested but not covered in istanbul due to dist build */ if (!SourceNode) { SourceNode = function (line, column, srcFile, chunks) { this.src = ''; if (chunks) { this.add(chunks); } }; /* istanbul ignore next */ SourceNode.prototype = { add: function add(chunks) { if (_utils.isArray(chunks)) { chunks = chunks.join(''); } this.src += chunks; }, prepend: function prepend(chunks) { if (_utils.isArray(chunks)) { chunks = chunks.join(''); } this.src = chunks + this.src; }, toStringWithSourceMap: function toStringWithSourceMap() { return { code: this.toString() }; }, toString: function toString() { return this.src; } }; } function castChunk(chunk, codeGen, loc) { if (_utils.isArray(chunk)) { var ret = []; for (var i = 0, len = chunk.length; i < len; i++) { ret.push(codeGen.wrap(chunk[i], loc)); } return ret; } else if (typeof chunk === 'boolean' || typeof chunk === 'number') { // Handle primitives that the SourceNode will throw up on return chunk + ''; } return chunk; } function CodeGen(srcFile) { this.srcFile = srcFile; this.source = []; } CodeGen.prototype = { isEmpty: function isEmpty() { return !this.source.length; }, prepend: function prepend(source, loc) { this.source.unshift(this.wrap(source, loc)); }, push: function push(source, loc) { this.source.push(this.wrap(source, loc)); }, merge: function merge() { var source = this.empty(); this.each(function (line) { source.add([' ', line, '\n']); }); return source; }, each: function each(iter) { for (var i = 0, len = this.source.length; i < len; i++) { iter(this.source[i]); } }, empty: function empty() { var loc = this.currentLocation || { start: {} }; return new SourceNode(loc.start.line, loc.start.column, this.srcFile); }, wrap: function wrap(chunk) { var loc = arguments.length <= 1 || arguments[1] === undefined ? this.currentLocation || { start: {} } : arguments[1]; if (chunk instanceof SourceNode) { return chunk; } chunk = castChunk(chunk, this, loc); return new SourceNode(loc.start.line, loc.start.column, this.srcFile, chunk); }, functionCall: function functionCall(fn, type, params) { params = this.generateList(params); return this.wrap([fn, type ? '.' + type + '(' : '(', params, ')']); }, quotedString: function quotedString(str) { return '"' + (str + '').replace(/\\/g, '\\\\').replace(/"/g, '\\"').replace(/\n/g, '\\n').replace(/\r/g, '\\r').replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4 .replace(/\u2029/g, '\\u2029') + '"'; }, objectLiteral: function objectLiteral(obj) { var pairs = []; for (var key in obj) { if (obj.hasOwnProperty(key)) { var value = castChunk(obj[key], this); if (value !== 'undefined') { pairs.push([this.quotedString(key), ':', value]); } } } var ret = this.generateList(pairs); ret.prepend('{'); ret.add('}'); return ret; }, generateList: function generateList(entries) { var ret = this.empty(); for (var i = 0, len = entries.length; i < len; i++) { if (i) { ret.add(','); } ret.add(castChunk(entries[i], this)); } return ret; }, generateArray: function generateArray(entries) { var ret = this.generateList(entries); ret.prepend('['); ret.add(']'); return ret; } }; exports['default'] = CodeGen; module.exports = exports['default']; /***/ } /******/ ]) }); ; ================================================ FILE: example/web-test-speed/js/highcharts.js ================================================ /* Highcharts JS v5.0.10 (2017-03-31) (c) 2009-2016 Torstein Honsi License: www.highcharts.com/license */ (function(L,a){"object"===typeof module&&module.exports?module.exports=L.document?a(L):a:L.Highcharts=a(L)})("undefined"!==typeof window?window:this,function(L){L=function(){var a=window,B=a.document,A=a.navigator&&a.navigator.userAgent||"",H=B&&B.createElementNS&&!!B.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect,G=/(edge|msie|trident)/i.test(A)&&!window.opera,r=!H,f=/Firefox/.test(A),l=f&&4>parseInt(A.split("Firefox/")[1],10);return a.Highcharts?a.Highcharts.error(16,!0):{product:"Highcharts", version:"5.0.10",deg2rad:2*Math.PI/360,doc:B,hasBidiBug:l,hasTouch:B&&void 0!==B.documentElement.ontouchstart,isMS:G,isWebKit:/AppleWebKit/.test(A),isFirefox:f,isTouchDevice:/(Mobile|Android|Windows Phone)/.test(A),SVG_NS:"http://www.w3.org/2000/svg",chartCount:0,seriesTypes:{},symbolSizes:{},svg:H,vml:r,win:a,charts:[],marginNames:["plotTop","marginRight","marginBottom","plotLeft"],noop:function(){}}}();(function(a){var B=[],A=a.charts,H=a.doc,G=a.win;a.error=function(r,f){r=a.isNumber(r)?"Highcharts error #"+ r+": www.highcharts.com/errors/"+r:r;if(f)throw Error(r);G.console&&console.log(r)};a.Fx=function(a,f,l){this.options=f;this.elem=a;this.prop=l};a.Fx.prototype={dSetter:function(){var a=this.paths[0],f=this.paths[1],l=[],q=this.now,k=a.length,u;if(1===q)l=this.toD;else if(k===f.length&&1>q)for(;k--;)u=parseFloat(a[k]),l[k]=isNaN(u)?a[k]:q*parseFloat(f[k]-u)+u;else l=f;this.elem.attr("d",l,null,!0)},update:function(){var a=this.elem,f=this.prop,l=this.now,q=this.options.step;if(this[f+"Setter"])this[f+ "Setter"]();else a.attr?a.element&&a.attr(f,l,null,!0):a.style[f]=l+this.unit;q&&q.call(a,l,this)},run:function(a,f,l){var r=this,k=function(a){return k.stopped?!1:r.step(a)},u;this.startTime=+new Date;this.start=a;this.end=f;this.unit=l;this.now=this.start;this.pos=0;k.elem=this.elem;k.prop=this.prop;k()&&1===B.push(k)&&(k.timerId=setInterval(function(){for(u=0;u=u+this.startTime){this.now=this.end;this.pos=1;this.update();a=d[this.prop]=!0;for(c in d)!0!==d[c]&&(a=!1);a&&k&&k.call(r);r=!1}else this.pos=q.easing((f-this.startTime)/u),this.now=this.start+(this.end-this.start)*this.pos,this.update(),r=!0;return r},initPath:function(r,f,l){function q(a){var b,e;for(t=a.length;t--;)b="M"===a[t]||"L"===a[t],e=/[a-zA-Z]/.test(a[t+3]),b&&e&&a.splice(t+1,0,a[t+1],a[t+2],a[t+1],a[t+ 2])}function k(a,e){for(;a.lengthd?"AM":"PM",P:12>d?"am":"pm",S:D(k.getSeconds()),L:D(Math.round(f% 1E3),3)},a.dateFormats);for(u in q)for(;-1!==r.indexOf("%"+u);)r=r.replace("%"+u,"function"===typeof q[u]?q[u](f):q[u]);return l?r.substr(0,1).toUpperCase()+r.substr(1):r};a.formatSingle=function(r,f){var l=/\.([0-9])/,q=a.defaultOptions.lang;/f$/.test(r)?(l=(l=r.match(l))?l[1]:-1,null!==f&&(f=a.numberFormat(f,l,q.decimalPoint,-1=l&&(f=[1/l]))); for(q=0;q=r||!k&&u<=(f[q]+(f[q+1]||f[q]))/2);q++);return d=a.correctFloat(d*l,-Math.round(Math.log(.001)/Math.LN10))};a.stableSort=function(a,f){var l=a.length,q,k;for(k=0;kl&&(l=a[f]);return l};a.destroyObjectProperties= function(a,f){for(var l in a)a[l]&&a[l]!==f&&a[l].destroy&&a[l].destroy(),delete a[l]};a.discardElement=function(r){var f=a.garbageBin;f||(f=a.createElement("div"));r&&f.appendChild(r);f.innerHTML=""};a.correctFloat=function(a,f){return parseFloat(a.toPrecision(f||14))};a.setAnimation=function(r,f){f.renderer.globalAnimation=a.pick(r,f.options.chart.animation,!0)};a.animObject=function(r){return a.isObject(r)?a.merge(r):{duration:r?500:0}};a.timeUnits={millisecond:1,second:1E3,minute:6E4,hour:36E5, day:864E5,week:6048E5,month:24192E5,year:314496E5};a.numberFormat=function(r,f,l,q){r=+r||0;f=+f;var k=a.defaultOptions.lang,u=(r.toString().split(".")[1]||"").length,d,c;-1===f?f=Math.min(u,20):a.isNumber(f)||(f=2);c=(Math.abs(r)+Math.pow(10,-Math.max(f,u)-1)).toFixed(f);u=String(a.pInt(c));d=3r?"-":"")+(d?u.substr(0,d)+q:"");r+=u.substr(d).replace(/(\d{3})(?=\d)/g,"$1"+q);f&&(r+=l+c.slice(-f));return r};Math.easeInOutSine= function(a){return-.5*(Math.cos(Math.PI*a)-1)};a.getStyle=function(r,f){return"width"===f?Math.min(r.offsetWidth,r.scrollWidth)-a.getStyle(r,"padding-left")-a.getStyle(r,"padding-right"):"height"===f?Math.min(r.offsetHeight,r.scrollHeight)-a.getStyle(r,"padding-top")-a.getStyle(r,"padding-bottom"):(r=G.getComputedStyle(r,void 0))&&a.pInt(r.getPropertyValue(f))};a.inArray=function(a,f){return f.indexOf?f.indexOf(a):[].indexOf.call(f,a)};a.grep=function(a,f){return[].filter.call(a,f)};a.find=function(a, f){return[].find.call(a,f)};a.map=function(a,f){for(var l=[],q=0,k=a.length;q>16,(f&65280)>>8,f&255,1]:4===l&&(q=[(f&3840)>>4|(f&3840)>>8,(f&240)>>4|f&240,(f&15)<<4|f&15,1])),!q)for(k=this.parsers.length;k--&&!q;)u=this.parsers[k],(l=u.regex.exec(f))&&(q=u.parse(l)); this.rgba=q||[]},get:function(a){var f=this.input,q=this.rgba,k;this.stops?(k=G(f),k.stops=[].concat(k.stops),B(this.stops,function(u,d){k.stops[d]=[k.stops[d][0],u.get(a)]})):k=q&&A(q[0])?"rgb"===a||!a&&1===q[3]?"rgb("+q[0]+","+q[1]+","+q[2]+")":"a"===a?q[3]:"rgba("+q.join(",")+")":f;return k},brighten:function(a){var f,q=this.rgba;if(this.stops)B(this.stops,function(k){k.brighten(a)});else if(A(a)&&0!==a)for(f=0;3>f;f++)q[f]+=r(255*a),0>q[f]&&(q[f]=0),255v.width)v={width:0,height:0}}else v=this.htmlGetBBox();e.isSVG&&(a=v.width,e=v.height,m&&"11px"===m.fontSize&&17===Math.round(e)&&(v.height=e=14), g&&(v.width=Math.abs(e*Math.sin(c))+Math.abs(a*Math.cos(c)),v.height=Math.abs(e*Math.cos(c))+Math.abs(a*Math.sin(c))));if(t&&0]*>/g,"")))},textSetter:function(a){a!==this.textStr&&(delete this.bBox,this.textStr=a,this.added&&this.renderer.buildText(this))},fillSetter:function(a,g,e){"string"===typeof a?e.setAttribute(g, a):a&&this.colorGradient(a,g,e)},visibilitySetter:function(a,g,e){"inherit"===a?e.removeAttribute(g):e.setAttribute(g,a)},zIndexSetter:function(a,g){var v=this.renderer,e=this.parentGroup,b=(e||v).element||v.box,c,h=this.element,m;c=this.added;var F;u(a)&&(h.zIndex=a,a=+a,this[g]===a&&(c=!1),this[g]=a);if(c){(a=this.zIndex)&&e&&(e.handleZ=!0);g=b.childNodes;for(F=0;Fa||!u(a)&&u(c)||0>a&&!u(c)&&b!==v.box)&&(b.insertBefore(h,e),m=!0);m||b.appendChild(h)}return m}, _defaultSetter:function(a,g,e){e.setAttribute(g,a)}};B.prototype.yGetter=B.prototype.xGetter;B.prototype.translateXSetter=B.prototype.translateYSetter=B.prototype.rotationSetter=B.prototype.verticalAlignSetter=B.prototype.scaleXSetter=B.prototype.scaleYSetter=function(a,g){this[g]=a;this.doTransform=!0};B.prototype["stroke-widthSetter"]=B.prototype.strokeSetter=function(a,g,e){this[g]=a;this.stroke&&this["stroke-width"]?(B.prototype.fillSetter.call(this,this.stroke,"stroke",e),e.setAttribute("stroke-width", this["stroke-width"]),this.hasStroke=!0):"stroke-width"===g&&0===a&&this.hasStroke&&(e.removeAttribute("stroke"),this.hasStroke=!1)};A=a.SVGRenderer=function(){this.init.apply(this,arguments)};A.prototype={Element:B,SVG_NS:N,init:function(a,g,b,c,h,F){var v;c=this.createElement("svg").attr({version:"1.1","class":"highcharts-root"}).css(this.getStyle(c));v=c.element;a.appendChild(v);-1===a.innerHTML.indexOf("xmlns")&&r(v,"xmlns",this.SVG_NS);this.isSVG=!0;this.box=v;this.boxWrapper=c;this.alignedObjects= [];this.url=(e||m)&&n.getElementsByTagName("base").length?O.location.href.replace(/#.*?$/,"").replace(/<[^>]*>/g,"").replace(/([\('\)])/g,"\\$1").replace(/ /g,"%20"):"";this.createElement("desc").add().element.appendChild(n.createTextNode("Created with Highcharts 5.0.10"));this.defs=this.createElement("defs").add();this.allowHTML=F;this.forExport=h;this.gradients={};this.cache={};this.cacheKeys=[];this.imgCount=0;this.setSize(g,b,!1);var x;e&&a.getBoundingClientRect&&(g=function(){q(a,{left:0,top:0}); x=a.getBoundingClientRect();q(a,{left:Math.ceil(x.left)-x.left+"px",top:Math.ceil(x.top)-x.top+"px"})},g(),this.unSubPixelFix=H(O,"resize",g))},getStyle:function(a){return this.style=b({fontFamily:'"Lucida Grande", "Lucida Sans Unicode", Arial, Helvetica, sans-serif',fontSize:"12px"},a)},setStyle:function(a){this.boxWrapper.css(this.getStyle(a))},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var a=this.defs;this.box=null;this.boxWrapper=this.boxWrapper.destroy();c(this.gradients|| {});this.gradients=null;a&&(this.defs=a.destroy());this.unSubPixelFix&&this.unSubPixelFix();return this.alignedObjects=null},createElement:function(a){var g=new this.Element;g.init(this,a);return g},draw:I,getRadialAttr:function(a,g){return{cx:a[0]-a[2]/2+g.cx*a[2],cy:a[1]-a[2]/2+g.cy*a[2],r:g.r*a[2]}},getSpanWidth:function(a,g){var v=a.getBBox(!0).width;!Q&&this.forExport&&(v=this.measureSpanWidth(g.firstChild.data,a.styles));return v},applyEllipsis:function(a,g,e,b){var v=this.getSpanWidth(a,g), c=v>b,v=e,h,m=0,F=e.length,x=function(a){g.removeChild(g.firstChild);a&&g.appendChild(n.createTextNode(a))};if(c){for(;m<=F;)h=Math.ceil((m+F)/2),v=e.substring(0,h)+"\u2026",x(v),v=this.getSpanWidth(a,g),m===F?m=F+1:v>b?F=h-1:m=h;0===F&&x("")}return c},buildText:function(a){var g=a.element,e=this,v=e.forExport,b=K(a.textStr,"").toString(),c=-1!==b.indexOf("\x3c"),m=g.childNodes,F,x,y,t,d=r(g,"x"),C=a.styles,p=a.textWidth,k=C&&C.lineHeight,w=C&&C.textOutline,u=C&&"ellipsis"===C.textOverflow,f=C&&"nowrap"=== C.whiteSpace,E=C&&C.fontSize,D,I,l=m.length,C=p&&!a.added&&this.box,P=function(a){var v;v=/(px|em)$/.test(a&&a.style.fontSize)?a.style.fontSize:E||e.style.fontSize||12;return k?J(k):e.fontMetrics(v,a.getAttribute("style")?a:g).h};D=[b,u,f,k,w,E,p].join();if(D!==a.textCache){for(a.textCache=D;l--;)g.removeChild(m[l]);c||w||u||p||-1!==b.indexOf(" ")?(F=/<.*class="([^"]+)".*>/,x=/<.*style="([^"]+)".*>/,y=/<.*href="(http[^"]+)".*>/,C&&C.appendChild(g),b=c?b.replace(/<(b|strong)>/g,'\x3cspan style\x3d"font-weight:bold"\x3e').replace(/<(i|em)>/g, '\x3cspan style\x3d"font-style:italic"\x3e').replace(//g,"\x3c/span\x3e").split(//g):[b],b=h(b,function(a){return""!==a}),z(b,function(b,c){var m,h=0;b=b.replace(/^\s+|\s+$/g,"").replace(//g,"\x3c/span\x3e|||");m=b.split("|||");z(m,function(b){if(""!==b||1===m.length){var C={},k=n.createElementNS(e.SVG_NS,"tspan"),w,E;F.test(b)&&(w=b.match(F)[1],r(k,"class",w));x.test(b)&&(E=b.match(x)[1].replace(/(;| |^)color([ :])/, "$1fill$2"),r(k,"style",E));y.test(b)&&!v&&(r(k,"onclick",'location.href\x3d"'+b.match(y)[1]+'"'),q(k,{cursor:"pointer"}));b=(b.replace(/<(.|\n)*?>/g,"")||" ").replace(/</g,"\x3c").replace(/>/g,"\x3e");if(" "!==b){k.appendChild(n.createTextNode(b));h?C.dx=0:c&&null!==d&&(C.x=d);r(k,C);g.appendChild(k);!h&&I&&(!Q&&v&&q(k,{display:"block"}),r(k,"dy",P(k)));if(p){C=b.replace(/([^\^])-/g,"$1- ").split(" ");w=1p,void 0===t&&(t=b),b&&1!==C.length?(k.removeChild(k.firstChild),D.unshift(C.pop())):(C=D,D=[],C.length&&!f&&(k=n.createElementNS(N,"tspan"),r(k,{dy:z,x:d}),E&&r(k,"style",E),g.appendChild(k)),M>p&&(p=M)),C.length&&k.appendChild(n.createTextNode(C.join(" ").replace(/- /g,"-")));a.rotation=l}h++}}});I=I||g.childNodes.length}),t&&a.attr("title",a.textStr),C&&C.removeChild(g),w&&a.applyTextOutline&&a.applyTextOutline(w)):g.appendChild(n.createTextNode(b.replace(/</g, "\x3c").replace(/>/g,"\x3e")))}},getContrast:function(a){a=l(a).rgba;return 510e?c>g+h&&cv?c>g+h&&cb&&v>a+h&&vc&&v>a+h&&va?a+3:Math.round(1.2*a);return{h:g,b:Math.round(.8*g),f:a}},rotCorr:function(a,g,e){var b=a;g&&e&&(b=Math.max(b*Math.cos(g*d),4));return{x:-a/3*Math.sin(g*d),y:b}},label:function(e,c,m,h,F,x,C,d,t){var v=this,p=v.g("button"!==t&&"label"),n=p.text=v.text("",0,0,C).attr({zIndex:1}),k,w,E=0,f=3, D=0,I,q,l,Q,N,K={},J,r,M=/^url\((.*?)\)$/.test(h),P=M,R,S,O,U;t&&p.addClass("highcharts-"+t);P=M;R=function(){return(J||0)%2/2};S=function(){var a=n.element.style,g={};w=(void 0===I||void 0===q||N)&&u(n.textStr)&&n.getBBox();p.width=(I||w.width||0)+2*f+D;p.height=(q||w.height||0)+2*f;r=f+v.fontMetrics(a&&a.fontSize,n).b;P&&(k||(p.box=k=v.symbols[h]||M?v.symbol(h):v.rect(),k.addClass(("button"===t?"":"highcharts-label-box")+(t?" highcharts-"+t+"-box":"")),k.add(p),a=R(),g.x=a,g.y=(d?-r:0)+a),g.width= Math.round(p.width),g.height=Math.round(p.height),k.attr(b(g,K)),K={})};O=function(){var a=D+f,g;g=d?0:r;u(I)&&w&&("center"===N||"right"===N)&&(a+={center:.5,right:1}[N]*(I-w.width));if(a!==n.x||g!==n.y)n.attr("x",a),void 0!==g&&n.attr("y",g);n.x=a;n.y=g};U=function(a,g){k?k.attr(a,g):K[a]=g};p.onAdd=function(){n.add(p);p.attr({text:e||0===e?e:"",x:c,y:m});k&&u(F)&&p.attr({anchorX:F,anchorY:x})};p.widthSetter=function(g){I=a.isNumber(g)?g:null};p.heightSetter=function(a){q=a};p["text-alignSetter"]= function(a){N=a};p.paddingSetter=function(a){u(a)&&a!==f&&(f=p.padding=a,O())};p.paddingLeftSetter=function(a){u(a)&&a!==D&&(D=a,O())};p.alignSetter=function(a){a={left:0,center:.5,right:1}[a];a!==E&&(E=a,w&&p.attr({x:l}))};p.textSetter=function(a){void 0!==a&&n.textSetter(a);S();O()};p["stroke-widthSetter"]=function(a,g){a&&(P=!0);J=this["stroke-width"]=a;U(g,a)};p.strokeSetter=p.fillSetter=p.rSetter=function(a,g){"fill"===g&&a&&(P=!0);U(g,a)};p.anchorXSetter=function(a,g){F=a;U(g,Math.round(a)- R()-l)};p.anchorYSetter=function(a,g){x=a;U(g,a-Q)};p.xSetter=function(a){p.x=a;E&&(a-=E*((I||w.width)+2*f));l=Math.round(a);p.attr("translateX",l)};p.ySetter=function(a){Q=p.y=Math.round(a);p.attr("translateY",Q)};var W=p.css;return b(p,{css:function(a){if(a){var g={};a=y(a);z(p.textProps,function(e){void 0!==a[e]&&(g[e]=a[e],delete a[e])});n.css(g)}return W.call(p,a)},getBBox:function(){return{width:w.width+2*f,height:w.height+2*f,x:w.x-f,y:w.y-f}},shadow:function(a){a&&(S(),k&&k.shadow(a));return p}, destroy:function(){g(p.element,"mouseenter");g(p.element,"mouseleave");n&&(n=n.destroy());k&&(k=k.destroy());B.prototype.destroy.call(p);p=v=S=O=U=null}})}};a.Renderer=A})(L);(function(a){var B=a.attr,A=a.createElement,H=a.css,G=a.defined,r=a.each,f=a.extend,l=a.isFirefox,q=a.isMS,k=a.isWebKit,u=a.pInt,d=a.SVGRenderer,c=a.win,n=a.wrap;f(a.SVGElement.prototype,{htmlCss:function(a){var b=this.element;if(b=a&&"SPAN"===b.tagName&&a.width)delete a.width,this.textWidth=b,this.updateTransform();a&&"ellipsis"=== a.textOverflow&&(a.whiteSpace="nowrap",a.overflow="hidden");this.styles=f(this.styles,a);H(this.element,a);return this},htmlGetBBox:function(){var a=this.element;"text"===a.nodeName&&(a.style.position="absolute");return{x:a.offsetLeft,y:a.offsetTop,width:a.offsetWidth,height:a.offsetHeight}},htmlUpdateTransform:function(){if(this.added){var a=this.renderer,b=this.element,c=this.translateX||0,h=this.translateY||0,d=this.x||0,n=this.y||0,w=this.textAlign||"left",e={left:0,center:.5,right:1}[w],x=this.styles; H(b,{marginLeft:c,marginTop:h});this.shadows&&r(this.shadows,function(a){H(a,{marginLeft:c+1,marginTop:h+1})});this.inverted&&r(b.childNodes,function(e){a.invertChild(e,b)});if("SPAN"===b.tagName){var C=this.rotation,f=u(this.textWidth),m=x&&x.whiteSpace,y=[C,w,b.innerHTML,this.textWidth,this.textAlign].join();y!==this.cTT&&(x=a.fontMetrics(b.style.fontSize).b,G(C)&&this.setSpanRotation(C,e,x),H(b,{width:"",whiteSpace:m||"nowrap"}),b.offsetWidth>f&&/[ \-]/.test(b.textContent||b.innerText)&&H(b,{width:f+ "px",display:"block",whiteSpace:m||"normal"}),this.getSpanCorrection(b.offsetWidth,x,e,C,w));H(b,{left:d+(this.xCorr||0)+"px",top:n+(this.yCorr||0)+"px"});k&&(x=b.offsetHeight);this.cTT=y}}else this.alignOnAdd=!0},setSpanRotation:function(a,b,p){var h={},d=q?"-ms-transform":k?"-webkit-transform":l?"MozTransform":c.opera?"-o-transform":"";h[d]=h.transform="rotate("+a+"deg)";h[d+(l?"Origin":"-origin")]=h.transformOrigin=100*b+"% "+p+"px";H(this.element,h)},getSpanCorrection:function(a,b,c){this.xCorr= -a*c;this.yCorr=-b}});f(d.prototype,{html:function(a,b,c){var h=this.createElement("span"),d=h.element,p=h.renderer,k=p.isSVG,e=function(a,e){r(["opacity","visibility"],function(b){n(a,b+"Setter",function(a,b,c,h){a.call(this,b,c,h);e[c]=b})})};h.textSetter=function(a){a!==d.innerHTML&&delete this.bBox;d.innerHTML=this.textStr=a;h.htmlUpdateTransform()};k&&e(h,h.element.style);h.xSetter=h.ySetter=h.alignSetter=h.rotationSetter=function(a,e){"align"===e&&(e="textAlign");h[e]=a;h.htmlUpdateTransform()}; h.attr({text:a,x:Math.round(b),y:Math.round(c)}).css({fontFamily:this.style.fontFamily,fontSize:this.style.fontSize,position:"absolute"});d.style.whiteSpace="nowrap";h.css=h.htmlCss;k&&(h.add=function(a){var b,c=p.box.parentNode,m=[];if(this.parentGroup=a){if(b=a.div,!b){for(;a;)m.push(a),a=a.parentGroup;r(m.reverse(),function(a){var x,d=B(a.element,"class");d&&(d={className:d});b=a.div=a.div||A("div",d,{position:"absolute",left:(a.translateX||0)+"px",top:(a.translateY||0)+"px",display:a.display, opacity:a.opacity,pointerEvents:a.styles&&a.styles.pointerEvents},b||c);x=b.style;f(a,{on:function(){h.on.apply({element:m[0].div},arguments);return a},translateXSetter:function(e,g){x.left=e+"px";a[g]=e;a.doTransform=!0},translateYSetter:function(e,g){x.top=e+"px";a[g]=e;a.doTransform=!0}});e(a,x)})}}else b=c;b.appendChild(d);h.added=!0;h.alignOnAdd&&h.htmlUpdateTransform();return h});return h}})})(L);(function(a){var B,A,H=a.createElement,G=a.css,r=a.defined,f=a.deg2rad,l=a.discardElement,q=a.doc, k=a.each,u=a.erase,d=a.extend;B=a.extendClass;var c=a.isArray,n=a.isNumber,z=a.isObject,b=a.merge;A=a.noop;var p=a.pick,h=a.pInt,t=a.SVGElement,D=a.SVGRenderer,w=a.win;a.svg||(A={docMode8:q&&8===q.documentMode,init:function(a,b){var e=["\x3c",b,' filled\x3d"f" stroked\x3d"f"'],c=["position: ","absolute",";"],m="div"===b;("shape"===b||m)&&c.push("left:0;top:0;width:1px;height:1px;");c.push("visibility: ",m?"hidden":"visible");e.push(' style\x3d"',c.join(""),'"/\x3e');b&&(e=m||"span"===b||"img"===b? e.join(""):a.prepVML(e),this.element=H(e));this.renderer=a},add:function(a){var e=this.renderer,b=this.element,c=e.box,m=a&&a.inverted,c=a?a.element||a:c;a&&(this.parentGroup=a);m&&e.invertChild(b,c);c.appendChild(b);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();if(this.onAdd)this.onAdd();this.className&&this.attr("class",this.className);return this},updateTransform:t.prototype.htmlUpdateTransform,setSpanRotation:function(){var a=this.rotation,b=Math.cos(a*f),c= Math.sin(a*f);G(this.element,{filter:a?["progid:DXImageTransform.Microsoft.Matrix(M11\x3d",b,", M12\x3d",-c,", M21\x3d",c,", M22\x3d",b,", sizingMethod\x3d'auto expand')"].join(""):"none"})},getSpanCorrection:function(a,b,c,h,m){var e=h?Math.cos(h*f):1,x=h?Math.sin(h*f):0,d=p(this.elemHeight,this.element.offsetHeight),t;this.xCorr=0>e&&-a;this.yCorr=0>x&&-d;t=0>e*x;this.xCorr+=x*b*(t?1-c:c);this.yCorr-=e*b*(h?t?c:1-c:1);m&&"left"!==m&&(this.xCorr-=a*c*(0>e?-1:1),h&&(this.yCorr-=d*c*(0>x?-1:1)),G(this.element, {textAlign:m}))},pathToVML:function(a){for(var e=a.length,b=[];e--;)n(a[e])?b[e]=Math.round(10*a[e])-5:"Z"===a[e]?b[e]="x":(b[e]=a[e],!a.isArc||"wa"!==a[e]&&"at"!==a[e]||(b[e+5]===b[e+7]&&(b[e+7]+=a[e+7]>a[e+5]?1:-1),b[e+6]===b[e+8]&&(b[e+8]+=a[e+8]>a[e+6]?1:-1)));return b.join(" ")||"x"},clip:function(a){var e=this,b;a?(b=a.members,u(b,e),b.push(e),e.destroyClip=function(){u(b,e)},a=a.getCSS(e)):(e.destroyClip&&e.destroyClip(),a={clip:e.docMode8?"inherit":"rect(auto)"});return e.css(a)},css:t.prototype.htmlCss, safeRemoveChild:function(a){a.parentNode&&l(a)},destroy:function(){this.destroyClip&&this.destroyClip();return t.prototype.destroy.apply(this)},on:function(a,b){this.element["on"+a]=function(){var a=w.event;a.target=a.srcElement;b(a)};return this},cutOffPath:function(a,b){var e;a=a.split(/[ ,]/);e=a.length;if(9===e||11===e)a[e-4]=a[e-2]=h(a[e-2])-10*b;return a.join(" ")},shadow:function(a,b,c){var e=[],m,d=this.element,t=this.renderer,x,n=d.style,g,F=d.path,k,C,w,f;F&&"string"!==typeof F.value&&(F= "x");C=F;if(a){w=p(a.width,3);f=(a.opacity||.15)/w;for(m=1;3>=m;m++)k=2*w+1-2*m,c&&(C=this.cutOffPath(F.value,k+.5)),g=['\x3cshape isShadow\x3d"true" strokeweight\x3d"',k,'" filled\x3d"false" path\x3d"',C,'" coordsize\x3d"10 10" style\x3d"',d.style.cssText,'" /\x3e'],x=H(t.prepVML(g),null,{left:h(n.left)+p(a.offsetX,1),top:h(n.top)+p(a.offsetY,1)}),c&&(x.cutOff=k+1),g=['\x3cstroke color\x3d"',a.color||"#000000",'" opacity\x3d"',f*m,'"/\x3e'],H(t.prepVML(g),null,null,x),b?b.element.appendChild(x): d.parentNode.insertBefore(x,d),e.push(x);this.shadows=e}return this},updateShadows:A,setAttr:function(a,b){this.docMode8?this.element[a]=b:this.element.setAttribute(a,b)},classSetter:function(a){(this.added?this.element:this).className=a},dashstyleSetter:function(a,b,c){(c.getElementsByTagName("stroke")[0]||H(this.renderer.prepVML(["\x3cstroke/\x3e"]),null,null,c))[b]=a||"solid";this[b]=a},dSetter:function(a,b,c){var e=this.shadows;a=a||[];this.d=a.join&&a.join(" ");c.path=a=this.pathToVML(a);if(e)for(c= e.length;c--;)e[c].path=e[c].cutOff?this.cutOffPath(a,e[c].cutOff):a;this.setAttr(b,a)},fillSetter:function(a,b,c){var e=c.nodeName;"SPAN"===e?c.style.color=a:"IMG"!==e&&(c.filled="none"!==a,this.setAttr("fillcolor",this.renderer.color(a,c,b,this)))},"fill-opacitySetter":function(a,b,c){H(this.renderer.prepVML(["\x3c",b.split("-")[0],' opacity\x3d"',a,'"/\x3e']),null,null,c)},opacitySetter:A,rotationSetter:function(a,b,c){c=c.style;this[b]=c[b]=a;c.left=-Math.round(Math.sin(a*f)+1)+"px";c.top=Math.round(Math.cos(a* f))+"px"},strokeSetter:function(a,b,c){this.setAttr("strokecolor",this.renderer.color(a,c,b,this))},"stroke-widthSetter":function(a,b,c){c.stroked=!!a;this[b]=a;n(a)&&(a+="px");this.setAttr("strokeweight",a)},titleSetter:function(a,b){this.setAttr(b,a)},visibilitySetter:function(a,b,c){"inherit"===a&&(a="visible");this.shadows&&k(this.shadows,function(e){e.style[b]=a});"DIV"===c.nodeName&&(a="hidden"===a?"-999em":0,this.docMode8||(c.style[b]=a?"visible":"hidden"),b="top");c.style[b]=a},xSetter:function(a, b,c){this[b]=a;"x"===b?b="left":"y"===b&&(b="top");this.updateClipping?(this[b]=a,this.updateClipping()):c.style[b]=a},zIndexSetter:function(a,b,c){c.style[b]=a}},A["stroke-opacitySetter"]=A["fill-opacitySetter"],a.VMLElement=A=B(t,A),A.prototype.ySetter=A.prototype.widthSetter=A.prototype.heightSetter=A.prototype.xSetter,A={Element:A,isIE8:-1z[0]&&b.push([1,z[1]]);k(b,function(g,b){t.test(g[1])?(p=a.color(g[1]),F=p.get("rgb"),w=p.get("a")):(F=g[1],w=1);E.push(100*g[0]+"% "+F);b?(v=w,D=F):(u=w,q=F)});if("fill"===h)if("gradient"===x)h=f.x1||f[0]||0,b=f.y1||f[1]||0,C=f.x2||f[2]||0,f=f.y2||f[3]||0,l='angle\x3d"'+(90-180*Math.atan((f-b)/(C-h))/Math.PI)+'"',r();else{var g=f.r,A=2*g,B=2*g,G=f.cx,V=f.cy,L=c.radialReference,T,g=function(){L&&(T=d.getBBox(),G+=(L[0]- T.x)/T.width-.5,V+=(L[1]-T.y)/T.height-.5,A*=L[2]/T.width,B*=L[2]/T.height);l='src\x3d"'+a.getOptions().global.VMLRadialGradientURL+'" size\x3d"'+A+","+B+'" origin\x3d"0.5,0.5" position\x3d"'+G+","+V+'" color2\x3d"'+q+'" ';r()};d.added?g():d.onAdd=g;g=D}else g=F}else t.test(b)&&"IMG"!==c.tagName?(p=a.color(b),d[h+"-opacitySetter"](p.get("a"),h,c),g=p.get("rgb")):(g=c.getElementsByTagName(h),g.length&&(g[0].opacity=1,g[0].type="solid"),g=b);return g},prepVML:function(a){var b=this.isIE8;a=a.join(""); b?(a=a.replace("/\x3e",' xmlns\x3d"urn:schemas-microsoft-com:vml" /\x3e'),a=-1===a.indexOf('style\x3d"')?a.replace("/\x3e",' style\x3d"display:inline-block;behavior:url(#default#VML);" /\x3e'):a.replace('style\x3d"','style\x3d"display:inline-block;behavior:url(#default#VML);')):a=a.replace("\x3c","\x3chcv:");return a},text:D.prototype.html,path:function(a){var b={coordsize:"10 10"};c(a)?b.d=a:z(a)&&d(b,a);return this.createElement("shape").attr(b)},circle:function(a,b,c){var e=this.symbol("circle"); z(a)&&(c=a.r,b=a.y,a=a.x);e.isCircle=!0;e.r=c;return e.attr({x:a,y:b})},g:function(a){var b;a&&(b={className:"highcharts-"+a,"class":"highcharts-"+a});return this.createElement("div").attr(b)},image:function(a,b,c,h,m){var e=this.createElement("img").attr({src:a});1this.max&&f>this.max;c&&d?(a&&(c.flat=c.toString()===d.toString(),k=0),c.push(n&&d[4]===c[4]?d[4]+k:d[4],n||d[5]!==c[5]?d[5]:d[5]+k,n&&d[1]===c[1]?d[1]+k:d[1],n||d[2]!==c[2]?d[2]:d[2]+k)):c=null;return c},addPlotBand:function(a){return this.addPlotBandOrLine(a,"plotBands")},addPlotLine:function(a){return this.addPlotBandOrLine(a,"plotLines")},addPlotBandOrLine:function(f,q){var d=(new a.PlotLineOrBand(this,f)).render(),c=this.userOptions;d&&(q&&(c[q]=c[q]||[],c[q].push(f)), this.plotLinesAndBands.push(d));return d},removePlotBandOrLine:function(a){for(var k=this.plotLinesAndBands,d=this.options,c=this.userOptions,n=k.length;n--;)k[n].id===a&&k[n].destroy();r([d.plotLines||[],c.plotLines||[],d.plotBands||[],c.plotBands||[]],function(c){for(n=c.length;n--;)c[n].id===a&&f(c,c[n])})}}})(L);(function(a){var B=a.correctFloat,A=a.defined,H=a.destroyObjectProperties,G=a.isNumber,r=a.merge,f=a.pick,l=a.deg2rad;a.Tick=function(a,f,l,d){this.axis=a;this.pos=f;this.type=l||"";this.isNew= !0;l||d||this.addLabel()};a.Tick.prototype={addLabel:function(){var a=this.axis,k=a.options,l=a.chart,d=a.categories,c=a.names,n=this.pos,z=k.labels,b=a.tickPositions,p=n===b[0],h=n===b[b.length-1],c=d?f(d[n],c[n],n):n,d=this.label,b=b.info,t;a.isDatetimeAxis&&b&&(t=k.dateTimeLabelFormats[b.higherRanks[n]||b.unitName]);this.isFirst=p;this.isLast=h;k=a.labelFormatter.call({axis:a,chart:l,isFirst:p,isLast:h,dateTimeLabelFormat:t,value:a.isLog?B(a.lin2log(c)):c});A(d)?d&&d.attr({text:k}):(this.labelLength= (this.label=d=A(k)&&z.enabled?l.renderer.text(k,0,0,z.useHTML).css(r(z.style)).add(a.labelGroup):null)&&d.getBBox().width,this.rotation=0)},getLabelSize:function(){return this.label?this.label.getBBox()[this.axis.horiz?"height":"width"]:0},handleOverflow:function(a){var k=this.axis,q=a.x,d=k.chart.chartWidth,c=k.chart.spacing,n=f(k.labelLeft,Math.min(k.pos,c[3])),c=f(k.labelRight,Math.max(k.pos+k.len,d-c[1])),z=this.label,b=this.rotation,p={left:0,center:.5,right:1}[k.labelAlign],h=z.getBBox().width, t=k.getSlotWidth(),D=t,w=1,e,x={};if(b)0>b&&q-p*hc&&(e=Math.round((d-q)/Math.cos(b*l)));else if(d=q+(1-p)*h,q-p*hc&&(D=c-a.x+D*p,w=-1),D=Math.min(t,D),DD||k.autoRotation&&(z.styles||{}).width)e=D;e&&(x.width=e,(k.options.labels.style||{}).textOverflow||(x.textOverflow="ellipsis"),z.css(x))},getPosition:function(a,f,l,d){var c=this.axis,n=c.chart,k=d&&n.oldChartHeight|| n.chartHeight;return{x:a?c.translate(f+l,null,null,d)+c.transB:c.left+c.offset+(c.opposite?(d&&n.oldChartWidth||n.chartWidth)-c.right-c.left:0),y:a?k-c.bottom+c.offset-(c.opposite?c.height:0):k-c.translate(f+l,null,null,d)-c.transB}},getLabelPosition:function(a,f,u,d,c,n,z,b){var p=this.axis,h=p.transA,t=p.reversed,k=p.staggerLines,w=p.tickRotCorr||{x:0,y:0},e=c.y;A(e)||(e=0===p.side?u.rotation?-8:-u.getBBox().height:2===p.side?w.y+8:Math.cos(u.rotation*l)*(w.y-u.getBBox(!1,0).height/2));a=a+c.x+ w.x-(n&&d?n*h*(t?-1:1):0);f=f+e-(n&&!d?n*h*(t?1:-1):0);k&&(u=z/(b||1)%k,p.opposite&&(u=k-u-1),f+=p.labelOffset/k*u);return{x:a,y:Math.round(f)}},getMarkPath:function(a,f,l,d,c,n){return n.crispLine(["M",a,f,"L",a+(c?0:-l),f+(c?l:0)],d)},renderGridLine:function(a,f,l){var d=this.axis,c=d.options,n=this.gridLine,k={},b=this.pos,p=this.type,h=d.tickmarkOffset,t=d.chart.renderer,D=p?p+"Grid":"grid",w=c[D+"LineWidth"],e=c[D+"LineColor"],c=c[D+"LineDashStyle"];n||(k.stroke=e,k["stroke-width"]=w,c&&(k.dashstyle= c),p||(k.zIndex=1),a&&(k.opacity=0),this.gridLine=n=t.path().attr(k).addClass("highcharts-"+(p?p+"-":"")+"grid-line").add(d.gridGroup));if(!a&&n&&(a=d.getPlotLinePath(b+h,n.strokeWidth()*l,a,!0)))n[this.isNew?"attr":"animate"]({d:a,opacity:f})},renderMark:function(a,k,l){var d=this.axis,c=d.options,n=d.chart.renderer,q=this.type,b=q?q+"Tick":"tick",p=d.tickSize(b),h=this.mark,t=!h,D=a.x;a=a.y;var w=f(c[b+"Width"],!q&&d.isXAxis?1:0),c=c[b+"Color"];p&&(d.opposite&&(p[0]=-p[0]),t&&(this.mark=h=n.path().addClass("highcharts-"+ (q?q+"-":"")+"tick").add(d.axisGroup),h.attr({stroke:c,"stroke-width":w})),h[t?"attr":"animate"]({d:this.getMarkPath(D,a,p[0],h.strokeWidth()*l,d.horiz,n),opacity:k}))},renderLabel:function(a,k,l,d){var c=this.axis,n=c.horiz,q=c.options,b=this.label,p=q.labels,h=p.step,t=c.tickmarkOffset,D=!0,w=a.x;a=a.y;b&&G(w)&&(b.xy=a=this.getLabelPosition(w,a,b,n,p,t,d,h),this.isFirst&&!this.isLast&&!f(q.showFirstLabel,1)||this.isLast&&!this.isFirst&&!f(q.showLastLabel,1)?D=!1:!n||c.isRadial||p.step||p.rotation|| k||0===l||this.handleOverflow(a),h&&d%h&&(D=!1),D&&G(a.y)?(a.opacity=l,b[this.isNew?"attr":"animate"](a)):b.attr("y",-9999),this.isNew=!1)},render:function(a,k,l){var d=this.axis,c=d.horiz,n=this.getPosition(c,this.pos,d.tickmarkOffset,k),q=n.x,b=n.y,d=c&&q===d.pos+d.len||!c&&b===d.pos?-1:1;l=f(l,1);this.isActive=!0;this.renderGridLine(k,l,d);this.renderMark(n,l,d);this.renderLabel(n,k,l,a)},destroy:function(){H(this,this.axis)}}})(L);(function(a){var B=a.addEvent,A=a.animObject,H=a.arrayMax,G=a.arrayMin, r=a.AxisPlotLineOrBandExtension,f=a.color,l=a.correctFloat,q=a.defaultOptions,k=a.defined,u=a.deg2rad,d=a.destroyObjectProperties,c=a.each,n=a.extend,z=a.fireEvent,b=a.format,p=a.getMagnitude,h=a.grep,t=a.inArray,D=a.isArray,w=a.isNumber,e=a.isString,x=a.merge,C=a.normalizeTickInterval,E=a.pick,m=a.PlotLineOrBand,y=a.removeEvent,I=a.splat,K=a.syncTimeout,J=a.Tick;a.Axis=function(){this.init.apply(this,arguments)};a.Axis.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:"%H:%M:%S.%L",second:"%H:%M:%S", minute:"%H:%M",hour:"%H:%M",day:"%e. %b",week:"%e. %b",month:"%b '%y",year:"%Y"},endOnTick:!1,labels:{enabled:!0,style:{color:"#666666",cursor:"default",fontSize:"11px"},x:0},minPadding:.01,maxPadding:.01,minorTickLength:2,minorTickPosition:"outside",startOfWeek:1,startOnTick:!1,tickLength:10,tickmarkPlacement:"between",tickPixelInterval:100,tickPosition:"outside",title:{align:"middle",style:{color:"#666666"}},type:"linear",minorGridLineColor:"#f2f2f2",minorGridLineWidth:1,minorTickColor:"#999999", lineColor:"#ccd6eb",lineWidth:1,gridLineColor:"#e6e6e6",tickColor:"#ccd6eb"},defaultYAxisOptions:{endOnTick:!0,tickPixelInterval:72,showLastLabel:!0,labels:{x:-8},maxPadding:.05,minPadding:.05,startOnTick:!0,title:{rotation:270,text:"Values"},stackLabels:{enabled:!1,formatter:function(){return a.numberFormat(this.total,-1)},style:{fontSize:"11px",fontWeight:"bold",color:"#000000",textOutline:"1px contrast"}},gridLineWidth:1,lineWidth:0},defaultLeftAxisOptions:{labels:{x:-15},title:{rotation:270}}, defaultRightAxisOptions:{labels:{x:15},title:{rotation:90}},defaultBottomAxisOptions:{labels:{autoRotation:[-45],x:0},title:{rotation:0}},defaultTopAxisOptions:{labels:{autoRotation:[-45],x:0},title:{rotation:0}},init:function(a,b){var g=b.isX;this.chart=a;this.horiz=a.inverted?!g:g;this.isXAxis=g;this.coll=this.coll||(g?"xAxis":"yAxis");this.opposite=b.opposite;this.side=b.side||(this.horiz?this.opposite?0:2:this.opposite?1:3);this.setOptions(b);var c=this.options,e=c.type;this.labelFormatter=c.labels.formatter|| this.defaultLabelFormatter;this.userOptions=b;this.minPixelPadding=0;this.reversed=c.reversed;this.visible=!1!==c.visible;this.zoomEnabled=!1!==c.zoomEnabled;this.hasNames="category"===e||!0===c.categories;this.categories=c.categories||this.hasNames;this.names=this.names||[];this.plotLinesAndBandsGroups={};this.isLog="logarithmic"===e;this.isDatetimeAxis="datetime"===e;this.positiveValuesOnly=this.isLog&&!this.allowNegativeLog;this.isLinked=k(c.linkedTo);this.ticks={};this.labelEdge=[];this.minorTicks= {};this.plotLinesAndBands=[];this.alternateBands={};this.len=0;this.minRange=this.userMinRange=c.minRange||c.maxZoom;this.range=c.range;this.offset=c.offset||0;this.stacks={};this.oldStacks={};this.stacksTouched=0;this.min=this.max=null;this.crosshair=E(c.crosshair,I(a.options.tooltip.crosshairs)[g?0:1],!1);var h;b=this.options.events;-1===t(this,a.axes)&&(g?a.axes.splice(a.xAxis.length,0,this):a.axes.push(this),a[this.coll].push(this));this.series=this.series||[];a.inverted&&g&&void 0===this.reversed&& (this.reversed=!0);this.removePlotLine=this.removePlotBand=this.removePlotBandOrLine;for(h in b)B(this,h,b[h]);this.lin2log=c.linearToLogConverter||this.lin2log;this.isLog&&(this.val2lin=this.log2lin,this.lin2val=this.lin2log)},setOptions:function(a){this.options=x(this.defaultOptions,"yAxis"===this.coll&&this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],x(q[this.coll],a))},defaultLabelFormatter:function(){var g= this.axis,c=this.value,e=g.categories,h=this.dateTimeLabelFormat,m=q.lang,d=m.numericSymbols,m=m.numericSymbolMagnitude||1E3,v=d&&d.length,p,t=g.options.labels.format,g=g.isLog?Math.abs(c):g.tickInterval;if(t)p=b(t,this);else if(e)p=c;else if(h)p=a.dateFormat(h,c);else if(v&&1E3<=g)for(;v--&&void 0===p;)e=Math.pow(m,v+1),g>=e&&0===10*c%e&&null!==d[v]&&0!==c&&(p=a.numberFormat(c/e,-1)+d[v]);void 0===p&&(p=1E4<=Math.abs(c)?a.numberFormat(c,-1):a.numberFormat(c,-1,void 0,""));return p},getSeriesExtremes:function(){var a= this,b=a.chart;a.hasVisibleSeries=!1;a.dataMin=a.dataMax=a.threshold=null;a.softThreshold=!a.isXAxis;a.buildStacks&&a.buildStacks();c(a.series,function(g){if(g.visible||!b.options.chart.ignoreHiddenSeries){var c=g.options,e=c.threshold,m;a.hasVisibleSeries=!0;a.positiveValuesOnly&&0>=e&&(e=null);if(a.isXAxis)c=g.xData,c.length&&(g=G(c),w(g)||g instanceof Date||(c=h(c,function(a){return w(a)}),g=G(c)),a.dataMin=Math.min(E(a.dataMin,c[0]),g),a.dataMax=Math.max(E(a.dataMax,c[0]),H(c)));else if(g.getExtremes(), m=g.dataMax,g=g.dataMin,k(g)&&k(m)&&(a.dataMin=Math.min(E(a.dataMin,g),g),a.dataMax=Math.max(E(a.dataMax,m),m)),k(e)&&(a.threshold=e),!c.softThreshold||a.positiveValuesOnly)a.softThreshold=!1}})},translate:function(a,b,c,e,h,m){var g=this.linkedParent||this,F=1,p=0,d=e?g.oldTransA:g.transA;e=e?g.oldMin:g.min;var t=g.minPixelPadding;h=(g.isOrdinal||g.isBroken||g.isLog&&h)&&g.lin2val;d||(d=g.transA);c&&(F*=-1,p=g.len);g.reversed&&(F*=-1,p-=F*(g.sector||g.len));b?(a=(a*F+p-t)/d+e,h&&(a=g.lin2val(a))): (h&&(a=g.val2lin(a)),a=F*(a-e)*d+p+F*t+(w(m)?d*m:0));return a},toPixels:function(a,b){return this.translate(a,!1,!this.horiz,null,!0)+(b?0:this.pos)},toValue:function(a,b){return this.translate(a-(b?0:this.pos),!0,!this.horiz,null,!0)},getPlotLinePath:function(a,b,c,e,h){var g=this.chart,m=this.left,F=this.top,p,d,t=c&&g.oldChartHeight||g.chartHeight,f=c&&g.oldChartWidth||g.chartWidth,n;p=this.transB;var y=function(a,b,g){if(ag)e?a=Math.min(Math.max(b,a),g):n=!0;return a};h=E(h,this.translate(a, null,null,c));a=c=Math.round(h+p);p=d=Math.round(t-h-p);w(h)?this.horiz?(p=F,d=t-this.bottom,a=c=y(a,m,m+this.width)):(a=m,c=f-this.right,p=d=y(p,F,F+this.height)):n=!0;return n&&!e?null:g.renderer.crispLine(["M",a,p,"L",c,d],b||1)},getLinearTickPositions:function(a,b,c){var g,e=l(Math.floor(b/a)*a);c=l(Math.ceil(c/a)*a);var h=[];if(this.single)return[b];for(b=e;b<=c;){h.push(b);b=l(b+a);if(b===g)break;g=b}return h},getMinorTickPositions:function(){var a=this,b=a.options,e=a.tickPositions,h=a.minorTickInterval, m=[],p=a.pointRangePadding||0,v=a.min-p,p=a.max+p,d=p-v;if(d&&d/h= this.minRange,p,v,d,t,f,n;this.isXAxis&&void 0===this.minRange&&!this.isLog&&(k(a.min)||k(a.max)?this.minRange=null:(c(this.series,function(a){t=a.xData;for(v=f=a.xIncrement?1:t.length-1;0=q?(r=q,y=0):g.dataMax<=q&&(K=q,n=0)),g.min=E(J,r,g.dataMin),g.max=E(A,K,g.dataMax));m&&(g.positiveValuesOnly&&!b&&0>=Math.min(g.min,E(g.dataMin,g.min))&&a.error(10,1),g.min=l(d(g.min),15),g.max=l(d(g.max),15));g.range&&k(g.max)&&(g.userMin=g.min=J=Math.max(g.min,g.minFromRange()),g.userMax=A=g.max,g.range=null);z(g,"foundExtremes");g.beforePadding&&g.beforePadding();g.adjustForMinRange(); !(I||g.axisPointRange||g.usePercentage||f)&&k(g.min)&&k(g.max)&&(d=g.max-g.min)&&(!k(J)&&y&&(g.min-=d*y),!k(A)&&n&&(g.max+=d*n));w(h.softMin)&&(g.min=Math.min(g.min,h.softMin));w(h.softMax)&&(g.max=Math.max(g.max,h.softMax));w(h.floor)&&(g.min=Math.max(g.min,h.floor));w(h.ceiling)&&(g.max=Math.min(g.max,h.ceiling));u&&k(g.dataMin)&&(q=q||0,!k(J)&&g.min=q?g.min=q:!k(A)&&g.max>q&&g.dataMax<=q&&(g.max=q));g.tickInterval=g.min===g.max||void 0===g.min||void 0===g.max?1:f&&!x&&D===g.linkedParent.options.tickPixelInterval? x=g.linkedParent.tickInterval:E(x,this.tickAmount?(g.max-g.min)/Math.max(this.tickAmount-1,1):void 0,I?1:(g.max-g.min)*D/Math.max(g.len,D));t&&!b&&c(g.series,function(a){a.processData(g.min!==g.oldMin||g.max!==g.oldMax)});g.setAxisTranslation(!0);g.beforeSetTickPositions&&g.beforeSetTickPositions();g.postProcessTickInterval&&(g.tickInterval=g.postProcessTickInterval(g.tickInterval));g.pointRange&&!x&&(g.tickInterval=Math.max(g.pointRange,g.tickInterval));b=E(h.minTickInterval,g.isDatetimeAxis&&g.closestPointRange); !x&&g.tickIntervalg.tickInterval&&1E3g.max)),!!this.tickAmount));this.tickAmount||(g.tickInterval=g.unsquish());this.setTickPositions()},setTickPositions:function(){var a=this.options,b,c=a.tickPositions,e=a.tickPositioner,h=a.startOnTick,m=a.endOnTick;this.tickmarkOffset=this.categories&&"between"===a.tickmarkPlacement&&1===this.tickInterval?.5:0;this.minorTickInterval= "auto"===a.minorTickInterval&&this.tickInterval?this.tickInterval/5:a.minorTickInterval;this.single=this.min===this.max&&k(this.min)&&!this.tickAmount&&!1!==a.allowDecimals;this.tickPositions=b=c&&c.slice();!b&&(b=this.isDatetimeAxis?this.getTimeTicks(this.normalizeTimeTickInterval(this.tickInterval,a.units),this.min,this.max,a.startOfWeek,this.ordinalPositions,this.closestPointRange,!0):this.isLog?this.getLogTickPositions(this.tickInterval,this.min,this.max):this.getLinearTickPositions(this.tickInterval, this.min,this.max),b.length>this.len&&(b=[b[0],b.pop()]),this.tickPositions=b,e&&(e=e.apply(this,[this.min,this.max])))&&(this.tickPositions=b=e);this.paddedTicks=b.slice(0);this.trimTicks(b,h,m);this.isLinked||(this.single&&(this.min-=.5,this.max+=.5),c||e||this.adjustTickAmount())},trimTicks:function(a,b,c){var g=a[0],e=a[a.length-1],h=this.minPointOffset||0;if(!this.isLinked){if(b&&-Infinity!==g)this.min=g;else for(;this.min-h>a[0];)a.shift();if(c)this.max=e;else for(;this.max+hb&&(this.finalTickAmt=b,b=5);this.tickAmount=b},adjustTickAmount:function(){var a=this.tickInterval,b=this.tickPositions,c=this.tickAmount,e=this.finalTickAmt,h=b&&b.length;if(hc&&(this.tickInterval*=2,this.setTickPositions());if(k(e)){for(a=c=b.length;a--;)(3===e&&1===a%2||2>=e&&0e&&(a=e)), k(c)&&(be&&(b=e))),this.displayBtn=void 0!==a||void 0!==b,this.setExtremes(a,b,!1,void 0,{trigger:"zoom"});return!0},setAxisSize:function(){var a=this.chart,b=this.options,c=b.offsets||[0,0,0,0],e=this.horiz,h=E(b.width,a.plotWidth-c[3]+c[1]),m=E(b.height,a.plotHeight-c[0]+c[2]),p=E(b.top,a.plotTop+c[0]),b=E(b.left,a.plotLeft+c[3]),c=/%$/;c.test(m)&&(m=Math.round(parseFloat(m)/100*a.plotHeight));c.test(p)&&(p=Math.round(parseFloat(p)/100*a.plotHeight+a.plotTop));this.left=b;this.top=p; this.width=h;this.height=m;this.bottom=a.chartHeight-m-p;this.right=a.chartWidth-h-b;this.len=Math.max(e?h:m,0);this.pos=e?b:p},getExtremes:function(){var a=this.isLog,b=this.lin2log;return{min:a?l(b(this.min)):this.min,max:a?l(b(this.max)):this.max,dataMin:this.dataMin,dataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}},getThreshold:function(a){var b=this.isLog,g=this.lin2log,c=b?g(this.min):this.min,b=b?g(this.max):this.max;null===a?a=c:c>a?a=c:ba?"right":195a?"left":"center"},tickSize:function(a){var b=this.options,g=b[a+"Length"],c=E(b[a+"Width"],"tick"===a&&this.isXAxis?1:0);if(c&&g)return"inside"===b[a+"Position"]&&(g=-g),[g,c]},labelMetrics:function(){return this.chart.renderer.fontMetrics(this.options.labels.style&&this.options.labels.style.fontSize,this.ticks[0]&&this.ticks[0].label)},unsquish:function(){var a=this.options.labels,b=this.horiz, e=this.tickInterval,h=e,m=this.len/(((this.categories?1:0)+this.max-this.min)/e),p,d=a.rotation,t=this.labelMetrics(),f,n=Number.MAX_VALUE,y,w=function(a){a/=m||1;a=1=a)f=w(Math.abs(t.h/Math.sin(u*a))),b=f+Math.abs(a/360),b(c.step||0)&&!c.rotation&&(this.staggerLines||1)*this.len/e||!b&&(h&&h-a.spacing[3]||.33*a.chartWidth)},renderUnsquish:function(){var a=this.chart,b=a.renderer,h=this.tickPositions,m=this.ticks,p=this.options.labels,d=this.horiz,v=this.getSlotWidth(),t=Math.max(1,Math.round(v-2*(p.padding||5))),f={},n=this.labelMetrics(),y=p.style&&p.style.textOverflow,k,w=0,D,l;e(p.rotation)|| (f.rotation=p.rotation||0);c(h,function(a){(a=m[a])&&a.labelLength>w&&(w=a.labelLength)});this.maxLabelLength=w;if(this.autoRotation)w>t&&w>n.h?f.rotation=this.labelRotation:this.labelRotation=0;else if(v&&(k={width:t+"px"},!y))for(k.textOverflow="clip",D=h.length;!d&&D--;)if(l=h[D],t=m[l].label)t.styles&&"ellipsis"===t.styles.textOverflow?t.css({textOverflow:"clip"}):m[l].labelLength>v&&t.css({width:v+"px"}),t.getBBox().height>this.len/h.length-(n.h-n.f)&&(t.specCss={textOverflow:"ellipsis"});f.rotation&& (k={width:(w>.5*a.chartHeight?.33*a.chartHeight:a.chartHeight)+"px"},y||(k.textOverflow="ellipsis"));if(this.labelAlign=p.align||this.autoLabelAlign(this.labelRotation))f.align=this.labelAlign;c(h,function(a){var b=(a=m[a])&&a.label;b&&(b.attr(f),k&&b.css(x(k,b.specCss)),delete b.specCss,a.rotation=f.rotation)});this.tickRotCorr=b.rotCorr(n.b,this.labelRotation||0,0!==this.side)},hasData:function(){return this.hasVisibleSeries||k(this.min)&&k(this.max)&&!!this.tickPositions},addTitle:function(a){var b= this.chart.renderer,c=this.horiz,g=this.opposite,e=this.options.title,h;this.axisTitle||((h=e.textAlign)||(h=(c?{low:"left",middle:"center",high:"right"}:{low:g?"right":"left",middle:"center",high:g?"left":"right"})[e.align]),this.axisTitle=b.text(e.text,0,0,e.useHTML).attr({zIndex:7,rotation:e.rotation||0,align:h}).addClass("highcharts-axis-title").css(e.style).add(this.axisGroup),this.axisTitle.isNew=!0);this.axisTitle[a?"show":"hide"](!0)},generateTick:function(a){var b=this.ticks;b[a]?b[a].addLabel(): b[a]=new J(this,a)},getOffset:function(){var a=this,b=a.chart,e=b.renderer,h=a.options,m=a.tickPositions,p=a.ticks,d=a.horiz,t=a.side,f=b.inverted?[1,0,3,2][t]:t,n,y,w=0,x,D=0,l=h.title,C=h.labels,q=0,I=b.axisOffset,b=b.clipOffset,u=[-1,1,1,-1][t],z,r=h.className,K=a.axisParent,J=this.tickSize("tick");n=a.hasData();a.showAxis=y=n||E(h.showEmpty,!0);a.staggerLines=a.horiz&&C.staggerLines;a.axisGroup||(a.gridGroup=e.g("grid").attr({zIndex:h.gridZIndex||1}).addClass("highcharts-"+this.coll.toLowerCase()+ "-grid "+(r||"")).add(K),a.axisGroup=e.g("axis").attr({zIndex:h.zIndex||2}).addClass("highcharts-"+this.coll.toLowerCase()+" "+(r||"")).add(K),a.labelGroup=e.g("axis-labels").attr({zIndex:C.zIndex||7}).addClass("highcharts-"+a.coll.toLowerCase()+"-labels "+(r||"")).add(K));if(n||a.isLinked)c(m,function(b,c){a.generateTick(b,c)}),a.renderUnsquish(),!1===C.reserveSpace||0!==t&&2!==t&&{1:"left",3:"right"}[t]!==a.labelAlign&&"center"!==a.labelAlign||c(m,function(a){q=Math.max(p[a].getLabelSize(),q)}), a.staggerLines&&(q*=a.staggerLines,a.labelOffset=q*(a.opposite?-1:1));else for(z in p)p[z].destroy(),delete p[z];l&&l.text&&!1!==l.enabled&&(a.addTitle(y),y&&(w=a.axisTitle.getBBox()[d?"height":"width"],x=l.offset,D=k(x)?0:E(l.margin,d?5:10)));a.renderLine();a.offset=u*E(h.offset,I[t]);a.tickRotCorr=a.tickRotCorr||{x:0,y:0};e=0===t?-a.labelMetrics().h:2===t?a.tickRotCorr.y:0;D=Math.abs(q)+D;q&&(D=D-e+u*(d?E(C.y,a.tickRotCorr.y+8*u):C.x));a.axisTitleMargin=E(x,D);I[t]=Math.max(I[t],a.axisTitleMargin+ w+u*a.offset,D,n&&m.length&&J?J[0]+u*a.offset:0);h=h.offset?0:2*Math.floor(a.axisLine.strokeWidth()/2);b[f]=Math.max(b[f],h)},getLinePath:function(a){var b=this.chart,c=this.opposite,g=this.offset,e=this.horiz,h=this.left+(c?this.width:0)+g,g=b.chartHeight-this.bottom-(c?this.height:0)+g;c&&(a*=-1);return b.renderer.crispLine(["M",e?this.left:h,e?g:this.top,"L",e?b.chartWidth-this.right:h,e?g:b.chartHeight-this.bottom],a)},renderLine:function(){this.axisLine||(this.axisLine=this.chart.renderer.path().addClass("highcharts-axis-line").add(this.axisGroup), this.axisLine.attr({stroke:this.options.lineColor,"stroke-width":this.options.lineWidth,zIndex:7}))},getTitlePosition:function(){var a=this.horiz,b=this.left,c=this.top,e=this.len,h=this.options.title,m=a?b:c,p=this.opposite,d=this.offset,t=h.x||0,f=h.y||0,n=this.chart.renderer.fontMetrics(h.style&&h.style.fontSize,this.axisTitle).f,e={low:m+(a?0:e),middle:m+e/2,high:m+(a?e:0)}[h.align],b=(a?c+this.height:b)+(a?1:-1)*(p?-1:1)*this.axisTitleMargin+(2===this.side?n:0);return{x:a?e+t:b+(p?this.width: 0)+d+t,y:a?b+f-(p?this.height:0)+d:e+f}},renderMinorTick:function(a){var b=this.chart.hasRendered&&w(this.oldMin),c=this.minorTicks;c[a]||(c[a]=new J(this,a,"minor"));b&&c[a].isNew&&c[a].render(null,!0);c[a].render(null,!1,1)},renderTick:function(a,b){var c=this.isLinked,g=this.ticks,e=this.chart.hasRendered&&w(this.oldMin);if(!c||a>=this.min&&a<=this.max)g[a]||(g[a]=new J(this,a)),e&&g[a].isNew&&g[a].render(b,!0,.1),g[a].render(b)},render:function(){var a=this,b=a.chart,e=a.options,h=a.isLog,p=a.lin2log, d=a.isLinked,t=a.tickPositions,f=a.axisTitle,n=a.ticks,y=a.minorTicks,k=a.alternateBands,w=e.stackLabels,x=e.alternateGridColor,D=a.tickmarkOffset,l=a.axisLine,C=a.showAxis,q=A(b.renderer.globalAnimation),I,E;a.labelEdge.length=0;a.overlap=!1;c([n,y,k],function(a){for(var b in a)a[b].isActive=!1});if(a.hasData()||d)a.minorTickInterval&&!a.categories&&c(a.getMinorTickPositions(),function(b){a.renderMinorTick(b)}),t.length&&(c(t,function(b,c){a.renderTick(b,c)}),D&&(0===a.min||a.single)&&(n[-1]||(n[-1]= new J(a,-1,null,!0)),n[-1].render(-1))),x&&c(t,function(c,e){E=void 0!==t[e+1]?t[e+1]+D:a.max-D;0===e%2&&c=c.second?0:E*Math.floor(e.getMilliseconds()/E));if(C>=c.second)e[A.hcSetSeconds](C>=c.minute?0:E*Math.floor(e.getSeconds()/E));if(C>=c.minute)e[A.hcSetMinutes](C>=c.hour?0:E*Math.floor(e[A.hcGetMinutes]()/E));if(C>=c.hour)e[A.hcSetHours](C>= c.day?0:E*Math.floor(e[A.hcGetHours]()/E));if(C>=c.day)e[A.hcSetDate](C>=c.month?1:E*Math.floor(e[A.hcGetDate]()/E));C>=c.month&&(e[A.hcSetMonth](C>=c.year?0:E*Math.floor(e[A.hcGetMonth]()/E)),w=e[A.hcGetFullYear]());if(C>=c.year)e[A.hcSetFullYear](w-w%E);if(C===c.week)e[A.hcSetDate](e[A.hcGetDate]()-e[A.hcGetDay]()+d(p,1));w=e[A.hcGetFullYear]();p=e[A.hcGetMonth]();var y=e[A.hcGetDate](),I=e[A.hcGetHours]();if(A.hcTimezoneOffset||A.hcGetTimezoneOffset)m=(!n||!!A.hcGetTimezoneOffset)&&(b-q>4*c.month|| k(q)!==k(b)),e=e.getTime(),e=new A(e+k(e));n=e.getTime();for(q=1;nh.length&&f(h,function(a){0===a%18E5&&"000000000"===H("%H%M%S%L",a)&&(t[a]="day")})}h.info=l(a,{higherRanks:t,totalRange:C*E});return h};B.prototype.normalizeTimeTickInterval=function(a,d){var b=d||[["millisecond",[1,2,5,10,20,25,50,100,200,500]],["second", [1,2,5,10,15,30]],["minute",[1,2,5,10,15,30]],["hour",[1,2,3,4,6,8,12]],["day",[1,2]],["week",[1,2]],["month",[1,2,3,4,6]],["year",null]];d=b[b.length-1];var p=c[d[0]],h=d[1],t;for(t=0;tl&&(!k||t<=q)&&void 0!==t&&z.push(t),t>q&&(D=!0),t=h;else l=c(l),q=c(q),a=f[k?"minorTickInterval":"tickInterval"],a=r("auto"===a?null:a,this._minorAutoInterval, f.tickPixelInterval/(k?5:1)*(q-l)/((k?d/this.tickPositions.length:d)||1)),a=G(a,null,A(a)),z=H(this.getLinearTickPositions(a,l,q),n),k||(this._minorAutoInterval=a/5);k||(this.tickInterval=a);return z};B.prototype.log2lin=function(a){return Math.log(a)/Math.LN10};B.prototype.lin2log=function(a){return Math.pow(10,a)}})(L);(function(a){var B=a.dateFormat,A=a.each,H=a.extend,G=a.format,r=a.isNumber,f=a.map,l=a.merge,q=a.pick,k=a.splat,u=a.syncTimeout,d=a.timeUnits;a.Tooltip=function(){this.init.apply(this, arguments)};a.Tooltip.prototype={init:function(a,d){this.chart=a;this.options=d;this.crosshairs=[];this.now={x:0,y:0};this.isHidden=!0;this.split=d.split&&!a.inverted;this.shared=d.shared||this.split},cleanSplit:function(a){A(this.chart.series,function(c){var d=c&&c.tt;d&&(!d.isActive||a?c.tt=d.destroy():d.isActive=!1)})},getLabel:function(){var a=this.chart.renderer,d=this.options;this.label||(this.split?this.label=a.g("tooltip"):(this.label=a.label("",0,0,d.shape||"callout",null,null,d.useHTML, null,"tooltip").attr({padding:d.padding,r:d.borderRadius}),this.label.attr({fill:d.backgroundColor,"stroke-width":d.borderWidth}).css(d.style).shadow(d.shadow)),this.label.attr({zIndex:8}).add());return this.label},update:function(a){this.destroy();this.init(this.chart,l(!0,this.options,a))},destroy:function(){this.label&&(this.label=this.label.destroy());this.split&&this.tt&&(this.cleanSplit(this.chart,!0),this.tt=this.tt.destroy());clearTimeout(this.hideTimer);clearTimeout(this.tooltipTimeout)}, move:function(a,d,f,b){var c=this,h=c.now,t=!1!==c.options.animation&&!c.isHidden&&(1n-t?n:n-t); else if(f)h[a]=Math.max(m,g+t+e>b?g:g+t);else return!1},E=function(a,b,e,g){var m;gb-c?m=!1:h[a]=gb-e/2?b-e-2:g-e/2;return m},m=function(a){var b=k;k=e;e=b;n=a},y=function(){!1!==l.apply(0,k)?!1!==E.apply(0,e)||n||(m(!0),y()):n?h.x=h.y=0:(m(!0),y())};(b.inverted||1y&&(t=!1);a=(c.series&&c.series.yAxis&&c.series.yAxis.pos)+(c.plotY||0);a-=p.plotTop;b.push({target:c.isHeader?p.plotHeight+k:a,rank:c.isHeader?1:0,size:w.tt.getBBox().height+1,point:c,x:y,tt:m})});this.cleanSplit();a.distribute(b,p.plotHeight+k);A(b,function(a){var b=a.point,c=b.series;a.tt.attr({visibility:void 0===a.pos?"hidden":"inherit",x:t||b.isHeader?a.x:b.plotX+p.plotLeft+q(n.distance, 16),y:a.pos+p.plotTop,anchorX:b.isHeader?b.plotX+p.plotLeft:b.plotX+c.xAxis.pos,anchorY:b.isHeader?a.pos+p.plotTop-15:b.plotY+c.yAxis.pos})})},updatePosition:function(a){var c=this.chart,d=this.getLabel(),d=(this.options.positioner||this.getPosition).call(this,d.width,d.height,a);this.move(Math.round(d.x),Math.round(d.y||0),a.plotX+c.plotLeft,a.plotY+c.plotTop)},getDateFormat:function(a,f,k,b){var c=B("%m-%d %H:%M:%S.%L",f),h,t,n={millisecond:15,second:12,minute:9,hour:6,day:3},w="millisecond";for(t in d){if(a=== d.week&&+B("%w",f)===k&&"00:00:00.000"===c.substr(6)){t="week";break}if(d[t]>a){t=w;break}if(n[t]&&c.substr(n[t])!=="01-01 00:00:00.000".substr(n[t]))break;"week"!==t&&(w=t)}t&&(h=b[t]);return h},getXDateFormat:function(a,d,f){d=d.dateTimeLabelFormats;var b=f&&f.closestPointRange;return(b?this.getDateFormat(b,a.x,f.options.startOfWeek,d):d.day)||d.year},tooltipFooterHeaderFormatter:function(a,d){var c=d?"footer":"header";d=a.series;var b=d.tooltipOptions,p=b.xDateFormat,h=d.xAxis,t=h&&"datetime"=== h.options.type&&r(a.key),c=b[c+"Format"];t&&!p&&(p=this.getXDateFormat(a,b,h));t&&p&&(c=c.replace("{point.key}","{point.key:"+p+"}"));return G(c,{point:a,series:d})},bodyFormatter:function(a){return f(a,function(a){var c=a.series.tooltipOptions;return(c.pointFormatter||a.point.tooltipFormatter).call(a.point,c.pointFormat)})}}})(L);(function(a){var B=a.addEvent,A=a.attr,H=a.charts,G=a.color,r=a.css,f=a.defined,l=a.doc,q=a.each,k=a.extend,u=a.fireEvent,d=a.offset,c=a.pick,n=a.removeEvent,z=a.splat, b=a.Tooltip,p=a.win;a.Pointer=function(a,b){this.init(a,b)};a.Pointer.prototype={init:function(a,d){this.options=d;this.chart=a;this.runChartClick=d.chart.events&&!!d.chart.events.click;this.pinchDown=[];this.lastValidTouch={};b&&d.tooltip.enabled&&(a.tooltip=new b(a,d.tooltip),this.followTouchMove=c(d.tooltip.followTouchMove,!0));this.setDOMEvents()},zoomOption:function(a){var b=this.chart,h=b.options.chart,d=h.zoomType||"",b=b.inverted;/touch/.test(a.type)&&(d=c(h.pinchType,d));this.zoomX=a=/x/.test(d); this.zoomY=d=/y/.test(d);this.zoomHor=a&&!b||d&&b;this.zoomVert=d&&!b||a&&b;this.hasZoom=a||d},normalize:function(a,b){var c,h;a=a||p.event;a.target||(a.target=a.srcElement);h=a.touches?a.touches.length?a.touches.item(0):a.changedTouches[0]:a;b||(this.chartPosition=b=d(this.chart.container));void 0===h.pageX?(c=Math.max(a.x,a.clientX-b.left),b=a.y):(c=h.pageX-b.left,b=h.pageY-b.top);return k(a,{chartX:Math.round(c),chartY:Math.round(b)})},getCoordinates:function(a){var b={xAxis:[],yAxis:[]};q(this.chart.axes, function(c){b[c.isXAxis?"xAxis":"yAxis"].push({axis:c,value:c.toValue(a[c.horiz?"chartX":"chartY"])})});return b},getKDPoints:function(a,b,d){var h=[],e,p,f;q(a,function(a){e=a.noSharedTooltip&&b;p=!b&&a.directTouch;a.visible&&!p&&c(a.options.enableMouseTracking,!0)&&(f=a.searchPoint(d,!e&&0>a.options.findNearestPointBy.indexOf("y")))&&f.series&&h.push(f)});h.sort(function(a,c){var e=a.distX-c.distX,h=a.dist-c.dist,m=(c.series.group&&c.series.group.zIndex)-(a.series.group&&a.series.group.zIndex); return 0!==e&&b?e:0!==h?h:0!==m?m:a.series.index>c.series.index?-1:1});if(b&&h[0]&&!h[0].series.noSharedTooltip)for(a=h.length;a--;)(h[a].x!==h[0].x||h[a].series.noSharedTooltip)&&h.splice(a,1);return h},getPointFromEvent:function(a){a=a.target;for(var b;a&&!b;)b=a.point,a=a.parentNode;return b},getHoverData:function(b,d,p,f,e,n){var h=b,t=d,m;f?e?(m=[],q(p,function(a){var b=a.noSharedTooltip&&e,d=!e&&a.directTouch;a.visible&&!b&&!d&&c(a.options.enableMouseTracking,!0)&&(a=a.searchKDTree({clientX:h.clientX, plotY:h.plotY},!b&&1===a.kdDimensions))&&a.series&&m.push(a)}),0===m.length&&(m=[h])):m=[h]:t&&!t.stickyTracking?(e||(p=[t]),m=this.getKDPoints(p,e,n),h=a.find(m,function(a){return a.series===t})):(b=a.grep(p,function(a){return a.stickyTracking}),m=this.getKDPoints(b,e,n),t=(h=m[0])&&h.series,e&&(m=this.getKDPoints(p,e,n)));m.sort(function(a,b){return a.series.index-b.series.index});return{hoverPoint:h,hoverSeries:t,hoverPoints:m}},runPointActions:function(b,d){var h=this.chart,p=h.tooltip,e=p?p.shared: !1,f=d||h.hoverPoint,t=f&&f.series||h.hoverSeries;d=this.getHoverData(f,t,h.series,!!d||!e&&t&&t.directTouch,e,b);var n,m,f=d.hoverPoint;n=(t=d.hoverSeries)&&t.tooltipOptions.followPointer;m=(e=e&&f&&!f.series.noSharedTooltip)?d.hoverPoints:f?[f]:[];if(f&&(f!==h.hoverPoint||p&&p.isHidden)){q(h.hoverPoints||[],function(b){-1===a.inArray(b,m)&&b.setState()});q(m||[],function(a){a.setState("hover")});if(h.hoverSeries!==t)t.onMouseOver();t&&!t.directTouch&&(h.hoverPoint&&h.hoverPoint.firePointEvent("mouseOut"), f.firePointEvent("mouseOver"));h.hoverPoints=m;h.hoverPoint=f;p&&p.refresh(e?m:f,b)}else n&&p&&!p.isHidden&&(f=p.getAnchor([{}],b),p.updatePosition({plotX:f[0],plotY:f[1]}));this.unDocMouseMove||(this.unDocMouseMove=B(l,"mousemove",function(b){var c=H[a.hoverChartIndex];if(c)c.pointer.onDocumentMouseMove(b)}));q(h.axes,function(a){c(a.crosshair.snap,!0)?q(m,function(c){c.series[a.coll]===a&&a.drawCrosshair(b,c)}):a.drawCrosshair(b)})},reset:function(a,b){var c=this.chart,h=c.hoverSeries,e=c.hoverPoint, d=c.hoverPoints,p=c.tooltip,f=p&&p.shared?d:e;a&&f&&q(z(f),function(b){b.series.isCartesian&&void 0===b.plotX&&(a=!1)});if(a)p&&f&&(p.refresh(f),e&&(e.setState(e.state,!0),q(c.axes,function(a){a.crosshair&&a.drawCrosshair(null,e)})));else{if(e)e.onMouseOut();d&&q(d,function(a){a.setState()});if(h)h.onMouseOut();p&&p.hide(b);this.unDocMouseMove&&(this.unDocMouseMove=this.unDocMouseMove());q(c.axes,function(a){a.hideCrosshair()});this.hoverX=c.hoverPoints=c.hoverPoint=null}},scaleGroups:function(a, b){var c=this.chart,h;q(c.series,function(e){h=a||e.getPlotBox();e.xAxis&&e.xAxis.zoomEnabled&&e.group&&(e.group.attr(h),e.markerGroup&&(e.markerGroup.attr(h),e.markerGroup.clip(b?c.clipRect:null)),e.dataLabelsGroup&&e.dataLabelsGroup.attr(h))});c.clipRect.attr(b||c.clipBox)},dragStart:function(a){var b=this.chart;b.mouseIsDown=a.type;b.cancelClick=!1;b.mouseDownX=this.mouseDownX=a.chartX;b.mouseDownY=this.mouseDownY=a.chartY},drag:function(a){var b=this.chart,c=b.options.chart,h=a.chartX,e=a.chartY, d=this.zoomHor,p=this.zoomVert,f=b.plotLeft,m=b.plotTop,n=b.plotWidth,k=b.plotHeight,l,q=this.selectionMarker,g=this.mouseDownX,u=this.mouseDownY,r=c.panKey&&a[c.panKey+"Key"];q&&q.touch||(hf+n&&(h=f+n),em+k&&(e=m+k),this.hasDragged=Math.sqrt(Math.pow(g-h,2)+Math.pow(u-e,2)),10m.max&&(f=m.max-e,z=!0);z?(K-=.8*(K-n[p][0]),y||(g-=.8*(g-n[p][1])),k()):n[p]=[K,g];E||(c[p]=q-w,c[l]=e);c=E?1/C:C;d[l]=e;d[p]=f;u[E?a?"scaleY":"scaleX":"scale"+h]=C;u["translate"+h]=c*w+(K-c*I)},pinch:function(a){var l=this,k=l.chart,u=l.pinchDown,d=a.touches,c=d.length,n=l.lastValidTouch,z=l.hasZoom,b=l.selectionMarker,p={},h=1===c&&(l.inClass(a.target,"highcharts-tracker")&&k.runTrackerClick|| l.runChartClick),t={};1c-6&&f(I||b.spacingBox.width-2*r-d.x)&&(this.itemX=r,this.itemY+=J+this.lastLineHeight+ K,this.lastLineHeight=0);this.maxItemWidth=Math.max(this.maxItemWidth,n);this.lastItemY=J+this.itemY+K;this.lastLineHeight=Math.max(e,this.lastLineHeight);a._legendItemPos=[this.itemX,this.itemY];f?this.itemX+=n:(this.itemY+=J+e+K,this.lastLineHeight=e);this.offsetWidth=I||Math.max((f?this.itemX-r-m:n)+r,this.offsetWidth)},getAllItems:function(){var a=[];f(this.chart.series,function(b){var c=b&&b.options;b&&u(c.showInLegend,r(c.linkedTo)?!1:void 0,!0)&&(a=a.concat(b.legendItems||("point"===c.legendType? b.data:b)))});return a},adjustMargins:function(a,c){var b=this.chart,d=this.options,p=d.align.charAt(0)+d.verticalAlign.charAt(0)+d.layout.charAt(0);d.floating||f([/(lth|ct|rth)/,/(rtv|rm|rbv)/,/(rbh|cb|lbh)/,/(lbv|lm|ltv)/],function(h,e){h.test(p)&&!r(a[e])&&(b[q[e]]=Math.max(b[q[e]],b.legend[(e+1)%2?"legendHeight":"legendWidth"]+[1,-1,-1,1][e]*d[e%2?"x":"y"]+u(d.margin,12)+c[e]))})},render:function(){var a=this,d=a.chart,h=d.renderer,n=a.group,l,q,e,x,u=a.box,r=a.options,m=a.padding;a.itemX=m;a.itemY= a.initialItemY;a.offsetWidth=0;a.lastItemY=0;n||(a.group=n=h.g("legend").attr({zIndex:7}).add(),a.contentGroup=h.g().attr({zIndex:1}).add(n),a.scrollGroup=h.g().add(a.contentGroup));a.renderTitle();l=a.getAllItems();c(l,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)});r.reversed&&l.reverse();a.allItems=l;a.display=q=!!l.length;a.lastLineHeight=0;f(l,function(b){a.renderItem(b)});e=(r.width||a.offsetWidth)+m;x=a.lastItemY+a.lastLineHeight+a.titleHeight; x=a.handleOverflow(x);x+=m;u||(a.box=u=h.rect().addClass("highcharts-legend-box").attr({r:r.borderRadius}).add(n),u.isNew=!0);u.attr({stroke:r.borderColor,"stroke-width":r.borderWidth||0,fill:r.backgroundColor||"none"}).shadow(r.shadow);0c&&!1!==r.enabled?(this.clipHeight=l=Math.max(c-20-this.titleHeight-e,0),this.currentPage=u(this.currentPage,1),this.fullHeight=a,f(g,function(a,b){var c=a._legendItemPos[1];a=Math.round(a.legendItem.getBBox().height);var e=K.length;if(!e||c-K[e-1]>l&&(J||c)!==K[e-1])K.push(J||c),e++;b===g.length-1&&c+a-K[e-1]>l&&K.push(c);c!==J&&(J=c)}),q||(q=b.clipRect=d.clipRect(0,e,9999,0),b.contentGroup.clip(q)),z(l),I||(this.nav=I=d.g().attr({zIndex:1}).add(this.group), this.up=d.symbol("triangle",0,0,y,y).on("click",function(){b.scroll(-1,m)}).add(I),this.pager=d.text("",15,10).addClass("highcharts-legend-navigation").css(r.style).add(I),this.down=d.symbol("triangle-down",0,0,y,y).on("click",function(){b.scroll(1,m)}).add(I)),b.scroll(0),a=c):I&&(z(),this.nav=I.destroy(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0);return a},scroll:function(a,c){var b=this.pages,f=b.length;a=this.currentPage+a;var p=this.clipHeight,n=this.options.navigation,e=this.pager, k=this.padding;a>f&&(a=f);0p&&(d=typeof a[0],"string"===d?c.name=a[0]:"number"===d&&(c.x=a[0]),h++);k=k.value;)k=c[++f];k&&k.color&&!this.options.color&&(this.color=k.color);return k},destroy:function(){var a=this.series.chart,c=a.hoverPoints,f;a.pointCount--;c&&(this.setState(),G(c,this),c.length||(a.hoverPoints=null));if(this===a.hoverPoint)this.onMouseOut();if(this.graphic||this.dataLabel)u(this),this.destroyElements();this.legendItem&&a.legend.destroyItem(this);for(f in this)this[f]=null},destroyElements:function(){for(var a=["graphic", "dataLabel","dataLabelUpper","connector","shadowGroup"],c,f=6;f--;)c=a[f],this[c]&&(this[c]=this[c].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,color:this.color,colorIndex:this.colorIndex,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},tooltipFormatter:function(a){var c=this.series,d=c.tooltipOptions,l=k(d.valueDecimals,""),b=d.valuePrefix||"",p=d.valueSuffix||"";A(c.pointArrayMap||["y"],function(c){c= "{point."+c;if(b||p)a=a.replace(c+"}",b+c+"}"+p);a=a.replace(c+"}",c+":,."+l+"f}")});return f(a,{point:this,series:this.series})},firePointEvent:function(a,c,f){var d=this,b=this.series.options;(b.point.events[a]||d.options&&d.options.events&&d.options.events[a])&&this.importEvents();"click"===a&&b.allowPointSelect&&(f=function(a){d.select&&d.select(null,a.ctrlKey||a.metaKey||a.shiftKey)});r(this,a,c,f)},visible:!0}})(L);(function(a){var B=a.addEvent,A=a.animObject,H=a.arrayMax,G=a.arrayMin,r=a.correctFloat, f=a.Date,l=a.defaultOptions,q=a.defaultPlotOptions,k=a.defined,u=a.each,d=a.erase,c=a.extend,n=a.fireEvent,z=a.grep,b=a.isArray,p=a.isNumber,h=a.isString,t=a.merge,D=a.pick,w=a.removeEvent,e=a.splat,x=a.SVGElement,C=a.syncTimeout,E=a.win;a.Series=a.seriesType("line",null,{lineWidth:2,allowPointSelect:!1,showCheckbox:!1,animation:{duration:1E3},events:{},marker:{lineWidth:0,lineColor:"#ffffff",radius:4,states:{hover:{animation:{duration:50},enabled:!0,radiusPlus:2,lineWidthPlus:1},select:{fillColor:"#cccccc", lineColor:"#000000",lineWidth:2}}},point:{events:{}},dataLabels:{align:"center",formatter:function(){return null===this.y?"":a.numberFormat(this.y,-1)},style:{fontSize:"11px",fontWeight:"bold",color:"contrast",textOutline:"1px contrast"},verticalAlign:"bottom",x:0,y:0,padding:5},cropThreshold:300,pointRange:0,softThreshold:!0,states:{hover:{animation:{duration:50},lineWidthPlus:1,marker:{},halo:{size:10,opacity:.25}},select:{marker:{}}},stickyTracking:!0,turboThreshold:1E3,findNearestPointBy:"x"}, {isCartesian:!0,pointClass:a.Point,sorted:!0,requireSorting:!0,directTouch:!1,axisTypes:["xAxis","yAxis"],colorCounter:0,parallelArrays:["x","y"],coll:"series",init:function(a,b){var e=this,d,m,g=a.series,h;e.chart=a;e.options=b=e.setOptions(b);e.linkedSeries=[];e.bindAxes();c(e,{name:b.name,state:"",visible:!1!==b.visible,selected:!0===b.selected});m=b.events;for(d in m)B(e,d,m[d]);if(m&&m.click||b.point&&b.point.events&&b.point.events.click||b.allowPointSelect)a.runTrackerClick=!0;e.getColor(); e.getSymbol();u(e.parallelArrays,function(a){e[a+"Data"]=[]});e.setData(b.data,!1);e.isCartesian&&(a.hasCartesianSeries=!0);g.length&&(h=g[g.length-1]);e._i=D(h&&h._i,-1)+1;a.orderSeries(this.insert(g))},insert:function(a){var b=this.options.index,c;if(p(b)){for(c=a.length;c--;)if(b>=D(a[c].options.index,a[c]._i)){a.splice(c+1,0,this);break}-1===c&&a.unshift(this);c+=1}else a.push(this);return D(c,a.length-1)},bindAxes:function(){var b=this,c=b.options,e=b.chart,d;u(b.axisTypes||[],function(m){u(e[m], function(a){d=a.options;if(c[m]===d.index||void 0!==c[m]&&c[m]===d.id||void 0===c[m]&&0===d.index)b.insert(a.series),b[m]=a,a.isDirty=!0});b[m]||b.optionalAxis===m||a.error(18,!0)})},updateParallelArrays:function(a,b){var c=a.series,e=arguments,d=p(b)?function(e){var g="y"===e&&c.toYData?c.toYData(a):a[e];c[e+"Data"][b]=g}:function(a){Array.prototype[b].apply(c[a+"Data"],Array.prototype.slice.call(e,2))};u(c.parallelArrays,d)},autoIncrement:function(){var a=this.options,b=this.xIncrement,c,e=a.pointIntervalUnit, b=D(b,a.pointStart,0);this.pointInterval=c=D(this.pointInterval,a.pointInterval,1);e&&(a=new f(b),"day"===e?a=+a[f.hcSetDate](a[f.hcGetDate]()+c):"month"===e?a=+a[f.hcSetMonth](a[f.hcGetMonth]()+c):"year"===e&&(a=+a[f.hcSetFullYear](a[f.hcGetFullYear]()+c)),c=a-b);this.xIncrement=b+c;return b},setOptions:function(a){var b=this.chart,c=b.options.plotOptions,b=b.userOptions||{},e=b.plotOptions||{},d=c[this.type];this.userOptions=a;c=t(d,c.series,a);this.tooltipOptions=t(l.tooltip,l.plotOptions[this.type].tooltip, b.tooltip,e.series&&e.series.tooltip,e[this.type]&&e[this.type].tooltip,a.tooltip);this.stickyTracking=D(a.stickyTracking,e[this.type]&&e[this.type].stickyTracking,e.series&&e.series.stickyTracking,this.tooltipOptions.shared&&!this.noSharedTooltip?!0:c.stickyTracking);null===d.marker&&delete c.marker;this.zoneAxis=c.zoneAxis;a=this.zones=(c.zones||[]).slice();!c.negativeColor&&!c.negativeFillColor||c.zones||a.push({value:c[this.zoneAxis+"Threshold"]||c.threshold||0,className:"highcharts-negative", color:c.negativeColor,fillColor:c.negativeFillColor});a.length&&k(a[a.length-1].value)&&a.push({color:this.color,fillColor:this.fillColor});return c},getCyclic:function(a,b,c){var e,d=this.chart,g=this.userOptions,m=a+"Index",h=a+"Counter",f=c?c.length:D(d.options.chart[a+"Count"],d[a+"Count"]);b||(e=D(g[m],g["_"+m]),k(e)||(d.series.length||(d[h]=0),g["_"+m]=e=d[h]%f,d[h]+=1),c&&(b=c[e]));void 0!==e&&(this[m]=e);this[a]=b},getColor:function(){this.options.colorByPoint?this.options.color=null:this.getCyclic("color", this.options.color||q[this.type].color,this.chart.options.colors)},getSymbol:function(){this.getCyclic("symbol",this.options.marker.symbol,this.chart.options.symbols)},drawLegendSymbol:a.LegendSymbolMixin.drawLineMarker,setData:function(c,e,d,f){var m=this,g=m.points,k=g&&g.length||0,n,l=m.options,y=m.chart,t=null,q=m.xAxis,x=l.turboThreshold,r=this.xData,w=this.yData,C=(n=m.pointArrayMap)&&n.length;c=c||[];n=c.length;e=D(e,!0);if(!1!==f&&n&&k===n&&!m.cropped&&!m.hasGroupedData&&m.visible)u(c,function(a, b){g[b].update&&a!==l.data[b]&&g[b].update(a,!1,null,!1)});else{m.xIncrement=null;m.colorCounter=0;u(this.parallelArrays,function(a){m[a+"Data"].length=0});if(x&&n>x){for(d=0;null===t&&dp||this.forceCrop))if(c[d-1]x)c=[],e=[];else if(c[0]x)m=this.cropData(this.xData,this.yData,q,x),c=m.xData,e=m.yData,m=m.start,g=!0;for(p=c.length||1;--p;)d=t?k(c[p])-k(c[p-1]):c[p]-c[p-1],0d&&this.requireSorting&&a.error(15);this.cropped=g;this.cropStart=m;this.processedXData=c;this.processedYData=e;this.closestPointRange= h},cropData:function(a,b,c,e){var d=a.length,g=0,m=d,h=D(this.cropShoulder,1),f;for(f=0;f=c){g=Math.max(0,f-h);break}for(c=f;ce){m=c+h;break}return{xData:a.slice(g,m),yData:b.slice(g,m),start:g,end:m}},generatePoints:function(){var a=this.options.data,b=this.data,c,d=this.processedXData,h=this.processedYData,g=this.pointClass,f=d.length,p=this.cropStart||0,k,n=this.hasGroupedData,l,t=[],q;b||n||(b=[],b.length=a.length,b=this.data=b);for(q=0;q=h&&(e[t]||n)<=f,k&&n)if(k=l.length)for(;k--;)null!==l[k]&&(m[g++]=l[k]);else m[g++]=l;this.dataMin=G(m);this.dataMax=H(m)},translate:function(){this.processedXData||this.processData();this.generatePoints();var a=this.options,b=a.stacking,c=this.xAxis,e=c.categories,d=this.yAxis,g=this.points,h=g.length,f=!!this.modifyValue,n=a.pointPlacement,l="between"===n||p(n), t=a.threshold,q=a.startFromThreshold?t:0,x,u,w,C,E=Number.MAX_VALUE;"between"===n&&(n=.5);p(n)&&(n*=D(a.pointRange||c.pointRange));for(a=0;a=B&&(z.isNull=!0);z.plotX=x=r(Math.min(Math.max(-1E5,c.translate(A,0,0,0,1,n,"flags"===this.type)),1E5));b&&this.visible&&!z.isNull&&H&&H[A]&&(C=this.getStackIndicator(C,A,this.index),G=H[A],B=G.points[C.key],u=B[0],B= B[1],u===q&&C.key===H[A].base&&(u=D(t,d.min)),d.positiveValuesOnly&&0>=u&&(u=null),z.total=z.stackTotal=G.total,z.percentage=G.total&&z.y/G.total*100,z.stackY=B,G.setOffset(this.pointXOffset||0,this.barW||0));z.yBottom=k(u)?d.translate(u,0,1,0,1):null;f&&(B=this.modifyValue(B,z));z.plotY=u="number"===typeof B&&Infinity!==B?Math.min(Math.max(-1E5,d.translate(B,0,1,0,1)),1E5):void 0;z.isInside=void 0!==u&&0<=u&&u<=d.len&&0<=x&&x<=c.len;z.clientX=l?r(c.translate(A,0,0,0,1,n)):x;z.negative=z.y<(t||0); z.category=e&&void 0!==e[z.x]?e[z.x]:z.x;z.isNull||(void 0!==w&&(E=Math.min(E,Math.abs(x-w))),w=x);z.zone=this.zones.length&&z.getZone()}this.closestPointRangePx=E},getValidPoints:function(a,b){var c=this.chart;return z(a||this.points||[],function(a){return b&&!c.isInsidePlot(a.plotX,a.plotY,c.inverted)?!1:!a.isNull})},setClip:function(a){var b=this.chart,c=this.options,e=b.renderer,d=b.inverted,g=this.clipBox,h=g||b.clipBox,m=this.sharedClipKey||["_sharedClip",a&&a.duration,a&&a.easing,h.height, c.xAxis,c.yAxis].join(),f=b[m],p=b[m+"m"];f||(a&&(h.width=0,b[m+"m"]=p=e.clipRect(-99,d?-b.plotLeft:-b.plotTop,99,d?b.chartWidth:b.chartHeight)),b[m]=f=e.clipRect(h),f.count={length:0});a&&!f.count[this.index]&&(f.count[this.index]=!0,f.count.length+=1);!1!==c.clip&&(this.group.clip(a||g?f:b.clipRect),this.markerGroup.clip(p),this.sharedClipKey=m);a||(f.count[this.index]&&(delete f.count[this.index],--f.count.length),0===f.count.length&&m&&b[m]&&(g||(b[m]=b[m].destroy()),b[m+"m"]&&(b[m+"m"]=b[m+"m"].destroy())))}, animate:function(a){var b=this.chart,c=A(this.options.animation),e;a?this.setClip(c):(e=this.sharedClipKey,(a=b[e])&&a.animate({width:b.plotSizeX},c),b[e+"m"]&&b[e+"m"].animate({width:b.plotSizeX+99},c),this.animate=null)},afterAnimate:function(){this.setClip();n(this,"afterAnimate")},drawPoints:function(){var a=this.points,b=this.chart,c,e,d,g,h=this.options.marker,f,n,k,l,t=this.markerGroup,q=D(h.enabled,this.xAxis.isRadial?!0:null,this.closestPointRangePx>=2*h.radius);if(!1!==h.enabled||this._hasPointMarkers)for(e= 0;ed&&b.shadow));h&&(h.startX=c.xMap,h.isArea=c.isArea)})},applyZones:function(){var a=this,b=this.chart,c=b.renderer,e=this.zones,d,g,h=this.clips||[],f,k=this.graph,p=this.area,n=Math.max(b.chartWidth,b.chartHeight),l=this[(this.zoneAxis||"y")+"Axis"],t,q,x=b.inverted,w,r,C,E,z=!1;e.length&&(k||p)&&l&&void 0!==l.min&&(q=l.reversed,w=l.horiz,k&&k.hide(),p&&p.hide(),t=l.getExtremes(),u(e,function(e,m){d=q?w?b.plotWidth:0:w?0: l.toPixels(t.min);d=Math.min(Math.max(D(g,d),0),n);g=Math.min(Math.max(Math.round(l.toPixels(D(e.value,t.max),!0)),0),n);z&&(d=g=l.toPixels(t.max));r=Math.abs(d-g);C=Math.min(d,g);E=Math.max(d,g);l.isXAxis?(f={x:x?E:C,y:0,width:r,height:n},w||(f.x=b.plotHeight-f.x)):(f={x:0,y:x?E:C,width:n,height:r},w&&(f.y=b.plotWidth-f.y));x&&c.isVML&&(f=l.isXAxis?{x:0,y:q?C:E,height:f.width,width:b.chartWidth}:{x:f.y-b.plotLeft-b.spacingBox.x,y:0,width:f.height,height:b.chartHeight});h[m]?h[m].animate(f):(h[m]= c.clipRect(f),k&&a["zone-graph-"+m].clip(h[m]),p&&a["zone-area-"+m].clip(h[m]));z=e.value>t.max}),this.clips=h)},invertGroups:function(a){function b(){u(["group","markerGroup"],function(b){c[b]&&(e.renderer.isVML&&c[b].attr({width:c.yAxis.len,height:c.xAxis.len}),c[b].width=c.yAxis.len,c[b].height=c.xAxis.len,c[b].invert(a))})}var c=this,e=c.chart,d;c.xAxis&&(d=B(e,"resize",b),B(c,"destroy",d),b(a),c.invertGroups=b)},plotGroup:function(a,b,c,e,d){var g=this[a],h=!g;h&&(this[a]=g=this.chart.renderer.g(b).attr({zIndex:e|| .1}).add(d),g.addClass("highcharts-series-"+this.index+" highcharts-"+this.type+"-series highcharts-color-"+this.colorIndex+" "+(this.options.className||"")));g.attr({visibility:c})[h?"attr":"animate"](this.getPlotBox());return g},getPlotBox:function(){var a=this.chart,b=this.xAxis,c=this.yAxis;a.inverted&&(b=c,c=this.xAxis);return{translateX:b?b.left:a.plotLeft,translateY:c?c.top:a.plotTop,scaleX:1,scaleY:1}},render:function(){var a=this,b=a.chart,c,e=a.options,d=!!a.animate&&b.renderer.isSVG&&A(e.animation).duration, g=a.visible?"inherit":"hidden",h=e.zIndex,f=a.hasRendered,k=b.seriesGroup,p=b.inverted;c=a.plotGroup("group","series",g,h,k);a.markerGroup=a.plotGroup("markerGroup","markers",g,h,k);d&&a.animate(!0);c.inverted=a.isCartesian?p:!1;a.drawGraph&&(a.drawGraph(),a.applyZones());a.drawDataLabels&&a.drawDataLabels();a.visible&&a.drawPoints();a.drawTracker&&!1!==a.options.enableMouseTracking&&a.drawTracker();a.invertGroups(p);!1===e.clip||a.sharedClipKey||f||c.clip(b.clipRect);d&&a.animate();f||(a.animationTimeout= C(function(){a.afterAnimate()},d));a.isDirty=!1;a.hasRendered=!0},redraw:function(){var a=this.chart,b=this.isDirty||this.isDirtyData,c=this.group,e=this.xAxis,d=this.yAxis;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:D(e&&e.left,a.plotLeft),translateY:D(d&&d.top,a.plotTop)}));this.translate();this.render();b&&delete this.kdTree},kdAxisArray:["clientX","plotY"],searchPoint:function(a,b){var c=this.xAxis,e=this.yAxis,d=this.chart.inverted;return this.searchKDTree({clientX:d? c.len-a.chartY+c.pos:a.chartX-c.pos,plotY:d?e.len-a.chartX+e.pos:a.chartY-e.pos},b)},buildKDTree:function(){function a(c,e,d){var g,h;if(h=c&&c.length)return g=b.kdAxisArray[e%d],c.sort(function(a,b){return a[g]-b[g]}),h=Math.floor(h/2),{point:c[h],left:a(c.slice(0,h),e+1,d),right:a(c.slice(h+1),e+1,d)}}this.buildingKdTree=!0;var b=this,c=-1n?"left":"right";t=0>n?"right":"left";b[l]&&(l=c(a,b[l],f+1,m),q=l[h]w;)q--;this.updateParallelArrays(g,"splice",q,0,0);this.updateParallelArrays(g,q);p&&g.name&&(p[w]=g.name);n.splice(q,0,a);l&&(this.data.splice(q,0,null),this.processData());"point"===e.legendType&& this.generatePoints();d&&(f[0]&&f[0].remove?f[0].remove(!1):(f.shift(),this.updateParallelArrays(g,"shift"),n.shift()));this.isDirtyData=this.isDirty=!0;c&&k.redraw(h)},removePoint:function(a,c,d){var e=this,h=e.data,f=h[a],k=e.points,p=e.chart,n=function(){k&&k.length===h.length&&k.splice(a,1);h.splice(a,1);e.options.data.splice(a,1);e.updateParallelArrays(f||{series:e},"splice",a,1);f&&f.destroy();e.isDirty=!0;e.isDirtyData=!0;c&&p.redraw()};D(d,p);c=b(c,!0);f?f.firePointEvent("remove",null,n): n()},remove:function(a,c,d){function e(){h.destroy();f.isDirtyLegend=f.isDirtyBox=!0;f.linkSeries();b(a,!0)&&f.redraw(c)}var h=this,f=h.chart;!1!==d?u(h,"remove",null,e):e()},update:function(a,c){var e=this,d=this.chart,h=this.userOptions,f=this.oldType||this.type,p=a.type||h.type||d.options.chart.type,n=t[f].prototype,q=["group","markerGroup","dataLabelsGroup"],g;if(p&&p!==f||void 0!==a.zIndex)q.length=0;l(q,function(a){q[a]=e[a];delete e[a]});a=z(h,{animation:!1,index:this.index,pointStart:this.xData[0]}, {data:this.options.data},a);this.remove(!1,null,!1);for(g in n)this[g]=void 0;k(this,t[p||f].prototype);l(q,function(a){e[a]=q[a]});this.init(d,a);this.oldType=f;d.linkSeries();b(c,!0)&&d.redraw(!1)}});k(H.prototype,{update:function(a,c){var e=this.chart;a=e.options[this.coll][this.options.index]=z(this.userOptions,a);this.destroy(!0);this.init(e,k(a,{events:void 0}));e.isDirtyBox=!0;b(c,!0)&&e.redraw()},remove:function(a){for(var c=this.chart,e=this.coll,d=this.series,h=d.length;h--;)d[h]&&d[h].remove(!1); q(c.axes,this);q(c[e],this);c.options[e].splice(this.options.index,1);l(c[e],function(a,b){a.options.index=b});this.destroy();c.isDirtyBox=!0;b(a,!0)&&c.redraw()},setTitle:function(a,b){this.update({title:a},b)},setCategories:function(a,b){this.update({categories:a},b)}})})(L);(function(a){var B=a.color,A=a.each,H=a.map,G=a.pick,r=a.Series,f=a.seriesType;f("area","line",{softThreshold:!1,threshold:0},{singleStacks:!1,getStackPoints:function(){var a=[],f=[],k=this.xAxis,r=this.yAxis,d=r.stacks[this.stackKey], c={},n=this.points,z=this.index,b=r.series,p=b.length,h,t=G(r.options.reversedStacks,!0)?1:-1,D,w;if(this.options.stacking){for(D=0;Da&&k>f?(k=Math.max(a,f),d=2*f-k):kG&&d>f?(d=Math.max(G,f),k=2*f-d):d=Math.abs(c)&&.5a.closestPointRange*a.xAxis.transA,k=a.borderWidth=l(f.borderWidth,k?0:1),b=a.yAxis,p=a.translatedThreshold=b.getThreshold(f.threshold),h=l(f.minPointLength,5),t=a.getColumnMetrics(),r=t.width,w=a.barW=Math.max(r,1+2*k),e=a.pointXOffset=t.offset;c.inverted&&(p-=.5);f.pointPadding&&(w=Math.ceil(w));q.prototype.translate.apply(a);H(a.points,function(d){var f=l(d.yBottom,p),k=999+Math.abs(f),k=Math.min(Math.max(-k,d.plotY),b.len+k),m=d.plotX+e,n=w,t=Math.min(k,f),q,u= Math.max(k,f)-t;Math.abs(u)h?f-h:p-(q?h:0));d.barX=m;d.pointWidth=r;d.tooltipPos=c.inverted?[b.len+b.pos-c.plotLeft-k,a.xAxis.len-m-n/2,u]:[m+n/2,k+b.pos-c.plotTop,u];d.shapeType="rect";d.shapeArgs=a.crispCol.apply(a,d.isNull?[d.plotX,b.len/2,0,0]:[m,t,n,u])})},getSymbol:a.noop,drawLegendSymbol:a.LegendSymbolMixin.drawRectangle,drawGraph:function(){this.group[this.dense?"addClass":"removeClass"]("highcharts-dense-data")}, pointAttribs:function(a,c){var d=this.options,k,b=this.pointAttrToOptions||{};k=b.stroke||"borderColor";var p=b["stroke-width"]||"borderWidth",h=a&&a.color||this.color,l=a[k]||d[k]||this.color||h,q=a[p]||d[p]||this[p]||0,b=d.dashStyle;a&&this.zones.length&&(h=(h=a.getZone())&&h.color||a.options.color||this.color);c&&(a=f(d.states[c],a.options.states&&a.options.states[c]||{}),c=a.brightness,h=a.color||void 0!==c&&A(h).brighten(a.brightness).get()||h,l=a[k]||l,q=a[p]||q,b=a.dashStyle||b);k={fill:h, stroke:l,"stroke-width":q};d.borderRadius&&(k.r=d.borderRadius);b&&(k.dashstyle=b);return k},drawPoints:function(){var a=this,c=this.chart,k=a.options,l=c.renderer,b=k.animationLimit||250,p;H(a.points,function(d){var h=d.graphic;if(r(d.plotY)&&null!==d.y){p=d.shapeArgs;if(h)h[c.pointCountk;++k)u= l[k],a=2>k||2===k&&/%$/.test(u),l[k]=A(u,[f,G,q,l[2]][k])+(a?r:0);l[3]>l[2]&&(l[3]=l[2]);return l}}})(L);(function(a){var B=a.addEvent,A=a.defined,H=a.each,G=a.extend,r=a.inArray,f=a.noop,l=a.pick,q=a.Point,k=a.Series,u=a.seriesType,d=a.setAnimation;u("pie","line",{center:[null,null],clip:!1,colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return null===this.y?void 0:this.point.name},x:0},ignoreHiddenPoint:!0,legendType:"point",marker:null,size:null,showInLegend:!1,slicedOffset:10, stickyTracking:!1,tooltip:{followPointer:!0},borderColor:"#ffffff",borderWidth:1,states:{hover:{brightness:.1,shadow:!1}}},{isCartesian:!1,requireSorting:!1,directTouch:!0,noSharedTooltip:!0,trackerGroups:["group","dataLabelsGroup"],axisTypes:[],pointAttribs:a.seriesTypes.column.prototype.pointAttribs,animate:function(a){var c=this,d=c.points,b=c.startAngleRad;a||(H(d,function(a){var d=a.graphic,f=a.shapeArgs;d&&(d.attr({r:a.startR||c.center[3]/2,start:b,end:b}),d.animate({r:f.r,start:f.start,end:f.end}, c.options.animation))}),c.animate=null)},updateTotals:function(){var a,d=0,f=this.points,b=f.length,k,h=this.options.ignoreHiddenPoint;for(a=0;ak.y&&(k.y=null),d+=h&&!k.visible?0:k.y;this.total=d;for(a=0;a1.5*Math.PI?q-=2*Math.PI:q<-Math.PI/2&&(q+=2*Math.PI);y.slicedTranslation={translateX:Math.round(Math.cos(q)*b),translateY:Math.round(Math.sin(q)*b)};h=Math.cos(q)*a[2]/2;k=Math.sin(q)*a[2]/2;y.tooltipPos=[a[0]+.7*h,a[1]+.7*k];y.half=q<-Math.PI/2||q>Math.PI/2?1:0;y.angle=q;f=Math.min(f,u/5);y.labelPos=[a[0]+h+Math.cos(q)*u,a[1]+k+Math.sin(q)*u,a[0]+h+Math.cos(q)*f,a[1]+k+Math.sin(q)*f,a[0]+h,a[1]+k,0>u?"center":y.half?"right":"left",q]}},drawGraph:null,drawPoints:function(){var a= this,d=a.chart.renderer,f,b,k,h,l=a.options.shadow;l&&!a.shadowGroup&&(a.shadowGroup=d.g("shadow").add(a.group));H(a.points,function(c){if(null!==c.y){b=c.graphic;h=c.shapeArgs;f=c.getTranslate();var p=c.shadowGroup;l&&!p&&(p=c.shadowGroup=d.g("shadow").add(a.shadowGroup));p&&p.attr(f);k=a.pointAttribs(c,c.selected&&"select");b?b.setRadialReference(a.center).attr(k).animate(G(h,f)):(c.graphic=b=d[c.shapeType](h).setRadialReference(a.center).attr(f).add(a.group),c.visible||b.attr({visibility:"hidden"}), b.attr(k).attr({"stroke-linejoin":"round"}).shadow(l,p));b.addClass(c.getClassName())}})},searchPoint:f,sortByAngle:function(a,d){a.sort(function(a,b){return void 0!==a.angle&&(b.angle-a.angle)*d})},drawLegendSymbol:a.LegendSymbolMixin.drawRectangle,getCenter:a.CenteredSeriesMixin.getCenter,getSymbol:f},{init:function(){q.prototype.init.apply(this,arguments);var a=this,d;a.name=l(a.name,"Slice");d=function(c){a.slice("select"===c.type)};B(a,"select",d);B(a,"unselect",d);return a},setVisible:function(a, d){var c=this,b=c.series,f=b.chart,h=b.options.ignoreHiddenPoint;d=l(d,h);a!==c.visible&&(c.visible=c.options.visible=a=void 0===a?!c.visible:a,b.options.data[r(c,b.data)]=c.options,H(["graphic","dataLabel","connector","shadowGroup"],function(b){if(c[b])c[b][a?"show":"hide"](!0)}),c.legendItem&&f.legend.colorizeItem(c,a),a||"hover"!==c.state||c.setState(""),h&&(b.isDirty=!0),d&&f.redraw())},slice:function(a,f,k){var b=this.series;d(k,b.chart);l(f,!0);this.sliced=this.options.sliced=A(a)?a:!this.sliced; b.options.data[r(this,b.data)]=this.options;this.graphic.animate(this.getTranslate());this.shadowGroup&&this.shadowGroup.animate(this.getTranslate())},getTranslate:function(){return this.sliced?this.slicedTranslation:{translateX:0,translateY:0}},haloPath:function(a){var c=this.shapeArgs;return this.sliced||!this.visible?[]:this.series.chart.renderer.symbols.arc(c.x,c.y,c.r+a,c.r+a,{innerR:this.shapeArgs.r,start:c.start,end:c.end})}})})(L);(function(a){var B=a.addEvent,A=a.arrayMax,H=a.defined,G=a.each, r=a.extend,f=a.format,l=a.map,q=a.merge,k=a.noop,u=a.pick,d=a.relativeLength,c=a.Series,n=a.seriesTypes,z=a.stableSort;a.distribute=function(a,c){function b(a,b){return a.target-b.target}var d,f=!0,k=a,e=[],p;p=0;for(d=a.length;d--;)p+=a[d].size;if(p>c){z(a,function(a,b){return(b.rank||0)-(a.rank||0)});for(p=d=0;p<=c;)p+=a[d].size,d++;e=a.splice(d-1,a.length)}z(a,b);for(a=l(a,function(a){return{size:a.size,targets:[a.target]}});f;){for(d=a.length;d--;)f=a[d],p=(Math.min.apply(0,f.targets)+Math.max.apply(0, f.targets))/2,f.pos=Math.min(Math.max(0,p-f.size/2),c-f.size);d=a.length;for(f=!1;d--;)0a[d].pos&&(a[d-1].size+=a[d].size,a[d-1].targets=a[d-1].targets.concat(a[d].targets),a[d-1].pos+a[d-1].size>c&&(a[d-1].pos=c-a[d-1].size),a.splice(d,1),f=!0)}d=0;G(a,function(a){var b=0;G(a.targets,function(){k[d].pos=a.pos+b;b+=k[d].size;d++})});k.push.apply(k,e);z(k,b)};c.prototype.drawDataLabels=function(){var a=this,c=a.options,d=c.dataLabels,k=a.points,l,n,e=a.hasRendered||0,r,C, E=u(d.defer,!0),m=a.chart.renderer;if(d.enabled||a._hasPointLabels)a.dlProcessOptions&&a.dlProcessOptions(d),C=a.plotGroup("dataLabelsGroup","data-labels",E&&!e?"hidden":"visible",d.zIndex||6),E&&(C.attr({opacity:+e}),e||B(a,"afterAnimate",function(){a.visible&&C.show(!0);C[c.animation?"animate":"attr"]({opacity:1},{duration:200})})),n=d,G(k,function(b){var e,h=b.dataLabel,k,g,p,t=b.connector,w=!h,x;l=b.dlOptions||b.options&&b.options.dataLabels;if(e=u(l&&l.enabled,n.enabled)&&null!==b.y)for(g in d= q(n,l),k=b.getLabelConfig(),r=d.format?f(d.format,k):d.formatter.call(k,d),x=d.style,p=d.rotation,x.color=u(d.color,x.color,a.color,"#000000"),"contrast"===x.color&&(b.contrastColor=m.getContrast(b.color||a.color),x.color=d.inside||0>d.distance||c.stacking?b.contrastColor:"#000000"),c.cursor&&(x.cursor=c.cursor),k={fill:d.backgroundColor,stroke:d.borderColor,"stroke-width":d.borderWidth,r:d.borderRadius||0,rotation:p,padding:d.padding,zIndex:1},k)void 0===k[g]&&delete k[g];!h||e&&H(r)?e&&H(r)&&(h? k.text=r:(h=b.dataLabel=m[p?"text":"label"](r,0,-9999,d.shape,null,null,d.useHTML,null,"data-label"),h.addClass("highcharts-data-label-color-"+b.colorIndex+" "+(d.className||"")+(d.useHTML?"highcharts-tracker":""))),h.attr(k),h.css(x).shadow(d.shadow),h.added||h.add(C),a.alignDataLabel(b,h,d,null,w)):(b.dataLabel=h.destroy(),t&&(b.connector=t.destroy()))})};c.prototype.alignDataLabel=function(a,c,d,f,k){var b=this.chart,e=b.inverted,h=u(a.plotX,-9999),l=u(a.plotY,-9999),p=c.getBBox(),m,n=d.rotation, q=d.align,t=this.visible&&(a.series.forceDL||b.isInsidePlot(h,Math.round(l),e)||f&&b.isInsidePlot(h,e?f.x+1:f.y+f.height-1,e)),D="justify"===u(d.overflow,"justify");t&&(m=d.style.fontSize,m=b.renderer.fontMetrics(m,c).b,f=r({x:e?b.plotWidth-l:h,y:Math.round(e?b.plotHeight-h:l),width:0,height:0},f),r(d,{width:p.width,height:p.height}),n?(D=!1,e=b.renderer.rotCorr(m,n),e={x:f.x+d.x+f.width/2+e.x,y:f.y+d.y+{top:0,middle:.5,bottom:1}[d.verticalAlign]*f.height},c[k?"attr":"animate"](e).attr({align:q}), h=(n+720)%360,h=180h,"left"===q?e.y-=h?p.height:0:"center"===q?(e.x-=p.width/2,e.y-=p.height/2):"right"===q&&(e.x-=p.width,e.y-=h?0:p.height)):(c.align(d,null,f),e=c.alignAttr),D?a.isLabelJustified=this.justifyDataLabel(c,d,e,p,f,k):u(d.crop,!0)&&(t=b.isInsidePlot(e.x,e.y)&&b.isInsidePlot(e.x+p.width,e.y+p.height)),d.shape&&!n&&c.attr({anchorX:a.plotX,anchorY:a.plotY}));t||(c.attr({y:-9999}),c.placed=!1)};c.prototype.justifyDataLabel=function(a,c,d,f,k,l){var b=this.chart,h=c.align,p=c.verticalAlign, n,m,q=a.box?0:a.padding||0;n=d.x+q;0>n&&("right"===h?c.align="left":c.x=-n,m=!0);n=d.x+f.width-q;n>b.plotWidth&&("left"===h?c.align="right":c.x=b.plotWidth-n,m=!0);n=d.y+q;0>n&&("bottom"===p?c.verticalAlign="top":c.y=-n,m=!0);n=d.y+f.height-q;n>b.plotHeight&&("top"===p?c.verticalAlign="bottom":c.y=b.plotHeight-n,m=!0);m&&(a.placed=!l,a.align(c,null,k));return m};n.pie&&(n.pie.prototype.drawDataLabels=function(){var b=this,d=b.data,f,k=b.chart,n=b.options.dataLabels,q=u(n.connectorPadding,10),e=u(n.connectorWidth, 1),r=k.plotWidth,C=k.plotHeight,E,m=n.distance,y=b.center,z=y[2]/2,B=y[1],H=0h-2?w:v,e),g._attr={visibility:M,align:L[6]},g._pos={x:O+n.x+({left:q,right:-q}[L[6]]||0),y:v+ n.y-10},L.x=O,L.y=v,null===b.options.size&&(F=g.getBBox().width,w=null,O-Fr-q&&(w=Math.round(O+F-r+q),S[1]=Math.max(w,S[1])),0>v-N/2?S[0]=Math.max(Math.round(-v+N/2),S[0]):v+N/2>C&&(S[2]=Math.max(Math.round(v+N/2-C),S[2])),g.sideOverflow=w)}),0===A(S)||this.verifyDataLabelOverflow(S))&&(this.placeDataLabels(),H&&e&&G(this.points,function(a){var c;E=a.connector;if((g=a.dataLabel)&&g._pos&&a.visible){M=g._attr.visibility;if(c=!E)a.connector=E=k.renderer.path().addClass("highcharts-data-label-connector highcharts-color-"+ a.colorIndex).add(b.dataLabelsGroup),E.attr({"stroke-width":e,stroke:n.connectorColor||a.color||"#666666"});E[c?"attr":"animate"]({d:b.connectorPath(a.labelPos)});E.attr("visibility",M)}else E&&(a.connector=E.destroy())}))},n.pie.prototype.connectorPath=function(a){var b=a.x,c=a.y;return u(this.options.dataLabels.softConnector,!0)?["M",b+("left"===a[6]?5:-5),c,"C",b,c,2*a[2]-a[4],2*a[3]-a[5],a[2],a[3],"L",a[4],a[5]]:["M",b+("left"===a[6]?5:-5),c,"L",a[2],a[3],"L",a[4],a[5]]},n.pie.prototype.placeDataLabels= function(){G(this.points,function(a){var b=a.dataLabel;b&&a.visible&&((a=b._pos)?(b.sideOverflow&&(b._attr.width=b.getBBox().width-b.sideOverflow,b.css({width:b._attr.width+"px",textOverflow:"ellipsis"}),b.shortened=!0),b.attr(b._attr),b[b.moved?"animate":"attr"](a),b.moved=!0):b&&b.attr({y:-9999}))},this)},n.pie.prototype.alignDataLabel=k,n.pie.prototype.verifyDataLabelOverflow=function(a){var b=this.center,c=this.options,f=c.center,k=c.minSize||80,l,e;null!==f[0]?l=Math.max(b[2]-Math.max(a[1],a[3]), k):(l=Math.max(b[2]-a[1]-a[3],k),b[0]+=(a[3]-a[1])/2);null!==f[1]?l=Math.max(Math.min(l,b[2]-Math.max(a[0],a[2])),k):(l=Math.max(Math.min(l,b[2]-a[0]-a[2]),k),b[1]+=(a[0]-a[2])/2);lu(this.translatedThreshold,e.yAxis.len)),p=u(f.inside, !!this.options.stacking);h&&(k=q(h),0>k.y&&(k.height+=k.y,k.y=0),h=k.y+k.height-e.yAxis.len,0a+c||e+kb+d||f+lthis.pointCount))},pan:function(a,b){var c=this,d=c.hoverPoints,e;d&&l(d,function(a){a.setState()});l("xy"===b?[1,0]:[1],function(b){b=c[b?"xAxis":"yAxis"][0];var d=b.horiz,f=a[d?"chartX":"chartY"],d=d? "mouseDownX":"mouseDownY",h=c[d],k=(b.pointRange||0)/2,g=b.getExtremes(),l=b.toValue(h-f,!0)+k,k=b.toValue(h+b.len-f,!0)-k,m=km&&0>g&&(b.setExtremes(h,l,!1,!1,{trigger:"pan"}),e=!0);c[d]=f});e&&c.redraw(!1);G(c.container,{cursor:"move"})}});q(p.prototype,{select:function(a,c){var e=this,f=e.series,h=f.chart;a=b(a, !e.selected);e.firePointEvent(a?"select":"unselect",{accumulate:c},function(){e.selected=e.options.selected=a;f.options.data[d(e,f.data)]=e.options;e.setState(a&&"select");c||l(h.getSelectedPoints(),function(a){a.selected&&a!==e&&(a.selected=a.options.selected=!1,f.options.data[d(a,f.data)]=a.options,a.setState(""),a.firePointEvent("unselect"))})})},onMouseOver:function(a){var b=this.series.chart.pointer;this.firePointEvent("mouseOver");b.runPointActions(a,this)},onMouseOut:function(){var a=this.series.chart; this.firePointEvent("mouseOut");l(a.hoverPoints||[],function(a){a.setState()});a.hoverPoints=a.hoverPoint=null},importEvents:function(){if(!this.hasImportedEvents){var a=z(this.series.options.point,this.options).events,b;this.events=a;for(b in a)B(this,b,a[b]);this.hasImportedEvents=!0}},setState:function(a,c){var d=Math.floor(this.plotX),e=this.plotY,h=this.series,k=h.options.states[a]||{},l=f[h.type].marker&&h.options.marker,n=l&&!1===l.enabled,p=l&&l.states&&l.states[a]||{},r=!1===p.enabled,g= h.stateMarkerGraphic,t=this.marker||{},u=h.chart,w=h.halo,z,A=l&&h.markerAttribs;a=a||"";if(!(a===this.state&&!c||this.selected&&"select"!==a||!1===k.enabled||a&&(r||n&&!1===p.enabled)||a&&t.states&&t.states[a]&&!1===t.states[a].enabled)){A&&(z=h.markerAttribs(this,a));if(this.graphic)this.state&&this.graphic.removeClass("highcharts-point-"+this.state),a&&this.graphic.addClass("highcharts-point-"+a),this.graphic.attr(h.pointAttribs(this,a)),z&&this.graphic.animate(z,b(u.options.chart.animation,p.animation, l.animation)),g&&g.hide();else{if(a&&p){l=t.symbol||h.symbol;g&&g.currentSymbol!==l&&(g=g.destroy());if(g)g[c?"animate":"attr"]({x:z.x,y:z.y});else l&&(h.stateMarkerGraphic=g=u.renderer.symbol(l,z.x,z.y,z.width,z.height).add(h.markerGroup),g.currentSymbol=l);g&&g.attr(h.pointAttribs(this,a))}g&&(g[a&&u.isInsidePlot(d,e,u.inverted)?"show":"hide"](),g.element.point=this)}(d=k.halo)&&d.size?(w||(h.halo=w=u.renderer.path().add(A?h.markerGroup:h.group)),w[c?"animate":"attr"]({d:this.haloPath(d.size)}), w.attr({"class":"highcharts-halo highcharts-color-"+b(this.colorIndex,h.colorIndex)}),w.point=this,w.attr(q({fill:this.color||h.color,"fill-opacity":d.opacity,zIndex:-1},d.attributes))):w&&w.point&&w.point.haloPath&&w.animate({d:w.point.haloPath(0)});this.state=a}},haloPath:function(a){return this.series.chart.renderer.symbols.circle(Math.floor(this.plotX)-a,this.plotY-a,2*a,2*a)}});q(h.prototype,{onMouseOver:function(){var a=this.chart,b=a.hoverSeries;if(b&&b!==this)b.onMouseOut();this.options.events.mouseOver&& k(this,"mouseOver");this.setState("hover");a.hoverSeries=this},onMouseOut:function(){var a=this.options,b=this.chart,c=b.tooltip,d=b.hoverPoint;b.hoverSeries=null;if(d)d.onMouseOut();this&&a.events.mouseOut&&k(this,"mouseOut");!c||this.stickyTracking||c.shared&&!this.noSharedTooltip||c.hide();this.setState()},setState:function(a){var c=this,d=c.options,f=c.graph,h=d.states,k=d.lineWidth,d=0;a=a||"";if(c.state!==a&&(l([c.group,c.markerGroup,c.dataLabelsGroup],function(b){b&&(c.state&&b.removeClass("highcharts-series-"+ c.state),a&&b.addClass("highcharts-series-"+a))}),c.state=a,!h[a]||!1!==h[a].enabled)&&(a&&(k=h[a].lineWidth||k+(h[a].lineWidthPlus||0)),f&&!f.dashstyle))for(k={"stroke-width":k},f.animate(k,b(c.chart.options.chart.animation,h[a]&&h[a].animation));c["zone-graph-"+d];)c["zone-graph-"+d].attr(k),d+=1},setVisible:function(a,b){var c=this,d=c.chart,e=c.legendItem,f,h=d.options.chart.ignoreHiddenSeries,n=c.visible;f=(c.visible=a=c.options.visible=c.userOptions.visible=void 0===a?!n:a)?"show":"hide";l(["group", "dataLabelsGroup","markerGroup","tracker","tt"],function(a){if(c[a])c[a][f]()});if(d.hoverSeries===c||(d.hoverPoint&&d.hoverPoint.series)===c)c.onMouseOut();e&&d.legend.colorizeItem(c,a);c.isDirty=!0;c.options.stacking&&l(d.series,function(a){a.options.stacking&&a.visible&&(a.isDirty=!0)});l(c.linkedSeries,function(b){b.setVisible(a,!1)});h&&(d.isDirtyBox=!0);!1!==b&&d.redraw();k(c,f)},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},select:function(a){this.selected=a=void 0=== a?!this.selected:a;this.checkbox&&(this.checkbox.checked=a);k(this,a?"select":"unselect")},drawTracker:a.drawTrackerGraph})})(L);(function(a){var B=a.Chart,A=a.each,H=a.inArray,G=a.isArray,r=a.isObject,f=a.pick,l=a.splat;B.prototype.setResponsive=function(f){var k=this.options.responsive,l=[],d=this.currentResponsive;k&&k.rules&&A(k.rules,function(c){void 0===c._id&&(c._id=a.uniqueKey());this.matchResponsiveRule(c,l,f)},this);var c=a.merge.apply(0,a.map(l,function(c){return a.find(k.rules,function(a){return a._id=== c}).chartOptions})),l=l.toString()||void 0;l!==(d&&d.ruleIds)&&(d&&this.update(d.undoOptions,f),l?(this.currentResponsive={ruleIds:l,mergedOptions:c,undoOptions:this.currentOptions(c)},this.update(c,f)):this.currentResponsive=void 0)};B.prototype.matchResponsiveRule=function(a,k){var l=a.condition;(l.callback||function(){return this.chartWidth<=f(l.maxWidth,Number.MAX_VALUE)&&this.chartHeight<=f(l.maxHeight,Number.MAX_VALUE)&&this.chartWidth>=f(l.minWidth,0)&&this.chartHeight>=f(l.minHeight,0)}).call(this)&& k.push(a._id)};B.prototype.currentOptions=function(a){function f(a,c,k,q){var b,d;for(b in a)if(!q&&-1 rule.test) ignoreCustomFragments: any[] }; /** * error events. Work only if bail is false */ onerror: any, /** * template file loader */ loader: any, /** * cache center adapter (depend on filename field) */ caches: any, /** * root directory of template. If filename field is not a local path, template will be found in root directory * @default '/' */ root: string; /** * @default '.art' * default extension. If no extensions, extname will be automatically added */ extname: string, /** * ignored variables. An array of template variables ignored by template compiler */ ignore: any[], // imported template variables imports: { [key: string]: Function } } /** * * @param filenameOrTemplateId [ for bowser ] id of template [ for Node ] fileName of template * @param content [ if is Object ] return compile result , [ if is string ] return compile Funtion */ declare function artTemplate(filenameOrTemplateId: string, content?: string | Object): any; declare namespace artTemplate { export const defaults: artTemplateDefaults; export const extension: { [key: string]: Function }; function render(source: string, data: any, options?: any): string; function compile(source: string, options?: any): (data: any) => string; } export = artTemplate; ================================================ FILE: index.js ================================================ const template = require('./lib/index'); const extension = require('./lib/extension'); template.extension = extension; require.extensions[template.defaults.extname] = extension; module.exports = template; ================================================ FILE: package.json ================================================ { "name": "art-template", "typings": "index.d.ts", "description": "JavaScript Template Engine", "homepage": "http://aui.github.com/art-template/", "version": "4.13.2", "keywords": [ "template" ], "author": "tangbin ", "repository": { "type": "git", "url": "git://github.com/aui/art-template.git" }, "scripts": { "build": "npm run build-lib && npm run build-web", "build-lib": "rm -rf lib && babel src --out-dir lib", "build-web": "export NODE_ENV=production && webpack", "dev": "babel src --watch --out-dir lib", "test": "export NODE_ENV=production && istanbul cover node_modules/mocha/bin/_mocha -- --ui exports --colors 'test/**/*.js'", "coverage": "cat ./coverage/lcov.info | coveralls" }, "main": "index.js", "files": [ "lib/", "index.d.ts" ], "engines": { "node": ">= 1.0.0" }, "dependencies": { "acorn": "^5.0.3", "escodegen": "^1.8.1", "estraverse": "^4.2.0", "html-minifier": "^3.4.3", "is-keyword-js": "^1.0.3", "js-tokens": "^3.0.1", "merge-source-map": "^1.0.3", "source-map": "^0.5.6" }, "devDependencies": { "babel-cli": "^6.26.0", "babel-preset-env": "^1.7.0", "coveralls": "^2.13.0", "eslint": "^3.19.0", "eslint-loader": "^1.7.1", "eslint-plugin-prettier": "^2.6.2", "istanbul": "^0.4.5", "mocha": "^5.2.0", "node-noop": "^1.0.0", "prettier": "^1.14.2", "webpack": "^3.0.0" }, "license": "MIT" } ================================================ FILE: src/compile/adapter/caches.js ================================================ const caches = { __data: Object.create(null), set: function(key, val) { this.__data[key] = val; }, get: function(key) { return this.__data[key]; }, reset: function() { this.__data = {}; } }; module.exports = caches; ================================================ FILE: src/compile/adapter/extend.js ================================================ const toString = Object.prototype.toString; const toType = value => { // Null: 兼容 IE8 return value === null ? 'Null' : toString.call(value).slice(8, -1); }; /** * 快速继承默认配置 * @param {Object} options * @param {?Object} defaults * @return {Object} */ const extend = function(target, defaults) { let object; const type = toType(target); if (type === 'Object') { object = Object.create(defaults || {}); } else if (type === 'Array') { object = [].concat(defaults || []); } if (object) { for (let index in target) { if (Object.hasOwnProperty.call(target, index)) { object[index] = extend(target[index], object[index]); } } return object; } else { return target; } }; module.exports = extend; ================================================ FILE: src/compile/adapter/html-minifier.js ================================================ const detectNode = typeof window === 'undefined'; /** * HTML 压缩器 * @param {string} source * @param {Object} options * @return {string} */ const htmlMinifier = (source, options) => { if (detectNode) { const htmlMinifier = require('html-minifier').minify; const htmlMinifierOptions = options.htmlMinifierOptions; const ignoreCustomFragments = options.rules.map(rule => rule.test); htmlMinifierOptions.ignoreCustomFragments.push(...ignoreCustomFragments); source = htmlMinifier(source, htmlMinifierOptions); } return source; }; module.exports = htmlMinifier; ================================================ FILE: src/compile/adapter/include.js ================================================ /** * 载入子模板 * @param {string} filename * @param {Object} data * @param {Object} blocks * @param {Object} options * @return {string} */ const include = (filename, data, blocks, options) => { const compile = require('../index'); options = options.$extend({ filename: options.resolveFilename(filename, options), bail: true, source: null }); return compile(options)(data, blocks); }; module.exports = include; ================================================ FILE: src/compile/adapter/loader.js ================================================ const detectNode = typeof window === 'undefined'; /** * 读取模板内容(同步方法) * @param {string} filename 模板名 * @param {?Object} options * @return {string} */ const loader = (filename /*, options*/) => { /* istanbul ignore else */ if (detectNode) { const fs = require('fs'); return fs.readFileSync(filename, 'utf8'); } else { const elem = document.getElementById(filename); return elem.value || elem.innerHTML; } }; module.exports = loader; ================================================ FILE: src/compile/adapter/onerror.js ================================================ /** * 调试器 * @param {Object} error * @param {?Object} options * @return {string} */ const onerror = (error /*, options*/) => { console.error(error.name, error.message); }; module.exports = onerror; ================================================ FILE: src/compile/adapter/resolve-filename.js ================================================ const detectNode = typeof window === 'undefined'; const LOCAL_MODULE = /^\.+\//; /** * 获取模板的绝对路径 * @param {string} filename * @param {Object} options * @return {string} */ const resolveFilename = (filename, options) => { /* istanbul ignore else */ if (detectNode) { const path = require('path'); const root = options.root; const extname = options.extname; if (LOCAL_MODULE.test(filename)) { const from = options.filename; const self = !from || filename === from; const base = self ? root : path.dirname(from); filename = path.resolve(base, filename); } else { filename = path.resolve(root, filename); } if (!path.extname(filename)) { filename = filename + extname; } } return filename; }; module.exports = resolveFilename; ================================================ FILE: src/compile/adapter/rule.art.js ================================================ /** * 简洁模板语法规则 */ const artRule = { test: /{{([@#]?)[ \t]*(\/?)([\w\W]*?)[ \t]*}}/, use: function(match, raw, close, code) { const compiler = this; const options = compiler.options; const esTokens = compiler.getEsTokens(code); const values = esTokens.map(token => token.value); const result = {}; let group; let output = raw ? 'raw' : false; let key = close + values.shift(); // 旧版语法升级提示 const warn = (oldSyntax, newSyntax) => { console.warn( `${options.filename || 'anonymous'}:${match.line + 1}:${match.start + 1}\n` + `Template upgrade: {{${oldSyntax}}} -> {{${newSyntax}}}` ); }; // v3 compat: #value if (raw === '#') { warn('#value', '@value'); } switch (key) { case 'set': code = `var ${values.join('').trim()}`; break; case 'if': code = `if(${values.join('').trim()}){`; break; case 'else': const indexIf = values.indexOf('if'); if (~indexIf) { values.splice(0, indexIf + 1); code = `}else if(${values.join('').trim()}){`; } else { code = `}else{`; } break; case '/if': code = '}'; break; case 'each': group = artRule._split(esTokens); group.shift(); if (group[1] === 'as') { // ... v3 compat ... warn('each object as value index', 'each object value index'); group.splice(1, 1); } const object = group[0] || '$data'; const value = group[1] || '$value'; const index = group[2] || '$index'; code = `$each(${object},function(${value},${index}){`; break; case '/each': code = '})'; break; case 'block': group = artRule._split(esTokens); group.shift(); code = `block(${group.join(',').trim()},function(){`; break; case '/block': code = '})'; break; case 'echo': key = 'print'; warn('echo value', 'value'); case 'print': case 'include': case 'extend': if ( values .join('') .trim() .indexOf('(') !== 0 ) { // 执行函数省略 `()` 与 `,` group = artRule._split(esTokens); group.shift(); code = `${key}(${group.join(',')})`; break; } default: if (~values.indexOf('|')) { const v3split = ':'; // ... v3 compat ... // 将过滤器解析成二维数组 const group = esTokens .reduce((group, token) => { const { value, type } = token; if (value === '|') { group.push([]); } else if (type !== `whitespace` && type !== `comment`) { if (!group.length) { group.push([]); } if (value === v3split && group[group.length - 1].length === 1) { warn('value | filter: argv', 'value | filter argv'); } else { group[group.length - 1].push(token); } } return group; }, []) .map(g => artRule._split(g)); // 将过滤器管道化 code = group.reduce( (accumulator, filter) => { const name = filter.shift(); filter.unshift(accumulator); return `$imports.${name}(${filter.join(',')})`; }, group .shift() .join(` `) .trim() ); } output = output || 'escape'; break; } result.code = code; result.output = output; return result; }, // 将多个 javascript 表达式拆分成组 // 支持基本运算、三元表达式、取值、运行函数,不支持 `typeof value` 操作 // 只支持 string、number、boolean、null、undefined 这几种类型声明,不支持 function、object、array _split: esTokens => { esTokens = esTokens.filter(({ type }) => { return type !== `whitespace` && type !== `comment`; }); let current = 0; let lastToken = esTokens.shift(); const punctuator = `punctuator`; const close = /\]|\)/; const group = [[lastToken]]; while (current < esTokens.length) { const esToken = esTokens[current]; if ( esToken.type === punctuator || (lastToken.type === punctuator && !close.test(lastToken.value)) ) { group[group.length - 1].push(esToken); } else { group.push([esToken]); } lastToken = esToken; current++; } return group.map(g => g.map(g => g.value).join(``)); } }; module.exports = artRule; ================================================ FILE: src/compile/adapter/rule.native.js ================================================ /** * 原生模板语法规则 */ const nativeRule = { test: /<%(#?)((?:==|=#|[=-])?)[ \t]*([\w\W]*?)[ \t]*(-?)%>/, use: (match, comment, output, code /*, trimMode*/) => { output = { '-': 'raw', '=': 'escape', '': false, // v3 compat: raw output '==': 'raw', '=#': 'raw' }[output]; // ejs compat: comment tag if (comment) { code = `/*${code}*/`; output = false; } // ejs compat: trims following newline // if (trimMode) {} return { code, output }; } }; module.exports = nativeRule; ================================================ FILE: src/compile/compiler.js ================================================ const esTokenizer = require('./es-tokenizer'); const tplTokenizer = require('./tpl-tokenizer'); /** 传递给模板的数据引用 */ const DATA = `$data`; /** 外部导入的所有全局变量引用 */ const IMPORTS = `$imports`; /** $imports.$escape */ const ESCAPE = `$escape`; /** $imports.$each */ const EACH = `$each`; /** 文本输出函数 */ const PRINT = `print`; /** 包含子模板函数 */ const INCLUDE = `include`; /** 继承布局模板函数 */ const EXTEND = `extend`; /** “模板块”读写函数 */ const BLOCK = `block`; /** 字符串拼接变量 */ const OUT = `$$out`; /** 运行时逐行调试记录变量 [line, start, source] */ const LINE = `$$line`; /** 所有“模板块”变量 */ const BLOCKS = `$$blocks`; /** 截取模版输出“流”的函数 */ const SLICE = `$$slice`; /** 继承的布局模板的文件地址变量 */ const FROM = `$$from`; /** 编译设置变量 */ const OPTIONS = `$$options`; const has = (object, key) => Object.hasOwnProperty.call(object, key); const stringify = JSON.stringify; class Compiler { /** * 模板编译器 * @param {Object} options */ constructor(options) { let source = options.source; const minimize = options.minimize; const htmlMinifier = options.htmlMinifier; // 编译选项 this.options = options; // 所有语句堆栈 this.stacks = []; // 运行时注入的上下文 this.context = []; // 模板语句编译后的代码 this.scripts = []; // context map this.CONTEXT_MAP = {}; // 忽略的变量名单 this.ignore = [DATA, IMPORTS, OPTIONS, ...options.ignore]; // 按需编译到模板渲染函数的内置变量 this.internal = { [OUT]: `''`, [LINE]: `[0,0]`, [BLOCKS]: `arguments[1]||{}`, [FROM]: `null`, [PRINT]: `function(){var s=''.concat.apply('',arguments);${OUT}+=s;return s}`, [INCLUDE]: `function(src,data){var s=${OPTIONS}.include(src,data||${DATA},arguments[2]||${BLOCKS},${OPTIONS});${OUT}+=s;return s}`, [EXTEND]: `function(from){${FROM}=from}`, [SLICE]: `function(c,p,s){p=${OUT};${OUT}='';c();s=${OUT};${OUT}=p+s;return s}`, [BLOCK]: `function(){var a=arguments,s;if(typeof a[0]==='function'){return ${SLICE}(a[0])}else if(${FROM}){if(!${BLOCKS}[a[0]]){${BLOCKS}[a[0]]=${SLICE}(a[1])}else{${OUT}+=${BLOCKS}[a[0]]}}else{s=${BLOCKS}[a[0]];if(typeof s==='string'){${OUT}+=s}else{s=${SLICE}(a[1])}return s}}` }; // 内置函数依赖关系声明 this.dependencies = { [PRINT]: [OUT], [INCLUDE]: [OUT, OPTIONS, DATA, BLOCKS], [EXTEND]: [FROM, /*[*/ INCLUDE /*]*/], [BLOCK]: [SLICE, FROM, OUT, BLOCKS] }; this.importContext(OUT); if (options.compileDebug) { this.importContext(LINE); } if (minimize) { try { source = htmlMinifier(source, options); } catch (error) {} } this.source = source; this.getTplTokens(source, options.rules, this).forEach(tokens => { if (tokens.type === tplTokenizer.TYPE_STRING) { this.parseString(tokens); } else { this.parseExpression(tokens); } }); } /** * 将模板代码转换成 tplToken 数组 * @param {string} source * @return {Object[]} */ getTplTokens(...args) { return tplTokenizer(...args); } /** * 将模板表达式转换成 esToken 数组 * @param {string} source * @return {Object[]} */ getEsTokens(source) { return esTokenizer(source); } /** * 获取变量列表 * @param {Object[]} esTokens * @return {string[]} */ getVariables(esTokens) { let ignore = false; return esTokens .filter(esToken => { return esToken.type !== `whitespace` && esToken.type !== `comment`; }) .filter(esToken => { if (esToken.type === `name` && !ignore) { return true; } ignore = esToken.type === `punctuator` && esToken.value === `.`; return false; }) .map(tooken => tooken.value); } /** * 导入模板上下文 * @param {string} name */ importContext(name) { let value = ``; const internal = this.internal; const dependencies = this.dependencies; const ignore = this.ignore; const context = this.context; const options = this.options; const imports = options.imports; const contextMap = this.CONTEXT_MAP; if (!has(contextMap, name) && ignore.indexOf(name) === -1) { if (has(internal, name)) { value = internal[name]; if (has(dependencies, name)) { dependencies[name].forEach(name => this.importContext(name)); } // imports 继承了 Global,但是继承的属性不分配到顶级变量中,避免占用了模板内部的变量名称 } else if (name === ESCAPE || name === EACH || has(imports, name)) { value = `${IMPORTS}.${name}`; } else { value = `${DATA}.${name}`; } contextMap[name] = value; context.push({ name, value }); } } /** * 解析字符串(HTML)直接输出语句 * @param {Object} tplToken */ parseString(tplToken) { let source = tplToken.value; if (!source) { return; } const code = `${OUT}+=${stringify(source)}`; this.scripts.push({ source, tplToken, code }); } /** * 解析逻辑表达式语句 * @param {Object} tplToken */ parseExpression(tplToken) { const source = tplToken.value; const script = tplToken.script; const output = script.output; const escape = this.options.escape; let code = script.code; if (output) { if (escape === false || output === tplTokenizer.TYPE_RAW) { code = `${OUT}+=${script.code}`; } else { code = `${OUT}+=${ESCAPE}(${script.code})`; } } const esToken = this.getEsTokens(code); this.getVariables(esToken).forEach(name => this.importContext(name)); this.scripts.push({ source, tplToken, code }); } /** * 检查解析后的模板语句是否存在语法错误 * @param {string} script * @return {boolean} */ checkExpression(script) { // 没有闭合的块级模板语句规则 // 基于正则规则来补全语法不能保证 100% 准确, // 但是在绝大多数情况下足以满足辅助开发调试的需要 const rules = [ // <% } %> // <% }else{ %> // <% }else if(a){ %> [/^\s*}[\w\W]*?{?[\s;]*$/, ''], // <% fn(c,function(a,b){ %> // <% fn(c, a=>{ %> // <% fn(c,(a,b)=>{ %> [/(^[\w\W]*?\([\w\W]*?(?:=>|\([\w\W]*?\))\s*{[\s;]*$)/, '$1})'], // <% if(a){ %> // <% for(var i in d){ %> [/(^[\w\W]*?\([\w\W]*?\)\s*{[\s;]*$)/, '$1}'] ]; let index = 0; while (index < rules.length) { if (rules[index][0].test(script)) { script = script.replace(...rules[index]); break; } index++; } try { new Function(script); return true; } catch (e) { return false; } } /** * 编译 * @return {function} */ build() { const options = this.options; const context = this.context; const scripts = this.scripts; const stacks = this.stacks; const source = this.source; const filename = options.filename; const imports = options.imports; const mappings = []; const extendMode = has(this.CONTEXT_MAP, EXTEND); let offsetLine = 0; // Create SourceMap: mapping const mapping = (code, { line, start }) => { const node = { generated: { line: stacks.length + offsetLine + 1, column: 1 }, original: { line: line + 1, column: start + 1 } }; offsetLine += code.split(/\n/).length - 1; return node; }; // Trim code const trim = code => { return code.replace(/^[\t ]+|[\t ]$/g, ''); }; stacks.push(`function(${DATA}){`); stacks.push(`'use strict'`); stacks.push(`${DATA}=${DATA}||{}`); stacks.push(`var ` + context.map(({ name, value }) => `${name}=${value}`).join(`,`)); if (options.compileDebug) { stacks.push(`try{`); scripts.forEach(script => { if (script.tplToken.type === tplTokenizer.TYPE_EXPRESSION) { stacks.push( `${LINE}=[${[script.tplToken.line, script.tplToken.start].join(',')}]` ); } mappings.push(mapping(script.code, script.tplToken)); stacks.push(trim(script.code)); }); stacks.push(`}catch(error){`); stacks.push( 'throw {' + [ `name:'RuntimeError'`, `path:${stringify(filename)}`, `message:error.message`, `line:${LINE}[0]+1`, `column:${LINE}[1]+1`, `source:${stringify(source)}`, `stack:error.stack` ].join(`,`) + '}' ); stacks.push(`}`); } else { scripts.forEach(script => { mappings.push(mapping(script.code, script.tplToken)); stacks.push(trim(script.code)); }); } if (extendMode) { stacks.push(`${OUT}=''`); stacks.push(`${INCLUDE}(${FROM},${DATA},${BLOCKS})`); } stacks.push(`return ${OUT}`); stacks.push(`}`); const renderCode = stacks.join(`\n`); try { const result = new Function(IMPORTS, OPTIONS, `return ${renderCode}`)(imports, options); result.mappings = mappings; result.sourcesContent = [source]; return result; } catch (error) { let index = 0; let line = 0; let start = 0; let generated; while (index < scripts.length) { const current = scripts[index]; if (!this.checkExpression(current.code)) { line = current.tplToken.line; start = current.tplToken.start; generated = current.code; break; } index++; } throw { name: `CompileError`, path: filename, message: error.message, line: line + 1, column: start + 1, source, generated, stack: error.stack }; } } } /** * 模板内置常量 */ Compiler.CONSTS = { DATA, IMPORTS, PRINT, INCLUDE, EXTEND, BLOCK, OPTIONS, OUT, LINE, BLOCKS, SLICE, FROM, ESCAPE, EACH }; module.exports = Compiler; ================================================ FILE: src/compile/defaults.js ================================================ const runtime = require('./runtime'); const extend = require('./adapter/extend'); const include = require('./adapter/include'); const onerror = require('./adapter/onerror'); const caches = require('./adapter/caches'); const loader = require('./adapter/loader'); const artRule = require('./adapter/rule.art'); const nativeRule = require('./adapter/rule.native'); const htmlMinifier = require('./adapter/html-minifier'); const resolveFilename = require('./adapter/resolve-filename'); const detectNode = typeof window === 'undefined'; /** 模板编译器默认配置 */ const settings = { // 模板内容。如果没有此字段,则会根据 filename 来加载模板内容 source: null, // 模板名 filename: null, // 模板语法规则列表 rules: [nativeRule, artRule], // 是否开启对模板输出语句自动编码功能。为 false 则关闭编码输出功能 // escape 可以防范 XSS 攻击 escape: true, // 启动模板引擎调试模式。如果为 true: {cache:false, minimize:false, compileDebug:true} debug: detectNode ? process.env.NODE_ENV !== 'production' : false, // bail 如果为 true,编译错误与运行时错误都会抛出异常 bail: true, // 是否开启缓存 cache: true, // 是否开启压缩。它会运行 htmlMinifier,将页面 HTML、CSS、CSS 进行压缩输出 // 如果模板包含没有闭合的 HTML 标签,请不要打开 minimize,否则可能被 htmlMinifier 修复或过滤 minimize: true, // 是否编译调试版 compileDebug: false, // 模板路径转换器 resolveFilename: resolveFilename, // 子模板编译适配器 include: include, // HTML 压缩器。仅在 NodeJS 环境下有效 htmlMinifier: htmlMinifier, // HTML 压缩器配置。参见 https://github.com/kangax/html-minifier htmlMinifierOptions: { collapseWhitespace: true, minifyCSS: true, minifyJS: true, // 运行时自动合并:rules.map(rule => rule.test) ignoreCustomFragments: [] }, // 错误事件。仅在 bail 为 false 时生效 onerror: onerror, // 模板文件加载器 loader: loader, // 缓存中心适配器(依赖 filename 字段) caches: caches, // 模板根目录。如果 filename 字段不是本地路径,则在 root 查找模板 root: '/', // 默认后缀名。如果没有后缀名,则会自动添加 extname extname: '.art', // 忽略的变量。被模板编译器忽略的模板变量列表 ignore: [], // 导入的模板变量 imports: runtime }; function Defaults() { this.$extend = function(options) { options = options || {}; return extend(options, options instanceof Defaults ? options : this); }; } Defaults.prototype = settings; module.exports = new Defaults(); ================================================ FILE: src/compile/error.js ================================================ /** * 模板错误处理类 * @param {Object} options */ class TemplateError extends Error { constructor(options) { super(options.message); this.name = 'TemplateError'; this.message = formatMessage(options); if (Error.captureStackTrace) { Error.captureStackTrace(this, this.constructor); } } } function formatMessage({ name, source, path, line, column, generated, message }) { if (!source) { return message; } const lines = source.split(/\n/); const start = Math.max(line - 3, 0); const end = Math.min(lines.length, line + 3); // Error context const context = lines .slice(start, end) .map((code, index) => { const number = index + start + 1; const left = number === line ? ' >> ' : ' '; return `${left}${number}| ${code}`; }) .join('\n'); // Alter exception message return ( `${path || 'anonymous'}:${line}:${column}\n` + `${context}\n\n` + `${name}: ${message}` + (generated ? `\n generated: ${generated}` : '') ); } module.exports = TemplateError; ================================================ FILE: src/compile/es-tokenizer.js ================================================ const isKeyword = require('is-keyword-js'); const jsTokens = require('js-tokens').default; const matchToToken = require('js-tokens').matchToToken; /** * 将逻辑表达式解释为 Tokens * @param {string} code * @return {Object[]} */ const esTokenizer = code => { const tokens = code .match(jsTokens) .map(value => { jsTokens.lastIndex = 0; return matchToToken(jsTokens.exec(value)); }) .map(token => { if (token.type === 'name' && isKeyword(token.value)) { token.type = 'keyword'; } return token; }); return tokens; }; module.exports = esTokenizer; ================================================ FILE: src/compile/index.js ================================================ const Compiler = require('./compiler'); const defaults = require('./defaults'); const TemplateError = require('./error'); const debugRender = (error, options) => { options.onerror(error, options); const render = () => `{Template Error}`; render.mappings = []; render.sourcesContent = []; return render; }; /** * 编译模版 * @param {string|Object} source 模板内容 * @param {?Object} options 编译选项 * @return {function} */ const compile = (source, options = {}) => { if (typeof source !== 'string') { options = source; } else { options.source = source; } // 合并默认配置 options = defaults.$extend(options); source = options.source; // debug 模式 /* istanbul ignore if */ if (options.debug === true) { options.cache = false; options.minimize = false; options.compileDebug = true; } if (options.compileDebug) { options.minimize = false; } // 转换成绝对路径 if (options.filename) { options.filename = options.resolveFilename(options.filename, options); } const filename = options.filename; const cache = options.cache; const caches = options.caches; // 匹配缓存 if (cache && filename) { const render = caches.get(filename); if (render) { return render; } } // 加载外部模板 if (!source) { try { source = options.loader(filename, options); options.source = source; } catch (e) { const error = new TemplateError({ name: 'CompileError', path: filename, message: `template not found: ${e.message}`, stack: e.stack }); if (options.bail) { throw error; } else { return debugRender(error, options); } } } let fn; const compiler = new Compiler(options); try { fn = compiler.build(); } catch (error) { error = new TemplateError(error); if (options.bail) { throw error; } else { return debugRender(error, options); } } const render = (data, blocks) => { try { return fn(data, blocks); } catch (error) { // 运行时出错以调试模式重载 if (!options.compileDebug) { options.cache = false; options.compileDebug = true; return compile(options)(data, blocks); } error = new TemplateError(error); if (options.bail) { throw error; } else { return debugRender(error, options)(); } } }; render.mappings = fn.mappings; render.sourcesContent = fn.sourcesContent; render.toString = () => fn.toString(); if (cache && filename) { caches.set(filename, render); } return render; }; compile.Compiler = Compiler; module.exports = compile; ================================================ FILE: src/compile/runtime.js ================================================ /*! art-template@runtime | https://github.com/aui/art-template */ const globalThis = typeof self !== 'undefined' ? self : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : {}; const runtime = Object.create(globalThis); const ESCAPE_REG = /["&'<>]/; /** * 编码模板输出的内容 * @param {any} content * @return {string} */ runtime.$escape = content => xmlEscape(toString(content)); /** * 迭代器,支持数组与对象 * @param {array|Object} data * @param {function} callback */ runtime.$each = (data, callback) => { if (Array.isArray(data)) { for (let i = 0, len = data.length; i < len; i++) { callback(data[i], i); } } else { for (let i in data) { callback(data[i], i); } } }; // 将目标转成字符 function toString(value) { if (typeof value !== 'string') { if (value === undefined || value === null) { value = ''; } else if (typeof value === 'function') { value = toString(value.call(value)); } else { value = JSON.stringify(value); } } return value; } // 编码 HTML 内容 function xmlEscape(content) { const html = '' + content; const regexResult = ESCAPE_REG.exec(html); if (!regexResult) { return content; } let result = ''; let i, lastIndex, char; for (i = regexResult.index, lastIndex = 0; i < html.length; i++) { switch (html.charCodeAt(i)) { case 34: char = '"'; break; case 38: char = '&'; break; case 39: char = '''; break; case 60: char = '<'; break; case 62: char = '>'; break; default: continue; } if (lastIndex !== i) { result += html.substring(lastIndex, i); } lastIndex = i + 1; result += char; } if (lastIndex !== i) { return result + html.substring(lastIndex, i); } else { return result; } } module.exports = runtime; ================================================ FILE: src/compile/tpl-tokenizer.js ================================================ const TYPE_STRING = 'string'; const TYPE_EXPRESSION = 'expression'; const TYPE_RAW = 'raw'; const TYPE_ESCAPE = 'escape'; function wrapString(token) { const value = new String(token.value); value.line = token.line; value.start = token.start; value.end = token.end; return value; } function Token(type, value, prevToken) { this.type = type; this.value = value; this.script = null; if (prevToken) { this.line = prevToken.line + prevToken.value.split(/\n/).length - 1; if (this.line === prevToken.line) { this.start = prevToken.end; } else { this.start = prevToken.value.length - prevToken.value.lastIndexOf('\n') - 1; } } else { this.line = 0; this.start = 0; } this.end = this.start + this.value.length; } /** * 将模板转换为 Tokens * @param {string} source * @param {Object[]} rules @see defaults.rules * @param {Object} context * @return {Object[]} */ const tplTokenizer = (source, rules, context = {}) => { const tokens = [new Token(TYPE_STRING, source)]; for (let i = 0; i < rules.length; i++) { const rule = rules[i]; const flags = rule.test.ignoreCase ? `ig` : `g`; const regexp = new RegExp(rule.test.source, flags); for (let i = 0; i < tokens.length; i++) { const token = tokens[i]; let prevToken = tokens[i - 1]; if (token.type !== TYPE_STRING) { continue; } let match, index = 0; const substitute = []; const value = token.value; while ((match = regexp.exec(value)) !== null) { if (match.index > index) { prevToken = new Token(TYPE_STRING, value.slice(index, match.index), prevToken); substitute.push(prevToken); } prevToken = new Token(TYPE_EXPRESSION, match[0], prevToken); match[0] = wrapString(prevToken); prevToken.script = rule.use.apply(context, match); substitute.push(prevToken); index = match.index + match[0].length; } if (index < value.length) { prevToken = new Token(TYPE_STRING, value.slice(index), prevToken); substitute.push(prevToken); } tokens.splice(i, 1, ...substitute); i += substitute.length - 1; } } return tokens; }; tplTokenizer.TYPE_STRING = TYPE_STRING; tplTokenizer.TYPE_EXPRESSION = TYPE_EXPRESSION; tplTokenizer.TYPE_RAW = TYPE_RAW; tplTokenizer.TYPE_ESCAPE = TYPE_ESCAPE; module.exports = tplTokenizer; ================================================ FILE: src/defaults.js ================================================ module.exports = require('./compile/defaults'); ================================================ FILE: src/extension.js ================================================ const templatePath = require.resolve('./index.js'); /** * require.extensions 扩展注册函数 * 使用动态编译机制 * @param {Object} module * @param {string} flnm */ const extension = function(module, flnm) { const filename = flnm || module.filename; const imports = 'var template=require(' + JSON.stringify(templatePath) + ')'; const options = JSON.stringify({ filename: filename }); module._compile( imports + '\n' + 'module.exports = template.compile(' + options + ');', filename ); }; module.exports = extension; ================================================ FILE: src/index.js ================================================ const render = require('./render'); const compile = require('./compile'); const defaults = require('./defaults'); /** * 模板引擎 * @param {string} filename 模板名 * @param {Object|string} content 数据或模板内容 * @return {string|function} 如果 content 为 string 则编译并缓存模板,否则渲染模板 */ const template = (filename, content) => { return content instanceof Object ? render( { filename }, content ) : compile({ filename, source: content }); }; template.render = render; template.compile = compile; template.defaults = defaults; module.exports = template; ================================================ FILE: src/precompile.js ================================================ const path = require('path'); const acorn = require('acorn'); const escodegen = require('escodegen'); const estraverse = require('estraverse'); const sourceMap = require('source-map'); const mergeSourceMap = require('merge-source-map'); const compile = require('./compile'); const defaults = require('./defaults'); const runtimePath = require.resolve('./runtime'); const CONSTS = compile.Compiler.CONSTS; const LOCAL_MODULE = /^\.+\//; // 获取默认设置 const getDefaults = options => { // new defaults const setting = { imports: runtimePath, bail: true, cache: false, debug: false, sourceMap: false, sourceRoot: options.sourceRoot }; for (let name in options) { setting[name] = options[name]; } return defaults.$extend(setting); }; // 转换外部模板文件引入语句的 filename 参数节点 // 所有绝对路径都转换成相对路径 const convertFilenameNode = (node, options) => { if (node.type === 'Literal') { const resolvePath = options.resolveFilename(node.value, options); const dirname = path.dirname(options.filename); const relativePath = path.relative(dirname, resolvePath); if (LOCAL_MODULE.test(relativePath)) { node.value = relativePath; } else { node.value = './' + relativePath; } delete node.raw; } return node; }; // 获取原始渲染函数的 sourceMap const getOldSourceMap = (mappings, { sourceRoot, source, file }) => { const oldSourceMap = new sourceMap.SourceMapGenerator({ file, sourceRoot }); mappings.forEach(mapping => { mapping.source = source; oldSourceMap.addMapping(mapping); }); return oldSourceMap.toJSON(); }; /** * 预编译模版,将模板编译成 javascript 代码 * 使用静态分析,将模板内部之间依赖转换成 `require()` * @param {Object} options 编译选项 * @return {Object} */ const precompile = (options = {}) => { if (typeof options.filename !== 'string') { throw Error('template.precompile(): "options.filename" required'); } options = getDefaults(options); let code = null; let sourceMap = null; let ast = null; const imports = options.imports; const functions = [CONSTS.INCLUDE, CONSTS.EXTEND]; if (typeof imports !== 'string') { throw Error( 'template.precompile(): "options.imports" is a file. Example:\n' + 'options: { imports: require.resolve("art-template/lib/runtime") }\n' ); } else { options.imports = require(imports); } const isLocalModule = LOCAL_MODULE.test(imports); const tplImportsPath = isLocalModule ? imports : path.relative(path.dirname(options.filename), imports); const fn = compile(options); code = '(' + fn.toString() + ')'; ast = acorn.parse(code, { locations: options.sourceMap }); let extendNode = null; const enter = function(node) { if (node.type === 'VariableDeclarator' && functions.indexOf(node.id.name) !== -1) { // TODO 对变量覆盖进行抛错 if (node.id.name === CONSTS.INCLUDE) { node['init'] = { type: 'FunctionExpression', params: [ { type: 'Identifier', name: 'content' } ], body: { type: 'BlockStatement', body: [ { type: 'ExpressionStatement', expression: { type: 'AssignmentExpression', operator: '+=', left: { type: 'Identifier', name: CONSTS.OUT }, right: { type: 'Identifier', name: 'content' } } }, { type: 'ReturnStatement', argument: { type: 'Identifier', name: CONSTS.OUT } } ] } }; return node; } else { this.remove(); } } else if ( node.type === 'CallExpression' && node.callee.type === 'Identifier' && functions.indexOf(node.callee.name) !== -1 ) { let replaceNode; switch (node.callee.name) { case CONSTS.EXTEND: extendNode = convertFilenameNode(node.arguments[0], options); replaceNode = { type: 'AssignmentExpression', operator: '=', left: { type: 'Identifier', name: CONSTS.FROM }, right: { type: 'Literal', value: true } }; break; case CONSTS.INCLUDE: const filename = node.arguments.shift(); const filenameNode = filename.name === CONSTS.FROM ? extendNode : convertFilenameNode(filename, options); const paramNodes = node.arguments.length ? node.arguments : [ { type: 'Identifier', name: CONSTS.DATA } ]; replaceNode = node; replaceNode['arguments'] = [ { type: 'CallExpression', callee: { type: 'CallExpression', callee: { type: 'Identifier', name: 'require' }, arguments: [filenameNode] }, arguments: paramNodes } ]; break; } return replaceNode; } }; ast = estraverse.replace(ast, { enter: enter }); if (options.sourceMap) { const sourceRoot = options.sourceRoot; const source = path.relative(sourceRoot, options.filename); const file = path.basename(source); const gen = escodegen.generate(ast, { sourceMap: source, file: file, sourceMapRoot: sourceRoot, sourceMapWithCode: true }); code = gen.code; const newSourceMap = gen.map.toJSON(); const oldSourceMap = getOldSourceMap(fn.mappings, { sourceRoot, source, file }); sourceMap = mergeSourceMap(oldSourceMap, newSourceMap); sourceMap.file = file; sourceMap.sourcesContent = fn.sourcesContent; } else { code = escodegen.generate(ast); } code = code.replace(/^\(|\)[;\s]*?$/g, ''); code = 'var ' + CONSTS.IMPORTS + ' = require(' + JSON.stringify(tplImportsPath) + ');\n' + 'module.exports = ' + code + ';'; return { code, ast, sourceMap, toString: () => code }; }; module.exports = precompile; ================================================ FILE: src/render.js ================================================ const compile = require('./compile'); /** * 渲染模板 * @param {string|Object} source 模板内容 * @param {Object} data 数据 * @param {?Object} options 选项 * @return {string} 渲染好的字符串 */ const render = (source, data, options) => compile(source, options)(data); module.exports = render; ================================================ FILE: src/runtime.js ================================================ module.exports = require('./compile/runtime'); ================================================ FILE: test/compile/adapter/caches.js ================================================ const assert = require('assert'); const caches = require('../../../src/compile/adapter/caches'); module.exports = { caches: { 'set value': () => { caches.set('test', 'hello'); assert.deepEqual('hello', caches.get('test')); }, 'get value': () => { assert.deepEqual('undefined', typeof caches.get('toString')); }, 'reset caches': () => { caches.set('test', 9); caches.reset(); assert.deepEqual(undefined, caches.get('test')); } } }; ================================================ FILE: test/compile/adapter/html-minifier.js ================================================ const assert = require('assert'); const htmlMinifier = require('../../../src/compile/adapter/html-minifier'); const rules = []; const htmlMinifierOptions = { collapseWhitespace: true, minifyCSS: true, minifyJS: true, ignoreCustomFragments: [] }; module.exports = { 'html-minifier': { text: () => { const result = htmlMinifier('hello world', { rules, htmlMinifierOptions }); assert.equal('hello world', result); }, tag: () => { let result; result = htmlMinifier('
', { rules, htmlMinifierOptions }); assert.equal('
', result); result = htmlMinifier('hello
world
', { rules, htmlMinifierOptions }); assert.equal('hello
world
', result); }, script: () => { const result = htmlMinifier('', { rules, htmlMinifierOptions }); assert.equal('', result); }, 'html fragment': () => { let result; result = htmlMinifier('hello
world', { rules, htmlMinifierOptions }); assert.equal('hello
world
', result); }, 'throw error': () => { let result = null; try { result = htmlMinifier('
{ const filename = path.resolve(__dirname, '..', '..', 'res', 'file.html'); assert.deepEqual('hello world', tplLoader(filename)); } } }; ================================================ FILE: test/compile/adapter/onerror.js ================================================ const onerror = require('../../../src/compile/adapter/onerror'); module.exports = { onerror: { basic: () => { onerror({}); } } }; ================================================ FILE: test/compile/adapter/resolve-filename.js ================================================ const assert = require('assert'); const resolveFilename = require('../../../src/compile/adapter/resolve-filename'); module.exports = { resolveFilename: { basic: () => { const test = (args, result) => { assert.deepEqual(result, resolveFilename(...args)); }; test( [ 'header.html', { root: '/' } ], '/header.html' ); test( [ 'header.html', { root: '/Root' } ], '/Root/header.html' ); test( [ 'header.html', { root: '/Root', extname: '.art', filename: '/Root/base/index.html' } ], '/Root/header.html' ); test( [ 'header.html', { root: '/Root', extname: '.art', filename: '/Web/base/index.html' } ], '/Root/header.html' ); test( [ './header.html', { root: '/' } ], '/header.html' ); test( [ './header.html', { root: '/Root' } ], '/Root/header.html' ); test( [ './header.html', { root: '/Root', extname: '.art', filename: '/Root/base/index.html' } ], '/Root/base/header.html' ); test( [ './header.html', { root: '/Root', extname: '.art', filename: '/Web/base/index.html' } ], '/Web/base/header.html' ); test( [ '../../header.html', { root: '/' } ], '/header.html' ); test( [ '../../header.html', { root: '/Root' } ], '/header.html' ); test( [ '../../header.html', { root: '/Root', extname: '.art', filename: '/Root/base/index.html' } ], '/header.html' ); test( [ '../../header.html', { root: '/Root', extname: '.art', filename: '/Web/base/index.html' } ], '/header.html' ); test( [ '/header.html', { root: '/' } ], '/header.html' ); test( [ '/header.html', { root: '/Root' } ], '/header.html' ); test( [ '/header.html', { root: '/Root', extname: '.art', filename: '/Root/base/index.html' } ], '/header.html' ); test( [ '/header.html', { root: '/Root', extname: '.art', filename: '/Web/base/index.html' } ], '/header.html' ); } } }; ================================================ FILE: test/compile/adapter/rule.art.js ================================================ const assert = require('assert'); const ruleArt = require('../../../src/compile/adapter/rule.art'); const esTokenizer = require('../../../src/compile/es-tokenizer'); const callRule = code => { const compiler = { options: {}, getEsTokens: esTokenizer }; const list = code.match(ruleArt.test); list[0] = new String(list[0]); list[0].line = 0; list[0].start = 0; return ruleArt.use.apply(compiler, list); }; module.exports = { syntax: { set: () => { assert.deepEqual( { code: 'var a = b', output: false }, callRule(`{{set a = b}}`) ); assert.deepEqual( { code: 'var a = b', output: false }, callRule(`{{ set a = b }}`) ); // 多个声明 assert.deepEqual( { code: 'var a = b, c = 1', output: false }, callRule(`{{set a = b, c = 1}}`) ); }, if: () => { // 布尔 assert.deepEqual( { code: 'if(value){', output: false }, callRule(`{{if value}}`) ); assert.deepEqual( { code: 'if(value){', output: false }, callRule(`{{ if value }}`) ); // 算术 assert.deepEqual( { code: 'if(a + b === 4){', output: false }, callRule(`{{if a + b === 4}}`) ); // 优先级 assert.deepEqual( { code: 'if((a + b) * c){', output: false }, callRule(`{{if (a + b) * c}}`) ); }, 'else if': () => { // 布尔 assert.deepEqual( { code: '}else if(value){', output: false }, callRule(`{{else if value}}`) ); assert.deepEqual( { code: '}else if(value){', output: false }, callRule(`{{ else if value }}`) ); // 算术 assert.deepEqual( { code: '}else if(a + b === 4){', output: false }, callRule(`{{else if a + b === 4}}`) ); // 优先级 assert.deepEqual( { code: '}else if((a + b) * c){', output: false }, callRule(`{{else if (a + b) * c}}`) ); }, else: () => { assert.deepEqual( { code: '}else{', output: false }, callRule(`{{else}}`) ); assert.deepEqual( { code: '}else{', output: false }, callRule(`{{ else }}`) ); }, '/if': () => { assert.deepEqual( { code: '}', output: false }, callRule(`{{/if}}`) ); assert.deepEqual( { code: '}', output: false }, callRule(`{{ /if }}`) ); }, each: () => { assert.deepEqual( { code: '$each($data,function($value,$index){', output: false }, callRule(`{{each}}`) ); assert.deepEqual( { code: '$each($data,function($value,$index){', output: false }, callRule(`{{ each }}`) ); assert.deepEqual( { code: '$each(list,function($value,$index){', output: false }, callRule(`{{each list}}`) ); assert.deepEqual( { code: '$each(list,function(val,$index){', output: false }, callRule(`{{each list val}}`) ); assert.deepEqual( { code: '$each(list,function(val,key){', output: false }, callRule(`{{each list val key}}`) ); // 表达式 assert.deepEqual( { code: '$each(list[a].b,function(val,key){', output: false }, callRule(`{{each list[a].b val key}}`) ); // 兼容 v3 as 语法 assert.deepEqual( { code: '$each(list,function(val,key){', output: false }, callRule(`{{each list as val key}}`) ); assert.deepEqual( { code: `$each(list['var'].a,function(val,key){`, output: false }, callRule(`{{each list['var'].a as val key}}`) ); }, '/each': () => { assert.deepEqual( { code: '})', output: false }, callRule(`{{/each}}`) ); assert.deepEqual( { code: '})', output: false }, callRule(`{{ /each }}`) ); }, block: () => { assert.deepEqual( { code: `block('header',function(){`, output: false }, callRule(`{{block 'header'}}`) ); assert.deepEqual( { code: `block('header',function(){`, output: false }, callRule(`{{ block 'header' }}`) ); }, include: () => { assert.deepEqual( { code: `include('header')`, output: false }, callRule(`{{include 'header'}}`) ); assert.deepEqual( { code: `include('header')`, output: false }, callRule(`{{ include 'header' }}`) ); assert.deepEqual( { code: `include('header',data)`, output: false }, callRule(`{{include 'header' data}}`) ); // 当作函数调用 assert.deepEqual( { code: `include('header',data)`, output: 'escape' }, callRule(`{{include('header',data)}}`) ); }, extend: () => { assert.deepEqual( { code: `extend('header')`, output: false }, callRule(`{{extend 'header'}}`) ); assert.deepEqual( { code: `extend('header')`, output: false }, callRule(`{{ extend 'header' }}`) ); // 当作函数调用 assert.deepEqual( { code: `extend('header')`, output: 'escape' }, callRule(`{{extend('header')}}`) ); } }, output: { autoescape: () => { assert.deepEqual( { code: 'value', output: 'escape' }, callRule(`{{value}}`) ); assert.deepEqual( { code: 'value', output: 'escape' }, callRule(`{{ value }}`) ); assert.deepEqual( { code: 'typeof value', output: 'escape' }, callRule(`{{typeof value}}`) ); assert.deepEqual( { code: 'value + 1', output: 'escape' }, callRule(`{{value + 1}}`) ); assert.deepEqual( { code: 'value?a:b', output: 'escape' }, callRule(`{{value?a:b}}`) ); assert.deepEqual( { code: 'value ? a : b', output: 'escape' }, callRule(`{{ value ? a : b }}`) ); }, raw: () => { assert.deepEqual( { code: 'value', output: 'raw' }, callRule(`{{@value}}`) ); assert.deepEqual( { code: 'value', output: 'raw' }, callRule(`{{@ value }}`) ); }, filter: () => { assert.deepEqual( { code: `$imports.c($imports.b(a))`, output: 'escape' }, callRule(`{{a | b | c}}`) ); assert.deepEqual( { code: `$imports.c($imports.b(a))`, output: 'escape' }, callRule(`{{ a | b | c }}`) ); assert.deepEqual( { code: `$imports.c($imports.b(a(9+9,54)))`, output: 'escape' }, callRule(`{{a(9 + 9, 54) | b | c}}`) ); assert.deepEqual( { code: `$imports.c($imports.b(a,1),2)`, output: 'escape' }, callRule(`{{a | b 1 | c 2}}`) ); assert.deepEqual( { code: `$imports.c($imports.b(a,1+3),2+4)`, output: 'escape' }, callRule(`{{a | b 1 + 3 | c 2 + 4}}`) ); assert.deepEqual( { code: `$imports.dateFormat(time)`, output: 'escape' }, callRule(`{{time | dateFormat}}`) ); assert.deepEqual( { code: `$imports.dateFormat(time,'yyyy-MM-dd')`, output: 'escape' }, callRule(`{{time | dateFormat 'yyyy-MM-dd'}}`) ); assert.deepEqual( { code: `$imports.dateFormat(time,'yyyy-MM-dd')`, output: 'escape' }, callRule(`{{time | dateFormat:'yyyy-MM-dd'}}`) ); assert.deepEqual( { code: `$imports.dateFormat(time,f?a.b[c]:y(),9.99)`, output: 'escape' }, callRule(`{{time | dateFormat f ? a.b[c] : y() 9.99}}`) ); assert.deepEqual( { code: `$imports.dateFormat(time||Date.now(),'yyyy-MM-dd')`, output: 'escape' }, callRule(`{{time || Date.now() | dateFormat 'yyyy-MM-dd'}}`) ); assert.deepEqual( { code: `$imports.dateFormat(item.add_time*1000,'yyyy-MM-dd hh:mm:ss')`, output: 'escape' }, callRule(`{{item.add_time*1000 | dateFormat 'yyyy-MM-dd hh:mm:ss'}}`) ); } }, 'rule.art': { _split: () => { let code; let esTokens; let result; code = 'a b c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a', 'b', 'c'], result); code = ' a b c '; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a', 'b', 'c'], result); code = 'a b c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a', 'b', 'c'], result); code = 'a.b c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a.b', 'c'], result); code = 'a. b c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a.b', 'c'], result); code = 'a[b] c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a[b]', 'c'], result); code = 'a["b"] c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a["b"]', 'c'], result); code = 'a["b"][c] c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a["b"][c]', 'c'], result); code = 'a["b"].c d'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a["b"].c', 'd'], result); code = 'a[" b "] c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a[" b "]', 'c'], result); code = 'a + b c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a+b', 'c'], result); code = 'a - b c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a-b', 'c'], result); code = 'a * b c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a*b', 'c'], result); code = 'a / b c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a/b', 'c'], result); code = 'a + b + c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a+b+c'], result); code = 'a + b.f + c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a+b.f+c'], result); code = 'a ? b : c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a?b:c'], result); code = 'a ? b : c ? d : e'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a?b:c?d:e'], result); code = 'a.f ? b : c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a.f?b:c'], result); code = 'a . f ? b : c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a.f?b:c'], result); code = 'a ? b : c . d'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a?b:c.d'], result); code = 'a ? b : c e'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['a?b:c', 'e'], result); code = '(a + b) / c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['(a+b)/c'], result); code = '(a + b) / c[a]'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['(a+b)/c[a]'], result); code = '++ a c'; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['++a', 'c'], result); code = `dateFormat 'yyyy-MM-dd hh:mm:ss'`; esTokens = esTokenizer(code); result = ruleArt._split(esTokens); assert.deepEqual(['dateFormat', `'yyyy-MM-dd hh:mm:ss'`], result); } } }; ================================================ FILE: test/compile/adapter/rule.native.js ================================================ const assert = require('assert'); const ruleNative = require('../../../src/compile/adapter/rule.native'); const esTokenizer = require('../../../src/compile/es-tokenizer'); const callRule = code => { const compiler = { options: {}, getEsTokens: esTokenizer }; const list = code.match(ruleNative.test); list[0] = new String(list[0]); list[0].line = 0; list[0].start = 0; return ruleNative.use.apply(compiler, list); }; module.exports = { syntax: { basic: () => { assert.deepEqual( { code: 'if (value) {', output: false }, callRule(`<%if (value) {%>`) ); assert.deepEqual( { code: 'if (value) {', output: false }, callRule(`<% if (value) { %>`) ); }, comment: () => { assert.deepEqual( { code: '/*if (value) {*/', output: false }, callRule(`<%#if (value) {%>`) ); }, trimMode: () => { assert.deepEqual( { code: 'value', output: false }, callRule(`<%value-%>`) ); } }, output: { autoescape: () => { assert.deepEqual( { code: 'value', output: 'escape' }, callRule(`<%=value%>`) ); assert.deepEqual( { code: 'value', output: 'escape' }, callRule(`<%= value %>`) ); assert.deepEqual( { code: 'typeof value', output: 'escape' }, callRule(`<%=typeof value%>`) ); assert.deepEqual( { code: 'value + 1', output: 'escape' }, callRule(`<%=value + 1%>`) ); assert.deepEqual( { code: 'value?a:b', output: 'escape' }, callRule(`<%=value?a:b%>`) ); assert.deepEqual( { code: 'value ? a : b', output: 'escape' }, callRule(`<%= value ? a : b %>`) ); }, raw: () => { assert.deepEqual( { code: 'value', output: 'raw' }, callRule(`<%-value%>`) ); assert.deepEqual( { code: 'value', output: 'raw' }, callRule(`<%- value %>`) ); } } }; ================================================ FILE: test/compile/compiler.js ================================================ const assert = require('assert'); const Compiler = require('../../src/compile/compiler'); const defaults = require('../../src/compile/defaults'); const ruleNative = require('../../src/compile/adapter/rule.native'); const htmlMinifier = ({ source }) => { return source.replace(/\s+/g, ` `).replace(//g, ``); }; module.exports = { getVariables: { basic: () => { const test = (code, result) => { const tokens = Compiler.prototype.getEsTokens(code); const variables = Compiler.prototype.getVariables(tokens); assert.deepEqual(result, variables); }; test('var', []); test('var a', ['a']); test('a', ['a']); test('a.b', ['a']); test('a.b.c', ['a']); test('a.b;c', ['a', 'c']); test('a.b\nd', ['a', 'd']); test('a.\nb', ['a']); test('0.99 + a', ['a']); test('0.99 + a + b.c', ['a', 'b']); test('a /*.*/. b /**/; c', ['a', 'c']); test('a ".b.c; d;" /*e*/ f', ['a', 'f']); test('a[b]', ['a', 'b']); test('a[b].c[d]', ['a', 'b', 'd']); test('a["b"]', ['a']); test('a["b"].c', ['a']); test(`var a, b, c`, ['a', 'b', 'c']); test(`function a(b,c){d}`, ['a', 'b', 'c', 'd']); test(`try{a}catch(b){c}`, ['a', 'b', 'c']); test(`{...a,\nb}`, ['a', 'b']); } }, importContext: { basic: () => { const test = (code, result, options) => { options = defaults.$extend(options); options.source = ''; const compiler = new Compiler(options); compiler.importContext(code); result.$$out = `''`; assert.deepEqual(result, compiler.CONTEXT_MAP); }; test('value', { value: '$data.value' }); //test('if', {}); //test('for', {}); test('$data', {}); test('$imports', {}); test('$escape', { $escape: '$imports.$escape' }); }, imports: () => { const options = defaults.$extend({}); options.imports.Math = Math; options.source = ''; const compiler = new Compiler(options); compiler.importContext('Math'); assert.deepEqual( { $$out: `''`, Math: '$imports.Math' }, compiler.CONTEXT_MAP ); } }, addSource: { basic: () => { const test = (code, result, options) => { options = defaults.$extend(options); options.minimize = false; options.source = code; const compiler = new Compiler(options); assert.deepEqual(result, compiler.scripts.map(script => script.code)); }; test('hello', ['$$out+="hello"']); test('<%=value%>', ['$$out+=$escape(value)']); test('hello<%=value%>', ['$$out+="hello"', '$$out+=$escape(value)']); test('hello\n<%=value%>', ['$$out+="hello\\n"', '$$out+=$escape(value)']); } }, parseString: { basic: () => { const test = (code, result, options) => { it(code, () => { options = defaults.$extend(options); options.source = ''; const compiler = new Compiler(options); const token = compiler.getTplTokens(code, [ruleNative]); compiler.parseString(token[0]); assert.deepEqual(result, compiler.scripts.map(script => script.code)); }); }; // raw test('hello', ['$$out+="hello"']); test("'hello'", ['$$out+="\'hello\'"']); test('"hello world"', ['$$out+="\\"hello world\\""']); test('
hello
', ['$$out+="
hello
"']); test('
hello
', ['$$out+="
hello
"']); // htmlMinifier test(' hello ', ['$$out+=" hello "'], { htmlMinifier }); test('\n hello \n\n.', ['$$out+=" hello ."'], { htmlMinifier }); test('"hello world"', ['$$out+="\\"hello world\\""'], { htmlMinifier }); test("'hello world'", ['$$out+="\'hello world\'"'], { htmlMinifier }); }, parseExpression: () => { const test = (code, result, options) => { it(code, () => { options = defaults.$extend(options); options.source = ''; const compiler = new Compiler(options); const token = compiler.getTplTokens(code, [ruleNative]); compiler.parseExpression(token[0]); assert.deepEqual(result, compiler.scripts.map(script => script.code)); }); }; // v3 compat test('<%=value%>', ['$$out+=$escape(value)']); test('<%=#value%>', ['$$out+=value']); // v4 test('<%-value%>', ['$$out+=value']); test('<%- value %>', ['$$out+= value']); test('<%=value%>', ['$$out+=value'], { escape: false }); test('<%-value%>', ['$$out+=value'], { escape: false }); test('<%if (value) {%>', ['if (value) {']); test('<% if (value) { %>', [' if (value) { ']); test('<% if ( value ) { %>', [' if ( value ) { '], { htmlMinifier }); } }, checkExpression: { basic: () => { const test = (code, result, options) => { options = defaults.$extend(options); options.source = code; const compiler = new Compiler(options); assert.deepEqual(result, compiler.checkExpression(code)); }; test('if(a){', true); test('for(var i in d){', true); test('fn(function(a,b){', true); test('fn ( function ( a, b ) { ', true); test('fn(1,function(a,b){', true); test('fn ( 1, function ( a, b ) { ', true); test('fn(function(){', true); test('fn ( function ( ) { ', true); test('fn(1,function(){', true); test('fn ( 1, function ( ) { ', true); test('fn((a,b)=>{', true); test('fn ( ( a , b ) => { ', true); test('fn(1,(a,b)=>{', true); test('fn ( 1, ( a , b ) => { ', true); test('fn(()=>{', true); test('fn ( ( ) => { ', true); test('fn(1,()=>{', true); test('fn ( 1 , ( ) => { ', true); test('$each(user.tags,function($value,$index){;', true); test('}else if(a){', true); test('}else{', true); test('}', true); //test('(a,b)=>{', true); test('if(a){}', true); test('for(var i in d){}', true); test('fn(function(a,b){})', true); test('fn((a,b)=>{})', true); test('@if(a){', false); test('@for(var i in d){', false); test('@fn(function(a,b){', false); test('@fn((a,b)=>{', false); } }, mappings: { basic: () => { const test = (source, result) => { const options = defaults.$extend({ source, minimize: false }); const compiler = new Compiler(options); const render = compiler.build(); const mappings = render.mappings; assert.deepEqual(result, mappings); }; test(`{{value}}`, [ { generated: { line: 5, column: 1 }, original: { line: 1, column: 1 } } ]); test(`abc{{value}}`, [ { generated: { line: 5, column: 1 }, original: { line: 1, column: 1 } }, { generated: { line: 6, column: 1 }, original: { line: 1, column: 4 } } ]); test(`abc\n{{value}}`, [ { generated: { line: 5, column: 1 }, original: { line: 1, column: 1 } }, { generated: { line: 6, column: 1 }, original: { line: 2, column: 1 } } ]); test(`abc\n<%\n print('s') \n eeee(2) %>\n{{a}}`, [ { generated: { line: 5, column: 1 }, original: { line: 1, column: 1 } }, { generated: { line: 6, column: 1 }, original: { line: 2, column: 1 } }, { generated: { line: 9, column: 1 }, original: { line: 4, column: 12 } }, { generated: { line: 10, column: 1 }, original: { line: 5, column: 1 } } ]); } }, build: { CompileError: { throw: () => { const options = Object.create(defaults); options.minimize = false; options.source = 'hello\n\n<% a b c d %>'; const compiler = new Compiler(options); try { compiler.build(); } catch (e) { assert.deepEqual('CompileError', e.name); assert.deepEqual(3, e.line); } } } } }; ================================================ FILE: test/compile/defaults.js ================================================ const assert = require('assert'); const defaults = require('../../src/compile/defaults'); module.exports = { defaults: { imports: () => { const imports = defaults.imports; const options = defaults.$extend({ imports: { test: 1 } }); assert.deepEqual(1, options.imports.test); assert.deepEqual(imports.$escape, options.imports.$escape); assert.deepEqual(undefined, imports.test); }, rules: () => { const rules = defaults.rules; const length = rules.length; const options = defaults.$extend({ rules: [null] }); assert.deepEqual(null, options.rules[0]); assert.deepEqual(rules[1], options.rules[1]); assert.deepEqual(length, rules.length); } } }; ================================================ FILE: test/compile/es-tokenizer.js ================================================ const assert = require('assert'); const esTokenizer = require('../../src/compile/es-tokenizer'); module.exports = { parser: { basic: () => { const test = (code, result) => { assert.deepEqual(result, esTokenizer(code)); }; test('var', [ { type: 'keyword', value: 'var' } ]); test('0.99', [ { type: 'number', value: '0.99' } ]); test('"value"', [ { type: 'string', value: '"value"', closed: true } ]); test('/*value*/', [ { type: 'comment', value: '/*value*/', closed: true } ]); test('=>', [ { type: 'punctuator', value: '=>' } ]); test('#', [ { type: 'invalid', value: '#' } ]); test('@', [ { type: 'invalid', value: '@' } ]); test('a.b.c+d', [ { type: 'name', value: 'a' }, { type: 'punctuator', value: '.' }, { type: 'name', value: 'b' }, { type: 'punctuator', value: '.' }, { type: 'name', value: 'c' }, { type: 'punctuator', value: '+' }, { type: 'name', value: 'd' } ]); test('[...a][b]', [ { type: 'punctuator', value: '[' }, { type: 'punctuator', value: '...' }, { type: 'name', value: 'a' }, { type: 'punctuator', value: ']' }, { type: 'punctuator', value: '[' }, { type: 'name', value: 'b' }, { type: 'punctuator', value: ']' } ]); test('@if a + b === 0', [ { type: 'invalid', value: '@' }, { type: 'keyword', value: 'if' }, { type: 'whitespace', value: ' ' }, { type: 'name', value: 'a' }, { type: 'whitespace', value: ' ' }, { type: 'punctuator', value: '+' }, { type: 'whitespace', value: ' ' }, { type: 'name', value: 'b' }, { type: 'whitespace', value: ' ' }, { type: 'punctuator', value: '===' }, { type: 'whitespace', value: ' ' }, { type: 'number', value: '0' } ]); } } }; ================================================ FILE: test/compile/index.js ================================================ const assert = require('assert'); const compile = require('../../src/compile/index'); const tplTokenizer = require('../../src/compile/tpl-tokenizer'); const defaults = require('../../src/compile/defaults'); const onerror = defaults.onerror; const path = require('path'); let render, data, result; module.exports = { before: () => { defaults.onerror = () => { return () => '{Template Error}'; }; }, after: () => { defaults.onerror = onerror; }, 'rule.native': { output: () => { render = compile('hello <%=value%>.'); data = { value: 'aui' }; result = render(data); assert.deepEqual('hello aui.', result); render = compile('hello <%=值%>.'); data = { 值: 'aui' }; result = render(data); assert.deepEqual('hello aui.', result); render = compile('hello <%=value%>.'); data = { value: '' }; result = render(data); assert.deepEqual('hello <aui>.', result); render = compile('hello <%-value%>.'); data = { value: '' }; result = render(data); assert.deepEqual('hello .', result); render = compile(`<%\nprint('hello > world')\n%>`); data = {}; result = render(data); assert.deepEqual('hello > world', result); // todo empty }, block: () => { render = compile('<% block(function(){ %>hello <%= value %>.<% }) %>', { bail: true }); data = { value: 'aui' }; result = render(data); assert.deepEqual('hello aui.', result); }, 'syntax compat: art-template@v3': () => { render = compile('<%== value %>'); data = { value: '' }; result = render(data); assert.deepEqual('', result); render = compile('<%=# value %>'); data = { value: '' }; result = render(data); assert.deepEqual('', result); }, 'syntax compat: ejs': () => { render = compile('<%# value %>'); data = { value: 'aui' }; result = render(data); assert.deepEqual('', result); render = compile('<%= value -%>'); data = { value: 'aui' }; result = render(data); assert.deepEqual('aui', result); } }, 'rule.art': { output: () => { render = compile('hello'); data = {}; result = render(data); assert.deepEqual('hello', result); render = compile('hello, {{value}}.'); data = { value: 'world' }; result = render(data); assert.deepEqual('hello, world.', result); render = compile('{{value}}'); data = { value: '<>' }; result = render(data); assert.deepEqual('<>', result); render = compile('{{@value}}'); data = { value: '<>' }; result = render(data); assert.deepEqual('<>', result); render = compile('{{a + b + c}}'); data = { a: 0, b: 1, c: 2 }; result = render(data); assert.deepEqual('3', result); render = compile('{{a ? b : c}}'); data = { a: 0, b: 1, c: 2 }; result = render(data); assert.deepEqual('2', result); render = compile('{{a || b || c}}'); data = { a: 0, b: 1, c: 2 }; result = render(data); assert.deepEqual('1', result); }, 'syntax compat: art-template@v3': () => { render = compile('{{#value}}'); data = { value: '<>' }; result = render(data); assert.deepEqual('<>', result); }, filter: () => { const dateFormat = (date, format) => { date = new Date(date); const map = { // 月份 M: date.getMonth() + 1, // 日 d: date.getDate(), // 小时 h: date.getHours(), // 分 m: date.getMinutes(), // 秒 s: date.getSeconds(), // 季度 q: Math.floor((date.getMonth() + 3) / 3), // 毫秒 S: date.getMilliseconds() }; format = format.replace(/([yMdhmsqS])+/g, (all, t) => { let v = map[t]; if (v !== undefined) { if (all.length > 1) { v = '0' + v; v = v.substr(v.length - 2); } return v; } else if (t === 'y') { return (date.getFullYear() + '').substr(4 - all.length); } return all; }); return format; }; const brackets = string => `『${string}』`; const imports = Object.assign({}, defaults.imports, { dateFormat, brackets }); const options = { imports }; const test = (code, data, result, options = {}) => { const render = compile(code, options); assert.deepEqual(result, render(data)); }; test(`{{print 'hello' '-' 'world'}}`, {}, `hello-world`, options); test( `{{value | brackets}}`, { value: '糖饼' }, '『糖饼』', options ); test( `{{value.name | brackets}}`, { value: { name: '糖饼' } }, '『糖饼』', options ); test( `{{time | dateFormat 'yyyy-MM-dd'}}`, { time: 1491566794863 }, `2017-04-07`, options ); test( `{{time|dateFormat 'yyyy-MM-dd'}}`, { time: 1491566794863 }, `2017-04-07`, options ); test( `{{time | dateFormat 'yyyy-MM-dd' | brackets}}`, { time: 1491566794863 }, `『2017-04-07』`, options ); test( `{{time * 1000 | dateFormat 'yyyy-MM-dd'}}`, { time: 1491566794 }, `2017-04-07`, options ); test(`{{3.14 | parseInt}}`, {}, `3`, options); test( `{{time | dateFormat:'yyyy-MM-dd'}}`, { time: 1491566794863 }, `2017-04-07`, options ); // ... v3 compat ... }, include: () => { compile('#title: {{title}}', { root: '/', filename: '/header.html', minimize: false }); render = compile(`{{include 'header.html'}}\ncontent: {{content}}`, { minimize: false, bail: true }); data = { title: 'hello', content: 'world' }; result = render(data); assert.deepEqual(`#title: hello\ncontent: world`, result); render = compile(`{{include file.header}}\ncontent: {{content}}`, { minimize: false }); data = { title: 'hello', content: 'world', file: { header: 'header.html' } }; result = render(data); assert.deepEqual(`#title: hello\ncontent: world`, result); render = compile(`{{include './header.html'}}\ncontent: {{content}}`, { minimize: false }); data = { title: 'hello', content: 'world' }; result = render(data); assert.deepEqual(`#title: hello\ncontent: world`, result); render = compile(`{{include 'header.html' sub}}\ncontent: {{content}}`, { minimize: false }); data = { title: 'hello', content: 'world', sub: { title: '糖饼' } }; result = render(data); assert.deepEqual(`#title: 糖饼\ncontent: world`, result); render = compile(`{{@include('header.html', {title: '糖饼'})}}\ncontent: {{content}}`, { bail: true, minimize: false }); data = { title: 'hello', content: 'world' }; result = render(data); assert.deepEqual(`#title: 糖饼\ncontent: world`, result); render = compile({ filename: path.resolve( __dirname, '..', '..', 'example', 'node-include', 'index.art' ), minimize: true }); data = { title: 'My Page' }; result = render(data); assert.equal(true, result.indexOf('My Page') > -1); assert.equal(true, result.indexOf('') > -1); assert.equal(false, /<\/html>.+/.test(result)); }, layout: () => { render = compile({ filename: path.resolve( __dirname, '..', '..', 'example', 'node-layout', 'index.art' ), minimize: true, bail: true }); data = { title: 'My Page' }; result = render(data); assert.equal(true, result.indexOf('My Page') > -1); assert.equal(true, result.indexOf('') > -1); }, echo: () => { render = compile('{{echo 2017}}'); data = {}; result = render(data); assert.deepEqual('2017', result); render = compile('{{echo value}}'); data = { value: 'hello' }; result = render(data); assert.deepEqual('hello', result); }, each: () => { render = compile('{{each}}{{$index}}{{$value}}{{/each}}'); data = ['a', 'b', 'c']; result = render(data); assert.deepEqual('0a1b2c', result); render = compile('{{each}}{{$index}}{{$value}}{{/each}}'); data = { a: 1, b: 2, c: 3 }; result = render(data); assert.deepEqual('a1b2c3', result); render = compile('{{each list}}{{$index}}{{$value}}{{/each}}'); data = { list: ['a', 'b', 'c'] }; result = render(data); assert.deepEqual('0a1b2c', result); render = compile('{{each list val}}{{$index}}{{val}}{{/each}}'); data = { list: ['a', 'b', 'c'] }; result = render(data); assert.deepEqual('0a1b2c', result); render = compile('{{each list val key}}{{key}}{{val}}{{/each}}'); data = { list: ['a', 'b', 'c'] }; result = render(data); assert.deepEqual('0a1b2c', result); render = compile('{{each list val key}}{{key}}{{val}}{{/each}}'); data = { list: ['a', 'b', 'c'] }; result = render(data); assert.deepEqual('0a1b2c', result); render = compile('{{each list.data val key}}{{key}}{{val}}{{/each}}'); data = { list: { data: ['a', 'b', 'c'] } }; result = render(data); assert.deepEqual('0a1b2c', result); // ... v3 compat ... render = compile('{{each list as val}}{{$index}}{{val}}{{/each}}'); data = { list: ['a', 'b', 'c'] }; result = render(data); assert.deepEqual('0a1b2c', result); render = compile('{{each list as val key}}{{key}}{{val}}{{/each}}'); data = { list: ['a', 'b', 'c'] }; result = render(data); assert.deepEqual('0a1b2c', result); // 空格兼容 render = compile('{{ each list.data val key }}{{key}}{{val}}{{ /each }}'); data = { list: { data: ['a', 'b', 'c'] } }; result = render(data); assert.deepEqual('0a1b2c', result); }, if: () => { render = compile('{{if value}}hello world{{/if}}'); data = { value: true }; result = render(data); assert.deepEqual('hello world', result); render = compile('{{if a.b}}hello world{{/if}}'); data = { a: { b: true } }; result = render(data); assert.deepEqual('hello world', result); render = compile('{{if a.b + 1}}hello world{{/if}}'); data = { a: { b: 1 } }; result = render(data); assert.deepEqual('hello world', result); render = compile('{{if value}}hello world{{else}}hello 糖饼{{/if}}'); data = { value: false }; result = render(data); assert.deepEqual('hello 糖饼', result); render = compile('{{if value !== false}}hello world{{else}}hello 糖饼{{/if}}'); data = { value: false }; result = render(data); assert.deepEqual('hello 糖饼', result); render = compile('{{if value!==false}}hello world{{else}}hello 糖饼{{/if}}'); data = { value: false }; result = render(data); assert.deepEqual('hello 糖饼', result); render = compile('{{if a + b === 3}}hello world{{/if}}'); data = { a: 1, b: 2 }; result = render(data); assert.deepEqual('hello world', result); render = compile('{{if a}}hello world{{else if b}}😊{{/if}}'); data = { a: 0, b: 2 }; result = render(data); assert.deepEqual('😊', result); render = compile('{{if a}}hello world{{else if b}}😊{{/if}}'); data = { a: 0, b: 0 }; result = render(data); assert.deepEqual('', result); }, set: () => { render = compile('{{set value="😊"}}{{value}}'); data = {}; result = render(data); assert.deepEqual('😊', result); } }, options: { minimize: { basic: () => { const render = compile('
\n <%=value%>', { minimize: true }); assert.deepEqual( '
aui', render({ value: 'aui' }) ); }, 'Do not compress unclosed tags': () => { const render = compile('
x
link x
link { let render; render = compile('
\n\n\n
{{value}}', { minimize: true }); assert.deepEqual( '
\n\n\n
aui', render({ value: 'aui' }) ); // TODO // render = compile('
\n\n<%=value%>
', { // minimize: true // }); // assert.deepEqual('
\n\naui
', render({ // value: 'aui' // })); }, 'Not compressed "textarea"': () => { let render; render = compile('{{value}}', { minimize: true }); assert.deepEqual( 'aui', render({ value: 'aui' }) ); } }, rules: () => { const source = 'hello ${name} <%=name%>'; const options = { rules: [ { test: /\${([\w\W]*?)}/, use: (match, code) => { return { code, output: tplTokenizer.TYPE_ESCAPE }; } } ] }; const render = compile(source, options); assert.deepEqual( 'hello aui <%=name%>', render({ name: 'aui' }) ); }, filename: () => { let render, html; render = compile({ filename: path.resolve(__dirname, '..', 'res', 'file') }); html = render({}); assert.deepEqual('hello world', html); render = compile({ extname: '.html', filename: path.resolve(__dirname, '..', 'res', 'file') }); html = render({}); assert.deepEqual('hello world', html); }, 'include: extend options': () => { let render, html; render = compile({ bail: true, filename: path.resolve(__dirname, '..', 'res', 'extend-options', 'file'), rules: [ { test: /\${([\w\W]*?)}/, use: function(match, code) { return { code: code, output: false }; } } ] }); html = render({ value: 'hello world' }); assert.deepEqual('hello world', html); render = compile({ bail: true, filename: path.resolve(__dirname, '..', 'res', 'extend-options', 'file2') }); html = render({ value: 'hello world' }); assert.deepEqual('${value}hello world', html); }, imports: () => { const render = compile('<%= $imports.stringify(value) %>', { bail: true, imports: { stringify: JSON.stringify, log: console.log } }); assert.deepEqual( '"hello"', render({ value: 'hello' }) ); } }, 'rule.mix': {}, errors: { RuntimeError: { error: () => { const render = compile('<%=a.b.c%>', { bail: false }); assert.deepEqual('{Template Error}', render({})); }, 'throw error': () => { const filename = '/test.html'; const render = compile({ filename, source: '<%=a.b.c%>', bail: true }); try { render({}); } catch (e) { assert.deepEqual('TemplateError', e.name); assert.deepEqual(true, e.message.indexOf(filename) !== -1); } } }, CompileError: { error: () => { let render; render = compile('<%=a b c%>', { bail: false }); assert.deepEqual('{Template Error}', render({})); render = compile('{{a b c}}', { bail: false }); assert.deepEqual('{Template Error}', render({})); }, 'throw error': () => { let render; try { render = compile('<%=a b c%>', { bail: true }); render({}); } catch (e) { assert.deepEqual('TemplateError', e.name); } assert.deepEqual(undefined, render); }, // 'error line': () => { // const tpl = ` // {{if user}} //

{{user.name}}

//
    // {{each user.tags}} //
  • {{$value}} {{a b c d}}
  • // {{/each}} //
// {{/if}}`; // let render; // try { // render = compile(tpl, { // bail: true, // minimize: false // }); // render({}); // } catch (e) { // assert.deepEqual(6, e.line); // } // assert.deepEqual(undefined, render); // }, 'template not found': () => { const render = compile({ filename: '/404.html', bail: false }); assert.deepEqual('{Template Error}', render({})); }, 'throw error: template not found': () => { try { compile({ filename: '/404.html', bail: true }); } catch (e) { assert.deepEqual(true, e.message.indexOf('template not found') !== -1); } } } }, toString: { 'compile to string': () => { const render = compile('<%=value%>'); assert.deepEqual('string', typeof render.toString()); assert.deepEqual(-1, render.toString.toString().indexOf('[native code]')); } } }; ================================================ FILE: test/compile/runtime.js ================================================ const assert = require('assert'); const runtime = require('../../src/compile/runtime'); module.exports = { escape: { basic: () => { const test = (content, result) => { assert.deepEqual(result, runtime.$escape(content)); }; // basic test('string', 'string'); test(1, '1'); test(0, '0'); test(function() { return 'value'; }, 'value'); test(() => 'value', 'value'); test(null, ''); test(undefined, ''); test([0, 1, 2, {}], JSON.stringify([0, 1, 2, {}])); test({}, JSON.stringify({})); }, html: () => { const test = (content, result) => { assert.deepEqual(result, runtime.$escape(content)); }; test('<', '<'); test('>', '>'); test('"', '"'); test("'", '''); test('&', '&'); }, mixing: () => { const test = (content, result) => { assert.deepEqual(result, runtime.$escape(content)); }; test('', '<img onerror="alert(0)">'); test( { '<': '<', '>': '>', '"': '"', "'": ''', '&': '&' }, '{"<":"&#60;",">":"&#62;","\\"":"&#34;","'":"&#39;","&":"&#38;"}' ); } } }; ================================================ FILE: test/compile/tpl-tokenizer.js ================================================ const assert = require('assert'); const tplTokenizer = require('../../src/compile/tpl-tokenizer'); module.exports = { 'type & value': { [tplTokenizer.TYPE_STRING]: () => { const result = tplTokenizer('value', []); assert.deepEqual( [ { type: tplTokenizer.TYPE_STRING, value: 'value', line: 0, start: 0, end: 5, script: null } ], result ); }, [tplTokenizer.TYPE_EXPRESSION]: () => { const rule = { test: /<%([\w\W]*?)%>/, use: (match, code) => { return { code, output: false }; } }; const result = tplTokenizer('<%value%>', [rule]); assert.deepEqual( [ { type: tplTokenizer.TYPE_EXPRESSION, value: '<%value%>', line: 0, start: 0, end: 9, script: { code: 'value', output: false } } ], result ); }, [tplTokenizer.TYPE_STRING + ' & ' + tplTokenizer.TYPE_EXPRESSION]: () => { const rule = { test: /<%([\w\W]*?)%>/, use: (match, code) => { return { code, output: false }; } }; const result = tplTokenizer('hello, <%value%>', [rule]); assert.deepEqual( [ { type: tplTokenizer.TYPE_STRING, value: 'hello, ', line: 0, start: 0, end: 7, script: null }, { type: tplTokenizer.TYPE_EXPRESSION, value: '<%value%>', line: 0, start: 7, end: 16, script: { code: 'value', output: false } } ], result ); } }, 'line & start & end': { 'check that the values are correct': () => { let result; const rules = [ { test: /<%([\w\W]*?)%>/, use: (match, code) => { return { code, output: false }; } }, { test: /\${([\w\W]*?)}/, use: (match, code) => { return { code, output: 'escape' }; } } ]; result = tplTokenizer('hello,\n <%value%>', rules); assert.deepEqual( [ { type: tplTokenizer.TYPE_STRING, value: 'hello,\n ', line: 0, start: 0, end: 8, script: null }, { type: tplTokenizer.TYPE_EXPRESSION, value: '<%value%>', line: 1, start: 1, end: 10, script: { code: 'value', output: false } } ], result ); result = tplTokenizer('hello,\n <%\nvalue\n%>\nxx${abc}', rules); assert.deepEqual( [ { type: tplTokenizer.TYPE_STRING, value: 'hello,\n ', line: 0, start: 0, end: 8, script: null }, { type: tplTokenizer.TYPE_EXPRESSION, value: '<%\nvalue\n%>', line: 1, start: 1, end: 12, script: { code: '\nvalue\n', output: false } }, { type: tplTokenizer.TYPE_STRING, value: '\nxx', line: 3, start: 2, end: 5, script: null }, { type: tplTokenizer.TYPE_EXPRESSION, value: '${abc}', line: 4, start: 2, end: 8, script: { code: 'abc', output: 'escape' } } ], result ); } } }; ================================================ FILE: test/index.js ================================================ const assert = require('assert'); const template = require('../src/index'); const defaults = require('../src/compile/defaults'); const path = require('path'); const root = defaults.root; module.exports = { before: () => { console.log('#index'); }, template: { render: () => { const html = template(__dirname + '/res/template.file.html', {}); assert.deepEqual('hello world', html); }, compile: () => { defaults.root = path.join(__dirname, 'res'); const render = template('template.file.html'); const html = render({}); assert.deepEqual('hello world', html); defaults.root = root; }, include: () => { defaults.root = path.join(__dirname, 'res'); const html = template('index/index.html', { name: 'aui' }); assert.deepEqual(true, html.indexOf('aui') !== -1); assert.deepEqual(true, html.indexOf('糖饼') !== -1); defaults.root = root; }, cache: () => { template('/index.html', 'hi, <%=value%>.'); const html = template('/index.html', { value: 'aui' }); assert.deepEqual('hi, aui.', html); }, nestedBlockUseActualValue: () => { defaults.root = path.join(__dirname, 'res'); const html = template('nested-block/index.art', { hello: 'hello' }); assert.deepEqual('hello', html); defaults.root = root; }, nestedBlockUseDefaultValue: () => { defaults.root = path.join(__dirname, 'res'); const html = template('nested-block/default.art', {}); assert.deepEqual('default', html); defaults.root = root; } } }; ================================================ FILE: test/node.js ================================================ const assert = require('assert'); const template = require('../'); const defaults = template.defaults; const path = require('path'); const resetBail = defaults.bail; const onerror = defaults.onerror; module.exports = { before: () => { console.log('#node'); require.extensions['.html'] = template.extension; require.extensions['.tpl'] = template.extension; defaults.onerror = () => { return () => '{Template Error}'; }; }, after: () => { defaults.onerror = onerror; }, extension: { 'require .art': () => { const render = require(path.join(__dirname, 'res', 'file')); assert.deepEqual('hello world', render({})); }, 'require .html': () => { const render = require(path.join(__dirname, 'res', 'extension.file.html')); assert.deepEqual('hello world', render({})); }, 'require .tpl': () => { const render = require(path.join(__dirname, 'res', 'extension.file.tpl')); assert.deepEqual('hello world', render({})); }, 'CompileError: bail=false': () => { defaults.bail = false; const render = require(path.join(__dirname, 'res', 'extension.compile-error.tpl')); assert.deepEqual('{Template Error}', render({})); defaults.bail = resetBail; }, 'CompileError: bail=true': () => { defaults.bail = true; let runder; const filename = path.join(__dirname, './res/extension.compile-error.2.tpl'); try { runder = require(filename); } catch (e) { assert.deepEqual('TemplateError', e.name); assert.deepEqual(true, e.message.indexOf(filename) !== -1); } assert.deepEqual('undefined', typeof runder); defaults.bail = resetBail; }, 'RuntimeError: bail=false': () => { defaults.bail = false; const render = require(path.join(__dirname, 'res', 'extension.runtime-error.tpl')); assert.deepEqual('{Template Error}', render({})); defaults.bail = resetBail; }, 'RuntimeError: bail=true': () => { defaults.bail = true; const filename = path.join(__dirname, 'res', 'extension.runtime-error.2.tpl'); try { const render = require(filename); render({}); } catch (e) { assert.deepEqual('TemplateError', e.name); assert.deepEqual(true, e.message.indexOf(filename) !== -1); } defaults.bail = resetBail; } } }; ================================================ FILE: test/res/extend-options/file.art ================================================ ${include('./include')} ================================================ FILE: test/res/extend-options/file2.art ================================================ ${value}{{value}} ================================================ FILE: test/res/extend-options/include.art ================================================ ${print(value)} ================================================ FILE: test/res/extension.compile-error.2.tpl ================================================ <% if (a b c) { %> ================================================ FILE: test/res/extension.compile-error.tpl ================================================ <% if (a b c) { %> ================================================ FILE: test/res/extension.file.html ================================================ hello world ================================================ FILE: test/res/extension.file.tpl ================================================ hello world ================================================ FILE: test/res/extension.runtime-error.2.tpl ================================================ <%= a.b.c %> ================================================ FILE: test/res/extension.runtime-error.tpl ================================================ <%= a.b.c %> ================================================ FILE: test/res/file.art ================================================ hello world ================================================ FILE: test/res/file.html ================================================ hello world ================================================ FILE: test/res/index/include.html ================================================ hello {{name}} ================================================ FILE: test/res/index/index.html ================================================ {{include './include.html'}} <% include('./include.html', {name: '糖饼'}) %> ================================================ FILE: test/res/nested-block/base-layout.art ================================================ {{block 'content'}}{{/block}} ================================================ FILE: test/res/nested-block/default.art ================================================ {{extend './layout.art'}} ================================================ FILE: test/res/nested-block/index.art ================================================ {{extend './layout.art'}} {{block 'inner'}}{{hello}}{{/block}} ================================================ FILE: test/res/nested-block/layout.art ================================================ {{extend './base-layout.art'}} {{block 'content'}}{{block 'inner'}}default{{/block}}{{/block}} ================================================ FILE: test/res/template.file.html ================================================ hello world ================================================ FILE: webpack.config.js ================================================ const path = require('path'); const webpack = require('webpack'); const packageInfo = require('./package.json'); const version = packageInfo.version; module.exports = { target: 'web', entry: { 'template-web': path.resolve(__dirname, 'lib', 'index') }, output: { path: path.resolve(__dirname, 'lib'), filename: '[name].js', library: 'template', libraryTarget: 'umd' }, node: { fs: 'empty', path: 'empty', process: false }, resolve: { alias: { 'html-minifier': 'node-noop' } }, module: { rules: [ { test: /\.js$/, use: [ { loader: 'eslint-loader' } ] } ] }, devtool: 'source-map', plugins: [ new webpack.BannerPlugin( `art-template@${version} for browser | https://github.com/aui/art-template` ), new webpack.optimize.ModuleConcatenationPlugin(), process.env.NODE_ENV === 'production' ? new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, screw_ie8: false }, mangle: { screw_ie8: false }, output: { screw_ie8: false } }) : () => {} ] };